diff --git a/.gitignore b/.gitignore index cb0a0ed..96b9770 100644 --- a/.gitignore +++ b/.gitignore
@@ -310,6 +310,7 @@ /third_party/bison /third_party/boringssl/src /third_party/bouncycastle/lib/*.jar +/third_party/byte_buddy/lib/*.jar /third_party/cacheinvalidation/cacheinvalidation_unittests_run.xml /third_party/cardboard-java/src /third_party/catapult @@ -397,6 +398,7 @@ /third_party/netty-tcnative/src /third_party/netty4/src /third_party/nss +/third_party/objenesis/lib/*.jar /third_party/omaha/src/omaha /third_party/openmax_dl/ /third_party/openh264/src
diff --git a/AUTHORS b/AUTHORS index 110519c..f7b118e 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -213,6 +213,7 @@ George Liaskos <geo.liaskos@gmail.com> Georgy Buranov <gburanov@gmail.com> Gergely Nagy <ngg@ngg.hu> +Gideon Pyzer <gjpyzer@gmail.com> Gitanshu Mehndiratta <g.mehndiratt@samsung.com> Giuseppe Iuculano <giuseppe@iuculano.it> Glenn Adams <glenn@chromium.org> @@ -296,6 +297,8 @@ Jiajia Qin <jiajia.qin@intel.com> Jiawei Shao <jiawei.shao@intel.com> Jie Chen <jie.a.chen@intel.com> +Jihoon Chung <jihoon@gmail.com> +Jihoon Chung <j.c@navercorp.com> Jihun Brent Kim <devgrapher@gmail.com> Jin Yang <jin.a.yang@intel.com> Jincheol Jo <jincheol.jo@navercorp.com>
diff --git a/DEPS b/DEPS index d6d5f96f..94476aa 100644 --- a/DEPS +++ b/DEPS
@@ -36,11 +36,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '2ab9057b31ee92060b9769ea1adfada51c11c010', + 'skia_revision': '8c200694f8eec5f623b3934b85c31dbb382be12c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '188b5e4e7a9e0226b816a3fc98dae0c877741dfd', + 'v8_revision': '9fd55f76d82496ca9233bd180f69152ff14b6613', # 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. @@ -52,11 +52,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': '33a32b8aa2b7274d246fcf85ce8f762cf4291418', + 'buildtools_revision': 'adb8bf4e8fc92aa1717bf151b862d58e6f27c4f2', + # Three lines of non-changing comments so that + # the commit queue can handle CLs rolling SwiftShader + # and whatever else without interference from each other. + 'swiftshader_revision': '3e204de9bb74b5379b42b7eea5c4b898b2698d56', # 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': '85af2a3cfcdfb2200510d337bfbf5b405858aa3b', + 'pdfium_revision': 'd0b6ed1a0842386e474c5fcd6bdbb260bb631bd1', # 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. @@ -64,7 +68,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. - 'boringssl_revision': '0d1b0961f9b8ef720cd96ae0a7ac3edcbbf538e5', + 'boringssl_revision': '96e1a25943ba98e644d71d23dd30815704da77a7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling google-toolbox-for-mac # and whatever else without interference from each other. @@ -80,7 +84,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': '2b411312ee0b4b0af6888d8b5f40b987df3b9c7c', + 'nacl_revision': 'ed65d7fff19bcebabe3a36970854f8444c151ef6', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype-android # and whatever else without interference from each other. @@ -88,7 +92,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '49d354d564ab7571921ee15356e9949f03fd1a92', + 'catapult_revision': '2fae0f4cec8b8ae76847d17686a95c8fad02035e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -102,6 +106,7 @@ 'boringssl.googlesource.com', 'pdfium.googlesource.com', 'android.googlesource.com', + 'swiftshader.googlesource.com', ] deps = { @@ -190,7 +195,7 @@ Var('chromium_git') + '/chromium/third_party/ffmpeg.git' + '@' + '75976ae026fdbedb14f006eec6cd9119c543aa7f', 'src/third_party/usrsctp/usrsctplib': - Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + '9a3e5465e9d96d8a7f78f1e996412d6235d7a359', + Var('chromium_git') + '/external/github.com/sctplab/usrsctp' + '@' + '4ce5badc821451f5dd5aa43fb75cbb93bacdf187', 'src/third_party/libsrtp': Var('chromium_git') + '/chromium/deps/libsrtp.git' + '@' + '48bdd208dcdbb018c4a154cf260414dbdfabb86d', # from svn revision 295151 @@ -202,7 +207,7 @@ Var('chromium_git') + '/chromium/deps/libjpeg_turbo.git' + '@' + '7260e4d8b8e1e40b17f03fafdf1cd83296900f76', 'src/third_party/flac': - Var('chromium_git') + '/chromium/deps/flac.git' + '@' + '812243a85937e06102ba312c6caf8823e243b35b', + Var('chromium_git') + '/chromium/deps/flac.git' + '@' + 'd0c35f878ec26f969c1631350b1d36fbd88ad8bb', 'src/third_party/flatbuffers/src': Var('chromium_git') + '/external/github.com/google/flatbuffers.git' + '@' + 'e92ae5199d52fd59540a800bec7eef46cd778257', @@ -214,7 +219,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' + '@' + 'dab9f13aa05550dd690be8bb37082fe78776d737', # commit position 13696 + Var('chromium_git') + '/external/webrtc/trunk/webrtc.git' + '@' + '56f770148f2ecb5a46e512c0ce66a4c7e5b2ad79', # commit position 13737 'src/third_party/openmax_dl': Var('chromium_git') + '/external/webrtc/deps/third_party/openmax.git' + '@' + Var('openmax_dl_revision'), @@ -249,11 +254,14 @@ 'src/third_party/ced/src': Var('chromium_git') + '/external/github.com/google/compact_enc_det.git' + '@' + '9012c0ab648025dd0f8df14294bf5d6d73793ac9', + 'src/third_party/swiftshader': + 'https://swiftshader.googlesource.com/SwiftShader.git' + '@' + Var('swiftshader_revision'), + 'src/third_party/cld_2/src': Var('chromium_git') + '/external/github.com/CLD2Owners/cld2.git' + '@' + '84b58a5d7690ebf05a91406f371ce00c3daf31c0', 'src/third_party/cld_3/src': - Var('chromium_git') + '/external/github.com/google/cld_3.git' + '@' + '94b690d6c2019d6a99a105c5c60c4b185660bd89', + Var('chromium_git') + '/external/github.com/google/cld_3.git' + '@' + '34400fc50e2028157e10083be7d0347e8ae8bcf3', 'src/third_party/libwebm/source': Var('chromium_git') + '/webm/libwebm.git' + '@' + '9a235e0bc94319c5f7184bd69cbe5468a74a025c', @@ -268,7 +276,7 @@ Var('chromium_git') + '/external/py_trace_event.git' + '@' + 'dd463ea9e2c430de2b9e53dea57a77b4c3ac9b30', 'src/third_party/dom_distiller_js/dist': - Var('chromium_git') + '/external/github.com/chromium/dom-distiller-dist.git' + '@' + 'f092aa790a0eb66135fa26d98a5f118997ed446d', + Var('chromium_git') + '/external/github.com/chromium/dom-distiller-dist.git' + '@' + 'a52cdd99c5adfe6e2e85da815fe390ce90567498', 'src/third_party/catapult': Var('chromium_git') + '/external/github.com/catapult-project/catapult.git' + '@' + @@ -481,7 +489,7 @@ Var('chromium_git') + '/external/github.com/kennethreitz/requests.git' + '@' + 'f172b30356d821d180fa4ecfa3e71c7274a32de4', 'src/third_party/custom_tabs_client/src': - Var('chromium_git') + '/external/github.com/GoogleChrome/custom-tabs-client.git' + '@' + '2d896e8578f12ce85b804cab9e8f7e6e8c1bab7d', + Var('chromium_git') + '/external/github.com/GoogleChrome/custom-tabs-client.git' + '@' + 'c51efbddc4f976c88d15c730a79feba65ca857af', 'src/third_party/gvr-android-sdk/src': Var('chromium_git') + '/external/github.com/googlevr/gvr-android-sdk.git' + '@' + 'cff15311c7c1abbe77b3c714135dccc2009ee473', @@ -630,6 +638,16 @@ ], }, { + 'name': 'byte_buddy', + 'pattern': '.', + 'action': ['python', + 'src/build/android/update_deps/update_third_party_deps.py', + 'download', + '-b', 'chromium-byte-buddy', + '-l', 'third_party/byte_buddy' + ], + }, + { 'name': 'espresso', 'pattern': '.', 'action': ['python', @@ -710,6 +728,16 @@ ], }, { + 'name': 'objenesis', + 'pattern': '.', + 'action': ['python', + 'src/build/android/update_deps/update_third_party_deps.py', + 'download', + '-b', 'chromium-objenesis', + '-l', 'third_party/objenesis' + ], + }, + { # Downloads the current stable linux sysroot to build/linux/ if needed. # This sysroot updates at about the same rate that the chrome build deps # change. This script is a no-op except for linux users who are doing
diff --git a/WATCHLISTS b/WATCHLISTS index b922810..93fa7f265 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -830,7 +830,6 @@ '|^components/browser_sync/'\ '|^components/sync/'\ '|^components/sync_bookmarks/'\ - '|^components/sync_driver/'\ '|^components/sync_sessions/', }, 'syncfs': {
diff --git a/android_webview/browser/aw_ssl_host_state_delegate.cc b/android_webview/browser/aw_ssl_host_state_delegate.cc index 1da4747..921d7de 100644 --- a/android_webview/browser/aw_ssl_host_state_delegate.cc +++ b/android_webview/browser/aw_ssl_host_state_delegate.cc
@@ -55,13 +55,17 @@ AwSSLHostStateDelegate::~AwSSLHostStateDelegate() { } -void AwSSLHostStateDelegate::HostRanInsecureContent(const std::string& host, - int pid) { +void AwSSLHostStateDelegate::HostRanInsecureContent( + const std::string& host, + int pid, + InsecureContentType content_type) { // Intentional no-op for Android WebView. } -bool AwSSLHostStateDelegate::DidHostRunInsecureContent(const std::string& host, - int pid) const { +bool AwSSLHostStateDelegate::DidHostRunInsecureContent( + const std::string& host, + int pid, + InsecureContentType content_type) const { // Intentional no-op for Android WebView. return false; }
diff --git a/android_webview/browser/aw_ssl_host_state_delegate.h b/android_webview/browser/aw_ssl_host_state_delegate.h index 45cbe79b..82e7dbf 100644 --- a/android_webview/browser/aw_ssl_host_state_delegate.h +++ b/android_webview/browser/aw_ssl_host_state_delegate.h
@@ -64,11 +64,15 @@ bool* expired_previous_decision) override; // Records that a host has run insecure content. - void HostRanInsecureContent(const std::string& host, int pid) override; + void HostRanInsecureContent(const std::string& host, + int pid, + InsecureContentType content_type) override; // Returns whether the specified host ran insecure content. - bool DidHostRunInsecureContent(const std::string& host, - int pid) const override; + bool DidHostRunInsecureContent( + const std::string& host, + int pid, + InsecureContentType content_type) const override; // Revokes all SSL certificate error allow exceptions made by the user for // |host|.
diff --git a/android_webview/java/src/org/chromium/android_webview/AwViewAndroidDelegate.java b/android_webview/java/src/org/chromium/android_webview/AwViewAndroidDelegate.java index 101db6ae..fdcfc94f 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwViewAndroidDelegate.java +++ b/android_webview/java/src/org/chromium/android_webview/AwViewAndroidDelegate.java
@@ -58,7 +58,8 @@ } } - AwViewAndroidDelegate(ViewGroup containerView, RenderCoordinates renderCoordinates) { + @VisibleForTesting + public AwViewAndroidDelegate(ViewGroup containerView, RenderCoordinates renderCoordinates) { mContainerView = containerView; mRenderCoordinates = renderCoordinates; }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsAnchorViewTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsAnchorViewTest.java index 0e2c68d..c688b39 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsAnchorViewTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsAnchorViewTest.java
@@ -12,7 +12,7 @@ import org.chromium.android_webview.AwViewAndroidDelegate; import org.chromium.base.test.util.Feature; -import org.chromium.ui.base.ViewAndroidDelegate; +import org.chromium.content.browser.RenderCoordinates; import org.chromium.ui.gfx.DeviceDisplayInfo; /** @@ -20,23 +20,65 @@ */ public class AwContentsAnchorViewTest extends AwTestBase { - private TestAwContentsClient mContentsClient = new TestAwContentsClient(); + private FrameLayout mContainerView; + private AwViewAndroidDelegate mViewDelegate; + + @Override + public void setUp() throws Exception { + super.setUp(); + mContainerView = new FrameLayout(getActivity()); + mViewDelegate = new AwViewAndroidDelegate(mContainerView, new RenderCoordinates()); + } + + @Feature({"AndroidWebView"}) + @SmallTest + @UiThreadTest + public void testAddAndRemoveAnchorViews() { + // Add 2 anchor views + View anchorView1 = addAnchorView(); + View anchorView2 = addAnchorView(); + + // Remove anchorView1 + removeAnchorView(anchorView1); + + // Try to remove anchorView1 again; no-op. + removeAnchorView(anchorView1); + + // Remove anchorView2 + removeAnchorView(anchorView2); + } + + @Feature({"AndroidWebView"}) + @SmallTest + @UiThreadTest + public void testAddAndMoveAnchorView() { + // Add anchorView and set layout params + View anchorView = addAnchorView(); + LayoutParams originalLayoutParams = setLayoutParams(anchorView, 0, 0); + + // Move it + LayoutParams updatedLayoutParams = setLayoutParams(anchorView, 1, 2); + assertFalse(areEqual(originalLayoutParams, updatedLayoutParams)); + + // Move it back to the original position + updatedLayoutParams = setLayoutParams(anchorView, 0, 0); + assertTrue(areEqual(originalLayoutParams, updatedLayoutParams)); + } @Feature({"AndroidWebView"}) @SmallTest @UiThreadTest public void testMovedAndRemovedAnchorViewIsNotTransferred() throws Throwable { // Add, move and remove anchorView - AwTestContainerView containerView = createAwTestContainerViewOnMainSync(mContentsClient); - View anchorView = addAnchorView(containerView); - setLayoutParams(containerView, anchorView, 1, 2); - removeAnchorView(containerView, anchorView); + View anchorView = addAnchorView(); + setLayoutParams(anchorView, 1, 2); + removeAnchorView(anchorView); // Replace container view - FrameLayout updatedContainerView = updateContainerView(containerView); + FrameLayout updatedContainerView = updateContainerView(); // Verify that no anchor view is transferred between containerViews - assertFalse(isViewInContainer(containerView, anchorView)); + assertFalse(isViewInContainer(mContainerView, anchorView)); assertFalse(isViewInContainer(updatedContainerView, anchorView)); } @@ -45,14 +87,13 @@ @UiThreadTest public void testTransferAnchorView() throws Throwable { // Add anchor view - AwTestContainerView containerView = createAwTestContainerViewOnMainSync(mContentsClient); - View anchorView = addAnchorView(containerView); + View anchorView = addAnchorView(); LayoutParams layoutParams = anchorView.getLayoutParams(); // Replace container view - FrameLayout updatedContainerView = updateContainerView(containerView); + FrameLayout updatedContainerView = updateContainerView(); verifyAnchorViewCorrectlyTransferred( - containerView, anchorView, updatedContainerView, layoutParams); + mContainerView, anchorView, updatedContainerView, layoutParams); } @Feature({"AndroidWebView"}) @@ -60,15 +101,14 @@ @UiThreadTest public void testTransferMovedAnchorView() throws Throwable { // Add anchor view and move it - AwTestContainerView containerView = createAwTestContainerViewOnMainSync(mContentsClient); - View anchorView = addAnchorView(containerView); - LayoutParams layoutParams = setLayoutParams(containerView, anchorView, 1, 2); + View anchorView = addAnchorView(); + LayoutParams layoutParams = setLayoutParams(anchorView, 1, 2); // Replace container view - FrameLayout updatedContainerView = updateContainerView(containerView); + FrameLayout updatedContainerView = updateContainerView(); verifyAnchorViewCorrectlyTransferred( - containerView, anchorView, updatedContainerView, layoutParams); + mContainerView, anchorView, updatedContainerView, layoutParams); } @Feature({"AndroidWebView"}) @@ -76,16 +116,15 @@ @UiThreadTest public void testRemoveTransferedAnchorView() throws Throwable { // Add anchor view - AwTestContainerView containerView = createAwTestContainerViewOnMainSync(mContentsClient); - View anchorView = addAnchorView(containerView); + View anchorView = addAnchorView(); // Replace container view - FrameLayout updatedContainerView = updateContainerView(containerView); + FrameLayout updatedContainerView = updateContainerView(); - verifyAnchorViewCorrectlyTransferred(containerView, anchorView, updatedContainerView); + verifyAnchorViewCorrectlyTransferred(mContainerView, anchorView, updatedContainerView); // Remove transferred anchor view - removeAnchorView(containerView, anchorView); + removeAnchorView(anchorView); } @Feature({"AndroidWebView"}) @@ -93,18 +132,17 @@ @UiThreadTest public void testMoveTransferedAnchorView() throws Throwable { // Add anchor view - AwTestContainerView containerView = createAwTestContainerViewOnMainSync(mContentsClient); - View anchorView = addAnchorView(containerView); + View anchorView = addAnchorView(); LayoutParams layoutParams = anchorView.getLayoutParams(); // Replace container view - FrameLayout updatedContainerView = updateContainerView(containerView); + FrameLayout updatedContainerView = updateContainerView(); verifyAnchorViewCorrectlyTransferred( - containerView, anchorView, updatedContainerView, layoutParams); + mContainerView, anchorView, updatedContainerView, layoutParams); // Move transferred anchor view - assertFalse(areEqual(layoutParams, setLayoutParams(containerView, anchorView, 1, 2))); + assertFalse(areEqual(layoutParams, setLayoutParams(anchorView, 1, 2))); } @Feature({"AndroidWebView"}) @@ -112,50 +150,47 @@ @UiThreadTest public void testTransferMultipleMovedAnchorViews() throws Throwable { // Add and move anchorView1 - AwTestContainerView containerView = createAwTestContainerViewOnMainSync(mContentsClient); - View anchorView1 = addAnchorView(containerView); - LayoutParams layoutParams1 = setLayoutParams(containerView, anchorView1, 1, 2); + View anchorView1 = addAnchorView(); + LayoutParams layoutParams1 = setLayoutParams(anchorView1, 1, 2); // Add and move anchorView2 - View anchorView2 = addAnchorView(containerView); - LayoutParams layoutParams2 = setLayoutParams(containerView, anchorView2, 2, 4); + View anchorView2 = addAnchorView(); + LayoutParams layoutParams2 = setLayoutParams(anchorView2, 2, 4); // Replace containerView - FrameLayout updatedContainerView = updateContainerView(containerView); + FrameLayout updatedContainerView = updateContainerView(); // Verify that anchor views are transfered with the same layout params. - assertFalse(isViewInContainer(containerView, anchorView1)); - assertFalse(isViewInContainer(containerView, anchorView2)); + assertFalse(isViewInContainer(mContainerView, anchorView1)); + assertFalse(isViewInContainer(mContainerView, anchorView2)); assertTrue(isViewInContainer(updatedContainerView, anchorView1)); assertTrue(isViewInContainer(updatedContainerView, anchorView2)); assertTrue(areEqual(layoutParams1, anchorView1.getLayoutParams())); assertTrue(areEqual(layoutParams2, anchorView2.getLayoutParams())); } - private static View addAnchorView(AwTestContainerView containerView) { - View anchorView = getViewDelegate(containerView).acquireView(); - assertTrue(isViewInContainer(containerView, anchorView)); + private View addAnchorView() { + View anchorView = mViewDelegate.acquireView(); + assertTrue(isViewInContainer(mContainerView, anchorView)); return anchorView; } - private static void removeAnchorView(AwTestContainerView containerView, View anchorView) { - getViewDelegate(containerView).removeView(anchorView); - assertFalse(isViewInContainer(containerView, anchorView)); + private void removeAnchorView(View anchorView) { + mViewDelegate.removeView(anchorView); + assertFalse(isViewInContainer(mContainerView, anchorView)); } - private static LayoutParams setLayoutParams(AwTestContainerView containerView, View anchorView, - int coords, int dimension) { - ViewAndroidDelegate delegate = getViewDelegate(containerView); - float scale = (float) DeviceDisplayInfo.create(containerView.getContext()).getDIPScale(); - delegate.setViewPosition(anchorView, coords, coords, dimension, dimension, scale, 10, 10); + private LayoutParams setLayoutParams(View anchorView, int coords, int dimension) { + float scale = (float) DeviceDisplayInfo.create(mContainerView.getContext()).getDIPScale(); + mViewDelegate.setViewPosition( + anchorView, coords, coords, dimension, dimension, scale, 10, 10); return anchorView.getLayoutParams(); } - private FrameLayout updateContainerView(AwTestContainerView oldContainerView) { + private FrameLayout updateContainerView() throws InterruptedException { FrameLayout containerView = new FrameLayout(getActivity()); getActivity().addView(containerView); - AwViewAndroidDelegate delegate = (AwViewAndroidDelegate) getViewDelegate(oldContainerView); - delegate.updateCurrentContainerView(containerView); + mViewDelegate.updateCurrentContainerView(containerView); return containerView; } @@ -179,8 +214,4 @@ private static boolean isViewInContainer(FrameLayout containerView, View view) { return containerView.indexOfChild(view) != -1; } - - private static ViewAndroidDelegate getViewDelegate(AwTestContainerView containerView) { - return containerView.getAwContents().getContentViewCore().getViewAndroidDelegate(); - } }
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java index a5fc91f4..70a4847e 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsClientShouldOverrideUrlLoadingTest.java
@@ -340,9 +340,8 @@ /* @SmallTest @Feature({"AndroidWebView", "Navigation"}) - crbug.com/462306 */ - @DisabledTest + @DisabledTest(message = "crbug.com/462306") public void testCalledWhenTopLevelAboutBlankNavigation() throws Throwable { standardSetup();
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwQuotaManagerBridgeTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwQuotaManagerBridgeTest.java index 0bbb7038..60ed3fa 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwQuotaManagerBridgeTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwQuotaManagerBridgeTest.java
@@ -160,9 +160,8 @@ /* @LargeTest @Feature({"AndroidWebView", "WebStore"}) - Too flaky. See crbug.com/609977. */ - @DisabledTest + @DisabledTest(message = "crbug.com/609977") public void testDeleteAllWithAppCache() throws Exception { final long initialUsage = getUsageForOrigin(mOrigin); @@ -186,9 +185,8 @@ /* @LargeTest @Feature({"AndroidWebView", "WebStore"}) - Too flaky. See crbug.com/609977. */ - @DisabledTest + @DisabledTest(message = "crbug.com/609977") public void testDeleteOriginWithAppCache() throws Exception { final long initialUsage = getUsageForOrigin(mOrigin); @@ -212,9 +210,8 @@ /* @LargeTest @Feature({"AndroidWebView", "WebStore"}) - Too flaky. See crbug.com/609977. */ - @DisabledTest + @DisabledTest(message = "crbug.com/609977") public void testGetResultsMatch() throws Exception { useAppCache();
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwSecondBrowserProcessTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwSecondBrowserProcessTest.java index 55d4125..d636635 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwSecondBrowserProcessTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwSecondBrowserProcessTest.java
@@ -44,11 +44,11 @@ /* * @LargeTest * @Feature({"AndroidWebView"}) - * See crbug.com/582146. We can't test that creating second browser + * We can't test that creating second browser * process succeeds either, because in debug it will crash due to an assert * in the SQL DB code. */ - @DisabledTest + @DisabledTest(message = "crbug.com/582146") public void testCreatingSecondBrowserProcessFails() throws Throwable { startSecondBrowserProcess(); assertFalse(tryStartingBrowserProcess());
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java index fc05a0f9..ed6ca71 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
@@ -1606,11 +1606,10 @@ } /* - * Disabled due to document.defaultCharset removal. crbug.com/587484 * @SmallTest * @Feature({"AndroidWebView", "Preferences"}) */ - @DisabledTest + @DisabledTest(message = "Disabled due to document.defaultCharset removal. crbug.com/587484") public void testDefaultTextEncodingWithTwoViews() throws Throwable { ViewPair views = createViews(); runPerViewSettingsTest(
diff --git a/android_webview/tools/webview_repack_locales.py b/android_webview/tools/webview_repack_locales.py index 3d687c2..5fe3e6b 100755 --- a/android_webview/tools/webview_repack_locales.py +++ b/android_webview/tools/webview_repack_locales.py
@@ -15,8 +15,10 @@ import shutil import sys -sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', - 'tools', 'grit')) +# Prepend the grit module from the source tree so it takes precedence over other +# grit versions that might present in the search path. +sys.path.insert(1, os.path.join(os.path.dirname(__file__), '..', '..', + 'tools', 'grit')) from grit.format import data_pack def calc_output(locale):
diff --git a/ash/accelerators/accelerator_controller_unittest.cc b/ash/accelerators/accelerator_controller_unittest.cc index 58b8e588..650336b0 100644 --- a/ash/accelerators/accelerator_controller_unittest.cc +++ b/ash/accelerators/accelerator_controller_unittest.cc
@@ -1124,9 +1124,15 @@ EXPECT_TRUE(test_api.is_animating_lock()); #endif + auto press_and_release_alt_tab = [&generator]() { + generator.PressKey(ui::VKEY_TAB, ui::EF_ALT_DOWN); + // Release the alt key to trigger the window activation. + generator.ReleaseKey(ui::VKEY_MENU, ui::EF_NONE); + }; + // A fullscreen window can consume ALT-TAB (preferred). ASSERT_EQ(w1, wm::GetActiveWindow()); - generator.PressKey(ui::VKEY_TAB, ui::EF_ALT_DOWN); + press_and_release_alt_tab(); ASSERT_EQ(w1, wm::GetActiveWindow()); ASSERT_NE(w2, wm::GetActiveWindow()); @@ -1141,7 +1147,7 @@ ASSERT_FALSE(w1_state->IsFullscreen()); EXPECT_EQ(w1, wm::GetActiveWindow()); - generator.PressKey(ui::VKEY_TAB, ui::EF_ALT_DOWN); + press_and_release_alt_tab(); ASSERT_NE(w1, wm::GetActiveWindow()); ASSERT_EQ(w2, wm::GetActiveWindow()); }
diff --git a/ash/app_list/app_list_presenter_delegate.cc b/ash/app_list/app_list_presenter_delegate.cc index 8023dd7..3da55438 100644 --- a/ash/app_list/app_list_presenter_delegate.cc +++ b/ash/app_list/app_list_presenter_delegate.cc
@@ -4,6 +4,7 @@ #include "ash/app_list/app_list_presenter_delegate.h" +#include "ash/aura/wm_window_aura.h" #include "ash/common/ash_switches.h" #include "ash/common/shelf/app_list_button.h" #include "ash/common/shelf/shelf_types.h" @@ -41,7 +42,7 @@ // Gets arrow location based on shelf alignment. views::BubbleBorder::Arrow GetBubbleArrow(aura::Window* window) { DCHECK(Shell::HasInstance()); - switch (Shelf::ForWindow(window)->alignment()) { + switch (Shelf::ForWindow(WmWindowAura::Get(window))->alignment()) { case SHELF_ALIGNMENT_BOTTOM: case SHELF_ALIGNMENT_BOTTOM_LOCKED: return views::BubbleBorder::BOTTOM_CENTER; @@ -60,7 +61,8 @@ views::Widget* widget) { DCHECK(Shell::HasInstance()); ShelfAlignment shelf_alignment = - Shelf::ForWindow(widget->GetNativeView()->GetRootWindow())->alignment(); + Shelf::ForWindow(WmLookup::Get()->GetWindowForWidget(widget)) + ->alignment(); gfx::Point anchor(button_bounds.CenterPoint()); switch (shelf_alignment) { case SHELF_ALIGNMENT_BOTTOM: @@ -138,9 +140,9 @@ keyboard::KeyboardController::GetInstance(); if (keyboard_controller) keyboard_controller->RemoveObserver(this); - views::Widget* widget = view_->GetWidget(); Shell::GetInstance()->RemovePreTargetHandler(this); - Shelf::ForWindow(widget->GetNativeWindow())->RemoveIconObserver(this); + WmWindow* window = WmLookup::Get()->GetWindowForWidget(view_->GetWidget()); + Shelf::ForWindow(window)->RemoveIconObserver(this); WmShell::Get()->RemoveShellObserver(this); } @@ -162,8 +164,8 @@ ->GetRootWindowForDisplayId(display_id); aura::Window* container = GetRootWindowController(root_window) ->GetContainer(kShellWindowId_AppListContainer); - AppListButton* applist_button = - Shelf::ForWindow(container)->GetAppListButton(); + Shelf* shelf = Shelf::ForWindow(WmWindowAura::Get(container)); + AppListButton* applist_button = shelf->GetAppListButton(); is_centered_ = view->ShouldCenterWindow(); bool is_fullscreen = IsFullscreenAppListEnabled() && WmShell::Get() @@ -190,11 +192,9 @@ applist_button_bounds = ScreenUtil::ConvertRectFromScreen(root_window, applist_button_bounds); view->InitAsBubbleAttachedToAnchor( - container, current_apps_page, - Shelf::ForWindow(container)->GetAppListButton(), - GetAnchorPositionOffsetToShelf( - applist_button_bounds, - Shelf::ForWindow(container)->GetAppListButton()->GetWidget()), + container, current_apps_page, applist_button, + GetAnchorPositionOffsetToShelf(applist_button_bounds, + applist_button->GetWidget()), GetBubbleArrow(container), true /* border_accepts_events */); view->SetArrowPaintType(views::BubbleBorder::PAINT_NONE); } @@ -204,21 +204,18 @@ if (keyboard_controller) keyboard_controller->AddObserver(this); Shell::GetInstance()->AddPreTargetHandler(this); - views::Widget* widget = view->GetWidget(); - Shelf::ForWindow(widget->GetNativeWindow())->AddIconObserver(this); + shelf->AddIconObserver(this); // By setting us as DnD recipient, the app list knows that we can // handle items. view->SetDragAndDropHostOfCurrentAppList( - Shelf::ForWindow(root_window)->GetDragAndDropHostForAppList()); + shelf->GetDragAndDropHostForAppList()); } void AppListPresenterDelegate::OnShown(int64_t display_id) { is_visible_ = true; // Update applist button status when app list visibility is changed. - aura::Window* root_window = Shell::GetInstance() - ->window_tree_host_manager() - ->GetRootWindowForDisplayId(display_id); + WmWindow* root_window = WmShell::Get()->GetRootWindowForDisplayId(display_id); Shelf::ForWindow(root_window)->GetAppListButton()->OnAppListShown(); } @@ -230,14 +227,12 @@ // App list needs to know the new shelf layout in order to calculate its // UI layout when AppListView visibility changes. - Shell::GetPrimaryRootWindowController() - ->GetShelfLayoutManager() - ->UpdateAutoHideState(); + Shelf* shelf = + Shelf::ForWindow(WmLookup::Get()->GetWindowForWidget(view_->GetWidget())); + shelf->shelf_layout_manager()->UpdateAutoHideState(); // Update applist button status when app list visibility is changed. - Shelf::ForWindow(view_->GetWidget()->GetNativeView()) - ->GetAppListButton() - ->OnAppListDismissed(); + shelf->GetAppListButton()->OnAppListDismissed(); } void AppListPresenterDelegate::UpdateBounds() { @@ -258,11 +253,10 @@ // App list needs to know the new shelf layout in order to calculate its // UI layout when AppListView visibility changes. - Shell::GetPrimaryRootWindowController() - ->GetShelfLayoutManager() - ->UpdateAutoHideState(); + Shelf* shelf = Shelf::ForWindow(WmWindowAura::Get(root_window)); + shelf->shelf_layout_manager()->UpdateAutoHideState(); - switch (Shelf::ForWindow(root_window)->alignment()) { + switch (shelf->alignment()) { case SHELF_ALIGNMENT_BOTTOM: case SHELF_ALIGNMENT_BOTTOM_LOCKED: return gfx::Vector2d(0, kAnimationOffset);
diff --git a/ash/ash.gyp b/ash/ash.gyp index 958b0e5ea..839ca21 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp
@@ -492,6 +492,8 @@ 'common/wm/wm_toplevel_window_event_handler.h', 'common/wm/wm_types.cc', 'common/wm/wm_types.h', + 'common/wm/wm_window_animations.cc', + 'common/wm/wm_window_animations.h', 'common/wm/workspace/magnetism_matcher.cc', 'common/wm/workspace/magnetism_matcher.h', 'common/wm/workspace/multi_window_resize_controller.cc', @@ -647,8 +649,8 @@ 'shelf/dimmer_view.h', 'shelf/shelf.cc', 'shelf/shelf.h', - 'shelf/shelf_bezel_event_filter.cc', - 'shelf/shelf_bezel_event_filter.h', + 'shelf/shelf_bezel_event_handler.cc', + 'shelf/shelf_bezel_event_handler.h', 'shelf/shelf_layout_manager.cc', 'shelf/shelf_layout_manager.h', 'shelf/shelf_layout_manager_observer.h',
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 81ee1055..58ec6e3 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -283,6 +283,9 @@ <message name="IDS_ASH_STATUS_TRAY_VOLUME" desc="The accessible text for the volume slider."> Volume </message> + <message name="IDS_ASH_STATUS_TRAY_VOLUME_MUTE" desc="The accessible text for the volume mute button."> + Mute + </message> <message name="IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME" desc="Label shown in tray for a display whose name is unknown."> Unknown Display
diff --git a/ash/aura/wm_root_window_controller_aura.cc b/ash/aura/wm_root_window_controller_aura.cc index 58a6459..aa27ee8 100644 --- a/ash/aura/wm_root_window_controller_aura.cc +++ b/ash/aura/wm_root_window_controller_aura.cc
@@ -76,6 +76,8 @@ } wm::WorkspaceWindowState WmRootWindowControllerAura::GetWorkspaceWindowState() { + if (!root_window_controller_->workspace_controller()) + return wm::WORKSPACE_WINDOW_STATE_DEFAULT; return root_window_controller_->workspace_controller()->GetWindowState(); }
diff --git a/ash/aura/wm_shelf_aura.cc b/ash/aura/wm_shelf_aura.cc index 4b4d5cb..cfeb53d1 100644 --- a/ash/aura/wm_shelf_aura.cc +++ b/ash/aura/wm_shelf_aura.cc
@@ -9,6 +9,7 @@ #include "ash/common/wm_window.h" #include "ash/shelf/dimmer_view.h" #include "ash/shelf/shelf.h" +#include "ash/shelf/shelf_bezel_event_handler.h" #include "ash/shelf/shelf_layout_manager.h" #include "ash/shell.h" #include "ui/views/widget/widget.h" @@ -55,6 +56,7 @@ DCHECK(!shelf_layout_manager_); shelf_layout_manager_ = shelf_layout_manager; shelf_layout_manager_->AddObserver(this); + bezel_event_handler_.reset(new ShelfBezelEventHandler(this)); } void WmShelfAura::SetShelf(Shelf* shelf) { @@ -80,7 +82,9 @@ void WmShelfAura::ResetShelfLayoutManager() { if (!shelf_layout_manager_) return; + // Clear event handlers that might otherwise forward events during shutdown. auto_hide_event_handler_.reset(); + bezel_event_handler_.reset(); shelf_layout_manager_->RemoveObserver(this); shelf_layout_manager_ = nullptr; } @@ -129,10 +133,6 @@ return shelf_layout_manager_->shelf_widget()->GetDimsShelf(); } -bool WmShelfAura::IsShowingOverflowBubble() const { - return shelf_->IsShowingOverflowBubble(); -} - void WmShelfAura::SchedulePaint() { // Can be called during shutdown if the overflow bubble is visible. if (shelf_) @@ -163,12 +163,11 @@ } void WmShelfAura::UpdateIconPositionForWindow(WmWindow* window) { - shelf_->UpdateIconPositionForWindow(WmWindowAura::GetAuraWindow(window)); + shelf_->UpdateIconPositionForWindow(window); } gfx::Rect WmShelfAura::GetScreenBoundsOfItemIconForWindow(WmWindow* window) { - return shelf_->GetScreenBoundsOfItemIconForWindow( - WmWindowAura::GetAuraWindow(window)); + return shelf_->GetScreenBoundsOfItemIconForWindow(window); } bool WmShelfAura::ProcessGestureEvent(const ui::GestureEvent& event) {
diff --git a/ash/aura/wm_shelf_aura.h b/ash/aura/wm_shelf_aura.h index 86d5186..28a6cf1 100644 --- a/ash/aura/wm_shelf_aura.h +++ b/ash/aura/wm_shelf_aura.h
@@ -15,6 +15,7 @@ namespace ash { class Shelf; +class ShelfBezelEventHandler; class ShelfLayoutManager; // Aura implementation of WmShelf. @@ -50,7 +51,6 @@ ShelfBackgroundType GetBackgroundType() const override; WmDimmerView* CreateDimmerView(bool disable_animations_for_test) override; bool IsDimmed() const override; - bool IsShowingOverflowBubble() const override; void SchedulePaint() override; bool IsVisible() const override; void UpdateVisibilityState() override; @@ -85,8 +85,13 @@ base::ObserverList<WmShelfObserver> observers_; // Forwards mouse and gesture events to ShelfLayoutManager for auto-hide. + // TODO(mash): Facilitate simliar functionality in mash: crbug.com/631216 std::unique_ptr<AutoHideEventHandler> auto_hide_event_handler_; + // Forwards touch gestures on a bezel sensor to the shelf. + // TODO(mash): Facilitate simliar functionality in mash: crbug.com/636647 + std::unique_ptr<ShelfBezelEventHandler> bezel_event_handler_; + DISALLOW_COPY_AND_ASSIGN(WmShelfAura); };
diff --git a/ash/aura/wm_shell_aura.cc b/ash/aura/wm_shell_aura.cc index 004253b..e9d077b 100644 --- a/ash/aura/wm_shell_aura.cc +++ b/ash/aura/wm_shell_aura.cc
@@ -234,8 +234,9 @@ display_observers_.RemoveObserver(observer); } -void WmShellAura::AddPointerWatcher(views::PointerWatcher* watcher) { - Shell::GetInstance()->AddPointerWatcher(watcher); +void WmShellAura::AddPointerWatcher(views::PointerWatcher* watcher, + bool wants_moves) { + Shell::GetInstance()->AddPointerWatcher(watcher, wants_moves); } void WmShellAura::RemovePointerWatcher(views::PointerWatcher* watcher) {
diff --git a/ash/aura/wm_shell_aura.h b/ash/aura/wm_shell_aura.h index 341a824..648b373f 100644 --- a/ash/aura/wm_shell_aura.h +++ b/ash/aura/wm_shell_aura.h
@@ -69,7 +69,8 @@ void RemoveActivationObserver(WmActivationObserver* observer) override; void AddDisplayObserver(WmDisplayObserver* observer) override; void RemoveDisplayObserver(WmDisplayObserver* observer) override; - void AddPointerWatcher(views::PointerWatcher* watcher) override; + void AddPointerWatcher(views::PointerWatcher* watcher, + bool wants_moves) override; void RemovePointerWatcher(views::PointerWatcher* watcher) override; bool IsTouchDown() override; #if defined(OS_CHROMEOS)
diff --git a/ash/aura/wm_window_aura.cc b/ash/aura/wm_window_aura.cc index ade4df5..a46b56f 100644 --- a/ash/aura/wm_window_aura.cc +++ b/ash/aura/wm_window_aura.cc
@@ -355,12 +355,14 @@ std::unique_ptr<WmLayoutManager> layout_manager) { // |window_| takes ownership of AuraLayoutManagerAdapter. window_->SetLayoutManager( - new AuraLayoutManagerAdapter(std::move(layout_manager))); + layout_manager ? new AuraLayoutManagerAdapter(std::move(layout_manager)) + : nullptr); } WmLayoutManager* WmWindowAura::GetLayoutManager() { - return static_cast<AuraLayoutManagerAdapter*>(window_->layout_manager()) - ->wm_layout_manager(); + AuraLayoutManagerAdapter* adapter = + static_cast<AuraLayoutManagerAdapter*>(window_->layout_manager()); + return adapter ? adapter->wm_layout_manager() : nullptr; } void WmWindowAura::SetVisibilityAnimationType(int type) {
diff --git a/ash/common/accelerators/accelerator_router.cc b/ash/common/accelerators/accelerator_router.cc index 51e08cbd..9b47ee6 100644 --- a/ash/common/accelerators/accelerator_router.cc +++ b/ash/common/accelerators/accelerator_router.cc
@@ -84,7 +84,7 @@ if (accelerator.IsCmdDown()) return true; - if (ContainsValue(WmShell::Get()->GetAllRootWindows(), target)) + if (base::ContainsValue(WmShell::Get()->GetAllRootWindows(), target)) return true; AcceleratorController* accelerator_controller =
diff --git a/ash/common/ash_switches.cc b/ash/common/ash_switches.cc index 1e45a7e..ee32e4b3 100644 --- a/ash/common/ash_switches.cc +++ b/ash/common/ash_switches.cc
@@ -78,9 +78,6 @@ // removed. const char kAshEnableTouchViewTesting[] = "ash-enable-touch-view-testing"; -// Enables the window cycling UI (more visual feedback for alt-tab). -const char kAshEnableWindowCycleUi[] = "ash-enable-window-cycle-ui"; - // Hides notifications that are irrelevant to Chrome OS device factory testing, // such as battery level updates. const char kAshHideNotificationsForFactory[] =
diff --git a/ash/common/ash_switches.h b/ash/common/ash_switches.h index 21617aa..2d19523 100644 --- a/ash/common/ash_switches.h +++ b/ash/common/ash_switches.h
@@ -38,7 +38,6 @@ ASH_EXPORT extern const char kAshEnableStableOverviewOrder[]; ASH_EXPORT extern const char kAshEnableSoftwareMirroring[]; ASH_EXPORT extern const char kAshEnableTouchViewTesting[]; -ASH_EXPORT extern const char kAshEnableWindowCycleUi[]; ASH_EXPORT extern const char kAshHideNotificationsForFactory[]; ASH_EXPORT extern const char kAshHostWindowBounds[]; ASH_EXPORT extern const char kAshMaterialDesign[];
diff --git a/ash/common/pointer_watcher_delegate.h b/ash/common/pointer_watcher_delegate.h index 75f8738..b653fde5 100644 --- a/ash/common/pointer_watcher_delegate.h +++ b/ash/common/pointer_watcher_delegate.h
@@ -18,7 +18,8 @@ public: virtual ~PointerWatcherDelegate() {} - virtual void AddPointerWatcher(views::PointerWatcher* watcher) = 0; + virtual void AddPointerWatcher(views::PointerWatcher* watcher, + bool wants_moves) = 0; virtual void RemovePointerWatcher(views::PointerWatcher* watcher) = 0; };
diff --git a/ash/common/shelf/overflow_bubble.cc b/ash/common/shelf/overflow_bubble.cc index aaf84ca..b0ae2bc 100644 --- a/ash/common/shelf/overflow_bubble.cc +++ b/ash/common/shelf/overflow_bubble.cc
@@ -19,7 +19,8 @@ bubble_(nullptr), anchor_(nullptr), shelf_view_(nullptr) { - WmShell::Get()->AddPointerWatcher(this); + const bool wants_moves = false; + WmShell::Get()->AddPointerWatcher(this, wants_moves); } OverflowBubble::~OverflowBubble() {
diff --git a/ash/common/shelf/overflow_button.cc b/ash/common/shelf/overflow_button.cc index 03fe492f..1412015 100644 --- a/ash/common/shelf/overflow_button.cc +++ b/ash/common/shelf/overflow_button.cc
@@ -8,6 +8,7 @@ #include "ash/common/material_design/material_design_controller.h" #include "ash/common/shelf/ink_drop_button_listener.h" #include "ash/common/shelf/shelf_constants.h" +#include "ash/common/shelf/shelf_view.h" #include "ash/common/shelf/wm_shelf.h" #include "ash/common/shelf/wm_shelf_util.h" #include "grit/ash_resources.h" @@ -26,13 +27,13 @@ namespace ash { -OverflowButton::OverflowButton(InkDropButtonListener* listener, - WmShelf* wm_shelf) +OverflowButton::OverflowButton(ShelfView* shelf_view, WmShelf* wm_shelf) : CustomButton(nullptr), bottom_image_(nullptr), - listener_(listener), + shelf_view_(shelf_view), wm_shelf_(wm_shelf), background_alpha_(0) { + DCHECK(shelf_view_); if (MaterialDesignController::IsShelfMaterial()) { bottom_image_md_ = CreateVectorIcon(gfx::VectorIconId::SHELF_OVERFLOW, kShelfIconColor); @@ -65,8 +66,7 @@ void OverflowButton::NotifyClick(const ui::Event& event) { CustomButton::NotifyClick(event); - if (listener_) - listener_->ButtonPressed(this, event, ink_drop()); + shelf_view_->ButtonPressed(this, event, ink_drop()); } void OverflowButton::PaintBackground(gfx::Canvas* canvas, @@ -78,7 +78,7 @@ canvas->DrawRoundRect(bounds, kOverflowButtonCornerRadius, background_paint); - if (wm_shelf_->IsShowingOverflowBubble()) { + if (shelf_view_->IsShowingOverflowBubble()) { SkPaint highlight_paint; highlight_paint.setFlags(SkPaint::kAntiAlias_Flag); highlight_paint.setColor(kShelfButtonActivatedHighlightColor); @@ -123,7 +123,7 @@ } int OverflowButton::NonMaterialBackgroundImageId() { - if (wm_shelf_->IsShowingOverflowBubble()) + if (shelf_view_->IsShowingOverflowBubble()) return IDR_AURA_NOTIFICATION_BACKGROUND_PRESSED; else if (wm_shelf_->IsDimmed()) return IDR_AURA_NOTIFICATION_BACKGROUND_ON_BLACK;
diff --git a/ash/common/shelf/overflow_button.h b/ash/common/shelf/overflow_button.h index b96479f..7f77ea3 100644 --- a/ash/common/shelf/overflow_button.h +++ b/ash/common/shelf/overflow_button.h
@@ -10,13 +10,14 @@ #include "ui/views/controls/button/custom_button.h" namespace ash { -class InkDropButtonListener; +class ShelfView; class WmShelf; // Shelf overflow chevron button. class OverflowButton : public views::CustomButton { public: - OverflowButton(InkDropButtonListener* listener, WmShelf* wm_shelf); + // |shelf_view| is the view containing this button. + OverflowButton(ShelfView* shelf_view, WmShelf* wm_shelf); ~OverflowButton() override; void OnShelfAlignmentChanged(); @@ -58,7 +59,7 @@ gfx::ImageSkia left_image_; gfx::ImageSkia right_image_; - InkDropButtonListener* listener_; + ShelfView* shelf_view_; WmShelf* wm_shelf_; // Alpha value used to paint the background.
diff --git a/ash/common/shelf/shelf_tooltip_manager.cc b/ash/common/shelf/shelf_tooltip_manager.cc index adf34ca9..e84cb3a 100644 --- a/ash/common/shelf/shelf_tooltip_manager.cc +++ b/ash/common/shelf/shelf_tooltip_manager.cc
@@ -120,7 +120,8 @@ bubble_(nullptr), weak_factory_(this) { shelf_view_->wm_shelf()->AddObserver(this); - WmShell::Get()->AddPointerWatcher(this); + const bool wants_moves = false; + WmShell::Get()->AddPointerWatcher(this, wants_moves); } ShelfTooltipManager::~ShelfTooltipManager() {
diff --git a/ash/common/shelf/shelf_view.cc b/ash/common/shelf/shelf_view.cc index 935045d8b..673fb6e 100644 --- a/ash/common/shelf/shelf_view.cc +++ b/ash/common/shelf/shelf_view.cc
@@ -553,6 +553,82 @@ return gfx::Rect(origin, preferred_size); } +void ShelfView::ButtonPressed(views::Button* sender, + const ui::Event& event, + views::InkDrop* ink_drop) { + if (sender == overflow_button_) { + ToggleOverflowBubble(); + shelf_button_pressed_metric_tracker_.ButtonPressed( + event, sender, ShelfItemDelegate::kNoAction); + return; + } + + // None of the checks in ShouldEventActivateButton() affects overflow button. + // So, it is safe to be checked after handling overflow button. + if (!ShouldEventActivateButton(sender, event)) + return; + + // Record the index for the last pressed shelf item. + last_pressed_index_ = view_model_->GetIndexOfView(sender); + DCHECK_LT(-1, last_pressed_index_); + + // Place new windows on the same display as the button. + WmWindow* window = WmLookup::Get()->GetWindowForWidget(sender->GetWidget()); + scoped_root_window_for_new_windows_.reset( + new ScopedRootWindowForNewWindows(window->GetRootWindow())); + + // Slow down activation animations if shift key is pressed. + std::unique_ptr<ui::ScopedAnimationDurationScaleMode> slowing_animations; + if (event.IsShiftDown()) { + slowing_animations.reset(new ui::ScopedAnimationDurationScaleMode( + ui::ScopedAnimationDurationScaleMode::SLOW_DURATION)); + } + + // Collect usage statistics before we decide what to do with the click. + switch (model_->items()[last_pressed_index_].type) { + case TYPE_APP_SHORTCUT: + case TYPE_WINDOWED_APP: + case TYPE_PLATFORM_APP: + case TYPE_BROWSER_SHORTCUT: + WmShell::Get()->RecordUserMetricsAction(UMA_LAUNCHER_CLICK_ON_APP); + break; + + case TYPE_APP_LIST: + WmShell::Get()->RecordUserMetricsAction( + UMA_LAUNCHER_CLICK_ON_APPLIST_BUTTON); + break; + + case TYPE_APP_PANEL: + case TYPE_DIALOG: + case TYPE_IME_MENU: + break; + + case TYPE_UNDEFINED: + NOTREACHED() << "ShelfItemType must be set."; + break; + } + + ShelfItemDelegate::PerformedAction performed_action = + model_->GetShelfItemDelegate(model_->items()[last_pressed_index_].id) + ->ItemSelected(event); + + shelf_button_pressed_metric_tracker_.ButtonPressed(event, sender, + performed_action); + + // For the app list menu no TRIGGERED ink drop effect is needed and it + // handles its own ACTIVATED/DEACTIVATED states. + if (performed_action == ShelfItemDelegate::kNewWindowCreated || + (performed_action != ShelfItemDelegate::kAppListMenuShown && + !ShowListMenuForView(model_->items()[last_pressed_index_], sender, event, + ink_drop))) { + ink_drop->AnimateToState(views::InkDropState::ACTION_TRIGGERED); + } + // Allow the menu to clear |scoped_root_window_for_new_windows_| during + // OnMenuClosed. + if (!IsShowingMenu()) + scoped_root_window_for_new_windows_.reset(); +} + //////////////////////////////////////////////////////////////////////////////// // ShelfView, FocusTraversable implementation: @@ -1684,82 +1760,6 @@ void ShelfView::OnSetShelfItemDelegate(ShelfID id, ShelfItemDelegate* item_delegate) {} -void ShelfView::ButtonPressed(views::Button* sender, - const ui::Event& event, - views::InkDrop* ink_drop) { - if (sender == overflow_button_) { - ToggleOverflowBubble(); - shelf_button_pressed_metric_tracker_.ButtonPressed( - event, sender, ShelfItemDelegate::kNoAction); - return; - } - - // None of the checks in ShouldEventActivateButton() affects overflow button. - // So, it is safe to be checked after handling overflow button. - if (!ShouldEventActivateButton(sender, event)) - return; - - // Record the index for the last pressed shelf item. - last_pressed_index_ = view_model_->GetIndexOfView(sender); - DCHECK_LT(-1, last_pressed_index_); - - // Place new windows on the same display as the button. - WmWindow* window = WmLookup::Get()->GetWindowForWidget(sender->GetWidget()); - scoped_root_window_for_new_windows_.reset( - new ScopedRootWindowForNewWindows(window->GetRootWindow())); - - // Slow down activation animations if shift key is pressed. - std::unique_ptr<ui::ScopedAnimationDurationScaleMode> slowing_animations; - if (event.IsShiftDown()) { - slowing_animations.reset(new ui::ScopedAnimationDurationScaleMode( - ui::ScopedAnimationDurationScaleMode::SLOW_DURATION)); - } - - // Collect usage statistics before we decide what to do with the click. - switch (model_->items()[last_pressed_index_].type) { - case TYPE_APP_SHORTCUT: - case TYPE_WINDOWED_APP: - case TYPE_PLATFORM_APP: - case TYPE_BROWSER_SHORTCUT: - WmShell::Get()->RecordUserMetricsAction(UMA_LAUNCHER_CLICK_ON_APP); - break; - - case TYPE_APP_LIST: - WmShell::Get()->RecordUserMetricsAction( - UMA_LAUNCHER_CLICK_ON_APPLIST_BUTTON); - break; - - case TYPE_APP_PANEL: - case TYPE_DIALOG: - case TYPE_IME_MENU: - break; - - case TYPE_UNDEFINED: - NOTREACHED() << "ShelfItemType must be set."; - break; - } - - ShelfItemDelegate::PerformedAction performed_action = - model_->GetShelfItemDelegate(model_->items()[last_pressed_index_].id) - ->ItemSelected(event); - - shelf_button_pressed_metric_tracker_.ButtonPressed(event, sender, - performed_action); - - // For the app list menu no TRIGGERED ink drop effect is needed and it - // handles its own ACTIVATED/DEACTIVATED states. - if (performed_action == ShelfItemDelegate::kNewWindowCreated || - (performed_action != ShelfItemDelegate::kAppListMenuShown && - !ShowListMenuForView(model_->items()[last_pressed_index_], sender, event, - ink_drop))) { - ink_drop->AnimateToState(views::InkDropState::ACTION_TRIGGERED); - } - // Allow the menu to clear |scoped_root_window_for_new_windows_| during - // OnMenuClosed. - if (!IsShowingMenu()) - scoped_root_window_for_new_windows_.reset(); -} - bool ShelfView::ShowListMenuForView(const ShelfItem& item, views::View* source, const ui::Event& event,
diff --git a/ash/common/shelf/shelf_view.h b/ash/common/shelf/shelf_view.h index e5f0dec..a8be074 100644 --- a/ash/common/shelf/shelf_view.h +++ b/ash/common/shelf/shelf_view.h
@@ -122,6 +122,11 @@ // coordinate system. gfx::Rect GetVisibleItemsBoundsInScreen(); + // InkDropButtonListener: + void ButtonPressed(views::Button* sender, + const ui::Event& event, + views::InkDrop* ink_drop) override; + // Overridden from FocusTraversable: views::FocusSearch* GetFocusSearch() override; FocusTraversable* GetFocusTraversableParent() override; @@ -292,11 +297,6 @@ void OnSetShelfItemDelegate(ShelfID id, ShelfItemDelegate* item_delegate) override; - // Overridden from InkDropButtonListener: - void ButtonPressed(views::Button* sender, - const ui::Event& event, - views::InkDrop* ink_drop) override; - // Show a list of all running items for this shelf |item|; it only shows a // menu if there are multiple running items. |source| specifies the view // responsible for showing the menu, and the bubble will point towards it.
diff --git a/ash/common/shelf/wm_shelf.h b/ash/common/shelf/wm_shelf.h index df9f5c1..4bfd2cfb 100644 --- a/ash/common/shelf/wm_shelf.h +++ b/ash/common/shelf/wm_shelf.h
@@ -64,11 +64,6 @@ // require shelf dimming. http://crbug.com/614453 virtual bool IsDimmed() const = 0; - // Whether the shelf item overflow bubble is visible. - // TODO(jamescook): Eliminate when ShelfView moves to //ash/common. - // http://crbug.com/615155 - virtual bool IsShowingOverflowBubble() const = 0; - // Schedules a repaint for all shelf buttons. // TODO(jamescook): Eliminate when ShelfView moves to //ash/common. // http://crbug.com/615155
diff --git a/ash/common/system/audio/volume_view.cc b/ash/common/system/audio/volume_view.cc index 6435bac..ee36be3b 100644 --- a/ash/common/system/audio/volume_view.cc +++ b/ash/common/system/audio/volume_view.cc
@@ -15,6 +15,7 @@ #include "ash/common/wm_shell.h" #include "grit/ash_resources.h" #include "grit/ash_strings.h" +#include "ui/accessibility/ax_view_state.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/canvas.h" #include "ui/gfx/image/image_skia_operations.h" @@ -26,6 +27,7 @@ #include "ui/views/controls/image_view.h" #include "ui/views/controls/separator.h" #include "ui/views/layout/box_layout.h" +#include "ui/views/painter.h" namespace { const int kVolumeImageWidth = 25; @@ -54,6 +56,9 @@ : views::ToggleImageButton(listener), audio_delegate_(audio_delegate), image_index_(-1) { + SetFocusBehavior(FocusBehavior::ALWAYS); + SetFocusPainter(views::Painter::CreateSolidFocusPainter( + kFocusBorderColor, gfx::Insets(1, 1, 1, 1))); SetImageAlignment(ALIGN_CENTER, ALIGN_MIDDLE); image_ = ui::ResourceBundle::GetSharedInstance().GetImageNamed( IDR_AURA_UBER_TRAY_VOLUME_LEVELS); @@ -89,6 +94,14 @@ return size; } + void GetAccessibleState(ui::AXViewState* state) override { + ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); + state->name = bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_VOLUME_MUTE); + state->role = ui::AX_ROLE_TOGGLE_BUTTON; + if (audio_delegate_->IsOutputAudioMuted()) + state->AddStateFlag(ui::AX_STATE_PRESSED); + } + // views::CustomButton: void StateChanged() override { if (state() == STATE_HOVERED || state() == STATE_PRESSED) {
diff --git a/ash/common/system/cast/tray_cast.cc b/ash/common/system/cast/tray_cast.cc index eab2437..cf97576 100644 --- a/ash/common/system/cast/tray_cast.cc +++ b/ash/common/system/cast/tray_cast.cc
@@ -4,6 +4,7 @@ #include "ash/common/system/cast/tray_cast.h" +#include "ash/common/material_design/material_design_controller.h" #include "ash/common/session/session_state_delegate.h" #include "ash/common/shelf/shelf_types.h" #include "ash/common/shelf/wm_shelf_util.h" @@ -27,7 +28,9 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/image/image.h" +#include "ui/gfx/paint_vector_icon.h" #include "ui/gfx/text_elider.h" +#include "ui/gfx/vector_icons_public.h" #include "ui/views/controls/button/button.h" #include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" @@ -57,6 +60,14 @@ return elided; } +// Returns a vectorized version of the Cast icon. The icon's interior region is +// filled in if |is_casting| is true. +gfx::ImageSkia GetCastIconForSystemMenu(bool is_casting) { + return gfx::CreateVectorIcon( + gfx::VectorIconId::SYSTEM_MENU_CAST, + is_casting ? kMenuIconColor : SK_ColorTRANSPARENT); +} + } // namespace namespace tray { @@ -80,7 +91,11 @@ ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); // Update the image and label. - SetImage(rb.GetImageNamed(IDR_AURA_UBER_TRAY_CAST).ToImageSkia()); + if (MaterialDesignController::IsSystemTrayMenuMaterial()) + SetImage(GetCastIconForSystemMenu(false)); + else + SetImage(*rb.GetImageNamed(IDR_AURA_UBER_TRAY_CAST).ToImageSkia()); + base::string16 label = rb.GetLocalizedString(IDS_ASH_STATUS_TRAY_CAST_DESKTOP); SetLabel(label); @@ -136,8 +151,12 @@ kTrayPopupPaddingHorizontal, 0, kTrayPopupPaddingBetweenItems)); icon_ = new FixedSizedImageView(0, GetTrayConstant(TRAY_POPUP_ITEM_HEIGHT)); - icon_->SetImage( - bundle.GetImageNamed(IDR_AURA_UBER_TRAY_CAST_ENABLED).ToImageSkia()); + if (MaterialDesignController::IsSystemTrayMenuMaterial()) { + icon_->SetImage(GetCastIconForSystemMenu(true)); + } else { + icon_->SetImage( + bundle.GetImageNamed(IDR_AURA_UBER_TRAY_CAST_ENABLED).ToImageSkia()); + } AddChildView(icon_); // The label which describes both what we are casting (ie, the desktop) and @@ -342,10 +361,14 @@ CastTrayView::CastTrayView(SystemTrayItem* tray_item) : TrayItemView(tray_item) { CreateImageView(); - - image_view()->SetImage(ui::ResourceBundle::GetSharedInstance() - .GetImageNamed(IDR_AURA_UBER_TRAY_SCREENSHARE) - .ToImageSkia()); + if (MaterialDesignController::UseMaterialDesignSystemIcons()) { + image_view()->SetImage(gfx::CreateVectorIcon( + gfx::VectorIconId::SYSTEM_TRAY_CAST, kTrayIconColor)); + } else { + image_view()->SetImage(ui::ResourceBundle::GetSharedInstance() + .GetImageNamed(IDR_AURA_UBER_TRAY_SCREENSHARE) + .ToImageSkia()); + } } CastTrayView::~CastTrayView() {}
diff --git a/ash/common/system/chromeos/bluetooth/tray_bluetooth.cc b/ash/common/system/chromeos/bluetooth/tray_bluetooth.cc index bd967e1..9480fba 100644 --- a/ash/common/system/chromeos/bluetooth/tray_bluetooth.cc +++ b/ash/common/system/chromeos/bluetooth/tray_bluetooth.cc
@@ -73,7 +73,7 @@ if (!MaterialDesignController::IsSystemTrayMenuMaterial()) { ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); SetImage( - bundle.GetImageNamed(IDR_AURA_UBER_TRAY_BLUETOOTH).ToImageSkia()); + *bundle.GetImageNamed(IDR_AURA_UBER_TRAY_BLUETOOTH).ToImageSkia()); } Update(); } @@ -87,8 +87,7 @@ gfx::VectorIconId icon_id = enabled ? gfx::VectorIconId::SYSTEM_MENU_BLUETOOTH : gfx::VectorIconId::SYSTEM_MENU_BLUETOOTH_DISABLED; - gfx::ImageSkia image = gfx::CreateVectorIcon(icon_id, kMenuIconColor); - SetImage(&image); + SetImage(gfx::CreateVectorIcon(icon_id, kMenuIconColor)); } if (delegate->GetBluetoothAvailable()) {
diff --git a/ash/common/system/chromeos/network/tray_network.cc b/ash/common/system/chromeos/network/tray_network.cc index b094425..436a2a3 100644 --- a/ash/common/system/chromeos/network/tray_network.cc +++ b/ash/common/system/chromeos/network/tray_network.cc
@@ -158,7 +158,7 @@ else ui::network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver( this); - SetImage(&image); + SetImage(image); SetLabel(label); SetAccessibleName(label); }
diff --git a/ash/common/system/chromeos/network/tray_sms.cc b/ash/common/system/chromeos/network/tray_sms.cc index 25c90300..0087881 100644 --- a/ash/common/system/chromeos/network/tray_sms.cc +++ b/ash/common/system/chromeos/network/tray_sms.cc
@@ -62,11 +62,10 @@ public: explicit SmsDefaultView(TraySms* owner) : TrayItemMore(owner, true) { if (MaterialDesignController::UseMaterialDesignSystemIcons()) { - gfx::ImageSkia image_md = CreateVectorIcon( - gfx::VectorIconId::SYSTEM_MENU_SMS, kMenuIconSize, kMenuIconColor); - SetImage(&image_md); + SetImage(gfx::CreateVectorIcon(gfx::VectorIconId::SYSTEM_MENU_SMS, + kMenuIconSize, kMenuIconColor)); } else { - SetImage(ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( + SetImage(*ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed( IDR_AURA_UBER_TRAY_SMS)); } Update();
diff --git a/ash/common/system/chromeos/network/tray_vpn.cc b/ash/common/system/chromeos/network/tray_vpn.cc index bb797c6..9fefa14 100644 --- a/ash/common/system/chromeos/network/tray_vpn.cc +++ b/ash/common/system/chromeos/network/tray_vpn.cc
@@ -71,7 +71,7 @@ else ui::network_icon::NetworkIconAnimation::GetInstance()->RemoveObserver( this); - SetImage(&image); + SetImage(image); SetLabel(label); SetAccessibleName(label); }
diff --git a/ash/common/system/chromeos/palette/palette_tray.cc b/ash/common/system/chromeos/palette/palette_tray.cc index d28e7f7..95db0eb5 100644 --- a/ash/common/system/chromeos/palette/palette_tray.cc +++ b/ash/common/system/chromeos/palette/palette_tray.cc
@@ -4,13 +4,10 @@ #include "ash/common/system/chromeos/palette/palette_tray.h" -#include "ash/common/ash_switches.h" -#include "ash/common/material_design/material_design_controller.h" #include "ash/common/shelf/shelf_constants.h" #include "ash/common/shelf/wm_shelf.h" #include "ash/common/shelf/wm_shelf_util.h" #include "ash/common/shell_window_ids.h" -#include "ash/common/system/chromeos/palette/palette_tool.h" #include "ash/common/system/chromeos/palette/palette_tool_manager.h" #include "ash/common/system/chromeos/palette/palette_utils.h" #include "ash/common/system/tray/system_tray_delegate.h" @@ -21,8 +18,6 @@ #include "ash/common/wm_root_window_controller.h" #include "ash/common/wm_shell.h" #include "ash/common/wm_window.h" -#include "base/command_line.h" -#include "base/sys_info.h" #include "grit/ash_resources.h" #include "grit/ash_strings.h" #include "ui/base/l10n/l10n_util.h" @@ -60,46 +55,63 @@ return separator; } -// Creates the title-bar view. -views::View* CreateTitleView() { - auto& rb = ui::ResourceBundle::GetSharedInstance(); +class TitleView : public views::View, public views::ButtonListener { + public: + explicit TitleView(PaletteTray* palette_tray) : palette_tray_(palette_tray) { + auto& rb = ui::ResourceBundle::GetSharedInstance(); - auto* root = new views::View(); - auto* box_layout = - new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0); - root->SetLayoutManager(box_layout); - root->SetBorder(views::Border::CreateEmptyBorder( - 0, ash::kTrayPopupPaddingHorizontal, 0, 0)); + auto* box_layout = + new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0); + SetLayoutManager(box_layout); + SetBorder(views::Border::CreateEmptyBorder( + 0, ash::kTrayPopupPaddingHorizontal, 0, 0)); - views::Label* text_label = - new views::Label(l10n_util::GetStringUTF16(IDS_ASH_PALETTE_TITLE)); - text_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); - text_label->SetFontList(rb.GetFontList(ui::ResourceBundle::BoldFont)); - root->AddChildView(text_label); - box_layout->SetFlexForView(text_label, 1); + views::Label* text_label = + new views::Label(l10n_util::GetStringUTF16(IDS_ASH_PALETTE_TITLE)); + text_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); + text_label->SetFontList(rb.GetFontList(ui::ResourceBundle::BoldFont)); + AddChildView(text_label); + box_layout->SetFlexForView(text_label, 1); - // TODO(jdufault): Use proper icons. - ash::TrayPopupHeaderButton* help_button = new ash::TrayPopupHeaderButton( - nullptr, IDR_AURA_UBER_TRAY_SHUTDOWN, IDR_AURA_UBER_TRAY_SHUTDOWN, - IDR_AURA_UBER_TRAY_SHUTDOWN_HOVER, IDR_AURA_UBER_TRAY_SHUTDOWN_HOVER, - IDS_ASH_STATUS_TRAY_SHUTDOWN); - help_button->SetTooltipText( - l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SHUTDOWN)); - root->AddChildView(help_button); + help_button_ = new ash::TrayPopupHeaderButton(this, IDR_AURA_UBER_TRAY_HELP, + IDS_ASH_STATUS_TRAY_HELP); + help_button_->SetTooltipText( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SHUTDOWN)); + AddChildView(help_button_); - root->AddChildView(CreateSeparator(views::Separator::VERTICAL)); + AddChildView(CreateSeparator(views::Separator::VERTICAL)); - // TODO(jdufault): Use proper icons. - ash::TrayPopupHeaderButton* settings_button = new ash::TrayPopupHeaderButton( - nullptr, IDR_AURA_UBER_TRAY_SHUTDOWN, IDR_AURA_UBER_TRAY_SHUTDOWN, - IDR_AURA_UBER_TRAY_SHUTDOWN_HOVER, IDR_AURA_UBER_TRAY_SHUTDOWN_HOVER, - IDS_ASH_STATUS_TRAY_SHUTDOWN); - settings_button->SetTooltipText( - l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SHUTDOWN)); - root->AddChildView(settings_button); + settings_button_ = new ash::TrayPopupHeaderButton( + this, IDR_AURA_UBER_TRAY_SETTINGS, IDS_ASH_STATUS_TRAY_SETTINGS); + settings_button_->SetTooltipText( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SETTINGS)); + AddChildView(settings_button_); + } - return root; -} + ~TitleView() override {} + + private: + // views::ButtonListener: + void ButtonPressed(views::Button* sender, const ui::Event& event) override { + if (sender == settings_button_) { + WmShell::Get()->system_tray_delegate()->ShowPaletteSettings(); + palette_tray_->HidePalette(); + } else if (sender == help_button_) { + WmShell::Get()->system_tray_delegate()->ShowPaletteHelp(); + palette_tray_->HidePalette(); + } else { + NOTREACHED(); + } + } + + // Unowned pointers to button views so we can determine which button was + // clicked. + ash::TrayPopupHeaderButton* settings_button_; + ash::TrayPopupHeaderButton* help_button_; + PaletteTray* palette_tray_; + + DISALLOW_COPY_AND_ASSIGN(TitleView); +}; } // namespace @@ -158,7 +170,7 @@ bubble_view->set_margins(gfx::Insets(bubble_view->margins().top(), 0, 0, 0)); // Add child views. - bubble_view->AddChildView(CreateTitleView()); + bubble_view->AddChildView(new TitleView(this)); bubble_view->AddChildView(CreateSeparator(views::Separator::HORIZONTAL)); AddToolsToView(bubble_view);
diff --git a/ash/common/system/chromeos/palette/palette_tray.h b/ash/common/system/chromeos/palette/palette_tray.h index dcd387c..18d900a 100644 --- a/ash/common/system/chromeos/palette/palette_tray.h +++ b/ash/common/system/chromeos/palette/palette_tray.h
@@ -50,6 +50,9 @@ void SetShelfAlignment(ShelfAlignment alignment) override; void AnchorUpdated() override; + // PaletteToolManager::Delegate: + void HidePalette() override; + private: // views::TrayBubbleView::Delegate: void BubbleViewDestroyed() override; @@ -66,7 +69,6 @@ void HideBubble(const views::TrayBubbleView* bubble_view) override; // PaletteToolManager::Delegate: - void HidePalette() override; void OnActiveToolChanged() override; WmWindow* GetWindow() override;
diff --git a/ash/common/system/chromeos/screen_security/screen_capture_tray_item.cc b/ash/common/system/chromeos/screen_security/screen_capture_tray_item.cc index 74d8557..1b2193681 100644 --- a/ash/common/system/chromeos/screen_security/screen_capture_tray_item.cc +++ b/ash/common/system/chromeos/screen_security/screen_capture_tray_item.cc
@@ -38,13 +38,13 @@ } views::View* ScreenCaptureTrayItem::CreateTrayView(LoginStatus status) { - set_tray_view(new tray::ScreenTrayView(this, IDR_AURA_UBER_TRAY_SCREENSHARE)); + set_tray_view(new tray::ScreenTrayView(this)); return tray_view(); } views::View* ScreenCaptureTrayItem::CreateDefaultView(LoginStatus status) { set_default_view(new tray::ScreenStatusView( - this, IDR_AURA_UBER_TRAY_SCREENSHARE_DARK, screen_capture_status_, + this, screen_capture_status_, l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SCREEN_CAPTURE_STOP))); return default_view(); }
diff --git a/ash/common/system/chromeos/screen_security/screen_share_tray_item.cc b/ash/common/system/chromeos/screen_security/screen_share_tray_item.cc index 7af2ea85..663b3f3 100644 --- a/ash/common/system/chromeos/screen_security/screen_share_tray_item.cc +++ b/ash/common/system/chromeos/screen_security/screen_share_tray_item.cc
@@ -34,13 +34,13 @@ } views::View* ScreenShareTrayItem::CreateTrayView(LoginStatus status) { - set_tray_view(new tray::ScreenTrayView(this, IDR_AURA_UBER_TRAY_SCREENSHARE)); + set_tray_view(new tray::ScreenTrayView(this)); return tray_view(); } views::View* ScreenShareTrayItem::CreateDefaultView(LoginStatus status) { set_default_view(new tray::ScreenStatusView( - this, IDR_AURA_UBER_TRAY_SCREENSHARE_DARK, + this, l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SCREEN_SHARE_BEING_HELPED), l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SCREEN_SHARE_STOP))); return default_view();
diff --git a/ash/common/system/chromeos/screen_security/screen_tray_item.cc b/ash/common/system/chromeos/screen_security/screen_tray_item.cc index c9ea1ca8..4e03a029 100644 --- a/ash/common/system/chromeos/screen_security/screen_tray_item.cc +++ b/ash/common/system/chromeos/screen_security/screen_tray_item.cc
@@ -4,10 +4,14 @@ #include "ash/common/system/chromeos/screen_security/screen_tray_item.h" +#include "ash/common/material_design/material_design_controller.h" #include "ash/common/shelf/wm_shelf_util.h" #include "ash/common/system/tray/fixed_sized_image_view.h" #include "ash/common/system/tray/tray_constants.h" +#include "grit/ash_resources.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/paint_vector_icon.h" +#include "ui/gfx/vector_icons_public.h" #include "ui/message_center/message_center.h" #include "ui/views/controls/label.h" #include "ui/views/layout/box_layout.h" @@ -20,13 +24,17 @@ namespace tray { // ScreenTrayView implementations. -ScreenTrayView::ScreenTrayView(ScreenTrayItem* screen_tray_item, int icon_id) +ScreenTrayView::ScreenTrayView(ScreenTrayItem* screen_tray_item) : TrayItemView(screen_tray_item), screen_tray_item_(screen_tray_item) { CreateImageView(); - image_view()->SetImage(ui::ResourceBundle::GetSharedInstance() - .GetImageNamed(icon_id) - .ToImageSkia()); - + if (MaterialDesignController::UseMaterialDesignSystemIcons()) { + image_view()->SetImage(gfx::CreateVectorIcon( + gfx::VectorIconId::SYSTEM_TRAY_SCREEN_SHARE, kTrayIconColor)); + } else { + image_view()->SetImage(ui::ResourceBundle::GetSharedInstance() + .GetImageNamed(IDR_AURA_UBER_TRAY_SCREENSHARE) + .ToImageSkia()); + } Update(); } @@ -38,14 +46,12 @@ // ScreenStatusView implementations. ScreenStatusView::ScreenStatusView(ScreenTrayItem* screen_tray_item, - int icon_id, const base::string16& label_text, const base::string16& stop_button_text) : screen_tray_item_(screen_tray_item), icon_(NULL), label_(NULL), stop_button_(NULL), - icon_id_(icon_id), label_text_(label_text), stop_button_text_(stop_button_text) { CreateItems(); @@ -82,13 +88,21 @@ void ScreenStatusView::CreateItems() { set_background(views::Background::CreateSolidBackground(kBackgroundColor)); - ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, kTrayPopupPaddingHorizontal, 0, kTrayPopupPaddingBetweenItems)); + icon_ = new FixedSizedImageView(0, GetTrayConstant(TRAY_POPUP_ITEM_HEIGHT)); - icon_->SetImage(bundle.GetImageNamed(icon_id_).ToImageSkia()); + if (MaterialDesignController::IsSystemTrayMenuMaterial()) { + icon_->SetImage(gfx::CreateVectorIcon( + gfx::VectorIconId::SYSTEM_MENU_SCREEN_SHARE, kMenuIconColor)); + } else { + ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); + icon_->SetImage(bundle.GetImageNamed(IDR_AURA_UBER_TRAY_SCREENSHARE_DARK) + .ToImageSkia()); + } AddChildView(icon_); + label_ = new views::Label; label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); label_->SetMultiLine(true);
diff --git a/ash/common/system/chromeos/screen_security/screen_tray_item.h b/ash/common/system/chromeos/screen_security/screen_tray_item.h index 0659099..7f2908f5 100644 --- a/ash/common/system/chromeos/screen_security/screen_tray_item.h +++ b/ash/common/system/chromeos/screen_security/screen_tray_item.h
@@ -28,7 +28,7 @@ class ScreenTrayView : public TrayItemView { public: - ScreenTrayView(ScreenTrayItem* screen_tray_item, int icon_id); + explicit ScreenTrayView(ScreenTrayItem* screen_tray_item); ~ScreenTrayView() override; void Update(); @@ -42,7 +42,6 @@ class ScreenStatusView : public views::View, public views::ButtonListener { public: ScreenStatusView(ScreenTrayItem* screen_tray_item, - int icon_id, const base::string16& label_text, const base::string16& stop_button_text); ~ScreenStatusView() override; @@ -61,7 +60,6 @@ views::ImageView* icon_; views::Label* label_; TrayPopupLabelButton* stop_button_; - int icon_id_; base::string16 label_text_; base::string16 stop_button_text_;
diff --git a/ash/common/system/ime/tray_ime_chromeos.cc b/ash/common/system/ime/tray_ime_chromeos.cc index 72df307..c511230 100644 --- a/ash/common/system/ime/tray_ime_chromeos.cc +++ b/ash/common/system/ime/tray_ime_chromeos.cc
@@ -70,7 +70,7 @@ explicit IMEDefaultView(SystemTrayItem* owner, const base::string16& label) : TrayItemMore(owner, true) { ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); - SetImage(bundle.GetImageNamed(IDR_AURA_UBER_TRAY_IME).ToImageSkia()); + SetImage(*bundle.GetImageNamed(IDR_AURA_UBER_TRAY_IME).ToImageSkia()); UpdateLabel(label); }
diff --git a/ash/common/system/tray/system_tray_delegate.cc b/ash/common/system/tray/system_tray_delegate.cc index 85e7fd3..dd481ab3 100644 --- a/ash/common/system/tray/system_tray_delegate.cc +++ b/ash/common/system/tray/system_tray_delegate.cc
@@ -113,6 +113,10 @@ void SystemTrayDelegate::ShowAccessibilitySettings() {} +void SystemTrayDelegate::ShowPaletteHelp() {} + +void SystemTrayDelegate::ShowPaletteSettings() {} + void SystemTrayDelegate::ShowPublicAccountInfo() {} void SystemTrayDelegate::ShowEnterpriseInfo() {}
diff --git a/ash/common/system/tray/system_tray_delegate.h b/ash/common/system/tray/system_tray_delegate.h index da9b78aa..94c98484 100644 --- a/ash/common/system/tray/system_tray_delegate.h +++ b/ash/common/system/tray/system_tray_delegate.h
@@ -189,6 +189,12 @@ // Show the settings related to accessilibity. virtual void ShowAccessibilitySettings(); + // Shows the help center article for palette. + virtual void ShowPaletteHelp(); + + // Shows the settings related to the palette. + virtual void ShowPaletteSettings(); + // Shows more information about public account mode. virtual void ShowPublicAccountInfo();
diff --git a/ash/common/system/tray/tray_background_view.cc b/ash/common/system/tray/tray_background_view.cc index 4d209a5..e6393764 100644 --- a/ash/common/system/tray/tray_background_view.cc +++ b/ash/common/system/tray/tray_background_view.cc
@@ -174,6 +174,11 @@ UpdateLayout(); } +void TrayBackgroundView::TrayContainer::SetMargin(const gfx::Insets& margin) { + margin_ = margin; + UpdateLayout(); +} + gfx::Size TrayBackgroundView::TrayContainer::GetPreferredSize() const { if (size_.IsEmpty()) return views::View::GetPreferredSize(); @@ -206,8 +211,9 @@ // Additional padding used to adjust the user-visible size of status tray // dark background. const int padding = 3; - SetBorder( - views::Border::CreateEmptyBorder(padding, padding, padding, padding)); + SetBorder(views::Border::CreateEmptyBorder(gfx::Insets(padding) + margin_)); + } else { + SetBorder(views::Border::CreateEmptyBorder(margin_)); } views::BoxLayout* layout = new views::BoxLayout(orientation, 0, 0, 0);
diff --git a/ash/common/system/tray/tray_background_view.h b/ash/common/system/tray/tray_background_view.h index 905a083c..74141740 100644 --- a/ash/common/system/tray/tray_background_view.h +++ b/ash/common/system/tray/tray_background_view.h
@@ -43,6 +43,8 @@ void set_size(const gfx::Size& size) { size_ = size; } + void SetMargin(const gfx::Insets& margin); + // views::View: gfx::Size GetPreferredSize() const override; @@ -58,6 +60,7 @@ ShelfAlignment alignment_; gfx::Size size_; + gfx::Insets margin_; DISALLOW_COPY_AND_ASSIGN(TrayContainer); };
diff --git a/ash/common/system/tray/tray_event_filter.cc b/ash/common/system/tray/tray_event_filter.cc index 8f83890..9f2c3d6 100644 --- a/ash/common/system/tray/tray_event_filter.cc +++ b/ash/common/system/tray/tray_event_filter.cc
@@ -24,8 +24,10 @@ void TrayEventFilter::AddWrapper(TrayBubbleWrapper* wrapper) { bool was_empty = wrappers_.empty(); wrappers_.insert(wrapper); - if (was_empty && !wrappers_.empty()) - WmShell::Get()->AddPointerWatcher(this); + if (was_empty && !wrappers_.empty()) { + const bool wants_moves = false; + WmShell::Get()->AddPointerWatcher(this, wants_moves); + } } void TrayEventFilter::RemoveWrapper(TrayBubbleWrapper* wrapper) {
diff --git a/ash/common/system/tray/tray_item_more.cc b/ash/common/system/tray/tray_item_more.cc index 7d901c3..d9b8244 100644 --- a/ash/common/system/tray/tray_item_more.cc +++ b/ash/common/system/tray/tray_item_more.cc
@@ -60,7 +60,7 @@ SchedulePaint(); } -void TrayItemMore::SetImage(const gfx::ImageSkia* image_skia) { +void TrayItemMore::SetImage(const gfx::ImageSkia& image_skia) { icon_->SetImage(image_skia); SchedulePaint(); }
diff --git a/ash/common/system/tray/tray_item_more.h b/ash/common/system/tray/tray_item_more.h index 26b7b88..918d3c3 100644 --- a/ash/common/system/tray/tray_item_more.h +++ b/ash/common/system/tray/tray_item_more.h
@@ -28,7 +28,7 @@ SystemTrayItem* owner() const { return owner_; } void SetLabel(const base::string16& label); - void SetImage(const gfx::ImageSkia* image_skia); + void SetImage(const gfx::ImageSkia& image_skia); void SetAccessibleName(const base::string16& name); protected:
diff --git a/ash/common/system/tray/tray_notification_view.cc b/ash/common/system/tray/tray_notification_view.cc index 049d0f8d..0d7fe29d 100644 --- a/ash/common/system/tray/tray_notification_view.cc +++ b/ash/common/system/tray/tray_notification_view.cc
@@ -65,8 +65,8 @@ icon_ = new views::ImageView; if (icon_id_ != 0) { if (MaterialDesignController::UseMaterialDesignSystemIcons()) { - icon_->SetImage(CreateVectorIcon(ResourceIdToVectorIconId(icon_id_), - kMenuIconSize, kMenuIconColor)); + icon_->SetImage(gfx::CreateVectorIcon(ResourceIdToVectorIconId(icon_id_), + kMenuIconColor)); } else { icon_->SetImage( ResourceBundle::GetSharedInstance().GetImageSkiaNamed(icon_id_));
diff --git a/ash/common/system/tray/tray_popup_header_button.cc b/ash/common/system/tray/tray_popup_header_button.cc index b37cae2..bb15d503 100644 --- a/ash/common/system/tray/tray_popup_header_button.cc +++ b/ash/common/system/tray/tray_popup_header_button.cc
@@ -17,22 +17,12 @@ "tray/TrayPopupHeaderButton"; TrayPopupHeaderButton::TrayPopupHeaderButton(views::ButtonListener* listener, - int enabled_resource_id, - int disabled_resource_id, - int enabled_resource_id_hover, - int disabled_resource_id_hover, + int icon_resource_id, int accessible_name_id) : views::ToggleImageButton(listener) { ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); SetImage(views::Button::STATE_NORMAL, - bundle.GetImageNamed(enabled_resource_id).ToImageSkia()); - SetToggledImage(views::Button::STATE_NORMAL, - bundle.GetImageNamed(disabled_resource_id).ToImageSkia()); - SetImage(views::Button::STATE_HOVERED, - bundle.GetImageNamed(enabled_resource_id_hover).ToImageSkia()); - SetToggledImage( - views::Button::STATE_HOVERED, - bundle.GetImageNamed(disabled_resource_id_hover).ToImageSkia()); + bundle.GetImageNamed(icon_resource_id).ToImageSkia()); SetImageAlignment(views::ImageButton::ALIGN_CENTER, views::ImageButton::ALIGN_MIDDLE); SetAccessibleName(bundle.GetLocalizedString(accessible_name_id)); @@ -42,6 +32,23 @@ kFocusBorderColor, gfx::Insets(1, 2, 2, 3))); } +TrayPopupHeaderButton::TrayPopupHeaderButton(views::ButtonListener* listener, + int enabled_resource_id, + int disabled_resource_id, + int enabled_resource_id_hover, + int disabled_resource_id_hover, + int accessible_name_id) + : TrayPopupHeaderButton(listener, enabled_resource_id, accessible_name_id) { + ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); + SetToggledImage(views::Button::STATE_NORMAL, + bundle.GetImageNamed(disabled_resource_id).ToImageSkia()); + SetImage(views::Button::STATE_HOVERED, + bundle.GetImageNamed(enabled_resource_id_hover).ToImageSkia()); + SetToggledImage( + views::Button::STATE_HOVERED, + bundle.GetImageNamed(disabled_resource_id_hover).ToImageSkia()); +} + TrayPopupHeaderButton::~TrayPopupHeaderButton() {} const char* TrayPopupHeaderButton::GetClassName() const {
diff --git a/ash/common/system/tray/tray_popup_header_button.h b/ash/common/system/tray/tray_popup_header_button.h index 1041ffc6..1777d45 100644 --- a/ash/common/system/tray/tray_popup_header_button.h +++ b/ash/common/system/tray/tray_popup_header_button.h
@@ -18,6 +18,9 @@ static const char kViewClassName[]; TrayPopupHeaderButton(views::ButtonListener* listener, + int icon_resource_id, + int accessible_name_id); + TrayPopupHeaderButton(views::ButtonListener* listener, int enabled_resource_id, int disabled_resource_id, int enabled_resource_id_hover,
diff --git a/ash/common/system/tray_accessibility.cc b/ash/common/system/tray_accessibility.cc index b078698..16115fff 100644 --- a/ash/common/system/tray_accessibility.cc +++ b/ash/common/system/tray_accessibility.cc
@@ -78,13 +78,11 @@ : TrayItemMore(owner, true) { ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); if (MaterialDesignController::UseMaterialDesignSystemIcons()) { - gfx::ImageSkia image_md = - CreateVectorIcon(gfx::VectorIconId::SYSTEM_MENU_ACCESSIBILITY, - kMenuIconSize, kMenuIconColor); - SetImage(&image_md); + SetImage(gfx::CreateVectorIcon( + gfx::VectorIconId::SYSTEM_MENU_ACCESSIBILITY, kMenuIconColor)); } else { - SetImage(bundle.GetImageNamed(IDR_AURA_UBER_TRAY_ACCESSIBILITY_DARK) - .ToImageSkia()); + SetImage(*bundle.GetImageNamed(IDR_AURA_UBER_TRAY_ACCESSIBILITY_DARK) + .ToImageSkia()); } base::string16 label = bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_ACCESSIBILITY);
diff --git a/ash/common/system/web_notification/web_notification_tray.cc b/ash/common/system/web_notification/web_notification_tray.cc index 9b7d7d2..fca5dea 100644 --- a/ash/common/system/web_notification/web_notification_tray.cc +++ b/ash/common/system/web_notification/web_notification_tray.cc
@@ -62,8 +62,22 @@ namespace { // Menu commands -const int kToggleQuietMode = 0; -const int kEnableQuietModeDay = 2; +constexpr int kToggleQuietMode = 0; +constexpr int kEnableQuietModeDay = 2; + +constexpr int kMaximumSmallIconCount = 3; + +constexpr gfx::Size kTrayItemInnerIconSize(16, 16); +constexpr gfx::Size kTrayItemInnerBellIconSize(18, 18); +constexpr gfx::Size kTrayItemOuterSize(26, 26); +constexpr gfx::Insets kTrayItemInsets(3, 3); + +constexpr int kTrayItemAnimationDurationMS = 200; + +constexpr size_t kMaximumNotificationNumber = 99; + +// Flag to disable animation. Only for testing. +bool disable_animations_for_test = false; } namespace { @@ -114,89 +128,169 @@ DISALLOW_COPY_AND_ASSIGN(WebNotificationBubbleWrapper); }; -class WebNotificationIcon : public views::View { +class WebNotificationItem : public views::View, public gfx::AnimationDelegate { public: - WebNotificationIcon() : is_bubble_visible_(false), unread_count_(0) { + WebNotificationItem(gfx::AnimationContainer* container, + WebNotificationTray* tray) + : tray_(tray) { + SetPaintToLayer(true); + layer()->SetFillsBoundsOpaquely(false); + views::View::SetVisible(false); + set_owned_by_client(); + SetLayoutManager(new views::FillLayout); - gfx::ImageSkia image; - if (MaterialDesignController::IsShelfMaterial()) { - image = CreateVectorIcon(gfx::VectorIconId::SHELF_NOTIFICATIONS, - kShelfIconColor); - } else { - image = - CreateVectorIcon(gfx::VectorIconId::NOTIFICATIONS, kNoUnreadIconSize, - kWebNotificationColorNoUnread); + animation_.reset(new gfx::SlideAnimation(this)); + animation_->SetContainer(container); + animation_->SetSlideDuration(kTrayItemAnimationDurationMS); + animation_->SetTweenType(gfx::Tween::LINEAR); + } + + void SetVisible(bool set_visible) override { + if (!GetWidget() || disable_animations_for_test) { + views::View::SetVisible(set_visible); + return; } - no_unread_icon_.SetImage(image); - no_unread_icon_.set_owned_by_client(); - - unread_label_.set_owned_by_client(); - SetupLabelForTray(&unread_label_); - - AddChildView(&no_unread_icon_); + if (!set_visible) { + animation_->Hide(); + AnimationProgressed(animation_.get()); + } else { + animation_->Show(); + AnimationProgressed(animation_.get()); + views::View::SetVisible(true); + } } - void SetBubbleVisible(bool visible) { - if (visible == is_bubble_visible_) - return; + void HideAndDelete() { + SetVisible(false); - is_bubble_visible_ = visible; - UpdateIconVisibility(); - } - - void SetUnreadCount(int unread_count) { - // base::FormatNumber doesn't convert to arabic numeric characters. - // TODO(mukai): use ICU to support conversion for such locales. - unread_count_ = unread_count; - UpdateIconVisibility(); + if (!visible() && !animation_->is_animating()) { + if (parent()) + parent()->RemoveChildView(this); + base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); + } else { + delete_after_animation_ = true; + } } protected: // Overridden from views::View: gfx::Size GetPreferredSize() const override { - const int size = GetTrayConstant(TRAY_ITEM_HEIGHT_LEGACY); - return gfx::Size(size, size); + if (!animation_.get() || !animation_->is_animating()) + return kTrayItemOuterSize; + + // Animate the width (or height) when this item shows (or hides) so that + // the icons on the left are shifted with the animation. + // Note that TrayItemView does the same thing. + gfx::Size size = kTrayItemOuterSize; + if (IsHorizontalLayout()) { + size.set_width(std::max( + 1, gfx::ToRoundedInt(size.width() * animation_->GetCurrentValue()))); + } else { + size.set_height(std::max( + 1, gfx::ToRoundedInt(size.height() * animation_->GetCurrentValue()))); + } + return size; } int GetHeightForWidth(int width) const override { return GetPreferredSize().height(); } - private: - void UpdateIconVisibility() { - if (unread_count_ == 0) { - if (!Contains(&no_unread_icon_)) { - RemoveAllChildViews(false /* delete_children */); - AddChildView(&no_unread_icon_); - } - } else { - if (!Contains(&unread_label_)) { - RemoveAllChildViews(false /* delete_children */); - AddChildView(&unread_label_); - } + bool IsHorizontalLayout() const { + return IsHorizontalAlignment(tray_->shelf_alignment()); + } - // TODO(mukai): move NINE_PLUS message to ui_strings, it doesn't need to - // be in ash_strings. - unread_label_.SetText( - (unread_count_ > 9) ? l10n_util::GetStringUTF16( - IDS_ASH_NOTIFICATION_UNREAD_COUNT_NINE_PLUS) - : base::FormatNumber(unread_count_)); - unread_label_.SetEnabledColor((unread_count_ > 0) - ? kWebNotificationColorWithUnread - : kWebNotificationColorNoUnread); + private: + // gfx::AnimationDelegate: + void AnimationProgressed(const gfx::Animation* animation) override { + gfx::Transform transform; + if (IsHorizontalLayout()) { + transform.Translate(0, animation->CurrentValueBetween( + static_cast<double>(height()) / 2., 0.)); + } else { + transform.Translate( + animation->CurrentValueBetween(static_cast<double>(width() / 2.), 0.), + 0); } + transform.Scale(animation->GetCurrentValue(), animation->GetCurrentValue()); + layer()->SetTransform(transform); + PreferredSizeChanged(); + } + void AnimationEnded(const gfx::Animation* animation) override { + if (animation->GetCurrentValue() < 0.1) + views::View::SetVisible(false); + + if (delete_after_animation_) { + if (parent()) + parent()->RemoveChildView(this); + base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); + } + } + void AnimationCanceled(const gfx::Animation* animation) override { + AnimationEnded(animation); + } + + std::unique_ptr<gfx::SlideAnimation> animation_; + bool delete_after_animation_ = false; + WebNotificationTray* tray_; + + DISALLOW_COPY_AND_ASSIGN(WebNotificationItem); +}; + +class WebNotificationImage : public WebNotificationItem { + public: + WebNotificationImage(const gfx::ImageSkia& image, + gfx::Size size, + gfx::AnimationContainer* container, + WebNotificationTray* tray) + : WebNotificationItem(container, tray) { + view_ = new views::ImageView(); + view_->SetImage(image); + view_->SetImageSize(size); + AddChildView(view_); + } + + private: + views::ImageView* view_; + + DISALLOW_COPY_AND_ASSIGN(WebNotificationImage); +}; + +class WebNotificationLabel : public WebNotificationItem { + public: + WebNotificationLabel(gfx::AnimationContainer* container, + WebNotificationTray* tray) + : WebNotificationItem(container, tray) { + view_ = new views::Label(); + SetupLabelForTray(view_); + AddChildView(view_); + } + + void SetNotificationCount(bool small_icons_exist, size_t notification_count) { + notification_count = std::min(notification_count, + kMaximumNotificationNumber); // cap with 99 + + // TODO(yoshiki): Use a string for "99" and "+99". + + base::string16 str = base::FormatNumber(notification_count); + if (small_icons_exist) { + if (!base::i18n::IsRTL()) + str = base::ASCIIToUTF16("+") + str; + else + str = str + base::ASCIIToUTF16("+"); + } + + view_->SetText(str); + view_->SetEnabledColor(kWebNotificationColorWithUnread); SchedulePaint(); } - bool is_bubble_visible_; - int unread_count_; + private: + views::Label* view_; - views::ImageView no_unread_icon_; - views::Label unread_label_; - - DISALLOW_COPY_AND_ASSIGN(WebNotificationIcon); + DISALLOW_COPY_AND_ASSIGN(WebNotificationLabel); }; WebNotificationTray::WebNotificationTray(WmShelf* shelf, @@ -205,7 +299,6 @@ : TrayBackgroundView(shelf), status_area_window_(status_area_window), system_tray_(system_tray), - icon_(new WebNotificationIcon), show_message_center_on_unlock_(false), should_update_tray_content_(false), should_block_shelf_auto_hide_(false) { @@ -213,7 +306,23 @@ DCHECK(status_area_window_); DCHECK(system_tray_); - tray_container()->AddChildView(icon_); + gfx::ImageSkia bell_image; + if (MaterialDesignController::IsShelfMaterial()) { + bell_image = CreateVectorIcon(gfx::VectorIconId::SHELF_NOTIFICATIONS, + kShelfIconColor); + } else { + bell_image = + CreateVectorIcon(gfx::VectorIconId::NOTIFICATIONS, kNoUnreadIconSize, + kWebNotificationColorNoUnread); + } + bell_icon_.reset(new WebNotificationImage(bell_image, + kTrayItemInnerBellIconSize, + animation_container_.get(), this)); + tray_container()->AddChildView(bell_icon_.get()); + + counter_.reset(new WebNotificationLabel(animation_container_.get(), this)); + tray_container()->AddChildView(counter_.get()); + SetContentsBackground(); tray_container()->SetBorder(views::Border::NullBorder()); message_center_tray_.reset(new message_center::MessageCenterTray( @@ -227,6 +336,8 @@ popup_alignment_delegate_->StartObserving(display::Screen::GetScreen(), display); OnMessageCenterTrayChanged(); + + tray_container()->SetMargin(kTrayItemInsets); } WebNotificationTray::~WebNotificationTray() { @@ -236,6 +347,11 @@ popup_collection_.reset(); } +// static +void WebNotificationTray::DisableAnimationsForTest(bool disable) { + disable_animations_for_test = disable; +} + // Public methods. bool WebNotificationTray::ShowMessageCenterInternal(bool show_settings) { @@ -248,7 +364,7 @@ message_center_tray_.get(), true); int max_height; - if (IsHorizontalAlignment(shelf()->GetAlignment())) { + if (IsHorizontalAlignment(shelf_alignment())) { max_height = shelf()->GetIdealBounds().y(); } else { // Assume the status area and bubble bottoms are aligned when vertical. @@ -266,7 +382,6 @@ system_tray_->SetHideNotifications(true); shelf()->UpdateAutoHideState(); - icon_->SetBubbleVisible(true); SetDrawBackgroundAsActive(true); return true; } @@ -284,7 +399,6 @@ show_message_center_on_unlock_ = false; system_tray_->SetHideNotifications(false); shelf()->UpdateAutoHideState(); - icon_->SetBubbleVisible(false); } void WebNotificationTray::SetTrayBubbleHeight(int height) { @@ -470,11 +584,61 @@ return; should_update_tray_content_ = false; + std::unordered_set<std::string> notification_ids; + for (auto pair : visible_small_icons_) + notification_ids.insert(pair.first); + + // Add small icons (up to kMaximumSmallIconCount = 3). message_center::MessageCenter* message_center = message_center_tray_->message_center(); - icon_->SetUnreadCount(message_center->UnreadNotificationCount()); + size_t visible_small_icon_count = 0; + for (const auto* notification : message_center->GetVisibleNotifications()) { + gfx::Image image = notification->small_image(); + if (image.IsEmpty()) + continue; + + if (visible_small_icon_count >= kMaximumSmallIconCount) + break; + visible_small_icon_count++; + + notification_ids.erase(notification->id()); + if (visible_small_icons_.count(notification->id()) != 0) + continue; + + auto* item = + new WebNotificationImage(image.AsImageSkia(), kTrayItemInnerIconSize, + animation_container_.get(), this); + visible_small_icons_.insert(std::make_pair(notification->id(), item)); + + tray_container()->AddChildViewAt(item, 0); + item->SetVisible(true); + } + + // Remove unnecessary icons. + for (const std::string& id : notification_ids) { + WebNotificationImage* item = visible_small_icons_[id]; + visible_small_icons_.erase(id); + item->HideAndDelete(); + } + + // Show or hide the bell icon. + size_t visible_notification_count = message_center->NotificationCount(); + bell_icon_->SetVisible(visible_notification_count == 0); + + // Show or hide the counter. + size_t hidden_icon_count = + visible_notification_count - visible_small_icon_count; + if (hidden_icon_count != 0) { + counter_->SetVisible(true); + counter_->SetNotificationCount( + (visible_small_icon_count != 0), // small_icons_exist + hidden_icon_count); + } else { + counter_->SetVisible(false); + } SetVisible(IsLoggedIn()); + PreferredSizeChanged(); Layout(); SchedulePaint(); if (IsLoggedIn())
diff --git a/ash/common/system/web_notification/web_notification_tray.h b/ash/common/system/web_notification/web_notification_tray.h index 1d13ffcf..0817c97 100644 --- a/ash/common/system/web_notification/web_notification_tray.h +++ b/ash/common/system/web_notification/web_notification_tray.h
@@ -14,6 +14,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "ui/base/models/simple_menu_model.h" +#include "ui/gfx/animation/animation_container.h" #include "ui/message_center/message_center_tray.h" #include "ui/message_center/message_center_tray_delegate.h" #include "ui/views/bubble/tray_bubble_view.h" @@ -41,7 +42,9 @@ class AshPopupAlignmentDelegate; class SystemTray; class WebNotificationBubbleWrapper; -class WebNotificationIcon; +class WebNotificationButton; +class WebNotificationImage; +class WebNotificationLabel; class WmWindow; class ASH_EXPORT WebNotificationTray @@ -56,6 +59,8 @@ SystemTray* system_tray); ~WebNotificationTray() override; + static void DisableAnimationsForTest(bool disable); + // Sets the height of the system tray bubble (or legacy notification bubble) // from the edge of the work area so that the web notification popups don't // overlap with the tray. Pass 0 if no bubble is shown. @@ -113,7 +118,7 @@ bool IsContextMenuEnabled() const override; message_center::MessageCenterTray* GetMessageCenterTray() override; - // Overridden from SimpleMenuModel::Delegate. + // Overridden from ui::SimpleMenuModel::Delegate. bool IsCommandIdChecked(int command_id) const override; bool IsCommandIdEnabled(int command_id) const override; void ExecuteCommand(int command_id, int event_flags) override; @@ -169,7 +174,13 @@ std::unique_ptr<message_center::MessageCenterTray> message_center_tray_; std::unique_ptr<WebNotificationBubbleWrapper> message_center_bubble_; std::unique_ptr<message_center::MessagePopupCollection> popup_collection_; - WebNotificationIcon* icon_; + std::unique_ptr<WebNotificationImage> bell_icon_; + std::unique_ptr<WebNotificationLabel> counter_; + + scoped_refptr<gfx::AnimationContainer> animation_container_ = + new gfx::AnimationContainer(); + + std::unordered_map<std::string, WebNotificationImage*> visible_small_icons_; bool show_message_center_on_unlock_;
diff --git a/ash/common/wm/maximize_mode/maximize_mode_window_manager.cc b/ash/common/wm/maximize_mode/maximize_mode_window_manager.cc index 3e2b9625..bb97c7d6 100644 --- a/ash/common/wm/maximize_mode/maximize_mode_window_manager.cc +++ b/ash/common/wm/maximize_mode/maximize_mode_window_manager.cc
@@ -57,7 +57,8 @@ void MaximizeModeWindowManager::AddWindow(WmWindow* window) { // Only add the window if it is a direct dependent of a container window // and not yet tracked. - if (!ShouldHandleWindow(window) || ContainsKey(window_state_map_, window) || + if (!ShouldHandleWindow(window) || + base::ContainsKey(window_state_map_, window) || !IsContainerWindow(window->GetParent())) { return; } @@ -110,11 +111,11 @@ const TreeChangeParams& params) { // A window can get removed and then re-added by a drag and drop operation. if (params.new_parent && IsContainerWindow(params.new_parent) && - !ContainsKey(window_state_map_, params.target)) { + !base::ContainsKey(window_state_map_, params.target)) { MaximizeAndTrackWindow(params.target); // When the state got added, the "WM_EVENT_ADDED_TO_WORKSPACE" event got // already sent and we have to notify our state again. - if (ContainsKey(window_state_map_, params.target)) { + if (base::ContainsKey(window_state_map_, params.target)) { wm::WMEvent event(wm::WM_EVENT_ADDED_TO_WORKSPACE); params.target->GetWindowState()->OnWMEvent(&event); } @@ -192,7 +193,7 @@ if (!ShouldHandleWindow(window)) return; - DCHECK(!ContainsKey(window_state_map_, window)); + DCHECK(!base::ContainsKey(window_state_map_, window)); window->AddObserver(this); // We create and remember a maximize mode state which will attach itself to @@ -212,7 +213,7 @@ // By telling the state object to revert, it will switch back the old // State object and destroy itself, calling WindowStateDestroyed(). it->second->LeaveMaximizeMode(it->first->GetWindowState()); - DCHECK(!ContainsKey(window_state_map_, window)); + DCHECK(!base::ContainsKey(window_state_map_, window)); } bool MaximizeModeWindowManager::ShouldHandleWindow(WmWindow* window) { @@ -237,7 +238,7 @@ for (WmWindow* root : WmShell::Get()->GetAllRootWindows()) { WmWindow* default_container = root->GetChildByShellWindowId(kShellWindowId_DefaultContainer); - DCHECK(!ContainsKey(observed_container_windows_, default_container)); + DCHECK(!base::ContainsKey(observed_container_windows_, default_container)); default_container->AddObserver(this); observed_container_windows_.insert(default_container); } @@ -257,7 +258,7 @@ } bool MaximizeModeWindowManager::IsContainerWindow(WmWindow* window) { - return ContainsKey(observed_container_windows_, window); + return base::ContainsKey(observed_container_windows_, window); } void MaximizeModeWindowManager::EnableBackdropBehindTopWindowOnEachDisplay(
diff --git a/ash/common/wm/panels/panel_layout_manager.cc b/ash/common/wm/panels/panel_layout_manager.cc index 0aeb65c3..99f9384 100644 --- a/ash/common/wm/panels/panel_layout_manager.cc +++ b/ash/common/wm/panels/panel_layout_manager.cc
@@ -212,6 +212,9 @@ set_focus_on_creation(false); Init(params); WmWindow* widget_window = WmLookup::Get()->GetWindowForWidget(this); + // TODO(sky): used for tracking down http://crbug.com/636113, remove once + // resolved. + CHECK(widget_window->GetParent() == parent); DCHECK_EQ(widget_window->GetRootWindow(), parent->GetRootWindow()); views::View* content_view = new views::View; background_ = new CalloutWidgetBackground; @@ -269,9 +272,12 @@ shelf_->RemoveObserver(this); shelf_ = nullptr; } - for (PanelList::iterator iter = panel_windows_.begin(); - iter != panel_windows_.end(); ++iter) { - delete iter->callout_widget; + { + base::AutoReset<bool> auto_reset(&is_deleting_callout_widgets_, true); + for (PanelList::iterator iter = panel_windows_.begin(); + iter != panel_windows_.end(); ++iter) { + delete iter->callout_widget; + } } panel_windows_.clear(); WmShell* shell = panel_container_->GetShell(); @@ -362,11 +368,21 @@ void PanelLayoutManager::OnWillRemoveWindowFromLayout(WmWindow* child) {} void PanelLayoutManager::OnWindowRemovedFromLayout(WmWindow* child) { - if (child->GetType() == ui::wm::WINDOW_TYPE_POPUP) + if (child->GetType() == ui::wm::WINDOW_TYPE_POPUP) { + if (is_deleting_callout_widgets_) + return; + + for (PanelInfo& panel_info : panel_windows_) { + WmWindow* widget_window = + WmLookup::Get()->GetWindowForWidget(panel_info.CalloutWidget()); + CHECK(widget_window != child); + } return; + } PanelList::iterator found = std::find(panel_windows_.begin(), panel_windows_.end(), child); if (found != panel_windows_.end()) { + base::AutoReset<bool> auto_reset(&is_deleting_callout_widgets_, true); delete found->callout_widget; panel_windows_.erase(found); } @@ -829,6 +845,10 @@ callout_bounds); callout_widget_window->SetBoundsDirect(callout_bounds); + // TODO(sky): used for tracking down http://crbug.com/636113, remove once + // resolved. + CHECK_EQ(panel_container_, callout_widget_window->GetParent()); + CHECK_EQ(panel_container_, panel->GetParent()); panel_container_->StackChildAbove(callout_widget_window, panel); ui::Layer* layer = callout_widget_window->GetLayer();
diff --git a/ash/common/wm/panels/panel_layout_manager.h b/ash/common/wm/panels/panel_layout_manager.h index 1b1fff5..4bfe9353 100644 --- a/ash/common/wm/panels/panel_layout_manager.h +++ b/ash/common/wm/panels/panel_layout_manager.h
@@ -195,6 +195,11 @@ // restored when the shelf becomes visible again. std::unique_ptr<WmWindowTracker> restore_windows_on_shelf_visible_; + // TODO(sky): used for tracking down http://crbug.com/636113, remove once + // resolved. + // Set to true when one or more callout widgets is deleted. + bool is_deleting_callout_widgets_ = false; + // The last active panel. Used to maintain stacking order even if no panels // are currently focused. WmWindow* last_active_panel_;
diff --git a/ash/common/wm/window_cycle_controller.cc b/ash/common/wm/window_cycle_controller.cc index 6135f600..4808148 100644 --- a/ash/common/wm/window_cycle_controller.cc +++ b/ash/common/wm/window_cycle_controller.cc
@@ -6,10 +6,12 @@ #include "ash/common/metrics/task_switch_source.h" #include "ash/common/session/session_state_delegate.h" +#include "ash/common/shell_window_ids.h" #include "ash/common/wm/mru_window_tracker.h" #include "ash/common/wm/window_cycle_event_filter.h" #include "ash/common/wm/window_cycle_list.h" #include "ash/common/wm_shell.h" +#include "ash/common/wm_window.h" #include "base/metrics/histogram.h" namespace ash { @@ -52,6 +54,19 @@ void WindowCycleController::StartCycling() { MruWindowTracker::WindowList window_list = WmShell::Get()->mru_window_tracker()->BuildMruWindowList(); + // Exclude the AppList window, which will hide as soon as cycling starts + // anyway. It doesn't make sense to count it as a "switchable" window, yet + // a lot of code relies on the MRU list returning the app window. If we + // don't manually remove it, the window cycling UI won't crash or misbehave, + // but there will be a flicker as the target window changes. + window_list.erase(std::remove_if(window_list.begin(), window_list.end(), + [](WmWindow* window) { + return window->GetRootWindow() + ->GetChildByShellWindowId( + kShellWindowId_AppListContainer) + ->Contains(window); + }), + window_list.end()); active_window_before_window_cycle_ = GetActiveWindow(window_list);
diff --git a/ash/common/wm/window_cycle_list.cc b/ash/common/wm/window_cycle_list.cc index a243819a..845dcaa 100644 --- a/ash/common/wm/window_cycle_list.cc +++ b/ash/common/wm/window_cycle_list.cc
@@ -17,6 +17,7 @@ #include "ash/common/wm_window.h" #include "base/command_line.h" #include "ui/accessibility/ax_view_state.h" +#include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/views/background.h" #include "ui/views/border.h" #include "ui/views/controls/label.h" @@ -29,6 +30,10 @@ namespace ash { +namespace { + +bool g_disable_initial_delay = false; + // Returns the window immediately below |window| in the current container. WmWindow* GetWindowBelow(WmWindow* window) { WmWindow* parent = window->GetParent(); @@ -60,6 +65,8 @@ DISALLOW_COPY_AND_ASSIGN(LayerFillBackgroundPainter); }; +} // namespace + // This class restores and moves a window to the front of the stacking order for // the duration of the class's scope. class ScopedShowWindow : public WmWindowObserver { @@ -92,12 +99,14 @@ // This view represents a single WmWindow by displaying a title and a thumbnail // of the window's contents. -class WindowPreviewView : public views::View { +class WindowPreviewView : public views::View, public WmWindowObserver { public: explicit WindowPreviewView(WmWindow* window) : window_title_(new views::Label), preview_background_(new views::View), - mirror_view_(window->CreateViewWithRecreatedLayers().release()) { + mirror_view_(window->CreateViewWithRecreatedLayers().release()), + window_observer_(this) { + window_observer_.Add(window); window_title_->SetText(window->GetTitle()); window_title_->SetHorizontalAlignment(gfx::ALIGN_LEFT); window_title_->SetEnabledColor(SK_ColorWHITE); @@ -161,6 +170,15 @@ state->name = window_title_->text(); } + // WmWindowObserver: + void OnWindowDestroying(WmWindow* window) override { + window_observer_.Remove(window); + } + + void OnWindowTitleChanged(WmWindow* window) override { + window_title_->SetText(window->GetTitle()); + } + private: // The maximum width of a window preview. static const int kMaxPreviewWidth = 512; @@ -217,6 +235,8 @@ // The view that actually renders a thumbnail version of the window. views::View* mirror_view_; + ScopedObserver<WmWindow, WmWindowObserver> window_observer_; + DISALLOW_COPY_AND_ASSIGN(WindowPreviewView); }; @@ -230,6 +250,13 @@ DCHECK(!windows.empty()); SetPaintToLayer(true); layer()->SetFillsBoundsOpaquely(false); + layer()->SetOpacity(0.0); + { + ui::ScopedLayerAnimationSettings animate_fade(layer()->GetAnimator()); + animate_fade.SetTransitionDuration( + base::TimeDelta::FromMilliseconds(100)); + layer()->SetOpacity(1.0); + } set_background(views::Background::CreateSolidBackground( SkColorSetA(SK_ColorBLACK, 0xCC))); @@ -273,7 +300,6 @@ AddChildView(highlight_view_); AddChildView(mirror_container_); - SetTargetWindow(windows.front()); } ~WindowCycleView() override {} @@ -282,16 +308,28 @@ target_window_ = target; if (GetWidget()) { Layout(); - DCHECK(Contains(GetFocusManager()->GetFocusedView())); - window_view_map_[target_window_]->RequestFocus(); + if (target_window_) { + // In the window destruction case, we may have already removed the + // focused view and hence not be the focused window. We should still + // always be active, though. + DCHECK_EQ(ash::WmShell::Get()->GetActiveWindow()->GetInternalWidget(), + GetWidget()); + window_view_map_[target_window_]->RequestFocus(); + } } } void HandleWindowDestruction(WmWindow* destroying_window, WmWindow* new_target) { auto view_iter = window_view_map_.find(destroying_window); - view_iter->second->parent()->RemoveChildView(view_iter->second); + views::View* parent = view_iter->second->parent(); + DCHECK_EQ(mirror_container_, parent); + parent->RemoveChildView(view_iter->second); window_view_map_.erase(view_iter); + // With one of its children now gone, we must re-layout |mirror_container_|. + // This must happen before SetTargetWindow() to make sure our own Layout() + // works correctly when it's calculating highlight bounds. + parent->Layout(); SetTargetWindow(new_target); } @@ -301,8 +339,7 @@ } void Layout() override { - // Possible if the last window is deleted. - if (!target_window_) + if (!target_window_ || bounds().IsEmpty()) return; // The preview list (|mirror_container_|) starts flush to the left of @@ -396,53 +433,35 @@ WindowCycleList::WindowCycleList(const WindowList& windows) : windows_(windows), current_index_(0), cycle_view_(nullptr) { - WmShell::Get()->mru_window_tracker()->SetIgnoreActivations(true); + if (!ShouldShowUi()) + WmShell::Get()->mru_window_tracker()->SetIgnoreActivations(true); for (WmWindow* window : windows_) window->AddObserver(this); if (ShouldShowUi()) { - cycle_view_ = new WindowCycleView(windows_); - - WmWindow* root_window = WmShell::Get()->GetRootWindowForNewWindows(); - views::Widget* widget = new views::Widget; - views::Widget::InitParams params; - params.delegate = cycle_view_; - params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; - params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; - params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; - params.accept_events = true; - // TODO(estade): make sure nothing untoward happens when the lock screen - // or a system modal dialog is shown. - root_window->GetRootWindowController() - ->ConfigureWidgetInitParamsForContainer( - widget, kShellWindowId_OverlayContainer, ¶ms); - widget->Init(params); - - // TODO(estade): right now this just extends past the edge of the screen if - // there are too many windows. Handle this more gracefully. Also, if - // the display metrics change, cancel the UI. - gfx::Rect widget_rect = widget->GetWorkAreaBoundsInScreen(); - int widget_height = cycle_view_->GetPreferredSize().height(); - widget_rect.set_y((widget_rect.height() - widget_height) / 2); - widget_rect.set_height(widget_height); - widget->SetBounds(widget_rect); - widget->Show(); - cycle_ui_widget_.reset(widget); + if (g_disable_initial_delay) { + InitWindowCycleView(); + } else { + show_ui_timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(150), + this, &WindowCycleList::InitWindowCycleView); + } } } WindowCycleList::~WindowCycleList() { - WmShell::Get()->mru_window_tracker()->SetIgnoreActivations(false); + if (!ShouldShowUi()) + WmShell::Get()->mru_window_tracker()->SetIgnoreActivations(false); + for (WmWindow* window : windows_) window->RemoveObserver(this); - if (showing_window_) + if (showing_window_) { showing_window_->CancelRestore(); - - if (cycle_view_ && cycle_view_->target_window()) { - cycle_view_->target_window()->Show(); - cycle_view_->target_window()->GetWindowState()->Activate(); + } else if (!windows_.empty()) { + WmWindow* target_window = windows_[current_index_]; + target_window->Show(); + target_window->GetWindowState()->Activate(); } } @@ -468,14 +487,22 @@ current_index_ = (current_index_ + windows_.size()) % windows_.size(); DCHECK(windows_[current_index_]); - if (cycle_view_) { - cycle_view_->SetTargetWindow(windows_[current_index_]); - return; - } + if (ShouldShowUi()) { + if (current_index_ > 1) + InitWindowCycleView(); - // Make sure the next window is visible. - showing_window_.reset(new ScopedShowWindow); - showing_window_->Show(windows_[current_index_]); + if (cycle_view_) + cycle_view_->SetTargetWindow(windows_[current_index_]); + } else { + // Make sure the next window is visible. + showing_window_.reset(new ScopedShowWindow); + showing_window_->Show(windows_[current_index_]); + } +} + +// static +void WindowCycleList::DisableInitialDelayForTesting() { + g_disable_initial_delay = true; } void WindowCycleList::OnWindowDestroying(WmWindow* window) { @@ -504,9 +531,41 @@ } bool WindowCycleList::ShouldShowUi() { - return windows_.size() > 1 && - base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kAshEnableWindowCycleUi); + return windows_.size() > 1; +} + +void WindowCycleList::InitWindowCycleView() { + if (cycle_view_) + return; + + cycle_view_ = new WindowCycleView(windows_); + cycle_view_->SetTargetWindow(windows_[current_index_]); + + WmWindow* root_window = WmShell::Get()->GetRootWindowForNewWindows(); + views::Widget* widget = new views::Widget; + views::Widget::InitParams params; + params.delegate = cycle_view_; + params.type = views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; + params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; + params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; + params.accept_events = true; + params.name = "WindowCycleList (Alt+Tab)"; + // TODO(estade): make sure nothing untoward happens when the lock screen + // or a system modal dialog is shown. + root_window->GetRootWindowController()->ConfigureWidgetInitParamsForContainer( + widget, kShellWindowId_OverlayContainer, ¶ms); + widget->Init(params); + + // TODO(estade): right now this just extends past the edge of the screen if + // there are too many windows. Handle this more gracefully. Also, if + // the display metrics change, cancel the UI. + gfx::Rect widget_rect = widget->GetWorkAreaBoundsInScreen(); + int widget_height = cycle_view_->GetPreferredSize().height(); + widget_rect.set_y((widget_rect.height() - widget_height) / 2); + widget_rect.set_height(widget_height); + widget->SetBounds(widget_rect); + widget->Show(); + cycle_ui_widget_.reset(widget); } } // namespace ash
diff --git a/ash/common/wm/window_cycle_list.h b/ash/common/wm/window_cycle_list.h index 3ae21ae0..6d073d16 100644 --- a/ash/common/wm/window_cycle_list.h +++ b/ash/common/wm/window_cycle_list.h
@@ -12,6 +12,7 @@ #include "ash/common/wm/window_cycle_controller.h" #include "ash/common/wm_window_observer.h" #include "base/macros.h" +#include "base/timer/timer.h" namespace views { class Label; @@ -41,6 +42,9 @@ private: friend class WindowCycleControllerTest; + + static void DisableInitialDelayForTesting(); + const WindowList& windows() const { return windows_; } // WmWindowObserver overrides: @@ -52,6 +56,9 @@ // Returns true if the window list overlay should be shown. bool ShouldShowUi(); + // Initializes and shows |cycle_view_|. + void InitWindowCycleView(); + // List of weak pointers to windows to use while cycling with the keyboard. // List is built when the user initiates the gesture (i.e. hits alt-tab the // first time) and is emptied when the gesture is complete (i.e. releases the @@ -63,6 +70,8 @@ int current_index_; // Wrapper for the window brought to the front. + // TODO(estade): remove ScopedShowWindow when we know we are happy launching + // the |cycle_view_| version. std::unique_ptr<ScopedShowWindow> showing_window_; // The top level View for the window cycle UI. May be null if the UI is not @@ -72,6 +81,9 @@ // The widget that hosts the window cycle UI. std::unique_ptr<views::Widget> cycle_ui_widget_; + // A timer to delay showing the UI. Quick Alt+Tab should not flash a UI. + base::OneShotTimer show_ui_timer_; + DISALLOW_COPY_AND_ASSIGN(WindowCycleList); };
diff --git a/ash/common/wm/wm_window_animations.cc b/ash/common/wm/wm_window_animations.cc new file mode 100644 index 0000000..64b431f --- /dev/null +++ b/ash/common/wm/wm_window_animations.cc
@@ -0,0 +1,28 @@ +// Copyright 2016 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 "ash/common/wm/wm_window_animations.h" + +#include "ui/compositor/layer.h" +#include "ui/gfx/transform.h" + +namespace ash { + +void SetTransformForScaleAnimation(ui::Layer* layer, + LayerScaleAnimationDirection type) { + // Scales for windows above and below the current workspace. + const float kLayerScaleAboveSize = 1.1f; + const float kLayerScaleBelowSize = .9f; + + const float scale = type == LAYER_SCALE_ANIMATION_ABOVE + ? kLayerScaleAboveSize + : kLayerScaleBelowSize; + gfx::Transform transform; + transform.Translate(-layer->bounds().width() * (scale - 1.0f) / 2, + -layer->bounds().height() * (scale - 1.0f) / 2); + transform.Scale(scale, scale); + layer->SetTransform(transform); +} + +} // namespace ash
diff --git a/ash/common/wm/wm_window_animations.h b/ash/common/wm/wm_window_animations.h new file mode 100644 index 0000000..d704304 --- /dev/null +++ b/ash/common/wm/wm_window_animations.h
@@ -0,0 +1,32 @@ +// Copyright 2016 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 ASH_COMMON_WM_WM_WINDOW_ANIMATIONS_H_ +#define ASH_COMMON_WM_WM_WINDOW_ANIMATIONS_H_ + +#include "ash/ash_export.h" + +namespace ui { +class Layer; +} + +// This is only for animations specific to Ash. For window animations shared +// with desktop Chrome, see ui/views/corewm/window_animations.h. +namespace ash { + +// Direction for ash-specific window animations used in workspaces and +// lock/unlock animations. +enum LayerScaleAnimationDirection { + LAYER_SCALE_ANIMATION_ABOVE, + LAYER_SCALE_ANIMATION_BELOW, +}; + +// Applies scale related to the specified AshWindowScaleType. +ASH_EXPORT void SetTransformForScaleAnimation( + ui::Layer* layer, + LayerScaleAnimationDirection type); + +} // namespace ash + +#endif // ASH_COMMON_WM_WM_WINDOW_ANIMATIONS_H_
diff --git a/ash/common/wm_shell.cc b/ash/common/wm_shell.cc index 5941e28..567c38c 100644 --- a/ash/common/wm_shell.cc +++ b/ash/common/wm_shell.cc
@@ -109,11 +109,26 @@ OnPinnedStateChanged(pinned_window)); } -void WmShell::OnVirtualKeyboardActivated(bool activated) { +void WmShell::NotifyVirtualKeyboardActivated(bool activated) { FOR_EACH_OBSERVER(ShellObserver, shell_observers_, OnVirtualKeyboardStateChanged(activated)); } +void WmShell::NotifyShelfCreatedForRootWindow(WmWindow* root_window) { + FOR_EACH_OBSERVER(ShellObserver, shell_observers_, + OnShelfCreatedForRootWindow(root_window)); +} + +void WmShell::NotifyShelfAlignmentChanged(WmWindow* root_window) { + FOR_EACH_OBSERVER(ShellObserver, shell_observers_, + OnShelfAlignmentChanged(root_window)); +} + +void WmShell::NotifyShelfAutoHideBehaviorChanged(WmWindow* root_window) { + FOR_EACH_OBSERVER(ShellObserver, shell_observers_, + OnShelfAutoHideBehaviorChanged(root_window)); +} + void WmShell::AddShellObserver(ShellObserver* observer) { shell_observers_.AddObserver(observer); }
diff --git a/ash/common/wm_shell.h b/ash/common/wm_shell.h index 8dd3d7e..c064efde 100644 --- a/ash/common/wm_shell.h +++ b/ash/common/wm_shell.h
@@ -283,16 +283,26 @@ // Called after overview mode has ended. virtual void OnOverviewModeEnded() = 0; - // Notifies observers after toggling fullscreen mode in |root_window|. + // Notify observers that fullscreen mode has changed for |root_window|. void NotifyFullscreenStateChanged(bool is_fullscreen, WmWindow* root_window); - // Notifies |observers_| when entering or exiting pinned mode for - // |pinned_window|. Entering or exiting can be checked by looking at - // |pinned_window|'s window state. + // Notify observers that |pinned_window| changed its pinned window state. void NotifyPinnedStateChanged(WmWindow* pinned_window); - // Called when virtual keyboard has been activated/deactivated. - void OnVirtualKeyboardActivated(bool activated); + // Notify observers that the virtual keyboard has been activated/deactivated. + void NotifyVirtualKeyboardActivated(bool activated); + + // Notify observers that the shelf was created for |root_window|. + // TODO(jamescook): Move to Shelf. + void NotifyShelfCreatedForRootWindow(WmWindow* root_window); + + // Notify observers that |root_window|'s shelf changed auto-hide alignment. + // TODO(jamescook): Move to Shelf. + void NotifyShelfAlignmentChanged(WmWindow* root_window); + + // Notify observers that |root_window|'s shelf changed auto-hide behavior. + // TODO(jamescook): Move to Shelf. + void NotifyShelfAutoHideBehaviorChanged(WmWindow* root_window); virtual SessionStateDelegate* GetSessionStateDelegate() = 0; @@ -305,7 +315,11 @@ void AddShellObserver(ShellObserver* observer); void RemoveShellObserver(ShellObserver* observer); - virtual void AddPointerWatcher(views::PointerWatcher* watcher) = 0; + // If |wants_moves| is true PointerWatcher::OnPointerEventObserved() is + // called for pointer move events. Enabling pointer moves may incur a + // performance hit and should be avoided if possible. + virtual void AddPointerWatcher(views::PointerWatcher* watcher, + bool wants_moves) = 0; virtual void RemovePointerWatcher(views::PointerWatcher* watcher) = 0; // TODO: Move these back to LockStateController when that has been moved.
diff --git a/ash/display/display_animator_chromeos.cc b/ash/display/display_animator_chromeos.cc index c61720d..6e552aa 100644 --- a/ash/display/display_animator_chromeos.cc +++ b/ash/display/display_animator_chromeos.cc
@@ -206,8 +206,8 @@ timer_->Stop(); timer_.reset(); } - STLDeleteContainerPairSecondPointers(hiding_layers_.begin(), - hiding_layers_.end()); + base::STLDeleteContainerPairSecondPointers(hiding_layers_.begin(), + hiding_layers_.end()); hiding_layers_.clear(); }
diff --git a/ash/display/display_color_manager_chromeos.cc b/ash/display/display_color_manager_chromeos.cc index 911dabde..3eca2ee 100644 --- a/ash/display/display_color_manager_chromeos.cc +++ b/ash/display/display_color_manager_chromeos.cc
@@ -158,7 +158,7 @@ DisplayColorManager::~DisplayColorManager() { configurator_->RemoveObserver(this); - STLDeleteValues(&calibration_map_); + base::STLDeleteValues(&calibration_map_); } void DisplayColorManager::OnDisplayModeChanged(
diff --git a/ash/display/window_tree_host_manager.cc b/ash/display/window_tree_host_manager.cc index 8179cbe..8b635266 100644 --- a/ash/display/window_tree_host_manager.cc +++ b/ash/display/window_tree_host_manager.cc
@@ -281,7 +281,7 @@ } CHECK(primary_rwc); - STLDeleteElements(&to_delete); + base::STLDeleteElements(&to_delete); delete primary_rwc; }
diff --git a/ash/mus/BUILD.gn b/ash/mus/BUILD.gn index 5778e5f..3141259 100644 --- a/ash/mus/BUILD.gn +++ b/ash/mus/BUILD.gn
@@ -61,8 +61,6 @@ "shelf_layout_manager_delegate.h", "shell_delegate_mus.cc", "shell_delegate_mus.h", - "status_layout_manager.cc", - "status_layout_manager.h", "window_manager.cc", "window_manager.h", "window_manager_application.cc",
diff --git a/ash/mus/bridge/wm_shelf_mus.cc b/ash/mus/bridge/wm_shelf_mus.cc index f56328c7..a1d4edea6e 100644 --- a/ash/mus/bridge/wm_shelf_mus.cc +++ b/ash/mus/bridge/wm_shelf_mus.cc
@@ -4,9 +4,11 @@ #include "ash/mus/bridge/wm_shelf_mus.h" +#include "ash/common/shell_window_ids.h" +#include "ash/common/wm_root_window_controller.h" #include "ash/mus/bridge/wm_window_mus.h" -#include "ash/mus/shelf_layout_manager.h" #include "services/ui/public/cpp/window.h" +#include "ui/views/widget/widget.h" // TODO(sky): fully implement this http://crbug.com/612631 . #undef NOTIMPLEMENTED @@ -15,25 +17,27 @@ namespace ash { namespace mus { -WmShelfMus::WmShelfMus(ShelfLayoutManager* shelf_layout_manager) - : shelf_layout_manager_(shelf_layout_manager) {} +WmShelfMus::WmShelfMus(WmRootWindowController* root_window_controller) { + DCHECK(root_window_controller); + // Create a placeholder shelf widget, because the status area code assumes it + // can access one. + // TODO(jamescook): Create a real shelf widget. http://crbug.com/615155 + shelf_widget_ = new views::Widget; + views::Widget::InitParams params( + views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); + root_window_controller->ConfigureWidgetInitParamsForContainer( + shelf_widget_, kShellWindowId_ShelfContainer, ¶ms); + shelf_widget_->Init(params); +} WmShelfMus::~WmShelfMus() {} WmWindow* WmShelfMus::GetWindow() { - return WmWindowMus::Get(shelf_layout_manager_->GetShelfWindow()); + return WmWindowMus::Get(shelf_widget_); } ShelfAlignment WmShelfMus::GetAlignment() const { - switch (shelf_layout_manager_->alignment()) { - case mash::shelf::mojom::Alignment::BOTTOM: - return SHELF_ALIGNMENT_BOTTOM; - case mash::shelf::mojom::Alignment::LEFT: - return SHELF_ALIGNMENT_LEFT; - case mash::shelf::mojom::Alignment::RIGHT: - return SHELF_ALIGNMENT_RIGHT; - } - NOTREACHED(); + NOTIMPLEMENTED(); return SHELF_ALIGNMENT_BOTTOM; } @@ -74,11 +78,6 @@ return false; } -bool WmShelfMus::IsShowingOverflowBubble() const { - NOTIMPLEMENTED(); - return false; -} - void WmShelfMus::SchedulePaint() { NOTIMPLEMENTED(); } @@ -94,7 +93,7 @@ ShelfVisibilityState WmShelfMus::GetVisibilityState() const { NOTIMPLEMENTED(); - return shelf_layout_manager_->GetShelfWindow() ? SHELF_VISIBLE : SHELF_HIDDEN; + return SHELF_VISIBLE; } gfx::Rect WmShelfMus::GetUserWorkAreaBounds() const {
diff --git a/ash/mus/bridge/wm_shelf_mus.h b/ash/mus/bridge/wm_shelf_mus.h index d670d18b..5db4d2b9 100644 --- a/ash/mus/bridge/wm_shelf_mus.h +++ b/ash/mus/bridge/wm_shelf_mus.h
@@ -5,23 +5,23 @@ #ifndef ASH_MUS_BRIDGE_WM_SHELF_MUS_H_ #define ASH_MUS_BRIDGE_WM_SHELF_MUS_H_ -#include <stdint.h> - -#include <vector> - #include "ash/common/shelf/wm_shelf.h" #include "base/macros.h" #include "base/observer_list.h" -namespace ash { -namespace mus { +namespace views { +class Widget; +} -class ShelfLayoutManager; +namespace ash { +class WmRootWindowController; + +namespace mus { // WmShelf implementation for mus. class WmShelfMus : public WmShelf { public: - explicit WmShelfMus(ShelfLayoutManager* shelf_layout_manager); + WmShelfMus(WmRootWindowController* root_window_controller); ~WmShelfMus() override; // WmShelf: @@ -35,7 +35,6 @@ ShelfBackgroundType GetBackgroundType() const override; WmDimmerView* CreateDimmerView(bool disable_animations_for_test) override; bool IsDimmed() const override; - bool IsShowingOverflowBubble() const override; void SchedulePaint() override; bool IsVisible() const override; void UpdateVisibilityState() override; @@ -54,7 +53,8 @@ private: base::ObserverList<WmShelfObserver> observers_; - ShelfLayoutManager* shelf_layout_manager_; + // Owned by native widget. + views::Widget* shelf_widget_; DISALLOW_COPY_AND_ASSIGN(WmShelfMus); };
diff --git a/ash/mus/bridge/wm_shell_mus.cc b/ash/mus/bridge/wm_shell_mus.cc index 254b52b..03539ea 100644 --- a/ash/mus/bridge/wm_shell_mus.cc +++ b/ash/mus/bridge/wm_shell_mus.cc
@@ -35,6 +35,7 @@ #include "services/ui/public/cpp/window.h" #include "services/ui/public/cpp/window_tree_client.h" #include "ui/display/screen.h" +#include "ui/views/mus/pointer_watcher_event_router.h" namespace ash { namespace mus { @@ -102,10 +103,13 @@ } // namespace -WmShellMus::WmShellMus(std::unique_ptr<ShellDelegate> shell_delegate, - WindowManager* window_manager) +WmShellMus::WmShellMus( + std::unique_ptr<ShellDelegate> shell_delegate, + WindowManager* window_manager, + views::PointerWatcherEventRouter* pointer_watcher_event_router) : WmShell(std::move(shell_delegate)), window_manager_(window_manager), + pointer_watcher_event_router_(pointer_watcher_event_router), session_state_delegate_(new SessionStateDelegateStub) { window_tree_client()->AddObserver(this); WmShell::Set(this); @@ -357,18 +361,18 @@ NOTIMPLEMENTED(); } -void WmShellMus::AddPointerWatcher(views::PointerWatcher* watcher) { - // TODO(jamescook): Move PointerWatcherDelegateMus to //ash/mus and use here. - NOTIMPLEMENTED(); +void WmShellMus::AddPointerWatcher(views::PointerWatcher* watcher, + bool wants_moves) { + pointer_watcher_event_router_->AddPointerWatcher(watcher, wants_moves); } void WmShellMus::RemovePointerWatcher(views::PointerWatcher* watcher) { - NOTIMPLEMENTED(); + pointer_watcher_event_router_->RemovePointerWatcher(watcher); } bool WmShellMus::IsTouchDown() { // TODO: implement me, http://crbug.com/634967. - NOTIMPLEMENTED(); + // NOTIMPLEMENTED is too spammy here. return false; }
diff --git a/ash/mus/bridge/wm_shell_mus.h b/ash/mus/bridge/wm_shell_mus.h index ae1b3890..6ebdd80 100644 --- a/ash/mus/bridge/wm_shell_mus.h +++ b/ash/mus/bridge/wm_shell_mus.h
@@ -23,6 +23,10 @@ class WindowTreeClient; } +namespace views { +class PointerWatcherEventRouter; +} + namespace ash { namespace mus { @@ -37,7 +41,8 @@ class WmShellMus : public WmShell, public ui::WindowTreeClientObserver { public: WmShellMus(std::unique_ptr<ShellDelegate> shell_delegate, - WindowManager* window_manager); + WindowManager* window_manager, + views::PointerWatcherEventRouter* pointer_watcher_event_router); ~WmShellMus() override; static WmShellMus* Get(); @@ -97,7 +102,8 @@ void RemoveActivationObserver(WmActivationObserver* observer) override; void AddDisplayObserver(WmDisplayObserver* observer) override; void RemoveDisplayObserver(WmDisplayObserver* observer) override; - void AddPointerWatcher(views::PointerWatcher* watcher) override; + void AddPointerWatcher(views::PointerWatcher* watcher, + bool wants_moves) override; void RemovePointerWatcher(views::PointerWatcher* watcher) override; bool IsTouchDown() override; #if defined(OS_CHROMEOS) @@ -119,6 +125,8 @@ WindowManager* window_manager_; + views::PointerWatcherEventRouter* pointer_watcher_event_router_; + std::vector<WmRootWindowControllerMus*> root_window_controllers_; std::unique_ptr<AcceleratorControllerDelegateMus>
diff --git a/ash/mus/root_window_controller.cc b/ash/mus/root_window_controller.cc index 887092f..f8d6340 100644 --- a/ash/mus/root_window_controller.cc +++ b/ash/mus/root_window_controller.cc
@@ -14,7 +14,9 @@ #include <vector> #include "ash/common/root_window_controller_common.h" +#include "ash/common/session/session_state_delegate.h" #include "ash/common/shell_window_ids.h" +#include "ash/common/system/status_area_widget.h" #include "ash/common/wm/always_on_top_controller.h" #include "ash/common/wm/container_finder.h" #include "ash/common/wm/dock/docked_window_layout_manager.h" @@ -30,7 +32,6 @@ #include "ash/mus/property_util.h" #include "ash/mus/screenlock_layout.h" #include "ash/mus/shelf_layout_manager.h" -#include "ash/mus/status_layout_manager.h" #include "ash/mus/window_manager.h" #include "base/bind.h" #include "base/command_line.h" @@ -65,6 +66,7 @@ root_window_controller_common_->CreateContainers(); root_window_controller_common_->CreateLayoutManagers(); CreateLayoutManagers(); + CreateStatusArea(); disconnected_app_handler_.reset(new DisconnectedAppHandler(root)); @@ -192,12 +194,7 @@ new ShelfLayoutManager(shelf_container->mus_window(), this); layout_managers_[shelf_container->mus_window()].reset(shelf_layout_manager); - wm_shelf_.reset(new WmShelfMus(shelf_layout_manager)); - - WmWindowMus* status_container = - GetWindowByShellWindowId(kShellWindowId_StatusContainer); - layout_managers_[status_container->mus_window()].reset( - new StatusLayoutManager(status_container->mus_window())); + wm_shelf_.reset(new WmShelfMus(wm_root_window_controller_.get())); WmWindowMus* default_container = GetWindowByShellWindowId(kShellWindowId_DefaultContainer); @@ -218,5 +215,21 @@ base::WrapUnique(new PanelLayoutManager(panel_container))); } +void RootWindowController::CreateStatusArea() { + WmWindowMus* status_container = + GetWindowByShellWindowId(kShellWindowId_StatusContainer); + // Owned by native widget. + StatusAreaWidget* status_area_widget = + new StatusAreaWidget(status_container, wm_shelf_.get()); + status_area_widget->CreateTrayViews(); + // TODO(jamescook): Remove this when ash::StatusAreaLayoutManager and + // ash::ShelfLayoutManager are working in mash. http://crbug.com/621112 + gfx::Size display_size = display_.bounds().size(); + status_area_widget->SetBounds(gfx::Rect(display_size.width() - 179, + display_size.height() - 48, 120, 40)); + if (WmShell::Get()->GetSessionStateDelegate()->IsActiveUserSessionStarted()) + status_area_widget->Show(); +} + } // namespace mus } // namespace ash
diff --git a/ash/mus/root_window_controller.h b/ash/mus/root_window_controller.h index ae1f013..de593d3 100644 --- a/ash/mus/root_window_controller.h +++ b/ash/mus/root_window_controller.h
@@ -49,8 +49,6 @@ ui::Window* root() { return root_; } - int window_count() { return window_count_; } - ui::Window* NewTopLevelWindow( std::map<std::string, std::vector<uint8_t>>* properties); @@ -85,6 +83,9 @@ // Creates the necessary set of layout managers in the shell windows. void CreateLayoutManagers(); + // Creates the status area widget that contains the system tray menu. + void CreateStatusArea(); + WindowManager* window_manager_; ui::Window* root_; int window_count_ = 0;
diff --git a/ash/mus/status_layout_manager.cc b/ash/mus/status_layout_manager.cc deleted file mode 100644 index 2eff898..0000000 --- a/ash/mus/status_layout_manager.cc +++ /dev/null
@@ -1,69 +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. - -#include "ash/mus/status_layout_manager.h" - -#include "ash/mus/property_util.h" -#include "ash/public/interfaces/ash_window_type.mojom.h" -#include "services/ui/public/cpp/window.h" -#include "ui/gfx/geometry/rect.h" - -namespace ash { -namespace mus { - -StatusLayoutManager::StatusLayoutManager(ui::Window* owner) - : LayoutManager(owner), - alignment_(mash::shelf::mojom::Alignment::BOTTOM), - auto_hide_behavior_(mash::shelf::mojom::AutoHideBehavior::NEVER) { - AddLayoutProperty(ui::mojom::WindowManager::kPreferredSize_Property); -} - -StatusLayoutManager::~StatusLayoutManager() {} - -// We explicitly don't make assertions about the number of children in this -// layout as the number of children can vary when the application providing the -// status area restarts. - -void StatusLayoutManager::LayoutWindow(ui::Window* window) { - if (GetAshWindowType(window) != mojom::AshWindowType::STATUS_AREA) { - // TODO(jamescook): Layout for notifications and other windows. - NOTIMPLEMENTED() << "Non-status-area window needs layout."; - return; - } - gfx::Size size = GetWindowPreferredSize(window); - if (alignment_ == mash::shelf::mojom::Alignment::BOTTOM) { - const int y = owner()->bounds().height() - size.height(); - // TODO(msw): Place the status area widget on the left for RTL UIs. - window->SetBounds(gfx::Rect(owner()->bounds().width() - size.width(), y, - size.width(), size.height())); - } else { - const int x = (alignment_ == mash::shelf::mojom::Alignment::LEFT) - ? 0 - : (owner()->bounds().width() - size.width()); - window->SetBounds(gfx::Rect(x, owner()->bounds().height() - size.height(), - size.width(), size.height())); - } -} - -void StatusLayoutManager::SetAlignment( - mash::shelf::mojom::Alignment alignment) { - if (alignment_ == alignment) - return; - - alignment_ = alignment; - for (ui::Window* window : owner()->children()) - LayoutWindow(window); -} - -void StatusLayoutManager::SetAutoHideBehavior( - mash::shelf::mojom::AutoHideBehavior auto_hide) { - if (auto_hide_behavior_ == auto_hide) - return; - - auto_hide_behavior_ = auto_hide; - NOTIMPLEMENTED(); -} - -} // namespace mus -} // namespace ash
diff --git a/ash/mus/status_layout_manager.h b/ash/mus/status_layout_manager.h deleted file mode 100644 index 13568cb..0000000 --- a/ash/mus/status_layout_manager.h +++ /dev/null
@@ -1,38 +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. - -#ifndef ASH_MUS_STATUS_LAYOUT_MANAGER_H_ -#define ASH_MUS_STATUS_LAYOUT_MANAGER_H_ - -#include "ash/mus/layout_manager.h" -#include "base/macros.h" -#include "mash/shelf/public/interfaces/shelf_constants.mojom.h" - -namespace ash { -namespace mus { - -// Lays out the status container, which contains the status area widget and -// notifications. -class StatusLayoutManager : public LayoutManager { - public: - explicit StatusLayoutManager(ui::Window* owner); - ~StatusLayoutManager() override; - - void SetAlignment(mash::shelf::mojom::Alignment alignment); - void SetAutoHideBehavior(mash::shelf::mojom::AutoHideBehavior auto_hide); - - private: - // Overridden from LayoutManager: - void LayoutWindow(ui::Window* window) override; - - mash::shelf::mojom::Alignment alignment_; - mash::shelf::mojom::AutoHideBehavior auto_hide_behavior_; - - DISALLOW_COPY_AND_ASSIGN(StatusLayoutManager); -}; - -} // namespace mus -} // namespace ash - -#endif // ASH_MUS_STATUS_LAYOUT_MANAGER_H_
diff --git a/ash/mus/window_manager.cc b/ash/mus/window_manager.cc index da15fa8e..ed46d9e2 100644 --- a/ash/mus/window_manager.cc +++ b/ash/mus/window_manager.cc
@@ -33,6 +33,7 @@ #include "ui/app_list/presenter/app_list_presenter.h" #include "ui/base/hit_test.h" #include "ui/events/mojo/event.mojom.h" +#include "ui/views/mus/pointer_watcher_event_router.h" #include "ui/views/mus/screen_mus.h" namespace ash { @@ -77,6 +78,9 @@ DCHECK(!window_tree_client_); window_tree_client_ = window_tree_client; + pointer_watcher_event_router_.reset( + new views::PointerWatcherEventRouter(window_tree_client)); + shadow_controller_.reset(new ShadowController(window_tree_client)); // The insets are roughly what is needed by CustomFrameView. The expectation @@ -95,7 +99,8 @@ std::unique_ptr<ShellDelegate> shell_delegate(new ShellDelegateMus( base::MakeUnique<AppListPresenterStub>(), connector_)); - shell_.reset(new WmShellMus(std::move(shell_delegate), this)); + shell_.reset(new WmShellMus(std::move(shell_delegate), this, + pointer_watcher_event_router_.get())); shell_->Initialize(); lookup_.reset(new WmLookupMus); } @@ -216,13 +221,15 @@ FOR_EACH_OBSERVER(WindowManagerObserver, observers_, OnWindowTreeClientDestroyed()); + pointer_watcher_event_router_.reset(); + window_tree_client_ = nullptr; window_manager_client_ = nullptr; } void WindowManager::OnPointerEventObserved(const ui::PointerEvent& event, ui::Window* target) { - // Does not use PointerWatchers. + pointer_watcher_event_router_->OnPointerEventObserved(event, target); } void WindowManager::SetWindowManagerClient(ui::WindowManagerClient* client) {
diff --git a/ash/mus/window_manager.h b/ash/mus/window_manager.h index 8c2c243..67ea7ca 100644 --- a/ash/mus/window_manager.h +++ b/ash/mus/window_manager.h
@@ -27,6 +27,10 @@ class Connector; } +namespace views { +class PointerWatcherEventRouter; +} + namespace ash { namespace mus { @@ -123,6 +127,9 @@ ui::WindowManagerClient* window_manager_client_ = nullptr; + std::unique_ptr<views::PointerWatcherEventRouter> + pointer_watcher_event_router_; + std::unique_ptr<ShadowController> shadow_controller_; std::set<std::unique_ptr<RootWindowController>> root_window_controllers_;
diff --git a/ash/mus/window_manager_application.cc b/ash/mus/window_manager_application.cc index a24d0b6d..1ea072c 100644 --- a/ash/mus/window_manager_application.cc +++ b/ash/mus/window_manager_application.cc
@@ -15,7 +15,7 @@ #include "services/shell/public/cpp/connector.h" #include "services/tracing/public/cpp/provider.h" #include "services/ui/common/event_matcher_util.h" -#include "services/ui/common/gpu_service.h" +#include "services/ui/public/cpp/gpu_service.h" #include "services/ui/public/cpp/window.h" #include "services/ui/public/cpp/window_tree_client.h" #include "ui/aura/env.h" @@ -96,7 +96,8 @@ void WindowManagerApplication::OnStart(const shell::Identity& identity) { aura_init_.reset(new views::AuraInit(connector(), "ash_mus_resources.pak")); gpu_service_ = ui::GpuService::Initialize(connector()); - compositor_context_factory_.reset(new views::SurfaceContextFactory()); + compositor_context_factory_.reset( + new views::SurfaceContextFactory(gpu_service_.get())); aura::Env::GetInstance()->set_context_factory( compositor_context_factory_.get()); window_manager_.reset(new WindowManager(connector()));
diff --git a/ash/pointer_watcher_delegate_aura.cc b/ash/pointer_watcher_delegate_aura.cc index 9e72178..2dfe4f9 100644 --- a/ash/pointer_watcher_delegate_aura.cc +++ b/ash/pointer_watcher_delegate_aura.cc
@@ -24,25 +24,43 @@ } void PointerWatcherDelegateAura::AddPointerWatcher( - views::PointerWatcher* watcher) { - pointer_watchers_.AddObserver(watcher); + views::PointerWatcher* watcher, + bool wants_moves) { + // We only allow a watcher to be added once. That is, we don't consider + // the pair of |watcher| and |wants_move| unique, just |watcher|. + if (wants_moves) { + DCHECK(!non_move_watchers_.HasObserver(watcher)); + move_watchers_.AddObserver(watcher); + } else { + DCHECK(!move_watchers_.HasObserver(watcher)); + non_move_watchers_.AddObserver(watcher); + } } void PointerWatcherDelegateAura::RemovePointerWatcher( views::PointerWatcher* watcher) { - pointer_watchers_.RemoveObserver(watcher); + non_move_watchers_.RemoveObserver(watcher); + move_watchers_.RemoveObserver(watcher); } void PointerWatcherDelegateAura::OnMouseEvent(ui::MouseEvent* event) { + if (event->type() == ui::ET_MOUSE_CAPTURE_CHANGED) { + FOR_EACH_OBSERVER(views::PointerWatcher, non_move_watchers_, + OnMouseCaptureChanged()); + FOR_EACH_OBSERVER(views::PointerWatcher, move_watchers_, + OnMouseCaptureChanged()); + return; + } + // For compatibility with the mus version, don't send moves. if (event->type() != ui::ET_MOUSE_PRESSED && event->type() != ui::ET_MOUSE_RELEASED) return; - ui::PointerEvent mouse_pointer_event(*event); - FOR_EACH_OBSERVER( - views::PointerWatcher, pointer_watchers_, - OnPointerEventObserved(mouse_pointer_event, GetLocationInScreen(*event), - GetTargetWidget(*event))); + + if (!ui::PointerEvent::CanConvertFrom(*event)) + return; + + NotifyWatchers(ui::PointerEvent(*event), *event); } void PointerWatcherDelegateAura::OnTouchEvent(ui::TouchEvent* event) { @@ -50,11 +68,9 @@ if (event->type() != ui::ET_TOUCH_PRESSED && event->type() != ui::ET_TOUCH_RELEASED) return; - ui::PointerEvent touch_pointer_event(*event); - FOR_EACH_OBSERVER( - views::PointerWatcher, pointer_watchers_, - OnPointerEventObserved(touch_pointer_event, GetLocationInScreen(*event), - GetTargetWidget(*event))); + + DCHECK(ui::PointerEvent::CanConvertFrom(*event)); + NotifyWatchers(ui::PointerEvent(*event), *event); } gfx::Point PointerWatcherDelegateAura::GetLocationInScreen( @@ -72,4 +88,20 @@ return views::Widget::GetTopLevelWidgetForNativeView(window); } +void PointerWatcherDelegateAura::NotifyWatchers( + const ui::PointerEvent& event, + const ui::LocatedEvent& original_event) { + const gfx::Point screen_location(GetLocationInScreen(original_event)); + views::Widget* target_widget = GetTargetWidget(original_event); + FOR_EACH_OBSERVER( + views::PointerWatcher, move_watchers_, + OnPointerEventObserved(event, screen_location, target_widget)); + if (event.type() != ui::ET_MOUSE_MOVED && + event.type() != ui::ET_TOUCH_MOVED) { + FOR_EACH_OBSERVER( + views::PointerWatcher, non_move_watchers_, + OnPointerEventObserved(event, screen_location, target_widget)); + } +} + } // namespace ash
diff --git a/ash/pointer_watcher_delegate_aura.h b/ash/pointer_watcher_delegate_aura.h index 1bea01d..2c47e20 100644 --- a/ash/pointer_watcher_delegate_aura.h +++ b/ash/pointer_watcher_delegate_aura.h
@@ -14,6 +14,7 @@ namespace ui { class LocatedEvent; +class PointerEvent; } namespace views { @@ -31,7 +32,8 @@ ~PointerWatcherDelegateAura() override; // PointerWatcherDelegate: - void AddPointerWatcher(views::PointerWatcher* watcher) override; + void AddPointerWatcher(views::PointerWatcher* watcher, + bool wants_moves) override; void RemovePointerWatcher(views::PointerWatcher* watcher) override; // ui::EventHandler: @@ -42,8 +44,19 @@ gfx::Point GetLocationInScreen(const ui::LocatedEvent& event) const; views::Widget* GetTargetWidget(const ui::LocatedEvent& event) const; - // Must be empty on destruction. - base::ObserverList<views::PointerWatcher, true> pointer_watchers_; + // Calls OnPointerEventObserved() on the appropriate set of watchers as + // determined by the type of event. |original_event| is the original + // event supplied to OnMouseEvent()/OnTouchEvent(), |pointer_event| is + // |original_event| converted to a PointerEvent. + void NotifyWatchers(const ui::PointerEvent& pointer_event, + const ui::LocatedEvent& original_event); + + // The true parameter to ObserverList indicates the list must be empty on + // destruction. Two sets of observers are maintained, one for observers not + // needing moves |non_move_watchers_| and |move_watchers_| for those + // observers wanting moves too. + base::ObserverList<views::PointerWatcher, true> non_move_watchers_; + base::ObserverList<views::PointerWatcher, true> move_watchers_; DISALLOW_COPY_AND_ASSIGN(PointerWatcherDelegateAura); };
diff --git a/ash/resources/default_100_percent/common/shelf/status_icon_background_normal.png b/ash/resources/default_100_percent/common/shelf/status_icon_background_normal.png index 565c5010..f36f875b 100644 --- a/ash/resources/default_100_percent/common/shelf/status_icon_background_normal.png +++ b/ash/resources/default_100_percent/common/shelf/status_icon_background_normal.png Binary files differ
diff --git a/ash/resources/default_100_percent/common/shelf/status_icon_background_onblack_normal.png b/ash/resources/default_100_percent/common/shelf/status_icon_background_onblack_normal.png index 41ba35c5..599b0ad 100644 --- a/ash/resources/default_100_percent/common/shelf/status_icon_background_onblack_normal.png +++ b/ash/resources/default_100_percent/common/shelf/status_icon_background_onblack_normal.png Binary files differ
diff --git a/ash/resources/default_100_percent/common/shelf/status_icon_background_pressed.png b/ash/resources/default_100_percent/common/shelf/status_icon_background_pressed.png index d8cdd77..4c46c41 100644 --- a/ash/resources/default_100_percent/common/shelf/status_icon_background_pressed.png +++ b/ash/resources/default_100_percent/common/shelf/status_icon_background_pressed.png Binary files differ
diff --git a/ash/resources/default_100_percent/common/shelf/status_launcher_menu_icon.png b/ash/resources/default_100_percent/common/shelf/status_launcher_menu_icon.png index 2c2b9e88..c00b2926 100644 --- a/ash/resources/default_100_percent/common/shelf/status_launcher_menu_icon.png +++ b/ash/resources/default_100_percent/common/shelf/status_launcher_menu_icon.png Binary files differ
diff --git a/ash/resources/default_200_percent/common/shelf/status_icon_background_normal.png b/ash/resources/default_200_percent/common/shelf/status_icon_background_normal.png index cc2d1b7..4de8fa4 100644 --- a/ash/resources/default_200_percent/common/shelf/status_icon_background_normal.png +++ b/ash/resources/default_200_percent/common/shelf/status_icon_background_normal.png Binary files differ
diff --git a/ash/resources/default_200_percent/common/shelf/status_icon_background_onblack_normal.png b/ash/resources/default_200_percent/common/shelf/status_icon_background_onblack_normal.png index 55bac58..d85fa712 100644 --- a/ash/resources/default_200_percent/common/shelf/status_icon_background_onblack_normal.png +++ b/ash/resources/default_200_percent/common/shelf/status_icon_background_onblack_normal.png Binary files differ
diff --git a/ash/resources/default_200_percent/common/shelf/status_icon_background_pressed.png b/ash/resources/default_200_percent/common/shelf/status_icon_background_pressed.png index 498b80bc..d916e54 100644 --- a/ash/resources/default_200_percent/common/shelf/status_icon_background_pressed.png +++ b/ash/resources/default_200_percent/common/shelf/status_icon_background_pressed.png Binary files differ
diff --git a/ash/resources/default_200_percent/common/shelf/status_launcher_menu_icon.png b/ash/resources/default_200_percent/common/shelf/status_launcher_menu_icon.png index a7e0c78..a508a660 100644 --- a/ash/resources/default_200_percent/common/shelf/status_launcher_menu_icon.png +++ b/ash/resources/default_200_percent/common/shelf/status_launcher_menu_icon.png Binary files differ
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc index a6b4275d..743160f 100644 --- a/ash/root_window_controller.cc +++ b/ash/root_window_controller.cc
@@ -16,6 +16,7 @@ #include "ash/common/login_status.h" #include "ash/common/root_window_controller_common.h" #include "ash/common/session/session_state_delegate.h" +#include "ash/common/shelf/shelf_delegate.h" #include "ash/common/shelf/shelf_types.h" #include "ash/common/shell_delegate.h" #include "ash/common/shell_window_ids.h" @@ -460,16 +461,24 @@ } void RootWindowController::ShowShelf() { - if (!shelf_widget_->shelf()) + if (!shelf_) return; - shelf_widget_->shelf()->SetVisible(true); + shelf_widget_->SetShelfVisibility(true); shelf_widget_->status_area_widget()->Show(); } void RootWindowController::CreateShelf() { - if (shelf_widget_->shelf()) + if (shelf_) return; - shelf_widget_->CreateShelf(); + ShelfView* shelf_view = shelf_widget_->CreateShelfView(); + + shelf_.reset( + new Shelf(wm_shelf_aura_.get(), shelf_view, shelf_widget_.get())); + shelf_widget_->set_shelf(shelf_.get()); + // Must be initialized before the delegate is notified because the delegate + // may try to access the WmShelf. + wm_shelf_aura_->SetShelf(shelf_.get()); + WmShell::Get()->shelf_delegate()->OnShelfCreated(shelf_.get()); if (panel_layout_manager_) panel_layout_manager_->SetShelf(wm_shelf_aura_.get()); @@ -481,15 +490,14 @@ } // Notify shell observers that the shelf has been created. - Shell::GetInstance()->OnShelfCreatedForRootWindow( + WmShell::Get()->NotifyShelfCreatedForRootWindow( WmWindowAura::Get(GetRootWindow())); shelf_widget_->PostCreateShelf(); } Shelf* RootWindowController::GetShelf() const { - // TODO(jamescook): Shelf should be owned by this class, not by ShelfWidget. - return shelf_widget_->shelf(); + return shelf_.get(); } void RootWindowController::UpdateAfterLoginStatusChange(LoginStatus status) { @@ -608,11 +616,12 @@ } shelf_widget_.reset(); + shelf_.reset(); } void RootWindowController::MoveWindowsTo(aura::Window* dst) { - // Clear the shelf first, so it doesn't update itself with wrong display info. - workspace_controller_->SetShelf(nullptr); + // Clear the workspace controller, so it doesn't incorrectly update the shelf. + workspace_controller_.reset(); ReparentAllWindows(GetRootWindow(), dst); } @@ -675,7 +684,7 @@ keyboard_controller->AddObserver(workspace_controller_->layout_manager()); keyboard_controller->AddObserver( always_on_top_controller_->GetLayoutManager()); - WmShell::Get()->OnVirtualKeyboardActivated(true); + WmShell::Get()->NotifyVirtualKeyboardActivated(true); aura::Window* parent = GetContainer(kShellWindowId_ImeWindowParentContainer); DCHECK(parent); aura::Window* keyboard_container = keyboard_controller->GetContainerWindow(); @@ -705,7 +714,7 @@ workspace_controller_->layout_manager()); keyboard_controller->RemoveObserver( always_on_top_controller_->GetLayoutManager()); - WmShell::Get()->OnVirtualKeyboardActivated(false); + WmShell::Get()->NotifyVirtualKeyboardActivated(false); } } @@ -790,10 +799,6 @@ aura::Window* root_window = GetRootWindow(); - aura::Window* default_container = - GetContainer(kShellWindowId_DefaultContainer); - // Workspace manager has its own layout managers. - aura::Window* modal_container = root_window->GetChildById(kShellWindowId_SystemModalContainer); DCHECK(modal_container); @@ -811,6 +816,8 @@ lock_modal_container->SetLayoutManager( new SystemModalContainerLayoutManager(lock_modal_container)); + WmWindow* default_container = + WmWindowAura::Get(GetContainer(kShellWindowId_DefaultContainer)); workspace_controller_.reset(new WorkspaceController(default_container)); WmWindow* always_on_top_container = @@ -825,8 +832,7 @@ WmWindow* wm_shelf_container = WmWindowAura::Get(shelf_container); WmWindow* wm_status_container = WmWindowAura::Get(status_container); shelf_widget_.reset(new ShelfWidget(wm_shelf_container, wm_status_container, - wm_shelf_aura_.get(), - workspace_controller())); + wm_shelf_aura_.get())); // Make it easier to resize windows that partially overlap the shelf. Must // occur after the ShelfLayoutManager is constructed by ShelfWidget. shelf_container->SetEventTargeter(base::MakeUnique<ShelfWindowTargeter>(
diff --git a/ash/root_window_controller.h b/ash/root_window_controller.h index a620e2a2..4fbef3f1 100644 --- a/ash/root_window_controller.h +++ b/ash/root_window_controller.h
@@ -280,6 +280,9 @@ // to it during construction of the shelf widget and status tray. std::unique_ptr<WmShelfAura> wm_shelf_aura_; + // Legacy shelf controller. Only present after shelf is created (post-login). + std::unique_ptr<Shelf> shelf_; + // The shelf widget for this root window. std::unique_ptr<ShelfWidget> shelf_widget_;
diff --git a/ash/shelf/shelf.cc b/ash/shelf/shelf.cc index d519ef1..f0619a70 100644 --- a/ash/shelf/shelf.cc +++ b/ash/shelf/shelf.cc
@@ -14,16 +14,12 @@ #include "ash/common/shelf/shelf_navigator.h" #include "ash/common/shelf/shelf_view.h" #include "ash/common/shell_window_ids.h" +#include "ash/common/wm_lookup.h" #include "ash/common/wm_shell.h" +#include "ash/common/wm_window_property.h" #include "ash/root_window_controller.h" -#include "ash/screen_util.h" #include "ash/shelf/shelf_layout_manager.h" -#include "ash/shelf/shelf_util.h" -#include "ash/shell.h" -#include "ash/wm/window_properties.h" #include "ui/aura/window.h" -#include "ui/aura/window_event_dispatcher.h" -#include "ui/aura/window_observer.h" #include "ui/compositor/layer.h" #include "ui/gfx/canvas.h" #include "ui/gfx/image/image.h" @@ -36,22 +32,16 @@ namespace ash { -const char Shelf::kNativeViewName[] = "ShelfView"; - -Shelf::Shelf(ShelfModel* shelf_model, - WmShelf* wm_shelf, +Shelf::Shelf(WmShelf* wm_shelf, + ShelfView* shelf_view, ShelfWidget* shelf_widget) : wm_shelf_(wm_shelf), shelf_widget_(shelf_widget), - shelf_view_(new ShelfView(shelf_model, - WmShell::Get()->shelf_delegate(), - wm_shelf, - shelf_widget)), + shelf_view_(shelf_view), shelf_locking_manager_(wm_shelf) { DCHECK(wm_shelf_); - shelf_view_->Init(); - shelf_widget_->GetContentsView()->AddChildView(shelf_view_); - shelf_widget_->GetNativeView()->SetName(kNativeViewName); + DCHECK(shelf_view_); + DCHECK(shelf_widget_); } Shelf::~Shelf() { @@ -60,13 +50,14 @@ // static Shelf* Shelf::ForPrimaryDisplay() { - return Shelf::ForWindow(Shell::GetPrimaryRootWindow()); + return Shelf::ForWindow(WmShell::Get()->GetPrimaryRootWindow()); } // static -Shelf* Shelf::ForWindow(const aura::Window* window) { +Shelf* Shelf::ForWindow(const WmWindow* window) { + const aura::Window* aura_window = WmWindowAura::GetAuraWindow(window); ShelfWidget* shelf_widget = - RootWindowController::ForWindow(window)->shelf_widget(); + RootWindowController::ForWindow(aura_window)->shelf_widget(); return shelf_widget ? shelf_widget->shelf() : nullptr; } @@ -84,8 +75,8 @@ shelf_view_->OnShelfAlignmentChanged(); shelf_widget_->OnShelfAlignmentChanged(); WmShell::Get()->shelf_delegate()->OnShelfAlignmentChanged(this); - Shell::GetInstance()->OnShelfAlignmentChanged( - WmWindowAura::Get(shelf_widget_->GetNativeWindow()->GetRootWindow())); + WmShell::Get()->NotifyShelfAlignmentChanged( + WmLookup::Get()->GetWindowForWidget(shelf_widget_)->GetRootWindow()); // ShelfLayoutManager will resize the shelf. } @@ -95,8 +86,8 @@ auto_hide_behavior_ = auto_hide_behavior; WmShell::Get()->shelf_delegate()->OnShelfAutoHideBehaviorChanged(this); - Shell::GetInstance()->OnShelfAutoHideBehaviorChanged( - WmWindowAura::Get(shelf_widget_->GetNativeWindow()->GetRootWindow())); + WmShell::Get()->NotifyShelfAutoHideBehaviorChanged( + WmLookup::Get()->GetWindowForWidget(shelf_widget_)->GetRootWindow()); } ShelfAutoHideState Shelf::GetAutoHideState() const { @@ -107,9 +98,8 @@ return shelf_widget_->shelf_layout_manager()->visibility_state(); } -gfx::Rect Shelf::GetScreenBoundsOfItemIconForWindow( - const aura::Window* window) { - ShelfID id = GetShelfIDForWindow(window); +gfx::Rect Shelf::GetScreenBoundsOfItemIconForWindow(WmWindow* window) { + ShelfID id = window->GetIntProperty(WmWindowProperty::SHELF_ID); gfx::Rect bounds(shelf_view_->GetIdealBoundsOfItemIcon(id)); gfx::Point screen_origin; views::View::ConvertPointToScreen(shelf_view_, &screen_origin); @@ -118,11 +108,11 @@ bounds.height()); } -void Shelf::UpdateIconPositionForWindow(aura::Window* window) { +void Shelf::UpdateIconPositionForWindow(WmWindow* window) { + WmWindow* shelf_window = WmLookup::Get()->GetWindowForWidget(shelf_widget_); shelf_view_->UpdatePanelIconPosition( - GetShelfIDForWindow(window), - ScreenUtil::ConvertRectFromScreen(shelf_widget()->GetNativeView(), - window->GetBoundsInScreen()) + window->GetIntProperty(WmWindowProperty::SHELF_ID), + shelf_window->ConvertRectFromScreen(window->GetBoundsInScreen()) .CenterPoint()); } @@ -133,15 +123,15 @@ ui::VKEY_UNKNOWN, // The actual key gets ignored. ui::EF_NONE); - const ShelfItem& item = shelf_view_->model()->items()[index]; - ShelfItemDelegate* item_delegate = - shelf_view_->model()->GetShelfItemDelegate(item.id); + ShelfModel* shelf_model = WmShell::Get()->shelf_model(); + const ShelfItem& item = shelf_model->items()[index]; + ShelfItemDelegate* item_delegate = shelf_model->GetShelfItemDelegate(item.id); item_delegate->ItemSelected(event); } void Shelf::CycleWindowLinear(CycleDirection direction) { int item_index = - GetNextActivatedItemIndex(*(shelf_view_->model()), direction); + GetNextActivatedItemIndex(*WmShell::Get()->shelf_model(), direction); if (item_index >= 0) ActivateShelfItem(item_index); } @@ -162,10 +152,6 @@ return shelf_view_->IsShowingOverflowBubble(); } -void Shelf::SetVisible(bool visible) const { - shelf_view_->SetVisible(visible); -} - bool Shelf::IsVisible() const { return shelf_view_->visible(); } @@ -179,7 +165,7 @@ } void Shelf::LaunchAppIndexAt(int item_index) { - ShelfModel* shelf_model = shelf_view_->model(); + ShelfModel* shelf_model = WmShell::Get()->shelf_model(); const ShelfItems& items = shelf_model->items(); int item_count = shelf_model->item_count(); int indexes_left = item_index >= 0 ? item_index : item_count;
diff --git a/ash/shelf/shelf.h b/ash/shelf/shelf.h index c22f451..696a8f9 100644 --- a/ash/shelf/shelf.h +++ b/ash/shelf/shelf.h
@@ -22,10 +22,6 @@ class ApplicationDragAndDropHost; } -namespace aura { -class Window; -} - namespace gfx { class Rect; } @@ -39,7 +35,6 @@ class FocusCycler; class ShelfDelegate; class ShelfIconObserver; -class ShelfModel; class ShelfView; class WmShelf; @@ -47,15 +42,12 @@ class ShelfTestAPI; } -// Controller for shelf state. All access to state (visibility, auto-hide, etc.) -// should occur via this class. +// Controller for shelf state. +// DEPRECATED: WmShelf is replacing this class as part of the mus/mash refactor. +// Use WmShelf for access to state (visibility, auto-hide, etc.). class ASH_EXPORT Shelf { public: - static const char kNativeViewName[]; - - Shelf(ShelfModel* model, - WmShelf* wm_shelf, - ShelfWidget* widget); + Shelf(WmShelf* wm_shelf, ShelfView* shelf_view, ShelfWidget* widget); ~Shelf(); // Return the shelf for the primary display. NULL if no user is logged in yet. @@ -66,12 +58,14 @@ // Return the shelf for the display that |window| is currently on, or a shelf // on primary display if the shelf per display feature is disabled. NULL if no // user is logged in yet. - static Shelf* ForWindow(const aura::Window* window); + static Shelf* ForWindow(const WmWindow* window); + // DEPRECATED. Use WmShelf::GetAlignment() and SetAlignment(). void SetAlignment(ShelfAlignment alignment); ShelfAlignment alignment() const { return alignment_; } // Sets the ShelfAutoHideBehavior. See enum description for details. + // DEPRECATED. Use WmShelf::GetAutoHideBehavior() and SetAutoHideBehavior(). void SetAutoHideBehavior(ShelfAutoHideBehavior auto_hide_behavior); ShelfAutoHideBehavior auto_hide_behavior() const { return auto_hide_behavior_; @@ -83,11 +77,11 @@ // Returns the screen bounds of the item for the specified window. If there is // no item for the specified window an empty rect is returned. - gfx::Rect GetScreenBoundsOfItemIconForWindow(const aura::Window* window); + gfx::Rect GetScreenBoundsOfItemIconForWindow(WmWindow* window); // Updates the icon position given the current window bounds. This is used // when dragging panels to reposition them with respect to the other panels. - void UpdateIconPositionForWindow(aura::Window* window); + void UpdateIconPositionForWindow(WmWindow* window); // Activates the the shelf item specified by the index in the list of shelf // items. @@ -102,9 +96,10 @@ // Returns true if the shelf is showing a context menu. bool IsShowingMenu() const; + // TODO(jamescook): Migrate this to ShelfWidget. bool IsShowingOverflowBubble() const; - void SetVisible(bool visible) const; + // TODO(jamescook): Migrate to ShelfWidget::IsShelfVisible(). bool IsVisible() const; void SchedulePaint();
diff --git a/ash/shelf/shelf_bezel_event_filter.cc b/ash/shelf/shelf_bezel_event_filter.cc deleted file mode 100644 index 224180c7..0000000 --- a/ash/shelf/shelf_bezel_event_filter.cc +++ /dev/null
@@ -1,62 +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 "ash/shelf/shelf_bezel_event_filter.h" - -#include "ash/shelf/shelf_layout_manager.h" -#include "ash/shell.h" -#include "ui/aura/window.h" -#include "ui/display/display.h" -#include "ui/display/screen.h" -#include "ui/gfx/geometry/point.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/wm/core/coordinate_conversion.h" - -namespace ash { - -ShelfBezelEventFilter::ShelfBezelEventFilter( - ShelfLayoutManager* shelf_layout_manager) - : shelf_layout_manager_(shelf_layout_manager), in_touch_drag_(false) { - Shell::GetInstance()->AddPreTargetHandler(this); -} - -ShelfBezelEventFilter::~ShelfBezelEventFilter() { - Shell::GetInstance()->RemovePreTargetHandler(this); -} - -void ShelfBezelEventFilter::OnGestureEvent(ui::GestureEvent* event) { - gfx::Point point_in_screen(event->location()); - aura::Window* target = static_cast<aura::Window*>(event->target()); - ::wm::ConvertPointToScreen(target, &point_in_screen); - gfx::Rect screen = display::Screen::GetScreen() - ->GetDisplayNearestPoint(point_in_screen) - .bounds(); - if ((!screen.Contains(point_in_screen) && - IsShelfOnBezel(screen, point_in_screen)) || - in_touch_drag_) { - if (shelf_layout_manager_->ProcessGestureEvent(*event)) { - switch (event->type()) { - case ui::ET_GESTURE_SCROLL_BEGIN: - in_touch_drag_ = true; - break; - case ui::ET_GESTURE_SCROLL_END: - case ui::ET_SCROLL_FLING_START: - in_touch_drag_ = false; - break; - default: - break; - } - event->StopPropagation(); - } - } -} - -bool ShelfBezelEventFilter::IsShelfOnBezel(const gfx::Rect& screen, - const gfx::Point& point) const { - return shelf_layout_manager_->SelectValueForShelfAlignment( - point.y() >= screen.bottom(), point.x() <= screen.x(), - point.x() >= screen.right()); -} - -} // namespace ash
diff --git a/ash/shelf/shelf_bezel_event_filter.h b/ash/shelf/shelf_bezel_event_filter.h deleted file mode 100644 index ff7d14d0..0000000 --- a/ash/shelf/shelf_bezel_event_filter.h +++ /dev/null
@@ -1,40 +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 ASH_SHELF_SHELF_BEZEL_EVENT_FILTER_H_ -#define ASH_SHELF_SHELF_BEZEL_EVENT_FILTER_H_ - -#include "base/macros.h" -#include "ui/events/event_handler.h" - -namespace gfx { -class Point; -class Rect; -} - -namespace ash { -class ShelfLayoutManager; - -// Detects and forwards touch gestures that occur on a bezel sensor to the -// shelf. -class ShelfBezelEventFilter : public ui::EventHandler { - public: - explicit ShelfBezelEventFilter(ShelfLayoutManager* shelf_layout_manager); - ~ShelfBezelEventFilter() override; - - // Overridden from ui::EventHandler: - void OnGestureEvent(ui::GestureEvent* event) override; - - private: - bool IsShelfOnBezel(const gfx::Rect& screen, const gfx::Point& point) const; - - ShelfLayoutManager* shelf_layout_manager_; - bool in_touch_drag_; - - DISALLOW_COPY_AND_ASSIGN(ShelfBezelEventFilter); -}; - -} // namespace ash - -#endif // ASH_SHELF_SHELF_BEZEL_EVENT_FILTER_H_
diff --git a/ash/shelf/shelf_bezel_event_handler.cc b/ash/shelf/shelf_bezel_event_handler.cc new file mode 100644 index 0000000..da40409 --- /dev/null +++ b/ash/shelf/shelf_bezel_event_handler.cc
@@ -0,0 +1,70 @@ +// 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 "ash/shelf/shelf_bezel_event_handler.h" + +#include "ash/common/shelf/wm_shelf.h" +#include "ash/shell.h" +#include "ui/aura/window.h" +#include "ui/display/display.h" +#include "ui/display/screen.h" +#include "ui/events/event.h" +#include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/wm/core/coordinate_conversion.h" + +namespace ash { + +ShelfBezelEventHandler::ShelfBezelEventHandler(WmShelf* shelf) + : shelf_(shelf), in_touch_drag_(false) { + Shell::GetInstance()->AddPreTargetHandler(this); +} + +ShelfBezelEventHandler::~ShelfBezelEventHandler() { + Shell::GetInstance()->RemovePreTargetHandler(this); +} + +void ShelfBezelEventHandler::OnGestureEvent(ui::GestureEvent* event) { + gfx::Point point_in_screen(event->location()); + aura::Window* target = static_cast<aura::Window*>(event->target()); + ::wm::ConvertPointToScreen(target, &point_in_screen); + gfx::Rect screen = display::Screen::GetScreen() + ->GetDisplayNearestPoint(point_in_screen) + .bounds(); + if ((!screen.Contains(point_in_screen) && + IsShelfOnBezel(screen, point_in_screen)) || + in_touch_drag_) { + if (shelf_->ProcessGestureEvent(*event)) { + switch (event->type()) { + case ui::ET_GESTURE_SCROLL_BEGIN: + in_touch_drag_ = true; + break; + case ui::ET_GESTURE_SCROLL_END: + case ui::ET_SCROLL_FLING_START: + in_touch_drag_ = false; + break; + default: + break; + } + event->StopPropagation(); + } + } +} + +bool ShelfBezelEventHandler::IsShelfOnBezel(const gfx::Rect& screen, + const gfx::Point& point) const { + switch (shelf_->GetAlignment()) { + case SHELF_ALIGNMENT_BOTTOM: + case SHELF_ALIGNMENT_BOTTOM_LOCKED: + return point.y() >= screen.bottom(); + case SHELF_ALIGNMENT_LEFT: + return point.x() <= screen.x(); + case SHELF_ALIGNMENT_RIGHT: + return point.x() >= screen.right(); + } + NOTREACHED(); + return false; +} + +} // namespace ash
diff --git a/ash/shelf/shelf_bezel_event_handler.h b/ash/shelf/shelf_bezel_event_handler.h new file mode 100644 index 0000000..e46550e3 --- /dev/null +++ b/ash/shelf/shelf_bezel_event_handler.h
@@ -0,0 +1,39 @@ +// 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 ASH_SHELF_SHELF_BEZEL_EVENT_HANDLER_H_ +#define ASH_SHELF_SHELF_BEZEL_EVENT_HANDLER_H_ + +#include "base/macros.h" +#include "ui/events/event_handler.h" + +namespace gfx { +class Point; +class Rect; +} + +namespace ash { +class WmShelf; + +// Forwards touch gestures on a bezel sensor to the shelf. +class ShelfBezelEventHandler : public ui::EventHandler { + public: + explicit ShelfBezelEventHandler(WmShelf* shelf); + ~ShelfBezelEventHandler() override; + + // Overridden from ui::EventHandler: + void OnGestureEvent(ui::GestureEvent* event) override; + + private: + bool IsShelfOnBezel(const gfx::Rect& screen, const gfx::Point& point) const; + + WmShelf* shelf_; + bool in_touch_drag_; + + DISALLOW_COPY_AND_ASSIGN(ShelfBezelEventHandler); +}; + +} // namespace ash + +#endif // ASH_SHELF_SHELF_BEZEL_EVENT_HANDLER_H_
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index 4422b63..a4f758b 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc
@@ -8,6 +8,7 @@ #include <cmath> #include <vector> +#include "ash/common/ash_switches.h" #include "ash/common/material_design/material_design_controller.h" #include "ash/common/session/session_state_delegate.h" #include "ash/common/shelf/shelf_constants.h" @@ -25,12 +26,9 @@ #include "ash/common/wm_shell.h" #include "ash/common/wm_window.h" #include "ash/shelf/shelf.h" -#include "ash/shelf/shelf_bezel_event_filter.h" #include "ash/shelf/shelf_layout_manager_observer.h" -#include "ash/shell.h" -#include "ash/wm/window_animations.h" -#include "ash/wm/workspace_controller.h" #include "base/auto_reset.h" +#include "base/command_line.h" #include "base/i18n/rtl.h" #include "ui/compositor/layer.h" #include "ui/compositor/layer_animation_observer.h" @@ -39,6 +37,8 @@ #include "ui/display/display.h" #include "ui/display/screen.h" #include "ui/events/event.h" +#include "ui/events/event_handler.h" +#include "ui/keyboard/keyboard_controller.h" #include "ui/keyboard/keyboard_util.h" #include "ui/views/border.h" #include "ui/views/widget/widget.h" @@ -49,6 +49,9 @@ // Delay before showing the shelf. This is after the mouse stops moving. const int kAutoHideDelayMS = 200; +// Duration of the animation to show or hide the shelf. +const int kAnimationDurationMS = 200; + // To avoid hiding the shelf when the mouse transitions from a message bubble // into the shelf, the hit test area is enlarged by this amount of pixels to // keep the shelf from hiding. @@ -144,10 +147,8 @@ ShelfLayoutManager::ShelfLayoutManager(ShelfWidget* shelf_widget) : updating_bounds_(false), shelf_widget_(shelf_widget), - workspace_controller_(NULL), window_overlaps_shelf_(false), mouse_over_shelf_when_auto_hide_timer_started_(false), - bezel_event_filter_(new ShelfBezelEventFilter(this)), gesture_drag_status_(GESTURE_DRAG_NONE), gesture_drag_amount_(0.f), gesture_drag_auto_hide_state_(SHELF_AUTO_HIDE_SHOWN), @@ -175,10 +176,6 @@ void ShelfLayoutManager::PrepareForShutdown() { in_shutdown_ = true; - // Clear all event filters, otherwise sometimes those filters may catch - // synthesized mouse event and cause crashes during the shutdown. - set_workspace_controller(NULL); - bezel_event_filter_.reset(); // Stop observing changes to avoid updating a partially destructed shelf. WmShell::Get()->RemoveActivationObserver(this); } @@ -209,16 +206,20 @@ return target_bounds.shelf_bounds_in_root.size(); } -void ShelfLayoutManager::LayoutShelf() { +void ShelfLayoutManager::LayoutShelfAndUpdateBounds(bool change_work_area) { TargetBounds target_bounds; CalculateTargetBounds(state_, &target_bounds); - UpdateBoundsAndOpacity(target_bounds, false, NULL); + UpdateBoundsAndOpacity(target_bounds, false, change_work_area, NULL); // Update insets in ShelfWindowTargeter when shelf bounds change. FOR_EACH_OBSERVER(ShelfLayoutManagerObserver, observers_, WillChangeVisibilityState(visibility_state())); } +void ShelfLayoutManager::LayoutShelf() { + LayoutShelfAndUpdateBounds(true); +} + ShelfVisibilityState ShelfLayoutManager::CalculateShelfVisibility() { switch (shelf_widget_->shelf()->auto_hide_behavior()) { case SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS: @@ -232,9 +233,10 @@ } void ShelfLayoutManager::UpdateVisibilityState() { - // Bail out early when there is no |workspace_controller_|, which happens - // during shutdown after PrepareForShutdown. Also bail before a shelf exists. - if (!workspace_controller_ || !shelf_widget_->shelf()) + WmWindow* shelf_window = WmLookup::Get()->GetWindowForWidget(shelf_widget_); + WmRootWindowController* controller = shelf_window->GetRootWindowController(); + // Bail out early before the shelf is initialized or after it is destroyed. + if (!controller || !shelf_widget_->shelf() || in_shutdown_) return; if (state_.is_screen_locked || state_.is_adding_user_screen) { @@ -245,7 +247,7 @@ // TODO(zelidrag): Verify shelf drag animation still shows on the device // when we are in SHELF_AUTO_HIDE_ALWAYS_HIDDEN. wm::WorkspaceWindowState window_state( - workspace_controller_->GetWindowState()); + controller->GetWorkspaceWindowState()); switch (window_state) { case wm::WORKSPACE_WINDOW_STATE_FULL_SCREEN: { if (IsShelfHiddenForFullscreen()) { @@ -402,11 +404,6 @@ UpdateShelfVisibilityAfterLoginUIChange(); } -void ShelfLayoutManager::OnShelfAlignmentChanged(WmWindow* root_window) { - if (Shell::GetInstance()->in_mus()) - LayoutShelf(); -} - void ShelfLayoutManager::OnShelfAutoHideBehaviorChanged(WmWindow* root_window) { UpdateVisibilityState(); } @@ -426,9 +423,15 @@ bool keyboard_is_about_to_hide = false; if (new_bounds.IsEmpty() && !keyboard_bounds_.IsEmpty()) keyboard_is_about_to_hide = true; + // If new window behavior flag enabled and in non-sticky mode, do not change + // the work area. + bool change_work_area = + (!base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kAshUseNewVKWindowBehavior) || + keyboard::KeyboardController::GetInstance()->get_lock_keyboard()); keyboard_bounds_ = new_bounds; - OnWindowResized(); + LayoutShelfAndUpdateBounds(change_work_area); // On login screen if keyboard has been just hidden, update bounds just once // but ignore target_bounds.work_area_insets since shelf overlaps with login @@ -474,15 +477,14 @@ ShelfLayoutManager::TargetBounds::~TargetBounds() {} void ShelfLayoutManager::SetState(ShelfVisibilityState visibility_state) { - if (!shelf_widget_->GetNativeView()) - return; - State state; state.visibility_state = visibility_state; state.auto_hide_state = CalculateAutoHideState(visibility_state); - state.window_state = workspace_controller_ - ? workspace_controller_->GetWindowState() - : wm::WORKSPACE_WINDOW_STATE_DEFAULT; + + WmWindow* shelf_window = WmLookup::Get()->GetWindowForWidget(shelf_widget_); + WmRootWindowController* controller = shelf_window->GetRootWindowController(); + state.window_state = controller ? controller->GetWorkspaceWindowState() + : wm::WORKSPACE_WINDOW_STATE_DEFAULT; // Preserve the log in screen states. state.is_adding_user_screen = state_.is_adding_user_screen; state.is_screen_locked = state_.is_screen_locked; @@ -541,9 +543,9 @@ TargetBounds target_bounds; CalculateTargetBounds(state_, &target_bounds); - UpdateBoundsAndOpacity(target_bounds, true, delay_background_change - ? update_shelf_observer_ - : NULL); + UpdateBoundsAndOpacity( + target_bounds, true /* animate */, true /* change_work_area */, + delay_background_change ? update_shelf_observer_ : NULL); // The delegate must be notified after |state_| is updated so that it can // query the new target bounds. @@ -567,6 +569,7 @@ void ShelfLayoutManager::UpdateBoundsAndOpacity( const TargetBounds& target_bounds, bool animate, + bool change_work_area, ui::ImplicitAnimationObserver* observer) { base::AutoReset<bool> auto_reset_updating_bounds(&updating_bounds_, true); { @@ -576,7 +579,7 @@ GetLayer(shelf_widget_->status_area_widget())->GetAnimator()); if (animate) { int duration = duration_override_in_ms_ ? duration_override_in_ms_ - : kCrossFadeDurationMS; + : kAnimationDurationMS; shelf_animation_setter.SetTransitionDuration( base::TimeDelta::FromMilliseconds(duration)); shelf_animation_setter.SetTweenType(gfx::Tween::EASE_OUT); @@ -596,12 +599,9 @@ status_animation_setter.AddObserver(observer); GetLayer(shelf_widget_)->SetOpacity(target_bounds.opacity); - // mash::wm::ShelfLayout manages window bounds when running in mash. - if (!Shell::GetInstance()->in_mus()) { - WmWindow* window = WmLookup::Get()->GetWindowForWidget(shelf_widget_); - shelf_widget_->SetBounds(window->GetParent()->ConvertRectToScreen( - target_bounds.shelf_bounds_in_root)); - } + WmWindow* shelf_window = WmLookup::Get()->GetWindowForWidget(shelf_widget_); + shelf_widget_->SetBounds(shelf_window->GetParent()->ConvertRectToScreen( + target_bounds.shelf_bounds_in_root)); GetLayer(shelf_widget_->status_area_widget()) ->SetOpacity(target_bounds.status_opacity); @@ -618,25 +618,23 @@ // this can be simplified. gfx::Rect status_bounds = target_bounds.status_bounds_in_shelf; status_bounds.Offset(target_bounds.shelf_bounds_in_root.OffsetFromOrigin()); - // mash::wm::ShelfLayout manages window bounds when running mash. - if (!Shell::GetInstance()->in_mus()) { - WmWindow* window = WmLookup::Get()->GetWindowForWidget( - shelf_widget_->status_area_widget()); - shelf_widget_->status_area_widget()->SetBounds( - window->GetParent()->ConvertRectToScreen(status_bounds)); - } + WmWindow* status_window = WmLookup::Get()->GetWindowForWidget( + shelf_widget_->status_area_widget()); + shelf_widget_->status_area_widget()->SetBounds( + status_window->GetParent()->ConvertRectToScreen(status_bounds)); + // For crbug.com/622431, when the shelf alignment is BOTTOM_LOCKED, we // don't set display work area, as it is not real user-set alignment. if (!state_.is_screen_locked && - shelf_widget_->GetAlignment() != SHELF_ALIGNMENT_BOTTOM_LOCKED) { + shelf_widget_->GetAlignment() != SHELF_ALIGNMENT_BOTTOM_LOCKED && + change_work_area) { gfx::Insets insets; // If user session is blocked (login to new user session or add user to // the existing session - multi-profile) then give 100% of work area only // if keyboard is not shown. if (!state_.is_adding_user_screen || !keyboard_bounds_.IsEmpty()) insets = target_bounds.work_area_insets; - WmWindow* window = WmLookup::Get()->GetWindowForWidget(shelf_widget_); - WmShell::Get()->SetDisplayWorkAreaInsets(window, insets); + WmShell::Get()->SetDisplayWorkAreaInsets(shelf_window, insets); } } @@ -907,25 +905,22 @@ shelf_widget_->status_area_widget()->IsActive())) return SHELF_AUTO_HIDE_SHOWN; - // TODO(jamescook): Track visible windows on mash via ShelfDelegate. - if (!Shell::GetInstance()->in_mus()) { - const std::vector<WmWindow*> windows = - WmShell::Get()->mru_window_tracker()->BuildWindowListIgnoreModal(); + const std::vector<WmWindow*> windows = + WmShell::Get()->mru_window_tracker()->BuildWindowListIgnoreModal(); - // Process the window list and check if there are any visible windows. - bool visible_window = false; - for (size_t i = 0; i < windows.size(); ++i) { - if (windows[i] && windows[i]->IsVisible() && - !windows[i]->GetWindowState()->IsMinimized() && - windows[i]->GetDisplayNearestWindow().id() == shelf_display_id) { - visible_window = true; - break; - } + // Process the window list and check if there are any visible windows. + bool visible_window = false; + for (size_t i = 0; i < windows.size(); ++i) { + if (windows[i] && windows[i]->IsVisible() && + !windows[i]->GetWindowState()->IsMinimized() && + windows[i]->GetDisplayNearestWindow().id() == shelf_display_id) { + visible_window = true; + break; } - // If there are no visible windows do not hide the shelf. - if (!visible_window) - return SHELF_AUTO_HIDE_SHOWN; } + // If there are no visible windows do not hide the shelf. + if (!visible_window) + return SHELF_AUTO_HIDE_SHOWN; if (gesture_drag_status_ == GESTURE_DRAG_COMPLETE_IN_PROGRESS) return gesture_drag_auto_hide_state_; @@ -1032,7 +1027,8 @@ } TargetBounds target_bounds; CalculateTargetBounds(state_, &target_bounds); - UpdateBoundsAndOpacity(target_bounds, true, NULL); + UpdateBoundsAndOpacity(target_bounds, true /* animate */, + true /* change_work_area */, NULL); UpdateVisibilityState(); }
diff --git a/ash/shelf/shelf_layout_manager.h b/ash/shelf/shelf_layout_manager.h index 9e180ad..b28a16e7 100644 --- a/ash/shelf/shelf_layout_manager.h +++ b/ash/shelf/shelf_layout_manager.h
@@ -32,11 +32,9 @@ namespace ash { class PanelLayoutManagerTest; -class ShelfBezelEventFilter; class ShelfLayoutManagerObserver; class ShelfLayoutManagerTest; class ShelfWidget; -class WorkspaceController; // ShelfLayoutManager is the layout manager responsible for the shelf and // status widgets. The shelf is given the total available width and told the @@ -57,10 +55,6 @@ explicit ShelfLayoutManager(ShelfWidget* shelf_widget); ~ShelfLayoutManager() override; - void set_workspace_controller(WorkspaceController* controller) { - workspace_controller_ = controller; - } - bool updating_bounds() const { return updating_bounds_; } // Clears internal data for shutdown process. @@ -86,6 +80,10 @@ } // Stops any animations and sets the bounds of the shelf and status widgets. + void LayoutShelfAndUpdateBounds(bool change_work_area); + + // Stops any animations, sets the bounds of the shelf and status widgets, and + // changes the work area void LayoutShelf(); // Returns shelf visibility state based on current value of auto hide @@ -134,7 +132,6 @@ // Overridden from ShellObserver: void OnLockStateChanged(bool locked) override; - void OnShelfAlignmentChanged(WmWindow* root_window) override; void OnShelfAutoHideBehaviorChanged(WmWindow* root_window) override; void OnPinnedStateChanged(WmWindow* pinned_window) override; @@ -237,9 +234,11 @@ // Updates the bounds and opacity of the shelf and status widgets. // If |observer| is specified, it will be called back when the animations, if - // any, are complete. + // any, are complete. |change_work_area| specifies whether or not to update + // the work area of the screen. void UpdateBoundsAndOpacity(const TargetBounds& target_bounds, bool animate, + bool change_work_area, ui::ImplicitAnimationObserver* observer); // Stops any animations and progresses them to the end. @@ -313,8 +312,6 @@ ShelfWidget* shelf_widget_; - WorkspaceController* workspace_controller_; - // Do any windows overlap the shelf? This is maintained by WorkspaceManager. bool window_overlaps_shelf_; @@ -324,9 +321,6 @@ // False when neither the auto hide timer nor the timer task are running. bool mouse_over_shelf_when_auto_hide_timer_started_; - // EventFilter used to detect when user issues a gesture on a bezel sensor. - std::unique_ptr<ShelfBezelEventFilter> bezel_event_filter_; - base::ObserverList<ShelfLayoutManagerObserver> observers_; // The shelf reacts to gesture-drags, and can be set to auto-hide for certain
diff --git a/ash/shelf/shelf_layout_manager_unittest.cc b/ash/shelf/shelf_layout_manager_unittest.cc index 95713ce0..2a5e248 100644 --- a/ash/shelf/shelf_layout_manager_unittest.cc +++ b/ash/shelf/shelf_layout_manager_unittest.cc
@@ -44,6 +44,9 @@ #include "ui/display/screen.h" #include "ui/events/gesture_detection/gesture_configuration.h" #include "ui/events/test/event_generator.h" +#include "ui/keyboard/keyboard_controller.h" +#include "ui/keyboard/keyboard_ui.h" +#include "ui/keyboard/keyboard_util.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" @@ -1936,4 +1939,110 @@ EXPECT_EQ(gfx::Point(500, 400), status_area_bounds.bottom_right()); } -} // namespace ash +class ShelfLayoutManagerKeyboardTest : public test::AshTestBase { + public: + ShelfLayoutManagerKeyboardTest() {} + ~ShelfLayoutManagerKeyboardTest() override {} + + // test::AshTestBase: + void SetUp() override { + test::AshTestBase::SetUp(); + UpdateDisplay("800x600"); + keyboard::SetAccessibilityKeyboardEnabled(true); + } + + void InitKeyboardBounds() { + gfx::Rect work_area( + display::Screen::GetScreen()->GetPrimaryDisplay().work_area()); + keyboard_bounds_.SetRect(work_area.x(), + work_area.y() + work_area.height() / 2, + work_area.width(), work_area.height() / 2); + } + + void EnableNewVKMode() { + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (!command_line->HasSwitch(switches::kAshUseNewVKWindowBehavior)) { + command_line->AppendSwitch(switches::kAshUseNewVKWindowBehavior); + } + } + + const gfx::Rect& keyboard_bounds() const { return keyboard_bounds_; } + + private: + gfx::Rect keyboard_bounds_; + + DISALLOW_COPY_AND_ASSIGN(ShelfLayoutManagerKeyboardTest); +}; + +TEST_F(ShelfLayoutManagerKeyboardTest, ShelfChangeWorkAreaInNonStickyMode) { + ShelfLayoutManager* layout_manager = GetShelfLayoutManager(); + keyboard::SetAccessibilityKeyboardEnabled(true); + InitKeyboardBounds(); + Shell::GetInstance()->CreateKeyboard(); + keyboard::KeyboardController* kb_controller = + keyboard::KeyboardController::GetInstance(); + gfx::Rect orig_work_area( + display::Screen::GetScreen()->GetPrimaryDisplay().work_area()); + + // Open keyboard in non-sticky mode. + kb_controller->ShowKeyboard(false); + layout_manager->OnKeyboardBoundsChanging(keyboard_bounds()); + + // Work area should be changed. + EXPECT_NE(orig_work_area, + display::Screen::GetScreen()->GetPrimaryDisplay().work_area()); + + kb_controller->HideKeyboard( + keyboard::KeyboardController::HIDE_REASON_AUTOMATIC); + layout_manager->OnKeyboardBoundsChanging(gfx::Rect()); + EXPECT_EQ(orig_work_area, + display::Screen::GetScreen()->GetPrimaryDisplay().work_area()); + + // Open keyboard in sticky mode. + kb_controller->ShowKeyboard(true); + layout_manager->OnKeyboardBoundsChanging(keyboard_bounds()); + + // Work area should be changed. + EXPECT_NE(orig_work_area, + display::Screen::GetScreen()->GetPrimaryDisplay().work_area()); +} + +// When kAshUseNewVKWindowBehavior flag enabled, do not change accessibility +// keyboard work area in non-sticky mode. +TEST_F(ShelfLayoutManagerKeyboardTest, + ShelfIgnoreWorkAreaChangeInNonStickyMode) { + // Append flag to ignore work area change in non-sticky mode. + EnableNewVKMode(); + + ShelfLayoutManager* layout_manager = GetShelfLayoutManager(); + InitKeyboardBounds(); + Shell::GetInstance()->CreateKeyboard(); + keyboard::KeyboardController* kb_controller = + keyboard::KeyboardController::GetInstance(); + gfx::Rect orig_work_area( + display::Screen::GetScreen()->GetPrimaryDisplay().work_area()); + + // Open keyboard in non-sticky mode. + kb_controller->ShowKeyboard(false); + layout_manager->OnKeyboardBoundsChanging(keyboard_bounds()); + + // Work area should not be changed. + EXPECT_EQ(orig_work_area, + display::Screen::GetScreen()->GetPrimaryDisplay().work_area()); + + kb_controller->HideKeyboard( + keyboard::KeyboardController::HIDE_REASON_AUTOMATIC); + layout_manager->OnKeyboardBoundsChanging(gfx::Rect()); + EXPECT_EQ(orig_work_area, + display::Screen::GetScreen()->GetPrimaryDisplay().work_area()); + + // Open keyboard in sticky mode. + kb_controller->ShowKeyboard(true); + layout_manager->OnKeyboardBoundsChanging(keyboard_bounds()); + + // Work area should be changed. + EXPECT_NE(orig_work_area, + display::Screen::GetScreen()->GetPrimaryDisplay().work_area()); +} + +} // namespace ash \ No newline at end of file
diff --git a/ash/shelf/shelf_view_unittest.cc b/ash/shelf/shelf_view_unittest.cc index ee9e276..31247b1 100644 --- a/ash/shelf/shelf_view_unittest.cc +++ b/ash/shelf/shelf_view_unittest.cc
@@ -20,8 +20,10 @@ #include "ash/common/shelf/shelf_tooltip_manager.h" #include "ash/common/shelf/wm_shelf.h" #include "ash/common/shell_window_ids.h" +#include "ash/common/system/web_notification/web_notification_tray.h" #include "ash/common/test/material_design_controller_test_api.h" #include "ash/common/wm_shell.h" +#include "ash/common/wm_window.h" #include "ash/shelf/shelf_widget.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" @@ -122,7 +124,7 @@ ShelfViewTestAPI* shelf_view_test() { return shelf_view_test_.get(); } Shelf* ShelfForSecondaryDisplay() { - return Shelf::ForWindow(Shell::GetAllRootWindows()[1]); + return Shelf::ForWindow(WmShell::Get()->GetAllRootWindows()[1]); } private: @@ -313,6 +315,8 @@ Shelf* shelf = Shelf::ForPrimaryDisplay(); shelf_view_ = ShelfTestAPI(shelf).shelf_view(); + WebNotificationTray::DisableAnimationsForTest(true); + // The bounds should be big enough for 4 buttons + overflow chevron. shelf_view_->SetBounds(0, 0, 500, GetShelfConstant(SHELF_SIZE)); @@ -326,6 +330,8 @@ } void TearDown() override { + WebNotificationTray::DisableAnimationsForTest(false); // Reenable animation + shelf_delegate_ = nullptr; test_api_.reset(); AshTestBase::TearDown(); @@ -1686,7 +1692,8 @@ return; UpdateDisplay("800x600,800x600"); - Shelf* secondary_shelf = Shelf::ForWindow(Shell::GetAllRootWindows()[1]); + Shelf* secondary_shelf = + Shelf::ForWindow(WmShell::Get()->GetAllRootWindows()[1]); ShelfView* shelf_view_for_secondary = ShelfTestAPI(secondary_shelf).shelf_view(); @@ -1755,9 +1762,9 @@ return; UpdateDisplay("800x600,800x600"); - ASSERT_EQ(2U, Shell::GetAllRootWindows().size()); + ASSERT_EQ(2U, WmShell::Get()->GetAllRootWindows().size()); - aura::Window* second_root = Shell::GetAllRootWindows()[1]; + WmWindow* second_root = WmShell::Get()->GetAllRootWindows()[1]; Shelf* secondary_shelf = Shelf::ForWindow(second_root); secondary_shelf->SetAlignment(SHELF_ALIGNMENT_LEFT); @@ -1777,9 +1784,10 @@ // Fetch the start point of dragging. gfx::Point start_point = button->GetBoundsInScreen().CenterPoint(); - ::wm::ConvertPointFromScreen(second_root, &start_point); + start_point = second_root->ConvertPointFromScreen(start_point); - ui::test::EventGenerator generator(second_root, start_point); + ui::test::EventGenerator generator(Shell::GetAllRootWindows()[1], + start_point); // Rip off the browser item. generator.PressLeftButton();
diff --git a/ash/shelf/shelf_widget.cc b/ash/shelf/shelf_widget.cc index 44c0a133..65aa1bc0 100644 --- a/ash/shelf/shelf_widget.cc +++ b/ash/shelf/shelf_widget.cc
@@ -11,6 +11,7 @@ #include "ash/common/shelf/shelf_background_animator_observer.h" #include "ash/common/shelf/shelf_constants.h" #include "ash/common/shelf/shelf_delegate.h" +#include "ash/common/shelf/shelf_view.h" #include "ash/common/shelf/wm_dimmer_view.h" #include "ash/common/shelf/wm_shelf.h" #include "ash/common/shelf/wm_shelf_util.h" @@ -19,10 +20,8 @@ #include "ash/common/wm_root_window_controller.h" #include "ash/common/wm_shell.h" #include "ash/common/wm_window.h" -#include "ash/shelf/shelf.h" #include "ash/shelf/shelf_layout_manager.h" #include "ash/wm/status_area_layout_manager.h" -#include "ash/wm/workspace_controller.h" #include "base/memory/ptr_util.h" #include "grit/ash_resources.h" #include "ui/base/resource/resource_bundle.h" @@ -52,7 +51,7 @@ public views::AccessiblePaneView, public ShelfBackgroundAnimatorObserver { public: - explicit DelegateView(ShelfWidget* shelf); + DelegateView(WmShelf* wm_shelf, ShelfWidget* shelf); ~DelegateView() override; void set_focus_cycler(FocusCycler* focus_cycler) { @@ -103,6 +102,7 @@ } private: + WmShelf* wm_shelf_; ShelfWidget* shelf_widget_; FocusCycler* focus_cycler_; int asset_background_alpha_; @@ -124,14 +124,18 @@ DISALLOW_COPY_AND_ASSIGN(DelegateView); }; -ShelfWidget::DelegateView::DelegateView(ShelfWidget* shelf_widget) - : shelf_widget_(shelf_widget), +ShelfWidget::DelegateView::DelegateView(WmShelf* wm_shelf, + ShelfWidget* shelf_widget) + : wm_shelf_(wm_shelf), + shelf_widget_(shelf_widget), focus_cycler_(nullptr), asset_background_alpha_(0), opaque_background_(ui::LAYER_SOLID_COLOR), opaque_foreground_(ui::LAYER_SOLID_COLOR), dimmer_view_(nullptr), disable_dimming_animations_for_test_(false) { + DCHECK(wm_shelf_); + DCHECK(shelf_widget_); SetLayoutManager(new views::FillLayout()); set_allow_deactivate_on_esc(true); opaque_background_.SetColor(SK_ColorBLACK); @@ -183,10 +187,10 @@ ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance(); gfx::ImageSkia shelf_background = *rb->GetImageSkiaNamed(IDR_ASH_SHELF_BACKGROUND); - const bool horizontal = IsHorizontalAlignment(shelf_widget_->GetAlignment()); + const bool horizontal = wm_shelf_->IsHorizontalAlignment(); if (!horizontal) { shelf_background = gfx::ImageSkiaOperations::CreateRotatedImage( - shelf_background, shelf_widget_->GetAlignment() == SHELF_ALIGNMENT_LEFT + shelf_background, wm_shelf_->GetAlignment() == SHELF_ALIGNMENT_LEFT ? SkBitmapOperations::ROTATION_90_CW : SkBitmapOperations::ROTATION_270_CW); } @@ -286,10 +290,11 @@ ShelfWidget::ShelfWidget(WmWindow* shelf_container, WmWindow* status_container, - WmShelfAura* wm_shelf_aura, - WorkspaceController* workspace_controller) + WmShelfAura* wm_shelf_aura) : wm_shelf_aura_(wm_shelf_aura), - delegate_view_(new DelegateView(this)), + shelf_(nullptr), + delegate_view_(new DelegateView(wm_shelf_aura, this)), + shelf_view_(nullptr), background_animator_(SHELF_BACKGROUND_DEFAULT, wm_shelf_aura_), activating_as_fallback_(false) { background_animator_.AddObserver(this); @@ -297,6 +302,7 @@ views::Widget::InitParams params( views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); + params.name = "ShelfWidget"; params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; params.delegate = delegate_view_; @@ -313,8 +319,6 @@ shelf_layout_manager_ = new ShelfLayoutManager(this); shelf_layout_manager_->AddObserver(this); shelf_container->SetLayoutManager(base::WrapUnique(shelf_layout_manager_)); - shelf_layout_manager_->set_workspace_controller(workspace_controller); - workspace_controller->SetShelf(shelf_layout_manager_); background_animator_.PaintBackground( shelf_layout_manager_->GetShelfBackgroundType(), BACKGROUND_CHANGE_IMMEDIATE); @@ -402,8 +406,8 @@ } ShelfAlignment ShelfWidget::GetAlignment() const { - // TODO(msw): This should not be called before |shelf_| is created. - return shelf_ ? shelf_->alignment() : SHELF_ALIGNMENT_BOTTOM_LOCKED; + WmShelf* wm_shelf = static_cast<WmShelf*>(wm_shelf_aura_); + return wm_shelf->GetAlignment(); } void ShelfWidget::OnShelfAlignmentChanged() { @@ -415,8 +419,8 @@ delegate_view_->SetDimmed(dimming); // Repaint all children, allowing updates to reflect dimmed state eg: // status area background, app list button and overflow button. - if (shelf_) - shelf_->SchedulePaint(); + if (shelf_view_) + shelf_view_->SchedulePaintForAllButtons(); status_area_widget_->SchedulePaint(); } @@ -424,23 +428,25 @@ return delegate_view_->GetDimmed(); } -void ShelfWidget::CreateShelf() { +ShelfView* ShelfWidget::CreateShelfView() { DCHECK(!shelf_); + DCHECK(!shelf_view_); - shelf_.reset(new Shelf(WmShell::Get()->shelf_model(), wm_shelf_aura_, this)); - // Must be initialized before the delegate is notified because the delegate - // may try to access the WmShelf. - wm_shelf_aura_->SetShelf(shelf_.get()); - WmShell::Get()->shelf_delegate()->OnShelfCreated(shelf_.get()); + shelf_view_ = + new ShelfView(WmShell::Get()->shelf_model(), + WmShell::Get()->shelf_delegate(), wm_shelf_aura_, this); + shelf_view_->Init(); + GetContentsView()->AddChildView(shelf_view_); + return shelf_view_; +} +void ShelfWidget::PostCreateShelf() { SetFocusCycler(WmShell::Get()->focus_cycler()); // Ensure the newly created |shelf_| gets current values. background_animator_.Initialize(this); -} -void ShelfWidget::PostCreateShelf() { - shelf_->SetVisible( + shelf_view_->SetVisible( WmShell::Get()->GetSessionStateDelegate()->IsActiveUserSessionStarted()); shelf_layout_manager_->LayoutShelf(); shelf_layout_manager_->UpdateAutoHideState(); @@ -448,12 +454,12 @@ } bool ShelfWidget::IsShelfVisible() const { - return shelf_.get() && shelf_->IsVisible(); + return shelf_view_ && shelf_view_->visible(); } void ShelfWidget::SetShelfVisibility(bool visible) { - if (shelf_) - shelf_->SetVisible(visible); + if (shelf_view_) + shelf_view_->SetVisible(visible); } void ShelfWidget::SetFocusCycler(FocusCycler* focus_cycler) { @@ -517,8 +523,8 @@ } void ShelfWidget::UpdateShelfItemBackground(int alpha) { - if (shelf_) - shelf_->UpdateShelfItemBackground(alpha); + if (shelf_view_) + shelf_view_->UpdateShelfItemBackground(alpha); } void ShelfWidget::WillDeleteShelfLayoutManager() {
diff --git a/ash/shelf/shelf_widget.h b/ash/shelf/shelf_widget.h index ebf3e02..83bd7b2 100644 --- a/ash/shelf/shelf_widget.h +++ b/ash/shelf/shelf_widget.h
@@ -20,10 +20,10 @@ class FocusCycler; class Shelf; class ShelfLayoutManager; +class ShelfView; class StatusAreaWidget; class WmShelfAura; class WmWindow; -class WorkspaceController; class ASH_EXPORT ShelfWidget : public views::Widget, public views::WidgetObserver, @@ -32,8 +32,7 @@ public: ShelfWidget(WmWindow* shelf_container, WmWindow* status_container, - WmShelfAura* wm_shelf_aura, - WorkspaceController* workspace_controller); + WmShelfAura* wm_shelf_aura); ~ShelfWidget() override; // Returns if shelf alignment option is enabled, and the user is able to @@ -41,6 +40,8 @@ static bool ShelfAlignmentAllowed(); void OnShelfAlignmentChanged(); + + // DEPRECATED: Prefer WmShelf::GetAlignment(). ShelfAlignment GetAlignment() const; // Sets the shelf's background type. @@ -57,11 +58,14 @@ void SetDimsShelf(bool dimming); bool GetDimsShelf() const; + // TODO(jamescook): Eliminate these. + Shelf* shelf() { return shelf_; } + void set_shelf(Shelf* shelf) { shelf_ = shelf; } + ShelfLayoutManager* shelf_layout_manager() { return shelf_layout_manager_; } - Shelf* shelf() const { return shelf_.get(); } StatusAreaWidget* status_area_widget() const { return status_area_widget_; } - void CreateShelf(); + ShelfView* CreateShelfView(); void PostCreateShelf(); // Set visibility of the shelf. @@ -110,12 +114,15 @@ // Owned by the shelf container's aura::Window. ShelfLayoutManager* shelf_layout_manager_; - std::unique_ptr<Shelf> shelf_; + // Owned by the root window controller. + Shelf* shelf_; StatusAreaWidget* status_area_widget_; // |delegate_view_| is the contents view of this widget and is cleaned up // during CloseChildWindows of the associated RootWindowController. DelegateView* delegate_view_; + // View containing the shelf items. Owned by the views hierarchy. + ShelfView* shelf_view_; ShelfBackgroundAnimator background_animator_; bool activating_as_fallback_;
diff --git a/ash/shelf/shelf_widget_unittest.cc b/ash/shelf/shelf_widget_unittest.cc index 6d955e2..7ba5bd5 100644 --- a/ash/shelf/shelf_widget_unittest.cc +++ b/ash/shelf/shelf_widget_unittest.cc
@@ -8,6 +8,8 @@ #include "ash/common/shelf/shelf_delegate.h" #include "ash/common/shelf/shelf_view.h" #include "ash/common/system/status_area_widget.h" +#include "ash/common/wm_shell.h" +#include "ash/common/wm_window.h" #include "ash/root_window_controller.h" #include "ash/shelf/shelf.h" #include "ash/shelf/shelf_layout_manager.h" @@ -20,7 +22,6 @@ #include "ash/wm/window_util.h" #include "ui/aura/window_event_dispatcher.h" #include "ui/display/display.h" -#include "ui/display/screen.h" #include "ui/events/event_utils.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" @@ -48,18 +49,18 @@ MaterialDesignController::MATERIAL_NORMAL, MaterialDesignController::MATERIAL_EXPERIMENTAL)); -void TestLauncherAlignment(aura::Window* root, +void TestLauncherAlignment(WmWindow* root, ShelfAlignment alignment, - const std::string& expected) { + const gfx::Rect& expected) { Shelf::ForWindow(root)->SetAlignment(alignment); - display::Screen* screen = display::Screen::GetScreen(); - EXPECT_EQ(expected, - screen->GetDisplayNearestWindow(root).work_area().ToString()); + EXPECT_EQ(expected.ToString(), + root->GetDisplayNearestWindow().work_area().ToString()); } -// TODO(msw): Broken on Windows. http://crbug.com/584038 -#if defined(OS_CHROMEOS) TEST_P(ShelfWidgetTest, TestAlignment) { + if (!SupportsHostWindowResize()) + return; + // Note that for a left- and right-aligned shelf, this offset must be // applied to a maximized window's width rather than its height. const int offset = GetMdMaximizedWindowHeightOffset(); @@ -67,75 +68,81 @@ UpdateDisplay("400x400"); { SCOPED_TRACE("Single Bottom"); - TestLauncherAlignment(Shell::GetPrimaryRootWindow(), SHELF_ALIGNMENT_BOTTOM, - gfx::Rect(0, 0, 400, 353 + offset).ToString()); + TestLauncherAlignment(WmShell::Get()->GetPrimaryRootWindow(), + SHELF_ALIGNMENT_BOTTOM, + gfx::Rect(0, 0, 400, 353 + offset)); } { SCOPED_TRACE("Single Locked"); - TestLauncherAlignment(Shell::GetPrimaryRootWindow(), + TestLauncherAlignment(WmShell::Get()->GetPrimaryRootWindow(), SHELF_ALIGNMENT_BOTTOM_LOCKED, - gfx::Rect(0, 0, 400, 353 + offset).ToString()); + gfx::Rect(0, 0, 400, 353 + offset)); } { SCOPED_TRACE("Single Right"); - TestLauncherAlignment(Shell::GetPrimaryRootWindow(), SHELF_ALIGNMENT_RIGHT, - gfx::Rect(0, 0, 353 + offset, 400).ToString()); + TestLauncherAlignment(WmShell::Get()->GetPrimaryRootWindow(), + SHELF_ALIGNMENT_RIGHT, + gfx::Rect(0, 0, 353 + offset, 400)); } { SCOPED_TRACE("Single Left"); - TestLauncherAlignment( - Shell::GetPrimaryRootWindow(), SHELF_ALIGNMENT_LEFT, - gfx::Rect(kShelfSize, 0, 353 + offset, 400).ToString()); + TestLauncherAlignment(WmShell::Get()->GetPrimaryRootWindow(), + SHELF_ALIGNMENT_LEFT, + gfx::Rect(kShelfSize, 0, 353 + offset, 400)); } +} + +TEST_P(ShelfWidgetTest, TestAlignmentForMultipleDisplays) { if (!SupportsMultipleDisplays()) return; + // Note that for a left- and right-aligned shelf, this offset must be + // applied to a maximized window's width rather than its height. + const int offset = GetMdMaximizedWindowHeightOffset(); + const int kShelfSize = GetShelfConstant(SHELF_SIZE); UpdateDisplay("300x300,500x500"); - aura::Window::Windows root_windows = Shell::GetAllRootWindows(); + std::vector<WmWindow*> root_windows = WmShell::Get()->GetAllRootWindows(); { SCOPED_TRACE("Primary Bottom"); TestLauncherAlignment(root_windows[0], SHELF_ALIGNMENT_BOTTOM, - gfx::Rect(0, 0, 300, 253 + offset).ToString()); + gfx::Rect(0, 0, 300, 253 + offset)); } { SCOPED_TRACE("Primary Locked"); TestLauncherAlignment(root_windows[0], SHELF_ALIGNMENT_BOTTOM_LOCKED, - gfx::Rect(0, 0, 300, 253 + offset).ToString()); + gfx::Rect(0, 0, 300, 253 + offset)); } { SCOPED_TRACE("Primary Right"); TestLauncherAlignment(root_windows[0], SHELF_ALIGNMENT_RIGHT, - gfx::Rect(0, 0, 253 + offset, 300).ToString()); + gfx::Rect(0, 0, 253 + offset, 300)); } { SCOPED_TRACE("Primary Left"); - TestLauncherAlignment( - root_windows[0], SHELF_ALIGNMENT_LEFT, - gfx::Rect(kShelfSize, 0, 253 + offset, 300).ToString()); + TestLauncherAlignment(root_windows[0], SHELF_ALIGNMENT_LEFT, + gfx::Rect(kShelfSize, 0, 253 + offset, 300)); } { SCOPED_TRACE("Secondary Bottom"); TestLauncherAlignment(root_windows[1], SHELF_ALIGNMENT_BOTTOM, - gfx::Rect(300, 0, 500, 453 + offset).ToString()); + gfx::Rect(300, 0, 500, 453 + offset)); } { SCOPED_TRACE("Secondary Locked"); TestLauncherAlignment(root_windows[1], SHELF_ALIGNMENT_BOTTOM_LOCKED, - gfx::Rect(300, 0, 500, 453 + offset).ToString()); + gfx::Rect(300, 0, 500, 453 + offset)); } { SCOPED_TRACE("Secondary Right"); TestLauncherAlignment(root_windows[1], SHELF_ALIGNMENT_RIGHT, - gfx::Rect(300, 0, 453 + offset, 500).ToString()); + gfx::Rect(300, 0, 453 + offset, 500)); } { SCOPED_TRACE("Secondary Left"); - TestLauncherAlignment( - root_windows[1], SHELF_ALIGNMENT_LEFT, - gfx::Rect(300 + kShelfSize, 0, 453 + offset, 500).ToString()); + TestLauncherAlignment(root_windows[1], SHELF_ALIGNMENT_LEFT, + gfx::Rect(300 + kShelfSize, 0, 453 + offset, 500)); } } -#endif // defined(OS_CHROMEOS) // Makes sure the shelf is initially sized correctly. TEST_P(ShelfWidgetTest, LauncherInitiallySized) { @@ -164,15 +171,17 @@ widget->SetFullscreen(true); } -#if defined(OS_CHROMEOS) // Verifies shelf is created with correct size after user login and when its // container and status widget has finished sizing. // See http://crbug.com/252533 TEST_P(ShelfWidgetTest, ShelfInitiallySizedAfterLogin) { + if (!SupportsMultipleDisplays()) + return; + SetUserLoggedIn(false); UpdateDisplay("300x200,400x300"); - ShelfWidget* shelf_widget = NULL; + ShelfWidget* shelf_widget = nullptr; Shell::RootWindowControllerList controllers( Shell::GetAllRootWindowControllers()); for (Shell::RootWindowControllerList::const_iterator i = controllers.begin(); @@ -182,13 +191,13 @@ break; } } - ASSERT_TRUE(shelf_widget != NULL); + ASSERT_TRUE(shelf_widget); SetUserLoggedIn(true); Shell::GetInstance()->CreateShelf(); Shelf* shelf = shelf_widget->shelf(); - ASSERT_TRUE(shelf != NULL); + ASSERT_TRUE(shelf); const int status_width = shelf_widget->status_area_widget()->GetWindowBoundsInScreen().width(); @@ -196,7 +205,6 @@ EXPECT_EQ(status_width, shelf_widget->GetContentsView()->width() - test::ShelfTestAPI(shelf).shelf_view()->width()); } -#endif // defined(OS_CHROMEOS) // Tests that the shelf lets mouse-events close to the edge fall through to the // window underneath.
diff --git a/ash/shell.cc b/ash/shell.cc index 3b69f661..a4b6c5ed 100644 --- a/ash/shell.cc +++ b/ash/shell.cc
@@ -373,11 +373,6 @@ (*iter)->CreateShelf(); } -void Shell::OnShelfCreatedForRootWindow(WmWindow* root_window) { - FOR_EACH_OBSERVER(ShellObserver, *wm_shell_->shell_observers(), - OnShelfCreatedForRootWindow(root_window)); -} - void Shell::CreateKeyboard() { if (in_mus_) return; @@ -419,8 +414,9 @@ } } -void Shell::AddPointerWatcher(views::PointerWatcher* watcher) { - pointer_watcher_delegate_->AddPointerWatcher(watcher); +void Shell::AddPointerWatcher(views::PointerWatcher* watcher, + bool wants_moves) { + pointer_watcher_delegate_->AddPointerWatcher(watcher, wants_moves); } void Shell::RemovePointerWatcher(views::PointerWatcher* watcher) { @@ -443,16 +439,6 @@ (*iter)->UpdateShelfVisibility(); } -void Shell::OnShelfAlignmentChanged(WmWindow* root_window) { - FOR_EACH_OBSERVER(ShellObserver, *wm_shell_->shell_observers(), - OnShelfAlignmentChanged(root_window)); -} - -void Shell::OnShelfAutoHideBehaviorChanged(WmWindow* root_window) { - FOR_EACH_OBSERVER(ShellObserver, *wm_shell_->shell_observers(), - OnShelfAutoHideBehaviorChanged(root_window)); -} - void Shell::CreateModalBackground(aura::Window* window) { RootWindowControllerList controllers = GetAllRootWindowControllers(); for (RootWindowControllerList::iterator iter = controllers.begin();
diff --git a/ash/shell.h b/ash/shell.h index 39ad425..251cf77 100644 --- a/ash/shell.h +++ b/ash/shell.h
@@ -246,9 +246,6 @@ // Initializes |shelf_|. Does nothing if it's already initialized. void CreateShelf(); - // Called when the shelf is created for |root_window|. - void OnShelfCreatedForRootWindow(WmWindow* root_window); - // Creates a virtual keyboard. Deletes the old virtual keyboard if it already // exists. void CreateKeyboard(); @@ -259,7 +256,7 @@ // Show shelf view if it was created hidden (before session has started). void ShowShelf(); - void AddPointerWatcher(views::PointerWatcher* watcher); + void AddPointerWatcher(views::PointerWatcher* watcher, bool wants_moves); void RemovePointerWatcher(views::PointerWatcher* watcher); #if defined(OS_CHROMEOS) @@ -356,14 +353,6 @@ // TODO(jamescook): Move to Shelf. void UpdateShelfVisibility(); - // Called when the alignment for a shelf changes. - // TODO(jamescook): Move to Shelf. - void OnShelfAlignmentChanged(WmWindow* root_window); - - // Called when the auto-hide behavior for a shelf changes. - // TODO(jamescook): Move to Shelf. - void OnShelfAutoHideBehaviorChanged(WmWindow* root_window); - // Creates a modal background (a partially-opaque fullscreen window) // on all displays for |window|. void CreateModalBackground(aura::Window* window);
diff --git a/ash/system/chromeos/power/power_event_observer.cc b/ash/system/chromeos/power/power_event_observer.cc index 1adfb03b..663a8a6 100644 --- a/ash/system/chromeos/power/power_event_observer.cc +++ b/ash/system/chromeos/power/power_event_observer.cc
@@ -26,7 +26,6 @@ for (aura::Window* window : Shell::GetAllRootWindows()) { ui::Compositor* compositor = window->GetHost()->compositor(); compositor->SetVisible(false); - compositor->FinishAllRendering(); } }
diff --git a/ash/system/chromeos/rotation/tray_rotation_lock.cc b/ash/system/chromeos/rotation/tray_rotation_lock.cc index 0a44b74..db14deb 100644 --- a/ash/system/chromeos/rotation/tray_rotation_lock.cc +++ b/ash/system/chromeos/rotation/tray_rotation_lock.cc
@@ -84,15 +84,13 @@ const gfx::VectorIconId icon_id = rotation_locked ? gfx::VectorIconId::SYSTEM_MENU_ROTATION_LOCK_LOCKED : gfx::VectorIconId::SYSTEM_MENU_ROTATION_LOCK_AUTO; - gfx::ImageSkia image_md = - CreateVectorIcon(icon_id, kMenuIconSize, kMenuIconColor); - SetImage(&image_md); + SetImage(gfx::CreateVectorIcon(icon_id, kMenuIconSize, kMenuIconColor)); } else { ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); const int resource_id = rotation_locked ? IDR_AURA_UBER_TRAY_AUTO_ROTATION_LOCKED_DARK : IDR_AURA_UBER_TRAY_AUTO_ROTATION_DARK; - SetImage(bundle.GetImageNamed(resource_id).ToImageSkia()); + SetImage(*bundle.GetImageNamed(resource_id).ToImageSkia()); } base::string16 label = l10n_util::GetStringUTF16(
diff --git a/ash/test/test_session_state_delegate.cc b/ash/test/test_session_state_delegate.cc index 023a17a..62c1b83d 100644 --- a/ash/test/test_session_state_delegate.cc +++ b/ash/test/test_session_state_delegate.cc
@@ -103,7 +103,7 @@ } TestSessionStateDelegate::~TestSessionStateDelegate() { - STLDeleteElements(&user_list_); + base::STLDeleteElements(&user_list_); } void TestSessionStateDelegate::AddUser(const AccountId& account_id) {
diff --git a/ash/touch_hud/mus/touch_hud_application.cc b/ash/touch_hud/mus/touch_hud_application.cc index b211438..702560b 100644 --- a/ash/touch_hud/mus/touch_hud_application.cc +++ b/ash/touch_hud/mus/touch_hud_application.cc
@@ -13,6 +13,7 @@ #include "services/ui/public/interfaces/window_manager_constants.mojom.h" #include "ui/views/mus/aura_init.h" #include "ui/views/mus/native_widget_mus.h" +#include "ui/views/mus/pointer_watcher_event_router.h" #include "ui/views/mus/window_manager_connection.h" #include "ui/views/pointer_watcher.h" #include "ui/views/widget/widget.h" @@ -31,10 +32,12 @@ views::Widget* widget) : window_manager_connection_(window_manager_connection), touch_hud_renderer_(new TouchHudRenderer(widget)) { - window_manager_connection_->AddPointerWatcher(this, true /* want_moves */); + window_manager_connection_->pointer_watcher_event_router() + ->AddPointerWatcher(this, false /* want_moves */); } ~TouchHudUI() override { - window_manager_connection_->RemovePointerWatcher(this); + window_manager_connection_->pointer_watcher_event_router() + ->RemovePointerWatcher(this); } private:
diff --git a/ash/utility/screenshot_controller.cc b/ash/utility/screenshot_controller.cc index 47d6ed4a..a44482a9 100644 --- a/ash/utility/screenshot_controller.cc +++ b/ash/utility/screenshot_controller.cc
@@ -336,7 +336,7 @@ SetSelectedWindow(nullptr); screenshot_delegate_ = nullptr; display::Screen::GetScreen()->RemoveObserver(this); - STLDeleteValues(&layers_); + base::STLDeleteValues(&layers_); cursor_setter_.reset(); EnableMouseWarp(true); }
diff --git a/ash/wm/panels/panel_layout_manager_unittest.cc b/ash/wm/panels/panel_layout_manager_unittest.cc index 335985f..5cc703b 100644 --- a/ash/wm/panels/panel_layout_manager_unittest.cc +++ b/ash/wm/panels/panel_layout_manager_unittest.cc
@@ -11,6 +11,7 @@ #include "ash/common/shelf/shelf_types.h" #include "ash/common/shelf/shelf_view.h" #include "ash/common/shell_window_ids.h" +#include "ash/common/system/web_notification/web_notification_tray.h" #include "ash/common/wm/mru_window_tracker.h" #include "ash/common/wm/window_state.h" #include "ash/common/wm_shell.h" @@ -54,6 +55,14 @@ shelf_view_test_.reset( new test::ShelfViewTestAPI(GetShelfView(Shelf::ForPrimaryDisplay()))); shelf_view_test_->SetAnimationDuration(1); + + WebNotificationTray::DisableAnimationsForTest(true); + } + + void TearDown() override { + test::AshTestBase::TearDown(); + + WebNotificationTray::DisableAnimationsForTest(false); // Reenable animation } aura::Window* CreateNormalWindow(const gfx::Rect& bounds) { @@ -115,19 +124,20 @@ EXPECT_FALSE(window1_bounds.Intersects(window2_bounds)); } - void IsPanelAboveLauncherIcon(const aura::Window* panel) { + void IsPanelAboveLauncherIcon(aura::Window* panel) { // Waits until all shelf view animations are done. shelf_view_test()->RunMessageLoopUntilAnimationsDone(); - Shelf* shelf = Shelf::ForWindow(panel); - gfx::Rect icon_bounds = shelf->GetScreenBoundsOfItemIconForWindow(panel); + WmWindow* wm_panel = WmWindowAura::Get(panel); + Shelf* shelf = Shelf::ForWindow(wm_panel); + gfx::Rect icon_bounds = shelf->GetScreenBoundsOfItemIconForWindow(wm_panel); ASSERT_FALSE(icon_bounds.width() == 0 && icon_bounds.height() == 0); gfx::Rect window_bounds = panel->GetBoundsInScreen(); ASSERT_LT(icon_bounds.width(), window_bounds.width()); ASSERT_LT(icon_bounds.height(), window_bounds.height()); gfx::Rect shelf_bounds = shelf->shelf_widget()->GetWindowBoundsInScreen(); - ShelfAlignment alignment = GetAlignment(panel->GetRootWindow()); + const ShelfAlignment alignment = shelf->alignment(); if (IsHorizontal(alignment)) { // The horizontal bounds of the panel window should contain the bounds of @@ -154,8 +164,9 @@ base::RunLoop().RunUntilIdle(); views::Widget* widget = GetCalloutWidgetForPanel(panel); - Shelf* shelf = Shelf::ForWindow(panel); - gfx::Rect icon_bounds = shelf->GetScreenBoundsOfItemIconForWindow(panel); + WmWindow* wm_panel = WmWindowAura::Get(panel); + Shelf* shelf = Shelf::ForWindow(wm_panel); + gfx::Rect icon_bounds = shelf->GetScreenBoundsOfItemIconForWindow(wm_panel); ASSERT_FALSE(icon_bounds.IsEmpty()); gfx::Rect panel_bounds = panel->GetBoundsInScreen(); @@ -164,7 +175,7 @@ EXPECT_TRUE(widget->IsVisible()); - ShelfAlignment alignment = GetAlignment(panel->GetRootWindow()); + const ShelfAlignment alignment = shelf->alignment(); if (alignment == SHELF_ALIGNMENT_LEFT) EXPECT_EQ(panel_bounds.x(), callout_bounds.right()); else if (alignment == SHELF_ALIGNMENT_RIGHT) @@ -206,16 +217,12 @@ } void SetAlignment(aura::Window* root_window, ShelfAlignment alignment) { - Shelf::ForWindow(root_window)->SetAlignment(alignment); - } - - ShelfAlignment GetAlignment(const aura::Window* root_window) { - return Shelf::ForWindow(root_window)->alignment(); + Shelf::ForWindow(WmWindowAura::Get(root_window))->SetAlignment(alignment); } void SetShelfAutoHideBehavior(aura::Window* window, ShelfAutoHideBehavior behavior) { - Shelf* shelf = Shelf::ForWindow(window); + Shelf* shelf = Shelf::ForWindow(WmWindowAura::Get(window)); shelf->SetAutoHideBehavior(behavior); test::ShelfViewTestAPI test_api(GetShelfView(shelf)); test_api.RunMessageLoopUntilAnimationsDone(); @@ -223,7 +230,7 @@ void SetShelfVisibilityState(aura::Window* window, ShelfVisibilityState visibility_state) { - Shelf* shelf = Shelf::ForWindow(window); + Shelf* shelf = Shelf::ForWindow(WmWindowAura::Get(window)); shelf->shelf_layout_manager()->SetState(visibility_state); } @@ -514,8 +521,12 @@ int window_x2 = w2->GetBoundsInRootWindow().CenterPoint().x(); int window_x3 = w3->GetBoundsInRootWindow().CenterPoint().x(); Shelf* shelf = Shelf::ForPrimaryDisplay(); - int icon_x1 = shelf->GetScreenBoundsOfItemIconForWindow(w1.get()).x(); - int icon_x2 = shelf->GetScreenBoundsOfItemIconForWindow(w2.get()).x(); + int icon_x1 = + shelf->GetScreenBoundsOfItemIconForWindow(WmWindowAura::Get(w1.get())) + .x(); + int icon_x2 = + shelf->GetScreenBoundsOfItemIconForWindow(WmWindowAura::Get(w2.get())) + .x(); EXPECT_EQ(window_x2 - window_x1, window_x3 - window_x2); int spacing = window_x2 - window_x1; EXPECT_GT(spacing, icon_x2 - icon_x1); @@ -579,7 +590,8 @@ CreatePanelWindow(gfx::Rect(600, 0, 50, 50))); ShelfView* shelf_view_1st = GetShelfView(Shelf::ForPrimaryDisplay()); - ShelfView* shelf_view_2nd = GetShelfView(Shelf::ForWindow(root_windows[1])); + ShelfView* shelf_view_2nd = + GetShelfView(Shelf::ForWindow(WmWindowAura::Get(root_windows[1]))); EXPECT_EQ(root_windows[0], p1_d1->GetRootWindow()); EXPECT_EQ(root_windows[0], p2_d1->GetRootWindow());
diff --git a/ash/wm/screen_pinning_controller.cc b/ash/wm/screen_pinning_controller.cc index bdc66fd2..a74dffe 100644 --- a/ash/wm/screen_pinning_controller.cc +++ b/ash/wm/screen_pinning_controller.cc
@@ -355,7 +355,7 @@ GetSystemModalWindowsExceptPinned(pinned_window_); for (WmWindow* system_modal : system_modal_containers) { const std::vector<WmWindow*> children = system_modal->GetChildren(); - if (!children.empty() && ContainsValue(dim_windows_, children[0])) { + if (!children.empty() && base::ContainsValue(dim_windows_, children[0])) { // The system modal dialog has the dim window. continue; }
diff --git a/ash/wm/session_state_animator_impl.cc b/ash/wm/session_state_animator_impl.cc index b52ee6b..ccd8c8e9 100644 --- a/ash/wm/session_state_animator_impl.cc +++ b/ash/wm/session_state_animator_impl.cc
@@ -7,8 +7,8 @@ #include <vector> #include "ash/common/shell_window_ids.h" +#include "ash/common/wm/wm_window_animations.h" #include "ash/shell.h" -#include "ash/wm/window_animations.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window_event_dispatcher.h" #include "ui/compositor/layer_animation_observer.h"
diff --git a/ash/wm/system_modal_container_layout_manager.cc b/ash/wm/system_modal_container_layout_manager.cc index 1928fd1c..36c7890 100644 --- a/ash/wm/system_modal_container_layout_manager.cc +++ b/ash/wm/system_modal_container_layout_manager.cc
@@ -202,7 +202,7 @@ capture_window->ReleaseCapture(); } DCHECK(window->IsVisible()); - DCHECK(!ContainsValue(modal_windows_, window)); + DCHECK(!base::ContainsValue(modal_windows_, window)); modal_windows_.push_back(window); Shell::GetInstance()->CreateModalBackground(window);
diff --git a/ash/wm/window_animations.cc b/ash/wm/window_animations.cc index 7702495..1a6ae8c 100644 --- a/ash/wm/window_animations.cc +++ b/ash/wm/window_animations.cc
@@ -9,6 +9,7 @@ #include <utility> #include <vector> +#include "ash/aura/wm_window_aura.h" #include "ash/common/wm/window_animation_types.h" #include "ash/screen_util.h" #include "ash/shelf/shelf.h" @@ -37,12 +38,14 @@ #include "ui/display/screen.h" #include "ui/gfx/geometry/vector3d_f.h" #include "ui/gfx/interpolated_transform.h" +#include "ui/gfx/transform.h" #include "ui/views/view.h" #include "ui/views/widget/widget.h" #include "ui/wm/core/window_util.h" namespace ash { namespace { + const int kLayerAnimationsForMinimizeDurationMS = 200; // Durations for the cross-fade animation, in milliseconds. @@ -59,10 +62,6 @@ const float kWindowAnimation_HideOpacity = 0.f; const float kWindowAnimation_ShowOpacity = 1.f; -// Scales for AshWindow above/below current workspace. -const float kLayerScaleAboveSize = 1.1f; -const float kLayerScaleBelowSize = .9f; - int64_t Round64(float f) { return static_cast<int64_t>(f + 0.5f); } @@ -434,25 +433,13 @@ return animations; } -// Returns scale related to the specified AshWindowScaleType. -void SetTransformForScaleAnimation(ui::Layer* layer, - LayerScaleAnimationDirection type) { - const float scale = type == LAYER_SCALE_ANIMATION_ABOVE - ? kLayerScaleAboveSize - : kLayerScaleBelowSize; - gfx::Transform transform; - transform.Translate(-layer->bounds().width() * (scale - 1.0f) / 2, - -layer->bounds().height() * (scale - 1.0f) / 2); - transform.Scale(scale, scale); - layer->SetTransform(transform); -} - gfx::Rect GetMinimizeAnimationTargetBoundsInScreen(aura::Window* window) { - Shelf* shelf = Shelf::ForWindow(window); + WmWindow* wm_window = WmWindowAura::Get(window); + Shelf* shelf = Shelf::ForWindow(wm_window); // Shelf is created lazily and can be NULL. if (!shelf) return gfx::Rect(); - gfx::Rect item_rect = shelf->GetScreenBoundsOfItemIconForWindow(window); + gfx::Rect item_rect = shelf->GetScreenBoundsOfItemIconForWindow(wm_window); // The launcher item is visible and has an icon. if (!item_rect.IsEmpty())
diff --git a/ash/wm/window_animations.h b/ash/wm/window_animations.h index 7543ecc6..e30993a 100644 --- a/ash/wm/window_animations.h +++ b/ash/wm/window_animations.h
@@ -9,29 +9,20 @@ #include "ash/ash_export.h" #include "ui/gfx/animation/tween.h" -#include "ui/gfx/transform.h" #include "ui/wm/core/window_animations.h" namespace aura { class Window; } + namespace ui { -class Layer; class LayerTreeOwner; } -namespace views {} // This is only for animations specific to Ash. For window animations shared // with desktop Chrome, see ui/views/corewm/window_animations.h. namespace ash { -// Direction for ash-specific window animations used in workspaces and -// lock/unlock animations. -enum LayerScaleAnimationDirection { - LAYER_SCALE_ANIMATION_ABOVE, - LAYER_SCALE_ANIMATION_BELOW, -}; - // Amount of time for the cross fade animation. extern const int kCrossFadeDurationMS; @@ -54,11 +45,6 @@ CreateBrightnessGrayscaleAnimationSequence(float target_value, base::TimeDelta duration); -// Applies scale related to the specified AshWindowScaleType. -ASH_EXPORT void SetTransformForScaleAnimation( - ui::Layer* layer, - LayerScaleAnimationDirection type); - // Returns the approximate bounds to which |window| will be animated when it // is minimized. The bounds are approximate because the minimize animation // involves rotation.
diff --git a/ash/wm/window_cycle_controller_unittest.cc b/ash/wm/window_cycle_controller_unittest.cc index ad61331f..48ab3b3 100644 --- a/ash/wm/window_cycle_controller_unittest.cc +++ b/ash/wm/window_cycle_controller_unittest.cc
@@ -78,6 +78,8 @@ test::AshTestBase::SetUp(); ASSERT_TRUE(test::TestShelfDelegate::instance()); + WindowCycleList::DisableInitialDelayForTesting(); + shelf_view_test_.reset(new test::ShelfViewTestAPI( test::ShelfTestAPI(Shelf::ForPrimaryDisplay()).shelf_view())); shelf_view_test_->SetAnimationDuration(1); @@ -173,15 +175,12 @@ // all the windows and wrap around. controller->HandleCycleWindow(WindowCycleController::FORWARD); EXPECT_TRUE(controller->IsCycling()); - EXPECT_TRUE(wm::IsActiveWindow(window1.get())); controller->HandleCycleWindow(WindowCycleController::FORWARD); EXPECT_TRUE(controller->IsCycling()); - EXPECT_TRUE(wm::IsActiveWindow(window2.get())); controller->HandleCycleWindow(WindowCycleController::FORWARD); EXPECT_TRUE(controller->IsCycling()); - EXPECT_TRUE(wm::IsActiveWindow(window0.get())); controller->StopCycling(); EXPECT_FALSE(controller->IsCycling()); @@ -192,29 +191,29 @@ wm::ActivateWindow(window1.get()); wm::ActivateWindow(window0.get()); - // Likewise we can cycle backwards through all the windows. + // Likewise we can cycle backwards through the windows. controller->HandleCycleWindow(WindowCycleController::BACKWARD); - EXPECT_TRUE(wm::IsActiveWindow(window2.get())); controller->HandleCycleWindow(WindowCycleController::BACKWARD); - EXPECT_TRUE(wm::IsActiveWindow(window1.get())); - controller->HandleCycleWindow(WindowCycleController::BACKWARD); - EXPECT_TRUE(wm::IsActiveWindow(window0.get())); controller->StopCycling(); - EXPECT_TRUE(wm::IsActiveWindow(window0.get())); + EXPECT_TRUE(wm::IsActiveWindow(window1.get())); + + // Reset our stacking order. + wm::ActivateWindow(window2.get()); + wm::ActivateWindow(window1.get()); + wm::ActivateWindow(window0.get()); // When the screen is locked, cycling window does not take effect. WmShell::Get()->GetSessionStateDelegate()->LockScreen(); EXPECT_TRUE(wm::IsActiveWindow(window0.get())); controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(wm::IsActiveWindow(window0.get())); - controller->HandleCycleWindow(WindowCycleController::BACKWARD); - EXPECT_TRUE(wm::IsActiveWindow(window0.get())); + EXPECT_FALSE(controller->IsCycling()); + // Unlock, it works again. WmShell::Get()->GetSessionStateDelegate()->UnlockScreen(); EXPECT_TRUE(wm::IsActiveWindow(window0.get())); controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(wm::IsActiveWindow(window1.get())); controller->HandleCycleWindow(WindowCycleController::FORWARD); + controller->StopCycling(); EXPECT_TRUE(wm::IsActiveWindow(window2.get())); // When a modal window is active, cycling window does not take effect. @@ -227,11 +226,13 @@ EXPECT_TRUE(wm::IsActiveWindow(modal_window.get())); controller->HandleCycleWindow(WindowCycleController::FORWARD); EXPECT_TRUE(wm::IsActiveWindow(modal_window.get())); + EXPECT_FALSE(controller->IsCycling()); EXPECT_FALSE(wm::IsActiveWindow(window0.get())); EXPECT_FALSE(wm::IsActiveWindow(window1.get())); EXPECT_FALSE(wm::IsActiveWindow(window2.get())); controller->HandleCycleWindow(WindowCycleController::BACKWARD); EXPECT_TRUE(wm::IsActiveWindow(modal_window.get())); + EXPECT_FALSE(controller->IsCycling()); EXPECT_FALSE(wm::IsActiveWindow(window0.get())); EXPECT_FALSE(wm::IsActiveWindow(window1.get())); EXPECT_FALSE(wm::IsActiveWindow(window2.get())); @@ -250,10 +251,13 @@ // Rotate focus, this should move focus to window0. WindowCycleController* controller = WmShell::Get()->window_cycle_controller(); controller->HandleCycleWindow(WindowCycleController::FORWARD); + controller->StopCycling(); EXPECT_TRUE(wm::GetWindowState(window0.get())->IsActive()); + EXPECT_FALSE(window1_state->IsActive()); // One more time. controller->HandleCycleWindow(WindowCycleController::FORWARD); + controller->StopCycling(); EXPECT_TRUE(window1_state->IsActive()); } @@ -272,11 +276,14 @@ // Rotate focus, this should move focus to window1 and unminimize it. WindowCycleController* controller = WmShell::Get()->window_cycle_controller(); controller->HandleCycleWindow(WindowCycleController::FORWARD); + controller->StopCycling(); + EXPECT_FALSE(window0_state->IsActive()); EXPECT_FALSE(window1_state->IsMinimized()); EXPECT_TRUE(window1_state->IsActive()); // One more time back to w0. controller->HandleCycleWindow(WindowCycleController::FORWARD); + controller->StopCycling(); EXPECT_TRUE(window0_state->IsActive()); } @@ -302,23 +309,6 @@ EXPECT_EQ(window0.get(), GetWindows(controller)[0]); EXPECT_EQ(window2.get(), GetWindows(controller)[1]); EXPECT_EQ(window1.get(), GetWindows(controller)[2]); - - controller->StopCycling(); - EXPECT_TRUE(wm::IsActiveWindow(window2.get())); - - controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(wm::IsActiveWindow(window0.get())); - - controller->StopCycling(); - - controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(wm::IsActiveWindow(window2.get())); - - controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(wm::IsActiveWindow(window1.get())); - - controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(wm::IsActiveWindow(window0.get())); } TEST_F(WindowCycleControllerTest, AlwaysOnTopMultiWindow) { @@ -345,26 +335,6 @@ EXPECT_EQ(window3.get(), GetWindows(controller)[1]); EXPECT_EQ(window2.get(), GetWindows(controller)[2]); EXPECT_EQ(window1.get(), GetWindows(controller)[3]); - - controller->StopCycling(); - EXPECT_TRUE(wm::IsActiveWindow(window3.get())); - - controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(wm::IsActiveWindow(window0.get())); - - controller->StopCycling(); - - controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(wm::IsActiveWindow(window3.get())); - - controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(wm::IsActiveWindow(window2.get())); - - controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(wm::IsActiveWindow(window1.get())); - - controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(wm::IsActiveWindow(window0.get())); } TEST_F(WindowCycleControllerTest, AlwaysOnTopMultipleRootWindows) { @@ -415,26 +385,6 @@ EXPECT_EQ(window3.get(), GetWindows(controller)[1]); EXPECT_EQ(window1.get(), GetWindows(controller)[2]); EXPECT_EQ(window0.get(), GetWindows(controller)[3]); - - controller->StopCycling(); - EXPECT_TRUE(wm::IsActiveWindow(window3.get())); - - controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(wm::IsActiveWindow(window2.get())); - - controller->StopCycling(); - - controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(wm::IsActiveWindow(window3.get())); - - controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(wm::IsActiveWindow(window1.get())); - - controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(wm::IsActiveWindow(window0.get())); - - controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(wm::IsActiveWindow(window2.get())); } TEST_F(WindowCycleControllerTest, MostRecentlyUsed) { @@ -458,23 +408,19 @@ EXPECT_EQ(window2.get(), GetWindows(controller)[1]); EXPECT_EQ(window1.get(), GetWindows(controller)[2]); + // Cycling through then stopping the cycling will activate a window. controller->HandleCycleWindow(WindowCycleController::FORWARD); controller->StopCycling(); EXPECT_TRUE(wm::IsActiveWindow(window1.get())); + // Cycling alone (without StopCycling()) doesn't activate. controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(wm::IsActiveWindow(window0.get())); + EXPECT_FALSE(wm::IsActiveWindow(window0.get())); + + // Showing the Alt+Tab UI does however deactivate the erstwhile active window. + EXPECT_FALSE(wm::IsActiveWindow(window1.get())); controller->StopCycling(); - - controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(wm::IsActiveWindow(window1.get())); - - controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(wm::IsActiveWindow(window2.get())); - - controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_TRUE(wm::IsActiveWindow(window0.get())); } // Tests that beginning window selection hides the app list. @@ -487,10 +433,14 @@ EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility()); controller->HandleCycleWindow(WindowCycleController::FORWARD); EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); + + // Make sure that dismissing the app list this way doesn't pass activation + // to a different window. + EXPECT_FALSE(wm::IsActiveWindow(window0.get())); + EXPECT_FALSE(wm::IsActiveWindow(window1.get())); } -// Tests that cycling through windows shows and minimizes windows as they -// are passed. +// Tests that cycling through windows doesn't change their minimized state. TEST_F(WindowCycleControllerTest, CyclePreservesMinimization) { WindowCycleController* controller = WmShell::Get()->window_cycle_controller(); @@ -503,7 +453,7 @@ // On window 2. controller->HandleCycleWindow(WindowCycleController::FORWARD); - EXPECT_FALSE(IsWindowMinimized(window1.get())); + EXPECT_TRUE(IsWindowMinimized(window1.get())); // Back on window 1. controller->HandleCycleWindow(WindowCycleController::FORWARD);
diff --git a/ash/wm/window_mirror_view.cc b/ash/wm/window_mirror_view.cc index e797dc9f..374207c 100644 --- a/ash/wm/window_mirror_view.cc +++ b/ash/wm/window_mirror_view.cc
@@ -36,7 +36,7 @@ WindowMirrorView::~WindowMirrorView() {} gfx::Size WindowMirrorView::GetPreferredSize() const { - return target_->GetBounds().size(); + return GetClientAreaBounds().size(); } void WindowMirrorView::Layout() { @@ -47,14 +47,17 @@ // Position at 0, 0. GetMirrorLayer()->SetBounds(gfx::Rect(GetMirrorLayer()->bounds().size())); + gfx::Transform transform; + gfx::Rect client_area_bounds = GetClientAreaBounds(); // Scale down if necessary. - gfx::Transform mirror_transform; if (size() != target_->GetBounds().size()) { const float scale = - width() / static_cast<float>(target_->GetBounds().width()); - mirror_transform.Scale(scale, scale); + width() / static_cast<float>(client_area_bounds.width()); + transform.Scale(scale, scale); } - GetMirrorLayer()->SetTransform(mirror_transform); + // Reposition such that the client area is the only part visible. + transform.Translate(-client_area_bounds.x(), -client_area_bounds.y()); + GetMirrorLayer()->SetTransform(transform); } bool WindowMirrorView::GetNeedsNotificationWhenVisibleBoundsChange() const { @@ -83,6 +86,8 @@ GetMirrorLayer()->parent()->Remove(GetMirrorLayer()); layer()->Add(GetMirrorLayer()); + // This causes us to clip the non-client areas of the window. + layer()->SetMasksToBounds(true); // Some extra work is needed when the target window is minimized. if (target_->GetWindowState()->IsMinimized()) { @@ -98,5 +103,13 @@ return layer_owner_->root(); } +gfx::Rect WindowMirrorView::GetClientAreaBounds() const { + // The target window may not have a widget in unit tests. + if (!target_->GetInternalWidget()) + return gfx::Rect(); + views::View* client_view = target_->GetInternalWidget()->client_view(); + return client_view->ConvertRectToWidget(client_view->GetLocalBounds()); +} + } // namespace wm } // namespace ash
diff --git a/ash/wm/window_mirror_view.h b/ash/wm/window_mirror_view.h index c59297f6..c91db5e 100644 --- a/ash/wm/window_mirror_view.h +++ b/ash/wm/window_mirror_view.h
@@ -21,9 +21,9 @@ class ForwardingLayerDelegate; -// A view that mirrors a single window. Layers are lifted from the underlying -// window (which gets new ones in their place). New paint calls, if any, are -// forwarded to the underlying window. +// A view that mirrors the client area of a single window. Layers are lifted +// from the underlying window (which gets new ones in their place). New paint +// calls, if any, are forwarded to the underlying window. class WindowMirrorView : public views::View, public ::wm::LayerDelegateFactory { public: explicit WindowMirrorView(WmWindowAura* window); @@ -45,6 +45,10 @@ // a child of |this->layer()|). ui::Layer* GetMirrorLayer(); + // Calculates the bounds of the client area of the Window in the widget + // coordinate space. + gfx::Rect GetClientAreaBounds() const; + // The original window that is being represented by |this|. WmWindowAura* target_;
diff --git a/ash/wm/workspace/multi_window_resize_controller_unittest.cc b/ash/wm/workspace/multi_window_resize_controller_unittest.cc index c3f5fbc..305f82b 100644 --- a/ash/wm/workspace/multi_window_resize_controller_unittest.cc +++ b/ash/wm/workspace/multi_window_resize_controller_unittest.cc
@@ -89,7 +89,8 @@ if ((resize_controller_->windows_.window1 == wm_window || resize_controller_->windows_.window2 == wm_window)) return true; - return ContainsValue(resize_controller_->windows_.other_windows, wm_window); + return base::ContainsValue(resize_controller_->windows_.other_windows, + wm_window); } bool IsOverWindows(const gfx::Point& loc) {
diff --git a/ash/wm/workspace/workspace_layout_manager_unittest.cc b/ash/wm/workspace/workspace_layout_manager_unittest.cc index 4be1023..718f6f2a 100644 --- a/ash/wm/workspace/workspace_layout_manager_unittest.cc +++ b/ash/wm/workspace/workspace_layout_manager_unittest.cc
@@ -841,7 +841,7 @@ window->SetProperty(aura::client::kAlwaysOnTopKey, true); window->Show(); - Shelf* shelf = Shelf::ForWindow(window.get()); + Shelf* shelf = Shelf::ForWindow(WmWindowAura::Get(window.get())); shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); window->SetBounds(ScreenUtil::GetMaximizedWindowBoundsInParent(window.get()));
diff --git a/ash/wm/workspace_controller.cc b/ash/wm/workspace_controller.cc index 80d1783..c8b9bdb 100644 --- a/ash/wm/workspace_controller.cc +++ b/ash/wm/workspace_controller.cc
@@ -6,17 +6,16 @@ #include <utility> -#include "ash/aura/wm_window_aura.h" +#include "ash/common/shelf/wm_shelf.h" #include "ash/common/shell_window_ids.h" +#include "ash/common/wm/dock/docked_window_layout_manager.h" +#include "ash/common/wm/fullscreen_window_finder.h" #include "ash/common/wm/window_state.h" +#include "ash/common/wm/wm_window_animations.h" #include "ash/common/wm/workspace/workspace_layout_manager.h" #include "ash/common/wm/workspace/workspace_layout_manager_backdrop_delegate.h" -#include "ash/root_window_controller.h" -#include "ash/shelf/shelf_layout_manager.h" -#include "ash/shell.h" -#include "ash/wm/window_animations.h" -#include "ash/wm/window_state_aura.h" -#include "ash/wm/window_util.h" +#include "ash/common/wm_root_window_controller.h" +#include "ash/common/wm_window.h" #include "ash/wm/workspace/workspace_event_handler.h" #include "base/memory/ptr_util.h" #include "ui/aura/client/aura_constants.h" @@ -35,96 +34,79 @@ // animation (when logging in). const int kInitialPauseTimeMS = 750; -// Returns true if there are visible docked windows in the same screen as the -// |shelf|. -bool IsDockedAreaVisible(const ShelfLayoutManager* shelf) { - return shelf->dock_bounds().width() > 0; -} +// The duration of the animation that occurs on first login. +const int kInitialAnimationDurationMS = 200; } // namespace -WorkspaceController::WorkspaceController(aura::Window* viewport) +WorkspaceController::WorkspaceController(WmWindow* viewport) : viewport_(viewport), - shelf_(NULL), event_handler_(new WorkspaceEventHandler), - layout_manager_(new WorkspaceLayoutManager(WmWindowAura::Get(viewport))) { - SetWindowVisibilityAnimationTransition(viewport_, ::wm::ANIMATE_NONE); - - WmWindowAura::Get(viewport_)->SetLayoutManager( - base::WrapUnique(layout_manager_)); - viewport_->AddPreTargetHandler(event_handler_.get()); + layout_manager_(new WorkspaceLayoutManager(viewport)) { + viewport_->SetVisibilityAnimationTransition(::wm::ANIMATE_NONE); + viewport_->SetLayoutManager(base::WrapUnique(layout_manager_)); + viewport_->AddLimitedPreTargetHandler(event_handler_.get()); } WorkspaceController::~WorkspaceController() { - viewport_->SetLayoutManager(NULL); - viewport_->RemovePreTargetHandler(event_handler_.get()); + viewport_->SetLayoutManager(nullptr); + viewport_->RemoveLimitedPreTargetHandler(event_handler_.get()); } wm::WorkspaceWindowState WorkspaceController::GetWindowState() const { - if (!shelf_) + if (!viewport_->GetRootWindowController()->HasShelf()) return wm::WORKSPACE_WINDOW_STATE_DEFAULT; - const aura::Window* topmost_fullscreen_window = - GetRootWindowController(viewport_->GetRootWindow()) - ->GetWindowForFullscreenMode(); - if (topmost_fullscreen_window && - !wm::GetWindowState(topmost_fullscreen_window)->ignored_by_shelf()) { + + const WmWindow* fullscreen = wm::GetWindowForFullscreenMode(viewport_); + if (fullscreen && !fullscreen->GetWindowState()->ignored_by_shelf()) return wm::WORKSPACE_WINDOW_STATE_FULL_SCREEN; - } // These are the container ids of containers which may contain windows that // may overlap the launcher shelf and affect its transparency. const int kWindowContainerIds[] = { kShellWindowId_DefaultContainer, kShellWindowId_DockedContainer, }; - const gfx::Rect shelf_bounds(shelf_->GetIdealBounds()); + const gfx::Rect shelf_bounds( + viewport_->GetRootWindowController()->GetShelf()->GetIdealBounds()); bool window_overlaps_launcher = false; - for (size_t idx = 0; idx < arraysize(kWindowContainerIds); idx++) { - const aura::Window* container = Shell::GetContainer( - viewport_->GetRootWindow(), kWindowContainerIds[idx]); - const aura::Window::Windows& windows(container->children()); - for (aura::Window::Windows::const_iterator i = windows.begin(); - i != windows.end(); ++i) { - wm::WindowState* window_state = wm::GetWindowState(*i); - if (window_state->ignored_by_shelf()) + for (size_t i = 0; i < arraysize(kWindowContainerIds); i++) { + WmWindow* container = viewport_->GetRootWindow()->GetChildByShellWindowId( + kWindowContainerIds[i]); + for (WmWindow* window : container->GetChildren()) { + wm::WindowState* window_state = window->GetWindowState(); + if (window_state->ignored_by_shelf() || + !window->GetLayer()->GetTargetVisibility()) { continue; - ui::Layer* layer = (*i)->layer(); - if (!layer->GetTargetVisibility()) - continue; - if (window_state->IsMaximized()) { + } + if (window_state->IsMaximized()) return wm::WORKSPACE_WINDOW_STATE_MAXIMIZED; - } - if (!window_overlaps_launcher && - ((*i)->bounds().Intersects(shelf_bounds))) { - window_overlaps_launcher = true; - } + window_overlaps_launcher |= window->GetBounds().Intersects(shelf_bounds); } } - return (window_overlaps_launcher || IsDockedAreaVisible(shelf_)) + // Check if there are visible docked windows in the same display. + DockedWindowLayoutManager* dock = DockedWindowLayoutManager::Get(viewport_); + const bool docked_area_visible = dock && !dock->docked_bounds().IsEmpty(); + return (window_overlaps_launcher || docked_area_visible) ? wm::WORKSPACE_WINDOW_STATE_WINDOW_OVERLAPS_SHELF : wm::WORKSPACE_WINDOW_STATE_DEFAULT; } -void WorkspaceController::SetShelf(ShelfLayoutManager* shelf) { - shelf_ = shelf; -} - void WorkspaceController::DoInitialAnimation() { viewport_->Show(); - viewport_->layer()->SetOpacity(0.0f); - SetTransformForScaleAnimation(viewport_->layer(), - LAYER_SCALE_ANIMATION_ABOVE); + ui::Layer* layer = viewport_->GetLayer(); + layer->SetOpacity(0.0f); + SetTransformForScaleAnimation(layer, LAYER_SCALE_ANIMATION_ABOVE); // In order for pause to work we need to stop animations. - viewport_->layer()->GetAnimator()->StopAnimating(); + layer->GetAnimator()->StopAnimating(); { - ui::ScopedLayerAnimationSettings settings( - viewport_->layer()->GetAnimator()); + ui::ScopedLayerAnimationSettings settings(layer->GetAnimator()); settings.SetPreemptionStrategy(ui::LayerAnimator::ENQUEUE_NEW_ANIMATION); - viewport_->layer()->GetAnimator()->SchedulePauseForProperties( + layer->GetAnimator()->SchedulePauseForProperties( base::TimeDelta::FromMilliseconds(kInitialPauseTimeMS), ui::LayerAnimationElement::TRANSFORM | ui::LayerAnimationElement::OPACITY | @@ -132,9 +114,9 @@ ui::LayerAnimationElement::VISIBILITY); settings.SetTweenType(gfx::Tween::EASE_OUT); settings.SetTransitionDuration( - base::TimeDelta::FromMilliseconds(kCrossFadeDurationMS)); - viewport_->layer()->SetTransform(gfx::Transform()); - viewport_->layer()->SetOpacity(1.0f); + base::TimeDelta::FromMilliseconds(kInitialAnimationDurationMS)); + layer->SetTransform(gfx::Transform()); + layer->SetOpacity(1.0f); } }
diff --git a/ash/wm/workspace_controller.h b/ash/wm/workspace_controller.h index fb8e3c3..610a65f8 100644 --- a/ash/wm/workspace_controller.h +++ b/ash/wm/workspace_controller.h
@@ -11,12 +11,8 @@ #include "ash/common/wm/workspace/workspace_types.h" #include "base/macros.h" -namespace aura { -class Window; -} - namespace ash { -class ShelfLayoutManager; +class WmWindow; class WorkspaceControllerTestHelper; class WorkspaceEventHandler; class WorkspaceLayoutManager; @@ -26,14 +22,12 @@ // various workspace pieces. class ASH_EXPORT WorkspaceController { public: - explicit WorkspaceController(aura::Window* viewport); + explicit WorkspaceController(WmWindow* viewport); virtual ~WorkspaceController(); // Returns the current window state. wm::WorkspaceWindowState GetWindowState() const; - void SetShelf(ShelfLayoutManager* shelf); - // Starts the animation that occurs on first login. void DoInitialAnimation(); @@ -47,9 +41,7 @@ private: friend class WorkspaceControllerTestHelper; - aura::Window* viewport_; - - ShelfLayoutManager* shelf_; + WmWindow* viewport_; std::unique_ptr<WorkspaceEventHandler> event_handler_; // Owned by |viewport_|.
diff --git a/base/BUILD.gn b/base/BUILD.gn index ae1159a..f5bf0494 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -2097,10 +2097,6 @@ deps += [ "//base/test:malloc_wrapper" ] - if (use_glib) { - configs += [ "//build/config/linux:glib" ] - } - if (!is_component_build) { # Set rpath to find libmalloc_wrapper.so even in a non-component build. configs += [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
diff --git a/base/debug/activity_analyzer.cc b/base/debug/activity_analyzer.cc index 3c4f808..438c241 100644 --- a/base/debug/activity_analyzer.cc +++ b/base/debug/activity_analyzer.cc
@@ -119,7 +119,7 @@ // Add this analyzer to the map of known ones, indexed by a unique thread // identifier. - DCHECK(!ContainsKey(analyzers_, analyzer->GetThreadKey())); + DCHECK(!base::ContainsKey(analyzers_, analyzer->GetThreadKey())); analyzer->allocator_reference_ = ref; analyzers_[analyzer->GetThreadKey()] = std::move(analyzer); }
diff --git a/base/debug/activity_analyzer.h b/base/debug/activity_analyzer.h index 5333de2..5a080b0 100644 --- a/base/debug/activity_analyzer.h +++ b/base/debug/activity_analyzer.h
@@ -20,9 +20,6 @@ // makes that information available to other code. class BASE_EXPORT ThreadActivityAnalyzer { public: - using Activity = ThreadActivityTracker::Activity; - using ActivitySnapshot = ThreadActivityTracker::ActivitySnapshot; - // This class provides keys that uniquely identify a thread, even across // multiple processes. class ThreadKey {
diff --git a/base/debug/activity_analyzer_unittest.cc b/base/debug/activity_analyzer_unittest.cc index ba23a481..ff656f60 100644 --- a/base/debug/activity_analyzer_unittest.cc +++ b/base/debug/activity_analyzer_unittest.cc
@@ -48,8 +48,6 @@ const int kMemorySize = 1 << 10; // 1MiB const int kStackSize = 1 << 10; // 1KiB - using Activity = ThreadActivityAnalyzer::Activity; - ActivityAnalyzerTest() {} ~ActivityAnalyzerTest() override { @@ -86,8 +84,8 @@ public: SimpleActivityThread(const std::string& name, const void* source, - ThreadActivityTracker::ActivityType activity, - const ThreadActivityTracker::ActivityData& data) + Activity::Type activity, + const ActivityData& data) : SimpleThread(name, Options()), source_(source), activity_(activity), @@ -125,8 +123,8 @@ private: const void* source_; - ThreadActivityTracker::ActivityType activity_; - ThreadActivityTracker::ActivityData data_; + Activity::Type activity_; + ActivityData data_; bool ready_ = false; bool exit_ = false; @@ -153,8 +151,8 @@ EXPECT_EQ(ta1, analyzer.GetAnalyzerForThread(tk1)); // Create a second thread that will do something. - SimpleActivityThread t2("t2", nullptr, ThreadActivityTracker::ACT_TASK, - ThreadActivityTracker::ActivityData::ForTask(11)); + SimpleActivityThread t2("t2", nullptr, Activity::ACT_TASK, + ActivityData::ForTask(11)); t2.Start(); t2.WaitReady();
diff --git a/base/debug/activity_tracker.cc b/base/debug/activity_tracker.cc index ea9e1258..7b3b185 100644 --- a/base/debug/activity_tracker.cc +++ b/base/debug/activity_tracker.cc
@@ -33,9 +33,69 @@ // The minimum depth a stack should support. const int kMinStackDepth = 2; +union ThreadRef { + int64_t as_id; +#if defined(OS_WIN) + // On Windows, the handle itself is often a pseudo-handle with a common + // value meaning "this thread" and so the thread-id is used. The former + // can be converted to a thread-id with a system call. + PlatformThreadId as_tid; +#elif defined(OS_POSIX) + // On Posix, the handle is always a unique identifier so no conversion + // needs to be done. However, it's value is officially opaque so there + // is no one correct way to convert it to a numerical identifier. + PlatformThreadHandle::Handle as_handle; +#endif +}; + } // namespace +// It doesn't matter what is contained in this (though it will be all zeros) +// as only the address of it is important. +const ActivityData kNullActivityData = {}; + +ActivityData ActivityData::ForThread(const PlatformThreadHandle& handle) { + ThreadRef thread_ref; + thread_ref.as_id = 0; // Zero the union in case other is smaller. +#if defined(OS_WIN) + thread_ref.as_tid = ::GetThreadId(handle.platform_handle()); +#elif defined(OS_POSIX) + thread_ref.as_handle = handle.platform_handle(); +#endif + return ForThread(thread_ref.as_id); +} + +// static +void Activity::FillFrom(Activity* activity, + const void* origin, + Type type, + const ActivityData& data) { + activity->time_internal = base::TimeTicks::Now().ToInternalValue(); + activity->origin_address = reinterpret_cast<uintptr_t>(origin); + activity->activity_type = type; + activity->data = data; + +#if defined(SYZYASAN) + // Create a stacktrace from the current location and get the addresses. + StackTrace stack_trace; + size_t stack_depth; + const void* const* stack_addrs = stack_trace.Addresses(&stack_depth); + // Copy the stack addresses, ignoring the first one (here). + size_t i; + for (i = 1; i < stack_depth && i < kActivityCallStackSize; ++i) { + activity->call_stack[i - 1] = reinterpret_cast<uintptr_t>(stack_addrs[i]); + } + activity->call_stack[i - 1] = 0; +#else + activity->call_stack[0] = 0; +#endif +} + +ActivitySnapshot::ActivitySnapshot() {} +ActivitySnapshot::~ActivitySnapshot() {} + + // This information is kept for every thread that is tracked. It is filled // the very first time the thread is seen. All fields must be of exact sizes // so there is no issue moving between 32 and 64-bit builds. @@ -43,32 +103,19 @@ // This unique number indicates a valid initialization of the memory. uint64_t cookie; - // The process-id and thread-id to which this data belongs. These identifiers - // are not guaranteed to mean anything but are unique, in combination, among - // all active trackers. It would be nice to always have the process_id be a - // 64-bit value but the necessity of having it atomic (for the memory barriers - // it provides) limits it to the natural word size of the machine. + // The process-id and thread-id (thread_ref.as_id) to which this data belongs. + // These identifiers are not guaranteed to mean anything but are unique, in + // combination, among all active trackers. It would be nice to always have + // the process_id be a 64-bit value but the necessity of having it atomic + // (for the memory barriers it provides) limits it to the natural word size + // of the machine. #ifdef ARCH_CPU_64_BITS std::atomic<int64_t> process_id; #else std::atomic<int32_t> process_id; int32_t process_id_padding; #endif - - union { - int64_t as_id; -#if defined(OS_WIN) - // On Windows, the handle itself is often a pseudo-handle with a common - // value meaning "this thread" and so the thread-id is used. The former - // can be converted to a thread-id with a system call. - PlatformThreadId as_tid; -#elif defined(OS_POSIX) - // On Posix, the handle is always a unique identifier so no conversion - // needs to be done. However, it's value is officially opaque so there - // is no one correct way to convert it to a numerical identifier. - PlatformThreadHandle::Handle as_handle; -#endif - } thread_ref; + ThreadRef thread_ref; // The start-time and start-ticks when the data was created. Each activity // record has a |time_internal| value that can be converted to a "wall time" @@ -101,29 +148,6 @@ char thread_name[32]; }; -// It doesn't matter what is contained in this (though it will be all zeros) -// as only the address of it is important. -const ThreadActivityTracker::ActivityData - ThreadActivityTracker::kNullActivityData = {}; - -ThreadActivityTracker::ActivityData -ThreadActivityTracker::ActivityData::ForThread( - const PlatformThreadHandle& handle) { - // Header already has a conversion union; reuse that. - ThreadActivityTracker::Header header; - header.thread_ref.as_id = 0; // Zero the union in case other is smaller. -#if defined(OS_WIN) - header.thread_ref.as_tid = ::GetThreadId(handle.platform_handle()); -#elif defined(OS_POSIX) - header.thread_ref.as_handle = handle.platform_handle(); -#endif - return ForThread(header.thread_ref.as_id); -} - -ThreadActivityTracker::ActivitySnapshot::ActivitySnapshot() {} -ThreadActivityTracker::ActivitySnapshot::~ActivitySnapshot() {} - - ThreadActivityTracker::ThreadActivityTracker(void* base, size_t size) : header_(static_cast<Header*>(base)), stack_(reinterpret_cast<Activity*>(reinterpret_cast<char*>(base) + @@ -201,11 +225,12 @@ ThreadActivityTracker::~ThreadActivityTracker() {} void ThreadActivityTracker::PushActivity(const void* origin, - ActivityType type, + Activity::Type type, const ActivityData& data) { // A thread-checker creates a lock to check the thread-id which means // re-entry into this code if lock acquisitions are being tracked. - DCHECK(type == ACT_LOCK_ACQUIRE || thread_checker_.CalledOnValidThread()); + DCHECK(type == Activity::ACT_LOCK_ACQUIRE || + thread_checker_.CalledOnValidThread()); // Get the current depth of the stack. No access to other memory guarded // by this variable is done here so a "relaxed" load is acceptable. @@ -223,28 +248,7 @@ // Get a pointer to the next activity and load it. No atomicity is required // here because the memory is known only to this thread. It will be made // known to other threads once the depth is incremented. - Activity* activity = &stack_[depth]; - activity->time_internal = base::TimeTicks::Now().ToInternalValue(); - activity->origin_address = reinterpret_cast<uintptr_t>(origin); - activity->activity_type = type; - activity->data = data; - -#if defined(SYZYASAN) - // Create a stacktrace from the current location and get the addresses. - StackTrace stack_trace; - size_t stack_depth; - const void* const* stack_addrs = stack_trace.Addresses(&stack_depth); - // Copy the stack addresses, ignoring the first one (here). - size_t i; - for (i = 1; i < stack_depth && i < kActivityCallStackSize; ++i) { - activity->call_stack[i - 1] = reinterpret_cast<uintptr_t>(stack_addrs[i]); - } - activity->call_stack[i - 1] = 0; -#else - // Since the memory was initially zero and nothing ever overwrites it in - // this "else" case, there is no need to write even the null terminator. - //activity->call_stack[0] = 0; -#endif + Activity::FillFrom(&stack_[depth], origin, type, data); // Save the incremented depth. Because this guards |activity| memory filled // above that may be read by another thread once the recorded depth changes, @@ -252,10 +256,10 @@ header_->current_depth.store(depth + 1, std::memory_order_release); } -void ThreadActivityTracker::ChangeActivity(ActivityType type, +void ThreadActivityTracker::ChangeActivity(Activity::Type type, const ActivityData& data) { DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(type != ACT_NULL || &data != &kNullActivityData); + DCHECK(type != Activity::ACT_NULL || &data != &kNullActivityData); // Get the current depth of the stack and acquire the data held there. uint32_t depth = header_->current_depth.load(std::memory_order_acquire); @@ -265,9 +269,9 @@ if (depth <= stack_slots_) { Activity* activity = &stack_[depth - 1]; - if (type != ACT_NULL) { - DCHECK_EQ(activity->activity_type & ACT_CATEGORY_MASK, - type & ACT_CATEGORY_MASK); + if (type != Activity::ACT_NULL) { + DCHECK_EQ(activity->activity_type & Activity::ACT_CATEGORY_MASK, + type & Activity::ACT_CATEGORY_MASK); activity->activity_type = type; } @@ -288,7 +292,7 @@ // A thread-checker creates a lock to check the thread-id which means // re-entry into this code if lock acquisitions are being tracked. - DCHECK(stack_[depth - 1].activity_type == ACT_LOCK_ACQUIRE || + DCHECK(stack_[depth - 1].activity_type == Activity::ACT_LOCK_ACQUIRE || thread_checker_.CalledOnValidThread()); // The stack has shrunk meaning that some other thread trying to copy the @@ -593,10 +597,8 @@ void GlobalActivityTracker::ReleaseTrackerForCurrentThreadForTesting() { ThreadActivityTracker* tracker = reinterpret_cast<ThreadActivityTracker*>(this_thread_tracker_.Get()); - if (tracker) { - this_thread_tracker_.Free(); + if (tracker) delete tracker; - } } GlobalActivityTracker::GlobalActivityTracker( @@ -700,70 +702,65 @@ delete reinterpret_cast<ManagedActivityTracker*>(value); } - ScopedActivity::ScopedActivity(const tracked_objects::Location& location, uint8_t action, uint32_t id, int32_t info) : GlobalActivityTracker::ScopedThreadActivity( location.program_counter(), - static_cast<ThreadActivityTracker::ActivityType>( - ThreadActivityTracker::ACT_GENERIC | action), - ThreadActivityTracker::ActivityData::ForGeneric(id, info), + static_cast<Activity::Type>(Activity::ACT_GENERIC | action), + ActivityData::ForGeneric(id, info), /*lock_allowed=*/true), id_(id) { // The action must not affect the category bits of the activity type. - DCHECK_EQ(0, action & ThreadActivityTracker::ACT_CATEGORY_MASK); + DCHECK_EQ(0, action & Activity::ACT_CATEGORY_MASK); } void ScopedActivity::ChangeAction(uint8_t action) { - DCHECK_EQ(0, action & ThreadActivityTracker::ACT_CATEGORY_MASK); - ChangeTypeAndData(static_cast<ThreadActivityTracker::ActivityType>( - ThreadActivityTracker::ACT_GENERIC | action), - ThreadActivityTracker::kNullActivityData); + DCHECK_EQ(0, action & Activity::ACT_CATEGORY_MASK); + ChangeTypeAndData(static_cast<Activity::Type>(Activity::ACT_GENERIC | action), + kNullActivityData); } void ScopedActivity::ChangeInfo(int32_t info) { - ChangeTypeAndData(ThreadActivityTracker::ACT_NULL, - ThreadActivityTracker::ActivityData::ForGeneric(id_, info)); + ChangeTypeAndData(Activity::ACT_NULL, ActivityData::ForGeneric(id_, info)); } void ScopedActivity::ChangeActionAndInfo(uint8_t action, int32_t info) { - DCHECK_EQ(0, action & ThreadActivityTracker::ACT_CATEGORY_MASK); - ChangeTypeAndData(static_cast<ThreadActivityTracker::ActivityType>( - ThreadActivityTracker::ACT_GENERIC | action), - ThreadActivityTracker::ActivityData::ForGeneric(id_, info)); + DCHECK_EQ(0, action & Activity::ACT_CATEGORY_MASK); + ChangeTypeAndData(static_cast<Activity::Type>(Activity::ACT_GENERIC | action), + ActivityData::ForGeneric(id_, info)); } ScopedTaskRunActivity::ScopedTaskRunActivity(const base::PendingTask& task) : GlobalActivityTracker::ScopedThreadActivity( task.posted_from.program_counter(), - ThreadActivityTracker::ACT_TASK_RUN, - ThreadActivityTracker::ActivityData::ForTask(task.sequence_num), + Activity::ACT_TASK_RUN, + ActivityData::ForTask(task.sequence_num), /*lock_allowed=*/true) {} ScopedLockAcquireActivity::ScopedLockAcquireActivity( const base::internal::LockImpl* lock) : GlobalActivityTracker::ScopedThreadActivity( nullptr, - ThreadActivityTracker::ACT_LOCK_ACQUIRE, - ThreadActivityTracker::ActivityData::ForLock(lock), + Activity::ACT_LOCK_ACQUIRE, + ActivityData::ForLock(lock), /*lock_allowed=*/false) {} ScopedEventWaitActivity::ScopedEventWaitActivity( const base::WaitableEvent* event) : GlobalActivityTracker::ScopedThreadActivity( nullptr, - ThreadActivityTracker::ACT_EVENT_WAIT, - ThreadActivityTracker::ActivityData::ForEvent(event), + Activity::ACT_EVENT_WAIT, + ActivityData::ForEvent(event), /*lock_allowed=*/true) {} ScopedThreadJoinActivity::ScopedThreadJoinActivity( const base::PlatformThreadHandle* thread) : GlobalActivityTracker::ScopedThreadActivity( nullptr, - ThreadActivityTracker::ACT_THREAD_JOIN, - ThreadActivityTracker::ActivityData::ForThread(*thread), + Activity::ACT_THREAD_JOIN, + ActivityData::ForThread(*thread), /*lock_allowed=*/true) {} #if !defined(OS_NACL) && !defined(OS_IOS) @@ -771,8 +768,8 @@ const base::Process* process) : GlobalActivityTracker::ScopedThreadActivity( nullptr, - ThreadActivityTracker::ACT_PROCESS_WAIT, - ThreadActivityTracker::ActivityData::ForProcess(process->Pid()), + Activity::ACT_PROCESS_WAIT, + ActivityData::ForProcess(process->Pid()), /*lock_allowed=*/true) {} #endif
diff --git a/base/debug/activity_tracker.h b/base/debug/activity_tracker.h index acac6b1..d6ff724 100644 --- a/base/debug/activity_tracker.h +++ b/base/debug/activity_tracker.h
@@ -39,29 +39,100 @@ namespace debug { -// This class manages tracking a stack of activities for a single thread in -// a persistent manner, implementing a bounded-size stack in a fixed-size -// memory allocation. In order to support an operational mode where another -// thread is analyzing this data in real-time, atomic operations are used -// where necessary to guarantee a consistent view from the outside. -// -// This class is not generally used directly but instead managed by the -// GlobalActivityTracker instance and updated using Scoped*Activity local -// objects. -class BASE_EXPORT ThreadActivityTracker { - public: - enum : int { - // The maximum number of call-stack addresses stored per activity. This - // cannot be changed without also changing the version number of the - // structure. See kTypeIdActivityTracker in GlobalActivityTracker. - kActivityCallStackSize = 10 - }; +class ThreadActivityTracker; +enum : int { + // The maximum number of call-stack addresses stored per activity. This + // cannot be changed without also changing the version number of the + // structure. See kTypeIdActivityTracker in GlobalActivityTracker. + kActivityCallStackSize = 10, +}; + +// The data associated with an activity is dependent upon the activity type. +// This union defines all of the various fields. All fields must be explicitly +// sized types to ensure no interoperability problems between 32-bit and +// 64-bit systems. +union ActivityData { + // Generic activities don't have any defined structure. + struct { + uint32_t id; // An arbitrary identifier used for association. + int32_t info; // An arbitrary value used for information purposes. + } generic; + struct { + uint64_t sequence_id; // The sequence identifier of the posted task. + } task; + struct { + uint64_t lock_address; // The memory address of the lock object. + } lock; + struct { + uint64_t event_address; // The memory address of the event object. + } event; + struct { + int64_t thread_id; // A unique identifier for a thread within a process. + } thread; + struct { + int64_t process_id; // A unique identifier for a process. + } process; + + // These methods create an ActivityData object from the appropriate + // parameters. Objects of this type should always be created this way to + // ensure that no fields remain unpopulated should the set of recorded + // fields change. They're defined inline where practical because they + // reduce to loading a small local structure with a few values, roughly + // the same as loading all those values into parameters. + + static ActivityData ForGeneric(uint32_t id, int32_t info) { + ActivityData data; + data.generic.id = id; + data.generic.info = info; + return data; + } + + static ActivityData ForTask(uint64_t sequence) { + ActivityData data; + data.task.sequence_id = sequence; + return data; + } + + static ActivityData ForLock(const void* lock) { + ActivityData data; + data.lock.lock_address = reinterpret_cast<uintptr_t>(lock); + return data; + } + + static ActivityData ForEvent(const void* event) { + ActivityData data; + data.event.event_address = reinterpret_cast<uintptr_t>(event); + return data; + } + + static ActivityData ForThread(const PlatformThreadHandle& handle); + static ActivityData ForThread(const int64_t id) { + ActivityData data; + data.thread.thread_id = id; + return data; + } + + static ActivityData ForProcess(const int64_t id) { + ActivityData data; + data.process.process_id = id; + return data; + } +}; + +// A "null" activity-data that can be passed to indicate "do not change". +extern const ActivityData kNullActivityData; + +// This structure is the full contents recorded for every activity pushed +// onto the stack. The |activity_type| indicates what is actually stored in +// the |data| field. All fields must be explicitly sized types to ensure no +// interoperability problems between 32-bit and 64-bit systems. +struct Activity { // The type of an activity on the stack. Activities are broken into // categories with the category ID taking the top 4 bits and the lower // bits representing an action within that category. This combination // makes it easy to "switch" based on the type during analysis. - enum ActivityType : uint8_t { + enum Type : uint8_t { // This "null" constant is used to indicate "do not change" in calls. ACT_NULL = 0, @@ -99,142 +170,82 @@ ACT_ACTION_MASK = 0xF }; - // The data associated with an activity is dependent upon the activity type. - // This union defines all of the various fields. All fields must be explicitly - // sized types to ensure no interoperability problems between 32-bit and - // 64-bit systems. - union ActivityData { - // Generic activities don't have any defined structure. - struct { - uint32_t id; // An arbitrary identifier used for association. - int32_t info; // An arbitrary value used for information purposes. - } generic; - struct { - uint64_t sequence_id; // The sequence identifier of the posted task. - } task; - struct { - uint64_t lock_address; // The memory address of the lock object. - } lock; - struct { - uint64_t event_address; // The memory address of the event object. - } event; - struct { - int64_t thread_id; // A unique identifier for a thread within a process. - } thread; - struct { - int64_t process_id; // A unique identifier for a process. - } process; + // Internal representation of time. During collection, this is in "ticks" + // but when returned in a snapshot, it is "wall time". + int64_t time_internal; - // These methods create an ActivityData object from the appropriate - // parameters. Objects of this type should always be created this way to - // ensure that no fields remain unpopulated should the set of recorded - // fields change. They're defined inline where practical because they - // reduce to loading a small local structure with a few values, roughly - // the same as loading all those values into parameters. + // The address that is the origin of the activity if it not obvious from + // the call stack. This is useful for things like tasks that are posted + // from a completely different thread though most activities will leave + // it null. + uint64_t origin_address; - static ActivityData ForGeneric(uint32_t id, int32_t info) { - ActivityData data; - data.generic.id = id; - data.generic.info = info; - return data; - } + // Array of program-counters that make up the top of the call stack. + // Despite the fixed size, this list is always null-terminated. Entries + // after the terminator have no meaning and may or may not also be null. + // The list will be completely empty if call-stack collection is not + // enabled. + uint64_t call_stack[kActivityCallStackSize]; - static ActivityData ForTask(uint64_t sequence) { - ActivityData data; - data.task.sequence_id = sequence; - return data; - } + // The (enumerated) type of the activity. This defines what fields of the + // |data| record are valid. + uint8_t activity_type; - static ActivityData ForLock(const void* lock) { - ActivityData data; - data.lock.lock_address = reinterpret_cast<uintptr_t>(lock); - return data; - } + // Padding to ensure that the next member begins on a 64-bit boundary + // even on 32-bit builds which ensures inter-operability between CPU + // architectures. New fields can be taken from this space. + uint8_t padding[7]; - static ActivityData ForEvent(const void* event) { - ActivityData data; - data.event.event_address = reinterpret_cast<uintptr_t>(event); - return data; - } + // Information specific to the |activity_type|. + ActivityData data; - static ActivityData ForThread(const PlatformThreadHandle& handle); - static ActivityData ForThread(const int64_t id) { - ActivityData data; - data.thread.thread_id = id; - return data; - } + static void FillFrom(Activity* activity, + const void* origin, + Type type, + const ActivityData& data); +}; - static ActivityData ForProcess(const int64_t id) { - ActivityData data; - data.process.process_id = id; - return data; - } - }; +// This structure holds a copy of all the internal data at the moment the +// "snapshot" operation is done. It is disconnected from the live tracker +// so that continued operation of the thread will not cause changes here. +struct BASE_EXPORT ActivitySnapshot { + // Explicit constructor/destructor are needed because of complex types + // with non-trivial default constructors and destructors. + ActivitySnapshot(); + ~ActivitySnapshot(); - // This structure is the full contents recorded for every activity pushed - // onto the stack. The |activity_type| indicates what is actually stored in - // the |data| field. All fields must be explicitly sized types to ensure no - // interoperability problems between 32-bit and 64-bit systems. - struct Activity { - // Internal representation of time. During collection, this is in "ticks" - // but when returned in a snapshot, it is "wall time". - int64_t time_internal; + // The name of the thread as set when it was created. The name may be + // truncated due to internal length limitations. + std::string thread_name; - // The address that is the origin of the activity if it not obvious from - // the call stack. This is useful for things like tasks that are posted - // from a completely different thread though most activities will leave - // it null. - uint64_t origin_address; + // The process and thread IDs. These values have no meaning other than + // they uniquely identify a running process and a running thread within + // that process. Thread-IDs can be re-used across different processes + // and both can be re-used after the process/thread exits. + int64_t process_id = 0; + int64_t thread_id = 0; - // Array of program-counters that make up the top of the call stack. - // Despite the fixed size, this list is always null-terminated. Entries - // after the terminator have no meaning and may or may not also be null. - // The list will be completely empty if call-stack collection is not - // enabled. - uint64_t call_stack[kActivityCallStackSize]; + // The current stack of activities that are underway for this thread. It + // is limited in its maximum size with later entries being left off. + std::vector<Activity> activity_stack; - // The (enumerated) type of the activity. This defines what fields of the - // |data| record are valid. - uint8_t activity_type; + // The current total depth of the activity stack, including those later + // entries not recorded in the |activity_stack| vector. + uint32_t activity_stack_depth = 0; +}; - // Padding to ensure that the next member begins on a 64-bit boundary - // even on 32-bit builds which ensures inter-operability between CPU - // architectures. New fields can be taken from this space. - uint8_t padding[7]; - // Information specific to the |activity_type|. - ActivityData data; - }; - - // This structure holds a copy of all the internal data at the moment the - // "snapshot" operation is done. It is disconnected from the live tracker - // so that continued operation of the thread will not cause changes here. - struct BASE_EXPORT ActivitySnapshot { - // Explicit constructor/destructor are needed because of complex types - // with non-trivial default constructors and destructors. - ActivitySnapshot(); - ~ActivitySnapshot(); - - // The name of the thread as set when it was created. The name may be - // truncated due to internal length limitations. - std::string thread_name; - - // The process and thread IDs. These values have no meaning other than - // they uniquely identify a running process and a running thread within - // that process. Thread-IDs can be re-used across different processes - // and both can be re-used after the process/thread exits. - int64_t process_id = 0; - int64_t thread_id = 0; - - // The current stack of activities that are underway for this thread. It - // is limited in its maximum size with later entries being left off. - std::vector<Activity> activity_stack; - - // The current total depth of the activity stack, including those later - // entries not recorded in the |activity_stack| vector. - uint32_t activity_stack_depth = 0; - }; - +// This class manages tracking a stack of activities for a single thread in +// a persistent manner, implementing a bounded-size stack in a fixed-size +// memory allocation. In order to support an operational mode where another +// thread is analyzing this data in real-time, atomic operations are used +// where necessary to guarantee a consistent view from the outside. +// +// This class is not generally used directly but instead managed by the +// GlobalActivityTracker instance and updated using Scoped*Activity local +// objects. +class BASE_EXPORT ThreadActivityTracker { + public: // This is the base class for having the compiler manage an activity on the // tracker's stack. It does nothing but call methods on the passed |tracker| // if it is not null, making it safe (and cheap) to create these objects @@ -243,7 +254,7 @@ public: ScopedActivity(ThreadActivityTracker* tracker, const void* origin, - ActivityType type, + Activity::Type type, const ActivityData& data) : tracker_(tracker) { if (tracker_) @@ -255,7 +266,7 @@ tracker_->PopActivity(); } - void ChangeTypeAndData(ActivityType type, const ActivityData& data) { + void ChangeTypeAndData(Activity::Type type, const ActivityData& data) { if (tracker_) tracker_->ChangeActivity(type, data); } @@ -278,7 +289,7 @@ // the code, though it can be null if the creator's address is not known. // The |type| and |data| describe the activity. void PushActivity(const void* origin, - ActivityType type, + Activity::Type type, const ActivityData& data); // Changes the activity |type| and |data| of the top-most entry on the stack. @@ -288,7 +299,7 @@ // unchanged. The type, if changed, must remain in the same category. // Changing both is not atomic so a snapshot operation could occur between // the update of |type| and |data| or between update of |data| fields. - void ChangeActivity(ActivityType type, const ActivityData& data); + void ChangeActivity(Activity::Type type, const ActivityData& data); // Indicates that an activity has completed. void PopActivity(); @@ -307,9 +318,6 @@ // the internal header structure for the stack. static size_t SizeForStackDepth(int stack_depth); - // A "null" activity-data that can be passed to indicate "do not change". - static const ActivityData kNullActivityData; - private: friend class ActivityTrackerTest; @@ -354,8 +362,8 @@ : public ThreadActivityTracker::ScopedActivity { public: ScopedThreadActivity(const void* origin, - ThreadActivityTracker::ActivityType type, - const ThreadActivityTracker::ActivityData& data, + Activity::Type type, + const ActivityData& data, bool lock_allowed) : ThreadActivityTracker::ScopedActivity( GetOrCreateTracker(lock_allowed),
diff --git a/base/debug/activity_tracker_unittest.cc b/base/debug/activity_tracker_unittest.cc index 8b49601..c36d8fa 100644 --- a/base/debug/activity_tracker_unittest.cc +++ b/base/debug/activity_tracker_unittest.cc
@@ -45,9 +45,6 @@ const int kMemorySize = 1 << 10; // 1MiB const int kStackSize = 1 << 10; // 1KiB - using Activity = ThreadActivityTracker::Activity; - using ActivityData = ThreadActivityTracker::ActivityData; - ActivityTrackerTest() {} ~ActivityTrackerTest() override { @@ -84,36 +81,34 @@ TEST_F(ActivityTrackerTest, PushPopTest) { std::unique_ptr<ThreadActivityTracker> tracker = CreateActivityTracker(); - ThreadActivityTracker::ActivitySnapshot snapshot; + ActivitySnapshot snapshot; ASSERT_TRUE(tracker->Snapshot(&snapshot)); ASSERT_EQ(0U, snapshot.activity_stack_depth); ASSERT_EQ(0U, snapshot.activity_stack.size()); char origin1; - tracker->PushActivity(&origin1, ThreadActivityTracker::ACT_TASK, + tracker->PushActivity(&origin1, Activity::ACT_TASK, ActivityData::ForTask(11)); ASSERT_TRUE(tracker->Snapshot(&snapshot)); ASSERT_EQ(1U, snapshot.activity_stack_depth); ASSERT_EQ(1U, snapshot.activity_stack.size()); EXPECT_NE(0, snapshot.activity_stack[0].time_internal); - EXPECT_EQ(ThreadActivityTracker::ACT_TASK, - snapshot.activity_stack[0].activity_type); + EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[0].activity_type); EXPECT_EQ(reinterpret_cast<uintptr_t>(&origin1), snapshot.activity_stack[0].origin_address); EXPECT_EQ(11U, snapshot.activity_stack[0].data.task.sequence_id); char origin2; char lock2; - tracker->PushActivity(&origin2, ThreadActivityTracker::ACT_LOCK, + tracker->PushActivity(&origin2, Activity::ACT_LOCK, ActivityData::ForLock(&lock2)); ASSERT_TRUE(tracker->Snapshot(&snapshot)); ASSERT_EQ(2U, snapshot.activity_stack_depth); ASSERT_EQ(2U, snapshot.activity_stack.size()); EXPECT_LE(snapshot.activity_stack[0].time_internal, snapshot.activity_stack[1].time_internal); - EXPECT_EQ(ThreadActivityTracker::ACT_LOCK, - snapshot.activity_stack[1].activity_type); + EXPECT_EQ(Activity::ACT_LOCK, snapshot.activity_stack[1].activity_type); EXPECT_EQ(reinterpret_cast<uintptr_t>(&origin2), snapshot.activity_stack[1].origin_address); EXPECT_EQ(reinterpret_cast<uintptr_t>(&lock2), @@ -123,8 +118,7 @@ ASSERT_TRUE(tracker->Snapshot(&snapshot)); ASSERT_EQ(1U, snapshot.activity_stack_depth); ASSERT_EQ(1U, snapshot.activity_stack.size()); - EXPECT_EQ(ThreadActivityTracker::ACT_TASK, - snapshot.activity_stack[0].activity_type); + EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[0].activity_type); EXPECT_EQ(reinterpret_cast<uintptr_t>(&origin1), snapshot.activity_stack[0].origin_address); EXPECT_EQ(11U, snapshot.activity_stack[0].data.task.sequence_id); @@ -140,7 +134,7 @@ ThreadActivityTracker* tracker = GlobalActivityTracker::Get()->GetOrCreateTrackerForCurrentThread(); - ThreadActivityTracker::ActivitySnapshot snapshot; + ActivitySnapshot snapshot; ASSERT_TRUE(tracker->Snapshot(&snapshot)); ASSERT_EQ(0U, snapshot.activity_stack_depth); @@ -153,8 +147,7 @@ ASSERT_TRUE(tracker->Snapshot(&snapshot)); ASSERT_EQ(1U, snapshot.activity_stack_depth); ASSERT_EQ(1U, snapshot.activity_stack.size()); - EXPECT_EQ(ThreadActivityTracker::ACT_TASK, - snapshot.activity_stack[0].activity_type); + EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[0].activity_type); { PendingTask task2(FROM_HERE, base::Bind(&DoNothing)); @@ -163,15 +156,13 @@ ASSERT_TRUE(tracker->Snapshot(&snapshot)); ASSERT_EQ(2U, snapshot.activity_stack_depth); ASSERT_EQ(2U, snapshot.activity_stack.size()); - EXPECT_EQ(ThreadActivityTracker::ACT_TASK, - snapshot.activity_stack[1].activity_type); + EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[1].activity_type); } ASSERT_TRUE(tracker->Snapshot(&snapshot)); ASSERT_EQ(1U, snapshot.activity_stack_depth); ASSERT_EQ(1U, snapshot.activity_stack.size()); - EXPECT_EQ(ThreadActivityTracker::ACT_TASK, - snapshot.activity_stack[0].activity_type); + EXPECT_EQ(Activity::ACT_TASK, snapshot.activity_stack[0].activity_type); } ASSERT_TRUE(tracker->Snapshot(&snapshot)); @@ -211,8 +202,8 @@ public: SimpleActivityThread(const std::string& name, const void* origin, - ThreadActivityTracker::ActivityType activity, - const ThreadActivityTracker::ActivityData& data) + Activity::Type activity, + const ActivityData& data) : SimpleThread(name, Options()), origin_(origin), activity_(activity), @@ -250,8 +241,8 @@ private: const void* origin_; - ThreadActivityTracker::ActivityType activity_; - ThreadActivityTracker::ActivityData data_; + Activity::Type activity_; + ActivityData data_; bool ready_ = false; bool exit_ = false; @@ -267,8 +258,8 @@ const size_t starting_active = GetGlobalActiveTrackerCount(); const size_t starting_inactive = GetGlobalInactiveTrackerCount(); - SimpleActivityThread t1("t1", nullptr, ThreadActivityTracker::ACT_TASK, - ThreadActivityTracker::ActivityData::ForTask(11)); + SimpleActivityThread t1("t1", nullptr, Activity::ACT_TASK, + ActivityData::ForTask(11)); t1.Start(); t1.WaitReady(); EXPECT_EQ(starting_active + 1, GetGlobalActiveTrackerCount()); @@ -281,8 +272,8 @@ // Start another thread and ensure it re-uses the existing memory. - SimpleActivityThread t2("t2", nullptr, ThreadActivityTracker::ACT_TASK, - ThreadActivityTracker::ActivityData::ForTask(22)); + SimpleActivityThread t2("t2", nullptr, Activity::ACT_TASK, + ActivityData::ForTask(22)); t2.Start(); t2.WaitReady(); EXPECT_EQ(starting_active + 1, GetGlobalActiveTrackerCount());
diff --git a/base/files/file_path_watcher_linux.cc b/base/files/file_path_watcher_linux.cc index 87bddd3..2444b445 100644 --- a/base/files/file_path_watcher_linux.cc +++ b/base/files/file_path_watcher_linux.cc
@@ -66,7 +66,9 @@ typedef std::set<FilePathWatcherImpl*> WatcherSet; InotifyReader(); - ~InotifyReader(); + // There is no destructor because |g_inotify_reader| is a + // base::LazyInstace::Leaky object. Having a destructor causes build + // issues with GCC 6 (http://crbug.com/636346). // We keep track of which delegates want to be notified on which watches. hash_map<Watch, WatcherSet> watchers_; @@ -80,9 +82,6 @@ // File descriptor returned by inotify_init. const int inotify_fd_; - // Use self-pipe trick to unblock select during shutdown. - int shutdown_pipe_[2]; - // Flag set to true when startup was successful. bool valid_; @@ -194,13 +193,10 @@ DISALLOW_COPY_AND_ASSIGN(FilePathWatcherImpl); }; -void InotifyReaderCallback(InotifyReader* reader, int inotify_fd, - int shutdown_fd) { +void InotifyReaderCallback(InotifyReader* reader, int inotify_fd) { // Make sure the file descriptors are good for use with select(). CHECK_LE(0, inotify_fd); CHECK_GT(FD_SETSIZE, inotify_fd); - CHECK_LE(0, shutdown_fd); - CHECK_GT(FD_SETSIZE, shutdown_fd); trace_event::TraceLog::GetInstance()->SetCurrentThreadBlocksMessageLoop(); @@ -208,20 +204,15 @@ fd_set rfds; FD_ZERO(&rfds); FD_SET(inotify_fd, &rfds); - FD_SET(shutdown_fd, &rfds); // Wait until some inotify events are available. int select_result = - HANDLE_EINTR(select(std::max(inotify_fd, shutdown_fd) + 1, - &rfds, NULL, NULL, NULL)); + HANDLE_EINTR(select(inotify_fd + 1, &rfds, NULL, NULL, NULL)); if (select_result < 0) { DPLOG(WARNING) << "select failed"; return; } - if (FD_ISSET(shutdown_fd, &rfds)) - return; - // Adjust buffer size to current event queue size. int buffer_size; int ioctl_result = HANDLE_EINTR(ioctl(inotify_fd, FIONREAD, @@ -263,33 +254,14 @@ if (inotify_fd_ < 0) PLOG(ERROR) << "inotify_init() failed"; - shutdown_pipe_[0] = -1; - shutdown_pipe_[1] = -1; - if (inotify_fd_ >= 0 && pipe(shutdown_pipe_) == 0 && thread_.Start()) { + if (inotify_fd_ >= 0 && thread_.Start()) { thread_.task_runner()->PostTask( FROM_HERE, - Bind(&InotifyReaderCallback, this, inotify_fd_, shutdown_pipe_[0])); + Bind(&InotifyReaderCallback, this, inotify_fd_)); valid_ = true; } } -InotifyReader::~InotifyReader() { - if (valid_) { - // Write to the self-pipe so that the select call in InotifyReaderTask - // returns. - ssize_t ret = HANDLE_EINTR(write(shutdown_pipe_[1], "", 1)); - DPCHECK(ret > 0); - DCHECK_EQ(ret, 1); - thread_.Stop(); - } - if (inotify_fd_ >= 0) - close(inotify_fd_); - if (shutdown_pipe_[0] >= 0) - close(shutdown_pipe_[0]); - if (shutdown_pipe_[1] >= 0) - close(shutdown_pipe_[1]); -} - InotifyReader::Watch InotifyReader::AddWatch( const FilePath& path, FilePathWatcherImpl* watcher) { if (!valid_)
diff --git a/base/ios/crb_protocol_observers.mm b/base/ios/crb_protocol_observers.mm index 8c4172a..1a3b9f73 100644 --- a/base/ios/crb_protocol_observers.mm +++ b/base/ios/crb_protocol_observers.mm
@@ -104,7 +104,7 @@ DCHECK(observer); DCHECK([observer conformsToProtocol:self.protocol]); - if (ContainsValue(_observers, observer)) + if (base::ContainsValue(_observers, observer)) return; _observers.push_back(observer);
diff --git a/base/mac/scoped_nsobject_unittest.mm b/base/mac/scoped_nsobject_unittest.mm index cefb5fe..5694e68 100644 --- a/base/mac/scoped_nsobject_unittest.mm +++ b/base/mac/scoped_nsobject_unittest.mm
@@ -32,7 +32,10 @@ base::scoped_nsobject<NSObject> p3 = p1; ASSERT_EQ(p1.get(), p3.get()); ASSERT_EQ(2u, [p1 retainCount]); - p3 = p1; + { + base::mac::ScopedNSAutoreleasePool pool; + p3 = p1; + } ASSERT_EQ(p1.get(), p3.get()); ASSERT_EQ(2u, [p1 retainCount]); }
diff --git a/base/mac/scoped_nsobject_unittest_arc.mm b/base/mac/scoped_nsobject_unittest_arc.mm index e693488..1f69c56 100644 --- a/base/mac/scoped_nsobject_unittest_arc.mm +++ b/base/mac/scoped_nsobject_unittest_arc.mm
@@ -63,8 +63,8 @@ EXPECT_EQ(p1.get(), p3.get()); } EXPECT_EQ(2, GetRetainCount(p1)); - p3 = p1; @autoreleasepool { + p3 = p1; EXPECT_EQ(p1.get(), p3.get()); } EXPECT_EQ(2, GetRetainCount(p1));
diff --git a/base/memory/scoped_vector.h b/base/memory/scoped_vector.h index f3581ea..ebc2617 100644 --- a/base/memory/scoped_vector.h +++ b/base/memory/scoped_vector.h
@@ -89,7 +89,7 @@ // Resize, deleting elements in the disappearing range if we are shrinking. void resize(size_t new_size) { if (v_.size() > new_size) - STLDeleteContainerPointers(v_.begin() + new_size, v_.end()); + base::STLDeleteContainerPointers(v_.begin() + new_size, v_.end()); v_.resize(new_size); } @@ -98,7 +98,7 @@ v_.assign(begin, end); } - void clear() { STLDeleteElements(&v_); } + void clear() { base::STLDeleteElements(&v_); } // Like |clear()|, but doesn't delete any elements. void weak_clear() { v_.clear(); } @@ -124,7 +124,7 @@ } iterator erase(iterator first, iterator last) { - STLDeleteContainerPointers(first, last); + base::STLDeleteContainerPointers(first, last); return v_.erase(first, last); }
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc index 93b9d0a2..a9effec 100644 --- a/base/message_loop/message_loop.cc +++ b/base/message_loop/message_loop.cc
@@ -214,7 +214,7 @@ // TODO(rvargas): Get rid of the OS guards. #if defined(USE_GLIB) && !defined(OS_NACL) typedef MessagePumpGlib MessagePumpForUI; -#elif defined(OS_LINUX) && !defined(OS_NACL) +#elif (defined(OS_LINUX) && !defined(OS_NACL)) || defined(OS_BSD) typedef MessagePumpLibevent MessagePumpForUI; #endif @@ -418,21 +418,13 @@ unbound_task_runner_->BindToCurrentThread(); unbound_task_runner_ = nullptr; SetThreadTaskRunnerHandle(); - { - // Save the current thread's ID for potential use by other threads - // later from GetThreadName(). - thread_id_ = PlatformThread::CurrentId(); - subtle::MemoryBarrier(); - } + thread_id_ = PlatformThread::CurrentId(); } std::string MessageLoop::GetThreadName() const { - if (thread_id_ == kInvalidThreadId) { - // |thread_id_| may already have been initialized but this thread might not - // have received the update yet. - subtle::MemoryBarrier(); - DCHECK_NE(kInvalidThreadId, thread_id_); - } + DCHECK_NE(kInvalidThreadId, thread_id_) + << "GetThreadName() must only be called after BindToCurrentThread()'s " + << "side-effects have been synchronized with this thread."; return ThreadIdNameManager::GetInstance()->GetName(thread_id_); }
diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h index d8eae01..9b0a51df 100644 --- a/base/message_loop/message_loop.h +++ b/base/message_loop/message_loop.h
@@ -301,9 +301,11 @@ // Returns the type passed to the constructor. Type type() const { return type_; } - // Returns the name of the thread this message loop is bound to. - // This function is only valid when this message loop is running and - // BindToCurrentThread has already been called. + // Returns the name of the thread this message loop is bound to. This function + // is only valid when this message loop is running, BindToCurrentThread has + // already been called and has an "happens-before" relationship with this call + // (this relationship is obtained implicitly by the MessageLoop's task posting + // system unless calling this very early). std::string GetThreadName() const; // Gets the TaskRunner associated with this message loop. @@ -552,7 +554,8 @@ scoped_refptr<SingleThreadTaskRunner> task_runner_; std::unique_ptr<ThreadTaskRunnerHandle> thread_task_runner_handle_; - // Id of the thread this message loop is bound to. + // Id of the thread this message loop is bound to. Initialized once when the + // MessageLoop is bound to its thread and constant forever after. PlatformThreadId thread_id_; #if !(defined(OS_MACOSX) && !defined(OS_IOS))
diff --git a/base/scoped_observer.h b/base/scoped_observer.h index 13d7ca8..7f1d6fba 100644 --- a/base/scoped_observer.h +++ b/base/scoped_observer.h
@@ -47,7 +47,7 @@ } bool IsObserving(Source* source) const { - return ContainsValue(sources_, source); + return base::ContainsValue(sources_, source); } bool IsObservingSources() const { return !sources_.empty(); }
diff --git a/base/stl_util.h b/base/stl_util.h index 8882ac9..b7e9cfc9 100644 --- a/base/stl_util.h +++ b/base/stl_util.h
@@ -259,20 +259,4 @@ } // namespace base -// TODO(skyostil): Remove these global aliases once all call sites have been -// fixed. -using base::ContainsKey; -using base::ContainsValue; -using base::STLClearObject; -using base::STLCount; -using base::STLDeleteContainerPairFirstPointers; -using base::STLDeleteContainerPairPointers; -using base::STLDeleteContainerPairSecondPointers; -using base::STLDeleteContainerPointers; -using base::STLDeleteElements; -using base::STLDeleteValues; -using base::STLElementDeleter; -using base::STLValueDeleter; -using base::string_as_array; - #endif // BASE_STL_UTIL_H_
diff --git a/base/strings/utf_string_conversion_utils.h b/base/strings/utf_string_conversion_utils.h index c7164045..2d95870 100644 --- a/base/strings/utf_string_conversion_utils.h +++ b/base/strings/utf_string_conversion_utils.h
@@ -5,7 +5,8 @@ #ifndef BASE_STRINGS_UTF_STRING_CONVERSION_UTILS_H_ #define BASE_STRINGS_UTF_STRING_CONVERSION_UTILS_H_ -// This should only be used by the various UTF string conversion files. +// Low-level UTF handling functions. Most code will want to use the functions +// in utf_string_conversions.h #include <stddef.h> #include <stdint.h>
diff --git a/base/task_scheduler/scheduler_worker_pool_impl.cc b/base/task_scheduler/scheduler_worker_pool_impl.cc index e143d161..497db9c 100644 --- a/base/task_scheduler/scheduler_worker_pool_impl.cc +++ b/base/task_scheduler/scheduler_worker_pool_impl.cc
@@ -213,11 +213,14 @@ bool CanDetach(SchedulerWorker* worker) override; void RegisterSingleThreadTaskRunner() { - subtle::Barrier_AtomicIncrement(&num_single_threaded_runners_, 1); + // No barrier as barriers only affect sequential consistency which is + // irrelevant in a single variable use case (they don't force an immediate + // flush anymore than atomics do by default). + subtle::NoBarrier_AtomicIncrement(&num_single_threaded_runners_, 1); } void UnregisterSingleThreadTaskRunner() { - subtle::Barrier_AtomicIncrement(&num_single_threaded_runners_, -1); + subtle::NoBarrier_AtomicIncrement(&num_single_threaded_runners_, -1); } private: @@ -540,14 +543,14 @@ bool SchedulerWorkerPoolImpl::SchedulerWorkerDelegateImpl::CanDetach( SchedulerWorker* worker) { // It's not an issue if |num_single_threaded_runners_| is incremented after - // this because the newly created TaskRunner (from which no task has run yet) - // will simply run all its tasks on the next physical thread created by the - // worker. + // this because the newly created SingleThreadTaskRunner (from which no task + // has run yet) will simply run all its tasks on the next physical thread + // created by the worker. const bool can_detach = !idle_start_time_.is_null() && (TimeTicks::Now() - idle_start_time_) > outer_->suggested_reclaim_time_ && worker != outer_->PeekAtIdleWorkersStack() && - !subtle::Acquire_Load(&num_single_threaded_runners_) && + !subtle::NoBarrier_Load(&num_single_threaded_runners_) && outer_->CanWorkerDetachForTesting(); return can_detach; }
diff --git a/base/task_scheduler/task_tracker.cc b/base/task_scheduler/task_tracker.cc index 7de82bf..7c1c2489 100644 --- a/base/task_scheduler/task_tracker.cc +++ b/base/task_scheduler/task_tracker.cc
@@ -41,6 +41,10 @@ } // namespace +// Atomic internal state used by TaskTracker. Sequential consistency shouldn't +// be assumed from these calls (i.e. a thread reading +// |HasShutdownStarted() == true| isn't guaranteed to see all writes made before +// |StartShutdown()| on the thread that invoked it). class TaskTracker::State { public: State() = default; @@ -49,7 +53,7 @@ // tasks blocking shutdown. Can only be called once. bool StartShutdown() { const auto new_value = - subtle::Barrier_AtomicIncrement(&bits_, kShutdownHasStartedMask); + subtle::NoBarrier_AtomicIncrement(&bits_, kShutdownHasStartedMask); // Check that the "shutdown has started" bit isn't zero. This would happen // if it was incremented twice. @@ -62,13 +66,13 @@ // Returns true if shutdown has started. bool HasShutdownStarted() const { - return subtle::Acquire_Load(&bits_) & kShutdownHasStartedMask; + return subtle::NoBarrier_Load(&bits_) & kShutdownHasStartedMask; } // Returns true if there are tasks blocking shutdown. bool AreTasksBlockingShutdown() const { const auto num_tasks_blocking_shutdown = - subtle::Acquire_Load(&bits_) >> kNumTasksBlockingShutdownBitOffset; + subtle::NoBarrier_Load(&bits_) >> kNumTasksBlockingShutdownBitOffset; DCHECK_GE(num_tasks_blocking_shutdown, 0); return num_tasks_blocking_shutdown != 0; } @@ -79,13 +83,13 @@ #if DCHECK_IS_ON() // Verify that no overflow will occur. const auto num_tasks_blocking_shutdown = - subtle::Acquire_Load(&bits_) >> kNumTasksBlockingShutdownBitOffset; + subtle::NoBarrier_Load(&bits_) >> kNumTasksBlockingShutdownBitOffset; DCHECK_LT(num_tasks_blocking_shutdown, std::numeric_limits<subtle::Atomic32>::max() - kNumTasksBlockingShutdownIncrement); #endif - const auto new_bits = subtle::Barrier_AtomicIncrement( + const auto new_bits = subtle::NoBarrier_AtomicIncrement( &bits_, kNumTasksBlockingShutdownIncrement); return new_bits & kShutdownHasStartedMask; } @@ -93,7 +97,7 @@ // Decrements the number of tasks blocking shutdown. Returns true if shutdown // has started and the number of tasks blocking shutdown becomes zero. bool DecrementNumTasksBlockingShutdown() { - const auto new_bits = subtle::Barrier_AtomicIncrement( + const auto new_bits = subtle::NoBarrier_AtomicIncrement( &bits_, -kNumTasksBlockingShutdownIncrement); const bool shutdown_has_started = new_bits & kShutdownHasStartedMask; const auto num_tasks_blocking_shutdown = @@ -110,6 +114,15 @@ // The LSB indicates whether shutdown has started. The other bits count the // number of tasks blocking shutdown. + // No barriers are required to read/write |bits_| as this class is only used + // as an atomic state checker, it doesn't provide sequential consistency + // guarantees w.r.t. external state. Sequencing of the TaskTracker::State + // operations themselves is guaranteed by the AtomicIncrement RMW (read- + // modify-write) semantics however. For example, if two threads are racing to + // call IncrementNumTasksBlockingShutdown() and StartShutdown() respectively, + // either the first thread will win and the StartShutdown() call will see the + // blocking task or the second thread will win and + // IncrementNumTasksBlockingShutdown() will know that shutdown has started. subtle::Atomic32 bits_ = 0; DISALLOW_COPY_AND_ASSIGN(State);
diff --git a/base/task_scheduler/task_tracker.h b/base/task_scheduler/task_tracker.h index 80cc3c02..44309e5 100644 --- a/base/task_scheduler/task_tracker.h +++ b/base/task_scheduler/task_tracker.h
@@ -46,7 +46,9 @@ void RunNextTaskInSequence(const Sequence* sequence); // Returns true once shutdown has started (Shutdown() has been called but - // might not have returned). + // might not have returned). Note: sequential consistency with the thread + // calling Shutdown() (or SetHasShutdownStartedForTesting()) isn't guaranteed + // by this call. bool HasShutdownStarted() const; // Returns true if shutdown has completed (Shutdown() has returned).
diff --git a/base/threading/sequenced_worker_pool.cc b/base/threading/sequenced_worker_pool.cc index d8d10f34..ef6047e 100644 --- a/base/threading/sequenced_worker_pool.cc +++ b/base/threading/sequenced_worker_pool.cc
@@ -1220,12 +1220,6 @@ NULL)) {} SequencedWorkerPool::SequencedWorkerPool(size_t max_threads, - const std::string& thread_name_prefix) - : SequencedWorkerPool(max_threads, - thread_name_prefix, - base::TaskPriority::USER_VISIBLE) {} - -SequencedWorkerPool::SequencedWorkerPool(size_t max_threads, const std::string& thread_name_prefix, base::TaskPriority task_priority, TestingObserver* observer)
diff --git a/base/threading/sequenced_worker_pool.h b/base/threading/sequenced_worker_pool.h index 4d90f92..0a4e476b 100644 --- a/base/threading/sequenced_worker_pool.h +++ b/base/threading/sequenced_worker_pool.h
@@ -185,13 +185,6 @@ const std::string& thread_name_prefix, base::TaskPriority task_priority); - // Deprecated, use the above constructor with |task_priority| instead. - // TODO(gab): Cleanup last few use cases of this before running the - // aforementioned base::TaskScheduler experiment (or make sure this - // constructor results in callers being opted out of the experiment). - SequencedWorkerPool(size_t max_threads, - const std::string& thread_name_prefix); - // Like above, but with |observer| for testing. Does not take ownership of // |observer|. SequencedWorkerPool(size_t max_threads,
diff --git a/base/threading/simple_thread.cc b/base/threading/simple_thread.cc index 6c64a17d..bf8218c2 100644 --- a/base/threading/simple_thread.cc +++ b/base/threading/simple_thread.cc
@@ -12,53 +12,46 @@ namespace base { SimpleThread::SimpleThread(const std::string& name_prefix) - : name_prefix_(name_prefix), - name_(name_prefix), - thread_(), - event_(WaitableEvent::ResetPolicy::MANUAL, - WaitableEvent::InitialState::NOT_SIGNALED), - tid_(0), - joined_(false) {} + : SimpleThread(name_prefix, Options()) {} SimpleThread::SimpleThread(const std::string& name_prefix, const Options& options) : name_prefix_(name_prefix), name_(name_prefix), options_(options), - thread_(), event_(WaitableEvent::ResetPolicy::MANUAL, - WaitableEvent::InitialState::NOT_SIGNALED), - tid_(0), - joined_(false) {} + WaitableEvent::InitialState::NOT_SIGNALED) {} SimpleThread::~SimpleThread() { DCHECK(HasBeenStarted()) << "SimpleThread was never started."; - DCHECK(HasBeenJoined()) << "SimpleThread destroyed without being Join()ed."; + DCHECK(!options_.joinable || HasBeenJoined()) + << "Joinable SimpleThread destroyed without being Join()ed."; } void SimpleThread::Start() { DCHECK(!HasBeenStarted()) << "Tried to Start a thread multiple times."; - bool success; - if (options_.priority() == ThreadPriority::NORMAL) { - success = PlatformThread::Create(options_.stack_size(), this, &thread_); - } else { - success = PlatformThread::CreateWithPriority(options_.stack_size(), this, - &thread_, options_.priority()); - } + bool success = + options_.joinable + ? PlatformThread::CreateWithPriority(options_.stack_size, this, + &thread_, options_.priority) + : PlatformThread::CreateNonJoinableWithPriority( + options_.stack_size, this, options_.priority); DCHECK(success); - base::ThreadRestrictions::ScopedAllowWait allow_wait; + ThreadRestrictions::ScopedAllowWait allow_wait; event_.Wait(); // Wait for the thread to complete initialization. } void SimpleThread::Join() { + DCHECK(options_.joinable) << "A non-joinable thread can't be joined."; DCHECK(HasBeenStarted()) << "Tried to Join a never-started thread."; DCHECK(!HasBeenJoined()) << "Tried to Join a thread multiple times."; PlatformThread::Join(thread_); + thread_ = PlatformThreadHandle(); joined_ = true; } bool SimpleThread::HasBeenStarted() { - base::ThreadRestrictions::ScopedAllowWait allow_wait; + ThreadRestrictions::ScopedAllowWait allow_wait; return event_.IsSignaled(); } @@ -77,24 +70,26 @@ DelegateSimpleThread::DelegateSimpleThread(Delegate* delegate, const std::string& name_prefix) - : SimpleThread(name_prefix), - delegate_(delegate) { -} + : DelegateSimpleThread(delegate, name_prefix, Options()) {} DelegateSimpleThread::DelegateSimpleThread(Delegate* delegate, const std::string& name_prefix, const Options& options) : SimpleThread(name_prefix, options), delegate_(delegate) { + DCHECK(delegate_); } -DelegateSimpleThread::~DelegateSimpleThread() { -} +DelegateSimpleThread::~DelegateSimpleThread() = default; void DelegateSimpleThread::Run() { DCHECK(delegate_) << "Tried to call Run without a delegate (called twice?)"; - delegate_->Run(); - delegate_ = NULL; + + // Non-joinable DelegateSimpleThreads are allowed to be deleted during Run(). + // Member state must not be accessed after invoking Run(). + Delegate* delegate = delegate_; + delegate_ = nullptr; + delegate->Run(); } DelegateSimpleThreadPool::DelegateSimpleThreadPool(
diff --git a/base/threading/simple_thread.h b/base/threading/simple_thread.h index 3deeb10..fd29a1f 100644 --- a/base/threading/simple_thread.h +++ b/base/threading/simple_thread.h
@@ -48,6 +48,7 @@ #include "base/base_export.h" #include "base/compiler_specific.h" +#include "base/macros.h" #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" #include "base/threading/platform_thread.h" @@ -58,25 +59,26 @@ // virtual Run method, or you can use the DelegateSimpleThread interface. class BASE_EXPORT SimpleThread : public PlatformThread::Delegate { public: - class BASE_EXPORT Options { + struct BASE_EXPORT Options { public: - Options() : stack_size_(0), priority_(ThreadPriority::NORMAL) {} - explicit Options(ThreadPriority priority) - : stack_size_(0), priority_(priority) {} - ~Options() {} + Options() = default; + explicit Options(ThreadPriority priority_in) : priority(priority_in) {} + ~Options() = default; - // We use the standard compiler-supplied copy constructor. + // Allow copies. + Options(const Options& other) = default; + Options& operator=(const Options& other) = default; // A custom stack size, or 0 for the system default. - void set_stack_size(size_t size) { stack_size_ = size; } - size_t stack_size() const { return stack_size_; } + size_t stack_size = 0; - // A custom thread priority. - void set_priority(ThreadPriority priority) { priority_ = priority; } - ThreadPriority priority() const { return priority_; } - private: - size_t stack_size_; - ThreadPriority priority_; + ThreadPriority priority = ThreadPriority::NORMAL; + + // If false, the underlying thread's PlatformThreadHandle will not be kept + // around and as such the SimpleThread instance will not be Join()able and + // must not be deleted before Run() is invoked. After that, it's up to + // the subclass to determine when it is safe to delete itself. + bool joinable = true; }; // Create a SimpleThread. |options| should be used to manage any specific @@ -106,7 +108,7 @@ // Return True if Start() has ever been called. bool HasBeenStarted(); - // Return True if Join() has evern been called. + // Return True if Join() has ever been called. bool HasBeenJoined() { return joined_; } // Overridden from PlatformThread::Delegate: @@ -116,18 +118,24 @@ const std::string name_prefix_; std::string name_; const Options options_; - PlatformThreadHandle thread_; // PlatformThread handle, invalid after Join! + PlatformThreadHandle thread_; // PlatformThread handle, reset after Join. WaitableEvent event_; // Signaled if Start() was ever called. - PlatformThreadId tid_; // The backing thread's id. - bool joined_; // True if Join has been called. + PlatformThreadId tid_ = kInvalidThreadId; // The backing thread's id. + bool joined_ = false; // True if Join has been called. + + DISALLOW_COPY_AND_ASSIGN(SimpleThread); }; +// A SimpleThread which delegates Run() to its Delegate. Non-joinable +// DelegateSimpleThread are safe to delete after Run() was invoked, their +// Delegates are also safe to delete after that point from this class' point of +// view (although implementations must of course make sure that Run() will not +// use their Delegate's member state after its deletion). class BASE_EXPORT DelegateSimpleThread : public SimpleThread { public: class BASE_EXPORT Delegate { public: - Delegate() { } - virtual ~Delegate() { } + virtual ~Delegate() = default; virtual void Run() = 0; }; @@ -142,6 +150,8 @@ private: Delegate* delegate_; + + DISALLOW_COPY_AND_ASSIGN(DelegateSimpleThread); }; // DelegateSimpleThreadPool allows you to start up a fixed number of threads, @@ -186,6 +196,8 @@ std::queue<Delegate*> delegates_; base::Lock lock_; // Locks delegates_ WaitableEvent dry_; // Not signaled when there is no work to do. + + DISALLOW_COPY_AND_ASSIGN(DelegateSimpleThreadPool); }; } // namespace base
diff --git a/base/threading/simple_thread_unittest.cc b/base/threading/simple_thread_unittest.cc index 14dd459..97ebf80 100644 --- a/base/threading/simple_thread_unittest.cc +++ b/base/threading/simple_thread_unittest.cc
@@ -2,9 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <memory> + #include "base/atomic_sequence_num.h" +#include "base/memory/ptr_util.h" #include "base/strings/string_number_conversions.h" #include "base/synchronization/waitable_event.h" +#include "base/test/gtest_util.h" #include "base/threading/simple_thread.h" #include "testing/gtest/include/gtest/gtest.h" @@ -17,11 +21,49 @@ SetIntRunner(int* ptr, int val) : ptr_(ptr), val_(val) { } ~SetIntRunner() override {} + private: void Run() override { *ptr_ = val_; } - private: int* ptr_; int val_; + + DISALLOW_COPY_AND_ASSIGN(SetIntRunner); +}; + +// Signals |started_| when Run() is invoked and waits until |released_| is +// signaled to return, signaling |done_| before doing so. Useful for tests that +// care to control Run()'s flow. +class ControlledRunner : public DelegateSimpleThread::Delegate { + public: + ControlledRunner() + : started_(WaitableEvent::ResetPolicy::MANUAL, + WaitableEvent::InitialState::NOT_SIGNALED), + released_(WaitableEvent::ResetPolicy::MANUAL, + WaitableEvent::InitialState::NOT_SIGNALED), + done_(WaitableEvent::ResetPolicy::MANUAL, + WaitableEvent::InitialState::NOT_SIGNALED) {} + + ~ControlledRunner() override { ReleaseAndWaitUntilDone(); } + + void WaitUntilStarted() { started_.Wait(); } + + void ReleaseAndWaitUntilDone() { + released_.Signal(); + done_.Wait(); + } + + private: + void Run() override { + started_.Signal(); + released_.Wait(); + done_.Signal(); + } + + WaitableEvent started_; + WaitableEvent released_; + WaitableEvent done_; + + DISALLOW_COPY_AND_ASSIGN(ControlledRunner); }; class WaitEventRunner : public DelegateSimpleThread::Delegate { @@ -29,22 +71,28 @@ explicit WaitEventRunner(WaitableEvent* event) : event_(event) { } ~WaitEventRunner() override {} + private: void Run() override { EXPECT_FALSE(event_->IsSignaled()); event_->Signal(); EXPECT_TRUE(event_->IsSignaled()); } - private: + WaitableEvent* event_; + + DISALLOW_COPY_AND_ASSIGN(WaitEventRunner); }; class SeqRunner : public DelegateSimpleThread::Delegate { public: explicit SeqRunner(AtomicSequenceNumber* seq) : seq_(seq) { } - void Run() override { seq_->GetNext(); } private: + void Run() override { seq_->GetNext(); } + AtomicSequenceNumber* seq_; + + DISALLOW_COPY_AND_ASSIGN(SeqRunner); }; // We count up on a sequence number, firing on the event when we've hit our @@ -56,6 +104,7 @@ int total, WaitableEvent* event) : seq_(seq), total_(total), event_(event) { } + private: void Run() override { if (seq_->GetNext() == total_) { event_->Signal(); @@ -64,10 +113,11 @@ } } - private: AtomicSequenceNumber* seq_; int total_; WaitableEvent* event_; + + DISALLOW_COPY_AND_ASSIGN(VerifyPoolRunner); }; } // namespace @@ -133,6 +183,46 @@ std::string("event_waiter/") + IntToString(thread.tid())); } +TEST(SimpleThreadTest, NonJoinableStartAndDieOnJoin) { + ControlledRunner runner; + + SimpleThread::Options options; + options.joinable = false; + DelegateSimpleThread thread(&runner, "non_joinable", options); + + EXPECT_FALSE(thread.HasBeenStarted()); + thread.Start(); + EXPECT_TRUE(thread.HasBeenStarted()); + + // Note: this is not quite the same as |thread.HasBeenStarted()| which + // represents ThreadMain() getting ready to invoke Run() whereas + // |runner.WaitUntilStarted()| ensures Run() was actually invoked. + runner.WaitUntilStarted(); + + EXPECT_FALSE(thread.HasBeenJoined()); + EXPECT_DCHECK_DEATH({ thread.Join(); }); +} + +TEST(SimpleThreadTest, NonJoinableInactiveDelegateDestructionIsOkay) { + std::unique_ptr<ControlledRunner> runner(new ControlledRunner); + + SimpleThread::Options options; + options.joinable = false; + std::unique_ptr<DelegateSimpleThread> thread( + new DelegateSimpleThread(runner.get(), "non_joinable", options)); + + thread->Start(); + runner->WaitUntilStarted(); + + // Deleting a non-joinable SimpleThread after Run() was invoked is okay. + thread.reset(); + + runner->WaitUntilStarted(); + runner->ReleaseAndWaitUntilDone(); + // It should be safe to destroy a Delegate after its Run() method completed. + runner.reset(); +} + TEST(SimpleThreadTest, ThreadPool) { AtomicSequenceNumber seq; SeqRunner runner(&seq);
diff --git a/base/threading/thread_local_storage.cc b/base/threading/thread_local_storage.cc index a7eb5278..0ef31f74 100644 --- a/base/threading/thread_local_storage.cc +++ b/base/threading/thread_local_storage.cc
@@ -194,12 +194,6 @@ } // namespace internal -ThreadLocalStorage::Slot::Slot(TLSDestructorFunc destructor) { - slot_ = 0; - base::subtle::Release_Store(&initialized_, 0); - Initialize(destructor); -} - void ThreadLocalStorage::StaticSlot::Initialize(TLSDestructorFunc destructor) { PlatformThreadLocalStorage::TLSKey key = base::subtle::NoBarrier_Load(&g_native_tls_key); @@ -249,4 +243,20 @@ tls_data[slot_] = value; } +ThreadLocalStorage::Slot::Slot(TLSDestructorFunc destructor) { + tls_slot_.Initialize(destructor); +} + +ThreadLocalStorage::Slot::~Slot() { + tls_slot_.Free(); +} + +void* ThreadLocalStorage::Slot::Get() const { + return tls_slot_.Get(); +} + +void ThreadLocalStorage::Slot::Set(void* value) { + tls_slot_.Set(value); +} + } // namespace base
diff --git a/base/threading/thread_local_storage.h b/base/threading/thread_local_storage.h index 013b0ae..bc956a7 100644 --- a/base/threading/thread_local_storage.h +++ b/base/threading/thread_local_storage.h
@@ -127,14 +127,20 @@ // A convenience wrapper around StaticSlot with a constructor. Can be used // as a member variable. - class BASE_EXPORT Slot : public StaticSlot { + class BASE_EXPORT Slot { public: - // Calls StaticSlot::Initialize(). explicit Slot(TLSDestructorFunc destructor = NULL); + ~Slot(); + + // Get the thread-local value stored in this slot. + // Values are guaranteed to initially be zero. + void* Get() const; + + // Set the slot's thread-local value to |value|. + void Set(void* value); private: - using StaticSlot::initialized_; - using StaticSlot::slot_; + StaticSlot tls_slot_; DISALLOW_COPY_AND_ASSIGN(Slot); };
diff --git a/base/time/time.h b/base/time/time.h index be0eb20..b09cd9ef 100644 --- a/base/time/time.h +++ b/base/time/time.h
@@ -242,6 +242,11 @@ return delta_ >= other.delta_; } +#if defined(OS_WIN) + // This works around crbug.com/635974 + constexpr TimeDelta(const TimeDelta& other) : delta_(other.delta_) {} +#endif + private: friend int64_t time_internal::SaturatedAdd(TimeDelta delta, int64_t value); friend int64_t time_internal::SaturatedSub(TimeDelta delta, int64_t value);
diff --git a/base/time/time_win_unittest.cc b/base/time/time_win_unittest.cc index ad5e0be..17c72230 100644 --- a/base/time/time_win_unittest.cc +++ b/base/time/time_win_unittest.cc
@@ -19,6 +19,11 @@ namespace base { namespace { +// For TimeDelta::ConstexprInitialization +constexpr int kExpectedDeltaInMilliseconds = 10; +constexpr TimeDelta kConstexprTimeDelta = + TimeDelta::FromMilliseconds(kExpectedDeltaInMilliseconds); + class MockTimeTicks : public TimeTicks { public: static DWORD Ticker() { @@ -290,4 +295,9 @@ } } +TEST(TimeDelta, ConstexprInitialization) { + // Make sure that TimeDelta works around crbug.com/635974 + EXPECT_EQ(kExpectedDeltaInMilliseconds, kConstexprTimeDelta.InMilliseconds()); +} + } // namespace base
diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc index 7b7022c..872cd17 100644 --- a/base/trace_event/trace_log.cc +++ b/base/trace_event/trace_log.cc
@@ -1645,7 +1645,7 @@ process_sort_index_ = sort_index; } -void TraceLog::SetProcessName(const std::string& process_name) { +void TraceLog::SetProcessName(const char* process_name) { AutoLock lock(lock_); process_name_ = process_name; }
diff --git a/base/trace_event/trace_log.h b/base/trace_event/trace_log.h index e4407e8..468160d 100644 --- a/base/trace_event/trace_log.h +++ b/base/trace_event/trace_log.h
@@ -316,8 +316,9 @@ // on their sort index, ascending, then by their name, and then tid. void SetProcessSortIndex(int sort_index); - // Sets the name of the process. - void SetProcessName(const std::string& process_name); + // Sets the name of the process. |process_name| should be a string literal + // since it is a whitelisted argument for background field trials. + void SetProcessName(const char* process_name); // Processes can have labels in addition to their names. Use labels, for // instance, to list out the web page titles that a process is handling.
diff --git a/blimp/README.md b/blimp/README.md index 3ed48f9..7da0fc3 100644 --- a/blimp/README.md +++ b/blimp/README.md
@@ -21,3 +21,5 @@ ## New to Markdown? For learning more about Markdown, read more at [markdown](docs/markdown.md). +Also be sure to read the +[Google style guide for Markdown](https://github.com/google/styleguide/blob/gh-pages/docguide/style.md).
diff --git a/blimp/client/BUILD.gn b/blimp/client/BUILD.gn index 52e0fd9..8c536ea 100644 --- a/blimp/client/BUILD.gn +++ b/blimp/client/BUILD.gn
@@ -147,6 +147,8 @@ "feature/compositor/blimp_compositor_manager.h", "feature/compositor/blimp_context_provider.cc", "feature/compositor/blimp_context_provider.h", + "feature/compositor/blimp_delegating_output_surface.cc", + "feature/compositor/blimp_delegating_output_surface.h", "feature/compositor/blimp_gpu_memory_buffer_manager.cc", "feature/compositor/blimp_gpu_memory_buffer_manager.h", "feature/compositor/blimp_input_handler_wrapper.cc", @@ -165,6 +167,7 @@ "//blimp/net", "//cc", "//cc/proto", + "//cc/surfaces", "//gpu/command_buffer/client", "//gpu/command_buffer/client:gl_in_process_context", "//gpu/command_buffer/client:gles2_c_lib",
diff --git a/blimp/client/app/android/blimp_client_session_android.cc b/blimp/client/app/android/blimp_client_session_android.cc index 18e0f554..d1bfafc 100644 --- a/blimp/client/app/android/blimp_client_session_android.cc +++ b/blimp/client/app/android/blimp_client_session_android.cc
@@ -13,6 +13,7 @@ #include "blimp/client/core/contents/tab_control_feature.h" #include "blimp/client/core/session/assignment_source.h" #include "blimp/client/feature/settings_feature.h" +#include "blimp/net/blimp_stats.h" #include "components/version_info/version_info.h" #include "jni/BlimpClientSession_jni.h" #include "net/base/net_errors.h" @@ -122,11 +123,10 @@ BlimpClientSessionAndroid::GetDebugInfo( JNIEnv* env, const base::android::JavaParamRef<jobject>& jobj) { - BlimpConnectionStatistics* stats = - BlimpClientSession::GetBlimpConnectionStatistics(); - int metrics[] = {stats->Get(BlimpConnectionStatistics::BYTES_RECEIVED), - stats->Get(BlimpConnectionStatistics::BYTES_SENT), - stats->Get(BlimpConnectionStatistics::COMMIT)}; + BlimpStats* stats = BlimpStats::GetInstance(); + int metrics[] = {stats->Get(BlimpStats::BYTES_RECEIVED), + stats->Get(BlimpStats::BYTES_SENT), + stats->Get(BlimpStats::COMMIT)}; return base::android::ToJavaIntArray(env, metrics, arraysize(metrics)); }
diff --git a/blimp/client/app/android/blimp_view.cc b/blimp/client/app/android/blimp_view.cc index 013c791..a2c84218 100644 --- a/blimp/client/app/android/blimp_view.cc +++ b/blimp/client/app/android/blimp_view.cc
@@ -7,6 +7,7 @@ #include <android/native_window_jni.h> #include "blimp/client/app/android/blimp_client_session_android.h" +#include "blimp/net/blimp_stats.h" #include "jni/BlimpView_jni.h" #include "ui/events/android/motion_event_android.h" #include "ui/gfx/geometry/size.h" @@ -34,8 +35,7 @@ return reinterpret_cast<intptr_t>(new BlimpView( env, jobj, gfx::Size(real_width, real_height), gfx::Size(width, height), - dp_to_px, client_session->GetRenderWidgetFeature(), - client_session->GetBlimpConnectionStatistics())); + dp_to_px, client_session->GetRenderWidgetFeature())); } // static @@ -48,8 +48,7 @@ const gfx::Size& real_size, const gfx::Size& size, float dp_to_px, - RenderWidgetFeature* render_widget_feature, - BlimpConnectionStatistics* blimp_connection_statistics) + RenderWidgetFeature* render_widget_feature) : device_scale_factor_(dp_to_px), compositor_manager_( BlimpCompositorManagerAndroid::Create(real_size, @@ -57,8 +56,7 @@ render_widget_feature, this)), current_surface_format_(0), - window_(gfx::kNullAcceleratedWidget), - blimp_connection_statistics_(blimp_connection_statistics) { + window_(gfx::kNullAcceleratedWidget) { java_obj_.Reset(env, jobj); } @@ -186,8 +184,7 @@ } void BlimpView::DidCommitAndDrawFrame() { - DCHECK(blimp_connection_statistics_); - blimp_connection_statistics_->Add(BlimpConnectionStatistics::COMMIT, 1); + BlimpStats::GetInstance()->Add(BlimpStats::COMMIT, 1); } } // namespace client
diff --git a/blimp/client/app/android/blimp_view.h b/blimp/client/app/android/blimp_view.h index 8bab0f3..fa60dec5 100644 --- a/blimp/client/app/android/blimp_view.h +++ b/blimp/client/app/android/blimp_view.h
@@ -17,8 +17,6 @@ } namespace blimp { -class BlimpConnectionStatistics; - namespace client { class RenderWidgetFeature; @@ -40,8 +38,7 @@ const gfx::Size& real_size, const gfx::Size& size, float dp_to_px, - RenderWidgetFeature* render_widget_feature, - BlimpConnectionStatistics* blimp_connection_statistics); + RenderWidgetFeature* render_widget_feature); // Methods called from Java via JNI. void Destroy(JNIEnv* env, const base::android::JavaParamRef<jobject>& jobj); @@ -112,8 +109,6 @@ gfx::AcceleratedWidget window_; - BlimpConnectionStatistics* blimp_connection_statistics_; - DISALLOW_COPY_AND_ASSIGN(BlimpView); };
diff --git a/blimp/client/app/blimp_discardable_memory_allocator.cc b/blimp/client/app/blimp_discardable_memory_allocator.cc index fecbf750..1b06143 100644 --- a/blimp/client/app/blimp_discardable_memory_allocator.cc +++ b/blimp/client/app/blimp_discardable_memory_allocator.cc
@@ -117,7 +117,7 @@ BlimpDiscardableMemoryAllocator::~BlimpDiscardableMemoryAllocator() { DCHECK_EQ(0, locked_chunks_); - STLDeleteElements(&live_unlocked_chunks_); + base::STLDeleteElements(&live_unlocked_chunks_); } std::unique_ptr<base::DiscardableMemory>
diff --git a/blimp/client/core/blimp_client_context_impl.cc b/blimp/client/core/blimp_client_context_impl.cc index 289602a..f90b1dc02 100644 --- a/blimp/client/core/blimp_client_context_impl.cc +++ b/blimp/client/core/blimp_client_context_impl.cc
@@ -50,11 +50,9 @@ file_thread_task_runner_(file_thread_task_runner), blimp_contents_manager_(new BlimpContentsManager), weak_factory_(this) { - blimp_connection_statistics_ = new BlimpConnectionStatistics(); net_components_.reset(new ClientNetworkComponents( base::MakeUnique<CrossThreadNetworkEventObserver>( - weak_factory_.GetWeakPtr(), base::SequencedTaskRunnerHandle::Get()), - base::WrapUnique(blimp_connection_statistics_))); + weak_factory_.GetWeakPtr(), base::SequencedTaskRunnerHandle::Get()))); // The |thread_pipe_manager_| must be set up correctly before features are // registered.
diff --git a/blimp/client/core/blimp_client_context_impl.h b/blimp/client/core/blimp_client_context_impl.h index dfc184b..86c3cc8 100644 --- a/blimp/client/core/blimp_client_context_impl.h +++ b/blimp/client/core/blimp_client_context_impl.h
@@ -17,7 +17,6 @@ #include "blimp/client/public/blimp_client_context.h" #include "blimp/client/public/contents/blimp_contents.h" #include "blimp/client/public/session/assignment.h" -#include "blimp/net/blimp_connection_statistics.h" #include "blimp/net/thread_pipe_manager.h" #include "url/gurl.h" @@ -73,10 +72,6 @@ // Connect() to get a valid assignment and later connect to the engine. std::unique_ptr<AssignmentSource> assignment_source_; - // Collects details of network, such as number of commits and bytes - // transferred over network. Owned by ClientNetworkComponents. - BlimpConnectionStatistics* blimp_connection_statistics_; - std::unique_ptr<BlimpContentsManager> blimp_contents_manager_; // Container struct for network components.
diff --git a/blimp/client/core/session/client_network_components.cc b/blimp/client/core/session/client_network_components.cc index 32deafd7..effa4ba2 100644 --- a/blimp/client/core/session/client_network_components.cc +++ b/blimp/client/core/session/client_network_components.cc
@@ -4,6 +4,8 @@ #include "blimp/client/core/session/client_network_components.h" +#include <utility> + #include "base/logging.h" #include "base/memory/ptr_util.h" #include "blimp/net/ssl_client_transport.h" @@ -13,13 +15,8 @@ namespace client { ClientNetworkComponents::ClientNetworkComponents( - std::unique_ptr<NetworkEventObserver> network_observer, - std::unique_ptr<BlimpConnectionStatistics> statistics) - : connection_handler_(), - network_observer_(std::move(network_observer)), - connection_statistics_(std::move(statistics)) { - DCHECK(connection_statistics_); -} + std::unique_ptr<NetworkEventObserver> network_observer) + : connection_handler_(), network_observer_(std::move(network_observer)) {} ClientNetworkComponents::~ClientNetworkComponents() { DCHECK(io_thread_checker_.CalledOnValidThread()); @@ -42,13 +39,12 @@ case Assignment::SSL: DCHECK(assignment.cert); connection_manager_->AddTransport(base::MakeUnique<SSLClientTransport>( - assignment.engine_endpoint, std::move(assignment.cert), - connection_statistics_.get(), nullptr)); + assignment.engine_endpoint, std::move(assignment.cert), nullptr)); transport_type = "SSL"; break; case Assignment::TCP: connection_manager_->AddTransport(base::MakeUnique<TCPClientTransport>( - assignment.engine_endpoint, connection_statistics_.get(), nullptr)); + assignment.engine_endpoint, nullptr)); transport_type = "TCP"; break; case Assignment::UNKNOWN:
diff --git a/blimp/client/core/session/client_network_components.h b/blimp/client/core/session/client_network_components.h index bae00bc..d77ab0b 100644 --- a/blimp/client/core/session/client_network_components.h +++ b/blimp/client/core/session/client_network_components.h
@@ -11,7 +11,6 @@ #include "blimp/client/core/session/assignment_source.h" #include "blimp/client/core/session/network_event_observer.h" #include "blimp/net/blimp_connection.h" -#include "blimp/net/blimp_connection_statistics.h" #include "blimp/net/browser_connection_handler.h" #include "blimp/net/client_connection_manager.h" @@ -25,9 +24,8 @@ public ConnectionErrorObserver { public: // Can be created on any thread. - ClientNetworkComponents( - std::unique_ptr<NetworkEventObserver> observer, - std::unique_ptr<BlimpConnectionStatistics> blimp_connection_statistics); + explicit ClientNetworkComponents( + std::unique_ptr<NetworkEventObserver> observer); ~ClientNetworkComponents() override; // Sets up network components. @@ -52,7 +50,6 @@ BrowserConnectionHandler connection_handler_; std::unique_ptr<ClientConnectionManager> connection_manager_; std::unique_ptr<NetworkEventObserver> network_observer_; - std::unique_ptr<BlimpConnectionStatistics> connection_statistics_; DISALLOW_COPY_AND_ASSIGN(ClientNetworkComponents); };
diff --git a/blimp/client/feature/compositor/blimp_compositor.cc b/blimp/client/feature/compositor/blimp_compositor.cc index edc742c..d1e3688 100644 --- a/blimp/client/feature/compositor/blimp_compositor.cc +++ b/blimp/client/feature/compositor/blimp_compositor.cc
@@ -14,6 +14,7 @@ #include "base/threading/thread_restrictions.h" #include "base/threading/thread_task_runner_handle.h" #include "blimp/client/feature/compositor/blimp_context_provider.h" +#include "blimp/client/feature/compositor/blimp_delegating_output_surface.h" #include "blimp/client/feature/compositor/blimp_output_surface.h" #include "cc/animation/animation_host.h" #include "cc/layers/layer.h" @@ -255,12 +256,30 @@ if (!host_->visible() || window_ == gfx::kNullAcceleratedWidget) return; - scoped_refptr<BlimpContextProvider> context_provider = + scoped_refptr<BlimpContextProvider> display_context_provider = BlimpContextProvider::Create(window_, client_->GetGpuMemoryBufferManager()); + scoped_refptr<BlimpContextProvider> compositor_context_provider = + BlimpContextProvider::Create(gfx::kNullAcceleratedWidget, + client_->GetGpuMemoryBufferManager()); + scoped_refptr<BlimpContextProvider> worker_context_provider = nullptr; + // TODO(khushalsagar): Make a worker context and bind it to the current + // thread: + // Worker context is bound to the main thread in RenderThreadImpl. One day + // that will change and then this will have to be removed. + // worker_context_provider->BindToCurrentThread(); - host_->SetOutputSurface( - base::WrapUnique(new BlimpOutputSurface(context_provider))); + auto display_output_surface = + base::MakeUnique<BlimpOutputSurface>(std::move(display_context_provider)); + auto delegating_output_surface = + base::MakeUnique<BlimpDelegatingOutputSurface>( + std::move(compositor_context_provider), + std::move(worker_context_provider), std::move(display_output_surface), + client_->GetGpuMemoryBufferManager(), + host_->settings().renderer_settings, + client_->GetCompositorTaskRunner().get()); + + host_->SetOutputSurface(std::move(delegating_output_surface)); output_surface_request_pending_ = false; }
diff --git a/blimp/client/feature/compositor/blimp_compositor_manager.cc b/blimp/client/feature/compositor/blimp_compositor_manager.cc index 42105fc..81edc48 100644 --- a/blimp/client/feature/compositor/blimp_compositor_manager.cc +++ b/blimp/client/feature/compositor/blimp_compositor_manager.cc
@@ -135,6 +135,7 @@ ->abort_commit_before_output_surface_creation = false; settings_->renderer_settings.buffer_to_texture_target_map = BlimpGpuMemoryBufferManager::GetDefaultBufferToTextureTargetMap(); + settings_->use_output_surface_begin_frame_source = true; } return settings_.get();
diff --git a/blimp/client/feature/compositor/blimp_context_provider.cc b/blimp/client/feature/compositor/blimp_context_provider.cc index a87aeef5..8c68d7b 100644 --- a/blimp/client/feature/compositor/blimp_context_provider.cc +++ b/blimp/client/feature/compositor/blimp_context_provider.cc
@@ -42,10 +42,10 @@ attribs_for_gles2.lose_context_when_out_of_memory = true; context_.reset(gpu::GLInProcessContext::Create( - nullptr /* service */, nullptr /* surface */, false /* is_offscreen */, - widget, nullptr /* share_context */, attribs_for_gles2, - gpu::SharedMemoryLimits(), gpu_memory_buffer_manager, - nullptr /* memory_limits */)); + nullptr /* service */, nullptr /* surface */, + widget == gfx::kNullAcceleratedWidget /* is_offscreen */, widget, + nullptr /* share_context */, attribs_for_gles2, gpu::SharedMemoryLimits(), + gpu_memory_buffer_manager, nullptr /* memory_limits */)); context_->GetImplementation()->SetLostContextCallback( base::Bind(&BlimpContextProvider::OnLostContext, base::Unretained(this))); }
diff --git a/blimp/client/feature/compositor/blimp_delegating_output_surface.cc b/blimp/client/feature/compositor/blimp_delegating_output_surface.cc new file mode 100644 index 0000000..98a1213 --- /dev/null +++ b/blimp/client/feature/compositor/blimp_delegating_output_surface.cc
@@ -0,0 +1,132 @@ +// Copyright 2016 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 "blimp/client/feature/compositor/blimp_delegating_output_surface.h" + +#include <stdint.h> +#include <utility> + +#include "cc/output/texture_mailbox_deleter.h" + +static constexpr uint32_t kCompositorClientId = 1; + +namespace blimp { +namespace client { + +BlimpDelegatingOutputSurface::BlimpDelegatingOutputSurface( + scoped_refptr<cc::ContextProvider> compositor_context_provider, + scoped_refptr<cc::ContextProvider> worker_context_provider, + std::unique_ptr<cc::OutputSurface> display_output_surface, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, + const cc::RendererSettings& renderer_settings, + base::SingleThreadTaskRunner* task_runner) + : cc::OutputSurface(std::move(compositor_context_provider), + std::move(worker_context_provider), + nullptr), + surface_manager_(new cc::SurfaceManager), + surface_id_allocator_(new cc::SurfaceIdAllocator(kCompositorClientId)), + surface_factory_(new cc::SurfaceFactory(surface_manager_.get(), this)) { + std::unique_ptr<cc::SyntheticBeginFrameSource> begin_frame_source( + new cc::DelayBasedBeginFrameSource( + base::MakeUnique<cc::DelayBasedTimeSource>(task_runner))); + std::unique_ptr<cc::DisplayScheduler> scheduler(new cc::DisplayScheduler( + begin_frame_source.get(), task_runner, + display_output_surface->capabilities().max_frames_pending)); + display_.reset(new cc::Display( + nullptr /*shared_bitmap_manager*/, gpu_memory_buffer_manager, + renderer_settings, std::move(begin_frame_source), + std::move(display_output_surface), std::move(scheduler), + base::MakeUnique<cc::TextureMailboxDeleter>(task_runner))); + + capabilities_.delegated_rendering = true; +} + +BlimpDelegatingOutputSurface::~BlimpDelegatingOutputSurface() = default; + +bool BlimpDelegatingOutputSurface::BindToClient( + cc::OutputSurfaceClient* client) { + bool bound = cc::OutputSurface::BindToClient(client); + DCHECK(bound); // No support for failing to set up the context. + + surface_manager_->RegisterSurfaceClientId(surface_id_allocator_->client_id()); + surface_manager_->RegisterSurfaceFactoryClient( + surface_id_allocator_->client_id(), this); + display_->Initialize(this, surface_manager_.get(), + surface_id_allocator_->client_id()); + // TODO(danakj): Do this when https://codereview.chromium.org/2238693002/ . + // display_->SetVisible(true); + return true; +} + +void BlimpDelegatingOutputSurface::DetachFromClient() { + if (!delegated_surface_id_.is_null()) + surface_factory_->Destroy(delegated_surface_id_); + surface_manager_->UnregisterSurfaceFactoryClient( + surface_id_allocator_->client_id()); + surface_manager_->InvalidateSurfaceClientId( + surface_id_allocator_->client_id()); + display_ = nullptr; + surface_factory_ = nullptr; + surface_id_allocator_ = nullptr; + surface_manager_ = nullptr; + cc::OutputSurface::DetachFromClient(); +} + +void BlimpDelegatingOutputSurface::SwapBuffers(cc::CompositorFrame frame) { + if (delegated_surface_id_.is_null()) { + delegated_surface_id_ = surface_id_allocator_->GenerateId(); + surface_factory_->Create(delegated_surface_id_); + } + display_->SetSurfaceId(delegated_surface_id_, + frame.metadata.device_scale_factor); + + gfx::Size frame_size = + frame.delegated_frame_data->render_pass_list.back()->output_rect.size(); + display_->Resize(frame_size); + + surface_factory_->SubmitCompositorFrame(delegated_surface_id_, + std::move(frame), base::Closure()); + cc::OutputSurface::PostSwapBuffersComplete(); +} + +void BlimpDelegatingOutputSurface::ForceReclaimResources() {} + +void BlimpDelegatingOutputSurface::BindFramebuffer() { + // This is a delegating output surface, no framebuffer/direct drawing support. + NOTREACHED(); +} + +uint32_t BlimpDelegatingOutputSurface::GetFramebufferCopyTextureFormat() { + // This is a delegating output surface, no framebuffer/direct drawing support. + NOTREACHED(); + return 0; +} + +void BlimpDelegatingOutputSurface::ReturnResources( + const cc::ReturnedResourceArray& resources) { + client_->ReclaimResources(resources); +} + +void BlimpDelegatingOutputSurface::SetBeginFrameSource( + cc::BeginFrameSource* begin_frame_source) { + client_->SetBeginFrameSource(begin_frame_source); +} + +void BlimpDelegatingOutputSurface::DisplayOutputSurfaceLost() { + DidLoseOutputSurface(); +} + +void BlimpDelegatingOutputSurface::DisplaySetMemoryPolicy( + const cc::ManagedMemoryPolicy& policy) { + SetMemoryPolicy(policy); +} + +void BlimpDelegatingOutputSurface::DisplayWillDrawAndSwap( + bool will_draw_and_swap, + const cc::RenderPassList& render_passes) {} + +void BlimpDelegatingOutputSurface::DisplayDidDrawAndSwap() {} + +} // namespace client +} // namespace blimp
diff --git a/blimp/client/feature/compositor/blimp_delegating_output_surface.h b/blimp/client/feature/compositor/blimp_delegating_output_surface.h new file mode 100644 index 0000000..7a1cd69d7 --- /dev/null +++ b/blimp/client/feature/compositor/blimp_delegating_output_surface.h
@@ -0,0 +1,71 @@ +// Copyright 2016 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 BLIMP_CLIENT_FEATURE_COMPOSITOR_BLIMP_DELEGATING_OUTPUT_SURFACE_H_ +#define BLIMP_CLIENT_FEATURE_COMPOSITOR_BLIMP_DELEGATING_OUTPUT_SURFACE_H_ + +#include "cc/output/output_surface.h" +#include "cc/output/renderer_settings.h" +#include "cc/scheduler/begin_frame_source.h" +#include "cc/surfaces/display.h" +#include "cc/surfaces/display_client.h" +#include "cc/surfaces/surface_factory.h" +#include "cc/surfaces/surface_factory_client.h" +#include "cc/surfaces/surface_id_allocator.h" +#include "cc/surfaces/surface_manager.h" + +namespace blimp { +namespace client { + +// Delegating output surface that owns and forwards frames to a Display. +class BlimpDelegatingOutputSurface : public cc::OutputSurface, + public cc::SurfaceFactoryClient, + public cc::DisplayClient { + public: + BlimpDelegatingOutputSurface( + scoped_refptr<cc::ContextProvider> compositor_context_provider, + scoped_refptr<cc::ContextProvider> worker_context_provider, + std::unique_ptr<cc::OutputSurface> display_output_surface, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, + const cc::RendererSettings& renderer_settings, + base::SingleThreadTaskRunner* task_runner); + ~BlimpDelegatingOutputSurface() override; + + // OutputSurface implementation. + bool BindToClient(cc::OutputSurfaceClient* client) override; + void DetachFromClient() override; + void SwapBuffers(cc::CompositorFrame frame) override; + void ForceReclaimResources() override; + void BindFramebuffer() override; + uint32_t GetFramebufferCopyTextureFormat() override; + + // SurfaceFactoryClient implementation. + void ReturnResources(const cc::ReturnedResourceArray& resources) override; + void SetBeginFrameSource(cc::BeginFrameSource* begin_frame_source) override; + + // DisplayClient implementation. + void DisplayOutputSurfaceLost() override; + void DisplaySetMemoryPolicy(const cc::ManagedMemoryPolicy& policy) override; + void DisplayWillDrawAndSwap(bool will_draw_and_swap, + const cc::RenderPassList& render_passes) override; + void DisplayDidDrawAndSwap() override; + + private: + // TODO(danakj): These don't need to be stored in unique_ptrs when + // OutputSurface is owned/destroyed on the compositor thread. + std::unique_ptr<cc::SurfaceManager> surface_manager_; + std::unique_ptr<cc::SurfaceIdAllocator> surface_id_allocator_; + cc::SurfaceId delegated_surface_id_; + + // Uses surface_manager_. + std::unique_ptr<cc::SurfaceFactory> surface_factory_; + + // Uses surface_manager_. + std::unique_ptr<cc::Display> display_; +}; + +} // namespace client +} // namespace blimp + +#endif // BLIMP_CLIENT_FEATURE_COMPOSITOR_BLIMP_DELEGATING_OUTPUT_SURFACE_H_
diff --git a/blimp/client/session/blimp_client_session.cc b/blimp/client/session/blimp_client_session.cc index 65dbad9..d20654f 100644 --- a/blimp/client/session/blimp_client_session.cc +++ b/blimp/client/session/blimp_client_session.cc
@@ -4,6 +4,7 @@ #include "blimp/client/session/blimp_client_session.h" +#include <utility> #include <vector> #include "base/bind.h" @@ -25,6 +26,7 @@ #include "blimp/client/feature/settings_feature.h" #include "blimp/common/blob_cache/in_memory_blob_cache.h" #include "blimp/net/blimp_message_thread_pipe.h" +#include "blimp/net/blimp_stats.h" #include "blimp/net/blob_channel/blob_channel_receiver.h" #include "blimp/net/blob_channel/helium_blob_receiver_delegate.h" #include "blimp/net/thread_pipe_manager.h" @@ -44,11 +46,10 @@ base::Thread::Options options; options.message_loop_type = base::MessageLoop::TYPE_IO; io_thread_.StartWithOptions(options); - blimp_connection_statistics_ = new BlimpConnectionStatistics(); net_components_.reset(new ClientNetworkComponents( base::WrapUnique(new CrossThreadNetworkEventObserver( - weak_factory_.GetWeakPtr(), base::SequencedTaskRunnerHandle::Get())), - base::WrapUnique(blimp_connection_statistics_))); + weak_factory_.GetWeakPtr(), + base::SequencedTaskRunnerHandle::Get())))); assignment_source_.reset(new AssignmentSource( assigner_endpoint, io_thread_.task_runner(), io_thread_.task_runner())); @@ -173,10 +174,5 @@ return settings_feature_.get(); } -BlimpConnectionStatistics* BlimpClientSession::GetBlimpConnectionStatistics() - const { - return blimp_connection_statistics_; -} - } // namespace client } // namespace blimp
diff --git a/blimp/client/session/blimp_client_session.h b/blimp/client/session/blimp_client_session.h index 10951470c..aaccdd8 100644 --- a/blimp/client/session/blimp_client_session.h +++ b/blimp/client/session/blimp_client_session.h
@@ -17,7 +17,6 @@ #include "blimp/client/core/session/network_event_observer.h" #include "blimp/client/public/session/assignment.h" #include "blimp/common/proto/blimp_message.pb.h" -#include "blimp/net/blimp_connection_statistics.h" #include "blimp/net/blimp_message_processor.h" namespace net { @@ -70,8 +69,6 @@ RenderWidgetFeature* GetRenderWidgetFeature() const; SettingsFeature* GetSettingsFeature() const; - BlimpConnectionStatistics* GetBlimpConnectionStatistics() const; - // The AssignmentCallback for when an assignment is ready. This will trigger // a connection to the engine. virtual void ConnectWithAssignment(AssignmentRequestResult result, @@ -116,10 +113,6 @@ // Connect() to get a valid assignment and later connect to the engine. std::unique_ptr<AssignmentSource> assignment_source_; - // Collects details of network, such as number of commits and bytes - // transferred over network. Ownership is maintained on the IO thread. - BlimpConnectionStatistics* blimp_connection_statistics_; - // Container struct for network components. // Must be deleted on the IO thread. std::unique_ptr<ClientNetworkComponents> net_components_;
diff --git a/blimp/docs/container.md b/blimp/docs/container.md index 57218a4a..8f10c8c3 100644 --- a/blimp/docs/container.md +++ b/blimp/docs/container.md
@@ -58,7 +58,7 @@ Using the tarfile you can create a Docker image: ```bash -docker build -f Dockerfile.base -t base - < ./out-linux/Debug/blimp_engine_bundle.tar.gz +docker build -t base - < ./blimp/tools/Dockerfile.base docker build -t blimp_engine - < ./out-linux/Debug/blimp_engine_bundle.tar.gz ```
diff --git a/blimp/docs/fonts.md b/blimp/docs/fonts.md index 379a5df..a133007 100644 --- a/blimp/docs/fonts.md +++ b/blimp/docs/fonts.md
@@ -9,9 +9,6 @@ licenses and which fonts use which license. 1. Update the `//third_party/blimp_fonts` target to include all the current fonts and their license files. -1. Update the engine dependencies using - `//blimp/tools/generate-engine-manifest.py`. This step is documented in - `//blimp/docs/container.md`. 1. Run the `upload_to_google_storage.py` (from depot_tools) script to upload the files. You must do this in the `//third_party/blimp_fonts` directory. To do this, execute:
diff --git a/blimp/docs/running.md b/blimp/docs/running.md index da74e26..76118fe 100644 --- a/blimp/docs/running.md +++ b/blimp/docs/running.md
@@ -163,7 +163,10 @@ * `--disable-cached-picture-raster`: Ensures that rasterized content is not destroyed before serialization. * `--android-fonts-path=$PATH`: Path to where the fonts are located. - Typically this would be `out-linux/Debug/gen/third_party/blimp_fonts`. + If the Android client is Kitkat system, this would be + `out-linux/Debug/gen/third_party/blimp_fonts/font_bundle/kitkat/`. + If the Android client is Marshmallow system, this would be + `out-linux/Debug/gen/third_party/blimp_fonts/font_bundle/marshmallow/`. * `--disable-remote-fonts`: Disables downloading of custom web fonts in the renderer. @@ -173,8 +176,74 @@ ```bash out-linux/Debug/blimp_engine_app \ - --android-fonts-path=out-linux/Debug/gen/third_party/blimp_fonts \ + --android-fonts-path=out-linux/Debug/gen/third_party/blimp_fonts/font_bundle/marshmallow/ \ --blimp-client-token-path=/tmp/blimpengine-token \ --enable-logging=stderr \ --vmodule="blimp*=1" ``` + +## Running client engine integration with script + +When building the target `blimp` on a Linux host, a script is created which +automates running the Blimp client and starting the engine. Setting up the +environment like this is much quicker than executing each of the steps +separately. It is used for development purpose as well as running tests under +integration environment. + +### Generate the script + +The script is wrapped as an command `client_engine_integration` and ends up in +`out-linux/Debug/bin/` which is generated with building engine. Command should be with +the positional argument `{start,run,load,stop}`. + +### Running the script + +One can use the script to set up engine and connect it with client, then start client. + +#### Option A + +1. `{start}` Start engine & forwarder: + + ```bash + out-linux/Debug/bin/client_engine_integration start + ``` + + Engine runs until when you run the script with `{stop}` as the positional argument. + +2. After engine starting successfully, run `{load}` client which installs apk in + device and runs blimp. + + ```bash + out-linux/Debug/bin/client_engine_integration load -p/--apk-path /path/to/apk + ``` + + You are now ready to run tests or do development. + + Instead of `{load}`, if want to manually install/launch the client can also do + e.g. the incremental install: + + ```bash + ninja -C out-android/Debug blimp && \ + out-android/Debug/bin/install_blimp_apk_incremental + ``` + +3. `{stop}` Stops the engine & the forwarder: + + ```bash + out-linux/Debug/bin/client_engine_integration stop + ``` + +#### Option B + +1. `{run}` Start and keep running engine & forwarder. + Script keeps running and auto-checking engine process. Is responsible for + killing engine if keyboard interrupts or client gets killed. + + ```bash + out-linux/Debug/bin/client_engine_integration run + ``` + +2. Same as step 2 in Option A. + +3. Engine should be auto-killed by keyboard stopping the `{run}` script or the client + gets wiped out. `{stop}` works as well.
diff --git a/blimp/engine/session/blimp_engine_session.cc b/blimp/engine/session/blimp_engine_session.cc index 6277723df..55c1b10 100644 --- a/blimp/engine/session/blimp_engine_session.cc +++ b/blimp/engine/session/blimp_engine_session.cc
@@ -27,9 +27,9 @@ #include "blimp/engine/common/blimp_user_agent.h" #include "blimp/engine/session/tab.h" #include "blimp/net/blimp_connection.h" -#include "blimp/net/blimp_connection_statistics.h" #include "blimp/net/blimp_message_multiplexer.h" #include "blimp/net/blimp_message_thread_pipe.h" +#include "blimp/net/blimp_stats.h" #include "blimp/net/blob_channel/blob_channel_sender_impl.h" #include "blimp/net/blob_channel/helium_blob_sender_delegate.h" #include "blimp/net/browser_connection_handler.h" @@ -157,7 +157,6 @@ std::unique_ptr<BrowserConnectionHandler> connection_handler_; std::unique_ptr<EngineAuthenticationHandler> authentication_handler_; std::unique_ptr<EngineConnectionManager> connection_manager_; - BlimpConnectionStatistics blimp_connection_statistics_; DISALLOW_COPY_AND_ASSIGN(EngineNetworkComponents); }; @@ -187,8 +186,7 @@ // Adds BlimpTransports to connection_manager_. net::IPEndPoint address(GetIPv4AnyAddress(), GetListeningPort()); - TCPEngineTransport* transport = - new TCPEngineTransport(address, &blimp_connection_statistics_, net_log_); + TCPEngineTransport* transport = new TCPEngineTransport(address, net_log_); connection_manager_->AddTransport(base::WrapUnique(transport)); transport->GetLocalAddress(&address);
diff --git a/blimp/net/BUILD.gn b/blimp/net/BUILD.gn index 9769866..9a45caa4d 100644 --- a/blimp/net/BUILD.gn +++ b/blimp/net/BUILD.gn
@@ -7,8 +7,6 @@ sources = [ "blimp_connection.cc", "blimp_connection.h", - "blimp_connection_statistics.cc", - "blimp_connection_statistics.h", "blimp_message_checkpoint_observer.h", "blimp_message_checkpointer.cc", "blimp_message_checkpointer.h", @@ -24,6 +22,8 @@ "blimp_message_thread_pipe.cc", "blimp_message_thread_pipe.h", "blimp_net_export.h", + "blimp_stats.cc", + "blimp_stats.h", "blimp_transport.h", "blob_channel/blob_channel_receiver.cc", "blob_channel/blob_channel_receiver.h", @@ -117,7 +117,6 @@ testonly = true sources = [ - "blimp_connection_statistics_unittest.cc", "blimp_connection_unittest.cc", "blimp_message_checkpointer_unittest.cc", "blimp_message_demultiplexer_unittest.cc", @@ -125,6 +124,7 @@ "blimp_message_output_buffer_unittest.cc", "blimp_message_pump_unittest.cc", "blimp_message_thread_pipe_unittest.cc", + "blimp_stats_unittest.cc", "blob_channel/blob_channel_integration_test.cc", "blob_channel/blob_channel_receiver_unittest.cc", "blob_channel/blob_channel_sender_unittest.cc",
diff --git a/blimp/net/blimp_connection_statistics.cc b/blimp/net/blimp_connection_statistics.cc deleted file mode 100644 index b61d23b7..0000000 --- a/blimp/net/blimp_connection_statistics.cc +++ /dev/null
@@ -1,26 +0,0 @@ -// Copyright 2016 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 "blimp/net/blimp_connection_statistics.h" - -namespace blimp { - -BlimpConnectionStatistics::BlimpConnectionStatistics() - : histogram_( - base::SparseHistogram::FactoryGet("BlimpSparseHistogram", - base::HistogramBase::kNoFlags)) {} - -BlimpConnectionStatistics::~BlimpConnectionStatistics() {} - -void BlimpConnectionStatistics::Add(EventType type, int data) { - histogram_->AddCount(type, data); -} - -int BlimpConnectionStatistics::Get(EventType type) { - std::unique_ptr<base::HistogramSamples> snapshot = - histogram_->SnapshotSamples(); - return snapshot->GetCount(type); -} - -} // namespace blimp
diff --git a/blimp/net/blimp_connection_statistics.h b/blimp/net/blimp_connection_statistics.h deleted file mode 100644 index fefd96d..0000000 --- a/blimp/net/blimp_connection_statistics.h +++ /dev/null
@@ -1,49 +0,0 @@ -// Copyright 2016 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 BLIMP_NET_BLIMP_CONNECTION_STATISTICS_H_ -#define BLIMP_NET_BLIMP_CONNECTION_STATISTICS_H_ - -#include <map> -#include "base/macros.h" -#include "base/metrics/sparse_histogram.h" -#include "blimp/net/blimp_net_export.h" - -namespace blimp { - -// Collects network traffic statistics. Maintains a counter for number of -// completed commits, bytes sent and received over network and notifies its -// observers on the main thread. -// This class is supposed to live an entire session, created and destroyed along -// it. This class is thread-safe. -class BLIMP_NET_EXPORT BlimpConnectionStatistics { - public: - enum EventType { - BYTES_SENT = 0, - BYTES_RECEIVED = 1, - COMMIT = 2, - }; - - BlimpConnectionStatistics(); - - ~BlimpConnectionStatistics(); - - // Accumulates values for a metric. - void Add(EventType type, int data); - - // Returns value for a metric. - int Get(EventType type); - - private: - // A histogram to hold the metrics. It will have one sample for each type of - // metric which will be accumulated on each subsequent call. Histograms are - // intentionally leaked at the process termination. - base::HistogramBase* histogram_; - - DISALLOW_COPY_AND_ASSIGN(BlimpConnectionStatistics); -}; - -} // namespace blimp - -#endif // BLIMP_NET_BLIMP_CONNECTION_STATISTICS_H_
diff --git a/blimp/net/blimp_connection_statistics_unittest.cc b/blimp/net/blimp_connection_statistics_unittest.cc deleted file mode 100644 index 6cb1bea..0000000 --- a/blimp/net/blimp_connection_statistics_unittest.cc +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2016 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/macros.h" -#include "blimp/net/blimp_connection_statistics.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace blimp { - -class BlimpConnectionStatisticsTest : public testing::Test { - public: - BlimpConnectionStatisticsTest() {} - - ~BlimpConnectionStatisticsTest() override {} - - protected: - BlimpConnectionStatistics stats_; - - private: - DISALLOW_COPY_AND_ASSIGN(BlimpConnectionStatisticsTest); -}; - -TEST_F(BlimpConnectionStatisticsTest, AddStatsAndVerify) { - DCHECK_EQ(0, stats_.Get(BlimpConnectionStatistics::BYTES_SENT)); - DCHECK_EQ(0, stats_.Get(BlimpConnectionStatistics::BYTES_RECEIVED)); - DCHECK_EQ(0, stats_.Get(BlimpConnectionStatistics::COMMIT)); - - stats_.Add(BlimpConnectionStatistics::BYTES_SENT, 10); - stats_.Add(BlimpConnectionStatistics::BYTES_SENT, 20); - stats_.Add(BlimpConnectionStatistics::BYTES_RECEIVED, 5); - stats_.Add(BlimpConnectionStatistics::COMMIT, 1); - - DCHECK_EQ(30, stats_.Get(BlimpConnectionStatistics::BYTES_SENT)); - DCHECK_EQ(5, stats_.Get(BlimpConnectionStatistics::BYTES_RECEIVED)); - DCHECK_EQ(1, stats_.Get(BlimpConnectionStatistics::COMMIT)); -} - -} // namespace blimp
diff --git a/blimp/net/blimp_stats.cc b/blimp/net/blimp_stats.cc new file mode 100644 index 0000000..3912adb --- /dev/null +++ b/blimp/net/blimp_stats.cc
@@ -0,0 +1,42 @@ +// Copyright 2016 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 "blimp/net/blimp_stats.h" + +#include "base/logging.h" + +namespace blimp { + +// static +base::LazyInstance<BlimpStats> BlimpStats::instance_ = + LAZY_INSTANCE_INITIALIZER; + +// static +BlimpStats* BlimpStats::GetInstance() { + return &instance_.Get(); +} + +BlimpStats::BlimpStats() { + for (size_t i = 0; i < EVENT_TYPE_MAX; ++i) { + base::subtle::NoBarrier_Store(&values_[i], 0); + } +} + +BlimpStats::~BlimpStats() {} + +void BlimpStats::Add(EventType type, base::subtle::Atomic32 amount) { + if (amount < 0) { + DLOG(FATAL) << "Illegal negative stat value: type=" << type + << ", amount=" << amount << "."; + return; + } + + base::subtle::NoBarrier_AtomicIncrement(&values_[type], amount); +} + +base::subtle::Atomic32 BlimpStats::Get(EventType type) const { + return base::subtle::NoBarrier_Load(&values_[type]); +} + +} // namespace blimp
diff --git a/blimp/net/blimp_stats.h b/blimp/net/blimp_stats.h new file mode 100644 index 0000000..c4019f3 --- /dev/null +++ b/blimp/net/blimp_stats.h
@@ -0,0 +1,59 @@ +// Copyright 2016 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 BLIMP_NET_BLIMP_STATS_H_ +#define BLIMP_NET_BLIMP_STATS_H_ + +#include <memory> +#include <vector> + +#include "base/atomicops.h" +#include "base/lazy_instance.h" +#include "base/macros.h" +#include "blimp/net/blimp_net_export.h" + +namespace blimp { + +// Maintains counters for completed commits, network bytes sent and +// network bytes received. Counters increase monotonically over the +// lifetime of the process. +// Class is thread-safe. Individual metrics may be safely modified or retrieved +// concurrently. +class BLIMP_NET_EXPORT BlimpStats { + public: + enum EventType { + BYTES_SENT, + BYTES_RECEIVED, + COMMIT, + EVENT_TYPE_MAX = COMMIT, + }; + + static BlimpStats* GetInstance(); + + // Increments the metric |type| by |amount|. |amount| must be a positive + // value. + void Add(EventType type, base::subtle::Atomic32 amount); + + // Returns value for the metric |type|. + base::subtle::Atomic32 Get(EventType type) const; + + private: + friend struct base::DefaultLazyInstanceTraits<BlimpStats>; + + static base::LazyInstance<BlimpStats> instance_; + + BlimpStats(); + ~BlimpStats(); + + // Values must be read or modified using base::subtle::NoBarrier* functions. + // We are using the NoBarrier* functions because we value performance over + // accuracy of the data. + base::subtle::Atomic32 values_[EVENT_TYPE_MAX]; + + DISALLOW_COPY_AND_ASSIGN(BlimpStats); +}; + +} // namespace blimp + +#endif // BLIMP_NET_BLIMP_STATS_H_
diff --git a/blimp/net/blimp_stats_unittest.cc b/blimp/net/blimp_stats_unittest.cc new file mode 100644 index 0000000..c58a282 --- /dev/null +++ b/blimp/net/blimp_stats_unittest.cc
@@ -0,0 +1,40 @@ +// Copyright 2016 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 <limits> + +#include "base/at_exit.h" +#include "base/macros.h" +#include "blimp/net/blimp_stats.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace blimp { + +class BlimpStatsTest : public testing::Test { + public: + BlimpStatsTest() {} + ~BlimpStatsTest() override {} + + private: + base::ShadowingAtExitManager at_exit_manager_; + + DISALLOW_COPY_AND_ASSIGN(BlimpStatsTest); +}; + +TEST_F(BlimpStatsTest, AddStatsAndVerify) { + EXPECT_EQ(0, BlimpStats::GetInstance()->Get(BlimpStats::BYTES_SENT)); + EXPECT_EQ(0, BlimpStats::GetInstance()->Get(BlimpStats::BYTES_RECEIVED)); + EXPECT_EQ(0, BlimpStats::GetInstance()->Get(BlimpStats::COMMIT)); + + BlimpStats::GetInstance()->Add(BlimpStats::BYTES_SENT, 10); + BlimpStats::GetInstance()->Add(BlimpStats::BYTES_SENT, 20); + BlimpStats::GetInstance()->Add(BlimpStats::BYTES_RECEIVED, 5); + BlimpStats::GetInstance()->Add(BlimpStats::COMMIT, 1); + + EXPECT_EQ(30, BlimpStats::GetInstance()->Get(BlimpStats::BYTES_SENT)); + EXPECT_EQ(5, BlimpStats::GetInstance()->Get(BlimpStats::BYTES_RECEIVED)); + EXPECT_EQ(1, BlimpStats::GetInstance()->Get(BlimpStats::COMMIT)); +} + +} // namespace blimp
diff --git a/blimp/net/blob_channel/blob_channel_sender_impl.cc b/blimp/net/blob_channel/blob_channel_sender_impl.cc index 84dec6c..7baf09f 100644 --- a/blimp/net/blob_channel/blob_channel_sender_impl.cc +++ b/blimp/net/blob_channel/blob_channel_sender_impl.cc
@@ -31,7 +31,7 @@ CacheStateEntry next_output; next_output.id = cached_id; next_output.was_delivered = - ContainsKey(receiver_cache_contents_, cached_id); + base::ContainsKey(receiver_cache_contents_, cached_id); output.push_back(next_output); } return output;
diff --git a/blimp/net/ssl_client_transport.cc b/blimp/net/ssl_client_transport.cc index 0cc7a63..bc1e61c 100644 --- a/blimp/net/ssl_client_transport.cc +++ b/blimp/net/ssl_client_transport.cc
@@ -4,6 +4,8 @@ #include "blimp/net/ssl_client_transport.h" +#include <utility> + #include "base/callback.h" #include "base/callback_helpers.h" #include "blimp/net/exact_match_cert_verifier.h" @@ -21,10 +23,8 @@ SSLClientTransport::SSLClientTransport(const net::IPEndPoint& ip_endpoint, scoped_refptr<net::X509Certificate> cert, - BlimpConnectionStatistics* statistics, net::NetLog* net_log) - : TCPClientTransport(ip_endpoint, statistics, net_log), - ip_endpoint_(ip_endpoint) { + : TCPClientTransport(ip_endpoint, net_log), ip_endpoint_(ip_endpoint) { // Test code may pass in a null value for |cert|. Only spin up a CertVerifier // if there is a cert present. if (cert) {
diff --git a/blimp/net/ssl_client_transport.h b/blimp/net/ssl_client_transport.h index 46c4a1d..8b9db0c 100644 --- a/blimp/net/ssl_client_transport.h +++ b/blimp/net/ssl_client_transport.h
@@ -31,7 +31,6 @@ namespace blimp { class BlimpConnection; -class BlimpConnectionStatistics; // Creates and connects SSL socket connections to an Engine. class BLIMP_NET_EXPORT SSLClientTransport : public TCPClientTransport { @@ -42,7 +41,6 @@ // |net_log|: the socket event log (optional). SSLClientTransport(const net::IPEndPoint& ip_endpoint, scoped_refptr<net::X509Certificate> cert, - BlimpConnectionStatistics* statistics, net::NetLog* net_log); ~SSLClientTransport() override;
diff --git a/blimp/net/ssl_client_transport_unittest.cc b/blimp/net/ssl_client_transport_unittest.cc index 1888372..c4d31132 100644 --- a/blimp/net/ssl_client_transport_unittest.cc +++ b/blimp/net/ssl_client_transport_unittest.cc
@@ -6,7 +6,6 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "blimp/net/blimp_connection.h" -#include "blimp/net/blimp_connection_statistics.h" #include "blimp/net/ssl_client_transport.h" #include "net/base/address_list.h" #include "net/base/ip_address.h" @@ -61,13 +60,11 @@ void ConfigureTransport(const net::IPEndPoint& ip_endpoint) { // The mock does not interact with the cert directly, so just leave it null. scoped_refptr<net::X509Certificate> cert; - transport_.reset( - new SSLClientTransport(ip_endpoint, cert, &statistics_, &net_log_)); + transport_.reset(new SSLClientTransport(ip_endpoint, cert, &net_log_)); transport_->SetClientSocketFactoryForTest(&socket_factory_); } base::MessageLoop message_loop; - BlimpConnectionStatistics statistics_; net::NetLog net_log_; net::StaticSocketDataProvider tcp_connect_; std::unique_ptr<net::SSLSocketDataProvider> ssl_connect_;
diff --git a/blimp/net/stream_packet_reader.cc b/blimp/net/stream_packet_reader.cc index 1fb9b52..08b652e4 100644 --- a/blimp/net/stream_packet_reader.cc +++ b/blimp/net/stream_packet_reader.cc
@@ -13,7 +13,7 @@ #include "base/single_thread_task_runner.h" #include "base/sys_byteorder.h" #include "base/threading/thread_task_runner_handle.h" -#include "blimp/net/blimp_connection_statistics.h" +#include "blimp/net/blimp_stats.h" #include "blimp/net/common.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" @@ -37,12 +37,8 @@ return out; } -StreamPacketReader::StreamPacketReader(net::StreamSocket* socket, - BlimpConnectionStatistics* statistics) - : read_state_(ReadState::IDLE), - socket_(socket), - statistics_(statistics), - weak_factory_(this) { +StreamPacketReader::StreamPacketReader(net::StreamSocket* socket) + : read_state_(ReadState::IDLE), socket_(socket), weak_factory_(this) { DCHECK(socket_); header_buffer_ = new net::GrowableIOBuffer; header_buffer_->SetCapacity(kPacketHeaderSizeBytes); @@ -140,7 +136,7 @@ return DoRead(payload_buffer_.get(), payload_size_ - payload_buffer_->offset()); } - statistics_->Add(BlimpConnectionStatistics::BYTES_RECEIVED, payload_size_); + BlimpStats::GetInstance()->Add(BlimpStats::BYTES_RECEIVED, payload_size_); // Finished reading the payload. read_state_ = ReadState::IDLE;
diff --git a/blimp/net/stream_packet_reader.h b/blimp/net/stream_packet_reader.h index 146e463..9b1559f1 100644 --- a/blimp/net/stream_packet_reader.h +++ b/blimp/net/stream_packet_reader.h
@@ -21,7 +21,6 @@ } // namespace net namespace blimp { -class BlimpConnectionStatistics; // Reads opaque length-prefixed packets of bytes from a StreamSocket. // The header segment is 32-bit, encoded in network byte order. @@ -31,10 +30,7 @@ public: // |socket|: The socket to read packets from. The caller must ensure |socket| // is valid while the reader is in-use (see ReadPacket below). - // |statistics|: Statistics collector to keep track of number of bytes read. - // |statistics| is expected to outlive |this|. - StreamPacketReader(net::StreamSocket* socket, - BlimpConnectionStatistics* statistics); + explicit StreamPacketReader(net::StreamSocket* socket); ~StreamPacketReader() override; @@ -82,7 +78,6 @@ scoped_refptr<net::GrowableIOBuffer> header_buffer_; scoped_refptr<net::GrowableIOBuffer> payload_buffer_; net::CompletionCallback callback_; - BlimpConnectionStatistics* statistics_; base::WeakPtrFactory<StreamPacketReader> weak_factory_;
diff --git a/blimp/net/stream_packet_reader_unittest.cc b/blimp/net/stream_packet_reader_unittest.cc index adf62dc7..37dc758 100644 --- a/blimp/net/stream_packet_reader_unittest.cc +++ b/blimp/net/stream_packet_reader_unittest.cc
@@ -3,11 +3,14 @@ // found in the LICENSE file. #include <stddef.h> +#include <memory> #include <string> +#include "base/at_exit.h" +#include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/sys_byteorder.h" -#include "blimp/net/blimp_connection_statistics.h" +#include "blimp/net/blimp_stats.h" #include "blimp/net/common.h" #include "blimp/net/stream_packet_reader.h" #include "blimp/net/test_common.h" @@ -35,20 +38,24 @@ StreamPacketReaderTest() : buffer_(new net::GrowableIOBuffer), test_msg_("U WOT M8"), - data_reader_(&socket_, &statistics_) {} + data_reader_(&socket_) {} ~StreamPacketReaderTest() override {} + void SetUp() override { + ASSERT_EQ(0, BlimpStats::GetInstance()->Get(BlimpStats::BYTES_RECEIVED)); + } + void ReadPacket() { data_reader_.ReadPacket(buffer_, callback_.callback()); } protected: + base::ShadowingAtExitManager at_exit_manager; base::MessageLoop message_loop_; scoped_refptr<net::GrowableIOBuffer> buffer_; std::string test_msg_; net::TestCompletionCallback callback_; testing::StrictMock<MockStreamSocket> socket_; testing::InSequence sequence_; - BlimpConnectionStatistics statistics_; StreamPacketReader data_reader_; }; @@ -159,12 +166,12 @@ ReadPacket(); ASSERT_EQ(static_cast<int>(test_msg_.size()), callback_.WaitForResult()); EXPECT_EQ(static_cast<int>(test_msg_.size()), - statistics_.Get(BlimpConnectionStatistics::BYTES_RECEIVED)); + BlimpStats::GetInstance()->Get(BlimpStats::BYTES_RECEIVED)); ReadPacket(); ASSERT_EQ(static_cast<int>(test_msg2.size()), callback_.WaitForResult()); EXPECT_EQ(static_cast<int>(test_msg_.size() + test_msg2.size()), - statistics_.Get(BlimpConnectionStatistics::BYTES_RECEIVED)); + BlimpStats::GetInstance()->Get(BlimpStats::BYTES_RECEIVED)); EXPECT_TRUE(BufferStartsWith(buffer_.get(), test_msg2.size(), test_msg2)); EXPECT_FALSE(callback_.have_result()); @@ -371,8 +378,7 @@ TEST_F(StreamPacketReaderTest, ReaderDeletedDuringAsyncHeaderRead) { net::CompletionCallback cb; net::TestCompletionCallback test_cb; - std::unique_ptr<StreamPacketReader> reader( - new StreamPacketReader(&socket_, &statistics_)); + std::unique_ptr<StreamPacketReader> reader(new StreamPacketReader(&socket_)); EXPECT_CALL(socket_, Read(NotNull(), kPacketHeaderSizeBytes, _)) .WillOnce(DoAll(FillBufferFromString<0>(EncodeHeader(test_msg_.size())), @@ -387,8 +393,7 @@ // StreamPacketReader object was destroyed. TEST_F(StreamPacketReaderTest, ReaderDeletedDuringAsyncPayloadRead) { net::CompletionCallback cb; - std::unique_ptr<StreamPacketReader> reader( - new StreamPacketReader(&socket_, &statistics_)); + std::unique_ptr<StreamPacketReader> reader(new StreamPacketReader(&socket_)); EXPECT_CALL(socket_, Read(NotNull(), kPacketHeaderSizeBytes, _)) .WillOnce(DoAll(FillBufferFromString<0>(EncodeHeader(test_msg_.size())),
diff --git a/blimp/net/stream_packet_writer.cc b/blimp/net/stream_packet_writer.cc index dd718d150..04fed0a 100644 --- a/blimp/net/stream_packet_writer.cc +++ b/blimp/net/stream_packet_writer.cc
@@ -14,7 +14,7 @@ #include "base/sys_byteorder.h" #include "base/threading/thread_task_runner_handle.h" #include "blimp/common/proto/blimp_message.pb.h" -#include "blimp/net/blimp_connection_statistics.h" +#include "blimp/net/blimp_stats.h" #include "blimp/net/common.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" @@ -38,17 +38,14 @@ return out; } -StreamPacketWriter::StreamPacketWriter(net::StreamSocket* socket, - BlimpConnectionStatistics* statistics) +StreamPacketWriter::StreamPacketWriter(net::StreamSocket* socket) : write_state_(WriteState::IDLE), socket_(socket), header_buffer_( new net::DrainableIOBuffer(new net::IOBuffer(kPacketHeaderSizeBytes), kPacketHeaderSizeBytes)), - statistics_(statistics), weak_factory_(this) { DCHECK(socket_); - DCHECK(statistics_); } StreamPacketWriter::~StreamPacketWriter() {} @@ -66,8 +63,8 @@ base::HostToNet32(data->BytesRemaining()); payload_buffer_ = data; - statistics_->Add(BlimpConnectionStatistics::BYTES_SENT, - payload_buffer_->BytesRemaining()); + BlimpStats::GetInstance()->Add(BlimpStats::BYTES_SENT, + payload_buffer_->BytesRemaining()); int result = DoWriteLoop(net::OK); if (result != net::ERR_IO_PENDING) { // Release the payload buffer, since the write operation has completed
diff --git a/blimp/net/stream_packet_writer.h b/blimp/net/stream_packet_writer.h index 19a71084..18744f4 100644 --- a/blimp/net/stream_packet_writer.h +++ b/blimp/net/stream_packet_writer.h
@@ -21,7 +21,6 @@ } // namespace net namespace blimp { -class BlimpConnectionStatistics; // Writes opaque length-prefixed packets to a StreamSocket. // The header segment is 32-bit, encoded in network byte order. @@ -31,10 +30,7 @@ public: // |socket|: The socket to write packets to. The caller must ensure |socket| // is valid while the reader is in-use (see ReadPacket below). - // |statistics|: Statistics collector which keeps track of number of bytes - // written. |statistics| is expected to outlive |this|. - StreamPacketWriter(net::StreamSocket* socket, - BlimpConnectionStatistics* statistics); + explicit StreamPacketWriter(net::StreamSocket* socket); ~StreamPacketWriter() override; @@ -78,7 +74,6 @@ scoped_refptr<net::DrainableIOBuffer> payload_buffer_; scoped_refptr<net::DrainableIOBuffer> header_buffer_; net::CompletionCallback callback_; - BlimpConnectionStatistics* statistics_; base::WeakPtrFactory<StreamPacketWriter> weak_factory_;
diff --git a/blimp/net/stream_packet_writer_unittest.cc b/blimp/net/stream_packet_writer_unittest.cc index 9a23340..41b3d5f 100644 --- a/blimp/net/stream_packet_writer_unittest.cc +++ b/blimp/net/stream_packet_writer_unittest.cc
@@ -2,11 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <memory> #include <string> +#include "base/at_exit.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" -#include "blimp/net/blimp_connection_statistics.h" +#include "blimp/net/blimp_stats.h" #include "blimp/net/common.h" #include "blimp/net/stream_packet_writer.h" #include "blimp/net/test_common.h" @@ -34,15 +36,15 @@ : test_data_( new net::DrainableIOBuffer(new net::StringIOBuffer(test_data_str_), test_data_str_.size())), - message_writer_(&socket_, &statistics_) {} + message_writer_(&socket_) {} protected: const std::string test_data_str_ = "U WOT M8"; - scoped_refptr<net::DrainableIOBuffer> test_data_; + base::ShadowingAtExitManager at_exit_manager_; base::MessageLoop message_loop_; MockStreamSocket socket_; - BlimpConnectionStatistics statistics_; + scoped_refptr<net::DrainableIOBuffer> test_data_; StreamPacketWriter message_writer_; testing::InSequence mock_sequence_; @@ -97,7 +99,7 @@ message_writer_.WritePacket(test_data_, writer_cb.callback()); EXPECT_EQ(static_cast<int>(payload.size()), - statistics_.Get(BlimpConnectionStatistics::BYTES_SENT)); + BlimpStats::GetInstance()->Get(BlimpStats::BYTES_SENT)); // Header is written - first one byte, then the remainder. header_cb.Run(1); @@ -203,8 +205,7 @@ net::TestCompletionCallback writer_cb; net::CompletionCallback header_cb; net::CompletionCallback payload_cb; - std::unique_ptr<StreamPacketWriter> writer( - new StreamPacketWriter(&socket_, &statistics_)); + std::unique_ptr<StreamPacketWriter> writer(new StreamPacketWriter(&socket_)); // Write header. EXPECT_CALL(socket_, Write(BufferEquals(EncodeHeader(test_data_str_.size())), @@ -224,8 +225,7 @@ net::TestCompletionCallback writer_cb; net::CompletionCallback header_cb; net::CompletionCallback payload_cb; - std::unique_ptr<StreamPacketWriter> writer( - new StreamPacketWriter(&socket_, &statistics_)); + std::unique_ptr<StreamPacketWriter> writer(new StreamPacketWriter(&socket_)); EXPECT_CALL(socket_, Write(BufferEquals(EncodeHeader(test_data_str_.size())), kPacketHeaderSizeBytes, _))
diff --git a/blimp/net/stream_socket_connection.cc b/blimp/net/stream_socket_connection.cc index 8efaaaa..bd0fad651 100644 --- a/blimp/net/stream_socket_connection.cc +++ b/blimp/net/stream_socket_connection.cc
@@ -4,6 +4,8 @@ #include "blimp/net/stream_socket_connection.h" +#include <utility> + #include "base/memory/ptr_util.h" #include "blimp/net/compressed_packet_reader.h" #include "blimp/net/compressed_packet_writer.h" @@ -13,16 +15,13 @@ namespace blimp { StreamSocketConnection::StreamSocketConnection( - std::unique_ptr<net::StreamSocket> socket, - BlimpConnectionStatistics* statistics) - : BlimpConnection( - base::WrapUnique(new CompressedPacketReader(base::WrapUnique( - new StreamPacketReader(socket.get(), statistics)))), - base::WrapUnique(new CompressedPacketWriter(base::WrapUnique( - new StreamPacketWriter(socket.get(), statistics))))), + std::unique_ptr<net::StreamSocket> socket) + : BlimpConnection(base::MakeUnique<CompressedPacketReader>( + base::MakeUnique<StreamPacketReader>(socket.get())), + base::MakeUnique<CompressedPacketWriter>( + base::MakeUnique<StreamPacketWriter>(socket.get()))), socket_(std::move(socket)) { DCHECK(socket_); - DCHECK(statistics); } StreamSocketConnection::~StreamSocketConnection() {}
diff --git a/blimp/net/stream_socket_connection.h b/blimp/net/stream_socket_connection.h index 48c4c3e..f86de22 100644 --- a/blimp/net/stream_socket_connection.h +++ b/blimp/net/stream_socket_connection.h
@@ -15,13 +15,11 @@ } // namespace net namespace blimp { -class BlimpConnectionStatistics; // BlimpConnection specialization for StreamSocket-based connections. class StreamSocketConnection : public BlimpConnection { public: - StreamSocketConnection(std::unique_ptr<net::StreamSocket> socket, - BlimpConnectionStatistics* statistics); + explicit StreamSocketConnection(std::unique_ptr<net::StreamSocket> socket); ~StreamSocketConnection() override;
diff --git a/blimp/net/tcp_client_transport.cc b/blimp/net/tcp_client_transport.cc index dd7850d0..173396b 100644 --- a/blimp/net/tcp_client_transport.cc +++ b/blimp/net/tcp_client_transport.cc
@@ -5,12 +5,12 @@ #include "blimp/net/tcp_client_transport.h" #include <memory> +#include <utility> #include "base/callback.h" #include "base/callback_helpers.h" #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" -#include "blimp/net/blimp_connection_statistics.h" #include "blimp/net/stream_socket_connection.h" #include "net/socket/client_socket_factory.h" #include "net/socket/stream_socket.h" @@ -19,14 +19,10 @@ namespace blimp { TCPClientTransport::TCPClientTransport(const net::IPEndPoint& ip_endpoint, - BlimpConnectionStatistics* statistics, net::NetLog* net_log) : ip_endpoint_(ip_endpoint), - blimp_connection_statistics_(statistics), net_log_(net_log), - socket_factory_(net::ClientSocketFactory::GetDefaultFactory()) { - DCHECK(blimp_connection_statistics_); -} + socket_factory_(net::ClientSocketFactory::GetDefaultFactory()) {} TCPClientTransport::~TCPClientTransport() {} @@ -57,8 +53,7 @@ std::unique_ptr<BlimpConnection> TCPClientTransport::TakeConnection() { DCHECK(connect_callback_.is_null()); DCHECK(socket_); - return base::WrapUnique(new StreamSocketConnection( - std::move(socket_), blimp_connection_statistics_)); + return base::MakeUnique<StreamSocketConnection>(std::move(socket_)); } const char* TCPClientTransport::GetName() const {
diff --git a/blimp/net/tcp_client_transport.h b/blimp/net/tcp_client_transport.h index 2bd6db80..d1444c51 100644 --- a/blimp/net/tcp_client_transport.h +++ b/blimp/net/tcp_client_transport.h
@@ -24,14 +24,12 @@ namespace blimp { class BlimpConnection; -class BlimpConnectionStatistics; // BlimpTransport which creates a TCP connection to one of the specified // |addresses| on each call to Connect(). class BLIMP_NET_EXPORT TCPClientTransport : public BlimpTransport { public: TCPClientTransport(const net::IPEndPoint& ip_endpoint, - BlimpConnectionStatistics* statistics, net::NetLog* net_log); ~TCPClientTransport() override; @@ -60,7 +58,6 @@ private: net::IPEndPoint ip_endpoint_; - BlimpConnectionStatistics* blimp_connection_statistics_; net::NetLog* net_log_; net::CompletionCallback connect_callback_; net::ClientSocketFactory* socket_factory_ = nullptr;
diff --git a/blimp/net/tcp_engine_transport.cc b/blimp/net/tcp_engine_transport.cc index 6375a8d..c694a43 100644 --- a/blimp/net/tcp_engine_transport.cc +++ b/blimp/net/tcp_engine_transport.cc
@@ -5,6 +5,7 @@ #include "blimp/net/tcp_engine_transport.h" #include <memory> +#include <utility> #include "base/callback.h" #include "base/callback_helpers.h" @@ -19,13 +20,8 @@ namespace blimp { TCPEngineTransport::TCPEngineTransport(const net::IPEndPoint& address, - BlimpConnectionStatistics* statistics, net::NetLog* net_log) - : address_(address), - blimp_connection_statistics_(statistics), - net_log_(net_log) { - DCHECK(blimp_connection_statistics_); -} + : address_(address), net_log_(net_log) {} TCPEngineTransport::~TCPEngineTransport() {} @@ -66,8 +62,8 @@ std::unique_ptr<BlimpConnection> TCPEngineTransport::TakeConnection() { DCHECK(connect_callback_.is_null()); DCHECK(accepted_socket_); - return base::WrapUnique(new StreamSocketConnection( - std::move(accepted_socket_), blimp_connection_statistics_)); + return base::WrapUnique( + new StreamSocketConnection(std::move(accepted_socket_))); } const char* TCPEngineTransport::GetName() const {
diff --git a/blimp/net/tcp_engine_transport.h b/blimp/net/tcp_engine_transport.h index 42da0189..56850aa2 100644 --- a/blimp/net/tcp_engine_transport.h +++ b/blimp/net/tcp_engine_transport.h
@@ -23,14 +23,12 @@ namespace blimp { class BlimpConnection; -class BlimpConnectionStatistics; // BlimpTransport which listens for a TCP connection at |address|. class BLIMP_NET_EXPORT TCPEngineTransport : public BlimpTransport { public: - // Caller retains the ownership of |statistics| and |net_log|. + // Caller retains the ownership of |net_log|. TCPEngineTransport(const net::IPEndPoint& address, - BlimpConnectionStatistics* statistics, net::NetLog* net_log); ~TCPEngineTransport() override; @@ -45,7 +43,6 @@ void OnTCPConnectAccepted(int result); const net::IPEndPoint address_; - BlimpConnectionStatistics* blimp_connection_statistics_; net::NetLog* net_log_; std::unique_ptr<net::ServerSocket> server_socket_; std::unique_ptr<net::StreamSocket> accepted_socket_;
diff --git a/blimp/net/tcp_transport_unittest.cc b/blimp/net/tcp_transport_unittest.cc index d8f5bbc..a692fd8 100644 --- a/blimp/net/tcp_transport_unittest.cc +++ b/blimp/net/tcp_transport_unittest.cc
@@ -10,7 +10,7 @@ #include "blimp/common/proto/blimp_message.pb.h" #include "blimp/common/proto/protocol_control.pb.h" #include "blimp/net/blimp_connection.h" -#include "blimp/net/blimp_connection_statistics.h" +#include "blimp/net/blimp_stats.h" #include "blimp/net/tcp_client_transport.h" #include "blimp/net/tcp_engine_transport.h" #include "blimp/net/test_common.h" @@ -33,7 +33,7 @@ protected: TCPTransportTest() { net::IPEndPoint local_address(net::IPAddress(127, 0, 0, 1), 0); - engine_.reset(new TCPEngineTransport(local_address, &statistics_, nullptr)); + engine_.reset(new TCPEngineTransport(local_address, nullptr)); } net::IPEndPoint GetLocalEndpoint() const { @@ -43,17 +43,15 @@ } base::MessageLoopForIO message_loop_; - BlimpConnectionStatistics statistics_; std::unique_ptr<TCPEngineTransport> engine_; }; TEST_F(TCPTransportTest, Connect) { - BlimpConnectionStatistics statistics; net::TestCompletionCallback accept_callback; engine_->Connect(accept_callback.callback()); net::TestCompletionCallback connect_callback; - TCPClientTransport client(GetLocalEndpoint(), &statistics, nullptr); + TCPClientTransport client(GetLocalEndpoint(), nullptr); client.Connect(connect_callback.callback()); EXPECT_EQ(net::OK, connect_callback.WaitForResult()); @@ -62,16 +60,15 @@ } TEST_F(TCPTransportTest, TwoClientConnections) { - BlimpConnectionStatistics statistics; net::TestCompletionCallback accept_callback1; engine_->Connect(accept_callback1.callback()); net::TestCompletionCallback connect_callback1; - TCPClientTransport client1(GetLocalEndpoint(), &statistics, nullptr); + TCPClientTransport client1(GetLocalEndpoint(), nullptr); client1.Connect(connect_callback1.callback()); net::TestCompletionCallback connect_callback2; - TCPClientTransport client2(GetLocalEndpoint(), &statistics, nullptr); + TCPClientTransport client2(GetLocalEndpoint(), nullptr); client2.Connect(connect_callback2.callback()); EXPECT_EQ(net::OK, connect_callback1.WaitForResult()); @@ -86,14 +83,11 @@ } TEST_F(TCPTransportTest, ExchangeMessages) { - BlimpConnectionStatistics statistics; - // Start the Engine transport and connect a client to it. net::TestCompletionCallback accept_callback; engine_->Connect(accept_callback.callback()); net::TestCompletionCallback client_connect_callback; - TCPClientTransport client(GetLocalEndpoint(), &statistics, - nullptr /* NetLog */); + TCPClientTransport client(GetLocalEndpoint(), nullptr); client.Connect(client_connect_callback.callback()); EXPECT_EQ(net::OK, client_connect_callback.WaitForResult()); EXPECT_EQ(net::OK, accept_callback.WaitForResult());
diff --git a/blimp/tools/client_engine_integration.py b/blimp/tools/client_engine_integration.py index f1807f3..3f45e3f 100755 --- a/blimp/tools/client_engine_integration.py +++ b/blimp/tools/client_engine_integration.py
@@ -19,7 +19,6 @@ import signal import subprocess import sys -import time SRC_PATH = os.path.abspath( os.path.join(os.path.dirname(__file__), '..', '..')) @@ -34,6 +33,7 @@ from devil.android import device_utils from devil.android import forwarder from devil.android.sdk import intent +from devil.android.sdk import version_codes from devil.utils import cmd_helper _CLIENT_TOKEN_PATH = posixpath.join('/', 'data', 'data', @@ -75,7 +75,7 @@ device.StartActivity(run_client_intent, blocking=True) -def RunEngine(output_linux_directory, token_file_path): +def RunEngine(output_linux_directory, token_file_path, device): """Start running engine Args: @@ -88,8 +88,14 @@ port = '0' blimp_engine_app = os.path.join(output_linux_directory, 'blimp_engine_app') + + sub_dir = "marshmallow" + if device.build_version_sdk == version_codes.KITKAT: + sub_dir = "kitkat" blimp_fonts_path = os.path.join(output_linux_directory, 'gen', - 'third_party', 'blimp_fonts') + 'third_party', 'blimp_fonts', + 'font_bundle', sub_dir) + run_engine_cmd = [ blimp_engine_app + ' --android-fonts-path=' + blimp_fonts_path + @@ -102,6 +108,7 @@ stderr=subprocess.STDOUT) for line in iter(p.stdout.readline, ''): + sys.stdout.write(line) l = line.rstrip() match = re.match(PORT_PATTERN, l) if match: @@ -170,13 +177,16 @@ device.PushChangedFiles(host_device_tuples) port_number, engine_process = RunEngine( - args.output_linux_directory, _TOKEN_FILE_PATH) + args.output_linux_directory, _TOKEN_FILE_PATH, device) json_object['port_number'] = port_number json_object['pid'] = engine_process.pid - logging.info("Engine port number: %s", port_number) - logging.info("Engine running PID: %d", engine_process.pid) + logging.info('Engine port number: %s', port_number) + logging.info('Engine running PID: %d', engine_process.pid) - if engine_process.poll() is None: + if engine_process.poll() is not None: + logging.error('Engine failed to start. Return code: %d', + engine_process.poll()) + else: try: port_pairs = [(port_number, port_number)] forwarder.Forwarder.Map(port_pairs, device) @@ -200,11 +210,13 @@ try: engine_process = _Start(args, json_file_path, device) while True: - time.sleep(1) - return_code = engine_process.poll() - if return_code is not None: + nextline = engine_process.stdout.readline() + if nextline == '' and engine_process.poll() is not None: # The engine died. sys.exit(1) + sys.stdout.write(nextline) + sys.stdout.flush() + except KeyboardInterrupt: sys.exit(0) finally:
diff --git a/build/android/BUILD.gn b/build/android/BUILD.gn index e1d4e9b..d0486020 100644 --- a/build/android/BUILD.gn +++ b/build/android/BUILD.gn
@@ -113,6 +113,7 @@ data = sources + [ "devil_chromium.json", "pylib/gtest/filter/", + "test_wrapper/logdog_wrapper.py", "//third_party/android_tools/sdk/build-tools/23.0.1/aapt", "//third_party/android_tools/sdk/build-tools/23.0.1/dexdump", "//third_party/android_tools/sdk/build-tools/23.0.1/lib/libc++.so",
diff --git a/build/android/gyp/write_build_config.py b/build/android/gyp/write_build_config.py index 22b4e27..5ad222a 100755 --- a/build/android/gyp/write_build_config.py +++ b/build/android/gyp/write_build_config.py
@@ -253,6 +253,9 @@ help='Whether this library requires running on the Android platform.') parser.add_option('--bypass-platform-checks', action='store_true', help='Bypass checks for support/require Android platform.') + parser.add_option('--extra-classpath-jars', + help='GYP-list of .jar files to include on the classpath when compiling, ' + 'but not to include in the final binary.') # android library options parser.add_option('--dex-path', help='Path to target\'s dex output.') @@ -521,6 +524,11 @@ javac_classpath = [c['jar_path'] for c in direct_library_deps] java_full_classpath = [c['jar_path'] for c in all_library_deps] + if options.extra_classpath_jars: + extra_jars = build_utils.ParseGypList(options.extra_classpath_jars) + deps_info['extra_classpath_jars'] = extra_jars + javac_classpath += extra_jars + # The java code for an instrumentation test apk is assembled differently for # ProGuard vs. non-ProGuard. # @@ -572,6 +580,10 @@ config['proguard'] = {} proguard_config = config['proguard'] proguard_config['input_paths'] = [options.jar_path] + java_full_classpath + extra_jars = set() + for c in all_library_deps: + extra_jars.update(c.get('extra_classpath_jars', ())) + proguard_config['lib_paths'] = list(extra_jars) # Dependencies for the final dex file of an apk or a 'deps_dex'. if options.type in ['android_apk', 'deps_dex']:
diff --git a/build/android/method_count.py b/build/android/method_count.py index fdbdaf5..1d9720c9 100755 --- a/build/android/method_count.py +++ b/build/android/method_count.py
@@ -48,10 +48,10 @@ # https://source.android.com/devices/tech/dalvik/dex-format.html -_CONTRIBUTORS_TO_DEX_CACHE = {'type_ids_size': 'types', - 'string_ids_size': 'strings', - 'method_ids_size': 'methods', - 'field_ids_size': 'fields'} +CONTRIBUTORS_TO_DEX_CACHE = {'type_ids_size': 'types', + 'string_ids_size': 'strings', + 'method_ids_size': 'methods', + 'field_ids_size': 'fields'} def _ExtractSizesFromDexFile(dex_path): @@ -61,7 +61,7 @@ # Each method, type, field, and string contributes 4 bytes (1 reference) # to our DexCache size. counts['dex_cache_size'] = ( - sum(counts[x] for x in _CONTRIBUTORS_TO_DEX_CACHE)) * 4 + sum(counts[x] for x in CONTRIBUTORS_TO_DEX_CACHE)) * 4 return counts m = re.match(r'([a-z_]+_size) *: (\d+)', line) if m: @@ -69,7 +69,7 @@ raise Exception('Unexpected end of output.') -def _ExtractSizesFromZip(path): +def ExtractSizesFromZip(path): tmpdir = tempfile.mkdtemp(suffix='_dex_extract') try: counts = collections.defaultdict(int) @@ -109,7 +109,7 @@ 'and --apk-name was not provided.' % args.dexfile) if os.path.splitext(args.dexfile)[1] in ('.zip', '.apk', '.jar'): - sizes = _ExtractSizesFromZip(args.dexfile) + sizes = ExtractSizesFromZip(args.dexfile) else: sizes = _ExtractSizesFromDexFile(args.dexfile) @@ -118,7 +118,7 @@ '%s_%s' % (args.apk_name, name), 'total', [sizes[value_key]], description or name) - for dex_header_name, readable_name in _CONTRIBUTORS_TO_DEX_CACHE.iteritems(): + for dex_header_name, readable_name in CONTRIBUTORS_TO_DEX_CACHE.iteritems(): print_result(readable_name, dex_header_name) print_result( 'DexCache_size', 'dex_cache_size', 'bytes of permanent dirty memory')
diff --git a/build/android/pylib/instrumentation/instrumentation_test_instance.py b/build/android/pylib/instrumentation/instrumentation_test_instance.py index 3a69c36..e72b894 100644 --- a/build/android/pylib/instrumentation/instrumentation_test_instance.py +++ b/build/android/pylib/instrumentation/instrumentation_test_instance.py
@@ -516,6 +516,8 @@ args.strict_mode and args.strict_mode != 'off'): self._flags.append('--strict-mode=' + args.strict_mode) + if hasattr(args, 'regenerate_goldens') and args.regenerate_goldens: + self._flags.append('--regenerate-goldens') def _initializeDriverAttributes(self): self._driver_apk = os.path.join(
diff --git a/build/android/pylib/local/device/local_device_environment.py b/build/android/pylib/local/device/local_device_environment.py index 43161437..9faf0f7 100644 --- a/build/android/pylib/local/device/local_device_environment.py +++ b/build/android/pylib/local/device/local_device_environment.py
@@ -188,9 +188,18 @@ try: m.Stop() m.Close() + _, temp_path = tempfile.mkstemp() + with open(m.output_file, 'r') as infile: + with open(temp_path, 'w') as outfile: + for line in infile: + outfile.write('Device(%s) %s' % (m.adb.GetDeviceSerial(), line)) + shutil.move(temp_path, m.output_file) except base_error.BaseError: logging.exception('Failed to stop logcat monitor for %s', m.adb.GetDeviceSerial()) + except IOError: + logging.exception('Failed to locate logcat for device %s', + m.adb.GetDeviceSerial()) if self._logcat_output_file: file_utils.MergeFiles(
diff --git a/build/android/resource_sizes.py b/build/android/resource_sizes.py index 16f9e610..ef42e4f1 100755 --- a/build/android/resource_sizes.py +++ b/build/android/resource_sizes.py
@@ -24,17 +24,21 @@ import devil_chromium from devil.utils import cmd_helper +import method_count from pylib import constants from pylib.constants import host_paths _GRIT_PATH = os.path.join(host_paths.DIR_SOURCE_ROOT, 'tools', 'grit') -with host_paths.SysPath(_GRIT_PATH): +# Prepend the grit module from the source tree so it takes precedence over other +# grit versions that might present in the search path. +with host_paths.SysPath(_GRIT_PATH, 1): from grit.format import data_pack # pylint: disable=import-error with host_paths.SysPath(host_paths.BUILD_COMMON_PATH): import perf_tests_results_helper # pylint: disable=import-error + # Python had a bug in zipinfo parsing that triggers on ChromeModern.apk # https://bugs.python.org/issue14315 def _PatchedDecodeExtra(self): @@ -352,29 +356,52 @@ return id_name_map -def PrintStaticInitializersCount(so_with_symbols_path, chartjson=None): - """Emits the performance result for static initializers found in the provided - shared library. Additionally, files for which static initializers were - found are printed on the standard output. +def _PrintStaticInitializersCountFromApk(apk_filename, chartjson=None): + print 'Finding static initializers (can take a minute)' + with zipfile.ZipFile(apk_filename) as z: + namelist = z.namelist() + out_dir = constants.GetOutDirectory() + si_count = 0 + for subpath in namelist: + if subpath.endswith('.so'): + unstripped_path = os.path.join(out_dir, 'lib.unstripped', + os.path.basename(subpath)) + if os.path.exists(unstripped_path): + si_count += _PrintStaticInitializersCount(unstripped_path) + else: + raise Exception('Unstripped .so not found. Looked here: %s', + unstripped_path) + ReportPerfResult(chartjson, 'StaticInitializersCount', 'count', si_count, + 'count') + + +def _PrintStaticInitializersCount(so_with_symbols_path): + """Counts the number of static initializers in the given shared library. + Additionally, files for which static initializers were found are printed + on the standard output. Args: so_with_symbols_path: Path to the unstripped libchrome.so file. + + Returns: + The number of static initializers found. """ # GetStaticInitializers uses get-static-initializers.py to get a list of all # static initializers. This does not work on all archs (particularly arm). # TODO(rnephew): Get rid of warning when crbug.com/585588 is fixed. si_count = CountStaticInitializers(so_with_symbols_path) static_initializers = GetStaticInitializers(so_with_symbols_path) - if si_count != len(static_initializers): + static_initializers_count = len(static_initializers) - 1 # Minus summary. + if si_count != static_initializers_count: print ('There are %d files with static initializers, but ' 'dump-static-initializers found %d:' % - (si_count, len(static_initializers))) + (si_count, static_initializers_count)) else: - print 'Found %d files with static initializers:' % si_count + print '%s - Found %d files with static initializers:' % ( + os.path.basename(so_with_symbols_path), si_count) print '\n'.join(static_initializers) - ReportPerfResult(chartjson, 'StaticInitializersCount', 'count', - si_count, 'count') + return si_count def _FormatBytes(byts): """Pretty-print a number of bytes.""" @@ -398,6 +425,19 @@ return total_size +def _PrintDexAnalysis(apk_filename, chartjson=None): + sizes = method_count.ExtractSizesFromZip(apk_filename) + + graph_title = os.path.basename(apk_filename) + '_Dex' + dex_metrics = method_count.CONTRIBUTORS_TO_DEX_CACHE + for key, label in dex_metrics.iteritems(): + ReportPerfResult(chartjson, graph_title, label, sizes[key], 'entries') + + graph_title = '%sCache' % graph_title + ReportPerfResult(chartjson, graph_title, 'DexCache', sizes['dex_cache_size'], + 'bytes') + + def main(argv): usage = """Usage: %prog [options] file1 file2 ... @@ -442,8 +482,9 @@ devil_chromium.Initialize() if options.so_with_symbols_path: - PrintStaticInitializersCount( - options.so_with_symbols_path, chartjson=chartjson) + si_count = _PrintStaticInitializersCount(options.so_with_symbols_path) + ReportPerfResult(chartjson, 'StaticInitializersCount', 'count', si_count, + 'count') PrintResourceSizes(files, chartjson=chartjson) @@ -451,6 +492,9 @@ if f.endswith('.apk'): PrintApkAnalysis(f, chartjson=chartjson) PrintPakAnalysis(f, options.min_pak_resource_size) + _PrintDexAnalysis(f, chartjson=chartjson) + if not options.so_with_symbols_path: + _PrintStaticInitializersCountFromApk(f, chartjson=chartjson) if chartjson: results_path = os.path.join(options.output_dir, 'results-chart.json')
diff --git a/build/android/test_runner.py b/build/android/test_runner.py index 0fb133c..6ec8a66 100755 --- a/build/android/test_runner.py +++ b/build/android/test_runner.py
@@ -422,6 +422,11 @@ help='StrictMode command-line flag set on the device, ' 'death/testing to kill the process, off to stop ' 'checking, flash to flash only. Default testing.') + group.add_argument('--regenerate-goldens', dest='regenerate_goldens', + action='store_true', + help='Causes the render tests to not fail when a check' + 'fails or the golden image is missing but to render' + 'the view and carry on.') AddCommonOptions(parser) AddDeviceOptions(parser)
diff --git a/build/android/test_wrapper/logdog_wrapper.py b/build/android/test_wrapper/logdog_wrapper.py new file mode 100755 index 0000000..6daea499 --- /dev/null +++ b/build/android/test_wrapper/logdog_wrapper.py
@@ -0,0 +1,67 @@ +#!/usr/bin/env python +# Copyright 2016 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. + +"""Wrapper for adding logdog streaming support to swarming tasks.""" + +import argparse +import logging +import os +import subprocess +import sys +import urllib + + +def CommandParser(): + # Parses the command line arguments being passed in + parser = argparse.ArgumentParser() + parser.add_argument('--logdog-bin-cmd', required=True, + help='Command for running logdog butler binary') + parser.add_argument('--project', required=True, + help='Name of logdog project') + parser.add_argument('--logdog-server', + default='services-dot-luci-logdog.appspot.com', + help='URL of logdog server, https:// is assumed.') + parser.add_argument('--service-account-json', required=True, + help='Location of authentication json') + parser.add_argument('--prefix', required=True, + help='Prefix to be used for logdog stream') + parser.add_argument('--source', required=True, + help='Location of file for logdog to stream') + parser.add_argument('--name', required=True, + help='Name to be used for logdog stream') + return parser + + +def CreateUrl(server, project, prefix, name): + stream_name = '%s/%s/+/%s' % (project, prefix, name) + return 'https://%s/v/?s=%s' % (server, urllib.quote_plus(stream_name)) + + +def main(): + parser = CommandParser() + args, test_cmd = parser.parse_known_args(sys.argv[1:]) + logging.basicConfig(level=logging.INFO) + if not test_cmd: + parser.error('Must specify command to run after the logdog flags') + result = subprocess.call(test_cmd) + if '${SWARMING_TASK_ID}' in args.prefix: + args.prefix = args.prefix.replace('${SWARMING_TASK_ID}', + os.environ.get('SWARMING_TASK_ID')) + url = CreateUrl('luci-logdog.appspot.com', args.project, args.prefix, + args.name) + logdog_cmd = [args.logdog_bin_cmd, '-project', args.project, + '-output', 'logdog,host=%s' % args.logdog_server, + '-prefix', args.prefix, + '-service-account-json', args.service_account_json, + 'stream', '-source', args.source, + '-stream', '-name=%s' % args.name] + if os.path.exists(args.logdog_bin_cmd): + subprocess.call(logdog_cmd) + logging.info('Logcats are located at: %s', url) + return result + + +if __name__ == '__main__': + sys.exit(main())
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index 7aa21f5..539fbd7b 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -337,6 +337,11 @@ rebase_path(invoker.bundled_srcjars, root_build_dir) args += [ "--bundled-srcjars=$_rebased_bundled_srcjars" ] } + if (defined(invoker.input_jars_paths)) { + _rebased_input_jars_paths = + rebase_path(invoker.input_jars_paths, root_build_dir) + args += [ "--extra-classpath-jars=$_rebased_input_jars_paths" ] + } if (current_toolchain != default_toolchain) { # This has to be a built-time error rather than a GN assert because many # packages have a mix of java and non-java targets. For example, the @@ -735,11 +740,9 @@ _proguard_jar_path = "//third_party/proguard/lib/proguard.jar" } _output_jar_path = invoker.output_jar_path - _input_jars_paths = [] - if (defined(invoker.input_jars_paths)) { - _input_jars_paths += invoker.input_jars_paths - } - inputs = _input_jars_paths + [ _proguard_jar_path ] + inputs = [ + _proguard_jar_path, + ] if (defined(invoker.alternative_android_sdk_jar)) { inputs += [ invoker.alternative_android_sdk_jar ] _rebased_android_sdk_jar = @@ -770,9 +773,6 @@ "--classpath", _rebased_android_sdk_jar, ] - foreach(c, _input_jars_paths) { - args += [ "--classpath=" + rebase_path(c, root_build_dir) ] - } if (proguard_verbose) { args += [ "--verbose" ] } @@ -1001,12 +1001,7 @@ template("process_java_prebuilt") { set_sources_assignment_filter([]) - forward_variables_from(invoker, - [ - "testonly", - "input_jars_paths", - ]) - assert(!defined(input_jars_paths) || input_jars_paths != [] || true) # Mark as used + forward_variables_from(invoker, [ "testonly" ]) assert(invoker.build_config != "") _build_config = invoker.build_config @@ -1763,6 +1758,7 @@ write_build_config(_build_config_target_name) { type = "java_prebuilt" + forward_variables_from(invoker, [ "input_jars_paths" ]) supports_android = _supports_android requires_android = defined(invoker.requires_android) && invoker.requires_android @@ -1782,9 +1778,7 @@ [ "jar_excluded_patterns", "strip_resource_classes", - "input_jars_paths", ]) - assert(!defined(input_jars_paths) || input_jars_paths != [] || true) # Mark as used visibility = [ ":$_ijar_target_name", @@ -1887,11 +1881,6 @@ _build_config = invoker.build_config - _input_jars_paths = [] - if (defined(invoker.input_jars_paths)) { - _input_jars_paths += invoker.input_jars_paths - } - _chromium_code = false if (defined(invoker.chromium_code)) { _chromium_code = invoker.chromium_code @@ -2038,9 +2027,6 @@ rebase_path(_android_sdk_ijar, root_build_dir) args += [ "--bootclasspath=$_rebased_android_sdk_ijar" ] } - foreach(c, _input_jars_paths) { - args += [ "--classpath=" + c ] - } foreach(e, _manifest_entries) { args += [ "--manifest-entry=" + e ] } @@ -2232,6 +2218,7 @@ build_config_target_name = "${_template_name}__build_config" write_build_config(build_config_target_name) { + forward_variables_from(invoker, [ "input_jars_paths" ]) if (defined(invoker.is_java_binary) && invoker.is_java_binary) { type = "java_binary" } else { @@ -2289,7 +2276,6 @@ "dist_jar_path", "enable_errorprone", "enable_incremental_javac_override", - "input_jars_paths", "jar_excluded_patterns", "manifest_entries", "processors_javac",
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 239be859..49c42b9a 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -1854,6 +1854,7 @@ args = [ "--proguard-configs=$_rebased_proguard_configs", "--input-paths=@FileArg($_rebased_build_config:proguard:input_paths)", + "--classpath=@FileArg($_rebased_build_config:proguard:lib_paths)", ] if (defined(invoker.apk_under_test)) { deps += [ @@ -2686,6 +2687,7 @@ forward_variables_from(invoker, [ "deps", + "input_jars_paths", "requires_android", "jar_excluded_patterns", ])
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 588db2bc..79723f6c 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -1015,6 +1015,12 @@ # TODO(thakis): https://crbug.com/617318 "-Wno-nonportable-include-path", ] + if (llvm_force_head_revision) { + cflags += [ + # TODO(hans): https://crbug.com/637306 + "-Wno-address-of-packed-member", + ] + } } } }
diff --git a/build/config/ios/rules.gni b/build/config/ios/rules.gni index 5a9b209..e21779f 100644 --- a/build/config/ios/rules.gni +++ b/build/config/ios/rules.gni
@@ -6,11 +6,253 @@ import("//build/config/mac/base_rules.gni") import("//build/config/mac/symbols.gni") -_is_secondary_build = - additional_toolchains != [] && current_toolchain != default_toolchain +# Control whether an intermediate source_set is used when building executables +# and shared_libraries for ios_app_bundle and ios_framework_bundle. This is a +# temporary flag that will be removed once scoped_nsobject_unittest{_arc}.mm +# tests are passing with this flag set to true (see crbug.com/637065) +_use_intermediate_source_set = false -_code_signing_script_path = "//build/config/ios/codesign.py" -_default_entitlements_path = "//build/config/ios/entitlements.plist" +# Invokes lipo on multiple arch-specific binaries to create a fat binary. +# +# Arguments +# +# arch_binary_target +# name of the target generating the arch-specific binaries, they must +# be named $target_out_dir/$toolchain_cpu/$arch_binary_output. +# +# arch_binary_output +# (optional, defaults to the name of $arch_binary_target) base name of +# the arch-specific binary generated by arch_binary_target. +# +# output_name +# (optional, defaults to $target_name) base name of the target output, +# the full path will be $target_out_dir/$output_name. +# +# configs +# (optional) a list of configurations, this is used to check whether +# the binary should be stripped, when "enable_stripping" is true. +# +template("lipo_binary") { + assert(defined(invoker.arch_binary_target), + "arch_binary_target must be defined for $target_name") + + _target_name = target_name + _output_name = target_name + if (defined(invoker.output_name)) { + _output_name = invoker.output_name + } + + _all_target_cpu = [ current_cpu ] + additional_target_cpus + _all_toolchains = [ current_toolchain ] + additional_toolchains + + _arch_binary_target = invoker.arch_binary_target + _arch_binary_output = get_label_info(_arch_binary_target, "name") + if (defined(invoker.arch_binary_output)) { + _arch_binary_output = invoker.arch_binary_output + } + + action(_target_name) { + forward_variables_from(invoker, + "*", + [ + "arch_binary_output", + "arch_binary_target", + "configs", + "output_name", + ]) + + script = "//build/toolchain/mac/linker_driver.py" + + outputs = [ + "$target_out_dir/$_output_name", + ] + + deps = [] + _index = 0 + inputs = [] + foreach(_cpu, _all_target_cpu) { + _toolchain = _all_toolchains[_index] + _index = _index + 1 + + inputs += + [ get_label_info("$_arch_binary_target($_toolchain)", + "target_out_dir") + "/$_cpu/$_arch_binary_output" ] + + deps += [ "$_arch_binary_target($_toolchain)" ] + } + + args = [ + "xcrun", + "lipo", + "-create", + "-output", + rebase_path("$target_out_dir/$_output_name", root_build_dir), + ] + rebase_path(inputs, root_build_dir) + + if (enable_dsyms) { + _dsyms_output_dir = "$root_out_dir/$_output_name.dSYM" + outputs += [ + "$_dsyms_output_dir/", + "$_dsyms_output_dir/Contents/Info.plist", + "$_dsyms_output_dir/Contents/Resources/DWARF/$_output_name", + ] + args += [ "-Wcrl,dsym," + rebase_path("$root_out_dir/.", root_build_dir) ] + } + + if (enable_stripping) { + # Check whether //build/config/mac:strip_all has been removed from the + # configs variables (as this is how stripping is disabled for a single + # target). + _strip_all_in_config = false + if (defined(invoker.configs)) { + foreach(_config, invoker.configs) { + if (_config == "//build/config/mac:strip_all") { + _strip_all_in_config = true + } + } + } + + if (_strip_all_in_config) { + args += [ "-Wcrl,strip,-x,-S" ] + if (save_unstripped_output) { + outputs += [ "$root_out_dir/$_output_name.unstripped" ] + args += [ "-Wcrl,unstripped," + + rebase_path("$root_out_dir/.", root_build_dir) ] + } + } + } + } +} + +# Wrapper around create_bundle taking care of code signature settings. +# +# Arguments +# +# product_type +# string, product type for the generated Xcode project. +# +# bundle_extension +# string, extension of the bundle, used to generate bundle name. +# +# bundle_binary_target +# string, label of the target generating the bundle main binary. +# +# bundle_binary_output +# (optional) string, base name of the binary generated by the +# bundle_binary_target target, defaults to the target name. +# +# extra_system_frameworks +# (optional) list of system framework to copy to the bundle. +# +# enable_code_signing +# (optional) boolean, control whether code signing is enabled or not, +# default to ios_enable_code_signing if not defined. +# +template("create_signed_bundle") { + assert(defined(invoker.product_type), + "product_type must be defined for $target_name") + assert(defined(invoker.bundle_extension), + "bundle_extension must be defined for $target_name") + assert(defined(invoker.bundle_binary_target), + "bundle_binary_target must be defined for $target_name") + + _target_name = target_name + _output_name = target_name + if (defined(invoker.output_name)) { + _output_name = invoker.output_name + } + + _bundle_binary_target = invoker.bundle_binary_target + _bundle_binary_output = get_label_info(_bundle_binary_target, "name") + if (defined(invoker.bundle_binary_output)) { + _bundle_binary_output = invoker.bundle_binary_output + } + + _bundle_extension = invoker.bundle_extension + _bundle_root_dir = "$root_out_dir/$_output_name$_bundle_extension" + + _entitlements_path = "//build/config/ios/entitlements.plist" + if (defined(invoker.entitlements_path)) { + _entitlements_path = invoker.entitlements_path + } + + _enable_code_signing = ios_enable_code_signing + if (defined(invoker.enable_code_signing)) { + _enable_code_signing = invoker.enable_code_signing + } + + create_bundle(_target_name) { + forward_variables_from(invoker, + [ + "data_deps", + "deps", + "product_type", + "public_configs", + "public_deps", + "testonly", + "visibility", + ]) + + bundle_root_dir = _bundle_root_dir + bundle_resources_dir = _bundle_root_dir + bundle_executable_dir = _bundle_root_dir + bundle_plugins_dir = "$_bundle_root_dir/PlugIns" + + if (!defined(public_deps)) { + public_deps = [] + } + public_deps += [ _bundle_binary_target ] + + if (defined(invoker.bundle_deps)) { + if (!defined(deps)) { + deps = [] + } + deps += invoker.bundle_deps + } + + code_signing_script = "//build/config/ios/codesign.py" + code_signing_sources = [ + _entitlements_path, + get_label_info(_bundle_binary_target, "target_out_dir") + + "/$_bundle_binary_output", + ] + code_signing_outputs = [ "$_bundle_root_dir/$_output_name" ] + if (_enable_code_signing) { + code_signing_outputs += + [ "$_bundle_root_dir/_CodeSignature/CodeResources" ] + } + if (ios_code_signing_identity != "" && ios_sdk_name != "iphonesimulator") { + code_signing_outputs += [ "$_bundle_root_dir/embedded.mobileprovision" ] + } + + if (defined(invoker.extra_system_frameworks)) { + foreach(_framework, invoker.extra_system_frameworks) { + code_signing_outputs += [ "$bundle_root_dir/Frameworks/" + + get_path_info(_framework, "file") ] + } + } + + code_signing_args = [ + "code-sign-bundle", + "-t=" + ios_sdk_name, + "-i=" + ios_code_signing_identity, + "-e=" + rebase_path(_entitlements_path, root_build_dir), + "-b=" + rebase_path("$target_out_dir/$_output_name", root_build_dir), + rebase_path(bundle_root_dir, root_build_dir), + ] + if (!_enable_code_signing) { + code_signing_args += [ "--disable-code-signature" ] + } + if (defined(invoker.extra_system_frameworks)) { + # All framework in extra_system_frameworks are expected to be + # system framework and the path to be already system absolute + # so do not use rebase_path here. + foreach(_framework, invoker.extra_system_frameworks) { + code_signing_args += [ "-F=" + _framework ] + } + } + } +} # Generates Info.plist files for Mac apps and frameworks. # @@ -117,6 +359,10 @@ # default to "com.apple.product-type.application". Should generally # not be overridden. # +# enable_code_signing +# (optional) boolean, control whether code signing is enabled or not, +# default to ios_enable_code_signing if not defined. +# # For more information, see "gn help executable". template("ios_app_bundle") { _output_name = target_name @@ -125,74 +371,19 @@ _output_name = invoker.output_name } - # This template expands to multiple targets with some differences between - # the the different build configuration. - # - # For a thin build (i.e. when additional_target_cpus is an empty list), - # it compiles the final application binary with an "executable" target, - # performs variable expansions on the Info.plist, defines some "bundle_data" - # target to pack Info.plist and the executable into the .app bundle, and - # finally a "create_bundle" target that packs everything the bundle. If the - # bundle needs to be signed, then the binary is copied into the bundle by - # the "create_bundle" target and the intermediate "bundle_data" target is - # not generated. - # - # For a multi-architecture build (aka fat-build), the template expands to - # a simple "executable" target for non-default toolchain. This is because - # the real application bundle will contains a single binary that supports - # all the architectures and creating a separate .app bundle for every - # architecture would be a waste of time. - # - # The target for the default toolchain of a multi-architecture build will - # build the executable for current_cpu in a temporary location. The real - # fat binary will be created by "lipo" command from all those "executable" - # target (including those of the non-default toolchains). This additional - # target has the same role as the "executable" target of a thin build. - # - # The rest of the build, including the codesigning step, are the same for - # thin and fat builds. + _arch_executable_source = _target_name + "_arch_executable_sources" + _arch_executable_target = _target_name + "_arch_executable" + _lipo_executable_target = _target_name + "_executable" - _executable_extra_deps = [] - _executable_extra_inputs = [] - _executable_extra_ldflags = [] - - # Embeds the entitlements file if building for simulator. This is optional - # with Xcode 7 or older but required with Xcode 8. This is not necessary for - # device build as the entitlement is embedded via the codesigning step. - if (use_ios_simulator) { - _generate_entitlements_target = _target_name + "_gen_entitlements" - _generate_entitlements_target_with_toolchain_suffix = - "$_generate_entitlements_target($default_toolchain)" - - _generate_entitlements_output = - get_label_info(_generate_entitlements_target_with_toolchain_suffix, - "target_gen_dir") + "/$_output_name.xcent" - - _executable_extra_inputs += [ _generate_entitlements_output ] - _executable_extra_deps += - [ ":$_generate_entitlements_target_with_toolchain_suffix" ] - _executable_extra_ldflags += [ - "-Xlinker", - "-sectcreate", - "-Xlinker", - "__TEXT", - "-Xlinker", - "__entitlements", - "-Xlinker", - rebase_path(_generate_entitlements_output, root_build_dir), - ] - } - - if (_is_secondary_build) { - # For the non-default toolchain of a fat-build, the template expands to a - # single "executable" target that creates "$root_out_dir/$_output_name". - executable(_target_name) { + if (_use_intermediate_source_set) { + source_set(_arch_executable_source) { forward_variables_from(invoker, "*", [ "bundle_deps", "bundle_deps_filter", "bundle_extension", + "enable_code_signing", "entitlements_path", "extra_substitutions", "extra_system_frameworks", @@ -200,80 +391,144 @@ "info_plist_target", "output_name", "product_type", + "visibility", ]) - if (defined(visibility)) { - visibility += [ ":*($default_toolchain)" ] - } + visibility = [ ":$_arch_executable_target" ] + } + } else { + assert(_arch_executable_source != "", + "mark _arch_executable_source as used") + } - if (!defined(deps)) { - deps = [] - } - deps += _executable_extra_deps + if (use_ios_simulator) { + _generate_entitlements_target = _target_name + "_gen_entitlements" + _generate_entitlements_output = + get_label_info(":$_generate_entitlements_target($default_toolchain)", + "target_out_dir") + "/$_output_name.xcent" + } - if (!defined(ldflags)) { - ldflags = [] - } - ldflags += _executable_extra_ldflags + executable(_arch_executable_target) { + forward_variables_from(invoker, + "*", + [ + "bundle_deps", + "bundle_deps_filter", + "bundle_extension", + "enable_code_signing", + "entitlements_path", + "extra_substitutions", + "extra_system_frameworks", + "info_plist", + "info_plist_target", + "output_name", + "product_type", + "sources", + "visibility", + ]) + if (!_use_intermediate_source_set) { + forward_variables_from(invoker, [ "sources" ]) + } + + visibility = [ ":$_lipo_executable_target($default_toolchain)" ] + if (current_toolchain != default_toolchain) { + visibility += [ ":$_target_name" ] + } + + if (!defined(deps)) { + deps = [] + } + if (_use_intermediate_source_set) { + deps += [ ":$_arch_executable_source" ] + } + + if (!defined(libs)) { + libs = [] + } + libs += [ "UIKit.framework" ] + + if (use_ios_simulator) { + deps += [ ":$_generate_entitlements_target($default_toolchain)" ] if (!defined(inputs)) { inputs = [] } - inputs += _executable_extra_inputs + inputs += [ _generate_entitlements_output ] - output_name = _output_name - if (!defined(libs)) { - libs = [] + if (!defined(ldflags)) { + ldflags = [] } - libs += [ "UIKit.framework" ] + ldflags += [ + "-Xlinker", + "-sectcreate", + "-Xlinker", + "__TEXT", + "-Xlinker", + "__entitlements", + "-Xlinker", + rebase_path(_generate_entitlements_output, root_build_dir), + ] + } + + output_name = _output_name + output_prefix_override = true + output_dir = "$target_out_dir/$current_cpu" + } + + if (current_toolchain != default_toolchain) { + # For fat builds, only the default toolchain will generate an application + # bundle. For the other toolchains, the template is only used for building + # the arch-specific binary, thus the default target is just a group(). + + group(_target_name) { + forward_variables_from(invoker, + [ + "visibility", + "testonly", + ]) + public_deps = [ + ":$_arch_executable_target", + ] } } else { - # This is either a thin build or the default toolchain of a fat-build. - # The template will expand in many different target ($target_name is the - # create_bundle target) used as input to the create_bundle target. - _generate_info_plist = target_name + "_generate_info_plist" - _bundle_data_info_plist = target_name + "_bundle_data_info_plist" + lipo_binary(_lipo_executable_target) { + forward_variables_from(invoker, + [ + "configs", + "testonly", + ]) - _entitlements_path = _default_entitlements_path - if (defined(invoker.entitlements_path)) { - _entitlements_path = invoker.entitlements_path + visibility = [ ":$_target_name" ] + output_name = _output_name + arch_binary_target = ":$_arch_executable_target" + arch_binary_output = _output_name } + _generate_info_plist = target_name + "_generate_info_plist" ios_info_plist(_generate_info_plist) { - visibility = [ ":$_bundle_data_info_plist" ] - if (use_ios_simulator) { - visibility += [ ":$_generate_entitlements_target" ] - } - executable_name = _output_name forward_variables_from(invoker, [ "extra_substitutions", "info_plist", "info_plist_target", ]) - } - bundle_data(_bundle_data_info_plist) { - visibility = [ ":$_target_name" ] - forward_variables_from(invoker, [ "testonly" ]) - sources = get_target_outputs(":$_generate_info_plist") - outputs = [ - "{{bundle_root_dir}}/Info.plist", - ] - public_deps = [ - ":$_generate_info_plist", - ] + executable_name = _output_name } if (use_ios_simulator) { + _entitlements_path = "//build/config/ios/entitlements.plist" + if (defined(invoker.entitlements_path)) { + _entitlements_path = invoker.entitlements_path + } + action(_generate_entitlements_target) { - _gen_info_plist_target = ":$_generate_info_plist" - _gen_info_plist_outputs = get_target_outputs(_gen_info_plist_target) + _gen_info_plist_outputs = get_target_outputs(":$_generate_info_plist") _info_plist_path = _gen_info_plist_outputs[0] - script = _code_signing_script_path + script = "//build/config/ios/codesign.py" deps = [ - _gen_info_plist_target, + ":$_generate_info_plist", ] sources = [ _entitlements_path, @@ -290,150 +545,44 @@ } } - _link_executable = _target_name + "_arch_executable" - _lipo_executable = _target_name + "_executable" + _bundle_data_info_plist = target_name + "_bundle_data_info_plist" + bundle_data(_bundle_data_info_plist) { + forward_variables_from(invoker, [ "testonly" ]) - _link_executable_visibility = [ ":$_lipo_executable" ] - _lipo_executable_visibility = [ ":$_target_name" ] + sources = get_target_outputs(":$_generate_info_plist") + outputs = [ + "{{bundle_root_dir}}/Info.plist", + ] + public_deps = [ + ":$_generate_info_plist", + ] + } - executable(_link_executable) { + create_signed_bundle(_target_name) { forward_variables_from(invoker, - "*", [ "bundle_deps", - "bundle_deps_filter", "bundle_extension", "data_deps", - "entitlements_path", - "extra_substitutions", - "extra_system_frameworks", - "info_plist", - "info_plist_target", - "output_name", - "product_type", - "visibility", - ]) - - visibility = _link_executable_visibility - - output_name = _output_name - output_prefix_override = true - output_dir = "$target_out_dir/$current_cpu" - - if (!defined(deps)) { - deps = [] - } - deps += _executable_extra_deps - - if (!defined(ldflags)) { - ldflags = [] - } - ldflags += _executable_extra_ldflags - - if (!defined(inputs)) { - inputs = [] - } - inputs += _executable_extra_inputs - - if (!defined(libs)) { - libs = [] - } - libs += [ "UIKit.framework" ] - } - - # Create the multi-architecture binary from all the single architecture - # binaries using "lipo". This target exists for the default toolchain - # of a fat-build only and depends on the expansion of "ios_app_bundle" - # for the other toolchains (i.e. a single "executable" target). - # - # This action only happens once per "ios_app_bundle" template (for the - # main toolchain). - action(_lipo_executable) { - forward_variables_from(invoker, [ "testonly" ]) - visibility = _lipo_executable_visibility - script = "//build/toolchain/mac/linker_driver.py" - outputs = [ - "$target_out_dir/$_output_name", - ] - inputs = [ - "$target_out_dir/$current_cpu/$_output_name", - ] - deps = [ - ":$_link_executable", - ] - foreach(_additional_toolchain, additional_toolchains) { - _additional_toolchain_target = "$_target_name($_additional_toolchain)" - deps += [ ":$_additional_toolchain_target" ] - inputs += [ get_label_info(_additional_toolchain_target, - "root_out_dir") + "/$_output_name" ] - } - args = [ - "xcrun", - "lipo", - "-create", - "-output", - rebase_path(outputs[0], root_build_dir), - ] + rebase_path(inputs, root_build_dir) - - if (enable_dsyms) { - _dsyms_dir = "$root_out_dir/$_output_name.dSYM/" - outputs += [ - "$_dsyms_dir/", - "$_dsyms_dir/Contents/Info.plist", - "$_dsyms_dir/Contents/Resources/DWARF/$_output_name", - ] - args += - [ "-Wcrl,dsym," + rebase_path("$root_out_dir/.", root_build_dir) ] - } - - if (enable_stripping) { - # Check whether //build/config/mac:strip_all has been removed from - # the configs variable (as this is how stripping is disabled for a - # single target). - _strip_all_in_config = false - if (defined(invoker.configs)) { - foreach(_config, invoker.configs) { - if (_config == "//build/config/mac:strip_all") { - _strip_all_in_config = true - } - } - } - - if (_strip_all_in_config) { - args += [ "-Wcrl,strip,-x,-S" ] - - if (save_unstripped_output) { - outputs += [ outputs[0] + ".unstripped" ] - args += [ "-Wcrl,unstripped," + - rebase_path(get_path_info(outputs[0], "dir"), - root_build_dir) ] - } - } - } - } - - create_bundle(target_name) { - forward_variables_from(invoker, - [ - "bundle_deps_filter", - "data_deps", "deps", + "enable_code_signing", + "entitlements_path", + "extra_system_frameworks", + "product_type", + "public_configs", "public_deps", "testonly", "visibility", ]) - if (!defined(deps)) { - deps = [] + output_name = _output_name + bundle_binary_target = ":$_lipo_executable_target" + bundle_binary_output = _output_name + + if (!defined(bundle_deps)) { + bundle_deps = [] } - deps += [ ":$_bundle_data_info_plist" ] - if (!defined(public_deps)) { - public_deps = [] - } - public_deps += [ ":$_lipo_executable" ] - if (defined(invoker.bundle_deps)) { - deps += invoker.bundle_deps - } + bundle_deps += [ ":$_bundle_data_info_plist" ] if (use_ios_simulator) { if (!defined(data_deps)) { @@ -442,102 +591,15 @@ data_deps += [ "//testing/iossim" ] } - if (defined(invoker.product_type)) { - product_type = invoker.product_type - } else { + if (!defined(product_type)) { product_type = "com.apple.product-type.application" } - if (defined(invoker.bundle_extension)) { - _bundle_extension = invoker.bundle_extension - } else { - _bundle_extension = ".app" - } - - bundle_root_dir = "$root_out_dir/$_output_name$_bundle_extension" - bundle_resources_dir = bundle_root_dir - bundle_executable_dir = bundle_root_dir - bundle_plugins_dir = "$bundle_root_dir/PlugIns" - - code_signing_script = _code_signing_script_path - code_signing_sources = [ - _entitlements_path, - "$target_out_dir/$_output_name", - ] - code_signing_outputs = [ "$bundle_root_dir/$_output_name" ] - if (ios_enable_code_signing) { - code_signing_outputs += - [ "$bundle_root_dir/_CodeSignature/CodeResources" ] - } - if (ios_code_signing_identity != "") { - code_signing_outputs += [ "$bundle_root_dir/embedded.mobileprovision" ] - } - if (defined(invoker.extra_system_frameworks)) { - foreach(_framework, invoker.extra_system_frameworks) { - code_signing_outputs += [ "$bundle_root_dir/Frameworks/" + - get_path_info(_framework, "file") ] - } - } - code_signing_args = [ - "code-sign-bundle", - "-t=" + ios_sdk_name, - "-i=" + ios_code_signing_identity, - "-e=" + rebase_path(_entitlements_path, root_build_dir), - "-b=" + rebase_path("$target_out_dir/$_output_name", root_build_dir), - rebase_path(bundle_root_dir, root_build_dir), - ] - if (defined(invoker.extra_system_frameworks)) { - # All framework in extra_system_frameworks are expected to be - # system framework and the path to be already system absolute - # so do not use rebase_path here. - foreach(_framework, invoker.extra_system_frameworks) { - code_signing_args += [ "-F=" + _framework ] - } - } - if (!ios_enable_code_signing) { - code_signing_args += [ "--disable-code-signature" ] + if (!defined(bundle_extension)) { + bundle_extension = ".app" } } } - - # TODO(crbug.com/395883): ensure those variables are marked as used to - # avoid errors while running "gn gen". - if (defined(invoker.entitlements_path)) { - assert(invoker.entitlements_path != "", - "mark invoker.entitlements_path as used") - } - if (defined(invoker.bundle_extension)) { - assert(invoker.bundle_extension != "", - "mark invoker.bundle_extension as used") - } - if (defined(invoker.bundle_extension)) { - assert(invoker.bundle_extension != "", - "mark invoker.bundle_extension as used") - } - if (defined(invoker.entitlements_path)) { - assert(invoker.entitlements_path != "", - "mark invoker.entitlements_path as used") - } - if (defined(invoker.extra_substitutions)) { - assert(invoker.extra_substitutions != [], - "mark invoker.extra_substitutions as used") - } - if (defined(invoker.info_plist)) { - assert(invoker.info_plist != "", "mark invoker.info_plist as used") - } - if (defined(invoker.info_plist_target)) { - assert(invoker.info_plist_target != "", - "mark invoker.info_plist_target as used") - } - if (defined(invoker.product_type)) { - assert(invoker.product_type != "", "mark product_type as used") - } - if (defined(invoker.bundle_deps)) { - assert(invoker.bundle_deps != [], "mark bundle_deps as used") - } - if (defined(invoker.bundle_deps_filter)) { - assert(invoker.bundle_deps_filter != [], "mark bundle_deps_filter as used") - } } set_defaults("ios_app_bundle") { @@ -717,12 +779,6 @@ # (optional) string, name of the generated framework without the # .framework suffix. If omitted, defaults to target_name. # -# framework_version: -# (optional) string, version of the framework. Typically this is a -# single letter, like "A". If omitted, the Versions/ subdirectory -# structure will not be created, and build output will go directly -# into the framework subdirectory. -# # public_headers: # (optional) list of paths to header file that needs to be copied # into the framework bundle Headers subdirectory. If omitted or @@ -732,6 +788,10 @@ # (optional) list of files. Needs to be defined and non-empty if # public_headers is defined and non-empty. # +# enable_code_signing +# (optional) boolean, control whether code signing is enabled or not, +# default to ios_enable_code_signing if not defined. +# # This template provides two targets for the resulting framework bundle. The # link-time behavior varies depending on which of the two targets below is # added as a dependency: @@ -814,40 +874,26 @@ _headers_map_config = _target_name + "_headers_map" } - # The expansion of the template is different for fat and thin builds. For - # thin build (and default toolchain of a fat build), the template expands - # to a "shared_library" target to create the bundle shared library and a - # "create_bundle" target (the main target) to create the bundle structure. - # - # For a fat build, the template just expands to the "shared_library" target - # for the non-default toolchain, while the final library is created using - # "lipo" in the expansion of the template for the default toolchain. - # - # The "$target_name+link" group for the non-default toolchain depends on the - # target of the same name from the default toolchain as this is the target - # that defines the real framework bundle (it will support the current cpu - # as it is a fat framework). + _arch_shared_library_source = _target_name + "_arch_shared_library_sources" + _arch_shared_library_target = _target_name + "_arch_shared_library" + _lipo_shared_library_target = _target_name + "_shared_library" - if (_is_secondary_build) { - shared_library(_target_name) { + if (_use_intermediate_source_set) { + source_set(_arch_shared_library_source) { forward_variables_from(invoker, "*", [ - "assert_no_deps", "bundle_deps", + "bundle_deps_filter", "data_deps", "enable_code_signing", "info_plist", "info_plist_target", "output_name", + "visibility", ]) - if (defined(visibility)) { - visibility += [ ":${_target_name}_shared_library($default_toolchain)" ] - } - output_name = _output_name - output_prefix_override = true - output_extension = "" - output_dir = "$target_out_dir/$_target_name" + + visibility = [ ":$_arch_shared_library_target" ] if (_has_public_headers) { configs += [ @@ -861,6 +907,74 @@ deps += [ ":$_framework_headers_target($default_toolchain)" ] } } + } else { + assert(_arch_shared_library_source != "", + "mark _arch_shared_library_source as used") + } + + shared_library(_arch_shared_library_target) { + forward_variables_from(invoker, + "*", + [ + "bundle_deps", + "bundle_deps_filter", + "data_deps", + "enable_code_signing", + "info_plist", + "info_plist_target", + "output_name", + "sources", + "visibility", + ]) + if (!_use_intermediate_source_set) { + forward_variables_from(invoker, [ "sources" ]) + } + + visibility = [ ":$_lipo_shared_library_target($default_toolchain)" ] + if (current_toolchain != default_toolchain) { + visibility += [ ":$_target_name" ] + } + + if (!defined(deps)) { + deps = [] + } + if (_use_intermediate_source_set) { + deps += [ ":$_arch_shared_library_source" ] + } else { + if (_has_public_headers) { + configs += [ + ":$_framework_headers_config($default_toolchain)", + ":$_headers_map_config($default_toolchain)", + ] + + if (!defined(deps)) { + deps = [] + } + deps += [ ":$_framework_headers_target($default_toolchain)" ] + } + } + + output_extension = "" + output_name = _output_name + output_prefix_override = true + output_dir = "$target_out_dir/$current_cpu" + } + + if (current_toolchain != default_toolchain) { + # For fat builds, only the default toolchain will generate a framework + # bundle. For the other toolchains, the template is only used for building + # the arch-specific binary, thus the default target is just a group(). + + group(_target_name) { + forward_variables_from(invoker, + [ + "visibility", + "testonly", + ]) + public_deps = [ + ":$_arch_shared_library_target", + ] + } group(_target_name + "+link") { forward_variables_from(invoker, @@ -879,8 +993,7 @@ } else { if (_has_public_headers) { _public_headers = invoker.public_headers - _framework_name = _output_name + ".framework" - _framework_root = "$root_out_dir/$_framework_name" + _framework_root = "$root_out_dir/$_output_name.framework" _header_map_filename = "$target_gen_dir/$_output_name.headers.hmap" @@ -936,7 +1049,7 @@ include_dirs = [ _header_map_filename ] ldflags = [ "-install_name", - "@rpath/$_framework_name/$_output_name", + "@rpath/$_output_name.framework/$_output_name", ] } @@ -957,132 +1070,30 @@ } } - # If the framework is unversioned, the final _target_name will be the - # create_bundle(_framework_target), otherwise an action with the name - # _target_name will depends on the the create_bundle() in order to prepare - # the versioned directory structure. - _framework_target = _target_name - _framework_name = _output_name + ".framework" - _framework_root_dir = "$root_out_dir/$_framework_name" - if (defined(invoker.framework_version) && invoker.framework_version != "") { - _framework_version = invoker.framework_version - _framework_root_dir += "/Versions/$_framework_version" - _framework_target = _target_name + "_create_bundle" - } - - _link_shared_library_target = target_name + "_arch_shared_library" - _lipo_shared_library_target = target_name + "_shared_library" - - _lipo_shared_library_visibility = [ ":$_framework_target" ] - _link_shared_library_visibility = [ ":$_lipo_shared_library_target" ] - - _arch_shared_library_dir = "$target_out_dir/$_link_shared_library_target" - _shared_library_dir = "$target_out_dir/$_lipo_shared_library_target" - - shared_library(_link_shared_library_target) { + lipo_binary(_lipo_shared_library_target) { forward_variables_from(invoker, - "*", [ - "assert_no_deps", - "bundle_deps", - "data_deps", - "enable_code_signing", - "info_plist", - "info_plist_target", - "output_name", - "visibility", + "configs", + "testonly", ]) - visibility = _link_shared_library_visibility + + visibility = [ ":$_target_name" ] output_name = _output_name - output_prefix_override = true - output_extension = "" - output_dir = _arch_shared_library_dir - - if (_has_public_headers) { - configs += [ ":$_headers_map_config($default_toolchain)" ] - - if (!defined(deps)) { - deps = [] - } - deps += [ ":$_framework_headers_target($default_toolchain)" ] - } - } - - action(_lipo_shared_library_target) { - forward_variables_from(invoker, [ "testonly" ]) - visibility = _lipo_shared_library_visibility - script = "//build/toolchain/mac/linker_driver.py" - outputs = [ - "$_shared_library_dir/$_output_name", - ] - inputs = [ - "$_arch_shared_library_dir/$_output_name", - ] - deps = [ - ":$_link_shared_library_target", - ] - foreach(_additional_toolchain, additional_toolchains) { - _additional_toolchain_target = "$_target_name($_additional_toolchain)" - deps += [ ":$_additional_toolchain_target" ] - inputs += [ get_label_info(_additional_toolchain_target, - "target_out_dir") + "/$_output_name" ] - } - args = [ - "xcrun", - "lipo", - "-create", - "-output", - rebase_path(outputs[0], root_build_dir), - ] + rebase_path(inputs, root_build_dir) - - if (enable_dsyms) { - _dsyms_dir = "$root_out_dir/$_output_name.dSYM/" - outputs += [ - "$_dsyms_dir/", - "$_dsyms_dir/Contents/Info.plist", - "$_dsyms_dir/Contents/Resources/DWARF/$_output_name", - ] - args += - [ "-Wcrl,dsym," + rebase_path("$root_out_dir/.", root_build_dir) ] - } - - if (enable_stripping) { - # Check whether //build/config/mac:strip_all has been removed from - # the configs variable (as this is how stripping is disabled for a - # single target). - _strip_all_in_config = false - if (defined(invoker.configs)) { - foreach(_config, invoker.configs) { - if (_config == "//build/config/mac:strip_all") { - _strip_all_in_config = true - } - } - } - - if (_strip_all_in_config) { - args += [ "-Wcrl,strip,-x,-S" ] - - if (save_unstripped_output) { - outputs += [ outputs[0] + ".unstripped" ] - args += [ "-Wcrl,unstripped," + - rebase_path(get_path_info(outputs[0], "dir"), - root_build_dir) ] - } - } - } + arch_binary_target = ":$_arch_shared_library_target" + arch_binary_output = _output_name } _framework_public_config = _target_name + "_public_config" config(_framework_public_config) { # TODO(sdefresne): should we have a framework_dirs similar to lib_dirs # and include_dirs to avoid duplicate values on the command-line. - visibility = [ ":$_framework_target" ] + visibility = [ ":$_target_name" ] ldflags = [ "-F", rebase_path("$root_out_dir/.", root_build_dir), ] lib_dirs = [ root_out_dir ] - libs = [ _framework_name ] + libs = [ "$_output_name.framework" ] } _info_plist_target = _target_name + "_info_plist" @@ -1110,104 +1121,30 @@ ] } - create_bundle(_framework_target) { + create_signed_bundle(_target_name) { forward_variables_from(invoker, [ + "bundle_deps", "data_deps", "deps", + "enable_code_signing", "public_configs", "public_deps", "testonly", + "visibility", ]) - if (defined(_framework_version)) { - visibility = [ ":$_target_name" ] - } else { - if (defined(invoker.visibility)) { - visibility = invoker.visibility - visibility += [ ":$_target_name+link" ] - } - } + product_type = "com.apple.product-type.framework" + bundle_extension = ".framework" + + output_name = _output_name + bundle_binary_target = ":$_lipo_shared_library_target" + bundle_binary_output = _output_name if (!defined(deps)) { deps = [] } deps += [ ":$_info_plist_bundle" ] - - if (defined(invoker.bundle_deps)) { - if (!defined(deps)) { - deps = [] - } - deps += invoker.bundle_deps - } - - bundle_root_dir = _framework_root_dir - bundle_resources_dir = _framework_root_dir - bundle_executable_dir = _framework_root_dir - - if (!defined(deps)) { - deps = [] - } - deps += [ ":$_lipo_shared_library_target" ] - - _entitlements_path = _default_entitlements_path - if (defined(invoker.entitlements_path)) { - _entitlements_path = invoker.entitlements_path - } - - _ios_enable_code_signing = ios_enable_code_signing - if (defined(invoker.enable_code_signing)) { - _ios_enable_code_signing = invoker.enable_code_signing - } - - code_signing_script = _code_signing_script_path - code_signing_sources = [ - _entitlements_path, - "$_shared_library_dir/$_output_name", - ] - code_signing_outputs = [ "$bundle_root_dir/$_output_name" ] - if (_ios_enable_code_signing) { - code_signing_outputs += - [ "$bundle_root_dir/_CodeSignature/CodeResources" ] - } - if (ios_code_signing_identity != "") { - code_signing_outputs += [ "$bundle_root_dir/embedded.mobileprovision" ] - } - code_signing_args = [ - "code-sign-bundle", - "-t=" + ios_sdk_name, - "-i=" + ios_code_signing_identity, - "-e=" + rebase_path(_entitlements_path, root_build_dir), - "-b=" + - rebase_path("$_shared_library_dir/$_output_name", root_build_dir), - rebase_path(bundle_root_dir, root_build_dir), - ] - if (!_ios_enable_code_signing) { - code_signing_args += [ "--disable-code-signature" ] - } - } - - if (defined(_framework_version)) { - action(_target_name) { - forward_variables_from(invoker, [ "testonly" ]) - - if (defined(invoker.visibility)) { - visibility = invoker.visibility - visibility += [ ":$_target_name+link" ] - } - - script = "//build/config/mac/package_framework.py" - outputs = [ - "$root_out_dir/$_framework_name/Versions/Current", - ] - args = [ - "$_framework_name", - "$_framework_version", - ] - public_deps = [ - ":$_framework_target", - ] - } } group(_target_name + "+link") { @@ -1272,16 +1209,39 @@ _host_target = _target_name + "_host" _host_output = _output_name + "_host" - if (_is_secondary_build) { - loadable_module(_xctest_target) { - visibility = [ ":${_xctest_target}_loadable_module($default_toolchain)" ] - sources = [ - "//build/config/ios/xctest_shell.mm", - ] - configs += [ "//build/config/ios:xctest_config" ] + _xctest_arch_loadable_module_target = _xctest_target + "_arch_loadable_module" + _xctest_lipo_loadable_module_target = _xctest_target + "_loadable_module" - output_name = _xctest_output - output_extension = "" + loadable_module(_xctest_arch_loadable_module_target) { + visibility = [ ":$_xctest_lipo_loadable_module_target($default_toolchain)" ] + if (current_toolchain != default_toolchain) { + visibility += [ ":$_target_name" ] + } + + sources = [ + "//build/config/ios/xctest_shell.mm", + ] + configs += [ "//build/config/ios:xctest_config" ] + + output_dir = "$target_out_dir/$current_cpu" + output_name = _xctest_output + output_prefix_override = true + output_extension = "" + } + + if (current_toolchain != default_toolchain) { + # For fat builds, only the default toolchain will generate a test bundle. + # For the other toolchains, the template is only used for building the + # arch-specific binary, thus the default target is just a group(). + group(_target_name) { + forward_variables_from(invoker, + [ + "visibility", + "testonly", + ]) + public_deps = [ + ":$_xctest_arch_loadable_module_target", + ] } } else { _xctest_info_plist_target = _xctest_target + "_info_plist" @@ -1303,129 +1263,34 @@ ] } - _xctest_loadable_module_target = _xctest_target + "_arch_loadable_module" - _xctest_lipo_loadable_module_target = _xctest_target + "_loadable_module" + lipo_binary(_xctest_lipo_loadable_module_target) { + forward_variables_from(invoker, + [ + "configs", + "testonly", + ]) - _xctest_loadable_module_visibility = - [ ":$_xctest_lipo_loadable_module_target" ] - _xctest_lipo_loadable_module_visibility = [ ":$_xctest_target" ] - - loadable_module(_xctest_loadable_module_target) { - visibility = _xctest_loadable_module_visibility - sources = [ - "//build/config/ios/xctest_shell.mm", - ] - configs += [ "//build/config/ios:xctest_config" ] - - output_dir = "$target_out_dir/$current_cpu" + visibility = [ ":$_xctest_target" ] output_name = _xctest_output - output_prefix_override = true - output_extension = "" - } - - action(_xctest_lipo_loadable_module_target) { - visibility = _xctest_lipo_loadable_module_visibility - script = "//build/toolchain/mac/linker_driver.py" - outputs = [ - "$target_out_dir/$_xctest_output", - ] - inputs = [ - "$target_out_dir/$current_cpu/$_xctest_output", - ] - deps = [ - ":$_xctest_loadable_module_target", - ] - foreach(_additional_toolchain, additional_toolchains) { - _additional_toolchain_target = "$_target_name($_additional_toolchain)" - deps += [ ":$_additional_toolchain_target" ] - inputs += [ get_label_info(_additional_toolchain_target, - "root_out_dir") + "/$_xctest_output" ] - } - args = [ - "xcrun", - "lipo", - "-create", - "-output", - rebase_path(outputs[0], root_build_dir), - ] + rebase_path(inputs, root_build_dir) - - if (enable_dsyms) { - _dsyms_dir = "$root_out_dir/$_output_name.dSYM/" - outputs += [ - "$_dsyms_dir/", - "$_dsyms_dir/Contents/Info.plist", - "$_dsyms_dir/Contents/Resources/DWARF/$_output_name", - ] - args += - [ "-Wcrl,dsym," + rebase_path("$root_out_dir/.", root_build_dir) ] - } - - if (enable_stripping) { - # Check whether //build/config/mac:strip_all has been removed from - # the configs variable (as this is how stripping is disabled for a - # single target). - _strip_all_in_config = false - if (defined(invoker.configs)) { - foreach(_config, invoker.configs) { - if (_config == "//build/config/mac:strip_all") { - _strip_all_in_config = true - } - } - } - - if (_strip_all_in_config) { - args += [ "-Wcrl,strip,-x,-S" ] - - if (save_unstripped_output) { - outputs += [ outputs[0] + ".unstripped" ] - args += [ "-Wcrl,unstripped," + - rebase_path(get_path_info(outputs[0], "dir"), - root_build_dir) ] - } - } - } + arch_binary_target = ":$_xctest_arch_loadable_module_target" + arch_binary_output = _xctest_output } _xctest_bundle = _xctest_target + "_bundle" - - create_bundle(_xctest_target) { + create_signed_bundle(_xctest_target) { + forward_variables_from(invoker, [ "enable_code_signing" ]) visibility = [ ":$_xctest_bundle" ] + product_type = "com.apple.product-type.bundle.unit-test" + bundle_extension = ".xctest" + + output_name = _xctest_output + bundle_binary_target = ":$_xctest_lipo_loadable_module_target" + bundle_binary_output = _xctest_output + deps = [ ":$_xctest_info_plist_bundle", - ":$_xctest_lipo_loadable_module_target", ] - bundle_root_dir = "$root_out_dir/$_xctest_output.xctest" - - _entitlements_path = _default_entitlements_path - if (defined(invoker.entitlements_path)) { - _entitlements_path = invoker.entitlements_path - } - - code_signing_script = _code_signing_script_path - code_signing_sources = [ - _entitlements_path, - "$target_out_dir/$_xctest_output", - ] - code_signing_outputs = [ "$bundle_root_dir/$_xctest_output" ] - if (ios_enable_code_signing) { - code_signing_outputs += - [ "$bundle_root_dir/_CodeSignature/CodeResources" ] - } - if (ios_code_signing_identity != "") { - code_signing_outputs += [ "$bundle_root_dir/embedded.mobileprovision" ] - } - code_signing_args = [ - "code-sign-bundle", - "-t=" + ios_sdk_name, - "-i=" + ios_code_signing_identity, - "-e=" + rebase_path(_entitlements_path, root_build_dir), - "-b=" + rebase_path("$target_out_dir/$_xctest_output", root_build_dir), - rebase_path(bundle_root_dir, root_build_dir), - ] - if (!ios_enable_code_signing) { - code_signing_args += [ "--disable-code-signature" ] - } } bundle_data(_xctest_bundle) { @@ -1461,7 +1326,7 @@ "$_ios_platform_library/PrivateFrameworks/IDEBundleInjection.framework", ] - if (!_is_secondary_build) { + if (current_toolchain == default_toolchain) { if (!defined(bundle_deps)) { bundle_deps = [] }
diff --git a/build/config/linux/atk/BUILD.gn b/build/config/linux/atk/BUILD.gn index 96bf8c0a..32eaf88 100644 --- a/build/config/linux/atk/BUILD.gn +++ b/build/config/linux/atk/BUILD.gn
@@ -6,7 +6,7 @@ import("//build/config/linux/pkg_config.gni") # CrOS doesn't install GTK, gconf or any gnome packages. -assert(!is_chromeos && use_gconf) +assert(!is_chromeos) # These packages should _only_ be expected when building for a target. # If these extra checks are not run, gconf is required when building host
diff --git a/build/config/mac/BUILD.gn b/build/config/mac/BUILD.gn index ec66a15..84180e6a 100644 --- a/build/config/mac/BUILD.gn +++ b/build/config/mac/BUILD.gn
@@ -3,12 +3,15 @@ # found in the LICENSE file. import("//build/config/sysroot.gni") -if (is_ios) { - import("//build/config/ios/ios_sdk.gni") -} import("//build/config/mac/mac_sdk.gni") import("//build/config/mac/symbols.gni") +if (is_ios) { + # This needs to be imported after mac_sdk.gni as it overrides some of the + # variables defined by it. + import("//build/config/ios/ios_sdk.gni") +} + # This is included by reference in the //build/config/compiler config that # is applied to all targets. It is here to separate out the logic. # @@ -40,6 +43,11 @@ ] } + # This is here so that all files get recompiled after an Xcode update. + # (defines are passed via the command line, and build system rebuild things + # when their commandline changes). Nothing should ever read this define. + defines = [ "CR_XCODE_VERSION=$xcode_version" ] + asmflags = common_mac_flags cflags = common_mac_flags
diff --git a/build/config/mac/symbols.gni b/build/config/mac/symbols.gni index 2cb0b8f0..6166b123d 100644 --- a/build/config/mac/symbols.gni +++ b/build/config/mac/symbols.gni
@@ -14,14 +14,14 @@ # the //build/toolchain/mac/linker_driver.py. Enabling this will result in # all shared library, loadable module, and executable targets having a dSYM # generated. - enable_dsyms = (is_official_build && is_chrome_branded) || using_sanitizer + enable_dsyms = is_official_build || using_sanitizer # Strip symbols from linked targets by default. If this is enabled, the # //build/config/mac:strip_all config will be applied to all linked targets. # If custom stripping parameters are required, remove that config from a # linked target and apply custom -Wcrl,strip flags. See # //build/toolchain/mac/linker_driver.py for more information. - enable_stripping = is_official_build && is_chrome_branded + enable_stripping = is_official_build } # Save unstripped copies of targets with a ".unstripped" suffix. This is
diff --git a/build/toolchain/cros/BUILD.gn b/build/toolchain/cros/BUILD.gn index 56a408b..bf139dc 100644 --- a/build/toolchain/cros/BUILD.gn +++ b/build/toolchain/cros/BUILD.gn
@@ -7,58 +7,65 @@ import("//build/toolchain/gcc_toolchain.gni") import("//build/toolchain/cros_toolchain.gni") -template("cros_target_toolchain") { - gcc_toolchain(target_name) { - assert(defined(invoker.toolchain_args)) - - # These are args for the template. - ar = cros_target_ar - cc = cros_target_cc - cxx = cros_target_cxx - ld = cxx - if (cros_target_ld != "") { - ld = cros_target_ld - } - if (cros_target_nm != "") { - nm = cros_target_nm - } - if (cros_target_readelf != "") { - readelf = cros_target_readelf - } - extra_cflags = cros_target_extra_cflags - extra_cppflags = cros_target_extra_cppflags - extra_cxxflags = cros_target_extra_cxxflags - extra_ldflags = cros_target_extra_ldflags - - toolchain_args = { - forward_variables_from(invoker.toolchain_args, "*") - - cc_wrapper = "" - - # This will override the default computation for is_clang in the - # secondary toolchain with the value of is_clang in the current toolchain - # (the current toolchain will always be the default toolchain here). - is_clang = is_clang - current_cpu = target_cpu - current_os = "chromeos" - use_debug_fission = use_debug_fission - use_sysroot = use_sysroot - } - } -} - # This is the normal toolchain for most targets. -cros_target_toolchain("target") { +gcc_toolchain("target") { + ar = cros_target_ar + cc = cros_target_cc + cxx = cros_target_cxx + ld = cxx + if (cros_target_ld != "") { + ld = cros_target_ld + } + if (cros_target_nm != "") { + nm = cros_target_nm + } + if (cros_target_readelf != "") { + readelf = cros_target_readelf + } + extra_cflags = cros_target_extra_cflags + extra_cppflags = cros_target_extra_cppflags + extra_cxxflags = cros_target_extra_cxxflags + extra_ldflags = cros_target_extra_ldflags + toolchain_args = { + cc_wrapper = "" + current_cpu = target_cpu + current_os = "chromeos" + is_clang = is_clang + use_debug_fission = use_debug_fission + use_gold = use_gold + use_sysroot = use_sysroot } } # This is a special toolchain needed just for the nacl_bootstrap target in # //native_client/src/trusted/service_runtime/linux. It is identical # to ":target" except that it forces use_debug_fission, use_gold, and -# use_sysroot off. -cros_target_toolchain("nacl_bootstrap") { +# use_sysroot off, and allows the user to set different sets of extra flags. +gcc_toolchain("nacl_bootstrap") { + ar = cros_target_ar + cc = cros_target_cc + cxx = cros_target_cxx + ld = cxx + if (cros_target_ld != "") { + ld = cros_target_ld + } + if (cros_target_nm != "") { + nm = cros_target_nm + } + if (cros_target_readelf != "") { + readelf = cros_target_readelf + } + extra_cflags = cros_nacl_bootstrap_extra_cflags + extra_cppflags = cros_nacl_bootstrap_extra_cppflags + extra_cxxflags = cros_nacl_bootstrap_extra_cxxflags + extra_ldflags = cros_nacl_bootstrap_extra_ldflags + toolchain_args = { + cc_wrapper = "" + current_cpu = target_cpu + current_os = "chromeos" + is_clang = is_clang use_debug_fission = false use_gold = false use_sysroot = false
diff --git a/build/toolchain/cros_toolchain.gni b/build/toolchain/cros_toolchain.gni index 17aa020f..fdfdb070 100644 --- a/build/toolchain/cros_toolchain.gni +++ b/build/toolchain/cros_toolchain.gni
@@ -73,4 +73,9 @@ cros_v8_snapshot_extra_cxxflags = "" cros_v8_snapshot_extra_ldflags = "" cros_v8_snapshot_is_clang = false + + cros_nacl_bootstrap_extra_cflags = "" + cros_nacl_bootstrap_extra_cppflags = "" + cros_nacl_bootstrap_extra_cxxflags = "" + cros_nacl_bootstrap_extra_ldflags = "" }
diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni index ad2d1339..eecb409 100644 --- a/build/toolchain/gcc_toolchain.gni +++ b/build/toolchain/gcc_toolchain.gni
@@ -470,28 +470,5 @@ } is_clang = true } - - # Backwards-compatible handling for toolchain definitions in the Native - # Client repo. - # - # TODO(brettw) bug 634446 remove this when - # //native_client/src/trusted/service_runtime/linux/BUILD.gn is updated to - # use the new-style toolchain_args. - if (defined(invoker.toolchain_cpu)) { - assert(!defined(toolchain_args.current_cpu)) - toolchain_args.current_cpu = invoker.toolchain_cpu - } - if (defined(invoker.toolchain_os)) { - assert(!defined(toolchain_args.current_os)) - toolchain_args.current_os = invoker.toolchain_os - } - if (defined(invoker.use_debug_fission)) { - assert(!defined(toolchain_args.use_debug_fission)) - toolchain_args.use_debug_fission = invoker.use_debug_fission - } - if (defined(invoker.use_gold)) { - assert(!defined(toolchain_args.use_gold)) - toolchain_args.use_gold = invoker.use_gold - } } }
diff --git a/build/toolchain/mac/BUILD.gn b/build/toolchain/mac/BUILD.gn index 44cf56d4..0c00e99 100644 --- a/build/toolchain/mac/BUILD.gn +++ b/build/toolchain/mac/BUILD.gn
@@ -58,9 +58,6 @@ root_build_dir), "trim scope") -# Work around for unused variable warning in template https://crbug.com/395883. -assert(tool_versions != "") - # Shared toolchain definition. Invocations should set current_os to set the # build args in this definition. template("mac_toolchain") { @@ -406,7 +403,7 @@ command = "rm -f {{output}} && " + "TOOL_VERSION=${tool_versions.compile_xcassets} " + "python $_tool -p $_sdk_name -t $_min_deployment_target " + - "-o {{output}} {{inputs}}" + "-T {{bundle_product_type}} -o {{output}} {{inputs}}" description = "COMPILE_XCASSETS {{output}}" pool = ":bundle_pool($default_toolchain)"
diff --git a/build/toolchain/mac/compile_xcassets.py b/build/toolchain/mac/compile_xcassets.py index 2e8c00e..ac0742e 100644 --- a/build/toolchain/mac/compile_xcassets.py +++ b/build/toolchain/mac/compile_xcassets.py
@@ -8,7 +8,17 @@ import sys -def CompileXCAssets(output, platform, min_deployment_target, inputs): +def CompileXCAssets( + output, platform, product_type, min_deployment_target, inputs): + """Compile the .xcassets bundles to an asset catalog using actool. + + Args: + output: absolute path to the containing bundle + platform: the targetted platform + product_type: the bundle type + min_deployment_target: minimum deployment target + inputs: list of absolute paths to .xcassets bundles + """ command = [ 'xcrun', 'actool', '--output-format=human-readable-text', '--compress-pngs', '--notices', '--warnings', '--errors', @@ -16,6 +26,9 @@ min_deployment_target, ] + if product_type != '': + command.extend(['--product-type', product_type]) + if platform == 'macosx': command.extend(['--target-device', 'mac']) else: @@ -67,6 +80,9 @@ '--output', '-o', required=True, help='path to the compiled assets catalog') parser.add_argument( + '--product-type', '-T', + help='type of the containing bundle') + parser.add_argument( 'inputs', nargs='+', help='path to input assets catalog sources') args = parser.parse_args() @@ -80,6 +96,7 @@ CompileXCAssets( args.output, args.platform, + args.product_type, args.minimum_deployment_target, args.inputs)
diff --git a/build/toolchain/nacl/BUILD.gn b/build/toolchain/nacl/BUILD.gn index f317108d..da2477a 100644 --- a/build/toolchain/nacl/BUILD.gn +++ b/build/toolchain/nacl/BUILD.gn
@@ -23,43 +23,42 @@ nacl_x86_glibc_rev = revisions[0] nacl_arm_glibc_rev = revisions[1] -# TODO(mcgrathr): Uncomment this when -# https://code.google.com/p/chromium/issues/detail?id=395883 is fixed. -#pnacl_newlib_rev = revisions[2] +pnacl_newlib_rev = revisions[2] + +if (host_os == "win") { + toolsuffix = ".exe" +} else { + toolsuffix = "" +} + +# The PNaCl toolchain tools are all wrapper scripts rather than binary +# executables. On POSIX systems, nobody cares what kind of executable +# file you are. But on Windows, scripts (.bat files) cannot be run +# directly and need the Windows shell (cmd.exe) specified explicily. +if (host_os == "win") { + # NOTE! The //build/toolchain/gcc_*_wrapper.py scripts recognize + # this exact prefix string, so they must be updated if this string + # is changed in any way. + scriptprefix = "cmd /c call " + scriptsuffix = ".bat" +} else { + scriptprefix = "" + scriptsuffix = "" +} + +# When the compilers are run via goma or ccache rather than directly by +# GN/Ninja, the goma/ccache wrapper handles .bat files but gets confused +# by being given the scriptprefix. +if (host_os == "win" && !use_goma && cc_wrapper == "") { + compiler_scriptprefix = scriptprefix +} else { + compiler_scriptprefix = "" +} template("pnacl_toolchain") { assert(defined(invoker.executable_extension), "Must define executable_extension") - # TODO(mcgrathr): See above. - pnacl_newlib_rev = revisions[2] - - # The PNaCl toolchain tools are all wrapper scripts rather than binary - # executables. On POSIX systems, nobody cares what kind of executable - # file you are. But on Windows, scripts (.bat files) cannot be run - # directly and need the Windows shell (cmd.exe) specified explicily. - # TODO(mcgrathr): Hoist this to top level when - # https://code.google.com/p/chromium/issues/detail?id=395883 is fixed. - if (host_os == "win") { - # NOTE! The //build/toolchain/gcc_*_wrapper.py scripts recognize - # this exact prefix string, so they must be updated if this string - # is changed in any way. - scriptprefix = "cmd /c call " - scriptsuffix = ".bat" - } else { - scriptprefix = "" - scriptsuffix = "" - } - - # When the compilers are run via goma or ccache rather than directly by - # GN/Ninja, the goma/ccache wrapper handles .bat files but gets confused - # by being given the scriptprefix. - if (host_os == "win" && !use_goma && cc_wrapper == "") { - compiler_scriptprefix = scriptprefix - } else { - compiler_scriptprefix = "" - } - nacl_toolchain(target_name) { toolchain_package = "pnacl_newlib" toolchain_revision = pnacl_newlib_rev @@ -122,14 +121,6 @@ invoker.toolchain_tuple + "-", root_build_dir) - # TODO(mcgrathr): Hoist this to top level when - # https://code.google.com/p/chromium/issues/detail?id=395883 is fixed. - if (host_os == "win") { - toolsuffix = ".exe" - } else { - toolsuffix = "" - } - nacl_toolchain("glibc_" + toolchain_cpu) { cc = toolprefix + "gcc" + toolsuffix cxx = toolprefix + "g++" + toolsuffix @@ -175,23 +166,12 @@ toolchain_cpu = target_name assert(defined(invoker.toolchain_tuple), "Must define toolchain_tuple") - # TODO(mcgrathr): See above. - pnacl_newlib_rev = revisions[2] - toolchain_package = "pnacl_newlib" toolchain_revision = pnacl_newlib_rev toolprefix = rebase_path("${nacl_toolchain_dir}/${toolchain_package}/bin/" + invoker.toolchain_tuple + "-", root_build_dir) - # TODO(mcgrathr): Hoist this to top level when - # https://code.google.com/p/chromium/issues/detail?id=395883 is fixed. - if (host_os == "win") { - toolsuffix = ".exe" - } else { - toolsuffix = "" - } - nacl_toolchain("clang_newlib_" + toolchain_cpu) { cc = toolprefix + "clang" + toolsuffix cxx = toolprefix + "clang++" + toolsuffix @@ -212,23 +192,12 @@ toolchain_cpu = target_name assert(defined(invoker.toolchain_tuple), "Must define toolchain_tuple") - # TODO(mcgrathr): See above. - pnacl_newlib_rev = revisions[2] - toolchain_package = "pnacl_newlib" toolchain_revision = pnacl_newlib_rev toolprefix = rebase_path("${nacl_toolchain_dir}/${toolchain_package}/bin/" + invoker.toolchain_tuple + "-", root_build_dir) - # TODO(mcgrathr): Hoist this to top level when - # https://code.google.com/p/chromium/issues/detail?id=395883 is fixed. - if (host_os == "win") { - toolsuffix = ".exe" - } else { - toolsuffix = "" - } - link_irt = rebase_path("//native_client/build/link_irt.py", root_build_dir) tls_edit_label =
diff --git a/build/toolchain/win/BUILD.gn b/build/toolchain/win/BUILD.gn index f46b90ff..0549a6b6 100644 --- a/build/toolchain/win/BUILD.gn +++ b/build/toolchain/win/BUILD.gn
@@ -356,12 +356,6 @@ "scope") template("win_x64_toolchains") { - # TODO(mcgrathr): These assignments are only required because of - # crbug.com/395883. Drop them if that ever gets fixed in GN. - goma_prefix = invoker.goma_prefix - x64_toolchain_data = invoker.x64_toolchain_data - clang_cl = invoker.clang_cl - msvc_toolchain(target_name) { environment = "environment.x64" cl = "${goma_prefix}\"${x64_toolchain_data.vc_bin_dir}/cl.exe\"" @@ -392,10 +386,9 @@ } win_x64_toolchains("x64") { - # TODO(mcgrathr): These assignments are only required because of - # crbug.com/395883. Drop them if that ever gets fixed in GN. - goma_prefix = goma_prefix - x64_toolchain_data = x64_toolchain_data + toolchain_args = { + # Use the defaults. + } } # The nacl_win64 toolchain is nearly identical to the plain x64 toolchain. @@ -404,12 +397,6 @@ # is_component_build to false in the toolchain_args() block, because # building nacl64.exe in component style does not work. win_x64_toolchains("nacl_win64") { - # TODO(mcgrathr): These assignments are only required because of - # crbug.com/395883. Drop them if that ever gets fixed in GN. - goma_prefix = goma_prefix - x64_toolchain_data = x64_toolchain_data - clang_cl = clang_cl - toolchain_args = { is_component_build = false }
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index 600920a7..c52a633 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -203,6 +203,8 @@ "output/buffer_to_texture_target_map.h", "output/ca_layer_overlay.cc", "output/ca_layer_overlay.h", + "output/color_lut_cache.cc", + "output/color_lut_cache.h", "output/compositor_frame.cc", "output/compositor_frame.h", "output/compositor_frame_metadata.cc",
diff --git a/cc/blink/web_content_layer_impl.cc b/cc/blink/web_content_layer_impl.cc index cf6e344d..c5068f1 100644 --- a/cc/blink/web_content_layer_impl.cc +++ b/cc/blink/web_content_layer_impl.cc
@@ -75,7 +75,7 @@ settings.use_cached_picture = UseCachedPictureRaster(); scoped_refptr<cc::DisplayItemList> display_list = - cc::DisplayItemList::Create(PaintableRegion(), settings); + cc::DisplayItemList::Create(settings); if (client_) { WebDisplayItemListImpl list(display_list.get()); client_->paintContents(&list, PaintingControlToWeb(painting_control));
diff --git a/cc/blink/web_display_item_list_impl.cc b/cc/blink/web_display_item_list_impl.cc index 7a4be016..e9935f3d 100644 --- a/cc/blink/web_display_item_list_impl.cc +++ b/cc/blink/web_display_item_list_impl.cc
@@ -22,6 +22,7 @@ #include "third_party/skia/include/core/SkColorFilter.h" #include "third_party/skia/include/core/SkMatrix44.h" #include "third_party/skia/include/core/SkPicture.h" +#include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/geometry/safe_integer_conversions.h" #include "ui/gfx/transform.h" @@ -32,8 +33,7 @@ scoped_refptr<cc::DisplayItemList> CreateUncachedDisplayItemListForBlink() { cc::DisplayItemListSettings settings; settings.use_cached_picture = false; - gfx::Rect layer_rect; - return cc::DisplayItemList::Create(layer_rect, settings); + return cc::DisplayItemList::Create(settings); } } // namespace @@ -50,13 +50,8 @@ void WebDisplayItemListImpl::appendDrawingItem( const blink::WebRect& visual_rect, sk_sp<const SkPicture> picture) { - if (display_item_list_->RetainsIndividualDisplayItems()) { - display_item_list_->CreateAndAppendDrawingItem<cc::DrawingDisplayItem>( - visual_rect, std::move(picture)); - } else { - cc::DrawingDisplayItem item(std::move(picture)); - display_item_list_->RasterIntoCanvas(item); - } + display_item_list_->CreateAndAppendDrawingItem<cc::DrawingDisplayItem>( + visual_rect, std::move(picture)); } void WebDisplayItemListImpl::appendClipItem( @@ -67,63 +62,36 @@ rounded_rects.push_back(rounded_clip_rects[i]); } bool antialias = true; - if (display_item_list_->RetainsIndividualDisplayItems()) { - display_item_list_->CreateAndAppendPairedBeginItem<cc::ClipDisplayItem>( - clip_rect, rounded_rects, antialias); - } else { - cc::ClipDisplayItem item(clip_rect, rounded_rects, antialias); - display_item_list_->RasterIntoCanvas(item); - } + display_item_list_->CreateAndAppendPairedBeginItem<cc::ClipDisplayItem>( + clip_rect, rounded_rects, antialias); } void WebDisplayItemListImpl::appendEndClipItem() { - if (display_item_list_->RetainsIndividualDisplayItems()) { - display_item_list_->CreateAndAppendPairedEndItem<cc::EndClipDisplayItem>(); - } else { - display_item_list_->RasterIntoCanvas(cc::EndClipDisplayItem()); - } + display_item_list_->CreateAndAppendPairedEndItem<cc::EndClipDisplayItem>(); } void WebDisplayItemListImpl::appendClipPathItem( const SkPath& clip_path, SkRegion::Op clip_op, bool antialias) { - if (display_item_list_->RetainsIndividualDisplayItems()) { - display_item_list_->CreateAndAppendPairedBeginItem<cc::ClipPathDisplayItem>( - clip_path, clip_op, antialias); - } else { - cc::ClipPathDisplayItem item(clip_path, clip_op, antialias); - display_item_list_->RasterIntoCanvas(item); - } + display_item_list_->CreateAndAppendPairedBeginItem<cc::ClipPathDisplayItem>( + clip_path, clip_op, antialias); } void WebDisplayItemListImpl::appendEndClipPathItem() { - if (display_item_list_->RetainsIndividualDisplayItems()) { - display_item_list_ - ->CreateAndAppendPairedEndItem<cc::EndClipPathDisplayItem>(); - } else { - display_item_list_->RasterIntoCanvas(cc::EndClipPathDisplayItem()); - } + display_item_list_ + ->CreateAndAppendPairedEndItem<cc::EndClipPathDisplayItem>(); } void WebDisplayItemListImpl::appendFloatClipItem( const blink::WebFloatRect& clip_rect) { - if (display_item_list_->RetainsIndividualDisplayItems()) { - display_item_list_ - ->CreateAndAppendPairedBeginItem<cc::FloatClipDisplayItem>(clip_rect); - } else { - cc::FloatClipDisplayItem item(clip_rect); - display_item_list_->RasterIntoCanvas(item); - } + display_item_list_->CreateAndAppendPairedBeginItem<cc::FloatClipDisplayItem>( + clip_rect); } void WebDisplayItemListImpl::appendEndFloatClipItem() { - if (display_item_list_->RetainsIndividualDisplayItems()) { - display_item_list_ - ->CreateAndAppendPairedEndItem<cc::EndFloatClipDisplayItem>(); - } else { - display_item_list_->RasterIntoCanvas(cc::EndFloatClipDisplayItem()); - } + display_item_list_ + ->CreateAndAppendPairedEndItem<cc::EndFloatClipDisplayItem>(); } void WebDisplayItemListImpl::appendTransformItem( @@ -131,22 +99,13 @@ gfx::Transform transform(gfx::Transform::kSkipInitialization); transform.matrix() = matrix; - if (display_item_list_->RetainsIndividualDisplayItems()) { - display_item_list_ - ->CreateAndAppendPairedBeginItem<cc::TransformDisplayItem>(transform); - } else { - cc::TransformDisplayItem item(transform); - display_item_list_->RasterIntoCanvas(item); - } + display_item_list_->CreateAndAppendPairedBeginItem<cc::TransformDisplayItem>( + transform); } void WebDisplayItemListImpl::appendEndTransformItem() { - if (display_item_list_->RetainsIndividualDisplayItems()) { - display_item_list_ - ->CreateAndAppendPairedEndItem<cc::EndTransformDisplayItem>(); - } else { - display_item_list_->RasterIntoCanvas(cc::EndTransformDisplayItem()); - } + display_item_list_ + ->CreateAndAppendPairedEndItem<cc::EndTransformDisplayItem>(); } void WebDisplayItemListImpl::appendCompositingItem( @@ -160,47 +119,27 @@ // value, but that breaks slimming paint reftests. const bool kLcdTextRequiresOpaqueLayer = true; - if (display_item_list_->RetainsIndividualDisplayItems()) { - display_item_list_ - ->CreateAndAppendPairedBeginItem<cc::CompositingDisplayItem>( - static_cast<uint8_t>(gfx::ToFlooredInt(255 * opacity)), xfermode, - bounds, sk_ref_sp(color_filter), kLcdTextRequiresOpaqueLayer); - } else { - cc::CompositingDisplayItem item( - static_cast<uint8_t>(gfx::ToFlooredInt(255 * opacity)), xfermode, - bounds, sk_ref_sp(color_filter), kLcdTextRequiresOpaqueLayer); - display_item_list_->RasterIntoCanvas(item); - } + display_item_list_ + ->CreateAndAppendPairedBeginItem<cc::CompositingDisplayItem>( + static_cast<uint8_t>(gfx::ToFlooredInt(255 * opacity)), xfermode, + bounds, sk_ref_sp(color_filter), kLcdTextRequiresOpaqueLayer); } void WebDisplayItemListImpl::appendEndCompositingItem() { - if (display_item_list_->RetainsIndividualDisplayItems()) { - display_item_list_ - ->CreateAndAppendPairedEndItem<cc::EndCompositingDisplayItem>(); - } else { - display_item_list_->RasterIntoCanvas(cc::EndCompositingDisplayItem()); - } + display_item_list_ + ->CreateAndAppendPairedEndItem<cc::EndCompositingDisplayItem>(); } void WebDisplayItemListImpl::appendFilterItem( const cc::FilterOperations& filters, - const blink::WebFloatRect& bounds) { - if (display_item_list_->RetainsIndividualDisplayItems()) { - display_item_list_->CreateAndAppendPairedBeginItem<cc::FilterDisplayItem>( - filters, bounds); - } else { - cc::FilterDisplayItem item(filters, bounds); - display_item_list_->RasterIntoCanvas(item); - } + const blink::WebFloatRect& filter_bounds) { + display_item_list_ + ->CreateAndAppendPairedBeginItemWithVisualRect<cc::FilterDisplayItem>( + gfx::ToEnclosingRect(filter_bounds), filters, filter_bounds); } void WebDisplayItemListImpl::appendEndFilterItem() { - if (display_item_list_->RetainsIndividualDisplayItems()) { - display_item_list_ - ->CreateAndAppendPairedEndItem<cc::EndFilterDisplayItem>(); - } else { - display_item_list_->RasterIntoCanvas(cc::EndFilterDisplayItem()); - } + display_item_list_->CreateAndAppendPairedEndItem<cc::EndFilterDisplayItem>(); } void WebDisplayItemListImpl::appendScrollItem( @@ -208,7 +147,8 @@ ScrollContainerId) { SkMatrix44 matrix(SkMatrix44::kUninitialized_Constructor); matrix.setTranslate(-scroll_offset.width, -scroll_offset.height, 0); - // TODO(wkorman): Should we translate the visual rect as well? + // TODO(wkorman): http://crbug.com/633636 Should we translate the visual rect + // as well? Create a test case and investigate. appendTransformItem(matrix); }
diff --git a/cc/blink/web_display_item_list_impl.h b/cc/blink/web_display_item_list_impl.h index 9b61e5b1..fc92f65 100644 --- a/cc/blink/web_display_item_list_impl.h +++ b/cc/blink/web_display_item_list_impl.h
@@ -62,7 +62,7 @@ SkColorFilter*) override; void appendEndCompositingItem() override; void appendFilterItem(const cc::FilterOperations& filters, - const blink::WebFloatRect& bounds) override; + const blink::WebFloatRect& filter_bounds) override; void appendEndFilterItem() override; void appendScrollItem(const blink::WebSize& scrollOffset, ScrollContainerId) override;
diff --git a/cc/cc.gyp b/cc/cc.gyp index ec0332022..96535a9 100644 --- a/cc/cc.gyp +++ b/cc/cc.gyp
@@ -287,6 +287,8 @@ 'output/filter_operations.h', 'output/geometry_binding.cc', 'output/geometry_binding.h', + 'output/gl_color_lut_cache.cc', + 'output/gl_color_lut_cache.h', 'output/gl_frame_data.cc', 'output/gl_frame_data.h', 'output/gl_renderer.cc', @@ -335,8 +337,8 @@ 'output/texture_mailbox_deleter.cc', 'output/texture_mailbox_deleter.h', 'output/vulkan_context_provider.h', - 'output/vulkan_in_process_context_provider.h', 'output/vulkan_in_process_context_provider.cc', + 'output/vulkan_in_process_context_provider.h', 'playback/clip_display_item.cc', 'playback/clip_display_item.h', 'playback/clip_path_display_item.cc',
diff --git a/cc/debug/benchmark_instrumentation.cc b/cc/debug/benchmark_instrumentation.cc index c32565e..ff221715 100644 --- a/cc/debug/benchmark_instrumentation.cc +++ b/cc/debug/benchmark_instrumentation.cc
@@ -13,10 +13,9 @@ // The benchmarks search for events and their arguments by name. void IssueImplThreadRenderingStatsEvent(const RenderingStats& stats) { - TRACE_EVENT_INSTANT1("benchmark", - "BenchmarkInstrumentation::ImplThreadRenderingStats", - TRACE_EVENT_SCOPE_THREAD, - "data", stats.AsTraceableData()); + TRACE_EVENT_INSTANT1( + "benchmark,rail", "BenchmarkInstrumentation::ImplThreadRenderingStats", + TRACE_EVENT_SCOPE_THREAD, "data", stats.AsTraceableData()); } void IssueDisplayRenderingStatsEvent() {
diff --git a/cc/debug/rasterize_and_record_benchmark.cc b/cc/debug/rasterize_and_record_benchmark.cc index 5babc0e..4e401323 100644 --- a/cc/debug/rasterize_and_record_benchmark.cc +++ b/cc/debug/rasterize_and_record_benchmark.cc
@@ -161,7 +161,7 @@ if (display_list->ShouldBeAnalyzedForSolidColor()) { gfx::Size layer_size = layer->paint_properties().bounds; skia::AnalysisCanvas canvas(layer_size.width(), layer_size.height()); - display_list->Raster(&canvas, nullptr, gfx::Rect(), 1.f); + display_list->Raster(&canvas, nullptr, gfx::Rect(layer_size), 1.f); } if (memory_used) {
diff --git a/cc/debug/rasterize_and_record_benchmark.h b/cc/debug/rasterize_and_record_benchmark.h index f68b566..f52b838d 100644 --- a/cc/debug/rasterize_and_record_benchmark.h +++ b/cc/debug/rasterize_and_record_benchmark.h
@@ -16,7 +16,6 @@ #include "base/time/time.h" #include "cc/debug/micro_benchmark_controller.h" #include "cc/playback/recording_source.h" -#include "ui/gfx/geometry/rect.h" namespace base { class DictionaryValue; @@ -26,6 +25,7 @@ class LayerTreeHost; class Layer; + class RasterizeAndRecordBenchmark : public MicroBenchmark { public: explicit RasterizeAndRecordBenchmark(
diff --git a/cc/input/input_handler.h b/cc/input/input_handler.h index 11a3310..bd11a62 100644 --- a/cc/input/input_handler.h +++ b/cc/input/input_handler.h
@@ -198,6 +198,12 @@ virtual ScrollElasticityHelper* CreateScrollElasticityHelper() = 0; + // Called by the single-threaded UI Compositor to get or set the scroll offset + // on the impl side. Retruns false if |layer_id| isn't in the active tree. + virtual bool GetScrollOffsetForLayer(int layer_id, + gfx::ScrollOffset* offset) = 0; + virtual bool ScrollLayerTo(int layer_id, const gfx::ScrollOffset& offset) = 0; + protected: InputHandler() {} virtual ~InputHandler() {}
diff --git a/cc/ipc/cc_param_traits.cc b/cc/ipc/cc_param_traits.cc index 26176cc..6d7eb529 100644 --- a/cc/ipc/cc_param_traits.cc +++ b/cc/ipc/cc_param_traits.cc
@@ -885,6 +885,7 @@ GetParamSize(s, p.ya_tex_size); GetParamSize(s, p.uv_tex_size); GetParamSize(s, p.color_space); + GetParamSize(s, p.video_color_space); GetParamSize(s, p.resource_offset); GetParamSize(s, p.resource_multiplier); GetParamSize(s, p.bits_per_channel); @@ -898,6 +899,7 @@ WriteParam(m, p.ya_tex_size); WriteParam(m, p.uv_tex_size); WriteParam(m, p.color_space); + WriteParam(m, p.video_color_space); WriteParam(m, p.resource_offset); WriteParam(m, p.resource_multiplier); WriteParam(m, p.bits_per_channel); @@ -912,6 +914,7 @@ ReadParam(m, iter, &p->ya_tex_size) && ReadParam(m, iter, &p->uv_tex_size) && ReadParam(m, iter, &p->color_space) && + ReadParam(m, iter, &p->video_color_space) && ReadParam(m, iter, &p->resource_offset) && ReadParam(m, iter, &p->resource_multiplier) && ReadParam(m, iter, &p->bits_per_channel) && @@ -934,6 +937,8 @@ l->append(", "); LogParam(p.color_space, l); l->append(", "); + LogParam(p.video_color_space, l); + l->append(", "); LogParam(p.resource_offset, l); l->append(", "); LogParam(p.resource_multiplier, l);
diff --git a/cc/ipc/cc_param_traits_unittest.cc b/cc/ipc/cc_param_traits_unittest.cc index 81c818f..00a7fee4 100644 --- a/cc/ipc/cc_param_traits_unittest.cc +++ b/cc/ipc/cc_param_traits_unittest.cc
@@ -263,6 +263,7 @@ SkScalar arbitrary_sigma = SkFloatToScalar(2.0f); YUVVideoDrawQuad::ColorSpace arbitrary_color_space = YUVVideoDrawQuad::REC_601; + gfx::ColorSpace arbitrary_video_color_space = gfx::ColorSpace::CreateREC601(); RenderPassId child_id(30, 5); RenderPassId root_id(10, 14); @@ -390,7 +391,8 @@ arbitrary_rect1_inside_rect1, arbitrary_bool1, arbitrary_rectf1, arbitrary_rectf2, arbitrary_size1, arbitrary_size2, arbitrary_resourceid1, arbitrary_resourceid2, arbitrary_resourceid3, arbitrary_resourceid4, - arbitrary_color_space, arbitrary_float1, arbitrary_float2, arbitrary_int); + arbitrary_color_space, arbitrary_video_color_space, arbitrary_float1, + arbitrary_float2, arbitrary_int); pass_cmp->CopyFromAndAppendDrawQuad(yuvvideo_in, yuvvideo_in->shared_quad_state);
diff --git a/cc/ipc/struct_traits_unittest.cc b/cc/ipc/struct_traits_unittest.cc index b66aa8c..f345087d 100644 --- a/cc/ipc/struct_traits_unittest.cc +++ b/cc/ipc/struct_traits_unittest.cc
@@ -878,6 +878,7 @@ const uint32_t v_plane_resource_id = 2468; const uint32_t a_plane_resource_id = 7890; const YUVVideoDrawQuad::ColorSpace color_space = YUVVideoDrawQuad::JPEG; + const gfx::ColorSpace video_color_space = gfx::ColorSpace::CreateJpeg(); const float resource_offset = 1337.5f; const float resource_multiplier = 1234.6f; const uint32_t bits_per_channel = 13; @@ -888,8 +889,8 @@ quad->SetAll(sqs, rect, opaque_rect, visible_rect, needs_blending, ya_tex_coord_rect, uv_tex_coord_rect, ya_tex_size, uv_tex_size, y_plane_resource_id, u_plane_resource_id, v_plane_resource_id, - a_plane_resource_id, color_space, resource_offset, - resource_multiplier, bits_per_channel); + a_plane_resource_id, color_space, video_color_space, + resource_offset, resource_multiplier, bits_per_channel); mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy(); std::unique_ptr<RenderPass> output;
diff --git a/cc/layers/empty_content_layer_client.cc b/cc/layers/empty_content_layer_client.cc index 1eac1a18..982e8f0c 100644 --- a/cc/layers/empty_content_layer_client.cc +++ b/cc/layers/empty_content_layer_client.cc
@@ -31,7 +31,7 @@ scoped_refptr<DisplayItemList> EmptyContentLayerClient::PaintContentsToDisplayList( PaintingControlSetting painting_status) { - return DisplayItemList::Create(gfx::Rect(), DisplayItemListSettings()); + return DisplayItemList::Create(DisplayItemListSettings()); } bool EmptyContentLayerClient::FillsBoundsCompletely() const {
diff --git a/cc/layers/heads_up_display_layer_impl.cc b/cc/layers/heads_up_display_layer_impl.cc index 1b62f08..176aa532 100644 --- a/cc/layers/heads_up_display_layer_impl.cc +++ b/cc/layers/heads_up_display_layer_impl.cc
@@ -96,9 +96,9 @@ std::unique_ptr<ScopedResource> resource = ScopedResource::Create(resource_provider); - resource->Allocate(internal_content_bounds_, - ResourceProvider::TEXTURE_HINT_IMMUTABLE, - resource_provider->best_texture_format()); + resource->Allocate( + internal_content_bounds_, ResourceProvider::TEXTURE_HINT_IMMUTABLE, + resource_provider->best_texture_format(), gfx::ColorSpace()); resources_.push_back(std::move(resource)); }
diff --git a/cc/layers/picture_image_layer.cc b/cc/layers/picture_image_layer.cc index 8ce991e5..33e617d 100644 --- a/cc/layers/picture_image_layer.cc +++ b/cc/layers/picture_image_layer.cc
@@ -66,7 +66,7 @@ settings.use_cached_picture = layer_tree_host()->settings().use_cached_picture_raster; scoped_refptr<DisplayItemList> display_list = - DisplayItemList::Create(PaintableRegion(), settings); + DisplayItemList::Create(settings); SkPictureRecorder recorder; SkCanvas* canvas =
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index b3bf1e6..c8b45b7 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc
@@ -56,6 +56,25 @@ // width and height should be an even multiple of 4 in size. const int kTileMinimalAlignment = 4; +// Intersect rects which may have right() and bottom() that overflow integer +// boundaries. This code is similar to gfx::Rect::Intersect with the exception +// that the types are promoted to int64_t when there is a chance of overflow. +gfx::Rect SafeIntersectRects(const gfx::Rect& one, const gfx::Rect& two) { + if (one.IsEmpty() || two.IsEmpty()) + return gfx::Rect(); + + int rx = std::max(one.x(), two.x()); + int ry = std::max(one.y(), two.y()); + int64_t rr = std::min(static_cast<int64_t>(one.x()) + one.width(), + static_cast<int64_t>(two.x()) + two.width()); + int64_t rb = std::min(static_cast<int64_t>(one.y()) + one.height(), + static_cast<int64_t>(two.y()) + two.height()); + if (rx > rr || ry > rb) + return gfx::Rect(); + return gfx::Rect(rx, ry, static_cast<int>(rr - rx), + static_cast<int>(rb - ry)); +} + } // namespace namespace cc { @@ -292,8 +311,10 @@ if (visible_geometry_rect.IsEmpty()) continue; - append_quads_data->visible_layer_area += - visible_geometry_rect.width() * visible_geometry_rect.height(); + int64_t visible_geometry_area = + static_cast<int64_t>(visible_geometry_rect.width()) * + visible_geometry_rect.height(); + append_quads_data->visible_layer_area += visible_geometry_area; bool has_draw_quad = false; if (*iter && iter->draw_info().IsReadyToDraw()) { @@ -357,10 +378,8 @@ append_quads_data->num_missing_tiles++; ++missing_tile_count; } - int64_t checkerboarded_area = - visible_geometry_rect.width() * visible_geometry_rect.height(); append_quads_data->checkerboarded_visible_content_area += - checkerboarded_area; + visible_geometry_area; // Intersect checkerboard rect with interest rect to generate rect where // we checkerboarded and has recording. The area where we don't have // recording is not necessarily a Rect, and its area is calculated using @@ -368,18 +387,18 @@ gfx::Rect visible_rect_has_recording = visible_geometry_rect; visible_rect_has_recording.Intersect(scaled_recorded_viewport); int64_t checkerboarded_has_recording_area = - visible_rect_has_recording.width() * + static_cast<int64_t>(visible_rect_has_recording.width()) * visible_rect_has_recording.height(); append_quads_data->checkerboarded_needs_raster_content_area += checkerboarded_has_recording_area; append_quads_data->checkerboarded_no_recording_content_area += - checkerboarded_area - checkerboarded_has_recording_area; + visible_geometry_area - checkerboarded_has_recording_area; continue; } if (iter.resolution() != HIGH_RESOLUTION) { append_quads_data->approximated_visible_content_area += - visible_geometry_rect.width() * visible_geometry_rect.height(); + visible_geometry_area; } // If we have a draw quad, but it's not low resolution, then @@ -515,7 +534,8 @@ .skewport_extrapolation_limit_in_screen_pixels * MaximumTilingContentsScale(); padded_bounds.Inset(-padding_amount, -padding_amount); - visible_rect_in_content_space.Intersect(padded_bounds); + visible_rect_in_content_space = + SafeIntersectRects(visible_rect_in_content_space, padded_bounds); } } viewport_rect_for_tile_priority_in_content_space_ =
diff --git a/cc/layers/picture_layer_impl_unittest.cc b/cc/layers/picture_layer_impl_unittest.cc index a35faf5..3e0d734 100644 --- a/cc/layers/picture_layer_impl_unittest.cc +++ b/cc/layers/picture_layer_impl_unittest.cc
@@ -270,7 +270,7 @@ void SetInitialDeviceScaleFactor(float device_scale_factor) { // Device scale factor is a per-tree property. However, tests can't directly // set the pending tree's device scale factor before the pending tree is - // created, and setting it after SetupPendingTreeis too late, since + // created, and setting it after SetupPendingTree is too late, since // draw properties will already have been updated on the tree. To handle // this, we initially set only the active tree's device scale factor, and we // copy this over to the pending tree inside SetupPendingTree.
diff --git a/cc/layers/render_surface_impl.cc b/cc/layers/render_surface_impl.cc index 264a6de..68c4543d 100644 --- a/cc/layers/render_surface_impl.cc +++ b/cc/layers/render_surface_impl.cc
@@ -171,6 +171,10 @@ return OwningEffectNode()->filters; } +gfx::Transform RenderSurfaceImpl::FiltersTransform() const { + return owning_layer_->DrawTransform(); +} + const FilterOperations& RenderSurfaceImpl::BackgroundFilters() const { return OwningEffectNode()->background_filters; }
diff --git a/cc/layers/render_surface_impl.h b/cc/layers/render_surface_impl.h index 1af8f81..82cec95 100644 --- a/cc/layers/render_surface_impl.h +++ b/cc/layers/render_surface_impl.h
@@ -156,6 +156,7 @@ const FilterOperations& Filters() const; const FilterOperations& BackgroundFilters() const; + gfx::Transform FiltersTransform() const; bool HasCopyRequest() const;
diff --git a/cc/layers/surface_layer.cc b/cc/layers/surface_layer.cc index 5dbc7a2f..989f90c 100644 --- a/cc/layers/surface_layer.cc +++ b/cc/layers/surface_layer.cc
@@ -28,8 +28,9 @@ metadata->satisfies_sequences.push_back(sequence_.sequence); } - void DidNotSwap(DidNotSwapReason reason) override { + DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override { satisfy_callback_.Run(sequence_); + return DidNotSwapAction::BREAK_PROMISE; } int64_t TraceId() const override { return 0; }
diff --git a/cc/layers/texture_layer_impl.cc b/cc/layers/texture_layer_impl.cc index 200dad4a26..1d5ab16 100644 --- a/cc/layers/texture_layer_impl.cc +++ b/cc/layers/texture_layer_impl.cc
@@ -111,7 +111,8 @@ if (!texture_copy_->id()) { texture_copy_->Allocate(texture_mailbox_.size_in_pixels(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, - resource_provider->best_texture_format()); + resource_provider->best_texture_format(), + gfx::ColorSpace()); } if (texture_copy_->id()) {
diff --git a/cc/layers/video_layer_impl.cc b/cc/layers/video_layer_impl.cc index 98e82093..2e5d25f 100644 --- a/cc/layers/video_layer_impl.cc +++ b/cc/layers/video_layer_impl.cc
@@ -19,6 +19,7 @@ #include "cc/trees/occlusion.h" #include "cc/trees/task_runner_provider.h" #include "media/base/video_frame.h" +#include "ui/gfx/color_space.h" #if defined(VIDEO_HOLE) #include "cc/quads/solid_color_draw_quad.h" @@ -284,8 +285,8 @@ frame_resources_.size() > 2 ? frame_resources_[2].id : frame_resources_[1].id, frame_resources_.size() > 3 ? frame_resources_[3].id : 0, color_space, - frame_resource_offset_, frame_resource_multiplier_, - frame_bits_per_channel_); + frame_->ColorSpace(), frame_resource_offset_, + frame_resource_multiplier_, frame_bits_per_channel_); ValidateQuadResources(yuv_video_quad); break; }
diff --git a/cc/output/ca_layer_overlay.cc b/cc/output/ca_layer_overlay.cc index 8c06814e..dabfc1e 100644 --- a/cc/output/ca_layer_overlay.cc +++ b/cc/output/ca_layer_overlay.cc
@@ -17,6 +17,8 @@ namespace { +bool g_allow_rpdq_quad_conversion = false; + // This enum is used for histogram states and should only have new values added // to the end before COUNT. enum CALayerResult { @@ -82,7 +84,11 @@ ca_layer_overlay->rpdq = quad; ca_layer_overlay->contents_rect = gfx::RectF(0, 0, 1, 1); - return CA_LAYER_SUCCESS; + // TODO(erikchen): Enable this when RenderPassDrawQuad promotion to CALayer + // is fully functional. https://crbug.com/581526. + if (g_allow_rpdq_quad_conversion) + return CA_LAYER_SUCCESS; + return CA_LAYER_FAILED_RENDER_PASS; } CALayerResult FromStreamVideoQuad(ResourceProvider* resource_provider, @@ -298,4 +304,8 @@ return true; } +void EnableRenderPassDrawQuadForTesting() { + g_allow_rpdq_quad_conversion = true; +} + } // namespace cc
diff --git a/cc/output/ca_layer_overlay.h b/cc/output/ca_layer_overlay.h index 34eb054e..17b4be22 100644 --- a/cc/output/ca_layer_overlay.h +++ b/cc/output/ca_layer_overlay.h
@@ -77,6 +77,9 @@ const QuadList& quad_list, CALayerOverlayList* ca_layer_overlays); +// Allows RenderPassDrawQuads to be converted to CALayerOverlays. +void CC_EXPORT EnableRenderPassDrawQuadForTesting(); + } // namespace cc #endif // CC_OUTPUT_CA_LAYER_OVERLAY_H_
diff --git a/cc/output/color_lut_cache.cc b/cc/output/color_lut_cache.cc new file mode 100644 index 0000000..6b7a5993 --- /dev/null +++ b/cc/output/color_lut_cache.cc
@@ -0,0 +1,109 @@ +// Copyright 2016 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 "cc/output/color_lut_cache.h" + +#include <stdint.h> +#include <cmath> +#include <vector> + +#include "gpu/command_buffer/client/gles2_interface.h" +#include "ui/gfx/color_transform.h" + +// After a LUT has not been used for this many frames, we release it. +const uint32_t kMaxFramesUnused = 10; + +ColorLUTCache::ColorLUTCache(gpu::gles2::GLES2Interface* gl) + : lut_cache_(0), gl_(gl) {} + +ColorLUTCache::~ColorLUTCache() { + GLuint textures[10]; + size_t n = 0; + for (const auto& cache_entry : lut_cache_) { + textures[n++] = cache_entry.second.first; + if (n == arraysize(textures)) { + gl_->DeleteTextures(n, textures); + n = 0; + } + } + if (n) + gl_->DeleteTextures(n, textures); +} + +namespace { + +unsigned char FloatToLUT(float f) { + return std::min<int>(255, std::max<int>(0, floorf(f * 255.0f + 0.5f))); +} +}; + +unsigned int ColorLUTCache::MakeLUT(const gfx::ColorSpace& from, + gfx::ColorSpace to, + int lut_samples) { + if (to == gfx::ColorSpace()) { + to = gfx::ColorSpace::CreateSRGB(); + } + std::unique_ptr<gfx::ColorTransform> transform( + gfx::ColorTransform::NewColorTransform( + from, to, gfx::ColorTransform::Intent::PERCEPTUAL)); + + int lut_entries = lut_samples * lut_samples * lut_samples; + float inverse = 1.0f / (lut_samples - 1); + std::vector<unsigned char> lut(lut_entries * 4); + std::vector<gfx::ColorTransform::TriStim> samples(lut_samples * 3); + unsigned char* lutp = lut.data(); + for (int y = 0; y < lut_samples; y++) { + for (int v = 0; v < lut_samples; v++) { + for (int u = 0; u < lut_samples; u++) { + samples[u].set_x(y * inverse); + samples[u].set_y(u * inverse); + samples[u].set_z(v * inverse); + } + transform->transform(samples.data(), samples.size()); + for (int u = 0; u < lut_samples; u++) { + *(lutp++) = FloatToLUT(samples[u].x()); + *(lutp++) = FloatToLUT(samples[u].y()); + *(lutp++) = FloatToLUT(samples[u].z()); + *(lutp++) = 255; // alpha + } + } + } + + unsigned int lut_texture; + gl_->GenTextures(1, &lut_texture); + gl_->BindTexture(GL_TEXTURE_2D, lut_texture); + gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + gl_->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lut_samples, + lut_samples * lut_samples, 0, GL_RGBA, GL_UNSIGNED_BYTE, + lut.data()); + return lut_texture; +} + +unsigned int ColorLUTCache::GetLUT(const gfx::ColorSpace& from, + const gfx::ColorSpace& to, + int lut_samples) { + CacheKey key(from, std::make_pair(to, lut_samples)); + auto iter = lut_cache_.Get(key); + if (iter != lut_cache_.end()) { + iter->second.second = current_frame_; + return iter->second.first; + } + + unsigned int lut = MakeLUT(from, to, lut_samples); + lut_cache_.Put(key, std::make_pair(lut, current_frame_)); + return lut; +} + +void ColorLUTCache::Swap() { + current_frame_++; + while (!lut_cache_.empty() && + current_frame_ - lut_cache_.rbegin()->second.first > + kMaxFramesUnused) { + gl_->DeleteTextures(1, &lut_cache_.rbegin()->second.first); + lut_cache_.ShrinkToSize(lut_cache_.size() - 1); + } +}
diff --git a/cc/output/color_lut_cache.h b/cc/output/color_lut_cache.h new file mode 100644 index 0000000..7d5effc --- /dev/null +++ b/cc/output/color_lut_cache.h
@@ -0,0 +1,45 @@ +// Copyright 2016 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_OUTPUT_COLOR_LUT_CACHE_H_ +#define CC_OUTPUT_COLOR_LUT_CACHE_H_ + +#include <map> + +#include "base/containers/mru_cache.h" +#include "base/macros.h" +#include "ui/gfx/color_space.h" + +namespace gpu { +namespace gles2 { +class GLES2Interface; +} +} + +class ColorLUTCache { + public: + explicit ColorLUTCache(gpu::gles2::GLES2Interface* gl); + ~ColorLUTCache(); + + unsigned int GetLUT(const gfx::ColorSpace& from, + const gfx::ColorSpace& to, + int lut_samples); + + // End of frame, assume all LUTs handed out are no longer used. + void Swap(); + + private: + unsigned int MakeLUT(const gfx::ColorSpace& from, + gfx::ColorSpace to, + int lut_samples); + typedef std::pair<gfx::ColorSpace, std::pair<gfx::ColorSpace, size_t>> + CacheKey; + + base::MRUCache<CacheKey, std::pair<unsigned int, size_t>> lut_cache_; + uint32_t current_frame_; + gpu::gles2::GLES2Interface* gl_; + DISALLOW_COPY_AND_ASSIGN(ColorLUTCache); +}; + +#endif // CC_OUTPUT_COLOR_LUT_CACHE_H_
diff --git a/cc/output/delegating_renderer.h b/cc/output/delegating_renderer.h index 79ed3c1..aed70f3 100644 --- a/cc/output/delegating_renderer.h +++ b/cc/output/delegating_renderer.h
@@ -33,8 +33,6 @@ const gfx::Rect& device_viewport_rect, const gfx::Rect& device_clip_rect) override; - void Finish() override {} - void SwapBuffers(CompositorFrameMetadata metadata) override; void ReclaimResources(const ReturnedResourceArray&) override;
diff --git a/cc/output/direct_renderer.cc b/cc/output/direct_renderer.cc index 61865b1d..a6de95e 100644 --- a/cc/output/direct_renderer.cc +++ b/cc/output/direct_renderer.cc
@@ -552,7 +552,8 @@ if (!texture->id()) { texture->Allocate(size, ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER, - resource_provider_->best_texture_format()); + resource_provider_->best_texture_format(), + output_surface_->device_color_space()); } DCHECK(texture->id());
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index 11db994..48611c4 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc
@@ -14,6 +14,7 @@ #include <string> #include <vector> +#include "base/feature_list.h" #include "base/logging.h" #include "base/macros.h" #include "base/memory/ptr_util.h" @@ -48,6 +49,7 @@ #include "gpu/command_buffer/client/context_support.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/common/gpu_memory_allocation.h" +#include "media/base/media_switches.h" #include "skia/ext/texture_handle.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkColor.h" @@ -57,6 +59,7 @@ #include "third_party/skia/include/gpu/GrContext.h" #include "third_party/skia/include/gpu/gl/GrGLInterface.h" #include "third_party/skia/include/gpu/gl/GrGLTypes.h" +#include "ui/gfx/color_space.h" #include "ui/gfx/geometry/quad_f.h" #include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/skia_util.h" @@ -386,7 +389,8 @@ use_sync_query_(false), gl_composited_texture_quad_border_( settings->gl_composited_texture_quad_border), - bound_geometry_(NO_BINDING) { + bound_geometry_(NO_BINDING), + color_lut_cache_(gl_) { DCHECK(gl_); DCHECK(context_support_); @@ -889,9 +893,10 @@ std::unique_ptr<ScopedResource> device_background_texture = ScopedResource::Create(resource_provider_); // CopyTexImage2D fails when called on a texture having immutable storage. - device_background_texture->Allocate( - bounding_rect.size(), ResourceProvider::TEXTURE_HINT_DEFAULT, - resource_provider_->best_texture_format()); + device_background_texture->Allocate(bounding_rect.size(), + ResourceProvider::TEXTURE_HINT_DEFAULT, + resource_provider_->best_texture_format(), + output_surface_->device_color_space()); { ResourceProvider::ScopedWriteLockGL lock( resource_provider_, device_background_texture->id(), false); @@ -1035,7 +1040,8 @@ TileDrawQuad* tile_quad = &bypass->second; // RGBA_8888 here is arbitrary and unused. Resource tile_resource(tile_quad->resource_id(), tile_quad->texture_size, - ResourceFormat::RGBA_8888); + ResourceFormat::RGBA_8888, + output_surface_->device_color_space()); // The projection matrix used by GLRenderer has a flip. As tile texture // inputs are oriented opposite to framebuffer outputs, don't flip via // texture coords and let the projection matrix naturallyd o it. @@ -2198,7 +2204,8 @@ bool use_alpha_plane = quad->a_plane_resource_id() != 0; bool use_nv12 = quad->v_plane_resource_id() == quad->u_plane_resource_id(); - + bool use_color_lut = + base::FeatureList::IsEnabled(media::kVideoColorManagement); DCHECK(!(use_nv12 && use_alpha_plane)); ResourceProvider::ScopedSamplerGL y_plane_lock( @@ -2237,11 +2244,14 @@ int v_texture_location = -1; int uv_texture_location = -1; int a_texture_location = -1; + int lut_texture_location = -1; int yuv_matrix_location = -1; int yuv_adj_location = -1; int alpha_location = -1; + int resource_multiplier_location = -1; + int resource_offset_location = -1; const VideoYUVProgram* program = GetVideoYUVProgram( - tex_coord_precision, sampler, use_alpha_plane, use_nv12); + tex_coord_precision, sampler, use_alpha_plane, use_nv12, use_color_lut); DCHECK(program && (program->initialized() || IsContextLost())); SetUseProgram(program->program()); matrix_location = program->vertex_shader().matrix_location(); @@ -2254,11 +2264,16 @@ v_texture_location = program->fragment_shader().v_texture_location(); uv_texture_location = program->fragment_shader().uv_texture_location(); a_texture_location = program->fragment_shader().a_texture_location(); + lut_texture_location = program->fragment_shader().lut_texture_location(); yuv_matrix_location = program->fragment_shader().yuv_matrix_location(); yuv_adj_location = program->fragment_shader().yuv_adj_location(); ya_clamp_rect_location = program->fragment_shader().ya_clamp_rect_location(); uv_clamp_rect_location = program->fragment_shader().uv_clamp_rect_location(); alpha_location = program->fragment_shader().alpha_location(); + resource_multiplier_location = + program->fragment_shader().resource_multiplier_location(); + resource_offset_location = + program->fragment_shader().resource_offset_location(); gfx::SizeF ya_tex_scale(1.0f, 1.0f); gfx::SizeF uv_tex_scale(1.0f, 1.0f); @@ -2383,13 +2398,35 @@ quad->resource_offset; } + if (lut_texture_location != -1) { + unsigned int lut_texture = color_lut_cache_.GetLUT( + quad->video_color_space, output_surface_->device_color_space(), 32); + gl_->ActiveTexture(GL_TEXTURE5); + gl_->BindTexture(GL_TEXTURE_2D, lut_texture); + gl_->Uniform1i(lut_texture_location, 5); + gl_->ActiveTexture(GL_TEXTURE0); + } + + if (resource_multiplier_location != -1) { + gl_->Uniform1f(resource_multiplier_location, quad->resource_multiplier); + } + + if (resource_offset_location != -1) { + gl_->Uniform1f(resource_offset_location, quad->resource_offset); + } + // The transform and vertex data are used to figure out the extents that the // un-antialiased quad should have and which vertex this is and the float // quad passed in via uniform is the actual geometry that gets used to draw // it. This is why this centered rect is used and not the original quad_rect. auto tile_rect = gfx::RectF(quad->rect); - gl_->UniformMatrix3fv(yuv_matrix_location, 1, 0, yuv_to_rgb_multiplied); - gl_->Uniform3fv(yuv_adj_location, 1, yuv_adjust_with_offset); + if (yuv_matrix_location != -1) { + gl_->UniformMatrix3fv(yuv_matrix_location, 1, 0, yuv_to_rgb_multiplied); + } + + if (yuv_adj_location) { + gl_->Uniform3fv(yuv_adj_location, 1, yuv_adjust_with_offset); + } SetShaderOpacity(quad->shared_quad_state->opacity, alpha_location); if (!clip_region) { @@ -2847,11 +2884,6 @@ gl_->DrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); } -void GLRenderer::Finish() { - TRACE_EVENT0("cc", "GLRenderer::Finish"); - gl_->Finish(); -} - void GLRenderer::SwapBuffers(CompositorFrameMetadata metadata) { DCHECK(!is_backbuffer_discarded_); @@ -2941,6 +2973,7 @@ swapped_and_acked_overlay_resources_.erase(response.texture); } } + color_lut_cache_.Swap(); } void GLRenderer::EnforceMemoryPolicy() { @@ -3632,16 +3665,19 @@ TexCoordPrecision precision, SamplerType sampler, bool use_alpha_plane, - bool use_nv12) { + bool use_nv12, + bool use_color_lut) { DCHECK_GE(precision, 0); DCHECK_LE(precision, LAST_TEX_COORD_PRECISION); DCHECK_GE(sampler, 0); DCHECK_LE(sampler, LAST_SAMPLER_TYPE); VideoYUVProgram* program = - &video_yuv_program_[precision][sampler][use_alpha_plane][use_nv12]; + &video_yuv_program_[precision][sampler][use_alpha_plane][use_nv12] + [use_color_lut]; if (!program->initialized()) { TRACE_EVENT0("cc", "GLRenderer::videoYUVProgram::initialize"); - program->mutable_fragment_shader()->SetFeatures(use_alpha_plane, use_nv12); + program->mutable_fragment_shader()->SetFeatures(use_alpha_plane, use_nv12, + use_color_lut); program->Initialize(output_surface_->context_provider(), precision, sampler); } @@ -3685,7 +3721,9 @@ for (int k = 0; k < 2; k++) { for (int l = 0; l < 2; l++) { - video_yuv_program_[i][j][k][l].Cleanup(gl_); + for (int m = 0; m < 2; m++) { + video_yuv_program_[i][j][k][l][m].Cleanup(gl_); + } } } } @@ -3764,6 +3802,10 @@ } void GLRenderer::ScheduleCALayers(DrawingFrame* frame) { + if (overlay_resource_pool_) { + overlay_resource_pool_->CheckBusyResources(); + } + scoped_refptr<CALayerOverlaySharedState> shared_state; size_t copied_render_pass_count = 0; for (const CALayerOverlay& ca_layer_overlay : frame->ca_layer_overlay_list) { @@ -3942,7 +3984,7 @@ // Establish destination texture. *resource = overlay_resource_pool_->AcquireResource( gfx::Size(updated_dst_rect.width(), updated_dst_rect.height()), - ResourceFormat::RGBA_8888); + ResourceFormat::RGBA_8888, output_surface_->device_color_space()); ResourceProvider::ScopedWriteLockGL destination(resource_provider_, (*resource)->id(), false); GLuint temp_fbo;
diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h index 0eb8426d..9ddfd16 100644 --- a/cc/output/gl_renderer.h +++ b/cc/output/gl_renderer.h
@@ -11,6 +11,7 @@ #include "base/cancelable_callback.h" #include "base/macros.h" #include "cc/base/cc_export.h" +#include "cc/output/color_lut_cache.h" #include "cc/output/direct_renderer.h" #include "cc/output/gl_renderer_draw_cache.h" #include "cc/output/program_binding.h" @@ -60,9 +61,6 @@ const RendererCapabilitiesImpl& Capabilities() const override; - // Waits for rendering to finish. - void Finish() override; - void SwapBuffers(CompositorFrameMetadata metadata) override; void SwapBuffersComplete() override; @@ -426,7 +424,8 @@ const VideoYUVProgram* GetVideoYUVProgram(TexCoordPrecision precision, SamplerType sampler, bool use_alpha_texture, - bool use_nv12); + bool use_nv12, + bool use_color_lut); const VideoStreamTextureProgram* GetVideoStreamTextureProgram( TexCoordPrecision precision); @@ -492,7 +491,7 @@ [LAST_MASK_VALUE + 1]; VideoYUVProgram video_yuv_program_[LAST_TEX_COORD_PRECISION + 1] - [LAST_SAMPLER_TYPE + 1][2][2]; + [LAST_SAMPLER_TYPE + 1][2][2][2]; VideoStreamTextureProgram video_stream_texture_program_[LAST_TEX_COORD_PRECISION + 1]; @@ -550,6 +549,7 @@ bool force_drawing_frame_framebuffer_unflipped_ = false; BoundGeometry bound_geometry_; + ColorLUTCache color_lut_cache_; DISALLOW_COPY_AND_ASSIGN(GLRenderer); };
diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc index b596162..b461c21 100644 --- a/cc/output/gl_renderer_unittest.cc +++ b/cc/output/gl_renderer_unittest.cc
@@ -185,8 +185,10 @@ renderer()->GetTileProgramSwizzleAA(precision, sampler)); for (int j = 0; j < 2; j++) { for (int k = 0; k < 2; k++) { - EXPECT_PROGRAM_VALID( - renderer()->GetVideoYUVProgram(precision, sampler, j, k)); + for (int l = 0; l < 2; l++) { + EXPECT_PROGRAM_VALID( + renderer()->GetVideoYUVProgram(precision, sampler, j, k, l)); + } } } } @@ -1364,7 +1366,7 @@ ResourceId mask = resource_provider_->CreateResource( gfx::Size(20, 12), ResourceProvider::TEXTURE_HINT_IMMUTABLE, - resource_provider_->best_texture_format()); + resource_provider_->best_texture_format(), gfx::ColorSpace()); resource_provider_->AllocateForTesting(mask); SkScalar matrix[20];
diff --git a/cc/output/latency_info_swap_promise.cc b/cc/output/latency_info_swap_promise.cc index f20eb2d4..96e08fc 100644 --- a/cc/output/latency_info_swap_promise.cc +++ b/cc/output/latency_info_swap_promise.cc
@@ -40,12 +40,14 @@ metadata->latency_info.push_back(latency_); } -void LatencyInfoSwapPromise::DidNotSwap(DidNotSwapReason reason) { +SwapPromise::DidNotSwapAction LatencyInfoSwapPromise::DidNotSwap( + DidNotSwapReason reason) { latency_.AddLatencyNumber(DidNotSwapReasonToLatencyComponentType(reason), 0, 0); // TODO(miletus): Turn this back on once per-event LatencyInfo tracking // is enabled in GPU side. // DCHECK(latency_.terminated); + return DidNotSwapAction::BREAK_PROMISE; } int64_t LatencyInfoSwapPromise::TraceId() const {
diff --git a/cc/output/latency_info_swap_promise.h b/cc/output/latency_info_swap_promise.h index 23a1c862..bc4916e 100644 --- a/cc/output/latency_info_swap_promise.h +++ b/cc/output/latency_info_swap_promise.h
@@ -20,7 +20,7 @@ void DidActivate() override {} void DidSwap(CompositorFrameMetadata* metadata) override; - void DidNotSwap(DidNotSwapReason reason) override; + DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override; void OnCommit() override; int64_t TraceId() const override;
diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc index 21277b8f..e7cc4d38 100644 --- a/cc/output/output_surface.cc +++ b/cc/output/output_surface.cc
@@ -217,6 +217,7 @@ float scale_factor, const gfx::ColorSpace& color_space, bool has_alpha) { + device_color_space_ = color_space; if (size == surface_size_ && scale_factor == device_scale_factor_ && has_alpha == has_alpha_) return;
diff --git a/cc/output/output_surface.h b/cc/output/output_surface.h index 3e8e9ee..87b03a37 100644 --- a/cc/output/output_surface.h +++ b/cc/output/output_surface.h
@@ -19,6 +19,7 @@ #include "cc/output/vulkan_context_provider.h" #include "cc/resources/returned_resource.h" #include "gpu/command_buffer/common/texture_in_use_response.h" +#include "ui/gfx/color_space.h" namespace ui { class LatencyInfo; @@ -128,6 +129,9 @@ bool alpha); gfx::Size SurfaceSize() const { return surface_size_; } float device_scale_factor() const { return device_scale_factor_; } + const gfx::ColorSpace& device_color_space() const { + return device_color_space_; + } // If supported, this causes a ReclaimResources for all resources that are // currently in use. @@ -194,7 +198,9 @@ std::unique_ptr<SoftwareOutputDevice> software_device_; gfx::Size surface_size_; float device_scale_factor_ = -1; + gfx::ColorSpace device_color_space_; bool has_alpha_ = true; + gfx::ColorSpace color_space_; base::ThreadChecker client_thread_checker_; void SetNeedsRedrawRect(const gfx::Rect& damage_rect);
diff --git a/cc/output/overlay_unittest.cc b/cc/output/overlay_unittest.cc index da22606..c289621 100644 --- a/cc/output/overlay_unittest.cc +++ b/cc/output/overlay_unittest.cc
@@ -1756,6 +1756,7 @@ protected: void SetUp() override { CALayerOverlayTest::SetUp(); + EnableRenderPassDrawQuadForTesting(); pass_ = CreateRenderPass(); quad_ = pass_->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); render_pass_id_.layer_id = 3;
diff --git a/cc/output/renderer.h b/cc/output/renderer.h index d91e9cd..8dadbfb 100644 --- a/cc/output/renderer.h +++ b/cc/output/renderer.h
@@ -75,9 +75,6 @@ const gfx::Rect& device_viewport_rect, const gfx::Rect& device_clip_rect) = 0; - // Waits for rendering to finish. - virtual void Finish() = 0; - // Puts backbuffer onscreen. virtual void SwapBuffers(CompositorFrameMetadata metadata) = 0; virtual void ReclaimResources(const ReturnedResourceArray& resources) {}
diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc index bf7290f..afb21a0 100644 --- a/cc/output/renderer_pixeltest.cc +++ b/cc/output/renderer_pixeltest.cc
@@ -135,7 +135,8 @@ } } ResourceId resource = resource_provider->CreateResource( - rect.size(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); + rect.size(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888, + gfx::ColorSpace()); resource_provider->CopyToResource( resource, reinterpret_cast<uint8_t*>(&pixels.front()), rect.size()); @@ -169,7 +170,8 @@ std::vector<uint32_t> pixels(num_pixels, pixel_color); ResourceId resource = resource_provider->CreateResource( - rect.size(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); + rect.size(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888, + gfx::ColorSpace()); resource_provider->CopyToResource( resource, reinterpret_cast<uint8_t*>(&pixels.front()), rect.size()); @@ -206,6 +208,8 @@ color_space = YUVVideoDrawQuad::JPEG; } + gfx::ColorSpace video_color_space = video_frame->ColorSpace(); + const gfx::Rect opaque_rect(0, 0, 0, 0); if (with_alpha) { @@ -278,7 +282,8 @@ yuv_quad->SetNew(shared_state, rect, opaque_rect, visible_rect, ya_tex_coord_rect, uv_tex_coord_rect, ya_tex_size, uv_tex_size, y_resource, u_resource, v_resource, a_resource, - color_space, 0.0f, 1.0f, bits_per_channel); + color_space, video_color_space, 0.0f, 1.0f, + bits_per_channel); } // Upshift video frame to 10 bit. @@ -483,6 +488,7 @@ void CreateTestYUVVideoDrawQuad_NV12(const SharedQuadState* shared_state, media::ColorSpace video_frame_color_space, + const gfx::ColorSpace& video_color_space, const gfx::RectF& tex_coord_rect, uint8_t y, uint8_t u, @@ -503,9 +509,10 @@ ResourceId y_resource = resource_provider->CreateResource( rect.size(), ResourceProvider::TEXTURE_HINT_DEFAULT, - resource_provider->YuvResourceFormat(8)); + resource_provider->YuvResourceFormat(8), gfx::ColorSpace()); ResourceId u_resource = resource_provider->CreateResource( - uv_tex_size, ResourceProvider::TEXTURE_HINT_DEFAULT, RGBA_8888); + uv_tex_size, ResourceProvider::TEXTURE_HINT_DEFAULT, RGBA_8888, + gfx::ColorSpace()); ResourceId v_resource = u_resource; ResourceId a_resource = 0; @@ -532,7 +539,7 @@ yuv_quad->SetNew(shared_state, rect, opaque_rect, visible_rect, ya_tex_coord_rect, uv_tex_coord_rect, ya_tex_size, uv_tex_size, y_resource, u_resource, v_resource, a_resource, - color_space, 0.0f, 1.0f, 8); + color_space, video_color_space, 0.0f, 1.0f, 8); } typedef ::testing::Types<GLRenderer, @@ -1231,8 +1238,9 @@ // YUV of (149,43,21) should be green (0,255,0) in RGB. CreateTestYUVVideoDrawQuad_NV12( - shared_state, media::COLOR_SPACE_JPEG, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), - 149, 43, 21, pass.get(), rect, rect, resource_provider_.get()); + shared_state, media::COLOR_SPACE_JPEG, gfx::ColorSpace::CreateJpeg(), + gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 149, 43, 21, pass.get(), rect, rect, + resource_provider_.get()); RenderPassList pass_list; pass_list.push_back(std::move(pass)); @@ -1825,7 +1833,8 @@ } ResourceId mask_resource_id = this->resource_provider_->CreateResource( - mask_rect.size(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); + mask_rect.size(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888, + gfx::ColorSpace()); { SkAutoLockPixels lock(bitmap); this->resource_provider_->CopyToResource( @@ -1918,7 +1927,8 @@ } ResourceId mask_resource_id = this->resource_provider_->CreateResource( - mask_rect.size(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); + mask_rect.size(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888, + gfx::ColorSpace()); { SkAutoLockPixels lock(bitmap); this->resource_provider_->CopyToResource( @@ -2673,7 +2683,8 @@ gfx::Size tile_size(2, 2); ResourceId resource = this->resource_provider_->CreateResource( - tile_size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); + tile_size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888, + gfx::ColorSpace()); { SkAutoLockPixels lock(bitmap); @@ -2723,7 +2734,8 @@ gfx::Size tile_size(2, 2); ResourceId resource = this->resource_provider_->CreateResource( - tile_size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); + tile_size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888, + gfx::ColorSpace()); { SkAutoLockPixels lock(bitmap); @@ -2774,7 +2786,8 @@ gfx::Size tile_size(2, 2); ResourceId resource = this->resource_provider_->CreateResource( - tile_size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); + tile_size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888, + gfx::ColorSpace()); { SkAutoLockPixels lock(bitmap); @@ -3137,7 +3150,8 @@ } ResourceId resource = this->resource_provider_->CreateResource( - mask_rect.size(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); + mask_rect.size(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888, + gfx::ColorSpace()); { SkAutoLockPixels lock(bitmap); this->resource_provider_->CopyToResource(
diff --git a/cc/output/shader.cc b/cc/output/shader.cc index 9b54c54..b5d16386 100644 --- a/cc/output/shader.cc +++ b/cc/output/shader.cc
@@ -2019,24 +2019,41 @@ v_texture_location_(-1), uv_texture_location_(-1), a_texture_location_(-1), + lut_texture_location_(-1), alpha_location_(-1), yuv_matrix_location_(-1), yuv_adj_location_(-1), ya_clamp_rect_location_(-1), - uv_clamp_rect_location_(-1) {} + uv_clamp_rect_location_(-1), + resource_multiplier_location_(-1), + resource_offset_location_(-1) {} void FragmentShaderYUVVideo::SetFeatures(bool use_alpha_texture, - bool use_nv12) { + bool use_nv12, + bool use_color_lut) { use_alpha_texture_ = use_alpha_texture; use_nv12_ = use_nv12; + use_color_lut_ = use_color_lut; } void FragmentShaderYUVVideo::Init(GLES2Interface* context, unsigned program, int* base_uniform_index) { static const char* uniforms[] = { - "y_texture", "u_texture", "v_texture", "uv_texture", "a_texture", - "alpha", "yuv_matrix", "yuv_adj", "ya_clamp_rect", "uv_clamp_rect"}; + "y_texture", + "u_texture", + "v_texture", + "uv_texture", + "a_texture", + "lut_texture", + "resource_multiplier", + "resource_offset", + "yuv_matrix", + "yuv_adj", + "alpha", + "ya_clamp_rect", + "uv_clamp_rect", + }; int locations[arraysize(uniforms)]; GetProgramUniformLocations(context, @@ -2046,15 +2063,26 @@ locations, base_uniform_index); y_texture_location_ = locations[0]; - u_texture_location_ = locations[1]; - v_texture_location_ = locations[2]; - uv_texture_location_ = locations[3]; - a_texture_location_ = locations[4]; - alpha_location_ = locations[5]; - yuv_matrix_location_ = locations[6]; - yuv_adj_location_ = locations[7]; - ya_clamp_rect_location_ = locations[8]; - uv_clamp_rect_location_ = locations[9]; + if (!use_nv12_) { + u_texture_location_ = locations[1]; + v_texture_location_ = locations[2]; + } else { + uv_texture_location_ = locations[3]; + } + if (use_alpha_texture_) { + a_texture_location_ = locations[4]; + } + if (use_color_lut_) { + lut_texture_location_ = locations[5]; + resource_multiplier_location_ = locations[6]; + resource_offset_location_ = locations[7]; + } else { + yuv_matrix_location_ = locations[8]; + yuv_adj_location_ = locations[9]; + } + alpha_location_ = locations[10]; + ya_clamp_rect_location_ = locations[11]; + uv_clamp_rect_location_ = locations[12]; } std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, @@ -2066,44 +2094,22 @@ varying TexCoordPrecision vec2 v_uvTexCoord; uniform SamplerType y_texture; uniform float alpha; - uniform vec3 yuv_adj; - uniform mat3 yuv_matrix; uniform vec4 ya_clamp_rect; uniform vec4 uv_clamp_rect; }); + + std::string functions = ""; if (use_nv12_) { head += " uniform SamplerType uv_texture;\n"; - } else { - head += " uniform SamplerType u_texture;\n"; - head += " uniform SamplerType v_texture;\n"; - } - if (use_alpha_texture_) { - head += " uniform SamplerType a_texture;\n"; - } - - std::string main = SHADER0([]() { - void main() { - vec2 ya_clamped = - max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord)); - float y_raw = TextureLookup(y_texture, ya_clamped).x; - vec2 uv_clamped = - max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord)); - vec2 uv_unsigned = GetUV(uv_clamped); - vec3 yuv = vec3(y_raw, uv_unsigned) + yuv_adj; - vec3 rgb = yuv_matrix * yuv; - gl_FragColor = vec4(rgb, 1.0) * GetAlpha(ya_clamped); - } - }); - - std::string get_uv; - if (use_nv12_) { - get_uv = SHADER0([]() { + functions += SHADER0([]() { vec2 GetUV(vec2 uv_clamped) { return TextureLookup(uv_texture, uv_clamped).xy; } }); } else { - get_uv = SHADER0([]() { + head += " uniform SamplerType u_texture;\n"; + head += " uniform SamplerType v_texture;\n"; + functions += SHADER0([]() { vec2 GetUV(vec2 uv_clamped) { return vec2(TextureLookup(u_texture, uv_clamped).x, TextureLookup(v_texture, uv_clamped).x); @@ -2111,20 +2117,63 @@ }); } - std::string get_alpha; if (use_alpha_texture_) { - get_alpha = SHADER0([]() { + head += " uniform SamplerType a_texture;\n"; + functions += SHADER0([]() { float GetAlpha(vec2 ya_clamped) { return alpha * TextureLookup(a_texture, ya_clamped).x; } }); } else { - get_alpha = SHADER0([]() { + functions += SHADER0([]() { float GetAlpha(vec2 ya_clamped) { return alpha; } }); } - return FRAGMENT_SHADER(head, get_uv + get_alpha + main); + if (use_color_lut_) { + head += " uniform sampler2D lut_texture;\n"; + head += " uniform float resource_multiplier;\n"; + head += " uniform float resource_offset;\n"; + functions += SHADER0([]() { + vec4 LUT(sampler2D sampler, vec3 pos, float size) { + pos *= size - 1.0; + // Select layer + float layer = min(floor(pos.x), size - 2.0); + // Compress the yz coordinates so they stay within + // [0.5 .. 31.5] / 32 (assuming a LUT size of 32^3) + pos.yz = (pos.yz + vec2(0.5)) / size; + pos.z = (pos.z + layer) / size; + return mix(texture2D(sampler, pos.yz), + texture2D(sampler, pos.yz + vec2(0, 1.0 / size)), + pos.x - layer); + } + + vec3 yuv2rgb(vec3 yuv) { + yuv = (yuv - vec3(resource_offset)) * resource_multiplier; + return LUT(lut_texture, yuv, 32.0).xyz; + } + }); + } else { + head += " uniform mat3 yuv_matrix;\n"; + head += " uniform vec3 yuv_adj;\n"; + functions += SHADER0([]() { + vec3 yuv2rgb(vec3 yuv) { return yuv_matrix * (yuv + yuv_adj); } + }); + } + + functions += SHADER0([]() { + void main() { + vec2 ya_clamped = + max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord)); + float y_raw = TextureLookup(y_texture, ya_clamped).x; + vec2 uv_clamped = + max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord)); + vec3 yuv = vec3(y_raw, GetUV(uv_clamped)); + gl_FragColor = vec4(yuv2rgb(yuv), 1.0) * GetAlpha(ya_clamped); + } + }); + + return FRAGMENT_SHADER(head, functions); } FragmentShaderColor::FragmentShaderColor() : color_location_(-1) {
diff --git a/cc/output/shader.h b/cc/output/shader.h index 327c5edc..21b4a70 100644 --- a/cc/output/shader.h +++ b/cc/output/shader.h
@@ -767,7 +767,7 @@ std::string GetShaderString( TexCoordPrecision precision, SamplerType sampler) const; - void SetFeatures(bool use_alpha_texture, bool use_nv12); + void SetFeatures(bool use_alpha_texture, bool use_nv12, bool use_color_lut); void Init(gpu::gles2::GLES2Interface* context, unsigned program, @@ -777,26 +777,35 @@ int v_texture_location() const { return v_texture_location_; } int uv_texture_location() const { return uv_texture_location_; } int a_texture_location() const { return a_texture_location_; } + int lut_texture_location() const { return lut_texture_location_; } int alpha_location() const { return alpha_location_; } int yuv_matrix_location() const { return yuv_matrix_location_; } int yuv_adj_location() const { return yuv_adj_location_; } int ya_clamp_rect_location() const { return ya_clamp_rect_location_; } int uv_clamp_rect_location() const { return uv_clamp_rect_location_; } + int resource_multiplier_location() const { + return resource_multiplier_location_; + } + int resource_offset_location() const { return resource_offset_location_; } private: bool use_alpha_texture_; bool use_nv12_; + bool use_color_lut_; int y_texture_location_; int u_texture_location_; int v_texture_location_; int uv_texture_location_; int a_texture_location_; + int lut_texture_location_; int alpha_location_; int yuv_matrix_location_; int yuv_adj_location_; int ya_clamp_rect_location_; int uv_clamp_rect_location_; + int resource_multiplier_location_; + int resource_offset_location_; DISALLOW_COPY_AND_ASSIGN(FragmentShaderYUVVideo); };
diff --git a/cc/output/software_renderer.cc b/cc/output/software_renderer.cc index 2aeaead..b49fcf2 100644 --- a/cc/output/software_renderer.cc +++ b/cc/output/software_renderer.cc
@@ -123,8 +123,6 @@ SetClipRect(gfx::Rect(size.width(), size.height())); } -void SoftwareRenderer::Finish() {} - void SoftwareRenderer::BindFramebufferToOutputSurface(DrawingFrame* frame) { DCHECK(!output_surface_->HasExternalStencilTest()); current_framebuffer_lock_ = nullptr;
diff --git a/cc/output/software_renderer.h b/cc/output/software_renderer.h index 0261bbb..831e05f 100644 --- a/cc/output/software_renderer.h +++ b/cc/output/software_renderer.h
@@ -34,7 +34,6 @@ ~SoftwareRenderer() override; const RendererCapabilitiesImpl& Capabilities() const override; - void Finish() override; void SwapBuffers(CompositorFrameMetadata metadata) override; void DiscardBackbuffer() override; void EnsureBackbuffer() override;
diff --git a/cc/output/software_renderer_unittest.cc b/cc/output/software_renderer_unittest.cc index bf40c86..9d52dada 100644 --- a/cc/output/software_renderer_unittest.cc +++ b/cc/output/software_renderer_unittest.cc
@@ -150,9 +150,11 @@ InitializeRenderer(base::WrapUnique(new SoftwareOutputDevice)); ResourceId resource_yellow = resource_provider()->CreateResource( - outer_size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); + outer_size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888, + gfx::ColorSpace()); ResourceId resource_cyan = resource_provider()->CreateResource( - inner_size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); + inner_size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888, + gfx::ColorSpace()); SkBitmap yellow_tile; yellow_tile.allocN32Pixels(outer_size.width(), outer_size.height()); @@ -221,7 +223,8 @@ InitializeRenderer(base::WrapUnique(new SoftwareOutputDevice)); ResourceId resource_cyan = resource_provider()->CreateResource( - tile_size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); + tile_size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888, + gfx::ColorSpace()); SkBitmap cyan_tile; // The lowest five rows are yellow. cyan_tile.allocN32Pixels(tile_size.width(), tile_size.height());
diff --git a/cc/output/swap_promise.h b/cc/output/swap_promise.h index f3c3fbdd..45a95311 100644 --- a/cc/output/swap_promise.h +++ b/cc/output/swap_promise.h
@@ -50,12 +50,19 @@ ACTIVATION_FAILS, }; + enum class DidNotSwapAction { + BREAK_PROMISE, + KEEP_ACTIVE, + }; + SwapPromise() {} virtual ~SwapPromise() {} virtual void DidActivate() = 0; virtual void DidSwap(CompositorFrameMetadata* metadata) = 0; - virtual void DidNotSwap(DidNotSwapReason reason) = 0; + // Return |KEEP_ACTIVE| if this promise should remain active (should not be + // broken by the owner). + virtual DidNotSwapAction DidNotSwap(DidNotSwapReason reason) = 0; // This is called when the main thread starts a (blocking) commit virtual void OnCommit() {}
diff --git a/cc/playback/discardable_image_map_unittest.cc b/cc/playback/discardable_image_map_unittest.cc index 05585b0..5c7b4ee7 100644 --- a/cc/playback/discardable_image_map_unittest.cc +++ b/cc/playback/discardable_image_map_unittest.cc
@@ -94,7 +94,7 @@ { DiscardableImageMap::ScopedMetadataGenerator generator(&image_map, visible_rect.size()); - display_list->Raster(generator.canvas(), nullptr, visible_rect, 1.f); + display_list->Raster(generator.canvas(), nullptr, gfx::Rect(), 1.f); } for (int y = 0; y < 4; ++y) { @@ -167,7 +167,7 @@ { DiscardableImageMap::ScopedMetadataGenerator generator(&image_map, layer_size); - display_list->Raster(generator.canvas(), nullptr, visible_rect, 1.f); + display_list->Raster(generator.canvas(), nullptr, gfx::Rect(), 1.f); } for (int y = 0; y < 4; ++y) { @@ -263,7 +263,7 @@ { DiscardableImageMap::ScopedMetadataGenerator generator(&image_map, visible_rect.size()); - display_list->Raster(generator.canvas(), nullptr, visible_rect, 1.f); + display_list->Raster(generator.canvas(), nullptr, gfx::Rect(), 1.f); } for (int y = 0; y < 4; ++y) { @@ -302,7 +302,7 @@ { DiscardableImageMap::ScopedMetadataGenerator generator(&image_map, visible_rect.size()); - display_list->Raster(generator.canvas(), nullptr, visible_rect, 1.f); + display_list->Raster(generator.canvas(), nullptr, gfx::Rect(), 1.f); } std::vector<PositionDrawImage> images = GetDiscardableImagesInRect(image_map, gfx::Rect(0, 0, 1, 1));
diff --git a/cc/playback/display_item_list.cc b/cc/playback/display_item_list.cc index 1f2c6be..0254827 100644 --- a/cc/playback/display_item_list.cc +++ b/cc/playback/display_item_list.cc
@@ -26,6 +26,7 @@ #include "third_party/skia/include/core/SkPictureRecorder.h" #include "third_party/skia/include/utils/SkPictureUtils.h" #include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/skia_util.h" namespace cc { @@ -43,41 +44,42 @@ return tracing_enabled; } +bool GetCanvasClipBounds(SkCanvas* canvas, gfx::Rect* clip_bounds) { + SkRect canvas_clip_bounds; + if (!canvas->getClipBounds(&canvas_clip_bounds)) + return false; + *clip_bounds = ToEnclosingRect(gfx::SkRectToRectF(canvas_clip_bounds)); + return true; +} + const int kDefaultNumDisplayItemsToReserve = 100; } // namespace -DisplayItemList::Inputs::Inputs(gfx::Rect layer_rect, - const DisplayItemListSettings& settings) +DisplayItemList::Inputs::Inputs(const DisplayItemListSettings& settings) : items(LargestDisplayItemSize(), LargestDisplayItemSize() * kDefaultNumDisplayItemsToReserve), - settings(settings), - layer_rect(layer_rect), - is_suitable_for_gpu_rasterization(true) {} + settings(settings) {} DisplayItemList::Inputs::~Inputs() {} scoped_refptr<DisplayItemList> DisplayItemList::Create( - const gfx::Rect& layer_rect, const DisplayItemListSettings& settings) { - return make_scoped_refptr(new DisplayItemList( - layer_rect, settings, - !settings.use_cached_picture || DisplayItemsTracingEnabled())); + return make_scoped_refptr(new DisplayItemList(settings)); } scoped_refptr<DisplayItemList> DisplayItemList::CreateFromProto( const proto::DisplayItemList& proto, ClientPictureCache* client_picture_cache, std::vector<uint32_t>* used_engine_picture_ids) { - gfx::Rect layer_rect = ProtoToRect(proto.layer_rect()); scoped_refptr<DisplayItemList> list = - DisplayItemList::Create(ProtoToRect(proto.layer_rect()), - DisplayItemListSettings(proto.settings())); + DisplayItemList::Create(DisplayItemListSettings(proto.settings())); for (int i = 0; i < proto.items_size(); i++) { const proto::DisplayItem& item_proto = proto.items(i); + const gfx::Rect visual_rect = ProtoToRect(proto.visual_rects(i)); DisplayItemProtoFactory::AllocateAndConstruct( - layer_rect, list.get(), item_proto, client_picture_cache, + visual_rect, list.get(), item_proto, client_picture_cache, used_engine_picture_ids); } @@ -86,23 +88,8 @@ return list; } -DisplayItemList::DisplayItemList(gfx::Rect layer_rect, - const DisplayItemListSettings& settings, - bool retain_individual_display_items) - : retain_individual_display_items_(retain_individual_display_items), - approximate_op_count_(0), - picture_memory_usage_(0), - inputs_(layer_rect, settings) { - if (inputs_.settings.use_cached_picture) { - SkRTreeFactory factory; - recorder_.reset(new SkPictureRecorder()); - - SkCanvas* canvas = recorder_->beginRecording( - inputs_.layer_rect.width(), inputs_.layer_rect.height(), &factory); - canvas->translate(-inputs_.layer_rect.x(), -inputs_.layer_rect.y()); - canvas->clipRect(gfx::RectToSkRect(inputs_.layer_rect)); - } -} +DisplayItemList::DisplayItemList(const DisplayItemListSettings& settings) + : inputs_(settings) {} DisplayItemList::~DisplayItemList() { } @@ -110,14 +97,18 @@ void DisplayItemList::ToProtobuf(proto::DisplayItemList* proto) { // The flattened SkPicture approach is going away, and the proto // doesn't currently support serializing that flattened picture. - DCHECK(retain_individual_display_items_); - - RectToProto(inputs_.layer_rect, proto->mutable_layer_rect()); inputs_.settings.ToProtobuf(proto->mutable_settings()); DCHECK_EQ(0, proto->items_size()); - for (const auto& item : inputs_.items) + DCHECK_EQ(0, proto->visual_rects_size()); + DCHECK(inputs_.items.size() == inputs_.visual_rects.size()) + << "items.size() " << inputs_.items.size() << " visual_rects.size() " + << inputs_.visual_rects.size(); + int i = 0; + for (const auto& item : inputs_.items) { + RectToProto(inputs_.visual_rects[i++], proto->add_visual_rects()); item.ToProtobuf(proto->add_items()); + } } void DisplayItemList::Raster(SkCanvas* canvas, @@ -125,7 +116,6 @@ const gfx::Rect& canvas_target_playback_rect, float contents_scale) const { canvas->save(); - if (!canvas_target_playback_rect.IsEmpty()) { // canvas_target_playback_rect is specified in device space. We can't // use clipRect because canvas CTM will be applied on it. Use clipRegion @@ -134,7 +124,6 @@ device_clip.setRect(gfx::RectToSkIRect(canvas_target_playback_rect)); canvas->clipRegion(device_clip); } - canvas->scale(contents_scale, contents_scale); Raster(canvas, callback); canvas->restore(); @@ -142,25 +131,19 @@ void DisplayItemList::Raster(SkCanvas* canvas, SkPicture::AbortCallback* callback) const { - if (!inputs_.settings.use_cached_picture) { - for (const auto& item : inputs_.items) - item.Raster(canvas, callback); - } else { - DCHECK(picture_); + gfx::Rect canvas_playback_rect; + if (!GetCanvasClipBounds(canvas, &canvas_playback_rect)) + return; - canvas->save(); - canvas->translate(inputs_.layer_rect.x(), inputs_.layer_rect.y()); - if (callback) { - // If we have a callback, we need to call |draw()|, |drawPicture()| - // doesn't take a callback. This is used by |AnalysisCanvas| to early - // out. - picture_->playback(canvas, callback); - } else { - // Prefer to call |drawPicture()| on the canvas since it could place the - // entire picture on the canvas instead of parsing the skia operations. - canvas->drawPicture(picture_.get()); - } - canvas->restore(); + std::vector<size_t> indices; + rtree_.Search(canvas_playback_rect, &indices); + for (size_t index : indices) { + inputs_.items[index].Raster(canvas, callback); + // We use a callback during solid color analysis on the compositor thread to + // break out early. Since we're handling a sequence of pictures via rtree + // query results ourselves, we have to respect the callback and early out. + if (callback && callback->abort()) + break; } } @@ -170,91 +153,51 @@ inputs_.visual_rects[inputs_.begin_item_indices.back()].Union(visual_rect); } -void DisplayItemList::ProcessAppendedItem(const DisplayItem* item) { - if (inputs_.settings.use_cached_picture) { - DCHECK(recorder_); - item->Raster(recorder_->getRecordingCanvas(), nullptr); - } - if (!retain_individual_display_items_) { - inputs_.items.Clear(); - } -} - -void DisplayItemList::RasterIntoCanvas(const DisplayItem& item) { - DCHECK(recorder_); - DCHECK(!retain_individual_display_items_); - - item.Raster(recorder_->getRecordingCanvas(), nullptr); -} - -bool DisplayItemList::RetainsIndividualDisplayItems() const { - return retain_individual_display_items_; -} - void DisplayItemList::Finalize() { TRACE_EVENT0("cc", "DisplayItemList::Finalize"); - // TODO(dtrainor): Need to deal with serializing visual_rects_. + // TODO(dtrainor): Need to deal with serializing inputs_.visual_rects. // http://crbug.com/568757. - DCHECK(!retain_individual_display_items_ || - inputs_.items.size() == inputs_.visual_rects.size()) + DCHECK(inputs_.items.size() == inputs_.visual_rects.size()) << "items.size() " << inputs_.items.size() << " visual_rects.size() " << inputs_.visual_rects.size(); + rtree_.Build(inputs_.visual_rects); - // TODO(vmpstr): Build and make use of an RTree from the visual - // rects. For now we just clear them out since we won't ever need - // them to stick around post-Finalize. http://crbug.com/527245 - // This clears both the vector and the vector's capacity, since visual_rects_ - // won't be used anymore. - std::vector<gfx::Rect>().swap(inputs_.visual_rects); - - if (inputs_.settings.use_cached_picture) { - // Convert to an SkPicture for faster rasterization. - DCHECK(inputs_.settings.use_cached_picture); - DCHECK(!picture_); - picture_ = recorder_->finishRecordingAsPicture(); - DCHECK(picture_); - picture_memory_usage_ = - SkPictureUtils::ApproximateBytesUsed(picture_.get()); - recorder_.reset(); - } + // TODO(wkorman): Restore the below, potentially with a switch to allow + // clearing visual rects except for Blimp engine. http://crbug.com/633750 + // if (!retain_visual_rects_) + // // This clears both the vector and the vector's capacity, since + // // visual_rects won't be used anymore. + // std::vector<gfx::Rect>().swap(inputs_.visual_rects); } bool DisplayItemList::IsSuitableForGpuRasterization() const { - return inputs_.is_suitable_for_gpu_rasterization; + // TODO(wkorman): This is more permissive than Picture's implementation, since + // none of the items might individually trigger a veto even though they + // collectively have enough "bad" operations that a corresponding Picture + // would get vetoed. See crbug.com/513016. + return inputs_.all_items_are_suitable_for_gpu_rasterization; } int DisplayItemList::ApproximateOpCount() const { - if (retain_individual_display_items_) - return approximate_op_count_; - return picture_ ? picture_->approximateOpCount() : 0; + return approximate_op_count_; } size_t DisplayItemList::ApproximateMemoryUsage() const { - // We double-count in this case. Produce zero to avoid being misleading. - if (inputs_.settings.use_cached_picture && retain_individual_display_items_) - return 0; - - DCHECK(!inputs_.settings.use_cached_picture || picture_); - size_t memory_usage = sizeof(*this); size_t external_memory_usage = 0; - if (retain_individual_display_items_) { - // Warning: this double-counts SkPicture data if use_cached_picture is - // also true. - for (const auto& item : inputs_.items) { - external_memory_usage += item.ExternalMemoryUsage(); - } + // Warning: this double-counts SkPicture data if use_cached_picture is + // also true. + for (const auto& item : inputs_.items) { + external_memory_usage += item.ExternalMemoryUsage(); } // Memory outside this class due to |items_|. memory_usage += inputs_.items.GetCapacityInBytes() + external_memory_usage; - // Memory outside this class due to |picture|. - memory_usage += picture_memory_usage_; - // TODO(jbroman): Does anything else owned by this class substantially // contribute to memory usage? + // TODO(vmpstr): Probably DiscardableImageMap is worth counting here. return memory_usage; } @@ -281,22 +224,20 @@ } state->EndArray(); // "items". } - state->SetValue("layer_rect", MathUtil::AsValue(inputs_.layer_rect)); + state->SetValue("layer_rect", MathUtil::AsValue(rtree_.GetBounds())); state->EndDictionary(); // "params". - if (!inputs_.layer_rect.IsEmpty()) { - SkPictureRecorder recorder; - SkCanvas* canvas = recorder.beginRecording(inputs_.layer_rect.width(), - inputs_.layer_rect.height()); - canvas->translate(-inputs_.layer_rect.x(), -inputs_.layer_rect.y()); - canvas->clipRect(gfx::RectToSkRect(inputs_.layer_rect)); - Raster(canvas, NULL, gfx::Rect(), 1.f); - sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture(); + SkPictureRecorder recorder; + gfx::Rect bounds = rtree_.GetBounds(); + SkCanvas* canvas = recorder.beginRecording(bounds.width(), bounds.height()); + canvas->translate(-bounds.x(), -bounds.y()); + canvas->clipRect(gfx::RectToSkRect(bounds)); + Raster(canvas, nullptr, gfx::Rect(), 1.f); + sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture(); - std::string b64_picture; - PictureDebugUtil::SerializeAsBase64(picture.get(), &b64_picture); - state->SetString("skp64", b64_picture); - } + std::string b64_picture; + PictureDebugUtil::SerializeAsBase64(picture.get(), &b64_picture); + state->SetString("skp64", b64_picture); return std::move(state); } @@ -314,19 +255,11 @@ void DisplayItemList::GenerateDiscardableImagesMetadata() { // This should be only called once, and only after CreateAndCacheSkPicture. DCHECK(image_map_.empty()); - DCHECK(!inputs_.settings.use_cached_picture || picture_); - if (inputs_.settings.use_cached_picture && !picture_->willPlayBackBitmaps()) - return; - // The cached picture is translated by -layer_rect_.origin during record, - // so we need to offset that back in order to get right positioning for - // images. + gfx::Rect bounds = rtree_.GetBounds(); DiscardableImageMap::ScopedMetadataGenerator generator( - &image_map_, - gfx::Size(inputs_.layer_rect.right(), inputs_.layer_rect.bottom())); - Raster(generator.canvas(), nullptr, - gfx::Rect(inputs_.layer_rect.right(), inputs_.layer_rect.bottom()), - 1.f); + &image_map_, gfx::Size(bounds.right(), bounds.bottom())); + Raster(generator.canvas(), nullptr, gfx::Rect(), 1.f); } void DisplayItemList::GetDiscardableImagesInRect(
diff --git a/cc/playback/display_item_list.h b/cc/playback/display_item_list.h index 2f19bb77..fcc936f 100644 --- a/cc/playback/display_item_list.h +++ b/cc/playback/display_item_list.h
@@ -16,11 +16,13 @@ #include "base/trace_event/trace_event.h" #include "cc/base/cc_export.h" #include "cc/base/contiguous_container.h" +#include "cc/base/rtree.h" #include "cc/playback/discardable_image_map.h" #include "cc/playback/display_item.h" #include "cc/playback/display_item_list_settings.h" #include "third_party/skia/include/core/SkPicture.h" #include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/rect_conversions.h" class SkCanvas; class SkPictureRecorder; @@ -37,13 +39,8 @@ class CC_EXPORT DisplayItemList : public base::RefCountedThreadSafe<DisplayItemList> { public: - // Creates a display item list. If picture caching is used, then layer_rect - // specifies the cull rect of the display item list (the picture will not - // exceed this rect). If picture caching is not used, then the given rect can - // be empty. - // TODO(vmpstr): Maybe this cull rect can be part of the settings instead. + // Creates a display item list. static scoped_refptr<DisplayItemList> Create( - const gfx::Rect& layer_rect, const DisplayItemListSettings& settings); // Creates a DisplayItemList from a Protobuf. @@ -65,18 +62,28 @@ void Raster(SkCanvas* canvas, SkPicture::AbortCallback* callback) const; - // This is a fast path for use only if canvas_ is set and - // retain_individual_display_items_ is false. This method also updates - // approximate_op_count_. - void RasterIntoCanvas(const DisplayItem& display_item); // Because processing happens in these CreateAndAppend functions, all the set // up for the item should be done via the args, which is why the return type // needs to be const, to prevent set-after-processing mistakes. + + // Most paired begin item types default to an empty visual rect, which will + // subsequently be grown as needed to encompass any contained items that draw + // content, such as drawing or filter items. template <typename DisplayItemType, typename... Args> const DisplayItemType& CreateAndAppendPairedBeginItem(Args&&... args) { + return CreateAndAppendPairedBeginItemWithVisualRect<DisplayItemType>( + gfx::Rect(), std::forward<Args>(args)...); + } + + // This method variant is exposed to allow filters to specify their visual + // rect since they may draw content despite containing no drawing items. + template <typename DisplayItemType, typename... Args> + const DisplayItemType& CreateAndAppendPairedBeginItemWithVisualRect( + const gfx::Rect& visual_rect, + Args&&... args) { size_t item_index = inputs_.visual_rects.size(); - inputs_.visual_rects.push_back(gfx::Rect()); + inputs_.visual_rects.push_back(visual_rect); inputs_.begin_item_indices.push_back(item_index); return AllocateAndConstruct<DisplayItemType>(std::forward<Args>(args)...); @@ -134,15 +141,13 @@ void Finalize(); void SetIsSuitableForGpuRasterization(bool is_suitable) { - inputs_.is_suitable_for_gpu_rasterization = is_suitable; + inputs_.all_items_are_suitable_for_gpu_rasterization = is_suitable; } bool IsSuitableForGpuRasterization() const; int ApproximateOpCount() const; size_t ApproximateMemoryUsage() const; bool ShouldBeAnalyzedForSolidColor() const; - bool RetainsIndividualDisplayItems() const; - std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValue( bool include_items) const; @@ -153,6 +158,10 @@ float raster_scale, std::vector<DrawImage>* images); + void SetRetainVisualRectsForTesting(bool retain) { + retain_visual_rects_ = retain; + } + size_t size() const { return inputs_.items.size(); } gfx::Rect VisualRectForTesting(int index) { @@ -168,39 +177,33 @@ } private: - DisplayItemList(gfx::Rect layer_rect, - const DisplayItemListSettings& display_list_settings, - bool retain_individual_display_items); + explicit DisplayItemList( + const DisplayItemListSettings& display_list_settings); ~DisplayItemList(); + RTree rtree_; + // For testing purposes only. Whether to keep visual rects across calls to + // Finalize(). + bool retain_visual_rects_ = false; + // If we're currently within a paired display item block, unions the // given visual rect with the begin display item's visual rect. void GrowCurrentBeginItemVisualRect(const gfx::Rect& visual_rect); - void ProcessAppendedItem(const DisplayItem* item); template <typename DisplayItemType, typename... Args> const DisplayItemType& AllocateAndConstruct(Args&&... args) { auto* item = &inputs_.items.AllocateAndConstruct<DisplayItemType>( std::forward<Args>(args)...); approximate_op_count_ += item->ApproximateOpCount(); - ProcessAppendedItem(item); return *item; } - sk_sp<SkPicture> picture_; - - std::unique_ptr<SkPictureRecorder> recorder_; - - bool retain_individual_display_items_; - int approximate_op_count_; - - // Memory usage due to the cached SkPicture. - size_t picture_memory_usage_; + int approximate_op_count_ = 0; DiscardableImageMap image_map_; struct Inputs { - Inputs(gfx::Rect layer_rect, const DisplayItemListSettings& settings); + explicit Inputs(const DisplayItemListSettings& settings); ~Inputs(); ContiguousContainer<DisplayItem> items; @@ -212,8 +215,7 @@ std::vector<gfx::Rect> visual_rects; std::vector<size_t> begin_item_indices; const DisplayItemListSettings settings; - gfx::Rect layer_rect; - bool is_suitable_for_gpu_rasterization; + bool all_items_are_suitable_for_gpu_rasterization = true; }; Inputs inputs_;
diff --git a/cc/playback/display_item_list_unittest.cc b/cc/playback/display_item_list_unittest.cc index 67d96b4a..ddfcb1b 100644 --- a/cc/playback/display_item_list_unittest.cc +++ b/cc/playback/display_item_list_unittest.cc
@@ -47,7 +47,7 @@ const gfx::Rect kVisualRect(0, 0, 42, 42); scoped_refptr<DisplayItemList> CreateDefaultList() { - return DisplayItemList::Create(gfx::Rect(), DisplayItemListSettings()); + return DisplayItemList::Create(DisplayItemListSettings()); } sk_sp<const SkPicture> CreateRectPicture(const gfx::Rect& bounds) { @@ -153,8 +153,9 @@ gfx::Size layer_size(10, 10); DisplayItemListSettings settings; - scoped_refptr<DisplayItemList> list = - DisplayItemList::Create(gfx::Rect(layer_size), settings); + settings.use_cached_picture = true; + scoped_refptr<DisplayItemList> list = DisplayItemList::Create(settings); + list->SetRetainVisualRectsForTesting(true); // Build the DrawingDisplayItem. AppendFirstSerializationTestPicture(list, layer_size); @@ -166,8 +167,9 @@ gfx::Size layer_size(10, 10); DisplayItemListSettings settings; - scoped_refptr<DisplayItemList> list = - DisplayItemList::Create(gfx::Rect(layer_size), settings); + settings.use_cached_picture = true; + scoped_refptr<DisplayItemList> list = DisplayItemList::Create(settings); + list->SetRetainVisualRectsForTesting(true); // Build the DrawingDisplayItem. AppendFirstSerializationTestPicture(list, layer_size); @@ -192,8 +194,9 @@ gfx::Size layer_size(10, 10); DisplayItemListSettings settings; - scoped_refptr<DisplayItemList> list = - DisplayItemList::Create(gfx::Rect(layer_size), settings); + settings.use_cached_picture = true; + scoped_refptr<DisplayItemList> list = DisplayItemList::Create(settings); + list->SetRetainVisualRectsForTesting(true); // Build the DrawingDisplayItem. AppendFirstSerializationTestPicture(list, layer_size); @@ -217,8 +220,9 @@ gfx::Size layer_size(10, 10); DisplayItemListSettings settings; - scoped_refptr<DisplayItemList> list = - DisplayItemList::Create(gfx::Rect(layer_size), settings); + settings.use_cached_picture = true; + scoped_refptr<DisplayItemList> list = DisplayItemList::Create(settings); + list->SetRetainVisualRectsForTesting(true); // Build the DrawingDisplayItem. AppendFirstSerializationTestPicture(list, layer_size); @@ -242,8 +246,9 @@ gfx::Size layer_size(10, 10); DisplayItemListSettings settings; - scoped_refptr<DisplayItemList> list = - DisplayItemList::Create(gfx::Rect(layer_size), settings); + settings.use_cached_picture = true; + scoped_refptr<DisplayItemList> list = DisplayItemList::Create(settings); + list->SetRetainVisualRectsForTesting(true); // Build the DrawingDisplayItem. AppendFirstSerializationTestPicture(list, layer_size); @@ -265,8 +270,9 @@ gfx::Size layer_size(10, 10); DisplayItemListSettings settings; - scoped_refptr<DisplayItemList> list = - DisplayItemList::Create(gfx::Rect(layer_size), settings); + settings.use_cached_picture = true; + scoped_refptr<DisplayItemList> list = DisplayItemList::Create(settings); + list->SetRetainVisualRectsForTesting(true); // Build the DrawingDisplayItem. AppendFirstSerializationTestPicture(list, layer_size); @@ -296,8 +302,8 @@ red_paint.setColor(SK_ColorRED); unsigned char pixels[4 * 100 * 100] = {0}; DisplayItemListSettings settings; - scoped_refptr<DisplayItemList> list = - DisplayItemList::Create(layer_rect, settings); + settings.use_cached_picture = true; + scoped_refptr<DisplayItemList> list = DisplayItemList::Create(settings); gfx::PointF offset(8.f, 9.f); gfx::RectF recording_rect(offset, gfx::SizeF(layer_rect.size())); @@ -339,8 +345,7 @@ unsigned char pixels[4 * 100 * 100] = {0}; DisplayItemListSettings settings; settings.use_cached_picture = true; - scoped_refptr<DisplayItemList> list = - DisplayItemList::Create(layer_rect, settings); + scoped_refptr<DisplayItemList> list = DisplayItemList::Create(settings); gfx::PointF first_offset(8.f, 9.f); gfx::RectF first_recording_rect(first_offset, gfx::SizeF(layer_rect.size())); @@ -399,8 +404,7 @@ unsigned char pixels[4 * 100 * 100] = {0}; DisplayItemListSettings settings; settings.use_cached_picture = true; - scoped_refptr<DisplayItemList> list = - DisplayItemList::Create(layer_rect, settings); + scoped_refptr<DisplayItemList> list = DisplayItemList::Create(settings); gfx::PointF first_offset(8.f, 9.f); gfx::RectF first_recording_rect(first_offset, gfx::SizeF(layer_rect.size())); @@ -452,10 +456,8 @@ gfx::Rect layer_rect(100, 100); FilterOperations filters; unsigned char pixels[4 * 100 * 100] = {0}; - DisplayItemListSettings settings; - settings.use_cached_picture = true; scoped_refptr<DisplayItemList> list = - DisplayItemList::Create(layer_rect, settings); + DisplayItemList::Create(DisplayItemListSettings()); sk_sp<SkSurface> source_surface = SkSurface::MakeRasterN32Premul(50, 50); SkCanvas* source_canvas = source_surface->getCanvas(); @@ -479,6 +481,24 @@ gfx::RectF filter_bounds(10.f, 10.f, 50.f, 50.f); list->CreateAndAppendPairedBeginItem<FilterDisplayItem>(filters, filter_bounds); + + // Include a rect drawing so that filter is actually applied to something. + { + SkPictureRecorder recorder; + sk_sp<SkCanvas> canvas; + + SkPaint red_paint; + red_paint.setColor(SK_ColorRED); + + canvas = sk_ref_sp(recorder.beginRecording( + SkRect::MakeXYWH(0, 0, layer_rect.width(), layer_rect.height()))); + canvas->drawRectCoords(filter_bounds.x(), filter_bounds.y(), + filter_bounds.right(), filter_bounds.bottom(), + red_paint); + list->CreateAndAppendDrawingItem<DrawingDisplayItem>( + ToNearestRect(filter_bounds), recorder.finishRecordingAsPicture()); + } + list->CreateAndAppendPairedEndItem<EndFilterDisplayItem>(); list->Finalize(); @@ -511,9 +531,8 @@ gfx::RectF recording_rect(offset, gfx::SizeF(layer_rect.size())); DisplayItemListSettings no_caching_settings; - no_caching_settings.use_cached_picture = false; scoped_refptr<DisplayItemList> list_without_caching = - DisplayItemList::Create(layer_rect, no_caching_settings); + DisplayItemList::Create(no_caching_settings); canvas = sk_ref_sp(recorder.beginRecording(gfx::RectFToSkRect(recording_rect))); @@ -530,7 +549,7 @@ DisplayItemListSettings caching_settings; caching_settings.use_cached_picture = true; scoped_refptr<DisplayItemList> list_with_caching = - DisplayItemList::Create(layer_rect, caching_settings); + DisplayItemList::Create(caching_settings); list_with_caching->CreateAndAppendDrawingItem<DrawingDisplayItem>(kVisualRect, picture); list_with_caching->Finalize(); @@ -559,7 +578,7 @@ // Using a cached picture, we should get about the right size. DisplayItemListSettings caching_settings; caching_settings.use_cached_picture = true; - list = DisplayItemList::Create(layer_rect, caching_settings); + list = DisplayItemList::Create(caching_settings); list->CreateAndAppendDrawingItem<DrawingDisplayItem>(kVisualRect, picture); list->Finalize(); memory_usage = list->ApproximateMemoryUsage(); @@ -569,43 +588,38 @@ // Using no cached picture, we should still get the right size. DisplayItemListSettings no_caching_settings; no_caching_settings.use_cached_picture = false; - list = DisplayItemList::Create(layer_rect, no_caching_settings); + list = DisplayItemList::Create(no_caching_settings); list->CreateAndAppendDrawingItem<DrawingDisplayItem>(kVisualRect, picture); list->Finalize(); memory_usage = list->ApproximateMemoryUsage(); EXPECT_GE(memory_usage, picture_size); EXPECT_LE(memory_usage, 2 * picture_size); - - // To avoid double counting, we expect zero size to be computed if both the - // picture and items are retained (currently this only happens due to certain - // categories being traced). - list = new DisplayItemList(layer_rect, caching_settings, true); - list->CreateAndAppendDrawingItem<DrawingDisplayItem>(kVisualRect, picture); - list->Finalize(); - memory_usage = list->ApproximateMemoryUsage(); - EXPECT_EQ(static_cast<size_t>(0), memory_usage); } -TEST(DisplayItemListTest, AsValueWithRectAndNoItems) { +TEST(DisplayItemListTest, AsValueWithNoItems) { scoped_refptr<DisplayItemList> list = - DisplayItemList::Create(gfx::Rect(1, 2, 8, 9), DisplayItemListSettings()); + DisplayItemList::Create(DisplayItemListSettings()); + list->SetRetainVisualRectsForTesting(true); list->Finalize(); std::string value = list->AsValue(true)->ToString(); + EXPECT_EQ(value.find("\"layer_rect\": [0,0,0,0]"), std::string::npos); EXPECT_NE(value.find("\"items\":[]"), std::string::npos); - EXPECT_NE(value.find("\"layer_rect\":[1,2,8,9]"), std::string::npos); + EXPECT_EQ(value.find("visualRect: [0,0 42x42]"), std::string::npos); EXPECT_NE(value.find("\"skp64\":"), std::string::npos); value = list->AsValue(false)->ToString(); + EXPECT_EQ(value.find("\"layer_rect\": [0,0,0,0]"), std::string::npos); EXPECT_EQ(value.find("\"items\":"), std::string::npos); - EXPECT_NE(value.find("\"layer_rect\":[1,2,8,9]"), std::string::npos); + EXPECT_EQ(value.find("visualRect: [0,0 42x42]"), std::string::npos); EXPECT_NE(value.find("\"skp64\":"), std::string::npos); } -TEST(DisplayItemListTest, AsValueWithRectAndItems) { +TEST(DisplayItemListTest, AsValueWithItems) { gfx::Rect layer_rect = gfx::Rect(1, 2, 8, 9); scoped_refptr<DisplayItemList> list = - DisplayItemList::Create(layer_rect, DisplayItemListSettings()); + DisplayItemList::Create(DisplayItemListSettings()); + list->SetRetainVisualRectsForTesting(true); gfx::Transform transform; transform.Translate(6.f, 7.f); list->CreateAndAppendPairedBeginItem<TransformDisplayItem>(transform); @@ -614,57 +628,20 @@ list->Finalize(); std::string value = list->AsValue(true)->ToString(); + EXPECT_EQ(value.find("\"layer_rect\": [0,0,42,42]"), std::string::npos); EXPECT_NE(value.find("{\"items\":[\"TransformDisplayItem"), std::string::npos); - EXPECT_NE(value.find("\"layer_rect\":[1,2,8,9]"), std::string::npos); + EXPECT_NE(value.find("visualRect: [0,0 42x42]"), std::string::npos); EXPECT_NE(value.find("\"skp64\":"), std::string::npos); value = list->AsValue(false)->ToString(); + EXPECT_EQ(value.find("\"layer_rect\": [0,0,42,42]"), std::string::npos); EXPECT_EQ(value.find("{\"items\":[\"TransformDisplayItem"), std::string::npos); - EXPECT_NE(value.find("\"layer_rect\":[1,2,8,9]"), std::string::npos); + EXPECT_EQ(value.find("visualRect: [0,0 42x42]"), std::string::npos); EXPECT_NE(value.find("\"skp64\":"), std::string::npos); } -TEST(DisplayItemListTest, AsValueWithEmptyRectAndNoItems) { - scoped_refptr<DisplayItemList> list = CreateDefaultList(); - list->Finalize(); - - std::string value = list->AsValue(true)->ToString(); - EXPECT_NE(value.find("\"items\":[]"), std::string::npos); - EXPECT_NE(value.find("\"layer_rect\":[0,0,0,0]"), std::string::npos); - EXPECT_EQ(value.find("\"skp64\":"), std::string::npos); - - value = list->AsValue(false)->ToString(); - EXPECT_EQ(value.find("\"items\":"), std::string::npos); - EXPECT_NE(value.find("\"layer_rect\":[0,0,0,0]"), std::string::npos); - EXPECT_EQ(value.find("\"skp64\":"), std::string::npos); -} - -TEST(DisplayItemListTest, AsValueWithEmptyRectAndItems) { - scoped_refptr<DisplayItemList> list = CreateDefaultList(); - gfx::Transform transform; - transform.Translate(6.f, 7.f); - list->CreateAndAppendPairedBeginItem<TransformDisplayItem>(transform); - AppendFirstSerializationTestPicture(list, gfx::Size()); - list->CreateAndAppendPairedEndItem<EndTransformDisplayItem>(); - list->Finalize(); - - std::string value = list->AsValue(true)->ToString(); - EXPECT_NE(value.find("\"items\":[\"TransformDisplayItem"), std::string::npos); - EXPECT_NE(value.find("\"layer_rect\":[0,0,0,0]"), std::string::npos); - // There should be one skp64 entry present associated with the test picture - // item, though the overall list has no skp64 as the layer rect is empty. - EXPECT_NE(value.find("\"skp64\":"), std::string::npos); - - value = list->AsValue(false)->ToString(); - EXPECT_EQ(value.find("\"items\":"), std::string::npos); - EXPECT_NE(value.find("\"layer_rect\":[0,0,0,0]"), std::string::npos); - // There should be no skp64 entry present as the items aren't included and the - // layer rect is empty. - EXPECT_EQ(value.find("\"skp64\":"), std::string::npos); -} - TEST(DisplayItemListTest, SizeEmpty) { scoped_refptr<DisplayItemList> list = CreateDefaultList(); EXPECT_EQ(0u, list->size()); @@ -943,4 +920,43 @@ EXPECT_RECT_EQ(merged_drawing_bounds, list->VisualRectForTesting(5)); } +TEST(DisplayItemListTest, AppendVisualRectOneFilterNoDrawings) { + scoped_refptr<DisplayItemList> list = CreateDefaultList(); + + // One filter containing no drawings: Bf, Ef + + gfx::Rect filter_bounds(5, 6, 1, 1); + list->CreateAndAppendPairedBeginItemWithVisualRect<FilterDisplayItem>( + filter_bounds, FilterOperations(), gfx::RectF(filter_bounds)); + + list->CreateAndAppendPairedEndItem<EndFilterDisplayItem>(); + + EXPECT_EQ(2u, list->size()); + EXPECT_RECT_EQ(filter_bounds, list->VisualRectForTesting(0)); + EXPECT_RECT_EQ(filter_bounds, list->VisualRectForTesting(1)); +} + +TEST(DisplayItemListTest, AppendVisualRectBlockContainingFilterNoDrawings) { + scoped_refptr<DisplayItemList> list = CreateDefaultList(); + + // One block containing one filter and no drawings: B1, Bf, Ef, E1. + + gfx::Rect clip_bounds(5, 6, 7, 8); + list->CreateAndAppendPairedBeginItem<ClipDisplayItem>( + clip_bounds, std::vector<SkRRect>(), true); + + gfx::Rect filter_bounds(5, 6, 1, 1); + list->CreateAndAppendPairedBeginItemWithVisualRect<FilterDisplayItem>( + filter_bounds, FilterOperations(), gfx::RectF(filter_bounds)); + + list->CreateAndAppendPairedEndItem<EndFilterDisplayItem>(); + list->CreateAndAppendPairedEndItem<EndClipDisplayItem>(); + + EXPECT_EQ(4u, list->size()); + EXPECT_RECT_EQ(filter_bounds, list->VisualRectForTesting(0)); + EXPECT_RECT_EQ(filter_bounds, list->VisualRectForTesting(1)); + EXPECT_RECT_EQ(filter_bounds, list->VisualRectForTesting(2)); + EXPECT_RECT_EQ(filter_bounds, list->VisualRectForTesting(3)); +} + } // namespace cc
diff --git a/cc/playback/recording_source.cc b/cc/playback/recording_source.cc index ae4933c..d5ad6ff 100644 --- a/cc/playback/recording_source.cc +++ b/cc/playback/recording_source.cc
@@ -192,7 +192,7 @@ display_list_->ApproximateOpCount()); gfx::Size layer_size = GetSize(); skia::AnalysisCanvas canvas(layer_size.width(), layer_size.height()); - display_list_->Raster(&canvas, nullptr, gfx::Rect(), 1.f); + display_list_->Raster(&canvas, nullptr, gfx::Rect(layer_size), 1.f); is_solid_color_ = canvas.GetColorIfSolid(&solid_color_); }
diff --git a/cc/proto/display_item.proto b/cc/proto/display_item.proto index 05cc060..2b7db4b 100644 --- a/cc/proto/display_item.proto +++ b/cc/proto/display_item.proto
@@ -21,8 +21,8 @@ message DisplayItemList { repeated DisplayItem items = 1; - optional cc.proto.Rect layer_rect = 2; optional DisplayItemListSettings settings = 3; + repeated cc.proto.Rect visual_rects = 4; } message DisplayItem {
diff --git a/cc/quads/draw_quad_unittest.cc b/cc/quads/draw_quad_unittest.cc index d30750c..8816733 100644 --- a/cc/quads/draw_quad_unittest.cc +++ b/cc/quads/draw_quad_unittest.cc
@@ -368,6 +368,15 @@ } \ SETUP_AND_COPY_QUAD_NEW(Type, quad_new); +#define CREATE_QUAD_13_ALL(Type, a, b, c, d, e, f, g, h, i, j, k, l, m) \ + Type* quad_all = render_pass->CreateAndAppendDrawQuad<Type>(); \ + { \ + QUAD_DATA quad_all->SetAll(shared_state, quad_rect, quad_opaque_rect, \ + quad_visible_rect, needs_blending, a, b, c, d, \ + e, f, g, h, i, j, k, l, m); \ + } \ + SETUP_AND_COPY_QUAD_ALL(Type, quad_all); + #define CREATE_QUAD_14_NEW(Type, a, b, c, d, e, f, g, h, i, j, k, l, m, n) \ Type* quad_new = render_pass->CreateAndAppendDrawQuad<Type>(); \ { \ @@ -376,6 +385,14 @@ } \ SETUP_AND_COPY_QUAD_NEW(Type, quad_new); +#define CREATE_QUAD_15_NEW(Type, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) \ + Type* quad_new = render_pass->CreateAndAppendDrawQuad<Type>(); \ + { \ + QUAD_DATA quad_new->SetNew(shared_state, quad_rect, a, b, c, d, e, f, g, \ + h, i, j, k, l, m, n, o); \ + } \ + SETUP_AND_COPY_QUAD_NEW(Type, quad_new); + #define CREATE_QUAD_ALL_RP(Type, a, b, c, d, e, f, g, copy_a) \ Type* quad_all = render_pass->CreateAndAppendDrawQuad<Type>(); \ { \ @@ -639,13 +656,15 @@ float resource_multiplier = 2.001f; uint32_t bits_per_channel = 5; YUVVideoDrawQuad::ColorSpace color_space = YUVVideoDrawQuad::JPEG; + gfx::ColorSpace video_color_space = gfx::ColorSpace::CreateJpeg(); CREATE_SHARED_STATE(); - CREATE_QUAD_14_NEW(YUVVideoDrawQuad, opaque_rect, visible_rect, + CREATE_QUAD_15_NEW(YUVVideoDrawQuad, opaque_rect, visible_rect, ya_tex_coord_rect, uv_tex_coord_rect, ya_tex_size, uv_tex_size, y_plane_resource_id, u_plane_resource_id, v_plane_resource_id, a_plane_resource_id, color_space, - resource_offset, resource_multiplier, bits_per_channel); + video_color_space, resource_offset, resource_multiplier, + bits_per_channel); EXPECT_EQ(DrawQuad::YUV_VIDEO_CONTENT, copy_quad->material); EXPECT_EQ(opaque_rect, copy_quad->opaque_rect); EXPECT_EQ(visible_rect, copy_quad->visible_rect); @@ -662,11 +681,11 @@ EXPECT_EQ(resource_multiplier, copy_quad->resource_multiplier); EXPECT_EQ(bits_per_channel, copy_quad->bits_per_channel); - CREATE_QUAD_12_ALL(YUVVideoDrawQuad, ya_tex_coord_rect, uv_tex_coord_rect, + CREATE_QUAD_13_ALL(YUVVideoDrawQuad, ya_tex_coord_rect, uv_tex_coord_rect, ya_tex_size, uv_tex_size, y_plane_resource_id, u_plane_resource_id, v_plane_resource_id, - a_plane_resource_id, color_space, resource_offset, - resource_multiplier, bits_per_channel); + a_plane_resource_id, color_space, video_color_space, + resource_offset, resource_multiplier, bits_per_channel); EXPECT_EQ(DrawQuad::YUV_VIDEO_CONTENT, copy_quad->material); EXPECT_EQ(ya_tex_coord_rect, copy_quad->ya_tex_coord_rect); EXPECT_EQ(uv_tex_coord_rect, copy_quad->uv_tex_coord_rect); @@ -879,13 +898,14 @@ ResourceId v_plane_resource_id = 4; ResourceId a_plane_resource_id = 63; YUVVideoDrawQuad::ColorSpace color_space = YUVVideoDrawQuad::JPEG; + gfx::ColorSpace video_color_space = gfx::ColorSpace::CreateJpeg(); CREATE_SHARED_STATE(); - CREATE_QUAD_14_NEW(YUVVideoDrawQuad, opaque_rect, visible_rect, + CREATE_QUAD_15_NEW(YUVVideoDrawQuad, opaque_rect, visible_rect, ya_tex_coord_rect, uv_tex_coord_rect, ya_tex_size, uv_tex_size, y_plane_resource_id, u_plane_resource_id, - v_plane_resource_id, a_plane_resource_id, color_space, 0.0, - 1.0, 5); + v_plane_resource_id, a_plane_resource_id, color_space, + video_color_space, 0.0, 1.0, 5); EXPECT_EQ(DrawQuad::YUV_VIDEO_CONTENT, copy_quad->material); EXPECT_EQ(y_plane_resource_id, quad_new->y_plane_resource_id()); EXPECT_EQ(u_plane_resource_id, quad_new->u_plane_resource_id());
diff --git a/cc/quads/yuv_video_draw_quad.cc b/cc/quads/yuv_video_draw_quad.cc index a3ac431..abe8d3f 100644 --- a/cc/quads/yuv_video_draw_quad.cc +++ b/cc/quads/yuv_video_draw_quad.cc
@@ -31,6 +31,7 @@ unsigned v_plane_resource_id, unsigned a_plane_resource_id, ColorSpace color_space, + const gfx::ColorSpace& video_color_space, float offset, float multiplier, uint32_t bits_per_channel) { @@ -47,6 +48,7 @@ resources.ids[kAPlaneResourceIdIndex] = a_plane_resource_id; resources.count = a_plane_resource_id ? 4 : 3; this->color_space = color_space; + this->video_color_space = video_color_space; this->resource_offset = offset; this->resource_multiplier = multiplier; this->bits_per_channel = bits_per_channel; @@ -66,6 +68,7 @@ unsigned v_plane_resource_id, unsigned a_plane_resource_id, ColorSpace color_space, + const gfx::ColorSpace& video_color_space, float offset, float multiplier, uint32_t bits_per_channel) { @@ -81,6 +84,7 @@ resources.ids[kAPlaneResourceIdIndex] = a_plane_resource_id; resources.count = resources.ids[kAPlaneResourceIdIndex] ? 4 : 3; this->color_space = color_space; + this->video_color_space = video_color_space; this->resource_offset = offset; this->resource_multiplier = multiplier; this->bits_per_channel = bits_per_channel;
diff --git a/cc/quads/yuv_video_draw_quad.h b/cc/quads/yuv_video_draw_quad.h index 2a26e6d..ef07848e 100644 --- a/cc/quads/yuv_video_draw_quad.h +++ b/cc/quads/yuv_video_draw_quad.h
@@ -11,6 +11,7 @@ #include "cc/base/cc_export.h" #include "cc/quads/draw_quad.h" +#include "ui/gfx/color_space.h" #include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/geometry/size.h" @@ -53,6 +54,7 @@ unsigned v_plane_resource_id, unsigned a_plane_resource_id, ColorSpace color_space, + const gfx::ColorSpace& video_color_space, float offset, float multiplier, uint32_t bits_per_channel); @@ -74,6 +76,7 @@ unsigned v_plane_resource_id, unsigned a_plane_resource_id, ColorSpace color_space, + const gfx::ColorSpace& video_color_space, float offset, float multiplier, uint32_t bits_per_channel); @@ -86,6 +89,8 @@ float resource_offset = 0.0f; float resource_multiplier = 1.0f; uint32_t bits_per_channel = 8; + // TODO(hubbe): Move to ResourceProvider::ScopedSamplerGL. + gfx::ColorSpace video_color_space; static const YUVVideoDrawQuad* MaterialCast(const DrawQuad*);
diff --git a/cc/raster/raster_buffer_provider_perftest.cc b/cc/raster/raster_buffer_provider_perftest.cc index 5ebd47a..fc5b5cb 100644 --- a/cc/raster/raster_buffer_provider_perftest.cc +++ b/cc/raster/raster_buffer_provider_perftest.cc
@@ -240,7 +240,7 @@ std::unique_ptr<ScopedResource> resource( ScopedResource::Create(resource_provider_.get())); resource->Allocate(size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, - RGBA_8888); + RGBA_8888, gfx::ColorSpace()); // No tile ids are given to support partial updates. std::unique_ptr<RasterBuffer> raster_buffer;
diff --git a/cc/raster/raster_buffer_provider_unittest.cc b/cc/raster/raster_buffer_provider_unittest.cc index ef6274c..a2aeeeb 100644 --- a/cc/raster/raster_buffer_provider_unittest.cc +++ b/cc/raster/raster_buffer_provider_unittest.cc
@@ -228,7 +228,7 @@ std::unique_ptr<ScopedResource> resource( ScopedResource::Create(resource_provider_.get())); resource->Allocate(size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, - RGBA_8888); + RGBA_8888, gfx::ColorSpace()); // The raster buffer has no tile ids associated with it for partial update, // so doesn't need to provide a valid dirty rect. @@ -247,7 +247,7 @@ std::unique_ptr<ScopedResource> resource( ScopedResource::Create(resource_provider_.get())); resource->Allocate(size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, - RGBA_8888); + RGBA_8888, gfx::ColorSpace()); std::unique_ptr<RasterBuffer> raster_buffer = raster_buffer_provider_->AcquireBufferForRaster(resource.get(), 0, 0);
diff --git a/cc/resources/resource.h b/cc/resources/resource.h index 7962d625..2075642 100644 --- a/cc/resources/resource.h +++ b/cc/resources/resource.h
@@ -17,14 +17,16 @@ class CC_EXPORT Resource { public: Resource() : id_(0), format_(RGBA_8888) {} - Resource(unsigned id, const gfx::Size& size, ResourceFormat format) - : id_(id), - size_(size), - format_(format) {} + Resource(unsigned id, + const gfx::Size& size, + ResourceFormat format, + const gfx::ColorSpace& color_space) + : id_(id), size_(size), format_(format), color_space_(color_space) {} ResourceId id() const { return id_; } gfx::Size size() const { return size_; } ResourceFormat format() const { return format_; } + const gfx::ColorSpace& color_space() const { return color_space_; } protected: void set_id(ResourceId id) { id_ = id; } @@ -32,11 +34,15 @@ size_ = size; format_ = format; } + void set_color_space(const gfx::ColorSpace& color_space) { + color_space_ = color_space; + } private: ResourceId id_; gfx::Size size_; ResourceFormat format_; + gfx::ColorSpace color_space_; DISALLOW_COPY_AND_ASSIGN(Resource); };
diff --git a/cc/resources/resource_pool.cc b/cc/resources/resource_pool.cc index fe4dabc..669897a 100644 --- a/cc/resources/resource_pool.cc +++ b/cc/resources/resource_pool.cc
@@ -95,7 +95,8 @@ } Resource* ResourcePool::AcquireResource(const gfx::Size& size, - ResourceFormat format) { + ResourceFormat format, + const gfx::ColorSpace& color_space) { // Finding resources in |unused_resources_| from MRU to LRU direction, touches // LRU resources only if needed, which increases possibility of expiring more // LRU resources within kResourceExpirationDelayMs. @@ -108,6 +109,8 @@ continue; if (resource->size() != size) continue; + if (resource->color_space() != color_space) + continue; // Transfer resource to |in_use_resources_|. in_use_resources_[resource->id()] = std::move(*it); @@ -121,10 +124,11 @@ PoolResource::Create(resource_provider_); if (use_gpu_memory_buffers_) { - pool_resource->AllocateWithGpuMemoryBuffer(size, format, usage_); + pool_resource->AllocateWithGpuMemoryBuffer(size, format, usage_, + color_space); } else { pool_resource->Allocate(size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, - format); + format, color_space); } DCHECK(ResourceUtil::VerifySizeInBytes<size_t>(pool_resource->size(),
diff --git a/cc/resources/resource_pool.h b/cc/resources/resource_pool.h index cd11c45..9f87c44 100644 --- a/cc/resources/resource_pool.h +++ b/cc/resources/resource_pool.h
@@ -44,7 +44,9 @@ ~ResourcePool() override; - Resource* AcquireResource(const gfx::Size& size, ResourceFormat format); + Resource* AcquireResource(const gfx::Size& size, + ResourceFormat format, + const gfx::ColorSpace& color_space); // Tries to acquire the resource with |previous_content_id| for us in partial // raster. If successful, this function will retun the invalidated rect which @@ -64,6 +66,9 @@ size_t max_resource_count); void ReduceResourceUsage(); + + // Must be called regularly to move resources from the busy pool to the unused + // pool. void CheckBusyResources(); size_t memory_usage_bytes() const { return in_use_memory_usage_bytes_; }
diff --git a/cc/resources/resource_pool_unittest.cc b/cc/resources/resource_pool_unittest.cc index 976afae..53ccf454 100644 --- a/cc/resources/resource_pool_unittest.cc +++ b/cc/resources/resource_pool_unittest.cc
@@ -44,7 +44,9 @@ TEST_F(ResourcePoolTest, AcquireRelease) { gfx::Size size(100, 100); ResourceFormat format = RGBA_8888; - Resource* resource = resource_pool_->AcquireResource(size, format); + gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB(); + Resource* resource = + resource_pool_->AcquireResource(size, format, color_space); EXPECT_EQ(size, resource->size()); EXPECT_EQ(format, resource->format()); EXPECT_TRUE(resource_provider_->CanLockForWrite(resource->id())); @@ -60,9 +62,11 @@ gfx::Size size(100, 100); ResourceFormat format = RGBA_8888; + gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB(); size_t resource_bytes = ResourceUtil::UncheckedSizeInBytes<size_t>(size, format); - Resource* resource = resource_pool_->AcquireResource(size, format); + Resource* resource = + resource_pool_->AcquireResource(size, format, color_space); EXPECT_EQ(resource_bytes, resource_pool_->GetTotalMemoryUsageForTesting()); EXPECT_EQ(resource_bytes, resource_pool_->memory_usage_bytes()); @@ -99,25 +103,36 @@ gfx::Size size(100, 100); ResourceFormat format = RGBA_8888; + gfx::ColorSpace color_space1; + gfx::ColorSpace color_space2 = gfx::ColorSpace::CreateSRGB(); - Resource* resource = resource_pool_->AcquireResource(size, format); + Resource* resource = + resource_pool_->AcquireResource(size, format, color_space1); resource_pool_->ReleaseResource(resource); resource_pool_->CheckBusyResources(); EXPECT_EQ(1u, resource_provider_->num_resources()); // Same size/format should re-use resource. - resource = resource_pool_->AcquireResource(size, format); + resource = resource_pool_->AcquireResource(size, format, color_space1); EXPECT_EQ(1u, resource_provider_->num_resources()); resource_pool_->ReleaseResource(resource); resource_pool_->CheckBusyResources(); EXPECT_EQ(1u, resource_provider_->num_resources()); - // Different size/format should alloate new resource. - resource = resource_pool_->AcquireResource(gfx::Size(50, 50), LUMINANCE_8); + // Different size/format should allocate new resource. + resource = resource_pool_->AcquireResource(gfx::Size(50, 50), LUMINANCE_8, + color_space1); EXPECT_EQ(2u, resource_provider_->num_resources()); resource_pool_->ReleaseResource(resource); resource_pool_->CheckBusyResources(); EXPECT_EQ(2u, resource_provider_->num_resources()); + + // Different color space should allocate new resource. + resource = resource_pool_->AcquireResource(size, format, color_space2); + EXPECT_EQ(3u, resource_provider_->num_resources()); + resource_pool_->ReleaseResource(resource); + resource_pool_->CheckBusyResources(); + EXPECT_EQ(3u, resource_provider_->num_resources()); } TEST_F(ResourcePoolTest, LostResource) { @@ -128,8 +143,10 @@ gfx::Size size(100, 100); ResourceFormat format = RGBA_8888; + gfx::ColorSpace color_space = gfx::ColorSpace::CreateSRGB(); - Resource* resource = resource_pool_->AcquireResource(size, format); + Resource* resource = + resource_pool_->AcquireResource(size, format, color_space); EXPECT_EQ(1u, resource_provider_->num_resources()); resource_provider_->LoseResourceForTesting(resource->id()); @@ -151,8 +168,10 @@ gfx::Size size(100, 100); ResourceFormat format = RGBA_8888; + gfx::ColorSpace color_space; - Resource* resource = resource_pool_->AcquireResource(size, format); + Resource* resource = + resource_pool_->AcquireResource(size, format, color_space); EXPECT_EQ(1u, resource_provider_->num_resources()); EXPECT_EQ(40000u, resource_pool_->GetTotalMemoryUsageForTesting()); EXPECT_EQ(1u, resource_pool_->resource_count()); @@ -188,8 +207,10 @@ gfx::Size size(100, 100); ResourceFormat format = RGBA_8888; + gfx::ColorSpace color_space; - Resource* resource = resource_pool_->AcquireResource(size, format); + Resource* resource = + resource_pool_->AcquireResource(size, format, color_space); EXPECT_EQ(1u, resource_provider_->num_resources()); EXPECT_EQ(40000u, resource_pool_->GetTotalMemoryUsageForTesting()); EXPECT_EQ(1u, resource_pool_->GetTotalResourceCountForTesting()); @@ -223,11 +244,13 @@ TEST_F(ResourcePoolTest, UpdateContentId) { gfx::Size size(100, 100); ResourceFormat format = RGBA_8888; + gfx::ColorSpace color_space; uint64_t content_id = 42; uint64_t new_content_id = 43; gfx::Rect new_invalidated_rect(20, 20, 10, 10); - Resource* resource = resource_pool_->AcquireResource(size, format); + Resource* resource = + resource_pool_->AcquireResource(size, format, color_space); resource_pool_->OnContentReplaced(resource->id(), content_id); resource_pool_->ReleaseResource(resource); resource_pool_->CheckBusyResources(); @@ -245,13 +268,15 @@ TEST_F(ResourcePoolTest, UpdateContentIdAndInvalidatedRect) { gfx::Size size(100, 100); ResourceFormat format = RGBA_8888; + gfx::ColorSpace color_space; uint64_t content_ids[] = {42, 43, 44}; gfx::Rect invalidated_rect(20, 20, 10, 10); gfx::Rect second_invalidated_rect(25, 25, 10, 10); gfx::Rect expected_total_invalidated_rect(20, 20, 15, 15); // Acquire a new resource with the first content id. - Resource* resource = resource_pool_->AcquireResource(size, format); + Resource* resource = + resource_pool_->AcquireResource(size, format, color_space); resource_pool_->OnContentReplaced(resource->id(), content_ids[0]); // Attempt to acquire this resource. It is in use, so its ID and invalidated
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index ce9b233..c2e850b 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc
@@ -548,26 +548,29 @@ } } -ResourceId ResourceProvider::CreateResource(const gfx::Size& size, - TextureHint hint, - ResourceFormat format) { +ResourceId ResourceProvider::CreateResource( + const gfx::Size& size, + TextureHint hint, + ResourceFormat format, + const gfx::ColorSpace& color_space) { DCHECK(!size.IsEmpty()); switch (default_resource_type_) { case RESOURCE_TYPE_GPU_MEMORY_BUFFER: // GPU memory buffers don't support LUMINANCE_F16. if (format != LUMINANCE_F16) { - return CreateGLTexture(size, hint, RESOURCE_TYPE_GPU_MEMORY_BUFFER, - format, - gfx::BufferUsage::GPU_READ_CPU_READ_WRITE); + return CreateGLTexture( + size, hint, RESOURCE_TYPE_GPU_MEMORY_BUFFER, format, + gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, color_space); } // Fall through and use a regular texture. case RESOURCE_TYPE_GL_TEXTURE: return CreateGLTexture(size, hint, RESOURCE_TYPE_GL_TEXTURE, format, - gfx::BufferUsage::GPU_READ_CPU_READ_WRITE); + gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, + color_space); case RESOURCE_TYPE_BITMAP: DCHECK_EQ(RGBA_8888, format); - return CreateBitmap(size); + return CreateBitmap(size, color_space); } LOG(FATAL) << "Invalid default resource type."; @@ -578,28 +581,31 @@ const gfx::Size& size, TextureHint hint, ResourceFormat format, - gfx::BufferUsage usage) { + gfx::BufferUsage usage, + const gfx::ColorSpace& color_space) { DCHECK(!size.IsEmpty()); switch (default_resource_type_) { case RESOURCE_TYPE_GPU_MEMORY_BUFFER: case RESOURCE_TYPE_GL_TEXTURE: { return CreateGLTexture(size, hint, RESOURCE_TYPE_GPU_MEMORY_BUFFER, - format, usage); + format, usage, color_space); } case RESOURCE_TYPE_BITMAP: DCHECK_EQ(RGBA_8888, format); - return CreateBitmap(size); + return CreateBitmap(size, color_space); } LOG(FATAL) << "Invalid default resource type."; return 0; } -ResourceId ResourceProvider::CreateGLTexture(const gfx::Size& size, - TextureHint hint, - ResourceType type, - ResourceFormat format, - gfx::BufferUsage usage) { +ResourceId ResourceProvider::CreateGLTexture( + const gfx::Size& size, + TextureHint hint, + ResourceType type, + ResourceFormat format, + gfx::BufferUsage usage, + const gfx::ColorSpace& color_space) { DCHECK_LE(size.width(), max_texture_size_); DCHECK_LE(size.height(), max_texture_size_); DCHECK(thread_checker_.CalledOnValidThread()); @@ -617,10 +623,12 @@ GL_LINEAR, hint, type, format)); resource->usage = usage; resource->allocated = false; + resource->color_space = color_space; return id; } -ResourceId ResourceProvider::CreateBitmap(const gfx::Size& size) { +ResourceId ResourceProvider::CreateBitmap(const gfx::Size& size, + const gfx::ColorSpace& color_space) { DCHECK(thread_checker_.CalledOnValidThread()); std::unique_ptr<SharedBitmap> bitmap = @@ -633,6 +641,7 @@ id, Resource(pixels, bitmap.release(), size, Resource::INTERNAL, GL_LINEAR)); resource->allocated = true; + resource->color_space = color_space; return id; }
diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h index 0207d87d..91ea858 100644 --- a/cc/resources/resource_provider.h +++ b/cc/resources/resource_provider.h
@@ -135,14 +135,16 @@ // Creates a resource of the default resource type. ResourceId CreateResource(const gfx::Size& size, TextureHint hint, - ResourceFormat format); + ResourceFormat format, + const gfx::ColorSpace& color_space); // Creates a resource for a particular texture target (the distinction between // texture targets has no effect in software mode). ResourceId CreateGpuMemoryBufferResource(const gfx::Size& size, TextureHint hint, ResourceFormat format, - gfx::BufferUsage usage); + gfx::BufferUsage usage, + const gfx::ColorSpace& color_space); // Wraps an external texture mailbox into a GL resource. ResourceId CreateResourceFromTextureMailbox( @@ -634,8 +636,10 @@ TextureHint hint, ResourceType type, ResourceFormat format, - gfx::BufferUsage usage); - ResourceId CreateBitmap(const gfx::Size& size); + gfx::BufferUsage usage, + const gfx::ColorSpace& color_space); + ResourceId CreateBitmap(const gfx::Size& size, + const gfx::ColorSpace& color_space); Resource* InsertResource(ResourceId id, Resource resource); Resource* GetResource(ResourceId id); const Resource* LockForRead(ResourceId id);
diff --git a/cc/resources/resource_provider_unittest.cc b/cc/resources/resource_provider_unittest.cc index 74d35267..7e00251 100644 --- a/cc/resources/resource_provider_unittest.cc +++ b/cc/resources/resource_provider_unittest.cc
@@ -562,7 +562,8 @@ ASSERT_EQ(4U, pixel_size); ResourceId id = resource_provider->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); EXPECT_EQ(1, static_cast<int>(resource_provider->num_resources())); if (expected_default_type == ResourceProvider::RESOURCE_TYPE_GL_TEXTURE) EXPECT_EQ(0u, context->NumTextures()); @@ -593,7 +594,8 @@ ASSERT_EQ(16U, pixel_size); ResourceId id = resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); uint8_t image[16] = {0}; resource_provider_->CopyToResource(id, image, size); @@ -626,18 +628,21 @@ size_t pixel_size = TextureSizeBytes(size, format); ASSERT_EQ(4U, pixel_size); + gfx::ColorSpace color_space1 = gfx::ColorSpace::CreateSRGB(); ResourceId id1 = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, color_space1); uint8_t data1[4] = { 1, 2, 3, 4 }; child_resource_provider_->CopyToResource(id1, data1, size); ResourceId id2 = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); uint8_t data2[4] = { 5, 5, 5, 5 }; child_resource_provider_->CopyToResource(id2, data2, size); ResourceId id3 = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); { ResourceProvider::ScopedWriteLockGpuMemoryBuffer lock( child_resource_provider_.get(), id3); @@ -655,10 +660,10 @@ external_sync_token.GetData()); EXPECT_TRUE(external_sync_token.HasData()); - gfx::ColorSpace id4_color_space = gfx::ColorSpace::CreateSRGB(); + gfx::ColorSpace color_space4 = gfx::ColorSpace::CreateXYZD50(); TextureMailbox id4_mailbox(external_mailbox, external_sync_token, GL_TEXTURE_EXTERNAL_OES); - id4_mailbox.set_color_space(id4_color_space); + id4_mailbox.set_color_space(color_space4); ResourceId id4 = child_resource_provider_->CreateResourceFromTextureMailbox( id4_mailbox, SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback))); @@ -752,10 +757,15 @@ EXPECT_FALSE(resource_provider_->IsOverlayCandidate(mapped_id4)); { + resource_provider_->WaitSyncTokenIfNeeded(mapped_id1); + ResourceProvider::ScopedReadLockGL lock1(resource_provider_.get(), + mapped_id1); + EXPECT_TRUE(lock1.color_space() == color_space1); + resource_provider_->WaitSyncTokenIfNeeded(mapped_id4); - ResourceProvider::ScopedReadLockGL lock(resource_provider_.get(), - mapped_id4); - EXPECT_TRUE(lock.color_space() == id4_color_space); + ResourceProvider::ScopedReadLockGL lock4(resource_provider_.get(), + mapped_id4); + EXPECT_TRUE(lock4.color_space() == color_space4); } { @@ -902,12 +912,14 @@ ASSERT_EQ(4U, pixel_size); ResourceId id1 = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); uint8_t data1[4] = {1, 2, 3, 4}; child_resource_provider_->CopyToResource(id1, data1, size); ResourceId id2 = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); { // Ensure locking the memory buffer doesn't create an unnecessary sync // point. @@ -1007,7 +1019,8 @@ ResourceFormat format = RGBA_8888; ResourceId id1 = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); uint8_t data1[4] = {1, 2, 3, 4}; child_resource_provider_->CopyToResource(id1, data1, size); @@ -1076,7 +1089,8 @@ ResourceFormat format = RGBA_8888; ResourceId id1 = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); uint8_t data1[4] = {1, 2, 3, 4}; child_resource_provider_->CopyToResource(id1, data1, size); child_resource_provider_->EnableReadLockFencesForTesting(id1); @@ -1133,13 +1147,15 @@ ResourceFormat format = RGBA_8888; ResourceId id1 = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); uint8_t data[4] = {1, 2, 3, 4}; child_resource_provider_->CopyToResource(id1, data, size); child_resource_provider_->EnableReadLockFencesForTesting(id1); ResourceId id2 = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); child_resource_provider_->CopyToResource(id2, data, size); ReturnedResourceArray returned_to_child; @@ -1199,13 +1215,15 @@ ResourceFormat format = RGBA_8888; ResourceId id1 = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); uint8_t data[4] = {1, 2, 3, 4}; child_resource_provider_->CopyToResource(id1, data, size); child_resource_provider_->EnableReadLockFencesForTesting(id1); ResourceId id2 = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); child_resource_provider_->CopyToResource(id2, data, size); ReturnedResourceArray returned_to_child; @@ -1261,12 +1279,14 @@ ASSERT_EQ(4U, pixel_size); ResourceId id1 = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); uint8_t data1[4] = { 1, 2, 3, 4 }; child_resource_provider_->CopyToResource(id1, data1, size); ResourceId id2 = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); uint8_t data2[4] = { 5, 5, 5, 5 }; child_resource_provider_->CopyToResource(id2, data2, size); @@ -1480,7 +1500,8 @@ ASSERT_EQ(4U, pixel_size); ResourceId id1 = child_resource_provider->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); uint8_t data1[4] = { 1, 2, 3, 4 }; child_resource_provider->CopyToResource(id1, data1, size); child_resource_provider->GenerateSyncTokenForResource(id1); @@ -1528,7 +1549,8 @@ ASSERT_EQ(4U, pixel_size); ResourceId id1 = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); uint8_t data1[4] = { 1, 2, 3, 4 }; child_resource_provider_->CopyToResource(id1, data1, size); @@ -1579,12 +1601,14 @@ ASSERT_EQ(4U, pixel_size); ResourceId id1 = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); uint8_t data1[4] = { 1, 2, 3, 4 }; child_resource_provider_->CopyToResource(id1, data1, size); ResourceId id2 = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); uint8_t data2[4] = {5, 5, 5, 5}; child_resource_provider_->CopyToResource(id2, data2, size); @@ -1683,12 +1707,14 @@ ASSERT_EQ(4U, pixel_size); ResourceId id1 = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); uint8_t data1[4] = {1, 2, 3, 4}; child_resource_provider_->CopyToResource(id1, data1, size); ResourceId id2 = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); uint8_t data2[4] = {5, 5, 5, 5}; child_resource_provider_->CopyToResource(id2, data2, size); @@ -1804,7 +1830,8 @@ ASSERT_EQ(4U, pixel_size); ResourceId id = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); uint8_t data[4] = { 1, 2, 3, 4 }; child_resource_provider_->CopyToResource(id, data, size); @@ -1859,7 +1886,8 @@ ASSERT_EQ(4U, pixel_size); ResourceId id = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); uint8_t data[4] = {1, 2, 3, 4}; child_resource_provider_->CopyToResource(id, data, size); @@ -2015,7 +2043,8 @@ ASSERT_EQ(4U, pixel_size); ResourceId id = child_resource_provider->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); // The new texture is created with GL_LINEAR. EXPECT_CALL(*child_context, bindTexture(GL_TEXTURE_2D, child_texture_id)) @@ -2291,7 +2320,8 @@ gfx::Size size(1, 1); ResourceFormat format = RGBA_8888; ResourceId resource = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); child_resource_provider_->AllocateForTesting(resource); // Expect a GL resource to be lost. bool should_lose_resource = @@ -2346,7 +2376,8 @@ gfx::Size size(1, 1); ResourceFormat format = RGBA_8888; ResourceId resource = child_resource_provider_->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); child_resource_provider_->AllocateForTesting(resource); ReturnedResourceArray returned_to_child; @@ -2648,7 +2679,8 @@ int texture_id = 1; ResourceId id = resource_provider->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); // Check that the texture gets created with the right sampler settings. EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)) @@ -2730,7 +2762,8 @@ // Check that the texture gets created with the right sampler settings. ResourceId id = resource_provider->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)); EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); @@ -2775,7 +2808,8 @@ for (int texture_id = 1; texture_id <= 2; ++texture_id) { // Check that the texture gets created with the right sampler settings. ResourceId id = resource_provider->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)); EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); @@ -2826,8 +2860,8 @@ }; for (GLuint texture_id = 1; texture_id <= arraysize(hints); ++texture_id) { // Check that the texture gets created with the right sampler settings. - ResourceId id = - resource_provider->CreateResource(size, hints[texture_id - 1], format); + ResourceId id = resource_provider->CreateResource( + size, hints[texture_id - 1], format, gfx::ColorSpace()); EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)); EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); @@ -3337,7 +3371,8 @@ // Lazy allocation. Don't allocate when creating the resource. id = resource_provider->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id)); EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(1); @@ -3350,7 +3385,8 @@ // Do allocate when we set the pixels. id = resource_provider->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id)); EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(3); @@ -3399,7 +3435,7 @@ for (GLuint texture_id = 1; texture_id <= arraysize(hints); ++texture_id) { // Lazy allocation. Don't allocate when creating the resource. ResourceId id = resource_provider->CreateResource( - size, hints[texture_id - 1], formats[i]); + size, hints[texture_id - 1], formats[i], gfx::ColorSpace()); EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id)); EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2); @@ -3457,7 +3493,7 @@ for (GLuint texture_id = 1; texture_id <= arraysize(hints); ++texture_id) { // Lazy allocation. Don't allocate when creating the resource. ResourceId id = resource_provider->CreateResource( - size, hints[texture_id - 1], formats[i]); + size, hints[texture_id - 1], formats[i], gfx::ColorSpace()); EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id)); EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2); @@ -3506,7 +3542,8 @@ DefaultBufferToTextureTargetMapForTesting())); id = resource_provider->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); EXPECT_CALL(*context, NextTextureId()) .WillOnce(Return(kTextureId)) @@ -3587,7 +3624,7 @@ int texture_id = 123; ResourceId id = resource_provider->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, ETC1); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, ETC1, gfx::ColorSpace()); EXPECT_NE(0u, id); EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id)); EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2); @@ -3622,7 +3659,7 @@ uint8_t pixels[8]; ResourceId id = resource_provider->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, ETC1); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, ETC1, gfx::ColorSpace()); EXPECT_NE(0u, id); EXPECT_CALL(*context, NextTextureId()).WillOnce(Return(texture_id)); EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(3); @@ -3679,7 +3716,8 @@ DefaultBufferToTextureTargetMapForTesting())); ResourceId id = resource_provider->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); resource_provider->AllocateForTesting(id); Mock::VerifyAndClearExpectations(context); @@ -3697,7 +3735,8 @@ DefaultBufferToTextureTargetMapForTesting())); ResourceId id = resource_provider->CreateResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); resource_provider->AllocateForTesting(id); Mock::VerifyAndClearExpectations(context);
diff --git a/cc/resources/scoped_resource.cc b/cc/resources/scoped_resource.cc index 532ca12..d65150d 100644 --- a/cc/resources/scoped_resource.cc +++ b/cc/resources/scoped_resource.cc
@@ -17,27 +17,33 @@ void ScopedResource::Allocate(const gfx::Size& size, ResourceProvider::TextureHint hint, - ResourceFormat format) { + ResourceFormat format, + const gfx::ColorSpace& color_space) { DCHECK(!id()); DCHECK(!size.IsEmpty()); set_dimensions(size, format); - set_id(resource_provider_->CreateResource(size, hint, format)); + set_id(resource_provider_->CreateResource(size, hint, format, color_space)); + set_color_space(color_space); #if DCHECK_IS_ON() allocate_thread_id_ = base::PlatformThread::CurrentId(); #endif } -void ScopedResource::AllocateWithGpuMemoryBuffer(const gfx::Size& size, - ResourceFormat format, - gfx::BufferUsage usage) { +void ScopedResource::AllocateWithGpuMemoryBuffer( + const gfx::Size& size, + ResourceFormat format, + gfx::BufferUsage usage, + const gfx::ColorSpace& color_space) { DCHECK(!id()); DCHECK(!size.IsEmpty()); set_dimensions(size, format); set_id(resource_provider_->CreateGpuMemoryBufferResource( - size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, usage)); + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, usage, + color_space)); + set_color_space(color_space); #if DCHECK_IS_ON() allocate_thread_id_ = base::PlatformThread::CurrentId();
diff --git a/cc/resources/scoped_resource.h b/cc/resources/scoped_resource.h index 80fd5e18..13f1e98 100644 --- a/cc/resources/scoped_resource.h +++ b/cc/resources/scoped_resource.h
@@ -29,10 +29,12 @@ void Allocate(const gfx::Size& size, ResourceProvider::TextureHint hint, - ResourceFormat format); + ResourceFormat format, + const gfx::ColorSpace& color_space); void AllocateWithGpuMemoryBuffer(const gfx::Size& size, ResourceFormat format, - gfx::BufferUsage usage); + gfx::BufferUsage usage, + const gfx::ColorSpace& color_space); void Free(); protected:
diff --git a/cc/resources/scoped_resource_unittest.cc b/cc/resources/scoped_resource_unittest.cc index dbb2625..d536e479 100644 --- a/cc/resources/scoped_resource_unittest.cc +++ b/cc/resources/scoped_resource_unittest.cc
@@ -53,7 +53,7 @@ std::unique_ptr<ScopedResource> texture = ScopedResource::Create(resource_provider.get()); texture->Allocate(gfx::Size(30, 30), ResourceProvider::TEXTURE_HINT_IMMUTABLE, - RGBA_8888); + RGBA_8888, gfx::ColorSpace()); // The texture has an allocated byte-size now. size_t expected_bytes = 30 * 30 * 4; @@ -82,7 +82,8 @@ EXPECT_EQ(0u, resource_provider->num_resources()); texture->Allocate(gfx::Size(30, 30), - ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); + ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888, + gfx::ColorSpace()); EXPECT_LT(0u, texture->id()); EXPECT_EQ(1u, resource_provider->num_resources()); } @@ -93,7 +94,8 @@ ScopedResource::Create(resource_provider.get()); EXPECT_EQ(0u, resource_provider->num_resources()); texture->Allocate(gfx::Size(30, 30), - ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); + ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888, + gfx::ColorSpace()); EXPECT_LT(0u, texture->id()); EXPECT_EQ(1u, resource_provider->num_resources()); texture->Free();
diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc index 3f94372..cdeb363e 100644 --- a/cc/resources/video_resource_updater.cc +++ b/cc/resources/video_resource_updater.cc
@@ -174,6 +174,7 @@ VideoResourceUpdater::ResourceList::iterator VideoResourceUpdater::AllocateResource(const gfx::Size& plane_size, ResourceFormat format, + const gfx::ColorSpace& color_space, bool has_mailbox, bool immutable_hint) { // TODO(danakj): Abstract out hw/sw resource create/delete from @@ -181,7 +182,7 @@ const ResourceId resource_id = resource_provider_->CreateResource( plane_size, immutable_hint ? ResourceProvider::TEXTURE_HINT_IMMUTABLE : ResourceProvider::TEXTURE_HINT_DEFAULT, - format); + format, color_space); if (resource_id == 0) return all_resources_.end(); @@ -356,9 +357,9 @@ // Check if we need to allocate a new resource. if (resource_it == all_resources_.end()) { const bool is_immutable = true; - resource_it = - AllocateResource(output_plane_resource_size, output_resource_format, - !software_compositor, is_immutable); + resource_it = AllocateResource( + output_plane_resource_size, output_resource_format, + video_frame->ColorSpace(), !software_compositor, is_immutable); } if (resource_it == all_resources_.end()) break; @@ -583,7 +584,7 @@ if (resource == all_resources_.end()) { const bool is_immutable = false; resource = AllocateResource(output_plane_resource_size, copy_target_format, - true, is_immutable); + video_frame->ColorSpace(), true, is_immutable); } resource->add_ref();
diff --git a/cc/resources/video_resource_updater.h b/cc/resources/video_resource_updater.h index 4dba54c..a5c063d 100644 --- a/cc/resources/video_resource_updater.h +++ b/cc/resources/video_resource_updater.h
@@ -138,6 +138,7 @@ typedef std::list<PlaneResource> ResourceList; ResourceList::iterator AllocateResource(const gfx::Size& plane_size, ResourceFormat format, + const gfx::ColorSpace& color_space, bool has_mailbox, bool immutable_hint); void DeleteResource(ResourceList::iterator resource_it);
diff --git a/cc/surfaces/display.cc b/cc/surfaces/display.cc index 9a5c7e5..31c9f176 100644 --- a/cc/surfaces/display.cc +++ b/cc/surfaces/display.cc
@@ -421,4 +421,9 @@ return current_surface_id_; } +void Display::ForceImmediateDrawAndSwapIfPossible() { + if (scheduler_) + scheduler_->ForceImmediateSwapIfPossible(); +} + } // namespace cc
diff --git a/cc/surfaces/display.h b/cc/surfaces/display.h index 0fc2fb0..235abf1 100644 --- a/cc/surfaces/display.h +++ b/cc/surfaces/display.h
@@ -117,6 +117,8 @@ bool has_scheduler() const { return !!scheduler_; } DirectRenderer* renderer_for_testing() const { return renderer_.get(); } + void ForceImmediateDrawAndSwapIfPossible(); + private: void InitializeRenderer(); void UpdateRootSurfaceResourcesLocked();
diff --git a/cc/test/fake_content_layer_client.cc b/cc/test/fake_content_layer_client.cc index 597eb02..11c8b3e 100644 --- a/cc/test/fake_content_layer_client.cc +++ b/cc/test/fake_content_layer_client.cc
@@ -55,7 +55,8 @@ DisplayItemListSettings settings; settings.use_cached_picture = display_list_use_cached_picture_; scoped_refptr<DisplayItemList> display_list = - DisplayItemList::Create(PaintableRegion(), settings); + DisplayItemList::Create(settings); + display_list->SetRetainVisualRectsForTesting(true); SkPictureRecorder recorder; sk_sp<SkCanvas> canvas;
diff --git a/cc/test/fake_proxy.h b/cc/test/fake_proxy.h index 0db56615..af7b99ed 100644 --- a/cc/test/fake_proxy.h +++ b/cc/test/fake_proxy.h
@@ -17,7 +17,6 @@ void SetLayerTreeHost(LayerTreeHost* host); - void FinishAllRendering() override {} bool IsStarted() const override; bool CommitToActiveTree() const override; void SetOutputSurface(OutputSurface* output_surface) override {}
diff --git a/cc/test/fake_ui_resource_layer_tree_host_impl.cc b/cc/test/fake_ui_resource_layer_tree_host_impl.cc index fd60c35..8d744df 100644 --- a/cc/test/fake_ui_resource_layer_tree_host_impl.cc +++ b/cc/test/fake_ui_resource_layer_tree_host_impl.cc
@@ -25,7 +25,8 @@ UIResourceData data; data.resource_id = resource_provider()->CreateResource( - bitmap.GetSize(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); + bitmap.GetSize(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888, + gfx::ColorSpace()); data.size = bitmap.GetSize(); data.opaque = bitmap.GetOpaque();
diff --git a/cc/test/render_pass_test_utils.cc b/cc/test/render_pass_test_utils.cc index f84774c..8855c48 100644 --- a/cc/test/render_pass_test_utils.cc +++ b/cc/test/render_pass_test_utils.cc
@@ -164,32 +164,32 @@ ResourceId resource1 = resource_provider->CreateResource( gfx::Size(45, 5), ResourceProvider::TEXTURE_HINT_IMMUTABLE, - resource_provider->best_texture_format()); + resource_provider->best_texture_format(), gfx::ColorSpace()); resource_provider->AllocateForTesting(resource1); ResourceId resource2 = resource_provider->CreateResource( gfx::Size(346, 61), ResourceProvider::TEXTURE_HINT_IMMUTABLE, - resource_provider->best_texture_format()); + resource_provider->best_texture_format(), gfx::ColorSpace()); resource_provider->AllocateForTesting(resource2); ResourceId resource3 = resource_provider->CreateResource( gfx::Size(12, 134), ResourceProvider::TEXTURE_HINT_IMMUTABLE, - resource_provider->best_texture_format()); + resource_provider->best_texture_format(), gfx::ColorSpace()); resource_provider->AllocateForTesting(resource3); ResourceId resource4 = resource_provider->CreateResource( gfx::Size(56, 12), ResourceProvider::TEXTURE_HINT_IMMUTABLE, - resource_provider->best_texture_format()); + resource_provider->best_texture_format(), gfx::ColorSpace()); resource_provider->AllocateForTesting(resource4); gfx::Size resource5_size(73, 26); ResourceId resource5 = resource_provider->CreateResource( resource5_size, ResourceProvider::TEXTURE_HINT_IMMUTABLE, - resource_provider->best_texture_format()); + resource_provider->best_texture_format(), gfx::ColorSpace()); resource_provider->AllocateForTesting(resource5); ResourceId resource6 = resource_provider->CreateResource( gfx::Size(64, 92), ResourceProvider::TEXTURE_HINT_IMMUTABLE, - resource_provider->best_texture_format()); + resource_provider->best_texture_format(), gfx::ColorSpace()); resource_provider->AllocateForTesting(resource6); ResourceId resource7 = resource_provider->CreateResource( gfx::Size(9, 14), ResourceProvider::TEXTURE_HINT_IMMUTABLE, - resource_provider->best_texture_format()); + resource_provider->best_texture_format(), gfx::ColorSpace()); resource_provider->AllocateForTesting(resource7); unsigned target = GL_TEXTURE_2D; @@ -282,18 +282,19 @@ for (int i = 0; i < 4; ++i) { plane_resources[i] = resource_provider->CreateResource( gfx::Size(20, 12), ResourceProvider::TEXTURE_HINT_IMMUTABLE, - resource_provider->best_texture_format()); + resource_provider->best_texture_format(), gfx::ColorSpace()); resource_provider->AllocateForTesting(plane_resources[i]); } YUVVideoDrawQuad::ColorSpace color_space = YUVVideoDrawQuad::REC_601; + YUVVideoDrawQuad* yuv_quad = to_pass->CreateAndAppendDrawQuad<YUVVideoDrawQuad>(); yuv_quad->SetNew(shared_state2, rect, opaque_rect, visible_rect, gfx::RectF(.0f, .0f, 100.0f, 100.0f), gfx::RectF(.0f, .0f, 50.0f, 50.0f), gfx::Size(100, 100), gfx::Size(50, 50), plane_resources[0], plane_resources[1], - plane_resources[2], plane_resources[3], color_space, 0.0, - 1.0, 8); + plane_resources[2], plane_resources[3], color_space, + gfx::ColorSpace::CreateJpeg(), 0.0, 1.0, 8); } } // namespace cc
diff --git a/cc/test/skia_common.cc b/cc/test/skia_common.cc index d7ffe2f..ec39908 100644 --- a/cc/test/skia_common.cc +++ b/cc/test/skia_common.cc
@@ -49,7 +49,7 @@ bitmap.installPixels(info, buffer, info.minRowBytes()); SkCanvas canvas(bitmap); canvas.clipRect(gfx::RectToSkRect(layer_rect)); - list->Raster(&canvas, NULL, gfx::Rect(), 1.0f); + list->Raster(&canvas, NULL, layer_rect, 1.0f); } bool AreDisplayListDrawingResultsSame(const gfx::Rect& layer_rect,
diff --git a/cc/test/solid_color_content_layer_client.cc b/cc/test/solid_color_content_layer_client.cc index f3a8ccd..b7138f27 100644 --- a/cc/test/solid_color_content_layer_client.cc +++ b/cc/test/solid_color_content_layer_client.cc
@@ -52,7 +52,7 @@ DisplayItemListSettings settings; settings.use_cached_picture = false; scoped_refptr<DisplayItemList> display_list = - DisplayItemList::Create(clip, settings); + DisplayItemList::Create(settings); display_list->CreateAndAppendDrawingItem<DrawingDisplayItem>( clip, recorder.finishRecordingAsPicture());
diff --git a/cc/test/test_delegating_output_surface.cc b/cc/test/test_delegating_output_surface.cc index 9f980c3..88b94ec 100644 --- a/cc/test/test_delegating_output_surface.cc +++ b/cc/test/test_delegating_output_surface.cc
@@ -10,7 +10,6 @@ #include "cc/output/begin_frame_args.h" #include "cc/output/copy_output_request.h" #include "cc/output/texture_mailbox_deleter.h" -#include "cc/test/begin_frame_args_test.h" static constexpr uint32_t kCompositorClientId = 1;
diff --git a/cc/test/test_delegating_output_surface.h b/cc/test/test_delegating_output_surface.h index f5ac294..fc5f1f81 100644 --- a/cc/test/test_delegating_output_surface.h +++ b/cc/test/test_delegating_output_surface.h
@@ -29,6 +29,7 @@ virtual void DisplayDidDrawAndSwap() = 0; }; +// Delegating output surface that owns and forwards frames to a Display. class TestDelegatingOutputSurface : public OutputSurface, public SurfaceFactoryClient, public DisplayClient { @@ -78,8 +79,8 @@ private: void DidDrawCallback(bool synchronous); - // TODO(danakj): These don't to be stored in unique_ptrs when OutputSurface - // is owned/destroyed on the compositor thread. + // TODO(danakj): These don't need to be stored in unique_ptrs when + // OutputSurface is owned/destroyed on the compositor thread. std::unique_ptr<SurfaceManager> surface_manager_; std::unique_ptr<SurfaceIdAllocator> surface_id_allocator_; SurfaceId delegated_surface_id_;
diff --git a/cc/tiles/tile_manager.cc b/cc/tiles/tile_manager.cc index 7323c21..ed30f46 100644 --- a/cc/tiles/tile_manager.cc +++ b/cc/tiles/tile_manager.cc
@@ -945,7 +945,8 @@ DCHECK_EQ(DetermineResourceFormat(tile), resource->format()); } else { resource = resource_pool_->AcquireResource(tile->desired_texture_size(), - DetermineResourceFormat(tile)); + DetermineResourceFormat(tile), + gfx::ColorSpace()); } // For LOW_RESOLUTION tiles, we don't draw or predecode images.
diff --git a/cc/tiles/tile_manager.h b/cc/tiles/tile_manager.h index ce69a7d..e81124a 100644 --- a/cc/tiles/tile_manager.h +++ b/cc/tiles/tile_manager.h
@@ -149,7 +149,7 @@ TileDrawInfo& draw_info = tiles[i]->draw_info(); draw_info.resource_ = resource_pool_->AcquireResource( tiles[i]->desired_texture_size(), - raster_buffer_provider_->GetResourceFormat(false)); + raster_buffer_provider_->GetResourceFormat(false), gfx::ColorSpace()); } }
diff --git a/cc/tiles/tile_manager_unittest.cc b/cc/tiles/tile_manager_unittest.cc index 3d657d7b..9e904b8 100644 --- a/cc/tiles/tile_manager_unittest.cc +++ b/cc/tiles/tile_manager_unittest.cc
@@ -1327,7 +1327,7 @@ EXPECT_TRUE(host_impl()->is_likely_to_require_a_draw()); Resource* resource = host_impl()->resource_pool()->AcquireResource( - gfx::Size(256, 256), RGBA_8888); + gfx::Size(256, 256), RGBA_8888, gfx::ColorSpace()); host_impl()->tile_manager()->CheckIfMoreTilesNeedToBePreparedForTesting(); EXPECT_FALSE(host_impl()->is_likely_to_require_a_draw()); @@ -1839,8 +1839,8 @@ &raster_buffer_provider); // Ensure there's a resource with our |kInvalidatedId| in the resource pool. - auto* resource = - host_impl->resource_pool()->AcquireResource(kTileSize, RGBA_8888); + auto* resource = host_impl->resource_pool()->AcquireResource( + kTileSize, RGBA_8888, gfx::ColorSpace()); host_impl->resource_pool()->OnContentReplaced(resource->id(), kInvalidatedId); host_impl->resource_pool()->ReleaseResource(resource); host_impl->resource_pool()->CheckBusyResources();
diff --git a/cc/trees/channel_main.h b/cc/trees/channel_main.h index c5dc59f..0466d77 100644 --- a/cc/trees/channel_main.h +++ b/cc/trees/channel_main.h
@@ -41,7 +41,6 @@ virtual void MainThreadHasStoppedFlingingOnImpl() = 0; virtual void SetInputThrottledUntilCommitOnImpl(bool is_throttled) = 0; virtual void SetDeferCommitsOnImpl(bool defer_commits) = 0; - virtual void FinishAllRenderingOnImpl(CompletionEvent* completion) = 0; virtual void SetVisibleOnImpl(bool visible) = 0; virtual void ReleaseOutputSurfaceOnImpl(CompletionEvent* completion) = 0; virtual void MainFrameWillHappenOnImplForTesting(
diff --git a/cc/trees/damage_tracker.cc b/cc/trees/damage_tracker.cc index 0f0eacd..73d4848 100644 --- a/cc/trees/damage_tracker.cc +++ b/cc/trees/damage_tracker.cc
@@ -139,7 +139,8 @@ damage_rect_for_this_update.Union(damage_from_surface_mask); damage_rect_for_this_update.Union(damage_from_leftover_rects); damage_rect_for_this_update = - filters.MapRect(damage_rect_for_this_update, SkMatrix::I()); + filters.MapRect(damage_rect_for_this_update, + target_surface->FiltersTransform().matrix()); } // Damage accumulates until we are notified that we actually did draw on that
diff --git a/cc/trees/damage_tracker_unittest.cc b/cc/trees/damage_tracker_unittest.cc index b73f2ba..74e7fa2 100644 --- a/cc/trees/damage_tracker_unittest.cc +++ b/cc/trees/damage_tracker_unittest.cc
@@ -27,6 +27,7 @@ namespace { void ExecuteCalculateDrawProperties(LayerImpl* root, + float device_scale_factor, LayerImplList* render_surface_layer_list) { // Sanity check: The test itself should create the root layer's render // surface, so that the surface (and its damage tracker) can @@ -35,7 +36,7 @@ FakeLayerTreeHostImpl::RecursiveUpdateNumChildren(root); LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, root->bounds(), render_surface_layer_list); + root, root->bounds(), device_scale_factor, render_surface_layer_list); LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); ASSERT_TRUE(root->render_surface()); } @@ -47,7 +48,7 @@ } } -void EmulateDrawingOneFrame(LayerImpl* root) { +void EmulateDrawingOneFrame(LayerImpl* root, float device_scale_factor = 1.f) { // This emulates only steps that are relevant to testing the damage tracker: // 1. computing the render passes and layerlists // 2. updating all damage trackers in the correct order @@ -55,7 +56,8 @@ // and surfaces. LayerImplList render_surface_layer_list; - ExecuteCalculateDrawProperties(root, &render_surface_layer_list); + ExecuteCalculateDrawProperties(root, device_scale_factor, + &render_surface_layer_list); // Iterate back-to-front, so that damage correctly propagates from descendant // surfaces to ancestors. @@ -665,6 +667,57 @@ child_damage_rect); } +TEST_F(DamageTrackerTest, VerifyDamageForHighDPIImageFilter) { + LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); + LayerImpl* child = root->test_properties()->children[0]; + gfx::Rect root_damage_rect, child_damage_rect; + + // Allow us to set damage on child too. + child->SetDrawsContent(true); + + FilterOperations filters; + filters.Append(FilterOperation::CreateBlurFilter(3.f)); + + // Setting the filter will damage the whole surface. + ClearDamageForAllSurfaces(root); + child->test_properties()->force_render_surface = true; + root->layer_tree_impl()->property_trees()->needs_rebuild = true; + int device_scale_factor = 2; + EmulateDrawingOneFrame(root, device_scale_factor); + child->OnFilterAnimated(filters); + EmulateDrawingOneFrame(root, device_scale_factor); + root_damage_rect = + root->render_surface()->damage_tracker()->current_damage_rect(); + child_damage_rect = + child->render_surface()->damage_tracker()->current_damage_rect(); + + // Blur outset is 9px for a 3px blur, scaled up by DSF. + int blur_outset = 9 * device_scale_factor; + gfx::Rect original_rect(100, 100, 100, 100); + gfx::Rect expected_child_damage_rect(60, 60); + expected_child_damage_rect.Inset(-blur_outset, -blur_outset); + gfx::Rect expected_root_damage_rect(child_damage_rect); + expected_root_damage_rect.Offset(200, 200); + gfx::Rect expected_total_damage_rect = expected_root_damage_rect; + expected_total_damage_rect.Union(original_rect); + EXPECT_EQ(expected_total_damage_rect, root_damage_rect); + EXPECT_EQ(expected_child_damage_rect, child_damage_rect); + + // Setting the update rect should damage only the affected area (original, + // outset by 3 * blur sigma * DSF). + ClearDamageForAllSurfaces(root); + child->SetUpdateRect(gfx::Rect(30, 30)); + EmulateDrawingOneFrame(root, device_scale_factor); + + root_damage_rect = + root->render_surface()->damage_tracker()->current_damage_rect(); + child_damage_rect = + child->render_surface()->damage_tracker()->current_damage_rect(); + + EXPECT_EQ(expected_root_damage_rect, root_damage_rect); + EXPECT_EQ(expected_child_damage_rect, child_damage_rect); +} + TEST_F(DamageTrackerTest, VerifyDamageForBackgroundBlurredChild) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); LayerImpl* child1 = root->test_properties()->children[0];
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 315c5b8a..8e0493a8 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -673,10 +673,6 @@ SetNeedsCommit(); } -void LayerTreeHost::FinishAllRendering() { - proxy_->FinishAllRendering(); -} - void LayerTreeHost::SetDeferCommits(bool defer_commits) { proxy_->SetDeferCommits(defer_commits); }
diff --git a/cc/trees/layer_tree_host.h b/cc/trees/layer_tree_host.h index 54445df..d7bb89d 100644 --- a/cc/trees/layer_tree_host.h +++ b/cc/trees/layer_tree_host.h
@@ -170,8 +170,6 @@ void LayoutAndUpdateLayers(); void Composite(base::TimeTicks frame_begin_time); - void FinishAllRendering(); - void SetDeferCommits(bool defer_commits); int source_frame_number() const { return source_frame_number_; }
diff --git a/cc/trees/layer_tree_host_common.cc b/cc/trees/layer_tree_host_common.cc index 7024f3a0..6306cc2 100644 --- a/cc/trees/layer_tree_host_common.cc +++ b/cc/trees/layer_tree_host_common.cc
@@ -109,11 +109,12 @@ CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, const gfx::Size& device_viewport_size, const gfx::Transform& device_transform, + float device_scale_factor, LayerImplList* render_surface_layer_list) : CalcDrawPropsImplInputs(root_layer, device_viewport_size, device_transform, - 1.f, + device_scale_factor, 1.f, NULL, NULL, @@ -134,10 +135,33 @@ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, const gfx::Size& device_viewport_size, + const gfx::Transform& device_transform, + LayerImplList* render_surface_layer_list) + : CalcDrawPropsImplInputsForTesting(root_layer, + device_viewport_size, + device_transform, + 1.f, + render_surface_layer_list) {} + +LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: + CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, + const gfx::Size& device_viewport_size, LayerImplList* render_surface_layer_list) : CalcDrawPropsImplInputsForTesting(root_layer, device_viewport_size, gfx::Transform(), + 1.f, + render_surface_layer_list) {} + +LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: + CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, + const gfx::Size& device_viewport_size, + float device_scale_factor, + LayerImplList* render_surface_layer_list) + : CalcDrawPropsImplInputsForTesting(root_layer, + device_viewport_size, + gfx::Transform(), + device_scale_factor, render_surface_layer_list) {} LayerTreeHostCommon::ScrollUpdateInfo::ScrollUpdateInfo()
diff --git a/cc/trees/layer_tree_host_common.h b/cc/trees/layer_tree_host_common.h index e50a514..6867e94 100644 --- a/cc/trees/layer_tree_host_common.h +++ b/cc/trees/layer_tree_host_common.h
@@ -108,9 +108,18 @@ CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, const gfx::Size& device_viewport_size, const gfx::Transform& device_transform, + float device_scale_factor, LayerImplList* render_surface_layer_list); CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, const gfx::Size& device_viewport_size, + const gfx::Transform& device_transform, + LayerImplList* render_surface_layer_list); + CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, + const gfx::Size& device_viewport_size, + LayerImplList* render_surface_layer_list); + CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, + const gfx::Size& device_viewport_size, + float device_scale_factor, LayerImplList* render_surface_layer_list); };
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 1cd732a..6891786 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -627,6 +627,27 @@ return scroll_elasticity_helper_.get(); } +bool LayerTreeHostImpl::GetScrollOffsetForLayer(int layer_id, + gfx::ScrollOffset* offset) { + LayerImpl* layer = active_tree()->FindActiveTreeLayerById(layer_id); + if (!layer) + return false; + + *offset = layer->CurrentScrollOffset(); + return true; +} + +bool LayerTreeHostImpl::ScrollLayerTo(int layer_id, + const gfx::ScrollOffset& offset) { + LayerImpl* layer = active_tree()->FindActiveTreeLayerById(layer_id); + if (!layer) + return false; + + layer->ScrollBy( + ScrollOffsetToVector2dF(offset - layer->CurrentScrollOffset())); + return true; +} + void LayerTreeHostImpl::QueueSwapPromiseForMainThreadScrollUpdate( std::unique_ptr<SwapPromise> swap_promise) { swap_promises_for_main_thread_scroll_update_.push_back( @@ -1695,11 +1716,6 @@ it->DidDrawFrame(); } -void LayerTreeHostImpl::FinishAllRendering() { - if (renderer_) - renderer_->Finish(); -} - int LayerTreeHostImpl::RequestedMSAASampleCount() const { if (settings_.gpu_rasterization_msaa_sample_count == -1) { // Use the most up-to-date version of device_scale_factor that we have. @@ -3664,7 +3680,8 @@ break; } id = resource_provider_->CreateResource( - bitmap.GetSize(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, format); + bitmap.GetSize(), ResourceProvider::TEXTURE_HINT_IMMUTABLE, format, + gfx::ColorSpace()); UIResourceData data; data.resource_id = id;
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h index 7f13dce..9ef5f6c 100644 --- a/cc/trees/layer_tree_host_impl.h +++ b/cc/trees/layer_tree_host_impl.h
@@ -202,6 +202,9 @@ std::unique_ptr<SwapPromiseMonitor> CreateLatencyInfoSwapPromiseMonitor( ui::LatencyInfo* latency) override; ScrollElasticityHelper* CreateScrollElasticityHelper() override; + bool GetScrollOffsetForLayer(int layer_id, + gfx::ScrollOffset* offset) override; + bool ScrollLayerTo(int layer_id, const gfx::ScrollOffset& offset) override; // TopControlsManagerClient implementation. float TopControlsHeight() const override; @@ -398,7 +401,6 @@ std::string LayerTreeAsJson() const; - void FinishAllRendering(); int RequestedMSAASampleCount() const; virtual bool InitializeRenderer(OutputSurface* output_surface);
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc index 7ecd6475f..696e1de 100644 --- a/cc/trees/layer_tree_host_impl_unittest.cc +++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -6490,7 +6490,8 @@ resource_id_(resource_provider->CreateResource( gfx::Size(1, 1), ResourceProvider::TEXTURE_HINT_IMMUTABLE, - RGBA_8888)) { + RGBA_8888, + gfx::ColorSpace())) { resource_provider->AllocateForTesting(resource_id_); SetBounds(gfx::Size(10, 10)); SetDrawsContent(true);
diff --git a/cc/trees/layer_tree_host_pixeltest_masks.cc b/cc/trees/layer_tree_host_pixeltest_masks.cc index 3d63cda3..3a37f8bd 100644 --- a/cc/trees/layer_tree_host_pixeltest_masks.cc +++ b/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -60,7 +60,7 @@ } scoped_refptr<DisplayItemList> display_list = - DisplayItemList::Create(PaintableRegion(), DisplayItemListSettings()); + DisplayItemList::Create(DisplayItemListSettings()); display_list->CreateAndAppendDrawingItem<DrawingDisplayItem>( PaintableRegion(), recorder.finishRecordingAsPicture()); @@ -360,7 +360,7 @@ } scoped_refptr<DisplayItemList> display_list = - DisplayItemList::Create(PaintableRegion(), DisplayItemListSettings()); + DisplayItemList::Create(DisplayItemListSettings()); display_list->CreateAndAppendDrawingItem<DrawingDisplayItem>( PaintableRegion(), recorder.finishRecordingAsPicture()); @@ -398,7 +398,7 @@ paint); scoped_refptr<DisplayItemList> display_list = - DisplayItemList::Create(PaintableRegion(), DisplayItemListSettings()); + DisplayItemList::Create(DisplayItemListSettings()); display_list->CreateAndAppendDrawingItem<DrawingDisplayItem>( PaintableRegion(), recorder.finishRecordingAsPicture());
diff --git a/cc/trees/layer_tree_host_pixeltest_tiles.cc b/cc/trees/layer_tree_host_pixeltest_tiles.cc index b6b1bb4..838a304 100644 --- a/cc/trees/layer_tree_host_pixeltest_tiles.cc +++ b/cc/trees/layer_tree_host_pixeltest_tiles.cc
@@ -113,7 +113,7 @@ DisplayItemListSettings settings; settings.use_cached_picture = false; scoped_refptr<DisplayItemList> display_list = - DisplayItemList::Create(PaintableRegion(), settings); + DisplayItemList::Create(settings); SkPictureRecorder recorder; sk_sp<SkCanvas> canvas =
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 1ea85c3..09cd0397 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -4484,7 +4484,7 @@ result_->did_swap_called = true; } - void DidNotSwap(DidNotSwapReason reason) override { + DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override { base::AutoLock lock(result_->lock); EXPECT_FALSE(result_->did_swap_called); EXPECT_FALSE(result_->did_not_swap_called); @@ -4492,6 +4492,7 @@ reason != DidNotSwapReason::SWAP_FAILS); result_->did_not_swap_called = true; result_->reason = reason; + return DidNotSwapAction::BREAK_PROMISE; } int64_t TraceId() const override { return 0; }
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc index feebe2e..d701b82b 100644 --- a/cc/trees/layer_tree_host_unittest_context.cc +++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -919,7 +919,8 @@ frame_data->render_pass_list.push_back(std::move(pass)); ResourceId resource = child_resource_provider_->CreateResource( - gfx::Size(4, 4), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888); + gfx::Size(4, 4), ResourceProvider::TEXTURE_HINT_IMMUTABLE, RGBA_8888, + gfx::ColorSpace()); ResourceProvider::ScopedWriteLockGL lock(child_resource_provider_.get(), resource, false);
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index 975e82e..0f0a4da 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc
@@ -1485,8 +1485,14 @@ void LayerTreeImpl::PassSwapPromises( std::vector<std::unique_ptr<SwapPromise>> new_swap_promises) { - for (const auto& swap_promise : swap_promise_list_) - swap_promise->DidNotSwap(SwapPromise::SWAP_FAILS); + for (auto& swap_promise : swap_promise_list_) { + if (swap_promise->DidNotSwap(SwapPromise::SWAP_FAILS) == + SwapPromise::DidNotSwapAction::KEEP_ACTIVE) { + // |swap_promise| must remain active, so place it in |new_swap_promises| + // in order to keep it alive and active. + new_swap_promises.push_back(std::move(swap_promise)); + } + } swap_promise_list_.clear(); swap_promise_list_.swap(new_swap_promises); } @@ -1508,12 +1514,30 @@ } void LayerTreeImpl::BreakSwapPromises(SwapPromise::DidNotSwapReason reason) { - for (const auto& swap_promise : swap_promise_list_) - swap_promise->DidNotSwap(reason); - swap_promise_list_.clear(); - for (const auto& swap_promise : pinned_swap_promise_list_) - swap_promise->DidNotSwap(reason); - pinned_swap_promise_list_.clear(); + { + std::vector<std::unique_ptr<SwapPromise>> persistent_swap_promises; + for (auto& swap_promise : swap_promise_list_) { + if (swap_promise->DidNotSwap(reason) == + SwapPromise::DidNotSwapAction::KEEP_ACTIVE) { + persistent_swap_promises.push_back(std::move(swap_promise)); + } + } + // |persistent_swap_promises| must remain active even when swap fails. + swap_promise_list_ = std::move(persistent_swap_promises); + } + + { + std::vector<std::unique_ptr<SwapPromise>> persistent_swap_promises; + for (auto& swap_promise : pinned_swap_promise_list_) { + if (swap_promise->DidNotSwap(reason) == + SwapPromise::DidNotSwapAction::KEEP_ACTIVE) { + persistent_swap_promises.push_back(std::move(swap_promise)); + } + } + + // |persistent_swap_promises| must remain active even when swap fails. + pinned_swap_promise_list_ = std::move(persistent_swap_promises); + } } void LayerTreeImpl::DidModifyTilePriorities() {
diff --git a/cc/trees/layer_tree_impl_unittest.cc b/cc/trees/layer_tree_impl_unittest.cc index a365985a..bb931cf9 100644 --- a/cc/trees/layer_tree_impl_unittest.cc +++ b/cc/trees/layer_tree_impl_unittest.cc
@@ -13,6 +13,7 @@ #include "cc/trees/draw_property_utils.h" #include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_host_impl.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace cc { @@ -2220,5 +2221,111 @@ EXPECT_EQ(2, result_layer->id()); } +namespace { + +class PersistentSwapPromise + : public SwapPromise, + public base::SupportsWeakPtr<PersistentSwapPromise> { + public: + PersistentSwapPromise() = default; + ~PersistentSwapPromise() override = default; + + void DidActivate() override {} + MOCK_METHOD1(DidSwap, void(CompositorFrameMetadata* metadata)); + + DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override { + return DidNotSwapAction::KEEP_ACTIVE; + } + + void OnCommit() override {} + int64_t TraceId() const override { return 0; } +}; + +class NotPersistentSwapPromise + : public SwapPromise, + public base::SupportsWeakPtr<NotPersistentSwapPromise> { + public: + NotPersistentSwapPromise() = default; + ~NotPersistentSwapPromise() override = default; + + void DidActivate() override {} + void DidSwap(CompositorFrameMetadata* metadata) override {} + + DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override { + return DidNotSwapAction::BREAK_PROMISE; + } + + void OnCommit() override {} + int64_t TraceId() const override { return 0; } +}; + +} // namespace + +TEST_F(LayerTreeImplTest, PersistentSwapPromisesAreKeptAlive) { + const size_t promises_count = 2; + + std::vector<base::WeakPtr<PersistentSwapPromise>> persistent_promises; + std::vector<std::unique_ptr<PersistentSwapPromise>> + persistent_promises_to_pass; + for (size_t i = 0; i < promises_count; ++i) { + persistent_promises_to_pass.push_back( + base::MakeUnique<PersistentSwapPromise>()); + } + + for (auto& promise : persistent_promises_to_pass) { + persistent_promises.push_back(promise->AsWeakPtr()); + host_impl().active_tree()->QueueSwapPromise(std::move(promise)); + } + + std::vector<std::unique_ptr<SwapPromise>> promises; + host_impl().active_tree()->PassSwapPromises(std::move(promises)); + host_impl().active_tree()->BreakSwapPromises( + SwapPromise::DidNotSwapReason::SWAP_FAILS); + + ASSERT_EQ(promises_count, persistent_promises.size()); + for (size_t i = 0; i < persistent_promises.size(); ++i) { + SCOPED_TRACE(testing::Message() << "While checking case #" << i); + ASSERT_TRUE(persistent_promises[i]); + EXPECT_CALL(*persistent_promises[i], DidSwap(testing::_)); + } + host_impl().active_tree()->FinishSwapPromises(nullptr); +} + +TEST_F(LayerTreeImplTest, NotPersistentSwapPromisesAreDroppedWhenSwapFails) { + const size_t promises_count = 2; + + std::vector<base::WeakPtr<NotPersistentSwapPromise>> not_persistent_promises; + std::vector<std::unique_ptr<NotPersistentSwapPromise>> + not_persistent_promises_to_pass; + for (size_t i = 0; i < promises_count; ++i) { + not_persistent_promises_to_pass.push_back( + base::MakeUnique<NotPersistentSwapPromise>()); + } + + for (auto& promise : not_persistent_promises_to_pass) { + not_persistent_promises.push_back(promise->AsWeakPtr()); + host_impl().active_tree()->QueueSwapPromise(std::move(promise)); + } + std::vector<std::unique_ptr<SwapPromise>> promises; + host_impl().active_tree()->PassSwapPromises(std::move(promises)); + + ASSERT_EQ(promises_count, not_persistent_promises.size()); + for (size_t i = 0; i < not_persistent_promises.size(); ++i) { + EXPECT_FALSE(not_persistent_promises[i]) << "While checking case #" << i; + } + + // Finally, check that not persistent promise doesn't survive + // |LayerTreeImpl::BreakSwapPromises|. + { + std::unique_ptr<NotPersistentSwapPromise> promise( + new NotPersistentSwapPromise()); + auto weak_promise = promise->AsWeakPtr(); + host_impl().active_tree()->QueueSwapPromise(std::move(promise)); + host_impl().active_tree()->BreakSwapPromises( + SwapPromise::DidNotSwapReason::SWAP_FAILS); + EXPECT_FALSE(weak_promise); + } +} + } // namespace } // namespace cc
diff --git a/cc/trees/proxy.h b/cc/trees/proxy.h index 09592bc2..be3a1ec 100644 --- a/cc/trees/proxy.h +++ b/cc/trees/proxy.h
@@ -36,8 +36,6 @@ public: virtual ~Proxy() {} - virtual void FinishAllRendering() = 0; - virtual bool IsStarted() const = 0; virtual bool CommitToActiveTree() const = 0;
diff --git a/cc/trees/proxy_impl.cc b/cc/trees/proxy_impl.cc index 4852da2a..7defc51f 100644 --- a/cc/trees/proxy_impl.cc +++ b/cc/trees/proxy_impl.cc
@@ -204,13 +204,6 @@ scheduler_->BeginMainFrameAborted(reason); } -void ProxyImpl::FinishAllRenderingOnImpl(CompletionEvent* completion) { - TRACE_EVENT0("cc", "ProxyImpl::FinishAllRenderingOnImplThread"); - DCHECK(IsImplThread()); - layer_tree_host_impl_->FinishAllRendering(); - completion->Signal(); -} - void ProxyImpl::SetVisibleOnImpl(bool visible) { TRACE_EVENT1("cc", "ProxyImpl::SetVisibleOnImplThread", "visible", visible); DCHECK(IsImplThread());
diff --git a/cc/trees/proxy_impl.h b/cc/trees/proxy_impl.h index 507ae33..116515ce 100644 --- a/cc/trees/proxy_impl.h +++ b/cc/trees/proxy_impl.h
@@ -44,7 +44,6 @@ CommitEarlyOutReason reason, base::TimeTicks main_thread_start_time, std::vector<std::unique_ptr<SwapPromise>> swap_promises); - void FinishAllRenderingOnImpl(CompletionEvent* completion); void SetVisibleOnImpl(bool visible); void ReleaseOutputSurfaceOnImpl(CompletionEvent* completion); void FinishGLOnImpl(CompletionEvent* completion);
diff --git a/cc/trees/proxy_main.cc b/cc/trees/proxy_main.cc index 2b78994..04de2809 100644 --- a/cc/trees/proxy_main.cc +++ b/cc/trees/proxy_main.cc
@@ -260,17 +260,6 @@ layer_tree_host_->DidBeginMainFrame(); } -void ProxyMain::FinishAllRendering() { - DCHECK(IsMainThread()); - DCHECK(!defer_commits_); - - // Make sure all GL drawing is finished on the impl thread. - DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_); - CompletionEvent completion; - channel_main_->FinishAllRenderingOnImpl(&completion); - completion.Wait(); -} - bool ProxyMain::IsStarted() const { DCHECK(IsMainThread()); return started_;
diff --git a/cc/trees/proxy_main.h b/cc/trees/proxy_main.h index bd5f7d7..41c35496 100644 --- a/cc/trees/proxy_main.h +++ b/cc/trees/proxy_main.h
@@ -81,7 +81,6 @@ friend class ProxyMainForTest; // Proxy implementation. - void FinishAllRendering() override; bool IsStarted() const override; bool CommitToActiveTree() const override; void SetOutputSurface(OutputSurface* output_surface) override;
diff --git a/cc/trees/remote_channel_impl.cc b/cc/trees/remote_channel_impl.cc index 0ffaecf..54547afe 100644 --- a/cc/trees/remote_channel_impl.cc +++ b/cc/trees/remote_channel_impl.cc
@@ -150,10 +150,6 @@ } } -void RemoteChannelImpl::FinishAllRendering() { - NOTREACHED() << "Should not be called on the remote client LayerTreeHost"; -} - bool RemoteChannelImpl::IsStarted() const { DCHECK(task_runner_provider_->IsMainThread()); return main().started;
diff --git a/cc/trees/remote_channel_impl.h b/cc/trees/remote_channel_impl.h index daca018d..81ae01b 100644 --- a/cc/trees/remote_channel_impl.h +++ b/cc/trees/remote_channel_impl.h
@@ -131,7 +131,6 @@ std::unique_ptr<proto::CompositorMessage> proto) override; // Proxy implementation - void FinishAllRendering() override; bool IsStarted() const override; bool CommitToActiveTree() const override; void SetOutputSurface(OutputSurface* output_surface) override;
diff --git a/cc/trees/remote_channel_main.cc b/cc/trees/remote_channel_main.cc index b9db7fa..4487d09 100644 --- a/cc/trees/remote_channel_main.cc +++ b/cc/trees/remote_channel_main.cc
@@ -100,10 +100,6 @@ SendMessageProto(proto); } -void RemoteChannelMain::FinishAllRenderingOnImpl(CompletionEvent* completion) { - completion->Signal(); -} - void RemoteChannelMain::SetVisibleOnImpl(bool visible) { NOTIMPLEMENTED() << "Visibility is not controlled by the server"; }
diff --git a/cc/trees/remote_channel_main.h b/cc/trees/remote_channel_main.h index 50845de0..b6d15bb 100644 --- a/cc/trees/remote_channel_main.h +++ b/cc/trees/remote_channel_main.h
@@ -39,7 +39,6 @@ void MainThreadHasStoppedFlingingOnImpl() override; void SetInputThrottledUntilCommitOnImpl(bool is_throttled) override; void SetDeferCommitsOnImpl(bool defer_commits) override; - void FinishAllRenderingOnImpl(CompletionEvent* completion) override; void SetVisibleOnImpl(bool visible) override; void ReleaseOutputSurfaceOnImpl(CompletionEvent* completion) override; void MainFrameWillHappenOnImplForTesting(
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc index b0c1abb..cf9206c 100644 --- a/cc/trees/single_thread_proxy.cc +++ b/cc/trees/single_thread_proxy.cc
@@ -108,15 +108,6 @@ DCHECK(!layer_tree_host_impl_); } -void SingleThreadProxy::FinishAllRendering() { - TRACE_EVENT0("cc", "SingleThreadProxy::FinishAllRendering"); - DCHECK(task_runner_provider_->IsMainThread()); - { - DebugScopedSetImplThread impl(task_runner_provider_); - layer_tree_host_impl_->FinishAllRendering(); - } -} - bool SingleThreadProxy::IsStarted() const { DCHECK(task_runner_provider_->IsMainThread()); return !!layer_tree_host_impl_; @@ -254,15 +245,6 @@ "461509 SingleThreadProxy::DoCommit7")); layer_tree_host_->FinishCommitOnImplThread(layer_tree_host_impl_.get()); -#if DCHECK_IS_ON() - // In the single-threaded case, the scale and scroll deltas should never be - // touched on the impl layer tree. - std::unique_ptr<ScrollAndScaleSet> scroll_info = - layer_tree_host_impl_->ProcessScrollDeltas(); - DCHECK(scroll_info->scrolls.empty()); - DCHECK_EQ(1.f, scroll_info->page_scale_delta); -#endif - if (scheduler_on_impl_thread_) scheduler_on_impl_thread_->DidCommit(); @@ -803,6 +785,14 @@ void SingleThreadProxy::DoBeginMainFrame( const BeginFrameArgs& begin_frame_args) { + // In the single-threaded case, the scale deltas should never be touched on + // the impl layer tree. However, impl-side scroll deltas may be manipulated + // directly via the InputHandler on the UI thread. + std::unique_ptr<ScrollAndScaleSet> scroll_info = + layer_tree_host_impl_->ProcessScrollDeltas(); + DCHECK_EQ(1.f, scroll_info->page_scale_delta); + layer_tree_host_->ApplyScrollAndScale(scroll_info.get()); + layer_tree_host_->WillBeginMainFrame(); layer_tree_host_->BeginMainFrame(begin_frame_args); layer_tree_host_->AnimateLayers(begin_frame_args.frame_time);
diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h index 46d7db7b..9e091ac 100644 --- a/cc/trees/single_thread_proxy.h +++ b/cc/trees/single_thread_proxy.h
@@ -36,7 +36,6 @@ ~SingleThreadProxy() override; // Proxy implementation - void FinishAllRendering() override; bool IsStarted() const override; bool CommitToActiveTree() const override; void SetOutputSurface(OutputSurface* output_surface) override;
diff --git a/cc/trees/threaded_channel.cc b/cc/trees/threaded_channel.cc index 67902ae..0ee94696 100644 --- a/cc/trees/threaded_channel.cc +++ b/cc/trees/threaded_channel.cc
@@ -116,13 +116,6 @@ base::Bind(&ProxyImpl::SetVisibleOnImpl, proxy_impl_weak_ptr_, visible)); } -void ThreadedChannel::FinishAllRenderingOnImpl(CompletionEvent* completion) { - DCHECK(IsMainThread()); - ImplThreadTaskRunner()->PostTask( - FROM_HERE, base::Bind(&ProxyImpl::FinishAllRenderingOnImpl, - proxy_impl_weak_ptr_, completion)); -} - void ThreadedChannel::ReleaseOutputSurfaceOnImpl(CompletionEvent* completion) { DCHECK(IsMainThread()); ImplThreadTaskRunner()->PostTask(
diff --git a/cc/trees/threaded_channel.h b/cc/trees/threaded_channel.h index 2333e33..06325efe5 100644 --- a/cc/trees/threaded_channel.h +++ b/cc/trees/threaded_channel.h
@@ -102,7 +102,6 @@ void SetVisibleOnImpl(bool visible) override; // Blocking calls to ProxyImpl - void FinishAllRenderingOnImpl(CompletionEvent* completion) override; void ReleaseOutputSurfaceOnImpl(CompletionEvent* completion) override; void MainFrameWillHappenOnImplForTesting( CompletionEvent* completion,
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index e894e2a..55aa467 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -282,9 +282,6 @@ # This target is a forwarding target to compile the necessary DLLs used # by Chrome. group("chrome_dll") { - # TODO(GYP) support incremental_chrome_dll on Windows for faster links in - # developer component builds. When that's supported, this target will need - # to become more complicated. data_deps = [ ":main_dll", ] @@ -353,10 +350,13 @@ "/DELAYLOAD:wsock32.dll", ] - # This is a large module that can't do incremental linking in some cases. - configs -= [ "//build/config/win:default_incremental_linking" ] - configs += - [ "//build/config/win:default_large_module_incremental_linking" ] + if (!is_component_build) { + # This is a large module that can't do incremental linking in some + # cases. + configs -= [ "//build/config/win:default_incremental_linking" ] + configs += + [ "//build/config/win:default_large_module_incremental_linking" ] + } } if (use_aura) {
diff --git a/chrome/VERSION b/chrome/VERSION index fa8b377..6e41e36 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=54 MINOR=0 -BUILD=2826 +BUILD=2830 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index f4363175e..04355f9 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -145,6 +145,7 @@ android_library("chrome_java") { deps = [ ":chrome_public_apk_manifest", + ":chrome_public_apk_template_resources", "//base:base_java", "//chrome/android/webapk/libs/client:client_java", "//chrome/android/webapk/libs/common:common_java", @@ -549,9 +550,7 @@ apk_name = "ChromePublic" shared_libraries = [ ":chrome" ] - deps = [ - ":chrome_public_apk_template_resources", - ] + deps = [] } chrome_public_apk_tmpl_shared("chrome_sync_shell_apk") {
diff --git a/chrome/android/java/proguard.flags b/chrome/android/java/proguard.flags index c6c45d17..3c8276cd 100644 --- a/chrome/android/java/proguard.flags +++ b/chrome/android/java/proguard.flags
@@ -8,15 +8,6 @@ -keep public class com.google.android.apps.chrome** extends android.app.Fragment -keep public class org.chromium** extends android.app.Fragment -# Keep protobuf code used via reflection -# TODO(tonyg): Removing these -keeps results in new notes, but nothing seems to -# break. This exclusion costs almost 100k of dex size so consider replacing it -# with a -dontnote after more testing. --keep class com.google.protobuf.** { - *** newBuilder(); - *** parseFrom(java.io.InputStream); -} - # Keep the client interfaces for cacheinvalidation as they are used as # argument types for some of our code that we're keeping and proguard warns # otherwise. @@ -25,7 +16,7 @@ } # Keep all Parcelables as they might be marshalled outside Chrome. --keepclassmembernames class * implements android.os.Parcelable { +-keepnames class * implements android.os.Parcelable { public static final ** CREATOR; } @@ -42,10 +33,3 @@ # Don't warn about those in case this app is linking against an older # platform version. We know about them, and they are safe. -dontwarn android.support.** - -# Proguard mistakenly optimizes away some null checks on final fields -# in the support library. -# See https://sourceforge.net/p/proguard/bugs/531/#fdc9/41e2 --keepclassmembers,allowshrinking,allowobfuscation class android.support.v7.widget.AppCompatButton { - !static final <fields>; -}
diff --git a/chrome/android/java/res/drawable-hdpi/bookmark_filter_offline_pages.png b/chrome/android/java/res/drawable-hdpi/bookmark_filter_offline_pages.png deleted file mode 100644 index d9aacea..0000000 --- a/chrome/android/java/res/drawable-hdpi/bookmark_filter_offline_pages.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/bookmark_filter_offline_pages.png b/chrome/android/java/res/drawable-mdpi/bookmark_filter_offline_pages.png deleted file mode 100644 index c2c845e8..0000000 --- a/chrome/android/java/res/drawable-mdpi/bookmark_filter_offline_pages.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/bookmark_filter_offline_pages.png b/chrome/android/java/res/drawable-xhdpi/bookmark_filter_offline_pages.png deleted file mode 100644 index 9495f288..0000000 --- a/chrome/android/java/res/drawable-xhdpi/bookmark_filter_offline_pages.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/bookmark_filter_offline_pages.png b/chrome/android/java/res/drawable-xxhdpi/bookmark_filter_offline_pages.png deleted file mode 100644 index ce97c85..0000000 --- a/chrome/android/java/res/drawable-xxhdpi/bookmark_filter_offline_pages.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/bookmark_filter_offline_pages.png b/chrome/android/java/res/drawable-xxxhdpi/bookmark_filter_offline_pages.png deleted file mode 100644 index 8c83bff..0000000 --- a/chrome/android/java/res/drawable-xxxhdpi/bookmark_filter_offline_pages.png +++ /dev/null Binary files differ
diff --git a/chrome/android/java/res/layout/download_manager_ui_space_widget.xml b/chrome/android/java/res/layout/download_manager_ui_space_widget.xml index af49fe41..34927e4e 100644 --- a/chrome/android/java/res/layout/download_manager_ui_space_widget.xml +++ b/chrome/android/java/res/layout/download_manager_ui_space_widget.xml
@@ -15,7 +15,7 @@ android:paddingStart="@dimen/drawer_margin_large" android:paddingEnd="@dimen/drawer_margin_large" android:textColor="@color/light_active_color" - android:textSize="32sp" /> + android:textSize="28sp" /> <TextView android:id="@+id/space_total_display" @@ -23,7 +23,8 @@ android:layout_height="wrap_content" android:paddingStart="@dimen/drawer_margin_large" android:paddingEnd="@dimen/drawer_margin_large" - android:textColor="@color/descriptive_text_color" /> + android:textColor="@color/descriptive_text_color" + android:textSize="14sp" /> <!-- TODO(dfalcantara): Style this toolbar as Material on JB & KK. These are currently broken in the support library and look Holo.
diff --git a/chrome/android/java/res/layout/four_button_menu_item.xml b/chrome/android/java/res/layout/four_button_menu_item.xml deleted file mode 100644 index bbec6abb..0000000 --- a/chrome/android/java/res/layout/four_button_menu_item.xml +++ /dev/null
@@ -1,44 +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. ---> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="match_parent" - android:layout_height="?android:attr/listPreferredItemHeightSmall" - android:layout_gravity="top|start" - android:orientation="horizontal"> - - <org.chromium.chrome.browser.widget.TintedImageButton - android:id="@+id/button_one" - android:layout_width="0dp" - android:layout_height="match_parent" - android:layout_weight="1" - android:background="?attr/listChoiceBackgroundIndicator" - android:scaleType="center" /> - - <org.chromium.chrome.browser.widget.TintedImageButton - android:id="@+id/button_two" - android:layout_width="0dp" - android:layout_height="match_parent" - android:layout_weight="1" - android:background="?attr/listChoiceBackgroundIndicator" - android:scaleType="center" /> - - <org.chromium.chrome.browser.widget.TintedImageButton - android:id="@+id/button_three" - android:layout_width="0dp" - android:layout_height="match_parent" - android:layout_weight="1" - android:background="?attr/listChoiceBackgroundIndicator" - android:scaleType="center" /> - - <org.chromium.chrome.browser.widget.TintedImageButton - android:id="@+id/button_four" - android:layout_width="0dp" - android:layout_height="match_parent" - android:layout_weight="1" - android:background="?attr/listChoiceBackgroundIndicator" - android:scaleType="center" /> -</LinearLayout>
diff --git a/chrome/android/java/res/layout/icon_row_menu_item.xml b/chrome/android/java/res/layout/icon_row_menu_item.xml new file mode 100644 index 0000000..f1f9e96 --- /dev/null +++ b/chrome/android/java/res/layout/icon_row_menu_item.xml
@@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2016 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="match_parent" + android:layout_height="?android:attr/listPreferredItemHeightSmall" + android:layout_gravity="top|start" + android:orientation="horizontal"> + + <org.chromium.chrome.browser.widget.TintedImageButton + android:id="@+id/button_one" + style="@style/OverflowMenuButton" /> + + <org.chromium.chrome.browser.widget.TintedImageButton + android:id="@+id/button_two" + style="@style/OverflowMenuButton" /> + + <org.chromium.chrome.browser.widget.TintedImageButton + android:id="@+id/button_three" + style="@style/OverflowMenuButton" /> + + <org.chromium.chrome.browser.widget.TintedImageButton + android:id="@+id/button_four" + style="@style/OverflowMenuButton" /> + + <org.chromium.chrome.browser.widget.TintedImageButton + android:id="@+id/button_five" + style="@style/OverflowMenuButton" /> +</LinearLayout>
diff --git a/chrome/android/java/res/layout/new_tab_page_action_card.xml b/chrome/android/java/res/layout/new_tab_page_action_card.xml index 8c2d1b41..e9fdccc 100644 --- a/chrome/android/java/res/layout/new_tab_page_action_card.xml +++ b/chrome/android/java/res/layout/new_tab_page_action_card.xml
@@ -3,35 +3,32 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<!-- The Layout takes the regular NTP Card attributes (padding, background - drawable) and adds the selectable ripple effects as foreground. The - foreground property requires to use a FrameLayout. --> -<FrameLayout +<!-- Unlike regular cards, we use a material standard 8dp padding instead of the + bigger one related to the peeking behaviour. This card will only have + buttons, that have themselves some padding. We just stay within the + material specifications. --> +<LinearLayout 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="wrap_content" - android:foreground="?attr/selectableItemBackgroundBorderless" - android:clickable="true" - android:padding="@dimen/snippets_padding_and_peeking_card_height" + android:orientation="vertical" + android:padding="8dp" android:background="@drawable/ntp_card"> - <!-- We don't use a button here since the effect and the click handler will - be done at the parent level, directly on the layout. We transferred - select styling properties from ButtonCompatBorderless and made it - unfocusable.--> - <TextView - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:clickable="false" - android:focusable="false" - android:gravity="center_vertical|center_horizontal" - android:minHeight="36dp" - android:paddingStart="8dp" - android:text="@string/more" - android:textAllCaps="true" - android:textColor="@color/light_active_color" - android:textSize="15sp" - android:textStyle="bold" /> -</FrameLayout> + <!-- Using some standard metrics (minWidth, paddings) to override the + special ones used in ButtonCompatBorderless --> + <Button + android:id="@+id/action_button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center_vertical|center_horizontal" + android:minWidth="0dp" + android:paddingEnd="16dp" + android:paddingStart="16dp" + android:text="@string/more" + android:textAllCaps="true" + android:textColor="@color/light_active_color" + style="@style/ButtonCompatBorderless" /> +</LinearLayout>
diff --git a/chrome/android/java/res/layout/new_tab_page_snippets_card.xml b/chrome/android/java/res/layout/new_tab_page_snippets_card.xml index b2a9109..4b1ca554 100644 --- a/chrome/android/java/res/layout/new_tab_page_snippets_card.xml +++ b/chrome/android/java/res/layout/new_tab_page_snippets_card.xml
@@ -41,7 +41,7 @@ android:id="@+id/article_publisher" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="16dp" + android:layout_marginTop="@dimen/snippets_publisher_margin_top_with_article_snippet" android:layout_alignParentStart="true" android:layout_below="@+id/article_snippet" android:drawablePadding="8dp"
diff --git a/chrome/android/java/res/layout/three_button_menu_item.xml b/chrome/android/java/res/layout/three_button_menu_item.xml deleted file mode 100644 index 6ec9040f..0000000 --- a/chrome/android/java/res/layout/three_button_menu_item.xml +++ /dev/null
@@ -1,36 +0,0 @@ -<?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="match_parent" - android:layout_height="?android:attr/listPreferredItemHeightSmall" - android:layout_gravity="top|start" - android:orientation="horizontal"> - - <org.chromium.chrome.browser.widget.TintedImageButton - android:id="@+id/button_one" - android:layout_width="0dp" - android:layout_height="match_parent" - android:layout_weight="1" - android:background="?attr/listChoiceBackgroundIndicator" - android:scaleType="center" /> - - <org.chromium.chrome.browser.widget.TintedImageButton - android:id="@+id/button_two" - android:layout_width="0dp" - android:layout_height="match_parent" - android:layout_weight="1" - android:background="?attr/listChoiceBackgroundIndicator" - android:scaleType="center" /> - - <org.chromium.chrome.browser.widget.TintedImageButton - android:id="@+id/button_three" - android:layout_width="0dp" - android:layout_height="match_parent" - android:layout_weight="1" - android:background="?attr/listChoiceBackgroundIndicator" - android:scaleType="center" /> -</LinearLayout>
diff --git a/chrome/android/java/res/menu/main_menu.xml b/chrome/android/java/res/menu/main_menu.xml index 216206b..ab351d8 100644 --- a/chrome/android/java/res/menu/main_menu.xml +++ b/chrome/android/java/res/menu/main_menu.xml
@@ -16,6 +16,9 @@ <item android:id="@+id/bookmark_this_page_id" android:title="@string/accessibility_menu_bookmark" android:icon="@drawable/btn_star"/> + <item android:id="@+id/offline_page_id" + android:title="@string/contextmenu_save_offline" + android:icon="@drawable/ic_get_app_white_24dp"/> <item android:id="@+id/info_menu_id" android:title="@string/accessibility_menu_info" android:icon="@drawable/btn_info" />
diff --git a/chrome/android/java/res/values-v17/styles.xml b/chrome/android/java/res/values-v17/styles.xml index d3a61503..02bc471a 100644 --- a/chrome/android/java/res/values-v17/styles.xml +++ b/chrome/android/java/res/values-v17/styles.xml
@@ -221,6 +221,13 @@ <item name="android:listPreferredItemHeightSmall">48dp</item> <item name="android:textSize">16sp</item> </style> + <style name="OverflowMenuButton"> + <item name="android:layout_width">0dp</item> + <item name="android:layout_height">match_parent</item> + <item name="android:layout_weight">1</item> + <item name="android:background">?attr/listChoiceBackgroundIndicator</item> + <item name="android:scaleType">center</item> + </style> <style name="OverflowMenuAnim"> <item name="android:windowEnterAnimation">@anim/menu_enter</item> <item name="android:windowExitAnimation">@anim/menu_exit</item>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index 0884174e..b77df2e 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -286,6 +286,8 @@ <dimen name="snippets_padding_and_peeking_card_height">16dp</dimen> <dimen name="snippets_card_9_patch_adjustment">2dp</dimen> <dimen name="snippets_article_header_height">40dp</dimen> + <dimen name="snippets_publisher_margin_top_with_article_snippet">16dp</dimen> + <dimen name="snippets_publisher_margin_top_without_article_snippet">8dp</dimen> <!-- Recent tabs page --> <dimen name="recent_tabs_visible_separator_padding">8dp</dimen>
diff --git a/chrome/android/java/res/xml/file_paths.xml b/chrome/android/java/res/xml/file_paths.xml index 63720fe..5be9ca6 100644 --- a/chrome/android/java/res/xml/file_paths.xml +++ b/chrome/android/java/res/xml/file_paths.xml
@@ -9,4 +9,9 @@ <paths xmlns:android="http://schemas.android.com/apk/res/android"> <files-path name="images" path="images/"/> <cache-path name="cache" path="net-export/"/> + + <!-- Note(twellington): This path is included to facilitate creating + content:// URIs for downloads. This may no longer work if/when users + are allowed to save files elsewhere. --> + <external-path name="downloads" path="Download/" /> </paths>
diff --git a/chrome/android/java/res/xml/sync_customization_preferences.xml b/chrome/android/java/res/xml/sync_customization_preferences.xml index f65a6ae..a5944de 100644 --- a/chrome/android/java/res/xml/sync_customization_preferences.xml +++ b/chrome/android/java/res/xml/sync_customization_preferences.xml
@@ -5,6 +5,11 @@ <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + <org.chromium.chrome.browser.preferences.SyncErrorCardPreference + android:key="sync_error_card" + android:icon="@drawable/sync_error" + android:title="@string/sync_error_card_title"/> + <org.chromium.chrome.browser.preferences.ChromeSwitchPreference android:key="sync_switch" android:title="@string/sign_in_sync"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/BasicNativePage.java b/chrome/android/java/src/org/chromium/chrome/browser/BasicNativePage.java index 4ec11fe0..a98797e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/BasicNativePage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/BasicNativePage.java
@@ -7,7 +7,7 @@ import android.app.Activity; import android.content.res.Resources; import android.view.View; -import android.view.ViewGroup.MarginLayoutParams; +import android.widget.FrameLayout.LayoutParams; import org.chromium.base.ApiCompatibilityUtils; import org.chromium.chrome.R; @@ -37,8 +37,8 @@ Resources res = mActivity.getResources(); - MarginLayoutParams layoutParams = new MarginLayoutParams( - MarginLayoutParams.MATCH_PARENT, MarginLayoutParams.MATCH_PARENT); + LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, + LayoutParams.MATCH_PARENT); layoutParams.setMargins(0, res.getDimensionPixelSize(R.dimen.tab_strip_height) + res.getDimensionPixelSize(R.dimen.toolbar_height_no_shadow),
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index 22553bd..4218cb9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -85,6 +85,7 @@ import org.chromium.chrome.browser.nfc.BeamController; import org.chromium.chrome.browser.nfc.BeamProvider; import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; +import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadBridge; import org.chromium.chrome.browser.omaha.UpdateMenuItemHelper; import org.chromium.chrome.browser.pageinfo.WebsiteSettingsPopup; import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomizations; @@ -1531,6 +1532,10 @@ } else if (id == R.id.bookmark_this_page_id) { addOrEditBookmark(currentTab); RecordUserAction.record("MobileMenuAddToBookmarks"); + } else if (id == R.id.offline_page_id) { + final OfflinePageDownloadBridge bridge = + new OfflinePageDownloadBridge(currentTab.getProfile()); + bridge.startDownload(currentTab); } else if (id == R.id.reload_menu_id) { if (currentTab.isLoading()) { currentTab.stopLoading();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java index 3118631..1f37fe3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -35,6 +35,7 @@ public static final String NTP_FAKE_OMNIBOX_TEXT = "NTPFakeOmniboxText"; public static final String NTP_MATERIAL_DESIGN = "NTPMaterialDesign"; public static final String NTP_SNIPPETS = "NTPSnippets"; + public static final String NTP_SNIPPETS_SAVE_TO_OFFLINE = "NTPSaveToOffline"; public static final String NTP_TOOLBAR = "NTPToolbar"; public static final String WEB_PAYMENTS = "WebPayments"; public static final String SYSTEM_DOWNLOAD_MANAGER = "SystemDownloadManager";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeSwitches.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeSwitches.java index 518007b..e07f6c0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeSwitches.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeSwitches.java
@@ -86,6 +86,12 @@ */ public static final String MARKET_URL_FOR_TESTING = "market-url-for-testing"; + + /** + * Show the button for saving an offline page. + */ + public static final String ENABLE_OFFLINE_PAGE_DOWNLOADING = "enable-offline-page-downloading"; + /////////////////////////////////////////////////////////////////////////////////////////////// // Native Switches /////////////////////////////////////////////////////////////////////////////////////////////// @@ -125,12 +131,6 @@ public static final String ENABLE_ANDROID_SPELLCHECKER = "enable-android-spellchecker"; /** - * Disable speculative TCP/IP preconnection. - * Native switch - switches::kDisablePreconnect - */ - public static final String DISABLE_PRECONNECT = "disable-preconnect"; - - /** * Specifies Android phone page loading progress bar animation. * Native switch - switches::kProgressBarAnimation */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java index 936279dd..9ad97e8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ShortcutHelper.java
@@ -14,14 +14,11 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; -import android.graphics.Path; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffXfermode; import android.graphics.Rect; -import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.os.AsyncTask; import android.text.TextUtils; import android.util.Base64; @@ -32,6 +29,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; +import org.chromium.blink_public.platform.WebDisplayMode; import org.chromium.chrome.R; import org.chromium.chrome.browser.webapps.WebappAuthenticator; import org.chromium.chrome.browser.webapps.WebappDataStorage; @@ -129,55 +127,62 @@ } /** - * Adds home screen shortcut which opens in a {@link WebappActivity}. - * This method must not be called on the UI thread. + * Adds home screen shortcut which opens in a {@link WebappActivity}. Creates web app + * home screen shortcut and registers web app asynchronously. Calls + * ShortcutHelper::OnWebappDataStored() when done. */ @SuppressWarnings("unused") @CalledByNative - private static void addWebapp(String id, String url, String scopeUrl, final String userTitle, - String name, String shortName, String iconUrl, Bitmap icon, int displayMode, - int orientation, int source, long themeColor, long backgroundColor, - final long callbackPointer) { - assert !ThreadUtils.runningOnUiThread(); + private static void addWebapp(final String id, final String url, final String scopeUrl, + final String userTitle, final String name, final String shortName, final String iconUrl, + final Bitmap icon, final int displayMode, final int orientation, final int source, + final long themeColor, final long backgroundColor, final long callbackPointer) { + new AsyncTask<Void, Void, Intent>() { + @Override + protected Intent doInBackground(Void... args0) { + // Encoding {@link icon} as a string and computing the mac are expensive. - Context context = ContextUtils.getApplicationContext(); - if (TextUtils.isEmpty(scopeUrl)) { - scopeUrl = getScopeFromUrl(url); - } + Context context = ContextUtils.getApplicationContext(); + String nonEmptyScopeUrl = + TextUtils.isEmpty(scopeUrl) ? getScopeFromUrl(url) : scopeUrl; + Intent shortcutIntent = createWebappShortcutIntent(id, + sDelegate.getFullscreenAction(), url, nonEmptyScopeUrl, name, shortName, + icon, WEBAPP_SHORTCUT_VERSION, displayMode, orientation, themeColor, + backgroundColor, iconUrl.isEmpty()); + shortcutIntent.putExtra(EXTRA_MAC, getEncodedMac(context, url)); + shortcutIntent.putExtra(EXTRA_SOURCE, source); + shortcutIntent.setPackage(context.getPackageName()); + return shortcutIntent; + } + @Override + protected void onPostExecute(final Intent resultIntent) { + Context context = ContextUtils.getApplicationContext(); + sDelegate.sendBroadcast( + context, createAddToHomeIntent(url, userTitle, icon, resultIntent)); - final Intent shortcutIntent = - createWebappShortcutIntent(id, sDelegate.getFullscreenAction(), url, scopeUrl, name, - shortName, icon, WEBAPP_SHORTCUT_VERSION, displayMode, orientation, - themeColor, backgroundColor, iconUrl.isEmpty()); - shortcutIntent.putExtra(EXTRA_MAC, getEncodedMac(context, url)); - shortcutIntent.putExtra(EXTRA_SOURCE, source); - shortcutIntent.setPackage(context.getPackageName()); - sDelegate.sendBroadcast( - context, createAddToHomeIntent(url, userTitle, icon, shortcutIntent)); + // Store the webapp data so that it is accessible without the intent. Once this + // process is complete, call back to native code to start the splash image + // download. + WebappRegistry.registerWebapp( + context, id, new WebappRegistry.FetchWebappDataStorageCallback() { + @Override + public void onWebappDataStorageRetrieved(WebappDataStorage storage) { + storage.updateFromShortcutIntent(resultIntent); + nativeOnWebappDataStored(callbackPointer); + } + }); - // Store the webapp data so that it is accessible without the intent. Once this process - // is complete, call back to native code to start the splash image download. - WebappRegistry.registerWebapp(context, id, - new WebappRegistry.FetchWebappDataStorageCallback() { - @Override - public void onWebappDataStorageRetrieved(WebappDataStorage storage) { - storage.updateFromShortcutIntent(shortcutIntent); - nativeOnWebappDataStored(callbackPointer); - } - }); - - showAddedToHomescreenToast(userTitle); + showAddedToHomescreenToast(userTitle); + } + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } /** * Adds home screen shortcut which opens in the browser Activity. - * This method must not be called on the UI thread. */ @SuppressWarnings("unused") @CalledByNative private static void addShortcut(String url, String userTitle, Bitmap icon, int source) { - assert !ThreadUtils.runningOnUiThread(); - Context context = ContextUtils.getApplicationContext(); final Intent shortcutIntent = createShortcutIntent(url); shortcutIntent.putExtra(EXTRA_SOURCE, source); @@ -191,23 +196,19 @@ * Show toast to alert user that the shortcut was added to the home screen. */ private static void showAddedToHomescreenToast(final String title) { - ThreadUtils.runOnUiThread(new Runnable() { - @Override - public void run() { - Context applicationContext = ContextUtils.getApplicationContext(); - String toastText = - applicationContext.getString(R.string.added_to_homescreen, title); - Toast toast = Toast.makeText(applicationContext, toastText, Toast.LENGTH_SHORT); - toast.show(); - } - }); + assert ThreadUtils.runningOnUiThread(); + + Context applicationContext = ContextUtils.getApplicationContext(); + String toastText = applicationContext.getString(R.string.added_to_homescreen, title); + Toast toast = Toast.makeText(applicationContext, toastText, Toast.LENGTH_SHORT); + toast.show(); } /** * Creates a storage location and stores the data for a web app using {@link WebappDataStorage}. - * @param id ID of the webapp which is storing data. + * @param id ID of the web app which is storing data. * @param splashImage Image which should be displayed on the splash screen of - * the webapp. This can be null of there is no image to show. + * the web app. This can be null of there is no image to show. */ @SuppressWarnings("unused") @CalledByNative @@ -257,10 +258,13 @@ * @param backgroundColor Background color of the web app. * @param isIconGenerated True if the icon is generated by Chromium. * @return Intent for onclick action of the shortcut. + * This method must not be called on the UI thread. */ public static Intent createWebappShortcutIntent(String id, String action, String url, String scope, String name, String shortName, Bitmap icon, int version, int displayMode, int orientation, long themeColor, long backgroundColor, boolean isIconGenerated) { + assert !ThreadUtils.runningOnUiThread(); + // Encode the icon as a base64 string (Launcher drops Bitmaps in the Intent). String encodedIcon = encodeBitmapAsString(icon); @@ -283,6 +287,19 @@ } /** + * Creates an intent with mostly empty parameters for launching a web app on the homescreen. + * @param id Id of the web app. + * @param url Url of the web app. + * @return the Intent + * This method must not be called on the UI thread. + */ + public static Intent createWebappShortcutIntentForTesting(String id, String url) { + assert !ThreadUtils.runningOnUiThread(); + return createWebappShortcutIntent(id, null, url, getScopeFromUrl(url), null, null, null, + WEBAPP_SHORTCUT_VERSION, WebDisplayMode.Standalone, 0, 0, 0, false); + } + + /** * Shortcut intent for icon on home screen. * @param url Url of the shortcut. * @return Intent for onclick action of the shortcut. @@ -321,8 +338,8 @@ } /** - * Adapts a website's icon (e.g. favicon or touch icon) to the Material design style guidelines - * for home screen icons. This involves adding some padding and rounding the corners. + * Adapts a website's icon (e.g. favicon or touch icon) to make it suitable for the home screen. + * This involves adding padding if the icon is a full sized square. * * @param context Context used to create the intent. * @param webIcon The website's favicon or touch icon. @@ -350,21 +367,19 @@ return webIcon; } - // Draw the web icon with padding around it. Canvas canvas = new Canvas(bitmap); - Rect innerBounds = new Rect(padding, padding, outerSize - padding, outerSize - padding); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setFilterBitmap(true); - canvas.drawBitmap(webIcon, null, innerBounds, paint); + Rect innerBounds; - // Round the corners. - int cornerRadius = Math.round(ICON_CORNER_RADIUS_RATIO * outerSize); - Path path = new Path(); - path.setFillType(Path.FillType.INVERSE_WINDING); - RectF innerBoundsF = new RectF(innerBounds); - path.addRoundRect(innerBoundsF, cornerRadius, cornerRadius, Path.Direction.CW); - paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); - canvas.drawPath(path, paint); + // Draw the icon with padding around it if all four corners are not transparent. Otherwise, + // don't add padding. + if (shouldPadIcon(webIcon)) { + innerBounds = new Rect(padding, padding, outerSize - padding, outerSize - padding); + } else { + innerBounds = new Rect(0, 0, outerSize, outerSize); + } + canvas.drawBitmap(webIcon, null, innerBounds, paint); return bitmap; } @@ -560,6 +575,23 @@ }; } + /** + * Returns true if we should add padding to this icon. We use a heuristic that if the pixels in + * all four corners of the icon are not transparent, we assume the icon is square and maximally + * sized, i.e. in need of padding. Otherwise, no padding is added. + */ + private static boolean shouldPadIcon(Bitmap icon) { + int maxX = icon.getWidth() - 1; + int maxY = icon.getHeight() - 1; + + if ((Color.alpha(icon.getPixel(0, 0)) != 0) && (Color.alpha(icon.getPixel(maxX, maxY)) != 0) + && (Color.alpha(icon.getPixel(0, maxY)) != 0) + && (Color.alpha(icon.getPixel(maxX, 0)) != 0)) { + return true; + } + return false; + } + private static int getIdealSizeFromResourceInDp(Context context, int resource) { float sizeInPx = context.getResources().getDimension(resource); float density = context.getResources().getDisplayMetrics().density;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java index 3484671..2518f4b0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuAdapter.java
@@ -31,6 +31,14 @@ /** * ListAdapter to customize the view of items in the list. + * + * The icon row in the menu is a special case of a MenuItem that displays multiple buttons in a row. + * If, for some unfathomable reason, you need to add yet another icon to the row (the current max + * is five), then you will need to: + * + * 1) Update icon_row_menu_item.xml to have as many buttons as you need. + * 2) Edit the {@link BUTTON_IDS} to reference your new button. + * 3) Hope that the icon row still fits on small phones. */ class AppMenuAdapter extends BaseAdapter { /** @@ -45,7 +53,7 @@ private static final int TITLE_BUTTON_MENU_ITEM = 1; /** - * Menu item that has four buttons. Every one of these buttons is displayed as an icon. + * Menu item that has three buttons. Every one of these buttons is displayed as an icon. */ private static final int THREE_BUTTON_MENU_ITEM = 2; @@ -55,14 +63,28 @@ private static final int FOUR_BUTTON_MENU_ITEM = 3; /** + * Menu item that has five buttons. Every one of these buttons is displayed as an icon. + */ + private static final int FIVE_BUTTON_MENU_ITEM = 4; + + /** * Menu item for updating Chrome; uses a custom layout. */ - private static final int UPDATE_MENU_ITEM = 4; + private static final int UPDATE_MENU_ITEM = 5; /** * The number of view types specified above. If you add a view type you MUST increment this. */ - private static final int VIEW_TYPE_COUNT = 5; + private static final int VIEW_TYPE_COUNT = 6; + + /** IDs of all of the buttons in icon_row_menu_item.xml. */ + private static final int[] BUTTON_IDS = { + R.id.button_one, + R.id.button_two, + R.id.button_three, + R.id.button_four, + R.id.button_five + }; /** MenuItem Animation Constants */ private static final int ENTER_ITEM_DURATION_MS = 350; @@ -102,6 +124,8 @@ if (item.getItemId() == R.id.update_menu_id) { return UPDATE_MENU_ITEM; + } else if (viewCount == 5) { + return FIVE_BUTTON_MENU_ITEM; } else if (viewCount == 4) { return FOUR_BUTTON_MENU_ITEM; } else if (viewCount == 3) { @@ -175,57 +199,15 @@ break; } case THREE_BUTTON_MENU_ITEM: { - ThreeButtonMenuItemViewHolder holder = null; - if (convertView == null - || !(convertView.getTag() instanceof ThreeButtonMenuItemViewHolder)) { - holder = new ThreeButtonMenuItemViewHolder(); - convertView = mInflater.inflate(R.layout.three_button_menu_item, parent, false); - holder.buttons[0] = - (TintedImageButton) convertView.findViewById(R.id.button_one); - holder.buttons[1] = - (TintedImageButton) convertView.findViewById(R.id.button_two); - holder.buttons[2] = - (TintedImageButton) convertView.findViewById(R.id.button_three); - convertView.setTag(holder); - convertView.setTag(R.id.menu_item_enter_anim_id, - buildIconItemEnterAnimator(holder.buttons)); - } else { - holder = (ThreeButtonMenuItemViewHolder) convertView.getTag(); - } - for (int i = 0; i < 3; i++) { - setupImageButton(holder.buttons[i], item.getSubMenu().getItem(i)); - } - - convertView.setFocusable(false); - convertView.setEnabled(false); + convertView = createMenuItemRow(convertView, parent, item, 3); break; } case FOUR_BUTTON_MENU_ITEM: { - FourButtonMenuItemViewHolder holder = null; - if (convertView == null - || !(convertView.getTag() instanceof FourButtonMenuItemViewHolder)) { - holder = new FourButtonMenuItemViewHolder(); - convertView = mInflater.inflate(R.layout.four_button_menu_item, parent, false); - holder.buttons[0] = - (TintedImageButton) convertView.findViewById(R.id.button_one); - holder.buttons[1] = - (TintedImageButton) convertView.findViewById(R.id.button_two); - holder.buttons[2] = - (TintedImageButton) convertView.findViewById(R.id.button_three); - holder.buttons[3] = - (TintedImageButton) convertView.findViewById(R.id.button_four); - convertView.setTag(holder); - convertView.setTag(R.id.menu_item_enter_anim_id, - buildIconItemEnterAnimator(holder.buttons)); - } else { - holder = (FourButtonMenuItemViewHolder) convertView.getTag(); - } - for (int i = 0; i < 4; i++) { - setupImageButton(holder.buttons[i], item.getSubMenu().getItem(i)); - } - - convertView.setFocusable(false); - convertView.setEnabled(false); + convertView = createMenuItemRow(convertView, parent, item, 4); + break; + } + case FIVE_BUTTON_MENU_ITEM: { + convertView = createMenuItemRow(convertView, parent, item, 5); break; } case TITLE_BUTTON_MENU_ITEM: { @@ -292,6 +274,9 @@ mAppMenu.onItemClick(item); } }); + + // Menu items may be hidden by command line flags before they get to this point. + button.setVisibility(item.isVisible() ? View.VISIBLE : View.GONE); } private void setupStandardMenuItemViewHolder(StandardMenuItemViewHolder holder, @@ -392,6 +377,41 @@ return animation; } + private View createMenuItemRow( + View convertView, ViewGroup parent, MenuItem item, int numItems) { + RowItemViewHolder holder = null; + if (convertView == null + || !(convertView.getTag() instanceof RowItemViewHolder) + || ((RowItemViewHolder) convertView.getTag()).buttons.length != numItems) { + holder = new RowItemViewHolder(numItems); + convertView = mInflater.inflate(R.layout.icon_row_menu_item, parent, false); + + // Save references to all the buttons. + for (int i = 0; i < numItems; i++) { + holder.buttons[i] = + (TintedImageButton) convertView.findViewById(BUTTON_IDS[i]); + } + + // Remove unused menu items. + for (int j = numItems; j < 5; j++) { + ((ViewGroup) convertView).removeView(convertView.findViewById(BUTTON_IDS[j])); + } + + convertView.setTag(holder); + convertView.setTag(R.id.menu_item_enter_anim_id, + buildIconItemEnterAnimator(holder.buttons)); + } else { + holder = (RowItemViewHolder) convertView.getTag(); + } + + for (int i = 0; i < numItems; i++) { + setupImageButton(holder.buttons[i], item.getSubMenu().getItem(i)); + } + convertView.setFocusable(false); + convertView.setEnabled(false); + return convertView; + } + static class StandardMenuItemViewHolder { public TextView text; public AppMenuItemIcon image; @@ -401,12 +421,12 @@ public TextView summary; } - static class ThreeButtonMenuItemViewHolder { - public TintedImageButton[] buttons = new TintedImageButton[3]; - } + private static class RowItemViewHolder { + public TintedImageButton[] buttons; - static class FourButtonMenuItemViewHolder { - public TintedImageButton[] buttons = new TintedImageButton[4]; + RowItemViewHolder(int numButtons) { + buttons = new TintedImageButton[numButtons]; + } } static class TitleButtonMenuItemViewHolder {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java index 6eee512..1e1f8c0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java
@@ -4,13 +4,18 @@ package org.chromium.chrome.browser.appmenu; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; import android.text.TextUtils; import android.view.Menu; import android.view.MenuItem; +import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.CommandLine; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeFeatureList; +import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.ShortcutHelper; import org.chromium.chrome.browser.UrlConstants; import org.chromium.chrome.browser.bookmarks.BookmarkBridge; @@ -104,6 +109,23 @@ MenuItem bookmarkMenuItem = menu.findItem(R.id.bookmark_this_page_id); updateBookmarkMenuItem(bookmarkMenuItem, currentTab); + + MenuItem offlineMenuItem = menu.findItem(R.id.offline_page_id); + if (offlineMenuItem != null) { + if (CommandLine.getInstance().hasSwitch( + ChromeSwitches.ENABLE_OFFLINE_PAGE_DOWNLOADING)) { + offlineMenuItem.setEnabled(!isChromeScheme); + Drawable drawable = offlineMenuItem.getIcon(); + if (drawable != null) { + int iconTint = ApiCompatibilityUtils.getColor( + mActivity.getResources(), R.color.light_normal_color); + drawable.mutate(); + drawable.setColorFilter(iconTint, PorterDuff.Mode.SRC_ATOP); + } + } else { + offlineMenuItem.setVisible(false); + } + } } menu.findItem(R.id.downloads_menu_id)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/LayoutTab.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/LayoutTab.java index f541c80..b5c41b8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/LayoutTab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/components/LayoutTab.java
@@ -228,7 +228,8 @@ boolean needsUpdate = false; // If the toolbar color changed, animate between the old and new colors. - if (mToolbarBackgroundColor != toolbarBackgroundColor && isVisible()) { + if (mToolbarBackgroundColor != toolbarBackgroundColor && isVisible() + && mInitFromHostCalled) { ChromeAnimation.Animation<ChromeAnimation.Animatable<?>> themeColorAnimation = createAnimation(this, Property.TOOLBAR_COLOR, 0.0f, 1.0f, ToolbarPhone.THEME_COLOR_TRANSITION_DURATION, 0, false,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java index 5f97968..8db89f9a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
@@ -54,6 +54,7 @@ * The stacking and visual behavior is driven by setting a {@link StripStacker}. */ public class StripLayoutHelper { + // Drag Constants private static final int REORDER_SCROLL_NONE = 0; private static final int REORDER_SCROLL_LEFT = 1; @@ -147,6 +148,7 @@ // Whether the CascadingStripStacker should be used. private boolean mShouldCascadeTabs; private boolean mIsFirstLayoutPass; + private boolean mAnimationsDisabledForTesting; // Tab menu item IDs public static final int ID_CLOSE_ALL_TABS = 0; @@ -559,7 +561,8 @@ // If the ScrollingStripStacker is being used and the new tab button is visible, go // directly to the new scroll offset rather than animating. Animating the scroll // causes the new tab button to disappear for a frame. - boolean shouldAnimate = !mNewTabButton.isVisible(); + boolean shouldAnimate = !mNewTabButton.isVisible() + && !mAnimationsDisabledForTesting; setScrollForScrollingTabStacker(delta, shouldAnimate, time); } else if (delta != 0.f) { mScroller.startScroll(mScrollOffset, 0, (int) delta, 0, time, EXPAND_DURATION_MS); @@ -1109,7 +1112,7 @@ // 5.a. Cancel any outstanding tab width animations. cancelAnimation(mStripTabs[i], StripLayoutTab.Property.WIDTH); - if (animate) { + if (animate && !mAnimationsDisabledForTesting) { startAnimation(buildTabResizeAnimation(tab, mCachedTabWidth), false); } else { mStripTabs[i].setWidth(mCachedTabWidth); @@ -1436,7 +1439,7 @@ if (index < newIndex) newIndex--; // 5. Animate if necessary. - if (animate) { + if (animate && !mAnimationsDisabledForTesting) { final float flipWidth = mCachedTabWidth - mTabOverlapWidth; final int direction = oldIndex <= newIndex ? 1 : -1; final float animationLength = @@ -1630,7 +1633,7 @@ private void setScrollForScrollingTabStacker(float delta, boolean shouldAnimate, long time) { if (delta == 0.f) return; - if (shouldAnimate) { + if (shouldAnimate && !mAnimationsDisabledForTesting) { mScroller.startScroll(mScrollOffset, 0, (int) delta, 0, time, EXPAND_DURATION_MS); } else { mScrollOffset += delta; @@ -1733,6 +1736,14 @@ return mTabOverlapWidth; } + /** + * Disables animations for testing purposes. + */ + @VisibleForTesting + public void disableAnimationsForTesting() { + mAnimationsDisabledForTesting = true; + } + private void setAccessibilityDescription(StripLayoutTab stripTab, Tab tab) { if (tab != null) setAccessibilityDescription(stripTab, tab.getTitle(), tab.isHidden()); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java index 13679ff7..86207a2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java
@@ -9,6 +9,7 @@ import android.content.Context; import android.graphics.RectF; +import org.chromium.base.ObserverList; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; import org.chromium.chrome.browser.compositor.layouts.ChromeAnimation; @@ -33,6 +34,13 @@ */ public class StripLayoutTab implements ChromeAnimation.Animatable<StripLayoutTab.Property>, VirtualView { + + /** An observer interface for StripLayoutTab. */ + public interface Observer { + /** @param visible Whether the StripLayoutTab is visible. */ + public void onVisibilityChanged(boolean visible); + } + /** * Animatable properties that can be used with a {@link ChromeAnimation.Animatable} on a * {@link StripLayoutTab}. @@ -89,6 +97,8 @@ // Preallocated private final RectF mClosePlacement = new RectF(); + private ObserverList<Observer> mObservers = new ObserverList<>(); + /** * Create a {@link StripLayoutTab} that represents the {@link Tab} with an id of * {@code id}. @@ -98,7 +108,7 @@ * @param loadTrackerCallback The {@link TabLoadTrackerCallback} to be notified of loading state * changes. * @param renderHost The {@link LayoutRenderHost}. - * @param incogntio Whether or not this layout tab is icognito. + * @param incognito Whether or not this layout tab is incognito. */ public StripLayoutTab(Context context, int id, TabLoadTrackerCallback loadTrackerCallback, LayoutRenderHost renderHost, boolean incognito) { @@ -117,6 +127,17 @@ mCloseButton.setAccessibilityDescription(description, description); } + /** @param observer The observer to add. */ + @VisibleForTesting + public void addObserver(Observer observer) { + mObservers.addObserver(observer); + } + + /** @param observer The observer to remove. */ + public void removeObserver(Observer observer) { + mObservers.removeObserver(observer); + } + /** * Get a list of virtual views for accessibility events. * @@ -173,6 +194,9 @@ */ public void setVisible(boolean visible) { mVisible = visible; + for (Observer observer : mObservers) { + observer.onVisibilityChanged(mVisible); + } } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java index 09c0ecf..6ea3a7f2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -247,7 +247,7 @@ if (params.isVideo()) { menu.findItem(R.id.contextmenu_save_video).setVisible( - UrlUtilities.isDownloadableScheme(params.getSrcUrl())); + params.canSaveMedia() && UrlUtilities.isDownloadableScheme(params.getSrcUrl())); } else if (params.isImage() && params.imageWasFetchedLoFi()) { DataReductionProxyUma.dataReductionProxyLoFiUIAction( DataReductionProxyUma.ACTION_LOAD_IMAGE_CONTEXT_MENU_SHOWN);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuParams.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuParams.java index 5a06e75..ad6202f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuParams.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ContextMenuParams.java
@@ -39,6 +39,7 @@ private final boolean mIsAnchor; private final boolean mIsImage; private final boolean mIsVideo; + private final boolean mCanSavemedia; /** * @return The URL associated with the main frame of the page that triggered the context menu. @@ -117,9 +118,13 @@ return mIsVideo; } + public boolean canSaveMedia() { + return mCanSavemedia; + } + private ContextMenuParams(int mediaType, String pageUrl, String linkUrl, String linkText, String unfilteredLinkUrl, String srcUrl, String titleText, boolean imageWasFetchedLoFi, - Referrer referrer) { + Referrer referrer, boolean canSavemedia) { mPageUrl = pageUrl; mLinkUrl = linkUrl; mLinkText = linkText; @@ -132,15 +137,17 @@ mIsAnchor = !TextUtils.isEmpty(linkUrl); mIsImage = mediaType == MediaType.MEDIA_TYPE_IMAGE; mIsVideo = mediaType == MediaType.MEDIA_TYPE_VIDEO; + mCanSavemedia = canSavemedia; } @CalledByNative private static ContextMenuParams create(int mediaType, String pageUrl, String linkUrl, String linkText, String unfilteredLinkUrl, String srcUrl, String titleText, - boolean imageWasFetchedLoFi, String sanitizedReferrer, int referrerPolicy) { + boolean imageWasFetchedLoFi, String sanitizedReferrer, int referrerPolicy, + boolean canSavemedia) { Referrer referrer = TextUtils.isEmpty(sanitizedReferrer) ? null : new Referrer(sanitizedReferrer, referrerPolicy); return new ContextMenuParams(mediaType, pageUrl, linkUrl, linkText, unfilteredLinkUrl, - srcUrl, titleText, imageWasFetchedLoFi, referrer); + srcUrl, titleText, imageWasFetchedLoFi, referrer, canSavemedia); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java index 55d64a2..6244c187 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java
@@ -298,8 +298,7 @@ } // Don't open explicitly opted out intents in custom tabs. - if (IntentUtils.safeGetBooleanExtra( - intent, CustomTabsIntent.EXTRA_USER_OPT_OUT_FROM_CUSTOM_TABS, false)) { + if (CustomTabsIntent.shouldAlwaysUseBrowserUI(intent)) { return false; } @@ -407,8 +406,7 @@ */ public static boolean isCustomTabIntent(Intent intent) { if (intent == null - || IntentUtils.safeGetBooleanExtra( - intent, CustomTabsIntent.EXTRA_USER_OPT_OUT_FROM_CUSTOM_TABS, false) + || CustomTabsIntent.shouldAlwaysUseBrowserUI(intent) || !intent.hasExtra(CustomTabsIntent.EXTRA_SESSION)) { return false; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryItemWrapper.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryItemWrapper.java index 4f857bb..0407f2c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryItemWrapper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadHistoryItemWrapper.java
@@ -18,7 +18,9 @@ import org.chromium.chrome.R; import org.chromium.chrome.browser.download.DownloadItem; import org.chromium.chrome.browser.download.DownloadManagerService; +import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadBridge; import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadItem; +import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.widget.DateDividedAdapter.TimedItem; import org.chromium.ui.widget.Toast; @@ -39,8 +41,8 @@ /** @return String showing where the download resides. */ abstract String getFilePath(); - /** @return A URI to where the file resides. */ - abstract Uri getUri(); + /** @return The file where the download resides. */ + abstract File getFile(); /** @return String to display for the file. */ abstract String getDisplayFileName(); @@ -71,6 +73,7 @@ private static final String MIMETYPE_DOCUMENT = "text"; private final DownloadItem mItem; + private File mFile; DownloadItemWrapper(DownloadItem item) { mItem = item; @@ -97,8 +100,9 @@ } @Override - public Uri getUri() { - return Uri.fromFile(new File(getFilePath())); + public File getFile() { + if (mFile == null) mFile = new File(getFilePath()); + return mFile; } @Override @@ -132,7 +136,7 @@ boolean success = false; String mimeType = mItem.getDownloadInfo().getMimeType(); - Uri fileUri = Uri.fromFile(new File(getFilePath())); + Uri fileUri = Uri.fromFile(getFile()); // Check if any apps can open the file. Intent fileIntent = new Intent(); @@ -202,6 +206,7 @@ /** Wraps a {@link OfflinePageDownloadItem}. */ static class OfflinePageItemWrapper extends DownloadHistoryItemWrapper { private final OfflinePageDownloadItem mItem; + private File mFile; OfflinePageItemWrapper(OfflinePageDownloadItem item) { mItem = item; @@ -228,8 +233,9 @@ } @Override - public Uri getUri() { - return Uri.fromFile(new File(getFilePath())); + public File getFile() { + if (mFile == null) mFile = new File(getFilePath()); + return mFile; } @Override @@ -259,12 +265,17 @@ } public void open() { - // TODO(dfalcantara): Figure out what to do here. + getBridge().openItem(getId()); } @Override public void delete() { - // TODO(dfalcantara): Figure out what to do here. + getBridge().deleteItem(getId()); + } + + private OfflinePageDownloadBridge getBridge() { + return new OfflinePageDownloadBridge( + Profile.getLastUsedProfile().getOriginalProfile()); } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java index 5ea54ce..52a2dccb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/DownloadManagerUi.java
@@ -7,6 +7,7 @@ import android.app.Activity; import android.content.Intent; import android.net.Uri; +import android.os.StrictMode; import android.support.v4.widget.DrawerLayout; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -20,6 +21,8 @@ import android.widget.ListView; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.ContentUriUtils; +import org.chromium.base.Log; import org.chromium.base.ObserverList; import org.chromium.chrome.R; import org.chromium.chrome.browser.BasicNativePage; @@ -254,7 +257,7 @@ if (selectedItems.size() == 1) { // Set up intent for 1 item. intentAction = Intent.ACTION_SEND; - shareIntent.putExtra(Intent.EXTRA_STREAM, selectedItems.get(0).getUri()); + shareIntent.putExtra(Intent.EXTRA_STREAM, getUriForItem(selectedItems.get(0))); } else { // Set up intent for multiple items. intentAction = Intent.ACTION_SEND_MULTIPLE; @@ -264,7 +267,7 @@ if (intentMimeType != null) intentMimeParts = intentMimeType.split(MIME_TYPE_DELIMITER); for (DownloadHistoryItemWrapper itemWrapper : mSelectionDelegate.getSelectedItems()) { - itemUris.add(itemWrapper.getUri()); + itemUris.add(getUriForItem(itemWrapper)); String mimeType = Intent.normalizeMimeType(itemWrapper.getMimeType()); @@ -302,6 +305,30 @@ mActivity.getString(R.string.share_link_chooser_title))); } + private Uri getUriForItem(DownloadHistoryItemWrapper itemWrapper) { + Uri uri = null; + + // #getContentUriFromFile causes a disk read when it calls into FileProvider#getUriForFile. + // Obtaining a content URI is on the critical path for creating a share intent after the + // user taps on the share button, so even if we were to run this method on a background + // thread we would have to wait. As it depends on user-selected items, we cannot + // know/preload which URIs we need until the user presses share. + StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); + try { + // Try to obtain a content:// URI, which is preferred to a file:/// URI so that + // receiving apps don't attempt to determine the file's mime type (which often fails). + uri = ContentUriUtils.getContentUriFromFile(mActivity.getApplicationContext(), + itemWrapper.getFile()); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Could not create content uri: " + e); + } + StrictMode.setThreadPolicy(oldPolicy); + + if (uri == null) uri = Uri.fromFile(itemWrapper.getFile()); + + return uri; + } + private void deleteSelectedItems() { for (DownloadHistoryItemWrapper wrappedItem : mSelectionDelegate.getSelectedItems()) { wrappedItem.delete();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/FilterAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/FilterAdapter.java index e2bfaff1..7b521572 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/FilterAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/FilterAdapter.java
@@ -53,8 +53,8 @@ R.layout.download_manager_ui_drawer_filter, null); } - int iconId = DownloadFilter.FILTER_LIST[position][0]; - labelView.setText(DownloadFilter.FILTER_LIST[position][1]); + int iconId = DownloadFilter.getDrawableForFilter(position); + labelView.setText(DownloadFilter.getStringIdForFilter(position)); Drawable iconDrawable = null; if (position == mSelectedIndex) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java index 4b60333..512201d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java
@@ -23,6 +23,8 @@ /** A View that manages the display of space used by the downloads. */ class SpaceDisplay extends RecyclerView.AdapterDataObserver { private static final String TAG = "download_ui"; + private static final long BYTES_PER_GIGABYTE = 1024 * 1024 * 1024; + private final AsyncTask<Void, Void, Long> mFileSystemBytesTask; private DownloadHistoryAdapter mHistoryAdapter; @@ -87,8 +89,10 @@ // Display how big the storage is. String fileSystemReadable = Formatter.formatFileSize(context, mFileSystemBytes); - mSpaceTotalTextView.setText(context.getString( - R.string.download_manager_ui_space_used, fileSystemReadable)); + + float fileSystemGigabytes = convertBytesToGigabytes(mFileSystemBytes); + mSpaceTotalTextView.setText(context.getResources().getString( + R.string.download_manager_ui_space_available, fileSystemGigabytes)); } // Indicate how much space has been used by downloads. @@ -96,6 +100,13 @@ int percentage = mFileSystemBytes == 0 ? 0 : (int) (100.0 * usedBytes / mFileSystemBytes); mSpaceBar.setProgress(percentage); - mSpaceUsedTextView.setText(Formatter.formatFileSize(context, usedBytes)); + + float usedGigabytes = convertBytesToGigabytes(usedBytes); + mSpaceUsedTextView.setText(context.getResources().getString( + R.string.download_manager_ui_space_used, usedGigabytes)); } -} \ No newline at end of file + + private float convertBytesToGigabytes(long bytes) { + return bytes / (float) BYTES_PER_GIGABYTE; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/BaseMediaRouteDialogManager.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/BaseMediaRouteDialogManager.java index 284f18dc..a6d5a7e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/BaseMediaRouteDialogManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/BaseMediaRouteDialogManager.java
@@ -6,9 +6,12 @@ import android.app.Activity; import android.content.Context; +import android.content.DialogInterface; +import android.os.Handler; import android.support.v4.app.DialogFragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; +import android.support.v7.app.MediaRouteChooserDialogFragment; import android.support.v7.media.MediaRouter; import android.view.View; import android.widget.FrameLayout; @@ -111,6 +114,51 @@ } /** + * Base class for media router dialog fragment. Classes inheriting from + * BaseMediaRouteDialogManager may extend the implementation but must redirect the empty + * constructor to this implementation to handle the case of the Fragment being created via + * this method. + */ + public static class Fragment extends MediaRouteChooserDialogFragment { + private final Handler mHandler = new Handler(); + private final SystemVisibilitySaver mVisibilitySaver = new SystemVisibilitySaver(); + protected BaseMediaRouteDialogManager mManager = null; + + public Fragment() { + mHandler.post(new Runnable() { + @Override + public void run() { + Fragment.this.dismiss(); + } + }); + } + + public Fragment(BaseMediaRouteDialogManager manager) { + mManager = manager; + } + + @Override + public void onStart() { + mVisibilitySaver.saveSystemVisibility(getActivity()); + super.onStart(); + } + + @Override + public void onStop() { + super.onStop(); + mVisibilitySaver.restoreSystemVisibility(getActivity()); + } + + @Override + public void onDismiss(DialogInterface dialog) { + super.onDismiss(dialog); + if (mManager == null) return; + + mManager.mDialogFragment = null; + } + } + + /** * Initializes and shows the {@link DialogFragment} instance corresponding to the dialog type * needed. *
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/MediaRouteChooserDialogManager.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/MediaRouteChooserDialogManager.java index 06f0dfb..0b5eb82 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/MediaRouteChooserDialogManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/MediaRouteChooserDialogManager.java
@@ -8,7 +8,6 @@ import android.content.DialogInterface; import android.support.v4.app.DialogFragment; import android.support.v4.app.FragmentManager; -import android.support.v7.app.MediaRouteChooserDialogFragment; import android.support.v7.media.MediaRouteSelector; import org.chromium.chrome.browser.media.router.cast.MediaSink; @@ -22,54 +21,51 @@ private static final String DIALOG_FRAGMENT_TAG = "android.support.v7.mediarouter:MediaRouteChooserDialogFragment"; - private boolean mCancelled; - public MediaRouteChooserDialogManager(MediaSource source, Context applicationContext, MediaRouteDialogDelegate delegate) { super(source, applicationContext, delegate); } + /** + * Fragment implementation for MediaRouteChooserDialogManager. + */ + public static class Fragment extends BaseMediaRouteDialogManager.Fragment { + private boolean mCancelled; + + public Fragment() { + super(); + } + + public Fragment(BaseMediaRouteDialogManager manager) { + super(manager); + } + + @Override + public void onCancel(DialogInterface dialog) { + mCancelled = true; + + mManager.delegate().onDialogCancelled(); + + super.onCancel(dialog); + } + + @Override + public void onDismiss(DialogInterface dialog) { + super.onDismiss(dialog); + + if (mCancelled || mManager == null) return; + + MediaSink newSink = + MediaSink.fromRoute(mManager.androidMediaRouter().getSelectedRoute()); + mManager.delegate().onSinkSelected(newSink); + } + } + @Override protected DialogFragment openDialogInternal(FragmentManager fm) { if (fm.findFragmentByTag(DIALOG_FRAGMENT_TAG) != null) return null; - MediaRouteChooserDialogFragment fragment = new MediaRouteChooserDialogFragment() { - final SystemVisibilitySaver mVisibilitySaver = new SystemVisibilitySaver(); - - @Override - public void onStart() { - mVisibilitySaver.saveSystemVisibility(getActivity()); - super.onStart(); - } - - @Override - public void onStop() { - super.onStop(); - mVisibilitySaver.restoreSystemVisibility(getActivity()); - } - - @Override - public void onCancel(DialogInterface dialog) { - mCancelled = true; - - delegate().onDialogCancelled(); - - super.onCancel(dialog); - } - - @Override - public void onDismiss(DialogInterface dialog) { - super.onDismiss(dialog); - - mDialogFragment = null; - - if (mCancelled) return; - - MediaSink newSink = MediaSink.fromRoute(androidMediaRouter().getSelectedRoute()); - delegate().onSinkSelected(newSink); - } - }; - + Fragment fragment = new Fragment(this); MediaRouteSelector selector = mediaSource().buildRouteSelector(); if (selector == null) return null;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/router/MediaRouteControllerDialogManager.java b/chrome/android/java/src/org/chromium/chrome/browser/media/router/MediaRouteControllerDialogManager.java index 6697e76..5a9b510b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/router/MediaRouteControllerDialogManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/router/MediaRouteControllerDialogManager.java
@@ -8,7 +8,6 @@ import android.content.DialogInterface; import android.support.v4.app.DialogFragment; import android.support.v4.app.FragmentManager; -import android.support.v7.app.MediaRouteControllerDialogFragment; import android.support.v7.media.MediaRouteSelector; import android.support.v7.media.MediaRouter; @@ -38,34 +37,37 @@ mMediaRouteId = mediaRouteId; } + /** + * Fragment implementation for MediaRouteControllerDialogManager. + */ + public static class Fragment extends BaseMediaRouteDialogManager.Fragment { + MediaRouter.Callback mCallback = null; + + public Fragment() { + super(); + } + + public Fragment(BaseMediaRouteDialogManager manager, MediaRouter.Callback callback) { + super(manager); + mCallback = callback; + } + + @Override + public void onDismiss(DialogInterface dialog) { + if (mManager != null) { + mManager.delegate().onDialogCancelled(); + mManager.androidMediaRouter().removeCallback(mCallback); + } + + super.onDismiss(dialog); + } + }; + @Override protected DialogFragment openDialogInternal(FragmentManager fm) { if (fm.findFragmentByTag(DIALOG_FRAGMENT_TAG) != null) return null; - MediaRouteControllerDialogFragment fragment = new MediaRouteControllerDialogFragment() { - final SystemVisibilitySaver mVisibilitySaver = new SystemVisibilitySaver(); - - @Override - public void onStart() { - mVisibilitySaver.saveSystemVisibility(getActivity()); - super.onStart(); - } - - @Override - public void onStop() { - super.onStop(); - mVisibilitySaver.restoreSystemVisibility(getActivity()); - } - - @Override - public void onDismiss(DialogInterface dialog) { - delegate().onDialogCancelled(); - androidMediaRouter().removeCallback(mCallback); - mDialogFragment = null; - super.onDismiss(dialog); - } - }; - + Fragment fragment = new Fragment(this, mCallback); MediaRouteSelector selector = mediaSource().buildRouteSelector(); if (selector == null) return null;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java index af955af8..9177041 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java
@@ -6,6 +6,7 @@ import android.app.Activity; import android.graphics.Canvas; +import android.support.v4.view.ViewCompat; import android.view.LayoutInflater; import android.view.View; import android.widget.TextView; @@ -83,7 +84,8 @@ @Override public void destroy() { - assert !getView().isAttachedToWindow() : "Destroy called before removed from window"; + assert !ViewCompat + .isAttachedToWindow(getView()) : "Destroy called before removed from window"; } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/MostVisitedLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/MostVisitedLayout.java index 2f570b7..7136d52 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/MostVisitedLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/MostVisitedLayout.java
@@ -22,6 +22,7 @@ private static final int MAX_COLUMNS = 4; private int mVerticalSpacing; + private int mExtraVerticalSpacing; private int mMinHorizontalSpacing; private int mMaxHorizontalSpacing; private int mMaxWidth; @@ -51,6 +52,14 @@ mMaxRows = rows; } + /** + * Sets the extra vertical spacing that must be used. It will be distributed evenly above each + * row. + */ + public void setExtraVerticalSpacing(int spacing) { + mExtraVerticalSpacing = spacing; + } + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int totalWidth = resolveSize(mMaxWidth, widthMeasureSpec); @@ -90,7 +99,8 @@ // Limit the number of rows to mMaxRows. int visibleChildCount = Math.min(childCount, mMaxRows * numColumns); - // Arrange the children in a grid. + // Arrange the visible children in a grid. + int numRows = (visibleChildCount + numColumns - 1) / numColumns; int paddingTop = getPaddingTop(); boolean isRtl = ApiCompatibilityUtils.isLayoutRtl(this); for (int i = 0; i < visibleChildCount; i++) { @@ -98,21 +108,22 @@ child.setVisibility(View.VISIBLE); int row = i / numColumns; int column = i % numColumns; - int childTop = row * (childHeight + mVerticalSpacing); + int verticalOffset = Math.round(mExtraVerticalSpacing * ((float) (row + 1) / numRows)); + int childTop = row * (childHeight + mVerticalSpacing) + verticalOffset; int childStart = gridStart + Math.round(column * (childWidth + horizontalSpacing)); MarginLayoutParams layoutParams = (MarginLayoutParams) child.getLayoutParams(); layoutParams.setMargins(isRtl ? 0 : childStart, childTop, isRtl ? childStart : 0, 0); child.setLayoutParams(layoutParams); } - // Hide the last row if it's incomplete. + // Hide any extra children in case there are more than needed for the maximum number of + // rows. for (int i = visibleChildCount; i < childCount; i++) { getChildAt(i).setVisibility(View.GONE); } - int numRows = (visibleChildCount + numColumns - 1) / numColumns; int totalHeight = paddingTop + getPaddingBottom() + numRows * childHeight - + (numRows - 1) * mVerticalSpacing; + + (numRows - 1) * mVerticalSpacing + mExtraVerticalSpacing; setMeasuredDimension(totalWidth, resolveSize(totalHeight, heightMeasureSpec)); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java index 9805257..db4bd45 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java
@@ -13,6 +13,7 @@ import android.net.Uri; import android.os.Build; import android.os.SystemClock; +import android.support.v4.view.ViewCompat; import android.view.ContextMenu; import android.view.LayoutInflater; import android.view.Menu; @@ -33,6 +34,7 @@ import org.chromium.chrome.browser.UrlConstants; import org.chromium.chrome.browser.bookmarks.BookmarkUtils; import org.chromium.chrome.browser.compositor.layouts.content.InvalidationAwareThumbnailProvider; +import org.chromium.chrome.browser.download.DownloadUtils; import org.chromium.chrome.browser.favicon.FaviconHelper; import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconImageCallback; import org.chromium.chrome.browser.favicon.FaviconHelper.IconAvailabilityCallback; @@ -372,6 +374,14 @@ } @Override + public void navigateToDownloadManager() { + if (mIsDestroyed) return; + assert ChromeFeatureList.isEnabled("DownloadsUi"); + RecordUserAction.record("MobileNTPSwitchToDownloadManager"); + DownloadUtils.showDownloadManager(mActivity, mTab); + } + + @Override public void focusSearchBox(boolean beginVoiceSearch, String pastedText) { if (mIsDestroyed) return; if (mFakeboxDelegate != null) { @@ -764,7 +774,8 @@ @Override public void destroy() { assert !mIsDestroyed; - assert !getView().isAttachedToWindow() : "Destroy called before removed from window"; + assert !ViewCompat + .isAttachedToWindow(getView()) : "Destroy called before removed from window"; if (mIsLoaded && !mTab.isHidden()) recordNTPInteractionTime(); if (mFaviconHelper != null) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java index 5015e7d..227b83c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageLayout.java
@@ -111,6 +111,10 @@ // Remove the scroll spacer from the layout so the weighted children can be measured // correctly. mScrollCompensationSpacer.setVisibility(View.GONE); + + // Remove the extra spacing before measuring because it might not be needed anymore. + mMostVisitedLayout.setExtraVerticalSpacing(0); + super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (getMeasuredHeight() > mParentViewportHeight) { @@ -139,6 +143,17 @@ super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } + if (mCardsUiEnabled && mMostVisitedLayout.getChildCount() > 0) { + // If the tiles do not go below the fold by much, it is not clear that the page is + // scrollable. Add some extra space if needed. + int currentBleed = getMeasuredHeight() - mParentViewportHeight; + int minimumBleed = + (int) (mMostVisitedLayout.getChildAt(0).getMeasuredHeight() * 0.7); + if (currentBleed < minimumBleed) { + mMostVisitedLayout.setExtraVerticalSpacing(minimumBleed - currentBleed); + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + } } else { mHasSpaceForPeekingCard = true; // This layout is smaller than or equal to its parent viewport. Redistribute any
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java index 10b98b9..7e510592 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageView.java
@@ -150,6 +150,9 @@ /** Opens the recent tabs page in the current tab. */ void navigateToRecentTabs(); + /** Opens the Download Manager UI in the current tab. */ + void navigateToDownloadManager(); + /** * Opens a URL in the current tab and records related metrics. * @param url the URL to open
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/UiConfig.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/UiConfig.java index 7b12a3b2..8d3aa5ad 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/UiConfig.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/UiConfig.java
@@ -84,6 +84,14 @@ } } + /** + * Returns the currently used display style. + */ + @DisplayStyle + public int getCurrentDisplayStyle() { + return mCurrentDisplayStyle; + } + @DisplayStyle private int computeDisplayStyleForCurrentConfig() { int widthDp = mContext.getResources().getConfiguration().screenWidthDp;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ActionListItem.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ActionListItem.java index 9d93dab..b4b254e1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ActionListItem.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/ActionListItem.java
@@ -6,30 +6,59 @@ import android.view.View; +import org.chromium.base.Log; import org.chromium.chrome.R; import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager; import org.chromium.chrome.browser.ntp.UiConfig; +import org.chromium.chrome.browser.ntp.snippets.KnownCategories; /** * Item that allows the user to perform an action on the NTP. */ class ActionListItem implements NewTabPageListItem { + private static final String TAG = "NtpCards"; + + private final int mCategory; + + public ActionListItem(int category) { + mCategory = category; + } + @Override public int getType() { return NewTabPageListItem.VIEW_TYPE_ACTION; } public static class ViewHolder extends CardViewHolder { + private ActionListItem mActionListItem; + public ViewHolder(NewTabPageRecyclerView recyclerView, final NewTabPageManager manager, UiConfig uiConfig) { super(R.layout.new_tab_page_action_card, recyclerView, uiConfig); - itemView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - // TODO(dgn): Implement other behaviours. - manager.navigateToBookmarks(); - } - }); + itemView.findViewById(R.id.action_button) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + int category = mActionListItem.mCategory; + if (category == KnownCategories.BOOKMARKS) { + manager.navigateToBookmarks(); + } else if (category == KnownCategories.DOWNLOADS) { + manager.navigateToDownloadManager(); + } else { + // TODO(pke): This should redirect to the C++ backend. Once it does, + // change the condition in the SuggestionsSection constructor. + Log.wtf(TAG, + "More action called on a dynamically added section: %d", + category); + } + } + }); + } + + @Override + public void onBindViewHolder(NewTabPageListItem item) { + super.onBindViewHolder(item); + mActionListItem = (ActionListItem) item; } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java index f5e1ae8..44dbcdc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java
@@ -11,6 +11,7 @@ import android.support.v4.view.animation.FastOutLinearInInterpolator; import android.support.v4.view.animation.FastOutSlowInInterpolator; import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.RecyclerView.ViewHolder; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.LayoutInflater; @@ -110,7 +111,11 @@ }); mUiConfig = uiConfig; - mDisplayStyleObserverAdapter = MarginResizer.createWithViewAdapter(itemView, mUiConfig); + + // Configure the resizer to use negative margins on regular display to balance out the + // lateral shadow of the card 9-patch and avoid a rounded corner effect. + mDisplayStyleObserverAdapter = + MarginResizer.createWithViewAdapter(itemView, mUiConfig, -mCards9PatchAdjustment); } /** @@ -131,17 +136,30 @@ @Override public void updateLayoutParams() { - RecyclerView.LayoutParams params = getParams(); - // Each card has the full elevation effect so we will remove bottom margin to overlay and // hide the bottom shadow of the previous card to give the effect of a divider instead of a // shadow. - if (mRecyclerView.getAdapter().getItemViewType(getAdapterPosition() + 1) - == NewTabPageListItem.VIEW_TYPE_SNIPPET) { - params.bottomMargin = -mCards9PatchAdjustment; - } else { - params.bottomMargin = 0; + // Notes: + // - An alternative way to check that 2 cards are coming one after the other would be to + // check the item's ViewType, but we decided against for now to avoid having to maintain + // a separate listing of all the view types that are cards. Their ViewHolders are all + // CardViewHolder so it's a robust way to do the check. + // - The drawback of using ViewHolders is that they are not instantiated yet for all the + // items in the list. At a given moment, the below code will not properly adjust the + // margin of cards for which the next card ViewHolder has not yet been created and added + // to the RecyclerView. It doesn't matter still because a layout pass will be requested + // when that ViewHolder is added, calling this method again and fixing the margins + // before they enter the view. + ViewHolder previousViewHolder = + mRecyclerView.findViewHolderForAdapterPosition(getAdapterPosition() - 1); + if (previousViewHolder instanceof CardViewHolder) { + ((CardViewHolder) previousViewHolder).getParams().bottomMargin = + -mCards9PatchAdjustment; } + + // Reset the margin to 0 here. If it should take the 9-patch adjustment into account, the + // next card will set the value, since the method is called on the cards in layout order. + getParams().bottomMargin = 0; } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/MarginResizer.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/MarginResizer.java index 71591da..b6d6a7c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/MarginResizer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/MarginResizer.java
@@ -15,15 +15,37 @@ * Adds lateral margins to the view when the display style is {@link UiConfig#DISPLAY_STYLE_WIDE}. */ public class MarginResizer implements DisplayStyleObserver { + private final int mDefaultMarginSizePixels; private final int mWideMarginSizePixels; private final View mView; + /** + * Factory method that creates a {@link MarginResizer} and wraps it in a + * {@link DisplayStyleObserverAdapter} that will take care of invoking it when appropriate. + * Uses 0px as margins when on a non wide layout. + * @param view the view that will have its margins resized + * @param config the UiConfig object to subscribe to + */ public static DisplayStyleObserverAdapter createWithViewAdapter(View view, UiConfig config) { - return new DisplayStyleObserverAdapter(view, config, new MarginResizer(view)); + return new DisplayStyleObserverAdapter(view, config, new MarginResizer(view, 0)); } - public MarginResizer(View view) { + /** + * Factory method that creates a {@link MarginResizer} and wraps it in a + * {@link DisplayStyleObserverAdapter} that will take care of invoking it when appropriate + * @param view the view that will have its margins resized + * @param config the UiConfig object to subscribe to + * @param defaultMargin the margins to use on non-wide layouts + */ + public static DisplayStyleObserverAdapter createWithViewAdapter( + View view, UiConfig config, int defaultMargin) { + return new DisplayStyleObserverAdapter( + view, config, new MarginResizer(view, defaultMargin)); + } + + public MarginResizer(View view, int defaultMarginSize) { mView = view; + mDefaultMarginSizePixels = defaultMarginSize; mWideMarginSizePixels = view.getResources().getDimensionPixelSize(R.dimen.ntp_wide_card_lateral_margins); } @@ -35,7 +57,8 @@ layoutParams.setMargins(mWideMarginSizePixels, layoutParams.topMargin, mWideMarginSizePixels, layoutParams.bottomMargin); } else { - layoutParams.setMargins(0, layoutParams.topMargin, 0, layoutParams.bottomMargin); + layoutParams.setMargins(mDefaultMarginSizePixels, layoutParams.topMargin, + mDefaultMarginSizePixels, layoutParams.bottomMargin); } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java index b9673f24..5a70252 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java
@@ -13,10 +13,12 @@ import org.chromium.base.Callback; import org.chromium.base.Log; +import org.chromium.chrome.R; import org.chromium.chrome.browser.ntp.NewTabPageLayout; import org.chromium.chrome.browser.ntp.NewTabPageUma; import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager; import org.chromium.chrome.browser.ntp.UiConfig; +import org.chromium.chrome.browser.ntp.snippets.CategoryInt; import org.chromium.chrome.browser.ntp.snippets.CategoryStatus; import org.chromium.chrome.browser.ntp.snippets.CategoryStatus.CategoryStatusEnum; import org.chromium.chrome.browser.ntp.snippets.SnippetArticleListItem; @@ -125,8 +127,14 @@ mUiConfig = uiConfig; for (int category : mSuggestionsSource.getCategories()) { + int categoryStatus = suggestionsSource.getCategoryStatus(category); + assert categoryStatus != CategoryStatus.NOT_PROVIDED; + if (categoryStatus == CategoryStatus.LOADING_ERROR + || categoryStatus == CategoryStatus.CATEGORY_EXPLICITLY_DISABLED) + continue; + setSuggestions(category, suggestionsSource.getSuggestionsForCategory(category), - suggestionsSource.getCategoryStatus(category)); + categoryStatus); } suggestionsSource.setObserver(this); updateGroups(); @@ -138,7 +146,7 @@ } @Override - public void onNewSuggestions(int category) { + public void onNewSuggestions(@CategoryInt int category) { // We never want to refresh the suggestions if we already have some content. if (mSections.containsKey(category) && mSections.get(category).hasSuggestions()) return; @@ -164,20 +172,34 @@ } @Override - public void onCategoryStatusChanged(int category, @CategoryStatusEnum int status) { + public void onCategoryStatusChanged(@CategoryInt int category, @CategoryStatusEnum int status) { // Observers should not be registered for this state. assert status != CategoryStatus.ALL_SUGGESTIONS_EXPLICITLY_DISABLED; // If there is no section for this category there is nothing to do. if (!mSections.containsKey(category)) return; + // The section provider has gone away. Keep open UIs as they are. + if (status == CategoryStatus.NOT_PROVIDED) return; + SuggestionsSection section = mSections.get(category); // The section already has suggestions but we just got notified about the provider being // enabled. Nothing to do. if (SnippetsBridge.isCategoryStatusAvailable(status) && section.hasSuggestions()) return; - setSuggestions(category, Collections.<SnippetArticleListItem>emptyList(), status); + if (status == CategoryStatus.CATEGORY_EXPLICITLY_DISABLED + || status == CategoryStatus.LOADING_ERROR) { + // Need to remove the entire section from the UI immediately. + mSections.remove(category); + } else { + // Two cases, in both we just want to update the status: + // - status is one of the AVAILABLE statuses, but we didn't have suggestions before and + // we're also not getting them now (but probably right after in OnNewSuggestions). + // - status is non-AVAILABLE, but also none of the serious ones above, so this will + // show a status card and remove the current content. + setSuggestions(category, Collections.<SnippetArticleListItem>emptyList(), status); + } updateGroups(); } @@ -268,11 +290,12 @@ SnippetsBridge.fetchSnippets(/*forceRequest=*/true); } - private void setSuggestions(int category, List<SnippetArticleListItem> suggestions, + private void setSuggestions(@CategoryInt int category, List<SnippetArticleListItem> suggestions, @CategoryStatusEnum int status) { if (!mSections.containsKey(category)) { SuggestionsCategoryInfo info = mSuggestionsSource.getCategoryInfo(category); - mSections.put(category, new SuggestionsSection(suggestions, status, info, this)); + mSections.put( + category, new SuggestionsSection(category, suggestions, status, info, this)); } else { mSections.get(category).setSuggestions(suggestions, status, this); } @@ -319,6 +342,10 @@ } }); + itemViewHolder.itemView.announceForAccessibility( + itemViewHolder.itemView.getResources().getString( + R.string.ntp_accessibility_item_removed, suggestion.mTitle)); + mSuggestionsSource.dismissSuggestion(suggestion); SuggestionsSection section = (SuggestionsSection) getGroup(position); section.dismissSuggestion(suggestion);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/StatusListItem.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/StatusListItem.java index dac9ab5..74921e3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/StatusListItem.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/StatusListItem.java
@@ -64,21 +64,6 @@ } } - private static class ErrorListItem extends StatusListItem { - public ErrorListItem(int headerStringId, int descriptionStringId) { - super(headerStringId, descriptionStringId, 0); - } - @Override - protected void performAction(Context context) { - // No action. - } - - @Override - protected boolean hasAction() { - return false; - } - } - private static class NoSnippets extends StatusListItem { private final NewTabPageAdapter mNewTabPageAdapter; @@ -110,26 +95,6 @@ } } - private static class CategoryExplicitlyDisabled extends ErrorListItem { - public CategoryExplicitlyDisabled() { - // TODO(pke): Those are technically the wrong strings, but they roughly fit in this - // case. This should only be called when the category has been disabled via enterprise - // policy. Replace this with proper error card once it has been specified. - super(R.string.ntp_status_card_title_empty, R.string.ntp_status_card_body_empty); - Log.d(TAG, "Registering card for error: Category Explicitly Disabled"); - } - } - - private static class ProviderError extends ErrorListItem { - public ProviderError() { - // TODO(pke): Those are technically the wrong strings, but they roughly fit in this - // case. This is only called if NTPSnippetsDatabase encounters an error. - // Replace this with proper error card once it has been specified. - super(R.string.ntp_status_card_title_empty, R.string.ntp_status_card_body_empty); - Log.d(TAG, "Registering card for error: Provider Error"); - } - } - private static final String TAG = "NtpCards"; private final int mHeaderStringId; @@ -149,27 +114,30 @@ return new SignedOut(); case CategoryStatus.ALL_SUGGESTIONS_EXPLICITLY_DISABLED: - Log.wtf(TAG, "FATAL: Attempted to create a status card while the feature should be " - + "off."); + Log.wtf(TAG, "Attempted to create a status card while the feature should be off."); return null; case CategoryStatus.CATEGORY_EXPLICITLY_DISABLED: - Log.d(TAG, "Not showing ARTICLES suggestions because this category is disabled."); - // TODO(pke): Replace this. - return new CategoryExplicitlyDisabled(); + // In this case, the entire section should have been cleared off the UI. + Log.wtf(TAG, "Attempted to create a status card for content suggestions " + + " when the category status is CATEGORY_EXPLICITLY_DISABLED."); + return null; case CategoryStatus.NOT_PROVIDED: - Log.wtf(TAG, "FATAL: Attempted to create a status card for content suggestions " - + " when provider for ARTICLES is not registered."); + // In this case, the UI should remain as it is and also keep the previous category + // status, so the NOT_PROVIDED should never reach here. + Log.wtf(TAG, "Attempted to create a status card for content suggestions " + + " when the category is NOT_PROVIDED."); return null; case CategoryStatus.LOADING_ERROR: - Log.d(TAG, "Not showing ARTICLES suggestions because of provider error."); - // TODO(pke): Replace this. - return new ProviderError(); + // In this case, the entire section should have been cleared off the UI. + Log.wtf(TAG, "Attempted to create a status card for content suggestions " + + " when the category is LOADING_ERROR."); + return null; default: - Log.wtf(TAG, "FATAL: Attempted to create a status card for an unknown value: %d", + Log.wtf(TAG, "Attempted to create a status card for an unknown value: %d", categoryStatus); return null; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsCategoryInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsCategoryInfo.java index b91a0d3..d10147e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsCategoryInfo.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsCategoryInfo.java
@@ -22,17 +22,30 @@ @ContentSuggestionsCardLayoutEnum private final int mCardLayout; - public SuggestionsCategoryInfo(String title, @ContentSuggestionsCardLayoutEnum int cardLayout) { - this.mTitle = title; - this.mCardLayout = cardLayout; + /** + * Whether the category supports a "More" button. The button either triggers + * a fixed action (like opening a native page) or, if there is no such fixed + * action, it queries the provider for more suggestions. + */ + private final boolean mHasMoreButton; + + public SuggestionsCategoryInfo( + String title, @ContentSuggestionsCardLayoutEnum int cardLayout, boolean hasMoreButton) { + mTitle = title; + mCardLayout = cardLayout; + mHasMoreButton = hasMoreButton; } public String getTitle() { - return this.mTitle; + return mTitle; } @ContentSuggestionsCardLayoutEnum public int getCardLayout() { - return this.mCardLayout; + return mCardLayout; + } + + public boolean hasMoreButton() { + return mHasMoreButton; } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java index 0129065e..edd9704 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SuggestionsSection.java
@@ -4,7 +4,9 @@ package org.chromium.chrome.browser.ntp.cards; +import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.ntp.snippets.CategoryStatus.CategoryStatusEnum; +import org.chromium.chrome.browser.ntp.snippets.KnownCategories; import org.chromium.chrome.browser.ntp.snippets.SnippetArticleListItem; import org.chromium.chrome.browser.ntp.snippets.SnippetHeaderListItem; import org.chromium.chrome.browser.ntp.snippets.SnippetsBridge; @@ -18,18 +20,26 @@ */ public class SuggestionsSection implements ItemGroup { private final List<SnippetArticleListItem> mSuggestions = new ArrayList<>(); - private final SuggestionsCategoryInfo mInfo; private final SnippetHeaderListItem mHeader; private StatusListItem mStatus; private final ProgressListItem mProgressIndicator = new ProgressListItem(); private final ActionListItem mMoreButton; - public SuggestionsSection(List<SnippetArticleListItem> suggestions, + public SuggestionsSection(int category, List<SnippetArticleListItem> suggestions, @CategoryStatusEnum int status, SuggestionsCategoryInfo info, NewTabPageAdapter adapter) { - mInfo = info; - mHeader = new SnippetHeaderListItem(mInfo.getTitle()); - mMoreButton = null; // TODO(pke): Read from info => ? new ActionListItem() : null; + + mHeader = new SnippetHeaderListItem(info.getTitle()); + // TODO(pke): Replace the condition with "info.hasMoreButton()" once all other categories + // are supported by the C++ backend, too. + // Right now, we hard-code all the sections that are handled in ActionListItem. + boolean showMoreButton = false; + if (category == KnownCategories.BOOKMARKS) { + showMoreButton = true; + } else if (category == KnownCategories.DOWNLOADS) { + showMoreButton = ChromeFeatureList.isEnabled("DownloadsUi"); + } + mMoreButton = showMoreButton ? new ActionListItem(category) : null; setSuggestions(suggestions, status, adapter); } @@ -49,10 +59,6 @@ public void dismissSuggestion(SnippetArticleListItem suggestion) { mSuggestions.remove(suggestion); - - if (mSuggestions.isEmpty()) { - mHeader.setVisible(false); - } } public boolean hasSuggestions() { @@ -63,8 +69,6 @@ @CategoryStatusEnum int status, NewTabPageAdapter adapter) { copyThumbnails(suggestions); - mHeader.setVisible(!suggestions.isEmpty()); - mStatus = StatusListItem.create(status, adapter); mProgressIndicator.setVisible(SnippetsBridge.isCategoryLoading(status));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/CategoryInt.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/CategoryInt.java new file mode 100644 index 0000000..8071944 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/CategoryInt.java
@@ -0,0 +1,19 @@ +// Copyright 2016 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.ntp.snippets; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Annotation used to denote int values that identify a content suggestion category. + * Because the set of categories is not fully known at compile time, we can't use an {@link @IntDef} + * annotation. + * Currently nothing enforces that a value annotated this way actually is a valid category ID, + * but it serves as documentation. + */ +@Retention(value = RetentionPolicy.SOURCE) +public @interface CategoryInt { +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleListItem.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleListItem.java index e10051f..54fc60ab 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleListItem.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleListItem.java
@@ -8,6 +8,7 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.browser.ntp.NewTabPageUma; import org.chromium.chrome.browser.ntp.cards.NewTabPageListItem; +import org.chromium.chrome.browser.ntp.snippets.ContentSuggestionsCardLayout.ContentSuggestionsCardLayoutEnum; /** * Represents the data for an article card on the NTP. @@ -40,6 +41,10 @@ /** The position of this article in the whole list of snippets. */ public final int mPosition; + /** The layout that should be used to display the snippet. */ + @ContentSuggestionsCardLayoutEnum + public final int mCardLayout; + /** Bitmap of the thumbnail, fetched lazily, when the RecyclerView wants to show the snippet. */ private Bitmap mThumbnailBitmap; @@ -53,7 +58,8 @@ * Creates a SnippetArticleListItem object that will hold the data. */ public SnippetArticleListItem(String id, String title, String publisher, String previewText, - String url, String ampUrl, long timestamp, float score, int position) { + String url, String ampUrl, long timestamp, float score, int position, + @ContentSuggestionsCardLayoutEnum int cardLayout) { mId = id; mTitle = title; mPublisher = publisher; @@ -63,6 +69,7 @@ mPublishTimestampMilliseconds = timestamp; mScore = score; mPosition = position; + mCardLayout = cardLayout; } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java index 02acf3e..52406762 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java
@@ -20,6 +20,7 @@ import android.view.View.MeasureSpec; import android.view.ViewTreeObserver; import android.widget.ImageView; +import android.widget.RelativeLayout; import android.widget.TextView; import org.chromium.base.ApiCompatibilityUtils; @@ -80,6 +81,7 @@ private int mPublisherFaviconSizePx; private final boolean mUseFaviconService; + private final UiConfig mUiConfig; /** * Constructs a SnippetCardItemView item used to display snippets @@ -127,16 +129,11 @@ } }); + mUiConfig = uiConfig; new DisplayStyleObserverAdapter(itemView, uiConfig, new DisplayStyleObserver() { @Override public void onDisplayStyleChanged(@UiConfig.DisplayStyle int newDisplayStyle) { - if (newDisplayStyle == UiConfig.DISPLAY_STYLE_NARROW) { - mHeadlineTextView.setMaxLines(4); - mArticleSnippetTextView.setVisibility(View.GONE); - } else { - mHeadlineTextView.setMaxLines(2); - mArticleSnippetTextView.setVisibility(View.VISIBLE); - } + updateLayout(); } }); @@ -169,7 +166,8 @@ R.string.contextmenu_open_in_incognito_tab); } - if (OfflinePageBridge.isBackgroundLoadingEnabled() + // TODO(peconn): Only show 'Save for Offline' for appropriate snippet types. + if (SnippetsConfig.isSaveToOfflineEnabled() && OfflinePageBridge.canSavePage(mArticle.mUrl)) { addContextMenuItem(menu, ID_SAVE_FOR_OFFLINE, R.string.contextmenu_save_offline); @@ -209,7 +207,7 @@ NewTabPageUma.OPEN_SNIPPET_METHODS_SAVE_FOR_OFFLINE); OfflinePageBridge bridge = OfflinePageBridge.getForProfile(Profile.getLastUsedProfile()); - bridge.savePageLaterForDownload(mArticle.mUrl); + bridge.savePageLaterForDownload(mArticle.mUrl, "ntp_suggestions"); return true; case ID_REMOVE: assert isDismissable() : "Context menu should not be shown for peeking card."; @@ -221,11 +219,44 @@ } } + /** + * Updates the layout taking into account screen dimensions and the type of snippet displayed. + */ + private void updateLayout() { + boolean narrow = mUiConfig.getCurrentDisplayStyle() == UiConfig.DISPLAY_STYLE_NARROW; + boolean minimal = mArticle.mCardLayout == ContentSuggestionsCardLayout.MINIMAL_CARD; + + // If the screen is narrow, increase the number of lines in the header. + mHeadlineTextView.setMaxLines(narrow ? 4 : 2); + + // If the screen is narrow or we are using the minimal layout, hide the article snippet. + mArticleSnippetTextView.setVisibility((narrow || minimal) ? View.GONE : View.VISIBLE); + + // If we are using minimal layout, hide the thumbnail. + mThumbnailView.setVisibility(minimal ? View.GONE : View.VISIBLE); + + // If we aren't showing the article snippet, reduce the top margin for publisher text. + RelativeLayout.LayoutParams params = + (RelativeLayout.LayoutParams) mPublisherTextView.getLayoutParams(); + + int topMargin = mPublisherTextView.getResources().getDimensionPixelSize( + minimal ? R.dimen.snippets_publisher_margin_top_without_article_snippet + : R.dimen.snippets_publisher_margin_top_with_article_snippet); + + params.setMargins(params.leftMargin, + topMargin, + params.rightMargin, + params.bottomMargin); + + mPublisherTextView.setLayoutParams(params); + } + @Override public void onBindViewHolder(NewTabPageListItem article) { super.onBindViewHolder(article); mArticle = (SnippetArticleListItem) article; + updateLayout(); mHeadlineTextView.setText(mArticle.mTitle); @@ -249,12 +280,15 @@ cancelImageFetch(); // If the article has a thumbnail already, reuse it. Otherwise start a fetch. - if (mArticle.getThumbnailBitmap() != null) { - mThumbnailView.setImageBitmap(mArticle.getThumbnailBitmap()); - } else { - mThumbnailView.setImageResource(R.drawable.ic_snippet_thumbnail_placeholder); - mImageCallback = new FetchImageCallback(this, mArticle); - mSuggestionsSource.fetchSuggestionImage(mArticle, mImageCallback); + // mThumbnailView's visibility is modified in updateLayout(). + if (mThumbnailView.getVisibility() == View.VISIBLE) { + if (mArticle.getThumbnailBitmap() != null) { + mThumbnailView.setImageBitmap(mArticle.getThumbnailBitmap()); + } else { + mThumbnailView.setImageResource(R.drawable.ic_snippet_thumbnail_placeholder); + mImageCallback = new FetchImageCallback(this, mArticle); + mSuggestionsSource.fetchSuggestionImage(mArticle, mImageCallback); + } } // Set the favicon of the publisher.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetHeaderListItem.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetHeaderListItem.java index e2a2f7a4..84f0977 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetHeaderListItem.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetHeaderListItem.java
@@ -16,12 +16,16 @@ */ public class SnippetHeaderListItem implements NewTabPageListItem { /** Whether the header should be shown. */ - private boolean mVisible = false; + private final boolean mVisible; /** The header text to be shown. */ private final String mHeaderText; public SnippetHeaderListItem(String headerText) { + // TODO(mvanouwerkerk): Configure mVisible in the constructor when we have a global status + // section without a visible header. + mVisible = true; + this.mHeaderText = headerText; } @@ -45,10 +49,6 @@ return mVisible; } - public void setVisible(boolean visible) { - mVisible = visible; - } - public String getHeaderText() { return mHeaderText; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java index 3893bfc8..7acd9c3 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsBridge.java
@@ -100,6 +100,7 @@ @Override public void fetchSuggestionImage(SnippetArticleListItem suggestion, Callback<Bitmap> callback) { + assert mNativeSnippetsBridge != 0; nativeFetchSuggestionImage(mNativeSnippetsBridge, suggestion.mId, callback); } @@ -141,27 +142,28 @@ @CalledByNative private static void addSuggestion(List<SnippetArticleListItem> suggestions, String id, String title, String publisher, String previewText, String url, String ampUrl, - long timestamp, float score) { + long timestamp, float score, int cardLayout) { int position = suggestions.size(); suggestions.add(new SnippetArticleListItem(id, title, publisher, previewText, url, ampUrl, - timestamp, score, position)); + timestamp, score, position, cardLayout)); } @CalledByNative private static SuggestionsCategoryInfo createSuggestionsCategoryInfo( - String title, int cardLayout) { - return new SuggestionsCategoryInfo(title, cardLayout); + String title, int cardLayout, boolean hasMoreButton) { + return new SuggestionsCategoryInfo(title, cardLayout, hasMoreButton); } @CalledByNative - private void onNewSuggestions(int category) { + private void onNewSuggestions(/* @CategoryInt */ int category) { assert mNativeSnippetsBridge != 0; assert mObserver != null; mObserver.onNewSuggestions(category); } @CalledByNative - private void onCategoryStatusChanged(int category, /* @CategoryStatusEnum */ int newStatus) { + private void onCategoryStatusChanged(/* @CategoryInt */ int category, /* @CategoryStatusEnum */ + int newStatus) { if (mObserver != null) mObserver.onCategoryStatusChanged(category, newStatus); } @@ -178,7 +180,7 @@ private native void nativeFetchSuggestionImage( long nativeNTPSnippetsBridge, String suggestionId, Callback<Bitmap> callback); private native void nativeDismissSuggestion(long nativeNTPSnippetsBridge, String suggestionId); - private static native void nativeGetURLVisited( + private native void nativeGetURLVisited( long nativeNTPSnippetsBridge, Callback<Boolean> callback, String url); private native void nativeSetObserver(long nativeNTPSnippetsBridge, SnippetsBridge bridge); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsConfig.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsConfig.java index 4397a92c..e15f86f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsConfig.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsConfig.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.ntp.snippets; import org.chromium.chrome.browser.ChromeFeatureList; +import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; import org.chromium.chrome.browser.preferences.PrefServiceBridge; /** @@ -17,4 +18,9 @@ return ChromeFeatureList.isEnabled(ChromeFeatureList.NTP_SNIPPETS) && PrefServiceBridge.getInstance().isSearchSuggestEnabled(); } + + public static boolean isSaveToOfflineEnabled() { + return ChromeFeatureList.isEnabled(ChromeFeatureList.NTP_SNIPPETS_SAVE_TO_OFFLINE) + && OfflinePageBridge.isBackgroundLoadingEnabled(); + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SuggestionsSource.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SuggestionsSource.java index 2d69120..2140655f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SuggestionsSource.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/snippets/SuggestionsSource.java
@@ -46,7 +46,8 @@ /** * Gets the current content suggestions for a category, in the order in which they should be - * displayed. + * displayed. If the status of the category is not one of the available statuses, this will + * return an empty list. */ List<SnippetArticleListItem> getSuggestionsForCategory(int category);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java index 60824e25..0a6ace7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
@@ -246,32 +246,17 @@ return result; } - /** - * Gets the offline pages associated with a provided online URL. The callback is called when - * the results are available. + /** + * Get the offline page associated with the provided offline URL. * - * @param onlineURL URL of the page. - * @param callback Called with the results. + * @param onlineUrl URL of the page. + * @param tabId Android tab ID. + * @param callback callback to pass back the + * matching {@link OfflinePageItem} if found. Will pass back null if not. */ - @VisibleForTesting - public void getPagesByOnlineUrl( - final String onlineUrl, final Callback<List<OfflinePageItem>> callback) { - runWhenLoaded(new Runnable() { - @Override - public void run() { - List<OfflinePageItem> result = new ArrayList<>(); - - // TODO(http://crbug.com/589526) This native API returns only one item, but in the - // future will return a list. - OfflinePageItem item = - nativeGetBestPageForOnlineURL(mNativeOfflinePageBridge, onlineUrl); - if (item != null) { - result.add(item); - } - - callback.onResult(result); - } - }); + public void selectPageForOnlineUrl(String onlineUrl, int tabId, + Callback<OfflinePageItem> callback) { + nativeSelectPageForOnlineUrl(mNativeOfflinePageBridge, onlineUrl, tabId, callback); } /** @@ -316,14 +301,15 @@ /** * Save the given URL as an offline page when the network becomes available with a randomly - * generated clientId in the 'async_loading' namespace. + * generated clientId in the given namespace. * * @param url The given URL to save for later. + * @param namespace The namespace for the offline page to be saved later. */ - public void savePageLaterForDownload(final String url) { + public void savePageLaterForDownload(final String url, final String namespace) { // Download UI needs "async_loading" namespace and a random (type 4) GUID. String uuid = UUID.randomUUID().toString(); - ClientId clientId = new ClientId("async_loading", uuid); + ClientId clientId = new ClientId(namespace, uuid); savePageLater(url, clientId); } @@ -518,8 +504,9 @@ @VisibleForTesting native OfflinePageItem nativeGetPageByOfflineId(long nativeOfflinePageBridge, long offlineId); - private native OfflinePageItem nativeGetBestPageForOnlineURL( - long nativeOfflinePageBridge, String onlineURL); + private native void nativeSelectPageForOnlineUrl( + long nativeOfflinePageBridge, String onlineUrl, int tabId, + Callback<OfflinePageItem> callback); private native void nativeGetPageByOfflineUrl( long nativeOfflinePageBridge, String offlineUrl, Callback<OfflinePageItem> callback); private native void nativeSavePage(long nativeOfflinePageBridge, SavePageCallback callback,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java index 1060270..54de20ea 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtils.java
@@ -39,10 +39,13 @@ /** Background task tag to differentiate from other task types */ public static final String TASK_TAG = "OfflinePageUtils"; - private static final int SNACKBAR_DURATION = 6 * 1000; // 6 second + private static final int DEFAULT_SNACKBAR_DURATION_MS = 6 * 1000; // 6 second private static final long STORAGE_ALMOST_FULL_THRESHOLD_BYTES = 10L * (1 << 20); // 10M + // Used instead of the constant so tests can override the value. + private static int sSnackbarDurationMs = DEFAULT_SNACKBAR_DURATION_MS; + private static OfflinePageUtils sInstance; private static OfflinePageUtils getInstance() { @@ -179,7 +182,7 @@ Snackbar.make(context.getString(R.string.offline_pages_viewing_offline_page), snackbarController, Snackbar.TYPE_ACTION, Snackbar.UMA_OFFLINE_PAGE_RELOAD) .setSingleLine(false).setAction(context.getString(R.string.reload), tabId); - snackbar.setDuration(SNACKBAR_DURATION); + snackbar.setDuration(sSnackbarDurationMs); snackbarManager.showSnackbar(snackbar); } @@ -289,4 +292,9 @@ static void setInstanceForTesting(OfflinePageUtils instance) { sInstance = instance; } + + @VisibleForTesting + public static void setSnackbarDurationForTesting(int durationMs) { + sSnackbarDurationMs = durationMs; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/downloads/OfflinePageDownloadBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/downloads/OfflinePageDownloadBridge.java index 428353e8..c1d3328 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/downloads/OfflinePageDownloadBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/downloads/OfflinePageDownloadBridge.java
@@ -8,6 +8,10 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; +import org.chromium.chrome.browser.tabmodel.document.TabDelegate; +import org.chromium.content_public.browser.LoadUrlParams; import java.util.ArrayList; import java.util.List; @@ -97,12 +101,57 @@ * Gets a download item related to the provided GUID. * @param guid a GUID of the item to get. * @return download item related to the offline page identified by GUID. - * */ + */ public OfflinePageDownloadItem getItem(String guid) { return nativeGetItemByGuid(mNativeOfflinePageDownloadBridge, guid); } /** + * Schedules deletion of the offline page identified by the GUID. + * If the item is still in the process of download, the download is canceled. + * Actual cancel and/or deletion happens asynchronously, Observer is notified when it's done. + * @param guid a GUID of the item to delete. + */ + public void deleteItem(String guid) { + nativeDeleteItemByGuid(mNativeOfflinePageDownloadBridge, guid); + } + + /** + * 'Opens' the offline page identified by the GUID. + * This is done by creating a new tab and navigating it to the saved local snapshot. + * No automatic redirection is happening based on the connection status. + * If the item with specified GUID is not found or can't be opened, nothing happens. + * @param guid a GUID of the item to open. + */ + public void openItem(String guid) { + String url = nativeGetOfflineUrlByGuid(mNativeOfflinePageDownloadBridge, guid); + if (url == null) return; + + LoadUrlParams params = new LoadUrlParams(url); + // TODO(dimich): W/o forcing offline, the page gets redirected to online + // URL if device is connected. Figure out how to force the offline by + // observing the request header. + // Map<String, String> headers = new HashMap<String, String>(); + // headers.put("x-chrome-force-offline", "true"); + // params.setExtraHeaders(headers); + final TabDelegate tabDelegate = new TabDelegate(false); + tabDelegate.createNewTab(params, TabLaunchType.FROM_LINK, null); + } + + /** + * Starts download of the page currently open in the specified Tab. + * If tab's contents are not yet loaded completely, we'll wait for it + * to load enough for snapshot to be reasonable. If the Chrome is made + * background and killed, the background request remains that will + * eventually load the page in background and obtain its offline + * snapshot. + * @param tab a tab contents of which will be saved locally. + */ + public void startDownload(Tab tab) { + // TODO(dimich): Next patch. + } + + /** * Method to ensure that the bridge is created for tests without calling the native portion of * initialization. * @param isTesting flag indicating whether the constructor will initialize native code. @@ -163,4 +212,6 @@ long nativeOfflinePageDownloadBridge, List<OfflinePageDownloadItem> items); native OfflinePageDownloadItem nativeGetItemByGuid( long nativeOfflinePageDownloadBridge, String guid); + native void nativeDeleteItemByGuid(long nativeOfflinePageDownloadBridge, String guid); + native String nativeGetOfflineUrlByGuid(long nativeOfflinePageDownloadBridge, String guid); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/pageinfo/WebsiteSettingsPopup.java b/chrome/android/java/src/org/chromium/chrome/browser/pageinfo/WebsiteSettingsPopup.java index de13e5e..b081c12 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/pageinfo/WebsiteSettingsPopup.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/pageinfo/WebsiteSettingsPopup.java
@@ -45,12 +45,10 @@ import android.widget.TextView; import org.chromium.base.ApiCompatibilityUtils; -import org.chromium.base.Callback; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; import org.chromium.chrome.browser.ContentSettingsType; -import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; import org.chromium.chrome.browser.offlinepages.OfflinePageItem; import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; import org.chromium.chrome.browser.omnibox.OmniboxUrlEmphasizer; @@ -933,33 +931,21 @@ assert false : "Invalid source passed"; } - OfflinePageBridge offlinePageBridge = OfflinePageBridge.getForProfile(tab.getProfile()); - if (offlinePageBridge == null) { - new WebsiteSettingsPopup( - activity, tab.getProfile(), tab.getWebContents(), null, null, contentPublisher); - return; + String offlinePageOriginalUrl = null; + String offlinePageCreationDate = null; + + OfflinePageItem offlinePage = tab.getOfflinePage(); + if (offlinePage != null) { + // Get formatted creation date of the offline page. + Date creationDate = new Date(offlinePage.getCreationTimeMs()); + DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM); + offlinePageCreationDate = df.format(creationDate); + offlinePageOriginalUrl = OfflinePageUtils.stripSchemeFromOnlineUrl( + offlinePage.getUrl()); } - Callback<OfflinePageItem> callback = new Callback<OfflinePageItem>() { - @Override - public void onResult(OfflinePageItem item) { - String offlinePageOriginalUrl = null; - String offlinePageCreationDate = null; - - if (item != null) { - // Get formatted creation date and original URL of the offline copy. - Date creationDate = new Date(item.getCreationTimeMs()); - DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM); - offlinePageCreationDate = df.format(creationDate); - offlinePageOriginalUrl = - OfflinePageUtils.stripSchemeFromOnlineUrl(item.getUrl()); - } - new WebsiteSettingsPopup(activity, tab.getProfile(), tab.getWebContents(), - offlinePageOriginalUrl, offlinePageCreationDate, contentPublisher); - } - }; - - offlinePageBridge.getPageByOfflineUrl(tab.getWebContents().getVisibleUrl(), callback); + new WebsiteSettingsPopup(activity, tab.getProfile(), tab.getWebContents(), + offlinePageOriginalUrl, offlinePageCreationDate, contentPublisher); } private static native long nativeInit(WebsiteSettingsPopup popup, WebContents webContents);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/OWNERS b/chrome/android/java/src/org/chromium/chrome/browser/payments/OWNERS new file mode 100644 index 0000000..29ccaea --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/OWNERS
@@ -0,0 +1 @@ +rouslan@chromium.org
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java index 9c411e3..f094d25c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
@@ -708,6 +708,8 @@ // This may update the line items. mUiShippingOptions.setSelectedItem(option); mClient.onShippingOptionChange(option.getIdentifier()); + mPaymentInformationCallback = callback; + return PaymentRequestUI.SELECTION_RESULT_ASYNCHRONOUS_VALIDATION; } else if (optionType == PaymentRequestUI.TYPE_CONTACT_DETAILS) { assert option instanceof AutofillContact; AutofillContact contact = (AutofillContact) option; @@ -834,7 +836,7 @@ @Override public void onDismiss() { disconnectFromClientWithDebugMessage("Dialog dismissed"); - closeUI(false); + closeUI(true); recordAbortReasonHistogram(PaymentRequestMetrics.ABORT_REASON_ABORTED_BY_USER); } @@ -846,7 +848,7 @@ Log.d(TAG, debugMessage); if (mClient != null) mClient.onError(reason); closeClient(); - closeUI(false); + closeUI(true); } @Override @@ -865,7 +867,7 @@ if (sObserverForTest != null) sObserverForTest.onPaymentRequestServiceUnableToAbort(); } else { closeClient(); - closeUI(false); + closeUI(true); recordAbortReasonHistogram(PaymentRequestMetrics.ABORT_REASON_ABORTED_BY_MERCHANT); } } @@ -887,7 +889,7 @@ public void close() { if (mClient == null) return; closeClient(); - closeUI(false); + closeUI(true); recordAbortReasonHistogram(PaymentRequestMetrics.ABORT_REASON_MOJO_RENDERER_CLOSING); } @@ -898,7 +900,7 @@ public void onConnectionError(MojoException e) { if (mClient == null) return; closeClient(); - closeUI(false); + closeUI(true); recordAbortReasonHistogram(PaymentRequestMetrics.ABORT_REASON_MOJO_CONNECTION_ERROR); } @@ -1068,6 +1070,14 @@ /** * Closes the UI. If the client is still connected, then it's notified of UI hiding. + * + * @param immediateClose If true, then UI immediately closes. If false, the UI shows the error + * message "There was an error processing your order." This message + * implies that the merchant attempted to process the order, failed, and + * called complete("fail") to notify the user. Therefore, this parameter + * may be "false" only when called from + * PaymentRequestImpl.complete(int result) method. All other callers + * should always pass "true." */ private void closeUI(boolean immediateClose) { if (mUI != null) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java index 3b2e9514..763957f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/PaymentRequestUI.java
@@ -527,14 +527,12 @@ } }; - if (shouldCloseImmediately || !mIsProcessingPayClicked) { + if (shouldCloseImmediately) { // The shouldCloseImmediately boolean is true when the merchant calls // instrumentResponse.complete("success") or instrumentResponse.complete("") // in JavaScript. dismissRunnable.run(); } else { - mIsProcessingPayClicked = false; - // Animate the bottom sheet going away. new DisappearingAnimator(false); @@ -603,9 +601,11 @@ mShippingAddressSectionInformation.setSelectedItem(option); result = mClient.onSectionOptionSelected( TYPE_SHIPPING_ADDRESSES, option, mUpdateSectionsCallback); - } else if (section == mShippingOptionSection) { + } else if (section == mShippingOptionSection + && mShippingOptionsSectionInformation.getSelectedItem() != option) { mShippingOptionsSectionInformation.setSelectedItem(option); - result = mClient.onSectionOptionSelected(TYPE_SHIPPING_OPTIONS, option, null); + result = mClient.onSectionOptionSelected( + TYPE_SHIPPING_OPTIONS, option, mUpdateSectionsCallback); } else if (section == mContactDetailsSection) { mContactDetailsSectionInformation.setSelectedItem(option); result = mClient.onSectionOptionSelected(TYPE_CONTACT_DETAILS, option, null); @@ -766,6 +766,7 @@ */ public void showProcessingMessage() { assert mIsProcessingPayClicked; + mIsProcessingPayClicked = false; changeSpinnerVisibility(true); mDialog.show(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/ListUrlsActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/ListUrlsActivity.java index 3b150b8..1b04cbe1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/ListUrlsActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/ListUrlsActivity.java
@@ -9,7 +9,6 @@ import android.animation.ObjectAnimator; import android.content.Context; import android.content.Intent; -import android.content.SharedPreferences; import android.graphics.Bitmap; import android.graphics.PorterDuff; import android.graphics.drawable.AnimationDrawable; @@ -36,7 +35,9 @@ import org.chromium.chrome.browser.widget.FadingShadowView; import org.chromium.components.location.LocationUtils; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; /** * This activity displays a list of nearby URLs as stored in the {@link UrlManager}. @@ -60,8 +61,9 @@ private static final int DURATION_SLIDE_UP_MS = 250; private static final int DURATION_SLIDE_DOWN_MS = 250; + private final List<PwsResult> mPwsResults = new ArrayList<>(); + private Context mContext; - private SharedPreferences mSharedPrefs; private NearbyUrlsAdapter mAdapter; private PwsClient mPwsClient; private ListView mListView; @@ -212,16 +214,14 @@ PhysicalWebUma.onForegroundPwsResolution(ListUrlsActivity.this, duration); } - // filter out duplicate site URLs. + // filter out duplicate groups. for (PwsResult pwsResult : pwsResults) { - String siteUrl = pwsResult.siteUrl; - String iconUrl = pwsResult.iconUrl; - - if (siteUrl != null && !mAdapter.hasSiteUrl(siteUrl)) { + mPwsResults.add(pwsResult); + if (!mAdapter.hasGroupId(pwsResult.groupId)) { mAdapter.add(pwsResult); - if (iconUrl != null && !mAdapter.hasIcon(iconUrl)) { - fetchIcon(iconUrl); + if (pwsResult.iconUrl != null && !mAdapter.hasIcon(pwsResult.iconUrl)) { + fetchIcon(pwsResult.iconUrl); } } } @@ -240,8 +240,22 @@ @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { PhysicalWebUma.onUrlSelected(this); - PwsResult pwsResult = mAdapter.getItem(position); - Intent intent = createNavigateToUrlIntent(pwsResult); + PwsResult minPwsResult = mAdapter.getItem(position); + String groupId = minPwsResult.groupId; + + // Make sure the PwsResult corresponds to the closest UrlDevice in the group. + double minDistance = Double.MAX_VALUE; + for (PwsResult pwsResult : mPwsResults) { + if (pwsResult.groupId.equals(groupId)) { + double distance = UrlManager.getInstance() + .getUrlInfoByUrl(pwsResult.requestUrl).getDistance(); + if (distance < minDistance) { + minDistance = distance; + minPwsResult = pwsResult; + } + } + } + Intent intent = createNavigateToUrlIntent(minPwsResult); mContext.startActivity(intent); } @@ -289,6 +303,7 @@ (AnimationDrawable) mScanningImageView.getDrawable(); animationDrawable.start(); + mPwsResults.clear(); resolve(urls, isUserInitiated); } } @@ -350,27 +365,24 @@ } private void initSharedPreferences() { - mSharedPrefs = ContextUtils.getAppSharedPreferences(); - int prefsVersion = mSharedPrefs.getInt(PREFS_VERSION_KEY, 0); - - if (prefsVersion == PREFS_VERSION) { + if (ContextUtils.getAppSharedPreferences().getInt(PREFS_VERSION_KEY, 0) == PREFS_VERSION) { return; } // Stored preferences are old, upgrade to the current version. - SharedPreferences.Editor editor = mSharedPrefs.edit(); - editor.putInt(PREFS_VERSION_KEY, PREFS_VERSION); - editor.apply(); + ContextUtils.getAppSharedPreferences().edit() + .putInt(PREFS_VERSION_KEY, PREFS_VERSION) + .apply(); } private int getBottomBarDisplayCount() { - return mSharedPrefs.getInt(PREFS_BOTTOM_BAR_KEY, 0); + return ContextUtils.getAppSharedPreferences().getInt(PREFS_BOTTOM_BAR_KEY, 0); } private void setBottomBarDisplayCount(int count) { - SharedPreferences.Editor editor = mSharedPrefs.edit(); - editor.putInt(PREFS_BOTTOM_BAR_KEY, count); - editor.apply(); + ContextUtils.getAppSharedPreferences().edit() + .putInt(PREFS_BOTTOM_BAR_KEY, count) + .apply(); } private static Intent createNavigateToUrlIntent(PwsResult pwsResult) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/NearbyUrlsAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/NearbyUrlsAdapter.java index f01caab..0ba4b8a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/NearbyUrlsAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/NearbyUrlsAdapter.java
@@ -53,6 +53,20 @@ } /** + * Return true if we already know we have a given groupId. + * @param groupId The requested groupId + * @return true if a PwsResult is present that has the given groupId + */ + public boolean hasGroupId(String groupId) { + for (int position = 0; position < getCount(); ++position) { + if (groupId.equals(getItem(position).groupId)) { + return true; + } + } + return false; + } + + /** * Get the view for an item in the data set. * @param position Index of the list view item within the array. * @param view The old view to reuse, if possible.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/UrlManager.java b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/UrlManager.java index 09fba2d..e41132d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/UrlManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/physicalweb/UrlManager.java
@@ -238,6 +238,10 @@ return urlInfos; } + public UrlInfo getUrlInfoByUrl(String url) { + return mUrlInfoMap.get(url); + } + public Set<String> getNearbyUrls() { return mNearbyUrls; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncErrorCardPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncErrorCardPreference.java new file mode 100644 index 0000000..399fb26 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncErrorCardPreference.java
@@ -0,0 +1,41 @@ +// Copyright 2016 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.preferences; + +import android.content.Context; +import android.graphics.Typeface; +import android.preference.Preference; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.chrome.R; + +/** + * A preference that displays hint message to resolve sync error. Click of it navigates user to + * appropriate place to resolve error. + */ +public class SyncErrorCardPreference extends Preference { + /** + * Constructor for inflating from XML. + */ + public SyncErrorCardPreference(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected View onCreateView(ViewGroup parent) { + View view = super.onCreateView(parent); + TextView title = (TextView) view.findViewById(android.R.id.title); + title.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16); + title.setTypeface(Typeface.create("sans-serif-medium", Typeface.NORMAL)); + title.setTextColor(ApiCompatibilityUtils.getColor( + getContext().getResources(), R.color.input_underline_error_color)); + return view; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePermissionsFetcher.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePermissionsFetcher.java index 7fdff01..0c318b7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePermissionsFetcher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/website/WebsitePermissionsFetcher.java
@@ -146,7 +146,11 @@ } private Website findOrCreateSite(WebsiteAddress origin, WebsiteAddress embedder) { - Pair<WebsiteAddress, WebsiteAddress> key = Pair.create(origin, embedder); + // In Jelly Bean a null value triggers a NullPointerException in Pair.hashCode(). Storing + // the origin twice works around it and won't conflict with other entries as this is how the + // native code indicates to this class that embedder == origin. https://crbug.com/636330 + Pair<WebsiteAddress, WebsiteAddress> key = + Pair.create(origin, embedder == null ? origin : embedder); Website site = mSites.get(key); if (site == null) { site = new Website(origin, embedder);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java index 71020d0..21df9011 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountManagementFragment.java
@@ -29,12 +29,10 @@ import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceFragment; import android.preference.PreferenceScreen; -import android.provider.Settings; import android.text.TextUtils; import android.util.Pair; import org.chromium.base.ContextUtils; -import org.chromium.base.Log; import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeApplication; @@ -53,7 +51,6 @@ import org.chromium.chrome.browser.sync.ProfileSyncService; import org.chromium.chrome.browser.sync.ProfileSyncService.SyncStateChangedListener; import org.chromium.chrome.browser.sync.ui.SyncCustomizationFragment; -import org.chromium.components.sync.AndroidSyncSettings; import org.chromium.components.sync.signin.AccountManagerHelper; import org.chromium.components.sync.signin.ChromeSigninController; @@ -293,15 +290,9 @@ if (ProfileSyncService.get() == null) return true; - if (AndroidSyncSettings.isMasterSyncEnabled(preferences)) { - Bundle args = new Bundle(); - args.putString( - SyncCustomizationFragment.ARGUMENT_ACCOUNT, account.name); - preferences.startFragment( - SyncCustomizationFragment.class.getName(), args); - } else { - openSyncSettingsPage(preferences); - } + Bundle args = new Bundle(); + args.putString(SyncCustomizationFragment.ARGUMENT_ACCOUNT, account.name); + preferences.startFragment(SyncCustomizationFragment.class.getName(), args); return true; } @@ -408,19 +399,6 @@ } } - private void openSyncSettingsPage(Activity activity) { - // TODO(crbug/557784): This needs to actually take the user to a specific account settings - // page. There doesn't seem to be an obvious way to do that at the moment, but should update - // this when we figure that out. - Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS); - intent.putExtra(Settings.EXTRA_ACCOUNT_TYPES, new String[] {"com.google"}); - if (intent.resolveActivity(activity.getPackageManager()) == null) { - Log.w(TAG, "Unable to resolve activity for: %s", intent); - return; - } - activity.startActivity(intent); - } - private void updateAccountsList() { PreferenceScreen prefScreen = getPreferenceScreen(); if (prefScreen == null) return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java index d699656..febeedb65 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java
@@ -10,6 +10,7 @@ import android.app.FragmentTransaction; import android.content.Context; import android.content.Intent; +import android.content.res.Resources; import android.net.Uri; import android.os.Bundle; import android.os.Handler; @@ -19,6 +20,8 @@ import android.preference.Preference.OnPreferenceClickListener; import android.preference.PreferenceFragment; import android.preference.SwitchPreference; +import android.provider.Settings; +import android.support.annotation.IntDef; import android.text.Spannable; import android.text.SpannableString; import android.text.style.ForegroundColorSpan; @@ -27,6 +30,7 @@ import android.view.ViewGroup; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.Callback; import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; @@ -35,6 +39,8 @@ import org.chromium.chrome.browser.invalidation.InvalidationController; import org.chromium.chrome.browser.preferences.ChromeSwitchPreference; import org.chromium.chrome.browser.preferences.SyncedAccountPreference; +import org.chromium.chrome.browser.signin.SigninManager; +import org.chromium.chrome.browser.sync.GoogleServiceAuthError; import org.chromium.chrome.browser.sync.ProfileSyncService; import org.chromium.chrome.browser.sync.SyncAccountSwitcher; import org.chromium.components.sync.AndroidSyncSettings; @@ -42,7 +48,10 @@ import org.chromium.components.sync.PassphraseType; import org.chromium.components.sync.StopSource; import org.chromium.components.sync.signin.AccountManagerHelper; +import org.chromium.components.sync.signin.ChromeSigninController; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.HashSet; import java.util.Set; @@ -85,6 +94,17 @@ public static final String PREFERENCE_SYNC_MANAGE_DATA = "sync_manage_data"; @VisibleForTesting public static final String PREFERENCE_SYNC_ACCOUNT_LIST = "synced_account"; + public static final String PREFERENCE_SYNC_ERROR_CARD = "sync_error_card"; + + @Retention(RetentionPolicy.SOURCE) + @IntDef({SYNC_NO_ERROR, SYNC_ANDROID_SYNC_DISABLED, SYNC_AUTH_ERROR, SYNC_PASSPHRASE_REQUIRED, + SYNC_OTHER_ERRORS}) + private @interface SyncError {} + private static final int SYNC_NO_ERROR = -1; + private static final int SYNC_ANDROID_SYNC_DISABLED = 0; + private static final int SYNC_AUTH_ERROR = 1; + private static final int SYNC_PASSPHRASE_REQUIRED = 2; + private static final int SYNC_OTHER_ERRORS = 3; public static final String ARGUMENT_ACCOUNT = "account"; @@ -116,11 +136,14 @@ private CheckBoxPreference mPaymentsIntegration; private Preference mSyncEncryption; private Preference mManageSyncData; + private Preference mSyncErrorCard; private CheckBoxPreference[] mAllTypes; private SyncedAccountPreference mSyncedAccountPreference; private ProfileSyncService mProfileSyncService; + @SyncError private int mCurrentSyncError = SYNC_NO_ERROR; + @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -147,6 +170,8 @@ mSyncEncryption.setOnPreferenceClickListener(this); mManageSyncData = findPreference(PREFERENCE_SYNC_MANAGE_DATA); mManageSyncData.setOnPreferenceClickListener(this); + mSyncErrorCard = findPreference(PREFERENCE_SYNC_ERROR_CARD); + mSyncErrorCard.setOnPreferenceClickListener(this); mAllTypes = new CheckBoxPreference[] { mSyncAutofill, mSyncBookmarks, mSyncOmnibox, mSyncPasswords, @@ -325,6 +350,7 @@ updateDataTypeState(); updateEncryptionState(); updateSyncAccountsListState(); + updateSyncErrorCard(); } /** @@ -523,6 +549,9 @@ } else if (preference == mManageSyncData) { openDashboardTabInNewActivityStack(); return true; + } else if (preference == mSyncErrorCard) { + onSyncErrorCardClicked(); + return true; } return false; } @@ -594,6 +623,109 @@ } } + private void updateSyncErrorCard() { + mCurrentSyncError = getSyncError(); + if (mCurrentSyncError != SYNC_NO_ERROR) { + String summary = getSyncErrorHint(mCurrentSyncError); + mSyncErrorCard.setSummary(summary); + getPreferenceScreen().addPreference(mSyncErrorCard); + } else { + getPreferenceScreen().removePreference(mSyncErrorCard); + } + } + + @SyncError + private int getSyncError() { + if (!AndroidSyncSettings.isMasterSyncEnabled(getActivity())) { + return SYNC_ANDROID_SYNC_DISABLED; + } + + if (!mSyncSwitchPreference.isChecked()) { + return SYNC_NO_ERROR; + } + + if (mProfileSyncService.getAuthError() + == GoogleServiceAuthError.State.INVALID_GAIA_CREDENTIALS) { + return SYNC_AUTH_ERROR; + } + + if (mProfileSyncService.getAuthError() != GoogleServiceAuthError.State.NONE) { + return SYNC_OTHER_ERRORS; + } + + if (mProfileSyncService.isSyncActive() + && mProfileSyncService.isPassphraseRequiredForDecryption()) { + return SYNC_PASSPHRASE_REQUIRED; + } + + return SYNC_NO_ERROR; + } + + /** + * Gets hint message to resolve sync error. + * @param error The sync error. + */ + private String getSyncErrorHint(@SyncError int error) { + Resources res = getActivity().getResources(); + switch (error) { + case SYNC_ANDROID_SYNC_DISABLED: + return res.getString(R.string.hint_android_sync_disabled); + case SYNC_AUTH_ERROR: + return res.getString(R.string.hint_sync_auth_error); + case SYNC_OTHER_ERRORS: + return res.getString(R.string.hint_other_sync_errors); + case SYNC_PASSPHRASE_REQUIRED: + return res.getString(R.string.hint_passphrase_required); + case SYNC_NO_ERROR: + default: + return null; + } + } + + private void onSyncErrorCardClicked() { + if (mCurrentSyncError == SYNC_NO_ERROR) { + return; + } + + if (mCurrentSyncError == SYNC_ANDROID_SYNC_DISABLED) { + // TODO(crbug.com/557784): This needs to actually take the user to a specific account + // settings page. There doesn't seem to be an obvious way to do that at the moment, but + // should update this when we figure that out. + Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS); + intent.putExtra(Settings.EXTRA_ACCOUNT_TYPES, new String[] {"com.google"}); + if (intent.resolveActivity(getActivity().getPackageManager()) != null) { + getActivity().startActivity(intent); + } + return; + } + + if (mCurrentSyncError == SYNC_AUTH_ERROR) { + AccountManagerHelper.get(getActivity()) + .updateCredentials(ChromeSigninController.get(getActivity()).getSignedInUser(), + getActivity(), new Callback<Boolean>() { + @Override + public void onResult(Boolean result) {} + }); + return; + } + + if (mCurrentSyncError == SYNC_OTHER_ERRORS) { + final Account account = ChromeSigninController.get(getActivity()).getSignedInUser(); + SigninManager.get(getActivity()).signOut(new Runnable() { + @Override + public void run() { + SigninManager.get(getActivity()).signIn(account, null, null); + } + }); + return; + } + + if (mCurrentSyncError == SYNC_PASSPHRASE_REQUIRED) { + displayPassphraseDialog(); + return; + } + } + /** * Listen to sync state changes. * @@ -611,6 +743,8 @@ || mIsPassphraseRequired != wasPassphraseRequired) { // Update all because Password syncability is also affected by the backend. updateSyncStateFromSwitch(); + } else { + updateSyncErrorCard(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java index 6cb24ac..2bd6584 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -54,7 +54,6 @@ import org.chromium.chrome.browser.UrlConstants; import org.chromium.chrome.browser.WebContentsFactory; import org.chromium.chrome.browser.banners.AppBannerManager; -import org.chromium.chrome.browser.bookmarks.BookmarkUtils; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.contextmenu.ContextMenuPopulator; import org.chromium.chrome.browser.contextualsearch.ContextualSearchTabHelper; @@ -70,6 +69,7 @@ import org.chromium.chrome.browser.navigation.TabWebContentsNavigationHandler; import org.chromium.chrome.browser.ntp.NativePageAssassin; import org.chromium.chrome.browser.ntp.NativePageFactory; +import org.chromium.chrome.browser.offlinepages.OfflinePageItem; import org.chromium.chrome.browser.omnibox.geo.GeolocationHeader; import org.chromium.chrome.browser.policy.PolicyAuditor; import org.chromium.chrome.browser.prerender.ExternalPrerenderHandler; @@ -203,13 +203,13 @@ private TabContentViewParent mContentViewParent; /** A list of Tab observers. These are used to broadcast Tab events to listeners. */ - private final ObserverList<TabObserver> mObservers = new ObserverList<TabObserver>(); + private final ObserverList<TabObserver> mObservers = new ObserverList<>(); /** * A list of {@link ContentViewCore} overlay objects that are managed by external components but * need to be sized and rendered along side this {@link Tab}s content. */ - private final List<ContentViewCore> mOverlayContentViewCores = new ArrayList<ContentViewCore>(); + private final List<ContentViewCore> mOverlayContentViewCores = new ArrayList<>(); // Content layer Observers and Delegates private ContentViewClient mContentViewClient; @@ -873,12 +873,11 @@ } /** - * @return The {@link View} displaying the current page in the tab. This might be a - * native view or a placeholder view for content rendered by the compositor. - * This can be {@code null}, if the tab is frozen or being initialized or destroyed. + * @return The {@link View} displaying the current page in the tab. This can be {@code null}, if + * the tab is frozen or being initialized or destroyed. */ public View getView() { - return mNativePage != null ? mNativePage.getView() : mContentViewParent; + return mContentViewParent; } /** @@ -2884,13 +2883,6 @@ } /** - * @return Whether an offline copy of this tab's URL exists. - */ - public boolean hasOfflineCopy() { - return isFrozen() ? false : nativeHasOfflineCopy(mNativeTabAndroid); - } - - /** * @return True if the offline page is opened. */ public boolean isOfflinePage() { @@ -2898,11 +2890,10 @@ } /** - * @return Url of the original page, if tab currently displays offline copy of it, - * <code>null</code> otherwise. + * @return The offline page if tab currently displays it, null otherwise. */ - public String getOfflinePageOriginalUrl() { - return isFrozen() ? null : nativeGetOfflinePageOriginalUrl(mNativeTabAndroid); + public OfflinePageItem getOfflinePage() { + return isFrozen() ? null : nativeGetOfflinePage(mNativeTabAndroid); } /** @@ -2911,8 +2902,8 @@ */ @CalledByNative public void showOfflinePages() { - // The offline pages filter view will be loaded by default when offline. - BookmarkUtils.showBookmarkManager(getActivity()); + // TODO(jianli): This is not currently used. Figure out what to do here. + // http://crbug.com/636574 } /** @@ -2920,11 +2911,9 @@ * the original page. Otherwise return the original url from DOMDistiller. */ public String getOriginalUrl() { - if (isOfflinePage()) { - return getOfflinePageOriginalUrl(); - } else { - return DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(getUrl()); - } + OfflinePageItem offlinePage = getOfflinePage(); + if (offlinePage != null) return offlinePage.getUrl(); + return DomDistillerUrlUtils.getOriginalUrlFromDistillerUrl(getUrl()); } /** @@ -3284,9 +3273,8 @@ long nativeTabAndroid, int constraints, int current, boolean animate); private native void nativeLoadOriginalImage(long nativeTabAndroid); private native long nativeGetBookmarkId(long nativeTabAndroid, boolean onlyEditable); - private native boolean nativeHasOfflineCopy(long nativeTabAndroid); private native boolean nativeIsOfflinePage(long nativeTabAndroid); - private native String nativeGetOfflinePageOriginalUrl(long nativeTabAndroid); + private native OfflinePageItem nativeGetOfflinePage(long nativeTabAndroid); private native void nativeSetInterceptNavigationDelegate(long nativeTabAndroid, InterceptNavigationDelegate delegate); private native void nativeAttachToTabContentManager(long nativeTabAndroid,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContentViewParent.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContentViewParent.java index 865893d..d2104ad 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContentViewParent.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContentViewParent.java
@@ -7,6 +7,7 @@ import android.content.Context; import android.support.design.widget.CoordinatorLayout; import android.support.design.widget.CoordinatorLayout.Behavior; +import android.view.Gravity; import android.view.View; import android.widget.FrameLayout; @@ -43,9 +44,16 @@ } removeCurrentContent(); + LayoutParams lp = (LayoutParams) viewToShow.getLayoutParams(); + if (lp == null) { + lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); + } + // Weirdly enough, if gravity is not top, top_margin is not respected by FrameLayout. + // Yet for many native pages on tablet, top_margin is necessary to not overlap the tab + // switcher. + lp.gravity = Gravity.TOP; UiUtils.removeViewFromParent(viewToShow); - addView(viewToShow, CONTENT_INDEX, new FrameLayout.LayoutParams( - LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); + addView(viewToShow, CONTENT_INDEX, lp); viewToShow.requestFocus(); } };
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java index 1ad3f72e..9a77ec5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabContextMenuItemDelegate.java
@@ -168,7 +168,7 @@ @Override public void onSavePageLater(String linkUrl) { OfflinePageBridge bridge = OfflinePageBridge.getForProfile(mTab.getProfile()); - bridge.savePageLaterForDownload(linkUrl); + bridge.savePageLaterForDownload(linkUrl, "async_loading"); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java index fd0629e9..e41e461 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkInstaller.java
@@ -37,9 +37,6 @@ "WebAPK install failed because installation from unknown sources is disabled."); return false; } - if (!new File(filePath).exists()) { - return false; - } Intent intent = new Intent(Intent.ACTION_VIEW); Uri fileUri = Uri.fromFile(new File(filePath)); intent.setDataAndType(fileUri, "application/vnd.android.package-archive");
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectionToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectionToolbar.java index 309490fd..637b722 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectionToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectionToolbar.java
@@ -94,6 +94,7 @@ @Override protected void onFinishInflate() { + super.onFinishInflate(); mNumberRollView = (NumberRollView) findViewById(R.id.selection_mode_number); }
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd index b73ba6e..2c8008ef 100644 --- a/chrome/android/java/strings/android_chrome_strings.grd +++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -380,9 +380,6 @@ </message> <!-- Homepage preferences --> - <message name="IDS_HOMEPAGE_DEFAULT_TITLE" desc="Label for checkbox to use the default homepage"> - Default - </message> <message name="IDS_OPTIONS_HOMEPAGE_EDIT_TITLE" desc="The title of the screen that allows users to change the URL that opens when they tap on the home page button in the omnibox."> Edit home page </message> @@ -424,17 +421,11 @@ <message name="IDS_CONTEXTUAL_SEARCH_TITLE" desc="Name for the Contextual Search feature, which allows users to search for a term in a web page by tapping on it."> Touch to Search </message> - <message name="IDS_CONTEXTUAL_SEARCH_ACTION_BAR" desc="Message shown on the action bar, to invite the user to tap to search for a term."> - Search for “<ph name="SEARCH_TERM">%1$s<ex>Eiffel Tower</ex></ph>” - </message> <message name="IDS_CONTEXTUAL_SEARCH_DESCRIPTION" desc="Description for Contextual Search preference"> Learn about topics on websites without leaving the page. Touch to Search sends a word and its surrounding context to Google Search, returning definitions, pictures, search results, and other details. To adjust your search term, long press to select. To refine your search, slide the panel all the way up and touch the search box. </message> - <message name="IDS_CONTEXTUAL_SEARCH_LEARN_MORE_URL" desc="URL for learning more about Contextual Search preference" translateable="false"> - https://support.google.com/chrome/answer/95440#android - </message> <message name="IDS_CONTEXTUAL_SEARCH_SHORT_DESCRIPTION" desc="A promo message shown to users who have Touch to Search enabled to explain the new behavior and provide an option to opt out"> Touch to Search sends the selected word and the current page as context to Google Search. You can turn it off in <ph name="BEGIN_LINK"><link></ph>Settings<ph name="END_LINK"></link></ph>. </message> @@ -517,12 +508,6 @@ <message name="IDS_CLEAR_COOKIES_AND_SITE_DATA_SUMMARY" desc="A summary for the 'Cookies and site data' option in the 'Clear Browsing Data' screen, explaining that deleting cookies and site data will sign the user out of most websites."> This will sign you out of most websites. </message> - <message name="IDS_CLEAR_COOKIES_AND_SITE_DATA_SUMMARY_2" desc="A summary for the 'Cookies and site data' option in the 'Clear Browsing Data' screen, explaining that deleting cookies and site data will reset user's preferences on most websites."> - Saved preferences on sites might get deleted - </message> - <message name="IDS_CLEAR_COOKIES_NO_SIGN_OUT_SUMMARY" desc="Text at the bottom of the Clear Browsing Data dialog informing that clearing cookies wouldn't sign the user out of Google Accounts. Dialog also contains a link which opens the Account Management screen."> - You won’t be signed out of your <ph name="BEGIN_LINK"><link></ph>Google Accounts<ph name="END_LINK"></link></ph> - </message> <message name="IDS_CLEAR_PASSWORDS_TITLE" desc="Title for Clear Passwords in Clear Browsing Data preference"> Saved passwords </message> @@ -538,9 +523,6 @@ <message name="IDS_CLEAR_BROWSING_DATA_PROGRESS_MESSAGE" desc='Message on the progress dialog used when waiting for "clear browsing data" to complete.'> Please wait… </message> - <message name="IDS_CAN_NOT_CLEAR_BROWSING_HISTORY_TOAST" desc="Message on the toast explaining that child account users can not clear their browsing history."> - Browsing history can’t be cleared with accounts for kids - </message> <message name="IDS_CLEAR_BROWSING_DATA_PERIOD_TITLE" desc="Label of the dropdown that selects the time period for which browsing data will be deleted. This sentence can be followed by any option, such as 'Clear data from the past day' or 'Clear data from the past hour'."> Clear data from the </message> @@ -1002,9 +984,6 @@ <message name="IDS_SYNC_ANDROID_MASTER_SYNC_DISABLED" desc="Message to show when Android master sync flag is disabled"> Android system sync disabled </message> - <message name="IDS_SYNC_IS_ENABLED" desc="Message to show when Chrome sync is enabled"> - Sync is on - </message> <message name="IDS_SYNC_IS_DISABLED" desc="Message to show when Chrome sync is disabled"> Sync is off </message> @@ -1014,20 +993,6 @@ <message name="IDS_SYNC_SETUP_PROGRESS" desc="Message indicating that sync setup is in progress"> Setup in progress… </message> - <message name="IDS_SYNC_ACCOUNT_HEADER" desc="Header for indicating to the user which account is being used for syncing"> - Sync account - </message> - - <!-- Confirm Sync account change dialog. --> - <message name="IDS_CONFIRM_ACCOUNT_CHANGE_DIALOG_TITLE" desc="Confirm Account change dialog title. This Dialog warns the user that signing in to sync will merge all their browsing data with the new sync email account. This dialog is displayed when user signs out of sync and tries to sign in again with a different account. Dialog also contains a link which opens a new dialog to clear sync data. [CHAR-LIMIT=40]."> - Confirm Google Account - </message> - <message name="IDS_CONFIRM_ACCOUNT_CHANGE_DIALOG_MESSAGE" desc="Message to display for google account change confirmation dialog."> - <ph name="ACCOUNT_EMAIL_LAST">%1$s<ex>user@example.com</ex></ph> was signed in. Signing in with <ph name="ACCOUNT_EMAIL_NEW">%2$s<ex>user@example.com</ex></ph> will merge synced data like bookmarks between accounts. To keep information separate, clear browsing data in <ph name="BEGIN_LINK"><link></ph>settings<ph name="END_LINK"></link></ph>. - </message> - <message name="IDS_CONFIRM_ACCOUNT_CHANGE_DIALOG_SIGNIN" desc="The string used in the dialog for the button that means user has confirmed to sign in as a different user and merge information. [CHAR-LIMIT=24]"> - Sign in - </message> <!-- Legal information preferences --> <message name="IDS_LEGAL_INFORMATION_TITLE" desc="Title for legal information [CHAR-LIMIT=32]"> @@ -1069,15 +1034,6 @@ </message> <!-- Sign-in strings --> - <message name="IDS_ADD_ACCOUNT_TITLE" desc="Title for add Google account dialog [CHAR-LIMIT=40]"> - Add a Google Account - </message> - <message name="IDS_ADD_ACCOUNT_MESSAGE" desc="Message to display for add Google account dialog"> - You have not yet set up a Google Account on this device - </message> - <message name="IDS_ADD_ACCOUNT_CONTINUE" desc="Continue button for add Google account dialog [CHAR-LIMIT=20]"> - Continue - </message> <message name="IDS_SIGNOUT_TITLE" desc="Title for sign out of Chrome dialog [CHAR-LIMIT=40]"> Sign out of Chrome? </message> @@ -1302,6 +1258,23 @@ <ph name="BEGIN_LINK"><link></ph>Get help<ph name="END_LINK"></link></ph> </message> + <!-- Hint of sync error solution strings --> + <message name="IDS_SYNC_ERROR_CARD_TITLE" desc="Title of the Sync Error Card. [CHAR-LIMIT=80]"> + Sync isn't working + </message> + <message name="IDS_HINT_ANDROID_SYNC_DISABLED" desc="Hint message to resolve Android system sync is disabled error. [CHAR-LIMIT=80]"> + Open Android settings and re-enable Android system sync to start Chrome sync + </message> + <message name="IDS_HINT_SYNC_AUTH_ERROR" desc="Hint message to resolve sync auth error. [CHAR-LIMIT=80]"> + Sign in again to start sync + </message> + <message name="IDS_HINT_PASSPHRASE_REQUIRED" desc="Hint message to resolve passphrase required error. [CHAR-LIMIT=80]"> + Enter your passphrase to start sync + </message> + <message name="IDS_HINT_OTHER_SYNC_ERRORS" desc="Hint message to resolve sync errors not listed independently. [CHAR-LIMIT=80]"> + Try signing in again + </message> + <!-- Sync error strings --> <message name="IDS_SYNC_ERROR_GENERIC" desc="Sync error string for generic error. [CHAR-LIMIT=80]"> Sync error @@ -1318,20 +1291,9 @@ <message name="IDS_SYNC_ERROR_SERVICE_UNAVAILABLE" desc="Sync error string for service unavailable. [CHAR-LIMIT=80]"> The service is not available; try again later. </message> - <message name="IDS_POLICY_DIALOG_TITLE" desc="Title to show on a dialog during sign-in, indicating that the account used has policy management enabled."> - Confirm sign-in - </message> - <message name="IDS_POLICY_DIALOG_MESSAGE" desc="Message to show on a dialog during sign-in, indicating that the account used has policy management enabled."> - This account is managed by <ph name="DOMAIN_NAME">%1$s<ex>google.com</ex></ph>. - -You are signing in with a managed account and giving its administrator control over your Chrome profile. Your Chrome data will become permanently tied to this account. Disconnecting from this account will delete the local Chrome data. - </message> <message name="IDS_POLICY_DIALOG_PROCEED" desc="Label on the button to accept the policy dialog during sign-in. [CHAR-LIMIT=20]"> Accept and sign in </message> - <message name="IDS_POLICY_DIALOG_CANCEL" desc="Label on the button to reject the policy dialog during sign-in. [CHAR-LIMIT=20]"> - Cancel - </message> <message name="IDS_WIPING_PROFILE_DATA_TITLE" desc="Title for the progress dialog shown while profile data is being wiped after signing out of an enterprise account"> Clearing account data </message> @@ -1612,18 +1574,9 @@ </message> <!-- WebsiteSettingsPopup (PageInfo dialog) --> - <message name="IDS_PAGE_INFO_COPY_URL_BUTTON" desc="Text in the button that copies the URL to the clipboard."> - Copy URL - </message> <message name="IDS_PAGE_INFO_SITE_SETTINGS_BUTTON" desc="Text in the button that opens a website's Site Settings from the Page Info dialog."> Site Settings </message> - <message name="IDS_PAGE_INFO_PERMISSION_ALLOW" desc="The label used in the permissions dropdowns in the Page Info dialog on mobile for the option that grants a permission."> - Allow - </message> - <message name="IDS_PAGE_INFO_PERMISSION_BLOCK" desc="The label used in the permissions dropdowns in the Page Info dialog on mobile for the option that denies a permission."> - Block - </message> <message name="IDS_PAGE_INFO_PERMISSION_ALLOWED" desc="The label used in the Page Info dialog to describe an allowed permission. Eg: Location - Allowed"> Allowed </message> @@ -1795,8 +1748,11 @@ <message name="IDS_OPEN_DOWNLOADED_LABEL" desc="A text label on the snackbar widget to open the downloaded file."> Open </message> - <message name="IDS_DOWNLOAD_MANAGER_UI_SPACE_USED" desc="String indicating that some amount (not part of this string) of the available space on the device has already been used."> - Used of <ph name="TOTAL_SPACE">%1$s<ex>12.55 GB</ex></ph> + <message name="IDS_DOWNLOAD_MANAGER_UI_SPACE_AVAILABLE" desc="String indicating how much storage is available on the device."> + <ph name="gigabytes">%1$1.2f<ex>12.5</ex></ph> GB available + </message> + <message name="IDS_DOWNLOAD_MANAGER_UI_SPACE_USED" desc="String indicating that some amount of storage (in gigabytes or GB) space on the device has been used."> + <ph name="gigabytes">%1$1.2f<ex>0.3</ex></ph> GB used </message> <message name="IDS_DOWNLOAD_MANAGER_UI_ALL_DOWNLOADS" desc="Indicates that clicking on this button shows all of your downloads."> All downloads @@ -1851,12 +1807,6 @@ <message name="IDS_FRE_SKIP_TEXT" desc="Text for second page skip button"> No thanks </message> - <message name="IDS_FRE_DONE" desc="Button to dismiss the sign-in screen once the user is done"> - Done - </message> - <message name="IDS_FRE_SETTINGS" desc="Button that opens Chrome settings"> - Settings - </message> <message name="IDS_FRE_TOS_AND_PRIVACY" desc="Message explaining that use of Chrome is governed by Chrome's terms of service and privacy notice."> By using this application, you agree to Chrome’s <ph name="BEGIN_LINK1"><LINK1></ph>Terms of Service<ph name="END_LINK1"></LINK1></ph> and <ph name="BEGIN_LINK2"><LINK2></ph>Privacy Notice<ph name="END_LINK2"></LINK2></ph>. </message> @@ -1874,9 +1824,6 @@ </message> <!-- Account Signin Strings --> - <message name="IDS_SIGNIN_SET_UP_CHROME" desc="Header text shown when the user is first setting up Chrome"> - Set up Chrome - </message> <message name="IDS_CHOOSE_ACCOUNT_SIGN_IN" desc="Sign in button for choose google account dialog [CHAR-LIMIT=20]"> Sign in </message> @@ -1898,9 +1845,6 @@ <message name="IDS_SIGNIN_OPEN_SETTINGS_ACCOUNTS" desc="Text for button to open Accounts page in device's Settings app"> Open settings </message> - <message name="IDS_MAKE_CHROME_YOURS" desc="Title for the signin promo that prompts the user to sign in to Chrome to have a personalized experirence. [CHAR-LIMIT=24]"> - Make Chrome yours - </message> <message name="IDS_SIGNIN_HI_NAME" desc="Title welcoming the user by their name after they have signed in."> Hi, <ph name="FULL_NAME">%1$s<ex>John Smith</ex></ph> </message> @@ -1919,44 +1863,13 @@ Warning </message> - <message name="IDS_CAST_NOTIFICATION_STOPPED" desc="AtHome notification text when stopped. [CHAR LIMIT=40]"> - Stopped - </message> - <message name="IDS_CAST_NOTIFICATION_FINISHED" desc="AtHome notification text when finished. [CHAR LIMIT=40]"> - Finished - </message> - <message name="IDS_CAST_NOTIFICATION_PAUSED" desc="AtHome notification text when paused. [CHAR LIMIT=40]"> - Paused - </message> - <!-- Messages for remote media playback (casting) --> - <message name="IDS_CAST_NOTIFICATION_LOADING" desc="AtHome notification text when loading a video. [CHAR LIMIT=40]"> - Loading video - </message> - <message name="IDS_CAST_NOTIFICATION_PLAYING" desc="AtHome notification text when playing a video. [CHAR LIMIT=40]"> - Playing video - </message> - <message name="IDS_CAST_NOTIFICATION_LOADING_FOR_VIDEO" desc="AtHome notification text when loading a given video. [CHAR LIMIT=40]"> - Loading “<ph name="VIDEO_TITLE">%1$s<ex>Psy - Gangnam Style - YouTube</ex></ph>” - </message> - <message name="IDS_CAST_NOTIFICATION_PLAYING_FOR_VIDEO" desc="AtHome notification text when playing a given video. [CHAR LIMIT=40]"> - Playing “<ph name="VIDEO_TITLE">%1$s<ex>Psy - Gangnam Style - YouTube</ex></ph>” - </message> - <message name="IDS_CAST_NOTIFICATION_PAUSED_FOR_VIDEO" desc="AtHome notification text when paused in a given video. [CHAR LIMIT=40]"> - Paused “<ph name="VIDEO_TITLE">%1$s<ex>Psy - Gangnam Style - YouTube</ex></ph>” - </message> - <message name="IDS_CAST_NOTIFICATION_FINISHED_FOR_VIDEO" desc="AtHome notification text when finished playing a given video. [CHAR LIMIT=40]"> - Finished “<ph name="VIDEO_TITLE">%1$s<ex>Psy - Gangnam Style - YouTube</ex></ph>” - </message> <message name="IDS_CAST_CASTING_VIDEO" desc="AtHome text to tell user which screen casting is happening. [CHAR LIMIT=40]"> Casting to <ph name="SCREEN_NAME">%1$s<ex>Living Room TV</ex></ph> </message> <message name="IDS_CAST_ERROR_PLAYING_VIDEO" desc="The message shown to the user when playing a video to the Chromecast fails."> Cannot play video on <ph name="SCREEN_NAME">%1$s<ex>Living Room TV</ex></ph>. </message> - <message name="IDS_CAST_PERMISSION_ERROR_PLAYING_VIDEO" desc="The message shown to the user when trying to play a video that the domain does not let us cast."> - Unable to cast video due to site restrictions - </message> <message name="IDS_ACCESSIBILITY_PLAY" desc="Content description for the play button that starts playing the media."> Play </message> @@ -1971,12 +1884,6 @@ <message name="IDS_NTP_BOOKMARKS" desc="Text for bookmarks button [CHAR-LIMIT=20]"> Bookmarks </message> - <message name="IDS_NTP_INTERESTS" desc="Text for a button to display interests. Interests are topics that we think the user is interested in (eg. sports teams, hobbies, places). [CHAR-LIMIT=20]"> - Interests - </message> - <message name="IDS_NTP_NO_INTERESTS_TOAST" desc="Toast notification displayed when interests retrieval fails"> - Could not retrieve interests. - </message> <message name="IDS_RECENT_TABS" desc="Text for button to show 'Recent tabs', i.e. recently closed tabs and tabs that are open on other devices [CHAR-LIMIT=20]"> Recent tabs </message> @@ -1989,6 +1896,9 @@ <message name="IDS_MOST_VISITED_ITEM_REMOVED" desc="Text shown when the user removes one of the most visited websites on the new tab page."> Item removed </message> + <message name="IDS_NTP_ACCESSIBILITY_ITEM_REMOVED" desc="Text announced for accessibility when the user removes an item from the new tab page e.g. by swiping it away or using the context menu."> + Item removed: <ph name="ITEM_TITLE">%1$s<ex>Prime minister announces new health care plans</ex></ph> + </message> <message name="IDS_ACCESSIBILITY_GOOGLE_DOODLE" desc="Content description for the Google Doodle (the fun, alternative Google logo) shown on the new tab page."> Google doodle: <ph name="DOODLE_DESCRIPTION">%1$s<ex>Einstein’s birthday</ex></ph> </message> @@ -2037,36 +1947,12 @@ <message name="IDS_REMOVE_ALL" desc="Context menu option to clear the list of recently closed tabs"> Remove all </message> - <message name="IDS_SNIPPETS_HEADER" desc="Header for a group of content snippets"> - Articles for you - </message> <message name="IDS_NTP_STATUS_CARD_TITLE_EMPTY" desc="Title of the card explaining the status of the ntp suggested content, when we don't have anything to show."> All Read </message> <message name="IDS_NTP_STATUS_CARD_BODY_EMPTY" desc="Body of the card explaining the status of the ntp suggested content, when we don't have anything to show."> More cards will appear when the time is right. </message> - <message name="IDS_NTP_STATUS_CARD_BODY_SIGNED_OUT" desc="Body of the card explaining the status of the ntp suggested content, when sync is disabled."> - To get personalized content suggested by Google, sign in to Chrome. - </message> - <message name="IDS_NTP_STATUS_CARD_GENERIC_TITLE" desc="Title of the card explaining what action the user can take to get suggested content on the NTP."> - Get suggested content - </message> - <message name="IDS_NTP_STATUS_CARD_BODY_SYNC" desc="Body of the card explaining the status of the ntp suggested content, when sync is disabled."> - To get personalized content suggested by Google, turn on sync. - </message> - <message name="IDS_NTP_STATUS_CARD_ACTION_SYNC" desc="Label of the action button for the card explaining the status of the ntp suggested content, when sync is disabled."> - Turn on sync - </message> - <message name="IDS_NTP_STATUS_CARD_BODY_HISTORY_SYNC" desc="Body of the card explaining the status of the ntp suggested content, when history sync is disabled."> - To get personalized content suggested by Google, turn on history sync. - </message> - <message name="IDS_NTP_STATUS_CARD_ACTION_HISTORY_SYNC" desc="Label of the action button for the card explaining the status of the ntp suggested content, when history sync is disabled."> - Turn on history sync - </message> - <message name="IDS_NTP_STATUS_CARD_BODY_PASSPHRASE" desc="Body of the card explaining the status of the ntp suggested content, when passphrase encryption is enabled."> - Personalized content suggestions are currently disabled, because your synced data is protected with a custom passphrase. - </message> <!-- Toolbar button strings --> <message name="IDS_OPEN_TABS" desc="Text for button to enter the tab switcher and show tabs that are open on this device"> @@ -2360,9 +2246,6 @@ <message name="IDS_ACCESSIBILITY_NTP_TOOLBAR_BTN_BOOKMARKS" desc="Content description for the bookmarks tab of the new tab page."> Bookmarks </message> - <message name="IDS_ACCESSIBILITY_NTP_TOOLBAR_BTN_INTERESTS" desc="Content description for the interests section of the new tab page."> - Interests - </message> <message name="IDS_ACCESSIBILITY_NTP_TOOLBAR_BTN_RECENT_TABS" desc="Content description for the recent tabs section of the new tab page."> Recent tabs </message> @@ -2372,15 +2255,6 @@ <message name="IDS_ACCESSIBILITY_BOOKMARK_MORE_INFO" desc="Content description for the button that shows option menu for a bookmark."> Options </message> - <message name="IDS_ACCESSIBILITY_BOOKMARK_DETAIL_CLOSE_BTN" desc="Content description for the close button that allows users to close the edit bookmark dialog."> - Close dialog - </message> - <message name="IDS_ACCESSIBILITY_BOOKMARK_DETAIL_DELETE_BTN" desc="Content description for the delete button that allows users to delete the current bookmark."> - Delete bookmark - </message> - <message name="IDS_ACCESSIBILITY_BOOKMARK_DETAIL_SAVE_BTN" desc="Content description for the save button that allows users to save the edited bookmark."> - Save bookmark - </message> <message name="IDS_ACCESSIBILITY_CANCEL_SELECTION" desc="Content description for the cancel selection button that deselects the selected items in a selectable list view."> Cancel selection </message> @@ -2511,9 +2385,6 @@ <message name="IDS_STORAGE_MANAGEMENT_ALL_STORAGE_DESCRIPTION" desc="Text used to describe all storage space used by Chrome."> Total data used by Chrome, including accounts, bookmarks, and saved settings </message> - <message name="IDS_STORAGE_MANAGEMENT_TOTAL_SIZE_LABEL" desc="The total amount of storage space used (followed by a number of megabytes). [CHAR LIMIT=25]"> - Total Storage - </message> <message name="IDS_STORAGE_MANAGEMENT_CLEAR_ALL_DATA_BUTTON" desc="Text on the button to clear all Chrome data. [CHAR LIMIT=30]"> Clear All Data </message> @@ -2651,12 +2522,6 @@ <message name="IDS_PAYMENTS_LOADING_MESSAGE" desc="The text that informs the user that payment information is being loaded up."> Loading </message> - <message name="IDS_PAYMENTS_PROCESSING_MESSAGE" desc="The text that informs the user that the payment is being verified and charged."> - Processing - </message> - <message name="IDS_PAYMENTS_SUCCESS_MESSAGE" desc="The text that informs the user that the payment has been verified and charged."> - Payment processed - </message> <message name="IDS_PAYMENTS_ERROR_MESSAGE" desc="The text that informs the user that there is error in verifying and charging the payment."> There was an error processing your order. Please check your account and try again. </message>
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 64afd91..5d3cf69 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -536,6 +536,7 @@ "java/src/org/chromium/chrome/browser/ntp/RecentlyClosedBridge.java", "java/src/org/chromium/chrome/browser/ntp/TitleUtil.java", "java/src/org/chromium/chrome/browser/ntp/UiConfig.java", + "java/src/org/chromium/chrome/browser/ntp/snippets/CategoryInt.java", "java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleListItem.java", "java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java", "java/src/org/chromium/chrome/browser/ntp/snippets/SnippetHeaderListItem.java", @@ -715,6 +716,7 @@ "java/src/org/chromium/chrome/browser/preferences/SeekBarPreference.java", "java/src/org/chromium/chrome/browser/preferences/SignInPreference.java", "java/src/org/chromium/chrome/browser/preferences/SpinnerPreference.java", + "java/src/org/chromium/chrome/browser/preferences/SyncErrorCardPreference.java", "java/src/org/chromium/chrome/browser/preferences/SyncPreference.java", "java/src/org/chromium/chrome/browser/preferences/SyncedAccountPreference.java", "java/src/org/chromium/chrome/browser/preferences/TextAndButtonPreference.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerIntegrationTest.java index 575e80b..7c89fb0 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/BindingManagerIntegrationTest.java
@@ -252,7 +252,7 @@ * crashed in background is restored in foreground. This is a regression test for * http://crbug.com/399521. */ - @DisabledTest // Flaked on the try bot: http://crbug.com/543153 + @DisabledTest(message = "crbug.com/543153") @LargeTest @Feature({"ProcessManagement"}) public void testCrashInBackground() throws InterruptedException {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/FocusedEditableTextFieldZoomTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/FocusedEditableTextFieldZoomTest.java index e06964f..b4627e3 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/FocusedEditableTextFieldZoomTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/FocusedEditableTextFieldZoomTest.java
@@ -72,12 +72,11 @@ }, TEST_TIMEOUT, DEFAULT_POLLING_INTERVAL); } - @DisabledTest - @Feature({"TabContents"}) /* * @LargeTest - * Broken by subpixel precision changes crbug.com/371119 */ + @DisabledTest(message = "Broken by subpixel precision changes crbug.com/371119") + @Feature({"TabContents"}) public void testZoomInToSelected() throws Throwable { // This should focus the text field and initiate a zoom in. Tab tab = getActivity().getActivityTab(); @@ -90,12 +89,11 @@ waitForZoomIn(contentViewCore, initialZoomLevel); } - @DisabledTest - @Feature({"TabContents"}) /* * @LargeTest - * Broken by subpixel precision changes crbug.com/371119 */ + @DisabledTest(message = "Broken by subpixel precision changes crbug.com/371119") + @Feature({"TabContents"}) public void testZoomOutOfSelectedIfOnlyBackPressed() throws Throwable { final Tab tab = getActivity().getActivityTab(); final ContentViewCore contentViewCore = tab.getContentViewCore();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java index 7500681..6735896 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/NavigateTest.java
@@ -150,7 +150,7 @@ assertEquals(expectedLocation(url), result); } - @DisabledTest // https://crbug.com/516018 + @DisabledTest(message = "crbug.com/516018") @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @MediumTest @Feature({"Navigation"})
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/PrerenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/PrerenderTest.java index bf1c479..23e02af 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/PrerenderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/PrerenderTest.java
@@ -49,7 +49,7 @@ /** * We are using Autocomplete Action Predictor to decide whether or not to prerender. - /* Without any training data the default action should be no-prerender. + * Without any training data the default action should be no-prerender. */ @LargeTest @Restriction({RESTRICTION_TYPE_NON_LOW_END_DEVICE}) @@ -127,7 +127,7 @@ @Restriction({RESTRICTION_TYPE_NON_LOW_END_DEVICE}) @Feature({"TabContents"}) */ - @DisabledTest // Prerenderer disables infobars. crbug.com/588808 + @DisabledTest(message = "Prerenderer disables infobars. crbug.com/588808") public void testInfoBarDismissed() throws InterruptedException { final String url = mTestServer.getURL( "/chrome/test/data/geolocation/geolocation_on_load.html");
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java index 5087cf6..3e02c507 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/TabsTest.java
@@ -578,9 +578,8 @@ /* @LargeTest @Feature({"Android-TabSwitcher"}) - Bug http://crbug.com/156746 */ - @DisabledTest + @DisabledTest(message = "crbug.com/156746") @Restriction({ChromeRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE}) public void testTabsCulling() throws InterruptedException { // Open one more tabs than maxTabsDrawn. @@ -1085,10 +1084,9 @@ /* @MediumTest @Feature({"Android-TabSwitcher"}) - Bug http://crbug.com/157259 */ @Restriction({ChromeRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE}) - @DisabledTest + @DisabledTest(message = "crbug.com/157259") public void testSwitchTabStackWithoutClosingTabsInLandscape() throws InterruptedException { getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); newIncognitoTabFromMenu();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/AppMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/AppMenuTest.java index 30c5f71..f163b8df 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/AppMenuTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/appmenu/AppMenuTest.java
@@ -194,9 +194,8 @@ /* @SmallTest @Feature({"Browser", "Main"}) - crbug.com/458193 */ - @DisabledTest + @DisabledTest(message = "crbug.com/458193") public void testChangingOrientationHidesMenu() throws InterruptedException { getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); showAppMenuAndAssertMenuShown();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTest.java index 8bef8bb18..283f0103d6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/AutofillTest.java
@@ -51,10 +51,11 @@ public void setUp() throws Exception { super.setUp(); - final ChromeActivity activity = getActivity(); mMockAutofillCallback = new MockAutofillCallback(); + final ChromeActivity activity = getActivity(); final ViewAndroidDelegate viewDelegate = - activity.getCurrentContentViewCore().getViewAndroidDelegate(); + ViewAndroidDelegate.createBasicDelegate( + activity.getCurrentContentViewCore().getContainerView()); ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/BrowsingDataRemoverIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/BrowsingDataRemoverIntegrationTest.java index 5073e6a..c9b0a44 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/BrowsingDataRemoverIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browsing_data/BrowsingDataRemoverIntegrationTest.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.browsing_data; +import android.content.Intent; +import android.os.AsyncTask; import android.test.suitebuilder.annotation.MediumTest; import org.chromium.base.ThreadUtils; @@ -57,6 +59,27 @@ startMainActivityOnBlankPage(); } + private void registerWebapp(final String webappId, final String webappUrl) throws Exception { + AsyncTask<Void, Void, Intent> shortcutIntentTask = new AsyncTask<Void, Void, Intent>() { + @Override + protected Intent doInBackground(Void... nothing) { + return ShortcutHelper.createWebappShortcutIntentForTesting(webappId, webappUrl); + } + }; + final Intent shortcutIntent = shortcutIntentTask.execute().get(); + + WebappRegistry.registerWebapp( + getActivity(), webappId, new WebappRegistry.FetchWebappDataStorageCallback() { + @Override + public void onWebappDataStorageRetrieved(WebappDataStorage storage) { + storage.updateFromShortcutIntent(shortcutIntent); + mCallbackCalled = true; + } + }); + + CriteriaHelper.pollUiThread(new CallbackCriteria()); + } + /** * Tests that web apps are unregistered after clearing with the "cookies and site data" option. * TODO(msramek): Expose more granular datatypes to the Java code, so we can directly test @@ -71,21 +94,7 @@ apps.put("webapp3", "http://example.com/"); for (final Map.Entry<String, String> app : apps.entrySet()) { - WebappRegistry.registerWebapp(getActivity(), app.getKey(), - new WebappRegistry.FetchWebappDataStorageCallback() { - @Override - public void onWebappDataStorageRetrieved(WebappDataStorage storage) { - storage.updateFromShortcutIntent( - ShortcutHelper.createWebappShortcutIntent( - app.getKey(), "", app.getValue(), "", "", "", null, - ShortcutHelper.WEBAPP_SHORTCUT_VERSION, 0, 0, 0, 0, - false)); - mCallbackCalled = true; - } - } - ); - - CriteriaHelper.pollUiThread(new CallbackCriteria()); + registerWebapp(app.getKey(), app.getValue()); } // Wait for the registration to finish.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java index d3327d6..c54eeaf 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java
@@ -8,7 +8,6 @@ import android.test.suitebuilder.annotation.LargeTest; import org.chromium.base.ThreadUtils; -import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.FlakyTest; import org.chromium.base.test.util.Restriction; @@ -29,6 +28,8 @@ import org.chromium.ui.UiUtils; import org.chromium.ui.base.LocalizationUtils; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; /** @@ -44,12 +45,11 @@ /** * Tests that the initial state of the system is good. This is so the default TabStrips match * the TabModels and we do not have to test this in further tests. - * @throws InterruptedException */ @LargeTest @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @Feature({"TabStrip"}) - public void testInitialState() throws InterruptedException { + public void testInitialState() throws Exception { getInstrumentation().waitForIdleSync(); compareAllTabStripsWithModel(); } @@ -57,12 +57,11 @@ /** * Tests that pressing the new tab button creates a new tab, properly updating the selected * index. - * @throws InterruptedException */ @LargeTest @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @Feature({"TabStrip", "Main"}) - public void testNewTabButtonWithOneTab() throws InterruptedException { + public void testNewTabButtonWithOneTab() throws Exception { getInstrumentation().waitForIdleSync(); assertEquals("Expected original tab to be selected", getActivity().getTabModelSelector().getModel(false).index(), 0); @@ -80,13 +79,12 @@ /** * Tests that pressing the new tab button creates a new tab when many exist, properly updating * the selected index. - * @throws InterruptedException */ @LargeTest @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @Feature({"TabStrip"}) @FlakyTest(message = "crbug.com/592961") - public void testNewTabButtonWithManyTabs() throws InterruptedException { + public void testNewTabButtonWithManyTabs() throws Exception { ChromeTabUtils.newTabsFromMenu(getInstrumentation(), getActivity(), 3); getInstrumentation().runOnMainSync(new Runnable() { @Override @@ -111,12 +109,11 @@ /** * Tests that creating a new tab from the menu properly updates the TabStrip. - * @throws InterruptedException */ @LargeTest @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @Feature({"TabStrip"}) - public void testNewTabFromMenu() throws InterruptedException { + public void testNewTabFromMenu() throws Exception { getInstrumentation().waitForIdleSync(); compareAllTabStripsWithModel(); ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity()); @@ -129,12 +126,11 @@ /** * Tests that creating a new incognito from the menu properly updates the TabStrips and * activates the incognito TabStrip. - * @throws InterruptedException */ @LargeTest @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @Feature({"TabStrip"}) - public void testNewIncognitoTabFromMenuAtNormalStrip() throws InterruptedException { + public void testNewIncognitoTabFromMenuAtNormalStrip() throws Exception { getInstrumentation().waitForIdleSync(); assertFalse("Expected normal strip to be selected", getActivity().getTabModelSelector().isIncognitoSelected()); @@ -151,12 +147,11 @@ /** * Tests that selecting a tab properly selects the new tab. - * @throws InterruptedException */ @LargeTest @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @Feature({"TabStrip"}) - public void testSelectWithTwoTabs() throws InterruptedException { + public void testSelectWithTwoTabs() throws Exception { ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity()); getInstrumentation().waitForIdleSync(); assertEquals("The second tab is not selected", @@ -171,12 +166,11 @@ /** * Tests that selecting a tab properly selects the new tab with many present. This lets us * also check that the visible tab ordering is correct. - * @throws InterruptedException */ @LargeTest @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @Feature({"TabStrip"}) - public void testSelectWithManyTabs() throws InterruptedException { + public void testSelectWithManyTabs() throws Exception { ChromeTabUtils.newTabsFromMenu(getInstrumentation(), getActivity(), 4); getInstrumentation().waitForIdleSync(); assertEquals("The last tab is not selected", @@ -194,12 +188,11 @@ /** * Tests closing a tab when there are two tabs open. The remaining tab should still be * selected. - * @throws InterruptedException */ @LargeTest @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @Feature({"TabStrip"}) - public void testCloseTabWithTwoTabs() throws InterruptedException { + public void testCloseTabWithTwoTabs() throws Exception { ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity()); getInstrumentation().waitForIdleSync(); assertEquals("There are not two tabs present", @@ -221,12 +214,11 @@ /** * Tests closing a tab when there are many tabs open. The remaining tab should still be * selected, even if the index has changed. - * @throws InterruptedException */ @LargeTest @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @Feature({"TabStrip"}) - public void testCloseTabWithManyTabs() throws InterruptedException { + public void testCloseTabWithManyTabs() throws Exception { ChromeTabUtils.newTabsFromMenu(getInstrumentation(), getActivity(), 4); getInstrumentation().waitForIdleSync(); assertEquals("There are not five tabs present", @@ -250,12 +242,11 @@ /** * Tests that closing the selected tab properly closes the current tab and updates to a new * selected tab. - * @throws InterruptedException */ @LargeTest @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @Feature({"TabStrip"}) - public void testCloseSelectedTab() throws InterruptedException { + public void testCloseSelectedTab() throws Exception { ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity()); getInstrumentation().waitForIdleSync(); assertEquals("There are not two tabs present", @@ -277,12 +268,11 @@ /** * Tests that selecting "Close all tabs" from the tab menu closes all tabs. * Also tests that long press on close button selects the tab and displays the menu. - * @throws InterruptedException */ @LargeTest @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @Feature({"TabStrip"}) - public void testCloseAllTabsFromTabMenuClosesAllTabs() throws InterruptedException { + public void testCloseAllTabsFromTabMenuClosesAllTabs() throws Exception { // 1. Create a second tab ChromeTabUtils.newTabFromMenu(getInstrumentation(), getActivity()); getInstrumentation().waitForIdleSync(); @@ -319,12 +309,11 @@ /** * Tests that the tab menu is dismissed when the orientation changes and no tabs * are closed. - * @throws InterruptedException */ @LargeTest @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @Feature({"TabStrip"}) - public void testTabMenuDismissedOnOrientationChange() throws InterruptedException { + public void testTabMenuDismissedOnOrientationChange() throws Exception { // 1. Set orientation to portrait getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); getInstrumentation().waitForIdleSync(); @@ -349,13 +338,12 @@ /** * Tests that pressing the incognito toggle button properly switches between the incognito * and normal TabStrips. - * @throws InterruptedException */ @LargeTest @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @Feature({"TabStrip"}) - public void testToggleIncognitoMode() throws InterruptedException { + public void testToggleIncognitoMode() throws Exception { getInstrumentation().waitForIdleSync(); assertFalse("Expected normal strip to be selected", getActivity().getTabModelSelector().isIncognitoSelected()); @@ -378,12 +366,11 @@ /** * Tests that closing the last incognito tab properly closes the incognito TabStrip and * switches to the normal TabStrip. - * @throws InterruptedException */ @LargeTest @Feature({"TabStrip"}) @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) - public void testCloseLastIncognitoTab() throws InterruptedException { + public void testCloseLastIncognitoTab() throws Exception { getInstrumentation().waitForIdleSync(); assertFalse("Expected normal strip to be selected", getActivity().getTabModelSelector().isIncognitoSelected()); @@ -403,12 +390,11 @@ /** * Tests that closing all incognito tab properly closes the incognito TabStrip and * switches to the normal TabStrip. - * @throws InterruptedException */ @LargeTest @Feature({"TabStrip"}) @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) - public void testCloseAllIncognitoTabsFromTabMenu() throws InterruptedException { + public void testCloseAllIncognitoTabsFromTabMenu() throws Exception { //1. Create two incognito tabs getInstrumentation().waitForIdleSync(); assertFalse("Expected normal strip to be selected", @@ -449,12 +435,11 @@ /** * Test that switching a tab and quickly changing the model stays on the correct new tab/model * when the tab finishes loading (when the GL overlay goes away). - * @throws InterruptedException */ @LargeTest @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @Feature({"TabStrip"}) - public void testTabSelectionViewDoesNotBreakModelSwitch() throws InterruptedException { + public void testTabSelectionViewDoesNotBreakModelSwitch() throws Exception { getInstrumentation().waitForIdleSync(); assertFalse("Expected normal strip to be selected", getActivity().getTabModelSelector().isIncognitoSelected()); @@ -481,7 +466,7 @@ @LargeTest @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @Feature({"TabStrip"}) - public void testSwitchStripStackersWithIncognito() throws InterruptedException { + public void testSwitchStripStackersWithIncognito() throws Exception { // Open an incognito tab to switch to the incognito model. newIncognitoTabFromMenu(); @@ -499,15 +484,24 @@ model.getTabAt(10).getId()); assertTabVisibility(false, tab); + // Create visibility callback helper. + final CallbackHelper helper = new CallbackHelper(); + tab.addObserver(new StripLayoutTab.Observer() { + @Override + public void onVisibilityChanged(boolean visible) { + // Notify the callback when tab becomes visible. + if (visible) helper.notifyCalled(); + } + }); + // Open another incognito tab to switch to the incognito model. newIncognitoTabFromMenu(); // Switch tab models to switch back to the regular tab strip. clickIncognitoToggleButton(); - getInstrumentation().waitForIdleSync(); - // Assert selected tab is visible. - assertTabVisibility(true, tab); + // Wait for selected tab to be visible. + helper.waitForCallback(0); // Switch to the CascadingStripStacker. setShouldCascadeTabsAndCheckTabStrips(true); @@ -521,7 +515,7 @@ @LargeTest @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @Feature({"TabStrip"}) - public void testSwitchStripStackersWithLastTabSelected() throws InterruptedException { + public void testSwitchStripStackersWithLastTabSelected() throws Exception { // Open enough regular tabs to cause the tabs to cascade or the strip to scroll depending // on which stacker is being used. ChromeTabUtils.newTabsFromMenu(getInstrumentation(), getActivity(), 10); @@ -541,7 +535,7 @@ @LargeTest @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @Feature({"TabStrip"}) - public void testSwitchStripStackersWithFirstTabSelected() throws InterruptedException { + public void testSwitchStripStackersWithFirstTabSelected() throws Exception { // Open enough regular tabs to cause the tabs to cascade or the strip to scroll depending // on which stacker is being used. ChromeTabUtils.newTabsFromMenu(getInstrumentation(), getActivity(), 10); @@ -575,7 +569,7 @@ @LargeTest @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @Feature({"TabStrip"}) - public void testSwitchStripStackersWithMiddleTabSelected() throws InterruptedException { + public void testSwitchStripStackersWithMiddleTabSelected() throws Exception { // Open enough regular tabs to cause the tabs to cascade or the strip to scroll depending // on which stacker is being used. ChromeTabUtils.newTabsFromMenu(getInstrumentation(), getActivity(), 10); @@ -599,7 +593,7 @@ @LargeTest @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @Feature({"TabStrip"}) - public void testScrollingStripStackerFadeOpacity() throws InterruptedException { + public void testScrollingStripStackerFadeOpacity() throws Exception { // Switch to the ScrollingStripStacker. setShouldCascadeTabsAndCheckTabStrips(false); @@ -637,11 +631,10 @@ * Test that selecting a tab that isn't currently visible causes the ScrollingStripStacker * to scroll to make it visible. */ - @DisabledTest(message = "crbug.com/635903") @LargeTest @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) @Feature({"TabStrip"}) - public void testScrollingStripStackerScrollsToSelectedTab() throws InterruptedException { + public void testScrollingStripStackerScrollsToSelectedTab() throws Exception { // Switch to the ScrollingStripStacker. setShouldCascadeTabsAndCheckTabStrips(false); @@ -650,16 +643,98 @@ // Get tab at index 0 and assert it is not visible. TabModel model = getActivity().getTabModelSelector().getModel(false); - StripLayoutTab tab = TabStripUtils.findStripLayoutTab(getActivity(), false, + final StripLayoutTab tab = TabStripUtils.findStripLayoutTab(getActivity(), false, model.getTabAt(0).getId()); assertTabVisibility(false, tab); + // Create visibility callback helper. + final CallbackHelper helper = new CallbackHelper(); + tab.addObserver(new StripLayoutTab.Observer() { + @Override + public void onVisibilityChanged(boolean visible) { + // Notify the helper when tab becomes visible. + if (visible) helper.notifyCalled(); + } + }); + // Select tab 0. ChromeTabUtils.switchTabInCurrentTabModel(getActivity(), 0); - getInstrumentation().waitForIdleSync(); // Tab should now be visible. - assertTabVisibility(true, tab); + helper.waitForCallback(0); + } + + /** + * Test that the draw positions for tabs match expectations at various scroll positions + * when using the ScrollingStripStacker. + */ + @LargeTest + @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) + @Feature({"TabStrip"}) + public void testScrollingStripStackerTabOffsets() throws Exception { + // Switch to the ScrollingStripStacker. + setShouldCascadeTabsAndCheckTabStrips(false); + + // Open enough regular tabs to cause the strip to scroll and select the first tab. + ChromeTabUtils.newTabsFromMenu(getInstrumentation(), getActivity(), 10); + + // Set up some variables. + StripLayoutHelper strip = TabStripUtils.getActiveStripLayoutHelper(getActivity()); + StripLayoutTab[] tabs = strip.getStripLayoutTabs(); + float tabDrawWidth = tabs[0].getWidth() - strip.getTabOverlapWidth(); + + // Disable animations. The animation that normally runs when scrolling the tab strip makes + // this test flaky. + strip.disableAnimationsForTesting(); + + // Create callback helper to be notified when first tab becomes visible. + final CallbackHelper visibleHelper = new CallbackHelper(); + tabs[0].addObserver(new StripLayoutTab.Observer() { + @Override + public void onVisibilityChanged(boolean visible) { + if (visible) visibleHelper.notifyCalled(); + } + }); + + // Switch to the first tab and wait until it's visible. + ChromeTabUtils.switchTabInCurrentTabModel(getActivity(), 0); + visibleHelper.waitForCallback(0); + + // Check initial model validity. + compareAllTabStripsWithModel(); + + // Assert getStripLayoutTabs() returns the expected number of tabs. + assertEquals("Unexpected number of StripLayoutTabs.", 11, tabs.length); + + // Create callback helper to be notified when first tab is no longer visible. + final CallbackHelper notVisibleHelper = new CallbackHelper(); + tabs[0].addObserver(new StripLayoutTab.Observer() { + @Override + public void onVisibilityChanged(boolean visible) { + if (!visible) notVisibleHelper.notifyCalled(); + } + }); + + // Scroll tab strip to 0 and check tab positions. + assertSetTabStripScrollOffset(0); + for (int i = 0; i < tabs.length; i++) { + assertTabDrawX(i * tabDrawWidth, tabs[i], i); + } + + // Scroll tab strip a little and check tab draw positions. + assertSetTabStripScrollOffset(-25); + for (int i = 0; i < tabs.length; i++) { + assertTabDrawX(i * tabDrawWidth - 25.f, tabs[i], i); + } + + // Scroll tab strip a lot and check tab draw positions. + assertSetTabStripScrollOffset(-500); + for (int i = 0; i < tabs.length; i++) { + assertTabDrawX(i * tabDrawWidth - 500.f, tabs[i], i); + } + + // Wait for the first tab in the strip to no longer be visible. + notVisibleHelper.waitForCallback(0); } /** @@ -686,53 +761,6 @@ } /** - * Test that the draw positions for tabs match expectations at various scroll positions - * when using the ScrollingStripStacker. - */ - @LargeTest - @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET) - @Feature({"TabStrip"}) - public void testScrollingStripStackerTabOffsets() throws InterruptedException { - // Switch to the ScrollingStripStacker. - setShouldCascadeTabsAndCheckTabStrips(false); - - // Open enough regular tabs to cause the strip to scroll and select the first tab. - ChromeTabUtils.newTabsFromMenu(getInstrumentation(), getActivity(), 10); - ChromeTabUtils.switchTabInCurrentTabModel(getActivity(), 0); - getInstrumentation().waitForIdleSync(); - - // Check initial model validity. - compareAllTabStripsWithModel(); - - // Set up some variables. - StripLayoutHelper strip = TabStripUtils.getActiveStripLayoutHelper(getActivity()); - StripLayoutTab[] tabs = strip.getStripLayoutTabs(); - float tabDrawWidth = tabs[0].getWidth() - strip.getTabOverlapWidth(); - - // Assert getStripLayoutTabs() returns the expected number of tabs. - assertEquals("Unexpected number of StripLayoutTabs.", 11, tabs.length); - - // Scroll tab strip to 0 and check tab positions. - assertSetTabStripScrollOffset(0); - for (int i = 0; i < tabs.length; i++) { - assertTabDrawX(i * tabDrawWidth, tabs[i]); - } - - // Scroll tab strip a little and check tab draw positions. - assertSetTabStripScrollOffset(-25); - for (int i = 0; i < tabs.length; i++) { - assertTabDrawX(i * tabDrawWidth - 25.f, tabs[i]); - } - - // Scroll tab strip a lot and check tab draw positions. - assertSetTabStripScrollOffset(-500); - for (int i = 0; i < tabs.length; i++) { - assertTabDrawX(i * tabDrawWidth - 500.f, tabs[i]); - } - assertTabVisibility(false, tabs[0]); - } - - /** * Take a model index and figure out which index it will be in the TabStrip's view hierarchy. * @param tabCount The number of tabs. * @param selectedIndex The index of the selected tab. @@ -828,7 +856,7 @@ * @param incognito Whether or not this tab is incognito or not. * @param id The id of the tab to compare. */ - protected void compareTabViewWithModel(boolean incognito, int id) { + protected void compareTabViewWithModel(boolean incognito, int id) throws ExecutionException { TabModel model = getActivity().getTabModelSelector().getModel(incognito); Tab tab = TabModelUtils.getTabById(model, id); StripLayoutHelper tabStrip = TabStripUtils.getStripLayoutHelper(getActivity(), incognito); @@ -872,7 +900,7 @@ * incognito tab is showing. * @param incognito Whether or not to check the incognito or normal TabStrip. */ - protected void compareTabStripWithModel(boolean incognito) { + protected void compareTabStripWithModel(boolean incognito) throws ExecutionException { TabModel model = getActivity().getTabModelSelector().getModel(incognito); StripLayoutHelper strip = TabStripUtils.getStripLayoutHelper(getActivity(), incognito); StripLayoutHelper activeStrip = TabStripUtils.getActiveStripLayoutHelper(getActivity()); @@ -906,7 +934,7 @@ * Compares all TabStrips with the corresponding TabModels. This also checks if the incognito * toggle is visible if necessary. */ - protected void compareAllTabStripsWithModel() { + protected void compareAllTabStripsWithModel() throws ExecutionException { compareTabStripWithModel(true); compareTabStripWithModel(false); } @@ -917,7 +945,8 @@ * @param shouldCascadeTabs Whether the {@link CascadingStripStacker} should be used. If false, * the {@link ScrollingStripStacker} will be used instead. */ - private void setShouldCascadeTabsAndCheckTabStrips(final boolean shouldCascadeTabs) { + private void setShouldCascadeTabsAndCheckTabStrips(final boolean shouldCascadeTabs) + throws ExecutionException { TabModel model = getActivity().getCurrentTabModel(); int selectedTabIndex = model.index(); @@ -956,7 +985,7 @@ * * @param scrollOffset The end scroll position for the tab strip. */ - private void assertSetTabStripScrollOffset(final int scrollOffset) { + private void assertSetTabStripScrollOffset(final int scrollOffset) throws ExecutionException { final StripLayoutHelper strip = TabStripUtils.getActiveStripLayoutHelper(getActivity()); ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override @@ -1025,16 +1054,21 @@ * @param tabStrip The StripLayoutHelper that owns the tab. * @param tabView The StripLayoutTab associated with the tab to check. */ - private void assertTabVisibilityForScrollingStripStacker(StripLayoutHelper tabStrip, - StripLayoutTab tabView) { + private void assertTabVisibilityForScrollingStripStacker(final StripLayoutHelper tabStrip, + final StripLayoutTab tabView) throws ExecutionException { // The visible percent for all tabs is 1.0 in the ScrollingStripStacker. assertEquals("ChromeTab is not completely visible. All tabs should be visible when " + "the ScrollingStripStacker is in use.", tabView.getVisiblePercentage(), 1.0f); // Only tabs that can currently be seen on the screen should be visible. - boolean shouldBeVisible = (tabView.getDrawX() + tabView.getWidth()) >= 0 - && tabView.getDrawX() <= tabStrip.getWidth(); + Boolean shouldBeVisible = ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() { + @Override + public Boolean call() throws Exception { + return (tabView.getDrawX() + tabView.getWidth()) >= 0 + && tabView.getDrawX() <= tabStrip.getWidth(); + } + }); assertTabVisibility(shouldBeVisible, tabView); } @@ -1043,18 +1077,35 @@ * @param shouldBeVisible Whether the tab should be visible. * @param tabView The StripLayoutTab associated with the tab to check. */ - private void assertTabVisibility(boolean shouldBeVisible, StripLayoutTab tabView) { + private void assertTabVisibility(final Boolean shouldBeVisible, final StripLayoutTab tabView) + throws ExecutionException { + Boolean isVisible = ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() { + @Override + public Boolean call() throws Exception { + return tabView.isVisible(); + } + }); + assertEquals("ChromeTab " + (shouldBeVisible ? "should" : "should not") + " be visible.", - shouldBeVisible, tabView.isVisible()); + shouldBeVisible, isVisible); } /** * Asserts that the tab has the expected draw X position. * @param expectedDrawX The expected draw X position. * @param tabView The StripLayoutTab associated with the tab to check. + * @param index The index for the tab. */ - private void assertTabDrawX(float expectedDrawX, StripLayoutTab tabView) { - assertEquals("Incorrect draw position for tab.", expectedDrawX, tabView.getDrawX()); + private void assertTabDrawX(float expectedDrawX, final StripLayoutTab tabView, int index) + throws ExecutionException { + Float tabDrawX = ThreadUtils.runOnUiThreadBlocking(new Callable<Float>() { + @Override + public Float call() throws Exception { + return tabView.getDrawX(); + } + }); + + assertEquals("Incorrect draw position for tab at " + index, expectedDrawX, tabDrawX); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java index c6707dcd..09ad3c6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -76,7 +76,7 @@ /** * Tests the Contextual Search Manager using instrumentation tests. */ -@CommandLineFlags.Add(ContextualSearchFieldTrial.SUPPRESSION_TAPS + "=1000") + public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<ChromeActivity> { private static final String TEST_PAGE = @@ -90,6 +90,8 @@ private static final String NORMAL_PRIORITY_SEARCH_ENDPOINT = "/search?"; private static final String LOW_PRIORITY_SEARCH_ENDPOINT = "/s?"; private static final String CONTEXTUAL_SEARCH_PREFETCH_PARAM = "&pf=c"; + // The number of ms to delay startup for all tests. + private static final int ACTIVITY_STARTUP_DELAY_MS = 1000; private ActivityMonitor mActivityMonitor; private ContextualSearchFakeServer mFakeServer; @@ -222,6 +224,10 @@ @Override public void startMainActivity() throws InterruptedException { startMainActivityWithURL(mTestServer.getURL(TEST_PAGE)); + // There's a problem with immediate startup that causes flakes due to the page not being + // ready, so specify a startup-delay of 1000 for legacy behavior. See crbug.com/635661. + // TODO(donnd): find a better way to wait for page-ready, or at least reduce the delay! + Thread.sleep(ACTIVITY_STARTUP_DELAY_MS); } //============================================================================================ @@ -2284,7 +2290,7 @@ /** * Tests that chained searches load correctly. */ - @DisabledTest // https://crbug.com/551711 + @DisabledTest(message = "crbug.com/551711") @SmallTest @Feature({"ContextualSearch"}) @Restriction({ChromeRestriction.RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/DistilledPagePrefsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/DistilledPagePrefsTest.java index 95ec5303..00f0d4b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/DistilledPagePrefsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/dom_distiller/DistilledPagePrefsTest.java
@@ -63,9 +63,8 @@ /* @SmallTest @Feature({"DomDistiller"}) - crbug.com/458196 */ - @DisabledTest + @DisabledTest(message = "crbug.com/458196") public void testSingleObserverTheme() throws InterruptedException { TestingObserver testObserver = new TestingObserver(); mDistilledPagePrefs.addObserver(testObserver); @@ -82,9 +81,8 @@ /* @SmallTest @Feature({"DomDistiller"}) - crbug.com/458196 */ - @DisabledTest + @DisabledTest(message = "crbug.com/458196") public void testMultipleObserversTheme() throws InterruptedException { TestingObserver testObserverOne = new TestingObserver(); mDistilledPagePrefs.addObserver(testObserverOne);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java index e646d97..7373621 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/infobar/InfoBarTest.java
@@ -124,7 +124,7 @@ @Smoke @MediumTest @Feature({"Browser", "Main"}) - @DisabledTest // crbug.com/593003 + @DisabledTest(message = "crbug.com/593003") public void testInfoBarForPopUp() throws InterruptedException { loadUrl(mTestServer.getURL(POPUP_PAGE)); assertTrue("InfoBar not added", mListener.addInfoBarAnimationFinished());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastSwitchVideoTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastSwitchVideoTest.java index dbcb7b5..fa5c1bfe 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastSwitchVideoTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/remote/CastSwitchVideoTest.java
@@ -7,7 +7,6 @@ import android.graphics.Rect; import android.test.suitebuilder.annotation.LargeTest; -import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.browser.tab.Tab; @@ -26,7 +25,7 @@ @Feature({"VideoFling"}) @LargeTest - @DisableIf.Build(hardware_is = "flo", message = "https://crbug.com/623526") + @FlakyTest(message = "https://crbug.com/623526") public void testPlayNewVideoInNewTab() throws InterruptedException, TimeoutException { // This won't currently work in document mode because we can't create new tabs if (FeatureUtilities.isDocumentMode(getActivity())) return; @@ -78,7 +77,7 @@ @Feature({"VideoFling"}) @LargeTest - @DisableIf.Build(hardware_is = "flo", message = "https://crbug.com/623526") + @FlakyTest(message = "https://crbug.com/623526") public void testCastNewVideoInNewTab() throws InterruptedException, TimeoutException { // This won't currently work in document mode because we can't create new tabs if (FeatureUtilities.isDocumentMode(getActivity())) return; @@ -114,7 +113,7 @@ @Feature({"VideoFling"}) @LargeTest - @DisableIf.Build(hardware_is = "flo", message = "https://crbug.com/623526") + @FlakyTest(message = "https://crbug.com/623526") public void testCastTwoVideosSamePage() throws InterruptedException, TimeoutException { checkCastSecondVideo(TWO_VIDEO_PAGE, new Runnable() { @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsTest.java index 239cb671..b1274372 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/offlinepages/OfflinePageUtilsTest.java
@@ -9,7 +9,6 @@ import android.test.suitebuilder.annotation.SmallTest; import org.chromium.base.Callback; -import org.chromium.base.Log; import org.chromium.base.ThreadUtils; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.chrome.browser.ChromeActivity; @@ -34,7 +33,6 @@ /** Unit tests for {@link OfflinePageUtils}. */ @CommandLineFlags.Add("enable-features=OfflineBookmarks") public class OfflinePageUtilsTest extends ChromeActivityTestCaseBase<ChromeActivity> { - private static final String TAG = "OfflinePageUtilsTest"; private static final String TEST_PAGE = "/chrome/test/data/android/about.html"; private static final int TIMEOUT_MS = 5000; private static final ClientId BOOKMARK_ID = @@ -54,8 +52,8 @@ ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { - // Ensure we start in an offline state. - NetworkChangeNotifier.forceConnectivityState(false); + // Ensure we start in an online state. + NetworkChangeNotifier.forceConnectivityState(true); Profile profile = Profile.getLastUsedProfile(); mOfflinePageBridge = OfflinePageBridge.getForProfile(profile); @@ -121,13 +119,11 @@ @Override public void onAction(Object actionData) { - Log.d(TAG, "onAction for snackbar"); mTabId = (int) actionData; } @Override public void onDismissNoAction(Object actionData) { - Log.d(TAG, "onDismissNoAction for snackbar"); if (actionData == null) return; mTabId = (int) actionData; mDismissed = true; @@ -150,32 +146,32 @@ @SmallTest public void testShowOfflineSnackbarIfNecessary() throws Exception { // Arrange - build a mock controller for sensing. - Log.d(TAG, "Starting test"); + OfflinePageUtils.setSnackbarDurationForTesting(1000); final MockSnackbarController mockSnackbarController = new MockSnackbarController(); - Log.d(TAG, "mockSnackbarController " + mockSnackbarController); // Save an offline page. String testUrl = mTestServer.getURL(TEST_PAGE); loadUrl(testUrl); savePage(SavePageResult.SUCCESS, testUrl); - // Load an offline page into the current tab. Note that this will create a - // SnackbarController when the page loads, but we use our own for the test. The one created - // here will also get the notification, but that won't interfere with our test. - List<OfflinePageItem> allPages = getAllPages(); - OfflinePageItem offlinePage = allPages.get(0); - String offlinePageUrl = offlinePage.getOfflineUrl(); - loadUrl(offlinePageUrl); - Log.d(TAG, "Calling showOfflineSnackbarIfNecessary from test"); + // With network disconnected, loading an online URL will result in loading an offline page. + // Note that this will create a SnackbarController when the page loads, but we use our own + // for the test. The one created here will also get the notification, but that won't + // interfere with our test. + ThreadUtils.runOnUiThreadBlocking(new Runnable() { + @Override + public void run() { + NetworkChangeNotifier.forceConnectivityState(false); + } + }); + loadUrl(testUrl); int tabId = getActivity().getActivityTab().getId(); // Act. This needs to be called from the UI thread. - Log.d(TAG, "before connecting NCN online state " + NetworkChangeNotifier.isOnline()); ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { - Log.d(TAG, "Showing offline snackbar from UI thread"); OfflinePageTabObserver.init(getActivity().getBaseContext(), getActivity().getSnackbarManager(), mockSnackbarController); OfflinePageUtils.showOfflineSnackbarIfNecessary(getActivity().getActivityTab()); @@ -193,8 +189,6 @@ mockSnackbarController.waitForSnackbarControllerToFinish(); // Assert snackbar was shown. - Log.d(TAG, "last tab id = " + mockSnackbarController.getLastTabId()); - Log.d(TAG, "dismissed = " + mockSnackbarController.getDismissed()); assertEquals(tabId, mockSnackbarController.getLastTabId()); assertTrue(mockSnackbarController.getDismissed()); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestDynamicShippingSingleAddressTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestDynamicShippingSingleAddressTest.java index 80fc1d9..e9ed01a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestDynamicShippingSingleAddressTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestDynamicShippingSingleAddressTest.java
@@ -4,13 +4,11 @@ package org.chromium.chrome.browser.payments; -import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE; - import android.content.DialogInterface; import android.test.suitebuilder.annotation.MediumTest; import org.chromium.base.ThreadUtils; -import org.chromium.base.test.util.Restriction; +import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -79,9 +77,12 @@ expectResultContains(new String[] {"Request cancelled"}); } - /** Add a valid address and complete the transaction. */ - @MediumTest - @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE) // crbug.com/626289 + /** + * Add a valid address and complete the transaction. + * @MediumTest + * @Restriction(RESTRICTION_TYPE_NON_LOW_END_DEVICE) // crbug.com/626289 + */ + @FlakyTest(message = "crbug.com/626289") public void testAddAddressAndPay() throws InterruptedException, ExecutionException, TimeoutException { triggerUIAndWait(mReadyForInput);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java index 8615ba88..34184cd 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestNoShippingTest.java
@@ -9,6 +9,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.test.util.FlakyTest; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; @@ -95,8 +96,11 @@ "123"}); } - /** Attempt to add an invalid credit card number and cancel payment. */ - @MediumTest + /** + * Attempt to add an invalid credit card number and cancel payment. + * @MediumTest + */ + @FlakyTest(message = "crbug.com/626289") public void testAddInvalidCardNumberAndCancel() throws InterruptedException, ExecutionException, TimeoutException { fillNewCardForm("123", "Bob", DECEMBER, NEXT_YEAR, FIRST_BILLING_ADDRESS); @@ -116,8 +120,11 @@ new int[] {month, year, billingAddress}, mBillingAddressChangeProcessed); } - /** Attempt to add a credit card with an empty name on card and cancel payment. */ - @MediumTest + /** + * Attempt to add a credit card with an empty name on card and cancel payment. + * @MediumTest + */ + @FlakyTest(message = "crbug.com/626289") public void testAddEmptyNameOnCardAndCancel() throws InterruptedException, ExecutionException, TimeoutException { fillNewCardForm("5454-5454-5454-5454", "", DECEMBER, NEXT_YEAR, FIRST_BILLING_ADDRESS);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/physicalweb/ListUrlsActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/physicalweb/ListUrlsActivityTest.java index 14756b9..7bfb9e4 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/physicalweb/ListUrlsActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/physicalweb/ListUrlsActivityTest.java
@@ -66,6 +66,7 @@ // Restore the onboarding state ContextUtils.getAppSharedPreferences().edit().putInt("physical_web", 2).apply(); UrlManager urlManager = UrlManager.getInstance(); + urlManager.clearAllUrls(); mMockPwsClient = new MockPwsClient(); urlManager.overridePwsClientForTesting(mMockPwsClient); urlManager.overrideNotificationManagerForTesting(new MockNotificationManagerProxy()); @@ -79,7 +80,7 @@ assertFalse(prefsManager.isPhysicalWebOnboarding()); assertTrue(prefsManager.isPhysicalWebEnabled()); - // Add URL. + // Add URLs. addUrl(URL, TITLE, DESC); // Launch the Activity. @@ -103,6 +104,90 @@ } @SmallTest + public void testNearestEntryInGroupSelectedNoChange() throws InterruptedException { + // Ensure the Physical Web is enabled. + PrivacyPreferencesManager prefsManager = PrivacyPreferencesManager.getInstance(); + prefsManager.setPhysicalWebEnabled(true); + assertFalse(prefsManager.isPhysicalWebOnboarding()); + assertTrue(prefsManager.isPhysicalWebEnabled()); + String url2 = "https://example.com/otherpage"; + UrlInfo urlInfo1 = new UrlInfo(URL, 2.0, System.currentTimeMillis()); + PwsResult pwsResult1 = new PwsResult(URL, URL, null, TITLE, DESC, null); + UrlInfo urlInfo2 = new UrlInfo(url2, 3.0, System.currentTimeMillis()); + PwsResult pwsResult2 = new PwsResult(url2, url2, null, TITLE, DESC, null); + + // Add the URLs. + mMockPwsClient.addPwsResult(pwsResult1); + mMockPwsClient.addPwsResult(pwsResult2); + mMockPwsClient.addCombinedPwsResults(); + UrlManager.getInstance().addUrl(urlInfo1); + UrlManager.getInstance().addUrl(urlInfo2); + getInstrumentation().waitForIdleSync(); + + // Launch the Activity. + ListUrlsActivity listActivity = launchActivity(); + TestContextWrapper testContextWrapper = new TestContextWrapper(listActivity); + listActivity.overrideContextForTesting(testContextWrapper); + getInstrumentation().waitForIdleSync(); + View listView = listActivity.findViewById(R.id.physical_web_urls_list); + + // Read the activity and tap the list entry. + ArrayList<View> entries = new ArrayList<>(); + listView.findViewsWithText(entries, TITLE, View.FIND_VIEWS_WITH_TEXT); + assertEquals(1, entries.size()); + View entry = entries.get(0); + TestTouchUtils.singleClickView(getInstrumentation(), entry); + testContextWrapper.waitForStartActivity(1000); + + // Test the fired intent to make sure the nearer beacon is selected. + assertEquals(1, testContextWrapper.startedIntents.size()); + assertEquals(URL, testContextWrapper.startedIntents.get(0).getDataString()); + } + + @SmallTest + public void testNearestEntryInGroupSelectedAfterChange() throws InterruptedException { + // Ensure the Physical Web is enabled. + PrivacyPreferencesManager prefsManager = PrivacyPreferencesManager.getInstance(); + prefsManager.setPhysicalWebEnabled(true); + assertFalse(prefsManager.isPhysicalWebOnboarding()); + assertTrue(prefsManager.isPhysicalWebEnabled()); + String url2 = "https://example.com/otherpage"; + UrlInfo urlInfo1 = new UrlInfo(URL, 2.0, System.currentTimeMillis()); + PwsResult pwsResult1 = new PwsResult(URL, URL, null, TITLE, DESC, null); + UrlInfo urlInfo2 = new UrlInfo(url2, 3.0, System.currentTimeMillis()); + PwsResult pwsResult2 = new PwsResult(url2, url2, null, TITLE, DESC, null); + + // Add the URLs. + mMockPwsClient.addPwsResult(pwsResult1); + mMockPwsClient.addPwsResult(pwsResult2); + mMockPwsClient.addCombinedPwsResults(); + UrlManager.getInstance().addUrl(urlInfo1); + UrlManager.getInstance().addUrl(urlInfo2); + getInstrumentation().waitForIdleSync(); + + // Launch the Activity. + ListUrlsActivity listActivity = launchActivity(); + TestContextWrapper testContextWrapper = new TestContextWrapper(listActivity); + listActivity.overrideContextForTesting(testContextWrapper); + getInstrumentation().waitForIdleSync(); + urlInfo2.setDistance(1.0); + getInstrumentation().waitForIdleSync(); + View listView = listActivity.findViewById(R.id.physical_web_urls_list); + + // Read the activity and tap the list entry. + ArrayList<View> entries = new ArrayList<>(); + listView.findViewsWithText(entries, TITLE, View.FIND_VIEWS_WITH_TEXT); + assertEquals(1, entries.size()); + View entry = entries.get(0); + TestTouchUtils.singleClickView(getInstrumentation(), entry); + testContextWrapper.waitForStartActivity(1000); + + // Test the fired intent to make sure the nearer beacon is selected. + assertEquals(1, testContextWrapper.startedIntents.size()); + assertEquals(url2, testContextWrapper.startedIntents.get(0).getDataString()); + } + + @SmallTest public void testUrlsListEmptyInOnboarding() { // In onboarding, we scan for nearby URLs but do not send them to the resolution service to // protect the user's privacy. This test checks that the URL list, which only displays
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/physicalweb/MockPwsClient.java b/chrome/android/javatests/src/org/chromium/chrome/browser/physicalweb/MockPwsClient.java index 296bf7b..c52b276e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/physicalweb/MockPwsClient.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/physicalweb/MockPwsClient.java
@@ -41,6 +41,20 @@ mPwsResults.add(pwsResults); } + public void addPwsResult(PwsResult pwsResult) { + List<PwsResult> pwsResults = new ArrayList<>(); + pwsResults.add(pwsResult); + addPwsResults(pwsResults); + } + + public void addCombinedPwsResults() { + List<PwsResult> pwsResults = new ArrayList<>(); + for (List<PwsResult> subList : mPwsResults) { + pwsResults.addAll(subList); + } + addPwsResults(pwsResults); + } + public void addIconBitmap(Bitmap iconBitmap) { mIconBitmaps.add(iconBitmap); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesTest.java index 8689b50..d9803fd 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesTest.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.preferences.privacy; +import android.content.Intent; +import android.os.AsyncTask; import android.os.Environment; import android.preference.CheckBoxPreference; import android.preference.Preference; @@ -143,13 +145,19 @@ */ @MediumTest public void testClearingHistoryClearsWebappScopesAndLaunchTimes() throws Exception { + AsyncTask<Void, Void, Intent> shortcutIntentTask = new AsyncTask<Void, Void, Intent>() { + @Override + protected Intent doInBackground(Void... nothing) { + return ShortcutHelper.createWebappShortcutIntentForTesting("id", "url"); + } + }; + final Intent shortcutIntent = shortcutIntentTask.execute().get(); + WebappRegistry.registerWebapp(getActivity(), "first", new WebappRegistry.FetchWebappDataStorageCallback() { @Override public void onWebappDataStorageRetrieved(WebappDataStorage storage) { - storage.updateFromShortcutIntent(ShortcutHelper.createWebappShortcutIntent( - "id", "action", "url", "scope", "name", "shortName", null, - ShortcutHelper.WEBAPP_SHORTCUT_VERSION, 0, 0, 0, 0, false)); + storage.updateFromShortcutIntent(shortcutIntent); mCallbackCalled = true; } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/printing/PrintingControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/printing/PrintingControllerTest.java index b6d96c5..2a436001 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/printing/PrintingControllerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/printing/PrintingControllerTest.java
@@ -157,12 +157,11 @@ /** * Test for http://crbug.com/528909 * - * Bug: http://crbug.com/532652 * @SmallTest * @Feature({"Printing"}) */ @CommandLineFlags.Add(ContentSwitches.DISABLE_POPUP_BLOCKING) - @DisabledTest + @DisabledTest(message = "crbug.com/532652") public void testPrintClosedWindow() throws Throwable { if (!ApiCompatibilityUtils.isPrintingSupported()) return;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/services/GoogleServicesManagerIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/services/GoogleServicesManagerIntegrationTest.java index 23fdf7f..aa582043 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/services/GoogleServicesManagerIntegrationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/services/GoogleServicesManagerIntegrationTest.java
@@ -10,6 +10,9 @@ import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.test.ChromeActivityTestCaseBase; +/** + * Google Services Manager tests + */ public class GoogleServicesManagerIntegrationTest extends ChromeActivityTestCaseBase<ChromeActivity> { @@ -19,12 +22,11 @@ /** * Test changing the state of auto login - * Bug: crbug.com/413289 * @Smoke * @SmallTest * @Feature({"Sync", "Main"}) */ - @DisabledTest + @DisabledTest(message = "crbug.com/413289") @UiThreadTest public void testSetAutologinState() { // TODO(acleung): Add back some sort of test for the GSM.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/OAuth2TokenServiceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/OAuth2TokenServiceTest.java index aab2f84c..c0973be 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/OAuth2TokenServiceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/OAuth2TokenServiceTest.java
@@ -34,11 +34,11 @@ AccountManagerHelper.overrideAccountManagerHelperForTests(mContext, mAccountManager); } - /* http://crbug.com/533417 + /* * @SmallTest * @Feature({"Sync"}) */ - @DisabledTest + @DisabledTest(message = "crbug.com/533417") public void testGetAccountsNoAccountsRegistered() { String[] accounts = OAuth2TokenService.getAccounts(mContext); assertEquals("There should be no accounts registered", 0, accounts.length); @@ -46,8 +46,7 @@ /*@SmallTest @Feature({"Sync"})*/ - // http://crbug.com/527852 - @DisabledTest + @DisabledTest(message = "crbug.com/527852") public void testGetAccountsOneAccountRegistered() { Account account1 = AccountManagerHelper.createAccountFromName("foo@gmail.com"); AccountHolder accountHolder1 = AccountHolder.create().account(account1).build(); @@ -63,8 +62,7 @@ /*@SmallTest @Feature({"Sync"})*/ - // http://crbug.com/527852 - @DisabledTest + @DisabledTest(message = "crbug.com/527852") public void testGetAccountsTwoAccountsRegistered() { Account account1 = AccountManagerHelper.createAccountFromName("foo@gmail.com"); AccountHolder accountHolder1 = AccountHolder.create().account(account1).build(); @@ -84,7 +82,7 @@ assertEquals("There should be zero registered account", 0, accounts.length); } - @DisabledTest // http://crbug.com/568620 + @DisabledTest(message = "crbug.com/568620") @SmallTest @Feature({"Sync"}) public void testGetOAuth2AccessTokenWithTimeoutOnSuccess() { @@ -95,8 +93,7 @@ /*@SmallTest @Feature({"Sync"})*/ - // http://crbug.com/527852 - @DisabledTest + @DisabledTest(message = "crbug.com/527852") public void testGetOAuth2AccessTokenWithTimeoutOnError() { String authToken = null; // Should not crash when auth token is null.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninHelperTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninHelperTest.java index d5da918..3aa7836 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninHelperTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/signin/SigninHelperTest.java
@@ -70,7 +70,7 @@ assertEquals("B", getNewSignedInAccountName()); } - @DisabledTest // crbug.com/568623 + @DisabledTest(message = "crbug.com/568623") @SmallTest public void testNotSignedInAccountRename() { setSignedInAccountName("A");
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java index f8346cde..96d3b9d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java
@@ -1307,6 +1307,7 @@ * @throws InterruptedException */ @MediumTest + @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE) // See crbug.com/633607 public void testAddTab() throws InterruptedException { TabModel model = getActivity().getTabModelSelector().getModel(false); ChromeTabCreator tabCreator = getActivity().getTabCreator(false); @@ -1424,6 +1425,7 @@ * 3. SaveState [ 1s ] - [ 1s ] */ @MediumTest + @Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE) // See crbug.com/633607 public void testSaveStateCommitsUndos() throws InterruptedException { TabModelSelector selector = getActivity().getTabModelSelector(); TabModel model = selector.getModel(false);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/translate/TranslateInfoBarTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/translate/TranslateInfoBarTest.java index 1de6882..728877d5 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/translate/TranslateInfoBarTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/translate/TranslateInfoBarTest.java
@@ -105,11 +105,10 @@ /** * Test infobar transitions. * - * Bug http://crbug.com/514449 * @MediumTest * @Feature({"Browser", "Main"}) */ - @DisabledTest + @DisabledTest(message = "crbug.com/514449") public void testTranslateTransitions() throws InterruptedException { loadUrl(mTestServer.getURL(TRANSLATE_PAGE)); assertTrue("InfoBar not Added", mListener.addInfoBarAnimationFinished());
diff --git a/chrome/android/javatests/src/org/chromium/chrome/test/util/parameters/SigninParametersTest.java b/chrome/android/javatests/src/org/chromium/chrome/test/util/parameters/SigninParametersTest.java index 8a9b30ab..b2e4c1c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/test/util/parameters/SigninParametersTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/test/util/parameters/SigninParametersTest.java
@@ -55,9 +55,8 @@ @SmallTest @ParameterizedTest(parameters = { @Parameter(tag = AddFakeAccountToAppParameter.PARAMETER_TAG)}) - crbug.com/524189 */ - @DisabledTest + @DisabledTest(message = "crbug.com/524189") public void testIsSignedInOnApp() { assertTrue("Should not be signed into app.", mAddFakeAccountToAppParameter.isSignedIn()); @@ -106,9 +105,8 @@ @ParameterizedTest(parameters = { @Parameter(tag = AddFakeAccountToAppParameter.PARAMETER_TAG), @Parameter(tag = AddFakeAccountToOsParameter.PARAMETER_TAG)}) - crbug.com/524189 */ - @DisabledTest + @DisabledTest(message = "crbug.com/524189") public void testIsSignedInOnFakeOSandApp() { assertTrue("Should be signed in on app.", mAddFakeAccountToAppParameter.isSignedIn()); @@ -133,9 +131,8 @@ @Parameter.Argument( name = AddGoogleAccountToOsParameter.ARGUMENT.PASSWORD, stringVar = GOOGLE_ACCOUNT_PASSWORD)})}) - crbug.com/524189 */ - @DisabledTest + @DisabledTest(message = "crbug.com/524189") public void testIsSignedInOnAppAndGoogleOS() { assertTrue("Should be signed into app.", mAddFakeAccountToAppParameter.isSignedIn()); @@ -184,9 +181,8 @@ @Parameter.Argument( name = AddGoogleAccountToOsParameter.ARGUMENT.PASSWORD, stringVar = GOOGLE_ACCOUNT_PASSWORD)})}) - crbug.com/524189 */ - @DisabledTest + @DisabledTest(message = "crbug.com/524189") public void testIsSignedInOnAppAndFakeOSandGoogleOS() { assertTrue("Should be signed into app.", mAddFakeAccountToAppParameter.isSignedIn());
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java index 8954a3d2..99ac7d0 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java
@@ -13,11 +13,13 @@ import org.chromium.base.Callback; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.test.util.Feature; +import org.chromium.chrome.browser.ntp.snippets.CategoryInt; import org.chromium.chrome.browser.ntp.snippets.CategoryStatus; import org.chromium.chrome.browser.ntp.snippets.CategoryStatus.CategoryStatusEnum; import org.chromium.chrome.browser.ntp.snippets.ContentSuggestionsCardLayout; import org.chromium.chrome.browser.ntp.snippets.KnownCategories; import org.chromium.chrome.browser.ntp.snippets.SnippetArticleListItem; +import org.chromium.chrome.browser.ntp.snippets.SnippetsBridge; import org.chromium.chrome.browser.ntp.snippets.SuggestionsSource; import org.chromium.testing.local.LocalRobolectricTestRunner; import org.junit.Before; @@ -39,22 +41,6 @@ @RunWith(LocalRobolectricTestRunner.class) @Config(manifest = Config.NONE) public class NewTabPageAdapterTest { - /** - * Number of elements, not including content suggestions that are loaded - * in a populated recycler view. - * The 3 elements are: above-the-fold, header, bottom spacer - * TODO(dgn): Make this depend on the category info of the loaded sections - * instead of being a constant, as it needs to know if the MORE button is - * present for example. - */ - private static final int PERMANENT_ELEMENTS_COUNT = 3; - - /** - * Number of elements that are loaded in an empty recycler view - * The 5 elements are: above-the-fold, header, status card, progress - * indicator, bottom spacer. - */ - private static final int EMPTY_STATE_ELEMENTS_COUNT = 5; private static class FakeSnippetsSource implements SuggestionsSource { private SuggestionsSource.Observer mObserver; @@ -62,21 +48,29 @@ private final Map<Integer, Integer> mCategoryStatus = new HashMap<>(); private final Map<Integer, SuggestionsCategoryInfo> mCategoryInfo = new HashMap<>(); - public void setStatusForCategory(int category, @CategoryStatusEnum int status) { + public void setStatusForCategory(@CategoryInt int category, + @CategoryStatusEnum int status) { mCategoryStatus.put(category, status); if (mObserver != null) mObserver.onCategoryStatusChanged(category, status); } public void setSuggestionsForCategory( - int category, List<SnippetArticleListItem> suggestions) { - mSuggestions.put(category, suggestions); + @CategoryInt int category, List<SnippetArticleListItem> suggestions) { + // Copy the suggestions list so that it can't be modified anymore. + mSuggestions.put(category, new ArrayList<>(suggestions)); if (mObserver != null) mObserver.onNewSuggestions(category); } - public void setInfoForCategory(int category, SuggestionsCategoryInfo info) { + public void setInfoForCategory(@CategoryInt int category, SuggestionsCategoryInfo info) { mCategoryInfo.put(category, info); } + public void silentlyRemoveCategory(int category) { + mSuggestions.remove(category); + mCategoryStatus.remove(category); + mCategoryInfo.remove(category); + } + @Override public void dismissSuggestion(SnippetArticleListItem suggestion) { throw new UnsupportedOperationException(); @@ -110,7 +104,7 @@ @CategoryStatusEnum @Override - public int getCategoryStatus(int category) { + public int getCategoryStatus(@CategoryInt int category) { return mCategoryStatus.get(category); } @@ -121,6 +115,9 @@ @Override public List<SnippetArticleListItem> getSuggestionsForCategory(int category) { + if (!SnippetsBridge.isCategoryStatusAvailable(mCategoryStatus.get(category))) { + return Collections.emptyList(); + } List<SnippetArticleListItem> result = mSuggestions.get(category); return result == null ? Collections.<SnippetArticleListItem>emptyList() : result; } @@ -129,6 +126,58 @@ private FakeSnippetsSource mSnippetsSource = new FakeSnippetsSource(); private NewTabPageAdapter mNtpAdapter; + /** + * Asserts that {@link #mNtpAdapter}.{@link NewTabPageAdapter#getItemCount()} corresponds to an + * NTP with the given sections in it. + * @param sections A list of sections, each represented by the number of items that are required + * to represent it on the UI. For readability, these numbers should be generated + * with the methods below. + */ + private void assertItemsFor(int... sections) { + int expectedCount = 1; // above-the-fold. + for (int section : sections) expectedCount += section; + if (sections.length > 0) expectedCount += 1; // bottom spacer. + int actualCount = mNtpAdapter.getItemCount(); + assertEquals("Expected " + expectedCount + " items, but the following " + actualCount + + " were present: " + mNtpAdapter.getItems(), + expectedCount, mNtpAdapter.getItemCount()); + } + + /** + * To be used with {@link #assertItemsFor(int...)}, for a section with {@code numSuggestions} + * cards in it. + * @param numSuggestions The number of suggestions in the section. If there are zero, use either + * no section at all (if it is not displayed) or + * {@link #sectionWithStatusCard()}. + * @return The number of items that should be used by the adapter to represent this section. + */ + private int section(int numSuggestions) { + assert numSuggestions > 0; + return 1 + numSuggestions; // Header and the content. + } + + /** + * To be used with {@link #assertItemsFor(int...)}, for a section with {@code numSuggestions} + * cards and a more-button. + * @param numSuggestions The number of suggestions in the section. If this is zero, the + * more-button is still shown. + * TODO(pke): In the future, we additionally show an empty-card if + * numSuggestions is zero. + * @return The number of items that should be used by the adapter to represent this section. + */ + private int sectionWithMoreButton(int numSuggestions) { + return 1 + numSuggestions + 1; // Header, the content and the more-button. + } + + /** + * To be used with {@link #assertItemsFor(int...)}, for a section that has no suggestions, but + * a status card to be displayed. + * @return The number of items that should be used by the adapter to represent this section. + */ + private int sectionWithStatusCard() { + return 3; // Header, status card and progress indicator. + } + @Before public void setUp() { RecordHistogram.disableForTests(); @@ -137,7 +186,7 @@ mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.INITIALIZING); mSnippetsSource.setInfoForCategory( KnownCategories.ARTICLES, new SuggestionsCategoryInfo("Articles for you", - ContentSuggestionsCardLayout.FULL_CARD)); + ContentSuggestionsCardLayout.FULL_CARD, false)); mNtpAdapter = new NewTabPageAdapter(null, null, mSnippetsSource, null); } @@ -148,19 +197,22 @@ @Test @Feature({"Ntp"}) public void testSnippetLoading() { - assertEquals(EMPTY_STATE_ELEMENTS_COUNT, mNtpAdapter.getItemCount()); + assertItemsFor(sectionWithStatusCard()); assertEquals(NewTabPageListItem.VIEW_TYPE_ABOVE_THE_FOLD, mNtpAdapter.getItemViewType(0)); assertEquals(NewTabPageListItem.VIEW_TYPE_HEADER, mNtpAdapter.getItemViewType(1)); assertEquals(NewTabPageListItem.VIEW_TYPE_STATUS, mNtpAdapter.getItemViewType(2)); assertEquals(NewTabPageListItem.VIEW_TYPE_PROGRESS, mNtpAdapter.getItemViewType(3)); assertEquals(NewTabPageListItem.VIEW_TYPE_SPACING, mNtpAdapter.getItemViewType(4)); - List<SnippetArticleListItem> snippets = createDummySnippets(); + List<SnippetArticleListItem> snippets = createDummySnippets(3); + mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AVAILABLE); mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snippets); List<NewTabPageListItem> loadedItems = new ArrayList<>(mNtpAdapter.getItems()); assertEquals(NewTabPageListItem.VIEW_TYPE_ABOVE_THE_FOLD, mNtpAdapter.getItemViewType(0)); assertEquals(NewTabPageListItem.VIEW_TYPE_HEADER, mNtpAdapter.getItemViewType(1)); + // From the loadedItems, cut out aboveTheFold and header from the front, + // and bottom spacer from the back. assertEquals(snippets, loadedItems.subList(2, loadedItems.size() - 1)); assertEquals(NewTabPageListItem.VIEW_TYPE_SPACING, mNtpAdapter.getItemViewType(loadedItems.size() - 1)); @@ -168,7 +220,8 @@ // The adapter should ignore any new incoming data. mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, Arrays.asList(new SnippetArticleListItem[] {new SnippetArticleListItem( - "foo", "title1", "pub1", "txt1", "foo", "bar", 0, 0, 0)})); + "foo", "title1", "pub1", "txt1", "foo", "bar", 0, 0, 0, + ContentSuggestionsCardLayout.FULL_CARD)})); assertEquals(loadedItems, mNtpAdapter.getItems()); } @@ -182,7 +235,7 @@ // If we don't get anything, we should be in the same situation as the initial one. mSnippetsSource.setSuggestionsForCategory( KnownCategories.ARTICLES, new ArrayList<SnippetArticleListItem>()); - assertEquals(EMPTY_STATE_ELEMENTS_COUNT, mNtpAdapter.getItemCount()); + assertItemsFor(sectionWithStatusCard()); assertEquals(NewTabPageListItem.VIEW_TYPE_ABOVE_THE_FOLD, mNtpAdapter.getItemViewType(0)); assertEquals(NewTabPageListItem.VIEW_TYPE_HEADER, mNtpAdapter.getItemViewType(1)); assertEquals(NewTabPageListItem.VIEW_TYPE_STATUS, mNtpAdapter.getItemViewType(2)); @@ -190,11 +243,14 @@ assertEquals(NewTabPageListItem.VIEW_TYPE_SPACING, mNtpAdapter.getItemViewType(4)); // We should load new snippets when we get notified about them. - List<SnippetArticleListItem> snippets = createDummySnippets(); + List<SnippetArticleListItem> snippets = createDummySnippets(5); + mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AVAILABLE); mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snippets); List<NewTabPageListItem> loadedItems = new ArrayList<>(mNtpAdapter.getItems()); assertEquals(NewTabPageListItem.VIEW_TYPE_ABOVE_THE_FOLD, mNtpAdapter.getItemViewType(0)); assertEquals(NewTabPageListItem.VIEW_TYPE_HEADER, mNtpAdapter.getItemViewType(1)); + // From the loadedItems, cut out aboveTheFold and header from the front, + // and bottom spacer from the back. assertEquals(snippets, loadedItems.subList(2, loadedItems.size() - 1)); assertEquals(NewTabPageListItem.VIEW_TYPE_SPACING, mNtpAdapter.getItemViewType(loadedItems.size() - 1)); @@ -202,7 +258,8 @@ // The adapter should ignore any new incoming data. mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, Arrays.asList(new SnippetArticleListItem[] {new SnippetArticleListItem( - "foo", "title1", "pub1", "txt1", "foo", "bar", 0, 0, 0)})); + "foo", "title1", "pub1", "txt1", "foo", "bar", 0, 0, 0, + ContentSuggestionsCardLayout.FULL_CARD)})); assertEquals(loadedItems, mNtpAdapter.getItems()); } @@ -212,27 +269,29 @@ @Test @Feature({"Ntp"}) public void testSnippetClearing() { - List<SnippetArticleListItem> snippets = createDummySnippets(); + List<SnippetArticleListItem> snippets = createDummySnippets(4); + mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AVAILABLE); mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snippets); - assertEquals(PERMANENT_ELEMENTS_COUNT + snippets.size(), mNtpAdapter.getItemCount()); + assertItemsFor(section(4)); // If we get told that snippets are enabled, we just leave the current // ones there and not clear. mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AVAILABLE); - assertEquals(PERMANENT_ELEMENTS_COUNT + snippets.size(), mNtpAdapter.getItemCount()); + assertItemsFor(section(4)); // When snippets are disabled, we clear them and we should go back to // the situation with the status card. mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.SIGNED_OUT); - assertEquals(EMPTY_STATE_ELEMENTS_COUNT, mNtpAdapter.getItemCount()); + assertItemsFor(sectionWithStatusCard()); // The adapter should now be waiting for new snippets. + snippets = createDummySnippets(6); mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AVAILABLE); mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snippets); - assertEquals(PERMANENT_ELEMENTS_COUNT + snippets.size(), mNtpAdapter.getItemCount()); + assertItemsFor(section(6)); } /** @@ -241,35 +300,38 @@ @Test @Feature({"Ntp"}) public void testSnippetLoadingBlock() { - List<SnippetArticleListItem> snippets = createDummySnippets(); + List<SnippetArticleListItem> snippets = createDummySnippets(3); // By default, status is INITIALIZING, so we can load snippets + mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AVAILABLE); mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snippets); - assertEquals(PERMANENT_ELEMENTS_COUNT + snippets.size(), mNtpAdapter.getItemCount()); + assertItemsFor(section(3)); - // If we have snippets, we should not load the new list. + // If we have snippets, we should not load the new list (i.e. the extra item does *not* + // appear). snippets.add(new SnippetArticleListItem("https://site.com/url1", "title1", "pub1", "txt1", - "https://site.com/url1", "https://amp.site.com/url1", 0, 0, 0)); + "https://site.com/url1", "https://amp.site.com/url1", 0, 0, 0, + ContentSuggestionsCardLayout.FULL_CARD)); mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snippets); - assertEquals(PERMANENT_ELEMENTS_COUNT + snippets.size() - 1, mNtpAdapter.getItemCount()); + assertItemsFor(section(3)); - // When snippets are disabled, we should not be able to load them + // When snippets are disabled, we should not be able to load them. mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.SIGNED_OUT); mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snippets); - assertEquals(EMPTY_STATE_ELEMENTS_COUNT, mNtpAdapter.getItemCount()); + assertItemsFor(sectionWithStatusCard()); // INITIALIZING lets us load snippets still. mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.INITIALIZING); mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snippets); - assertEquals(PERMANENT_ELEMENTS_COUNT + snippets.size(), mNtpAdapter.getItemCount()); + assertItemsFor(sectionWithStatusCard()); - // The adapter should now be waiting for new snippets. + // The adapter should now be waiting for new snippets and the fourth one should appear. mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AVAILABLE); mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snippets); - assertEquals(PERMANENT_ELEMENTS_COUNT + snippets.size(), mNtpAdapter.getItemCount()); + assertItemsFor(section(4)); } /** @@ -294,30 +356,90 @@ assertTrue(progress.isVisible()); mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, - CategoryStatus.NOT_PROVIDED); - assertFalse(progress.isVisible()); - - mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, - CategoryStatus.CATEGORY_EXPLICITLY_DISABLED); - assertFalse(progress.isVisible()); - - mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.SIGNED_OUT); assertFalse(progress.isVisible()); - - mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, - CategoryStatus.LOADING_ERROR); - assertFalse(progress.isVisible()); } - private List<SnippetArticleListItem> createDummySnippets() { + /** + * Tests that the entire section disappears if its status switches to LOADING_ERROR or + * CATEGORY_EXPLICITLY_DISABLED. Also tests that they are not shown when the NTP reloads. + */ + @Test + @Feature({"Ntp"}) + public void testSectionClearingWhenUnavailable() { + List<SnippetArticleListItem> snippets = createDummySnippets(5); + mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AVAILABLE); + mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snippets); + assertItemsFor(section(5)); + + // When the category goes away with a hard error, the section is cleared from the UI. + mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, + CategoryStatus.LOADING_ERROR); + assertItemsFor(); + + // Same when loading a new NTP. + mNtpAdapter = new NewTabPageAdapter(null, null, mSnippetsSource, null); + assertItemsFor(); + + // Same for CATEGORY_EXPLICITLY_DISABLED. + mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AVAILABLE); + mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snippets); + assertItemsFor(section(5)); + mSnippetsSource.setStatusForCategory( + KnownCategories.ARTICLES, CategoryStatus.CATEGORY_EXPLICITLY_DISABLED); + assertItemsFor(); + + // Same when loading a new NTP. + mNtpAdapter = new NewTabPageAdapter(null, null, mSnippetsSource, null); + assertItemsFor(); + } + + /** + * Tests that the UI remains untouched if a category switches to NOT_PROVIDED. + */ + @Test + @Feature({"Ntp"}) + public void testUIUntouchedWhenNotProvided() { + List<SnippetArticleListItem> snippets = createDummySnippets(4); + mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AVAILABLE); + mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snippets); + assertItemsFor(section(4)); + + // When the category switches to NOT_PROVIDED, UI stays the same. + mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.NOT_PROVIDED); + mSnippetsSource.silentlyRemoveCategory(KnownCategories.ARTICLES); + assertItemsFor(section(4)); + + // But it disappears when loading a new NTP. + mNtpAdapter = new NewTabPageAdapter(null, null, mSnippetsSource, null); + assertItemsFor(); + } + + @Test + @Feature({"Ntp"}) + public void testMoreButton() { + List<SnippetArticleListItem> articles = createDummySnippets(3); + mSnippetsSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AVAILABLE); + mSnippetsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, articles); + assertItemsFor(section(3)); + + List<SnippetArticleListItem> bookmarks = createDummySnippets(10); + mSnippetsSource.setInfoForCategory(KnownCategories.BOOKMARKS, + new SuggestionsCategoryInfo("Bookmarks", ContentSuggestionsCardLayout.MINIMAL_CARD, + true)); + mSnippetsSource.setStatusForCategory(KnownCategories.BOOKMARKS, CategoryStatus.AVAILABLE); + mSnippetsSource.setSuggestionsForCategory(KnownCategories.BOOKMARKS, bookmarks); + assertItemsFor(sectionWithMoreButton(10), section(3)); + } + + private List<SnippetArticleListItem> createDummySnippets(int count) { List<SnippetArticleListItem> snippets = new ArrayList<>(); - snippets.add(new SnippetArticleListItem("https://site.com/url1", "title1", "pub1", "txt1", - "https://site.com/url1", "https://amp.site.com/url1", 0, 0, 0)); - snippets.add(new SnippetArticleListItem("https://site.com/url2", "title2", "pub2", "txt2", - "https://site.com/url2", "https://amp.site.com/url2", 0, 0, 0)); - snippets.add(new SnippetArticleListItem("https://site.com/url3", "title3", "pub3", "txt3", - "https://site.com/url3", "https://amp.site.com/url3", 0, 0, 0)); + for (int index = 0; index < count; index++) { + snippets.add(new SnippetArticleListItem("https://site.com/url" + index, "title" + index, + "pub" + index, "txt" + index, "https://site.com/url" + index, + "https://amp.site.com/url" + index, 0, 0, 0, + ContentSuggestionsCardLayout.FULL_CARD)); + } return snippets; } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/downloads/OfflinePageDownloadBridgeTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/downloads/OfflinePageDownloadBridgeTest.java index 1d4aaec..5c19d75 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/downloads/OfflinePageDownloadBridgeTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/downloads/OfflinePageDownloadBridgeTest.java
@@ -129,6 +129,25 @@ @Test @Feature({"OfflinePages"}) + public void testDeleteItemByGuid() { + OfflinePageDownloadItem item = createDownloadItem1(); + doNothing().when(mBridge).nativeDeleteItemByGuid(anyLong(), eq(item.getGuid())); + mBridge.deleteItem(item.getGuid()); + verify(mBridge, times(1)).nativeDeleteItemByGuid(eq(0L), eq(item.getGuid())); + } + + @Test + @Feature({"OfflinePages"}) + public void testOpenItemByGuid() { + OfflinePageDownloadItem item = createDownloadItem1(); + // Empty URL skips actual intent. + doReturn("").when(mBridge).nativeGetOfflineUrlByGuid(anyLong(), eq(item.getGuid())); + mBridge.openItem(item.getGuid()); + verify(mBridge, times(1)).nativeGetOfflineUrlByGuid(eq(0L), eq(item.getGuid())); + } + + @Test + @Feature({"OfflinePages"}) public void testCreateDownloadItemAndAddToList() { List<OfflinePageDownloadItem> list = new ArrayList<>(); OfflinePageDownloadItem item1 = createDownloadItem1();
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappDataStorageTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappDataStorageTest.java index b4b6564..70bcb19 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappDataStorageTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappDataStorageTest.java
@@ -11,6 +11,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Bitmap; +import android.os.AsyncTask; import org.chromium.base.test.util.Feature; import org.chromium.blink_public.platform.WebDisplayMode; @@ -245,9 +246,15 @@ final long themeColor = 2; final long backgroundColor = 3; final boolean isIconGenerated = false; - Intent shortcutIntent = ShortcutHelper.createWebappShortcutIntent(id, action, url, scope, - name, shortName, icon, ShortcutHelper.WEBAPP_SHORTCUT_VERSION, displayMode, - orientation, themeColor, backgroundColor, isIconGenerated); + AsyncTask<Void, Void, Intent> shortcutIntentTask = new AsyncTask<Void, Void, Intent>() { + @Override + protected Intent doInBackground(Void... nothing) { + return ShortcutHelper.createWebappShortcutIntent(id, action, url, scope, name, + shortName, icon, ShortcutHelper.WEBAPP_SHORTCUT_VERSION, displayMode, + orientation, themeColor, backgroundColor, isIconGenerated); + } + }; + Intent shortcutIntent = shortcutIntentTask.execute().get(); WebappDataStorage storage = WebappDataStorage.open(Robolectric.application, "test"); storage.updateFromShortcutIntent(shortcutIntent);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java index 2ec5cc8..09b1db30 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java
@@ -10,10 +10,10 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.os.AsyncTask; import android.text.TextUtils; import org.chromium.base.test.util.Feature; -import org.chromium.blink_public.platform.WebDisplayMode; import org.chromium.chrome.browser.ShortcutHelper; import org.chromium.chrome.browser.browsing_data.UrlFilters; import org.chromium.testing.local.BackgroundShadowAsyncTask; @@ -749,10 +749,14 @@ WebappRegistry.KEY_WEBAPP_SET, Collections.<String>emptySet()); } - private Intent createShortcutIntent(String url) { - return ShortcutHelper.createWebappShortcutIntent("id", "action", url, - ShortcutHelper.getScopeFromUrl(url), "name", "shortName", null, - ShortcutHelper.WEBAPP_SHORTCUT_VERSION, WebDisplayMode.Standalone, 0, 0, 0, false); + private Intent createShortcutIntent(final String url) throws Exception { + AsyncTask<Void, Void, Intent> shortcutIntentTask = new AsyncTask<Void, Void, Intent>() { + @Override + protected Intent doInBackground(Void... nothing) { + return ShortcutHelper.createWebappShortcutIntentForTesting("id", url); + } + }; + return shortcutIntentTask.execute().get(); } private Intent createWebApkIntent(String webappId, String webApkPackage) {
diff --git a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java index 5ef00c2..47f038d 100644 --- a/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java +++ b/chrome/android/sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java
@@ -34,6 +34,7 @@ import org.chromium.components.sync.PassphraseType; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -214,8 +215,7 @@ } Set<Integer> expectedTypes = new HashSet<Integer>(dataTypes.keySet()); - // TODO(zea): update this once preferences are supported. - expectedTypes.remove(ModelType.PREFERENCES); + expectedTypes.add(ModelType.PREFERENCES); expectedTypes.add(ModelType.PRIORITY_PREFERENCES); assertDataTypesAre(expectedTypes); togglePreference(dataTypes.get(ModelType.AUTOFILL)); @@ -708,10 +708,7 @@ public void run() { Set<Integer> actualDataTypes = mProfileSyncService.getPreferredDataTypes(); assertTrue(actualDataTypes.containsAll(enabledDataTypes)); - // There is no Set.containsNone(), sadly. - for (Integer disabledDataType : disabledDataTypes) { - assertFalse(actualDataTypes.contains(disabledDataType)); - } + assertTrue(Collections.disjoint(disabledDataTypes, actualDataTypes)); } }); }
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index e1d4c52..2ec21696 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -1644,6 +1644,12 @@ <message name="IDS_LANGUAGE_SECTION_TITLE" desc="Title of language selection screen" meaning="A title of the dialog where user should select ChromeOS UI language and default keyboard layout during initial device setup."> Choose your language & keyboard </message> + <message name="IDS_ACCESSIBILITY_SECTION_TITLE" desc="Title of accessibility options screen" meaning="A title of the dialog where user can control ChromeOS UI accessibility (like large cursor or screen reader) options during initial device setup."> + Accessibility settings + </message> + <message name="IDS_ACCESSIBILITY_SECTION_HINT" desc="Under-title line on the accessibility options screen" meaning="A hint to the user that these settings help to make device more usable."> + Configure your device to be more usable. + </message> <message name="IDS_NETWORK_SECTION_TITLE" desc="Title of network selection screen" meaning="A title of the dialog where user should select network to connect to Internet"> Connect to network </message> @@ -1659,18 +1665,48 @@ <message name="IDS_OOBE_SPOKEN_FEEDBACK_OPTION" desc="Spoken feedback option shown on OOBE screens accessibility menu."> ChromeVox (spoken feedback) </message> + <message name="IDS_SPOKEN_FEEDBACK_OPTION_OFF" desc="A value for Spoken Feedback accessibility option when it is off."> + Off + </message> + <message name="IDS_SPOKEN_FEEDBACK_OPTION_ON" desc="A value for Spoken Feedback accessibility option when it is on."> + On + </message> <message name="IDS_OOBE_LARGE_CURSOR_OPTION" desc="Large mouse cursor option shown on OOBE screens accessibility menu."> Large mouse cursor </message> + <message name="IDS_LARGE_CURSOR_OPTION_OFF" desc="A value for Large Mouse Cursor accessibility option when it is off."> + Normal + </message> + <message name="IDS_LARGE_CURSOR_OPTION_ON" desc="A value for Large Mouse Cursor accessibility option when it is on."> + Large + </message> <message name="IDS_OOBE_HIGH_CONTRAST_MODE_OPTION" desc="High contrast mode option shown on OOBE screens accessibility menu."> High contrast mode </message> + <message name="IDS_HIGH_CONTRAST_OPTION_OFF" desc="A value for High Contrast Mode accessibility option when it is off."> + Off + </message> + <message name="IDS_HIGH_CONTRAST_OPTION_ON" desc="A value for High Contrast Mode accessibility option when it is on."> + On + </message> <message name="IDS_OOBE_SCREEN_MAGNIFIER_OPTION" desc="Screen magnifier option shown on OOBE screens accessibility menu."> Screen magnifier </message> + <message name="IDS_SCREEN_MAGNIFIER_OPTION_OFF" desc="A value for Screen Magnifier Option accessibility option when it is off."> + Off + </message> + <message name="IDS_SCREEN_MAGNIFIER_OPTION_ON" desc="A value for Screen Magnifier Option accessibility option when it is on."> + On + </message> <message name="IDS_OOBE_VIRTUAL_KEYBOARD_OPTION" desc="Virtual keyboard option shown on the OOBE screens accessibility menu."> On-screen keyboard </message> + <message name="IDS_VIRTUAL_KEYBOARD_OPTION_OFF" desc="A value for Virtual Keyboard accessibility option when it is off."> + Off + </message> + <message name="IDS_VIRTUAL_KEYBOARD_OPTION_ON" desc="A value for Virtual Keyboard accessibility option when it is on."> + On + </message> <message name="IDS_OOBE_CLOSE_ACCESSIBILITY_MENU" desc="Text to be spoken when focus is set to the close button of accessibility options menu."> Close accessibility menu </message> @@ -6654,77 +6690,6 @@ Failed to submit NDEF: </message> - <!-- About consumer management service --> - <message name="IDS_OPTIONS_DEVICE_CONTROL_SECTION_TITLE" desc="The title of the device control section in the settings page."> - Device control - </message> - <message name="IDS_OPTIONS_CONSUMER_MANAGEMENT_DESCRIPTION" desc="Description of the consumer management service in the settings page."> - Let Google help you remotely lock, erase, and locate your device. - </message> - <message name="IDS_OPTIONS_CONSUMER_MANAGEMENT_ENROLL_BUTTON" desc="The text of the consumer management button in the settings page when the device is not enrolled."> - Enroll - </message> - <message name="IDS_OPTIONS_CONSUMER_MANAGEMENT_ENROLLING_BUTTON" desc="The text of the consumer management button in the settings page when enrollment is in progress."> - Enrolling... - </message> - <message name="IDS_OPTIONS_CONSUMER_MANAGEMENT_UNENROLL_BUTTON" desc="The text of the consumer management button in the settings page when the device is enrolled."> - Unenroll - </message> - <message name="IDS_OPTIONS_CONSUMER_MANAGEMENT_UNENROLLING_BUTTON" desc="The text of the consumer management button in the settings page when unenrollment is in progress."> - Unenrolling... - </message> - <message name="IDS_OPTIONS_CONSUMER_MANAGEMENT_OVERLAY" desc="The title of the consumer management overlay in the settings page used for both enrollment and unenrollment."> - Consumer management - </message> - <message name="IDS_OPTIONS_CONSUMER_MANAGEMENT_OVERLAY_ENROLL_TITLE" desc="The title of the consumer management overlay in the settings page for enrollment."> - Enroll <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> - </message> - <message name="IDS_OPTIONS_CONSUMER_MANAGEMENT_OVERLAY_ENROLL_MESSAGE" desc="The description of the consumer management overlay in the settings page for enrollment."> - You are about to enroll this <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> with Google to enable the ability to remotely locate, wipe, and lock the device. This will require a reboot. Do you wish to continue? - </message> - <message name="IDS_OPTIONS_CONSUMER_MANAGEMENT_OVERLAY_ENROLL" desc="The button text of the consumer management overlay in the settings page for enrollment."> - Enroll and restart - </message> - <message name="IDS_OPTIONS_CONSUMER_MANAGEMENT_OVERLAY_UNENROLL_TITLE" desc="The title of the consumer management overlay in the settings page for unenrollment."> - Unenroll <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> - </message> - <message name="IDS_OPTIONS_CONSUMER_MANAGEMENT_OVERLAY_UNENROLL_MESSAGE" desc="The description of the consumer management overlay in the settings page for unenrollment."> - You are about to unenroll this <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> with Google to disable the ability to remotely locate, wipe, and lock the device. This will require a reboot. Do you wish to continue? - </message> - <message name="IDS_OPTIONS_CONSUMER_MANAGEMENT_OVERLAY_UNENROLL" desc="The button text of the consumer management overlay in the settings page for unenrollment."> - Unenroll and restart - </message> - <message name="IDS_CONSUMER_MANAGEMENT_ENROLLMENT_NOTIFICATION_TITLE" desc="The title of the desktop notification shown when consumer management enrollment is completed"> - Enrolled - </message> - <message name="IDS_CONSUMER_MANAGEMENT_ENROLLMENT_NOTIFICATION_BODY" desc="The body of the desktop notification shown when consumer management enrollment is completed"> - You can now lock this device remotely anytime on Chrome Manager. - </message> - <message name="IDS_CONSUMER_MANAGEMENT_ENROLLMENT_FAILURE_NOTIFICATION_TITLE" desc="The title of the desktop notification shown when consumer management enrollment fails"> - Unable to enroll - </message> - <message name="IDS_CONSUMER_MANAGEMENT_ENROLLMENT_FAILURE_NOTIFICATION_BODY" desc="The body of the desktop notification shown when consumer management enrollment fails"> - Enrollment in Google Device Manager was not successful. - </message> - <message name="IDS_CONSUMER_MANAGEMENT_UNENROLLMENT_NOTIFICATION_TITLE" desc="The title of the desktop notification shown when consumer management unenrollment is completed"> - Unenrolled - </message> - <message name="IDS_CONSUMER_MANAGEMENT_UNENROLLMENT_NOTIFICATION_BODY" desc="The body of the desktop notification shown when consumer management unenrollment is completed"> - This device can no longer be managed remotely by the owner (you). - </message> - <message name="IDS_CONSUMER_MANAGEMENT_UNENROLLMENT_FAILURE_NOTIFICATION_TITLE" desc="The title of the desktop notification shown when consumer management unenrollment fails"> - Failed to unenroll - </message> - <message name="IDS_CONSUMER_MANAGEMENT_UNENROLLMENT_FAILURE_NOTIFICATION_BODY" desc="The body of the desktop notification shown when consumer management unenrollment fails"> - Unenrollment from remote management was not successful. - </message> - <message name="IDS_CONSUMER_MANAGEMENT_NOTIFICATION_MODIFY_SETTINGS_BUTTON" desc="The label of the modify settings button on the desktop notification shown when consumer management enrollment or unenrollment is completed"> - Modify settings - </message> - <message name="IDS_CONSUMER_MANAGEMENT_NOTIFICATION_TRY_AGAIN_BUTTON" desc="The label of the modify settings button on the desktop notification shown when consumer management enrollment or unenrollment fails"> - Try again - </message> - <!-- Set time/date UI display strings --> <message name="IDS_SET_TIME_TITLE" desc="Title of the set time/date UI."> Check your system time @@ -6821,14 +6786,14 @@ </message> <!-- Android Apps --> - <message name="IDS_OPTIONS_ARC_TITLE" desc="The title of Android Apps section."> - Android apps + <message name="IDS_OPTIONS_ARC_TITLE" desc="The title of Google Play Store section."> + Google Play Store </message> - <message name="IDS_OPTIONS_ARC_ENABLE" desc="Label for the checkbox that enables Android apps."> - Enable Android apps on your Chromebook. + <message name="IDS_OPTIONS_ARC_ENABLE" desc="Label for the checkbox that enables Google Play Store apps."> + Enable Google Play Store on your Chromebook. </message> <message name="IDS_OPTIONS_ARC_MANAGE_APPS" desc="Label for launching Android apps settings."> - Manage your Android apps in <ph name="BEGIN_LINK"><a is="action-link" id="android-apps-settings-link" role="link"></ph>Settings<ph name="END_LINK"></a></ph>. + Manage your Android <ph name="BEGIN_LINK"><a is="action-link" id="android-apps-settings-link" role="link"></ph>preferences<ph name="END_LINK"></a></ph>. </message> <message name="IDS_ARC_NOTIFICATION_TITLE" desc="Title of the first-run notification that enables Android apps."> Google Play Store
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index c5211bb..1173e9a 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -465,7 +465,7 @@ No synced tabs </message> <message name="IDS_MD_HISTORY_OPEN_TABS_MENU_ITEM" desc="Label displayed in history sidebar button to display synced tabs from other devices."> - Synced tabs + Tabs from other devices </message> <message name="IDS_MD_HISTORY_SIGN_IN_BUTTON" desc="Label displayed on a button to let user sign in to Chrome to get synced tab history."> Sign in to Chrome @@ -5840,6 +5840,12 @@ <message name="IDS_FLAGS_V8_IGNITION_DESCRIPTION" desc="Description for the flag to enable the JavaScript interpreter."> Enable V8 to use the experimental Ignition interpreter for JavaScript execution. </message> + <message name="IDS_FLAGS_ENABLE_ASM_WASM_NAME" desc="Title for the flag to enable Asm.js to WebAssembly."> + Experimental Validate Asm.js and convert to WebAssembly when valid. + </message> + <message name="IDS_FLAGS_ENABLE_ASM_WASM_DESCRIPTION" desc="Description for the flag to enable Asm.js to WebAssembly."> + Validate Asm.js when "use asm" is present and then convert to WebAssembly. + </message> <message name="IDS_FLAGS_ENABLE_WASM_NAME" desc="Title for the flag to enable WebAssembly."> Experimental WebAssembly </message> @@ -6015,12 +6021,6 @@ <message name="IDS_FLAGS_ASH_ENABLE_UNIFIED_DESKTOP_DESCRIPTION" desc="Description for the flag to enable unified desktop mode."> Enable unified desktop mode which allows a window to span multiple displays. </message> - <message name="IDS_FLAGS_ASH_ENABLE_WINDOW_CYCLE_UI_NAME" desc="Name for the flag to enable the window cycle (Alt+Tab) UI."> - Enable window cycle UI. - </message> - <message name="IDS_FLAGS_ASH_ENABLE_WINDOW_CYCLE_UI_DESCRIPTION" desc="Description for the flag to enable the window cycle (Alt+Tab) UI."> - Enable window cycle UI (visual feedback for Alt+Tab). - </message> <message name="IDS_FLAGS_BOOT_ANIMATION" desc="Name for the flag for wallpaper boot animation (except for OOBE)."> Boot animation </message> @@ -6543,6 +6543,12 @@ <message name="IDS_FLAGS_TRANSLATE_2016Q2_UI_DESCRIPTION" desc="Description for the flag to enable the Translate 2016Q2 UI."> Improved triggering logic and look for Translate Bubble UI </message> + <message name="IDS_FLAGS_TRANSLATE_LANGUAGE_BY_ULP_NAME" desc="Name of the flag to enable the Translate Language by ULP."> + Translate Language by ULP + </message> + <message name="IDS_FLAGS_TRANSLATE_LANGUAGE_BY_ULP_DESCRIPTION" desc="Description for the flag to enable the Translate Language by ULP."> + Improved translate target language and triggering logic by considering information from User Language Profile (ULP). + </message> <message name="IDS_FLAGS_VIEWS_RECT_BASED_TARGETING_NAME" desc="Name of about:flags option for rect-based targeting in views"> Rect-based targeting in views </message> @@ -11812,9 +11818,6 @@ <message name="IDS_SYNC_CHOOSE_DATATYPES" desc="A drop-down menu item for users who want to select some datatypes to sync."> Choose what to sync </message> - <message name="IDS_SYNC_DATATYPE_PREFERENCES" desc="Settings, one of the data types that we allow syncing."> - Settings - </message> <if expr="chromeos"> <message name="IDS_SYNC_DATATYPE_THEMES" desc="Themes, one of the data types that we allow syncing."> Themes & wallpapers @@ -15132,12 +15135,24 @@ <message name="IDS_FLAGS_ENABLE_NTP_SNIPPETS_DESCRIPTION" desc="Description for the flag to enable snippets on the New Tab page." translateable="false"> If enabled, the New Tab page will show a list of content snippets </message> - <message name="IDS_FLAGS_ENABLE_NTP_OFFLINE_PAGE_SUGGESTIONS_NAME" desc="Name for the flag to enable offline page suggestions on the New Tab page." translateable="false"> - Show offline pages on the New Tab page + <message name="IDS_FLAGS_ENABLE_NTP_RECENT_OFFLINE_TAB_SUGGESTIONS_NAME" desc="Name for the flag to enable suggestions for recently viewed tabs, which were captured offline, on the New Tab page." translateable="false"> + Show recent offline tabs on the New Tab page </message> - <message name="IDS_FLAGS_ENABLE_NTP_OFFLINE_PAGE_SUGGESTIONS_DESCRIPTION" desc="Description for the flag to enable offline page suggestions on the New Tab page." translateable="false"> + <message name="IDS_FLAGS_ENABLE_NTP_RECENT_OFFLINE_TAB_SUGGESTIONS_DESCRIPTION" desc="Description for the flag to enable suggestions for recently viewed tabs on the New Tab page." translateable="false"> If enabled, the list of content suggestions on the New Tab page (see #enable-ntp-snippets) will contain pages that were captured offline during browsing (see #offlining-recent-pages) </message> + <message name="IDS_FLAGS_ENABLE_NTP_SAVE_TO_OFFLINE_NAME" desc="Name for the flag to enable offline page suggestions on the New Tab page." translateable="false"> + Show option to save to offline in Snippets context menu. + </message> + <message name="IDS_FLAGS_ENABLE_NTP_SAVE_TO_OFFLINE_DESCRIPTION" desc="Description for the flag to enable offline page suggestions on the New Tab page." translateable="false"> + If enabled, the Snippets context menu (see #enable-ntp-snippets) will contain the option to save linked page for offline viewing. + </message> + <message name="IDS_FLAGS_ENABLE_NTP_DOWNLOAD_SUGGESTIONS_NAME" desc="Name for the flag to enable downloads suggestions on the New Tab page." translateable="false"> + Show downloads on the New Tab page + </message> + <message name="IDS_FLAGS_ENABLE_NTP_DOWNLOAD_SUGGESTIONS_DESCRIPTION" desc="Description for the flag to enable downloads suggestions on the New Tab page." translateable="false"> + If enabled, the list of content suggestions on the New Tab page (see #enable-ntp-snippets) will contain pages that the user downloaded for later use. + </message> <message name="IDS_FLAGS_ENABLE_NTP_BOOKMARK_SUGGESTIONS_NAME" desc="Name for the flag to enable bookmark suggestions on the New Tab page." translateable="false"> Show recently visited bookmarks on the New Tab page </message>
diff --git a/chrome/app/mash/mash_runner.cc b/chrome/app/mash/mash_runner.cc index a2b3a0bd..a0860be1 100644 --- a/chrome/app/mash/mash_runner.cc +++ b/chrome/app/mash/mash_runner.cc
@@ -66,7 +66,7 @@ // ServiceFactory: void CreateService(shell::mojom::ServiceRequest request, - const mojo::String& mojo_name) override { + const std::string& mojo_name) override { if (service_) { LOG(ERROR) << "request to create additional service " << mojo_name; return;
diff --git a/chrome/app/nibs/ContentSubresourceFilter.xib b/chrome/app/nibs/ContentSubresourceFilter.xib index 2cbceee..f55aa9e 100644 --- a/chrome/app/nibs/ContentSubresourceFilter.xib +++ b/chrome/app/nibs/ContentSubresourceFilter.xib
@@ -68,7 +68,7 @@ </subviews> </customView> <textField verticalHuggingPriority="750" id="7"> - <rect key="frame" x="17" y="100" width="282" height="14"/> + <rect key="frame" x="8" y="68" width="282" height="14"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> <textFieldCell key="cell" controlSize="small" sendsActionOnEndEditing="YES" title="^IDS_FILTERED_DECEPTIVE_CONTENT_PROMPT_EXPLANATION" id="8"> <font key="font" metaFont="smallSystem"/> @@ -76,6 +76,15 @@ <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> </textFieldCell> </textField> + <textField verticalHuggingPriority="750" id="dgF-Po-kkg"> + <rect key="frame" x="8" y="86" width="282" height="28"/> + <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/> + <textFieldCell key="cell" controlSize="small" sendsActionOnEndEditing="YES" title="^IDS_FILTERED_DECEPTIVE_CONTENT_PROMPT_TITLE" id="AxL-Md-rce"> + <font key="font" metaFont="smallSystem"/> + <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> + <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/> + </textFieldCell> + </textField> </subviews> </customView> </subviews>
diff --git a/chrome/app/theme/default_100_percent/common/bookmark_bar_folder.png b/chrome/app/theme/default_100_percent/common/bookmark_bar_folder.png deleted file mode 100644 index 4f6eee20..0000000 --- a/chrome/app/theme/default_100_percent/common/bookmark_bar_folder.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_100_percent/cros/consumer_management_notification_icon.png b/chrome/app/theme/default_100_percent/cros/consumer_management_notification_icon.png deleted file mode 100644 index dc2e839..0000000 --- a/chrome/app/theme/default_100_percent/cros/consumer_management_notification_icon.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_100_percent/win/bookmark_bar_folder.png b/chrome/app/theme/default_100_percent/win/bookmark_bar_folder.png new file mode 100644 index 0000000..21a0de0 --- /dev/null +++ b/chrome/app/theme/default_100_percent/win/bookmark_bar_folder.png Binary files differ
diff --git a/chrome/app/theme/default_100_percent/win/bookmark_bar_folder_managed.png b/chrome/app/theme/default_100_percent/win/bookmark_bar_folder_managed.png index 4485f14..25c08056 100644 --- a/chrome/app/theme/default_100_percent/win/bookmark_bar_folder_managed.png +++ b/chrome/app/theme/default_100_percent/win/bookmark_bar_folder_managed.png Binary files differ
diff --git a/chrome/app/theme/default_100_percent/win/bookmark_bar_folder_supervised.png b/chrome/app/theme/default_100_percent/win/bookmark_bar_folder_supervised.png index 5e433679..c9862f0 100644 --- a/chrome/app/theme/default_100_percent/win/bookmark_bar_folder_supervised.png +++ b/chrome/app/theme/default_100_percent/win/bookmark_bar_folder_supervised.png Binary files differ
diff --git a/chrome/app/theme/default_200_percent/common/bookmark_bar_folder.png b/chrome/app/theme/default_200_percent/common/bookmark_bar_folder.png deleted file mode 100644 index 3ca76aaa..0000000 --- a/chrome/app/theme/default_200_percent/common/bookmark_bar_folder.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/cros/consumer_management_notification_icon.png b/chrome/app/theme/default_200_percent/cros/consumer_management_notification_icon.png deleted file mode 100644 index 9f278bf..0000000 --- a/chrome/app/theme/default_200_percent/cros/consumer_management_notification_icon.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/win/bookmark_bar_folder.png b/chrome/app/theme/default_200_percent/win/bookmark_bar_folder.png new file mode 100644 index 0000000..28bd3b8d --- /dev/null +++ b/chrome/app/theme/default_200_percent/win/bookmark_bar_folder.png Binary files differ
diff --git a/chrome/app/theme/default_200_percent/win/bookmark_bar_folder_managed.png b/chrome/app/theme/default_200_percent/win/bookmark_bar_folder_managed.png index 7e6127e..79abb5c 100644 --- a/chrome/app/theme/default_200_percent/win/bookmark_bar_folder_managed.png +++ b/chrome/app/theme/default_200_percent/win/bookmark_bar_folder_managed.png Binary files differ
diff --git a/chrome/app/theme/default_200_percent/win/bookmark_bar_folder_supervised.png b/chrome/app/theme/default_200_percent/win/bookmark_bar_folder_supervised.png index 18de87f..0ef83ec 100644 --- a/chrome/app/theme/default_200_percent/win/bookmark_bar_folder_supervised.png +++ b/chrome/app/theme/default_200_percent/win/bookmark_bar_folder_supervised.png Binary files differ
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index f0119de8..c36c357 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd
@@ -122,10 +122,8 @@ <structure type="chrome_scaled_image" name="IDR_BOOKMARK_BAR_FOLDER_MANAGED_WHITE" file="mac/bookmark_bar_folder_managed_white.png" /> <structure type="chrome_scaled_image" name="IDR_BOOKMARK_BAR_FOLDER_SUPERVISED_WHITE" file="mac/bookmark_bar_folder_supervised_white.png" /> </if> - <if expr="not is_macosx and not is_ios"> - <structure type="chrome_scaled_image" name="IDR_BOOKMARK_BAR_FOLDER" file="common/bookmark_bar_folder.png" /> - </if> <if expr="is_win"> + <structure type="chrome_scaled_image" name="IDR_BOOKMARK_BAR_FOLDER" file="win/bookmark_bar_folder.png" /> <structure type="chrome_scaled_image" name="IDR_BOOKMARK_BAR_FOLDER_MANAGED" file="win/bookmark_bar_folder_managed.png" /> <structure type="chrome_scaled_image" name="IDR_BOOKMARK_BAR_FOLDER_SUPERVISED" file="win/bookmark_bar_folder_supervised.png" /> </if> @@ -149,9 +147,6 @@ <if expr="is_win"> <structure type="chrome_scaled_image" name="IDR_CONFLICT_FAVICON" file="common/favicon_conflicts.png" /> </if> - <if expr="chromeos"> - <structure type="chrome_scaled_image" name="IDR_CONSUMER_MANAGEMENT_NOTIFICATION_ICON" file="cros/consumer_management_notification_icon.png" /> - </if> <!-- Ash doesn't draw rounded content area, so needs a special top image. --> <if expr="not use_ash">
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 5d213c7..9f30beaf 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -167,7 +167,6 @@ "//components/supervised_user_error_page", "//components/sync", "//components/sync_bookmarks", - "//components/sync_driver", "//components/sync_sessions", "//components/tracing:startup_tracing", "//components/translate/core/browser", @@ -1217,8 +1216,6 @@ "chromeos/policy/cloud_external_data_manager_base_test_util.h", "chromeos/policy/device_policy_builder.cc", "chromeos/policy/device_policy_builder.h", - "chromeos/policy/fake_consumer_management_service.cc", - "chromeos/policy/fake_consumer_management_service.h", "chromeos/policy/fake_device_cloud_policy_initializer.cc", "chromeos/policy/fake_device_cloud_policy_initializer.h", "chromeos/policy/fake_device_cloud_policy_manager.cc",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index afe1798c..13bffe0 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS
@@ -40,7 +40,6 @@ "+mojo/converters", "+mojo/runner/child", "+services/shell/public/cpp", - "+services/ui/common", # TODO(sad): Should be removed: crbug.com/634377 "+services/ui/public", "+policy", # For generated headers and source "+ppapi/c", # For various types.
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index bd408e0..5a01c86 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -56,8 +56,9 @@ #include "components/signin/core/common/signin_switches.h" #include "components/spellcheck/common/spellcheck_switches.h" #include "components/ssl_config/ssl_config_switches.h" -#include "components/sync_driver/sync_driver_switches.h" +#include "components/sync/driver/sync_driver_switches.h" #include "components/tracing/common/tracing_switches.h" +#include "components/translate/core/browser/translate_manager.h" #include "components/translate/core/browser/translate_prefs.h" #include "components/version_info/version_info.h" #include "content/public/browser/user_metrics.h" @@ -810,6 +811,9 @@ {"enable-javascript-harmony", IDS_FLAGS_JAVASCRIPT_HARMONY_NAME, IDS_FLAGS_JAVASCRIPT_HARMONY_DESCRIPTION, kOsAll, SINGLE_VALUE_TYPE(switches::kJavaScriptHarmony)}, + {"enable-asm-webassembly", IDS_FLAGS_ENABLE_ASM_WASM_NAME, + IDS_FLAGS_ENABLE_ASM_WASM_DESCRIPTION, kOsAll, + SINGLE_VALUE_TYPE(switches::kEnableAsmWasm)}, {"enable-webassembly", IDS_FLAGS_ENABLE_WASM_NAME, IDS_FLAGS_ENABLE_WASM_DESCRIPTION, kOsAll, SINGLE_VALUE_TYPE(switches::kEnableWasm)}, @@ -907,9 +911,6 @@ {"ash-enable-unified-desktop", IDS_FLAGS_ASH_ENABLE_UNIFIED_DESKTOP_NAME, IDS_FLAGS_ASH_ENABLE_UNIFIED_DESKTOP_DESCRIPTION, kOsCrOS, SINGLE_VALUE_TYPE(ash::switches::kAshEnableUnifiedDesktop)}, - {"ash-enable-window-cycle-ui", IDS_FLAGS_ASH_ENABLE_WINDOW_CYCLE_UI_NAME, - IDS_FLAGS_ASH_ENABLE_WINDOW_CYCLE_UI_DESCRIPTION, kOsCrOS, - SINGLE_VALUE_TYPE(ash::switches::kAshEnableWindowCycleUi)}, {"enable-easy-unlock-proximity-detection", IDS_FLAGS_EASY_UNLOCK_PROXIMITY_DETECTION_NAME, IDS_FLAGS_EASY_UNLOCK_PROXIMITY_DETECTION_DESCRIPTION, kOsCrOS, @@ -1283,7 +1284,7 @@ IDS_FLAGS_SHOW_ALL_BOOKMARKS_VIEW_DESCRIPTION, kOsAndroid, FEATURE_VALUE_TYPE(chrome::android::kAllBookmarksFeature)}, {"enable-downloads-ui", IDS_FLAGS_ENABLE_DOWNLOADS_UI_NAME, - IDS_FLAGS_ENABLE_DOWNLOADS_UI_DESCRIPTION, kOsAndroid, + IDS_FLAGS_ENABLE_DOWNLOADS_UI_DESCRIPTION, kOsAndroid, FEATURE_VALUE_TYPE(chrome::android::kDownloadsUiFeature)}, {"enable-accessibility-tab-switcher", IDS_FLAGS_ACCESSIBILITY_TAB_SWITCHER_NAME, @@ -1337,6 +1338,9 @@ IDS_FLAGS_TRANSLATE_2016Q2_UI_DESCRIPTION, kOsCrOS | kOsWin | kOsLinux, FEATURE_VALUE_TYPE(translate::kTranslateUI2016Q2)}, #endif + {"translate-lang-by-ulp", IDS_FLAGS_TRANSLATE_LANGUAGE_BY_ULP_NAME, + IDS_FLAGS_TRANSLATE_LANGUAGE_BY_ULP_DESCRIPTION, kOsAll, + FEATURE_VALUE_TYPE(translate::kTranslateLanguageByULP)}, #if defined(OS_MACOSX) {"enable-native-notifications", IDS_NOTIFICATIONS_NATIVE_FLAG, IDS_NOTIFICATIONS_NATIVE_FLAG_DESCRIPTION, kOsMac, @@ -1902,10 +1906,19 @@ ntp_snippets::kContentSuggestionsFeature, kNTPSnippetsFeatureVariations, ntp_snippets::kStudyName)}, - {"enable-ntp-offline-page-suggestions", - IDS_FLAGS_ENABLE_NTP_OFFLINE_PAGE_SUGGESTIONS_NAME, - IDS_FLAGS_ENABLE_NTP_OFFLINE_PAGE_SUGGESTIONS_DESCRIPTION, kOsAndroid, - FEATURE_VALUE_TYPE(ntp_snippets::kOfflinePageSuggestionsFeature)}, + {"enable-ntp-save-to-offline", + IDS_FLAGS_ENABLE_NTP_SAVE_TO_OFFLINE_NAME, + IDS_FLAGS_ENABLE_NTP_SAVE_TO_OFFLINE_DESCRIPTION, kOsAndroid, + FEATURE_VALUE_TYPE(ntp_snippets::kSaveToOfflineFeature)}, + {"enable-ntp-recent-offline-tab-suggestions", + IDS_FLAGS_ENABLE_NTP_RECENT_OFFLINE_TAB_SUGGESTIONS_NAME, + IDS_FLAGS_ENABLE_NTP_RECENT_OFFLINE_TAB_SUGGESTIONS_DESCRIPTION, + kOsAndroid, + FEATURE_VALUE_TYPE(ntp_snippets::kRecentOfflineTabSuggestionsFeature)}, + {"enable-ntp-download-suggestions", + IDS_FLAGS_ENABLE_NTP_DOWNLOAD_SUGGESTIONS_NAME, + IDS_FLAGS_ENABLE_NTP_DOWNLOAD_SUGGESTIONS_DESCRIPTION, kOsAndroid, + FEATURE_VALUE_TYPE(ntp_snippets::kDownloadSuggestionsFeature)}, {"enable-ntp-bookmark-suggestions", IDS_FLAGS_ENABLE_NTP_BOOKMARK_SUGGESTIONS_NAME, IDS_FLAGS_ENABLE_NTP_BOOKMARK_SUGGESTIONS_DESCRIPTION, kOsAndroid,
diff --git a/chrome/browser/after_startup_task_utils.cc b/chrome/browser/after_startup_task_utils.cc index 0d0eab6..c5c29e8 100644 --- a/chrome/browser/after_startup_task_utils.cc +++ b/chrome/browser/after_startup_task_utils.cc
@@ -192,6 +192,27 @@ } // namespace +AfterStartupTaskUtils::Runner::Runner( + scoped_refptr<base::TaskRunner> destination_runner) + : destination_runner_(std::move(destination_runner)) { + DCHECK(destination_runner_); +} + +AfterStartupTaskUtils::Runner::~Runner() = default; + +bool AfterStartupTaskUtils::Runner::PostDelayedTask( + const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeDelta delay) { + DCHECK(delay.is_zero()); + AfterStartupTaskUtils::PostTask(from_here, destination_runner_, task); + return true; +} + +bool AfterStartupTaskUtils::Runner::RunsTasksOnCurrentThread() const { + return destination_runner_->RunsTasksOnCurrentThread(); +} + void AfterStartupTaskUtils::StartMonitoringStartup() { // The observer is self-deleting. (new StartupObserver)->Start(); @@ -199,15 +220,15 @@ void AfterStartupTaskUtils::PostTask( const tracked_objects::Location& from_here, - const scoped_refptr<base::TaskRunner>& task_runner, + const scoped_refptr<base::TaskRunner>& destination_runner, const base::Closure& task) { if (IsBrowserStartupComplete()) { - task_runner->PostTask(from_here, task); + destination_runner->PostTask(from_here, task); return; } std::unique_ptr<AfterStartupTask> queued_task( - new AfterStartupTask(from_here, task_runner, task)); + new AfterStartupTask(from_here, destination_runner, task)); QueueTask(std::move(queued_task)); }
diff --git a/chrome/browser/after_startup_task_utils.h b/chrome/browser/after_startup_task_utils.h index 77388dd..1975130 100644 --- a/chrome/browser/after_startup_task_utils.h +++ b/chrome/browser/after_startup_task_utils.h
@@ -8,29 +8,45 @@ #include "base/bind.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/task_runner.h" namespace android { class AfterStartupTaskUtilsJNI; } -namespace base { -class TaskRunner; -} -namespace tracked_objects { -class Location; -}; - class AfterStartupTaskUtils { public: + // A helper TaskRunner which merely forwards to + // AfterStartupTaskUtils::PostTask(). Doesn't support tasks with a non-zero + // delay. + class Runner : public base::TaskRunner { + public: + explicit Runner(scoped_refptr<base::TaskRunner> destination_runner); + + // Overrides from base::TaskRunner: + bool PostDelayedTask(const tracked_objects::Location& from_here, + const base::Closure& task, + base::TimeDelta delay) override; + bool RunsTasksOnCurrentThread() const override; + + private: + ~Runner() override; + + const scoped_refptr<base::TaskRunner> destination_runner_; + + DISALLOW_COPY_AND_ASSIGN(Runner); + }; + // Observes startup and when complete runs tasks that have accrued. static void StartMonitoringStartup(); // Used to augment the behavior of BrowserThread::PostAfterStartupTask // for chrome. Tasks are queued until startup is complete. // Note: see browser_thread.h - static void PostTask(const tracked_objects::Location& from_here, - const scoped_refptr<base::TaskRunner>& task_runner, - const base::Closure& task); + static void PostTask( + const tracked_objects::Location& from_here, + const scoped_refptr<base::TaskRunner>& destination_runner, + const base::Closure& task); // Returns true if browser startup is complete. Only use this on a one-off // basis; If you need to poll this function constantly, use the above
diff --git a/chrome/browser/after_startup_task_utils_unittest.cc b/chrome/browser/after_startup_task_utils_unittest.cc index 5dd16a7..c1433b7 100644 --- a/chrome/browser/after_startup_task_utils_unittest.cc +++ b/chrome/browser/after_startup_task_utils_unittest.cc
@@ -198,3 +198,29 @@ EXPECT_EQ(2, db_thread_->ran_task_count()); EXPECT_EQ(2, ui_thread_->ran_task_count()); } + +// Verify that posting to an AfterStartupTaskUtils::Runner bound to |db_thread_| +// results in the same behavior as posting via +// AfterStartupTaskUtils::PostTask(..., db_thread_, ...). +TEST_F(AfterStartupTaskTest, AfterStartupTaskUtilsRunner) { + scoped_refptr<base::TaskRunner> after_startup_runner = + make_scoped_refptr(new AfterStartupTaskUtils::Runner(db_thread_)); + + EXPECT_FALSE(AfterStartupTaskUtils::IsBrowserStartupComplete()); + after_startup_runner->PostTask( + FROM_HERE, base::Bind(&AfterStartupTaskTest::VerifyExpectedThread, + BrowserThread::DB)); + + RunLoop().RunUntilIdle(); + EXPECT_FALSE(AfterStartupTaskUtils::IsBrowserStartupComplete()); + EXPECT_EQ(0, db_thread_->total_task_count()); + + AfterStartupTaskUtils::SetBrowserStartupIsCompleteForTesting(); + EXPECT_EQ(1, db_thread_->posted_task_count()); + + FlushDBThread(); + RunLoop().RunUntilIdle(); + EXPECT_EQ(1, db_thread_->ran_task_count()); + + EXPECT_EQ(0, ui_thread_->total_task_count()); +}
diff --git a/chrome/browser/android/banners/app_banner_infobar_delegate_android.cc b/chrome/browser/android/banners/app_banner_infobar_delegate_android.cc index 04b164f..0ad21075 100644 --- a/chrome/browser/android/banners/app_banner_infobar_delegate_android.cc +++ b/chrome/browser/android/banners/app_banner_infobar_delegate_android.cc
@@ -23,7 +23,6 @@ #include "chrome/common/render_messages.h" #include "chrome/grit/generated_resources.h" #include "components/rappor/rappor_utils.h" -#include "content/public/browser/browser_thread.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "content/public/common/manifest.h" @@ -262,11 +261,9 @@ info.UpdateSource(ShortcutInfo::SOURCE_APP_BANNER); const std::string& uid = base::GenerateGUID(); - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::Bind(&ShortcutHelper::AddToLauncherInBackgroundWithSkBitmap, - web_contents->GetBrowserContext(), info, uid, *icon_.get(), - weak_manager_->FetchWebappSplashScreenImageCallback(uid))); + ShortcutHelper::AddToLauncherWithSkBitmap( + web_contents->GetBrowserContext(), info, uid, *icon_.get(), + weak_manager_->FetchWebappSplashScreenImageCallback(uid)); } SendBannerAccepted(web_contents, "web");
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index 8de418c..10d9b20 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -39,6 +39,7 @@ &kAndroidPayIntegrationV1, &kImportantSitesInCBD, &ntp_snippets::kContentSuggestionsFeature, + &ntp_snippets::kSaveToOfflineFeature, &kNTPFakeOmniboxTextFeature, &kNTPMaterialDesign, &kNTPOfflinePagesFeature,
diff --git a/chrome/browser/android/foreign_session_helper.h b/chrome/browser/android/foreign_session_helper.h index 501fa12..308deb0 100644 --- a/chrome/browser/android/foreign_session_helper.h +++ b/chrome/browser/android/foreign_session_helper.h
@@ -11,7 +11,7 @@ #include "base/macros.h" #include "base/scoped_observer.h" #include "chrome/browser/profiles/profile.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/sync_service_observer.h" using base::android::ScopedJavaLocalRef;
diff --git a/chrome/browser/android/metrics/uma_session_stats.cc b/chrome/browser/android/metrics/uma_session_stats.cc index 4b8c6ab..8afb993 100644 --- a/chrome/browser/android/metrics/uma_session_stats.cc +++ b/chrome/browser/android/metrics/uma_session_stats.cc
@@ -144,6 +144,9 @@ &experiment_ids); } + UMA_HISTOGRAM_COUNTS_100("UMA.ExternalExperiment.GroupCount", + experiment_ids.size()); + std::vector<uint32_t> group_name_hashes; group_name_hashes.reserve(experiment_ids.size());
diff --git a/chrome/browser/android/ntp/ntp_snippets_bridge.cc b/chrome/browser/android/ntp/ntp_snippets_bridge.cc index 5818ae0..ad10f01d 100644 --- a/chrome/browser/android/ntp/ntp_snippets_bridge.cc +++ b/chrome/browser/android/ntp/ntp_snippets_bridge.cc
@@ -141,13 +141,20 @@ return base::android::ScopedJavaLocalRef<jobject>(env, nullptr); return Java_SnippetsBridge_createSuggestionsCategoryInfo( env, ConvertUTF16ToJavaString(env, info->title()).obj(), - static_cast<int>(info->card_layout())); + static_cast<int>(info->card_layout()), info->has_more_button()); } ScopedJavaLocalRef<jobject> NTPSnippetsBridge::GetSuggestionsForCategory( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, jint category) { + // Get layout for the category. + base::Optional<CategoryInfo> info = + content_suggestions_service_->GetCategoryInfo( + content_suggestions_service_->category_factory()->FromIDValue( + category)); + DCHECK(info); + const std::vector<ContentSuggestion>& suggestions = content_suggestions_service_->GetSuggestionsForCategory( content_suggestions_service_->category_factory()->FromIDValue( @@ -162,7 +169,8 @@ ConvertUTF16ToJavaString(env, suggestion.snippet_text()).obj(), ConvertUTF8ToJavaString(env, suggestion.url().spec()).obj(), ConvertUTF8ToJavaString(env, suggestion.amp_url().spec()).obj(), - suggestion.publish_date().ToJavaTime(), suggestion.score()); + suggestion.publish_date().ToJavaTime(), suggestion.score(), + static_cast<int>(info->card_layout())); } return result; }
diff --git a/chrome/browser/android/offline_pages/downloads/offline_page_download_bridge.cc b/chrome/browser/android/offline_pages/downloads/offline_page_download_bridge.cc index 4ae4a7e..585aa8e 100644 --- a/chrome/browser/android/offline_pages/downloads/offline_page_download_bridge.cc +++ b/chrome/browser/android/offline_pages/downloads/offline_page_download_bridge.cc
@@ -14,6 +14,7 @@ #include "components/offline_pages/offline_page_model.h" #include "jni/OfflinePageDownloadBridge_jni.h" #include "net/base/filename_util.h" +#include "url/gurl.h" using base::android::AttachCurrentThread; using base::android::ConvertJavaStringToUTF8; @@ -27,16 +28,16 @@ namespace { -void ToJavaOfflinePageDownloadItemList(JNIEnv* env, - jobject j_result_obj, - const DownloadUIItemsMap& items_map) { - for (const auto& guid_item_pair : items_map) { - const DownloadUIItem& item = *(guid_item_pair.second.get()); +void ToJavaOfflinePageDownloadItemList( + JNIEnv* env, + jobject j_result_obj, + const std::vector<const DownloadUIItem*>& items) { + for (const auto item : items) { Java_OfflinePageDownloadBridge_createDownloadItemAndAddToList( - env, j_result_obj, ConvertUTF8ToJavaString(env, item.guid).obj(), - ConvertUTF8ToJavaString(env, item.url.spec()).obj(), - ConvertUTF8ToJavaString(env, item.target_path.value()).obj(), - item.start_time.ToJavaTime(), item.total_bytes); + env, j_result_obj, ConvertUTF8ToJavaString(env, item->guid).obj(), + ConvertUTF8ToJavaString(env, item->url.spec()).obj(), + ConvertUTF8ToJavaString(env, item->target_path.value()).obj(), + item->start_time.ToJavaTime(), item->total_bytes); } } @@ -80,19 +81,39 @@ const JavaParamRef<jobject>& j_result_obj) { DCHECK(j_result_obj); - const DownloadUIItemsMap& items_map = download_ui_adapter_->GetAllItems(); - ToJavaOfflinePageDownloadItemList(env, j_result_obj, items_map); + std::vector<const DownloadUIItem*> items = + download_ui_adapter_->GetAllItems(); + ToJavaOfflinePageDownloadItemList(env, j_result_obj, items); } ScopedJavaLocalRef<jobject> OfflinePageDownloadBridge::GetItemByGuid( JNIEnv* env, const JavaParamRef<jobject>& obj, - const base::android::JavaParamRef<jstring>& j_guid) { + const JavaParamRef<jstring>& j_guid) { std::string guid = ConvertJavaStringToUTF8(env, j_guid); const DownloadUIItem* item = download_ui_adapter_->GetItem(guid); return ToJavaOfflinePageDownloadItem(env, *item); } +void OfflinePageDownloadBridge::DeleteItemByGuid( + JNIEnv* env, + const JavaParamRef<jobject>& obj, + const JavaParamRef<jstring>& j_guid) { + std::string guid = ConvertJavaStringToUTF8(env, j_guid); + download_ui_adapter_->DeleteItem(guid); +} + +ScopedJavaLocalRef<jstring> OfflinePageDownloadBridge::GetOfflineUrlByGuid( + JNIEnv* env, + const JavaParamRef<jobject>& obj, + const JavaParamRef<jstring>& j_guid) { + std::string guid = ConvertJavaStringToUTF8(env, j_guid); + GURL url = download_ui_adapter_->GetOfflineUrlByGuid(guid); + if (!url.is_valid()) + return ScopedJavaLocalRef<jstring>(); + return ConvertUTF8ToJavaString(env, url.spec()); +} + void OfflinePageDownloadBridge::ItemsLoaded() { JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jobject> obj = weak_java_ref_.get(env);
diff --git a/chrome/browser/android/offline_pages/downloads/offline_page_download_bridge.h b/chrome/browser/android/offline_pages/downloads/offline_page_download_bridge.h index 0421b6c..ad394feb 100644 --- a/chrome/browser/android/offline_pages/downloads/offline_page_download_bridge.h +++ b/chrome/browser/android/offline_pages/downloads/offline_page_download_bridge.h
@@ -44,6 +44,15 @@ const base::android::JavaParamRef<jobject>& obj, const base::android::JavaParamRef<jstring>& j_guid); + void DeleteItemByGuid(JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jstring>& j_guid); + + base::android::ScopedJavaLocalRef<jstring> GetOfflineUrlByGuid( + JNIEnv* env, + const base::android::JavaParamRef<jobject>& obj, + const base::android::JavaParamRef<jstring>& j_guid); + // DownloadUIAdapter::Observer implementation. void ItemsLoaded() override; void ItemAdded(const DownloadUIItem& item) override;
diff --git a/chrome/browser/android/offline_pages/offline_page_bridge.cc b/chrome/browser/android/offline_pages/offline_page_bridge.cc index 9400fe3..b5be9a6 100644 --- a/chrome/browser/android/offline_pages/offline_page_bridge.cc +++ b/chrome/browser/android/offline_pages/offline_page_bridge.cc
@@ -184,6 +184,13 @@ return ScopedJavaLocalRef<jobject>(bridge->java_ref()); } +// static +ScopedJavaLocalRef<jobject> OfflinePageBridge::ConvertToJavaOfflinePage( + JNIEnv* env, + const OfflinePageItem& offline_page) { + return ToJavaOfflinePageItem(env, offline_page); +} + OfflinePageBridge::OfflinePageBridge(JNIEnv* env, content::BrowserContext* browser_context, OfflinePageModel* offline_page_model) @@ -301,16 +308,22 @@ return ToJavaOfflinePageItem(env, *offline_page); } -ScopedJavaLocalRef<jobject> OfflinePageBridge::GetBestPageForOnlineURL( +void OfflinePageBridge::SelectPageForOnlineUrl( JNIEnv* env, const JavaParamRef<jobject>& obj, - const JavaParamRef<jstring>& online_url) { - const OfflinePageItem* offline_page = - offline_page_model_->MaybeGetBestPageForOnlineURL( - GURL(ConvertJavaStringToUTF8(env, online_url))); - if (!offline_page) - return ScopedJavaLocalRef<jobject>(); - return ToJavaOfflinePageItem(env, *offline_page); + const JavaParamRef<jstring>& j_online_url, + int tab_id, + const JavaParamRef<jobject>& j_callback_obj) { + DCHECK(j_callback_obj); + + ScopedJavaGlobalRef<jobject> j_callback_ref; + j_callback_ref.Reset(env, j_callback_obj); + + OfflinePageUtils::SelectPageForOnlineURL( + browser_context_, + GURL(ConvertJavaStringToUTF8(env, j_online_url)), + tab_id, + base::Bind(&SingleOfflinePageItemCallback, j_callback_ref)); } void OfflinePageBridge::GetPageByOfflineUrl(
diff --git a/chrome/browser/android/offline_pages/offline_page_bridge.h b/chrome/browser/android/offline_pages/offline_page_bridge.h index 5dbe1cb..58d80423 100644 --- a/chrome/browser/android/offline_pages/offline_page_bridge.h +++ b/chrome/browser/android/offline_pages/offline_page_bridge.h
@@ -9,6 +9,7 @@ #include "base/android/jni_android.h" #include "base/android/jni_weak_ref.h" +#include "base/android/scoped_java_ref.h" #include "base/macros.h" #include "base/supports_user_data.h" #include "components/offline_pages/offline_page_item.h" @@ -28,6 +29,10 @@ class OfflinePageBridge : public OfflinePageModel::Observer, public base::SupportsUserData::Data { public: + static base::android::ScopedJavaLocalRef<jobject> ConvertToJavaOfflinePage( + JNIEnv* env, + const OfflinePageItem& offline_page); + OfflinePageBridge(JNIEnv* env, content::BrowserContext* browser_context, OfflinePageModel* offline_page_model); @@ -66,10 +71,12 @@ const base::android::JavaParamRef<jobject>& obj, jlong offline_id); - base::android::ScopedJavaLocalRef<jobject> GetBestPageForOnlineURL( + void SelectPageForOnlineUrl( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, - const base::android::JavaParamRef<jstring>& online_url); + const base::android::JavaParamRef<jstring>& j_online_url, + int tab_id, + const base::android::JavaParamRef<jobject>& j_callback_obj); void GetPageByOfflineUrl( JNIEnv* env,
diff --git a/chrome/browser/android/offline_pages/offline_page_request_handler.cc b/chrome/browser/android/offline_pages/offline_page_request_handler.cc new file mode 100644 index 0000000..0e9056c --- /dev/null +++ b/chrome/browser/android/offline_pages/offline_page_request_handler.cc
@@ -0,0 +1,105 @@ +// Copyright 2016 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/android/offline_pages/offline_page_request_handler.h" + +#include "components/offline_pages/offline_page_feature.h" +#include "content/public/browser/browser_thread.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_interceptor.h" + +namespace offline_pages { + +namespace { + +int kUserDataKey; // Only address is used. + +// An interceptor to hijack requests and potentially service them based on +// their offline information. +class OfflinePageRequestInterceptor : public net::URLRequestInterceptor { + public: + explicit OfflinePageRequestInterceptor(void* profile_id) + : profile_id_(profile_id) { + DCHECK(profile_id); + } + ~OfflinePageRequestInterceptor() override {} + + private: + // Overrides from net::URLRequestInterceptor: + net::URLRequestJob* MaybeInterceptRequest( + net::URLRequest* request, + net::NetworkDelegate* network_delegate) const override { + OfflinePageRequestHandler* handler = OfflinePageRequestHandler::GetHandler( + request); + if (!handler) + return nullptr; + return handler->MaybeCreateJob(request, network_delegate, profile_id_); + } + + // The profile for processing offline pages. + void* const profile_id_; + + DISALLOW_COPY_AND_ASSIGN(OfflinePageRequestInterceptor); +}; + +} // namespace + +// static +void OfflinePageRequestHandler::InitializeHandler( + net::URLRequest* request, + content::ResourceType resource_type) { + if (!IsOfflinePagesEnabled()) + return; + + // Ignore the requests not for the main resource. + if (resource_type != content::RESOURCE_TYPE_MAIN_FRAME) + return; + + // Ignore non-http/https requests. + if (!request->url().SchemeIsHTTPOrHTTPS()) + return; + + // Ignore requests other than GET. + if (request->method() != "GET") + return; + + // Any more precise checks to see if the request should be intercepted are + // asynchronous, so just create our handler in all cases. + request->SetUserData(&kUserDataKey, new OfflinePageRequestHandler()); +} + +// static +OfflinePageRequestHandler* OfflinePageRequestHandler::GetHandler( + net::URLRequest* request) { + return static_cast<OfflinePageRequestHandler*>( + request->GetUserData(&kUserDataKey)); +} + +// static +std::unique_ptr<net::URLRequestInterceptor> +OfflinePageRequestHandler::CreateInterceptor(void* profile_id) { + if (!IsOfflinePagesEnabled()) + return nullptr; + + return std::unique_ptr<net::URLRequestInterceptor>( + new OfflinePageRequestInterceptor(profile_id)); +} + +OfflinePageRequestHandler::OfflinePageRequestHandler() { +} + +OfflinePageRequestHandler::~OfflinePageRequestHandler() { +} + +net::URLRequestJob* OfflinePageRequestHandler::MaybeCreateJob( + net::URLRequest* request, + net::NetworkDelegate* network_delegate, + void* profile_id) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + + // TODO(jianli): to be implemented. + return nullptr; +} + +} // namespace offline_pages
diff --git a/chrome/browser/android/offline_pages/offline_page_request_handler.h b/chrome/browser/android/offline_pages/offline_page_request_handler.h new file mode 100644 index 0000000..3504028 --- /dev/null +++ b/chrome/browser/android/offline_pages/offline_page_request_handler.h
@@ -0,0 +1,73 @@ +// Copyright 2016 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_ANDROID_OFFLINE_PAGES_OFFLINE_PAGE_REQUEST_HANDLER_H_ +#define CHROME_BROWSER_ANDROID_OFFLINE_PAGES_OFFLINE_PAGE_REQUEST_HANDLER_H_ + +#include "base/macros.h" +#include "base/supports_user_data.h" +#include "content/public/common/resource_type.h" + +namespace net { +class NetworkDelegate; +class URLRequest; +class URLRequestInterceptor; +class URLRequestJob; +} + +namespace offline_pages { + +// Class for servicing requests based on their offline information. Created one +// per URLRequest and attached to each request. +// +// For each supported profile, OfflinePageRequestHandler::CreateInterceptor +// should be called once to install the custom interceptor. +// +// For each request: +// 1) When a request is starting, OfflinePageRequestHandler::InitializeHandler +// will be called to create a new handler and attach to the request. +// 2) When a request is being processed, MaybeInterceptRequest of custom +// interceptor will be inquired. +// 2.1) If the attached OfflinePageRequestHandler for the request is found, +// delegate to OfflinePageRequestHandler::MaybeCreateJob to do the work. +// 2.1.1) Do immediate checks for those scenarios that the interception +// is not needed. Bail out if so. +// 2.1.2) Start an async task to try to find the offline page. +// 2.1.3) Return a custom URLRequestJob that is put on hold to wait +// for the result of finding offline page. +// 2.2) Otherwise, bail out without interception. +class OfflinePageRequestHandler : public base::SupportsUserData::Data { + public: + // Attaches a newly created handler if the given |request| needs to + // be handled by offline pages. + static void InitializeHandler(net::URLRequest* request, + content::ResourceType resource_type); + + // Returns the handler attached to |request|. This may return null if no + // handler is attached. + static OfflinePageRequestHandler* GetHandler(net::URLRequest* request); + + // Creates a protocol interceptor for offline pages. Created one per + // supported, i.e. non-incognito, profile. + // |profile_id|, which identifies the profile, is passed as a void* to ensure + // it's not accidently used on the IO thread. + static std::unique_ptr<net::URLRequestInterceptor> CreateInterceptor( + void* profile_id); + + ~OfflinePageRequestHandler() override; + + net::URLRequestJob* MaybeCreateJob( + net::URLRequest* request, + net::NetworkDelegate* network_delegate, + void* profile_id); + + private: + OfflinePageRequestHandler(); + + DISALLOW_COPY_AND_ASSIGN(OfflinePageRequestHandler); +}; + +} // namespace offline_pages + +#endif // CHROME_BROWSER_ANDROID_OFFLINE_PAGES_OFFLINE_PAGE_REQUEST_HANDLER_H_
diff --git a/chrome/browser/android/offline_pages/offline_page_tab_helper.cc b/chrome/browser/android/offline_pages/offline_page_tab_helper.cc index 0bb07c2..506124a 100644 --- a/chrome/browser/android/offline_pages/offline_page_tab_helper.cc +++ b/chrome/browser/android/offline_pages/offline_page_tab_helper.cc
@@ -8,7 +8,6 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram.h" -#include "base/strings/string_number_conversions.h" #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "chrome/browser/android/offline_pages/offline_page_model_factory.h" @@ -65,12 +64,8 @@ DefaultDelegate() {} // offline_pages::OfflinePageTabHelper::Delegate implementation: bool GetTabId(content::WebContents* web_contents, - std::string* tab_id) const override { - int temp_tab_id; - if (!OfflinePageUtils::GetTabId(web_contents, &temp_tab_id)) - return false; - *tab_id = base::IntToString(temp_tab_id); - return true; + int* tab_id) const override { + return OfflinePageUtils::GetTabId(web_contents, tab_id); } base::Time Now() const override { return base::Time::Now(); } }; @@ -119,14 +114,14 @@ } if (net::NetworkChangeNotifier::IsOffline()) { - GetPagesForRedirectToOffline( + GetBestPageForRedirectToOffline( RedirectResult::REDIRECTED_ON_DISCONNECTED_NETWORK, navigated_url); return; } content::BrowserContext* context = web_contents()->GetBrowserContext(); if (ShouldUseOfflineForSlowNetwork(context)) { - GetPagesForRedirectToOffline( + GetBestPageForRedirectToOffline( RedirectResult::REDIRECTED_ON_PROHIBITIVELY_SLOW_NETWORK, navigated_url); return; @@ -185,7 +180,7 @@ return; } - GetPagesForRedirectToOffline( + GetBestPageForRedirectToOffline( RedirectResult::REDIRECTED_ON_FLAKY_NETWORK, navigated_url); } @@ -210,50 +205,33 @@ ReportRedirectResultUMA(RedirectResult::REDIRECTED_ON_CONNECTED_NETWORK); } -void OfflinePageTabHelper::GetPagesForRedirectToOffline( +void OfflinePageTabHelper::GetBestPageForRedirectToOffline( RedirectResult result, const GURL& online_url) { - OfflinePageModel* offline_page_model = - OfflinePageModelFactory::GetForBrowserContext( - web_contents()->GetBrowserContext()); - if (!offline_page_model) - return; - - offline_page_model->GetPagesByOnlineURL( - online_url, - base::Bind(&OfflinePageTabHelper::SelectBestPageForRedirectToOffline, - weak_ptr_factory_.GetWeakPtr(), result, online_url)); -} - -void OfflinePageTabHelper::SelectBestPageForRedirectToOffline( - RedirectResult result, - const GURL& online_url, - const MultipleOfflinePageItemResult& pages) { - DCHECK(result == RedirectResult::REDIRECTED_ON_FLAKY_NETWORK || - result == RedirectResult::REDIRECTED_ON_DISCONNECTED_NETWORK || - result == RedirectResult::REDIRECTED_ON_PROHIBITIVELY_SLOW_NETWORK); - // When there is no valid tab android there is nowhere to show the offline // page, so we can leave. - std::string tab_id; + int tab_id; if (!delegate_->GetTabId(web_contents(), &tab_id)) { ReportRedirectResultUMA(RedirectResult::NO_TAB_ID); return; } - const OfflinePageItem* selected_page = nullptr; - for (const auto& offline_page : pages) { - if ((offline_page.client_id.name_space == kBookmarkNamespace) || - (offline_page.client_id.name_space == kAsyncNamespace) || - (offline_page.client_id.name_space == kLastNNamespace && - offline_page.client_id.id == tab_id)) { - if (!selected_page || - offline_page.creation_time > selected_page->creation_time) { - selected_page = &offline_page; - } - } - } + OfflinePageUtils::SelectPageForOnlineURL( + web_contents()->GetBrowserContext(), + online_url, + tab_id, + base::Bind(&OfflinePageTabHelper::SelectPageForOnlineURLDone, + weak_ptr_factory_.GetWeakPtr(), result, online_url)); +} - if (!selected_page) { +void OfflinePageTabHelper::SelectPageForOnlineURLDone( + RedirectResult result, + const GURL& online_url, + const OfflinePageItem* offline_page) { + DCHECK(result == RedirectResult::REDIRECTED_ON_FLAKY_NETWORK || + result == RedirectResult::REDIRECTED_ON_DISCONNECTED_NETWORK || + result == RedirectResult::REDIRECTED_ON_PROHIBITIVELY_SLOW_NETWORK); + + if (!offline_page) { switch (result) { case RedirectResult::REDIRECTED_ON_FLAKY_NETWORK: ReportRedirectResultUMA( @@ -276,14 +254,14 @@ // If the page is being loaded on a slow network, only use the offline page // if it was created within the past 7 days. if (result == RedirectResult::REDIRECTED_ON_PROHIBITIVELY_SLOW_NETWORK && - delegate_->Now() - selected_page->creation_time > + delegate_->Now() - offline_page->creation_time > base::TimeDelta::FromDays(7)) { ReportRedirectResultUMA( RedirectResult::PAGE_NOT_FRESH_ON_PROHIBITIVELY_SLOW_NETWORK); return; } - TryRedirectToOffline(result, online_url, *selected_page); + TryRedirectToOffline(result, online_url, *offline_page); } void OfflinePageTabHelper::TryRedirectToOffline(
diff --git a/chrome/browser/android/offline_pages/offline_page_tab_helper.h b/chrome/browser/android/offline_pages/offline_page_tab_helper.h index 3a9b3e5..6bf460b0 100644 --- a/chrome/browser/android/offline_pages/offline_page_tab_helper.h +++ b/chrome/browser/android/offline_pages/offline_page_tab_helper.h
@@ -32,7 +32,7 @@ public: virtual ~Delegate() {} virtual bool GetTabId(content::WebContents* web_contents, - std::string* tab_id) const = 0; + int* tab_id) const = 0; virtual base::Time Now() const = 0; }; @@ -94,12 +94,12 @@ // redirect to that offline page, and caching metadata of that page locally. // RedirectResult is accumulated along the codepath to reflect the overall // result of redirection - and be reported to UMA at the end. - void GetPagesForRedirectToOffline(RedirectResult result, - const GURL& online_url); - void SelectBestPageForRedirectToOffline( + void GetBestPageForRedirectToOffline(RedirectResult result, + const GURL& online_url); + void SelectPageForOnlineURLDone( RedirectResult result, const GURL& online_url, - const MultipleOfflinePageItemResult& pages); + const OfflinePageItem* offline_page); void TryRedirectToOffline(RedirectResult result, const GURL& from_url, const OfflinePageItem& offline_page);
diff --git a/chrome/browser/android/offline_pages/offline_page_tab_helper_unittest.cc b/chrome/browser/android/offline_pages/offline_page_tab_helper_unittest.cc index aa8b76d0..c7392a3f 100644 --- a/chrome/browser/android/offline_pages/offline_page_tab_helper_unittest.cc +++ b/chrome/browser/android/offline_pages/offline_page_tab_helper_unittest.cc
@@ -13,6 +13,7 @@ #include "base/memory/weak_ptr.h" #include "base/metrics/field_trial.h" #include "base/run_loop.h" +#include "base/strings/string_number_conversions.h" #include "base/test/histogram_tester.h" #include "base/test/simple_test_clock.h" #include "base/time/time.h" @@ -45,7 +46,7 @@ const ClientId kTestClientId = ClientId(kBookmarkNamespace, "1234"); const int64_t kTestFileSize = 876543LL; const char kRedirectResultHistogram[] = "OfflinePages.RedirectResult"; -const char kTabId[] = "42"; +const int kTabId = 42; class TestNetworkChangeNotifier : public net::NetworkChangeNotifier { public: @@ -68,14 +69,14 @@ class TestDelegate : public OfflinePageTabHelper::Delegate { public: TestDelegate(bool has_tab_android, - std::string tab_id, + int tab_id, base::SimpleTestClock* clock) : clock_(clock), has_tab_android_(has_tab_android), tab_id_(tab_id) {} ~TestDelegate() override {} // offline_pages::OfflinePageTabHelper::Delegate implementation: bool GetTabId(content::WebContents* web_contents, - std::string* tab_id) const override { + int* tab_id) const override { if (has_tab_android_) *tab_id = tab_id_; return has_tab_android_; @@ -86,7 +87,7 @@ private: base::SimpleTestClock* clock_; bool has_tab_android_; - std::string tab_id_; + int tab_id_; }; } // namespace @@ -340,7 +341,7 @@ kTestPageUrl, base::FilePath(FILE_PATH_LITERAL("page2.mhtml")))); // We expect this copy to be used later. - ClientId client_id(kLastNNamespace, kTabId); + ClientId client_id(kLastNNamespace, base::IntToString(kTabId)); model->SavePage( kTestPageUrl, client_id, std::move(archiver), base::Bind(&OfflinePageTabHelperTest::OnSavePageDone, AsWeakPtr())); @@ -366,7 +367,7 @@ EXPECT_EQ(expected_offline_id, item->offline_id); EXPECT_EQ(expected_offline_url, item->GetOfflineURL()); EXPECT_EQ(kLastNNamespace, item->client_id.name_space); - EXPECT_EQ(kTabId, item->client_id.id); + EXPECT_EQ(base::IntToString(kTabId), item->client_id.id); } TEST_F(OfflinePageTabHelperTest, PageFor2GSlow) { @@ -421,7 +422,7 @@ base::FilePath(FILE_PATH_LITERAL("AsyncLoadedPage.mhtml")))); // We expect this Async Loading Namespace copy to be used. - ClientId client_id(kAsyncNamespace, kTabId); + ClientId client_id(kAsyncNamespace, base::IntToString(kTabId)); model->SavePage( kTestPageUrl, client_id, std::move(archiver), base::Bind(&OfflinePageTabHelperTest::OnSavePageDone, AsWeakPtr()));
diff --git a/chrome/browser/android/offline_pages/offline_page_utils.cc b/chrome/browser/android/offline_pages/offline_page_utils.cc index aa787a8..a607b434 100644 --- a/chrome/browser/android/offline_pages/offline_page_utils.cc +++ b/chrome/browser/android/offline_pages/offline_page_utils.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/android/offline_pages/offline_page_model_factory.h" #include "chrome/browser/android/offline_pages/offline_page_tab_helper.h" #include "chrome/browser/android/tab_android.h" +#include "components/offline_pages/client_namespace_constants.h" #include "components/offline_pages/offline_page_feature.h" #include "components/offline_pages/offline_page_item.h" #include "components/offline_pages/offline_page_model.h" @@ -24,23 +25,6 @@ namespace offline_pages { namespace { -// Returns an offline page originated from the |online_url|. -const OfflinePageItem* MaybeGetBestOfflinePageForOnlineURL( - content::BrowserContext* browser_context, - const GURL& online_url) { - DCHECK(browser_context); - - if (!IsOfflinePagesEnabled()) - return nullptr; - - OfflinePageModel* offline_page_model = - OfflinePageModelFactory::GetForBrowserContext(browser_context); - if (!offline_page_model) - return nullptr; - - return offline_page_model->MaybeGetBestPageForOnlineURL(online_url); -} - // Returns an offline page that is stored as the |offline_url|. const OfflinePageItem* GetOfflinePageForOfflineURL( content::BrowserContext* browser_context, @@ -73,6 +57,26 @@ callback.Run(result_url); } +void OnGetPagesByOnlineURLDone( + int tab_id, + const base::Callback<void(const OfflinePageItem*)>& callback, + const MultipleOfflinePageItemResult& pages) { + const OfflinePageItem* selected_page = nullptr; + std::string tab_id_str = base::IntToString(tab_id); + for (const auto& offline_page : pages) { + if ((offline_page.client_id.name_space == kBookmarkNamespace) || + (offline_page.client_id.name_space == kAsyncNamespace) || + (offline_page.client_id.name_space == kLastNNamespace && + offline_page.client_id.id == tab_id_str)) { + if (!selected_page || + offline_page.creation_time > selected_page->creation_time) { + selected_page = &offline_page; + } + } + } + callback.Run(selected_page); +} + } // namespace // static @@ -97,6 +101,24 @@ } // static +void OfflinePageUtils::SelectPageForOnlineURL( + content::BrowserContext* browser_context, + const GURL& online_url, + int tab_id, + const base::Callback<void(const OfflinePageItem*)>& callback) { + OfflinePageModel* offline_page_model = + OfflinePageModelFactory::GetForBrowserContext(browser_context); + if (!offline_page_model) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(callback, nullptr)); + return; + } + + offline_page_model->GetPagesByOnlineURL( + online_url, base::Bind(&OnGetPagesByOnlineURLDone, tab_id, callback)); +} + +// static void OfflinePageUtils::GetOnlineURLForOfflineURL( content::BrowserContext* browser_context, const GURL& offline_url, @@ -120,15 +142,6 @@ } // static -bool OfflinePageUtils::HasOfflinePageForOnlineURL( - content::BrowserContext* browser_context, - const GURL& online_url) { - const OfflinePageItem* offline_page = - MaybeGetBestOfflinePageForOnlineURL(browser_context, online_url); - return offline_page && !offline_page->file_path.empty(); -} - -// static void OfflinePageUtils::MarkPageAccessed( content::BrowserContext* browser_context, const GURL& offline_url) { DCHECK(browser_context);
diff --git a/chrome/browser/android/offline_pages/offline_page_utils.h b/chrome/browser/android/offline_pages/offline_page_utils.h index 11455ff2..5e74803 100644 --- a/chrome/browser/android/offline_pages/offline_page_utils.h +++ b/chrome/browser/android/offline_pages/offline_page_utils.h
@@ -24,6 +24,17 @@ // Returns true if |url| might point to an offline page. static bool MightBeOfflineURL(const GURL& url); + // Returns via callback an offline page saved for |online_url|, if any. The + // page is chosen based on creation date; a more recently created offline + // page will be preferred over an older one. The offline page captured from + // last visit in the tab will not be considered if its tab id does not match + // the provided |tab_id|. + static void SelectPageForOnlineURL( + content::BrowserContext* browser_context, + const GURL& online_url, + int tab_id, + const base::Callback<void(const OfflinePageItem*)>& callback); + // Gets an online URL of an offline page with |offline_url| if one exists. // Deprecated. Use |GetOnlineURLForOfflineURL|. static GURL MaybeGetOnlineURLForOfflineURL( @@ -40,11 +51,6 @@ static bool IsOfflinePage(content::BrowserContext* browser_context, const GURL& offline_url); - // Checks whether offline page for |online_url| exists. - static bool HasOfflinePageForOnlineURL( - content::BrowserContext* browser_context, - const GURL& online_url); - // Marks that the offline page related to the |offline_url| has been accessed. static void MarkPageAccessed(content::BrowserContext* browser_context, const GURL& offline_url);
diff --git a/chrome/browser/android/offline_pages/offline_page_utils_unittest.cc b/chrome/browser/android/offline_pages/offline_page_utils_unittest.cc index 64f3fe3..4b32cdc 100644 --- a/chrome/browser/android/offline_pages/offline_page_utils_unittest.cc +++ b/chrome/browser/android/offline_pages/offline_page_utils_unittest.cc
@@ -240,15 +240,4 @@ EXPECT_FALSE(OfflinePageUtils::IsOfflinePage(profile(), kTestPage4Url)); } -TEST_F(OfflinePageUtilsTest, HasOfflinePageForOnlineURL) { - EXPECT_TRUE( - OfflinePageUtils::HasOfflinePageForOnlineURL(profile(), kTestPage1Url)); - EXPECT_TRUE( - OfflinePageUtils::HasOfflinePageForOnlineURL(profile(), kTestPage2Url)); - EXPECT_FALSE( - OfflinePageUtils::HasOfflinePageForOnlineURL(profile(), kTestPage3Url)); - EXPECT_FALSE( - OfflinePageUtils::HasOfflinePageForOnlineURL(profile(), kTestPage4Url)); -} - } // namespace offline_pages
diff --git a/chrome/browser/android/shortcut_helper.cc b/chrome/browser/android/shortcut_helper.cc index 7ab5602..26000d2 100644 --- a/chrome/browser/android/shortcut_helper.cc +++ b/chrome/browser/android/shortcut_helper.cc
@@ -64,34 +64,30 @@ } // anonymous namespace // static -void ShortcutHelper::AddToLauncherInBackgroundWithSkBitmap( +void ShortcutHelper::AddToLauncherWithSkBitmap( content::BrowserContext* browser_context, const ShortcutInfo& info, const std::string& webapp_id, const SkBitmap& icon_bitmap, const base::Closure& splash_image_callback) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - if (info.display == blink::WebDisplayModeStandalone || info.display == blink::WebDisplayModeFullscreen) { if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableWebApk)) { - InstallWebApkInBackgroundWithSkBitmap(browser_context, info, icon_bitmap); + InstallWebApkWithSkBitmap(browser_context, info, icon_bitmap); return; } - AddWebappInBackgroundWithSkBitmap(info, webapp_id, icon_bitmap, - splash_image_callback); + AddWebappWithSkBitmap(info, webapp_id, icon_bitmap, splash_image_callback); return; } - AddShortcutInBackgroundWithSkBitmap(info, icon_bitmap); + AddShortcutWithSkBitmap(info, icon_bitmap); } // static -void ShortcutHelper::InstallWebApkInBackgroundWithSkBitmap( +void ShortcutHelper::InstallWebApkWithSkBitmap( content::BrowserContext* browser_context, const ShortcutInfo& info, const SkBitmap& icon_bitmap) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); // WebApkInstaller destroys itself when it is done. WebApkInstaller* installer = new WebApkInstaller(info, icon_bitmap); installer->InstallAsync(browser_context, @@ -99,13 +95,11 @@ } // static -void ShortcutHelper::AddWebappInBackgroundWithSkBitmap( +void ShortcutHelper::AddWebappWithSkBitmap( const ShortcutInfo& info, const std::string& webapp_id, const SkBitmap& icon_bitmap, const base::Closure& splash_image_callback) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - // Send the data to the Java side to create the shortcut. JNIEnv* env = base::android::AttachCurrentThread(); ScopedJavaLocalRef<jstring> java_webapp_id = @@ -151,7 +145,7 @@ callback_pointer); } -void ShortcutHelper::AddShortcutInBackgroundWithSkBitmap( +void ShortcutHelper::AddShortcutWithSkBitmap( const ShortcutInfo& info, const SkBitmap& icon_bitmap) { JNIEnv* env = base::android::AttachCurrentThread(); @@ -295,7 +289,7 @@ // Callback used by Java when the shortcut has been created. // |splash_image_callback| is a pointer to a base::Closure allocated in -// AddShortcutInBackgroundWithSkBitmap, so reinterpret_cast it back and run it. +// AddShortcutWithSkBitmap, so reinterpret_cast it back and run it. // // This callback should only ever be called when the shortcut was for a // webapp-capable site; otherwise, |splash_image_callback| will have never been
diff --git a/chrome/browser/android/shortcut_helper.h b/chrome/browser/android/shortcut_helper.h index f24995df..a9c4b88 100644 --- a/chrome/browser/android/shortcut_helper.h +++ b/chrome/browser/android/shortcut_helper.h
@@ -28,8 +28,7 @@ // added depends on the properties in |info|. Calls one of // InstallWebApkInBackgroundWithSkBitmap, AddWebappInBackgroundWithSkBitmap, // or AddShortcutInBackgroundWithSkBitmap. - // Must not be called on the UI thread. - static void AddToLauncherInBackgroundWithSkBitmap( + static void AddToLauncherWithSkBitmap( content::BrowserContext* browser_context, const ShortcutInfo& info, const std::string& webapp_id, @@ -37,8 +36,7 @@ const base::Closure& splash_image_callback); // Installs WebAPK and adds shortcut to the launcher. - // Must not be called on the UI thread. - static void InstallWebApkInBackgroundWithSkBitmap( + static void InstallWebApkWithSkBitmap( content::BrowserContext* browser_context, const ShortcutInfo& info, const SkBitmap& icon_bitmap); @@ -48,16 +46,14 @@ // completed. This is necessary as Java will asynchronously create and // populate a WebappDataStorage object for standalone-capable sites. This must // exist before the splash image can be stored. - // Must not be called on the UI thread. - static void AddWebappInBackgroundWithSkBitmap( + static void AddWebappWithSkBitmap( const ShortcutInfo& info, const std::string& webapp_id, const SkBitmap& icon_bitmap, const base::Closure& splash_image_callback); // Adds a shortcut which opens in a browser tab to the launcher. - // Must not be called on the UI thread. - static void AddShortcutInBackgroundWithSkBitmap( + static void AddShortcutWithSkBitmap( const ShortcutInfo& info, const SkBitmap& icon_bitmap);
diff --git a/chrome/browser/android/tab_android.cc b/chrome/browser/android/tab_android.cc index a64861bc..13b4109b 100644 --- a/chrome/browser/android/tab_android.cc +++ b/chrome/browser/android/tab_android.cc
@@ -14,6 +14,7 @@ #include "cc/layers/layer.h" #include "chrome/browser/android/compositor/tab_content_manager.h" #include "chrome/browser/android/metrics/uma_utils.h" +#include "chrome/browser/android/offline_pages/offline_page_bridge.h" #include "chrome/browser/android/offline_pages/offline_page_model_factory.h" #include "chrome/browser/android/offline_pages/offline_page_utils.h" #include "chrome/browser/android/tab_web_contents_delegate_android.h" @@ -782,34 +783,23 @@ is_preview); } -jboolean TabAndroid::HasOfflineCopy(JNIEnv* env, - const JavaParamRef<jobject>& obj) { - GURL url = dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl( - web_contents()->GetURL()); - return offline_pages::OfflinePageUtils::HasOfflinePageForOnlineURL( - GetProfile(), url); -} - jboolean TabAndroid::IsOfflinePage(JNIEnv* env, const JavaParamRef<jobject>& obj) { - GURL url = dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl( - web_contents()->GetURL()); - return offline_pages::OfflinePageUtils::IsOfflinePage(GetProfile(), url); + return offline_pages::OfflinePageUtils::GetOfflinePageFromWebContents( + web_contents()) != nullptr; } -ScopedJavaLocalRef<jstring> TabAndroid::GetOfflinePageOriginalUrl( +ScopedJavaLocalRef<jobject> TabAndroid::GetOfflinePage( JNIEnv* env, const JavaParamRef<jobject>& obj) { - GURL url = dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl( - web_contents()->GetURL()); - GURL original_url = - offline_pages::OfflinePageUtils::MaybeGetOnlineURLForOfflineURL( - GetProfile(), url); - if (!original_url.is_valid()) - return ScopedJavaLocalRef<jstring>(); + const offline_pages::OfflinePageItem* offline_page = + offline_pages::OfflinePageUtils::GetOfflinePageFromWebContents( + web_contents()); + if (!offline_page) + return ScopedJavaLocalRef<jobject>(); - return ScopedJavaLocalRef<jstring>( - ConvertUTF8ToJavaString(env, original_url.spec())); + return offline_pages::android::OfflinePageBridge::ConvertToJavaOfflinePage( + env, *offline_page); } bool TabAndroid::HasPrerenderedUrl(JNIEnv* env,
diff --git a/chrome/browser/android/tab_android.h b/chrome/browser/android/tab_android.h index 9094abf..fddc5d7 100644 --- a/chrome/browser/android/tab_android.h +++ b/chrome/browser/android/tab_android.h
@@ -230,7 +230,7 @@ jboolean IsOfflinePage(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); - base::android::ScopedJavaLocalRef<jstring> GetOfflinePageOriginalUrl( + base::android::ScopedJavaLocalRef<jobject> GetOfflinePage( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
diff --git a/chrome/browser/android/thumbnail/thumbnail_cache.cc b/chrome/browser/android/thumbnail/thumbnail_cache.cc index 295d7fb..307bbe3 100644 --- a/chrome/browser/android/thumbnail/thumbnail_cache.cc +++ b/chrome/browser/android/thumbnail/thumbnail_cache.cc
@@ -205,9 +205,8 @@ return thumbnail; } - if (force_disk_read && - ContainsValue(visible_ids_, tab_id) && - !ContainsValue(read_queue_, tab_id)) { + if (force_disk_read && base::ContainsValue(visible_ids_, tab_id) && + !base::ContainsValue(read_queue_, tab_id)) { read_queue_.push_back(tab_id); ReadNextThumbnail(); } @@ -295,8 +294,7 @@ while (iter != priority.end() && count < ids_size) { TabId tab_id = *iter; visible_ids_.push_back(tab_id); - if (!cache_.Get(tab_id) && - !ContainsValue(read_queue_, tab_id)) + if (!cache_.Get(tab_id) && !base::ContainsValue(read_queue_, tab_id)) read_queue_.push_back(tab_id); iter++; count++; @@ -403,8 +401,7 @@ } void ThumbnailCache::MakeSpaceForNewItemIfNecessary(TabId tab_id) { - if (cache_.Get(tab_id) || - !ContainsValue(visible_ids_, tab_id) || + if (cache_.Get(tab_id) || !base::ContainsValue(visible_ids_, tab_id) || cache_.size() < cache_.MaximumCacheSize()) { return; } @@ -416,7 +413,7 @@ for (ExpiringThumbnailCache::iterator iter = cache_.begin(); iter != cache_.end(); iter++) { - if (!ContainsValue(visible_ids_, iter->first)) { + if (!base::ContainsValue(visible_ids_, iter->first)) { key_to_remove = iter->first; found_key_to_remove = true; break;
diff --git a/chrome/browser/android/webapk/webapk_installer.cc b/chrome/browser/android/webapk/webapk_installer.cc index 3764492c2..19affd8 100644 --- a/chrome/browser/android/webapk/webapk_installer.cc +++ b/chrome/browser/android/webapk/webapk_installer.cc
@@ -12,10 +12,13 @@ #include "base/command_line.h" #include "base/files/file_path.h" #include "base/files/file_util.h" +#include "base/memory/ref_counted.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/task_runner_util.h" +#include "base/threading/sequenced_worker_pool.h" #include "chrome/browser/android/shortcut_helper.h" #include "chrome/browser/android/webapk/webapk.pb.h" #include "chrome/browser/profiles/profile.h" @@ -81,6 +84,13 @@ return base::StringPrintf("rgba(%d,%d,%d,%.2f)", r, g, b, a); } +// Returns task runner for running background tasks. +scoped_refptr<base::TaskRunner> GetBackgroundTaskRunner() { + return content::BrowserThread::GetBlockingPool() + ->GetTaskRunnerWithShutdownBehavior( + base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); +} + } // anonymous namespace WebApkInstaller::WebApkInstaller(const ShortcutInfo& shortcut_info, @@ -89,7 +99,7 @@ shortcut_icon_(shortcut_icon), webapk_download_url_timeout_ms_(kWebApkDownloadUrlTimeoutMs), download_timeout_ms_(kDownloadTimeoutMs), - io_weak_ptr_factory_(this) { + weak_ptr_factory_(this) { base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); server_url_ = GURL(command_line->HasSwitch(switches::kWebApkServerUrl) @@ -101,25 +111,25 @@ void WebApkInstaller::InstallAsync(content::BrowserContext* browser_context, const FinishCallback& finish_callback) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - finish_callback_ = finish_callback; - // base::Unretained() is safe because WebApkInstaller owns itself and does not - // start the timeout timer till after - // InitializeRequestContextGetterOnUIThread() is called. - content::BrowserThread::PostTask( - content::BrowserThread::UI, FROM_HERE, - base::Bind(&WebApkInstaller::InitializeRequestContextGetterOnUIThread, - base::Unretained(this), browser_context)); + InstallAsyncWithURLRequestContextGetter( + Profile::FromBrowserContext(browser_context)->GetRequestContext(), + finish_callback); } void WebApkInstaller::InstallAsyncWithURLRequestContextGetter( net::URLRequestContextGetter* request_context_getter, const FinishCallback& finish_callback) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); request_context_getter_ = request_context_getter; finish_callback_ = finish_callback; - SendCreateWebApkRequest(); + // base::Unretained() is safe because WebApkInstaller owns itself and does not + // start the timeout timer till after SendCreateWebApkRequest() is called. + base::PostTaskAndReplyWithResult( + GetBackgroundTaskRunner().get(), FROM_HERE, + base::Bind(&WebApkInstaller::BuildWebApkProtoInBackground, + base::Unretained(this)), + base::Bind(&WebApkInstaller::SendCreateWebApkRequest, + base::Unretained(this))); } void WebApkInstaller::SetTimeoutMs(int timeout_ms) { @@ -136,7 +146,6 @@ } void WebApkInstaller::OnURLFetchComplete(const net::URLFetcher* source) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); timer_.Stop(); if (!source->GetStatus().is_success() || @@ -163,27 +172,12 @@ OnGotWebApkDownloadUrl(signed_download_url, response->package_name()); } -void WebApkInstaller::InitializeRequestContextGetterOnUIThread( - content::BrowserContext* browser_context) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - // Profile::GetRequestContext() must be called on UI thread. - request_context_getter_ = - Profile::FromBrowserContext(browser_context)->GetRequestContext(); - - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::Bind(&WebApkInstaller::SendCreateWebApkRequest, - io_weak_ptr_factory_.GetWeakPtr())); -} - -void WebApkInstaller::SendCreateWebApkRequest() { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - std::unique_ptr<webapk::WebApk> webapk_proto = BuildWebApkProto(); - - timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds( - webapk_download_url_timeout_ms_), - base::Bind(&WebApkInstaller::OnTimeout, - io_weak_ptr_factory_.GetWeakPtr())); +void WebApkInstaller::SendCreateWebApkRequest( + std::unique_ptr<webapk::WebApk> webapk_proto) { + timer_.Start( + FROM_HERE, + base::TimeDelta::FromMilliseconds(webapk_download_url_timeout_ms_), + base::Bind(&WebApkInstaller::OnTimeout, weak_ptr_factory_.GetWeakPtr())); url_fetcher_ = net::URLFetcher::Create(server_url_, net::URLFetcher::POST, this); @@ -196,32 +190,26 @@ void WebApkInstaller::OnGotWebApkDownloadUrl(const GURL& download_url, const std::string& package_name) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - base::FilePath output_dir; base::android::GetCacheDirectory(&output_dir); // TODO(pkotwicz): Download WebAPKs into WebAPK-specific subdirectory // directory. // TODO(pkotwicz): Figure out when downloaded WebAPK should be deleted. - timer_.Start(FROM_HERE, - base::TimeDelta::FromMilliseconds(download_timeout_ms_), - base::Bind(&WebApkInstaller::OnTimeout, - io_weak_ptr_factory_.GetWeakPtr())); + timer_.Start( + FROM_HERE, base::TimeDelta::FromMilliseconds(download_timeout_ms_), + base::Bind(&WebApkInstaller::OnTimeout, weak_ptr_factory_.GetWeakPtr())); base::FilePath output_path = output_dir.AppendASCII(package_name); downloader_.reset(new FileDownloader( download_url, output_path, true, request_context_getter_, base::Bind(&WebApkInstaller::OnWebApkDownloaded, - io_weak_ptr_factory_.GetWeakPtr(), output_path, - package_name))); + weak_ptr_factory_.GetWeakPtr(), output_path, package_name))); } void WebApkInstaller::OnWebApkDownloaded(const base::FilePath& file_path, const std::string& package_name, FileDownloader::Result result) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - timer_.Stop(); if (result != FileDownloader::DOWNLOADED) { @@ -229,6 +217,26 @@ return; } + int posix_permissions = base::FILE_PERMISSION_READ_BY_USER | + base::FILE_PERMISSION_WRITE_BY_USER | + base::FILE_PERMISSION_READ_BY_GROUP | + base::FILE_PERMISSION_READ_BY_OTHERS; + base::PostTaskAndReplyWithResult( + GetBackgroundTaskRunner().get(), FROM_HERE, + base::Bind(&base::SetPosixFilePermissions, file_path, posix_permissions), + base::Bind(&WebApkInstaller::OnWebApkMadeWorldReadable, + weak_ptr_factory_.GetWeakPtr(), file_path, package_name)); +} + +void WebApkInstaller::OnWebApkMadeWorldReadable( + const base::FilePath& file_path, + const std::string& package_name, + bool change_permission_success) { + if (!change_permission_success) { + OnFailure(); + return; + } + JNIEnv* env = base::android::AttachCurrentThread(); base::android::ScopedJavaLocalRef<jstring> java_file_path = base::android::ConvertUTF8ToJavaString(env, file_path.value()); @@ -242,7 +250,10 @@ OnFailure(); } -std::unique_ptr<webapk::WebApk> WebApkInstaller::BuildWebApkProto() { +std::unique_ptr<webapk::WebApk> +WebApkInstaller::BuildWebApkProtoInBackground() { + DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); + std::unique_ptr<webapk::WebApk> webapk(new webapk::WebApk); webapk->set_manifest_url(shortcut_info_.manifest_url.spec()); webapk->set_requester_application_package( @@ -278,7 +289,6 @@ } void WebApkInstaller::OnTimeout() { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); OnFailure(); }
diff --git a/chrome/browser/android/webapk/webapk_installer.h b/chrome/browser/android/webapk/webapk_installer.h index 0aac26e..6b8f363 100644 --- a/chrome/browser/android/webapk/webapk_installer.h +++ b/chrome/browser/android/webapk/webapk_installer.h
@@ -73,29 +73,37 @@ // net::URLFetcherDelegate: void OnURLFetchComplete(const net::URLFetcher* source) override; - // Initializes |request_context_getter_| on UI thread. - void InitializeRequestContextGetterOnUIThread( - content::BrowserContext* browser_context); - // Sends request to WebAPK server to create WebAPK. During a successful // request the WebAPK server responds with the URL of the generated WebAPK. - void SendCreateWebApkRequest(); + // |webapk| is the proto to send to the WebAPK server. + void SendCreateWebApkRequest(std::unique_ptr<webapk::WebApk> webapk_proto); // Called with the URL of generated WebAPK and the package name that the // WebAPK should be installed at. void OnGotWebApkDownloadUrl(const GURL& download_url, const std::string& package_name); - // Called once the WebAPK has been downloaded. Installs the WebAPK if the - // download was successful. + // Called once the WebAPK has been downloaded. Makes the downloaded WebAPK + // world readable and installs the WebAPK if the download was successful. // |file_path| is the file path that the WebAPK was downloaded to. // |package_name| is the package name that the WebAPK should be installed at. void OnWebApkDownloaded(const base::FilePath& file_path, const std::string& package_name, FileDownloader::Result result); + // Called once the downloaded WebAPK has been made world readable. Installs + // the WebAPK. + // |file_path| is the file path that the WebAPK was downloaded to. + // |package_name| is the package name that the WebAPK should be installed at. + // |change_permission_success| is whether the WebAPK could be made world + // readable. + void OnWebApkMadeWorldReadable(const base::FilePath& file_path, + const std::string& package_name, + bool change_permission_success); + // Populates webapk::WebApk and returns it. - std::unique_ptr<webapk::WebApk> BuildWebApkProto(); + // Must be called on a worker thread because it encodes an SkBitmap. + std::unique_ptr<webapk::WebApk> BuildWebApkProtoInBackground(); // Called when the request to the WebAPK server times out or when the WebAPK // download times out. @@ -141,8 +149,8 @@ // The number of milliseconds to wait for the WebAPK download to complete. int download_timeout_ms_; - // Used to get |weak_ptr_| on the IO thread. - base::WeakPtrFactory<WebApkInstaller> io_weak_ptr_factory_; + // Used to get |weak_ptr_|. + base::WeakPtrFactory<WebApkInstaller> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(WebApkInstaller); };
diff --git a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc index 9915636f..b9dbccf 100644 --- a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc +++ b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc
@@ -4,15 +4,16 @@ #include "chrome/browser/android/webapps/add_to_homescreen_data_fetcher.h" +#include <vector> + #include "base/bind.h" #include "base/callback.h" #include "base/location.h" #include "base/strings/string16.h" -#include "base/task/cancelable_task_tracker.h" #include "chrome/browser/android/offline_pages/offline_page_utils.h" #include "chrome/browser/android/shortcut_helper.h" #include "chrome/browser/favicon/favicon_service_factory.h" -#include "chrome/browser/manifest/manifest_icon_downloader.h" +#include "chrome/browser/installable/installable_manager.h" #include "chrome/browser/manifest/manifest_icon_selector.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/chrome_constants.h" @@ -20,11 +21,11 @@ #include "chrome/common/web_application_info.h" #include "components/dom_distiller/core/url_utils.h" #include "components/favicon/core/favicon_service.h" +#include "components/favicon_base/favicon_types.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/user_metrics.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" -#include "content/public/common/frame_navigate_params.h" #include "content/public/common/manifest.h" #include "third_party/WebKit/public/platform/modules/screen_orientation/WebScreenOrientationLockType.h" #include "ui/display/display.h" @@ -33,7 +34,38 @@ #include "ui/gfx/favicon_size.h" #include "url/gurl.h" -using content::Manifest; +namespace { + +// Looks up the original, online URL of the site requested. The URL from the +// WebContents may be an offline page or a distilled article which is not +// appropriate for a home screen shortcut. +GURL GetShortcutUrl(content::BrowserContext* browser_context, + const GURL& actual_url) { + GURL original_url = + dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl(actual_url); + + // If URL points to an offline content, get original URL. + GURL online_url = + offline_pages::OfflinePageUtils::MaybeGetOnlineURLForOfflineURL( + browser_context, original_url); + if (online_url.is_valid()) + return online_url; + + return original_url; +} + +InstallableParams ParamsToPerformInstallableCheck(int ideal_icon_size_in_dp, + int minimum_icon_size_in_dp) { + // TODO(hanxi): change check_installable to true for WebAPKs. + InstallableParams params; + params.ideal_icon_size_in_dp = ideal_icon_size_in_dp; + params.minimum_icon_size_in_dp = minimum_icon_size_in_dp; + params.check_installable = false; + params.fetch_valid_icon = true; + return params; +} + +} // namespace AddToHomescreenDataFetcher::AddToHomescreenDataFetcher( content::WebContents* web_contents, @@ -44,27 +76,28 @@ Observer* observer) : WebContentsObserver(web_contents), weak_observer_(observer), - is_waiting_for_web_application_info_(false), - is_icon_saved_(false), - is_ready_(false), - icon_timeout_timer_(false, false), - shortcut_info_(GetShortcutUrl(web_contents->GetURL())), + shortcut_info_(GetShortcutUrl(web_contents->GetBrowserContext(), + web_contents->GetLastCommittedURL())), + data_timeout_timer_(false, false), ideal_icon_size_in_dp_(ideal_icon_size_in_dp), minimum_icon_size_in_dp_(minimum_icon_size_in_dp), ideal_splash_image_size_in_dp_(ideal_splash_image_size_in_dp), - minimum_splash_image_size_in_dp_(minimum_splash_image_size_in_dp) { + minimum_splash_image_size_in_dp_(minimum_splash_image_size_in_dp), + is_waiting_for_web_application_info_(true), + is_icon_saved_(false), + is_ready_(false) { DCHECK(minimum_icon_size_in_dp <= ideal_icon_size_in_dp); DCHECK(minimum_splash_image_size_in_dp <= ideal_splash_image_size_in_dp); // Send a message to the renderer to retrieve information about the page. - is_waiting_for_web_application_info_ = true; Send(new ChromeViewMsg_GetWebApplicationInfo(routing_id())); } void AddToHomescreenDataFetcher::OnDidGetWebApplicationInfo( const WebApplicationInfo& received_web_app_info) { is_waiting_for_web_application_info_ = false; - if (!web_contents() || !weak_observer_) return; + if (!web_contents() || !weak_observer_) + return; // Sanitize received_web_app_info. WebApplicationInfo web_app_info = received_web_app_info; @@ -75,8 +108,8 @@ // Simply set the user-editable title to be the page's title shortcut_info_.user_title = web_app_info.title.empty() - ? web_contents()->GetTitle() - : web_app_info.title; + ? web_contents()->GetTitle() + : web_app_info.title; shortcut_info_.short_name = shortcut_info_.user_title; shortcut_info_.name = shortcut_info_.user_title; @@ -101,57 +134,68 @@ break; } - web_contents()->GetManifest( - base::Bind(&AddToHomescreenDataFetcher::OnDidGetManifest, this)); + InstallableManager::CreateForWebContents(web_contents()); + InstallableManager* manager = + InstallableManager::FromWebContents(web_contents()); + DCHECK(manager); + + // Kick off a timeout for downloading data. If we haven't finished within the + // timeout, fall back to using a dynamically-generated launcher icon. + data_timeout_timer_.Start( + FROM_HERE, base::TimeDelta::FromMilliseconds(4000), + base::Bind(&AddToHomescreenDataFetcher::OnFaviconFetched, this, + favicon_base::FaviconRawBitmapResult())); + + manager->GetData( + ParamsToPerformInstallableCheck(ideal_icon_size_in_dp_, + minimum_icon_size_in_dp_), + base::Bind(&AddToHomescreenDataFetcher::OnDidPerformInstallableCheck, + this)); } -void AddToHomescreenDataFetcher::OnDidGetManifest( - const GURL& manifest_url, - const content::Manifest& manifest) { - if (!web_contents() || !weak_observer_) return; +void AddToHomescreenDataFetcher::OnDidPerformInstallableCheck( + const InstallableData& data) { + if (!web_contents() || !weak_observer_) + return; - if (!manifest.IsEmpty()) { - content::RecordAction( - base::UserMetricsAction("webapps.AddShortcut.Manifest")); - shortcut_info_.UpdateFromManifest(manifest); - shortcut_info_.manifest_url = manifest_url; - } - - GURL icon_src = ManifestIconSelector::FindBestMatchingIcon( - manifest.icons, ideal_icon_size_in_dp_, minimum_icon_size_in_dp_); - - // If fetching the Manifest icon fails, fallback to the best favicon - // for the page. - if (!ManifestIconDownloader::Download( - web_contents(), - icon_src, - ideal_icon_size_in_dp_, - minimum_icon_size_in_dp_, - base::Bind(&AddToHomescreenDataFetcher::OnManifestIconFetched, - this, icon_src))) { - FetchFavicon(); + if (!data.manifest.IsEmpty()) { + content::RecordAction( + base::UserMetricsAction("webapps.AddShortcut.Manifest")); + shortcut_info_.UpdateFromManifest(data.manifest); + shortcut_info_.manifest_url = data.manifest_url; } // Save the splash screen URL for the later download. splash_screen_url_ = ManifestIconSelector::FindBestMatchingIcon( - manifest.icons, ideal_splash_image_size_in_dp_, + data.manifest.icons, ideal_splash_image_size_in_dp_, minimum_splash_image_size_in_dp_); weak_observer_->OnUserTitleAvailable(shortcut_info_.user_title); - // Kick off a timeout for downloading the icon. If an icon isn't set within - // the timeout, fall back to using a dynamically-generated launcher icon. - icon_timeout_timer_.Start(FROM_HERE, - base::TimeDelta::FromMilliseconds(3000), - base::Bind( - &AddToHomescreenDataFetcher::OnFaviconFetched, - this, - favicon_base::FaviconRawBitmapResult())); + if (data.icon && !data.icon->drawsNothing()) { + // TODO(hanxi): implement WebAPK path if shortcut_info_.url has a secure + // scheme and data.is_installable is true. + shortcut_info_.icon_url = data.icon_url; + + // base::Bind copies the arguments internally, so it is safe to pass it + // data.icon (which is not owned by us). + content::BrowserThread::GetBlockingPool() + ->PostWorkerTaskWithShutdownBehavior( + FROM_HERE, + base::Bind( + &AddToHomescreenDataFetcher::CreateLauncherIconInBackground, + this, *(data.icon)), + base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); + return; + } + + FetchFavicon(); } bool AddToHomescreenDataFetcher::OnMessageReceived( const IPC::Message& message) { - if (!is_waiting_for_web_application_info_) return false; + if (!is_waiting_for_web_application_info_) + return false; bool handled = true; @@ -176,21 +220,20 @@ } void AddToHomescreenDataFetcher::FetchFavicon() { - if (!web_contents() || !weak_observer_) return; - - Profile* profile = - Profile::FromBrowserContext(web_contents()->GetBrowserContext()); + if (!web_contents() || !weak_observer_) + return; // Grab the best, largest icon we can find to represent this bookmark. // TODO(dfalcantara): Try combining with the new BookmarksHandler once its // rewrite is further along. - std::vector<int> icon_types; - icon_types.push_back(favicon_base::FAVICON); - icon_types.push_back(favicon_base::TOUCH_PRECOMPOSED_ICON | - favicon_base::TOUCH_ICON); + std::vector<int> icon_types{ + favicon_base::FAVICON, + favicon_base::TOUCH_PRECOMPOSED_ICON | favicon_base::TOUCH_ICON}; + favicon::FaviconService* favicon_service = - FaviconServiceFactory::GetForProfile(profile, - ServiceAccessType::EXPLICIT_ACCESS); + FaviconServiceFactory::GetForProfile( + Profile::FromBrowserContext(web_contents()->GetBrowserContext()), + ServiceAccessType::EXPLICIT_ACCESS); // Using favicon if its size is not smaller than platform required size, // otherwise using the largest icon among all avaliable icons. @@ -199,9 +242,7 @@ display::Screen::GetScreen()->GetPrimaryDisplay().device_scale_factor(); int threshold_to_get_any_largest_icon = ideal_icon_size_in_px - 1; favicon_service->GetLargestRawFaviconForPageURL( - shortcut_info_.url, - icon_types, - threshold_to_get_any_largest_icon, + shortcut_info_.url, icon_types, threshold_to_get_any_largest_icon, base::Bind(&AddToHomescreenDataFetcher::OnFaviconFetched, this), &favicon_task_tracker_); } @@ -212,69 +253,52 @@ return; content::BrowserThread::GetBlockingPool()->PostWorkerTaskWithShutdownBehavior( - FROM_HERE, - base::Bind(&AddToHomescreenDataFetcher::CreateLauncherIconInBackground, - this, shortcut_info_.url, bitmap_result), + FROM_HERE, base::Bind(&AddToHomescreenDataFetcher:: + CreateLauncherIconFromFaviconInBackground, + this, bitmap_result), base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); } -void AddToHomescreenDataFetcher::CreateLauncherIconInBackground( - const GURL& page_url, +void AddToHomescreenDataFetcher::CreateLauncherIconFromFaviconInBackground( const favicon_base::FaviconRawBitmapResult& bitmap_result) { DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); - SkBitmap icon_bitmap; + SkBitmap raw_icon; if (bitmap_result.is_valid()) { gfx::PNGCodec::Decode(bitmap_result.bitmap_data->front(), - bitmap_result.bitmap_data->size(), - &icon_bitmap); + bitmap_result.bitmap_data->size(), &raw_icon); } + shortcut_info_.icon_url = bitmap_result.icon_url; + CreateLauncherIconInBackground(raw_icon); +} + +void AddToHomescreenDataFetcher::CreateLauncherIconInBackground( + const SkBitmap& raw_icon) { + DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); + + SkBitmap icon; bool is_generated = false; if (weak_observer_) { - icon_bitmap = weak_observer_->FinalizeLauncherIconInBackground( - icon_bitmap, page_url, &is_generated); + icon = weak_observer_->FinalizeLauncherIconInBackground( + raw_icon, shortcut_info_.url, &is_generated); } - GURL icon_url = is_generated ? GURL() : bitmap_result.icon_url; + if (is_generated) + shortcut_info_.icon_url = GURL(); + content::BrowserThread::PostTask( content::BrowserThread::UI, FROM_HERE, - base::Bind(&AddToHomescreenDataFetcher::NotifyObserver, this, icon_url, - icon_bitmap)); + base::Bind(&AddToHomescreenDataFetcher::NotifyObserver, this, icon)); } -void AddToHomescreenDataFetcher::OnManifestIconFetched(const GURL& icon_url, - const SkBitmap& icon) { - if (icon.drawsNothing()) { - FetchFavicon(); - return; - } - NotifyObserver(icon_url, icon); -} - -void AddToHomescreenDataFetcher::NotifyObserver(const GURL& icon_url, - const SkBitmap& bitmap) { +void AddToHomescreenDataFetcher::NotifyObserver(const SkBitmap& icon) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); if (!web_contents() || !weak_observer_ || is_icon_saved_) return; is_icon_saved_ = true; - shortcut_info_.icon_url = icon_url; - shortcut_icon_ = bitmap; + shortcut_icon_ = icon; is_ready_ = true; weak_observer_->OnDataAvailable(shortcut_info_, shortcut_icon_); } - -GURL AddToHomescreenDataFetcher::GetShortcutUrl(const GURL& actual_url) { - GURL original_url = - dom_distiller::url_utils::GetOriginalUrlFromDistillerUrl(actual_url); - - // If URL points to an offline content, get original URL. - GURL online_url = - offline_pages::OfflinePageUtils::MaybeGetOnlineURLForOfflineURL( - web_contents()->GetBrowserContext(), original_url); - if (online_url.is_valid()) - return online_url; - - return original_url; -}
diff --git a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.h b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.h index 55ca890e..47e8d06 100644 --- a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.h +++ b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.h
@@ -7,23 +7,28 @@ #include "base/callback_forward.h" #include "base/macros.h" +#include "base/memory/ref_counted.h" #include "base/task/cancelable_task_tracker.h" #include "base/timer/timer.h" #include "chrome/browser/android/shortcut_info.h" -#include "chrome/common/web_application_info.h" -#include "components/favicon_base/favicon_types.h" #include "content/public/browser/web_contents_observer.h" -#include "content/public/common/manifest.h" +#include "third_party/skia/include/core/SkBitmap.h" namespace content { class WebContents; -} // namespace content +} + +namespace favicon_base { +struct FaviconRawBitmapResult; +} namespace IPC { class Message; } class GURL; +struct InstallableData; +struct WebApplicationInfo; // Aysnchronously fetches and processes data needed to create a shortcut for an // Android Home screen launcher. @@ -53,8 +58,8 @@ const SkBitmap& icon) = 0; }; - // Initialize the fetcher by requesting the information about the page to the - // renderer process. The initialization is asynchronous and + // Initialize the fetcher by requesting the information about the page from + // the renderer process. The initialization is asynchronous and // OnDidGetWebApplicationInfo is expected to be called when finished. AddToHomescreenDataFetcher(content::WebContents* web_contents, int ideal_icon_size_in_dp, @@ -70,20 +75,18 @@ // IPC message received when the initialization is finished. void OnDidGetWebApplicationInfo(const WebApplicationInfo& web_app_info); - // Called when the Manifest has been parsed, or if no Manifest was found. - void OnDidGetManifest(const GURL& manifest_url, - const content::Manifest& manifest); - // Accessors, etc. void set_weak_observer(Observer* observer) { weak_observer_ = observer; } - bool is_ready() { return is_ready_; } + bool is_ready() const { return is_ready_; } ShortcutInfo& shortcut_info() { return shortcut_info_; } - const SkBitmap& shortcut_icon() { return shortcut_icon_; } + const SkBitmap& shortcut_icon() const { return shortcut_icon_; } // WebContentsObserver bool OnMessageReceived(const IPC::Message& message) override; private: + friend class base::RefCounted<AddToHomescreenDataFetcher>; + ~AddToHomescreenDataFetcher() override; // Grabs the favicon for the current URL. @@ -91,44 +94,39 @@ void OnFaviconFetched( const favicon_base::FaviconRawBitmapResult& bitmap_result); - // Creates the launcher icon from the given bitmap and page URL. The page URL - // is used to generate an icon if there is no bitmap in |bitmap_result| or the + // Creates the launcher icon from the given bitmap. shortcut_info_.url is + // used to generate an icon if there is no bitmap in |bitmap_result| or the // bitmap is not large enough. - void CreateLauncherIconInBackground( - const GURL& page_url, + void CreateLauncherIconFromFaviconInBackground( const favicon_base::FaviconRawBitmapResult& bitmap_result); - // Callback run after an attempt to download manifest icon has been made. May - // kick off the download of a favicon if it failed (i.e. the bitmap is empty). - void OnManifestIconFetched(const GURL& icon_url, const SkBitmap& icon); + // Called when InstallableManager finishes looking for a manifest and icon. + void OnDidPerformInstallableCheck(const InstallableData& data); + + // Creates the launcher icon from the given |icon|. + void CreateLauncherIconInBackground(const SkBitmap& raw__icon); // Notifies the observer that the shortcut data is all available. - void NotifyObserver(const GURL& icon_url, const SkBitmap& icon); - - // Looks up the original, online URL of the site requested. The URL from the - // WebContents may be an offline page or a distilled article which is not - // appropriate for a home screen shortcut. - GURL GetShortcutUrl(const GURL& original_url); + void NotifyObserver(const SkBitmap& icon); Observer* weak_observer_; - bool is_waiting_for_web_application_info_; - bool is_icon_saved_; - bool is_ready_; - base::Timer icon_timeout_timer_; + // The icon must only be set on the UI thread for thread safety. + SkBitmap shortcut_icon_; ShortcutInfo shortcut_info_; GURL splash_screen_url_; - // The icon must only be set on the UI thread for thread safety. - SkBitmap shortcut_icon_; base::CancelableTaskTracker favicon_task_tracker_; + base::Timer data_timeout_timer_; const int ideal_icon_size_in_dp_; const int minimum_icon_size_in_dp_; const int ideal_splash_image_size_in_dp_; const int minimum_splash_image_size_in_dp_; + bool is_waiting_for_web_application_info_; + bool is_icon_saved_; + bool is_ready_; - friend class base::RefCounted<AddToHomescreenDataFetcher>; DISALLOW_COPY_AND_ASSIGN(AddToHomescreenDataFetcher); };
diff --git a/chrome/browser/android/webapps/add_to_homescreen_dialog_helper.cc b/chrome/browser/android/webapps/add_to_homescreen_dialog_helper.cc index 709b6ef5..465ec4c 100644 --- a/chrome/browser/android/webapps/add_to_homescreen_dialog_helper.cc +++ b/chrome/browser/android/webapps/add_to_homescreen_dialog_helper.cc
@@ -4,8 +4,6 @@ #include "chrome/browser/android/webapps/add_to_homescreen_dialog_helper.h" -#include <jni.h> - #include "base/android/jni_android.h" #include "base/android/jni_string.h" #include "base/guid.h" @@ -16,15 +14,11 @@ #include "chrome/browser/banners/app_banner_settings_helper.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents.h" -#include "content/public/common/manifest.h" #include "jni/AddToHomescreenDialogHelper_jni.h" #include "ui/gfx/android/java_bitmap.h" -#include "ui/gfx/color_analysis.h" -#include "url/gurl.h" using base::android::JavaParamRef; using base::android::ScopedJavaLocalRef; -using content::Manifest; jlong Initialize(JNIEnv* env, const JavaParamRef<jobject>& obj, @@ -127,11 +121,9 @@ RecordAddToHomescreen(); const std::string& uid = base::GenerateGUID(); - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::Bind(&ShortcutHelper::AddToLauncherInBackgroundWithSkBitmap, - web_contents->GetBrowserContext(), info, uid, icon, - data_fetcher_->FetchSplashScreenImageCallback(uid))); + ShortcutHelper::AddToLauncherWithSkBitmap( + web_contents->GetBrowserContext(), info, uid, icon, + data_fetcher_->FetchSplashScreenImageCallback(uid)); } bool AddToHomescreenDialogHelper::RegisterAddToHomescreenDialogHelper(
diff --git a/chrome/browser/android/webapps/add_to_homescreen_dialog_helper.h b/chrome/browser/android/webapps/add_to_homescreen_dialog_helper.h index 3b1de6a..296011b 100644 --- a/chrome/browser/android/webapps/add_to_homescreen_dialog_helper.h +++ b/chrome/browser/android/webapps/add_to_homescreen_dialog_helper.h
@@ -6,21 +6,21 @@ #define CHROME_BROWSER_ANDROID_WEBAPPS_ADD_TO_HOMESCREEN_DIALOG_HELPER_H_ #include "base/android/jni_android.h" -#include "base/android/jni_weak_ref.h" +#include "base/android/scoped_java_ref.h" #include "base/macros.h" -#include "chrome/browser/android/shortcut_info.h" #include "chrome/browser/android/webapps/add_to_homescreen_data_fetcher.h" -#include "content/public/common/manifest.h" +#include "third_party/skia/include/core/SkBitmap.h" namespace content { class WebContents; -} // namespace content +} namespace IPC { class Message; } class GURL; +struct ShortcutInfo; // AddToHomescreenDialogHelper is the C++ counterpart of // org.chromium.chrome.browser's AddToHomescreenDialogHelper in Java. The object
diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm index 0568b6a..3d66888 100644 --- a/chrome/browser/app_controller_mac.mm +++ b/chrome/browser/app_controller_mac.mm
@@ -531,8 +531,9 @@ appShimMenuController_.reset(); - STLDeleteContainerPairSecondPointers(profileBookmarkMenuBridgeMap_.begin(), - profileBookmarkMenuBridgeMap_.end()); + base::STLDeleteContainerPairSecondPointers( + profileBookmarkMenuBridgeMap_.begin(), + profileBookmarkMenuBridgeMap_.end()); } - (void)didEndMainMessageLoop {
diff --git a/chrome/browser/apps/app_browsertest.cc b/chrome/browser/apps/app_browsertest.cc index 146fb76..7300ae4 100644 --- a/chrome/browser/apps/app_browsertest.cc +++ b/chrome/browser/apps/app_browsertest.cc
@@ -1244,7 +1244,7 @@ incognito_profile, file_manager, NEW_FOREGROUND_TAB, extensions::SOURCE_TEST)); - while (!ContainsKey(opener_app_ids_, file_manager->id())) { + while (!base::ContainsKey(opener_app_ids_, file_manager->id())) { content::RunAllPendingInMessageLoop(); } }
diff --git a/chrome/browser/apps/app_window_registry_util.cc b/chrome/browser/apps/app_window_registry_util.cc index d7689938..d8702de 100644 --- a/chrome/browser/apps/app_window_registry_util.cc +++ b/chrome/browser/apps/app_window_registry_util.cc
@@ -86,7 +86,7 @@ AppWindowList window_list_copy(registry->app_windows()); for (auto* window : window_list_copy) { // Ensure window is still valid. - if (ContainsValue(registry->app_windows(), window)) + if (base::ContainsValue(registry->app_windows(), window)) window->GetBaseWindow()->Close(); } }
diff --git a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc index b58ba5a7..79ef9b5 100644 --- a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc +++ b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
@@ -28,7 +28,7 @@ #include "components/history/core/browser/history_service.h" #include "components/omnibox/browser/autocomplete_classifier.h" #include "components/prefs/pref_service.h" -#include "components/sync_driver/sync_service_utils.h" +#include "components/sync/driver/sync_service_utils.h" #include "content/public/browser/notification_service.h" #if defined(ENABLE_EXTENSIONS)
diff --git a/chrome/browser/autocomplete/search_provider_unittest.cc b/chrome/browser/autocomplete/search_provider_unittest.cc index a8ae05ab..ebf9ea7 100644 --- a/chrome/browser/autocomplete/search_provider_unittest.cc +++ b/chrome/browser/autocomplete/search_provider_unittest.cc
@@ -52,7 +52,7 @@ #include "components/search_engines/template_url_service.h" #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/signin_manager.h" -#include "components/sync_driver/pref_names.h" +#include "components/sync/driver/pref_names.h" #include "components/variations/entropy_provider.h" #include "components/variations/variations_associated_data.h" #include "content/public/test/test_browser_thread_bundle.h"
diff --git a/chrome/browser/background/background_application_list_model.cc b/chrome/browser/background/background_application_list_model.cc index 60cd674..bb2a50c 100644 --- a/chrome/browser/background/background_application_list_model.cc +++ b/chrome/browser/background/background_application_list_model.cc
@@ -147,8 +147,8 @@ } BackgroundApplicationListModel::~BackgroundApplicationListModel() { - STLDeleteContainerPairSecondPointers(applications_.begin(), - applications_.end()); + base::STLDeleteContainerPairSecondPointers(applications_.begin(), + applications_.end()); } BackgroundApplicationListModel::BackgroundApplicationListModel(Profile* profile)
diff --git a/chrome/browser/background/background_mode_manager.cc b/chrome/browser/background/background_mode_manager.cc index e41b14b..5abf78b 100644 --- a/chrome/browser/background/background_mode_manager.cc +++ b/chrome/browser/background/background_mode_manager.cc
@@ -413,6 +413,22 @@ return in_background_mode_; } +bool BackgroundModeManager::IsBackgroundWithoutWindows() const { + return KeepAliveRegistry::GetInstance()->WouldRestartWithout({ + // Transient startup related KeepAlives, not related to any UI. + KeepAliveOrigin::SESSION_RESTORE, + KeepAliveOrigin::BACKGROUND_MODE_MANAGER_STARTUP, + + // Notification KeepAlives are not dependent on the Chrome UI being + // loaded, and can be registered when we were in pure background mode. + // They just block it to avoid issues. Ignore them when determining if we + // are in that mode. + KeepAliveOrigin::NOTIFICATION, + KeepAliveOrigin::PENDING_NOTIFICATION_CLICK_EVENT, + KeepAliveOrigin::IN_FLIGHT_PUSH_MESSAGE, + }); +} + int BackgroundModeManager::NumberOfBackgroundModeData() { return background_mode_data_.size(); }
diff --git a/chrome/browser/background/background_mode_manager.h b/chrome/browser/background/background_mode_manager.h index d17d8ada..adf60b9 100644 --- a/chrome/browser/background/background_mode_manager.h +++ b/chrome/browser/background/background_mode_manager.h
@@ -93,6 +93,9 @@ // Returns true if background mode is active. virtual bool IsBackgroundModeActive(); + // Returns true if we are in pure background mode, without windows. + bool IsBackgroundWithoutWindows() const; + // Suspends background mode until either ResumeBackgroundMode is called or // Chrome is restarted. This has the same effect as ending background mode // for the current browser session.
diff --git a/chrome/browser/background_sync/background_sync_controller_impl.cc b/chrome/browser/background_sync/background_sync_controller_impl.cc index d5b8e67c..3720cff 100644 --- a/chrome/browser/background_sync/background_sync_controller_impl.cc +++ b/chrome/browser/background_sync/background_sync_controller_impl.cc
@@ -54,7 +54,7 @@ parameters->disable = true; } - if (ContainsKey(field_params, kMaxAttemptsParameterName)) { + if (base::ContainsKey(field_params, kMaxAttemptsParameterName)) { int max_attempts; if (base::StringToInt(field_params[kMaxAttemptsParameterName], &max_attempts)) { @@ -62,7 +62,7 @@ } } - if (ContainsKey(field_params, kInitialRetryParameterName)) { + if (base::ContainsKey(field_params, kInitialRetryParameterName)) { int initial_retry_delay_sec; if (base::StringToInt(field_params[kInitialRetryParameterName], &initial_retry_delay_sec)) { @@ -71,7 +71,7 @@ } } - if (ContainsKey(field_params, kRetryDelayFactorParameterName)) { + if (base::ContainsKey(field_params, kRetryDelayFactorParameterName)) { int retry_delay_factor; if (base::StringToInt(field_params[kRetryDelayFactorParameterName], &retry_delay_factor)) { @@ -79,7 +79,7 @@ } } - if (ContainsKey(field_params, kMinSyncRecoveryTimeName)) { + if (base::ContainsKey(field_params, kMinSyncRecoveryTimeName)) { int min_sync_recovery_time_sec; if (base::StringToInt(field_params[kMinSyncRecoveryTimeName], &min_sync_recovery_time_sec)) { @@ -88,7 +88,7 @@ } } - if (ContainsKey(field_params, kMaxSyncEventDurationName)) { + if (base::ContainsKey(field_params, kMaxSyncEventDurationName)) { int max_sync_event_duration_sec; if (base::StringToInt(field_params[kMaxSyncEventDurationName], &max_sync_event_duration_sec)) {
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 4e3f92b..d3b133f0 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -226,6 +226,8 @@ <include name="IDR_MD_HISTORY_HISTORY_ITEM_HTML" file="resources\md_history\history_item.html" type="BINDATA" /> <include name="IDR_MD_HISTORY_HISTORY_ITEM_JS" file="resources\md_history\history_item.js" type="BINDATA" /> <include name="IDR_MD_HISTORY_HISTORY_JS" file="resources\md_history\history.js" type="BINDATA" /> + <include name="IDR_MD_HISTORY_HISTORY_LIST_BEHAVIOR_HTML" file="resources\md_history\history_list_behavior.html" type="BINDATA" /> + <include name="IDR_MD_HISTORY_HISTORY_LIST_BEHAVIOR_JS" file="resources\md_history\history_list_behavior.js" type="BINDATA" /> <include name="IDR_MD_HISTORY_HISTORY_LIST_HTML" file="resources\md_history\history_list.html" type="BINDATA" /> <include name="IDR_MD_HISTORY_HISTORY_LIST_JS" file="resources\md_history\history_list.js" type="BINDATA" /> <include name="IDR_MD_HISTORY_HISTORY_TOOLBAR_HTML" file="resources\md_history\history_toolbar.html" type="BINDATA" />
diff --git a/chrome/browser/browsing_data/browsing_data_appcache_helper_unittest.cc b/chrome/browser/browsing_data/browsing_data_appcache_helper_unittest.cc index ece320a72..f6263502f 100644 --- a/chrome/browser/browsing_data/browsing_data_appcache_helper_unittest.cc +++ b/chrome/browser/browsing_data/browsing_data_appcache_helper_unittest.cc
@@ -75,17 +75,17 @@ callback.info_collection()->infos_by_origin; ASSERT_EQ(2u, collection.size()); - EXPECT_TRUE(ContainsKey(collection, manifest1.GetOrigin())); + EXPECT_TRUE(base::ContainsKey(collection, manifest1.GetOrigin())); ASSERT_EQ(1u, collection[manifest1.GetOrigin()].size()); EXPECT_EQ(manifest1, collection[manifest1.GetOrigin()].at(0).manifest_url); - EXPECT_TRUE(ContainsKey(collection, manifest2.GetOrigin())); + EXPECT_TRUE(base::ContainsKey(collection, manifest2.GetOrigin())); EXPECT_EQ(2u, collection[manifest2.GetOrigin()].size()); std::set<GURL> manifest_results; manifest_results.insert(collection[manifest2.GetOrigin()].at(0).manifest_url); manifest_results.insert(collection[manifest2.GetOrigin()].at(1).manifest_url); - EXPECT_TRUE(ContainsKey(manifest_results, manifest2)); - EXPECT_TRUE(ContainsKey(manifest_results, manifest3)); + EXPECT_TRUE(base::ContainsKey(manifest_results, manifest2)); + EXPECT_TRUE(base::ContainsKey(manifest_results, manifest3)); } TEST_F(CannedBrowsingDataAppCacheHelperTest, Unique) { @@ -105,7 +105,7 @@ callback.info_collection()->infos_by_origin; ASSERT_EQ(1u, collection.size()); - EXPECT_TRUE(ContainsKey(collection, manifest.GetOrigin())); + EXPECT_TRUE(base::ContainsKey(collection, manifest.GetOrigin())); ASSERT_EQ(1u, collection[manifest.GetOrigin()].size()); EXPECT_EQ(manifest, collection[manifest.GetOrigin()].at(0).manifest_url); } @@ -139,7 +139,8 @@ EXPECT_EQ(3u, helper->GetAppCacheCount()); helper->DeleteAppCacheGroup(manifest2); EXPECT_EQ(2u, helper->GetAppCacheCount()); - EXPECT_FALSE(ContainsKey(helper->GetOriginAppCacheInfoMap(), manifest2)); + EXPECT_FALSE( + base::ContainsKey(helper->GetOriginAppCacheInfoMap(), manifest2)); } TEST_F(CannedBrowsingDataAppCacheHelperTest, IgnoreExtensionsAndDevTools) {
diff --git a/chrome/browser/browsing_data/browsing_data_cookie_helper.cc b/chrome/browser/browsing_data/browsing_data_cookie_helper.cc index fe405c4e..efebdf1 100644 --- a/chrome/browser/browsing_data/browsing_data_cookie_helper.cc +++ b/chrome/browser/browsing_data/browsing_data_cookie_helper.cc
@@ -109,8 +109,8 @@ } void CannedBrowsingDataCookieHelper::Reset() { - STLDeleteContainerPairSecondPointers(origin_cookie_set_map_.begin(), - origin_cookie_set_map_.end()); + base::STLDeleteContainerPairSecondPointers(origin_cookie_set_map_.begin(), + origin_cookie_set_map_.end()); origin_cookie_set_map_.clear(); }
diff --git a/chrome/browser/browsing_data/browsing_data_file_system_helper_unittest.cc b/chrome/browser/browsing_data/browsing_data_file_system_helper_unittest.cc index 14f430e..4455b71 100644 --- a/chrome/browser/browsing_data/browsing_data_file_system_helper_unittest.cc +++ b/chrome/browser/browsing_data/browsing_data_file_system_helper_unittest.cc
@@ -214,21 +214,21 @@ if (info.origin == kOrigin1) { EXPECT_FALSE(test_hosts_found[0]); test_hosts_found[0] = true; - EXPECT_FALSE(ContainsKey(info.usage_map, kPersistent)); - EXPECT_TRUE(ContainsKey(info.usage_map, kTemporary)); + EXPECT_FALSE(base::ContainsKey(info.usage_map, kPersistent)); + EXPECT_TRUE(base::ContainsKey(info.usage_map, kTemporary)); EXPECT_EQ(kEmptyFileSystemSize, info.usage_map.at(storage::kFileSystemTypeTemporary)); } else if (info.origin == kOrigin2) { EXPECT_FALSE(test_hosts_found[1]); test_hosts_found[1] = true; - EXPECT_TRUE(ContainsKey(info.usage_map, kPersistent)); - EXPECT_FALSE(ContainsKey(info.usage_map, kTemporary)); + EXPECT_TRUE(base::ContainsKey(info.usage_map, kPersistent)); + EXPECT_FALSE(base::ContainsKey(info.usage_map, kTemporary)); EXPECT_EQ(kEmptyFileSystemSize, info.usage_map.at(kPersistent)); } else if (info.origin == kOrigin3) { EXPECT_FALSE(test_hosts_found[2]); test_hosts_found[2] = true; - EXPECT_TRUE(ContainsKey(info.usage_map, kPersistent)); - EXPECT_TRUE(ContainsKey(info.usage_map, kTemporary)); + EXPECT_TRUE(base::ContainsKey(info.usage_map, kPersistent)); + EXPECT_TRUE(base::ContainsKey(info.usage_map, kTemporary)); EXPECT_EQ(kEmptyFileSystemSize, info.usage_map.at(kPersistent)); EXPECT_EQ(kEmptyFileSystemSize, info.usage_map.at(kTemporary)); } else { @@ -254,8 +254,8 @@ BrowsingDataFileSystemHelper::FileSystemInfo info = *(file_system_info_list_->begin()); EXPECT_EQ(kOrigin3, info.origin); - EXPECT_TRUE(ContainsKey(info.usage_map, kPersistent)); - EXPECT_TRUE(ContainsKey(info.usage_map, kTemporary)); + EXPECT_TRUE(base::ContainsKey(info.usage_map, kPersistent)); + EXPECT_TRUE(base::ContainsKey(info.usage_map, kTemporary)); EXPECT_EQ(kEmptyFileSystemSize, info.usage_map[kPersistent]); EXPECT_EQ(kEmptyFileSystemSize, info.usage_map[kTemporary]); } @@ -282,14 +282,14 @@ std::list<BrowsingDataFileSystemHelper::FileSystemInfo>::iterator info = file_system_info_list_->begin(); EXPECT_EQ(kOrigin1, info->origin); - EXPECT_TRUE(ContainsKey(info->usage_map, kPersistent)); - EXPECT_FALSE(ContainsKey(info->usage_map, kTemporary)); + EXPECT_TRUE(base::ContainsKey(info->usage_map, kPersistent)); + EXPECT_FALSE(base::ContainsKey(info->usage_map, kTemporary)); EXPECT_EQ(200, info->usage_map[kPersistent]); info++; EXPECT_EQ(kOrigin2, info->origin); - EXPECT_FALSE(ContainsKey(info->usage_map, kPersistent)); - EXPECT_TRUE(ContainsKey(info->usage_map, kTemporary)); + EXPECT_FALSE(base::ContainsKey(info->usage_map, kPersistent)); + EXPECT_TRUE(base::ContainsKey(info->usage_map, kTemporary)); EXPECT_EQ(100, info->usage_map[kTemporary]); }
diff --git a/chrome/browser/browsing_data/mock_browsing_data_channel_id_helper.cc b/chrome/browser/browsing_data/mock_browsing_data_channel_id_helper.cc index 357d9c89..2e8fd22c 100644 --- a/chrome/browser/browsing_data/mock_browsing_data_channel_id_helper.cc +++ b/chrome/browser/browsing_data/mock_browsing_data_channel_id_helper.cc
@@ -27,13 +27,13 @@ void MockBrowsingDataChannelIDHelper::DeleteChannelID( const std::string& server_id) { ASSERT_FALSE(callback_.is_null()); - ASSERT_TRUE(ContainsKey(channel_ids_, server_id)); + ASSERT_TRUE(base::ContainsKey(channel_ids_, server_id)); channel_ids_[server_id] = false; } void MockBrowsingDataChannelIDHelper::AddChannelIDSample( const std::string& server_id) { - ASSERT_FALSE(ContainsKey(channel_ids_, server_id)); + ASSERT_FALSE(base::ContainsKey(channel_ids_, server_id)); std::unique_ptr<crypto::ECPrivateKey> key(crypto::ECPrivateKey::Create()); channel_id_list_.push_back( net::ChannelIDStore::ChannelID(server_id, base::Time(), std::move(key)));
diff --git a/chrome/browser/browsing_data/mock_browsing_data_cookie_helper.cc b/chrome/browser/browsing_data/mock_browsing_data_cookie_helper.cc index 7183661..d98feee 100644 --- a/chrome/browser/browsing_data/mock_browsing_data_cookie_helper.cc +++ b/chrome/browser/browsing_data/mock_browsing_data_cookie_helper.cc
@@ -31,7 +31,7 @@ const net::CanonicalCookie& cookie) { ASSERT_FALSE(callback_.is_null()); std::string key = cookie.Name() + "=" + cookie.Value(); - ASSERT_TRUE(ContainsKey(cookies_, key)); + ASSERT_TRUE(base::ContainsKey(cookies_, key)); cookies_[key] = false; }
diff --git a/chrome/browser/browsing_data/mock_browsing_data_database_helper.cc b/chrome/browser/browsing_data/mock_browsing_data_database_helper.cc index cf53c37..45c8b90 100644 --- a/chrome/browser/browsing_data/mock_browsing_data_database_helper.cc +++ b/chrome/browser/browsing_data/mock_browsing_data_database_helper.cc
@@ -28,7 +28,7 @@ const std::string& name) { ASSERT_FALSE(callback_.is_null()); std::string key = origin + ":" + name; - ASSERT_TRUE(ContainsKey(databases_, key)); + ASSERT_TRUE(base::ContainsKey(databases_, key)); last_deleted_origin_ = origin; last_deleted_db_ = name; databases_[key] = false;
diff --git a/chrome/browser/browsing_data/mock_browsing_data_file_system_helper.cc b/chrome/browser/browsing_data/mock_browsing_data_file_system_helper.cc index 14e9413..d76ec10 100644 --- a/chrome/browser/browsing_data/mock_browsing_data_file_system_helper.cc +++ b/chrome/browser/browsing_data/mock_browsing_data_file_system_helper.cc
@@ -27,7 +27,7 @@ const GURL& origin) { ASSERT_FALSE(callback_.is_null()); std::string key = origin.spec(); - ASSERT_TRUE(ContainsKey(file_systems_, key)); + ASSERT_TRUE(base::ContainsKey(file_systems_, key)); last_deleted_origin_ = origin; file_systems_[key] = false; }
diff --git a/chrome/browser/browsing_data/mock_browsing_data_indexed_db_helper.cc b/chrome/browser/browsing_data/mock_browsing_data_indexed_db_helper.cc index 42e1f6d..e5ad8ff9 100644 --- a/chrome/browser/browsing_data/mock_browsing_data_indexed_db_helper.cc +++ b/chrome/browser/browsing_data/mock_browsing_data_indexed_db_helper.cc
@@ -32,7 +32,7 @@ void MockBrowsingDataIndexedDBHelper::DeleteIndexedDB( const GURL& origin) { ASSERT_FALSE(callback_.is_null()); - ASSERT_TRUE(ContainsKey(origins_, origin)); + ASSERT_TRUE(base::ContainsKey(origins_, origin)); origins_[origin] = false; }
diff --git a/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.cc b/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.cc index 2c17d57..faebe3a 100644 --- a/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.cc +++ b/chrome/browser/browsing_data/mock_browsing_data_local_storage_helper.cc
@@ -27,7 +27,7 @@ void MockBrowsingDataLocalStorageHelper::DeleteOrigin( const GURL& origin) { ASSERT_FALSE(callback_.is_null()); - ASSERT_TRUE(ContainsKey(origins_, origin)); + ASSERT_TRUE(base::ContainsKey(origins_, origin)); last_deleted_origin_ = origin; origins_[origin] = false; }
diff --git a/chrome/browser/browsing_data/mock_browsing_data_service_worker_helper.cc b/chrome/browser/browsing_data/mock_browsing_data_service_worker_helper.cc index d047f78..b8f93e6 100644 --- a/chrome/browser/browsing_data/mock_browsing_data_service_worker_helper.cc +++ b/chrome/browser/browsing_data/mock_browsing_data_service_worker_helper.cc
@@ -34,7 +34,7 @@ void MockBrowsingDataServiceWorkerHelper::DeleteServiceWorkers( const GURL& origin) { ASSERT_FALSE(callback_.is_null()); - ASSERT_TRUE(ContainsKey(origins_, origin)); + ASSERT_TRUE(base::ContainsKey(origins_, origin)); origins_[origin] = false; }
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index a868c5e..1f980cb 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -248,7 +248,7 @@ #if defined(USE_AURA) #include "services/shell/runner/common/client_util.h" -#include "services/ui/common/gpu_service.h" +#include "services/ui/public/cpp/gpu_service.h" #include "ui/views/mus/window_manager_connection.h" #endif @@ -1619,7 +1619,6 @@ #endif switches::kEnableNetBenchmarking, switches::kEnableNewBookmarkApps, - switches::kEnableWasm, #if !defined(DISABLE_NACL) switches::kForcePNaClSubzero, #endif
diff --git a/chrome/browser/chromeos/accessibility/accessibility_manager.cc b/chrome/browser/chromeos/accessibility/accessibility_manager.cc index 8dee3337..9039d729 100644 --- a/chrome/browser/chromeos/accessibility/accessibility_manager.cc +++ b/chrome/browser/chromeos/accessibility/accessibility_manager.cc
@@ -10,6 +10,7 @@ #include <memory> #include <utility> +#include "ash/aura/wm_window_aura.h" #include "ash/autoclick/autoclick_controller.h" #include "ash/common/session/session_state_delegate.h" #include "ash/common/wm_shell.h" @@ -1522,7 +1523,8 @@ chromevox_panel_widget_observer_.reset(nullptr); chromevox_panel_ = nullptr; - ash::Shelf* shelf = ash::Shelf::ForWindow(root_window); + ash::Shelf* shelf = + ash::Shelf::ForWindow(ash::WmWindowAura::Get(root_window)); if (!shelf) return;
diff --git a/chrome/browser/chromeos/accessibility/chromevox_panel.cc b/chrome/browser/chromeos/accessibility/chromevox_panel.cc index b043ce8..f0a5d78 100644 --- a/chrome/browser/chromeos/accessibility/chromevox_panel.cc +++ b/chrome/browser/chromeos/accessibility/chromevox_panel.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "ash/aura/wm_window_aura.h" #include "ash/common/accessibility_types.h" #include "ash/common/shell_window_ids.h" #include "ash/root_window_controller.h" @@ -115,7 +116,8 @@ } void ChromeVoxPanel::UpdatePanelHeight() { - ash::Shelf* shelf = ash::Shelf::ForWindow(GetRootWindow()); + ash::Shelf* shelf = + ash::Shelf::ForWindow(ash::WmWindowAura::Get(GetRootWindow())); if (!shelf) return;
diff --git a/chrome/browser/chromeos/arc/arc_auth_service.cc b/chrome/browser/chromeos/arc/arc_auth_service.cc index aa330059..99750711 100644 --- a/chrome/browser/chromeos/arc/arc_auth_service.cc +++ b/chrome/browser/chromeos/arc/arc_auth_service.cc
@@ -234,13 +234,52 @@ // user noticing. OnSignInFailedInternal(ProvisioningResult::ARC_STOPPED); } - if (!clear_required_) + + if (clear_required_) { + // This should be always true, but just in case as this is looked at + // inside RemoveArcData() at first. + DCHECK(arc_bridge_service()->stopped()); + RemoveArcData(); + } else { + // To support special "Stop and enable ARC" procedure for enterprise, + // here call OnArcDataRemoved(true) as if the data removal is successfully + // done. + // TODO(hidehiko): Restructure the code. + OnArcDataRemoved(true); + } +} + +void ArcAuthService::RemoveArcData() { + if (!arc_bridge_service()->stopped()) { + // Just set a flag. On bridge stopped, this will be re-called, + // then session manager should remove the data. + clear_required_ = true; return; + } clear_required_ = false; chromeos::DBusThreadManager::Get()->GetSessionManagerClient()->RemoveArcData( cryptohome::Identification( multi_user_util::GetAccountIdFromProfile(profile_)), - chromeos::SessionManagerClient::ArcCallback()); + base::Bind(&ArcAuthService::OnArcDataRemoved, + weak_ptr_factory_.GetWeakPtr())); +} + +void ArcAuthService::OnArcDataRemoved(bool success) { + LOG_IF(ERROR, !success) << "Required ARC user data wipe failed."; + + // Here check if |reenable_arc_| is marked or not. + // The only case this happens should be in the special case for enterprise + // "on managed lost" case. In that case, OnBridgeStopped() should trigger + // the RemoveArcData(), then this. + // TODO(hidehiko): Restructure the code. + if (!reenable_arc_) + return; + + // Restart ARC anyway. Let the enterprise reporting instance decide whether + // the ARC user data wipe is still required or not. + reenable_arc_ = false; + VLOG(1) << "Reenable ARC"; + EnableArc(); } std::string ArcAuthService::GetAndResetAuthCode() { @@ -352,7 +391,7 @@ result == ProvisioningResult::CLOUD_PROVISION_FLOW_TIMEOUT || result == ProvisioningResult::CLOUD_PROVISION_FLOW_INTERNAL_ERROR || result == ProvisioningResult::UNKNOWN_ERROR) - clear_required_ = true; + RemoveArcData(); // We'll delay shutting down the bridge in this case to allow people to send // feedback. @@ -421,6 +460,7 @@ if (profile_->GetPrefs()->GetBoolean(prefs::kArcEnabled)) { OnOptInPreferenceChanged(); } else { + RemoveArcData(); UpdateEnabledStateUMA(false); PrefServiceSyncableFromProfile(profile_)->AddObserver(this); OnIsSyncingChanged(); @@ -527,6 +567,7 @@ if (!arc_enabled) { StopArc(); + RemoveArcData(); return; } @@ -597,6 +638,15 @@ OnOptInUIShowPage(ui_page_, ui_page_status_)); } +// This is the special method to support enterprise mojo API. +// TODO(hidehiko): Remove this. +void ArcAuthService::StopAndEnableArc() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK(!arc_bridge_service()->stopped()); + reenable_arc_ = true; + StopArc(); +} + void ArcAuthService::StartArc() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); arc_bridge_service()->HandleStartup();
diff --git a/chrome/browser/chromeos/arc/arc_auth_service.h b/chrome/browser/chromeos/arc/arc_auth_service.h index 3466f88..4a2c8eb 100644 --- a/chrome/browser/chromeos/arc/arc_auth_service.h +++ b/chrome/browser/chromeos/arc/arc_auth_service.h
@@ -181,6 +181,15 @@ // Stops ARC without changing ArcEnabled preference. void StopArc(); + // StopArc(), then EnableArc(). Between them data clear may happens. + // This is a special method to support enterprise device lost case. + // This can be called only when ARC is running. + void StopAndEnableArc(); + + // Removes the data if ARC is stopped. Otherwise, queue to remove the data + // on ARC is stopped. + void RemoveArcData(); + // Returns current page that has to be shown in OptIn UI. UIPage ui_page() const { return ui_page_; } @@ -201,6 +210,7 @@ void StartAndroidManagementClient(); void CheckAndroidManagement(bool background_mode); void StartArcIfSignedIn(); + void OnArcDataRemoved(bool success); // Unowned pointer. Keeps current profile. Profile* profile_ = nullptr; @@ -219,6 +229,7 @@ UIPage ui_page_ = UIPage::NO_PAGE; base::string16 ui_page_status_; bool clear_required_ = false; + bool reenable_arc_ = false; bool waiting_for_reply_ = false; std::unique_ptr<ArcAuthContext> context_;
diff --git a/chrome/browser/chromeos/arc/arc_auth_service_unittest.cc b/chrome/browser/chromeos/arc/arc_auth_service_unittest.cc index 1fb5b02..f9be5c2 100644 --- a/chrome/browser/chromeos/arc/arc_auth_service_unittest.cc +++ b/chrome/browser/chromeos/arc/arc_auth_service_unittest.cc
@@ -25,6 +25,7 @@ #include "chrome/common/pref_names.h" #include "chrome/test/base/testing_profile.h" #include "chromeos/chromeos_switches.h" +#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/login/user_names.h" #include "components/arc/arc_bridge_service.h" #include "components/arc/test/fake_arc_bridge_service.h" @@ -57,6 +58,8 @@ ~ArcAuthServiceTest() override = default; void SetUp() override { + chromeos::DBusThreadManager::Initialize(); + base::CommandLine::ForCurrentProcess()->AppendSwitch( chromeos::switches::kEnableArc); ArcAuthService::DisableUIForTesting(); @@ -83,7 +86,10 @@ chromeos::WallpaperManager::Initialize(); } - void TearDown() override { chromeos::WallpaperManager::Shutdown(); } + void TearDown() override { + chromeos::WallpaperManager::Shutdown(); + chromeos::DBusThreadManager::Shutdown(); + } chromeos::FakeChromeUserManager* GetFakeUserManager() const { return static_cast<chromeos::FakeChromeUserManager*>(
diff --git a/chrome/browser/chromeos/arc/arc_enterprise_reporting_service.cc b/chrome/browser/chromeos/arc/arc_enterprise_reporting_service.cc index 47babc73..674de87 100644 --- a/chrome/browser/chromeos/arc/arc_enterprise_reporting_service.cc +++ b/chrome/browser/chromeos/arc/arc_enterprise_reporting_service.cc
@@ -38,22 +38,9 @@ if (state == mojom::ManagementState::MANAGED_DO_LOST) { DCHECK(arc::ArcServiceManager::Get()); - ArcServiceManager::Get()->arc_user_data_service()->RequireUserDataWiped( - base::Bind(&ArcEnterpriseReportingService::RestartArc, - weak_ptr_factory_.GetWeakPtr())); - ArcAuthService::Get()->StopArc(); + ArcAuthService::Get()->RemoveArcData(); + ArcAuthService::Get()->StopAndEnableArc(); } } -void ArcEnterpriseReportingService::RestartArc(bool result) { - DCHECK(thread_checker_.CalledOnValidThread()); - if (!result) - LOG(ERROR) << "Required ARC user data wipe failed."; - - // Restart ARC anyway. Let the enterprise reporting instance decide whether - // the ARC user data wipe is still required or not. - VLOG(1) << "Restart ARC"; - ArcAuthService::Get()->EnableArc(); -} - } // namespace arc
diff --git a/chrome/browser/chromeos/arc/arc_enterprise_reporting_service.h b/chrome/browser/chromeos/arc/arc_enterprise_reporting_service.h index 129b68d..35f8ca3 100644 --- a/chrome/browser/chromeos/arc/arc_enterprise_reporting_service.h +++ b/chrome/browser/chromeos/arc/arc_enterprise_reporting_service.h
@@ -33,9 +33,6 @@ void ReportManagementState(mojom::ManagementState state) override; private: - // DBus callback, restarts ARC after ARC user data wipe. - void RestartArc(bool success); - base::ThreadChecker thread_checker_; mojo::Binding<mojom::EnterpriseReportingHost> binding_;
diff --git a/chrome/browser/chromeos/arc/arc_process_service.cc b/chrome/browser/chromeos/arc/arc_process_service.cc index 78a203c3e..e9f8b52 100644 --- a/chrome/browser/chromeos/arc/arc_process_service.cc +++ b/chrome/browser/chromeos/arc/arc_process_service.cc
@@ -40,7 +40,9 @@ ArcProcessService::ArcProcessService(ArcBridgeService* bridge_service) : ArcService(bridge_service), - worker_pool_(new SequencedWorkerPool(1, "arc_process_manager")), + worker_pool_(new SequencedWorkerPool(1, + "arc_process_manager", + base::TaskPriority::USER_VISIBLE)), weak_ptr_factory_(this) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); arc_bridge_service()->process()->AddObserver(this);
diff --git a/chrome/browser/chromeos/extensions/file_manager/event_router.cc b/chrome/browser/chromeos/extensions/file_manager/event_router.cc index ae9c5fa1..b950bc5 100644 --- a/chrome/browser/chromeos/extensions/file_manager/event_router.cc +++ b/chrome/browser/chromeos/extensions/file_manager/event_router.cc
@@ -397,7 +397,7 @@ DLOG_IF(WARNING, !file_watchers_.empty()) << "Not all file watchers are " << "removed. This can happen when Files.app is open during shutdown."; - STLDeleteValues(&file_watchers_); + base::STLDeleteValues(&file_watchers_); if (!profile_) { NOTREACHED(); return;
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc b/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc index 74169ce..26265b0 100644 --- a/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc +++ b/chrome/browser/chromeos/extensions/file_manager/file_manager_private_apitest.cc
@@ -172,7 +172,7 @@ DCHECK(!disk_mount_manager_mock_); DCHECK(!testing_profile_); DCHECK(!event_router_); - STLDeleteValues(&volumes_); + base::STLDeleteValues(&volumes_); } void SetUpOnMainThread() override {
diff --git a/chrome/browser/chromeos/extensions/gfx_utils.cc b/chrome/browser/chromeos/extensions/gfx_utils.cc index 0b867db..49737a6 100644 --- a/chrome/browser/chromeos/extensions/gfx_utils.cc +++ b/chrome/browser/chromeos/extensions/gfx_utils.cc
@@ -4,10 +4,12 @@ #include "chrome/browser/chromeos/extensions/gfx_utils.h" +#include "base/lazy_instance.h" #include "chrome/browser/chromeos/arc/arc_auth_service.h" #include "chrome/browser/chromeos/arc/arc_support_host.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" #include "chrome/common/extensions/extension_constants.h" #include "chrome/common/pref_names.h" @@ -19,8 +21,167 @@ #include "ui/gfx/image/image_skia_operations.h" namespace extensions { + +namespace { + +// The badge map between |arc_package_name| and |extension_id|. Note the mapping +// from |extension_id| to |arc_package_name| is unique, but the mapping from +// |arc_package_name| to |extension_id| is not. +const struct { + const char* arc_package_name; + const char* extension_id; +} kDualBadgeMap[] = { + // Google Keep + {"com.google.android.keep", "hmjkmjkepdijhoojdojkdfohbdgmmhki"}, + {"com.google.android.keep", "dondgdlndnpianbklfnehgdhkickdjck"}, + // GMail + {"com.google.android.gm", extension_misc::kGmailAppId}, + {"com.google.android.gm", "bjdhhokmhgelphffoafoejjmlfblpdha"}, + // Google Drive + {"com.google.android.apps.docs", extension_misc::kDriveHostedAppId}, + {"com.google.android.apps.docs", "mdhnphfgagkpdhndljccoackjjhghlif"}, + // Google Maps + {"com.google.android.apps.maps", "lneaknkopdijkpnocmklfnjbeapigfbh"}, + // Calculator + {"com.google.android.calculator", "joodangkbfjnajiiifokapkpmhfnpleo"}, + // Chrome Remote Desktop + {"com.google.chromeremotedesktop", "gbchcmhmhahfdphkhkmpfmihenigjmpp"}, + {"com.google.chromeremotedesktop", "cdjikkcakjcdjemakobkmijmikhkegcj"}, + // Google Calender + {"com.google.android.calendar", "ejjicmeblgpmajnghnpcppodonldlgfn"}, + {"com.google.android.calendar", "fpgfohogebplgnamlafljlcidjedbdeb"}, + // Google Docs + {"com.google.android.apps.docs.editors.docs", + extension_misc::kGoogleDocAppId}, + {"com.google.android.apps.docs.editors.docs", + "npnjdccdffhdndcbeappiamcehbhjibf"}, + // Google Slides + {"com.google.android.apps.docs.editors.slides", + extension_misc::kGoogleSlidesAppId}, + {"com.google.android.apps.docs.editors.slides", + "hdmobeajeoanbanmdlabnbnlopepchip"}, + // Google Sheets + {"com.google.android.apps.docs.editors.sheets", + extension_misc::kGoogleSheetsAppId}, + {"com.google.android.apps.docs.editors.sheets", + "nifkmgcdokhkjghdlgflonppnefddien"}, + // YouTube + {"com.google.android.youtube", extension_misc::kYoutubeAppId}, + {"com.google.android.youtube", "pbdihpaifchmclcmkfdgffnnpfbobefh"}, + // Google Play Books + {"com.google.android.apps.books", "mmimngoggfoobjdlefbcabngfnmieonb"}, + // Google+ + {"com.google.android.apps.plus", "dlppkpafhbajpcmmoheippocdidnckmm"}, + {"com.google.android.apps.plus", "fgjnkhlabjcaajddbaenilcmpcidahll"}, + // Google Play Movies & TV + {"com.google.android.videos", "gdijeikdkaembjbdobgfkoidjkpbmlkd"}, + {"com.google.android.videos", "amfoiggnkefambnaaphodjdmdooiinna"}, + // Google Play Music + {"com.google.android.music", extension_misc::kGooglePlayMusicAppId}, + {"com.google.android.music", "onbhgdmifjebcabplolilidlpgeknifi"}, + // Google Now + {"com.google.android.launcher", "mnfadmojomeniojkkikjpgjaegolkbpb"}, + // Google Photos + {"com.google.android.apps.photos", "hcglmfcclpfgljeaiahehebeoaiicbko"}, + {"com.google.android.apps.photos", "efjnaogkjbogokcnohkmnjdojkikgobo"}, + {"com.google.android.apps.photos", "ifpkhncdnjfipfjlhfidljjffdgklanh"}, + // Google Classroom + {"com.google.android.apps.classroom", "mfhehppjhmmnlfbbopchdfldgimhfhfk"}, + // Google Hangouts + {"com.google.android.talk", "knipolnnllmklapflnccelgolnpehhpl"}, + {"com.google.android.talk", "cgmlfbhkckbedohgdepgbkflommbfkep"}, + {"com.google.android.talk", "gldgpnmcpaogjlojhhpebkbbanacoglc"}, + // Google Play Music + {"com.google.android.music", "fahmaaghhglfmonjliepjlchgpgfmobi"}, + // Google News + {"com.google.android.apps.genie.geniewidget", + "dllkocilcinkggkchnjgegijklcililc"}, +}; + +// This class maintains the maps between the extension id and its equivalent +// Arc package name. +class AppDualBadgeMap { + public: + using ArcAppToExtensionsMap = + std::unordered_map<std::string, std::vector<std::string>>; + using ExtensionToArcAppMap = std::unordered_map<std::string, std::string>; + + AppDualBadgeMap() { + for (size_t i = 0; i < arraysize(kDualBadgeMap); ++i) { + arc_app_to_extensions_map_[kDualBadgeMap[i].arc_package_name].push_back( + kDualBadgeMap[i].extension_id); + extension_to_arc_app_map_[kDualBadgeMap[i].extension_id] = + kDualBadgeMap[i].arc_package_name; + } + } + + std::vector<std::string> GetExtensionIdsForArcPackageName( + std::string arc_package_name) { + const auto iter = arc_app_to_extensions_map_.find(arc_package_name); + if (iter == arc_app_to_extensions_map_.end()) + return std::vector<std::string>(); + return iter->second; + } + + std::string GetArcPackageNameFromExtensionId(std::string extension_id) { + const auto iter = extension_to_arc_app_map_.find(extension_id); + if (iter == extension_to_arc_app_map_.end()) + return std::string(); + return iter->second; + } + + private: + ArcAppToExtensionsMap arc_app_to_extensions_map_; + ExtensionToArcAppMap extension_to_arc_app_map_; + + DISALLOW_COPY_AND_ASSIGN(AppDualBadgeMap); +}; + +base::LazyInstance<AppDualBadgeMap> g_dual_badge_map = + LAZY_INSTANCE_INITIALIZER; + +} // namespace + namespace util { +std::string GetEquivalentInstalledArcApp(content::BrowserContext* context, + const std::string& extension_id) { + const std::string arc_package_name = + g_dual_badge_map.Get().GetArcPackageNameFromExtensionId(extension_id); + if (arc_package_name.empty()) + return std::string(); + + ArcAppListPrefs* prefs = ArcAppListPrefs::Get(context); + if (prefs) { + std::unique_ptr<ArcAppListPrefs::PackageInfo> arc_info = + prefs->GetPackage(arc_package_name); + if (arc_info.get() && !arc_info->package_name.empty()) + return arc_package_name; + } + return std::string(); +} + +const std::vector<std::string> GetEquivalentInstalledExtensions( + content::BrowserContext* context, + const std::string& arc_package_name) { + const ExtensionRegistry* registry = ExtensionRegistry::Get(context); + if (!registry) + return std::vector<std::string>(); + + std::vector<std::string> extension_ids = + g_dual_badge_map.Get().GetExtensionIdsForArcPackageName(arc_package_name); + if (extension_ids.empty()) + return std::vector<std::string>(); + + extension_ids.erase( + std::remove_if(extension_ids.begin(), extension_ids.end(), + [registry](std::string extension_id) { + return !registry->GetInstalledExtension(extension_id); + }), + extension_ids.end()); + return extension_ids; +} + void MaybeApplyChromeBadge(content::BrowserContext* context, const std::string& extension_id, gfx::ImageSkia* icon_out) { @@ -41,20 +202,13 @@ return; } - // No badge on Chrome browser or the Play store app. - if (extension_id == extension_misc::kChromeAppId || - extension_id == ArcSupportHost::kHostAppId) { - return; - } - const ExtensionRegistry* registry = ExtensionRegistry::Get(context); - if (!registry) + if (!registry || !registry->GetInstalledExtension(extension_id)) return; - const Extension* extension = registry->GetInstalledExtension(extension_id); - // Only badge Chrome apps that can open in a tab. Platform apps can only be - // opened in a window. - if (!extension || extension->is_platform_app()) + std::string arc_package_name = + GetEquivalentInstalledArcApp(context, extension_id); + if (arc_package_name.empty()) return; const gfx::ImageSkia* badge_image =
diff --git a/chrome/browser/chromeos/extensions/gfx_utils.h b/chrome/browser/chromeos/extensions/gfx_utils.h index b42653ea..e8da2678 100644 --- a/chrome/browser/chromeos/extensions/gfx_utils.h +++ b/chrome/browser/chromeos/extensions/gfx_utils.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_CHROMEOS_EXTENSIONS_GFX_UTILS_H_ #include <string> +#include <vector> namespace content { class BrowserContext; @@ -18,6 +19,19 @@ namespace extensions { namespace util { +// Returns the equivalent Playstore app package name that has been installed to +// the Chrome extension (identified by ||extension_id|). Returns an empty string +// if there is no such Playstore app. +std::string GetEquivalentInstalledArcApp(content::BrowserContext* context, + const std::string& extension_id); + +// Returns the equivalent Chrome extensions that have been installed to the +// Playstore app (identified by |arc_package_name|). Returns an empty vector if +// there is no such Chrome extension. +const std::vector<std::string> GetEquivalentInstalledExtensions( + content::BrowserContext* context, + const std::string& arc_package_name); + // May apply additional badge in order to distinguish dual apps from Chrome and // Android side. void MaybeApplyChromeBadge(content::BrowserContext* context,
diff --git a/chrome/browser/chromeos/extensions/gfx_utils_unittest.cc b/chrome/browser/chromeos/extensions/gfx_utils_unittest.cc new file mode 100644 index 0000000..1f0c8cf --- /dev/null +++ b/chrome/browser/chromeos/extensions/gfx_utils_unittest.cc
@@ -0,0 +1,176 @@ +// Copyright 2016 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/extensions/gfx_utils.h" + +#include "base/macros.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/extensions/extension_service_test_base.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/app_list/arc/arc_app_test.h" +#include "chrome/test/base/testing_profile.h" +#include "components/arc/test/fake_app_instance.h" +#include "extensions/common/extension.h" +#include "extensions/common/extension_builder.h" + +namespace extensions { + +namespace { + +const char* kGmailArcPackage = "com.google.android.gm"; +const char* kGmailExtensionId1 = "pjkljhegncpnkpknbcohdijeoejaedia"; +const char* kGmailExtensionId2 = "bjdhhokmhgelphffoafoejjmlfblpdha"; + +const char* kDriveArcPackage = "com.google.android.apps.docs"; +const char* kKeepExtensionId = "hmjkmjkepdijhoojdojkdfohbdgmmhki"; + +} // namespace + +class DualBadgeMapTest : public ExtensionServiceTestBase { + public: + DualBadgeMapTest() {} + ~DualBadgeMapTest() override { profile_.reset(); } + + void SetUp() override { + extensions::ExtensionServiceTestBase::SetUp(); + InitializeEmptyExtensionService(); + arc_test_.SetUp(profile_.get()); + } + + void TearDown() override { arc_test_.TearDown(); } + + Profile* profile() { return profile_.get(); } + + protected: + arc::mojom::ArcPackageInfo CreateArcPackage(const std::string& package_name) { + arc::mojom::ArcPackageInfo package; + package.package_name = package_name; + package.package_version = 1; + package.last_backup_android_id = 1; + package.last_backup_time = 1; + package.sync = false; + return package; + } + + void AddArcPackage(const arc::mojom::ArcPackageInfo& package) { + arc_test_.AddPackage(package); + arc_test_.app_instance()->SendPackageAdded(package); + } + + void RemoveArcPackage(const arc::mojom::ArcPackageInfo& package) { + arc_test_.RemovePackage(package); + arc_test_.app_instance()->SendPackageUninstalled(package.package_name); + } + + scoped_refptr<Extension> CreateExtension(const std::string& id) { + return ExtensionBuilder() + .SetManifest(DictionaryBuilder() + .Set("name", "test") + .Set("version", "0.1") + .Build()) + .SetID(id) + .Build(); + } + + void AddExtension(const Extension* extension) { + service()->AddExtension(extension); + } + + void RemoveExtension(const Extension* extension) { + service()->UninstallExtension(extension->id(), + extensions::UNINSTALL_REASON_FOR_TESTING, + base::Bind(&base::DoNothing), NULL); + } + + private: + ArcAppTest arc_test_; + + DISALLOW_COPY_AND_ASSIGN(DualBadgeMapTest); +}; + +TEST_F(DualBadgeMapTest, ExtensionToArcAppMapTest) { + // Install two Gmail extension apps. + AddExtension(CreateExtension(kGmailExtensionId1).get()); + AddExtension(CreateExtension(kGmailExtensionId2).get()); + + EXPECT_EQ("", extensions::util::GetEquivalentInstalledArcApp( + profile(), kGmailExtensionId1)); + EXPECT_EQ("", extensions::util::GetEquivalentInstalledArcApp( + profile(), kGmailExtensionId2)); + + // Install Gmail Playstore app. + const arc::mojom::ArcPackageInfo app_info = + CreateArcPackage(kGmailArcPackage); + AddArcPackage(app_info); + EXPECT_EQ(kGmailArcPackage, extensions::util::GetEquivalentInstalledArcApp( + profile(), kGmailExtensionId1)); + EXPECT_EQ(kGmailArcPackage, extensions::util::GetEquivalentInstalledArcApp( + profile(), kGmailExtensionId2)); + + RemoveArcPackage(app_info); + EXPECT_EQ("", extensions::util::GetEquivalentInstalledArcApp( + profile(), kGmailExtensionId1)); + EXPECT_EQ("", extensions::util::GetEquivalentInstalledArcApp( + profile(), kGmailExtensionId2)); + + // Install an unrelated Playstore app. + AddArcPackage(CreateArcPackage(kDriveArcPackage)); + EXPECT_EQ("", extensions::util::GetEquivalentInstalledArcApp( + profile(), kGmailExtensionId1)); + EXPECT_EQ("", extensions::util::GetEquivalentInstalledArcApp( + profile(), kGmailExtensionId2)); +} + +TEST_F(DualBadgeMapTest, ArcAppToExtensionMapTest) { + // Install Gmail Playstore app. + AddArcPackage(CreateArcPackage(kGmailArcPackage)); + + std::vector<std::string> extension_ids = + extensions::util::GetEquivalentInstalledExtensions(profile(), + kGmailArcPackage); + EXPECT_TRUE(0 == extension_ids.size()); + + // Install Gmail extension app. + scoped_refptr<Extension> extension1 = CreateExtension(kGmailExtensionId1); + AddExtension(extension1.get()); + extension_ids = extensions::util::GetEquivalentInstalledExtensions( + profile(), kGmailArcPackage); + EXPECT_TRUE(1 == extension_ids.size()); + EXPECT_TRUE(std::find(extension_ids.begin(), extension_ids.end(), + kGmailExtensionId1) != extension_ids.end()); + + // Install another Gmail extension app. + scoped_refptr<Extension> extension2 = CreateExtension(kGmailExtensionId2); + AddExtension(extension2.get()); + extension_ids = extensions::util::GetEquivalentInstalledExtensions( + profile(), kGmailArcPackage); + EXPECT_TRUE(2 == extension_ids.size()); + EXPECT_TRUE(std::find(extension_ids.begin(), extension_ids.end(), + kGmailExtensionId1) != extension_ids.end()); + EXPECT_TRUE(std::find(extension_ids.begin(), extension_ids.end(), + kGmailExtensionId2) != extension_ids.end()); + + RemoveExtension(extension1.get()); + extension_ids = extensions::util::GetEquivalentInstalledExtensions( + profile(), kGmailArcPackage); + EXPECT_TRUE(1 == extension_ids.size()); + EXPECT_FALSE(std::find(extension_ids.begin(), extension_ids.end(), + kGmailExtensionId1) != extension_ids.end()); + EXPECT_TRUE(std::find(extension_ids.begin(), extension_ids.end(), + kGmailExtensionId2) != extension_ids.end()); + + RemoveExtension(extension2.get()); + extension_ids = extensions::util::GetEquivalentInstalledExtensions( + profile(), kGmailArcPackage); + EXPECT_TRUE(0 == extension_ids.size()); + + // Install an unrelated Google Keep extension app. + scoped_refptr<Extension> extension = CreateExtension(kKeepExtensionId); + AddExtension(extension.get()); + extension_ids = extensions::util::GetEquivalentInstalledExtensions( + profile(), kGmailArcPackage); + EXPECT_TRUE(0 == extension_ids.size()); +} + +} // namespace extensions
diff --git a/chrome/browser/chromeos/file_manager/fake_disk_mount_manager.cc b/chrome/browser/chromeos/file_manager/fake_disk_mount_manager.cc index 82fcf407..a740093 100644 --- a/chrome/browser/chromeos/file_manager/fake_disk_mount_manager.cc +++ b/chrome/browser/chromeos/file_manager/fake_disk_mount_manager.cc
@@ -35,7 +35,7 @@ } FakeDiskMountManager::~FakeDiskMountManager() { - STLDeleteValues(&disks_); + base::STLDeleteValues(&disks_); } void FakeDiskMountManager::AddObserver(Observer* observer) {
diff --git a/chrome/browser/chromeos/file_manager/file_browser_handlers.cc b/chrome/browser/chromeos/file_manager/file_browser_handlers.cc index cae2455..013aada6 100644 --- a/chrome/browser/chromeos/file_manager/file_browser_handlers.cc +++ b/chrome/browser/chromeos/file_manager/file_browser_handlers.cc
@@ -520,7 +520,7 @@ for (FileBrowserHandlerList::const_iterator itr = handlers.begin(); itr != handlers.end(); ++itr) { - if (ContainsKey(common_handler_set, *itr)) + if (base::ContainsKey(common_handler_set, *itr)) intersection.push_back(*itr); }
diff --git a/chrome/browser/chromeos/file_manager/file_tasks.cc b/chrome/browser/chromeos/file_manager/file_tasks.cc index 7dab852..1079d744 100644 --- a/chrome/browser/chromeos/file_manager/file_tasks.cc +++ b/chrome/browser/chromeos/file_manager/file_tasks.cc
@@ -630,7 +630,7 @@ FullTaskDescriptor* task = &tasks->at(i); DCHECK(!task->is_default()); const std::string task_id = TaskDescriptorToId(task->task_descriptor()); - if (ContainsKey(default_task_ids, task_id)) { + if (base::ContainsKey(default_task_ids, task_id)) { task->set_is_default(true); return; }
diff --git a/chrome/browser/chromeos/file_system_provider/request_manager.cc b/chrome/browser/chromeos/file_system_provider/request_manager.cc index 17b3777..2b6a76a 100644 --- a/chrome/browser/chromeos/file_system_provider/request_manager.cc +++ b/chrome/browser/chromeos/file_system_provider/request_manager.cc
@@ -49,7 +49,7 @@ } DCHECK_EQ(0u, requests_.size()); - STLDeleteValues(&requests_); + base::STLDeleteValues(&requests_); } int RequestManager::CreateRequest(RequestType type,
diff --git a/chrome/browser/chromeos/file_system_provider/service.cc b/chrome/browser/chromeos/file_system_provider/service.cc index 881db10..2519a2c 100644 --- a/chrome/browser/chromeos/file_system_provider/service.cc +++ b/chrome/browser/chromeos/file_system_provider/service.cc
@@ -82,7 +82,7 @@ } DCHECK_EQ(0u, file_system_map_.size()); - STLDeleteValues(&file_system_map_); + base::STLDeleteValues(&file_system_map_); } // static
diff --git a/chrome/browser/chromeos/hats/hats_notification_controller.cc b/chrome/browser/chromeos/hats/hats_notification_controller.cc index cea30123..00415a4 100644 --- a/chrome/browser/chromeos/hats/hats_notification_controller.cc +++ b/chrome/browser/chromeos/hats/hats_notification_controller.cc
@@ -111,7 +111,8 @@ } HatsNotificationController::~HatsNotificationController() { - network_portal_detector::GetInstance()->RemoveObserver(this); + if (network_portal_detector::IsInitialized()) + network_portal_detector::GetInstance()->RemoveObserver(this); } void HatsNotificationController::Initialize(bool is_new_device) {
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc b/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc index 8b90cb0..9b0663a 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc +++ b/chrome/browser/chromeos/input_method/input_method_engine_browsertests.cc
@@ -19,10 +19,10 @@ #include "ui/base/ime/chromeos/input_method_descriptor.h" #include "ui/base/ime/chromeos/input_method_manager.h" #include "ui/base/ime/chromeos/mock_ime_candidate_window_handler.h" -#include "ui/base/ime/chromeos/mock_ime_input_context_handler.h" #include "ui/base/ime/composition_text.h" #include "ui/base/ime/ime_bridge.h" #include "ui/base/ime/ime_engine_handler_interface.h" +#include "ui/base/ime/mock_ime_input_context_handler.h" #include "ui/base/ime/text_input_flags.h" #include "ui/chromeos/ime/input_method_menu_item.h" #include "ui/chromeos/ime/input_method_menu_manager.h" @@ -157,8 +157,8 @@ InputMethodManager::Get()->GetActiveIMEState()->ChangeInputMethod( kIdentityIMEID, false /* show_message */); - std::unique_ptr<MockIMEInputContextHandler> mock_input_context( - new MockIMEInputContextHandler()); + std::unique_ptr<ui::MockIMEInputContextHandler> mock_input_context( + new ui::MockIMEInputContextHandler()); std::unique_ptr<MockIMECandidateWindowHandler> mock_candidate_window( new MockIMECandidateWindowHandler()); @@ -240,8 +240,8 @@ InputMethodManager::Get()->GetActiveIMEState()->ChangeInputMethod( kAPIArgumentIMEID, false /* show_message */); - std::unique_ptr<MockIMEInputContextHandler> mock_input_context( - new MockIMEInputContextHandler()); + std::unique_ptr<ui::MockIMEInputContextHandler> mock_input_context( + new ui::MockIMEInputContextHandler()); std::unique_ptr<MockIMECandidateWindowHandler> mock_candidate_window( new MockIMECandidateWindowHandler());
diff --git a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc index fc20b9c4..80eec519e 100644 --- a/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc +++ b/chrome/browser/chromeos/input_method/input_method_engine_unittest.cc
@@ -19,9 +19,9 @@ #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/ime/chromeos/extension_ime_util.h" #include "ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.h" -#include "ui/base/ime/chromeos/mock_ime_input_context_handler.h" #include "ui/base/ime/ime_bridge.h" #include "ui/base/ime/ime_engine_handler_interface.h" +#include "ui/base/ime/mock_ime_input_context_handler.h" #include "ui/base/ime/text_input_flags.h" #include "ui/gfx/geometry/rect.h" @@ -131,7 +131,7 @@ layouts_.push_back("us"); InitInputMethod(); ui::IMEBridge::Initialize(); - mock_ime_input_context_handler_.reset(new MockIMEInputContextHandler()); + mock_ime_input_context_handler_.reset(new ui::MockIMEInputContextHandler()); ui::IMEBridge::Get()->SetInputContextHandler( mock_ime_input_context_handler_.get()); } @@ -166,7 +166,8 @@ GURL options_page_; GURL input_view_; - std::unique_ptr<MockIMEInputContextHandler> mock_ime_input_context_handler_; + std::unique_ptr<ui::MockIMEInputContextHandler> + mock_ime_input_context_handler_; private: DISALLOW_COPY_AND_ASSIGN(InputMethodEngineTest);
diff --git a/chrome/browser/chromeos/launcher_search_provider/launcher_search_provider_service.cc b/chrome/browser/chromeos/launcher_search_provider/launcher_search_provider_service.cc index 3e774fc..b1aeaf25 100644 --- a/chrome/browser/chromeos/launcher_search_provider/launcher_search_provider_service.cc +++ b/chrome/browser/chromeos/launcher_search_provider/launcher_search_provider_service.cc
@@ -94,7 +94,8 @@ void Service::OnOpenResult(const ExtensionId& extension_id, const std::string& item_id) { CacheListenerExtensionIds(); - CHECK(ContainsValue(*cached_listener_extension_ids_.get(), extension_id)); + CHECK( + base::ContainsValue(*cached_listener_extension_ids_.get(), extension_id)); extensions::EventRouter* event_router = extensions::EventRouter::Get(profile_); @@ -119,8 +120,10 @@ // If |extension| is not in the listener extensions list, ignore it. CacheListenerExtensionIds(); - if (!ContainsValue(*cached_listener_extension_ids_.get(), extension->id())) + if (!base::ContainsValue(*cached_listener_extension_ids_.get(), + extension->id())) { return; + } // Set search results to provider. DCHECK(provider_);
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc index 6504a74..a40ff12b 100644 --- a/chrome/browser/chromeos/login/chrome_restart_request.cc +++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -105,12 +105,12 @@ ::switches::kEnableDisplayList2dCanvas, ::switches::kForceDisplayList2dCanvas, ::switches::kEnableCanvas2dDynamicRenderingModeSwitching, + ::switches::kEnableColorCorrectRendering, ::switches::kDisableGpuSandbox, ::switches::kEnableDistanceFieldText, ::switches::kEnableGpuAsyncWorkerContext, ::switches::kEnableGpuMemoryBufferVideoFrames, ::switches::kEnableGpuRasterization, - ::switches::kEnableImageColorProfiles, ::switches::kEnableLogging, ::switches::kEnableLowResTiling, ::switches::kDisablePartialRaster, @@ -209,14 +209,12 @@ cc::switches::kSlowDownRasterScaleFactor, cc::switches::kUIEnableLayerLists, cc::switches::kUIShowFPSCounter, - chromeos::switches::kConsumerDeviceManagementUrl, chromeos::switches::kDbusStub, chromeos::switches::kDbusUnstubClients, chromeos::switches::kDisableArcDataWipe, chromeos::switches::kDisableArcOptInVerification, chromeos::switches::kDisableLoginAnimations, chromeos::switches::kEnableArc, - chromeos::switches::kEnableConsumerManagement, chromeos::switches::kEnterpriseDisableArc, chromeos::switches::kEnterpriseEnableForcedReEnrollment, chromeos::switches::kHasChromeOSDiamondKey,
diff --git a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h index 68a6552..f8f87d0 100644 --- a/chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h +++ b/chrome/browser/chromeos/login/easy_unlock/easy_unlock_key_manager.h
@@ -110,8 +110,8 @@ ReadOperationQueue read_operation_queue_; // Scopes the raw operation pointers to the lifetime of this object. - STLElementDeleter<WriteOperationQueue> write_queue_deleter_; - STLElementDeleter<ReadOperationQueue> read_queue_deleter_; + base::STLElementDeleter<WriteOperationQueue> write_queue_deleter_; + base::STLElementDeleter<ReadOperationQueue> read_queue_deleter_; // Stores the current operation in progress. At most one of these variables // can be non-null at any time.
diff --git a/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_impl.cc b/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_impl.cc index 69e7c8a..e8bfd33f 100644 --- a/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_impl.cc +++ b/chrome/browser/chromeos/login/enrollment/enterprise_enrollment_helper_impl.cc
@@ -156,9 +156,7 @@ connector->GetDeviceCloudPolicyInitializer(); CHECK(dcp_initializer); dcp_initializer->StartEnrollment( - policy::MANAGEMENT_MODE_ENTERPRISE_MANAGED, - connector->device_management_service(), - nullptr /* owner_settings_service */, enrollment_config_, token, + connector->device_management_service(), enrollment_config_, token, device_modes, base::Bind(&EnterpriseEnrollmentHelperImpl::OnEnrollmentFinished, weak_ptr_factory_.GetWeakPtr()));
diff --git a/chrome/browser/chromeos/login/oobe_localization_browsertest.cc b/chrome/browser/chromeos/login/oobe_localization_browsertest.cc index d04ff58..76bcc37 100644 --- a/chrome/browser/chromeos/login/oobe_localization_browsertest.cc +++ b/chrome/browser/chromeos/login/oobe_localization_browsertest.cc
@@ -424,7 +424,7 @@ std::string()); } -IN_PROC_BROWSER_TEST_P(OobeLocalizationTest, LocalizationTest) { +IN_PROC_BROWSER_TEST_P(OobeLocalizationTest, DISABLED_LocalizationTest) { RunLocalizationTest(); }
diff --git a/chrome/browser/chromeos/login/screens/controller_pairing_screen.cc b/chrome/browser/chromeos/login/screens/controller_pairing_screen.cc index e203af1..20a9d7f 100644 --- a/chrome/browser/chromeos/login/screens/controller_pairing_screen.cc +++ b/chrome/browser/chromeos/login/screens/controller_pairing_screen.cc
@@ -153,7 +153,7 @@ kContextKeyPage, devices.empty() ? kPageDevicesDiscovery : kPageDeviceSelect); std::string selected_device = context_.GetString(kContextKeySelectedDevice); - if (!ContainsValue(devices, selected_device)) + if (!base::ContainsValue(devices, selected_device)) selected_device.clear(); if (devices.empty()) { device_preselected_ = false;
diff --git a/chrome/browser/chromeos/login/signin/auth_sync_observer.h b/chrome/browser/chromeos/login/signin/auth_sync_observer.h index 88ffc808..9690f1f0 100644 --- a/chrome/browser/chromeos/login/signin/auth_sync_observer.h +++ b/chrome/browser/chromeos/login/signin/auth_sync_observer.h
@@ -10,7 +10,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "components/keyed_service/core/keyed_service.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/sync_service_observer.h" class Profile;
diff --git a/chrome/browser/chromeos/mobile_config.cc b/chrome/browser/chromeos/mobile_config.cc index d3547c8..fe180ae3 100644 --- a/chrome/browser/chromeos/mobile_config.cc +++ b/chrome/browser/chromeos/mobile_config.cc
@@ -194,7 +194,7 @@ } void MobileConfig::Carrier::RemoveDeals() { - STLDeleteValues(&deals_); + base::STLDeleteValues(&deals_); } // MobileConfig::LocaleConfig implementation. ---------------------------------- @@ -317,7 +317,7 @@ } MobileConfig::~MobileConfig() { - STLDeleteValues(&carriers_); + base::STLDeleteValues(&carriers_); } void MobileConfig::LoadConfig() {
diff --git a/chrome/browser/chromeos/net/network_portal_notification_controller.cc b/chrome/browser/chromeos/net/network_portal_notification_controller.cc index 1cc5ca8..300732ed 100644 --- a/chrome/browser/chromeos/net/network_portal_notification_controller.cc +++ b/chrome/browser/chromeos/net/network_portal_notification_controller.cc
@@ -26,7 +26,6 @@ #include "chrome/browser/chromeos/mobile/mobile_activator.h" #include "chrome/browser/chromeos/net/network_portal_web_dialog.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/policy/consumer_management_service.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/browser_dialogs.h"
diff --git a/chrome/browser/chromeos/ownership/fake_owner_settings_service.cc b/chrome/browser/chromeos/ownership/fake_owner_settings_service.cc index 8042251..f56f535 100644 --- a/chrome/browser/chromeos/ownership/fake_owner_settings_service.cc +++ b/chrome/browser/chromeos/ownership/fake_owner_settings_service.cc
@@ -30,13 +30,6 @@ FakeOwnerSettingsService::~FakeOwnerSettingsService() { } -void FakeOwnerSettingsService::SetManagementSettings( - const ManagementSettings& settings, - const OnManagementSettingsSetCallback& callback) { - last_settings_ = settings; - callback.Run(set_management_settings_result_); -} - bool FakeOwnerSettingsService::Set(const std::string& setting, const base::Value& value) { CHECK(settings_provider_);
diff --git a/chrome/browser/chromeos/ownership/fake_owner_settings_service.h b/chrome/browser/chromeos/ownership/fake_owner_settings_service.h index 3f785c1..7f664ace 100644 --- a/chrome/browser/chromeos/ownership/fake_owner_settings_service.h +++ b/chrome/browser/chromeos/ownership/fake_owner_settings_service.h
@@ -37,9 +37,6 @@ } // OwnerSettingsServiceChromeOS: - void SetManagementSettings( - const ManagementSettings& settings, - const OnManagementSettingsSetCallback& callback) override; bool Set(const std::string& setting, const base::Value& value) override; private:
diff --git a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc index 881bc22c..0b356b4d 100644 --- a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc +++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.cc
@@ -159,32 +159,6 @@ callback); } -// Returns true if it is okay to transfer from the current mode to the new -// mode. This function should be called in SetManagementMode(). -bool CheckManagementModeTransition(policy::ManagementMode current_mode, - policy::ManagementMode new_mode) { - // Mode is not changed. - if (current_mode == new_mode) - return true; - - switch (current_mode) { - case policy::MANAGEMENT_MODE_LOCAL_OWNER: - // For consumer management enrollment. - return new_mode == policy::MANAGEMENT_MODE_CONSUMER_MANAGED; - - case policy::MANAGEMENT_MODE_ENTERPRISE_MANAGED: - // Management mode cannot be set when it is currently ENTERPRISE_MANAGED. - return false; - - case policy::MANAGEMENT_MODE_CONSUMER_MANAGED: - // For consumer management unenrollment. - return new_mode == policy::MANAGEMENT_MODE_LOCAL_OWNER; - } - - NOTREACHED(); - return false; -} - } // namespace OwnerSettingsServiceChromeOS::ManagementSettings::ManagementSettings() { @@ -203,7 +177,6 @@ waiting_for_profile_creation_(true), waiting_for_tpm_token_(true), has_pending_fixups_(false), - has_pending_management_settings_(false), weak_factory_(this), store_settings_factory_(this) { if (TPMTokenLoader::IsInitialized()) { @@ -262,7 +235,7 @@ bool OwnerSettingsServiceChromeOS::HasPendingChanges() const { return !pending_changes_.empty() || tentative_settings_.get() || - has_pending_management_settings_ || has_pending_fixups_; + has_pending_fixups_; } bool OwnerSettingsServiceChromeOS::HandlesSetting(const std::string& setting) { @@ -377,38 +350,6 @@ device_settings_service_ = nullptr; } -void OwnerSettingsServiceChromeOS::SetManagementSettings( - const ManagementSettings& settings, - const OnManagementSettingsSetCallback& callback) { - if ((!IsOwner() && !IsOwnerInTests(user_id_))) { - if (!callback.is_null()) - callback.Run(false /* success */); - return; - } - - policy::ManagementMode current_mode = policy::MANAGEMENT_MODE_LOCAL_OWNER; - if (has_pending_management_settings_) { - current_mode = pending_management_settings_.management_mode; - } else if (device_settings_service_ && - device_settings_service_->policy_data()) { - current_mode = - policy::GetManagementMode(*device_settings_service_->policy_data()); - } - - if (!CheckManagementModeTransition(current_mode, settings.management_mode)) { - LOG(ERROR) << "Invalid management mode transition: current mode = " - << current_mode << ", new mode = " << settings.management_mode; - if (!callback.is_null()) - callback.Run(false /* success */); - return; - } - - pending_management_settings_ = settings; - has_pending_management_settings_ = true; - pending_management_settings_callbacks_.push_back(callback); - StorePendingChanges(); -} - // static void OwnerSettingsServiceChromeOS::IsOwnerForSafeModeAsync( const std::string& user_hash, @@ -431,8 +372,6 @@ std::unique_ptr<em::PolicyData> OwnerSettingsServiceChromeOS::AssemblePolicy( const std::string& user_id, const em::PolicyData* policy_data, - bool apply_pending_management_settings, - const ManagementSettings& pending_management_settings, em::ChromeDeviceSettingsProto* settings) { std::unique_ptr<em::PolicyData> policy(new em::PolicyData()); if (policy_data) { @@ -448,20 +387,6 @@ // setting is set. We set the management mode to LOCAL_OWNER initially. policy->set_management_mode(em::PolicyData::LOCAL_OWNER); } - if (apply_pending_management_settings) { - policy::SetManagementMode(*policy, - pending_management_settings.management_mode); - - if (pending_management_settings.request_token.empty()) - policy->clear_request_token(); - else - policy->set_request_token(pending_management_settings.request_token); - - if (pending_management_settings.device_id.empty()) - policy->clear_device_id(); - else - policy->set_device_id(pending_management_settings.device_id); - } policy->set_policy_type(policy::dm_protocol::kChromeDevicePolicyType); policy->set_timestamp( (base::Time::Now() - base::Time::UnixEpoch()).InMilliseconds()); @@ -772,10 +697,8 @@ std::unique_ptr<em::PolicyData> policy = AssemblePolicy(user_id_, device_settings_service_->policy_data(), - has_pending_management_settings_, - pending_management_settings_, &settings); + &settings); has_pending_fixups_ = false; - has_pending_management_settings_ = false; bool rv = AssembleAndSignPolicyAsync( content::BrowserThread::GetBlockingPool(), std::move(policy), @@ -809,13 +732,6 @@ store_settings_factory_.InvalidateWeakPtrs(); FOR_EACH_OBSERVER(OwnerSettingsService::Observer, observers_, OnSignedPolicyStored(success)); - - std::vector<OnManagementSettingsSetCallback> callbacks; - pending_management_settings_callbacks_.swap(callbacks); - for (const auto& callback : callbacks) { - if (!callback.is_null()) - callback.Run(success); - } StorePendingChanges(); }
diff --git a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h index 6350b520..800ddbc9 100644 --- a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h +++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h
@@ -36,10 +36,10 @@ class FakeOwnerSettingsService; -// The class is a profile-keyed service which holds public/private -// keypair corresponds to a profile. The keypair is reloaded automatically when -// profile is created and TPM token is ready. Note that the private part of a -// key can be loaded only for the owner. +// The class is a profile-keyed service which holds public/private keypair +// corresponds to a profile. The keypair is reloaded automatically when profile +// is created and TPM token is ready. Note that the private part of a key can be +// loaded only for the owner. // // TODO (ygorshenin@): move write path for device settings here // (crbug.com/230018). @@ -54,7 +54,6 @@ ManagementSettings(); ~ManagementSettings(); - policy::ManagementMode management_mode; std::string request_token; std::string device_id; }; @@ -90,11 +89,6 @@ void DeviceSettingsUpdated() override; void OnDeviceSettingsServiceShutdown() override; - // Sets the management related settings. - virtual void SetManagementSettings( - const ManagementSettings& settings, - const OnManagementSettingsSetCallback& callback); - // Checks if the user is the device owner, without the user profile having to // been initialized. Should be used only if login state is in safe mode. static void IsOwnerForSafeModeAsync( @@ -107,8 +101,6 @@ static std::unique_ptr<enterprise_management::PolicyData> AssemblePolicy( const std::string& user_id, const enterprise_management::PolicyData* policy_data, - bool apply_pending_mangement_settings, - const ManagementSettings& pending_management_settings, enterprise_management::ChromeDeviceSettingsProto* settings); // Updates device |settings|. @@ -184,17 +176,6 @@ base::ScopedPtrHashMap<std::string, std::unique_ptr<base::Value>> pending_changes_; - // True if there're pending changes to management settings. - bool has_pending_management_settings_; - - // A set of pending changes to management settings. - ManagementSettings pending_management_settings_; - - // A set of callbacks that need to be run after management settings - // are set and policy is stored. - std::vector<OnManagementSettingsSetCallback> - pending_management_settings_callbacks_; - // A protobuf containing pending changes to device settings. std::unique_ptr<enterprise_management::ChromeDeviceSettingsProto> tentative_settings_;
diff --git a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_unittest.cc b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_unittest.cc index 4384762..a2f5b238 100644 --- a/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_unittest.cc +++ b/chrome/browser/chromeos/ownership/owner_settings_service_chromeos_unittest.cc
@@ -182,128 +182,6 @@ .release_channel()); } -TEST_F(OwnerSettingsServiceChromeOSTest, SetManagementSettingsModeTransition) { - ReloadDeviceSettings(); - EXPECT_EQ(DeviceSettingsService::STORE_SUCCESS, - device_settings_service_.status()); - - // The initial management mode should be LOCAL_OWNER. - EXPECT_TRUE(device_settings_service_.policy_data()->has_management_mode()); - EXPECT_EQ(em::PolicyData::LOCAL_OWNER, - device_settings_service_.policy_data()->management_mode()); - - OwnerSettingsServiceChromeOS::ManagementSettings management_settings; - management_settings.management_mode = - policy::MANAGEMENT_MODE_CONSUMER_MANAGED; - management_settings.request_token = "fake_request_token"; - management_settings.device_id = "fake_device_id"; - OwnerSettingsServiceChromeOS::OnManagementSettingsSetCallback - on_management_settings_set_callback = - base::Bind(&OwnerSettingsServiceChromeOSTest::OnManagementSettingsSet, - base::Unretained(this)); - - // LOCAL_OWNER -> CONSUMER_MANAGED: Okay. - service_->SetManagementSettings(management_settings, - on_management_settings_set_callback); - FlushDeviceSettings(); - - EXPECT_TRUE(management_settings_set_); - EXPECT_EQ(em::PolicyData::CONSUMER_MANAGED, - device_settings_service_.policy_data()->management_mode()); - - // CONSUMER_MANAGED -> ENTERPRISE_MANAGED: Invalid. - management_settings.management_mode = - policy::MANAGEMENT_MODE_ENTERPRISE_MANAGED; - service_->SetManagementSettings(management_settings, - on_management_settings_set_callback); - FlushDeviceSettings(); - - EXPECT_FALSE(management_settings_set_); - EXPECT_EQ(em::PolicyData::CONSUMER_MANAGED, - device_settings_service_.policy_data()->management_mode()); - - // CONSUMER_MANAGED -> LOCAL_OWNER: Okay. - management_settings.management_mode = policy::MANAGEMENT_MODE_LOCAL_OWNER; - service_->SetManagementSettings(management_settings, - on_management_settings_set_callback); - FlushDeviceSettings(); - - EXPECT_TRUE(management_settings_set_); - EXPECT_EQ(em::PolicyData::LOCAL_OWNER, - device_settings_service_.policy_data()->management_mode()); - - // LOCAL_OWNER -> ENTERPRISE_MANAGED: Invalid. - management_settings.management_mode = - policy::MANAGEMENT_MODE_ENTERPRISE_MANAGED; - service_->SetManagementSettings(management_settings, - on_management_settings_set_callback); - FlushDeviceSettings(); - - EXPECT_FALSE(management_settings_set_); - EXPECT_EQ(em::PolicyData::LOCAL_OWNER, - device_settings_service_.policy_data()->management_mode()); - - // Inject a policy data with management mode set to ENTERPRISE_MANAGED. - device_policy_.policy_data().set_management_mode( - em::PolicyData::ENTERPRISE_MANAGED); - device_policy_.Build(); - device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob()); - ReloadDeviceSettings(); - EXPECT_EQ(em::PolicyData::ENTERPRISE_MANAGED, - device_settings_service_.policy_data()->management_mode()); - - // ENTERPRISE_MANAGED -> LOCAL_OWNER: Invalid. - management_settings.management_mode = policy::MANAGEMENT_MODE_LOCAL_OWNER; - service_->SetManagementSettings(management_settings, - on_management_settings_set_callback); - FlushDeviceSettings(); - - EXPECT_FALSE(management_settings_set_); - EXPECT_EQ(em::PolicyData::ENTERPRISE_MANAGED, - device_settings_service_.policy_data()->management_mode()); - - // ENTERPRISE_MANAGED -> CONSUMER_MANAGED: Invalid. - management_settings.management_mode = - policy::MANAGEMENT_MODE_CONSUMER_MANAGED; - service_->SetManagementSettings(management_settings, - on_management_settings_set_callback); - FlushDeviceSettings(); - - EXPECT_FALSE(management_settings_set_); - EXPECT_EQ(em::PolicyData::ENTERPRISE_MANAGED, - device_settings_service_.policy_data()->management_mode()); -} - -TEST_F(OwnerSettingsServiceChromeOSTest, SetManagementSettingsSuccess) { - ReloadDeviceSettings(); - EXPECT_EQ(DeviceSettingsService::STORE_SUCCESS, - device_settings_service_.status()); - - OwnerSettingsServiceChromeOS::ManagementSettings management_settings; - management_settings.management_mode = - policy::MANAGEMENT_MODE_CONSUMER_MANAGED; - management_settings.request_token = "fake_request_token"; - management_settings.device_id = "fake_device_id"; - service_->SetManagementSettings( - management_settings, - base::Bind(&OwnerSettingsServiceChromeOSTest::OnManagementSettingsSet, - base::Unretained(this))); - FlushDeviceSettings(); - - EXPECT_EQ(DeviceSettingsService::STORE_SUCCESS, - device_settings_service_.status()); - ASSERT_TRUE(device_settings_service_.device_settings()); - - // Check that the loaded policy_data contains the expected values. - const em::PolicyData* policy_data = device_settings_service_.policy_data(); - EXPECT_EQ(policy::dm_protocol::kChromeDevicePolicyType, - policy_data->policy_type()); - EXPECT_EQ(device_settings_service_.GetUsername(), policy_data->username()); - EXPECT_EQ(em::PolicyData::CONSUMER_MANAGED, policy_data->management_mode()); - EXPECT_EQ("fake_request_token", policy_data->request_token()); - EXPECT_EQ("fake_device_id", policy_data->device_id()); -} - TEST_F(OwnerSettingsServiceChromeOSTest, ForceWhitelist) { EXPECT_FALSE(FindInListValue(device_policy_.policy_data().username(), provider_->Get(kAccountsPrefUsers)));
diff --git a/chrome/browser/chromeos/platform_keys/platform_keys_service.cc b/chrome/browser/chromeos/platform_keys/platform_keys_service.cc index 520b25a..96be721 100644 --- a/chrome/browser/chromeos/platform_keys/platform_keys_service.cc +++ b/chrome/browser/chromeos/platform_keys/platform_keys_service.cc
@@ -427,7 +427,7 @@ certificate->os_cert_handle(), &unused_key_size, &actual_key_type); const std::vector<net::X509Certificate::PublicKeyType>& accepted_types = request_.certificate_key_types; - if (!ContainsValue(accepted_types, actual_key_type)) + if (!base::ContainsValue(accepted_types, actual_key_type)) continue; }
diff --git a/chrome/browser/chromeos/policy/blocking_login_browsertest.cc b/chrome/browser/chromeos/policy/blocking_login_browsertest.cc index fc0df0d..2764ec73 100644 --- a/chrome/browser/chromeos/policy/blocking_login_browsertest.cc +++ b/chrome/browser/chromeos/policy/blocking_login_browsertest.cc
@@ -117,7 +117,7 @@ void TearDownOnMainThread() override { RunUntilIdle(); EXPECT_TRUE(responses_.empty()); - STLDeleteElements(&responses_); + base::STLDeleteElements(&responses_); OobeBaseTest::TearDownOnMainThread(); }
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc index d5caadc..7b74c7b9 100644 --- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc +++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
@@ -22,7 +22,6 @@ #include "chrome/browser/chromeos/policy/affiliated_invalidation_service_provider.h" #include "chrome/browser/chromeos/policy/affiliated_invalidation_service_provider_impl.h" #include "chrome/browser/chromeos/policy/bluetooth_policy_handler.h" -#include "chrome/browser/chromeos/policy/consumer_management_service.h" #include "chrome/browser/chromeos/policy/device_cloud_policy_initializer.h" #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h" #include "chrome/browser/chromeos/policy/device_local_account.h" @@ -61,13 +60,6 @@ namespace { -// TODO(davidyu): Update the URL to the real one once it is ready. -// http://crbug.com/366491. -// -// The URL for the consumer device management server. -const char kDefaultConsumerDeviceManagementServerUrl[] = - "https://m.google.com/devicemanagement/data/api"; - // Install attributes for tests. EnterpriseInstallAttributes* g_testing_install_attributes = NULL; @@ -80,17 +72,6 @@ pool->GetSequenceToken(), base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); } -std::string GetDeviceManagementServerUrlForConsumer() { - const base::CommandLine* command_line = - base::CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch( - chromeos::switches::kConsumerDeviceManagementUrl)) { - return command_line->GetSwitchValueASCII( - chromeos::switches::kConsumerDeviceManagementUrl); - } - return kDefaultConsumerDeviceManagementServerUrl; -} - } // namespace BrowserPolicyConnectorChromeOS::BrowserPolicyConnectorChromeOS() @@ -126,16 +107,6 @@ install_attributes_->Init(install_attrs_file); } - const base::CommandLine* command_line = - base::CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch( - chromeos::switches::kEnableConsumerManagement)) { - consumer_management_service_.reset( - new ConsumerManagementService( - cryptohome_client, - chromeos::DeviceSettingsService::Get())); - } - std::unique_ptr<DeviceCloudPolicyStoreChromeOS> device_cloud_policy_store( new DeviceCloudPolicyStoreChromeOS( chromeos::DeviceSettingsService::Get(), install_attributes_.get(), @@ -163,18 +134,6 @@ affiliated_invalidation_service_provider_.reset( new AffiliatedInvalidationServiceProviderImpl); - const base::CommandLine* command_line = - base::CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch(chromeos::switches::kEnableConsumerManagement)) { - std::unique_ptr<DeviceManagementService::Configuration> configuration( - new DeviceManagementServiceConfiguration( - GetDeviceManagementServerUrlForConsumer())); - consumer_device_management_service_.reset( - new DeviceManagementService(std::move(configuration))); - consumer_device_management_service_->ScheduleInitialization( - kServiceInitializationStartupDelay); - } - if (device_cloud_policy_manager_) { // Note: for now the |device_cloud_policy_manager_| is using the global // schema registry. Eventually it will have its own registry, once device @@ -292,11 +251,6 @@ global_user_cloud_policy_provider_->SetDelegate(user_policy_provider); } -void BrowserPolicyConnectorChromeOS::SetConsumerManagementServiceForTesting( - std::unique_ptr<ConsumerManagementService> service) { - consumer_management_service_ = std::move(service); -} - void BrowserPolicyConnectorChromeOS::SetDeviceCloudPolicyInitializerForTesting( std::unique_ptr<DeviceCloudPolicyInitializer> initializer) { device_cloud_policy_initializer_ = std::move(initializer); @@ -365,7 +319,6 @@ new DeviceCloudPolicyInitializer( local_state_, device_management_service(), - consumer_device_management_service_.get(), GetBackgroundTaskRunner(), install_attributes_.get(), state_keys_broker_.get(),
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h index 368a8955..54ec472 100644 --- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h +++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h
@@ -30,7 +30,6 @@ class AffiliatedInvalidationServiceProvider; class AffiliatedRemoteCommandsInvalidator; class BluetoothPolicyHandler; -class ConsumerManagementService; class DeviceCloudPolicyInitializer; class DeviceLocalAccountPolicyService; class DeviceManagementService; @@ -116,18 +115,6 @@ // delegate, if there is one. void SetUserPolicyDelegate(ConfigurationPolicyProvider* user_policy_provider); - ConsumerManagementService* GetConsumerManagementService() const { - return consumer_management_service_.get(); - } - - DeviceManagementService* GetDeviceManagementServiceForConsumer() const { - return consumer_device_management_service_.get(); - } - - // Sets the consumer management service for testing. - void SetConsumerManagementServiceForTesting( - std::unique_ptr<ConsumerManagementService> service); - // Sets the device cloud policy initializer for testing. void SetDeviceCloudPolicyInitializerForTesting( std::unique_ptr<DeviceCloudPolicyInitializer> initializer); @@ -161,10 +148,8 @@ std::unique_ptr<EnterpriseInstallAttributes> install_attributes_; std::unique_ptr<AffiliatedInvalidationServiceProvider> affiliated_invalidation_service_provider_; - std::unique_ptr<ConsumerManagementService> consumer_management_service_; DeviceCloudPolicyManagerChromeOS* device_cloud_policy_manager_; PrefService* local_state_; - std::unique_ptr<DeviceManagementService> consumer_device_management_service_; std::unique_ptr<DeviceCloudPolicyInitializer> device_cloud_policy_initializer_; std::unique_ptr<DeviceLocalAccountPolicyService>
diff --git a/chrome/browser/chromeos/policy/cloud_external_data_manager_base_unittest.cc b/chrome/browser/chromeos/policy/cloud_external_data_manager_base_unittest.cc index 9e598424..c023683 100644 --- a/chrome/browser/chromeos/policy/cloud_external_data_manager_base_unittest.cc +++ b/chrome/browser/chromeos/policy/cloud_external_data_manager_base_unittest.cc
@@ -225,7 +225,7 @@ } void CloudExternalDataManagerBaseTest::ResetCallbackData() { - STLDeleteValues(&callback_data_); + base::STLDeleteValues(&callback_data_); } void CloudExternalDataManagerBaseTest::OnFetchDone(
diff --git a/chrome/browser/chromeos/policy/cloud_external_data_policy_observer.cc b/chrome/browser/chromeos/policy/cloud_external_data_policy_observer.cc index 196b6a0..dae3e20 100644 --- a/chrome/browser/chromeos/policy/cloud_external_data_policy_observer.cc +++ b/chrome/browser/chromeos/policy/cloud_external_data_policy_observer.cc
@@ -169,7 +169,7 @@ } const std::string& user_id = user->email(); - if (ContainsKey(logged_in_user_observers_, user_id)) { + if (base::ContainsKey(logged_in_user_observers_, user_id)) { NOTREACHED(); return; } @@ -184,7 +184,7 @@ void CloudExternalDataPolicyObserver::OnPolicyUpdated( const std::string& user_id) { - if (ContainsKey(logged_in_user_observers_, user_id)) { + if (base::ContainsKey(logged_in_user_observers_, user_id)) { // When a device-local account is logged in, a policy change triggers both // OnPolicyUpdated() and PolicyServiceObserver::OnPolicyUpdated(). Ignore // the former so that the policy change is handled only once. @@ -253,7 +253,7 @@ for (DeviceLocalAccountEntryMap::iterator it = device_local_account_entries_.begin(); it != device_local_account_entries_.end(); ) { - if (!ContainsKey(device_local_accounts, it->first)) { + if (!base::ContainsKey(device_local_accounts, it->first)) { const std::string user_id = it->first; device_local_account_entries_.erase(it++); // When a device-local account whose external data reference was set is
diff --git a/chrome/browser/chromeos/policy/consumer_enrollment_handler.cc b/chrome/browser/chromeos/policy/consumer_enrollment_handler.cc deleted file mode 100644 index efc8f50..0000000 --- a/chrome/browser/chromeos/policy/consumer_enrollment_handler.cc +++ /dev/null
@@ -1,149 +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/chromeos/policy/consumer_enrollment_handler.h" - -#include "base/bind.h" -#include "base/location.h" -#include "base/logging.h" -#include "base/single_thread_task_runner.h" -#include "base/threading/thread_task_runner_handle.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/policy/consumer_management_service.h" -#include "chrome/browser/chromeos/policy/consumer_management_stage.h" -#include "chrome/browser/chromeos/policy/device_cloud_policy_initializer.h" -#include "chrome/browser/chromeos/policy/enrollment_config.h" -#include "chrome/browser/chromeos/policy/enrollment_status_chromeos.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" -#include "chrome/browser/signin/signin_manager_factory.h" -#include "components/policy/core/common/cloud/cloud_policy_constants.h" -#include "components/signin/core/browser/profile_oauth2_token_service.h" -#include "components/signin/core/browser/signin_manager_base.h" -#include "google_apis/gaia/gaia_constants.h" -#include "google_apis/gaia/google_service_auth_error.h" - -namespace policy { - -ConsumerEnrollmentHandler::ConsumerEnrollmentHandler( - Profile* profile, - ConsumerManagementService* consumer_management_service, - DeviceManagementService* device_management_service) - : Consumer("consumer_enrollment_handler"), - profile_(profile), - consumer_management_service_(consumer_management_service), - device_management_service_(device_management_service), - weak_ptr_factory_(this) { - gaia_account_id_ = SigninManagerFactory::GetForProfile(profile)-> - GetAuthenticatedAccountId(); - ContinueEnrollmentProcess(); -} - -ConsumerEnrollmentHandler::~ConsumerEnrollmentHandler() { -} - -void ConsumerEnrollmentHandler::Shutdown() { - ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)-> - RemoveObserver(this); -} - -void ConsumerEnrollmentHandler::OnRefreshTokenAvailable( - const std::string& account_id) { - if (account_id == gaia_account_id_) { - ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)-> - RemoveObserver(this); - OnOwnerRefreshTokenAvailable(); - } -} - -void ConsumerEnrollmentHandler::OnGetTokenSuccess( - const OAuth2TokenService::Request* request, - const std::string& access_token, - const base::Time& expiration_time) { - DCHECK_EQ(token_request_.get(), request); - base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, - token_request_.release()); - - OnOwnerAccessTokenAvailable(access_token); -} - -void ConsumerEnrollmentHandler::OnGetTokenFailure( - const OAuth2TokenService::Request* request, - const GoogleServiceAuthError& error) { - DCHECK_EQ(token_request_.get(), request); - base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, - token_request_.release()); - - LOG(ERROR) << "Failed to get the access token: " << error.ToString(); - EndEnrollment(ConsumerManagementStage::EnrollmentGetTokenFailed()); -} - -void ConsumerEnrollmentHandler::ContinueEnrollmentProcess() { - // First, we need to ensure that the refresh token is available. - ProfileOAuth2TokenService* token_service = - ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); - if (token_service->RefreshTokenIsAvailable(gaia_account_id_)) { - OnOwnerRefreshTokenAvailable(); - } else { - token_service->AddObserver(this); - } -} - -void ConsumerEnrollmentHandler::OnOwnerRefreshTokenAvailable() { - // Now we can request the OAuth access token for device management to send the - // device registration request to the device management server. - OAuth2TokenService::ScopeSet oauth_scopes; - oauth_scopes.insert(GaiaConstants::kDeviceManagementServiceOAuth); - token_request_ = ProfileOAuth2TokenServiceFactory::GetForProfile( - profile_)->StartRequest(gaia_account_id_, oauth_scopes, this); -} - -void ConsumerEnrollmentHandler::OnOwnerAccessTokenAvailable( - const std::string& access_token) { - // Now that we have the access token, we got everything we need to send the - // device registration request to the device management server. - BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - DeviceCloudPolicyInitializer* initializer = - connector->GetDeviceCloudPolicyInitializer(); - CHECK(initializer); - - policy::DeviceCloudPolicyInitializer::AllowedDeviceModes device_modes; - device_modes[policy::DEVICE_MODE_ENTERPRISE] = true; - - EnrollmentConfig enrollment_config; - enrollment_config.mode = EnrollmentConfig::MODE_MANUAL; - initializer->StartEnrollment( - MANAGEMENT_MODE_CONSUMER_MANAGED, device_management_service_, - chromeos::OwnerSettingsServiceChromeOSFactory::GetForBrowserContext( - profile_), - enrollment_config, access_token, device_modes, - base::Bind(&ConsumerEnrollmentHandler::OnEnrollmentCompleted, - weak_ptr_factory_.GetWeakPtr())); -} - -void ConsumerEnrollmentHandler::OnEnrollmentCompleted(EnrollmentStatus status) { - if (status.status() != EnrollmentStatus::STATUS_SUCCESS) { - LOG(ERROR) << "Failed to enroll the device." - << " status=" << status.status() - << " client_status=" << status.client_status() - << " http_status=" << status.http_status() - << " store_status=" << status.store_status() - << " validation_status=" << status.validation_status(); - EndEnrollment(ConsumerManagementStage::EnrollmentDMServerFailed()); - return; - } - - EndEnrollment(ConsumerManagementStage::EnrollmentSuccess()); -} - -void ConsumerEnrollmentHandler::EndEnrollment( - const ConsumerManagementStage& stage) { - consumer_management_service_->SetStage(stage); -} - -} // namespace policy
diff --git a/chrome/browser/chromeos/policy/consumer_enrollment_handler.h b/chrome/browser/chromeos/policy/consumer_enrollment_handler.h deleted file mode 100644 index 02b22a1..0000000 --- a/chrome/browser/chromeos/policy/consumer_enrollment_handler.h +++ /dev/null
@@ -1,86 +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_CHROMEOS_POLICY_CONSUMER_ENROLLMENT_HANDLER_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_CONSUMER_ENROLLMENT_HANDLER_H_ - -#include <memory> -#include <string> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "components/keyed_service/core/keyed_service.h" -#include "google_apis/gaia/oauth2_token_service.h" - -class Profile; - -namespace policy { - -class ConsumerManagementService; -class ConsumerManagementStage; -class DeviceManagementService; -class EnrollmentStatus; - -// Consumer enrollment handler automatically continues the enrollment process -// after the owner ID is stored in the boot lockbox and thw owner signs in. -class ConsumerEnrollmentHandler - : public KeyedService, - public OAuth2TokenService::Consumer, - public OAuth2TokenService::Observer { - public: - ConsumerEnrollmentHandler( - Profile* profile, - ConsumerManagementService* consumer_management_service, - DeviceManagementService* device_management_service); - ~ConsumerEnrollmentHandler() override; - - void Shutdown() override; - - // OAuth2TokenService::Observer: - void OnRefreshTokenAvailable(const std::string& account_id) override; - - // OAuth2TokenService::Consumer: - void OnGetTokenSuccess( - const OAuth2TokenService::Request* request, - const std::string& access_token, - const base::Time& expiration_time) override; - void OnGetTokenFailure( - const OAuth2TokenService::Request* request, - const GoogleServiceAuthError& error) override; - - OAuth2TokenService::Request* GetTokenRequestForTesting() { - return token_request_.get(); - } - - private: - // Continues the enrollment process after the owner ID is stored into the boot - // lockbox and the owner signs in. - void ContinueEnrollmentProcess(); - - // Called when the owner's refresh token is available. - void OnOwnerRefreshTokenAvailable(); - - // Called when the owner's access token for device management is available. - void OnOwnerAccessTokenAvailable(const std::string& access_token); - - // Called upon the completion of the enrollment process. - void OnEnrollmentCompleted(EnrollmentStatus status); - - // Ends the enrollment process. - void EndEnrollment(const ConsumerManagementStage& stage); - - Profile* profile_; - ConsumerManagementService* consumer_management_service_; - DeviceManagementService* device_management_service_; - std::string gaia_account_id_; - - std::unique_ptr<OAuth2TokenService::Request> token_request_; - base::WeakPtrFactory<ConsumerEnrollmentHandler> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(ConsumerEnrollmentHandler); -}; - -} // namespace policy - -#endif // CHROME_BROWSER_CHROMEOS_POLICY_CONSUMER_ENROLLMENT_HANDLER_H_
diff --git a/chrome/browser/chromeos/policy/consumer_enrollment_handler_factory.cc b/chrome/browser/chromeos/policy/consumer_enrollment_handler_factory.cc deleted file mode 100644 index 93756c25..0000000 --- a/chrome/browser/chromeos/policy/consumer_enrollment_handler_factory.cc +++ /dev/null
@@ -1,78 +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/chromeos/policy/consumer_enrollment_handler_factory.h" - -#include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/policy/consumer_enrollment_handler.h" -#include "chrome/browser/chromeos/policy/consumer_management_service.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" -#include "chrome/browser/signin/signin_manager_factory.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/user_manager/user_manager.h" - -namespace policy { - -// static -ConsumerEnrollmentHandler* -ConsumerEnrollmentHandlerFactory::GetForBrowserContext( - content::BrowserContext* context) { - return static_cast<ConsumerEnrollmentHandler*>( - GetInstance()->GetServiceForBrowserContext(context, true)); -} - -// static -ConsumerEnrollmentHandlerFactory* -ConsumerEnrollmentHandlerFactory::GetInstance() { - return base::Singleton<ConsumerEnrollmentHandlerFactory>::get(); -} - -ConsumerEnrollmentHandlerFactory::ConsumerEnrollmentHandlerFactory() - : BrowserContextKeyedServiceFactory( - "ConsumerEnrollmentHandler", - BrowserContextDependencyManager::GetInstance()) { - DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance()); - DependsOn(SigninManagerFactory::GetInstance()); -} - -ConsumerEnrollmentHandlerFactory::~ConsumerEnrollmentHandlerFactory() { -} - -KeyedService* ConsumerEnrollmentHandlerFactory::BuildServiceInstanceFor( - content::BrowserContext* context) const { - // Some tests don't have a user manager and may crash at IsOwnerProfile(). - if (!user_manager::UserManager::IsInitialized()) - return nullptr; - - // On a fresh device, the first time the owner signs in, IsOwnerProfile() - // will return false. But it is okay since there's no enrollment in progress. - Profile* profile = Profile::FromBrowserContext(context); - if (!chromeos::ProfileHelper::IsOwnerProfile(profile)) - return nullptr; - - BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - ConsumerManagementService* service = - connector->GetConsumerManagementService(); - if (!service || - service->GetStatus() != ConsumerManagementService::STATUS_ENROLLING) { - return nullptr; - } - - return new ConsumerEnrollmentHandler( - profile, - service, - connector->GetDeviceManagementServiceForConsumer()); -} - -bool ConsumerEnrollmentHandlerFactory::ServiceIsCreatedWithBrowserContext() - const { - return true; -} - -} // namespace policy
diff --git a/chrome/browser/chromeos/policy/consumer_enrollment_handler_factory.h b/chrome/browser/chromeos/policy/consumer_enrollment_handler_factory.h deleted file mode 100644 index 72436fde..0000000 --- a/chrome/browser/chromeos/policy/consumer_enrollment_handler_factory.h +++ /dev/null
@@ -1,46 +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_CHROMEOS_POLICY_CONSUMER_ENROLLMENT_HANDLER_FACTORY_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_CONSUMER_ENROLLMENT_HANDLER_FACTORY_H_ - -#include "base/macros.h" -#include "base/memory/singleton.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -class Profile; - -namespace content { -class BrowserContext; -} - -namespace policy { - -class ConsumerEnrollmentHandler; - -class ConsumerEnrollmentHandlerFactory - : public BrowserContextKeyedServiceFactory { - public: - static ConsumerEnrollmentHandler* GetForBrowserContext( - content::BrowserContext* context); - - static ConsumerEnrollmentHandlerFactory* GetInstance(); - - private: - friend struct base::DefaultSingletonTraits<ConsumerEnrollmentHandlerFactory>; - - ConsumerEnrollmentHandlerFactory(); - ~ConsumerEnrollmentHandlerFactory() override; - - // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( - content::BrowserContext* context) const override; - bool ServiceIsCreatedWithBrowserContext() const override; - - DISALLOW_COPY_AND_ASSIGN(ConsumerEnrollmentHandlerFactory); -}; - -} // namespace policy - -#endif // CHROME_BROWSER_CHROMEOS_POLICY_CONSUMER_ENROLLMENT_HANDLER_FACTORY_H_
diff --git a/chrome/browser/chromeos/policy/consumer_enrollment_handler_factory_unittest.cc b/chrome/browser/chromeos/policy/consumer_enrollment_handler_factory_unittest.cc deleted file mode 100644 index c7824747..0000000 --- a/chrome/browser/chromeos/policy/consumer_enrollment_handler_factory_unittest.cc +++ /dev/null
@@ -1,90 +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/chromeos/policy/consumer_enrollment_handler_factory.h" - -#include "base/memory/ptr_util.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" -#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/policy/consumer_management_service.h" -#include "chrome/browser/chromeos/policy/consumer_management_stage.h" -#include "chrome/browser/chromeos/policy/fake_consumer_management_service.h" -#include "chrome/test/base/testing_browser_process.h" -#include "chrome/test/base/testing_profile_manager.h" -#include "content/public/test/test_browser_thread_bundle.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { -const char* kTestOwner = "test.owner@chromium.org.test"; -const char* kTestUser = "test.user@chromium.org.test"; -} - -namespace policy { - -class ConsumerEnrollmentHandlerFactoryTest : public testing::Test { - public: - ConsumerEnrollmentHandlerFactoryTest() - : fake_service_(new FakeConsumerManagementService()), - fake_user_manager_(new chromeos::FakeChromeUserManager()), - scoped_user_manager_enabler_(fake_user_manager_), - testing_profile_manager_( - new TestingProfileManager(TestingBrowserProcess::GetGlobal())) { - // Set up FakeConsumerManagementService. - fake_service_->SetStatusAndStage( - ConsumerManagementService::STATUS_ENROLLING, - ConsumerManagementStage::EnrollmentOwnerStored()); - - // Inject fake objects. - BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - connector->SetConsumerManagementServiceForTesting( - base::WrapUnique(fake_service_)); - - // Set up FakeChromeUserManager. - fake_user_manager_->AddUser(owner_account_id); - fake_user_manager_->AddUser(test_account_id); - fake_user_manager_->set_owner_id(owner_account_id); - } - - void SetUp() override { - testing::Test::SetUp(); - - ASSERT_TRUE(testing_profile_manager_->SetUp()); - } - - const AccountId owner_account_id = AccountId::FromUserEmail(kTestOwner); - const AccountId test_account_id = AccountId::FromUserEmail(kTestUser); - - content::TestBrowserThreadBundle thread_bundle_; - FakeConsumerManagementService* fake_service_; - chromeos::FakeChromeUserManager* fake_user_manager_; - chromeos::ScopedUserManagerEnabler scoped_user_manager_enabler_; - std::unique_ptr<TestingProfileManager> testing_profile_manager_; -}; - -TEST_F(ConsumerEnrollmentHandlerFactoryTest, ServiceIsCreated) { - Profile* profile = testing_profile_manager_->CreateTestingProfile( - owner_account_id.GetUserEmail()); - EXPECT_TRUE(ConsumerEnrollmentHandlerFactory::GetForBrowserContext(profile)); -} - -TEST_F(ConsumerEnrollmentHandlerFactoryTest, ServiceIsNotCreatedForNonOwner) { - Profile* profile = testing_profile_manager_->CreateTestingProfile(kTestUser); - EXPECT_FALSE(ConsumerEnrollmentHandlerFactory::GetForBrowserContext(profile)); -} - -TEST_F(ConsumerEnrollmentHandlerFactoryTest, - ServiceIsNotCreatedIfItHasNothingToDo) { - fake_service_->SetStatusAndStage( - ConsumerManagementService::STATUS_UNENROLLED, - ConsumerManagementStage::None()); - - Profile* profile = testing_profile_manager_->CreateTestingProfile(kTestOwner); - EXPECT_FALSE(ConsumerEnrollmentHandlerFactory::GetForBrowserContext(profile)); -} - -} // namespace policy
diff --git a/chrome/browser/chromeos/policy/consumer_enrollment_handler_unittest.cc b/chrome/browser/chromeos/policy/consumer_enrollment_handler_unittest.cc deleted file mode 100644 index 47f1611..0000000 --- a/chrome/browser/chromeos/policy/consumer_enrollment_handler_unittest.cc +++ /dev/null
@@ -1,157 +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/chromeos/policy/consumer_enrollment_handler.h" - -#include <memory> -#include <utility> - -#include "base/memory/ptr_util.h" -#include "base/run_loop.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" -#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/policy/consumer_management_service.h" -#include "chrome/browser/chromeos/policy/consumer_management_stage.h" -#include "chrome/browser/chromeos/policy/enrollment_status_chromeos.h" -#include "chrome/browser/chromeos/policy/fake_consumer_management_service.h" -#include "chrome/browser/chromeos/policy/fake_device_cloud_policy_initializer.h" -#include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h" -#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" -#include "chrome/browser/signin/signin_manager_factory.h" -#include "chrome/test/base/testing_browser_process.h" -#include "chrome/test/base/testing_profile_manager.h" -#include "components/signin/core/browser/fake_profile_oauth2_token_service.h" -#include "components/signin/core/browser/profile_oauth2_token_service.h" -#include "components/signin/core/browser/signin_manager_base.h" -#include "components/syncable_prefs/pref_service_syncable.h" -#include "content/public/test/test_browser_thread_bundle.h" -#include "google_apis/gaia/google_service_auth_error.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { -const char* kTestOwner = "test.owner@chromium.org.test"; -const char* kTestUser = "test.user@chromium.org.test"; -} - -namespace policy { - -class ConsumerEnrollmentHandlerTest : public testing::Test { - public: - ConsumerEnrollmentHandlerTest() - : fake_service_(new FakeConsumerManagementService()), - fake_initializer_(new FakeDeviceCloudPolicyInitializer()), - fake_user_manager_(new chromeos::FakeChromeUserManager()), - scoped_user_manager_enabler_(fake_user_manager_), - testing_profile_manager_( - new TestingProfileManager(TestingBrowserProcess::GetGlobal())) { - // Set up FakeConsumerManagementService. - fake_service_->SetStatusAndStage( - ConsumerManagementService::STATUS_ENROLLING, - ConsumerManagementStage::EnrollmentOwnerStored()); - - // Inject fake objects. - BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - connector->SetConsumerManagementServiceForTesting( - base::WrapUnique(fake_service_)); - connector->SetDeviceCloudPolicyInitializerForTesting( - base::WrapUnique(fake_initializer_)); - - // Set up FakeChromeUserManager. - fake_user_manager_->AddUser(AccountId::FromUserEmail(kTestOwner)); - fake_user_manager_->AddUser(AccountId::FromUserEmail(kTestUser)); - fake_user_manager_->set_owner_id(AccountId::FromUserEmail(kTestOwner)); - } - - void SetUp() override { - ASSERT_TRUE(testing_profile_manager_->SetUp()); - TestingProfile::TestingFactories factories; - factories.push_back( - std::make_pair(ProfileOAuth2TokenServiceFactory::GetInstance(), - BuildAutoIssuingFakeProfileOAuth2TokenService)); - profile_ = testing_profile_manager_->CreateTestingProfile( - kTestUser, std::unique_ptr<syncable_prefs::PrefServiceSyncable>(), - base::UTF8ToUTF16(kTestUser), 0, std::string(), factories); - - // Set up the authenticated user name and ID. - SigninManagerFactory::GetForProfile(profile_) - ->SetAuthenticatedAccountInfo(kTestOwner, kTestOwner); - - // Issue a fake refresh token. - GetFakeProfileOAuth2TokenService()->UpdateCredentials(kTestOwner, - "fake_token"); - } - - FakeProfileOAuth2TokenService* GetFakeProfileOAuth2TokenService() { - return static_cast<FakeProfileOAuth2TokenService*>( - ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)); - } - - void RunEnrollmentTest() { - handler_.reset( - new ConsumerEnrollmentHandler(profile_, fake_service_, NULL)); - base::RunLoop().RunUntilIdle(); - } - - content::TestBrowserThreadBundle thread_bundle; - FakeConsumerManagementService* fake_service_; - FakeDeviceCloudPolicyInitializer* fake_initializer_; - chromeos::FakeChromeUserManager* fake_user_manager_; - chromeos::ScopedUserManagerEnabler scoped_user_manager_enabler_; - std::unique_ptr<TestingProfileManager> testing_profile_manager_; - Profile* profile_; - std::unique_ptr<ConsumerEnrollmentHandler> handler_; -}; - -TEST_F(ConsumerEnrollmentHandlerTest, EnrollsSuccessfully) { - EXPECT_FALSE(fake_initializer_->was_start_enrollment_called()); - - RunEnrollmentTest(); - - EXPECT_TRUE(fake_initializer_->was_start_enrollment_called()); - EXPECT_EQ(ConsumerManagementStage::EnrollmentSuccess(), - fake_service_->GetStage()); -} - -TEST_F(ConsumerEnrollmentHandlerTest, FailsToGetAccessToken) { - // Disable auto-posting so that RunEnrollmentTest() should stop and wait for - // the access token to be available. - GetFakeProfileOAuth2TokenService()-> - set_auto_post_fetch_response_on_message_loop(false); - - RunEnrollmentTest(); - - // The service should have a pending token request. - OAuth2TokenService::Request* token_request = - handler_->GetTokenRequestForTesting(); - EXPECT_TRUE(token_request); - - // Tell the service that the access token is not available because of some - // backend issue. - handler_->OnGetTokenFailure( - token_request, - GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_ERROR)); - - EXPECT_FALSE(fake_initializer_->was_start_enrollment_called()); - EXPECT_EQ(ConsumerManagementStage::EnrollmentGetTokenFailed(), - fake_service_->GetStage()); -} - -TEST_F(ConsumerEnrollmentHandlerTest, FailsToRegister) { - EXPECT_FALSE(fake_initializer_->was_start_enrollment_called()); - fake_initializer_->set_enrollment_status(EnrollmentStatus::ForStatus( - EnrollmentStatus::STATUS_REGISTRATION_FAILED)); - - RunEnrollmentTest(); - - EXPECT_TRUE(fake_initializer_->was_start_enrollment_called()); - EXPECT_EQ(ConsumerManagementStage::EnrollmentDMServerFailed(), - fake_service_->GetStage()); -} - -} // namespace policy
diff --git a/chrome/browser/chromeos/policy/consumer_management_notifier.cc b/chrome/browser/chromeos/policy/consumer_management_notifier.cc deleted file mode 100644 index ec80349..0000000 --- a/chrome/browser/chromeos/policy/consumer_management_notifier.cc +++ /dev/null
@@ -1,200 +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/chromeos/policy/consumer_management_notifier.h" - -#include <string> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/strings/string16.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/chromeos/policy/consumer_management_stage.h" -#include "chrome/browser/notifications/notification.h" -#include "chrome/browser/notifications/notification_delegate.h" -#include "chrome/browser/notifications/notification_ui_manager.h" -#include "chrome/browser/ui/browser_navigator.h" -#include "chrome/browser/ui/browser_navigator_params.h" -#include "chrome/common/url_constants.h" -#include "grit/generated_resources.h" -#include "grit/theme_resources.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/page_transition_types.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/base/window_open_disposition.h" -#include "ui/message_center/notification_types.h" -#include "ui/message_center/notifier_settings.h" -#include "url/gurl.h" - -namespace { - -// Desktop notification constants. -const char kEnrollmentNotificationId[] = "consumer_management.enroll"; -const char kEnrollmentNotificationUrl[] = "chrome://consumer-management/enroll"; -const char kUnenrollmentNotificationId[] = "consumer_management.unenroll"; -const char kUnenrollmentNotificationUrl[] = - "chrome://consumer-management/unenroll"; - -// The path to the consumer management enrollment/unenrollment confirmation -// overlay, relative to the settings page URL. -const char kConsumerManagementOverlay[] = "consumer-management-overlay"; - -class DesktopNotificationDelegate : public NotificationDelegate { - public: - // |button_click_callback| is called when the button in the notification is - // clicked. - DesktopNotificationDelegate(const std::string& id, - const base::Closure& button_click_callback); - - // NotificationDelegate: - std::string id() const override; - void ButtonClick(int button_index) override; - - private: - ~DesktopNotificationDelegate() override; - - const std::string id_; - const base::Closure button_click_callback_; - - DISALLOW_COPY_AND_ASSIGN(DesktopNotificationDelegate); -}; - -DesktopNotificationDelegate::DesktopNotificationDelegate( - const std::string& id, - const base::Closure& button_click_callback) - : id_(id), button_click_callback_(button_click_callback) { -} - -DesktopNotificationDelegate::~DesktopNotificationDelegate() { -} - -std::string DesktopNotificationDelegate::id() const { - return id_; -} - -void DesktopNotificationDelegate::ButtonClick(int button_index) { - button_click_callback_.Run(); -} - -} // namespace - -namespace policy { - -ConsumerManagementNotifier::ConsumerManagementNotifier( - Profile* profile, - ConsumerManagementService* consumer_management_service) - : profile_(profile), - consumer_management_service_(consumer_management_service), - weak_ptr_factory_(this) { - consumer_management_service_->AddObserver(this); - OnConsumerManagementStatusChanged(); -} - -ConsumerManagementNotifier::~ConsumerManagementNotifier() { -} - -void ConsumerManagementNotifier::Shutdown() { - consumer_management_service_->RemoveObserver(this); -} - -void ConsumerManagementNotifier::OnConsumerManagementStatusChanged() { - const ConsumerManagementStage stage = - consumer_management_service_->GetStage(); - if (stage.HasPendingNotification()) { - // Reset the stage so that we won't show the same notification, again. - consumer_management_service_->SetStage(ConsumerManagementStage::None()); - ShowNotification(stage); - } -} - -void ConsumerManagementNotifier::ShowNotification( - const ConsumerManagementStage& stage) { - if (stage.HasEnrollmentSucceeded()) { - ShowDesktopNotification( - kEnrollmentNotificationId, - kEnrollmentNotificationUrl, - IDS_CONSUMER_MANAGEMENT_ENROLLMENT_NOTIFICATION_TITLE, - IDS_CONSUMER_MANAGEMENT_ENROLLMENT_NOTIFICATION_BODY, - IDS_CONSUMER_MANAGEMENT_NOTIFICATION_MODIFY_SETTINGS_BUTTON, - base::Bind(&ConsumerManagementNotifier::OpenSettingsPage, - weak_ptr_factory_.GetWeakPtr())); - } else if (stage.HasEnrollmentFailed()) { - ShowDesktopNotification( - kEnrollmentNotificationId, - kEnrollmentNotificationUrl, - IDS_CONSUMER_MANAGEMENT_ENROLLMENT_FAILURE_NOTIFICATION_TITLE, - IDS_CONSUMER_MANAGEMENT_ENROLLMENT_FAILURE_NOTIFICATION_BODY, - IDS_CONSUMER_MANAGEMENT_NOTIFICATION_TRY_AGAIN_BUTTON, - base::Bind(&ConsumerManagementNotifier::TryAgain, - weak_ptr_factory_.GetWeakPtr())); - } else if (stage.HasUnenrollmentSucceeded()) { - ShowDesktopNotification( - kUnenrollmentNotificationId, - kUnenrollmentNotificationUrl, - IDS_CONSUMER_MANAGEMENT_UNENROLLMENT_NOTIFICATION_TITLE, - IDS_CONSUMER_MANAGEMENT_UNENROLLMENT_NOTIFICATION_BODY, - IDS_CONSUMER_MANAGEMENT_NOTIFICATION_MODIFY_SETTINGS_BUTTON, - base::Bind(&ConsumerManagementNotifier::OpenSettingsPage, - weak_ptr_factory_.GetWeakPtr())); - } else if (stage.HasUnenrollmentFailed()) { - ShowDesktopNotification( - kUnenrollmentNotificationId, - kUnenrollmentNotificationUrl, - IDS_CONSUMER_MANAGEMENT_UNENROLLMENT_FAILURE_NOTIFICATION_TITLE, - IDS_CONSUMER_MANAGEMENT_UNENROLLMENT_FAILURE_NOTIFICATION_BODY, - IDS_CONSUMER_MANAGEMENT_NOTIFICATION_TRY_AGAIN_BUTTON, - base::Bind(&ConsumerManagementNotifier::TryAgain, - weak_ptr_factory_.GetWeakPtr())); - } else { - NOTREACHED(); - } -} - -void ConsumerManagementNotifier::ShowDesktopNotification( - const std::string& notification_id, - const std::string& notification_url, - int title_message_id, - int body_message_id, - int button_label_message_id, - const base::Closure& button_click_callback) { - message_center::RichNotificationData optional_field; - optional_field.buttons.push_back(message_center::ButtonInfo( - l10n_util::GetStringUTF16(button_label_message_id))); - - Notification notification( - message_center::NOTIFICATION_TYPE_SIMPLE, - l10n_util::GetStringUTF16(title_message_id), - l10n_util::GetStringUTF16(body_message_id), - ui::ResourceBundle::GetSharedInstance().GetImageNamed( - IDR_CONSUMER_MANAGEMENT_NOTIFICATION_ICON), - message_center::NotifierId(message_center::NotifierId::SYSTEM_COMPONENT, - notification_id), - base::string16(), // display_source - GURL(notification_url), notification_id, optional_field, - new DesktopNotificationDelegate(notification_id, button_click_callback)); - - notification.SetSystemPriority(); - g_browser_process->notification_ui_manager()->Add(notification, profile_); -} - -void ConsumerManagementNotifier::OpenSettingsPage() const { - const GURL url(chrome::kChromeUISettingsURL); - chrome::NavigateParams params(profile_, url, ui::PAGE_TRANSITION_LINK); - params.disposition = NEW_FOREGROUND_TAB; - chrome::Navigate(¶ms); -} - -void ConsumerManagementNotifier::TryAgain() const { - const GURL base_url(chrome::kChromeUISettingsURL); - const GURL url = base_url.Resolve(kConsumerManagementOverlay); - - chrome::NavigateParams params(profile_, url, ui::PAGE_TRANSITION_LINK); - params.disposition = NEW_FOREGROUND_TAB; - chrome::Navigate(¶ms); -} - -} // namespace policy
diff --git a/chrome/browser/chromeos/policy/consumer_management_notifier.h b/chrome/browser/chromeos/policy/consumer_management_notifier.h deleted file mode 100644 index e107b7f0..0000000 --- a/chrome/browser/chromeos/policy/consumer_management_notifier.h +++ /dev/null
@@ -1,68 +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_CHROMEOS_POLICY_CONSUMER_MANAGEMENT_NOTIFIER_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_CONSUMER_MANAGEMENT_NOTIFIER_H_ - -#include <string> - -#include "base/callback_forward.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "chrome/browser/chromeos/policy/consumer_management_service.h" -#include "components/keyed_service/core/keyed_service.h" - -class Profile; - -namespace policy { - -class ConsumerManagementStage; - -// ConsumerManagementNotifier observes ConsumerManagementService and shows -// a desktop notification to the device owner if consumer enrollment or -// unenrollment suceeds or fails. -class ConsumerManagementNotifier - : public KeyedService, - public ConsumerManagementService::Observer { - public: - ConsumerManagementNotifier( - Profile* profile, - ConsumerManagementService* consumer_management_service); - ~ConsumerManagementNotifier() override; - - void Shutdown() override; - - // ConsumerManagementService::Observer: - void OnConsumerManagementStatusChanged() override; - - private: - // Shows a notification based on |stage|. - void ShowNotification(const ConsumerManagementStage& stage); - - // Shows a desktop notification. - void ShowDesktopNotification( - const std::string& notification_id, - const std::string& notification_url, - int title_message_id, - int body_message_id, - int button_label_message_id, - const base::Closure& button_click_callback); - - // Opens the settings page. - void OpenSettingsPage() const; - - // Opens the enrollment/unenrollment confirmation dialog in the settings page. - void TryAgain() const; - - Profile* profile_; - ConsumerManagementService* consumer_management_service_; - - base::WeakPtrFactory<ConsumerManagementNotifier> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(ConsumerManagementNotifier); -}; - -} // namespace policy - -#endif // CHROME_BROWSER_CHROMEOS_POLICY_CONSUMER_MANAGEMENT_NOTIFIER_H_
diff --git a/chrome/browser/chromeos/policy/consumer_management_notifier_factory.cc b/chrome/browser/chromeos/policy/consumer_management_notifier_factory.cc deleted file mode 100644 index 1df68639f..0000000 --- a/chrome/browser/chromeos/policy/consumer_management_notifier_factory.cc +++ /dev/null
@@ -1,67 +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/chromeos/policy/consumer_management_notifier_factory.h" - -#include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/policy/consumer_management_notifier.h" -#include "chrome/browser/chromeos/profiles/profile_helper.h" -#include "chrome/browser/profiles/profile.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/user_manager/user_manager.h" - -namespace policy { - -// static -ConsumerManagementNotifier* -ConsumerManagementNotifierFactory::GetForBrowserContext( - content::BrowserContext* context) { - return static_cast<ConsumerManagementNotifier*>( - GetInstance()->GetServiceForBrowserContext(context, true)); -} - -// static -ConsumerManagementNotifierFactory* -ConsumerManagementNotifierFactory::GetInstance() { - return base::Singleton<ConsumerManagementNotifierFactory>::get(); -} - -ConsumerManagementNotifierFactory::ConsumerManagementNotifierFactory() - : BrowserContextKeyedServiceFactory( - "ConsumerManagementNotifier", - BrowserContextDependencyManager::GetInstance()) { -} - -ConsumerManagementNotifierFactory::~ConsumerManagementNotifierFactory() { -} - -KeyedService* ConsumerManagementNotifierFactory::BuildServiceInstanceFor( - content::BrowserContext* context) const { - // Some tests don't have a user manager and may crash at IsOwnerProfile(). - if (!user_manager::UserManager::IsInitialized()) - return nullptr; - - // On a fresh device, the first time the owner signs in, IsOwnerProfile() - // will return false. But it is okay since there's no notification to show. - Profile* profile = Profile::FromBrowserContext(context); - if (!chromeos::ProfileHelper::IsOwnerProfile(profile)) - return nullptr; - - ConsumerManagementService* service = - g_browser_process->platform_part()->browser_policy_connector_chromeos()-> - GetConsumerManagementService(); - if (!service) - return nullptr; - - return new ConsumerManagementNotifier(profile, service); -} - -bool ConsumerManagementNotifierFactory::ServiceIsCreatedWithBrowserContext() - const { - return true; -} - -} // namespace policy
diff --git a/chrome/browser/chromeos/policy/consumer_management_notifier_factory.h b/chrome/browser/chromeos/policy/consumer_management_notifier_factory.h deleted file mode 100644 index f8e935a..0000000 --- a/chrome/browser/chromeos/policy/consumer_management_notifier_factory.h +++ /dev/null
@@ -1,44 +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_CHROMEOS_POLICY_CONSUMER_MANAGEMENT_NOTIFIER_FACTORY_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_CONSUMER_MANAGEMENT_NOTIFIER_FACTORY_H_ - -#include "base/macros.h" -#include "base/memory/singleton.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace content { -class BrowserContext; -} - -namespace policy { - -class ConsumerManagementNotifier; - -class ConsumerManagementNotifierFactory - : public BrowserContextKeyedServiceFactory { - public: - static ConsumerManagementNotifier* GetForBrowserContext( - content::BrowserContext* context); - - static ConsumerManagementNotifierFactory* GetInstance(); - - private: - friend struct base::DefaultSingletonTraits<ConsumerManagementNotifierFactory>; - - ConsumerManagementNotifierFactory(); - ~ConsumerManagementNotifierFactory() override; - - // BrowserContextKeyedServiceFactory: - KeyedService* BuildServiceInstanceFor( - content::BrowserContext* context) const override; - bool ServiceIsCreatedWithBrowserContext() const override; - - DISALLOW_COPY_AND_ASSIGN(ConsumerManagementNotifierFactory); -}; - -} // namespace policy - -#endif // CHROME_BROWSER_CHROMEOS_POLICY_CONSUMER_MANAGEMENT_NOTIFIER_FACTORY_H_
diff --git a/chrome/browser/chromeos/policy/consumer_management_notifier_factory_unittest.cc b/chrome/browser/chromeos/policy/consumer_management_notifier_factory_unittest.cc deleted file mode 100644 index d7516eb2..0000000 --- a/chrome/browser/chromeos/policy/consumer_management_notifier_factory_unittest.cc +++ /dev/null
@@ -1,77 +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/chromeos/policy/consumer_management_notifier_factory.h" - -#include "base/memory/ptr_util.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" -#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/policy/consumer_management_service.h" -#include "chrome/browser/chromeos/policy/consumer_management_stage.h" -#include "chrome/browser/chromeos/policy/fake_consumer_management_service.h" -#include "chrome/test/base/testing_browser_process.h" -#include "chrome/test/base/testing_profile_manager.h" -#include "content/public/test/test_browser_thread_bundle.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { -const char* kTestOwner = "test.owner@chromium.org.test"; -const char* kTestUser = "test.user@chromium.org.test"; -} - -namespace policy { - -class ConsumerManagementNotifierFactoryTest : public testing::Test { - public: - ConsumerManagementNotifierFactoryTest() - : fake_service_(new FakeConsumerManagementService()), - fake_user_manager_(new chromeos::FakeChromeUserManager()), - scoped_user_manager_enabler_(fake_user_manager_), - testing_profile_manager_( - new TestingProfileManager(TestingBrowserProcess::GetGlobal())) { - // Set up FakeConsumerManagementService. - fake_service_->SetStatusAndStage( - ConsumerManagementService::STATUS_UNENROLLED, - ConsumerManagementStage::None()); - - // Inject fake objects. - BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - connector->SetConsumerManagementServiceForTesting( - base::WrapUnique(fake_service_)); - - // Set up FakeChromeUserManager. - fake_user_manager_->AddUser(AccountId::FromUserEmail(kTestOwner)); - fake_user_manager_->AddUser(AccountId::FromUserEmail(kTestUser)); - fake_user_manager_->set_owner_id(AccountId::FromUserEmail(kTestOwner)); - } - - void SetUp() override { - ASSERT_TRUE(testing_profile_manager_->SetUp()); - } - - content::TestBrowserThreadBundle thread_bundle_; - FakeConsumerManagementService* fake_service_; - chromeos::FakeChromeUserManager* fake_user_manager_; - chromeos::ScopedUserManagerEnabler scoped_user_manager_enabler_; - std::unique_ptr<TestingProfileManager> testing_profile_manager_; -}; - -TEST_F(ConsumerManagementNotifierFactoryTest, ServiceIsCreated) { - Profile* profile = testing_profile_manager_->CreateTestingProfile(kTestOwner); - EXPECT_TRUE( - ConsumerManagementNotifierFactory::GetForBrowserContext(profile)); -} - -TEST_F(ConsumerManagementNotifierFactoryTest, - ServiceIsNotCreatedForNonOwner) { - Profile* profile = testing_profile_manager_->CreateTestingProfile(kTestUser); - EXPECT_FALSE( - ConsumerManagementNotifierFactory::GetForBrowserContext(profile)); -} - -} // namespace policy
diff --git a/chrome/browser/chromeos/policy/consumer_management_notifier_unittest.cc b/chrome/browser/chromeos/policy/consumer_management_notifier_unittest.cc deleted file mode 100644 index 229b7f0..0000000 --- a/chrome/browser/chromeos/policy/consumer_management_notifier_unittest.cc +++ /dev/null
@@ -1,154 +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/chromeos/policy/consumer_management_notifier.h" - -#include <memory> - -#include "base/memory/ptr_util.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/policy/consumer_management_service.h" -#include "chrome/browser/chromeos/policy/consumer_management_stage.h" -#include "chrome/browser/chromeos/policy/fake_consumer_management_service.h" -#include "chrome/browser/notifications/notification_ui_manager.h" -#include "chrome/test/base/browser_with_test_window_test.h" -#include "chrome/test/base/testing_browser_process.h" -#include "chrome/test/base/testing_profile_manager.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace policy { - -class ConsumerManagementNotifierTest : public BrowserWithTestWindowTest { - public: - ConsumerManagementNotifierTest() - : fake_service_(new FakeConsumerManagementService()) { - fake_service_->SetStatusAndStage( - ConsumerManagementService::STATUS_UNENROLLED, - ConsumerManagementStage::None()); - - // Inject objects. - BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - connector->SetConsumerManagementServiceForTesting( - base::WrapUnique(fake_service_)); - } - - void SetUp() override { - BrowserWithTestWindowTest::SetUp(); - - // Set up TestingProfileManager. This is required for NotificationUIManager. - testing_profile_manager_.reset(new TestingProfileManager( - TestingBrowserProcess::GetGlobal())); - ASSERT_TRUE(testing_profile_manager_->SetUp()); - } - - void TearDown() override { - if (notification_) - notification_->Shutdown(); - notification_.reset(); - g_browser_process->notification_ui_manager()->CancelAll(); - testing_profile_manager_.reset(); - - BrowserWithTestWindowTest::TearDown(); - } - - void CreateConsumerManagementNotifier() { - notification_.reset( - new ConsumerManagementNotifier(profile(), fake_service_)); - } - - bool HasEnrollmentNotification() { - return g_browser_process->notification_ui_manager()->FindById( - "consumer_management.enroll", - NotificationUIManager::GetProfileID(profile())); - } - - bool HasUnenrollmentNotification() { - return g_browser_process->notification_ui_manager()->FindById( - "consumer_management.unenroll", - NotificationUIManager::GetProfileID(profile())); - } - - FakeConsumerManagementService* fake_service_; - std::unique_ptr<TestingProfileManager> testing_profile_manager_; - std::unique_ptr<ConsumerManagementNotifier> notification_; -}; - -TEST_F(ConsumerManagementNotifierTest, - ShowsEnrollmentNotificationWhenCreated) { - fake_service_->SetStatusAndStage( - ConsumerManagementService::STATUS_UNENROLLED, - ConsumerManagementStage::EnrollmentCanceled()); - EXPECT_FALSE(HasEnrollmentNotification()); - EXPECT_FALSE(HasUnenrollmentNotification()); - - CreateConsumerManagementNotifier(); - - EXPECT_EQ(ConsumerManagementStage::None(), fake_service_->GetStage()); - EXPECT_TRUE(HasEnrollmentNotification()); - EXPECT_FALSE(HasUnenrollmentNotification()); -} - -TEST_F(ConsumerManagementNotifierTest, - ShowsUnenrollmentNotificationWhenCreated) { - fake_service_->SetStatusAndStage( - ConsumerManagementService::STATUS_UNENROLLED, - ConsumerManagementStage::UnenrollmentSuccess()); - EXPECT_FALSE(HasEnrollmentNotification()); - EXPECT_FALSE(HasUnenrollmentNotification()); - - CreateConsumerManagementNotifier(); - - EXPECT_EQ(ConsumerManagementStage::None(), fake_service_->GetStage()); - EXPECT_FALSE(HasEnrollmentNotification()); - EXPECT_TRUE(HasUnenrollmentNotification()); -} - -TEST_F(ConsumerManagementNotifierTest, - ShowsEnrollmentNotificationWhenStatusChanged) { - fake_service_->SetStatusAndStage( - ConsumerManagementService::STATUS_ENROLLING, - ConsumerManagementStage::EnrollmentOwnerStored()); - - CreateConsumerManagementNotifier(); - EXPECT_EQ(ConsumerManagementStage::EnrollmentOwnerStored(), - fake_service_->GetStage()); - EXPECT_FALSE(HasEnrollmentNotification()); - EXPECT_FALSE(HasUnenrollmentNotification()); - - fake_service_->SetStatusAndStage( - ConsumerManagementService::STATUS_ENROLLED, - ConsumerManagementStage::EnrollmentSuccess()); - EXPECT_EQ(ConsumerManagementStage::None(), fake_service_->GetStage()); - EXPECT_TRUE(HasEnrollmentNotification()); - EXPECT_FALSE(HasUnenrollmentNotification()); -} - -TEST_F(ConsumerManagementNotifierTest, - ShowsUnenrollmentNotificationWhenStatusChanged) { - fake_service_->SetStatusAndStage( - ConsumerManagementService::STATUS_ENROLLED, - ConsumerManagementStage::None()); - - CreateConsumerManagementNotifier(); - EXPECT_FALSE(HasEnrollmentNotification()); - EXPECT_FALSE(HasUnenrollmentNotification()); - - fake_service_->SetStatusAndStage( - ConsumerManagementService::STATUS_UNENROLLING, - ConsumerManagementStage::UnenrollmentRequested()); - EXPECT_FALSE(HasEnrollmentNotification()); - EXPECT_FALSE(HasUnenrollmentNotification()); - - fake_service_->SetStatusAndStage( - ConsumerManagementService::STATUS_UNENROLLED, - ConsumerManagementStage::UnenrollmentSuccess()); - EXPECT_EQ(ConsumerManagementStage::None(), fake_service_->GetStage()); - EXPECT_FALSE(HasEnrollmentNotification()); - EXPECT_TRUE(HasUnenrollmentNotification()); -} - -} // namespace policy
diff --git a/chrome/browser/chromeos/policy/consumer_management_service.cc b/chrome/browser/chromeos/policy/consumer_management_service.cc deleted file mode 100644 index 11b99774..0000000 --- a/chrome/browser/chromeos/policy/consumer_management_service.cc +++ /dev/null
@@ -1,200 +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/chromeos/policy/consumer_management_service.h" - -#include "base/bind.h" -#include "base/callback.h" -#include "base/logging.h" -#include "base/macros.h" -#include "chrome/browser/browser_process.h" -#include "chrome/common/pref_names.h" -#include "chromeos/dbus/cryptohome/rpc.pb.h" -#include "chromeos/dbus/cryptohome_client.h" -#include "components/policy/core/common/cloud/cloud_policy_constants.h" -#include "components/prefs/pref_registry_simple.h" -#include "components/prefs/pref_service.h" -#include "policy/proto/device_management_backend.pb.h" - -namespace em = enterprise_management; - -namespace { - -// Boot atttributes ID. -const char kAttributeOwnerId[] = "consumer_management.owner_id"; - -// The string of Status enum. -const char* const kStatusString[] = { - "StatusUnknown", - "StatusEnrolled", - "StatusEnrolling", - "StatusUnenrolled", - "StatusUnenrolling", -}; - -static_assert( - arraysize(kStatusString) == policy::ConsumerManagementService::STATUS_LAST, - "invalid kStatusString array size"); - -} // namespace - -namespace policy { - -ConsumerManagementService::ConsumerManagementService( - chromeos::CryptohomeClient* client, - chromeos::DeviceSettingsService* device_settings_service) - : client_(client), - device_settings_service_(device_settings_service), - weak_ptr_factory_(this) { - // A NULL value may be passed in tests. - if (device_settings_service_) - device_settings_service_->AddObserver(this); -} - -ConsumerManagementService::~ConsumerManagementService() { - if (device_settings_service_) - device_settings_service_->RemoveObserver(this); -} - -// static -void ConsumerManagementService::RegisterPrefs(PrefRegistrySimple* registry) { - registry->RegisterIntegerPref( - prefs::kConsumerManagementStage, - ConsumerManagementStage::None().ToInternalValue()); -} - -void ConsumerManagementService::AddObserver(Observer* observer) { - observers_.AddObserver(observer); -} - -void ConsumerManagementService::RemoveObserver(Observer* observer) { - observers_.RemoveObserver(observer); -} - -ConsumerManagementService::Status -ConsumerManagementService::GetStatus() const { - if (!device_settings_service_) - return STATUS_UNKNOWN; - - const em::PolicyData* policy_data = device_settings_service_->policy_data(); - if (!policy_data) - return STATUS_UNKNOWN; - - const ConsumerManagementStage stage = GetStage(); - if (GetManagementMode(*policy_data) == MANAGEMENT_MODE_CONSUMER_MANAGED) { - if (stage.IsUnenrolling()) - return STATUS_UNENROLLING; - return STATUS_ENROLLED; - } - - if (stage.IsEnrolling()) - return STATUS_ENROLLING; - - return STATUS_UNENROLLED; -} - -std::string ConsumerManagementService::GetStatusString() const { - return kStatusString[GetStatus()]; -} - -ConsumerManagementStage ConsumerManagementService::GetStage() const { - const PrefService* prefs = g_browser_process->local_state(); - const int stage = prefs->GetInteger(prefs::kConsumerManagementStage); - return ConsumerManagementStage::FromInternalValue(stage); -} - -void ConsumerManagementService::SetStage( - const ConsumerManagementStage& stage) { - PrefService* prefs = g_browser_process->local_state(); - prefs->SetInteger(prefs::kConsumerManagementStage, stage.ToInternalValue()); - - NotifyStatusChanged(); -} - -void ConsumerManagementService::GetOwner(const GetOwnerCallback& callback) { - cryptohome::GetBootAttributeRequest request; - request.set_name(kAttributeOwnerId); - client_->GetBootAttribute( - request, - base::Bind(&ConsumerManagementService::OnGetBootAttributeDone, - weak_ptr_factory_.GetWeakPtr(), - callback)); -} - -void ConsumerManagementService::SetOwner(const std::string& user_id, - const SetOwnerCallback& callback) { - cryptohome::SetBootAttributeRequest request; - request.set_name(kAttributeOwnerId); - request.set_value(user_id.data(), user_id.size()); - client_->SetBootAttribute( - request, - base::Bind(&ConsumerManagementService::OnSetBootAttributeDone, - weak_ptr_factory_.GetWeakPtr(), - callback)); -} - -void ConsumerManagementService::OwnershipStatusChanged() { -} - -void ConsumerManagementService::DeviceSettingsUpdated() { - NotifyStatusChanged(); -} - -void ConsumerManagementService::OnDeviceSettingsServiceShutdown() { - device_settings_service_ = nullptr; -} - -void ConsumerManagementService::NotifyStatusChanged() { - FOR_EACH_OBSERVER(Observer, observers_, OnConsumerManagementStatusChanged()); -} - -void ConsumerManagementService::OnGetBootAttributeDone( - const GetOwnerCallback& callback, - chromeos::DBusMethodCallStatus call_status, - bool dbus_success, - const cryptohome::BaseReply& reply) { - if (!dbus_success || reply.error() != 0) { - LOG(ERROR) << "Failed to get the owner info from boot lockbox."; - callback.Run(""); - return; - } - - callback.Run( - reply.GetExtension(cryptohome::GetBootAttributeReply::reply).value()); -} - -void ConsumerManagementService::OnSetBootAttributeDone( - const SetOwnerCallback& callback, - chromeos::DBusMethodCallStatus call_status, - bool dbus_success, - const cryptohome::BaseReply& reply) { - if (!dbus_success || reply.error() != 0) { - LOG(ERROR) << "Failed to set owner info in boot lockbox."; - callback.Run(false); - return; - } - - cryptohome::FlushAndSignBootAttributesRequest request; - client_->FlushAndSignBootAttributes( - request, - base::Bind(&ConsumerManagementService::OnFlushAndSignBootAttributesDone, - weak_ptr_factory_.GetWeakPtr(), - callback)); -} - -void ConsumerManagementService::OnFlushAndSignBootAttributesDone( - const SetOwnerCallback& callback, - chromeos::DBusMethodCallStatus call_status, - bool dbus_success, - const cryptohome::BaseReply& reply) { - if (!dbus_success || reply.error() != 0) { - LOG(ERROR) << "Failed to flush and sign boot lockbox."; - callback.Run(false); - return; - } - - callback.Run(true); -} - -} // namespace policy
diff --git a/chrome/browser/chromeos/policy/consumer_management_service.h b/chrome/browser/chromeos/policy/consumer_management_service.h deleted file mode 100644 index 848284f5..0000000 --- a/chrome/browser/chromeos/policy/consumer_management_service.h +++ /dev/null
@@ -1,152 +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_CHROMEOS_POLICY_CONSUMER_MANAGEMENT_SERVICE_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_CONSUMER_MANAGEMENT_SERVICE_H_ - -#include <string> - -#include "base/callback_forward.h" -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/observer_list.h" -#include "chrome/browser/chromeos/policy/consumer_management_stage.h" -#include "chrome/browser/chromeos/settings/device_settings_service.h" -#include "chromeos/dbus/dbus_method_call_status.h" - -class PrefRegistrySimple; - -namespace chromeos { -class CryptohomeClient; -} - -namespace cryptohome { -class BaseReply; -} - -namespace policy { - -// The consumer management service handles several things: -// -// 1. The consumer management status: The consumer management status is an enum -// indicating if the device is consumer-managed and if enrollment or un- -// enrollment is in progress. The service can be observed and the observers -// will be notified when the status is changed. Note that the observers may -// be notified even when the status is NOT changed. The observers need to -// check the status upon receiving the notification. -// -// 2. The consumer management stage: The consumer management stage is a value -// indicating the enrollment or the unenrollment process, stored in local -// state to pass the information across reboots and between components, -// including settings page, sign-in screen, and user notification. -// -// 3. Boot lockbox owner ID: Unlike the owner ID in CrosSettings, the owner ID -// stored in the boot lockbox can only be modified after reboot and before -// the first session starts. It is guaranteed that if the device is consumer -// managed, the owner ID in the boot lockbox will be available, but not the -// other way. -class ConsumerManagementService - : public chromeos::DeviceSettingsService::Observer { - public: - // The status indicates if the device is enrolled, or if enrollment or - // unenrollment is in progress. If you want to add a value here, please also - // update |kStatusString| in the .cc file, and |ConsumerManagementStatus| in - // chrome/browser/resources/options/chromeos/consumer_management_overlay.js - enum Status { - // The status is currently unavailable. - STATUS_UNKNOWN = 0, - - STATUS_ENROLLED, - STATUS_ENROLLING, - STATUS_UNENROLLED, - STATUS_UNENROLLING, - - // This should always be the last one. - STATUS_LAST, - }; - - class Observer { - public: - // Called when the status changes. - virtual void OnConsumerManagementStatusChanged() = 0; - }; - - // GetOwner() invokes this with an argument set to the owner user ID, - // or an empty string on failure. - typedef base::Callback<void(const std::string&)> GetOwnerCallback; - - // SetOwner() invokes this with an argument indicating success or failure. - typedef base::Callback<void(bool)> SetOwnerCallback; - - // |client| and |device_settings_service| should outlive this object. - ConsumerManagementService( - chromeos::CryptohomeClient* client, - chromeos::DeviceSettingsService* device_settings_service); - - ~ConsumerManagementService() override; - - // Registers prefs. - static void RegisterPrefs(PrefRegistrySimple* registry); - - void AddObserver(Observer* observer); - void RemoveObserver(Observer* observer); - - // Returns the status. - virtual Status GetStatus() const; - - // Returns the string value of the status. - std::string GetStatusString() const; - - // Returns the stage. - virtual ConsumerManagementStage GetStage() const; - - // Sets the stage. - virtual void SetStage(const ConsumerManagementStage& stage); - - // Returns the device owner stored in the boot lockbox via |callback|. - void GetOwner(const GetOwnerCallback& callback); - - // Stores the device owner user ID into the boot lockbox and signs it. - // |callback| is invoked with an agument indicating success or failure. - void SetOwner(const std::string& user_id, const SetOwnerCallback& callback); - - // chromeos::DeviceSettingsService::Observer: - void OwnershipStatusChanged() override; - void DeviceSettingsUpdated() override; - void OnDeviceSettingsServiceShutdown() override; - - protected: - void NotifyStatusChanged(); - - private: - void OnGetBootAttributeDone( - const GetOwnerCallback& callback, - chromeos::DBusMethodCallStatus call_status, - bool dbus_success, - const cryptohome::BaseReply& reply); - - void OnSetBootAttributeDone(const SetOwnerCallback& callback, - chromeos::DBusMethodCallStatus call_status, - bool dbus_success, - const cryptohome::BaseReply& reply); - - void OnFlushAndSignBootAttributesDone( - const SetOwnerCallback& callback, - chromeos::DBusMethodCallStatus call_status, - bool dbus_success, - const cryptohome::BaseReply& reply); - - chromeos::CryptohomeClient* client_; - chromeos::DeviceSettingsService* device_settings_service_; - - base::ObserverList<Observer, true> observers_; - base::WeakPtrFactory<ConsumerManagementService> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(ConsumerManagementService); -}; - -} // namespace policy - -#endif // CHROME_BROWSER_CHROMEOS_POLICY_CONSUMER_MANAGEMENT_SERVICE_H_
diff --git a/chrome/browser/chromeos/policy/consumer_management_service_unittest.cc b/chrome/browser/chromeos/policy/consumer_management_service_unittest.cc deleted file mode 100644 index ea206e7..0000000 --- a/chrome/browser/chromeos/policy/consumer_management_service_unittest.cc +++ /dev/null
@@ -1,253 +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/chromeos/policy/consumer_management_service.h" - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/callback.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/chromeos/policy/device_policy_builder.h" -#include "chrome/browser/chromeos/settings/device_settings_test_helper.h" -#include "chrome/common/pref_names.h" -#include "chrome/test/base/browser_with_test_window_test.h" -#include "chrome/test/base/scoped_testing_local_state.h" -#include "chrome/test/base/testing_browser_process.h" -#include "chrome/test/base/testing_profile_manager.h" -#include "chromeos/dbus/cryptohome/rpc.pb.h" -#include "chromeos/dbus/cryptohome_client.h" -#include "chromeos/dbus/mock_cryptohome_client.h" -#include "components/prefs/pref_registry_simple.h" -#include "components/prefs/pref_service.h" -#include "policy/proto/device_management_backend.pb.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using testing::Invoke; -using testing::NiceMock; -using testing::_; - -namespace em = enterprise_management; - -namespace { -const char kAttributeOwnerId[] = "consumer_management.owner_id"; -const char kTestOwner[] = "test@chromium.org.test"; -} - -namespace policy { - -class ConsumerManagementServiceTest : public BrowserWithTestWindowTest { - public: - ConsumerManagementServiceTest() - : cryptohome_result_(false), - set_owner_status_(false) { - ON_CALL(mock_cryptohome_client_, GetBootAttribute(_, _)) - .WillByDefault( - Invoke(this, &ConsumerManagementServiceTest::MockGetBootAttribute)); - ON_CALL(mock_cryptohome_client_, SetBootAttribute(_, _)) - .WillByDefault( - Invoke(this, &ConsumerManagementServiceTest::MockSetBootAttribute)); - ON_CALL(mock_cryptohome_client_, FlushAndSignBootAttributes(_, _)) - .WillByDefault( - Invoke(this, - &ConsumerManagementServiceTest:: - MockFlushAndSignBootAttributes)); - } - - void SetUp() override { - BrowserWithTestWindowTest::SetUp(); - - testing_profile_manager_.reset(new TestingProfileManager( - TestingBrowserProcess::GetGlobal())); - ASSERT_TRUE(testing_profile_manager_->SetUp()); - service_.reset(new ConsumerManagementService(&mock_cryptohome_client_, - NULL)); - } - - void TearDown() override { - testing_profile_manager_.reset(); - service_.reset(); - - BrowserWithTestWindowTest::TearDown(); - } - - ConsumerManagementStage GetStageFromLocalState() { - return ConsumerManagementStage::FromInternalValue( - g_browser_process->local_state()->GetInteger( - prefs::kConsumerManagementStage)); - } - - void SetStageInLocalState(ConsumerManagementStage stage) { - g_browser_process->local_state()->SetInteger( - prefs::kConsumerManagementStage, stage.ToInternalValue()); - } - - void MockGetBootAttribute( - const cryptohome::GetBootAttributeRequest& request, - const chromeos::CryptohomeClient::ProtobufMethodCallback& callback) { - get_boot_attribute_request_ = request; - callback.Run(cryptohome_status_, cryptohome_result_, cryptohome_reply_); - } - - void MockSetBootAttribute( - const cryptohome::SetBootAttributeRequest& request, - const chromeos::CryptohomeClient::ProtobufMethodCallback& callback) { - set_boot_attribute_request_ = request; - callback.Run(cryptohome_status_, cryptohome_result_, cryptohome_reply_); - } - - void MockFlushAndSignBootAttributes( - const cryptohome::FlushAndSignBootAttributesRequest& request, - const chromeos::CryptohomeClient::ProtobufMethodCallback& callback) { - callback.Run(cryptohome_status_, cryptohome_result_, cryptohome_reply_); - } - - void OnGetOwnerDone(const std::string& owner) { - owner_ = owner; - } - - void OnSetOwnerDone(bool status) { - set_owner_status_ = status; - } - - NiceMock<chromeos::MockCryptohomeClient> mock_cryptohome_client_; - std::unique_ptr<ConsumerManagementService> service_; - std::unique_ptr<TestingProfileManager> testing_profile_manager_; - - // Variables for setting the return value or catching the arguments of mock - // functions. - chromeos::DBusMethodCallStatus cryptohome_status_; - bool cryptohome_result_; - cryptohome::BaseReply cryptohome_reply_; - cryptohome::GetBootAttributeRequest get_boot_attribute_request_; - cryptohome::SetBootAttributeRequest set_boot_attribute_request_; - std::string owner_; - bool set_owner_status_; -}; - -TEST_F(ConsumerManagementServiceTest, CanGetStage) { - EXPECT_EQ(ConsumerManagementStage::None(), service_->GetStage()); - - SetStageInLocalState(ConsumerManagementStage::EnrollmentRequested()); - - EXPECT_EQ(ConsumerManagementStage::EnrollmentRequested(), - service_->GetStage()); -} - -TEST_F(ConsumerManagementServiceTest, CanSetStage) { - EXPECT_EQ(ConsumerManagementStage::None(), GetStageFromLocalState()); - - service_->SetStage(ConsumerManagementStage::EnrollmentRequested()); - - EXPECT_EQ(ConsumerManagementStage::EnrollmentRequested(), - GetStageFromLocalState()); -} - -TEST_F(ConsumerManagementServiceTest, CanGetOwner) { - cryptohome_status_ = chromeos::DBUS_METHOD_CALL_SUCCESS; - cryptohome_result_ = true; - cryptohome_reply_.MutableExtension(cryptohome::GetBootAttributeReply::reply)-> - set_value(kTestOwner); - - service_->GetOwner(base::Bind(&ConsumerManagementServiceTest::OnGetOwnerDone, - base::Unretained(this))); - - EXPECT_EQ(kAttributeOwnerId, get_boot_attribute_request_.name()); - EXPECT_EQ(kTestOwner, owner_); -} - -TEST_F(ConsumerManagementServiceTest, GetOwnerReturnsAnEmptyStringWhenItFails) { - cryptohome_status_ = chromeos::DBUS_METHOD_CALL_FAILURE; - cryptohome_result_ = false; - cryptohome_reply_.MutableExtension(cryptohome::GetBootAttributeReply::reply)-> - set_value(kTestOwner); - - service_->GetOwner(base::Bind(&ConsumerManagementServiceTest::OnGetOwnerDone, - base::Unretained(this))); - - EXPECT_EQ("", owner_); -} - -TEST_F(ConsumerManagementServiceTest, CanSetOwner) { - cryptohome_status_ = chromeos::DBUS_METHOD_CALL_SUCCESS; - cryptohome_result_ = true; - - service_->SetOwner(kTestOwner, - base::Bind(&ConsumerManagementServiceTest::OnSetOwnerDone, - base::Unretained(this))); - - EXPECT_EQ(kAttributeOwnerId, set_boot_attribute_request_.name()); - EXPECT_EQ(kTestOwner, set_boot_attribute_request_.value()); - EXPECT_TRUE(set_owner_status_); -} - -TEST_F(ConsumerManagementServiceTest, SetOwnerReturnsFalseWhenItFails) { - cryptohome_status_ = chromeos::DBUS_METHOD_CALL_FAILURE; - cryptohome_result_ = false; - - service_->SetOwner(kTestOwner, - base::Bind(&ConsumerManagementServiceTest::OnSetOwnerDone, - base::Unretained(this))); - - EXPECT_FALSE(set_owner_status_); -} - -class ConsumerManagementServiceStatusTest - : public chromeos::DeviceSettingsTestBase { - public: - ConsumerManagementServiceStatusTest() - : testing_local_state_(TestingBrowserProcess::GetGlobal()), - service_(NULL, &device_settings_service_) { - } - - void SetStageInLocalState(ConsumerManagementStage stage) { - testing_local_state_.Get()->SetInteger( - prefs::kConsumerManagementStage, stage.ToInternalValue()); - } - - void SetManagementMode(em::PolicyData::ManagementMode mode) { - device_policy_.policy_data().set_management_mode(mode); - device_policy_.Build(); - device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob()); - ReloadDeviceSettings(); - } - - ScopedTestingLocalState testing_local_state_; - ConsumerManagementService service_; -}; - -TEST_F(ConsumerManagementServiceStatusTest, - GetStatusAndGetStatusStringNotificationWork) { - EXPECT_EQ(ConsumerManagementService::STATUS_UNKNOWN, service_.GetStatus()); - EXPECT_EQ("StatusUnknown", service_.GetStatusString()); - - SetManagementMode(em::PolicyData::LOCAL_OWNER); - SetStageInLocalState(ConsumerManagementStage::None()); - - EXPECT_EQ(ConsumerManagementService::STATUS_UNENROLLED, service_.GetStatus()); - EXPECT_EQ("StatusUnenrolled", service_.GetStatusString()); - - SetStageInLocalState(ConsumerManagementStage::EnrollmentRequested()); - - EXPECT_EQ(ConsumerManagementService::STATUS_ENROLLING, service_.GetStatus()); - EXPECT_EQ("StatusEnrolling", service_.GetStatusString()); - - SetManagementMode(em::PolicyData::CONSUMER_MANAGED); - SetStageInLocalState(ConsumerManagementStage::EnrollmentSuccess()); - - EXPECT_EQ(ConsumerManagementService::STATUS_ENROLLED, service_.GetStatus()); - EXPECT_EQ("StatusEnrolled", service_.GetStatusString()); - - SetStageInLocalState(ConsumerManagementStage::UnenrollmentRequested()); - EXPECT_EQ(ConsumerManagementService::STATUS_UNENROLLING, - service_.GetStatus()); - EXPECT_EQ("StatusUnenrolling", service_.GetStatusString()); - - SetManagementMode(em::PolicyData::LOCAL_OWNER); - SetStageInLocalState(ConsumerManagementStage::UnenrollmentSuccess()); - EXPECT_EQ(ConsumerManagementService::STATUS_UNENROLLED, service_.GetStatus()); - EXPECT_EQ("StatusUnenrolled", service_.GetStatusString()); -} - -} // namespace policy
diff --git a/chrome/browser/chromeos/policy/consumer_management_stage.cc b/chrome/browser/chromeos/policy/consumer_management_stage.cc deleted file mode 100644 index 7a031fd..0000000 --- a/chrome/browser/chromeos/policy/consumer_management_stage.cc +++ /dev/null
@@ -1,137 +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/chromeos/policy/consumer_management_stage.h" - -#include "base/logging.h" - -namespace policy { - -// static -ConsumerManagementStage ConsumerManagementStage::None() { - return ConsumerManagementStage(NONE); -} - -// static -ConsumerManagementStage ConsumerManagementStage::EnrollmentRequested() { - return ConsumerManagementStage(ENROLLMENT_REQUESTED); -} - -// static -ConsumerManagementStage ConsumerManagementStage::EnrollmentOwnerStored() { - return ConsumerManagementStage(ENROLLMENT_OWNER_STORED); -} - -// static -ConsumerManagementStage ConsumerManagementStage::EnrollmentSuccess() { - return ConsumerManagementStage(ENROLLMENT_SUCCESS); -} - -// static -ConsumerManagementStage ConsumerManagementStage::EnrollmentCanceled() { - return ConsumerManagementStage(ENROLLMENT_CANCELED); -} - -// static -ConsumerManagementStage ConsumerManagementStage::EnrollmentBootLockboxFailed() { - return ConsumerManagementStage(ENROLLMENT_BOOT_LOCKBOX_FAILED); -} - -// static -ConsumerManagementStage ConsumerManagementStage::EnrollmentGetTokenFailed() { - return ConsumerManagementStage(ENROLLMENT_GET_TOKEN_FAILED); -} - -// static -ConsumerManagementStage ConsumerManagementStage::EnrollmentDMServerFailed() { - return ConsumerManagementStage(ENROLLMENT_DM_SERVER_FAILED); -} - -// static -ConsumerManagementStage ConsumerManagementStage::UnenrollmentRequested() { - return ConsumerManagementStage(UNENROLLMENT_REQUESTED); -} - -// static -ConsumerManagementStage ConsumerManagementStage::UnenrollmentSuccess() { - return ConsumerManagementStage(UNENROLLMENT_SUCCESS); -} - -// static -ConsumerManagementStage ConsumerManagementStage::UnenrollmentDMServerFailed() { - return ConsumerManagementStage(UNENROLLMENT_DM_SERVER_FAILED); -} - -// static -ConsumerManagementStage -ConsumerManagementStage::UnenrollmentUpdateDeviceSettingsFailed() { - return ConsumerManagementStage(UNENROLLMENT_UPDATE_DEVICE_SETTINGS_FAILED); -} - -bool ConsumerManagementStage::operator==( - const ConsumerManagementStage& other) const { - return value_ == other.value_; -} - -bool ConsumerManagementStage::HasPendingNotification() const { - return HasEnrollmentSucceeded() || - HasEnrollmentFailed() || - HasUnenrollmentSucceeded() || - HasUnenrollmentFailed(); -} - -bool ConsumerManagementStage::IsEnrolling() const { - return value_ == ENROLLMENT_REQUESTED || value_ == ENROLLMENT_OWNER_STORED; -} - -bool ConsumerManagementStage::IsEnrollmentRequested() const { - return value_ == ENROLLMENT_REQUESTED; -} - -bool ConsumerManagementStage::HasEnrollmentSucceeded() const { - return value_ == ENROLLMENT_SUCCESS; -} - -bool ConsumerManagementStage::HasEnrollmentFailed() const { - return value_ == ENROLLMENT_CANCELED || - value_ == ENROLLMENT_BOOT_LOCKBOX_FAILED || - value_ == ENROLLMENT_GET_TOKEN_FAILED || - value_ == ENROLLMENT_DM_SERVER_FAILED; -} - -bool ConsumerManagementStage::IsUnenrolling() const { - return value_ == UNENROLLMENT_REQUESTED; -} - -bool ConsumerManagementStage::HasUnenrollmentSucceeded() const { - return value_ == UNENROLLMENT_SUCCESS; -} - -bool ConsumerManagementStage::HasUnenrollmentFailed() const { - return value_ == UNENROLLMENT_DM_SERVER_FAILED || - value_ == UNENROLLMENT_UPDATE_DEVICE_SETTINGS_FAILED; -} - -// static -ConsumerManagementStage ConsumerManagementStage::FromInternalValue( - int int_value) { - ConsumerManagementStage::Value value = ConsumerManagementStage::NONE; - if (int_value >= ConsumerManagementStage::NONE && - int_value < ConsumerManagementStage::LAST) { - value = static_cast<ConsumerManagementStage::Value>(int_value); - } else { - LOG(ERROR) << "Unknown stage: " << int_value; - } - - return ConsumerManagementStage(value); -} - -int ConsumerManagementStage::ToInternalValue() const { - return static_cast<int>(value_); -} - -ConsumerManagementStage::ConsumerManagementStage(Value value) : value_(value) { -} - -} // namespace policy
diff --git a/chrome/browser/chromeos/policy/consumer_management_stage.h b/chrome/browser/chromeos/policy/consumer_management_stage.h deleted file mode 100644 index 4d374c4..0000000 --- a/chrome/browser/chromeos/policy/consumer_management_stage.h +++ /dev/null
@@ -1,120 +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_CHROMEOS_POLICY_CONSUMER_MANAGEMENT_STAGE_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_CONSUMER_MANAGEMENT_STAGE_H_ - -namespace policy { - -// The consumer management stage is a value indicating the current stage of the -// enrollment or the unenrollment process. This class has a bunch of methods -// that return a boolean based on the stage. The callers should use those -// methods instead of the internal value. -class ConsumerManagementStage { - public: - // The following static methods return objects for each stage. For each stage, - // one or more boolean member methods may return true. The methods which - // return true are documented in the parentheses for each stage. - // - // Nothing is going on. - static ConsumerManagementStage None(); - // Enrollment was requested by the owner. - // (IsEnrolling, IsEnrollmentRequested) - static ConsumerManagementStage EnrollmentRequested(); - // The owner ID was stored in the boot lockbox. - // (IsEnrolling) - static ConsumerManagementStage EnrollmentOwnerStored(); - // The enrollment process has succeeded. - // (HasPendingNotification, HasEnrollmentSucceeded) - static ConsumerManagementStage EnrollmentSuccess(); - // The enrollment process was canceled by the user. - // (HasPendingNotification, HasEnrollmentFailed) - static ConsumerManagementStage EnrollmentCanceled(); - // Failed to write to the boot lockbox. - // (HasPendingNotification, HasEnrollmentFailed) - static ConsumerManagementStage EnrollmentBootLockboxFailed(); - // Failed to get the access token. - // (HasPendingNotification, HasEnrollmentFailed) - static ConsumerManagementStage EnrollmentGetTokenFailed(); - // Failed to register the device. - // (HasPendingNotification, HasEnrollmentFailed) - static ConsumerManagementStage EnrollmentDMServerFailed(); - // Unenrollment was requested by the owner. - // (IsUnenrolling) - static ConsumerManagementStage UnenrollmentRequested(); - // The unenrollment process has succeeded. - // (HasPengindNotification, HasUnenrollmentSucceeded) - static ConsumerManagementStage UnenrollmentSuccess(); - // Failed to unregister the device. - // (HasPendingNotification, HasUnenrollmentFailed) - static ConsumerManagementStage UnenrollmentDMServerFailed(); - // Failed to update the device settings. - // (HasPendingNotification, HasUnenrollmentFailed) - static ConsumerManagementStage UnenrollmentUpdateDeviceSettingsFailed(); - - // Copyable. - ConsumerManagementStage(const ConsumerManagementStage& other) = default; - ConsumerManagementStage& operator=( - const ConsumerManagementStage& other) = default; - - bool operator==(const ConsumerManagementStage& other) const; - - // Returns true if there's a notification that should be shown. - bool HasPendingNotification() const; - - // Returns true if the enrollment process is in progress. - bool IsEnrolling() const; - - // Returns true if enrollment is requested. - bool IsEnrollmentRequested() const; - - // Returns true if the enrollment process succeeded. - bool HasEnrollmentSucceeded() const; - - // Returns true if the enrollment process failed. - bool HasEnrollmentFailed() const; - - // Returns true if the unenrollment process is in progress. - bool IsUnenrolling() const; - - // Returns true if the unenrollment process succeeded. - bool HasUnenrollmentSucceeded() const; - - // Returns true if the unenrollment process failed. - bool HasUnenrollmentFailed() const; - - // Returns an instance from an internal value. Returns |None()| if |int_value| - // is out of range. This should only be used in de-serialization. - static ConsumerManagementStage FromInternalValue(int int_value); - - // Returns the internal value. This should only be used in serialization. - int ToInternalValue() const; - - private: - // Note that the numerical values are stored in local state. They should never - // be changed. - enum Value { - NONE = 0, - ENROLLMENT_REQUESTED = 1, - ENROLLMENT_OWNER_STORED = 2, - ENROLLMENT_SUCCESS = 3, - ENROLLMENT_CANCELED = 4, - ENROLLMENT_BOOT_LOCKBOX_FAILED = 5, - ENROLLMENT_GET_TOKEN_FAILED = 6, - ENROLLMENT_DM_SERVER_FAILED = 7, - UNENROLLMENT_REQUESTED = 8, - UNENROLLMENT_SUCCESS = 9, - UNENROLLMENT_DM_SERVER_FAILED = 10, - UNENROLLMENT_UPDATE_DEVICE_SETTINGS_FAILED = 11, - LAST, // This should always be the last one. - }; - - explicit ConsumerManagementStage(Value value); - - Value value_; -}; - -} // namespace policy - -#endif // CHROME_BROWSER_CHROMEOS_POLICY_CONSUMER_MANAGEMENT_STAGE_H_
diff --git a/chrome/browser/chromeos/policy/consumer_unenrollment_handler.cc b/chrome/browser/chromeos/policy/consumer_unenrollment_handler.cc deleted file mode 100644 index c29df77..0000000 --- a/chrome/browser/chromeos/policy/consumer_unenrollment_handler.cc +++ /dev/null
@@ -1,78 +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/chromeos/policy/consumer_unenrollment_handler.h" - -#include "base/bind.h" -#include "base/logging.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos.h" -#include "chrome/browser/chromeos/policy/consumer_management_service.h" -#include "chrome/browser/chromeos/policy/consumer_management_stage.h" -#include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h" -#include "components/policy/core/common/cloud/cloud_policy_constants.h" -#include "policy/proto/device_management_backend.pb.h" - -namespace em = enterprise_management; - -namespace policy { - -ConsumerUnenrollmentHandler::ConsumerUnenrollmentHandler( - ConsumerManagementService* consumer_management_service, - DeviceCloudPolicyManagerChromeOS* device_cloud_policy_manager, - chromeos::OwnerSettingsServiceChromeOS* owner_settings_service) - : consumer_management_service_(consumer_management_service), - device_cloud_policy_manager_(device_cloud_policy_manager), - owner_settings_service_(owner_settings_service), - weak_factory_(this) {} - -ConsumerUnenrollmentHandler::~ConsumerUnenrollmentHandler() { -} - -void ConsumerUnenrollmentHandler::Start() { - if (consumer_management_service_->GetStatus() != - ConsumerManagementService::STATUS_ENROLLED) { - return; - } - - device_cloud_policy_manager_->Unregister( - base::Bind(&ConsumerUnenrollmentHandler::OnUnregistered, - weak_factory_.GetWeakPtr())); -} - -void ConsumerUnenrollmentHandler::OnUnregistered(bool success) { - if (!success) { - consumer_management_service_->SetStage( - ConsumerManagementStage::UnenrollmentDMServerFailed()); - LOG(ERROR) << "Failed to unregister and disconnect device cloud policy " - << "manager."; - return; - } - - - chromeos::OwnerSettingsServiceChromeOS::ManagementSettings settings; - settings.management_mode = MANAGEMENT_MODE_LOCAL_OWNER; - owner_settings_service_->SetManagementSettings( - settings, - base::Bind(&ConsumerUnenrollmentHandler::OnManagementSettingsSet, - weak_factory_.GetWeakPtr())); -} - -void ConsumerUnenrollmentHandler::OnManagementSettingsSet(bool success) { - if (!success) { - consumer_management_service_->SetStage( - ConsumerManagementStage::UnenrollmentUpdateDeviceSettingsFailed()); - LOG(ERROR) << "Failed to unset request token and device ID."; - return; - } - - consumer_management_service_->SetStage( - ConsumerManagementStage::UnenrollmentSuccess()); - - // Disconnecting the device cloud policy manager will restart the device - // cloud policy initializer. So this must be done after the management - // settings are updated, so that the initializer won't reconnect the manager. - device_cloud_policy_manager_->Disconnect(); -} - -} // namespace policy
diff --git a/chrome/browser/chromeos/policy/consumer_unenrollment_handler.h b/chrome/browser/chromeos/policy/consumer_unenrollment_handler.h deleted file mode 100644 index 79621c1..0000000 --- a/chrome/browser/chromeos/policy/consumer_unenrollment_handler.h +++ /dev/null
@@ -1,49 +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_CHROMEOS_POLICY_CONSUMER_UNENROLLMENT_HANDLER_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_CONSUMER_UNENROLLMENT_HANDLER_H_ - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "components/keyed_service/core/keyed_service.h" - -namespace chromeos { -class OwnerSettingsServiceChromeOS; -} - -namespace policy { - -class ConsumerManagementService; -class DeviceCloudPolicyManagerChromeOS; - -// ConsumerUnenrollmentHandler unenrolls the device from the consumer management -// service. It sends a request to the server and resets the management settings. -class ConsumerUnenrollmentHandler : public KeyedService { - public: - ConsumerUnenrollmentHandler( - ConsumerManagementService* consumer_management_service, - DeviceCloudPolicyManagerChromeOS* device_cloud_policy_manager, - chromeos::OwnerSettingsServiceChromeOS* owner_settings_service); - ~ConsumerUnenrollmentHandler() override; - - // Starts the unenrollment process. - void Start(); - - private: - void OnUnregistered(bool success); - void OnManagementSettingsSet(bool success); - - ConsumerManagementService* consumer_management_service_; - DeviceCloudPolicyManagerChromeOS* device_cloud_policy_manager_; - chromeos::OwnerSettingsServiceChromeOS* owner_settings_service_; - - base::WeakPtrFactory<ConsumerUnenrollmentHandler> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(ConsumerUnenrollmentHandler); -}; - -} // namespace policy - -#endif // CHROME_BROWSER_CHROMEOS_POLICY_CONSUMER_UNENROLLMENT_HANDLER_H_
diff --git a/chrome/browser/chromeos/policy/consumer_unenrollment_handler_factory.cc b/chrome/browser/chromeos/policy/consumer_unenrollment_handler_factory.cc deleted file mode 100644 index bb3e0ef3..0000000 --- a/chrome/browser/chromeos/policy/consumer_unenrollment_handler_factory.cc +++ /dev/null
@@ -1,51 +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/chromeos/policy/consumer_unenrollment_handler_factory.h" - -#include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part.h" -#include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" -#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/policy/consumer_unenrollment_handler.h" -#include "components/keyed_service/content/browser_context_dependency_manager.h" - -namespace policy { - -// static -ConsumerUnenrollmentHandler* -ConsumerUnenrollmentHandlerFactory::GetForBrowserContext( - content::BrowserContext* context) { - return static_cast<ConsumerUnenrollmentHandler*>( - GetInstance()->GetServiceForBrowserContext(context, true)); -} - -// static -ConsumerUnenrollmentHandlerFactory* -ConsumerUnenrollmentHandlerFactory::GetInstance() { - return base::Singleton<ConsumerUnenrollmentHandlerFactory>::get(); -} - -ConsumerUnenrollmentHandlerFactory::ConsumerUnenrollmentHandlerFactory() - : BrowserContextKeyedServiceFactory( - "ConsumerUnenrollmentHandler", - BrowserContextDependencyManager::GetInstance()) { - DependsOn(chromeos::OwnerSettingsServiceChromeOSFactory::GetInstance()); -} - -ConsumerUnenrollmentHandlerFactory::~ConsumerUnenrollmentHandlerFactory() { -} - -KeyedService* ConsumerUnenrollmentHandlerFactory::BuildServiceInstanceFor( - content::BrowserContext* context) const { - BrowserPolicyConnectorChromeOS* connector = - g_browser_process->platform_part()->browser_policy_connector_chromeos(); - return new ConsumerUnenrollmentHandler( - connector->GetConsumerManagementService(), - connector->GetDeviceCloudPolicyManager(), - chromeos::OwnerSettingsServiceChromeOSFactory::GetForBrowserContext( - context)); -} - -} // namespace policy
diff --git a/chrome/browser/chromeos/policy/consumer_unenrollment_handler_factory.h b/chrome/browser/chromeos/policy/consumer_unenrollment_handler_factory.h deleted file mode 100644 index c706eb3..0000000 --- a/chrome/browser/chromeos/policy/consumer_unenrollment_handler_factory.h +++ /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. - -#ifndef CHROME_BROWSER_CHROMEOS_POLICY_CONSUMER_UNENROLLMENT_HANDLER_FACTORY_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_CONSUMER_UNENROLLMENT_HANDLER_FACTORY_H_ - -#include "base/macros.h" -#include "base/memory/singleton.h" -#include "components/keyed_service/content/browser_context_keyed_service_factory.h" - -namespace policy { - -class ConsumerUnenrollmentHandler; - -class ConsumerUnenrollmentHandlerFactory - : public BrowserContextKeyedServiceFactory { - public: - static ConsumerUnenrollmentHandler* GetForBrowserContext( - content::BrowserContext* context); - - static ConsumerUnenrollmentHandlerFactory* GetInstance(); - - private: - friend struct base::DefaultSingletonTraits< - ConsumerUnenrollmentHandlerFactory>; - - ConsumerUnenrollmentHandlerFactory(); - ~ConsumerUnenrollmentHandlerFactory() override; - - KeyedService* BuildServiceInstanceFor( - content::BrowserContext* context) const override; - - DISALLOW_COPY_AND_ASSIGN(ConsumerUnenrollmentHandlerFactory); -}; - -} // namespace policy - -#endif // CHROME_BROWSER_CHROMEOS_POLICY_CONSUMER_UNENROLLMENT_HANDLER_FACTORY_H_
diff --git a/chrome/browser/chromeos/policy/consumer_unenrollment_handler_unittest.cc b/chrome/browser/chromeos/policy/consumer_unenrollment_handler_unittest.cc deleted file mode 100644 index dd3835ea..0000000 --- a/chrome/browser/chromeos/policy/consumer_unenrollment_handler_unittest.cc +++ /dev/null
@@ -1,127 +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/chromeos/policy/consumer_unenrollment_handler.h" - -#include <memory> -#include <utility> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/threading/thread_task_runner_handle.h" -#include "chrome/browser/chromeos/ownership/fake_owner_settings_service.h" -#include "chrome/browser/chromeos/policy/consumer_management_service.h" -#include "chrome/browser/chromeos/policy/consumer_management_stage.h" -#include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h" -#include "chrome/browser/chromeos/policy/enterprise_install_attributes.h" -#include "chrome/browser/chromeos/policy/fake_consumer_management_service.h" -#include "chrome/browser/chromeos/policy/fake_device_cloud_policy_manager.h" -#include "chrome/browser/chromeos/settings/device_settings_service.h" -#include "chrome/browser/chromeos/settings/device_settings_test_helper.h" -#include "chrome/test/base/testing_profile.h" -#include "chromeos/dbus/fake_cryptohome_client.h" -#include "components/ownership/mock_owner_key_util.h" -#include "policy/proto/device_management_backend.pb.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace policy { - -class ConsumerUnenrollmentHandlerTest - : public chromeos::DeviceSettingsTestBase { - public: - ConsumerUnenrollmentHandlerTest() - : fake_service_(new FakeConsumerManagementService()), - fake_cryptohome_client_(new chromeos::FakeCryptohomeClient()), - install_attributes_( - new EnterpriseInstallAttributes(fake_cryptohome_client_.get())) { - // Set up FakeConsumerManagementService. - fake_service_->SetStatusAndStage( - ConsumerManagementService::STATUS_ENROLLED, - ConsumerManagementStage::None()); - } - - void SetUp() override { - DeviceSettingsTestBase::SetUp(); - - // Set up the ownership, so that we can modify device settings. - owner_key_util_->SetPrivateKey(device_policy_.GetSigningKey()); - InitOwner(AccountId::FromUserEmail(device_policy_.policy_data().username()), - true); - FlushDeviceSettings(); - - - // Set up FakeDeviceCloudPolicyManager. - std::unique_ptr<DeviceCloudPolicyStoreChromeOS> store_( - new DeviceCloudPolicyStoreChromeOS( - &device_settings_service_, install_attributes_.get(), - base::ThreadTaskRunnerHandle::Get())); - fake_manager_.reset(new FakeDeviceCloudPolicyManager( - std::move(store_), base::ThreadTaskRunnerHandle::Get())); - - // Set up FakeOwnerSettingsService. - fake_owner_settings_service_.reset(new chromeos::FakeOwnerSettingsService( - profile_.get(), owner_key_util_, nullptr)); - chromeos::OwnerSettingsServiceChromeOS::ManagementSettings settings; - settings.management_mode = policy::MANAGEMENT_MODE_CONSUMER_MANAGED; - settings.request_token = "fake_request_token"; - settings.device_id = "fake_device_id"; - fake_owner_settings_service_->SetManagementSettings( - settings, - base::Bind(&ConsumerUnenrollmentHandlerTest::OnManagementSettingsSet, - base::Unretained(this))); - } - - void OnManagementSettingsSet(bool success) { - EXPECT_TRUE(success); - } - - void RunUnenrollment() { - handler_.reset(new ConsumerUnenrollmentHandler( - fake_service_.get(), fake_manager_.get(), - fake_owner_settings_service_.get())); - handler_->Start(); - FlushDeviceSettings(); - } - - std::unique_ptr<FakeConsumerManagementService> fake_service_; - std::unique_ptr<chromeos::FakeCryptohomeClient> fake_cryptohome_client_; - std::unique_ptr<EnterpriseInstallAttributes> install_attributes_; - std::unique_ptr<FakeDeviceCloudPolicyManager> fake_manager_; - std::unique_ptr<chromeos::FakeOwnerSettingsService> - fake_owner_settings_service_; - - std::unique_ptr<ConsumerUnenrollmentHandler> handler_; -}; - -TEST_F(ConsumerUnenrollmentHandlerTest, UnenrollmentSucceeds) { - EXPECT_EQ(ConsumerManagementStage::None(), fake_service_->GetStage()); - - RunUnenrollment(); - - EXPECT_EQ(ConsumerManagementStage::UnenrollmentSuccess(), - fake_service_->GetStage()); - const chromeos::OwnerSettingsServiceChromeOS::ManagementSettings& settings = - fake_owner_settings_service_->last_settings(); - EXPECT_EQ(policy::MANAGEMENT_MODE_LOCAL_OWNER, settings.management_mode); - EXPECT_EQ("", settings.request_token); - EXPECT_EQ("", settings.device_id); -} - -TEST_F(ConsumerUnenrollmentHandlerTest, - UnenrollmentFailsOnServerError) { - EXPECT_EQ(ConsumerManagementStage::None(), fake_service_->GetStage()); - fake_manager_->set_unregister_result(false); - - RunUnenrollment(); - - EXPECT_EQ(ConsumerManagementStage::UnenrollmentDMServerFailed(), - fake_service_->GetStage()); - const chromeos::OwnerSettingsServiceChromeOS::ManagementSettings& settings = - fake_owner_settings_service_->last_settings(); - EXPECT_EQ(policy::MANAGEMENT_MODE_CONSUMER_MANAGED, settings.management_mode); - EXPECT_EQ("fake_request_token", settings.request_token); - EXPECT_EQ("fake_device_id", settings.device_id); -} - -} // namespace policy
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_initializer.cc b/chrome/browser/chromeos/policy/device_cloud_policy_initializer.cc index e841e0f..f3f0c9a 100644 --- a/chrome/browser/chromeos/policy/device_cloud_policy_initializer.cc +++ b/chrome/browser/chromeos/policy/device_cloud_policy_initializer.cc
@@ -52,7 +52,6 @@ DeviceCloudPolicyInitializer::DeviceCloudPolicyInitializer( PrefService* local_state, DeviceManagementService* enterprise_service, - DeviceManagementService* consumer_service, const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, EnterpriseInstallAttributes* install_attributes, ServerBackedStateKeysBroker* state_keys_broker, @@ -60,7 +59,6 @@ DeviceCloudPolicyManagerChromeOS* manager) : local_state_(local_state), enterprise_service_(enterprise_service), - consumer_service_(consumer_service), background_task_runner_(background_task_runner), install_attributes_(install_attributes), state_keys_broker_(state_keys_broker), @@ -95,9 +93,7 @@ } void DeviceCloudPolicyInitializer::StartEnrollment( - ManagementMode management_mode, DeviceManagementService* device_management_service, - chromeos::OwnerSettingsServiceChromeOS* owner_settings_service, const EnrollmentConfig& enrollment_config, const std::string& auth_token, const AllowedDeviceModes& allowed_device_modes, @@ -108,10 +104,9 @@ manager_->core()->Disconnect(); enrollment_handler_.reset(new EnrollmentHandlerChromeOS( device_store_, install_attributes_, state_keys_broker_, - owner_settings_service, CreateClient(device_management_service), - background_task_runner_, enrollment_config, auth_token, - install_attributes_->GetDeviceId(), manager_->GetDeviceRequisition(), - allowed_device_modes, management_mode, + CreateClient(device_management_service), background_task_runner_, + enrollment_config, auth_token, install_attributes_->GetDeviceId(), + manager_->GetDeviceRequisition(), allowed_device_modes, base::Bind(&DeviceCloudPolicyInitializer::EnrollmentCompleted, base::Unretained(this), enrollment_callback))); enrollment_handler_->StartEnrollment(); @@ -263,18 +258,7 @@ enrollment_handler_) { return; } - - DeviceManagementService* service = nullptr; - if (GetManagementMode(*device_store_->policy()) == - MANAGEMENT_MODE_CONSUMER_MANAGED) { - service = consumer_service_; - } else if (GetManagementMode(*device_store_->policy()) == - MANAGEMENT_MODE_ENTERPRISE_MANAGED) { - service = enterprise_service_; - } - - if (service) - StartConnection(CreateClient(service)); + StartConnection(CreateClient(enterprise_service_)); } void DeviceCloudPolicyInitializer::StartConnection(
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_initializer.h b/chrome/browser/chromeos/policy/device_cloud_policy_initializer.h index 926df112..146cafe 100644 --- a/chrome/browser/chromeos/policy/device_cloud_policy_initializer.h +++ b/chrome/browser/chromeos/policy/device_cloud_policy_initializer.h
@@ -24,10 +24,6 @@ class SequencedTaskRunner; } -namespace chromeos { -class OwnerSettingsServiceChromeOS; -} - namespace policy { class DeviceCloudPolicyManagerChromeOS; @@ -50,7 +46,6 @@ DeviceCloudPolicyInitializer( PrefService* local_state, DeviceManagementService* enterprise_service, - DeviceManagementService* consumer_service, const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, EnterpriseInstallAttributes* install_attributes, ServerBackedStateKeysBroker* state_keys_broker, @@ -67,12 +62,8 @@ // operation. // |allowed_modes| specifies acceptable DEVICE_MODE_* constants for // enrollment. - // |management_mode| should be either MANAGEMENT_MODE_ENTERPRISE or - // MANAGEMENT_MODE_CONSUMER. virtual void StartEnrollment( - ManagementMode management_mode, DeviceManagementService* device_management_service, - chromeos::OwnerSettingsServiceChromeOS* owner_settings_service, const EnrollmentConfig& enrollment_config, const std::string& auth_token, const AllowedDeviceModes& allowed_modes, @@ -107,7 +98,6 @@ PrefService* local_state_; DeviceManagementService* enterprise_service_; - DeviceManagementService* consumer_service_; scoped_refptr<base::SequencedTaskRunner> background_task_runner_; EnterpriseInstallAttributes* install_attributes_; ServerBackedStateKeysBroker* state_keys_broker_;
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_initializer_unittest.cc b/chrome/browser/chromeos/policy/device_cloud_policy_initializer_unittest.cc index 4a0f5cc..bf8a169c 100644 --- a/chrome/browser/chromeos/policy/device_cloud_policy_initializer_unittest.cc +++ b/chrome/browser/chromeos/policy/device_cloud_policy_initializer_unittest.cc
@@ -34,7 +34,6 @@ : device_cloud_policy_initializer_(&local_state_, nullptr, nullptr, - nullptr, &install_attributes_, nullptr, nullptr,
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc index ca3fab6..6168c19 100644 --- a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc +++ b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc
@@ -178,7 +178,6 @@ manager_->AddDeviceCloudPolicyManagerObserver(this); initializer_.reset(new DeviceCloudPolicyInitializer( &local_state_, &device_management_service_, - &consumer_device_management_service_, base::ThreadTaskRunnerHandle::Get(), install_attributes_.get(), &state_keys_broker_, store_, manager_.get())); initializer_->Init(); @@ -218,7 +217,6 @@ std::string url_fetcher_response_string_; TestingPrefServiceSimple local_state_; MockDeviceManagementService device_management_service_; - MockDeviceManagementService consumer_device_management_service_; chromeos::ScopedTestDeviceSettingsService test_device_settings_service_; chromeos::ScopedTestCrosSettings test_cros_settings_; chromeos::system::ScopedFakeStatisticsProvider fake_statistics_provider_; @@ -377,8 +375,7 @@ protected: DeviceCloudPolicyManagerChromeOSEnrollmentTest() - : management_mode_(MANAGEMENT_MODE_ENTERPRISE_MANAGED), - register_status_(DM_STATUS_SUCCESS), + : register_status_(DM_STATUS_SUCCESS), policy_fetch_status_(DM_STATUS_SUCCESS), robot_auth_fetch_status_(DM_STATUS_SUCCESS), store_result_(true), @@ -425,13 +422,10 @@ EXPECT_EQ(EnrollmentStatus::STATUS_SUCCESS, status_.status()); ASSERT_TRUE(manager_->core()->client()); EXPECT_TRUE(manager_->core()->client()->is_registered()); - - if (management_mode_ != MANAGEMENT_MODE_CONSUMER_MANAGED) { - EXPECT_EQ(DEVICE_MODE_ENTERPRISE, install_attributes_->GetMode()); - EXPECT_TRUE(store_->has_policy()); - EXPECT_TRUE(store_->is_managed()); - VerifyPolicyPopulated(); - } + EXPECT_EQ(DEVICE_MODE_ENTERPRISE, install_attributes_->GetMode()); + EXPECT_TRUE(store_->has_policy()); + EXPECT_TRUE(store_->is_managed()); + VerifyPolicyPopulated(); } void RunTest() { @@ -457,8 +451,7 @@ EnrollmentConfig enrollment_config; enrollment_config.mode = EnrollmentConfig::MODE_MANUAL; initializer_->StartEnrollment( - management_mode_, &device_management_service_, owner_settings_service, - enrollment_config, "auth token", modes, + &device_management_service_, enrollment_config, "auth token", modes, base::Bind(&DeviceCloudPolicyManagerChromeOSEnrollmentTest::Done, base::Unretained(this))); base::RunLoop().RunUntilIdle(); @@ -537,10 +530,7 @@ url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); } - if (management_mode_ == MANAGEMENT_MODE_CONSUMER_MANAGED) - FlushDeviceSettings(); - else - base::RunLoop().RunUntilIdle(); + base::RunLoop().RunUntilIdle(); if (done_) return; @@ -567,8 +557,6 @@ ReloadDeviceSettings(); } - ManagementMode management_mode_; - DeviceManagementStatus register_status_; em::DeviceManagementResponse register_response_; @@ -680,23 +668,6 @@ status_.store_status()); } -TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, - SuccessfulConsumerManagementEnrollment) { - management_mode_ = MANAGEMENT_MODE_CONSUMER_MANAGED; - owner_key_util_->SetPrivateKey(device_policy_.GetNewSigningKey()); - InitOwner(AccountId::FromUserEmail(device_policy_.policy_data().username()), - true); - FlushDeviceSettings(); - - device_policy_.policy_data().set_management_mode(em::PolicyData::LOCAL_OWNER); - device_policy_.Build(); - device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob()); - ReloadDeviceSettings(); - - RunTest(); - ExpectSuccessfulEnrollment(); -} - TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, UnregisterSucceeds) { // Enroll first. RunTest();
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.cc b/chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.cc index 83c2d28..b6d05b8a 100644 --- a/chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.cc +++ b/chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.cc
@@ -61,7 +61,7 @@ true); validator->ValidateAgainstCurrentPolicy( device_settings_service_->policy_data(), - CloudPolicyValidatorBase::TIMESTAMP_REQUIRED, + CloudPolicyValidatorBase::TIMESTAMP_FULLY_VALIDATED, CloudPolicyValidatorBase::DM_TOKEN_REQUIRED); validator.release()->StartValidation( base::Bind(&DeviceCloudPolicyStoreChromeOS::OnPolicyToStoreValidated, @@ -144,20 +144,7 @@ device_settings_service_->status(); const bool is_enterprise_managed = install_attributes_->IsEnterpriseDevice(); - bool is_or_was_consumer_managed = false; - if (policy_data) { - const ManagementMode management_mode = GetManagementMode(*policy_data); - if (management_mode == MANAGEMENT_MODE_CONSUMER_MANAGED || - (management_mode == MANAGEMENT_MODE_LOCAL_OWNER && - policy() && - GetManagementMode(*policy()) == MANAGEMENT_MODE_CONSUMER_MANAGED)) { - // The device is consumer-managed, or was consumer-managed and is now - // unmanaged. - is_or_was_consumer_managed = true; - } - } - - if (!is_enterprise_managed && !is_or_was_consumer_managed) { + if (!is_enterprise_managed) { status_ = STATUS_BAD_STATE; NotifyStoreError(); return; @@ -166,41 +153,39 @@ // For enterprise devices, once per session, validate internal consistency of // enrollment state (DM token must be present on enrolled devices) and in case // of failure set flag to indicate that recovery is required. - if (is_enterprise_managed) { - switch (status) { - case chromeos::DeviceSettingsService::STORE_SUCCESS: - case chromeos::DeviceSettingsService::STORE_KEY_UNAVAILABLE: - case chromeos::DeviceSettingsService::STORE_NO_POLICY: - case chromeos::DeviceSettingsService::STORE_INVALID_POLICY: - case chromeos::DeviceSettingsService::STORE_VALIDATION_ERROR: { - if (!enrollment_validation_done_) { - enrollment_validation_done_ = true; - const bool has_dm_token = - status == chromeos::DeviceSettingsService::STORE_SUCCESS && - policy_data && - policy_data->has_request_token(); + switch (status) { + case chromeos::DeviceSettingsService::STORE_SUCCESS: + case chromeos::DeviceSettingsService::STORE_KEY_UNAVAILABLE: + case chromeos::DeviceSettingsService::STORE_NO_POLICY: + case chromeos::DeviceSettingsService::STORE_INVALID_POLICY: + case chromeos::DeviceSettingsService::STORE_VALIDATION_ERROR: { + if (!enrollment_validation_done_) { + enrollment_validation_done_ = true; + const bool has_dm_token = + status == chromeos::DeviceSettingsService::STORE_SUCCESS && + policy_data && + policy_data->has_request_token(); - // At the time LoginDisplayHostImpl decides whether enrollment flow is - // to be started, policy hasn't been read yet. To work around this, - // once the need for recovery is detected upon policy load, a flag is - // stored in prefs which is accessed by LoginDisplayHostImpl early - // during (next) boot. - if (!has_dm_token) { - LOG(ERROR) << "Device policy read on enrolled device yields " - << "no DM token! Status: " << status << "."; - chromeos::StartupUtils::MarkEnrollmentRecoveryRequired(); - } - UMA_HISTOGRAM_BOOLEAN("Enterprise.EnrolledPolicyHasDMToken", - has_dm_token); + // At the time LoginDisplayHostImpl decides whether enrollment flow is + // to be started, policy hasn't been read yet. To work around this, + // once the need for recovery is detected upon policy load, a flag is + // stored in prefs which is accessed by LoginDisplayHostImpl early + // during (next) boot. + if (!has_dm_token) { + LOG(ERROR) << "Device policy read on enrolled device yields " + << "no DM token! Status: " << status << "."; + chromeos::StartupUtils::MarkEnrollmentRecoveryRequired(); } - break; + UMA_HISTOGRAM_BOOLEAN("Enterprise.EnrolledPolicyHasDMToken", + has_dm_token); } - case chromeos::DeviceSettingsService::STORE_POLICY_ERROR: - case chromeos::DeviceSettingsService::STORE_OPERATION_FAILED: - case chromeos::DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR: - // Do nothing for write errors or transient read errors. - break; + break; } + case chromeos::DeviceSettingsService::STORE_POLICY_ERROR: + case chromeos::DeviceSettingsService::STORE_OPERATION_FAILED: + case chromeos::DeviceSettingsService::STORE_TEMP_VALIDATION_ERROR: + // Do nothing for write errors or transient read errors. + break; } switch (status) {
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos_unittest.cc b/chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos_unittest.cc index 0c85d8c..f51f96c 100644 --- a/chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos_unittest.cc +++ b/chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos_unittest.cc
@@ -71,16 +71,6 @@ ASSERT_EQ(EnterpriseInstallAttributes::LOCK_SUCCESS, result); } - void SetManagementModeAndLoad(em::PolicyData::ManagementMode mode) { - device_policy_.policy_data().set_management_mode(mode); - device_policy_.Build(); - device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob()); - device_settings_service_.Load(); - FlushDeviceSettings(); - EXPECT_EQ(chromeos::DeviceSettingsService::STORE_SUCCESS, - device_settings_service_.status()); - } - void ExpectFailure(CloudPolicyStore::Status expected_status) { EXPECT_EQ(expected_status, store_->status()); EXPECT_TRUE(store_->is_initialized()); @@ -88,17 +78,6 @@ EXPECT_FALSE(store_->is_managed()); } - void ExpectSuccessWithManagementMode(ManagementMode mode) { - EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); - EXPECT_TRUE(store_->is_initialized()); - EXPECT_TRUE(store_->has_policy()); - EXPECT_TRUE(store_->is_managed()); - EXPECT_TRUE(store_->policy()); - EXPECT_TRUE(store_->policy_map().empty()); - if (store_->policy()) - EXPECT_EQ(mode, GetManagementMode(*store_->policy())); - } - void ExpectSuccess() { EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); EXPECT_TRUE(store_->is_initialized()); @@ -176,17 +155,6 @@ ExpectSuccess(); } -TEST_F(DeviceCloudPolicyStoreChromeOSTest, UpdateFromServiceOnConsumerDevices) { - ResetToNonEnterprise(); - - SetManagementModeAndLoad(em::PolicyData::CONSUMER_MANAGED); - ExpectSuccessWithManagementMode(MANAGEMENT_MODE_CONSUMER_MANAGED); - - // Unenroll from consumer management. - SetManagementModeAndLoad(em::PolicyData::LOCAL_OWNER); - ExpectSuccessWithManagementMode(MANAGEMENT_MODE_LOCAL_OWNER); -} - TEST_F(DeviceCloudPolicyStoreChromeOSTest, StoreSuccess) { PrepareExistingPolicy(); store_->Store(device_policy_.policy());
diff --git a/chrome/browser/chromeos/policy/device_local_account_policy_service.cc b/chrome/browser/chromeos/policy/device_local_account_policy_service.cc index 0a5becf..27b29c9 100644 --- a/chrome/browser/chromeos/policy/device_local_account_policy_service.cc +++ b/chrome/browser/chromeos/policy/device_local_account_policy_service.cc
@@ -51,14 +51,16 @@ namespace { // Creates and initializes a cloud policy client. Returns nullptr if the device -// is not enterprise-enrolled. +// doesn't have credentials in device settings (i.e. is not +// enterprise-enrolled). std::unique_ptr<CloudPolicyClient> CreateClient( chromeos::DeviceSettingsService* device_settings_service, DeviceManagementService* device_management_service, scoped_refptr<net::URLRequestContextGetter> system_request_context) { const em::PolicyData* policy_data = device_settings_service->policy_data(); if (!policy_data || - GetManagementMode(*policy_data) != MANAGEMENT_MODE_ENTERPRISE_MANAGED || + !policy_data->has_request_token() || + !policy_data->has_device_id() || !device_management_service) { return std::unique_ptr<CloudPolicyClient>(); } @@ -89,7 +91,7 @@ for (base::FilePath path = enumerator.Next(); !path.empty(); path = enumerator.Next()) { const std::string subdirectory(path.BaseName().MaybeAsASCII()); - if (!ContainsKey(subdirectories_to_keep, subdirectory)) + if (!base::ContainsKey(subdirectories_to_keep, subdirectory)) base::DeleteFile(path, true); } }
diff --git a/chrome/browser/chromeos/policy/device_local_account_policy_store.cc b/chrome/browser/chromeos/policy/device_local_account_policy_store.cc index bcae8d7..033e5bb 100644 --- a/chrome/browser/chromeos/policy/device_local_account_policy_store.cc +++ b/chrome/browser/chromeos/policy/device_local_account_policy_store.cc
@@ -161,8 +161,8 @@ validator->ValidateAgainstCurrentPolicy( policy(), valid_timestamp_required - ? CloudPolicyValidatorBase::TIMESTAMP_REQUIRED - : CloudPolicyValidatorBase::TIMESTAMP_NOT_REQUIRED, + ? CloudPolicyValidatorBase::TIMESTAMP_FULLY_VALIDATED + : CloudPolicyValidatorBase::TIMESTAMP_NOT_VALIDATED, CloudPolicyValidatorBase::DM_TOKEN_NOT_REQUIRED); // Validate the DMToken to match what device policy has.
diff --git a/chrome/browser/chromeos/policy/enrollment_config.cc b/chrome/browser/chromeos/policy/enrollment_config.cc deleted file mode 100644 index bca5f4d62..0000000 --- a/chrome/browser/chromeos/policy/enrollment_config.cc +++ /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. - -#include "chrome/browser/chromeos/policy/enrollment_config.h" - -namespace policy { - -// TODO(drcrash): Initialize in declarations and get rid of constructor. -EnrollmentConfig::EnrollmentConfig() - : mode(MODE_NONE), - // TODO(drcrash): Change to best available once ZTE is everywhere. - auth_mechanism(AUTH_MECHANISM_INTERACTIVE) {} - -} // namespace policy
diff --git a/chrome/browser/chromeos/policy/enrollment_config.h b/chrome/browser/chromeos/policy/enrollment_config.h index 1c36fee8..03788c1 100644 --- a/chrome/browser/chromeos/policy/enrollment_config.h +++ b/chrome/browser/chromeos/policy/enrollment_config.h
@@ -49,9 +49,6 @@ AUTH_MECHANISM_BEST_AVAILABLE, }; - // Initializes |mode| to MODE_NONE and |management_domain| to empty string. - EnrollmentConfig(); - // Whether enrollment should be triggered. bool should_enroll() const { return mode != MODE_NONE; } @@ -63,7 +60,7 @@ } // Indicates the enrollment flow variant to trigger during OOBE. - Mode mode; + Mode mode = MODE_NONE; // The domain to enroll the device to, if applicable. If this is not set, the // device may be enrolled to any domain. Note that for the case where the @@ -75,7 +72,8 @@ std::string management_domain; // The authentication mechanism to use. - AuthMechanism auth_mechanism; + // TODO(drcrash): Change to best available once ZTE is everywhere. + AuthMechanism auth_mechanism = AUTH_MECHANISM_INTERACTIVE; }; } // namespace policy
diff --git a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc index c2cc9645..bc030841 100644 --- a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc +++ b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.cc
@@ -67,7 +67,6 @@ DeviceCloudPolicyStoreChromeOS* store, EnterpriseInstallAttributes* install_attributes, ServerBackedStateKeysBroker* state_keys_broker, - chromeos::OwnerSettingsServiceChromeOS* owner_settings_service, std::unique_ptr<CloudPolicyClient> client, scoped_refptr<base::SequencedTaskRunner> background_task_runner, const EnrollmentConfig& enrollment_config, @@ -75,12 +74,10 @@ const std::string& client_id, const std::string& requisition, const AllowedDeviceModes& allowed_device_modes, - ManagementMode management_mode, const EnrollmentCallback& completion_callback) : store_(store), install_attributes_(install_attributes), state_keys_broker_(state_keys_broker), - owner_settings_service_(owner_settings_service), client_(std::move(client)), background_task_runner_(background_task_runner), enrollment_config_(enrollment_config), @@ -88,7 +85,6 @@ client_id_(client_id), requisition_(requisition), allowed_device_modes_(allowed_device_modes), - management_mode_(management_mode), completion_callback_(completion_callback), device_mode_(DEVICE_MODE_NOT_SET), skip_robot_auth_(false), @@ -97,8 +93,6 @@ weak_ptr_factory_(this) { CHECK(!client_->is_registered()); CHECK_EQ(DM_STATUS_SUCCESS, client_->status()); - CHECK(management_mode_ == MANAGEMENT_MODE_ENTERPRISE_MANAGED || - management_mode_ == MANAGEMENT_MODE_CONSUMER_MANAGED); store_->AddObserver(this); client_->AddObserver(this); client_->AddPolicyTypeToFetch(dm_protocol::kChromeDevicePolicyType, @@ -144,8 +138,9 @@ new em::PolicyFetchResponse(*policy)), background_task_runner_)); - validator->ValidateTimestamp(base::Time(), base::Time::NowFromSystemTime(), - CloudPolicyValidatorBase::TIMESTAMP_REQUIRED); + validator->ValidateTimestamp( + base::Time(), base::Time::NowFromSystemTime(), + CloudPolicyValidatorBase::TIMESTAMP_FULLY_VALIDATED); // If this is re-enrollment, make sure that the new policy matches the // previously-enrolled domain. @@ -158,23 +153,12 @@ CloudPolicyValidatorBase::DM_TOKEN_REQUIRED); validator->ValidatePolicyType(dm_protocol::kChromeDevicePolicyType); validator->ValidatePayload(); - if (management_mode_ == MANAGEMENT_MODE_CONSUMER_MANAGED) { - // For consumer-managed devices, although we don't store the policy, we - // still need to verify its integrity since we use the request token in it. - // The consumer device management server does not have the verification - // key, and we need to skip checking on that by passing an empty key to - // ValidateInitialKey(). ValidateInitialKey() still checks that the policy - // data is correctly signed by the new public key when the verification key - // is empty. - validator->ValidateInitialKey(std::string(), std::string()); - } else { - // If |domain| is empty here, the policy validation code will just use the - // domain from the username field in the policy itself to do key validation. - // TODO(mnissler): Plumb the enrolling user's username into this object so - // we can validate the username on the resulting policy, and use the domain - // from that username to validate the key below (http://crbug.com/343074). - validator->ValidateInitialKey(GetPolicyVerificationKey(), domain); - } + // If |domain| is empty here, the policy validation code will just use the + // domain from the username field in the policy itself to do key validation. + // TODO(mnissler): Plumb the enrolling user's username into this object so we + // can validate the username on the resulting policy, and use the domain from + // that username to validate the key below (http://crbug.com/343074). + validator->ValidateInitialKey(GetPolicyVerificationKey(), domain); validator.release()->StartValidation( base::Bind(&EnrollmentHandlerChromeOS::HandlePolicyValidationResult, weak_ptr_factory_.GetWeakPtr())); @@ -369,26 +353,10 @@ // Since this method is also called directly. weak_ptr_factory_.InvalidateWeakPtrs(); - if (management_mode_ == MANAGEMENT_MODE_CONSUMER_MANAGED) { - CHECK(owner_settings_service_); - - // Consumer device enrollment doesn't use install attributes. Instead, - // we put the information in the owners settings. - enrollment_step_ = STEP_STORE_TOKEN_AND_ID; - chromeos::OwnerSettingsServiceChromeOS::ManagementSettings settings; - settings.management_mode = management_mode_; - settings.request_token = request_token_; - settings.device_id = device_id_; - owner_settings_service_->SetManagementSettings( - settings, - base::Bind(&EnrollmentHandlerChromeOS::HandleSetManagementSettingsDone, - weak_ptr_factory_.GetWeakPtr())); - } else { - install_attributes_->LockDevice( - username_, device_mode_, device_id_, - base::Bind(&EnrollmentHandlerChromeOS::HandleLockDeviceResult, - weak_ptr_factory_.GetWeakPtr())); - } + install_attributes_->LockDevice( + username_, device_mode_, device_id_, + base::Bind(&EnrollmentHandlerChromeOS::HandleLockDeviceResult, + weak_ptr_factory_.GetWeakPtr())); } void EnrollmentHandlerChromeOS::HandleSetManagementSettingsDone(bool success) { @@ -463,12 +431,6 @@ return; } - if (management_mode_ == MANAGEMENT_MODE_CONSUMER_MANAGED) { - // For consumer management enrollment, we don't store the policy. - ReportResult(EnrollmentStatus::ForStatus(EnrollmentStatus::STATUS_SUCCESS)); - return; - } - enrollment_step_ = STEP_STORE_POLICY; store_->InstallInitialPolicy(*policy_); }
diff --git a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.h b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.h index a21d93b..3a39f9f 100644 --- a/chrome/browser/chromeos/policy/enrollment_handler_chromeos.h +++ b/chrome/browser/chromeos/policy/enrollment_handler_chromeos.h
@@ -26,10 +26,6 @@ class SequencedTaskRunner; } -namespace chromeos { -class OwnerSettingsServiceChromeOS; -} - namespace policy { class DeviceCloudPolicyStoreChromeOS; @@ -60,12 +56,10 @@ // are acceptable. If the mode specified by the server is not acceptable, // enrollment will fail with an EnrollmentStatus indicating // STATUS_REGISTRATION_BAD_MODE. - // |management_mode| should be either ENTERPRISE_MANAGED or CONSUMER_MANAGED. EnrollmentHandlerChromeOS( DeviceCloudPolicyStoreChromeOS* store, EnterpriseInstallAttributes* install_attributes, ServerBackedStateKeysBroker* state_keys_broker, - chromeos::OwnerSettingsServiceChromeOS* owner_settings_service, std::unique_ptr<CloudPolicyClient> client, scoped_refptr<base::SequencedTaskRunner> background_task_runner, const EnrollmentConfig& enrollment_config, @@ -73,7 +67,6 @@ const std::string& client_id, const std::string& requisition, const AllowedDeviceModes& allowed_device_modes, - ManagementMode management_mode, const EnrollmentCallback& completion_callback); ~EnrollmentHandlerChromeOS() override; @@ -160,7 +153,6 @@ DeviceCloudPolicyStoreChromeOS* store_; EnterpriseInstallAttributes* install_attributes_; ServerBackedStateKeysBroker* state_keys_broker_; - chromeos::OwnerSettingsServiceChromeOS* owner_settings_service_; std::unique_ptr<CloudPolicyClient> client_; scoped_refptr<base::SequencedTaskRunner> background_task_runner_; std::unique_ptr<gaia::GaiaOAuthClient> gaia_oauth_client_; @@ -170,7 +162,6 @@ std::string client_id_; std::string requisition_; AllowedDeviceModes allowed_device_modes_; - ManagementMode management_mode_; EnrollmentCallback completion_callback_; // The current state key provided by |state_keys_broker_|.
diff --git a/chrome/browser/chromeos/policy/fake_consumer_management_service.cc b/chrome/browser/chromeos/policy/fake_consumer_management_service.cc deleted file mode 100644 index 0e9d13e..0000000 --- a/chrome/browser/chromeos/policy/fake_consumer_management_service.cc +++ /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. - -#include "chrome/browser/chromeos/policy/fake_consumer_management_service.h" - -namespace policy { - -FakeConsumerManagementService::FakeConsumerManagementService() - : ConsumerManagementService(NULL, NULL), - status_(STATUS_UNKNOWN), - stage_(ConsumerManagementStage::None()) { -} - -FakeConsumerManagementService::~FakeConsumerManagementService() { -} - -void FakeConsumerManagementService::SetStatusAndStage( - Status status, const ConsumerManagementStage& stage) { - status_ = status; - SetStage(stage); -} - -ConsumerManagementService::Status -FakeConsumerManagementService::GetStatus() const { - return status_; -} - -ConsumerManagementStage FakeConsumerManagementService::GetStage() const { - return stage_; -} - -void FakeConsumerManagementService::SetStage( - const ConsumerManagementStage& stage) { - stage_ = stage; - NotifyStatusChanged(); -} - -} // namespace policy
diff --git a/chrome/browser/chromeos/policy/fake_consumer_management_service.h b/chrome/browser/chromeos/policy/fake_consumer_management_service.h deleted file mode 100644 index fdd588e..0000000 --- a/chrome/browser/chromeos/policy/fake_consumer_management_service.h +++ /dev/null
@@ -1,36 +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_CHROMEOS_POLICY_FAKE_CONSUMER_MANAGEMENT_SERVICE_H_ -#define CHROME_BROWSER_CHROMEOS_POLICY_FAKE_CONSUMER_MANAGEMENT_SERVICE_H_ - -#include "base/macros.h" -#include "chrome/browser/chromeos/policy/consumer_management_service.h" -#include "chrome/browser/chromeos/policy/consumer_management_stage.h" - -namespace policy { - -class FakeConsumerManagementService : public ConsumerManagementService { - public: - FakeConsumerManagementService(); - ~FakeConsumerManagementService() override; - - // Set both status and stage. - void SetStatusAndStage(Status status, const ConsumerManagementStage& stage); - - // ConsumerManagementServcie: - Status GetStatus() const override; - ConsumerManagementStage GetStage() const override; - void SetStage(const ConsumerManagementStage& stage) override; - - private: - Status status_; - ConsumerManagementStage stage_; - - DISALLOW_COPY_AND_ASSIGN(FakeConsumerManagementService); -}; - -} // namespace policy - -#endif // CHROME_BROWSER_CHROMEOS_POLICY_FAKE_CONSUMER_MANAGEMENT_SERVICE_H_
diff --git a/chrome/browser/chromeos/policy/fake_device_cloud_policy_initializer.cc b/chrome/browser/chromeos/policy/fake_device_cloud_policy_initializer.cc index 700cdd4..550d3e5 100644 --- a/chrome/browser/chromeos/policy/fake_device_cloud_policy_initializer.cc +++ b/chrome/browser/chromeos/policy/fake_device_cloud_policy_initializer.cc
@@ -14,7 +14,6 @@ : DeviceCloudPolicyInitializer( NULL, // local_state NULL, // enterprise_service - NULL, // consumer_service // background_task_runner scoped_refptr<base::SequencedTaskRunner>(NULL), NULL, // install_attributes @@ -33,9 +32,7 @@ } void FakeDeviceCloudPolicyInitializer::StartEnrollment( - ManagementMode management_mode, DeviceManagementService* device_management_service, - chromeos::OwnerSettingsServiceChromeOS* owner_settings_service, const EnrollmentConfig& enrollment_config, const std::string& auth_token, const AllowedDeviceModes& allowed_modes,
diff --git a/chrome/browser/chromeos/policy/fake_device_cloud_policy_initializer.h b/chrome/browser/chromeos/policy/fake_device_cloud_policy_initializer.h index 179048f2..9824e4d 100644 --- a/chrome/browser/chromeos/policy/fake_device_cloud_policy_initializer.h +++ b/chrome/browser/chromeos/policy/fake_device_cloud_policy_initializer.h
@@ -25,9 +25,7 @@ void Shutdown() override; void StartEnrollment( - ManagementMode management_mode, DeviceManagementService* device_management_service, - chromeos::OwnerSettingsServiceChromeOS* owner_settings_service, const EnrollmentConfig& enrollment_config, const std::string& auth_token, const AllowedDeviceModes& allowed_modes,
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc b/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc index 24710c4..4179165 100644 --- a/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc +++ b/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc
@@ -272,7 +272,7 @@ std::unique_ptr<em::PolicyFetchResponse> policy) { // Create and configure a validator. std::unique_ptr<UserCloudPolicyValidator> validator = CreateValidator( - std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_REQUIRED); + std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_FULLY_VALIDATED); validator->ValidateUsername(account_id_.GetUserEmail(), true); if (policy_key_.empty()) { validator->ValidateInitialKey(GetPolicyVerificationKey(), @@ -421,7 +421,7 @@ // Create and configure a validator for the loaded legacy policy. Note that // the signature on this policy is not verified. std::unique_ptr<UserCloudPolicyValidator> validator = CreateValidator( - std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_REQUIRED); + std::move(policy), CloudPolicyValidatorBase::TIMESTAMP_FULLY_VALIDATED); validator->ValidateUsername(account_id_.GetUserEmail(), true); validator.release()->StartValidation( base::Bind(&UserCloudPolicyStoreChromeOS::OnLegacyPolicyValidated,
diff --git a/chrome/browser/chromeos/settings/cros_settings.cc b/chrome/browser/chromeos/settings/cros_settings.cc index 9484c4ed..c0d7f889 100644 --- a/chrome/browser/chromeos/settings/cros_settings.cc +++ b/chrome/browser/chromeos/settings/cros_settings.cc
@@ -83,8 +83,8 @@ } CrosSettings::~CrosSettings() { - STLDeleteElements(&providers_); - STLDeleteValues(&settings_observers_); + base::STLDeleteElements(&providers_); + base::STLDeleteValues(&settings_observers_); } bool CrosSettings::IsCrosSettings(const std::string& path) {
diff --git a/chrome/browser/chromeos/settings/cros_settings_unittest.cc b/chrome/browser/chromeos/settings/cros_settings_unittest.cc index 9fb676c8..a7897d7 100644 --- a/chrome/browser/chromeos/settings/cros_settings_unittest.cc +++ b/chrome/browser/chromeos/settings/cros_settings_unittest.cc
@@ -40,7 +40,7 @@ void TearDown() override { ASSERT_TRUE(expected_props_.empty()); - STLDeleteValues(&expected_props_); + base::STLDeleteValues(&expected_props_); } void FetchPref(const std::string& pref) {
diff --git a/chrome/browser/chromeos/settings/device_settings_provider.cc b/chrome/browser/chromeos/settings/device_settings_provider.cc index 031449c..f91b2cc 100644 --- a/chrome/browser/chromeos/settings/device_settings_provider.cc +++ b/chrome/browser/chromeos/settings/device_settings_provider.cc
@@ -683,15 +683,9 @@ TrustedStatus trusted_status) { PrefValueMap new_values_cache; - // If the device is not managed, or is consumer-managed, we set the device - // owner value. - if (policy_data.has_username() && - (policy::GetManagementMode(policy_data) == - policy::MANAGEMENT_MODE_LOCAL_OWNER || - policy::GetManagementMode(policy_data) == - policy::MANAGEMENT_MODE_CONSUMER_MANAGED)) { + // If the device is not managed, we set the device owner value. + if (policy_data.has_username() && !policy_data.has_request_token()) new_values_cache.SetString(kDeviceOwner, policy_data.username()); - } if (policy_data.has_service_account_identity()) { new_values_cache.SetString(kServiceAccountIdentity,
diff --git a/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc b/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc index 1a13aa9..3ced026 100644 --- a/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc +++ b/chrome/browser/chromeos/settings/device_settings_provider_unittest.cc
@@ -410,25 +410,6 @@ EXPECT_TRUE(base::Value::Equals(&expected_accounts, actual_accounts)); } -TEST_F(DeviceSettingsProviderTest, OwnerIsStillSetWhenDeviceIsConsumerManaged) { - owner_key_util_->SetPrivateKey(device_policy_.GetSigningKey()); - InitOwner(AccountId::FromUserEmail(device_policy_.policy_data().username()), - true); - device_policy_.policy_data().set_management_mode( - em::PolicyData::CONSUMER_MANAGED); - device_policy_.policy_data().set_request_token("test request token"); - device_policy_.Build(); - device_settings_test_helper_.set_policy_blob(device_policy_.GetBlob()); - FlushDeviceSettings(); - - // Expect that kDeviceOwner is not empty. - const base::Value* value = provider_->Get(kDeviceOwner); - ASSERT_TRUE(value); - std::string string_value; - EXPECT_TRUE(value->GetAsString(&string_value)); - EXPECT_FALSE(string_value.empty()); -} - TEST_F(DeviceSettingsProviderTest, DecodeDeviceState) { EXPECT_CALL(*this, SettingChanged(_)).Times(AtLeast(1)); device_policy_.policy_data().mutable_device_state()->set_device_mode(
diff --git a/chrome/browser/chromeos/settings/session_manager_operation.cc b/chrome/browser/chromeos/settings/session_manager_operation.cc index 317bbcb..be2c7f6 100644 --- a/chrome/browser/chromeos/settings/session_manager_operation.cc +++ b/chrome/browser/chromeos/settings/session_manager_operation.cc
@@ -173,7 +173,7 @@ // server. validator->ValidateAgainstCurrentPolicy( policy_data_.get(), - policy::CloudPolicyValidatorBase::TIMESTAMP_NOT_REQUIRED, + policy::CloudPolicyValidatorBase::TIMESTAMP_NOT_VALIDATED, policy::CloudPolicyValidatorBase::DM_TOKEN_NOT_REQUIRED); validator->ValidatePolicyType(policy::dm_protocol::kChromeDevicePolicyType); validator->ValidatePayload();
diff --git a/chrome/browser/command_updater.cc b/chrome/browser/command_updater.cc index eae13ce04..e93a729 100644 --- a/chrome/browser/command_updater.cc +++ b/chrome/browser/command_updater.cc
@@ -25,7 +25,8 @@ } CommandUpdater::~CommandUpdater() { - STLDeleteContainerPairSecondPointers(commands_.begin(), commands_.end()); + base::STLDeleteContainerPairSecondPointers(commands_.begin(), + commands_.end()); } bool CommandUpdater::SupportsCommand(int id) const {
diff --git a/chrome/browser/component_updater/component_updater_prefs.cc b/chrome/browser/component_updater/component_updater_prefs.cc new file mode 100644 index 0000000..5a983dfb --- /dev/null +++ b/chrome/browser/component_updater/component_updater_prefs.cc
@@ -0,0 +1,17 @@ +// Copyright 2016 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/component_updater/component_updater_prefs.h" + +#include "chrome/browser/component_updater/recovery_component_installer.h" +#include "chrome/browser/component_updater/supervised_user_whitelist_installer.h" + +namespace component_updater { + +void RegisterPrefs(PrefRegistrySimple* registry) { + RegisterPrefsForRecoveryComponent(registry); + SupervisedUserWhitelistInstaller::RegisterPrefs(registry); +} + +} // namespace component_updater
diff --git a/chrome/browser/component_updater/component_updater_prefs.h b/chrome/browser/component_updater/component_updater_prefs.h new file mode 100644 index 0000000..4210d2c --- /dev/null +++ b/chrome/browser/component_updater/component_updater_prefs.h
@@ -0,0 +1,17 @@ +// Copyright 2016 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_COMPONENT_UPDATER_COMPONENT_UPDATER_PREFS_H_ +#define CHROME_BROWSER_COMPONENT_UPDATER_COMPONENT_UPDATER_PREFS_H_ + +class PrefRegistrySimple; + +namespace component_updater { + +// Registers local preferences related to the component updater. +void RegisterPrefs(PrefRegistrySimple* registry); + +} // namespace component_updater + +#endif // CHROME_BROWSER_COMPONENT_UPDATER_COMPONENT_UPDATER_PREFS_H_
diff --git a/chrome/browser/component_updater/sw_reporter_installer_win.cc b/chrome/browser/component_updater/sw_reporter_installer_win.cc index b9707718..9cfbb75 100644 --- a/chrome/browser/component_updater/sw_reporter_installer_win.cc +++ b/chrome/browser/component_updater/sw_reporter_installer_win.cc
@@ -130,9 +130,12 @@ const base::FilePath& install_dir, std::unique_ptr<base::DictionaryValue> manifest) override { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - safe_browsing::RunSwReporter(install_dir.Append(kSwReporterExeName), - version, base::ThreadTaskRunnerHandle::Get(), - base::WorkerPool::GetTaskRunner(true)); + content::BrowserThread::PostAfterStartupTask( + FROM_HERE, base::ThreadTaskRunnerHandle::Get(), + base::Bind(&safe_browsing::RunSwReporter, + install_dir.Append(kSwReporterExeName), version, + base::ThreadTaskRunnerHandle::Get(), + base::WorkerPool::GetTaskRunner(true))); } base::FilePath GetRelativeInstallDir() const override {
diff --git a/chrome/browser/content_settings/content_settings_browsertest.cc b/chrome/browser/content_settings/content_settings_browsertest.cc index dc8aa11..39ca7ad 100644 --- a/chrome/browser/content_settings/content_settings_browsertest.cc +++ b/chrome/browser/content_settings/content_settings_browsertest.cc
@@ -254,7 +254,6 @@ content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - MockWebContentsLoadFailObserver observer(web_contents); EXPECT_CALL(observer, DidFinishNavigation(IsErrorTooManyRedirects()));
diff --git a/chrome/browser/devtools/chrome_devtools_discovery_provider.cc b/chrome/browser/devtools/chrome_devtools_discovery_provider.cc index 7343c77..3535d6df 100644 --- a/chrome/browser/devtools/chrome_devtools_discovery_provider.cc +++ b/chrome/browser/devtools/chrome_devtools_discovery_provider.cc
@@ -36,7 +36,7 @@ std::vector<DevToolsTargetImpl*> list = DevToolsTargetImpl::EnumerateAll(); devtools_discovery::DevToolsTargetDescriptor::List result; result.reserve(list.size()); - for (const auto& descriptor : list) + for (auto* descriptor : list) result.push_back(descriptor); return result; }
diff --git a/chrome/browser/devtools/device/devtools_android_bridge.cc b/chrome/browser/devtools/device/devtools_android_bridge.cc index 8593912..43eb419 100644 --- a/chrome/browser/devtools/device/devtools_android_bridge.cc +++ b/chrome/browser/devtools/device/devtools_android_bridge.cc
@@ -527,10 +527,11 @@ void DevToolsAndroidBridge::RemotePageTarget::Inspect(Profile* profile) const { Activate(); - bool isWorker = remote_type_ == kTargetTypeWorker || - remote_type_ == kTargetTypeServiceWorker; + bool is_worker = remote_type_ == kTargetTypeWorker || + remote_type_ == kTargetTypeServiceWorker; + bool is_v8_only = remote_type_ == kTargetTypeNode; DevToolsWindow::OpenExternalFrontend(profile, frontend_url_, GetAgentHost(), - isWorker); + is_worker, is_v8_only); } bool DevToolsAndroidBridge::RemotePageTarget::Activate() const {
diff --git a/chrome/browser/devtools/device/port_forwarding_controller.cc b/chrome/browser/devtools/device/port_forwarding_controller.cc index e0adc9ce..062d731 100644 --- a/chrome/browser/devtools/device/port_forwarding_controller.cc +++ b/chrome/browser/devtools/device/port_forwarding_controller.cc
@@ -489,7 +489,7 @@ it != registry_.end(); ++it) { registry_copy.push_back(it->second); } - STLDeleteElements(®istry_copy); + base::STLDeleteElements(®istry_copy); } }
diff --git a/chrome/browser/devtools/device/tcp_device_provider.cc b/chrome/browser/devtools/device/tcp_device_provider.cc index 42ab000..ceb27b32 100644 --- a/chrome/browser/devtools/device/tcp_device_provider.cc +++ b/chrome/browser/devtools/device/tcp_device_provider.cc
@@ -82,7 +82,7 @@ std::vector<std::string> result; for (const net::HostPortPair& target : targets_) { const std::string& host = target.host(); - if (ContainsValue(result, host)) + if (base::ContainsValue(result, host)) continue; result.push_back(host); }
diff --git a/chrome/browser/devtools/devtools_file_watcher.cc b/chrome/browser/devtools/devtools_file_watcher.cc index b92f146..e5af5a5 100644 --- a/chrome/browser/devtools/devtools_file_watcher.cc +++ b/chrome/browser/devtools/devtools_file_watcher.cc
@@ -138,7 +138,7 @@ } pending_paths_.clear(); - for (auto watcher : listeners_) { + for (auto* watcher : listeners_) { BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(watcher->callback_, changed_paths)); }
diff --git a/chrome/browser/devtools/devtools_sanity_browsertest.cc b/chrome/browser/devtools/devtools_sanity_browsertest.cc index 3497bc5..be3a0b28 100644 --- a/chrome/browser/devtools/devtools_sanity_browsertest.cc +++ b/chrome/browser/devtools/devtools_sanity_browsertest.cc
@@ -819,7 +819,6 @@ // Tests that BeforeUnload event gets called on devtools that are opened // on another devtools. -// Disabled because of http://crbug.com/497857 IN_PROC_BROWSER_TEST_F(DevToolsBeforeUnloadTest, TestDevToolsOnDevTools) { ASSERT_TRUE(spawned_test_server()->Start());
diff --git a/chrome/browser/devtools/devtools_target_impl.cc b/chrome/browser/devtools/devtools_target_impl.cc index 13d0911..26921243 100644 --- a/chrome/browser/devtools/devtools_target_impl.cc +++ b/chrome/browser/devtools/devtools_target_impl.cc
@@ -34,6 +34,7 @@ const char DevToolsTargetImpl::kTargetTypeWorker[] = "worker"; const char DevToolsTargetImpl::kTargetTypeWebView[] = "webview"; const char DevToolsTargetImpl::kTargetTypeIFrame[] = "iframe"; +const char DevToolsTargetImpl::kTargetTypeNode[] = "node"; const char DevToolsTargetImpl::kTargetTypeOther[] = "other"; const char DevToolsTargetImpl::kTargetTypeServiceWorker[] = "service_worker";
diff --git a/chrome/browser/devtools/devtools_target_impl.h b/chrome/browser/devtools/devtools_target_impl.h index 984a0aa..6322a3a 100644 --- a/chrome/browser/devtools/devtools_target_impl.h +++ b/chrome/browser/devtools/devtools_target_impl.h
@@ -26,6 +26,7 @@ static const char kTargetTypeWorker[]; static const char kTargetTypeWebView[]; static const char kTargetTypeIFrame[]; + static const char kTargetTypeNode[]; static const char kTargetTypeOther[]; static const char kTargetTypeServiceWorker[];
diff --git a/chrome/browser/devtools/devtools_targets_ui.cc b/chrome/browser/devtools/devtools_targets_ui.cc index f88eaa0..a332096 100644 --- a/chrome/browser/devtools/devtools_targets_ui.cc +++ b/chrome/browser/devtools/devtools_targets_ui.cc
@@ -234,7 +234,7 @@ base::ListValue list_value; std::map<std::string, base::DictionaryValue*> id_to_descriptor; - STLDeleteValues(&targets_); + base::STLDeleteValues(&targets_); for (DevToolsTargetImpl* target : targets) { targets_[target->GetId()] = target; id_to_descriptor[target->GetId()] = Serialize(*target); @@ -324,7 +324,7 @@ void AdbTargetsUIHandler::DeviceListChanged( const DevToolsAndroidBridge::RemoteDevices& devices) { remote_browsers_.clear(); - STLDeleteValues(&targets_); + base::STLDeleteValues(&targets_); if (!android_bridge_) return; @@ -401,7 +401,7 @@ } DevToolsTargetsUIHandler::~DevToolsTargetsUIHandler() { - STLDeleteValues(&targets_); + base::STLDeleteValues(&targets_); } // static
diff --git a/chrome/browser/devtools/devtools_window.cc b/chrome/browser/devtools/devtools_window.cc index 5a3f23b..5708765a 100644 --- a/chrome/browser/devtools/devtools_window.cc +++ b/chrome/browser/devtools/devtools_window.cc
@@ -450,7 +450,7 @@ DevToolsWindow* DevToolsWindow::CreateDevToolsWindowForWorker( Profile* profile) { content::RecordAction(base::UserMetricsAction("DevTools_InspectWorker")); - return Create(profile, GURL(), NULL, true, std::string(), false, ""); + return Create(profile, GURL(), NULL, true, false, std::string(), false, ""); } // static @@ -473,8 +473,8 @@ const scoped_refptr<content::DevToolsAgentHost>& agent_host) { DevToolsWindow* window = FindDevToolsWindow(agent_host.get()); if (!window) { - window = DevToolsWindow::Create( - profile, GURL(), nullptr, false, std::string(), false, std::string()); + window = DevToolsWindow::Create(profile, GURL(), nullptr, false, false, + std::string(), false, std::string()); if (!window) return; window->bindings_->AttachTo(agent_host); @@ -503,10 +503,11 @@ Profile* profile, const std::string& frontend_url, const scoped_refptr<content::DevToolsAgentHost>& agent_host, - bool isWorker) { + bool is_worker, + bool is_v8_only) { DevToolsWindow* window = FindDevToolsWindow(agent_host.get()); if (!window) { - window = Create(profile, GURL(), nullptr, isWorker, + window = Create(profile, GURL(), nullptr, is_worker, is_v8_only, DevToolsUI::GetProxyURL(frontend_url).spec(), false, std::string()); if (!window) return; @@ -532,7 +533,7 @@ content::RecordAction( base::UserMetricsAction("DevTools_InspectRenderer")); window = Create(profile, GURL(), inspected_web_contents, - false, std::string(), true, settings); + false, false, std::string(), true, settings); if (!window) return; window->bindings_->AttachTo(agent.get()); @@ -782,6 +783,7 @@ const GURL& frontend_url, content::WebContents* inspected_web_contents, bool shared_worker_frontend, + bool v8_only_frontend, const std::string& remote_frontend, bool can_dock, const std::string& settings) { @@ -803,6 +805,7 @@ // Create WebContents with devtools. GURL url(GetDevToolsURL(profile, frontend_url, shared_worker_frontend, + v8_only_frontend, remote_frontend, can_dock)); std::unique_ptr<WebContents> main_web_contents( @@ -824,6 +827,7 @@ GURL DevToolsWindow::GetDevToolsURL(Profile* profile, const GURL& base_url, bool shared_worker_frontend, + bool v8_only_frontend, const std::string& remote_frontend, bool can_dock) { // Compatibility errors are encoded with data urls, pass them @@ -840,6 +844,8 @@ ((frontend_url.find("?") == std::string::npos) ? "?" : "&")); if (shared_worker_frontend) url_string += "&isSharedWorker=true"; + if (v8_only_frontend) + url_string += "&v8only=true"; if (remote_frontend.size()) { url_string += "&remoteFrontend=true"; } else {
diff --git a/chrome/browser/devtools/devtools_window.h b/chrome/browser/devtools/devtools_window.h index a32b4c9..5dc6221a 100644 --- a/chrome/browser/devtools/devtools_window.h +++ b/chrome/browser/devtools/devtools_window.h
@@ -103,7 +103,8 @@ Profile* profile, const std::string& frontend_uri, const scoped_refptr<content::DevToolsAgentHost>& agent_host, - bool isWorker); + bool is_worker, + bool is_v8_only); // Worker frontend is always undocked. static void OpenDevToolsWindowForWorker( @@ -247,12 +248,14 @@ const GURL& frontend_url, content::WebContents* inspected_web_contents, bool shared_worker_frontend, + bool v8_only_frontend, const std::string& remote_frontend, bool can_dock, const std::string& settings); static GURL GetDevToolsURL(Profile* profile, const GURL& base_url, bool shared_worker_frontend, + bool v8_only_frontend, const std::string& remote_frontend, bool can_dock);
diff --git a/chrome/browser/diagnostics/diagnostics_model.cc b/chrome/browser/diagnostics/diagnostics_model.cc index 4ad99e97..0fc085a 100644 --- a/chrome/browser/diagnostics/diagnostics_model.cc +++ b/chrome/browser/diagnostics/diagnostics_model.cc
@@ -50,7 +50,7 @@ public: DiagnosticsModelImpl() : tests_run_(0) {} - ~DiagnosticsModelImpl() override { STLDeleteElements(&tests_); } + ~DiagnosticsModelImpl() override { base::STLDeleteElements(&tests_); } int GetTestRunCount() const override { return tests_run_; }
diff --git a/chrome/browser/download/download_history_unittest.cc b/chrome/browser/download/download_history_unittest.cc index 761de7645..cbebd55 100644 --- a/chrome/browser/download/download_history_unittest.cc +++ b/chrome/browser/download/download_history_unittest.cc
@@ -191,7 +191,7 @@ history_(NULL), manager_observer_(NULL), download_created_index_(0) {} - ~DownloadHistoryTest() override { STLDeleteElements(&items_); } + ~DownloadHistoryTest() override { base::STLDeleteElements(&items_); } protected: void TearDown() override { download_history_.reset(); }
diff --git a/chrome/browser/download/download_path_reservation_tracker.cc b/chrome/browser/download/download_path_reservation_tracker.cc index 34fe46b..5add5db2 100644 --- a/chrome/browser/download/download_path_reservation_tracker.cc +++ b/chrome/browser/download/download_path_reservation_tracker.cc
@@ -289,7 +289,7 @@ void RevokeReservation(ReservationKey key) { DCHECK_CURRENTLY_ON(BrowserThread::FILE); DCHECK(g_reservation_map != NULL); - DCHECK(ContainsKey(*g_reservation_map, key)); + DCHECK(base::ContainsKey(*g_reservation_map, key)); g_reservation_map->erase(key); if (g_reservation_map->size() == 0) { // No more reservations. Delete map.
diff --git a/chrome/browser/download/download_query_unittest.cc b/chrome/browser/download/download_query_unittest.cc index 09ceabf..fbdbc00 100644 --- a/chrome/browser/download/download_query_unittest.cc +++ b/chrome/browser/download/download_query_unittest.cc
@@ -59,7 +59,7 @@ ~DownloadQueryTest() override {} - void TearDown() override { STLDeleteElements(&mocks_); } + void TearDown() override { base::STLDeleteElements(&mocks_); } void CreateMocks(int count) { for (int i = 0; i < count; ++i) {
diff --git a/chrome/browser/download/download_request_limiter.cc b/chrome/browser/download/download_request_limiter.cc index 17247d4..89ba925 100644 --- a/chrome/browser/download/download_request_limiter.cc +++ b/chrome/browser/download/download_request_limiter.cc
@@ -469,7 +469,7 @@ void DownloadRequestLimiter::Remove(TabDownloadState* state, content::WebContents* contents) { - DCHECK(ContainsKey(state_map_, contents)); + DCHECK(base::ContainsKey(state_map_, contents)); state_map_.erase(contents); delete state; }
diff --git a/chrome/browser/download/download_status_updater.cc b/chrome/browser/download/download_status_updater.cc index 3c876aa..221fb7f 100644 --- a/chrome/browser/download/download_status_updater.cc +++ b/chrome/browser/download/download_status_updater.cc
@@ -56,7 +56,7 @@ } DownloadStatusUpdater::~DownloadStatusUpdater() { - STLDeleteElements(¬ifiers_); + base::STLDeleteElements(¬ifiers_); } bool DownloadStatusUpdater::GetProgress(float* progress,
diff --git a/chrome/browser/download/download_status_updater_unittest.cc b/chrome/browser/download/download_status_updater_unittest.cc index ccfa800..63039622 100644 --- a/chrome/browser/download/download_status_updater_unittest.cc +++ b/chrome/browser/download/download_status_updater_unittest.cc
@@ -65,7 +65,7 @@ managers_.clear(); for (std::vector<Items>::iterator it = manager_items_.begin(); it != manager_items_.end(); ++it) - STLDeleteContainerPointers(it->begin(), it->end()); + base::STLDeleteContainerPointers(it->begin(), it->end()); base::RunLoop().RunUntilIdle(); // Allow DownloadManager destruction. }
diff --git a/chrome/browser/download/notification/download_notification_manager.h b/chrome/browser/download/notification/download_notification_manager.h index e164c08..3b45d86 100644 --- a/chrome/browser/download/notification/download_notification_manager.h +++ b/chrome/browser/download/notification/download_notification_manager.h
@@ -32,7 +32,8 @@ std::map<Profile*, DownloadNotificationManagerForProfile*> manager_for_profile_; - STLValueDeleter<std::map<Profile*, DownloadNotificationManagerForProfile*>> + base::STLValueDeleter< + std::map<Profile*, DownloadNotificationManagerForProfile*>> items_deleter_; }; @@ -69,7 +70,8 @@ // Pointer to the message center instance. message_center::MessageCenter* message_center_; - STLValueDeleter<std::map<content::DownloadItem*, DownloadItemNotification*>> + base::STLValueDeleter< + std::map<content::DownloadItem*, DownloadItemNotification*>> items_deleter_; };
diff --git a/chrome/browser/engagement/site_engagement_eviction_policy.cc b/chrome/browser/engagement/site_engagement_eviction_policy.cc index 869e072..7d52f56 100644 --- a/chrome/browser/engagement/site_engagement_eviction_policy.cc +++ b/chrome/browser/engagement/site_engagement_eviction_policy.cc
@@ -65,7 +65,7 @@ usage.second - GetSoftQuotaForOrigin(origin, score_provider->GetScore(origin), total_engagement_points, global_quota); - if (overuse > max_overuse && !ContainsKey(exceptions, origin)) { + if (overuse > max_overuse && !base::ContainsKey(exceptions, origin)) { max_overuse = overuse; origin_to_evict = origin; }
diff --git a/chrome/browser/extensions/api/content_settings/content_settings_store.cc b/chrome/browser/extensions/api/content_settings/content_settings_store.cc index 46ca488..b2e8c52 100644 --- a/chrome/browser/extensions/api/content_settings/content_settings_store.cc +++ b/chrome/browser/extensions/api/content_settings/content_settings_store.cc
@@ -52,7 +52,7 @@ } ContentSettingsStore::~ContentSettingsStore() { - STLDeleteValues(&entries_); + base::STLDeleteValues(&entries_); } std::unique_ptr<RuleIterator> ContentSettingsStore::GetRuleIterator(
diff --git a/chrome/browser/extensions/api/debugger/debugger_api.cc b/chrome/browser/extensions/api/debugger/debugger_api.cc index c3aa966..36e39db9 100644 --- a/chrome/browser/extensions/api/debugger/debugger_api.cc +++ b/chrome/browser/extensions/api/debugger/debugger_api.cc
@@ -728,7 +728,7 @@ std::unique_ptr<base::ListValue> result(new base::ListValue()); for (size_t i = 0; i < target_list.size(); ++i) result->Append(SerializeTarget(*target_list[i])); - STLDeleteContainerPointers(target_list.begin(), target_list.end()); + base::STLDeleteContainerPointers(target_list.begin(), target_list.end()); SetResult(std::move(result)); SendResponse(true); }
diff --git a/chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.cc b/chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.cc index 05fcde9e..ca4a994 100644 --- a/chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.cc +++ b/chrome/browser/extensions/api/declarative_content/chrome_content_rules_registry.cc
@@ -136,7 +136,7 @@ content::WebContents* contents, const content::LoadCommittedDetails& details, const content::FrameNavigateParams& params) { - if (ContainsKey(active_rules_, contents)) { + if (base::ContainsKey(active_rules_, contents)) { EvaluationScope evaluation_scope(this); for (const std::unique_ptr<ContentPredicateEvaluator>& evaluator : evaluators_) @@ -321,7 +321,7 @@ // Remove the ContentRule from active_rules_. for (auto& tab_rules_pair : active_rules_) { - if (ContainsKey(tab_rules_pair.second, rule)) { + if (base::ContainsKey(tab_rules_pair.second, rule)) { ContentAction::ApplyInfo apply_info = {rule->extension, browser_context(), tab_rules_pair.first, rule->priority}; @@ -363,14 +363,14 @@ void ChromeContentRulesRegistry::EvaluateConditionsForTab( content::WebContents* tab) { std::set<const ContentRule*> matching_rules = GetMatchingRules(tab); - if (matching_rules.empty() && !ContainsKey(active_rules_, tab)) + if (matching_rules.empty() && !base::ContainsKey(active_rules_, tab)) return; std::set<const ContentRule*>& prev_matching_rules = active_rules_[tab]; for (const ContentRule* rule : matching_rules) { ContentAction::ApplyInfo apply_info = {rule->extension, browser_context(), tab, rule->priority}; - if (!ContainsKey(prev_matching_rules, rule)) { + if (!base::ContainsKey(prev_matching_rules, rule)) { for (const std::unique_ptr<const ContentAction>& action : rule->actions) action->Apply(apply_info); } else { @@ -379,7 +379,7 @@ } } for (const ContentRule* rule : prev_matching_rules) { - if (!ContainsKey(matching_rules, rule)) { + if (!base::ContainsKey(matching_rules, rule)) { ContentAction::ApplyInfo apply_info = {rule->extension, browser_context(), tab, rule->priority}; for (const std::unique_ptr<const ContentAction>& action : rule->actions)
diff --git a/chrome/browser/extensions/api/declarative_content/declarative_content_css_condition_tracker.cc b/chrome/browser/extensions/api/declarative_content/declarative_content_css_condition_tracker.cc index 745b331c..82c25da 100644 --- a/chrome/browser/extensions/api/declarative_content/declarative_content_css_condition_tracker.cc +++ b/chrome/browser/extensions/api/declarative_content/declarative_content_css_condition_tracker.cc
@@ -234,7 +234,7 @@ content::WebContents* contents, const content::LoadCommittedDetails& details, const content::FrameNavigateParams& params) { - DCHECK(ContainsKey(per_web_contents_tracker_, contents)); + DCHECK(base::ContainsKey(per_web_contents_tracker_, contents)); per_web_contents_tracker_[contents]->OnWebContentsNavigation(details, params); } @@ -250,7 +250,7 @@ loc->second->matching_css_selectors(); for (const std::string& predicate_css_selector : typed_predicate->css_selectors()) { - if (!ContainsKey(matching_css_selectors, predicate_css_selector)) + if (!base::ContainsKey(matching_css_selectors, predicate_css_selector)) return false; } @@ -304,7 +304,7 @@ void DeclarativeContentCssConditionTracker::DeletePerWebContentsTracker( content::WebContents* contents) { - DCHECK(ContainsKey(per_web_contents_tracker_, contents)); + DCHECK(base::ContainsKey(per_web_contents_tracker_, contents)); per_web_contents_tracker_.erase(contents); }
diff --git a/chrome/browser/extensions/api/declarative_content/declarative_content_is_bookmarked_condition_tracker.cc b/chrome/browser/extensions/api/declarative_content/declarative_content_is_bookmarked_condition_tracker.cc index 879edc8..884a756 100644 --- a/chrome/browser/extensions/api/declarative_content/declarative_content_is_bookmarked_condition_tracker.cc +++ b/chrome/browser/extensions/api/declarative_content/declarative_content_is_bookmarked_condition_tracker.cc
@@ -110,7 +110,7 @@ void DeclarativeContentIsBookmarkedConditionTracker::PerWebContentsTracker:: BookmarkRemovedForUrls(const std::set<GURL>& urls) { - if (ContainsKey(urls, web_contents()->GetVisibleURL())) { + if (base::ContainsKey(urls, web_contents()->GetVisibleURL())) { is_url_bookmarked_ = false; request_evaluation_.Run(web_contents()); } @@ -202,7 +202,7 @@ content::WebContents* contents, const content::LoadCommittedDetails& details, const content::FrameNavigateParams& params) { - DCHECK(ContainsKey(per_web_contents_tracker_, contents)); + DCHECK(base::ContainsKey(per_web_contents_tracker_, contents)); per_web_contents_tracker_[contents]->UpdateState(true); } @@ -274,7 +274,7 @@ void DeclarativeContentIsBookmarkedConditionTracker::DeletePerWebContentsTracker( content::WebContents* contents) { - DCHECK(ContainsKey(per_web_contents_tracker_, contents)); + DCHECK(base::ContainsKey(per_web_contents_tracker_, contents)); per_web_contents_tracker_.erase(contents); }
diff --git a/chrome/browser/extensions/api/declarative_content/declarative_content_is_bookmarked_condition_tracker_unittest.cc b/chrome/browser/extensions/api/declarative_content/declarative_content_is_bookmarked_condition_tracker_unittest.cc index ae3295e8..44fcb66 100644 --- a/chrome/browser/extensions/api/declarative_content/declarative_content_is_bookmarked_condition_tracker_unittest.cc +++ b/chrome/browser/extensions/api/declarative_content/declarative_content_is_bookmarked_condition_tracker_unittest.cc
@@ -82,7 +82,7 @@ // ContentPredicateEvaluator::Delegate: void RequestEvaluation(content::WebContents* contents) override { - EXPECT_FALSE(ContainsKey(evaluation_requests_, contents)); + EXPECT_FALSE(base::ContainsKey(evaluation_requests_, contents)); evaluation_requests_.insert(contents); }
diff --git a/chrome/browser/extensions/api/declarative_content/declarative_content_page_url_condition_tracker.cc b/chrome/browser/extensions/api/declarative_content/declarative_content_page_url_condition_tracker.cc index 5866146..e6271fe 100644 --- a/chrome/browser/extensions/api/declarative_content/declarative_content_page_url_condition_tracker.cc +++ b/chrome/browser/extensions/api/declarative_content/declarative_content_page_url_condition_tracker.cc
@@ -194,7 +194,7 @@ content::WebContents* contents, const content::LoadCommittedDetails& details, const content::FrameNavigateParams& params) { - DCHECK(ContainsKey(per_web_contents_tracker_, contents)); + DCHECK(base::ContainsKey(per_web_contents_tracker_, contents)); per_web_contents_tracker_[contents]->UpdateMatchesForCurrentUrl(true); } @@ -208,8 +208,8 @@ DCHECK(loc != per_web_contents_tracker_.end()); const std::set<url_matcher::URLMatcherConditionSet::ID>& web_contents_id_matches = loc->second->matches(); - return ContainsKey(web_contents_id_matches, - typed_predicate->url_matcher_condition_set()->id()); + return base::ContainsKey(web_contents_id_matches, + typed_predicate->url_matcher_condition_set()->id()); } bool DeclarativeContentPageUrlConditionTracker::IsEmpty() const { @@ -218,7 +218,7 @@ void DeclarativeContentPageUrlConditionTracker::DeletePerWebContentsTracker( content::WebContents* contents) { - DCHECK(ContainsKey(per_web_contents_tracker_, contents)); + DCHECK(base::ContainsKey(per_web_contents_tracker_, contents)); per_web_contents_tracker_.erase(contents); }
diff --git a/chrome/browser/extensions/api/declarative_content/declarative_content_page_url_condition_tracker_unittest.cc b/chrome/browser/extensions/api/declarative_content/declarative_content_page_url_condition_tracker_unittest.cc index ef8dad9..a719121 100644 --- a/chrome/browser/extensions/api/declarative_content/declarative_content_page_url_condition_tracker_unittest.cc +++ b/chrome/browser/extensions/api/declarative_content/declarative_content_page_url_condition_tracker_unittest.cc
@@ -39,7 +39,7 @@ // ContentPredicateEvaluator::Delegate: void RequestEvaluation(content::WebContents* contents) override { - EXPECT_FALSE(ContainsKey(evaluation_requests_, contents)); + EXPECT_FALSE(base::ContainsKey(evaluation_requests_, contents)); evaluation_requests_.insert(contents); }
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc index ef9c1b2..96a375b 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc
@@ -288,8 +288,10 @@ for (std::set<const WebRequestRule*>::const_iterator it = matches.begin(); it != matches.end(); ++it) matches_ids.insert((*it)->id()); - EXPECT_TRUE(ContainsKey(matches_ids, std::make_pair(kExtensionId, kRuleId1))); - EXPECT_TRUE(ContainsKey(matches_ids, std::make_pair(kExtensionId, kRuleId2))); + EXPECT_TRUE( + base::ContainsKey(matches_ids, std::make_pair(kExtensionId, kRuleId1))); + EXPECT_TRUE( + base::ContainsKey(matches_ids, std::make_pair(kExtensionId, kRuleId2))); GURL foobar_url("http://www.foobar.com"); std::unique_ptr<net::URLRequest> foobar_request(
diff --git a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc index 1cc6c91e..3d8381b 100644 --- a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc +++ b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
@@ -95,12 +95,10 @@ registrar_.Remove(this, extensions::NOTIFICATION_EXTENSION_DOWNLOADS_EVENT, content::NotificationService::AllSources()); - STLDeleteElements(&events_); + base::STLDeleteElements(&events_); } - void ClearEvents() { - STLDeleteElements(&events_); - } + void ClearEvents() { base::STLDeleteElements(&events_); } class Event { public:
diff --git a/chrome/browser/extensions/api/gcd_private/privet_v3_session.cc b/chrome/browser/extensions/api/gcd_private/privet_v3_session.cc index 5dfa456..8c22f781 100644 --- a/chrome/browser/extensions/api/gcd_private/privet_v3_session.cc +++ b/chrome/browser/extensions/api/gcd_private/privet_v3_session.cc
@@ -356,8 +356,8 @@ } std::string auth_code(hmac.DigestLength(), ' '); - if (!hmac.Sign(session_id_, - reinterpret_cast<unsigned char*>(string_as_array(&auth_code)), + if (!hmac.Sign(session_id_, reinterpret_cast<unsigned char*>( + base::string_as_array(&auth_code)), auth_code.size())) { LOG(FATAL) << "Signing failed"; return callback.Run(Result::STATUS_SESSIONERROR);
diff --git a/chrome/browser/extensions/api/gcd_private/privet_v3_session_unittest.cc b/chrome/browser/extensions/api/gcd_private/privet_v3_session_unittest.cc index 77f6e2f..e60d8b00 100644 --- a/chrome/browser/extensions/api/gcd_private/privet_v3_session_unittest.cc +++ b/chrome/browser/extensions/api/gcd_private/privet_v3_session_unittest.cc
@@ -232,8 +232,9 @@ const std::string& key = spake.GetUnverifiedKey(); EXPECT_TRUE(hmac.Init(key)); std::string signature(hmac.DigestLength(), ' '); - EXPECT_TRUE(hmac.Sign(fingerprint, reinterpret_cast<unsigned char*>( - string_as_array(&signature)), + EXPECT_TRUE(hmac.Sign(fingerprint, + reinterpret_cast<unsigned char*>( + base::string_as_array(&signature)), signature.size())); std::string signature_base64;
diff --git a/chrome/browser/extensions/api/identity/identity_apitest.cc b/chrome/browser/extensions/api/identity/identity_apitest.cc index ed567e198..6a92142 100644 --- a/chrome/browser/extensions/api/identity/identity_apitest.cc +++ b/chrome/browser/extensions/api/identity/identity_apitest.cc
@@ -1570,8 +1570,8 @@ const ExtensionTokenKey* token_key = func->GetExtensionTokenKeyForTest(); EXPECT_EQ(2ul, token_key->scopes.size()); - EXPECT_TRUE(ContainsKey(token_key->scopes, "scope1")); - EXPECT_TRUE(ContainsKey(token_key->scopes, "scope2")); + EXPECT_TRUE(base::ContainsKey(token_key->scopes, "scope1")); + EXPECT_TRUE(base::ContainsKey(token_key->scopes, "scope2")); } IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, ScopesEmpty) { @@ -1599,7 +1599,7 @@ const ExtensionTokenKey* token_key = func->GetExtensionTokenKeyForTest(); EXPECT_EQ(1ul, token_key->scopes.size()); - EXPECT_TRUE(ContainsKey(token_key->scopes, "email")); + EXPECT_TRUE(base::ContainsKey(token_key->scopes, "email")); } IN_PROC_BROWSER_TEST_F(GetAuthTokenFunctionTest, ScopesEmailFooBar) { @@ -1616,9 +1616,9 @@ const ExtensionTokenKey* token_key = func->GetExtensionTokenKeyForTest(); EXPECT_EQ(3ul, token_key->scopes.size()); - EXPECT_TRUE(ContainsKey(token_key->scopes, "email")); - EXPECT_TRUE(ContainsKey(token_key->scopes, "foo")); - EXPECT_TRUE(ContainsKey(token_key->scopes, "bar")); + EXPECT_TRUE(base::ContainsKey(token_key->scopes, "email")); + EXPECT_TRUE(base::ContainsKey(token_key->scopes, "foo")); + EXPECT_TRUE(base::ContainsKey(token_key->scopes, "bar")); }
diff --git a/chrome/browser/extensions/api/identity/identity_mint_queue.cc b/chrome/browser/extensions/api/identity/identity_mint_queue.cc index ed8e899..74825eb17 100644 --- a/chrome/browser/extensions/api/identity/identity_mint_queue.cc +++ b/chrome/browser/extensions/api/identity/identity_mint_queue.cc
@@ -73,8 +73,8 @@ bool IdentityMintRequestQueue::empty(IdentityMintRequestQueue::MintType type, const ExtensionTokenKey& key) { RequestQueueMap& request_queue_map = GetRequestQueueMap(type); - return !ContainsKey(request_queue_map, key) || - (request_queue_map.find(key))->second.empty(); + return !base::ContainsKey(request_queue_map, key) || + (request_queue_map.find(key))->second.empty(); } IdentityMintRequestQueue::RequestQueueMap&
diff --git a/chrome/browser/extensions/api/management/management_browsertest.cc b/chrome/browser/extensions/api/management/management_browsertest.cc index d6a7c04..68d048f 100644 --- a/chrome/browser/extensions/api/management/management_browsertest.cc +++ b/chrome/browser/extensions/api/management/management_browsertest.cc
@@ -336,8 +336,8 @@ ASSERT_EQ("2.0", extension->VersionString()); ASSERT_TRUE(notification_listener.started()); ASSERT_TRUE(notification_listener.finished()); - ASSERT_TRUE(ContainsKey(notification_listener.updates(), - "ogjcoiohnmldgjemafoockdghcjciccf")); + ASSERT_TRUE(base::ContainsKey(notification_listener.updates(), + "ogjcoiohnmldgjemafoockdghcjciccf")); notification_listener.Reset(); // Now try doing an update to version 3, which has been incorrectly @@ -352,8 +352,8 @@ ASSERT_TRUE(WaitForExtensionInstallError()); ASSERT_TRUE(notification_listener.started()); ASSERT_TRUE(notification_listener.finished()); - ASSERT_TRUE(ContainsKey(notification_listener.updates(), - "ogjcoiohnmldgjemafoockdghcjciccf")); + ASSERT_TRUE(base::ContainsKey(notification_listener.updates(), + "ogjcoiohnmldgjemafoockdghcjciccf")); // Make sure the extension state is the same as before. ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); @@ -436,8 +436,8 @@ listener2.WaitUntilSatisfied(); ASSERT_TRUE(notification_listener.started()); ASSERT_TRUE(notification_listener.finished()); - ASSERT_TRUE(ContainsKey(notification_listener.updates(), - "ogjcoiohnmldgjemafoockdghcjciccf")); + ASSERT_TRUE(base::ContainsKey(notification_listener.updates(), + "ogjcoiohnmldgjemafoockdghcjciccf")); notification_listener.Reset(); }
diff --git a/chrome/browser/extensions/api/messaging/incognito_connectability.cc b/chrome/browser/extensions/api/messaging/incognito_connectability.cc index 5fcf618..f361ab58 100644 --- a/chrome/browser/extensions/api/messaging/incognito_connectability.cc +++ b/chrome/browser/extensions/api/messaging/incognito_connectability.cc
@@ -242,10 +242,10 @@ break; } - DCHECK(ContainsKey(pending_origins_, make_pair(extension_id, origin))); + DCHECK(base::ContainsKey(pending_origins_, make_pair(extension_id, origin))); PendingOrigin& pending_origin = pending_origins_[make_pair(extension_id, origin)]; - DCHECK(ContainsKey(pending_origin, infobar_manager)); + DCHECK(base::ContainsKey(pending_origin, infobar_manager)); std::vector<base::Callback<void(bool)>> callbacks; if (response == ScopedAlertTracker::INTERACTIVE) {
diff --git a/chrome/browser/extensions/api/messaging/message_service.cc b/chrome/browser/extensions/api/messaging/message_service.cc index 92af506..0f8d9d8 100644 --- a/chrome/browser/extensions/api/messaging/message_service.cc +++ b/chrome/browser/extensions/api/messaging/message_service.cc
@@ -233,7 +233,8 @@ MessageService::~MessageService() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); + base::STLDeleteContainerPairSecondPointers(channels_.begin(), + channels_.end()); channels_.clear(); } @@ -772,8 +773,9 @@ PendingMessage(source_port_id, message)); // A channel should only be holding pending messages because it is in one // of these states. - DCHECK(!ContainsKey(pending_tls_channel_id_channels_, channel_id)); - DCHECK(!ContainsKey(pending_lazy_background_page_channels_, channel_id)); + DCHECK(!base::ContainsKey(pending_tls_channel_id_channels_, channel_id)); + DCHECK( + !base::ContainsKey(pending_lazy_background_page_channels_, channel_id)); return; } PendingChannelMap::iterator pending_for_tls_channel_id = @@ -783,7 +785,8 @@ PendingMessage(source_port_id, message)); // A channel should only be holding pending messages because it is in one // of these states. - DCHECK(!ContainsKey(pending_lazy_background_page_channels_, channel_id)); + DCHECK( + !base::ContainsKey(pending_lazy_background_page_channels_, channel_id)); return; } EnqueuePendingMessageForLazyBackgroundLoad(source_port_id,
diff --git a/chrome/browser/extensions/api/platform_keys/verify_trust_api.cc b/chrome/browser/extensions/api/platform_keys/verify_trust_api.cc index be8ad64d..32fa2ef 100644 --- a/chrome/browser/extensions/api/platform_keys/verify_trust_api.cc +++ b/chrome/browser/extensions/api/platform_keys/verify_trust_api.cc
@@ -176,7 +176,7 @@ return; } - if (!ContainsKey(extension_to_verifier_, extension_id)) { + if (!base::ContainsKey(extension_to_verifier_, extension_id)) { extension_to_verifier_[extension_id] = make_linked_ptr(net::CertVerifier::CreateDefault().release()); }
diff --git a/chrome/browser/extensions/api/preference/preference_api.cc b/chrome/browser/extensions/api/preference/preference_api.cc index faafcae..4fe2c60 100644 --- a/chrome/browser/extensions/api/preference/preference_api.cc +++ b/chrome/browser/extensions/api/preference/preference_api.cc
@@ -132,6 +132,8 @@ APIPermission::kPrivacy, APIPermission::kPrivacy}, {"webRTCIPHandlingPolicy", prefs::kWebRTCIPHandlingPolicy, APIPermission::kPrivacy, APIPermission::kPrivacy}, + {"webRTCUDPPortRange", prefs::kWebRTCUDPPortRange, APIPermission::kPrivacy, + APIPermission::kPrivacy}, #endif // accessibilityFeatures.animationPolicy is available for // all platforms but the others from accessibilityFeatures @@ -298,8 +300,8 @@ } ~PrefMapping() { - STLDeleteContainerPairSecondPointers(transformers_.begin(), - transformers_.end()); + base::STLDeleteContainerPairSecondPointers(transformers_.begin(), + transformers_.end()); } void RegisterPrefTransformer(const std::string& browser_pref,
diff --git a/chrome/browser/extensions/api/sessions/sessions_apitest.cc b/chrome/browser/extensions/api/sessions/sessions_apitest.cc index 54a70c8..c60ebd8c 100644 --- a/chrome/browser/extensions/api/sessions/sessions_apitest.cc +++ b/chrome/browser/extensions/api/sessions/sessions_apitest.cc
@@ -31,8 +31,8 @@ #include "components/sync/api/fake_sync_change_processor.h" #include "components/sync/api/sync_error_factory_mock.h" #include "components/sync/core/attachments/attachment_service_proxy_for_test.h" -#include "components/sync_driver/local_device_info_provider_mock.h" -#include "components/sync_driver/sync_api_component_factory_mock.h" +#include "components/sync/driver/local_device_info_provider_mock.h" +#include "components/sync/driver/sync_api_component_factory_mock.h" #include "components/sync_sessions/sessions_sync_manager.h" #include "extensions/browser/api_test_utils.h"
diff --git a/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper.cc b/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper.cc index 726df26e..7b392ad 100644 --- a/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper.cc +++ b/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper.cc
@@ -13,7 +13,7 @@ #include "chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api.h" #include "chrome/browser/profiles/profile.h" #include "components/crx_file/id_util.h" -#include "components/sync_driver/device_info.h" +#include "components/sync/driver/device_info.h" using base::DictionaryValue; using base::Value;
diff --git a/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper_unittest.cc b/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper_unittest.cc index aa887edf..b8d00145 100644 --- a/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper_unittest.cc +++ b/chrome/browser/extensions/api/signed_in_devices/id_mapping_helper_unittest.cc
@@ -10,7 +10,7 @@ #include "base/guid.h" #include "base/memory/scoped_vector.h" #include "base/values.h" -#include "components/sync_driver/device_info.h" +#include "components/sync/driver/device_info.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api.cc b/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api.cc index 5145d00a..14b7f96 100644 --- a/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api.cc +++ b/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api.cc
@@ -14,8 +14,8 @@ #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/common/extensions/api/signed_in_devices.h" #include "components/browser_sync/browser/profile_sync_service.h" -#include "components/sync_driver/device_info_tracker.h" -#include "components/sync_driver/local_device_info_provider.h" +#include "components/sync/driver/device_info_tracker.h" +#include "components/sync/driver/local_device_info_provider.h" #include "extensions/browser/extension_prefs.h" using base::DictionaryValue;
diff --git a/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc b/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc index 66541ed5..8170b85 100644 --- a/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc +++ b/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_api_unittest.cc
@@ -19,8 +19,8 @@ #include "chrome/browser/sync/profile_sync_test_util.h" #include "components/browser_sync/browser/profile_sync_service_mock.h" #include "components/prefs/pref_service.h" -#include "components/sync_driver/device_info.h" -#include "components/sync_driver/device_info_tracker.h" +#include "components/sync/driver/device_info.h" +#include "components/sync/driver/device_info_tracker.h" #include "content/public/test/test_browser_thread_bundle.h" #include "extensions/common/extension.h" #include "testing/gmock/include/gmock/gmock.h"
diff --git a/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.cc b/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.cc index ecb7a82..aa96a66 100644 --- a/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.cc +++ b/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.cc
@@ -19,7 +19,7 @@ #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/common/extensions/api/signed_in_devices.h" #include "components/browser_sync/browser/profile_sync_service.h" -#include "components/sync_driver/device_info.h" +#include "components/sync/driver/device_info.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/extension.h"
diff --git a/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.h b/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.h index bc5cacb..050c51387 100644 --- a/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.h +++ b/chrome/browser/extensions/api/signed_in_devices/signed_in_devices_manager.h
@@ -11,7 +11,7 @@ #include "base/macros.h" #include "base/memory/scoped_vector.h" #include "base/scoped_observer.h" -#include "components/sync_driver/device_info_tracker.h" +#include "components/sync/driver/device_info_tracker.h" #include "extensions/browser/browser_context_keyed_api_factory.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_registry_observer.h"
diff --git a/chrome/browser/extensions/api/socket/tls_socket_unittest.cc b/chrome/browser/extensions/api/socket/tls_socket_unittest.cc index a305c948..812a99d 100644 --- a/chrome/browser/extensions/api/socket/tls_socket_unittest.cc +++ b/chrome/browser/extensions/api/socket/tls_socket_unittest.cc
@@ -17,6 +17,7 @@ #include "net/base/io_buffer.h" #include "net/base/net_errors.h" #include "net/base/rand_callback.h" +#include "net/socket/next_proto.h" #include "net/socket/ssl_client_socket.h" #include "net/socket/tcp_client_socket.h" #include "testing/gmock/include/gmock/gmock.h" @@ -55,6 +56,8 @@ MOCK_METHOD0(SetOmniboxSpeculation, void()); MOCK_CONST_METHOD0(WasEverUsed, bool()); MOCK_CONST_METHOD0(UsingTCPFastOpen, bool()); + MOCK_CONST_METHOD0(WasNpnNegotiated, bool()); + MOCK_CONST_METHOD0(GetNegotiatedProtocol, net::NextProto()); MOCK_METHOD1(GetSSLInfo, bool(net::SSLInfo*)); MOCK_CONST_METHOD1(GetConnectionAttempts, void(net::ConnectionAttempts*)); MOCK_METHOD0(ClearConnectionAttempts, void()); @@ -67,8 +70,6 @@ unsigned char*, unsigned int)); MOCK_METHOD1(GetSSLCertRequestInfo, void(net::SSLCertRequestInfo*)); - MOCK_CONST_METHOD1(GetNextProto, - net::SSLClientSocket::NextProtoStatus(std::string*)); MOCK_CONST_METHOD0(GetUnverifiedServerCertificateChain, scoped_refptr<net::X509Certificate>()); MOCK_CONST_METHOD0(GetChannelIDService, net::ChannelIDService*());
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc index c43670ac..cbced11e 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api.cc +++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -993,10 +993,15 @@ continue; } - // If tab_manager isn't present, then no tabs are discarded. - bool discarded = tab_manager && tab_manager->IsTabDiscarded(web_contents); - if (!MatchesBool(params->query_info.discarded.get(), discarded)) + if (!MatchesBool(params->query_info.discarded.get(), + tab_manager->IsTabDiscarded(web_contents))) { continue; + } + + if (!MatchesBool(params->query_info.auto_discardable.get(), + tab_manager->IsTabAutoDiscardable(web_contents))) { + continue; + } if (!MatchesBool(params->query_info.muted.get(), web_contents->IsAudioMuted())) { @@ -1336,6 +1341,12 @@ tab_strip->SetOpenerOfWebContentsAt(tab_index, opener_contents); } + if (params->update_properties.auto_discardable.get()) { + bool state = *params->update_properties.auto_discardable; + g_browser_process->GetTabManager()->SetTabAutoDiscardableState(contents, + state); + } + if (!is_async) { PopulateResult(); SendResponse(true);
diff --git a/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc b/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc index f8edf1b..7dedc4eb 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc +++ b/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc
@@ -201,11 +201,11 @@ int first_tab_id = -1; ASSERT_TRUE(first_tab_info->GetInteger("id", &first_tab_id)); - EXPECT_TRUE(ContainsValue(expected_tabs_ids, first_tab_id)); + EXPECT_TRUE(base::ContainsValue(expected_tabs_ids, first_tab_id)); int third_tab_id = -1; ASSERT_TRUE(third_tab_info->GetInteger("id", &third_tab_id)); - EXPECT_TRUE(ContainsValue(expected_tabs_ids, third_tab_id)); + EXPECT_TRUE(base::ContainsValue(expected_tabs_ids, third_tab_id)); } }
diff --git a/chrome/browser/extensions/api/tabs/tabs_constants.cc b/chrome/browser/extensions/api/tabs/tabs_constants.cc index 8229974..8d4392b 100644 --- a/chrome/browser/extensions/api/tabs/tabs_constants.cc +++ b/chrome/browser/extensions/api/tabs/tabs_constants.cc
@@ -32,6 +32,7 @@ const char kPinnedKey[] = "pinned"; const char kAudibleKey[] = "audible"; const char kDiscardedKey[] = "discarded"; +const char kAutoDiscardableKey[] = "autoDiscardable"; const char kMutedKey[] = "muted"; const char kMutedInfoKey[] = "mutedInfo"; const char kQualityKey[] = "quality";
diff --git a/chrome/browser/extensions/api/tabs/tabs_constants.h b/chrome/browser/extensions/api/tabs/tabs_constants.h index 9191750..f9b633b 100644 --- a/chrome/browser/extensions/api/tabs/tabs_constants.h +++ b/chrome/browser/extensions/api/tabs/tabs_constants.h
@@ -37,6 +37,7 @@ extern const char kPinnedKey[]; extern const char kAudibleKey[]; extern const char kDiscardedKey[]; +extern const char kAutoDiscardableKey[]; extern const char kMutedKey[]; extern const char kMutedInfoKey[]; extern const char kQualityKey[];
diff --git a/chrome/browser/extensions/api/tabs/tabs_event_router.cc b/chrome/browser/extensions/api/tabs/tabs_event_router.cc index 3a2f021..f11e908 100644 --- a/chrome/browser/extensions/api/tabs/tabs_event_router.cc +++ b/chrome/browser/extensions/api/tabs/tabs_event_router.cc
@@ -569,4 +569,16 @@ } } +void TabsEventRouter::OnAutoDiscardableStateChange(WebContents* contents, + bool is_auto_discardable) { + TabStripModel* tab_strip = nullptr; + int tab_index = -1; + + if (ExtensionTabUtil::GetTabStripModel(contents, &tab_strip, &tab_index)) { + std::set<std::string> changed_property_names; + changed_property_names.insert(tabs_constants::kAutoDiscardableKey); + DispatchTabUpdatedEvent(contents, std::move(changed_property_names)); + } +} + } // namespace extensions
diff --git a/chrome/browser/extensions/api/tabs/tabs_event_router.h b/chrome/browser/extensions/api/tabs/tabs_event_router.h index bae63dc..da6004c7 100644 --- a/chrome/browser/extensions/api/tabs/tabs_event_router.h +++ b/chrome/browser/extensions/api/tabs/tabs_event_router.h
@@ -94,6 +94,8 @@ // memory::TabManagerObserver: void OnDiscardedStateChange(content::WebContents* contents, bool is_discarded) override; + void OnAutoDiscardableStateChange(content::WebContents* contents, + bool is_auto_discardable) override; private: // "Synthetic" event. Called from TabInsertedAt if new tab is detected.
diff --git a/chrome/browser/extensions/api/tabs/tabs_test.cc b/chrome/browser/extensions/api/tabs/tabs_test.cc index 4438537..6927d6f 100644 --- a/chrome/browser/extensions/api/tabs/tabs_test.cc +++ b/chrome/browser/extensions/api/tabs/tabs_test.cc
@@ -1576,6 +1576,118 @@ EXPECT_TRUE(base::MatchPattern(error, keys::kCannotFindTabToDiscard)); } +IN_PROC_BROWSER_TEST_F(ExtensionTabsTest, AutoDiscardableProperty) { + // Create two aditional tabs. + content::OpenURLParams params(GURL(url::kAboutBlankURL), content::Referrer(), + NEW_BACKGROUND_TAB, ui::PAGE_TRANSITION_LINK, + false); + content::WebContents* web_contents_a = browser()->OpenURL(params); + content::WebContents* web_contents_b = browser()->OpenURL(params); + + // Creates Tab object to ensure the property is correct for the extension. + TabStripModel* tab_strip_model = browser()->tab_strip_model(); + std::unique_ptr<api::tabs::Tab> tab_object_a = + ExtensionTabUtil::CreateTabObject(web_contents_a, tab_strip_model, 0); + EXPECT_TRUE(tab_object_a->auto_discardable); + + // Set up query and update functions with the extension. + scoped_refptr<const Extension> extension = test_util::CreateEmptyExtension(); + auto RunQueryFunction = [this, &extension](const char* query_info) { + scoped_refptr<TabsQueryFunction> function = new TabsQueryFunction(); + function->set_extension(extension.get()); + return utils::ToList(utils::RunFunctionAndReturnSingleResult( + function.get(), query_info, browser())); + }; + auto RunUpdateFunction = [this, &extension](std::string update_info) { + scoped_refptr<TabsUpdateFunction> function = new TabsUpdateFunction(); + function->set_extension(extension.get()); + return utils::ToDictionary(utils::RunFunctionAndReturnSingleResult( + function.get(), update_info, browser())); + }; + + // Queries and results used. + const char* kAutoDiscardableQueryInfo = "[{\"autoDiscardable\": true}]"; + const char* kNonAutoDiscardableQueryInfo = "[{\"autoDiscardable\": false}]"; + std::unique_ptr<base::ListValue> query_result; + std::unique_ptr<base::DictionaryValue> update_result; + + // Get auto-discardable tabs. Returns all since tabs are auto-discardable + // by default. + query_result.reset(RunQueryFunction(kAutoDiscardableQueryInfo)); + EXPECT_EQ(3u, query_result->GetSize()); + + // Get non auto-discardable tabs. + query_result.reset(RunQueryFunction(kNonAutoDiscardableQueryInfo)); + EXPECT_EQ(0u, query_result->GetSize()); + + // Update the auto-discardable state of web contents A. + int tab_id_a = ExtensionTabUtil::GetTabId(web_contents_a); + update_result.reset(RunUpdateFunction( + base::StringPrintf("[%u, {\"autoDiscardable\": false}]", tab_id_a))); + EXPECT_EQ(tab_id_a, api_test_utils::GetInteger(update_result.get(), "id")); + EXPECT_FALSE( + api_test_utils::GetBoolean(update_result.get(), "autoDiscardable")); + + // Make sure the property is changed accordingly after updating the tab. + tab_object_a = + ExtensionTabUtil::CreateTabObject(web_contents_a, tab_strip_model, 0); + EXPECT_FALSE(tab_object_a->auto_discardable); + + // Get auto-discardable tabs after changing the status of web contents A. + query_result.reset(RunQueryFunction(kAutoDiscardableQueryInfo)); + EXPECT_EQ(2u, query_result->GetSize()); + + // Get non auto-discardable tabs after changing the status of web contents A. + query_result.reset(RunQueryFunction(kNonAutoDiscardableQueryInfo)); + EXPECT_EQ(1u, query_result->GetSize()); + + // Make sure the returned tab is the correct one. + int id = -1; + base::Value* tab = nullptr; + EXPECT_TRUE(query_result->Get(0, &tab)); + utils::ToDictionary(tab)->GetInteger(keys::kIdKey, &id); + EXPECT_EQ(tab_id_a, id); + + // Update the auto-discardable state of web contents B. + int tab_id_b = ExtensionTabUtil::GetTabId(web_contents_b); + update_result.reset(RunUpdateFunction( + base::StringPrintf("[%u, {\"autoDiscardable\": false}]", tab_id_b))); + EXPECT_EQ(tab_id_b, api_test_utils::GetInteger(update_result.get(), "id")); + EXPECT_FALSE( + api_test_utils::GetBoolean(update_result.get(), "autoDiscardable")); + + // Get auto-discardable tabs after changing the status of both created tabs. + query_result.reset(RunQueryFunction(kAutoDiscardableQueryInfo)); + EXPECT_EQ(1u, query_result->GetSize()); + + // Make sure the returned tab is the correct one. + id = -1; + tab = nullptr; + EXPECT_TRUE(query_result->Get(0, &tab)); + utils::ToDictionary(tab)->GetInteger(keys::kIdKey, &id); + EXPECT_EQ(ExtensionTabUtil::GetTabId(tab_strip_model->GetWebContentsAt(0)), + id); + + // Get auto-discardable tabs after changing the status of both created tabs. + query_result.reset(RunQueryFunction(kNonAutoDiscardableQueryInfo)); + EXPECT_EQ(2u, query_result->GetSize()); + + // Resets the first tab back to auto-discardable. + update_result.reset(RunUpdateFunction( + base::StringPrintf("[%u, {\"autoDiscardable\": true}]", tab_id_a))); + EXPECT_EQ(tab_id_a, api_test_utils::GetInteger(update_result.get(), "id")); + EXPECT_TRUE( + api_test_utils::GetBoolean(update_result.get(), "autoDiscardable")); + + // Get auto-discardable tabs after resetting the status of web contents A. + query_result.reset(RunQueryFunction(kAutoDiscardableQueryInfo)); + EXPECT_EQ(2u, query_result->GetSize()); + + // Get non auto-discardable tabs after resetting the status of web contents A. + query_result.reset(RunQueryFunction(kNonAutoDiscardableQueryInfo)); + EXPECT_EQ(1u, query_result->GetSize()); +} + // Tester class for the tabs.zoom* api functions. class ExtensionTabsZoomTest : public ExtensionTabsTest { public:
diff --git a/chrome/browser/extensions/blacklist.cc b/chrome/browser/extensions/blacklist.cc index ece8cb9c..1517156 100644 --- a/chrome/browser/extensions/blacklist.cc +++ b/chrome/browser/extensions/blacklist.cc
@@ -304,7 +304,7 @@ for (std::vector<std::string>::const_iterator ids_it = ids.begin(); ids_it != ids.end(); ++ids_it) { - if (!ContainsKey(blacklist_state_cache_, *ids_it)) { + if (!base::ContainsKey(blacklist_state_cache_, *ids_it)) { have_all_in_cache = false; break; }
diff --git a/chrome/browser/extensions/blacklist_state_fetcher.cc b/chrome/browser/extensions/blacklist_state_fetcher.cc index 7b83a9d..f0ff060 100644 --- a/chrome/browser/extensions/blacklist_state_fetcher.cc +++ b/chrome/browser/extensions/blacklist_state_fetcher.cc
@@ -28,7 +28,7 @@ BlacklistStateFetcher::~BlacklistStateFetcher() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - STLDeleteContainerPairFirstPointers(requests_.begin(), requests_.end()); + base::STLDeleteContainerPairFirstPointers(requests_.begin(), requests_.end()); requests_.clear(); } @@ -46,7 +46,7 @@ } } - bool request_already_sent = ContainsKey(callbacks_, id); + bool request_already_sent = base::ContainsKey(callbacks_, id); callbacks_.insert(std::make_pair(id, callback)); if (request_already_sent) return;
diff --git a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc index 2d44b432..b53243a 100644 --- a/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc +++ b/chrome/browser/extensions/chrome_content_browser_client_extensions_part.cc
@@ -139,8 +139,7 @@ if (!origin.SchemeIs(kExtensionScheme)) return false; - // If there is no extension installed for the URL, it couldn't have - // committed. + // If there is no extension installed for the URL, it couldn't have committed. // (If the extension was recently uninstalled, the tab would have closed.) ProfileIOData* io_data = ProfileIOData::FromResourceContext(resource_context); InfoMap* extension_info_map = io_data->GetExtensionInfoMap(); @@ -155,14 +154,12 @@ if (extension->is_platform_app() && !process_map.Contains(extension->id(), child_id)) { // This is a platform app origin not in the app's own process. If there - // are - // no accessible resources, this is illegal. + // are no accessible resources, this is illegal. if (!extension->GetManifestData(manifest_keys::kWebviewAccessibleResources)) return true; // If there are accessible resources, the origin is only legal if the - // given - // process is a guest of the app. + // given process is a guest of the app. std::string owner_extension_id; int owner_process_id; WebViewRendererState::GetInstance()->GetOwnerInfo( @@ -173,9 +170,8 @@ } // With only the origin and not the full URL, we don't have enough - // information - // to validate hosted apps or web_accessible_resources in normal extensions. - // Assume they're legal. + // information to validate hosted apps or web_accessible_resources in normal + // extensions. Assume they're legal. return false; }
diff --git a/chrome/browser/extensions/chrome_content_verifier_delegate.cc b/chrome/browser/extensions/chrome_content_verifier_delegate.cc index 2dd15aac..3251de98 100644 --- a/chrome/browser/extensions/chrome_content_verifier_delegate.cc +++ b/chrome/browser/extensions/chrome_content_verifier_delegate.cc
@@ -188,7 +188,7 @@ UMA_HISTOGRAM_BOOLEAN("Extensions.CorruptExtensionBecameDisabled", true); UMA_HISTOGRAM_ENUMERATION("Extensions.CorruptExtensionDisabledReason", reason, ContentVerifyJob::FAILURE_REASON_MAX); - } else if (!ContainsKey(would_be_disabled_ids_, extension_id)) { + } else if (!base::ContainsKey(would_be_disabled_ids_, extension_id)) { UMA_HISTOGRAM_BOOLEAN("Extensions.CorruptExtensionWouldBeDisabled", true); would_be_disabled_ids_.insert(extension_id); } @@ -196,7 +196,7 @@ void ChromeContentVerifierDelegate::LogFailureForPolicyForceInstall( const std::string& extension_id) { - if (!ContainsKey(corrupt_policy_extensions_, extension_id)) { + if (!base::ContainsKey(corrupt_policy_extensions_, extension_id)) { corrupt_policy_extensions_.insert(extension_id); UMA_HISTOGRAM_BOOLEAN("Extensions.CorruptPolicyExtensionWouldBeDisabled", true);
diff --git a/chrome/browser/extensions/component_migration_helper.cc b/chrome/browser/extensions/component_migration_helper.cc index 3a3c1a3..7de2caa 100644 --- a/chrome/browser/extensions/component_migration_helper.cc +++ b/chrome/browser/extensions/component_migration_helper.cc
@@ -130,7 +130,7 @@ GetActionIdForExtensionId(extension_id); if (component_action_id.empty()) return; - if (ContainsKey(enabled_actions_, component_action_id)) { + if (base::ContainsKey(enabled_actions_, component_action_id)) { UnloadExtension(extension_id); SetComponentActionPref(component_action_id, true);
diff --git a/chrome/browser/extensions/content_verifier_browsertest.cc b/chrome/browser/extensions/content_verifier_browsertest.cc index d51c3c92..f688dd47 100644 --- a/chrome/browser/extensions/content_verifier_browsertest.cc +++ b/chrome/browser/extensions/content_verifier_browsertest.cc
@@ -30,7 +30,7 @@ ~UnloadObserver() override {} void WaitForUnload(const ExtensionId& id) { - if (ContainsKey(observed_, id)) + if (base::ContainsKey(observed_, id)) return; ASSERT_TRUE(loop_runner_.get() == NULL); @@ -362,7 +362,7 @@ // The content scripts might fail verification the first time since the // one-time processing might not be finished yet - if that's the case then // we want to wait until that work is done. - if (!ContainsKey(verifier_observer.completed_fetches(), id)) + if (!base::ContainsKey(verifier_observer.completed_fetches(), id)) verifier_observer.WaitForFetchComplete(id); // Now disable/re-enable the extension to cause the content scripts to be @@ -393,7 +393,7 @@ ASSERT_EQ(extension->id(), id); // Wait for the content verification code to finish processing the hashes. - if (!ContainsKey(verifier_observer.completed_fetches(), id)) + if (!base::ContainsKey(verifier_observer.completed_fetches(), id)) verifier_observer.WaitForFetchComplete(id); // Now disable the extension, since content scripts are read at enable time,
diff --git a/chrome/browser/extensions/extension_action.h b/chrome/browser/extensions/extension_action.h index dabf4d4..393b2c77 100644 --- a/chrome/browser/extensions/extension_action.h +++ b/chrome/browser/extensions/extension_action.h
@@ -168,7 +168,7 @@ if (const bool* tab_is_visible = FindOrNull(&is_visible_, tab_id)) return *tab_is_visible; - if (ContainsKey(declarative_show_count_, tab_id)) + if (base::ContainsKey(declarative_show_count_, tab_id)) return true; if (const bool* default_is_visible =
diff --git a/chrome/browser/extensions/extension_action_runner.cc b/chrome/browser/extensions/extension_action_runner.cc index ad112f5..654129f 100644 --- a/chrome/browser/extensions/extension_action_runner.cc +++ b/chrome/browser/extensions/extension_action_runner.cc
@@ -125,7 +125,7 @@ } void ExtensionActionRunner::RunBlockedActions(const Extension* extension) { - DCHECK(ContainsKey(pending_scripts_, extension->id()) || + DCHECK(base::ContainsKey(pending_scripts_, extension->id()) || web_request_blocked_.count(extension->id()) != 0); // Clicking to run the extension counts as granting it permission to run on
diff --git a/chrome/browser/extensions/extension_icon_manager.cc b/chrome/browser/extensions/extension_icon_manager.cc index cec9a5b..ae163be 100644 --- a/chrome/browser/extensions/extension_icon_manager.cc +++ b/chrome/browser/extensions/extension_icon_manager.cc
@@ -79,7 +79,7 @@ const SkBitmap& ExtensionIconManager::GetIcon(const std::string& extension_id) { const SkBitmap* result = NULL; - if (ContainsKey(icons_, extension_id)) { + if (base::ContainsKey(icons_, extension_id)) { result = &icons_[extension_id]; } else { EnsureDefaultIcon(); @@ -103,7 +103,7 @@ // We may have removed the icon while waiting for it to load. In that case, // do nothing. - if (!ContainsKey(pending_icons_, extension_id)) + if (!base::ContainsKey(pending_icons_, extension_id)) return; pending_icons_.erase(extension_id);
diff --git a/chrome/browser/extensions/extension_resource_request_policy_apitest.cc b/chrome/browser/extensions/extension_resource_request_policy_apitest.cc index db8a606..0eb1128a 100644 --- a/chrome/browser/extensions/extension_resource_request_policy_apitest.cc +++ b/chrome/browser/extensions/extension_resource_request_policy_apitest.cc
@@ -12,6 +12,7 @@ #include "chrome/test/base/test_switches.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/navigation_handle.h" +#include "content/public/browser/notification_service.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/test/browser_test_utils.h" @@ -235,9 +236,10 @@ LinkToWebAccessibleResources) { std::string result; ASSERT_TRUE(embedded_test_server()->Start()); - ASSERT_TRUE(LoadExtension(test_data_dir_ - .AppendASCII("extension_resource_request_policy") - .AppendASCII("web_accessible"))); + const extensions::Extension* extension = LoadExtension( + test_data_dir_.AppendASCII("extension_resource_request_policy") + .AppendASCII("web_accessible")); + ASSERT_TRUE(extension); GURL accessible_linked_resource(embedded_test_server()->GetURL( "/extensions/api_test/extension_resource_request_policy/" @@ -261,27 +263,34 @@ &result)); EXPECT_EQ("about:blank", result); + + // Redirects can sometimes occur before the load event, so use a + // UrlLoadObserver instead of blocking waiting for two load events. + GURL accessible_url = extension->GetResourceURL("/test.png"); + ui_test_utils::UrlLoadObserver accessible_observer( + accessible_url, content::NotificationService::AllSources()); GURL accessible_client_redirect_resource(embedded_test_server()->GetURL( "/extensions/api_test/extension_resource_request_policy/" "web_accessible/accessible_redirect_resource.html")); - ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), - accessible_client_redirect_resource, 2); - ASSERT_TRUE(content::ExecuteScriptAndExtractString( - browser()->tab_strip_model()->GetActiveWebContents(), - "window.domAutomationController.send(document.URL)", - &result)); - EXPECT_NE("about:blank", result); + ui_test_utils::NavigateToURL(browser(), accessible_client_redirect_resource); + accessible_observer.Wait(); + EXPECT_EQ(accessible_url, browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetLastCommittedURL()); + ui_test_utils::UrlLoadObserver nonaccessible_observer( + GURL("about:blank"), content::NotificationService::AllSources()); GURL nonaccessible_client_redirect_resource(embedded_test_server()->GetURL( "/extensions/api_test/extension_resource_request_policy/" "web_accessible/nonaccessible_redirect_resource.html")); - ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), - nonaccessible_client_redirect_resource, 2); - ASSERT_TRUE(content::ExecuteScriptAndExtractString( - browser()->tab_strip_model()->GetActiveWebContents(), - "window.domAutomationController.send(document.URL)", - &result)); - EXPECT_EQ("about:blank", result); + ui_test_utils::NavigateToURL(browser(), + nonaccessible_client_redirect_resource); + nonaccessible_observer.Wait(); + EXPECT_EQ(GURL("about:blank"), browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetLastCommittedURL()); } IN_PROC_BROWSER_TEST_F(ExtensionResourceRequestPolicyTest,
diff --git a/chrome/browser/extensions/extension_special_storage_policy.cc b/chrome/browser/extensions/extension_special_storage_policy.cc index eed89f2..26eabfe 100644 --- a/chrome/browser/extensions/extension_special_storage_policy.cc +++ b/chrome/browser/extensions/extension_special_storage_policy.cc
@@ -304,7 +304,7 @@ ExtensionSpecialStoragePolicy::SpecialCollection::SpecialCollection() {} ExtensionSpecialStoragePolicy::SpecialCollection::~SpecialCollection() { - STLDeleteValues(&cached_results_); + base::STLDeleteValues(&cached_results_); } bool ExtensionSpecialStoragePolicy::SpecialCollection::Contains( @@ -363,5 +363,5 @@ } void ExtensionSpecialStoragePolicy::SpecialCollection::ClearCache() { - STLDeleteValues(&cached_results_); + base::STLDeleteValues(&cached_results_); }
diff --git a/chrome/browser/extensions/extension_tab_util.cc b/chrome/browser/extensions/extension_tab_util.cc index 74ab6e98..cfd503c 100644 --- a/chrome/browser/extensions/extension_tab_util.cc +++ b/chrome/browser/extensions/extension_tab_util.cc
@@ -389,10 +389,10 @@ tab_object->highlighted = tab_strip && tab_strip->IsTabSelected(tab_index); tab_object->pinned = tab_strip && tab_strip->IsTabPinned(tab_index); tab_object->audible.reset(new bool(contents->WasRecentlyAudible())); - - memory::TabManager* tab_manager = g_browser_process->GetTabManager(); - tab_object->discarded = tab_manager && tab_manager->IsTabDiscarded(contents); - + tab_object->discarded = + g_browser_process->GetTabManager()->IsTabDiscarded(contents); + tab_object->auto_discardable = + g_browser_process->GetTabManager()->IsTabAutoDiscardable(contents); tab_object->muted_info = CreateMutedInfo(contents); tab_object->incognito = contents->GetBrowserContext()->IsOffTheRecord(); tab_object->width.reset(
diff --git a/chrome/browser/extensions/extension_tabs_apitest.cc b/chrome/browser/extensions/extension_tabs_apitest.cc index 1ed844e4..015c264 100644 --- a/chrome/browser/extensions/extension_tabs_apitest.cc +++ b/chrome/browser/extensions/extension_tabs_apitest.cc
@@ -277,7 +277,7 @@ << message_; } -IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DiscardedState) { +IN_PROC_BROWSER_TEST_F(ExtensionApiTest, OnUpdatedDiscardedState) { ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "discarded.html")) << message_; }
diff --git a/chrome/browser/extensions/external_install_manager.cc b/chrome/browser/extensions/external_install_manager.cc index 4ced39a4..5d79207 100644 --- a/chrome/browser/extensions/external_install_manager.cc +++ b/chrome/browser/extensions/external_install_manager.cc
@@ -78,7 +78,7 @@ void ExternalInstallManager::AddExternalInstallError(const Extension* extension, bool is_new_profile) { // Error already exists or has been previously shown. - if (ContainsKey(errors_, extension->id()) || + if (base::ContainsKey(errors_, extension->id()) || shown_ids_.count(extension->id()) > 0) return; @@ -115,7 +115,7 @@ const ExtensionSet& disabled_extensions = ExtensionRegistry::Get(browser_context_)->disabled_extensions(); for (const scoped_refptr<const Extension>& extension : disabled_extensions) { - if (ContainsKey(errors_, extension->id()) || + if (base::ContainsKey(errors_, extension->id()) || shown_ids_.count(extension->id()) > 0) continue; @@ -232,7 +232,7 @@ // not sent out if the extension is disabled (which it is here). const std::string& extension_id = content::Details<const Extension>(details).ptr()->id(); - if (ContainsKey(errors_, extension_id)) + if (base::ContainsKey(errors_, extension_id)) RemoveExternalInstallError(extension_id); }
diff --git a/chrome/browser/extensions/external_pref_loader.h b/chrome/browser/extensions/external_pref_loader.h index 776cca14..d438a0f 100644 --- a/chrome/browser/extensions/external_pref_loader.h +++ b/chrome/browser/extensions/external_pref_loader.h
@@ -14,7 +14,7 @@ #include "base/values.h" #include "chrome/browser/extensions/external_loader.h" #include "components/browser_sync/browser/profile_sync_service.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/sync_service_observer.h" #include "components/syncable_prefs/pref_service_syncable_observer.h" class Profile;
diff --git a/chrome/browser/extensions/external_provider_impl.cc b/chrome/browser/extensions/external_provider_impl.cc index 9a7026c..3673d8e 100644 --- a/chrome/browser/extensions/external_provider_impl.cc +++ b/chrome/browser/extensions/external_provider_impl.cc
@@ -247,7 +247,7 @@ if (supported_locales->GetString(j, ¤t_locale) && l10n_util::IsValidLocaleSyntax(current_locale)) { current_locale = l10n_util::NormalizeLocale(current_locale); - if (ContainsValue(browser_locales, current_locale)) { + if (base::ContainsValue(browser_locales, current_locale)) { locale_supported = true; break; }
diff --git a/chrome/browser/extensions/external_provider_impl_chromeos_unittest.cc b/chrome/browser/extensions/external_provider_impl_chromeos_unittest.cc index 7d7606a..1601dc3 100644 --- a/chrome/browser/extensions/external_provider_impl_chromeos_unittest.cc +++ b/chrome/browser/extensions/external_provider_impl_chromeos_unittest.cc
@@ -33,7 +33,7 @@ #include "components/sync/api/fake_sync_change_processor.h" #include "components/sync/api/sync_change_processor.h" #include "components/sync/api/sync_error_factory_mock.h" -#include "components/sync_driver/pref_names.h" +#include "components/sync/driver/pref_names.h" #include "components/syncable_prefs/pref_service_syncable.h" #include "components/user_manager/fake_user_manager.h" #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/extensions/install_signer.cc b/chrome/browser/extensions/install_signer.cc index 9bf403c..0100058 100644 --- a/chrome/browser/extensions/install_signer.cc +++ b/chrome/browser/extensions/install_signer.cc
@@ -99,7 +99,7 @@ hash->Update(salt.data(), salt.size()); std::string result_bytes(crypto::kSHA256Length, 0); - hash->Finish(string_as_array(&result_bytes), result_bytes.size()); + hash->Finish(base::string_as_array(&result_bytes), result_bytes.size()); base::Base64Encode(result_bytes, result); return true; @@ -356,7 +356,7 @@ salt_ = std::string(kSaltBytes, 0); DCHECK_EQ(kSaltBytes, salt_.size()); - crypto::RandBytes(string_as_array(&salt_), salt_.size()); + crypto::RandBytes(base::string_as_array(&salt_), salt_.size()); std::string hash_base64; if (!HashWithMachineId(salt_, &hash_base64)) {
diff --git a/chrome/browser/extensions/install_verifier.cc b/chrome/browser/extensions/install_verifier.cc index 6d10cff1..ac25d7f 100644 --- a/chrome/browser/extensions/install_verifier.cc +++ b/chrome/browser/extensions/install_verifier.cc
@@ -271,12 +271,12 @@ } bool InstallVerifier::IsKnownId(const std::string& id) const { - return signature_.get() && (ContainsKey(signature_->ids, id) || - ContainsKey(signature_->invalid_ids, id)); + return signature_.get() && (base::ContainsKey(signature_->ids, id) || + base::ContainsKey(signature_->invalid_ids, id)); } bool InstallVerifier::IsInvalid(const std::string& id) const { - return ((signature_.get() && ContainsKey(signature_->invalid_ids, id))); + return ((signature_.get() && base::ContainsKey(signature_->invalid_ids, id))); } void InstallVerifier::VerifyExtension(const std::string& extension_id) { @@ -328,8 +328,8 @@ bool found_any = false; for (ExtensionIdSet::const_iterator i = ids.begin(); i != ids.end(); ++i) { - if (ContainsKey(signature_->ids, *i) || - ContainsKey(signature_->invalid_ids, *i)) { + if (base::ContainsKey(signature_->ids, *i) || + base::ContainsKey(signature_->invalid_ids, *i)) { found_any = true; break; } @@ -406,7 +406,8 @@ bool verified = true; MustRemainDisabledOutcome outcome = VERIFIED; - if (ContainsKey(InstallSigner::GetForcedNotFromWebstore(), extension->id())) { + if (base::ContainsKey(InstallSigner::GetForcedNotFromWebstore(), + extension->id())) { verified = false; outcome = FORCED_NOT_VERIFIED; } else if (!IsFromStore(*extension)) { @@ -421,7 +422,7 @@ outcome = NO_SIGNATURE; } else if (!IsVerified(extension->id())) { if (signature_.get() && - !ContainsKey(signature_->invalid_ids, extension->id())) { + !base::ContainsKey(signature_->invalid_ids, extension->id())) { outcome = NOT_VERIFIED_BUT_UNKNOWN_ID; } else { verified = false; @@ -548,8 +549,8 @@ } bool InstallVerifier::IsVerified(const std::string& id) const { - return ((signature_.get() && ContainsKey(signature_->ids, id)) || - ContainsKey(provisional_, id)); + return ((signature_.get() && base::ContainsKey(signature_->ids, id)) || + base::ContainsKey(provisional_, id)); } void InstallVerifier::BeginFetch() { @@ -568,7 +569,7 @@ if (operation.type == InstallVerifier::REMOVE) { for (ExtensionIdSet::const_iterator i = operation.ids.begin(); i != operation.ids.end(); ++i) { - if (ContainsKey(ids_to_sign, *i)) + if (base::ContainsKey(ids_to_sign, *i)) ids_to_sign.erase(*i); } } else { // All other operation types are some form of "ADD".
diff --git a/chrome/browser/extensions/menu_manager.cc b/chrome/browser/extensions/menu_manager.cc index dc9913d..993622c 100644 --- a/chrome/browser/extensions/menu_manager.cc +++ b/chrome/browser/extensions/menu_manager.cc
@@ -132,7 +132,7 @@ contexts_(contexts) {} MenuItem::~MenuItem() { - STLDeleteElements(&children_); + base::STLDeleteElements(&children_); } MenuItem* MenuItem::ReleaseChild(const Id& child_id, @@ -166,7 +166,7 @@ std::set<Id> removed = child->RemoveAllDescendants(); result.insert(removed.begin(), removed.end()); } - STLDeleteElements(&children_); + base::STLDeleteElements(&children_); return result; } @@ -318,7 +318,7 @@ MenuManager::~MenuManager() { MenuItemMap::iterator i; for (i = context_items_.begin(); i != context_items_.end(); ++i) { - STLDeleteElements(&(i->second)); + base::STLDeleteElements(&(i->second)); } } @@ -349,12 +349,12 @@ const MenuItem::ExtensionKey& key = item->id().extension_key; // The item must have a non-empty key, and not have already been added. - if (key.empty() || ContainsKey(items_by_id_, item->id())) + if (key.empty() || base::ContainsKey(items_by_id_, item->id())) return false; DCHECK_EQ(extension->id(), key.extension_id); - bool first_item = !ContainsKey(context_items_, key); + bool first_item = !base::ContainsKey(context_items_, key); context_items_[key].push_back(item); items_by_id_[item->id()] = item; @@ -378,7 +378,7 @@ if (!parent || parent->type() != MenuItem::NORMAL || parent->incognito() != child->incognito() || parent->extension_id() != child->extension_id() || - ContainsKey(items_by_id_, child->id())) + base::ContainsKey(items_by_id_, child->id())) return false; parent->AddChild(child); items_by_id_[child->id()] = child; @@ -460,7 +460,7 @@ } bool MenuManager::RemoveContextMenuItem(const MenuItem::Id& id) { - if (!ContainsKey(items_by_id_, id)) + if (!base::ContainsKey(items_by_id_, id)) return false; MenuItem* menu_item = GetItemById(id); @@ -544,7 +544,7 @@ items_by_id_.erase(*j); } } - STLDeleteElements(&context_items_for_key); + base::STLDeleteElements(&context_items_for_key); context_items_.erase(extension_key); icon_manager_.RemoveIcon(extension_id); } @@ -780,7 +780,7 @@ } bool MenuManager::ItemUpdated(const MenuItem::Id& id) { - if (!ContainsKey(items_by_id_, id)) + if (!base::ContainsKey(items_by_id_, id)) return false; MenuItem* menu_item = GetItemById(id); @@ -868,7 +868,7 @@ const Extension* extension, UnloadedExtensionInfo::Reason reason) { MenuItem::ExtensionKey extension_key(extension->id()); - if (ContainsKey(context_items_, extension_key)) { + if (base::ContainsKey(context_items_, extension_key)) { RemoveAllContextItems(extension_key); } }
diff --git a/chrome/browser/extensions/permissions_based_management_policy_provider_unittest.cc b/chrome/browser/extensions/permissions_based_management_policy_provider_unittest.cc index aa919c0..0f096b0d 100644 --- a/chrome/browser/extensions/permissions_based_management_policy_provider_unittest.cc +++ b/chrome/browser/extensions/permissions_based_management_policy_provider_unittest.cc
@@ -42,9 +42,7 @@ pref_names::kExtensionManagement); } - void TearDown() override { - STLDeleteElements(&perm_list_); - } + void TearDown() override { base::STLDeleteElements(&perm_list_); } // Get API permissions name for |id|, we cannot use arbitrary strings since // they will be ignored by ExtensionManagementService.
diff --git a/chrome/browser/extensions/shared_user_script_master.cc b/chrome/browser/extensions/shared_user_script_master.cc index 329254d..6a0dde4 100644 --- a/chrome/browser/extensions/shared_user_script_master.cc +++ b/chrome/browser/extensions/shared_user_script_master.cc
@@ -34,24 +34,27 @@ content::BrowserContext* browser_context, const Extension* extension, UnloadedExtensionInfo::Reason reason) { - loader_.RemoveScripts(GetScriptsMetadata(extension)); + const UserScriptList& script_list = + ContentScriptsInfo::GetContentScripts(extension); + std::set<UserScriptIDPair> scripts_to_remove; + for (const UserScript& script : script_list) + scripts_to_remove.insert(UserScriptIDPair(script.id(), script.host_id())); + loader_.RemoveScripts(scripts_to_remove); } -const std::set<UserScript> SharedUserScriptMaster::GetScriptsMetadata( +const std::vector<UserScript> SharedUserScriptMaster::GetScriptsMetadata( const Extension* extension) { bool incognito_enabled = util::IsIncognitoEnabled(extension->id(), profile_); const UserScriptList& script_list = ContentScriptsInfo::GetContentScripts(extension); - std::set<UserScript> script_set; - for (UserScriptList::const_iterator it = script_list.begin(); - it != script_list.end(); - ++it) { - UserScript script = *it; - script.set_incognito_enabled(incognito_enabled); - script_set.insert(script); + std::vector<UserScript> scripts; + scripts.reserve(script_list.size()); + for (const UserScript& script : script_list) { + scripts.push_back(UserScript(script)); + scripts.back().set_incognito_enabled(incognito_enabled); } - return script_set; + return scripts; } } // namespace extensions
diff --git a/chrome/browser/extensions/shared_user_script_master.h b/chrome/browser/extensions/shared_user_script_master.h index b697829e..5fb32d4 100644 --- a/chrome/browser/extensions/shared_user_script_master.h +++ b/chrome/browser/extensions/shared_user_script_master.h
@@ -45,7 +45,7 @@ // Gets an extension's scripts' metadata; i.e., gets a list of UserScript // objects that contains script info, but not the contents of the scripts. - const std::set<UserScript> GetScriptsMetadata(const Extension* extension); + const UserScriptList GetScriptsMetadata(const Extension* extension); // Script loader that handles loading contents of scripts into shared memory // and notifying renderers of scripts in shared memory.
diff --git a/chrome/browser/extensions/test_blacklist.cc b/chrome/browser/extensions/test_blacklist.cc index 7ff92ea..e18dc4e 100644 --- a/chrome/browser/extensions/test_blacklist.cc +++ b/chrome/browser/extensions/test_blacklist.cc
@@ -33,7 +33,7 @@ ++request_count_; BlacklistState result = NOT_BLACKLISTED; - if (ContainsKey(states_, id)) + if (base::ContainsKey(states_, id)) result = states_[id]; base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
diff --git a/chrome/browser/extensions/test_blacklist_state_fetcher.cc b/chrome/browser/extensions/test_blacklist_state_fetcher.cc index d504e04f..fc34c7bb 100644 --- a/chrome/browser/extensions/test_blacklist_state_fetcher.cc +++ b/chrome/browser/extensions/test_blacklist_state_fetcher.cc
@@ -62,7 +62,7 @@ std::string id = request.id(); ClientCRXListInfoResponse response; - if (ContainsKey(verdicts_, id)) + if (base::ContainsKey(verdicts_, id)) response.set_verdict(verdicts_[id]); else response.set_verdict(ClientCRXListInfoResponse::NOT_IN_BLACKLIST);
diff --git a/chrome/browser/extensions/updater/extension_cache_fake.cc b/chrome/browser/extensions/updater/extension_cache_fake.cc index 7eab5da..0032d15 100644 --- a/chrome/browser/extensions/updater/extension_cache_fake.cc +++ b/chrome/browser/extensions/updater/extension_cache_fake.cc
@@ -55,7 +55,7 @@ const base::FilePath& file_path, const std::string& version, const PutExtensionCallback& callback) { - if (ContainsKey(allowed_extensions_, id)) { + if (base::ContainsKey(allowed_extensions_, id)) { cache_[id].first = version; cache_[id].second = file_path; content::BrowserThread::PostTask(
diff --git a/chrome/browser/extensions/updater/extension_cache_impl.cc b/chrome/browser/extensions/updater/extension_cache_impl.cc index 8c393937..3ad55ed3 100644 --- a/chrome/browser/extensions/updater/extension_cache_impl.cc +++ b/chrome/browser/extensions/updater/extension_cache_impl.cc
@@ -89,7 +89,7 @@ } bool ExtensionCacheImpl::CachingAllowed(const std::string& id) { - return ContainsKey(allowed_extensions_, id); + return base::ContainsKey(allowed_extensions_, id); } void ExtensionCacheImpl::OnCacheInitialized() {
diff --git a/chrome/browser/extensions/updater/extension_updater.cc b/chrome/browser/extensions/updater/extension_updater.cc index 63d7b3834..45ef758 100644 --- a/chrome/browser/extensions/updater/extension_updater.cc +++ b/chrome/browser/extensions/updater/extension_updater.cc
@@ -591,7 +591,7 @@ } void ExtensionUpdater::NotifyIfFinished(int request_id) { - DCHECK(ContainsKey(requests_in_progress_, request_id)); + DCHECK(base::ContainsKey(requests_in_progress_, request_id)); const InProgressCheck& request = requests_in_progress_[request_id]; if (request.in_progress_ids_.empty()) { VLOG(2) << "Finished update check " << request_id;
diff --git a/chrome/browser/extensions/updater/extension_updater_unittest.cc b/chrome/browser/extensions/updater/extension_updater_unittest.cc index 5a933f0..550b890 100644 --- a/chrome/browser/extensions/updater/extension_updater_unittest.cc +++ b/chrome/browser/extensions/updater/extension_updater_unittest.cc
@@ -507,7 +507,7 @@ extension_id_ = file.extension_id; install_path_ = file.path; - if (ContainsKey(fake_crx_installers_, extension_id_)) { + if (base::ContainsKey(fake_crx_installers_, extension_id_)) { *out_crx_installer = fake_crx_installers_[extension_id_]; return true; } @@ -594,7 +594,8 @@ base::SplitStringIntoKeyValuePairs(unescaped, '=', '&', &extension_params); std::multimap<std::string, std::string> param_map; param_map.insert(extension_params.begin(), extension_params.end()); - if (ContainsKey(param_map, "id") && ContainsKey(param_map, "ping")) { + if (base::ContainsKey(param_map, "id") && + base::ContainsKey(param_map, "ping")) { std::string id = param_map.find("id")->second; result[id] = ParamsMap(); @@ -607,7 +608,7 @@ base::StringPairs ping_params; base::SplitStringIntoKeyValuePairs(ping, '=', '&', &ping_params); for (const auto& ping_param : ping_params) { - if (!ContainsKey(result[id], ping_param.first)) + if (!base::ContainsKey(result[id], ping_param.first)) result[id][ping_param.first] = std::set<std::string>(); result[id][ping_param.first].insert(ping_param.second); } @@ -1708,7 +1709,7 @@ std::map<std::string, ParamsMap> url1_ping_data = GetPingDataFromURL(url1_fetch_url); ParamsMap url1_params = ParamsMap(); - if (!url1_ping_data.empty() && ContainsKey(url1_ping_data, id)) + if (!url1_ping_data.empty() && base::ContainsKey(url1_ping_data, id)) url1_params = url1_ping_data[id]; // First make sure the non-google query had no ping parameter. @@ -1717,14 +1718,14 @@ // Now make sure the google query had the correct ping parameter. bool did_rollcall = false; if (rollcall_ping_days != 0) { - ASSERT_TRUE(ContainsKey(url1_params, "r")); + ASSERT_TRUE(base::ContainsKey(url1_params, "r")); ASSERT_EQ(1u, url1_params["r"].size()); EXPECT_EQ(base::IntToString(rollcall_ping_days), *url1_params["r"].begin()); did_rollcall = true; } if (active_bit && active_ping_days != 0 && did_rollcall) { - ASSERT_TRUE(ContainsKey(url1_params, "a")); + ASSERT_TRUE(base::ContainsKey(url1_params, "a")); ASSERT_EQ(1u, url1_params["a"].size()); EXPECT_EQ(base::IntToString(active_ping_days), *url1_params["a"].begin()); @@ -1843,14 +1844,14 @@ // Make sure that all the enabled extensions have "e=1" in their ping // parameter. for (const auto& ext : enabled_extensions) { - ASSERT_TRUE(ContainsKey(all_pings, ext->id())); + ASSERT_TRUE(base::ContainsKey(all_pings, ext->id())); ParamsMap& ping = all_pings[ext->id()]; - EXPECT_FALSE(ContainsKey(ping, "dr")); - ASSERT_TRUE(ContainsKey(ping, "e")) << url; + EXPECT_FALSE(base::ContainsKey(ping, "dr")); + ASSERT_TRUE(base::ContainsKey(ping, "e")) << url; std::set<std::string> e = ping["e"]; ASSERT_EQ(1u, e.size()) << url; EXPECT_EQ(std::string("1"), *e.begin()) << url; - EXPECT_FALSE(ContainsKey(ping, "dr")); + EXPECT_FALSE(base::ContainsKey(ping, "dr")); } // Make sure that all the disable extensions have the appropriate @@ -1860,18 +1861,18 @@ for (size_t i = 0; i < disabled.size(); i++) { scoped_refptr<const Extension>& ext = disabled_extensions[i]; int disable_reasons = disabled[i]; - ASSERT_TRUE(ContainsKey(all_pings, ext->id())) << url; + ASSERT_TRUE(base::ContainsKey(all_pings, ext->id())) << url; ParamsMap& ping = all_pings[ext->id()]; - ASSERT_TRUE(ContainsKey(ping, "e")) << url; + ASSERT_TRUE(base::ContainsKey(ping, "e")) << url; std::set<std::string> e = ping["e"]; ASSERT_EQ(1u, e.size()) << url; EXPECT_EQ(std::string("0"), *e.begin()) << url; if (disable_reasons == 0) { - EXPECT_FALSE(ContainsKey(ping, "dr")); + EXPECT_FALSE(base::ContainsKey(ping, "dr")); } else { - ASSERT_TRUE(ContainsKey(ping, "dr")); + ASSERT_TRUE(base::ContainsKey(ping, "dr")); int found_reasons = 0; for (const auto& reason_string : ping["dr"]) { int reason = 0;
diff --git a/chrome/browser/extensions/warning_badge_service.cc b/chrome/browser/extensions/warning_badge_service.cc index f226fb3..cebe7a67 100644 --- a/chrome/browser/extensions/warning_badge_service.cc +++ b/chrome/browser/extensions/warning_badge_service.cc
@@ -139,7 +139,7 @@ bool non_suppressed_warnings_exist = false; for (std::set<Warning>::const_iterator i = warnings.begin(); i != warnings.end(); ++i) { - if (!ContainsKey(suppressed_warnings_, *i)) { + if (!base::ContainsKey(suppressed_warnings_, *i)) { non_suppressed_warnings_exist = true; break; }
diff --git a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc index f2fab03f3..1e85ef9 100644 --- a/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc +++ b/chrome/browser/feedback/system_logs/log_sources/chrome_internal_log_source.cc
@@ -14,7 +14,7 @@ #include "chrome/common/pref_names.h" #include "components/browser_sync/browser/profile_sync_service.h" #include "components/prefs/pref_service.h" -#include "components/sync_driver/about_sync_util.h" +#include "components/sync/driver/about_sync_util.h" #include "content/public/browser/browser_thread.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/extension.h"
diff --git a/chrome/browser/google/google_update_win.cc b/chrome/browser/google/google_update_win.cc index 1289a7da..6514ab8 100644 --- a/chrome/browser/google/google_update_win.cc +++ b/chrome/browser/google/google_update_win.cc
@@ -584,6 +584,10 @@ DCHECK(FAILED(hresult)); // Return results immediately since the driver is not polling Google Update. + // Release the reference on the COM objects so that they are torn down in the + // blocking pool before bouncing back to the caller's task runner. + app_bundle_cookie_.Revoke(); + google_update_cookie_.Revoke(); OnUpgradeError(error_code, hresult, -1, base::string16()); result_runner_->DeleteSoon(FROM_HERE, this); } @@ -985,9 +989,6 @@ html_error_message_ = l10n_util::GetStringFUTF16( IDS_ABOUT_BOX_GOOGLE_UPDATE_ERROR, error_string, html_error_msg); } - - app_bundle_cookie_.Revoke(); - google_update_cookie_.Revoke(); } } // namespace
diff --git a/chrome/browser/guest_view/web_view/context_menu_content_type_web_view.cc b/chrome/browser/guest_view/web_view/context_menu_content_type_web_view.cc index 743a375..e4eb867b 100644 --- a/chrome/browser/guest_view/web_view/context_menu_content_type_web_view.cc +++ b/chrome/browser/guest_view/web_view/context_menu_content_type_web_view.cc
@@ -53,7 +53,7 @@ if (chrome::GetChannel() >= version_info::Channel::DEV) { // Hide dev tools items in guests inside WebUI if we are not running // canary or tott. - auto web_view_guest = + auto* web_view_guest = extensions::WebViewGuest::FromWebContents(source_web_contents()); // Note that this check might not be sufficient to hide dev tools // items on OS_MACOSX if we start supporting <webview> inside
diff --git a/chrome/browser/icon_manager.cc b/chrome/browser/icon_manager.cc index e0c8ce1a..6596ab3 100644 --- a/chrome/browser/icon_manager.cc +++ b/chrome/browser/icon_manager.cc
@@ -36,7 +36,7 @@ } IconManager::~IconManager() { - STLDeleteValues(&icon_cache_); + base::STLDeleteValues(&icon_cache_); } gfx::Image* IconManager::LookupIconFromFilepath(const base::FilePath& file_name,
diff --git a/chrome/browser/importer/ie_importer_browsertest_win.cc b/chrome/browser/importer/ie_importer_browsertest_win.cc index 1113e37b..ab48d8e 100644 --- a/chrome/browser/importer/ie_importer_browsertest_win.cc +++ b/chrome/browser/importer/ie_importer_browsertest_win.cc
@@ -322,7 +322,7 @@ // TODO(jcampan): bug 1169230: we should test keyword importing for IE. // In order to do that we'll probably need to mock the Windows registry. NOTREACHED(); - STLDeleteContainerPointers(template_url.begin(), template_url.end()); + base::STLDeleteContainerPointers(template_url.begin(), template_url.end()); } void AddFavicons(const favicon_base::FaviconUsageDataList& usage) override {
diff --git a/chrome/browser/intranet_redirect_detector.cc b/chrome/browser/intranet_redirect_detector.cc index 32a90cb..3f2a7f9 100644 --- a/chrome/browser/intranet_redirect_detector.cc +++ b/chrome/browser/intranet_redirect_detector.cc
@@ -48,7 +48,7 @@ IntranetRedirectDetector::~IntranetRedirectDetector() { net::NetworkChangeNotifier::RemoveIPAddressObserver(this); - STLDeleteElements(&fetchers_); + base::STLDeleteElements(&fetchers_); } // static @@ -68,7 +68,7 @@ in_sleep_ = false; // If another fetch operation is still running, cancel it. - STLDeleteElements(&fetchers_); + base::STLDeleteElements(&fetchers_); resulting_origins_.clear(); const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
diff --git a/chrome/browser/io_thread_unittest.cc b/chrome/browser/io_thread_unittest.cc index f7899766..4efa28ba 100644 --- a/chrome/browser/io_thread_unittest.cc +++ b/chrome/browser/io_thread_unittest.cc
@@ -348,13 +348,13 @@ QuicVersionFromCommandLine) { command_line_.AppendSwitch("enable-quic"); std::string version = - net::QuicVersionToString(net::QuicSupportedVersions().back()); + net::QuicVersionToString(net::AllSupportedVersions().back()); command_line_.AppendSwitchASCII("quic-version", version); ConfigureParamsFromFieldTrialsAndCommandLine(); net::QuicVersionVector supported_versions; - supported_versions.push_back(net::QuicSupportedVersions().back()); + supported_versions.push_back(net::AllSupportedVersions().back()); EXPECT_EQ(supported_versions, params_.quic_supported_versions); } @@ -382,11 +382,11 @@ EXPECT_EQ(2u, params_.origins_to_force_quic_on.size()); EXPECT_TRUE( - ContainsKey(params_.origins_to_force_quic_on, - net::HostPortPair::FromString("www.example.com:443"))); + base::ContainsKey(params_.origins_to_force_quic_on, + net::HostPortPair::FromString("www.example.com:443"))); EXPECT_TRUE( - ContainsKey(params_.origins_to_force_quic_on, - net::HostPortPair::FromString("www.example.org:443"))); + base::ContainsKey(params_.origins_to_force_quic_on, + net::HostPortPair::FromString("www.example.org:443"))); } TEST_F(ConfigureParamsFromFieldTrialsAndCommandLineTest, @@ -398,7 +398,7 @@ EXPECT_EQ(1u, params_.origins_to_force_quic_on.size()); EXPECT_TRUE( - ContainsKey(params_.origins_to_force_quic_on, net::HostPortPair())); + base::ContainsKey(params_.origins_to_force_quic_on, net::HostPortPair())); } TEST_F(ConfigureParamsFromFieldTrialsAndCommandLineTest, @@ -410,8 +410,10 @@ ConfigureParamsFromFieldTrialsAndCommandLine(); EXPECT_EQ(2u, params_.quic_host_whitelist.size()); - EXPECT_TRUE(ContainsKey(params_.quic_host_whitelist, "www.example.org")); - EXPECT_TRUE(ContainsKey(params_.quic_host_whitelist, "www.example.com")); + EXPECT_TRUE( + base::ContainsKey(params_.quic_host_whitelist, "www.example.org")); + EXPECT_TRUE( + base::ContainsKey(params_.quic_host_whitelist, "www.example.com")); } TEST_F(ConfigureParamsFromFieldTrialsAndCommandLineTest,
diff --git a/chrome/browser/lifetime/keep_alive_registry.cc b/chrome/browser/lifetime/keep_alive_registry.cc index 77c3ae3..195956f 100644 --- a/chrome/browser/lifetime/keep_alive_registry.cc +++ b/chrome/browser/lifetime/keep_alive_registry.cc
@@ -37,6 +37,36 @@ observers_.RemoveObserver(observer); } +bool KeepAliveRegistry::WouldRestartWithout( + const std::vector<KeepAliveOrigin>& origins) const { + int registered_count = 0; + int restart_allowed_count = 0; + + for (auto origin : origins) { + auto counts_it = registered_keep_alives_.find(origin); + if (counts_it != registered_keep_alives_.end()) { + registered_count += counts_it->second; + + counts_it = restart_allowed_keep_alives_.find(origin); + if (counts_it != restart_allowed_keep_alives_.end()) + restart_allowed_count += counts_it->second; + } else { + // |registered_keep_alives_| is supposed to be a superset of + // |restart_allowed_keep_alives_| + DCHECK(restart_allowed_keep_alives_.find(origin) == + restart_allowed_keep_alives_.end()); + } + } + + registered_count = registered_count_ - registered_count; + restart_allowed_count = restart_allowed_count_ - restart_allowed_count; + + DCHECK_GE(registered_count, 0); + DCHECK_GE(restart_allowed_count, 0); + + return registered_count == restart_allowed_count; +} + //////////////////////////////////////////////////////////////////////////////// // Private methods @@ -58,8 +88,10 @@ ++registered_keep_alives_[origin]; ++registered_count_; - if (restart == KeepAliveRestartOption::ENABLED) + if (restart == KeepAliveRestartOption::ENABLED) { + ++restart_allowed_keep_alives_[origin]; ++restart_allowed_count_; + } bool new_keeping_alive = IsKeepingAlive(); bool new_restart_allowed = IsRestartAllowed(); @@ -80,14 +112,12 @@ --registered_count_; DCHECK_GE(registered_count_, 0); + DecrementCount(origin, ®istered_keep_alives_); - int new_count = --registered_keep_alives_[origin]; - DCHECK_GE(registered_keep_alives_[origin], 0); - if (new_count == 0) - registered_keep_alives_.erase(origin); - - if (restart == KeepAliveRestartOption::ENABLED) + if (restart == KeepAliveRestartOption::ENABLED) { --restart_allowed_count_; + DecrementCount(origin, &restart_allowed_keep_alives_); + } bool new_keeping_alive = IsKeepingAlive(); bool new_restart_allowed = IsRestartAllowed(); @@ -117,6 +147,14 @@ OnKeepAliveRestartStateChanged(new_restart_allowed)); } +void KeepAliveRegistry::DecrementCount(KeepAliveOrigin origin, + OriginMap* keep_alive_map) { + int new_count = --keep_alive_map->at(origin); + DCHECK_GE(keep_alive_map->at(origin), 0); + if (new_count == 0) + keep_alive_map->erase(origin); +} + std::ostream& operator<<(std::ostream& out, const KeepAliveRegistry& registry) { out << "{registered_count_=" << registry.registered_count_ << ", restart_allowed_count_=" << registry.restart_allowed_count_
diff --git a/chrome/browser/lifetime/keep_alive_registry.h b/chrome/browser/lifetime/keep_alive_registry.h index 0028ce3..d8a7e4f 100644 --- a/chrome/browser/lifetime/keep_alive_registry.h +++ b/chrome/browser/lifetime/keep_alive_registry.h
@@ -5,7 +5,7 @@ #ifndef CHROME_BROWSER_LIFETIME_KEEP_ALIVE_REGISTRY_H_ #define CHROME_BROWSER_LIFETIME_KEEP_ALIVE_REGISTRY_H_ -#include <map> +#include <unordered_map> #include "base/macros.h" #include "base/memory/singleton.h" @@ -36,6 +36,10 @@ void AddObserver(KeepAliveStateObserver* observer); void RemoveObserver(KeepAliveStateObserver* observer); + // Returns whether restart would be allowed if all the keep alives for the + // provided |origins| were not registered. + bool WouldRestartWithout(const std::vector<KeepAliveOrigin>& origins) const; + private: friend struct base::DefaultSingletonTraits<KeepAliveRegistry>; // Friend to be able to use Register/Unregister @@ -43,6 +47,16 @@ friend std::ostream& operator<<(std::ostream& out, const KeepAliveRegistry& registry); + // TODO(dgn): Remove this when std::hash supports enums directly (c++14) + // http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2148 + struct EnumClassHash { + std::size_t operator()(KeepAliveOrigin origin) const { + return static_cast<int>(origin); + } + }; + + using OriginMap = std::unordered_map<KeepAliveOrigin, int, EnumClassHash>; + KeepAliveRegistry(); ~KeepAliveRegistry(); @@ -54,9 +68,17 @@ void OnKeepAliveStateChanged(bool new_keeping_alive); void OnRestartAllowedChanged(bool new_restart_allowed); + // Unregisters one occurrence of the provided |origin| from |keep_alive_map| + void DecrementCount(KeepAliveOrigin origin, OriginMap* keep_alive_map); + // Tracks the registered KeepAlives, storing the origin and the number of // registered KeepAlives for each. - std::map<KeepAliveOrigin, int> registered_keep_alives_; + OriginMap registered_keep_alives_; + + // Tracks the registered KeepAlives that had KeepAliveRestartOption::ENABLED + // set, storing the origin and the number of restart allowed KeepAlives for + // each origin. + OriginMap restart_allowed_keep_alives_; // Total number of registered KeepAlives int registered_count_;
diff --git a/chrome/browser/lifetime/keep_alive_registry_unittest.cc b/chrome/browser/lifetime/keep_alive_registry_unittest.cc index e20a778..768c3d7 100644 --- a/chrome/browser/lifetime/keep_alive_registry_unittest.cc +++ b/chrome/browser/lifetime/keep_alive_registry_unittest.cc
@@ -137,3 +137,42 @@ EXPECT_EQ(0, on_restart_allowed_call_count_); EXPECT_EQ(0, on_restart_forbidden_call_count_); } + +TEST_F(KeepAliveRegistryTest, WouldRestartWithoutTest) { + // WouldRestartWithout() should have the same results as IsRestartAllowed() + // when called with an empty vector. + std::vector<KeepAliveOrigin> empty_vector; + + // Init and sanity checks. + ScopedKeepAlive kar(KeepAliveOrigin::BACKGROUND_MODE_MANAGER, + KeepAliveRestartOption::ENABLED); + ASSERT_TRUE(registry_->IsRestartAllowed()); + EXPECT_EQ(registry_->IsRestartAllowed(), + registry_->WouldRestartWithout(empty_vector)); + ScopedKeepAlive ka1(KeepAliveOrigin::CHROME_APP_DELEGATE, + KeepAliveRestartOption::DISABLED); + ASSERT_FALSE(registry_->IsRestartAllowed()); + + // Basic case: exclude one KeepAlive. + EXPECT_TRUE( + registry_->WouldRestartWithout({KeepAliveOrigin::CHROME_APP_DELEGATE})); + EXPECT_FALSE(registry_->WouldRestartWithout( + {KeepAliveOrigin::BACKGROUND_MODE_MANAGER})); + + // Check it works properly with multiple KeepAlives of the same type + ScopedKeepAlive ka2(KeepAliveOrigin::CHROME_APP_DELEGATE, + KeepAliveRestartOption::DISABLED); + EXPECT_TRUE( + registry_->WouldRestartWithout({KeepAliveOrigin::CHROME_APP_DELEGATE})); + + // Check it works properly with different KeepAlive types + ScopedKeepAlive ka3(KeepAliveOrigin::PANEL, KeepAliveRestartOption::DISABLED); + EXPECT_FALSE( + registry_->WouldRestartWithout({KeepAliveOrigin::CHROME_APP_DELEGATE})); + EXPECT_FALSE(registry_->WouldRestartWithout( + {KeepAliveOrigin::BACKGROUND_MODE_MANAGER})); + EXPECT_TRUE(registry_->WouldRestartWithout( + {KeepAliveOrigin::CHROME_APP_DELEGATE, KeepAliveOrigin::PANEL})); + EXPECT_EQ(registry_->IsRestartAllowed(), + registry_->WouldRestartWithout(empty_vector)); +}
diff --git a/chrome/browser/local_discovery/service_discovery_device_lister.cc b/chrome/browser/local_discovery/service_discovery_device_lister.cc index 08fdf61..d500ef8 100644 --- a/chrome/browser/local_discovery/service_discovery_device_lister.cc +++ b/chrome/browser/local_discovery/service_discovery_device_lister.cc
@@ -65,7 +65,7 @@ } // If there is already a resolver working on this service, don't add one. - if (ContainsKey(resolvers_, service_name)) { + if (base::ContainsKey(resolvers_, service_name)) { VLOG(1) << "Resolver already exists, service_name: " << service_name; return; }
diff --git a/chrome/browser/media/media_stream_devices_controller.cc b/chrome/browser/media/media_stream_devices_controller.cc index 11d6df95..6b8aa8c 100644 --- a/chrome/browser/media/media_stream_devices_controller.cc +++ b/chrome/browser/media/media_stream_devices_controller.cc
@@ -115,7 +115,7 @@ bool is_secure) { RequestMap::key_type key = std::make_pair(render_process_id, render_frame_id); - if (!ContainsKey(GetRequestMap(), key)) { + if (!base::ContainsKey(GetRequestMap(), key)) { UMA_HISTOGRAM_BOOLEAN("Pepper.SecureOrigin.MediaStreamRequest", is_secure); GetRequestMap()[key] =
diff --git a/chrome/browser/media/router/media_sinks_observer.cc b/chrome/browser/media/router/media_sinks_observer.cc index 524d6e0b..61bb1096f 100644 --- a/chrome/browser/media/router/media_sinks_observer.cc +++ b/chrome/browser/media/router/media_sinks_observer.cc
@@ -44,7 +44,7 @@ base::AutoReset<bool> reset_in_on_sinks_updated(&in_on_sinks_updated_, true); #endif - if (origins.empty() || ContainsValue(origins, origin_)) + if (origins.empty() || base::ContainsValue(origins, origin_)) OnSinksReceived(sinks); else OnSinksReceived(std::vector<MediaSink>());
diff --git a/chrome/browser/media_galleries/fileapi/itunes_data_provider.cc b/chrome/browser/media_galleries/fileapi/itunes_data_provider.cc index e8231ef..c272111 100644 --- a/chrome/browser/media_galleries/fileapi/itunes_data_provider.cc +++ b/chrome/browser/media_galleries/fileapi/itunes_data_provider.cc
@@ -201,7 +201,7 @@ bool ITunesDataProvider::KnownArtist(const ArtistName& artist) const { DCHECK(MediaFileSystemBackend::CurrentlyOnMediaTaskRunnerThread()); DCHECK(valid()); - return ContainsKey(library_, artist); + return base::ContainsKey(library_, artist); } bool ITunesDataProvider::KnownAlbum(const ArtistName& artist, @@ -211,7 +211,7 @@ Library::const_iterator library_it = library_.find(artist); if (library_it == library_.end()) return false; - return ContainsKey(library_it->second, album); + return base::ContainsKey(library_it->second, album); } base::FilePath ITunesDataProvider::GetTrackLocation(
diff --git a/chrome/browser/media_galleries/fileapi/mtp_device_map_service.cc b/chrome/browser/media_galleries/fileapi/mtp_device_map_service.cc index 6941878f..b22022e 100644 --- a/chrome/browser/media_galleries/fileapi/mtp_device_map_service.cc +++ b/chrome/browser/media_galleries/fileapi/mtp_device_map_service.cc
@@ -33,7 +33,7 @@ DCHECK(!filesystem_id.empty()); const AsyncDelegateKey key = GetAsyncDelegateKey(device_location, read_only); - if (!ContainsKey(mtp_device_usage_map_, key)) { + if (!base::ContainsKey(mtp_device_usage_map_, key)) { // Note that this initializes the delegate asynchronously, but since // the delegate will only be used from the IO thread, it is guaranteed // to be created before use of it expects it to be there. @@ -82,7 +82,7 @@ DCHECK(!device_location.empty()); const AsyncDelegateKey key = GetAsyncDelegateKey(device_location, read_only); - if (ContainsKey(async_delegate_map_, key)) + if (base::ContainsKey(async_delegate_map_, key)) return; async_delegate_map_[key] = delegate; }
diff --git a/chrome/browser/media_galleries/fileapi/supported_audio_video_checker.cc b/chrome/browser/media_galleries/fileapi/supported_audio_video_checker.cc index 466e251..2dc8a51 100644 --- a/chrome/browser/media_galleries/fileapi/supported_audio_video_checker.cc +++ b/chrome/browser/media_galleries/fileapi/supported_audio_video_checker.cc
@@ -40,7 +40,7 @@ }; bool HasSupportedAudioVideoExtension(const base::FilePath& file) { - return ContainsKey(audio_video_extensions_, file.Extension()); + return base::ContainsKey(audio_video_extensions_, file.Extension()); } private:
diff --git a/chrome/browser/media_galleries/fileapi/supported_image_type_validator.cc b/chrome/browser/media_galleries/fileapi/supported_image_type_validator.cc index 7a7529ef..d433a58 100644 --- a/chrome/browser/media_galleries/fileapi/supported_image_type_validator.cc +++ b/chrome/browser/media_galleries/fileapi/supported_image_type_validator.cc
@@ -42,7 +42,7 @@ result.reset(new std::string); result->resize(file_info.size); - if (file.Read(0, string_as_array(result.get()), file_info.size) != + if (file.Read(0, base::string_as_array(result.get()), file_info.size) != file_info.size) { result.reset(); }
diff --git a/chrome/browser/media_galleries/gallery_watch_manager.cc b/chrome/browser/media_galleries/gallery_watch_manager.cc index b396cf9..c3147b596 100644 --- a/chrome/browser/media_galleries/gallery_watch_manager.cc +++ b/chrome/browser/media_galleries/gallery_watch_manager.cc
@@ -109,7 +109,7 @@ // This can occur if the GalleryWatchManager attempts to watch the same path // again before recieving the callback. It's benign. - if (ContainsKey(watchers_, path)) { + if (base::ContainsKey(watchers_, path)) { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, base::Bind(callback, false)); return; @@ -196,7 +196,7 @@ GalleryWatchManagerObserver* observer) { DCHECK(browser_context); DCHECK(observer); - DCHECK(!ContainsKey(observers_, browser_context)); + DCHECK(!base::ContainsKey(observers_, browser_context)); observers_[browser_context] = observer; } @@ -241,7 +241,7 @@ DCHECK(extension); WatchOwner owner(browser_context, extension->id(), gallery_id); - if (ContainsKey(watches_, owner)) { + if (base::ContainsKey(watches_, owner)) { callback.Run(std::string()); return; } @@ -250,14 +250,14 @@ g_browser_process->media_file_system_registry()->GetPreferences( Profile::FromBrowserContext(browser_context)); - if (!ContainsKey(preferences->known_galleries(), gallery_id)) { + if (!base::ContainsKey(preferences->known_galleries(), gallery_id)) { callback.Run(kInvalidGalleryIDError); return; } MediaGalleryPrefIdSet permitted = preferences->GalleriesForExtension(*extension); - if (!ContainsKey(permitted, gallery_id)) { + if (!base::ContainsKey(permitted, gallery_id)) { callback.Run(kNoPermissionError); return; } @@ -271,7 +271,7 @@ } // Observe the preferences if we haven't already. - if (!ContainsKey(observed_preferences_, preferences)) { + if (!base::ContainsKey(observed_preferences_, preferences)) { observed_preferences_.insert(preferences); preferences->AddGalleryChangeObserver(this); } @@ -280,7 +280,7 @@ EnsureBrowserContextSubscription(owner.browser_context); // Start the FilePathWatcher on |gallery_path| if necessary. - if (ContainsKey(watched_paths_, path)) { + if (base::ContainsKey(watched_paths_, path)) { OnFileWatchActivated(owner, path, callback, true); } else { base::Callback<void(bool)> on_watch_added = @@ -405,7 +405,7 @@ ++it) { Profile* profile = Profile::FromBrowserContext(it->browser_context); RemoveWatch(it->browser_context, it->extension_id, it->gallery_id); - if (ContainsKey(observers_, profile)) + if (base::ContainsKey(observers_, profile)) observers_[profile]->OnGalleryWatchDropped(it->extension_id, it->gallery_id); } @@ -441,8 +441,8 @@ for (it = notification_info->second.owners.begin(); it != notification_info->second.owners.end(); ++it) { - DCHECK(ContainsKey(watches_, *it)); - if (ContainsKey(observers_, it->browser_context)) { + DCHECK(base::ContainsKey(watches_, *it)); + if (base::ContainsKey(observers_, it->browser_context)) { observers_[it->browser_context]->OnGalleryChanged(it->extension_id, it->gallery_id); } @@ -453,7 +453,7 @@ const std::string& extension_id, MediaGalleryPrefId pref_id) { RemoveWatch(pref->profile(), extension_id, pref_id); - if (ContainsKey(observers_, pref->profile())) + if (base::ContainsKey(observers_, pref->profile())) observers_[pref->profile()]->OnGalleryWatchDropped(extension_id, pref_id); } @@ -473,7 +473,7 @@ it != extension_ids.end(); ++it) { RemoveWatch(pref->profile(), *it, pref_id); - if (ContainsKey(observers_, pref->profile())) + if (base::ContainsKey(observers_, pref->profile())) observers_[pref->profile()]->OnGalleryWatchDropped(*it, pref_id); } } @@ -488,7 +488,7 @@ MediaGalleryPrefIdSet detached_ids = preferences->LookUpGalleriesByDeviceId(info.device_id()); - if (ContainsKey(detached_ids, it->first.gallery_id)) { + if (base::ContainsKey(detached_ids, it->first.gallery_id)) { WatchOwner owner = it->first; DeactivateFileWatch(owner, it->second); // Post increment moves iterator to next element while deleting current.
diff --git a/chrome/browser/media_galleries/gallery_watch_manager_unittest.cc b/chrome/browser/media_galleries/gallery_watch_manager_unittest.cc index 0c7388c..517c852 100644 --- a/chrome/browser/media_galleries/gallery_watch_manager_unittest.cc +++ b/chrome/browser/media_galleries/gallery_watch_manager_unittest.cc
@@ -239,22 +239,22 @@ MediaGalleryPrefIdSet set1 = manager()->GetWatchSet(profile(), extension()->id()); EXPECT_EQ(1u, set1.size()); - EXPECT_TRUE(ContainsKey(set1, id1)); + EXPECT_TRUE(base::ContainsKey(set1, id1)); // Test that the second watch was added correctly too. AddAndConfirmWatch(id2); MediaGalleryPrefIdSet set2 = manager()->GetWatchSet(profile(), extension()->id()); EXPECT_EQ(2u, set2.size()); - EXPECT_TRUE(ContainsKey(set2, id1)); - EXPECT_TRUE(ContainsKey(set2, id2)); + EXPECT_TRUE(base::ContainsKey(set2, id1)); + EXPECT_TRUE(base::ContainsKey(set2, id2)); // Remove first watch and test that the second is still in there. manager()->RemoveWatch(profile(), extension()->id(), id1); MediaGalleryPrefIdSet set3 = manager()->GetWatchSet(profile(), extension()->id()); EXPECT_EQ(1u, set3.size()); - EXPECT_TRUE(ContainsKey(set3, id2)); + EXPECT_TRUE(base::ContainsKey(set3, id2)); // Try removing the first watch again and test that it has no effect. manager()->RemoveWatch(profile(), extension()->id(), id1);
diff --git a/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.cc b/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.cc index 2f417223..1c6b4b5 100644 --- a/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.cc +++ b/chrome/browser/media_galleries/linux/mtp_device_delegate_impl_linux.cc
@@ -426,7 +426,7 @@ file_id_to_node_map_(file_id_to_node_map) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); DCHECK(file_id_to_node_map_); - DCHECK(!ContainsKey(*file_id_to_node_map_, file_id_)); + DCHECK(!base::ContainsKey(*file_id_to_node_map_, file_id_)); (*file_id_to_node_map_)[file_id_] = this; } @@ -461,7 +461,7 @@ std::set<std::string> children_to_erase; for (ChildNodes::const_iterator it = children_.begin(); it != children_.end(); ++it) { - if (ContainsKey(children_to_keep, it->first)) + if (base::ContainsKey(children_to_keep, it->first)) continue; children_to_erase.insert(it->first); }
diff --git a/chrome/browser/media_galleries/linux/mtp_device_task_helper_map_service.cc b/chrome/browser/media_galleries/linux/mtp_device_task_helper_map_service.cc index dfa85e3..dd054d4 100644 --- a/chrome/browser/media_galleries/linux/mtp_device_task_helper_map_service.cc +++ b/chrome/browser/media_galleries/linux/mtp_device_task_helper_map_service.cc
@@ -28,7 +28,7 @@ DCHECK(!storage_name.empty()); const MTPDeviceTaskHelperKey key = GetMTPDeviceTaskHelperKey(storage_name, read_only); - DCHECK(!ContainsKey(task_helper_map_, key)); + DCHECK(!base::ContainsKey(task_helper_map_, key)); MTPDeviceTaskHelper* task_helper = new MTPDeviceTaskHelper(); task_helper_map_[key] = task_helper; return task_helper;
diff --git a/chrome/browser/media_galleries/media_file_system_registry.cc b/chrome/browser/media_galleries/media_file_system_registry.cc index a51aebb0..0fc94d39 100644 --- a/chrome/browser/media_galleries/media_file_system_registry.cc +++ b/chrome/browser/media_galleries/media_file_system_registry.cc
@@ -91,7 +91,7 @@ virtual ~RPHReferenceManager(); // Remove all references, but don't call |no_references_callback|. - void Reset() { STLDeleteValues(&observer_map_); } + void Reset() { base::STLDeleteValues(&observer_map_); } // Returns true if there are no references; bool empty() const { return observer_map_.empty(); } @@ -161,7 +161,7 @@ content::WebContents* contents) { RenderProcessHost* rph = contents->GetRenderProcessHost(); RPHObserver* state = NULL; - if (!ContainsKey(observer_map_, rph)) { + if (!base::ContainsKey(observer_map_, rph)) { state = new RPHObserver(this, rph); observer_map_[rph] = state; } else { @@ -198,14 +198,14 @@ } RPHReferenceManager::RPHObserver::~RPHObserver() { - STLDeleteValues(&observed_web_contentses_); + base::STLDeleteValues(&observed_web_contentses_); if (host_) host_->RemoveObserver(this); } void RPHReferenceManager::RPHObserver::AddWebContentsObserver( WebContents* web_contents) { - if (ContainsKey(observed_web_contentses_, web_contents)) + if (base::ContainsKey(observed_web_contentses_, web_contents)) return; RPHWebContentsObserver* observer = @@ -391,7 +391,7 @@ const MediaGalleryPrefInfo& gallery_info = galleries_info.find(pref_id)->second; const std::string& device_id = gallery_info.device_id; - if (!ContainsKey(*attached_devices, device_id)) + if (!base::ContainsKey(*attached_devices, device_id)) continue; PrefIdFsInfoMap::const_iterator existing_info = @@ -446,7 +446,7 @@ base::FilePath path = gallery.AbsolutePath(); const std::string& device_id = gallery.device_id; - if (ContainsKey(pref_id_map_, gallery.pref_id)) { + if (base::ContainsKey(pref_id_map_, gallery.pref_id)) { result = base::File::FILE_OK; } else if (MediaStorageUtil::CanCreateFileSystem(device_id, path) && file_system_context_->RegisterFileSystem(device_id, fs_name, @@ -561,7 +561,7 @@ preferences->GalleriesForExtension(*extension); if (gallery == preferences->known_galleries().end() || - !ContainsKey(permitted_galleries, pref_id)) { + !base::ContainsKey(permitted_galleries, pref_id)) { BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::Bind(callback, base::File::FILE_ERROR_NOT_FOUND)); @@ -581,9 +581,9 @@ MediaGalleriesPreferences* MediaFileSystemRegistry::GetPreferences( Profile* profile) { // Create an empty ExtensionHostMap for this profile on first initialization. - if (!ContainsKey(extension_hosts_map_, profile)) { + if (!base::ContainsKey(extension_hosts_map_, profile)) { extension_hosts_map_[profile] = ExtensionHostMap(); - DCHECK(!ContainsKey(profile_subscription_map_, profile)); + DCHECK(!base::ContainsKey(profile_subscription_map_, profile)); profile_subscription_map_[profile] = ShutdownNotifierFactory::GetInstance()->Get(profile)->Subscribe( base::Bind(&MediaFileSystemRegistry::OnProfileShutdown, @@ -809,7 +809,7 @@ extension_registry->enabled_extensions().GetByID(it->first)); } for (size_t i = 0; i < extensions.size(); ++i) { - if (!ContainsKey(extension_hosts_map_, profile)) + if (!base::ContainsKey(extension_hosts_map_, profile)) break; ExtensionHostMap::const_iterator gallery_host_it = extension_host_map.find(extensions[i]->id());
diff --git a/chrome/browser/media_galleries/media_file_system_registry_unittest.cc b/chrome/browser/media_galleries/media_file_system_registry_unittest.cc index e607d33..a90cba99 100644 --- a/chrome/browser/media_galleries/media_file_system_registry_unittest.cc +++ b/chrome/browser/media_galleries/media_file_system_registry_unittest.cc
@@ -133,7 +133,7 @@ } void TestMediaFileSystemContext::RevokeFileSystem(const std::string& fs_name) { - if (!ContainsKey(file_systems_by_name_, fs_name)) + if (!base::ContainsKey(file_systems_by_name_, fs_name)) return; EXPECT_EQ(1U, file_systems_by_name_.erase(fs_name)); } @@ -166,7 +166,7 @@ FSInfoMap* results, const std::vector<MediaFileSystemInfo>& file_systems) { for (size_t i = 0; i < file_systems.size(); ++i) { - ASSERT_FALSE(ContainsKey(*results, file_systems[i].pref_id)); + ASSERT_FALSE(base::ContainsKey(*results, file_systems[i].pref_id)); (*results)[file_systems[i].pref_id] = file_systems[i]; } } @@ -397,7 +397,7 @@ MockProfileSharedRenderProcessHostFactory:: ~MockProfileSharedRenderProcessHostFactory() { - STLDeleteValues(&rph_map_); + base::STLDeleteValues(&rph_map_); } content::MockRenderProcessHost* @@ -718,7 +718,7 @@ for (FSInfoMap::const_iterator it = new_galleries_info.begin(); it != new_galleries_info.end(); ++it) { - if (ContainsKey(galleries_info, it->first)) + if (base::ContainsKey(galleries_info, it->first)) continue; ASSERT_FALSE(found_new);
diff --git a/chrome/browser/media_galleries/media_galleries_permission_controller.cc b/chrome/browser/media_galleries/media_galleries_permission_controller.cc index cbd2ab8..b2c4d4b 100644 --- a/chrome/browser/media_galleries/media_galleries_permission_controller.cc +++ b/chrome/browser/media_galleries/media_galleries_permission_controller.cc
@@ -179,8 +179,8 @@ for (GalleryPermissionsMap::const_iterator iter = known_galleries_.begin(); iter != known_galleries_.end(); ++iter) { MediaGalleryPrefId pref_id = GetPrefId(iter->first); - if (!ContainsKey(forgotten_galleries_, iter->first) && - existing == ContainsKey(pref_permitted_galleries_, pref_id)) { + if (!base::ContainsKey(forgotten_galleries_, iter->first) && + existing == base::ContainsKey(pref_permitted_galleries_, pref_id)) { result.push_back(iter->second); } } @@ -246,7 +246,7 @@ GalleryDialogId gallery_id) { media_galleries::UsageCount(media_galleries::DIALOG_FORGET_GALLERY); if (!new_galleries_.erase(gallery_id)) { - DCHECK(ContainsKey(known_galleries_, gallery_id)); + DCHECK(base::ContainsKey(known_galleries_, gallery_id)); forgotten_galleries_.insert(gallery_id); } dialog_->UpdateGalleries(); @@ -399,7 +399,7 @@ iter != pref_permitted_galleries_.end(); ++iter) { GalleryDialogId gallery_id = GetDialogId(*iter); - DCHECK(ContainsKey(known_galleries_, gallery_id)); + DCHECK(base::ContainsKey(known_galleries_, gallery_id)); known_galleries_[gallery_id].selected = true; } @@ -417,7 +417,7 @@ for (GalleryPermissionsMap::const_iterator iter = known_galleries_.begin(); iter != known_galleries_.end(); ++iter) { MediaGalleryPrefId pref_id = GetPrefId(iter->first); - if (ContainsKey(forgotten_galleries_, iter->first)) { + if (base::ContainsKey(forgotten_galleries_, iter->first)) { preferences_->ForgetGalleryById(pref_id); } else { bool changed = preferences_->SetGalleryPermissionForExtension(
diff --git a/chrome/browser/media_galleries/media_galleries_preferences.cc b/chrome/browser/media_galleries/media_galleries_preferences.cc index ad8c7aa..bb6aeb4 100644 --- a/chrome/browser/media_galleries/media_galleries_preferences.cc +++ b/chrome/browser/media_galleries/media_galleries_preferences.cc
@@ -826,7 +826,7 @@ DCHECK(IsInitialized()); DCHECK(extension); if (!include_unpermitted_galleries && - !ContainsKey(GalleriesForExtension(*extension), gallery_id)) + !base::ContainsKey(GalleriesForExtension(*extension), gallery_id)) return base::FilePath(); MediaGalleriesPrefInfoMap::const_iterator it = @@ -1150,7 +1150,7 @@ new ListPrefUpdate(prefs, prefs::kMediaGalleriesRememberedGalleries)); base::ListValue* list = update->Get(); - if (!ContainsKey(known_galleries_, id)) + if (!base::ContainsKey(known_galleries_, id)) return; for (base::ListValue::iterator iter = list->begin(); @@ -1191,7 +1191,7 @@ bool MediaGalleriesPreferences::NonAutoGalleryHasPermission( MediaGalleryPrefId id) const { DCHECK(IsInitialized()); - DCHECK(!ContainsKey(known_galleries_, id) || + DCHECK(!base::ContainsKey(known_galleries_, id) || known_galleries_.find(id)->second.type != MediaGalleryPrefInfo::kAutoDetected); ExtensionPrefs* prefs = GetExtensionPrefs();
diff --git a/chrome/browser/media_galleries/media_galleries_preferences_unittest.cc b/chrome/browser/media_galleries/media_galleries_preferences_unittest.cc index 96becbf..62a7d53 100644 --- a/chrome/browser/media_galleries/media_galleries_preferences_unittest.cc +++ b/chrome/browser/media_galleries/media_galleries_preferences_unittest.cc
@@ -211,8 +211,8 @@ VerifyGalleryInfo(it->second, it->first); if (it->second.type != MediaGalleryPrefInfo::kAutoDetected && it->second.type != MediaGalleryPrefInfo::kBlackListed) { - if (!ContainsKey(expected_galleries_for_all, it->first) && - !ContainsKey(expected_galleries_for_regular, it->first)) { + if (!base::ContainsKey(expected_galleries_for_all, it->first) && + !base::ContainsKey(expected_galleries_for_regular, it->first)) { EXPECT_FALSE(gallery_prefs_->NonAutoGalleryHasPermission(it->first)); } else { EXPECT_TRUE(gallery_prefs_->NonAutoGalleryHasPermission(it->first));
diff --git a/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win_unittest.cc b/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win_unittest.cc index 7d3c38a..7d0f923 100644 --- a/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win_unittest.cc +++ b/chrome/browser/media_galleries/win/mtp_device_delegate_impl_win_unittest.cc
@@ -47,7 +47,7 @@ FSInfoMap* results, const std::vector<MediaFileSystemInfo>& file_systems) { for (size_t i = 0; i < file_systems.size(); ++i) { - ASSERT_FALSE(ContainsKey(*results, file_systems[i].pref_id)); + ASSERT_FALSE(base::ContainsKey(*results, file_systems[i].pref_id)); (*results)[file_systems[i].pref_id] = file_systems[i]; } }
diff --git a/chrome/browser/metrics/chrome_metrics_service_accessor.h b/chrome/browser/metrics/chrome_metrics_service_accessor.h index f5b94e72..b27ce9f 100644 --- a/chrome/browser/metrics/chrome_metrics_service_accessor.h +++ b/chrome/browser/metrics/chrome_metrics_service_accessor.h
@@ -62,6 +62,10 @@ class SRTGlobalError; } +namespace settings { +class MetricsReportingHandler; +} + namespace speech { class ChromeSpeechRecognitionManagerDelegate; } @@ -94,6 +98,7 @@ friend class options::BrowserOptionsHandler; friend bool prerender::IsOmniboxEnabled(Profile* profile); friend class safe_browsing::IncidentReportingService; + friend class settings::MetricsReportingHandler; friend class speech::ChromeSpeechRecognitionManagerDelegate; friend class StackSamplingConfiguration; friend class system_logs::ChromeInternalLogSource;
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc index da34086..968ad63 100644 --- a/chrome/browser/metrics/chrome_metrics_service_client.cc +++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -61,7 +61,7 @@ #include "components/omnibox/browser/omnibox_metrics_provider.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" -#include "components/sync_driver/device_count_metrics_provider.h" +#include "components/sync/driver/device_count_metrics_provider.h" #include "components/version_info/version_info.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/histogram_fetcher.h" @@ -91,6 +91,7 @@ #if defined(OS_WIN) #include <windows.h> + #include "chrome/browser/metrics/antivirus_metrics_provider_win.h" #include "chrome/browser/metrics/google_update_metrics_provider_win.h" #include "chrome/common/metrics_constants_util_win.h"
diff --git a/chrome/browser/metrics/metrics_service_browsertest.cc b/chrome/browser/metrics/metrics_service_browsertest.cc index 9f329da..2ba8c021 100644 --- a/chrome/browser/metrics/metrics_service_browsertest.cc +++ b/chrome/browser/metrics/metrics_service_browsertest.cc
@@ -60,14 +60,7 @@ } }; -// Flaky failing DCHECK on Windows, see crbug.com/636052 -#if defined(OS_WIN) -#define MAYBE_CloseRenderersNormally DISABLED_CloseRenderersNormally -#else -#define MAYBE_CloseRenderersNormally CloseRenderersNormally -#endif -IN_PROC_BROWSER_TEST_F(MetricsServiceBrowserTest, - MAYBE_CloseRenderersNormally) { +IN_PROC_BROWSER_TEST_F(MetricsServiceBrowserTest, CloseRenderersNormally) { OpenTabs(); // Verify that the expected stability metrics were recorded. @@ -84,8 +77,7 @@ // Flaky on Linux. See http://crbug.com/131094 // Child crashes fail the process on ASan (see crbug.com/411251, // crbug.com/368525). -// Flaky failing DCHECK on Windows, see crbug.com/635770 -#if defined(OS_LINUX) || defined(ADDRESS_SANITIZER) || defined(OS_WIN) +#if defined(OS_LINUX) || defined(ADDRESS_SANITIZER) #define MAYBE_CrashRenderers DISABLED_CrashRenderers #else #define MAYBE_CrashRenderers CrashRenderers @@ -120,3 +112,4 @@ // is set to true, but this preference isn't set until the browser // exits... it's not clear to me how to test that. } +
diff --git a/chrome/browser/metrics/plugin_metrics_provider.cc b/chrome/browser/metrics/plugin_metrics_provider.cc index ca0c3be..ebd235a5 100644 --- a/chrome/browser/metrics/plugin_metrics_provider.cc +++ b/chrome/browser/metrics/plugin_metrics_provider.cc
@@ -334,7 +334,7 @@ PluginMetricsProvider::GetChildProcessStats( const content::ChildProcessData& data) { const base::string16& child_name = data.name; - if (!ContainsKey(child_process_stats_buffer_, child_name)) { + if (!base::ContainsKey(child_process_stats_buffer_, child_name)) { child_process_stats_buffer_[child_name] = ChildProcessStats(data.process_type); }
diff --git a/chrome/browser/net/predictor.cc b/chrome/browser/net/predictor.cc index ff6b83ac..6070a1042 100644 --- a/chrome/browser/net/predictor.cc +++ b/chrome/browser/net/predictor.cc
@@ -15,6 +15,7 @@ #include "base/callback.h" #include "base/compiler_specific.h" #include "base/containers/mru_cache.h" +#include "base/feature_list.h" #include "base/location.h" #include "base/logging.h" #include "base/macros.h" @@ -56,6 +57,13 @@ namespace chrome_browser_net { +namespace { + +const base::Feature kNetworkPrediction{"NetworkPrediction", + base::FEATURE_ENABLED_BY_DEFAULT}; + +} // namespace + // static const int Predictor::kPredictorReferrerVersion = 2; const double Predictor::kPreconnectWorthyExpectedValue = 0.8; @@ -92,7 +100,7 @@ // we change the format so that we discard old data. static const int kPredictorStartupFormatVersion = 1; -Predictor::Predictor(bool preconnect_enabled, bool predictor_enabled) +Predictor::Predictor(bool predictor_enabled) : url_request_context_getter_(nullptr), predictor_enabled_(predictor_enabled), user_prefs_(nullptr), @@ -106,7 +114,6 @@ transport_security_state_(nullptr), ssl_config_service_(nullptr), proxy_service_(nullptr), - preconnect_enabled_(preconnect_enabled), consecutive_omnibox_preconnect_count_(0), referrers_(kMaxReferrers), observer_(nullptr), @@ -122,12 +129,11 @@ } // static -Predictor* Predictor::CreatePredictor(bool preconnect_enabled, - bool predictor_enabled, - bool simple_shutdown) { +Predictor* Predictor::CreatePredictor(bool simple_shutdown) { + bool predictor_enabled = base::FeatureList::IsEnabled(kNetworkPrediction); if (simple_shutdown) - return new SimplePredictor(preconnect_enabled, predictor_enabled); - return new Predictor(preconnect_enabled, predictor_enabled); + return new SimplePredictor(predictor_enabled); + return new Predictor(predictor_enabled); } void Predictor::RegisterProfilePrefs( @@ -165,7 +171,7 @@ void Predictor::AnticipateOmniboxUrl(const GURL& url, bool preconnectable) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!predictor_enabled_) + if (!PredictorEnabled()) return; if (!url.is_valid() || !url.has_host()) return; @@ -179,45 +185,41 @@ UrlInfo::ResolutionMotivation motivation(UrlInfo::OMNIBOX_MOTIVATED); base::TimeTicks now = base::TimeTicks::Now(); - if (PreconnectEnabled()) { - if (preconnectable && !is_new_host_request) { - ++consecutive_omnibox_preconnect_count_; - // The omnibox suggests a search URL (for which we can preconnect) after - // one or two characters are typed, even though such typing often (1 in - // 3?) becomes a real URL. This code waits till is has more evidence of a - // preconnectable URL (search URL) before forming a preconnection, so as - // to reduce the useless preconnect rate. - // Perchance this logic should be pushed back into the omnibox, where the - // actual characters typed, such as a space, can better forcast whether - // we need to search/preconnect or not. By waiting for at least 4 - // characters in a row that have lead to a search proposal, we avoid - // preconnections for a prefix like "www." and we also wait until we have - // at least a 4 letter word to search for. - // Each character typed appears to induce 2 calls to - // AnticipateOmniboxUrl(), so we double 4 characters and limit at 8 - // requests. - // TODO(jar): Use an A/B test to optimize this. - const int kMinConsecutiveRequests = 8; - if (consecutive_omnibox_preconnect_count_ >= kMinConsecutiveRequests) { - // TODO(jar): Perhaps we should do a GET to leave the socket open in the - // pool. Currently, we just do a connect, which MAY be reset if we - // don't use it in 10 secondes!!! As a result, we may do more - // connections, and actually cost the server more than if we did a real - // get with a fake request (/gen_204 might be the good path on Google). - const int kMaxSearchKeepaliveSeconds(10); - if ((now - last_omnibox_preconnect_).InSeconds() < - kMaxSearchKeepaliveSeconds) - return; // We've done a preconnect recently. - last_omnibox_preconnect_ = now; - const int kConnectionsNeeded = 1; - PreconnectUrl(CanonicalizeUrl(url), GURL(), motivation, - kAllowCredentialsOnPreconnectByDefault, - kConnectionsNeeded); - return; // Skip pre-resolution, since we'll open a connection. - } - } else { - consecutive_omnibox_preconnect_count_ = 0; + if (preconnectable && !is_new_host_request) { + ++consecutive_omnibox_preconnect_count_; + // The omnibox suggests a search URL (for which we can preconnect) after + // one or two characters are typed, even though such typing often (1 in + // 3?) becomes a real URL. This code waits till is has more evidence of a + // preconnectable URL (search URL) before forming a preconnection, so as + // to reduce the useless preconnect rate. + // Perchance this logic should be pushed back into the omnibox, where the + // actual characters typed, such as a space, can better forcast whether + // we need to search/preconnect or not. By waiting for at least 4 + // characters in a row that have lead to a search proposal, we avoid + // preconnections for a prefix like "www." and we also wait until we have + // at least a 4 letter word to search for. + // Each character typed appears to induce 2 calls to AnticipateOmniboxUrl(), + // so we double 4 characters and limit at 8 requests. + // TODO(jar): Use an A/B test to optimize this. + const int kMinConsecutiveRequests = 8; + if (consecutive_omnibox_preconnect_count_ >= kMinConsecutiveRequests) { + // TODO(jar): Perhaps we should do a GET to leave the socket open in the + // pool. Currently, we just do a connect, which MAY be reset if we + // don't use it in 10 secondes!!! As a result, we may do more + // connections, and actually cost the server more than if we did a real + // get with a fake request (/gen_204 might be the good path on Google). + const int kMaxSearchKeepaliveSeconds(10); + if ((now - last_omnibox_preconnect_).InSeconds() < + kMaxSearchKeepaliveSeconds) + return; // We've done a preconnect recently. + last_omnibox_preconnect_ = now; + const int kConnectionsNeeded = 1; + PreconnectUrl(CanonicalizeUrl(url), GURL(), motivation, + kAllowCredentialsOnPreconnectByDefault, kConnectionsNeeded); + return; // Skip pre-resolution, since we'll open a connection. } + } else { + consecutive_omnibox_preconnect_count_ = 0; } // Fall through and consider pre-resolution. @@ -233,8 +235,7 @@ last_omnibox_preresolve_ = now; BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, + BrowserThread::IO, FROM_HERE, base::Bind(&Predictor::Resolve, base::Unretained(this), CanonicalizeUrl(url), motivation)); } @@ -243,7 +244,7 @@ const GURL& first_party_for_cookies) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || BrowserThread::CurrentlyOn(BrowserThread::IO)); - if (!predictor_enabled_ || !PreconnectEnabled() || !url.is_valid() || + if (!PredictorEnabled() || !url.is_valid() || !url.has_host()) return; if (!CanPreresolveAndPreconnect()) @@ -415,7 +416,7 @@ void Predictor::LearnFromNavigation(const GURL& referring_url, const GURL& target_url) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (!predictor_enabled_ || !CanPreresolveAndPreconnect()) + if (!PredictorEnabled() || !CanPreresolveAndPreconnect()) return; DCHECK_EQ(referring_url, Predictor::CanonicalizeUrl(referring_url)); DCHECK_NE(referring_url, GURL::EmptyGURL()); @@ -449,7 +450,7 @@ // We'd like the following no-cache... but it doesn't work. // "<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">" "</head><body>"); - if (predictor && predictor->predictor_enabled() && + if (predictor && predictor->PredictorEnabled() && predictor->CanPreresolveAndPreconnect()) { predictor->GetHtmlInfo(output); } else { @@ -628,7 +629,7 @@ void Predictor::LearnAboutInitialNavigation(const GURL& url) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - if (!predictor_enabled_ || nullptr == initial_observer_.get() || + if (!PredictorEnabled() || nullptr == initial_observer_.get() || !CanPreresolveAndPreconnect()) { return; } @@ -657,7 +658,7 @@ UrlInfo::ResolutionMotivation motivation) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || BrowserThread::CurrentlyOn(BrowserThread::IO)); - if (!predictor_enabled_) + if (!PredictorEnabled()) return; if (!CanPreresolveAndPreconnect()) return; @@ -679,7 +680,7 @@ void Predictor::SaveStateForNextStartup() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (!predictor_enabled_) + if (!PredictorEnabled()) return; if (!CanPreresolveAndPreconnect()) return; @@ -792,7 +793,7 @@ const GURL& first_party_for_cookies) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || BrowserThread::CurrentlyOn(BrowserThread::IO)); - if (!predictor_enabled_) + if (!PredictorEnabled()) return; if (!CanPreresolveAndPreconnect()) return; @@ -845,6 +846,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_EQ(url.GetWithEmptyPath(), url); + DCHECK(PredictorEnabled()); // Peek here, and Get after logging the index into the MRU. Referrers::iterator it = referrers_.Get(url); if (referrers_.end() == it) { @@ -854,11 +856,9 @@ // size of the list with all the "Leaf" nodes in the tree (nodes that don't // load any subresources). If we learn about this resource, we will instead // provide a more carefully estimated preconnection count. - if (PreconnectEnabled()) { - PreconnectUrlOnIOThread(url, first_party_for_cookies, - UrlInfo::SELF_REFERAL_MOTIVATED, - kAllowCredentialsOnPreconnectByDefault, 2); - } + PreconnectUrlOnIOThread(url, first_party_for_cookies, + UrlInfo::SELF_REFERAL_MOTIVATED, + kAllowCredentialsOnPreconnectByDefault, 2); return; } Referrer* referrer = &(it->second); @@ -874,8 +874,7 @@ static_cast<int>(connection_expectation * 100), 10, 5000, 50); future_url->second.ReferrerWasObserved(); - if (PreconnectEnabled() && - connection_expectation > kPreconnectWorthyExpectedValue) { + if (connection_expectation > kPreconnectWorthyExpectedValue) { evalution = PRECONNECTION; future_url->second.IncrementPreconnectionCount(); int count = static_cast<int>(std::ceil(connection_expectation)); @@ -1062,14 +1061,14 @@ //----------------------------------------------------------------------------- -bool Predictor::PreconnectEnabled() const { - base::AutoLock lock(preconnect_enabled_lock_); - return preconnect_enabled_; +bool Predictor::PredictorEnabled() const { + base::AutoLock lock(predictor_enabled_lock_); + return predictor_enabled_; } -void Predictor::SetPreconnectEnabledForTest(bool preconnect_enabled) { - base::AutoLock lock(preconnect_enabled_lock_); - preconnect_enabled_ = preconnect_enabled; +void Predictor::SetPredictorEnabledForTest(bool predictor_enabled) { + base::AutoLock lock(predictor_enabled_lock_); + predictor_enabled_ = predictor_enabled; } Predictor::HostNameQueue::HostNameQueue() {
diff --git a/chrome/browser/net/predictor.h b/chrome/browser/net/predictor.h index 572f19c8..7023275 100644 --- a/chrome/browser/net/predictor.h +++ b/chrome/browser/net/predictor.h
@@ -124,17 +124,14 @@ // The maximum size of the MRU cache of referrers. static const int kMaxReferrers; - // |max_concurrent| specifies how many concurrent (parallel) prefetches will - // be performed. Host lookups will be issued through |host_resolver|. - explicit Predictor(bool preconnect_enabled, bool predictor_enabled); + explicit Predictor(bool predictor_enabled); virtual ~Predictor(); // This function is used to create a predictor. For testing, we can create // a version which does a simpler shutdown. - static Predictor* CreatePredictor(bool preconnect_enabled, - bool predictor_enabled, - bool simple_shutdown); + // TODO(636128): This method should return a unique_ptr. + static Predictor* CreatePredictor(bool simple_shutdown); static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); @@ -299,15 +296,11 @@ return profile_io_data_; } - bool predictor_enabled() const { - return predictor_enabled_; - } + bool PredictorEnabled() const; - bool PreconnectEnabled() const; - - // Used only for testing. Overrides command line flag to disable preconnect, - // which is added in the browser test fixture. - void SetPreconnectEnabledForTest(bool preconnect_enabled); + // Used only for testing. Overrides command line flag to disable the + // predictor, which is added in the browser test fixture. + void SetPredictorEnabledForTest(bool predictor_enabled); net::URLRequestContextGetter* url_request_context_getter_for_test() { return url_request_context_getter_.get(); @@ -466,7 +459,9 @@ // Status of speculative DNS resolution and speculative TCP/IP connection // feature. This is false if and only if disabled by a command line switch. - const bool predictor_enabled_; + // Protected by |preconnect_enabled_lock_|, which is used by tests to bypass + // the command line flags. + bool predictor_enabled_; // This is set by InitNetworkPredictor and used for calling // CanPrefetchAndPrerenderUI and CanPreresolveAndPreconnectUI. @@ -510,12 +505,6 @@ // The ProxyService, used to determine whether preresolve is useful. net::ProxyService* proxy_service_; - // Are we currently using preconnection, rather than just DNS resolution, for - // subresources and omni-box search URLs. This is false if and only if - // disabled by a command line switch. Protected by |preconnect_enabled_lock_|, - // which is used by tests to bypass the command line flags. - bool preconnect_enabled_; - // Most recent suggestion from Omnibox provided via AnticipateOmniboxUrl(). std::string last_omnibox_host_; @@ -552,8 +541,8 @@ // thread. std::unique_ptr<base::WeakPtrFactory<Predictor>> ui_weak_factory_; - // Protects |preconnect_enabled_|. - mutable base::Lock preconnect_enabled_lock_; + // Protects |predictor_enabled_|. + mutable base::Lock predictor_enabled_lock_; DISALLOW_COPY_AND_ASSIGN(Predictor); }; @@ -561,8 +550,8 @@ // This version of the predictor is used for testing. class SimplePredictor : public Predictor { public: - explicit SimplePredictor(bool preconnect_enabled, bool predictor_enabled) - : Predictor(preconnect_enabled, predictor_enabled) {} + explicit SimplePredictor(bool predictor_enabled) + : Predictor(predictor_enabled) {} ~SimplePredictor() override {} void InitNetworkPredictor(PrefService* user_prefs, IOThread* io_thread,
diff --git a/chrome/browser/net/predictor_browsertest.cc b/chrome/browser/net/predictor_browsertest.cc index d4f63569..9003400 100644 --- a/chrome/browser/net/predictor_browsertest.cc +++ b/chrome/browser/net/predictor_browsertest.cc
@@ -402,8 +402,8 @@ bool HasHostBeenLookedUpLocked(const GURL& url) { lock_.AssertAcquired(); - return ContainsKey(successful_dns_lookups_, url) || - ContainsKey(unsuccessful_dns_lookups_, url); + return base::ContainsKey(successful_dns_lookups_, url) || + base::ContainsKey(unsuccessful_dns_lookups_, url); } bool HasHostBeenLookedUp(const GURL& url) { @@ -434,7 +434,7 @@ base::AutoLock lock(lock_); EXPECT_TRUE(HasHostBeenLookedUpLocked(url)) << "Expected to have looked up " << url.spec(); - return ContainsKey(successful_dns_lookups_, url); + return base::ContainsKey(successful_dns_lookups_, url); } void set_task_runner( @@ -532,7 +532,7 @@ base::Bind(&RedirectForPathHandler, "/", cross_site_test_server()->GetURL("/title1.html"))); - predictor()->SetPreconnectEnabledForTest(true); + predictor()->SetPredictorEnabledForTest(true); InstallPredictorObserver(embedded_test_server()->base_url(), cross_site_test_server()->base_url()); observer()->set_task_runner(task_runner_); @@ -726,7 +726,7 @@ } void ExpectUrlRequestedFromPredictor(const GURL& url) { - EXPECT_TRUE(ContainsKey(predictor()->results_, url)); + EXPECT_TRUE(base::ContainsKey(predictor()->results_, url)); } void DiscardAllResultsOnUIThread() { @@ -1371,9 +1371,14 @@ PrepareFrameSubresources(referring_url_); observer()->WaitUntilHostLookedUp(target_url_); - // Verify that both urls were requested by the predictor. Note that the - // startup URL may be requested before the observer attaches itself. - ExpectUrlRequestedFromPredictor(startup_url_); + // Since the predictor is only enabled after startup, just ensure that + // |startup_url_| is persisted in the prefs. + std::string startup_list; + GetListFromPrefsAsString(prefs::kDnsPrefetchingStartupList, + &startup_list); + EXPECT_THAT(startup_list, HasSubstr(startup_url_.host())); + + // Verify that the |target_url_| is requested by the predictor. EXPECT_FALSE(observer()->HostFound(target_url_)); }
diff --git a/chrome/browser/net/predictor_unittest.cc b/chrome/browser/net/predictor_unittest.cc index 9a6939e0..02131208 100644 --- a/chrome/browser/net/predictor_unittest.cc +++ b/chrome/browser/net/predictor_unittest.cc
@@ -145,13 +145,13 @@ } TEST_F(PredictorTest, StartupShutdownTest) { - Predictor testing_master(true, true); + Predictor testing_master(true); testing_master.Shutdown(); } // Make sure nil referral lists really have no entries, and no latency listed. TEST_F(PredictorTest, ReferrerSerializationNilTest) { - Predictor predictor(true, true); + Predictor predictor(true); std::unique_ptr<base::ListValue> referral_list(new base::ListValue); predictor.SerializeReferrers(referral_list.get()); @@ -167,7 +167,7 @@ // deserialized into the database, and can be extracted back out via // serialization without being changed. TEST_F(PredictorTest, ReferrerSerializationSingleReferrerTest) { - Predictor predictor(true, true); + Predictor predictor(true); const GURL motivation_url("http://www.google.com:91"); const GURL subresource_url("http://icons.google.com:90"); const double kUseRate = 23.4; @@ -191,7 +191,7 @@ // Test that the referrers are sorted in MRU order in the HTML UI. TEST_F(PredictorTest, GetHtmlReferrerLists) { - SimplePredictor predictor(true, true); + SimplePredictor predictor(true); predictor.LearnFromNavigation(GURL("http://www.source_b.test"), GURL("http://www.target_b.test")); @@ -220,7 +220,7 @@ // Expect the exact same HTML when the predictor's referrers are serialized and // deserialized (implies ordering remains the same). TEST_F(PredictorTest, SerializeAndDeserialize) { - SimplePredictor predictor(true, true); + SimplePredictor predictor(true); for (int i = 0; i < Predictor::kMaxReferrers * 2; ++i) { predictor.LearnFromNavigation( @@ -244,7 +244,7 @@ // Filling the MRU cache should evict entries that were used less recently. TEST_F(PredictorTest, FillMRUCache) { - SimplePredictor predictor(true, true); + SimplePredictor predictor(true); for (int i = 0; i < Predictor::kMaxReferrers * 2; ++i) { predictor.LearnFromNavigation( @@ -376,7 +376,7 @@ } TEST_F(PredictorTest, DiscardPredictorResults) { - SimplePredictor predictor(true, true); + SimplePredictor predictor(true); base::ListValue referral_list; predictor.SerializeReferrers(&referral_list); EXPECT_EQ(1U, referral_list.GetSize()); @@ -420,7 +420,7 @@ net::TransportSecurityState state; state.AddHSTS(kHttpUrl.host(), expiry, false); - Predictor predictor(true, true); + Predictor predictor(true); TestPredictorObserver observer; predictor.SetObserver(&observer); predictor.SetTransportSecurityState(&state); @@ -446,7 +446,7 @@ net::TransportSecurityState state; state.AddHSTS(kHttpUrl.host(), expiry, false); - SimplePredictor predictor(true, true); + SimplePredictor predictor(true); TestPredictorObserver observer; predictor.SetObserver(&observer); predictor.SetTransportSecurityState(&state); @@ -474,7 +474,7 @@ net::TransportSecurityState state; state.AddHSTS(kHttpUrl.host(), expiry, false); - SimplePredictor predictor(true, true); + SimplePredictor predictor(true); TestPredictorObserver observer; predictor.SetObserver(&observer); predictor.SetTransportSecurityState(&state); @@ -495,7 +495,7 @@ // Don't actually try to resolve names. Predictor::set_max_parallel_resolves(0); - Predictor testing_master(true, true); + Predictor testing_master(true); GURL goog("http://www.google.com:80"); testing_master.Resolve(goog, UrlInfo::OMNIBOX_MOTIVATED); @@ -508,7 +508,7 @@ // Don't actually try to resolve names. Predictor::set_max_parallel_resolves(0); - Predictor testing_master(true, true); + Predictor testing_master(true); net::ProxyConfig config; config.proxy_rules().ParseFromString("http=socks://localhost:12345"); @@ -529,7 +529,7 @@ // Don't actually try to resolve names. Predictor::set_max_parallel_resolves(0); - Predictor testing_master(true, true); + Predictor testing_master(true); net::ProxyConfig config = net::ProxyConfig::CreateDirect(); std::unique_ptr<net::ProxyService> proxy_service( net::ProxyService::CreateFixed(config)); @@ -548,7 +548,7 @@ // Don't actually try to resolve names. Predictor::set_max_parallel_resolves(0); - Predictor testing_master(true, true); + Predictor testing_master(true); net::ProxyConfig config = net::ProxyConfig::CreateFromCustomPacURL(GURL( "http://foopy/proxy.pac")); std::unique_ptr<net::ProxyService> proxy_service(
diff --git a/chrome/browser/notifications/message_center_notification_manager.cc b/chrome/browser/notifications/message_center_notification_manager.cc index b032ec2..99cc590 100644 --- a/chrome/browser/notifications/message_center_notification_manager.cc +++ b/chrome/browser/notifications/message_center_notification_manager.cc
@@ -78,8 +78,8 @@ message_center_->SetNotifierSettingsProvider(NULL); message_center_->RemoveObserver(this); - STLDeleteContainerPairSecondPointers(profile_notifications_.begin(), - profile_notifications_.end()); + base::STLDeleteContainerPairSecondPointers(profile_notifications_.begin(), + profile_notifications_.end()); profile_notifications_.clear(); }
diff --git a/chrome/browser/notifications/message_center_settings_controller_unittest.cc b/chrome/browser/notifications/message_center_settings_controller_unittest.cc index ea47722..e3b05ede 100644 --- a/chrome/browser/notifications/message_center_settings_controller_unittest.cc +++ b/chrome/browser/notifications/message_center_settings_controller_unittest.cc
@@ -293,7 +293,7 @@ EXPECT_EQ(kBarId, notifiers[0]->notifier_id.id); EXPECT_EQ(kFooId, notifiers[1]->notifier_id.id); - STLDeleteElements(¬ifiers); + base::STLDeleteElements(¬ifiers); } TEST_F(MessageCenterSettingsControllerTest, SetWebPageNotifierEnabled) {
diff --git a/chrome/browser/notifications/platform_notification_service_impl.cc b/chrome/browser/notifications/platform_notification_service_impl.cc index 4f38094..4408a1c0 100644 --- a/chrome/browser/notifications/platform_notification_service_impl.cc +++ b/chrome/browser/notifications/platform_notification_service_impl.cc
@@ -281,6 +281,12 @@ base::Closure* cancel_callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + // Posted tasks can request notifications to be added, which would cause a + // crash (see |ScopedKeepAlive|). We just do nothing here, the user would not + // see the notification anyway, since we are shutting down. + if (g_browser_process->IsShuttingDown()) + return; + Profile* profile = Profile::FromBrowserContext(browser_context); DCHECK(profile); DCHECK_EQ(0u, notification_data.actions.size()); @@ -320,6 +326,12 @@ const content::NotificationResources& notification_resources) { DCHECK_CURRENTLY_ON(BrowserThread::UI); + // Posted tasks can request notifications to be added, which would cause a + // crash (see |ScopedKeepAlive|). We just do nothing here, the user would not + // see the notification anyway, since we are shutting down. + if (g_browser_process->IsShuttingDown()) + return; + Profile* profile = Profile::FromBrowserContext(browser_context); DCHECK(profile);
diff --git a/chrome/browser/ntp_snippets/bookmark_last_visit_updater.cc b/chrome/browser/ntp_snippets/bookmark_last_visit_updater.cc index 001e8e2..6b9b6f01 100644 --- a/chrome/browser/ntp_snippets/bookmark_last_visit_updater.cc +++ b/chrome/browser/ntp_snippets/bookmark_last_visit_updater.cc
@@ -4,12 +4,16 @@ #include "chrome/browser/ntp_snippets/bookmark_last_visit_updater.h" +#include "components/bookmarks/browser/bookmark_model.h" +#include "components/bookmarks/browser/bookmark_node.h" #include "components/ntp_snippets/bookmarks/bookmark_last_visit_utils.h" #include "content/public/browser/navigation_handle.h" DEFINE_WEB_CONTENTS_USER_DATA_KEY(BookmarkLastVisitUpdater); -BookmarkLastVisitUpdater::~BookmarkLastVisitUpdater() {} +BookmarkLastVisitUpdater::~BookmarkLastVisitUpdater() { + bookmark_model_->RemoveObserver(this); +} // static void BookmarkLastVisitUpdater::CreateForWebContentsWithBookmarkModel( @@ -23,12 +27,43 @@ content::WebContents* web_contents, bookmarks::BookmarkModel* bookmark_model) : content::WebContentsObserver(web_contents), - bookmark_model_(bookmark_model) {} + bookmark_model_(bookmark_model), + web_contents_(web_contents) { + bookmark_model->AddObserver(this); +} void BookmarkLastVisitUpdater::DidStartNavigation( content::NavigationHandle* navigation_handle) { + // Mark visited bookmark when the navigation starts (may end somewhere else + // due to server-side redirects). + NewURLVisited(navigation_handle); +} + +void BookmarkLastVisitUpdater::DidRedirectNavigation( + content::NavigationHandle* navigation_handle) { + // Mark visited bookmark also after each redirect. + NewURLVisited(navigation_handle); +} + +void BookmarkLastVisitUpdater::NewURLVisited( + content::NavigationHandle* navigation_handle) { if (!navigation_handle->IsInMainFrame() || navigation_handle->IsErrorPage()) return; + ntp_snippets::UpdateBookmarkOnURLVisitedInMainFrame( bookmark_model_, navigation_handle->GetURL()); } + +void BookmarkLastVisitUpdater::BookmarkNodeAdded( + bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* parent, + int index) { + const GURL& new_bookmark_url = parent->GetChild(index)->url(); + + if (new_bookmark_url == web_contents_->GetLastCommittedURL()) { + // Consider in this TabHelper only bookmarks created from this tab (and not + // the ones created from other tabs or created through bookmark sync). + ntp_snippets::UpdateBookmarkOnURLVisitedInMainFrame( + bookmark_model_, new_bookmark_url); + } +}
diff --git a/chrome/browser/ntp_snippets/bookmark_last_visit_updater.h b/chrome/browser/ntp_snippets/bookmark_last_visit_updater.h index ff9aa9b..38422fb6 100644 --- a/chrome/browser/ntp_snippets/bookmark_last_visit_updater.h +++ b/chrome/browser/ntp_snippets/bookmark_last_visit_updater.h
@@ -6,13 +6,16 @@ #define CHROME_BROWSER_NTP_SNIPPETS_BOOKMARK_LAST_VISIT_UPDATER_H_ #include <memory> +#include <set> #include "base/macros.h" +#include "components/bookmarks/browser/bookmark_model_observer.h" #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" namespace bookmarks { class BookmarkModel; +class BookmarkNode; } // namespace bookmarks namespace content { @@ -24,7 +27,8 @@ // generic function ntp_snippets::UpdateBookmarkOnURLVisitedInMainFrame(). class BookmarkLastVisitUpdater : public content::WebContentsObserver, - public content::WebContentsUserData<BookmarkLastVisitUpdater> { + public content::WebContentsUserData<BookmarkLastVisitUpdater>, + public bookmarks::BookmarkModelObserver { public: ~BookmarkLastVisitUpdater() override; @@ -38,11 +42,45 @@ BookmarkLastVisitUpdater(content::WebContents* web_contents, bookmarks::BookmarkModel* bookmark_model); + // Overridden from BookmarkModelObserver: + void BookmarkModelLoaded(bookmarks::BookmarkModel* model, + bool ids_reassigned) override {} + void BookmarkNodeMoved(bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* old_parent, + int old_index, + const bookmarks::BookmarkNode* new_parent, + int new_index) override {} + void BookmarkNodeAdded(bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* parent, + int index) override; + void BookmarkNodeRemoved( + bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* parent, + int old_index, + const bookmarks::BookmarkNode* node, + const std::set<GURL>& no_longer_bookmarked) override {} + void BookmarkNodeChanged(bookmarks::BookmarkModel* model, + 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 {} + void BookmarkNodeFaviconChanged( + bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* node) override {} + // Overridden from content::WebContentsObserver: void DidStartNavigation( content::NavigationHandle* navigation_handle) override; + void DidRedirectNavigation( + content::NavigationHandle* navigation_handle) override; + + void NewURLVisited(content::NavigationHandle* navigation_handle); bookmarks::BookmarkModel* bookmark_model_; + content::WebContents* web_contents_; DISALLOW_COPY_AND_ASSIGN(BookmarkLastVisitUpdater); };
diff --git a/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc b/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc index 9d30964..afa227d 100644 --- a/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc +++ b/chrome/browser/ntp_snippets/content_suggestions_service_factory.cc
@@ -126,15 +126,23 @@ #if defined(OS_ANDROID) // Create the OfflinePageSuggestionsProvider. - if (base::FeatureList::IsEnabled( - ntp_snippets::kOfflinePageSuggestionsFeature)) { + bool recent_tabs_enabled = base::FeatureList::IsEnabled( + ntp_snippets::kRecentOfflineTabSuggestionsFeature); + bool downloads_enabled = + base::FeatureList::IsEnabled(ntp_snippets::kDownloadSuggestionsFeature); + bool download_manager_ui_enabled = + base::FeatureList::IsEnabled(chrome::android::kDownloadsUiFeature); + if (recent_tabs_enabled || downloads_enabled) { OfflinePageModel* offline_page_model = OfflinePageModelFactory::GetForBrowserContext(profile); std::unique_ptr<OfflinePageSuggestionsProvider> offline_page_suggestions_provider = base::MakeUnique<OfflinePageSuggestionsProvider>( - service, service->category_factory(), offline_page_model); + recent_tabs_enabled, downloads_enabled, + download_manager_ui_enabled, service, + service->category_factory(), offline_page_model, + profile->GetPrefs()); service->RegisterProvider(std::move(offline_page_suggestions_provider)); } #endif // OS_ANDROID @@ -180,7 +188,7 @@ suggestions_service, g_browser_process->GetApplicationLocale(), scheduler, base::MakeUnique<NTPSnippetsFetcher>( signin_manager, token_service, request_context, - profile->GetPrefs(), + profile->GetPrefs(), service->category_factory(), base::Bind(&safe_json::SafeJsonParser::Parse), is_stable_channel), base::MakeUnique<ImageFetcherImpl>(
diff --git a/chrome/browser/page_load_metrics/metrics_web_contents_observer.cc b/chrome/browser/page_load_metrics/metrics_web_contents_observer.cc index 30106cd9..e8e6661 100644 --- a/chrome/browser/page_load_metrics/metrics_web_contents_observer.cc +++ b/chrome/browser/page_load_metrics/metrics_web_contents_observer.cc
@@ -176,6 +176,13 @@ return false; } + if (!EventsInOrder(timing.first_paint, timing.first_meaningful_paint)) { + NOTREACHED() << "Invalid first_paint " << timing.first_paint + << " for first_meaningful_paint " + << timing.first_meaningful_paint; + return false; + } + return true; } @@ -235,6 +242,8 @@ observer->OnFirstImagePaint(new_timing, extra_info); if (new_timing.first_contentful_paint && !last_timing.first_contentful_paint) observer->OnFirstContentfulPaint(new_timing, extra_info); + if (new_timing.first_meaningful_paint && !last_timing.first_meaningful_paint) + observer->OnFirstMeaningfulPaint(new_timing, extra_info); if (new_timing.parse_start && !last_timing.parse_start) observer->OnParseStart(new_timing, extra_info); if (new_timing.parse_stop && !last_timing.parse_stop)
diff --git a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.cc index 7915a4d..d60b8cf 100644 --- a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.cc
@@ -63,6 +63,12 @@ return LOAD_TYPE_NONE; } +void RecordFirstMeaningfulPaintStatus( + internal::FirstMeaningfulPaintStatus status) { + UMA_HISTOGRAM_ENUMERATION(internal::kHistogramFirstMeaningfulPaintStatus, + status, internal::FIRST_MEANINGFUL_PAINT_LAST_ENTRY); +} + } // namespace namespace internal { @@ -100,6 +106,10 @@ "PageLoad.PaintTiming.NavigationToFirstContentfulPaint"; const char kBackgroundHistogramFirstContentfulPaint[] = "PageLoad.PaintTiming.NavigationToFirstContentfulPaint.Background"; +const char kHistogramFirstMeaningfulPaint[] = + "PageLoad.Experimental.PaintTiming.NavigationToFirstMeaningfulPaint"; +const char kHistogramParseStartToFirstMeaningfulPaint[] = + "PageLoad.Experimental.PaintTiming.ParseStartToFirstMeaningfulPaint"; const char kHistogramParseStartToFirstContentfulPaint[] = "PageLoad.PaintTiming.ParseStartToFirstContentfulPaint"; const char kBackgroundHistogramParseStartToFirstContentfulPaint[] = @@ -108,6 +118,8 @@ "PageLoad.ParseTiming.NavigationToParseStart"; const char kBackgroundHistogramParseStart[] = "PageLoad.ParseTiming.NavigationToParseStart.Background"; +const char kHistogramFirstMeaningfulPaintToNetworkStable[] = + "PageLoad.Experimental.PaintTiming.FirstMeaningfulPaintToNetworkStable"; const char kHistogramParseDuration[] = "PageLoad.ParseTiming.ParseDuration"; const char kBackgroundHistogramParseDuration[] = "PageLoad.ParseTiming.ParseDuration.Background"; @@ -178,12 +190,16 @@ const char kRapporMetricsNameCoarseTiming[] = "PageLoad.CoarseTiming.NavigationToFirstContentfulPaint"; +const char kHistogramFirstMeaningfulPaintStatus[] = + "PageLoad.Experimental.PaintTiming.FirstMeaningfulPaintStatus"; + } // namespace internal CorePageLoadMetricsObserver::CorePageLoadMetricsObserver() : transition_(ui::PAGE_TRANSITION_LINK), initiated_by_user_gesture_(false), - was_no_store_main_resource_(false) {} + was_no_store_main_resource_(false), + had_first_paint_(false) {} CorePageLoadMetricsObserver::~CorePageLoadMetricsObserver() {} @@ -191,6 +207,7 @@ content::NavigationHandle* navigation_handle) { transition_ = navigation_handle->GetPageTransition(); initiated_by_user_gesture_ = navigation_handle->HasUserGesture(); + navigation_start_ = navigation_handle->NavigationStart(); const net::HttpResponseHeaders* headers = navigation_handle->GetResponseHeaders(); if (headers) { @@ -241,6 +258,8 @@ void CorePageLoadMetricsObserver::OnFirstPaint( const page_load_metrics::PageLoadTiming& timing, const page_load_metrics::PageLoadExtraInfo& info) { + had_first_paint_ = true; + if (WasStartedInForegroundOptionalEventInForeground(timing.first_paint, info)) { PAGE_LOAD_HISTOGRAM(internal::kHistogramFirstPaint, @@ -346,6 +365,35 @@ } } +void CorePageLoadMetricsObserver::OnFirstMeaningfulPaint( + const page_load_metrics::PageLoadTiming& timing, + const page_load_metrics::PageLoadExtraInfo& info) { + base::TimeTicks paint = + navigation_start_ + timing.first_meaningful_paint.value(); + if (first_user_interaction_after_first_paint_.is_null() || + paint < first_user_interaction_after_first_paint_) { + if (WasStartedInForegroundOptionalEventInForeground( + timing.first_meaningful_paint, info)) { + PAGE_LOAD_HISTOGRAM(internal::kHistogramFirstMeaningfulPaint, + timing.first_meaningful_paint.value()); + PAGE_LOAD_HISTOGRAM( + internal::kHistogramParseStartToFirstMeaningfulPaint, + timing.first_meaningful_paint.value() - timing.parse_start.value()); + PAGE_LOAD_HISTOGRAM( + internal::kHistogramFirstMeaningfulPaintToNetworkStable, + base::TimeTicks::Now() - paint); + RecordFirstMeaningfulPaintStatus( + internal::FIRST_MEANINGFUL_PAINT_RECORDED); + } else { + RecordFirstMeaningfulPaintStatus( + internal::FIRST_MEANINGFUL_PAINT_BACKGROUNDED); + } + } else { + RecordFirstMeaningfulPaintStatus( + internal::FIRST_MEANINGFUL_PAINT_USER_INTERACTION_BEFORE_FMP); + } +} + void CorePageLoadMetricsObserver::OnParseStart( const page_load_metrics::PageLoadTiming& timing, const page_load_metrics::PageLoadExtraInfo& info) { @@ -399,13 +447,24 @@ int total_requests = info.num_cache_requests + info.num_network_requests; if (total_requests) { - UMA_HISTOGRAM_PERCENTAGE( - internal::kHistogramCacheRequestPercentParseStop, - (100 * info.num_cache_requests) / total_requests); + int percent_cached = (100 * info.num_cache_requests) / total_requests; + UMA_HISTOGRAM_PERCENTAGE(internal::kHistogramCacheRequestPercentParseStop, + percent_cached); UMA_HISTOGRAM_COUNTS(internal::kHistogramCacheTotalRequestsParseStop, info.num_cache_requests); UMA_HISTOGRAM_COUNTS(internal::kHistogramTotalRequestsParseStop, info.num_cache_requests + info.num_network_requests); + + // Separate out parse duration based on cache percent. + if (percent_cached <= 50) { + PAGE_LOAD_HISTOGRAM( + "PageLoad.Experimental.ParseDuration.CachedPercent.0-50", + parse_duration); + } else { + PAGE_LOAD_HISTOGRAM( + "PageLoad.Experimental.ParseDuration.CachedPercent.51-100", + parse_duration); + } } } else { @@ -448,6 +507,14 @@ } } +void CorePageLoadMetricsObserver::OnUserInput( + const blink::WebInputEvent& event) { + if (had_first_paint_ && first_user_interaction_after_first_paint_.is_null() && + event.type != blink::WebInputEvent::MouseMove) { + first_user_interaction_after_first_paint_ = base::TimeTicks::Now(); + } +} + void CorePageLoadMetricsObserver::RecordTimingHistograms( const page_load_metrics::PageLoadTiming& timing, const page_load_metrics::PageLoadExtraInfo& info) { @@ -483,6 +550,11 @@ PAGE_LOAD_HISTOGRAM(internal::kHistogramFirstForeground, info.first_foreground_time.value()); } + + if (timing.first_paint && !timing.first_meaningful_paint) { + RecordFirstMeaningfulPaintStatus( + internal::FIRST_MEANINGFUL_PAINT_DID_NOT_REACH_NETWORK_STABLE); + } } void CorePageLoadMetricsObserver::RecordRappor(
diff --git a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h index a7d06d5..e836361 100644 --- a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h +++ b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h
@@ -20,8 +20,10 @@ extern const char kHistogramDomContentLoaded[]; extern const char kHistogramLoad[]; extern const char kHistogramFirstContentfulPaint[]; +extern const char kHistogramFirstMeaningfulPaint[]; extern const char kHistogramParseDuration[]; extern const char kHistogramParseBlockedOnScriptLoad[]; +extern const char kHistogramParseStartToFirstMeaningfulPaint[]; extern const char kBackgroundHistogramCommit[]; extern const char kBackgroundHistogramFirstLayout[]; @@ -42,6 +44,15 @@ extern const char kHistogramFailedProvisionalLoad[]; extern const char kRapporMetricsNameCoarseTiming[]; +extern const char kHistogramFirstMeaningfulPaintStatus[]; + +enum FirstMeaningfulPaintStatus { + FIRST_MEANINGFUL_PAINT_RECORDED, + FIRST_MEANINGFUL_PAINT_BACKGROUNDED, + FIRST_MEANINGFUL_PAINT_DID_NOT_REACH_NETWORK_STABLE, + FIRST_MEANINGFUL_PAINT_USER_INTERACTION_BEFORE_FMP, + FIRST_MEANINGFUL_PAINT_LAST_ENTRY +}; } // namespace internal @@ -77,6 +88,9 @@ void OnFirstContentfulPaint( const page_load_metrics::PageLoadTiming& timing, const page_load_metrics::PageLoadExtraInfo& extra_info) override; + void OnFirstMeaningfulPaint( + const page_load_metrics::PageLoadTiming& timing, + const page_load_metrics::PageLoadExtraInfo& extra_info) override; void OnParseStart( const page_load_metrics::PageLoadTiming& timing, const page_load_metrics::PageLoadExtraInfo& extra_info) override; @@ -88,6 +102,7 @@ void OnFailedProvisionalLoad( const page_load_metrics::FailedProvisionalLoadInfo& failed_load_info, const page_load_metrics::PageLoadExtraInfo& extra_info) override; + void OnUserInput(const blink::WebInputEvent& event) override; private: void RecordTimingHistograms(const page_load_metrics::PageLoadTiming& timing, @@ -98,6 +113,9 @@ ui::PageTransition transition_; bool initiated_by_user_gesture_; bool was_no_store_main_resource_; + bool had_first_paint_; + base::TimeTicks navigation_start_; + base::TimeTicks first_user_interaction_after_first_paint_; DISALLOW_COPY_AND_ASSIGN(CorePageLoadMetricsObserver); };
diff --git a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer_unittest.cc index 769c89f..36632e7e 100644 --- a/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer_unittest.cc +++ b/chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer_unittest.cc
@@ -548,3 +548,52 @@ internal::kHistogramLoadTypeParseStartNewNavigation, timing.parse_start.value().InMilliseconds(), 1); } + +TEST_F(CorePageLoadMetricsObserverTest, FirstMeaningfulPaint) { + page_load_metrics::PageLoadTiming timing; + timing.navigation_start = base::Time::FromDoubleT(1); + timing.parse_start = base::TimeDelta::FromMilliseconds(5); + timing.first_meaningful_paint = base::TimeDelta::FromMilliseconds(10); + PopulateRequiredTimingFields(&timing); + + NavigateAndCommit(GURL(kDefaultTestUrl)); + SimulateTimingUpdate(timing); + NavigateAndCommit(GURL(kDefaultTestUrl2)); + + histogram_tester().ExpectTotalCount( + internal::kHistogramFirstMeaningfulPaint, 1); + histogram_tester().ExpectTotalCount( + internal::kHistogramParseStartToFirstMeaningfulPaint, 1); + histogram_tester().ExpectBucketCount( + internal::kHistogramFirstMeaningfulPaintStatus, + internal::FIRST_MEANINGFUL_PAINT_RECORDED, 1); +} + +TEST_F(CorePageLoadMetricsObserverTest, FirstMeaningfulPaintAfterInteraction) { + page_load_metrics::PageLoadTiming timing; + timing.navigation_start = base::Time::FromDoubleT(1); + timing.parse_start = base::TimeDelta::FromMilliseconds(5); + timing.first_paint = base::TimeDelta::FromMilliseconds(10); + PopulateRequiredTimingFields(&timing); + + NavigateAndCommit(GURL(kDefaultTestUrl)); + SimulateTimingUpdate(timing); + + blink::WebMouseEvent mouse_event; + mouse_event.type = blink::WebInputEvent::MouseDown; + SimulateInputEvent(mouse_event); + + timing.first_meaningful_paint = base::TimeDelta::FromMilliseconds(1000); + PopulateRequiredTimingFields(&timing); + SimulateTimingUpdate(timing); + + NavigateAndCommit(GURL(kDefaultTestUrl2)); + + histogram_tester().ExpectTotalCount( + internal::kHistogramFirstMeaningfulPaint, 0); + histogram_tester().ExpectTotalCount( + internal::kHistogramParseStartToFirstMeaningfulPaint, 0); + histogram_tester().ExpectBucketCount( + internal::kHistogramFirstMeaningfulPaintStatus, + internal::FIRST_MEANINGFUL_PAINT_USER_INTERACTION_BEFORE_FMP, 1); +}
diff --git a/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.cc b/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.cc index cc46351..153228f9 100644 --- a/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.cc +++ b/chrome/browser/page_load_metrics/observers/page_load_metrics_observer_test_harness.cc
@@ -53,6 +53,9 @@ // static void PageLoadMetricsObserverTestHarness::PopulateRequiredTimingFields( PageLoadTiming* inout_timing) { + if (inout_timing->first_meaningful_paint && !inout_timing->first_paint) { + inout_timing->first_paint = inout_timing->first_meaningful_paint; + } if (inout_timing->first_contentful_paint && !inout_timing->first_paint) { inout_timing->first_paint = inout_timing->first_contentful_paint; }
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc index 6f6a801..6cab290 100644 --- a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc +++ b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc
@@ -377,3 +377,51 @@ histogram_tester_.ExpectTotalCount( internal::kHistogramAbortClientRedirectBeforeCommit, 1); } + +IN_PROC_BROWSER_TEST_F(MetricsWebContentsObserverBrowserTest, + FirstMeaningfulPaintRecorded) { + ASSERT_TRUE(embedded_test_server()->Start()); + + ui_test_utils::NavigateToURL(browser(), + embedded_test_server()->GetURL("/title1.html")); + + // Wait until the renderer finishes observing layouts. + const int kNetworkIdleTime = 2000; + const int kMargin = 500; + const std::string javascript = base::StringPrintf( + "setTimeout(() => window.domAutomationController.send(true), %d)", + kNetworkIdleTime + kMargin); + bool result; + EXPECT_TRUE(content::ExecuteScriptAndExtractBool( + browser()->tab_strip_model()->GetActiveWebContents(), + javascript, &result)); + EXPECT_TRUE(result); + + NavigateToUntrackedUrl(); + histogram_tester_.ExpectUniqueSample( + internal::kHistogramFirstMeaningfulPaintStatus, + internal::FIRST_MEANINGFUL_PAINT_RECORDED, 1); + histogram_tester_.ExpectTotalCount( + internal::kHistogramFirstMeaningfulPaint, 1); + histogram_tester_.ExpectTotalCount( + internal::kHistogramParseStartToFirstMeaningfulPaint, 1); +} + +IN_PROC_BROWSER_TEST_F(MetricsWebContentsObserverBrowserTest, + FirstMeaningfulPaintNotRecorded) { + ASSERT_TRUE(embedded_test_server()->Start()); + + ui_test_utils::NavigateToURL(browser(), + embedded_test_server()->GetURL("/title1.html")); + + // Navigate away before a FMP is reported. + NavigateToUntrackedUrl(); + + histogram_tester_.ExpectUniqueSample( + internal::kHistogramFirstMeaningfulPaintStatus, + internal::FIRST_MEANINGFUL_PAINT_DID_NOT_REACH_NETWORK_STABLE, 1); + histogram_tester_.ExpectTotalCount( + internal::kHistogramFirstMeaningfulPaint, 0); + histogram_tester_.ExpectTotalCount( + internal::kHistogramParseStartToFirstMeaningfulPaint, 0); +}
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_observer.h b/chrome/browser/page_load_metrics/page_load_metrics_observer.h index af8d1971..4288ae0 100644 --- a/chrome/browser/page_load_metrics/page_load_metrics_observer.h +++ b/chrome/browser/page_load_metrics/page_load_metrics_observer.h
@@ -184,6 +184,8 @@ const PageLoadExtraInfo& extra_info) {} virtual void OnFirstContentfulPaint(const PageLoadTiming& timing, const PageLoadExtraInfo& extra_info) {} + virtual void OnFirstMeaningfulPaint(const PageLoadTiming& timing, + const PageLoadExtraInfo& extra_info) {} virtual void OnParseStart(const PageLoadTiming& timing, const PageLoadExtraInfo& extra_info) {} virtual void OnParseStop(const PageLoadTiming& timing,
diff --git a/chrome/browser/password_manager/credential_manager_browsertest.cc b/chrome/browser/password_manager/credential_manager_browsertest.cc index 2e8dc79..14cd679 100644 --- a/chrome/browser/password_manager/credential_manager_browsertest.cc +++ b/chrome/browser/password_manager/credential_manager_browsertest.cc
@@ -44,8 +44,8 @@ CredentialManagerBrowserTest() = default; bool IsShowingAccountChooser() { - return PasswordsModelDelegateFromWebContents(WebContents())->GetState() == - password_manager::ui::CREDENTIAL_REQUEST_STATE; + return PasswordsModelDelegateFromWebContents(WebContents())-> + GetState() == password_manager::ui::CREDENTIAL_REQUEST_STATE; } // Make sure that the password store processed all the previous calls which @@ -93,8 +93,9 @@ "navigator.credentials.get({password: true})" ".then(cred => window.location = '/password/done.html')")); WaitForPasswordStore(); - ASSERT_EQ(password_manager::ui::CREDENTIAL_REQUEST_STATE, - PasswordsModelDelegateFromWebContents(WebContents())->GetState()); + ASSERT_EQ( + password_manager::ui::CREDENTIAL_REQUEST_STATE, + PasswordsModelDelegateFromWebContents(WebContents())->GetState()); PasswordsModelDelegateFromWebContents(WebContents())->ChooseCredential( signin_form, password_manager::CredentialType::CREDENTIAL_TYPE_PASSWORD);
diff --git a/chrome/browser/password_manager/native_backend_kwallet_x_unittest.cc b/chrome/browser/password_manager/native_backend_kwallet_x_unittest.cc index e64e16b..f2df3e40 100644 --- a/chrome/browser/password_manager/native_backend_kwallet_x_unittest.cc +++ b/chrome/browser/password_manager/native_backend_kwallet_x_unittest.cc
@@ -535,7 +535,7 @@ return nullptr; EXPECT_EQ("org.kde.KWallet", method_call->GetInterface()); - if (ContainsKey(failing_methods_, method_call->GetMember())) + if (base::ContainsKey(failing_methods_, method_call->GetMember())) return nullptr; std::unique_ptr<dbus::Response> response; if (method_call->GetMember() == "isEnabled") {
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc index 49ca26d..2b65d7b 100644 --- a/chrome/browser/password_manager/password_manager_browsertest.cc +++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -93,7 +93,7 @@ base::CompareCase::SENSITIVE)) return std::unique_ptr<net::test_server::HttpResponse>(); - if (ContainsKey(request.headers, "Authorization")) { + if (base::ContainsKey(request.headers, "Authorization")) { std::unique_ptr<net::test_server::BasicHttpResponse> http_response( new net::test_server::BasicHttpResponse); http_response->set_code(net::HTTP_OK);
diff --git a/chrome/browser/password_manager/password_manager_test_base.cc b/chrome/browser/password_manager/password_manager_test_base.cc index bac34c67..6e45005d 100644 --- a/chrome/browser/password_manager/password_manager_test_base.cc +++ b/chrome/browser/password_manager/password_manager_test_base.cc
@@ -57,40 +57,39 @@ } BubbleObserver::BubbleObserver(content::WebContents* web_contents) - : passwords_model_delegate_( - PasswordsModelDelegateFromWebContents(web_contents)) {} + : passwords_ui_controller_( + ManagePasswordsUIController::FromWebContents(web_contents)) {} bool BubbleObserver::IsShowingSavePrompt() const { - return passwords_model_delegate_->GetState() == + return passwords_ui_controller_->GetState() == password_manager::ui::PENDING_PASSWORD_STATE; } bool BubbleObserver::IsShowingUpdatePrompt() const { - return passwords_model_delegate_->GetState() == + return passwords_ui_controller_->GetState() == password_manager::ui::PENDING_PASSWORD_UPDATE_STATE; } void BubbleObserver::Dismiss() const { - passwords_model_delegate_->OnBubbleHidden(); + passwords_ui_controller_->OnBubbleHidden(); // Navigate away to reset the state to inactive. - static_cast<content::WebContentsObserver*>( - static_cast<ManagePasswordsUIController*>(passwords_model_delegate_)) - ->DidNavigateMainFrame(content::LoadCommittedDetails(), - content::FrameNavigateParams()); + static_cast<content::WebContentsObserver*>(passwords_ui_controller_) + ->DidNavigateMainFrame(content::LoadCommittedDetails(), + content::FrameNavigateParams()); ASSERT_EQ(password_manager::ui::INACTIVE_STATE, - passwords_model_delegate_->GetState()); + passwords_ui_controller_->GetState()); } void BubbleObserver::AcceptSavePrompt() const { ASSERT_TRUE(IsShowingSavePrompt()); - passwords_model_delegate_->SavePassword(); + passwords_ui_controller_->SavePassword(); EXPECT_FALSE(IsShowingSavePrompt()); } void BubbleObserver::AcceptUpdatePrompt( const autofill::PasswordForm& form) const { ASSERT_TRUE(IsShowingUpdatePrompt()); - passwords_model_delegate_->UpdatePassword(form); + passwords_ui_controller_->UpdatePassword(form); EXPECT_FALSE(IsShowingUpdatePrompt()); }
diff --git a/chrome/browser/password_manager/password_manager_test_base.h b/chrome/browser/password_manager/password_manager_test_base.h index 823cdac1..5d36a1e 100644 --- a/chrome/browser/password_manager/password_manager_test_base.h +++ b/chrome/browser/password_manager/password_manager_test_base.h
@@ -16,7 +16,7 @@ struct PasswordForm; } -class PasswordsModelDelegate; +class ManagePasswordsUIController; class NavigationObserver : public content::WebContentsObserver { public: @@ -81,7 +81,7 @@ void AcceptUpdatePrompt(const autofill::PasswordForm& form) const; private: - PasswordsModelDelegate* const passwords_model_delegate_; + ManagePasswordsUIController* const passwords_ui_controller_; DISALLOW_COPY_AND_ASSIGN(BubbleObserver); };
diff --git a/chrome/browser/password_manager/password_store_mac.cc b/chrome/browser/password_manager/password_store_mac.cc index aa058c2..14e0b5e 100644 --- a/chrome/browser/password_manager/password_store_mac.cc +++ b/chrome/browser/password_manager/password_store_mac.cc
@@ -547,7 +547,7 @@ ScopedVector<autofill::PasswordForm> unused_keychain_forms; unused_keychain_forms.reserve(keychain_forms->size()); for (auto*& keychain_form : *keychain_forms) { - if (!ContainsKey(used_keychain_forms, keychain_form)) { + if (!base::ContainsKey(used_keychain_forms, keychain_form)) { unused_keychain_forms.push_back(keychain_form); keychain_form = nullptr; } @@ -611,8 +611,8 @@ }); database_forms->swap(unused_db_forms); - STLDeleteContainerPairSecondPointers(item_form_pairs.begin(), - item_form_pairs.end()); + base::STLDeleteContainerPairSecondPointers(item_form_pairs.begin(), + item_form_pairs.end()); for (SecKeychainItemRef item : keychain_items) { keychain.Free(item); } @@ -1029,8 +1029,8 @@ } } } - STLDeleteContainerPairSecondPointers(item_form_pairs.begin(), - item_form_pairs.end()); + base::STLDeleteContainerPairSecondPointers(item_form_pairs.begin(), + item_form_pairs.end()); for (SecKeychainItemRef item : keychain_items) keychain_->Free(item);
diff --git a/chrome/browser/password_manager/password_store_mac_unittest.cc b/chrome/browser/password_manager/password_store_mac_unittest.cc index 1b83eb6..20089ec 100644 --- a/chrome/browser/password_manager/password_store_mac_unittest.cc +++ b/chrome/browser/password_manager/password_store_mac_unittest.cc
@@ -512,8 +512,8 @@ internal_keychain_helpers::ExtractPasswordsMergeableWithForm( *keychain_, item_form_pairs, *query_form); EXPECT_EQ(test_data[i].expected_merge_matches, matching_items.size()); - STLDeleteContainerPairSecondPointers(item_form_pairs.begin(), - item_form_pairs.end()); + base::STLDeleteContainerPairSecondPointers(item_form_pairs.begin(), + item_form_pairs.end()); for (std::vector<SecKeychainItemRef>::iterator i = keychain_items.begin(); i != keychain_items.end(); ++i) { keychain_->Free(*i);
diff --git a/chrome/browser/password_manager/password_store_win_unittest.cc b/chrome/browser/password_manager/password_store_win_unittest.cc index 3b024958..81bb5c92 100644 --- a/chrome/browser/password_manager/password_store_win_unittest.cc +++ b/chrome/browser/password_manager/password_store_win_unittest.cc
@@ -188,7 +188,7 @@ }; ACTION(STLDeleteElements0) { - STLDeleteContainerPointers(arg0.begin(), arg0.end()); + base::STLDeleteContainerPointers(arg0.begin(), arg0.end()); } ACTION(QuitUIMessageLoop) {
diff --git a/chrome/browser/password_manager/password_store_x_unittest.cc b/chrome/browser/password_manager/password_store_x_unittest.cc index 19e3652..bbae5ee 100644 --- a/chrome/browser/password_manager/password_store_x_unittest.cc +++ b/chrome/browser/password_manager/password_store_x_unittest.cc
@@ -399,7 +399,7 @@ }; ACTION(STLDeleteElements0) { - STLDeleteContainerPointers(arg0.begin(), arg0.end()); + base::STLDeleteContainerPointers(arg0.begin(), arg0.end()); } TEST_P(PasswordStoreXTest, Notifications) {
diff --git a/chrome/browser/permissions/permission_uma_util_unittest.cc b/chrome/browser/permissions/permission_uma_util_unittest.cc index 89deb6a..4d0d529 100644 --- a/chrome/browser/permissions/permission_uma_util_unittest.cc +++ b/chrome/browser/permissions/permission_uma_util_unittest.cc
@@ -15,8 +15,8 @@ #include "components/browser_sync/common/browser_sync_switches.h" #include "components/prefs/pref_service.h" #include "components/sync/base/model_type.h" -#include "components/sync_driver/glue/sync_backend_host_mock.h" -#include "components/sync_driver/sync_prefs.h" +#include "components/sync/driver/glue/sync_backend_host_mock.h" +#include "components/sync/driver/sync_prefs.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/plugins/plugin_finder.cc b/chrome/browser/plugins/plugin_finder.cc index 2279de0..e9902ab 100644 --- a/chrome/browser/plugins/plugin_finder.cc +++ b/chrome/browser/plugins/plugin_finder.cc
@@ -247,9 +247,9 @@ PluginFinder::~PluginFinder() { #if defined(ENABLE_PLUGIN_INSTALLATION) - STLDeleteValues(&installers_); + base::STLDeleteValues(&installers_); #endif - STLDeleteValues(&identifier_plugin_); + base::STLDeleteValues(&identifier_plugin_); } #if defined(ENABLE_PLUGIN_INSTALLATION) @@ -310,7 +310,7 @@ version_ = version; - STLDeleteValues(&identifier_plugin_); + base::STLDeleteValues(&identifier_plugin_); for (base::DictionaryValue::Iterator plugin_it(*plugin_list); !plugin_it.IsAtEnd(); plugin_it.Advance()) {
diff --git a/chrome/browser/plugins/plugin_observer.cc b/chrome/browser/plugins/plugin_observer.cc index 340e2359..2494c38 100644 --- a/chrome/browser/plugins/plugin_observer.cc +++ b/chrome/browser/plugins/plugin_observer.cc
@@ -312,7 +312,7 @@ PluginObserver::~PluginObserver() { #if defined(ENABLE_PLUGIN_INSTALLATION) - STLDeleteValues(&plugin_placeholders_); + base::STLDeleteValues(&plugin_placeholders_); #endif }
diff --git a/chrome/browser/plugins/plugin_power_saver_browsertest.cc b/chrome/browser/plugins/plugin_power_saver_browsertest.cc index 3ecbfd4e..1626bec 100644 --- a/chrome/browser/plugins/plugin_power_saver_browsertest.cc +++ b/chrome/browser/plugins/plugin_power_saver_browsertest.cc
@@ -179,10 +179,10 @@ int w = 0; int h = 0; std::vector<unsigned char> decoded; - if (!gfx::PNGCodec::Decode( - reinterpret_cast<unsigned char*>(string_as_array(&reference_data)), - reference_data.size(), gfx::PNGCodec::FORMAT_BGRA, &decoded, &w, - &h)) { + if (!gfx::PNGCodec::Decode(reinterpret_cast<unsigned char*>( + base::string_as_array(&reference_data)), + reference_data.size(), gfx::PNGCodec::FORMAT_BGRA, + &decoded, &w, &h)) { return false; }
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index e75090be..758c63d 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -45,7 +45,7 @@ #include "components/search_engines/default_search_policy_handler.h" #include "components/signin/core/common/signin_pref_names.h" #include "components/ssl_config/ssl_config_prefs.h" -#include "components/sync_driver/sync_policy_handler.h" +#include "components/sync/driver/sync_policy_handler.h" #include "components/translate/core/common/translate_pref_names.h" #include "components/variations/pref_names.h" #include "policy/policy_constants.h" @@ -399,6 +399,11 @@ prefs::kEnableMediaRouter, base::Value::TYPE_BOOLEAN }, #endif // defined(ENABLE_MEDIA_ROUTER) +#if defined(ENABLE_WEBRTC) + { key::kWebRtcUdpPortRange, + prefs::kWebRTCUDPPortRange, + base::Value::TYPE_STRING }, +#endif // defined(ENABLE_WEBRTC) #if !defined(OS_MACOSX) { key::kFullscreenAllowed, prefs::kFullscreenAllowed,
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc index a765274..b80ad6a3 100644 --- a/chrome/browser/policy/policy_browsertest.cc +++ b/chrome/browser/policy/policy_browsertest.cc
@@ -118,6 +118,7 @@ #include "components/strings/grit/components_strings.h" #include "components/translate/core/browser/language_state.h" #include "components/translate/core/browser/translate_infobar_delegate.h" +#include "components/user_prefs/user_prefs.h" #include "components/variations/service/variations_service.h" #include "components/version_info/version_info.h" #include "content/public/browser/browser_child_process_host_iterator.h" @@ -279,6 +280,11 @@ FILE_PATH_LITERAL("fullscreen_app"); #endif // !defined(OS_MACOSX) +#if defined(ENABLE_WEBRTC) +// Arbitrary port range for testing the WebRTC UDP port policy. +const char kTestWebRtcUdpPortRange[] = "10000-10100"; +#endif + // Filters requests to the hosts in |urls| and redirects them to the test data // dir through URLRequestMockHTTPJobs. void RedirectHostsToTestData(const char* const urls[], size_t size) { @@ -371,10 +377,15 @@ content::WebContents* contents = browser->tab_strip_model()->GetActiveWebContents(); EXPECT_EQ(url, contents->GetURL()); - base::string16 spec16 = base::UTF8ToUTF16(url.spec()); - base::string16 title = - l10n_util::GetStringFUTF16(IDS_ERRORPAGES_TITLE_BLOCKED, spec16); - EXPECT_NE(title, contents->GetTitle()); + + base::string16 blocked_page_title; + if (url.has_host()) { + blocked_page_title = base::UTF8ToUTF16(url.host()); + } else { + // Local file paths show the full URL. + blocked_page_title = base::UTF8ToUTF16(url.spec()); + } + EXPECT_NE(blocked_page_title, contents->GetTitle()); } // Verifies that access to the given url |spec| is blocked. @@ -384,10 +395,15 @@ content::WebContents* contents = browser->tab_strip_model()->GetActiveWebContents(); EXPECT_EQ(url, contents->GetURL()); - base::string16 spec16 = base::UTF8ToUTF16(url.spec()); - base::string16 title = - l10n_util::GetStringFUTF16(IDS_ERRORPAGES_TITLE_BLOCKED, spec16); - EXPECT_EQ(title, contents->GetTitle()); + + base::string16 blocked_page_title; + if (url.has_host()) { + blocked_page_title = base::UTF8ToUTF16(url.host()); + } else { + // Local file paths show the full URL. + blocked_page_title = base::UTF8ToUTF16(url.spec()); + } + EXPECT_EQ(blocked_page_title, contents->GetTitle()); // Verify that the expected error page is being displayed. bool result = false; @@ -1020,6 +1036,7 @@ // policy. Also checks that default search can be completely disabled. const base::string16 kKeyword(base::ASCIIToUTF16("testsearch")); const std::string kSearchURL("http://search.example/search?q={searchTerms}"); + const std::string kInstantURL("http://does/not/exist"); const std::string kAlternateURL0( "http://search.example/search#q={searchTerms}"); const std::string kAlternateURL1("http://search.example/#q={searchTerms}"); @@ -1036,6 +1053,7 @@ ASSERT_TRUE(default_search); EXPECT_NE(kKeyword, default_search->keyword()); EXPECT_NE(kSearchURL, default_search->url()); + EXPECT_NE(kInstantURL, default_search->instant_url()); EXPECT_FALSE( default_search->alternate_urls().size() == 2 && default_search->alternate_urls()[0] == kAlternateURL0 && @@ -1057,6 +1075,9 @@ policies.Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, base::WrapUnique(new base::StringValue(kSearchURL)), nullptr); + policies.Set(key::kDefaultSearchProviderInstantURL, POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, + base::WrapUnique(new base::StringValue(kInstantURL)), nullptr); std::unique_ptr<base::ListValue> alternate_urls(new base::ListValue); alternate_urls->AppendString(kAlternateURL0); alternate_urls->AppendString(kAlternateURL1); @@ -1083,6 +1104,7 @@ ASSERT_TRUE(default_search); EXPECT_EQ(kKeyword, default_search->keyword()); EXPECT_EQ(kSearchURL, default_search->url()); + EXPECT_EQ(kInstantURL, default_search->instant_url()); EXPECT_EQ(2U, default_search->alternate_urls().size()); EXPECT_EQ(kAlternateURL0, default_search->alternate_urls()[0]); EXPECT_EQ(kAlternateURL1, default_search->alternate_urls()[1]); @@ -1191,124 +1213,6 @@ } } -IN_PROC_BROWSER_TEST_F(PolicyTest, ReplaceSearchTerms) { - MakeRequestFail make_request_fail("search.example"); - - search::EnableQueryExtractionForTesting(); - - // Verifies that a default search is made using the provider configured via - // policy. Also checks that default search can be completely disabled. - const base::string16 kKeyword(base::ASCIIToUTF16("testsearch")); - const std::string kSearchURL("https://www.google.com/search?q={searchTerms}"); - const std::string kInstantURL("http://does/not/exist"); - const std::string kAlternateURL0( - "https://www.google.com/search#q={searchTerms}"); - const std::string kAlternateURL1("https://www.google.com/#q={searchTerms}"); - const std::string kSearchTermsReplacementKey( - "{google:instantExtendedEnabledKey}"); - - TemplateURLService* service = TemplateURLServiceFactory::GetForProfile( - browser()->profile()); - search_test_utils::WaitForTemplateURLServiceToLoad(service); - TemplateURL* default_search = service->GetDefaultSearchProvider(); - ASSERT_TRUE(default_search); - EXPECT_NE(kKeyword, default_search->keyword()); - EXPECT_NE(kSearchURL, default_search->url()); - EXPECT_NE(kInstantURL, default_search->instant_url()); - EXPECT_FALSE( - default_search->alternate_urls().size() == 2 && - default_search->alternate_urls()[0] == kAlternateURL0 && - default_search->alternate_urls()[1] == kAlternateURL1); - - // Override the default search provider using policies. - PolicyMap policies; - policies.Set(key::kDefaultSearchProviderEnabled, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, - base::WrapUnique(new base::FundamentalValue(true)), nullptr); - policies.Set(key::kDefaultSearchProviderKeyword, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, - base::WrapUnique(new base::StringValue(kKeyword)), nullptr); - policies.Set(key::kDefaultSearchProviderSearchURL, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, - base::WrapUnique(new base::StringValue(kSearchURL)), nullptr); - policies.Set(key::kDefaultSearchProviderInstantURL, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, - base::WrapUnique(new base::StringValue(kInstantURL)), nullptr); - std::unique_ptr<base::ListValue> alternate_urls(new base::ListValue); - alternate_urls->AppendString(kAlternateURL0); - alternate_urls->AppendString(kAlternateURL1); - policies.Set(key::kDefaultSearchProviderAlternateURLs, POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, - std::move(alternate_urls), nullptr); - policies.Set( - key::kDefaultSearchProviderSearchTermsReplacementKey, - POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, - base::WrapUnique(new base::StringValue(kSearchTermsReplacementKey)), - nullptr); - UpdateProviderPolicy(policies); - default_search = service->GetDefaultSearchProvider(); - ASSERT_TRUE(default_search); - EXPECT_EQ(kKeyword, default_search->keyword()); - EXPECT_EQ(kSearchURL, default_search->url()); - EXPECT_EQ(kInstantURL, default_search->instant_url()); - EXPECT_EQ(2U, default_search->alternate_urls().size()); - EXPECT_EQ(kAlternateURL0, default_search->alternate_urls()[0]); - EXPECT_EQ(kAlternateURL1, default_search->alternate_urls()[1]); - - // Query terms replacement requires that the renderer process be a recognized - // Instant renderer. Fake it. - InstantService* instant_service = - InstantServiceFactory::GetForProfile(browser()->profile()); - instant_service->AddInstantProcess(browser()->tab_strip_model()-> - GetActiveWebContents()->GetRenderProcessHost()->GetID()); - - // Verify that searching from the omnibox does search term replacement with - // first URL pattern. - chrome::FocusLocationBar(browser()); - LocationBar* location_bar = browser()->window()->GetLocationBar(); - OmniboxView* omnibox_view = location_bar->GetOmniboxView(); - ui_test_utils::SendToOmniboxAndSubmit(location_bar, - "https://www.google.com/?espv=1#q=foobar"); - EXPECT_TRUE( - browser()->toolbar_model()->WouldPerformSearchTermReplacement(false)); - EXPECT_EQ(base::ASCIIToUTF16("foobar"), omnibox_view->GetText()); - - // Verify that not using espv=1 does not do search term replacement. - chrome::FocusLocationBar(browser()); - ui_test_utils::SendToOmniboxAndSubmit(location_bar, - "https://www.google.com/?q=foobar"); - EXPECT_FALSE( - browser()->toolbar_model()->WouldPerformSearchTermReplacement(false)); - EXPECT_EQ(base::ASCIIToUTF16("https://www.google.com/?q=foobar"), - omnibox_view->GetText()); - - // Verify that searching from the omnibox does search term replacement with - // second URL pattern. - chrome::FocusLocationBar(browser()); - ui_test_utils::SendToOmniboxAndSubmit(location_bar, - "https://www.google.com/search?espv=1#q=banana"); - EXPECT_TRUE( - browser()->toolbar_model()->WouldPerformSearchTermReplacement(false)); - EXPECT_EQ(base::ASCIIToUTF16("banana"), omnibox_view->GetText()); - - // Verify that searching from the omnibox does search term replacement with - // standard search URL pattern. - chrome::FocusLocationBar(browser()); - ui_test_utils::SendToOmniboxAndSubmit(location_bar, - "https://www.google.com/search?q=tractor+parts&espv=1"); - EXPECT_TRUE( - browser()->toolbar_model()->WouldPerformSearchTermReplacement(false)); - EXPECT_EQ(base::ASCIIToUTF16("tractor parts"), omnibox_view->GetText()); - - // Verify that searching from the omnibox prioritizes hash over query. - chrome::FocusLocationBar(browser()); - ui_test_utils::SendToOmniboxAndSubmit(location_bar, - "https://www.google.com/search?q=tractor+parts&espv=1#q=foobar"); - EXPECT_TRUE( - browser()->toolbar_model()->WouldPerformSearchTermReplacement(false)); - EXPECT_EQ(base::ASCIIToUTF16("foobar"), omnibox_view->GetText()); -} - IN_PROC_BROWSER_TEST_F(PolicyTest, Disable3DAPIs) { // This test assumes Gpu access. if (!content::GpuDataManager::GetInstance()->GpuAccessAllowed(NULL)) @@ -3741,6 +3645,54 @@ } #endif // defined(ENABLE_MEDIA_ROUTER) +#if defined(ENABLE_WEBRTC) +// Sets the proper policy before the browser is started. +template <bool enable> +class WebRtcUdpPortRangePolicyTest : public PolicyTest { + public: + WebRtcUdpPortRangePolicyTest() = default; + void SetUpInProcessBrowserTestFixture() override { + PolicyTest::SetUpInProcessBrowserTestFixture(); + PolicyMap policies; + if (enable) { + policies.Set( + key::kWebRtcUdpPortRange, POLICY_LEVEL_MANDATORY, POLICY_SCOPE_USER, + POLICY_SOURCE_CLOUD, + base::WrapUnique(new base::StringValue(kTestWebRtcUdpPortRange)), + nullptr); + } + provider_.UpdateChromePolicy(policies); + } + + private: + DISALLOW_COPY_AND_ASSIGN(WebRtcUdpPortRangePolicyTest<enable>); +}; + +using WebRtcUdpPortRangeEnabledPolicyTest = WebRtcUdpPortRangePolicyTest<true>; +using WebRtcUdpPortRangeDisabledPolicyTest = + WebRtcUdpPortRangePolicyTest<false>; + +IN_PROC_BROWSER_TEST_F(WebRtcUdpPortRangeEnabledPolicyTest, + WebRtcUdpPortRangeEnabled) { + std::string port_range; + const PrefService::Preference* pref = + user_prefs::UserPrefs::Get(browser()->profile()) + ->FindPreference(prefs::kWebRTCUDPPortRange); + pref->GetValue()->GetAsString(&port_range); + EXPECT_EQ(kTestWebRtcUdpPortRange, port_range); +} + +IN_PROC_BROWSER_TEST_F(WebRtcUdpPortRangeDisabledPolicyTest, + WebRtcUdpPortRangeDisabled) { + std::string port_range; + const PrefService::Preference* pref = + user_prefs::UserPrefs::Get(browser()->profile()) + ->FindPreference(prefs::kWebRTCUDPPortRange); + pref->GetValue()->GetAsString(&port_range); + EXPECT_TRUE(port_range.empty()); +} +#endif // defined(ENABLE_WEBRTC) + #if !defined(OS_CHROMEOS) // Similar to PolicyTest but sets the proper policy before the browser is // started.
diff --git a/chrome/browser/policy/policy_prefs_browsertest.cc b/chrome/browser/policy/policy_prefs_browsertest.cc index 65c4e90..f7510d2 100644 --- a/chrome/browser/policy/policy_prefs_browsertest.cc +++ b/chrome/browser/policy/policy_prefs_browsertest.cc
@@ -488,7 +488,7 @@ PolicyTestCases policy_test_cases; for (Schema::Iterator it = chrome_schema.GetPropertiesIterator(); !it.IsAtEnd(); it.Advance()) { - EXPECT_TRUE(ContainsKey(policy_test_cases.map(), it.key())) + EXPECT_TRUE(base::ContainsKey(policy_test_cases.map(), it.key())) << "Missing policy test case for: " << it.key(); } }
diff --git a/chrome/browser/power/process_power_collector.cc b/chrome/browser/power/process_power_collector.cc index ce118ae9..19c0f63 100644 --- a/chrome/browser/power/process_power_collector.cc +++ b/chrome/browser/power/process_power_collector.cc
@@ -182,7 +182,7 @@ const content::RenderProcessHost* rph, const GURL& origin) { base::ProcessHandle handle = rph->GetHandle(); - if (!ContainsKey(metrics_map_, handle)) { + if (!base::ContainsKey(metrics_map_, handle)) { metrics_map_[handle] = base::MakeUnique<PerProcessData>( #if defined(OS_MACOSX) base::ProcessMetrics::CreateProcessMetrics(handle, nullptr),
diff --git a/chrome/browser/predictors/autocomplete_action_predictor.cc b/chrome/browser/predictors/autocomplete_action_predictor.cc index 3b79ea99..a92ab887 100644 --- a/chrome/browser/predictors/autocomplete_action_predictor.cc +++ b/chrome/browser/predictors/autocomplete_action_predictor.cc
@@ -129,7 +129,7 @@ } for (const auto& i : result) { - if (!ContainsValue(match_it->urls, i.destination_url)) + if (!base::ContainsValue(match_it->urls, i.destination_url)) match_it->urls.push_back(i.destination_url); } }
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_tab_helper.cc b/chrome/browser/predictors/resource_prefetch_predictor_tab_helper.cc index ec827f1..d6d2dd7 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_tab_helper.cc +++ b/chrome/browser/predictors/resource_prefetch_predictor_tab_helper.cc
@@ -8,7 +8,6 @@ #include "chrome/browser/predictors/resource_prefetch_predictor_factory.h" #include "chrome/browser/profiles/profile.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/load_from_memory_cache_details.h" DEFINE_WEB_CONTENTS_USER_DATA_KEY( predictors::ResourcePrefetchPredictorTabHelper); @@ -39,7 +38,9 @@ } void ResourcePrefetchPredictorTabHelper::DidLoadResourceFromMemoryCache( - const content::LoadFromMemoryCacheDetails& details) { + const GURL& url, + const std::string& mime_type, + content::ResourceType resource_type) { DCHECK_CURRENTLY_ON(BrowserThread::UI); ResourcePrefetchPredictor* predictor = @@ -50,11 +51,11 @@ ResourcePrefetchPredictor::URLRequestSummary summary; summary.navigation_id = NavigationID(web_contents()); - summary.resource_url = details.url; - summary.mime_type = details.mime_type; + summary.resource_url = url; + summary.mime_type = mime_type; summary.resource_type = ResourcePrefetchPredictor::GetResourceTypeFromMimeType( - details.mime_type, details.resource_type); + mime_type, resource_type); summary.was_cached = true; predictor->RecordURLResponse(summary); }
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_tab_helper.h b/chrome/browser/predictors/resource_prefetch_predictor_tab_helper.h index 5cbabdc..917135c 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_tab_helper.h +++ b/chrome/browser/predictors/resource_prefetch_predictor_tab_helper.h
@@ -20,7 +20,9 @@ // content::WebContentsObserver implementation void DocumentOnLoadCompletedInMainFrame() override; void DidLoadResourceFromMemoryCache( - const content::LoadFromMemoryCacheDetails& details) override; + const GURL& url, + const std::string& mime_type, + content::ResourceType resource_type) override; private: explicit ResourcePrefetchPredictorTabHelper(
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_tables_unittest.cc b/chrome/browser/predictors/resource_prefetch_predictor_tables_unittest.cc index af63d51..5146ab3 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_tables_unittest.cc +++ b/chrome/browser/predictors/resource_prefetch_predictor_tables_unittest.cc
@@ -238,7 +238,7 @@ for (ResourceRows::const_iterator rhs_it = rhs.begin(); rhs_it != rhs.end(); ++rhs_it) { const GURL& resource = rhs_it->resource_url; - EXPECT_FALSE(ContainsKey(resources_seen, resource)); + EXPECT_FALSE(base::ContainsKey(resources_seen, resource)); for (ResourceRows::const_iterator lhs_it = lhs.begin(); lhs_it != lhs.end(); ++lhs_it) { @@ -247,7 +247,7 @@ break; } } - EXPECT_TRUE(ContainsKey(resources_seen, resource)); + EXPECT_TRUE(base::ContainsKey(resources_seen, resource)); } EXPECT_EQ(lhs.size(), resources_seen.size()); }
diff --git a/chrome/browser/predictors/resource_prefetcher.cc b/chrome/browser/predictors/resource_prefetcher.cc index b81ff69..3a818d1 100644 --- a/chrome/browser/predictors/resource_prefetcher.cc +++ b/chrome/browser/predictors/resource_prefetcher.cc
@@ -57,8 +57,8 @@ ResourcePrefetcher::~ResourcePrefetcher() { // Delete any pending net::URLRequests. - STLDeleteContainerPairFirstPointers(inflight_requests_.begin(), - inflight_requests_.end()); + base::STLDeleteContainerPairFirstPointers(inflight_requests_.begin(), + inflight_requests_.end()); } void ResourcePrefetcher::Start() {
diff --git a/chrome/browser/predictors/resource_prefetcher_manager.cc b/chrome/browser/predictors/resource_prefetcher_manager.cc index 822935ea..69c8bfc 100644 --- a/chrome/browser/predictors/resource_prefetcher_manager.cc +++ b/chrome/browser/predictors/resource_prefetcher_manager.cc
@@ -46,8 +46,8 @@ void ResourcePrefetcherManager::ShutdownOnIOThread() { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - STLDeleteContainerPairSecondPointers(prefetcher_map_.begin(), - prefetcher_map_.end()); + base::STLDeleteContainerPairSecondPointers(prefetcher_map_.begin(), + prefetcher_map_.end()); } void ResourcePrefetcherManager::MaybeAddPrefetch( @@ -59,7 +59,7 @@ // Don't add a duplicate prefetch for the same host or URL. std::string key = key_type == PREFETCH_KEY_TYPE_HOST ? navigation_id.main_frame_url.host() : navigation_id.main_frame_url.spec(); - if (ContainsKey(prefetcher_map_, key)) + if (base::ContainsKey(prefetcher_map_, key)) return; ResourcePrefetcher* prefetcher = new ResourcePrefetcher(
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index 64d4108c..10726d0 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -16,8 +16,7 @@ #include "chrome/browser/browser_shutdown.h" #include "chrome/browser/budget_service/background_budget_service.h" #include "chrome/browser/chrome_content_browser_client.h" -#include "chrome/browser/component_updater/recovery_component_installer.h" -#include "chrome/browser/component_updater/supervised_user_whitelist_installer.h" +#include "chrome/browser/component_updater/component_updater_prefs.h" #include "chrome/browser/custom_handlers/protocol_handler_registry.h" #include "chrome/browser/devtools/devtools_window.h" #include "chrome/browser/download/download_prefs.h" @@ -94,7 +93,7 @@ #include "components/ssl_config/ssl_config_service_manager.h" #include "components/startup_metric_utils/browser/startup_metric_utils.h" #include "components/subresource_filter/core/browser/ruleset_service.h" -#include "components/sync_driver/sync_prefs.h" +#include "components/sync/driver/sync_prefs.h" #include "components/syncable_prefs/pref_service_syncable.h" #include "components/translate/core/browser/translate_prefs.h" #include "components/update_client/update_client.h" @@ -176,7 +175,6 @@ #include "chrome/browser/chromeos/platform_keys/key_permissions.h" #include "chrome/browser/chromeos/policy/auto_enrollment_client.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/policy/consumer_management_service.h" #include "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h" #include "chrome/browser/chromeos/policy/device_status_collector.h" #include "chrome/browser/chromeos/policy/policy_cert_service_factory.h" @@ -207,6 +205,7 @@ #if defined(OS_ANDROID) #include "chrome/browser/notifications/notification_platform_bridge_android.h" +#include "components/ntp_snippets/offline_pages/offline_page_suggestions_provider.h" #endif #if defined(OS_CHROMEOS) && defined(ENABLE_APP_LIST) @@ -329,8 +328,7 @@ ChromeMetricsServiceClient::RegisterPrefs(registry); ChromeTracingDelegate::RegisterPrefs(registry); variations::VariationsService::RegisterPrefs(registry); - component_updater::RegisterPrefsForRecoveryComponent(registry); - component_updater::SupervisedUserWhitelistInstaller::RegisterPrefs(registry); + component_updater::RegisterPrefs(registry); ExternalProtocolHandler::RegisterPrefs(registry); flags_ui::PrefServiceFlagsStorage::RegisterPrefs(registry); geolocation::RegisterPrefs(registry); @@ -417,7 +415,6 @@ invalidation::InvalidatorStorage::RegisterPrefs(registry); policy::AutoEnrollmentClient::RegisterPrefs(registry); policy::BrowserPolicyConnectorChromeOS::RegisterPrefs(registry); - policy::ConsumerManagementService::RegisterPrefs(registry); policy::DeviceCloudPolicyManagerChromeOS::RegisterPrefs(registry); policy::DeviceStatusCollector::RegisterPrefs(registry); policy::PolicyCertServiceFactory::RegisterPrefs(registry); @@ -562,6 +559,7 @@ #if defined(OS_ANDROID) NotificationPlatformBridgeAndroid::RegisterProfilePrefs(registry); + ntp_snippets::OfflinePageSuggestionsProvider::RegisterProfilePrefs(registry); #endif #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/prefs/chrome_pref_service_factory.cc b/chrome/browser/prefs/chrome_pref_service_factory.cc index d984a44..8441372 100644 --- a/chrome/browser/prefs/chrome_pref_service_factory.cc +++ b/chrome/browser/prefs/chrome_pref_service_factory.cc
@@ -49,7 +49,7 @@ #include "components/search_engines/search_engines_pref_names.h" #include "components/signin/core/common/signin_pref_names.h" #include "components/sync/base/model_type.h" -#include "components/sync_driver/pref_names.h" +#include "components/sync/driver/pref_names.h" #include "components/syncable_prefs/pref_model_associator.h" #include "components/syncable_prefs/pref_service_syncable.h" #include "components/syncable_prefs/pref_service_syncable_factory.h"
diff --git a/chrome/browser/printing/background_printing_manager.cc b/chrome/browser/printing/background_printing_manager.cc index 1f81bb48..cc7adae4 100644 --- a/chrome/browser/printing/background_printing_manager.cc +++ b/chrome/browser/printing/background_printing_manager.cc
@@ -61,7 +61,7 @@ // preview WebContents trying to print). In such a case it will fail to print, // but we should at least clean up the observers. // TODO(thestig): Handle this case better. - STLDeleteValues(&printing_contents_map_); + base::STLDeleteValues(&printing_contents_map_); } void BackgroundPrintingManager::OwnPrintPreviewDialog( @@ -131,7 +131,7 @@ bool BackgroundPrintingManager::HasPrintPreviewDialog( WebContents* preview_dialog) { - return ContainsKey(printing_contents_map_, preview_dialog); + return base::ContainsKey(printing_contents_map_, preview_dialog); } } // namespace printing
diff --git a/chrome/browser/printing/print_preview_data_service.cc b/chrome/browser/printing/print_preview_data_service.cc index ab81695..4f6c1e9 100644 --- a/chrome/browser/printing/print_preview_data_service.cc +++ b/chrome/browser/printing/print_preview_data_service.cc
@@ -52,7 +52,8 @@ // Returns the available draft page count. int GetAvailableDraftPageCount() { int page_data_map_size = page_data_map_.size(); - if (ContainsKey(page_data_map_, printing::COMPLETE_PREVIEW_DOCUMENT_INDEX)) + if (base::ContainsKey(page_data_map_, + printing::COMPLETE_PREVIEW_DOCUMENT_INDEX)) page_data_map_size--; return page_data_map_size; } @@ -105,7 +106,7 @@ int32_t preview_ui_id, int index, scoped_refptr<base::RefCountedBytes> data_bytes) { - if (!ContainsKey(data_store_map_, preview_ui_id)) { + if (!base::ContainsKey(data_store_map_, preview_ui_id)) { data_store_map_[preview_ui_id] = make_scoped_refptr(new PrintPreviewDataStore()); }
diff --git a/chrome/browser/process_singleton_posix.cc b/chrome/browser/process_singleton_posix.cc index f9880c7..d8ea926e 100644 --- a/chrome/browser/process_singleton_posix.cc +++ b/chrome/browser/process_singleton_posix.cc
@@ -559,7 +559,7 @@ ~LinuxWatcher() override { DCHECK_CURRENTLY_ON(BrowserThread::IO); - STLDeleteElements(&readers_); + base::STLDeleteElements(&readers_); base::MessageLoopForIO* ml = base::MessageLoopForIO::current(); ml->RemoveDestructionObserver(this);
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc index 0f4ec9d..0a16760 100644 --- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -90,8 +90,6 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/ownership/owner_settings_service_chromeos_factory.h" -#include "chrome/browser/chromeos/policy/consumer_enrollment_handler_factory.h" -#include "chrome/browser/chromeos/policy/consumer_management_notifier_factory.h" #include "chrome/browser/chromeos/policy/policy_cert_service_factory.h" #include "chrome/browser/chromeos/policy/recommendation_restorer_factory.h" #include "chrome/browser/chromeos/policy/user_cloud_policy_manager_factory_chromeos.h" @@ -282,8 +280,6 @@ policy::ProfilePolicyConnectorFactory::GetInstance(); #if defined(OS_CHROMEOS) chromeos::OwnerSettingsServiceChromeOSFactory::GetInstance(); - policy::ConsumerEnrollmentHandlerFactory::GetInstance(); - policy::ConsumerManagementNotifierFactory::GetInstance(); policy::PolicyCertServiceFactory::GetInstance(); policy::RecommendationRestorerFactory::GetInstance(); policy::UserCloudPolicyManagerFactoryChromeOS::GetInstance();
diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc index dc2e7ce..a4fc11b 100644 --- a/chrome/browser/profiles/profile.cc +++ b/chrome/browser/profiles/profile.cc
@@ -17,7 +17,7 @@ #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" -#include "components/sync_driver/sync_prefs.h" +#include "components/sync/driver/sync_prefs.h" #include "content/public/browser/host_zoom_map.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index 5e842004..e0ccdcfd 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc
@@ -417,13 +417,8 @@ set_is_guest_profile(path == ProfileManager::GetGuestProfilePath()); set_is_system_profile(path == ProfileManager::GetSystemProfilePath()); - // Determine if prefetch is enabled for this profile. - // If not profile_manager is present, it means we are in a unittest. - const base::CommandLine* command_line = - base::CommandLine::ForCurrentProcess(); + // If profile_manager is not present, it means we are in a unittest. predictor_ = chrome_browser_net::Predictor::CreatePredictor( - !command_line->HasSwitch(switches::kDisablePreconnect), - !command_line->HasSwitch(switches::kDnsPrefetchDisable), g_browser_process->profile_manager() == NULL); // If we are creating the profile synchronously, then we should load the
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc index fd8d9a342..d1ab4a9 100644 --- a/chrome/browser/profiles/profile_impl_io_data.cc +++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -68,6 +68,10 @@ #include "net/url_request/url_request_job_factory_impl.h" #include "storage/browser/quota/special_storage_policy.h" +#if defined(OS_ANDROID) +#include "chrome/browser/android/offline_pages/offline_page_request_handler.h" +#endif // defined(OS_ANDROID) + namespace { net::BackendType ChooseCacheBackendType() { @@ -528,6 +532,15 @@ new net::URLRequestJobFactoryImpl()); InstallProtocolHandlers(main_job_factory.get(), protocol_handlers); + // Install the Offline Page Interceptor. +#if defined(OS_ANDROID) + std::unique_ptr<net::URLRequestInterceptor> offline_page_interceptor = + offline_pages::OfflinePageRequestHandler::CreateInterceptor( + profile_params->profile); + if (offline_page_interceptor) + request_interceptors.push_back(std::move(offline_page_interceptor)); +#endif + // The data reduction proxy interceptor should be as close to the network // as possible. request_interceptors.insert(
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index dd0f063..11b38772 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc
@@ -75,7 +75,7 @@ #include "components/policy/core/common/cloud/user_cloud_policy_manager.h" #include "components/prefs/pref_service.h" #include "components/signin/core/common/signin_pref_names.h" -#include "components/sync_driver/pref_names.h" +#include "components/sync/driver/pref_names.h" #include "components/url_formatter/url_fixer.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/host_zoom_map.h" @@ -817,7 +817,7 @@ content::URLRequestInterceptorScopedVector request_interceptors) const { DCHECK(initialized_); net::URLRequestContext* context = NULL; - if (ContainsKey(app_request_context_map_, partition_descriptor)) { + if (base::ContainsKey(app_request_context_map_, partition_descriptor)) { context = app_request_context_map_[partition_descriptor]; } else { context = AcquireIsolatedAppRequestContext( @@ -835,7 +835,8 @@ const StoragePartitionDescriptor& partition_descriptor) const { DCHECK(initialized_); net::URLRequestContext* context = NULL; - if (ContainsKey(isolated_media_request_context_map_, partition_descriptor)) { + if (base::ContainsKey(isolated_media_request_context_map_, + partition_descriptor)) { context = isolated_media_request_context_map_[partition_descriptor]; } else { context = AcquireIsolatedMediaRequestContext(app_context,
diff --git a/chrome/browser/push_messaging/push_messaging_service_impl.cc b/chrome/browser/push_messaging/push_messaging_service_impl.cc index be99393..d69217db 100644 --- a/chrome/browser/push_messaging/push_messaging_service_impl.cc +++ b/chrome/browser/push_messaging/push_messaging_service_impl.cc
@@ -204,6 +204,10 @@ in_flight_message_deliveries_.insert(app_id); #if BUILDFLAG(ENABLE_BACKGROUND) + UMA_HISTOGRAM_BOOLEAN("PushMessaging.ReceivedMessageInBackground", + g_browser_process->background_mode_manager() + ->IsBackgroundWithoutWindows()); + if (!in_flight_keep_alive_) { in_flight_keep_alive_.reset( new ScopedKeepAlive(KeepAliveOrigin::IN_FLIGHT_PUSH_MESSAGE,
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index ad0e6d23..82ed3656 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -56,7 +56,6 @@ #include "chrome/browser/tab_contents/retargeting_details.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_commands.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_navigator_params.h" @@ -1586,9 +1585,7 @@ incognito_avail != IncognitoModePrefs::DISABLED; case IDC_PRINT: - return prefs->GetBoolean(prefs::kPrintingEnabled) && - (params_.media_type == WebContextMenuData::MediaTypeNone || - params_.media_flags & WebContextMenuData::MediaCanPrint); + return IsPrintPreviewEnabled(); case IDC_CONTENT_CONTEXT_SEARCHWEBFOR: case IDC_CONTENT_CONTEXT_GOTOURL: @@ -2087,6 +2084,16 @@ ui::CLIPBOARD_TYPE_COPY_PASTE); } +bool RenderViewContextMenu::IsPrintPreviewEnabled() const { + if (params_.media_type != WebContextMenuData::MediaTypeNone && + !(params_.media_flags & WebContextMenuData::MediaCanPrint)) { + return false; + } + + Browser* browser = GetBrowser(); + return browser && chrome::CanPrint(browser); +} + bool RenderViewContextMenu::IsRouteMediaEnabled() const { if (!media_router::MediaRouterEnabled(browser_context_)) return false; @@ -2449,3 +2456,7 @@ source_web_contents_->GetRenderViewHost()-> ExecutePluginActionAtLocation(location, action); } + +Browser* RenderViewContextMenu::GetBrowser() const { + return chrome::FindBrowserWithWebContents(embedder_web_contents_); +}
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.h b/chrome/browser/renderer_context_menu/render_view_context_menu.h index c4c63cb..8d213fcd 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.h +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.h
@@ -14,6 +14,7 @@ #include "base/observer_list.h" #include "base/strings/string16.h" #include "chrome/browser/custom_handlers/protocol_handler_registry.h" +#include "chrome/browser/ui/browser.h" #include "components/renderer_context_menu/context_menu_content_type.h" #include "components/renderer_context_menu/render_view_context_menu_base.h" #include "components/renderer_context_menu/render_view_context_menu_observer.h" @@ -164,6 +165,7 @@ bool IsSavePageEnabled() const; bool IsPasteEnabled() const; bool IsPasteAndMatchStyleEnabled() const; + bool IsPrintPreviewEnabled() const; bool IsRouteMediaEnabled() const; // Command execution functions. @@ -201,6 +203,8 @@ void PluginActionAt(const gfx::Point& location, const blink::WebPluginAction& action); + Browser* GetBrowser() const; + // Returns a list of registered ProtocolHandlers that can handle the clicked // on URL. ProtocolHandlerRegistry::ProtocolHandlerList GetHandlersForLinkUrl();
diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc index 53d4e66..e56c24f 100644 --- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc +++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc
@@ -49,6 +49,7 @@ #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h" #include "components/google/core/browser/google_util.h" #include "components/policy/core/common/cloud/policy_header_io_helper.h" +#include "components/rappor/rappor_utils.h" #include "components/search_engines/template_url_service.h" #include "components/variations/net/variations_http_headers.h" #include "content/public/browser/browser_thread.h" @@ -104,6 +105,7 @@ #endif #if defined(OS_ANDROID) +#include "chrome/browser/android/offline_pages/offline_page_request_handler.h" #include "chrome/browser/renderer_host/data_reduction_proxy_resource_throttle_android.h" #include "components/navigation_interception/intercept_navigation_delegate.h" #endif @@ -493,6 +495,13 @@ io_data->resource_prefetch_predictor_observer()->OnRequestStarted( request, resource_type, info->GetChildID(), info->GetRenderFrameID()); } + +#if defined(OS_ANDROID) + if (!io_data->IsOffTheRecord()) { + offline_pages::OfflinePageRequestHandler::InitializeHandler( + request, resource_type); + } +#endif } void ChromeResourceDispatcherHostDelegate::DownloadStarting( @@ -869,3 +878,22 @@ return ProfileIOData::FromResourceContext(resource_context)-> CreateClientCertStore(); } + +// Record RAPPOR for aborted main frame loads. Separate into a fast and +// slow bucket because a shocking number of aborts happen under 100ms. +void ChromeResourceDispatcherHostDelegate::OnAbortedFrameLoad( + const GURL& url, + base::TimeDelta request_loading_time) { + if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { + BrowserThread::PostTask( + BrowserThread::UI, FROM_HERE, + base::Bind(&ChromeResourceDispatcherHostDelegate::OnAbortedFrameLoad, + base::Unretained(this), url, request_loading_time)); + return; + } + + std::string metric_name = (request_loading_time.InMilliseconds() < 100 ? + "Net.ErrAborted.Fast" : "Net.ErrAborted.Slow"); + rappor::SampleDomainAndRegistryFromGURL( + g_browser_process->rappor_service(), metric_name, url); +}
diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h index dd211f29..dcdc499 100644 --- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h +++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.h
@@ -97,6 +97,8 @@ net::URLRequest* request) const override; std::unique_ptr<net::ClientCertStore> CreateClientCertStore( content::ResourceContext* resource_context) override; + void OnAbortedFrameLoad(const GURL& url, + base::TimeDelta request_loading_time) override; // Called on the UI thread. Allows switching out the // ExternalProtocolHandler::Delegate for testing code.
diff --git a/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc b/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc index 15a8ae0..8950f605 100644 --- a/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc +++ b/chrome/browser/renderer_host/site_per_process_text_input_browsertest.cc
@@ -565,6 +565,43 @@ reset_state_observer.Wait(); } +// This test creates a page with multiple child frames and adds an <input> to +// each frame. Then, sequentially, each <input> is focused by sending a tab key. +// Then, after |TextInputState.type| for a view is changed to text, the test +// sends a set composition IPC to the active widget and waits until the widget +// updates its composition range. +IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest, + TrackCompositionRangeForAllFrames) { + CreateIframePage("a(b,c(a,b),d)"); + std::vector<content::RenderFrameHost*> frames{ + GetFrame(IndexVector{}), GetFrame(IndexVector{0}), + GetFrame(IndexVector{1}), GetFrame(IndexVector{1, 0}), + GetFrame(IndexVector{1, 1}), GetFrame(IndexVector{2})}; + std::vector<content::RenderWidgetHostView*> views; + for (auto* frame : frames) + views.push_back(frame->GetView()); + for (size_t i = 0; i < frames.size(); ++i) + AddInputFieldToFrame(frames[i], "text", "text", true); + + content::WebContents* web_contents = active_contents(); + + auto send_tab_set_composition_wait_for_bounds_change = [&web_contents]( + content::RenderWidgetHostView* view) { + ViewTextInputTypeObserver type_observer(web_contents, view, + ui::TEXT_INPUT_TYPE_TEXT); + SimulateKeyPress(web_contents, ui::DomKey::TAB, ui::DomCode::TAB, + ui::VKEY_TAB, false, false, false, false); + type_observer.Wait(); + + ViewCompositionRangeChangedObserver range_observer(web_contents, view); + EXPECT_TRUE(content::RequestCompositionInfoFromActiveWidget(web_contents)); + range_observer.Wait(); + }; + + for (auto* view : views) + send_tab_set_composition_wait_for_bounds_change(view); +} + // TODO(ekaramad): Enable the following tests on other platforms when the // corresponding feature is implemented (http://crbug.com/578168). #if defined(USE_AURA) @@ -608,44 +645,6 @@ // This test creates a page with multiple child frames and adds an <input> to // each frame. Then, sequentially, each <input> is focused by sending a tab key. -// Then, after |TextInputState.type| for a view is changed to text, the test -// sends a set composition IPC to the active widget and waits until the widget -// updates its composition range. -IN_PROC_BROWSER_TEST_F(SitePerProcessTextInputManagerTest, - TrackCompositionRangeForAllFrames) { - // TODO(ekaramd): After IME methods are implemented for WebFrameWidgetImpl, - // change the page so that it contains child frames as well - // (crbug.com/626746). - CreateIframePage("a()"); - std::vector<content::RenderFrameHost*> frames{GetFrame(IndexVector{})}; - std::vector<content::RenderWidgetHostView*> views; - for (auto* frame : frames) - views.push_back(frame->GetView()); - for (size_t i = 0; i < frames.size(); ++i) - AddInputFieldToFrame(frames[i], "text", "", true); - - content::WebContents* web_contents = active_contents(); - - auto send_tab_set_composition_wait_for_bounds_change = - [&web_contents](content::RenderWidgetHostView* view) { - ViewTextInputTypeObserver type_observer(web_contents, view, - ui::TEXT_INPUT_TYPE_TEXT); - SimulateKeyPress(web_contents, ui::DomKey::TAB, ui::DomCode::TAB, - ui::VKEY_TAB, false, false, false, false); - type_observer.Wait(); - ViewCompositionRangeChangedObserver range_observer(web_contents, view); - content::SetCompositionForRenderWidgetHost( - view->GetRenderWidgetHost(), base::ASCIIToUTF16("text"), - {ui::CompositionUnderline()}, gfx::Range::InvalidRange(), 0, 0); - range_observer.Wait(); - }; - - for (auto* view : views) - send_tab_set_composition_wait_for_bounds_change(view); -} - -// This test creates a page with multiple child frames and adds an <input> to -// each frame. Then, sequentially, each <input> is focused by sending a tab key. // After focusing each input, a sequence of key presses (character 'E') are sent // to the focused widget and then the whole text is selected using Ctrl+A. The // test then verifies that the selection length equals the length of the
diff --git a/chrome/browser/renderer_preferences_util.cc b/chrome/browser/renderer_preferences_util.cc index 1a1a910..d47d2d0 100644 --- a/chrome/browser/renderer_preferences_util.cc +++ b/chrome/browser/renderer_preferences_util.cc
@@ -4,7 +4,11 @@ #include "chrome/browser/renderer_preferences_util.h" +#include <string> + #include "base/macros.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" #include "build/build_config.h" #include "chrome/browser/profiles/profile.h" #include "chrome/common/pref_names.h" @@ -28,6 +32,46 @@ #include "ui/views/linux_ui/linux_ui.h" #endif +namespace { + +// Parses a string |range| with a port range in the form "<min>-<max>". +// If |range| is not in the correct format or contains an invalid range, zero +// is written to |min_port| and |max_port|. +// TODO(guidou): Consider replacing with remoting/protocol/port_range.cc +void ParsePortRange(const std::string& range, + uint16_t* min_port, + uint16_t* max_port) { + *min_port = 0; + *max_port = 0; + + if (range.empty()) + return; + + size_t separator_index = range.find('-'); + if (separator_index == std::string::npos) + return; + + std::string min_port_string, max_port_string; + base::TrimWhitespaceASCII(range.substr(0, separator_index), base::TRIM_ALL, + &min_port_string); + base::TrimWhitespaceASCII(range.substr(separator_index + 1), base::TRIM_ALL, + &max_port_string); + unsigned min_port_uint, max_port_uint; + if (!base::StringToUint(min_port_string, &min_port_uint) || + !base::StringToUint(max_port_string, &max_port_uint)) { + return; + } + if (min_port_uint == 0 || min_port_uint > max_port_uint || + max_port_uint > UINT16_MAX) { + return; + } + + *min_port = static_cast<uint16_t>(min_port_uint); + *max_port = static_cast<uint16_t>(max_port_uint); +} + +} // namespace + namespace renderer_preferences_util { void UpdateFromSystemSettings(content::RendererPreferences* prefs, @@ -55,6 +99,10 @@ prefs->webrtc_ip_handling_policy = pref_service->GetString(prefs::kWebRTCIPHandlingPolicy); } + std::string webrtc_udp_port_range = + pref_service->GetString(prefs::kWebRTCUDPPortRange); + ParsePortRange(webrtc_udp_port_range, &prefs->webrtc_udp_min_port, + &prefs->webrtc_udp_max_port); #endif #if defined(USE_DEFAULT_RENDER_THEME)
diff --git a/chrome/browser/resources/about_invalidations.css b/chrome/browser/resources/about_invalidations.css index 4f52a60..c8626af 100644 --- a/chrome/browser/resources/about_invalidations.css +++ b/chrome/browser/resources/about_invalidations.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ body { font-size: 80%;
diff --git a/chrome/browser/resources/about_sys/about_sys.css b/chrome/browser/resources/about_sys/about_sys.css index ffc45d0..7952417 100644 --- a/chrome/browser/resources/about_sys/about_sys.css +++ b/chrome/browser/resources/about_sys/about_sys.css
@@ -1,7 +1,6 @@ /* 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. */ #anchor { display: none;
diff --git a/chrome/browser/resources/chromeos/arc_support/lso.css b/chrome/browser/resources/chromeos/arc_support/lso.css index 3e5556544..a4629ba 100644 --- a/chrome/browser/resources/chromeos/arc_support/lso.css +++ b/chrome/browser/resources/chromeos/arc_support/lso.css
@@ -1,8 +1,6 @@ -/** - * Copyright 2016 The Chromium Authors. All rights reserved. +/* Copyright 2016 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. */ ::-webkit-scrollbar { background: transparent;
diff --git a/chrome/browser/resources/chromeos/arc_support/main.css b/chrome/browser/resources/chromeos/arc_support/main.css index 02be7b71..563da75 100644 --- a/chrome/browser/resources/chromeos/arc_support/main.css +++ b/chrome/browser/resources/chromeos/arc_support/main.css
@@ -1,8 +1,6 @@ -/** - * Copyright 2016 The Chromium Authors. All rights reserved. +/* Copyright 2016 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. */ html, body,
diff --git a/chrome/browser/resources/chromeos/arc_support/playstore.css b/chrome/browser/resources/chromeos/arc_support/playstore.css index 08cbf22..74f01ad 100644 --- a/chrome/browser/resources/chromeos/arc_support/playstore.css +++ b/chrome/browser/resources/chromeos/arc_support/playstore.css
@@ -1,8 +1,6 @@ -/** - * Copyright 2016 The Chromium Authors. All rights reserved. +/* Copyright 2016 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. */ body { margin: 0;
diff --git a/chrome/browser/resources/chromeos/choose_mobile_network.css b/chrome/browser/resources/chromeos/choose_mobile_network.css index 6486685..70d1d9d 100644 --- a/chrome/browser/resources/chromeos/choose_mobile_network.css +++ b/chrome/browser/resources/chromeos/choose_mobile_network.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ .scanning-msg { -webkit-margin-start: 50px;
diff --git a/chrome/browser/resources/chromeos/chromevox/BUILD.gn b/chrome/browser/resources/chromeos/chromevox/BUILD.gn index ca38116..1be3800 100644 --- a/chrome/browser/resources/chromeos/chromevox/BUILD.gn +++ b/chrome/browser/resources/chromeos/chromevox/BUILD.gn
@@ -5,7 +5,6 @@ import("//build/config/features.gni") import("//testing/test.gni") import("//chrome/test/base/js2gtest.gni") -import("chromevox.gni") assert(is_chromeos) @@ -15,6 +14,221 @@ chromevox_compress_js = !is_debug } +closure_library_dir = + "//chrome/third_party/chromevox/third_party/closure-library/closure/goog" + +jsbundler_modules = rebase_path([ + "depstree.py", + "source.py", + "treescan.py", + ], + ".", + "$closure_library_dir/../bin/build") +jsbundler_modules += + [ "//third_party/WebKit/Source/devtools/scripts/rjsmin.py" ] + +# List of all modules that are included in one or more of the production +# chromevox scripts. +chromevox_modules = [ + "braille/braille_display_manager.js", + "braille/braille_input_handler.js", + "braille/braille_key_types.js", + "braille/braille_table.js", + "braille/braille_translator_manager.js", + "braille/expanding_braille_translator.js", + "braille/liblouis.js", + "braille/nav_braille.js", + "braille/pan_strategy.js", + "braille/spans.js", + "chromevox/background/background.js", + "chromevox/background/braille_captions_background.js", + "chromevox/background/injected_script_loader.js", + "chromevox/background/kbexplorer.js", + "chromevox/background/keymaps/key_map.js", + "chromevox/background/mathmaps/math_map.js", + "chromevox/background/options.js", + "chromevox/background/prefs.js", + "chromevox/background/tabs_api_handler.js", + "chromevox/injected/active_indicator.js", + "chromevox/injected/api_implementation.js", + "chromevox/injected/api_util.js", + "chromevox/injected/console_tts.js", + "chromevox/injected/event_suspender.js", + "chromevox/injected/event_watcher.js", + "chromevox/injected/history.js", + "chromevox/injected/init_document.js", + "chromevox/injected/init_globals.js", + "chromevox/injected/initial_speech.js", + "chromevox/injected/keyboard_handler.js", + "chromevox/injected/live_regions.js", + "chromevox/injected/navigation_history.js", + "chromevox/injected/navigation_manager.js", + "chromevox/injected/navigation_shifter.js", + "chromevox/injected/navigation_speaker.js", + "chromevox/injected/node_breadcrumb.js", + "chromevox/injected/script_installer.js", + "chromevox/injected/serializer.js", + "chromevox/injected/ui/braille_overlay_widget.js", + "chromevox/injected/ui/context_menu_widget.js", + "chromevox/injected/ui/keyboard_help_widget.js", + "chromevox/injected/ui/node_search_widget.js", + "chromevox/injected/ui/overlay_widget.js", + "chromevox/injected/ui/search_widget.js", + "chromevox/injected/ui/select_widget.js", + "chromevox/injected/ui/spoken_messages.js", + "chromevox/injected/ui/widget.js", + "chromevox/injected/user_commands.js", + "chromevox/injected/user_event_detail.js", + "common/aria_util.js", + "common/aural_style_util.js", + "common/braille_text_handler.js", + "common/braille_util.js", + "common/buildinfo.js", + "common/chromevox.js", + "common/chromevox_json.js", + "common/command_store.js", + "common/composite_tts.js", + "common/content_editable_extractor.js", + "common/cursor.js", + "common/cursor_selection.js", + "common/date_widget.js", + "common/description_util.js", + "common/dom_predicates.js", + "common/dom_util.js", + "common/earcon_util.js", + "common/editable_text.js", + "common/editable_text_area_shadow.js", + "common/editable_text_base.js", + "common/find_util.js", + "common/focus_util.js", + "common/focuser.js", + "common/group_util.js", + "common/interframe.js", + "common/key_sequence.js", + "common/key_util.js", + "common/math_semantic_attr.js", + "common/math_semantic_tree.js", + "common/math_semantic_util.js", + "common/math_util.js", + "common/media_widget.js", + "common/memoize.js", + "common/msgs.js", + "common/nav_description.js", + "common/nav_math_description.js", + "common/node_state.js", + "common/page_selection.js", + "common/platform_util.js", + "common/selection_util.js", + "common/spannable.js", + "common/string_util.js", + "common/table_util.js", + "common/time_widget.js", + "common/traverse_content.js", + "common/traverse_math.js", + "common/traverse_table.js", + "common/traverse_util.js", + "common/xpath_util.js", + "cvox2/background/automation_object_constructor_installer.js", + "cvox2/background/automation_predicate.js", + "cvox2/background/automation_util.js", + "cvox2/background/background.js", + "cvox2/background/base_automation_handler.js", + "cvox2/background/chromevox_state.js", + "cvox2/background/command_handler.js", + "cvox2/background/constants.js", + "cvox2/background/cursors.js", + "cvox2/background/desktop_automation_handler.js", + "cvox2/background/earcon_engine.js", + "cvox2/background/editing.js", + "cvox2/background/i_search.js", + "cvox2/background/keyboard_handler.js", + "cvox2/background/live_regions.js", + "cvox2/background/next_earcons.js", + "cvox2/background/notifications.js", + "cvox2/background/output.js", + "cvox2/background/panel.js", + "cvox2/background/panel_command.js", + "cvox2/background/panel_menu.js", + "cvox2/background/panel_menu_item.js", + "cvox2/background/stubs.js", + "cvox2/background/tabs_automation_handler.js", + "cvox2/background/tree_walker.js", + "cvox2/background/tutorial.js", + "cvox2/injected/keyboard_handler.js", + "cvox2/injected/loader.js", + "extensions/searchvox/abstract_result.js", + "extensions/searchvox/constants.js", + "extensions/searchvox/context_menu.js", + "extensions/searchvox/loader.js", + "extensions/searchvox/results.js", + "extensions/searchvox/search.js", + "extensions/searchvox/search_tools.js", + "extensions/searchvox/util.js", + "host/chrome/braille.js", + "host/chrome/braille_background.js", + "host/chrome/classic_earcons.js", + "host/chrome/earcons.js", + "host/chrome/extension_bridge.js", + "host/chrome/host.js", + "host/chrome/mathjax.js", + "host/chrome/tts.js", + "host/chrome/tts_background.js", + "host/chrome/tts_base.js", + "host/interface/abstract_earcons.js", + "host/interface/abstract_host.js", + "host/interface/abstract_mathjax.js", + "host/interface/abstract_tts.js", + "host/interface/braille_interface.js", + "host/interface/host_factory.js", + "host/interface/mathjax_interface.js", + "host/interface/tts_interface.js", + "speech_rules/base_rule_store.js", + "speech_rules/math_simple_store.js", + "speech_rules/math_store.js", + "speech_rules/mathml_store.js", + "speech_rules/mathml_store_rules.js", + "speech_rules/mathml_store_util.js", + "speech_rules/speech_rule.js", + "speech_rules/speech_rule_engine.js", + "speech_rules/speech_rule_evaluator.js", + "speech_rules/speech_rule_functions.js", + "speech_rules/speech_rule_store.js", + "speech_rules/store_util.js", + "walkers/abstract_node_walker.js", + "walkers/abstract_selection_walker.js", + "walkers/abstract_shifter.js", + "walkers/abstract_walker.js", + "walkers/bare_object_walker.js", + "walkers/character_walker.js", + "walkers/column_walker.js", + "walkers/group_walker.js", + "walkers/layout_line_walker.js", + "walkers/math_shifter.js", + "walkers/object_walker.js", + "walkers/row_walker.js", + "walkers/sentence_walker.js", + "walkers/structural_line_walker.js", + "walkers/table_shifter.js", + "walkers/table_walker.js", + "walkers/word_walker.js", +] + +# Closure library modules neede by chromevox. +relative_closure_library_modules = [ + "i18n/pluralrules.js", + "i18n/ordinalrules.js", + "i18n/messageformat.js", + "string/string.js", + "dom/nodetype.js", + "base.js", + "asserts/asserts.js", + "debug/error.js", + "object/object.js", +] + +closure_library_modules = + rebase_path(relative_closure_library_modules, ".", closure_library_dir) + chromevox_out_dir = "$root_out_dir/resources/chromeos/chromevox" group("chromevox") {
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox.gni b/chrome/browser/resources/chromeos/chromevox/chromevox.gni deleted file mode 100644 index fa0f455..0000000 --- a/chrome/browser/resources/chromeos/chromevox/chromevox.gni +++ /dev/null
@@ -1,224 +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. -# Common variables shared amongst all ChromeVox targets. - -assert(is_chromeos) - -# TODO(plundblad): Move the below variables to BUILD.gn when crbug.com/395883 -# is resolved. - -closure_library_dir = - "//chrome/third_party/chromevox/third_party/closure-library/closure/goog" - -jsbundler_modules = rebase_path([ - "depstree.py", - "source.py", - "treescan.py", - ], - ".", - "$closure_library_dir/../bin/build") -jsbundler_modules += - [ "//third_party/WebKit/Source/devtools/scripts/rjsmin.py" ] - -# List of all modules that are included in one or more of the production -# chromevox scripts. -chromevox_modules = [ - "braille/braille_display_manager.js", - "braille/braille_input_handler.js", - "braille/braille_key_types.js", - "braille/braille_table.js", - "braille/braille_translator_manager.js", - "braille/expanding_braille_translator.js", - "braille/liblouis.js", - "braille/nav_braille.js", - "braille/pan_strategy.js", - "braille/spans.js", - "chromevox/background/background.js", - "chromevox/background/braille_captions_background.js", - "chromevox/background/injected_script_loader.js", - "chromevox/background/kbexplorer.js", - "chromevox/background/keymaps/key_map.js", - "chromevox/background/mathmaps/math_map.js", - "chromevox/background/options.js", - "chromevox/background/prefs.js", - "chromevox/background/tabs_api_handler.js", - "chromevox/injected/active_indicator.js", - "chromevox/injected/api_implementation.js", - "chromevox/injected/api_util.js", - "chromevox/injected/console_tts.js", - "chromevox/injected/event_suspender.js", - "chromevox/injected/event_watcher.js", - "chromevox/injected/history.js", - "chromevox/injected/init_document.js", - "chromevox/injected/init_globals.js", - "chromevox/injected/initial_speech.js", - "chromevox/injected/keyboard_handler.js", - "chromevox/injected/live_regions.js", - "chromevox/injected/navigation_history.js", - "chromevox/injected/navigation_manager.js", - "chromevox/injected/navigation_shifter.js", - "chromevox/injected/navigation_speaker.js", - "chromevox/injected/node_breadcrumb.js", - "chromevox/injected/script_installer.js", - "chromevox/injected/serializer.js", - "chromevox/injected/ui/braille_overlay_widget.js", - "chromevox/injected/ui/context_menu_widget.js", - "chromevox/injected/ui/keyboard_help_widget.js", - "chromevox/injected/ui/node_search_widget.js", - "chromevox/injected/ui/overlay_widget.js", - "chromevox/injected/ui/search_widget.js", - "chromevox/injected/ui/select_widget.js", - "chromevox/injected/ui/spoken_messages.js", - "chromevox/injected/ui/widget.js", - "chromevox/injected/user_commands.js", - "chromevox/injected/user_event_detail.js", - "common/aria_util.js", - "common/aural_style_util.js", - "common/braille_text_handler.js", - "common/braille_util.js", - "common/buildinfo.js", - "common/chromevox.js", - "common/chromevox_json.js", - "common/command_store.js", - "common/composite_tts.js", - "common/content_editable_extractor.js", - "common/cursor.js", - "common/cursor_selection.js", - "common/date_widget.js", - "common/description_util.js", - "common/dom_predicates.js", - "common/dom_util.js", - "common/earcon_util.js", - "common/editable_text.js", - "common/editable_text_area_shadow.js", - "common/editable_text_base.js", - "common/find_util.js", - "common/focus_util.js", - "common/focuser.js", - "common/group_util.js", - "common/interframe.js", - "common/key_sequence.js", - "common/key_util.js", - "common/math_semantic_attr.js", - "common/math_semantic_tree.js", - "common/math_semantic_util.js", - "common/math_util.js", - "common/media_widget.js", - "common/memoize.js", - "common/msgs.js", - "common/nav_description.js", - "common/nav_math_description.js", - "common/node_state.js", - "common/page_selection.js", - "common/platform_util.js", - "common/selection_util.js", - "common/spannable.js", - "common/string_util.js", - "common/table_util.js", - "common/time_widget.js", - "common/traverse_content.js", - "common/traverse_math.js", - "common/traverse_table.js", - "common/traverse_util.js", - "common/xpath_util.js", - "cvox2/background/automation_object_constructor_installer.js", - "cvox2/background/automation_predicate.js", - "cvox2/background/automation_util.js", - "cvox2/background/background.js", - "cvox2/background/base_automation_handler.js", - "cvox2/background/chromevox_state.js", - "cvox2/background/command_handler.js", - "cvox2/background/constants.js", - "cvox2/background/cursors.js", - "cvox2/background/desktop_automation_handler.js", - "cvox2/background/earcon_engine.js", - "cvox2/background/editing.js", - "cvox2/background/i_search.js", - "cvox2/background/keyboard_handler.js", - "cvox2/background/live_regions.js", - "cvox2/background/next_earcons.js", - "cvox2/background/notifications.js", - "cvox2/background/output.js", - "cvox2/background/panel.js", - "cvox2/background/panel_command.js", - "cvox2/background/panel_menu.js", - "cvox2/background/panel_menu_item.js", - "cvox2/background/stubs.js", - "cvox2/background/tabs_automation_handler.js", - "cvox2/background/tree_walker.js", - "cvox2/background/tutorial.js", - "cvox2/injected/keyboard_handler.js", - "cvox2/injected/loader.js", - "extensions/searchvox/abstract_result.js", - "extensions/searchvox/constants.js", - "extensions/searchvox/context_menu.js", - "extensions/searchvox/loader.js", - "extensions/searchvox/results.js", - "extensions/searchvox/search.js", - "extensions/searchvox/search_tools.js", - "extensions/searchvox/util.js", - "host/chrome/braille.js", - "host/chrome/braille_background.js", - "host/chrome/classic_earcons.js", - "host/chrome/earcons.js", - "host/chrome/extension_bridge.js", - "host/chrome/host.js", - "host/chrome/mathjax.js", - "host/chrome/tts.js", - "host/chrome/tts_background.js", - "host/chrome/tts_base.js", - "host/interface/abstract_earcons.js", - "host/interface/abstract_host.js", - "host/interface/abstract_mathjax.js", - "host/interface/abstract_tts.js", - "host/interface/braille_interface.js", - "host/interface/host_factory.js", - "host/interface/mathjax_interface.js", - "host/interface/tts_interface.js", - "speech_rules/base_rule_store.js", - "speech_rules/math_simple_store.js", - "speech_rules/math_store.js", - "speech_rules/mathml_store.js", - "speech_rules/mathml_store_rules.js", - "speech_rules/mathml_store_util.js", - "speech_rules/speech_rule.js", - "speech_rules/speech_rule_engine.js", - "speech_rules/speech_rule_evaluator.js", - "speech_rules/speech_rule_functions.js", - "speech_rules/speech_rule_store.js", - "speech_rules/store_util.js", - "walkers/abstract_node_walker.js", - "walkers/abstract_selection_walker.js", - "walkers/abstract_shifter.js", - "walkers/abstract_walker.js", - "walkers/bare_object_walker.js", - "walkers/character_walker.js", - "walkers/column_walker.js", - "walkers/group_walker.js", - "walkers/layout_line_walker.js", - "walkers/math_shifter.js", - "walkers/object_walker.js", - "walkers/row_walker.js", - "walkers/sentence_walker.js", - "walkers/structural_line_walker.js", - "walkers/table_shifter.js", - "walkers/table_walker.js", - "walkers/word_walker.js", -] - -# Closure library modules neede by chromevox. -relative_closure_library_modules = [ - "i18n/pluralrules.js", - "i18n/ordinalrules.js", - "i18n/messageformat.js", - "string/string.js", - "dom/nodetype.js", - "base.js", - "asserts/asserts.js", - "debug/error.js", - "object/object.js", -] - -closure_library_modules = - rebase_path(relative_closure_library_modules, ".", closure_library_dir)
diff --git a/chrome/browser/resources/chromeos/chromevox/chromevox/background/kbexplorer.js b/chrome/browser/resources/chromeos/chromevox/chromevox/background/kbexplorer.js index 49be20c..70a41282 100644 --- a/chrome/browser/resources/chromeos/chromevox/chromevox/background/kbexplorer.js +++ b/chrome/browser/resources/chromeos/chromevox/chromevox/background/kbexplorer.js
@@ -9,6 +9,9 @@ goog.provide('cvox.KbExplorer'); +goog.require('cvox.ChromeVoxKbHandler'); +goog.require('cvox.CommandStore'); +goog.require('cvox.KeyMap'); goog.require('cvox.KeyUtil'); @@ -38,6 +41,14 @@ backgroundWindow.removeEventListener( 'keypress', cvox.KbExplorer.onKeyPress, true); }; + if (localStorage['useNext'] == 'true') { + cvox.ChromeVoxKbHandler.handlerKeyMap = cvox.KeyMap.fromNext(); + cvox.ChromeVox.modKeyStr = 'Search'; + } else { + cvox.ChromeVoxKbHandler.handlerKeyMap = cvox.KeyMap.fromDefaults(); + cvox.ChromeVox.modKeyStr = 'Search+Shift'; + } + cvox.ChromeVoxKbHandler.commandHandler = cvox.KbExplorer.onCommand; }; @@ -54,6 +65,9 @@ if (evt.keyCode == 87 && evt.ctrlKey) { return true; } + + cvox.ChromeVoxKbHandler.basicKeyDownActionsListener(evt); + evt.preventDefault(); evt.stopPropagation(); return false; @@ -78,3 +92,12 @@ evt.preventDefault(); evt.stopPropagation(); }; + +/** + * Queues up command description. + * @param {string} command + */ +cvox.KbExplorer.onCommand = function(command) { + var commandText = Msgs.getMsg(cvox.CommandStore.messageForCommand(command)); + chrome.extension.getBackgroundPage()['speak'](commandText); +};
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js index 282e0c88..c06e675f 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
@@ -564,6 +564,10 @@ treeItem: { enter: '$role $expanded $collapsed ' + '@describe_index($indexInParent, $parentChildCount) ' + + '@describe_depth($hierarchicalLevel)', + speak: '$name ' + + '$role $expanded $collapsed ' + + '@describe_index($indexInParent, $parentChildCount) ' + '@describe_depth($hierarchicalLevel)' }, window: {
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/panel.css b/chrome/browser/resources/chromeos/chromevox/cvox2/background/panel.css index 4ad4ef28..71a19af7 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/panel.css +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/panel.css
@@ -1,7 +1,6 @@ /* Copyright 2016 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. */ body { border: 0;
diff --git a/chrome/browser/resources/chromeos/drive_internals.css b/chrome/browser/resources/chromeos/drive_internals.css index b14b68fe..74caea6 100644 --- a/chrome/browser/resources/chromeos/drive_internals.css +++ b/chrome/browser/resources/chromeos/drive_internals.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ #gcache-contents { font-size: small;
diff --git a/chrome/browser/resources/chromeos/first_run/app/style.css b/chrome/browser/resources/chromeos/first_run/app/style.css index 399b29a..3d781e8 100644 --- a/chrome/browser/resources/chromeos/first_run/app/style.css +++ b/chrome/browser/resources/chromeos/first_run/app/style.css
@@ -1,8 +1,6 @@ -/** - * Copyright 2013 The Chromium Authors. All rights reserved. +/* 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. */ body { margin: 0;
diff --git a/chrome/browser/resources/chromeos/first_run/bubble.css b/chrome/browser/resources/chromeos/first_run/bubble.css index 7c11c0e..56e3a2a 100644 --- a/chrome/browser/resources/chromeos/first_run/bubble.css +++ b/chrome/browser/resources/chromeos/first_run/bubble.css
@@ -1,8 +1,6 @@ -/** - * Copyright 2013 The Chromium Authors. All rights reserved. +/* 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. */ .bubble .arrow { border: solid transparent;
diff --git a/chrome/browser/resources/chromeos/first_run/first_run.css b/chrome/browser/resources/chromeos/first_run/first_run.css index e5d5d0bd..7b54502b 100644 --- a/chrome/browser/resources/chromeos/first_run/first_run.css +++ b/chrome/browser/resources/chromeos/first_run/first_run.css
@@ -1,8 +1,6 @@ -/** - * Copyright 2013 The Chromium Authors. All rights reserved. +/* 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. */ [hidden] { display: none !important;
diff --git a/chrome/browser/resources/chromeos/first_run/preload.css b/chrome/browser/resources/chromeos/first_run/preload.css index 03baa02..36b9442 100644 --- a/chrome/browser/resources/chromeos/first_run/preload.css +++ b/chrome/browser/resources/chromeos/first_run/preload.css
@@ -1,14 +1,10 @@ -/** - * Copyright 2014 The Chromium Authors. All rights reserved. +/* 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. - */ + * found in the LICENSE file. */ -/** - * Preloads images. Without preloading, background image starts loading in +/* Preloads images. Without preloading, background image starts loading in * the moment when CSS property is applied. Image loading has visible delay and - * looks like defect. - */ + * looks like defect. */ @media all and (-webkit-max-device-pixel-ratio: 1.5) { body::after {
diff --git a/chrome/browser/resources/chromeos/first_run/step.css b/chrome/browser/resources/chromeos/first_run/step.css index 52e424ee..587790b 100644 --- a/chrome/browser/resources/chromeos/first_run/step.css +++ b/chrome/browser/resources/chromeos/first_run/step.css
@@ -1,8 +1,6 @@ -/** - * Copyright 2013 The Chromium Authors. All rights reserved. +/* 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. */ .step { background: white;
diff --git a/chrome/browser/resources/chromeos/first_run/step_bubble.css b/chrome/browser/resources/chromeos/first_run/step_bubble.css index 202a2de..4e5199d 100644 --- a/chrome/browser/resources/chromeos/first_run/step_bubble.css +++ b/chrome/browser/resources/chromeos/first_run/step_bubble.css
@@ -1,8 +1,6 @@ -/** - * Copyright 2013 The Chromium Authors. All rights reserved. +/* 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. */ .step.bubble { border: 1px solid;
diff --git a/chrome/browser/resources/chromeos/keyboard_overlay.css b/chrome/browser/resources/chromeos/keyboard_overlay.css index a364742b..fd7cd59 100644 --- a/chrome/browser/resources/chromeos/keyboard_overlay.css +++ b/chrome/browser/resources/chromeos/keyboard_overlay.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ body { -webkit-user-select: none;
diff --git a/chrome/browser/resources/chromeos/keyboard_overlay.js b/chrome/browser/resources/chromeos/keyboard_overlay.js index 1d4c9b9..dc6e05a 100644 --- a/chrome/browser/resources/chromeos/keyboard_overlay.js +++ b/chrome/browser/resources/chromeos/keyboard_overlay.js
@@ -212,6 +212,14 @@ delete shortcutDataCache['0<>CTRL<>SHIFT']; } + if (!loadTimeData.getBoolean('backspaceGoesBackFeatureEnabled')) { + // If the "backspace key goes back" experiment is not enabled, then we + // clear the shortcuts for Backspace and Shift+Backspace to go back or + // forward respectively. + delete shortcutDataCache['backspace']; + delete shortcutDataCache['backspace<>SHIFT']; + } + return shortcutDataCache; } @@ -555,15 +563,6 @@ classes.push('keyboard-overlay-key-background'); - if ((shortcutId == 'keyboardOverlayGoBack' || - shortcutId == 'keyboardOverlayGoForward') && - !loadTimeData.getBoolean('backspaceGoesBackFeatureEnabled')) { - // If the "backspace key goes back" experiment is not enabled, then we - // clear the shortcuts for Backspace and Shift+Backspace to go back or - // forward respectively. - shortcutId = null; - } - if (shortcutId) { classes.push('is-shortcut'); classes.push('keyboard-overlay-shortcut-key-background');
diff --git a/chrome/browser/resources/chromeos/login/accessibility_menu.css b/chrome/browser/resources/chromeos/login/accessibility_menu.css index d291f7c..dde3410e 100644 --- a/chrome/browser/resources/chromeos/login/accessibility_menu.css +++ b/chrome/browser/resources/chromeos/login/accessibility_menu.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ #accessibility-menu { -webkit-padding-end: 80px;
diff --git a/chrome/browser/resources/chromeos/login/api_keys_notice.css b/chrome/browser/resources/chromeos/login/api_keys_notice.css index 2c473e05..dea471b 100644 --- a/chrome/browser/resources/chromeos/login/api_keys_notice.css +++ b/chrome/browser/resources/chromeos/login/api_keys_notice.css
@@ -1,7 +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. - */ + * found in the LICENSE file. */ #api-keys-notice-container { display: flex;
diff --git a/chrome/browser/resources/chromeos/login/apps_menu.css b/chrome/browser/resources/chromeos/login/apps_menu.css index 9068fab..0af08554 100644 --- a/chrome/browser/resources/chromeos/login/apps_menu.css +++ b/chrome/browser/resources/chromeos/login/apps_menu.css
@@ -1,7 +1,6 @@ /* 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. */ .apps-menu-item { -webkit-padding-start: 24px;
diff --git a/chrome/browser/resources/chromeos/login/controller_pairing_page.css b/chrome/browser/resources/chromeos/login/controller_pairing_page.css index 4882169..459db5bb 100644 --- a/chrome/browser/resources/chromeos/login/controller_pairing_page.css +++ b/chrome/browser/resources/chromeos/login/controller_pairing_page.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ :host { background-color: var(--google-green-500);
diff --git a/chrome/browser/resources/chromeos/login/custom_elements_oobe.html b/chrome/browser/resources/chromeos/login/custom_elements_oobe.html index 680f38a..1bd9b09 100644 --- a/chrome/browser/resources/chromeos/login/custom_elements_oobe.html +++ b/chrome/browser/resources/chromeos/login/custom_elements_oobe.html
@@ -14,6 +14,7 @@ <include src="saml_interstitial.html"> <include src="throbber_notice.html"> <include src="navigation_bar.html"> +<include src="oobe_a11y_option.html"> <include src="oobe_buttons.html"> <include src="oobe_card.html"> <include src="oobe_dialog.html">
diff --git a/chrome/browser/resources/chromeos/login/custom_elements_oobe.js b/chrome/browser/resources/chromeos/login/custom_elements_oobe.js index 5ba20e49..147e5eb 100644 --- a/chrome/browser/resources/chromeos/login/custom_elements_oobe.js +++ b/chrome/browser/resources/chromeos/login/custom_elements_oobe.js
@@ -24,6 +24,7 @@ <include src="saml_interstitial.js"> <include src="throbber_notice.js"> <include src="navigation_bar.js"> +<include src="oobe_a11y_option.js"> <include src="oobe_buttons.js"> <include src="oobe_card.js"> <include src="oobe_dialog.js">
diff --git a/chrome/browser/resources/chromeos/login/gaia_button.css b/chrome/browser/resources/chromeos/login/gaia_button.css index 8e6586d..3840845 100644 --- a/chrome/browser/resources/chromeos/login/gaia_button.css +++ b/chrome/browser/resources/chromeos/login/gaia_button.css
@@ -1,7 +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. - */ + * found in the LICENSE file. */ :host { display: inline-block;
diff --git a/chrome/browser/resources/chromeos/login/gaia_card.css b/chrome/browser/resources/chromeos/login/gaia_card.css index 8fd09300..4c066bc9 100644 --- a/chrome/browser/resources/chromeos/login/gaia_card.css +++ b/chrome/browser/resources/chromeos/login/gaia_card.css
@@ -1,7 +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. - */ + * found in the LICENSE file. */ :host { display: flex;
diff --git a/chrome/browser/resources/chromeos/login/gaia_header.css b/chrome/browser/resources/chromeos/login/gaia_header.css index ccb7c13..8833372 100644 --- a/chrome/browser/resources/chromeos/login/gaia_header.css +++ b/chrome/browser/resources/chromeos/login/gaia_header.css
@@ -1,7 +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. - */ + * found in the LICENSE file. */ :host { display: flex;
diff --git a/chrome/browser/resources/chromeos/login/gaia_icon_button.css b/chrome/browser/resources/chromeos/login/gaia_icon_button.css index 81bb054..bd736ff 100644 --- a/chrome/browser/resources/chromeos/login/gaia_icon_button.css +++ b/chrome/browser/resources/chromeos/login/gaia_icon_button.css
@@ -1,7 +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. - */ + * found in the LICENSE file. */ #iconButton { height: 24px;
diff --git a/chrome/browser/resources/chromeos/login/gaia_input.css b/chrome/browser/resources/chromeos/login/gaia_input.css index c23d0e0..b261bdb7 100644 --- a/chrome/browser/resources/chromeos/login/gaia_input.css +++ b/chrome/browser/resources/chromeos/login/gaia_input.css
@@ -1,7 +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. - */ + * found in the LICENSE file. */ :host { display: block;
diff --git a/chrome/browser/resources/chromeos/login/gaia_input_form.css b/chrome/browser/resources/chromeos/login/gaia_input_form.css index 728f518..a52593b 100644 --- a/chrome/browser/resources/chromeos/login/gaia_input_form.css +++ b/chrome/browser/resources/chromeos/login/gaia_input_form.css
@@ -1,7 +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. - */ + * found in the LICENSE file. */ :host { display: block;
diff --git a/chrome/browser/resources/chromeos/login/gaia_password_changed.css b/chrome/browser/resources/chromeos/login/gaia_password_changed.css index a4f9304..792d5cb 100644 --- a/chrome/browser/resources/chromeos/login/gaia_password_changed.css +++ b/chrome/browser/resources/chromeos/login/gaia_password_changed.css
@@ -1,7 +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. - */ + * found in the LICENSE file. */ :host { display: block;
diff --git a/chrome/browser/resources/chromeos/login/header_bar.css b/chrome/browser/resources/chromeos/login/header_bar.css index b3ea0d6..7375e5f 100644 --- a/chrome/browser/resources/chromeos/login/header_bar.css +++ b/chrome/browser/resources/chromeos/login/header_bar.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ #login-header-bar { -webkit-padding-start: 15px;
diff --git a/chrome/browser/resources/chromeos/login/navigation_bar.css b/chrome/browser/resources/chromeos/login/navigation_bar.css index 465b178a..07105eae 100644 --- a/chrome/browser/resources/chromeos/login/navigation_bar.css +++ b/chrome/browser/resources/chromeos/login/navigation_bar.css
@@ -1,7 +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. - */ + * found in the LICENSE file. */ :host { display: block;
diff --git a/chrome/browser/resources/chromeos/login/network_dropdown.css b/chrome/browser/resources/chromeos/login/network_dropdown.css index b15dcda3..e19a5dd 100644 --- a/chrome/browser/resources/chromeos/login/network_dropdown.css +++ b/chrome/browser/resources/chromeos/login/network_dropdown.css
@@ -2,8 +2,7 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * - * This is the stylesheet used by the network drop-down control. - */ + * This is the stylesheet used by the network drop-down control. */ .dropdown-title { -webkit-appearance: none;
diff --git a/chrome/browser/resources/chromeos/login/notification_card.css b/chrome/browser/resources/chromeos/login/notification_card.css index 2be458d..3556e83 100644 --- a/chrome/browser/resources/chromeos/login/notification_card.css +++ b/chrome/browser/resources/chromeos/login/notification_card.css
@@ -1,7 +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. - */ + * found in the LICENSE file. */ #container { padding: 40px;
diff --git a/chrome/browser/resources/chromeos/login/offline_gaia.css b/chrome/browser/resources/chromeos/login/offline_gaia.css index 45a78ec4..9669aa48 100644 --- a/chrome/browser/resources/chromeos/login/offline_gaia.css +++ b/chrome/browser/resources/chromeos/login/offline_gaia.css
@@ -1,7 +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. - */ + * found in the LICENSE file. */ :host { display: flex;
diff --git a/chrome/browser/resources/chromeos/login/oobe.js b/chrome/browser/resources/chromeos/login/oobe.js index 3a9a4bc..84dd96b 100644 --- a/chrome/browser/resources/chromeos/login/oobe.js +++ b/chrome/browser/resources/chromeos/login/oobe.js
@@ -287,6 +287,8 @@ $('screen-magnifier').checked = data.screenMagnifierEnabled; $('large-cursor').checked = data.largeCursorEnabled; $('virtual-keyboard').checked = data.virtualKeyboardEnabled; + + $('oobe-welcome-md').a11yStatus = data; }, /**
diff --git a/chrome/browser/resources/chromeos/login/oobe_a11y_option.html b/chrome/browser/resources/chromeos/login/oobe_a11y_option.html new file mode 100644 index 0000000..502e5d69 --- /dev/null +++ b/chrome/browser/resources/chromeos/login/oobe_a11y_option.html
@@ -0,0 +1,22 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html"> + +<dom-module name="oobe-a11y-option"> + <template> + <div class="layout horizontal"> + <div id="labelContainer" class="flex layout vertical"> + <div id="titleContainer"> + <content select=".title"></content> + </div> + <div class="display-value" hidden="[[!checked]]"> + <content select=".checked-value"></content> + </div> + <div class="display-value" hidden="[[checked]]"> + <content select=".unchecked-value"></content> + </div> + </div> + <paper-toggle-button checked="{{checked}}"></paper-toggle-button> + </div> + </template> +</dom-module>
diff --git a/chrome/browser/resources/chromeos/login/oobe_a11y_option.js b/chrome/browser/resources/chromeos/login/oobe_a11y_option.js new file mode 100644 index 0000000..6d5fac7d --- /dev/null +++ b/chrome/browser/resources/chromeos/login/oobe_a11y_option.js
@@ -0,0 +1,23 @@ +// Copyright 2016 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. + +Polymer({ + is: 'oobe-a11y-option', + + properties: { + /** + * If paper-toggle-button is checked. + */ + checked: { + type: Boolean, + }, + + /** + * Chrome message handling this option. + */ + chromeMessage: { + type: String, + }, + }, +});
diff --git a/chrome/browser/resources/chromeos/login/oobe_dialog.css b/chrome/browser/resources/chromeos/login/oobe_dialog.css index 2599245..9f69992 100644 --- a/chrome/browser/resources/chromeos/login/oobe_dialog.css +++ b/chrome/browser/resources/chromeos/login/oobe_dialog.css
@@ -30,6 +30,7 @@ } .footer-container { + overflow-y: auto; padding: 24px 40px 34px; }
diff --git a/chrome/browser/resources/chromeos/login/oobe_i18n_dropdown.html b/chrome/browser/resources/chromeos/login/oobe_i18n_dropdown.html index 55dd811..0fe181b 100644 --- a/chrome/browser/resources/chromeos/login/oobe_i18n_dropdown.html +++ b/chrome/browser/resources/chromeos/login/oobe_i18n_dropdown.html
@@ -3,6 +3,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-iconset-svg/iron-iconset-svg.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-dropdown-menu/paper-dropdown-menu.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/paper-item/paper-item.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-listbox/paper-listbox.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
diff --git a/chrome/browser/resources/chromeos/login/oobe_popup_overlay.css b/chrome/browser/resources/chromeos/login/oobe_popup_overlay.css index 57a6bf4..d25f0da7 100644 --- a/chrome/browser/resources/chromeos/login/oobe_popup_overlay.css +++ b/chrome/browser/resources/chromeos/login/oobe_popup_overlay.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ .popup-overlay { -webkit-transition: 250ms opacity;
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen.css b/chrome/browser/resources/chromeos/login/oobe_screen.css index 86b1209..e39c7eb 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen.css +++ b/chrome/browser/resources/chromeos/login/oobe_screen.css
@@ -2,8 +2,7 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * - * This contains common styling for all the OOBE screens. - */ + * This contains common styling for all the OOBE screens. */ .step { box-sizing: border-box;
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_auto_enrollment_check.css b/chrome/browser/resources/chromeos/login/oobe_screen_auto_enrollment_check.css index b0735e47..2c722f0 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_auto_enrollment_check.css +++ b/chrome/browser/resources/chromeos/login/oobe_screen_auto_enrollment_check.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ #auto-enrollment-check { min-height: 395px;
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_autolaunch.css b/chrome/browser/resources/chromeos/login/oobe_screen_autolaunch.css index 9a0f050..fbc379b 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_autolaunch.css +++ b/chrome/browser/resources/chromeos/login/oobe_screen_autolaunch.css
@@ -1,7 +1,6 @@ /* 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. */ #autolaunch { min-height: 423px;
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_controller_pairing.css b/chrome/browser/resources/chromeos/login/oobe_screen_controller_pairing.css index 76b222a..07b0e078 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_controller_pairing.css +++ b/chrome/browser/resources/chromeos/login/oobe_screen_controller_pairing.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ /* TODO(dzhioev): support RTL. http://crbug.com/423354 */ /* TODO(xdai): Remove the hard-coded font-family for 'Roboto'. */
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_enable_debugging.css b/chrome/browser/resources/chromeos/login/oobe_screen_enable_debugging.css index 9c23f20e..634656c 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_enable_debugging.css +++ b/chrome/browser/resources/chromeos/login/oobe_screen_enable_debugging.css
@@ -1,7 +1,6 @@ /* 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. */ #debugging { display: flex;
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_enable_kiosk.css b/chrome/browser/resources/chromeos/login/oobe_screen_enable_kiosk.css index ba4ab38..2934d73a 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_enable_kiosk.css +++ b/chrome/browser/resources/chromeos/login/oobe_screen_enable_kiosk.css
@@ -1,7 +1,6 @@ /* 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. */ #kiosk-enable { min-height: 423px;
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_eula.css b/chrome/browser/resources/chromeos/login/oobe_screen_eula.css index accb4a3d..9ae7104 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_eula.css +++ b/chrome/browser/resources/chromeos/login/oobe_screen_eula.css
@@ -1,7 +1,6 @@ /* 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. */ #eula { min-height: 395px;
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.css b/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.css index 050b21b..a9251436 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.css +++ b/chrome/browser/resources/chromeos/login/oobe_screen_hid_detection.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ #hid-detection { min-height: 395px;
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing.css b/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing.css index cbbae9b2..fbefdb5 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing.css +++ b/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ /* TODO(dzhioev): support RTL. http://crbug.com/423354 */
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing_page.css b/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing_page.css index 4ca1f9bf..b0b2270a 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing_page.css +++ b/chrome/browser/resources/chromeos/login/oobe_screen_host_pairing_page.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ :host { display: block;
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_network.css b/chrome/browser/resources/chromeos/login/oobe_screen_network.css index d68d226..cfa6af6 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_network.css +++ b/chrome/browser/resources/chromeos/login/oobe_screen_network.css
@@ -1,7 +1,6 @@ /* 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. */ #connect { min-height: 395px;
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.css b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.css index 9ef604d..04703d1b 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.css +++ b/chrome/browser/resources/chromeos/login/oobe_screen_oauth_enrollment.css
@@ -1,7 +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. - */ + * found in the LICENSE file. */ #oauth-enrollment { height: 528px;
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_reset.css b/chrome/browser/resources/chromeos/login/oobe_screen_reset.css index abe034b..27b9506 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_reset.css +++ b/chrome/browser/resources/chromeos/login/oobe_screen_reset.css
@@ -1,7 +1,6 @@ /* 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. */ #reset { display: flex;
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_terms_of_service.css b/chrome/browser/resources/chromeos/login/oobe_screen_terms_of_service.css index 82017d7c..b342c8a 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_terms_of_service.css +++ b/chrome/browser/resources/chromeos/login/oobe_screen_terms_of_service.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ #terms-of-service { padding: 70px 17px 21px;
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_update.css b/chrome/browser/resources/chromeos/login/oobe_screen_update.css index f522347..7523840 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_update.css +++ b/chrome/browser/resources/chromeos/login/oobe_screen_update.css
@@ -1,7 +1,6 @@ /* 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. */ #update { min-height: 423px;
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_user_image.css b/chrome/browser/resources/chromeos/login/oobe_screen_user_image.css index 7c56e77..464a43c 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_user_image.css +++ b/chrome/browser/resources/chromeos/login/oobe_screen_user_image.css
@@ -1,7 +1,6 @@ /* 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. */ #user-image { min-height: 443px; @@ -55,16 +54,14 @@ padding: 2px; } -/** - * #user-image-preview can have the following classes: +/* #user-image-preview can have the following classes: * .default-image: one of the default images is selected (including the grey * silhouette); * .profile-image: profile image is selected; * .profile-image-loading: profile image is being loaded; * .online: camera is streaming video; * .camera: camera (live or photo) is selected; - * .live: camera is in live mode (no photo taken yet/last photo removed). - */ + * .live: camera is in live mode (no photo taken yet/last photo removed). */ #user-image-preview { float: right; margin: 4px;
diff --git a/chrome/browser/resources/chromeos/login/oobe_types.js b/chrome/browser/resources/chromeos/login/oobe_types.js index 826941b..0b1a096a 100644 --- a/chrome/browser/resources/chromeos/login/oobe_types.js +++ b/chrome/browser/resources/chromeos/login/oobe_types.js
@@ -31,3 +31,14 @@ */ OobeTypes.IMEDsc; +/** + * A set of flags of accessibility options for ChromeOS OOBE. + * @typedef {{ + * highContrastEnabled: Boolean, + * spokenFeedbackEnabled: Boolean, + * screenMagnifierEnabled: Boolean, + * largeCursorEnabled: Boolean, + * virtualKeyboardEnabled: Boolean, + * }} + */ +OobeTypes.A11yStatuses;
diff --git a/chrome/browser/resources/chromeos/login/oobe_welcome.css b/chrome/browser/resources/chromeos/login/oobe_welcome.css index 4e63b014..8604adc 100644 --- a/chrome/browser/resources/chromeos/login/oobe_welcome.css +++ b/chrome/browser/resources/chromeos/login/oobe_welcome.css
@@ -32,3 +32,11 @@ .language-selection-entry:last-of-type { border-bottom: 1px solid lightgrey; } + +oobe-a11y-option { + border-top: 1px solid lightgrey; +} + +oobe-a11y-option:last-of-type { + border-bottom: 1px solid lightgrey; +}
diff --git a/chrome/browser/resources/chromeos/login/oobe_welcome.html b/chrome/browser/resources/chromeos/login/oobe_welcome.html index a9c55a55..cefa890 100644 --- a/chrome/browser/resources/chromeos/login/oobe_welcome.html +++ b/chrome/browser/resources/chromeos/login/oobe_welcome.html
@@ -38,7 +38,8 @@ </iron-icon> <div id="currentLanguage">[[currentLanguage]]</div> </div> - <div class="buttonbox layout vertical"> + <div class="buttonbox layout vertical" + on-tap="onWelcomeAccessibilityButtonClicked_"> <iron-icon icon="icons:accessibility" class="bottom-button self-center"> </iron-icon> @@ -83,6 +84,69 @@ </oobe-text-button> </div> </oobe-dialog> + <oobe-dialog class="fit" hidden="[[!accessibilityOptionsScreenShown]]" + has-buttons> + <iron-icon icon="icons:accessibility" class="oobe-icon"></iron-icon> + <div class="header flex layout vertical end-justified start"> + <h1 class="welcome-message" i18n-content="accessibilitySectionTitle"> + </h1> + <h1 class="welcome-message-hint" + i18n-content="accessibilitySectionHint"> + </h1> + </div> + <div class="footer layout vertical"> + <oobe-a11y-option checked="[[a11yStatus.spokenFeedbackEnabled]]" + on-change="onA11yOptionChanged_" + chrome-message="enableSpokenFeedback"> + <span class="title" i18n-content="spokenFeedbackOption"></span> + <span class="checked-value" i18n-content="spokenFeedbackOptionOn"> + </span> + <span class="unchecked-value" i18n-content="spokenFeedbackOptionOff"> + </span> + </oobe-a11y-option> + <oobe-a11y-option checked="[[a11yStatus.largeCursorEnabled]]" + on-change="onA11yOptionChanged_" + chrome-message="enableLargeCursor"> + <span class="title" i18n-content="largeCursorOption"></span> + <span class="checked-value" i18n-content="largeCursorOptionOn"> + </span> + <span class="unchecked-value" i18n-content="largeCursorOptionOff"> + </span> + </oobe-a11y-option> + <oobe-a11y-option checked="[[a11yStatus.highContrastEnabled]]" + on-change="onA11yOptionChanged_" + chrome-message="enableHighContrast"> + <span class="title" i18n-content="highContrastOption"></span> + <span class="checked-value" i18n-content="highContrastOptionOn"> + </span> + <span class="unchecked-value" i18n-content="highContrastOptionOff"> + </span> + </oobe-a11y-option> + <oobe-a11y-option checked="[[a11yStatus.screenMagnifierEnabled]]" + on-change="onA11yOptionChanged_" + chrome-message="enableScreenMagnifier"> + <span class="title" i18n-content="screenMagnifierOption"></span> + <span class="checked-value" i18n-content="screenMagnifierOptionOn"> + </span> + <span class="unchecked-value" i18n-content="screenMagnifierOptionOff"> + </span> + </oobe-a11y-option> + <oobe-a11y-option checked="[[a11yStatus.virtualKeyboardEnabled]]" + on-change="onA11yOptionChanged_" + chrome-message="enableVirtualKeyboard"> + <span class="title" i18n-content="virtualKeyboardOption"></span> + <span class="checked-value" i18n-content="virtualKeyboardOptionOn"> + </span> + <span class="unchecked-value" i18n-content="virtualKeyboardOptionOff"> + </span> + </oobe-a11y-option> + </div> + <div class="bottom-buttons layout horizontal"> + <oobe-text-button inverse on-tap="closeAccessibilitySection_" + i18n-content="oobeOKButtonText"> + </oobe-text-button> + </div> + </oobe-dialog> <oobe-dialog id="networkSection" class="fit" hidden="[[!networkSelectionScreenShown]]"> <iron-icon icon="oobe-welcome:wifi" class="oobe-icon"></iron-icon>
diff --git a/chrome/browser/resources/chromeos/login/oobe_welcome.js b/chrome/browser/resources/chromeos/login/oobe_welcome.js index 52cb4f9..8a55404 100644 --- a/chrome/browser/resources/chromeos/login/oobe_welcome.js +++ b/chrome/browser/resources/chromeos/login/oobe_welcome.js
@@ -51,6 +51,14 @@ }, /** + * Flag that shows Accessibility Options screen. + */ + accessibilityOptionsScreenShown: { + type: Boolean, + value: false, + }, + + /** * Flag that shows Network Selection screen. */ networkSelectionScreenShown: { @@ -65,6 +73,14 @@ type: Boolean, value: false, }, + + /** + * Accessibility options status. + * @type {!OobeTypes.A11yStatuses} + */ + a11yStatus: { + type: Object, + }, }, /** @@ -74,6 +90,7 @@ this.welcomeScreenShown = false; this.networkSelectionScreenShown = false; this.languageSelectionScreenShown = false; + this.accessibilityOptionsScreenShown = false; }, /** @@ -149,6 +166,16 @@ }, /** + * Handle "Accessibility" button for "Welcome" screen. + * + * @private + */ + onWelcomeAccessibilityButtonClicked_: function() { + this.hideAllScreens_(); + this.accessibilityOptionsScreenShown = true; + }, + + /** * Handle Networwork Setup screen "Proxy settings" button. * * @private @@ -280,4 +307,29 @@ this.hideAllScreens_(); this.welcomeScreenShown = true; }, + + /** ******************** Accessibility section ******************* */ + + /** + * Handle "OK" button for "Accessibility Options" screen. + * + * @private + */ + closeAccessibilitySection_: function() { + this.hideAllScreens_(); + this.welcomeScreenShown = true; + }, + + /** + * Handle all accessibility buttons. + * Note that each <oobe-a11y-option> has chromeMessage attribute + * containing Chromium callback name. + * + * @private + * @param {!Event} event + */ + onA11yOptionChanged_: function(event) { + chrome.send( + event.currentTarget.chromeMessage, [event.currentTarget.checked]); + }, });
diff --git a/chrome/browser/resources/chromeos/login/pairing_device_list.css b/chrome/browser/resources/chromeos/login/pairing_device_list.css index eb2c725..16088ec 100644 --- a/chrome/browser/resources/chromeos/login/pairing_device_list.css +++ b/chrome/browser/resources/chromeos/login/pairing_device_list.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ /* TODO(dzhioev): support RTL. http://crbug.com/423354 */
diff --git a/chrome/browser/resources/chromeos/login/saml_confirm_password.css b/chrome/browser/resources/chromeos/login/saml_confirm_password.css index 18b494c..3b5ce3a 100644 --- a/chrome/browser/resources/chromeos/login/saml_confirm_password.css +++ b/chrome/browser/resources/chromeos/login/saml_confirm_password.css
@@ -1,7 +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. - */ + * found in the LICENSE file. */ :host { display: block;
diff --git a/chrome/browser/resources/chromeos/login/screen_app_launch_splash.css b/chrome/browser/resources/chromeos/login/screen_app_launch_splash.css index 0a97b02f..cd546e1d 100644 --- a/chrome/browser/resources/chromeos/login/screen_app_launch_splash.css +++ b/chrome/browser/resources/chromeos/login/screen_app_launch_splash.css
@@ -1,7 +1,6 @@ /* 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. */ #app-launch-splash { -webkit-box-align: center;
diff --git a/chrome/browser/resources/chromeos/login/screen_confirm_password.css b/chrome/browser/resources/chromeos/login/screen_confirm_password.css index 4be097c..038571a 100644 --- a/chrome/browser/resources/chromeos/login/screen_confirm_password.css +++ b/chrome/browser/resources/chromeos/login/screen_confirm_password.css
@@ -1,7 +1,6 @@ /* 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. */ #confirm-password { height: 528px; /* Should be the same as #gaia-signin. */
diff --git a/chrome/browser/resources/chromeos/login/screen_device_disabled.css b/chrome/browser/resources/chromeos/login/screen_device_disabled.css index 73d669d..7c6dc89 100644 --- a/chrome/browser/resources/chromeos/login/screen_device_disabled.css +++ b/chrome/browser/resources/chromeos/login/screen_device_disabled.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ #device-disabled, #device-disabled-top-container,
diff --git a/chrome/browser/resources/chromeos/login/screen_error_message.css b/chrome/browser/resources/chromeos/login/screen_error_message.css index f688f48c..986a4a90 100644 --- a/chrome/browser/resources/chromeos/login/screen_error_message.css +++ b/chrome/browser/resources/chromeos/login/screen_error_message.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ #error-message { width: 650px;
diff --git a/chrome/browser/resources/chromeos/login/screen_fatal_error.css b/chrome/browser/resources/chromeos/login/screen_fatal_error.css index 68cbe95a..f641108d 100644 --- a/chrome/browser/resources/chromeos/login/screen_fatal_error.css +++ b/chrome/browser/resources/chromeos/login/screen_fatal_error.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ #fatal-error { height: 528px; /* Should be the same as #gaia-signin. */
diff --git a/chrome/browser/resources/chromeos/login/screen_gaia_signin.css b/chrome/browser/resources/chromeos/login/screen_gaia_signin.css index 13223b1..f180879e 100644 --- a/chrome/browser/resources/chromeos/login/screen_gaia_signin.css +++ b/chrome/browser/resources/chromeos/login/screen_gaia_signin.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ #gaia-signin { height: 528px;
diff --git a/chrome/browser/resources/chromeos/login/screen_password_changed.css b/chrome/browser/resources/chromeos/login/screen_password_changed.css index 6423d0c..9cee7e6c 100644 --- a/chrome/browser/resources/chromeos/login/screen_password_changed.css +++ b/chrome/browser/resources/chromeos/login/screen_password_changed.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ #password-changed { height: 528px; /* Should be the same as #gaia-signin. */
diff --git a/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.css b/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.css index ed4f5246..baf3c24 100644 --- a/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.css +++ b/chrome/browser/resources/chromeos/login/screen_supervised_user_creation.css
@@ -199,8 +199,7 @@ } /* This class will be set for elements with hide-on-import class by JS when - * page is used in 'import' mode - */ + * page is used in 'import' mode. */ #supervised-user-creation .hidden-on-import { display: none; }
diff --git a/chrome/browser/resources/chromeos/login/screen_tpm_error.css b/chrome/browser/resources/chromeos/login/screen_tpm_error.css index 62340abd..78b70c6 100644 --- a/chrome/browser/resources/chromeos/login/screen_tpm_error.css +++ b/chrome/browser/resources/chromeos/login/screen_tpm_error.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ #tpm-error-message { min-width: 650px;
diff --git a/chrome/browser/resources/chromeos/login/screen_unrecoverable_cryptohome_error.css b/chrome/browser/resources/chromeos/login/screen_unrecoverable_cryptohome_error.css index 6cf3a25..83b2bf8b 100644 --- a/chrome/browser/resources/chromeos/login/screen_unrecoverable_cryptohome_error.css +++ b/chrome/browser/resources/chromeos/login/screen_unrecoverable_cryptohome_error.css
@@ -1,7 +1,6 @@ -/* Copyright (c) 2016 The Chromium Authors. All rights reserved. +/* Copyright 2016 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. */ #unrecoverable-cryptohome-error { width: 448px; /* Should be the same as #gaia-signin. */
diff --git a/chrome/browser/resources/chromeos/login/screen_wrong_hwid.css b/chrome/browser/resources/chromeos/login/screen_wrong_hwid.css index 0955d3c..b0fb4f9 100644 --- a/chrome/browser/resources/chromeos/login/screen_wrong_hwid.css +++ b/chrome/browser/resources/chromeos/login/screen_wrong_hwid.css
@@ -2,8 +2,7 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * - * This is the stylesheet used by the wrong HWID screen. - */ + * This is the stylesheet used by the wrong HWID screen. */ #wrong-hwid { padding: 40px 17px 30px;
diff --git a/chrome/browser/resources/chromeos/login/throbber_notice.css b/chrome/browser/resources/chromeos/login/throbber_notice.css index 8ca67e3..275110d 100644 --- a/chrome/browser/resources/chromeos/login/throbber_notice.css +++ b/chrome/browser/resources/chromeos/login/throbber_notice.css
@@ -1,7 +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. - */ + * found in the LICENSE file. */ :host { align-items: center;
diff --git a/chrome/browser/resources/chromeos/login/unrecoverable_cryptohome_error_card.css b/chrome/browser/resources/chromeos/login/unrecoverable_cryptohome_error_card.css index 4bc35e3..2703e0b4 100644 --- a/chrome/browser/resources/chromeos/login/unrecoverable_cryptohome_error_card.css +++ b/chrome/browser/resources/chromeos/login/unrecoverable_cryptohome_error_card.css
@@ -1,7 +1,6 @@ /* Copyright 2016 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. */ :host .content { padding: 24px 24px 16px;
diff --git a/chrome/browser/resources/chromeos/mobile_dialogs.css b/chrome/browser/resources/chromeos/mobile_dialogs.css index 9c96e68..91d3a5f 100644 --- a/chrome/browser/resources/chromeos/mobile_dialogs.css +++ b/chrome/browser/resources/chromeos/mobile_dialogs.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ body { cursor: default;
diff --git a/chrome/browser/resources/chromeos/mobile_setup.css b/chrome/browser/resources/chromeos/mobile_setup.css index 2ce8a8e..c437a7d 100644 --- a/chrome/browser/resources/chromeos/mobile_setup.css +++ b/chrome/browser/resources/chromeos/mobile_setup.css
@@ -1,7 +1,6 @@ /* 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. */ html, body {
diff --git a/chrome/browser/resources/chromeos/neterror.css b/chrome/browser/resources/chromeos/neterror.css index 1b72f5d..7db6f20 100644 --- a/chrome/browser/resources/chromeos/neterror.css +++ b/chrome/browser/resources/chromeos/neterror.css
@@ -35,10 +35,8 @@ } .icon-generic { - /** - * Can't access chrome://theme/IDR_ERROR_NETWORK_GENERIC from an untrusted - * renderer process, so embed the resource manually. - */ + /* Can't access chrome://theme/IDR_ERROR_NETWORK_GENERIC from an untrusted + * renderer process, so embed the resource manually. */ content: -webkit-image-set( url(../../../../components/resources/default_100_percent/neterror/error_network_generic.png) 1x, url(../../../../components/resources/default_200_percent/neterror/error_network_generic.png) 2x);
diff --git a/chrome/browser/resources/chromeos/nfc_debug.css b/chrome/browser/resources/chromeos/nfc_debug.css index 9ffa968f..1c7dc73 100644 --- a/chrome/browser/resources/chromeos/nfc_debug.css +++ b/chrome/browser/resources/chromeos/nfc_debug.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ body { margin: 0
diff --git a/chrome/browser/resources/chromeos/power.css b/chrome/browser/resources/chromeos/power.css index a675d894..42847238 100644 --- a/chrome/browser/resources/chromeos/power.css +++ b/chrome/browser/resources/chromeos/power.css
@@ -1,8 +1,6 @@ -/* - * Copyright 2014 The Chromium Authors. All rights reserved. +/* 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. - */ + * found in the LICENSE file. */ #main-table { border-collapse: collapse;
diff --git a/chrome/browser/resources/chromeos/sim_unlock.css b/chrome/browser/resources/chromeos/sim_unlock.css index 9e9d588..99c9036 100644 --- a/chrome/browser/resources/chromeos/sim_unlock.css +++ b/chrome/browser/resources/chromeos/sim_unlock.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ .error { color: red;
diff --git a/chrome/browser/resources/chromeos/slow.css b/chrome/browser/resources/chromeos/slow.css index ceca2c3..1f07719 100644 --- a/chrome/browser/resources/chromeos/slow.css +++ b/chrome/browser/resources/chromeos/slow.css
@@ -1,7 +1,6 @@ /* 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. */ body { background-color: #E6E6E6;
diff --git a/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css b/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css index c38868a..78c5a76d 100644 --- a/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css +++ b/chrome/browser/resources/chromeos/wallpaper_manager/css/wallpaper_manager.css
@@ -18,15 +18,13 @@ /* Click events are not received in draggable area. Making all clickable areas * not draggable to receive click events. - * TODO(bshe): Remove this when http://crbug.com/142275 fixed. - */ + * TODO(bshe): Remove this when http://crbug.com/142275 fixed. */ .dialog-topbar #navstrip, .dialog-topbar #window-close-button, .overlay-container .page, #author-website, /* TODO(bshe): Once http://crbug.com/369651 fixed, use .image-picker instead of - * #category-container. - */ + * #category-container. */ #category-container, #surprise-me { -webkit-app-region: no-drag; @@ -156,8 +154,7 @@ display: block; /* Set font size to 0 to remove the extra vertical margin between two rows of * thumbnails. - * TODO(bshe): Find the root cause of the margin. - */ + * TODO(bshe): Find the root cause of the margin. */ font-size: 0; height: 287px; outline: none; @@ -219,8 +216,7 @@ /* The width and height of img tag need to be set here. Otherwise, an incorrect * image size may be used during layout. Some images may be misaligned as a * result. See http://code.google.com/p/chromium/issues/detail?id=148480 for - * screen shot. - */ + * screen shot. */ .image-picker img { height: 68px; width: 108px;
diff --git a/chrome/browser/resources/device_log_ui/device_log_ui.css b/chrome/browser/resources/device_log_ui/device_log_ui.css index 76e1092..e4dc5da 100644 --- a/chrome/browser/resources/device_log_ui/device_log_ui.css +++ b/chrome/browser/resources/device_log_ui/device_log_ui.css
@@ -1,8 +1,6 @@ -/* - * Copyright 2014 The Chromium Authors. All rights reserved. +/* 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. - */ + * found in the LICENSE file. */ html { height: 100%;
diff --git a/chrome/browser/resources/domain_reliability_internals.css b/chrome/browser/resources/domain_reliability_internals.css index a8fe22d..94e47c8 100644 --- a/chrome/browser/resources/domain_reliability_internals.css +++ b/chrome/browser/resources/domain_reliability_internals.css
@@ -1,4 +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. - */ + * found in the LICENSE file. */
diff --git a/chrome/browser/resources/feedback/manifest.json b/chrome/browser/resources/feedback/manifest.json index 5a6139db..581118e 100644 --- a/chrome/browser/resources/feedback/manifest.json +++ b/chrome/browser/resources/feedback/manifest.json
@@ -18,7 +18,7 @@ "background": { "scripts": ["js/event_handler.js"] }, - "content_security_policy": "default-src 'none'; script-src 'self' blob: filesystem: chrome://resources; style-src 'unsafe-inline' blob: chrome: file: filesystem: data: *; img-src * blob: file: filesystem: data:; media-src 'self' blob: filesystem:" + "content_security_policy": "default-src 'none'; script-src 'self' blob: filesystem: chrome://resources; style-src 'unsafe-inline' blob: chrome: file: filesystem: data: *; img-src * blob: chrome: file: filesystem: data:; media-src 'self' blob: filesystem:" }, "display_in_launcher": false, "display_in_new_tab_page": false
diff --git a/chrome/browser/resources/gaia_auth/main.css b/chrome/browser/resources/gaia_auth/main.css index 3979476..1bbc0d6d 100644 --- a/chrome/browser/resources/gaia_auth/main.css +++ b/chrome/browser/resources/gaia_auth/main.css
@@ -1,7 +1,6 @@ /* 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. */ html, body,
diff --git a/chrome/browser/resources/help/channel_change_page.css b/chrome/browser/resources/help/channel_change_page.css index 4efbd0ea..16ca904 100644 --- a/chrome/browser/resources/help/channel_change_page.css +++ b/chrome/browser/resources/help/channel_change_page.css
@@ -1,7 +1,6 @@ /* 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. */ #channel-change-page { min-height: 200px;
diff --git a/chrome/browser/resources/help/help.css b/chrome/browser/resources/help/help.css index 60a09abe..cf008009 100644 --- a/chrome/browser/resources/help/help.css +++ b/chrome/browser/resources/help/help.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ body { -webkit-user-select: text;
diff --git a/chrome/browser/resources/help/help_content.css b/chrome/browser/resources/help/help_content.css index 4c47256..86209a76 100644 --- a/chrome/browser/resources/help/help_content.css +++ b/chrome/browser/resources/help/help_content.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ #about-container { align-items: center;
diff --git a/chrome/browser/resources/history/history.css b/chrome/browser/resources/history/history.css index 810aa55a..1d4da44 100644 --- a/chrome/browser/resources/history/history.css +++ b/chrome/browser/resources/history/history.css
@@ -332,8 +332,7 @@ * directive would show up incorrectly (e.g. '(www.google.com (5'). Using * 'embed' makes the engine set the text in the parentheses as LTR even * when the layout is set to RTL, which makes using -webkit-*-start - * impossible. So use margins and dir='rtl'. - */ + * impossible. So use margins and dir='rtl'. */ direction: rtl; unicode-bidi: embed; }
diff --git a/chrome/browser/resources/inline_login/inline_login.css b/chrome/browser/resources/inline_login/inline_login.css index c0cf004..f550f1c 100644 --- a/chrome/browser/resources/inline_login/inline_login.css +++ b/chrome/browser/resources/inline_login/inline_login.css
@@ -1,7 +1,6 @@ /* 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. */ html, body,
diff --git a/chrome/browser/resources/instant/instant.css b/chrome/browser/resources/instant/instant.css index 4c39e13..af57b88 100644 --- a/chrome/browser/resources/instant/instant.css +++ b/chrome/browser/resources/instant/instant.css
@@ -1,8 +1,6 @@ -/* - * Copyright 2012 The Chromium Authors. All rights reserved. +/* 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. - */ + * found in the LICENSE file. */ body { font-size: 12px;
diff --git a/chrome/browser/resources/local_ntp/most_visited_single.css b/chrome/browser/resources/local_ntp/most_visited_single.css index d2d356f9..84109232 100644 --- a/chrome/browser/resources/local_ntp/most_visited_single.css +++ b/chrome/browser/resources/local_ntp/most_visited_single.css
@@ -240,10 +240,8 @@ width: 48px; } -/* - We use ::after without content to provide an aditional element on top of - the thumbnail. -*/ +/* We use ::after without content to provide an aditional element on top of the + * thumbnail. */ .mv-thumb.failed-img::after { border: 8px solid #f2f2f2; border-radius: 50%; @@ -277,10 +275,8 @@ width: 16px; } -/* - We use ::after without content to provide the masked X element. - The "bottom" div is actually just the gradient. -*/ +/* We use ::after without content to provide the masked X element. The "bottom" + * div is actually just the gradient. */ .mv-x::after { -webkit-mask-image: -webkit-image-set( url(chrome-search://local-ntp/images/close_3_mask.png) 1x,
diff --git a/chrome/browser/resources/md_history/compiled_resources2.gyp b/chrome/browser/resources/md_history/compiled_resources2.gyp index c363db9..91d410a 100644 --- a/chrome/browser/resources/md_history/compiled_resources2.gyp +++ b/chrome/browser/resources/md_history/compiled_resources2.gyp
@@ -24,6 +24,7 @@ '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-collapse/compiled_resources2.gyp:iron-collapse-extracted', 'constants', 'history_item', + 'history_list_behavior', '../history/compiled_resources2.gyp:externs', ], 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], @@ -49,13 +50,21 @@ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util', 'constants', - 'browser_service', 'history_item', + 'history_list_behavior', '../history/compiled_resources2.gyp:externs', ], 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], }, { + 'target_name': 'history_list_behavior', + 'dependencies': [ + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', + 'browser_service', + ], + 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { 'target_name': 'history_toolbar', 'dependencies': [ '<(DEPTH)/ui/webui/resources/cr_elements/cr_toolbar/compiled_resources2.gyp:cr_toolbar', @@ -81,6 +90,7 @@ 'dependencies': [ 'grouped_list', 'history_list', + 'history_list_behavior', '<(EXTERNS_GYP):chrome_send', '../history/compiled_resources2.gyp:externs', ],
diff --git a/chrome/browser/resources/md_history/grouped_list.html b/chrome/browser/resources/md_history/grouped_list.html index b1f2a6b..e7728604 100644 --- a/chrome/browser/resources/md_history/grouped_list.html +++ b/chrome/browser/resources/md_history/grouped_list.html
@@ -3,6 +3,7 @@ <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html"> <link rel="import" href="chrome://history/constants.html"> <link rel="import" href="chrome://history/history_item.html"> +<link rel="import" href="chrome://history/history_list_behavior.html"> <link rel="import" href="chrome://history/shared_style.html"> <dom-module id="history-grouped-list"> @@ -39,9 +40,8 @@ } .group-container { + @apply(--card-box-shadow); background: #fff; - border: 1px solid var(--card-border-color); - border-bottom-width: 2px; border-radius: 2px; margin-bottom: var(--card-padding-between); max-width: var(--card-max-width); @@ -66,11 +66,11 @@ } </style> <div id="no-results" class="centered-message" - hidden$="[[hasResults_(groupedHistoryData_.length)]]"> - [[noResultsMessage_(searchedTerm, querying)]] + hidden$="[[hasResults(groupedHistoryData_.length)]]"> + [[noResultsMessage(searchedTerm, querying)]] </div> <div id="main-container" - hidden$="[[!hasResults_(groupedHistoryData_.length)]]"> + hidden$="[[!hasResults(groupedHistoryData_.length)]]"> <template is="dom-repeat" items="[[groupedHistoryData_]]" as="group" initial-count="1" index-as="groupIndex"> <div class="group-container"> @@ -101,6 +101,8 @@ groupIndex, domainIndex, itemIndex)]]" search-term="[[searchedTerm]]" number-of-items="[[historyData.length]]" + path="[[pathForItem_( + groupIndex, domainIndex, itemIndex)]]" embedded> </history-item> </template>
diff --git a/chrome/browser/resources/md_history/grouped_list.js b/chrome/browser/resources/md_history/grouped_list.js index 9d14bfc9e..f5ca7d0 100644 --- a/chrome/browser/resources/md_history/grouped_list.js +++ b/chrome/browser/resources/md_history/grouped_list.js
@@ -16,11 +16,11 @@ */ var HistoryGroup; -// TODO(calamity): Support selection by refactoring selection out of -// history-list and into history-app. Polymer({ is: 'history-grouped-list', + behaviors: [HistoryListBehavior], + properties: { // An array of history entries in reverse chronological order. historyData: { @@ -156,21 +156,36 @@ visits, itemIndex, this.searchedTerm); }, - hasResults_: function(historyDataLength) { - return historyDataLength > 0; + /** + * @param {number} groupIndex + * @param {number} domainIndex + * @param {number} itemIndex + * @return {string} + * @private + */ + pathForItem_: function(groupIndex, domainIndex, itemIndex) { + return [ + 'groupedHistoryData_', groupIndex, 'domains', domainIndex, 'visits', + itemIndex + ].join('.'); }, + /** + * @param {HistoryDomain} domain + * @return {string} + * @private + */ getWebsiteIconStyle_: function(domain) { return 'background-image: ' + cr.icon.getFaviconImageSet(domain.visits[0].url); }, + /** + * @param {boolean} expanded + * @return {string} + * @private + */ getDropdownIcon_: function(expanded) { return expanded ? 'cr:expand-less' : 'cr:expand-more'; }, - - noResultsMessage_: function(searchedTerm) { - var messageId = searchedTerm !== '' ? 'noSearchResults' : 'noResults'; - return loadTimeData.getString(messageId); - }, });
diff --git a/chrome/browser/resources/md_history/history_item.html b/chrome/browser/resources/md_history/history_item.html index 37f5168..f07a315b 100644 --- a/chrome/browser/resources/md_history/history_item.html +++ b/chrome/browser/resources/md_history/history_item.html
@@ -20,10 +20,7 @@ } :host(:not([embedded])) #main-container { - background: #fff; - border-color: var(--card-border-color); - border-style: solid; - border-width: 0 1px; + position: relative; } :host(:not([embedded])) #sizing-container { @@ -34,14 +31,7 @@ margin-top: var(--first-card-padding-top); } - :host([is-card-start]) #main-container { - border-radius: 2px 2px 0 0; - border-top-width: 1px; - } - :host([is-card-end]) #main-container { - border-bottom-width: 2px; - border-radius: 0 0 2px 2px; margin-bottom: var(--card-padding-between); } @@ -126,10 +116,34 @@ -webkit-margin-start: 77px; height: 15px; } + + #background { + background: #fff; + bottom: -1px; /* Prevents shadow artifacts when zoomed */ + left: 0; + position: absolute; + right: 0; + top: 0; + z-index: -1; + } + + :host([embedded]) #background { + display: none; + } + + :host([is-card-start]) #background { + border-radius: 2px 2px 0 0; + } + + :host([is-card-end]) #background { + border-radius: 0 0 2px 2px; + bottom: 0; + } </style> <div id="sizing-container"> <div id="main-container"> + <div id="background"></div> <div id="date-accessed" class="card-title"> [[cardTitle_(numberOfItems, item.dateRelativeDay, searchTerm)]] </div>
diff --git a/chrome/browser/resources/md_history/history_item.js b/chrome/browser/resources/md_history/history_item.js index 3146359..3ece411 100644 --- a/chrome/browser/resources/md_history/history_item.js +++ b/chrome/browser/resources/md_history/history_item.js
@@ -28,7 +28,10 @@ hasTimeGap: {type: Boolean}, - numberOfItems: {type: Number} + numberOfItems: {type: Number}, + + // The path of this history item inside its parent. + path: String, }, /** @@ -37,7 +40,9 @@ * @private */ onCheckboxSelected_: function() { + // TODO(calamity): Fire this event whenever |selected| changes. this.fire('history-checkbox-select', { + element: this, countAddition: this.$.checkbox.checked ? 1 : -1 }); },
diff --git a/chrome/browser/resources/md_history/history_list.html b/chrome/browser/resources/md_history/history_list.html index 9148450..13746da4 100644 --- a/chrome/browser/resources/md_history/history_list.html +++ b/chrome/browser/resources/md_history/history_list.html
@@ -1,9 +1,9 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-scroll-threshold/iron-scroll-threshold.html"> -<link rel="import" href="chrome://history/browser_service.html"> <link rel="import" href="chrome://history/constants.html"> <link rel="import" href="chrome://history/history_item.html"> +<link rel="import" href="chrome://history/history_list_behavior.html"> <link rel="import" href="chrome://history/shared_style.html"> <dom-module id="history-list"> @@ -11,10 +11,11 @@ <style include="shared-style"> :host { display: block; + overflow: overlay; } #infinite-list { - height: 100%; + @apply(--card-container-filter); } history-item { @@ -23,7 +24,7 @@ </style> <div id="no-results" class="centered-message" hidden$="[[hasResults(historyData_.length)]]"> - {{noResultsMessage_(searchedTerm, querying)}} + {{noResultsMessage(searchedTerm, querying)}} </div> <iron-list items="{{historyData_}}" as="item" id="infinite-list" hidden$="[[!hasResults(historyData_.length)]]"> @@ -35,7 +36,8 @@ is-card-end="[[isCardEnd_(item, index, historyData_.length)]]" has-time-gap="[[needsTimeGap_(item, index, historyData_.length)]]" search-term="[[searchedTerm]]" - number-of-items="[[historyData_.length]]"> + number-of-items="[[historyData_.length]]" + path="[[pathForItem_(index)]]"> </history-item> </template> </iron-list>
diff --git a/chrome/browser/resources/md_history/history_list.js b/chrome/browser/resources/md_history/history_list.js index aaba653..11b5911 100644 --- a/chrome/browser/resources/md_history/history_list.js +++ b/chrome/browser/resources/md_history/history_list.js
@@ -5,6 +5,8 @@ Polymer({ is: 'history-list', + behaviors: [HistoryListBehavior], + properties: { // The search term for the current query. Set when the query returns. searchedTerm: { @@ -26,7 +28,7 @@ }, listeners: { - 'infinite-list.scroll': 'notifyListScroll_', + 'scroll': 'notifyListScroll_', 'remove-bookmark-stars': 'removeBookmarkStars_', }, @@ -36,6 +38,8 @@ // resize events to fire before the list is attached and can be measured. // Adding another resize here ensures it will get sized correctly. /** @type {IronListElement} */(this.$['infinite-list']).notifyResize(); + this.$['infinite-list'].scrollTarget = this; + this.$['scroll-threshold'].scrollTarget = this; }, /** @@ -93,75 +97,6 @@ }, /** - * Cycle through each entry in historyData_ and set all items to be - * unselected. - * @param {number} overallItemCount The number of checkboxes selected. - */ - unselectAllItems: function(overallItemCount) { - if (this.historyData_ === undefined) - return; - - for (var i = 0; i < this.historyData_.length; i++) { - if (this.historyData_[i].selected) { - this.set('historyData_.' + i + '.selected', false); - overallItemCount--; - if (overallItemCount == 0) - break; - } - } - }, - - /** - * Remove the given |items| from the list. Expected to be called after the - * items are removed from the backend. - * @param {!Array<!HistoryEntry>} removalList - * @private - */ - removeDeletedHistory_: function(removalList) { - // This set is only for speed. Note that set inclusion for objects is by - // reference, so this relies on the HistoryEntry objects never being copied. - var deletedItems = new Set(removalList); - var splices = []; - - for (var i = this.historyData_.length - 1; i >= 0; i--) { - var item = this.historyData_[i]; - if (deletedItems.has(item)) { - // Removes the selected item from historyData_. Use unshift so - // |splices| ends up in index order. - splices.unshift({ - index: i, - removed: [item], - addedCount: 0, - object: this.historyData_, - type: 'splice' - }); - this.historyData_.splice(i, 1); - } - } - // notifySplices gives better performance than individually splicing as it - // batches all of the updates together. - this.notifySplices('historyData_', splices); - }, - - /** - * Performs a request to the backend to delete all selected items. If - * successful, removes them from the view. Does not prompt the user before - * deleting -- see <history-list-container> for a version of this method which - * does prompt. - */ - deleteSelected: function() { - var toBeRemoved = this.historyData_.filter(function(item) { - return item.selected; - }); - md_history.BrowserService.getInstance() - .deleteItems(toBeRemoved) - .then(function(items) { - this.removeDeletedHistory_(items); - this.fire('unselect-all'); - }.bind(this)); - }, - - /** * Called when the page is scrolled to near the bottom of the list. * @private */ @@ -186,17 +121,6 @@ this.historyData_, index, this.searchedTerm); }, - hasResults: function(historyDataLength) { - return historyDataLength > 0; - }, - - noResultsMessage_: function(searchedTerm, isLoading) { - if (isLoading) - return ''; - var messageId = searchedTerm !== '' ? 'noSearchResults' : 'noResults'; - return loadTimeData.getString(messageId); - }, - /** * True if the given item is the beginning of a new card. * @param {HistoryEntry} item @@ -244,4 +168,13 @@ notifyListScroll_: function() { this.fire('history-list-scrolled'); }, + + /** + * @param {number} index + * @return {string} + * @private + */ + pathForItem_: function(index) { + return 'historyData_.' + index; + }, });
diff --git a/chrome/browser/resources/md_history/history_list_behavior.html b/chrome/browser/resources/md_history/history_list_behavior.html new file mode 100644 index 0000000..0fb28cbf --- /dev/null +++ b/chrome/browser/resources/md_history/history_list_behavior.html
@@ -0,0 +1 @@ +<script src="chrome://history/history_list_behavior.js"></script>
diff --git a/chrome/browser/resources/md_history/history_list_behavior.js b/chrome/browser/resources/md_history/history_list_behavior.js new file mode 100644 index 0000000..0716b84 --- /dev/null +++ b/chrome/browser/resources/md_history/history_list_behavior.js
@@ -0,0 +1,199 @@ +// Copyright 2016 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 + * @param {string} currentPath + */ +var SelectionTreeNode = function(currentPath) { + /** @type {string} */ + this.currentPath = currentPath; + /** @type {boolean} */ + this.leaf = false; + /** @type {Array<number>} */ + this.indexes = []; + /** @type {Array<SelectionTreeNode>} */ + this.children = []; +}; + +/** + * @param {number} index + * @param {string} path + */ +SelectionTreeNode.prototype.addChild = function(index, path) { + this.indexes.push(index); + this.children[index] = new SelectionTreeNode(path); +}; + +/** @polymerBehavior */ +var HistoryListBehavior = { + properties: { + /** + * Polymer paths to the history items contained in this list. + * @type {Array<string>} selectedPaths + */ + selectedPaths: { + type: Array, + value: /** @return {Array<string>} */ function() { return []; } + }, + }, + + listeners: { + 'history-checkbox-select': 'itemSelected_', + }, + + /** + * @param {number} historyDataLength + * @return {boolean} + * @private + */ + hasResults: function(historyDataLength) { return historyDataLength > 0; }, + + /** + * @param {string} searchedTerm + * @param {boolean} isLoading + * @return {string} + * @private + */ + noResultsMessage: function(searchedTerm, isLoading) { + if (isLoading) + return ''; + + var messageId = searchedTerm !== '' ? 'noSearchResults' : 'noResults'; + return loadTimeData.getString(messageId); + }, + + /** + * Deselect each item in |selectedPaths|. + */ + unselectAllItems: function() { + this.selectedPaths.forEach(function(path) { + this.set(path + '.selected', false); + }.bind(this)); + + this.selectedPaths = []; + }, + + /** + * Performs a request to the backend to delete all selected items. If + * successful, removes them from the view. Does not prompt the user before + * deleting -- see <history-list-container> for a version of this method which + * does prompt. + */ + deleteSelected: function() { + var toBeRemoved = this.selectedPaths.map(function(path) { + return this.get(path); + }.bind(this)); + md_history.BrowserService.getInstance() + .deleteItems(toBeRemoved) + .then(function() { + this.removeItemsByPath(this.selectedPaths); + this.fire('unselect-all'); + }.bind(this)); + }, + + /** + * Removes the history items in |paths|. Assumes paths are of a.0.b.0... + * structure. + * + * We want to use notifySplices to update the arrays for performance reasons + * which requires manually batching and sending the notifySplices for each + * level. To do this, we build a tree where each node is an array and then + * depth traverse it to remove items. Each time a node has all children + * deleted, we can also remove the node. + * + * @param {Array<string>} paths + * @private + */ + removeItemsByPath: function(paths) { + if (paths.length == 0) + return; + + this.removeItemsBeneathNode_(this.buildRemovalTree_(paths)); + }, + + /** + * Creates the tree to traverse in order to remove |paths| from this list. + * Assumes paths are of a.0.b.0... + * structure. + * + * @param {Array<string>} paths + * @return {SelectionTreeNode} + * @private + */ + buildRemovalTree_: function(paths) { + var rootNode = new SelectionTreeNode(paths[0].split('.')[0]); + + // Build a tree to each history item specified in |paths|. + paths.forEach(function(path) { + var components = path.split('.'); + var node = rootNode; + components.shift(); + while (components.length > 1) { + var index = Number(components.shift()); + var arrayName = components.shift(); + + if (!node.children[index]) + node.addChild(index, [node.currentPath, index, arrayName].join('.')); + + node = node.children[index]; + } + node.leaf = true; + node.indexes.push(Number(components.shift())); + }); + + return rootNode; + }, + + /** + * Removes the history items underneath |node| and deletes container arrays as + * they become empty. + * @param {SelectionTreeNode} node + * @return {boolean} Whether this node's array should be deleted. + * @private + */ + removeItemsBeneathNode_: function(node) { + var array = this.get(node.currentPath); + var splices = []; + + node.indexes.sort(function(a, b) { return b - a; }); + node.indexes.forEach(function(index) { + if (node.leaf || this.removeItemsBeneathNode_(node.children[index])) { + var item = array.splice(index, 1); + splices.push({ + index: index, + removed: [item], + addedCount: 0, + object: array, + type: 'splice' + }); + } + }.bind(this)); + + if (array.length == 0) + return true; + + // notifySplices gives better performance than individually splicing as it + // batches all of the updates together. + this.notifySplices(node.currentPath, splices); + return false; + }, + + /** + * @param {Event} e + * @private + */ + itemSelected_: function(e) { + var item = e.detail.element; + var path = item.path; + if (item.selected) { + this.push('selectedPaths', path); + return; + } + + var index = this.selectedPaths.indexOf(path); + if (index != -1) + this.splice('selectedPaths', index, 1); + }, +};
diff --git a/chrome/browser/resources/md_history/history_toolbar.js b/chrome/browser/resources/md_history/history_toolbar.js index fd6f035..d346317e 100644 --- a/chrome/browser/resources/md_history/history_toolbar.js +++ b/chrome/browser/resources/md_history/history_toolbar.js
@@ -6,6 +6,8 @@ is: 'history-toolbar', properties: { // Number of history items currently selected. + // TODO(calamity): bind this to + // listContainer.selectedItem.selectedPaths.length. count: { type: Number, value: 0,
diff --git a/chrome/browser/resources/md_history/list_container.js b/chrome/browser/resources/md_history/list_container.js index 402db595..6cc6518 100644 --- a/chrome/browser/resources/md_history/list_container.js +++ b/chrome/browser/resources/md_history/list_container.js
@@ -87,8 +87,7 @@ }, unselectAllItems: function(count) { - /** @type {HistoryListElement} */ (this.$['infinite-list']) - .unselectAllItems(count); + this.getSelectedList_().unselectAllItems(count); }, /** @@ -141,7 +140,7 @@ /** @private */ onDialogConfirmTap_: function() { - this.$['infinite-list'].deleteSelected(); + this.getSelectedList_().deleteSelected(); this.$.dialog.close(); }, @@ -183,7 +182,7 @@ md_history.BrowserService.getInstance() .deleteItems([menu.itemData]) .then(function(items) { - this.$['infinite-list'].removeDeletedHistory_(items); + this.getSelectedList_().removeItemsByPath(items[0].path); // This unselect-all is to reset the toolbar when deleting a selected // item. TODO(tsergeant): Make this automatic based on observing list // modifications. @@ -191,4 +190,12 @@ }.bind(this)); menu.closeMenu(); }, + + /** + * @return {HTMLElement} + * @private + */ + getSelectedList_: function() { + return this.$.content.selectedItem; + }, });
diff --git a/chrome/browser/resources/md_history/shared_style.html b/chrome/browser/resources/md_history/shared_style.html index 294b914..3c782602 100644 --- a/chrome/browser/resources/md_history/shared_style.html +++ b/chrome/browser/resources/md_history/shared_style.html
@@ -3,6 +3,16 @@ <style> :root { --card-border-color: rgba(0, 0, 0, 0.14); + --card-box-shadow: { + box-shadow: 0 2px 2px rgba(0, 0, 0, .05), + 0 1px 4px rgba(0, 0, 0, .08), + 0 1px 1px rgba(0, 0, 0, .2);; + }; + --card-container-filter: { + filter: drop-shadow(0 2px 1px rgba(0, 0, 0, .05)) + drop-shadow(0 1px 0px rgba(0, 0, 0, .08)) + drop-shadow(0 1px 1px rgba(0, 0, 0, .2)); + }; --card-first-last-item-padding: 8px; --card-max-width: 960px; --card-min-width: 550px;
diff --git a/chrome/browser/resources/md_history/synced_device_card.html b/chrome/browser/resources/md_history/synced_device_card.html index 77549703..b227d7b 100644 --- a/chrome/browser/resources/md_history/synced_device_card.html +++ b/chrome/browser/resources/md_history/synced_device_card.html
@@ -45,13 +45,12 @@ } #collapse { - border-bottom: 1px solid var(--card-border-color); overflow: hidden; } #history-item-container { + @apply(--card-box-shadow); background: #fff; - border: 1px solid var(--card-border-color); border-radius: 2px; } @@ -77,7 +76,8 @@ </div> <div id="right-buttons"> <button is="paper-icon-button-light" id="menu-button" - class="icon-button" on-tap="onMenuButtonTap_"> + class="icon-button" on-tap="onMenuButtonTap_" + title="$i18n{moreActionsButton}"> <iron-icon icon="cr:more-vert"></iron-icon> </button> <button is="paper-icon-button-light" class="icon-button"
diff --git a/chrome/browser/resources/md_history/synced_device_manager.html b/chrome/browser/resources/md_history/synced_device_manager.html index bd8b029..ddf3ae1e 100644 --- a/chrome/browser/resources/md_history/synced_device_manager.html +++ b/chrome/browser/resources/md_history/synced_device_manager.html
@@ -11,7 +11,7 @@ <style include="shared-style"> :host { display: block; - overflow: auto; + overflow: overlay; } #illustration {
diff --git a/chrome/browser/resources/md_user_manager/user_manager.html b/chrome/browser/resources/md_user_manager/user_manager.html index 7b726c8..54b93880 100644 --- a/chrome/browser/resources/md_user_manager/user_manager.html +++ b/chrome/browser/resources/md_user_manager/user_manager.html
@@ -320,6 +320,7 @@ <error-dialog></error-dialog> <include src="../../../../ui/login/account_picker/user_pod_template.html"> </user-manager-pages> + <link rel="import" href="chrome://resources/html/i18n_template.html"> <script src="user_manager.js"></script> </body> </html>
diff --git a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.css b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.css index dc16b716..9ef29c9 100644 --- a/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.css +++ b/chrome/browser/resources/media_router/elements/media_router_container/media_router_container.css
@@ -154,8 +154,7 @@ overflow-x: hidden; /* overflow-y is set to auto when the results are actually displayed to allow * scrolling. It is set to hidden by default so the scrollbar isn't displayed - * while animating. - */ + * while animating. */ overflow-y: hidden; position: absolute; right: 0; @@ -216,8 +215,7 @@ } /* Separate icon class is a consequence of box-sizing: border-box set by - * paper-icon-button. This should achieve the same dimensions as .sink-icon. - */ + * paper-icon-button. This should achieve the same dimensions as .sink-icon. */ #sink-search-icon { -webkit-margin-start: 4px; -webkit-padding-end: 12px; @@ -246,7 +244,6 @@ } .sink-text { - -webkit-padding-end: var(--dialog-padding-end); flex-flow: row nowrap; line-height: normal; overflow: hidden;
diff --git a/chrome/browser/resources/net_internals/chromeos_view.css b/chrome/browser/resources/net_internals/chromeos_view.css index df0b65e8..5739974 100644 --- a/chrome/browser/resources/net_internals/chromeos_view.css +++ b/chrome/browser/resources/net_internals/chromeos_view.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ #chromeos-view-password-div, #chromeos-view-parse-status {
diff --git a/chrome/browser/resources/net_internals/events_view.css b/chrome/browser/resources/net_internals/events_view.css index 80b4d65..1183bfb 100644 --- a/chrome/browser/resources/net_internals/events_view.css +++ b/chrome/browser/resources/net_internals/events_view.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ #events-view-filter-box { background: #efefef;
diff --git a/chrome/browser/resources/net_internals/main.css b/chrome/browser/resources/net_internals/main.css index a96a7f1a..6beb421 100644 --- a/chrome/browser/resources/net_internals/main.css +++ b/chrome/browser/resources/net_internals/main.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ /* Only common styles should be declared here. */ @@ -17,10 +16,8 @@ padding-left: 2em; } -/** - * This class is used to create the splitter widget in - * ResizbleVerticalSplitView. - */ +/* This class is used to create the splitter widget in + * ResizbleVerticalSplitView. */ .vertical-splitter { -webkit-user-select: none; border-left: 1px solid #afafaf; @@ -42,10 +39,8 @@ font-size: 133%; } -/** - * This class should be given to top-level content boxes (like the view's main - * DIV). It gives them a consistent padding, and makes them scrollable. - */ +/* This class should be given to top-level content boxes (like the view's main + * DIV). It gives them a consistent padding, and makes them scrollable. */ .content-box { overflow: auto; padding: 20px 10px 10px 20px; @@ -61,9 +56,7 @@ margin-left: -10px; } -/** - * Styles for TABLE that uses a thin collapsed border. - */ +/* Styles for TABLE that uses a thin collapsed border. */ table.styled-table { border-collapse: collapse; } @@ -112,9 +105,7 @@ background: rgb(255,217,217); } -/** - * Styling for event logs. - */ +/* Styling for event logs. */ .event-log p { white-space: nowrap; } @@ -128,16 +119,12 @@ text-decoration: none; } -/** - * Styling for text indicating a potential problem or error state. - */ +/* Styling for text indicating a potential problem or error state. */ .warning-text { color: rgb(238, 0, 0); } -/** - * Styling for help windows that appear when mousing over an element. - */ +/* Styling for help windows that appear when mousing over an element. */ .mouse-over-help { background: #EEE; border: 1px solid black; @@ -145,9 +132,7 @@ z-index: 1; } -/** - * Styling for elements that show a help window on mouse over. - */ +/* Styling for elements that show a help window on mouse over. */ .mouse-over-help-hover { color: blue; cursor: help;
diff --git a/chrome/browser/resources/net_internals/spdy_view.html b/chrome/browser/resources/net_internals/spdy_view.html index 3fb82f80..74b5915 100644 --- a/chrome/browser/resources/net_internals/spdy_view.html +++ b/chrome/browser/resources/net_internals/spdy_view.html
@@ -29,7 +29,7 @@ <th>Host</th> <th>Proxy</th> <th>ID</th> - <th>Protocol Negotiated</th> + <th>Negotiated Protocol</th> <th>Active streams</th> <th>Unclaimed pushed</th> <th>Max</th> @@ -54,7 +54,10 @@ </td> <td jscontent="proxy"></td> <td><a jsvalues=".href: '#events&q=id:' + source_id" jscontent="source_id"></a></td> - <td jscontent="protocol_negotiated"></td> + <!-- "protocol_negotiated" was renamed "negotiated_protocol" in release 54 + at https://crrev.com/2229693003. + TODO(bnc): Remove support for netlog json files from earlier browsers around 2016 December. --> + <td jscontent="$this.negotiated_protocol == undefined ? $this.protocol_negotiated : $this.negotiated_protocol"></td> <td jscontent="active_streams"></td> <td jscontent="unclaimed_pushed_streams"></td> <td jscontent="max_concurrent_streams"></td>
diff --git a/chrome/browser/resources/net_internals/status_view.css b/chrome/browser/resources/net_internals/status_view.css index b9efa8e4..f2d71e0 100644 --- a/chrome/browser/resources/net_internals/status_view.css +++ b/chrome/browser/resources/net_internals/status_view.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ .capture-status-view { background: rgb(238, 0, 0);
diff --git a/chrome/browser/resources/net_internals/timeline_view.css b/chrome/browser/resources/net_internals/timeline_view.css index 5ce1994..0bcea44 100644 --- a/chrome/browser/resources/net_internals/timeline_view.css +++ b/chrome/browser/resources/net_internals/timeline_view.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ #timeline-view-selection-div { display: inline-block;
diff --git a/chrome/browser/resources/ntp4/incognito_and_guest_tab.css b/chrome/browser/resources/ntp4/incognito_and_guest_tab.css index 4055c59..ef6f279 100644 --- a/chrome/browser/resources/ntp4/incognito_and_guest_tab.css +++ b/chrome/browser/resources/ntp4/incognito_and_guest_tab.css
@@ -2,8 +2,7 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * - * Incognito and guest mode NTP shared CSS. - */ + * Incognito and guest mode NTP shared CSS. */ body { -webkit-font-smoothing: antialiased; @@ -31,8 +30,7 @@ } /* 'Learn More' button styled like a Material Design text button. - * TODO(edwardjung): Switch styled links to actual text buttons. - */ + * TODO(edwardjung): Switch styled links to actual text buttons. */ .learn-more-button { color: rgb(66, 133, 244); display: inline-block;
diff --git a/chrome/browser/resources/ntp4/nav_dot.css b/chrome/browser/resources/ntp4/nav_dot.css index ebcf48b1..52abe78 100644 --- a/chrome/browser/resources/ntp4/nav_dot.css +++ b/chrome/browser/resources/ntp4/nav_dot.css
@@ -3,8 +3,8 @@ * found in the LICENSE file. */ /* TODO(estade): handle overflow better? I tried overflow-x: hidden and - overflow-y: visible (for the new dot animation), but this makes a scroll - bar appear */ + * overflow-y: visible (for the new dot animation), but this makes a scroll + * bar appear */ #dot-list { /* Expand to take up all available horizontal space. */ -webkit-box-flex: 1; @@ -72,8 +72,7 @@ } /* Everything below here should be themed but we don't have appropriate colors - * yet. - */ + * yet. */ .dot input { color: #b2b2b2; }
diff --git a/chrome/browser/resources/ntp4/new_incognito_tab_theme.css b/chrome/browser/resources/ntp4/new_incognito_tab_theme.css index 62ec092..e6c6a69 100644 --- a/chrome/browser/resources/ntp4/new_incognito_tab_theme.css +++ b/chrome/browser/resources/ntp4/new_incognito_tab_theme.css
@@ -1,7 +1,6 @@ /* 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. */ html { background-attachment: fixed;
diff --git a/chrome/browser/resources/options/browser_options.html b/chrome/browser/resources/options/browser_options.html index fcfbb64..218964d 100644 --- a/chrome/browser/resources/options/browser_options.html +++ b/chrome/browser/resources/options/browser_options.html
@@ -348,18 +348,6 @@ </div> </div> </section> - - <section id="device-control-section" hidden> - <h3 i18n-content="deviceControlTitle"></h3> - <div id="consumer-management-section"> - <div class="settings-row"> - <span i18n-content="consumerManagementDescription"></span> - </div> - <div class="settings-row"> - <button id="consumer-management-button"></button> - </div> - </div> - </section> </if> <section id="privacy-section"> <h3 i18n-content="advancedSectionTitlePrivacy"></h3>
diff --git a/chrome/browser/resources/options/browser_options.js b/chrome/browser/resources/options/browser_options.js index 87fe6704..1fd2873 100644 --- a/chrome/browser/resources/options/browser_options.js +++ b/chrome/browser/resources/options/browser_options.js
@@ -640,16 +640,6 @@ }; } - // Device control section. - if (cr.isChromeOS && - UIAccountTweaks.currentUserIsOwner() && - loadTimeData.getBoolean('consumerManagementEnabled')) { - $('device-control-section').hidden = false; - $('consumer-management-button').onclick = function(event) { - PageManager.showPageByName('consumer-management-overlay'); - }; - } - // Easy Unlock section. if (loadTimeData.getBoolean('easyUnlockAllowed')) { $('easy-unlock-section').hidden = false; @@ -2392,43 +2382,6 @@ }; /** - * Shows different button text for each consumer management enrollment - * status. - * @enum {string} status Consumer management service status string. - */ - BrowserOptions.setConsumerManagementStatus = function(status) { - var button = $('consumer-management-button'); - if (status == 'StatusUnknown') { - button.hidden = true; - return; - } - - button.hidden = false; - /** @type {string} */ var strId; - switch (status) { - case ConsumerManagementOverlay.Status.STATUS_UNENROLLED: - strId = 'consumerManagementEnrollButton'; - button.disabled = false; - ConsumerManagementOverlay.setStatus(status); - break; - case ConsumerManagementOverlay.Status.STATUS_ENROLLING: - strId = 'consumerManagementEnrollingButton'; - button.disabled = true; - break; - case ConsumerManagementOverlay.Status.STATUS_ENROLLED: - strId = 'consumerManagementUnenrollButton'; - button.disabled = false; - ConsumerManagementOverlay.setStatus(status); - break; - case ConsumerManagementOverlay.Status.STATUS_UNENROLLING: - strId = 'consumerManagementUnenrollingButton'; - button.disabled = true; - break; - } - button.textContent = loadTimeData.getString(strId); - }; - - /** * Shows Android Apps settings when they are available. * (Chrome OS only). */
diff --git a/chrome/browser/resources/options/chromeos/change_picture_options.css b/chrome/browser/resources/options/chromeos/change_picture_options.css index 63f0381..97b9838 100644 --- a/chrome/browser/resources/options/chromeos/change_picture_options.css +++ b/chrome/browser/resources/options/chromeos/change_picture_options.css
@@ -43,15 +43,13 @@ padding: 2px; } -/** - * #user-image-preview can have the following classes: +/* #user-image-preview can have the following classes: * .default-image: one of the default images is selected (including the grey * silhouette); * .profile-image: profile image is selected; * .online: camera is streaming video; * .camera: camera (live or photo) is selected; - * .live: camera is in live mode (no photo taken yet/last photo removed). - */ + * .live: camera is in live mode (no photo taken yet/last photo removed). */ #user-image-preview { margin: 18px 10px 0 0;
diff --git a/chrome/browser/resources/options/chromeos/consumer_management_overlay.css b/chrome/browser/resources/options/chromeos/consumer_management_overlay.css deleted file mode 100644 index 16c74341..0000000 --- a/chrome/browser/resources/options/chromeos/consumer_management_overlay.css +++ /dev/null
@@ -1,7 +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. */ - -#consumer-management-overlay { - width: 500px; -}
diff --git a/chrome/browser/resources/options/chromeos/consumer_management_overlay.html b/chrome/browser/resources/options/chromeos/consumer_management_overlay.html deleted file mode 100644 index 9e7f763..0000000 --- a/chrome/browser/resources/options/chromeos/consumer_management_overlay.html +++ /dev/null
@@ -1,37 +0,0 @@ -<div id="consumer-management-overlay" class="page" hidden> - <div class="close-button"></div> - <div id="enroll-content" hidden> - <h1 i18n-content="consumerManagementOverlayEnrollTitle"></h1> - <div class="content-area"> - <span i18n-content="consumerManagementOverlayEnrollMessage"></span> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="consumer-management-overlay-enroll-cancel" type="reset" - i18n-content="cancel"> - </button> - <button id="consumer-management-overlay-enroll" - class="default-button" type="submit" - i18n-content="consumerManagementOverlayEnroll"> - </button> - </div> - </div> - </div> - <div id="unenroll-content" hidden> - <h1 i18n-content="consumerManagementOverlayUnenrollTitle"></h1> - <div class="content-area"> - <span i18n-content="consumerManagementOverlayUnenrollMessage"></span> - </div> - <div class="action-area"> - <div class="button-strip"> - <button id="consumer-management-overlay-unenroll-cancel" type="reset" - i18n-content="cancel"> - </button> - <button id="consumer-management-overlay-unenroll" - class="default-button" type="submit" - i18n-content="consumerManagementOverlayUnenroll"> - </button> - </div> - </div> - </div> -</div>
diff --git a/chrome/browser/resources/options/chromeos/consumer_management_overlay.js b/chrome/browser/resources/options/chromeos/consumer_management_overlay.js deleted file mode 100644 index c9d7a889..0000000 --- a/chrome/browser/resources/options/chromeos/consumer_management_overlay.js +++ /dev/null
@@ -1,72 +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. - -cr.define('options', function() { - var Page = cr.ui.pageManager.Page; - var PageManager = cr.ui.pageManager.PageManager; - - /** - * ConsumerManagementOverlay class - * Dialog that allows users to enroll/unenroll consumer management service. - * @constructor - * @extends {cr.ui.pageManager.Page} - */ - function ConsumerManagementOverlay() { - Page.call(this, 'consumer-management-overlay', - loadTimeData.getString('consumerManagementOverlayTabTitle'), - 'consumer-management-overlay'); - - $('consumer-management-overlay-enroll').onclick = function(event) { - chrome.send('enrollConsumerManagement'); - PageManager.closeOverlay(); - }; - $('consumer-management-overlay-unenroll').onclick = function(event) { - chrome.send('unenrollConsumerManagement'); - PageManager.closeOverlay(); - }; - $('consumer-management-overlay-enroll-cancel').onclick = function(event) { - PageManager.closeOverlay(); - }; - $('consumer-management-overlay-unenroll-cancel').onclick = function(event) { - PageManager.closeOverlay(); - }; - } - - cr.addSingletonGetter(ConsumerManagementOverlay); - - ConsumerManagementOverlay.prototype = { - __proto__: Page.prototype, - }; - - /** - * Consumer management status. - * See chrome/browser/chromeos/policy/consumer_management_service.h. - * @enum {string} - */ - ConsumerManagementOverlay.Status = { - STATUS_UNKNOWN: 'StatusUnknown', - STATUS_ENROLLED: 'StatusEnrolled', - STATUS_ENROLLING: 'StatusEnrolling', - STATUS_UNENROLLED: 'StatusUnenrolled', - STATUS_UNENROLLING: 'StatusUnenrolling' - }; - - /** - * Shows enrollment or unenrollment content based on the status. - * @enum {string} status Consumer management service status string. - */ - ConsumerManagementOverlay.setStatus = function(status) { - // Status should only be enrolled or unenrolled. - assert(status == this.Status.STATUS_ENROLLED || - status == this.Status.STATUS_UNENROLLED); - var enrolled = status == this.Status.STATUS_ENROLLED; - $('enroll-content').hidden = enrolled; - $('unenroll-content').hidden = !enrolled; - }; - - // Export - return { - ConsumerManagementOverlay: ConsumerManagementOverlay - }; -});
diff --git a/chrome/browser/resources/options/chromeos/storage_manager.css b/chrome/browser/resources/options/chromeos/storage_manager.css index 5d75d14..98712ab 100644 --- a/chrome/browser/resources/options/chromeos/storage_manager.css +++ b/chrome/browser/resources/options/chromeos/storage_manager.css
@@ -19,36 +19,46 @@ margin: 0; } -.storage-manager-section:not(:last-child) { - margin-bottom: 30px; -} - .storage-manager-item, .storage-manager-subitem { + align-items: baseline; display: flex; - font-size: 125%; /* go to 15px from 12px */ justify-content: space-between; - margin: 14px 0; } .storage-manager-item { color: black; + margin: 18px 0; +} + +.storage-manager-item .storage-manager-item-label { + font-size: 125%; /* go to 15px from 12px */ } .storage-manager-subitem { -webkit-padding-start: 20px; + margin: 14px 0; } .storage-manager-subitem .storage-manager-item-size { color: rgba(0, 0, 0, 0.54); } +#storage-manager-section-capacity { + margin-bottom: 23px; +} + +#storage-manager-section-capacity .storage-manager-item { + margin-bottom: 24px; + margin-top: 18px; +} + #storage-manager-section-in-use { - margin-bottom: 45px; + margin-bottom: 30px; } #storage-manager-section-available { - margin-bottom: 30px; + margin-bottom: 18px; } .critically-low-space #storage-manager-message-critically-low-space,
diff --git a/chrome/browser/resources/options/chromeos/storage_manager.html b/chrome/browser/resources/options/chromeos/storage_manager.html index 483562b..8ca8fa5 100644 --- a/chrome/browser/resources/options/chromeos/storage_manager.html +++ b/chrome/browser/resources/options/chromeos/storage_manager.html
@@ -22,9 +22,10 @@ </div> <div class="content-area"> - <div class="storage-manager-section"> + <div id="storage-manager-section-capacity" class="storage-manager-section"> <div class="storage-manager-item"> - <span i18n-content="storageItemLabelCapacity"></span> + <span i18n-content="storageItemLabelCapacity" + class="storage-manager-item-label"></span> <span id="storage-manager-size-capacity" class="storage-manager-item-size"></span> </div> @@ -32,7 +33,8 @@ </div> <div id="storage-manager-section-in-use" class="storage-manager-section"> <div class="storage-manager-item"> - <span i18n-content="storageItemLabelInUse"></span> + <span i18n-content="storageItemLabelInUse" + class="storage-manager-item-label"></span> <span id="storage-manager-size-in-use" class="storage-manager-item-size"></span> </div> @@ -81,7 +83,8 @@ </div> <div id="storage-manager-section-available" class="storage-manager-section"> <div class="storage-manager-item"> - <span i18n-content="storageItemLabelAvailable"></span> + <span i18n-content="storageItemLabelAvailable" + class="storage-manager-item-label"></span> <span id="storage-manager-size-available" class="storage-manager-item-size"></span> </div>
diff --git a/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.css b/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.css index c0e8d30..8a0ec40 100644 --- a/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.css +++ b/chrome/browser/resources/options/chromeos/third_party_ime_confirm_overlay.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ #third-party-ime-confirm-overlay { width: 500px;
diff --git a/chrome/browser/resources/options/clear_browser_data_overlay.css b/chrome/browser/resources/options/clear_browser_data_overlay.css index a571478..2cfeb46 100644 --- a/chrome/browser/resources/options/clear_browser_data_overlay.css +++ b/chrome/browser/resources/options/clear_browser_data_overlay.css
@@ -34,6 +34,9 @@ .clear-browser-data-counter { color: #999; +} + +input[type=checkbox] ~ span { line-height: 1.4em; }
diff --git a/chrome/browser/resources/options/hotword_confirm_overlay.css b/chrome/browser/resources/options/hotword_confirm_overlay.css index ef7288ff..542d8745 100644 --- a/chrome/browser/resources/options/hotword_confirm_overlay.css +++ b/chrome/browser/resources/options/hotword_confirm_overlay.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ #hotword-confirm-overlay { width: 500px;
diff --git a/chrome/browser/resources/options/options.html b/chrome/browser/resources/options/options.html index b6a95411..350ebcc 100644 --- a/chrome/browser/resources/options/options.html +++ b/chrome/browser/resources/options/options.html
@@ -56,7 +56,6 @@ <link rel="stylesheet" href="chromeos/arc_opt_out_confirm_overlay.css"> <link rel="stylesheet" href="chromeos/bluetooth.css"> <link rel="stylesheet" href="chromeos/change_picture_options.css"> -<link rel="stylesheet" href="chromeos/consumer_management_overlay.css"> <link rel="stylesheet" href="chromeos/display_options.css"> <link rel="stylesheet" href="chromeos/display_overscan.css"> <link rel="stylesheet" href="chromeos/internet_detail.css"> @@ -136,7 +135,6 @@ <include src="chromeos/bluetooth_add_device_overlay.html"> <include src="chromeos/bluetooth_pair_device_overlay.html"> <include src="chromeos/change_picture_options.html"> - <include src="chromeos/consumer_management_overlay.html"> <include src="chromeos/display_options.html"> <include src="chromeos/keyboard_overlay.html"> <include src="chromeos/note_overlay.html">
diff --git a/chrome/browser/resources/options/options.js b/chrome/browser/resources/options/options.js index 7148c64..b6a3410 100644 --- a/chrome/browser/resources/options/options.js +++ b/chrome/browser/resources/options/options.js
@@ -208,8 +208,6 @@ [$('account-picture')]); PageManager.registerOverlay(StorageClearDriveCacheOverlay.getInstance(), StorageManager.getInstance()); - PageManager.registerOverlay(ConsumerManagementOverlay.getInstance(), - BrowserOptions.getInstance()); PageManager.registerOverlay(DetailsInternetPage.getInstance(), BrowserOptions.getInstance()); PageManager.registerOverlay(DisplayOptions.getInstance(),
diff --git a/chrome/browser/resources/options/options_bundle.js b/chrome/browser/resources/options/options_bundle.js index 56f9836d..416a840d 100644 --- a/chrome/browser/resources/options/options_bundle.js +++ b/chrome/browser/resources/options/options_bundle.js
@@ -31,7 +31,6 @@ <include src="chromeos/proxy_rules_list.js"> <include src="chromeos/accounts_user_list.js"> <include src="chromeos/accounts_user_name_edit.js"> -<include src="chromeos/consumer_management_overlay.js"> <include src="chromeos/display_layout.js"> <include src="chromeos/display_layout_manager.js"> <include src="chromeos/display_layout_manager_multi.js"> @@ -46,7 +45,6 @@ <include src="chromeos/power_overlay.js"> var AccountsOptions = options.AccountsOptions; var ChangePictureOptions = options.ChangePictureOptions; -var ConsumerManagementOverlay = options.ConsumerManagementOverlay; var DetailsInternetPage = options.internet.DetailsInternetPage; var DisplayOptions = options.DisplayOptions; var DisplayOverscan = options.DisplayOverscan;
diff --git a/chrome/browser/resources/options/options_page.css b/chrome/browser/resources/options/options_page.css index d0ccfa2..c454205 100644 --- a/chrome/browser/resources/options/options_page.css +++ b/chrome/browser/resources/options/options_page.css
@@ -89,8 +89,7 @@ } /* Omit top padding (currently only on #settings) whenever the search page is - * showing. - */ + * showing. */ #searchPage:not([hidden]) + #settings { padding-top: 0; } @@ -317,8 +316,7 @@ /* Don't use display:none or visibility:hidden because we need to keep an * element focusable. * We shrink only height. We don't shrink width to avoid to change the size - * of containing boxes. - */ + * of containing boxes. */ border-bottom: 0 !important; border-top: 0 !important; height: 0 !important; @@ -433,8 +431,7 @@ html:not([hasFlashPlugin]) .flash-plugin-area, /* If the Flash plug-in supports the NPP_ClearSiteData API, we don't need to - * show the link to the Flash storage settings manager: - */ + * show the link to the Flash storage settings manager: */ html[flashPluginSupportsClearSiteData] .flash-plugin-area, html:not([flashPluginSupportsClearSiteData]) .clear-plugin-lso-data-enabled, html[flashPluginSupportsClearSiteData] .clear-plugin-lso-data-disabled,
diff --git a/chrome/browser/resources/options/password_manager.css b/chrome/browser/resources/options/password_manager.css index 18314ef..1bb9997c 100644 --- a/chrome/browser/resources/options/password_manager.css +++ b/chrome/browser/resources/options/password_manager.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ #password-manager > div.content-area { width: 600px;
diff --git a/chrome/browser/resources/options/spelling_confirm_overlay.css b/chrome/browser/resources/options/spelling_confirm_overlay.css index 434c26c..ea3594b 100644 --- a/chrome/browser/resources/options/spelling_confirm_overlay.css +++ b/chrome/browser/resources/options/spelling_confirm_overlay.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ #spelling-confirm-overlay { width: 500px;
diff --git a/chrome/browser/resources/options/subpages_tab_controls.css b/chrome/browser/resources/options/subpages_tab_controls.css index 45f5f5c..5ab21c3 100644 --- a/chrome/browser/resources/options/subpages_tab_controls.css +++ b/chrome/browser/resources/options/subpages_tab_controls.css
@@ -20,8 +20,7 @@ /* To avoid tabs changing size when they are clicked and their labels become * bold, we actually put two labels inside each tab: an inactive label and an * active label. Only one is visible at a time, but the bold label is used to - * size the tab even when it's not visible. This keeps the tab size constant. - */ + * size the tab even when it's not visible. This keeps the tab size constant. */ .subpages-nav-tabs .active-tab-label, .subpages-nav-tabs .tab-label:hover { font-weight: bold; @@ -42,9 +41,8 @@ visibility: hidden; } -/* .tab is not removed when .active-tab is added, so we must - * override the hidden visibility above in the active tab case. - */ +/* .tab is not removed when .active-tab is added, so we must override the hidden + * visibility above in the active tab case. */ .subpages-nav-tabs .active-tab .active-tab-label { visibility: visible; }
diff --git a/chrome/browser/resources/password_manager_internals/password_manager_internals.css b/chrome/browser/resources/password_manager_internals/password_manager_internals.css index c55215a6..09a6603 100644 --- a/chrome/browser/resources/password_manager_internals/password_manager_internals.css +++ b/chrome/browser/resources/password_manager_internals/password_manager_internals.css
@@ -2,8 +2,7 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * - * chrome://password-manager-internals/ - */ + * chrome://password-manager-internals/ */ #logging-note { font-style: italic;
diff --git a/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.css b/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.css index 1133812..74ac2728 100644 --- a/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.css +++ b/chrome/browser/resources/pdf/elements/viewer-bookmark/viewer-bookmark.css
@@ -22,8 +22,7 @@ * for showing up for clicks, while still allowing it with tab-navigation. * This undoes a paper-ripple bugfix aimed at non-Chrome browsers. * TODO(tsergeant): Improve focus in viewer-bookmark so this can be removed - * (https://crbug.com/5448190). - */ + * (https://crbug.com/5448190). */ pointer-events: auto; }
diff --git a/chrome/browser/resources/pdf/pdf.js b/chrome/browser/resources/pdf/pdf.js index da29ea7..c7b1720 100644 --- a/chrome/browser/resources/pdf/pdf.js +++ b/chrome/browser/resources/pdf/pdf.js
@@ -131,8 +131,8 @@ this.delayedScriptingMessages_ = []; - this.isPrintPreview_ = this.originalUrl_.indexOf( - 'chrome://print') == 0; + this.isPrintPreview_ = this.originalUrl_.indexOf('chrome://print') == 0; + // Parse open pdf parameters. this.paramsParser_ = new OpenPDFParamsParser(this.getNamedDestination_.bind(this)); @@ -188,8 +188,7 @@ window.addEventListener('message', this.handleScriptingMessage.bind(this), false); - this.plugin_.setAttribute('src', - this.originalUrl_); + this.plugin_.setAttribute('src', this.originalUrl_); this.plugin_.setAttribute('stream-url', this.browserApi_.getStreamInfo().streamUrl); var headers = ''; @@ -230,8 +229,7 @@ this.plugin_.addEventListener('mouseup', this.toolbar_.hideDropdowns.bind(this.toolbar_)); - this.toolbar_.docTitle = - getFilenameFromURL(this.originalUrl_); + this.toolbar_.docTitle = getFilenameFromURL(this.originalUrl_); } document.body.addEventListener('change-page', function(e) { @@ -261,8 +259,7 @@ document.addEventListener('mouseout', this.handleMouseEvent_.bind(this)); var isInTab = this.browserApi_.getStreamInfo().tabId != -1; - var isSourceFileUrl = - this.originalUrl_.indexOf('file://') == 0; + var isSourceFileUrl = this.originalUrl_.indexOf('file://') == 0; this.navigator_ = new Navigator(this.originalUrl_, this.viewport_, this.paramsParser_, onNavigateInCurrentTab.bind(undefined, @@ -654,8 +651,7 @@ if (message.data.title) { document.title = message.data.title; } else { - document.title = - getFilenameFromURL(this.originalUrl_); + document.title = getFilenameFromURL(this.originalUrl_); } this.bookmarks_ = message.data.bookmarks; if (this.toolbar_) { @@ -667,8 +663,7 @@ this.viewportScroller_.setEnableScrolling(message.data.isSelecting); break; case 'getNamedDestinationReply': - this.paramsParser_.onNamedDestinationReceived( - message.data.pageNumber); + this.paramsParser_.onNamedDestinationReceived(message.data.pageNumber); break; case 'formFocusChange': this.isFormFieldFocused_ = message.data.focused;
diff --git a/chrome/browser/resources/predictors/predictors.css b/chrome/browser/resources/predictors/predictors.css index 8ca8a199..fb70515 100644 --- a/chrome/browser/resources/predictors/predictors.css +++ b/chrome/browser/resources/predictors/predictors.css
@@ -1,8 +1,6 @@ -/* - * Copyright (c) 2012 The Chromium Authors. All rights reserved. +/* 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. - */ + * found in the LICENSE file. */ body { margin: 20px;
diff --git a/chrome/browser/resources/search_header.css b/chrome/browser/resources/search_header.css index ce09f827..2974894 100644 --- a/chrome/browser/resources/search_header.css +++ b/chrome/browser/resources/search_header.css
@@ -11,8 +11,7 @@ * | Summary (90235 things currently great) _Great links_ | * * The title expands to fill any space it needs and the search bar is locked to - * the end of the header (e.g., right in LTR, left in RTL). - */ + * the end of the header (e.g., right in LTR, left in RTL). */ header, .summary {
diff --git a/chrome/browser/resources/settings/a11y_page/a11y_page.html b/chrome/browser/resources/settings/a11y_page/a11y_page.html index 85bcf7f..1977b0a 100644 --- a/chrome/browser/resources/settings/a11y_page/a11y_page.html +++ b/chrome/browser/resources/settings/a11y_page/a11y_page.html
@@ -17,7 +17,7 @@ <if expr="chromeos"> <settings-animated-pages id="pages" current-route="{{currentRoute}}" section="a11y"> - <neon-animatable id="main"> + <neon-animatable route-path="default"> <div class="settings-box first"> <div class="start"> $i18n{optionsInMenuLabel} @@ -33,7 +33,7 @@ </paper-button> </div> </neon-animatable> - <template is="dom-if" name="manage-a11y"> + <template is="dom-if" route-path="/manageAccessibility"> <settings-subpage associated-control="[[$$('#subpage-trigger')]]" page-title="$i18n{manageAccessibilityFeatures}">
diff --git a/chrome/browser/resources/settings/about_page/about_page.html b/chrome/browser/resources/settings/about_page/about_page.html index 544ff45..99ef7cb 100644 --- a/chrome/browser/resources/settings/about_page/about_page.html +++ b/chrome/browser/resources/settings/about_page/about_page.html
@@ -68,7 +68,7 @@ <div> <settings-section page-title="$i18n{aboutPageTitle}" section="about"> <settings-animated-pages id="pages" section="about"> - <neon-animatable id="main"> + <neon-animatable route-path="default"> <div class="settings-box"> <img id="product-logo" srcset="chrome://theme/current-channel-logo@1x 1x, @@ -170,7 +170,7 @@ </if> </neon-animatable> <if expr="chromeos"> - <template is="dom-if" name="detailed-build-info"> + <template is="dom-if" route-path="/help/details"> <settings-subpage page-title="$i18n{aboutDetailedBuildInfo}"> <settings-detailed-build-info></settings-detailed-build-info> </settings-subpage>
diff --git a/chrome/browser/resources/settings/appearance_page/appearance_page.html b/chrome/browser/resources/settings/appearance_page/appearance_page.html index 8303b98..bbfe5cc3 100644 --- a/chrome/browser/resources/settings/appearance_page/appearance_page.html +++ b/chrome/browser/resources/settings/appearance_page/appearance_page.html
@@ -25,7 +25,7 @@ } </style> <settings-animated-pages id="pages" section="appearance"> - <neon-animatable id="main"> + <neon-animatable route-path="default"> <if expr="chromeos"> <div class="settings-box first two-line" id="wallpaperButton" on-tap="openWallpaperManager_" actionable @@ -124,7 +124,7 @@ </settings-dropdown-menu> </div> </neon-animatable> - <template is="dom-if" name="appearance-fonts"> + <template is="dom-if" route-path="/fonts"> <settings-subpage associated-control="[[$$('#customize-fonts-subpage-trigger')]]" page-title="$i18n{customizeFonts}">
diff --git a/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html b/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html index f27f2ac..e5bb2552 100644 --- a/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html +++ b/chrome/browser/resources/settings/bluetooth_page/bluetooth_page.html
@@ -41,7 +41,7 @@ } </style> <settings-animated-pages id="pages" section="bluetooth"> - <neon-animatable id="main"> + <neon-animatable route-path="default"> <div class="settings-box first"> <div class="layout horizontal center flex"> <iron-icon icon="settings:bluetooth"></iron-icon>
diff --git a/chrome/browser/resources/settings/controls/settings_checkbox.html b/chrome/browser/resources/settings/controls/settings_checkbox.html index bd8a2548..220ffc79 100644 --- a/chrome/browser/resources/settings/controls/settings_checkbox.html +++ b/chrome/browser/resources/settings/controls/settings_checkbox.html
@@ -1,6 +1,5 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_events/cr_events.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_behavior.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html"> <link rel="import" href="/controls/pref_control_behavior.html"> @@ -37,8 +36,6 @@ -webkit-margin-start: var(--checkbox-spacing); } </style> - <cr-events id="events"></cr-events> - <div id="outerRow" noSubLabel$="[[!subLabel]]"> <paper-checkbox id="checkbox" checked="{{checked}}" disabled="[[checkboxDisabled_(disabled, pref)]]">
diff --git a/chrome/browser/resources/settings/controls/settings_checkbox.js b/chrome/browser/resources/settings/controls/settings_checkbox.js index 34e89be..7dabd98 100644 --- a/chrome/browser/resources/settings/controls/settings_checkbox.js +++ b/chrome/browser/resources/settings/controls/settings_checkbox.js
@@ -57,11 +57,6 @@ 'prefValueChanged_(pref.value)' ], - /** @override */ - ready: function() { - this.$.events.forward(this.$.checkbox, ['change']); - }, - /** * Polymer observer for pref.value. * @param {*} prefValue
diff --git a/chrome/browser/resources/settings/controls/settings_input.html b/chrome/browser/resources/settings/controls/settings_input.html index 8089692..265cbe35b 100644 --- a/chrome/browser/resources/settings/controls/settings_input.html +++ b/chrome/browser/resources/settings/controls/settings_input.html
@@ -1,6 +1,5 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html"> -<link rel="import" href="chrome://resources/cr_elements/cr_events/cr_events.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_behavior.html"> <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html"> <link rel="import" href="/controls/pref_control_behavior.html"> @@ -13,8 +12,6 @@ display: inline-block; } </style> - <cr-events id="events"></cr-events> - <div id="outerDiv" class="layout horizontal center"> <paper-input id="input" auto-validate value="{{value}}" error-message="[[errorMessage]]" label="[[label]]"
diff --git a/chrome/browser/resources/settings/controls/settings_input.js b/chrome/browser/resources/settings/controls/settings_input.js index 9ddf8383..1de44bb 100644 --- a/chrome/browser/resources/settings/controls/settings_input.js +++ b/chrome/browser/resources/settings/controls/settings_input.js
@@ -48,11 +48,6 @@ type: { type: String }, }, - /** @override */ - ready: function() { - this.$.events.forward(this.$.input, ['change']); - }, - /** * Focuses the 'input' element. */
diff --git a/chrome/browser/resources/settings/device_page/device_page.html b/chrome/browser/resources/settings/device_page/device_page.html index f910dfc..0ae40c7 100644 --- a/chrome/browser/resources/settings/device_page/device_page.html +++ b/chrome/browser/resources/settings/device_page/device_page.html
@@ -20,7 +20,7 @@ <template> <style include="settings-shared"></style> <settings-animated-pages id="pages" section="device"> - <neon-animatable id="main"> + <neon-animatable id="main" route-path="default"> <div id="pointersRow" class="settings-box first" on-tap="onPointersTap_" actionable> <iron-icon icon="[[getPointersIcon_(hasMouse_, hasTouchpad_)]]"> @@ -47,7 +47,7 @@ <div class="middle">$i18n{displayTitle}</div> </div> </neon-animatable> - <template is="dom-if" name="pointers"> + <template is="dom-if" route-path="/pointer-overlay"> <settings-subpage associated-control="[[$$('#pointersRow')]]" page-title="[[getPointersTitle_(hasMouse_, hasTouchpad_)]]"> @@ -56,7 +56,7 @@ </settings-pointers> </settings-subpage> </template> - <template is="dom-if" name="keyboard"> + <template is="dom-if" route-path="/keyboard-overlay"> <settings-subpage associated-control="[[$$('#keyboardRow')]]" page-title="$i18n{keyboardTitle}"> @@ -64,7 +64,7 @@ </settings-subpage> </template> <template is="dom-if" if=[[noteAllowed_]]> - <template is="dom-if" name="note"> + <template is="dom-if" route-path="/note"> <settings-subpage associated-control="[[$$('#noteRow')]]" page-title="$i18n{noteTitle}"> @@ -72,7 +72,7 @@ </settings-subpage> </template> </template> - <template is="dom-if" name="display"> + <template is="dom-if" route-path="/display"> <settings-subpage associated-control="[[$$('#displayRow')]]" page-title="$i18n{displayTitle}">
diff --git a/chrome/browser/resources/settings/internet_page/internet_page.html b/chrome/browser/resources/settings/internet_page/internet_page.html index b83b36c..8249812 100644 --- a/chrome/browser/resources/settings/internet_page/internet_page.html +++ b/chrome/browser/resources/settings/internet_page/internet_page.html
@@ -24,7 +24,7 @@ } </style> <settings-animated-pages id="pages" section="internet"> - <neon-animatable id="main"> + <neon-animatable route-path="default"> <network-summary on-show-detail="onShowDetail_" default-network="{{defaultNetwork}}" on-show-known-networks="onShowKnownNetworks_" @@ -51,7 +51,7 @@ </div> </template> </neon-animatable> - <template is="dom-if" name="network-detail" no-search> + <template is="dom-if" route-path="/networkDetail" no-search> <settings-subpage page-title="$i18n{internetDetailPageTitle}"> <settings-internet-detail-page guid="[[detailGuid]]" @@ -60,7 +60,7 @@ </settings-internet-detail-page> </settings-subpage> </template> - <template is="dom-if" name="known-networks" no-search> + <template is="dom-if" route-path="/knownNetworks" no-search> <settings-subpage page-title="$i18n{internetKnownNetworksPageTitle}"> <settings-internet-known-networks-page network-type="[[knownNetworksType]]"
diff --git a/chrome/browser/resources/settings/languages_page/languages_page.html b/chrome/browser/resources/settings/languages_page/languages_page.html index 040a5eb..391a2ba 100644 --- a/chrome/browser/resources/settings/languages_page/languages_page.html +++ b/chrome/browser/resources/settings/languages_page/languages_page.html
@@ -34,7 +34,7 @@ </style> <settings-languages languages="{{languages}}"></settings-languages> <settings-animated-pages id="pages" section="languages"> - <neon-animatable id="main"> + <neon-animatable route-path="default"> <div id="manage-languages-subpage-trigger" class="settings-box first two-line"> <div class="start"> @@ -79,11 +79,13 @@ </if> <paper-icon-button id="more-[[item.language.code]]" icon="cr:more-vert" toggles - active="{{item.optionsMenuOpened}}"> + active="{{item.optionsMenuOpened}}" + on-tap="stopPropagationHandler_"> </paper-icon-button> <iron-dropdown opened="{{item.optionsMenuOpened}}" horizontal-align="right" vertical-align="auto"> - <div class="dropdown-content"> + <div class="dropdown-content" + on-tap="stopPropagationHandler_"> <button class="dropdown-item" role="option" on-tap="onMoveUpTap_" hidden="[[isFirstLanguage_(index, @@ -186,7 +188,7 @@ </iron-collapse> </if> </neon-animatable> - <template is="dom-if" name="manage-languages"> + <template is="dom-if" route-path="/manageLanguages"> <settings-subpage associated-control="[[$$('#manage-languages-subpage-trigger')]]" page-title="$i18n{manageLanguagesPageTitle}"> @@ -194,7 +196,7 @@ prefs="{{prefs}}"></settings-manage-languages-page> </settings-subpage> </template> - <template is="dom-if" name="language-detail" no-search> + <template is="dom-if" route-path="/languages/edit" no-search> <settings-subpage page-title="[[detailLanguage_.language.displayName]]"> <settings-language-detail-page id="languageDetailPage" prefs="{{prefs}}" detail="[[detailLanguage_]]"> @@ -202,7 +204,7 @@ </settings-subpage> </template> <if expr="chromeos"> - <template is="dom-if" name="manage-input-methods"> + <template is="dom-if" route-path="/inputMethods"> <settings-subpage associated-control="[[$$('#manage-input-methods-subpage-trigger')]]" page-title="$i18n{manageInputMethodsPageTitle}"> @@ -212,7 +214,7 @@ </template> </if> <if expr="not is_macosx"> - <template is="dom-if" name="edit-dictionary"> + <template is="dom-if" route-path="/editDictionary"> <settings-subpage associated-control="[[$$('#spellcheck-subpage-trigger')]]" page-title="$i18n{editDictionaryPageTitle}">
diff --git a/chrome/browser/resources/settings/languages_page/languages_page.js b/chrome/browser/resources/settings/languages_page/languages_page.js index d88a859..f36e18a7 100644 --- a/chrome/browser/resources/settings/languages_page/languages_page.js +++ b/chrome/browser/resources/settings/languages_page/languages_page.js
@@ -56,7 +56,7 @@ /** * Handler for clicking a language on the main page, which selects the * language as the prospective UI language on Chrome OS and Windows. - * @param {!{model: !{item: !LanguageState}}} e + * @param {!Event} e The tap event. */ onLanguageTap_: function(e) { // Only change the UI language on platforms that allow it. @@ -64,8 +64,19 @@ return; // Set the prospective UI language. This won't take effect until a restart. - if (e.model.item.language.supportsUI) - this.languageHelper_.setUILanguage(e.model.item.language.code); + var tapEvent = /** @type {!{model: !{item: !LanguageState}}} */(e); + if (tapEvent.model.item.language.supportsUI) + this.languageHelper_.setUILanguage(tapEvent.model.item.language.code); + }, + + /** + * Stops tap events on the language options menu, its trigger, or its items + * from bubbling up to the language itself. Tap events on the language are + * handled in onLanguageTap_. + * @param {!Event} e The tap event. + */ + stopPropagationHandler_: function(e) { + e.stopPropagation(); }, /**
diff --git a/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.html b/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.html index d8b1a86..a8872c5 100644 --- a/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.html +++ b/chrome/browser/resources/settings/passwords_and_forms_page/passwords_and_forms_page.html
@@ -16,7 +16,7 @@ <template> <style include="settings-shared"></style> <settings-animated-pages id="pages" section="passwordsAndForms"> - <neon-animatable id="main"> + <neon-animatable route-path="default"> <div class="settings-box first two-line" on-tap="onAutofillTap_" id="autofillManagerButton" actionable$="[[prefs.autofill.enabled.value]]"> @@ -40,7 +40,7 @@ </paper-toggle-button> </div> </neon-animatable> - <template is="dom-if" name="manage-autofill"> + <template is="dom-if" route-path="/autofill"> <settings-subpage associated-control="[[$$('#autofillManagerButton')]]" page-title="$i18n{autofill}"> @@ -49,7 +49,7 @@ </settings-autofill-section> </settings-subpage> </template> - <template is="dom-if" name="manage-passwords"> + <template is="dom-if" route-path="/managePasswords"> <settings-subpage associated-control="[[$$('#passwordManagerButton')]]" page-title="$i18n{passwords}"
diff --git a/chrome/browser/resources/settings/people_page/people_page.html b/chrome/browser/resources/settings/people_page/people_page.html index 13b2f0a1..c954603 100644 --- a/chrome/browser/resources/settings/people_page/people_page.html +++ b/chrome/browser/resources/settings/people_page/people_page.html
@@ -73,7 +73,7 @@ } </style> <settings-animated-pages id="pages" section="people"> - <neon-animatable id="main"> + <neon-animatable route-path="default"> <div id="picture-subpage-trigger" class="settings-box first two-line"> <img id="profile-icon" src="[[profileIconUrl_]]" on-tap="onPictureTap_" actionable> @@ -239,18 +239,18 @@ </div> </template> </neon-animatable> - <template is="dom-if" if="[[isAdvancedSyncSettingsVisible_(syncStatus)]]"> - <template is="dom-if" name="sync"> - <settings-subpage - associated-control="[[$$('#customize-sync')]]" - page-title="$i18n{syncPageTitle}"> - <settings-sync-page></settings-sync-page> - </settings-subpage> - </template> + <template is="dom-if" route-path="/syncSetup" + no-search$="[[!isAdvancedSyncSettingsVisible_(syncStatus)]]"> + <settings-subpage + associated-control="[[$$('#customize-sync')]]" + page-title="$i18n{syncPageTitle}" + no-search$="[[!isAdvancedSyncSettingsVisible_(syncStatus)]]"> + <settings-sync-page></settings-sync-page> + </settings-subpage> </template> <if expr="chromeos"> <template is="dom-if" if="[[quickUnlockEnabled_]]"> - <template is="dom-if" name="lockScreen"> + <template is="dom-if" route-path="/lockScreen" no-search> <settings-subpage page-title="$i18n{lockScreenTitle}"> <settings-lock-screen prefs="{{prefs}}"> @@ -258,14 +258,14 @@ </settings-subpage> </template> </template> - <template is="dom-if" name="users"> + <template is="dom-if" route-path="/accounts"> <settings-subpage associated-control="[[$$('#manage-other-people-subpage-trigger')]]" page-title="$i18n{usersPageTitle}"> <settings-users-page prefs="{{prefs}}"></settings-users-page> </settings-subpage> </template> - <template is="dom-if" name="changePicture"> + <template is="dom-if" route-path="/changePicture"> <settings-subpage associated-control="[[$$('#picture-subpage-trigger')]]" page-title="$i18n{changePictureTitle}"> @@ -274,7 +274,7 @@ </template> </if> <if expr="not chromeos"> - <template is="dom-if" name="manageProfile"> + <template is="dom-if" route-path="/manageProfile"> <settings-subpage associated-control="[[$$('#picture-subpage-trigger')]]" page-title="$i18n{editPerson}">
diff --git a/chrome/browser/resources/settings/people_page/sync_page.html b/chrome/browser/resources/settings/people_page/sync_page.html index a4ecc8293..df21c04 100644 --- a/chrome/browser/resources/settings/people_page/sync_page.html +++ b/chrome/browser/resources/settings/people_page/sync_page.html
@@ -1,7 +1,6 @@ <link rel="import" href="chrome://resources/html/i18n_behavior.html"> <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-pages/iron-pages.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html"> @@ -24,178 +23,179 @@ width: var(--paper-input-max-width); } </style> - <iron-pages id="pages" selected="[[selectedPage_]]" attr-for-selected="id"> - <div id="[[pages.SPINNER]]" class="settings-box first"> - $i18n{syncLoading} + <div id="[[pages.SPINNER]]" class="settings-box first" + hidden$="[[!isStatus_(pages.SPINNER, pageStatus_)]]"> + $i18n{syncLoading} + </div> + <div id="[[pages.TIMEOUT]]" class="settings-box first" + hidden$="[[!isStatus_(pages.TIMEOUT, pageStatus_)]]"> + $i18n{syncTimeout} + </div> + <div id="[[pages.CONFIGURE]]" + hidden$="[[!isStatus_(pages.CONFIGURE, pageStatus_)]]"> + <div class="settings-box first"> + <paper-checkbox id="syncAllDataTypesCheckbox" + checked="{{syncPrefs.syncAllDataTypes}}" + on-change="onSyncAllDataTypesChanged_"> + $i18n{syncEverythingCheckboxLabel} + </paper-checkbox> </div> - <div id="[[pages.TIMEOUT]]" class="settings-box first"> - $i18n{syncTimeout} - </div> - <div id="[[pages.CONFIGURE]]"> - <div class="settings-box first"> - <paper-checkbox id="syncAllDataTypesCheckbox" - checked="{{syncPrefs.syncAllDataTypes}}" - on-change="onSyncAllDataTypesChanged_"> - $i18n{syncEverythingCheckboxLabel} - </paper-checkbox> - </div> + <div class="list-frame"> + <paper-checkbox checked="{{syncPrefs.appsSynced}}" + on-change="onSingleSyncDataTypeChanged_" class="list-item" + hidden="[[!syncPrefs.appsRegistered]]" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.appsEnforced)]]"> + $i18n{appCheckboxLabel} + </paper-checkbox> + + <!-- Autofill has a special on-change handler to deal with + Payments integriation. --> + <paper-checkbox checked="{{syncPrefs.autofillSynced}}" + on-change="onAutofillDataTypeChanged_" class="list-item" + hidden="[[!syncPrefs.autofillRegistered]]" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.autofillEnforced)]]"> + $i18n{autofillCheckboxLabel} + </paper-checkbox> + + <paper-checkbox checked="{{syncPrefs.bookmarksSynced}}" + on-change="onSingleSyncDataTypeChanged_" class="list-item" + hidden="[[!syncPrefs.bookmarksRegistered]]" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.bookmarksEnforced)]]"> + $i18n{bookmarksCheckboxLabel} + </paper-checkbox> + <paper-checkbox checked="{{syncPrefs.extensionsSynced}}" + on-change="onSingleSyncDataTypeChanged_" class="list-item" + hidden="[[!syncPrefs.extensionsRegistered]]" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.extensionsEnforced)]]"> + $i18n{extensionsCheckboxLabel} + </paper-checkbox> + <paper-checkbox checked="{{syncPrefs.typedUrlsSynced}}" + on-change="onSingleSyncDataTypeChanged_" class="list-item" + hidden="[[!syncPrefs.typedUrlsRegistered]]" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.typedUrlsEnforced)]]"> + $i18n{historyCheckboxLabel} + </paper-checkbox> + <paper-checkbox checked="{{syncPrefs.passwordsSynced}}" + on-change="onSingleSyncDataTypeChanged_" class="list-item" + hidden="[[!syncPrefs.passwordsRegistered]]" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.passwordsEnforced)]]"> + $i18n{passwordsCheckboxLabel} + </paper-checkbox> + <paper-checkbox checked="{{syncPrefs.preferencesSynced}}" + on-change="onSingleSyncDataTypeChanged_" class="list-item" + hidden="[[!syncPrefs.preferencesRegistered]]" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.preferencesEnforced)]]"> + $i18n{settingsCheckboxLabel} + </paper-checkbox> + <paper-checkbox checked="{{syncPrefs.themesSynced}}" + on-change="onSingleSyncDataTypeChanged_" class="list-item" + hidden="[[!syncPrefs.themesRegistered]]" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.themesEnforced)]]"> + $i18n{themesAndWallpapersCheckboxLabel} + </paper-checkbox> + <paper-checkbox checked="{{syncPrefs.tabsSynced}}" + on-change="onSingleSyncDataTypeChanged_" class="list-item" + hidden="[[!syncPrefs.tabsRegistered]]" + disabled="[[shouldSyncCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.tabsEnforced)]]"> + $i18n{openTabsCheckboxLabel} + </paper-checkbox> + + <!-- The Payments integration checkbox is a special case in many ways. + It's visible only if autofill is registered. It's disabled and + unchecked if autofill is unchecked.--> + <paper-checkbox checked="{{syncPrefs.paymentsIntegrationEnabled}}" + on-change="onSingleSyncDataTypeChanged_" class="list-item" + hidden="[[!syncPrefs.autofillRegistered]]" + disabled="[[shouldPaymentsCheckboxBeDisabled_( + syncPrefs.syncAllDataTypes, syncPrefs.autofillSynced)]]"> + $i18n{enablePaymentsIntegrationCheckboxLabel} + <a href="$i18nRaw{autofillHelpURL}" target="_blank"> + $i18n{learnMore} + </a> + </paper-checkbox> + </div> + + <div class="settings-box two-line single-column" actionable + on-tap="onManageSyncedDataTap_"> + <div>$i18n{manageSyncedDataTitle}</div> + <div class="secondary">$i18n{manageSyncedDataDescription}</div> + </div> + + <div class="settings-box two-line single-column"> + <div>$i18n{encryptionOptionsTitle}</div> + <div class="secondary">$i18n{syncDataEncryptedText}</div> + </div> + + <div id="encryptionRadioGroupContainer" class="list-frame" + hidden="[[syncPrefs.passphraseRequired]]"> + <paper-radio-group + selected="[[selectedEncryptionRadio_( + syncPrefs.passphraseTypeIsCustom)]]" + on-paper-radio-group-changed="onEncryptionRadioSelectionChanged_"> + <paper-radio-button name="encrypt-with-google" + class="list-item" disabled="[[syncPrefs.encryptAllData]]"> + $i18n{encryptWithGoogleCredentialsLabel} + </paper-radio-button> + <paper-radio-button name="encrypt-with-passphrase" + class="list-item" disabled="[[syncPrefs.encryptAllData]]"> + <span> + [[encryptWithPassphraseBody_(syncPrefs.fullEncryptionBody)]] + </span> + </paper-radio-button> + </paper-radio-group> + </div> + + <template is="dom-if" if="[[creatingNewPassphrase_]]"> <div class="list-frame"> - <paper-checkbox checked="{{syncPrefs.appsSynced}}" - on-change="onSingleSyncDataTypeChanged_" class="list-item" - hidden="[[!syncPrefs.appsRegistered]]" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.appsEnforced)]]"> - $i18n{appCheckboxLabel} - </paper-checkbox> - - <!-- Autofill has a special on-change handler to deal with - Payments integriation. --> - <paper-checkbox checked="{{syncPrefs.autofillSynced}}" - on-change="onAutofillDataTypeChanged_" class="list-item" - hidden="[[!syncPrefs.autofillRegistered]]" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.autofillEnforced)]]"> - $i18n{autofillCheckboxLabel} - </paper-checkbox> - - <paper-checkbox checked="{{syncPrefs.bookmarksSynced}}" - on-change="onSingleSyncDataTypeChanged_" class="list-item" - hidden="[[!syncPrefs.bookmarksRegistered]]" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.bookmarksEnforced)]]"> - $i18n{bookmarksCheckboxLabel} - </paper-checkbox> - <paper-checkbox checked="{{syncPrefs.extensionsSynced}}" - on-change="onSingleSyncDataTypeChanged_" class="list-item" - hidden="[[!syncPrefs.extensionsRegistered]]" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.extensionsEnforced)]]"> - $i18n{extensionsCheckboxLabel} - </paper-checkbox> - <paper-checkbox checked="{{syncPrefs.typedUrlsSynced}}" - on-change="onSingleSyncDataTypeChanged_" class="list-item" - hidden="[[!syncPrefs.typedUrlsRegistered]]" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.typedUrlsEnforced)]]"> - $i18n{historyCheckboxLabel} - </paper-checkbox> - <paper-checkbox checked="{{syncPrefs.passwordsSynced}}" - on-change="onSingleSyncDataTypeChanged_" class="list-item" - hidden="[[!syncPrefs.passwordsRegistered]]" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.passwordsEnforced)]]"> - $i18n{passwordsCheckboxLabel} - </paper-checkbox> - <paper-checkbox checked="{{syncPrefs.preferencesSynced}}" - on-change="onSingleSyncDataTypeChanged_" class="list-item" - hidden="[[!syncPrefs.preferencesRegistered]]" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.preferencesEnforced)]]"> - $i18n{settingsCheckboxLabel} - </paper-checkbox> - <paper-checkbox checked="{{syncPrefs.themesSynced}}" - on-change="onSingleSyncDataTypeChanged_" class="list-item" - hidden="[[!syncPrefs.themesRegistered]]" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.themesEnforced)]]"> - $i18n{themesAndWallpapersCheckboxLabel} - </paper-checkbox> - <paper-checkbox checked="{{syncPrefs.tabsSynced}}" - on-change="onSingleSyncDataTypeChanged_" class="list-item" - hidden="[[!syncPrefs.tabsRegistered]]" - disabled="[[shouldSyncCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.tabsEnforced)]]"> - $i18n{openTabsCheckboxLabel} - </paper-checkbox> - - <!-- The Payments integration checkbox is a special case in many ways. - It's visible only if autofill is registered. It's disabled and - unchecked if autofill is unchecked.--> - <paper-checkbox checked="{{syncPrefs.paymentsIntegrationEnabled}}" - on-change="onSingleSyncDataTypeChanged_" class="list-item" - hidden="[[!syncPrefs.autofillRegistered]]" - disabled="[[shouldPaymentsCheckboxBeDisabled_( - syncPrefs.syncAllDataTypes, syncPrefs.autofillSynced)]]"> - $i18n{enablePaymentsIntegrationCheckboxLabel} - <a href="$i18nRaw{autofillHelpURL}" target="_blank"> - $i18n{learnMore} - </a> - </paper-checkbox> - </div> - - <div class="settings-box two-line single-column" actionable - on-tap="onManageSyncedDataTap_"> - <div>$i18n{manageSyncedDataTitle}</div> - <div class="secondary">$i18n{manageSyncedDataDescription}</div> - </div> - - <div class="settings-box two-line single-column"> - <div>$i18n{encryptionOptionsTitle}</div> - <div class="secondary">$i18n{syncDataEncryptedText}</div> - </div> - - <div id="encryptionRadioGroupContainer" class="list-frame" - hidden="[[syncPrefs.passphraseRequired]]"> - <paper-radio-group - selected="[[selectedEncryptionRadio_( - syncPrefs.passphraseTypeIsCustom)]]" - on-paper-radio-group-changed="onEncryptionRadioSelectionChanged_"> - <paper-radio-button name="encrypt-with-google" - class="list-item" disabled="[[syncPrefs.encryptAllData]]"> - $i18n{encryptWithGoogleCredentialsLabel} - </paper-radio-button> - <paper-radio-button name="encrypt-with-passphrase" - class="list-item" disabled="[[syncPrefs.encryptAllData]]"> - <span> - [[encryptWithPassphraseBody_(syncPrefs.fullEncryptionBody)]] - </span> - </paper-radio-button> - </paper-radio-group> - </div> - - <template is="dom-if" if="[[creatingNewPassphrase_]]"> - <div class="list-frame"> - <div id="create-password-box"> - <div>$i18n{passphraseExplanationText}</div> - <paper-input id="passphraseInput" type="password" - placeholder="$i18n{passphrasePlaceholder}" - error-message="$i18n{emptyPassphraseError}"> - </paper-input> - <paper-input id="passphraseConfirmationInput" type="password" - placeholder="$i18n{passphraseConfirmationPlaceholder}" - error-message="$i18n{mismatchedPassphraseError}"> - </paper-input> - <paper-button id="saveNewPassphrase" - on-tap="onSaveNewPassphraseTap_" class="action-button"> - $i18n{save} - </paper-button> - </div> - </div> - </template> - - <template is="dom-if" if="[[syncPrefs.passphraseRequired]]"> - <div class="list-frame"> - <div id="askCustomPassphraseMessage" - hidden$="[[!syncPrefs.passphraseTypeIsCustom]]"> - [[syncPrefs.enterPassphraseBody]] - </div> - <div id="askOldGooglePassphraseMessage" - hidden$="[[syncPrefs.passphraseTypeIsCustom]]"> - [[syncPrefs.enterGooglePassphraseBody]] - </div> - <paper-input id="existingPassphraseInput" type="password" + <div id="create-password-box"> + <div>$i18n{passphraseExplanationText}</div> + <paper-input id="passphraseInput" type="password" placeholder="$i18n{passphrasePlaceholder}" - error-message="$i18n{incorrectPassphraseError}"> + error-message="$i18n{emptyPassphraseError}"> </paper-input> - <paper-button id="submitExistingPassphrase" - on-tap="onSubmitExistingPassphraseTap_" class="action-button"> - $i18n{submitPassphraseButton} + <paper-input id="passphraseConfirmationInput" type="password" + placeholder="$i18n{passphraseConfirmationPlaceholder}" + error-message="$i18n{mismatchedPassphraseError}"> + </paper-input> + <paper-button id="saveNewPassphrase" + on-tap="onSaveNewPassphraseTap_" class="action-button"> + $i18n{save} </paper-button> </div> - </template> - </div> - </iron-pages> + </div> + </template> + + <template is="dom-if" if="[[syncPrefs.passphraseRequired]]"> + <div class="list-frame"> + <div id="askCustomPassphraseMessage" + hidden$="[[!syncPrefs.passphraseTypeIsCustom]]"> + [[syncPrefs.enterPassphraseBody]] + </div> + <div id="askOldGooglePassphraseMessage" + hidden$="[[syncPrefs.passphraseTypeIsCustom]]"> + [[syncPrefs.enterGooglePassphraseBody]] + </div> + <paper-input id="existingPassphraseInput" type="password" + placeholder="$i18n{passphrasePlaceholder}" + error-message="$i18n{incorrectPassphraseError}"> + </paper-input> + <paper-button id="submitExistingPassphrase" + on-tap="onSubmitExistingPassphraseTap_" class="action-button"> + $i18n{submitPassphraseButton} + </paper-button> + </div> + </template> + </div> </template> <script src="sync_page.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/people_page/sync_page.js b/chrome/browser/resources/settings/people_page/sync_page.js index 0ef62fb..0d9a738 100644 --- a/chrome/browser/resources/settings/people_page/sync_page.js +++ b/chrome/browser/resources/settings/people_page/sync_page.js
@@ -61,12 +61,14 @@ }, /** - * The curerntly displayed page. + * The current page status. Defaults to |CONFIGURE| such that the searching + * algorithm can search useful content when the page is not visible to the + * user. * @private {?settings.PageStatus} */ - selectedPage_: { + pageStatus_: { type: String, - value: settings.PageStatus.SPINNER, + value: settings.PageStatus.CONFIGURE, }, /** @@ -145,6 +147,15 @@ this.onNavigateAwayFromPage_(); }, + /** + * @param {!settings.PageStatus} expectedPageStatus + * @return {boolean} + * @private + */ + isStatus_: function(expectedPageStatus) { + return expectedPageStatus == this.pageStatus_; + }, + /** @private */ onNavigateToPage_: function() { // The element is not ready for C++ interaction until it is attached. @@ -155,7 +166,7 @@ return; // Display loading page until the settings have been retrieved. - this.selectedPage_ = settings.PageStatus.SPINNER; + this.pageStatus_ = settings.PageStatus.SPINNER; this.browserProxy_.didNavigateToSyncPage(); @@ -168,6 +179,10 @@ if (!this.unloadCallback_) return; + // Reset the status to CONFIGURE such that the searching algorithm can + // search useful content when the page is not visible to the user. + this.pageStatus_ = settings.PageStatus.CONFIGURE; + this.browserProxy_.didNavigateAwayFromSyncPage(); window.removeEventListener('unload', this.unloadCallback_); @@ -180,7 +195,7 @@ */ handleSyncPrefsChanged_: function(syncPrefs) { this.syncPrefs = syncPrefs; - this.selectedPage_ = settings.PageStatus.CONFIGURE; + this.pageStatus_ = settings.PageStatus.CONFIGURE; // If autofill is not registered or synced, force Payments integration off. if (!this.syncPrefs.autofillRegistered || !this.syncPrefs.autofillSynced) @@ -291,14 +306,14 @@ case settings.PageStatus.SPINNER: case settings.PageStatus.TIMEOUT: case settings.PageStatus.CONFIGURE: - this.selectedPage_ = pageStatus; + this.pageStatus_ = pageStatus; return; case settings.PageStatus.DONE: if (settings.getCurrentRoute() == settings.Route.SYNC) settings.navigateTo(settings.Route.PEOPLE); return; case settings.PageStatus.PASSPHRASE_FAILED: - if (this.selectedPage_ == this.pages.CONFIGURE && + if (this.pageStatus_ == this.pages.CONFIGURE && this.syncPrefs && this.syncPrefs.passphraseRequired) { this.$$('#existingPassphraseInput').invalid = true; }
diff --git a/chrome/browser/resources/settings/printing_page/printing_page.html b/chrome/browser/resources/settings/printing_page/printing_page.html index f54a418f..c72cc1108 100644 --- a/chrome/browser/resources/settings/printing_page/printing_page.html +++ b/chrome/browser/resources/settings/printing_page/printing_page.html
@@ -19,7 +19,7 @@ <array-selector id="arraySelector" items="{{cupsPrinters}}" selected="{{detailPrinter_}}"> </array-selector> - <neon-animatable id="main"> + <neon-animatable route-path="default"> <if expr="chromeos"> <div id="cupsPrinters" class="settings-box first" on-tap="onTapCupsPrinters_" actionable> @@ -34,7 +34,7 @@ </div> </neon-animatable> <if expr="chromeos"> - <template is="dom-if" name="cups-printers"> + <template is="dom-if" route-path="/cupsPrinters"> <settings-subpage associated-control="[[$$('#cupsPrinters')]]" page-title="$i18n{cupsPrintersTitle}"> @@ -42,14 +42,14 @@ </settings-cups-printers> </settings-subpage> </template> - <template is="dom-if" name="cups-printer-details-page" restamp no-search> + <template is="dom-if" route-path="/cupsPrinterDetails" restamp no-search> <settings-subpage page-title="$i18n{printerDetailsTitle}"> <settings-cups-printer-details-page printer="{{detailPrinter_}}"> </settings-cups-printer-details-page> </settings-subpage> </template> </if> - <template is="dom-if" name="cloud-printers"> + <template is="dom-if" route-path="/cloudPrinters"> <settings-subpage associated-control="[[$$('#cloudPrinters')]]" page-title="$i18n{cloudPrintersTitle}">
diff --git a/chrome/browser/resources/settings/privacy_page/compiled_resources2.gyp b/chrome/browser/resources/settings/privacy_page/compiled_resources2.gyp index 19a9339b..c2b4372f 100644 --- a/chrome/browser/resources/settings/privacy_page/compiled_resources2.gyp +++ b/chrome/browser/resources/settings/privacy_page/compiled_resources2.gyp
@@ -14,6 +14,7 @@ { 'target_name': 'privacy_page', 'dependencies': [ + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:web_ui_listener_behavior', '../compiled_resources2.gyp:route', '../settings_page/compiled_resources2.gyp:settings_animated_pages', '../settings_ui/compiled_resources2.gyp:settings_ui_types',
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html index c65111dd..8e88c1c 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page.html +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -1,4 +1,6 @@ +<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_vars_css.html"> <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html"> <link rel="import" href="chrome://resources/polymer/v1_0/neon-animation/neon-animatable.html"> <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html"> @@ -18,20 +20,38 @@ <if expr="use_nss_certs"> <link rel="import" href="/certificate_manager_page/certificate_manager_page.html"> </if> -<if expr="is_win or is_macosx"> <link rel="import" href="/privacy_page/privacy_page_browser_proxy.html"> -</if> <dom-module id="settings-privacy-page"> <template> - <style include="settings-shared"></style> + <style include="settings-shared"> + /* TODO(dbeam): this is similar to a 1 line checkbox. Worth somehow + * combining? */ + #metricsReporting { + align-items: center; + display: flex; + min-height: var(--settings-row-min-height); + } + + #metricsReportingCheckbox { + display: inline-block; + } + + #metricsReporting paper-tooltip { + --paper-tooltip: var(--cr-policy-tooltip); + } + + #indicator { + -webkit-margin-start: var(--checkbox-spacing); + } + </style> <template is="dom-if" if="[[showClearBrowsingDataDialog_]]" restamp> <settings-clear-browsing-data-dialog prefs="{{prefs}}" on-close="onDialogClosed_"> </settings-clear-browsing-data-dialog> </template> <settings-animated-pages id="pages" section="privacy"> - <neon-animatable id="main"> + <neon-animatable route-path="default"> <div class="settings-box block first"> <p class="privacy-explanation"> $i18nRaw{improveBrowsingExperience} @@ -63,13 +83,29 @@ label="$i18n{spellingPref}"> </settings-checkbox> <if expr="chromeos"> - <settings-checkbox + <settings-checkbox pref="{{prefs.cros.metrics.reportingEnabled}}" label="$i18n{enableLogging}"> </settings-checkbox> -</if> - <!-- TODO(jlklein): Add non-chromeos metrics box. --> -</if> +</if><!-- chromeos --> +<if expr="not chromeos"> + <div id="metricsReporting"> + <paper-checkbox id="metricsReportingCheckbox" + on-tap="onMetricsReportingCheckboxTap_" + checked="[[metricsReporting_.enabled]]" + disabled="[[metricsReporting_.managed]]"> + $i18n{enableLogging} + </paper-checkbox> + <template is="dom-if" if="[[metricsReporting_.managed]]" restamp> + <iron-icon id="indicator" tabindex=0 icon="cr:domain"></iron-icon> + <paper-tooltip for="indicator" position="top" + fit-to-visible-bounds> + $i18n{controlledSettingPolicy} + </paper-tooltip> + </template> + </div> +</if><!-- not chromeos --> +</if><!-- _google_chrome --> <settings-checkbox pref="{{prefs.enable_do_not_track}}" label="$i18n{doNotTrack}"> </settings-checkbox> @@ -98,13 +134,14 @@ <div class="secondary">$i18n{siteSettingsDescription}</div> </div> <div class="settings-box"> - <paper-button on-tap="onClearBrowsingDataTap_" class="primary-button"> + <paper-button id="clearBrowsingData" + on-tap="onClearBrowsingDataTap_" class="primary-button"> $i18n{clearBrowsingData} </paper-button> </div> </neon-animatable> <if expr="use_nss_certs"> - <template is="dom-if" name="manage-certificates"> + <template is="dom-if" route-path="/certificates"> <settings-subpage associated-control="[[$$('#manageCertificates')]]" page-title="$i18n{manageCertificates}"> @@ -113,7 +150,7 @@ </settings-subpage> </template> </if> - <template is="dom-if" name="site-settings"> + <template is="dom-if" route-path="/siteSettings"> <settings-subpage associated-control="[[$$('#site-settings-subpage-trigger')]]" id="site-settings" @@ -123,12 +160,12 @@ </settings-subpage> </template> - <template is="dom-if" name="all-sites" no-search> + <template is="dom-if" route-path="/siteSettings/all" no-search> <settings-subpage page-title="$i18n{siteSettingsCategoryAllSites}"> <all-sites selected-site="{{selectedSite}}"></all-sites> </settings-subpage> </template> - <template is="dom-if" name="site-settings-category-automatic-downloads" + <template is="dom-if" route-path="/siteSettings/automaticDownloads" no-search> no-search> <settings-subpage page-title="$i18n{siteSettingsAutomaticDownloads}"> <site-settings-category @@ -137,7 +174,7 @@ </site-settings-category> </settings-subpage> </template> - <template is="dom-if" name="site-settings-category-background-sync" + <template is="dom-if" route-path="/siteSettings/backgroundSync" no-search> no-search> <settings-subpage page-title="$i18n{siteSettingsBackgroundSync}"> <site-settings-category @@ -146,7 +183,7 @@ </site-settings-category> </settings-subpage> </template> - <template is="dom-if" name="site-settings-category-camera" no-search> + <template is="dom-if" route-path="/siteSettings/camera" no-search> <settings-subpage page-title="$i18n{siteSettingsCategoryCamera}"> <site-settings-category selected-site="{{selectedSite}}" @@ -155,7 +192,7 @@ </site-settings-category> </settings-subpage> </template> - <template is="dom-if" name="site-settings-category-cookies" no-search> + <template is="dom-if" route-path="/siteSettings/cookies" no-search> <settings-subpage page-title="$i18n{siteSettingsCategoryCookies}"> <site-settings-category selected-site="{{selectedSite}}" @@ -171,7 +208,7 @@ </site-settings-category> </settings-subpage> </template> - <template is="dom-if" name="site-settings-category-images" no-search> + <template is="dom-if" route-path="/siteSettings/images" no-search> <settings-subpage page-title="$i18n{siteSettingsCategoryImages}"> <site-settings-category selected-site="{{selectedSite}}" @@ -179,7 +216,7 @@ </site-settings-category> </settings-subpage> </template> - <template is="dom-if" name="site-settings-category-location" no-search> + <template is="dom-if" route-path="/siteSettings/location" no-search> <settings-subpage page-title="$i18n{siteSettingsCategoryLocation}"> <site-settings-category selected-site="{{selectedSite}}" @@ -192,7 +229,7 @@ <protocol-handlers></protocol-handlers> </settings-subpage> </template> - <template is="dom-if" name="site-settings-category-javascript" no-search> + <template is="dom-if" route-path="/siteSettings/javascript" no-search> <settings-subpage page-title="$i18n{siteSettingsCategoryJavascript}"> <site-settings-category selected-site="{{selectedSite}}" @@ -200,7 +237,7 @@ </site-settings-category> </settings-subpage> </template> - <template is="dom-if" name="site-settings-category-keygen" no-search> + <template is="dom-if" route-path="/siteSettings/keygen" no-search> <settings-subpage page-title="$i18n{siteSettingsKeygen}"> <site-settings-category selected-site="{{selectedSite}}" @@ -208,7 +245,7 @@ </site-settings-category> </settings-subpage> </template> - <template is="dom-if" name="site-settings-category-microphone" no-search> + <template is="dom-if" route-path="/siteSettings/microphone" no-search> <settings-subpage page-title="$i18n{siteSettingsCategoryMicrophone}"> <site-settings-category selected-site="{{selectedSite}}" @@ -217,8 +254,7 @@ </site-settings-category> </settings-subpage> </template> - <template is="dom-if" name="site-settings-category-notifications" - no-search> + <template is="dom-if" route-path="/siteSettings/notifications" no-search> <settings-subpage page-title="$i18n{siteSettingsCategoryNotifications}"> <site-settings-category selected-site="{{selectedSite}}" @@ -226,7 +262,7 @@ </site-settings-category> </settings-subpage> </template> - <template is="dom-if" name="site-settings-category-plugins" no-search> + <template is="dom-if" route-path="/siteSettings/plugins" no-search> <settings-subpage page-title="$i18n{siteSettingsPlugins}"> <site-settings-category selected-site="{{selectedSite}}" @@ -234,7 +270,7 @@ </site-settings-category> </settings-subpage> </template> - <template is="dom-if" name="site-settings-category-popups" no-search> + <template is="dom-if" route-path="/siteSettings/popups" no-search> <settings-subpage page-title="$i18n{siteSettingsCategoryPopups}"> <site-settings-category selected-site="{{selectedSite}}" @@ -242,8 +278,7 @@ </site-settings-category> </settings-subpage> </template> - <template is="dom-if" name="site-settings-category-unsandboxed-plugins" - no-search> + <template is="dom-if" route-path="/siteSettings/unsandboxedPlugins" no-search> <settings-subpage page-title="$i18n{siteSettingsUnsandboxedPlugins}"> <site-settings-category selected-site="{{selectedSite}}"
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.js b/chrome/browser/resources/settings/privacy_page/privacy_page.js index 1134a53..496fd34ba 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page.js +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.js
@@ -10,7 +10,12 @@ Polymer({ is: 'settings-privacy-page', - behaviors: [settings.RouteObserverBehavior], + behaviors: [ + settings.RouteObserverBehavior, +<if expr="_google_chrome and not chromeos"> + WebUIListenerBehavior, +</if> + ], properties: { /** @@ -21,24 +26,37 @@ notify: true, }, - /** @private */ - showClearBrowsingDataDialog_: Boolean, - /** * Dictionary defining page visibility. * @type {!PrivacyPageVisibility} */ pageVisibility: Object, + +<if expr="_google_chrome and not chromeos"> + /** @type {MetricsReporting} */ + metricsReporting_: Object, +</if> + + /** @private */ + showClearBrowsingDataDialog_: Boolean, }, ready: function() { this.ContentSettingsTypes = settings.ContentSettingsTypes; + +<if expr="_google_chrome and not chromeos"> + var boundSetMetricsReporting = this.setMetricsReporting_.bind(this); + this.addWebUIListener('metrics-reporting-change', boundSetMetricsReporting); + + var browserProxy = settings.PrivacyPageBrowserProxyImpl.getInstance(); + browserProxy.getMetricsReporting().then(boundSetMetricsReporting); +</if> }, /** @protected */ currentRouteChanged: function() { this.showClearBrowsingDataDialog_ = - settings.getCurrentRoute().dialog == 'clear-browsing-data'; + settings.getCurrentRoute() == settings.Route.CLEAR_BROWSER_DATA; }, /** @private */ @@ -66,4 +84,21 @@ onDialogClosed_: function() { settings.navigateTo(settings.Route.PRIVACY); }, + +<if expr="_google_chrome and not chromeos"> + /** @private */ + onMetricsReportingCheckboxTap_: function() { + var browserProxy = settings.PrivacyPageBrowserProxyImpl.getInstance(); + var enabled = this.$.metricsReportingCheckbox.checked; + browserProxy.setMetricsReportingEnabled(enabled); + }, + + /** + * @param {!MetricsReporting} metricsReporting + * @private + */ + setMetricsReporting_: function(metricsReporting) { + this.metricsReporting_ = metricsReporting; + }, +</if> });
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page_browser_proxy.js b/chrome/browser/resources/settings/privacy_page/privacy_page_browser_proxy.js index 98d9e507..54975912 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page_browser_proxy.js +++ b/chrome/browser/resources/settings/privacy_page/privacy_page_browser_proxy.js
@@ -4,13 +4,26 @@ /** @fileoverview Handles interprocess communcation for the privacy page. */ +/** @typedef {{enabled: boolean, managed: boolean}} */ +var MetricsReporting; + cr.define('settings', function() { /** @interface */ function PrivacyPageBrowserProxy() {} PrivacyPageBrowserProxy.prototype = { +<if expr="_google_chrome and not chromeos"> + /** @return {!Promise<!MetricsReporting>} */ + getMetricsReporting: assertNotReached, + + /** @param {boolean} enabled */ + setMetricsReportingEnabled: assertNotReached, +</if> + +<if expr="is_win or is_macosx"> /** Invokes the native certificate manager (used by win and mac). */ showManageSSLCertificates: function() {}, +</if> }; /** @@ -21,10 +34,24 @@ cr.addSingletonGetter(PrivacyPageBrowserProxyImpl); PrivacyPageBrowserProxyImpl.prototype = { +<if expr="_google_chrome and not chromeos"> + /** @override */ + getMetricsReporting: function() { + return cr.sendWithPromise('getMetricsReporting'); + }, + + /** @override */ + setMetricsReportingEnabled: function(enabled) { + chrome.send('setMetricsReportingEnabled', [enabled]); + }, +</if> + +<if expr="is_win or is_macosx"> /** @override */ showManageSSLCertificates: function() { chrome.send('showManageSSLCertificates'); }, +</if> }; return {
diff --git a/chrome/browser/resources/settings/route.js b/chrome/browser/resources/settings/route.js index 981c574e..0238bb4e 100644 --- a/chrome/browser/resources/settings/route.js +++ b/chrome/browser/resources/settings/route.js
@@ -18,7 +18,6 @@ // Below are all legacy properties to provide compatibility with the old // routing system. TODO(tommycli): Remove once routing refactor complete. this.section = ''; - /** @type {!Array<string>} */ this.subpage = []; }; Route.prototype = { @@ -26,11 +25,10 @@ * Returns a new Route instance that's a child of this route. * @param {string} path Extends this route's path if it doesn't contain a * leading slash. - * @param {string=} opt_subpageName * @return {!settings.Route} * @private */ - createChild: function(path, opt_subpageName) { + createChild: function(path) { assert(path); // |path| extends this route's path if it doesn't have a leading slash. @@ -40,24 +38,7 @@ var route = new Route(newUrl); route.parent = this; route.section = this.section; - route.subpage = this.subpage.slice(); // Shallow copy. - if (opt_subpageName) - route.subpage.push(opt_subpageName); - - return route; - }, - - /** - * Returns a new Route instance that's a child dialog of this route. - * @param {string} path - * @param {string} dialogName - * @return {!settings.Route} - * @private - */ - createDialog: function(path, dialogName) { - var route = this.createChild(path); - route.dialog = dialogName; return route; }, @@ -87,6 +68,14 @@ } return false; }, + + /** + * Returns true if this route is a subpage of a section. + * @return {boolean} + */ + isSubpage: function() { + return !!this.parent && this.parent.section == this.section; + }, }; // Abbreviated variable for easier definitions. @@ -99,159 +88,139 @@ <if expr="chromeos"> r.INTERNET = r.BASIC.createSection('/internet', 'internet'); - r.NETWORK_DETAIL = r.INTERNET.createChild('/networkDetail', 'network-detail'); - r.KNOWN_NETWORKS = r.INTERNET.createChild('/knownNetworks', 'known-networks'); + r.NETWORK_DETAIL = r.INTERNET.createChild('/networkDetail'); + r.KNOWN_NETWORKS = r.INTERNET.createChild('/knownNetworks'); </if> r.APPEARANCE = r.BASIC.createSection('/appearance', 'appearance'); - r.FONTS = r.APPEARANCE.createChild('/fonts', 'appearance-fonts'); + r.FONTS = r.APPEARANCE.createChild('/fonts'); r.DEFAULT_BROWSER = r.BASIC.createSection('/defaultBrowser', 'defaultBrowser'); r.SEARCH = r.BASIC.createSection('/search', 'search'); - r.SEARCH_ENGINES = r.SEARCH.createChild('/searchEngines', 'search-engines'); + r.SEARCH_ENGINES = r.SEARCH.createChild('/searchEngines'); r.ON_STARTUP = r.BASIC.createSection('/onStartup', 'onStartup'); r.PEOPLE = r.BASIC.createSection('/people', 'people'); - r.SYNC = r.PEOPLE.createChild('/syncSetup', 'sync'); + r.SYNC = r.PEOPLE.createChild('/syncSetup'); <if expr="not chromeos"> - r.MANAGE_PROFILE = r.PEOPLE.createChild('/manageProfile', 'manageProfile'); + r.MANAGE_PROFILE = r.PEOPLE.createChild('/manageProfile'); </if> <if expr="chromeos"> - r.CHANGE_PICTURE = r.PEOPLE.createChild('/changePicture', 'changePicture'); - r.ACCOUNTS = r.PEOPLE.createChild('/accounts', 'users'); - r.LOCK_SCREEN = r.PEOPLE.createChild('/lockScreen', 'lockScreen'); - r.SETUP_PIN = r.LOCK_SCREEN.createDialog('/setupPin', 'setupPin'); + r.CHANGE_PICTURE = r.PEOPLE.createChild('/changePicture'); + r.ACCOUNTS = r.PEOPLE.createChild('/accounts'); + r.LOCK_SCREEN = r.PEOPLE.createChild('/lockScreen'); r.DEVICE = r.BASIC.createSection('/device', 'device'); - r.POINTERS = r.DEVICE.createChild('/pointer-overlay', 'pointers'); - r.KEYBOARD = r.DEVICE.createChild('/keyboard-overlay', 'keyboard'); - r.DISPLAY = r.DEVICE.createChild('/display', 'display'); - r.NOTES = r.DEVICE.createChild('/note', 'note'); + r.POINTERS = r.DEVICE.createChild('/pointer-overlay'); + r.KEYBOARD = r.DEVICE.createChild('/keyboard-overlay'); + r.DISPLAY = r.DEVICE.createChild('/display'); + r.NOTES = r.DEVICE.createChild('/note'); </if> r.PRIVACY = r.ADVANCED.createSection('/privacy', 'privacy'); - r.CERTIFICATES = - r.PRIVACY.createChild('/certificates', 'manage-certificates'); - r.CLEAR_BROWSER_DATA = - r.PRIVACY.createDialog('/clearBrowserData', 'clear-browsing-data'); - r.SITE_SETTINGS = r.PRIVACY.createChild('/siteSettings', 'site-settings'); - r.SITE_SETTINGS_ALL = r.SITE_SETTINGS.createChild('all', 'all-sites'); - r.SITE_SETTINGS_ALL_DETAILS = - r.SITE_SETTINGS_ALL.createChild('details', 'site-details'); + r.CERTIFICATES = r.PRIVACY.createChild('/certificates'); - r.SITE_SETTINGS_HANDLERS = r.SITE_SETTINGS.createChild( - 'handlers', 'protocol-handlers'); + // CLEAR_BROWSER_DATA is the only navigable dialog route. It's the only child + // of a section that's not a subpage. Don't add any more routes like these. + // If more navigable dialogs are needed, add explicit support in Route. + r.CLEAR_BROWSER_DATA = r.PRIVACY.createChild('/clearBrowserData'); + r.CLEAR_BROWSER_DATA.isSubpage = function() { return false; }; - // TODO(tommicli): Find a way to refactor these repetitive category routes. - r.SITE_SETTINGS_AUTOMATIC_DOWNLOADS = r.SITE_SETTINGS.createChild( - 'automaticDownloads', 'site-settings-category-automatic-downloads'); - r.SITE_SETTINGS_BACKGROUND_SYNC = r.SITE_SETTINGS.createChild( - 'backgroundSync', 'site-settings-category-background-sync'); - r.SITE_SETTINGS_CAMERA = r.SITE_SETTINGS.createChild( - 'camera', 'site-settings-category-camera'); - r.SITE_SETTINGS_COOKIES = r.SITE_SETTINGS.createChild( - 'cookies', 'site-settings-category-cookies'); - r.SITE_SETTINGS_IMAGES = r.SITE_SETTINGS.createChild( - 'images', 'site-settings-category-images'); - r.SITE_SETTINGS_JAVASCRIPT = r.SITE_SETTINGS.createChild( - 'javascript', 'site-settings-category-javascript'); - r.SITE_SETTINGS_KEYGEN = r.SITE_SETTINGS.createChild( - 'keygen', 'site-settings-category-keygen'); - r.SITE_SETTINGS_LOCATION = r.SITE_SETTINGS.createChild( - 'location', 'site-settings-category-location'); - r.SITE_SETTINGS_MICROPHONE = r.SITE_SETTINGS.createChild( - 'microphone', 'site-settings-category-microphone'); - r.SITE_SETTINGS_NOTIFICATIONS = r.SITE_SETTINGS.createChild( - 'notifications', 'site-settings-category-notifications'); - r.SITE_SETTINGS_PLUGINS = r.SITE_SETTINGS.createChild( - 'plugins', 'site-settings-category-plugins'); - r.SITE_SETTINGS_POPUPS = r.SITE_SETTINGS.createChild( - 'popups', 'site-settings-category-popups'); - r.SITE_SETTINGS_UNSANDBOXED_PLUGINS = r.SITE_SETTINGS.createChild( - 'unsandboxedPlugins', 'site-settings-category-unsandboxed-plugins'); + r.SITE_SETTINGS = r.PRIVACY.createChild('/siteSettings'); + r.SITE_SETTINGS_ALL = r.SITE_SETTINGS.createChild('all'); + r.SITE_SETTINGS_ALL_DETAILS = r.SITE_SETTINGS_ALL.createChild('details'); + + r.SITE_SETTINGS_HANDLERS = r.SITE_SETTINGS.createChild('handlers'); + + // TODO(tommycli): Find a way to refactor these repetitive category routes. + r.SITE_SETTINGS_AUTOMATIC_DOWNLOADS = + r.SITE_SETTINGS.createChild('automaticDownloads'); + r.SITE_SETTINGS_BACKGROUND_SYNC = + r.SITE_SETTINGS.createChild('backgroundSync'); + r.SITE_SETTINGS_CAMERA = r.SITE_SETTINGS.createChild('camera'); + r.SITE_SETTINGS_COOKIES = r.SITE_SETTINGS.createChild('cookies'); + r.SITE_SETTINGS_IMAGES = r.SITE_SETTINGS.createChild('images'); + r.SITE_SETTINGS_JAVASCRIPT = r.SITE_SETTINGS.createChild('javascript'); + r.SITE_SETTINGS_KEYGEN = r.SITE_SETTINGS.createChild('keygen'); + r.SITE_SETTINGS_LOCATION = r.SITE_SETTINGS.createChild('location'); + r.SITE_SETTINGS_MICROPHONE = r.SITE_SETTINGS.createChild('microphone'); + r.SITE_SETTINGS_NOTIFICATIONS = r.SITE_SETTINGS.createChild('notifications'); + r.SITE_SETTINGS_PLUGINS = r.SITE_SETTINGS.createChild('plugins'); + r.SITE_SETTINGS_POPUPS = r.SITE_SETTINGS.createChild('popups'); + r.SITE_SETTINGS_UNSANDBOXED_PLUGINS = + r.SITE_SETTINGS.createChild('unsandboxedPlugins'); r.SITE_SETTINGS_AUTOMATIC_DOWNLOADS_DETAILS = - r.SITE_SETTINGS_AUTOMATIC_DOWNLOADS.createChild('details', - 'site-details'); + r.SITE_SETTINGS_AUTOMATIC_DOWNLOADS.createChild('details'); r.SITE_SETTINGS_BACKGROUND_SYNC_DETAILS = - r.SITE_SETTINGS_BACKGROUND_SYNC.createChild('details', 'site-details'); + r.SITE_SETTINGS_BACKGROUND_SYNC.createChild('details'); r.SITE_SETTINGS_CAMERA_DETAILS = - r.SITE_SETTINGS_CAMERA.createChild('details', 'site-details'); + r.SITE_SETTINGS_CAMERA.createChild('details'); r.SITE_SETTINGS_COOKIES_DETAILS = - r.SITE_SETTINGS_COOKIES.createChild('details', 'site-details'); + r.SITE_SETTINGS_COOKIES.createChild('details'); r.SITE_SETTINGS_IMAGES_DETAILS = - r.SITE_SETTINGS_IMAGES.createChild('details', 'site-details'); + r.SITE_SETTINGS_IMAGES.createChild('details'); r.SITE_SETTINGS_JAVASCRIPT_DETAILS = - r.SITE_SETTINGS_JAVASCRIPT.createChild('details', 'site-details'); + r.SITE_SETTINGS_JAVASCRIPT.createChild('details'); r.SITE_SETTINGS_KEYGEN_DETAILS = - r.SITE_SETTINGS_KEYGEN.createChild('details', 'site-details'); + r.SITE_SETTINGS_KEYGEN.createChild('details'); r.SITE_SETTINGS_LOCATION_DETAILS = - r.SITE_SETTINGS_LOCATION.createChild('details', 'site-details'); + r.SITE_SETTINGS_LOCATION.createChild('details'); r.SITE_SETTINGS_MICROPHONE_DETAILS = - r.SITE_SETTINGS_MICROPHONE.createChild('details', 'site-details'); + r.SITE_SETTINGS_MICROPHONE.createChild('details'); r.SITE_SETTINGS_NOTIFICATIONS_DETAILS = - r.SITE_SETTINGS_NOTIFICATIONS.createChild('details', 'site-details'); + r.SITE_SETTINGS_NOTIFICATIONS.createChild('details'); r.SITE_SETTINGS_PLUGINS_DETAILS = - r.SITE_SETTINGS_PLUGINS.createChild('details', 'site-details'); + r.SITE_SETTINGS_PLUGINS.createChild('details'); r.SITE_SETTINGS_POPUPS_DETAILS = - r.SITE_SETTINGS_POPUPS.createChild('details', 'site-details'); + r.SITE_SETTINGS_POPUPS.createChild('details'); r.SITE_SETTINGS_UNSANDBOXED_PLUGINS_DETAILS = - r.SITE_SETTINGS_UNSANDBOXED_PLUGINS.createChild('details', - 'site-details'); + r.SITE_SETTINGS_UNSANDBOXED_PLUGINS.createChild('details'); <if expr="chromeos"> r.DATETIME = r.ADVANCED.createSection('/dateTime', 'dateTime'); r.BLUETOOTH = r.ADVANCED.createSection('/bluetooth', 'bluetooth'); - r.BLUETOOTH_ADD_DEVICE = - r.BLUETOOTH.createChild('/bluetoothAddDevice', 'bluetooth-add-device'); - r.BLUETOOTH_PAIR_DEVICE = r.BLUETOOTH_ADD_DEVICE.createChild( - 'bluetoothPairDevice', 'bluetooth-pair-device'); + r.BLUETOOTH_ADD_DEVICE = r.BLUETOOTH.createChild('/bluetoothAddDevice'); + r.BLUETOOTH_PAIR_DEVICE = + r.BLUETOOTH_ADD_DEVICE.createChild('bluetoothPairDevice'); </if> r.PASSWORDS = r.ADVANCED.createSection('/passwords', 'passwordsAndForms'); - r.AUTOFILL = r.PASSWORDS.createChild('/autofill', 'manage-autofill'); - r.MANAGE_PASSWORDS = - r.PASSWORDS.createChild('/managePasswords', 'manage-passwords'); + r.AUTOFILL = r.PASSWORDS.createChild('/autofill'); + r.MANAGE_PASSWORDS = r.PASSWORDS.createChild('/managePasswords'); r.LANGUAGES = r.ADVANCED.createSection('/languages', 'languages'); - r.LANGUAGES_DETAIL = r.LANGUAGES.createChild('edit', 'language-detail'); - r.MANAGE_LANGUAGES = - r.LANGUAGES.createChild('/manageLanguages', 'manage-languages'); + r.LANGUAGES_DETAIL = r.LANGUAGES.createChild('edit'); + r.MANAGE_LANGUAGES = r.LANGUAGES.createChild('/manageLanguages'); <if expr="chromeos"> - r.INPUT_METHODS = - r.LANGUAGES.createChild('/inputMethods', 'manage-input-methods'); + r.INPUT_METHODS = r.LANGUAGES.createChild('/inputMethods'); </if> <if expr="not is_macosx"> - r.EDIT_DICTIONARY = - r.LANGUAGES.createChild('/editDictionary', 'edit-dictionary'); + r.EDIT_DICTIONARY = r.LANGUAGES.createChild('/editDictionary'); </if> r.DOWNLOADS = r.ADVANCED.createSection('/downloadsDirectory', 'downloads'); r.PRINTING = r.ADVANCED.createSection('/printing', 'printing'); - r.CLOUD_PRINTERS = r.PRINTING.createChild('/cloudPrinters', 'cloud-printers'); + r.CLOUD_PRINTERS = r.PRINTING.createChild('/cloudPrinters'); <if expr="chromeos"> - r.CUPS_PRINTERS = r.PRINTING.createChild('/cupsPrinters', 'cups-printers'); - r.CUPS_PRINTER_DETAIL = r.CUPS_PRINTERS.createChild( - '/cupsPrinterDetails', 'cups-printer-details-page'); + r.CUPS_PRINTERS = r.PRINTING.createChild('/cupsPrinters'); + r.CUPS_PRINTER_DETAIL = r.CUPS_PRINTERS.createChild('/cupsPrinterDetails'); </if> r.ACCESSIBILITY = r.ADVANCED.createSection('/accessibility', 'a11y'); - r.MANAGE_ACCESSIBILITY = r.ACCESSIBILITY.createChild( - '/manageAccessibility', 'manage-a11y'); + r.MANAGE_ACCESSIBILITY = r.ACCESSIBILITY.createChild('/manageAccessibility'); r.SYSTEM = r.ADVANCED.createSection('/system', 'system'); r.RESET = r.ADVANCED.createSection('/reset', 'reset'); <if expr="chromeos"> - r.INPUT_METHODS = - r.LANGUAGES.createChild('/inputMethods', 'manage-input-methods'); - r.DETAILED_BUILD_INFO = - r.ABOUT.createChild('/help/details', 'detailed-build-info'); + r.INPUT_METHODS = r.LANGUAGES.createChild('/inputMethods'); + r.DETAILED_BUILD_INFO = r.ABOUT.createChild('/help/details'); r.DETAILED_BUILD_INFO.section = 'about'; </if> @@ -346,10 +315,6 @@ */ var navigateTo = function(route, opt_dynamicParameters) { var params = opt_dynamicParameters || new URLSearchParams(); - if (assert(route) == currentRoute_ && - params.toString() == currentQueryParameters_.toString()) { - return; - } var url = route.path; if (opt_dynamicParameters) {
diff --git a/chrome/browser/resources/settings/search_page/search_page.html b/chrome/browser/resources/settings/search_page/search_page.html index c85e109..b6a175a 100644 --- a/chrome/browser/resources/settings/search_page/search_page.html +++ b/chrome/browser/resources/settings/search_page/search_page.html
@@ -15,7 +15,7 @@ <style include="settings-shared"> </style> <settings-animated-pages id="pages" section="search"> - <neon-animatable id="main"> + <neon-animatable route-path="default"> <div class="settings-box first"> <p class="start">$i18n{searchExplanation}</p> <paper-dropdown-menu vertical-align="auto" no-label-float> @@ -37,7 +37,7 @@ </paper-button> </div> </neon-animatable> - <template is="dom-if" name="search-engines"> + <template is="dom-if" route-path="/searchEngines"> <settings-subpage associated-control="[[$$('#subpage-trigger')]]" page-title="$i18n{searchEnginesManage}">
diff --git a/chrome/browser/resources/settings/settings_main/settings_main.html b/chrome/browser/resources/settings/settings_main/settings_main.html index 0eb24b26..53be671 100644 --- a/chrome/browser/resources/settings/settings_main/settings_main.html +++ b/chrome/browser/resources/settings/settings_main/settings_main.html
@@ -64,10 +64,10 @@ </template> <template is="dom-if" if="[[showAdvancedSettings_(pageVisibility.advancedSettings)]]"> - <template is="dom-if" - if="[[showAdvancedToggle_(showPages_.basic, inSubpage_)]]"> + <template is="dom-if" if="[[showAdvancedToggle_( + showPages_.basic, inSubpage_, previousShowPages_)]]"> <div id="toggleSpacer"></div> - <div id="toggleContainer" hidden$="[[showNoResultsFound_]]"> + <div id="toggleContainer"> <div id="advancedToggle" on-tap="toggleAdvancedPage_"> <span>$i18n{advancedPageTitle}</span> <iron-icon icon="[[arrowState_(showPages_.advanced)]]"></iron-icon>
diff --git a/chrome/browser/resources/settings/settings_main/settings_main.js b/chrome/browser/resources/settings/settings_main/settings_main.js index 676429b..ec56d0f 100644 --- a/chrome/browser/resources/settings/settings_main/settings_main.js +++ b/chrome/browser/resources/settings/settings_main/settings_main.js
@@ -3,6 +3,11 @@ // found in the LICENSE file. /** + * @typedef {{about: boolean, basic: boolean, advanced: boolean}} + */ +var MainPageVisibility; + +/** * @fileoverview * 'settings-main' displays the selected settings page. */ @@ -37,8 +42,7 @@ /** * Controls which main pages are displayed via dom-ifs. - * @type {!{about: boolean, basic: boolean, advanced: boolean}} - * @private + * @private {!MainPageVisibility} */ showPages_: { type: Object, @@ -47,6 +51,17 @@ }, }, + /** + * The main pages that were displayed before search was initiated. When + * |null| it indicates that currently the page is displaying its normal + * contents, instead of displaying search results. + * @private {?MainPageVisibility} + */ + previousShowPages_: { + type: Object, + value: null, + }, + /** @private */ showNoResultsFound_: { type: Boolean, @@ -112,18 +127,17 @@ }, /** - * @param {boolean} showBasicPage - * @param {boolean} inSubpage * @return {boolean} * @private */ - showAdvancedToggle_: function(showBasicPage, inSubpage) { - return showBasicPage && !inSubpage; + showAdvancedToggle_: function() { + var inSearchMode = !!this.previousShowPages_; + return this.showPages_.basic && !this.inSubpage_ && !inSearchMode; }, /** @protected */ currentRouteChanged: function(newRoute) { - this.inSubpage_ = newRoute.subpage.length > 0; + this.inSubpage_ = newRoute.isSubpage(); this.style.height = this.inSubpage_ ? '100%' : ''; if (settings.Route.ABOUT.contains(newRoute)) { @@ -162,7 +176,7 @@ */ overscrollHeight_: function() { var route = settings.getCurrentRoute(); - if (route.subpage.length != 0 || this.showPages_.about) + if (route.isSubpage() || this.showPages_.about) return 0; var query = 'settings-section[section="' + route.section + '"]'; @@ -190,7 +204,8 @@ * @private */ ensureInDefaultSearchPage_: function() { - settings.navigateTo(settings.Route.BASIC); + if (settings.getCurrentRoute() != settings.Route.BASIC) + settings.navigateTo(settings.Route.BASIC); }, /** @@ -198,6 +213,12 @@ * @return {!Promise} A promise indicating that searching finished. */ searchContents: function(query) { + if (!this.previousShowPages_) { + // Store which pages are shown before search, so that they can be restored + // after the user clears the search results. + this.previousShowPages_ = this.showPages_; + } + this.ensureInDefaultSearchPage_(); this.toolbarSpinnerActive = true; @@ -223,8 +244,15 @@ } this.toolbarSpinnerActive = false; + var showingSearchResults = !request.isSame(''); this.showNoResultsFound_ = - !request.isSame('') && !request.didFindMatches(); + showingSearchResults && !request.didFindMatches(); + + if (!showingSearchResults) { + // Restore the pages that were shown before search was initiated. + this.showPages_ = assert(this.previousShowPages_); + this.previousShowPages_ = null; + } }.bind(this)); }.bind(this), 0); }.bind(this));
diff --git a/chrome/browser/resources/settings/settings_page/main_page_behavior.js b/chrome/browser/resources/settings/settings_page/main_page_behavior.js index b1b31d65..59c66b2 100644 --- a/chrome/browser/resources/settings/settings_page/main_page_behavior.js +++ b/chrome/browser/resources/settings/settings_page/main_page_behavior.js
@@ -39,12 +39,12 @@ /** * @param {!settings.Route} newRoute - * @param {!settings.Route} oldRoute + * @param {settings.Route} oldRoute */ currentRouteChanged: function(newRoute, oldRoute) { // Allow the page to load before expanding the section. TODO(michaelpg): // Time this better when refactoring settings-animated-pages. - if (!oldRoute && newRoute.subpage.length) + if (!oldRoute && newRoute.isSubpage()) setTimeout(this.tryTransitionToSection_.bind(this)); else this.tryTransitionToSection_(); @@ -75,7 +75,7 @@ this.$$('settings-section.expanded')); if (expandedSection) { // If the section shouldn't be expanded, collapse it. - if (!currentRoute.subpage.length || expandedSection != currentSection) { + if (!currentRoute.isSubpage() || expandedSection != currentSection) { promise = this.collapseSection_(expandedSection); // Scroll to the collapsed section. TODO(michaelpg): This can look weird // because the collapse we just scheduled calculated its end target @@ -86,7 +86,7 @@ } } else if (currentSection) { // Expand the section into a subpage or scroll to it on the main page. - if (currentRoute.subpage.length) + if (currentRoute.isSubpage()) promise = this.expandSection_(currentSection); else this.scrollToSection_(); @@ -113,7 +113,7 @@ // Cancel the animation to go back to the main page if the animating // section shouldn't be expanded. if (animatingSection.section != currentRoute.section || - !currentRoute.subpage.length) { + !currentRoute.isSubpage()) { this.currentAnimation_.cancel(); } // Otherwise, let the expand animation continue. @@ -121,7 +121,7 @@ } assert(animatingSection.classList.contains('collapsing')); - if (!currentRoute.subpage.length) + if (!currentRoute.isSubpage()) return; // If the collapsing section actually matches the current route's section,
diff --git a/chrome/browser/resources/settings/settings_page/settings_animated_pages.html b/chrome/browser/resources/settings/settings_page/settings_animated_pages.html index 60ccd277..192fe21 100644 --- a/chrome/browser/resources/settings/settings_page/settings_animated_pages.html +++ b/chrome/browser/resources/settings/settings_page/settings_animated_pages.html
@@ -27,7 +27,7 @@ position: static; } </style> - <neon-animated-pages id="animatedPages" attr-for-selected="id"> + <neon-animated-pages id="animatedPages" attr-for-selected="route-path"> <content select="*"></content> </neon-animated-pages> </template>
diff --git a/chrome/browser/resources/settings/settings_page/settings_animated_pages.js b/chrome/browser/resources/settings/settings_page/settings_animated_pages.js index 5b979920..f5fcf77 100644 --- a/chrome/browser/resources/settings/settings_page/settings_animated_pages.js +++ b/chrome/browser/resources/settings/settings_page/settings_animated_pages.js
@@ -66,12 +66,12 @@ /** @protected */ currentRouteChanged: function(newRoute, oldRoute) { - if (newRoute.section == this.section && newRoute.subpage.length > 0) { + if (newRoute.section == this.section && newRoute.isSubpage()) { this.switchToSubpage_(newRoute, oldRoute); } else { this.$.animatedPages.exitAnimation = 'fade-out-animation'; this.$.animatedPages.entryAnimation = 'fade-in-animation'; - this.$.animatedPages.selected = 'main'; + this.$.animatedPages.selected = 'default'; } }, @@ -92,8 +92,7 @@ this.ensureSubpageInstance_(); if (oldRoute) { - var oldRouteIsSubpage = oldRoute.subpage.length > 0; - if (oldRouteIsSubpage && oldRoute.contains(newRoute)) { + if (oldRoute.isSubpage() && oldRoute.contains(newRoute)) { // Slide left for a descendant subpage. this.$.animatedPages.exitAnimation = 'slide-left-animation'; this.$.animatedPages.entryAnimation = 'slide-from-right-animation'; @@ -106,7 +105,7 @@ this.$.animatedPages.exitAnimation = 'fade-out-animation'; this.$.animatedPages.entryAnimation = 'fade-in-animation'; - if (!oldRouteIsSubpage) { + if (!oldRoute.isSubpage()) { // Set the height the expand animation should start at before // beginning the transition to the new subpage. // TODO(michaelpg): Remove MainPageBehavior's dependency on this @@ -119,7 +118,7 @@ } } - this.$.animatedPages.selected = newRoute.subpage.slice(-1)[0]; + this.$.animatedPages.selected = newRoute.path; }, /** @@ -127,9 +126,9 @@ * @private */ ensureSubpageInstance_: function() { - var id = settings.getCurrentRoute().subpage.slice(-1)[0]; + var routePath = settings.getCurrentRoute().path; var template = Polymer.dom(this).querySelector( - 'template[name="' + id + '"]'); + 'template[route-path="' + routePath + '"]'); // Nothing to do if the subpage isn't wrapped in a <template> or the // template is already stamped. @@ -139,8 +138,8 @@ // Set the subpage's id for use by neon-animated-pages. var subpage = /** @type {{_content: DocumentFragment}} */(template)._content .querySelector('settings-subpage'); - if (!subpage.id) - subpage.id = id; + subpage.setAttribute('route-path', routePath); + // Carry over the 'no-search' attribute from the template to the stamped // instance, such that the stamped instance will also be ignored by the // searching algorithm.
diff --git a/chrome/browser/resources/settings/settings_resources.grd b/chrome/browser/resources/settings/settings_resources.grd index 36279116..06dedb4 100644 --- a/chrome/browser/resources/settings/settings_resources.grd +++ b/chrome/browser/resources/settings/settings_resources.grd
@@ -712,14 +712,13 @@ file="privacy_page/privacy_page.js" flattenhtml="true" type="chrome_html" /> - <if expr="is_win or is_macosx"> - <structure name="IDR_SETTINGS_PRIVACY_PAGE_BROWSER_PROXY_HTML" - file="privacy_page/privacy_page_browser_proxy.html" - type="chrome_html" /> - <structure name="IDR_SETTINGS_PRIVACY_PAGE_BROWSER_PROXY_JS" - file="privacy_page/privacy_page_browser_proxy.js" - type="chrome_html" /> - </if> + <structure name="IDR_SETTINGS_PRIVACY_PAGE_BROWSER_PROXY_HTML" + file="privacy_page/privacy_page_browser_proxy.html" + type="chrome_html" /> + <structure name="IDR_SETTINGS_PRIVACY_PAGE_BROWSER_PROXY_JS" + file="privacy_page/privacy_page_browser_proxy.js" + preprocess="true" + type="chrome_html" /> <structure name="IDR_SETTINGS_PROTOCOL_HANDLERS_HTML" file="site_settings/protocol_handlers.html" type="chrome_html" />
diff --git a/chrome/browser/resources/settings/site_settings/compiled_resources2.gyp b/chrome/browser/resources/settings/site_settings/compiled_resources2.gyp index 2a45b8b..f19480d 100644 --- a/chrome/browser/resources/settings/site_settings/compiled_resources2.gyp +++ b/chrome/browser/resources/settings/site_settings/compiled_resources2.gyp
@@ -51,6 +51,14 @@ 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], }, { + 'target_name': 'protocol_handlers', + 'dependencies': [ + '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:web_ui_listener_behavior', + 'site_settings_behavior', + ], + 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], + }, + { 'target_name': 'site_data', 'dependencies': [ '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:web_ui_listener_behavior',
diff --git a/chrome/browser/resources/settings/site_settings/protocol_handlers.js b/chrome/browser/resources/settings/site_settings/protocol_handlers.js index 2f37b29..7182f9a 100644 --- a/chrome/browser/resources/settings/site_settings/protocol_handlers.js +++ b/chrome/browser/resources/settings/site_settings/protocol_handlers.js
@@ -8,6 +8,10 @@ * protocol handlers category under Site Settings. */ +/** + * All possible actions in the menu. + * @enum {string} + */ var MenuActions = { SET_DEFAULT: 'SetDefault', REMOVE: 'Remove', @@ -69,7 +73,7 @@ /** * Obtains the description for the main toggle. - * @param {number} categoryEnabled Whether the main toggle is enabled. + * @param {boolean} categoryEnabled Whether the main toggle is enabled. * @return {string} The description to use. * @private */ @@ -128,6 +132,8 @@ /** * A handler when an action is selected in the action menu. + * @param {!{model: !{item: ProtocolHandlerEntry}, + * detail: !{selected: string}}} event * @private */ onActionMenuIronActivate_: function(event) {
diff --git a/chrome/browser/resources/settings/site_settings/site_list.html b/chrome/browser/resources/settings/site_settings/site_list.html index 063a03ab..89f11f9 100644 --- a/chrome/browser/resources/settings/site_settings/site_list.html +++ b/chrome/browser/resources/settings/site_settings/site_list.html
@@ -26,14 +26,6 @@ right: 8px; } - .button-container { - -webkit-margin-start: -4px; - } - - .no-upper { - text-transform: none; - } - .selectable { -webkit-user-select: text; } @@ -66,45 +58,39 @@ <template is="dom-if" if="[[isPolicyControlled_(item.source)]]"> <iron-icon icon="cr:domain"></iron-icon> </template> - <template is="dom-if" if="[[shouldShowMenu_(item.source)]]"> - <paper-menu-button> - <paper-icon-button icon="cr:more-vert" - class="dropdown-trigger"> - </paper-icon-button> - <paper-menu id="actionMenu" class="dropdown-content" - on-iron-activate="onActionMenuIronActivate_" - attr-for-selected="menu-value"> - <paper-item - hidden="[[!showAllowAction_]]" - menu-value$="[[PermissionValues.ALLOW]]"> - $i18n{siteSettingsActionAllow} - </paper-item> - <paper-item - hidden="[[!showBlockAction_]]" - menu-value$="[[PermissionValues.BLOCK]]"> - $i18n{siteSettingsActionBlock} - </paper-item> - <paper-item - hidden="[[!showSessionOnlyAction_]]" - menu-value$="[[PermissionValues.SESSION_ONLY]]"> - $i18n{siteSettingsActionSessionOnly} - </paper-item> - <paper-item - menu-value$="[[PermissionValues.DEFAULT]]"> - $i18n{siteSettingsActionReset} - </paper-item> - </paper-menu> - </paper-menu-button> - </template> + <paper-menu-button hidden="[[!shouldShowMenu_(item.source)]]"> + <paper-icon-button icon="cr:more-vert" class="dropdown-trigger"> + </paper-icon-button> + <paper-menu id="actionMenu" class="dropdown-content" + on-iron-activate="onActionMenuIronActivate_" + attr-for-selected="menu-value"> + <paper-item + hidden="[[!showAllowAction_]]" + menu-value$="[[PermissionValues.ALLOW]]"> + $i18n{siteSettingsActionAllow} + </paper-item> + <paper-item + hidden="[[!showBlockAction_]]" + menu-value$="[[PermissionValues.BLOCK]]"> + $i18n{siteSettingsActionBlock} + </paper-item> + <paper-item + hidden="[[!showSessionOnlyAction_]]" + menu-value$="[[PermissionValues.SESSION_ONLY]]"> + $i18n{siteSettingsActionSessionOnly} + </paper-item> + <paper-item + menu-value$="[[PermissionValues.DEFAULT]]"> + $i18n{siteSettingsActionReset} + </paper-item> + </paper-menu> + </paper-menu-button> </div> </template> <template is="dom-if" if="[[!allSites]]"> - <div class="button-container"> - <paper-button on-tap="onAddSiteTap_" - class="primary-button no-upper"> - $i18n{addSiteLink} - </paper-button> + <div class="list-item list-button" on-tap="onAddSiteTap_"> + $i18n{addSiteLink} </div> </template> </div>
diff --git a/chrome/browser/resources/settings/site_settings/site_list.js b/chrome/browser/resources/settings/site_settings/site_list.js index 7650672..8b4aeb30 100644 --- a/chrome/browser/resources/settings/site_settings/site_list.js +++ b/chrome/browser/resources/settings/site_settings/site_list.js
@@ -302,8 +302,12 @@ return null; // TODO(finnur): Hmm, it would probably be better to ensure scheme on the // JS/C++ boundary. - return new URL( - this.ensureUrlHasScheme(originOrPattern.replace('[*.]', ''))); + // TODO(dschuyler): I agree. This filtering should be done in one go, rather + // that during the sort. The URL generation should be wrapped in a try/catch + // as well. + originOrPattern = originOrPattern.replace('*://', ''); + originOrPattern = originOrPattern.replace('[*.]', ''); + return new URL(this.ensureUrlHasScheme(originOrPattern)); }, /**
diff --git a/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js b/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js index c944ccdc..37fcce6 100644 --- a/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js +++ b/chrome/browser/resources/settings/site_settings/site_settings_prefs_browser_proxy.js
@@ -40,6 +40,12 @@ */ var MediaPickerEntry; +/** + * @typedef {{protocol: string, + * spec: string}} + */ + var ProtocolHandlerEntry; + cr.define('settings', function() { /** @interface */ function SiteSettingsPrefsBrowserProxy() {}
diff --git a/chrome/browser/resources/snippets_internals.html b/chrome/browser/resources/snippets_internals.html index f80dbe3..cb2f2f0 100644 --- a/chrome/browser/resources/snippets_internals.html +++ b/chrome/browser/resources/snippets_internals.html
@@ -25,8 +25,14 @@ <td class="name">Snippets enabled <td id="flag-snippets" class="value"> <tr> - <td class="name">Offline Page Suggestions enabled - <td id="flag-offline-page-suggestions" class="value"> + <td class="name">Recent Tab Suggestions enabled + <td id="flag-recent-offline-tab-suggestions" class="value"> + <tr> + <td class="name">Download Suggestions enabled + <td id="flag-download-suggestions" class="value"> + <tr> + <td class="name">Bookmark Suggestions enabled + <td id="flag-bookmark-suggestions" class="value"> <tr> <td class="name">Snippets restricted to hosts <td id="switch-restrict-to-hosts" class="value">
diff --git a/chrome/browser/resources/uber/uber_shared.css b/chrome/browser/resources/uber/uber_shared.css index d4c6bdff..a53533c 100644 --- a/chrome/browser/resources/uber/uber_shared.css +++ b/chrome/browser/resources/uber/uber_shared.css
@@ -38,8 +38,7 @@ * 600px max-width + 18px -webkit-padding-start + 20px -webkit-margin-end * so we mirror this value here so the headers match width and horizontal * alignment when scrolling sideways. - * other-devices.css' .device width depends on this, please keep in sync. - */ + * other-devices.css' .device width depends on this, please keep in sync. */ max-width: 738px; min-width: 600px; position: fixed;
diff --git a/chrome/browser/resources/user_manager/control_bar.css b/chrome/browser/resources/user_manager/control_bar.css index 7763287..13dfbea 100644 --- a/chrome/browser/resources/user_manager/control_bar.css +++ b/chrome/browser/resources/user_manager/control_bar.css
@@ -1,11 +1,9 @@ /* 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. */ /* Overrides of styles in chrome/browser/resources/chromeos/login/header_bar.js -* that are needed by the desktop user chooser screen -*/ + * that are needed by the desktop user chooser screen. */ #login-header-bar { background-color: white; border-top: 1px solid #e2e2e2;
diff --git a/chrome/browser/resources/user_manager/user_manager.css b/chrome/browser/resources/user_manager/user_manager.css index 70e27dd1..a9d911c8 100644 --- a/chrome/browser/resources/user_manager/user_manager.css +++ b/chrome/browser/resources/user_manager/user_manager.css
@@ -1,7 +1,6 @@ /* 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. */ /* Overrides for the desktop user manager screen. */
diff --git a/chrome/browser/resources/user_manager/user_manager_tutorial.css b/chrome/browser/resources/user_manager/user_manager_tutorial.css index eb0e9ced..13a1c84 100644 --- a/chrome/browser/resources/user_manager/user_manager_tutorial.css +++ b/chrome/browser/resources/user_manager/user_manager_tutorial.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ .tutorial-slide { -webkit-transition: opacity 200ms ease-in-out;
diff --git a/chrome/browser/safe_browsing/client_side_detection_service.cc b/chrome/browser/safe_browsing/client_side_detection_service.cc index 8360aad5..e3b6803f 100644 --- a/chrome/browser/safe_browsing/client_side_detection_service.cc +++ b/chrome/browser/safe_browsing/client_side_detection_service.cc
@@ -108,11 +108,11 @@ ClientSideDetectionService::~ClientSideDetectionService() { weak_factory_.InvalidateWeakPtrs(); - STLDeleteContainerPairPointers(client_phishing_reports_.begin(), - client_phishing_reports_.end()); + base::STLDeleteContainerPairPointers(client_phishing_reports_.begin(), + client_phishing_reports_.end()); client_phishing_reports_.clear(); - STLDeleteContainerPairPointers(client_malware_reports_.begin(), - client_malware_reports_.end()); + base::STLDeleteContainerPairPointers(client_malware_reports_.begin(), + client_malware_reports_.end()); client_malware_reports_.clear(); } @@ -149,8 +149,8 @@ if (!info->callback.is_null()) info->callback.Run(info->phishing_url, false); } - STLDeleteContainerPairPointers(client_phishing_reports_.begin(), - client_phishing_reports_.end()); + base::STLDeleteContainerPairPointers(client_phishing_reports_.begin(), + client_phishing_reports_.end()); client_phishing_reports_.clear(); for (std::map<const net::URLFetcher*, ClientMalwareReportInfo*>::iterator it = client_malware_reports_.begin(); @@ -159,8 +159,8 @@ if (!info->callback.is_null()) info->callback.Run(info->original_url, info->original_url, false); } - STLDeleteContainerPairPointers(client_malware_reports_.begin(), - client_malware_reports_.end()); + base::STLDeleteContainerPairPointers(client_malware_reports_.begin(), + client_malware_reports_.end()); client_malware_reports_.clear(); cache_.clear(); }
diff --git a/chrome/browser/safe_browsing/incident_reporting/extension_data_collection.cc b/chrome/browser/safe_browsing/incident_reporting/extension_data_collection.cc index 0d2ce1c..6287629 100644 --- a/chrome/browser/safe_browsing/incident_reporting/extension_data_collection.cc +++ b/chrome/browser/safe_browsing/incident_reporting/extension_data_collection.cc
@@ -76,10 +76,11 @@ std::unique_ptr<extensions::InstallSignature> signature_from_prefs = extensions::InstallSignature::FromValue(*signature); if (signature_from_prefs) { - if (ContainsKey(signature_from_prefs->ids, extension_id)) { + if (base::ContainsKey(signature_from_prefs->ids, extension_id)) { extension_info->set_has_signature_validation(true); extension_info->set_signature_is_valid(true); - } else if (ContainsKey(signature_from_prefs->invalid_ids, extension_id)) { + } else if (base::ContainsKey(signature_from_prefs->invalid_ids, + extension_id)) { extension_info->set_has_signature_validation(true); extension_info->set_signature_is_valid(false); }
diff --git a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc index 2de8eb7..cf0b0226 100644 --- a/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc +++ b/chrome/browser/safe_browsing/incident_reporting/incident_reporting_service.cc
@@ -393,7 +393,7 @@ CancelDownloadCollection(); CancelAllReportUploads(); - STLDeleteValues(&profiles_); + base::STLDeleteValues(&profiles_); } std::unique_ptr<IncidentReceiver>
diff --git a/chrome/browser/safe_browsing/local_database_manager.cc b/chrome/browser/safe_browsing/local_database_manager.cc index 9f48be6..1543cd3 100644 --- a/chrome/browser/safe_browsing/local_database_manager.cc +++ b/chrome/browser/safe_browsing/local_database_manager.cc
@@ -773,7 +773,7 @@ if (check->client) check->OnSafeBrowsingResult(); } - STLDeleteElements(&checks_); + base::STLDeleteElements(&checks_); gethash_requests_.clear(); }
diff --git a/chrome/browser/safe_browsing/ping_manager.cc b/chrome/browser/safe_browsing/ping_manager.cc index 01824639..f4afeb6 100644 --- a/chrome/browser/safe_browsing/ping_manager.cc +++ b/chrome/browser/safe_browsing/ping_manager.cc
@@ -75,8 +75,8 @@ SafeBrowsingPingManager::~SafeBrowsingPingManager() { // Delete in-progress safebrowsing reports (hits and details). - STLDeleteContainerPointers(safebrowsing_reports_.begin(), - safebrowsing_reports_.end()); + base::STLDeleteContainerPointers(safebrowsing_reports_.begin(), + safebrowsing_reports_.end()); } // net::URLFetcherDelegate implementation ----------------------------------
diff --git a/chrome/browser/safe_browsing/protocol_manager.cc b/chrome/browser/safe_browsing/protocol_manager.cc index 5ba83b1..e8c600d0 100644 --- a/chrome/browser/safe_browsing/protocol_manager.cc +++ b/chrome/browser/safe_browsing/protocol_manager.cc
@@ -193,8 +193,8 @@ SafeBrowsingProtocolManager::~SafeBrowsingProtocolManager() { // Delete in-progress SafeBrowsing requests. - STLDeleteContainerPairFirstPointers(hash_requests_.begin(), - hash_requests_.end()); + base::STLDeleteContainerPairFirstPointers(hash_requests_.begin(), + hash_requests_.end()); hash_requests_.clear(); }
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc index 19158a2a7..4083537 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -334,7 +334,7 @@ void SafeBrowsingService::ShutDown() { // Deletes the PrefChangeRegistrars, whose dtors also unregister |this| as an // observer of the preferences. - STLDeleteValues(&prefs_map_); + base::STLDeleteValues(&prefs_map_); // Remove Profile creation/destruction observers. prefs_registrar_.RemoveAll();
diff --git a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc index 8662a6d6..2a8783475 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service_browsertest.cc
@@ -297,8 +297,8 @@ continue; std::vector<int> list_ids_for_url = badurls_it->second.list_ids; - if (ContainsValue(list_ids_for_url, list_id0) || - ContainsValue(list_ids_for_url, list_id1)) { + if (base::ContainsValue(list_ids_for_url, list_id0) || + base::ContainsValue(list_ids_for_url, list_id1)) { prefix_hits->insert(prefix_hits->end(), badurls_it->second.prefix_hits.begin(), badurls_it->second.prefix_hits.end());
diff --git a/chrome/browser/search/instant_unittest_base.cc b/chrome/browser/search/instant_unittest_base.cc index bd65fb9..17cd80d 100644 --- a/chrome/browser/search/instant_unittest_base.cc +++ b/chrome/browser/search/instant_unittest_base.cc
@@ -33,8 +33,14 @@ } void InstantUnitTestBase::SetUp() { - search::EnableQueryExtractionForTesting(); - SetUpHelper(); + BrowserWithTestWindowTest::SetUp(); + + template_url_service_ = TemplateURLServiceFactory::GetForProfile(profile()); + search_test_utils::WaitForTemplateURLServiceToLoad(template_url_service_); + + UIThreadSearchTermsData::SetGoogleBaseURL("https://www.google.com/"); + SetUserSelectedDefaultSearchProvider("{google:baseURL}"); + instant_service_ = InstantServiceFactory::GetForProfile(profile()); } void InstantUnitTestBase::TearDown() { @@ -42,12 +48,6 @@ BrowserWithTestWindowTest::TearDown(); } -#if !defined(OS_ANDROID) -void InstantUnitTestBase::SetUpWithoutQueryExtraction() { - SetUpHelper(); -} -#endif - void InstantUnitTestBase::SetUserSelectedDefaultSearchProvider( const std::string& base_url) { TemplateURLData data; @@ -88,14 +88,3 @@ profile, &TemplateURLServiceFactory::BuildInstanceFor); return profile; } - -void InstantUnitTestBase::SetUpHelper() { - BrowserWithTestWindowTest::SetUp(); - - template_url_service_ = TemplateURLServiceFactory::GetForProfile(profile()); - search_test_utils::WaitForTemplateURLServiceToLoad(template_url_service_); - - UIThreadSearchTermsData::SetGoogleBaseURL("https://www.google.com/"); - SetUserSelectedDefaultSearchProvider("{google:baseURL}"); - instant_service_ = InstantServiceFactory::GetForProfile(profile()); -}
diff --git a/chrome/browser/search/instant_unittest_base.h b/chrome/browser/search/instant_unittest_base.h index e6bebf5..e489fe0 100644 --- a/chrome/browser/search/instant_unittest_base.h +++ b/chrome/browser/search/instant_unittest_base.h
@@ -26,11 +26,6 @@ void SetUp() override; void TearDown() override; -#if !defined(OS_ANDROID) - // Query extraction is always enabled on Android and iOS. - void SetUpWithoutQueryExtraction(); -#endif - // Adds and sets the default search provider using the base_url. // The base_url should have the http[s]:// prefix and a trailing / after the // TLD. @@ -52,8 +47,6 @@ private: // BrowserWithTestWindowTest override: TestingProfile* CreateProfile() override; - - void SetUpHelper(); }; #endif // CHROME_BROWSER_SEARCH_INSTANT_UNITTEST_BASE_H_
diff --git a/chrome/browser/search/search.cc b/chrome/browser/search/search.cc index aeb5e1a7..63815c45 100644 --- a/chrome/browser/search/search.cc +++ b/chrome/browser/search/search.cc
@@ -154,18 +154,6 @@ return GURL(ref.ReplaceSearchTerms(search_terms_args, search_terms_data)); } -bool MatchesAnySearchURL(const GURL& url, - TemplateURL* template_url, - const SearchTermsData& search_terms_data) { - for (const TemplateURLRef& ref : template_url->url_refs()) { - GURL search_url = - TemplateURLRefToGURL(ref, search_terms_data, false, false); - if (search_url.is_valid() && MatchesOriginAndPath(url, search_url)) - return true; - } - return false; -} - // Returns true if |url| can be used as an Instant URL for |profile|. bool IsInstantURL(const GURL& url, Profile* profile) { if (!IsInstantExtendedAPIEnabled()) @@ -192,41 +180,13 @@ if (!instant_url.is_valid()) return false; - if (MatchesOriginAndPath(url, instant_url)) - return true; - - return IsQueryExtractionEnabled() && - MatchesAnySearchURL(url, template_url, search_terms_data); + return MatchesOriginAndPath(url, instant_url); } base::string16 GetSearchTermsImpl(const content::WebContents* contents, const content::NavigationEntry* entry) { - if (!contents || !IsQueryExtractionEnabled()) - return base::string16(); - - // For security reasons, don't extract search terms if the page is not being - // rendered in the privileged Instant renderer process. This is to protect - // against a malicious page somehow scripting the search results page and - // faking search terms in the URL. Random pages can't get into the Instant - // renderer and scripting doesn't work cross-process, so if the page is in - // the Instant process, we know it isn't being exploited. - Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext()); - if (IsInstantExtendedAPIEnabled() && - !IsRenderedInInstantProcess(contents, profile) && - ((entry == contents->GetController().GetLastCommittedEntry()) || - !ShouldAssignURLToInstantRenderer(entry->GetURL(), profile))) - return base::string16(); - - // Check to see if search terms have already been extracted. - base::string16 search_terms = GetSearchTermsFromNavigationEntry(entry); - if (!search_terms.empty()) - return search_terms; - - if (!IsQueryExtractionAllowedForURL(profile, entry->GetVirtualURL())) - return base::string16(); - - // Otherwise, extract from the URL. - return ExtractSearchTermsFromURL(profile, entry->GetVirtualURL()); + // TODO(treib): Remove this and update callers accordingly. crbug.com/627747 + return base::string16(); } bool IsURLAllowedForSupervisedUser(const GURL& url, Profile* profile) {
diff --git a/chrome/browser/search/search.h b/chrome/browser/search/search.h index bd8a27549..b32da50 100644 --- a/chrome/browser/search/search.h +++ b/chrome/browser/search/search.h
@@ -39,10 +39,9 @@ // Returns whether the suggest is enabled for the given |profile|. bool IsSuggestPrefEnabled(Profile* profile); -// Extracts and returns search terms from |url|. Does not consider -// IsQueryExtractionEnabled() and Instant support state of the page and does -// not check for a privileged process, so most callers should use -// GetSearchTerms() below instead. +// Extracts and returns search terms from |url|. Does not consider Instant +// support state of the page and does not check for a privileged process, so +// most callers should use GetSearchTerms() below instead. base::string16 ExtractSearchTermsFromURL(Profile* profile, const GURL& url); // Returns true if it is okay to extract search terms from |url|. |url| must @@ -51,9 +50,8 @@ bool IsQueryExtractionAllowedForURL(Profile* profile, const GURL& url); // Returns the search terms attached to a specific NavigationEntry, or empty -// string otherwise. Does not consider IsQueryExtractionEnabled() and does not -// check Instant support, so most callers should use GetSearchTerms() below -// instead. +// string otherwise. Does not check Instant support, so most callers should use +// GetSearchTerms() below instead. base::string16 GetSearchTermsFromNavigationEntry( const content::NavigationEntry* entry);
diff --git a/chrome/browser/search/search_unittest.cc b/chrome/browser/search/search_unittest.cc index 0085720..3df1685b 100644 --- a/chrome/browser/search/search_unittest.cc +++ b/chrome/browser/search/search_unittest.cc
@@ -121,15 +121,13 @@ }; TEST_F(SearchTest, ShouldAssignURLToInstantRendererExtendedEnabled) { - EnableQueryExtractionForTesting(); - const SearchTestCase kTestCases[] = { {chrome::kChromeSearchLocalNtpUrl, true, ""}, {"https://foo.com/instant?strk", true, ""}, {"https://foo.com/instant#strk", true, ""}, {"https://foo.com/instant?strk=0", true, ""}, - {"https://foo.com/url?strk", true, ""}, - {"https://foo.com/alt?strk", true, ""}, + {"https://foo.com/url?strk", false, ""}, + {"https://foo.com/alt?strk", false, ""}, {"http://foo.com/instant", false, "Non-HTTPS"}, {"http://foo.com/instant?strk", false, "Non-HTTPS"}, {"http://foo.com/instant?strk=1", false, "Non-HTTPS"}, @@ -172,8 +170,6 @@ } TEST_F(SearchTest, ShouldUseProcessPerSiteForInstantURL) { - EnableQueryExtractionForTesting(); - const SearchTestCase kTestCases[] = { {"chrome-search://local-ntp", true, "Local NTP"}, {"chrome-search://remote-ntp", true, "Remote NTP"}, @@ -216,30 +212,28 @@ } kProcessIsolationTestCases[] = { {"Local NTP -> SRP", "chrome-search://local-ntp", true, - "https://foo.com/url?strk", true, false }, + "https://foo.com/url?strk", false, false }, {"Local NTP -> Regular", "chrome-search://local-ntp", true, "https://foo.com/other", false, false }, {"Remote NTP -> SRP", "https://foo.com/newtab?strk", true, - "https://foo.com/url?strk", true, false }, + "https://foo.com/url?strk", false, false }, {"Remote NTP -> Regular", "https://foo.com/newtab?strk", true, "https://foo.com/other", false, false }, {"SRP -> SRP", - "https://foo.com/url?strk", true, - "https://foo.com/url?strk", true, true }, + "https://foo.com/url?strk", false, + "https://foo.com/url?strk", false, true }, {"SRP -> Regular", - "https://foo.com/url?strk", true, - "https://foo.com/other", false, false }, + "https://foo.com/url?strk", false, + "https://foo.com/other", false, true }, {"Regular -> SRP", "https://foo.com/other", false, - "https://foo.com/url?strk", true, false }, + "https://foo.com/url?strk", false, true }, }; TEST_F(SearchTest, ProcessIsolation) { - EnableQueryExtractionForTesting(); - for (size_t i = 0; i < arraysize(kProcessIsolationTestCases); ++i) { const ProcessIsolationTestCase& test = kProcessIsolationTestCases[i]; AddTab(browser(), GURL("chrome://blank")); @@ -277,8 +271,6 @@ } TEST_F(SearchTest, ProcessIsolation_RendererInitiated) { - EnableQueryExtractionForTesting(); - for (size_t i = 0; i < arraysize(kProcessIsolationTestCases); ++i) { const ProcessIsolationTestCase& test = kProcessIsolationTestCases[i]; AddTab(browser(), GURL("chrome://blank")); @@ -344,7 +336,6 @@ }; TEST_F(SearchTest, InstantNTPExtendedEnabled) { - EnableQueryExtractionForTesting(); AddTab(browser(), GURL("chrome://blank")); for (size_t i = 0; i < arraysize(kInstantNTPTestCases); ++i) { const SearchTestCase& test = kInstantNTPTestCases[i]; @@ -357,7 +348,6 @@ } TEST_F(SearchTest, InstantNTPCustomNavigationEntry) { - EnableQueryExtractionForTesting(); AddTab(browser(), GURL("chrome://blank")); for (size_t i = 0; i < arraysize(kInstantNTPTestCases); ++i) { const SearchTestCase& test = kInstantNTPTestCases[i]; @@ -585,7 +575,6 @@ EXPECT_FALSE(IsNTPURL(invalid_url, profile())); // No margin. - EnableQueryExtractionForTesting(); profile()->GetPrefs()->SetBoolean(prefs::kSearchSuggestEnabled, true); GURL remote_ntp_url(GetInstantURL(profile(), false)); GURL search_url_with_search_terms("https://foo.com/url?strk&bar=abc"); @@ -595,7 +584,7 @@ EXPECT_TRUE(IsNTPURL(local_ntp_url, profile())); EXPECT_TRUE(IsNTPURL(remote_ntp_url, profile())); EXPECT_FALSE(IsNTPURL(search_url_with_search_terms, profile())); - EXPECT_TRUE(IsNTPURL(search_url_without_search_terms, profile())); + EXPECT_FALSE(IsNTPURL(search_url_without_search_terms, profile())); EXPECT_FALSE(IsNTPURL(ntp_url, NULL)); EXPECT_FALSE(IsNTPURL(local_ntp_url, NULL)); @@ -719,22 +708,8 @@ TemplateURL* template_url_; }; -TEST_F(SearchURLTest, QueryExtractionEnabled) { - UIThreadSearchTermsData::SetGoogleBaseURL("http://www.google.com/"); - EnableQueryExtractionForTesting(); - EXPECT_TRUE(IsQueryExtractionEnabled()); - TemplateURLRef::SearchTermsArgs search_terms_args(base::ASCIIToUTF16("foo")); - GURL result(template_url_->url_ref().ReplaceSearchTerms( - search_terms_args, UIThreadSearchTermsData(profile()))); - ASSERT_TRUE(result.is_valid()); - // Query extraction is enabled. Make sure - // {google:instantExtendedEnabledParameter} is set in the search URL. - EXPECT_EQ("http://www.google.com/search?espv=2&q=foo", result.spec()); -} - TEST_F(SearchURLTest, QueryExtractionDisabled) { UIThreadSearchTermsData::SetGoogleBaseURL("http://www.google.com/"); - EXPECT_FALSE(IsQueryExtractionEnabled()); TemplateURLRef::SearchTermsArgs search_terms_args(base::ASCIIToUTF16("foo")); GURL result(template_url_->url_ref().ReplaceSearchTerms( search_terms_args, UIThreadSearchTermsData(profile())));
diff --git a/chrome/browser/sessions/session_restore.cc b/chrome/browser/sessions/session_restore.cc index 2b8c35d..1bc94036 100644 --- a/chrome/browser/sessions/session_restore.cc +++ b/chrome/browser/sessions/session_restore.cc
@@ -245,7 +245,7 @@ } ~SessionRestoreImpl() override { - STLDeleteElements(&windows_); + base::STLDeleteElements(&windows_); active_session_restorers->erase(this); if (active_session_restorers->empty()) {
diff --git a/chrome/browser/sessions/session_restore_stats_collector.cc b/chrome/browser/sessions/session_restore_stats_collector.cc index 0231062..f2ced1b 100644 --- a/chrome/browser/sessions/session_restore_stats_collector.cc +++ b/chrome/browser/sessions/session_restore_stats_collector.cc
@@ -285,7 +285,7 @@ if (tab_state.loading_state == TAB_IS_LOADED) loaded_tabs.push_back(tab_state.controller); } - for (auto& tab : loaded_tabs) + for (auto* tab : loaded_tabs) RemoveTab(tab); } break; @@ -373,7 +373,7 @@ SessionRestoreStatsCollector::TabState* SessionRestoreStatsCollector::GetTabState(RenderWidgetHost* tab) { for (auto& pair : tabs_tracked_) { - auto rwh = GetRenderWidgetHost(pair.first); + auto* rwh = GetRenderWidgetHost(pair.first); if (rwh == tab) return &pair.second; }
diff --git a/chrome/browser/shell_integration_linux_unittest.cc b/chrome/browser/shell_integration_linux_unittest.cc index abff7f5..b66e1100 100644 --- a/chrome/browser/shell_integration_linux_unittest.cc +++ b/chrome/browser/shell_integration_linux_unittest.cc
@@ -46,7 +46,7 @@ } bool GetVar(base::StringPiece variable_name, std::string* result) override { - if (ContainsKey(variables_, variable_name.as_string())) { + if (base::ContainsKey(variables_, variable_name.as_string())) { *result = variables_[variable_name.as_string()]; return true; }
diff --git a/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc b/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc index 4dab194..24438445 100644 --- a/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc +++ b/chrome/browser/signin/easy_unlock_service_signin_chromeos.cc
@@ -284,7 +284,8 @@ weak_ptr_factory_.InvalidateWeakPtrs(); proximity_auth::ScreenlockBridge::Get()->RemoveObserver(this); chromeos::LoginState::Get()->RemoveObserver(this); - STLDeleteContainerPairSecondPointers(user_data_.begin(), user_data_.end()); + base::STLDeleteContainerPairSecondPointers(user_data_.begin(), + user_data_.end()); user_data_.clear(); }
diff --git a/chrome/browser/signin/oauth2_token_service_delegate_android.cc b/chrome/browser/signin/oauth2_token_service_delegate_android.cc index 39638d96..e88f5222 100644 --- a/chrome/browser/signin/oauth2_token_service_delegate_android.cc +++ b/chrome/browser/signin/oauth2_token_service_delegate_android.cc
@@ -364,7 +364,7 @@ std::vector<AccountInfo> accounts_info = account_tracker_service_->GetAccounts(); for (const AccountInfo& info : accounts_info) { - if (!ContainsValue(curr_ids, info.account_id)) + if (!base::ContainsValue(curr_ids, info.account_id)) account_tracker_service_->RemoveAccount(info.account_id); } @@ -383,13 +383,13 @@ std::vector<std::string>* refreshed_ids, std::vector<std::string>* revoked_ids, bool force_notifications) { - bool currently_signed_in = ContainsValue(curr_ids, signed_in_id); + bool currently_signed_in = base::ContainsValue(curr_ids, signed_in_id); if (currently_signed_in) { // Revoke token for ids that have been removed from the device. for (const std::string& prev_id : prev_ids) { if (prev_id == signed_in_id) continue; - if (!ContainsValue(curr_ids, prev_id)) { + if (!base::ContainsValue(curr_ids, prev_id)) { DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ValidateAccounts:" << "revoked=" << prev_id; revoked_ids->push_back(prev_id); @@ -397,8 +397,7 @@ } // Refresh token for new ids or all ids if |force_notifications|. - if (force_notifications || - !ContainsValue(prev_ids, signed_in_id)) { + if (force_notifications || !base::ContainsValue(prev_ids, signed_in_id)) { // Always fire the primary signed in account first. DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ValidateAccounts:" << "refreshed=" << signed_in_id; @@ -407,15 +406,14 @@ for (const std::string& curr_id : curr_ids) { if (curr_id == signed_in_id) continue; - if (force_notifications || - !ContainsValue(prev_ids, curr_id)) { + if (force_notifications || !base::ContainsValue(prev_ids, curr_id)) { DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ValidateAccounts:" << "refreshed=" << curr_id; refreshed_ids->push_back(curr_id); } } } else { - if (ContainsValue(prev_ids, signed_in_id)) { + if (base::ContainsValue(prev_ids, signed_in_id)) { DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ValidateAccounts:" << "revoked=" << signed_in_id; revoked_ids->push_back(signed_in_id);
diff --git a/chrome/browser/site_per_process_interactive_browsertest.cc b/chrome/browser/site_per_process_interactive_browsertest.cc index 9c105d7..3cbea83b 100644 --- a/chrome/browser/site_per_process_interactive_browsertest.cc +++ b/chrome/browser/site_per_process_interactive_browsertest.cc
@@ -368,7 +368,7 @@ std::vector<std::string> response_params = base::SplitString( response, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); if (response_params[0] == "fullscreenchange") { - EXPECT_TRUE(ContainsKey(remaining_events, response_params[1])); + EXPECT_TRUE(base::ContainsKey(remaining_events, response_params[1])); remaining_events.erase(response_params[1]); } else if (response_params[0] == "resize") { resize_validated = true;
diff --git a/chrome/browser/spellchecker/spelling_service_client.cc b/chrome/browser/spellchecker/spelling_service_client.cc index ea3671d..be81257 100644 --- a/chrome/browser/spellchecker/spelling_service_client.cc +++ b/chrome/browser/spellchecker/spelling_service_client.cc
@@ -50,8 +50,8 @@ } SpellingServiceClient::~SpellingServiceClient() { - STLDeleteContainerPairPointers(spellcheck_fetchers_.begin(), - spellcheck_fetchers_.end()); + base::STLDeleteContainerPairPointers(spellcheck_fetchers_.begin(), + spellcheck_fetchers_.end()); } bool SpellingServiceClient::RequestTextCheck(
diff --git a/chrome/browser/ssl/chrome_security_state_model_client.cc b/chrome/browser/ssl/chrome_security_state_model_client.cc index 0988c8ac..bc917b7 100644 --- a/chrome/browser/ssl/chrome_security_state_model_client.cc +++ b/chrome/browser/ssl/chrome_security_state_model_client.cc
@@ -133,14 +133,14 @@ security_style_explanations->ran_insecure_content = security_info.mixed_content_status == - SecurityStateModel::RAN_MIXED_CONTENT || + SecurityStateModel::CONTENT_STATUS_RAN || security_info.mixed_content_status == - SecurityStateModel::RAN_AND_DISPLAYED_MIXED_CONTENT; + SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN; security_style_explanations->displayed_insecure_content = security_info.mixed_content_status == - SecurityStateModel::DISPLAYED_MIXED_CONTENT || + SecurityStateModel::CONTENT_STATUS_DISPLAYED || security_info.mixed_content_status == - SecurityStateModel::RAN_AND_DISPLAYED_MIXED_CONTENT; + SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN; if (net::IsCertStatusError(security_info.cert_status)) { base::string16 error_string = base::UTF8ToUTF16(net::ErrorToString( @@ -246,10 +246,12 @@ ssl.sct_statuses.begin(), ssl.sct_statuses.end()); state->displayed_mixed_content = - (ssl.content_status & content::SSLStatus::DISPLAYED_INSECURE_CONTENT) - ? true - : false; + !!(ssl.content_status & content::SSLStatus::DISPLAYED_INSECURE_CONTENT); state->ran_mixed_content = - (ssl.content_status & content::SSLStatus::RAN_INSECURE_CONTENT) ? true - : false; + !!(ssl.content_status & content::SSLStatus::RAN_INSECURE_CONTENT); + state->displayed_content_with_cert_errors = + !!(ssl.content_status & + content::SSLStatus::DISPLAYED_CONTENT_WITH_CERT_ERRORS); + state->ran_content_with_cert_errors = + !!(ssl.content_status & content::SSLStatus::RAN_CONTENT_WITH_CERT_ERRORS); }
diff --git a/chrome/browser/ssl/chrome_security_state_model_client_browser_tests.cc b/chrome/browser/ssl/chrome_security_state_model_client_browser_tests.cc index 6d55b8c..3cd98ca 100644 --- a/chrome/browser/ssl/chrome_security_state_model_client_browser_tests.cc +++ b/chrome/browser/ssl/chrome_security_state_model_client_browser_tests.cc
@@ -169,7 +169,7 @@ content::WebContents* contents, SecurityStateModel::SecurityLevel expect_security_level, SecurityStateModel::SHA1DeprecationStatus expect_sha1_status, - SecurityStateModel::MixedContentStatus expect_mixed_content_status, + SecurityStateModel::ContentStatus expect_mixed_content_status, bool pkp_bypassed, bool expect_cert_error) { ASSERT_TRUE(contents); @@ -205,7 +205,7 @@ EXPECT_EQ(SecurityStateModel::NONE, security_info.security_level); EXPECT_EQ(SecurityStateModel::NO_DEPRECATED_SHA1, security_info.sha1_deprecation_status); - EXPECT_EQ(SecurityStateModel::NO_MIXED_CONTENT, + EXPECT_EQ(SecurityStateModel::CONTENT_STATUS_NONE, security_info.mixed_content_status); EXPECT_TRUE(security_info.sct_verify_statuses.empty()); EXPECT_FALSE(security_info.scheme_is_cryptographic); @@ -303,7 +303,7 @@ EXPECT_EQ(SecurityStateModel::NONE, security_info.security_level); EXPECT_EQ(SecurityStateModel::NO_DEPRECATED_SHA1, security_info.sha1_deprecation_status); - EXPECT_EQ(SecurityStateModel::NO_MIXED_CONTENT, + EXPECT_EQ(SecurityStateModel::CONTENT_STATUS_NONE, security_info.mixed_content_status); EXPECT_TRUE(security_info.sct_verify_statuses.empty()); EXPECT_FALSE(security_info.scheme_is_cryptographic); @@ -322,7 +322,7 @@ CheckSecurityInfoForSecure( browser()->tab_strip_model()->GetActiveWebContents(), SecurityStateModel::SECURE, SecurityStateModel::NO_DEPRECATED_SHA1, - SecurityStateModel::NO_MIXED_CONTENT, false, + SecurityStateModel::CONTENT_STATUS_NONE, false, false /* expect cert status error */); } @@ -340,7 +340,7 @@ browser()->tab_strip_model()->GetActiveWebContents(), SecurityStateModel::SECURITY_ERROR, SecurityStateModel::DEPRECATED_SHA1_MAJOR, - SecurityStateModel::NO_MIXED_CONTENT, false, + SecurityStateModel::CONTENT_STATUS_NONE, false, false /* expect cert status error */); } @@ -364,7 +364,7 @@ CheckSecurityInfoForSecure( browser()->tab_strip_model()->GetActiveWebContents(), SecurityStateModel::NONE, SecurityStateModel::NO_DEPRECATED_SHA1, - SecurityStateModel::DISPLAYED_MIXED_CONTENT, false, + SecurityStateModel::CONTENT_STATUS_DISPLAYED, false, false /* expect cert status error */); // Navigate to an HTTPS page that displays mixed content dynamically. @@ -376,7 +376,7 @@ CheckSecurityInfoForSecure( browser()->tab_strip_model()->GetActiveWebContents(), SecurityStateModel::SECURE, SecurityStateModel::NO_DEPRECATED_SHA1, - SecurityStateModel::NO_MIXED_CONTENT, false, + SecurityStateModel::CONTENT_STATUS_NONE, false, false /* expect cert status error */); // Load the insecure image. bool js_result = false; @@ -387,7 +387,7 @@ CheckSecurityInfoForSecure( browser()->tab_strip_model()->GetActiveWebContents(), SecurityStateModel::NONE, SecurityStateModel::NO_DEPRECATED_SHA1, - SecurityStateModel::DISPLAYED_MIXED_CONTENT, false, + SecurityStateModel::CONTENT_STATUS_DISPLAYED, false, false /* expect cert status error */); // Navigate to an HTTPS page that runs mixed content. @@ -400,7 +400,7 @@ browser()->tab_strip_model()->GetActiveWebContents(), SecurityStateModel::SECURITY_ERROR, SecurityStateModel::NO_DEPRECATED_SHA1, - SecurityStateModel::RAN_MIXED_CONTENT, false, + SecurityStateModel::CONTENT_STATUS_RAN, false, false /* expect cert status error */); // Navigate to an HTTPS page that runs and displays mixed content. @@ -413,7 +413,7 @@ browser()->tab_strip_model()->GetActiveWebContents(), SecurityStateModel::SECURITY_ERROR, SecurityStateModel::NO_DEPRECATED_SHA1, - SecurityStateModel::RAN_AND_DISPLAYED_MIXED_CONTENT, false, + SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN, false, false /* expect cert status error */); // Navigate to an HTTPS page that runs mixed content in an iframe. @@ -434,10 +434,99 @@ browser()->tab_strip_model()->GetActiveWebContents(), SecurityStateModel::SECURITY_ERROR, SecurityStateModel::NO_DEPRECATED_SHA1, - SecurityStateModel::RAN_MIXED_CONTENT, false, + SecurityStateModel::CONTENT_STATUS_RAN, false, false /* expect cert status error */); } +IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, + ActiveContentWithCertErrors) { + ASSERT_TRUE(https_server_.Start()); + SetUpMockCertVerifierForHttpsServer(0, net::OK); + + // Navigate to an HTTPS page and simulate active content with + // certificate errors. + ui_test_utils::NavigateToURL(browser(), https_server_.GetURL("/title1.html")); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(web_contents); + content::NavigationEntry* entry = + web_contents->GetController().GetVisibleEntry(); + ASSERT_TRUE(entry); + entry->GetSSL().content_status |= + content::SSLStatus::RAN_CONTENT_WITH_CERT_ERRORS; + + ChromeSecurityStateModelClient* model_client = + ChromeSecurityStateModelClient::FromWebContents(web_contents); + ASSERT_TRUE(model_client); + const SecurityStateModel::SecurityInfo& security_info = + model_client->GetSecurityInfo(); + + EXPECT_FALSE(net::IsCertStatusError(security_info.cert_status)); + EXPECT_EQ(SecurityStateModel::SECURITY_ERROR, security_info.security_level); + EXPECT_EQ(SecurityStateModel::CONTENT_STATUS_RAN, + security_info.content_with_cert_errors_status); +} + +IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, + PassiveContentWithCertErrors) { + ASSERT_TRUE(https_server_.Start()); + SetUpMockCertVerifierForHttpsServer(0, net::OK); + + // Navigate to an HTTPS page and simulate passive content with + // certificate errors. + ui_test_utils::NavigateToURL(browser(), https_server_.GetURL("/title1.html")); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(web_contents); + content::NavigationEntry* entry = + web_contents->GetController().GetVisibleEntry(); + ASSERT_TRUE(entry); + entry->GetSSL().content_status |= + content::SSLStatus::DISPLAYED_CONTENT_WITH_CERT_ERRORS; + + ChromeSecurityStateModelClient* model_client = + ChromeSecurityStateModelClient::FromWebContents(web_contents); + ASSERT_TRUE(model_client); + const SecurityStateModel::SecurityInfo& security_info = + model_client->GetSecurityInfo(); + + EXPECT_FALSE(net::IsCertStatusError(security_info.cert_status)); + EXPECT_EQ(SecurityStateModel::NONE, security_info.security_level); + EXPECT_EQ(SecurityStateModel::CONTENT_STATUS_DISPLAYED, + security_info.content_with_cert_errors_status); +} + +IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, + ActiveAndPassiveContentWithCertErrors) { + ASSERT_TRUE(https_server_.Start()); + SetUpMockCertVerifierForHttpsServer(0, net::OK); + + // Navigate to an HTTPS page and simulate active and passive content + // with certificate errors. + ui_test_utils::NavigateToURL(browser(), https_server_.GetURL("/title1.html")); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(web_contents); + content::NavigationEntry* entry = + web_contents->GetController().GetVisibleEntry(); + ASSERT_TRUE(entry); + entry->GetSSL().content_status |= + content::SSLStatus::RAN_CONTENT_WITH_CERT_ERRORS; + entry->GetSSL().content_status |= + content::SSLStatus::DISPLAYED_CONTENT_WITH_CERT_ERRORS; + + ChromeSecurityStateModelClient* model_client = + ChromeSecurityStateModelClient::FromWebContents(web_contents); + ASSERT_TRUE(model_client); + const SecurityStateModel::SecurityInfo& security_info = + model_client->GetSecurityInfo(); + + EXPECT_FALSE(net::IsCertStatusError(security_info.cert_status)); + EXPECT_EQ(SecurityStateModel::SECURITY_ERROR, security_info.security_level); + EXPECT_EQ(SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN, + security_info.content_with_cert_errors_status); +} + // Same as the test above but with a long-lived SHA1 cert. IN_PROC_BROWSER_TEST_F(ChromeSecurityStateModelClientTest, MixedContentWithBrokenSHA1) { @@ -466,7 +555,7 @@ browser()->tab_strip_model()->GetActiveWebContents(), SecurityStateModel::SECURITY_ERROR, SecurityStateModel::DEPRECATED_SHA1_MAJOR, - SecurityStateModel::DISPLAYED_MIXED_CONTENT, false, + SecurityStateModel::CONTENT_STATUS_DISPLAYED, false, false /* expect cert status error */); // Navigate to an HTTPS page that displays mixed content dynamically. @@ -479,7 +568,7 @@ browser()->tab_strip_model()->GetActiveWebContents(), SecurityStateModel::SECURITY_ERROR, SecurityStateModel::DEPRECATED_SHA1_MAJOR, - SecurityStateModel::NO_MIXED_CONTENT, false, + SecurityStateModel::CONTENT_STATUS_NONE, false, false /* expect cert status error */); // Load the insecure image. bool js_result = false; @@ -491,7 +580,7 @@ browser()->tab_strip_model()->GetActiveWebContents(), SecurityStateModel::SECURITY_ERROR, SecurityStateModel::DEPRECATED_SHA1_MAJOR, - SecurityStateModel::DISPLAYED_MIXED_CONTENT, false, + SecurityStateModel::CONTENT_STATUS_DISPLAYED, false, false /* expect cert status error */); // Navigate to an HTTPS page that runs mixed content. @@ -504,7 +593,7 @@ browser()->tab_strip_model()->GetActiveWebContents(), SecurityStateModel::SECURITY_ERROR, SecurityStateModel::DEPRECATED_SHA1_MAJOR, - SecurityStateModel::RAN_MIXED_CONTENT, false, + SecurityStateModel::CONTENT_STATUS_RAN, false, false /* expect cert status error */); // Navigate to an HTTPS page that runs and displays mixed content. @@ -517,7 +606,7 @@ browser()->tab_strip_model()->GetActiveWebContents(), SecurityStateModel::SECURITY_ERROR, SecurityStateModel::DEPRECATED_SHA1_MAJOR, - SecurityStateModel::RAN_AND_DISPLAYED_MIXED_CONTENT, false, + SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN, false, false /* expect cert status error */); } @@ -544,7 +633,7 @@ CheckSecurityInfoForSecure( browser()->tab_strip_model()->GetActiveWebContents(), SecurityStateModel::SECURE, SecurityStateModel::NO_DEPRECATED_SHA1, - SecurityStateModel::NO_MIXED_CONTENT, false, + SecurityStateModel::CONTENT_STATUS_NONE, false, false /* expect cert status error */); } @@ -560,7 +649,7 @@ browser()->tab_strip_model()->GetActiveWebContents(), SecurityStateModel::SECURITY_ERROR, SecurityStateModel::NO_DEPRECATED_SHA1, - SecurityStateModel::NO_MIXED_CONTENT, false, + SecurityStateModel::CONTENT_STATUS_NONE, false, true /* expect cert status error */); ProceedThroughInterstitial( @@ -570,7 +659,7 @@ browser()->tab_strip_model()->GetActiveWebContents(), SecurityStateModel::SECURITY_ERROR, SecurityStateModel::NO_DEPRECATED_SHA1, - SecurityStateModel::NO_MIXED_CONTENT, false, + SecurityStateModel::CONTENT_STATUS_NONE, false, true /* expect cert status error */); // Navigate to a broken HTTPS page that displays mixed content. @@ -584,7 +673,7 @@ browser()->tab_strip_model()->GetActiveWebContents(), SecurityStateModel::SECURITY_ERROR, SecurityStateModel::NO_DEPRECATED_SHA1, - SecurityStateModel::DISPLAYED_MIXED_CONTENT, false, + SecurityStateModel::CONTENT_STATUS_DISPLAYED, false, true /* expect cert status error */); } @@ -645,7 +734,7 @@ CheckSecurityInfoForSecure( browser()->tab_strip_model()->GetActiveWebContents(), SecurityStateModel::SECURE, SecurityStateModel::NO_DEPRECATED_SHA1, - SecurityStateModel::NO_MIXED_CONTENT, true, false); + SecurityStateModel::CONTENT_STATUS_NONE, true, false); const content::SecurityStyleExplanations& explanation = observer.latest_explanations(); @@ -732,7 +821,7 @@ CheckSecurityInfoForSecure( browser()->tab_strip_model()->GetActiveWebContents(), SecurityStateModel::SECURE, SecurityStateModel::NO_DEPRECATED_SHA1, - SecurityStateModel::NO_MIXED_CONTENT, false, + SecurityStateModel::CONTENT_STATUS_NONE, false, false /* expect cert status error */); // Navigate to a page that doesn't finish loading. Test that the @@ -764,14 +853,14 @@ EXPECT_TRUE(content::WaitForLoadStop(new_contents)); CheckSecurityInfoForSecure(new_contents, SecurityStateModel::SECURE, SecurityStateModel::NO_DEPRECATED_SHA1, - SecurityStateModel::NO_MIXED_CONTENT, false, + SecurityStateModel::CONTENT_STATUS_NONE, false, false /* expect cert status error */); browser()->tab_strip_model()->InsertWebContentsAt(0, new_contents, TabStripModel::ADD_NONE); CheckSecurityInfoForSecure(new_contents, SecurityStateModel::SECURE, SecurityStateModel::NO_DEPRECATED_SHA1, - SecurityStateModel::NO_MIXED_CONTENT, false, + SecurityStateModel::CONTENT_STATUS_NONE, false, false /* expect cert status error */); }
diff --git a/chrome/browser/ssl/chrome_ssl_host_state_delegate.cc b/chrome/browser/ssl/chrome_ssl_host_state_delegate.cc index 7d2fdfe2..f6e31e0 100644 --- a/chrome/browser/ssl/chrome_ssl_host_state_delegate.cc +++ b/chrome/browser/ssl/chrome_ssl_host_state_delegate.cc
@@ -434,15 +434,33 @@ return false; } -void ChromeSSLHostStateDelegate::HostRanInsecureContent(const std::string& host, - int pid) { - ran_insecure_content_hosts_.insert(BrokenHostEntry(host, pid)); +void ChromeSSLHostStateDelegate::HostRanInsecureContent( + const std::string& host, + int pid, + InsecureContentType content_type) { + switch (content_type) { + case MIXED_CONTENT: + ran_mixed_content_hosts_.insert(BrokenHostEntry(host, pid)); + return; + case CERT_ERRORS_CONTENT: + ran_content_with_cert_errors_hosts_.insert(BrokenHostEntry(host, pid)); + return; + } } bool ChromeSSLHostStateDelegate::DidHostRunInsecureContent( const std::string& host, - int pid) const { - return !!ran_insecure_content_hosts_.count(BrokenHostEntry(host, pid)); + int pid, + InsecureContentType content_type) const { + switch (content_type) { + case MIXED_CONTENT: + return !!ran_mixed_content_hosts_.count(BrokenHostEntry(host, pid)); + case CERT_ERRORS_CONTENT: + return !!ran_content_with_cert_errors_hosts_.count( + BrokenHostEntry(host, pid)); + } + NOTREACHED(); + return false; } void ChromeSSLHostStateDelegate::SetClock(std::unique_ptr<base::Clock> clock) { clock_.reset(clock.release());
diff --git a/chrome/browser/ssl/chrome_ssl_host_state_delegate.h b/chrome/browser/ssl/chrome_ssl_host_state_delegate.h index 8a01205..b958a1d 100644 --- a/chrome/browser/ssl/chrome_ssl_host_state_delegate.h +++ b/chrome/browser/ssl/chrome_ssl_host_state_delegate.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_SSL_CHROME_SSL_HOST_STATE_DELEGATE_H_ #include <memory> +#include <set> #include "base/gtest_prod_util.h" #include "base/macros.h" @@ -37,9 +38,13 @@ const net::X509Certificate& cert, net::CertStatus error, bool* expired_previous_decision) override; - void HostRanInsecureContent(const std::string& host, int pid) override; - bool DidHostRunInsecureContent(const std::string& host, - int pid) const override; + void HostRanInsecureContent(const std::string& host, + int pid, + InsecureContentType content_type) override; + bool DidHostRunInsecureContent( + const std::string& host, + int pid, + InsecureContentType content_type) const override; // Revokes all SSL certificate error allow exceptions made by the user for // |host| in the given Profile. @@ -110,10 +115,14 @@ // contains insecure content in that renderer process. typedef std::pair<std::string, int> BrokenHostEntry; - // Hosts which have been contaminated with insecure content in the + // Hosts which have been contaminated with insecure mixed content in the // specified process. Note that insecure content can travel between // same-origin frames in one processs but cannot jump between processes. - std::set<BrokenHostEntry> ran_insecure_content_hosts_; + std::set<BrokenHostEntry> ran_mixed_content_hosts_; + + // Hosts which have been contaminated with content with certificate errors in + // the specific process. + std::set<BrokenHostEntry> ran_content_with_cert_errors_hosts_; // This is a GUID to mark this unique session. Whenever a certificate decision // expiration is set, the GUID is saved as well so Chrome can tell if it was
diff --git a/chrome/browser/ssl/chrome_ssl_host_state_delegate_test.cc b/chrome/browser/ssl/chrome_ssl_host_state_delegate_test.cc index 70fa459..568dd94 100644 --- a/chrome/browser/ssl/chrome_ssl_host_state_delegate_test.cc +++ b/chrome/browser/ssl/chrome_ssl_host_state_delegate_test.cc
@@ -196,21 +196,73 @@ Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext()); content::SSLHostStateDelegate* state = profile->GetSSLHostStateDelegate(); - EXPECT_FALSE(state->DidHostRunInsecureContent("www.google.com", 42)); - EXPECT_FALSE(state->DidHostRunInsecureContent("www.google.com", 191)); - EXPECT_FALSE(state->DidHostRunInsecureContent("example.com", 42)); + EXPECT_FALSE(state->DidHostRunInsecureContent( + "www.google.com", 42, content::SSLHostStateDelegate::MIXED_CONTENT)); + EXPECT_FALSE(state->DidHostRunInsecureContent( + "www.google.com", 191, content::SSLHostStateDelegate::MIXED_CONTENT)); + EXPECT_FALSE(state->DidHostRunInsecureContent( + "example.com", 42, content::SSLHostStateDelegate::MIXED_CONTENT)); + EXPECT_FALSE(state->DidHostRunInsecureContent( + "www.google.com", 42, + content::SSLHostStateDelegate::CERT_ERRORS_CONTENT)); + EXPECT_FALSE(state->DidHostRunInsecureContent( + "www.google.com", 191, + content::SSLHostStateDelegate::CERT_ERRORS_CONTENT)); + EXPECT_FALSE(state->DidHostRunInsecureContent( + "example.com", 42, content::SSLHostStateDelegate::CERT_ERRORS_CONTENT)); - state->HostRanInsecureContent("www.google.com", 42); + // Mark a site as MIXED_CONTENT and check that only that host/child id + // is affected, and only for MIXED_CONTENT (not for + // CERT_ERRORS_CONTENT); + state->HostRanInsecureContent("www.google.com", 42, + content::SSLHostStateDelegate::MIXED_CONTENT); - EXPECT_TRUE(state->DidHostRunInsecureContent("www.google.com", 42)); - EXPECT_FALSE(state->DidHostRunInsecureContent("www.google.com", 191)); - EXPECT_FALSE(state->DidHostRunInsecureContent("example.com", 42)); + EXPECT_TRUE(state->DidHostRunInsecureContent( + "www.google.com", 42, content::SSLHostStateDelegate::MIXED_CONTENT)); + EXPECT_FALSE(state->DidHostRunInsecureContent( + "www.google.com", 42, + content::SSLHostStateDelegate::CERT_ERRORS_CONTENT)); + EXPECT_FALSE(state->DidHostRunInsecureContent( + "www.google.com", 191, content::SSLHostStateDelegate::MIXED_CONTENT)); + EXPECT_FALSE(state->DidHostRunInsecureContent( + "example.com", 42, content::SSLHostStateDelegate::MIXED_CONTENT)); - state->HostRanInsecureContent("example.com", 42); + // Mark another site as MIXED_CONTENT, and check that that host/child + // id is affected (for MIXED_CONTENT only), and that the previously + // host/child id is still marked as MIXED_CONTENT. + state->HostRanInsecureContent("example.com", 42, + content::SSLHostStateDelegate::MIXED_CONTENT); - EXPECT_TRUE(state->DidHostRunInsecureContent("www.google.com", 42)); - EXPECT_FALSE(state->DidHostRunInsecureContent("www.google.com", 191)); - EXPECT_TRUE(state->DidHostRunInsecureContent("example.com", 42)); + EXPECT_TRUE(state->DidHostRunInsecureContent( + "www.google.com", 42, content::SSLHostStateDelegate::MIXED_CONTENT)); + EXPECT_FALSE(state->DidHostRunInsecureContent( + "www.google.com", 191, content::SSLHostStateDelegate::MIXED_CONTENT)); + EXPECT_TRUE(state->DidHostRunInsecureContent( + "example.com", 42, content::SSLHostStateDelegate::MIXED_CONTENT)); + EXPECT_FALSE(state->DidHostRunInsecureContent( + "example.com", 42, content::SSLHostStateDelegate::CERT_ERRORS_CONTENT)); + + // Mark a MIXED_CONTENT host/child id as CERT_ERRORS_CONTENT also. + state->HostRanInsecureContent( + "example.com", 42, content::SSLHostStateDelegate::CERT_ERRORS_CONTENT); + + EXPECT_FALSE(state->DidHostRunInsecureContent( + "www.google.com", 191, content::SSLHostStateDelegate::MIXED_CONTENT)); + EXPECT_TRUE(state->DidHostRunInsecureContent( + "example.com", 42, content::SSLHostStateDelegate::MIXED_CONTENT)); + EXPECT_TRUE(state->DidHostRunInsecureContent( + "example.com", 42, content::SSLHostStateDelegate::CERT_ERRORS_CONTENT)); + + // Mark a non-MIXED_CONTENT host as CERT_ERRORS_CONTENT. + state->HostRanInsecureContent( + "www.google.com", 191, + content::SSLHostStateDelegate::CERT_ERRORS_CONTENT); + + EXPECT_TRUE(state->DidHostRunInsecureContent( + "www.google.com", 191, + content::SSLHostStateDelegate::CERT_ERRORS_CONTENT)); + EXPECT_FALSE(state->DidHostRunInsecureContent( + "www.google.com", 191, content::SSLHostStateDelegate::MIXED_CONTENT)); } // Test the migration code needed as a result of changing how the content
diff --git a/chrome/browser/ssl/security_state_model_android.cc b/chrome/browser/ssl/security_state_model_android.cc index b861e67..ad24fa0 100644 --- a/chrome/browser/ssl/security_state_model_android.cc +++ b/chrome/browser/ssl/security_state_model_android.cc
@@ -59,8 +59,8 @@ ChromeSecurityStateModelClient::FromWebContents(web_contents); DCHECK(model_client); return model_client->GetSecurityInfo().mixed_content_status == - security_state::SecurityStateModel::DISPLAYED_MIXED_CONTENT || + security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED || model_client->GetSecurityInfo().mixed_content_status == security_state::SecurityStateModel:: - RAN_AND_DISPLAYED_MIXED_CONTENT; + CONTENT_STATUS_DISPLAYED_AND_RAN; }
diff --git a/chrome/browser/ssl/ssl_browser_tests.cc b/chrome/browser/ssl/ssl_browser_tests.cc index 456bfd37..6e95c62 100644 --- a/chrome/browser/ssl/ssl_browser_tests.cc +++ b/chrome/browser/ssl/ssl_browser_tests.cc
@@ -325,9 +325,13 @@ net::EmbeddedTestServer::CERT_MISMATCHED_NAME); https_server_mismatched_.AddDefaultHandlers(base::FilePath(kDocRoot)); - // TODO(estark): once http://crbug.com/634171 is fixed and certificate - // errors for subresources don't generate DISPLAYED_INSECURE_CONTENT remove - // these filters. + // Sometimes favicons load before tests check the authentication + // state, and sometimes they load after. This is problematic on + // tests that load pages with certificate errors, because the page + // will be marked as having displayed subresources with certificate + // errors only if the favicon loads before the test checks the + // authentication state. To avoid this non-determinism, add an + // interceptor to hang all favicon requests. std::unique_ptr<net::URLRequestInterceptor> interceptor(new FaviconFilter); net::URLRequestFilter::GetInstance()->AddHostnameInterceptor( "https", "127.0.0.1", std::move(interceptor)); @@ -940,11 +944,8 @@ // We should see no interstitial, but we should have an error // (red-crossed-out-https) in the URL bar. - // TODO(estark): once http://crbug.com/634171 is fixed and certificate - // errors for subresources don't generate - // DISPLAYED/RAN_INSECURE_CONTENT switch this back to AuthState::NONE. CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID, - AuthState::RAN_INSECURE_CONTENT); + AuthState::NONE); // We should see that the script tag in the page loaded and ran (and // wasn't blocked by the certificate error). @@ -2231,11 +2232,8 @@ observer.Wait(); // We should still be authentication broken. - // TODO(estark): once http://crbug.com/634171 is fixed and certificate - // errors for subresources don't generate - // DISPLAYED/RAN_INSECURE_CONTENT switch this back to AuthState::NONE. CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID, - AuthState::RAN_INSECURE_CONTENT); + AuthState::NONE); } // From an HTTP top frame, navigate to good and bad HTTPS (security state should @@ -2341,6 +2339,14 @@ CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID, AuthState::NONE); + ChromeSecurityStateModelClient* client = + ChromeSecurityStateModelClient::FromWebContents(tab); + ASSERT_TRUE(client); + EXPECT_EQ(security_state::SecurityStateModel::CONTENT_STATUS_NONE, + client->GetSecurityInfo().mixed_content_status); + EXPECT_EQ(security_state::SecurityStateModel::CONTENT_STATUS_NONE, + client->GetSecurityInfo().content_with_cert_errors_status); + // Navigate to safe page that has Worker loading unsafe content. // Expect content to load but be marked as auth broken due to running insecure // content. @@ -2350,8 +2356,12 @@ ui_test_utils::NavigateToURL( browser(), https_server_.GetURL(page_with_unsafe_worker_path)); CheckWorkerLoadResult(tab, true); // Worker loads insecure content - CheckAuthenticationBrokenState(tab, CertError::NONE, - AuthState::RAN_INSECURE_CONTENT); + CheckAuthenticationBrokenState(tab, CertError::NONE, AuthState::NONE); + + EXPECT_EQ(security_state::SecurityStateModel::CONTENT_STATUS_NONE, + client->GetSecurityInfo().mixed_content_status); + EXPECT_EQ(security_state::SecurityStateModel::CONTENT_STATUS_RAN, + client->GetSecurityInfo().content_with_cert_errors_status); } // Visits a page with unsafe content and makes sure that if a user exception to @@ -2360,9 +2370,16 @@ WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); ASSERT_NO_FATAL_FAILURE(SetUpUnsafeContentsWithUserException( "/ssl/page_with_unsafe_contents.html")); - CheckAuthenticationBrokenState( - tab, CertError::NONE, - AuthState::RAN_INSECURE_CONTENT | AuthState::DISPLAYED_INSECURE_CONTENT); + CheckAuthenticationBrokenState(tab, CertError::NONE, AuthState::NONE); + + ChromeSecurityStateModelClient* client = + ChromeSecurityStateModelClient::FromWebContents(tab); + ASSERT_TRUE(client); + EXPECT_EQ(security_state::SecurityStateModel::CONTENT_STATUS_NONE, + client->GetSecurityInfo().mixed_content_status); + EXPECT_EQ( + security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN, + client->GetSecurityInfo().content_with_cert_errors_status); int img_width; EXPECT_TRUE(content::ExecuteScriptAndExtractInt( @@ -2378,8 +2395,7 @@ EXPECT_TRUE(js_result); // Test that active subresources with the same certificate errors as - // the main resources don't cause mixed content UI downgrades. (Such - // errors would be confusing and duplicative.) + // the main resources also get noted in |content_with_cert_errors_status|. std::string replacement_path; GetFilePathWithHostAndPortReplacement( "/ssl/page_with_unsafe_contents.html", @@ -2390,12 +2406,14 @@ EXPECT_TRUE(content::ExecuteScriptAndExtractBool( tab, "window.domAutomationController.send(IsFooSet());", &js_result)); EXPECT_TRUE(js_result); - // TODO(estark): once http://crbug.com/634171 is fixed and certificate - // errors for subresources don't generate - // DISPLAYED/RAN_INSECURE_CONTENT switch this back to AuthState::NONE. - CheckAuthenticationBrokenState( - tab, net::CERT_STATUS_COMMON_NAME_INVALID, - AuthState::DISPLAYED_INSECURE_CONTENT | AuthState::RAN_INSECURE_CONTENT); + CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID, + AuthState::NONE); + + EXPECT_EQ(security_state::SecurityStateModel::CONTENT_STATUS_NONE, + client->GetSecurityInfo().mixed_content_status); + EXPECT_EQ( + security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN, + client->GetSecurityInfo().content_with_cert_errors_status); } // Like the test above, but only displaying inactive content (an image). @@ -2403,7 +2421,15 @@ WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); ASSERT_NO_FATAL_FAILURE( SetUpUnsafeContentsWithUserException("/ssl/page_with_unsafe_image.html")); - CheckAuthenticatedState(tab, AuthState::DISPLAYED_INSECURE_CONTENT); + CheckAuthenticatedState(tab, AuthState::NONE); + + ChromeSecurityStateModelClient* client = + ChromeSecurityStateModelClient::FromWebContents(tab); + ASSERT_TRUE(client); + EXPECT_EQ(security_state::SecurityStateModel::CONTENT_STATUS_NONE, + client->GetSecurityInfo().mixed_content_status); + EXPECT_EQ(security_state::SecurityStateModel::CONTENT_STATUS_DISPLAYED, + client->GetSecurityInfo().content_with_cert_errors_status); int img_width; EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
diff --git a/chrome/browser/supervised_user/child_accounts/child_account_service.cc b/chrome/browser/supervised_user/child_accounts/child_account_service.cc index 5081a2d..a624431 100644 --- a/chrome/browser/supervised_user/child_accounts/child_account_service.cc +++ b/chrome/browser/supervised_user/child_accounts/child_account_service.cc
@@ -296,12 +296,10 @@ #if defined(OS_CHROMEOS) user_manager::User* user = chromeos::ProfileHelper::Get()->GetUserByProfile(profile_); - if (user) { + if (user) user_manager::UserManager::Get()->ChangeUserChildStatus(user, is_child); - } else { - LOG(WARNING) << - "User instance wasn't found while setting child account flag."; - } + else if (!chromeos::ProfileHelper::Get()->IsSigninProfile(profile_)) + LOG(DFATAL) << "User instance not found while setting child account flag."; #endif }
diff --git a/chrome/browser/supervised_user/supervised_user_service.h b/chrome/browser/supervised_user/supervised_user_service.h index 81ca0d2..0c37600e 100644 --- a/chrome/browser/supervised_user/supervised_user_service.h +++ b/chrome/browser/supervised_user/supervised_user_service.h
@@ -28,8 +28,8 @@ #include "chrome/browser/ui/browser_list_observer.h" #include "components/keyed_service/core/keyed_service.h" #include "components/prefs/pref_change_registrar.h" -#include "components/sync_driver/sync_service_observer.h" -#include "components/sync_driver/sync_type_preference_provider.h" +#include "components/sync/driver/sync_service_observer.h" +#include "components/sync/driver/sync_type_preference_provider.h" #include "net/url_request/url_request_context_getter.h" #if defined(ENABLE_EXTENSIONS)
diff --git a/chrome/browser/supervised_user/supervised_user_sync_data_type_controller.h b/chrome/browser/supervised_user/supervised_user_sync_data_type_controller.h index e0596b2..d8e7050f 100644 --- a/chrome/browser/supervised_user/supervised_user_sync_data_type_controller.h +++ b/chrome/browser/supervised_user/supervised_user_sync_data_type_controller.h
@@ -6,8 +6,8 @@ #define CHROME_BROWSER_SUPERVISED_USER_SUPERVISED_USER_SYNC_DATA_TYPE_CONTROLLER_H_ #include "base/macros.h" -#include "components/sync_driver/data_type_controller.h" -#include "components/sync_driver/ui_data_type_controller.h" +#include "components/sync/driver/data_type_controller.h" +#include "components/sync/driver/ui_data_type_controller.h" namespace sync_driver { class SyncClient;
diff --git a/chrome/browser/sync/DEPS b/chrome/browser/sync/DEPS index 668f86a..5dd6f12 100644 --- a/chrome/browser/sync/DEPS +++ b/chrome/browser/sync/DEPS
@@ -1,7 +1,7 @@ include_rules = [ "+components/invalidation", "+components/sync/core", - "+components/sync_driver", + "+components/sync/driver", "+components/sync_sessions", "+components/wifi_sync", "+google/cacheinvalidation",
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc index 77ae249..a4dabfeb 100644 --- a/chrome/browser/sync/chrome_sync_client.cc +++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -31,6 +31,7 @@ #include "chrome/browser/themes/theme_service.h" #include "chrome/browser/themes/theme_service_factory.h" #include "chrome/browser/themes/theme_syncable_service.h" +#include "chrome/browser/ui/app_list/arc/arc_package_sync_data_type_controller.h" #include "chrome/browser/ui/sync/browser_synced_window_delegates_getter.h" #include "chrome/browser/undo/bookmark_undo_service_factory.h" #include "chrome/browser/web_data_service_factory.h" @@ -54,13 +55,13 @@ #include "components/password_manager/sync/browser/password_model_worker.h" #include "components/search_engines/search_engine_data_type_controller.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" +#include "components/sync/driver/glue/browser_thread_model_worker.h" +#include "components/sync/driver/glue/chrome_report_unrecoverable_error.h" +#include "components/sync/driver/glue/ui_model_worker.h" +#include "components/sync/driver/sync_api_component_factory.h" +#include "components/sync/driver/sync_util.h" +#include "components/sync/driver/ui_data_type_controller.h" #include "components/sync/engine/passive_model_worker.h" -#include "components/sync_driver/glue/browser_thread_model_worker.h" -#include "components/sync_driver/glue/chrome_report_unrecoverable_error.h" -#include "components/sync_driver/glue/ui_model_worker.h" -#include "components/sync_driver/sync_api_component_factory.h" -#include "components/sync_driver/sync_util.h" -#include "components/sync_driver/ui_data_type_controller.h" #include "components/sync_sessions/sync_sessions_client.h" #include "components/syncable_prefs/pref_service_syncable.h" #include "content/public/browser/browser_thread.h" @@ -530,13 +531,6 @@ } #endif - // Preference sync is enabled by default. Register unless explicitly - // disabled. - if (!disabled_types.Has(syncer::PREFERENCES)) { - sync_service->RegisterDataTypeController(new UIDataTypeController( - ui_thread, error_callback, syncer::PREFERENCES, this)); - } - #if defined(ENABLE_THEMES) // Theme sync is enabled by default. Register unless explicitly disabled. if (!disabled_types.Has(syncer::THEMES)) { @@ -610,8 +604,8 @@ ui_thread, error_callback, syncer::WIFI_CREDENTIALS, this)); } // TODO (lgcheng@) Add switch for this. - sync_service->RegisterDataTypeController(new UIDataTypeController( - ui_thread, error_callback, syncer::ARC_PACKAGE, this)); + sync_service->RegisterDataTypeController(new ArcPackageSyncDataTypeController( + syncer::ARC_PACKAGE, error_callback, this, profile_)); #endif }
diff --git a/chrome/browser/sync/chrome_sync_client.h b/chrome/browser/sync/chrome_sync_client.h index 17908fd..22e1c5a 100644 --- a/chrome/browser/sync/chrome_sync_client.h +++ b/chrome/browser/sync/chrome_sync_client.h
@@ -9,7 +9,7 @@ #include "base/macros.h" #include "chrome/browser/sync/glue/extensions_activity_monitor.h" -#include "components/sync_driver/sync_client.h" +#include "components/sync/driver/sync_client.h" class Profile;
diff --git a/chrome/browser/sync/chrome_sync_client_unittest.cc b/chrome/browser/sync/chrome_sync_client_unittest.cc index 2c286aa..f7f89c7 100644 --- a/chrome/browser/sync/chrome_sync_client_unittest.cc +++ b/chrome/browser/sync/chrome_sync_client_unittest.cc
@@ -7,7 +7,7 @@ #include <memory> #include "chrome/common/url_constants.h" -#include "components/sync_driver/sync_api_component_factory.h" +#include "components/sync/driver/sync_api_component_factory.h" #include "components/sync_sessions/sync_sessions_client.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/chrome/browser/sync/glue/extension_data_type_controller.h b/chrome/browser/sync/glue/extension_data_type_controller.h index 6988db39..b057d07 100644 --- a/chrome/browser/sync/glue/extension_data_type_controller.h +++ b/chrome/browser/sync/glue/extension_data_type_controller.h
@@ -9,8 +9,8 @@ #include "base/compiler_specific.h" #include "base/macros.h" -#include "components/sync_driver/generic_change_processor.h" -#include "components/sync_driver/ui_data_type_controller.h" +#include "components/sync/driver/generic_change_processor.h" +#include "components/sync/driver/ui_data_type_controller.h" class Profile;
diff --git a/chrome/browser/sync/glue/extension_setting_data_type_controller.cc b/chrome/browser/sync/glue/extension_setting_data_type_controller.cc index 6aab845..ff4f6ab 100644 --- a/chrome/browser/sync/glue/extension_setting_data_type_controller.cc +++ b/chrome/browser/sync/glue/extension_setting_data_type_controller.cc
@@ -9,7 +9,7 @@ #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/profiles/profile.h" #include "components/sync/api/syncable_service.h" -#include "components/sync_driver/generic_change_processor.h" +#include "components/sync/driver/generic_change_processor.h" #include "content/public/browser/browser_thread.h" #include "extensions/browser/extension_system.h"
diff --git a/chrome/browser/sync/glue/extension_setting_data_type_controller.h b/chrome/browser/sync/glue/extension_setting_data_type_controller.h index 84322aa..9f8e7d8 100644 --- a/chrome/browser/sync/glue/extension_setting_data_type_controller.h +++ b/chrome/browser/sync/glue/extension_setting_data_type_controller.h
@@ -9,7 +9,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" -#include "components/sync_driver/non_ui_data_type_controller.h" +#include "components/sync/driver/non_ui_data_type_controller.h" class Profile;
diff --git a/chrome/browser/sync/glue/theme_data_type_controller.h b/chrome/browser/sync/glue/theme_data_type_controller.h index 1110ade..17a4251 100644 --- a/chrome/browser/sync/glue/theme_data_type_controller.h +++ b/chrome/browser/sync/glue/theme_data_type_controller.h
@@ -6,7 +6,7 @@ #define CHROME_BROWSER_SYNC_GLUE_THEME_DATA_TYPE_CONTROLLER_H_ #include "base/macros.h" -#include "components/sync_driver/ui_data_type_controller.h" +#include "components/sync/driver/ui_data_type_controller.h" class Profile;
diff --git a/chrome/browser/sync/profile_sync_service_android.cc b/chrome/browser/sync/profile_sync_service_android.cc index 8ecf44bc..39717cb 100644 --- a/chrome/browser/sync/profile_sync_service_android.cc +++ b/chrome/browser/sync/profile_sync_service_android.cc
@@ -31,9 +31,9 @@ #include "components/signin/core/browser/signin_manager.h" #include "components/sync/core/network_resources.h" #include "components/sync/core/read_transaction.h" -#include "components/sync_driver/about_sync_util.h" -#include "components/sync_driver/pref_names.h" -#include "components/sync_driver/sync_prefs.h" +#include "components/sync/driver/about_sync_util.h" +#include "components/sync/driver/pref_names.h" +#include "components/sync/driver/sync_prefs.h" #include "content/public/browser/browser_thread.h" #include "google/cacheinvalidation/types.pb.h" #include "google_apis/gaia/gaia_constants.h"
diff --git a/chrome/browser/sync/profile_sync_service_android.h b/chrome/browser/sync/profile_sync_service_android.h index b8c5d04..cdfbec4 100644 --- a/chrome/browser/sync/profile_sync_service_android.h +++ b/chrome/browser/sync/profile_sync_service_android.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_SYNC_PROFILE_SYNC_SERVICE_ANDROID_H_ #include <jni.h> + #include <map> #include "base/android/jni_weak_ref.h" @@ -14,8 +15,8 @@ #include "base/macros.h" #include "base/time/time.h" #include "components/invalidation/public/invalidation_util.h" -#include "components/sync_driver/sync_prefs.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/sync_prefs.h" +#include "components/sync/driver/sync_service_observer.h" #include "google/cacheinvalidation/include/types.h" #include "google_apis/gaia/google_service_auth_error.h"
diff --git a/chrome/browser/sync/profile_sync_service_factory.cc b/chrome/browser/sync/profile_sync_service_factory.cc index 7b984703..b485f60f 100644 --- a/chrome/browser/sync/profile_sync_service_factory.cc +++ b/chrome/browser/sync/profile_sync_service_factory.cc
@@ -37,9 +37,9 @@ #include "components/network_time/network_time_tracker.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_manager.h" -#include "components/sync_driver/signin_manager_wrapper.h" -#include "components/sync_driver/startup_controller.h" -#include "components/sync_driver/sync_util.h" +#include "components/sync/driver/signin_manager_wrapper.h" +#include "components/sync/driver/startup_controller.h" +#include "components/sync/driver/sync_util.h" #include "content/public/browser/browser_thread.h" #include "url/gurl.h"
diff --git a/chrome/browser/sync/profile_sync_service_factory_unittest.cc b/chrome/browser/sync/profile_sync_service_factory_unittest.cc index 2264a75..3d97334 100644 --- a/chrome/browser/sync/profile_sync_service_factory_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_factory_unittest.cc
@@ -14,7 +14,7 @@ #include "components/browser_sync/browser/profile_sync_service.h" #include "components/browser_sync/common/browser_sync_switches.h" #include "components/sync/base/model_type.h" -#include "components/sync_driver/data_type_controller.h" +#include "components/sync/driver/data_type_controller.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/app_list/app_list_switches.h" @@ -45,7 +45,6 @@ #endif datatypes.push_back(syncer::EXTENSIONS); datatypes.push_back(syncer::EXTENSION_SETTINGS); - datatypes.push_back(syncer::PREFERENCES); datatypes.push_back(syncer::SEARCH_ENGINES); datatypes.push_back(syncer::THEMES); datatypes.push_back(syncer::SUPERVISED_USERS); @@ -63,6 +62,7 @@ datatypes.push_back(syncer::FAVICON_IMAGES); datatypes.push_back(syncer::HISTORY_DELETE_DIRECTIVES); datatypes.push_back(syncer::PASSWORDS); + datatypes.push_back(syncer::PREFERENCES); datatypes.push_back(syncer::PRIORITY_PREFERENCES); datatypes.push_back(syncer::SESSIONS); datatypes.push_back(syncer::PROXY_TABS);
diff --git a/chrome/browser/sync/profile_sync_test_util.cc b/chrome/browser/sync/profile_sync_test_util.cc index 5f6ce7e..aee56f3 100644 --- a/chrome/browser/sync/profile_sync_test_util.cc +++ b/chrome/browser/sync/profile_sync_test_util.cc
@@ -17,9 +17,9 @@ #include "components/browser_sync/browser/profile_sync_service.h" #include "components/browser_sync/browser/profile_sync_test_util.h" #include "components/signin/core/browser/signin_manager.h" -#include "components/sync_driver/signin_manager_wrapper.h" -#include "components/sync_driver/startup_controller.h" -#include "components/sync_driver/sync_api_component_factory_mock.h" +#include "components/sync/driver/signin_manager_wrapper.h" +#include "components/sync/driver/startup_controller.h" +#include "components/sync/driver/sync_api_component_factory_mock.h" ProfileSyncService::InitParams CreateProfileSyncServiceParamsForTest( Profile* profile) {
diff --git a/chrome/browser/sync/sessions/sessions_sync_manager_unittest.cc b/chrome/browser/sync/sessions/sessions_sync_manager_unittest.cc index 25e41f3..d54c62e 100644 --- a/chrome/browser/sync/sessions/sessions_sync_manager_unittest.cc +++ b/chrome/browser/sync/sessions/sessions_sync_manager_unittest.cc
@@ -27,9 +27,9 @@ #include "components/sync/api/attachments/attachment_id.h" #include "components/sync/api/sync_error_factory_mock.h" #include "components/sync/core/attachments/attachment_service_proxy_for_test.h" -#include "components/sync_driver/device_info.h" -#include "components/sync_driver/local_device_info_provider_mock.h" -#include "components/sync_driver/sync_api_component_factory.h" +#include "components/sync/driver/device_info.h" +#include "components/sync/driver/local_device_info_provider_mock.h" +#include "components/sync/driver/sync_api_component_factory.h" #include "components/sync_sessions/sync_sessions_client.h" #include "components/sync_sessions/synced_tab_delegate.h" #include "components/sync_sessions/synced_window_delegate.h"
diff --git a/chrome/browser/sync/supervised_user_signin_manager_wrapper.h b/chrome/browser/sync/supervised_user_signin_manager_wrapper.h index 64421ea..6d49080 100644 --- a/chrome/browser/sync/supervised_user_signin_manager_wrapper.h +++ b/chrome/browser/sync/supervised_user_signin_manager_wrapper.h
@@ -8,7 +8,7 @@ #include <string> #include "base/macros.h" -#include "components/sync_driver/signin_manager_wrapper.h" +#include "components/sync/driver/signin_manager_wrapper.h" class Profile; class SigninManagerBase;
diff --git a/chrome/browser/sync/sync_error_notifier_ash.h b/chrome/browser/sync/sync_error_notifier_ash.h index dd05ff1..9582049 100644 --- a/chrome/browser/sync/sync_error_notifier_ash.h +++ b/chrome/browser/sync/sync_error_notifier_ash.h
@@ -11,7 +11,7 @@ #include "base/macros.h" #include "base/strings/string16.h" #include "components/keyed_service/core/keyed_service.h" -#include "components/sync_driver/sync_error_controller.h" +#include "components/sync/driver/sync_error_controller.h" class Profile;
diff --git a/chrome/browser/sync/sync_error_notifier_ash_unittest.cc b/chrome/browser/sync/sync_error_notifier_ash_unittest.cc index 9948d322..3621a5a 100644 --- a/chrome/browser/sync/sync_error_notifier_ash_unittest.cc +++ b/chrome/browser/sync/sync_error_notifier_ash_unittest.cc
@@ -23,7 +23,7 @@ #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" #include "components/browser_sync/browser/profile_sync_service_mock.h" -#include "components/sync_driver/sync_error_controller.h" +#include "components/sync/driver/sync_error_controller.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/message_center/notification.h"
diff --git a/chrome/browser/sync/sync_global_error.h b/chrome/browser/sync/sync_global_error.h index cbdddd3..ac853a28 100644 --- a/chrome/browser/sync/sync_global_error.h +++ b/chrome/browser/sync/sync_global_error.h
@@ -9,7 +9,7 @@ #include "base/macros.h" #include "chrome/browser/ui/global_error/global_error.h" #include "components/keyed_service/core/keyed_service.h" -#include "components/sync_driver/sync_error_controller.h" +#include "components/sync/driver/sync_error_controller.h" class GlobalErrorService; class LoginUIService;
diff --git a/chrome/browser/sync/sync_global_error_unittest.cc b/chrome/browser/sync/sync_global_error_unittest.cc index e7af93f..ed7eae81 100644 --- a/chrome/browser/sync/sync_global_error_unittest.cc +++ b/chrome/browser/sync/sync_global_error_unittest.cc
@@ -17,7 +17,7 @@ #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" #include "chrome/test/base/browser_with_test_window_test.h" #include "chrome/test/base/testing_profile.h" -#include "components/sync_driver/sync_error_controller.h" +#include "components/sync/driver/sync_error_controller.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_source.h"
diff --git a/chrome/browser/sync/sync_startup_tracker.h b/chrome/browser/sync/sync_startup_tracker.h index eb73612..9b5a3b0 100644 --- a/chrome/browser/sync/sync_startup_tracker.h +++ b/chrome/browser/sync/sync_startup_tracker.h
@@ -7,7 +7,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/sync_service_observer.h" class Profile;
diff --git a/chrome/browser/sync/sync_ui_util.cc b/chrome/browser/sync/sync_ui_util.cc index 695f1ee9..30afb16 100644 --- a/chrome/browser/sync/sync_ui_util.cc +++ b/chrome/browser/sync/sync_ui_util.cc
@@ -45,7 +45,7 @@ #include "components/user_manager/user_manager.h" #else #include "chrome/browser/signin/signin_manager_factory.h" -#include "components/sync_driver/sync_error_controller.h" +#include "components/sync/driver/sync_error_controller.h" #endif // defined(OS_CHROMEOS) typedef GoogleServiceAuthError AuthError;
diff --git a/chrome/browser/sync/test/integration/fake_server_invalidation_service.cc b/chrome/browser/sync/test/integration/fake_server_invalidation_service.cc index f8fb68c..12443e58 100644 --- a/chrome/browser/sync/test/integration/fake_server_invalidation_service.cc +++ b/chrome/browser/sync/test/integration/fake_server_invalidation_service.cc
@@ -11,7 +11,7 @@ #include "components/invalidation/public/invalidation.h" #include "components/invalidation/public/object_id_invalidation_map.h" #include "components/sync/base/model_type.h" -#include "components/sync_driver/invalidation_helper.h" +#include "components/sync/driver/invalidation_helper.h" namespace fake_server {
diff --git a/chrome/browser/sync/test/integration/migration_test.cc b/chrome/browser/sync/test/integration/migration_test.cc index b5d841e..f41b940a 100644 --- a/chrome/browser/sync/test/integration/migration_test.cc +++ b/chrome/browser/sync/test/integration/migration_test.cc
@@ -106,6 +106,10 @@ preferred_data_types.Remove(syncer::AUTOFILL_WALLET_DATA); preferred_data_types.Remove(syncer::AUTOFILL_WALLET_METADATA); + // Arc package will be unready during this test, so we should not request + // that it be migrated. + preferred_data_types.Remove(syncer::ARC_PACKAGE); + // Make sure all clients have the same preferred data types. for (int i = 1; i < num_clients(); ++i) { const syncer::ModelTypeSet other_preferred_data_types =
diff --git a/chrome/browser/sync/test/integration/migration_watcher.h b/chrome/browser/sync/test/integration/migration_watcher.h index 53630c8d..b1b124dc 100644 --- a/chrome/browser/sync/test/integration/migration_watcher.h +++ b/chrome/browser/sync/test/integration/migration_watcher.h
@@ -7,7 +7,7 @@ #include "base/macros.h" #include "components/sync/base/model_type.h" -#include "components/sync_driver/backend_migrator.h" +#include "components/sync/driver/backend_migrator.h" class ProfileSyncServiceHarness; class MigrationWaiter;
diff --git a/chrome/browser/sync/test/integration/multi_client_status_change_checker.h b/chrome/browser/sync/test/integration/multi_client_status_change_checker.h index 9493c45..fc7db1a 100644 --- a/chrome/browser/sync/test/integration/multi_client_status_change_checker.h +++ b/chrome/browser/sync/test/integration/multi_client_status_change_checker.h
@@ -10,7 +10,7 @@ #include "base/compiler_specific.h" #include "base/time/time.h" #include "chrome/browser/sync/test/integration/status_change_checker.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/sync_service_observer.h" class ProfileSyncService;
diff --git a/chrome/browser/sync/test/integration/p2p_invalidation_forwarder.cc b/chrome/browser/sync/test/integration/p2p_invalidation_forwarder.cc index 59c1f46..ba66f5d3 100644 --- a/chrome/browser/sync/test/integration/p2p_invalidation_forwarder.cc +++ b/chrome/browser/sync/test/integration/p2p_invalidation_forwarder.cc
@@ -6,8 +6,8 @@ #include "components/browser_sync/browser/profile_sync_service.h" #include "components/invalidation/impl/p2p_invalidation_service.h" +#include "components/sync/driver/invalidation_helper.h" #include "components/sync/sessions/sync_session_snapshot.h" -#include "components/sync_driver/invalidation_helper.h" P2PInvalidationForwarder::P2PInvalidationForwarder( ProfileSyncService* sync_service,
diff --git a/chrome/browser/sync/test/integration/p2p_invalidation_forwarder.h b/chrome/browser/sync/test/integration/p2p_invalidation_forwarder.h index 59fe52c..52e93bc 100644 --- a/chrome/browser/sync/test/integration/p2p_invalidation_forwarder.h +++ b/chrome/browser/sync/test/integration/p2p_invalidation_forwarder.h
@@ -7,7 +7,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/sync_service_observer.h" class ProfileSyncService;
diff --git a/chrome/browser/sync/test/integration/p2p_sync_refresher.h b/chrome/browser/sync/test/integration/p2p_sync_refresher.h index 7a71f25d..e10b8c22 100644 --- a/chrome/browser/sync/test/integration/p2p_sync_refresher.h +++ b/chrome/browser/sync/test/integration/p2p_sync_refresher.h
@@ -6,7 +6,7 @@ #define CHROME_BROWSER_SYNC_TEST_INTEGRATION_P2P_SYNC_REFRESHER_H_ #include "base/macros.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/sync_service_observer.h" class Profile; class ProfileSyncService;
diff --git a/chrome/browser/sync/test/integration/profile_sync_service_harness.cc b/chrome/browser/sync/test/integration/profile_sync_service_harness.cc index f7adf0a3..0536ace 100644 --- a/chrome/browser/sync/test/integration/profile_sync_service_harness.cc +++ b/chrome/browser/sync/test/integration/profile_sync_service_harness.cc
@@ -30,7 +30,7 @@ #include "components/signin/core/browser/signin_manager_base.h" #include "components/sync/base/progress_marker_map.h" #include "components/sync/base/sync_string_conversions.h" -#include "components/sync_driver/about_sync_util.h" +#include "components/sync/driver/about_sync_util.h" #include "google_apis/gaia/gaia_constants.h" using syncer::sessions::SyncSessionSnapshot;
diff --git a/chrome/browser/sync/test/integration/sessions_helper.cc b/chrome/browser/sync/test/integration/sessions_helper.cc index acb0495..88017734 100644 --- a/chrome/browser/sync/test/integration/sessions_helper.cc +++ b/chrome/browser/sync/test/integration/sessions_helper.cc
@@ -27,7 +27,7 @@ #include "chrome/browser/ui/singleton_tabs.h" #include "chrome/common/chrome_switches.h" #include "components/browser_sync/browser/profile_sync_service.h" -#include "components/sync_driver/sync_client.h" +#include "components/sync/driver/sync_client.h" #include "components/sync_sessions/open_tabs_ui_delegate.h" #include "content/public/test/test_utils.h" #include "url/gurl.h" @@ -44,7 +44,7 @@ } ScopedWindowMap::~ScopedWindowMap() { - STLDeleteContainerPairSecondPointers(windows_.begin(), windows_.end()); + base::STLDeleteContainerPairSecondPointers(windows_.begin(), windows_.end()); } SessionWindowMap* ScopedWindowMap::GetMutable() { @@ -56,7 +56,7 @@ } void ScopedWindowMap::Reset(SessionWindowMap* windows) { - STLDeleteContainerPairSecondPointers(windows_.begin(), windows_.end()); + base::STLDeleteContainerPairSecondPointers(windows_.begin(), windows_.end()); windows_.clear(); std::swap(*windows, windows_); }
diff --git a/chrome/browser/sync/test/integration/single_client_status_change_checker.h b/chrome/browser/sync/test/integration/single_client_status_change_checker.h index 2ffafde..118cdc03 100644 --- a/chrome/browser/sync/test/integration/single_client_status_change_checker.h +++ b/chrome/browser/sync/test/integration/single_client_status_change_checker.h
@@ -8,7 +8,7 @@ #include "base/compiler_specific.h" #include "base/time/time.h" #include "chrome/browser/sync/test/integration/multi_client_status_change_checker.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/sync_service_observer.h" class ProfileSyncService;
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc index 5175399..0f3176f 100644 --- a/chrome/browser/sync/test/integration/sync_test.cc +++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -70,12 +70,12 @@ #include "components/search_engines/template_url_service.h" #include "components/signin/core/browser/profile_identity_provider.h" #include "components/signin/core/browser/signin_manager.h" +#include "components/sync/driver/invalidation_helper.h" +#include "components/sync/driver/sync_driver_switches.h" #include "components/sync/engine_impl/sync_scheduler_impl.h" #include "components/sync/protocol/sync.pb.h" #include "components/sync/test/fake_server/fake_server.h" #include "components/sync/test/fake_server/fake_server_network_resources.h" -#include "components/sync_driver/invalidation_helper.h" -#include "components/sync_driver/sync_driver_switches.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/sync_file_system/drive_backend/drive_backend_sync_unittest.cc b/chrome/browser/sync_file_system/drive_backend/drive_backend_sync_unittest.cc index 76f7d20a..85e1d1d 100644 --- a/chrome/browser/sync_file_system/drive_backend/drive_backend_sync_unittest.cc +++ b/chrome/browser/sync_file_system/drive_backend/drive_backend_sync_unittest.cc
@@ -232,7 +232,7 @@ SyncStatusCode RegisterApp(const std::string& app_id) { GURL origin = extensions::Extension::GetBaseURLFromExtensionId(app_id); - if (!ContainsKey(file_systems_, app_id)) { + if (!base::ContainsKey(file_systems_, app_id)) { CannedSyncableFileSystem* file_system = new CannedSyncableFileSystem( origin, in_memory_env_.get(), io_task_runner_.get(), file_task_runner_.get()); @@ -266,7 +266,7 @@ void AddLocalFolder(const std::string& app_id, const base::FilePath::StringType& path) { - ASSERT_TRUE(ContainsKey(file_systems_, app_id)); + ASSERT_TRUE(base::ContainsKey(file_systems_, app_id)); EXPECT_EQ(base::File::FILE_OK, file_systems_[app_id]->CreateDirectory( CreateURL(app_id, path))); @@ -276,7 +276,7 @@ const base::FilePath::StringType& path, const std::string& content) { storage::FileSystemURL url(CreateURL(app_id, path)); - ASSERT_TRUE(ContainsKey(file_systems_, app_id)); + ASSERT_TRUE(base::ContainsKey(file_systems_, app_id)); EXPECT_EQ(base::File::FILE_OK, file_systems_[app_id]->CreateFile(url)); int64_t bytes_written = file_systems_[app_id]->WriteString(url, content); EXPECT_EQ(static_cast<int64_t>(content.size()), bytes_written); @@ -286,7 +286,7 @@ void UpdateLocalFile(const std::string& app_id, const base::FilePath::StringType& path, const std::string& content) { - ASSERT_TRUE(ContainsKey(file_systems_, app_id)); + ASSERT_TRUE(base::ContainsKey(file_systems_, app_id)); int64_t bytes_written = file_systems_[app_id]->WriteString(CreateURL(app_id, path), content); EXPECT_EQ(static_cast<int64_t>(content.size()), bytes_written); @@ -295,7 +295,7 @@ void RemoveLocal(const std::string& app_id, const base::FilePath::StringType& path) { - ASSERT_TRUE(ContainsKey(file_systems_, app_id)); + ASSERT_TRUE(base::ContainsKey(file_systems_, app_id)); EXPECT_EQ(base::File::FILE_OK, file_systems_[app_id]->Remove( CreateURL(app_id, path), @@ -424,7 +424,7 @@ itr != remote_entries.end(); ++itr) { const google_apis::FileResource& remote_entry = **itr; - EXPECT_FALSE(ContainsKey(app_root_by_title, remote_entry.title())); + EXPECT_FALSE(base::ContainsKey(app_root_by_title, remote_entry.title())); app_root_by_title[remote_entry.title()] = *itr; } @@ -434,7 +434,7 @@ const std::string& app_id = itr->first; SCOPED_TRACE(testing::Message() << "Verifying app: " << app_id); CannedSyncableFileSystem* file_system = itr->second; - ASSERT_TRUE(ContainsKey(app_root_by_title, app_id)); + ASSERT_TRUE(base::ContainsKey(app_root_by_title, app_id)); VerifyConsistencyForFolder( app_id, base::FilePath(), app_root_by_title[app_id]->file_id(), @@ -456,7 +456,8 @@ remote_entry_by_title; for (size_t i = 0; i < remote_entries.size(); ++i) { google_apis::FileResource* remote_entry = remote_entries[i]; - EXPECT_FALSE(ContainsKey(remote_entry_by_title, remote_entry->title())) + EXPECT_FALSE( + base::ContainsKey(remote_entry_by_title, remote_entry->title())) << "title: " << remote_entry->title(); remote_entry_by_title[remote_entry->title()] = remote_entry; } @@ -475,7 +476,7 @@ storage::VirtualPath::BaseName(entry_url.path()).AsUTF8Unsafe(); SCOPED_TRACE(testing::Message() << "Verifying entry: " << title); - ASSERT_TRUE(ContainsKey(remote_entry_by_title, title)); + ASSERT_TRUE(base::ContainsKey(remote_entry_by_title, title)); const google_apis::FileResource& remote_entry = *remote_entry_by_title[title]; if (local_entry.is_directory) { @@ -512,7 +513,7 @@ } size_t CountLocalFile(const std::string& app_id) { - if (!ContainsKey(file_systems_, app_id)) + if (!base::ContainsKey(file_systems_, app_id)) return 0; CannedSyncableFileSystem* file_system = file_systems_[app_id]; @@ -544,7 +545,7 @@ SCOPED_TRACE(testing::Message() << "Verifying local file: " << "app_id = " << app_id << ", path = " << path); - ASSERT_TRUE(ContainsKey(file_systems_, app_id)); + ASSERT_TRUE(base::ContainsKey(file_systems_, app_id)); EXPECT_EQ(base::File::FILE_OK, file_systems_[app_id]->VerifyFile( CreateURL(app_id, path), content)); @@ -555,7 +556,7 @@ SCOPED_TRACE(testing::Message() << "Verifying local file: " << "app_id = " << app_id << ", path = " << path); - ASSERT_TRUE(ContainsKey(file_systems_, app_id)); + ASSERT_TRUE(base::ContainsKey(file_systems_, app_id)); EXPECT_EQ(base::File::FILE_OK, file_systems_[app_id]->DirectoryExists(CreateURL(app_id, path))); }
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_database.cc b/chrome/browser/sync_file_system/drive_backend/metadata_database.cc index a8ac38a..d131b39 100644 --- a/chrome/browser/sync_file_system/drive_backend/metadata_database.cc +++ b/chrome/browser/sync_file_system/drive_backend/metadata_database.cc
@@ -1436,7 +1436,7 @@ if (!parent_tracker.active()) continue; - if (ContainsKey(parents_to_exclude, parent_tracker.tracker_id())) + if (base::ContainsKey(parents_to_exclude, parent_tracker.tracker_id())) continue; CreateTrackerForParentAndFileMetadata(
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_database_index.cc b/chrome/browser/sync_file_system/drive_backend/metadata_database_index.cc index f3cd15aa..22820e3 100644 --- a/chrome/browser/sync_file_system/drive_backend/metadata_database_index.cc +++ b/chrome/browser/sync_file_system/drive_backend/metadata_database_index.cc
@@ -170,7 +170,7 @@ ScopedVector<FileTracker> reachable_trackers; for (size_t i = 0; i < contents->file_trackers.size(); ++i) { FileTracker* tracker = contents->file_trackers[i]; - if (ContainsKey(visited_trackers, tracker->tracker_id())) { + if (base::ContainsKey(visited_trackers, tracker->tracker_id())) { reachable_trackers.push_back(tracker); contents->file_trackers[i] = nullptr; } else { @@ -188,7 +188,7 @@ ScopedVector<FileMetadata> referred_file_metadata; for (size_t i = 0; i < contents->file_metadata.size(); ++i) { FileMetadata* metadata = contents->file_metadata[i]; - if (ContainsKey(referred_file_ids, metadata->file_id())) { + if (base::ContainsKey(referred_file_ids, metadata->file_id())) { referred_file_metadata.push_back(metadata); contents->file_metadata[i] = nullptr; } else { @@ -522,7 +522,7 @@ DVLOG(3) << " Add to app_root_by_app_id_: " << new_tracker.app_id(); DCHECK(new_tracker.active()); - DCHECK(!ContainsKey(app_root_by_app_id_, new_tracker.app_id())); + DCHECK(!base::ContainsKey(app_root_by_app_id_, new_tracker.app_id())); app_root_by_app_id_[new_tracker.app_id()] = new_tracker.tracker_id(); } @@ -534,7 +534,7 @@ if (IsAppRoot(old_tracker) && !IsAppRoot(new_tracker)) { DCHECK(old_tracker.active()); DCHECK(!new_tracker.active()); - DCHECK(ContainsKey(app_root_by_app_id_, old_tracker.app_id())); + DCHECK(base::ContainsKey(app_root_by_app_id_, old_tracker.app_id())); DVLOG(3) << " Remove from app_root_by_app_id_: " << old_tracker.app_id(); @@ -542,7 +542,7 @@ } else if (!IsAppRoot(old_tracker) && IsAppRoot(new_tracker)) { DCHECK(!old_tracker.active()); DCHECK(new_tracker.active()); - DCHECK(!ContainsKey(app_root_by_app_id_, new_tracker.app_id())); + DCHECK(!base::ContainsKey(app_root_by_app_id_, new_tracker.app_id())); DVLOG(3) << " Add to app_root_by_app_id_: " << new_tracker.app_id(); @@ -554,7 +554,7 @@ const FileTracker& tracker) { if (IsAppRoot(tracker)) { DCHECK(tracker.active()); - DCHECK(ContainsKey(app_root_by_app_id_, tracker.app_id())); + DCHECK(base::ContainsKey(app_root_by_app_id_, tracker.app_id())); DVLOG(3) << " Remove from app_root_by_app_id_: " << tracker.app_id(); @@ -569,7 +569,8 @@ trackers_by_file_id_[new_tracker.file_id()].Insert(new_tracker); if (trackers_by_file_id_[new_tracker.file_id()].size() > 1) { - DVLOG_IF(3, !ContainsKey(multi_tracker_file_ids_, new_tracker.file_id())) + DVLOG_IF(3, + !base::ContainsKey(multi_tracker_file_ids_, new_tracker.file_id())) << " Add to multi_tracker_file_ids_: " << new_tracker.file_id(); multi_tracker_file_ids_.insert(new_tracker.file_id()); } @@ -582,7 +583,7 @@ DCHECK_EQ(old_tracker.file_id(), new_tracker.file_id()); std::string file_id = new_tracker.file_id(); - DCHECK(ContainsKey(trackers_by_file_id_, file_id)); + DCHECK(base::ContainsKey(trackers_by_file_id_, file_id)); if (old_tracker.active() && !new_tracker.active()) trackers_by_file_id_[file_id].Deactivate(new_tracker.tracker_id()); @@ -604,7 +605,7 @@ found->second.Erase(tracker.tracker_id()); if (trackers_by_file_id_[tracker.file_id()].size() <= 1) { - DVLOG_IF(3, ContainsKey(multi_tracker_file_ids_, tracker.file_id())) + DVLOG_IF(3, base::ContainsKey(multi_tracker_file_ids_, tracker.file_id())) << " Remove from multi_tracker_file_ids_: " << tracker.file_id(); multi_tracker_file_ids_.erase(tracker.file_id()); } @@ -625,8 +626,8 @@ if (trackers_by_parent_and_title_[parent][title].size() > 1 && !title.empty()) { - DVLOG_IF(3, !ContainsKey(multi_backing_file_paths_, - ParentIDAndTitle(parent, title))) + DVLOG_IF(3, !base::ContainsKey(multi_backing_file_paths_, + ParentIDAndTitle(parent, title))) << " Add to multi_backing_file_paths_: " << parent << " " << title; multi_backing_file_paths_.insert(ParentIDAndTitle(parent, title)); } @@ -667,17 +668,17 @@ if (trackers_by_parent_and_title_[parent][old_title].size() <= 1 && !old_title.empty()) { - DVLOG_IF(3, ContainsKey(multi_backing_file_paths_, - ParentIDAndTitle(parent, old_title))) - << " Remove from multi_backing_file_paths_: " - << parent << " " << old_title; + DVLOG_IF(3, base::ContainsKey(multi_backing_file_paths_, + ParentIDAndTitle(parent, old_title))) + << " Remove from multi_backing_file_paths_: " << parent << " " + << old_title; multi_backing_file_paths_.erase(ParentIDAndTitle(parent, old_title)); } if (trackers_by_parent_and_title_[parent][title].size() > 1 && !title.empty()) { - DVLOG_IF(3, !ContainsKey(multi_backing_file_paths_, - ParentIDAndTitle(parent, title))) + DVLOG_IF(3, !base::ContainsKey(multi_backing_file_paths_, + ParentIDAndTitle(parent, title))) << " Add to multi_backing_file_paths_: " << parent << " " << title; multi_backing_file_paths_.insert(ParentIDAndTitle(parent, title)); } @@ -697,8 +698,8 @@ int64_t parent = tracker.parent_tracker_id(); std::string title = GetTrackerTitle(tracker); - DCHECK(ContainsKey(trackers_by_parent_and_title_, parent)); - DCHECK(ContainsKey(trackers_by_parent_and_title_[parent], title)); + DCHECK(base::ContainsKey(trackers_by_parent_and_title_, parent)); + DCHECK(base::ContainsKey(trackers_by_parent_and_title_[parent], title)); DVLOG(3) << " Remove from trackers_by_parent_and_title_: " << parent << " " << title; @@ -707,10 +708,10 @@ if (trackers_by_parent_and_title_[parent][title].size() <= 1 && !title.empty()) { - DVLOG_IF(3, ContainsKey(multi_backing_file_paths_, - ParentIDAndTitle(parent, title))) - << " Remove from multi_backing_file_paths_: " - << parent << " " << title; + DVLOG_IF(3, base::ContainsKey(multi_backing_file_paths_, + ParentIDAndTitle(parent, title))) + << " Remove from multi_backing_file_paths_: " << parent << " " + << title; multi_backing_file_paths_.erase(ParentIDAndTitle(parent, title)); } @@ -723,8 +724,8 @@ void MetadataDatabaseIndex::AddToDirtyTrackerIndexes( const FileTracker& new_tracker) { - DCHECK(!ContainsKey(dirty_trackers_, new_tracker.tracker_id())); - DCHECK(!ContainsKey(demoted_dirty_trackers_, new_tracker.tracker_id())); + DCHECK(!base::ContainsKey(dirty_trackers_, new_tracker.tracker_id())); + DCHECK(!base::ContainsKey(demoted_dirty_trackers_, new_tracker.tracker_id())); if (new_tracker.dirty()) { DVLOG(3) << " Add to dirty_trackers_: " << new_tracker.tracker_id(); @@ -739,16 +740,16 @@ int64_t tracker_id = new_tracker.tracker_id(); if (old_tracker.dirty() && !new_tracker.dirty()) { - DCHECK(ContainsKey(dirty_trackers_, tracker_id) || - ContainsKey(demoted_dirty_trackers_, tracker_id)); + DCHECK(base::ContainsKey(dirty_trackers_, tracker_id) || + base::ContainsKey(demoted_dirty_trackers_, tracker_id)); DVLOG(3) << " Remove from dirty_trackers_: " << tracker_id; dirty_trackers_.erase(tracker_id); demoted_dirty_trackers_.erase(tracker_id); } else if (!old_tracker.dirty() && new_tracker.dirty()) { - DCHECK(!ContainsKey(dirty_trackers_, tracker_id)); - DCHECK(!ContainsKey(demoted_dirty_trackers_, tracker_id)); + DCHECK(!base::ContainsKey(dirty_trackers_, tracker_id)); + DCHECK(!base::ContainsKey(demoted_dirty_trackers_, tracker_id)); DVLOG(3) << " Add to dirty_trackers_: " << tracker_id; @@ -760,8 +761,8 @@ const FileTracker& tracker) { if (tracker.dirty()) { int64_t tracker_id = tracker.tracker_id(); - DCHECK(ContainsKey(dirty_trackers_, tracker_id) || - ContainsKey(demoted_dirty_trackers_, tracker_id)); + DCHECK(base::ContainsKey(dirty_trackers_, tracker_id) || + base::ContainsKey(demoted_dirty_trackers_, tracker_id)); DVLOG(3) << " Remove from dirty_trackers_: " << tracker_id; dirty_trackers_.erase(tracker_id);
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_database_index_on_disk.cc b/chrome/browser/sync_file_system/drive_backend/metadata_database_index_on_disk.cc index d9bcd7c..41f5d7e 100644 --- a/chrome/browser/sync_file_system/drive_backend/metadata_database_index_on_disk.cc +++ b/chrome/browser/sync_file_system/drive_backend/metadata_database_index_on_disk.cc
@@ -223,7 +223,7 @@ continue; } - if (ContainsKey(visited_trackers, tracker->tracker_id())) { + if (base::ContainsKey(visited_trackers, tracker->tracker_id())) { referred_file_ids.insert(tracker->file_id()); } else { PutFileTrackerDeletionToDB(tracker->tracker_id(), db); @@ -245,7 +245,7 @@ continue; } - if (!ContainsKey(referred_file_ids, metadata->file_id())) + if (!base::ContainsKey(referred_file_ids, metadata->file_id())) PutFileMetadataDeletionToDB(metadata->file_id(), db); } }
diff --git a/chrome/browser/sync_file_system/drive_backend/tracker_id_set.cc b/chrome/browser/sync_file_system/drive_backend/tracker_id_set.cc index 53ea1c9..5e039f924 100644 --- a/chrome/browser/sync_file_system/drive_backend/tracker_id_set.cc +++ b/chrome/browser/sync_file_system/drive_backend/tracker_id_set.cc
@@ -40,7 +40,7 @@ } void TrackerIDSet::Erase(int64_t tracker_id) { - DCHECK(ContainsKey(tracker_ids_, tracker_id)); + DCHECK(base::ContainsKey(tracker_ids_, tracker_id)); if (active_tracker_ == tracker_id) active_tracker_ = 0; @@ -49,13 +49,13 @@ void TrackerIDSet::Activate(int64_t tracker_id) { DCHECK(!active_tracker_); - DCHECK(ContainsKey(tracker_ids_, tracker_id)); + DCHECK(base::ContainsKey(tracker_ids_, tracker_id)); active_tracker_ = tracker_id; } void TrackerIDSet::Deactivate(int64_t tracker_id) { DCHECK_EQ(active_tracker_, tracker_id); - DCHECK(ContainsKey(tracker_ids_, tracker_id)); + DCHECK(base::ContainsKey(tracker_ids_, tracker_id)); active_tracker_ = 0; }
diff --git a/chrome/browser/sync_file_system/local/local_file_change_tracker.cc b/chrome/browser/sync_file_system/local/local_file_change_tracker.cc index 49aacd9..e18fb1c 100644 --- a/chrome/browser/sync_file_system/local/local_file_change_tracker.cc +++ b/chrome/browser/sync_file_system/local/local_file_change_tracker.cc
@@ -94,8 +94,10 @@ void LocalFileChangeTracker::OnStartUpdate(const FileSystemURL& url) { DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); - if (ContainsKey(changes_, url) || ContainsKey(demoted_changes_, url)) + if (base::ContainsKey(changes_, url) || + base::ContainsKey(demoted_changes_, url)) { return; + } // TODO(nhiroki): propagate the error code (see http://crbug.com/152127). MarkDirtyOnDatabase(url); } @@ -178,7 +180,7 @@ void LocalFileChangeTracker::CreateFreshMirrorForURL( const storage::FileSystemURL& url) { DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); - DCHECK(!ContainsKey(mirror_changes_, url)); + DCHECK(!base::ContainsKey(mirror_changes_, url)); mirror_changes_[url] = ChangeInfo(); } @@ -190,10 +192,12 @@ return; mirror_changes_.erase(found); - if (ContainsKey(changes_, url) || ContainsKey(demoted_changes_, url)) + if (base::ContainsKey(changes_, url) || + base::ContainsKey(demoted_changes_, url)) { MarkDirtyOnDatabase(url); - else + } else { ClearDirtyOnDatabase(url); + } UpdateNumChanges(); } @@ -206,11 +210,11 @@ return; } const ChangeInfo& info = found->second; - if (ContainsKey(demoted_changes_, url)) { - DCHECK(!ContainsKey(changes_, url)); + if (base::ContainsKey(demoted_changes_, url)) { + DCHECK(!base::ContainsKey(changes_, url)); demoted_changes_[url] = info; } else { - DCHECK(!ContainsKey(demoted_changes_, url)); + DCHECK(!base::ContainsKey(demoted_changes_, url)); change_seqs_[info.change_seq] = url; changes_[url] = info; } @@ -224,7 +228,7 @@ FileChangeMap::iterator found = changes_.find(url); if (found == changes_.end()) return; - DCHECK(!ContainsKey(demoted_changes_, url)); + DCHECK(!base::ContainsKey(demoted_changes_, url)); change_seqs_.erase(found->second.change_seq); demoted_changes_.insert(*found); changes_.erase(found); @@ -241,8 +245,8 @@ FileChangeList::List change_list = iter->second.change_list.list(); // Make sure that this URL is in no queues. - DCHECK(!ContainsKey(change_seqs_, iter->second.change_seq)); - DCHECK(!ContainsKey(changes_, url)); + DCHECK(!base::ContainsKey(change_seqs_, iter->second.change_seq)); + DCHECK(!base::ContainsKey(changes_, url)); change_seqs_[iter->second.change_seq] = url; changes_.insert(*iter); @@ -417,13 +421,13 @@ const FileSystemURL& url, const FileChange& change) { DCHECK(file_task_runner_->RunsTasksOnCurrentThread()); int change_seq = current_change_seq_number_++; - if (ContainsKey(demoted_changes_, url)) { + if (base::ContainsKey(demoted_changes_, url)) { RecordChangeToChangeMaps(url, change, change_seq, &demoted_changes_, nullptr); } else { RecordChangeToChangeMaps(url, change, change_seq, &changes_, &change_seqs_); } - if (ContainsKey(mirror_changes_, url)) { + if (base::ContainsKey(mirror_changes_, url)) { RecordChangeToChangeMaps(url, change, change_seq, &mirror_changes_, nullptr); }
diff --git a/chrome/browser/sync_file_system/local/local_file_change_tracker_unittest.cc b/chrome/browser/sync_file_system/local/local_file_change_tracker_unittest.cc index 829cc0f..fb2964d 100644 --- a/chrome/browser/sync_file_system/local/local_file_change_tracker_unittest.cc +++ b/chrome/browser/sync_file_system/local/local_file_change_tracker_unittest.cc
@@ -178,14 +178,14 @@ file_system_.GetChangedURLsInTracker(&urls); EXPECT_EQ(5U, urls.size()); - EXPECT_TRUE(ContainsKey(urls, URL(kPath1))); - EXPECT_TRUE(ContainsKey(urls, URL(kPath2))); - EXPECT_TRUE(ContainsKey(urls, URL(kPath3))); - EXPECT_TRUE(ContainsKey(urls, URL(kPath4))); - EXPECT_TRUE(ContainsKey(urls, URL(kPath5))); + EXPECT_TRUE(base::ContainsKey(urls, URL(kPath1))); + EXPECT_TRUE(base::ContainsKey(urls, URL(kPath2))); + EXPECT_TRUE(base::ContainsKey(urls, URL(kPath3))); + EXPECT_TRUE(base::ContainsKey(urls, URL(kPath4))); + EXPECT_TRUE(base::ContainsKey(urls, URL(kPath5))); // Changes for kPath0 must have been offset and removed. - EXPECT_FALSE(ContainsKey(urls, URL(kPath0))); + EXPECT_FALSE(base::ContainsKey(urls, URL(kPath0))); // GetNextChangedURLs only returns up to max_urls (i.e. 3) urls. std::deque<FileSystemURL> urls_to_process; @@ -670,8 +670,8 @@ ASSERT_EQ(2U, urls.size()); // The exact order of recursive removal cannot be determined. - EXPECT_TRUE(ContainsKey(urls, URL(kPath1))); - EXPECT_TRUE(ContainsKey(urls, URL(kPath2))); + EXPECT_TRUE(base::ContainsKey(urls, URL(kPath1))); + EXPECT_TRUE(base::ContainsKey(urls, URL(kPath2))); } TEST_F(LocalFileChangeTrackerTest, ResetForFileSystem) { @@ -694,10 +694,10 @@ FileSystemURLSet urls; GetAllChangedURLs(&urls); EXPECT_EQ(4u, urls.size()); - EXPECT_TRUE(ContainsKey(urls, URL(kPath0))); - EXPECT_TRUE(ContainsKey(urls, URL(kPath1))); - EXPECT_TRUE(ContainsKey(urls, URL(kPath2))); - EXPECT_TRUE(ContainsKey(urls, URL(kPath3))); + EXPECT_TRUE(base::ContainsKey(urls, URL(kPath0))); + EXPECT_TRUE(base::ContainsKey(urls, URL(kPath1))); + EXPECT_TRUE(base::ContainsKey(urls, URL(kPath2))); + EXPECT_TRUE(base::ContainsKey(urls, URL(kPath3))); // Reset all changes for the file system. change_tracker()->ResetForFileSystem(
diff --git a/chrome/browser/sync_file_system/local/local_file_sync_context.cc b/chrome/browser/sync_file_system/local/local_file_sync_context.cc index 3ecc82f..db114e2 100644 --- a/chrome/browser/sync_file_system/local/local_file_sync_context.cc +++ b/chrome/browser/sync_file_system/local/local_file_sync_context.cc
@@ -68,7 +68,7 @@ FileSystemContext* file_system_context, const SyncStatusCallback& callback) { DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); - if (ContainsKey(file_system_contexts_, file_system_context)) { + if (base::ContainsKey(file_system_contexts_, file_system_context)) { // The context has been already initialized. Just dispatch the callback // with SYNC_STATUS_OK. ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, SYNC_STATUS_OK)); @@ -741,8 +741,8 @@ return; } DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); - DCHECK(!ContainsKey(file_system_contexts_, file_system_context)); - DCHECK(ContainsKey(pending_initialize_callbacks_, file_system_context)); + DCHECK(!base::ContainsKey(file_system_contexts_, file_system_context)); + DCHECK(base::ContainsKey(pending_initialize_callbacks_, file_system_context)); SyncFileSystemBackend* backend = SyncFileSystemBackend::GetBackend(file_system_context);
diff --git a/chrome/browser/sync_file_system/local/local_file_sync_context_unittest.cc b/chrome/browser/sync_file_system/local/local_file_sync_context_unittest.cc index 3484ef7..54e7e17 100644 --- a/chrome/browser/sync_file_system/local/local_file_sync_context_unittest.cc +++ b/chrome/browser/sync_file_system/local/local_file_sync_context_unittest.cc
@@ -410,7 +410,7 @@ FileSystemURLSet urls; file_system.GetChangedURLsInTracker(&urls); ASSERT_EQ(1U, urls.size()); - EXPECT_TRUE(ContainsKey(urls, kURL)); + EXPECT_TRUE(base::ContainsKey(urls, kURL)); // Finishing the test. sync_context_->ShutdownOnUIThread(); @@ -452,7 +452,7 @@ FileSystemURLSet urls; file_system1.GetChangedURLsInTracker(&urls); ASSERT_EQ(1U, urls.size()); - EXPECT_TRUE(ContainsKey(urls, kURL1)); + EXPECT_TRUE(base::ContainsKey(urls, kURL1)); // file_system1's tracker must have no change. urls.clear(); @@ -466,13 +466,13 @@ urls.clear(); file_system1.GetChangedURLsInTracker(&urls); ASSERT_EQ(1U, urls.size()); - EXPECT_TRUE(ContainsKey(urls, kURL1)); + EXPECT_TRUE(base::ContainsKey(urls, kURL1)); // file_system2's tracker now must have the change for kURL2. urls.clear(); file_system2.GetChangedURLsInTracker(&urls); ASSERT_EQ(1U, urls.size()); - EXPECT_TRUE(ContainsKey(urls, kURL2)); + EXPECT_TRUE(base::ContainsKey(urls, kURL2)); SyncFileMetadata metadata; FileChangeList changes; @@ -632,9 +632,9 @@ FileSystemURLSet urls; file_system.GetChangedURLsInTracker(&urls); ASSERT_EQ(3U, urls.size()); - ASSERT_TRUE(ContainsKey(urls, kFile)); - ASSERT_TRUE(ContainsKey(urls, kDir)); - ASSERT_TRUE(ContainsKey(urls, kChild)); + ASSERT_TRUE(base::ContainsKey(urls, kFile)); + ASSERT_TRUE(base::ContainsKey(urls, kDir)); + ASSERT_TRUE(base::ContainsKey(urls, kChild)); for (FileSystemURLSet::iterator iter = urls.begin(); iter != urls.end(); ++iter) { file_system.ClearChangeForURLInTracker(*iter); @@ -794,7 +794,7 @@ FileSystemURLSet urls; file_system.GetChangedURLsInTracker(&urls); ASSERT_EQ(1U, urls.size()); - EXPECT_TRUE(ContainsKey(urls, kFile1)); + EXPECT_TRUE(base::ContainsKey(urls, kFile1)); file_system.ClearChangeForURLInTracker(*urls.begin()); // Prepare temporary files which represent the remote file data.
diff --git a/chrome/browser/sync_file_system/local/local_file_sync_service.cc b/chrome/browser/sync_file_system/local/local_file_sync_service.cc index e62b953..cc6dad4 100644 --- a/chrome/browser/sync_file_system/local/local_file_sync_service.cc +++ b/chrome/browser/sync_file_system/local/local_file_sync_service.cc
@@ -65,7 +65,7 @@ next_ = change_count_map_.begin(); DCHECK_NE(0, next_->second); *origin = next_++->first; - if (!ContainsKey(disabled_origins_, *origin)) + if (!base::ContainsKey(disabled_origins_, *origin)) return true; } while (next_ != begin); return false; @@ -75,7 +75,7 @@ int64_t num_changes = 0; for (Map::const_iterator iter = change_count_map_.begin(); iter != change_count_map_.end(); ++iter) { - if (ContainsKey(disabled_origins_, iter->first)) + if (base::ContainsKey(disabled_origins_, iter->first)) continue; num_changes += iter->second; } @@ -161,7 +161,7 @@ return; } DCHECK(!origin.is_empty()); - DCHECK(ContainsKey(origin_to_contexts_, origin)); + DCHECK(base::ContainsKey(origin_to_contexts_, origin)); DVLOG(1) << "Starting ProcessLocalChange"; @@ -184,7 +184,7 @@ void LocalFileSyncService::HasPendingLocalChanges( const FileSystemURL& url, const HasPendingLocalChangeCallback& callback) { - if (!ContainsKey(origin_to_contexts_, url.origin())) { + if (!base::ContainsKey(origin_to_contexts_, url.origin())) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(callback, SYNC_FILE_ERROR_INVALID_URL, false)); @@ -214,7 +214,7 @@ void LocalFileSyncService::GetLocalFileMetadata( const FileSystemURL& url, const SyncFileMetadataCallback& callback) { - DCHECK(ContainsKey(origin_to_contexts_, url.origin())); + DCHECK(base::ContainsKey(origin_to_contexts_, url.origin())); sync_context_->GetFileMetadata(origin_to_contexts_[url.origin()], url, callback); } @@ -224,7 +224,7 @@ const PrepareChangeCallback& callback) { DVLOG(1) << "PrepareForProcessRemoteChange: " << url.DebugString(); - if (!ContainsKey(origin_to_contexts_, url.origin())) { + if (!base::ContainsKey(origin_to_contexts_, url.origin())) { // This could happen if a remote sync is triggered for the app that hasn't // been initialized in this service. DCHECK(profile_); @@ -259,7 +259,7 @@ return; } - DCHECK(ContainsKey(origin_to_contexts_, url.origin())); + DCHECK(base::ContainsKey(origin_to_contexts_, url.origin())); sync_context_->PrepareForSync( origin_to_contexts_[url.origin()], url, LocalFileSyncContext::SYNC_EXCLUSIVE, @@ -271,7 +271,7 @@ const base::FilePath& local_path, const FileSystemURL& url, const SyncStatusCallback& callback) { - DCHECK(ContainsKey(origin_to_contexts_, url.origin())); + DCHECK(base::ContainsKey(origin_to_contexts_, url.origin())); util::Log(logging::LOG_VERBOSE, FROM_HERE, "[Remote -> Local] ApplyRemoteChange: %s on %s", change.DebugString().c_str(), @@ -288,7 +288,7 @@ const FileSystemURL& url, bool clear_local_changes, const base::Closure& completion_callback) { - DCHECK(ContainsKey(origin_to_contexts_, url.origin())); + DCHECK(base::ContainsKey(origin_to_contexts_, url.origin())); sync_context_->FinalizeExclusiveSync( origin_to_contexts_[url.origin()], url, clear_local_changes, completion_callback); @@ -298,7 +298,7 @@ const FileSystemURL& url, const FileChange& change, const SyncStatusCallback& callback) { - DCHECK(ContainsKey(origin_to_contexts_, url.origin())); + DCHECK(base::ContainsKey(origin_to_contexts_, url.origin())); sync_context_->RecordFakeLocalChange(origin_to_contexts_[url.origin()], url, change, callback); } @@ -309,7 +309,7 @@ for (std::set<GURL>::const_iterator iter = origins.begin(); iter != origins.end(); ++iter) { const GURL& origin = *iter; - if (!ContainsKey(origin_to_contexts_, origin)) { + if (!base::ContainsKey(origin_to_contexts_, origin)) { // This could happen if this is called for apps/origins that haven't // been initialized yet, or for apps/origins that are disabled. // (Local change tracker could call this for uninitialized origins @@ -334,7 +334,7 @@ } void LocalFileSyncService::SetOriginEnabled(const GURL& origin, bool enabled) { - if (!ContainsKey(origin_to_contexts_, origin)) + if (!base::ContainsKey(origin_to_contexts_, origin)) return; origin_change_map_.SetOriginEnabled(origin, enabled); } @@ -468,7 +468,7 @@ const FileSystemURL& url = sync_file_info.url; if (status != SYNC_STATUS_OK || changes.empty()) { - DCHECK(ContainsKey(origin_to_contexts_, url.origin())); + DCHECK(base::ContainsKey(origin_to_contexts_, url.origin())); sync_context_->FinalizeSnapshotSync( origin_to_contexts_[url.origin()], url, status, base::Bind(callback, status, url));
diff --git a/chrome/browser/sync_file_system/local/local_file_sync_service_unittest.cc b/chrome/browser/sync_file_system/local/local_file_sync_service_unittest.cc index 723a77f..41c81cac 100644 --- a/chrome/browser/sync_file_system/local/local_file_sync_service_unittest.cc +++ b/chrome/browser/sync_file_system/local/local_file_sync_service_unittest.cc
@@ -634,7 +634,7 @@ GURL origin; while (!all_origins.empty()) { ASSERT_TRUE(NextOriginToProcess(&origin)); - ASSERT_TRUE(ContainsKey(all_origins, origin)); + ASSERT_TRUE(base::ContainsKey(all_origins, origin)); all_origins.erase(origin); } @@ -647,7 +647,7 @@ all_origins.insert(kOrigin3); while (!all_origins.empty()) { ASSERT_TRUE(NextOriginToProcess(&origin)); - ASSERT_TRUE(ContainsKey(all_origins, origin)); + ASSERT_TRUE(base::ContainsKey(all_origins, origin)); all_origins.erase(origin); } @@ -658,7 +658,7 @@ all_origins.insert(kOrigin3); while (!all_origins.empty()) { ASSERT_TRUE(NextOriginToProcess(&origin)); - ASSERT_TRUE(ContainsKey(all_origins, origin)); + ASSERT_TRUE(base::ContainsKey(all_origins, origin)); all_origins.erase(origin); } @@ -669,7 +669,7 @@ all_origins.insert(kOrigins, kOrigins + arraysize(kOrigins)); while (!all_origins.empty()) { ASSERT_TRUE(NextOriginToProcess(&origin)); - ASSERT_TRUE(ContainsKey(all_origins, origin)); + ASSERT_TRUE(base::ContainsKey(all_origins, origin)); all_origins.erase(origin); } } @@ -694,7 +694,7 @@ GURL origin; while (!all_origins.empty()) { ASSERT_TRUE(NextOriginToProcess(&origin)); - ASSERT_TRUE(ContainsKey(all_origins, origin)); + ASSERT_TRUE(base::ContainsKey(all_origins, origin)); all_origins.erase(origin); } @@ -706,7 +706,7 @@ all_origins.insert(kOrigin3); while (!all_origins.empty()) { ASSERT_TRUE(NextOriginToProcess(&origin)); - ASSERT_TRUE(ContainsKey(all_origins, origin)); + ASSERT_TRUE(base::ContainsKey(all_origins, origin)); all_origins.erase(origin); } @@ -726,7 +726,7 @@ all_origins.insert(kOrigin3); while (!all_origins.empty()) { ASSERT_TRUE(NextOriginToProcess(&origin)); - ASSERT_TRUE(ContainsKey(all_origins, origin)); + ASSERT_TRUE(base::ContainsKey(all_origins, origin)); all_origins.erase(origin); } }
diff --git a/chrome/browser/sync_file_system/local/local_file_sync_status.cc b/chrome/browser/sync_file_system/local/local_file_sync_status.cc index 953c374e..b26831a 100644 --- a/chrome/browser/sync_file_system/local/local_file_sync_status.cc +++ b/chrome/browser/sync_file_system/local/local_file_sync_status.cc
@@ -61,7 +61,7 @@ // Check if any ancestor of |normalized_path| is in |writing_|. while (true) { - if (ContainsKey(paths, normalized_path)) + if (base::ContainsKey(paths, normalized_path)) return true; if (storage::VirtualPath::IsRootPath(normalized_path))
diff --git a/chrome/browser/sync_file_system/local/syncable_file_system_unittest.cc b/chrome/browser/sync_file_system/local/syncable_file_system_unittest.cc index 15384ff..ec43d33 100644 --- a/chrome/browser/sync_file_system/local/syncable_file_system_unittest.cc +++ b/chrome/browser/sync_file_system/local/syncable_file_system_unittest.cc
@@ -202,9 +202,9 @@ file_system_.GetChangedURLsInTracker(&urls); EXPECT_EQ(3U, urls.size()); - EXPECT_TRUE(ContainsKey(urls, URL(kPath0))); - EXPECT_TRUE(ContainsKey(urls, URL(kPath1))); - EXPECT_TRUE(ContainsKey(urls, URL(kPath2))); + EXPECT_TRUE(base::ContainsKey(urls, URL(kPath0))); + EXPECT_TRUE(base::ContainsKey(urls, URL(kPath1))); + EXPECT_TRUE(base::ContainsKey(urls, URL(kPath2))); VerifyAndClearChange(URL(kPath0), FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, @@ -236,9 +236,9 @@ // kPath0 and its all chidren (kPath1 and kPath2) must have been deleted. EXPECT_EQ(3U, urls.size()); - EXPECT_TRUE(ContainsKey(urls, URL(kPath0))); - EXPECT_TRUE(ContainsKey(urls, URL(kPath1))); - EXPECT_TRUE(ContainsKey(urls, URL(kPath2))); + EXPECT_TRUE(base::ContainsKey(urls, URL(kPath0))); + EXPECT_TRUE(base::ContainsKey(urls, URL(kPath1))); + EXPECT_TRUE(base::ContainsKey(urls, URL(kPath2))); VerifyAndClearChange(URL(kPath0), FileChange(FileChange::FILE_CHANGE_DELETE,
diff --git a/chrome/browser/sync_file_system/subtree_set.cc b/chrome/browser/sync_file_system/subtree_set.cc index 6d135e59..19a64f38 100644 --- a/chrome/browser/sync_file_system/subtree_set.cc +++ b/chrome/browser/sync_file_system/subtree_set.cc
@@ -30,8 +30,8 @@ storage::VirtualPath::GetNormalizedFilePath(subtree_root); // Check if |subtree_root| contains any of subtrees in the container. - if (ContainsKey(inclusive_ancestors_of_subtree_roots_, - normalized_subtree_root)) + if (base::ContainsKey(inclusive_ancestors_of_subtree_roots_, + normalized_subtree_root)) return false; base::FilePath path(normalized_subtree_root);
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 43741c9..57e0b765 100644 --- a/chrome/browser/sync_file_system/sync_file_system_service.cc +++ b/chrome/browser/sync_file_system/sync_file_system_service.cc
@@ -33,7 +33,7 @@ #include "chrome/browser/sync_file_system/sync_status_code.h" #include "chrome/browser/sync_file_system/syncable_file_system_util.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_service.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/storage_partition.h" #include "extensions/browser/extension_prefs.h"
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 8255d6a..d9435cd9 100644 --- a/chrome/browser/sync_file_system/sync_file_system_service.h +++ b/chrome/browser/sync_file_system/sync_file_system_service.h
@@ -22,7 +22,7 @@ #include "chrome/browser/sync_file_system/sync_service_state.h" #include "chrome/browser/sync_file_system/task_logger.h" #include "components/keyed_service/core/keyed_service.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/sync_service_observer.h" #include "extensions/browser/extension_registry_observer.h" #include "url/gurl.h"
diff --git a/chrome/browser/sync_file_system/task_logger.cc b/chrome/browser/sync_file_system/task_logger.cc index 00e2196a..fcfa16d 100644 --- a/chrome/browser/sync_file_system/task_logger.cc +++ b/chrome/browser/sync_file_system/task_logger.cc
@@ -53,7 +53,7 @@ } void TaskLogger::ClearLog() { - STLDeleteContainerPointers(log_history_.begin(), log_history_.end()); + base::STLDeleteContainerPointers(log_history_.begin(), log_history_.end()); log_history_.clear(); }
diff --git a/chrome/browser/task_manager/mock_web_contents_task_manager.cc b/chrome/browser/task_manager/mock_web_contents_task_manager.cc index b322d1a5..612b6b2 100644 --- a/chrome/browser/task_manager/mock_web_contents_task_manager.cc +++ b/chrome/browser/task_manager/mock_web_contents_task_manager.cc
@@ -19,13 +19,13 @@ void MockWebContentsTaskManager::TaskAdded(Task* task) { DCHECK(task); - DCHECK(!ContainsValue(tasks_, task)); + DCHECK(!base::ContainsValue(tasks_, task)); tasks_.push_back(task); } void MockWebContentsTaskManager::TaskRemoved(Task* task) { DCHECK(task); - DCHECK(ContainsValue(tasks_, task)); + DCHECK(base::ContainsValue(tasks_, task)); tasks_.erase(std::find(tasks_.begin(), tasks_.end(), task)); }
diff --git a/chrome/browser/themes/browser_theme_pack.cc b/chrome/browser/themes/browser_theme_pack.cc index 59a1b7fd..66d2c63 100644 --- a/chrome/browser/themes/browser_theme_pack.cc +++ b/chrome/browser/themes/browser_theme_pack.cc
@@ -889,7 +889,7 @@ source_images_(NULL) { scale_factors_ = ui::GetSupportedScaleFactors(); // On Windows HiDPI SCALE_FACTOR_100P may not be supported by default. - if (!ContainsValue(scale_factors_, ui::SCALE_FACTOR_100P)) + if (!base::ContainsValue(scale_factors_, ui::SCALE_FACTOR_100P)) scale_factors_.push_back(ui::SCALE_FACTOR_100P); }
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 8df4dffb..59b95a9d 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -111,7 +111,7 @@ "//components/ssl_errors", "//components/startup_metric_utils/browser:lib", "//components/strings", - "//components/sync_driver", + "//components/sync", "//components/sync_sessions", "//components/toolbar", "//components/translate/core/browser", @@ -676,6 +676,8 @@ "passwords/manage_passwords_ui_controller_mock.h", "passwords/password_dialog_controller_mock.cc", "passwords/password_dialog_controller_mock.h", + "passwords/passwords_model_delegate_mock.cc", + "passwords/passwords_model_delegate_mock.h", ] }
diff --git a/chrome/browser/ui/android/connection_info_popup_android.cc b/chrome/browser/ui/android/connection_info_popup_android.cc index faea509a..9b0dea95 100644 --- a/chrome/browser/ui/android/connection_info_popup_android.cc +++ b/chrome/browser/ui/android/connection_info_popup_android.cc
@@ -195,8 +195,8 @@ void ConnectionInfoPopupAndroid::SetPermissionInfo( const PermissionInfoList& permission_info_list, const ChosenObjectInfoList& chosen_object_info_list) { - STLDeleteContainerPointers(chosen_object_info_list.begin(), - chosen_object_info_list.end()); + base::STLDeleteContainerPointers(chosen_object_info_list.begin(), + chosen_object_info_list.end()); NOTIMPLEMENTED(); }
diff --git a/chrome/browser/ui/android/context_menu_helper.cc b/chrome/browser/ui/android/context_menu_helper.cc index 5d6b16c..0d404fb 100644 --- a/chrome/browser/ui/android/context_menu_helper.cc +++ b/chrome/browser/ui/android/context_menu_helper.cc
@@ -18,6 +18,7 @@ #include "content/public/common/context_menu_params.h" #include "jni/ContextMenuHelper_jni.h" #include "jni/ContextMenuParams_jni.h" +#include "third_party/WebKit/public/web/WebContextMenuData.h" #include "ui/android/window_android.h" #include "ui/gfx/geometry/point.h" @@ -103,7 +104,8 @@ ConvertUTF16ToJavaString(env, params.title_text).obj(), image_was_fetched_lo_fi, ConvertUTF8ToJavaString(env, sanitizedReferrer.spec()).obj(), - params.referrer_policy); + params.referrer_policy, + params.media_flags & blink::WebContextMenuData::MediaCanSave); return jmenu_info; }
diff --git a/chrome/browser/ui/android/website_settings_popup_android.cc b/chrome/browser/ui/android/website_settings_popup_android.cc index 9281918..5aa0bf6 100644 --- a/chrome/browser/ui/android/website_settings_popup_android.cc +++ b/chrome/browser/ui/android/website_settings_popup_android.cc
@@ -112,14 +112,14 @@ user_specified_settings_to_display; for (const auto& permission : permission_info_list) { - if (ContainsValue(permissions_to_display, permission.type) && + if (base::ContainsValue(permissions_to_display, permission.type) && permission.setting != CONTENT_SETTING_DEFAULT) { user_specified_settings_to_display[permission.type] = permission.setting; } } for (const auto& permission : permissions_to_display) { - if (ContainsKey(user_specified_settings_to_display, permission)) { + if (base::ContainsKey(user_specified_settings_to_display, permission)) { base::string16 setting_title = WebsiteSettingsUI::PermissionTypeToUIString(permission);
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service.cc b/chrome/browser/ui/app_list/app_list_syncable_service.cc index b4d070a2..97db26e0 100644 --- a/chrome/browser/ui/app_list/app_list_syncable_service.cc +++ b/chrome/browser/ui/app_list/app_list_syncable_service.cc
@@ -263,7 +263,8 @@ model_observer_.reset(); model_pref_updater_.reset(); - STLDeleteContainerPairSecondPointers(sync_items_.begin(), sync_items_.end()); + base::STLDeleteContainerPairSecondPointers(sync_items_.begin(), + sync_items_.end()); } void AppListSyncableService::BuildModel() { @@ -622,7 +623,7 @@ SyncItem* sync_item = (iter++)->second; if (sync_item->item_type != sync_pb::AppListSpecifics::TYPE_FOLDER) continue; - if (!ContainsKey(parent_ids, sync_item->item_id)) + if (!base::ContainsKey(parent_ids, sync_item->item_id)) DeleteSyncItem(sync_item); } } @@ -945,7 +946,7 @@ AppListSyncableService::CreateSyncItem( const std::string& item_id, sync_pb::AppListSpecifics::AppListItemType item_type) { - DCHECK(!ContainsKey(sync_items_, item_id)); + DCHECK(!base::ContainsKey(sync_items_, item_id)); SyncItem* sync_item = new SyncItem(item_id, item_type); sync_items_[item_id] = sync_item; return sync_item;
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.cc b/chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.cc index fecaf94..86a0e7e 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.cc
@@ -30,6 +30,12 @@ is_sync_test_ = true; } +void ArcAppListPrefsFactory::RecreateServiceInstanceForTesting( + content::BrowserContext* context) { + Disassociate(context); + BuildServiceInstanceFor(context); +} + ArcAppListPrefsFactory::ArcAppListPrefsFactory() : BrowserContextKeyedServiceFactory( "ArcAppListPrefs",
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h b/chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h index 24f7fdd..388b7e4 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h +++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h
@@ -24,6 +24,7 @@ static ArcAppListPrefsFactory* GetInstance(); static void SetFactoryForSyncTest(); + void RecreateServiceInstanceForTesting(content::BrowserContext* context); private: friend struct base::DefaultSingletonTraits<ArcAppListPrefsFactory>;
diff --git a/chrome/browser/ui/app_list/arc/arc_app_test.cc b/chrome/browser/ui/app_list/arc/arc_app_test.cc index a1387bac..16b7b82 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_test.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_test.cc
@@ -11,7 +11,9 @@ #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h" #include "chromeos/chromeos_switches.h" +#include "chromeos/dbus/dbus_thread_manager.h" #include "components/arc/arc_bridge_service.h" #include "components/arc/test/fake_app_instance.h" #include "components/arc/test/fake_arc_bridge_service.h" @@ -47,6 +49,10 @@ } void ArcAppTest::SetUp(Profile* profile) { + if (!chromeos::DBusThreadManager::IsInitialized()) { + chromeos::DBusThreadManager::Initialize(); + dbus_thread_manager_initialized_ = true; + } base::CommandLine::ForCurrentProcess()->AppendSwitch( chromeos::switches::kEnableArc); DCHECK(!profile_); @@ -105,6 +111,13 @@ fake_shortcuts_.push_back(shortcutInfo); } + // A valid |arc_app_list_prefs_| is needed for the Arc bridge service and the + // Arc auth service. + arc_app_list_pref_ = ArcAppListPrefs::Get(profile_); + if (!arc_app_list_pref_) { + ArcAppListPrefsFactory::GetInstance()->RecreateServiceInstanceForTesting( + profile_); + } bridge_service_.reset(new arc::FakeArcBridgeService()); auth_service_.reset(new arc::ArcAuthService(bridge_service_.get())); @@ -126,6 +139,13 @@ void ArcAppTest::TearDown() { auth_service_.reset(); + if (dbus_thread_manager_initialized_) { + // DBusThreadManager may be initialized from other testing utility, + // such as ash::test::AshTestHelper::SetUp(), so Shutdown() only when + // it is initialized in ArcAppTest::SetUp(). + chromeos::DBusThreadManager::Shutdown(); + dbus_thread_manager_initialized_ = false; + } } void ArcAppTest::StopArcInstance() {
diff --git a/chrome/browser/ui/app_list/arc/arc_app_test.h b/chrome/browser/ui/app_list/arc/arc_app_test.h index a1b7162..326b9f15 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_test.h +++ b/chrome/browser/ui/app_list/arc/arc_app_test.h
@@ -94,6 +94,8 @@ std::vector<arc::mojom::ArcPackageInfo> fake_packages_; std::vector<arc::mojom::ShortcutInfo> fake_shortcuts_; + bool dbus_thread_manager_initialized_ = false; + DISALLOW_COPY_AND_ASSIGN(ArcAppTest); };
diff --git a/chrome/browser/ui/app_list/arc/arc_package_sync_data_type_controller.cc b/chrome/browser/ui/app_list/arc/arc_package_sync_data_type_controller.cc new file mode 100644 index 0000000..e1cd33e --- /dev/null +++ b/chrome/browser/ui/app_list/arc/arc_package_sync_data_type_controller.cc
@@ -0,0 +1,33 @@ +// Copyright 2016 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/app_list/arc/arc_package_sync_data_type_controller.h" + +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" +#include "components/arc/common/app.mojom.h" +#include "components/arc/instance_holder.h" +#include "content/public/browser/browser_thread.h" + +ArcPackageSyncDataTypeController::ArcPackageSyncDataTypeController( + syncer::ModelType type, + const base::Closure& error_callback, + sync_driver::SyncClient* sync_client, + Profile* profile) + : sync_driver::UIDataTypeController( + content::BrowserThread::GetTaskRunnerForThread( + content::BrowserThread::UI), + error_callback, + type, + sync_client), + profile_(profile) {} + +ArcPackageSyncDataTypeController::~ArcPackageSyncDataTypeController() {} + +bool ArcPackageSyncDataTypeController::ReadyForStart() const { + ArcAppListPrefs* prefs = ArcAppListPrefs::Get(profile_); + if (prefs && prefs->app_instance_holder()->instance()) + return true; + return false; +}
diff --git a/chrome/browser/ui/app_list/arc/arc_package_sync_data_type_controller.h b/chrome/browser/ui/app_list/arc/arc_package_sync_data_type_controller.h new file mode 100644 index 0000000..b953a9f --- /dev/null +++ b/chrome/browser/ui/app_list/arc/arc_package_sync_data_type_controller.h
@@ -0,0 +1,38 @@ +// Copyright 2016 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_APP_LIST_ARC_ARC_PACKAGE_SYNC_DATA_TYPE_CONTROLLER_H_ +#define CHROME_BROWSER_UI_APP_LIST_ARC_ARC_PACKAGE_SYNC_DATA_TYPE_CONTROLLER_H_ + +#include "base/macros.h" +#include "components/sync/driver/data_type_controller.h" +#include "components/sync/driver/ui_data_type_controller.h" + +namespace sync_driver { +class SyncClient; +} + +class Profile; + +// A UIDataTypeController for arc package sync datatypes, which enables or +// disables these types based on whether ArcAppInstance is ready. +class ArcPackageSyncDataTypeController + : public sync_driver::UIDataTypeController { + public: + ArcPackageSyncDataTypeController(syncer::ModelType type, + const base::Closure& error_callback, + sync_driver::SyncClient* sync_client, + Profile* profile); + + bool ReadyForStart() const override; + + private: + // DataTypeController is RefCounted. + ~ArcPackageSyncDataTypeController() override; + + Profile* const profile_; + + DISALLOW_COPY_AND_ASSIGN(ArcPackageSyncDataTypeController); +}; +#endif // CHROME_BROWSER_UI_APP_LIST_ARC_ARC_PACKAGE_SYNC_DATA_TYPE_CONTROLLER_H_
diff --git a/chrome/browser/ui/app_list/arc/arc_package_syncable_service.cc b/chrome/browser/ui/app_list/arc/arc_package_syncable_service.cc index 5e196ce..a06579a 100644 --- a/chrome/browser/ui/app_list/arc/arc_package_syncable_service.cc +++ b/chrome/browser/ui/app_list/arc/arc_package_syncable_service.cc
@@ -7,6 +7,7 @@ #include <unordered_set> #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #include "chrome/browser/ui/app_list/arc/arc_package_syncable_service_factory.h" #include "chrome/common/pref_names.h" @@ -14,6 +15,7 @@ #include "components/sync/api/sync_change_processor.h" #include "components/sync/api/sync_data.h" #include "components/sync/api/sync_merge_result.h" +#include "components/sync/driver/sync_service.h" #include "components/sync/protocol/sync.pb.h" namespace arc { @@ -23,6 +25,8 @@ using syncer::SyncChange; using ArcSyncItem = ArcPackageSyncableService::SyncItem; +constexpr int64_t kNoAndroidID = 0; + std::unique_ptr<ArcSyncItem> CreateSyncItemFromSyncSpecifics( const sync_pb::ArcPackageSpecifics& specifics) { return base::MakeUnique<ArcSyncItem>( @@ -132,7 +136,7 @@ std::unique_ptr<ArcSyncItem> sync_item( CreateSyncItemFromSyncData(sync_data)); const std::string& package_name = sync_item->package_name; - if (!ContainsKey(local_package_set, package_name)) { + if (!base::ContainsKey(local_package_set, package_name)) { pending_install_items_[package_name] = std::move(sync_item); InstallPackage(pending_install_items_[package_name].get()); } else { @@ -144,7 +148,7 @@ // Creates sync items for local unsynced packages. syncer::SyncChangeList change_list; for (const auto& local_package_name : local_packages) { - if (ContainsKey(sync_items_, local_package_name)) + if (base::ContainsKey(sync_items_, local_package_name)) continue; if (!ShouldSyncPackage(local_package_name)) @@ -165,6 +169,7 @@ sync_processor_.reset(); sync_error_handler_.reset(); + flare_.Reset(); sync_items_.clear(); pending_install_items_.clear(); @@ -215,6 +220,12 @@ bool ArcPackageSyncableService::SyncStarted() { if (sync_processor_.get()) return true; + + sync_driver::SyncService* sync_service = + ProfileSyncServiceFactory::GetSyncServiceForBrowserContext(profile_); + if (sync_service) + sync_service->ReenableDatatype(syncer::ARC_PACKAGE); + if (flare_.is_null()) { VLOG(2) << this << ": SyncStarted: Flare."; flare_ = sync_start_util::GetFlareForSyncableService(profile_->GetPath()); @@ -266,6 +277,13 @@ // Pending install item. Confirm install. if (install_iter != pending_install_items_.end()) { + if (install_iter->second->last_backup_android_id == kNoAndroidID && + package_info.last_backup_android_id != kNoAndroidID) { + pending_install_items_.erase(install_iter); + SendSyncChange(package_info, SyncChange::ACTION_UPDATE); + return; + } + sync_items_[package_name] = std::move(install_iter->second); pending_install_items_.erase(install_iter); return;
diff --git a/chrome/browser/ui/ash/app_sync_ui_state.h b/chrome/browser/ui/ash/app_sync_ui_state.h index 9b59c9c..c0382271 100644 --- a/chrome/browser/ui/ash/app_sync_ui_state.h +++ b/chrome/browser/ui/ash/app_sync_ui_state.h
@@ -10,7 +10,7 @@ #include "base/observer_list.h" #include "base/timer/timer.h" #include "components/keyed_service/core/keyed_service.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/sync_service_observer.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "extensions/browser/extension_registry_observer.h"
diff --git a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc index 497a50e9..8e752925 100644 --- a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc +++ b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.cc
@@ -134,7 +134,9 @@ return false; } - gfx::NativeWindow GetNativeWindow() const override { return nullptr; } + gfx::NativeWindow GetNativeWindow() const override { + return widget_ ? widget_->GetNativeWindow() : nullptr; + } gfx::Rect GetRestoredBounds() const override { NOTREACHED();
diff --git a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_item_controller.cc b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_item_controller.cc index fc3efbea..7524f30 100644 --- a/chrome/browser/ui/ash/launcher/arc_app_window_launcher_item_controller.cc +++ b/chrome/browser/ui/ash/launcher/arc_app_window_launcher_item_controller.cc
@@ -11,6 +11,8 @@ #include "chrome/browser/ui/ash/launcher/chrome_launcher_app_menu_item_v2app.h" #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" #include "chrome/browser/ui/ash/launcher/launcher_application_menu_item_model.h" +#include "ui/aura/window.h" +#include "ui/base/base_window.h" ArcAppWindowLauncherItemController::ArcAppWindowLauncherItemController( const std::string& arc_app_id, @@ -45,12 +47,14 @@ ArcAppWindowLauncherItemController::GetApplicationList(int event_flags) { ChromeLauncherAppMenuItems items = AppWindowLauncherItemController::GetApplicationList(event_flags); - for (size_t i = 0; i < windows().size(); ++i) { + size_t i = 0; + for (auto it = windows().begin(); it != windows().end(); ++it, ++i) { // TODO(khmel): resolve correct icon here. gfx::Image image; + aura::Window* window = (*it)->GetNativeWindow(); items.push_back(new ChromeLauncherAppMenuItemV2App( - GetTitle(), &image, app_id(), launcher_controller(), i, - i == 0 /* has_leading_separator */)); + (window ? window->title() : GetTitle()), &image, app_id(), + launcher_controller(), i, i == 0 /* has_leading_separator */)); } return items; }
diff --git a/chrome/browser/ui/ash/launcher/browser_status_monitor.cc b/chrome/browser/ui/ash/launcher/browser_status_monitor.cc index 34d06eae..022d24d 100644 --- a/chrome/browser/ui/ash/launcher/browser_status_monitor.cc +++ b/chrome/browser/ui/ash/launcher/browser_status_monitor.cc
@@ -122,8 +122,8 @@ browser_tab_strip_tracker_.StopObservingAndSendOnBrowserRemoved(); - STLDeleteContainerPairSecondPointers(webcontents_to_observer_map_.begin(), - webcontents_to_observer_map_.end()); + base::STLDeleteContainerPairSecondPointers( + webcontents_to_observer_map_.begin(), webcontents_to_observer_map_.end()); } void BrowserStatusMonitor::UpdateAppItemState(
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.cc index c48e651..9bd33e0 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl.cc
@@ -13,6 +13,7 @@ #include "ash/common/shelf/shelf_model.h" #include "ash/common/system/tray/system_tray_delegate.h" #include "ash/common/wm_shell.h" +#include "ash/common/wm_window.h" #include "ash/root_window_controller.h" #include "ash/shelf/shelf.h" #include "ash/shell.h" @@ -1309,7 +1310,7 @@ } void ChromeLauncherControllerImpl::SetShelfAutoHideBehaviorFromPrefs() { - for (auto* window : ash::Shell::GetAllRootWindows()) { + for (ash::WmWindow* window : ash::WmShell::Get()->GetAllRootWindows()) { ash::Shelf* shelf = ash::Shelf::ForWindow(window); if (shelf) { shelf->SetAutoHideBehavior(ash::launcher::GetShelfAutoHideBehaviorPref( @@ -1322,7 +1323,7 @@ if (!ash::ShelfWidget::ShelfAlignmentAllowed()) return; - for (auto* window : ash::Shell::GetAllRootWindows()) { + for (ash::WmWindow* window : ash::WmShell::Get()->GetAllRootWindows()) { ash::Shelf* shelf = ash::Shelf::ForWindow(window); if (shelf) { shelf->SetAlignment(ash::launcher::GetShelfAlignmentPref(
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_browsertest.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_browsertest.cc index 9a4ef82..4af3bfb 100644 --- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_browsertest.cc +++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_impl_browsertest.cc
@@ -6,6 +6,7 @@ #include <stddef.h> +#include "ash/aura/wm_window_aura.h" #include "ash/common/ash_switches.h" #include "ash/common/shelf/app_list_button.h" #include "ash/common/shelf/shelf_button.h" @@ -376,7 +377,8 @@ int index = model_->GetItemIndexForType(ash::TYPE_BROWSER_SHORTCUT); DCHECK_GE(index, 0); ash::ShelfItem item = model_->items()[index]; - ash::Shelf* shelf = ash::Shelf::ForWindow(CurrentContext()); + ash::Shelf* shelf = + ash::Shelf::ForWindow(ash::WmWindowAura::Get(CurrentContext())); std::unique_ptr<LauncherContextMenu> menu(LauncherContextMenu::Create( controller_, &item, ash::test::ShelfTestAPI(shelf).wm_shelf())); return menu; @@ -1898,7 +1900,8 @@ // Get a number of interfaces we need. DCHECK_EQ(ash::Shell::GetAllRootWindows().size(), 2U); aura::Window* secondary_root_window = ash::Shell::GetAllRootWindows()[1]; - ash::Shelf* secondary_shelf = ash::Shelf::ForWindow(secondary_root_window); + ash::Shelf* secondary_shelf = + ash::Shelf::ForWindow(ash::WmWindowAura::Get(secondary_root_window)); ui::test::EventGenerator generator(secondary_root_window, gfx::Point()); ash::test::ShelfViewTestAPI test(
diff --git a/chrome/browser/ui/ash/launcher/launcher_extension_app_updater.cc b/chrome/browser/ui/ash/launcher/launcher_extension_app_updater.cc index b2f87802..a779a8da 100644 --- a/chrome/browser/ui/ash/launcher/launcher_extension_app_updater.cc +++ b/chrome/browser/ui/ash/launcher/launcher_extension_app_updater.cc
@@ -4,8 +4,10 @@ #include "chrome/browser/ui/ash/launcher/launcher_extension_app_updater.h" +#include "chrome/browser/chromeos/extensions/gfx_utils.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #include "extensions/browser/extension_registry.h" LauncherExtensionAppUpdater::LauncherExtensionAppUpdater( @@ -18,6 +20,10 @@ // ArcAuthService may not be available for some unit tests. if (arc_auth_service) arc_auth_service->AddObserver(this); + + ArcAppListPrefs* prefs = ArcAppListPrefs::Get(browser_context); + if (prefs) + prefs->AddObserver(this); } LauncherExtensionAppUpdater::~LauncherExtensionAppUpdater() { @@ -26,6 +32,10 @@ arc::ArcAuthService* arc_auth_service = arc::ArcAuthService::Get(); if (arc_auth_service) arc_auth_service->RemoveObserver(this); + + ArcAppListPrefs* prefs = ArcAppListPrefs::Get(browser_context()); + if (prefs) + prefs->RemoveObserver(this); } void LauncherExtensionAppUpdater::OnExtensionLoaded( @@ -66,6 +76,16 @@ UpdateHostedApps(); } +void LauncherExtensionAppUpdater::OnPackageInstalled( + const arc::mojom::ArcPackageInfo& package_info) { + UpdateEquivalentHostedApp(package_info.package_name); +} + +void LauncherExtensionAppUpdater::OnPackageRemoved( + const std::string& package_name) { + UpdateEquivalentHostedApp(package_name); +} + void LauncherExtensionAppUpdater::StartObservingExtensionRegistry() { DCHECK(!extension_registry_); extension_registry_ = extensions::ExtensionRegistry::Get(browser_context()); @@ -101,3 +121,12 @@ void LauncherExtensionAppUpdater::UpdateHostedApp(const std::string& app_id) { delegate()->OnAppUpdated(browser_context(), app_id); } + +void LauncherExtensionAppUpdater::UpdateEquivalentHostedApp( + const std::string& arc_package_name) { + const std::vector<std::string> extension_ids = + extensions::util::GetEquivalentInstalledExtensions(browser_context(), + arc_package_name); + for (const auto& iter : extension_ids) + UpdateHostedApp(iter); +}
diff --git a/chrome/browser/ui/ash/launcher/launcher_extension_app_updater.h b/chrome/browser/ui/ash/launcher/launcher_extension_app_updater.h index b39b3b71..1de637ff 100644 --- a/chrome/browser/ui/ash/launcher/launcher_extension_app_updater.h +++ b/chrome/browser/ui/ash/launcher/launcher_extension_app_updater.h
@@ -7,6 +7,7 @@ #include "base/macros.h" #include "chrome/browser/chromeos/arc/arc_auth_service.h" +#include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #include "chrome/browser/ui/ash/launcher/launcher_app_updater.h" #include "extensions/browser/extension_registry_observer.h" @@ -17,7 +18,8 @@ class LauncherExtensionAppUpdater : public LauncherAppUpdater, public extensions::ExtensionRegistryObserver, - public arc::ArcAuthService::Observer { + public arc::ArcAuthService::Observer, + public ArcAppListPrefs::Observer { public: LauncherExtensionAppUpdater(Delegate* delegate, content::BrowserContext* browser_context); @@ -38,6 +40,11 @@ // arc::ArcAuthService::Observer: void OnOptInChanged(arc::ArcAuthService::State state) override; + // ArcAppListPrefs::Observer + void OnPackageInstalled( + const arc::mojom::ArcPackageInfo& package_info) override; + void OnPackageRemoved(const std::string& package_name) override; + private: void StartObservingExtensionRegistry(); void StopObservingExtensionRegistry(); @@ -45,6 +52,7 @@ void UpdateHostedApps(); void UpdateHostedApps(const extensions::ExtensionSet& extensions); void UpdateHostedApp(const std::string& app_id); + void UpdateEquivalentHostedApp(const std::string& arc_package_name); extensions::ExtensionRegistry* extension_registry_ = nullptr;
diff --git a/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc b/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc index c13ba13..bdbe655 100644 --- a/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc +++ b/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc
@@ -9,6 +9,7 @@ #include "ash/common/wm/window_positioner.h" #include "ash/common/wm/window_state.h" #include "ash/common/wm_shell.h" +#include "ash/common/wm_window.h" #include "ash/desktop_background/user_wallpaper_delegate.h" #include "ash/root_window_controller.h" #include "ash/shelf/shelf.h" @@ -231,7 +232,7 @@ chrome_launcher_controller->ActiveUserChanged( new_account_id_.GetUserEmail()); // Hide the black rectangle on top of each shelf again. - for (aura::Window* window : ash::Shell::GetAllRootWindows()) { + for (ash::WmWindow* window : ash::WmShell::Get()->GetAllRootWindows()) { ash::ShelfWidget* shelf = ash::Shelf::ForWindow(window)->shelf_widget(); shelf->HideShelfBehindBlackBar(false, duration_override); } @@ -264,7 +265,7 @@ // CPU usage and therefore effect jank, we should avoid hiding the shelf if // the start and end location are the same and cover the shelf instead with // a black rectangle on top. - ash::Shelf* shelf = ash::Shelf::ForWindow(window); + ash::Shelf* shelf = ash::Shelf::ForWindow(ash::WmWindowAura::Get(window)); if (GetScreenCover(window) != NO_USER_COVERS_SCREEN && (!chrome_launcher_controller || !chrome_launcher_controller->ShelfBoundsChangesProbablyWithUser(
diff --git a/chrome/browser/ui/ash/shelf_browsertest.cc b/chrome/browser/ui/ash/shelf_browsertest.cc index 7a3112e..eb2188a 100644 --- a/chrome/browser/ui/ash/shelf_browsertest.cc +++ b/chrome/browser/ui/ash/shelf_browsertest.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "ash/aura/wm_window_aura.h" #include "ash/shelf/shelf.h" #include "ash/shelf/shelf_layout_manager.h" #include "base/strings/utf_string_conversions.h" @@ -15,7 +16,8 @@ // Confirm that a status bubble doesn't cause the shelf to darken. IN_PROC_BROWSER_TEST_F(ShelfBrowserTest, StatusBubble) { ash::ShelfLayoutManager* shelf_layout_manager = - ash::Shelf::ForWindow(browser()->window()->GetNativeWindow()) + ash::Shelf::ForWindow( + ash::WmWindowAura::Get(browser()->window()->GetNativeWindow())) ->shelf_layout_manager(); EXPECT_TRUE(shelf_layout_manager->IsVisible());
diff --git a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc index 4ed3cf92..904de32 100644 --- a/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc +++ b/chrome/browser/ui/ash/system_tray_delegate_chromeos.cc
@@ -136,6 +136,7 @@ const char kDisplaySettingsSubPageName[] = "display"; const char kDisplayOverscanSettingsSubPageName[] = "displayOverscan"; +const char kPaletteSettingsSubPageName[] = "note-overlay"; void ExtractIMEInfo(const input_method::InputMethodDescriptor& ime, const input_method::InputMethodUtil& util, @@ -520,6 +521,18 @@ ShowSettingsSubPageForActiveUser(sub_page); } +void SystemTrayDelegateChromeOS::ShowPaletteHelp() { + chrome::ScopedTabbedBrowserDisplayer displayer( + ProfileManager::GetActiveUserProfile()); + chrome::ShowSingletonTab(displayer.browser(), + GURL(chrome::kChromePaletteHelpURL)); +} + +void SystemTrayDelegateChromeOS::ShowPaletteSettings() { + content::RecordAction(base::UserMetricsAction("ShowPaletteOptions")); + ShowSettingsSubPageForActiveUser(kPaletteSettingsSubPageName); +} + void SystemTrayDelegateChromeOS::ShowPublicAccountInfo() { chrome::ScopedTabbedBrowserDisplayer displayer( ProfileManager::GetActiveUserProfile());
diff --git a/chrome/browser/ui/ash/system_tray_delegate_chromeos.h b/chrome/browser/ui/ash/system_tray_delegate_chromeos.h index 3a95d00..1e5c0af 100644 --- a/chrome/browser/ui/ash/system_tray_delegate_chromeos.h +++ b/chrome/browser/ui/ash/system_tray_delegate_chromeos.h
@@ -107,6 +107,8 @@ void ShowHelp() override; void ShowAccessibilityHelp() override; void ShowAccessibilitySettings() override; + void ShowPaletteHelp() override; + void ShowPaletteSettings() override; void ShowPublicAccountInfo() override; void ShowSupervisedUserInfo() override; void ShowEnterpriseInfo() override;
diff --git a/chrome/browser/ui/avatar_button_error_controller.h b/chrome/browser/ui/avatar_button_error_controller.h index a294522..3ed18bf7 100644 --- a/chrome/browser/ui/avatar_button_error_controller.h +++ b/chrome/browser/ui/avatar_button_error_controller.h
@@ -7,7 +7,7 @@ #include "chrome/browser/ui/avatar_button_error_controller_delegate.h" #include "components/signin/core/browser/signin_error_controller.h" -#include "components/sync_driver/sync_error_controller.h" +#include "components/sync/driver/sync_error_controller.h" class Profile;
diff --git a/chrome/browser/ui/browser_instant_controller_unittest.cc b/chrome/browser/ui/browser_instant_controller_unittest.cc index 8e6127fc..f139f21 100644 --- a/chrome/browser/ui/browser_instant_controller_unittest.cc +++ b/chrome/browser/ui/browser_instant_controller_unittest.cc
@@ -54,7 +54,7 @@ {"Remote Embedded NTP", "https://www.google.com/newtab", true, true, false, false}, {"Remote Embedded SERP", "https://www.google.com/url?strk&bar=search+terms", - true, true, false, false}, + false, false, false, false}, {"Other NTP", "https://bar.com/newtab", false, false, false, false} }; @@ -66,7 +66,7 @@ {"Remote Embedded NTP", "https://www.google.com/newtab", true, false, true, true}, {"Remote Embedded SERP", "https://www.google.com/url?strk&bar=search+terms", - true, true, false, false}, + false, false, false, false}, {"Other NTP", "https://bar.com/newtab", false, false, false, false} };
diff --git a/chrome/browser/ui/browser_ui_prefs.cc b/chrome/browser/ui/browser_ui_prefs.cc index 7584efa..cae2a2a 100644 --- a/chrome/browser/ui/browser_ui_prefs.cc +++ b/chrome/browser/ui/browser_ui_prefs.cc
@@ -116,6 +116,7 @@ registry->RegisterBooleanPref(prefs::kWebRTCNonProxiedUdpEnabled, true); registry->RegisterStringPref(prefs::kWebRTCIPHandlingPolicy, content::kWebRTCIPHandlingDefault); + registry->RegisterStringPref(prefs::kWebRTCUDPPortRange, std::string()); #endif // Dictionaries to keep track of default tasks in the file browser.
diff --git a/chrome/browser/ui/cocoa/app_menu/app_menu_controller_unittest.mm b/chrome/browser/ui/cocoa/app_menu/app_menu_controller_unittest.mm index 01ad14d..6e79e5d6 100644 --- a/chrome/browser/ui/cocoa/app_menu/app_menu_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/app_menu/app_menu_controller_unittest.mm
@@ -27,9 +27,9 @@ #include "components/browser_sync/browser/profile_sync_service.h" #include "components/sync/api/fake_sync_change_processor.h" #include "components/sync/api/sync_error_factory_mock.h" -#include "components/sync_driver/local_device_info_provider_mock.h" -#include "components/sync_driver/sync_client.h" -#include "components/sync_driver/sync_prefs.h" +#include "components/sync/driver/local_device_info_provider_mock.h" +#include "components/sync/driver/sync_client.h" +#include "components/sync/driver/sync_prefs.h" #include "components/sync_sessions/fake_sync_sessions_client.h" #include "components/sync_sessions/sessions_sync_manager.h" #include "grit/theme_resources.h"
diff --git a/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm b/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm index 051bd0b..ab08a77 100644 --- a/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm +++ b/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm
@@ -99,11 +99,13 @@ } void SaveCardBubbleViewBridge::Hide() { - // SaveCardBubbleViewBridge::OnBubbleClosed won't be able to call - // OnBubbleClosed on the bubble controller since we null the reference to it - // below. So we need to call it here. - controller_->OnBubbleClosed(); - controller_ = nullptr; + if (controller_) { + // SaveCardBubbleViewBridge::OnBubbleClosed won't be able to call + // OnBubbleClosed on the bubble controller since we null the reference to it + // below. So we need to call it here. + controller_->OnBubbleClosed(); + controller_ = nullptr; + } [view_controller_ close]; }
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm index 86a384a..866ad49d 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller.mm
@@ -1905,7 +1905,6 @@ if (shouldShowFullscreenToolbar_ == visible) return; - [fullscreenToolbarController_ setToolbarFraction:0.0]; shouldShowFullscreenToolbar_ = visible; [self adjustUIForSlidingFullscreenStyle: shouldShowFullscreenToolbar_ ? fullscreen_mac::OMNIBOX_TABS_PRESENT
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm b/chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm index 26bac1e3..b8681d9 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller_browsertest.mm
@@ -313,7 +313,7 @@ // Views not in |view_list| must either be nil or not parented. for (size_t i = 0; i < VIEW_ID_COUNT; ++i) { - if (!ContainsValue(view_list, i)) { + if (!base::ContainsValue(view_list, i)) { NSView* view = GetViewWithID(static_cast<ViewID>(i)); EXPECT_TRUE(!view || ![view superview]); }
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_private.h b/chrome/browser/ui/cocoa/browser_window_controller_private.h index 2bd50d4a..b9c8128 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller_private.h +++ b/chrome/browser/ui/cocoa/browser_window_controller_private.h
@@ -73,11 +73,6 @@ regularWindow:(NSWindow*)regularWindow fullscreenWindow:(NSWindow*)fullscreenWindow; -// Called when a permission bubble closes, and informs the fullscreen toolbar -// controller that the dropdown can be hidden. (The dropdown should never be -// hidden while a permissions bubble is visible.) -- (void)permissionBubbleWindowWillClose:(NSNotification*)notification; - // Updates the anchor position of the permission bubble. - (void)updatePermissionBubbleAnchor;
diff --git a/chrome/browser/ui/cocoa/browser_window_controller_private.mm b/chrome/browser/ui/cocoa/browser_window_controller_private.mm index 1eb48d44..bb3abfdf 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller_private.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller_private.mm
@@ -447,16 +447,6 @@ [self enableBarVisibilityUpdates]; } -- (void)permissionBubbleWindowWillClose:(NSNotification*)notification { - NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; - [center removeObserver:self - name:NSWindowWillCloseNotification - object:[notification object]]; - [self releaseBarVisibilityForOwner:[notification object] - withAnimation:YES - delay:YES]; -} - - (void)updatePermissionBubbleAnchor { PermissionRequestManager* manager = [self permissionRequestManager]; if (manager) @@ -470,23 +460,6 @@ BOOL showDropdown = !fullscreenForTab && !kioskMode && ([self floatingBarHasFocus]); - PermissionRequestManager* manager = [self permissionRequestManager]; - if (manager && manager->IsBubbleVisible()) { - NSWindow* bubbleWindow = manager->GetBubbleWindow(); - DCHECK(bubbleWindow); - // A visible permission bubble will force the dropdown to remain - // visible. - [self lockBarVisibilityForOwner:bubbleWindow withAnimation:NO delay:NO]; - showDropdown = YES; - // Register to be notified when the permission bubble is closed, to - // allow fullscreen to hide the dropdown. - NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; - [center addObserver:self - selector:@selector(permissionBubbleWindowWillClose:) - name:NSWindowWillCloseNotification - object:bubbleWindow]; - } - NSView* contentView = [[self window] contentView]; [fullscreenToolbarController_ setupFullscreenToolbarForContentView:contentView
diff --git a/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.mm b/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.mm index f11960d..e0e09f2 100644 --- a/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.mm +++ b/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa.mm
@@ -306,7 +306,7 @@ } - (void)dealloc { - STLDeleteValues(&mediaMenus_); + base::STLDeleteValues(&mediaMenus_); [super dealloc]; } @@ -314,7 +314,7 @@ if (!titleLabel_) return; - NSString* label = base::SysUTF8ToNSString( + NSString* label = base::SysUTF16ToNSString( contentSettingBubbleModel_->bubble_content().title); [titleLabel_ setStringValue:label];
diff --git a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm index f76f2a3..d837c4e 100644 --- a/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm +++ b/chrome/browser/ui/cocoa/location_bar/autocomplete_text_field_editor.mm
@@ -489,6 +489,24 @@ DCHECK(interpretingKeyEvents_); interpretingKeyEvents_ = NO; + + // -[NSTextView interpretKeyEvents:] invalidates the existing layout. + // + // observer->OnDidChange() calls OmniboxViewMac::ApplyTextStyle, which + // invalidates the existing layout again, but in a slightly different way. + // Details unclear. + // + // On older versions of macOS, this results in a single call to -[NSTextView + // drawRect:] on the next frame, which paints the correct contents. + // + // On macOS 10.12 dp4, for unknown reasons, this causes two calls to + // -[NSTextView drawRect:] across two(!) frames. The first call to + // -[NSTextView drawRect:] draws no text, which causes a flicker in the + // omnibox. Forcing a layout ensures that drawRect: is only called once, and + // is drawn with the correct contents. + // https://crbug.com/634318. + [self.layoutManager + ensureLayoutForCharacterRange:NSMakeRange(0, self.textStorage.length)]; } - (BOOL)shouldChangeTextInRange:(NSRange)affectedCharRange
diff --git a/chrome/browser/ui/cocoa/location_bar/bubble_decoration.h b/chrome/browser/ui/cocoa/location_bar/bubble_decoration.h index 5381588..3e25bdbc3 100644 --- a/chrome/browser/ui/cocoa/location_bar/bubble_decoration.h +++ b/chrome/browser/ui/cocoa/location_bar/bubble_decoration.h
@@ -48,6 +48,9 @@ // from. |frame| is the decoration's frame in the containing cell. NSRect GetImageRectInFrame(NSRect frame); + // Returns the text color when the theme is dark. + virtual NSColor* GetDarkModeTextColor(); + private: friend class SelectedKeywordDecorationTest; FRIEND_TEST_ALL_PREFIXES(SelectedKeywordDecorationTest,
diff --git a/chrome/browser/ui/cocoa/location_bar/bubble_decoration.mm b/chrome/browser/ui/cocoa/location_bar/bubble_decoration.mm index 2e84e9b..36a6f0f3 100644 --- a/chrome/browser/ui/cocoa/location_bar/bubble_decoration.mm +++ b/chrome/browser/ui/cocoa/location_bar/bubble_decoration.mm
@@ -79,6 +79,10 @@ return image_rect; } +NSColor* BubbleDecoration::GetDarkModeTextColor() { + return skia::SkColorToSRGBNSColor(kMaterialDarkModeTextColor); +} + CGFloat BubbleDecoration::GetWidthForSpace(CGFloat width) { const CGFloat all_width = GetWidthForImageAndLabel(image_, label_); if (all_width <= width) @@ -124,9 +128,7 @@ [line stroke]; NSColor* text_color = - in_dark_mode - ? skia::SkColorToSRGBNSColor(kMaterialDarkModeTextColor) - : GetBackgroundBorderColor(); + in_dark_mode ? GetDarkModeTextColor() : GetBackgroundBorderColor(); SetTextColor(text_color); }
diff --git a/chrome/browser/ui/cocoa/location_bar/ev_bubble_decoration.h b/chrome/browser/ui/cocoa/location_bar/ev_bubble_decoration.h index 97cd4b8e..51be0a1 100644 --- a/chrome/browser/ui/cocoa/location_bar/ev_bubble_decoration.h +++ b/chrome/browser/ui/cocoa/location_bar/ev_bubble_decoration.h
@@ -52,6 +52,9 @@ // Implement |BubbleDecoration|. ui::NinePartImageIds GetBubbleImageIds() override; + protected: + NSColor* GetDarkModeTextColor() override; + private: // The real label. BubbleDecoration's label may be elided. base::scoped_nsobject<NSString> full_label_;
diff --git a/chrome/browser/ui/cocoa/location_bar/ev_bubble_decoration.mm b/chrome/browser/ui/cocoa/location_bar/ev_bubble_decoration.mm index b48bb4ac..2adf645 100644 --- a/chrome/browser/ui/cocoa/location_bar/ev_bubble_decoration.mm +++ b/chrome/browser/ui/cocoa/location_bar/ev_bubble_decoration.mm
@@ -164,3 +164,7 @@ ui::NinePartImageIds EVBubbleDecoration::GetBubbleImageIds() { return IMAGE_GRID(IDR_OMNIBOX_EV_BUBBLE); } + +NSColor* EVBubbleDecoration::GetDarkModeTextColor() { + return [NSColor whiteColor]; +}
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.h b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.h index 6d98c21..fd98054 100644 --- a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.h +++ b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.h
@@ -12,45 +12,32 @@ class OmniboxPopupViewMac; -@interface OmniboxPopupCellData : NSObject<NSCopying> { - @private - // Left hand side of the separator (e.g. a hyphen). - NSAttributedString* contents_; - // Right hand side of the separator (e.g. a hyphen). - NSAttributedString* description_; +@interface OmniboxPopupCellData : NSObject<NSCopying> - // NOTE: While |prefix_| is used only for postfix suggestions, it still needs - // to be a member of the class. This allows the |NSAttributedString| instance - // to stay alive between the call to |drawTitle| and the actual paint event - // which accesses the |NSAttributedString| instance. - NSAttributedString* prefix_; - - // Common icon that shows next to most rows in the list. - NSImage* image_; - // Uncommon icon that only shows on answer rows (e.g. weather). - NSImage* answerImage_; - - // The offset at which the infinite suggestion contents should be displayed. - CGFloat contentsOffset_; - - BOOL isContentsRTL_; - - // Is this suggestion an answer or calculator result. - bool isAnswer_; - - AutocompleteMatch::Type matchType_; - - int maxLines_; -} - +// Left hand side of the separator (e.g. a hyphen). @property(readonly, retain, nonatomic) NSAttributedString* contents; + +// Right hand side of the separator (e.g. a hyphen). @property(readonly, retain, nonatomic) NSAttributedString* description; + +// NOTE: While |prefix_| is used only for postfix suggestions, it still needs +// to be a member of the class. This allows the |NSAttributedString| instance +// to stay alive between the call to |drawTitle| and the actual paint event +// which accesses the |NSAttributedString| instance. @property(readonly, retain, nonatomic) NSAttributedString* prefix; + +// Common icon that shows next to most rows in the list. @property(readonly, retain, nonatomic) NSImage* image; @property(retain, nonatomic) NSImage* incognitoImage; + +// Uncommon icon that only shows on answer rows (e.g. weather). @property(readonly, retain, nonatomic) NSImage* answerImage; + +// The offset at which the infinite suggestion contents should be displayed. @property(readonly, nonatomic) CGFloat contentsOffset; @property(readonly, nonatomic) BOOL isContentsRTL; + +// Is this suggestion an answer or calculator result. @property(readonly, nonatomic) bool isAnswer; @property(readonly, nonatomic) AutocompleteMatch::Type matchType; @property(readonly, nonatomic) int maxLines;
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm index 4d7bbcc..0f44f22 100644 --- a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm +++ b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_cell.mm
@@ -11,6 +11,7 @@ #include "base/i18n/rtl.h" #include "base/mac/foundation_util.h" +#include "base/mac/objc_property_releaser.h" #include "base/mac/scoped_nsobject.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -395,6 +396,11 @@ } // namespace +@interface OmniboxPopupCellData () { + base::mac::ObjCPropertyReleaser propertyReleaser_OmniboxPopupCellData_; +} +@end + @interface OmniboxPopupCell () - (CGFloat)drawMatchPart:(NSAttributedString*)attributedString withFrame:(NSRect)cellFrame @@ -465,15 +471,12 @@ } maxLines_ = 1; } + propertyReleaser_OmniboxPopupCellData_.Init(self, + [OmniboxPopupCellData class]); } return self; } -- (void)dealloc { - [incognitoImage_ release]; - [super dealloc]; -} - - (instancetype)copyWithZone:(NSZone*)zone { return [self retain]; }
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_matrix.h b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_matrix.h index 07daf9b..fa110bf 100644 --- a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_matrix.h +++ b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_matrix.h
@@ -17,7 +17,7 @@ class OmniboxPopupViewMac; @interface OmniboxPopupTableController - : NSViewController<NSTableViewDelegate, NSTableViewDataSource> { + : NSObject<NSTableViewDelegate, NSTableViewDataSource> { @private base::scoped_nsobject<NSArray> array_; NSInteger hoveredIndex_;
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.mm index 8dbaac1..f5355de 100644 --- a/chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.mm +++ b/chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.mm
@@ -115,11 +115,11 @@ answerImage = gfx::Image::CreateFrom1xBitmap(model_->answer_bitmap()).CopyNSImage(); } - [matrix_ setController:[[OmniboxPopupTableController alloc] + [matrix_ setController:[[[OmniboxPopupTableController alloc] initWithMatchResults:result tableView:matrix_ popupView:*this - answerImage:answerImage]]; + answerImage:answerImage] autorelease]]; BOOL is_dark_theme = [matrix_ hasDarkTheme]; [matrix_ setSeparator:[OmniboxPopupCell createSeparatorStringForDarkTheme:is_dark_theme]];
diff --git a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm index 75a7789..4394268 100644 --- a/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm +++ b/chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.mm
@@ -106,9 +106,8 @@ if (!ui::MaterialDesignController::IsModeMaterial()) { return ColorWithRGBBytes(0x07, 0x95, 0x00); } - return in_dark_mode - ? skia::SkColorToSRGBNSColor(SkColorSetA(SK_ColorWHITE, 0x7F)) - : skia::SkColorToSRGBNSColor(gfx::kGoogleGreen700); + return in_dark_mode ? skia::SkColorToSRGBNSColor(SK_ColorWHITE) + : skia::SkColorToSRGBNSColor(gfx::kGoogleGreen700); } NSColor* SecurityWarningSchemeColor(bool in_dark_mode) { return in_dark_mode
diff --git a/chrome/browser/ui/cocoa/passwords/base_passwords_controller_test.h b/chrome/browser/ui/cocoa/passwords/base_passwords_controller_test.h index 7153b890..27c20724 100644 --- a/chrome/browser/ui/cocoa/passwords/base_passwords_controller_test.h +++ b/chrome/browser/ui/cocoa/passwords/base_passwords_controller_test.h
@@ -5,18 +5,19 @@ #ifndef CHROME_BROWSER_UI_COCOA_PASSWORDS_BASE_PASSWORDS_CONTROLLER_TEST_H_ #define CHROME_BROWSER_UI_COCOA_PASSWORDS_BASE_PASSWORDS_CONTROLLER_TEST_H_ +#include <memory> + #include "base/mac/scoped_nsobject.h" #include "chrome/browser/ui/cocoa/cocoa_profile_test.h" #include "chrome/browser/ui/cocoa/cocoa_test_helper.h" #import "chrome/browser/ui/cocoa/passwords/base_passwords_content_view_controller.h" #include "chrome/browser/ui/passwords/manage_passwords_bubble_model.h" +#include "chrome/browser/ui/passwords/passwords_model_delegate_mock.h" namespace content { class WebContents; } // namespace content - -class ManagePasswordsUIControllerMock; -class ManagePasswordsBubbleModel; +class PasswordsModelDelegateMock; // Helper delegate for testing the views of the password management bubble. @interface ContentViewDelegateMock : NSObject<BasePasswordsContentViewDelegate> @@ -32,7 +33,9 @@ ~ManagePasswordsControllerTest() override; void SetUp() override; - ManagePasswordsUIControllerMock* ui_controller() { return ui_controller_; } + PasswordsModelDelegateMock* ui_controller() { + return ui_controller_.get(); + } ContentViewDelegateMock* delegate() { return delegate_.get(); } ManagePasswordsBubbleModel* GetModelAndCreateIfNull(); @@ -47,7 +50,7 @@ virtual ManagePasswordsBubbleModel::DisplayReason GetDisplayReason() const; private: - ManagePasswordsUIControllerMock* ui_controller_; + std::unique_ptr<PasswordsModelDelegateMock> ui_controller_; std::unique_ptr<content::WebContents> test_web_contents_; std::unique_ptr<ManagePasswordsBubbleModel> model_; base::scoped_nsobject<ContentViewDelegateMock> delegate_;
diff --git a/chrome/browser/ui/cocoa/passwords/base_passwords_controller_test.mm b/chrome/browser/ui/cocoa/passwords/base_passwords_controller_test.mm index 8e1868f8..582f508e 100644 --- a/chrome/browser/ui/cocoa/passwords/base_passwords_controller_test.mm +++ b/chrome/browser/ui/cocoa/passwords/base_passwords_controller_test.mm
@@ -6,9 +6,9 @@ #include "base/strings/utf_string_conversions.h" #include "chrome/browser/password_manager/password_store_factory.h" -#include "chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h" #include "components/password_manager/core/browser/mock_password_store.h" #include "components/password_manager/core/browser/password_manager_test_utils.h" +#include "content/public/browser/web_contents.h" #include "content/public/test/web_contents_tester.h" namespace { @@ -28,12 +28,12 @@ void ManagePasswordsControllerTest::SetUp() { CocoaProfileTest::SetUp(); - // Create the test UIController here so that it's bound to and owned by - // |test_web_contents_| and therefore accessible to the model. + test_web_contents_.reset( - content::WebContentsTester::CreateTestWebContents(profile(), NULL)); - ui_controller_ = new testing::NiceMock<ManagePasswordsUIControllerMock>( - test_web_contents_.get()); + content::WebContentsTester::CreateTestWebContents(profile(), nullptr)); + ui_controller_.reset(new testing::NiceMock<PasswordsModelDelegateMock>); + ON_CALL(*ui_controller_, GetWebContents()) + .WillByDefault(Return(test_web_contents_.get())); PasswordStoreFactory::GetInstance()->SetTestingFactoryAndUse( profile(), password_manager::BuildPasswordStore< content::BrowserContext, @@ -44,7 +44,7 @@ ManagePasswordsBubbleModel* ManagePasswordsControllerTest::GetModelAndCreateIfNull() { if (!model_) { - model_.reset(new ManagePasswordsBubbleModel(test_web_contents_.get(), + model_.reset(new ManagePasswordsBubbleModel(ui_controller_->AsWeakPtr(), GetDisplayReason())); [delegate() setModel:model_.get()]; } @@ -64,7 +64,7 @@ EXPECT_CALL(*ui_controller_, GetState()) .WillOnce(Return(password_manager::ui::PENDING_PASSWORD_STATE)); GetModelAndCreateIfNull(); - ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(ui_controller_)); + ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(ui_controller_.get())); } void ManagePasswordsControllerTest::SetUpUpdatePendingState( @@ -82,7 +82,7 @@ EXPECT_CALL(*ui_controller_, GetState()) .WillOnce(Return(password_manager::ui::PENDING_PASSWORD_UPDATE_STATE)); GetModelAndCreateIfNull(); - ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(ui_controller_)); + ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(ui_controller_.get())); } void ManagePasswordsControllerTest::SetUpConfirmationState() { @@ -91,7 +91,7 @@ EXPECT_CALL(*ui_controller_, GetState()) .WillOnce(Return(password_manager::ui::CONFIRMATION_STATE)); GetModelAndCreateIfNull(); - ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(ui_controller_)); + ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(ui_controller_.get())); } void ManagePasswordsControllerTest::SetUpManageState( @@ -102,7 +102,7 @@ EXPECT_CALL(*ui_controller_, GetState()) .WillOnce(Return(password_manager::ui::MANAGE_STATE)); GetModelAndCreateIfNull(); - ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(ui_controller_)); + ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(ui_controller_.get())); } ManagePasswordsBubbleModel::DisplayReason
diff --git a/chrome/browser/ui/cocoa/passwords/passwords_bubble_cocoa.mm b/chrome/browser/ui/cocoa/passwords/passwords_bubble_cocoa.mm index 8c871a9..d5e520aa 100644 --- a/chrome/browser/ui/cocoa/passwords/passwords_bubble_cocoa.mm +++ b/chrome/browser/ui/cocoa/passwords/passwords_bubble_cocoa.mm
@@ -13,6 +13,7 @@ #include "chrome/browser/ui/cocoa/location_bar/manage_passwords_decoration.h" #import "chrome/browser/ui/cocoa/passwords/passwords_bubble_controller.h" #include "chrome/browser/ui/passwords/manage_passwords_icon.h" +#include "chrome/browser/ui/passwords/passwords_model_delegate.h" #include "content/public/browser/web_contents.h" typedef void (^Callback)(void); @@ -43,7 +44,8 @@ content::WebContents* webContents, ManagePasswordsBubbleModel::DisplayReason displayReason, ManagePasswordsIcon* icon) - : model_(webContents, displayReason), + : model_(PasswordsModelDelegateFromWebContents(webContents), + displayReason), icon_(icon), controller_(nil), webContents_(webContents),
diff --git a/chrome/browser/ui/cocoa/passwords/passwords_bubble_cocoa_unittest.mm b/chrome/browser/ui/cocoa/passwords/passwords_bubble_cocoa_unittest.mm index 23618c9f..af7d027 100644 --- a/chrome/browser/ui/cocoa/passwords/passwords_bubble_cocoa_unittest.mm +++ b/chrome/browser/ui/cocoa/passwords/passwords_bubble_cocoa_unittest.mm
@@ -97,7 +97,7 @@ ManagePasswordsUIControllerMock* UIController() { return static_cast<ManagePasswordsUIControllerMock*>( - PasswordsModelDelegateFromWebContents(test_web_contents_)); + ManagePasswordsUIController::FromWebContents(test_web_contents_)); } ManagePasswordsBubbleController* controller() {
diff --git a/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm b/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm index 8a39e73..dfa48fc 100644 --- a/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm +++ b/chrome/browser/ui/cocoa/profiles/avatar_base_controller.mm
@@ -28,7 +28,7 @@ const CGFloat kMenuYOffsetAdjust = 1.0; // Offset needed to align the edge of the avatar bubble with the edge of the // avatar button. -const CGFloat kMenuXOffsetAdjust = 2.0; +const CGFloat kMenuXOffsetAdjust = 1.0; @interface AvatarBaseController (Private) // Shows the avatar bubble.
diff --git a/chrome/browser/ui/cocoa/profiles/avatar_button_controller.mm b/chrome/browser/ui/cocoa/profiles/avatar_button_controller.mm index 0796752..409f9ab 100644 --- a/chrome/browser/ui/cocoa/profiles/avatar_button_controller.mm +++ b/chrome/browser/ui/cocoa/profiles/avatar_button_controller.mm
@@ -171,6 +171,8 @@ [avatarButton setBezelStyle:NSShadowlessSquareBezelStyle]; [avatarButton setButtonType:NSMomentaryChangeButton]; + if (switches::IsMaterialDesignUserMenu()) + [[avatarButton cell] setHighlightsBy:NSNoCellMask]; [avatarButton setBordered:YES]; [avatarButton setAutoresizingMask:NSViewMinXMargin | NSViewMinYMargin]; @@ -264,13 +266,15 @@ NSImage* errorIcon = switches::IsMaterialDesignUserMenu() ? NSImageFromImageSkia(gfx::CreateVectorIcon( - gfx::VectorIconId::SYNC_PROBLEM, 13, gfx::kGoogleRed700)) + gfx::VectorIconId::SYNC_PROBLEM, 16, gfx::kGoogleRed700)) : GetImageFromResourceID(IDR_ICON_PROFILES_AVATAR_BUTTON_ERROR); [button setDefaultImage:errorIcon]; [button setHoverImage:nil]; [button setPressedImage:nil]; [button setImage:errorIcon]; - [button setImagePosition:NSImageRight]; + [button setImagePosition:switches::IsMaterialDesignUserMenu() + ? NSImageLeft + : NSImageRight]; } else { [button setDefaultImage:nil]; [button setHoverImage:nil];
diff --git a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm index 433ef2f..328a875d 100644 --- a/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm +++ b/chrome/browser/ui/cocoa/profiles/profile_chooser_controller.mm
@@ -574,14 +574,12 @@ [[CustomCircleImageCell alloc] init]); [self setCell:cell.get()]; - const int imageSide = - switches::IsMaterialDesignUserMenu() ? kMdImageSide : kLargeImageSide; - [self setDefaultImage:CreateProfileImage(profileIcon, imageSide, - profiles::SHAPE_CIRCLE)]; + [self setDefaultImage:CreateProfileImage(profileIcon, kLargeImageSide, + profiles::SHAPE_SQUARE)]; [self setImagePosition:NSImageOnly]; if (editingAllowed) { - NSRect bounds = NSMakeRect(0, 0, imageSide, imageSide); + NSRect bounds = NSMakeRect(0, 0, kLargeImageSide, kLargeImageSide); [self setTarget:self]; [self setAction:@selector(editPhoto:)]; changePhotoImage_.reset([[TransparentBackgroundImageView alloc] @@ -841,6 +839,8 @@ initWithLeftMarginSpacing:kHorizontalSpacing imageTitleSpacing:imageTitleSpacing]); [cell setLineBreakMode:NSLineBreakByTruncatingTail]; + if (switches::IsMaterialDesignUserMenu()) + [cell setHighlightsBy:NSNoCellMask]; [self setCell:cell.get()]; } return self; @@ -870,7 +870,7 @@ } - (BOOL)canBecomeKeyView { - return YES; + return [self isEnabled] ? YES : NO; } @end @@ -1168,7 +1168,7 @@ accountIdToRemove_ = SigninManagerFactory::GetForProfile( browser_->profile())->GetAuthenticatedAccountId(); } else { - DCHECK(ContainsKey(currentProfileAccounts_, tag)); + DCHECK(base::ContainsKey(currentProfileAccounts_, tag)); accountIdToRemove_ = currentProfileAccounts_[tag]; } @@ -2051,52 +2051,17 @@ // Profile card button that contains the profile icon, name, and username. NSRect rect = NSMakeRect(0, yOffset, GetFixedMenuWidth(), kMdImageSide + kVerticalSpacing); - NSButton* profileCard = [self hoverButtonWithRect:rect - text:[[NSString alloc] init] - action:@selector(editProfile:)]; + NSButton* profileCard = + [self hoverButtonWithRect:rect + text:[[NSString alloc] init] + image:CreateProfileImage(item.icon, kMdImageSide, + profiles::SHAPE_CIRCLE) + action:@selector(editProfile:)]; + [[profileCard cell] setImageDimsWhenDisabled:NO]; [container addSubview:profileCard]; if (isGuestSession_) [profileCard setEnabled:NO]; - // Profile icon, left-aligned. - base::scoped_nsobject<NSImageView> iconView([[NSImageView alloc] - initWithFrame:NSMakeRect(xOffset, cardYOffset, kMdImageSide, - kMdImageSide)]); - [iconView setImage:CreateProfileImage(item.icon, kMdImageSide, - profiles::SHAPE_CIRCLE)]; - [profileCard addSubview:iconView]; - - // Profile name, left-aligned to the right of profile icon. - xOffset += kMdImageSide + kHorizontalSpacing; - CGFloat fontSize = kTextFontSize + 1.0; - NSTextField* profileName = BuildLabel( - base::SysUTF16ToNSString( - profiles::GetAvatarNameForProfile(browser_->profile()->GetPath())), - NSZeroPoint, nil); - [[profileName cell] setLineBreakMode:NSLineBreakByTruncatingTail]; - [profileName setFont:[NSFont labelFontOfSize:fontSize]]; - [profileName - setFrame:NSMakeRect( - xOffset, - cardYOffset + - (kMdImageSide - [profileName frame].size.height) / 2, - availableTextWidth, [profileName frame].size.height)]; - [profileCard addSubview:profileName]; - - // Username, left-aligned to the right of profile icon and below the profile - // name. - if (item.signed_in && !switches::IsEnableAccountConsistency()) { - // Adjust the y-position of profile name to leave space for username. - cardYOffset += kMdImageSide / 2 - [profileName frame].size.height; - [profileName setFrameOrigin:NSMakePoint(xOffset, cardYOffset)]; - - NSTextField* username = BuildLabel( - ElideEmail(base::UTF16ToUTF8(item.username), availableTextWidth), - NSZeroPoint, skia::SkColorToSRGBNSColor(SK_ColorGRAY)); - [username setFrameOrigin:NSMakePoint(xOffset, NSMaxY([profileName frame]))]; - [profileCard addSubview:username]; - } - // Profile badge for supervised account. if (browser_->profile()->IsSupervised()) { base::scoped_nsobject<NSImageView> supervisedIcon( @@ -2111,15 +2076,46 @@ NSSize size = [[supervisedIcon image] size]; [supervisedIcon setFrameSize:size]; - NSRect profileIconFrame = [iconView frame]; const int badgeSpacing = 4; - [supervisedIcon setFrameOrigin:NSMakePoint(NSMaxX(profileIconFrame) - + [supervisedIcon setFrameOrigin:NSMakePoint(xOffset + kMdImageSide - size.width + badgeSpacing, - NSMaxY(profileIconFrame) - + cardYOffset + kMdImageSide - size.height + badgeSpacing)]; [profileCard addSubview:supervisedIcon]; } + // Profile name, left-aligned to the right of profile icon. + xOffset += kMdImageSide + kHorizontalSpacing; + CGFloat fontSize = kTextFontSize + 1.0; + NSTextField* profileName = BuildLabel( + base::SysUTF16ToNSString( + profiles::GetAvatarNameForProfile(browser_->profile()->GetPath())), + NSZeroPoint, nil); + [[profileName cell] setLineBreakMode:NSLineBreakByTruncatingTail]; + [profileName setFont:[NSFont labelFontOfSize:fontSize]]; + [profileName sizeToFit]; + const int profileNameYOffset = + cardYOffset + + std::floor((kMdImageSide - NSHeight([profileName frame])) / 2); + [profileName + setFrame:NSMakeRect(xOffset, profileNameYOffset, availableTextWidth, + NSHeight([profileName frame]))]; + [profileCard addSubview:profileName]; + + // Username, left-aligned to the right of profile icon and below the profile + // name. + if (item.signed_in && !switches::IsEnableAccountConsistency()) { + // Adjust the y-position of profile name to leave space for username. + cardYOffset += kMdImageSide / 2 - [profileName frame].size.height; + [profileName setFrameOrigin:NSMakePoint(xOffset, cardYOffset)]; + + NSTextField* username = BuildLabel( + ElideEmail(base::UTF16ToUTF8(item.username), availableTextWidth), + NSZeroPoint, skia::SkColorToSRGBNSColor(SK_ColorGRAY)); + [username setFrameOrigin:NSMakePoint(xOffset, NSMaxY([profileName frame]))]; + [profileCard addSubview:username]; + } + yOffset = NSMaxY([profileCard frame]); [container setFrameSize:NSMakeSize(GetFixedMenuWidth(), yOffset)]; return container.autorelease(); @@ -2332,7 +2328,8 @@ NSFontAttributeName : [profileButton font] }]; - if (std::ceil(textSize.width) > availableWidth) + if (!switches::IsMaterialDesignUserMenu() && + std::ceil(textSize.width) > availableWidth) [profileButton setToolTip:[profileButton title]]; return profileButton.autorelease();
diff --git a/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h b/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h index 3f1eb330..20acf9f 100644 --- a/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h +++ b/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h
@@ -38,11 +38,7 @@ } // namespace chrome // A controller class that manages the SadTabView (aka "Aw Snap" or crash page). -@interface SadTabController : NSViewController { - @private - content::WebContents* webContents_; // Weak reference. - base::scoped_nsobject<SadTabView> sadTabView_; -} +@interface SadTabController : NSViewController // Designated initializer. - (id)initWithWebContents:(content::WebContents*)webContents;
diff --git a/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.mm b/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.mm index 747dfe2..f8d9fa69 100644 --- a/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.mm +++ b/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.mm
@@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h" +#import "chrome/browser/ui/cocoa/tab_contents/sad_tab_controller.h" -#include "base/mac/bundle_locations.h" #import "chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.h" #include "chrome/common/url_constants.h" +#include "chrome/grit/generated_resources.h" +#include "components/strings/grit/components_strings.h" #include "content/public/browser/web_contents.h" using content::OpenURLParams; @@ -36,7 +37,13 @@ } // namespace chrome -@implementation SadTabController +@interface SadTabController ()<SadTabViewDelegate> +@end + +@implementation SadTabController { + content::WebContents* webContents_; + SadTabView* sadTabView_; +} - (id)initWithWebContents:(content::WebContents*)webContents { if ((self = [super init])) { @@ -56,27 +63,34 @@ } - (void)dealloc { - [[sadTabView_ reloadButton] setTarget:nil]; + sadTabView_.delegate = nil; [super dealloc]; } - (void)loadView { - sadTabView_.reset([[SadTabView alloc] init]); - [[sadTabView_ reloadButton] setTarget:self]; - [[sadTabView_ reloadButton] setAction:@selector(reloadPage:)]; - [self setView:sadTabView_]; + sadTabView_ = [[SadTabView new] autorelease]; + sadTabView_.delegate = self; + + [sadTabView_ setTitle:IDS_SAD_TAB_TITLE]; + [sadTabView_ setMessage:IDS_SAD_TAB_MESSAGE]; + [sadTabView_ setButtonTitle:IDS_SAD_TAB_RELOAD_LABEL]; + [sadTabView_ setHelpLinkTitle:IDS_SAD_TAB_LEARN_MORE_LINK + URL:@(chrome::kCrashReasonURL)]; + + self.view = sadTabView_; } - (content::WebContents*)webContents { return webContents_; } -- (IBAction)reloadPage:(id)sender { +- (void)sadTabViewButtonClicked:(SadTabView*)sadTabView { webContents_->GetController().Reload(true); } -- (void)openLearnMoreAboutCrashLink:(id)sender { - OpenURLParams params(GURL(chrome::kCrashReasonURL), Referrer(), CURRENT_TAB, +- (void)sadTabView:(SadTabView*)sadTabView + helpLinkClickedWithURL:(NSString*)url { + OpenURLParams params(GURL(url.UTF8String), Referrer(), CURRENT_TAB, ui::PAGE_TRANSITION_LINK, false); webContents_->OpenURL(params); }
diff --git a/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller_unittest.mm b/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller_unittest.mm index f9c47faf..f7fee6b2 100644 --- a/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/tab_contents/sad_tab_controller_unittest.mm
@@ -11,6 +11,8 @@ #include "chrome/common/url_constants.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_contents_delegate.h" #import "ui/base/cocoa/controls/hyperlink_text_view.h" @interface SadTabView (ExposedForTesting) @@ -31,14 +33,28 @@ namespace { +class ContentsDelegate : public content::WebContentsDelegate { + public: + content::WebContents* OpenURLFromTab( + content::WebContents* source, + const content::OpenURLParams& params) override { + opened_url_ = params.url; + return nullptr; + } + + const GURL& OpenedURL() { return opened_url_; } + + private: + GURL opened_url_; +}; + class SadTabControllerTest : public ChromeRenderViewHostTestHarness { public: - SadTabControllerTest() : test_window_(nil) { - link_clicked_ = false; - } + SadTabControllerTest() : test_window_(nil) {} void SetUp() override { ChromeRenderViewHostTestHarness::SetUp(); + web_contents()->SetDelegate(&contents_delegate_); // Inherting from ChromeRenderViewHostTestHarness means we can't inherit // from from CocoaTest, so do a bootstrap and create test window. CocoaTest::BootstrapCocoa(); @@ -74,32 +90,17 @@ return ([view helpTextView]); } - static bool link_clicked_; + ContentsDelegate contents_delegate_; CocoaTestHelperWindow* test_window_; }; -// static -bool SadTabControllerTest::link_clicked_; - TEST_F(SadTabControllerTest, ClickOnLink) { base::scoped_nsobject<SadTabController> controller(CreateController()); HyperlinkTextView* help = GetHelpTextView(controller); EXPECT_TRUE(help); - EXPECT_FALSE(link_clicked_); + EXPECT_TRUE(contents_delegate_.OpenedURL().is_empty()); [help clickedOnLink:@(chrome::kCrashReasonURL) atIndex:0]; - EXPECT_TRUE(link_clicked_); + EXPECT_EQ(contents_delegate_.OpenedURL(), GURL(chrome::kCrashReasonURL)); } } // namespace - -@implementation NSApplication (SadTabControllerUnitTest) -// Add handler for the openLearnMoreAboutCrashLink: action to NSApp for testing -// purposes. Normally this would be sent up the responder tree correctly, but -// since tests run in the background, key window and main window are never set -// on NSApplication. Adding it to NSApplication directly removes the need for -// worrying about what the current window with focus is. -- (void)openLearnMoreAboutCrashLink:(id)sender { - SadTabControllerTest::link_clicked_ = true; -} - -@end
diff --git a/chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.h b/chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.h index e5f420a1..bbaf5906 100644 --- a/chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.h +++ b/chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.h
@@ -5,23 +5,27 @@ #ifndef CHROME_BROWSER_UI_COCOA_TAB_CONTENTS_SAD_TAB_VIEW_COCOA_H_ #define CHROME_BROWSER_UI_COCOA_TAB_CONTENTS_SAD_TAB_VIEW_COCOA_H_ -#include "base/mac/scoped_nsobject.h" - #import <Cocoa/Cocoa.h> -namespace content { -class WebContents; -} +#import "ui/base/cocoa/controls/hyperlink_text_view.h" -@class SadTabContainerView; +@class SadTabView; + +@protocol SadTabViewDelegate +- (void)sadTabViewButtonClicked:(SadTabView*)sadTabView; +- (void)sadTabView:(SadTabView*)sadTabView + helpLinkClickedWithURL:(NSString*)url; +@end // A view that displays the "sad tab" (aka crash page). -@interface SadTabView : NSView { - @private - base::scoped_nsobject<SadTabContainerView> container_; -} +@interface SadTabView : NSView -@property(readonly,nonatomic) NSButton* reloadButton; +@property(nonatomic, assign) id<SadTabViewDelegate> delegate; + +- (void)setTitle:(int)title; +- (void)setMessage:(int)message; +- (void)setButtonTitle:(int)buttonTitle; +- (void)setHelpLinkTitle:(int)helpLinkTitle URL:(NSString*)url; @end
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 dab060a6..f52babb 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
@@ -4,248 +4,192 @@ #include "chrome/browser/ui/cocoa/tab_contents/sad_tab_view_cocoa.h" -#include <stddef.h> - -#include "base/logging.h" -#include "base/strings/sys_string_conversions.h" -#include "chrome/common/url_constants.h" -#include "chrome/grit/generated_resources.h" +#import "base/mac/foundation_util.h" #include "components/grit/components_scaled_resources.h" -#include "components/strings/grit/components_strings.h" #import "third_party/google_toolbox_for_mac/src/AppKit/GTMUILocalizerAndLayoutTweaker.h" #import "ui/base/cocoa/controls/blue_label_button.h" -#import "ui/base/cocoa/controls/hyperlink_text_view.h" #import "ui/base/cocoa/nscolor_additions.h" -#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_mac.h" #include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/image/image.h" + +namespace { // Maximum width used by page contents. -static const CGFloat kMaxContainerWidth = 600; +const CGFloat kMaxContainerWidth = 600; // Padding between icon and title. -static const CGFloat kIconTitleSpacing = 40; +const CGFloat kIconTitleSpacing = 40; // Padding between title and message. -static const CGFloat kTitleMessageSpacing = 18; +const CGFloat kTitleMessageSpacing = 18; // Padding between message and link. -static const CGFloat kMessageLinkSpacing = 50; +const CGFloat kMessageLinkSpacing = 50; // Padding between message and button. -static const CGFloat kMessageButtonSpacing = 44; +const CGFloat kMessageButtonSpacing = 44; // Minimum margins on all sides. -static const CGFloat kTabMargin = 13; +const CGFloat kTabMargin = 13; // Maximum margin on top. -static const CGFloat kMaxTopMargin = 130; +const CGFloat kMaxTopMargin = 130; -@interface SadTabTextView : NSTextField - -- (id)initWithStringResourceID:(int)stringResourceID; - -@end - -@implementation SadTabTextView - -- (id)initWithStringResourceID:(int)stringResourceID { - if (self = [super init]) { - base::scoped_nsobject<NSMutableParagraphStyle> style( - [[NSMutableParagraphStyle alloc] init]); - [style setLineSpacing:6]; - base::scoped_nsobject<NSAttributedString> title([[NSAttributedString alloc] - initWithString:l10n_util::GetNSString(stringResourceID) - attributes:@{ NSParagraphStyleAttributeName : style }]); - [self setAttributedStringValue:title]; - - [self setAlignment:NSLeftTextAlignment]; - [self setEditable:NO]; - [self setBezeled:NO]; - [self setAutoresizingMask:NSViewWidthSizable|NSViewMaxYMargin]; - } - return self; +NSTextField* MakeLabelTextField(NSRect frame) { + NSTextField* ret = [[[NSTextField alloc] initWithFrame:frame] autorelease]; + ret.autoresizingMask = NSViewWidthSizable | NSViewMaxYMargin; + ret.editable = NO; + ret.drawsBackground = NO; + ret.bezeled = NO; + return ret; } -- (BOOL)isOpaque { - return YES; -} +} // namespace -@end - -@interface SadTabContainerView : NSView<NSTextViewDelegate> { - @private - base::scoped_nsobject<NSImageView> image_; - base::scoped_nsobject<NSTextField> title_; - base::scoped_nsobject<NSTextField> message_; - base::scoped_nsobject<HyperlinkTextView> help_; - base::scoped_nsobject<NSButton> button_; -} - -- (instancetype)initWithBackgroundColor:(NSColor*)backgroundColor; - -@property(readonly,nonatomic) NSButton* reloadButton; - -// The height to fit the content elements within the current width. -@property(readonly,nonatomic) CGFloat contentHeight; - +@interface SadTabContainerView : NSView @end @implementation SadTabContainerView - -- (instancetype)initWithBackgroundColor:(NSColor*)backgroundColor { - if ((self = [super initWithFrame:NSZeroRect])) { - // Load resource for image and set it. - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - NSImage* iconImage = rb.GetNativeImageNamed(IDR_CRASH_SAD_TAB).ToNSImage(); - NSRect imageFrame = NSZeroRect; - imageFrame.size = [iconImage size]; - image_.reset([[NSImageView alloc] initWithFrame:imageFrame]); - [image_ setImage:iconImage]; - [image_ setAutoresizingMask:NSViewMaxXMargin|NSViewMaxYMargin]; - [self addSubview:image_]; - - // Set up the title. - title_.reset( - [[SadTabTextView alloc] initWithStringResourceID:IDS_SAD_TAB_TITLE]); - [title_ setFont:[NSFont systemFontOfSize:24]]; - [title_ setBackgroundColor:backgroundColor]; - [title_ setTextColor:[NSColor colorWithCalibratedWhite:38.0f/255.0f - alpha:1.0]]; - [title_ sizeToFit]; - [title_ setFrameOrigin: - NSMakePoint(0, NSMaxY(imageFrame) + kIconTitleSpacing)]; - [self addSubview:title_]; - - // Set up the message. - message_.reset( - [[SadTabTextView alloc] initWithStringResourceID:IDS_SAD_TAB_MESSAGE]); - [message_ setFont:[NSFont systemFontOfSize:14]]; - [message_ setBackgroundColor:backgroundColor]; - [message_ setTextColor:[NSColor colorWithCalibratedWhite:81.0f/255.0f - alpha:1.0]]; - [message_ setFrameOrigin: - NSMakePoint(0, NSMaxY([title_ frame]) + kTitleMessageSpacing)]; - [self addSubview:message_]; - - [self initializeHelpText]; - - button_.reset([[BlueLabelButton alloc] init]); - [button_ setTitle:l10n_util::GetNSString(IDS_SAD_TAB_RELOAD_LABEL)]; - [button_ sizeToFit]; - [button_ setTarget:self]; - [button_ setAction:@selector(reloadPage:)]; - [self addSubview:button_]; - } - return self; -} - - (BOOL)isFlipped { return YES; } - -- (NSButton*)reloadButton { - return button_; -} - -- (CGFloat)contentHeight { - return NSMaxY([button_ frame]); -} - -- (void)resizeSubviewsWithOldSize:(NSSize)oldSize { - [super resizeSubviewsWithOldSize:oldSize]; - - // |message_| can wrap to variable number of lines. - [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:message_]; - - [help_ setFrameOrigin: - NSMakePoint(0, NSMaxY([message_ frame]) + kMessageLinkSpacing)]; - - [button_ setFrameOrigin: - NSMakePoint(NSMaxX([self bounds]) - NSWidth([button_ frame]), - NSMaxY([message_ frame]) + kMessageButtonSpacing)]; -} - -- (void)initializeHelpText { - // Programmatically create the help link. Note that the frame's initial - // height must be set for the programmatic resizing to work. - NSFont* helpFont = [message_ font]; - NSRect helpFrame = NSMakeRect(0, 0, 1, [helpFont pointSize] + 4); - help_.reset([[HyperlinkTextView alloc] initWithFrame:helpFrame]); - [help_ setAutoresizingMask:NSViewWidthSizable|NSViewMaxYMargin]; - [help_ setDrawsBackground:YES]; - [help_ setBackgroundColor:[message_ backgroundColor]]; - [[help_ textContainer] setLineFragmentPadding:2]; // To align with message_. - [self addSubview:help_]; - [help_ setDelegate:self]; - - // Get the help text and link. - size_t linkOffset = 0; - const base::string16 helpLink = - l10n_util::GetStringUTF16(IDS_SAD_TAB_LEARN_MORE_LINK); - NSString* helpMessage(base::SysUTF16ToNSString(helpLink)); - [help_ setMessage:helpMessage - withFont:helpFont - messageColor:[message_ textColor]]; - [help_ addLinkRange:NSMakeRange(linkOffset, helpLink.length()) - withURL:@(chrome::kCrashReasonURL) - linkColor:[message_ textColor]]; - [help_ setAlignment:NSLeftTextAlignment]; - [help_ sizeToFit]; -} - -// Called when someone clicks on the embedded link. -- (BOOL)textView:(NSTextView*)textView - clickedOnLink:(id)link - atIndex:(NSUInteger)charIndex { - [NSApp sendAction:@selector(openLearnMoreAboutCrashLink:) to:nil from:self]; - return YES; -} - @end -@implementation SadTabView +@interface SadTabView ()<NSTextViewDelegate> +@end -+ (NSColor*)backgroundColor { - return [NSColor colorWithCalibratedWhite:245.0f/255.0f alpha:1.0]; +@implementation SadTabView { + NSView* container_; + NSImageView* icon_; + NSTextField* title_; + NSTextField* message_; + HyperlinkTextView* help_; + NSButton* button_; } +@synthesize delegate = delegate_; + - (instancetype)initWithFrame:(NSRect)frame { if ((self = [super initWithFrame:frame])) { - [self setWantsLayer:YES]; + self.wantsLayer = YES; + self.layer.backgroundColor = + [NSColor colorWithCalibratedWhite:245.0f / 255.0f alpha:1.0].cr_CGColor; + container_ = [[SadTabContainerView new] autorelease]; - container_.reset([[SadTabContainerView alloc] - initWithBackgroundColor:[SadTabView backgroundColor]]); + NSImage* iconImage = ResourceBundle::GetSharedInstance() + .GetNativeImageNamed(IDR_CRASH_SAD_TAB) + .ToNSImage(); + icon_ = [[NSImageView new] autorelease]; + icon_.image = iconImage; + icon_.frameSize = iconImage.size; + icon_.autoresizingMask = NSViewMaxXMargin | NSViewMaxYMargin; + [container_ addSubview:icon_]; + + CGFloat width = self.bounds.size.width; + title_ = MakeLabelTextField( + NSMakeRect(0, NSMaxY(icon_.frame) + kIconTitleSpacing, width, 0)); + title_.font = [NSFont systemFontOfSize:24]; + title_.textColor = + [NSColor colorWithCalibratedWhite:38.0f / 255.0f alpha:1.0]; + [title_ sizeToFit]; + [container_ addSubview:title_]; + + message_ = + MakeLabelTextField(NSMakeRect(0, NSMaxY(title_.frame), width, 0)); + base::mac::ObjCCast<NSCell>(message_.cell).wraps = YES; + message_.font = [NSFont systemFontOfSize:14]; + message_.textColor = + [NSColor colorWithCalibratedWhite:81.0f / 255.0f alpha:1.0]; + [container_ addSubview:message_]; + + help_ = [[[HyperlinkTextView alloc] + initWithFrame:NSMakeRect(0, 0, 1, message_.font.pointSize + 4)] + autorelease]; + help_.delegate = self; + help_.autoresizingMask = NSViewWidthSizable | NSViewMaxYMargin; + help_.textContainer.lineFragmentPadding = 2; // To align with message_. + [container_ addSubview:help_]; + + button_ = [[BlueLabelButton new] autorelease]; + button_.target = self; + button_.action = @selector(buttonClicked); + [container_ addSubview:button_]; + [self addSubview:container_]; } return self; } -- (CALayer*)makeBackingLayer { - CALayer* layer = [super makeBackingLayer]; - [layer setBackgroundColor:[[SadTabView backgroundColor] cr_CGColor]]; - return layer; -} - - (BOOL)isFlipped { return YES; } - (void)resizeSubviewsWithOldSize:(NSSize)oldSize { - NSRect bounds = [self bounds]; + [super resizeSubviewsWithOldSize:oldSize]; - // Set the container size first because its contentHeight will depend on its - // width. - NSSize frameSize = NSMakeSize( - std::min(NSWidth(bounds) - 2 * kTabMargin, kMaxContainerWidth), - NSHeight(bounds)); - [container_ setFrameSize:frameSize]; + NSSize size = self.bounds.size; + NSSize containerSize = NSMakeSize( + std::min(size.width - 2 * kTabMargin, kMaxContainerWidth), size.height); - // Center horizontally. - // Top margin is at least kTabMargin and at most kMaxTopMargin. - [container_ setFrameOrigin:NSMakePoint( - floor((NSWidth(bounds) - frameSize.width) / 2), - std::min(kMaxTopMargin, std::max(kTabMargin, - NSHeight(bounds) - [container_ contentHeight] - kTabMargin)))]; + // Set the container's size first because text wrapping depends on its width. + container_.frameSize = containerSize; + + // |message_| can wrap to variable number of lines. + [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField:message_]; + + message_.frameOrigin = + NSMakePoint(0, NSMaxY(title_.frame) + kTitleMessageSpacing); + help_.frameOrigin = + NSMakePoint(0, NSMaxY(message_.frame) + kMessageLinkSpacing); + + button_.frameOrigin = + NSMakePoint(containerSize.width - NSWidth(button_.bounds), + NSMaxY(message_.frame) + kMessageButtonSpacing); + + containerSize.height = NSMaxY(button_.frame); + container_.frameSize = containerSize; + + // Center. Top margin is must be between kTabMargin and kMaxTopMargin. + container_.frameOrigin = NSMakePoint( + floor((size.width - containerSize.width) / 2), + std::min(kMaxTopMargin, + std::max(kTabMargin, + size.height - containerSize.height - kTabMargin))); } -- (NSButton*)reloadButton { - return [container_ reloadButton]; +- (void)setTitle:(int)title { + NSMutableParagraphStyle* style = [[NSMutableParagraphStyle new] autorelease]; + style.lineSpacing = 6; + + title_.attributedStringValue = [[[NSAttributedString alloc] + initWithString:l10n_util::GetNSString(title) + attributes:@{NSParagraphStyleAttributeName : style}] autorelease]; +} + +- (void)setMessage:(int)message { + message_.stringValue = l10n_util::GetNSString(message); +} + +- (void)setButtonTitle:(int)buttonTitle { + button_.title = l10n_util::GetNSString(buttonTitle); + [button_ sizeToFit]; +} + +- (void)setHelpLinkTitle:(int)helpLinkTitle URL:(NSString*)url { + NSString* title = l10n_util::GetNSString(helpLinkTitle); + [help_ setMessage:title + withFont:message_.font + messageColor:message_.textColor]; + [help_ addLinkRange:NSMakeRange(0, title.length) + withURL:url + linkColor:message_.textColor]; + [help_ sizeToFit]; +} + +- (void)buttonClicked { + [delegate_ sadTabViewButtonClicked:self]; +} + +// Called when someone clicks on the embedded link. +- (BOOL)textView:(NSTextView*)textView + clickedOnLink:(id)link + atIndex:(NSUInteger)charIndex { + [delegate_ sadTabView:self helpLinkClickedWithURL:(NSString*)link]; + return YES; } @end
diff --git a/chrome/browser/ui/cocoa/translate/translate_bubble_controller.h b/chrome/browser/ui/cocoa/translate/translate_bubble_controller.h index 0aeb9631..913559a 100644 --- a/chrome/browser/ui/cocoa/translate/translate_bubble_controller.h +++ b/chrome/browser/ui/cocoa/translate/translate_bubble_controller.h
@@ -25,7 +25,8 @@ // pops up when clicking the Translate icon on Omnibox. This bubble // allows us to translate a foreign page into user-selected language, // revert this, and configure the translate setting. -@interface TranslateBubbleController : BaseBubbleController { +@interface TranslateBubbleController + : BaseBubbleController<NSTextViewDelegate> { @private content::WebContents* webContents_; std::unique_ptr<TranslateBubbleModel> model_; @@ -40,13 +41,20 @@ // The 'Cancel' button on the advanced (option) panel. NSButton* advancedCancelButton_; + // The 'Always translate' checkbox on the before panel. + // This is nil when the current WebContents is in an incognito window. + NSButton* beforeAlwaysTranslateCheckbox_; + // The 'Always translate' checkbox on the advanced (option) panel. // This is nil when the current WebContents is in an incognito window. - NSButton* alwaysTranslateCheckbox_; + NSButton* advancedAlwaysTranslateCheckbox_; // The 'Try again' button on the error panel. NSButton* tryAgainButton_; + // The '[x]' close button on the upper right side of the before panel. + NSButton* closeButton_; + // The combobox model which is used to deny translation at the view before // translate. std::unique_ptr<TranslateDenialComboboxModel> translateDenialComboboxModel_; @@ -59,6 +67,9 @@ // Whether the translation is actually executed once at least. BOOL translateExecuted_; + + // The state of the 'Always ...' checkboxes. + BOOL shouldAlwaysTranslate_; } @property(readonly, nonatomic) const content::WebContents* webContents; @@ -75,6 +86,6 @@ // The methods on this category are used internally by the controller and are // only exposed for testing purposes. DO NOT USE OTHERWISE. @interface TranslateBubbleController (ExposedForTesting) -- (void)handleTranslateButtonPressed; -- (void)handleDenialPopUpButtonNopeSelected; +- (IBAction)handleCloseButtonPressed:(id)sender; +- (IBAction)handleTranslateButtonPressed:(id)sender; @end
diff --git a/chrome/browser/ui/cocoa/translate/translate_bubble_controller.mm b/chrome/browser/ui/cocoa/translate/translate_bubble_controller.mm index cc2b6d2..1ab231bb 100644 --- a/chrome/browser/ui/cocoa/translate/translate_bubble_controller.mm +++ b/chrome/browser/ui/cocoa/translate/translate_bubble_controller.mm
@@ -12,8 +12,10 @@ #include "base/metrics/histogram_macros.h" #include "base/strings/sys_string_conversions.h" #include "chrome/browser/ui/chrome_pages.h" +#include "chrome/browser/ui/chrome_style.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/bubble_combobox.h" +#import "chrome/browser/ui/cocoa/hover_close_button.h" #import "chrome/browser/ui/cocoa/info_bubble_view.h" #import "chrome/browser/ui/cocoa/info_bubble_window.h" #import "chrome/browser/ui/cocoa/toolbar/toolbar_controller.h" @@ -26,7 +28,10 @@ #include "content/public/browser/browser_context.h" #include "content/public/common/referrer.h" #include "grit/components_strings.h" +#include "grit/ui_resources.h" +#include "skia/ext/skia_utils_mac.h" #include "ui/base/cocoa/cocoa_base_utils.h" +#include "ui/base/cocoa/controls/hyperlink_text_view.h" #import "ui/base/cocoa/controls/hyperlink_button_cell.h" #import "ui/base/cocoa/window_size_constants.h" #include "ui/base/l10n/l10n_util.h" @@ -45,7 +50,6 @@ items_.push_back(base::string16()); // Menu items in the drop down menu. - items_.push_back(l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_DENY)); items_.push_back(l10n_util::GetStringFUTF16( IDS_TRANSLATE_BUBBLE_NEVER_TRANSLATE_LANG, original_language_name)); @@ -66,6 +70,10 @@ DISALLOW_COPY_AND_ASSIGN(TranslateDenialComboboxModel); }; +const CGFloat kIconWidth = 30; +const CGFloat kIconHeight = 30; +const CGFloat kIconPadding = 12; + const CGFloat kWindowWidth = 320; // Padding between the window frame and content. @@ -73,7 +81,7 @@ const CGFloat kRelatedControlHorizontalSpacing = -2; -const CGFloat kRelatedControlVerticalSpacing = 4; +const CGFloat kRelatedControlVerticalSpacing = 8; const CGFloat kUnrelatedControlVerticalSpacing = 20; const CGFloat kContentWidth = kWindowWidth - 2 * kFramePadding; @@ -87,6 +95,12 @@ - (NSView*)newErrorView; - (NSView*)newAdvancedView; - (void)updateAdvancedView; +- (void)updateAlwaysCheckboxes; +- (NSImageView*)addIcon:(NSView*)view; +- (NSTextView*)addStyledTextView:(NSString*)message + toView:(NSView*)view + withRanges:(std::vector<NSRange>)ranges + delegate:(id<NSTextViewDelegate>)delegate; - (NSTextField*)addText:(NSString*)text toView:(NSView*)view; - (NSButton*)addLinkButtonWithText:(NSString*)text @@ -98,22 +112,25 @@ - (NSButton*)addCheckbox:(NSString*)title action:(SEL)action toView:(NSView*)view; +- (NSButton*)addCloseButton:(NSView*)view action:(SEL)action; - (NSPopUpButton*)addPopUpButton:(ui::ComboboxModel*)model action:(SEL)action toView:(NSView*)view; -- (void)handleAlwaysTranslateCheckboxPressed; -- (void)handleDoneButtonPressed; -- (void)handleCancelButtonPressed; -- (void)handleShowOriginalButtonPressed; -- (void)handleTryAgainButtonPressed; -- (void)handleAdvancedLinkButtonPressed; -- (void)handleLanguageSettingsLinkButtonPressed; -- (void)handleDenialPopUpButtonNopeSelected; -- (void)handleDenialPopUpButtonNeverTranslateLanguageSelected; -- (void)handleDenialPopUpButtonNeverTranslateSiteSelected; -- (void)handleSourceLanguagePopUpButtonSelectedItemChanged:(id)sender; -- (void)handleTargetLanguagePopUpButtonSelectedItemChanged:(id)sender; - +- (IBAction)handleAlwaysTranslateCheckboxPressed:(id)sender; +- (IBAction)handleDoneButtonPressed:(id)sender; +- (IBAction)handleCancelButtonPressed:(id)sender; +- (IBAction)handleCloseButtonPressed:(id)sender; +- (IBAction)handleShowOriginalButtonPressed:(id)sender; +- (IBAction)handleTryAgainButtonPressed:(id)sender; +- (IBAction)handleAdvancedLinkButtonPressed:(id)sender; +- (IBAction)handleLanguageSettingsLinkButtonPressed:(id)sender; +- (IBAction)handleDenialPopUpButtonNeverTranslateLanguageSelected:(id)sender; +- (IBAction)handleDenialPopUpButtonNeverTranslateSiteSelected:(id)sender; +- (IBAction)handleSourceLanguagePopUpButtonSelectedItemChanged:(id)sender; +- (IBAction)handleTargetLanguagePopUpButtonSelectedItemChanged:(id)sender; +- (BOOL)textView:(NSTextView*)aTextView + clickedOnLink:(id)link + atIndex:(NSUInteger)charIndex; @end @implementation TranslateBubbleController @@ -142,6 +159,13 @@ anchoredAt:NSZeroPoint])) { webContents_ = webContents; model_ = std::move(model); + + shouldAlwaysTranslate_ = model_->ShouldAlwaysTranslate(); + if (!webContents_->GetBrowserContext()->IsOffTheRecord()) { + shouldAlwaysTranslate_ = + model_->ShouldAlwaysTranslateBeCheckedByDefault(); + } + if (model_->GetViewState() != TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE) { translateExecuted_ = YES; @@ -160,7 +184,12 @@ [self newAdvancedView], } retain]); + // The [X] Close Button. + closeButton_ = [self addCloseButton:[[self window] contentView] + action:@selector(handleCloseButtonPressed:)]; + [self performLayout]; + translate::ReportUiAction(translate::BUBBLE_SHOWN); } return self; } @@ -204,8 +233,9 @@ } - (void)performLayout { + [self updateAlwaysCheckboxes]; NSWindow* window = [self window]; - [[window contentView] setSubviews:@[ [self currentView] ]]; + [[window contentView] setSubviews:@[ [self currentView], closeButton_ ]]; CGFloat height = NSHeight([[self currentView] frame]) + 2 * kFramePadding + info_bubble::kBubbleArrowHeight; @@ -213,6 +243,14 @@ NSRect windowFrame = [window contentRectForFrameRect:[[self window] frame]]; NSRect newWindowFrame = [window frameRectForContentRect:NSMakeRect( NSMinX(windowFrame), NSMaxY(windowFrame) - height, kWindowWidth, height)]; + + // Adjust the origin of closeButton. + CGFloat closeX = kWindowWidth - chrome_style::kCloseButtonPadding - + chrome_style::GetCloseButtonSize(); + CGFloat closeY = height - kFramePadding - chrome_style::kCloseButtonPadding - + info_bubble::kBubbleArrowHeight; + [closeButton_ setFrameOrigin:NSMakePoint(closeX, closeY)]; + [window setFrame:newWindowFrame display:YES animate:[[self window] isVisible]]; @@ -226,26 +264,32 @@ 0); NSView* view = [[NSView alloc] initWithFrame:contentFrame]; - NSString* message = - l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_BEFORE_TRANSLATE); - NSTextField* textLabel = [self addText:message - toView:view]; - message = l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_ADVANCED); - NSButton* advancedLinkButton = - [self addLinkButtonWithText:message - action:@selector(handleAdvancedLinkButtonPressed) - toView:view]; + base::string16 originalLanguageName = + model_->GetLanguageNameAt(model_->GetOriginalLanguageIndex()); + base::string16 targetLanguageName = + model_->GetLanguageNameAt(model_->GetTargetLanguageIndex()); + + std::vector<size_t> offsets; + NSString* message = l10n_util::GetNSStringF( + IDS_TRANSLATE_BUBBLE_BEFORE_TRANSLATE_NEW, originalLanguageName, + targetLanguageName, &offsets); + std::vector<NSRange> ranges; + ranges.push_back(NSMakeRange(offsets[0], originalLanguageName.length())); + ranges.push_back(NSMakeRange(offsets[1], targetLanguageName.length())); + + NSTextView* textLabel = [self addStyledTextView:message + toView:view + withRanges:ranges + delegate:self]; NSString* title = l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_ACCEPT); NSButton* translateButton = [self addButton:title - action:@selector(handleTranslateButtonPressed) + action:@selector(handleTranslateButtonPressed:) toView:view]; [translateButton setKeyEquivalent:@"\r"]; - base::string16 originalLanguageName = - model_->GetLanguageNameAt(model_->GetOriginalLanguageIndex()); // TODO(hajimehoshi): When TranslateDenialComboboxModel is factored out as a // common model, ui::MenuModel will be used here. translateDenialComboboxModel_.reset( @@ -257,16 +301,14 @@ [denyPopUpButton setPullsDown:YES]; [[denyPopUpButton itemAtIndex:1] setTarget:self]; [[denyPopUpButton itemAtIndex:1] - setAction:@selector(handleDenialPopUpButtonNopeSelected)]; + setAction:@selector( + handleDenialPopUpButtonNeverTranslateLanguageSelected:)]; [[denyPopUpButton itemAtIndex:2] setTarget:self]; [[denyPopUpButton itemAtIndex:2] - setAction:@selector(handleDenialPopUpButtonNeverTranslateLanguageSelected)]; - [[denyPopUpButton itemAtIndex:3] setTarget:self]; - [[denyPopUpButton itemAtIndex:3] - setAction:@selector(handleDenialPopUpButtonNeverTranslateSiteSelected)]; + setAction:@selector(handleDenialPopUpButtonNeverTranslateSiteSelected:)]; title = base::SysUTF16ToNSString( - l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_DENY)); + l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_OPTIONS_MENU_BUTTON)); [[denyPopUpButton itemAtIndex:0] setTitle:title]; // Adjust width for the first item. @@ -276,6 +318,17 @@ [denyPopUpButton sizeToFit]; [denyPopUpButton setMenu:originalMenu]; + // 'Always translate' checkbox + if (!webContents_->GetBrowserContext()->IsOffTheRecord()) { + title = + l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_ALWAYS_DO_THIS); + SEL action = @selector(handleAlwaysTranslateCheckboxPressed:); + beforeAlwaysTranslateCheckbox_ = + [self addCheckbox:title action:action toView:view]; + } + + NSImageView* icon = [self addIcon:view]; + // Layout CGFloat yPos = 0; @@ -293,11 +346,19 @@ yPos += NSHeight([translateButton frame]) + kUnrelatedControlVerticalSpacing; - [textLabel setFrameOrigin:NSMakePoint(0, yPos)]; - [advancedLinkButton setFrameOrigin:NSMakePoint( - NSWidth([textLabel frame]), yPos)]; + if (beforeAlwaysTranslateCheckbox_) { + [beforeAlwaysTranslateCheckbox_ + setFrameOrigin:NSMakePoint(kIconWidth + kIconPadding, yPos)]; - [view setFrameSize:NSMakeSize(kContentWidth, NSMaxY([textLabel frame]))]; + yPos += NSHeight([beforeAlwaysTranslateCheckbox_ frame]) + + kRelatedControlVerticalSpacing; + } + + [textLabel setFrameOrigin:NSMakePoint(kIconWidth + kIconPadding, yPos)]; + + yPos = NSMaxY([textLabel frame]); + [icon setFrameOrigin:NSMakePoint(0, yPos - kIconHeight)]; + [view setFrameSize:NSMakeSize(kContentWidth, yPos)]; return view; } @@ -318,9 +379,10 @@ l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_REVERT); NSButton* showOriginalButton = [self addButton:title - action:@selector(handleShowOriginalButtonPressed) + action:@selector(handleShowOriginalButtonPressed:) toView:view]; [showOriginalButton setEnabled:NO]; + NSImageView* icon = [self addIcon:view]; // Layout // TODO(hajimehoshi): Use l10n_util::VerticallyReflowGroup. @@ -332,9 +394,11 @@ yPos += NSHeight([showOriginalButton frame]) + kUnrelatedControlVerticalSpacing; - [textLabel setFrameOrigin:NSMakePoint(0, yPos)]; + [textLabel setFrameOrigin:NSMakePoint(kIconWidth + kIconPadding, yPos)]; - [view setFrameSize:NSMakeSize(kContentWidth, NSMaxY([textLabel frame]))]; + yPos = NSMaxY([textLabel frame]); + [icon setFrameOrigin:NSMakePoint(0, yPos - kIconHeight)]; + [view setFrameSize:NSMakeSize(kContentWidth, yPos)]; return view; } @@ -354,15 +418,17 @@ message = l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_ADVANCED); NSButton* advancedLinkButton = [self addLinkButtonWithText:message - action:@selector(handleAdvancedLinkButtonPressed) + action:@selector(handleAdvancedLinkButtonPressed:) toView:view]; NSString* title = l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_REVERT); NSButton* showOriginalButton = [self addButton:title - action:@selector(handleShowOriginalButtonPressed) + action:@selector(handleShowOriginalButtonPressed:) toView:view]; + NSImageView* icon = [self addIcon:view]; + // Layout CGFloat yPos = 0; @@ -372,11 +438,13 @@ yPos += NSHeight([showOriginalButton frame]) + kUnrelatedControlVerticalSpacing; - [textLabel setFrameOrigin:NSMakePoint(0, yPos)]; + [textLabel setFrameOrigin:NSMakePoint(kIconWidth + kIconPadding, yPos)]; [advancedLinkButton setFrameOrigin:NSMakePoint( NSMaxX([textLabel frame]), yPos)]; - [view setFrameSize:NSMakeSize(kContentWidth, NSMaxY([textLabel frame]))]; + yPos = NSMaxY([textLabel frame]); + [icon setFrameOrigin:NSMakePoint(0, yPos - kIconHeight)]; + [view setFrameSize:NSMakeSize(kContentWidth, yPos)]; return view; } @@ -395,14 +463,16 @@ message = l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_ADVANCED); NSButton* advancedLinkButton = [self addLinkButtonWithText:message - action:@selector(handleAdvancedLinkButtonPressed) + action:@selector(handleAdvancedLinkButtonPressed:) toView:view]; NSString* title = l10n_util::GetNSString(IDS_TRANSLATE_BUBBLE_TRY_AGAIN); tryAgainButton_ = [self addButton:title - action:@selector(handleTryAgainButtonPressed) + action:@selector(handleTryAgainButtonPressed:) toView:view]; + NSImageView* icon = [self addIcon:view]; + // Layout CGFloat yPos = 0; @@ -413,11 +483,13 @@ yPos += NSHeight([tryAgainButton_ frame]) + kUnrelatedControlVerticalSpacing; - [textLabel setFrameOrigin:NSMakePoint(0, yPos)]; + [textLabel setFrameOrigin:NSMakePoint(kIconWidth + kIconPadding, yPos)]; [advancedLinkButton setFrameOrigin:NSMakePoint(NSMaxX([textLabel frame]), yPos)]; - [view setFrameSize:NSMakeSize(kContentWidth, NSMaxY([textLabel frame]))]; + yPos = NSMaxY([textLabel frame]); + [icon setFrameOrigin:NSMakePoint(0, yPos - kIconHeight)]; + [view setFrameSize:NSMakeSize(kContentWidth, yPos)]; return view; } @@ -458,30 +530,28 @@ toView:view]; // 'Always translate' checkbox - BOOL isIncognitoWindow = webContents_ ? - webContents_->GetBrowserContext()->IsOffTheRecord() : NO; - if (!isIncognitoWindow) { + if (!webContents_->GetBrowserContext()->IsOffTheRecord()) { NSString* title = l10n_util::GetNSStringWithFixup(IDS_TRANSLATE_BUBBLE_ALWAYS); - action = @selector(handleAlwaysTranslateCheckboxPressed); - alwaysTranslateCheckbox_ = [self addCheckbox:title - action:action - toView:view]; + action = @selector(handleAlwaysTranslateCheckboxPressed:); + advancedAlwaysTranslateCheckbox_ = + [self addCheckbox:title action:action toView:view]; } // Buttons advancedDoneButton_ = [self addButton:l10n_util::GetNSStringWithFixup(IDS_DONE) - action:@selector(handleDoneButtonPressed) + action:@selector(handleDoneButtonPressed:) toView:view]; + [advancedDoneButton_ setKeyEquivalent:@"\r"]; advancedCancelButton_ = [self addButton:l10n_util::GetNSStringWithFixup(IDS_CANCEL) - action:@selector(handleCancelButtonPressed) + action:@selector(handleCancelButtonPressed:) toView:view]; NSString* message = l10n_util::GetNSStringWithFixup( IDS_TRANSLATE_BUBBLE_LANGUAGE_SETTINGS); - action = @selector(handleLanguageSettingsLinkButtonPressed); + action = @selector(handleLanguageSettingsLinkButtonPressed:); NSButton* languageSettingsLinkButton = [self addLinkButtonWithText:message action:action @@ -509,11 +579,12 @@ yPos = NSHeight([advancedDoneButton_ frame]) + kUnrelatedControlVerticalSpacing; - if (alwaysTranslateCheckbox_) { - [alwaysTranslateCheckbox_ setFrameOrigin:NSMakePoint(textLabelWidth, yPos)]; + if (advancedAlwaysTranslateCheckbox_) { + [advancedAlwaysTranslateCheckbox_ + setFrameOrigin:NSMakePoint(textLabelWidth, yPos)]; - yPos += NSHeight([alwaysTranslateCheckbox_ frame]) + - kRelatedControlVerticalSpacing; + yPos += NSHeight([advancedAlwaysTranslateCheckbox_ frame]) + + kRelatedControlVerticalSpacing; } CGFloat diffY = [[sourcePopUpButton cell] @@ -547,9 +618,6 @@ } - (void)updateAdvancedView { - NSInteger state = model_->ShouldAlwaysTranslate() ? NSOnState : NSOffState; - [alwaysTranslateCheckbox_ setState:state]; - NSString* title; if (model_->IsPageTranslatedInCurrentLanguages()) title = l10n_util::GetNSStringWithFixup(IDS_DONE); @@ -568,6 +636,55 @@ [advancedCancelButton_ setFrameOrigin:frame.origin]; } +- (void)updateAlwaysCheckboxes { + NSInteger state = shouldAlwaysTranslate_ ? NSOnState : NSOffState; + [beforeAlwaysTranslateCheckbox_ setState:state]; + [advancedAlwaysTranslateCheckbox_ setState:state]; +} + +- (NSImageView*)addIcon:(NSView*)view { + NSRect imageFrame = NSMakeRect(0, 0, kIconWidth, kIconHeight); + base::scoped_nsobject<NSImageView> image( + [[NSImageView alloc] initWithFrame:imageFrame]); + [image setImage:(ui::ResourceBundle::GetSharedInstance() + .GetImageNamed(IDR_TRANSLATE_ICON_BUBBLE) + .ToNSImage())]; + [view addSubview:image]; + return image.get(); +} + +- (NSTextView*)addStyledTextView:(NSString*)message + toView:(NSView*)view + withRanges:(std::vector<NSRange>)ranges + delegate:(id<NSTextViewDelegate>)delegate { + NSRect frame = + NSMakeRect(kFramePadding + kIconWidth + kIconPadding, kFramePadding, + kContentWidth - kIconWidth - kIconPadding, 0); + base::scoped_nsobject<HyperlinkTextView> styledText( + [[HyperlinkTextView alloc] initWithFrame:frame]); + [styledText setMessage:message + withFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]] + messageColor:(skia::SkColorToCalibratedNSColor(SK_ColorBLACK))]; + [styledText setDelegate:delegate]; + + NSColor* linkColor = + skia::SkColorToCalibratedNSColor(chrome_style::GetLinkColor()); + // Create the link with no underlining. + [styledText setLinkTextAttributes:nil]; + NSTextStorage* storage = [styledText textStorage]; + for (const auto& range : ranges) { + [styledText addLinkRange:range withURL:nil linkColor:linkColor]; + [storage addAttribute:NSUnderlineStyleAttributeName + value:@(NSUnderlineStyleNone) + range:range]; + } + + [view addSubview:styledText]; + [styledText setVerticallyResizable:YES]; + [styledText sizeToFit]; + return styledText.get(); +} + - (NSTextField*)addText:(NSString*)text toView:(NSView*)view { base::scoped_nsobject<NSTextField> textField( @@ -640,6 +757,17 @@ return button.get(); } +- (NSButton*)addCloseButton:(NSView*)view action:(SEL)action { + const int extent = chrome_style::GetCloseButtonSize(); + NSRect frame = NSMakeRect(0, 0, extent, extent); + base::scoped_nsobject<NSButton> button( + [[WebUIHoverCloseButton alloc] initWithFrame:frame]); + [button setTarget:self]; + [button setAction:action]; + [view addSubview:button.get()]; + return button.get(); +} + - (NSPopUpButton*)addPopUpButton:(ui::ComboboxModel*)model action:(SEL)action toView:(NSView*)view { @@ -654,24 +782,23 @@ return button.get(); } -- (void)handleTranslateButtonPressed { +- (IBAction)handleTranslateButtonPressed:(id)sender { + model_->SetAlwaysTranslate(shouldAlwaysTranslate_); translate::ReportUiAction(translate::TRANSLATE_BUTTON_CLICKED); translateExecuted_ = YES; model_->Translate(); } -- (void)handleAlwaysTranslateCheckboxPressed { - translate::ReportUiAction([alwaysTranslateCheckbox_ state] == NSOnState - ? translate::ALWAYS_TRANSLATE_CHECKED - : translate::ALWAYS_TRANSLATE_UNCHECKED); +- (IBAction)handleAlwaysTranslateCheckboxPressed:(id)sender { + shouldAlwaysTranslate_ = [sender state] == NSOnState; + translate::ReportUiAction(shouldAlwaysTranslate_ + ? translate::ALWAYS_TRANSLATE_CHECKED + : translate::ALWAYS_TRANSLATE_UNCHECKED); } -- (void)handleDoneButtonPressed { +- (IBAction)handleDoneButtonPressed:(id)sender { translate::ReportUiAction(translate::DONE_BUTTON_CLICKED); - if (alwaysTranslateCheckbox_) { - model_->SetAlwaysTranslate( - [alwaysTranslateCheckbox_ state] == NSOnState); - } + model_->SetAlwaysTranslate(shouldAlwaysTranslate_); if (model_->IsPageTranslatedInCurrentLanguages()) { model_->GoBackFromAdvanced(); [self performLayout]; @@ -682,29 +809,35 @@ } } -- (void)handleCancelButtonPressed { +- (IBAction)handleCancelButtonPressed:(id)sender { translate::ReportUiAction(translate::CANCEL_BUTTON_CLICKED); model_->GoBackFromAdvanced(); [self performLayout]; } -- (void)handleShowOriginalButtonPressed { +- (IBAction)handleCloseButtonPressed:(id)sender { + model_->DeclineTranslation(); + translate::ReportUiAction(translate::CLOSE_BUTTON_CLICKED); + [self close]; +} + +- (IBAction)handleShowOriginalButtonPressed:(id)sender { translate::ReportUiAction(translate::SHOW_ORIGINAL_BUTTON_CLICKED); model_->RevertTranslation(); [self close]; } -- (void)handleTryAgainButtonPressed { +- (IBAction)handleTryAgainButtonPressed:(id)sender { model_->Translate(); translate::ReportUiAction(translate::TRY_AGAIN_BUTTON_CLICKED); } -- (void)handleAdvancedLinkButtonPressed { +- (IBAction)handleAdvancedLinkButtonPressed:(id)sender { translate::ReportUiAction(translate::ADVANCED_LINK_CLICKED); [self switchView:TranslateBubbleModel::VIEW_STATE_ADVANCED]; } -- (void)handleLanguageSettingsLinkButtonPressed { +- (IBAction)handleLanguageSettingsLinkButtonPressed:(id)sender { GURL url = chrome::GetSettingsUrl(chrome::kLanguageOptionsSubPage); webContents_->OpenURL( content::OpenURLParams(url, content::Referrer(), NEW_FOREGROUND_TAB, @@ -713,38 +846,42 @@ [self close]; } -- (void)handleDenialPopUpButtonNopeSelected { - translate::ReportUiAction(translate::NOPE_MENU_CLICKED); - model_->DeclineTranslation(); - [self close]; -} - -- (void)handleDenialPopUpButtonNeverTranslateLanguageSelected { +- (IBAction)handleDenialPopUpButtonNeverTranslateLanguageSelected:(id)sender { translate::ReportUiAction(translate::NEVER_TRANSLATE_LANGUAGE_MENU_CLICKED); model_->DeclineTranslation(); model_->SetNeverTranslateLanguage(true); [self close]; } -- (void)handleDenialPopUpButtonNeverTranslateSiteSelected { +- (IBAction)handleDenialPopUpButtonNeverTranslateSiteSelected:(id)sender { translate::ReportUiAction(translate::NEVER_TRANSLATE_SITE_MENU_CLICKED); model_->DeclineTranslation(); model_->SetNeverTranslateSite(true); [self close]; } -- (void)handleSourceLanguagePopUpButtonSelectedItemChanged:(id)sender { +- (IBAction)handleSourceLanguagePopUpButtonSelectedItemChanged:(id)sender { translate::ReportUiAction(translate::SOURCE_LANGUAGE_MENU_CLICKED); NSPopUpButton* button = base::mac::ObjCCastStrict<NSPopUpButton>(sender); model_->UpdateOriginalLanguageIndex([button indexOfSelectedItem]); [self updateAdvancedView]; } -- (void)handleTargetLanguagePopUpButtonSelectedItemChanged:(id)sender { +- (IBAction)handleTargetLanguagePopUpButtonSelectedItemChanged:(id)sender { translate::ReportUiAction(translate::TARGET_LANGUAGE_MENU_CLICKED); NSPopUpButton* button = base::mac::ObjCCastStrict<NSPopUpButton>(sender); model_->UpdateTargetLanguageIndex([button indexOfSelectedItem]); [self updateAdvancedView]; } +// The NSTextViewDelegate method which called when user click on the +// source or target language on the before translate view. +- (BOOL)textView:(NSTextView*)aTextView + clickedOnLink:(id)link + atIndex:(NSUInteger)charIndex { + translate::ReportUiAction(translate::ADVANCED_LINK_CLICKED); + [self switchView:TranslateBubbleModel::VIEW_STATE_ADVANCED]; + return YES; +} + @end
diff --git a/chrome/browser/ui/cocoa/translate/translate_bubble_controller_unittest.mm b/chrome/browser/ui/cocoa/translate/translate_bubble_controller_unittest.mm index 4feceb8..937bf91 100644 --- a/chrome/browser/ui/cocoa/translate/translate_bubble_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/translate/translate_bubble_controller_unittest.mm
@@ -116,9 +116,9 @@ SwitchToErrorView(); NSView* errorView = [bubble() errorView]; - // We should have 3 subview inside the error view: - // A NSTextField and two NSButton. - EXPECT_EQ(3UL, [[errorView subviews] count]); + // We should have 4 subview inside the error view: + // A NSTextField, a NSImageView and two NSButton. + EXPECT_EQ(4UL, [[errorView subviews] count]); // one of the subview should be "Try again" button. EXPECT_TRUE([[errorView subviews] containsObject:[bubble() tryAgainButton]]); @@ -128,6 +128,40 @@ CloseBubble(); } +TEST_F(TranslateBubbleControllerTest, SwitchViews) { + // A basic test which just switch between views to make sure no crash. + EXPECT_FALSE(bubble()); + + ShowBubble(); + EXPECT_TRUE(bubble()); + + // Switch to during translating view. + [bubble() + switchView:(TranslateBubbleModel::ViewState::VIEW_STATE_TRANSLATING)]; + + EXPECT_TRUE(bubble()); + + // Switch to after translating view. + [bubble() + switchView:(TranslateBubbleModel::ViewState::VIEW_STATE_AFTER_TRANSLATE)]; + + EXPECT_TRUE(bubble()); + + // Switch to advanced view. + [bubble() switchView:(TranslateBubbleModel::ViewState::VIEW_STATE_ADVANCED)]; + + EXPECT_TRUE(bubble()); + + // Switch to before translating view. + [bubble() switchView: + (TranslateBubbleModel::ViewState::VIEW_STATE_BEFORE_TRANSLATE)]; + + EXPECT_TRUE(bubble()); + + CloseBubble(); + EXPECT_FALSE(bubble()); +} + TEST_F(TranslateBubbleControllerTest, CloseRegistersDecline) { const char kDeclineTranslateDismissUI[] = "Translate.DeclineTranslateDismissUI"; @@ -142,11 +176,12 @@ histogram_tester.ExpectTotalCount(kDeclineTranslate, 0); } - // A close while pressing e.g. 'Nope', registers as decline. + // A close while pressing e.g. 'x', registers as decline. { base::HistogramTester histogram_tester; ShowBubble(); - [bubble() handleDenialPopUpButtonNopeSelected]; + [bubble() handleCloseButtonPressed:nil]; + CloseBubble(); histogram_tester.ExpectTotalCount(kDeclineTranslateDismissUI, 0); histogram_tester.ExpectTotalCount(kDeclineTranslate, 1);
diff --git a/chrome/browser/ui/cocoa/translate/translate_bubble_test_utils_cocoa.mm b/chrome/browser/ui/cocoa/translate/translate_bubble_test_utils_cocoa.mm index 53e5d9f..bad6d18 100644 --- a/chrome/browser/ui/cocoa/translate/translate_bubble_test_utils_cocoa.mm +++ b/chrome/browser/ui/cocoa/translate/translate_bubble_test_utils_cocoa.mm
@@ -36,7 +36,7 @@ NSWindow* native_window = browser->window()->GetNativeWindow(); BrowserWindowController* controller = [BrowserWindowController browserWindowControllerForWindow:native_window]; - [[controller translateBubbleController] handleTranslateButtonPressed]; + [[controller translateBubbleController] handleTranslateButtonPressed:nil]; } } // namespace test_utils
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 3746bf4..101d6a1 100644 --- a/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.mm +++ b/chrome/browser/ui/cocoa/website_settings/permission_bubble_controller.mm
@@ -65,6 +65,8 @@ const CGFloat kBubbleMinWidth = 315.0f; const NSSize kPermissionIconSize = {18, 18}; +const NSInteger kFullscreenLeftOffset = 40; + } // namespace // NSPopUpButton with a menu containing two items: allow and block. @@ -208,6 +210,10 @@ // Called when the 'close' button is pressed. - (void)onClose:(id)sender; +// Returns the constant offset from the left to use for fullscreen permission +// bubbles. Only used in tests. ++ (NSInteger)getFullscreenLeftOffset; + // 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; @@ -256,9 +262,11 @@ [[parentWindow windowController] locationBarBridge]; anchor = location_bar->GetPageInfoBubblePoint(); } else { - // Center the bubble if there's no location bar. + // Position the bubble on the left of the screen if there is no page info + // button to point at. NSRect contentFrame = [[parentWindow contentView] frame]; - anchor = NSMakePoint(NSMidX(contentFrame), NSMaxY(contentFrame)); + anchor = NSMakePoint(NSMinX(contentFrame) + kFullscreenLeftOffset, + NSMaxY(contentFrame)); } return ui::ConvertPointFromWindowToScreen(parentWindow, anchor); @@ -484,8 +492,7 @@ } - (info_bubble::BubbleArrowLocation)getExpectedArrowLocation { - return [self hasVisibleLocationBar] ? info_bubble::kTopLeft - : info_bubble::kNoArrow; + return info_bubble::kTopLeft; } - (NSWindow*)getExpectedParentWindow { @@ -620,6 +627,10 @@ delegate_->Closing(); } ++ (NSInteger)getFullscreenLeftOffset { + return kFullscreenLeftOffset; +} + - (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 eaf37cf..e6c6338b6 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
@@ -38,6 +38,7 @@ - (void)onBlock:(id)sender; - (void)onCustomize:(id)sender; - (void)onCheckboxChanged:(id)sender; ++ (NSInteger)getFullscreenLeftOffset; @end @interface SplitBlockButton (ExposedForTesting) @@ -87,7 +88,7 @@ void TearDown() override { [controller_ close]; chrome::testing::NSRunLoopRunAllPending(); - STLDeleteElements(&requests_); + base::STLDeleteElements(&requests_); CocoaProfileTest::TearDown(); } @@ -374,10 +375,12 @@ NSPoint anchor = [controller_ getExpectedAnchorPoint]; - // Expected anchor location will be top center when there's no location bar. + // Expected anchor location will be top left when there's no location bar. NSWindow* window = browser()->window()->GetNativeWindow(); - NSRect frame = [window frame]; - NSPoint expected = NSMakePoint(frame.size.width / 2, frame.size.height); + NSRect frame = [[window contentView] frame]; + NSPoint expected = NSMakePoint( + NSMinX(frame) + [PermissionBubbleController getFullscreenLeftOffset], + NSMaxY(frame)); expected = ui::ConvertPointFromWindowToScreen(window, expected); EXPECT_NSEQ(expected, anchor); }
diff --git a/chrome/browser/ui/cocoa/website_settings/permission_prompt_impl_views_mac.mm b/chrome/browser/ui/cocoa/website_settings/permission_prompt_impl_views_mac.mm index 91311bd1..518e5b8 100644 --- a/chrome/browser/ui/cocoa/website_settings/permission_prompt_impl_views_mac.mm +++ b/chrome/browser/ui/cocoa/website_settings/permission_prompt_impl_views_mac.mm
@@ -28,9 +28,7 @@ } views::BubbleBorder::Arrow PermissionPromptImpl::GetAnchorArrow() { - return [PermissionBubbleController hasVisibleLocationBarForBrowser:browser_] - ? views::BubbleBorder::TOP_LEFT - : views::BubbleBorder::NONE; + return views::BubbleBorder::TOP_LEFT; } // static
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc index d141885..d4d6bdd 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -159,7 +159,7 @@ int title_id = GetIdForContentType(title_ids, num_title_ids, content_type()); if (title_id) - set_title(l10n_util::GetStringUTF8(title_id)); + set_title(l10n_util::GetStringUTF16(title_id)); } void ContentSettingSimpleBubbleModel::SetManageLink() { @@ -654,7 +654,7 @@ } else if (CameraAccessed()) { title_id = IDS_CAMERA_ACCESSED; } - set_title(l10n_util::GetStringUTF8(title_id)); + set_title(l10n_util::GetStringUTF16(title_id)); } void ContentSettingMediaStreamBubbleModel::SetRadioGroup() { @@ -1047,12 +1047,12 @@ // Note that we ignore the |title| parameter. if (previous_handler_.IsEmpty()) { - set_title(l10n_util::GetStringFUTF8( + set_title(l10n_util::GetStringFUTF16( IDS_REGISTER_PROTOCOL_HANDLER_CONFIRM, base::UTF8ToUTF16(pending_handler_.url().host()), protocol)); } else { - set_title(l10n_util::GetStringFUTF8( + set_title(l10n_util::GetStringFUTF16( IDS_REGISTER_PROTOCOL_HANDLER_CONFIRM_REPLACE, base::UTF8ToUTF16(pending_handler_.url().host()), protocol, @@ -1171,6 +1171,7 @@ Profile* profile) : ContentSettingBubbleModel(delegate, web_contents, profile) { SetTitle(); + SetMessage(); SetManageLink(); } @@ -1178,10 +1179,8 @@ ~ContentSettingSubresourceFilterBubbleModel() {} void ContentSettingSubresourceFilterBubbleModel::SetTitle() { - // TODO(melandory): For this bubble we need to introduce ability to have a - // caption (something which appears above title and has bigger font). - set_title(l10n_util::GetStringUTF8( - IDS_FILTERED_DECEPTIVE_CONTENT_PROMPT_EXPLANATION)); + set_title( + l10n_util::GetStringUTF16(IDS_FILTERED_DECEPTIVE_CONTENT_PROMPT_TITLE)); } void ContentSettingSubresourceFilterBubbleModel::SetManageLink() { @@ -1190,6 +1189,11 @@ l10n_util::GetStringUTF8(IDS_FILTERED_DECEPTIVE_CONTENT_PROMPT_RELOAD)); } +void ContentSettingSubresourceFilterBubbleModel::SetMessage() { + set_message(l10n_util::GetStringUTF16( + IDS_FILTERED_DECEPTIVE_CONTENT_PROMPT_EXPLANATION)); +} + void ContentSettingSubresourceFilterBubbleModel::OnManageLinkClicked() { subresource_filter::ContentSubresourceFilterDriverFactory* driver_factory = subresource_filter::ContentSubresourceFilterDriverFactory::
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.h b/chrome/browser/ui/content_settings/content_setting_bubble_model.h index 1105d57..315de036 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.h +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.h
@@ -112,7 +112,8 @@ BubbleContent(); ~BubbleContent(); - std::string title; + base::string16 title; + base::string16 message; ListItems list_items; RadioGroup radio_group; bool radio_group_enabled; @@ -188,7 +189,10 @@ Profile* profile() const { return profile_; } Delegate* delegate() const { return delegate_; } - void set_title(const std::string& title) { bubble_content_.title = title; } + void set_title(const base::string16& title) { bubble_content_.title = title; } + void set_message(const base::string16& message) { + bubble_content_.message = message; + } void add_list_item(const ListItem& item) { bubble_content_.list_items.push_back(item); } @@ -316,6 +320,8 @@ override; private: + void SetMessage(); + // ContentSettingBubbleModel: void SetTitle() override; void SetManageLink() override;
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc index 7f57540..3f15a0d 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
@@ -97,7 +97,7 @@ NULL, web_contents(), profile(), CONTENT_SETTINGS_TYPE_COOKIES)); const ContentSettingBubbleModel::BubbleContent& bubble_content = content_setting_bubble_model->bubble_content(); - std::string title = bubble_content.title; + base::string16 title = bubble_content.title; EXPECT_FALSE(title.empty()); ASSERT_EQ(2U, bubble_content.radio_group.radio_items.size()); EXPECT_FALSE(bubble_content.custom_link.empty()); @@ -152,7 +152,7 @@ const ContentSettingBubbleModel::BubbleContent& bubble_content = content_setting_bubble_model->bubble_content(); EXPECT_EQ(bubble_content.title, - l10n_util::GetStringUTF8(IDS_MICROPHONE_CAMERA_ALLOWED)); + l10n_util::GetStringUTF16(IDS_MICROPHONE_CAMERA_ALLOWED)); EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size()); EXPECT_EQ(bubble_content.radio_group.radio_items[0], l10n_util::GetStringFUTF8( @@ -511,7 +511,7 @@ const ContentSettingBubbleModel::BubbleContent& bubble_content = content_setting_bubble_model->bubble_content(); EXPECT_EQ(bubble_content.title, - l10n_util::GetStringUTF8(IDS_MICROPHONE_ACCESSED)); + l10n_util::GetStringUTF16(IDS_MICROPHONE_ACCESSED)); EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size()); EXPECT_EQ(bubble_content.radio_group.radio_items[0], l10n_util::GetStringFUTF8( @@ -542,7 +542,7 @@ const ContentSettingBubbleModel::BubbleContent& new_bubble_content = content_setting_bubble_model->bubble_content(); EXPECT_EQ(new_bubble_content.title, - l10n_util::GetStringUTF8(IDS_MICROPHONE_BLOCKED)); + l10n_util::GetStringUTF16(IDS_MICROPHONE_BLOCKED)); EXPECT_EQ(2U, new_bubble_content.radio_group.radio_items.size()); EXPECT_EQ(new_bubble_content.radio_group.radio_items[0], l10n_util::GetStringFUTF8( @@ -584,7 +584,7 @@ const ContentSettingBubbleModel::BubbleContent& bubble_content = content_setting_bubble_model->bubble_content(); EXPECT_EQ(bubble_content.title, - l10n_util::GetStringUTF8(IDS_CAMERA_ACCESSED)); + l10n_util::GetStringUTF16(IDS_CAMERA_ACCESSED)); EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size()); EXPECT_EQ(bubble_content.radio_group.radio_items[0], l10n_util::GetStringFUTF8( @@ -615,7 +615,7 @@ const ContentSettingBubbleModel::BubbleContent& new_bubble_content = content_setting_bubble_model->bubble_content(); EXPECT_EQ(new_bubble_content.title, - l10n_util::GetStringUTF8(IDS_CAMERA_BLOCKED)); + l10n_util::GetStringUTF16(IDS_CAMERA_BLOCKED)); EXPECT_EQ(2U, new_bubble_content.radio_group.radio_items.size()); EXPECT_EQ(new_bubble_content.radio_group.radio_items[0], l10n_util::GetStringFUTF8( @@ -659,7 +659,7 @@ const ContentSettingBubbleModel::BubbleContent& bubble_content = content_setting_bubble_model->bubble_content(); EXPECT_EQ(bubble_content.title, - l10n_util::GetStringUTF8(IDS_MICROPHONE_ACCESSED)); + l10n_util::GetStringUTF16(IDS_MICROPHONE_ACCESSED)); EXPECT_EQ(2U, bubble_content.radio_group.radio_items.size()); EXPECT_EQ(bubble_content.radio_group.radio_items[0], l10n_util::GetStringFUTF8( @@ -688,7 +688,7 @@ const ContentSettingBubbleModel::BubbleContent& new_bubble_content = content_setting_bubble_model->bubble_content(); EXPECT_EQ(new_bubble_content.title, - l10n_util::GetStringUTF8(IDS_MICROPHONE_CAMERA_ALLOWED)); + l10n_util::GetStringUTF16(IDS_MICROPHONE_CAMERA_ALLOWED)); EXPECT_EQ(2U, new_bubble_content.radio_group.radio_items.size()); EXPECT_EQ(new_bubble_content.radio_group.radio_items[0], l10n_util::GetStringFUTF8( @@ -736,7 +736,7 @@ const ContentSettingBubbleModel::BubbleContent& bubble_content = content_setting_bubble_model->bubble_content(); - std::string title = bubble_content.title; + base::string16 title = bubble_content.title; EXPECT_FALSE(title.empty()); ASSERT_EQ(2U, bubble_content.radio_group.radio_items.size()); std::string radio1 = bubble_content.radio_group.radio_items[0]; @@ -926,8 +926,11 @@ profile())); const ContentSettingBubbleModel::BubbleContent& bubble_content = content_setting_bubble_model->bubble_content(); - EXPECT_EQ(bubble_content.title, - l10n_util::GetStringUTF8( + EXPECT_EQ( + bubble_content.title, + l10n_util::GetStringUTF16(IDS_FILTERED_DECEPTIVE_CONTENT_PROMPT_TITLE)); + EXPECT_EQ(bubble_content.message, + l10n_util::GetStringUTF16( IDS_FILTERED_DECEPTIVE_CONTENT_PROMPT_EXPLANATION)); EXPECT_EQ(0U, bubble_content.radio_group.radio_items.size()); EXPECT_EQ(0, bubble_content.radio_group.default_item);
diff --git a/chrome/browser/ui/global_error/global_error_service.cc b/chrome/browser/ui/global_error/global_error_service.cc index 342815e..e0c70d278 100644 --- a/chrome/browser/ui/global_error/global_error_service.cc +++ b/chrome/browser/ui/global_error/global_error_service.cc
@@ -19,7 +19,7 @@ } GlobalErrorService::~GlobalErrorService() { - STLDeleteElements(&errors_); + base::STLDeleteElements(&errors_); } void GlobalErrorService::AddGlobalError(GlobalError* error) {
diff --git a/chrome/browser/ui/input_method/input_method_engine.h b/chrome/browser/ui/input_method/input_method_engine.h index 59f60476..2b3de7c5 100644 --- a/chrome/browser/ui/input_method/input_method_engine.h +++ b/chrome/browser/ui/input_method/input_method_engine.h
@@ -41,7 +41,6 @@ void HideImeWindow(int window_id); void CloseImeWindows(); - private: // input_method::InputMethodEngineBase: void FocusOut() override; void SetCompositionBounds(const std::vector<gfx::Rect>& bounds) override; @@ -52,6 +51,7 @@ const std::string& text) override; bool SendKeyEvent(ui::KeyEvent* ui_event, const std::string& code) override; + private: // ui::ImeWindowObserver: void OnWindowDestroyed(ui::ImeWindow* ime_window) override;
diff --git a/chrome/browser/ui/input_method/input_method_engine_unittest.cc b/chrome/browser/ui/input_method/input_method_engine_unittest.cc new file mode 100644 index 0000000..8664e8792 --- /dev/null +++ b/chrome/browser/ui/input_method/input_method_engine_unittest.cc
@@ -0,0 +1,260 @@ +// Copyright 2016 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/message_loop/message_loop.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/input_method/input_method_engine.h" +#include "chrome/browser/ui/input_method/input_method_engine_base.h" +#include "chrome/test/base/testing_profile.h" +#include "content/public/test/test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/ime/ime_bridge.h" +#include "ui/base/ime/ime_engine_handler_interface.h" +#include "ui/base/ime/mock_ime_input_context_handler.h" +#include "ui/base/ime/text_input_flags.h" + +namespace input_method { +namespace { +const char kTestExtensionId[] = "test_extension"; + +enum CallsBitmap { + NONE = 0U, + ONACTIVATE = 1U, + ONDEACTIVATED = 2U, + ONFOCUS = 4U, + ONBLUR = 8U, + ONKEYEVENT = 16U, + ONRESET = 32U, + ONCOMPOSITIONBOUNDSCHANGED = 64U, + ONSURROUNDINGTEXTCHANGED = 128U +}; + +// The surrounding information. +struct SurroundingInfo { + std::string text; + int focus; + int anchor; + int offset; +}; + +class KeyEventDoneCallback { + public: + explicit KeyEventDoneCallback(bool expected_argument) + : expected_argument_(expected_argument), is_called_(false) {} + ~KeyEventDoneCallback() {} + + void Run(bool consumed) { + if (consumed == expected_argument_) { + base::MessageLoop::current()->QuitWhenIdle(); + is_called_ = true; + } + } + + void WaitUntilCalled() { + while (!is_called_) + content::RunMessageLoop(); + } + + private: + bool expected_argument_; + bool is_called_; + + DISALLOW_COPY_AND_ASSIGN(KeyEventDoneCallback); +}; + +class TestObserver : public InputMethodEngineBase::Observer { + public: + TestObserver() : calls_bitmap_(NONE) {} + ~TestObserver() override {} + + // InputMethodEngineBase::Observer: + void OnActivate(const std::string& engine_id) override { + calls_bitmap_ |= ONACTIVATE; + } + void OnFocus( + const ui::IMEEngineHandlerInterface::InputContext& context) override { + calls_bitmap_ |= ONFOCUS; + } + void OnBlur(int context_id) override { calls_bitmap_ |= ONBLUR; } + void OnKeyEvent( + const std::string& engine_id, + const InputMethodEngineBase::KeyboardEvent& event, + ui::IMEEngineHandlerInterface::KeyEventDoneCallback& key_data) override { + calls_bitmap_ |= ONKEYEVENT; + key_event_ = event; + } + void OnReset(const std::string& engine_id) override { + calls_bitmap_ |= ONRESET; + } + void OnDeactivated(const std::string& engine_id) override { + calls_bitmap_ |= ONDEACTIVATED; + } + void OnCompositionBoundsChanged( + const std::vector<gfx::Rect>& bounds) override { + calls_bitmap_ |= ONCOMPOSITIONBOUNDSCHANGED; + composition_bounds_ = bounds; + } + bool IsInterestedInKeyEvent() const override { return true; } + void OnSurroundingTextChanged(const std::string& engine_id, + const std::string& text, + int cursor_pos, + int anchor_pos, + int offset) override { + calls_bitmap_ |= ONSURROUNDINGTEXTCHANGED; + surrounding_info_.text = text; + surrounding_info_.focus = cursor_pos; + surrounding_info_.anchor = anchor_pos; + surrounding_info_.offset = offset; + } + + // Returns and resets the bitmap |calls_bitmap_|. + unsigned char GetCallsBitmapAndReset() { + unsigned char ret = calls_bitmap_; + calls_bitmap_ = NONE; + return ret; + } + + const InputMethodEngineBase::KeyboardEvent& GetKeyEvent() { + return key_event_; + } + + const std::vector<gfx::Rect>& GetCompositionBounds() { + return composition_bounds_; + } + + const SurroundingInfo& GetSurroundingInfo() { return surrounding_info_; } + + private: + unsigned char calls_bitmap_; + InputMethodEngineBase::KeyboardEvent key_event_; + std::vector<gfx::Rect> composition_bounds_; + SurroundingInfo surrounding_info_; + + DISALLOW_COPY_AND_ASSIGN(TestObserver); +}; + +class InputMethodEngineTest : public testing::Test { + public: + InputMethodEngineTest() : observer_(nullptr) { + ui::IMEBridge::Initialize(); + mock_ime_input_context_handler_.reset(new ui::MockIMEInputContextHandler()); + ui::IMEBridge::Get()->SetInputContextHandler( + mock_ime_input_context_handler_.get()); + CreateEngine(kTestExtensionId); + } + ~InputMethodEngineTest() override { + ui::IMEBridge::Get()->SetInputContextHandler(nullptr); + engine_.reset(); + } + + protected: + void CreateEngine(const char* extension_id) { + engine_.reset(new InputMethodEngine()); + observer_ = new TestObserver(); + std::unique_ptr<InputMethodEngineBase::Observer> observer_ptr(observer_); + engine_->Initialize(std::move(observer_ptr), extension_id, profile_.get()); + } + + void FocusIn(ui::TextInputType input_type) { + ui::IMEEngineHandlerInterface::InputContext input_context( + input_type, ui::TEXT_INPUT_MODE_DEFAULT, ui::TEXT_INPUT_FLAG_NONE); + engine_->FocusIn(input_context); + ui::IMEBridge::Get()->SetCurrentInputContext(input_context); + } + + std::unique_ptr<InputMethodEngine> engine_; + + TestObserver* observer_; + std::unique_ptr<ui::MockIMEInputContextHandler> + mock_ime_input_context_handler_; + // The associated testing profile. + std::unique_ptr<TestingProfile> profile_; + + private: + DISALLOW_COPY_AND_ASSIGN(InputMethodEngineTest); +}; + +} // namespace + +// Tests input.ime.onActivate/onDeactivate/onFocus/onBlur API. +TEST_F(InputMethodEngineTest, TestActivateAndFocus) { + // Enables the extension with focus. + engine_->Enable(""); + FocusIn(ui::TEXT_INPUT_TYPE_URL); + EXPECT_EQ(ONACTIVATE | ONFOCUS, observer_->GetCallsBitmapAndReset()); + // Focus out. + engine_->FocusOut(); + EXPECT_EQ(ONBLUR, observer_->GetCallsBitmapAndReset()); + // Disables the extension. + engine_->Disable(); + EXPECT_EQ(ONDEACTIVATED, observer_->GetCallsBitmapAndReset()); +} + +// Tests input.ime.onKeyEvent API. +TEST_F(InputMethodEngineTest, TestKeyEvent) { + // Enables the extension with focus. + engine_->Enable(""); + FocusIn(ui::TEXT_INPUT_TYPE_URL); + EXPECT_EQ(ONACTIVATE | ONFOCUS, observer_->GetCallsBitmapAndReset()); + // Sends key events. + ui::KeyEvent key_event(ui::ET_KEY_PRESSED, ui::VKEY_A, ui::EF_NONE); + KeyEventDoneCallback callback(false); + ui::IMEEngineHandlerInterface::KeyEventDoneCallback keyevent_callback = + base::Bind(&KeyEventDoneCallback::Run, base::Unretained(&callback)); + engine_->ProcessKeyEvent(key_event, keyevent_callback); + EXPECT_EQ(ONKEYEVENT, observer_->GetCallsBitmapAndReset()); + EXPECT_EQ("keydown", observer_->GetKeyEvent().type); + EXPECT_EQ("a", observer_->GetKeyEvent().key); + EXPECT_EQ("KeyA", observer_->GetKeyEvent().code); + EXPECT_EQ('A', observer_->GetKeyEvent().key_code); + EXPECT_FALSE(observer_->GetKeyEvent().alt_key); + EXPECT_FALSE(observer_->GetKeyEvent().ctrl_key); + EXPECT_FALSE(observer_->GetKeyEvent().shift_key); + EXPECT_FALSE(observer_->GetKeyEvent().caps_lock); +} + +// Tests input.ime.onReset API. +TEST_F(InputMethodEngineTest, TestReset) { + // Enables the extension with focus. + engine_->Enable(""); + FocusIn(ui::TEXT_INPUT_TYPE_URL); + EXPECT_EQ(ONACTIVATE | ONFOCUS, observer_->GetCallsBitmapAndReset()); + + // Resets the engine. + engine_->Reset(); + EXPECT_EQ(ONRESET, observer_->GetCallsBitmapAndReset()); +} + +// Tests input.ime.onCompositionBoundsChanged API. +TEST_F(InputMethodEngineTest, TestCompositionBoundsChanged) { + // Enables the extension with focus. + engine_->Enable(""); + FocusIn(ui::TEXT_INPUT_TYPE_URL); + EXPECT_EQ(ONACTIVATE | ONFOCUS, observer_->GetCallsBitmapAndReset()); + // Sets the composition to trigger the composition bounds changed event. + std::vector<gfx::Rect> rects; + rects.push_back(gfx::Rect()); + engine_->SetCompositionBounds(rects); + EXPECT_EQ(ONCOMPOSITIONBOUNDSCHANGED, observer_->GetCallsBitmapAndReset()); + EXPECT_EQ(1U, observer_->GetCompositionBounds().size()); +} + +// Tests input.ime.onSurroundingTextChanged API. +TEST_F(InputMethodEngineTest, TestSurroundingTextChanged) { + // Enables the extension with focus. + engine_->Enable(""); + FocusIn(ui::TEXT_INPUT_TYPE_URL); + EXPECT_EQ(ONACTIVATE | ONFOCUS, observer_->GetCallsBitmapAndReset()); + // Sets the surrounding text. + engine_->SetSurroundingText("text" /* Surrounding text*/, + 0 /*focused position*/, 1 /*anchor position*/, + 0 /*offset position*/); + EXPECT_EQ(ONSURROUNDINGTEXTCHANGED, observer_->GetCallsBitmapAndReset()); + EXPECT_EQ("text", observer_->GetSurroundingInfo().text); + EXPECT_EQ(0, observer_->GetSurroundingInfo().focus); + EXPECT_EQ(1, observer_->GetSurroundingInfo().anchor); + EXPECT_EQ(0, observer_->GetSurroundingInfo().offset); +} + +} // namespace input_method
diff --git a/chrome/browser/ui/libgtk2ui/gtk2_ui.cc b/chrome/browser/ui/libgtk2ui/gtk2_ui.cc index b9d22c54..23512617 100644 --- a/chrome/browser/ui/libgtk2ui/gtk2_ui.cc +++ b/chrome/browser/ui/libgtk2ui/gtk2_ui.cc
@@ -439,6 +439,11 @@ if (dpi < 0) { const double kDefaultDPI = 96; + if (display::Display::HasForceDeviceScaleFactor()) { + dpi = display::Display::GetForcedDeviceScaleFactor() * kDefaultDPI; + return dpi; + } + GtkSettings* gtk_settings = gtk_settings_get_default(); CHECK(gtk_settings); gint gtk_dpi = -1;
diff --git a/chrome/browser/ui/login/login_handler_browsertest.cc b/chrome/browser/ui/login/login_handler_browsertest.cc index 6d8838f..84fe0e9 100644 --- a/chrome/browser/ui/login/login_handler_browsertest.cc +++ b/chrome/browser/ui/login/login_handler_browsertest.cc
@@ -103,6 +103,12 @@ const char kAuthBasicPage[] = "/auth-basic"; const char kAuthDigestPage[] = "/auth-digest"; +// It does not matter what pages are selected as no-auth, as long as they exist. +// Navigating to non-existing pages caused flakes in the past +// (https://crbug.com/636875). +const char kNoAuthPage1[] = "/simple.html"; +const char kNoAuthPage2[] = "/form.html"; + base::string16 ExpectedTitleFromAuth(const base::string16& username, const base::string16& password) { // The TestServer sets the title to username/password on successful login. @@ -317,101 +323,128 @@ EXPECT_EQ(expected_title2, title_watcher2.WaitAndGetTitle()); } -// Test login prompt cancellation. -IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, TestCancelAuth) { +// Test manual login prompt cancellation. +IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, TestCancelAuth_Manual) { ASSERT_TRUE(embedded_test_server()->Start()); - GURL auth_page = embedded_test_server()->GetURL(kAuthBasicPage); - GURL no_auth_page_1 = embedded_test_server()->GetURL("/a"); - GURL no_auth_page_2 = embedded_test_server()->GetURL("/b"); - GURL no_auth_page_3 = embedded_test_server()->GetURL("/c"); + const GURL kAuthURL = embedded_test_server()->GetURL(kAuthBasicPage); - content::WebContents* contents = - browser()->tab_strip_model()->GetActiveWebContents(); - NavigationController* controller = &contents->GetController(); + NavigationController* controller = + &browser()->tab_strip_model()->GetActiveWebContents()->GetController(); + + LoginPromptBrowserTestObserver observer; + observer.Register(content::Source<NavigationController>(controller)); + + WindowedLoadStopObserver load_stop_waiter(controller, 1); + WindowedAuthNeededObserver auth_needed_waiter(controller); + browser()->OpenURL(OpenURLParams(kAuthURL, Referrer(), CURRENT_TAB, + ui::PAGE_TRANSITION_TYPED, false)); + auth_needed_waiter.Wait(); + WindowedAuthCancelledObserver auth_cancelled_waiter(controller); + LoginHandler* handler = *observer.handlers().begin(); + ASSERT_TRUE(handler); + handler->CancelAuth(); + auth_cancelled_waiter.Wait(); + load_stop_waiter.Wait(); + EXPECT_TRUE(observer.handlers().empty()); +} + +// Test login prompt cancellation on navigation to a new page. +IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, TestCancelAuth_OnNavigation) { + ASSERT_TRUE(embedded_test_server()->Start()); + const GURL kAuthURL = embedded_test_server()->GetURL(kAuthBasicPage); + const GURL kNoAuthURL = embedded_test_server()->GetURL(kNoAuthPage1); + + NavigationController* controller = + &browser()->tab_strip_model()->GetActiveWebContents()->GetController(); + + LoginPromptBrowserTestObserver observer; + observer.Register(content::Source<NavigationController>(controller)); + + // One LOAD_STOP event for kAuthURL and one for kNoAuthURL. + const int kLoadStopEvents = 2; + WindowedLoadStopObserver load_stop_waiter(controller, kLoadStopEvents); + WindowedAuthNeededObserver auth_needed_waiter(controller); + browser()->OpenURL(OpenURLParams(kAuthURL, Referrer(), CURRENT_TAB, + ui::PAGE_TRANSITION_TYPED, false)); + auth_needed_waiter.Wait(); + WindowedAuthCancelledObserver auth_cancelled_waiter(controller); + // Navigating while auth is requested is the same as cancelling. + browser()->OpenURL(OpenURLParams(kNoAuthURL, Referrer(), CURRENT_TAB, + ui::PAGE_TRANSITION_TYPED, false)); + auth_cancelled_waiter.Wait(); + load_stop_waiter.Wait(); + EXPECT_TRUE(observer.handlers().empty()); +} + +// Test login prompt cancellation on navigation to back. +IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, TestCancelAuth_OnBack) { + ASSERT_TRUE(embedded_test_server()->Start()); + const GURL kAuthURL = embedded_test_server()->GetURL(kAuthBasicPage); + const GURL kNoAuthURL = embedded_test_server()->GetURL(kNoAuthPage1); + + NavigationController* controller = + &browser()->tab_strip_model()->GetActiveWebContents()->GetController(); LoginPromptBrowserTestObserver observer; observer.Register(content::Source<NavigationController>(controller)); // First navigate to an unauthenticated page so we have something to // go back to. - ui_test_utils::NavigateToURL(browser(), no_auth_page_1); + ui_test_utils::NavigateToURL(browser(), kNoAuthURL); - // Navigating while auth is requested is the same as cancelling. - { - // We need to wait for two LOAD_STOP events. One for auth_page and one for - // no_auth_page_2. - WindowedLoadStopObserver load_stop_waiter(controller, 2); - WindowedAuthNeededObserver auth_needed_waiter(controller); - browser()->OpenURL(OpenURLParams( - auth_page, Referrer(), CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, - false)); - auth_needed_waiter.Wait(); - WindowedAuthCancelledObserver auth_cancelled_waiter(controller); - browser()->OpenURL(OpenURLParams( - no_auth_page_2, Referrer(), CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, - false)); - auth_cancelled_waiter.Wait(); - load_stop_waiter.Wait(); - EXPECT_TRUE(observer.handlers().empty()); - } + // One LOAD_STOP event for kAuthURL and one for kNoAuthURL. + const int kLoadStopEvents = 2; + WindowedLoadStopObserver load_stop_waiter(controller, kLoadStopEvents); + WindowedAuthNeededObserver auth_needed_waiter(controller); + browser()->OpenURL(OpenURLParams(kAuthURL, Referrer(), CURRENT_TAB, + ui::PAGE_TRANSITION_TYPED, false)); + auth_needed_waiter.Wait(); + WindowedAuthCancelledObserver auth_cancelled_waiter(controller); + // Navigating back while auth is requested is the same as cancelling. + ASSERT_TRUE(controller->CanGoBack()); + controller->GoBack(); + auth_cancelled_waiter.Wait(); + load_stop_waiter.Wait(); + EXPECT_TRUE(observer.handlers().empty()); +} - // Try navigating backwards. - { - // As above, we wait for two LOAD_STOP events; one for each navigation. - WindowedLoadStopObserver load_stop_waiter(controller, 2); - WindowedAuthNeededObserver auth_needed_waiter(controller); - browser()->OpenURL(OpenURLParams( - auth_page, Referrer(), CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, - false)); - auth_needed_waiter.Wait(); - WindowedAuthCancelledObserver auth_cancelled_waiter(controller); - ASSERT_TRUE(chrome::CanGoBack(browser())); - chrome::GoBack(browser(), CURRENT_TAB); - auth_cancelled_waiter.Wait(); - load_stop_waiter.Wait(); - EXPECT_TRUE(observer.handlers().empty()); - } +// Test login prompt cancellation on navigation to forward. +IN_PROC_BROWSER_TEST_F(LoginPromptBrowserTest, TestCancelAuth_OnForward) { + ASSERT_TRUE(embedded_test_server()->Start()); + const GURL kAuthURL = embedded_test_server()->GetURL(kAuthBasicPage); + const GURL kNoAuthURL1 = embedded_test_server()->GetURL(kNoAuthPage1); + const GURL kNoAuthURL2 = embedded_test_server()->GetURL(kNoAuthPage2); + + NavigationController* controller = + &browser()->tab_strip_model()->GetActiveWebContents()->GetController(); + + LoginPromptBrowserTestObserver observer; + observer.Register(content::Source<NavigationController>(controller)); + + ui_test_utils::NavigateToURL(browser(), kNoAuthURL1); // Now add a page and go back, so we have something to go forward to. - ui_test_utils::NavigateToURL(browser(), no_auth_page_3); + ui_test_utils::NavigateToURL(browser(), kNoAuthURL2); { WindowedLoadStopObserver load_stop_waiter(controller, 1); - chrome::GoBack(browser(), CURRENT_TAB); // Should take us to page 1 + ASSERT_TRUE(controller->CanGoBack()); + controller->GoBack(); load_stop_waiter.Wait(); } - { - // We wait for two LOAD_STOP events; one for each navigation. - WindowedLoadStopObserver load_stop_waiter(controller, 2); - WindowedAuthNeededObserver auth_needed_waiter(controller); - browser()->OpenURL(OpenURLParams( - auth_page, Referrer(), CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, - false)); - auth_needed_waiter.Wait(); - WindowedAuthCancelledObserver auth_cancelled_waiter(controller); - ASSERT_TRUE(chrome::CanGoForward(browser())); - chrome::GoForward(browser(), CURRENT_TAB); // Should take us to page 3 - auth_cancelled_waiter.Wait(); - load_stop_waiter.Wait(); - EXPECT_TRUE(observer.handlers().empty()); - } - - // Now test that cancelling works as expected. - { - WindowedLoadStopObserver load_stop_waiter(controller, 1); - WindowedAuthNeededObserver auth_needed_waiter(controller); - browser()->OpenURL(OpenURLParams( - auth_page, Referrer(), CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, - false)); - auth_needed_waiter.Wait(); - WindowedAuthCancelledObserver auth_cancelled_waiter(controller); - LoginHandler* handler = *observer.handlers().begin(); - ASSERT_TRUE(handler); - handler->CancelAuth(); - auth_cancelled_waiter.Wait(); - load_stop_waiter.Wait(); - EXPECT_TRUE(observer.handlers().empty()); - } + // One LOAD_STOP event for kAuthURL and one for kNoAuthURL. + const int kLoadStopEvents = 2; + WindowedLoadStopObserver load_stop_waiter(controller, kLoadStopEvents); + WindowedAuthNeededObserver auth_needed_waiter(controller); + browser()->OpenURL(OpenURLParams(kAuthURL, Referrer(), CURRENT_TAB, + ui::PAGE_TRANSITION_TYPED, false)); + auth_needed_waiter.Wait(); + WindowedAuthCancelledObserver auth_cancelled_waiter(controller); + ASSERT_TRUE(controller->CanGoForward()); + controller->GoForward(); + auth_cancelled_waiter.Wait(); + load_stop_waiter.Wait(); + EXPECT_TRUE(observer.handlers().empty()); } // Test handling of resources that require authentication even though
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc index 8fe645b..72d8ac2 100644 --- a/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc +++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model.cc
@@ -41,11 +41,8 @@ return Profile::FromBrowserContext(web_contents->GetBrowserContext()); } -void CleanStatisticsForSite(content::WebContents* web_contents, - const GURL& origin) { - DCHECK(web_contents); - Profile* profile = - Profile::FromBrowserContext(web_contents->GetBrowserContext()); +void CleanStatisticsForSite(Profile* profile, const GURL& origin) { + DCHECK(profile); password_manager::PasswordStore* password_store = PasswordStoreFactory::GetForProfile(profile, ServiceAccessType::IMPLICIT_ACCESS) @@ -173,7 +170,7 @@ password_manager::metrics_util::CHROME_SIGNIN_OK || sign_in_promo_dismissal_reason_ == password_manager::metrics_util::CHROME_SIGNIN_CANCEL) { - DCHECK(model->web_contents()); + DCHECK(model->delegate_); int show_count = model->GetProfile()->GetPrefs()->GetInteger( password_manager::prefs::kNumberSignInPasswordPromoShown); UMA_HISTOGRAM_COUNTS_100("PasswordManager.SignInPromoCountTilClick", @@ -192,13 +189,9 @@ metrics_util::NO_UPDATE_SUBMISSION) { update_password_submission_event_ = model->GetUpdateDismissalReason(NO_INTERACTION); - PasswordsModelDelegate* delegate = - model->web_contents() - ? PasswordsModelDelegateFromWebContents(model->web_contents()) - : nullptr; - if (delegate && + if (model->delegate_ && model->state() == password_manager::ui::PENDING_PASSWORD_UPDATE_STATE) - delegate->OnNoInteractionOnUpdate(); + model->delegate_->OnNoInteractionOnUpdate(); } if (update_password_submission_event_ != metrics_util::NO_UPDATE_SUBMISSION) @@ -207,25 +200,22 @@ } ManagePasswordsBubbleModel::ManagePasswordsBubbleModel( - content::WebContents* web_contents, + base::WeakPtr<PasswordsModelDelegate> delegate, DisplayReason display_reason) - : content::WebContentsObserver(web_contents), - password_overridden_(false) { - PasswordsModelDelegate* delegate = - PasswordsModelDelegateFromWebContents(web_contents); - - origin_ = delegate->GetOrigin(); - state_ = delegate->GetState(); + : password_overridden_(false), + delegate_(std::move(delegate)) { + origin_ = delegate_->GetOrigin(); + state_ = delegate_->GetState(); if (state_ == password_manager::ui::PENDING_PASSWORD_STATE || state_ == password_manager::ui::PENDING_PASSWORD_UPDATE_STATE) { - pending_password_ = delegate->GetPendingPassword(); - local_credentials_ = DeepCopyForms(delegate->GetCurrentForms()); + pending_password_ = delegate_->GetPendingPassword(); + local_credentials_ = DeepCopyForms(delegate_->GetCurrentForms()); } else if (state_ == password_manager::ui::CONFIRMATION_STATE) { // We don't need anything. } else if (state_ == password_manager::ui::AUTO_SIGNIN_STATE) { - pending_password_ = delegate->GetPendingPassword(); + pending_password_ = delegate_->GetPendingPassword(); } else { - local_credentials_ = DeepCopyForms(delegate->GetCurrentForms()); + local_credentials_ = DeepCopyForms(delegate_->GetCurrentForms()); } if (state_ == password_manager::ui::PENDING_PASSWORD_STATE || @@ -264,14 +254,14 @@ interaction_stats.origin_domain = origin_.GetOrigin(); interaction_stats.username_value = pending_password_.username_value; password_manager::InteractionsStats* stats = - delegate->GetCurrentInteractionStats(); + delegate_->GetCurrentInteractionStats(); if (stats) { DCHECK_EQ(interaction_stats.username_value, stats->username_value); DCHECK_EQ(interaction_stats.origin_domain, stats->origin_domain); interaction_stats.dismissal_count = stats->dismissal_count; } } else if (state_ == password_manager::ui::PENDING_PASSWORD_UPDATE_STATE) { - password_overridden_ = delegate->IsPasswordOverridden(); + password_overridden_ = delegate_->IsPasswordOverridden(); } manage_link_ = @@ -327,17 +317,13 @@ interaction_keeper_.reset(new InteractionKeeper(std::move(interaction_stats), display_disposition)); - delegate->OnBubbleShown(); + delegate_->OnBubbleShown(); } ManagePasswordsBubbleModel::~ManagePasswordsBubbleModel() { interaction_keeper_->ReportInteractions(this); - // web_contents() is nullptr if the tab is closing. - PasswordsModelDelegate* delegate = - web_contents() ? PasswordsModelDelegateFromWebContents(web_contents()) - : nullptr; - if (delegate) - delegate->OnBubbleHidden(); + if (delegate_) + delegate_->OnBubbleHidden(); } void ManagePasswordsBubbleModel::OnNeverForThisSiteClicked() { @@ -345,8 +331,8 @@ interaction_keeper_->set_dismissal_reason(metrics_util::CLICKED_NEVER); interaction_keeper_->set_update_password_submission_event( GetUpdateDismissalReason(NOPE_CLICKED)); - CleanStatisticsForSite(web_contents(), origin_); - PasswordsModelDelegateFromWebContents(web_contents())->NeverSavePassword(); + CleanStatisticsForSite(GetProfile(), origin_); + delegate_->NeverSavePassword(); } void ManagePasswordsBubbleModel::OnSaveClicked() { @@ -354,22 +340,21 @@ interaction_keeper_->set_dismissal_reason(metrics_util::CLICKED_SAVE); interaction_keeper_->set_update_password_submission_event( GetUpdateDismissalReason(UPDATE_CLICKED)); - CleanStatisticsForSite(web_contents(), origin_); - PasswordsModelDelegateFromWebContents(web_contents())->SavePassword(); + CleanStatisticsForSite(GetProfile(), origin_); + delegate_->SavePassword(); } void ManagePasswordsBubbleModel::OnNopeUpdateClicked() { interaction_keeper_->set_update_password_submission_event( GetUpdateDismissalReason(NOPE_CLICKED)); - PasswordsModelDelegateFromWebContents(web_contents())->OnNopeUpdateClicked(); + delegate_->OnNopeUpdateClicked(); } void ManagePasswordsBubbleModel::OnUpdateClicked( const autofill::PasswordForm& password_form) { interaction_keeper_->set_update_password_submission_event( GetUpdateDismissalReason(UPDATE_CLICKED)); - PasswordsModelDelegateFromWebContents(web_contents())->UpdatePassword( - password_form); + delegate_->UpdatePassword(password_form); } void ManagePasswordsBubbleModel::OnDoneClicked() { @@ -386,18 +371,15 @@ interaction_keeper_->set_dismissal_reason(metrics_util::CLICKED_MANAGE); if (GetSmartLockBrandingState(GetProfile()) == password_bubble_experiment::SmartLockBranding::FULL) { - PasswordsModelDelegateFromWebContents(web_contents()) - ->NavigateToExternalPasswordManager(); + delegate_->NavigateToExternalPasswordManager(); } else { - PasswordsModelDelegateFromWebContents(web_contents()) - ->NavigateToPasswordManagerSettingsPage(); + delegate_->NavigateToPasswordManagerSettingsPage(); } } void ManagePasswordsBubbleModel::OnBrandLinkClicked() { interaction_keeper_->set_dismissal_reason(metrics_util::CLICKED_BRAND_NAME); - PasswordsModelDelegateFromWebContents(web_contents()) - ->NavigateToSmartLockHelpPage(); + delegate_->NavigateToSmartLockHelpPage(); } void ManagePasswordsBubbleModel::OnAutoSignInToastTimeout() { @@ -426,8 +408,7 @@ metrics_util::CHROME_SIGNIN_OK); GetProfile()->GetPrefs()->SetBoolean( password_manager::prefs::kWasSignInPasswordPromoClicked, true); - PasswordsModelDelegateFromWebContents(web_contents()) - ->NavigateToChromeSignIn(); + delegate_->NavigateToChromeSignIn(); } void ManagePasswordsBubbleModel::OnSkipSignInClicked() { @@ -438,7 +419,11 @@ } Profile* ManagePasswordsBubbleModel::GetProfile() const { - return GetProfileFromWebContents(web_contents()); + return GetProfileFromWebContents(GetWebContents()); +} + +content::WebContents* ManagePasswordsBubbleModel::GetWebContents() const { + return delegate_ ? delegate_->GetWebContents() : nullptr; } bool ManagePasswordsBubbleModel::ShouldShowMultipleAccountUpdateUI() const { @@ -491,14 +476,14 @@ ? PasswordTittleType::SAVE_PASSWORD : PasswordTittleType::SAVE_ACCOUNT); GetSavePasswordDialogTitleTextAndLinkRange( - web_contents()->GetVisibleURL(), origin_, + GetWebContents()->GetVisibleURL(), origin_, GetSmartLockBrandingState(GetProfile()) != password_bubble_experiment::SmartLockBranding::NONE, type, &title_, &title_brand_link_range_); } void ManagePasswordsBubbleModel::UpdateManageStateTitle() { - GetManagePasswordsDialogTitleText(web_contents()->GetVisibleURL(), origin_, + GetManagePasswordsDialogTitleText(GetWebContents()->GetVisibleURL(), origin_, &title_); }
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model.h b/chrome/browser/ui/passwords/manage_passwords_bubble_model.h index 2b01a57b..0fcc2c9 100644 --- a/chrome/browser/ui/passwords/manage_passwords_bubble_model.h +++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model.h
@@ -9,34 +9,34 @@ #include "base/macros.h" #include "base/memory/scoped_vector.h" +#include "base/memory/weak_ptr.h" #include "base/time/clock.h" #include "components/autofill/core/common/password_form.h" #include "components/password_manager/core/browser/password_manager_metrics_util.h" #include "components/password_manager/core/browser/statistics_table.h" #include "components/password_manager/core/common/password_manager_ui.h" -#include "content/public/browser/web_contents_observer.h" #include "ui/gfx/range/range.h" -class Profile; - namespace content { class WebContents; } +class PasswordsModelDelegate; +class Profile; + // This model provides data for the ManagePasswordsBubble and controls the // password management actions. -class ManagePasswordsBubbleModel : public content::WebContentsObserver { +class ManagePasswordsBubbleModel { public: enum PasswordAction { REMOVE_PASSWORD, ADD_PASSWORD }; enum DisplayReason { AUTOMATIC, USER_ACTION }; - // Creates a ManagePasswordsBubbleModel, which holds a raw pointer to the - // WebContents in which it lives. Construction implies that the bubble - // is shown. The bubble's state is updated from the - // ManagePasswordsUIController associated with |web_contents|. - ManagePasswordsBubbleModel(content::WebContents* web_contents, + // Creates a ManagePasswordsBubbleModel, which holds a weak pointer to the + // delegate. Construction implies that the bubble is shown. The bubble's state + // is updated from the ManagePasswordsUIController associated with |delegate|. + ManagePasswordsBubbleModel(base::WeakPtr<PasswordsModelDelegate> delegate, DisplayReason reason); - ~ManagePasswordsBubbleModel() override; + ~ManagePasswordsBubbleModel(); // Called by the view code when the "Nope" button in clicked by the user in // update bubble. @@ -104,6 +104,7 @@ } Profile* GetProfile() const; + content::WebContents* GetWebContents() const; // Returns true iff the multiple account selection prompt for account update // should be presented. @@ -151,6 +152,9 @@ // Responsible for recording all the interactions required. std::unique_ptr<InteractionKeeper> interaction_keeper_; + // A bridge to ManagePasswordsUIController instance. + base::WeakPtr<PasswordsModelDelegate> delegate_; + DISALLOW_COPY_AND_ASSIGN(ManagePasswordsBubbleModel); };
diff --git a/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc index b4930e62..cfbeb72 100644 --- a/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc +++ b/chrome/browser/ui/passwords/manage_passwords_bubble_model_unittest.cc
@@ -16,7 +16,7 @@ #include "chrome/browser/password_manager/password_store_factory.h" #include "chrome/browser/sync/profile_sync_service_factory.h" #include "chrome/browser/sync/profile_sync_test_util.h" -#include "chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h" +#include "chrome/browser/ui/passwords/passwords_model_delegate_mock.h" #include "chrome/test/base/testing_profile.h" #include "components/browser_sync/browser/profile_sync_service_mock.h" #include "components/password_manager/core/browser/mock_password_store.h" @@ -29,6 +29,7 @@ #include "components/password_manager/core/common/password_manager_ui.h" #include "components/prefs/pref_service.h" #include "components/variations/variations_associated_data.h" +#include "content/public/browser/web_contents.h" #include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/web_contents_tester.h" #include "testing/gmock/include/gmock/gmock.h" @@ -96,10 +97,7 @@ void SetUp() override { test_web_contents_.reset( content::WebContentsTester::CreateTestWebContents(&profile_, nullptr)); - // Create the test UIController here so that it's bound to - // |test_web_contents_| and therefore accessible to the model. - new testing::StrictMock<ManagePasswordsUIControllerMock>( - test_web_contents_.get()); + mock_delegate_.reset(new testing::StrictMock<PasswordsModelDelegateMock>); PasswordStoreFactory::GetInstance()->SetTestingFactoryAndUse( profile(), password_manager::BuildPasswordStore< @@ -108,8 +106,8 @@ } void TearDown() override { - // Reset WebContents first. It can happen if the user closes the tab. - test_web_contents_.reset(); + // Reset the delegate first. It can happen if the user closes the tab. + mock_delegate_.reset(); model_.reset(); variations::testing::ClearAllVariationIDs(); variations::testing::ClearAllVariationParams(); @@ -126,13 +124,10 @@ .get()); } - ManagePasswordsUIControllerMock* controller() { - return static_cast<ManagePasswordsUIControllerMock*>( - PasswordsModelDelegateFromWebContents(test_web_contents_.get())); + PasswordsModelDelegateMock* controller() { + return mock_delegate_.get(); } - content::WebContents* test_web_contents() { return test_web_contents_.get(); } - ManagePasswordsBubbleModel* model() { return model_.get(); } void SetUpWithState(password_manager::ui::State state, @@ -155,19 +150,23 @@ std::unique_ptr<content::WebContents> test_web_contents_; base::FieldTrialList field_trials_; std::unique_ptr<ManagePasswordsBubbleModel> model_; + std::unique_ptr<PasswordsModelDelegateMock> mock_delegate_; }; void ManagePasswordsBubbleModelTest::SetUpWithState( password_manager::ui::State state, ManagePasswordsBubbleModel::DisplayReason reason) { - ManagePasswordsUIControllerMock* mock = controller(); GURL origin(kSiteOrigin); - EXPECT_CALL(*mock, GetOrigin()).WillOnce(ReturnRef(origin)); - EXPECT_CALL(*mock, GetState()).WillOnce(Return(state)); - EXPECT_CALL(*mock, OnBubbleShown()); + EXPECT_CALL(*controller(), GetOrigin()).WillOnce(ReturnRef(origin)); + EXPECT_CALL(*controller(), GetState()).WillOnce(Return(state)); + EXPECT_CALL(*controller(), OnBubbleShown()); + EXPECT_CALL(*controller(), GetWebContents()).WillRepeatedly( + Return(test_web_contents_.get())); model_.reset( - new ManagePasswordsBubbleModel(test_web_contents_.get(), reason)); - ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(mock)); + new ManagePasswordsBubbleModel(mock_delegate_->AsWeakPtr(), reason)); + ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(controller())); + EXPECT_CALL(*controller(), GetWebContents()).WillRepeatedly( + Return(test_web_contents_.get())); } void ManagePasswordsBubbleModelTest::PretendPasswordWaiting() { @@ -208,13 +207,9 @@ } void ManagePasswordsBubbleModelTest::DestroyModel() { - ManagePasswordsUIControllerMock* mock = - test_web_contents_ ? controller() : nullptr; - if (mock) - EXPECT_CALL(*mock, OnBubbleHidden()); + EXPECT_CALL(*controller(), OnBubbleHidden()); model_.reset(); - if (mock) - ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(mock)); + ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(controller())); } void ManagePasswordsBubbleModelTest::DestroyModelExpectReason(
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc index 81f5748..3ea412b 100644 --- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc +++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
@@ -59,7 +59,8 @@ ManagePasswordsUIController::ManagePasswordsUIController( content::WebContents* web_contents) : content::WebContentsObserver(web_contents), - bubble_status_(NOT_SHOWN) { + bubble_status_(NOT_SHOWN), + weak_ptr_factory_(this) { passwords_data_.set_client( ChromePasswordManagerClient::FromWebContents(web_contents)); password_manager::PasswordStore* password_store = @@ -174,6 +175,8 @@ ManagePasswordsIconView* icon) { if (bubble_status_ == SHOULD_POP_UP) { DCHECK(!dialog_controller_); + // This will detach any existing bubble so OnBubbleHidden() isn't called. + weak_ptr_factory_.InvalidateWeakPtrs(); // We must display the icon before showing the bubble, as the bubble would // be otherwise unanchored. icon->SetState(GetState()); @@ -191,6 +194,15 @@ } } +base::WeakPtr<PasswordsModelDelegate> +ManagePasswordsUIController::GetModelDelegateProxy() { + return weak_ptr_factory_.GetWeakPtr(); +} + +content::WebContents* ManagePasswordsUIController::GetWebContents() const { + return web_contents(); +} + const GURL& ManagePasswordsUIController::GetOrigin() const { return passwords_data_.origin(); } @@ -298,13 +310,16 @@ } void ManagePasswordsUIController::ChooseCredential( - autofill::PasswordForm form, + const autofill::PasswordForm& form, password_manager::CredentialType credential_type) { DCHECK(dialog_controller_); DCHECK_EQ(password_manager::CredentialType::CREDENTIAL_TYPE_PASSWORD, credential_type); + // Copy the argument before destroying the controller. |form| is a member of + // |dialog_controller_|. + autofill::PasswordForm copy_form = form; dialog_controller_.reset(); - passwords_data_.ChooseCredential(&form); + passwords_data_.ChooseCredential(©_form); passwords_data_.TransitionToState(password_manager::ui::MANAGE_STATE); UpdateBubbleAndIconVisibility(); }
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.h b/chrome/browser/ui/passwords/manage_passwords_ui_controller.h index 802aa5b..d075a48 100644 --- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.h +++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_UI_CONTROLLER_H_ #define CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_UI_CONTROLLER_H_ +#include <memory> #include <vector> #include "base/macros.h" @@ -79,7 +80,10 @@ return bubble_status_ == SHOULD_POP_UP; } + base::WeakPtr<PasswordsModelDelegate> GetModelDelegateProxy(); + // PasswordsModelDelegate: + content::WebContents* GetWebContents() const override; const GURL& GetOrigin() const override; password_manager::ui::State GetState() const override; const autofill::PasswordForm& GetPendingPassword() const override; @@ -98,7 +102,7 @@ void SavePassword() override; void UpdatePassword(const autofill::PasswordForm& password_form) override; void ChooseCredential( - autofill::PasswordForm form, + const autofill::PasswordForm& form, password_manager::CredentialType credential_type) override; void NavigateToExternalPasswordManager() override; void NavigateToSmartLockHelpPage() override; @@ -172,6 +176,17 @@ BubbleStatus bubble_status_; + // The bubbles of different types can pop up unpredictably superseding each + // other. However, closing the bubble may affect the state of + // ManagePasswordsUIController internally. This is undesired if + // ManagePasswordsUIController is in the process of opening a new bubble. The + // situation is worse on Windows where the bubble is destroyed asynchronously. + // Thus, OnBubbleHidden() can be called after the new one is shown. By that + // time the internal state of ManagePasswordsUIController has nothing to do + // with the old bubble. + // Invalidating all the weak pointers will detach the current bubble. + base::WeakPtrFactory<ManagePasswordsUIController> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(ManagePasswordsUIController); };
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h b/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h index c748722..454d2ec 100644 --- a/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h +++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h
@@ -36,8 +36,8 @@ MOCK_METHOD0(NeverSavePassword, void()); MOCK_METHOD0(SavePassword, void()); MOCK_METHOD1(UpdatePassword, void(const autofill::PasswordForm&)); - MOCK_METHOD2(ChooseCredential, - void(autofill::PasswordForm, password_manager::CredentialType)); + MOCK_METHOD2(ChooseCredential, void(const autofill::PasswordForm&, + password_manager::CredentialType)); MOCK_METHOD0(NavigateToExternalPasswordManager, void()); MOCK_METHOD0(NavigateToSmartLockPage, void()); MOCK_METHOD0(NavigateToSmartLockHelpPage, void());
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc index d5c7178..a8a3037 100644 --- a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc +++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h" #include "chrome/browser/ui/passwords/password_dialog_controller.h" #include "chrome/browser/ui/passwords/password_dialog_prompts.h" +#include "chrome/browser/ui/passwords/passwords_model_delegate.h" #include "chrome/test/base/chrome_render_view_host_test_harness.h" #include "chrome/test/base/testing_profile.h" #include "components/autofill/core/common/password_form.h" @@ -122,6 +123,8 @@ opened_bubble_ = IsAutomaticallyOpeningBubble(); ManagePasswordsUIController::UpdateBubbleAndIconVisibility(); OnUpdateBubbleAndIconVisibility(); + TestManagePasswordsIconView view; + UpdateIconAndBubbleState(&view); if (opened_bubble_) OnBubbleShown(); } @@ -743,3 +746,26 @@ TEST_F(ManagePasswordsUIControllerTest, ConfirmationStatePasswordAutofilled) { TestNotChangingStateOnAutofill(password_manager::ui::CONFIRMATION_STATE); } + +TEST_F(ManagePasswordsUIControllerTest, OpenBubbleTwice) { + // Open the autosignin bubble. + ScopedVector<autofill::PasswordForm> local_credentials; + local_credentials.push_back(new autofill::PasswordForm(test_local_form())); + EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility()); + controller()->OnAutoSignin(std::move(local_credentials), + test_local_form().origin); + EXPECT_EQ(password_manager::ui::AUTO_SIGNIN_STATE, controller()->GetState()); + // The delegate used by the bubble for communicating with the controller. + base::WeakPtr<PasswordsModelDelegate> proxy_delegate = + controller()->GetModelDelegateProxy(); + + // Open the bubble again. + local_credentials.push_back(new autofill::PasswordForm(test_local_form())); + EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility()); + controller()->OnAutoSignin(std::move(local_credentials), + test_local_form().origin); + EXPECT_EQ(password_manager::ui::AUTO_SIGNIN_STATE, controller()->GetState()); + // Check the delegate is destroyed. Thus, the first bubble has no way to mess + // up with the controller's state. + EXPECT_FALSE(proxy_delegate); +}
diff --git a/chrome/browser/ui/passwords/password_dialog_controller_impl_unittest.cc b/chrome/browser/ui/passwords/password_dialog_controller_impl_unittest.cc index 7252fea..c112fedb4 100644 --- a/chrome/browser/ui/passwords/password_dialog_controller_impl_unittest.cc +++ b/chrome/browser/ui/passwords/password_dialog_controller_impl_unittest.cc
@@ -11,8 +11,8 @@ #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "base/test/histogram_tester.h" -#include "chrome/browser/ui/passwords/manage_passwords_ui_controller_mock.h" #include "chrome/browser/ui/passwords/password_dialog_prompts.h" +#include "chrome/browser/ui/passwords/passwords_model_delegate_mock.h" #include "chrome/test/base/testing_profile.h" #include "components/autofill/core/common/password_form.h" #include "components/password_manager/core/browser/password_bubble_experiment.h" @@ -20,7 +20,6 @@ #include "components/password_manager/core/common/password_manager_pref_names.h" #include "components/prefs/pref_service.h" #include "content/public/test/test_browser_thread_bundle.h" -#include "content/public/test/web_contents_tester.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -63,15 +62,11 @@ class PasswordDialogControllerTest : public testing::Test { public: PasswordDialogControllerTest() - : test_web_contents_(content::WebContentsTester::CreateTestWebContents( - &profile_, nullptr)), - ui_controller_mock_(new StrictMock<ManagePasswordsUIControllerMock>( - test_web_contents_.get())), - controller_(&profile_, ui_controller_mock_) { + : controller_(&profile_, &ui_controller_mock_) { } - ManagePasswordsUIControllerMock& ui_controller_mock() { - return *ui_controller_mock_; + PasswordsModelDelegateMock& ui_controller_mock() { + return ui_controller_mock_; } PasswordDialogControllerImpl& controller() { return controller_; } @@ -81,9 +76,7 @@ private: content::TestBrowserThreadBundle thread_bundle_; TestingProfile profile_; - std::unique_ptr<content::WebContents> test_web_contents_; - // Owned by |test_web_contents_|. - ManagePasswordsUIControllerMock* ui_controller_mock_; + StrictMock<PasswordsModelDelegateMock> ui_controller_mock_; PasswordDialogControllerImpl controller_; };
diff --git a/chrome/browser/ui/passwords/passwords_model_delegate.cc b/chrome/browser/ui/passwords/passwords_model_delegate.cc index 12e299d..71142142 100644 --- a/chrome/browser/ui/passwords/passwords_model_delegate.cc +++ b/chrome/browser/ui/passwords/passwords_model_delegate.cc
@@ -6,8 +6,9 @@ #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h" -PasswordsModelDelegate* PasswordsModelDelegateFromWebContents( - content::WebContents* web_contents) { +base::WeakPtr<PasswordsModelDelegate> +PasswordsModelDelegateFromWebContents(content::WebContents* web_contents) { DCHECK(web_contents); - return ManagePasswordsUIController::FromWebContents(web_contents); + return ManagePasswordsUIController::FromWebContents(web_contents)-> + GetModelDelegateProxy(); }
diff --git a/chrome/browser/ui/passwords/passwords_model_delegate.h b/chrome/browser/ui/passwords/passwords_model_delegate.h index e6833df..fa99936 100644 --- a/chrome/browser/ui/passwords/passwords_model_delegate.h +++ b/chrome/browser/ui/passwords/passwords_model_delegate.h
@@ -7,6 +7,7 @@ #include <vector> +#include "base/memory/weak_ptr.h" #include "components/password_manager/core/common/credential_manager_types.h" #include "components/password_manager/core/common/password_manager_ui.h" @@ -26,6 +27,9 @@ // and notify about user actions. class PasswordsModelDelegate { public: + // Returns WebContents* the model is attached to. + virtual content::WebContents* GetWebContents() const = 0; + // Returns the URL of the site the current forms are retrieved for. virtual const GURL& GetOrigin() const = 0; @@ -76,10 +80,9 @@ virtual void UpdatePassword(const autofill::PasswordForm& password_form) = 0; // Called from the dialog controller when the user chooses a credential. - // Everything is passed by value because the controller can be destroyed - // inside the method. + // Controller can be destroyed inside the method. virtual void ChooseCredential( - autofill::PasswordForm form, + const autofill::PasswordForm& form, password_manager::CredentialType credential_type) = 0; // Open a new tab pointing to passwords.google.com. @@ -98,8 +101,7 @@ virtual ~PasswordsModelDelegate() = default; }; -// Returns ManagePasswordsUIController instance for |contents| -PasswordsModelDelegate* PasswordsModelDelegateFromWebContents( - content::WebContents* web_contents); +base::WeakPtr<PasswordsModelDelegate> +PasswordsModelDelegateFromWebContents(content::WebContents* web_contents); #endif // CHROME_BROWSER_UI_PASSWORDS_PASSWORDS_MODEL_DELEGATE_H_
diff --git a/chrome/browser/ui/passwords/passwords_model_delegate_mock.cc b/chrome/browser/ui/passwords/passwords_model_delegate_mock.cc new file mode 100644 index 0000000..d06ab601 --- /dev/null +++ b/chrome/browser/ui/passwords/passwords_model_delegate_mock.cc
@@ -0,0 +1,11 @@ +// Copyright 2016 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/passwords/passwords_model_delegate_mock.h" + +#include "components/autofill/core/common/password_form.h" + +PasswordsModelDelegateMock::PasswordsModelDelegateMock() = default; + +PasswordsModelDelegateMock::~PasswordsModelDelegateMock() = default;
diff --git a/chrome/browser/ui/passwords/passwords_model_delegate_mock.h b/chrome/browser/ui/passwords/passwords_model_delegate_mock.h new file mode 100644 index 0000000..053199da --- /dev/null +++ b/chrome/browser/ui/passwords/passwords_model_delegate_mock.h
@@ -0,0 +1,51 @@ +// Copyright 2016 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_PASSWORDS_PASSWORDS_MODEL_DELEGATE_MOCK_H_ +#define CHROME_BROWSER_UI_PASSWORDS_PASSWORDS_MODEL_DELEGATE_MOCK_H_ + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "chrome/browser/ui/passwords/passwords_model_delegate.h" +#include "testing/gmock/include/gmock/gmock.h" + +class PasswordsModelDelegateMock + : public PasswordsModelDelegate, + public base::SupportsWeakPtr<PasswordsModelDelegateMock>{ + public: + PasswordsModelDelegateMock(); + ~PasswordsModelDelegateMock() override; + + MOCK_CONST_METHOD0(GetWebContents, content::WebContents*()); + MOCK_CONST_METHOD0(GetOrigin, const GURL&()); + MOCK_CONST_METHOD0(GetState, password_manager::ui::State()); + MOCK_CONST_METHOD0(GetPendingPassword, const autofill::PasswordForm&()); + MOCK_CONST_METHOD0(IsPasswordOverridden, bool()); + MOCK_CONST_METHOD0(GetCurrentForms, + const std::vector<const autofill::PasswordForm*>&()); + MOCK_CONST_METHOD0(GetFederatedForms, + const std::vector<const autofill::PasswordForm*>&()); + MOCK_CONST_METHOD0(GetCurrentInteractionStats, + password_manager::InteractionsStats*()); + MOCK_METHOD0(OnBubbleShown, void()); + MOCK_METHOD0(OnBubbleHidden, void()); + MOCK_METHOD0(OnNoInteractionOnUpdate, void()); + MOCK_METHOD0(OnNopeUpdateClicked, void()); + MOCK_METHOD0(NeverSavePassword, void()); + MOCK_METHOD0(SavePassword, void()); + MOCK_METHOD1(UpdatePassword, void(const autofill::PasswordForm&)); + MOCK_METHOD2(ChooseCredential, void(const autofill::PasswordForm&, + password_manager::CredentialType)); + MOCK_METHOD0(NavigateToExternalPasswordManager, void()); + MOCK_METHOD0(NavigateToSmartLockPage, void()); + MOCK_METHOD0(NavigateToSmartLockHelpPage, void()); + MOCK_METHOD0(NavigateToPasswordManagerSettingsPage, void()); + MOCK_METHOD0(NavigateToChromeSignIn, void()); + MOCK_METHOD0(OnDialogHidden, void()); + + private: + DISALLOW_COPY_AND_ASSIGN(PasswordsModelDelegateMock); +}; + +#endif // CHROME_BROWSER_UI_PASSWORDS_PASSWORDS_MODEL_DELEGATE_MOCK_H_
diff --git a/chrome/browser/ui/prefs/prefs_tab_helper.cc b/chrome/browser/ui/prefs/prefs_tab_helper.cc index 7827c10fb..d22384c 100644 --- a/chrome/browser/ui/prefs/prefs_tab_helper.cc +++ b/chrome/browser/ui/prefs/prefs_tab_helper.cc
@@ -349,6 +349,7 @@ renderer_callback); pref_change_registrar_.Add(prefs::kWebRTCIPHandlingPolicy, renderer_callback); + pref_change_registrar_.Add(prefs::kWebRTCUDPPortRange, renderer_callback); #endif #if !defined(OS_MACOSX)
diff --git a/chrome/browser/ui/search/instant_extended_interactive_uitest.cc b/chrome/browser/ui/search/instant_extended_interactive_uitest.cc index c104a8d..fbf196d 100644 --- a/chrome/browser/ui/search/instant_extended_interactive_uitest.cc +++ b/chrome/browser/ui/search/instant_extended_interactive_uitest.cc
@@ -146,7 +146,6 @@ protected: void SetUpInProcessBrowserTestFixture() override { - search::EnableQueryExtractionForTesting(); ASSERT_TRUE(https_test_server().Start()); GURL instant_url = https_test_server().GetURL("/instant_extended.html?strk=1&"); @@ -257,7 +256,6 @@ } void SetUpInProcessBrowserTestFixture() override { - search::EnableQueryExtractionForTesting(); ASSERT_TRUE(https_test_server().Start()); GURL instant_url = https_test_server().GetURL("/instant_extended.html?strk=1&"); @@ -323,16 +321,12 @@ DISALLOW_COPY_AND_ASSIGN(InstantPolicyTest); }; -IN_PROC_BROWSER_TEST_F(InstantExtendedTest, SearchReusesInstantTab) { +IN_PROC_BROWSER_TEST_F(InstantExtendedTest, SearchDoesntReuseInstantTab) { ASSERT_NO_FATAL_FAILURE(SetupInstant(browser())); FocusOmnibox(); - content::WindowedNotificationObserver observer( - chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED, - content::NotificationService::AllSources()); SetOmniboxText("flowers"); PressEnterAndWaitForFrameLoad(); - observer.Wait(); // Just did a regular search. content::WebContents* active_tab = @@ -344,11 +338,11 @@ SetOmniboxText("puppies"); PressEnterAndWaitForNavigation(); - // Should have reused the tab and sent an onsubmit message. + // Should not have reused the tab. active_tab = browser()->tab_strip_model()->GetActiveWebContents(); ASSERT_THAT(active_tab->GetURL().spec(), HasSubstr("q=puppies")); ASSERT_TRUE(UpdateSearchState(active_tab)); - EXPECT_EQ(1, submit_count_); + EXPECT_EQ(0, submit_count_); } IN_PROC_BROWSER_TEST_F(InstantExtendedTest, @@ -374,13 +368,8 @@ ASSERT_NO_FATAL_FAILURE(SetupInstant(browser())); FocusOmnibox(); - // Create an observer to wait for the instant tab to support Instant. - content::WindowedNotificationObserver observer_1( - chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED, - content::NotificationService::AllSources()); SetOmniboxText("flowers"); PressEnterAndWaitForFrameLoad(); - observer_1.Wait(); // Just did a regular search. content::WebContents* active_tab = @@ -390,12 +379,8 @@ ASSERT_EQ(0, submit_count_); // Typed in a search URL "by hand". - content::WindowedNotificationObserver observer_2( - chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED, - content::NotificationService::AllSources()); SetOmniboxText(instant_url().Resolve("#q=puppies").spec()); PressEnterAndWaitForNavigation(); - observer_2.Wait(); // Should not have reused the tab. active_tab = browser()->tab_strip_model()->GetActiveWebContents(); @@ -542,111 +527,6 @@ EXPECT_EQ(2, on_theme_changed_calls); } -// Flaky on all bots. http://crbug.com/253092 -// Test to verify that the omnibox search query is updated on browser -// back button press event. -IN_PROC_BROWSER_TEST_F(InstantExtendedTest, - DISABLED_UpdateSearchQueryOnBackNavigation) { - ASSERT_NO_FATAL_FAILURE(SetupInstant(browser())); - - // Focus omnibox and confirm overlay isn't shown. - FocusOmnibox(); - - // Create an observer to wait for the instant tab to support Instant. - content::WindowedNotificationObserver observer( - chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED, - content::NotificationService::AllSources()); - - SetOmniboxText("flowers"); - // Commit the search by pressing 'Enter'. - PressEnterAndWaitForNavigation(); - observer.Wait(); - - EXPECT_EQ(ASCIIToUTF16("flowers"), omnibox()->GetText()); - - // Typing in the new search query in omnibox. - SetOmniboxText("cattles"); - // Commit the search by pressing 'Enter'. - PressEnterAndWaitForNavigation(); - // 'Enter' commits the query as it was typed. This creates a navigation entry - // in the history. - EXPECT_EQ(ASCIIToUTF16("cattles"), omnibox()->GetText()); - - content::WebContents* active_tab = - browser()->tab_strip_model()->GetActiveWebContents(); - EXPECT_TRUE(active_tab->GetController().CanGoBack()); - content::WindowedNotificationObserver load_stop_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<content::NavigationController>( - &active_tab->GetController())); - active_tab->GetController().GoBack(); - load_stop_observer.Wait(); - - EXPECT_EQ(ASCIIToUTF16("flowers"), omnibox()->GetText()); - // Commit the search by pressing 'Enter'. - FocusOmnibox(); - PressEnterAndWaitForNavigation(); - EXPECT_EQ(ASCIIToUTF16("flowers"), omnibox()->GetText()); -} - -// Flaky: crbug.com/253092. -// Test to verify that the omnibox search query is updated on browser -// forward button press events. -IN_PROC_BROWSER_TEST_F(InstantExtendedTest, - DISABLED_UpdateSearchQueryOnForwardNavigation) { - ASSERT_NO_FATAL_FAILURE(SetupInstant(browser())); - - // Focus omnibox and confirm overlay isn't shown. - FocusOmnibox(); - - // Create an observer to wait for the instant tab to support Instant. - content::WindowedNotificationObserver observer( - chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED, - content::NotificationService::AllSources()); - - SetOmniboxText("flowers"); - // Commit the search by pressing 'Enter'. - PressEnterAndWaitForNavigation(); - observer.Wait(); - - EXPECT_EQ(ASCIIToUTF16("flowers"), omnibox()->GetText()); - - // Typing in the new search query in omnibox. - SetOmniboxText("cattles"); - // Commit the search by pressing 'Enter'. - PressEnterAndWaitForNavigation(); - // 'Enter' commits the query as it was typed. This creates a navigation entry - // in the history. - EXPECT_EQ(ASCIIToUTF16("cattles"), omnibox()->GetText()); - - content::WebContents* active_tab = - browser()->tab_strip_model()->GetActiveWebContents(); - EXPECT_TRUE(active_tab->GetController().CanGoBack()); - content::WindowedNotificationObserver load_stop_observer( - content::NOTIFICATION_LOAD_STOP, - content::Source<content::NavigationController>( - &active_tab->GetController())); - active_tab->GetController().GoBack(); - load_stop_observer.Wait(); - - EXPECT_EQ(ASCIIToUTF16("flowers"), omnibox()->GetText()); - - active_tab = browser()->tab_strip_model()->GetActiveWebContents(); - EXPECT_TRUE(active_tab->GetController().CanGoForward()); - content::WindowedNotificationObserver load_stop_observer_2( - content::NOTIFICATION_LOAD_STOP, - content::Source<content::NavigationController>( - &active_tab->GetController())); - active_tab->GetController().GoForward(); - load_stop_observer_2.Wait(); - - // Commit the search by pressing 'Enter'. - FocusOmnibox(); - EXPECT_EQ(ASCIIToUTF16("cattles"), omnibox()->GetText()); - PressEnterAndWaitForNavigation(); - EXPECT_EQ(ASCIIToUTF16("cattles"), omnibox()->GetText()); -} - // Flaky on all bots since re-enabled in r208032, crbug.com/253092 IN_PROC_BROWSER_TEST_F(InstantExtendedTest, DISABLED_NavigateBackToNTP) { ASSERT_NO_FATAL_FAILURE(SetupInstant(browser())); @@ -661,25 +541,10 @@ ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); EXPECT_EQ(2, browser()->tab_strip_model()->count()); - content::WindowedNotificationObserver observer( - chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED, - content::NotificationService::AllSources()); SetOmniboxText("flowers"); PressEnterAndWaitForNavigation(); - observer.Wait(); - EXPECT_EQ(ASCIIToUTF16("flowers"), omnibox()->GetText()); - - // Typing in the new search query in omnibox. - // Commit the search by pressing 'Enter'. - SetOmniboxText("cattles"); - PressEnterAndWaitForNavigation(); - - // 'Enter' commits the query as it was typed. This creates a navigation entry - // in the history. - EXPECT_EQ(ASCIIToUTF16("cattles"), omnibox()->GetText()); - - // Navigate back to "flowers" search result page. + // Navigate back to NTP. content::WebContents* active_tab = browser()->tab_strip_model()->GetActiveWebContents(); EXPECT_TRUE(active_tab->GetController().CanGoBack()); @@ -690,18 +555,6 @@ active_tab->GetController().GoBack(); load_stop_observer.Wait(); - EXPECT_EQ(ASCIIToUTF16("flowers"), omnibox()->GetText()); - - // Navigate back to NTP. - active_tab = browser()->tab_strip_model()->GetActiveWebContents(); - EXPECT_TRUE(active_tab->GetController().CanGoBack()); - content::WindowedNotificationObserver load_stop_observer_2( - content::NOTIFICATION_LOAD_STOP, - content::Source<content::NavigationController>( - &active_tab->GetController())); - active_tab->GetController().GoBack(); - load_stop_observer_2.Wait(); - active_tab = browser()->tab_strip_model()->GetActiveWebContents(); EXPECT_TRUE(search::IsInstantNTP(active_tab)); } @@ -781,12 +634,8 @@ net::URLRequestStatus::SUCCESS); // Navigate to a search results page. - content::WindowedNotificationObserver observer( - chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED, - content::NotificationService::AllSources()); SetOmniboxText("flowers"); PressEnterAndWaitForNavigation(); - observer.Wait(); // Set the fake response for suggest request. Response has prefetch details. // Ensure that the page received the suggest response, then add another @@ -851,12 +700,8 @@ net::URLRequestStatus::SUCCESS); // Navigate to a search results page. - content::WindowedNotificationObserver observer( - chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED, - content::NotificationService::AllSources()); SetOmniboxText("flowers"); PressEnterAndWaitForNavigation(); - observer.Wait(); // Set the fake response for suggest request. Response has no prefetch // details. Ensure that the page received a blank query to clear the @@ -887,40 +732,6 @@ ASSERT_EQ("", prefetch_query_value_); } -#if defined(OS_LINUX) && defined(ADDRESS_SANITIZER) -// Flaky timeouts at shutdown on Linux ASan; http://crbug.com/505478. -#define MAYBE_ShowURL DISABLED_ShowURL -#else -#define MAYBE_ShowURL ShowURL -#endif -IN_PROC_BROWSER_TEST_F(InstantExtendedTest, MAYBE_ShowURL) { - ASSERT_NO_FATAL_FAILURE(SetupInstant(browser())); - FocusOmnibox(); - - // Create an observer to wait for the instant tab to support Instant. - content::WindowedNotificationObserver observer( - chrome::NOTIFICATION_INSTANT_TAB_SUPPORT_DETERMINED, - content::NotificationService::AllSources()); - - // Do a search and commit it. The omnibox should show the search terms. - SetOmniboxText("foo"); - EXPECT_EQ(ASCIIToUTF16("foo"), omnibox()->GetText()); - browser()->window()->GetLocationBar()->AcceptInput(); - observer.Wait(); - EXPECT_FALSE(omnibox()->model()->user_input_in_progress()); - EXPECT_TRUE(browser()->toolbar_model()->WouldPerformSearchTermReplacement( - false)); - EXPECT_EQ(ASCIIToUTF16("foo"), omnibox()->GetText()); - - // Calling ShowURL() should disable search term replacement and show the URL. - omnibox()->ShowURL(); - EXPECT_FALSE(browser()->toolbar_model()->WouldPerformSearchTermReplacement( - false)); - // Don't bother looking for a specific URL; ensuring we're no longer showing - // the search terms is sufficient. - EXPECT_NE(ASCIIToUTF16("foo"), omnibox()->GetText()); -} - // Check that clicking on a result sends the correct referrer. IN_PROC_BROWSER_TEST_F(InstantExtendedTest, Referrer) { ASSERT_TRUE(embedded_test_server()->Start());
diff --git a/chrome/browser/ui/search/instant_extended_manual_interactive_uitest.cc b/chrome/browser/ui/search/instant_extended_manual_interactive_uitest.cc index 8cccea2..df4ec7f 100644 --- a/chrome/browser/ui/search/instant_extended_manual_interactive_uitest.cc +++ b/chrome/browser/ui/search/instant_extended_manual_interactive_uitest.cc
@@ -72,10 +72,6 @@ } protected: - void SetUpInProcessBrowserTestFixture() override { - search::EnableQueryExtractionForTesting(); - } - content::WebContents* active_tab() { return browser()->tab_strip_model()->GetActiveWebContents(); }
diff --git a/chrome/browser/ui/search/instant_search_prerenderer.cc b/chrome/browser/ui/search/instant_search_prerenderer.cc index 4fd25a2..9aa3ffd 100644 --- a/chrome/browser/ui/search/instant_search_prerenderer.cc +++ b/chrome/browser/ui/search/instant_search_prerenderer.cc
@@ -22,12 +22,6 @@ namespace { -// Returns true if the underlying page supports Instant search. -bool PageSupportsInstantSearch(content::WebContents* contents) { - // Search results page supports Instant search. - return SearchTabHelper::FromWebContents(contents)->IsSearchResultsPage(); -} - // Returns true if |match| is associated with the default search provider. bool MatchIsFromDefaultSearchProvider(const AutocompleteMatch& match, Profile* profile) { @@ -126,9 +120,7 @@ return false; } - // InstantSearchPrerenderer can commit query to the prerendered page only if - // the underlying |source| page doesn't support Instant search. - return !PageSupportsInstantSearch(source); + return true; } bool InstantSearchPrerenderer::UsePrerenderedPage( @@ -184,8 +176,7 @@ // This handles the by-far-the-most-common cases while still being simple and // maintainable. return source && AutocompleteMatch::IsSearchType(match.type) && - MatchIsFromDefaultSearchProvider(match, profile_) && - !PageSupportsInstantSearch(source); + MatchIsFromDefaultSearchProvider(match, profile_); } content::WebContents* InstantSearchPrerenderer::prerender_contents() const {
diff --git a/chrome/browser/ui/search/instant_search_prerenderer_unittest.cc b/chrome/browser/ui/search/instant_search_prerenderer_unittest.cc index fad234d..40ba21ae 100644 --- a/chrome/browser/ui/search/instant_search_prerenderer_unittest.cc +++ b/chrome/browser/ui/search/instant_search_prerenderer_unittest.cc
@@ -347,15 +347,6 @@ AutocompleteMatchType::URL_WHAT_YOU_TYPED); EXPECT_FALSE(AutocompleteMatch::IsSearchType(url_type_match.type)); EXPECT_FALSE(prerenderer->IsAllowed(url_type_match, active_tab)); - - // Search results page supports Instant search. InstantSearchPrerenderer is - // used only when the underlying page doesn't support Instant. - NavigateAndCommitActiveTab(GURL("https://www.google.com/alt#quux=foo&strk")); - active_tab = GetActiveWebContents(); - EXPECT_FALSE( - search::ExtractSearchTermsFromURL(profile(), active_tab->GetURL()) - .empty()); - EXPECT_FALSE(prerenderer->IsAllowed(search_type_match, active_tab)); } TEST_F(InstantSearchPrerendererTest, UsePrerenderPage) { @@ -481,13 +472,6 @@ #if !defined(OS_ANDROID) class TestUsePrerenderPage : public InstantSearchPrerendererTest { - protected: - void SetUp() override { - // Disable query extraction flag in field trials. - ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( - "EmbeddedSearch", "Group1 strk:20 query_extraction:0")); - InstantUnitTestBase::SetUpWithoutQueryExtraction(); - } }; TEST_F(TestUsePrerenderPage, ExtractSearchTermsAndUsePrerenderPage) {
diff --git a/chrome/browser/ui/search/search_tab_helper.cc b/chrome/browser/ui/search/search_tab_helper.cc index 0f467f2..d962d629 100644 --- a/chrome/browser/ui/search/search_tab_helper.cc +++ b/chrome/browser/ui/search/search_tab_helper.cc
@@ -221,10 +221,6 @@ ipc_router_.OnTabDeactivated(); } -bool SearchTabHelper::IsSearchResultsPage() { - return model_.mode().is_origin_search(); -} - void SearchTabHelper::DidStartNavigationToPendingEntry( const GURL& url, content::NavigationController::ReloadType /* reload_type */) {
diff --git a/chrome/browser/ui/search/search_tab_helper.h b/chrome/browser/ui/search/search_tab_helper.h index 8f908350..62aef36 100644 --- a/chrome/browser/ui/search/search_tab_helper.h +++ b/chrome/browser/ui/search/search_tab_helper.h
@@ -85,9 +85,6 @@ // Called when the tab corresponding to |this| instance is deactivated. void OnTabDeactivated(); - // Returns true if the underlying page is a search results page. - bool IsSearchResultsPage(); - void set_delegate(SearchTabHelperDelegate* delegate) { delegate_ = delegate; } private:
diff --git a/chrome/browser/ui/search_engines/template_url_table_model.cc b/chrome/browser/ui/search_engines/template_url_table_model.cc index d512e29..e0854440 100644 --- a/chrome/browser/ui/search_engines/template_url_table_model.cc +++ b/chrome/browser/ui/search_engines/template_url_table_model.cc
@@ -130,11 +130,11 @@ TemplateURLTableModel::~TemplateURLTableModel() { template_url_service_->RemoveObserver(this); - STLDeleteElements(&entries_); + base::STLDeleteElements(&entries_); } void TemplateURLTableModel::Reload() { - STLDeleteElements(&entries_); + base::STLDeleteElements(&entries_); TemplateURLService::TemplateURLVector urls = template_url_service_->GetTemplateURLs();
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_observer.h b/chrome/browser/ui/sync/one_click_signin_sync_observer.h index 6bf3c02..07bb1fe 100644 --- a/chrome/browser/ui/sync/one_click_signin_sync_observer.h +++ b/chrome/browser/ui/sync/one_click_signin_sync_observer.h
@@ -7,7 +7,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/sync_service_observer.h" #include "content/public/browser/web_contents_observer.h" #include "url/gurl.h"
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_observer_unittest.cc b/chrome/browser/ui/sync/one_click_signin_sync_observer_unittest.cc index 669c5ad..f4df074d 100644 --- a/chrome/browser/ui/sync/one_click_signin_sync_observer_unittest.cc +++ b/chrome/browser/ui/sync/one_click_signin_sync_observer_unittest.cc
@@ -21,7 +21,7 @@ #include "chrome/test/base/testing_profile.h" #include "components/browser_sync/browser/test_profile_sync_service.h" #include "components/signin/core/browser/signin_manager.h" -#include "components/sync_driver/startup_controller.h" +#include "components/sync/driver/startup_controller.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "content/public/test/test_utils.h"
diff --git a/chrome/browser/ui/sync/one_click_signin_sync_starter.cc b/chrome/browser/ui/sync/one_click_signin_sync_starter.cc index d889a87..1041812 100644 --- a/chrome/browser/ui/sync/one_click_signin_sync_starter.cc +++ b/chrome/browser/ui/sync/one_click_signin_sync_starter.cc
@@ -38,7 +38,7 @@ #include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/browser/signin_metrics.h" #include "components/signin/core/common/profile_management_switches.h" -#include "components/sync_driver/sync_prefs.h" +#include "components/sync/driver/sync_prefs.h" #include "content/public/browser/user_metrics.h" #include "net/base/url_util.h" #include "net/url_request/url_request_context_getter.h"
diff --git a/chrome/browser/ui/tabs/tab_strip_model.cc b/chrome/browser/ui/tabs/tab_strip_model.cc index 3c621fd8..cd2649a 100644 --- a/chrome/browser/ui/tabs/tab_strip_model.cc +++ b/chrome/browser/ui/tabs/tab_strip_model.cc
@@ -245,7 +245,7 @@ } TabStripModel::~TabStripModel() { - STLDeleteElements(&contents_data_); + base::STLDeleteElements(&contents_data_); order_controller_.reset(); }
diff --git a/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model_unittest.cc b/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model_unittest.cc index 6ee4b06..70af651b 100644 --- a/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model_unittest.cc +++ b/chrome/browser/ui/toolbar/recent_tabs_sub_menu_model_unittest.cc
@@ -34,9 +34,9 @@ #include "components/sessions/core/session_types.h" #include "components/sync/api/fake_sync_change_processor.h" #include "components/sync/api/sync_error_factory_mock.h" -#include "components/sync_driver/local_device_info_provider_mock.h" -#include "components/sync_driver/sync_client.h" -#include "components/sync_driver/sync_prefs.h" +#include "components/sync/driver/local_device_info_provider_mock.h" +#include "components/sync/driver/sync_client.h" +#include "components/sync/driver/sync_prefs.h" #include "components/sync_sessions/sessions_sync_manager.h" #include "components/sync_sessions/synced_session.h" #include "content/public/browser/browser_thread.h"
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_model.cc b/chrome/browser/ui/toolbar/toolbar_actions_model.cc index 7f23173..2af73b7 100644 --- a/chrome/browser/ui/toolbar/toolbar_actions_model.cc +++ b/chrome/browser/ui/toolbar/toolbar_actions_model.cc
@@ -336,8 +336,7 @@ DCHECK(actions_initialized_); // See if we have a last known good position for this extension. - bool is_new_extension = - !ContainsValue(last_known_positions_, item.id); + bool is_new_extension = !base::ContainsValue(last_known_positions_, item.id); // New extensions go at the right (end) of the visible extensions. Other // extensions go at their previous position. @@ -620,7 +619,7 @@ } bool ToolbarActionsModel::HasItem(const ToolbarItem& item) const { - return ContainsValue(toolbar_items_, item); + return base::ContainsValue(toolbar_items_, item); } bool ToolbarActionsModel::HasComponentAction( @@ -743,7 +742,7 @@ std::vector<std::string> pref_positions = extension_prefs_->GetToolbarOrder(); size_t pref_position_size = pref_positions.size(); for (size_t i = 0; i < last_known_positions_.size(); ++i) { - if (!ContainsValue(pref_positions, last_known_positions_[i])) { + if (!base::ContainsValue(pref_positions, last_known_positions_[i])) { pref_positions.push_back(last_known_positions_[i]); } }
diff --git a/chrome/browser/ui/toolbar/toolbar_model_unittest.cc b/chrome/browser/ui/toolbar/toolbar_model_unittest.cc index c22d5bc8..d6ab1544 100644 --- a/chrome/browser/ui/toolbar/toolbar_model_unittest.cc +++ b/chrome/browser/ui/toolbar/toolbar_model_unittest.cc
@@ -8,22 +8,13 @@ #include "base/command_line.h" #include "base/macros.h" -#include "base/metrics/field_trial.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h" -#include "chrome/browser/search/search.h" -#include "chrome/browser/search_engines/template_url_service_factory.h" -#include "chrome/browser/search_engines/ui_thread_search_terms_data.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/chrome_switches.h" #include "chrome/test/base/browser_with_test_window_test.h" -#include "components/google/core/browser/google_switches.h" -#include "components/search/search.h" -#include "components/search_engines/template_url_service.h" #include "components/toolbar/toolbar_model.h" -#include "components/variations/entropy_provider.h" #include "content/public/browser/navigation_entry.h" #include "content/public/common/content_constants.h" #include "content/public/common/ssl_status.h" @@ -36,105 +27,35 @@ struct TestItem { GURL url; - // The expected text to display when both forms of URL replacement are - // inactive. - base::string16 expected_text_url_replacement_inactive; - // The expected text to display when query extraction is active. - base::string16 expected_text_query_extraction; - // The expected text to display when both query extraction and URL removal are - // active. - base::string16 expected_text_both; - bool would_perform_search_term_replacement; - bool should_display_url; + base::string16 expected_text; } test_items[] = { { GURL("view-source:http://www.google.com"), - base::ASCIIToUTF16("view-source:www.google.com"), - base::ASCIIToUTF16("view-source:www.google.com"), - base::string16(), - false, - true + base::ASCIIToUTF16("view-source:www.google.com") }, { GURL("view-source:chrome://newtab/"), - base::ASCIIToUTF16("view-source:chrome://newtab"), - base::ASCIIToUTF16("view-source:chrome://newtab"), - base::string16(), - false, - true + base::ASCIIToUTF16("view-source:chrome://newtab") }, { GURL("chrome-extension://monkey/balls.html"), - base::ASCIIToUTF16("chrome-extension://monkey/balls.html"), - base::ASCIIToUTF16("chrome-extension://monkey/balls.html"), - base::string16(), - false, - true + base::ASCIIToUTF16("chrome-extension://monkey/balls.html") }, { GURL(url::kAboutBlankURL), - base::ASCIIToUTF16(url::kAboutBlankURL), - base::ASCIIToUTF16(url::kAboutBlankURL), - base::string16(), - false, - true + base::ASCIIToUTF16(url::kAboutBlankURL) }, { GURL("http://searchurl/?q=tractor+supply"), - base::ASCIIToUTF16("searchurl/?q=tractor+supply"), - base::ASCIIToUTF16("searchurl/?q=tractor+supply"), - base::string16(), - false, - true + base::ASCIIToUTF16("searchurl/?q=tractor+supply") }, { GURL("http://google.com/search?q=tractor+supply&espv=1"), - base::ASCIIToUTF16("google.com/search?q=tractor+supply&espv=1"), - base::ASCIIToUTF16("google.com/search?q=tractor+supply&espv=1"), - base::string16(), - false, - true + base::ASCIIToUTF16("google.com/search?q=tractor+supply&espv=1") }, { GURL("https://google.ca/search?q=tractor+supply"), - base::ASCIIToUTF16("https://google.ca/search?q=tractor+supply"), - base::ASCIIToUTF16("https://google.ca/search?q=tractor+supply"), - base::string16(), - false, - true - }, - { - GURL("https://google.com/search?q=tractor+supply"), - base::ASCIIToUTF16("https://google.com/search?q=tractor+supply"), - base::ASCIIToUTF16("https://google.com/search?q=tractor+supply"), - base::string16(), - false, - true - }, - { - GURL("https://google.com/search?q=tractor+supply&espv=1"), - base::ASCIIToUTF16("https://google.com/search?q=tractor+supply&espv=1"), - base::ASCIIToUTF16("tractor supply"), - base::ASCIIToUTF16("tractor supply"), - true, - true - }, - { - GURL("https://google.com/search?q=tractorsupply.com&espv=1"), - base::ASCIIToUTF16("https://google.com/search?q=tractorsupply.com&espv=1"), - base::ASCIIToUTF16("tractorsupply.com"), - base::ASCIIToUTF16("tractorsupply.com"), - true, - true - }, - { - GURL("https://google.com/search?q=ftp://tractorsupply.ie&espv=1"), - base::ASCIIToUTF16( - "https://google.com/search?q=ftp://tractorsupply.ie&espv=1"), - base::ASCIIToUTF16("ftp://tractorsupply.ie"), - base::ASCIIToUTF16("ftp://tractorsupply.ie"), - true, - true + base::ASCIIToUTF16("https://google.ca/search?q=tractor+supply") }, }; @@ -146,7 +67,6 @@ class ToolbarModelTest : public BrowserWithTestWindowTest { public: ToolbarModelTest(); - ToolbarModelTest(Browser::Type browser_type, bool hosted_app); ~ToolbarModelTest() override; // BrowserWithTestWindowTest: @@ -154,40 +74,28 @@ protected: void NavigateAndCheckText(const GURL& url, - const base::string16& expected_text, - bool would_perform_search_term_replacement, - bool should_display_url); + const base::string16& expected_text); void NavigateAndCheckElided(const GURL& https_url); private: - std::unique_ptr<base::FieldTrialList> field_trial_list_; - DISALLOW_COPY_AND_ASSIGN(ToolbarModelTest); }; ToolbarModelTest::ToolbarModelTest() { } -ToolbarModelTest::ToolbarModelTest(Browser::Type browser_type, bool hosted_app) - : BrowserWithTestWindowTest(browser_type, hosted_app) {} - ToolbarModelTest::~ToolbarModelTest() { } void ToolbarModelTest::SetUp() { BrowserWithTestWindowTest::SetUp(); - TemplateURLServiceFactory::GetInstance()->SetTestingFactoryAndUse( - profile(), &TemplateURLServiceFactory::BuildInstanceFor); AutocompleteClassifierFactory::GetInstance()->SetTestingFactoryAndUse( profile(), &AutocompleteClassifierFactory::BuildInstanceFor); - UIThreadSearchTermsData::SetGoogleBaseURL("http://google.com/"); } void ToolbarModelTest::NavigateAndCheckText( const GURL& url, - const base::string16& expected_text, - bool would_perform_search_term_replacement, - bool should_display_url) { + const base::string16& expected_text) { // Check while loading. content::NavigationController* controller = &browser()->tab_strip_model()->GetWebContentsAt(0)->GetController(); @@ -195,32 +103,14 @@ std::string()); ToolbarModel* toolbar_model = browser()->toolbar_model(); EXPECT_EQ(expected_text, toolbar_model->GetText()); - EXPECT_EQ(would_perform_search_term_replacement, - toolbar_model->WouldPerformSearchTermReplacement(false)); - EXPECT_EQ(should_display_url, toolbar_model->ShouldDisplayURL()); + EXPECT_FALSE(toolbar_model->WouldPerformSearchTermReplacement(false)); + EXPECT_TRUE(toolbar_model->ShouldDisplayURL()); // Check after commit. CommitPendingLoad(controller); - // Fake a secure connection for HTTPS URLs, or the toolbar will refuse to - // extract search terms. - if (url.SchemeIsCryptographic()) { - controller->GetVisibleEntry()->GetSSL().security_style = - content::SECURITY_STYLE_AUTHENTICATED; - } EXPECT_EQ(expected_text, toolbar_model->GetText()); - EXPECT_EQ(would_perform_search_term_replacement, - toolbar_model->WouldPerformSearchTermReplacement(false)); - EXPECT_EQ(should_display_url, toolbar_model->ShouldDisplayURL()); - - // Now pretend the user started modifying the omnibox. - toolbar_model->set_input_in_progress(true); EXPECT_FALSE(toolbar_model->WouldPerformSearchTermReplacement(false)); - EXPECT_EQ(would_perform_search_term_replacement, - toolbar_model->WouldPerformSearchTermReplacement(true)); - - // Tell the ToolbarModel that the user has stopped editing. This prevents - // this function from having side effects. - toolbar_model->set_input_in_progress(false); + EXPECT_TRUE(toolbar_model->ShouldDisplayURL()); } void ToolbarModelTest::NavigateAndCheckElided(const GURL& url) { @@ -244,114 +134,15 @@ base::CompareCase::SENSITIVE)); } -class PopupToolbarModelTest : public ToolbarModelTest { - public: - PopupToolbarModelTest(); - ~PopupToolbarModelTest() override; - - DISALLOW_COPY_AND_ASSIGN(PopupToolbarModelTest); -}; - -PopupToolbarModelTest::PopupToolbarModelTest() - : ToolbarModelTest(Browser::TYPE_POPUP, false) {} - -PopupToolbarModelTest::~PopupToolbarModelTest() { -} - // Actual tests --------------------------------------------------------------- -// Test that we only replace URLs when query extraction and URL replacement -// are enabled. -TEST_F(ToolbarModelTest, ShouldDisplayURL_QueryExtraction) { +// Test URL display. +TEST_F(ToolbarModelTest, ShouldDisplayURL) { AddTab(browser(), GURL(url::kAboutBlankURL)); - // Before we enable instant extended, query extraction is disabled. - EXPECT_FALSE(search::IsQueryExtractionEnabled()) - << "This test expects query extraction to be disabled."; - for (size_t i = 0; i < arraysize(test_items); ++i) { - const TestItem& test_item = test_items[i]; - NavigateAndCheckText(test_item.url, - test_item.expected_text_url_replacement_inactive, - false, test_item.should_display_url); + for (const TestItem& test_item : test_items) { + NavigateAndCheckText(test_item.url, test_item.expected_text); } - - search::EnableQueryExtractionForTesting(); - EXPECT_TRUE(search::IsQueryExtractionEnabled()); - EXPECT_TRUE(browser()->toolbar_model()->url_replacement_enabled()); - for (size_t i = 0; i < arraysize(test_items); ++i) { - const TestItem& test_item = test_items[i]; - NavigateAndCheckText(test_item.url, - test_item.expected_text_query_extraction, - test_item.would_perform_search_term_replacement, - test_item.should_display_url); - } - - // Disabling URL replacement should reset to only showing URLs. - browser()->toolbar_model()->set_url_replacement_enabled(false); - for (size_t i = 0; i < arraysize(test_items); ++i) { - const TestItem& test_item = test_items[i]; - NavigateAndCheckText(test_item.url, - test_item.expected_text_url_replacement_inactive, - false, test_item.should_display_url); - } -} - - // Verify that search terms are extracted while the page is loading. -TEST_F(ToolbarModelTest, SearchTermsWhileLoading) { - search::EnableQueryExtractionForTesting(); - AddTab(browser(), GURL(url::kAboutBlankURL)); - - // While loading, we should be willing to extract search terms. - content::NavigationController* controller = - &browser()->tab_strip_model()->GetWebContentsAt(0)->GetController(); - controller->LoadURL(GURL("https://google.com/search?q=tractor+supply&espv=1"), - content::Referrer(), ui::PAGE_TRANSITION_LINK, - std::string()); - ToolbarModel* toolbar_model = browser()->toolbar_model(); - controller->GetVisibleEntry()->GetSSL().security_style = - content::SECURITY_STYLE_UNKNOWN; - EXPECT_TRUE(toolbar_model->WouldPerformSearchTermReplacement(false)); - - // When done loading, we shouldn't extract search terms if we didn't get an - // authenticated connection. - CommitPendingLoad(controller); - controller->GetVisibleEntry()->GetSSL().security_style = - content::SECURITY_STYLE_UNKNOWN; - EXPECT_FALSE(toolbar_model->WouldPerformSearchTermReplacement(false)); -} - -// When the Google base URL is overridden on the command line, we should extract -// search terms from URLs that start with that base URL even when they're not -// secure. -TEST_F(ToolbarModelTest, GoogleBaseURL) { - search::EnableQueryExtractionForTesting(); - AddTab(browser(), GURL(url::kAboutBlankURL)); - - // If the Google base URL wasn't specified on the command line, then if it's - // HTTP, we should not extract search terms. - UIThreadSearchTermsData::SetGoogleBaseURL("http://www.foo.com/"); - NavigateAndCheckText( - GURL("http://www.foo.com/search?q=tractor+supply&espv=1"), - base::ASCIIToUTF16("www.foo.com/search?q=tractor+supply&espv=1"), false, - true); - - // The same URL, when specified on the command line, should allow search term - // extraction. - UIThreadSearchTermsData::SetGoogleBaseURL(std::string()); - base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - switches::kGoogleBaseURL, "http://www.foo.com/"); - - // For the default search engine to reflect the new Google base URL we just - // set, the TemplateURLService has to know the base URL changed. Normally the - // GoogleURLTracker is the source of such change notifications, but since here - // we're modifying the base URL value directly by changing the command-line - // flags, we need to manually tell TemplateURLService to check for changes. - TemplateURLServiceFactory::GetInstance()->GetForProfile(profile())-> - GoogleBaseURLChanged(); - - NavigateAndCheckText( - GURL("http://www.foo.com/search?q=tractor+supply&espv=1"), - base::ASCIIToUTF16("tractor supply"), true, true); } TEST_F(ToolbarModelTest, ShouldElideLongURLs) { @@ -361,38 +152,3 @@ GURL(std::string("https://www.foo.com/?") + long_text)); NavigateAndCheckElided(GURL(std::string("data:abc") + long_text)); } - -// Test that URL display in a popup respects the query extraction flag. -TEST_F(PopupToolbarModelTest, ShouldDisplayURL) { - AddTab(browser(), GURL(url::kAboutBlankURL)); - - // Check with query extraction disabled. - EXPECT_FALSE(search::IsQueryExtractionEnabled()); - for (size_t i = 0; i < arraysize(test_items); ++i) { - const TestItem& test_item = test_items[i]; - NavigateAndCheckText(test_item.url, - test_item.expected_text_url_replacement_inactive, - false, test_item.should_display_url); - } - - // With query extraction enabled, search term replacement should be performed. - search::EnableQueryExtractionForTesting(); - EXPECT_TRUE(search::IsQueryExtractionEnabled()); - EXPECT_TRUE(browser()->toolbar_model()->url_replacement_enabled()); - for (size_t i = 0; i < arraysize(test_items); ++i) { - const TestItem& test_item = test_items[i]; - NavigateAndCheckText(test_item.url, - test_item.expected_text_query_extraction, - test_item.would_perform_search_term_replacement, - test_item.should_display_url); - } - - // Disabling URL replacement should reset to only showing URLs. - browser()->toolbar_model()->set_url_replacement_enabled(false); - for (size_t i = 0; i < arraysize(test_items); ++i) { - const TestItem& test_item = test_items[i]; - NavigateAndCheckText(test_item.url, - test_item.expected_text_url_replacement_inactive, - false, test_item.should_display_url); - } -}
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc index 2224811c..275661e 100644 --- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc +++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc
@@ -30,6 +30,7 @@ #include "ui/base/hit_test.h" #include "ui/base/models/simple_menu_model.h" #include "ui/gfx/skia_util.h" +#include "ui/views/controls/menu/menu_model_adapter.h" #include "ui/views/controls/menu/menu_runner.h" #include "ui/views/widget/widget.h" @@ -236,9 +237,8 @@ views::View* source, const gfx::Point& p, ui::MenuSourceType source_type) { - std::unique_ptr<ui::MenuModel> model = - CreateMultiUserContextMenu(app_window()->GetNativeWindow()); - if (!model.get()) + menu_model_ = CreateMultiUserContextMenu(app_window()->GetNativeWindow()); + if (!menu_model_.get()) return; // Only show context menu if point is in caption. @@ -248,15 +248,19 @@ int hit_test = widget()->non_client_view()->NonClientHitTest(point_in_view_coords); if (hit_test == HTCAPTION) { + menu_model_adapter_.reset(new views::MenuModelAdapter( + menu_model_.get(), + base::Bind(&ChromeNativeAppWindowViewsAuraAsh::OnMenuClosed, + base::Unretained(this)))); menu_runner_.reset(new views::MenuRunner( - model.get(), - views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU)); - if (menu_runner_->RunMenuAt(source->GetWidget(), NULL, - gfx::Rect(p, gfx::Size(0, 0)), - views::MENU_ANCHOR_TOPLEFT, source_type) == - views::MenuRunner::MENU_DELETED) { - return; - } + menu_model_adapter_->CreateMenu(), views::MenuRunner::HAS_MNEMONICS | + views::MenuRunner::CONTEXT_MENU | + views::MenuRunner::ASYNC)); + menu_runner_->RunMenuAt(source->GetWidget(), NULL, + gfx::Rect(p, gfx::Size(0, 0)), + views::MENU_ANCHOR_TOPLEFT, source_type); + } else { + menu_model_.reset(); } } @@ -344,3 +348,9 @@ ->SetClientArea(insets, std::move(additional_client_regions)); } } + +void ChromeNativeAppWindowViewsAuraAsh::OnMenuClosed() { + menu_runner_.reset(); + menu_model_adapter_.reset(); + menu_model_.reset(); +}
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.h b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.h index f8b56dc..3c47469 100644 --- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.h +++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.h
@@ -15,7 +15,12 @@ class ImmersiveFullscreenController; } +namespace ui { +class MenuModel; +} + namespace views { +class MenuModelAdapter; class MenuRunner; } @@ -65,6 +70,9 @@ FRIEND_TEST_ALL_PREFIXES(ShapedAppWindowTargeterTest, ResizeInsetsWithinBounds); + // Callback for MenuModelAdapter + void OnMenuClosed(); + // Used to put non-frameless windows into immersive fullscreen on ChromeOS. In // immersive fullscreen, the window header (title bar and window controls) // slides onscreen as an overlay when the mouse is hovered at the top of the @@ -73,6 +81,8 @@ immersive_fullscreen_controller_; // Used to show the system menu. + std::unique_ptr<ui::MenuModel> menu_model_; + std::unique_ptr<views::MenuModelAdapter> menu_model_adapter_; std::unique_ptr<views::MenuRunner> menu_runner_; DISALLOW_COPY_AND_ASSIGN(ChromeNativeAppWindowViewsAuraAsh);
diff --git a/chrome/browser/ui/views/content_setting_bubble_contents.cc b/chrome/browser/ui/views/content_setting_bubble_contents.cc index da0754f..091a23c4 100644 --- a/chrome/browser/ui/views/content_setting_bubble_contents.cc +++ b/chrome/browser/ui/views/content_setting_bubble_contents.cc
@@ -203,8 +203,7 @@ bool bubble_content_empty = true; if (!bubble_content.title.empty()) { - views::Label* title_label = new views::Label(base::UTF8ToUTF16( - bubble_content.title)); + views::Label* title_label = new views::Label(bubble_content.title); title_label->SetMultiLine(true); title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); layout->StartRow(0, kSingleColumnSetId); @@ -212,6 +211,16 @@ bubble_content_empty = false; } + if (!bubble_content.message.empty()) { + views::Label* message_label = new views::Label(bubble_content.message); + layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); + message_label->SetMultiLine(true); + message_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); + layout->StartRow(0, kSingleColumnSetId); + layout->AddView(message_label); + bubble_content_empty = false; + } + if (!bubble_content.learn_more_link.empty()) { learn_more_link_ = new views::Link(base::UTF8ToUTF16(bubble_content.learn_more_link));
diff --git a/chrome/browser/ui/views/download/download_shelf_context_menu_view.cc b/chrome/browser/ui/views/download/download_shelf_context_menu_view.cc index 26cf968..faa4d43 100644 --- a/chrome/browser/ui/views/download/download_shelf_context_menu_view.cc +++ b/chrome/browser/ui/views/download/download_shelf_context_menu_view.cc
@@ -10,6 +10,7 @@ #include "content/public/browser/download_item.h" #include "content/public/browser/page_navigator.h" #include "ui/gfx/geometry/point.h" +#include "ui/views/controls/menu/menu_model_adapter.h" #include "ui/views/controls/menu/menu_runner.h" DownloadShelfContextMenuView::DownloadShelfContextMenuView( @@ -26,9 +27,14 @@ // Run() should not be getting called if the DownloadItem was destroyed. DCHECK(menu_model); - menu_runner_.reset(new views::MenuRunner( - menu_model, - views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU)); + menu_model_adapter_.reset(new views::MenuModelAdapter( + menu_model, base::Bind(&DownloadShelfContextMenuView::OnMenuClosed, + base::Unretained(this)))); + + menu_runner_.reset(new views::MenuRunner(menu_model_adapter_->CreateMenu(), + views::MenuRunner::HAS_MNEMONICS | + views::MenuRunner::CONTEXT_MENU | + views::MenuRunner::ASYNC)); // The menu's alignment is determined based on the UI layout. views::MenuAnchorPosition position; @@ -37,14 +43,11 @@ else position = views::MENU_ANCHOR_TOPLEFT; - // The return value of RunMenuAt indicates whether the MenuRunner was deleted - // while running the menu, which indicates that the containing view may have - // been deleted. We ignore the return value because our caller already assumes - // that the view could be deleted by the time we return from here. - if (menu_runner_->RunMenuAt( - parent_widget, NULL, rect, position, source_type) == - views::MenuRunner::MENU_DELETED) { - return; - } + menu_runner_->RunMenuAt(parent_widget, NULL, rect, position, source_type); +} + +void DownloadShelfContextMenuView::OnMenuClosed() { close_time_ = base::TimeTicks::Now(); + menu_model_adapter_.reset(); + menu_runner_.reset(); }
diff --git a/chrome/browser/ui/views/download/download_shelf_context_menu_view.h b/chrome/browser/ui/views/download/download_shelf_context_menu_view.h index f57335c..8a4d8ed 100644 --- a/chrome/browser/ui/views/download/download_shelf_context_menu_view.h +++ b/chrome/browser/ui/views/download/download_shelf_context_menu_view.h
@@ -23,6 +23,7 @@ } namespace views { +class MenuModelAdapter; class MenuRunner; class Widget; } @@ -41,6 +42,10 @@ ui::MenuSourceType source_type); private: + // Callback for MenuModelAdapter + void OnMenuClosed(); + + std::unique_ptr<views::MenuModelAdapter> menu_model_adapter_; std::unique_ptr<views::MenuRunner> menu_runner_; // Time the menu was closed.
diff --git a/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc b/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc index c1d24a4..91b82db 100644 --- a/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc +++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view.cc
@@ -486,6 +486,12 @@ return layout; } +void ExtensionInstallDialogView::OnNativeThemeChanged( + const ui::NativeTheme* theme) { + scroll_view_->SetBackgroundColor( + theme->GetSystemColor(ui::NativeTheme::kColorId_DialogBackground)); +} + int ExtensionInstallDialogView::GetDialogButtons() const { int buttons = prompt_->GetDialogButtons(); // Simply having just an OK button is *not* supported. See comment on function
diff --git a/chrome/browser/ui/views/extensions/extension_install_dialog_view.h b/chrome/browser/ui/views/extensions/extension_install_dialog_view.h index ac6fbcd..b9ee2fb8 100644 --- a/chrome/browser/ui/views/extensions/extension_install_dialog_view.h +++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view.h
@@ -51,6 +51,9 @@ const views::ScrollView* scroll_view() const { return scroll_view_; } private: + // views::View: + void OnNativeThemeChanged(const ui::NativeTheme* theme) override; + // views::DialogDelegateView: int GetDialogButtons() const override; base::string16 GetDialogButtonLabel(ui::DialogButton button) const override;
diff --git a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc index 0021d922..2c04d3a 100644 --- a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc +++ b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.cc
@@ -21,6 +21,7 @@ #include "ui/views/controls/button/image_button.h" #include "ui/views/controls/button/md_text_button.h" #include "ui/views/controls/label.h" +#include "ui/views/controls/menu/menu_model_adapter.h" #include "ui/views/controls/menu/menu_runner.h" #include "ui/views/controls/scroll_view.h" #include "ui/views/controls/separator.h" @@ -305,24 +306,30 @@ void MediaGalleriesDialogViews::ShowContextMenu(const gfx::Point& point, ui::MenuSourceType source_type, MediaGalleryPrefId id) { - context_menu_runner_.reset(new views::MenuRunner( + menu_model_adapter_.reset(new views::MenuModelAdapter( controller_->GetContextMenu(id), - views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU)); + base::Bind(&MediaGalleriesDialogViews::OnMenuClosed, + base::Unretained(this)))); - if (context_menu_runner_->RunMenuAt(GetWidget(), - NULL, - gfx::Rect(point.x(), point.y(), 0, 0), - views::MENU_ANCHOR_TOPLEFT, - source_type) == - views::MenuRunner::MENU_DELETED) { - return; - } + context_menu_runner_.reset(new views::MenuRunner( + menu_model_adapter_->CreateMenu(), views::MenuRunner::HAS_MNEMONICS | + views::MenuRunner::CONTEXT_MENU | + views::MenuRunner::ASYNC)); + + context_menu_runner_->RunMenuAt(GetWidget(), NULL, + gfx::Rect(point.x(), point.y(), 0, 0), + views::MENU_ANCHOR_TOPLEFT, source_type); } bool MediaGalleriesDialogViews::ControllerHasWebContents() const { return controller_->WebContents() != NULL; } +void MediaGalleriesDialogViews::OnMenuClosed() { + menu_model_adapter_.reset(); + context_menu_runner_.reset(); +} + // MediaGalleriesDialogViewsController ----------------------------------------- // static
diff --git a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.h b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.h index 72c360f..2971414 100644 --- a/chrome/browser/ui/views/extensions/media_galleries_dialog_views.h +++ b/chrome/browser/ui/views/extensions/media_galleries_dialog_views.h
@@ -18,6 +18,7 @@ namespace views { class Checkbox; class LabelButton; +class MenuModelAdapter; class MenuRunner; class Widget; } @@ -87,6 +88,9 @@ // In unit tests, it may not. bool ControllerHasWebContents() const; + // Callback for MenuModelAdapter. + void OnMenuClosed(); + MediaGalleriesDialogController* controller_; // The contents of the dialog. Owned by the view hierarchy, except in tests. @@ -107,6 +111,7 @@ // True if the user has pressed accept. bool accepted_; + std::unique_ptr<views::MenuModelAdapter> menu_model_adapter_; std::unique_ptr<views::MenuRunner> context_menu_runner_; DISALLOW_COPY_AND_ASSIGN(MediaGalleriesDialogViews);
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index a219ea3..7ffa3e9 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -891,7 +891,7 @@ for (PageActionViews::const_iterator i(page_action_views_.begin()); i != page_action_views_.end(); ++i) RemoveChildView(*i); - STLDeleteElements(&page_action_views_); + base::STLDeleteElements(&page_action_views_); } bool LocationBarView::RefreshPageActionViews() {
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc index a6a717c..a04bcafc 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.cc
@@ -16,7 +16,6 @@ #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h" #include "chrome/browser/command_updater.h" -#include "chrome/browser/search/search.h" #include "chrome/browser/ui/omnibox/chrome_omnibox_client.h" #include "chrome/browser/ui/omnibox/clipboard_utils.h" #include "chrome/browser/ui/view_ids.h" @@ -30,7 +29,6 @@ #include "components/omnibox/browser/omnibox_edit_model.h" #include "components/omnibox/browser/omnibox_field_trial.h" #include "components/omnibox/browser/omnibox_popup_model.h" -#include "components/search/search.h" #include "components/toolbar/toolbar_model.h" #include "content/public/browser/web_contents.h" #include "extensions/common/constants.h" @@ -1096,14 +1094,6 @@ menu_contents->AddSeparator(ui::NORMAL_SEPARATOR); - if (search::IsQueryExtractionEnabled()) { - int select_all_position = menu_contents->GetIndexOfCommandId( - IDS_APP_SELECT_ALL); - DCHECK_GE(select_all_position, 0); - menu_contents->InsertItemWithStringIdAt( - select_all_position + 1, IDS_SHOW_URL, IDS_SHOW_URL); - } - // Minor note: We use IDC_ for command id here while the underlying textfield // is using IDS_ for all its command ids. This is because views cannot depend // on IDC_ for now.
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc index 74c2694..09464ec 100644 --- a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc +++ b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view.cc
@@ -11,6 +11,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" +#include "chrome/browser/ui/passwords/passwords_model_delegate.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/passwords/credentials_item_view.h" #include "chrome/browser/ui/views/passwords/credentials_selection_view.h" @@ -771,7 +772,7 @@ } content::WebContents* ManagePasswordsBubbleView::web_contents() const { - return model_.web_contents(); + return model_.GetWebContents(); } ManagePasswordsBubbleView::ManagePasswordsBubbleView( @@ -779,7 +780,7 @@ views::View* anchor_view, DisplayReason reason) : LocationBarBubbleDelegateView(anchor_view, web_contents), - model_(web_contents, + model_(PasswordsModelDelegateFromWebContents(web_contents), reason == AUTOMATIC ? ManagePasswordsBubbleModel::AUTOMATIC : ManagePasswordsBubbleModel::USER_ACTION), initially_focused_view_(nullptr) {
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_interactive_uitest.cc b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_interactive_uitest.cc index 914c22ba..7fc213a1 100644 --- a/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/passwords/manage_passwords_bubble_view_interactive_uitest.cc
@@ -316,8 +316,9 @@ content::RunAllPendingInMessageLoop(); content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - EXPECT_EQ(password_manager::ui::MANAGE_STATE, - PasswordsModelDelegateFromWebContents(web_contents)->GetState()); + EXPECT_EQ( + password_manager::ui::MANAGE_STATE, + PasswordsModelDelegateFromWebContents(web_contents)->GetState()); } IN_PROC_BROWSER_TEST_F(ManagePasswordsBubbleViewTest, AutoSigninNoFocus) {
diff --git a/chrome/browser/ui/views/profiles/new_avatar_button.cc b/chrome/browser/ui/views/profiles/new_avatar_button.cc index e4d4b8a8..d57e346 100644 --- a/chrome/browser/ui/views/profiles/new_avatar_button.cc +++ b/chrome/browser/ui/views/profiles/new_avatar_button.cc
@@ -198,7 +198,7 @@ } else if (error_controller_.HasAvatarError()) { if (switches::IsMaterialDesignUserMenu()) { SetImage(views::Button::STATE_NORMAL, - gfx::CreateVectorIcon(gfx::VectorIconId::SYNC_PROBLEM, 13, + gfx::CreateVectorIcon(gfx::VectorIconId::SYNC_PROBLEM, 16, gfx::kGoogleRed700)); } else { SetImage(views::Button::STATE_NORMAL,
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc index 3957836..93e82fa 100644 --- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc +++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -45,7 +45,7 @@ #include "components/signin/core/browser/signin_header_helper.h" #include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/common/profile_management_switches.h" -#include "components/sync_driver/sync_error_controller.h" +#include "components/sync/driver/sync_error_controller.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/user_metrics.h" #include "grit/theme_resources.h" @@ -198,6 +198,10 @@ views::Border::CreateEmptyBorder(0, button_margin, 0, button_margin)); SetFocusForPlatform(); set_request_focus_on_press(true); + + if (switches::IsMaterialDesignUserMenu()) { + label()->SetHandlesTooltips(false); + } } BackgroundColorHoverButton(views::ButtonListener* listener,
diff --git a/chrome/browser/ui/views/tabs/window_finder_mus.cc b/chrome/browser/ui/views/tabs/window_finder_mus.cc index af753aa..c42aec3a 100644 --- a/chrome/browser/ui/views/tabs/window_finder_mus.cc +++ b/chrome/browser/ui/views/tabs/window_finder_mus.cc
@@ -27,7 +27,7 @@ aura::Window* content_window = widget->GetNativeWindow(); // If we were instructed to ignore this window, ignore it. - if (ContainsKey(ignore, content_window)) + if (base::ContainsKey(ignore, content_window)) continue; return content_window;
diff --git a/chrome/browser/ui/views/toolbar/browser_actions_container.cc b/chrome/browser/ui/views/toolbar/browser_actions_container.cc index 162c126..f4b6cbe 100644 --- a/chrome/browser/ui/views/toolbar/browser_actions_container.cc +++ b/chrome/browser/ui/views/toolbar/browser_actions_container.cc
@@ -183,7 +183,7 @@ } void BrowserActionsContainer::RemoveAllViews() { - STLDeleteElements(&toolbar_action_views_); + base::STLDeleteElements(&toolbar_action_views_); } void BrowserActionsContainer::Redraw(bool order_changed) {
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_view_interactive_uitest.cc b/chrome/browser/ui/views/toolbar/toolbar_action_view_interactive_uitest.cc index 0e56223..32ca813 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_action_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_action_view_interactive_uitest.cc
@@ -61,7 +61,8 @@ gfx::Point action_view_loc = ui_test_utils::GetCenterInScreenCoordinates(action_view); ui_controls::SendMouseMove(action_view_loc.x(), action_view_loc.y()); - ui_controls::SendMouseEvents(button, ui_controls::DOWN | ui_controls::UP); + EXPECT_TRUE(ui_test_utils::SendMouseEventsSync( + button, ui_controls::DOWN | ui_controls::UP)); } // Tests the context menu of an overflowed action. @@ -195,17 +196,18 @@ gfx::Point app_button_loc = ui_test_utils::GetCenterInScreenCoordinates(app_menu_button); ui_controls::SendMouseMove(app_button_loc.x(), app_button_loc.y()); - ui_controls::SendMouseEvents(ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP); + EXPECT_TRUE(ui_test_utils::SendMouseEventsSync( + ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP)); base::RunLoop().RunUntilIdle(); TestOverflowedToolbarAction(browser(), ui_controls::LEFT); - // The extension should have been activated. - listener.WaitUntilSatisfied(); - - // And the app menu should no longer be showing. + base::RunLoop().RunUntilIdle(); + // The app menu should no longer be showing. EXPECT_FALSE(app_menu_button->IsMenuShowing()); + + // And the extension should have been activated. + listener.WaitUntilSatisfied(); } #if defined(USE_OZONE) @@ -258,8 +260,8 @@ gfx::Point app_button_loc = ui_test_utils::GetCenterInScreenCoordinates(app_menu_button); ui_controls::SendMouseMove(app_button_loc.x(), app_button_loc.y()); - ui_controls::SendMouseEvents(ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP); + EXPECT_TRUE(ui_test_utils::SendMouseEventsSync( + ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP)); base::RunLoop().RunUntilIdle(); TestOverflowedToolbarAction(browser(), ui_controls::RIGHT); @@ -367,8 +369,8 @@ gfx::Point app_button_loc = ui_test_utils::GetCenterInScreenCoordinates(app_menu_button); ui_controls::SendMouseMove(app_button_loc.x(), app_button_loc.y()); - ui_controls::SendMouseEvents(ui_controls::LEFT, - ui_controls::DOWN | ui_controls::UP); + EXPECT_TRUE(ui_test_utils::SendMouseEventsSync( + ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP)); base::RunLoop().RunUntilIdle(); @@ -379,11 +381,16 @@ // The key down event targets the toolbar action in the app menu. ui_controls::SendKeyPress(native_window, ui::VKEY_DOWN, false, false, false, false); - ui_controls::SendKeyPress(native_window, ui::VKEY_RETURN, false, false, false, - false); + // The triggering of the action and subsequent widget destruction occurs on + // the message loop. Wait for this all to complete. + base::RunLoop loop; + ui_controls::SendKeyPressNotifyWhenDone(native_window, ui::VKEY_RETURN, false, + false, false, false, + loop.QuitClosure()); + loop.Run(); - // The extension should have been activated. - EXPECT_TRUE(listener.WaitUntilSatisfied()); - // And the menu should be closed + // The menu should be closed. EXPECT_FALSE(app_menu_button->IsMenuShowing()); + // And the extension should have been activated. + EXPECT_TRUE(listener.WaitUntilSatisfied()); }
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 ac90cc17e7..f982f85 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
@@ -629,8 +629,8 @@ // In addition, if a permission is set to the default setting, WebsiteSettings // removes it from |permission_info_list|, but the button should remain. if (permissions_content_) { - STLDeleteContainerPointers(chosen_object_info_list.begin(), - chosen_object_info_list.end()); + base::STLDeleteContainerPointers(chosen_object_info_list.begin(), + chosen_object_info_list.end()); return; }
diff --git a/chrome/browser/ui/website_settings/mock_permission_prompt_factory.cc b/chrome/browser/ui/website_settings/mock_permission_prompt_factory.cc index c239f67e..cbdab35e 100644 --- a/chrome/browser/ui/website_settings/mock_permission_prompt_factory.cc +++ b/chrome/browser/ui/website_settings/mock_permission_prompt_factory.cc
@@ -84,7 +84,7 @@ } void MockPermissionPromptFactory::ShowView(MockPermissionPrompt* prompt) { - if (ContainsValue(prompts_, prompt)) + if (base::ContainsValue(prompts_, prompt)) return; prompts_.push_back(prompt);
diff --git a/chrome/browser/ui/website_settings/permission_bubble_request.cc b/chrome/browser/ui/website_settings/permission_bubble_request.cc deleted file mode 100644 index 7180ab0..0000000 --- a/chrome/browser/ui/website_settings/permission_bubble_request.cc +++ /dev/null
@@ -1,19 +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. - -#include "chrome/browser/ui/website_settings/permission_bubble_request.h" - -#include "ui/gfx/vector_icons_public.h" - -gfx::VectorIconId PermissionBubbleRequest::GetVectorIconId() const { - return gfx::VectorIconId::VECTOR_ICON_NONE; -} - -PermissionBubbleType PermissionBubbleRequest::GetPermissionBubbleType() const { - return PermissionBubbleType::UNKNOWN; -} - -PermissionBubbleGestureType PermissionBubbleRequest::GetGestureType() const { - return PermissionBubbleGestureType::UNKNOWN; -}
diff --git a/chrome/browser/ui/website_settings/website_settings.cc b/chrome/browser/ui/website_settings/website_settings.cc index 4a5fb69a..ff46e29 100644 --- a/chrome/browser/ui/website_settings/website_settings.cc +++ b/chrome/browser/ui/website_settings/website_settings.cc
@@ -560,12 +560,12 @@ } if (security_info.mixed_content_status != - SecurityStateModel::NO_MIXED_CONTENT) { + SecurityStateModel::CONTENT_STATUS_NONE) { bool ran_insecure_content = (security_info.mixed_content_status == - SecurityStateModel::RAN_MIXED_CONTENT || + SecurityStateModel::CONTENT_STATUS_RAN || security_info.mixed_content_status == - SecurityStateModel::RAN_AND_DISPLAYED_MIXED_CONTENT); + SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN); site_connection_status_ = ran_insecure_content ? SITE_CONNECTION_STATUS_MIXED_SCRIPT : SITE_CONNECTION_STATUS_MIXED_CONTENT;
diff --git a/chrome/browser/ui/website_settings/website_settings_unittest.cc b/chrome/browser/ui/website_settings/website_settings_unittest.cc index 6c38587b..baf675a 100644 --- a/chrome/browser/ui/website_settings/website_settings_unittest.cc +++ b/chrome/browser/ui/website_settings/website_settings_unittest.cc
@@ -385,7 +385,7 @@ security_info_.cert_status = 0; security_info_.security_bits = 81; // No error if > 80. security_info_.mixed_content_status = - SecurityStateModel::DISPLAYED_MIXED_CONTENT; + SecurityStateModel::CONTENT_STATUS_DISPLAYED; int status = 0; status = SetSSLVersion(status, net::SSL_CONNECTION_VERSION_TLS1); status = SetSSLCipherSuite(status, CR_TLS_RSA_WITH_AES_256_CBC_SHA256); @@ -411,7 +411,7 @@ security_info_.cert_status = 0; security_info_.security_bits = 81; // No error if > 80. security_info_.mixed_content_status = - SecurityStateModel::RAN_AND_DISPLAYED_MIXED_CONTENT; + SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN; int status = 0; status = SetSSLVersion(status, net::SSL_CONNECTION_VERSION_TLS1); status = SetSSLCipherSuite(status, CR_TLS_RSA_WITH_AES_256_CBC_SHA256); @@ -445,7 +445,7 @@ security_info_.cert_status = net::CERT_STATUS_IS_EV; security_info_.security_bits = 81; // No error if > 80. security_info_.mixed_content_status = - SecurityStateModel::DISPLAYED_MIXED_CONTENT; + SecurityStateModel::CONTENT_STATUS_DISPLAYED; int status = 0; status = SetSSLVersion(status, net::SSL_CONNECTION_VERSION_TLS1); status = SetSSLCipherSuite(status, CR_TLS_RSA_WITH_AES_256_CBC_SHA256);
diff --git a/chrome/browser/ui/webui/browsing_history_handler.cc b/chrome/browser/ui/webui/browsing_history_handler.cc index 1d077ead..770cb5fc 100644 --- a/chrome/browser/ui/webui/browsing_history_handler.cc +++ b/chrome/browser/ui/webui/browsing_history_handler.cc
@@ -48,10 +48,10 @@ #include "components/keyed_service/core/service_access_type.h" #include "components/prefs/pref_service.h" #include "components/query_parser/snippet.h" +#include "components/sync/driver/device_info.h" +#include "components/sync/driver/device_info_tracker.h" #include "components/sync/protocol/history_delete_directive_specifics.pb.h" #include "components/sync/protocol/sync_enums.pb.h" -#include "components/sync_driver/device_info.h" -#include "components/sync_driver/device_info_tracker.h" #include "components/url_formatter/url_formatter.h" #include "content/public/browser/url_data_source.h" #include "content/public/browser/web_ui.h"
diff --git a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc index 188ffd2..417055d 100644 --- a/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.cc
@@ -171,7 +171,7 @@ if (input_method.empty()) return; - if (!ContainsValue(*input_methods, input_method)) + if (!base::ContainsValue(*input_methods, input_method)) input_methods->insert(input_methods->begin(), input_method); }
diff --git a/chrome/browser/ui/webui/chromeos/login/l10n_util.cc b/chrome/browser/ui/webui/chromeos/login/l10n_util.cc index 49a7aa84..41389aa 100644 --- a/chrome/browser/ui/webui/chromeos/login/l10n_util.cc +++ b/chrome/browser/ui/webui/chromeos/login/l10n_util.cc
@@ -155,7 +155,7 @@ if (lang.empty() || lang == language_id) continue; - if (ContainsValue(base_language_codes, language_id)) { + if (base::ContainsValue(base_language_codes, language_id)) { // Language is supported. No need to replace continue; } @@ -163,7 +163,7 @@ if (!l10n_util::CheckAndResolveLocale(language_id, &resolved_locale)) continue; - if (!ContainsValue(base_language_codes, resolved_locale)) { + if (!base::ContainsValue(base_language_codes, resolved_locale)) { // Resolved locale is not supported. continue; } @@ -186,26 +186,25 @@ it != language_codes.end(); ++it) { // Exclude the language which is not in |base_langauge_codes| even it has // input methods. - if (!ContainsValue(base_language_codes, *it)) - continue; + if (!base::ContainsValue(base_language_codes, *it)) + continue; - const base::string16 display_name = - l10n_util::GetDisplayNameForLocale(*it, app_locale, true); - const base::string16 native_display_name = - l10n_util::GetDisplayNameForLocale(*it, *it, true); + const base::string16 display_name = + l10n_util::GetDisplayNameForLocale(*it, app_locale, true); + const base::string16 native_display_name = + l10n_util::GetDisplayNameForLocale(*it, *it, true); - language_map[display_name] = - std::make_pair(*it, native_display_name); + language_map[display_name] = std::make_pair(*it, native_display_name); - const std::map<std::string, int>::const_iterator index_pos = - language_index.find(*it); - if (index_pos != language_index.end()) { - base::string16& stored_display_name = - most_relevant_locales_display_names[index_pos->second]; - if (stored_display_name.empty()) { - stored_display_name = display_name; - ++most_relevant_locales_count; - } + const std::map<std::string, int>::const_iterator index_pos = + language_index.find(*it); + if (index_pos != language_index.end()) { + base::string16& stored_display_name = + most_relevant_locales_display_names[index_pos->second]; + if (stored_display_name.empty()) { + stored_display_name = display_name; + ++most_relevant_locales_count; + } } else { display_names.push_back(display_name); }
diff --git a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc index 6e31d3c..bb2135d 100644 --- a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
@@ -166,6 +166,8 @@ // MD-OOBE builder->Add("oobeOKButtonText", IDS_OOBE_OK_BUTTON_TEXT); builder->Add("languageSectionTitle", IDS_LANGUAGE_SECTION_TITLE); + builder->Add("accessibilitySectionTitle", IDS_ACCESSIBILITY_SECTION_TITLE); + builder->Add("accessibilitySectionHint", IDS_ACCESSIBILITY_SECTION_HINT); builder->Add("networkSectionTitle", IDS_NETWORK_SECTION_TITLE); builder->Add("networkSectionHint", IDS_NETWORK_SECTION_HINT); @@ -174,6 +176,18 @@ builder->Add("proxySettingsMenuName", IDS_PROXY_SETTINGS_MENU_NAME); builder->Add("addWiFiNetworkMenuName", IDS_ADD_WI_FI_NETWORK_MENU_NAME); builder->Add("addMobileNetworkMenuName", IDS_ADD_MOBILE_NETWORK_MENU_NAME); + + builder->Add("highContrastOptionOff", IDS_HIGH_CONTRAST_OPTION_OFF); + builder->Add("highContrastOptionOn", IDS_HIGH_CONTRAST_OPTION_ON); + builder->Add("largeCursorOptionOff", IDS_LARGE_CURSOR_OPTION_OFF); + builder->Add("largeCursorOptionOn", IDS_LARGE_CURSOR_OPTION_ON); + builder->Add("screenMagnifierOptionOff", IDS_SCREEN_MAGNIFIER_OPTION_OFF); + builder->Add("screenMagnifierOptionOn", IDS_SCREEN_MAGNIFIER_OPTION_ON); + builder->Add("spokenFeedbackOptionOff", IDS_SPOKEN_FEEDBACK_OPTION_OFF); + builder->Add("spokenFeedbackOptionOn", IDS_SPOKEN_FEEDBACK_OPTION_ON); + builder->Add("virtualKeyboardOptionOff", IDS_VIRTUAL_KEYBOARD_OPTION_OFF); + builder->Add("virtualKeyboardOptionOn", IDS_VIRTUAL_KEYBOARD_OPTION_ON); + } void NetworkScreenHandler::GetAdditionalParameters(
diff --git a/chrome/browser/ui/webui/cookies_tree_model_util.cc b/chrome/browser/ui/webui/cookies_tree_model_util.cc index a1cef917..afacc2b 100644 --- a/chrome/browser/ui/webui/cookies_tree_model_util.cc +++ b/chrome/browser/ui/webui/cookies_tree_model_util.cc
@@ -201,18 +201,18 @@ const storage::FileSystemType kTemp = storage::kFileSystemTypeTemporary; dict->SetString(kKeyOrigin, file_system_info.origin.spec()); - dict->SetString(kKeyPersistent, - ContainsKey(file_system_info.usage_map, kPerm) ? - base::UTF16ToUTF8(ui::FormatBytes( - file_system_info.usage_map.find(kPerm)->second)) : - l10n_util::GetStringUTF8( - IDS_COOKIES_FILE_SYSTEM_USAGE_NONE)); - dict->SetString(kKeyTemporary, - ContainsKey(file_system_info.usage_map, kTemp) ? - base::UTF16ToUTF8(ui::FormatBytes( - file_system_info.usage_map.find(kTemp)->second)) : - l10n_util::GetStringUTF8( - IDS_COOKIES_FILE_SYSTEM_USAGE_NONE)); + dict->SetString( + kKeyPersistent, + base::ContainsKey(file_system_info.usage_map, kPerm) + ? base::UTF16ToUTF8(ui::FormatBytes( + file_system_info.usage_map.find(kPerm)->second)) + : l10n_util::GetStringUTF8(IDS_COOKIES_FILE_SYSTEM_USAGE_NONE)); + dict->SetString( + kKeyTemporary, + base::ContainsKey(file_system_info.usage_map, kTemp) + ? base::UTF16ToUTF8(ui::FormatBytes( + file_system_info.usage_map.find(kTemp)->second)) + : l10n_util::GetStringUTF8(IDS_COOKIES_FILE_SYSTEM_USAGE_NONE)); break; } case CookieTreeNode::DetailedInfo::TYPE_QUOTA: {
diff --git a/chrome/browser/ui/webui/extensions/extension_icon_source.cc b/chrome/browser/ui/webui/extensions/extension_icon_source.cc index ac6c03f..b3fb79d 100644 --- a/chrome/browser/ui/webui/extensions/extension_icon_source.cc +++ b/chrome/browser/ui/webui/extensions/extension_icon_source.cc
@@ -147,7 +147,7 @@ ExtensionIconSource::~ExtensionIconSource() { // Clean up all the temporary data we're holding for requests. - STLDeleteValues(&request_map_); + base::STLDeleteValues(&request_map_); } const SkBitmap* ExtensionIconSource::GetDefaultAppImage() {
diff --git a/chrome/browser/ui/webui/foreign_session_handler.h b/chrome/browser/ui/webui/foreign_session_handler.h index 91c8314..37fae2c 100644 --- a/chrome/browser/ui/webui/foreign_session_handler.h +++ b/chrome/browser/ui/webui/foreign_session_handler.h
@@ -11,7 +11,7 @@ #include "base/scoped_observer.h" #include "base/time/time.h" #include "chrome/browser/sessions/session_service.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/sync_service_observer.h" #include "components/sync_sessions/open_tabs_ui_delegate.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_message_handler.h"
diff --git a/chrome/browser/ui/webui/inspect_ui.cc b/chrome/browser/ui/webui/inspect_ui.cc index 3fdb614..18c88bd 100644 --- a/chrome/browser/ui/webui/inspect_ui.cc +++ b/chrome/browser/ui/webui/inspect_ui.cc
@@ -416,7 +416,7 @@ if (target_handlers_.empty()) return; - STLDeleteValues(&target_handlers_); + base::STLDeleteValues(&target_handlers_); port_status_serializer_.reset();
diff --git a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc index 6c7e2fc..fa88541 100644 --- a/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc +++ b/chrome/browser/ui/webui/local_discovery/local_discovery_ui_handler.cc
@@ -79,13 +79,13 @@ const std::set<std::string>& local_ids, base::ListValue* devices_list) { for (const auto& i : devices) { - if (ContainsKey(local_ids, i.id)) { + if (base::ContainsKey(local_ids, i.id)) { devices_list->Append(CreateDeviceInfo(i)); } } for (const auto& i : devices) { - if (!ContainsKey(local_ids, i.id)) { + if (!base::ContainsKey(local_ids, i.id)) { devices_list->Append(CreateDeviceInfo(i)); } } @@ -277,7 +277,8 @@ const GURL& url) { web_ui()->CallJavascriptFunctionUnsafe( "local_discovery.onRegistrationConfirmedOnPrinter"); - if (!ContainsKey(device_descriptions_, current_http_client_->GetName())) { + if (!base::ContainsKey(device_descriptions_, + current_http_client_->GetName())) { SendRegisterError(); return; }
diff --git a/chrome/browser/ui/webui/md_downloads/downloads_list_tracker.cc b/chrome/browser/ui/webui/md_downloads/downloads_list_tracker.cc index aa7d0dd..caf07f6 100644 --- a/chrome/browser/ui/webui/md_downloads/downloads_list_tracker.cc +++ b/chrome/browser/ui/webui/md_downloads/downloads_list_tracker.cc
@@ -340,6 +340,7 @@ !item.IsTemporary() && !item.GetFileNameToReportUser().empty() && !item.GetTargetFilePath().empty() && + !item.GetURL().is_empty() && DownloadItemModel(const_cast<DownloadItem*>(&item)).ShouldShowInShelf() && DownloadQuery::MatchesQuery(search_terms_, item); }
diff --git a/chrome/browser/ui/webui/md_downloads/downloads_list_tracker_unittest.cc b/chrome/browser/ui/webui/md_downloads/downloads_list_tracker_unittest.cc index 0e7adfd..f3f8978 100644 --- a/chrome/browser/ui/webui/md_downloads/downloads_list_tracker_unittest.cc +++ b/chrome/browser/ui/webui/md_downloads/downloads_list_tracker_unittest.cc
@@ -98,7 +98,7 @@ ~DownloadsListTrackerTest() override { for (auto* mock_item : mock_items_) testing::Mock::VerifyAndClear(mock_item); - STLDeleteElements(&mock_items_); + base::STLDeleteElements(&mock_items_); } // testing::Test:
diff --git a/chrome/browser/ui/webui/md_history_ui.cc b/chrome/browser/ui/webui/md_history_ui.cc index 01e7845d..b41dac4 100644 --- a/chrome/browser/ui/webui/md_history_ui.cc +++ b/chrome/browser/ui/webui/md_history_ui.cc
@@ -131,6 +131,10 @@ source->AddResourcePath("history_list.html", IDR_MD_HISTORY_HISTORY_LIST_HTML); source->AddResourcePath("history_list.js", IDR_MD_HISTORY_HISTORY_LIST_JS); + source->AddResourcePath("history_list_behavior.html", + IDR_MD_HISTORY_HISTORY_LIST_BEHAVIOR_HTML); + source->AddResourcePath("history_list_behavior.js", + IDR_MD_HISTORY_HISTORY_LIST_BEHAVIOR_JS); source->AddResourcePath("history_toolbar.html", IDR_MD_HISTORY_HISTORY_TOOLBAR_HTML); source->AddResourcePath("history_toolbar.js",
diff --git a/chrome/browser/ui/webui/media_router/media_router_ui.cc b/chrome/browser/ui/webui/media_router/media_router_ui.cc index a03e149..e4e1e70 100644 --- a/chrome/browser/ui/webui/media_router/media_router_ui.cc +++ b/chrome/browser/ui/webui/media_router/media_router_ui.cc
@@ -149,7 +149,7 @@ } } #endif - if (ContainsValue(joinable_route_ids, route.media_route_id())) { + if (base::ContainsValue(joinable_route_ids, route.media_route_id())) { joinable_route_ids_for_display.push_back(route.media_route_id()); } @@ -207,7 +207,7 @@ if (create_session_request_) { bool presentation_sinks_available = std::any_of( sinks_.begin(), sinks_.end(), [](const MediaSinkWithCastModes& sink) { - return ContainsValue(sink.cast_modes, MediaCastMode::DEFAULT); + return base::ContainsValue(sink.cast_modes, MediaCastMode::DEFAULT); }); if (presentation_sinks_available) { create_session_request_->InvokeErrorCallback(content::PresentationError(
diff --git a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc index bd36420..f434f28 100644 --- a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc +++ b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc
@@ -880,7 +880,8 @@ media_router_ui_->GetRouteProviderExtensionId(); for (const MediaRoute& route : routes) { - bool can_join = ContainsValue(joinable_route_ids, route.media_route_id()); + bool can_join = + base::ContainsValue(joinable_route_ids, route.media_route_id()); int current_cast_mode = CurrentCastModeForRouteId(route.media_route_id(), current_cast_modes); std::unique_ptr<base::DictionaryValue> route_val(RouteToValue(
diff --git a/chrome/browser/ui/webui/media_router/query_result_manager.cc b/chrome/browser/ui/webui/media_router/query_result_manager.cc index ba2f04a7..132bd92 100644 --- a/chrome/browser/ui/webui/media_router/query_result_manager.cc +++ b/chrome/browser/ui/webui/media_router/query_result_manager.cc
@@ -131,7 +131,7 @@ // (1) Iterate through current sink set, remove cast mode from those that // do not appear in latest result. for (auto it = all_sinks_.begin(); it != all_sinks_.end(); /*no-op*/) { - if (!ContainsKey(result_sink_ids, it->first)) { + if (!base::ContainsKey(result_sink_ids, it->first)) { it->second.cast_modes.erase(cast_mode); } if (!IsValid(it->second)) {
diff --git a/chrome/browser/ui/webui/media_router/query_result_manager_unittest.cc b/chrome/browser/ui/webui/media_router/query_result_manager_unittest.cc index 0d580191..c575d05 100644 --- a/chrome/browser/ui/webui/media_router/query_result_manager_unittest.cc +++ b/chrome/browser/ui/webui/media_router/query_result_manager_unittest.cc
@@ -103,7 +103,7 @@ cast_modes = query_result_manager_.GetSupportedCastModes(); EXPECT_EQ(1u, cast_modes.size()); - EXPECT_TRUE(ContainsKey(cast_modes, MediaCastMode::DEFAULT)); + EXPECT_TRUE(base::ContainsKey(cast_modes, MediaCastMode::DEFAULT)); actual_source = query_result_manager_.GetSourceForCastMode( MediaCastMode::DEFAULT); EXPECT_TRUE(source.Equals(actual_source)); @@ -118,7 +118,7 @@ cast_modes = query_result_manager_.GetSupportedCastModes(); EXPECT_EQ(1u, cast_modes.size()); - EXPECT_TRUE(ContainsKey(cast_modes, MediaCastMode::DEFAULT)); + EXPECT_TRUE(base::ContainsKey(cast_modes, MediaCastMode::DEFAULT)); actual_source = query_result_manager_.GetSourceForCastMode( MediaCastMode::DEFAULT); EXPECT_TRUE(another_source.Equals(actual_source));
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc index a9314bd..c033096 100644 --- a/chrome/browser/ui/webui/options/browser_options_handler.cc +++ b/chrome/browser/ui/webui/options/browser_options_handler.cc
@@ -459,18 +459,7 @@ IDS_OPTIONS_SETTINGS_ACCESSIBILITY_AUTOCLICK_DELAY_VERY_SHORT }, { "changePicture", IDS_OPTIONS_CHANGE_PICTURE }, { "changePictureCaption", IDS_OPTIONS_CHANGE_PICTURE_CAPTION }, - { "consumerManagementDescription", - IDS_OPTIONS_CONSUMER_MANAGEMENT_DESCRIPTION }, - { "consumerManagementEnrollButton", - IDS_OPTIONS_CONSUMER_MANAGEMENT_ENROLL_BUTTON }, - { "consumerManagementEnrollingButton", - IDS_OPTIONS_CONSUMER_MANAGEMENT_ENROLLING_BUTTON }, - { "consumerManagementUnenrollButton", - IDS_OPTIONS_CONSUMER_MANAGEMENT_UNENROLL_BUTTON }, - { "consumerManagementUnenrollingButton", - IDS_OPTIONS_CONSUMER_MANAGEMENT_UNENROLLING_BUTTON }, { "datetimeTitle", IDS_OPTIONS_SETTINGS_SECTION_TITLE_DATETIME }, - { "deviceControlTitle", IDS_OPTIONS_DEVICE_CONTROL_SECTION_TITLE }, { "deviceGroupDescription", IDS_OPTIONS_DEVICE_GROUP_DESCRIPTION }, { "deviceGroupPointer", IDS_OPTIONS_DEVICE_GROUP_POINTER_SECTION }, { "disableGData", IDS_OPTIONS_DISABLE_GDATA }, @@ -679,10 +668,6 @@ proximity_auth::switches::kEnableProximityDetection)); #if defined(OS_CHROMEOS) - values->SetBoolean("consumerManagementEnabled", - base::CommandLine::ForCurrentProcess()->HasSwitch( - chromeos::switches::kEnableConsumerManagement)); - RegisterTitle(values, "thirdPartyImeConfirmOverlay", IDS_OPTIONS_SETTINGS_LANGUAGES_THIRD_PARTY_WARNING_TITLE); values->SetBoolean("usingNewProfilesUI", false); @@ -869,11 +854,6 @@ ExtensionRegistry::Get(Profile::FromWebUI(web_ui()))->RemoveObserver(this); #endif #if defined(OS_CHROMEOS) - policy::ConsumerManagementService* consumer_management = - g_browser_process->platform_part()->browser_policy_connector_chromeos()-> - GetConsumerManagementService(); - if (consumer_management) - consumer_management->RemoveObserver(this); ArcAppListPrefs* arc_prefs = ArcAppListPrefs::Get( Profile::FromWebUI(web_ui())); if (arc_prefs) @@ -1091,14 +1071,6 @@ chromeos::WallpaperManager::Get()->IsPolicyControlled( user->GetAccountId())); - policy::ConsumerManagementService* consumer_management = - g_browser_process->platform_part()->browser_policy_connector_chromeos()-> - GetConsumerManagementService(); - if (consumer_management) { - OnConsumerManagementStatusChanged(); - consumer_management->AddObserver(this); - } - if (arc::ArcAuthService::IsAllowedForProfile(profile) && !arc::ArcAuthService::IsOptInVerificationDisabled()) { base::FundamentalValue is_arc_enabled( @@ -1610,14 +1582,6 @@ chromeos::reset::DIALOG_VIEW_TYPE_SIZE); } -void BrowserOptionsHandler::OnConsumerManagementStatusChanged() { - const std::string& status = g_browser_process->platform_part()-> - browser_policy_connector_chromeos()->GetConsumerManagementService()-> - GetStatusString(); - web_ui()->CallJavascriptFunctionUnsafe( - "BrowserOptions.setConsumerManagementStatus", base::StringValue(status)); -} - #endif // defined(OS_CHROMEOS) void BrowserOptionsHandler::UpdateSyncState() { @@ -2212,7 +2176,7 @@ const policy::PolicyMap& current) { std::set<std::string> different_keys; current.GetDifferingKeys(previous, &different_keys); - if (ContainsKey(different_keys, policy::key::kMetricsReportingEnabled)) + if (base::ContainsKey(different_keys, policy::key::kMetricsReportingEnabled)) SetupMetricsReportingCheckbox(); }
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.h b/chrome/browser/ui/webui/options/browser_options_handler.h index 77b15d9..20d1bf9 100644 --- a/chrome/browser/ui/webui/options/browser_options_handler.h +++ b/chrome/browser/ui/webui/options/browser_options_handler.h
@@ -25,7 +25,7 @@ #include "components/search_engines/template_url_service_observer.h" #include "components/signin/core/browser/signin_manager_base.h" #include "components/signin/core/common/signin_pref_names.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/sync_service_observer.h" #include "content/public/browser/notification_observer.h" #include "extensions/browser/extension_registry_observer.h" #include "google_apis/gaia/google_service_auth_error.h" @@ -33,7 +33,6 @@ #include "ui/shell_dialogs/select_file_dialog.h" #if defined(OS_CHROMEOS) -#include "chrome/browser/chromeos/policy/consumer_management_service.h" #include "chrome/browser/chromeos/system/pointer_device_observer.h" #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #else // defined(OS_CHROMEOS) @@ -64,7 +63,6 @@ public ui::SelectFileDialog::Listener, #if defined(OS_CHROMEOS) public chromeos::system::PointerDeviceObserver::Observer, - public policy::ConsumerManagementService::Observer, public ArcAppListPrefs::Observer, #endif public TemplateURLServiceObserver, @@ -147,9 +145,6 @@ // Will be called when powerwash dialog is shown. void OnPowerwashDialogShow(const base::ListValue* args); - // ConsumerManagementService::Observer: - void OnConsumerManagementStatusChanged() override; - // ArcAppListPrefs::Observer overrides. void OnAppReadyChanged(const std::string& app_id, bool ready) override; void OnAppRemoved(const std::string& app_id) override;
diff --git a/chrome/browser/ui/webui/options/chromeos/consumer_management_handler.cc b/chrome/browser/ui/webui/options/chromeos/consumer_management_handler.cc deleted file mode 100644 index 7acbd03..0000000 --- a/chrome/browser/ui/webui/options/chromeos/consumer_management_handler.cc +++ /dev/null
@@ -1,112 +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/options/chromeos/consumer_management_handler.h" - -#include "ash/common/system/chromeos/devicetype_utils.h" -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/logging.h" -#include "base/values.h" -#include "chrome/browser/chromeos/policy/consumer_management_service.h" -#include "chrome/browser/chromeos/policy/consumer_management_stage.h" -#include "chrome/browser/chromeos/policy/consumer_unenrollment_handler.h" -#include "chrome/browser/chromeos/policy/consumer_unenrollment_handler_factory.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/grit/generated_resources.h" -#include "chromeos/dbus/dbus_thread_manager.h" -#include "chromeos/dbus/power_manager_client.h" -#include "components/user_manager/user_manager.h" -#include "content/public/browser/web_ui.h" -#include "ui/base/l10n/l10n_util.h" - -namespace chromeos { -namespace options { - -ConsumerManagementHandler::ConsumerManagementHandler( - policy::ConsumerManagementService* management_service) - : management_service_(management_service) { -} - -ConsumerManagementHandler::~ConsumerManagementHandler() { -} - -void ConsumerManagementHandler::GetLocalizedValues( - base::DictionaryValue* localized_strings) { - DCHECK(localized_strings); - - RegisterTitle(localized_strings, "consumerManagementOverlay", - IDS_OPTIONS_CONSUMER_MANAGEMENT_OVERLAY); - - // Enroll. - localized_strings->SetString( - "consumerManagementOverlayEnrollTitle", - ash::SubstituteChromeOSDeviceType( - IDS_OPTIONS_CONSUMER_MANAGEMENT_OVERLAY_ENROLL_TITLE)); - localized_strings->SetString( - "consumerManagementOverlayEnrollMessage", - ash::SubstituteChromeOSDeviceType( - IDS_OPTIONS_CONSUMER_MANAGEMENT_OVERLAY_ENROLL_MESSAGE)); - localized_strings->SetString( - "consumerManagementOverlayEnroll", - l10n_util::GetStringUTF16( - IDS_OPTIONS_CONSUMER_MANAGEMENT_OVERLAY_ENROLL)); - - // Unenroll. - localized_strings->SetString( - "consumerManagementOverlayUnenrollTitle", - ash::SubstituteChromeOSDeviceType( - IDS_OPTIONS_CONSUMER_MANAGEMENT_OVERLAY_UNENROLL_TITLE)); - localized_strings->SetString( - "consumerManagementOverlayUnenrollMessage", - ash::SubstituteChromeOSDeviceType( - IDS_OPTIONS_CONSUMER_MANAGEMENT_OVERLAY_UNENROLL_MESSAGE)); - localized_strings->SetString( - "consumerManagementOverlayUnenroll", - l10n_util::GetStringUTF16( - IDS_OPTIONS_CONSUMER_MANAGEMENT_OVERLAY_UNENROLL)); -} - -void ConsumerManagementHandler::RegisterMessages() { - web_ui()->RegisterMessageCallback( - "enrollConsumerManagement", - base::Bind(&ConsumerManagementHandler::HandleEnrollConsumerManagement, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( - "unenrollConsumerManagement", - base::Bind(&ConsumerManagementHandler::HandleUnenrollConsumerManagement, - base::Unretained(this))); -} - -void ConsumerManagementHandler::HandleEnrollConsumerManagement( - const base::ListValue* args) { - if (!user_manager::UserManager::Get()->IsCurrentUserOwner()) { - LOG(ERROR) << "Received enrollConsumerManagement, but the current user is " - << "not the owner."; - return; - } - - CHECK(management_service_); - management_service_->SetStage( - policy::ConsumerManagementStage::EnrollmentRequested()); - chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RequestRestart(); -} - -void ConsumerManagementHandler::HandleUnenrollConsumerManagement( - const base::ListValue* args) { - if (!user_manager::UserManager::Get()->IsCurrentUserOwner()) { - LOG(ERROR) << "Received unenrollConsumerManagement, but the current user " - << "is not the owner."; - return; - } - - CHECK(management_service_); - management_service_->SetStage( - policy::ConsumerManagementStage::UnenrollmentRequested()); - policy::ConsumerUnenrollmentHandlerFactory::GetForBrowserContext( - Profile::FromWebUI(web_ui()))->Start(); -} - -} // namespace options -} // namespace chromeos
diff --git a/chrome/browser/ui/webui/options/chromeos/consumer_management_handler.h b/chrome/browser/ui/webui/options/chromeos/consumer_management_handler.h deleted file mode 100644 index a2c618c9..0000000 --- a/chrome/browser/ui/webui/options/chromeos/consumer_management_handler.h +++ /dev/null
@@ -1,44 +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_OPTIONS_CHROMEOS_CONSUMER_MANAGEMENT_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_CONSUMER_MANAGEMENT_HANDLER_H_ - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/values.h" -#include "chrome/browser/ui/webui/options/options_ui.h" - -namespace policy { -class ConsumerManagementService; -} - -namespace chromeos { -namespace options { - -// Consumer management overlay page UI handler. -class ConsumerManagementHandler : public ::options::OptionsPageUIHandler { - public: - explicit ConsumerManagementHandler( - policy::ConsumerManagementService* management_service); - ~ConsumerManagementHandler() override; - - // OptionsPageUIHandler implementation. - void GetLocalizedValues(base::DictionaryValue* localized_strings) override; - void RegisterMessages() override; - - private: - // Handles the button click events from the browser options page. - void HandleEnrollConsumerManagement(const base::ListValue* args); - void HandleUnenrollConsumerManagement(const base::ListValue* args); - - policy::ConsumerManagementService* management_service_; - - DISALLOW_COPY_AND_ASSIGN(ConsumerManagementHandler); -}; - -} // namespace options -} // namespace chromeos - -#endif // CHROME_BROWSER_UI_WEBUI_OPTIONS_CHROMEOS_CONSUMER_MANAGEMENT_HANDLER_H_
diff --git a/chrome/browser/ui/webui/options/content_settings_handler.cc b/chrome/browser/ui/webui/options/content_settings_handler.cc index b3ec85b..4649e648 100644 --- a/chrome/browser/ui/webui/options/content_settings_handler.cc +++ b/chrome/browser/ui/webui/options/content_settings_handler.cc
@@ -722,7 +722,7 @@ UpdateAllExceptionsViewsFromModel(); UpdateAllChooserExceptionsViewsFromModel(); } else { - if (ContainsKey(GetExceptionsInfoMap(), details.type())) + if (base::ContainsKey(GetExceptionsInfoMap(), details.type())) UpdateExceptionsViewFromModel(details.type()); } }
diff --git a/chrome/browser/ui/webui/options/manage_profile_handler.h b/chrome/browser/ui/webui/options/manage_profile_handler.h index fe6ec6c..91aa476 100644 --- a/chrome/browser/ui/webui/options/manage_profile_handler.h +++ b/chrome/browser/ui/webui/options/manage_profile_handler.h
@@ -12,7 +12,7 @@ #include "chrome/browser/profiles/profile_attributes_storage.h" #include "chrome/browser/ui/webui/options/options_ui.h" #include "components/prefs/pref_change_registrar.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/sync_service_observer.h" namespace base { class StringValue;
diff --git a/chrome/browser/ui/webui/options/options_ui.cc b/chrome/browser/ui/webui/options/options_ui.cc index d1498e47..559f096 100644 --- a/chrome/browser/ui/webui/options/options_ui.cc +++ b/chrome/browser/ui/webui/options/options_ui.cc
@@ -81,12 +81,10 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" -#include "chrome/browser/chromeos/policy/consumer_management_service.h" #include "chrome/browser/chromeos/system/pointer_device_observer.h" #include "chrome/browser/ui/webui/options/chromeos/accounts_options_handler.h" #include "chrome/browser/ui/webui/options/chromeos/bluetooth_options_handler.h" #include "chrome/browser/ui/webui/options/chromeos/change_picture_options_handler.h" -#include "chrome/browser/ui/webui/options/chromeos/consumer_management_handler.h" #include "chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h" #include "chrome/browser/ui/webui/options/chromeos/cros_language_options_handler.h" #include "chrome/browser/ui/webui/options/chromeos/date_time_options_handler.h" @@ -343,13 +341,6 @@ new chromeos::options::StatsOptionsHandler()); AddOptionsPageUIHandler(localized_strings, new chromeos::options::StorageManagerHandler()); - - policy::ConsumerManagementService* consumer_management = - g_browser_process->platform_part()->browser_policy_connector_chromeos()-> - GetConsumerManagementService(); - chromeos::options::ConsumerManagementHandler* consumer_management_handler = - new chromeos::options::ConsumerManagementHandler(consumer_management); - AddOptionsPageUIHandler(localized_strings, consumer_management_handler); #endif #if defined(USE_NSS_CERTS) AddOptionsPageUIHandler(localized_strings,
diff --git a/chrome/browser/ui/webui/options/sync_setup_handler.cc b/chrome/browser/ui/webui/options/sync_setup_handler.cc index 3462aee..60adb6e 100644 --- a/chrome/browser/ui/webui/options/sync_setup_handler.cc +++ b/chrome/browser/ui/webui/options/sync_setup_handler.cc
@@ -48,7 +48,7 @@ #include "components/signin/core/browser/signin_header_helper.h" #include "components/signin/core/browser/signin_metrics.h" #include "components/signin/core/common/profile_management_switches.h" -#include "components/sync_driver/sync_prefs.h" +#include "components/sync/driver/sync_prefs.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h"
diff --git a/chrome/browser/ui/webui/options/sync_setup_handler_unittest.cc b/chrome/browser/ui/webui/options/sync_setup_handler_unittest.cc index 28196bd..aadfa7a1 100644 --- a/chrome/browser/ui/webui/options/sync_setup_handler_unittest.cc +++ b/chrome/browser/ui/webui/options/sync_setup_handler_unittest.cc
@@ -29,7 +29,7 @@ #include "components/prefs/pref_service.h" #include "components/signin/core/browser/fake_auth_status_provider.h" #include "components/signin/core/browser/signin_manager.h" -#include "components/sync_driver/sync_prefs.h" +#include "components/sync/driver/sync_prefs.h" #include "content/public/browser/web_ui.h" #include "content/public/test/test_browser_thread.h" #include "content/public/test/test_browser_thread_bundle.h"
diff --git a/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.cc b/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.cc index 30e236e..524c6c0 100644 --- a/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.cc +++ b/chrome/browser/ui/webui/password_manager_internals/password_manager_internals_ui.cc
@@ -87,7 +87,7 @@ if (url.is_valid() && url.has_query()) { std::vector<std::string> query_parameters = base::SplitString( url.query(), "&", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); - if (ContainsValue(query_parameters, "reset_fre")) + if (base::ContainsValue(query_parameters, "reset_fre")) ResetAutoSignInFirstRunExperience(); } }
diff --git a/chrome/browser/ui/webui/settings/md_settings_ui.cc b/chrome/browser/ui/webui/settings/md_settings_ui.cc index 43de40b8..6e30deb2 100644 --- a/chrome/browser/ui/webui/settings/md_settings_ui.cc +++ b/chrome/browser/ui/webui/settings/md_settings_ui.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/ui/webui/settings/font_handler.h" #include "chrome/browser/ui/webui/settings/languages_handler.h" #include "chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.h" +#include "chrome/browser/ui/webui/settings/metrics_reporting_handler.h" #include "chrome/browser/ui/webui/settings/people_handler.h" #include "chrome/browser/ui/webui/settings/profile_info_handler.h" #include "chrome/browser/ui/webui/settings/protocol_handlers_handler.h" @@ -79,6 +80,9 @@ AddSettingsPageUIHandler(new ProtocolHandlersHandler()); AddSettingsPageUIHandler(new LanguagesHandler(web_ui)); AddSettingsPageUIHandler(new MediaDevicesSelectionHandler(profile)); +#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS) + AddSettingsPageUIHandler(new MetricsReportingHandler()); +#endif AddSettingsPageUIHandler(new PeopleHandler(profile)); AddSettingsPageUIHandler(new ProfileInfoHandler(profile)); AddSettingsPageUIHandler(new SearchEnginesHandler(profile));
diff --git a/chrome/browser/ui/webui/settings/metrics_reporting_handler.cc b/chrome/browser/ui/webui/settings/metrics_reporting_handler.cc new file mode 100644 index 0000000..1121c85 --- /dev/null +++ b/chrome/browser/ui/webui/settings/metrics_reporting_handler.cc
@@ -0,0 +1,107 @@ +// Copyright 2016 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. + +#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS) + +#include "chrome/browser/ui/webui/settings/metrics_reporting_handler.h" + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/values.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/metrics/chrome_metrics_service_accessor.h" +#include "chrome/browser/metrics/metrics_reporting_state.h" +#include "components/metrics/metrics_pref_names.h" +#include "components/prefs/pref_service.h" +#include "content/public/browser/web_ui.h" +#include "policy/policy_constants.h" + +namespace settings { + +MetricsReportingHandler::MetricsReportingHandler() {} +MetricsReportingHandler::~MetricsReportingHandler() {} + +void MetricsReportingHandler::RegisterMessages() { + web_ui()->RegisterMessageCallback("getMetricsReporting", + base::Bind(&MetricsReportingHandler::HandleGetMetricsReporting, + base::Unretained(this))); + web_ui()->RegisterMessageCallback("setMetricsReportingEnabled", + base::Bind(&MetricsReportingHandler::HandleSetMetricsReportingEnabled, + base::Unretained(this))); +} + +void MetricsReportingHandler::OnJavascriptAllowed() { + pref_member_.reset(new BooleanPrefMember); + pref_member_->Init(metrics::prefs::kMetricsReportingEnabled, + g_browser_process->local_state(), + base::Bind(&MetricsReportingHandler::OnPrefChanged, + base::Unretained(this))); + + policy_registrar_.reset(new policy::PolicyChangeRegistrar( + g_browser_process->policy_service(), + policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string()))); + policy_registrar_->Observe(policy::key::kMetricsReportingEnabled, + base::Bind(&MetricsReportingHandler::OnPolicyChanged, + base::Unretained(this))); +} + +void MetricsReportingHandler::OnJavascriptDisallowed() { + pref_member_.reset(); + policy_registrar_.reset(); +} + +void MetricsReportingHandler::HandleGetMetricsReporting( + const base::ListValue* args) { + AllowJavascript(); + const base::Value* callback_id; + CHECK(args->Get(0, &callback_id)); + ResolveJavascriptCallback(*callback_id, *CreateMetricsReportingDict()); +} + +std::unique_ptr<base::DictionaryValue> + MetricsReportingHandler::CreateMetricsReportingDict() { + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue); + dict->SetBoolean("enabled", + ChromeMetricsServiceAccessor::IsMetricsAndCrashReportingEnabled()); + dict->SetBoolean("managed", IsMetricsReportingPolicyManaged()); + return dict; +} + +void MetricsReportingHandler::HandleSetMetricsReportingEnabled( + const base::ListValue* args) { + if (IsMetricsReportingPolicyManaged()) { + NOTREACHED(); + // NOTE: ChangeMetricsReportingState() already checks whether metrics + // reporting is managed by policy. Also, the UI really shouldn't be able to + // send this message when managed. However, in this specific case, there's a + // sane, graceful fallback so we might as well do that. + SendMetricsReportingChange(); + return; + } + + bool enabled; + CHECK(args->GetBoolean(0, &enabled)); + ChangeMetricsReportingState(enabled); +} + +void MetricsReportingHandler::OnPolicyChanged(const base::Value* previous, + const base::Value* current) { + SendMetricsReportingChange(); +} + +void MetricsReportingHandler::OnPrefChanged(const std::string& pref_name) { + DCHECK_EQ(metrics::prefs::kMetricsReportingEnabled, pref_name); + SendMetricsReportingChange(); +} + +void MetricsReportingHandler::SendMetricsReportingChange() { + CallJavascriptFunction( + "cr.webUIListenerCallback", + base::StringValue("metrics-reporting-change"), + *CreateMetricsReportingDict()); +} + +} // namespace settings + +#endif // defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/webui/settings/metrics_reporting_handler.h b/chrome/browser/ui/webui/settings/metrics_reporting_handler.h new file mode 100644 index 0000000..73cc5bd95 --- /dev/null +++ b/chrome/browser/ui/webui/settings/metrics_reporting_handler.h
@@ -0,0 +1,73 @@ +// Copyright 2016 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_SETTINGS_METRICS_REPORTING_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_SETTINGS_METRICS_REPORTING_HANDLER_H_ + +#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS) + +#include <memory> + +#include "base/macros.h" +#include "chrome/browser/ui/webui/settings/settings_page_ui_handler.h" +#include "components/policy/core/common/policy_service.h" +#include "components/prefs/pref_member.h" + +namespace base { +class DictionaryValue; +} + +namespace settings { + +class MetricsReportingHandler : public SettingsPageUIHandler { + public: + MetricsReportingHandler(); + ~MetricsReportingHandler() override; + + // SettingsPageUIHandler: + void RegisterMessages() override; + void OnJavascriptAllowed() override; + void OnJavascriptDisallowed() override; + + protected: + // Handler for "getMetricsReporting" message. No arguments. Protected for + // testing. + void HandleGetMetricsReporting(const base::ListValue* args); + + private: + // Describes the state of metrics reporting in a base::DictionaryValue. + // Friends with ChromeMetricsServiceAccessor. + std::unique_ptr<base::DictionaryValue> CreateMetricsReportingDict(); + + // Handler for "setMetricsReportingEnabled" message. Passed a single, + // |enabled| boolean argument. + void HandleSetMetricsReportingEnabled(const base::ListValue* args); + + // Called when the policies that affect whether metrics reporting is managed + // change. + void OnPolicyChanged(const base::Value* current_policy, + const base::Value* previous_policy); + + // Called when the local state pref controlling metrics reporting changes. + void OnPrefChanged(const std::string& pref_name); + + // Sends a "metrics-reporting-change" WebUI listener event to the page. + void SendMetricsReportingChange(); + + // Used to track pref changes that affect whether metrics reporting is + // enabled. + std::unique_ptr<BooleanPrefMember> pref_member_; + + // Used to track policy changes that affect whether metrics reporting is + // enabled or managed. + std::unique_ptr<policy::PolicyChangeRegistrar> policy_registrar_; + + DISALLOW_COPY_AND_ASSIGN(MetricsReportingHandler); +}; + +} // namespace settings + +#endif // defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS) + +#endif // CHROME_BROWSER_UI_WEBUI_SETTINGS_METRICS_REPORTING_HANDLER_H_
diff --git a/chrome/browser/ui/webui/settings/metrics_reporting_handler_unittest.cc b/chrome/browser/ui/webui/settings/metrics_reporting_handler_unittest.cc new file mode 100644 index 0000000..038cd6a --- /dev/null +++ b/chrome/browser/ui/webui/settings/metrics_reporting_handler_unittest.cc
@@ -0,0 +1,127 @@ +// Copyright 2016 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. + +#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS) + +#include "chrome/browser/ui/webui/settings/metrics_reporting_handler.h" + +#include "base/memory/ptr_util.h" +#include "base/values.h" +#include "chrome/test/base/scoped_testing_local_state.h" +#include "chrome/test/base/testing_browser_process.h" +#include "components/metrics/metrics_pref_names.h" +#include "components/policy/core/browser/browser_policy_connector.h" +#include "components/policy/core/common/mock_configuration_policy_provider.h" +#include "components/policy/core/common/policy_map.h" +#include "components/policy/core/common/policy_types.h" +#include "components/prefs/pref_service.h" +#include "content/public/browser/web_ui.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "content/public/test/test_web_ui.h" +#include "policy/policy_constants.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace settings { + +class TestingMetricsReportingHandler : public MetricsReportingHandler { + public: + using MetricsReportingHandler::set_web_ui; + using MetricsReportingHandler::HandleGetMetricsReporting; +}; + +class MetricsReportingHandlerTest : public testing::Test { + public: + MetricsReportingHandlerTest() { + // Local state must be set up before |handler_|. + TestingBrowserProcess::CreateInstance(); + local_state_.reset(new ScopedTestingLocalState( + TestingBrowserProcess::GetGlobal())); + + handler_.reset(new TestingMetricsReportingHandler); + handler_->set_web_ui(&test_web_ui_); + + EXPECT_CALL(provider_, IsInitializationComplete(testing::_)).WillRepeatedly( + testing::Return(true)); + policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_); + } + + void SetUp() override { + ASSERT_EQ(local_state(), g_browser_process->local_state()); + EXPECT_TRUE(test_web_ui()->call_data().empty()); + + base::ListValue args; + args.Append(base::WrapUnique(new base::FundamentalValue(1))); + handler()->HandleGetMetricsReporting(&args); + + EXPECT_TRUE(handler()->IsJavascriptAllowed()); + EXPECT_EQ(1u, test_web_ui()->call_data().size()); + + test_web_ui()->ClearTrackedCalls(); + } + + void TearDown() override { + handler_.reset(); + } + + PrefService* local_state() { return local_state_->Get(); } + TestingMetricsReportingHandler* handler() { return handler_.get(); } + content::TestWebUI* test_web_ui() { return &test_web_ui_; } + policy::PolicyMap* map() { return &map_; } + policy::MockConfigurationPolicyProvider* provider() { return &provider_; } + + private: + content::TestBrowserThreadBundle thread_bundle_; + content::TestWebUI test_web_ui_; + std::unique_ptr<ScopedTestingLocalState> local_state_; + std::unique_ptr<TestingMetricsReportingHandler> handler_; + + policy::MockConfigurationPolicyProvider provider_; + policy::PolicyMap map_; +}; + +TEST_F(MetricsReportingHandlerTest, PrefChangesNotifyPage) { + // Toggle the pref. + local_state()->SetBoolean( + metrics::prefs::kMetricsReportingEnabled, + !local_state()->GetBoolean(metrics::prefs::kMetricsReportingEnabled)); + EXPECT_EQ(1u, test_web_ui()->call_data().size()); + + test_web_ui()->ClearTrackedCalls(); + handler()->DisallowJavascript(); + + // Toggle the pref again, while JavaScript is disabled. + local_state()->SetBoolean( + metrics::prefs::kMetricsReportingEnabled, + !local_state()->GetBoolean(metrics::prefs::kMetricsReportingEnabled)); + EXPECT_TRUE(test_web_ui()->call_data().empty()); +} + +TEST_F(MetricsReportingHandlerTest, PolicyChangesNotifyPage) { + // Change the policy, check that the page was notified. + map()->Set(policy::key::kMetricsReportingEnabled, + policy::POLICY_LEVEL_MANDATORY, + policy::POLICY_SCOPE_USER, + policy::POLICY_SOURCE_CLOUD, + base::WrapUnique(new base::FundamentalValue(true)), + nullptr); + provider()->UpdateChromePolicy(*map()); + EXPECT_EQ(1u, test_web_ui()->call_data().size()); + + test_web_ui()->ClearTrackedCalls(); + handler()->DisallowJavascript(); + + // Policies changing while JavaScript is disabled shouldn't notify the page. + map()->Set(policy::key::kMetricsReportingEnabled, + policy::POLICY_LEVEL_MANDATORY, + policy::POLICY_SCOPE_USER, + policy::POLICY_SOURCE_CLOUD, + base::WrapUnique(new base::FundamentalValue(false)), + nullptr); + provider()->UpdateChromePolicy(*map()); + EXPECT_TRUE(test_web_ui()->call_data().empty()); +} + +} // namespace settings + +#endif // defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc index 6cf9f39..68da5a6 100644 --- a/chrome/browser/ui/webui/settings/people_handler.cc +++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -44,7 +44,7 @@ #include "components/signin/core/browser/signin_metrics.h" #include "components/signin/core/common/profile_management_switches.h" #include "components/signin/core/common/signin_pref_names.h" -#include "components/sync_driver/sync_prefs.h" +#include "components/sync/driver/sync_prefs.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h"
diff --git a/chrome/browser/ui/webui/settings/people_handler.h b/chrome/browser/ui/webui/settings/people_handler.h index ac6f8cd..98303b24 100644 --- a/chrome/browser/ui/webui/settings/people_handler.h +++ b/chrome/browser/ui/webui/settings/people_handler.h
@@ -18,7 +18,7 @@ #include "chrome/browser/ui/webui/signin/login_ui_service.h" #include "components/prefs/pref_change_registrar.h" #include "components/signin/core/browser/signin_manager_base.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/sync_service_observer.h" class LoginUIService; class ProfileSyncService;
diff --git a/chrome/browser/ui/webui/settings/people_handler_unittest.cc b/chrome/browser/ui/webui/settings/people_handler_unittest.cc index 213d7b27..7c48167 100644 --- a/chrome/browser/ui/webui/settings/people_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/people_handler_unittest.cc
@@ -30,7 +30,7 @@ #include "components/prefs/pref_service.h" #include "components/signin/core/browser/fake_auth_status_provider.h" #include "components/signin/core/browser/signin_manager.h" -#include "components/sync_driver/sync_prefs.h" +#include "components/sync/driver/sync_prefs.h" #include "components/syncable_prefs/pref_service_syncable.h" #include "content/public/browser/web_ui.h" #include "content/public/test/test_browser_thread.h"
diff --git a/chrome/browser/ui/webui/settings/site_settings_handler.cc b/chrome/browser/ui/webui/settings/site_settings_handler.cc index 34443f4..e1e590d 100644 --- a/chrome/browser/ui/webui/settings/site_settings_handler.cc +++ b/chrome/browser/ui/webui/settings/site_settings_handler.cc
@@ -4,21 +4,106 @@ #include "chrome/browser/ui/webui/settings/site_settings_handler.h" +#include <memory> +#include <string> +#include <utility> + #include "base/bind.h" +#include "base/macros.h" +#include "base/values.h" #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" #include "chrome/browser/content_settings/host_content_settings_map_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/site_settings_helper.h" +#include "chrome/common/extensions/manifest_handlers/app_launch_info.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/content_settings/core/common/content_settings_types.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_ui.h" +#include "extensions/browser/extension_registry.h" +#include "extensions/common/permissions/api_permission.h" +#include "extensions/common/permissions/permissions_data.h" #include "storage/browser/quota/quota_manager.h" #include "storage/common/quota/quota_status_code.h" #include "ui/base/text/bytes_formatting.h" + namespace settings { +namespace { + +const char kAppName[] = "appName"; +const char kAppId[] = "appId"; + +// Return an appropriate API Permission ID for the given string name. +extensions::APIPermission::APIPermission::ID APIPermissionFromGroupName( + std::string type) { + // Once there are more than two groups to consider, this should be changed to + // something better than if's. + + if (site_settings::ContentSettingsTypeFromGroupName(type) == + CONTENT_SETTINGS_TYPE_GEOLOCATION) + return extensions::APIPermission::APIPermission::kGeolocation; + + if (site_settings::ContentSettingsTypeFromGroupName(type) == + CONTENT_SETTINGS_TYPE_NOTIFICATIONS) + return extensions::APIPermission::APIPermission::kNotifications; + + return extensions::APIPermission::APIPermission::kInvalid; +} + +// Add an "Allow"-entry to the list of |exceptions| for a |url_pattern| from +// the web extent of a hosted |app|. +void AddExceptionForHostedApp(const std::string& url_pattern, + const extensions::Extension& app, base::ListValue* exceptions) { + std::unique_ptr<base::DictionaryValue> exception(new base::DictionaryValue()); + + std::string setting_string = + content_settings::ContentSettingToString(CONTENT_SETTING_ALLOW); + DCHECK(!setting_string.empty()); + + exception->SetString(site_settings::kSetting, setting_string); + exception->SetString(site_settings::kOrigin, url_pattern); + exception->SetString(site_settings::kEmbeddingOrigin, url_pattern); + exception->SetString(site_settings::kSource, "HostedApp"); + exception->SetString(kAppName, app.name()); + exception->SetString(kAppId, app.id()); + exceptions->Append(std::move(exception)); +} + +// Asks the |profile| for hosted apps which have the |permission| set, and +// adds their web extent and launch URL to the |exceptions| list. +void AddExceptionsGrantedByHostedApps(content::BrowserContext* context, + extensions::APIPermission::APIPermission::ID permission, + base::ListValue* exceptions) { + const extensions::ExtensionSet& extensions = + extensions::ExtensionRegistry::Get(context)->enabled_extensions(); + for (extensions::ExtensionSet::const_iterator extension = extensions.begin(); + extension != extensions.end(); ++extension) { + if (!(*extension)->is_hosted_app() || + !(*extension)->permissions_data()->HasAPIPermission(permission)) + continue; + + extensions::URLPatternSet web_extent = (*extension)->web_extent(); + // Add patterns from web extent. + for (extensions::URLPatternSet::const_iterator pattern = web_extent.begin(); + pattern != web_extent.end(); ++pattern) { + std::string url_pattern = pattern->GetAsString(); + AddExceptionForHostedApp(url_pattern, *extension->get(), exceptions); + } + // Retrieve the launch URL. + GURL launch_url = + extensions::AppLaunchInfo::GetLaunchWebURL(extension->get()); + // Skip adding the launch URL if it is part of the web extent. + if (web_extent.MatchesURL(launch_url)) + continue; + AddExceptionForHostedApp(launch_url.spec(), *extension->get(), exceptions); + } +} + +} // namespace + + SiteSettingsHandler::SiteSettingsHandler(Profile* profile) : profile_(profile), observer_(this) { } @@ -226,6 +311,10 @@ HostContentSettingsMap* map = HostContentSettingsMapFactory::GetForProfile(profile_); std::unique_ptr<base::ListValue> exceptions(new base::ListValue); + + AddExceptionsGrantedByHostedApps(profile_, APIPermissionFromGroupName(type), + exceptions.get()); + site_settings::GetExceptionsFromHostContentSettingsMap( map, content_type, web_ui(), exceptions.get()); ResolveJavascriptCallback(*callback_id, *exceptions.get());
diff --git a/chrome/browser/ui/webui/snippets_internals_message_handler.cc b/chrome/browser/ui/webui/snippets_internals_message_handler.cc index e2705a8..4efe2c9 100644 --- a/chrome/browser/ui/webui/snippets_internals_message_handler.cc +++ b/chrome/browser/ui/webui/snippets_internals_message_handler.cc
@@ -191,10 +191,15 @@ SendBoolean("flag-snippets", base::FeatureList::IsEnabled( ntp_snippets::kContentSuggestionsFeature)); - - SendBoolean("flag-offline-page-suggestions", + SendBoolean("flag-recent-offline-tab-suggestions", base::FeatureList::IsEnabled( - ntp_snippets::kOfflinePageSuggestionsFeature)); + ntp_snippets::kRecentOfflineTabSuggestionsFeature)); + SendBoolean( + "flag-download-suggestions", + base::FeatureList::IsEnabled(ntp_snippets::kDownloadSuggestionsFeature)); + SendBoolean( + "flag-bookmark-suggestions", + base::FeatureList::IsEnabled(ntp_snippets::kBookmarkSuggestionsFeature)); web_ui()->CallJavascriptFunctionUnsafe( "chrome.SnippetsInternals.setHostRestricted",
diff --git a/chrome/browser/ui/webui/sync_internals_message_handler.cc b/chrome/browser/ui/webui/sync_internals_message_handler.cc index 2d994320..f4e6eeb6b 100644 --- a/chrome/browser/ui/webui/sync_internals_message_handler.cc +++ b/chrome/browser/ui/webui/sync_internals_message_handler.cc
@@ -15,13 +15,13 @@ #include "components/browser_sync/browser/profile_sync_service.h" #include "components/signin/core/browser/signin_manager_base.h" #include "components/sync/base/weak_handle.h" +#include "components/sync/driver/about_sync_util.h" +#include "components/sync/driver/sync_service.h" #include "components/sync/engine/events/protocol_event.h" #include "components/sync/js/js_event_details.h" #include "components/sync/sessions/commit_counters.h" #include "components/sync/sessions/status_counters.h" #include "components/sync/sessions/update_counters.h" -#include "components/sync_driver/about_sync_util.h" -#include "components/sync_driver/sync_service.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/web_ui.h"
diff --git a/chrome/browser/ui/webui/sync_internals_message_handler.h b/chrome/browser/ui/webui/sync_internals_message_handler.h index b274e02..2011b9f2 100644 --- a/chrome/browser/ui/webui/sync_internals_message_handler.h +++ b/chrome/browser/ui/webui/sync_internals_message_handler.h
@@ -13,11 +13,11 @@ #include "base/memory/weak_ptr.h" #include "base/scoped_observer.h" #include "base/values.h" +#include "components/sync/driver/protocol_event_observer.h" +#include "components/sync/driver/sync_service_observer.h" #include "components/sync/js/js_controller.h" #include "components/sync/js/js_event_handler.h" #include "components/sync/sessions/type_debug_info_observer.h" -#include "components/sync_driver/protocol_event_observer.h" -#include "components/sync_driver/sync_service_observer.h" #include "content/public/browser/web_ui_message_handler.h" class ProfileSyncService;
diff --git a/chrome/browser/ui/webui/sync_internals_message_handler_unittest.cc b/chrome/browser/ui/webui/sync_internals_message_handler_unittest.cc index 6e848f5..5863b70 100644 --- a/chrome/browser/ui/webui/sync_internals_message_handler_unittest.cc +++ b/chrome/browser/ui/webui/sync_internals_message_handler_unittest.cc
@@ -11,8 +11,8 @@ #include "base/memory/ref_counted.h" #include "chrome/test/base/testing_profile.h" #include "components/browser_sync/common/browser_sync_switches.h" -#include "components/sync_driver/about_sync_util.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/about_sync_util.h" +#include "components/sync/driver/sync_service.h" #include "content/public/browser/site_instance.h" #include "content/public/browser/web_contents.h" #include "content/public/test/test_browser_thread_bundle.h"
diff --git a/chrome/browser/ui/webui/sync_internals_ui.cc b/chrome/browser/ui/webui/sync_internals_ui.cc index 7e41894..70efff90 100644 --- a/chrome/browser/ui/webui/sync_internals_ui.cc +++ b/chrome/browser/ui/webui/sync_internals_ui.cc
@@ -7,7 +7,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/webui/sync_internals_message_handler.h" #include "chrome/common/url_constants.h" -#include "components/sync_driver/about_sync_util.h" +#include "components/sync/driver/about_sync_util.h" #include "content/public/browser/web_ui.h" #include "content/public/browser/web_ui_data_source.h" #include "grit/components_resources.h"
diff --git a/chrome/browser/ui/webui/uber/uber_ui.cc b/chrome/browser/ui/webui/uber/uber_ui.cc index 6f77ecf..fbbbf31 100644 --- a/chrome/browser/ui/webui/uber/uber_ui.cc +++ b/chrome/browser/ui/webui/uber/uber_ui.cc
@@ -72,7 +72,7 @@ iter != extension_set.end(); ++iter) { const extensions::URLOverrides::URLOverrideMap& map = extensions::URLOverrides::GetChromeURLOverrides(iter->get()); - if (ContainsKey(map, extension_type)) + if (base::ContainsKey(map, extension_type)) return true; } @@ -175,7 +175,7 @@ } UberUI::~UberUI() { - STLDeleteValues(&sub_uis_); + base::STLDeleteValues(&sub_uis_); } void UberUI::RegisterSubpage(const std::string& page_url, @@ -185,7 +185,7 @@ } content::WebUI* UberUI::GetSubpage(const std::string& page_url) { - if (!ContainsKey(sub_uis_, page_url)) + if (!base::ContainsKey(sub_uis_, page_url)) return NULL; return sub_uis_[page_url]; }
diff --git a/chrome/browser/ui/webui/version_ui.cc b/chrome/browser/ui/webui/version_ui.cc index 292bcbe2..3ed5fbb 100644 --- a/chrome/browser/ui/webui/version_ui.cc +++ b/chrome/browser/ui/webui/version_ui.cc
@@ -135,9 +135,11 @@ #if defined(__clang__) html_source->AddString("compiler", "clang"); #elif defined(_MSC_VER) && _MSC_VER == 1900 +#if BUILDFLAG(PGO_BUILD) + html_source->AddString("compiler", "MSVC 2015 (PGO)"); +#else html_source->AddString("compiler", "MSVC 2015"); -#elif defined(_MSC_VER) && _MSC_VER == 1800 - html_source->AddString("compiler", "MSVC 2013"); +#endif #elif defined(_MSC_VER) #error "Unsupported version of MSVC." #else
diff --git a/chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc b/chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc index 862f602..3690eaf4 100644 --- a/chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc +++ b/chrome/browser/ui/window_sizer/window_sizer_ash_uitest.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "ash/aura/wm_window_aura.h" #include "ash/common/shelf/shelf_view.h" #include "ash/shelf/shelf.h" #include "ash/shell.h" @@ -53,7 +54,8 @@ } gfx::Rect GetChromeIconBoundsForRootWindow(aura::Window* root_window) { - ash::Shelf* shelf = ash::Shelf::ForWindow(root_window); + ash::Shelf* shelf = + ash::Shelf::ForWindow(ash::WmWindowAura::Get(root_window)); const ash::ShelfView* shelf_view = ash::test::ShelfTestAPI(shelf).shelf_view(); const views::ViewModel* view_model = shelf_view->view_model_for_test();
diff --git a/chrome/browser/usb/usb_chooser_context.cc b/chrome/browser/usb/usb_chooser_context.cc index 44c6884f..53427ca 100644 --- a/chrome/browser/usb/usb_chooser_context.cc +++ b/chrome/browser/usb/usb_chooser_context.cc
@@ -159,7 +159,7 @@ auto it = ephemeral_devices_.find( std::make_pair(requesting_origin, embedding_origin)); if (it != ephemeral_devices_.end() && - ContainsValue(it->second, device->guid())) { + base::ContainsValue(it->second, device->guid())) { return true; }
diff --git a/chrome/browser/usb/web_usb_permission_provider.cc b/chrome/browser/usb/web_usb_permission_provider.cc index 9ed19a49..a6a9bc6 100644 --- a/chrome/browser/usb/web_usb_permission_provider.cc +++ b/chrome/browser/usb/web_usb_permission_provider.cc
@@ -34,18 +34,18 @@ if (!set) return false; - if (ContainsValue(set->origins, origin)) + if (base::ContainsValue(set->origins, origin)) return true; for (const auto& configuration : set->configurations) { if (configuration_value && *configuration_value != configuration.configuration_value) continue; - if (ContainsValue(configuration.origins, origin)) + if (base::ContainsValue(configuration.origins, origin)) return true; for (const auto& function : configuration.functions) { if (first_interface && *first_interface != function.first_interface) continue; - if (ContainsValue(function.origins, origin)) + if (base::ContainsValue(function.origins, origin)) return true; } }
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 51cf1d1a..54cdb8e 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi
@@ -154,6 +154,8 @@ 'browser/component_updater/component_patcher_operation_out_of_process.cc', 'browser/component_updater/component_patcher_operation_out_of_process.h', 'browser/component_updater/component_updater_resource_throttle.cc', + 'browser/component_updater/component_updater_prefs.cc', + 'browser/component_updater/component_updater_prefs.h', 'browser/component_updater/component_updater_resource_throttle.h', 'browser/component_updater/ev_whitelist_component_installer.cc', 'browser/component_updater/ev_whitelist_component_installer.h', @@ -1625,6 +1627,8 @@ 'browser/android/offline_pages/offline_page_mhtml_archiver.h', 'browser/android/offline_pages/offline_page_model_factory.cc', 'browser/android/offline_pages/offline_page_model_factory.h', + 'browser/android/offline_pages/offline_page_request_handler.cc', + 'browser/android/offline_pages/offline_page_request_handler.h', 'browser/android/offline_pages/offline_page_tab_helper.cc', 'browser/android/offline_pages/offline_page_tab_helper.h', 'browser/android/offline_pages/offline_page_utils.cc', @@ -3326,7 +3330,6 @@ '../components/components.gyp:subresource_filter_core_browser', '../components/components.gyp:supervised_user_error_page', '../components/components.gyp:sync_bookmarks', - '../components/components.gyp:sync_driver', '../components/components.gyp:sync_sessions', '../components/components.gyp:translate_core_browser', '../components/components.gyp:translate_core_common',
diff --git a/chrome/chrome_browser_chromeos.gypi b/chrome/chrome_browser_chromeos.gypi index a64ea11f..0924dc93 100644 --- a/chrome/chrome_browser_chromeos.gypi +++ b/chrome/chrome_browser_chromeos.gypi
@@ -824,22 +824,6 @@ 'browser/chromeos/policy/cloud_external_data_store.h', 'browser/chromeos/policy/configuration_policy_handler_chromeos.cc', 'browser/chromeos/policy/configuration_policy_handler_chromeos.h', - 'browser/chromeos/policy/consumer_enrollment_handler.cc', - 'browser/chromeos/policy/consumer_enrollment_handler.h', - 'browser/chromeos/policy/consumer_enrollment_handler_factory.cc', - 'browser/chromeos/policy/consumer_enrollment_handler_factory.h', - 'browser/chromeos/policy/consumer_management_notifier.cc', - 'browser/chromeos/policy/consumer_management_notifier.h', - 'browser/chromeos/policy/consumer_management_notifier_factory.cc', - 'browser/chromeos/policy/consumer_management_notifier_factory.h', - 'browser/chromeos/policy/consumer_management_service.cc', - 'browser/chromeos/policy/consumer_management_service.h', - 'browser/chromeos/policy/consumer_management_stage.cc', - 'browser/chromeos/policy/consumer_management_stage.h', - 'browser/chromeos/policy/consumer_unenrollment_handler.cc', - 'browser/chromeos/policy/consumer_unenrollment_handler.h', - 'browser/chromeos/policy/consumer_unenrollment_handler_factory.cc', - 'browser/chromeos/policy/consumer_unenrollment_handler_factory.h', 'browser/chromeos/policy/device_cloud_policy_initializer.cc', 'browser/chromeos/policy/device_cloud_policy_initializer.h', 'browser/chromeos/policy/device_cloud_policy_manager_chromeos.cc', @@ -870,7 +854,6 @@ 'browser/chromeos/policy/device_status_collector.h', 'browser/chromeos/policy/display_rotation_default_handler.cc', 'browser/chromeos/policy/display_rotation_default_handler.h', - 'browser/chromeos/policy/enrollment_config.cc', 'browser/chromeos/policy/enrollment_config.h', 'browser/chromeos/policy/enrollment_handler_chromeos.cc', 'browser/chromeos/policy/enrollment_handler_chromeos.h',
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index d67a046..a3fb4ba3 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi
@@ -775,6 +775,8 @@ 'browser/ui/app_list/arc/arc_package_syncable_service.h', 'browser/ui/app_list/arc/arc_package_syncable_service_factory.cc', 'browser/ui/app_list/arc/arc_package_syncable_service_factory.h', + 'browser/ui/app_list/arc/arc_package_sync_data_type_controller.cc', + 'browser/ui/app_list/arc/arc_package_sync_data_type_controller.h', 'browser/ui/app_list/search/arc_app_result.cc', 'browser/ui/app_list/search/arc_app_result.h', 'browser/ui/ash/launcher/arc_app_deferred_launcher_controller.cc', @@ -1943,8 +1945,6 @@ 'browser/ui/webui/options/chromeos/bluetooth_options_handler.h', 'browser/ui/webui/options/chromeos/change_picture_options_handler.cc', 'browser/ui/webui/options/chromeos/change_picture_options_handler.h', - 'browser/ui/webui/options/chromeos/consumer_management_handler.cc', - 'browser/ui/webui/options/chromeos/consumer_management_handler.h', 'browser/ui/webui/options/chromeos/core_chromeos_options_handler.cc', 'browser/ui/webui/options/chromeos/core_chromeos_options_handler.h', 'browser/ui/webui/options/chromeos/cros_language_options_handler.cc', @@ -2073,6 +2073,8 @@ 'browser/ui/webui/settings/font_handler.h', 'browser/ui/webui/settings/languages_handler.cc', 'browser/ui/webui/settings/languages_handler.h', + 'browser/ui/webui/settings/metrics_reporting_handler.cc', + 'browser/ui/webui/settings/metrics_reporting_handler.h', 'browser/ui/webui/settings/md_settings_localized_strings_provider.cc', 'browser/ui/webui/settings/md_settings_localized_strings_provider.h', 'browser/ui/webui/settings/md_settings_ui.cc', @@ -2893,7 +2895,6 @@ '../components/components.gyp:onc_component', '../components/components.gyp:password_manager_core_browser', '../components/components.gyp:policy', - '../components/components.gyp:sync_driver', '../components/components.gyp:toolbar', '../components/components.gyp:update_client', '../components/components.gyp:version_ui',
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi index c1c4dae1..1b03a2b 100644 --- a/chrome/chrome_renderer.gypi +++ b/chrome/chrome_renderer.gypi
@@ -211,23 +211,6 @@ 'renderer/safe_browsing/scorer.cc', 'renderer/safe_browsing/scorer.h', ], - 'chrome_renderer_spellchecker_sources': [ - 'renderer/spellchecker/custom_dictionary_engine.cc', - 'renderer/spellchecker/custom_dictionary_engine.h', - 'renderer/spellchecker/hunspell_engine.cc', - 'renderer/spellchecker/hunspell_engine.h', - 'renderer/spellchecker/platform_spelling_engine.cc', - 'renderer/spellchecker/platform_spelling_engine.h', - 'renderer/spellchecker/spellcheck.cc', - 'renderer/spellchecker/spellcheck.h', - 'renderer/spellchecker/spellcheck_language.cc', - 'renderer/spellchecker/spellcheck_language.h', - 'renderer/spellchecker/spellcheck_provider.cc', - 'renderer/spellchecker/spellcheck_provider.h', - 'renderer/spellchecker/spellcheck_worditerator.cc', - 'renderer/spellchecker/spellcheck_worditerator.h', - 'renderer/spellchecker/spelling_engine.h', - ], 'chrome_renderer_printing_sources': [ 'renderer/printing/chrome_print_web_view_helper_delegate.cc', 'renderer/printing/chrome_print_web_view_helper_delegate.h', @@ -357,28 +340,7 @@ ], }], ['enable_spellcheck==1', { - 'sources': [ - '<@(chrome_renderer_spellchecker_sources)', - ], - 'conditions': [ - ['OS!="android"', { - 'dependencies': [ - '../third_party/hunspell/hunspell.gyp:hunspell', - ], - }], - ], - }], - ['use_browser_spellchecker==0', { - 'sources!': [ - 'renderer/spellchecker/platform_spelling_engine.cc', - 'renderer/spellchecker/platform_spelling_engine.h', - ] - }], - ['OS=="android"', { - 'sources!': [ - 'renderer/spellchecker/hunspell_engine.cc', - 'renderer/spellchecker/hunspell_engine.h', - ] + 'dependencies': [ '../components/components.gyp:spellcheck_renderer' ] }], ['enable_basic_printing==1 or enable_print_preview==1', { 'dependencies': [
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index a381b73..abbe8976 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi
@@ -389,14 +389,6 @@ 'browser/spellchecker/spellcheck_service_unittest.cc', 'browser/spellchecker/spelling_service_client_unittest.cc', 'browser/spellchecker/word_trimmer_unittest.cc', - 'renderer/spellchecker/custom_dictionary_engine_unittest.cc', - 'renderer/spellchecker/spellcheck_multilingual_unittest.cc', - 'renderer/spellchecker/spellcheck_provider_hunspell_unittest.cc', - 'renderer/spellchecker/spellcheck_provider_mac_unittest.cc', - 'renderer/spellchecker/spellcheck_provider_test.cc', - 'renderer/spellchecker/spellcheck_provider_test.h', - 'renderer/spellchecker/spellcheck_unittest.cc', - 'renderer/spellchecker/spellcheck_worditerator_unittest.cc', 'tools/convert_dict/convert_dict_unittest.cc', ], 'chrome_unit_tests_background_sources': [ @@ -992,6 +984,7 @@ 'browser/chromeos/extensions/external_cache_unittest.cc', 'browser/chromeos/extensions/file_manager/device_event_router_unittest.cc', 'browser/chromeos/extensions/file_manager/job_event_router_unittest.cc', + 'browser/chromeos/extensions/gfx_utils_unittest.cc', 'browser/chromeos/extensions/quick_unlock_private/quick_unlock_private_api_unittest.cc', 'browser/chromeos/extensions/wallpaper_private_api_unittest.cc', 'browser/chromeos/external_metrics_unittest.cc', @@ -1085,12 +1078,6 @@ 'browser/chromeos/policy/cloud_external_data_policy_observer_unittest.cc', 'browser/chromeos/policy/cloud_external_data_store_unittest.cc', 'browser/chromeos/policy/configuration_policy_handler_chromeos_unittest.cc', - 'browser/chromeos/policy/consumer_enrollment_handler_factory_unittest.cc', - 'browser/chromeos/policy/consumer_enrollment_handler_unittest.cc', - 'browser/chromeos/policy/consumer_management_notifier_factory_unittest.cc', - 'browser/chromeos/policy/consumer_management_notifier_unittest.cc', - 'browser/chromeos/policy/consumer_management_service_unittest.cc', - 'browser/chromeos/policy/consumer_unenrollment_handler_unittest.cc', 'browser/chromeos/policy/device_cloud_policy_initializer_unittest.cc', 'browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc', 'browser/chromeos/policy/device_cloud_policy_store_chromeos_unittest.cc', @@ -1168,6 +1155,7 @@ 'browser/resources/chromeos/braille_ime/braille_ime_unittest.gtestjs', ], 'chrome_unit_tests_desktop_linux_sources': [ + 'browser/ui/input_method/input_method_engine_unittest.cc', 'browser/password_manager/native_backend_kwallet_x_unittest.cc', 'browser/shell_integration_linux_unittest.cc', ], @@ -1410,6 +1398,7 @@ ], 'chrome_unit_tests_win_sources': [ 'app/chrome_dll.rc', + 'browser/ui/input_method/input_method_engine_unittest.cc', 'test/data/resource.rc', ], 'chrome_unit_tests_win_mac_sources': [ @@ -1590,6 +1579,7 @@ 'browser/ui/webui/options/password_manager_handler_unittest.cc', 'browser/ui/webui/options/pepper_flash_content_settings_utils_unittest.cc', 'browser/ui/webui/options/sync_setup_handler_unittest.cc', + 'browser/ui/webui/settings/metrics_reporting_handler_unittest.cc', 'browser/ui/webui/settings/people_handler_unittest.cc', 'browser/ui/webui/settings/profile_info_handler_unittest.cc', 'browser/ui/webui/settings/reset_settings_handler_unittest.cc', @@ -1716,7 +1706,6 @@ '../components/components.gyp:rappor_test_support', '../components/components.gyp:search_engines_test_support', '../components/components.gyp:signin_core_browser_test_support', - '../components/components.gyp:sync_driver_test_support', '../components/components.gyp:sync_sessions_test_support', '../components/components.gyp:syncable_prefs_test_support', '../components/components.gyp:toolbar_test_support', @@ -1732,6 +1721,7 @@ '../sql/sql.gyp:sql', '../sql/sql.gyp:test_support_sql', '../components/sync.gyp:sync', + '../components/sync.gyp:test_support_sync_driver', '../testing/gmock.gyp:gmock', '../testing/gtest.gyp:gtest', '../third_party/zlib/zlib.gyp:zlib', @@ -2022,8 +2012,6 @@ 'browser/chromeos/policy/cloud_external_data_manager_base_test_util.h', 'browser/chromeos/policy/device_policy_builder.cc', 'browser/chromeos/policy/device_policy_builder.h', - 'browser/chromeos/policy/fake_consumer_management_service.cc', - 'browser/chromeos/policy/fake_consumer_management_service.h', 'browser/chromeos/policy/fake_device_cloud_policy_initializer.cc', 'browser/chromeos/policy/fake_device_cloud_policy_initializer.h', 'browser/chromeos/policy/fake_device_cloud_policy_manager.cc', @@ -2403,13 +2391,6 @@ ['OS!="mac" and OS!="ios"', { 'dependencies': [ '../third_party/hunspell/hunspell.gyp:hunspell' ], }], - ['OS=="android"', { - 'sources!': [ - 'renderer/spellchecker/spellcheck_multilingual_unittest.cc', - 'renderer/spellchecker/spellcheck_provider_hunspell_unittest.cc', - 'renderer/spellchecker/spellcheck_unittest.cc', - ], - }] ], }], ['enable_one_click_signin==1', { @@ -2625,8 +2606,6 @@ 'browser/spellchecker/spellcheck_service_unittest.cc', 'browser/ui/tests/ui_gfx_image_unittest.cc', # This tests Chrome's spellchecker which Mac doesn't use. - 'renderer/spellchecker/spellcheck_multilingual_unittest.cc', - 'renderer/spellchecker/spellcheck_provider_hunspell_unittest.cc', 'tools/convert_dict/convert_dict_unittest.cc', ], 'conditions': [
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn index cbb7a7b5..d750bef 100644 --- a/chrome/common/BUILD.gn +++ b/chrome/common/BUILD.gn
@@ -47,6 +47,7 @@ "ENABLE_ONE_CLICK_SIGNIN=$enable_one_click_signin", "ENABLE_PACKAGE_MASH_SERVICES=$enable_package_mash_services", "USE_VULCANIZE=$use_vulcanize", + "PGO_BUILD=$pgo_build", ] }
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index dd6ee356..fcbe47e 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -77,9 +77,10 @@ const base::Feature kMaterialDesignExtensions{ "MaterialDesignExtensions", base::FEATURE_DISABLED_BY_DEFAULT}; #endif -// Enables YouTube Flash videos to be overriden. + +// Enables YouTube Flash videos to be overridden. const base::Feature kOverrideYouTubeFlashEmbed{ - "override-youtube-flash-emed", base::FEATURE_ENABLED_BY_DEFAULT}; + "OverrideYouTubeFlashEmbed", base::FEATURE_ENABLED_BY_DEFAULT}; // Enables or disables the Material Design version of chrome://history. const base::Feature kMaterialDesignHistory{
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 7985e3e..65dd673 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc
@@ -270,9 +270,6 @@ // Disable pop-up blocking. const char kDisablePopupBlocking[] = "disable-popup-blocking"; -// Disable speculative TCP/IP preconnection. -const char kDisablePreconnect[] = "disable-preconnect"; - // Disables print preview (For testing, and for users who don't like us. :[ ) const char kDisablePrintPreview[] = "disable-print-preview"; @@ -326,9 +323,6 @@ const char kDnsLogDetails[] = "dns-log-details"; -// Disables prefetching of DNS information. -const char kDnsPrefetchDisable[] = "dns-prefetch-disable"; - // Requests that a running browser process dump its collected histograms to a // given file. The file is overwritten if it exists. const char kDumpBrowserHistograms[] = "dump-browser-histograms";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 64a2e84..b16fa4a 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h
@@ -87,7 +87,6 @@ extern const char kDisablePermissionActionReporting[]; extern const char kDisablePermissionsBlacklist[]; extern const char kDisablePopupBlocking[]; -extern const char kDisablePreconnect[]; extern const char kDisablePrintPreview[]; extern const char kDisablePromptOnRepost[]; extern const char kDisablePushApiBackgroundMode[]; @@ -102,7 +101,6 @@ extern const char kDiskCacheDir[]; extern const char kDiskCacheSize[]; extern const char kDnsLogDetails[]; -extern const char kDnsPrefetchDisable[]; extern const char kDumpBrowserHistograms[]; extern const char kEasyUnlockAppPath[]; extern const char kEnableAddToShelf[];
diff --git a/chrome/common/component_flash_hint_file_linux.cc b/chrome/common/component_flash_hint_file_linux.cc index f59741d..91c9137 100644 --- a/chrome/common/component_flash_hint_file_linux.cc +++ b/chrome/common/component_flash_hint_file_linux.cc
@@ -133,7 +133,7 @@ return false; std::string hash(crypto::kSHA256Length, 0); - SHA256Hash(mapped_file, string_as_array(&hash), hash.size()); + SHA256Hash(mapped_file, base::string_as_array(&hash), hash.size()); return WriteToDisk(kCurrentHintFileVersion, crypto::SecureHash::Algorithm::SHA256, hash, moved_plugin, @@ -209,7 +209,8 @@ std::vector<uint8_t> file_hash(crypto::kSHA256Length, 0); SHA256Hash(plugin_file, &file_hash[0], file_hash.size()); - if (!crypto::SecureMemEqual(&file_hash[0], string_as_array(&decoded_hash), + if (!crypto::SecureMemEqual(&file_hash[0], + base::string_as_array(&decoded_hash), crypto::kSHA256Length)) { LOG(ERROR) << "The hash recorded in the component flash hint file does not "
diff --git a/chrome/common/extensions/api/tabs.json b/chrome/common/extensions/api/tabs.json index 1f64ec11..e457f47 100644 --- a/chrome/common/extensions/api/tabs.json +++ b/chrome/common/extensions/api/tabs.json
@@ -52,6 +52,7 @@ "pinned": {"type": "boolean", "description": "Whether the tab is pinned."}, "audible": {"type": "boolean", "optional": true, "description": "Whether the tab has produced sound over the past couple of seconds (but it might not be heard if also muted). Equivalent to whether the speaker audio indicator is showing."}, "discarded": {"type": "boolean", "description": "Whether the tab is discarded. A discarded tab is one whose content has been unloaded from memory, but is still visible in the tab strip. Its content gets reloaded the next time it's activated."}, + "autoDiscardable": {"type": "boolean", "description": "Whether the tab can be discarded automatically by the browser when resources are low."}, "mutedInfo": {"$ref": "MutedInfo", "optional": true, "description": "Current tab muted state and the reason for the last state change."}, "url": {"type": "string", "optional": true, "description": "The URL the tab is displaying. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission."}, "title": {"type": "string", "optional": true, "description": "The title of the tab. This property is only present if the extension's manifest includes the <code>\"tabs\"</code> permission."}, @@ -451,7 +452,12 @@ "discarded": { "type": "boolean", "optional": true, - "description": "Whether the tab is discarded. A discarded tab is one whose content has been unloaded from memory, but is still visible in the tab strip. Its content gets reloaded the next time it's activated." + "description": "Whether the tabs are discarded. A discarded tab is one whose content has been unloaded from memory, but is still visible in the tab strip. Its content gets reloaded the next time it's activated." + }, + "autoDiscardable": { + "type": "boolean", + "optional": true, + "description": "Whether the tabs can be discarded automatically by the browser when resources are low." }, "currentWindow": { "type": "boolean", @@ -605,6 +611,11 @@ "minimum": 0, "optional": true, "description": "The ID of the tab that opened this tab. If specified, the opener tab must be in the same window as this tab." + }, + "autoDiscardable": { + "type": "boolean", + "optional": true, + "description": "Whether the tab should be discarded automatically by the browser when resources are low." } } }, @@ -986,6 +997,11 @@ "optional": true, "description": "The tab's new discarded state." }, + "autoDiscardable": { + "type": "boolean", + "optional": true, + "description": "The tab's new auto-discardable state." + }, "mutedInfo": { "$ref": "MutedInfo", "optional": true,
diff --git a/chrome/common/extensions/docs/templates/intros/bluetooth_low_energy.html b/chrome/common/extensions/docs/templates/intros/bluetooth_low_energy.html index eb3d7b5..e6c7150 100644 --- a/chrome/common/extensions/docs/templates/intros/bluetooth_low_energy.html +++ b/chrome/common/extensions/docs/templates/intros/bluetooth_low_energy.html
@@ -1,6 +1,6 @@ <p class="caution"> <b>Important:</b> - This API works <b>only on OS X, Windows and Chrome OS</b>. + This API works only on <b>Chrome OS</b>. </p> <p class="note"> <b>Note:</b>
diff --git a/chrome/common/features.gni b/chrome/common/features.gni index 8bb1fbe..2cafd96 100644 --- a/chrome/common/features.gni +++ b/chrome/common/features.gni
@@ -7,6 +7,7 @@ import("//build/config/chrome_build.gni") import("//build/config/chromecast_build.gni") +import("//build/config/compiler/compiler.gni") # Please keep features in alphabetical order. declare_args() { @@ -41,6 +42,9 @@ # Use vulcanized HTML/CSS/JS resources to speed up WebUI (chrome://) # pages. https://github.com/polymer/vulcanize use_vulcanize = true + + # Indicates if the build is using PGO. + pgo_build = chrome_pgo_phase > 0 } chrome_grit_defines = [
diff --git a/chrome/common/page_load_metrics/page_load_metrics_messages.h b/chrome/common/page_load_metrics/page_load_metrics_messages.h index 1403667..1cc36c9 100644 --- a/chrome/common/page_load_metrics/page_load_metrics_messages.h +++ b/chrome/common/page_load_metrics/page_load_metrics_messages.h
@@ -22,6 +22,7 @@ IPC_STRUCT_TRAITS_MEMBER(first_text_paint) IPC_STRUCT_TRAITS_MEMBER(first_image_paint) IPC_STRUCT_TRAITS_MEMBER(first_contentful_paint) + IPC_STRUCT_TRAITS_MEMBER(first_meaningful_paint) IPC_STRUCT_TRAITS_MEMBER(parse_start) IPC_STRUCT_TRAITS_MEMBER(parse_stop) IPC_STRUCT_TRAITS_MEMBER(parse_blocked_on_script_load_duration)
diff --git a/chrome/common/page_load_metrics/page_load_timing.cc b/chrome/common/page_load_metrics/page_load_timing.cc index 21c3204..d96844881 100644 --- a/chrome/common/page_load_metrics/page_load_timing.cc +++ b/chrome/common/page_load_metrics/page_load_timing.cc
@@ -23,6 +23,7 @@ first_text_paint == other.first_text_paint && first_image_paint == other.first_image_paint && first_contentful_paint == other.first_contentful_paint && + first_meaningful_paint == other.first_meaningful_paint && parse_start == other.parse_start && parse_stop == other.parse_stop && parse_blocked_on_script_load_duration == other.parse_blocked_on_script_load_duration && @@ -34,8 +35,9 @@ return navigation_start.is_null() && !response_start && !dom_content_loaded_event_start && !load_event_start && !first_layout && !first_paint && !first_text_paint && - !first_image_paint && !first_contentful_paint && !parse_start && - !parse_stop && !parse_blocked_on_script_load_duration && + !first_image_paint && !first_contentful_paint && + !first_meaningful_paint && !parse_start && !parse_stop && + !parse_blocked_on_script_load_duration && !parse_blocked_on_script_load_from_document_write_duration; }
diff --git a/chrome/common/page_load_metrics/page_load_timing.h b/chrome/common/page_load_metrics/page_load_timing.h index e41235b..bb67edc 100644 --- a/chrome/common/page_load_metrics/page_load_timing.h +++ b/chrome/common/page_load_metrics/page_load_timing.h
@@ -52,6 +52,8 @@ base::Optional<base::TimeDelta> first_image_paint; // Time when the first contentful thing (image, text, etc.) is painted. base::Optional<base::TimeDelta> first_contentful_paint; + // (Experimental) Time when the page's primary content is painted. + base::Optional<base::TimeDelta> first_meaningful_paint; // Time that the document's parser started and stopped parsing main resource // content.
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index d3a8501a..c5e2281e 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -1275,6 +1275,8 @@ // Define the IP handling policy override that WebRTC should follow. When not // set, it defaults to "default". const char kWebRTCIPHandlingPolicy[] = "webrtc.ip_handling_policy"; +// Define range of UDP ports allowed to be used by WebRTC PeerConnections. +const char kWebRTCUDPPortRange[] = "webrtc.udp_port_range"; #endif // *************** LOCAL STATE *************** @@ -1841,11 +1843,6 @@ // System uptime, when last logout started. // This is saved to file and cleared after chrome process starts. const char kLogoutStartedLast[] = "chromeos.logout-started"; - -// An integer pref of the current consumer management stage. The meaning of the -// value is defined in: -// chrome/browser/chromeos/policy/consumer_management_stage.h -const char kConsumerManagementStage[] = "consumer_management.stage"; #endif // defined(OS_CHROMEOS) // Whether there is a Flash version installed that supports clearing LSO data.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index e013ace..cee6e27c 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -433,6 +433,7 @@ extern const char kWebRTCMultipleRoutesEnabled[]; extern const char kWebRTCNonProxiedUdpEnabled[]; extern const char kWebRTCIPHandlingPolicy[]; +extern const char kWebRTCUDPPortRange[]; #endif extern const char kGLVendorString[];
diff --git a/chrome/common/trace_event_args_whitelist.cc b/chrome/common/trace_event_args_whitelist.cc index 616ec12..3b021a24 100644 --- a/chrome/common/trace_event_args_whitelist.cc +++ b/chrome/common/trace_event_args_whitelist.cc
@@ -23,6 +23,7 @@ const WhitelistEntry kEventArgsWhitelist[] = { {"__metadata", "thread_name", nullptr}, + {"__metadata", "process_name", nullptr}, {"ipc", "SyncChannel::Send", nullptr}, {"toplevel", "*", nullptr}, {"latencyInfo", "*", kInputLatencyAllowedArgs},
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc index 4cde4ae..4bb24261 100644 --- a/chrome/common/url_constants.cc +++ b/chrome/common/url_constants.cc
@@ -429,6 +429,8 @@ "https://support.google.com/chromebook/?p=accessibility_menu"; const char kChromeAccessibilitySettingsURL[] = "/chromevox/background/options.html"; +const char kChromePaletteHelpURL[] = + "https://support.google.com/chromebook?p=stylus_help"; #endif // defined(OS_CHROMEOS) #if BUILDFLAG(ENABLE_ONE_CLICK_SIGNIN)
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h index aea5622..cafdbbd 100644 --- a/chrome/common/url_constants.h +++ b/chrome/common/url_constants.h
@@ -370,6 +370,8 @@ extern const char kChromeAccessibilityHelpURL[]; // Accessibility settings link for Chrome. extern const char kChromeAccessibilitySettingsURL[]; +// Palette help link for Chrome. +extern const char kChromePaletteHelpURL[]; #endif #if BUILDFLAG(ENABLE_ONE_CLICK_SIGNIN)
diff --git a/chrome/common/variations/child_process_field_trial_syncer.cc b/chrome/common/variations/child_process_field_trial_syncer.cc index a0ba9391..d559b1f 100644 --- a/chrome/common/variations/child_process_field_trial_syncer.cc +++ b/chrome/common/variations/child_process_field_trial_syncer.cc
@@ -42,7 +42,7 @@ base::FieldTrial::ActiveGroups current_active_trials; base::FieldTrialList::GetActiveFieldTrialGroups(¤t_active_trials); for (const auto& trial : current_active_trials) { - if (!ContainsKey(initially_active_trials_set, trial.trial_name)) + if (!base::ContainsKey(initially_active_trials_set, trial.trial_name)) observer_->OnFieldTrialGroupFinalized(trial.trial_name, trial.group_name); } }
diff --git a/chrome/common/variations/variations_util.cc b/chrome/common/variations/variations_util.cc index cd5062d6..dc63a29 100644 --- a/chrome/common/variations/variations_util.cc +++ b/chrome/common/variations/variations_util.cc
@@ -92,6 +92,13 @@ base::FieldTrial* trial = base::FieldTrialList::CreateFieldTrial(group.study, group.group_name); + if (!trial) { + DLOG(WARNING) << "Field trial config study skipped: " << group.study + << "." << group.group_name + << " (it is overridden from chrome://flags)"; + continue; + } + for (size_t j = 0; j < group.enable_features_size; ++j) { feature_list->RegisterFieldTrialOverride( group.enable_features[j], base::FeatureList::OVERRIDE_ENABLE_FEATURE,
diff --git a/chrome/installer/mac/app/BUILD.gn b/chrome/installer/mac/app/BUILD.gn index 31101a70..d535005c 100644 --- a/chrome/installer/mac/app/BUILD.gn +++ b/chrome/installer/mac/app/BUILD.gn
@@ -43,20 +43,6 @@ ] } -executable("mac_installer") { - sources = [ - "main.m", - ] - deps = [ - ":mac_installer_base", - ] - - libs = [ - "AppKit.framework", - "CoreFoundation.framework", - ] -} - test("mac_installer_unittests") { sources = [ "testing/OmahaXMLRequest_test.mm",
diff --git a/chrome/installer/mac/app/MainDelegate.h b/chrome/installer/mac/app/MainDelegate.h deleted file mode 100644 index 3b2a03c0..0000000 --- a/chrome/installer/mac/app/MainDelegate.h +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2016 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_INSTALLER_MAC_APP_MAINDELEGATE_H_ -#define CHROME_INSTALLER_MAC_APP_MAINDELEGATE_H_ - -#import <Foundation/Foundation.h> - -#import "Downloader.h" -#import "OmahaCommunication.h" - -@interface MainDelegate - : NSObject<OmahaCommunicationDelegate, DownloaderDelegate> -- (void)runApplication; -@end - -#endif // CHROME_INSTALLER_MAC_APP_MAINDELEGATE_H_
diff --git a/chrome/installer/mac/app/MainDelegate.m b/chrome/installer/mac/app/MainDelegate.m deleted file mode 100644 index 0a9c28da..0000000 --- a/chrome/installer/mac/app/MainDelegate.m +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2016 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 "MainDelegate.h" - -@implementation MainDelegate - -- (void)runApplication { - OmahaCommunication* omahaMessenger = [[OmahaCommunication alloc] init]; - omahaMessenger.delegate = self; - - [omahaMessenger fetchDownloadURLs]; -} - -- (void)onOmahaSuccessWithURLs:(NSArray*)URLs { - Downloader* download = [[Downloader alloc] init]; - download.delegate = self; - - [download downloadChromeImageToDownloadsDirectory:[URLs firstObject]]; -} - -- (void)onOmahaFailureWithError:(NSError*)error { - NSLog(@"error: %@", [error localizedDescription]); - exit(1); -} - -- (void)onDownloadSuccess { - NSLog(@"end of program, exiting."); - NSLog(@"in the ideal world, we would be unpacking now"); - exit(0); -} - -- (void)onDownloadFailureWithError:(NSError*)error { - NSLog(@"error: %@", [error localizedDescription]); - exit(1); -} - -@end
diff --git a/chrome/installer/mac/app/OmahaXMLParser.h b/chrome/installer/mac/app/OmahaXMLParser.h index 687c5dae..0454e1a 100644 --- a/chrome/installer/mac/app/OmahaXMLParser.h +++ b/chrome/installer/mac/app/OmahaXMLParser.h
@@ -9,7 +9,7 @@ @interface OmahaXMLParser : NSObject -// Parses an XML document and extracts all the URL's it finds as well as the +// Parses an XML document and extracts all the URLs found as well as the // filename. Adds each URL into the array chromeIncompleteDownloadURLs_. + (NSArray*)parseXML:(NSData*)omahaResponseXML error:(NSError**)error;
diff --git a/chrome/installer/mac/app/OmahaXMLParser.m b/chrome/installer/mac/app/OmahaXMLParser.m index 016adb500..d1a0a1d 100644 --- a/chrome/installer/mac/app/OmahaXMLParser.m +++ b/chrome/installer/mac/app/OmahaXMLParser.m
@@ -46,7 +46,7 @@ // attribute that indicates a URL follows. Copies each URL into an array. // Note that the URLs in the XML file are incomplete. They need the filename // appended to end. The second if statement checks for the tag "package" which -// contains the filename we need to complete the URLs. +// contains the filename needed to complete the URLs. - (void)parser:(NSXMLParser*)parser didStartElement:(NSString*)elementName namespaceURI:(NSString*)namespaceURI
diff --git a/chrome/installer/mac/app/SystemInfo.h b/chrome/installer/mac/app/SystemInfo.h index 42998b74..4ac9b97 100644 --- a/chrome/installer/mac/app/SystemInfo.h +++ b/chrome/installer/mac/app/SystemInfo.h
@@ -14,10 +14,10 @@ @interface SystemInfo : NSObject // Gets the CPU architecture type of the client's system, which will be used // when crafting the query to Omaha. This will return either "x84_64h" for -// systems running on Intel Haswell chips, "i486" for other Intel machines, -// or strings representing other CPU types ("amd", "pentium", and "i686", for -// example, are all possible; however, due to the above macro, we limit the -// possible return strings to either "x84_64h" or "i486"). +// systems running on Intel Haswell chips, "i486" for other Intel machines, or +// strings representing other CPU types ("amd", "pentium", and "i686", for +// example, are all possible; however, due to the above macro, the possible +// return strings are limited to either "x84_64h" or "i486"). + (NSString*)getArch; // Gets the operating system version of the client. This function may return
diff --git a/chrome/installer/mac/app/testing/requestCheck.dtd b/chrome/installer/mac/app/testing/requestCheck.dtd index 7a8571d6..8df0bc0 100644 --- a/chrome/installer/mac/app/testing/requestCheck.dtd +++ b/chrome/installer/mac/app/testing/requestCheck.dtd
@@ -15,7 +15,7 @@ <!-- Below, this indicates that |protocol| is a required attribute of the - |request| element; by indicating `NMTOKEN`, we indicate that this attribute + |request| element; the presence of `NMTOKEN` indicates that this attribute must have a value associated with it that does not contain whitespace. `CDATA` would be the more commonly used keyword for content with whitespace. -->
diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn index bd82cadc..53cff96e 100644 --- a/chrome/renderer/BUILD.gn +++ b/chrome/renderer/BUILD.gn
@@ -152,19 +152,7 @@ "..") } if (enable_spellcheck) { - sources += - rebase_path(gypi_values.chrome_renderer_spellchecker_sources, ".", "..") - deps += [ "//components/spellcheck/common:common" ] - - if (!is_android) { - deps += [ "//third_party/hunspell" ] - } - } - if (!use_browser_spellchecker) { - sources -= [ - "spellchecker/platform_spelling_engine.cc", - "spellchecker/platform_spelling_engine.h", - ] + deps += [ "//components/spellcheck/renderer:renderer" ] } if (enable_basic_printing || enable_print_preview) { deps += [ "//printing" ] @@ -180,12 +168,6 @@ if (is_win) { deps += [ "//third_party/wtl" ] } - if (is_android) { - sources -= [ - "spellchecker/hunspell_engine.cc", - "spellchecker/hunspell_engine.h", - ] - } if (is_chromeos) { deps += [ "//chrome/renderer/leak_detector:leak_detector" ]
diff --git a/chrome/renderer/DEPS b/chrome/renderer/DEPS index fc80ec98..42c00265 100644 --- a/chrome/renderer/DEPS +++ b/chrome/renderer/DEPS
@@ -28,6 +28,7 @@ "+components/printing/renderer", "+components/signin/core/common", "+components/spellcheck/common", + "+components/spellcheck/renderer", "+components/startup_metric_utils/common", "+components/strings/grit", # For generated headers "+components/subresource_filter/content/renderer",
diff --git a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc index 9b14dc0..25a0b57 100644 --- a/chrome/renderer/autofill/password_autofill_agent_browsertest.cc +++ b/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
@@ -363,11 +363,6 @@ password_element_.setAutofilled(false); } - void SimulateDidEndEditing(WebFrame* input_frame, WebInputElement& input) { - static_cast<blink::WebAutofillClient*>(autofill_agent_) - ->textFieldDidEndEditing(input); - } - void SimulateSuggestionChoice(WebInputElement& username_input) { base::string16 username(base::ASCIIToUTF16(kAliceUsername)); base::string16 password(base::ASCIIToUTF16(kAlicePassword)); @@ -755,8 +750,8 @@ CheckTextFieldsDOMState("alicia", false, kAlicePassword, true); } -// Tests that we only autocomplete on focus lost and with a full username match -// when |wait_for_username| is true. +// Tests that lost focus does not trigger filling when |wait_for_username| is +// true. TEST_F(PasswordAutofillAgentTest, WaitUsername) { // Simulate the browser sending back the login info. fill_data_.wait_for_username = true; @@ -765,32 +760,12 @@ // No auto-fill should have taken place. CheckTextFieldsState(std::string(), false, std::string(), false); + SimulateUsernameChange(kAliceUsername); + // Change focus in between to make sure blur events don't trigger filling. + SetFocused(password_element_); + SetFocused(username_element_); // No autocomplete should happen when text is entered in the username. - SimulateUsernameChange("a"); - CheckTextFieldsState("a", false, std::string(), false); - SimulateUsernameChange("al"); - CheckTextFieldsState("al", false, std::string(), false); - SimulateUsernameChange(kAliceUsername); CheckTextFieldsState(kAliceUsername, false, std::string(), false); - - // Autocomplete should happen only when the username textfield is blurred with - // a full match. - SimulateUsernameChange("a"); - static_cast<blink::WebAutofillClient*>(autofill_agent_) - ->textFieldDidEndEditing(username_element_); - CheckTextFieldsState("a", false, std::string(), false); - SimulateUsernameChange("al"); - static_cast<blink::WebAutofillClient*>(autofill_agent_) - ->textFieldDidEndEditing(username_element_); - CheckTextFieldsState("al", false, std::string(), false); - SimulateUsernameChange("alices"); - static_cast<blink::WebAutofillClient*>(autofill_agent_) - ->textFieldDidEndEditing(username_element_); - CheckTextFieldsState("alices", false, std::string(), false); - SimulateUsernameChange(kAliceUsername); - static_cast<blink::WebAutofillClient*>(autofill_agent_) - ->textFieldDidEndEditing(username_element_); - CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true); } TEST_F(PasswordAutofillAgentTest, IsWebNodeVisibleTest) { @@ -1468,18 +1443,13 @@ } // The user first accepts a suggestion, but then overwrites the password. This -// test checks that the overwritten password is not reverted back if the user -// triggers autofill through focusing (but not changing) the username again. +// test checks that the overwritten password is not reverted back. TEST_F(PasswordAutofillAgentTest, NoopEditingDoesNotOverwriteManuallyEditedPassword) { - // Simulate having credentials which needed to wait until the user starts - // typing the username to be filled (e.g., PSL-matched credentials). Those are - // the ones which can be filled as a result of TextFieldDidEndEditing. fill_data_.wait_for_username = true; - SimulateOnFillPasswordForm(fill_data_); - // Simulate that the user typed their name to make the autofill work. SimulateUsernameChange(kAliceUsername); - SimulateDidEndEditing(GetMainFrame(), username_element_); + SimulateOnFillPasswordForm(fill_data_); + SimulateSuggestionChoice(username_element_); const std::string old_username(username_element_.value().utf8()); const std::string old_password(password_element_.value().utf8()); const std::string new_password(old_password + "modify"); @@ -1487,9 +1457,9 @@ // The user changes the password. SimulatePasswordChange(new_password); - // The user switches back into the username field, but leaves that without - // changes. - SimulateDidEndEditing(GetMainFrame(), username_element_); + // Change focus in between to make sure blur events don't trigger filling. + SetFocused(password_element_); + SetFocused(username_element_); // The password should have stayed as the user changed it. CheckTextFieldsDOMState(old_username, true, new_password, false);
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 98ffc3a..66b4564 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -147,8 +147,8 @@ #endif #if defined(ENABLE_SPELLCHECK) -#include "chrome/renderer/spellchecker/spellcheck.h" -#include "chrome/renderer/spellchecker/spellcheck_provider.h" +#include "components/spellcheck/renderer/spellcheck.h" +#include "components/spellcheck/renderer/spellcheck_provider.h" #endif #if defined(ENABLE_WEBRTC)
diff --git a/chrome/renderer/page_load_metrics/metrics_render_frame_observer.cc b/chrome/renderer/page_load_metrics/metrics_render_frame_observer.cc index ef32d84..2b156854 100644 --- a/chrome/renderer/page_load_metrics/metrics_render_frame_observer.cc +++ b/chrome/renderer/page_load_metrics/metrics_render_frame_observer.cc
@@ -124,9 +124,10 @@ timing.navigation_start = base::Time::FromDoubleT(start); if (perf.responseStart() > 0.0) timing.response_start = ClampDelta(perf.responseStart(), start); - if (perf.domContentLoadedEventStart() > 0.0) + if (perf.domContentLoadedEventStart() > 0.0) { timing.dom_content_loaded_event_start = ClampDelta(perf.domContentLoadedEventStart(), start); + } if (perf.loadEventStart() > 0.0) timing.load_event_start = ClampDelta(perf.loadEventStart(), start); if (perf.firstLayout() > 0.0) @@ -137,9 +138,14 @@ timing.first_text_paint = ClampDelta(perf.firstTextPaint(), start); if (perf.firstImagePaint() > 0.0) timing.first_image_paint = ClampDelta(perf.firstImagePaint(), start); - if (perf.firstContentfulPaint() > 0.0) + if (perf.firstContentfulPaint() > 0.0) { timing.first_contentful_paint = ClampDelta(perf.firstContentfulPaint(), start); + } + if (perf.firstMeaningfulPaint() > 0.0) { + timing.first_meaningful_paint = + ClampDelta(perf.firstMeaningfulPaint(), start); + } if (perf.parseStart() > 0.0) timing.parse_start = ClampDelta(perf.parseStart(), start); if (perf.parseStop() > 0.0)
diff --git a/chrome/renderer/pepper/pepper_uma_host.cc b/chrome/renderer/pepper/pepper_uma_host.cc index 56ef732..4174838 100644 --- a/chrome/renderer/pepper/pepper_uma_host.cc +++ b/chrome/renderer/pepper/pepper_uma_host.cc
@@ -120,12 +120,12 @@ } if (IsPluginWhitelisted() && - ContainsKey(allowed_histogram_prefixes_, HashPrefix(histogram))) { + base::ContainsKey(allowed_histogram_prefixes_, HashPrefix(histogram))) { return true; } - if (ContainsKey(allowed_plugin_base_names_, - plugin_base_name_.MaybeAsASCII())) { + if (base::ContainsKey(allowed_plugin_base_names_, + plugin_base_name_.MaybeAsASCII())) { return true; }
diff --git a/chrome/renderer/resources/extensions/automation/automation_node.js b/chrome/renderer/resources/extensions/automation/automation_node.js index 357f19214..d24c2d6 100644 --- a/chrome/renderer/resources/extensions/automation/automation_node.js +++ b/chrome/renderer/resources/extensions/automation/automation_node.js
@@ -307,18 +307,22 @@ get previousSibling() { var parent = this.parent; + if (!parent) + return undefined; + parent = privates(parent).impl; var indexInParent = GetIndexInParent(this.treeID, this.id); - if (parent && indexInParent > 0) - return parent.children[indexInParent - 1]; - return undefined; + return this.rootImpl.get( + GetChildIDAtIndex(parent.treeID, parent.id, indexInParent - 1)); }, get nextSibling() { var parent = this.parent; + if (!parent) + return undefined; + parent = privates(parent).impl; var indexInParent = GetIndexInParent(this.treeID, this.id); - if (parent && indexInParent < parent.children.length) - return parent.children[indexInParent + 1]; - return undefined; + return this.rootImpl.get( + GetChildIDAtIndex(parent.treeID, parent.id, indexInParent + 1)); }, doDefault: function() {
diff --git a/chrome/renderer/spellchecker/OWNERS b/chrome/renderer/spellchecker/OWNERS deleted file mode 100644 index b7b7d5d..0000000 --- a/chrome/renderer/spellchecker/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -groby@chromium.org -rouslan@chromium.org
diff --git a/chrome/renderer/spellchecker/custom_dictionary_engine.cc b/chrome/renderer/spellchecker/custom_dictionary_engine.cc deleted file mode 100644 index f2bf49d..0000000 --- a/chrome/renderer/spellchecker/custom_dictionary_engine.cc +++ /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. - -#include "chrome/renderer/spellchecker/custom_dictionary_engine.h" - -#include <stddef.h> - -#include "base/strings/utf_string_conversions.h" - -CustomDictionaryEngine::CustomDictionaryEngine() { -} - -CustomDictionaryEngine::~CustomDictionaryEngine() { -} - -void CustomDictionaryEngine::Init(const std::set<std::string>& custom_words) { - dictionary_.clear(); - - // SpellingMenuOberver calls UTF16ToUTF8(word) to convert words for storage, - // synchronization, and use in the custom dictionary engine. Since - // (UTF8ToUTF16(UTF16ToUTF8(word)) == word) holds, the engine does not need to - // normalize the strings. - for (const std::string& word : custom_words) - dictionary_.insert(base::UTF8ToUTF16(word)); -} - -void CustomDictionaryEngine::OnCustomDictionaryChanged( - const std::set<std::string>& words_added, - const std::set<std::string>& words_removed) { - for (const std::string& word : words_added) - dictionary_.insert(base::UTF8ToUTF16(word)); - - for (const std::string& word : words_removed) - dictionary_.erase(base::UTF8ToUTF16(word)); -} - -bool CustomDictionaryEngine::SpellCheckWord( - const base::string16& text, - int misspelling_start, - int misspelling_len) { - // The text to be checked is empty on OSX(async) right now. - // TODO(groby): Fix as part of async hook-up. (http://crbug.com/178241) - return - misspelling_start >= 0 && - misspelling_len > 0 && - size_t(misspelling_start + misspelling_len) <= text.length() && - dictionary_.count(text.substr(misspelling_start, misspelling_len)) > 0; -}
diff --git a/chrome/renderer/spellchecker/custom_dictionary_engine.h b/chrome/renderer/spellchecker/custom_dictionary_engine.h deleted file mode 100644 index be594bb1fa..0000000 --- a/chrome/renderer/spellchecker/custom_dictionary_engine.h +++ /dev/null
@@ -1,43 +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_RENDERER_SPELLCHECKER_CUSTOM_DICTIONARY_ENGINE_H_ -#define CHROME_RENDERER_SPELLCHECKER_CUSTOM_DICTIONARY_ENGINE_H_ - -#include <set> -#include <string> - -#include "base/macros.h" -#include "base/strings/string16.h" - -// Custom spellcheck dictionary. Words in this dictionary are always correctly -// spelled. Words that are not in this dictionary may or may not be correctly -// spelled. -class CustomDictionaryEngine { - public: - CustomDictionaryEngine(); - ~CustomDictionaryEngine(); - - // Initialize the custom dictionary engine. - void Init(const std::set<std::string>& words); - - // Spellcheck |text|. Assumes that another spelling engine has set - // |misspelling_start| and |misspelling_len| to indicate a misspelling. - // Returns true if there are no misspellings, otherwise returns false. - bool SpellCheckWord(const base::string16& text, - int misspelling_start, - int misspelling_len); - - // Update custom dictionary words. - void OnCustomDictionaryChanged(const std::set<std::string>& words_added, - const std::set<std::string>& words_removed); - - private: - // Correctly spelled words. - std::set<base::string16> dictionary_; - - DISALLOW_COPY_AND_ASSIGN(CustomDictionaryEngine); -}; - -#endif // CHROME_RENDERER_SPELLCHECKER_CUSTOM_DICTIONARY_ENGINE_H_
diff --git a/chrome/renderer/spellchecker/custom_dictionary_engine_unittest.cc b/chrome/renderer/spellchecker/custom_dictionary_engine_unittest.cc deleted file mode 100644 index 2e9f61e9..0000000 --- a/chrome/renderer/spellchecker/custom_dictionary_engine_unittest.cc +++ /dev/null
@@ -1,30 +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. - -#include "base/strings/utf_string_conversions.h" -#include "chrome/renderer/spellchecker/custom_dictionary_engine.h" -#include "testing/gtest/include/gtest/gtest.h" - -TEST(CustomDictionaryTest, HandlesEmptyWordWithInvalidSubstring) { - CustomDictionaryEngine engine; - std::set<std::string> custom_words; - engine.Init(custom_words); - EXPECT_FALSE(engine.SpellCheckWord(base::string16().c_str(), 15, 23)); -} - -TEST(CustomDictionaryTest, Basic) { - CustomDictionaryEngine engine; - EXPECT_FALSE(engine.SpellCheckWord(base::ASCIIToUTF16("helllo").c_str(), - 0, 6)); - std::set<std::string> custom_words; - custom_words.insert("helllo"); - engine.Init(custom_words); - EXPECT_TRUE(engine.SpellCheckWord(base::ASCIIToUTF16("helllo").c_str(), - 0, 6)); -} - -TEST(CustomDictionaryTest, HandlesNullCharacters) { - base::char16 data[4] = {'a', 0, 'b', 'c'}; - EXPECT_FALSE(CustomDictionaryEngine().SpellCheckWord(data, 1, 1)); -}
diff --git a/chrome/renderer/spellchecker/hunspell_engine.cc b/chrome/renderer/spellchecker/hunspell_engine.cc deleted file mode 100644 index c528aaff..0000000 --- a/chrome/renderer/spellchecker/hunspell_engine.cc +++ /dev/null
@@ -1,140 +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/renderer/spellchecker/hunspell_engine.h" - -#include <stddef.h> -#include <algorithm> -#include <iterator> -#include <utility> - -#include "base/files/memory_mapped_file.h" -#include "base/time/time.h" -#include "components/spellcheck/common/spellcheck_common.h" -#include "components/spellcheck/common/spellcheck_messages.h" -#include "content/public/renderer/render_thread.h" -#include "third_party/hunspell/src/hunspell/hunspell.hxx" - -using content::RenderThread; - -namespace { - // Maximum length of words we actually check. - // 64 is the observed limits for OSX system checker. - const size_t kMaxCheckedLen = 64; - - // Maximum length of words we provide suggestions for. - // 24 is the observed limits for OSX system checker. - const size_t kMaxSuggestLen = 24; - - static_assert(kMaxCheckedLen <= size_t(MAXWORDLEN), - "MaxCheckedLen too long"); - static_assert(kMaxSuggestLen <= kMaxCheckedLen, - "MaxSuggestLen too long"); -} // namespace - -#if !defined(USE_BROWSER_SPELLCHECKER) -SpellingEngine* CreateNativeSpellingEngine() { - return new HunspellEngine(); -} -#endif - -HunspellEngine::HunspellEngine() - : hunspell_enabled_(false), - initialized_(false), - dictionary_requested_(false) { - // Wait till we check the first word before doing any initializing. -} - -HunspellEngine::~HunspellEngine() { -} - -void HunspellEngine::Init(base::File file) { - initialized_ = true; - hunspell_.reset(); - bdict_file_.reset(); - file_ = std::move(file); - hunspell_enabled_ = file_.IsValid(); - // Delay the actual initialization of hunspell until it is needed. -} - -void HunspellEngine::InitializeHunspell() { - if (hunspell_.get()) - return; - - bdict_file_.reset(new base::MemoryMappedFile); - - if (bdict_file_->Initialize(std::move(file_))) { - hunspell_.reset(new Hunspell(bdict_file_->data(), bdict_file_->length())); - } else { - NOTREACHED() << "Could not mmap spellchecker dictionary."; - } -} - -bool HunspellEngine::CheckSpelling(const base::string16& word_to_check, - int tag) { - // Assume all words that cannot be checked are valid. Since Chrome can't - // offer suggestions on them, either, there's no point in flagging them to - // the user. - bool word_correct = true; - std::string word_to_check_utf8(base::UTF16ToUTF8(word_to_check)); - - // Limit the size of checked words. - if (word_to_check_utf8.length() <= kMaxCheckedLen) { - // If |hunspell_| is NULL here, an error has occurred, but it's better - // to check rather than crash. - if (hunspell_.get()) { - // |hunspell_->spell| returns 0 if the word is misspelled. - word_correct = (hunspell_->spell(word_to_check_utf8.c_str()) != 0); - } - } - - return word_correct; -} - -void HunspellEngine::FillSuggestionList( - const base::string16& wrong_word, - std::vector<base::string16>* optional_suggestions) { - std::string wrong_word_utf8(base::UTF16ToUTF8(wrong_word)); - if (wrong_word_utf8.length() > kMaxSuggestLen) - return; - - // If |hunspell_| is NULL here, an error has occurred, but it's better - // to check rather than crash. - // TODO(groby): Technically, it's not. We should track down the issue. - if (!hunspell_.get()) - return; - - char** suggestions = NULL; - int number_of_suggestions = - hunspell_->suggest(&suggestions, wrong_word_utf8.c_str()); - - // Populate the vector of WideStrings. - for (int i = 0; i < number_of_suggestions; ++i) { - if (i < spellcheck::kMaxSuggestions) - optional_suggestions->push_back(base::UTF8ToUTF16(suggestions[i])); - free(suggestions[i]); - } - if (suggestions != NULL) - free(suggestions); -} - -bool HunspellEngine::InitializeIfNeeded() { - if (!initialized_ && !dictionary_requested_) { - // RenderThread will not exist in test. - if (RenderThread::Get()) - RenderThread::Get()->Send(new SpellCheckHostMsg_RequestDictionary); - dictionary_requested_ = true; - return true; - } - - // Don't initialize if hunspell is disabled. - if (file_.IsValid()) - InitializeHunspell(); - - return !initialized_; -} - -bool HunspellEngine::IsEnabled() { - return hunspell_enabled_; -}
diff --git a/chrome/renderer/spellchecker/hunspell_engine.h b/chrome/renderer/spellchecker/hunspell_engine.h deleted file mode 100644 index 2adde594..0000000 --- a/chrome/renderer/spellchecker/hunspell_engine.h +++ /dev/null
@@ -1,63 +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_RENDERER_SPELLCHECKER_HUNSPELL_ENGINE_H_ -#define CHROME_RENDERER_SPELLCHECKER_HUNSPELL_ENGINE_H_ - -#include <memory> -#include <string> -#include <vector> - -#include "base/strings/string16.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/renderer/spellchecker/spelling_engine.h" -#include "components/spellcheck/common/spellcheck_common.h" - -class Hunspell; - -namespace base { -class MemoryMappedFile; -} - -class HunspellEngine : public SpellingEngine { - public: - HunspellEngine(); - ~HunspellEngine() override; - - void Init(base::File file) override; - - bool InitializeIfNeeded() override; - bool IsEnabled() override; - bool CheckSpelling(const base::string16& word_to_check, int tag) override; - void FillSuggestionList( - const base::string16& wrong_word, - std::vector<base::string16>* optional_suggestions) override; - - private: - // Initializes the Hunspell dictionary, or does nothing if |hunspell_| is - // non-null. This blocks. - void InitializeHunspell(); - - // We memory-map the BDict file. - std::unique_ptr<base::MemoryMappedFile> bdict_file_; - - // The hunspell dictionary in use. - std::unique_ptr<Hunspell> hunspell_; - - base::File file_; - - // This flag is true if hunspell is enabled. - bool hunspell_enabled_; - - // This flag is true if we have been initialized. - // The value indicates whether we should request a - // dictionary from the browser when the render view asks us to check the - // spelling of a word. - bool initialized_; - - // This flag is true if we have requested dictionary. - bool dictionary_requested_; -}; - -#endif // CHROME_RENDERER_SPELLCHECKER_HUNSPELL_ENGINE_H_
diff --git a/chrome/renderer/spellchecker/platform_spelling_engine.cc b/chrome/renderer/spellchecker/platform_spelling_engine.cc deleted file mode 100644 index 97a66aaa6..0000000 --- a/chrome/renderer/spellchecker/platform_spelling_engine.cc +++ /dev/null
@@ -1,47 +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/renderer/spellchecker/platform_spelling_engine.h" - -#include "components/spellcheck/common/spellcheck_messages.h" -#include "content/public/renderer/render_thread.h" - -using content::RenderThread; - -SpellingEngine* CreateNativeSpellingEngine() { - return new PlatformSpellingEngine(); -} - -void PlatformSpellingEngine::Init(base::File bdict_file) { - DCHECK(!bdict_file.IsValid()); -} - -bool PlatformSpellingEngine::InitializeIfNeeded() { - return false; -} - -bool PlatformSpellingEngine::IsEnabled() { - return true; -} - -// Synchronously query against the platform's spellchecker. -// TODO(groby): We might want async support here, too. Ideally, -// all engines share a similar path for async requests. -bool PlatformSpellingEngine::CheckSpelling(const base::string16& word_to_check, - int tag) { - bool word_correct = false; - RenderThread::Get()->Send(new SpellCheckHostMsg_CheckSpelling( - word_to_check, tag, &word_correct)); - return word_correct; -} - -// Synchronously query against the platform's spellchecker. -// TODO(groby): We might want async support here, too. Ideally, -// all engines share a similar path for async requests. -void PlatformSpellingEngine::FillSuggestionList( - const base::string16& wrong_word, - std::vector<base::string16>* optional_suggestions) { - RenderThread::Get()->Send(new SpellCheckHostMsg_FillSuggestionList( - wrong_word, optional_suggestions)); -}
diff --git a/chrome/renderer/spellchecker/platform_spelling_engine.h b/chrome/renderer/spellchecker/platform_spelling_engine.h deleted file mode 100644 index 5cb0b23..0000000 --- a/chrome/renderer/spellchecker/platform_spelling_engine.h +++ /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. - -#ifndef CHROME_RENDERER_SPELLCHECKER_PLATFORM_SPELLING_ENGINE_H_ -#define CHROME_RENDERER_SPELLCHECKER_PLATFORM_SPELLING_ENGINE_H_ - -#include "base/compiler_specific.h" -#include "chrome/renderer/spellchecker/spelling_engine.h" - -class PlatformSpellingEngine : public SpellingEngine { - public: - void Init(base::File bdict_file) override; - bool InitializeIfNeeded() override; - bool IsEnabled() override; - bool CheckSpelling(const base::string16& word_to_check, int tag) override; - void FillSuggestionList( - const base::string16& wrong_word, - std::vector<base::string16>* optional_suggestions) override; -}; - -#endif // CHROME_RENDERER_SPELLCHECKER_PLATFORM_SPELLING_ENGINE_H_ -
diff --git a/chrome/renderer/spellchecker/spellcheck.cc b/chrome/renderer/spellchecker/spellcheck.cc deleted file mode 100644 index d548285..0000000 --- a/chrome/renderer/spellchecker/spellcheck.cc +++ /dev/null
@@ -1,547 +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/renderer/spellchecker/spellcheck.h" - -#include <stddef.h> -#include <stdint.h> -#include <algorithm> -#include <utility> - -#include "base/bind.h" -#include "base/command_line.h" -#include "base/location.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/single_thread_task_runner.h" -#include "base/stl_util.h" -#include "base/threading/thread_task_runner_handle.h" -#include "build/build_config.h" -#include "chrome/common/channel_info.h" -#include "chrome/renderer/spellchecker/spellcheck_language.h" -#include "chrome/renderer/spellchecker/spellcheck_provider.h" -#include "components/spellcheck/common/spellcheck_common.h" -#include "components/spellcheck/common/spellcheck_messages.h" -#include "components/spellcheck/common/spellcheck_result.h" -#include "components/spellcheck/common/spellcheck_switches.h" -#include "content/public/renderer/render_thread.h" -#include "content/public/renderer/render_view.h" -#include "content/public/renderer/render_view_visitor.h" -#include "ipc/ipc_platform_file.h" -#include "third_party/WebKit/public/platform/WebString.h" -#include "third_party/WebKit/public/platform/WebVector.h" -#include "third_party/WebKit/public/web/WebTextCheckingCompletion.h" -#include "third_party/WebKit/public/web/WebTextCheckingResult.h" -#include "third_party/WebKit/public/web/WebTextDecorationType.h" -#include "third_party/WebKit/public/web/WebView.h" - -using blink::WebVector; -using blink::WebString; -using blink::WebTextCheckingResult; -using blink::WebTextDecorationType; - -namespace { -const int kNoOffset = 0; -const int kNoTag = 0; - -class UpdateSpellcheckEnabled : public content::RenderViewVisitor { - public: - explicit UpdateSpellcheckEnabled(bool enabled) : enabled_(enabled) {} - bool Visit(content::RenderView* render_view) override; - - private: - bool enabled_; // New spellcheck-enabled state. - DISALLOW_COPY_AND_ASSIGN(UpdateSpellcheckEnabled); -}; - -bool UpdateSpellcheckEnabled::Visit(content::RenderView* render_view) { - SpellCheckProvider* provider = SpellCheckProvider::Get(render_view); - DCHECK(provider); - provider->EnableSpellcheck(enabled_); - return true; -} - -class DocumentMarkersCollector : public content::RenderViewVisitor { - public: - DocumentMarkersCollector() {} - ~DocumentMarkersCollector() override {} - const std::vector<uint32_t>& markers() const { return markers_; } - bool Visit(content::RenderView* render_view) override; - - private: - std::vector<uint32_t> markers_; - DISALLOW_COPY_AND_ASSIGN(DocumentMarkersCollector); -}; - -bool DocumentMarkersCollector::Visit(content::RenderView* render_view) { - if (!render_view || !render_view->GetWebView()) - return true; - WebVector<uint32_t> markers; - render_view->GetWebView()->spellingMarkers(&markers); - for (size_t i = 0; i < markers.size(); ++i) - markers_.push_back(markers[i]); - // Visit all render views. - return true; -} - -class DocumentMarkersRemover : public content::RenderViewVisitor { - public: - explicit DocumentMarkersRemover(const std::set<std::string>& words); - ~DocumentMarkersRemover() override {} - bool Visit(content::RenderView* render_view) override; - - private: - WebVector<WebString> words_; - DISALLOW_COPY_AND_ASSIGN(DocumentMarkersRemover); -}; - -DocumentMarkersRemover::DocumentMarkersRemover( - const std::set<std::string>& words) - : words_(words.size()) { - std::transform(words.begin(), words.end(), words_.begin(), - [](const std::string& w) { return WebString::fromUTF8(w); }); -} - -bool DocumentMarkersRemover::Visit(content::RenderView* render_view) { - if (render_view && render_view->GetWebView()) - render_view->GetWebView()->removeSpellingMarkersUnderWords(words_); - return true; -} - -bool IsApostrophe(base::char16 c) { - const base::char16 kApostrophe = 0x27; - const base::char16 kRightSingleQuotationMark = 0x2019; - return c == kApostrophe || c == kRightSingleQuotationMark; -} - -// Makes sure that the apostrophes in the |spelling_suggestion| are the same -// type as in the |misspelled_word| and in the same order. Ignore differences in -// the number of apostrophes. -void PreserveOriginalApostropheTypes(const base::string16& misspelled_word, - base::string16* spelling_suggestion) { - auto it = spelling_suggestion->begin(); - for (const base::char16& c : misspelled_word) { - if (IsApostrophe(c)) { - it = std::find_if(it, spelling_suggestion->end(), IsApostrophe); - if (it == spelling_suggestion->end()) - return; - - *it++ = c; - } - } -} - -} // namespace - -class SpellCheck::SpellcheckRequest { - public: - SpellcheckRequest(const base::string16& text, - blink::WebTextCheckingCompletion* completion) - : text_(text), completion_(completion) { - DCHECK(completion); - } - ~SpellcheckRequest() {} - - base::string16 text() { return text_; } - blink::WebTextCheckingCompletion* completion() { return completion_; } - - private: - base::string16 text_; // Text to be checked in this task. - - // The interface to send the misspelled ranges to WebKit. - blink::WebTextCheckingCompletion* completion_; - - DISALLOW_COPY_AND_ASSIGN(SpellcheckRequest); -}; - - -// Initializes SpellCheck object. -// spellcheck_enabled_ currently MUST be set to true, due to peculiarities of -// the initialization sequence. -// Since it defaults to true, newly created SpellCheckProviders will enable -// spellchecking. After the first word is typed, the provider requests a check, -// which in turn triggers the delayed initialization sequence in SpellCheck. -// This does send a message to the browser side, which triggers the creation -// of the SpellcheckService. That does create the observer for the preference -// responsible for enabling/disabling checking, which allows subsequent changes -// to that preference to be sent to all SpellCheckProviders. -// Setting |spellcheck_enabled_| to false by default prevents that mechanism, -// and as such the SpellCheckProviders will never be notified of different -// values. -// TODO(groby): Simplify this. -SpellCheck::SpellCheck() : spellcheck_enabled_(true) {} - -SpellCheck::~SpellCheck() { -} - -void SpellCheck::FillSuggestions( - const std::vector<std::vector<base::string16>>& suggestions_list, - std::vector<base::string16>* optional_suggestions) { - DCHECK(optional_suggestions); - size_t num_languages = suggestions_list.size(); - - // Compute maximum number of suggestions in a single language. - size_t max_suggestions = 0; - for (const auto& suggestions : suggestions_list) - max_suggestions = std::max(max_suggestions, suggestions.size()); - - for (size_t count = 0; count < (max_suggestions * num_languages); ++count) { - size_t language = count % num_languages; - size_t index = count / num_languages; - - if (suggestions_list[language].size() <= index) - continue; - - const base::string16& suggestion = suggestions_list[language][index]; - // Only add the suggestion if it's unique. - if (!ContainsValue(*optional_suggestions, suggestion)) { - optional_suggestions->push_back(suggestion); - } - if (optional_suggestions->size() >= spellcheck::kMaxSuggestions) { - break; - } - } -} - -bool SpellCheck::OnControlMessageReceived(const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(SpellCheck, message) - IPC_MESSAGE_HANDLER(SpellCheckMsg_Init, OnInit) - IPC_MESSAGE_HANDLER(SpellCheckMsg_CustomDictionaryChanged, - OnCustomDictionaryChanged) - IPC_MESSAGE_HANDLER(SpellCheckMsg_EnableSpellCheck, OnEnableSpellCheck) - IPC_MESSAGE_HANDLER(SpellCheckMsg_RequestDocumentMarkers, - OnRequestDocumentMarkers) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - - return handled; -} - -void SpellCheck::OnInit( - const std::vector<SpellCheckBDictLanguage>& bdict_languages, - const std::set<std::string>& custom_words) { - languages_.clear(); - for (const auto& bdict_language : bdict_languages) { - AddSpellcheckLanguage( - IPC::PlatformFileForTransitToFile(bdict_language.file), - bdict_language.language); - } - - custom_dictionary_.Init(custom_words); -#if !defined(USE_BROWSER_SPELLCHECKER) - PostDelayedSpellCheckTask(pending_request_param_.release()); -#endif -} - -void SpellCheck::OnCustomDictionaryChanged( - const std::set<std::string>& words_added, - const std::set<std::string>& words_removed) { - custom_dictionary_.OnCustomDictionaryChanged(words_added, words_removed); - if (words_added.empty()) - return; - DocumentMarkersRemover markersRemover(words_added); - content::RenderView::ForEach(&markersRemover); -} - -void SpellCheck::OnEnableSpellCheck(bool enable) { - spellcheck_enabled_ = enable; - UpdateSpellcheckEnabled updater(enable); - content::RenderView::ForEach(&updater); -} - -void SpellCheck::OnRequestDocumentMarkers() { - DocumentMarkersCollector collector; - content::RenderView::ForEach(&collector); - content::RenderThread::Get()->Send( - new SpellCheckHostMsg_RespondDocumentMarkers(collector.markers())); -} - -// TODO(groby): Make sure we always have a spelling engine, even before -// AddSpellcheckLanguage() is called. -void SpellCheck::AddSpellcheckLanguage(base::File file, - const std::string& language) { - languages_.push_back(new SpellcheckLanguage()); - languages_.back()->Init(std::move(file), language); -} - -bool SpellCheck::SpellCheckWord( - const base::char16* text_begin, - int position_in_text, - int text_length, - int tag, - int* misspelling_start, - int* misspelling_len, - std::vector<base::string16>* optional_suggestions) { - DCHECK(text_length >= position_in_text); - DCHECK(misspelling_start && misspelling_len) << "Out vars must be given."; - - // Do nothing if we need to delay initialization. (Rather than blocking, - // report the word as correctly spelled.) - if (InitializeIfNeeded()) - return true; - - // These are for holding misspelling or skippable word positions and lengths - // between calls to SpellcheckLanguage::SpellCheckWord. - int possible_misspelling_start; - int possible_misspelling_len; - // The longest sequence of text that all languages agree is skippable. - int agreed_skippable_len; - // A vector of vectors containing spelling suggestions from different - // languages. - std::vector<std::vector<base::string16>> suggestions_list; - // A vector to hold a language's misspelling suggestions between spellcheck - // calls. - std::vector<base::string16> language_suggestions; - - // This loop only advances if all languages agree that a sequence of text is - // skippable. - for (; position_in_text <= text_length; - position_in_text += agreed_skippable_len) { - // Reseting |agreed_skippable_len| to the worst-case length each time - // prevents some unnecessary iterations. - agreed_skippable_len = text_length; - *misspelling_start = 0; - *misspelling_len = 0; - suggestions_list.clear(); - - for (ScopedVector<SpellcheckLanguage>::iterator language = - languages_.begin(); - language != languages_.end();) { - language_suggestions.clear(); - SpellcheckLanguage::SpellcheckWordResult result = - (*language)->SpellCheckWord( - text_begin, position_in_text, text_length, tag, - &possible_misspelling_start, &possible_misspelling_len, - optional_suggestions ? &language_suggestions : nullptr); - - switch (result) { - case SpellcheckLanguage::SpellcheckWordResult::IS_CORRECT: - *misspelling_start = 0; - *misspelling_len = 0; - return true; - case SpellcheckLanguage::SpellcheckWordResult::IS_SKIPPABLE: - agreed_skippable_len = - std::min(agreed_skippable_len, possible_misspelling_len); - // If true, this means the spellchecker moved past a word that was - // previously determined to be misspelled or skippable, which means - // another spellcheck language marked it as correct. - if (position_in_text != possible_misspelling_start) { - *misspelling_len = 0; - position_in_text = possible_misspelling_start; - suggestions_list.clear(); - language = languages_.begin(); - } else { - language++; - } - break; - case SpellcheckLanguage::SpellcheckWordResult::IS_MISSPELLED: - *misspelling_start = possible_misspelling_start; - *misspelling_len = possible_misspelling_len; - // If true, this means the spellchecker moved past a word that was - // previously determined to be misspelled or skippable, which means - // another spellcheck language marked it as correct. - if (position_in_text != *misspelling_start) { - suggestions_list.clear(); - language = languages_.begin(); - position_in_text = *misspelling_start; - } else { - suggestions_list.push_back(language_suggestions); - language++; - } - break; - } - } - - // If |*misspelling_len| is non-zero, that means at least one language - // marked a word misspelled and no other language considered it correct. - if (*misspelling_len != 0) { - if (optional_suggestions) - FillSuggestions(suggestions_list, optional_suggestions); - return false; - } - } - - NOTREACHED(); - return true; -} - -bool SpellCheck::SpellCheckParagraph( - const base::string16& text, - WebVector<WebTextCheckingResult>* results) { -#if !defined(USE_BROWSER_SPELLCHECKER) - // Mac and Android have their own spell checkers,so this method won't be used - DCHECK(results); - std::vector<WebTextCheckingResult> textcheck_results; - size_t length = text.length(); - size_t position_in_text = 0; - - // Spellcheck::SpellCheckWord() automatically breaks text into words and - // checks the spellings of the extracted words. This function sets the - // position and length of the first misspelled word and returns false when - // the text includes misspelled words. Therefore, we just repeat calling the - // function until it returns true to check the whole text. - int misspelling_start = 0; - int misspelling_length = 0; - while (position_in_text <= length) { - if (SpellCheckWord(text.c_str(), - position_in_text, - length, - kNoTag, - &misspelling_start, - &misspelling_length, - NULL)) { - results->assign(textcheck_results); - return true; - } - - if (!custom_dictionary_.SpellCheckWord( - text, misspelling_start, misspelling_length)) { - base::string16 replacement; - textcheck_results.push_back(WebTextCheckingResult( - blink::WebTextDecorationTypeSpelling, - misspelling_start, - misspelling_length, - replacement)); - } - position_in_text = misspelling_start + misspelling_length; - } - results->assign(textcheck_results); - return false; -#else - // This function is only invoked for spell checker functionality that runs - // on the render thread. OSX and Android builds don't have that. - NOTREACHED(); - return true; -#endif -} - -// OSX and Android use their own spell checkers -#if !defined(USE_BROWSER_SPELLCHECKER) -void SpellCheck::RequestTextChecking( - const base::string16& text, - blink::WebTextCheckingCompletion* completion) { - // Clean up the previous request before starting a new request. - if (pending_request_param_.get()) - pending_request_param_->completion()->didCancelCheckingText(); - - pending_request_param_.reset(new SpellcheckRequest( - text, completion)); - // We will check this text after we finish loading the hunspell dictionary. - if (InitializeIfNeeded()) - return; - - PostDelayedSpellCheckTask(pending_request_param_.release()); -} -#endif - -bool SpellCheck::InitializeIfNeeded() { - if (languages_.empty()) - return true; - - bool initialize_if_needed = false; - for (SpellcheckLanguage* language : languages_) - initialize_if_needed |= language->InitializeIfNeeded(); - - return initialize_if_needed; -} - -// OSX and Android don't have |pending_request_param_| -#if !defined(USE_BROWSER_SPELLCHECKER) -void SpellCheck::PostDelayedSpellCheckTask(SpellcheckRequest* request) { - if (!request) - return; - - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&SpellCheck::PerformSpellCheck, AsWeakPtr(), - base::Owned(request))); -} -#endif - -// Mac and Android use their platform engines instead. -#if !defined(USE_BROWSER_SPELLCHECKER) -void SpellCheck::PerformSpellCheck(SpellcheckRequest* param) { - DCHECK(param); - - if (languages_.empty() || - std::find_if(languages_.begin(), languages_.end(), - [](SpellcheckLanguage* language) { - return !language->IsEnabled(); - }) != languages_.end()) { - param->completion()->didCancelCheckingText(); - } else { - WebVector<blink::WebTextCheckingResult> results; - SpellCheckParagraph(param->text(), &results); - param->completion()->didFinishCheckingText(results); - } -} -#endif - -void SpellCheck::CreateTextCheckingResults( - ResultFilter filter, - int line_offset, - const base::string16& line_text, - const std::vector<SpellCheckResult>& spellcheck_results, - WebVector<WebTextCheckingResult>* textcheck_results) { - DCHECK(!line_text.empty()); - - std::vector<WebTextCheckingResult> results; - for (const SpellCheckResult& spellcheck_result : spellcheck_results) { - DCHECK_LE(static_cast<size_t>(spellcheck_result.location), - line_text.length()); - DCHECK_LE(static_cast<size_t>(spellcheck_result.location + - spellcheck_result.length), - line_text.length()); - - const base::string16& misspelled_word = - line_text.substr(spellcheck_result.location, spellcheck_result.length); - base::string16 replacement = spellcheck_result.replacement; - SpellCheckResult::Decoration decoration = spellcheck_result.decoration; - - // Ignore words in custom dictionary. - if (custom_dictionary_.SpellCheckWord(misspelled_word, 0, - misspelled_word.length())) { - continue; - } - - // Use the same types of appostrophes as in the mispelled word. - PreserveOriginalApostropheTypes(misspelled_word, &replacement); - - // Ignore misspellings due the typographical apostrophe. - if (misspelled_word == replacement) - continue; - - if (filter == USE_NATIVE_CHECKER) { - // Double-check misspelled words with out spellchecker and attach grammar - // markers to them if our spellchecker tells us they are correct words, - // i.e. they are probably contextually-misspelled words. - int unused_misspelling_start = 0; - int unused_misspelling_length = 0; - if (decoration == SpellCheckResult::SPELLING && - SpellCheckWord(misspelled_word.c_str(), kNoOffset, - misspelled_word.length(), kNoTag, - &unused_misspelling_start, &unused_misspelling_length, - nullptr)) { - decoration = SpellCheckResult::GRAMMAR; - } - } - - results.push_back(WebTextCheckingResult( - static_cast<WebTextDecorationType>(decoration), - line_offset + spellcheck_result.location, spellcheck_result.length, - replacement, spellcheck_result.hash)); - } - - textcheck_results->assign(results); -} - -bool SpellCheck::IsSpellcheckEnabled() { -#if defined(OS_ANDROID) - if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - spellcheck::switches::kEnableAndroidSpellChecker)) { - return false; - } -#endif - return spellcheck_enabled_; -}
diff --git a/chrome/renderer/spellchecker/spellcheck.h b/chrome/renderer/spellchecker/spellcheck.h deleted file mode 100644 index 2b4386e..0000000 --- a/chrome/renderer/spellchecker/spellcheck.h +++ /dev/null
@@ -1,164 +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_RENDERER_SPELLCHECKER_SPELLCHECK_H_ -#define CHROME_RENDERER_SPELLCHECKER_SPELLCHECK_H_ - -#include <memory> -#include <set> -#include <string> -#include <vector> - -#include "base/files/file.h" -#include "base/gtest_prod_util.h" -#include "base/macros.h" -#include "base/memory/scoped_vector.h" -#include "base/memory/weak_ptr.h" -#include "base/strings/string16.h" -#include "chrome/renderer/spellchecker/custom_dictionary_engine.h" -#include "content/public/renderer/render_thread_observer.h" - -struct SpellCheckBDictLanguage; -class SpellcheckLanguage; -struct SpellCheckResult; - -namespace blink { -class WebTextCheckingCompletion; -struct WebTextCheckingResult; -template <typename T> class WebVector; -} - -namespace IPC { -class Message; -} - -// TODO(morrita): Needs reorg with SpellCheckProvider. -// See http://crbug.com/73699. -// Shared spellchecking logic/data for a RenderProcess. All RenderViews use -// this object to perform spellchecking tasks. -class SpellCheck : public content::RenderThreadObserver, - public base::SupportsWeakPtr<SpellCheck> { - public: - // TODO(groby): I wonder if this can be private, non-mac only. - class SpellcheckRequest; - enum ResultFilter { - DO_NOT_MODIFY = 1, // Do not modify results. - USE_NATIVE_CHECKER, // Use native checker to double-check. - }; - - SpellCheck(); - ~SpellCheck() override; - - void AddSpellcheckLanguage(base::File file, const std::string& language); - - // If there are no dictionary files, then this requests them from the browser - // and does not block. In this case it returns true. - // If there are dictionary files, but their Hunspell has not been loaded, then - // this loads their Hunspell. - // If each dictionary file's Hunspell is already loaded, this does nothing. In - // both the latter cases it returns false, meaning that it is OK to continue - // spellchecking. - bool InitializeIfNeeded(); - - // SpellCheck a word. - // Returns true if spelled correctly for any language in |languages_|, false - // otherwise. - // If any spellcheck languages failed to initialize, always returns true. - // The |tag| parameter should either be a unique identifier for the document - // that the word came from (if the current platform requires it), or 0. - // In addition, finds the suggested words for a given word - // and puts them into |*optional_suggestions|. - // If the word is spelled correctly, the vector is empty. - // If optional_suggestions is NULL, suggested words will not be looked up. - // Note that doing suggest lookups can be slow. - bool SpellCheckWord(const base::char16* text_begin, - int position_in_text, - int text_length, - int tag, - int* misspelling_start, - int* misspelling_len, - std::vector<base::string16>* optional_suggestions); - - // SpellCheck a paragraph. - // Returns true if |text| is correctly spelled, false otherwise. - // If the spellchecker failed to initialize, always returns true. - bool SpellCheckParagraph( - const base::string16& text, - blink::WebVector<blink::WebTextCheckingResult>* results); - - // Requests to spellcheck the specified text in the background. This function - // posts a background task and calls SpellCheckParagraph() in the task. -#if !defined (USE_BROWSER_SPELLCHECKER) - void RequestTextChecking(const base::string16& text, - blink::WebTextCheckingCompletion* completion); -#endif - - // Creates a list of WebTextCheckingResult objects (used by WebKit) from a - // list of SpellCheckResult objects (used by Chrome). This function also - // checks misspelled words returned by the Spelling service and changes the - // underline colors of contextually-misspelled words. - void CreateTextCheckingResults( - ResultFilter filter, - int line_offset, - const base::string16& line_text, - const std::vector<SpellCheckResult>& spellcheck_results, - blink::WebVector<blink::WebTextCheckingResult>* textcheck_results); - - bool IsSpellcheckEnabled(); - - private: - friend class SpellCheckTest; - FRIEND_TEST_ALL_PREFIXES(SpellCheckTest, GetAutoCorrectionWord_EN_US); - FRIEND_TEST_ALL_PREFIXES(SpellCheckTest, - RequestSpellCheckMultipleTimesWithoutInitialization); - - // Evenly fill |optional_suggestions| with a maximum of |kMaxSuggestions| - // suggestions from |suggestions_list|. suggestions_list[i][j] is the j-th - // suggestion from the i-th language's suggestions. |optional_suggestions| - // cannot be null. - static void FillSuggestions( - const std::vector<std::vector<base::string16>>& suggestions_list, - std::vector<base::string16>* optional_suggestions); - - // RenderThreadObserver implementation: - bool OnControlMessageReceived(const IPC::Message& message) override; - - // Message handlers. - void OnInit(const std::vector<SpellCheckBDictLanguage>& bdict_languages, - const std::set<std::string>& custom_words); - void OnCustomDictionaryChanged(const std::set<std::string>& words_added, - const std::set<std::string>& words_removed); - void OnEnableSpellCheck(bool enable); - void OnRequestDocumentMarkers(); - -#if !defined (USE_BROWSER_SPELLCHECKER) - // Posts delayed spellcheck task and clear it if any. - // Takes ownership of |request|. - void PostDelayedSpellCheckTask(SpellcheckRequest* request); - - // Performs spell checking from the request queue. - void PerformSpellCheck(SpellcheckRequest* request); - - // The parameters of a pending background-spellchecking request. When WebKit - // sends a background-spellchecking request before initializing hunspell, - // we save its parameters and start spellchecking after we finish initializing - // hunspell. (When WebKit sends two or more requests, we cancel the previous - // requests so we do not have to use vectors.) - std::unique_ptr<SpellcheckRequest> pending_request_param_; -#endif - - // A vector of objects used to actually check spelling, one for each enabled - // language. - ScopedVector<SpellcheckLanguage> languages_; - - // Custom dictionary spelling engine. - CustomDictionaryEngine custom_dictionary_; - - // Remember state for spellchecking. - bool spellcheck_enabled_; - - DISALLOW_COPY_AND_ASSIGN(SpellCheck); -}; - -#endif // CHROME_RENDERER_SPELLCHECKER_SPELLCHECK_H_
diff --git a/chrome/renderer/spellchecker/spellcheck_language.cc b/chrome/renderer/spellchecker/spellcheck_language.cc deleted file mode 100644 index a1dd4ce..0000000 --- a/chrome/renderer/spellchecker/spellcheck_language.cc +++ /dev/null
@@ -1,151 +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/renderer/spellchecker/spellcheck_language.h" - -#include <utility> - -#include "base/logging.h" -#include "chrome/renderer/spellchecker/spellcheck_worditerator.h" -#include "chrome/renderer/spellchecker/spelling_engine.h" - - -SpellcheckLanguage::SpellcheckLanguage() - : platform_spelling_engine_(CreateNativeSpellingEngine()) { -} - -SpellcheckLanguage::~SpellcheckLanguage() { -} - -void SpellcheckLanguage::Init(base::File file, const std::string& language) { - DCHECK(platform_spelling_engine_.get()); - platform_spelling_engine_->Init(std::move(file)); - - character_attributes_.SetDefaultLanguage(language); - text_iterator_.Reset(); - contraction_iterator_.Reset(); -} - -bool SpellcheckLanguage::InitializeIfNeeded() { - DCHECK(platform_spelling_engine_.get()); - return platform_spelling_engine_->InitializeIfNeeded(); -} - -SpellcheckLanguage::SpellcheckWordResult SpellcheckLanguage::SpellCheckWord( - const base::char16* text_begin, - int position_in_text, - int text_length, - int tag, - int* skip_or_misspelling_start, - int* skip_or_misspelling_len, - std::vector<base::string16>* optional_suggestions) { - int remaining_text_len = text_length - position_in_text; - DCHECK(remaining_text_len >= 0); - DCHECK(skip_or_misspelling_start && skip_or_misspelling_len) - << "Out vars must be given."; - - // Do nothing if we need to delay initialization. (Rather than blocking, - // report the word as correctly spelled.) - if (InitializeIfNeeded()) - return IS_CORRECT; - - // Do nothing if spell checking is disabled. - if (!platform_spelling_engine_.get() || - !platform_spelling_engine_->IsEnabled()) - return IS_CORRECT; - - *skip_or_misspelling_start = 0; - *skip_or_misspelling_len = 0; - if (remaining_text_len == 0) - return IS_CORRECT; // No input means always spelled correctly. - - base::string16 word; - int word_start; - int word_length; - if (!text_iterator_.IsInitialized() && - !text_iterator_.Initialize(&character_attributes_, true)) { - // We failed to initialize text_iterator_, return as spelled correctly. - VLOG(1) << "Failed to initialize SpellcheckWordIterator"; - return IS_CORRECT; - } - - text_iterator_.SetText(text_begin + position_in_text, remaining_text_len); - DCHECK(platform_spelling_engine_.get()); - for (SpellcheckWordIterator::WordIteratorStatus status = - text_iterator_.GetNextWord(&word, &word_start, &word_length); - status != SpellcheckWordIterator::IS_END_OF_TEXT; - status = text_iterator_.GetNextWord(&word, &word_start, &word_length)) { - // Found a character that is not able to be spellchecked so determine how - // long the sequence of uncheckable characters is and then return. - if (status == SpellcheckWordIterator::IS_SKIPPABLE) { - *skip_or_misspelling_start = position_in_text + word_start; - while (status == SpellcheckWordIterator::IS_SKIPPABLE) { - *skip_or_misspelling_len += word_length; - status = text_iterator_.GetNextWord(&word, &word_start, &word_length); - } - return IS_SKIPPABLE; - } - - // Found a word (or a contraction) that the spellchecker can check the - // spelling of. - if (platform_spelling_engine_->CheckSpelling(word, tag)) - continue; - - // If the given word is a concatenated word of two or more valid words - // (e.g. "hello:hello"), we should treat it as a valid word. - if (IsValidContraction(word, tag)) - continue; - - *skip_or_misspelling_start = position_in_text + word_start; - *skip_or_misspelling_len = word_length; - - // Get the list of suggested words. - if (optional_suggestions) { - platform_spelling_engine_->FillSuggestionList(word, - optional_suggestions); - } - return IS_MISSPELLED; - } - - return IS_CORRECT; -} - -// Returns whether or not the given string is a valid contraction. -// This function is a fall-back when the SpellcheckWordIterator class -// returns a concatenated word which is not in the selected dictionary -// (e.g. "in'n'out") but each word is valid. -bool SpellcheckLanguage::IsValidContraction(const base::string16& contraction, - int tag) { - if (!contraction_iterator_.IsInitialized() && - !contraction_iterator_.Initialize(&character_attributes_, false)) { - // We failed to initialize the word iterator, return as spelled correctly. - VLOG(1) << "Failed to initialize contraction_iterator_"; - return true; - } - - contraction_iterator_.SetText(contraction.c_str(), contraction.length()); - - base::string16 word; - int word_start; - int word_length; - - DCHECK(platform_spelling_engine_.get()); - for (SpellcheckWordIterator::WordIteratorStatus status = - contraction_iterator_.GetNextWord(&word, &word_start, &word_length); - status != SpellcheckWordIterator::IS_END_OF_TEXT; - status = contraction_iterator_.GetNextWord(&word, &word_start, - &word_length)) { - if (status == SpellcheckWordIterator::IS_SKIPPABLE) - continue; - - if (!platform_spelling_engine_->CheckSpelling(word, tag)) - return false; - } - return true; -} - -bool SpellcheckLanguage::IsEnabled() { - DCHECK(platform_spelling_engine_.get()); - return platform_spelling_engine_->IsEnabled(); -}
diff --git a/chrome/renderer/spellchecker/spellcheck_language.h b/chrome/renderer/spellchecker/spellcheck_language.h deleted file mode 100644 index 14024af4..0000000 --- a/chrome/renderer/spellchecker/spellcheck_language.h +++ /dev/null
@@ -1,99 +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_RENDERER_SPELLCHECKER_SPELLCHECK_LANGUAGE_H_ -#define CHROME_RENDERER_SPELLCHECKER_SPELLCHECK_LANGUAGE_H_ - -#include <memory> -#include <queue> -#include <string> -#include <vector> - -#include "base/files/file.h" -#include "base/macros.h" -#include "base/strings/string16.h" -#include "chrome/renderer/spellchecker/spellcheck_worditerator.h" - -class SpellingEngine; - -class SpellcheckLanguage { - public: - enum SpellcheckWordResult { - // Denotes that every recognized word is spelled correctly, from the point - // of spellchecking to the end of the text. - IS_CORRECT, - // A sequence of skippable characters, such as punctuation, spaces, or - // characters not recognized by the current spellchecking language. - IS_SKIPPABLE, - // A misspelled word has been found in the text. - IS_MISSPELLED - }; - - SpellcheckLanguage(); - ~SpellcheckLanguage(); - - void Init(base::File file, const std::string& language); - - // Spellcheck a sequence of text. - // |text_length| is the length of the text being spellchecked. The |tag| - // parameter should either be a unique identifier for the document that the - // word came from (if the current platform requires it), or 0. - // - // - Returns IS_CORRECT if every word from |position_in_text| to the end of - // the text is recognized and spelled correctly. Also, returns IS_CORRECT if - // the spellchecker failed to initialize. - // - // - Returns IS_SKIPPABLE if a sequence of skippable characters, such as - // punctuation, spaces, or unrecognized characters, is found. - // |skip_or_misspelling_start| and |skip_or_misspelling_len| are then set to - // the position and the length of the sequence of skippable characters. - // - // - Returns IS_MISSPELLED if a misspelled word is found. - // |skip_or_misspelling_start| and |skip_or_misspelling_len| are then set to - // the position and length of the misspelled word. In addition, finds the - // suggested words for a given misspelled word and puts them into - // |*optional_suggestions|. If optional_suggestions is NULL, suggested words - // will not be looked up. Note that doing suggest lookups can be slow. - SpellcheckWordResult SpellCheckWord( - const base::char16* text_begin, - int position_in_text, - int text_length, - int tag, - int* skip_or_misspelling_start, - int* skip_or_misspelling_len, - std::vector<base::string16>* optional_suggestions); - - // Initialize |spellcheck_| if that hasn't happened yet. - bool InitializeIfNeeded(); - - // Return true if the underlying spellcheck engine is enabled. - bool IsEnabled(); - - private: - friend class SpellCheckTest; - - // Returns whether or not the given word is a contraction of valid words - // (e.g. "word:word"). - bool IsValidContraction(const base::string16& word, int tag); - - // Represents character attributes used for filtering out characters which - // are not supported by this SpellCheck object. - SpellcheckCharAttribute character_attributes_; - - // Represents word iterators used in this spellchecker. The |text_iterator_| - // splits text provided by WebKit into words, contractions, or concatenated - // words. The |contraction_iterator_| splits a concatenated word extracted by - // |text_iterator_| into word components so we can treat a concatenated word - // consisting only of correct words as a correct word. - SpellcheckWordIterator text_iterator_; - SpellcheckWordIterator contraction_iterator_; - - // Pointer to a platform-specific spelling engine, if it is in use. This - // should only be set if hunspell is not used. (I.e. on OSX, for now) - std::unique_ptr<SpellingEngine> platform_spelling_engine_; - - DISALLOW_COPY_AND_ASSIGN(SpellcheckLanguage); -}; - -#endif // CHROME_RENDERER_SPELLCHECKER_SPELLCHECK_LANGUAGE_H_
diff --git a/chrome/renderer/spellchecker/spellcheck_multilingual_unittest.cc b/chrome/renderer/spellchecker/spellcheck_multilingual_unittest.cc deleted file mode 100644 index 37eaeba..0000000 --- a/chrome/renderer/spellchecker/spellcheck_multilingual_unittest.cc +++ /dev/null
@@ -1,256 +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. - -#include <stddef.h> - -#include <algorithm> -#include <memory> -#include <utility> - -#include "base/macros.h" -#include "base/path_service.h" -#include "base/strings/string_split.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/renderer/spellchecker/spellcheck.h" -#include "chrome/renderer/spellchecker/spellcheck_provider_test.h" -#include "components/spellcheck/common/spellcheck_common.h" -#include "components/spellcheck/common/spellcheck_result.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/public/platform/WebString.h" -#include "third_party/WebKit/public/platform/WebVector.h" -#include "third_party/WebKit/public/web/WebTextCheckingResult.h" - -namespace { - -struct SpellcheckTestCase { - // A string of text for checking. - const wchar_t* input; - // The position and the length of the first misspelled word, if any. - int expected_misspelling_start; - int expected_misspelling_length; -}; - -base::FilePath GetHunspellDirectory() { - base::FilePath hunspell_directory; - if (!PathService::Get(base::DIR_SOURCE_ROOT, &hunspell_directory)) - return base::FilePath(); - - hunspell_directory = hunspell_directory.AppendASCII("third_party"); - hunspell_directory = hunspell_directory.AppendASCII("hunspell_dictionaries"); - return hunspell_directory; -} - -} // namespace - -class MultilingualSpellCheckTest : public testing::Test { - public: - MultilingualSpellCheckTest() {} - - void ReinitializeSpellCheck(const std::string& unsplit_languages) { - spellcheck_ = new SpellCheck(); - provider_.reset(new TestingSpellCheckProvider(spellcheck_)); - InitializeSpellCheck(unsplit_languages); - } - - void InitializeSpellCheck(const std::string& unsplit_languages) { - base::FilePath hunspell_directory = GetHunspellDirectory(); - EXPECT_FALSE(hunspell_directory.empty()); - std::vector<std::string> languages = base::SplitString( - unsplit_languages, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - - for (const auto& language : languages) { - base::File file( - spellcheck::GetVersionedFileName(language, hunspell_directory), - base::File::FLAG_OPEN | base::File::FLAG_READ); - spellcheck_->AddSpellcheckLanguage(std::move(file), language); - } - } - - ~MultilingualSpellCheckTest() override {} - TestingSpellCheckProvider* provider() { return provider_.get(); } - - protected: - void ExpectSpellCheckWordResults(const std::string& languages, - const SpellcheckTestCase* test_cases, - size_t num_test_cases) { - ReinitializeSpellCheck(languages); - - for (size_t i = 0; i < num_test_cases; ++i) { - int misspelling_start = 0; - int misspelling_length = 0; - static_cast<blink::WebSpellCheckClient*>(provider()) - ->spellCheck(blink::WebString(base::WideToUTF16(test_cases[i].input)), - misspelling_start, misspelling_length, nullptr); - - EXPECT_EQ(test_cases[i].expected_misspelling_start, misspelling_start) - << "Improper misspelling location found with the languages " - << languages << " when checking \"" << test_cases[i].input << "\"."; - EXPECT_EQ(test_cases[i].expected_misspelling_length, misspelling_length) - << "Improper misspelling length found with the languages " - << languages << " when checking \"" << test_cases[i].input << "\"."; - } - } - - void ExpectSpellCheckParagraphResults( - const base::string16& input, - const std::vector<SpellCheckResult>& expected) { - blink::WebVector<blink::WebTextCheckingResult> results; - spellcheck_->SpellCheckParagraph(blink::WebString(input), &results); - - EXPECT_EQ(expected.size(), results.size()); - size_t size = std::min(results.size(), expected.size()); - for (size_t i = 0; i < size; ++i) { - EXPECT_EQ(blink::WebTextDecorationTypeSpelling, results[i].decoration); - EXPECT_EQ(expected[i].location, results[i].location); - EXPECT_EQ(expected[i].length, results[i].length); - } - } - - private: - // Owned by |provider_|. - SpellCheck* spellcheck_; - std::unique_ptr<TestingSpellCheckProvider> provider_; -}; - -// Check that a string of different words is properly spellchecked for different -// combinations of different languages. -TEST_F(MultilingualSpellCheckTest, MultilingualSpellCheckWord) { - static const SpellcheckTestCase kTestCases[] = { - // An English, Spanish, Russian, and Greek word, all spelled correctly. - {L"rocket destruyan \x0432\x0441\x0435\x0445 \x03C4\x03B9\x03C2", 0, 0}, - // A misspelled English word. - {L"rocktt destruyan \x0432\x0441\x0435\x0445 \x03C4\x03B9\x03C2", 0, 6}, - // A misspelled Spanish word. - {L"rocket destruynn \x0432\x0441\x0435\x0445 \x03C4\x03B9\x03C2", 7, 9}, - // A misspelled Russian word. - {L"rocket destruyan \x0430\x0430\x0430\x0430 \x03C4\x03B9\x03C2", 17, 4}, - // A misspelled Greek word. - {L"rocket destruyan \x0432\x0441\x0435\x0445 \x03B1\x03B1\x03B1\x03B1", - 22, 4}, - // An English word, then Russian, and then a misspelled English word. - {L"rocket \x0432\x0441\x0435\x0445 rocktt", 12, 6}, - }; - - // A sorted list of languages. This must start sorted to get all possible - // permutations. - std::string languages = "el-GR,en-US,es-ES,ru-RU"; - std::vector<std::string> permuted_languages = base::SplitString( - languages, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - - do { - languages = base::JoinString(permuted_languages, ","); - ExpectSpellCheckWordResults(languages, kTestCases, arraysize(kTestCases)); - } while (std::next_permutation(permuted_languages.begin(), - permuted_languages.end())); -} - -TEST_F(MultilingualSpellCheckTest, MultilingualSpellCheckWordEnglishSpanish) { - static const SpellcheckTestCase kTestCases[] = { - {L"", 0, 0}, - {L"head hand foot legs arms", 0, 0}, - {L"head hand foot legs arms zzzz", 25, 4}, - {L"head hand zzzz foot legs arms", 10, 4}, - {L"zzzz head hand foot legs arms", 0, 4}, - {L"zzzz head zzzz foot zzzz arms", 0, 4}, - {L"head hand foot arms zzzz zzzz", 20, 4}, - {L"I do not want a monstrous snake near me.", 0, 0}, - {L"zz do not want a monstrous snake near me.", 0, 2}, - {L"I do not want zz monstrous snake near me.", 14, 2}, - {L"I do not want a monstrous zz near me.", 26, 2}, - {L"I do not want a monstrou snake near me.", 16, 8}, - {L"I do not want a monstrous snake near zz.", 37, 2}, - {L"Partially Spanish is very bueno.", 0, 0}, - {L"Sleeping in the biblioteca is good.", 0, 0}, - {L"Hermano is my favorite name.", 0, 0}, - {L"hola hola hola hola hola hola", 0, 0}, - {L"sand hola hola hola hola hola", 0, 0}, - {L"hola sand sand sand sand sand", 0, 0}, - {L"sand sand sand sand sand hola", 0, 0}, - {L"sand hola sand hola sand hola", 0, 0}, - {L"hola sand hola sand hola sand", 0, 0}, - {L"hola:legs", 0, 9}, - {L"legs:hola", 0, 9}}; - ExpectSpellCheckWordResults("en-US,es-ES", kTestCases, arraysize(kTestCases)); -} - -// If there are no spellcheck languages, no text should be marked as misspelled. -TEST_F(MultilingualSpellCheckTest, MultilingualSpellCheckParagraphBlank) { - ReinitializeSpellCheck(std::string()); - - ExpectSpellCheckParagraphResults( - // English, German, Spanish, and a misspelled word. - base::UTF8ToUTF16("rocket Schwarzkommando destruyan pcnyhon"), - std::vector<SpellCheckResult>()); -} - -// Make sure nothing is considered misspelled when at least one of the selected -// languages determines that a word is correctly spelled. -TEST_F(MultilingualSpellCheckTest, MultilingualSpellCheckParagraphCorrect) { - ReinitializeSpellCheck("en-US,es-ES,de-DE"); - - ExpectSpellCheckParagraphResults( - // English, German, and Spanish words, all spelled correctly. - base::UTF8ToUTF16("rocket Schwarzkommando destruyan"), - std::vector<SpellCheckResult>()); -} - -// Make sure that all the misspellings in the text are found. -TEST_F(MultilingualSpellCheckTest, MultilingualSpellCheckParagraph) { - ReinitializeSpellCheck("en-US,es-ES"); - std::vector<SpellCheckResult> expected; - expected.push_back(SpellCheckResult(SpellCheckResult::SPELLING, 7, 15)); - expected.push_back(SpellCheckResult(SpellCheckResult::SPELLING, 33, 7)); - - ExpectSpellCheckParagraphResults( - // English, German, Spanish, and a misspelled word. - base::UTF8ToUTF16("rocket Schwarzkommando destruyan pcnyhon"), expected); -} - -// Ensure that suggestions are handled properly for multiple languages. -TEST_F(MultilingualSpellCheckTest, MultilingualSpellCheckSuggestions) { - ReinitializeSpellCheck("en-US,es-ES"); - static const struct { - // A string of text for checking. - const wchar_t* input; - // The position and the length of the first invalid word. - int expected_misspelling_start; - int expected_misspelling_length; - // A comma separated string of suggested words that should occur, in their - // expected order. - const wchar_t* expected_suggestions; - } kTestCases[] = { - {L"rocket", 0, 0}, - {L"destruyan", 0, 0}, - {L"rocet", 0, 5, L"rocket,roce,crochet,troce,rocen"}, - {L"jum", 0, 3, L"hum,jun,ju,um,juma"}, - {L"asdne", 0, 5, L"sadness,desasne"}, - }; - - for (size_t i = 0; i < arraysize(kTestCases); ++i) { - blink::WebVector<blink::WebString> suggestions; - int misspelling_start; - int misspelling_length; - static_cast<blink::WebSpellCheckClient*>(provider()) - ->spellCheck(blink::WebString(base::WideToUTF16(kTestCases[i].input)), - misspelling_start, misspelling_length, &suggestions); - - EXPECT_EQ(kTestCases[i].expected_misspelling_start, misspelling_start); - EXPECT_EQ(kTestCases[i].expected_misspelling_length, misspelling_length); - if (!kTestCases[i].expected_suggestions) { - EXPECT_EQ(0UL, suggestions.size()); - continue; - } - - std::vector<base::string16> expected_suggestions = base::SplitString( - base::WideToUTF16(kTestCases[i].expected_suggestions), - base::string16(1, ','), base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - - EXPECT_EQ(expected_suggestions.size(), suggestions.size()); - for (size_t j = 0; - j < std::min(expected_suggestions.size(), suggestions.size()); j++) { - EXPECT_EQ(expected_suggestions[j], base::string16(suggestions[j])); - } - } -}
diff --git a/chrome/renderer/spellchecker/spellcheck_provider.cc b/chrome/renderer/spellchecker/spellcheck_provider.cc deleted file mode 100644 index 84ad8e4..0000000 --- a/chrome/renderer/spellchecker/spellcheck_provider.cc +++ /dev/null
@@ -1,351 +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/renderer/spellchecker/spellcheck_provider.h" - -#include "base/command_line.h" -#include "base/metrics/histogram.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/renderer/spellchecker/spellcheck.h" -#include "chrome/renderer/spellchecker/spellcheck_language.h" -#include "components/spellcheck/common/spellcheck_marker.h" -#include "components/spellcheck/common/spellcheck_messages.h" -#include "components/spellcheck/common/spellcheck_result.h" -#include "content/public/renderer/render_view.h" -#include "third_party/WebKit/public/platform/WebVector.h" -#include "third_party/WebKit/public/web/WebDocument.h" -#include "third_party/WebKit/public/web/WebElement.h" -#include "third_party/WebKit/public/web/WebLocalFrame.h" -#include "third_party/WebKit/public/web/WebTextCheckingCompletion.h" -#include "third_party/WebKit/public/web/WebTextCheckingResult.h" -#include "third_party/WebKit/public/web/WebTextDecorationType.h" -#include "third_party/WebKit/public/web/WebView.h" - -using blink::WebElement; -using blink::WebLocalFrame; -using blink::WebString; -using blink::WebTextCheckingCompletion; -using blink::WebTextCheckingResult; -using blink::WebTextDecorationType; -using blink::WebVector; - -static_assert(int(blink::WebTextDecorationTypeSpelling) == - int(SpellCheckResult::SPELLING), "mismatching enums"); -static_assert(int(blink::WebTextDecorationTypeGrammar) == - int(SpellCheckResult::GRAMMAR), "mismatching enums"); -static_assert(int(blink::WebTextDecorationTypeInvisibleSpellcheck) == - int(SpellCheckResult::INVISIBLE), "mismatching enums"); - -SpellCheckProvider::SpellCheckProvider( - content::RenderView* render_view, - SpellCheck* spellcheck) - : content::RenderViewObserver(render_view), - content::RenderViewObserverTracker<SpellCheckProvider>(render_view), - spelling_panel_visible_(false), - spellcheck_(spellcheck) { - DCHECK(spellcheck_); - if (render_view) { // NULL in unit tests. - render_view->GetWebView()->setSpellCheckClient(this); - EnableSpellcheck(spellcheck_->IsSpellcheckEnabled()); - } -} - -SpellCheckProvider::~SpellCheckProvider() { -} - -void SpellCheckProvider::RequestTextChecking( - const base::string16& text, - WebTextCheckingCompletion* completion, - const std::vector<SpellCheckMarker>& markers) { - // Ignore invalid requests. - if (text.empty() || !HasWordCharacters(text, 0)) { - completion->didCancelCheckingText(); - return; - } - - // Try to satisfy check from cache. - if (SatisfyRequestFromCache(text, completion)) - return; - - // Send this text to a browser. A browser checks the user profile and send - // this text to the Spelling service only if a user enables this feature. - last_request_.clear(); - last_results_.assign(blink::WebVector<blink::WebTextCheckingResult>()); - -#if defined(USE_BROWSER_SPELLCHECKER) - // Text check (unified request for grammar and spell check) is only - // available for browser process, so we ask the system spellchecker - // over IPC or return an empty result if the checker is not - // available. - Send(new SpellCheckHostMsg_RequestTextCheck( - routing_id(), - text_check_completions_.Add(completion), - text, - markers)); -#else - Send(new SpellCheckHostMsg_CallSpellingService( - routing_id(), - text_check_completions_.Add(completion), - base::string16(text), - markers)); -#endif // !USE_BROWSER_SPELLCHECKER -} - -bool SpellCheckProvider::OnMessageReceived(const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(SpellCheckProvider, message) -#if !defined(USE_BROWSER_SPELLCHECKER) - IPC_MESSAGE_HANDLER(SpellCheckMsg_RespondSpellingService, - OnRespondSpellingService) -#endif -#if defined(USE_BROWSER_SPELLCHECKER) - IPC_MESSAGE_HANDLER(SpellCheckMsg_AdvanceToNextMisspelling, - OnAdvanceToNextMisspelling) - IPC_MESSAGE_HANDLER(SpellCheckMsg_RespondTextCheck, OnRespondTextCheck) - IPC_MESSAGE_HANDLER(SpellCheckMsg_ToggleSpellPanel, OnToggleSpellPanel) -#endif - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -void SpellCheckProvider::FocusedNodeChanged(const blink::WebNode& unused) { -#if defined(USE_BROWSER_SPELLCHECKER) - WebLocalFrame* frame = render_view()->GetWebView()->focusedFrame(); - WebElement element = frame->document().isNull() ? WebElement() : - frame->document().focusedElement(); - bool enabled = !element.isNull() && element.isEditable(); - bool checked = enabled && frame->isContinuousSpellCheckingEnabled(); - - Send(new SpellCheckHostMsg_ToggleSpellCheck(routing_id(), enabled, checked)); -#endif // USE_BROWSER_SPELLCHECKER -} - -void SpellCheckProvider::spellCheck( - const WebString& text, - int& offset, - int& length, - WebVector<WebString>* optional_suggestions) { - base::string16 word(text); - std::vector<base::string16> suggestions; - const int kWordStart = 0; - spellcheck_->SpellCheckWord( - word.c_str(), kWordStart, word.size(), routing_id(), - &offset, &length, optional_suggestions ? & suggestions : NULL); - if (optional_suggestions) { - *optional_suggestions = suggestions; - UMA_HISTOGRAM_COUNTS("SpellCheck.api.check.suggestions", word.size()); - } else { - UMA_HISTOGRAM_COUNTS("SpellCheck.api.check", word.size()); - // If optional_suggestions is not requested, the API is called - // for marking. So we use this for counting markable words. - Send(new SpellCheckHostMsg_NotifyChecked(routing_id(), word, 0 < length)); - } -} - -void SpellCheckProvider::requestCheckingOfText( - const WebString& text, - const WebVector<uint32_t>& markers, - const WebVector<unsigned>& marker_offsets, - WebTextCheckingCompletion* completion) { - std::vector<SpellCheckMarker> spellcheck_markers; - for (size_t i = 0; i < markers.size(); ++i) { - spellcheck_markers.push_back( - SpellCheckMarker(markers[i], marker_offsets[i])); - } - RequestTextChecking(text, completion, spellcheck_markers); - UMA_HISTOGRAM_COUNTS("SpellCheck.api.async", text.length()); -} - -void SpellCheckProvider::cancelAllPendingRequests() { - for (WebTextCheckCompletions::iterator iter(&text_check_completions_); - !iter.IsAtEnd(); iter.Advance()) { - iter.GetCurrentValue()->didCancelCheckingText(); - } - text_check_completions_.Clear(); -} - -void SpellCheckProvider::showSpellingUI(bool show) { -#if defined(USE_BROWSER_SPELLCHECKER) - UMA_HISTOGRAM_BOOLEAN("SpellCheck.api.showUI", show); - Send(new SpellCheckHostMsg_ShowSpellingPanel(routing_id(), show)); -#endif -} - -bool SpellCheckProvider::isShowingSpellingUI() { - return spelling_panel_visible_; -} - -void SpellCheckProvider::updateSpellingUIWithMisspelledWord( - const WebString& word) { -#if defined(USE_BROWSER_SPELLCHECKER) - Send(new SpellCheckHostMsg_UpdateSpellingPanelWithMisspelledWord(routing_id(), - word)); -#endif -} - -#if !defined(USE_BROWSER_SPELLCHECKER) -void SpellCheckProvider::OnRespondSpellingService( - int identifier, - bool succeeded, - const base::string16& line, - const std::vector<SpellCheckResult>& results) { - WebTextCheckingCompletion* completion = - text_check_completions_.Lookup(identifier); - if (!completion) - return; - text_check_completions_.Remove(identifier); - - // If |succeeded| is false, we use local spellcheck as a fallback. - if (!succeeded) { - spellcheck_->RequestTextChecking(line, completion); - return; - } - - // Double-check the returned spellchecking results with our spellchecker to - // visualize the differences between ours and the on-line spellchecker. - blink::WebVector<blink::WebTextCheckingResult> textcheck_results; - spellcheck_->CreateTextCheckingResults(SpellCheck::USE_NATIVE_CHECKER, - 0, - line, - results, - &textcheck_results); - completion->didFinishCheckingText(textcheck_results); - - // Cache the request and the converted results. - last_request_ = line; - last_results_.swap(textcheck_results); -} -#endif - -bool SpellCheckProvider::HasWordCharacters( - const base::string16& text, - int index) const { - const base::char16* data = text.data(); - int length = text.length(); - while (index < length) { - uint32_t code = 0; - U16_NEXT(data, index, length, code); - UErrorCode error = U_ZERO_ERROR; - if (uscript_getScript(code, &error) != USCRIPT_COMMON) - return true; - } - return false; -} - -#if defined(USE_BROWSER_SPELLCHECKER) -void SpellCheckProvider::OnAdvanceToNextMisspelling() { - if (!render_view()->GetWebView()) - return; - render_view()->GetWebView()->focusedFrame()->executeCommand( - WebString::fromUTF8("AdvanceToNextMisspelling")); -} - -void SpellCheckProvider::OnRespondTextCheck( - int identifier, - const base::string16& line, - const std::vector<SpellCheckResult>& results) { - // TODO(groby): Unify with SpellCheckProvider::OnRespondSpellingService - DCHECK(spellcheck_); - WebTextCheckingCompletion* completion = - text_check_completions_.Lookup(identifier); - if (!completion) - return; - text_check_completions_.Remove(identifier); - blink::WebVector<blink::WebTextCheckingResult> textcheck_results; - spellcheck_->CreateTextCheckingResults(SpellCheck::DO_NOT_MODIFY, - 0, - line, - results, - &textcheck_results); - completion->didFinishCheckingText(textcheck_results); - - // TODO(groby): Add request caching once OSX reports back original request. - // (cf. SpellCheckProvider::OnRespondSpellingService) - // Cache the request and the converted results. -} - -void SpellCheckProvider::OnToggleSpellPanel(bool is_currently_visible) { - if (!render_view()->GetWebView()) - return; - // We need to tell the webView whether the spelling panel is visible or not so - // that it won't need to make ipc calls later. - spelling_panel_visible_ = is_currently_visible; - render_view()->GetWebView()->focusedFrame()->executeCommand( - WebString::fromUTF8("ToggleSpellPanel")); -} -#endif - -void SpellCheckProvider::EnableSpellcheck(bool enable) { - if (!render_view()->GetWebView()) - return; - - WebLocalFrame* frame = render_view()->GetWebView()->focusedFrame(); - // TODO(yabinh): The null check should be unnecessary. - // See crbug.com/625068 - if (!frame) - return; - - frame->enableContinuousSpellChecking(enable); - if (!enable) - frame->removeSpellingMarkers(); -} - -bool SpellCheckProvider::SatisfyRequestFromCache( - const base::string16& text, - WebTextCheckingCompletion* completion) { - size_t last_length = last_request_.length(); - - // Send back the |last_results_| if the |last_request_| is a substring of - // |text| and |text| does not have more words to check. Provider cannot cancel - // the spellcheck request here, because WebKit might have discarded the - // previous spellcheck results and erased the spelling markers in response to - // the user editing the text. - base::string16 request(text); - size_t text_length = request.length(); - if (text_length >= last_length && - !request.compare(0, last_length, last_request_)) { - if (text_length == last_length || !HasWordCharacters(text, last_length)) { - completion->didFinishCheckingText(last_results_); - return true; - } - int code = 0; - int length = static_cast<int>(text_length); - U16_PREV(text.data(), 0, length, code); - UErrorCode error = U_ZERO_ERROR; - if (uscript_getScript(code, &error) != USCRIPT_COMMON) { - completion->didCancelCheckingText(); - return true; - } - } - // Create a subset of the cached results and return it if the given text is a - // substring of the cached text. - if (text_length < last_length && - !last_request_.compare(0, text_length, request)) { - size_t result_size = 0; - for (size_t i = 0; i < last_results_.size(); ++i) { - size_t start = last_results_[i].location; - size_t end = start + last_results_[i].length; - if (start <= text_length && end <= text_length) - ++result_size; - } - if (result_size > 0) { - blink::WebVector<blink::WebTextCheckingResult> results(result_size); - for (size_t i = 0; i < result_size; ++i) { - results[i].decoration = last_results_[i].decoration; - results[i].location = last_results_[i].location; - results[i].length = last_results_[i].length; - results[i].replacement = last_results_[i].replacement; - } - completion->didFinishCheckingText(results); - return true; - } - } - - return false; -} - -void SpellCheckProvider::OnDestruct() { - delete this; -}
diff --git a/chrome/renderer/spellchecker/spellcheck_provider.h b/chrome/renderer/spellchecker/spellcheck_provider.h deleted file mode 100644 index 1a6ddcd..0000000 --- a/chrome/renderer/spellchecker/spellcheck_provider.h +++ /dev/null
@@ -1,134 +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_RENDERER_SPELLCHECKER_SPELLCHECK_PROVIDER_H_ -#define CHROME_RENDERER_SPELLCHECKER_SPELLCHECK_PROVIDER_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <vector> - -#include "base/id_map.h" -#include "base/macros.h" -#include "content/public/renderer/render_view_observer.h" -#include "content/public/renderer/render_view_observer_tracker.h" -#include "third_party/WebKit/public/web/WebSpellCheckClient.h" - -class RenderView; -class SpellCheck; -class SpellCheckMarker; -struct SpellCheckResult; - -namespace blink { -class WebString; -class WebTextCheckingCompletion; -struct WebTextCheckingResult; -} - -// This class deals with invoking browser-side spellcheck mechanism -// which is done asynchronously. -class SpellCheckProvider - : public content::RenderViewObserver, - public content::RenderViewObserverTracker<SpellCheckProvider>, - public blink::WebSpellCheckClient { - public: - typedef IDMap<blink::WebTextCheckingCompletion> WebTextCheckCompletions; - - SpellCheckProvider(content::RenderView* render_view, - SpellCheck* spellcheck); - ~SpellCheckProvider() override; - - // Requests async spell and grammar checker to the platform text - // checker, which is available on the browser process. - void RequestTextChecking( - const base::string16& text, - blink::WebTextCheckingCompletion* completion, - const std::vector<SpellCheckMarker>& markers); - - // The number of ongoing IPC requests. - size_t pending_text_request_size() const { - return text_check_completions_.size(); - } - - // Replace shared spellcheck data. - void set_spellcheck(SpellCheck* spellcheck) { spellcheck_ = spellcheck; } - - // Enables document-wide spellchecking. - void EnableSpellcheck(bool enabled); - - // RenderViewObserver implementation. - bool OnMessageReceived(const IPC::Message& message) override; - void FocusedNodeChanged(const blink::WebNode& node) override; - - private: - friend class TestingSpellCheckProvider; - - // Tries to satisfy a spell check request from the cache in |last_request_|. - // Returns true (and cancels/finishes the completion) if it can, false - // if the provider should forward the query on. - bool SatisfyRequestFromCache(const base::string16& text, - blink::WebTextCheckingCompletion* completion); - - // RenderViewObserver implementation. - void OnDestruct() override; - - // blink::WebSpellCheckClient implementation. - void spellCheck( - const blink::WebString& text, - int& offset, - int& length, - blink::WebVector<blink::WebString>* optional_suggestions) override; - - void requestCheckingOfText( - const blink::WebString& text, - const blink::WebVector<uint32_t>& markers, - const blink::WebVector<unsigned>& marker_offsets, - blink::WebTextCheckingCompletion* completion) override; - - void cancelAllPendingRequests() override; - void showSpellingUI(bool show) override; - bool isShowingSpellingUI() override; - void updateSpellingUIWithMisspelledWord( - const blink::WebString& word) override; - -#if !defined(USE_BROWSER_SPELLCHECKER) - void OnRespondSpellingService( - int identifier, - bool succeeded, - const base::string16& text, - const std::vector<SpellCheckResult>& results); -#endif - - // Returns whether |text| has word characters, i.e. whether a spellchecker - // needs to check this text. - bool HasWordCharacters(const base::string16& text, int index) const; - -#if defined(USE_BROWSER_SPELLCHECKER) - void OnAdvanceToNextMisspelling(); - void OnRespondTextCheck( - int identifier, - const base::string16& line, - const std::vector<SpellCheckResult>& results); - void OnToggleSpellPanel(bool is_currently_visible); -#endif - - // Holds ongoing spellchecking operations, assigns IDs for the IPC routing. - WebTextCheckCompletions text_check_completions_; - - // The last text sent to the browser process to spellcheck it and its - // spellchecking results. - base::string16 last_request_; - blink::WebVector<blink::WebTextCheckingResult> last_results_; - - // True if the browser is showing the spelling panel for us. - bool spelling_panel_visible_; - - // Weak pointer to shared (per RenderView) spellcheck data. - SpellCheck* spellcheck_; - - DISALLOW_COPY_AND_ASSIGN(SpellCheckProvider); -}; - -#endif // CHROME_RENDERER_SPELLCHECKER_SPELLCHECK_PROVIDER_H_
diff --git a/chrome/renderer/spellchecker/spellcheck_provider_hunspell_unittest.cc b/chrome/renderer/spellchecker/spellcheck_provider_hunspell_unittest.cc deleted file mode 100644 index 25f612c..0000000 --- a/chrome/renderer/spellchecker/spellcheck_provider_hunspell_unittest.cc +++ /dev/null
@@ -1,183 +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 <vector> - -#include "base/stl_util.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/renderer/spellchecker/spellcheck_provider_test.h" -#include "components/spellcheck/common/spellcheck_marker.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/public/platform/WebString.h" - -// Tests for Hunspell functionality in SpellcheckingProvider - -using base::ASCIIToUTF16; -using base::WideToUTF16; - -namespace { - -TEST_F(SpellCheckProviderTest, UsingHunspell) { - FakeTextCheckingCompletion completion; - provider_.RequestTextChecking(blink::WebString("hello"), - &completion, - std::vector<SpellCheckMarker>()); - EXPECT_EQ(completion.completion_count_, 1U); - EXPECT_EQ(provider_.messages_.size(), 0U); - EXPECT_EQ(provider_.pending_text_request_size(), 0U); -} - -// Tests that the SpellCheckProvider object sends a spellcheck request when a -// user finishes typing a word. Also this test verifies that this object checks -// only a line being edited by the user. -TEST_F(SpellCheckProviderTest, MultiLineText) { - FakeTextCheckingCompletion completion; - - // Verify that the SpellCheckProvider class does not spellcheck empty text. - provider_.ResetResult(); - provider_.RequestTextChecking( - blink::WebString(), &completion, std::vector<SpellCheckMarker>()); - EXPECT_TRUE(provider_.text_.empty()); - - // Verify that the SpellCheckProvider class does not spellcheck text while we - // are typing a word. - provider_.ResetResult(); - provider_.RequestTextChecking( - blink::WebString("First"), &completion, std::vector<SpellCheckMarker>()); - EXPECT_TRUE(provider_.text_.empty()); - - // Verify that the SpellCheckProvider class spellcheck the first word when we - // type a space key, i.e. when we finish typing a word. - provider_.ResetResult(); - provider_.RequestTextChecking(blink::WebString("First "), - &completion, - std::vector<SpellCheckMarker>()); - EXPECT_EQ(ASCIIToUTF16("First "), provider_.text_); - - // Verify that the SpellCheckProvider class spellcheck the first line when we - // type a return key, i.e. when we finish typing a line. - provider_.ResetResult(); - provider_.RequestTextChecking(blink::WebString("First Second\n"), - &completion, - std::vector<SpellCheckMarker>()); - EXPECT_EQ(ASCIIToUTF16("First Second\n"), provider_.text_); - - // Verify that the SpellCheckProvider class spellcheck the lines when we - // finish typing a word "Third" to the second line. - provider_.ResetResult(); - provider_.RequestTextChecking(blink::WebString("First Second\nThird "), - &completion, - std::vector<SpellCheckMarker>()); - EXPECT_EQ(ASCIIToUTF16("First Second\nThird "), provider_.text_); - - // Verify that the SpellCheckProvider class does not send a spellcheck request - // when a user inserts whitespace characters. - provider_.ResetResult(); - provider_.RequestTextChecking(blink::WebString("First Second\nThird "), - &completion, - std::vector<SpellCheckMarker>()); - EXPECT_TRUE(provider_.text_.empty()); - - // Verify that the SpellCheckProvider class spellcheck the lines when we type - // a period. - provider_.ResetResult(); - provider_.RequestTextChecking( - blink::WebString("First Second\nThird Fourth."), - &completion, - std::vector<SpellCheckMarker>()); - EXPECT_EQ(ASCIIToUTF16("First Second\nThird Fourth."), provider_.text_); -} - -// Tests that the SpellCheckProvider class does not send requests to the -// spelling service when not necessary. -TEST_F(SpellCheckProviderTest, CancelUnnecessaryRequests) { - FakeTextCheckingCompletion completion; - provider_.RequestTextChecking(blink::WebString("hello."), - &completion, - std::vector<SpellCheckMarker>()); - EXPECT_EQ(completion.completion_count_, 1U); - EXPECT_EQ(completion.cancellation_count_, 0U); - EXPECT_EQ(provider_.spelling_service_call_count_, 1U); - - // Test that the SpellCheckProvider does not send a request with the same text - // as above. - provider_.RequestTextChecking(blink::WebString("hello."), - &completion, - std::vector<SpellCheckMarker>()); - EXPECT_EQ(completion.completion_count_, 2U); - EXPECT_EQ(completion.cancellation_count_, 0U); - EXPECT_EQ(provider_.spelling_service_call_count_, 1U); - - // Test that the SpellCheckProvider class cancels an incoming request that - // does not include any words. - provider_.RequestTextChecking(blink::WebString(":-)"), - &completion, - std::vector<SpellCheckMarker>()); - EXPECT_EQ(completion.completion_count_, 3U); - EXPECT_EQ(completion.cancellation_count_, 1U); - EXPECT_EQ(provider_.spelling_service_call_count_, 1U); - - // Test that the SpellCheckProvider class sends a request when it receives a - // Russian word. - const wchar_t kRussianWord[] = L"\x0431\x0451\x0434\x0440\x0430"; - provider_.RequestTextChecking(blink::WebString(WideToUTF16(kRussianWord)), - &completion, - std::vector<SpellCheckMarker>()); - EXPECT_EQ(completion.completion_count_, 4U); - EXPECT_EQ(completion.cancellation_count_, 1U); - EXPECT_EQ(provider_.spelling_service_call_count_, 2U); -} - -// Tests that the SpellCheckProvider calls didFinishCheckingText() when -// necessary. -TEST_F(SpellCheckProviderTest, CompleteNecessaryRequests) { - FakeTextCheckingCompletion completion; - - base::string16 text = ASCIIToUTF16("Icland is an icland "); - provider_.RequestTextChecking( - blink::WebString(text), &completion, std::vector<SpellCheckMarker>()); - EXPECT_EQ(0U, completion.cancellation_count_) << "Should finish checking \"" - << text << "\""; - - const int kSubstringLength = 18; - base::string16 substring = text.substr(0, kSubstringLength); - provider_.RequestTextChecking(blink::WebString(substring), - &completion, - std::vector<SpellCheckMarker>()); - EXPECT_EQ(0U, completion.cancellation_count_) << "Should finish checking \"" - << substring << "\""; - - provider_.RequestTextChecking( - blink::WebString(text), &completion, std::vector<SpellCheckMarker>()); - EXPECT_EQ(0U, completion.cancellation_count_) << "Should finish checking \"" - << text << "\""; -} - -// Tests that the SpellCheckProvider cancels spelling requests in the middle of -// a word. -TEST_F(SpellCheckProviderTest, CancelMidWordRequests) { - FakeTextCheckingCompletion completion; - provider_.RequestTextChecking(blink::WebString("hello "), - &completion, - std::vector<SpellCheckMarker>()); - EXPECT_EQ(completion.completion_count_, 1U); - EXPECT_EQ(completion.cancellation_count_, 0U); - EXPECT_EQ(provider_.spelling_service_call_count_, 1U); - - provider_.RequestTextChecking(blink::WebString("hello world"), - &completion, - std::vector<SpellCheckMarker>()); - EXPECT_EQ(completion.completion_count_, 2U); - EXPECT_EQ(completion.cancellation_count_, 1U); - EXPECT_EQ(provider_.spelling_service_call_count_, 1U); - - provider_.RequestTextChecking(blink::WebString("hello world."), - &completion, - std::vector<SpellCheckMarker>()); - EXPECT_EQ(completion.completion_count_, 3U); - EXPECT_EQ(completion.cancellation_count_, 1U); - EXPECT_EQ(provider_.spelling_service_call_count_, 2U); -} - -} // namespace
diff --git a/chrome/renderer/spellchecker/spellcheck_provider_mac_unittest.cc b/chrome/renderer/spellchecker/spellcheck_provider_mac_unittest.cc deleted file mode 100644 index c280602b..0000000 --- a/chrome/renderer/spellchecker/spellcheck_provider_mac_unittest.cc +++ /dev/null
@@ -1,92 +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 <tuple> -#include <vector> - -#include "base/strings/utf_string_conversions.h" -#include "chrome/renderer/spellchecker/spellcheck_provider_test.h" -#include "components/spellcheck/common/spellcheck_marker.h" -#include "components/spellcheck/common/spellcheck_messages.h" -#include "components/spellcheck/common/spellcheck_result.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/public/platform/WebString.h" - -namespace { - -class SpellCheckProviderMacTest : public SpellCheckProviderTest {}; - -void FakeMessageArrival( - SpellCheckProvider* provider, - const SpellCheckHostMsg_RequestTextCheck::Param& parameters) { - std::vector<SpellCheckResult> fake_result; - bool handled = provider->OnMessageReceived( - SpellCheckMsg_RespondTextCheck( - 0, - std::get<1>(parameters), - base::ASCIIToUTF16("test"), - fake_result)); - EXPECT_TRUE(handled); -} - -TEST_F(SpellCheckProviderMacTest, SingleRoundtripSuccess) { - FakeTextCheckingCompletion completion; - - provider_.RequestTextChecking(blink::WebString("hello "), - &completion, - std::vector<SpellCheckMarker>()); - EXPECT_EQ(completion.completion_count_, 0U); - EXPECT_EQ(provider_.messages_.size(), 1U); - EXPECT_EQ(provider_.pending_text_request_size(), 1U); - - SpellCheckHostMsg_RequestTextCheck::Param read_parameters1; - bool ok = SpellCheckHostMsg_RequestTextCheck::Read( - provider_.messages_[0], &read_parameters1); - EXPECT_TRUE(ok); - EXPECT_EQ(std::get<2>(read_parameters1), base::UTF8ToUTF16("hello ")); - - FakeMessageArrival(&provider_, read_parameters1); - EXPECT_EQ(completion.completion_count_, 1U); - EXPECT_EQ(provider_.pending_text_request_size(), 0U); -} - -TEST_F(SpellCheckProviderMacTest, TwoRoundtripSuccess) { - FakeTextCheckingCompletion completion1; - provider_.RequestTextChecking(blink::WebString("hello "), - &completion1, - std::vector<SpellCheckMarker>()); - FakeTextCheckingCompletion completion2; - provider_.RequestTextChecking(blink::WebString("bye "), - &completion2, - std::vector<SpellCheckMarker>()); - - EXPECT_EQ(completion1.completion_count_, 0U); - EXPECT_EQ(completion2.completion_count_, 0U); - EXPECT_EQ(provider_.messages_.size(), 2U); - EXPECT_EQ(provider_.pending_text_request_size(), 2U); - - SpellCheckHostMsg_RequestTextCheck::Param read_parameters1; - bool ok = SpellCheckHostMsg_RequestTextCheck::Read( - provider_.messages_[0], &read_parameters1); - EXPECT_TRUE(ok); - EXPECT_EQ(std::get<2>(read_parameters1), base::UTF8ToUTF16("hello ")); - - SpellCheckHostMsg_RequestTextCheck::Param read_parameters2; - ok = SpellCheckHostMsg_RequestTextCheck::Read( - provider_.messages_[1], &read_parameters2); - EXPECT_TRUE(ok); - EXPECT_EQ(std::get<2>(read_parameters2), base::UTF8ToUTF16("bye ")); - - FakeMessageArrival(&provider_, read_parameters1); - EXPECT_EQ(completion1.completion_count_, 1U); - EXPECT_EQ(completion2.completion_count_, 0U); - EXPECT_EQ(provider_.pending_text_request_size(), 1U); - - FakeMessageArrival(&provider_, read_parameters2); - EXPECT_EQ(completion1.completion_count_, 1U); - EXPECT_EQ(completion2.completion_count_, 1U); - EXPECT_EQ(provider_.pending_text_request_size(), 0U); -} - -} // namespace
diff --git a/chrome/renderer/spellchecker/spellcheck_provider_test.cc b/chrome/renderer/spellchecker/spellcheck_provider_test.cc deleted file mode 100644 index 26f8505..0000000 --- a/chrome/renderer/spellchecker/spellcheck_provider_test.cc +++ /dev/null
@@ -1,101 +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/renderer/spellchecker/spellcheck_provider_test.h" - -#include "base/stl_util.h" -#include "chrome/renderer/spellchecker/spellcheck.h" -#include "components/spellcheck/common/spellcheck_marker.h" -#include "components/spellcheck/common/spellcheck_messages.h" -#include "ipc/ipc_message_macros.h" - -class MockSpellcheck: public SpellCheck { -}; - -FakeTextCheckingCompletion::FakeTextCheckingCompletion() -: completion_count_(0), - cancellation_count_(0) { -} - -FakeTextCheckingCompletion::~FakeTextCheckingCompletion() {} - -void FakeTextCheckingCompletion::didFinishCheckingText( - const blink::WebVector<blink::WebTextCheckingResult>& results) { - ++completion_count_; -} - -void FakeTextCheckingCompletion::didCancelCheckingText() { - ++completion_count_; - ++cancellation_count_; -} - -TestingSpellCheckProvider::TestingSpellCheckProvider() - : SpellCheckProvider(NULL, new MockSpellcheck), - spelling_service_call_count_(0) { -} - -TestingSpellCheckProvider::TestingSpellCheckProvider( - SpellCheck* spellcheck) - : SpellCheckProvider(nullptr, spellcheck), - spelling_service_call_count_(0) { -} - -TestingSpellCheckProvider::~TestingSpellCheckProvider() { - delete spellcheck_; -} - -bool TestingSpellCheckProvider::Send(IPC::Message* message) { -#if !defined(USE_BROWSER_SPELLCHECKER) - // Call our mock message handlers. - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(TestingSpellCheckProvider, *message) - IPC_MESSAGE_HANDLER(SpellCheckHostMsg_CallSpellingService, - OnCallSpellingService) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - - if (handled) { - delete message; - return true; - } -#endif - - messages_.push_back(message); - return true; -} - -void TestingSpellCheckProvider::OnCallSpellingService(int route_id, - int identifier, - const base::string16& text, - const std::vector<SpellCheckMarker>& markers) { -#if defined (USE_BROWSER_SPELLCHECKER) - NOTREACHED(); -#else - ++spelling_service_call_count_; - blink::WebTextCheckingCompletion* completion = - text_check_completions_.Lookup(identifier); - if (!completion) { - ResetResult(); - return; - } - text_.assign(text); - text_check_completions_.Remove(identifier); - std::vector<blink::WebTextCheckingResult> results; - results.push_back(blink::WebTextCheckingResult( - blink::WebTextDecorationTypeSpelling, - 0, 5, blink::WebString("hello"))); - completion->didFinishCheckingText(results); - last_request_ = text; - last_results_ = results; -#endif -} - -void TestingSpellCheckProvider::ResetResult() { - text_.clear(); -} - -SpellCheckProviderTest::SpellCheckProviderTest() {} -SpellCheckProviderTest::~SpellCheckProviderTest() {} - -
diff --git a/chrome/renderer/spellchecker/spellcheck_provider_test.h b/chrome/renderer/spellchecker/spellcheck_provider_test.h deleted file mode 100644 index 07630e4..0000000 --- a/chrome/renderer/spellchecker/spellcheck_provider_test.h +++ /dev/null
@@ -1,68 +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_RENDERER_SPELLCHECKER_SPELLCHECK_PROVIDER_TEST_H_ -#define CHROME_RENDERER_SPELLCHECKER_SPELLCHECK_PROVIDER_TEST_H_ - -#include <stddef.h> - -#include <vector> - -#include "base/memory/scoped_vector.h" -#include "base/strings/string16.h" -#include "chrome/renderer/spellchecker/spellcheck_provider.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/public/platform/WebVector.h" -#include "third_party/WebKit/public/web/WebTextCheckingCompletion.h" -#include "third_party/WebKit/public/web/WebTextCheckingResult.h" - -namespace IPC { - class Message; -} - -// A fake completion object for verification. -class FakeTextCheckingCompletion : public blink::WebTextCheckingCompletion { - public: - FakeTextCheckingCompletion(); - ~FakeTextCheckingCompletion(); - - void didFinishCheckingText( - const blink::WebVector<blink::WebTextCheckingResult>& results) override; - void didCancelCheckingText() override; - - size_t completion_count_; - size_t cancellation_count_; -}; - -// Faked test target, which stores sent message for verification. -class TestingSpellCheckProvider : public SpellCheckProvider { - public: - TestingSpellCheckProvider(); - // Takes ownership of |spellcheck|. - explicit TestingSpellCheckProvider(SpellCheck* spellcheck); - - ~TestingSpellCheckProvider() override; - bool Send(IPC::Message* message) override; - void OnCallSpellingService(int route_id, - int identifier, - const base::string16& text, - const std::vector<SpellCheckMarker>& markers); - void ResetResult(); - - base::string16 text_; - ScopedVector<IPC::Message> messages_; - size_t spelling_service_call_count_; -}; - -// SpellCheckProvider test fixture. -class SpellCheckProviderTest : public testing::Test { - public: - SpellCheckProviderTest(); - ~SpellCheckProviderTest() override; - - protected: - TestingSpellCheckProvider provider_; -}; - -#endif // CHROME_RENDERER_SPELLCHECKER_SPELLCHECK_PROVIDER_TEST_H_
diff --git a/chrome/renderer/spellchecker/spellcheck_unittest.cc b/chrome/renderer/spellchecker/spellcheck_unittest.cc deleted file mode 100644 index 527516b..0000000 --- a/chrome/renderer/spellchecker/spellcheck_unittest.cc +++ /dev/null
@@ -1,1570 +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/renderer/spellchecker/spellcheck.h" - -#include <stddef.h> - -#include <memory> -#include <utility> - -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/macros.h" -#include "base/message_loop/message_loop.h" -#include "base/path_service.h" -#include "base/run_loop.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "build/build_config.h" -#include "chrome/renderer/spellchecker/hunspell_engine.h" -#include "chrome/renderer/spellchecker/spellcheck_language.h" -#include "components/spellcheck/common/spellcheck_common.h" -#include "components/spellcheck/common/spellcheck_result.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/public/platform/WebVector.h" -#include "third_party/WebKit/public/web/WebTextCheckingCompletion.h" -#include "third_party/WebKit/public/web/WebTextCheckingResult.h" - -#define TYPOGRAPHICAL_APOSTROPHE L"\x2019" - -namespace { -const int kNoOffset = 0; -const int kNoTag = 0; - -base::FilePath GetHunspellDirectory() { - base::FilePath hunspell_directory; - if (!PathService::Get(base::DIR_SOURCE_ROOT, &hunspell_directory)) - return base::FilePath(); - - hunspell_directory = hunspell_directory.AppendASCII("third_party"); - hunspell_directory = hunspell_directory.AppendASCII("hunspell_dictionaries"); - return hunspell_directory; -} - -} // namespace - -// TODO(groby): This needs to be a BrowserTest for OSX. -class SpellCheckTest : public testing::Test { - public: - SpellCheckTest() { - ReinitializeSpellCheck("en-US"); - } - - void ReinitializeSpellCheck(const std::string& language) { - spell_check_.reset(new SpellCheck()); - InitializeSpellCheck(language); - } - - void UninitializeSpellCheck() { - spell_check_.reset(new SpellCheck()); - } - - bool InitializeIfNeeded() { - return spell_check()->InitializeIfNeeded(); - } - - void InitializeSpellCheck(const std::string& language) { - base::FilePath hunspell_directory = GetHunspellDirectory(); - EXPECT_FALSE(hunspell_directory.empty()); - base::File file( - spellcheck::GetVersionedFileName(language, hunspell_directory), - base::File::FLAG_OPEN | base::File::FLAG_READ); -#if defined(OS_MACOSX) - // TODO(groby): Forcing spellcheck to use hunspell, even on OSX. - // Instead, tests should exercise individual spelling engines. - spell_check_->languages_.push_back(new SpellcheckLanguage()); - spell_check_->languages_.front()->platform_spelling_engine_.reset( - new HunspellEngine); - spell_check_->languages_.front()->Init(std::move(file), language); -#else - spell_check_->AddSpellcheckLanguage(std::move(file), language); -#endif - } - - ~SpellCheckTest() override {} - - SpellCheck* spell_check() { return spell_check_.get(); } - - bool CheckSpelling(const std::string& word, int tag) { - return spell_check_->languages_.front() - ->platform_spelling_engine_->CheckSpelling(base::ASCIIToUTF16(word), - tag); - } - - bool IsValidContraction(const base::string16& word, int tag) { - return spell_check_->languages_.front()->IsValidContraction(word, tag); - } - - static void FillSuggestions( - const std::vector<std::vector<base::string16>>& suggestions_list, - std::vector<base::string16>* optional_suggestions) { - SpellCheck::FillSuggestions(suggestions_list, optional_suggestions); - } - -#if !defined(OS_MACOSX) - protected: - void TestSpellCheckParagraph( - const base::string16& input, - const std::vector<SpellCheckResult>& expected) { - blink::WebVector<blink::WebTextCheckingResult> results; - spell_check()->SpellCheckParagraph(input, - &results); - - EXPECT_EQ(results.size(), expected.size()); - size_t size = std::min(results.size(), expected.size()); - for (size_t j = 0; j < size; ++j) { - EXPECT_EQ(results[j].decoration, blink::WebTextDecorationTypeSpelling); - EXPECT_EQ(results[j].location, expected[j].location); - EXPECT_EQ(results[j].length, expected[j].length); - } - } -#endif - - private: - std::unique_ptr<SpellCheck> spell_check_; - base::MessageLoop loop; -}; - -// A fake completion object for verification. -class MockTextCheckingCompletion : public blink::WebTextCheckingCompletion { - public: - MockTextCheckingCompletion() - : completion_count_(0) { - } - - void didFinishCheckingText( - const blink::WebVector<blink::WebTextCheckingResult>& results) override { - completion_count_++; - last_results_ = results; - } - - void didCancelCheckingText() override { - completion_count_++; - } - - size_t completion_count_; - blink::WebVector<blink::WebTextCheckingResult> last_results_; -}; - -// Operates unit tests for the content::SpellCheck::SpellCheckWord() function -// with the US English dictionary. -// The unit tests in this function consist of: -// * Tests for the function with empty strings; -// * Tests for the function with a valid English word; -// * Tests for the function with a valid non-English word; -// * Tests for the function with a valid English word with a preceding -// space character; -// * Tests for the function with a valid English word with a preceding -// non-English word; -// * Tests for the function with a valid English word with a following -// space character; -// * Tests for the function with a valid English word with a following -// non-English word; -// * Tests for the function with two valid English words concatenated -// with space characters or non-English words; -// * Tests for the function with an invalid English word; -// * Tests for the function with an invalid English word with a preceding -// space character; -// * Tests for the function with an invalid English word with a preceding -// non-English word; -// * Tests for the function with an invalid English word with a following -// space character; -// * Tests for the function with an invalid English word with a following -// non-English word, and; -// * Tests for the function with two invalid English words concatenated -// with space characters or non-English words. -// A test with a "[ROBUSTNESS]" mark shows it is a robustness test and it uses -// grammatically incorrect string. -// TODO(groby): Please feel free to add more tests. -TEST_F(SpellCheckTest, SpellCheckStrings_EN_US) { - static const struct { - // A string to be tested. - const wchar_t* input; - // An expected result for this test case. - // * true: the input string does not have any invalid words. - // * false: the input string has one or more invalid words. - bool expected_result; - // The position and the length of the first invalid word. - int misspelling_start; - int misspelling_length; - } kTestCases[] = { - // Empty strings. - {L"", true}, - {L" ", true}, - {L"\xA0", true}, - {L"\x3000", true}, - - // A valid English word "hello". - {L"hello", true}, - // A valid Chinese word (meaning "hello") consisting of two CJKV - // ideographs - {L"\x4F60\x597D", true}, - // A valid Korean word (meaning "hello") consisting of five hangul - // syllables - {L"\xC548\xB155\xD558\xC138\xC694", true}, - // A valid Japanese word (meaning "hello") consisting of five Hiragana - // letters - {L"\x3053\x3093\x306B\x3061\x306F", true}, - // A valid Hindi word (meaning ?) consisting of six Devanagari letters - // (This word is copied from "http://b/issue?id=857583".) - {L"\x0930\x093E\x091C\x0927\x093E\x0928", true}, - // A valid English word "affix" using a Latin ligature 'ffi' - {L"a\xFB03x", true}, - // A valid English word "hello" (fullwidth version) - {L"\xFF28\xFF45\xFF4C\xFF4C\xFF4F", true}, - // Two valid Greek words (meaning "hello") consisting of seven Greek - // letters - {L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5", true}, - // A valid Russian word (meaning "hello") consisting of twelve Cyrillic - // letters - {L"\x0437\x0434\x0440\x0430\x0432\x0441" - L"\x0442\x0432\x0443\x0439\x0442\x0435", true}, - // A valid English contraction - {L"isn't", true}, - // A valid English contraction with a typographical apostrophe. - {L"isn" TYPOGRAPHICAL_APOSTROPHE L"t", true}, - // A valid English word enclosed with underscores. - {L"_hello_", true}, - - // A valid English word with a preceding whitespace - {L" " L"hello", true}, - // A valid English word with a preceding no-break space - {L"\xA0" L"hello", true}, - // A valid English word with a preceding ideographic space - {L"\x3000" L"hello", true}, - // A valid English word with a preceding Chinese word - {L"\x4F60\x597D" L"hello", true}, - // [ROBUSTNESS] A valid English word with a preceding Korean word - {L"\xC548\xB155\xD558\xC138\xC694" L"hello", true}, - // A valid English word with a preceding Japanese word - {L"\x3053\x3093\x306B\x3061\x306F" L"hello", true}, - // [ROBUSTNESS] A valid English word with a preceding Hindi word - {L"\x0930\x093E\x091C\x0927\x093E\x0928" L"hello", true}, - // [ROBUSTNESS] A valid English word with two preceding Greek words - {L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5" - L"hello", true}, - // [ROBUSTNESS] A valid English word with a preceding Russian word - {L"\x0437\x0434\x0440\x0430\x0432\x0441" - L"\x0442\x0432\x0443\x0439\x0442\x0435" L"hello", true}, - - // A valid English word with a following whitespace - {L"hello" L" ", true}, - // A valid English word with a following no-break space - {L"hello" L"\xA0", true}, - // A valid English word with a following ideographic space - {L"hello" L"\x3000", true}, - // A valid English word with a following Chinese word - {L"hello" L"\x4F60\x597D", true}, - // [ROBUSTNESS] A valid English word with a following Korean word - {L"hello" L"\xC548\xB155\xD558\xC138\xC694", true}, - // A valid English word with a following Japanese word - {L"hello" L"\x3053\x3093\x306B\x3061\x306F", true}, - // [ROBUSTNESS] A valid English word with a following Hindi word - {L"hello" L"\x0930\x093E\x091C\x0927\x093E\x0928", true}, - // [ROBUSTNESS] A valid English word with two following Greek words - {L"hello" - L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5", true}, - // [ROBUSTNESS] A valid English word with a following Russian word - {L"hello" L"\x0437\x0434\x0440\x0430\x0432\x0441" - L"\x0442\x0432\x0443\x0439\x0442\x0435", true}, - - // Two valid English words concatenated with a whitespace - {L"hello" L" " L"hello", true}, - // Two valid English words concatenated with a no-break space - {L"hello" L"\xA0" L"hello", true}, - // Two valid English words concatenated with an ideographic space - {L"hello" L"\x3000" L"hello", true}, - // Two valid English words concatenated with a Chinese word - {L"hello" L"\x4F60\x597D" L"hello", true}, - // [ROBUSTNESS] Two valid English words concatenated with a Korean word - {L"hello" L"\xC548\xB155\xD558\xC138\xC694" L"hello", true}, - // Two valid English words concatenated with a Japanese word - {L"hello" L"\x3053\x3093\x306B\x3061\x306F" L"hello", true}, - // [ROBUSTNESS] Two valid English words concatenated with a Hindi word - {L"hello" L"\x0930\x093E\x091C\x0927\x093E\x0928" L"hello" , true}, - // [ROBUSTNESS] Two valid English words concatenated with two Greek words - {L"hello" L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5" - L"hello", true}, - // [ROBUSTNESS] Two valid English words concatenated with a Russian word - {L"hello" L"\x0437\x0434\x0440\x0430\x0432\x0441" - L"\x0442\x0432\x0443\x0439\x0442\x0435" L"hello", true}, - // [ROBUSTNESS] Two valid English words concatenated with a contraction - // character. - {L"hello:hello", true}, - - // An invalid English word - {L"ifmmp", false, 0, 5}, - // An invalid English word "bffly" containing a Latin ligature 'ffl' - {L"b\xFB04y", false, 0, 3}, - // An invalid English word "ifmmp" (fullwidth version) - {L"\xFF29\xFF46\xFF4D\xFF4D\xFF50", false, 0, 5}, - // An invalid English contraction - {L"jtm'u", false, 0, 5}, - // An invalid English word enclosed with underscores. - {L"_ifmmp_", false, 1, 5}, - - // An invalid English word with a preceding whitespace - {L" " L"ifmmp", false, 1, 5}, - // An invalid English word with a preceding no-break space - {L"\xA0" L"ifmmp", false, 1, 5}, - // An invalid English word with a preceding ideographic space - {L"\x3000" L"ifmmp", false, 1, 5}, - // An invalid English word with a preceding Chinese word - {L"\x4F60\x597D" L"ifmmp", false, 2, 5}, - // [ROBUSTNESS] An invalid English word with a preceding Korean word - {L"\xC548\xB155\xD558\xC138\xC694" L"ifmmp", false, 5, 5}, - // An invalid English word with a preceding Japanese word - {L"\x3053\x3093\x306B\x3061\x306F" L"ifmmp", false, 5, 5}, - // [ROBUSTNESS] An invalid English word with a preceding Hindi word - {L"\x0930\x093E\x091C\x0927\x093E\x0928" L"ifmmp", false, 6, 5}, - // [ROBUSTNESS] An invalid English word with two preceding Greek words - {L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5" - L"ifmmp", false, 8, 5}, - // [ROBUSTNESS] An invalid English word with a preceding Russian word - {L"\x0437\x0434\x0440\x0430\x0432\x0441" - L"\x0442\x0432\x0443\x0439\x0442\x0435" L"ifmmp", false, 12, 5}, - - // An invalid English word with a following whitespace - {L"ifmmp" L" ", false, 0, 5}, - // An invalid English word with a following no-break space - {L"ifmmp" L"\xA0", false, 0, 5}, - // An invalid English word with a following ideographic space - {L"ifmmp" L"\x3000", false, 0, 5}, - // An invalid English word with a following Chinese word - {L"ifmmp" L"\x4F60\x597D", false, 0, 5}, - // [ROBUSTNESS] An invalid English word with a following Korean word - {L"ifmmp" L"\xC548\xB155\xD558\xC138\xC694", false, 0, 5}, - // An invalid English word with a following Japanese word - {L"ifmmp" L"\x3053\x3093\x306B\x3061\x306F", false, 0, 5}, - // [ROBUSTNESS] An invalid English word with a following Hindi word - {L"ifmmp" L"\x0930\x093E\x091C\x0927\x093E\x0928", false, 0, 5}, - // [ROBUSTNESS] An invalid English word with two following Greek words - {L"ifmmp" - L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5", false, 0, 5}, - // [ROBUSTNESS] An invalid English word with a following Russian word - {L"ifmmp" L"\x0437\x0434\x0440\x0430\x0432\x0441" - L"\x0442\x0432\x0443\x0439\x0442\x0435", false, 0, 5}, - - // Two invalid English words concatenated with a whitespace - {L"ifmmp" L" " L"ifmmp", false, 0, 5}, - // Two invalid English words concatenated with a no-break space - {L"ifmmp" L"\xA0" L"ifmmp", false, 0, 5}, - // Two invalid English words concatenated with an ideographic space - {L"ifmmp" L"\x3000" L"ifmmp", false, 0, 5}, - // Two invalid English words concatenated with a Chinese word - {L"ifmmp" L"\x4F60\x597D" L"ifmmp", false, 0, 5}, - // [ROBUSTNESS] Two invalid English words concatenated with a Korean word - {L"ifmmp" L"\xC548\xB155\xD558\xC138\xC694" L"ifmmp", false, 0, 5}, - // Two invalid English words concatenated with a Japanese word - {L"ifmmp" L"\x3053\x3093\x306B\x3061\x306F" L"ifmmp", false, 0, 5}, - // [ROBUSTNESS] Two invalid English words concatenated with a Hindi word - {L"ifmmp" L"\x0930\x093E\x091C\x0927\x093E\x0928" L"ifmmp" , false, 0, 5}, - // [ROBUSTNESS] Two invalid English words concatenated with two Greek words - {L"ifmmp" L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5" - L"ifmmp", false, 0, 5}, - // [ROBUSTNESS] Two invalid English words concatenated with a Russian word - {L"ifmmp" L"\x0437\x0434\x0440\x0430\x0432\x0441" - L"\x0442\x0432\x0443\x0439\x0442\x0435" L"ifmmp", false, 0, 5}, - // [ROBUSTNESS] Two invalid English words concatenated with a contraction - // character. - {L"ifmmp:ifmmp", false, 0, 11}, - - // [REGRESSION] Issue 13432: "Any word of 13 or 14 characters is not - // spellcheck" <http://crbug.com/13432>. - {L"qwertyuiopasd", false, 0, 13}, - {L"qwertyuiopasdf", false, 0, 14}, - - // [REGRESSION] Issue 128896: "en_US hunspell dictionary includes - // acknowledgement but not acknowledgements" <http://crbug.com/128896> - {L"acknowledgement", true}, - {L"acknowledgements", true}, - - // Issue 123290: "Spellchecker should treat numbers as word characters" - {L"0th", true}, - {L"1st", true}, - {L"2nd", true}, - {L"3rd", true}, - {L"4th", true}, - {L"5th", true}, - {L"6th", true}, - {L"7th", true}, - {L"8th", true}, - {L"9th", true}, - {L"10th", true}, - {L"100th", true}, - {L"1000th", true}, - {L"25", true}, - {L"2012", true}, - {L"100,000,000", true}, - {L"3.141592653", true}, - }; - - for (size_t i = 0; i < arraysize(kTestCases); ++i) { - size_t input_length = 0; - if (kTestCases[i].input != NULL) { - input_length = wcslen(kTestCases[i].input); - } - int misspelling_start; - int misspelling_length; - bool result = spell_check()->SpellCheckWord( - base::WideToUTF16(kTestCases[i].input).c_str(), - kNoOffset, - static_cast<int>(input_length), - kNoTag, - &misspelling_start, - &misspelling_length, NULL); - - EXPECT_EQ(kTestCases[i].expected_result, result); - EXPECT_EQ(kTestCases[i].misspelling_start, misspelling_start); - EXPECT_EQ(kTestCases[i].misspelling_length, misspelling_length); - } -} - -TEST_F(SpellCheckTest, SpellCheckSuggestions_EN_US) { - static const struct { - // A string to be tested. - const wchar_t* input; - // An expected result for this test case. - // * true: the input string does not have any invalid words. - // * false: the input string has one or more invalid words. - bool expected_result; - // The position and the length of the first invalid word. - int misspelling_start; - int misspelling_length; - - // A suggested word that should occur. - const wchar_t* suggested_word; - } kTestCases[] = { - {L"ello", false, 0, 0, L"hello"}, - {L"ello", false, 0, 0, L"cello"}, - {L"wate", false, 0, 0, L"water"}, - {L"wate", false, 0, 0, L"waste"}, - {L"wate", false, 0, 0, L"sate"}, - {L"wate", false, 0, 0, L"ate"}, - {L"jum", false, 0, 0, L"jump"}, - {L"jum", false, 0, 0, L"hum"}, - {L"jum", false, 0, 0, L"sum"}, - {L"jum", false, 0, 0, L"um"}, - {L"alot", false, 0, 0, L"a lot"}, - // A regression test for Issue 36523. - {L"privliged", false, 0, 0, L"privileged"}, - // TODO (Sidchat): add many more examples. - }; - - for (size_t i = 0; i < arraysize(kTestCases); ++i) { - std::vector<base::string16> suggestions; - size_t input_length = 0; - if (kTestCases[i].input != NULL) { - input_length = wcslen(kTestCases[i].input); - } - int misspelling_start; - int misspelling_length; - bool result = spell_check()->SpellCheckWord( - base::WideToUTF16(kTestCases[i].input).c_str(), - kNoOffset, - static_cast<int>(input_length), - kNoTag, - &misspelling_start, - &misspelling_length, - &suggestions); - - // Check for spelling. - EXPECT_EQ(kTestCases[i].expected_result, result); - - // Check if the suggested words occur. - bool suggested_word_is_present = false; - for (int j = 0; j < static_cast<int>(suggestions.size()); j++) { - if (suggestions.at(j).compare( - base::WideToUTF16(kTestCases[i].suggested_word)) == 0) { - suggested_word_is_present = true; - break; - } - } - - EXPECT_TRUE(suggested_word_is_present); - } -} - -// This test verifies our spellchecker can split a text into words and check -// the spelling of each word in the text. -#if defined(THREAD_SANITIZER) -// SpellCheckTest.SpellCheckText fails under ThreadSanitizer v2. -// See http://crbug.com/217909. -#define MAYBE_SpellCheckText DISABLED_SpellCheckText -#else -#define MAYBE_SpellCheckText SpellCheckText -#endif // THREAD_SANITIZER -TEST_F(SpellCheckTest, MAYBE_SpellCheckText) { - static const struct { - const char* language; - const wchar_t* input; - } kTestCases[] = { - { - // Afrikaans - "af-ZA", - L"Google se missie is om die w\x00EAreld se inligting te organiseer en " - L"dit bruikbaar en toeganklik te maak." - }, { - // Bulgarian - "bg-BG", - L"\x041c\x0438\x0441\x0438\x044f\x0442\x0430 " - L"\x043d\x0430 Google \x0435 \x0434\x0430 \x043e" - L"\x0440\x0433\x0430\x043d\x0438\x0437\x0438\x0440" - L"\x0430 \x0441\x0432\x0435\x0442\x043e\x0432" - L"\x043d\x0430\x0442\x0430 \x0438\x043d\x0444" - L"\x043e\x0440\x043c\x0430\x0446\x0438\x044f " - L"\x0438 \x0434\x0430 \x044f \x043d" - L"\x0430\x043f\x0440\x0430\x0432\x0438 \x0443" - L"\x043d\x0438\x0432\x0435\x0440\x0441\x0430\x043b" - L"\x043d\x043e \x0434\x043e\x0441\x0442\x044a" - L"\x043f\x043d\x0430 \x0438 \x043f\x043e" - L"\x043b\x0435\x0437\x043d\x0430." - }, { - // Catalan - "ca-ES", - L"La missi\x00F3 de Google \x00E9s organitzar la informaci\x00F3 " - L"del m\x00F3n i fer que sigui \x00FAtil i accessible universalment." - }, { - // Czech - "cs-CZ", - L"Posl\x00E1n\x00EDm spole\x010Dnosti Google je " - L"uspo\x0159\x00E1\x0064\x0061t informace z cel\x00E9ho sv\x011Bta " - L"tak, aby byly v\x0161\x0065obecn\x011B p\x0159\x00EDstupn\x00E9 " - L"a u\x017Eite\x010Dn\x00E9." - }, { - // Danish - "da-DK", - L"Googles " - L"mission er at organisere verdens information og g\x00F8re den " - L"almindeligt tilg\x00E6ngelig og nyttig." - }, { - // German - "de-DE", - L"Das Ziel von Google besteht darin, die auf der Welt vorhandenen " - L"Informationen zu organisieren und allgemein zug\x00E4nglich und " - L"nutzbar zu machen." - }, { - // Greek - "el-GR", - L"\x0391\x03C0\x03BF\x03C3\x03C4\x03BF\x03BB\x03AE " - L"\x03C4\x03B7\x03C2 Google \x03B5\x03AF\x03BD\x03B1\x03B9 " - L"\x03BD\x03B1 \x03BF\x03C1\x03B3\x03B1\x03BD\x03CE\x03BD\x03B5\x03B9 " - L"\x03C4\x03B9\x03C2 " - L"\x03C0\x03BB\x03B7\x03C1\x03BF\x03C6\x03BF\x03C1\x03AF\x03B5\x03C2 " - L"\x03C4\x03BF\x03C5 \x03BA\x03CC\x03C3\x03BC\x03BF\x03C5 " - L"\x03BA\x03B1\x03B9 \x03BD\x03B1 \x03C4\x03B9\x03C2 " - L"\x03BA\x03B1\x03B8\x03B9\x03C3\x03C4\x03AC " - L"\x03C0\x03C1\x03BF\x03C3\x03B2\x03AC\x03C3\x03B9\x03BC\x03B5\x03C2 " - L"\x03BA\x03B1\x03B9 \x03C7\x03C1\x03AE\x03C3\x03B9\x03BC\x03B5\x03C2." - }, { - // English (Australia) - "en-AU", - L"Google's mission is to organise the world's information and make it " - L"universally accessible and useful." - }, { - // English (Canada) - "en-CA", - L"Google's mission is to organize the world's information and make it " - L"universally accessible and useful." - }, { - // English (United Kingdom) - "en-GB", - L"Google's mission is to organise the world's information and make it " - L"universally accessible and useful." - }, { - // English (United States) - "en-US", - L"Google's mission is to organize the world's information and make it " - L"universally accessible and useful." - }, { - // Spanish - "es-ES", - L"La misi\x00F3n de " - // L"Google" - to be added. - L" es organizar la informaci\x00F3n mundial " - L"para que resulte universalmente accesible y \x00FAtil." - }, { - // Estonian - "et-EE", - // L"Google'ile " - to be added. - L"\x00FClesanne on korraldada maailma teavet ja teeb selle " - L"k\x00F5igile k\x00E4ttesaadavaks ja kasulikuks.", - }, { - // Persian - "fa", - L"\x0686\x0647 \x0637\x0648\x0631 \x0622\x06cc\x0627 \x0634\x0645\x0627 " - L"\x0627\x06cc\x0631\x0627\x0646\x06cc \x0647\x0633\x062a\x06cc\x062f" - }, { - // Faroese - "fo-FO", - L"Google er at samskipa alla vitan \x00ED heiminum og gera hana alment " - L"atkomiliga og n\x00FDtiliga." - }, { - // French - "fr-FR", - L"Google a pour mission d'organiser les informations \x00E0 " - L"l'\x00E9\x0063helle mondiale dans le but de les rendre accessibles " - L"et utiles \x00E0 tous." - }, { - // Hebrew - "he-IL", - L"\x05D4\x05DE\x05E9\x05D9\x05DE\x05D4 \x05E9\x05DC Google " - L"\x05D4\x05D9\x05D0 \x05DC\x05D0\x05E8\x05D2\x05DF " - L"\x05D0\x05EA \x05D4\x05DE\x05D9\x05D3\x05E2 " - L"\x05D4\x05E2\x05D5\x05DC\x05DE\x05D9 " - L"\x05D5\x05DC\x05D4\x05E4\x05D5\x05DA \x05D0\x05D5\x05EA\x05D5 " - L"\x05DC\x05D6\x05DE\x05D9\x05DF " - L"\x05D5\x05E9\x05D9\x05DE\x05D5\x05E9\x05D9 \x05D1\x05DB\x05DC " - L"\x05D4\x05E2\x05D5\x05DC\x05DD. " - // Two words with ASCII double/single quoation marks. - L"\x05DE\x05E0\x05DB\x0022\x05DC \x05E6\x0027\x05D9\x05E4\x05E1" - }, { - // Hindi - "hi-IN", - L"Google \x0915\x093E \x092E\x093F\x0936\x0928 " - L"\x0926\x0941\x0928\x093F\x092F\x093E \x0915\x0940 " - L"\x091C\x093E\x0928\x0915\x093E\x0930\x0940 \x0915\x094B " - L"\x0935\x094D\x092F\x0935\x0938\x094D\x0925\x093F\x0924 " - L"\x0915\x0930\x0928\x093E \x0914\x0930 \x0909\x0938\x0947 " - L"\x0938\x093E\x0930\x094D\x0935\x092D\x094C\x092E\x093F\x0915 " - L"\x0930\x0942\x092A \x0938\x0947 \x092A\x0939\x0941\x0901\x091A " - L"\x092E\x0947\x0902 \x0914\x0930 \x0909\x092A\x092F\x094B\x0917\x0940 " - L"\x092C\x0928\x093E\x0928\x093E \x0939\x0948." - }, { - // Hungarian - "hu-HU", - L"A Google azt a k\x00FCldet\x00E9st v\x00E1llalta mag\x00E1ra, " - L"hogy a vil\x00E1gon fellelhet\x0151 inform\x00E1\x0063i\x00F3kat " - L"rendszerezze \x00E9s \x00E1ltal\x00E1nosan el\x00E9rhet\x0151v\x00E9, " - L"illetve haszn\x00E1lhat\x00F3v\x00E1 tegye." - }, { - // Croatian - "hr-HR", - // L"Googleova " - to be added. - L"je misija organizirati svjetske informacije i u\x010Diniti ih " - // L"univerzalno " - to be added. - L"pristupa\x010Dnima i korisnima." - }, { - // Indonesian - "id-ID", - L"Misi Google adalah untuk mengelola informasi dunia dan membuatnya " - L"dapat diakses dan bermanfaat secara universal." - }, { - // Italian - "it-IT", - L"La missione di Google \x00E8 organizzare le informazioni a livello " - L"mondiale e renderle universalmente accessibili e fruibili." - }, { - // Lithuanian - "lt-LT", - L"\x201EGoogle\x201C tikslas \x2013 rinkti ir sisteminti pasaulio " - L"informacij\x0105 bei padaryti j\x0105 prieinam\x0105 ir " - L"nauding\x0105 visiems." - }, { - // Latvian - "lv-LV", - L"Google uzdevums ir k\x0101rtot pasaules inform\x0101" - L"ciju un padar\x012Bt to univers\x0101li pieejamu un noder\x012Bgu." - }, { - // Norwegian - "nb-NO", - // L"Googles " - to be added. - L"m\x00E5l er \x00E5 organisere informasjonen i verden og " - L"gj\x00F8re den tilgjengelig og nyttig for alle." - }, { - // Dutch - "nl-NL", - L"Het doel van Google is om alle informatie wereldwijd toegankelijk " - L"en bruikbaar te maken." - }, { - // Polish - "pl-PL", - L"Misj\x0105 Google jest uporz\x0105" L"dkowanie \x015Bwiatowych " - L"zasob\x00F3w informacji, aby sta\x0142y si\x0119 one powszechnie " - L"dost\x0119pne i u\x017Cyteczne." - }, { - // Portuguese (Brazil) - "pt-BR", - L"A miss\x00E3o do " -#if !defined(OS_MACOSX) - L"Google " -#endif - L"\x00E9 organizar as informa\x00E7\x00F5" - L"es do mundo todo e " -#if !defined(OS_MACOSX) - L"torn\x00E1-las " -#endif - L"acess\x00EDveis e \x00FAteis em car\x00E1ter universal." - }, { - // Portuguese (Portugal) - "pt-PT", - L"O " -#if !defined(OS_MACOSX) - L"Google " -#endif - L"tem por miss\x00E3o organizar a informa\x00E7\x00E3o do " - L"mundo e " -#if !defined(OS_MACOSX) - L"torn\x00E1-la " -#endif - L"universalmente acess\x00EDvel e \x00FAtil" - }, { - // Romanian - "ro-RO", - L"Misiunea Google este de a organiza informa\x021B3iile lumii \x0219i de " - L"a le face accesibile \x0219i utile la nivel universal." - }, { - // Russian - "ru-RU", - L"\x041C\x0438\x0441\x0441\x0438\x044F Google " - L"\x0441\x043E\x0441\x0442\x043E\x0438\x0442 \x0432 " - L"\x043E\x0440\x0433\x0430\x043D\x0438\x0437\x0430\x0446\x0438\x0438 " - L"\x043C\x0438\x0440\x043E\x0432\x043E\x0439 " - L"\x0438\x043D\x0444\x043E\x0440\x043C\x0430\x0446\x0438\x0438, " - L"\x043E\x0431\x0435\x0441\x043F\x0435\x0447\x0435\x043D\x0438\x0438 " - L"\x0435\x0435 " - L"\x0434\x043E\x0441\x0442\x0443\x043F\x043D\x043E\x0441\x0442\x0438 " - L"\x0438 \x043F\x043E\x043B\x044C\x0437\x044B \x0434\x043B\x044F " - L"\x0432\x0441\x0435\x0445." - // A Russian word including U+0451. (Bug 15558 <http://crbug.com/15558>) - L"\x0451\x043B\x043A\x0430" - }, { - // Serbo-Croatian (Serbian Latin) - "sh", - L"Google-ova misija je da organizuje sve informacije na svetu i " - L"u\x010dini ih univerzal-no dostupnim i korisnim." - }, { - // Serbian - "sr", - L"\x0047\x006f\x006f\x0067\x006c\x0065\x002d\x043e\x0432\x0430 " - L"\x043c\x0438\x0441\x0438\x0458\x0430 \x0458\x0435 \x0434\x0430 " - L"\x043e\x0440\x0433\x0430\x043d\x0438\x0437\x0443\x0458\x0435 " - L"\x0441\x0432\x0435 " - L"\x0438\x043d\x0444\x043e\x0440\x043c\x0430\x0446\x0438\x0458\x0435 " - L"\x043d\x0430 \x0441\x0432\x0435\x0442\x0443 \x0438 " - L"\x0443\x0447\x0438\x043d\x0438 \x0438\x0445 " - L"\x0443\x043d\x0438\x0432\x0435\x0440\x0437\x0430\x043b\x043d\x043e " - L"\x0434\x043e\x0441\x0442\x0443\x043f\x043d\x0438\x043c \x0438 " - L"\x043a\x043e\x0440\x0438\x0441\x043d\x0438\x043c." - }, { - // Slovak - "sk-SK", - L"Spolo\x010Dnos\x0165 Google si dala za \x00FAlohu usporiada\x0165 " - L"inform\x00E1\x0063ie " - L"z cel\x00E9ho sveta a zabezpe\x010Di\x0165, " - L"aby boli v\x0161eobecne dostupn\x00E9 a u\x017Eito\x010Dn\x00E9." - }, { - // Slovenian - "sl-SI", - // L"Googlovo " - to be added. - L"poslanstvo je organizirati svetovne informacije in " - L"omogo\x010Diti njihovo dostopnost in s tem uporabnost za vse." - }, { - // Swedish - "sv-SE", - L"Googles m\x00E5ls\x00E4ttning \x00E4r att ordna v\x00E4rldens " - L"samlade information och g\x00F6ra den tillg\x00E4nglig f\x00F6r alla." - }, { - // Turkish - "tr-TR", - // L"Google\x2019\x0131n " - to be added. - L"misyonu, d\x00FCnyadaki t\x00FCm bilgileri " - L"organize etmek ve evrensel olarak eri\x015Filebilir ve " - L"kullan\x0131\x015Fl\x0131 k\x0131lmakt\x0131r." - }, { - // Ukranian - "uk-UA", - L"\x041c\x0456\x0441\x0456\x044f " - L"\x043a\x043e\x043c\x043f\x0430\x043d\x0456\x0457 Google " - L"\x043f\x043e\x043b\x044f\x0433\x0430\x0454 \x0432 " - L"\x0442\x043e\x043c\x0443, \x0449\x043e\x0431 " - L"\x0443\x043f\x043e\x0440\x044f\x0434\x043a\x0443\x0432\x0430\x0442" - L"\x0438 \x0456\x043d\x0444\x043e\x0440\x043c\x0430\x0446\x0456\x044e " - L"\x0437 \x0443\x0441\x044c\x043e\x0433\x043e " - L"\x0441\x0432\x0456\x0442\x0443 \x0442\x0430 " - L"\x0437\x0440\x043e\x0431\x0438\x0442\x0438 \x0457\x0457 " - L"\x0443\x043d\x0456\x0432\x0435\x0440\x0441\x0430\x043b\x044c\x043d" - L"\x043e \x0434\x043e\x0441\x0442\x0443\x043f\x043d\x043e\x044e " - L"\x0442\x0430 \x043a\x043e\x0440\x0438\x0441\x043d\x043e\x044e." - }, { - // Vietnamese - "vi-VN", - L"Nhi\x1EC7m v\x1EE5 c\x1EE7\x0061 " - L"Google la \x0111\x1EC3 t\x1ED5 ch\x1EE9\x0063 " - L"c\x00E1\x0063 th\x00F4ng tin c\x1EE7\x0061 " - L"th\x1EBF gi\x1EDBi va l\x00E0m cho n\x00F3 universal c\x00F3 " - L"th\x1EC3 truy c\x1EADp va h\x1EEFu d\x1EE5ng h\x01A1n." - }, { - // Korean - "ko", - L"Google\xC758 \xBAA9\xD45C\xB294 \xC804\xC138\xACC4\xC758 " - L"\xC815\xBCF4\xB97C \xCCB4\xACC4\xD654\xD558\xC5EC \xBAA8\xB450\xAC00 " - L"\xD3B8\xB9AC\xD558\xAC8C \xC774\xC6A9\xD560 \xC218 " - L"\xC788\xB3C4\xB85D \xD558\xB294 \xAC83\xC785\xB2C8\xB2E4." - }, { - // Albanian - "sq", - L"Misioni i Google \x00EBsht\x00EB q\x00EB t\x00EB organizoj\x00EB " - L"informacionin e bot\x00EBs dhe t\x00EB b\x00EBjn\x00EB at\x00EB " - L"universalisht t\x00EB arritshme dhe t\x00EB dobishme." - }, { - // Tamil - "ta", - L"Google \x0B87\x0BA9\x0BCD " - L"\x0BA8\x0BC7\x0BBE\x0B95\x0BCD\x0B95\x0BAE\x0BCD " - L"\x0B89\x0BB2\x0B95\x0BBF\x0BA9\x0BCD \x0BA4\x0B95\x0BB5\x0BB2\x0BCD " - L"\x0B8F\x0BB1\x0BCD\x0BAA\x0BBE\x0B9F\x0BC1 \x0B87\x0BA4\x0BC1 " - L"\x0B89\x0BB2\x0B95\x0BB3\x0BBE\x0BB5\x0BBF\x0BAF " - L"\x0B85\x0BA3\x0BC1\x0B95\x0B95\x0BCD \x0B95\x0BC2\x0B9F\x0BBF\x0BAF " - L"\x0BAE\x0BB1\x0BCD\x0BB1\x0BC1\x0BAE\x0BCD " - L"\x0BAA\x0BAF\x0BA9\x0BC1\x0BB3\x0BCD\x0BB3 " - L"\x0B9A\x0BC6\x0BAF\x0BCD\x0BAF \x0B89\x0BB3\x0BCD\x0BB3\x0BA4\x0BC1." - }, { - // Tajik - "tg", - L"\x041c\x0438\x0441\x0441\x0438\x044f\x0438 Google \x0438\x043d " - L"\x043c\x0443\x0440\x0430\x0442\x0442\x0430\x0431 " - L"\x0441\x043e\x0445\x0442\x0430\x043d\x0438 " - L"\x043c\x0430\x044a\x043b\x0443\x043c\x043e\x0442\x04b3\x043e\x0438 " - L"\x043c\x0430\x0432\x04b7\x0443\x0434\x0430, \x043e\x0441\x043e\x043d " - L"\x043d\x0430\x043c\x0443\x0434\x0430\x043d\x0438 " - L"\x0438\x0441\x0442\x0438\x0444\x043e\x0434\x0430\x0431\x0430\x0440" - L"\x04e3 \x0432\x0430 \x0434\x0430\x0441\x0442\x0440\x0430\x0441\x0438 " - L"\x0443\x043c\x0443\x043c " - L"\x0433\x0430\x0440\x0434\x043e\x043d\x0438\x0434\x0430\x043d\x0438 " - L"\x043e\x043d\x04b3\x043e \x0430\x0441\x0442." - }, - }; - - for (size_t i = 0; i < arraysize(kTestCases); ++i) { - ReinitializeSpellCheck(kTestCases[i].language); - size_t input_length = 0; - if (kTestCases[i].input != NULL) - input_length = wcslen(kTestCases[i].input); - - int misspelling_start = 0; - int misspelling_length = 0; - bool result = spell_check()->SpellCheckWord( - base::WideToUTF16(kTestCases[i].input).c_str(), - kNoOffset, - static_cast<int>(input_length), - kNoTag, - &misspelling_start, - &misspelling_length, NULL); - - EXPECT_TRUE(result) - << "\"" - << std::wstring(kTestCases[i].input).substr( - misspelling_start, misspelling_length) - << "\" is misspelled in " - << kTestCases[i].language - << "."; - EXPECT_EQ(0, misspelling_start); - EXPECT_EQ(0, misspelling_length); - } -} - -// Verify that our SpellCheck::SpellCheckWord() returns false when it checks -// misspelled words. -TEST_F(SpellCheckTest, MisspelledWords) { - static const struct { - const char* language; - const wchar_t* input; - } kTestCases[] = { - { - // A misspelled word for English - "en-US", - L"aaaaaaaaaa", - }, { - // A misspelled word for Greek. - "el-GR", - L"\x03B1\x03B1\x03B1\x03B1\x03B1\x03B1\x03B1\x03B1\x03B1\x03B1", - }, { - // A misspelled word for Persian. - "fa", - L"\x06cc\x06a9\x06cc\x0634\x0627\x0646", - }, { - // A misspelled word for Hebrew - "he-IL", - L"\x05D0\x05D0\x05D0\x05D0\x05D0\x05D0\x05D0\x05D0\x05D0\x05D0", - }, { - // Hindi - "hi-IN", - L"\x0905\x0905\x0905\x0905\x0905\x0905\x0905\x0905\x0905\x0905", - }, { - // A misspelled word for Russian - "ru-RU", - L"\x0430\x0430\x0430\x0430\x0430\x0430\x0430\x0430\x0430\x0430", - }, - }; - - for (size_t i = 0; i < arraysize(kTestCases); ++i) { - ReinitializeSpellCheck(kTestCases[i].language); - - base::string16 word(base::WideToUTF16(kTestCases[i].input)); - int word_length = static_cast<int>(word.length()); - int misspelling_start = 0; - int misspelling_length = 0; - bool result = spell_check()->SpellCheckWord(word.c_str(), - kNoOffset, - word_length, - kNoTag, - &misspelling_start, - &misspelling_length, - NULL); - EXPECT_FALSE(result); - EXPECT_EQ(0, misspelling_start); - EXPECT_EQ(word_length, misspelling_length); - } -} - -// Since SpellCheck::SpellCheckParagraph is not implemented on Mac, -// we skip these SpellCheckParagraph tests on Mac. -#if !defined(OS_MACOSX) - -// Make sure SpellCheckParagraph does not crash if the input is empty. -TEST_F(SpellCheckTest, SpellCheckParagraphEmptyParagraph) { - std::vector<SpellCheckResult> expected; - TestSpellCheckParagraph(base::UTF8ToUTF16(""), expected); -} - -// A simple test case having no misspellings. -TEST_F(SpellCheckTest, SpellCheckParagraphNoMisspellings) { - const base::string16 text = base::UTF8ToUTF16("apple"); - std::vector<SpellCheckResult> expected; - TestSpellCheckParagraph(text, expected); -} - -// A simple test case having one misspelling. -TEST_F(SpellCheckTest, SpellCheckParagraphSingleMisspellings) { - const base::string16 text = base::UTF8ToUTF16("zz"); - std::vector<SpellCheckResult> expected; - expected.push_back(SpellCheckResult( - SpellCheckResult::SPELLING, 0, 2)); - - TestSpellCheckParagraph(text, expected); -} - -// A simple test case having multiple misspellings. -TEST_F(SpellCheckTest, SpellCheckParagraphMultipleMisspellings) { - const base::string16 text = base::UTF8ToUTF16("zz, zz"); - std::vector<SpellCheckResult> expected; - expected.push_back(SpellCheckResult( - SpellCheckResult::SPELLING, 0, 2)); - expected.push_back(SpellCheckResult( - SpellCheckResult::SPELLING, 4, 2)); - - TestSpellCheckParagraph(text, expected); -} - -// Make sure a relatively long (correct) sentence can be spellchecked. -TEST_F(SpellCheckTest, SpellCheckParagraphLongSentence) { - std::vector<SpellCheckResult> expected; - // The text is taken from US constitution preamble. - const base::string16 text = base::UTF8ToUTF16( - "We the people of the United States, in order to form a more perfect " - "union, establish justice, insure domestic tranquility, provide for " - "the common defense, promote the general welfare, and secure the " - "blessings of liberty to ourselves and our posterity, do ordain and " - "establish this Constitution for the United States of America."); - - TestSpellCheckParagraph(text, expected); -} - -// Make sure all misspellings can be found in a relatively long sentence. -TEST_F(SpellCheckTest, SpellCheckParagraphLongSentenceMultipleMisspellings) { - std::vector<SpellCheckResult> expected; - - // All 'the' are converted to 'hte' in US consitition preamble. - const base::string16 text = base::UTF8ToUTF16( - "We hte people of hte United States, in order to form a more perfect " - "union, establish justice, insure domestic tranquility, provide for " - "hte common defense, promote hte general welfare, and secure hte " - "blessings of liberty to ourselves and our posterity, do ordain and " - "establish this Constitution for hte United States of America."); - - expected.push_back(SpellCheckResult( - SpellCheckResult::SPELLING, 3, 3)); - expected.push_back(SpellCheckResult( - SpellCheckResult::SPELLING, 17, 3)); - expected.push_back(SpellCheckResult( - SpellCheckResult::SPELLING, 135, 3)); - expected.push_back(SpellCheckResult( - SpellCheckResult::SPELLING, 163, 3)); - expected.push_back(SpellCheckResult( - SpellCheckResult::SPELLING, 195, 3)); - expected.push_back(SpellCheckResult( - SpellCheckResult::SPELLING, 298, 3)); - - TestSpellCheckParagraph(text, expected); -} - -// We also skip RequestSpellCheck tests on Mac, because a system spellchecker -// is used on Mac instead of SpellCheck::RequestTextChecking. - -// Make sure RequestTextChecking does not crash if input is empty. -TEST_F(SpellCheckTest, RequestSpellCheckWithEmptyString) { - MockTextCheckingCompletion completion; - - spell_check()->RequestTextChecking(base::string16(), &completion); - - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ(completion.completion_count_, 1U); -} - -// A simple test case having no misspellings. -TEST_F(SpellCheckTest, RequestSpellCheckWithoutMisspelling) { - MockTextCheckingCompletion completion; - - const base::string16 text = base::ASCIIToUTF16("hello"); - spell_check()->RequestTextChecking(text, &completion); - - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ(completion.completion_count_, 1U); -} - -// A simple test case having one misspelling. -TEST_F(SpellCheckTest, RequestSpellCheckWithSingleMisspelling) { - MockTextCheckingCompletion completion; - - const base::string16 text = base::ASCIIToUTF16("apple, zz"); - spell_check()->RequestTextChecking(text, &completion); - - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ(completion.completion_count_, 1U); - EXPECT_EQ(completion.last_results_.size(), 1U); - EXPECT_EQ(completion.last_results_[0].location, 7); - EXPECT_EQ(completion.last_results_[0].length, 2); -} - -// A simple test case having a few misspellings. -TEST_F(SpellCheckTest, RequestSpellCheckWithMisspellings) { - MockTextCheckingCompletion completion; - - const base::string16 text = base::ASCIIToUTF16("apple, zz, orange, zz"); - spell_check()->RequestTextChecking(text, &completion); - - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ(completion.completion_count_, 1U); - EXPECT_EQ(completion.last_results_.size(), 2U); - EXPECT_EQ(completion.last_results_[0].location, 7); - EXPECT_EQ(completion.last_results_[0].length, 2); - EXPECT_EQ(completion.last_results_[1].location, 19); - EXPECT_EQ(completion.last_results_[1].length, 2); -} - -// A test case that multiple requests comes at once. Make sure all -// requests are processed. -TEST_F(SpellCheckTest, RequestSpellCheckWithMultipleRequests) { - MockTextCheckingCompletion completion[3]; - - const base::string16 text[3] = { - base::ASCIIToUTF16("what, zz"), - base::ASCIIToUTF16("apple, zz"), - base::ASCIIToUTF16("orange, zz") - }; - - for (int i = 0; i < 3; ++i) - spell_check()->RequestTextChecking(text[i], &completion[i]); - - base::RunLoop().RunUntilIdle(); - - for (int i = 0; i < 3; ++i) { - EXPECT_EQ(completion[i].completion_count_, 1U); - EXPECT_EQ(completion[i].last_results_.size(), 1U); - EXPECT_EQ(completion[i].last_results_[0].location, 6 + i); - EXPECT_EQ(completion[i].last_results_[0].length, 2); - } -} - -// A test case that spellchecking is requested before initializing. -// In this case, we postpone to post a request. -TEST_F(SpellCheckTest, RequestSpellCheckWithoutInitialization) { - UninitializeSpellCheck(); - - MockTextCheckingCompletion completion; - const base::string16 text = base::ASCIIToUTF16("zz"); - - spell_check()->RequestTextChecking(text, &completion); - - // The task will not be posted yet. - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(completion.completion_count_, 0U); -} - -// Requests several spellchecking before initializing. Except the last one, -// posting requests is cancelled and text is rendered as correct one. -TEST_F(SpellCheckTest, RequestSpellCheckMultipleTimesWithoutInitialization) { - UninitializeSpellCheck(); - - MockTextCheckingCompletion completion[3]; - const base::string16 text[3] = { - base::ASCIIToUTF16("what, zz"), - base::ASCIIToUTF16("apple, zz"), - base::ASCIIToUTF16("orange, zz") - }; - - // Calls RequestTextchecking a few times. - for (int i = 0; i < 3; ++i) - spell_check()->RequestTextChecking(text[i], &completion[i]); - - // The last task will be posted after initialization, however the other - // requests should be pressed without spellchecking. - base::RunLoop().RunUntilIdle(); - for (int i = 0; i < 2; ++i) - EXPECT_EQ(completion[i].completion_count_, 1U); - EXPECT_EQ(completion[2].completion_count_, 0U); - - // Checks the last request is processed after initialization. - InitializeSpellCheck("en-US"); - - // Calls PostDelayedSpellCheckTask instead of OnInit here for simplicity. - spell_check()->PostDelayedSpellCheckTask( - spell_check()->pending_request_param_.release()); - base::RunLoop().RunUntilIdle(); - for (int i = 0; i < 3; ++i) - EXPECT_EQ(completion[i].completion_count_, 1U); -} - -#endif - -// Verify that the SpellCheck class keeps the spelling marker added to a -// misspelled word "zz". -TEST_F(SpellCheckTest, CreateTextCheckingResultsKeepsMarkers) { - base::string16 text = base::ASCIIToUTF16("zz"); - std::vector<SpellCheckResult> spellcheck_results; - spellcheck_results.push_back( - SpellCheckResult(SpellCheckResult::SPELLING, 0, 2, base::string16())); - blink::WebVector<blink::WebTextCheckingResult> textcheck_results; - spell_check()->CreateTextCheckingResults(SpellCheck::USE_NATIVE_CHECKER, 0, - text, spellcheck_results, - &textcheck_results); - ASSERT_EQ(spellcheck_results.size(), textcheck_results.size()); - EXPECT_EQ(blink::WebTextDecorationTypeSpelling, - textcheck_results[0].decoration); - EXPECT_EQ(spellcheck_results[0].location, textcheck_results[0].location); - EXPECT_EQ(spellcheck_results[0].length, textcheck_results[0].length); -} - -// Verify that the SpellCheck class replaces the spelling marker added to a -// contextually-misspelled word "bean" with a grammar marker. -TEST_F(SpellCheckTest, CreateTextCheckingResultsAddsGrammarMarkers) { - base::string16 text = base::ASCIIToUTF16("I have bean to USA."); - std::vector<SpellCheckResult> spellcheck_results; - spellcheck_results.push_back( - SpellCheckResult(SpellCheckResult::SPELLING, 7, 4, base::string16())); - blink::WebVector<blink::WebTextCheckingResult> textcheck_results; - spell_check()->CreateTextCheckingResults(SpellCheck::USE_NATIVE_CHECKER, 0, - text, spellcheck_results, - &textcheck_results); - ASSERT_EQ(spellcheck_results.size(), textcheck_results.size()); - EXPECT_EQ(blink::WebTextDecorationTypeGrammar, - textcheck_results[0].decoration); - EXPECT_EQ(spellcheck_results[0].location, textcheck_results[0].location); - EXPECT_EQ(spellcheck_results[0].length, textcheck_results[0].length); -} - -// Verify that the SpellCheck preserves the original apostrophe type in the -// checked text, regardless of the type of apostrophe the browser returns. -TEST_F(SpellCheckTest, CreateTextCheckingResultsKeepsTypographicalApostrophe) { - base::string16 text = base::WideToUTF16( - L"Ik've havn" TYPOGRAPHICAL_APOSTROPHE L"t ni'n" - TYPOGRAPHICAL_APOSTROPHE L"out-s I've I" TYPOGRAPHICAL_APOSTROPHE - L"ve"); - std::vector<SpellCheckResult> spellcheck_results; - - // All typewriter apostrophe results. - spellcheck_results.push_back(SpellCheckResult(SpellCheckResult::SPELLING, 0, - 5, base::UTF8ToUTF16("I've"))); - spellcheck_results.push_back(SpellCheckResult( - SpellCheckResult::SPELLING, 6, 6, base::UTF8ToUTF16("haven't"))); - spellcheck_results.push_back(SpellCheckResult( - SpellCheckResult::SPELLING, 13, 10, base::UTF8ToUTF16("in'n'out's"))); - - // Replacements that differ only by apostrophe type should be ignored. - spellcheck_results.push_back(SpellCheckResult(SpellCheckResult::SPELLING, 24, - 4, base::UTF8ToUTF16("I've"))); - spellcheck_results.push_back(SpellCheckResult(SpellCheckResult::SPELLING, 29, - 4, base::UTF8ToUTF16("I've"))); - - // All typographical apostrophe results. - spellcheck_results.push_back( - SpellCheckResult(SpellCheckResult::SPELLING, 0, 5, - base::WideToUTF16(L"I" TYPOGRAPHICAL_APOSTROPHE L"ve"))); - spellcheck_results.push_back(SpellCheckResult( - SpellCheckResult::SPELLING, 6, 6, - base::WideToUTF16(L"haven" TYPOGRAPHICAL_APOSTROPHE L"t"))); - spellcheck_results.push_back(SpellCheckResult( - SpellCheckResult::SPELLING, 13, 10, base::WideToUTF16( - L"in" TYPOGRAPHICAL_APOSTROPHE L"n" TYPOGRAPHICAL_APOSTROPHE L"out" - TYPOGRAPHICAL_APOSTROPHE L"s"))); - - // Replacements that differ only by apostrophe type should be ignored. - spellcheck_results.push_back( - SpellCheckResult(SpellCheckResult::SPELLING, 24, 4, - base::WideToUTF16(L"I" TYPOGRAPHICAL_APOSTROPHE L"ve"))); - spellcheck_results.push_back( - SpellCheckResult(SpellCheckResult::SPELLING, 29, 4, - base::WideToUTF16(L"I" TYPOGRAPHICAL_APOSTROPHE L"ve"))); - - blink::WebVector<blink::WebTextCheckingResult> textcheck_results; - spell_check()->CreateTextCheckingResults(SpellCheck::USE_NATIVE_CHECKER, 0, - text, spellcheck_results, - &textcheck_results); - - static const wchar_t* kExpectedReplacements[] = { - L"I've", - L"haven" TYPOGRAPHICAL_APOSTROPHE L"t", - L"in'n" TYPOGRAPHICAL_APOSTROPHE L"out's", - L"I've", - L"haven" TYPOGRAPHICAL_APOSTROPHE L"t", - L"in'n" TYPOGRAPHICAL_APOSTROPHE L"out" TYPOGRAPHICAL_APOSTROPHE L"s", - }; - - ASSERT_EQ(arraysize(kExpectedReplacements), textcheck_results.size()); - for (size_t i = 0; i < arraysize(kExpectedReplacements); ++i) { - EXPECT_EQ(base::WideToUTF16(kExpectedReplacements[i]), - textcheck_results[i].replacement) - << "i=" << i << "\nactual: \"" - << base::string16(textcheck_results[i].replacement) << "\""; - } -} - -// Checks some words that should be present in all English dictionaries. -TEST_F(SpellCheckTest, EnglishWords) { - static const struct { - const char* input; - bool should_pass; - } kTestCases[] = { - // Issue 146093: "Chromebook" and "Chromebox" not included in spell-checking - // dictionary. - {"Chromebook", true}, - {"Chromebooks", true}, - {"Chromebox", true}, - {"Chromeboxes", true}, - {"Chromeblade", true}, - {"Chromeblades", true}, - {"Chromebase", true}, - {"Chromebases", true}, - // Issue 94708: Spell-checker incorrectly reports whisky as misspelled. - {"whisky", true}, - {"whiskey", true}, - {"whiskies", true}, - // Issue 98678: "Recency" should be included in client-side dictionary. - {"recency", true}, - {"recencies", false}, - // Issue 140486 - {"movie", true}, - {"movies", true}, - }; - - static const char* const kLocales[] = { "en-GB", "en-US", "en-CA", "en-AU" }; - - for (size_t j = 0; j < arraysize(kLocales); ++j) { - ReinitializeSpellCheck(kLocales[j]); - for (size_t i = 0; i < arraysize(kTestCases); ++i) { - size_t input_length = 0; - if (kTestCases[i].input != NULL) - input_length = strlen(kTestCases[i].input); - - int misspelling_start = 0; - int misspelling_length = 0; - bool result = spell_check()->SpellCheckWord( - base::ASCIIToUTF16(kTestCases[i].input).c_str(), - kNoOffset, - static_cast<int>(input_length), - kNoTag, - &misspelling_start, - &misspelling_length, NULL); - - EXPECT_EQ(kTestCases[i].should_pass, result) << kTestCases[i].input << - " in " << kLocales[j]; - } - } -} - -// Checks that NOSUGGEST works in English dictionaries. -TEST_F(SpellCheckTest, NoSuggest) { - static const struct { - const char* input; - const char* suggestion; - const char* locale; - bool should_pass; - } kTestCases[] = { - {"suckerbert", "cocksucker", "en-GB", true}, - {"suckerbert", "cocksucker", "en-US", true}, - {"suckerbert", "cocksucker", "en-CA", true}, - {"suckerbert", "cocksucker", "en-AU", true}, - {"suckerbert", "cocksuckers", "en-GB", true}, - {"suckerbert", "cocksuckers", "en-US", true}, - {"suckerbert", "cocksuckers", "en-CA", true}, - {"suckerbert", "cocksuckers", "en-AU", true}, - {"Batasunaa", "Batasuna", "ca-ES", true}, - {"pornoo", "porno", "it-IT", true}, - {"catass", "catas", "lt-LT", true}, - {"kuracc", "kurac", "sl-SI", true}, - {"pittt", "pitt", "sv-SE", true}, - }; - - size_t test_cases_size = arraysize(kTestCases); - for (size_t i = 0; i < test_cases_size; ++i) { - ReinitializeSpellCheck(kTestCases[i].locale); - size_t suggestion_length = 0; - if (kTestCases[i].suggestion != NULL) - suggestion_length = strlen(kTestCases[i].suggestion); - - // First check that the NOSUGGEST flag didn't mark this word as not being in - // the dictionary. - int misspelling_start = 0; - int misspelling_length = 0; - bool result = spell_check()->SpellCheckWord( - base::ASCIIToUTF16(kTestCases[i].suggestion).c_str(), - kNoOffset, - static_cast<int>(suggestion_length), - kNoTag, - &misspelling_start, - &misspelling_length, NULL); - - EXPECT_EQ(kTestCases[i].should_pass, result) << kTestCases[i].suggestion << - " in " << kTestCases[i].locale; - - // Now verify that this test case does not show up as a suggestion. - std::vector<base::string16> suggestions; - size_t input_length = 0; - if (kTestCases[i].input != NULL) - input_length = strlen(kTestCases[i].input); - result = spell_check()->SpellCheckWord( - base::ASCIIToUTF16(kTestCases[i].input).c_str(), - kNoOffset, - static_cast<int>(input_length), - kNoTag, - &misspelling_start, - &misspelling_length, - &suggestions); - // Input word should be a misspelling. - EXPECT_FALSE(result) << kTestCases[i].input - << " is not a misspelling in " - << kTestCases[i].locale; - // Check if the suggested words occur. - for (int j = 0; j < static_cast<int>(suggestions.size()); j++) { - for (size_t t = 0; t < test_cases_size; t++) { - int compare_result = suggestions.at(j).compare( - base::ASCIIToUTF16(kTestCases[t].suggestion)); - EXPECT_FALSE(compare_result == 0) << kTestCases[t].suggestion << - " in " << kTestCases[i].locale; - } - } - } -} - -// Check that the correct dictionary files are checked in. -TEST_F(SpellCheckTest, DictionaryFiles) { - std::vector<std::string> spellcheck_languages; - spellcheck::SpellCheckLanguages(&spellcheck_languages); - EXPECT_FALSE(spellcheck_languages.empty()); - - base::FilePath hunspell = GetHunspellDirectory(); - for (size_t i = 0; i < spellcheck_languages.size(); ++i) { - base::FilePath dict = - spellcheck::GetVersionedFileName(spellcheck_languages[i], hunspell); - EXPECT_TRUE(base::PathExists(dict)) << dict.value() << " not found"; - } -} - -// TODO(groby): Add a test for hunspell itself, when MAXWORDLEN is exceeded. -TEST_F(SpellCheckTest, SpellingEngine_CheckSpelling) { - static const struct { - const char* word; - bool expected_result; - } kTestCases[] = { - { "", true }, - { "automatic", true }, - { "hello", true }, - { "forglobantic", false }, - { "xfdssfsdfaasds", false }, - { // 64 chars are the longest word to check - this should fail checking. - "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl", - false - }, - { // Any word longer than 64 chars should be exempt from checking. - "reallylongwordthatabsolutelyexceedsthespecifiedcharacterlimitabit", - true - } - }; - - // Initialization magic - call InitializeIfNeeded twice. The first one simply - // flags internal state that a dictionary was requested. The second one will - // take the passed-in file and initialize hunspell with it. (The file was - // passed to hunspell in the ctor for the test fixture). - // This needs to be done since we need to ensure the SpellingEngine objects - // contained in the SpellcheckLanguages in |languages_| from the test fixture - // does get initialized. - // TODO(groby): Clean up this mess. - InitializeIfNeeded(); - ASSERT_FALSE(InitializeIfNeeded()); - - for (size_t i = 0; i < arraysize(kTestCases); ++i) { - bool result = CheckSpelling(kTestCases[i].word, 0); - EXPECT_EQ(kTestCases[i].expected_result, result) << - "Failed test for " << kTestCases[i].word; - } -} - -// Chrome should not suggest "Othello" for "hellllo" or "identically" for -// "accidently". -TEST_F(SpellCheckTest, LogicalSuggestions) { - static const struct { - const char* misspelled; - const char* suggestion; - } kTestCases[] = { - { "hellllo", "hello" }, - { "accidently", "accidentally" } - }; - - for (size_t i = 0; i < arraysize(kTestCases); ++i) { - int misspelling_start = 0; - int misspelling_length = 0; - std::vector<base::string16> suggestions; - EXPECT_FALSE(spell_check()->SpellCheckWord( - base::ASCIIToUTF16(kTestCases[i].misspelled).c_str(), - kNoOffset, - strlen(kTestCases[i].misspelled), - kNoTag, - &misspelling_start, - &misspelling_length, - &suggestions)); - EXPECT_GE(suggestions.size(), static_cast<size_t>(1)); - if (suggestions.size() > 0) - EXPECT_EQ(suggestions[0], base::ASCIIToUTF16(kTestCases[i].suggestion)); - } -} - -// Words with apostrophes should be valid contractions. -TEST_F(SpellCheckTest, IsValidContraction) { - static const char* kLanguages[] = { - "en-AU", - "en-CA", - "en-GB", - "en-US", - }; - - static const wchar_t* kWords[] = { - L"in'n'out", - L"in" TYPOGRAPHICAL_APOSTROPHE L"n" TYPOGRAPHICAL_APOSTROPHE L"out", - }; - - for (size_t i = 0; i < arraysize(kLanguages); ++i) { - ReinitializeSpellCheck(kLanguages[i]); - for (size_t j = 0; j < arraysize(kWords); ++j) - EXPECT_TRUE(IsValidContraction(base::WideToUTF16(kWords[j]), 0)); - } -} - -TEST_F(SpellCheckTest, FillSuggestions_OneLanguageNoSuggestions) { - std::vector<std::vector<base::string16>> suggestions_list; - std::vector<base::string16> suggestion_results; - - suggestions_list.resize(1); - - FillSuggestions(suggestions_list, &suggestion_results); - EXPECT_TRUE(suggestion_results.empty()); -} - -TEST_F(SpellCheckTest, FillSuggestions_OneLanguageFewSuggestions) { - std::vector<std::vector<base::string16>> suggestions_list; - std::vector<base::string16> suggestion_results; - - suggestions_list.resize(1); - suggestions_list[0].push_back(base::ASCIIToUTF16("foo")); - - FillSuggestions(suggestions_list, &suggestion_results); - ASSERT_EQ(1U, suggestion_results.size()); - EXPECT_EQ(base::ASCIIToUTF16("foo"), suggestion_results[0]); -} - -TEST_F(SpellCheckTest, FillSuggestions_OneLanguageManySuggestions) { - std::vector<std::vector<base::string16>> suggestions_list; - std::vector<base::string16> suggestion_results; - - suggestions_list.resize(1); - for (int i = 0; i < spellcheck::kMaxSuggestions + 2; ++i) - suggestions_list[0].push_back(base::ASCIIToUTF16(base::IntToString(i))); - - FillSuggestions(suggestions_list, &suggestion_results); - ASSERT_EQ(static_cast<size_t>(spellcheck::kMaxSuggestions), - suggestion_results.size()); - for (int i = 0; i < spellcheck::kMaxSuggestions; ++i) - EXPECT_EQ(base::ASCIIToUTF16(base::IntToString(i)), suggestion_results[i]); -} - -TEST_F(SpellCheckTest, FillSuggestions_RemoveDuplicates) { - std::vector<std::vector<base::string16>> suggestions_list; - std::vector<base::string16> suggestion_results; - - suggestions_list.resize(2); - for (size_t i = 0; i < 2; ++i) { - suggestions_list[i].push_back(base::ASCIIToUTF16("foo")); - suggestions_list[i].push_back(base::ASCIIToUTF16("bar")); - suggestions_list[i].push_back(base::ASCIIToUTF16("baz")); - } - - FillSuggestions(suggestions_list, &suggestion_results); - ASSERT_EQ(3U, suggestion_results.size()); - EXPECT_EQ(base::ASCIIToUTF16("foo"), suggestion_results[0]); - EXPECT_EQ(base::ASCIIToUTF16("bar"), suggestion_results[1]); - EXPECT_EQ(base::ASCIIToUTF16("baz"), suggestion_results[2]); -} - -TEST_F(SpellCheckTest, FillSuggestions_TwoLanguages) { - std::vector<std::vector<base::string16>> suggestions_list; - std::vector<base::string16> suggestion_results; - - suggestions_list.resize(2); - for (size_t i = 0; i < 2; ++i) { - std::string prefix = base::IntToString(i); - suggestions_list[i].push_back(base::ASCIIToUTF16(prefix + "foo")); - suggestions_list[i].push_back(base::ASCIIToUTF16(prefix + "bar")); - suggestions_list[i].push_back(base::ASCIIToUTF16(prefix + "baz")); - } - - // Yes, this test assumes kMaxSuggestions is 5. If it isn't, the test needs - // to be updated accordingly. - ASSERT_EQ(5, spellcheck::kMaxSuggestions); - FillSuggestions(suggestions_list, &suggestion_results); - ASSERT_EQ(5U, suggestion_results.size()); - EXPECT_EQ(base::ASCIIToUTF16("0foo"), suggestion_results[0]); - EXPECT_EQ(base::ASCIIToUTF16("1foo"), suggestion_results[1]); - EXPECT_EQ(base::ASCIIToUTF16("0bar"), suggestion_results[2]); - EXPECT_EQ(base::ASCIIToUTF16("1bar"), suggestion_results[3]); - EXPECT_EQ(base::ASCIIToUTF16("0baz"), suggestion_results[4]); -} - -TEST_F(SpellCheckTest, FillSuggestions_ThreeLanguages) { - std::vector<std::vector<base::string16>> suggestions_list; - std::vector<base::string16> suggestion_results; - - suggestions_list.resize(3); - for (size_t i = 0; i < 3; ++i) { - std::string prefix = base::IntToString(i); - suggestions_list[i].push_back(base::ASCIIToUTF16(prefix + "foo")); - suggestions_list[i].push_back(base::ASCIIToUTF16(prefix + "bar")); - suggestions_list[i].push_back(base::ASCIIToUTF16(prefix + "baz")); - } - - // Yes, this test assumes kMaxSuggestions is 5. If it isn't, the test needs - // to be updated accordingly. - ASSERT_EQ(5, spellcheck::kMaxSuggestions); - FillSuggestions(suggestions_list, &suggestion_results); - ASSERT_EQ(5U, suggestion_results.size()); - EXPECT_EQ(base::ASCIIToUTF16("0foo"), suggestion_results[0]); - EXPECT_EQ(base::ASCIIToUTF16("1foo"), suggestion_results[1]); - EXPECT_EQ(base::ASCIIToUTF16("2foo"), suggestion_results[2]); - EXPECT_EQ(base::ASCIIToUTF16("0bar"), suggestion_results[3]); - EXPECT_EQ(base::ASCIIToUTF16("1bar"), suggestion_results[4]); -}
diff --git a/chrome/renderer/spellchecker/spellcheck_worditerator.cc b/chrome/renderer/spellchecker/spellcheck_worditerator.cc deleted file mode 100644 index 0816fa9..0000000 --- a/chrome/renderer/spellchecker/spellcheck_worditerator.cc +++ /dev/null
@@ -1,445 +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. - -// Implements a custom word iterator used for our spellchecker. - -#include "chrome/renderer/spellchecker/spellcheck_worditerator.h" - -#include <map> -#include <memory> -#include <string> -#include <utility> - -#include "base/i18n/break_iterator.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/renderer/spellchecker/spellcheck.h" -#include "third_party/icu/source/common/unicode/normlzr.h" -#include "third_party/icu/source/common/unicode/schriter.h" -#include "third_party/icu/source/common/unicode/uscript.h" -#include "third_party/icu/source/i18n/unicode/ulocdata.h" - -using base::i18n::BreakIterator; - -// SpellcheckCharAttribute implementation: - -SpellcheckCharAttribute::SpellcheckCharAttribute() - : script_code_(USCRIPT_LATIN) { -} - -SpellcheckCharAttribute::~SpellcheckCharAttribute() { -} - -void SpellcheckCharAttribute::SetDefaultLanguage(const std::string& language) { - CreateRuleSets(language); -} - -base::string16 SpellcheckCharAttribute::GetRuleSet( - bool allow_contraction) const { - return allow_contraction ? - ruleset_allow_contraction_ : ruleset_disallow_contraction_; -} - -void SpellcheckCharAttribute::CreateRuleSets(const std::string& language) { - // The template for our custom rule sets, which is based on the word-break - // rules of ICU 4.0: - // <http://source.icu-project.org/repos/icu/icu/tags/release-4-0/source/data/brkitr/word.txt>. - // The major differences from the original one are listed below: - // * It discards comments in the original rules. - // * It discards characters not needed by our spellchecker (e.g. numbers, - // punctuation characters, Hiraganas, Katakanas, CJK Ideographs, and so on). - // * It allows customization of the $ALetter value (i.e. word characters). - // * It allows customization of the $ALetterPlus value (i.e. whether or not to - // use the dictionary data). - // * It allows choosing whether or not to split a text at contraction - // characters. - // This template only changes the forward-iteration rules. So, calling - // ubrk_prev() returns the same results as the original template. - static const char kRuleTemplate[] = - "!!chain;" - "$CR = [\\p{Word_Break = CR}];" - "$LF = [\\p{Word_Break = LF}];" - "$Newline = [\\p{Word_Break = Newline}];" - "$Extend = [\\p{Word_Break = Extend}];" - "$Format = [\\p{Word_Break = Format}];" - "$Katakana = [\\p{Word_Break = Katakana}];" - // Not all the characters in a given script are ALetter. - // For instance, U+05F4 is MidLetter. So, this may be - // better, but it leads to an empty set error in Thai. - // "$ALetter = [[\\p{script=%s}] & [\\p{Word_Break = ALetter}]];" - "$ALetter = [\\p{script=%s}%s];" - // U+0027 (single quote/apostrophe) is not in MidNumLet any more - // in UAX 29 rev 21 or later. For our purpose, U+0027 - // has to be treated as MidNumLet. ( http://crbug.com/364072 ) - "$MidNumLet = [\\p{Word_Break = MidNumLet} \\u0027];" - "$MidLetter = [\\p{Word_Break = MidLetter}%s];" - "$MidNum = [\\p{Word_Break = MidNum}];" - "$Numeric = [\\p{Word_Break = Numeric}];" - "$ExtendNumLet = [\\p{Word_Break = ExtendNumLet}];" - - "$Control = [\\p{Grapheme_Cluster_Break = Control}]; " - "%s" // ALetterPlus - - "$KatakanaEx = $Katakana ($Extend | $Format)*;" - "$ALetterEx = $ALetterPlus ($Extend | $Format)*;" - "$MidNumLetEx = $MidNumLet ($Extend | $Format)*;" - "$MidLetterEx = $MidLetter ($Extend | $Format)*;" - "$MidNumEx = $MidNum ($Extend | $Format)*;" - "$NumericEx = $Numeric ($Extend | $Format)*;" - "$ExtendNumLetEx = $ExtendNumLet ($Extend | $Format)*;" - - "$Hiragana = [\\p{script=Hiragana}];" - "$Ideographic = [\\p{Ideographic}];" - "$HiraganaEx = $Hiragana ($Extend | $Format)*;" - "$IdeographicEx = $Ideographic ($Extend | $Format)*;" - - "!!forward;" - "$CR $LF;" - "[^$CR $LF $Newline]? ($Extend | $Format)+;" - "$ALetterEx {200};" - "$ALetterEx $ALetterEx {200};" - "%s" // (Allow|Disallow) Contraction - - "!!reverse;" - "$BackALetterEx = ($Format | $Extend)* $ALetterPlus;" - "$BackMidNumLetEx = ($Format | $Extend)* $MidNumLet;" - "$BackNumericEx = ($Format | $Extend)* $Numeric;" - "$BackMidNumEx = ($Format | $Extend)* $MidNum;" - "$BackMidLetterEx = ($Format | $Extend)* $MidLetter;" - "$BackKatakanaEx = ($Format | $Extend)* $Katakana;" - "$BackExtendNumLetEx= ($Format | $Extend)* $ExtendNumLet;" - "$LF $CR;" - "($Format | $Extend)* [^$CR $LF $Newline]?;" - "$BackALetterEx $BackALetterEx;" - "$BackALetterEx ($BackMidLetterEx | $BackMidNumLetEx) $BackALetterEx;" - "$BackNumericEx $BackNumericEx;" - "$BackNumericEx $BackALetterEx;" - "$BackALetterEx $BackNumericEx;" - "$BackNumericEx ($BackMidNumEx | $BackMidNumLetEx) $BackNumericEx;" - "$BackKatakanaEx $BackKatakanaEx;" - "$BackExtendNumLetEx ($BackALetterEx | $BackNumericEx |" - " $BackKatakanaEx | $BackExtendNumLetEx);" - "($BackALetterEx | $BackNumericEx | $BackKatakanaEx)" - " $BackExtendNumLetEx;" - - "!!safe_reverse;" - "($Extend | $Format)+ .?;" - "($MidLetter | $MidNumLet) $BackALetterEx;" - "($MidNum | $MidNumLet) $BackNumericEx;" - - "!!safe_forward;" - "($Extend | $Format)+ .?;" - "($MidLetterEx | $MidNumLetEx) $ALetterEx;" - "($MidNumEx | $MidNumLetEx) $NumericEx;"; - - // Retrieve the script codes used by the given language from ICU. When the - // given language consists of two or more scripts, we just use the first - // script. The size of returned script codes is always < 8. Therefore, we use - // an array of size 8 so we can include all script codes without insufficient - // buffer errors. - UErrorCode error = U_ZERO_ERROR; - UScriptCode script_code[8]; - int scripts = uscript_getCode(language.c_str(), script_code, - arraysize(script_code), &error); - if (U_SUCCESS(error) && scripts >= 1) - script_code_ = script_code[0]; - - // Retrieve the values for $ALetter and $ALetterPlus. We use the dictionary - // only for the languages which need it (i.e. Korean and Thai) to prevent ICU - // from returning dictionary words (i.e. Korean or Thai words) for languages - // which don't need them. - const char* aletter = uscript_getName(script_code_); - if (!aletter) - aletter = "Latin"; - - const char kWithDictionary[] = - "$dictionary = [:LineBreak = Complex_Context:];" - "$ALetterPlus = [$ALetter [$dictionary-$Extend-$Control]];"; - const char kWithoutDictionary[] = "$ALetterPlus = $ALetter;"; - const char* aletter_plus = kWithoutDictionary; - if (script_code_ == USCRIPT_HANGUL || script_code_ == USCRIPT_THAI || - script_code_ == USCRIPT_LAO || script_code_ == USCRIPT_KHMER) - aletter_plus = kWithDictionary; - - // Treat numbers as word characters except for Arabic and Hebrew. - const char* aletter_extra = " [0123456789]"; - if (script_code_ == USCRIPT_HEBREW) - aletter_extra = ""; - else if (script_code_ == USCRIPT_ARABIC) - // When "script=Arabic", it does not include tatweel, which is - // "script=Common" so add it back. Otherwise, it creates unwanted - // word breaks. - aletter_extra = " [\\u0640]"; - - const char kMidLetterExtra[] = ""; - // For Hebrew, treat single/double quoation marks as MidLetter. - const char kMidLetterExtraHebrew[] = "\"'"; - const char* midletter_extra = kMidLetterExtra; - if (script_code_ == USCRIPT_HEBREW) - midletter_extra = kMidLetterExtraHebrew; - - // Create two custom rule-sets: one allows contraction and the other does not. - // We save these strings in UTF-16 so we can use it without conversions. (ICU - // needs UTF-16 strings.) - const char kAllowContraction[] = - "$ALetterEx ($MidLetterEx | $MidNumLetEx) $ALetterEx {200};"; - const char kDisallowContraction[] = ""; - - ruleset_allow_contraction_ = base::ASCIIToUTF16( - base::StringPrintf(kRuleTemplate, - aletter, - aletter_extra, - midletter_extra, - aletter_plus, - kAllowContraction)); - ruleset_disallow_contraction_ = base::ASCIIToUTF16( - base::StringPrintf(kRuleTemplate, - aletter, - aletter_extra, - midletter_extra, - aletter_plus, - kDisallowContraction)); -} - -bool SpellcheckCharAttribute::OutputChar(UChar c, - base::string16* output) const { - // Call the language-specific function if necessary. - // Otherwise, we call the default one. - switch (script_code_) { - case USCRIPT_ARABIC: - return OutputArabic(c, output); - - case USCRIPT_HANGUL: - return OutputHangul(c, output); - - case USCRIPT_HEBREW: - return OutputHebrew(c, output); - - default: - return OutputDefault(c, output); - } -} - -bool SpellcheckCharAttribute::OutputArabic(UChar c, - base::string16* output) const { - // Include non-Arabic characters (which should trigger a spelling error) - // and Arabic characters excluding vowel marks and class "Lm". - // We filter the latter because, while they are "letters", they are - // optional and so don't affect the correctness of the rest of the word. - if (!(0x0600 <= c && c <= 0x06FF) || (u_isalpha(c) && c != 0x0640)) - output->push_back(c); - return true; -} - -bool SpellcheckCharAttribute::OutputHangul(UChar c, - base::string16* output) const { - // Decompose a Hangul character to a Hangul vowel and consonants used by our - // spellchecker. A Hangul character of Unicode is a ligature consisting of a - // Hangul vowel and consonants, e.g. U+AC01 "Gag" consists of U+1100 "G", - // U+1161 "a", and U+11A8 "g". That is, we can treat each Hangul character as - // a point of a cubic linear space consisting of (first consonant, vowel, last - // consonant). Therefore, we can compose a Hangul character from a vowel and - // two consonants with linear composition: - // character = 0xAC00 + - // (first consonant - 0x1100) * 28 * 21 + - // (vowel - 0x1161) * 28 + - // (last consonant - 0x11A7); - // We can also decompose a Hangul character with linear decomposition: - // first consonant = (character - 0xAC00) / 28 / 21; - // vowel = (character - 0xAC00) / 28 % 21; - // last consonant = (character - 0xAC00) % 28; - // This code is copied from Unicode Standard Annex #15 - // <http://unicode.org/reports/tr15> and added some comments. - const int kSBase = 0xAC00; // U+AC00: the top of Hangul characters. - const int kLBase = 0x1100; // U+1100: the top of Hangul first consonants. - const int kVBase = 0x1161; // U+1161: the top of Hangul vowels. - const int kTBase = 0x11A7; // U+11A7: the top of Hangul last consonants. - const int kLCount = 19; // The number of Hangul first consonants. - const int kVCount = 21; // The number of Hangul vowels. - const int kTCount = 28; // The number of Hangul last consonants. - const int kNCount = kVCount * kTCount; - const int kSCount = kLCount * kNCount; - - int index = c - kSBase; - if (index < 0 || index >= kSBase + kSCount) { - // This is not a Hangul syllable. Call the default output function since we - // should output this character when it is a Hangul syllable. - return OutputDefault(c, output); - } - - // This is a Hangul character. Decompose this characters into Hangul vowels - // and consonants. - int l = kLBase + index / kNCount; - int v = kVBase + (index % kNCount) / kTCount; - int t = kTBase + index % kTCount; - output->push_back(l); - output->push_back(v); - if (t != kTBase) - output->push_back(t); - return true; -} - -bool SpellcheckCharAttribute::OutputHebrew(UChar c, - base::string16* output) const { - // Discard characters except Hebrew alphabets. We also discard Hebrew niqquds - // to prevent our Hebrew dictionary from marking a Hebrew word including - // niqquds as misspelled. (Same as Arabic vowel marks, we need to check - // niqquds manually and filter them out since their script codes are - // USCRIPT_HEBREW.) - // Pass through ASCII single/double quotation marks and Hebrew Geresh and - // Gershayim. - if ((0x05D0 <= c && c <= 0x05EA) || c == 0x22 || c == 0x27 || - c == 0x05F4 || c == 0x05F3) - output->push_back(c); - return true; -} - -bool SpellcheckCharAttribute::OutputDefault(UChar c, - base::string16* output) const { - // Check the script code of this character and output only if it is the one - // used by the spellchecker language. - UErrorCode status = U_ZERO_ERROR; - UScriptCode script_code = uscript_getScript(c, &status); - if (script_code == script_code_ || script_code == USCRIPT_COMMON) - output->push_back(c); - return true; -} - -// SpellcheckWordIterator implementation: - -SpellcheckWordIterator::SpellcheckWordIterator() - : text_(NULL), - attribute_(NULL), - iterator_() { -} - -SpellcheckWordIterator::~SpellcheckWordIterator() { - Reset(); -} - -bool SpellcheckWordIterator::Initialize( - const SpellcheckCharAttribute* attribute, - bool allow_contraction) { - // Create a custom ICU break iterator with empty text used in this object. (We - // allow setting text later so we can re-use this iterator.) - DCHECK(attribute); - const base::string16 rule(attribute->GetRuleSet(allow_contraction)); - - // If there is no rule set, the attributes were invalid. - if (rule.empty()) - return false; - - std::unique_ptr<BreakIterator> iterator( - new BreakIterator(base::string16(), rule)); - if (!iterator->Init()) { - // Since we're not passing in any text, the only reason this could fail - // is if we fail to parse the rules. Since the rules are hardcoded, - // that would be a bug in this class. - NOTREACHED() << "failed to open iterator (broken rules)"; - return false; - } - iterator_ = std::move(iterator); - - // Set the character attributes so we can normalize the words extracted by - // this iterator. - attribute_ = attribute; - return true; -} - -bool SpellcheckWordIterator::IsInitialized() const { - // Return true iff we have an iterator. - return !!iterator_; -} - -bool SpellcheckWordIterator::SetText(const base::char16* text, size_t length) { - DCHECK(!!iterator_); - - // Set the text to be split by this iterator. - if (!iterator_->SetText(text, length)) { - LOG(ERROR) << "failed to set text"; - return false; - } - - text_ = text; - return true; -} - -SpellcheckWordIterator::WordIteratorStatus SpellcheckWordIterator::GetNextWord( - base::string16* word_string, - int* word_start, - int* word_length) { - DCHECK(!!text_); - - word_string->clear(); - *word_start = 0; - *word_length = 0; - - if (!text_) { - return IS_END_OF_TEXT; - } - - // Find a word that can be checked for spelling or a character that can be - // skipped over. Rather than moving past a skippable character this returns - // IS_SKIPPABLE and defers handling the character to the calling function. - while (iterator_->Advance()) { - const size_t start = iterator_->prev(); - const size_t length = iterator_->pos() - start; - switch (iterator_->GetWordBreakStatus()) { - case BreakIterator::IS_WORD_BREAK: { - if (Normalize(start, length, word_string)) { - *word_start = start; - *word_length = length; - return IS_WORD; - } - break; - } - case BreakIterator::IS_SKIPPABLE_WORD: { - *word_string = iterator_->GetString(); - *word_start = start; - *word_length = length; - return IS_SKIPPABLE; - } - // |iterator_| is RULE_BASED so the break status should never be - // IS_LINE_OR_CHAR_BREAK. - case BreakIterator::IS_LINE_OR_CHAR_BREAK: { - NOTREACHED(); - break; - } - } - } - - // There aren't any more words in the given text. - return IS_END_OF_TEXT; -} - -void SpellcheckWordIterator::Reset() { - iterator_.reset(); -} - -bool SpellcheckWordIterator::Normalize(int input_start, - int input_length, - base::string16* output_string) const { - // We use NFKC (Normalization Form, Compatible decomposition, followed by - // canonical Composition) defined in Unicode Standard Annex #15 to normalize - // this token because it it the most suitable normalization algorithm for our - // spellchecker. Nevertheless, it is not a perfect algorithm for our - // spellchecker and we need manual normalization as well. The normalized - // text does not have to be NUL-terminated since its characters are copied to - // string16, which adds a NUL character when we need. - icu::UnicodeString input(FALSE, &text_[input_start], input_length); - UErrorCode status = U_ZERO_ERROR; - icu::UnicodeString output; - icu::Normalizer::normalize(input, UNORM_NFKC, 0, output, status); - if (status != U_ZERO_ERROR && status != U_STRING_NOT_TERMINATED_WARNING) - return false; - - // Copy the normalized text to the output. - icu::StringCharacterIterator it(output); - for (UChar c = it.first(); c != icu::CharacterIterator::DONE; c = it.next()) - attribute_->OutputChar(c, output_string); - - return !output_string->empty(); -}
diff --git a/chrome/renderer/spellchecker/spellcheck_worditerator.h b/chrome/renderer/spellchecker/spellcheck_worditerator.h deleted file mode 100644 index be40e98..0000000 --- a/chrome/renderer/spellchecker/spellcheck_worditerator.h +++ /dev/null
@@ -1,200 +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. - -// Defines an iterator class that enumerates words supported by our spellchecker -// from multi-language text. This class is used for filtering out characters -// not supported by our spellchecker. - -#ifndef CHROME_RENDERER_SPELLCHECKER_SPELLCHECK_WORDITERATOR_H_ -#define CHROME_RENDERER_SPELLCHECKER_SPELLCHECK_WORDITERATOR_H_ - -#include <stddef.h> - -#include <memory> -#include <string> - -#include "base/macros.h" -#include "base/strings/string16.h" -#include "third_party/icu/source/common/unicode/uscript.h" - -namespace base { -namespace i18n { -class BreakIterator; -} // namespace i18n -} // namespace base - -// A class which encapsulates language-specific operations used by -// SpellcheckWordIterator. When we set the spellchecker language, this class -// creates rule sets that filter out the characters not supported by the -// spellchecker. (Please read the comment in the SpellcheckWordIterator class -// about how to use this class.) -class SpellcheckCharAttribute { - public: - SpellcheckCharAttribute(); - ~SpellcheckCharAttribute(); - - // Sets the language of the spellchecker. When this function is called with an - // ISO language code, this function creates the custom rule-sets used by - // the ICU break iterator so it can extract only words used by the language. - // GetRuleSet() returns the rule-sets created in this function. - void SetDefaultLanguage(const std::string& language); - - // Returns a custom rule-set string used by the ICU break iterator. This class - // has two rule-sets, one splits a contraction and the other does not, so we - // can split a concaticated word (e.g. "seven-year-old") into words (e.g. - // "seven", "year", and "old") and check their spellings. The result stirng is - // encoded in UTF-16 since ICU needs UTF-16 strings. - base::string16 GetRuleSet(bool allow_contraction) const; - - // Outputs a character only if it is a word character. (Please read the - // comments in CreateRuleSets() why we need this function.) - bool OutputChar(UChar c, base::string16* output) const; - - private: - // Creates the rule-sets that return words possibly used by the given - // language. Unfortunately, these rule-sets are not perfect and have some - // false-positives. For example, they return combined accent marks even though - // we need English words only. We call OutputCharacter() to filter out such - // false-positive characters. - void CreateRuleSets(const std::string& language); - - // Outputs a character only if it is one used by the given language. These - // functions are called from OutputChar(). - bool OutputArabic(UChar c, base::string16* output) const; - bool OutputHangul(UChar c, base::string16* output) const; - bool OutputHebrew(UChar c, base::string16* output) const; - bool OutputDefault(UChar c, base::string16* output) const; - - // The custom rule-set strings used by ICU break iterator. Since it is not so - // easy to create custom rule-sets from an ISO language code, this class - // saves these rule-set strings created when we set the language. - base::string16 ruleset_allow_contraction_; - base::string16 ruleset_disallow_contraction_; - - // The script code used by this language. - UScriptCode script_code_; - - DISALLOW_COPY_AND_ASSIGN(SpellcheckCharAttribute); -}; - -// A class which extracts words that can be checked for spelling from a -// multi-language string. The ICU word-break iterator does not discard some -// punctuation characters attached to a word. For example, when we set a word -// "_hello_" to a word-break iterator, it just returns "_hello_". Neither does -// it discard characters not used by the language. For example, it returns -// Russian words even though we need English words only. To extract only the -// words that our spellchecker can check their spellings, this class uses custom -// rule-sets created by the SpellcheckCharAttribute class. Also, this class -// normalizes extracted words so our spellchecker can check the spellings of -// words that include ligatures, combined characters, full-width characters, -// etc. This class uses UTF-16 strings as its input and output strings since -// UTF-16 is the native encoding of ICU and avoid unnecessary conversions -// when changing the encoding of this string for our spellchecker. (Chrome can -// use two or more spellcheckers and we cannot assume their encodings.) -// The following snippet is an example that extracts words with this class. -// -// // Creates the language-specific attributes for US English. -// SpellcheckCharAttribute attribute; -// attribute.SetDefaultLanguage("en-US"); -// -// // Set up a SpellcheckWordIterator object which extracts English words, -// // and retrieve them. -// SpellcheckWordIterator iterator; -// base::string16 text(base::UTF8ToUTF16("this is a test.")); -// iterator.Initialize(&attribute, true); -// iterator.SetText(text.c_str(), text_.length()); -// -// base::string16 word; -// int offset; -// int length; -// while (iterator.GetNextWord(&word, &offset, &length)) { -// ... -// } -// -class SpellcheckWordIterator { - public: - enum WordIteratorStatus { - // The end of a sequence of text that the iterator recognizes as characters - // that can form a word. - IS_WORD, - // Non-word characters that the iterator can skip past, such as punctuation, - // whitespace, and characters from another character set. - IS_SKIPPABLE, - // The end of the text that the iterator is going over. - IS_END_OF_TEXT - }; - - SpellcheckWordIterator(); - ~SpellcheckWordIterator(); - - // Initializes a word-iterator object with the language-specific attribute. If - // we need to split contractions and concatenated words, call this function - // with its 'allow_contraction' parameter false. (This function uses lots of - // temporal memory to compile a custom word-break rule into an automaton.) - bool Initialize(const SpellcheckCharAttribute* attribute, - bool allow_contraction); - - // Returns whether this word iterator is initialized. - bool IsInitialized() const; - - // Set text to be iterated. (This text does not have to be NULL-terminated.) - // This function also resets internal state so we can reuse this iterator - // without calling Initialize(). - bool SetText(const base::char16* text, size_t length); - - // Advances |iterator_| through |text_| and gets the current status of the - // word iterator within |text|: - // - // - Returns IS_WORD if the iterator just found the end of a sequence of word - // characters and it was able to normalize the sequence. This stores the - // normalized string into |word_string| and stores the position and length - // into |word_start| and |word_length| respectively. Keep in mind that - // since this function normalizes the output word, the length of - // |word_string| may be different from the |word_length|. Therefore, when - // we call functions that change the input text, such as - // string16::replace(), we need to use |word_start| and |word_length| as - // listed in the following snippet: - // - // while(iterator.GetNextWord(&word, &offset, &length)) - // text.replace(offset, length, word); - // - // - Returns IS_SKIPPABLE if the iterator just found a character that the - // iterator can skip past such as punctuation, whitespace, and characters - // from another character set. This stores the character, position, and - // length into |word_string|, |word_start|, and |word_length| respectively. - // - // - Returns IS_END_OF_TEXT if the iterator has reached the end of |text_|. - SpellcheckWordIterator::WordIteratorStatus - GetNextWord(base::string16* word_string, int* word_start, int* word_length); - - // Releases all the resources attached to this object. - void Reset(); - - private: - // Normalizes a non-terminated string returned from an ICU word-break - // iterator. A word returned from an ICU break iterator may include characters - // not supported by our spellchecker, e.g. ligatures, combining/ characters, - // full-width letters, etc. This function replaces such characters with - // alternative characters supported by our spellchecker. This function also - // calls SpellcheckWordIterator::OutputChar() to filter out false-positive - // characters. - bool Normalize(int input_start, - int input_length, - base::string16* output_string) const; - - // The pointer to the input string from which we are extracting words. - const base::char16* text_; - - // The language-specific attributes used for filtering out non-word - // characters. - const SpellcheckCharAttribute* attribute_; - - // The break iterator. - std::unique_ptr<base::i18n::BreakIterator> iterator_; - - DISALLOW_COPY_AND_ASSIGN(SpellcheckWordIterator); -}; - -#endif // CHROME_RENDERER_SPELLCHECKER_SPELLCHECK_WORDITERATOR_H_ -
diff --git a/chrome/renderer/spellchecker/spellcheck_worditerator_unittest.cc b/chrome/renderer/spellchecker/spellcheck_worditerator_unittest.cc deleted file mode 100644 index ff4c4673..0000000 --- a/chrome/renderer/spellchecker/spellcheck_worditerator_unittest.cc +++ /dev/null
@@ -1,508 +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 <stddef.h> - -#include <string> -#include <vector> - -#include "base/format_macros.h" -#include "base/i18n/break_iterator.h" -#include "base/macros.h" -#include "base/strings/string_split.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/renderer/spellchecker/spellcheck_worditerator.h" -#include "testing/gtest/include/gtest/gtest.h" - -using base::i18n::BreakIterator; -using WordIteratorStatus = SpellcheckWordIterator::WordIteratorStatus; - -namespace { - -struct TestCase { - const char* language; - bool allow_contraction; - const wchar_t* expected_words; -}; - -base::string16 GetRulesForLanguage(const std::string& language) { - SpellcheckCharAttribute attribute; - attribute.SetDefaultLanguage(language); - return attribute.GetRuleSet(true); -} - -WordIteratorStatus GetNextNonSkippableWord(SpellcheckWordIterator* iterator, - base::string16* word_string, - int* word_start, - int* word_length) { - WordIteratorStatus status = SpellcheckWordIterator::IS_SKIPPABLE; - while (status == SpellcheckWordIterator::IS_SKIPPABLE) - status = iterator->GetNextWord(word_string, word_start, word_length); - return status; -} - -} // namespace - -// Tests whether or not our SpellcheckWordIterator can extract words used by the -// specified language from a multi-language text. -TEST(SpellcheckWordIteratorTest, SplitWord) { - // An input text. This text includes words of several languages. (Some words - // are not separated with whitespace characters.) Our SpellcheckWordIterator - // should extract the words used by the specified language from this text and - // normalize them so our spell-checker can check their spellings. If - // characters are found that are not from the specified language the test - // skips them. - const wchar_t kTestText[] = - // Graphic characters - L"!@#$%^&*()" - // Latin (including a contraction character and a ligature). - L"hello:hello a\xFB03x" - // Greek - L"\x03B3\x03B5\x03B9\x03AC\x0020\x03C3\x03BF\x03C5" - // Cyrillic - L"\x0437\x0434\x0440\x0430\x0432\x0441\x0442\x0432" - L"\x0443\x0439\x0442\x0435" - // Hebrew (including niqquds) - L"\x05e9\x05c1\x05b8\x05dc\x05d5\x05b9\x05dd " - // Hebrew words with U+0027 and U+05F3 - L"\x05e6\x0027\x05d9\x05e4\x05e1 \x05e6\x05F3\x05d9\x05e4\x05e1 " - // Hebrew words with U+0022 and U+05F4 - L"\x05e6\x05d4\x0022\x05dc \x05e6\x05d4\x05f4\x05dc " - // Hebrew words enclosed with ASCII quotes. - L"\"\x05e6\x05d4\x0022\x05dc\" '\x05e9\x05c1\x05b8\x05dc\x05d5'" - // Arabic (including vowel marks) - L"\x0627\x064e\x0644\x0633\x064e\x0651\x0644\x0627\x0645\x064f " - L"\x0639\x064e\x0644\x064e\x064a\x0652\x0643\x064f\x0645\x0652 " - // Farsi/Persian (including vowel marks) - // Make sure \u064b - \u0652 are removed. - L"\x0647\x0634\x064e\x0631\x062d " - L"\x0647\x062e\x0648\x0627\x0647 " - L"\x0650\x062f\x0631\x062f " - L"\x0631\x0645\x0627\x0646\x0652 " - L"\x0633\x0631\x0651 " - L"\x0646\x0646\x064e\x062c\x064f\x0633 " - L"\x0627\x0644\x062d\x0645\x062f " - // Also make sure that class "Lm" (the \u0640) is filtered out too. - L"\x062c\x062c\x0640\x062c\x062c" - // Hindi - L"\x0930\x093E\x091C\x0927\x093E\x0928" - // Thai - L"\x0e2a\x0e27\x0e31\x0e2a\x0e14\x0e35\x0020\x0e04" - L"\x0e23\x0e31\x0e1a" - // Hiraganas - L"\x3053\x3093\x306B\x3061\x306F" - // CJKV ideographs - L"\x4F60\x597D" - // Hangul Syllables - L"\xC548\xB155\xD558\xC138\xC694" - // Full-width latin : Hello - L"\xFF28\xFF45\xFF4C\xFF4C\xFF4F " - L"e.g.,"; - - // The languages and expected results used in this test. - static const TestCase kTestCases[] = { - { - // English (keep contraction words) - "en-US", true, L"hello:hello affix Hello e.g" - }, { - // English (split contraction words) - "en-US", false, L"hello hello affix Hello e g" - }, { - // Greek - "el-GR", true, - L"\x03B3\x03B5\x03B9\x03AC\x0020\x03C3\x03BF\x03C5" - }, { - // Russian - "ru-RU", true, - L"\x0437\x0434\x0440\x0430\x0432\x0441\x0442\x0432" - L"\x0443\x0439\x0442\x0435" - }, { - // Hebrew - "he-IL", true, - L"\x05e9\x05dc\x05d5\x05dd " - L"\x05e6\x0027\x05d9\x05e4\x05e1 \x05e6\x05F3\x05d9\x05e4\x05e1 " - L"\x05e6\x05d4\x0022\x05dc \x05e6\x05d4\x05f4\x05dc " - L"\x05e6\x05d4\x0022\x05dc \x05e9\x05dc\x05d5" - }, { - // Arabic - "ar", true, - L"\x0627\x0644\x0633\x0644\x0627\x0645 " - L"\x0639\x0644\x064a\x0643\x0645 " - // Farsi/Persian - L"\x0647\x0634\x0631\x062d " - L"\x0647\x062e\x0648\x0627\x0647 " - L"\x062f\x0631\x062f " - L"\x0631\x0645\x0627\x0646 " - L"\x0633\x0631 " - L"\x0646\x0646\x062c\x0633 " - L"\x0627\x0644\x062d\x0645\x062f " - L"\x062c\x062c\x062c\x062c" - }, { - // Hindi - "hi-IN", true, - L"\x0930\x093E\x091C\x0927\x093E\x0928" - }, { - // Thai - "th-TH", true, - L"\x0e2a\x0e27\x0e31\x0e2a\x0e14\x0e35\x0020\x0e04" - L"\x0e23\x0e31\x0e1a" - }, { - // Korean - "ko-KR", true, - L"\x110b\x1161\x11ab\x1102\x1167\x11bc\x1112\x1161" - L"\x1109\x1166\x110b\x116d" - }, - }; - - for (size_t i = 0; i < arraysize(kTestCases); ++i) { - SCOPED_TRACE(base::StringPrintf("kTestCases[%" PRIuS "]: language=%s", i, - kTestCases[i].language)); - - SpellcheckCharAttribute attributes; - attributes.SetDefaultLanguage(kTestCases[i].language); - - base::string16 input(base::WideToUTF16(kTestText)); - SpellcheckWordIterator iterator; - EXPECT_TRUE(iterator.Initialize(&attributes, - kTestCases[i].allow_contraction)); - EXPECT_TRUE(iterator.SetText(input.c_str(), input.length())); - - std::vector<base::string16> expected_words = base::SplitString( - base::WideToUTF16(kTestCases[i].expected_words), - base::string16(1, ' '), base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); - - base::string16 actual_word; - int actual_start, actual_len; - size_t index = 0; - for (SpellcheckWordIterator::WordIteratorStatus status = - iterator.GetNextWord(&actual_word, &actual_start, &actual_len); - status != SpellcheckWordIterator::IS_END_OF_TEXT; - status = - iterator.GetNextWord(&actual_word, &actual_start, &actual_len)) { - if (status == SpellcheckWordIterator::WordIteratorStatus::IS_SKIPPABLE) - continue; - - EXPECT_TRUE(index < expected_words.size()); - if (index < expected_words.size()) - EXPECT_EQ(expected_words[index], actual_word); - ++index; - } - } -} - -// Tests whether our SpellcheckWordIterator extracts an empty word without -// getting stuck in an infinite loop when inputting a Khmer text. (This is a -// regression test for Issue 46278.) -TEST(SpellcheckWordIteratorTest, RuleSetConsistency) { - SpellcheckCharAttribute attributes; - attributes.SetDefaultLanguage("en-US"); - - const wchar_t kTestText[] = L"\x1791\x17c1\x002e"; - base::string16 input(base::WideToUTF16(kTestText)); - - SpellcheckWordIterator iterator; - EXPECT_TRUE(iterator.Initialize(&attributes, true)); - EXPECT_TRUE(iterator.SetText(input.c_str(), input.length())); - - // When SpellcheckWordIterator uses an inconsistent ICU ruleset, the following - // iterator.GetNextWord() calls get stuck in an infinite loop. Therefore, this - // test succeeds if this call returns without timeouts. - base::string16 actual_word; - int actual_start, actual_len; - WordIteratorStatus status = GetNextNonSkippableWord( - &iterator, &actual_word, &actual_start, &actual_len); - - EXPECT_EQ(SpellcheckWordIterator::WordIteratorStatus::IS_END_OF_TEXT, status); - EXPECT_EQ(0, actual_start); - EXPECT_EQ(0, actual_len); -} - -// Vertify our SpellcheckWordIterator can treat ASCII numbers as word characters -// on LTR languages. On the other hand, it should not treat ASCII numbers as -// word characters on RTL languages because they change the text direction from -// RTL to LTR. -TEST(SpellcheckWordIteratorTest, TreatNumbersAsWordCharacters) { - // A set of a language, a dummy word, and a text direction used in this test. - // For each language, this test splits a dummy word, which consists of ASCII - // numbers and an alphabet of the language, into words. When ASCII numbers are - // treated as word characters, the split word becomes equal to the dummy word. - // Otherwise, the split word does not include ASCII numbers. - static const struct { - const char* language; - const wchar_t* text; - bool left_to_right; - } kTestCases[] = { - { - // English - "en-US", L"0123456789" L"a", true, - }, { - // Greek - "el-GR", L"0123456789" L"\x03B1", true, - }, { - // Russian - "ru-RU", L"0123456789" L"\x0430", true, - }, { - // Hebrew - "he-IL", L"0123456789" L"\x05D0", false, - }, { - // Arabic - "ar", L"0123456789" L"\x0627", false, - }, { - // Hindi - "hi-IN", L"0123456789" L"\x0905", true, - }, { - // Thai - "th-TH", L"0123456789" L"\x0e01", true, - }, { - // Korean - "ko-KR", L"0123456789" L"\x1100\x1161", true, - }, - }; - - for (size_t i = 0; i < arraysize(kTestCases); ++i) { - SCOPED_TRACE(base::StringPrintf("kTestCases[%" PRIuS "]: language=%s", i, - kTestCases[i].language)); - - SpellcheckCharAttribute attributes; - attributes.SetDefaultLanguage(kTestCases[i].language); - - base::string16 input_word(base::WideToUTF16(kTestCases[i].text)); - SpellcheckWordIterator iterator; - EXPECT_TRUE(iterator.Initialize(&attributes, true)); - EXPECT_TRUE(iterator.SetText(input_word.c_str(), input_word.length())); - - base::string16 actual_word; - int actual_start, actual_len; - WordIteratorStatus status = GetNextNonSkippableWord( - &iterator, &actual_word, &actual_start, &actual_len); - - EXPECT_EQ(SpellcheckWordIterator::WordIteratorStatus::IS_WORD, status); - if (kTestCases[i].left_to_right) - EXPECT_EQ(input_word, actual_word); - else - EXPECT_NE(input_word, actual_word); - } -} - -// Verify SpellcheckWordIterator treats typographical apostrophe as a part of -// the word. -TEST(SpellcheckWordIteratorTest, TypographicalApostropheIsPartOfWord) { - static const struct { - const char* language; - const wchar_t* input; - const wchar_t* expected; - } kTestCases[] = { - // Typewriter apostrophe: - {"en-AU", L"you're", L"you're"}, - {"en-CA", L"you're", L"you're"}, - {"en-GB", L"you're", L"you're"}, - {"en-US", L"you're", L"you're"}, - {"en-US", L"!!!!you're", L"you're"}, - // Typographical apostrophe: - {"en-AU", L"you\x2019re", L"you\x2019re"}, - {"en-CA", L"you\x2019re", L"you\x2019re"}, - {"en-GB", L"you\x2019re", L"you\x2019re"}, - {"en-US", L"you\x2019re", L"you\x2019re"}, - {"en-US", L"....you\x2019re", L"you\x2019re"}, - }; - - for (size_t i = 0; i < arraysize(kTestCases); ++i) { - SpellcheckCharAttribute attributes; - attributes.SetDefaultLanguage(kTestCases[i].language); - - base::string16 input_word(base::WideToUTF16(kTestCases[i].input)); - base::string16 expected_word(base::WideToUTF16(kTestCases[i].expected)); - SpellcheckWordIterator iterator; - EXPECT_TRUE(iterator.Initialize(&attributes, true)); - EXPECT_TRUE(iterator.SetText(input_word.c_str(), input_word.length())); - - base::string16 actual_word; - int actual_start, actual_len; - WordIteratorStatus status = GetNextNonSkippableWord( - &iterator, &actual_word, &actual_start, &actual_len); - - EXPECT_EQ(SpellcheckWordIterator::WordIteratorStatus::IS_WORD, status); - EXPECT_EQ(expected_word, actual_word); - EXPECT_LE(0, actual_start); - EXPECT_EQ(expected_word.length(), - static_cast<base::string16::size_type>(actual_len)); - } -} - -TEST(SpellcheckWordIteratorTest, Initialization) { - // Test initialization works when a default language is set. - { - SpellcheckCharAttribute attributes; - attributes.SetDefaultLanguage("en-US"); - - SpellcheckWordIterator iterator; - EXPECT_TRUE(iterator.Initialize(&attributes, true)); - } - - // Test initialization fails when no default language is set. - { - SpellcheckCharAttribute attributes; - - SpellcheckWordIterator iterator; - EXPECT_FALSE(iterator.Initialize(&attributes, true)); - } -} - -// This test uses English rules to check that different character set -// combinations properly find word breaks and skippable characters. -TEST(SpellcheckWordIteratorTest, FindSkippableWordsEnglish) { - // A string containing the English word "foo", followed by two Khmer - // characters, the English word "Can", and then two Russian characters and - // punctuation. - base::string16 text( - base::WideToUTF16(L"foo \x1791\x17C1 Can \x041C\x0438...")); - BreakIterator iter(text, GetRulesForLanguage("en-US")); - ASSERT_TRUE(iter.Init()); - - EXPECT_TRUE(iter.Advance()); - // Finds "foo". - EXPECT_EQ(base::UTF8ToUTF16("foo"), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_WORD_BREAK); - EXPECT_TRUE(iter.Advance()); - // Finds the space and then the Khmer characters. - EXPECT_EQ(base::UTF8ToUTF16(" "), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - EXPECT_EQ(base::WideToUTF16(L"\x1791\x17C1"), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - // Finds the next space and "Can". - EXPECT_EQ(base::UTF8ToUTF16(" "), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - EXPECT_EQ(base::UTF8ToUTF16("Can"), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_WORD_BREAK); - EXPECT_TRUE(iter.Advance()); - // Finds the next space and each Russian character. - EXPECT_EQ(base::UTF8ToUTF16(" "), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - EXPECT_EQ(base::WideToUTF16(L"\x041C"), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - EXPECT_EQ(base::WideToUTF16(L"\x0438"), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - // Finds the periods at the end. - EXPECT_EQ(base::UTF8ToUTF16("."), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - EXPECT_EQ(base::UTF8ToUTF16("."), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - EXPECT_EQ(base::UTF8ToUTF16("."), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_FALSE(iter.Advance()); -} - -// This test uses Russian rules to check that different character set -// combinations properly find word breaks and skippable characters. -TEST(SpellcheckWordIteratorTest, FindSkippableWordsRussian) { - // A string containing punctuation followed by two Russian characters, the - // English word "Can", and then two Khmer characters. - base::string16 text(base::WideToUTF16(L".;\x041C\x0438 Can \x1791\x17C1 ")); - BreakIterator iter(text, GetRulesForLanguage("ru-RU")); - ASSERT_TRUE(iter.Init()); - - EXPECT_TRUE(iter.Advance()); - // Finds the period and semicolon. - EXPECT_EQ(base::UTF8ToUTF16("."), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - EXPECT_EQ(base::UTF8ToUTF16(";"), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - // Finds all the Russian characters. - EXPECT_EQ(base::WideToUTF16(L"\x041C\x0438"), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_WORD_BREAK); - EXPECT_TRUE(iter.Advance()); - // Finds the space and each character in "Can". - EXPECT_EQ(base::UTF8ToUTF16(" "), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - EXPECT_EQ(base::UTF8ToUTF16("C"), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - EXPECT_EQ(base::UTF8ToUTF16("a"), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - EXPECT_EQ(base::UTF8ToUTF16("n"), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - // Finds the next space, the Khmer characters, and the last two spaces. - EXPECT_EQ(base::UTF8ToUTF16(" "), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - EXPECT_EQ(base::WideToUTF16(L"\x1791\x17C1"), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - EXPECT_EQ(base::UTF8ToUTF16(" "), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - EXPECT_EQ(base::UTF8ToUTF16(" "), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_FALSE(iter.Advance()); -} - -// This test uses Khmer rules to check that different character set combinations -// properly find word breaks and skippable characters. Khmer does not use spaces -// between words and uses a dictionary to determine word breaks instead. -TEST(SpellcheckWordIteratorTest, FindSkippableWordsKhmer) { - // A string containing two Russian characters followed by two, three, and - // two-character Khmer words, and then English characters and punctuation. - base::string16 text(base::WideToUTF16( - L"\x041C\x0438 \x178F\x17BE\x179B\x17C4\x1780\x1798\x1780zoo. ,")); - BreakIterator iter(text, GetRulesForLanguage("km")); - ASSERT_TRUE(iter.Init()); - - EXPECT_TRUE(iter.Advance()); - // Finds each Russian character and the space. - EXPECT_EQ(base::WideToUTF16(L"\x041C"), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - EXPECT_EQ(base::WideToUTF16(L"\x0438"), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - EXPECT_EQ(base::UTF8ToUTF16(" "), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - // Finds the first two-character Khmer word. - EXPECT_EQ(base::WideToUTF16(L"\x178F\x17BE"), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_WORD_BREAK); - EXPECT_TRUE(iter.Advance()); - // Finds the three-character Khmer word and then the next two-character word. - // Note: Technically these are two different Khmer words so the Khmer language - // rule should find a break between them but due to the heuristic/statistical - // nature of the Khmer word breaker it does not. - EXPECT_EQ(base::WideToUTF16(L"\x179B\x17C4\x1780\x1798\x1780"), - iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_WORD_BREAK); - EXPECT_TRUE(iter.Advance()); - // Finds each character in "zoo". - EXPECT_EQ(base::UTF8ToUTF16("z"), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - EXPECT_EQ(base::UTF8ToUTF16("o"), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - EXPECT_EQ(base::UTF8ToUTF16("o"), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - // Finds the period, space, and comma. - EXPECT_EQ(base::UTF8ToUTF16("."), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - EXPECT_EQ(base::UTF8ToUTF16(" "), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_TRUE(iter.Advance()); - EXPECT_EQ(base::UTF8ToUTF16(","), iter.GetString()); - EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); - EXPECT_FALSE(iter.Advance()); -}
diff --git a/chrome/renderer/spellchecker/spelling_engine.h b/chrome/renderer/spellchecker/spelling_engine.h deleted file mode 100644 index 12e502d..0000000 --- a/chrome/renderer/spellchecker/spelling_engine.h +++ /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. - -#ifndef CHROME_RENDERER_SPELLCHECKER_SPELLING_ENGINE_H_ -#define CHROME_RENDERER_SPELLCHECKER_SPELLING_ENGINE_H_ - -#include <string> -#include <vector> - -#include "base/files/file.h" -#include "base/strings/string16.h" - -// Creates the platform's "native" spelling engine. -class SpellingEngine* CreateNativeSpellingEngine(); - -// Interface to different spelling engines. -class SpellingEngine { - public: - virtual ~SpellingEngine() {} - - // Initialize spelling engine with browser-side info. Must be called before - // any other functions are called. - virtual void Init(base::File bdict_file) = 0; - virtual bool InitializeIfNeeded() = 0; - virtual bool IsEnabled() = 0; - virtual bool CheckSpelling(const base::string16& word_to_check, int tag) = 0; - virtual void FillSuggestionList( - const base::string16& wrong_word, - std::vector<base::string16>* optional_suggestions) = 0; -}; - -#endif // CHROME_RENDERER_SPELLCHECKER_SPELLING_ENGINE_H_ -
diff --git a/chrome/service/cloud_print/cloud_print_service_helpers.cc b/chrome/service/cloud_print/cloud_print_service_helpers.cc index c3a3650..24833705 100644 --- a/chrome/service/cloud_print/cloud_print_service_helpers.cc +++ b/chrome/service/cloud_print/cloud_print_service_helpers.cc
@@ -82,7 +82,7 @@ } bool IsDryRunJob(const std::vector<std::string>& tags) { - return ContainsValue(tags, kCloudPrintServiceTagDryRunFlag); + return base::ContainsValue(tags, kCloudPrintServiceTagDryRunFlag); } std::string GetCloudPrintAuthHeaderFromStore() {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index b1c07cc..18c988c5 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -111,7 +111,7 @@ "//components/search_engines:test_support", "//components/signin/core/browser:test_support", "//components/sync", - "//components/sync_driver:test_support", + "//components/sync:test_support_sync_driver", "//components/sync_sessions:test_support", "//components/syncable_prefs:test_support", "//components/toolbar:test_support", @@ -1930,22 +1930,12 @@ ".", "//chrome") } + if (enable_spellcheck) { sources += rebase_path( chrome_tests_unit_gypi_values.chrome_unit_tests_spellchecker_sources, ".", "//chrome") - if (is_mac && !is_ios) { - deps += [ "//third_party/hunspell" ] - } - - if (is_android) { - sources -= [ - "../renderer/spellchecker/spellcheck_multilingual_unittest.cc", - "../renderer/spellchecker/spellcheck_provider_hunspell_unittest.cc", - "../renderer/spellchecker/spellcheck_unittest.cc", - ] - } } if (enable_one_click_signin) { @@ -2170,8 +2160,6 @@ "../browser/ui/tests/ui_gfx_image_unittest.cc", # This tests Chrome's spellchecker which Mac doesn't use. - "../renderer/spellchecker/spellcheck_multilingual_unittest.cc", - "../renderer/spellchecker/spellcheck_provider_hunspell_unittest.cc", "../tools/convert_dict/convert_dict_unittest.cc", ] @@ -2228,9 +2216,12 @@ ] } if (is_win) { - # The PDB gets too large for incremental linking. - configs -= [ "//build/config/win:default_incremental_linking" ] - configs += [ "//build/config/win:no_incremental_linking" ] + if (!is_component_build) { + # The PDB gets too large for incremental linking. + configs -= [ "//build/config/win:default_incremental_linking" ] + configs += + [ "//build/config/win:default_large_module_incremental_linking" ] + } sources += rebase_path(chrome_tests_unit_gypi_values.chrome_unit_tests_win_sources,
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java index bb4fa79..650e8c69 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestCaseBase.java
@@ -93,7 +93,7 @@ @CommandLineFlags.Add({ ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, // Preconnect causes issues with the single-threaded Java test server. - ChromeSwitches.DISABLE_PRECONNECT}) + "--disable-features=NetworkPrediction"}) public abstract class ChromeActivityTestCaseBase<T extends ChromeActivity> extends BaseActivityInstrumentationTestCase<T> {
diff --git a/chrome/test/base/chrome_process_util.cc b/chrome/test/base/chrome_process_util.cc index 61d6ef6..f09063b 100644 --- a/chrome/test/base/chrome_process_util.cc +++ b/chrome/test/base/chrome_process_util.cc
@@ -43,7 +43,7 @@ : parent_pids_(parent_pids.begin(), parent_pids.end()) {} bool Includes(const base::ProcessEntry& entry) const override { - return ContainsKey(parent_pids_, entry.parent_pid()); + return base::ContainsKey(parent_pids_, entry.parent_pid()); } private:
diff --git a/chrome/test/base/chrome_render_view_test.cc b/chrome/test/base/chrome_render_view_test.cc index 27bbff7..43565c3 100644 --- a/chrome/test/base/chrome_render_view_test.cc +++ b/chrome/test/base/chrome_render_view_test.cc
@@ -11,12 +11,12 @@ #include "chrome/browser/chrome_content_browser_client.h" #include "chrome/common/chrome_content_client.h" #include "chrome/renderer/chrome_content_renderer_client.h" -#include "chrome/renderer/spellchecker/spellcheck.h" #include "chrome/test/base/chrome_unit_test_suite.h" #include "components/autofill/content/renderer/autofill_agent.h" #include "components/autofill/content/renderer/password_autofill_agent.h" #include "components/autofill/content/renderer/test_password_autofill_agent.h" #include "components/autofill/content/renderer/test_password_generation_agent.h" +#include "components/spellcheck/renderer/spellcheck.h" #include "content/public/browser/native_web_keyboard_event.h" #include "content/public/common/renderer_preferences.h" #include "content/public/renderer/render_view.h"
diff --git a/chrome/test/base/test_launcher_utils.cc b/chrome/test/base/test_launcher_utils.cc index 3616ddb0..81f9ca4c 100644 --- a/chrome/test/base/test_launcher_utils.cc +++ b/chrome/test/base/test_launcher_utils.cc
@@ -8,6 +8,7 @@ #include "base/command_line.h" #include "base/environment.h" +#include "base/feature_list.h" #include "base/logging.h" #include "base/path_service.h" #include "base/strings/string_number_conversions.h" @@ -26,7 +27,8 @@ void PrepareBrowserCommandLineForTests(base::CommandLine* command_line) { // Turn off preconnects because they break the brittle python webserver; // see http://crbug.com/60035. - command_line->AppendSwitch(switches::kDisablePreconnect); + command_line->AppendSwitchASCII(switches::kDisableFeatures, + "NetworkPrediction"); // Don't show the first run ui. command_line->AppendSwitch(switches::kNoFirstRun);
diff --git a/chrome/test/base/ui_test_utils.cc b/chrome/test/base/ui_test_utils.cc index 6ebbd91..b3f7143 100644 --- a/chrome/test/base/ui_test_utils.cc +++ b/chrome/test/base/ui_test_utils.cc
@@ -97,7 +97,7 @@ BrowserAddedObserver observer; new_browser = observer.WaitForSingleNewBrowser(); // The new browser should never be in |excluded_browsers|. - DCHECK(!ContainsKey(excluded_browsers, new_browser)); + DCHECK(!base::ContainsKey(excluded_browsers, new_browser)); } return new_browser; }
diff --git a/chrome/test/chromedriver/chrome/device_manager.cc b/chrome/test/chromedriver/chrome/device_manager.cc index 7627f3fe1..f4705a7 100644 --- a/chrome/test/chromedriver/chrome/device_manager.cc +++ b/chrome/test/chromedriver/chrome/device_manager.cc
@@ -183,7 +183,7 @@ if (status.IsError()) return status; - if (!ContainsValue(devices, device_serial)) + if (!base::ContainsValue(devices, device_serial)) return Status(kUnknownError, "Device " + device_serial + " is not online"); @@ -211,5 +211,5 @@ } bool DeviceManager::IsDeviceLocked(const std::string& device_serial) { - return ContainsValue(active_devices_, device_serial); + return base::ContainsValue(active_devices_, device_serial); }
diff --git a/chrome/test/chromedriver/chrome/devtools_http_client.cc b/chrome/test/chromedriver/chrome/devtools_http_client.cc index 34023ae..ea1f1dd 100644 --- a/chrome/test/chromedriver/chrome/devtools_http_client.cc +++ b/chrome/test/chromedriver/chrome/devtools_http_client.cc
@@ -158,7 +158,7 @@ } bool DevToolsHttpClient::IsBrowserWindow(const WebViewInfo& view) const { - return ContainsKey(*window_types_, view.type) || + return base::ContainsKey(*window_types_, view.type) || (view.type == WebViewInfo::kOther && (base::StartsWith(view.url, "chrome-extension://", base::CompareCase::SENSITIVE) ||
diff --git a/chrome/test/chromedriver/chrome/stub_web_view.cc b/chrome/test/chromedriver/chrome/stub_web_view.cc index 53b1cef..43c7b47 100644 --- a/chrome/test/chromedriver/chrome/stub_web_view.cc +++ b/chrome/test/chromedriver/chrome/stub_web_view.cc
@@ -172,3 +172,15 @@ Status StubWebView::SynthesizePinchGesture(int x, int y, double scale_factor) { return Status(kOk); } + +Status StubWebView::GetScreenOrientation(std::string* orientation) { + return Status(kOk); +} + +Status StubWebView::SetScreenOrientation(std::string orientation) { + return Status(kOk); +} + +Status StubWebView::DeleteScreenOrientation() { + return Status(kOk); +}
diff --git a/chrome/test/chromedriver/chrome/stub_web_view.h b/chrome/test/chromedriver/chrome/stub_web_view.h index e6ca9d2..84397dd 100644 --- a/chrome/test/chromedriver/chrome/stub_web_view.h +++ b/chrome/test/chromedriver/chrome/stub_web_view.h
@@ -80,6 +80,9 @@ int xoffset, int yoffset) override; Status SynthesizePinchGesture(int x, int y, double scale_factor) override; + Status GetScreenOrientation(std::string* orientation) override; + Status SetScreenOrientation(std::string orientation) override; + Status DeleteScreenOrientation() override; private: std::string id_;
diff --git a/chrome/test/chromedriver/chrome/web_view.h b/chrome/test/chromedriver/chrome/web_view.h index 7a6719be..85dea3f 100644 --- a/chrome/test/chromedriver/chrome/web_view.h +++ b/chrome/test/chromedriver/chrome/web_view.h
@@ -190,6 +190,12 @@ int yoffset) = 0; virtual Status SynthesizePinchGesture(int x, int y, double scale_factor) = 0; + + virtual Status GetScreenOrientation(std::string* orientation) = 0; + + virtual Status SetScreenOrientation(std::string orientation) = 0; + + virtual Status DeleteScreenOrientation() = 0; }; #endif // CHROME_TEST_CHROMEDRIVER_CHROME_WEB_VIEW_H_
diff --git a/chrome/test/chromedriver/chrome/web_view_impl.cc b/chrome/test/chromedriver/chrome/web_view_impl.cc index 27ad54f0..d801ffa 100644 --- a/chrome/test/chromedriver/chrome/web_view_impl.cc +++ b/chrome/test/chromedriver/chrome/web_view_impl.cc
@@ -635,6 +635,37 @@ return client_->SendCommand("Input.synthesizePinchGesture", params); } +Status WebViewImpl::GetScreenOrientation(std::string* orientation) { + base::DictionaryValue empty_params; + std::unique_ptr<base::DictionaryValue> result; + Status status = + client_->SendCommandAndGetResult("Emulation.getScreenOrientation", + empty_params, + &result); + if (status.IsError() || !result->GetString("orientation", orientation)) + return status; + return Status(kOk); +} + +Status WebViewImpl::SetScreenOrientation(std::string orientation) { + base::DictionaryValue params; + params.SetString("screenOrientation", orientation); + Status status = + client_->SendCommand("Emulation.lockScreenOrientation", params); + if (status.IsError()) + return status; + return Status(kOk); +} + +Status WebViewImpl::DeleteScreenOrientation() { + base::DictionaryValue params; + Status status = + client_->SendCommand("Emulation.unlockScreenOrientation", params); + if (status.IsError()) + return status; + return Status(kOk); +} + Status WebViewImpl::CallAsyncFunctionInternal( const std::string& frame, const std::string& function, @@ -873,4 +904,6 @@ return Status(kOk); } + + } // namespace internal
diff --git a/chrome/test/chromedriver/chrome/web_view_impl.h b/chrome/test/chromedriver/chrome/web_view_impl.h index b326c46..faa60607 100644 --- a/chrome/test/chromedriver/chrome/web_view_impl.h +++ b/chrome/test/chromedriver/chrome/web_view_impl.h
@@ -111,6 +111,10 @@ int xoffset, int yoffset) override; Status SynthesizePinchGesture(int x, int y, double scale_factor) override; + Status GetScreenOrientation(std::string* orientation) override; + Status SetScreenOrientation(std::string orientation) override; + Status DeleteScreenOrientation() override; + private: Status TraverseHistoryWithJavaScript(int delta);
diff --git a/chrome/test/chromedriver/client/chromedriver.py b/chrome/test/chromedriver/client/chromedriver.py index f211bb4..183af40d 100644 --- a/chrome/test/chromedriver/client/chromedriver.py +++ b/chrome/test/chromedriver/client/chromedriver.py
@@ -478,4 +478,17 @@ def SetNetworkConnection(self, connection_type): params = {'parameters': {'type': connection_type}} - self.ExecuteCommand(Command.SET_NETWORK_CONNECTION, params) \ No newline at end of file + self.ExecuteCommand(Command.SET_NETWORK_CONNECTION, params) + + def GetScreenOrientation(self): + screen_orientation = self.ExecuteCommand(Command.GET_SCREEN_ORIENTATION) + return { + 'orientation': screen_orientation['orientation'] + } + + def SetScreenOrientation(self, orientation_type): + params = {'parameters': {'orientation': orientation_type}} + self.ExecuteCommand(Command.SET_SCREEN_ORIENTATION, params) + + def DeleteScreenOrientationLock(self): + self.ExecuteCommand(Command.DELETE_SCREEN_ORIENTATION) \ No newline at end of file
diff --git a/chrome/test/chromedriver/client/command_executor.py b/chrome/test/chromedriver/client/command_executor.py index 2003f76d..2b9fa6b 100644 --- a/chrome/test/chromedriver/client/command_executor.py +++ b/chrome/test/chromedriver/client/command_executor.py
@@ -128,6 +128,8 @@ _Method.GET, '/session/:sessionId/session_storage/size') GET_SCREEN_ORIENTATION = (_Method.GET, '/session/:sessionId/orientation') SET_SCREEN_ORIENTATION = (_Method.POST, '/session/:sessionId/orientation') + DELETE_SCREEN_ORIENTATION = ( + _Method.DELETE, '/session/:sessionId/orientation') MOUSE_CLICK = (_Method.POST, '/session/:sessionId/click') MOUSE_DOUBLE_CLICK = (_Method.POST, '/session/:sessionId/doubleclick') MOUSE_BUTTON_DOWN = (_Method.POST, '/session/:sessionId/buttondown')
diff --git a/chrome/test/chromedriver/commands.cc b/chrome/test/chromedriver/commands.cc index 9978510..8a4061b3 100644 --- a/chrome/test/chromedriver/commands.cc +++ b/chrome/test/chromedriver/commands.cc
@@ -257,7 +257,7 @@ if (status_tmp.IsError() && status_tmp.code() != kChromeNotReachable) { status.AddDetails( "failed to check if window was closed: " + status_tmp.message()); - } else if (!ContainsValue(web_view_ids, session->window)) { + } else if (!base::ContainsValue(web_view_ids, session->window)) { status = Status(kOk); } }
diff --git a/chrome/test/chromedriver/run_buildbot_steps.py b/chrome/test/chromedriver/run_buildbot_steps.py index 95314c03..45837955 100755 --- a/chrome/test/chromedriver/run_buildbot_steps.py +++ b/chrome/test/chromedriver/run_buildbot_steps.py
@@ -449,7 +449,7 @@ options, _ = parser.parse_args() bitness = '32' - if util.IsLinux() and platform_module.architecture()[0] == '64bit': + if util.Is64Bit(): bitness = '64' platform = '%s%s' % (util.GetPlatformName(), bitness) if options.android_packages:
diff --git a/chrome/test/chromedriver/server/http_handler.cc b/chrome/test/chromedriver/server/http_handler.cc index 364bc18..2c5426c 100644 --- a/chrome/test/chromedriver/server/http_handler.cc +++ b/chrome/test/chromedriver/server/http_handler.cc
@@ -479,13 +479,18 @@ CommandMapping( kGet, "session/:sessionId/orientation", - WrapToCommand("GetOrientation", - base::Bind(&ExecuteUnimplementedCommand))), + WrapToCommand("GetScreenOrientation", + base::Bind(&ExecuteGetScreenOrientation))), CommandMapping( kPost, "session/:sessionId/orientation", - WrapToCommand("SetOrientation", - base::Bind(&ExecuteUnimplementedCommand))), + WrapToCommand("SetScreenOrientation", + base::Bind(&ExecuteSetScreenOrientation))), + CommandMapping( + kDelete, + "session/:sessionId/orientation", + WrapToCommand("DeleteScreenOrientation", + base::Bind(&ExecuteDeleteScreenOrientation))), CommandMapping(kPost, "session/:sessionId/click", WrapToCommand("Click", base::Bind(&ExecuteMouseClick))), @@ -571,7 +576,6 @@ "Logs", WrapToCommand("Logs", base::Bind(&ExecuteUnimplementedCommand))), CommandMapping(kGet, "status", base::Bind(&ExecuteGetStatus)), - // Custom Chrome commands: // Allow quit all to be called with GET or POST. CommandMapping(
diff --git a/chrome/test/chromedriver/session.h b/chrome/test/chromedriver/session.h index f1db7621..b582212 100644 --- a/chrome/test/chromedriver/session.h +++ b/chrome/test/chromedriver/session.h
@@ -74,6 +74,7 @@ std::unique_ptr<Geoposition> overridden_geoposition; std::unique_ptr<DeviceMetrics> overridden_device_metrics; std::unique_ptr<NetworkConditions> overridden_network_conditions; + std::string orientation_type; // Logs that populate from DevTools events. ScopedVector<WebDriverLog> devtools_logs; std::unique_ptr<WebDriverLog> driver_log;
diff --git a/chrome/test/chromedriver/session_commands.cc b/chrome/test/chromedriver/session_commands.cc index d885472..10ac634 100644 --- a/chrome/test/chromedriver/session_commands.cc +++ b/chrome/test/chromedriver/session_commands.cc
@@ -525,9 +525,7 @@ int connection_type = 0; connection_type = desktop->GetNetworkConnection(); - base::DictionaryValue connection; - connection.SetInteger("connection_type", connection_type); - value->reset(connection.DeepCopy()); + value->reset(new base::FundamentalValue(connection_type)); return Status(kOk); } @@ -828,9 +826,56 @@ return Status(kOk); } - Status ExecuteUnimplementedCommand(Session* session, const base::DictionaryValue& params, std::unique_ptr<base::Value>* value) { return Status(kUnknownCommand); } + +Status ExecuteGetScreenOrientation(Session* session, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value) { + WebView* web_view = nullptr; + Status status = session->GetTargetWindow(&web_view); + if (status.IsError()) + return status; + + std::string screen_orientation; + status = web_view->GetScreenOrientation(&screen_orientation); + if (status.IsError()) + return status; + + base::DictionaryValue orientation_value; + orientation_value.SetString("orientation", screen_orientation); + value->reset(orientation_value.DeepCopy()); + return Status(kOk); +} + +Status ExecuteSetScreenOrientation(Session* session, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value) { + WebView* web_view = nullptr; + Status status = session->GetTargetWindow(&web_view); + if (status.IsError()) + return status; + + std::string screen_orientation; + params.GetString("parameters.orientation", &screen_orientation); + status = web_view->SetScreenOrientation(screen_orientation); + if (status.IsError()) + return status; + return Status(kOk); +} + +Status ExecuteDeleteScreenOrientation(Session* session, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value) { + WebView* web_view = nullptr; + Status status = session->GetTargetWindow(&web_view); + if (status.IsError()) + return status; + status = web_view->DeleteScreenOrientation(); + if (status.IsError()) + return status; + return Status(kOk); +}
diff --git a/chrome/test/chromedriver/session_commands.h b/chrome/test/chromedriver/session_commands.h index 76d766e..96d1fe0 100644 --- a/chrome/test/chromedriver/session_commands.h +++ b/chrome/test/chromedriver/session_commands.h
@@ -162,4 +162,16 @@ const base::DictionaryValue& params, std::unique_ptr<base::Value>* value); +Status ExecuteGetScreenOrientation(Session* session, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value); + +Status ExecuteSetScreenOrientation(Session* session, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value); + +Status ExecuteDeleteScreenOrientation(Session* session, + const base::DictionaryValue& params, + std::unique_ptr<base::Value>* value); + #endif // CHROME_TEST_CHROMEDRIVER_SESSION_COMMANDS_H_
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index bd12fd55..1d2e45c 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -61,6 +61,11 @@ 'ChromeDriverTest.testReturningAFunctionInJavascript', # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1367 'ChromeExtensionsCapabilityTest.testWaitsForExtensionToLoad', + # TODO: re-enable tests when DevTools supports ScreenOrientation commands. + 'ChromeDriverAndroidTest.testScreenOrientation', + 'ChromeDriverAndroidTest.testMultipleScreenOrientationChanges', + 'ChromeDriverAndroidTest.testDeleteScreenOrientationManual', + 'ChromeDriverAndroidTest.testScreenOrientationAcrossMultipleTabs', ] _VERSION_SPECIFIC_FILTER = {} @@ -72,8 +77,6 @@ 'ChromeDriverTest.testConsoleLogSources', # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1447 'ChromeDriverTest.testPendingConsoleLog', - # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1450 - 'PerfTest.testColdExecuteScript', ] _OS_SPECIFIC_FILTER = {} @@ -1402,6 +1405,112 @@ self._drivers[0].Quit() self._drivers[0] = self.CreateDriver() + def testScreenOrientation(self): + self._driver = self.CreateDriver() + self._driver.Load( + ChromeDriverTest.GetHttpUrlForFile('/chromedriver/orientation_test.html')) + screen_orientation_js = self._driver.ExecuteScript( + 'return screen.orientation.type') + screen_orientation = self._driver.GetScreenOrientation()['orientation'] + if screen_orientation == "LANDSCAPE": + screen_orientation = 'landscape-primary' + elif screen_orientation == "PORTRAIT": + screen_orientation = 'portrait-primary' + self.assertEqual(screen_orientation, screen_orientation_js) + + self._driver.SetScreenOrientation("portrait-primary") + screen_orientation = self._driver.GetScreenOrientation() + self.WaitForCondition( + lambda: 'orientation change 1' in self._driver.FindElement( + 'tag name', 'div').GetText()) + self.assertEqual(screen_orientation['orientation'], "PORTRAIT") + + self._driver.SetScreenOrientation("portrait-secondary") + self.WaitForCondition( + lambda: 'orientation change 2' in self._driver.FindElement( + 'tag name', 'div').GetText()) + screen_orientation = self._driver.GetScreenOrientation() + self.assertEqual(screen_orientation['orientation'], "PORTRAIT") + + self._driver.SetScreenOrientation("PORTRAIT") + self.WaitForCondition( + lambda: 'orientation change 3' in self._driver.FindElement( + 'tag name', 'div').GetText()) + screen_orientation = self._driver.GetScreenOrientation() + self.assertEqual(screen_orientation['orientation'], "PORTRAIT") + + self._driver.SetScreenOrientation("landscape-primary") + self.WaitForCondition( + lambda: 'orientation change 4' in self._driver.FindElement( + 'tag name', 'div').GetText()) + screen_orientation = self._driver.GetScreenOrientation() + self.assertEqual(screen_orientation['orientation'], "LANDSCAPE") + + self._driver.SetScreenOrientation("landscape-secondary") + self.WaitForCondition( + lambda: 'orientation change 5' in self._driver.FindElement( + 'tag name', 'div').GetText()) + screen_orientation = self._driver.GetScreenOrientation() + self.assertEqual(screen_orientation['orientation'], "LANDSCAPE") + + self._driver.SetScreenOrientation("LANDSCAPE") + self.WaitForCondition( + lambda: 'orientation change 6' in self._driver.FindElement( + 'tag name', 'div').GetText()) + screen_orientation = self._driver.GetScreenOrientation() + self.assertEqual(screen_orientation['orientation'], "LANDSCAPE") + + def testMultipleScreenOrientationChanges(self): + self._driver = self.CreateDriver() + + self._driver.SetScreenOrientation('PORTRAIT') + self.assertEqual( + self._driver.GetScreenOrientation()['orientation'], 'PORTRAIT') + + self._driver.SetScreenOrientation('PORTRAIT') + self.assertEqual( + self._driver.GetScreenOrientation()['orientation'], 'PORTRAIT') + + self._driver.DeleteScreenOrientation() + self._driver.DeleteScreenOrientation() + + def testDeleteScreenOrientationManual(self): + self._driver = self.CreateDriver() + + manual_test = False; + + self._driver.SetScreenOrientation("LANDSCAPE") + screen_orientation = self._driver.GetScreenOrientation() + self.assertEqual(screen_orientation['orientation'], "LANDSCAPE") + if(manual_test): + time.sleep(10) + # While sleeping, test that the orientation cannot be changed. + + print "Screen orientation lock deleted." + self._driver.DeleteScreenOrientation(); + if(manual_test): + time.sleep(10) + # While sleeping, test that orientation can be changed by manually + # rotating the device. + + def testScreenOrientationAcrossMultipleTabs(self): + self._driver = self.CreateDriver() + + self._driver.SetScreenOrientation('LANDSCAPE') + self._driver.Load( + ChromeDriverTest.GetHttpUrlForFile('/chromedriver/page_test.html')) + window1 = self._driver.GetCurrentWindowHandle() + self._driver.FindElement('id', 'link').Click() + orientation = self._driver.GetScreenOrientation() + self.assertEqual(orientation['orientation'], 'LANDSCAPE') + + self._driver.ExecuteScript('window.name = "oldWindow";') + self._driver.SwitchToWindow('oldWindow') + self.assertEqual(window1, self._driver.GetCurrentWindowHandle()) + orientation = self._driver.GetScreenOrientation() + self.assertEqual(orientation['orientation'], 'LANDSCAPE') + + class ChromeDownloadDirTest(ChromeDriverBaseTest): def __init__(self, *args, **kwargs): @@ -1794,7 +1903,7 @@ connection_type = 0x8 driver.SetNetworkConnection(connection_type) network = driver.GetNetworkConnection() - self.assertEquals(network['connection_type'], connection_type) + self.assertEquals(network, connection_type) def testEmulateNetworkConnectionMultipleBits(self): driver = self.CreateDriver( @@ -1805,7 +1914,7 @@ connection_type = 0x38 driver.SetNetworkConnection(connection_type) network = driver.GetNetworkConnection() - self.assertEquals(network['connection_type'], connection_type) + self.assertEquals(network, connection_type) def testWifiAndAirplaneModeEmulation(self): driver = self.CreateDriver( @@ -1816,7 +1925,7 @@ connection_type = 0x3 driver.SetNetworkConnection(connection_type) network = driver.GetNetworkConnection() - self.assertEquals(network['connection_type'], connection_type) + self.assertEquals(network, connection_type) def testNetworkConnectionTypeIsAppliedToAllTabsImmediately(self): def respondWithString(request): @@ -1871,7 +1980,7 @@ connection_type = 0x1; driver.SetNetworkConnection(connection_type) network = driver.GetNetworkConnection() - self.assertEquals(network['connection_type'], connection_type) + self.assertEquals(network, connection_type) # Navigate to another window. driver.FindElement('id', 'link').Click() @@ -1891,7 +2000,7 @@ # Test whether first window has old or new network conditions. network = driver.GetNetworkConnection() - self.assertEquals(network['connection_type'], connection_type) + self.assertEquals(network, connection_type) def testW3cCompliantResponses(self): # Asserts that chromedriver has received the correct response.
diff --git a/chrome/test/data/chromedriver/orientation_test.html b/chrome/test/data/chromedriver/orientation_test.html new file mode 100644 index 0000000..687b5aa --- /dev/null +++ b/chrome/test/data/chromedriver/orientation_test.html
@@ -0,0 +1,20 @@ +<html> + <title>orientation test</title> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + </head> + <body> + <script type="text/javascript"> + + var testnumber = 1; + + window.addEventListener('orientationchange', function() { + var elt = document.getElementById('orientation'); + elt.innerHTML = 'orientation change ' + testnumber; + testnumber++; + }); + + </script> + <div id='orientation'> + </div> + </body> +</html>
diff --git a/chrome/test/data/extensions/api_test/tabs/basics/discarded.js b/chrome/test/data/extensions/api_test/tabs/basics/discarded.js index 7d212a82..f2fe5b2 100644 --- a/chrome/test/data/extensions/api_test/tabs/basics/discarded.js +++ b/chrome/test/data/extensions/api_test/tabs/basics/discarded.js
@@ -20,6 +20,7 @@ })); }, + // Tests chrome.tabs.onUpdated for Discarded property. function discard() { // Initially tab isn't discarded. assertFalse(testTab.discarded); @@ -70,5 +71,57 @@ }); chrome.tabs.reload(testTab.id); + }, + + // Tests chrome.tabs.onUpdated for autoDiscardable property. + function setNonAutoDiscardable() { + // Initially the tab is auto-discardable. + assertTrue(testTab.autoDiscardable); + + var onUpdatedCompleted = chrome.test.listenForever( + chrome.tabs.onUpdated, + function(tabId, changeInfo, tab) { + if ('autoDiscardable' in changeInfo) { + // Make sure it's the right tab. + assertEq(testTab.id, tab.id); + + // Make sure the auto-discardable state changed correctly. + assertFalse(changeInfo.autoDiscardable); + assertFalse(tab.autoDiscardable); + + onUpdatedCompleted(); + } + }); + + chrome.tabs.update(testTab.id, { autoDiscardable: false }, + pass(function(tab) { + assertFalse(tab.autoDiscardable); + testTab = tab; + })); + }, + + function resetAutoDiscardable() { + // Tab was set to non auto-discardable. + assertFalse(testTab.autoDiscardable); + + var onUpdatedCompleted = chrome.test.listenForever( + chrome.tabs.onUpdated, + function(tabId, changeInfo, tab) { + if ('autoDiscardable' in changeInfo) { + // Make sure it's the right tab. + assertEq(testTab.id, tab.id); + + // Make sure the auto-discardable state changed correctly. + assertTrue(changeInfo.autoDiscardable); + assertTrue(tab.autoDiscardable); + + onUpdatedCompleted(); + } + }); + + chrome.tabs.update(testTab.id, { autoDiscardable: true }, + pass(function (tab) { + assertTrue(tab.autoDiscardable); + })); } ]);
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 747a9f7a..5e1a390 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -1951,6 +1951,14 @@ ] }, + "WebRtcUdpPortRange": { + "os": ["win", "linux", "mac", "chromeos", "android"], + "test_policy": { "WebRtcUdpPortRange": "10000-11999" }, + "pref_mappings": [ + { "pref": "webrtc.udp_port_range" } + ] + }, + "----- Chrome OS policies ------------------------------------------------": {}, "ChromeOsLockOnIdleSuspend": {
diff --git a/chrome/test/data/webui/md_history/history_grouped_list_test.js b/chrome/test/data/webui/md_history/history_grouped_list_test.js index 1b990afa..931f427 100644 --- a/chrome/test/data/webui/md_history/history_grouped_list_test.js +++ b/chrome/test/data/webui/md_history/history_grouped_list_test.js
@@ -9,14 +9,17 @@ var toolbar; var groupedList; var sidebar; + var listContainer; var SIMPLE_RESULTS; var PER_DAY_RESULTS; var PER_MONTH_RESULTS; + suiteSetup(function() { app = $('history-app'); app.grouped_ = true; + listContainer = app.$['history']; toolbar = app.$['toolbar']; sidebar = app.$['content-side-bar']; @@ -135,20 +138,121 @@ test('items rendered when expanded', function() { app.set('queryState_.range', HistoryRange.WEEK); app.historyResult(createHistoryInfo(), SIMPLE_RESULTS); - var getItems = function() { - return Polymer.dom(groupedList.root) - .querySelectorAll('history-item'); - }; return flush().then(function() { - assertEquals(0, getItems().length); + assertEquals( + 0, polymerSelectAll(groupedList, 'history-item').length); MockInteractions.tap(groupedList.$$('.domain-heading')); return flush(); }).then(function() { - assertEquals(2, getItems().length); + assertEquals( + 2, polymerSelectAll(groupedList, 'history-item').length); }); }); + test('items deletion in week view', function(done) { + var results = [ + createHistoryEntry('2016-03-13', 'https://en.wikipedia.org/a'), + createHistoryEntry('2016-03-13', 'https://en.wikipedia.org/b'), + createHistoryEntry('2016-03-13', 'https://en.wikipedia.org/c'), + createHistoryEntry('2016-03-13', 'https://en.wikipedia.org/d'), + createHistoryEntry('2016-03-13', 'https://www.youtube.com/a'), + createHistoryEntry('2016-03-13', 'https://www.youtube.com/b'), + createHistoryEntry('2016-03-11', 'https://en.wikipedia.org'), + createHistoryEntry('2016-03-10', 'https://www.youtube.com') + ]; + app.set('queryState_.range', HistoryRange.WEEK); + app.historyResult(createHistoryInfo(), results); + + waitForEvent(groupedList, 'dom-change', function() { + return polymerSelectAll( + groupedList, '.dropdown-indicator').length == 4; + }).then(function() { + polymerSelectAll(groupedList, '.dropdown-indicator'). + forEach(MockInteractions.tap); + + return flush(); + }).then(function() { + var items = polymerSelectAll(groupedList, 'history-item'); + + MockInteractions.tap(items[0].$.checkbox); + MockInteractions.tap(items[2].$.checkbox); + MockInteractions.tap(items[4].$.checkbox); + MockInteractions.tap(items[5].$.checkbox); + MockInteractions.tap(items[6].$.checkbox); + MockInteractions.tap(items[7].$.checkbox); + + // Select and deselect item 1. + MockInteractions.tap(items[1].$.checkbox); + MockInteractions.tap(items[1].$.checkbox); + + registerMessageCallback('removeVisits', this, function() { + flush().then(function() { + deleteComplete(); + return waitForEvent(groupedList, 'dom-change', function() { + return polymerSelectAll( + groupedList, '.dropdown-indicator').length == 1; + }); + }).then(function() { + items = polymerSelectAll(groupedList, 'history-item'); + assertEquals(2, items.length); + assertEquals('https://en.wikipedia.org/b', items[0].item.title); + assertEquals('https://en.wikipedia.org/d', items[1].item.title); + assertEquals( + 1, polymerSelectAll(groupedList, '.domain-heading') + .length); + + assertEquals( + 1, polymerSelectAll(groupedList, + '.group-container').length); + + assertFalse(listContainer.$.dialog.open); + done(); + }); + }); + + MockInteractions.tap(app.$.toolbar.$$('#delete-button')); + + // Confirmation dialog should appear. + assertTrue(listContainer.$.dialog.open); + + MockInteractions.tap(listContainer.$$('.action-button')); + }); + }); + + test('build removal tree', function() { + var paths = [ + 'a.0.b.1', + 'a.0.b.3', + 'a.2.b.3', + ]; + + var expected = { + currentPath: 'a', + leaf: false, + indexes: [0, 2], + children: [ + { + currentPath: 'a.0.b', + leaf: true, + indexes: [1, 3], + children: [], + }, + null, + { + currentPath: 'a.2.b', + leaf: true, + indexes: [3], + children: [], + }, + ], + }; + + assertEquals( + JSON.stringify(expected), + JSON.stringify(groupedList.buildRemovalTree_(paths))); + }); + teardown(function() { app.set('queryState_.results', []); app.set('queryState_.searchedTerm', '');
diff --git a/chrome/test/data/webui/md_history/history_item_test.js b/chrome/test/data/webui/md_history/history_item_test.js index 83ce632a..fd824d0 100644 --- a/chrome/test/data/webui/md_history/history_item_test.js +++ b/chrome/test/data/webui/md_history/history_item_test.js
@@ -63,13 +63,13 @@ var items = Polymer.dom(element.root).querySelectorAll('history-item'); - element.removeDeletedHistory_([element.historyData_[3]]); + element.removeItemsByPath(['historyData_.3']); assertEquals(5, element.historyData_.length); // Checks that a new time gap separator has been inserted. assertTrue(items[2].hasTimeGap); - element.removeDeletedHistory_([element.historyData_[3]]); + element.removeItemsByPath(['historyData_.3']); // Checks time gap separator is removed. assertFalse(items[2].hasTimeGap);
diff --git a/chrome/test/data/webui/md_history/history_list_test.js b/chrome/test/data/webui/md_history/history_list_test.js index 6dd1804..43d8394e 100644 --- a/chrome/test/data/webui/md_history/history_list_test.js +++ b/chrome/test/data/webui/md_history/history_list_test.js
@@ -34,8 +34,7 @@ test('cancelling selection of multiple items', function() { app.historyResult(createHistoryInfo(), TEST_HISTORY_RESULTS); return flush().then(function() { - var items = - Polymer.dom(element.root).querySelectorAll('history-item'); + var items = polymerSelectAll(element, 'history-item'); MockInteractions.tap(items[2].$.checkbox); MockInteractions.tap(items[3].$.checkbox); @@ -65,8 +64,7 @@ app.historyResult(createHistoryInfo(), TEST_HISTORY_RESULTS); return flush().then(function() { - var items = - Polymer.dom(element.root).querySelectorAll('history-item'); + var items = polymerSelectAll(element, 'history-item'); assertTrue(items[0].isCardStart); assertTrue(items[0].isCardEnd); assertFalse(items[1].isCardEnd); @@ -83,7 +81,7 @@ return flush().then(function() { var items = - Polymer.dom(element.root).querySelectorAll('history-item'); + polymerSelectAll(element, 'history-item'); assertTrue(items[3].isCardStart); assertTrue(items[5].isCardEnd); @@ -100,14 +98,13 @@ app.historyResult(createHistoryInfo(), ADDITIONAL_RESULTS); return flush().then(function() { - element.removeDeletedHistory_([ - element.historyData_[2], element.historyData_[5], - element.historyData_[7] + element.removeItemsByPath([ + 'historyData_.2', 'historyData_.5', 'historyData_.7' ]); return flush(); }).then(function() { - items = Polymer.dom(element.root).querySelectorAll('history-item'); + items = polymerSelectAll(element, 'history-item'); assertEquals(element.historyData_.length, 5); assertEquals(element.historyData_[0].dateRelativeDay, @@ -184,12 +181,12 @@ app.historyResult(createHistoryInfo(), TEST_HISTORY_RESULTS); return flush().then(function() { - items = Polymer.dom(element.root).querySelectorAll('history-item'); + items = polymerSelectAll(element, 'history-item'); MockInteractions.tap(items[2].$['menu-button']); assertTrue(sharedMenu.menuOpen); - element.$['infinite-list'].scrollTop = 100; - return flush(); + element.$['infinite-list'].scrollToIndex(20); + return waitForEvent(sharedMenu, 'menu-open-changed'); }).then(function() { assertFalse(sharedMenu.menuOpen); }); @@ -216,16 +213,25 @@ var listContainer = app.$.history; app.historyResult(createHistoryInfo(), TEST_HISTORY_RESULTS); app.historyResult(createHistoryInfo(), ADDITIONAL_RESULTS); + app.historyResult(createHistoryInfo(), [ + createHistoryEntry('2015-01-01', 'http://example.com'), + createHistoryEntry('2015-01-01', 'http://example.com'), + createHistoryEntry('2015-01-01', 'http://example.com') + ]); flush().then(function() { - items = Polymer.dom(element.root).querySelectorAll('history-item'); + items = polymerSelectAll(element, 'history-item'); MockInteractions.tap(items[2].$.checkbox); MockInteractions.tap(items[5].$.checkbox); MockInteractions.tap(items[7].$.checkbox); + MockInteractions.tap(items[8].$.checkbox); + MockInteractions.tap(items[9].$.checkbox); + MockInteractions.tap(items[10].$.checkbox); registerMessageCallback('removeVisits', this, function() { flush().then(function() { deleteComplete(); + return flush(); }).then(function() { assertEquals(element.historyData_.length, 5); assertEquals(element.historyData_[0].dateRelativeDay, @@ -235,6 +241,15 @@ assertEquals(element.historyData_[4].dateRelativeDay, '2016-03-11'); assertFalse(listContainer.$.dialog.open); + + // Ensure the UI is correctly updated. + items = polymerSelectAll(element, 'history-item'); + assertEquals('https://www.google.com', items[0].item.title); + assertEquals('https://www.example.com', items[1].item.title); + assertEquals('https://en.wikipedia.org', items[2].item.title); + assertEquals('https://en.wikipedia.org', items[3].item.title); + assertEquals('https://www.google.com', items[4].item.title); + done(); }); }); @@ -252,7 +267,7 @@ var listContainer = app.$.history; app.historyResult(createHistoryInfo(), TEST_HISTORY_RESULTS); flush().then(function() { - items = Polymer.dom(element.root).querySelectorAll('history-item'); + items = polymerSelectAll(element, 'history-item'); // Dialog should not appear when there is no item selected. MockInteractions.pressAndReleaseKeyOn(
diff --git a/chrome/test/data/webui/md_history/test_util.js b/chrome/test/data/webui/md_history/test_util.js index d4f44ea3..7ec8a6d7 100644 --- a/chrome/test/data/webui/md_history/test_util.js +++ b/chrome/test/data/webui/md_history/test_util.js
@@ -75,3 +75,37 @@ term: searchTerm || '' }; } + +/** + * @param {Element} element + * @param {string} selector + * @return {Element} + */ +function polymerSelectAll(element, selector) { + return Polymer.dom(element.root).querySelectorAll(selector); +} + +/** + * Returns a promise which is resolved when |eventName| is fired on |element| + * and |predicate| is true. + * @param {HTMLElement} element + * @param {string} eventName + * @param {function(Event): boolean} predicate + * @return {Promise} + */ +function waitForEvent(element, eventName, predicate) { + if (!predicate) + predicate = function() { return true; }; + + return new Promise(function(resolve) { + var listener = function(e) { + if (!predicate(e)) + return; + + resolve(); + element.removeEventListener(eventName, listener); + } + + element.addEventListener(eventName, listener); + }); +}
diff --git a/chrome/test/data/webui/settings/cr_settings_browsertest.js b/chrome/test/data/webui/settings/cr_settings_browsertest.js index 7b8dd08..6f15067 100644 --- a/chrome/test/data/webui/settings/cr_settings_browsertest.js +++ b/chrome/test/data/webui/settings/cr_settings_browsertest.js
@@ -792,3 +792,25 @@ TEST_F('CrControlledRadioButtonTest', 'All', function() { mocha.run(); }); + +GEN('#if defined(GOOGLE_CHROME_BUILD) && !defined(OS_CHROMEOS)'); + +function CrSettingsMetricsReportingTest() {} + +CrSettingsMetricsReportingTest.prototype = { + __proto__: CrSettingsBrowserTest.prototype, + + /** @override */ + browsePreload: 'chrome://md-settings/privacy_page/privacy_page.html', + + extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([ + 'test_browser_proxy.js', + 'metrics_reporting_tests.js', + ]), +}; + +TEST_F('CrSettingsMetricsReportingTest', 'All', function() { + mocha.run(); +}); + +GEN('#endif');
diff --git a/chrome/test/data/webui/settings/device_page_tests.js b/chrome/test/data/webui/settings/device_page_tests.js index 93ed9f4..f396722 100644 --- a/chrome/test/data/webui/settings/device_page_tests.js +++ b/chrome/test/data/webui/settings/device_page_tests.js
@@ -165,15 +165,14 @@ }); /** @return {!Promise<!HTMLElement>} */ - function showAndGetDeviceSubpage(subpage) { + function showAndGetDeviceSubpage(subpage, expectedRoute) { return new Promise(function(resolve, reject) { var row = assert(devicePage.$$('#main #' + subpage + 'Row')); devicePage.$.pages.addEventListener('neon-animation-finish', resolve); MockInteractions.tap(row); }).then(function() { - assertEquals('device', settings.getCurrentRoute().section); - assertEquals(subpage, settings.getCurrentRoute().subpage[0]); - var page = devicePage.$$('#' + subpage + ' settings-' + subpage); + assertEquals(expectedRoute, settings.getCurrentRoute()); + var page = devicePage.$$('settings-' + subpage); return assert(page); }); }; @@ -213,21 +212,21 @@ var pointersPage; setup(function() { - return showAndGetDeviceSubpage('pointers').then(function(page) { - pointersPage = page; - }); + return showAndGetDeviceSubpage( + 'pointers', settings.Route.POINTERS).then(function(page) { + pointersPage = page; + }); }); test('subpage responds to pointer attach/detach', function() { - assertEquals('pointers', settings.getCurrentRoute().subpage[0]); - assertTrue(settings.getCurrentRoute() == settings.Route.POINTERS); + assertEquals(settings.Route.POINTERS, settings.getCurrentRoute()); assertLT(0, pointersPage.$.mouse.offsetHeight); assertLT(0, pointersPage.$.touchpad.offsetHeight); assertLT(0, pointersPage.$$('#mouse h2').offsetHeight); assertLT(0, pointersPage.$$('#touchpad h2').offsetHeight); cr.webUIListenerCallback('has-touchpad-changed', false); - assertEquals('pointers', settings.getCurrentRoute().subpage[0]); + assertEquals(settings.Route.POINTERS, settings.getCurrentRoute()); assertLT(0, pointersPage.$.mouse.offsetHeight); assertEquals(0, pointersPage.$.touchpad.offsetHeight); assertEquals(0, pointersPage.$$('#mouse h2').offsetHeight); @@ -239,12 +238,12 @@ cr.webUIListenerCallback('has-mouse-changed', false); }).then(function() { - assertEquals(0, settings.getCurrentRoute().subpage.length); + assertEquals(settings.Route.DEVICE, settings.getCurrentRoute()); assertEquals(0, devicePage.$$('#main #pointersRow').offsetHeight); cr.webUIListenerCallback('has-touchpad-changed', true); assertLT(0, devicePage.$$('#main #pointersRow').offsetHeight); - return showAndGetDeviceSubpage('pointers'); + return showAndGetDeviceSubpage('pointers', settings.Route.POINTERS); }).then(function(page) { assertEquals(0, pointersPage.$.mouse.offsetHeight); assertLT(0, pointersPage.$.touchpad.offsetHeight); @@ -252,7 +251,7 @@ assertEquals(0, pointersPage.$$('#touchpad h2').offsetHeight); cr.webUIListenerCallback('has-mouse-changed', true); - assertEquals('pointers', settings.getCurrentRoute().subpage[0]); + assertEquals(settings.Route.POINTERS, settings.getCurrentRoute()); assertLT(0, pointersPage.$.mouse.offsetHeight); assertLT(0, pointersPage.$.touchpad.offsetHeight); assertLT(0, pointersPage.$$('#mouse h2').offsetHeight); @@ -326,7 +325,8 @@ test(assert(TestNames.Keyboard), function() { // Open the keyboard subpage. - return showAndGetDeviceSubpage('keyboard').then(function(keyboardPage) { + return showAndGetDeviceSubpage( + 'keyboard', settings.Route.KEYBOARD).then(function(keyboardPage) { // Initially, the optional keys are hidden. expectFalse(!!keyboardPage.$$('#capsLockKey')); expectFalse(!!keyboardPage.$$('#diamondKey')); @@ -420,7 +420,8 @@ var displayPage; return Promise.all([ // Get the display sub-page. - showAndGetDeviceSubpage('display').then(function(page) { + showAndGetDeviceSubpage( + 'display', settings.Route.DISPLAY).then(function(page) { displayPage = page; }), // Wait for the initial call to getInfo.
diff --git a/chrome/test/data/webui/settings/languages_page_browsertest.js b/chrome/test/data/webui/settings/languages_page_browsertest.js index e327fcd1..dd36cb1 100644 --- a/chrome/test/data/webui/settings/languages_page_browsertest.js +++ b/chrome/test/data/webui/settings/languages_page_browsertest.js
@@ -54,6 +54,7 @@ var languagesSection; var languagesPage; + var languageHelper; suiteSetup(function() { advanced.set('pageVisibility.languages', true); Polymer.dom.flush(); @@ -63,16 +64,17 @@ languagesPage = languagesSection.querySelector('settings-languages-page'); assertTrue(!!languagesPage); - return LanguageHelperImpl.getInstance().whenReady(); + languageHelper = LanguageHelperImpl.getInstance(); + return languageHelper.whenReady(); }.bind(this)); teardown(function(done) { // Close the section if we're in a sub-page. - if (settings.getCurrentRoute().subpage.length == 0) { - done(); - } else { + if (settings.getCurrentRoute().isSubpage()) { settings.navigateTo(settings.Route.ADVANCED); setTimeout(done); + } else { + done(); } }); @@ -84,6 +86,18 @@ assertTrue(!!languagesPage.$$('settings-manage-languages-page')); }); + test('Should not set UI language', function() { + var languagesCollapse = languagesPage.$.languagesCollapse; + var languageOptionsDropdownTrigger = languagesCollapse.querySelector( + 'paper-icon-button'); + assertTrue(!!languageOptionsDropdownTrigger); + + // This shouldn't get called. + languageHelper.setUILanguage = assertNotReached; + + MockInteractions.tap(languageOptionsDropdownTrigger); + }); + test('language detail', function() { var languagesCollapse = languagesPage.$.languagesCollapse; var languageDetailMenuItem = languagesCollapse.querySelectorAll(
diff --git a/chrome/test/data/webui/settings/metrics_reporting_tests.js b/chrome/test/data/webui/settings/metrics_reporting_tests.js new file mode 100644 index 0000000..bf684d7 --- /dev/null +++ b/chrome/test/data/webui/settings/metrics_reporting_tests.js
@@ -0,0 +1,80 @@ +// Copyright 2016 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 + * @extends {TestBrowserProxy} + * @implements {settings.PrivacyPageBrowserProxy} + */ +function TestPrivacyPageBrowserProxy() { + settings.TestBrowserProxy.call(this, [ + 'getMetricsReporting', + 'setMetricsReportingEnabled', + ]); +} + +TestPrivacyPageBrowserProxy.prototype = { + __proto__: settings.TestBrowserProxy.prototype, + + /** @type {!MetricsReporting} */ + metricsReporting: { + enabled: true, + managed: true, + }, + + /** @override */ + getMetricsReporting: function() { + this.methodCalled('getMetricsReporting'); + return Promise.resolve(this.metricsReporting); + }, + + /** @override */ + setMetricsReportingEnabled: function(enabled) { + this.methodCalled('setMetricsReportingEnabled', enabled); + }, +}; + +suite('metrics reporting', function() { + /** @type {settings.TestPrivacyPageBrowserProxy} */ + var testBrowserProxy; + + /** @type {SettingsPrivacyPageElement} */ + var page; + + setup(function() { + testBrowserProxy = new TestPrivacyPageBrowserProxy(); + settings.PrivacyPageBrowserProxyImpl.instance_ = testBrowserProxy; + PolymerTest.clearBody(); + page = document.createElement('settings-privacy-page'); + }); + + teardown(function() { page.remove(); }); + + test('changes to whether metrics reporting is enabled/managed', function() { + return testBrowserProxy.whenCalled('getMetricsReporting').then(function() { + Polymer.dom.flush(); + + var checkbox = page.$.metricsReportingCheckbox; + assertEquals(testBrowserProxy.metricsReporting.enabled, checkbox.checked); + var indicatorVisible = !!page.$$('#indicator'); + assertEquals(testBrowserProxy.metricsReporting.managed, indicatorVisible); + + var changedMetrics = { + enabled: !testBrowserProxy.metricsReporting.enabled, + managed: !testBrowserProxy.metricsReporting.managed, + }; + cr.webUIListenerCallback('metrics-reporting-change', changedMetrics); + Polymer.dom.flush(); + + assertEquals(changedMetrics.enabled, checkbox.checked); + indicatorVisible = !!page.$$('#indicator'); + assertEquals(changedMetrics.managed, indicatorVisible); + + var toggled = !changedMetrics.enabled; + + MockInteractions.tap(checkbox); + return testBrowserProxy.whenCalled('setMetricsReportingEnabled', toggled); + }); + }); +});
diff --git a/chrome/test/data/webui/settings/people_page_sync_page_test.js b/chrome/test/data/webui/settings/people_page_sync_page_test.js index 87a04af..fe8be55 100644 --- a/chrome/test/data/webui/settings/people_page_sync_page_test.js +++ b/chrome/test/data/webui/settings/people_page_sync_page_test.js
@@ -112,7 +112,9 @@ cr.webUIListenerCallback('page-status-changed', settings.PageStatus.CONFIGURE); - assertEquals(settings.PageStatus.CONFIGURE, syncPage.$.pages.selected); + assertFalse(syncPage.$$('#' + settings.PageStatus.CONFIGURE).hidden); + assertTrue(syncPage.$$('#' + settings.PageStatus.TIMEOUT).hidden); + assertTrue(syncPage.$$('#' + settings.PageStatus.SPINNER).hidden); // Start with Sync All with no encryption selected. cr.webUIListenerCallback('sync-prefs-changed', getSyncAllPrefs()); @@ -163,20 +165,34 @@ }), test('LoadingAndTimeout', function() { + var configurePage = syncPage.$$('#' + settings.PageStatus.CONFIGURE); + var spinnerPage = syncPage.$$('#' + settings.PageStatus.SPINNER); + var timeoutPage = syncPage.$$('#' + settings.PageStatus.TIMEOUT); + cr.webUIListenerCallback('page-status-changed', settings.PageStatus.SPINNER); - assertEquals(settings.PageStatus.SPINNER, syncPage.$.pages.selected); + assertTrue(configurePage.hidden); + assertTrue(timeoutPage.hidden); + assertFalse(spinnerPage.hidden); + cr.webUIListenerCallback('page-status-changed', settings.PageStatus.TIMEOUT); - assertEquals(settings.PageStatus.TIMEOUT, syncPage.$.pages.selected); + assertTrue(configurePage.hidden); + assertFalse(timeoutPage.hidden); + assertTrue(spinnerPage.hidden); + cr.webUIListenerCallback('page-status-changed', settings.PageStatus.CONFIGURE); - assertEquals(settings.PageStatus.CONFIGURE, syncPage.$.pages.selected); + assertFalse(configurePage.hidden); + assertTrue(timeoutPage.hidden); + assertTrue(spinnerPage.hidden); // Should remain on the CONFIGURE page even if the passphrase failed. cr.webUIListenerCallback('page-status-changed', settings.PageStatus.PASSPHRASE_FAILED); - assertEquals(settings.PageStatus.CONFIGURE, syncPage.$.pages.selected); + assertFalse(configurePage.hidden); + assertTrue(timeoutPage.hidden); + assertTrue(spinnerPage.hidden); }); test('SettingIndividualDatatypes', function() {
diff --git a/chrome/test/data/webui/settings/privacy_page_test.js b/chrome/test/data/webui/settings/privacy_page_test.js index 9b2759b..c42bbe0 100644 --- a/chrome/test/data/webui/settings/privacy_page_test.js +++ b/chrome/test/data/webui/settings/privacy_page_test.js
@@ -89,6 +89,27 @@ }); } + function registerPrivacyPageTests() { + suite('PrivacyPage', function() { + /** @type {SettingsPrivacyPageElement} */ + var page; + + setup(function() { + page = document.createElement('settings-privacy-page'); + document.body.appendChild(page); + }); + + teardown(function() { page.remove(); }); + + test('showClearBrowsingDataDialog', function() { + assertFalse(!!page.$$('settings-clear-browsing-data-dialog')); + MockInteractions.tap(page.$.clearBrowsingData); + Polymer.dom.flush(); + assertTrue(!!page.$$('settings-clear-browsing-data-dialog')); + }); + }); + } + function registerClearBrowsingDataTests() { suite('ClearBrowsingData', function() { /** @type {settings.TestClearBrowsingDataBrowserProxy} */ @@ -234,6 +255,7 @@ registerNativeCertificateManagerTests(); registerClearBrowsingDataTests(); + registerPrivacyPageTests(); }, }; });
diff --git a/chrome/test/data/webui/settings/route_tests.js b/chrome/test/data/webui/settings/route_tests.js index cf91efd..c84fbdc 100644 --- a/chrome/test/data/webui/settings/route_tests.js +++ b/chrome/test/data/webui/settings/route_tests.js
@@ -7,45 +7,34 @@ // Set up root page routes. var BASIC = new settings.Route('/'); var ADVANCED = new settings.Route('/advanced'); - assertDeepEquals([], ADVANCED.subpage); + assertFalse(ADVANCED.isSubpage()); // Test a section route. var PRIVACY = ADVANCED.createChild('/privacy'); PRIVACY.section = 'privacy'; assertEquals(ADVANCED, PRIVACY.parent); - assertDeepEquals([], PRIVACY.subpage); + assertFalse(PRIVACY.isSubpage()); assertFalse(BASIC.contains(PRIVACY)); assertTrue(ADVANCED.contains(PRIVACY)); assertTrue(PRIVACY.contains(PRIVACY)); assertFalse(PRIVACY.contains(ADVANCED)); // Test a subpage route. - var SITE_SETTINGS = PRIVACY.createChild('/siteSettings', 'site-settings'); + var SITE_SETTINGS = PRIVACY.createChild('/siteSettings'); assertEquals('/siteSettings', SITE_SETTINGS.path); assertEquals(PRIVACY, SITE_SETTINGS.parent); assertFalse(!!SITE_SETTINGS.dialog); - assertDeepEquals(['site-settings'], SITE_SETTINGS.subpage); + assertTrue(SITE_SETTINGS.isSubpage()); assertEquals('privacy', SITE_SETTINGS.section); assertFalse(BASIC.contains(SITE_SETTINGS)); assertTrue(ADVANCED.contains(SITE_SETTINGS)); assertTrue(PRIVACY.contains(SITE_SETTINGS)); // Test a sub-subpage route. - var SITE_SETTINGS_ALL = - SITE_SETTINGS.createChild('all', 'all-sites'); + var SITE_SETTINGS_ALL = SITE_SETTINGS.createChild('all'); assertEquals('/siteSettings/all', SITE_SETTINGS_ALL.path); assertEquals(SITE_SETTINGS, SITE_SETTINGS_ALL.parent); - assertDeepEquals(['site-settings', 'all-sites'], SITE_SETTINGS_ALL.subpage); - - // Test a dialog route. - var CLEAR_BROWSING_DATA = - PRIVACY.createDialog('/clearBrowsingData', 'clear-browsing-data'); - assertEquals(PRIVACY, CLEAR_BROWSING_DATA.parent); - assertEquals('clear-browsing-data', CLEAR_BROWSING_DATA.dialog); - assertEquals('privacy', CLEAR_BROWSING_DATA.section); - assertFalse(BASIC.contains(CLEAR_BROWSING_DATA)); - assertTrue(ADVANCED.contains(CLEAR_BROWSING_DATA)); - assertTrue(PRIVACY.contains(CLEAR_BROWSING_DATA)); + assertTrue(SITE_SETTINGS_ALL.isSubpage()); }); test('no duplicate routes', function() {
diff --git a/chrome/test/data/webui/settings/settings_main_test.js b/chrome/test/data/webui/settings/settings_main_test.js index e058e921..efd6eab 100644 --- a/chrome/test/data/webui/settings/settings_main_test.js +++ b/chrome/test/data/webui/settings/settings_main_test.js
@@ -49,11 +49,6 @@ /** @type {?SettingsMainElement} */ var settingsMain = null; - // TODO(tommycli): Remove once settings.navigateTo is no longer a stub. - settings.navigateTo = function(route) { - settingsMain.currentRoute = route; - }; - setup(function() { searchManager = new TestSearchManager(); settings.setSearchManagerForTesting(searchManager); @@ -67,13 +62,19 @@ teardown(function() { settingsMain.remove(); }); test('no results page shows and hides', function() { + Polymer.dom.flush(); var noSearchResults = settingsMain.$.noSearchResults; assertTrue(!!noSearchResults); assertTrue(noSearchResults.hidden); + var toggleContainer = settingsMain.$$('#toggleContainer'); + assertTrue(!!toggleContainer); + assertNotEquals('none', toggleContainer.style.display); + searchManager.setMatchesFound(false); return settingsMain.searchContents('Query1').then(function() { assertFalse(noSearchResults.hidden); + assertEquals('none', toggleContainer.style.display); searchManager.setMatchesFound(true); return settingsMain.searchContents('Query2'); @@ -83,16 +84,42 @@ }); // Ensure that when the user clears the search box, the "no results" page - // is hidden. + // is hidden and the "advanced page toggle" is visible again. test('no results page hides on clear', function() { + Polymer.dom.flush(); var noSearchResults = settingsMain.$.noSearchResults; assertTrue(!!noSearchResults); assertTrue(noSearchResults.hidden); - searchManager.setMatchesFound(false); + var toggleContainer = settingsMain.$$('#toggleContainer'); + assertTrue(!!toggleContainer); + assertNotEquals('none', toggleContainer.style.display); + + searchManager.setMatchesFound(false); // Clearing the search box is effectively a search for the empty string. return settingsMain.searchContents('').then(function() { + Polymer.dom.flush(); assertTrue(noSearchResults.hidden); + assertNotEquals('none', toggleContainer.style.display); + }); + }); + + test('advanced page restored after search results cleared', function() { + // Simulating searching while the advanced page is collapsed. + settingsMain.currentRouteChanged(settings.Route.BASIC); + Polymer.dom.flush(); + + assertFalse(!!settingsMain.$$('settings-advanced-page')); + + searchManager.setMatchesFound(true); + return settingsMain.searchContents('Query1').then(function() { + searchManager.setMatchesFound(false); + return settingsMain.searchContents(''); + }).then(function() { + Polymer.dom.flush(); + // Checking that it remains hidden after results are cleared. + assertEquals( + 'none', settingsMain.$$('settings-advanced-page').style.display); }); }); });
diff --git a/chrome/test/data/webui/settings/settings_page_browsertest.js b/chrome/test/data/webui/settings/settings_page_browsertest.js index 7e601164..cb75c4d 100644 --- a/chrome/test/data/webui/settings/settings_page_browsertest.js +++ b/chrome/test/data/webui/settings/settings_page_browsertest.js
@@ -92,15 +92,15 @@ // The section's main child should be stamped and visible. var main = stampedChildren.filter(function(element) { - return element.id == 'main'; + return element.getAttribute('route-path') == 'default'; }); - assertEquals(main.length, 1, '#main not found for section ' + + assertEquals(main.length, 1, 'default card not found for section ' + section.section); assertGT(main[0].offsetHeight, 0); // Any other stamped subpages should not be visible. var subpages = stampedChildren.filter(function(element) { - return element.id != 'main'; + return element.getAttribute('route-path') != 'default'; }); for (var subpage of subpages) { assertEquals(subpage.offsetHeight, 0, 'Expected subpage #' + subpage.id +
diff --git a/chrome/test/data/webui/settings/site_list_tests.js b/chrome/test/data/webui/settings/site_list_tests.js index 72ca4bd..ae021e1 100644 --- a/chrome/test/data/webui/settings/site_list_tests.js +++ b/chrome/test/data/webui/settings/site_list_tests.js
@@ -268,15 +268,22 @@ }); /** + * Fetch the non-hidden menu items from the list. + * @param {!HTMLElement} parentElement + */ + function getMenuItems(listContainer) { + return listContainer.children[0].querySelectorAll( + 'paper-menu-button paper-item:not([hidden])'); + } + + /** * Asserts the menu looks as expected. * @param {Array<string>} items The items expected to show in the menu. * @param {!HTMLElement} parentElement The parent node to start looking * in. */ function assertMenu(items, parentElement) { - var listItem = parentElement.$.listContainer.children[0]; - var menuItems = listItem.querySelectorAll( - 'paper-menu-button paper-item:not([hidden])'); + var menuItems = getMenuItems(parentElement.$.listContainer); assertEquals(items.length, menuItems.length); for (var i = 0; i < items.length; i++) assertEquals(items[i], menuItems[i].textContent.trim()); @@ -641,6 +648,20 @@ // No further checks needed. If this fails, it will hang the test. }); }); + + test('Select menu item', function() { + // Test for error: "Cannot read property 'origin' of undefined". + setupCategory(settings.ContentSettingsTypes.GEOLOCATION, + settings.PermissionValues.ALLOW, prefs); + return browserProxy.whenCalled('getExceptionList').then(function( + contentType) { + Polymer.dom.flush(); + var menuItems = getMenuItems(testElement.$.listContainer); + assertTrue(!!menuItems); + MockInteractions.tap(menuItems[0]); + return browserProxy.whenCalled('setCategoryPermissionForOrigin'); + }); + }); }); } return {
diff --git a/chrome/test/media_router/media_router_e2e_browsertest.cc b/chrome/test/media_router/media_router_e2e_browsertest.cc index 1a29bc1..d9de4b5 100644 --- a/chrome/test/media_router/media_router_e2e_browsertest.cc +++ b/chrome/test/media_router/media_router_e2e_browsertest.cc
@@ -117,7 +117,7 @@ } bool MediaRouterE2EBrowserTest::IsSinkDiscovered() const { - return ContainsKey(observer_->sink_map, receiver()); + return base::ContainsKey(observer_->sink_map, receiver()); } bool MediaRouterE2EBrowserTest::IsRouteCreated() const {
diff --git a/chrome/third_party/chromevox/BUILD.gn b/chrome/third_party/chromevox/BUILD.gn index 3e161c65..62e6afa 100644 --- a/chrome/third_party/chromevox/BUILD.gn +++ b/chrome/third_party/chromevox/BUILD.gn
@@ -2,36 +2,34 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -if (is_chromeos) { - import("//chrome/browser/resources/chromeos/chromevox/chromevox.gni") +assert(is_chromeos) - chromevox_out_dir = "$root_out_dir/resources/chromeos/chromevox" +chromevox_out_dir = "$root_out_dir/resources/chromeos/chromevox" - group("chromevox_third_party_resources") { - deps = [ - ":chromevox_third_party_background_resources", - ":chromevox_third_party_injected_resources", - ] - } +group("chromevox_third_party_resources") { + deps = [ + ":chromevox_third_party_background_resources", + ":chromevox_third_party_injected_resources", + ] +} - copy("chromevox_third_party_background_resources") { - sources = [ - "chromevox/background/chrome_shared2.css", - "chromevox/background/options.css", - "chromevox/background/options_widgets.css", - ] - outputs = [ - "$chromevox_out_dir/chromevox/background/{{source_file_part}}", - ] - } +copy("chromevox_third_party_background_resources") { + sources = [ + "chromevox/background/chrome_shared2.css", + "chromevox/background/options.css", + "chromevox/background/options_widgets.css", + ] + outputs = [ + "$chromevox_out_dir/chromevox/background/{{source_file_part}}", + ] +} - copy("chromevox_third_party_injected_resources") { - sources = [ - "chromevox/injected/mathjax.js", - "chromevox/injected/mathjax_external_util.js", - ] - outputs = [ - "$chromevox_out_dir/chromevox/injected/{{source_file_part}}", - ] - } +copy("chromevox_third_party_injected_resources") { + sources = [ + "chromevox/injected/mathjax.js", + "chromevox/injected/mathjax_external_util.js", + ] + outputs = [ + "$chromevox_out_dir/chromevox/injected/{{source_file_part}}", + ] }
diff --git a/chrome/tools/build/repack_locales.py b/chrome/tools/build/repack_locales.py index dc82d7d..7708d07 100755 --- a/chrome/tools/build/repack_locales.py +++ b/chrome/tools/build/repack_locales.py
@@ -14,8 +14,10 @@ import os import sys -sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', - 'tools', 'grit')) +# Prepend the grit module from the source tree so it takes precedence over other +# grit versions that might present in the search path. +sys.path.insert(1, os.path.join(os.path.dirname(__file__), '..', '..', '..', + 'tools', 'grit')) from grit.format import data_pack # The gyp "branding" variable.
diff --git a/chrome/tools/disable_outdated_build_detector/constants.cc b/chrome/tools/disable_outdated_build_detector/constants.cc index 7d69c82..53d45be 100644 --- a/chrome/tools/disable_outdated_build_detector/constants.cc +++ b/chrome/tools/disable_outdated_build_detector/constants.cc
@@ -20,15 +20,6 @@ } // namespace env -// App GUIDs for Google Chrome and the Google Chrome binaries. -#if defined(GOOGLE_CHROME_BUILD) -const wchar_t kChromeAppGuid[] = L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; -const wchar_t kBinariesAppGuid[] = L"{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}"; -#else -const wchar_t kChromeAppGuid[] = L""; -const wchar_t kBinariesAppGuid[] = L""; -#endif - // The new brand to which organic installs will be switched. const wchar_t kAOHY[] = L"AOHY";
diff --git a/chrome/tools/disable_outdated_build_detector/constants.h b/chrome/tools/disable_outdated_build_detector/constants.h index 30b6eac..be5085e 100644 --- a/chrome/tools/disable_outdated_build_detector/constants.h +++ b/chrome/tools/disable_outdated_build_detector/constants.h
@@ -20,9 +20,6 @@ } // namespace env -extern const wchar_t kChromeAppGuid[]; -extern const wchar_t kBinariesAppGuid[]; - extern const wchar_t kAOHY[]; extern const wchar_t kBrand[]; extern const wchar_t kInstallerResult[];
diff --git a/chrome/tools/disable_outdated_build_detector/disable_outdated_build_detector.cc b/chrome/tools/disable_outdated_build_detector/disable_outdated_build_detector.cc index 01d2f16..7c19239 100644 --- a/chrome/tools/disable_outdated_build_detector/disable_outdated_build_detector.cc +++ b/chrome/tools/disable_outdated_build_detector/disable_outdated_build_detector.cc
@@ -29,7 +29,7 @@ bool IsChromeMultiInstall(bool system_level) { base::win::RegKey key; - LONG result = OpenClientStateKey(system_level, kChromeAppGuid, &key); + LONG result = OpenClientStateKey(system_level, App::CHROME_BROWSER, &key); if (result != ERROR_SUCCESS) return false; base::string16 uninstall_arguments; @@ -41,15 +41,13 @@ return command_line.HasSwitch(switches::kMultiInstall); } -// Disables the outdated build detector for |app_guid|. On failures, |detail| -// will be populated with a Windows error code corresponding to the failure -// mode. Returns the exit code for the operation. -ExitCode DisableForApp(bool system_level, - const wchar_t* app_guid, - uint32_t* detail) { +// Disables the outdated build detector for |app|. On failures, |detail| will be +// populated with a Windows error code corresponding to the failure mode. +// Returns the exit code for the operation. +ExitCode DisableForApp(bool system_level, App app, uint32_t* detail) { base::win::RegKey key; - *detail = OpenClientStateKey(system_level, app_guid, &key); + *detail = OpenClientStateKey(system_level, app, &key); if (*detail == ERROR_FILE_NOT_FOUND) return ExitCode::NO_CHROME; if (*detail != ERROR_SUCCESS) @@ -78,14 +76,14 @@ // for the operation. ExitCode DisableOutdatedBuildDetectorImpl(bool system_level, uint32_t* detail) { // Update Chrome's brand code. - ExitCode exit_code = DisableForApp(system_level, kChromeAppGuid, detail); + ExitCode exit_code = DisableForApp(system_level, App::CHROME_BROWSER, detail); // If that succeeded and Chrome is multi-install, make a best-effort attempt // to update the binaries' brand code. if (exit_code == ExitCode::CHROME_BRAND_UPDATED && IsChromeMultiInstall(system_level)) { ExitCode secondary_code = - DisableForApp(system_level, kBinariesAppGuid, detail); + DisableForApp(system_level, App::CHROME_BINARIES, detail); if (secondary_code == ExitCode::CHROME_BRAND_UPDATED) exit_code = ExitCode::BOTH_BRANDS_UPDATED; }
diff --git a/chrome/tools/disable_outdated_build_detector/google_update_integration.cc b/chrome/tools/disable_outdated_build_detector/google_update_integration.cc index 604f682d..19e08a3 100644 --- a/chrome/tools/disable_outdated_build_detector/google_update_integration.cc +++ b/chrome/tools/disable_outdated_build_detector/google_update_integration.cc
@@ -9,13 +9,18 @@ #include "base/win/registry.h" uint32_t OpenClientStateKey(bool system_level, - const wchar_t* app_guid, + App app, base::win::RegKey* key) { #if defined(GOOGLE_CHROME_BUILD) + constexpr wchar_t kChromeAppGuid[] = + L"{8A69D345-D564-463c-AFF1-A69D9E530F96}"; + constexpr wchar_t kBinariesAppGuid[] = + L"{4DC8B4CA-1BDA-483e-B5FA-D3C12E15B62D}"; base::string16 path(base::StringPrintf( - L"Software\\Google\\Update\\ClientState\\%ls", app_guid)); + L"Software\\Google\\Update\\ClientState\\%ls", + (app == App::CHROME_BINARIES ? kBinariesAppGuid : kChromeAppGuid))); #else - base::string16 path(app_guid == kBinariesAppGuid + base::string16 path(app == App::CHROME_BINARIES ? L"Software\\Chromium Binaries" : L"Software\\Chromium"); #endif @@ -26,7 +31,7 @@ void WriteResultInfo(bool system_level, const ResultInfo& result_info) { base::win::RegKey key; - uint32_t result = OpenClientStateKey(system_level, kChromeAppGuid, &key); + uint32_t result = OpenClientStateKey(system_level, App::CHROME_BROWSER, &key); if (result != ERROR_SUCCESS) return; key.WriteValue(kInstallerResult,
diff --git a/chrome/tools/disable_outdated_build_detector/google_update_integration.h b/chrome/tools/disable_outdated_build_detector/google_update_integration.h index 7651354c..c8e1505 100644 --- a/chrome/tools/disable_outdated_build_detector/google_update_integration.h +++ b/chrome/tools/disable_outdated_build_detector/google_update_integration.h
@@ -22,12 +22,16 @@ uint32_t installer_extra_code1; }; +// An identifier of an app's registration with Google Update. +enum class App { + CHROME_BROWSER, + CHROME_BINARIES, +}; + // Opens the Google Update ClientState key in the registry for the app -// identified by |app_guid| at |system_level|. Returns ERROR_SUCCESS or another +// identified by |app| at |system_level|. Returns ERROR_SUCCESS or another // Windows error value. -uint32_t OpenClientStateKey(bool system_level, - const wchar_t* app_guid, - base::win::RegKey* key); +uint32_t OpenClientStateKey(bool system_level, App app, base::win::RegKey* key); // Writes the data in |result_info| into Chrome's ClientState key. void WriteResultInfo(bool system_level, const ResultInfo& result_info);
diff --git a/chrome/utility/chrome_content_utility_client.cc b/chrome/utility/chrome_content_utility_client.cc index cfe37b08..4621660 100644 --- a/chrome/utility/chrome_content_utility_client.cc +++ b/chrome/utility/chrome_content_utility_client.cc
@@ -152,8 +152,10 @@ bool ChromeContentUtilityClient::OnMessageReceived( const IPC::Message& message) { - if (filter_messages_ && !ContainsKey(message_id_whitelist_, message.type())) + if (filter_messages_ && + !base::ContainsKey(message_id_whitelist_, message.type())) { return false; + } bool handled = true; IPC_BEGIN_MESSAGE_MAP(ChromeContentUtilityClient, message)
diff --git a/chrome/utility/importer/firefox_importer.cc b/chrome/utility/importer/firefox_importer.cc index cbeab3b..e487c92e 100644 --- a/chrome/utility/importer/firefox_importer.cc +++ b/chrome/utility/importer/firefox_importer.cc
@@ -333,7 +333,7 @@ } } - STLDeleteElements(&list); + base::STLDeleteElements(&list); // Write into profile. if (!bookmarks.empty() && !cancelled()) {
diff --git a/chrome/utility/media_galleries/iapps_xml_utils.cc b/chrome/utility/media_galleries/iapps_xml_utils.cc index bb42f39..57d9cc6 100644 --- a/chrome/utility/media_galleries/iapps_xml_utils.cc +++ b/chrome/utility/media_galleries/iapps_xml_utils.cc
@@ -90,7 +90,7 @@ return result; result.resize(file_info.size); - int bytes_read = file.Read(0, string_as_array(&result), file_info.size); + int bytes_read = file.Read(0, base::string_as_array(&result), file_info.size); if (bytes_read != file_info.size) result.clear(); @@ -154,7 +154,7 @@ } bool XmlDictReader::Found(const std::string& key) const { - return ContainsKey(found_, key); + return base::ContainsKey(found_, key); } } // namespace iapps
diff --git a/chromecast/app/linux/cast_crash_reporter_client_unittest.cc b/chromecast/app/linux/cast_crash_reporter_client_unittest.cc index 48899f0..3e42fc8 100644 --- a/chromecast/app/linux/cast_crash_reporter_client_unittest.cc +++ b/chromecast/app/linux/cast_crash_reporter_client_unittest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include <fstream> +#include <vector> #include "base/base_paths.h" #include "base/bind.h" @@ -10,7 +11,6 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/macros.h" -#include "base/memory/scoped_vector.h" #include "base/test/scoped_path_override.h" #include "base/threading/thread_restrictions.h" #include "base/values.h" @@ -99,7 +99,7 @@ base::FilePath lockfile = home_path().Append("minidumps").Append("lockfile"); ASSERT_TRUE(base::PathExists(lockfile)); - ScopedVector<DumpInfo> dumps; + std::vector<std::unique_ptr<DumpInfo>> dumps; ASSERT_TRUE(FetchDumps(lockfile.value(), &dumps)); ASSERT_EQ(1u, dumps.size());
diff --git a/chromecast/base/cast_paths.cc b/chromecast/base/cast_paths.cc index ce726848..7a8fd9f 100644 --- a/chromecast/base/cast_paths.cc +++ b/chromecast/base/cast_paths.cc
@@ -47,6 +47,17 @@ #endif // defined(OS_ANDROID) return true; } + case FILE_CAST_CRL: { + base::FilePath data_dir; +#if defined(OS_ANDROID) + CHECK(PathService::Get(base::DIR_ANDROID_APP_DATA, &data_dir)); + *result = data_dir.Append("cast_shell.crl"); +#else + CHECK(PathService::Get(DIR_CAST_HOME, &data_dir)); + *result = data_dir.Append(".eureka.crl"); +#endif // defined(OS_ANDROID) + return true; + } case FILE_CAST_PAK: { base::FilePath base_dir; #if defined(OS_ANDROID)
diff --git a/chromecast/base/cast_paths.h b/chromecast/base/cast_paths.h index 11433a407..fa7bc63e 100644 --- a/chromecast/base/cast_paths.h +++ b/chromecast/base/cast_paths.h
@@ -22,6 +22,7 @@ FILE_CAST_ANDROID_LOG, // Log file location for Android. #endif // defined(OS_ANDROID) FILE_CAST_CONFIG, // Config/preferences file path. + FILE_CAST_CRL, // CRL persistent cache file path. FILE_CAST_PAK, // cast_shell.pak file path. PATH_END };
diff --git a/chromecast/base/chromecast_switches.cc b/chromecast/base/chromecast_switches.cc index d63c1c1..587c210 100644 --- a/chromecast/base/chromecast_switches.cc +++ b/chromecast/base/chromecast_switches.cc
@@ -14,6 +14,11 @@ // Value indicating whether flag from command line switch is false. const char kSwitchValueFalse[] = "false"; +// Server url to upload crash data to. +// Default is "http://clients2.google.com/cr/report" for prod devices. +// Default is "http://clients2.google.com/cr/staging_report" for non prod. +const char kCrashServerUrl[] = "crash-server-url"; + // Enable the CMA media pipeline. const char kEnableCmaMediaPipeline[] = "enable-cma-media-pipeline";
diff --git a/chromecast/base/chromecast_switches.h b/chromecast/base/chromecast_switches.h index 7fa69df..890c72a 100644 --- a/chromecast/base/chromecast_switches.h +++ b/chromecast/base/chromecast_switches.h
@@ -15,6 +15,9 @@ extern const char kSwitchValueTrue[]; extern const char kSwitchValueFalse[]; +// Url to upload crash data to. +extern const char kCrashServerUrl[]; + // Media switches extern const char kEnableCmaMediaPipeline[];
diff --git a/chromecast/crash/BUILD.gn b/chromecast/crash/BUILD.gn index 888619df..765d03a 100644 --- a/chromecast/crash/BUILD.gn +++ b/chromecast/crash/BUILD.gn
@@ -2,6 +2,7 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//chromecast/chromecast.gni") import("//testing/test.gni") source_set("crash") { @@ -21,6 +22,8 @@ "linux/minidump_generator.h", "linux/minidump_params.cc", "linux/minidump_params.h", + "linux/minidump_uploader.cc", + "linux/minidump_uploader.h", "linux/minidump_writer.cc", "linux/minidump_writer.h", "linux/synchronized_minidump_manager.cc", @@ -32,7 +35,35 @@ "//breakpad:client", "//chromecast/base", "//chromecast/base:cast_version", + "//components/metrics", + "//components/prefs", ] + + if (chromecast_branding == "public") { + deps += [ "//chromecast/base:cast_sys_info" ] + } else { + deps += [ "//chromecast/base:cast_sys_info_shlib" ] + } +} + +executable("crash_uploader") { + sources = [ + "linux/crash_uploader.cc", + ] + + deps = [ + ":crash", + "//base", + "//chromecast/base", + "//chromecast/public", + "//chromecast/system/reboot:reboot_util", + ] + + if (chromecast_branding == "public") { + deps += [ "//chromecast/base:cast_sys_info" ] + } else { + deps += [ "//chromecast/base:cast_sys_info_shlib" ] + } } source_set("test_support") { @@ -54,6 +85,7 @@ "cast_crashdump_uploader_unittest.cc", "linux/dummy_minidump_generator_unittest.cc", "linux/dump_info_unittest.cc", + "linux/minidump_uploader_unittest.cc", "linux/minidump_writer_unittest.cc", "linux/synchronized_minidump_manager_unittest.cc", ] @@ -65,7 +97,10 @@ "//base/test:run_all_unittests", "//base/test:test_support", "//breakpad:client", + "//chromecast/base:cast_sys_info", "//chromecast/base:test_support", + "//components/metrics", + "//components/prefs:test_support", "//testing/gmock", "//testing/gtest", ]
diff --git a/chromecast/crash/cast_crashdump_uploader.h b/chromecast/crash/cast_crashdump_uploader.h index b1238940..29686b2 100644 --- a/chromecast/crash/cast_crashdump_uploader.h +++ b/chromecast/crash/cast_crashdump_uploader.h
@@ -42,9 +42,10 @@ explicit CastCrashdumpUploader(const CastCrashdumpData& data); ~CastCrashdumpUploader(); - bool AddAttachment(const std::string& label, const std::string& filename); - void SetParameter(const std::string& key, const std::string& value); - bool Upload(std::string* response); + virtual bool AddAttachment(const std::string& label, + const std::string& filename); + virtual void SetParameter(const std::string& key, const std::string& value); + virtual bool Upload(std::string* response); private: bool CheckRequiredParametersArePresent();
diff --git a/chromecast/crash/linux/DEPS b/chromecast/crash/linux/DEPS new file mode 100644 index 0000000..ed2a0a8 --- /dev/null +++ b/chromecast/crash/linux/DEPS
@@ -0,0 +1,6 @@ +include_rules = [ + "+chromecast/crash", + "+chromecast/system", + "+components/metrics", + "+components/prefs", +]
diff --git a/chromecast/crash/linux/crash_testing_utils.cc b/chromecast/crash/linux/crash_testing_utils.cc index 5dfdab2..e90228f 100644 --- a/chromecast/crash/linux/crash_testing_utils.cc +++ b/chromecast/crash/linux/crash_testing_utils.cc
@@ -17,8 +17,8 @@ #define RCHECK(cond, retval, err) \ do { \ - LOG(ERROR) << (err); \ if (!(cond)) { \ + LOG(ERROR) << (err); \ return (retval); \ } \ } while (0) @@ -88,7 +88,7 @@ } bool FetchDumps(const std::string& lockfile_path, - ScopedVector<DumpInfo>* dumps) { + std::vector<std::unique_ptr<DumpInfo>>* dumps) { DCHECK(dumps); std::unique_ptr<base::ListValue> dump_list = ParseLockFile(lockfile_path); RCHECK(dump_list, false, "Failed to parse lockfile"); @@ -117,7 +117,7 @@ base::DictionaryValue* ratelimit_fields = new base::DictionaryValue(); metadata->Set(kRatelimitKey, base::WrapUnique(ratelimit_fields)); - ratelimit_fields->SetString(kRatelimitPeriodStartKey, "0"); + ratelimit_fields->SetDouble(kRatelimitPeriodStartKey, 0.0); ratelimit_fields->SetInteger(kRatelimitPeriodDumpsKey, 0); std::unique_ptr<base::ListValue> dumps =
diff --git a/chromecast/crash/linux/crash_testing_utils.h b/chromecast/crash/linux/crash_testing_utils.h index fba70bc..55511f8 100644 --- a/chromecast/crash/linux/crash_testing_utils.h +++ b/chromecast/crash/linux/crash_testing_utils.h
@@ -6,8 +6,8 @@ #define CHROMECAST_CRASH_LINUX_CRASH_TESTING_UTILS_H_ #include <memory> +#include <vector> -#include "base/memory/scoped_vector.h" #include "base/time/time.h" namespace chromecast { @@ -22,7 +22,7 @@ // Populates |dumps| with all the DumpInfo entries serialized in the lockfile at // |lockfile_path|. Returns true on success, false on error. bool FetchDumps(const std::string& lockfile_path, - ScopedVector<DumpInfo>* dumps); + std::vector<std::unique_ptr<DumpInfo>>* dumps); // Clear all dumps in the lockfile at |lockfile_path|. // Returns true on success, false on error.
diff --git a/chromecast/crash/linux/crash_uploader.cc b/chromecast/crash/linux/crash_uploader.cc new file mode 100644 index 0000000..a12d0e84 --- /dev/null +++ b/chromecast/crash/linux/crash_uploader.cc
@@ -0,0 +1,71 @@ +// Copyright 2016 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 <sys/resource.h> + +#include <memory> +#include <utility> + +#include "base/at_exit.h" +#include "base/bind.h" +#include "base/command_line.h" +#include "base/logging.h" +#include "base/message_loop/message_loop.h" +#include "base/threading/platform_thread.h" +#include "base/time/time.h" +#include "chromecast/base/cast_paths.h" +#include "chromecast/base/cast_sys_info_util.h" +#include "chromecast/base/chromecast_switches.h" +#include "chromecast/crash/linux/minidump_uploader.h" +#include "chromecast/public/cast_sys_info.h" +#include "chromecast/system/reboot/reboot_util.h" + +namespace { + +// Upload crash dump for every 60 seconds. +const int kUploadRetryIntervalDefault = 60; + +} // namespace + +int main(int argc, char** argv) { + base::AtExitManager exit_manager; + base::CommandLine::Init(argc, argv); + chromecast::RegisterPathProvider(); + logging::InitLogging(logging::LoggingSettings()); + + LOG(INFO) << "Starting crash uploader..."; + + // Nice +19. Crash uploads are not time critical and we don't want to + // interfere with user playback. + setpriority(PRIO_PROCESS, 0, 19); + + // Create the main message loop. + base::MessageLoopForIO message_loop; + + std::unique_ptr<chromecast::CastSysInfo> sys_info = + chromecast::CreateSysInfo(); + + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + std::string server_url( + command_line->GetSwitchValueASCII(switches::kCrashServerUrl)); + chromecast::MinidumpUploader uploader(sys_info.get(), server_url); + while (true) { + bool successful = uploader.UploadAllMinidumps(); + if (uploader.reboot_scheduled()) + chromecast::RebootUtil::RebootNow( + chromecast::RebootShlib::CRASH_UPLOADER); + + if (successful) { + LOG(INFO) << "Dump files successfully managed."; + } else { + LOG(ERROR) << "Critical MinidumpUploader failure."; + return EXIT_FAILURE; + } + + base::PlatformThread::Sleep( + base::TimeDelta::FromSeconds(kUploadRetryIntervalDefault)); + } + + return EXIT_SUCCESS; +}
diff --git a/chromecast/crash/linux/minidump_uploader.cc b/chromecast/crash/linux/minidump_uploader.cc new file mode 100644 index 0000000..76c2210 --- /dev/null +++ b/chromecast/crash/linux/minidump_uploader.cc
@@ -0,0 +1,292 @@ +// Copyright 2016 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 "chromecast/crash/linux/minidump_uploader.h" + +#include <errno.h> +#include <regex.h> +#include <stdlib.h> +#include <string.h> + +#include <fstream> +#include <list> +#include <memory> +#include <sstream> +#include <vector> + +#include "base/bind.h" +#include "base/files/file_util.h" +#include "base/logging.h" +#include "base/path_service.h" +#include "base/single_thread_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" +#include "chromecast/base/cast_paths.h" +#include "chromecast/base/pref_names.h" +#include "chromecast/base/version.h" +#include "chromecast/crash/cast_crashdump_uploader.h" +#include "chromecast/crash/linux/dump_info.h" +#include "chromecast/public/cast_sys_info.h" +#include "components/metrics/metrics_pref_names.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" +#include "components/prefs/pref_service_factory.h" + +namespace chromecast { + +namespace { + +const char kProductName[] = "Eureka"; + +const char kCrashServerStaging[] = + "http://clients2.google.com/cr/staging_report"; +const char kCrashServerProduction[] = "http://clients2.google.com/cr/report"; + +typedef std::vector<std::unique_ptr<DumpInfo>> DumpList; + +std::unique_ptr<PrefService> CreatePrefService() { + base::FilePath prefs_path; + CHECK(PathService::Get(chromecast::FILE_CAST_CONFIG, &prefs_path)); + VLOG(1) << "Loading prefs from " << prefs_path.value(); + + PrefRegistrySimple* registry = new PrefRegistrySimple; + registry->RegisterBooleanPref(prefs::kOptInStats, true); + registry->RegisterStringPref(::metrics::prefs::kMetricsClientID, ""); + + PrefServiceFactory prefServiceFactory; + prefServiceFactory.SetUserPrefsFile( + prefs_path, base::ThreadTaskRunnerHandle::Get().get()); + return prefServiceFactory.Create(registry); +} + +bool IsDumpObsolete(const DumpInfo& dump) { + return dump.params().cast_release_version.empty() || + dump.params().cast_build_number.empty(); +} + +} // namespace + +MinidumpUploader::MinidumpUploader(CastSysInfo* sys_info, + const std::string& server_url, + CastCrashdumpUploader* const uploader, + const PrefServiceGeneratorCallback callback) + : release_channel_(sys_info->GetSystemReleaseChannel()), + product_name_(sys_info->GetProductName()), + device_model_(sys_info->GetDeviceModel()), + board_name_(sys_info->GetBoardName()), + board_revision_(sys_info->GetBoardRevision()), + manufacturer_(sys_info->GetManufacturer()), + system_version_(sys_info->GetSystemBuildNumber()), + upload_location_(!server_url.empty() + ? server_url + : (sys_info->GetBuildType() == CastSysInfo::BUILD_ENG + ? kCrashServerStaging + : kCrashServerProduction)), + last_upload_ratelimited_(true), + reboot_scheduled_(false), + uploader_(uploader), + pref_service_generator_(callback) {} + +MinidumpUploader::MinidumpUploader(CastSysInfo* sys_info, + const std::string& server_url) + : MinidumpUploader(sys_info, + server_url, + nullptr, + base::Bind(&CreatePrefService)) {} + +MinidumpUploader::~MinidumpUploader() {} + +bool MinidumpUploader::UploadAllMinidumps() { + if (HasDumps()) + return AcquireLockAndDoWork(); + + return true; +} + +bool MinidumpUploader::DoWork() { + // Read the file stream line by line into a list. As each file is uploaded, + // it is subsequently deleted from the list. If the file cannot be found + // (which is a possible scenario if the file uploaded previously, but the + // device powered off before the log could be updated), it is also deleted. + // Whenever an upload fails (due to lost connection), the remaining entries + // on the list will overwrite the log file. This way, the log file reflects + // the state of the un-uploaded dumps as best as it can. + // Note: it is also possible that a dump previously uploaded exists in the + // list, *and* can also be found. This might happen if the device powered + // off before the dump can be deleted and the log updated. This is + // unpreventable. + + DumpList dumps(GetDumps()); + + int num_uploaded = 0; + + std::unique_ptr<PrefService> pref_service = pref_service_generator_.Run(); + const std::string& client_id( + pref_service->GetString(::metrics::prefs::kMetricsClientID)); + bool opt_in_stats = pref_service->GetBoolean(prefs::kOptInStats); + // Handle each dump and consume it out of the structure. + while (dumps.size()) { + const DumpInfo& dump = *(dumps.front()); + const base::FilePath dump_path(dump.crashed_process_dump()); + base::FilePath log_path(dump.logfile()); + + bool ignore_and_erase_dump = false; + if (!opt_in_stats) { + LOG(INFO) << "OptInStats is false, removing crash dump"; + ignore_and_erase_dump = true; + } else if (IsDumpObsolete(dump)) { + NOTREACHED(); + LOG(INFO) << "DumpInfo belongs to older version, removing crash dump"; + ignore_and_erase_dump = true; + } + + // Ratelimiting persists across reboots, thus we to keep track of + // last_upload_ratelimited_ to detect when we first become ratelimited. + // Otherwise once ratelimited, we will reboot every time we try to upload a + // dump. + if (CanUploadDump()) { + last_upload_ratelimited_ = false; + } else { + LOG(INFO) << "Can't upload dump: Ratelimited."; + ignore_and_erase_dump = true; + + // If the last upload wasn't ratelimited and this one is, then this is the + // first time we reached the ratelimit. Reboot the device. + if (!last_upload_ratelimited_) + reboot_scheduled_ = true; + + last_upload_ratelimited_ = true; + } + + // Record dump for ratelimiting + IncrementNumDumpsInCurrentPeriod(); + + if (ignore_and_erase_dump) { + base::DeleteFile(dump_path, false); + base::DeleteFile(log_path, false); + dumps.erase(dumps.begin()); + continue; + } + + LOG(INFO) << "OptInStats is true, uploading crash dump"; + + int64_t size; + if (!dump_path.empty() && !base::GetFileSize(dump_path, &size)) { + // either the file does not exist, or there was an error logging its + // path, or settings its permission; regardless, we can't upload it. + dumps.erase(dumps.begin()); + continue; + } + + std::stringstream comment; + if (log_path.empty()) { + comment << "Log file not specified. "; + } else if (!base::GetFileSize(log_path, &size)) { + comment << "Can't get size of " << log_path.value() << ": " + << strerror(errno); + // if we can't find the log file, don't upload the log + log_path.clear(); + } else { + comment << "Log size is " << size << ". "; + } + + std::stringstream uptime_stream; + uptime_stream << dump.params().process_uptime; + + const std::string version(dump.params().cast_release_version + "." + + dump.params().cast_build_number + + dump.params().suffix); + // attempt to upload + LOG(INFO) << "Uploading crash to " << upload_location_; + CastCrashdumpData crashdump_data; + crashdump_data.product = kProductName; + crashdump_data.version = version; + crashdump_data.guid = client_id; + crashdump_data.ptime = uptime_stream.str(); + crashdump_data.comments = comment.str(); + crashdump_data.minidump_pathname = dump_path.value(); + crashdump_data.crash_server = upload_location_; + + // Depending on if a testing CastCrashdumpUploader object has been set, + // assign |g| as a reference to the correct object. + CastCrashdumpUploader vanilla(crashdump_data); + CastCrashdumpUploader& g = (uploader_ ? *uploader_ : vanilla); + + if (!log_path.empty() && !g.AddAttachment("log_file", log_path.value())) { + LOG(ERROR) << "Could not attach log file " << log_path.value(); + // Don't fail to upload just because of this. + comment << "Could not attach log file " << log_path.value() << ". "; + } + + // Dump some Android properties directly into product data. + g.SetParameter("ro.revision", board_revision_); + g.SetParameter("ro.product.release.track", release_channel_); + g.SetParameter("ro.hardware", board_name_); + g.SetParameter("ro.product.name", product_name_); + g.SetParameter("ro.product.model", device_model_); + g.SetParameter("ro.product.manufacturer", manufacturer_); + g.SetParameter("ro.system.version", system_version_); + + // Add app state information + if (!dump.params().previous_app_name.empty()) { + g.SetParameter("previous_app", dump.params().previous_app_name); + } + if (!dump.params().current_app_name.empty()) { + g.SetParameter("current_app", dump.params().current_app_name); + } + if (!dump.params().last_app_name.empty()) { + g.SetParameter("last_app", dump.params().last_app_name); + } + if (!dump.params().reason.empty()) { + g.SetParameter("reason", dump.params().reason); + } + + std::string response; + if (!g.Upload(&response)) { + // We have failed to upload this file. + // Save our state by flushing our dumps to the lockfile + // We'll come back around later and try again. + LOG(ERROR) << "Upload report failed. response: " << response; + SetCurrentDumps(dumps); + return true; + } + + LOG(INFO) << "Uploaded report id " << response; + // upload succeeded, so delete the entry + dumps.erase(dumps.begin()); + // delete the dump if it exists in /data/minidumps. + // (We may use a fake dump file which should not be deleted.) + if (!dump_path.empty() && dump_path.DirName() == dump_path_ && + !base::DeleteFile(dump_path, false)) { + LOG(WARNING) << "remove dump " << dump_path.value() << " failed" + << strerror(errno); + } + // delete the log if exists + if (!log_path.empty() && !base::DeleteFile(log_path, false)) { + LOG(WARNING) << "remove log " << log_path.value() << " failed" + << strerror(errno); + } + ++num_uploaded; + } + + // This will simply empty the log file. + // Entries should either be skipped/deleted or processed/deleted. + SetCurrentDumps(dumps); + + // If we reach here, then the log file should be empty, and there should + // be no more dumps to upload. However, it is possible that there are + // lingering files (for example, if the dump was written, but the log + // updating failed). Since we have no entries on these files, we cannot + // upload them. Therefore we should delete them. This is also a good way + // to make sure system resources aren't being drained. + + int num_deleted = GetNumDumps(true /* delete_all_dumps */); + if (num_deleted > 0) { + LOG(WARNING) << num_deleted << " lingering dump files deleted."; + } + + LOG(INFO) << num_uploaded << " dumps were uploaded."; + return true; +} + +} // namespace chromecast
diff --git a/chromecast/crash/linux/minidump_uploader.h b/chromecast/crash/linux/minidump_uploader.h new file mode 100644 index 0000000..dc46d00 --- /dev/null +++ b/chromecast/crash/linux/minidump_uploader.h
@@ -0,0 +1,76 @@ +// Copyright 2016 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 CHROMECAST_CRASH_LINUX_MINIDUMP_UPLOADER_H_ +#define CHROMECAST_CRASH_LINUX_MINIDUMP_UPLOADER_H_ + +#include <string> + +#include "base/callback.h" +#include "base/macros.h" +#include "chromecast/crash/linux/synchronized_minidump_manager.h" + +class PrefService; + +namespace chromecast { + +class CastCrashdumpUploader; +class CastSysInfo; + +// Class for uploading minidumps with synchronized access to the minidumps +// directory. +class MinidumpUploader : public SynchronizedMinidumpManager { + public: + using PrefServiceGeneratorCallback = + base::Callback<std::unique_ptr<PrefService>()>; + + // If |server_url| is empty, a default server url will be chosen. + MinidumpUploader(CastSysInfo* sys_info, const std::string& server_url); + MinidumpUploader(CastSysInfo* sys_info, + const std::string& server_url, + CastCrashdumpUploader* const uploader, + const PrefServiceGeneratorCallback callback); + ~MinidumpUploader() override; + + // Attempts to upload all minidumps in the minidumps directory. Acquires a + // mutually exclusive lock on the directory before doing work to ensure that + // access to these minidumps is synchronized between other instances of this + // class. Returns true if successful, false otherwise. + bool UploadAllMinidumps(); + + bool reboot_scheduled() const { return reboot_scheduled_; } + + private: + // SynchronizedMinidumpManager implementation: + bool DoWork() override; + + // From CastSysInfo. + const std::string release_channel_; + const std::string product_name_; + const std::string device_model_; + const std::string board_name_; + const std::string board_revision_; + const std::string manufacturer_; + const std::string system_version_; + + const std::string upload_location_; + + // Whether or not we were ratelimited for the last upload. + // Used to detect when we first become ratelimited. Must be initialized to + // true to prevent reboot loops when ratelimited. + bool last_upload_ratelimited_; + + // Whether or not a reboot should be scheduled. + bool reboot_scheduled_; + + // Used for injecting mocks/inducing different behavior in unittests. + CastCrashdumpUploader* const uploader_; + const PrefServiceGeneratorCallback pref_service_generator_; + + DISALLOW_COPY_AND_ASSIGN(MinidumpUploader); +}; + +} // namespace chromecast + +#endif // CHROMECAST_CRASH_LINUX_MINIDUMP_UPLOADER_H_
diff --git a/chromecast/crash/linux/minidump_uploader_unittest.cc b/chromecast/crash/linux/minidump_uploader_unittest.cc new file mode 100644 index 0000000..3a33da8 --- /dev/null +++ b/chromecast/crash/linux/minidump_uploader_unittest.cc
@@ -0,0 +1,374 @@ +// Copyright 2016 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 "chromecast/crash/linux/minidump_uploader.h" + +#include <memory> +#include <vector> + +#include "base/base_paths.h" +#include "base/bind.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/test/scoped_path_override.h" +#include "base/time/time.h" +#include "chromecast/base/cast_sys_info_dummy.h" +#include "chromecast/base/pref_names.h" +#include "chromecast/crash/cast_crashdump_uploader.h" +#include "chromecast/crash/linux/crash_testing_utils.h" +#include "chromecast/public/cast_sys_info.h" +#include "components/metrics/metrics_pref_names.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" +#include "components/prefs/testing_pref_service.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chromecast { +namespace { + +const char kLockfileName[] = "lockfile"; +const char kMetadataName[] = "metadata"; +const char kMinidumpSubdir[] = "minidumps"; + +typedef std::vector<std::unique_ptr<DumpInfo>> DumpList; + +std::unique_ptr<PrefService> CreateFakePrefService(bool opt_in) { + std::unique_ptr<TestingPrefServiceSimple> retval( + new TestingPrefServiceSimple); + retval->registry()->RegisterBooleanPref(prefs::kOptInStats, opt_in); + retval->registry()->RegisterStringPref(::metrics::prefs::kMetricsClientID, + ""); + return retval; +} + +bool DumpsAreEqual(const DumpInfo& l, const DumpInfo& r) { + return l.crashed_process_dump() == r.crashed_process_dump() && + l.logfile() == r.logfile(); +} + +class MockCastCrashdumpUploader : public CastCrashdumpUploader { + public: + MockCastCrashdumpUploader(const CastCrashdumpData& data) + : CastCrashdumpUploader(data) {} + + MOCK_METHOD2(AddAttachment, + bool(const std::string& label, const std::string& filename)); + MOCK_METHOD2(SetParameter, + void(const std::string& key, const std::string& value)); + MOCK_METHOD1(Upload, bool(std::string* response)); +}; + +using ::testing::_; +using ::testing::AtLeast; +using ::testing::Return; +using ::testing::StrictMock; + +class MinidumpUploaderTest : public testing::Test { + public: + MinidumpUploaderTest() {} + ~MinidumpUploaderTest() override {} + + protected: + void SetUp() override { + // Set up a temporary directory which will be used as our fake home dir. + ASSERT_TRUE(fake_home_dir_.CreateUniqueTempDir()); + path_override_.reset( + new base::ScopedPathOverride(base::DIR_HOME, fake_home_dir_.path())); + + minidump_dir_ = fake_home_dir_.path().Append(kMinidumpSubdir); + lockfile_ = minidump_dir_.Append(kLockfileName); + metadata_ = minidump_dir_.Append(kMetadataName); + + // Create minidump directory. + ASSERT_TRUE(base::CreateDirectory(minidump_dir_)); + + CastCrashdumpData data; + mock_crash_uploader_.reset(new StrictMock<MockCastCrashdumpUploader>(data)); + } + + std::unique_ptr<DumpInfo> GenerateDumpWithFiles( + const base::FilePath& minidump_path, + const base::FilePath& logfile_path) { + // Must pass in non-empty MinidumpParams to circumvent the internal checks. + std::unique_ptr<DumpInfo> dump(new DumpInfo( + minidump_path.value(), logfile_path.value(), base::Time::Now(), + MinidumpParams("_", 0, "_", "_", "_", "_", "_", "_", "_"))); + + CHECK(AppendLockFile(lockfile_.value(), metadata_.value(), *dump)); + base::File minidump( + minidump_path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); + base::File logfile(logfile_path, + base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); + CHECK(minidump.IsValid()); + CHECK(logfile.IsValid()); + + return dump; + } + + MockCastCrashdumpUploader& mock_crash_uploader() { + return *mock_crash_uploader_; + } + + CastSysInfoDummy& sys_info_dummy() { return sys_info_dummy_; } + + base::FilePath minidump_dir_; // Path to the minidump directory. + base::FilePath lockfile_; // Path to the lockfile in |minidump_dir_|. + base::FilePath metadata_; // Path to the metadata in |minidump_dir_|. + + private: + base::ScopedTempDir fake_home_dir_; + std::unique_ptr<base::ScopedPathOverride> path_override_; + + CastSysInfoDummy sys_info_dummy_; + std::unique_ptr<StrictMock<MockCastCrashdumpUploader>> mock_crash_uploader_; +}; + +TEST_F(MinidumpUploaderTest, AvoidsLockingWithoutDumps) { + MinidumpUploader uploader(&sys_info_dummy(), "", &mock_crash_uploader(), + base::Bind(&CreateFakePrefService, true)); + + // Ensure the uploader did not initialize files unnecessarily. + ASSERT_TRUE(uploader.UploadAllMinidumps()); + ASSERT_TRUE(base::IsDirectoryEmpty(minidump_dir_)); +} + +TEST_F(MinidumpUploaderTest, RemovesDumpsWithoutOptIn) { + const base::FilePath& minidump_path = minidump_dir_.Append("ayy"); + const base::FilePath& logfile_path = minidump_dir_.Append("lmao"); + + // Write a dump info entry. + GenerateDumpWithFiles(minidump_path, logfile_path); + MinidumpUploader uploader(&sys_info_dummy(), "", &mock_crash_uploader(), + base::Bind(&CreateFakePrefService, false)); + + // MinidumpUploader should not call upon CastCrashdumpUploader. + ASSERT_TRUE(uploader.UploadAllMinidumps()); + + // Ensure dump files were deleted, lockfile was emptied. + ASSERT_FALSE(base::PathExists(minidump_path)); + ASSERT_FALSE(base::PathExists(logfile_path)); + + int64_t size = -1; + ASSERT_TRUE(base::GetFileSize(lockfile_, &size)); + ASSERT_EQ(size, 0); +} + +TEST_F(MinidumpUploaderTest, SavesDumpInfoWithUploadFailure) { + const base::FilePath& minidump_path = minidump_dir_.Append("ayy"); + const base::FilePath& logfile_path = minidump_dir_.Append("lmao"); + + // Write one entry with appropriate files. + std::unique_ptr<DumpInfo> dump( + GenerateDumpWithFiles(minidump_path, logfile_path)); + MinidumpUploader uploader(&sys_info_dummy(), "", &mock_crash_uploader(), + base::Bind(&CreateFakePrefService, true)); + + // Induce an upload failure. + EXPECT_CALL(mock_crash_uploader(), + AddAttachment("log_file", logfile_path.value())) + .WillOnce(Return(true)); + EXPECT_CALL(mock_crash_uploader(), SetParameter(_, _)).Times(AtLeast(0)); + EXPECT_CALL(mock_crash_uploader(), Upload(_)).WillOnce(Return(false)); + ASSERT_TRUE(uploader.UploadAllMinidumps()); + + // Ensure dump files were preserved, lockfile was not emptied. + ASSERT_TRUE(base::PathExists(minidump_path)); + ASSERT_TRUE(base::PathExists(logfile_path)); + + DumpList dumps; + ASSERT_TRUE(FetchDumps(lockfile_.value(), &dumps)); + ASSERT_TRUE(DumpsAreEqual(*dump, *dumps.front())); +} + +TEST_F(MinidumpUploaderTest, SavesRemainingDumpInfoWithMidwayUploadFailure) { + const base::FilePath& minidump_path = minidump_dir_.Append("ayy"); + const base::FilePath& logfile_path = minidump_dir_.Append("lmao"); + const base::FilePath& minidump_path2 = minidump_dir_.Append("ayy2"); + const base::FilePath& logfile_path2 = minidump_dir_.Append("lmao2"); + + // Write two entries, each with their own files. + GenerateDumpWithFiles(minidump_path, logfile_path); + std::unique_ptr<DumpInfo> dump2( + GenerateDumpWithFiles(minidump_path2, logfile_path2)); + MinidumpUploader uploader(&sys_info_dummy(), "", &mock_crash_uploader(), + base::Bind(&CreateFakePrefService, true)); + + // First allow a successful upload, then induce failure. + EXPECT_CALL(mock_crash_uploader(), + AddAttachment("log_file", logfile_path.value())) + .WillOnce(Return(true)); + EXPECT_CALL(mock_crash_uploader(), + AddAttachment("log_file", logfile_path2.value())) + .WillOnce(Return(true)); + EXPECT_CALL(mock_crash_uploader(), SetParameter(_, _)).Times(AtLeast(0)); + EXPECT_CALL(mock_crash_uploader(), Upload(_)) + .WillOnce(Return(true)) + .WillOnce(Return(false)); + ASSERT_TRUE(uploader.UploadAllMinidumps()); + + // Info should exist in the lockfile, but should only be non-uploaded dump. + DumpList dumps; + ASSERT_TRUE(FetchDumps(lockfile_.value(), &dumps)); + ASSERT_TRUE(DumpsAreEqual(*dump2, *dumps.front())); + + // Ensure uploaded files are gone, non-uploaded files remain. + ASSERT_FALSE(base::PathExists(minidump_path)); + ASSERT_FALSE(base::PathExists(logfile_path)); + ASSERT_TRUE(base::PathExists(minidump_path2)); + ASSERT_TRUE(base::PathExists(logfile_path2)); + + // Finally, upload successfully. + EXPECT_CALL(mock_crash_uploader(), + AddAttachment("log_file", logfile_path2.value())) + .WillOnce(Return(true)); + EXPECT_CALL(mock_crash_uploader(), SetParameter(_, _)).Times(AtLeast(0)); + EXPECT_CALL(mock_crash_uploader(), Upload(_)).WillOnce(Return(true)); + ASSERT_TRUE(uploader.UploadAllMinidumps()); + + // Ensure all dump files have been removed, lockfile has been emptied. + int64_t size = -1; + ASSERT_TRUE(base::GetFileSize(lockfile_, &size)); + ASSERT_EQ(size, 0); + + ASSERT_TRUE(base::DeleteFile(lockfile_, false)); + ASSERT_TRUE(base::DeleteFile(metadata_, false)); + ASSERT_TRUE(base::IsDirectoryEmpty(minidump_dir_)); +} + +TEST_F(MinidumpUploaderTest, FailsUploadWithMissingMinidumpFile) { + const base::FilePath& minidump_path = minidump_dir_.Append("ayy"); + const base::FilePath& logfile_path = minidump_dir_.Append("lmao"); + + // Write one entry with appropriate files. + GenerateDumpWithFiles(minidump_path, logfile_path); + MinidumpUploader uploader(&sys_info_dummy(), "", &mock_crash_uploader(), + base::Bind(&CreateFakePrefService, true)); + + // No CastCrashdumpUploader methods should be called. + ASSERT_TRUE(base::DeleteFile(minidump_path, false)); + ASSERT_TRUE(uploader.UploadAllMinidumps()); + + // Ensure dump files were deleted, lockfile was emptied. + ASSERT_FALSE(base::PathExists(minidump_path)); + ASSERT_FALSE(base::PathExists(logfile_path)); + + int64_t size = -1; + ASSERT_TRUE(base::GetFileSize(lockfile_, &size)); + ASSERT_EQ(size, 0); +} + +TEST_F(MinidumpUploaderTest, UploadsWithoutMissingLogFile) { + const base::FilePath& minidump_path = minidump_dir_.Append("ayy"); + const base::FilePath& logfile_path = minidump_dir_.Append("lmao"); + + // Write one entry with appropriate files. + GenerateDumpWithFiles(minidump_path, logfile_path); + MinidumpUploader uploader(&sys_info_dummy(), "", &mock_crash_uploader(), + base::Bind(&CreateFakePrefService, true)); + + // Delete logfile, crash uploader should still work as intended. + ASSERT_TRUE(base::DeleteFile(logfile_path, false)); + EXPECT_CALL(mock_crash_uploader(), SetParameter(_, _)).Times(AtLeast(0)); + EXPECT_CALL(mock_crash_uploader(), Upload(_)).WillOnce(Return(true)); + ASSERT_TRUE(uploader.UploadAllMinidumps()); + + // Ensure dump files were deleted, lockfile was emptied. + ASSERT_FALSE(base::PathExists(minidump_path)); + ASSERT_FALSE(base::PathExists(logfile_path)); + + int64_t size = -1; + ASSERT_TRUE(base::GetFileSize(lockfile_, &size)); + ASSERT_EQ(size, 0); +} + +TEST_F(MinidumpUploaderTest, DeletesLingeringFiles) { + const base::FilePath& minidump_path = minidump_dir_.Append("ayy"); + const base::FilePath& logfile_path = minidump_dir_.Append("lmao"); + const base::FilePath& temp1 = minidump_dir_.Append("chrome"); + const base::FilePath& temp2 = minidump_dir_.Append("cast"); + + // Create "fake" lingering files in minidump directory. + base::File generator(temp1, + base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); + generator.Close(); + generator.Initialize(temp2, + base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); + generator.Close(); + ASSERT_TRUE(base::PathExists(temp1)); + ASSERT_TRUE(base::PathExists(temp2)); + + // Write a real entry. + GenerateDumpWithFiles(minidump_path, logfile_path); + MinidumpUploader uploader(&sys_info_dummy(), "", &mock_crash_uploader(), + base::Bind(&CreateFakePrefService, true)); + + EXPECT_CALL(mock_crash_uploader(), + AddAttachment("log_file", logfile_path.value())) + .WillOnce(Return(true)); + EXPECT_CALL(mock_crash_uploader(), SetParameter(_, _)).Times(AtLeast(0)); + EXPECT_CALL(mock_crash_uploader(), Upload(_)).WillOnce(Return(true)); + ASSERT_TRUE(uploader.UploadAllMinidumps()); + + // Ensure dump/lingering files were deleted, lockfile was emptied. + ASSERT_FALSE(base::PathExists(minidump_path)); + ASSERT_FALSE(base::PathExists(logfile_path)); + ASSERT_FALSE(base::PathExists(temp1)); + ASSERT_FALSE(base::PathExists(temp2)); + + int64_t size = -1; + ASSERT_TRUE(base::GetFileSize(lockfile_, &size)); + ASSERT_EQ(size, 0); +} + +TEST_F(MinidumpUploaderTest, SchedulesRebootWhenRatelimited) { + const base::FilePath& minidump_path = minidump_dir_.Append("ayy"); + const base::FilePath& logfile_path = minidump_dir_.Append("lmao"); + + MinidumpUploader uploader(&sys_info_dummy(), "", &mock_crash_uploader(), + base::Bind(&CreateFakePrefService, true)); + // Generate max dumps. + for (int i = 0; i < SynchronizedMinidumpManager::kRatelimitPeriodMaxDumps + 1; + i++) + GenerateDumpWithFiles(minidump_path, logfile_path); + + // MinidumpUploader should call CastCrashdumpUploader once (other |max| dumps + // files do not exist). Reboot should be scheduled, as this is first + // ratelimit. + EXPECT_CALL(mock_crash_uploader(), + AddAttachment("log_file", logfile_path.value())) + .WillOnce(Return(true)); + EXPECT_CALL(mock_crash_uploader(), SetParameter(_, _)).Times(AtLeast(0)); + EXPECT_CALL(mock_crash_uploader(), Upload(_)).WillOnce(Return(true)); + ASSERT_TRUE(uploader.UploadAllMinidumps()); + ASSERT_TRUE(uploader.reboot_scheduled()); + + // Ensure dump files were deleted, lockfile was emptied. + ASSERT_FALSE(base::PathExists(minidump_path)); + ASSERT_FALSE(base::PathExists(logfile_path)); + + int64_t size = -1; + ASSERT_TRUE(base::GetFileSize(lockfile_, &size)); + ASSERT_EQ(size, 0); + + // Generate one dump for a second pass. + GenerateDumpWithFiles(minidump_path, logfile_path); + MinidumpUploader uploader2(&sys_info_dummy(), "", &mock_crash_uploader(), + base::Bind(&CreateFakePrefService, true)); + + // MinidumpUploader should not call CastCrashdumpUploader (due to ratelimit). + // Reboot should NOT be scheduled, as this is second ratelimit. + ASSERT_TRUE(uploader2.UploadAllMinidumps()); + ASSERT_FALSE(uploader2.reboot_scheduled()); + + // Ensure dump files were deleted, lockfile was emptied. + ASSERT_FALSE(base::PathExists(minidump_path)); + ASSERT_FALSE(base::PathExists(logfile_path)); + + ASSERT_TRUE(base::GetFileSize(lockfile_, &size)); + ASSERT_EQ(size, 0); +} + +} // namespace +} // namespace chromecast
diff --git a/chromecast/crash/linux/synchronized_minidump_manager.cc b/chromecast/crash/linux/synchronized_minidump_manager.cc index 8fa73d7..6a0a0a7 100644 --- a/chromecast/crash/linux/synchronized_minidump_manager.cc +++ b/chromecast/crash/linux/synchronized_minidump_manager.cc
@@ -329,21 +329,21 @@ metadata_.reset(); } -ScopedVector<DumpInfo> SynchronizedMinidumpManager::GetDumps() { - ScopedVector<DumpInfo> dumps; +std::vector<std::unique_ptr<DumpInfo>> SynchronizedMinidumpManager::GetDumps() { + std::vector<std::unique_ptr<DumpInfo>> dumps; for (const auto& elem : *dumps_) { - dumps.push_back(new DumpInfo(elem.get())); + dumps.push_back(std::unique_ptr<DumpInfo>(new DumpInfo(elem.get()))); } return dumps; } bool SynchronizedMinidumpManager::SetCurrentDumps( - const ScopedVector<DumpInfo>& dumps) { + const std::vector<std::unique_ptr<DumpInfo>>& dumps) { dumps_->Clear(); - for (DumpInfo* dump : dumps) + for (auto& dump : dumps) dumps_->Append(dump->GetAsValue()); return true;
diff --git a/chromecast/crash/linux/synchronized_minidump_manager.h b/chromecast/crash/linux/synchronized_minidump_manager.h index 9bd09a0..4441624 100644 --- a/chromecast/crash/linux/synchronized_minidump_manager.h +++ b/chromecast/crash/linux/synchronized_minidump_manager.h
@@ -5,9 +5,10 @@ #ifndef CHROMECAST_CRASH_LINUX_SYNCHRONIZED_MINIDUMP_MANAGER_H_ #define CHROMECAST_CRASH_LINUX_SYNCHRONIZED_MINIDUMP_MANAGER_H_ +#include <vector> + #include "base/files/file_path.h" #include "base/macros.h" -#include "base/memory/scoped_vector.h" #include "base/values.h" #include "chromecast/crash/linux/dump_info.h" @@ -65,10 +66,10 @@ virtual bool DoWork() = 0; // Get the current dumps in the lockfile. - ScopedVector<DumpInfo> GetDumps(); + std::vector<std::unique_ptr<DumpInfo>> GetDumps(); // Set |dumps| as the dumps in |lockfile_|, replacing current list of dumps. - bool SetCurrentDumps(const ScopedVector<DumpInfo>& dumps); + bool SetCurrentDumps(const std::vector<std::unique_ptr<DumpInfo>>& dumps); // Serialize |dump_info| and append it to the lockfile. Note that the child // class must only call this inside DoWork(). This should be the only method
diff --git a/chromecast/crash/linux/synchronized_minidump_manager_unittest.cc b/chromecast/crash/linux/synchronized_minidump_manager_unittest.cc index fa3e22c..555e963 100644 --- a/chromecast/crash/linux/synchronized_minidump_manager_unittest.cc +++ b/chromecast/crash/linux/synchronized_minidump_manager_unittest.cc
@@ -16,6 +16,7 @@ #include <fstream> #include <memory> #include <utility> +#include <vector> #include "base/base_paths.h" #include "base/bind.h" @@ -23,7 +24,6 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/memory/ptr_util.h" -#include "base/memory/scoped_vector.h" #include "base/process/launch.h" #include "base/test/scoped_path_override.h" #include "base/threading/platform_thread.h" @@ -40,6 +40,8 @@ const char kMetadataName[] = "metadata"; const char kMinidumpSubdir[] = "minidumps"; +typedef std::vector<std::unique_ptr<DumpInfo>> DumpList; + // A trivial implementation of SynchronizedMinidumpManager, which does no work // to the minidump and exposes its protected members for testing. This simply // adds an entry to the lockfile. @@ -249,7 +251,7 @@ ASSERT_FALSE(manager.add_entry_return_code()); // Verify the lockfile is untouched. - ScopedVector<DumpInfo> dumps; + DumpList dumps; ASSERT_TRUE(FetchDumps(lockfile_.value(), &dumps)); ASSERT_EQ(0u, dumps.size()); } @@ -269,7 +271,7 @@ ASSERT_TRUE(manager.add_entry_return_code()); // Test that the manager was successful in logging the entry. - ScopedVector<DumpInfo> dumps; + DumpList dumps; ASSERT_TRUE(FetchDumps(lockfile_.value(), &dumps)); ASSERT_EQ(1u, dumps.size()); @@ -325,7 +327,7 @@ EXPECT_TRUE(sleepy_manager.work_done()); // Test that both entries were logged. - ScopedVector<DumpInfo> dumps; + DumpList dumps; ASSERT_TRUE(FetchDumps(lockfile_.value(), &dumps)); EXPECT_EQ(2u, dumps.size()); } @@ -372,7 +374,7 @@ EXPECT_TRUE(manager.work_done()); // Test that both entries were logged. - ScopedVector<DumpInfo> dumps; + DumpList dumps; ASSERT_TRUE(FetchDumps(lockfile_.value(), &dumps)); EXPECT_EQ(2u, dumps.size()); }
diff --git a/chromecast/tools/build/chromecast_repack_locales.py b/chromecast/tools/build/chromecast_repack_locales.py index fec1011..05db65d 100755 --- a/chromecast/tools/build/chromecast_repack_locales.py +++ b/chromecast/tools/build/chromecast_repack_locales.py
@@ -14,8 +14,10 @@ import os import sys -sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', - 'tools', 'grit')) +# Prepend the grit module from the source tree so it takes precedence over other +# grit versions that might present in the search path. +sys.path.insert(1, os.path.join(os.path.dirname(__file__), '..', '..', '..', + 'tools', 'grit')) from grit.format import data_pack # Some build paths defined by gyp.
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 25ef5bf..7e9b339 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -8689.0.0 \ No newline at end of file +8703.0.0 \ No newline at end of file
diff --git a/chromeos/audio/audio_devices_pref_handler_stub.cc b/chromeos/audio/audio_devices_pref_handler_stub.cc index 82a5b4a5..9f71356 100644 --- a/chromeos/audio/audio_devices_pref_handler_stub.cc +++ b/chromeos/audio/audio_devices_pref_handler_stub.cc
@@ -18,8 +18,10 @@ double AudioDevicesPrefHandlerStub::GetOutputVolumeValue( const AudioDevice* device) { if (!device || - !ContainsKey(audio_device_volume_gain_map_, device->stable_device_id)) + !base::ContainsKey(audio_device_volume_gain_map_, + device->stable_device_id)) { return kDefaultOutputVolumePercent; + } return audio_device_volume_gain_map_[device->stable_device_id]; } @@ -27,8 +29,10 @@ const AudioDevice* device) { // TODO(rkc): The default value for gain is wrong. http://crbug.com/442489 if (!device || - !ContainsKey(audio_device_volume_gain_map_, device->stable_device_id)) + !base::ContainsKey(audio_device_volume_gain_map_, + device->stable_device_id)) { return 75.0; + } return audio_device_volume_gain_map_[device->stable_device_id]; }
diff --git a/chromeos/chromeos_switches.cc b/chromeos/chromeos_switches.cc index 507b2c1..bccec7f 100644 --- a/chromeos/chromeos_switches.cc +++ b/chromeos/chromeos_switches.cc
@@ -76,9 +76,6 @@ const char kConservativeThreshold[] = "conservative"; -// Specifies the URL of the consumer device management backend. -const char kConsumerDeviceManagementUrl[] = "consumer-device-management-url"; - // Forces CrOS region value. const char kCrosRegion[] = "cros-region"; @@ -222,10 +219,6 @@ // Enables starting the ARC instance upon session start. const char kEnableArc[] = "enable-arc"; -// Enables consumer management, which allows user to enroll, remotely lock and -// locate the device. -const char kEnableConsumerManagement[] = "enable-consumer-management"; - // Enables Data Saver prompt on cellular networks. const char kEnableDataSaverPrompt[] = "enable-datasaver-prompt";
diff --git a/chromeos/chromeos_switches.h b/chromeos/chromeos_switches.h index fe4377da..c153252 100644 --- a/chromeos/chromeos_switches.h +++ b/chromeos/chromeos_switches.h
@@ -33,7 +33,6 @@ CHROMEOS_EXPORT extern const char kChildWallpaperLarge[]; CHROMEOS_EXPORT extern const char kChildWallpaperSmall[]; CHROMEOS_EXPORT extern const char kConservativeThreshold[]; -CHROMEOS_EXPORT extern const char kConsumerDeviceManagementUrl[]; CHROMEOS_EXPORT extern const char kCrosRegion[]; CHROMEOS_EXPORT extern const char kCrosRegionsMode[]; CHROMEOS_EXPORT extern const char kCrosRegionsModeHide[]; @@ -78,7 +77,6 @@ CHROMEOS_EXPORT extern const char kEafePath[]; CHROMEOS_EXPORT extern const char kEafeUrl[]; CHROMEOS_EXPORT extern const char kEnableArc[]; -CHROMEOS_EXPORT extern const char kEnableConsumerManagement[]; CHROMEOS_EXPORT extern const char kEnableDataSaverPrompt[]; CHROMEOS_EXPORT extern const char kEnableExperimentalAccessibilityFeatures[]; CHROMEOS_EXPORT extern const char kEnableExtensionAssetsSharing[];
diff --git a/chromeos/dbus/fake_shill_device_client.cc b/chromeos/dbus/fake_shill_device_client.cc index b982276..2264069 100644 --- a/chromeos/dbus/fake_shill_device_client.cc +++ b/chromeos/dbus/fake_shill_device_client.cc
@@ -66,8 +66,8 @@ weak_ptr_factory_(this) {} FakeShillDeviceClient::~FakeShillDeviceClient() { - STLDeleteContainerPairSecondPointers( - observer_list_.begin(), observer_list_.end()); + base::STLDeleteContainerPairSecondPointers(observer_list_.begin(), + observer_list_.end()); } // ShillDeviceClient overrides.
diff --git a/chromeos/dbus/fake_shill_profile_client.cc b/chromeos/dbus/fake_shill_profile_client.cc index 66dada6..55579ee 100644 --- a/chromeos/dbus/fake_shill_profile_client.cc +++ b/chromeos/dbus/fake_shill_profile_client.cc
@@ -41,7 +41,7 @@ } FakeShillProfileClient::~FakeShillProfileClient() { - STLDeleteValues(&profiles_); + base::STLDeleteValues(&profiles_); } void FakeShillProfileClient::Init(dbus::Bus* bus) { @@ -240,7 +240,7 @@ } void FakeShillProfileClient::ClearProfiles() { - STLDeleteValues(&profiles_); + base::STLDeleteValues(&profiles_); } FakeShillProfileClient::ProfileProperties* FakeShillProfileClient::GetProfile(
diff --git a/chromeos/dbus/fake_shill_service_client.cc b/chromeos/dbus/fake_shill_service_client.cc index fb68fe4..f41a9f7 100644 --- a/chromeos/dbus/fake_shill_service_client.cc +++ b/chromeos/dbus/fake_shill_service_client.cc
@@ -55,8 +55,8 @@ } FakeShillServiceClient::~FakeShillServiceClient() { - STLDeleteContainerPairSecondPointers( - observer_list_.begin(), observer_list_.end()); + base::STLDeleteContainerPairSecondPointers(observer_list_.begin(), + observer_list_.end()); } @@ -604,7 +604,7 @@ return; } - if (ContainsKey(connect_behavior_, service_path)) { + if (base::ContainsKey(connect_behavior_, service_path)) { const base::Closure& custom_connect_behavior = connect_behavior_[service_path]; VLOG(1) << "Running custom connect behavior for " << service_path;
diff --git a/chromeos/dbus/nfc_client_helpers.cc b/chromeos/dbus/nfc_client_helpers.cc index 1469d26d..2bdad84f 100644 --- a/chromeos/dbus/nfc_client_helpers.cc +++ b/chromeos/dbus/nfc_client_helpers.cc
@@ -92,7 +92,7 @@ // won't access it after the iterator becomes invalidated. const dbus::ObjectPath &object_path = iter->first; ++iter; - if (!ContainsKey(object_path_set, object_path)) + if (!base::ContainsKey(object_path_set, object_path)) RemoveObject(object_path); } } @@ -194,7 +194,7 @@ const std::string& service_name, DBusObjectMap::Delegate* delegate, dbus::Bus* bus) { - if (ContainsKey(paths_to_object_maps_, object_path)) { + if (base::ContainsKey(paths_to_object_maps_, object_path)) { LOG(ERROR) << "Mapping already exists for object path: " << object_path.value(); return false;
diff --git a/chromeos/dbus/system_clock_client.cc b/chromeos/dbus/system_clock_client.cc index 047a29c..600536d 100644 --- a/chromeos/dbus/system_clock_client.cc +++ b/chromeos/dbus/system_clock_client.cc
@@ -23,7 +23,7 @@ SystemClockClientImpl() : can_set_time_(false), can_set_time_initialized_(false), - system_clock_proxy_(NULL), + system_clock_proxy_(nullptr), weak_ptr_factory_(this) {} ~SystemClockClientImpl() override {} @@ -58,11 +58,6 @@ system_clock_proxy_ = bus->GetObjectProxy( system_clock::kSystemClockServiceName, dbus::ObjectPath(system_clock::kSystemClockServicePath)); - - // Check whether the system clock can be set. - GetCanSet(); - - // Monitor the D-Bus signal for TimeUpdated changes. system_clock_proxy_->ConnectToSignal( system_clock::kSystemClockInterface, system_clock::kSystemClockUpdated, @@ -70,9 +65,21 @@ weak_ptr_factory_.GetWeakPtr()), base::Bind(&SystemClockClientImpl::TimeUpdatedConnected, weak_ptr_factory_.GetWeakPtr())); + system_clock_proxy_->WaitForServiceToBeAvailable( + base::Bind(&SystemClockClientImpl::ServiceInitiallyAvailable, + weak_ptr_factory_.GetWeakPtr())); } private: + // Called once when the service initially becomes available (or immediately if + // it's already available). + void ServiceInitiallyAvailable(bool service_is_available) { + if (service_is_available) + GetCanSet(); + else + LOG(ERROR) << "Failed to wait for D-Bus service availability"; + } + // Called when a TimeUpdated signal is received. void TimeUpdatedReceived(dbus::Signal* signal) { VLOG(1) << "TimeUpdated signal received: " << signal->ToString(); @@ -122,8 +129,7 @@ system_clock::kSystemClockCanSet); dbus::MessageWriter writer(&method_call); system_clock_proxy_->CallMethod( - &method_call, - dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, base::Bind(&SystemClockClientImpl::OnGetCanSet, weak_ptr_factory_.GetWeakPtr())); } @@ -140,22 +146,11 @@ DISALLOW_COPY_AND_ASSIGN(SystemClockClientImpl); }; -void SystemClockClient::Observer::SystemClockUpdated() { -} - -void SystemClockClient::Observer::SystemClockCanSetTimeChanged( - bool can_set_time) { -} - -SystemClockClient::SystemClockClient() { -} - -SystemClockClient::~SystemClockClient() { -} - // static SystemClockClient* SystemClockClient::Create() { return new SystemClockClientImpl(); } +SystemClockClient::SystemClockClient() {} + } // namespace chromeos
diff --git a/chromeos/dbus/system_clock_client.h b/chromeos/dbus/system_clock_client.h index 98a4892..fbfe309 100644 --- a/chromeos/dbus/system_clock_client.h +++ b/chromeos/dbus/system_clock_client.h
@@ -21,18 +21,16 @@ class Observer { public: // Called when the status is updated. - virtual void SystemClockUpdated(); + virtual void SystemClockUpdated() {} - // Called when the system clock has become settable or unsettable, e.g., + // Called when the system clock has become settable or unsettable, e.g. // when the clock syncs with or goes out of sync with the network. - virtual void SystemClockCanSetTimeChanged(bool can_set_time); + virtual void SystemClockCanSetTimeChanged(bool can_set_time) {} protected: virtual ~Observer() {} }; - ~SystemClockClient() override; - // Adds the given observer. virtual void AddObserver(Observer* observer) = 0; // Removes the given observer if this object has the observer.
diff --git a/chromeos/dbus/update_engine_client.cc b/chromeos/dbus/update_engine_client.cc index 2abd1b0..b2ae229 100644 --- a/chromeos/dbus/update_engine_client.cc +++ b/chromeos/dbus/update_engine_client.cc
@@ -231,18 +231,20 @@ base::Bind(&UpdateEngineClientImpl::StatusUpdateConnected, weak_ptr_factory_.GetWeakPtr())); update_engine_proxy_->WaitForServiceToBeAvailable( - base::Bind(&UpdateEngineClientImpl::OnProxyAvailabilityChanged, + base::Bind(&UpdateEngineClientImpl::OnServiceInitiallyAvailable, weak_ptr_factory_.GetWeakPtr())); } private: - void OnProxyAvailabilityChanged(bool service_is_available) { + void OnServiceInitiallyAvailable(bool service_is_available) { if (service_is_available) { // Get update engine status for the initial status. Update engine won't // send StatusUpdate signal unless there is a status change. If chrome // crashes after UPDATE_STATUS_UPDATED_NEED_REBOOT status is set, // restarted chrome would not get this status. See crbug.com/154104. GetUpdateEngineStatus(); + } else { + LOG(ERROR) << "Failed to wait for D-Bus service to become available"; } }
diff --git a/chromeos/disks/disk_mount_manager.cc b/chromeos/disks/disk_mount_manager.cc index f75e1ac4..869aa5c7 100644 --- a/chromeos/disks/disk_mount_manager.cc +++ b/chromeos/disks/disk_mount_manager.cc
@@ -51,7 +51,7 @@ } ~DiskMountManagerImpl() override { - STLDeleteContainerPairSecondPointers(disks_.begin(), disks_.end()); + base::STLDeleteContainerPairSecondPointers(disks_.begin(), disks_.end()); } // DiskMountManager override.
diff --git a/chromeos/disks/mock_disk_mount_manager.cc b/chromeos/disks/mock_disk_mount_manager.cc index ba076bb..2cca317 100644 --- a/chromeos/disks/mock_disk_mount_manager.cc +++ b/chromeos/disks/mock_disk_mount_manager.cc
@@ -67,7 +67,7 @@ } MockDiskMountManager::~MockDiskMountManager() { - STLDeleteContainerPairSecondPointers(disks_.begin(), disks_.end()); + base::STLDeleteContainerPairSecondPointers(disks_.begin(), disks_.end()); disks_.clear(); }
diff --git a/chromeos/network/client_cert_resolver.cc b/chromeos/network/client_cert_resolver.cc index 12beecd..d457b5308 100644 --- a/chromeos/network/client_cert_resolver.cc +++ b/chromeos/network/client_cert_resolver.cc
@@ -387,7 +387,7 @@ for (NetworkStateHandler::NetworkStateList::const_iterator it = networks.begin(); it != networks.end(); ++it) { const std::string& service_path = (*it)->path(); - if (ContainsKey(old_resolved_networks, service_path)) { + if (base::ContainsKey(old_resolved_networks, service_path)) { resolved_networks_.insert(service_path); continue; }
diff --git a/chromeos/network/managed_network_configuration_handler_impl.cc b/chromeos/network/managed_network_configuration_handler_impl.cc index 2c89a221..941147f 100644 --- a/chromeos/network/managed_network_configuration_handler_impl.cc +++ b/chromeos/network/managed_network_configuration_handler_impl.cc
@@ -98,7 +98,7 @@ }; ManagedNetworkConfigurationHandlerImpl::Policies::~Policies() { - STLDeleteValues(&per_network_config); + base::STLDeleteValues(&per_network_config); } void ManagedNetworkConfigurationHandlerImpl::AddObserver( @@ -415,7 +415,7 @@ DCHECK(onc_source != ::onc::ONC_SOURCE_DEVICE_POLICY || userhash.empty()); Policies* policies = NULL; - if (ContainsKey(policies_by_user_, userhash)) { + if (base::ContainsKey(policies_by_user_, userhash)) { policies = policies_by_user_[userhash].get(); } else { policies = new Policies; @@ -466,7 +466,7 @@ modified_policies.insert(guid); } - STLDeleteValues(&old_per_network_config); + base::STLDeleteValues(&old_per_network_config); ApplyOrQueuePolicies(userhash, &modified_policies); FOR_EACH_OBSERVER(NetworkPolicyObserver, observers_, PoliciesChanged(userhash)); @@ -491,7 +491,7 @@ return false; } - if (ContainsKey(policy_applicators_, userhash)) { + if (base::ContainsKey(policy_applicators_, userhash)) { // A previous policy application is still running. Queue the modified // policies. // Note, even if |modified_policies| is empty, this means that a policy @@ -602,7 +602,7 @@ FROM_HERE, policy_applicators_[userhash].release()); policy_applicators_.erase(userhash); - if (ContainsKey(queued_modified_policies_, userhash)) { + if (base::ContainsKey(queued_modified_policies_, userhash)) { std::set<std::string> modified_policies; queued_modified_policies_[userhash].swap(modified_policies); // Remove |userhash| from the queue.
diff --git a/chromeos/network/managed_network_configuration_handler_unittest.cc b/chromeos/network/managed_network_configuration_handler_unittest.cc index ca03cac4..7242979 100644 --- a/chromeos/network/managed_network_configuration_handler_unittest.cc +++ b/chromeos/network/managed_network_configuration_handler_unittest.cc
@@ -132,7 +132,7 @@ entry_paths->AppendString(it.key()); } - ASSERT_TRUE(ContainsKey(profile_to_user_, profile_path.value())); + ASSERT_TRUE(base::ContainsKey(profile_to_user_, profile_path.value())); const std::string& userhash = profile_to_user_[profile_path.value()]; result->SetStringWithoutPathExpansion(shill::kUserHashProperty, userhash);
diff --git a/chromeos/network/network_configuration_handler.cc b/chromeos/network/network_configuration_handler.cc index 7cabfdf0..128c5dea 100644 --- a/chromeos/network/network_configuration_handler.cc +++ b/chromeos/network/network_configuration_handler.cc
@@ -335,7 +335,7 @@ const network_handler::ErrorCallback& error_callback) { // Service.Remove is not reliable. Instead, request the profile entries // for the service and remove each entry. - if (ContainsKey(profile_entry_deleters_, service_path)) { + if (base::ContainsKey(profile_entry_deleters_, service_path)) { InvokeErrorCallback(service_path, error_callback, "RemoveConfigurationInProgress"); return; @@ -378,8 +378,8 @@ } NetworkConfigurationHandler::~NetworkConfigurationHandler() { - STLDeleteContainerPairSecondPointers(profile_entry_deleters_.begin(), - profile_entry_deleters_.end()); + base::STLDeleteContainerPairSecondPointers(profile_entry_deleters_.begin(), + profile_entry_deleters_.end()); } void NetworkConfigurationHandler::Init(
diff --git a/chromeos/network/network_configuration_handler_unittest.cc b/chromeos/network/network_configuration_handler_unittest.cc index 4d9d517..2bbe079c 100644 --- a/chromeos/network/network_configuration_handler_unittest.cc +++ b/chromeos/network/network_configuration_handler_unittest.cc
@@ -99,8 +99,8 @@ public: TestNetworkConfigurationObserver() {} ~TestNetworkConfigurationObserver() override { - STLDeleteContainerPairSecondPointers(configurations_.begin(), - configurations_.end()); + base::STLDeleteContainerPairSecondPointers(configurations_.begin(), + configurations_.end()); } // NetworkConfigurationObserver
diff --git a/chromeos/network/network_state_handler.cc b/chromeos/network/network_state_handler.cc index 9585760..4caaa7ce 100644 --- a/chromeos/network/network_state_handler.cc +++ b/chromeos/network/network_state_handler.cc
@@ -75,8 +75,8 @@ // destry the class. if (!did_shutdown_) Shutdown(); - STLDeleteContainerPointers(network_list_.begin(), network_list_.end()); - STLDeleteContainerPointers(device_list_.begin(), device_list_.end()); + base::STLDeleteContainerPointers(network_list_.begin(), network_list_.end()); + base::STLDeleteContainerPointers(device_list_.begin(), device_list_.end()); } void NetworkStateHandler::Shutdown() { @@ -464,7 +464,7 @@ for (ManagedStateList::iterator iter = managed_list->begin(); iter != managed_list->end(); ++iter) { ManagedState* managed = *iter; - DCHECK(!ContainsKey(managed_map, managed->path())); + DCHECK(!base::ContainsKey(managed_map, managed->path())); managed_map[managed->path()] = managed; } // Clear the list (pointers are temporarily owned by managed_map). @@ -494,7 +494,8 @@ list_entries.insert(path); } // Delete any remaining entries in managed_map. - STLDeleteContainerPairSecondPointers(managed_map.begin(), managed_map.end()); + base::STLDeleteContainerPairSecondPointers(managed_map.begin(), + managed_map.end()); } void NetworkStateHandler::ProfileListChanged() {
diff --git a/chromeos/network/policy_applicator.cc b/chromeos/network/policy_applicator.cc index 21b0c32..12f85e25 100644 --- a/chromeos/network/policy_applicator.cc +++ b/chromeos/network/policy_applicator.cc
@@ -60,7 +60,7 @@ } PolicyApplicator::~PolicyApplicator() { - STLDeleteValues(&all_policies_); + base::STLDeleteValues(&all_policies_); VLOG(1) << "Destroying PolicyApplicator for " << profile_.userhash; }
diff --git a/chromeos/network/shill_property_handler.cc b/chromeos/network/shill_property_handler.cc index a1e643f4..7ac56f1 100644 --- a/chromeos/network/shill_property_handler.cc +++ b/chromeos/network/shill_property_handler.cc
@@ -112,10 +112,10 @@ ShillPropertyHandler::~ShillPropertyHandler() { // Delete network service observers. - STLDeleteContainerPairSecondPointers(observed_networks_.begin(), - observed_networks_.end()); - STLDeleteContainerPairSecondPointers(observed_devices_.begin(), - observed_devices_.end()); + base::STLDeleteContainerPairSecondPointers(observed_networks_.begin(), + observed_networks_.end()); + base::STLDeleteContainerPairSecondPointers(observed_devices_.begin(), + observed_devices_.end()); CHECK(shill_manager_ == DBusThreadManager::Get()->GetShillManagerClient()); shill_manager_->RemovePropertyChangedObserver(this); }
diff --git a/chromeos/settings/timezone_settings.cc b/chromeos/settings/timezone_settings.cc index dcc9eda..7dbe669 100644 --- a/chromeos/settings/timezone_settings.cc +++ b/chromeos/settings/timezone_settings.cc
@@ -335,7 +335,7 @@ }; TimezoneSettingsBaseImpl::~TimezoneSettingsBaseImpl() { - STLDeleteElements(&timezones_); + base::STLDeleteElements(&timezones_); } const icu::TimeZone& TimezoneSettingsBaseImpl::GetTimezone() {
diff --git a/chromeos/settings/timezone_settings_unittest.cc b/chromeos/settings/timezone_settings_unittest.cc index 7f7a6426..3c9e129a 100644 --- a/chromeos/settings/timezone_settings_unittest.cc +++ b/chromeos/settings/timezone_settings_unittest.cc
@@ -40,7 +40,7 @@ } } - void TearDown() override { STLDeleteElements(&timezones_); } + void TearDown() override { base::STLDeleteElements(&timezones_); } protected: std::vector<TimeZone*> timezones_;
diff --git a/chromeos/system/name_value_pairs_parser.cc b/chromeos/system/name_value_pairs_parser.cc index 2bf34b6..d037aa8 100644 --- a/chromeos/system/name_value_pairs_parser.cc +++ b/chromeos/system/name_value_pairs_parser.cc
@@ -48,7 +48,7 @@ void NameValuePairsParser::AddNameValuePair(const std::string& key, const std::string& value) { - if (!ContainsKey(*map_, key)) { + if (!base::ContainsKey(*map_, key)) { (*map_)[key] = value; VLOG(1) << "name: " << key << ", value: " << value; } else {
diff --git a/components/BUILD.gn b/components/BUILD.gn index 56a4557..3ceef463 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -129,7 +129,6 @@ "//components/supervised_user_error_page:unit_tests", "//components/sync:unit_tests", "//components/sync_bookmarks:unit_tests", - "//components/sync_driver:unit_tests", "//components/sync_sessions:unit_tests", "//components/syncable_prefs:unit_tests", "//components/translate/core/browser:unit_tests", @@ -198,9 +197,9 @@ "//components/precache/content:unit_tests", "//components/safe_browsing_db:unit_tests", "//components/safe_json:unit_tests", + "//components/spellcheck/renderer:unit_tests", "//components/subresource_filter/content/browser:unit_tests", "//components/subresource_filter/content/renderer:unit_tests", - "//components/test_runner:test_runner", "//components/tracing:unit_tests", "//components/visitedlink/test:unit_tests", "//components/wallpaper:unit_tests",
diff --git a/components/OWNERS b/components/OWNERS index 6c195601..00584eb 100644 --- a/components/OWNERS +++ b/components/OWNERS
@@ -207,10 +207,12 @@ per-file supervised_user_error_page.gypi=file://components/supervised_user_error_page/OWNERS per-file supervised_user_error_page_strings.grdp=file://components/supervised_user_error_page/OWNERS -per-file sync_driver.gypi=file://components/sync_driver/OWNERS +per-file sync.gyp=file://components/sync/OWNERS per-file sync_sessions.gypi=file://components/sync_sessions/OWNERS +per-file sync_ui_strings.grdp=file://components/sync/OWNERS + per-file timers.gypi=file://components/timers/OWNERS per-file tracing.gyp=file://components/tracing/OWNERS
diff --git a/components/arc/arc_service_manager.cc b/components/arc/arc_service_manager.cc index 21b8f37..a206fd4c 100644 --- a/components/arc/arc_service_manager.cc +++ b/components/arc/arc_service_manager.cc
@@ -99,10 +99,6 @@ const AccountId& account_id, std::unique_ptr<BooleanPrefMember> arc_enabled_pref) { DCHECK(thread_checker_.CalledOnValidThread()); - - arc_user_data_service_.reset(new ArcUserDataService(arc_bridge_service(), - std::move(arc_enabled_pref), account_id)); - AddService(base::WrapUnique( new ArcNotificationManager(arc_bridge_service(), account_id))); } @@ -110,7 +106,6 @@ void ArcServiceManager::Shutdown() { icon_loader_ = nullptr; activity_resolver_ = nullptr; - arc_user_data_service_ = nullptr; services_.clear(); }
diff --git a/components/arc/arc_service_manager.h b/components/arc/arc_service_manager.h index a2150f4c..256a1992 100644 --- a/components/arc/arc_service_manager.h +++ b/components/arc/arc_service_manager.h
@@ -21,7 +21,6 @@ class ArcBridgeService; class ArcService; -class ArcUserDataService; // Manages creation and destruction of services that communicate with the ARC // instance via the ArcBridgeService. @@ -67,10 +66,6 @@ return activity_resolver_; } - ArcUserDataService* arc_user_data_service() { - return arc_user_data_service_.get(); - } - private: base::ThreadChecker thread_checker_; scoped_refptr<base::TaskRunner> blocking_task_runner_; @@ -79,7 +74,6 @@ std::vector<std::unique_ptr<ArcService>> services_; scoped_refptr<ActivityIconLoader> icon_loader_; scoped_refptr<LocalActivityResolver> activity_resolver_; - std::unique_ptr<ArcUserDataService> arc_user_data_service_; DISALLOW_COPY_AND_ASSIGN(ArcServiceManager); };
diff --git a/components/arc/metrics/arc_metrics_service.cc b/components/arc/metrics/arc_metrics_service.cc index 38e59d78..826f0647 100644 --- a/components/arc/metrics/arc_metrics_service.cc +++ b/components/arc/metrics/arc_metrics_service.cc
@@ -28,10 +28,10 @@ : ArcService(bridge_service), binding_(this), process_observer_(this), + oom_kills_monitor_handle_(OomKillsMonitor::StartMonitoring()), weak_ptr_factory_(this) { arc_bridge_service()->metrics()->AddObserver(this); arc_bridge_service()->process()->AddObserver(&process_observer_); - oom_kills_monitor_.Start(); } ArcMetricsService::~ArcMetricsService() {
diff --git a/components/arc/metrics/arc_metrics_service.h b/components/arc/metrics/arc_metrics_service.h index 7b7958b..06fdf7b 100644 --- a/components/arc/metrics/arc_metrics_service.h +++ b/components/arc/metrics/arc_metrics_service.h
@@ -70,7 +70,7 @@ base::ThreadChecker thread_checker_; base::RepeatingTimer timer_; - OomKillsMonitor oom_kills_monitor_; + OomKillsMonitor::Handle oom_kills_monitor_handle_; base::TimeTicks arc_start_time_;
diff --git a/components/arc/metrics/oom_kills_monitor.cc b/components/arc/metrics/oom_kills_monitor.cc index 3dc4de62..719b778 100644 --- a/components/arc/metrics/oom_kills_monitor.cc +++ b/components/arc/metrics/oom_kills_monitor.cc
@@ -11,10 +11,12 @@ #include <vector> #include "base/bind.h" +#include "base/debug/leak_annotations.h" #include "base/files/file_util.h" #include "base/files/scoped_file.h" #include "base/location.h" #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" #include "base/posix/safe_strerror.h" #include "base/sequenced_task_runner.h" @@ -33,25 +35,6 @@ using base::SequencedWorkerPool; using base::TimeDelta; -OomKillsMonitor::OomKillsMonitor() - : worker_pool_( - new SequencedWorkerPool(1, "oom_kills_monitor")) {} - -OomKillsMonitor::~OomKillsMonitor() { - Stop(); -} - -void OomKillsMonitor::Start() { - auto task_runner = worker_pool_->GetTaskRunnerWithShutdownBehavior( - SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); - task_runner->PostTask( - FROM_HERE, base::Bind(&OomKillsMonitor::Run, worker_pool_)); -} - -void OomKillsMonitor::Stop() { - worker_pool_->Shutdown(); -} - namespace { int64_t GetTimestamp(const StringPiece& line) { @@ -154,9 +137,48 @@ } // namespace +OomKillsMonitor::Handle::Handle(OomKillsMonitor* outer) : outer_(outer) { + DCHECK(outer_); +} + +OomKillsMonitor::Handle::~Handle() { + outer_->is_shutting_down_.Set(); +} + +OomKillsMonitor::OomKillsMonitor() { + base::SimpleThread::Options non_joinable_options; + non_joinable_options.joinable = false; + non_joinable_worker_thread_ = base::MakeUnique<base::DelegateSimpleThread>( + this, "oom_kills_monitor", non_joinable_options); + non_joinable_worker_thread_->Start(); +} + +OomKillsMonitor::~OomKillsMonitor() { + // The instance has to be leaked on shutdown as it is referred to by a + // non-joinable thread but ~OomKillsMonitor() can't be explicitly deleted as + // it overrides ~SimpleThread(), it should nevertheless never be invoked. + NOTREACHED(); +} + // static -void OomKillsMonitor::Run( - scoped_refptr<base::SequencedWorkerPool> worker_pool) { +OomKillsMonitor::Handle OomKillsMonitor::StartMonitoring() { +#if DCHECK_IS_ON() + static volatile bool monitoring_active = false; + DCHECK(!monitoring_active); + monitoring_active = true; +#endif + + // Instantiate the OomKillsMonitor and its underlying thread. The + // OomKillsMonitor itself has to be leaked on shutdown per having a + // non-joinable thread associated to its state. The OomKillsMonitor::Handle + // will notify the OomKillsMonitor when it is destroyed so that the underlying + // thread can at a minimum not do extra work during shutdown. + OomKillsMonitor* instance = new OomKillsMonitor; + ANNOTATE_LEAKING_OBJECT_PTR(instance); + return Handle(instance); +} + +void OomKillsMonitor::Run() { base::ScopedFILE kmsg_handle( base::OpenFile(base::FilePath("/dev/kmsg"), "r")); if (!kmsg_handle) { @@ -171,7 +193,7 @@ char buf[kMaxBufSize]; while (fgets(buf, kMaxBufSize, kmsg_handle.get())) { - if (worker_pool->IsShutdownInProgress()) { + if (is_shutting_down_.IsSet()) { DVLOG(1) << "Chrome is shutting down, exit now."; break; }
diff --git a/components/arc/metrics/oom_kills_monitor.h b/components/arc/metrics/oom_kills_monitor.h index c6cf7995..f4e188445 100644 --- a/components/arc/metrics/oom_kills_monitor.h +++ b/components/arc/metrics/oom_kills_monitor.h
@@ -5,33 +5,58 @@ #ifndef COMPONENTS_ARC_METRICS_OOM_KILLS_MONITOR_H_ #define COMPONENTS_ARC_METRICS_OOM_KILLS_MONITOR_H_ +#include <memory> + #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/threading/sequenced_worker_pool.h" +#include "base/synchronization/atomic_flag.h" +#include "base/threading/simple_thread.h" namespace arc { // Traces kernel OOM kill events and lowmemorykiller (if enabled) events. // // OomKillsMonitor listens to kernel messages for both OOM kills and -// lowmemorykiller kills, then reports to UMA. +// lowmemorykiller kills, then reports to UMA. It uses a non-joinable thread +// in order to avoid blocking shutdown. // // Note: There should be only one OomKillsMonitor instance globally at any given // time, otherwise UMA would receive duplicate events. -class OomKillsMonitor { +class OomKillsMonitor : public base::DelegateSimpleThread::Delegate { public: - OomKillsMonitor(); - ~OomKillsMonitor(); + // A handle representing the OomKillsMonitor's lifetime (the monitor itself + // can't be destroyed per being a non-joinable Thread). + class Handle { + public: + // Constructs a handle that will flag |outer| as shutting down on + // destruction. + explicit Handle(OomKillsMonitor* outer); - void Start(); - void Stop(); + ~Handle(); + + private: + OomKillsMonitor* const outer_; + }; + + // Instantiates the OomKillsMonitor instance and starts it. This must only + // be invoked once per process. + static Handle StartMonitoring(); private: - // Keeps a reference to worker_pool_ in case |this| is deleted in - // shutdown process while this thread returns from a blocking read. - static void Run(scoped_refptr<base::SequencedWorkerPool> worker_pool); + OomKillsMonitor(); + ~OomKillsMonitor() override; - scoped_refptr<base::SequencedWorkerPool> worker_pool_; + // Overridden from base::DelegateSimpleThread::Delegate: + void Run() override; + + // A flag set when OomKillsMonitor is shutdown so that its thread can poll + // it and attempt to wind down from that point (to avoid unecessary work, not + // because it blocks shutdown). + base::AtomicFlag is_shutting_down_; + + // The underlying worker thread which is non-joinable to avoid blocking + // shutdown. + std::unique_ptr<base::DelegateSimpleThread> non_joinable_worker_thread_; DISALLOW_COPY_AND_ASSIGN(OomKillsMonitor); };
diff --git a/components/autofill.gypi b/components/autofill.gypi index 860ae23..624777fe 100644 --- a/components/autofill.gypi +++ b/components/autofill.gypi
@@ -95,7 +95,6 @@ 'rappor', 'signin_core_browser', 'signin_core_common', - 'sync_driver', 'variations_net', 'webdata_common', ],
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc index 0a17887..42d5bbe 100644 --- a/components/autofill/content/renderer/autofill_agent.cc +++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -331,7 +331,6 @@ } void AutofillAgent::textFieldDidEndEditing(const WebInputElement& element) { - password_autofill_agent_->TextFieldDidEndEditing(element); GetAutofillDriver()->DidEndTextFieldEditing(); }
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc index 35b23c2..3de92a1d 100644 --- a/components/autofill/content/renderer/form_autofill_util.cc +++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -229,7 +229,7 @@ return base::string16(); } - if (element.hasHTMLTagName("div") && ContainsKey(divs_to_skip, node)) + if (element.hasHTMLTagName("div") && base::ContainsKey(divs_to_skip, node)) return base::string16(); } @@ -675,9 +675,11 @@ bool IsLabelValid(base::StringPiece16 inferred_label, const std::vector<base::char16>& stop_words) { // If |inferred_label| has any character other than those in |stop_words|. - auto* first_non_stop_word = std::find_if( - inferred_label.begin(), inferred_label.end(), - [&stop_words](base::char16 c) { return !ContainsValue(stop_words, c); }); + auto* first_non_stop_word = + std::find_if(inferred_label.begin(), inferred_label.end(), + [&stop_words](base::char16 c) { + return !base::ContainsValue(stop_words, c); + }); return first_non_stop_word != inferred_label.end(); } @@ -707,7 +709,7 @@ std::vector<std::string> tag_names = AncestorTagNames(element); std::set<std::string> seen_tag_names; for (const std::string& tag_name : tag_names) { - if (ContainsKey(seen_tag_names, tag_name)) + if (base::ContainsKey(seen_tag_names, tag_name)) continue; seen_tag_names.insert(tag_name);
diff --git a/components/autofill/content/renderer/form_cache.cc b/components/autofill/content/renderer/form_cache.cc index 2877999..0ff0722 100644 --- a/components/autofill/content/renderer/form_cache.cc +++ b/components/autofill/content/renderer/form_cache.cc
@@ -131,7 +131,7 @@ if (num_fields_seen > form_util::kMaxParseableFields) return forms; - if (!ContainsKey(parsed_forms_, form) && + if (!base::ContainsKey(parsed_forms_, form) && IsFormInteresting(form, num_editable_elements)) { for (auto it = parsed_forms_.begin(); it != parsed_forms_.end(); ++it) { if (it->SameFormAs(form)) {
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc index b20b3f4..282f10a 100644 --- a/components/autofill/content/renderer/password_autofill_agent.cc +++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -624,40 +624,6 @@ element->setValue(element->suggestedValue(), true); } -bool PasswordAutofillAgent::TextFieldDidEndEditing( - const blink::WebInputElement& element) { - WebInputToPasswordInfoMap::const_iterator iter = - web_input_to_password_info_.find(element); - if (iter == web_input_to_password_info_.end()) - return false; - - const PasswordInfo& password_info = iter->second; - // Don't let autofill overwrite an explicit change made by the user. - if (password_info.password_was_edited_last) - return false; - - const PasswordFormFillData& fill_data = password_info.fill_data; - - // If wait_for_username is false, we should have filled when the text changed. - if (!fill_data.wait_for_username) - return false; - - blink::WebInputElement password = password_info.password_field; - if (!IsElementEditable(password)) - return false; - - blink::WebInputElement username = element; // We need a non-const. - - // Do not set selection when ending an editing session, otherwise it can - // mess with focus. - FillUserNameAndPassword(&username, &password, fill_data, true, false, - &field_value_and_properties_map_, - base::Bind(&PasswordValueGatekeeper::RegisterElement, - base::Unretained(&gatekeeper_)), - nullptr); - return true; -} - bool PasswordAutofillAgent::TextDidChangeInTextField( const blink::WebInputElement& element) { // TODO(vabr): Get a mutable argument instead. http://crbug.com/397083 @@ -668,9 +634,6 @@ web_input_to_password_info_.find(element); if (iter != web_input_to_password_info_.end()) { iter->second.password_was_edited_last = false; - // If wait_for_username is true we will fill when the username loses focus. - if (iter->second.fill_data.wait_for_username) - return false; } // Show the popup with the list of available usernames.
diff --git a/components/autofill/content/renderer/password_autofill_agent.h b/components/autofill/content/renderer/password_autofill_agent.h index 90b48fd..b623e6fe 100644 --- a/components/autofill/content/renderer/password_autofill_agent.h +++ b/components/autofill/content/renderer/password_autofill_agent.h
@@ -42,7 +42,6 @@ // WebFrameClient editor related calls forwarded by AutofillAgent. // If they return true, it indicates the event was consumed and should not // be used for any other autofill activity. - bool TextFieldDidEndEditing(const blink::WebInputElement& element); bool TextDidChangeInTextField(const blink::WebInputElement& element); // Function that should be called whenever the value of |element| changes due
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index 994095b..a389809 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -182,7 +182,6 @@ "//components/signin/core/common", "//components/strings", "//components/sync", - "//components/sync_driver", "//components/variations/net", "//components/version_info", "//components/webdata/common", @@ -347,8 +346,7 @@ "//components/strings", "//components/sync", "//components/sync:test_support_sync_api", - "//components/sync_driver", - "//components/sync_driver:test_support", + "//components/sync:test_support_sync_driver", "//components/variations", "//components/webdata/common", "//components/webdata_services:test_support",
diff --git a/components/autofill/core/browser/DEPS b/components/autofill/core/browser/DEPS index cca7e4bf..42f1d17 100644 --- a/components/autofill/core/browser/DEPS +++ b/components/autofill/core/browser/DEPS
@@ -5,7 +5,6 @@ "+components/signin/core/browser", "+components/signin/core/common", "+components/sync", - "+components/sync_driver", "+components/variations", "+components/version_info", "+components/webdata/common",
diff --git a/components/autofill/core/browser/autofill_country.cc b/components/autofill/core/browser/autofill_country.cc index f89e4c1..412783b 100644 --- a/components/autofill/core/browser/autofill_country.cc +++ b/components/autofill/core/browser/autofill_country.cc
@@ -56,8 +56,8 @@ std::string country_code = icu::Locale(likely_locale.c_str()).getCountry(); // Default to the United States if we have no better guess. - if (!ContainsValue(CountryDataMap::GetInstance()->country_codes(), - country_code)) { + if (!base::ContainsValue(CountryDataMap::GetInstance()->country_codes(), + country_code)) { return "US"; }
diff --git a/components/autofill/core/browser/autofill_download_manager.cc b/components/autofill/core/browser/autofill_download_manager.cc index ced1711..53ac081 100644 --- a/components/autofill/core/browser/autofill_download_manager.cc +++ b/components/autofill/core/browser/autofill_download_manager.cc
@@ -155,8 +155,8 @@ } AutofillDownloadManager::~AutofillDownloadManager() { - STLDeleteContainerPairFirstPointers(url_fetchers_.begin(), - url_fetchers_.end()); + base::STLDeleteContainerPairFirstPointers(url_fetchers_.begin(), + url_fetchers_.end()); } bool AutofillDownloadManager::StartQueryRequest(
diff --git a/components/autofill/core/browser/autofill_experiments.cc b/components/autofill/core/browser/autofill_experiments.cc index 102af86..3977350 100644 --- a/components/autofill/core/browser/autofill_experiments.cc +++ b/components/autofill/core/browser/autofill_experiments.cc
@@ -13,7 +13,7 @@ #include "components/autofill/core/common/autofill_pref_names.h" #include "components/autofill/core/common/autofill_switches.h" #include "components/prefs/pref_service.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_service.h" #include "components/variations/variations_associated_data.h" #include "google_apis/gaia/gaia_auth_util.h"
diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc index cf22acfc..fc526b65 100644 --- a/components/autofill/core/browser/autofill_external_delegate.cc +++ b/components/autofill/core/browser/autofill_external_delegate.cc
@@ -343,12 +343,12 @@ std::set<base::string16> data_list_set(data_list_values_.begin(), data_list_values_.end()); suggestions->erase( - std::remove_if(suggestions->begin(), suggestions->end(), - [&data_list_set](const Suggestion& suggestion) { - return suggestion.frontend_id == - POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY && - ContainsKey(data_list_set, suggestion.value); - }), + std::remove_if( + suggestions->begin(), suggestions->end(), + [&data_list_set](const Suggestion& suggestion) { + return suggestion.frontend_id == POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY && + base::ContainsKey(data_list_set, suggestion.value); + }), suggestions->end()); #if !defined(OS_ANDROID)
diff --git a/components/autofill/core/browser/autofill_wallet_data_type_controller.cc b/components/autofill/core/browser/autofill_wallet_data_type_controller.cc index 08e7ece17..df6fc33 100644 --- a/components/autofill/core/browser/autofill_wallet_data_type_controller.cc +++ b/components/autofill/core/browser/autofill_wallet_data_type_controller.cc
@@ -11,8 +11,8 @@ #include "components/prefs/pref_service.h" #include "components/sync/api/sync_error.h" #include "components/sync/api/syncable_service.h" -#include "components/sync_driver/sync_client.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_client.h" +#include "components/sync/driver/sync_service.h" namespace browser_sync {
diff --git a/components/autofill/core/browser/autofill_wallet_data_type_controller.h b/components/autofill/core/browser/autofill_wallet_data_type_controller.h index 84ed7b6b..c31af633 100644 --- a/components/autofill/core/browser/autofill_wallet_data_type_controller.h +++ b/components/autofill/core/browser/autofill_wallet_data_type_controller.h
@@ -7,7 +7,7 @@ #include "base/macros.h" #include "components/prefs/pref_change_registrar.h" -#include "components/sync_driver/non_ui_data_type_controller.h" +#include "components/sync/driver/non_ui_data_type_controller.h" namespace autofill { class AutofillWebDataService;
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc index 5e6092c..05add517 100644 --- a/components/autofill/core/browser/personal_data_manager.cc +++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -5,6 +5,7 @@ #include "components/autofill/core/browser/personal_data_manager.h" #include <stddef.h> + #include <algorithm> #include <list> #include <map> @@ -39,7 +40,7 @@ #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/common/signin_pref_names.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_service.h" #include "components/variations/variations_associated_data.h" #include "components/version_info/version_info.h" #include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
diff --git a/components/autofill/core/browser/phone_field_unittest.cc b/components/autofill/core/browser/phone_field_unittest.cc index b32bbdc..14c0b2c 100644 --- a/components/autofill/core/browser/phone_field_unittest.cc +++ b/components/autofill/core/browser/phone_field_unittest.cc
@@ -158,7 +158,7 @@ CheckField("areacode1", PHONE_HOME_CITY_CODE); CheckField("prefix2", PHONE_HOME_NUMBER); CheckField("suffix3", PHONE_HOME_NUMBER); - EXPECT_TRUE(ContainsKey(field_candidates_map_, ASCIIToUTF16("ext4"))); + EXPECT_TRUE(base::ContainsKey(field_candidates_map_, ASCIIToUTF16("ext4"))); } }
diff --git a/components/autofill/core/browser/webdata/autofill_data_type_controller.h b/components/autofill/core/browser/webdata/autofill_data_type_controller.h index ed7a8330..6bcf0ee 100644 --- a/components/autofill/core/browser/webdata/autofill_data_type_controller.h +++ b/components/autofill/core/browser/webdata/autofill_data_type_controller.h
@@ -11,7 +11,7 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "components/sync_driver/non_ui_data_type_controller.h" +#include "components/sync/driver/non_ui_data_type_controller.h" namespace autofill { class AutofillWebDataService;
diff --git a/components/autofill/core/browser/webdata/autofill_data_type_controller_unittest.cc b/components/autofill/core/browser/webdata/autofill_data_type_controller_unittest.cc index 6d5a7bd8..6d26a2e 100644 --- a/components/autofill/core/browser/webdata/autofill_data_type_controller_unittest.cc +++ b/components/autofill/core/browser/webdata/autofill_data_type_controller_unittest.cc
@@ -17,8 +17,8 @@ #include "components/autofill/core/browser/webdata/autocomplete_syncable_service.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/sync/api/sync_error.h" -#include "components/sync_driver/data_type_controller_mock.h" -#include "components/sync_driver/fake_sync_client.h" +#include "components/sync/driver/data_type_controller_mock.h" +#include "components/sync/driver/fake_sync_client.h" #include "components/webdata_services/web_data_service_test_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc b/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc index e9f5be1..d37048b 100644 --- a/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc +++ b/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc
@@ -10,7 +10,7 @@ #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/sync/api/sync_error.h" #include "components/sync/api/syncable_service.h" -#include "components/sync_driver/sync_client.h" +#include "components/sync/driver/sync_client.h" using autofill::AutofillWebDataService;
diff --git a/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h b/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h index 5e13080..2186bb2 100644 --- a/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h +++ b/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h
@@ -10,7 +10,7 @@ #include "base/memory/ref_counted.h" #include "base/scoped_observer.h" #include "components/autofill/core/browser/personal_data_manager_observer.h" -#include "components/sync_driver/non_ui_data_type_controller.h" +#include "components/sync/driver/non_ui_data_type_controller.h" namespace autofill { class AutofillWebDataService;
diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc index 98ebfafc..20bdea8 100644 --- a/components/autofill/core/browser/webdata/autofill_table.cc +++ b/components/autofill/core/browser/webdata/autofill_table.cc
@@ -702,7 +702,7 @@ for (const FormFieldData& element : elements) { if (seen_names.size() >= kMaximumUniqueNames) break; - if (ContainsKey(seen_names, element.name)) + if (base::ContainsKey(seen_names, element.name)) continue; result = result && AddFormFieldValueTime(element, changes, time); seen_names.insert(element.name);
diff --git a/components/autofill/core/browser/webdata/autofill_table_unittest.cc b/components/autofill/core/browser/webdata/autofill_table_unittest.cc index df40d8b..53ef3bff 100644 --- a/components/autofill/core/browser/webdata/autofill_table_unittest.cc +++ b/components/autofill/core/browser/webdata/autofill_table_unittest.cc
@@ -1608,7 +1608,7 @@ EXPECT_EQ(CreditCard::OK, outputs[0]->GetServerStatus()); EXPECT_EQ(CreditCard::EXPIRED, outputs[1]->GetServerStatus()); - STLDeleteContainerPointers(outputs.begin(), outputs.end()); + base::STLDeleteContainerPointers(outputs.begin(), outputs.end()); } TEST_F(AutofillTableTest, MaskUnmaskServerCards) { @@ -1633,7 +1633,7 @@ EXPECT_TRUE(CreditCard::FULL_SERVER_CARD == outputs[0]->record_type()); EXPECT_EQ(full_number, outputs[0]->GetRawInfo(CREDIT_CARD_NUMBER)); - STLDeleteContainerPointers(outputs.begin(), outputs.end()); + base::STLDeleteContainerPointers(outputs.begin(), outputs.end()); outputs.clear(); // Re-mask the number, we should only get the last 4 digits out. @@ -1643,7 +1643,7 @@ EXPECT_TRUE(CreditCard::MASKED_SERVER_CARD == outputs[0]->record_type()); EXPECT_EQ(masked_number, outputs[0]->GetRawInfo(CREDIT_CARD_NUMBER)); - STLDeleteContainerPointers(outputs.begin(), outputs.end()); + base::STLDeleteContainerPointers(outputs.begin(), outputs.end()); outputs.clear(); } @@ -1674,7 +1674,7 @@ EXPECT_TRUE(outputs[0]->record_type() == CreditCard::FULL_SERVER_CARD); EXPECT_EQ(full_number, outputs[0]->GetRawInfo(CREDIT_CARD_NUMBER)); - STLDeleteContainerPointers(outputs.begin(), outputs.end()); + base::STLDeleteContainerPointers(outputs.begin(), outputs.end()); outputs.clear(); // Call set again with the masked number. @@ -1687,7 +1687,7 @@ EXPECT_TRUE(outputs[0]->record_type() == CreditCard::FULL_SERVER_CARD); EXPECT_EQ(full_number, outputs[0]->GetRawInfo(CREDIT_CARD_NUMBER)); - STLDeleteContainerPointers(outputs.begin(), outputs.end()); + base::STLDeleteContainerPointers(outputs.begin(), outputs.end()); outputs.clear(); // Set inputs that do not include our old card. @@ -1707,7 +1707,7 @@ EXPECT_EQ(random_card.server_id(), outputs[0]->server_id()); EXPECT_EQ(ASCIIToUTF16("2222"), outputs[0]->GetRawInfo(CREDIT_CARD_NUMBER)); - STLDeleteContainerPointers(outputs.begin(), outputs.end()); + base::STLDeleteContainerPointers(outputs.begin(), outputs.end()); outputs.clear(); // Putting back the original card masked should make it masked (this tests @@ -1720,7 +1720,7 @@ EXPECT_EQ(masked_card.server_id(), outputs[0]->server_id()); EXPECT_EQ(ASCIIToUTF16("1111"), outputs[0]->GetRawInfo(CREDIT_CARD_NUMBER)); - STLDeleteContainerPointers(outputs.begin(), outputs.end()); + base::STLDeleteContainerPointers(outputs.begin(), outputs.end()); outputs.clear(); } @@ -1826,7 +1826,7 @@ ASSERT_EQ(1u, outputs.size()); EXPECT_EQ(one.server_id(), outputs[0]->server_id()); - STLDeleteContainerPointers(outputs.begin(), outputs.end()); + base::STLDeleteContainerPointers(outputs.begin(), outputs.end()); outputs.clear(); // Set a different profile. @@ -1839,7 +1839,7 @@ ASSERT_EQ(1u, outputs.size()); EXPECT_EQ(two.server_id(), outputs[0]->server_id()); - STLDeleteContainerPointers(outputs.begin(), outputs.end()); + base::STLDeleteContainerPointers(outputs.begin(), outputs.end()); outputs.clear(); }
diff --git a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc index 1bc55bb..d4117a0a 100644 --- a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc +++ b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc
@@ -525,7 +525,7 @@ const WDResult<std::vector<AutofillProfile*> >* r = static_cast<const WDResult<std::vector<AutofillProfile*> >*>(result); std::vector<AutofillProfile*> profiles = r->GetValue(); - STLDeleteElements(&profiles); + base::STLDeleteElements(&profiles); } void AutofillWebDataBackendImpl::DestroyAutofillCreditCardResult( @@ -535,7 +535,7 @@ static_cast<const WDResult<std::vector<CreditCard*> >*>(result); std::vector<CreditCard*> credit_cards = r->GetValue(); - STLDeleteElements(&credit_cards); + base::STLDeleteElements(&credit_cards); } } // namespace autofill
diff --git a/components/autofill/core/browser/webdata/web_data_service_unittest.cc b/components/autofill/core/browser/webdata/web_data_service_unittest.cc index ff25550..431c057 100644 --- a/components/autofill/core/browser/webdata/web_data_service_unittest.cc +++ b/components/autofill/core/browser/webdata/web_data_service_unittest.cc
@@ -308,7 +308,7 @@ EXPECT_EQ(handle, consumer.handle()); ASSERT_EQ(1U, consumer.result().size()); EXPECT_EQ(profile, *consumer.result()[0]); - STLDeleteElements(&consumer.result()); + base::STLDeleteElements(&consumer.result()); } TEST_F(WebDataServiceAutofillTest, ProfileRemove) { @@ -327,7 +327,7 @@ EXPECT_EQ(handle, consumer.handle()); ASSERT_EQ(1U, consumer.result().size()); EXPECT_EQ(profile, *consumer.result()[0]); - STLDeleteElements(&consumer.result()); + base::STLDeleteElements(&consumer.result()); // Check that GUID-based notification was sent. const AutofillProfileChange expected_change( @@ -372,7 +372,7 @@ ASSERT_EQ(2U, consumer.result().size()); EXPECT_EQ(profile2, *consumer.result()[0]); EXPECT_EQ(profile1, *consumer.result()[1]); - STLDeleteElements(&consumer.result()); + base::STLDeleteElements(&consumer.result()); AutofillProfile profile2_changed(profile2); profile2_changed.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Bill")); @@ -395,7 +395,7 @@ EXPECT_EQ(profile2_changed, *consumer2.result()[0]); EXPECT_NE(profile2, *consumer2.result()[0]); EXPECT_EQ(profile1, *consumer2.result()[1]); - STLDeleteElements(&consumer2.result()); + base::STLDeleteElements(&consumer2.result()); } TEST_F(WebDataServiceAutofillTest, CreditAdd) { @@ -410,7 +410,7 @@ EXPECT_EQ(handle, consumer.handle()); ASSERT_EQ(1U, consumer.result().size()); EXPECT_EQ(card, *consumer.result()[0]); - STLDeleteElements(&consumer.result()); + base::STLDeleteElements(&consumer.result()); } TEST_F(WebDataServiceAutofillTest, CreditCardRemove) { @@ -427,7 +427,7 @@ EXPECT_EQ(handle, consumer.handle()); ASSERT_EQ(1U, consumer.result().size()); EXPECT_EQ(credit_card, *consumer.result()[0]); - STLDeleteElements(&consumer.result()); + base::STLDeleteElements(&consumer.result()); // Remove the credit card. wds_->RemoveCreditCard(credit_card.guid()); @@ -461,7 +461,7 @@ ASSERT_EQ(2U, consumer.result().size()); EXPECT_EQ(card2, *consumer.result()[0]); EXPECT_EQ(card1, *consumer.result()[1]); - STLDeleteElements(&consumer.result()); + base::STLDeleteElements(&consumer.result()); CreditCard card2_changed(card2); card2_changed.SetRawInfo(CREDIT_CARD_NAME_FULL, ASCIIToUTF16("Bill")); @@ -478,7 +478,7 @@ EXPECT_NE(card2, *consumer2.result()[0]); EXPECT_EQ(card2_changed, *consumer2.result()[0]); EXPECT_EQ(card1, *consumer2.result()[1]); - STLDeleteElements(&consumer2.result()); + base::STLDeleteElements(&consumer2.result()); } TEST_F(WebDataServiceAutofillTest, AutofillRemoveModifiedBetween) { @@ -498,7 +498,7 @@ EXPECT_EQ(handle, profile_consumer.handle()); ASSERT_EQ(1U, profile_consumer.result().size()); EXPECT_EQ(profile, *profile_consumer.result()[0]); - STLDeleteElements(&profile_consumer.result()); + base::STLDeleteElements(&profile_consumer.result()); // Add a credit card. CreditCard credit_card; @@ -512,7 +512,7 @@ EXPECT_EQ(handle, card_consumer.handle()); ASSERT_EQ(1U, card_consumer.result().size()); EXPECT_EQ(credit_card, *card_consumer.result()[0]); - STLDeleteElements(&card_consumer.result()); + base::STLDeleteElements(&card_consumer.result()); // Check that GUID-based notification was sent for the profile. const AutofillProfileChange expected_profile_change(
diff --git a/components/autofill/ios/browser/js_autofill_manager.mm b/components/autofill/ios/browser/js_autofill_manager.mm index b56be25..e6c8ba79 100644 --- a/components/autofill/ios/browser/js_autofill_manager.mm +++ b/components/autofill/ios/browser/js_autofill_manager.mm
@@ -74,10 +74,10 @@ } - (void)fillPredictionData:(NSString*)dataString { - [self deferredEvaluate: - [NSString - stringWithFormat:@"__gCrWeb.autofill.fillPredictionData(%@);", - dataString]]; + NSString* script = + [NSString stringWithFormat:@"__gCrWeb.autofill.fillPredictionData(%@);", + dataString]; + [self executeJavaScript:script completionHandler:nil]; } @end
diff --git a/components/autofill/ios/browser/js_suggestion_manager.mm b/components/autofill/ios/browser/js_suggestion_manager.mm index 368ad29..fb29f04 100644 --- a/components/autofill/ios/browser/js_suggestion_manager.mm +++ b/components/autofill/ios/browser/js_suggestion_manager.mm
@@ -98,9 +98,8 @@ } - (void)closeKeyboard { - // Deferred execution used because of a risk of crwebinvoke:// triggered - // immediately by the loss of focus. - [self deferredEvaluate:@"document.activeElement.blur()"]; + [self executeJavaScript:@"document.activeElement.blur()" + completionHandler:nil]; } @end
diff --git a/components/browser_sync.gypi b/components/browser_sync.gypi index 9ab4286..98e76ee 100644 --- a/components/browser_sync.gypi +++ b/components/browser_sync.gypi
@@ -30,7 +30,6 @@ 'signin_core_browser', 'syncable_prefs', 'sync_bookmarks', - 'sync_driver', 'sync_sessions', 'variations', 'version_info', @@ -38,9 +37,6 @@ 'include_dirs': [ '..', ], - 'export_dependent_settings': [ - 'sync_driver', - ], 'sources': [ # Note: file list duplicated in GN build. 'browser_sync/browser/profile_sync_components_factory_impl.cc', @@ -76,6 +72,7 @@ '../base/base.gyp:test_support_base', '../google_apis/google_apis.gyp:google_apis', '../components/sync.gyp:sync', + '../components/sync.gyp:test_support_sync_driver', '../testing/gmock.gyp:gmock', 'bookmarks_browser', 'browser_sync_browser', @@ -85,8 +82,6 @@ 'pref_registry', 'signin_core_browser', 'signin_core_browser_test_support', - 'sync_driver', - 'sync_driver_test_support', 'sync_sessions_test_support', 'syncable_prefs_test_support', ],
diff --git a/components/browser_sync/browser/BUILD.gn b/components/browser_sync/browser/BUILD.gn index 556f9fd..1e31678 100644 --- a/components/browser_sync/browser/BUILD.gn +++ b/components/browser_sync/browser/BUILD.gn
@@ -15,7 +15,7 @@ ] public_deps = [ - "//components/sync_driver", + "//components/sync", ] deps = [ @@ -34,7 +34,6 @@ "//components/prefs", "//components/signin/core/browser", "//components/strings", - "//components/sync", "//components/sync_bookmarks", "//components/sync_sessions", "//components/syncable_prefs", @@ -78,10 +77,10 @@ "//components/signin/core/browser:test_support", "//components/signin/core/common:common", "//components/strings", + "//components/sync", "//components/sync:test_support_sync_core_impl", + "//components/sync:test_support_sync_driver", "//components/sync_bookmarks:sync_bookmarks", - "//components/sync_driver", - "//components/sync_driver:test_support", "//components/sync_sessions", "//components/sync_sessions:test_support", "//components/syncable_prefs", @@ -123,10 +122,10 @@ "//components/pref_registry", "//components/signin/core/browser:browser", "//components/signin/core/browser:test_support", + "//components/sync", "//components/sync:test_support_sync_core", "//components/sync:test_support_sync_core_impl", - "//components/sync_driver", - "//components/sync_driver:test_support", + "//components/sync:test_support_sync_driver", "//components/sync_sessions:test_support", "//components/syncable_prefs:test_support", "//google_apis",
diff --git a/components/browser_sync/browser/DEPS b/components/browser_sync/browser/DEPS index e9a5aaf..ed67f114 100644 --- a/components/browser_sync/browser/DEPS +++ b/components/browser_sync/browser/DEPS
@@ -16,7 +16,6 @@ "+components/sync", "+components/syncable_prefs", "+components/sync_bookmarks", - "+components/sync_driver", "+components/sync_sessions", "+components/strings", "+components/variations",
diff --git a/components/browser_sync/browser/abstract_profile_sync_service_test.cc b/components/browser_sync/browser/abstract_profile_sync_service_test.cc index 36fae2b..943ef62 100644 --- a/components/browser_sync/browser/abstract_profile_sync_service_test.cc +++ b/components/browser_sync/browser/abstract_profile_sync_service_test.cc
@@ -17,9 +17,9 @@ #include "components/sync/core/test/sync_manager_factory_for_profile_sync_test.h" #include "components/sync/core/test/test_internal_components_factory.h" #include "components/sync/core/test/test_user_share.h" +#include "components/sync/driver/glue/sync_backend_host_core.h" +#include "components/sync/driver/sync_api_component_factory_mock.h" #include "components/sync/protocol/sync.pb.h" -#include "components/sync_driver/glue/sync_backend_host_core.h" -#include "components/sync_driver/sync_api_component_factory_mock.h" #include "google_apis/gaia/gaia_constants.h" using syncer::ModelType;
diff --git a/components/browser_sync/browser/profile_sync_components_factory_impl.cc b/components/browser_sync/browser/profile_sync_components_factory_impl.cc index d367059f..e4ad0e0 100644 --- a/components/browser_sync/browser/profile_sync_components_factory_impl.cc +++ b/components/browser_sync/browser/profile_sync_components_factory_impl.cc
@@ -7,6 +7,7 @@ #include <utility> #include "base/command_line.h" +#include "base/feature_list.h" #include "base/memory/ptr_util.h" #include "base/memory/ref_counted.h" #include "build/build_config.h" @@ -28,20 +29,20 @@ #include "components/sync/core/attachments/attachment_service.h" #include "components/sync/core/attachments/attachment_service_impl.h" #include "components/sync/core/attachments/attachment_uploader_impl.h" +#include "components/sync/driver/data_type_manager_impl.h" +#include "components/sync/driver/device_info_data_type_controller.h" +#include "components/sync/driver/glue/chrome_report_unrecoverable_error.h" +#include "components/sync/driver/glue/sync_backend_host.h" +#include "components/sync/driver/glue/sync_backend_host_impl.h" +#include "components/sync/driver/local_device_info_provider_impl.h" +#include "components/sync/driver/proxy_data_type_controller.h" +#include "components/sync/driver/sync_client.h" +#include "components/sync/driver/sync_driver_switches.h" +#include "components/sync/driver/ui_data_type_controller.h" +#include "components/sync/driver/ui_model_type_controller.h" #include "components/sync_bookmarks/bookmark_change_processor.h" #include "components/sync_bookmarks/bookmark_data_type_controller.h" #include "components/sync_bookmarks/bookmark_model_associator.h" -#include "components/sync_driver/data_type_manager_impl.h" -#include "components/sync_driver/device_info_data_type_controller.h" -#include "components/sync_driver/glue/chrome_report_unrecoverable_error.h" -#include "components/sync_driver/glue/sync_backend_host.h" -#include "components/sync_driver/glue/sync_backend_host_impl.h" -#include "components/sync_driver/local_device_info_provider_impl.h" -#include "components/sync_driver/proxy_data_type_controller.h" -#include "components/sync_driver/sync_client.h" -#include "components/sync_driver/sync_driver_switches.h" -#include "components/sync_driver/ui_data_type_controller.h" -#include "components/sync_driver/ui_model_type_controller.h" #include "components/sync_sessions/session_data_type_controller.h" #include "google_apis/gaia/oauth2_token_service.h" #include "google_apis/gaia/oauth2_token_service_request.h" @@ -86,6 +87,13 @@ return syncer::ModelTypeSet(); } +// Used to gate syncing preferences, see crbug.com/374865 for more information. +// Has always been on for desktop/ChromeOS, so default to on. This feature is +// mainly to give us a kill switch should something go wrong with starting to +// sync prefs on mobile. +const base::Feature kSyncPreferencesFeature{"SyncPreferences", + base::FEATURE_ENABLED_BY_DEFAULT}; + } // namespace ProfileSyncComponentsFactoryImpl::ProfileSyncComponentsFactoryImpl( @@ -244,6 +252,12 @@ sync_client_->GetPasswordStateChangedCallback(), password_store_)); } + if (!disabled_types.Has(syncer::PREFERENCES) && + base::FeatureList::IsEnabled(kSyncPreferencesFeature)) { + sync_service->RegisterDataTypeController(new UIDataTypeController( + ui_thread_, error_callback, syncer::PREFERENCES, sync_client_)); + } + if (!disabled_types.Has(syncer::PRIORITY_PREFERENCES)) { sync_service->RegisterDataTypeController( new UIDataTypeController(ui_thread_, error_callback,
diff --git a/components/browser_sync/browser/profile_sync_components_factory_impl.h b/components/browser_sync/browser/profile_sync_components_factory_impl.h index c70e233c..3c04a32 100644 --- a/components/browser_sync/browser/profile_sync_components_factory_impl.h +++ b/components/browser_sync/browser/profile_sync_components_factory_impl.h
@@ -12,7 +12,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "components/sync/base/model_type.h" -#include "components/sync_driver/sync_api_component_factory.h" +#include "components/sync/driver/sync_api_component_factory.h" #include "components/version_info/version_info.h" #include "url/gurl.h"
diff --git a/components/browser_sync/browser/profile_sync_service.cc b/components/browser_sync/browser/profile_sync_service.cc index 2bca804..530dc37ed 100644 --- a/components/browser_sync/browser/profile_sync_service.cc +++ b/components/browser_sync/browser/profile_sync_service.cc
@@ -55,32 +55,32 @@ #include "components/sync/core/shared_model_type_processor.h" #include "components/sync/core/shutdown_reason.h" #include "components/sync/core/sync_encryption_handler.h" +#include "components/sync/driver/backend_migrator.h" +#include "components/sync/driver/change_processor.h" +#include "components/sync/driver/data_type_controller.h" +#include "components/sync/driver/device_info.h" +#include "components/sync/driver/device_info_service.h" +#include "components/sync/driver/device_info_sync_service.h" +#include "components/sync/driver/device_info_tracker.h" +#include "components/sync/driver/glue/chrome_report_unrecoverable_error.h" +#include "components/sync/driver/glue/sync_backend_host.h" +#include "components/sync/driver/glue/sync_backend_host_impl.h" +#include "components/sync/driver/pref_names.h" +#include "components/sync/driver/signin_manager_wrapper.h" +#include "components/sync/driver/sync_api_component_factory.h" +#include "components/sync/driver/sync_client.h" +#include "components/sync/driver/sync_driver_switches.h" +#include "components/sync/driver/sync_error_controller.h" +#include "components/sync/driver/sync_stopped_reporter.h" +#include "components/sync/driver/sync_type_preference_provider.h" +#include "components/sync/driver/sync_util.h" +#include "components/sync/driver/system_encryptor.h" +#include "components/sync/driver/user_selectable_sync_type.h" #include "components/sync/js/js_event_details.h" #include "components/sync/protocol/sync.pb.h" #include "components/sync/sessions/model_neutral_state.h" #include "components/sync/sessions/type_debug_info_observer.h" #include "components/sync/syncable/directory.h" -#include "components/sync_driver/backend_migrator.h" -#include "components/sync_driver/change_processor.h" -#include "components/sync_driver/data_type_controller.h" -#include "components/sync_driver/device_info.h" -#include "components/sync_driver/device_info_service.h" -#include "components/sync_driver/device_info_sync_service.h" -#include "components/sync_driver/device_info_tracker.h" -#include "components/sync_driver/glue/chrome_report_unrecoverable_error.h" -#include "components/sync_driver/glue/sync_backend_host.h" -#include "components/sync_driver/glue/sync_backend_host_impl.h" -#include "components/sync_driver/pref_names.h" -#include "components/sync_driver/signin_manager_wrapper.h" -#include "components/sync_driver/sync_api_component_factory.h" -#include "components/sync_driver/sync_client.h" -#include "components/sync_driver/sync_driver_switches.h" -#include "components/sync_driver/sync_error_controller.h" -#include "components/sync_driver/sync_stopped_reporter.h" -#include "components/sync_driver/sync_type_preference_provider.h" -#include "components/sync_driver/sync_util.h" -#include "components/sync_driver/system_encryptor.h" -#include "components/sync_driver/user_selectable_sync_type.h" #include "components/sync_sessions/favicon_cache.h" #include "components/sync_sessions/session_data_type_controller.h" #include "components/sync_sessions/sessions_sync_manager.h"
diff --git a/components/browser_sync/browser/profile_sync_service.h b/components/browser_sync/browser/profile_sync_service.h index 312740d..4d68f71 100644 --- a/components/browser_sync/browser/profile_sync_service.h +++ b/components/browser_sync/browser/profile_sync_service.h
@@ -34,21 +34,21 @@ #include "components/sync/core/shutdown_reason.h" #include "components/sync/core/sync_manager_factory.h" #include "components/sync/core/user_share.h" +#include "components/sync/driver/data_type_controller.h" +#include "components/sync/driver/data_type_manager.h" +#include "components/sync/driver/data_type_manager_observer.h" +#include "components/sync/driver/data_type_status_table.h" +#include "components/sync/driver/glue/sync_backend_host.h" +#include "components/sync/driver/local_device_info_provider.h" +#include "components/sync/driver/protocol_event_observer.h" +#include "components/sync/driver/startup_controller.h" +#include "components/sync/driver/sync_client.h" +#include "components/sync/driver/sync_frontend.h" +#include "components/sync/driver/sync_prefs.h" +#include "components/sync/driver/sync_service.h" +#include "components/sync/driver/sync_stopped_reporter.h" #include "components/sync/engine/model_safe_worker.h" #include "components/sync/js/sync_js_controller.h" -#include "components/sync_driver/data_type_controller.h" -#include "components/sync_driver/data_type_manager.h" -#include "components/sync_driver/data_type_manager_observer.h" -#include "components/sync_driver/data_type_status_table.h" -#include "components/sync_driver/glue/sync_backend_host.h" -#include "components/sync_driver/local_device_info_provider.h" -#include "components/sync_driver/protocol_event_observer.h" -#include "components/sync_driver/startup_controller.h" -#include "components/sync_driver/sync_client.h" -#include "components/sync_driver/sync_frontend.h" -#include "components/sync_driver/sync_prefs.h" -#include "components/sync_driver/sync_service.h" -#include "components/sync_driver/sync_stopped_reporter.h" #include "components/version_info/version_info.h" #include "google_apis/gaia/google_service_auth_error.h" #include "google_apis/gaia/oauth2_token_service.h"
diff --git a/components/browser_sync/browser/profile_sync_service_autofill_unittest.cc b/components/browser_sync/browser/profile_sync_service_autofill_unittest.cc index 7caa290..3dce8d8 100644 --- a/components/browser_sync/browser/profile_sync_service_autofill_unittest.cc +++ b/components/browser_sync/browser/profile_sync_service_autofill_unittest.cc
@@ -47,12 +47,12 @@ #include "components/sync/core/read_transaction.h" #include "components/sync/core/write_node.h" #include "components/sync/core/write_transaction.h" +#include "components/sync/driver/data_type_controller.h" +#include "components/sync/driver/data_type_manager_impl.h" +#include "components/sync/driver/sync_api_component_factory_mock.h" #include "components/sync/protocol/autofill_specifics.pb.h" #include "components/sync/syncable/mutable_entry.h" #include "components/sync/syncable/syncable_write_transaction.h" -#include "components/sync_driver/data_type_controller.h" -#include "components/sync_driver/data_type_manager_impl.h" -#include "components/sync_driver/sync_api_component_factory_mock.h" #include "components/syncable_prefs/pref_service_syncable.h" #include "components/version_info/version_info.h" #include "components/webdata/common/web_database.h"
diff --git a/components/browser_sync/browser/profile_sync_service_bookmark_unittest.cc b/components/browser_sync/browser/profile_sync_service_bookmark_unittest.cc index d68f402a..6851168 100644 --- a/components/browser_sync/browser/profile_sync_service_bookmark_unittest.cc +++ b/components/browser_sync/browser/profile_sync_service_bookmark_unittest.cc
@@ -47,13 +47,13 @@ #include "components/sync/core/write_node.h" #include "components/sync/core/write_transaction.h" #include "components/sync/core_impl/syncapi_internal.h" +#include "components/sync/driver/fake_sync_client.h" #include "components/sync/syncable/mutable_entry.h" #include "components/sync/syncable/syncable_id.h" #include "components/sync/syncable/syncable_util.h" #include "components/sync/syncable/syncable_write_transaction.h" #include "components/sync_bookmarks/bookmark_change_processor.h" #include "components/sync_bookmarks/bookmark_model_associator.h" -#include "components/sync_driver/fake_sync_client.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/components/browser_sync/browser/profile_sync_service_mock.h b/components/browser_sync/browser/profile_sync_service_mock.h index b9a858c..b003269 100644 --- a/components/browser_sync/browser/profile_sync_service_mock.h +++ b/components/browser_sync/browser/profile_sync_service_mock.h
@@ -12,10 +12,10 @@ #include "base/strings/string16.h" #include "components/browser_sync/browser/profile_sync_service.h" #include "components/sync/base/model_type.h" +#include "components/sync/driver/change_processor.h" +#include "components/sync/driver/data_type_controller.h" +#include "components/sync/driver/device_info.h" #include "components/sync/protocol/sync_protocol_error.h" -#include "components/sync_driver/change_processor.h" -#include "components/sync_driver/data_type_controller.h" -#include "components/sync_driver/device_info.h" #include "google_apis/gaia/google_service_auth_error.h" #include "testing/gmock/include/gmock/gmock.h"
diff --git a/components/browser_sync/browser/profile_sync_service_startup_unittest.cc b/components/browser_sync/browser/profile_sync_service_startup_unittest.cc index b67f8e2..6d35f16 100644 --- a/components/browser_sync/browser/profile_sync_service_startup_unittest.cc +++ b/components/browser_sync/browser/profile_sync_service_startup_unittest.cc
@@ -17,14 +17,14 @@ #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/common/signin_pref_names.h" -#include "components/sync_driver/data_type_manager.h" -#include "components/sync_driver/data_type_manager_mock.h" -#include "components/sync_driver/fake_data_type_controller.h" -#include "components/sync_driver/glue/sync_backend_host_mock.h" -#include "components/sync_driver/pref_names.h" -#include "components/sync_driver/sync_api_component_factory_mock.h" -#include "components/sync_driver/sync_prefs.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/data_type_manager.h" +#include "components/sync/driver/data_type_manager_mock.h" +#include "components/sync/driver/fake_data_type_controller.h" +#include "components/sync/driver/glue/sync_backend_host_mock.h" +#include "components/sync/driver/pref_names.h" +#include "components/sync/driver/sync_api_component_factory_mock.h" +#include "components/sync/driver/sync_prefs.h" +#include "components/sync/driver/sync_service_observer.h" #include "components/syncable_prefs/pref_service_syncable.h" #include "google_apis/gaia/gaia_auth_consumer.h" #include "google_apis/gaia/gaia_constants.h"
diff --git a/components/browser_sync/browser/profile_sync_service_typed_url_unittest.cc b/components/browser_sync/browser/profile_sync_service_typed_url_unittest.cc index 74822f61..a72a84d 100644 --- a/components/browser_sync/browser/profile_sync_service_typed_url_unittest.cc +++ b/components/browser_sync/browser/profile_sync_service_typed_url_unittest.cc
@@ -37,8 +37,8 @@ #include "components/sync/core/test/data_type_error_handler_mock.h" #include "components/sync/core/write_node.h" #include "components/sync/core/write_transaction.h" +#include "components/sync/driver/data_type_manager_impl.h" #include "components/sync/protocol/typed_url_specifics.pb.h" -#include "components/sync_driver/data_type_manager_impl.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h"
diff --git a/components/browser_sync/browser/profile_sync_service_unittest.cc b/components/browser_sync/browser/profile_sync_service_unittest.cc index 45b5497..1e637e4 100644 --- a/components/browser_sync/browser/profile_sync_service_unittest.cc +++ b/components/browser_sync/browser/profile_sync_service_unittest.cc
@@ -29,16 +29,16 @@ #include "components/signin/core/browser/account_tracker_service.h" #include "components/signin/core/browser/fake_signin_manager.h" #include "components/strings/grit/components_strings.h" -#include "components/sync_driver/data_type_manager.h" -#include "components/sync_driver/data_type_manager_observer.h" -#include "components/sync_driver/fake_data_type_controller.h" -#include "components/sync_driver/glue/sync_backend_host_mock.h" -#include "components/sync_driver/pref_names.h" -#include "components/sync_driver/sync_api_component_factory_mock.h" -#include "components/sync_driver/sync_driver_switches.h" -#include "components/sync_driver/sync_prefs.h" -#include "components/sync_driver/sync_service_observer.h" -#include "components/sync_driver/sync_util.h" +#include "components/sync/driver/data_type_manager.h" +#include "components/sync/driver/data_type_manager_observer.h" +#include "components/sync/driver/fake_data_type_controller.h" +#include "components/sync/driver/glue/sync_backend_host_mock.h" +#include "components/sync/driver/pref_names.h" +#include "components/sync/driver/sync_api_component_factory_mock.h" +#include "components/sync/driver/sync_driver_switches.h" +#include "components/sync/driver/sync_prefs.h" +#include "components/sync/driver/sync_service_observer.h" +#include "components/sync/driver/sync_util.h" #include "components/syncable_prefs/testing_pref_service_syncable.h" #include "components/version_info/version_info.h" #include "components/version_info/version_info_values.h"
diff --git a/components/browser_sync/browser/profile_sync_test_util.cc b/components/browser_sync/browser/profile_sync_test_util.cc index 5852310..25578299 100644 --- a/components/browser_sync/browser/profile_sync_test_util.cc +++ b/components/browser_sync/browser/profile_sync_test_util.cc
@@ -9,11 +9,11 @@ #include "components/history/core/browser/history_model_worker.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/signin/core/browser/signin_manager_base.h" +#include "components/sync/driver/glue/browser_thread_model_worker.h" +#include "components/sync/driver/glue/ui_model_worker.h" +#include "components/sync/driver/signin_manager_wrapper.h" +#include "components/sync/driver/sync_prefs.h" #include "components/sync/engine/passive_model_worker.h" -#include "components/sync_driver/glue/browser_thread_model_worker.h" -#include "components/sync_driver/glue/ui_model_worker.h" -#include "components/sync_driver/signin_manager_wrapper.h" -#include "components/sync_driver/sync_prefs.h" #include "net/url_request/url_request_test_util.h" namespace browser_sync {
diff --git a/components/browser_sync/browser/profile_sync_test_util.h b/components/browser_sync/browser/profile_sync_test_util.h index ae554e28..202f44d 100644 --- a/components/browser_sync/browser/profile_sync_test_util.h +++ b/components/browser_sync/browser/profile_sync_test_util.h
@@ -19,8 +19,8 @@ #include "components/signin/core/browser/fake_profile_oauth2_token_service.h" #include "components/signin/core/browser/fake_signin_manager.h" #include "components/signin/core/browser/test_signin_client.h" -#include "components/sync_driver/fake_sync_client.h" -#include "components/sync_driver/sync_api_component_factory_mock.h" +#include "components/sync/driver/fake_sync_client.h" +#include "components/sync/driver/sync_api_component_factory_mock.h" #include "components/sync_sessions/fake_sync_sessions_client.h" #include "components/syncable_prefs/testing_pref_service_syncable.h"
diff --git a/components/browser_sync/browser/test_profile_sync_service.h b/components/browser_sync/browser/test_profile_sync_service.h index 125255a..22609c2b 100644 --- a/components/browser_sync/browser/test_profile_sync_service.h +++ b/components/browser_sync/browser/test_profile_sync_service.h
@@ -8,9 +8,9 @@ #include "base/macros.h" #include "components/browser_sync/browser/profile_sync_service.h" #include "components/sync/base/weak_handle.h" +#include "components/sync/driver/data_type_manager.h" #include "components/sync/js/js_event_handler.h" #include "components/sync/test/engine/test_id_factory.h" -#include "components/sync_driver/data_type_manager.h" namespace sync_driver { class SyncPrefs;
diff --git a/components/browsing_data.gypi b/components/browsing_data.gypi index 6b2e95c..7e9ea7d 100644 --- a/components/browsing_data.gypi +++ b/components/browsing_data.gypi
@@ -13,7 +13,7 @@ 'components.gyp:autofill_core_browser', 'components.gyp:history_core_browser', 'components.gyp:password_manager_core_browser', - 'components.gyp:sync_driver', + 'sync.gyp:sync', 'components.gyp:webdata_common', 'prefs/prefs.gyp:prefs', ],
diff --git a/components/browsing_data/core/BUILD.gn b/components/browsing_data/core/BUILD.gn index 19ae36c..927ce1259 100644 --- a/components/browsing_data/core/BUILD.gn +++ b/components/browsing_data/core/BUILD.gn
@@ -28,7 +28,7 @@ "//components/history/core/browser", "//components/password_manager/core/browser", "//components/prefs:prefs", - "//components/sync_driver", + "//components/sync", "//components/webdata/common", ] }
diff --git a/components/browsing_data/core/DEPS b/components/browsing_data/core/DEPS index f04c02e..7efb83a 100644 --- a/components/browsing_data/core/DEPS +++ b/components/browsing_data/core/DEPS
@@ -3,6 +3,6 @@ "+components/history/core/browser", "+components/password_manager/core/browser", "+components/prefs", - "+components/sync_driver", + "+components/sync/driver", "+components/webdata/common", ]
diff --git a/components/browsing_data/core/counters/history_counter.h b/components/browsing_data/core/counters/history_counter.h index 2b835584..48b6fa09 100644 --- a/components/browsing_data/core/counters/history_counter.h +++ b/components/browsing_data/core/counters/history_counter.h
@@ -10,8 +10,8 @@ #include "components/browsing_data/core/counters/browsing_data_counter.h" #include "components/history/core/browser/history_service.h" #include "components/history/core/browser/web_history_service.h" -#include "components/sync_driver/sync_service.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/sync_service.h" +#include "components/sync/driver/sync_service_observer.h" namespace browsing_data {
diff --git a/components/browsing_data_ui.gypi b/components/browsing_data_ui.gypi index f7d10e0f..85365c29 100644 --- a/components/browsing_data_ui.gypi +++ b/components/browsing_data_ui.gypi
@@ -11,7 +11,7 @@ 'dependencies': [ '../base/base.gyp:base', 'history_core_browser', - 'sync_driver', + 'sync.gyp:sync', 'version_info', ], 'include_dirs': [
diff --git a/components/browsing_data_ui/BUILD.gn b/components/browsing_data_ui/BUILD.gn index f969701..b544f55 100644 --- a/components/browsing_data_ui/BUILD.gn +++ b/components/browsing_data_ui/BUILD.gn
@@ -11,7 +11,7 @@ deps = [ "//base", "//components/history/core/browser", - "//components/sync_driver:sync_driver", + "//components/sync", "//components/version_info", ] } @@ -27,8 +27,8 @@ "//base", "//components/history/core/test:test", "//components/signin/core/browser:test_support", + "//components/sync:test_support_sync_driver", "//components/sync/protocol:protocol", - "//components/sync_driver:test_support", "//components/version_info:version_info", "//net", "//testing/gtest",
diff --git a/components/browsing_data_ui/DEPS b/components/browsing_data_ui/DEPS index 34c3258..3cb5fa0 100644 --- a/components/browsing_data_ui/DEPS +++ b/components/browsing_data_ui/DEPS
@@ -5,7 +5,7 @@ "+components/signin", "+components/sync/base", "+components/sync/core", - "+components/sync_driver", + "+components/sync/driver", "+components/version_info", "+net", ]
diff --git a/components/browsing_data_ui/history_notice_utils.cc b/components/browsing_data_ui/history_notice_utils.cc index dca2c14e..f3556f30 100644 --- a/components/browsing_data_ui/history_notice_utils.cc +++ b/components/browsing_data_ui/history_notice_utils.cc
@@ -11,7 +11,7 @@ #include "base/strings/stringprintf.h" #include "base/threading/thread_task_runner_handle.h" #include "components/history/core/browser/web_history_service.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_service.h" #include "components/version_info/version_info.h" namespace {
diff --git a/components/browsing_data_ui/history_notice_utils_unittest.cc b/components/browsing_data_ui/history_notice_utils_unittest.cc index dae05bac..4594af8 100644 --- a/components/browsing_data_ui/history_notice_utils_unittest.cc +++ b/components/browsing_data_ui/history_notice_utils_unittest.cc
@@ -15,7 +15,7 @@ #include "components/signin/core/browser/fake_signin_manager.h" #include "components/signin/core/browser/test_signin_client.h" #include "components/sync/base/model_type.h" -#include "components/sync_driver/fake_sync_service.h" +#include "components/sync/driver/fake_sync_service.h" #include "components/version_info/version_info.h" #include "net/http/http_status_code.h" #include "net/url_request/url_request_test_util.h"
diff --git a/components/cast_certificate/cast_cert_validator.cc b/components/cast_certificate/cast_cert_validator.cc index 9dcff2f..3e9bb222 100644 --- a/components/cast_certificate/cast_cert_validator.cc +++ b/components/cast_certificate/cast_cert_validator.cc
@@ -67,12 +67,16 @@ // storage. template <size_t N> void AddAnchor(const uint8_t (&data)[N]) { - scoped_refptr<net::ParsedCertificate> root = + scoped_refptr<net::ParsedCertificate> cert = net::ParsedCertificate::CreateFromCertificateData( data, N, net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE, {}); - CHECK(root); - store_.AddTrustedCertificate(std::move(root)); + CHECK(cert); + // TODO(crbug.com/635200): Support anchor constraints, and initialize the + // anchor using constraints from the self-signed certificate. + scoped_refptr<net::TrustAnchor> anchor = + net::TrustAnchor::CreateFromCertificateNoConstraints(std::move(cert)); + store_.AddTrustAnchor(std::move(anchor)); } net::TrustStore store_;
diff --git a/components/cast_certificate/cast_crl.cc b/components/cast_certificate/cast_crl.cc index 94ecb1a..e923395 100644 --- a/components/cast_certificate/cast_crl.cc +++ b/components/cast_certificate/cast_crl.cc
@@ -62,12 +62,17 @@ CastCRLTrustStore() { // Initialize the trust store with the root certificate. - scoped_refptr<net::ParsedCertificate> root = + scoped_refptr<net::ParsedCertificate> cert = net::ParsedCertificate::CreateFromCertificateData( kCastCRLRootCaDer, sizeof(kCastCRLRootCaDer), net::ParsedCertificate::DataSource::EXTERNAL_REFERENCE, {}); - CHECK(root); - store_.AddTrustedCertificate(std::move(root)); + CHECK(cert); + // TODO(crbug.com/635200): Support anchor constraints, and initialize the + // anchor using constraints from the self-signed certificate. + scoped_refptr<net::TrustAnchor> anchor = + net::TrustAnchor::CreateFromCertificateNoConstraints(std::move(cert)); + CHECK(anchor); + store_.AddTrustAnchor(std::move(anchor)); } net::TrustStore store_; @@ -166,8 +171,11 @@ } // Set CRL expiry to the earliest of the cert chain expiry and CRL expiry. + // Note that the trust anchor is not part of this loop. + // "expiration" of the trust anchor is handled instead by its + // presence in the trust store. *overall_not_after = not_after; - for (const auto& cert : result.paths[result.best_result_index]->path) { + for (const auto& cert : result.paths[result.best_result_index]->path.certs) { net::der::GeneralizedTime cert_not_after = cert->tbs().validity_not_after; if (cert_not_after < *overall_not_after) *overall_not_after = cert_not_after; @@ -191,7 +199,7 @@ const net::der::GeneralizedTime& overall_not_after); ~CastCRLImpl() override; - bool CheckRevocation(const net::ParsedCertificateList& trusted_chain, + bool CheckRevocation(const net::CertPath& trusted_chain, const base::Time& time) const override; private: @@ -245,12 +253,13 @@ // Verifies the revocation status of the certificate chain, at the specified // time. -bool CastCRLImpl::CheckRevocation( - const net::ParsedCertificateList& trusted_chain, - const base::Time& time) const { - if (trusted_chain.empty()) +bool CastCRLImpl::CheckRevocation(const net::CertPath& trusted_chain, + const base::Time& time) const { + if (trusted_chain.IsEmpty()) return false; + DCHECK(trusted_chain.trust_anchor); + // Check the validity of the CRL at the specified time. net::der::GeneralizedTime verification_time; if (!net::der::EncodeTimeAsGeneralizedTime(time, &verification_time)) { @@ -262,12 +271,20 @@ return false; } - // Check revocation. - for (size_t i = 0; i < trusted_chain.size(); ++i) { - const auto& parsed_cert = trusted_chain[i]; + // Check revocation. Note that this loop has "+ 1" in order to also loop + // over the trust anchor (which is treated specially). + for (size_t i = 0; i < trusted_chain.certs.size() + 1; ++i) { + // This loop iterates over both certificates AND then the trust + // anchor after exhausing the certs. + net::der::Input spki_tlv; + if (i == trusted_chain.certs.size()) { + spki_tlv = trusted_chain.trust_anchor->spki(); + } else { + spki_tlv = trusted_chain.certs[i]->tbs().spki_tlv; + } + // Calculate the public key's hash to check for revocation. - std::string spki_hash = - crypto::SHA256HashString(parsed_cert->tbs().spki_tlv.AsString()); + std::string spki_hash = crypto::SHA256HashString(spki_tlv.AsString()); if (revoked_hashes_.find(spki_hash) != revoked_hashes_.end()) { VLOG(2) << "Public key is revoked."; return false; @@ -277,7 +294,7 @@ if (i > 0) { auto issuer_iter = revoked_serial_numbers_.find(spki_hash); if (issuer_iter != revoked_serial_numbers_.end()) { - const auto& subordinate = trusted_chain[i - 1]; + const auto& subordinate = trusted_chain.certs[i - 1]; uint64_t serial_number; // Only Google generated device certificates will be revoked by range. // These will always be less than 64 bits in length.
diff --git a/components/cast_certificate/cast_crl.h b/components/cast_certificate/cast_crl.h index f7d102a9..0ab6964 100644 --- a/components/cast_certificate/cast_crl.h +++ b/components/cast_certificate/cast_crl.h
@@ -16,6 +16,7 @@ namespace net { class TrustStore; +struct CertPath; } namespace cast_certificate { @@ -29,17 +30,14 @@ // of X.509 certificates. // // Inputs: - // * |certs| is the verified chain of X.509 certificates: - // * |certs[0]| is the target certificate (i.e. the device certificate). - // * |certs[i]| is the certificate that issued certs[i-1]. - // * |certs.back()| is assumed to be a trusted root. + // * |chain| the chain of verified certificates, including trust anchor. // // * |time| is the unix timestamp to use for determining if the certificate // is revoked. // // Output: // Returns true if no certificate in the chain was revoked. - virtual bool CheckRevocation(const net::ParsedCertificateList& certs, + virtual bool CheckRevocation(const net::CertPath& chain, const base::Time& time) const = 0; };
diff --git a/components/cast_certificate/cast_crl_unittest.cc b/components/cast_certificate/cast_crl_unittest.cc index 5698dbe..5d845fe 100644 --- a/components/cast_certificate/cast_crl_unittest.cc +++ b/components/cast_certificate/cast_crl_unittest.cc
@@ -20,10 +20,12 @@ const auto trusted_test_roots = cast_certificate::testing::ReadCertificateChainFromFile(path); for (const auto& trusted_root : trusted_test_roots) { - scoped_refptr<net::ParsedCertificate> anchor( + scoped_refptr<net::ParsedCertificate> cert( net::ParsedCertificate::CreateFromCertificateCopy(trusted_root, {})); - EXPECT_TRUE(anchor); - trust_store->AddTrustedCertificate(std::move(anchor)); + EXPECT_TRUE(cert); + scoped_refptr<net::TrustAnchor> anchor = + net::TrustAnchor::CreateFromCertificateNoConstraints(std::move(cert)); + trust_store->AddTrustAnchor(std::move(anchor)); } return trust_store; }
diff --git a/components/certificate_transparency/log_proof_fetcher.cc b/components/certificate_transparency/log_proof_fetcher.cc index 0cfcc39..53c2e7c 100644 --- a/components/certificate_transparency/log_proof_fetcher.cc +++ b/components/certificate_transparency/log_proof_fetcher.cc
@@ -397,8 +397,8 @@ } LogProofFetcher::~LogProofFetcher() { - STLDeleteContainerPointers(inflight_fetches_.begin(), - inflight_fetches_.end()); + base::STLDeleteContainerPointers(inflight_fetches_.begin(), + inflight_fetches_.end()); } void LogProofFetcher::FetchSignedTreeHead(
diff --git a/components/components.gyp b/components/components.gyp index ee33fc3e..d670750 100644 --- a/components/components.gyp +++ b/components/components.gyp
@@ -92,7 +92,6 @@ 'suggestions.gypi', 'supervised_user_error_page.gypi', 'sync_bookmarks.gypi', - 'sync_driver.gypi', 'sync_sessions.gypi', 'syncable_prefs.gypi', 'toolbar.gypi',
diff --git a/components/components_tests.gyp b/components/components_tests.gyp index 300082b..44c7672a 100644 --- a/components/components_tests.gyp +++ b/components/components_tests.gyp
@@ -556,7 +556,6 @@ 'policy/core/browser/url_blacklist_policy_handler_unittest.cc', 'policy/core/common/async_policy_provider_unittest.cc', 'policy/core/common/cloud/cloud_policy_client_unittest.cc', - 'policy/core/common/cloud/cloud_policy_constants_unittest.cc', 'policy/core/common/cloud/cloud_policy_core_unittest.cc', 'policy/core/common/cloud/cloud_policy_manager_unittest.cc', 'policy/core/common/cloud/cloud_policy_refresh_scheduler_unittest.cc', @@ -753,6 +752,16 @@ 'signin/ios/browser/account_consistency_service_unittest.mm', 'signin/ios/browser/profile_oauth2_token_service_ios_delegate_unittest.mm', ], + 'spellcheck_unittest_sources': [ + 'spellcheck/renderer/custom_dictionary_engine_unittest.cc', + 'spellcheck/renderer/spellcheck_multilingual_unittest.cc', + 'spellcheck/renderer/spellcheck_provider_hunspell_unittest.cc', + 'spellcheck/renderer/spellcheck_provider_mac_unittest.cc', + 'spellcheck/renderer/spellcheck_provider_test.cc', + 'spellcheck/renderer/spellcheck_provider_test.h', + 'spellcheck/renderer/spellcheck_unittest.cc', + 'spellcheck/renderer/spellcheck_worditerator_unittest.cc', + ], 'ssl_config_unittest_sources': [ 'ssl_config/ssl_config_service_manager_pref_unittest.cc', ], @@ -812,6 +821,34 @@ 'sync/api/sync_data_unittest.cc', 'sync/api/sync_error_unittest.cc', 'sync/api/sync_merge_result_unittest.cc', + 'sync/driver/about_sync_util_unittest.cc', + 'sync/driver/backend_migrator_unittest.cc', + 'sync/driver/data_type_manager_impl_unittest.cc', + 'sync/driver/device_count_metrics_provider_unittest.cc', + 'sync/driver/device_info_data_type_controller_unittest.cc', + 'sync/driver/device_info_service_unittest.cc', + 'sync/driver/device_info_sync_service_unittest.cc', + 'sync/driver/device_info_util_unittest.cc', + 'sync/driver/frontend_data_type_controller_unittest.cc', + 'sync/driver/generic_change_processor_unittest.cc', + 'sync/driver/glue/browser_thread_model_worker_unittest.cc', + 'sync/driver/glue/sync_backend_host_impl_unittest.cc', + 'sync/driver/glue/sync_backend_registrar_unittest.cc', + 'sync/driver/glue/ui_model_worker_unittest.cc', + 'sync/driver/local_device_info_provider_unittest.cc', + 'sync/driver/model_association_manager_unittest.cc', + 'sync/driver/non_blocking_data_type_controller_unittest.cc', + 'sync/driver/non_ui_data_type_controller_unittest.cc', + 'sync/driver/non_ui_model_type_controller_unittest.cc', + 'sync/driver/profile_sync_auth_provider_unittest.cc', + 'sync/driver/shared_change_processor_unittest.cc', + 'sync/driver/startup_controller_unittest.cc', + 'sync/driver/sync_prefs_unittest.cc', + 'sync/driver/sync_stopped_reporter_unittest.cc', + 'sync/driver/sync_util_unittest.cc', + 'sync/driver/system_encryptor_unittest.cc', + 'sync/driver/ui_data_type_controller_unittest.cc', + 'sync/driver/ui_model_type_controller_unittest.cc', 'sync/engine_impl/apply_control_data_updates_unittest.cc', 'sync/engine_impl/backoff_delay_provider_unittest.cc', 'sync/engine_impl/directory_commit_contribution_unittest.cc', @@ -889,36 +926,6 @@ 'sync_bookmarks_unittest_sources': [ 'sync_bookmarks/bookmark_data_type_controller_unittest.cc', ], - 'sync_driver_unittest_sources': [ - 'sync_driver/about_sync_util_unittest.cc', - 'sync_driver/backend_migrator_unittest.cc', - 'sync_driver/data_type_manager_impl_unittest.cc', - 'sync_driver/device_count_metrics_provider_unittest.cc', - 'sync_driver/device_info_data_type_controller_unittest.cc', - 'sync_driver/device_info_service_unittest.cc', - 'sync_driver/device_info_sync_service_unittest.cc', - 'sync_driver/device_info_util_unittest.cc', - 'sync_driver/frontend_data_type_controller_unittest.cc', - 'sync_driver/generic_change_processor_unittest.cc', - 'sync_driver/glue/browser_thread_model_worker_unittest.cc', - 'sync_driver/glue/sync_backend_host_impl_unittest.cc', - 'sync_driver/glue/sync_backend_registrar_unittest.cc', - 'sync_driver/glue/ui_model_worker_unittest.cc', - 'sync_driver/local_device_info_provider_unittest.cc', - 'sync_driver/model_association_manager_unittest.cc', - 'sync_driver/non_blocking_data_type_controller_unittest.cc', - 'sync_driver/non_ui_data_type_controller_unittest.cc', - 'sync_driver/non_ui_model_type_controller_unittest.cc', - 'sync_driver/profile_sync_auth_provider_unittest.cc', - 'sync_driver/shared_change_processor_unittest.cc', - 'sync_driver/startup_controller_unittest.cc', - 'sync_driver/sync_prefs_unittest.cc', - 'sync_driver/sync_stopped_reporter_unittest.cc', - 'sync_driver/sync_util_unittest.cc', - 'sync_driver/system_encryptor_unittest.cc', - 'sync_driver/ui_data_type_controller_unittest.cc', - 'sync_driver/ui_model_type_controller_unittest.cc', - ], 'sync_sessions_unittest_sources': [ 'sync_sessions/favicon_cache_unittest.cc', 'sync_sessions/revisit/bookmarks_page_revisit_observer_unittest.cc', @@ -1158,7 +1165,6 @@ '<@(supervised_user_error_page_unittest_sources)', '<@(sync_unittest_sources)', '<@(sync_bookmarks_unittest_sources)', - '<@(sync_driver_unittest_sources)', '<@(sync_sessions_unittest_sources)', '<@(syncable_prefs_unittest_sources)', '<@(translate_unittest_sources)', @@ -1290,6 +1296,7 @@ 'components.gyp:sessions_test_support', 'components.gyp:signin_core_browser', 'components.gyp:signin_core_browser_test_support', + 'components.gyp:spellcheck_renderer', 'components.gyp:ssl_config', 'components.gyp:ssl_errors', 'components.gyp:subresource_filter_core_browser_test_support', @@ -1299,8 +1306,6 @@ 'components.gyp:suggestions', 'components.gyp:supervised_user_error_page', 'components.gyp:sync_bookmarks', - 'components.gyp:sync_driver', - 'components.gyp:sync_driver_test_support', 'components.gyp:sync_sessions', 'components.gyp:sync_sessions_test_support', 'components.gyp:syncable_prefs_test_support', @@ -1333,6 +1338,7 @@ 'sync.gyp:test_support_sync_api', 'sync.gyp:test_support_sync_core', 'sync.gyp:test_support_sync_core_impl', + 'sync.gyp:test_support_sync_driver', 'url_formatter/url_formatter.gyp:url_formatter', ], 'conditions': [ @@ -1369,6 +1375,24 @@ 'components.gyp:constrained_window', ] }], + ['enable_spellcheck==1', { + 'sources': [ '<@(spellcheck_unittest_sources)' ], + 'conditions': [ + ['OS=="android"', { + 'sources!': [ + 'spellcheck/renderer/spellcheck_multilingual_unittest.cc', + 'spellcheck/renderer/spellcheck_provider_hunspell_unittest.cc', + 'spellcheck/renderer/spellcheck_unittest.cc', + ], + }], + ['OS=="mac"', { + 'sources!': [ + 'spellcheck/renderer/spellcheck_multilingual_unittest.cc', + 'spellcheck/renderer/spellcheck_provider_hunspell_unittest.cc', + ], + }], + ], + }], ['OS=="win"', { 'dependencies': [ 'components.gyp:browser_watcher', @@ -1703,7 +1727,7 @@ ], 'sources': [ '<@(policy_unittest_sources)', - 'sync_driver/sync_policy_handler_unittest.cc', + 'sync/driver/sync_policy_handler_unittest.cc', ], 'conditions': [ ['OS=="android"', { @@ -1745,7 +1769,7 @@ }, { # configuration_policy!=1 'sources!': [ 'search_engines/default_search_policy_handler_unittest.cc', - 'sync_driver/sync_policy_handler_unittest.cc', + 'sync/driver/sync_policy_handler_unittest.cc', ], }], ['enable_plugins == 1', {
diff --git a/components/content_settings/core/browser/content_settings_info.cc b/components/content_settings/core/browser/content_settings_info.cc index 62e5c68..c111944e 100644 --- a/components/content_settings/core/browser/content_settings_info.cc +++ b/components/content_settings/core/browser/content_settings_info.cc
@@ -21,7 +21,7 @@ ContentSettingsInfo::~ContentSettingsInfo() {} bool ContentSettingsInfo::IsSettingValid(ContentSetting setting) const { - return ContainsKey(valid_settings_, setting); + return base::ContainsKey(valid_settings_, setting); } } // namespace content_settings
diff --git a/components/content_settings/core/browser/content_settings_registry.cc b/components/content_settings/core/browser/content_settings_registry.cc index c104f67..cdcccc5 100644 --- a/components/content_settings/core/browser/content_settings_registry.cc +++ b/components/content_settings/core/browser/content_settings_registry.cc
@@ -339,9 +339,9 @@ ContentSettingsInfo::IncognitoBehavior incognito_behavior) { // Ensure that nothing has been registered yet for the given type. DCHECK(!website_settings_registry_->Get(type)); - DCHECK(incognito_behavior - != ContentSettingsInfo::INHERIT_IN_INCOGNITO_EXCEPT_ALLOW - || ContainsKey(valid_settings, CONTENT_SETTING_ASK)) + DCHECK(incognito_behavior != + ContentSettingsInfo::INHERIT_IN_INCOGNITO_EXCEPT_ALLOW || + base::ContainsKey(valid_settings, CONTENT_SETTING_ASK)) << "If INHERIT_IN_INCOGNITO_EXCEPT_ALLOW is set, ASK must be listed as a " "valid setting."; std::unique_ptr<base::Value> default_value( @@ -357,7 +357,7 @@ if (!website_settings_info) return; - DCHECK(!ContainsKey(content_settings_info_, type)); + DCHECK(!base::ContainsKey(content_settings_info_, type)); content_settings_info_[type] = base::WrapUnique( new ContentSettingsInfo(website_settings_info, whitelisted_schemes, valid_settings, incognito_behavior));
diff --git a/components/content_settings/core/browser/host_content_settings_map.cc b/components/content_settings/core/browser/host_content_settings_map.cc index 1805e9c..bf860d8 100644 --- a/components/content_settings/core/browser/host_content_settings_map.cc +++ b/components/content_settings/core/browser/host_content_settings_map.cc
@@ -187,7 +187,7 @@ MigrateKeygenSettings(); MigrateDomainScopedSettings(false); - RecordNumberOfExceptions(); + RecordExceptionMetrics(); } // static @@ -600,7 +600,7 @@ return weak_ptr_factory_.GetWeakPtr(); } -void HostContentSettingsMap::RecordNumberOfExceptions() { +void HostContentSettingsMap::RecordExceptionMetrics() { for (const content_settings::WebsiteSettingsInfo* info : *content_settings::WebsiteSettingsRegistry::GetInstance()) { ContentSettingsType content_type = info->type(); @@ -610,6 +610,17 @@ GetSettingsForOneType(content_type, std::string(), &settings); size_t num_exceptions = 0; for (const ContentSettingPatternSource& setting_entry : settings) { + // Skip default settings. + if (setting_entry.primary_pattern == ContentSettingsPattern::Wildcard() && + setting_entry.secondary_pattern == + ContentSettingsPattern::Wildcard()) { + continue; + } + + UMA_HISTOGRAM_ENUMERATION("ContentSettings.ExceptionScheme", + setting_entry.primary_pattern.GetScheme(), + ContentSettingsPattern::SCHEME_MAX); + if (setting_entry.source == "preference") ++num_exceptions; } @@ -756,7 +767,7 @@ HostContentSettingsMap::~HostContentSettingsMap() { DCHECK(!prefs_); - STLDeleteValues(&content_settings_providers_); + base::STLDeleteValues(&content_settings_providers_); } void HostContentSettingsMap::ShutdownOnUIThread() {
diff --git a/components/content_settings/core/browser/host_content_settings_map.h b/components/content_settings/core/browser/host_content_settings_map.h index bb22309..13a9234a 100644 --- a/components/content_settings/core/browser/host_content_settings_map.h +++ b/components/content_settings/core/browser/host_content_settings_map.h
@@ -329,8 +329,8 @@ // leave in some code to remove old-format settings for a long time. void MigrateKeygenSettings(); - // Collect UMA data about the number of exceptions. - void RecordNumberOfExceptions(); + // Collect UMA data of exceptions. + void RecordExceptionMetrics(); // Adds content settings for |content_type| and |resource_identifier|, // provided by |provider|, into |settings|. If |incognito| is true, adds only
diff --git a/components/content_settings/core/common/content_settings.cc b/components/content_settings/core/common/content_settings.cc index c742698..1e25f171 100644 --- a/components/content_settings/core/common/content_settings.cc +++ b/components/content_settings/core/common/content_settings.cc
@@ -71,7 +71,7 @@ } } - DCHECK(ContainsKey(kMap, content_setting)); + DCHECK(base::ContainsKey(kMap, content_setting)); *num_values = arraysize(kHistogramOrder); return kMap[content_setting]; }
diff --git a/components/content_settings/core/common/content_settings_pattern.cc b/components/content_settings/core/common/content_settings_pattern.cc index aa89594..348892e5 100644 --- a/components/content_settings/core/common/content_settings_pattern.cc +++ b/components/content_settings/core/common/content_settings_pattern.cc
@@ -21,6 +21,19 @@ // The component supports only one scheme for simplicity. const char* non_port_non_domain_wildcard_scheme = NULL; +// Keep it consistent with enum SchemeType in content_settings_pattern.h. +const char* const kSchemeNames[] = { + "wildcard", + "other", + url::kHttpScheme, + url::kHttpsScheme, + url::kFileScheme, + "chrome-extension", +}; + +static_assert(arraysize(kSchemeNames) == ContentSettingsPattern::SCHEME_MAX, + "kSchemeNames should have SCHEME_MAX elements"); + std::string GetDefaultPort(const std::string& scheme) { if (scheme == url::kHttpScheme) return "80"; @@ -590,6 +603,17 @@ return std::string(); } +ContentSettingsPattern::SchemeType ContentSettingsPattern::GetScheme() const { + if (parts_.is_scheme_wildcard) + return SCHEME_WILDCARD; + + for (size_t i = 2; i < arraysize(kSchemeNames); ++i) { + if (parts_.scheme == kSchemeNames[i]) + return static_cast<SchemeType>(i); + } + return SCHEME_OTHER; +} + ContentSettingsPattern::Relation ContentSettingsPattern::Compare( const ContentSettingsPattern& other) const { // Two invalid patterns are identical in the way they behave. They don't match
diff --git a/components/content_settings/core/common/content_settings_pattern.h b/components/content_settings/core/common/content_settings_pattern.h index b5b8352..fc7b6091 100644 --- a/components/content_settings/core/common/content_settings_pattern.h +++ b/components/content_settings/core/common/content_settings_pattern.h
@@ -53,6 +53,19 @@ DISJOINT_ORDER_PRE = 2, }; + // This enum is used to back an UMA histogram, the order of existing values + // should not be changed. New values should only append before SCHEME_MAX. + // Also keep it consistent with kSchemeNames in content_settings_pattern.cc. + enum SchemeType { + SCHEME_WILDCARD, + SCHEME_OTHER, + SCHEME_HTTP, + SCHEME_HTTPS, + SCHEME_FILE, + SCHEME_CHROMEEXTENSION, + SCHEME_MAX, + }; + struct PatternParts { PatternParts(); PatternParts(const PatternParts& other); @@ -178,6 +191,9 @@ // Returns a std::string representation of this pattern. std::string ToString() const; + // Returns scheme type of pattern. + ContentSettingsPattern::SchemeType GetScheme() const; + // Compares the pattern with a given |other| pattern and returns the // |Relation| of the two patterns. Relation Compare(const ContentSettingsPattern& other) const;
diff --git a/components/content_settings/core/common/content_settings_pattern_unittest.cc b/components/content_settings/core/common/content_settings_pattern_unittest.cc index 38125c4..9ca58774 100644 --- a/components/content_settings/core/common/content_settings_pattern_unittest.cc +++ b/components/content_settings/core/common/content_settings_pattern_unittest.cc
@@ -808,4 +808,22 @@ ContentSettingsPattern::FromString("https://[*.]google.com:443"), &origin_pattern)); EXPECT_EQ("https://google.com:443", origin_pattern.ToString()); +} + +TEST(ContentSettingsPatternTest, Schemes) { + EXPECT_EQ(ContentSettingsPattern::SCHEME_HTTP, + Pattern("http://www.example.com").GetScheme()); + EXPECT_EQ(ContentSettingsPattern::SCHEME_HTTPS, + Pattern("https://www.example.com").GetScheme()); + EXPECT_EQ(ContentSettingsPattern::SCHEME_FILE, + Pattern("file:///tmp/file.html").GetScheme()); + EXPECT_EQ(ContentSettingsPattern::SCHEME_CHROMEEXTENSION, + Pattern("chrome-extension://peoadpeiejnhkmpaakpnompolbglelel/") + .GetScheme()); + EXPECT_EQ(ContentSettingsPattern::SCHEME_WILDCARD, + Pattern("192.168.0.1").GetScheme()); + EXPECT_EQ(ContentSettingsPattern::SCHEME_WILDCARD, + Pattern("www.example.com").GetScheme()); + EXPECT_EQ(ContentSettingsPattern::SCHEME_OTHER, + Pattern("filesystem:http://www.google.com/temporary/").GetScheme()); } \ No newline at end of file
diff --git a/components/crash/content/browser/crash_dump_manager_android.cc b/components/crash/content/browser/crash_dump_manager_android.cc index 1a618ff20..0d9c0aa 100644 --- a/components/crash/content/browser/crash_dump_manager_android.cc +++ b/components/crash/content/browser/crash_dump_manager_android.cc
@@ -77,7 +77,8 @@ { base::AutoLock auto_lock(child_process_id_to_minidump_path_lock_); - DCHECK(!ContainsKey(child_process_id_to_minidump_path_, child_process_id)); + DCHECK(!base::ContainsKey(child_process_id_to_minidump_path_, + child_process_id)); child_process_id_to_minidump_path_[child_process_id] = minidump_path; } return minidump_file;
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn index 4298e99..8534e6bdb 100644 --- a/components/cronet/android/BUILD.gn +++ b/components/cronet/android/BUILD.gn
@@ -30,6 +30,12 @@ jni_package = "cronet" } +java_cpp_enum("effective_connection_type_java") { + sources = [ + "//net/nqe/effective_connection_type.h", + ] +} + java_cpp_enum("chromium_url_request_java") { sources = [ "chromium_url_request.h", @@ -60,7 +66,10 @@ deps = [ "//third_party/android_tools:android_support_annotations_java", ] - srcjar_deps = [ ":url_request_error_java" ] + srcjar_deps = [ + ":effective_connection_type_java", + ":url_request_error_java", + ] } java_cpp_enum("http_cache_type_java") { @@ -305,6 +314,7 @@ srcjar_deps = [ ":cronet_api_version_srcjar", + ":effective_connection_type_java", ":http_cache_type_java", ":url_request_error_java", ":load_states_list",
diff --git a/components/cronet/android/api/src/org/chromium/net/CronetEngine.java b/components/cronet/android/api/src/org/chromium/net/CronetEngine.java index 221f002..bfaaacc 100644 --- a/components/cronet/android/api/src/org/chromium/net/CronetEngine.java +++ b/components/cronet/android/api/src/org/chromium/net/CronetEngine.java
@@ -914,12 +914,33 @@ * exists, it is truncated before starting. If actively logging, * this method is ignored. * @param logAll {@code true} to include basic events, user cookies, - * credentials and all transferred bytes in the log. + * credentials and all transferred bytes in the log. This option presents + * a privacy risk, since it exposes the user's credentials, and should + * only be used with the user's consent and in situations where the log + * won't be public. * {@code false} to just include basic events. */ public abstract void startNetLogToFile(String fileName, boolean logAll); /** + * Starts NetLog logging to a specified directory with a bounded size. The NetLog will contain + * events emitted by all live CronetEngines. The NetLog is useful for debugging. + * The log can be viewed by stitching the files using net/log/stitch_net_log_files.py and + * using a Chrome browser navigated to chrome://net-internals/#import + * @param dirPath the directory where the log files will be created. It must already exist. + * NetLog files must not already exist in the directory. If actively logging, + * this method is ignored. + * @param logAll {@code true} to include basic events, user cookies, + * credentials and all transferred bytes in the log. This option presents a + * privacy risk, since it exposes the user's credentials, and should only be + * used with the user's consent and in situations where the log won't be public. + * {@code false} to just include basic events. + * @param maxSize the maximum total disk space in bytes that should be used by NetLog. Actual + * disk space usage may exceed this limit slightly. + */ + public abstract void startNetLogToDisk(String dirPath, boolean logAll, int maxSize); + + /** * Stops NetLog logging and flushes file to disk. If a logging session is * not in progress, this call is ignored. */ @@ -963,6 +984,13 @@ public abstract byte[] getGlobalMetricsDeltas(); /** + * Returns the effective connection type computed by the network quality + * estimator. + * @hide as it's a prototype. + */ + public abstract int getEffectiveConnectionType(); + + /** * Configures the network quality estimator for testing. This must be called * before round trip time and throughput listeners are added, and after the * network quality estimator has been enabled.
diff --git a/components/cronet/android/api/src/org/chromium/net/JavaCronetEngine.java b/components/cronet/android/api/src/org/chromium/net/JavaCronetEngine.java index d899a6ac4..d1155030 100644 --- a/components/cronet/android/api/src/org/chromium/net/JavaCronetEngine.java +++ b/components/cronet/android/api/src/org/chromium/net/JavaCronetEngine.java
@@ -91,6 +91,9 @@ public void startNetLogToFile(String fileName, boolean logAll) {} @Override + public void startNetLogToDisk(String dirPath, boolean logAll, int maxSize) {} + + @Override public void stopNetLog() {} @Override @@ -104,6 +107,11 @@ } @Override + public int getEffectiveConnectionType() { + return EffectiveConnectionType.EFFECTIVE_CONNECTION_TYPE_UNKNOWN; + } + + @Override public void configureNetworkQualityEstimatorForTesting( boolean useLocalHostRequests, boolean useSmallerResponses) {}
diff --git a/components/cronet/android/cronet_url_request_context_adapter.cc b/components/cronet/android/cronet_url_request_context_adapter.cc index b189fc40..82e574d 100644 --- a/components/cronet/android/cronet_url_request_context_adapter.cc +++ b/components/cronet/android/cronet_url_request_context_adapter.cc
@@ -16,6 +16,7 @@ #include "base/android/jni_string.h" #include "base/base64.h" #include "base/bind.h" +#include "base/callback.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/files/scoped_file.h" @@ -25,6 +26,7 @@ #include "base/memory/ptr_util.h" #include "base/memory/scoped_vector.h" #include "base/message_loop/message_loop.h" +#include "base/metrics/histogram_macros.h" #include "base/metrics/statistics_recorder.h" #include "base/single_thread_task_runner.h" #include "base/time/time.h" @@ -49,9 +51,9 @@ #include "net/cookies/cookie_monster.h" #include "net/http/http_auth_handler_factory.h" #include "net/http/http_server_properties_manager.h" +#include "net/log/bounded_file_net_log_observer.h" #include "net/log/write_to_file_net_log_observer.h" #include "net/nqe/external_estimate_provider.h" -#include "net/nqe/network_quality_estimator.h" #include "net/proxy/proxy_config_service_android.h" #include "net/proxy/proxy_service.h" #include "net/sdch/sdch_owner.h" @@ -69,6 +71,9 @@ namespace { +// Always split NetLog events into 10 files. +const int kNumNetLogEventFiles = 10; + // This class wraps a NetLog that also contains network change events. class NetLogWithNetworkChangeEvents { public: @@ -419,8 +424,10 @@ if (network_quality_estimator_) { network_quality_estimator_->RemoveRTTObserver(this); network_quality_estimator_->RemoveThroughputObserver(this); + network_quality_estimator_->RemoveEffectiveConnectionTypeObserver(this); } - // Stop |write_to_file_observer_| if there is one. + + // Stop NetLog observer if there is one. StopNetLogHelper(); } @@ -600,13 +607,23 @@ if (config->enable_network_quality_estimator) { DCHECK(!network_quality_estimator_); + std::map<std::string, std::string> variation_params; + // Configure network quality estimator: Specify the algorithm that should + // be used for computing the effective connection type. The algorithm + // is specified using the key-value pairs defined in + // //net/nqe/network_quality_estimator.cc. + // TODO(tbansal): Investigate a more robust way of configuring the network + // quality estimator. + variation_params["effective_connection_type_algorithm"] = + "TransportRTTOrDownstreamThroughput"; network_quality_estimator_.reset(new net::NetworkQualityEstimator( - std::unique_ptr<net::ExternalEstimateProvider>(), - std::map<std::string, std::string>(), false, false)); + std::unique_ptr<net::ExternalEstimateProvider>(), variation_params, + false, false)); // Set the socket performance watcher factory so that network quality // estimator is notified of socket performance metrics from TCP and QUIC. context_builder.set_socket_performance_watcher_factory( network_quality_estimator_->GetSocketPerformanceWatcherFactory()); + network_quality_estimator_->AddEffectiveConnectionTypeObserver(this); } context_ = context_builder.Build(); @@ -669,6 +686,7 @@ // If there is a cert_verifier, then populate its cache with // |cert_verifier_data|. if (!config->cert_verifier_data.empty() && context_->cert_verifier()) { + SCOPED_UMA_HISTOGRAM_TIMER("Net.Cronet.CertVerifierCache.DeserializeTime"); std::string data; cronet_pb::CertVerificationCache cert_verification_cache; if (base::Base64Decode(config->cert_verifier_data, &data) && @@ -783,6 +801,21 @@ /*constants=*/nullptr, /*url_request_context=*/nullptr); } +void CronetURLRequestContextAdapter::StartNetLogToDisk( + JNIEnv* env, + const JavaParamRef<jobject>& jcaller, + const JavaParamRef<jstring>& jdir_name, + jboolean jlog_all, + jint jmax_size) { + PostTaskToNetworkThread( + FROM_HERE, + base::Bind(&CronetURLRequestContextAdapter:: + StartNetLogToBoundedFileOnNetworkThread, + base::Unretained(this), + base::android::ConvertJavaStringToUTF8(env, jdir_name), + jlog_all, jmax_size)); +} + void CronetURLRequestContextAdapter::StopNetLog( JNIEnv* env, const JavaParamRef<jobject>& jcaller) { @@ -803,6 +836,7 @@ DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread()); std::string encoded_data; if (is_context_initialized_ && context_->cert_verifier()) { + SCOPED_UMA_HISTOGRAM_TIMER("Net.Cronet.CertVerifierCache.SerializeTime"); std::string data; cronet_pb::CertVerificationCache cert_cache = SerializeCertVerifierCache(*reinterpret_cast<net::CachingCertVerifier*>( @@ -825,6 +859,14 @@ return file_thread_.get(); } +void CronetURLRequestContextAdapter::OnEffectiveConnectionTypeChanged( + net::EffectiveConnectionType effective_connection_type) { + DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread()); + Java_CronetUrlRequestContext_onEffectiveConnectionTypeChanged( + base::android::AttachCurrentThread(), jcronet_url_request_context_.obj(), + effective_connection_type); +} + void CronetURLRequestContextAdapter::OnRTTObservation( int32_t rtt_ms, const base::TimeTicks& timestamp, @@ -845,11 +887,57 @@ (timestamp - base::TimeTicks::UnixEpoch()).InMilliseconds(), source); } +void CronetURLRequestContextAdapter::StartNetLogToBoundedFileOnNetworkThread( + const std::string& dir_path, + bool include_socket_bytes, + int size) { + DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread()); + + // Do nothing if already logging to a directory. + if (bounded_file_observer_) + return; + + // Filepath for NetLog files must exist and be writable. + base::FilePath file_path(dir_path); + DCHECK(base::PathIsWritable(file_path)); + + bounded_file_observer_.reset( + new net::BoundedFileNetLogObserver(GetFileThread()->task_runner())); + if (include_socket_bytes) { + bounded_file_observer_->set_capture_mode( + net::NetLogCaptureMode::IncludeSocketBytes()); + } + + bounded_file_observer_->StartObserving(g_net_log.Get().net_log(), file_path, + /*constants=*/nullptr, context_.get(), + size, kNumNetLogEventFiles); +} + +void CronetURLRequestContextAdapter::StopBoundedFileNetLogOnNetworkThread() { + DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread()); + bounded_file_observer_->StopObserving( + context_.get(), + base::Bind(&CronetURLRequestContextAdapter::StopNetLogCompleted, + base::Unretained(this))); + bounded_file_observer_.reset(); +} + +void CronetURLRequestContextAdapter::StopNetLogCompleted() { + Java_CronetUrlRequestContext_stopNetLogCompleted( + base::android::AttachCurrentThread(), jcronet_url_request_context_.obj()); +} + void CronetURLRequestContextAdapter::StopNetLogHelper() { base::AutoLock lock(write_to_file_observer_lock_); + DCHECK(!(write_to_file_observer_ && bounded_file_observer_)); if (write_to_file_observer_) { write_to_file_observer_->StopObserving(/*url_request_context=*/nullptr); write_to_file_observer_.reset(); + } else if (bounded_file_observer_) { + PostTaskToNetworkThread(FROM_HERE, + base::Bind(&CronetURLRequestContextAdapter:: + StopBoundedFileNetLogOnNetworkThread, + base::Unretained(this))); } }
diff --git a/components/cronet/android/cronet_url_request_context_adapter.h b/components/cronet/android/cronet_url_request_context_adapter.h index 42626a3f..901f26c6 100644 --- a/components/cronet/android/cronet_url_request_context_adapter.h +++ b/components/cronet/android/cronet_url_request_context_adapter.h
@@ -18,6 +18,7 @@ #include "base/memory/ref_counted.h" #include "base/threading/thread.h" #include "components/prefs/json_pref_store.h" +#include "net/nqe/effective_connection_type.h" #include "net/nqe/network_quality_estimator.h" #include "net/nqe/network_quality_observation_source.h" @@ -35,6 +36,7 @@ class SdchOwner; class URLRequestContext; class WriteToFileNetLogObserver; +class BoundedFileNetLogObserver; } // namespace net namespace cronet { @@ -49,7 +51,8 @@ // Adapter between Java CronetUrlRequestContext and net::URLRequestContext. class CronetURLRequestContextAdapter - : public net::NetworkQualityEstimator::RTTObserver, + : public net::NetworkQualityEstimator::EffectiveConnectionTypeObserver, + public net::NetworkQualityEstimator::RTTObserver, public net::NetworkQualityEstimator::ThroughputObserver { public: explicit CronetURLRequestContextAdapter( @@ -82,6 +85,14 @@ const base::android::JavaParamRef<jstring>& jfile_name, jboolean jlog_all); + // Starts NetLog logging to disk with a bounded amount of disk space. This + // can be called on any thread. + void StartNetLogToDisk(JNIEnv* env, + const base::android::JavaParamRef<jobject>& jcaller, + const base::android::JavaParamRef<jstring>& jdir_name, + jboolean jlog_all, + jint jmax_size); + // Stops NetLog logging to file. This can be called on any thread. This will // flush any remaining writes to disk. void StopNetLog(JNIEnv* env, @@ -149,6 +160,11 @@ void ProvideRTTObservationsOnNetworkThread(bool should); void ProvideThroughputObservationsOnNetworkThread(bool should); + // net::NetworkQualityEstimator::EffectiveConnectionTypeObserver + // implementation. + void OnEffectiveConnectionTypeChanged( + net::EffectiveConnectionType effective_connection_type) override; + // net::NetworkQualityEstimator::RTTObserver implementation. void OnRTTObservation(int32_t rtt_ms, const base::TimeTicks& timestamp, @@ -160,6 +176,19 @@ const base::TimeTicks& timestamp, net::NetworkQualityObservationSource source) override; + // Same as StartNetLogToDisk, but called only on the network thread. + void StartNetLogToBoundedFileOnNetworkThread(const std::string& dir_path, + bool include_socket_bytes, + int size); + + // Stops NetLog logging to file by calling StopObserving() and destroying + // the |bounded_file_observer_|. + void StopBoundedFileNetLogOnNetworkThread(); + + // Callback for StopObserving() that unblocks the Java ConditionVariable and + // signals that it is safe to access the NetLog files. + void StopNetLogCompleted(); + // Helper method to stop NetLog logging to file. This can be called on any // thread. This will flush any remaining writes to disk. void StopNetLogHelper(); @@ -175,6 +204,8 @@ std::unique_ptr<net::WriteToFileNetLogObserver> write_to_file_observer_; base::Lock write_to_file_observer_lock_; + std::unique_ptr<net::BoundedFileNetLogObserver> bounded_file_observer_; + // |pref_service_| should outlive the HttpServerPropertiesManager owned by // |context_|. std::unique_ptr<PrefService> pref_service_;
diff --git a/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java b/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java index 47d4345..893cf259 100644 --- a/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java +++ b/components/cronet/android/java/src/org/chromium/net/impl/CronetUrlRequestContext.java
@@ -20,6 +20,7 @@ import org.chromium.base.annotations.UsedByReflection; import org.chromium.net.BidirectionalStream; import org.chromium.net.CronetEngine; +import org.chromium.net.EffectiveConnectionType; import org.chromium.net.NetworkQualityRttListener; import org.chromium.net.NetworkQualityThroughputListener; import org.chromium.net.RequestFinishedInfo; @@ -77,6 +78,14 @@ */ private final Object mFinishedListenerLock = new Object(); + /** + * Current effective connection type as computed by the network quality + * estimator. + */ + @GuardedBy("mNetworkQualityLock") + private int mEffectiveConnectionType = + EffectiveConnectionType.EFFECTIVE_CONNECTION_TYPE_UNKNOWN; + @GuardedBy("mNetworkQualityLock") private final ObserverList<NetworkQualityRttListener> mRttListenerList = new ObserverList<NetworkQualityRttListener>(); @@ -97,6 +106,21 @@ /** Holds CertVerifier data. */ private String mCertVerifierData; + private ConditionVariable mStopNetLogCompleted; + + /** + * True if a NetLog observer is active. + */ + @GuardedBy("mLock") + private boolean mIsLogging; + + /** + * True if a NetLog observer that writes to disk with a bounded amount of space has been + * activated by calling StartNetLogToDisk(). + */ + @GuardedBy("mLock") + private boolean mNetLogToDisk; + @UsedByReflection("CronetEngine.java") public CronetUrlRequestContext(final CronetEngine.Builder builder) { CronetLibraryLoader.ensureInitialized(builder.getContext(), builder); @@ -211,6 +235,9 @@ // so other thread could access it). mInitCompleted.block(); + // If not logging, this is a no-op. + stopNetLog(); + synchronized (mLock) { // It is possible that adapter is already destroyed on another thread. if (!haveRequestContextAdapter()) { @@ -226,15 +253,43 @@ synchronized (mLock) { checkHaveAdapter(); nativeStartNetLogToFile(mUrlRequestContextAdapter, fileName, logAll); + mIsLogging = true; + } + } + + @Override + public void startNetLogToDisk(String dirPath, boolean logAll, int maxSize) { + synchronized (mLock) { + checkHaveAdapter(); + nativeStartNetLogToDisk(mUrlRequestContextAdapter, dirPath, logAll, maxSize); + mIsLogging = true; + mNetLogToDisk = true; } } @Override public void stopNetLog() { synchronized (mLock) { + if (!mIsLogging) { + return; + } checkHaveAdapter(); nativeStopNetLog(mUrlRequestContextAdapter); + mIsLogging = false; + if (!mNetLogToDisk) { + return; + } + mStopNetLogCompleted = new ConditionVariable(); } + mStopNetLogCompleted.block(); + } + + @CalledByNative + public void stopNetLogCompleted() { + synchronized (mLock) { + mNetLogToDisk = false; + } + mStopNetLogCompleted.open(); } @Override @@ -260,6 +315,17 @@ return nativeGetHistogramDeltas(); } + @Override + public int getEffectiveConnectionType() { + if (!mNetworkQualityEstimatorEnabled) { + throw new IllegalStateException("Network quality estimator must be enabled"); + } + synchronized (mNetworkQualityLock) { + checkHaveAdapter(); + return mEffectiveConnectionType; + } + } + @VisibleForTesting @Override public void configureNetworkQualityEstimatorForTesting( @@ -437,6 +503,16 @@ @SuppressWarnings("unused") @CalledByNative + private void onEffectiveConnectionTypeChanged(int effectiveConnectionType) { + synchronized (mNetworkQualityLock) { + // Convert the enum returned by the network quality estimator to an enum of type + // EffectiveConnectionType. + mEffectiveConnectionType = effectiveConnectionType; + } + } + + @SuppressWarnings("unused") + @CalledByNative private void onRttObservation(final int rttMs, final long whenMs, final int source) { synchronized (mNetworkQualityLock) { for (final NetworkQualityRttListener listener : mRttListenerList) { @@ -530,6 +606,10 @@ private native void nativeStartNetLogToFile(long nativePtr, String fileName, boolean logAll); @NativeClassQualifiedName("CronetURLRequestContextAdapter") + private native void nativeStartNetLogToDisk( + long nativePtr, String dirPath, boolean logAll, int maxSize); + + @NativeClassQualifiedName("CronetURLRequestContextAdapter") private native void nativeStopNetLog(long nativePtr); @NativeClassQualifiedName("CronetURLRequestContextAdapter")
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamTest.java index 2cef0df..2f435fbc 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/BidirectionalStreamTest.java
@@ -868,8 +868,7 @@ @SmallTest @Feature({"Cronet"}) @OnlyRunNativeCronet - // Disabled due to timeout. See crbug.com/591112 - @DisabledTest + @DisabledTest(message = "Disabled due to timeout. See crbug.com/591112") public void testReadAndWrite() throws Exception { String url = Http2TestServer.getEchoStreamUrl(); TestBidirectionalStreamCallback callback = new TestBidirectionalStreamCallback() {
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java index b9eeef9..5e0cdda 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestContextTest.java
@@ -12,10 +12,10 @@ import android.os.StrictMode; import android.test.suitebuilder.annotation.SmallTest; +import org.chromium.base.FileUtils; import org.chromium.base.PathUtils; import org.chromium.base.annotations.JNINamespace; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.net.TestUrlRequestCallback.ResponseStep; import org.chromium.net.impl.CronetLibraryLoader; import org.chromium.net.impl.CronetUrlRequestContext; @@ -41,6 +41,8 @@ "http://mock.failed.request/-2"; private static final String MOCK_CRONET_TEST_SUCCESS_URL = "http://mock.http/success.txt"; + private static final int MAX_FILE_SIZE = 1000000000; + private static final int NUM_EVENT_FILES = 10; private EmbeddedTestServer mTestServer; private String mUrl; @@ -326,17 +328,16 @@ assertEquals(mNetworkQualityThread, rttListener.getThread()); assertEquals(mNetworkQualityThread, throughputListener.getThread()); + // Verify that effective connection type callback is received and + // effective connection type is correctly set. + assertTrue(mTestFramework.mCronetEngine.getEffectiveConnectionType() + != EffectiveConnectionType.EFFECTIVE_CONNECTION_TYPE_UNKNOWN); + mTestFramework.mCronetEngine.shutdown(); } - - - /** @SmallTest @Feature({"Cronet"}) - https://crbug.com/596929 - */ - @FlakyTest public void testShutdown() throws Exception { mTestFramework = startCronetTestFramework(); TestUrlRequestCallback callback = new ShutdownTestUrlRequestCallback(); @@ -385,6 +386,7 @@ @SmallTest @Feature({"Cronet"}) + @OnlyRunNativeCronet public void testShutdownDuringInit() throws Exception { final CronetTestFramework testFramework = startCronetTestFrameworkAndSkipLibraryInit(); final ConditionVariable block = new ConditionVariable(false); @@ -408,7 +410,8 @@ // Create new request context, but its initialization on the main thread // will be stuck behind blockingTask. - final CronetEngine cronetEngine = testFramework.initCronetEngine(); + final CronetUrlRequestContext cronetEngine = + (CronetUrlRequestContext) testFramework.initCronetEngine(); // Unblock the main thread, so context gets initialized and shutdown on // it. block.open(); @@ -416,7 +419,7 @@ cronetEngine.shutdown(); // Verify that context is shutdown. try { - cronetEngine.stopNetLog(); + cronetEngine.getUrlRequestContextAdapter(); fail("Should throw an exception."); } catch (Exception e) { assertEquals("Engine is shut down.", e.getMessage()); @@ -425,6 +428,7 @@ @SmallTest @Feature({"Cronet"}) + @OnlyRunNativeCronet public void testInitAndShutdownOnMainThread() throws Exception { final CronetTestFramework testFramework = startCronetTestFrameworkAndSkipLibraryInit(); final ConditionVariable block = new ConditionVariable(false); @@ -434,12 +438,13 @@ @Override public void run() { // Create new request context, loading the library. - final CronetEngine cronetEngine = testFramework.initCronetEngine(); + final CronetUrlRequestContext cronetEngine = + (CronetUrlRequestContext) testFramework.initCronetEngine(); // Shutdown right after init. cronetEngine.shutdown(); // Verify that context is shutdown. try { - cronetEngine.stopNetLog(); + cronetEngine.getUrlRequestContextAdapter(); fail("Should throw an exception."); } catch (Exception e) { assertEquals("Engine is shut down.", e.getMessage()); @@ -465,11 +470,8 @@ } } - /* @SmallTest @Feature({"Cronet"}) - */ - @FlakyTest(message = "https://crbug.com/592444") public void testShutdownAfterError() throws Exception { mTestFramework = startCronetTestFramework(); TestUrlRequestCallback callback = new ShutdownTestUrlRequestCallback(); @@ -536,6 +538,37 @@ @SmallTest @Feature({"Cronet"}) @OnlyRunNativeCronet // No netlogs for pure java impl + public void testBoundedFileNetLog() throws Exception { + Context context = getContext(); + File directory = new File(PathUtils.getDataDirectory(context)); + File netLogDir = new File(directory, "NetLog"); + assertFalse(netLogDir.exists()); + assertTrue(netLogDir.mkdir()); + File eventFile = new File(netLogDir, "event_file_0.json"); + CronetEngine cronetEngine = new CronetUrlRequestContext( + new CronetEngine.Builder(context).setLibraryName("cronet_tests")); + // Start NetLog immediately after the request context is created to make + // sure that the call won't crash the app even when the native request + // context is not fully initialized. See crbug.com/470196. + cronetEngine.startNetLogToDisk(netLogDir.getPath(), false, MAX_FILE_SIZE); + + // Start a request. + TestUrlRequestCallback callback = new TestUrlRequestCallback(); + UrlRequest.Builder urlRequestBuilder = + new UrlRequest.Builder(mUrl, callback, callback.getExecutor(), cronetEngine); + urlRequestBuilder.build().start(); + callback.blockForDone(); + cronetEngine.stopNetLog(); + assertTrue(eventFile.exists()); + assertTrue(eventFile.length() != 0); + assertFalse(hasBytesInNetLog(eventFile)); + FileUtils.recursivelyDeleteFile(netLogDir); + assertFalse(netLogDir.exists()); + } + + @SmallTest + @Feature({"Cronet"}) + @OnlyRunNativeCronet // No netlogs for pure java impl // Tests that if stopNetLog is not explicity called, CronetEngine.shutdown() // will take care of it. crbug.com/623701. public void testNoStopNetLog() throws Exception { @@ -563,6 +596,37 @@ @SmallTest @Feature({"Cronet"}) + @OnlyRunNativeCronet // No netlogs for pure java impl + // Tests that if stopNetLog is not explicity called, CronetEngine.shutdown() + // will take care of it. crbug.com/623701. + public void testNoStopBoundedFileNetLog() throws Exception { + Context context = getContext(); + File directory = new File(PathUtils.getDataDirectory(context)); + File netLogDir = new File(directory, "NetLog"); + assertFalse(netLogDir.exists()); + assertTrue(netLogDir.mkdir()); + File eventFile = new File(netLogDir, "event_file_0.json"); + CronetEngine cronetEngine = new CronetUrlRequestContext( + new CronetEngine.Builder(context).setLibraryName("cronet_tests")); + cronetEngine.startNetLogToDisk(netLogDir.getPath(), false, MAX_FILE_SIZE); + + // Start a request. + TestUrlRequestCallback callback = new TestUrlRequestCallback(); + UrlRequest.Builder urlRequestBuilder = + new UrlRequest.Builder(mUrl, callback, callback.getExecutor(), cronetEngine); + urlRequestBuilder.build().start(); + callback.blockForDone(); + // Shut down the engine without calling stopNetLog. + cronetEngine.shutdown(); + assertTrue(eventFile.exists()); + assertTrue(eventFile.length() != 0); + + FileUtils.recursivelyDeleteFile(netLogDir); + assertFalse(netLogDir.exists()); + } + + @SmallTest + @Feature({"Cronet"}) @OnlyRunNativeCronet // Tests that NetLog contains events emitted by all live CronetEngines. public void testNetLogContainEventsFromAllLiveEngines() throws Exception { @@ -606,6 +670,62 @@ @SmallTest @Feature({"Cronet"}) @OnlyRunNativeCronet + // Tests that NetLog contains events emitted by all live CronetEngines. + public void testBoundedFileNetLogContainEventsFromAllLiveEngines() throws Exception { + Context context = getContext(); + File directory = new File(PathUtils.getDataDirectory(context)); + File netLogDir1 = new File(directory, "NetLog1"); + assertFalse(netLogDir1.exists()); + assertTrue(netLogDir1.mkdir()); + File netLogDir2 = new File(directory, "NetLog2"); + assertFalse(netLogDir2.exists()); + assertTrue(netLogDir2.mkdir()); + File eventFile1 = new File(netLogDir1, "event_file_0.json"); + File eventFile2 = new File(netLogDir2, "event_file_0.json"); + + CronetUrlRequestContext cronetEngine1 = new CronetUrlRequestContext( + new CronetEngine.Builder(context).setLibraryName("cronet_tests")); + CronetUrlRequestContext cronetEngine2 = new CronetUrlRequestContext( + new CronetEngine.Builder(context).setLibraryName("cronet_tests")); + + cronetEngine1.startNetLogToDisk(netLogDir1.getPath(), false, MAX_FILE_SIZE); + cronetEngine2.startNetLogToDisk(netLogDir2.getPath(), false, MAX_FILE_SIZE); + + // Warm CronetEngine and make sure both CronetUrlRequestContexts are + // initialized before testing the logs. + makeRequestAndCheckStatus(cronetEngine1, mUrl, 200); + makeRequestAndCheckStatus(cronetEngine2, mUrl, 200); + + // Use cronetEngine1 to make a request to mUrl404. + makeRequestAndCheckStatus(cronetEngine1, mUrl404, 404); + + // Use cronetEngine2 to make a request to mUrl500. + makeRequestAndCheckStatus(cronetEngine2, mUrl500, 500); + + cronetEngine1.stopNetLog(); + cronetEngine2.stopNetLog(); + + assertTrue(eventFile1.exists()); + assertTrue(eventFile2.exists()); + assertTrue(eventFile1.length() != 0); + assertTrue(eventFile2.length() != 0); + + // Make sure both files contain the two requests made separately using + // different engines. + assertTrue(containsStringInNetLog(eventFile1, mUrl404)); + assertTrue(containsStringInNetLog(eventFile1, mUrl500)); + assertTrue(containsStringInNetLog(eventFile2, mUrl404)); + assertTrue(containsStringInNetLog(eventFile2, mUrl500)); + + FileUtils.recursivelyDeleteFile(netLogDir1); + assertFalse(netLogDir1.exists()); + FileUtils.recursivelyDeleteFile(netLogDir2); + assertFalse(netLogDir2.exists()); + } + + @SmallTest + @Feature({"Cronet"}) + @OnlyRunNativeCronet // Tests that if CronetEngine is shut down when reading from disk cache, // there isn't a crash. See crbug.com/486120. public void testShutDownEngineWhenReadingFromDiskCache() throws Exception { @@ -675,6 +795,35 @@ @SmallTest @Feature({"Cronet"}) + @OnlyRunNativeCronet + public void testBoundedFileNetLogAfterShutdown() throws Exception { + mTestFramework = startCronetTestFramework(); + TestUrlRequestCallback callback = new TestUrlRequestCallback(); + UrlRequest.Builder urlRequestBuilder = new UrlRequest.Builder( + mUrl, callback, callback.getExecutor(), mTestFramework.mCronetEngine); + urlRequestBuilder.build().start(); + callback.blockForDone(); + mTestFramework.mCronetEngine.shutdown(); + + File directory = new File(PathUtils.getDataDirectory(getContext())); + File netLogDir = new File(directory, "NetLog"); + assertFalse(netLogDir.exists()); + assertTrue(netLogDir.mkdir()); + File constantsFile = new File(netLogDir, "constants.json"); + try { + mTestFramework.mCronetEngine.startNetLogToDisk( + netLogDir.getPath(), false, MAX_FILE_SIZE); + fail("Should throw an exception."); + } catch (Exception e) { + assertEquals("Engine is shut down.", e.getMessage()); + } + assertFalse(constantsFile.exists()); + FileUtils.recursivelyDeleteFile(netLogDir); + assertFalse(netLogDir.exists()); + } + + @SmallTest + @Feature({"Cronet"}) public void testNetLogStartMultipleTimes() throws Exception { mTestFramework = startCronetTestFramework(); File directory = new File(PathUtils.getDataDirectory(getContext())); @@ -700,6 +849,35 @@ @SmallTest @Feature({"Cronet"}) + public void testBoundedFileNetLogStartMultipleTimes() throws Exception { + mTestFramework = startCronetTestFramework(); + File directory = new File(PathUtils.getDataDirectory(getContext())); + File netLogDir = new File(directory, "NetLog"); + assertFalse(netLogDir.exists()); + assertTrue(netLogDir.mkdir()); + File eventFile = new File(netLogDir, "event_file_0.json"); + // Start NetLog multiple times. This should be equivalent to starting NetLog + // once. Each subsequent start (without calling stopNetLog) should be a no-op. + mTestFramework.mCronetEngine.startNetLogToDisk(netLogDir.getPath(), false, MAX_FILE_SIZE); + mTestFramework.mCronetEngine.startNetLogToDisk(netLogDir.getPath(), false, MAX_FILE_SIZE); + mTestFramework.mCronetEngine.startNetLogToDisk(netLogDir.getPath(), false, MAX_FILE_SIZE); + mTestFramework.mCronetEngine.startNetLogToDisk(netLogDir.getPath(), false, MAX_FILE_SIZE); + // Start a request. + TestUrlRequestCallback callback = new TestUrlRequestCallback(); + UrlRequest.Builder urlRequestBuilder = new UrlRequest.Builder( + mUrl, callback, callback.getExecutor(), mTestFramework.mCronetEngine); + urlRequestBuilder.build().start(); + callback.blockForDone(); + mTestFramework.mCronetEngine.stopNetLog(); + assertTrue(eventFile.exists()); + assertTrue(eventFile.length() != 0); + assertFalse(hasBytesInNetLog(eventFile)); + FileUtils.recursivelyDeleteFile(netLogDir); + assertFalse(netLogDir.exists()); + } + + @SmallTest + @Feature({"Cronet"}) public void testNetLogStopMultipleTimes() throws Exception { mTestFramework = startCronetTestFramework(); File directory = new File(PathUtils.getDataDirectory(getContext())); @@ -726,6 +904,36 @@ @SmallTest @Feature({"Cronet"}) + public void testBoundedFileNetLogStopMultipleTimes() throws Exception { + mTestFramework = startCronetTestFramework(); + File directory = new File(PathUtils.getDataDirectory(getContext())); + File netLogDir = new File(directory, "NetLog"); + assertFalse(netLogDir.exists()); + assertTrue(netLogDir.mkdir()); + File eventFile = new File(netLogDir, "event_file_0.json"); + mTestFramework.mCronetEngine.startNetLogToDisk(netLogDir.getPath(), false, MAX_FILE_SIZE); + // Start a request. + TestUrlRequestCallback callback = new TestUrlRequestCallback(); + UrlRequest.Builder urlRequestBuilder = new UrlRequest.Builder( + mUrl, callback, callback.getExecutor(), mTestFramework.mCronetEngine); + urlRequestBuilder.build().start(); + callback.blockForDone(); + // Stop NetLog multiple times. This should be equivalent to stopping NetLog once. + // Each subsequent stop (without calling startNetLogToDisk first) should be a no-op. + mTestFramework.mCronetEngine.stopNetLog(); + mTestFramework.mCronetEngine.stopNetLog(); + mTestFramework.mCronetEngine.stopNetLog(); + mTestFramework.mCronetEngine.stopNetLog(); + mTestFramework.mCronetEngine.stopNetLog(); + assertTrue(eventFile.exists()); + assertTrue(eventFile.length() != 0); + assertFalse(hasBytesInNetLog(eventFile)); + FileUtils.recursivelyDeleteFile(netLogDir); + assertFalse(netLogDir.exists()); + } + + @SmallTest + @Feature({"Cronet"}) @OnlyRunNativeCronet public void testNetLogWithBytes() throws Exception { Context context = getContext(); @@ -749,6 +957,35 @@ assertTrue(!file.exists()); } + @SmallTest + @Feature({"Cronet"}) + @OnlyRunNativeCronet + public void testBoundedFileNetLogWithBytes() throws Exception { + Context context = getContext(); + File directory = new File(PathUtils.getDataDirectory(context)); + File netLogDir = new File(directory, "NetLog"); + assertFalse(netLogDir.exists()); + assertTrue(netLogDir.mkdir()); + File eventFile = new File(netLogDir, "event_file_0.json"); + CronetUrlRequestContext cronetEngine = new CronetUrlRequestContext( + new CronetEngine.Builder(context).setLibraryName("cronet_tests")); + // Start NetLog with logAll as true. + cronetEngine.startNetLogToDisk(netLogDir.getPath(), true, MAX_FILE_SIZE); + // Start a request. + TestUrlRequestCallback callback = new TestUrlRequestCallback(); + UrlRequest.Builder urlRequestBuilder = + new UrlRequest.Builder(mUrl, callback, callback.getExecutor(), cronetEngine); + urlRequestBuilder.build().start(); + callback.blockForDone(); + cronetEngine.stopNetLog(); + + assertTrue(eventFile.exists()); + assertTrue(eventFile.length() != 0); + assertTrue(hasBytesInNetLog(eventFile)); + FileUtils.recursivelyDeleteFile(netLogDir); + assertFalse(netLogDir.exists()); + } + private boolean hasBytesInNetLog(File logFile) throws Exception { return containsStringInNetLog(logFile, "\"hex_encoded_bytes\""); }
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java index d5dc3924..85fdfbff 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/CronetUrlRequestTest.java
@@ -10,7 +10,6 @@ import android.util.Log; import org.chromium.base.test.util.Feature; -import org.chromium.base.test.util.FlakyTest; import org.chromium.net.TestUrlRequestCallback.FailureType; import org.chromium.net.TestUrlRequestCallback.ResponseStep; import org.chromium.net.impl.CronetUrlRequest; @@ -1553,11 +1552,8 @@ callback.mOnCanceledCalled); } - /* @SmallTest @Feature({"Cronet"}) - */ - @FlakyTest(message = "https://crbug.com/592444") public void testFailures() throws Exception { throwOrCancel(FailureType.CANCEL_SYNC, ResponseStep.ON_RECEIVED_REDIRECT, false, false);
diff --git a/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java b/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java index 6088f25..3298f00 100644 --- a/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java +++ b/components/cronet/android/test/javatests/src/org/chromium/net/QuicTest.java
@@ -224,6 +224,11 @@ // NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC assertTrue(rttListener.rttObservationCount(2) > 0); + // Verify that effective connection type callback is received and + // effective connection type is correctly set. + assertTrue(mTestFramework.mCronetEngine.getEffectiveConnectionType() + != EffectiveConnectionType.EFFECTIVE_CONNECTION_TYPE_UNKNOWN); + mTestFramework.mCronetEngine.shutdown(); } }
diff --git a/components/cronet/android/test/quic_test_server.cc b/components/cronet/android/test/quic_test_server.cc index cbcf2cc..beb5712 100644 --- a/components/cronet/android/test/quic_test_server.cc +++ b/components/cronet/android/test/quic_test_server.cc
@@ -54,7 +54,7 @@ directory.Append("quic_test.example.com.key.pkcs8"), directory.Append("quic_test.example.com.key.sct"))); g_quic_server = new net::QuicSimpleServer(std::move(proof_source), config, - net::QuicSupportedVersions()); + net::AllSupportedVersions()); // Start listening. int rv = g_quic_server->Listen(
diff --git a/components/cronet/ios/BUILD.gn b/components/cronet/ios/BUILD.gn index 4153445..f360d8b1 100644 --- a/components/cronet/ios/BUILD.gn +++ b/components/cronet/ios/BUILD.gn
@@ -64,7 +64,6 @@ ios_framework_bundle("cronet_framework") { output_name = "Cronet" info_plist_target = ":tweak_cronet_plist" - enable_code_signing = false deps = [ ":cronet_sources", @@ -147,6 +146,10 @@ _license_path = "$_package_dir/LICENSE" script = "//components/cronet/tools/cronet_licenses.py" + inputs = [ + "//build/util/LASTCHANGE", + "//buildtools/$host_os/gn", + ] outputs = [ _license_path, ] @@ -154,6 +157,8 @@ "license", rebase_path(_license_path, root_build_dir), "--gn", + "--gn-path", + rebase_path("//buildtools/$host_os/gn", root_build_dir), ] }
diff --git a/components/cronet/ios/test/quic_test_server.cc b/components/cronet/ios/test/quic_test_server.cc index a54c1c86..8f64c5b7 100644 --- a/components/cronet/ios/test/quic_test_server.cc +++ b/components/cronet/ios/test/quic_test_server.cc
@@ -77,7 +77,7 @@ directory.Append("quic_test.example.com.key.pkcs8"), directory.Append("quic_test.example.com.key.sct"))); g_quic_server = new net::QuicSimpleServer(std::move(proof_source), config, - net::QuicSupportedVersions()); + net::AllSupportedVersions()); // Start listening. int rv = g_quic_server->Listen(
diff --git a/components/cronet/tools/cronet_licenses.py b/components/cronet/tools/cronet_licenses.py index c68933d..19dde63 100755 --- a/components/cronet/tools/cronet_licenses.py +++ b/components/cronet/tools/cronet_licenses.py
@@ -64,15 +64,15 @@ return '\n'.join(content) -def FindThirdPartyDeps(gn_out_dir): +def FindThirdPartyDeps(gn_path, gn_out_dir): # Generate gn project in temp directory and use it to find dependencies. # Current gn directory cannot ba used because gn doesn't allow recursive # invocations due to potential side effects. try: tmp_dir = tempfile.mkdtemp(dir = gn_out_dir) shutil.copy(gn_out_dir + "/args.gn", tmp_dir) - subprocess.check_output(["gn", "gen", tmp_dir]) - gn_deps = subprocess.check_output(["gn", "desc", tmp_dir, \ + subprocess.check_output([gn_path, "gen", tmp_dir]) + gn_deps = subprocess.check_output([gn_path, "desc", tmp_dir, "//net", "deps", "--as=buildfile", "--all"]) finally: if os.path.exists(tmp_dir): @@ -97,15 +97,18 @@ usage='%prog command [options]') parser.add_option('--gn', help='Use gn deps to find third party dependencies', action='store_true') + parser.add_option('--gn-path', default='gn', + help='Path to gn executable (default: %(default)s)') parser.description = (__doc__ + '\nCommands:\n' \ ' license [filename]\n' \ ' Generate Cronet LICENSE to filename or stdout.\n') - (_, args) = parser.parse_args() + (flags, args) = parser.parse_args() + print flags - if _.gn: + if flags.gn: global third_party_dirs - third_party_dirs = FindThirdPartyDeps(os.getcwd()) + third_party_dirs = FindThirdPartyDeps(flags.gn_path, os.getcwd()) if not args: parser.print_help()
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 561204eb..7a3b4b1b 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
@@ -886,9 +886,9 @@ EXPECT_EQ(test.expected_bypass_type, drp_test_context()->io_data()->bypass_stats()->GetBypassType()); // Check the bad proxy list. - EXPECT_EQ( - test.expected_bad_proxy, - ContainsKey(context()->proxy_service()->proxy_retry_info(), kPrimary)); + EXPECT_EQ(test.expected_bad_proxy, + base::ContainsKey(context()->proxy_service()->proxy_retry_info(), + kPrimary)); } }
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 e3f345d5..f48244c 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
@@ -532,9 +532,13 @@ std::string variation_value = variations::GetVariationParamValue( field_trial, "effective_connection_type"); if (!variation_value.empty()) { - lofi_effective_connection_type_threshold_ = - net::NetworkQualityEstimator::GetEffectiveConnectionTypeForName( - variation_value); + bool effective_connection_type_available = + net::GetEffectiveConnectionTypeForName( + variation_value, &lofi_effective_connection_type_threshold_); + DCHECK(effective_connection_type_available); + + // Silence unused variable warning in release builds. + (void)effective_connection_type_available; } else { // Use the default parameters. lofi_effective_connection_type_threshold_ = @@ -774,8 +778,8 @@ params::IsIncludedInLoFiControlFieldTrial()) && !params::IsLoFiSlowConnectionsOnlyViaFlags()); DCHECK_EQ(0, measuring_duration.InMilliseconds() % 1000); - DCHECK( - ContainsValue(GetLofiAccuracyRecordingIntervals(), measuring_duration)); + DCHECK(base::ContainsValue(GetLofiAccuracyRecordingIntervals(), + measuring_duration)); if (network_quality_at_last_query_ == NETWORK_QUALITY_AT_LAST_QUERY_UNKNOWN) return;
diff --git a/components/devtools_discovery/devtools_discovery_manager.cc b/components/devtools_discovery/devtools_discovery_manager.cc index 3c472fa7..e3e7d90 100644 --- a/components/devtools_discovery/devtools_discovery_manager.cc +++ b/components/devtools_discovery/devtools_discovery_manager.cc
@@ -21,7 +21,7 @@ } DevToolsDiscoveryManager::~DevToolsDiscoveryManager() { - STLDeleteElements(&providers_); + base::STLDeleteElements(&providers_); } void DevToolsDiscoveryManager::AddProvider(std::unique_ptr<Provider> provider) {
diff --git a/components/devtools_http_handler/devtools_http_handler.cc b/components/devtools_http_handler/devtools_http_handler.cc index 48f5811..17b9e99 100644 --- a/components/devtools_http_handler/devtools_http_handler.cc +++ b/components/devtools_http_handler/devtools_http_handler.cc
@@ -344,8 +344,8 @@ DevToolsHttpHandler::~DevToolsHttpHandler() { TerminateOnUI(thread_, server_wrapper_, socket_factory_); - STLDeleteValues(&descriptor_map_); - STLDeleteValues(&connection_to_client_); + base::STLDeleteValues(&descriptor_map_); + base::STLDeleteValues(&connection_to_client_); } GURL DevToolsHttpHandler::GetFrontendURL(const std::string& path) { @@ -582,7 +582,7 @@ devtools_discovery::DevToolsDiscoveryManager::GetInstance()-> GetDescriptors(); std::sort(descriptors.begin(), descriptors.end(), TimeComparator); - STLDeleteValues(&descriptor_map_); + base::STLDeleteValues(&descriptor_map_); base::ListValue list_value; for (DevToolsTargetDescriptor* descriptor : descriptors) { descriptor_map_[descriptor->GetId()] = descriptor;
diff --git a/components/domain_reliability/context.cc b/components/domain_reliability/context.cc index 723614a..fc39044b5 100644 --- a/components/domain_reliability/context.cc +++ b/components/domain_reliability/context.cc
@@ -106,7 +106,7 @@ } void DomainReliabilityContext::ClearBeacons() { - STLDeleteElements(&beacons_); + base::STLDeleteElements(&beacons_); beacons_.clear(); uploading_beacons_size_ = 0; } @@ -230,7 +230,7 @@ void DomainReliabilityContext::CommitUpload() { auto begin = beacons_.begin(); auto end = begin + uploading_beacons_size_; - STLDeleteContainerPointers(begin, end); + base::STLDeleteContainerPointers(begin, end); beacons_.erase(begin, end); DCHECK_NE(0u, uploading_beacons_size_); uploading_beacons_size_ = 0;
diff --git a/components/domain_reliability/dispatcher.cc b/components/domain_reliability/dispatcher.cc index c5ca463..3c42a97 100644 --- a/components/domain_reliability/dispatcher.cc +++ b/components/domain_reliability/dispatcher.cc
@@ -47,7 +47,7 @@ DomainReliabilityDispatcher::~DomainReliabilityDispatcher() { // TODO(juliatuttle): STLElementDeleter? - STLDeleteElements(&tasks_); + base::STLDeleteElements(&tasks_); } void DomainReliabilityDispatcher::ScheduleTask(
diff --git a/components/domain_reliability/google_configs_unittest.cc b/components/domain_reliability/google_configs_unittest.cc index a1d215c5..8dfd3b0 100644 --- a/components/domain_reliability/google_configs_unittest.cc +++ b/components/domain_reliability/google_configs_unittest.cc
@@ -15,14 +15,14 @@ TEST(DomainReliabilityGoogleConfigsTest, Enumerate) { ConfigPointerVector configs; - STLElementDeleter<ConfigPointerVector> configs_deleter(&configs); + base::STLElementDeleter<ConfigPointerVector> configs_deleter(&configs); GetAllGoogleConfigs(&configs); } TEST(DomainReliabilityGoogleConfigsTest, ConfigsAreValid) { ConfigPointerVector configs; - STLElementDeleter<ConfigPointerVector> configs_deleter(&configs); + base::STLElementDeleter<ConfigPointerVector> configs_deleter(&configs); GetAllGoogleConfigs(&configs); for (auto* config : configs)
diff --git a/components/domain_reliability/monitor_unittest.cc b/components/domain_reliability/monitor_unittest.cc index 7b1ba3a5..df65d304 100644 --- a/components/domain_reliability/monitor_unittest.cc +++ b/components/domain_reliability/monitor_unittest.cc
@@ -272,7 +272,7 @@ std::vector<DomainReliabilityConfig*> google_configs; GetAllGoogleConfigs(&google_configs); size_t num_google_configs = google_configs.size(); - STLDeleteElements(&google_configs); + base::STLDeleteElements(&google_configs); // The monitor should have contexts for all of the baked-in configs. EXPECT_EQ(num_baked_in_configs + num_google_configs,
diff --git a/components/domain_reliability/uploader.cc b/components/domain_reliability/uploader.cc index 8ed2e0e..a5bfcfb 100644 --- a/components/domain_reliability/uploader.cc +++ b/components/domain_reliability/uploader.cc
@@ -62,8 +62,8 @@ ~DomainReliabilityUploaderImpl() override { // Delete any in-flight URLFetchers. - STLDeleteContainerPairFirstPointers( - upload_callbacks_.begin(), upload_callbacks_.end()); + base::STLDeleteContainerPairFirstPointers(upload_callbacks_.begin(), + upload_callbacks_.end()); } // DomainReliabilityUploader implementation:
diff --git a/components/drive/chromeos/directory_loader.cc b/components/drive/chromeos/directory_loader.cc index 17acdd2..224b9f1 100644 --- a/components/drive/chromeos/directory_loader.cc +++ b/components/drive/chromeos/directory_loader.cc
@@ -209,7 +209,7 @@ } DirectoryLoader::~DirectoryLoader() { - STLDeleteElements(&fast_fetch_feed_fetcher_set_); + base::STLDeleteElements(&fast_fetch_feed_fetcher_set_); } void DirectoryLoader::AddObserver(ChangeListLoaderObserver* observer) {
diff --git a/components/drive/file_write_watcher.cc b/components/drive/file_write_watcher.cc index e28f3c73..b298adc 100644 --- a/components/drive/file_write_watcher.cc +++ b/components/drive/file_write_watcher.cc
@@ -115,7 +115,8 @@ FileWriteWatcher::FileWriteWatcherImpl::~FileWriteWatcherImpl() { DCHECK(file_task_runner_->BelongsToCurrentThread()); - STLDeleteContainerPairSecondPointers(watchers_.begin(), watchers_.end()); + base::STLDeleteContainerPairSecondPointers(watchers_.begin(), + watchers_.end()); } void FileWriteWatcher::FileWriteWatcherImpl::DestroyOnFileThread() {
diff --git a/components/drive/service/fake_drive_service.cc b/components/drive/service/fake_drive_service.cc index 8cdbf69..c691f1f 100644 --- a/components/drive/service/fake_drive_service.cc +++ b/components/drive/service/fake_drive_service.cc
@@ -252,7 +252,7 @@ FakeDriveService::~FakeDriveService() { DCHECK(thread_checker_.CalledOnValidThread()); - STLDeleteValues(&entries_); + base::STLDeleteValues(&entries_); } bool FakeDriveService::LoadAppListForDriveApi(
diff --git a/components/error_page/common/localized_error.cc b/components/error_page/common/localized_error.cc index fd4be4a..348664a 100644 --- a/components/error_page/common/localized_error.cc +++ b/components/error_page/common/localized_error.cc
@@ -73,7 +73,6 @@ struct LocalizedErrorMap { int error_code; - unsigned int title_resource_id; unsigned int heading_resource_id; // Detailed summary used when the error is in the main frame and shown on // mouse over when the error is in a frame. @@ -84,7 +83,6 @@ const LocalizedErrorMap net_error_options[] = { {net::ERR_TIMED_OUT, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_ERRORPAGES_HEADING_NOT_AVAILABLE, IDS_ERRORPAGES_SUMMARY_TIMED_OUT, SUGGEST_CHECK_CONNECTION | SUGGEST_FIREWALL_CONFIG | SUGGEST_PROXY_CONFIG | @@ -92,7 +90,6 @@ SHOW_BUTTON_RELOAD, }, {net::ERR_CONNECTION_TIMED_OUT, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_ERRORPAGES_HEADING_NOT_AVAILABLE, IDS_ERRORPAGES_SUMMARY_TIMED_OUT, SUGGEST_CHECK_CONNECTION | SUGGEST_FIREWALL_CONFIG | SUGGEST_PROXY_CONFIG | @@ -100,7 +97,6 @@ SHOW_BUTTON_RELOAD, }, {net::ERR_CONNECTION_CLOSED, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_ERRORPAGES_HEADING_NOT_AVAILABLE, IDS_ERRORPAGES_SUMMARY_CONNECTION_CLOSED, SUGGEST_CHECK_CONNECTION | SUGGEST_FIREWALL_CONFIG | SUGGEST_PROXY_CONFIG | @@ -108,7 +104,6 @@ SHOW_BUTTON_RELOAD, }, {net::ERR_CONNECTION_RESET, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_ERRORPAGES_HEADING_NOT_AVAILABLE, IDS_ERRORPAGES_SUMMARY_CONNECTION_RESET, SUGGEST_CHECK_CONNECTION | SUGGEST_FIREWALL_CONFIG | SUGGEST_PROXY_CONFIG | @@ -116,21 +111,18 @@ SHOW_BUTTON_RELOAD, }, {net::ERR_CONNECTION_REFUSED, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_ERRORPAGES_HEADING_NOT_AVAILABLE, IDS_ERRORPAGES_SUMMARY_CONNECTION_REFUSED, SUGGEST_CHECK_CONNECTION | SUGGEST_FIREWALL_CONFIG | SUGGEST_PROXY_CONFIG, SHOW_BUTTON_RELOAD, }, {net::ERR_CONNECTION_FAILED, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_ERRORPAGES_HEADING_NOT_AVAILABLE, IDS_ERRORPAGES_SUMMARY_CONNECTION_FAILED, SUGGEST_DIAGNOSE_TOOL, SHOW_BUTTON_RELOAD, }, {net::ERR_NAME_NOT_RESOLVED, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_ERRORPAGES_HEADING_NOT_AVAILABLE, IDS_ERRORPAGES_SUMMARY_NAME_NOT_RESOLVED, SUGGEST_CHECK_CONNECTION | SUGGEST_DNS_CONFIG | SUGGEST_FIREWALL_CONFIG | @@ -138,21 +130,18 @@ SHOW_BUTTON_RELOAD, }, {net::ERR_ICANN_NAME_COLLISION, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_ERRORPAGES_HEADING_NOT_AVAILABLE, IDS_ERRORPAGES_SUMMARY_ICANN_NAME_COLLISION, SUGGEST_NONE, SHOW_NO_BUTTONS, }, {net::ERR_ADDRESS_UNREACHABLE, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_ERRORPAGES_HEADING_NOT_AVAILABLE, IDS_ERRORPAGES_SUMMARY_ADDRESS_UNREACHABLE, SUGGEST_DIAGNOSE_TOOL, SHOW_BUTTON_RELOAD, }, {net::ERR_NETWORK_ACCESS_DENIED, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_ERRORPAGES_HEADING_NETWORK_ACCESS_DENIED, IDS_ERRORPAGES_SUMMARY_NETWORK_ACCESS_DENIED, SUGGEST_CHECK_CONNECTION | SUGGEST_FIREWALL_CONFIG | @@ -160,196 +149,168 @@ SHOW_NO_BUTTONS, }, {net::ERR_PROXY_CONNECTION_FAILED, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_ERRORPAGES_HEADING_INTERNET_DISCONNECTED, IDS_ERRORPAGES_SUMMARY_PROXY_CONNECTION_FAILED, SUGGEST_PROXY_CONFIG | SUGGEST_CONTACT_ADMINISTRATOR | SUGGEST_DIAGNOSE_TOOL, SHOW_NO_BUTTONS, }, {net::ERR_INTERNET_DISCONNECTED, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_ERRORPAGES_HEADING_INTERNET_DISCONNECTED, IDS_ERRORPAGES_HEADING_INTERNET_DISCONNECTED, SUGGEST_OFFLINE_CHECKS | SUGGEST_DIAGNOSE_TOOL, SHOW_NO_BUTTONS, }, {net::ERR_FILE_NOT_FOUND, - IDS_ERRORPAGES_TITLE_LOAD_FAILED, IDS_ERRORPAGES_HEADING_FILE_NOT_FOUND, IDS_ERRORPAGES_SUMMARY_FILE_NOT_FOUND, SUGGEST_NONE, SHOW_NO_BUTTONS, }, {net::ERR_CACHE_MISS, - IDS_ERRORPAGES_TITLE_LOAD_FAILED, IDS_ERRORPAGES_HEADING_CACHE_READ_FAILURE, IDS_ERRORPAGES_SUMMARY_CACHE_READ_FAILURE, SUGGEST_NONE, SHOW_BUTTON_RELOAD, }, {net::ERR_CACHE_READ_FAILURE, - IDS_ERRORPAGES_TITLE_LOAD_FAILED, IDS_ERRORPAGES_HEADING_CACHE_READ_FAILURE, IDS_ERRORPAGES_SUMMARY_CACHE_READ_FAILURE, SUGGEST_NONE, SHOW_BUTTON_RELOAD, }, {net::ERR_NETWORK_IO_SUSPENDED, - IDS_ERRORPAGES_TITLE_LOAD_FAILED, IDS_ERRORPAGES_HEADING_CONNECTION_INTERRUPTED, IDS_ERRORPAGES_SUMMARY_NETWORK_IO_SUSPENDED, SUGGEST_NONE, SHOW_BUTTON_RELOAD, }, {net::ERR_TOO_MANY_REDIRECTS, - IDS_ERRORPAGES_TITLE_LOAD_FAILED, IDS_ERRORPAGES_HEADING_PAGE_NOT_WORKING, IDS_ERRORPAGES_SUMMARY_TOO_MANY_REDIRECTS, SUGGEST_LEARNMORE, SHOW_BUTTON_RELOAD, }, {net::ERR_EMPTY_RESPONSE, - IDS_ERRORPAGES_TITLE_LOAD_FAILED, IDS_ERRORPAGES_HEADING_PAGE_NOT_WORKING, IDS_ERRORPAGES_SUMMARY_EMPTY_RESPONSE, SUGGEST_NONE, SHOW_BUTTON_RELOAD, }, {net::ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, - IDS_ERRORPAGES_TITLE_LOAD_FAILED, IDS_ERRORPAGES_HEADING_PAGE_NOT_WORKING, IDS_ERRORPAGES_SUMMARY_INVALID_RESPONSE, SUGGEST_NONE, SHOW_BUTTON_RELOAD, }, {net::ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, - IDS_ERRORPAGES_TITLE_LOAD_FAILED, IDS_ERRORPAGES_HEADING_PAGE_NOT_WORKING, IDS_ERRORPAGES_SUMMARY_INVALID_RESPONSE, SUGGEST_NONE, SHOW_BUTTON_RELOAD, }, {net::ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, - IDS_ERRORPAGES_TITLE_LOAD_FAILED, IDS_ERRORPAGES_HEADING_PAGE_NOT_WORKING, IDS_ERRORPAGES_SUMMARY_INVALID_RESPONSE, SUGGEST_NONE, SHOW_BUTTON_RELOAD, }, {net::ERR_INVALID_HTTP_RESPONSE, - IDS_ERRORPAGES_TITLE_LOAD_FAILED, IDS_ERRORPAGES_HEADING_PAGE_NOT_WORKING, IDS_ERRORPAGES_SUMMARY_INVALID_RESPONSE, SUGGEST_NONE, SHOW_BUTTON_RELOAD, }, {net::ERR_CONTENT_LENGTH_MISMATCH, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_ERRORPAGES_HEADING_PAGE_NOT_WORKING, IDS_ERRORPAGES_SUMMARY_CONNECTION_CLOSED, SUGGEST_NONE, SHOW_BUTTON_RELOAD, }, {net::ERR_INCOMPLETE_CHUNKED_ENCODING, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_ERRORPAGES_HEADING_PAGE_NOT_WORKING, IDS_ERRORPAGES_SUMMARY_CONNECTION_CLOSED, SUGGEST_NONE, SHOW_BUTTON_RELOAD, }, {net::ERR_SSL_PROTOCOL_ERROR, - IDS_ERRORPAGES_TITLE_LOAD_FAILED, IDS_ERRORPAGES_HEADING_INSECURE_CONNECTION, IDS_ERRORPAGES_SUMMARY_INVALID_RESPONSE, SUGGEST_DIAGNOSE_TOOL, SHOW_BUTTON_RELOAD, }, {net::ERR_BAD_SSL_CLIENT_AUTH_CERT, - IDS_ERRORPAGES_TITLE_LOAD_FAILED, IDS_ERRORPAGES_HEADING_INSECURE_CONNECTION, IDS_ERRORPAGES_SUMMARY_BAD_SSL_CLIENT_AUTH_CERT, SUGGEST_CONTACT_ADMINISTRATOR, SHOW_NO_BUTTONS, }, {net::ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY, - IDS_ERRORPAGES_TITLE_LOAD_FAILED, IDS_ERRORPAGES_HEADING_INSECURE_CONNECTION, IDS_ERRORPAGES_SUMMARY_SSL_SECURITY_ERROR, SUGGEST_LEARNMORE, SHOW_NO_BUTTONS, }, {net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN, - IDS_ERRORPAGES_TITLE_LOAD_FAILED, IDS_ERRORPAGES_HEADING_INSECURE_CONNECTION, IDS_CERT_ERROR_SUMMARY_PINNING_FAILURE_DETAILS, SUGGEST_NONE, SHOW_NO_BUTTONS, }, {net::ERR_TEMPORARILY_THROTTLED, - IDS_ERRORPAGES_TITLE_ACCESS_DENIED, IDS_ERRORPAGES_HEADING_NOT_AVAILABLE, IDS_ERRORPAGES_SUMMARY_NOT_AVAILABLE, SUGGEST_DISABLE_EXTENSION, SHOW_NO_BUTTONS, }, {net::ERR_BLOCKED_BY_CLIENT, - IDS_ERRORPAGES_TITLE_BLOCKED, IDS_ERRORPAGES_HEADING_BLOCKED, IDS_ERRORPAGES_SUMMARY_BLOCKED_BY_EXTENSION, SUGGEST_DISABLE_EXTENSION, SHOW_BUTTON_RELOAD, }, {net::ERR_NETWORK_CHANGED, - IDS_ERRORPAGES_TITLE_LOAD_FAILED, IDS_ERRORPAGES_HEADING_CONNECTION_INTERRUPTED, IDS_ERRORPAGES_SUMMARY_NETWORK_CHANGED, SUGGEST_NONE, SHOW_BUTTON_RELOAD, }, {net::ERR_BLOCKED_BY_ADMINISTRATOR, - IDS_ERRORPAGES_TITLE_BLOCKED, IDS_ERRORPAGES_HEADING_BLOCKED, IDS_ERRORPAGES_SUMMARY_BLOCKED_BY_ADMINISTRATOR, SUGGEST_CONTACT_ADMINISTRATOR, SHOW_NO_BUTTONS, }, {net::ERR_BLOCKED_ENROLLMENT_CHECK_PENDING, - IDS_ERRORPAGES_TITLE_BLOCKED, IDS_ERRORPAGES_HEADING_INTERNET_DISCONNECTED, IDS_ERRORPAGES_SUMMARY_BLOCKED_ENROLLMENT_CHECK_PENDING, SUGGEST_COMPLETE_SETUP, SHOW_NO_BUTTONS, }, {net::ERR_SSL_FALLBACK_BEYOND_MINIMUM_VERSION, - IDS_ERRORPAGES_TITLE_LOAD_FAILED, IDS_ERRORPAGES_HEADING_INSECURE_CONNECTION, IDS_ERRORPAGES_SUMMARY_INVALID_RESPONSE, SUGGEST_NONE, SHOW_NO_BUTTONS, }, {net::ERR_SSL_VERSION_OR_CIPHER_MISMATCH, - IDS_ERRORPAGES_TITLE_LOAD_FAILED, IDS_ERRORPAGES_HEADING_INSECURE_CONNECTION, IDS_ERRORPAGES_SUMMARY_SSL_VERSION_OR_CIPHER_MISMATCH, SUGGEST_UNSUPPORTED_CIPHER, SHOW_NO_BUTTONS, }, {net::ERR_SSL_OBSOLETE_CIPHER, - IDS_ERRORPAGES_TITLE_LOAD_FAILED, IDS_ERRORPAGES_HEADING_INSECURE_CONNECTION, IDS_ERRORPAGES_SUMMARY_SSL_VERSION_OR_CIPHER_MISMATCH, SUGGEST_UNSUPPORTED_CIPHER, SHOW_NO_BUTTONS, }, {net::ERR_TEMPORARY_BACKOFF, - IDS_ERRORPAGES_TITLE_ACCESS_DENIED, IDS_ERRORPAGES_HEADING_ACCESS_DENIED, IDS_ERRORPAGES_SUMMARY_TEMPORARY_BACKOFF, SUGGEST_NONE, SHOW_NO_BUTTONS, }, {net::ERR_SSL_SERVER_CERT_BAD_FORMAT, - IDS_ERRORPAGES_TITLE_LOAD_FAILED, IDS_ERRORPAGES_HEADING_INSECURE_CONNECTION, IDS_ERRORPAGES_SUMMARY_SSL_SECURITY_ERROR, SUGGEST_NONE, @@ -362,7 +323,6 @@ // to also appear in the array above. const LocalizedErrorMap repost_error = { net::ERR_CACHE_MISS, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_HTTP_POST_WARNING_TITLE, IDS_ERRORPAGES_HTTP_POST_WARNING, SUGGEST_REPOST_RELOAD, @@ -371,46 +331,40 @@ const LocalizedErrorMap http_error_options[] = { { - 403, IDS_ERRORPAGES_TITLE_ACCESS_DENIED, - IDS_ERRORPAGES_HEADING_ACCESS_DENIED, IDS_ERRORPAGES_SUMMARY_FORBIDDEN, + 403, IDS_ERRORPAGES_HEADING_ACCESS_DENIED, + IDS_ERRORPAGES_SUMMARY_FORBIDDEN, SUGGEST_NONE, SHOW_BUTTON_RELOAD, + }, + { + 404, IDS_ERRORPAGES_HEADING_NOT_FOUND, IDS_ERRORPAGES_SUMMARY_NOT_FOUND, SUGGEST_NONE, SHOW_BUTTON_RELOAD, }, { - 404, IDS_ERRORPAGES_TITLE_NOT_FOUND, IDS_ERRORPAGES_HEADING_NOT_FOUND, - IDS_ERRORPAGES_SUMMARY_NOT_FOUND, SUGGEST_NONE, SHOW_BUTTON_RELOAD, - }, - { - 410, IDS_ERRORPAGES_TITLE_NOT_FOUND, IDS_ERRORPAGES_HEADING_NOT_FOUND, - IDS_ERRORPAGES_SUMMARY_GONE, SUGGEST_NONE, SHOW_NO_BUTTONS, + 410, IDS_ERRORPAGES_HEADING_NOT_FOUND, IDS_ERRORPAGES_SUMMARY_GONE, + SUGGEST_NONE, SHOW_NO_BUTTONS, }, { - 500, IDS_ERRORPAGES_TITLE_LOAD_FAILED, - IDS_ERRORPAGES_HEADING_PAGE_NOT_WORKING, + 500, IDS_ERRORPAGES_HEADING_PAGE_NOT_WORKING, IDS_ERRORPAGES_SUMMARY_WEBSITE_CANNOT_HANDLE_REQUEST, SUGGEST_NONE, SHOW_BUTTON_RELOAD, }, { - 501, IDS_ERRORPAGES_TITLE_LOAD_FAILED, - IDS_ERRORPAGES_HEADING_PAGE_NOT_WORKING, + 501, IDS_ERRORPAGES_HEADING_PAGE_NOT_WORKING, IDS_ERRORPAGES_SUMMARY_WEBSITE_CANNOT_HANDLE_REQUEST, SUGGEST_NONE, SHOW_NO_BUTTONS, }, { - 502, IDS_ERRORPAGES_TITLE_LOAD_FAILED, - IDS_ERRORPAGES_HEADING_PAGE_NOT_WORKING, + 502, IDS_ERRORPAGES_HEADING_PAGE_NOT_WORKING, IDS_ERRORPAGES_SUMMARY_WEBSITE_CANNOT_HANDLE_REQUEST, SUGGEST_NONE, SHOW_BUTTON_RELOAD, }, { - 503, IDS_ERRORPAGES_TITLE_LOAD_FAILED, - IDS_ERRORPAGES_HEADING_PAGE_NOT_WORKING, + 503, IDS_ERRORPAGES_HEADING_PAGE_NOT_WORKING, IDS_ERRORPAGES_SUMMARY_WEBSITE_CANNOT_HANDLE_REQUEST, SUGGEST_NONE, SHOW_BUTTON_RELOAD, }, { - 504, IDS_ERRORPAGES_TITLE_LOAD_FAILED, - IDS_ERRORPAGES_HEADING_PAGE_NOT_WORKING, + 504, IDS_ERRORPAGES_HEADING_PAGE_NOT_WORKING, IDS_ERRORPAGES_SUMMARY_GATEWAY_TIMEOUT, SUGGEST_NONE, SHOW_BUTTON_RELOAD, }, @@ -418,7 +372,6 @@ const LocalizedErrorMap dns_probe_error_options[] = { {error_page::DNS_PROBE_POSSIBLE, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_ERRORPAGES_HEADING_NOT_AVAILABLE, IDS_ERRORPAGES_SUMMARY_DNS_PROBE_RUNNING, SUGGEST_DIAGNOSE_TOOL, @@ -429,7 +382,6 @@ // error, which might be one of several DNS-related errors. {error_page::DNS_PROBE_STARTED, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_ERRORPAGES_HEADING_NOT_AVAILABLE, IDS_ERRORPAGES_SUMMARY_DNS_PROBE_RUNNING, // Include SUGGEST_RELOAD so the More button doesn't jump when we update. @@ -441,14 +393,12 @@ // original error, which might be one of several DNS-related errors. {error_page::DNS_PROBE_FINISHED_NO_INTERNET, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_ERRORPAGES_HEADING_INTERNET_DISCONNECTED, IDS_ERRORPAGES_HEADING_INTERNET_DISCONNECTED, SUGGEST_OFFLINE_CHECKS | SUGGEST_DIAGNOSE_TOOL, SHOW_NO_BUTTONS, }, {error_page::DNS_PROBE_FINISHED_BAD_CONFIG, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_ERRORPAGES_HEADING_NOT_AVAILABLE, IDS_ERRORPAGES_SUMMARY_NAME_NOT_RESOLVED, SUGGEST_DNS_CONFIG | SUGGEST_FIREWALL_CONFIG | SUGGEST_PROXY_CONFIG | @@ -456,7 +406,6 @@ SHOW_BUTTON_RELOAD, }, {error_page::DNS_PROBE_FINISHED_NXDOMAIN, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_ERRORPAGES_HEADING_NOT_AVAILABLE, IDS_ERRORPAGES_SUMMARY_NAME_NOT_RESOLVED, SUGGEST_DIAGNOSE_TOOL, @@ -880,7 +829,6 @@ // options with default values. LocalizedErrorMap options = { 0, - IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, IDS_ERRORPAGES_HEADING_NOT_AVAILABLE, IDS_ERRORPAGES_SUMMARY_NOT_AVAILABLE, SUGGEST_NONE, @@ -899,7 +847,6 @@ if (error_domain == net::kErrorDomain && error_code == net::ERR_ACCESS_DENIED && failed_url.scheme() == "file") { - options.title_resource_id = IDS_ERRORPAGES_TITLE_ACCESS_DENIED; options.heading_resource_id = IDS_ERRORPAGES_HEADING_FILE_ACCESS_DENIED; options.summary_resource_id = IDS_ERRORPAGES_SUMMARY_FILE_ACCESS_DENIED; options.suggestions = SUGGEST_NONE; @@ -912,12 +859,15 @@ // URLs are always LTR. if (base::i18n::IsRTL()) base::i18n::WrapStringWithLTRFormatting(&failed_url_string); - error_strings->SetString("title", - l10n_util::GetStringFUTF16(options.title_resource_id, failed_url_string)); - std::string icon_class = GetIconClassForError(error_domain, error_code); - error_strings->SetString("iconClass", icon_class); base::string16 host_name(url_formatter::IDNToUnicode(failed_url.host())); + if (failed_url.SchemeIsHTTPOrHTTPS()) + error_strings->SetString("title", host_name); + else + error_strings->SetString("title", failed_url_string); + + std::string icon_class = GetIconClassForError(error_domain, error_code); + error_strings->SetString("iconClass", icon_class); base::DictionaryValue* heading = new base::DictionaryValue; heading->SetString("msg",
diff --git a/components/error_page_strings.grdp b/components/error_page_strings.grdp index ac0cad9..6272ced 100644 --- a/components/error_page_strings.grdp +++ b/components/error_page_strings.grdp
@@ -98,21 +98,6 @@ <message name="IDS_ERRORPAGES_SUGGESTION_UNSUPPORTED_CIPHER_BODY" desc="The detailed explanation body text displayed for SSL cipher and version errors."> The client and server don't support a common SSL protocol version or cipher suite. </message> - <message name="IDS_ERRORPAGES_TITLE_NOT_AVAILABLE" desc="Title of the error page when we can't connect to a site."> - <ph name="SITE">$1<ex>google.com</ex></ph> is not available - </message> - <message name="IDS_ERRORPAGES_TITLE_ACCESS_DENIED" desc="Title in the error page when a server returns a 403. Also suitable for similar error codes."> - Access to <ph name="URL">$1<ex>http://www.google.com/foo/bar</ex></ph> denied. - </message> - <message name="IDS_ERRORPAGES_TITLE_NOT_FOUND" desc="Title of the error page when the server returns a 404 or 410."> - <ph name="URL">$1<ex>http://www.google.com/foo/bar</ex></ph> is not found - </message> - <message name="IDS_ERRORPAGES_TITLE_LOAD_FAILED" desc="Title of the error page when we can't load a page."> - <ph name="URL">$1<ex>http://some-unreliable-site.com/</ex></ph> failed to load - </message> - <message name="IDS_ERRORPAGES_TITLE_BLOCKED" desc="Title in the error page when a request is blocked (e.g. by an extension)."> - <ph name="URL">$1<ex>http://www.google.com/foo/bar</ex></ph> was blocked - </message> <message name="IDS_ERRORPAGES_HEADING_NOT_AVAILABLE" desc="Heading in the error page when we can't connect to a site."> This site can’t be reached </message>
diff --git a/components/exo/BUILD.gn b/components/exo/BUILD.gn index fbc866c..c770897 100644 --- a/components/exo/BUILD.gn +++ b/components/exo/BUILD.gn
@@ -84,12 +84,11 @@ testonly = true sources = [ - # Disable tests - they are flaky: crbug.com/630625 - # "buffer_unittest.cc", - # "display_unittest.cc", - # "gamepad_unittest.cc", - # "keyboard_unittest.cc", - # "pointer_unittest.cc", + "buffer_unittest.cc", + "display_unittest.cc", + "gamepad_unittest.cc", + "keyboard_unittest.cc", + "pointer_unittest.cc", "shared_memory_unittest.cc", "shell_surface_unittest.cc", "sub_surface_unittest.cc",
diff --git a/components/exo/buffer.cc b/components/exo/buffer.cc index 03e2ddb..7ec46c5 100644 --- a/components/exo/buffer.cc +++ b/components/exo/buffer.cc
@@ -91,14 +91,19 @@ // Buffer::Texture // Encapsulates the state and logic needed to bind a buffer to a GLES2 texture. -class Buffer::Texture { +class Buffer::Texture : public ui::ContextFactoryObserver { public: - explicit Texture(cc::ContextProvider* context_provider); - Texture(cc::ContextProvider* context_provider, + Texture(ui::ContextFactory* context_factory, + cc::ContextProvider* context_provider); + Texture(ui::ContextFactory* context_factory, + cc::ContextProvider* context_provider, gfx::GpuMemoryBuffer* gpu_memory_buffer, unsigned texture_target, unsigned query_type); - ~Texture(); + ~Texture() override; + + // Overridden from ui::ContextFactoryObserver: + void OnLostResources() override; // Returns true if GLES2 resources for texture have been lost. bool IsLost(); @@ -130,11 +135,13 @@ gpu::Mailbox mailbox() const { return mailbox_; } private: + void DestroyResources(); void ReleaseWhenQueryResultIsAvailable(const base::Closure& callback); void Released(); void ScheduleWaitForRelease(base::TimeDelta delay); void WaitForRelease(); + ui::ContextFactory* context_factory_; scoped_refptr<cc::ContextProvider> context_provider_; const unsigned texture_target_; const unsigned query_type_; @@ -151,8 +158,10 @@ DISALLOW_COPY_AND_ASSIGN(Texture); }; -Buffer::Texture::Texture(cc::ContextProvider* context_provider) - : context_provider_(context_provider), +Buffer::Texture::Texture(ui::ContextFactory* context_factory, + cc::ContextProvider* context_provider) + : context_factory_(context_factory), + context_provider_(context_provider), texture_target_(GL_TEXTURE_2D), query_type_(GL_COMMANDS_COMPLETED_CHROMIUM), internalformat_(GL_RGBA), @@ -161,13 +170,17 @@ texture_id_ = CreateGLTexture(gles2, texture_target_); // Generate a crypto-secure random mailbox name. CreateGLTextureMailbox(gles2, texture_id_, texture_target_, &mailbox_); + // Provides a notification when |context_provider_| is lost. + context_factory_->AddObserver(this); } -Buffer::Texture::Texture(cc::ContextProvider* context_provider, +Buffer::Texture::Texture(ui::ContextFactory* context_factory, + cc::ContextProvider* context_provider, gfx::GpuMemoryBuffer* gpu_memory_buffer, unsigned texture_target, unsigned query_type) - : context_provider_(context_provider), + : context_factory_(context_factory), + context_provider_(context_provider), texture_target_(texture_target), query_type_(query_type), internalformat_(GLInternalFormat(gpu_memory_buffer->GetFormat())), @@ -181,28 +194,36 @@ gles2->GenQueriesEXT(1, &query_id_); texture_id_ = CreateGLTexture(gles2, texture_target_); + // Provides a notification when |context_provider_| is lost. + context_factory_->AddObserver(this); } Buffer::Texture::~Texture() { - gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); - gles2->DeleteTextures(1, &texture_id_); - if (query_id_) - gles2->DeleteQueriesEXT(1, &query_id_); - if (image_id_) - gles2->DestroyImageCHROMIUM(image_id_); + DestroyResources(); + context_factory_->RemoveObserver(this); +} + +void Buffer::Texture::OnLostResources() { + DestroyResources(); + context_provider_ = nullptr; } bool Buffer::Texture::IsLost() { - gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); - return gles2->GetGraphicsResetStatusKHR() != GL_NO_ERROR; + if (context_provider_) { + gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); + return gles2->GetGraphicsResetStatusKHR() != GL_NO_ERROR; + } + return true; } void Buffer::Texture::Release(const base::Closure& callback, const gpu::SyncToken& sync_token, bool is_lost) { - gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); - if (sync_token.HasData()) - gles2->WaitSyncTokenCHROMIUM(sync_token.GetConstData()); + if (context_provider_) { + gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); + if (sync_token.HasData()) + gles2->WaitSyncTokenCHROMIUM(sync_token.GetConstData()); + } // Run callback as texture can be reused immediately after waiting for sync // token. @@ -210,75 +231,93 @@ } gpu::SyncToken Buffer::Texture::BindTexImage() { - gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); - gles2->ActiveTexture(GL_TEXTURE0); - gles2->BindTexture(texture_target_, texture_id_); - DCHECK_NE(image_id_, 0u); - gles2->BindTexImage2DCHROMIUM(texture_target_, image_id_); - // Generate a crypto-secure random mailbox name if not already done. - if (mailbox_.IsZero()) - CreateGLTextureMailbox(gles2, texture_id_, texture_target_, &mailbox_); - // Create and return a sync token that can be used to ensure that the - // BindTexImage2DCHROMIUM call is processed before issuing any commands - // that will read from the texture on a different context. - uint64_t fence_sync = gles2->InsertFenceSyncCHROMIUM(); - gles2->OrderingBarrierCHROMIUM(); gpu::SyncToken sync_token; - gles2->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData()); + if (context_provider_) { + gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); + gles2->ActiveTexture(GL_TEXTURE0); + gles2->BindTexture(texture_target_, texture_id_); + DCHECK_NE(image_id_, 0u); + gles2->BindTexImage2DCHROMIUM(texture_target_, image_id_); + // Generate a crypto-secure random mailbox name if not already done. + if (mailbox_.IsZero()) + CreateGLTextureMailbox(gles2, texture_id_, texture_target_, &mailbox_); + // Create and return a sync token that can be used to ensure that the + // BindTexImage2DCHROMIUM call is processed before issuing any commands + // that will read from the texture on a different context. + uint64_t fence_sync = gles2->InsertFenceSyncCHROMIUM(); + gles2->OrderingBarrierCHROMIUM(); + gles2->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData()); + } return sync_token; } void Buffer::Texture::ReleaseTexImage(const base::Closure& callback, const gpu::SyncToken& sync_token, bool is_lost) { - gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); - if (sync_token.HasData()) - gles2->WaitSyncTokenCHROMIUM(sync_token.GetConstData()); - gles2->ActiveTexture(GL_TEXTURE0); - gles2->BindTexture(texture_target_, texture_id_); - DCHECK_NE(query_id_, 0u); - gles2->BeginQueryEXT(query_type_, query_id_); - gles2->ReleaseTexImage2DCHROMIUM(texture_target_, image_id_); - gles2->EndQueryEXT(query_type_); - // Run callback when query result is available and ReleaseTexImage has been - // handled if sync token has data and buffer has been used. If buffer was - // never used then run the callback immediately. - if (sync_token.HasData()) { - ReleaseWhenQueryResultIsAvailable(callback); - } else { - callback.Run(); + if (context_provider_) { + gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); + if (sync_token.HasData()) + gles2->WaitSyncTokenCHROMIUM(sync_token.GetConstData()); + gles2->ActiveTexture(GL_TEXTURE0); + gles2->BindTexture(texture_target_, texture_id_); + DCHECK_NE(query_id_, 0u); + gles2->BeginQueryEXT(query_type_, query_id_); + gles2->ReleaseTexImage2DCHROMIUM(texture_target_, image_id_); + gles2->EndQueryEXT(query_type_); + // Run callback when query result is available and ReleaseTexImage has been + // handled if sync token has data and buffer has been used. If buffer was + // never used then run the callback immediately. + if (sync_token.HasData()) { + ReleaseWhenQueryResultIsAvailable(callback); + return; + } } + callback.Run(); } gpu::SyncToken Buffer::Texture::CopyTexImage(Texture* destination, const base::Closure& callback) { - gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); - gles2->ActiveTexture(GL_TEXTURE0); - gles2->BindTexture(texture_target_, texture_id_); - DCHECK_NE(image_id_, 0u); - gles2->BindTexImage2DCHROMIUM(texture_target_, image_id_); - gles2->CopyTextureCHROMIUM(texture_id_, destination->texture_id_, - internalformat_, GL_UNSIGNED_BYTE, false, false, - false); - DCHECK_NE(query_id_, 0u); - gles2->BeginQueryEXT(query_type_, query_id_); - gles2->ReleaseTexImage2DCHROMIUM(texture_target_, image_id_); - gles2->EndQueryEXT(query_type_); - // Run callback when query result is available and ReleaseTexImage has been - // handled. - ReleaseWhenQueryResultIsAvailable(callback); - // Create and return a sync token that can be used to ensure that the - // CopyTextureCHROMIUM call is processed before issuing any commands - // that will read from the target texture on a different context. - uint64_t fence_sync = gles2->InsertFenceSyncCHROMIUM(); - gles2->OrderingBarrierCHROMIUM(); gpu::SyncToken sync_token; - gles2->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData()); + if (context_provider_) { + gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); + gles2->ActiveTexture(GL_TEXTURE0); + gles2->BindTexture(texture_target_, texture_id_); + DCHECK_NE(image_id_, 0u); + gles2->BindTexImage2DCHROMIUM(texture_target_, image_id_); + gles2->CopyTextureCHROMIUM(texture_id_, destination->texture_id_, + internalformat_, GL_UNSIGNED_BYTE, false, false, + false); + DCHECK_NE(query_id_, 0u); + gles2->BeginQueryEXT(query_type_, query_id_); + gles2->ReleaseTexImage2DCHROMIUM(texture_target_, image_id_); + gles2->EndQueryEXT(query_type_); + // Run callback when query result is available and ReleaseTexImage has been + // handled. + ReleaseWhenQueryResultIsAvailable(callback); + // Create and return a sync token that can be used to ensure that the + // CopyTextureCHROMIUM call is processed before issuing any commands + // that will read from the target texture on a different context. + uint64_t fence_sync = gles2->InsertFenceSyncCHROMIUM(); + gles2->OrderingBarrierCHROMIUM(); + gles2->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData()); + } return sync_token; } +void Buffer::Texture::DestroyResources() { + if (context_provider_) { + gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); + gles2->DeleteTextures(1, &texture_id_); + if (query_id_) + gles2->DeleteQueriesEXT(1, &query_id_); + if (image_id_) + gles2->DestroyImageCHROMIUM(image_id_); + } +} + void Buffer::Texture::ReleaseWhenQueryResultIsAvailable( const base::Closure& callback) { + DCHECK(context_provider_); DCHECK(release_callback_.is_null()); release_callback_ = callback; base::TimeDelta wait_for_release_delay = @@ -321,7 +360,7 @@ base::Closure callback = base::ResetAndReturn(&release_callback_); - { + if (context_provider_) { TRACE_EVENT0("exo", "Buffer::Texture::WaitForQueryResult"); // We need to wait for the result to be available. Getting the result of @@ -385,11 +424,11 @@ if (texture_ && texture_->IsLost()) texture_.reset(); + ui::ContextFactory* context_factory = + aura::Env::GetInstance()->context_factory(); // Note: This can fail if GPU acceleration has been disabled. scoped_refptr<cc::ContextProvider> context_provider = - aura::Env::GetInstance() - ->context_factory() - ->SharedMainThreadContextProvider(); + context_factory->SharedMainThreadContextProvider(); if (!context_provider) { DLOG(WARNING) << "Failed to acquire a context provider"; Release(); // Decrements the use count @@ -401,8 +440,8 @@ // |texture| using a call to CopyTexImage. if (!contents_texture_) { contents_texture_ = base::WrapUnique( - new Texture(context_provider.get(), gpu_memory_buffer_.get(), - texture_target_, query_type_)); + new Texture(context_factory, context_provider.get(), + gpu_memory_buffer_.get(), texture_target_, query_type_)); } if (use_zero_copy_) { @@ -425,8 +464,10 @@ } // Create a mailbox texture that we copy the buffer contents to. - if (!texture_) - texture_ = base::WrapUnique(new Texture(context_provider.get())); + if (!texture_) { + texture_ = + base::WrapUnique(new Texture(context_factory, context_provider.get())); + } // Copy the contents of |contents_texture| to |texture| and produce a // texture mailbox from the result in |texture|.
diff --git a/components/exo/gamepad.cc b/components/exo/gamepad.cc index b997045d..c7a5f56 100644 --- a/components/exo/gamepad.cc +++ b/components/exo/gamepad.cc
@@ -16,7 +16,8 @@ #include "components/exo/shell_surface.h" #include "components/exo/surface.h" #include "device/gamepad/gamepad_data_fetcher.h" -#include "device/gamepad/gamepad_platform_data_fetcher.h" +#include "device/gamepad/gamepad_pad_state_provider.h" +#include "device/gamepad/gamepad_platform_data_fetcher_linux.h" #include "ui/aura/client/focus_client.h" #include "ui/aura/window.h" @@ -30,7 +31,7 @@ std::unique_ptr<device::GamepadDataFetcher> CreateGamepadPlatformDataFetcher() { return std::unique_ptr<device::GamepadDataFetcher>( - new device::GamepadPlatformDataFetcher()); + new device::GamepadPlatformDataFetcherLinux()); } // Time between gamepad polls in milliseconds. @@ -45,7 +46,8 @@ // This class is reference counted to allow it to shut down safely on the // polling thread even if the Gamepad has been destroyed on the origin thread. class Gamepad::ThreadSafeGamepadChangeFetcher - : public base::RefCountedThreadSafe< + : public device::GamepadPadStateProvider, + public base::RefCountedThreadSafe< Gamepad::ThreadSafeGamepadChangeFetcher> { public: using ProcessGamepadChangesCallback = @@ -74,7 +76,7 @@ private: friend class base::RefCountedThreadSafe<ThreadSafeGamepadChangeFetcher>; - virtual ~ThreadSafeGamepadChangeFetcher() {} + ~ThreadSafeGamepadChangeFetcher() override {} // Enables or disables polling. void EnablePollingOnPollingThread(bool enabled) { @@ -84,6 +86,7 @@ if (is_enabled_) { if (!fetcher_) { fetcher_ = create_fetcher_callback_.Run(); + InitializeDataFetcher(fetcher_.get()); DCHECK(fetcher_); } SchedulePollOnPollingThread(); @@ -119,7 +122,31 @@ DCHECK(fetcher_); blink::WebGamepads new_state = state_; - fetcher_->GetGamepadData(&new_state, false); + fetcher_->GetGamepadData( + false /* No hardware changed notification from the system */); + + new_state.length = 0; + device::PadState& pad_state = pad_states_.get()[0]; + + // After querying the gamepad clear the state if it did not have it's active + // state updated but is still listed as being associated with a specific + // source. This indicates the gamepad is disconnected. + if (!pad_state.active_state && + pad_state.source != device::GAMEPAD_SOURCE_NONE) { + ClearPadState(pad_state); + } + + MapAndSanitizeGamepadData(&pad_state, &new_state.items[0], + false /* Don't sanitize gamepad data */); + + // If the gamepad was active then increment the length of the WebGamepads + // struct to indicate it's valid, then set the pad state to inactive. If the + // gamepad is still actively reporting the next call to GetGamepadData will + // set the active state to active again. + if (pad_state.active_state) { + new_state.length++; + pad_state.active_state = device::GAMEPAD_INACTIVE; + } if (std::max(new_state.length, state_.length) > 0) { if (new_state.items[0].connected != state_.items[0].connected ||
diff --git a/components/feedback/feedback_uploader_unittest.cc b/components/feedback/feedback_uploader_unittest.cc index 3736b31..7539e8bd 100644 --- a/components/feedback/feedback_uploader_unittest.cc +++ b/components/feedback/feedback_uploader_unittest.cc
@@ -77,7 +77,7 @@ } void MockDispatchReport(const std::string& report_data) { - if (ContainsKey(dispatched_reports_, report_data)) { + if (base::ContainsKey(dispatched_reports_, report_data)) { dispatched_reports_[report_data]++; } else { dispatched_reports_[report_data] = 1;
diff --git a/components/flags_ui/flags_state.cc b/components/flags_ui/flags_state.cc index c3d992b..e0f1593b 100644 --- a/components/flags_ui/flags_state.cc +++ b/components/flags_ui/flags_state.cc
@@ -404,7 +404,7 @@ // For any featrue name in |features| that is not in |switch_added_values| - // i.e. it wasn't added by about_flags code, add it to |remaining_features|. for (const std::string& feature : features) { - if (!ContainsKey(switch_added_values, feature)) + if (!base::ContainsKey(switch_added_values, feature)) remaining_features.push_back(feature); } @@ -592,7 +592,7 @@ const std::string& switch_name, const std::string& switch_value, std::map<std::string, SwitchEntry>* name_to_switch_map) { - DCHECK(!ContainsKey(*name_to_switch_map, key)); + DCHECK(!base::ContainsKey(*name_to_switch_map, key)); SwitchEntry* entry = &(*name_to_switch_map)[key]; entry->switch_name = switch_name; @@ -604,7 +604,7 @@ const std::string& feature_name, bool feature_state, std::map<std::string, SwitchEntry>* name_to_switch_map) { - DCHECK(!ContainsKey(*name_to_switch_map, key)); + DCHECK(!base::ContainsKey(*name_to_switch_map, key)); SwitchEntry* entry = &(*name_to_switch_map)[key]; entry->feature_name = feature_name; @@ -665,11 +665,11 @@ std::vector<std::string> features = base::FeatureList::SplitFeatureListString(original_switch_value); // Only add features that don't already exist in the lists. - // Note: The ContainsValue() call results in O(n^2) performance, but in + // Note: The base::ContainsValue() call results in O(n^2) performance, but in // practice n should be very small. for (const auto& entry : feature_switches) { if (entry.second == feature_state && - !ContainsValue(features, entry.first)) { + !base::ContainsValue(features, entry.first)) { features.push_back(entry.first); appended_switches_[switch_name].insert(entry.first); }
diff --git a/components/flags_ui/flags_state_unittest.cc b/components/flags_ui/flags_state_unittest.cc index 5c6bbc0a6..5789342 100644 --- a/components/flags_ui/flags_state_unittest.cc +++ b/components/flags_ui/flags_state_unittest.cc
@@ -409,10 +409,10 @@ // This shouldn't do anything before ConvertFlagsToSwitches() wasn't called. flags_state_->RemoveFlagsSwitches(&switch_list); ASSERT_EQ(4u, switch_list.size()); - EXPECT_TRUE(ContainsKey(switch_list, kSwitch1)); - EXPECT_TRUE(ContainsKey(switch_list, switches::kFlagSwitchesBegin)); - EXPECT_TRUE(ContainsKey(switch_list, switches::kFlagSwitchesEnd)); - EXPECT_TRUE(ContainsKey(switch_list, "foo")); + EXPECT_TRUE(base::ContainsKey(switch_list, kSwitch1)); + EXPECT_TRUE(base::ContainsKey(switch_list, switches::kFlagSwitchesBegin)); + EXPECT_TRUE(base::ContainsKey(switch_list, switches::kFlagSwitchesEnd)); + EXPECT_TRUE(base::ContainsKey(switch_list, "foo")); // Call ConvertFlagsToSwitches(), then RemoveFlagsSwitches() again. base::CommandLine command_line(base::CommandLine::NO_PROGRAM); @@ -424,7 +424,7 @@ // Now the about:flags-related switch should have been removed. ASSERT_EQ(1u, switch_list.size()); - EXPECT_TRUE(ContainsKey(switch_list, "foo")); + EXPECT_TRUE(base::ContainsKey(switch_list, "foo")); } TEST_F(FlagsStateTest, RemoveFlagSwitches_Features) { @@ -475,13 +475,13 @@ kDisableFeatures); auto switch_list = command_line.GetSwitches(); EXPECT_EQ(cases[i].expected_enable_features != nullptr, - ContainsKey(switch_list, kEnableFeatures)); + base::ContainsKey(switch_list, kEnableFeatures)); if (cases[i].expected_enable_features) EXPECT_EQ(CreateSwitch(cases[i].expected_enable_features), switch_list[kEnableFeatures]); EXPECT_EQ(cases[i].expected_disable_features != nullptr, - ContainsKey(switch_list, kDisableFeatures)); + base::ContainsKey(switch_list, kDisableFeatures)); if (cases[i].expected_disable_features) EXPECT_EQ(CreateSwitch(cases[i].expected_disable_features), switch_list[kDisableFeatures]); @@ -491,12 +491,12 @@ switch_list = command_line.GetSwitches(); flags_state_->RemoveFlagsSwitches(&switch_list); EXPECT_EQ(cases[i].existing_enable_features != nullptr, - ContainsKey(switch_list, kEnableFeatures)); + base::ContainsKey(switch_list, kEnableFeatures)); if (cases[i].existing_enable_features) EXPECT_EQ(CreateSwitch(cases[i].existing_enable_features), switch_list[kEnableFeatures]); EXPECT_EQ(cases[i].existing_disable_features != nullptr, - ContainsKey(switch_list, kEnableFeatures)); + base::ContainsKey(switch_list, kEnableFeatures)); if (cases[i].existing_disable_features) EXPECT_EQ(CreateSwitch(cases[i].existing_disable_features), switch_list[kDisableFeatures]);
diff --git a/components/gcm_driver.gypi b/components/gcm_driver.gypi index a748645..63e8afd 100644 --- a/components/gcm_driver.gypi +++ b/components/gcm_driver.gypi
@@ -29,11 +29,10 @@ 'gcm_driver_common', 'gcm_driver_crypto', 'os_crypt', - 'sync_driver', '../base/base.gyp:base', '../google_apis/gcm/gcm.gyp:gcm', '../net/net.gyp:net', - '../components/sync.gyp:sync_proto', + '../components/sync.gyp:sync', '../url/url.gyp:url_lib', ], 'include_dirs': [
diff --git a/components/gcm_driver/BUILD.gn b/components/gcm_driver/BUILD.gn index 7f8e34a..db35996 100644 --- a/components/gcm_driver/BUILD.gn +++ b/components/gcm_driver/BUILD.gn
@@ -68,8 +68,7 @@ "//components/pref_registry", "//components/prefs", "//components/signin/core/browser", - "//components/sync/protocol", - "//components/sync_driver", + "//components/sync", "//components/version_info", "//google_apis", "//google_apis/gcm",
diff --git a/components/gcm_driver/DEPS b/components/gcm_driver/DEPS index 274a839..4423dce1 100644 --- a/components/gcm_driver/DEPS +++ b/components/gcm_driver/DEPS
@@ -4,8 +4,8 @@ "+components/pref_registry", "+components/prefs", "+components/signin", + "+components/sync/driver", "+components/sync/protocol", - "+components/sync_driver", "+components/timers", # Only used for Chrome OS builds. "+components/version_info", # TODO(johnme): Fix this layering violation.
diff --git a/components/gcm_driver/gcm_desktop_utils.cc b/components/gcm_driver/gcm_desktop_utils.cc index 332ad32a..bf121079 100644 --- a/components/gcm_driver/gcm_desktop_utils.cc +++ b/components/gcm_driver/gcm_desktop_utils.cc
@@ -13,7 +13,7 @@ #include "components/gcm_driver/gcm_client_factory.h" #include "components/gcm_driver/gcm_driver.h" #include "components/gcm_driver/gcm_driver_desktop.h" -#include "components/sync_driver/sync_util.h" +#include "components/sync/driver/sync_util.h" #include "url/gurl.h" namespace gcm {
diff --git a/components/guest_view/browser/guest_view_manager.cc b/components/guest_view/browser/guest_view_manager.cc index d98ef1ac..1734c76 100644 --- a/components/guest_view/browser/guest_view_manager.cc +++ b/components/guest_view/browser/guest_view_manager.cc
@@ -239,7 +239,8 @@ void GuestViewManager::AddGuest(int guest_instance_id, WebContents* guest_web_contents) { - CHECK(!ContainsKey(guest_web_contents_by_instance_id_, guest_instance_id)); + CHECK(!base::ContainsKey(guest_web_contents_by_instance_id_, + guest_instance_id)); CHECK(CanUseGuestInstanceID(guest_instance_id)); guest_web_contents_by_instance_id_[guest_instance_id] = guest_web_contents; @@ -422,7 +423,7 @@ bool GuestViewManager::CanUseGuestInstanceID(int guest_instance_id) { if (guest_instance_id <= last_instance_id_removed_) return false; - return !ContainsKey(removed_instance_ids_, guest_instance_id); + return !base::ContainsKey(removed_instance_ids_, guest_instance_id); } // static
diff --git a/components/history.gypi b/components/history.gypi index ed624612..52aac08 100644 --- a/components/history.gypi +++ b/components/history.gypi
@@ -29,7 +29,6 @@ 'prefs/prefs.gyp:prefs', 'query_parser', 'signin_core_browser', - 'sync_driver', 'url_formatter/url_formatter.gyp:url_formatter', 'version_info', ],
diff --git a/components/history/DEPS b/components/history/DEPS index c7a89f0..3208ad1 100644 --- a/components/history/DEPS +++ b/components/history/DEPS
@@ -5,7 +5,6 @@ "+components/prefs", "+components/signin/core", "+components/sync", - "+components/sync_driver", "+google_apis/gaia", "+net", "+sql",
diff --git a/components/history/core/browser/BUILD.gn b/components/history/core/browser/BUILD.gn index 32ccb5f..8de0639 100644 --- a/components/history/core/browser/BUILD.gn +++ b/components/history/core/browser/BUILD.gn
@@ -98,7 +98,6 @@ "//components/query_parser", "//components/signin/core/browser", "//components/sync", - "//components/sync_driver", "//components/url_formatter", "//components/version_info", "//google_apis", @@ -207,7 +206,7 @@ "//components/signin/core/browser", "//components/signin/core/browser:test_support", "//components/sync:test_support_sync_api", - "//components/sync_driver:test_support", + "//components/sync:test_support_sync_driver", "//sql", "//sql:test_support", "//testing/gtest",
diff --git a/components/history/core/browser/download_database.cc b/components/history/core/browser/download_database.cc index cf90813..8687d38 100644 --- a/components/history/core/browser/download_database.cc +++ b/components/history/core/browser/download_database.cc
@@ -425,7 +425,7 @@ dropped_reason, DROPPED_REASON_MAX + 1); } else { - DCHECK(!ContainsKey(info_map, info->id)); + DCHECK(!base::ContainsKey(info_map, info->id)); uint32_t id = info->id; info_map[id] = info.release(); } @@ -453,8 +453,8 @@ // Confirm the id has already been seen--if it hasn't, discard the // record. - DCHECK(ContainsKey(info_map, id)); - if (!ContainsKey(info_map, id)) + DCHECK(base::ContainsKey(info_map, id)); + if (!base::ContainsKey(info_map, id)) continue; // Confirm all previous URLs in the chain have already been seen;
diff --git a/components/history/core/browser/history_backend.cc b/components/history/core/browser/history_backend.cc index 5b450209..431eb37 100644 --- a/components/history/core/browser/history_backend.cc +++ b/components/history/core/browser/history_backend.cc
@@ -217,8 +217,8 @@ HistoryBackend::~HistoryBackend() { DCHECK(!scheduled_commit_) << "Deleting without cleanup"; - STLDeleteContainerPointers(queued_history_db_tasks_.begin(), - queued_history_db_tasks_.end()); + base::STLDeleteContainerPointers(queued_history_db_tasks_.begin(), + queued_history_db_tasks_.end()); queued_history_db_tasks_.clear(); // Release stashed embedder object before cleaning up the databases. @@ -2243,8 +2243,8 @@ void HistoryBackend::ProcessDBTaskImpl() { if (!db_) { // db went away, release all the refs. - STLDeleteContainerPointers(queued_history_db_tasks_.begin(), - queued_history_db_tasks_.end()); + base::STLDeleteContainerPointers(queued_history_db_tasks_.begin(), + queued_history_db_tasks_.end()); queued_history_db_tasks_.clear(); return; }
diff --git a/components/history/core/browser/history_delete_directives_data_type_controller.cc b/components/history/core/browser/history_delete_directives_data_type_controller.cc index a2f7f1e..27ff7be 100644 --- a/components/history/core/browser/history_delete_directives_data_type_controller.cc +++ b/components/history/core/browser/history_delete_directives_data_type_controller.cc
@@ -4,8 +4,8 @@ #include "components/history/core/browser/history_delete_directives_data_type_controller.h" -#include "components/sync_driver/sync_client.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_client.h" +#include "components/sync/driver/sync_service.h" namespace browser_sync {
diff --git a/components/history/core/browser/history_delete_directives_data_type_controller.h b/components/history/core/browser/history_delete_directives_data_type_controller.h index 0e79187..3dbec95 100644 --- a/components/history/core/browser/history_delete_directives_data_type_controller.h +++ b/components/history/core/browser/history_delete_directives_data_type_controller.h
@@ -6,9 +6,9 @@ #define COMPONENTS_HISTORY_CORE_BROWSER_HISTORY_DELETE_DIRECTIVES_DATA_TYPE_CONTROLLER_H_ #include "base/macros.h" -#include "components/sync_driver/local_device_info_provider.h" -#include "components/sync_driver/sync_service_observer.h" -#include "components/sync_driver/ui_data_type_controller.h" +#include "components/sync/driver/local_device_info_provider.h" +#include "components/sync/driver/sync_service_observer.h" +#include "components/sync/driver/ui_data_type_controller.h" namespace browser_sync {
diff --git a/components/history/core/browser/typed_url_data_type_controller.cc b/components/history/core/browser/typed_url_data_type_controller.cc index 776e698..1063b54 100644 --- a/components/history/core/browser/typed_url_data_type_controller.cc +++ b/components/history/core/browser/typed_url_data_type_controller.cc
@@ -10,7 +10,7 @@ #include "components/history/core/browser/history_db_task.h" #include "components/history/core/browser/history_service.h" #include "components/prefs/pref_service.h" -#include "components/sync_driver/sync_client.h" +#include "components/sync/driver/sync_client.h" namespace browser_sync {
diff --git a/components/history/core/browser/typed_url_data_type_controller.h b/components/history/core/browser/typed_url_data_type_controller.h index 9e84a35..92dd0276 100644 --- a/components/history/core/browser/typed_url_data_type_controller.h +++ b/components/history/core/browser/typed_url_data_type_controller.h
@@ -12,8 +12,8 @@ #include "base/memory/ref_counted.h" #include "base/task/cancelable_task_tracker.h" #include "components/prefs/pref_change_registrar.h" -#include "components/sync_driver/non_ui_data_type_controller.h" -#include "components/sync_driver/sync_api_component_factory.h" +#include "components/sync/driver/non_ui_data_type_controller.h" +#include "components/sync/driver/sync_api_component_factory.h" namespace history { class HistoryBackend;
diff --git a/components/history/core/browser/visit_tracker.cc b/components/history/core/browser/visit_tracker.cc index fccd2e1..742e8090 100644 --- a/components/history/core/browser/visit_tracker.cc +++ b/components/history/core/browser/visit_tracker.cc
@@ -22,7 +22,8 @@ } VisitTracker::~VisitTracker() { - STLDeleteContainerPairSecondPointers(contexts_.begin(), contexts_.end()); + base::STLDeleteContainerPairSecondPointers(contexts_.begin(), + contexts_.end()); } // This function is potentially slow because it may do up to two brute-force
diff --git a/components/history/core/browser/web_history_service.cc b/components/history/core/browser/web_history_service.cc index eca55b8..3902be39 100644 --- a/components/history/core/browser/web_history_service.cc +++ b/components/history/core/browser/web_history_service.cc
@@ -17,8 +17,8 @@ #include "base/strings/utf_string_conversions.h" #include "base/values.h" #include "components/signin/core/browser/signin_manager.h" +#include "components/sync/driver/sync_util.h" #include "components/sync/protocol/history_status.pb.h" -#include "components/sync_driver/sync_util.h" #include "google_apis/gaia/gaia_urls.h" #include "google_apis/gaia/google_service_auth_error.h" #include "google_apis/gaia/oauth2_token_service.h" @@ -334,10 +334,10 @@ } WebHistoryService::~WebHistoryService() { - STLDeleteElements(&pending_expire_requests_); - STLDeleteElements(&pending_audio_history_requests_); - STLDeleteElements(&pending_web_and_app_activity_requests_); - STLDeleteElements(&pending_other_forms_of_browsing_history_requests_); + base::STLDeleteElements(&pending_expire_requests_); + base::STLDeleteElements(&pending_audio_history_requests_); + base::STLDeleteElements(&pending_web_and_app_activity_requests_); + base::STLDeleteElements(&pending_other_forms_of_browsing_history_requests_); } WebHistoryService::Request* WebHistoryService::CreateRequest(
diff --git a/components/invalidation/impl/registration_manager.cc b/components/invalidation/impl/registration_manager.cc index a48b895a..a2d3c3e 100644 --- a/components/invalidation/impl/registration_manager.cc +++ b/components/invalidation/impl/registration_manager.cc
@@ -65,7 +65,7 @@ RegistrationManager::~RegistrationManager() { DCHECK(CalledOnValidThread()); - STLDeleteValues(®istration_statuses_); + base::STLDeleteValues(®istration_statuses_); } ObjectIdSet RegistrationManager::UpdateRegisteredIds(const ObjectIdSet& ids) { @@ -86,7 +86,7 @@ for (ObjectIdSet::const_iterator it = to_register.begin(); it != to_register.end(); ++it) { - if (!ContainsKey(registration_statuses_, *it)) { + if (!base::ContainsKey(registration_statuses_, *it)) { registration_statuses_.insert( std::make_pair(*it, new RegistrationStatus(*it, this))); }
diff --git a/components/invalidation/impl/registration_manager_unittest.cc b/components/invalidation/impl/registration_manager_unittest.cc index 0ffe843..29d3865 100644 --- a/components/invalidation/impl/registration_manager_unittest.cc +++ b/components/invalidation/impl/registration_manager_unittest.cc
@@ -55,7 +55,7 @@ ~FakeInvalidationClient() override {} void LoseRegistration(const invalidation::ObjectId& oid) { - EXPECT_TRUE(ContainsKey(registered_ids_, oid)); + EXPECT_TRUE(base::ContainsKey(registered_ids_, oid)); registered_ids_.erase(oid); } @@ -70,7 +70,7 @@ void Acknowledge(const invalidation::AckHandle& handle) override {} void Register(const invalidation::ObjectId& oid) override { - EXPECT_FALSE(ContainsKey(registered_ids_, oid)); + EXPECT_FALSE(base::ContainsKey(registered_ids_, oid)); registered_ids_.insert(oid); } @@ -79,7 +79,7 @@ } void Unregister(const invalidation::ObjectId& oid) override { - EXPECT_TRUE(ContainsKey(registered_ids_, oid)); + EXPECT_TRUE(base::ContainsKey(registered_ids_, oid)); registered_ids_.erase(oid); }
diff --git a/components/invalidation/impl/sync_invalidation_listener_unittest.cc b/components/invalidation/impl/sync_invalidation_listener_unittest.cc index dd471da..3701ecd 100644 --- a/components/invalidation/impl/sync_invalidation_listener_unittest.cc +++ b/components/invalidation/impl/sync_invalidation_listener_unittest.cc
@@ -779,18 +779,18 @@ EXPECT_TRUE(GetSavedInvalidations().empty()); FireInvalidate(id, 1, "hello"); EXPECT_EQ(1U, GetSavedInvalidations().size()); - EXPECT_TRUE(ContainsKey(GetSavedInvalidations(), id)); + EXPECT_TRUE(base::ContainsKey(GetSavedInvalidations(), id)); FireInvalidate(kPreferencesId_, 2, "world"); EXPECT_EQ(2U, GetSavedInvalidations().size()); - EXPECT_TRUE(ContainsKey(GetSavedInvalidations(), id)); - EXPECT_TRUE(ContainsKey(GetSavedInvalidations(), kPreferencesId_)); + EXPECT_TRUE(base::ContainsKey(GetSavedInvalidations(), id)); + EXPECT_TRUE(base::ContainsKey(GetSavedInvalidations(), kPreferencesId_)); ObjectIdSet ids; ids.insert(id); listener_.UpdateRegisteredIds(ids); EXPECT_EQ(1U, GetSavedInvalidations().size()); - EXPECT_TRUE(ContainsKey(GetSavedInvalidations(), id)); + EXPECT_TRUE(base::ContainsKey(GetSavedInvalidations(), id)); } TEST_F(SyncInvalidationListenerTest, DuplicateInvaldiations_Simple) {
diff --git a/components/invalidation/impl/sync_system_resources.cc b/components/invalidation/impl/sync_system_resources.cc index 1440dc30..089f7a15 100644 --- a/components/invalidation/impl/sync_system_resources.cc +++ b/components/invalidation/impl/sync_system_resources.cc
@@ -93,7 +93,7 @@ is_stopped_ = true; is_started_ = false; weak_factory_.InvalidateWeakPtrs(); - STLDeleteElements(&posted_tasks_); + base::STLDeleteElements(&posted_tasks_); } void SyncInvalidationScheduler::Schedule(invalidation::TimeDelta delay, @@ -139,7 +139,7 @@ received_messages_count_(0) {} SyncNetworkChannel::~SyncNetworkChannel() { - STLDeleteElements(&network_status_receivers_); + base::STLDeleteElements(&network_status_receivers_); } void SyncNetworkChannel::SetMessageReceiver(
diff --git a/components/keyed_service/core/keyed_service_factory.cc b/components/keyed_service/core/keyed_service_factory.cc index 7fe14077..938ddc5d 100644 --- a/components/keyed_service/core/keyed_service_factory.cc +++ b/components/keyed_service/core/keyed_service_factory.cc
@@ -97,7 +97,7 @@ void KeyedServiceFactory::Associate(base::SupportsUserData* context, std::unique_ptr<KeyedService> service) { - DCHECK(!ContainsKey(mapping_, context)); + DCHECK(!base::ContainsKey(mapping_, context)); mapping_.insert(std::make_pair(context, service.release())); }
diff --git a/components/keyed_service/core/refcounted_keyed_service_factory.cc b/components/keyed_service/core/refcounted_keyed_service_factory.cc index d33340b..7c44c2c 100644 --- a/components/keyed_service/core/refcounted_keyed_service_factory.cc +++ b/components/keyed_service/core/refcounted_keyed_service_factory.cc
@@ -89,7 +89,7 @@ void RefcountedKeyedServiceFactory::Associate( base::SupportsUserData* context, const scoped_refptr<RefcountedKeyedService>& service) { - DCHECK(!ContainsKey(mapping_, context)); + DCHECK(!base::ContainsKey(mapping_, context)); mapping_.insert(std::make_pair(context, service)); }
diff --git a/components/metrics/metrics_state_manager.cc b/components/metrics/metrics_state_manager.cc index cf1b4a12..b470e3d 100644 --- a/components/metrics/metrics_state_manager.cc +++ b/components/metrics/metrics_state_manager.cc
@@ -257,7 +257,11 @@ // The GUID retrieved (and possibly fixed above) should be valid unless // retrieval failed. - DCHECK(!client_info || base::IsValidGUID(client_info->client_id)); + // DCHECK(!client_info || base::IsValidGUID(client_info->client_id)); + // Temporary hack for http://crbug.com/635255. + // TODO(asvitkine): address this the right way. + if (client_info && !base::IsValidGUID(client_info->client_id)) + return nullptr; return client_info; }
diff --git a/components/metrics/profiler/profiler_metrics_provider.cc b/components/metrics/profiler/profiler_metrics_provider.cc index df64e29..2ab8c031 100644 --- a/components/metrics/profiler/profiler_metrics_provider.cc +++ b/components/metrics/profiler/profiler_metrics_provider.cc
@@ -107,7 +107,8 @@ if (IsCellularLogicEnabled()) return; - const bool new_phase = !ContainsKey(profiler_events_cache_, profiling_phase); + const bool new_phase = + !base::ContainsKey(profiler_events_cache_, profiling_phase); ProfilerEventProto* profiler_event = &profiler_events_cache_[profiling_phase]; if (new_phase) {
diff --git a/components/metrics/stability_metrics_helper.cc b/components/metrics/stability_metrics_helper.cc index af7f1b4f..a94563d 100644 --- a/components/metrics/stability_metrics_helper.cc +++ b/components/metrics/stability_metrics_helper.cc
@@ -182,45 +182,63 @@ int exit_code) { int histogram_type = was_extension_process ? RENDERER_TYPE_EXTENSION : RENDERER_TYPE_RENDERER; - if (status == base::TERMINATION_STATUS_PROCESS_CRASHED || - status == base::TERMINATION_STATUS_ABNORMAL_TERMINATION) { - if (was_extension_process) { - IncrementPrefValue(prefs::kStabilityExtensionRendererCrashCount); - UMA_HISTOGRAM_SPARSE_SLOWLY("CrashExitCodes.Extension", - MapCrashExitCodeForHistogram(exit_code)); - } else { - IncrementPrefValue(prefs::kStabilityRendererCrashCount); + switch (status) { + case base::TERMINATION_STATUS_NORMAL_TERMINATION: + break; + case base::TERMINATION_STATUS_PROCESS_CRASHED: + case base::TERMINATION_STATUS_ABNORMAL_TERMINATION: + case base::TERMINATION_STATUS_OOM: + if (was_extension_process) { + IncrementPrefValue(prefs::kStabilityExtensionRendererCrashCount); - UMA_HISTOGRAM_SPARSE_SLOWLY("CrashExitCodes.Renderer", - MapCrashExitCodeForHistogram(exit_code)); - } + UMA_HISTOGRAM_SPARSE_SLOWLY("CrashExitCodes.Extension", + MapCrashExitCodeForHistogram(exit_code)); + } else { + IncrementPrefValue(prefs::kStabilityRendererCrashCount); - UMA_HISTOGRAM_ENUMERATION("BrowserRenderProcessHost.ChildCrashes", - histogram_type, RENDERER_TYPE_COUNT); - } else if (status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED) { - RecordChildKills(histogram_type); -#if defined(OS_CHROMEOS) - } else if (status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM) { - RecordChildKills(histogram_type); - UMA_HISTOGRAM_ENUMERATION("BrowserRenderProcessHost.ChildKills.OOM", - was_extension_process ? 2 : 1, 3); - RecordMemoryStats(was_extension_process - ? RECORD_MEMORY_STATS_EXTENSIONS_OOM_KILLED - : RECORD_MEMORY_STATS_CONTENTS_OOM_KILLED); + UMA_HISTOGRAM_SPARSE_SLOWLY("CrashExitCodes.Renderer", + MapCrashExitCodeForHistogram(exit_code)); + } + + UMA_HISTOGRAM_ENUMERATION("BrowserRenderProcessHost.ChildCrashes", + histogram_type, RENDERER_TYPE_COUNT); + break; + case base::TERMINATION_STATUS_PROCESS_WAS_KILLED: + RecordChildKills(histogram_type); + break; +#if defined(OS_ANDROID) + case base::TERMINATION_STATUS_OOM_PROTECTED: + // TODO(wfh): Check if this should be a Kill or a Crash on Android. + break; #endif - } else if (status == base::TERMINATION_STATUS_STILL_RUNNING) { - UMA_HISTOGRAM_ENUMERATION("BrowserRenderProcessHost.DisconnectedAlive", - histogram_type, RENDERER_TYPE_COUNT); - } else if (status == base::TERMINATION_STATUS_LAUNCH_FAILED) { - UMA_HISTOGRAM_ENUMERATION("BrowserRenderProcessHost.ChildLaunchFailures", - histogram_type, RENDERER_TYPE_COUNT); - UMA_HISTOGRAM_SPARSE_SLOWLY( - "BrowserRenderProcessHost.ChildLaunchFailureCodes", exit_code); - if (was_extension_process) - IncrementPrefValue(prefs::kStabilityExtensionRendererFailedLaunchCount); - else - IncrementPrefValue(prefs::kStabilityRendererFailedLaunchCount); +#if defined(OS_CHROMEOS) + case base::TERMINATION_STATUS_PROCESS_WAS_KILLED_BY_OOM: + RecordChildKills(histogram_type); + UMA_HISTOGRAM_ENUMERATION("BrowserRenderProcessHost.ChildKills.OOM", + was_extension_process ? 2 : 1, 3); + RecordMemoryStats(was_extension_process + ? RECORD_MEMORY_STATS_EXTENSIONS_OOM_KILLED + : RECORD_MEMORY_STATS_CONTENTS_OOM_KILLED); + break; +#endif + case base::TERMINATION_STATUS_STILL_RUNNING: + UMA_HISTOGRAM_ENUMERATION("BrowserRenderProcessHost.DisconnectedAlive", + histogram_type, RENDERER_TYPE_COUNT); + break; + case base::TERMINATION_STATUS_LAUNCH_FAILED: + UMA_HISTOGRAM_ENUMERATION("BrowserRenderProcessHost.ChildLaunchFailures", + histogram_type, RENDERER_TYPE_COUNT); + UMA_HISTOGRAM_SPARSE_SLOWLY( + "BrowserRenderProcessHost.ChildLaunchFailureCodes", exit_code); + if (was_extension_process) + IncrementPrefValue(prefs::kStabilityExtensionRendererFailedLaunchCount); + else + IncrementPrefValue(prefs::kStabilityRendererFailedLaunchCount); + break; + case base::TERMINATION_STATUS_MAX_ENUM: + NOTREACHED(); + break; } }
diff --git a/components/metrics/stability_metrics_helper_unittest.cc b/components/metrics/stability_metrics_helper_unittest.cc index d5aa929..018906d 100644 --- a/components/metrics/stability_metrics_helper_unittest.cc +++ b/components/metrics/stability_metrics_helper_unittest.cc
@@ -5,6 +5,7 @@ #include "components/metrics/stability_metrics_helper.h" #include "base/macros.h" +#include "base/test/histogram_tester.h" #include "components/metrics/proto/system_profile.pb.h" #include "components/prefs/pref_service.h" #include "components/prefs/scoped_user_pref_update.h" @@ -15,6 +16,15 @@ namespace { +enum RendererType { + RENDERER_TYPE_RENDERER = 1, + RENDERER_TYPE_EXTENSION, + // NOTE: Add new action types only immediately above this line. Also, + // make sure the enum list in tools/metrics/histograms/histograms.xml is + // updated with any change in here. + RENDERER_TYPE_COUNT +}; + class StabilityMetricsHelperTest : public testing::Test { protected: StabilityMetricsHelperTest() : prefs_(new TestingPrefServiceSimple) { @@ -52,6 +62,7 @@ TEST_F(StabilityMetricsHelperTest, LogRendererCrash) { StabilityMetricsHelper helper(prefs()); + base::HistogramTester histogram_tester; // Crash and abnormal termination should increment renderer crash count. helper.LogRendererCrash(false, base::TERMINATION_STATUS_PROCESS_CRASHED, 1); @@ -59,6 +70,9 @@ helper.LogRendererCrash(false, base::TERMINATION_STATUS_ABNORMAL_TERMINATION, 1); + // OOM should increment renderer crash count. + helper.LogRendererCrash(false, base::TERMINATION_STATUS_OOM, 1); + // Kill does not increment renderer crash count. helper.LogRendererCrash(false, base::TERMINATION_STATUS_PROCESS_WAS_KILLED, 1); @@ -72,7 +86,7 @@ // be executed immediately. helper.ProvideStabilityMetrics(&system_profile); - EXPECT_EQ(2, system_profile.stability().renderer_crash_count()); + EXPECT_EQ(3, system_profile.stability().renderer_crash_count()); EXPECT_EQ(1, system_profile.stability().renderer_failed_launch_count()); EXPECT_EQ(0, system_profile.stability().extension_renderer_crash_count()); @@ -81,6 +95,9 @@ // Crash and abnormal termination should increment extension crash count. helper.LogRendererCrash(true, base::TERMINATION_STATUS_PROCESS_CRASHED, 1); + // OOM should increment extension renderer crash count. + helper.LogRendererCrash(true, base::TERMINATION_STATUS_OOM, 1); + // Failed launch increments extension failed launch count. helper.LogRendererCrash(true, base::TERMINATION_STATUS_LAUNCH_FAILED, 1); @@ -88,9 +105,36 @@ helper.ProvideStabilityMetrics(&system_profile); EXPECT_EQ(0, system_profile.stability().renderer_crash_count()); - EXPECT_EQ(1, system_profile.stability().extension_renderer_crash_count()); + EXPECT_EQ(2, system_profile.stability().extension_renderer_crash_count()); EXPECT_EQ( 1, system_profile.stability().extension_renderer_failed_launch_count()); + + // TERMINATION_STATUS_PROCESS_CRASHED, TERMINATION_STATUS_ABNORMAL_TERMINATION + // and TERMINATION_STATUS_OOM = 3. + histogram_tester.ExpectUniqueSample("CrashExitCodes.Renderer", 1, 3); + histogram_tester.ExpectBucketCount("BrowserRenderProcessHost.ChildCrashes", + RENDERER_TYPE_RENDERER, 3); + + // TERMINATION_STATUS_PROCESS_CRASHED and TERMINATION_STATUS_OOM = 2. + histogram_tester.ExpectUniqueSample("CrashExitCodes.Extension", 1, 2); + histogram_tester.ExpectBucketCount("BrowserRenderProcessHost.ChildCrashes", + RENDERER_TYPE_EXTENSION, 2); + + // One launch failure each. + histogram_tester.ExpectBucketCount( + "BrowserRenderProcessHost.ChildLaunchFailures", RENDERER_TYPE_RENDERER, + 1); + histogram_tester.ExpectBucketCount( + "BrowserRenderProcessHost.ChildLaunchFailures", RENDERER_TYPE_EXTENSION, + 1); + histogram_tester.ExpectBucketCount( + "BrowserRenderProcessHost.ChildLaunchFailureCodes", 1, 2); + + // TERMINATION_STATUS_PROCESS_WAS_KILLED for a renderer. + histogram_tester.ExpectBucketCount("BrowserRenderProcessHost.ChildKills", + RENDERER_TYPE_RENDERER, 1); + histogram_tester.ExpectBucketCount("BrowserRenderProcessHost.ChildKills", + RENDERER_TYPE_EXTENSION, 0); } } // namespace metrics
diff --git a/components/network_session_configurator/network_session_configurator.cc b/components/network_session_configurator/network_session_configurator.cc index 92630b0..48af1c0d 100644 --- a/components/network_session_configurator/network_session_configurator.cc +++ b/components/network_session_configurator/network_session_configurator.cc
@@ -352,7 +352,7 @@ namespace network_session_configurator { net::QuicVersion ParseQuicVersion(const std::string& quic_version) { - net::QuicVersionVector supported_versions = net::QuicSupportedVersions(); + net::QuicVersionVector supported_versions = net::AllSupportedVersions(); for (size_t i = 0; i < supported_versions.size(); ++i) { net::QuicVersion version = supported_versions[i]; if (net::QuicVersionToString(version) == quic_version) {
diff --git a/components/network_session_configurator/network_session_configurator_unittest.cc b/components/network_session_configurator/network_session_configurator_unittest.cc index 5073805..fe724146 100644 --- a/components/network_session_configurator/network_session_configurator_unittest.cc +++ b/components/network_session_configurator/network_session_configurator_unittest.cc
@@ -199,14 +199,14 @@ TEST_F(NetworkSessionConfiguratorTest, QuicVersionFromFieldTrialParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["quic_version"] = - net::QuicVersionToString(net::QuicSupportedVersions().back()); + net::QuicVersionToString(net::AllSupportedVersions().back()); variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); ParseFieldTrials(); net::QuicVersionVector supported_versions; - supported_versions.push_back(net::QuicSupportedVersions().back()); + supported_versions.push_back(net::AllSupportedVersions().back()); EXPECT_EQ(supported_versions, params_.quic_supported_versions); } @@ -374,8 +374,10 @@ ParseFieldTrials(); EXPECT_EQ(2u, params_.quic_host_whitelist.size()); - EXPECT_TRUE(ContainsKey(params_.quic_host_whitelist, "www.example.org")); - EXPECT_TRUE(ContainsKey(params_.quic_host_whitelist, "www.example.com")); + EXPECT_TRUE( + base::ContainsKey(params_.quic_host_whitelist, "www.example.org")); + EXPECT_TRUE( + base::ContainsKey(params_.quic_host_whitelist, "www.example.com")); } TEST_F(NetworkSessionConfiguratorTest, TCPFastOpenHttpsEnabled) {
diff --git a/components/ntp_snippets.gypi b/components/ntp_snippets.gypi index 27817218..20cbe2398 100644 --- a/components/ntp_snippets.gypi +++ b/components/ntp_snippets.gypi
@@ -27,7 +27,7 @@ 'prefs/prefs.gyp:prefs', 'signin_core_browser', 'suggestions', - 'sync_driver', + 'sync.gyp:sync', 'variations', 'variations_net', ],
diff --git a/components/ntp_snippets/BUILD.gn b/components/ntp_snippets/BUILD.gn index 596b376..7a28656 100644 --- a/components/ntp_snippets/BUILD.gn +++ b/components/ntp_snippets/BUILD.gn
@@ -62,7 +62,7 @@ "//components/prefs", "//components/signin/core/browser", "//components/suggestions", - "//components/sync_driver", + "//components/sync", "//google_apis", "//net", "//url", @@ -117,7 +117,7 @@ "//components/signin/core/browser:test_support", "//components/signin/core/common", "//components/strings", - "//components/sync_driver:test_support", + "//components/sync:test_support_sync_driver", "//components/variations", "//net:test_support", "//testing/gtest",
diff --git a/components/ntp_snippets/DEPS b/components/ntp_snippets/DEPS index 1dd9061..95fd603 100644 --- a/components/ntp_snippets/DEPS +++ b/components/ntp_snippets/DEPS
@@ -7,7 +7,7 @@ "+components/prefs", "+components/signin", "+components/suggestions", - "+components/sync_driver", + "+components/sync/driver", "+components/variations", "+grit/components_strings.h", "+net/base",
diff --git a/components/ntp_snippets/bookmarks/bookmark_last_visit_utils.cc b/components/ntp_snippets/bookmarks/bookmark_last_visit_utils.cc index 77f659d1..5efe847 100644 --- a/components/ntp_snippets/bookmarks/bookmark_last_visit_utils.cc +++ b/components/ntp_snippets/bookmarks/bookmark_last_visit_utils.cc
@@ -61,14 +61,16 @@ std::string last_visit_date_string; node->GetMetaInfo(kBookmarkLastVisitDateKey, &last_visit_date_string); - - // Use creation date if no last visit info present. - if (last_visit_date_string.empty()) - return node->date_added(); - return ParseLastVisitDate(last_visit_date_string); } +base::Time GetLastVisitDateForBookmarkIfNotDismissed(const BookmarkNode* node) { + if (IsDismissedFromNTPForBookmark(node)) + return base::Time::UnixEpoch(); + + return GetLastVisitDateForBookmark(node); +} + void MarkBookmarksDismissed(BookmarkModel* bookmark_model, const GURL& url) { std::vector<const BookmarkNode*> nodes; bookmark_model->GetNodesByURL(url, &nodes); @@ -109,8 +111,8 @@ std::vector<BookmarkModel::URLAndTitle> bookmarks; bookmark_model->GetBookmarks(&bookmarks); - // Remove the bookmark URLs whose bookmarks are all dismissed or whose most - // recent visit is older than |min_visit_time|. + // Remove the URLs for that no bookmark has a recent visit (more recent than + // |min_visit_time|). Recent visits to dismissed bookmarks are not considered. bookmarks.erase( std::remove_if(bookmarks.begin(), bookmarks.end(), [&bookmark_model, &min_visit_time]( @@ -120,17 +122,15 @@ bookmark_model->GetNodesByURL(bookmark.url, &bookmarks_for_url); - // Check if there is a recently visited bookmark and not - // all bookmarks are dismissed. - bool has_recent_visit = false; - bool all_dismissed = true; + // Keep if at least one (non-dismissed) bookmark has been + // recently visited. for (const BookmarkNode* node : bookmarks_for_url) { - if (GetLastVisitDateForBookmark(node) > min_visit_time) - has_recent_visit = true; - if (!IsDismissedFromNTPForBookmark(node)) - all_dismissed = false; + if (GetLastVisitDateForBookmarkIfNotDismissed(node) > + min_visit_time) + return false; } - return all_dismissed || !has_recent_visit; + // Otherwise erase this URL. + return true; }), bookmarks.end());
diff --git a/components/ntp_snippets/bookmarks/bookmark_last_visit_utils.h b/components/ntp_snippets/bookmarks/bookmark_last_visit_utils.h index 36ff7db..01fd935 100644 --- a/components/ntp_snippets/bookmarks/bookmark_last_visit_utils.h +++ b/components/ntp_snippets/bookmarks/bookmark_last_visit_utils.h
@@ -27,10 +27,15 @@ bookmarks::BookmarkModel* bookmark_model, const GURL& url); -// Gets the last visit date for a given bookmark |node|. If the bookmark lacks -// this info, it returns it creation date. +// Gets the last visit date for a given bookmark |node|. The visit when the +// bookmark is created also counts. base::Time GetLastVisitDateForBookmark(const bookmarks::BookmarkNode* node); +// Like GetLastVisitDateForBookmark, but it returns the unix epoch if the +// bookmark is dismissed from NTP. +base::Time GetLastVisitDateForBookmarkIfNotDismissed( + const bookmarks::BookmarkNode* node); + // Marks all bookmarks with the given URL as dismissed. void MarkBookmarksDismissed(bookmarks::BookmarkModel* bookmark_model, const GURL& url);
diff --git a/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc b/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc index f77fcd4..7090d12 100644 --- a/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc +++ b/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.cc
@@ -92,7 +92,7 @@ CategoryInfo BookmarkSuggestionsProvider::GetCategoryInfo(Category category) { return CategoryInfo( l10n_util::GetStringUTF16(IDS_NTP_BOOKMARK_SUGGESTIONS_SECTION_HEADER), - ContentSuggestionsCardLayout::MINIMAL_CARD); + ContentSuggestionsCardLayout::MINIMAL_CARD, /* has_more_button */ true); } void BookmarkSuggestionsProvider::DismissSuggestion( @@ -150,13 +150,14 @@ BookmarkModel* model, const BookmarkNode* node) { // Store the last visit date of the node that is about to change. - node_to_change_last_visit_date_ = GetLastVisitDateForBookmark(node); + node_to_change_last_visit_date_ = + GetLastVisitDateForBookmarkIfNotDismissed(node); } void BookmarkSuggestionsProvider::BookmarkMetaInfoChanged( BookmarkModel* model, const BookmarkNode* node) { - base::Time time = GetLastVisitDateForBookmark(node); + base::Time time = GetLastVisitDateForBookmarkIfNotDismissed(node); if (time == node_to_change_last_visit_date_ || time < end_of_list_last_visit_date_) return; @@ -166,6 +167,20 @@ FetchBookmarks(); } +void BookmarkSuggestionsProvider::BookmarkNodeRemoved( + bookmarks::BookmarkModel* model, + const bookmarks::BookmarkNode* parent, + int old_index, + const bookmarks::BookmarkNode* node, + const std::set<GURL>& no_longer_bookmarked) { + if (GetLastVisitDateForBookmarkIfNotDismissed(node) < + end_of_list_last_visit_date_) + return; + + // Some node from our list got deleted, we should update the suggestions. + FetchBookmarks(); +} + ContentSuggestion BookmarkSuggestionsProvider::ConvertBookmark( const BookmarkNode* bookmark) { ContentSuggestion suggestion(
diff --git a/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h b/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h index 79b723e..1f2aabd 100644 --- a/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h +++ b/components/ntp_snippets/bookmarks/bookmark_suggestions_provider.h
@@ -64,7 +64,7 @@ const bookmarks::BookmarkNode* parent, int old_index, const bookmarks::BookmarkNode* node, - const std::set<GURL>& no_longer_bookmarked) override {} + const std::set<GURL>& no_longer_bookmarked) override; void BookmarkNodeChanged(bookmarks::BookmarkModel* model, const bookmarks::BookmarkNode* node) override {} void BookmarkNodeFaviconChanged(
diff --git a/components/ntp_snippets/category.h b/components/ntp_snippets/category.h index 0991ab2..bd19a15 100644 --- a/components/ntp_snippets/category.h +++ b/components/ntp_snippets/category.h
@@ -19,8 +19,11 @@ // On Android builds, a Java counterpart will be generated for this enum. // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.ntp.snippets enum class KnownCategories { - // Pages downloaded for offline consumption. - OFFLINE_PAGES, + // Pages recently downloaded during normal navigation. + RECENT_TABS, + + // Pages downloaded by the user for offline consumption. + DOWNLOADS, // Recently used bookmarks. BOOKMARKS,
diff --git a/components/ntp_snippets/category_factory.cc b/components/ntp_snippets/category_factory.cc index fc9482cb..5ab6cdb 100644 --- a/components/ntp_snippets/category_factory.cc +++ b/components/ntp_snippets/category_factory.cc
@@ -12,7 +12,8 @@ CategoryFactory::CategoryFactory() { // Add all local categories in a fixed order. - AddKnownCategory(KnownCategories::OFFLINE_PAGES); + AddKnownCategory(KnownCategories::DOWNLOADS); + AddKnownCategory(KnownCategories::RECENT_TABS); AddKnownCategory(KnownCategories::BOOKMARKS); }
diff --git a/components/ntp_snippets/category_info.cc b/components/ntp_snippets/category_info.cc index 213b2fa..9a03caf 100644 --- a/components/ntp_snippets/category_info.cc +++ b/components/ntp_snippets/category_info.cc
@@ -7,8 +7,11 @@ namespace ntp_snippets { CategoryInfo::CategoryInfo(const base::string16& title, - ContentSuggestionsCardLayout card_layout) - : title_(title), card_layout_(card_layout) {} + ContentSuggestionsCardLayout card_layout, + bool has_more_button) + : title_(title), + card_layout_(card_layout), + has_more_button_(has_more_button) {} CategoryInfo::~CategoryInfo() {}
diff --git a/components/ntp_snippets/category_info.h b/components/ntp_snippets/category_info.h index 8ae272e..0187209f 100644 --- a/components/ntp_snippets/category_info.h +++ b/components/ntp_snippets/category_info.h
@@ -24,7 +24,8 @@ class CategoryInfo { public: CategoryInfo(const base::string16& title, - ContentSuggestionsCardLayout card_layout); + ContentSuggestionsCardLayout card_layout, + bool has_more_button); CategoryInfo(CategoryInfo&&) = default; CategoryInfo& operator=(CategoryInfo&&) = default; @@ -36,9 +37,15 @@ // Layout of the cards to be used to display suggestions in this category. ContentSuggestionsCardLayout card_layout() const { return card_layout_; } + // Whether the category supports a "More" button. The button either triggers + // a fixed action (like opening a native page) or, if there is no such fixed + // action, it queries the provider for more suggestions. + bool has_more_button() const { return has_more_button_; } + private: base::string16 title_; ContentSuggestionsCardLayout card_layout_; + bool has_more_button_; DISALLOW_COPY_AND_ASSIGN(CategoryInfo); };
diff --git a/components/ntp_snippets/content_suggestions_provider.cc b/components/ntp_snippets/content_suggestions_provider.cc index bf209411..3f071889 100644 --- a/components/ntp_snippets/content_suggestions_provider.cc +++ b/components/ntp_snippets/content_suggestions_provider.cc
@@ -26,13 +26,13 @@ std::string ContentSuggestionsProvider::MakeUniqueID( Category category, - const std::string& within_category_id) { + const std::string& within_category_id) const { return base::StringPrintf(kCombinedIDFormat, category.id(), within_category_id.c_str()); } Category ContentSuggestionsProvider::GetCategoryFromUniqueID( - const std::string& unique_id) { + const std::string& unique_id) const { size_t colon_index = unique_id.find(kSeparator); DCHECK_NE(std::string::npos, colon_index) << "Not a valid unique_id: " << unique_id; @@ -43,7 +43,7 @@ } std::string ContentSuggestionsProvider::GetWithinCategoryIDFromUniqueID( - const std::string& unique_id) { + const std::string& unique_id) const { size_t colon_index = unique_id.find(kSeparator); DCHECK_NE(std::string::npos, colon_index) << "Not a valid unique_id: " << unique_id;
diff --git a/components/ntp_snippets/content_suggestions_provider.h b/components/ntp_snippets/content_suggestions_provider.h index 2f343a4..23d403c 100644 --- a/components/ntp_snippets/content_suggestions_provider.h +++ b/components/ntp_snippets/content_suggestions_provider.h
@@ -123,11 +123,12 @@ // application-wide, because this provider is the only one that provides // suggestions for that category. std::string MakeUniqueID(Category category, - const std::string& within_category_id); + const std::string& within_category_id) const; // Reverse functions for MakeUniqueID() - Category GetCategoryFromUniqueID(const std::string& unique_id); - std::string GetWithinCategoryIDFromUniqueID(const std::string& unique_id); + Category GetCategoryFromUniqueID(const std::string& unique_id) const; + std::string GetWithinCategoryIDFromUniqueID( + const std::string& unique_id) const; Observer* observer() const { return observer_; } CategoryFactory* category_factory() const { return category_factory_; }
diff --git a/components/ntp_snippets/content_suggestions_service.cc b/components/ntp_snippets/content_suggestions_service.cc index 3311d45..7b23609c 100644 --- a/components/ntp_snippets/content_suggestions_service.cc +++ b/components/ntp_snippets/content_suggestions_service.cc
@@ -183,18 +183,19 @@ ContentSuggestionsProvider* provider, Category category, std::vector<ContentSuggestion> new_suggestions) { - if (RegisterCategoryIfRequired(provider, category)) { + if (RegisterCategoryIfRequired(provider, category)) NotifyCategoryStatusChanged(category); - } + + if (!IsCategoryStatusAvailable(provider->GetCategoryStatus(category))) + return; for (const ContentSuggestion& suggestion : suggestions_by_category_[category]) { id_category_map_.erase(suggestion.id()); } - for (const ContentSuggestion& suggestion : new_suggestions) { + for (const ContentSuggestion& suggestion : new_suggestions) id_category_map_.insert(std::make_pair(suggestion.id(), category)); - } suggestions_by_category_[category] = std::move(new_suggestions);
diff --git a/components/ntp_snippets/content_suggestions_service_unittest.cc b/components/ntp_snippets/content_suggestions_service_unittest.cc index 064cd389..a7f7538 100644 --- a/components/ntp_snippets/content_suggestions_service_unittest.cc +++ b/components/ntp_snippets/content_suggestions_service_unittest.cc
@@ -75,7 +75,7 @@ CategoryInfo GetCategoryInfo(Category category) { return CategoryInfo(base::ASCIIToUTF16("Section title"), - ContentSuggestionsCardLayout::FULL_CARD); + ContentSuggestionsCardLayout::FULL_CARD, true); } void FireSuggestionsChanged(Category category, std::vector<int> numbers) { @@ -207,7 +207,7 @@ Eq(ContentSuggestionsService::State::ENABLED)); Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); Category offline_pages_category = - FromKnownCategory(KnownCategories::OFFLINE_PAGES); + FromKnownCategory(KnownCategories::BOOKMARKS); ASSERT_THAT(providers(), IsEmpty()); EXPECT_THAT(service()->GetCategories(), IsEmpty()); EXPECT_THAT(service()->GetCategoryStatus(articles_category), @@ -240,7 +240,7 @@ TEST_F(ContentSuggestionsServiceDisabledTest, ShouldDoNothingWhenDisabled) { Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); Category offline_pages_category = - FromKnownCategory(KnownCategories::OFFLINE_PAGES); + FromKnownCategory(KnownCategories::BOOKMARKS); EXPECT_THAT(service()->state(), Eq(ContentSuggestionsService::State::DISABLED)); EXPECT_THAT(providers(), IsEmpty()); @@ -256,7 +256,7 @@ TEST_F(ContentSuggestionsServiceTest, ShouldRedirectFetchSuggestionImage) { Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); Category offline_pages_category = - FromKnownCategory(KnownCategories::OFFLINE_PAGES); + FromKnownCategory(KnownCategories::BOOKMARKS); MockProvider* provider1 = MakeProvider(articles_category); MockProvider* provider2 = MakeProvider(offline_pages_category); @@ -289,7 +289,7 @@ TEST_F(ContentSuggestionsServiceTest, ShouldRedirectDismissSuggestion) { Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); Category offline_pages_category = - FromKnownCategory(KnownCategories::OFFLINE_PAGES); + FromKnownCategory(KnownCategories::BOOKMARKS); MockProvider* provider1 = MakeProvider(articles_category); MockProvider* provider2 = MakeProvider(offline_pages_category); @@ -304,7 +304,7 @@ TEST_F(ContentSuggestionsServiceTest, ShouldForwardSuggestions) { Category articles_category = FromKnownCategory(KnownCategories::ARTICLES); Category offline_pages_category = - FromKnownCategory(KnownCategories::OFFLINE_PAGES); + FromKnownCategory(KnownCategories::BOOKMARKS); // Create and register providers MockProvider* provider1 = MakeProvider(articles_category); @@ -343,7 +343,7 @@ ExpectThatSuggestionsAre(offline_pages_category, {13, 14}); Mock::VerifyAndClearExpectations(&observer); - // provider2 reports OFFLINE_PAGES as unavailable + // provider2 reports BOOKMARKS as unavailable EXPECT_CALL(observer, OnCategoryStatusChanged( offline_pages_category, CategoryStatus::CATEGORY_EXPLICITLY_DISABLED))
diff --git a/components/ntp_snippets/features.cc b/components/ntp_snippets/features.cc index 9ed4735f..0393b31 100644 --- a/components/ntp_snippets/features.cc +++ b/components/ntp_snippets/features.cc
@@ -10,12 +10,17 @@ "NTPArticleSuggestions", base::FEATURE_ENABLED_BY_DEFAULT}; const base::Feature kBookmarkSuggestionsFeature{ - "NTPBookmarkSuggestions", base::FEATURE_DISABLED_BY_DEFAULT}; + "NTPBookmarkSuggestions", base::FEATURE_ENABLED_BY_DEFAULT}; -const base::Feature kOfflinePageSuggestionsFeature{ +const base::Feature kRecentOfflineTabSuggestionsFeature{ "NTPOfflinePageSuggestions", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kSaveToOfflineFeature{ + "NTPSaveToOffline", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kDownloadSuggestionsFeature{ + "NTPDownloadSuggestions", base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kContentSuggestionsFeature{ - "NTPSnippets", base::FEATURE_DISABLED_BY_DEFAULT}; + "NTPSnippets", base::FEATURE_ENABLED_BY_DEFAULT}; } // namespace ntp_snippets
diff --git a/components/ntp_snippets/features.h b/components/ntp_snippets/features.h index 130ed24..46344d58 100644 --- a/components/ntp_snippets/features.h +++ b/components/ntp_snippets/features.h
@@ -9,10 +9,15 @@ namespace ntp_snippets { -// Features to turn individual providers on/off. +// Features to turn individual providers/categories on/off. extern const base::Feature kArticleSuggestionsFeature; extern const base::Feature kBookmarkSuggestionsFeature; -extern const base::Feature kOfflinePageSuggestionsFeature; +extern const base::Feature kRecentOfflineTabSuggestionsFeature; +extern const base::Feature kDownloadSuggestionsFeature; + +// Feature to allow the 'save to offline' option to appear in the snippets +// context menu. +extern const base::Feature kSaveToOfflineFeature; // Global toggle for the whole content suggestions feature. If this is set to // false, all the per-provider features are ignored.
diff --git a/components/ntp_snippets/ntp_snippet.cc b/components/ntp_snippets/ntp_snippet.cc index d69a77ab..8515e4f9 100644 --- a/components/ntp_snippets/ntp_snippet.cc +++ b/components/ntp_snippets/ntp_snippet.cc
@@ -260,6 +260,12 @@ return base::Int64ToString((time - base::Time::UnixEpoch()).InSeconds()); } +bool NTPSnippet::CompareCategoriesByID::operator()( + const Category& left, + const Category& right) const { + return left.id() < right.id(); +} + void NTPSnippet::FindBestSource() { // The same article can be hosted by multiple sources, e.g. nytimes.com, // cnn.com, etc. We need to parse the list of sources for this article and
diff --git a/components/ntp_snippets/ntp_snippet.h b/components/ntp_snippets/ntp_snippet.h index 18b0729..3d2d6bf 100644 --- a/components/ntp_snippets/ntp_snippet.h +++ b/components/ntp_snippets/ntp_snippet.h
@@ -5,12 +5,14 @@ #ifndef COMPONENTS_NTP_SNIPPETS_NTP_SNIPPET_H_ #define COMPONENTS_NTP_SNIPPETS_NTP_SNIPPET_H_ +#include <map> #include <memory> #include <string> #include <vector> #include "base/macros.h" #include "base/time/time.h" +#include "components/ntp_snippets/category.h" #include "url/gurl.h" namespace base { @@ -32,8 +34,11 @@ }; class NTPSnippet { + struct CompareCategoriesByID; + public: using PtrVector = std::vector<std::unique_ptr<NTPSnippet>>; + using CategoryMap = std::map<Category, PtrVector, CompareCategoriesByID>; // Creates a new snippet with the given |id|. // Public for testing only - create snippets using the Create* methods below. @@ -130,6 +135,10 @@ static std::string TimeToJsonString(const base::Time& time); private: + struct CompareCategoriesByID { + bool operator()(const Category& left, const Category& right) const; + }; + void FindBestSource(); std::string id_;
diff --git a/components/ntp_snippets/ntp_snippets_fetcher.cc b/components/ntp_snippets/ntp_snippets_fetcher.cc index d8ca5090..eb99d74 100644 --- a/components/ntp_snippets/ntp_snippets_fetcher.cc +++ b/components/ntp_snippets/ntp_snippets_fetcher.cc
@@ -20,6 +20,7 @@ #include "base/time/default_tick_clock.h" #include "base/values.h" #include "components/data_use_measurement/core/data_use_user_data.h" +#include "components/ntp_snippets/category_factory.h" #include "components/ntp_snippets/ntp_snippets_constants.h" #include "components/ntp_snippets/switches.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" @@ -152,6 +153,7 @@ OAuth2TokenService* token_service, scoped_refptr<URLRequestContextGetter> url_request_context_getter, PrefService* pref_service, + CategoryFactory* category_factory, const ParseJSONCallback& parse_json_callback, bool is_stable_channel) : OAuth2TokenService::Consumer("ntp_snippets"), @@ -159,6 +161,7 @@ token_service_(token_service), waiting_for_refresh_token_(false), url_request_context_getter_(url_request_context_getter), + category_factory_(category_factory), parse_json_callback_(parse_json_callback), fetch_url_(GetFetchEndpoint()), fetch_api_(UsesChromeContentSuggestionsAPI(fetch_url_) @@ -169,6 +172,7 @@ request_throttler_( pref_service, RequestThrottler::RequestType::CONTENT_SUGGESTION_FETCHER), + oauth_token_retried_(false), weak_ptr_factory_(this) { // Parse the variation parameters and set the defaults if missing. std::string personalization = variations::GetVariationParamValue( @@ -232,6 +236,7 @@ if (use_authentication && signin_manager_->IsAuthenticated()) { // Signed-in: get OAuth token --> fetch snippets. + oauth_token_retried_ = false; StartTokenRequest(); } else if (use_authentication && signin_manager_->AuthInProgress()) { // Currently signing in: wait for auth to finish (the refresh token) --> @@ -402,6 +407,7 @@ params.host_restricts = UsesHostRestrictions() ? hosts_ : std::set<std::string>(); params.count_to_fetch = count_to_fetch_; + // TODO(jkrcal, treib): Add unit-tests for authenticated fetches. FetchSnippetsImpl(fetch_url_, base::StringPrintf(kAuthorizationRequestHeaderFormat, oauth_access_token.c_str()), @@ -436,8 +442,17 @@ const OAuth2TokenService::Request* request, const GoogleServiceAuthError& error) { oauth_request_.reset(); - DLOG(ERROR) << "Unable to get token: " << error.ToString() - << " - fetching the snippets without authentication."; + + if (!oauth_token_retried_ && + error.state() == GoogleServiceAuthError::State::REQUEST_CANCELED) { + // The request (especially on startup) can get reset by loading the refresh + // token - do it one more time. + oauth_token_retried_ = true; + StartTokenRequest(); + return; + } + + DLOG(ERROR) << "Unable to get token: " << error.ToString(); FetchFinished( OptionalSnippets(), FetchResult::OAUTH_TOKEN_ERROR, /*extra_message=*/base::StringPrintf(" (%s)", error.ToString().c_str())); @@ -453,6 +468,7 @@ token_service_->RemoveObserver(this); waiting_for_refresh_token_ = false; + oauth_token_retried_ = false; StartTokenRequest(); } @@ -494,7 +510,7 @@ } bool NTPSnippetsFetcher::JsonToSnippets(const base::Value& parsed, - NTPSnippet::PtrVector* snippets) { + NTPSnippet::CategoryMap* snippets) { const base::DictionaryValue* top_dict = nullptr; if (!parsed.GetAsDictionary(&top_dict)) { return false; @@ -502,10 +518,13 @@ switch (fetch_api_) { case CHROME_READER_API: { + Category category = + category_factory_->FromKnownCategory(KnownCategories::ARTICLES); + NTPSnippet::PtrVector* articles = &(*snippets)[category]; const base::ListValue* recos = nullptr; return top_dict->GetList("recos", &recos) && AddSnippetsFromListValue(/* content_suggestions_api = */ false, - *recos, snippets); + *recos, articles); } case CHROME_CONTENT_SUGGESTIONS_API: { @@ -514,15 +533,20 @@ return false; } - // Merge all categories together, for now. - // TODO(sfiera): preserve categories from server. for (const auto& v : *categories) { - const base::DictionaryValue* category = nullptr; + int category_id = -1; + const base::DictionaryValue* category_value = nullptr; const base::ListValue* suggestions = nullptr; - if (!(v->GetAsDictionary(&category) && - category->GetList("suggestions", &suggestions) && - AddSnippetsFromListValue(/* content_suggestions_api = */ true, - *suggestions, snippets))) { + if (!(v->GetAsDictionary(&category_value) && + category_value->GetInteger("id", &category_id) && + (category_id > 0) && + category_value->GetList("suggestions", &suggestions))) { + return false; + } + Category category = category_factory_->FromRemoteCategory(category_id); + NTPSnippet::PtrVector* articles = &(*snippets)[category]; + if (!AddSnippetsFromListValue( + /* content_suggestions_api = */ true, *suggestions, articles)) { return false; } } @@ -534,7 +558,7 @@ } void NTPSnippetsFetcher::OnJsonParsed(std::unique_ptr<base::Value> parsed) { - NTPSnippet::PtrVector snippets; + NTPSnippet::CategoryMap snippets; if (JsonToSnippets(*parsed, &snippets)) { FetchFinished(OptionalSnippets(std::move(snippets)), FetchResult::SUCCESS, /*extra_message=*/std::string());
diff --git a/components/ntp_snippets/ntp_snippets_fetcher.h b/components/ntp_snippets/ntp_snippets_fetcher.h index 11a4e40f..52c49f5 100644 --- a/components/ntp_snippets/ntp_snippets_fetcher.h +++ b/components/ntp_snippets/ntp_snippets_fetcher.h
@@ -47,7 +47,7 @@ using ParseJSONCallback = base::Callback< void(const std::string&, const SuccessCallback&, const ErrorCallback&)>; - using OptionalSnippets = base::Optional<NTPSnippet::PtrVector>; + using OptionalSnippets = base::Optional<NTPSnippet::CategoryMap>; // |snippets| contains parsed snippets if a fetch succeeded. If problems // occur, |snippets| contains no value (no actual vector in base::Optional). // Error details can be retrieved using last_status(). @@ -80,6 +80,7 @@ OAuth2TokenService* oauth2_token_service, scoped_refptr<net::URLRequestContextGetter> url_request_context_getter, PrefService* pref_service, + CategoryFactory* category_factory, const ParseJSONCallback& parse_json_callback, bool is_stable_channel); ~NTPSnippetsFetcher() override; @@ -175,7 +176,7 @@ void OnURLFetchComplete(const net::URLFetcher* source) override; bool JsonToSnippets(const base::Value& parsed, - NTPSnippet::PtrVector* snippets); + NTPSnippet::CategoryMap* snippets); void OnJsonParsed(std::unique_ptr<base::Value> parsed); void OnJsonError(const std::string& error); void FetchFinished(OptionalSnippets snippets, @@ -191,6 +192,7 @@ // Holds the URL request context. scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; + CategoryFactory* const category_factory_; const ParseJSONCallback parse_json_callback_; base::TimeTicks fetch_start_time_; std::string last_status_; @@ -230,6 +232,9 @@ // Request throttler for limiting requests. RequestThrottler request_throttler_; + // When a token request gets canceled, we want to retry once. + bool oauth_token_retried_; + base::WeakPtrFactory<NTPSnippetsFetcher> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(NTPSnippetsFetcher);
diff --git a/components/ntp_snippets/ntp_snippets_fetcher_unittest.cc b/components/ntp_snippets/ntp_snippets_fetcher_unittest.cc index 9b6cfcc..1d1f9149 100644 --- a/components/ntp_snippets/ntp_snippets_fetcher_unittest.cc +++ b/components/ntp_snippets/ntp_snippets_fetcher_unittest.cc
@@ -15,6 +15,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "base/values.h" +#include "components/ntp_snippets/category_factory.h" #include "components/ntp_snippets/ntp_snippet.h" #include "components/ntp_snippets/ntp_snippets_constants.h" #include "components/prefs/testing_pref_service.h" @@ -34,6 +35,7 @@ namespace { +using testing::_; using testing::ElementsAre; using testing::Eq; using testing::IsEmpty; @@ -43,6 +45,7 @@ using testing::PrintToString; using testing::SizeIs; using testing::StartsWith; +using testing::WithArg; const char kTestChromeReaderUrlFormat[] = "https://chromereader-pa.googleapis.com/v1/fetch?key=%s"; @@ -53,14 +56,24 @@ // Artificial time delay for JSON parsing. const int64_t kTestJsonParsingLatencyMs = 20; -MATCHER(HasValue, "") { - return static_cast<bool>(arg); +ACTION_P(MovePointeeTo, ptr) { + *ptr = std::move(*arg0); } -MATCHER_P(PointeeSizeIs, - size, - std::string("contains a value with size ") + PrintToString(size)) { - return arg && static_cast<int>(arg->size()) == size; +MATCHER(HasValue, "") { + return static_cast<bool>(*arg); +} + +MATCHER(IsEmptyArticleList, "is an empty list of articles") { + NTPSnippetsFetcher::OptionalSnippets& snippets = *arg; + return snippets && snippets->size() == 1 && snippets->begin()->second.empty(); +} + +MATCHER_P(IsSingleArticle, url, "is a list with the single article %(url)s") { + NTPSnippetsFetcher::OptionalSnippets& snippets = *arg; + return snippets && snippets->size() == 1 && + snippets->begin()->second.size() == 1 && + snippets->begin()->second[0]->best_source().url.spec() == url; } MATCHER_P(EqualsJSON, json, "equals JSON") { @@ -86,10 +99,10 @@ public: // Workaround for gMock's lack of support for movable arguments. void WrappedRun(NTPSnippetsFetcher::OptionalSnippets snippets) { - Run(snippets); + Run(&snippets); } - MOCK_METHOD1(Run, void(const NTPSnippetsFetcher::OptionalSnippets& snippets)); + MOCK_METHOD1(Run, void(NTPSnippetsFetcher::OptionalSnippets* snippets)); }; // Factory for FakeURLFetcher objects that always generate errors. @@ -154,13 +167,11 @@ RequestThrottler::RegisterProfilePrefs(pref_service_->registry()); snippets_fetcher_ = base::MakeUnique<NTPSnippetsFetcher>( - fake_signin_manager_.get(), - fake_token_service_.get(), - scoped_refptr<net::TestURLRequestContextGetter>( - new net::TestURLRequestContextGetter(mock_task_runner_.get())), - pref_service_.get(), - base::Bind(&ParseJsonDelayed), - /*is_stable_channel=*/true); + fake_signin_manager_.get(), fake_token_service_.get(), + scoped_refptr<net::TestURLRequestContextGetter>( + new net::TestURLRequestContextGetter(mock_task_runner_.get())), + pref_service_.get(), &category_factory_, base::Bind(&ParseJsonDelayed), + /*is_stable_channel=*/true); snippets_fetcher_->SetCallback( base::Bind(&MockSnippetsAvailableCallback::WrappedRun, @@ -212,6 +223,7 @@ std::unique_ptr<OAuth2TokenService> fake_token_service_; std::unique_ptr<NTPSnippetsFetcher> snippets_fetcher_; std::unique_ptr<TestingPrefServiceSimple> pref_service_; + CategoryFactory category_factory_; MockSnippetsAvailableCallback mock_callback_; const std::string test_lang_; const GURL test_url_; @@ -364,7 +376,7 @@ "}]}"; SetFakeResponse(/*data=*/kJsonStr, net::HTTP_OK, net::URLRequestStatus::SUCCESS); - EXPECT_CALL(mock_callback(), Run(/*snippets=*/PointeeSizeIs(1))).Times(1); + EXPECT_CALL(mock_callback(), Run(IsSingleArticle("http://localhost/foobar"))); snippets_fetcher().FetchSnippetsFromHosts(test_hosts(), test_lang(), /*count=*/1, /*force_request=*/true); @@ -399,7 +411,7 @@ "}]}"; SetFakeResponse(/*data=*/kJsonStr, net::HTTP_OK, net::URLRequestStatus::SUCCESS); - EXPECT_CALL(mock_callback(), Run(/*snippets=*/PointeeSizeIs(1))).Times(1); + EXPECT_CALL(mock_callback(), Run(IsSingleArticle("http://localhost/foobar"))); snippets_fetcher().FetchSnippetsFromHosts(test_hosts(), test_lang(), /*count=*/1, /*force_request=*/true); @@ -414,11 +426,84 @@ /*count=*/1))); } +TEST_F(NTPSnippetsContentSuggestionsFetcherTest, ServerCategories) { + const std::string kJsonStr = + "{\"categories\" : [{" + " \"id\": 1," + " \"localizedTitle\": \"Articles for You\"," + " \"suggestions\" : [{" + " \"ids\" : [\"http://localhost/foobar\"]," + " \"title\" : \"Foo Barred from Baz\"," + " \"snippet\" : \"...\"," + " \"fullPageUrl\" : \"http://localhost/foobar\"," + " \"creationTime\" : \"2016-06-30T11:01:37.000Z\"," + " \"expirationTime\" : \"2016-07-01T11:01:37.000Z\"," + " \"attribution\" : \"Foo News\"," + " \"imageUrl\" : \"http://localhost/foobar.jpg\"," + " \"ampUrl\" : \"http://localhost/amp\"," + " \"faviconUrl\" : \"http://localhost/favicon.ico\" " + " }]" + "}, {" + " \"id\": 2," + " \"localizedTitle\": \"Articles for Me\"," + " \"suggestions\" : [{" + " \"ids\" : [\"http://localhost/foo2\"]," + " \"title\" : \"Foo Barred from Baz\"," + " \"snippet\" : \"...\"," + " \"fullPageUrl\" : \"http://localhost/foo2\"," + " \"creationTime\" : \"2016-06-30T11:01:37.000Z\"," + " \"expirationTime\" : \"2016-07-01T11:01:37.000Z\"," + " \"attribution\" : \"Foo News\"," + " \"imageUrl\" : \"http://localhost/foo2.jpg\"," + " \"ampUrl\" : \"http://localhost/amp\"," + " \"faviconUrl\" : \"http://localhost/favicon.ico\" " + " }]" + "}]}"; + SetFakeResponse(/*data=*/kJsonStr, net::HTTP_OK, + net::URLRequestStatus::SUCCESS); + NTPSnippetsFetcher::OptionalSnippets snippets; + EXPECT_CALL(mock_callback(), Run(_)) + .WillOnce(WithArg<0>(MovePointeeTo(&snippets))); + snippets_fetcher().FetchSnippetsFromHosts(test_hosts(), test_lang(), + /*count=*/1, + /*force_request=*/true); + FastForwardUntilNoTasksRemain(); + + ASSERT_TRUE(snippets); + ASSERT_THAT(snippets->size(), Eq(2u)); + for (const auto& category : *snippets) { + const auto& articles = category.second; + switch (category.first.id()) { + case static_cast<int>(KnownCategories::ARTICLES): + ASSERT_THAT(articles.size(), Eq(1u)); + EXPECT_THAT(articles[0]->best_source().url.spec(), + Eq("http://localhost/foobar")); + break; + case static_cast<int>(KnownCategories::ARTICLES) + 1: + ASSERT_THAT(articles.size(), Eq(1u)); + EXPECT_THAT(articles[0]->best_source().url.spec(), + Eq("http://localhost/foo2")); + break; + default: + FAIL() << "unknown category ID " << category.first.id(); + } + } + + EXPECT_THAT(snippets_fetcher().last_status(), Eq("OK")); + EXPECT_THAT(snippets_fetcher().last_json(), Eq(kJsonStr)); + EXPECT_THAT(histogram_tester().GetAllSamples( + "NewTabPage.Snippets.FetchHttpResponseOrErrorCode"), + ElementsAre(base::Bucket(/*min=*/200, /*count=*/1))); + EXPECT_THAT(histogram_tester().GetAllSamples("NewTabPage.Snippets.FetchTime"), + ElementsAre(base::Bucket(/*min=*/kTestJsonParsingLatencyMs, + /*count=*/1))); +} + TEST_F(NTPSnippetsFetcherTest, ShouldFetchSuccessfullyEmptyList) { const std::string kJsonStr = "{\"recos\": []}"; SetFakeResponse(/*data=*/kJsonStr, net::HTTP_OK, net::URLRequestStatus::SUCCESS); - EXPECT_CALL(mock_callback(), Run(/*snippets=*/PointeeSizeIs(0))).Times(1); + EXPECT_CALL(mock_callback(), Run(IsEmptyArticleList())); snippets_fetcher().FetchSnippetsFromHosts(test_hosts(), test_lang(), /*count=*/1, /*force_request=*/true); @@ -601,7 +686,7 @@ const std::string kJsonStr = "{ \"recos\": [] }"; SetFakeResponse(/*data=*/kJsonStr, net::HTTP_OK, net::URLRequestStatus::SUCCESS); - EXPECT_CALL(mock_callback(), Run(/*snippets=*/PointeeSizeIs(0))).Times(1); + EXPECT_CALL(mock_callback(), Run(IsEmptyArticleList())); snippets_fetcher().FetchSnippetsFromHosts(test_hosts(), test_lang(), /*count=*/1, /*force_request=*/true);
diff --git a/components/ntp_snippets/ntp_snippets_service.cc b/components/ntp_snippets/ntp_snippets_service.cc index 295acfb..4a657a0 100644 --- a/components/ntp_snippets/ntp_snippets_service.cc +++ b/components/ntp_snippets/ntp_snippets_service.cc
@@ -284,7 +284,7 @@ CategoryInfo NTPSnippetsService::GetCategoryInfo(Category category) { return CategoryInfo( l10n_util::GetStringUTF16(IDS_NTP_ARTICLE_SUGGESTIONS_SECTION_HEADER), - ContentSuggestionsCardLayout::FULL_CARD); + ContentSuggestionsCardLayout::FULL_CARD, /* has_more_button */ false); } void NTPSnippetsService::DismissSuggestion(const std::string& suggestion_id) { @@ -472,13 +472,14 @@ DCHECK(category_status_ == CategoryStatus::AVAILABLE || category_status_ == CategoryStatus::AVAILABLE_LOADING); - if (snippets) { + // TODO(sfiera): support more than just the provided_category_ ARTICLES. + if (snippets && (snippets->find(provided_category_) != snippets->end())) { // Sparse histogram used because the number of snippets is small (bound by // kMaxSnippetCount). DCHECK_LE(snippets->size(), static_cast<size_t>(kMaxSnippetCount)); UMA_HISTOGRAM_SPARSE_SLOWLY("NewTabPage.Snippets.NumArticlesFetched", - snippets->size()); - MergeSnippets(std::move(*snippets)); + (*snippets)[provided_category_].size()); + MergeSnippets(std::move((*snippets)[provided_category_])); } ClearExpiredSnippets();
diff --git a/components/ntp_snippets/ntp_snippets_service.h b/components/ntp_snippets/ntp_snippets_service.h index 43a27de..8e1a829 100644 --- a/components/ntp_snippets/ntp_snippets_service.h +++ b/components/ntp_snippets/ntp_snippets_service.h
@@ -27,7 +27,7 @@ #include "components/ntp_snippets/ntp_snippets_scheduler.h" #include "components/ntp_snippets/ntp_snippets_status_service.h" #include "components/suggestions/suggestions_service.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/sync_service_observer.h" class PrefRegistrySimple; class PrefService;
diff --git a/components/ntp_snippets/ntp_snippets_service_unittest.cc b/components/ntp_snippets/ntp_snippets_service_unittest.cc index f826aea..20334cd5 100644 --- a/components/ntp_snippets/ntp_snippets_service_unittest.cc +++ b/components/ntp_snippets/ntp_snippets_service_unittest.cc
@@ -318,7 +318,7 @@ base::MakeUnique<NTPSnippetsFetcher>( fake_signin_manager(), fake_token_service_.get(), std::move(request_context_getter), pref_service(), - base::Bind(&ParseJson), + &category_factory_, base::Bind(&ParseJson), /*is_stable_channel=*/true); fake_signin_manager()->SignIn("foo@bar.com");
diff --git a/components/ntp_snippets/ntp_snippets_test_utils.cc b/components/ntp_snippets/ntp_snippets_test_utils.cc index c00629c7..d20b7af 100644 --- a/components/ntp_snippets/ntp_snippets_test_utils.cc +++ b/components/ntp_snippets/ntp_snippets_test_utils.cc
@@ -12,7 +12,7 @@ #include "components/signin/core/browser/fake_signin_manager.h" #include "components/signin/core/browser/test_signin_client.h" #include "components/signin/core/common/signin_pref_names.h" -#include "components/sync_driver/fake_sync_service.h" +#include "components/sync/driver/fake_sync_service.h" namespace ntp_snippets { namespace test {
diff --git a/components/ntp_snippets/ntp_snippets_test_utils.h b/components/ntp_snippets/ntp_snippets_test_utils.h index 20e9c854..430515a 100644 --- a/components/ntp_snippets/ntp_snippets_test_utils.h +++ b/components/ntp_snippets/ntp_snippets_test_utils.h
@@ -7,7 +7,7 @@ #include <memory> -#include "components/sync_driver/fake_sync_service.h" +#include "components/sync/driver/fake_sync_service.h" #include "testing/gtest/include/gtest/gtest.h" class AccountTrackerService;
diff --git a/components/ntp_snippets/offline_pages/offline_page_suggestions_provider.cc b/components/ntp_snippets/offline_pages/offline_page_suggestions_provider.cc index ee8a254..0c15373 100644 --- a/components/ntp_snippets/offline_pages/offline_page_suggestions_provider.cc +++ b/components/ntp_snippets/offline_pages/offline_page_suggestions_provider.cc
@@ -4,11 +4,21 @@ #include "components/ntp_snippets/offline_pages/offline_page_suggestions_provider.h" +#include <algorithm> + #include "base/bind.h" +#include "base/guid.h" #include "base/location.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" +#include "base/values.h" +#include "components/ntp_snippets/pref_names.h" +#include "components/offline_pages/client_namespace_constants.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" +#include "grit/components_strings.h" +#include "ui/base/l10n/l10n_util.h" #include "ui/gfx/image/image.h" using offline_pages::MultipleOfflinePageItemResult; @@ -21,17 +31,41 @@ const int kMaxSuggestionsCount = 5; +struct OrderByMostRecentlyVisited { + bool operator()(const OfflinePageItem* left, + const OfflinePageItem* right) const { + return left->last_access_time > right->last_access_time; + } +}; + } // namespace OfflinePageSuggestionsProvider::OfflinePageSuggestionsProvider( + bool recent_tabs_enabled, + bool downloads_enabled, + bool download_manager_ui_enabled, ContentSuggestionsProvider::Observer* observer, CategoryFactory* category_factory, - OfflinePageModel* offline_page_model) + OfflinePageModel* offline_page_model, + PrefService* pref_service) : ContentSuggestionsProvider(observer, category_factory), - category_status_(CategoryStatus::AVAILABLE_LOADING), + recent_tabs_status_(recent_tabs_enabled + ? CategoryStatus::AVAILABLE_LOADING + : CategoryStatus::NOT_PROVIDED), + downloads_status_(downloads_enabled ? CategoryStatus::AVAILABLE_LOADING + : CategoryStatus::NOT_PROVIDED), offline_page_model_(offline_page_model), - provided_category_( - category_factory->FromKnownCategory(KnownCategories::OFFLINE_PAGES)) { + recent_tabs_category_( + category_factory->FromKnownCategory(KnownCategories::RECENT_TABS)), + downloads_category_( + category_factory->FromKnownCategory(KnownCategories::DOWNLOADS)), + pref_service_(pref_service), + dismissed_recent_tab_ids_(ReadDismissedIDsFromPrefs( + prefs::kDismissedRecentOfflineTabSuggestions)), + dismissed_download_ids_( + ReadDismissedIDsFromPrefs(prefs::kDismissedDownloadSuggestions)), + download_manager_ui_enabled_(download_manager_ui_enabled) { + DCHECK(recent_tabs_enabled || downloads_enabled); offline_page_model_->AddObserver(this); FetchOfflinePages(); } @@ -40,30 +74,72 @@ offline_page_model_->RemoveObserver(this); } +// static +void OfflinePageSuggestionsProvider::RegisterProfilePrefs( + PrefRegistrySimple* registry) { + registry->RegisterListPref(prefs::kDismissedRecentOfflineTabSuggestions); + registry->RegisterListPref(prefs::kDismissedDownloadSuggestions); +} + //////////////////////////////////////////////////////////////////////////////// // Private methods std::vector<Category> OfflinePageSuggestionsProvider::GetProvidedCategories() { - return std::vector<Category>({provided_category_}); + std::vector<Category> provided_categories; + if (recent_tabs_status_ != CategoryStatus::NOT_PROVIDED) + provided_categories.push_back(recent_tabs_category_); + if (downloads_status_ != CategoryStatus::NOT_PROVIDED) + provided_categories.push_back(downloads_category_); + return provided_categories; } CategoryStatus OfflinePageSuggestionsProvider::GetCategoryStatus( Category category) { - DCHECK_EQ(category, provided_category_); - return category_status_; + if (category == recent_tabs_category_) + return recent_tabs_status_; + if (category == downloads_category_) + return downloads_status_; + NOTREACHED() << "Unknown category " << category.id(); + return CategoryStatus::NOT_PROVIDED; } CategoryInfo OfflinePageSuggestionsProvider::GetCategoryInfo( Category category) { - // TODO(pke): Use the proper string once it's agreed on. - return CategoryInfo(base::ASCIIToUTF16("Offline pages"), - ContentSuggestionsCardLayout::MINIMAL_CARD); + if (category == recent_tabs_category_) { + return CategoryInfo(l10n_util::GetStringUTF16( + IDS_NTP_RECENT_TAB_SUGGESTIONS_SECTION_HEADER), + ContentSuggestionsCardLayout::MINIMAL_CARD, + /* has_more_button */ false); + } + if (category == downloads_category_) { + return CategoryInfo( + l10n_util::GetStringUTF16(IDS_NTP_DOWNLOAD_SUGGESTIONS_SECTION_HEADER), + ContentSuggestionsCardLayout::MINIMAL_CARD, + /* has_more_button */ download_manager_ui_enabled_); + } + NOTREACHED() << "Unknown category " << category.id(); + return CategoryInfo(base::string16(), + ContentSuggestionsCardLayout::MINIMAL_CARD, + /* has_more_button */ false); } void OfflinePageSuggestionsProvider::DismissSuggestion( const std::string& suggestion_id) { - // TODO(pke): Implement some "dont show on NTP anymore" behaviour, - // then also implement ClearDismissedSuggestionsForDebugging. + Category category = GetCategoryFromUniqueID(suggestion_id); + std::string offline_page_id = GetWithinCategoryIDFromUniqueID(suggestion_id); + if (category == recent_tabs_category_) { + DCHECK_NE(CategoryStatus::NOT_PROVIDED, recent_tabs_status_); + dismissed_recent_tab_ids_.insert(offline_page_id); + StoreDismissedIDsToPrefs(prefs::kDismissedRecentOfflineTabSuggestions, + dismissed_recent_tab_ids_); + } else if (category == downloads_category_) { + DCHECK_NE(CategoryStatus::NOT_PROVIDED, downloads_status_); + dismissed_download_ids_.insert(offline_page_id); + StoreDismissedIDsToPrefs(prefs::kDismissedDownloadSuggestions, + dismissed_download_ids_); + } else { + NOTREACHED() << "Unknown category " << category.id(); + } } void OfflinePageSuggestionsProvider::FetchSuggestionImage( @@ -77,22 +153,53 @@ void OfflinePageSuggestionsProvider::ClearCachedSuggestionsForDebugging( Category category) { - DCHECK_EQ(category, provided_category_); // Ignored. } std::vector<ContentSuggestion> OfflinePageSuggestionsProvider::GetDismissedSuggestionsForDebugging( Category category) { - DCHECK_EQ(category, provided_category_); - // TODO(pke): Implement when dismissed suggestions are supported. - return std::vector<ContentSuggestion>(); + // TODO(pke): Make GetDismissedSuggestionsForDebugging asynchronous so this + // can return proper values. + std::vector<ContentSuggestion> suggestions; + const std::set<std::string>* dismissed_ids = nullptr; + if (category == recent_tabs_category_) { + DCHECK_NE(CategoryStatus::NOT_PROVIDED, recent_tabs_status_); + dismissed_ids = &dismissed_recent_tab_ids_; + } else if (category == downloads_category_) { + DCHECK_NE(CategoryStatus::NOT_PROVIDED, downloads_status_); + dismissed_ids = &dismissed_download_ids_; + } else { + NOTREACHED() << "Unknown category " << category.id(); + return suggestions; + } + + for (const std::string& dismissed_id : *dismissed_ids) { + ContentSuggestion suggestion( + MakeUniqueID(category, dismissed_id), + GURL("http://dismissed-offline-page-" + dismissed_id)); + suggestion.set_title(base::UTF8ToUTF16("Title not available")); + suggestions.push_back(std::move(suggestion)); + } + return suggestions; } void OfflinePageSuggestionsProvider::ClearDismissedSuggestionsForDebugging( Category category) { - DCHECK_EQ(category, provided_category_); - // TODO(pke): Implement when dismissed suggestions are supported. + if (category == recent_tabs_category_) { + DCHECK_NE(CategoryStatus::NOT_PROVIDED, recent_tabs_status_); + dismissed_recent_tab_ids_.clear(); + StoreDismissedIDsToPrefs(prefs::kDismissedRecentOfflineTabSuggestions, + dismissed_recent_tab_ids_); + } else if (category == downloads_category_) { + DCHECK_NE(CategoryStatus::NOT_PROVIDED, downloads_status_); + dismissed_download_ids_.clear(); + StoreDismissedIDsToPrefs(prefs::kDismissedDownloadSuggestions, + dismissed_download_ids_); + } else { + NOTREACHED() << "Unknown category " << category.id(); + } + FetchOfflinePages(); } void OfflinePageSuggestionsProvider::OfflinePageModelLoaded( @@ -120,40 +227,126 @@ void OfflinePageSuggestionsProvider::OnOfflinePagesLoaded( const MultipleOfflinePageItemResult& result) { - NotifyStatusChanged(CategoryStatus::AVAILABLE); + bool need_recent_tabs = recent_tabs_status_ != CategoryStatus::NOT_PROVIDED; + bool need_downloads = downloads_status_ != CategoryStatus::NOT_PROVIDED; + if (need_recent_tabs) + NotifyStatusChanged(recent_tabs_category_, CategoryStatus::AVAILABLE); + if (need_downloads) + NotifyStatusChanged(downloads_category_, CategoryStatus::AVAILABLE); - std::vector<ContentSuggestion> suggestions; + std::vector<const OfflinePageItem*> recent_tab_items; + std::vector<const OfflinePageItem*> download_items; for (const OfflinePageItem& item : result) { - // TODO(pke): Make sure the URL is actually opened as an offline URL. - // Currently, the browser opens the offline URL and then immediately - // redirects to the online URL if the device is online. - ContentSuggestion suggestion( - MakeUniqueID(provided_category_, base::IntToString(item.offline_id)), - item.GetOfflineURL()); + if (need_recent_tabs && + item.client_id.name_space == offline_pages::kLastNNamespace && + !dismissed_recent_tab_ids_.count(base::IntToString(item.offline_id))) { + recent_tab_items.push_back(&item); + } - // TODO(pke): Sort my most recently visited and only keep the top one of - // multiple entries for the same URL. - // TODO(pke): Get more reasonable data from the OfflinePageModel here. - suggestion.set_title(base::UTF8ToUTF16(item.url.spec())); - suggestion.set_snippet_text(base::string16()); - suggestion.set_publish_date(item.creation_time); - suggestion.set_publisher_name(base::UTF8ToUTF16(item.url.host())); - suggestions.emplace_back(std::move(suggestion)); - if (suggestions.size() == kMaxSuggestionsCount) - break; + // TODO(pke): Use kDownloadNamespace once the OfflinePageModel uses that. + // The current logic is taken from DownloadUIAdapter::IsVisibleInUI. + if (need_downloads && + item.client_id.name_space == offline_pages::kAsyncNamespace && + base::IsValidGUID(item.client_id.id) && + !dismissed_download_ids_.count(base::IntToString(item.offline_id))) { + download_items.push_back(&item); + } } - observer()->OnNewSuggestions(this, provided_category_, - std::move(suggestions)); + // TODO(pke): Once we have our OfflinePageModel getter and that doesn't do it + // already, filter out duplicate URLs for recent tabs here. Duplicates for + // downloads are fine. + + if (need_recent_tabs) { + observer()->OnNewSuggestions( + this, recent_tabs_category_, + GetMostRecentlyVisited(recent_tabs_category_, + std::move(recent_tab_items))); + } + if (need_downloads) { + observer()->OnNewSuggestions( + this, downloads_category_, + GetMostRecentlyVisited(downloads_category_, std::move(download_items))); + } } void OfflinePageSuggestionsProvider::NotifyStatusChanged( + Category category, CategoryStatus new_status) { - if (category_status_ == new_status) - return; - category_status_ = new_status; + if (category == recent_tabs_category_) { + DCHECK_NE(CategoryStatus::NOT_PROVIDED, recent_tabs_status_); + if (recent_tabs_status_ == new_status) + return; + recent_tabs_status_ = new_status; + observer()->OnCategoryStatusChanged(this, category, new_status); + } else if (category == downloads_category_) { + DCHECK_NE(CategoryStatus::NOT_PROVIDED, downloads_status_); + if (downloads_status_ == new_status) + return; + downloads_status_ = new_status; + observer()->OnCategoryStatusChanged(this, category, new_status); + } else { + NOTREACHED() << "Unknown category " << category.id(); + } +} - observer()->OnCategoryStatusChanged(this, provided_category_, new_status); +ContentSuggestion OfflinePageSuggestionsProvider::ConvertOfflinePage( + Category category, + const OfflinePageItem& offline_page) const { + // TODO(pke): Make sure the URL is actually opened as an offline URL. + // Currently, the browser opens the offline URL and then immediately + // redirects to the online URL if the device is online. + ContentSuggestion suggestion( + MakeUniqueID(category, base::IntToString(offline_page.offline_id)), + offline_page.GetOfflineURL()); + + if (offline_page.title.empty()) { + // TODO(pke): Remove this fallback once the OfflinePageModel provides titles + // for all (relevant) OfflinePageItems. + suggestion.set_title(base::UTF8ToUTF16(offline_page.url.spec())); + } else { + suggestion.set_title(offline_page.title); + } + suggestion.set_publish_date(offline_page.creation_time); + suggestion.set_publisher_name(base::UTF8ToUTF16(offline_page.url.host())); + return suggestion; +} + +std::vector<ContentSuggestion> +OfflinePageSuggestionsProvider::GetMostRecentlyVisited( + Category category, + std::vector<const OfflinePageItem*> offline_page_items) const { + std::sort(offline_page_items.begin(), offline_page_items.end(), + OrderByMostRecentlyVisited()); + std::vector<ContentSuggestion> suggestions; + for (const OfflinePageItem* offline_page_item : offline_page_items) { + suggestions.push_back(ConvertOfflinePage(category, *offline_page_item)); + if (suggestions.size() == kMaxSuggestionsCount) + break; + } + return suggestions; +} + +std::set<std::string> OfflinePageSuggestionsProvider::ReadDismissedIDsFromPrefs( + const std::string& pref_name) const { + std::set<std::string> dismissed_ids; + const base::ListValue* list = pref_service_->GetList(pref_name); + for (const std::unique_ptr<base::Value>& value : *list) { + std::string dismissed_id; + bool success = value->GetAsString(&dismissed_id); + DCHECK(success) << "Failed to parse dismissed offline page ID from prefs"; + dismissed_ids.insert(dismissed_id); + } + return dismissed_ids; +} + +void OfflinePageSuggestionsProvider::StoreDismissedIDsToPrefs( + const std::string& pref_name, + const std::set<std::string>& dismissed_ids) { + base::ListValue list; + for (const std::string& dismissed_id : dismissed_ids) + list.AppendString(dismissed_id); + pref_service_->Set(pref_name, list); } } // namespace ntp_snippets
diff --git a/components/ntp_snippets/offline_pages/offline_page_suggestions_provider.h b/components/ntp_snippets/offline_pages/offline_page_suggestions_provider.h index 6266256f..862ea5d 100644 --- a/components/ntp_snippets/offline_pages/offline_page_suggestions_provider.h +++ b/components/ntp_snippets/offline_pages/offline_page_suggestions_provider.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_NTP_SNIPPETS_OFFLINE_PAGES_OFFLINE_PAGE_SUGGESTIONS_PROVIDER_H_ #define COMPONENTS_NTP_SNIPPETS_OFFLINE_PAGES_OFFLINE_PAGE_SUGGESTIONS_PROVIDER_H_ +#include <set> #include <string> #include <vector> @@ -17,6 +18,9 @@ #include "components/offline_pages/offline_page_model.h" #include "components/offline_pages/offline_page_types.h" +class PrefRegistrySimple; +class PrefService; + namespace gfx { class Image; } @@ -31,11 +35,17 @@ public offline_pages::OfflinePageModel::Observer { public: OfflinePageSuggestionsProvider( + bool recent_tabs_enabled, + bool downloads_enabled, + bool download_manager_ui_enabled, ContentSuggestionsProvider::Observer* observer, CategoryFactory* category_factory, - offline_pages::OfflinePageModel* offline_page_model); + offline_pages::OfflinePageModel* offline_page_model, + PrefService* pref_service); ~OfflinePageSuggestionsProvider() override; + static void RegisterProfilePrefs(PrefRegistrySimple* registry); + private: // ContentSuggestionsProvider implementation. std::vector<Category> GetProvidedCategories() override; @@ -62,14 +72,47 @@ void OnOfflinePagesLoaded( const offline_pages::MultipleOfflinePageItemResult& result); - // Updates the |category_status_| and notifies the |observer_|, if necessary. - void NotifyStatusChanged(CategoryStatus new_status); + // Updates the |category_status_| of the |category| and notifies the + // |observer_|, if necessary. + void NotifyStatusChanged(Category category, CategoryStatus new_status); - CategoryStatus category_status_; + // Converts an OfflinePageItem to a ContentSuggestion for the |category|. + ContentSuggestion ConvertOfflinePage( + Category category, + const offline_pages::OfflinePageItem& offline_page) const; + + // Gets the |kMaxSuggestionsCount| most recently visited OfflinePageItems from + // the list, orders them by last visit date and converts them to + // ContentSuggestions for the |category|. + std::vector<ContentSuggestion> GetMostRecentlyVisited( + Category category, + std::vector<const offline_pages::OfflinePageItem*> offline_page_items) + const; + + // Reads dismissed IDs from the pref with name |pref_name|. + std::set<std::string> ReadDismissedIDsFromPrefs( + const std::string& pref_name) const; + + // Writes |dismissed_ids| to the pref with name |pref_name|. + void StoreDismissedIDsToPrefs(const std::string& pref_name, + const std::set<std::string>& dismissed_ids); + + CategoryStatus recent_tabs_status_; + CategoryStatus downloads_status_; offline_pages::OfflinePageModel* offline_page_model_; - const Category provided_category_; + const Category recent_tabs_category_; + const Category downloads_category_; + + PrefService* pref_service_; + + std::set<std::string> dismissed_recent_tab_ids_; + std::set<std::string> dismissed_download_ids_; + + // Whether the Download Manager UI is enabled, in which case the More button + // for the Downloads section can redirect there. + const bool download_manager_ui_enabled_; DISALLOW_COPY_AND_ASSIGN(OfflinePageSuggestionsProvider); };
diff --git a/components/ntp_snippets/pref_names.cc b/components/ntp_snippets/pref_names.cc index 67e1dc6..21df19573 100644 --- a/components/ntp_snippets/pref_names.cc +++ b/components/ntp_snippets/pref_names.cc
@@ -16,5 +16,10 @@ const char kSnippetFetcherQuotaCount[] = "ntp.request_throttler.suggestion_fetcher.count"; +const char kDismissedRecentOfflineTabSuggestions[] = + "ntp_suggestions.offline_pages.recent_tabs.dismissed_ids"; +const char kDismissedDownloadSuggestions[] = + "ntp_suggestions.offline_pages.downloads.dismissed_ids"; + } // namespace prefs } // namespace ntp_snippets
diff --git a/components/ntp_snippets/pref_names.h b/components/ntp_snippets/pref_names.h index 4fdea4e..422260e 100644 --- a/components/ntp_snippets/pref_names.h +++ b/components/ntp_snippets/pref_names.h
@@ -18,6 +18,9 @@ // requests. extern const char kSnippetFetcherQuotaDay[]; +extern const char kDismissedRecentOfflineTabSuggestions[]; +extern const char kDismissedDownloadSuggestions[]; + } // namespace prefs } // namespace ntp_snippets
diff --git a/components/ntp_snippets_strings.grdp b/components/ntp_snippets_strings.grdp index f83018d..cda76f0 100644 --- a/components/ntp_snippets_strings.grdp +++ b/components/ntp_snippets_strings.grdp
@@ -14,6 +14,14 @@ Articles for you </message> + <message name="IDS_NTP_RECENT_TAB_SUGGESTIONS_SECTION_HEADER" desc="Header of the recent tabs section, which is a list of pages that the user recently viewed, displayed as cards on the New Tab Page."> + Recent tabs + </message> + + <message name="IDS_NTP_DOWNLOAD_SUGGESTIONS_SECTION_HEADER" desc="Header of the downloads section, which is a list of pages (or files) that the user downloaded, displayed as cards on the New Tab Page."> + Downloads + </message> + <message name="IDS_NTP_BOOKMARK_SUGGESTIONS_SECTION_HEADER" desc="Header of the bookmarks section, which is a list of the user's most recently used bookmarks displayed as cards on the New Tab Page."> Recent bookmarks </message>
diff --git a/components/offline_pages/background/request_coordinator.cc b/components/offline_pages/background/request_coordinator.cc index cde6ced..fe6e832 100644 --- a/components/offline_pages/background/request_coordinator.cc +++ b/components/offline_pages/background/request_coordinator.cc
@@ -90,38 +90,43 @@ weak_ptr_factory_.GetWeakPtr())); return true; } -void RequestCoordinator::GetQueuedRequests( - const std::string& client_namespace, - const QueuedRequestCallback& callback) { +void RequestCoordinator::GetAllRequests(const GetRequestsCallback& callback) { // Get all matching requests from the request queue, send them to our // callback. We bind the namespace and callback to the front of the callback // param set. queue_->GetRequests(base::Bind(&RequestCoordinator::GetQueuedRequestsCallback, - weak_ptr_factory_.GetWeakPtr(), - client_namespace, callback)); + weak_ptr_factory_.GetWeakPtr(), callback)); } -// For each request matching the client_namespace, return the ClientId. void RequestCoordinator::GetQueuedRequestsCallback( - const std::string& client_namespace, - const QueuedRequestCallback& callback, + const GetRequestsCallback& callback, RequestQueue::GetRequestsResult result, const std::vector<SavePageRequest>& requests) { - std::vector<ClientId> client_ids; - - for (const auto& request : requests) { - if (client_namespace == request.client_id().name_space) - client_ids.push_back(request.client_id()); - } - - callback.Run(client_ids); + callback.Run(requests); } void RequestCoordinator::RemoveRequests( - const std::vector<ClientId>& client_ids) { - queue_->RemoveRequestsByClientId( - client_ids, base::Bind(&RequestCoordinator::UpdateMultipleRequestCallback, - weak_ptr_factory_.GetWeakPtr())); + const std::vector<int64_t>& request_ids) { + queue_->RemoveRequests(request_ids, + base::Bind(&RequestCoordinator::RemoveRequestsCallback, + weak_ptr_factory_.GetWeakPtr())); +} + +void RequestCoordinator::PauseRequests( + const std::vector<int64_t>& request_ids) { + queue_->ChangeRequestsState( + request_ids, SavePageRequest::RequestState::PAUSED, + base::Bind(&RequestCoordinator::UpdateMultipleRequestCallback, + weak_ptr_factory_.GetWeakPtr())); +} + +void RequestCoordinator::ResumeRequests( + const std::vector<int64_t>& request_ids) { + queue_->ChangeRequestsState( + request_ids, SavePageRequest::RequestState::AVAILABLE, + base::Bind(&RequestCoordinator::UpdateMultipleRequestCallback, + weak_ptr_factory_.GetWeakPtr())); + // TODO: Should we also schedule a task, in case there is not one scheduled? } void RequestCoordinator::AddRequestResultCallback( @@ -156,6 +161,13 @@ } } +void RequestCoordinator::RemoveRequestsCallback( + const RequestQueue::UpdateMultipleRequestResults& results) { + // TODO(petewil): Today the RemoveRequests API does not come with a callback. + // Should we add one? Perhaps the notifications from the observer will be + // sufficient. +} + void RequestCoordinator::StopProcessing() { is_canceled_ = true; if (offliner_ && is_busy_) { @@ -310,10 +322,11 @@ // completed. Since we call MarkAttemptCompleted within the if branches, // the completed_attempt_count has not yet been updated when we are checking // the if condition. - queue_->RemoveRequest( - request.request_id(), - base::Bind(&RequestCoordinator::UpdateRequestCallback, - weak_ptr_factory_.GetWeakPtr(), request.client_id())); + std::vector<int64_t> remove_requests; + remove_requests.push_back(request.request_id()); + queue_->RemoveRequests( + remove_requests, base::Bind(&RequestCoordinator::RemoveRequestsCallback, + weak_ptr_factory_.GetWeakPtr())); } else { // If we failed, but are not over the limit, update the request in the // queue.
diff --git a/components/offline_pages/background/request_coordinator.h b/components/offline_pages/background/request_coordinator.h index 5c6c03b..2273da55 100644 --- a/components/offline_pages/background/request_coordinator.h +++ b/components/offline_pages/background/request_coordinator.h
@@ -50,21 +50,27 @@ bool SavePageLater( const GURL& url, const ClientId& client_id, bool user_reqeusted); - // Remove a list of requests by |client_id|. This removes requests from the + // Remove a list of requests by |request_id|. This removes requests from the // request queue, but does not cancel an in-progress pre-render. // TODO(petewil): Add code to cancel an in-progress pre-render. - void RemoveRequests(const std::vector<ClientId>& client_ids); + void RemoveRequests(const std::vector<int64_t>& request_ids); - // Callback that receives the response for GetQueuedRequests. Client must + // Pause a list of requests by |request_id|. This will change the state + // in the request queue so the request cannot be started. + // TODO(petewil): Add code to cancel an in-progress pre-render. + void PauseRequests(const std::vector<int64_t>& request_ids); + + // Resume a list of previously paused requests, making them available. + void ResumeRequests(const std::vector<int64_t>& request_ids); + + // Callback that receives the response for GetAllRequests. Client must // copy the result right away, it goes out of scope at the end of the // callback. - typedef base::Callback<void(const std::vector<ClientId>&)> - QueuedRequestCallback; + typedef base::Callback<void(const std::vector<SavePageRequest>&)> + GetRequestsCallback; - // For a client namespace, get the ClientId of all requests for that - // namespace. - void GetQueuedRequests(const std::string& client_namespace, - const QueuedRequestCallback& callback); + // Get all save page request items in the callback. + void GetAllRequests(const GetRequestsCallback& callback); // Starts processing of one or more queued save page later requests. // Returns whether processing was started and that caller should expect @@ -112,9 +118,8 @@ private: // Receives the results of a get from the request queue, and turns that into - // ClientId objects for the caller of GetQueuedRequests. - void GetQueuedRequestsCallback(const std::string& client_namespace, - const QueuedRequestCallback& callback, + // SavePageRequest objects for the caller of GetQueuedRequests. + void GetQueuedRequestsCallback(const GetRequestsCallback& callback, RequestQueue::GetRequestsResult result, const std::vector<SavePageRequest>& requests); @@ -128,6 +133,9 @@ void UpdateMultipleRequestCallback(RequestQueue::UpdateRequestResult result); + void RemoveRequestsCallback( + const RequestQueue::UpdateMultipleRequestResults& results); + // Callback from the request picker when it has chosen our next request. void RequestPicked(const SavePageRequest& request);
diff --git a/components/offline_pages/background/request_coordinator_unittest.cc b/components/offline_pages/background/request_coordinator_unittest.cc index 6ef185c..5cda745 100644 --- a/components/offline_pages/background/request_coordinator_unittest.cc +++ b/components/offline_pages/background/request_coordinator_unittest.cc
@@ -162,7 +162,7 @@ const std::vector<SavePageRequest>& requests); // Callback for getting request statuses. - void GetQueuedRequestsDone(const std::vector<ClientId>& client_ids); + void GetQueuedRequestsDone(const std::vector<SavePageRequest>& requests); void SendOfflinerDoneCallback(const SavePageRequest& request, Offliner::RequestStatus status); @@ -175,10 +175,6 @@ return last_requests_; } - const std::vector<ClientId>& last_client_ids() const { - return last_client_ids_; - } - void EnableOfflinerCallback(bool enable) { offliner_->enable_callback(enable); } @@ -208,7 +204,6 @@ private: RequestQueue::GetRequestsResult last_get_requests_result_; std::vector<SavePageRequest> last_requests_; - std::vector<ClientId> last_client_ids_; scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; base::ThreadTaskRunnerHandle task_runner_handle_; std::unique_ptr<RequestCoordinator> coordinator_; @@ -253,8 +248,8 @@ } void RequestCoordinatorTest::GetQueuedRequestsDone( - const std::vector<ClientId>& client_ids) { - last_client_ids_ = client_ids; + const std::vector<SavePageRequest>& requests) { + last_requests_ = requests; waiter_.Signal(); } @@ -628,7 +623,7 @@ EXPECT_EQ(1UL, last_requests().size()); } -TEST_F(RequestCoordinatorTest, GetQueuedRequests) { +TEST_F(RequestCoordinatorTest, GetAllRequests) { // Add two requests to the queue. offline_pages::SavePageRequest request1(kRequestId1, kUrl1, kClientId1, base::Time::Now(), kUserRequested); @@ -643,10 +638,8 @@ PumpLoop(); // Start the async status fetching. - coordinator()->GetQueuedRequests( - kClientNamespace, - base::Bind(&RequestCoordinatorTest::GetQueuedRequestsDone, - base::Unretained(this))); + coordinator()->GetAllRequests(base::Bind( + &RequestCoordinatorTest::GetQueuedRequestsDone, base::Unretained(this))); PumpLoop(); // Wait for async get to finish. @@ -654,9 +647,9 @@ PumpLoop(); // Check that the statuses found in the callback match what we expect. - EXPECT_EQ(2UL, last_client_ids().size()); - EXPECT_EQ(kId1, last_client_ids().at(0).id); - EXPECT_EQ(kId2, last_client_ids().at(1).id); + EXPECT_EQ(2UL, last_requests().size()); + EXPECT_EQ(kRequestId1, last_requests().at(0).request_id()); + EXPECT_EQ(kRequestId2, last_requests().at(1).request_id()); } } // namespace offline_pages
diff --git a/components/offline_pages/background/request_picker.cc b/components/offline_pages/background/request_picker.cc index 47bff56..84b73056 100644 --- a/components/offline_pages/background/request_picker.cc +++ b/components/offline_pages/background/request_picker.cc
@@ -121,6 +121,10 @@ if (request.completed_attempt_count() >= policy_->GetMaxCompletedTries()) return false; + // If the request is paused, do not consider it. + if (request.request_state() == SavePageRequest::RequestState::PAUSED) + return false; + // If the request is expired, do not consider it. // TODO(petewil): We need to remove this from the queue. base::TimeDelta requestAge = base::Time::Now() - request.creation_time();
diff --git a/components/offline_pages/background/request_queue.cc b/components/offline_pages/background/request_queue.cc index fd4cc54a..6d1e8bf 100644 --- a/components/offline_pages/background/request_queue.cc +++ b/components/offline_pages/background/request_queue.cc
@@ -50,14 +50,10 @@ // Completes the remove request call. -void RemoveRequestDone(const RequestQueue::UpdateRequestCallback& callback, - bool success, - int deleted_requests_count) { - DCHECK_EQ(1, deleted_requests_count); - RequestQueue::UpdateRequestResult result = - success ? RequestQueue::UpdateRequestResult::SUCCESS - : RequestQueue::UpdateRequestResult::STORE_FAILURE; - callback.Run(result); +void RemoveRequestsDone( + const RequestQueue::RemoveRequestsCallback& callback, + const RequestQueue::UpdateMultipleRequestResults& results) { + callback.Run(results); } } // namespace @@ -129,17 +125,17 @@ base::Bind(&UpdateRequestDone, update_callback)); } -void RequestQueue::RemoveRequest(int64_t request_id, - const UpdateRequestCallback& callback) { - std::vector<int64_t> request_ids{request_id}; - store_->RemoveRequests(request_ids, base::Bind(RemoveRequestDone, callback)); +void RequestQueue::RemoveRequests(const std::vector<int64_t>& request_ids, + const RemoveRequestsCallback& callback) { + store_->RemoveRequests(request_ids, base::Bind(RemoveRequestsDone, callback)); } -void RequestQueue::RemoveRequestsByClientId( - const std::vector<ClientId>& client_ids, +void RequestQueue::ChangeRequestsState( + const std::vector<int64_t>& request_ids, + const SavePageRequest::RequestState new_state, const UpdateRequestCallback& callback) { - store_->RemoveRequestsByClientId(client_ids, - base::Bind(RemoveRequestDone, callback)); + store_->ChangeRequestsState(request_ids, new_state, + base::Bind(UpdateRequestDone, callback)); } void RequestQueue::PurgeRequests(const PurgeRequestsCallback& callback) {}
diff --git a/components/offline_pages/background/request_queue.h b/components/offline_pages/background/request_queue.h index 429c375..ca1e4d7 100644 --- a/components/offline_pages/background/request_queue.h +++ b/components/offline_pages/background/request_queue.h
@@ -14,12 +14,12 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "components/offline_pages/background/save_page_request.h" #include "components/offline_pages/offline_page_item.h" namespace offline_pages { class RequestQueueStore; -class SavePageRequest; // Class responsible for managing save page requests. class RequestQueue { @@ -43,6 +43,10 @@ // exist. }; + // Type for a pair of request_id and result. + typedef std::vector<std::pair<int64_t, UpdateRequestResult>> + UpdateMultipleRequestResults; + // Callback used for |GetRequests|. typedef base::Callback<void(GetRequestsResult, const std::vector<SavePageRequest>&)> @@ -52,9 +56,13 @@ typedef base::Callback<void(AddRequestResult, const SavePageRequest& request)> AddRequestCallback; - // Callback used by |UdpateRequest| and |RemoveRequest|. + // Callback used by |UdpateRequest|. typedef base::Callback<void(UpdateRequestResult)> UpdateRequestCallback; + // Callback used by |RemoveRequests|. + typedef base::Callback<void(const UpdateMultipleRequestResults& results)> + RemoveRequestsCallback; + explicit RequestQueue(std::unique_ptr<RequestQueueStore> store); ~RequestQueue(); @@ -74,14 +82,20 @@ void UpdateRequest(const SavePageRequest& request, const UpdateRequestCallback& callback); - // Removes the request matching the |request_id|. Result is returned through - // |callback|. - void RemoveRequest(int64_t request_id, const UpdateRequestCallback& callback); + // Removes the requests matching the |request_ids|. Result is returned through + // |callback|. If a request id cannot be removed, this will still remove the + // others. + void RemoveRequests(const std::vector<int64_t>& request_ids, + const RemoveRequestsCallback& callback); - // Removes the requests matching the |client_ids|. Results are returned - // through |callback|. - void RemoveRequestsByClientId(const std::vector<ClientId>& client_id, - const UpdateRequestCallback& callback); + // Changes the state to |new_state_ for requests matching the + // |request_ids|. Results are returned through |callback|. + // TODO(petewil): Instead of having one function per property, + // modify this to have a single update function that updates an entire + // request, and doesn't need to care what updates. + void ChangeRequestsState(const std::vector<int64_t>& request_ids, + const SavePageRequest::RequestState new_state, + const UpdateRequestCallback& callback); void GetForUpdateDone( const RequestQueue::UpdateRequestCallback& update_callback,
diff --git a/components/offline_pages/background/request_queue_in_memory_store.cc b/components/offline_pages/background/request_queue_in_memory_store.cc index 32219a9..e6348e8 100644 --- a/components/offline_pages/background/request_queue_in_memory_store.cc +++ b/components/offline_pages/background/request_queue_in_memory_store.cc
@@ -4,8 +4,6 @@ #include "components/offline_pages/background/request_queue_in_memory_store.h" -#include <set> - #include "base/bind.h" #include "base/location.h" #include "base/threading/thread_task_runner_handle.h" @@ -40,37 +38,43 @@ void RequestQueueInMemoryStore::RemoveRequests( const std::vector<int64_t>& request_ids, const RemoveCallback& callback) { - int count = 0; + RequestQueue::UpdateMultipleRequestResults results; + RequestQueue::UpdateRequestResult result; RequestsMap::iterator iter; for (auto request_id : request_ids) { iter = requests_.find(request_id); if (iter != requests_.end()) { requests_.erase(iter); - ++count; + result = RequestQueue::UpdateRequestResult::SUCCESS; + } else { + result = RequestQueue::UpdateRequestResult::REQUEST_DOES_NOT_EXIST; } + results.push_back(std::make_pair(request_id, result)); } - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(callback, true, count)); + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + base::Bind(callback, results)); } -void RequestQueueInMemoryStore::RemoveRequestsByClientId( - const std::vector<ClientId>& client_ids, - const RemoveCallback& callback) { +void RequestQueueInMemoryStore::ChangeRequestsState( + const std::vector<int64_t>& request_ids, + const SavePageRequest::RequestState new_state, + const UpdateCallback& callback) { int count = 0; - std::set<ClientId> client_id_set(client_ids.begin(), client_ids.end()); - for (auto iter = requests_.begin(); iter != requests_.end(); ) { - if (client_id_set.find(iter->second.client_id()) != client_id_set.end()) { - requests_.erase(iter++); + for (int64_t request_id : request_ids) { + auto pair = requests_.find(request_id); + if (pair != requests_.end()) { ++count; - } else { - ++iter; + pair->second.set_request_state(new_state); } } - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(callback, true, count)); + RequestQueueStore::UpdateStatus status = + count > 0 ? UpdateStatus::UPDATED : UpdateStatus::FAILED; + + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + base::Bind(callback, status)); } void RequestQueueInMemoryStore::Reset(const ResetCallback& callback) {
diff --git a/components/offline_pages/background/request_queue_in_memory_store.h b/components/offline_pages/background/request_queue_in_memory_store.h index cc02921c..efab1397 100644 --- a/components/offline_pages/background/request_queue_in_memory_store.h +++ b/components/offline_pages/background/request_queue_in_memory_store.h
@@ -11,11 +11,10 @@ #include "base/macros.h" #include "components/offline_pages/background/request_queue_store.h" +#include "components/offline_pages/background/save_page_request.h" namespace offline_pages { -class SavePageRequest; - // Interface for classes storing save page requests. class RequestQueueInMemoryStore : public RequestQueueStore { public: @@ -26,14 +25,17 @@ void GetRequests(const GetRequestsCallback& callback) override; void AddOrUpdateRequest(const SavePageRequest& request, const UpdateCallback& callback) override; + // Remove requests by request ID. In case the |request_ids| is empty, the // result will be true, but the count of deleted pages will be 0. void RemoveRequests(const std::vector<int64_t>& request_ids, const RemoveCallback& callback) override; - // Remove requests by client ID. In case the |client_ids| is empty, the - // result will be true, but the count of deleted pages will be 0. - void RemoveRequestsByClientId(const std::vector<ClientId>& client_ids, - const RemoveCallback& callback) override; + + // Set the state of associated requests to |new_state|. + void ChangeRequestsState(const std::vector<int64_t>& request_ids, + const SavePageRequest::RequestState new_state, + const UpdateCallback& callback) override; + void Reset(const ResetCallback& callback) override; private:
diff --git a/components/offline_pages/background/request_queue_store.h b/components/offline_pages/background/request_queue_store.h index d4a9d35..c9b0af9 100644 --- a/components/offline_pages/background/request_queue_store.h +++ b/components/offline_pages/background/request_queue_store.h
@@ -9,12 +9,12 @@ #include <vector> #include "base/callback.h" +#include "components/offline_pages/background/request_queue.h" +#include "components/offline_pages/background/save_page_request.h" #include "components/offline_pages/offline_page_item.h" namespace offline_pages { -class SavePageRequest; - // Interface for classes storing save page requests. class RequestQueueStore { public: @@ -23,14 +23,16 @@ UPDATED, // Request was updated successfully. FAILED, // Add or update attempt failed. }; + // TODO(petewil): What if no items were updated? Maybe this should work more + // like DeleteCallback, passing pairs of request_id and status. typedef base::Callback<void( bool /* success */, const std::vector<SavePageRequest>& /* requests */)> GetRequestsCallback; typedef base::Callback<void(UpdateStatus)> UpdateCallback; - typedef base::Callback<void(bool /* success */, - int /* number of deleted requests */)> + typedef base::Callback<void( + const RequestQueue::UpdateMultipleRequestResults&)> RemoveCallback; typedef base::Callback<void(bool /* success */)> ResetCallback; @@ -52,14 +54,12 @@ virtual void RemoveRequests(const std::vector<int64_t>& request_ids, const RemoveCallback& callback) = 0; - // Asynchronously removes requests from the store using their ClientIds. - // Result of the update, and a number of removed pages is passed in the - // callback. Result of remove should be false, when one of the provided items - // couldn't be deleted, e.g. because it was missing. In case client_ids is - // empty, though this will return true, but the count of deleted pages will be - // 0. - virtual void RemoveRequestsByClientId(const std::vector<ClientId>& client_ids, - const RemoveCallback& callback) = 0; + // Asynchronously changes the state of requests from the store using their + // request id. + virtual void ChangeRequestsState( + const std::vector<int64_t>& request_ids, + const SavePageRequest::RequestState new_state, + const UpdateCallback& callback) = 0; // Resets the store. virtual void Reset(const ResetCallback& callback) = 0;
diff --git a/components/offline_pages/background/request_queue_store_sql.cc b/components/offline_pages/background/request_queue_store_sql.cc index 264b2ac..ad007dc 100644 --- a/components/offline_pages/background/request_queue_store_sql.cc +++ b/components/offline_pages/background/request_queue_store_sql.cc
@@ -66,61 +66,69 @@ return statement.Run(); } -bool DeleteRequestByClientId(sql::Connection* db, const ClientId& client_id) { - const char kSql[] = "DELETE FROM " REQUEST_QUEUE_TABLE_NAME - " WHERE client_namespace=? AND client_id=?"; +bool ChangeRequestState(sql::Connection* db, + const int64_t request_id, + const SavePageRequest::RequestState new_state) { + const char kSql[] = "UPDATE " REQUEST_QUEUE_TABLE_NAME + " SET state=?" + " WHERE request_id=?"; sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql)); - statement.BindString(0, client_id.name_space); - statement.BindString(1, client_id.id); - DVLOG(2) << kSql << " client_namespace " << client_id.name_space - << " client_id " << client_id.id; + statement.BindInt64(0, static_cast<int64_t>(new_state)); + statement.BindInt64(1, request_id); return statement.Run(); } bool DeleteRequestsByIds(sql::Connection* db, const std::vector<int64_t>& request_ids, - int* count) { - DCHECK(count); + RequestQueue::UpdateMultipleRequestResults& results) { // If you create a transaction but don't Commit() it is automatically // rolled back by its destructor when it falls out of scope. sql::Transaction transaction(db); - if (!transaction.Begin()) + if (!transaction.Begin()) { + for (int64_t request_id : request_ids) + results.push_back(std::make_pair( + request_id, RequestQueue::UpdateRequestResult::STORE_FAILURE)); return false; - - *count = 0; - for (auto request_id : request_ids) { - if (!DeleteRequestById(db, request_id)) - return false; - *count += db->GetLastChangeCount(); } - if (!transaction.Commit()) + for (auto request_id : request_ids) { + RequestQueue::UpdateRequestResult result; + if (DeleteRequestById(db, request_id)) + result = RequestQueue::UpdateRequestResult::SUCCESS; + else + result = RequestQueue::UpdateRequestResult::REQUEST_DOES_NOT_EXIST; + results.push_back(std::make_pair(request_id, result)); + } + + if (!transaction.Commit()) { + results.clear(); + for (int64_t request_id : request_ids) + results.push_back(std::make_pair( + request_id, RequestQueue::UpdateRequestResult::STORE_FAILURE)); return false; + } return true; } -bool DeleteRequestsByClientIds(sql::Connection* db, - const std::vector<ClientId>& client_ids, - int* count) { - DCHECK(count); +RequestQueueStore::UpdateStatus ChangeRequestsState( + sql::Connection* db, + const std::vector<int64_t>& request_ids, + SavePageRequest::RequestState new_state) { // If you create a transaction but don't Commit() it is automatically // rolled back by its destructor when it falls out of scope. sql::Transaction transaction(db); if (!transaction.Begin()) - return false; - - *count = 0; - for (const auto& client_id : client_ids) { - if (!DeleteRequestByClientId(db, client_id)) - return false; - *count += db->GetLastChangeCount(); + return RequestQueueStore::UpdateStatus::FAILED; + for (const auto& request_id : request_ids) { + if (!ChangeRequestState(db, request_id, new_state)) + return RequestQueueStore::UpdateStatus::FAILED; } if (!transaction.Commit()) - return false; + return RequestQueueStore::UpdateStatus::FAILED; - return true; + return RequestQueueStore::UpdateStatus::UPDATED; } // Create a save page request from a SQL result. Expects complete rows with @@ -267,26 +275,23 @@ scoped_refptr<base::SingleThreadTaskRunner> runner, const std::vector<int64_t>& request_ids, const RemoveCallback& callback) { + RequestQueue::UpdateMultipleRequestResults results; // TODO(fgorski): add UMA metrics here. - int count = 0; - if (DeleteRequestsByIds(db, request_ids, &count)) - runner->PostTask(FROM_HERE, base::Bind(callback, true, count)); - else - runner->PostTask(FROM_HERE, base::Bind(callback, false, 0)); + DeleteRequestsByIds(db, request_ids, results); + runner->PostTask(FROM_HERE, base::Bind(callback, results)); } // static -void RequestQueueStoreSQL::RemoveRequestsByClientIdSync( +void RequestQueueStoreSQL::ChangeRequestsStateSync( sql::Connection* db, scoped_refptr<base::SingleThreadTaskRunner> runner, - const std::vector<ClientId>& client_ids, - const RemoveCallback& callback) { + const std::vector<int64_t>& request_ids, + const SavePageRequest::RequestState new_state, + const UpdateCallback& callback) { // TODO(fgorski): add UMA metrics here. - int count = 0; - if (DeleteRequestsByClientIds(db, client_ids, &count)) - runner->PostTask(FROM_HERE, base::Bind(callback, true, count)); - else - runner->PostTask(FROM_HERE, base::Bind(callback, false, 0)); + RequestQueueStore::UpdateStatus status = + offline_pages::ChangeRequestsState(db, request_ids, new_state); + runner->PostTask(FROM_HERE, base::Bind(callback, status)); } // static @@ -303,15 +308,22 @@ runner->PostTask(FROM_HERE, base::Bind(callback, success)); } -void RequestQueueStoreSQL::GetRequests(const GetRequestsCallback& callback) { +bool RequestQueueStoreSQL::CheckDb(const base::Closure& callback) { DCHECK(db_.get()); if (!db_.get()) { // Nothing to do, but post a callback instead of calling directly // to preserve the async style behavior to prevent bugs. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(callback, false, std::vector<SavePageRequest>())); - return; + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + base::Bind(callback)); + return false; } + return true; +} + +void RequestQueueStoreSQL::GetRequests(const GetRequestsCallback& callback) { + DCHECK(db_.get()); + if (!CheckDb(base::Bind(callback, false, std::vector<SavePageRequest>()))) + return; background_task_runner_->PostTask( FROM_HERE, base::Bind(&RequestQueueStoreSQL::GetRequestsSync, db_.get(), @@ -321,13 +333,8 @@ void RequestQueueStoreSQL::AddOrUpdateRequest(const SavePageRequest& request, const UpdateCallback& callback) { DCHECK(db_.get()); - if (!db_.get()) { - // Nothing to do, but post a callback instead of calling directly - // to preserve the async style behavior to prevent bugs. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(callback, UpdateStatus::FAILED)); + if (!CheckDb(base::Bind(callback, UpdateStatus::FAILED))) return; - } background_task_runner_->PostTask( FROM_HERE, @@ -335,21 +342,18 @@ base::ThreadTaskRunnerHandle::Get(), request, callback)); } -// TODO(petewil): This is unused, since request_coordinator doesn't keep -// request_ids, and neither do clients. Plan is to remove this API in a future -// changelist. If we do discover a need to keep it, name it // RemoveRequestsByRequestId to be more parallell with RemoveRequestsByClientId. void RequestQueueStoreSQL::RemoveRequests( const std::vector<int64_t>& request_ids, const RemoveCallback& callback) { - DCHECK(db_.get()); - if (!db_.get()) { - // Nothing to do, but post a callback instead of calling directly - // to preserve the async style behavior to prevent bugs. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(callback, false, 0)); + // Set up a failed set of results in case we fail the DB check. + RequestQueue::UpdateMultipleRequestResults results; + for (int64_t request_id : request_ids) + results.push_back(std::make_pair( + request_id, RequestQueue::UpdateRequestResult::STORE_FAILURE)); + + if (!CheckDb(base::Bind(callback, results))) return; - } background_task_runner_->PostTask( FROM_HERE, @@ -357,33 +361,23 @@ base::ThreadTaskRunnerHandle::Get(), request_ids, callback)); } -void RequestQueueStoreSQL::RemoveRequestsByClientId( - const std::vector<ClientId>& client_ids, - const RemoveCallback& callback) { - DCHECK(db_.get()); - if (!db_.get()) { - // Nothing to do, but post a callback instead of calling directly - // to preserve the async style behavior to prevent bugs. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(callback, false, 0)); +void RequestQueueStoreSQL::ChangeRequestsState( + const std::vector<int64_t>& request_ids, + const SavePageRequest::RequestState new_state, + const UpdateCallback& callback) { + if (!CheckDb(base::Bind(callback, UpdateStatus::FAILED))) return; - } background_task_runner_->PostTask( - FROM_HERE, - base::Bind(&RequestQueueStoreSQL::RemoveRequestsByClientIdSync, db_.get(), - base::ThreadTaskRunnerHandle::Get(), client_ids, callback)); + FROM_HERE, base::Bind(&RequestQueueStoreSQL::ChangeRequestsStateSync, + db_.get(), base::ThreadTaskRunnerHandle::Get(), + request_ids, new_state, callback)); } void RequestQueueStoreSQL::Reset(const ResetCallback& callback) { DCHECK(db_.get()); - if (!db_.get()) { - // Nothing to do, but post a callback instead of calling directly - // to preserve the async style behavior to prevent bugs. - base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, - base::Bind(callback, false)); + if (!CheckDb(base::Bind(callback, false))) return; - } background_task_runner_->PostTask( FROM_HERE,
diff --git a/components/offline_pages/background/request_queue_store_sql.h b/components/offline_pages/background/request_queue_store_sql.h index 18f6e879..10631dc6 100644 --- a/components/offline_pages/background/request_queue_store_sql.h +++ b/components/offline_pages/background/request_queue_store_sql.h
@@ -38,8 +38,9 @@ const UpdateCallback& callback) override; void RemoveRequests(const std::vector<int64_t>& request_ids, const RemoveCallback& callback) override; - void RemoveRequestsByClientId(const std::vector<ClientId>& client_ids, - const RemoveCallback& callback) override; + void ChangeRequestsState(const std::vector<int64_t>& request_ids, + const SavePageRequest::RequestState new_state, + const UpdateCallback& callback) override; void Reset(const ResetCallback& callback) override; private: @@ -61,16 +62,20 @@ scoped_refptr<base::SingleThreadTaskRunner> runner, const std::vector<int64_t>& request_ids, const RemoveCallback& callback); - static void RemoveRequestsByClientIdSync( + static void ChangeRequestsStateSync( sql::Connection* db, scoped_refptr<base::SingleThreadTaskRunner> runner, - const std::vector<ClientId>& client_ids, - const RemoveCallback& callback); + const std::vector<int64_t>& request_ids, + const SavePageRequest::RequestState new_state, + const UpdateCallback& callback); static void ResetSync(sql::Connection* db, const base::FilePath& db_file_path, scoped_refptr<base::SingleThreadTaskRunner> runner, const ResetCallback& callback); + // Helper functions to return immediately if no database is found. + bool CheckDb(const base::Closure& callback); + // Used to initialize DB connection. static void OpenConnectionSync( sql::Connection* db,
diff --git a/components/offline_pages/background/request_queue_store_unittest.cc b/components/offline_pages/background/request_queue_store_unittest.cc index 691a52a..23406d4 100644 --- a/components/offline_pages/background/request_queue_store_unittest.cc +++ b/components/offline_pages/background/request_queue_store_unittest.cc
@@ -11,6 +11,7 @@ #include "base/files/scoped_temp_dir.h" #include "base/test/test_simple_task_runner.h" #include "base/threading/thread_task_runner_handle.h" +#include "components/offline_pages/background/request_queue.h" #include "components/offline_pages/background/request_queue_in_memory_store.h" #include "components/offline_pages/background/request_queue_store_sql.h" #include "components/offline_pages/background/save_page_request.h" @@ -67,13 +68,16 @@ // Callback used for add/update request. void AddOrUpdateDone(UpdateStatus result); // Callback used for remove requests. - void RemoveDone(bool result, int count); + void RemoveDone(const RequestQueue::UpdateMultipleRequestResults& results); // Callback used for reset. void ResetDone(bool result); LastResult last_result() const { return last_result_; } UpdateStatus last_update_status() const { return last_update_status_; } - int last_remove_count() const { return last_remove_count_; } + const RequestQueue::UpdateMultipleRequestResults& last_remove_results() + const { + return last_remove_results_; + } const std::vector<SavePageRequest>& last_requests() const { return last_requests_; } @@ -84,7 +88,7 @@ private: LastResult last_result_; UpdateStatus last_update_status_; - int last_remove_count_; + RequestQueue::UpdateMultipleRequestResults last_remove_results_; std::vector<SavePageRequest> last_requests_; scoped_refptr<base::TestSimpleTaskRunner> task_runner_; @@ -94,7 +98,6 @@ RequestQueueStoreTestBase::RequestQueueStoreTestBase() : last_result_(LastResult::kNone), last_update_status_(UpdateStatus::FAILED), - last_remove_count_(0), task_runner_(new base::TestSimpleTaskRunner), task_runner_handle_(task_runner_) { EXPECT_TRUE(temp_directory_.CreateUniqueTempDir()); @@ -112,7 +115,7 @@ void RequestQueueStoreTestBase::ClearResults() { last_result_ = LastResult::kNone; last_update_status_ = UpdateStatus::FAILED; - last_remove_count_ = 0; + last_remove_results_.clear(); last_requests_.clear(); } @@ -127,9 +130,9 @@ last_update_status_ = status; } -void RequestQueueStoreTestBase::RemoveDone(bool result, int count) { - last_result_ = result ? LastResult::kTrue : LastResult::kFalse; - last_remove_count_ = count; +void RequestQueueStoreTestBase::RemoveDone( + const RequestQueue::UpdateMultipleRequestResults& results) { + last_remove_results_ = results; } void RequestQueueStoreTestBase::ResetDone(bool result) { @@ -257,135 +260,118 @@ ASSERT_TRUE(updated_request == this->last_requests()[0]); } -TYPED_TEST(RequestQueueStoreTest, RemoveRequest) { +TYPED_TEST(RequestQueueStoreTest, RemoveRequests) { std::unique_ptr<RequestQueueStore> store(this->BuildStore()); base::Time creation_time = base::Time::Now(); - SavePageRequest original_request( - kRequestId, kUrl, kClientId, creation_time, kUserRequested); - store->AddOrUpdateRequest( - original_request, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, - base::Unretained(this))); - this->PumpLoop(); - this->ClearResults(); - - std::vector<int64_t> request_ids{kRequestId}; - store->RemoveRequests(request_ids, - base::Bind(&RequestQueueStoreTestBase::RemoveDone, - base::Unretained(this))); - ASSERT_EQ(LastResult::kNone, this->last_result()); - ASSERT_EQ(0, this->last_remove_count()); - this->PumpLoop(); - ASSERT_EQ(LastResult::kTrue, this->last_result()); - ASSERT_EQ(1, this->last_remove_count()); - this->ClearResults(); - - store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, - base::Unretained(this))); - this->PumpLoop(); - ASSERT_EQ(LastResult::kTrue, this->last_result()); - ASSERT_TRUE(this->last_requests().empty()); - this->ClearResults(); - - // Try to remove a request that is not in the queue. - store->RemoveRequests(request_ids, - base::Bind(&RequestQueueStoreTestBase::RemoveDone, - base::Unretained(this))); - ASSERT_EQ(LastResult::kNone, this->last_result()); - ASSERT_EQ(0, this->last_remove_count()); - this->PumpLoop(); - ASSERT_EQ(LastResult::kTrue, this->last_result()); - ASSERT_EQ(0, this->last_remove_count()); -} - -TYPED_TEST(RequestQueueStoreTest, RemoveRequestByClientId) { - std::unique_ptr<RequestQueueStore> store(this->BuildStore()); - base::Time creation_time = base::Time::Now(); - - // Create requests and add them to the queue. SavePageRequest request1(kRequestId, kUrl, kClientId, creation_time, - kUserRequested); + kUserRequested); + store->AddOrUpdateRequest( + request1, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, + base::Unretained(this))); SavePageRequest request2(kRequestId2, kUrl2, kClientId2, creation_time, - kUserRequested); - store->AddOrUpdateRequest( - request1, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, - base::Unretained(this))); + kUserRequested); store->AddOrUpdateRequest( request2, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, base::Unretained(this))); this->PumpLoop(); this->ClearResults(); - // Remove a request. - std::vector<ClientId> client_ids_to_delete{kClientId}; - store->RemoveRequestsByClientId( - client_ids_to_delete, - base::Bind( - &RequestQueueStoreTestBase::RemoveDone, base::Unretained(this))); - ASSERT_EQ(LastResult::kNone, this->last_result()); - ASSERT_EQ(0, this->last_remove_count()); + std::vector<int64_t> request_ids{kRequestId, kRequestId2}; + store->RemoveRequests(request_ids, + base::Bind(&RequestQueueStoreTestBase::RemoveDone, + base::Unretained(this))); + ASSERT_EQ(0ul, this->last_remove_results().size()); this->PumpLoop(); - ASSERT_EQ(LastResult::kTrue, this->last_result()); - ASSERT_EQ(1, this->last_remove_count()); + ASSERT_EQ(2ul, this->last_remove_results().size()); + ASSERT_EQ(RequestQueue::UpdateRequestResult::SUCCESS, + this->last_remove_results().at(0).second); + ASSERT_EQ(RequestQueue::UpdateRequestResult::SUCCESS, + this->last_remove_results().at(1).second); this->ClearResults(); - // Check to see what remains in the queue. Removed request should be gone. store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, base::Unretained(this))); this->PumpLoop(); ASSERT_EQ(LastResult::kTrue, this->last_result()); - // The other request should still be in the queue. - ASSERT_EQ(1UL, this->last_requests().size()); - ASSERT_EQ(kClientId2, this->last_requests().at(0).client_id()); + ASSERT_TRUE(this->last_requests().empty()); this->ClearResults(); // Try to remove a request that is not in the queue. - store->RemoveRequestsByClientId( - client_ids_to_delete, - base::Bind( - &RequestQueueStoreTestBase::RemoveDone, base::Unretained(this))); + store->RemoveRequests(request_ids, + base::Bind(&RequestQueueStoreTestBase::RemoveDone, + base::Unretained(this))); + ASSERT_EQ(LastResult::kNone, this->last_result()); this->PumpLoop(); - ASSERT_EQ(LastResult::kTrue, this->last_result()); - ASSERT_EQ(0, this->last_remove_count()); + ASSERT_EQ(2ul, this->last_remove_results().size()); + // Since the SQL statement returns true on a delete of an item that isn't + // present, SQL is returning SUCCESS, but the memory is returning + // REQUEST_DOES_NOT_EXIST, so we just check that the result is not failure. + ASSERT_NE(RequestQueue::UpdateRequestResult::STORE_FAILURE, + this->last_remove_results().at(0).second); + ASSERT_NE(RequestQueue::UpdateRequestResult::STORE_FAILURE, + this->last_remove_results().at(1).second); } -TYPED_TEST(RequestQueueStoreTest, RemoveRequestWithSameClientId) { +TYPED_TEST(RequestQueueStoreTest, PauseAndResumeRequest) { std::unique_ptr<RequestQueueStore> store(this->BuildStore()); base::Time creation_time = base::Time::Now(); - // Create requests and add them to the queue. + // Create request and add it to the queue. SavePageRequest request1(kRequestId, kUrl, kClientId, creation_time, - kUserRequested); - SavePageRequest request2(kRequestId2, kUrl2, kClientId, creation_time, - kUserRequested); + kUserRequested); store->AddOrUpdateRequest( request1, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, base::Unretained(this))); - store->AddOrUpdateRequest( - request2, base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, - base::Unretained(this))); this->PumpLoop(); this->ClearResults(); - // Remove a request. - std::vector<ClientId> client_ids_to_delete{kClientId}; - store->RemoveRequestsByClientId( - client_ids_to_delete, - base::Bind( - &RequestQueueStoreTestBase::RemoveDone, base::Unretained(this))); + // Pause a request. + std::vector<int64_t> request_ids{kRequestId}; + store->ChangeRequestsState( + request_ids, SavePageRequest::RequestState::PAUSED, + base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, + base::Unretained(this))); ASSERT_EQ(LastResult::kNone, this->last_result()); - ASSERT_EQ(0, this->last_remove_count()); this->PumpLoop(); - ASSERT_EQ(LastResult::kTrue, this->last_result()); - ASSERT_EQ(2, this->last_remove_count()); + + // Verify pause succeeded + ASSERT_EQ(UpdateStatus::UPDATED, this->last_update_status()); this->ClearResults(); - // Check to see what remains in the queue. Removed request should be gone. + // Get the request from the queue to check it out store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, base::Unretained(this))); this->PumpLoop(); ASSERT_EQ(LastResult::kTrue, this->last_result()); - // The other request should still be in the queue. - ASSERT_TRUE(this->last_requests().empty()); + // The request should still be in the queue. + ASSERT_EQ(1UL, this->last_requests().size()); + // Request 1 should be paused. + ASSERT_EQ(SavePageRequest::RequestState::PAUSED, + this->last_requests().at(0).request_state()); + this->ClearResults(); + + // Now resume the same request we paused. + store->ChangeRequestsState( + request_ids, SavePageRequest::RequestState::AVAILABLE, + base::Bind(&RequestQueueStoreTestBase::AddOrUpdateDone, + base::Unretained(this))); + ASSERT_EQ(LastResult::kNone, this->last_result()); + this->PumpLoop(); + + // Verify resume succeeded. + ASSERT_EQ(UpdateStatus::UPDATED, this->last_update_status()); + this->ClearResults(); + + // Get the request from the queue to check it out + store->GetRequests(base::Bind(&RequestQueueStoreTestBase::GetRequestsDone, + base::Unretained(this))); + this->PumpLoop(); + ASSERT_EQ(LastResult::kTrue, this->last_result()); + // The request should still be in the queue. + ASSERT_EQ(1UL, this->last_requests().size()); + // Request 1 should be paused. + ASSERT_EQ(SavePageRequest::RequestState::AVAILABLE, + this->last_requests().at(0).request_state()); this->ClearResults(); }
diff --git a/components/offline_pages/background/request_queue_unittest.cc b/components/offline_pages/background/request_queue_unittest.cc index 967257c..079513ea7 100644 --- a/components/offline_pages/background/request_queue_unittest.cc +++ b/components/offline_pages/background/request_queue_unittest.cc
@@ -49,7 +49,8 @@ void GetRequestsDone(GetRequestsResult result, const std::vector<SavePageRequest>& requests); // Callback for removing request. - void RemoveRequestDone(UpdateRequestResult result); + void RemoveRequestDone( + const RequestQueue::UpdateMultipleRequestResults& results); void UpdateRequestDone(UpdateRequestResult result); @@ -60,7 +61,10 @@ return last_added_request_.get(); } - UpdateRequestResult last_remove_result() const { return last_remove_result_; } + const RequestQueue::UpdateMultipleRequestResults& last_remove_results() + const { + return last_remove_results_; + } UpdateRequestResult last_update_result() const { return last_update_result_; } @@ -74,8 +78,7 @@ private: AddRequestResult last_add_result_; std::unique_ptr<SavePageRequest> last_added_request_; - - UpdateRequestResult last_remove_result_; + RequestQueue::UpdateMultipleRequestResults last_remove_results_; UpdateRequestResult last_update_result_; GetRequestsResult last_get_requests_result_; @@ -88,7 +91,6 @@ RequestQueueTest::RequestQueueTest() : last_add_result_(AddRequestResult::STORE_FAILURE), - last_remove_result_(UpdateRequestResult::STORE_FAILURE), last_update_result_(UpdateRequestResult::STORE_FAILURE), last_get_requests_result_(GetRequestsResult::STORE_FAILURE), task_runner_(new base::TestSimpleTaskRunner), @@ -119,8 +121,9 @@ last_requests_ = requests; } -void RequestQueueTest::RemoveRequestDone(UpdateRequestResult result) { - last_remove_result_ = result; +void RequestQueueTest::RemoveRequestDone( + const RequestQueue::UpdateMultipleRequestResults& results) { + last_remove_results_ = results; } void RequestQueueTest::UpdateRequestDone(UpdateRequestResult result) { @@ -162,11 +165,14 @@ PumpLoop(); ASSERT_EQ(kRequestId, last_added_request()->request_id()); - queue()->RemoveRequest( - kRequestId, + std::vector<int64_t> remove_requests; + remove_requests.push_back(kRequestId); + queue()->RemoveRequests( + remove_requests, base::Bind(&RequestQueueTest::RemoveRequestDone, base::Unretained(this))); PumpLoop(); - ASSERT_EQ(UpdateRequestResult::SUCCESS, last_remove_result()); + ASSERT_EQ(1ul, last_remove_results().size()); + ASSERT_EQ(UpdateRequestResult::SUCCESS, last_remove_results().at(0).second); queue()->GetRequests( base::Bind(&RequestQueueTest::GetRequestsDone, base::Unretained(this))); @@ -175,41 +181,95 @@ ASSERT_EQ(0ul, last_requests().size()); } -TEST_F(RequestQueueTest, RemoveRequestByClientId) { +TEST_F(RequestQueueTest, RemoveSeveralRequests) { base::Time creation_time = base::Time::Now(); - // Put two requests on the queue with different client IDs. SavePageRequest request(kRequestId, kUrl, kClientId, creation_time, kUserRequested); queue()->AddRequest(request, base::Bind(&RequestQueueTest::AddRequestDone, base::Unretained(this))); + PumpLoop(); + ASSERT_EQ(kRequestId, last_added_request()->request_id()); + SavePageRequest request2(kRequestId2, kUrl2, kClientId2, creation_time, kUserRequested); queue()->AddRequest(request2, base::Bind(&RequestQueueTest::AddRequestDone, base::Unretained(this))); PumpLoop(); + ASSERT_EQ(kRequestId2, last_added_request()->request_id()); + + std::vector<int64_t> remove_requests; + remove_requests.push_back(kRequestId); + remove_requests.push_back(kRequestId2); + queue()->RemoveRequests( + remove_requests, + base::Bind(&RequestQueueTest::RemoveRequestDone, base::Unretained(this))); + PumpLoop(); + ASSERT_EQ(2ul, last_remove_results().size()); + ASSERT_EQ(UpdateRequestResult::SUCCESS, last_remove_results().at(0).second); + ASSERT_EQ(UpdateRequestResult::SUCCESS, last_remove_results().at(1).second); + ASSERT_EQ(kRequestId, last_remove_results().at(0).first); + ASSERT_EQ(kRequestId2, last_remove_results().at(1).first); queue()->GetRequests( base::Bind(&RequestQueueTest::GetRequestsDone, base::Unretained(this))); PumpLoop(); + + // Verify both requests are no longer in the queue. ASSERT_EQ(GetRequestsResult::SUCCESS, last_get_requests_result()); - ASSERT_EQ(2ul, last_requests().size()); + ASSERT_EQ(0ul, last_requests().size()); +} - std::vector<ClientId> client_ids; - client_ids.push_back(kClientId); - - // Removing the first client ID should leave only the second on the queue. - queue()->RemoveRequestsByClientId( - client_ids, - base::Bind(&RequestQueueTest::RemoveRequestDone, base::Unretained(this))); +TEST_F(RequestQueueTest, PauseAndResume) { + base::Time creation_time = base::Time::Now(); + SavePageRequest request(kRequestId, kUrl, kClientId, creation_time, + kUserRequested); + queue()->AddRequest(request, base::Bind(&RequestQueueTest::AddRequestDone, + base::Unretained(this))); PumpLoop(); - ASSERT_EQ(UpdateRequestResult::SUCCESS, last_remove_result()); + ASSERT_EQ(kRequestId, last_added_request()->request_id()); queue()->GetRequests( base::Bind(&RequestQueueTest::GetRequestsDone, base::Unretained(this))); PumpLoop(); ASSERT_EQ(GetRequestsResult::SUCCESS, last_get_requests_result()); ASSERT_EQ(1ul, last_requests().size()); - ASSERT_EQ(kClientId2, last_requests().front().client_id()); + + std::vector<int64_t> request_ids; + request_ids.push_back(kRequestId); + + // Pause the request. + queue()->ChangeRequestsState( + request_ids, SavePageRequest::RequestState::PAUSED, + base::Bind(&RequestQueueTest::UpdateRequestDone, base::Unretained(this))); + PumpLoop(); + ASSERT_EQ(UpdateRequestResult::SUCCESS, last_update_result()); + + queue()->GetRequests( + base::Bind(&RequestQueueTest::GetRequestsDone, base::Unretained(this))); + PumpLoop(); + + // Verify the request is paused. + ASSERT_EQ(GetRequestsResult::SUCCESS, last_get_requests_result()); + ASSERT_EQ(1ul, last_requests().size()); + ASSERT_EQ(SavePageRequest::RequestState::PAUSED, + last_requests().front().request_state()); + + // Resume the request. + queue()->ChangeRequestsState( + request_ids, SavePageRequest::RequestState::AVAILABLE, + base::Bind(&RequestQueueTest::UpdateRequestDone, base::Unretained(this))); + PumpLoop(); + ASSERT_EQ(UpdateRequestResult::SUCCESS, last_update_result()); + + queue()->GetRequests( + base::Bind(&RequestQueueTest::GetRequestsDone, base::Unretained(this))); + PumpLoop(); + + // Verify the request is no longer paused. + ASSERT_EQ(GetRequestsResult::SUCCESS, last_get_requests_result()); + ASSERT_EQ(1ul, last_requests().size()); + ASSERT_EQ(SavePageRequest::RequestState::AVAILABLE, + last_requests().front().request_state()); } // A longer test populating the request queue with more than one item, properly @@ -235,11 +295,15 @@ ASSERT_EQ(GetRequestsResult::SUCCESS, last_get_requests_result()); ASSERT_EQ(2ul, last_requests().size()); - queue()->RemoveRequest( - request1.request_id(), + std::vector<int64_t> remove_requests; + remove_requests.push_back(request1.request_id()); + queue()->RemoveRequests( + remove_requests, base::Bind(&RequestQueueTest::RemoveRequestDone, base::Unretained(this))); PumpLoop(); - ASSERT_EQ(UpdateRequestResult::SUCCESS, last_remove_result()); + ASSERT_EQ(1ul, last_remove_results().size()); + ASSERT_EQ(kRequestId, last_remove_results().at(0).first); + ASSERT_EQ(UpdateRequestResult::SUCCESS, last_remove_results().at(0).second); queue()->GetRequests( base::Bind(&RequestQueueTest::GetRequestsDone, base::Unretained(this)));
diff --git a/components/offline_pages/downloads/download_ui_adapter.cc b/components/offline_pages/downloads/download_ui_adapter.cc index 776fd8c..906ae7b2 100644 --- a/components/offline_pages/downloads/download_ui_adapter.cc +++ b/components/offline_pages/downloads/download_ui_adapter.cc
@@ -19,6 +19,13 @@ const char kDownloadUIAdapterKey[] = "download-ui-adapter"; } +DownloadUIAdapter::ItemInfo::ItemInfo(const OfflinePageItem& page) + : ui_item(base::MakeUnique<DownloadUIItem>(page)), + offline_id(page.offline_id), + offline_url(page.GetOfflineURL()) {} + +DownloadUIAdapter::ItemInfo::~ItemInfo() {} + DownloadUIAdapter::DownloadUIAdapter(OfflinePageModel* model) : model_(model), is_loaded_(false), @@ -74,25 +81,55 @@ void DownloadUIAdapter::OfflinePageDeleted( int64_t offline_id, const ClientId& client_id) { - for(const auto& item : items_) { - if (item.second->guid == client_id.id) { - items_.erase(item.first); - FOR_EACH_OBSERVER(Observer, observers_, ItemDeleted(client_id.id)); - return; - } - } + if (!IsVisibleInUI(client_id)) + return; + std::string guid = client_id.id; + DownloadUIItems::const_iterator it = items_.find(guid); + if (it == items_.end()) + return; + items_.erase(it); + FOR_EACH_OBSERVER(Observer, observers_, ItemDeleted(guid)); } -const DownloadUIItemsMap& DownloadUIAdapter::GetAllItems() const { - return items_; +std::vector<const DownloadUIItem*> DownloadUIAdapter::GetAllItems() const { + std::vector<const DownloadUIItem*> result; + for (const auto& item : items_) + result.push_back(item.second->ui_item.get()); + return result; } const DownloadUIItem* DownloadUIAdapter::GetItem(const std::string& guid) const { - DownloadUIItemsMap::const_iterator it = items_.find(guid); + DownloadUIItems::const_iterator it = items_.find(guid); if (it == items_.end()) return nullptr; - return (*it).second.get(); + return it->second->ui_item.get(); +} + +void DownloadUIAdapter::DeleteItem(const std::string& guid) { + // TODO(dimich): Also remove pending request from RequestQueue. + DownloadUIItems::const_iterator it = items_.find(guid); + if (it == items_.end()) + return; + + std::vector<int64_t> page_ids; + page_ids.push_back(it->second->offline_id); + // TODO(dimich): This should be ExpirePages(...Now()..) when Expire is + // firing Observer method. The resulting Observer notification will update + // local cache. + model_->DeletePagesByOfflineId( + page_ids, base::Bind(&DownloadUIAdapter::OnDeletePagesDone, + weak_ptr_factory_.GetWeakPtr())); +} + +GURL DownloadUIAdapter::GetOfflineUrlByGuid( + const std::string& guid) const { + // TODO(dimich): when requests are also in the cache, filter them out. + // Requests do not yet have offline URL. + DownloadUIItems::const_iterator it = items_.find(guid); + if (it != items_.end()) + return it->second->offline_url; + return GURL(); } void DownloadUIAdapter::LoadCache() { @@ -113,11 +150,10 @@ void DownloadUIAdapter::OnOfflinePagesLoaded( const MultipleOfflinePageItemResult& pages) { for (const auto& page : pages) { - if (IsVisibleInUI(page)) { - std::unique_ptr<DownloadUIItem> new_item(new DownloadUIItem(page)); - const std::string& guid = new_item->guid; + if (IsVisibleInUI(page.client_id)) { + std::string guid = page.client_id.id; DCHECK(items_.find(guid) == items_.end()); - items_[guid] = std::move(new_item); + items_[guid] = base::MakeUnique<ItemInfo>(page); } } is_loaded_ = true; @@ -136,27 +172,30 @@ const MultipleOfflinePageItemResult& pages) { std::vector<std::string> added_guids; for (const auto& page : pages) { - if (!IsVisibleInUI(page)) // Item should be filtered out. + if (!IsVisibleInUI(page.client_id)) // Item should be filtered out. continue; const std::string& guid = page.client_id.id; if (items_.find(guid) != items_.end()) // Item already exists. continue; - std::unique_ptr<DownloadUIItem> item(new DownloadUIItem(page)); - items_[guid] = std::move(item); + items_[guid] = base::MakeUnique<ItemInfo>(page); added_guids.push_back(guid); } // Only one added page CHECK(added_guids.size() <= 1); for (auto& guid : added_guids) { - const DownloadUIItem& item = *(items_.find(guid)->second.get()); + const DownloadUIItem& item = *(items_.find(guid)->second->ui_item.get()); FOR_EACH_OBSERVER(Observer, observers_, ItemAdded(item)); } } -bool DownloadUIAdapter::IsVisibleInUI(const OfflinePageItem& page) { - // TODO(dimich): set up the right filter here. - return page.client_id.name_space == kAsyncNamespace && - base::IsValidGUID(page.client_id.id); +void DownloadUIAdapter::OnDeletePagesDone(DeletePageResult result) { + // TODO(dimich): Consider adding UMA to record user actions. +} + +bool DownloadUIAdapter::IsVisibleInUI(const ClientId& client_id) { + const std::string& name_space = client_id.name_space; + return (name_space == kAsyncNamespace || name_space == kDownloadNamespace) && + base::IsValidGUID(client_id.id); } } // namespace offline_pages
diff --git a/components/offline_pages/downloads/download_ui_adapter.h b/components/offline_pages/downloads/download_ui_adapter.h index d96f11d..937799b 100644 --- a/components/offline_pages/downloads/download_ui_adapter.h +++ b/components/offline_pages/downloads/download_ui_adapter.h
@@ -8,19 +8,16 @@ #include <map> #include <memory> #include <string> +#include <vector> #include "base/observer_list.h" #include "base/supports_user_data.h" #include "components/offline_pages/downloads/download_ui_item.h" #include "components/offline_pages/offline_page_model.h" #include "components/offline_pages/offline_page_types.h" +#include "url/gurl.h" namespace offline_pages { - -// Key is DownloadUIItem.guid. -typedef - std::map<std::string, std::unique_ptr<DownloadUIItem>> DownloadUIItemsMap; - // C++ side of the UI Adapter. Mimics DownloadManager/Item/History (since we // share UI with Downloads). // An instance of this class is owned by OfflinePageModel and is shared between @@ -66,10 +63,17 @@ void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); - const DownloadUIItemsMap& GetAllItems() const; - // May return nullptr. + // Returns all UI items. The list contains references to items in the cache + // and has to be used synchronously. + std::vector<const DownloadUIItem*> GetAllItems() const; + // May return nullptr if item with specified guid does not exist. const DownloadUIItem* GetItem(const std::string& guid) const; + // Commands from UI. Start async operations, result is observable + // via Observer or directly by the user (as in 'open'). + void DeleteItem(const std::string& guid); + GURL GetOfflineUrlByGuid(const std::string& guid) const; + // OfflinePageModel::Observer void OfflinePageModelLoaded(OfflinePageModel* model) override; void OfflinePageModelChanged(OfflinePageModel* model) override; @@ -77,6 +81,21 @@ const ClientId& client_id) override; private: + struct ItemInfo { + explicit ItemInfo(const OfflinePageItem& page); + ~ItemInfo(); + + std::unique_ptr<DownloadUIItem> ui_item; + // Additional cached data, not exposed to UI through DownloadUIItem. + int64_t offline_id; + GURL offline_url; + + private: + DISALLOW_COPY_AND_ASSIGN(ItemInfo); + }; + + typedef std::map<std::string, std::unique_ptr<ItemInfo>> DownloadUIItems; + void LoadCache(); void ClearCache(); @@ -84,15 +103,17 @@ void OnOfflinePagesLoaded(const MultipleOfflinePageItemResult& pages); void NotifyItemsLoaded(Observer* observer); void OnOfflinePagesChanged(const MultipleOfflinePageItemResult& pages); - bool IsVisibleInUI(const OfflinePageItem& page); + void OnDeletePagesDone(DeletePageResult result); + + bool IsVisibleInUI(const ClientId& page); // Always valid, this class is a member of the model. OfflinePageModel* model_; bool is_loaded_; - // The cache of UI items. - DownloadUIItemsMap items_; + // The cache of UI items. The key is DownloadUIItem.guid. + DownloadUIItems items_; // The observers. base::ObserverList<Observer> observers_;
diff --git a/components/offline_pages/offline_page_model.h b/components/offline_pages/offline_page_model.h index 9c6efb7..07aa4ed 100644 --- a/components/offline_pages/offline_page_model.h +++ b/components/offline_pages/offline_page_model.h
@@ -165,16 +165,6 @@ const GURL& online_url, const MultipleOfflinePageItemCallback& callback) = 0; - // Returns via callback an offline page saved for |online_url|, if any. The - // best page is chosen based on creation date; a more recently created offline - // page will be preferred over an older one. This API function does not - // respect namespaces, as it is used to choose which page is rendered in a - // tab. Today all namespaces are treated equally for the purposes of this - // selection. - virtual void GetBestPageForOnlineURL( - const GURL& online_url, - const SingleOfflinePageItemCallback callback) = 0; - // Returns an offline page saved for |online_url|. A nullptr is returned if // not found. See |GetBestPageForOnlineURL| for selection criteria. virtual const OfflinePageItem* MaybeGetBestPageForOnlineURL(
diff --git a/components/offline_pages/offline_page_model_impl.cc b/components/offline_pages/offline_page_model_impl.cc index a4d63b2..c97b2967 100644 --- a/components/offline_pages/offline_page_model_impl.cc +++ b/components/offline_pages/offline_page_model_impl.cc
@@ -566,20 +566,6 @@ return nullptr; } -void OfflinePageModelImpl::GetBestPageForOnlineURL( - const GURL& online_url, - const SingleOfflinePageItemCallback callback) { - RunWhenLoaded( - base::Bind(&OfflinePageModelImpl::GetBestPageForOnlineURLWhenLoadDone, - weak_ptr_factory_.GetWeakPtr(), online_url, callback)); -} - -void OfflinePageModelImpl::GetBestPageForOnlineURLWhenLoadDone( - const GURL& online_url, - const SingleOfflinePageItemCallback& callback) const { - callback.Run(MaybeGetBestPageForOnlineURL(online_url)); -} - void OfflinePageModelImpl::GetPagesByOnlineURL( const GURL& online_url, const MultipleOfflinePageItemCallback& callback) {
diff --git a/components/offline_pages/offline_page_model_impl.h b/components/offline_pages/offline_page_model_impl.h index b93a227..fe165386b 100644 --- a/components/offline_pages/offline_page_model_impl.h +++ b/components/offline_pages/offline_page_model_impl.h
@@ -101,9 +101,6 @@ void GetPagesByOnlineURL( const GURL& online_url, const MultipleOfflinePageItemCallback& callback) override; - void GetBestPageForOnlineURL( - const GURL& online_url, - const SingleOfflinePageItemCallback callback) override; const OfflinePageItem* MaybeGetBestPageForOnlineURL( const GURL& online_url) const override; void CheckMetadataConsistency() override; @@ -157,9 +154,6 @@ void GetPageByOfflineURLWhenLoadDone( const GURL& offline_url, const SingleOfflinePageItemCallback& callback) const; - void GetBestPageForOnlineURLWhenLoadDone( - const GURL& online_url, - const SingleOfflinePageItemCallback& callback) const; void MarkPageAccessedWhenLoadDone(int64_t offline_id); void CheckMetadataConsistencyWhenLoadDone();
diff --git a/components/offline_pages/stub_offline_page_model.cc b/components/offline_pages/stub_offline_page_model.cc index 9d00e46a..68119ad 100644 --- a/components/offline_pages/stub_offline_page_model.cc +++ b/components/offline_pages/stub_offline_page_model.cc
@@ -58,9 +58,6 @@ void StubOfflinePageModel::GetPagesByOnlineURL( const GURL& online_url, const MultipleOfflinePageItemCallback& callback) {} -void StubOfflinePageModel::GetBestPageForOnlineURL( - const GURL& online_url, - const SingleOfflinePageItemCallback callback) {} const OfflinePageItem* StubOfflinePageModel::MaybeGetBestPageForOnlineURL( const GURL& online_url) const { return nullptr;
diff --git a/components/offline_pages/stub_offline_page_model.h b/components/offline_pages/stub_offline_page_model.h index 36515df..6d55280 100644 --- a/components/offline_pages/stub_offline_page_model.h +++ b/components/offline_pages/stub_offline_page_model.h
@@ -59,9 +59,6 @@ void GetPagesByOnlineURL( const GURL& online_url, const MultipleOfflinePageItemCallback& callback) override; - void GetBestPageForOnlineURL( - const GURL& online_url, - const SingleOfflinePageItemCallback callback) override; const OfflinePageItem* MaybeGetBestPageForOnlineURL( const GURL& online_url) const override; void CheckMetadataConsistency() override;
diff --git a/components/omnibox/browser/omnibox_edit_model.cc b/components/omnibox/browser/omnibox_edit_model.cc index 4d6b3c5..5e954999 100644 --- a/components/omnibox/browser/omnibox_edit_model.cc +++ b/components/omnibox/browser/omnibox_edit_model.cc
@@ -80,7 +80,8 @@ // Histogram name which counts the number of milliseconds a user takes // between focusing and opening an omnibox match. -const char kFocusToOpenTimeHistogram[] = "Omnibox.FocusToOpenTimeAnyPopupState"; +const char kFocusToOpenTimeHistogram[] = + "Omnibox.FocusToOpenTimeAnyPopupState2"; // Split the percentage match histograms into buckets based on the width of the // omnibox. @@ -731,9 +732,11 @@ client_->OnURLOpenedFromOmnibox(&log); OmniboxEventGlobalTracker::GetInstance()->OnURLOpened(&log); LOCAL_HISTOGRAM_BOOLEAN("Omnibox.EventCount", true); - DCHECK(!last_omnibox_focus_.is_null()) - << "An omnibox focus should have occurred before opening a match."; - UMA_HISTOGRAM_TIMES(kFocusToOpenTimeHistogram, now - last_omnibox_focus_); + if (!last_omnibox_focus_.is_null()) { + // Only record focus to open time when a focus actually happened (as + // opposed to, say, dragging a link onto the omnibox). + UMA_HISTOGRAM_TIMES(kFocusToOpenTimeHistogram, now - last_omnibox_focus_); + } TemplateURLService* service = client_->GetTemplateURLService(); TemplateURL* template_url = match.GetTemplateURL(service, false);
diff --git a/components/omnibox/browser/verbatim_match.cc b/components/omnibox/browser/verbatim_match.cc index e4efcf7..381ba3d 100644 --- a/components/omnibox/browser/verbatim_match.cc +++ b/components/omnibox/browser/verbatim_match.cc
@@ -9,7 +9,6 @@ #include "components/omnibox/browser/autocomplete_input.h" #include "components/omnibox/browser/autocomplete_provider_client.h" #include "components/omnibox/browser/history_url_provider.h" -#include "components/search/search.h" #include "url/gurl.h" AutocompleteMatch VerbatimMatchForURL( @@ -20,15 +19,12 @@ int verbatim_relevance) { DCHECK(!input.text().empty()); AutocompleteMatch match; - // If query-in-the-omnibox is not enabled (and thus the verbatim match for - // a URL is guaranteed to be a URL) and the caller already knows where the - // verbatim match should go and has provided a HistoryURLProvider to aid in - // its construction, construct the match directly, don't call Classify() on - // the input. Classify() runs all providers' synchronous passes. Some - // providers such as HistoryQuick can have a slow synchronous pass on some - // inputs. - if (history_url_provider && destination_url.is_valid() && - !search::IsQueryExtractionEnabled()) { + // If the caller already knows where the verbatim match should go and has + // provided a HistoryURLProvider to aid in its construction, construct the + // match directly, don't call Classify() on the input. Classify() runs all + // providers' synchronous passes. Some providers such as HistoryQuick can + // have a slow synchronous pass on some inputs. + if (history_url_provider && destination_url.is_valid()) { match = history_url_provider->SuggestExactInput( input, destination_url,
diff --git a/components/password_manager.gypi b/components/password_manager.gypi index 0710957..7f57edf 100644 --- a/components/password_manager.gypi +++ b/components/password_manager.gypi
@@ -22,7 +22,6 @@ '../third_party/re2/re2.gyp:re2', 'password_manager_core_common', 'password_manager_core_browser_proto', - 'sync_driver', 'url_formatter/url_formatter.gyp:url_formatter', ], 'include_dirs': [
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn index 081f9f93..848230d 100644 --- a/components/password_manager/core/browser/BUILD.gn +++ b/components/password_manager/core/browser/BUILD.gn
@@ -137,7 +137,7 @@ "//components/pref_registry", "//components/prefs", "//components/strings", - "//components/sync_driver", + "//components/sync", "//components/url_formatter", "//components/variations", "//components/webdata/common", @@ -291,7 +291,7 @@ "//components/prefs:test_support", "//components/strings", "//components/sync:test_support_sync_api", - "//components/sync_driver:test_support", + "//components/sync:test_support_sync_driver", "//components/variations", "//net:test_support", "//sql:test_support",
diff --git a/components/password_manager/core/browser/DEPS b/components/password_manager/core/browser/DEPS index 593c27c..b95f832 100644 --- a/components/password_manager/core/browser/DEPS +++ b/components/password_manager/core/browser/DEPS
@@ -2,7 +2,7 @@ "+components/autofill/core/browser", "+components/keyed_service/core", "+components/pref_registry", - "+components/sync_driver", + "+components/sync/driver", "+components/url_formatter", "+components/variations", "+components/webdata/common",
diff --git a/components/password_manager/core/browser/password_bubble_experiment.cc b/components/password_manager/core/browser/password_bubble_experiment.cc index 9b41bde9..0339782 100644 --- a/components/password_manager/core/browser/password_bubble_experiment.cc +++ b/components/password_manager/core/browser/password_bubble_experiment.cc
@@ -13,7 +13,7 @@ #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_service.h" #include "components/variations/variations_associated_data.h" namespace password_bubble_experiment {
diff --git a/components/password_manager/core/browser/password_bubble_experiment_unittest.cc b/components/password_manager/core/browser/password_bubble_experiment_unittest.cc index 823fbc9c..9fe466c 100644 --- a/components/password_manager/core/browser/password_bubble_experiment_unittest.cc +++ b/components/password_manager/core/browser/password_bubble_experiment_unittest.cc
@@ -12,7 +12,7 @@ #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" #include "components/prefs/testing_pref_service.h" -#include "components/sync_driver/fake_sync_service.h" +#include "components/sync/driver/fake_sync_service.h" #include "components/variations/variations_associated_data.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/components/password_manager/core/browser/password_manager_util.cc b/components/password_manager/core/browser/password_manager_util.cc index dc0e7e2..6ddd6d6b 100644 --- a/components/password_manager/core/browser/password_manager_util.cc +++ b/components/password_manager/core/browser/password_manager_util.cc
@@ -9,7 +9,7 @@ #include "base/memory/ptr_util.h" #include "components/autofill/core/common/password_form.h" #include "components/password_manager/core/browser/log_manager.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_service.h" namespace password_manager_util {
diff --git a/components/password_manager/core/browser/password_store_default_unittest.cc b/components/password_manager/core/browser/password_store_default_unittest.cc index 566e43f..d4d0a77 100644 --- a/components/password_manager/core/browser/password_store_default_unittest.cc +++ b/components/password_manager/core/browser/password_store_default_unittest.cc
@@ -156,7 +156,7 @@ PasswordStoreDefaultTestDelegate); ACTION(STLDeleteElements0) { - STLDeleteContainerPointers(arg0.begin(), arg0.end()); + base::STLDeleteContainerPointers(arg0.begin(), arg0.end()); } TEST(PasswordStoreDefaultTest, NonASCIIData) {
diff --git a/components/password_manager/core/browser/password_store_factory_util.h b/components/password_manager/core/browser/password_store_factory_util.h index 695328a..599fe0b 100644 --- a/components/password_manager/core/browser/password_store_factory_util.h +++ b/components/password_manager/core/browser/password_store_factory_util.h
@@ -15,7 +15,7 @@ #include "components/password_manager/core/browser/login_database.h" #include "components/password_manager/core/browser/password_store.h" #include "components/sync/api/syncable_service.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_service.h" #include "net/url_request/url_request_context_getter.h" namespace password_manager {
diff --git a/components/password_manager/core/browser/password_store_unittest.cc b/components/password_manager/core/browser/password_store_unittest.cc index 7823ba6..c268251 100644 --- a/components/password_manager/core/browser/password_store_unittest.cc +++ b/components/password_manager/core/browser/password_store_unittest.cc
@@ -98,7 +98,7 @@ }; ACTION(STLDeleteElements0) { - STLDeleteContainerPointers(arg0.begin(), arg0.end()); + base::STLDeleteContainerPointers(arg0.begin(), arg0.end()); } TEST_F(PasswordStoreTest, IgnoreOldWwwGoogleLogins) {
diff --git a/components/password_manager/sync/browser/BUILD.gn b/components/password_manager/sync/browser/BUILD.gn index 1449278..82acc7d 100644 --- a/components/password_manager/sync/browser/BUILD.gn +++ b/components/password_manager/sync/browser/BUILD.gn
@@ -24,7 +24,7 @@ "//components/password_manager/core/common", "//components/prefs", "//components/signin/core/browser", - "//components/sync_driver", + "//components/sync", "//components/syncable_prefs", "//google_apis", "//net", @@ -53,7 +53,7 @@ "//components/signin/core/browser:test_support", "//components/signin/core/common", "//components/sync:test_support_sync_api", - "//components/sync_driver:test_support", + "//components/sync:test_support_sync_driver", "//components/syncable_prefs", "//components/syncable_prefs:test_support", "//testing/gmock",
diff --git a/components/password_manager/sync/browser/DEPS b/components/password_manager/sync/browser/DEPS index 3f62df029..f209e86da 100644 --- a/components/password_manager/sync/browser/DEPS +++ b/components/password_manager/sync/browser/DEPS
@@ -3,9 +3,9 @@ "+components/pref_registry", "+components/signin/core/browser", "+components/signin/core/common", - "+components/sync_driver", "+components/sync/base", "+components/sync/core", + "+components/sync/driver", "+components/sync/engine", "+components/syncable_prefs", "+google_apis/gaia",
diff --git a/components/password_manager/sync/browser/password_data_type_controller.cc b/components/password_manager/sync/browser/password_data_type_controller.cc index 5ee4f0b..32a1a72b 100644 --- a/components/password_manager/sync/browser/password_data_type_controller.cc +++ b/components/password_manager/sync/browser/password_data_type_controller.cc
@@ -7,8 +7,8 @@ #include "base/bind.h" #include "base/metrics/histogram.h" #include "components/password_manager/core/browser/password_store.h" -#include "components/sync_driver/sync_client.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_client.h" +#include "components/sync/driver/sync_service.h" namespace browser_sync {
diff --git a/components/password_manager/sync/browser/password_data_type_controller.h b/components/password_manager/sync/browser/password_data_type_controller.h index 6205d90a..d4f6d1b 100644 --- a/components/password_manager/sync/browser/password_data_type_controller.h +++ b/components/password_manager/sync/browser/password_data_type_controller.h
@@ -9,8 +9,8 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "components/sync_driver/non_ui_data_type_controller.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/non_ui_data_type_controller.h" +#include "components/sync/driver/sync_service_observer.h" namespace password_manager { class PasswordStore;
diff --git a/components/password_manager/sync/browser/password_manager_setting_migrator_service.cc b/components/password_manager/sync/browser/password_manager_setting_migrator_service.cc index 091f2168c..728fffb 100644 --- a/components/password_manager/sync/browser/password_manager_setting_migrator_service.cc +++ b/components/password_manager/sync/browser/password_manager_setting_migrator_service.cc
@@ -10,7 +10,7 @@ #include "build/build_config.h" #include "components/password_manager/core/browser/password_manager_settings_migration_experiment.h" #include "components/password_manager/core/common/password_manager_pref_names.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_service.h" #include "components/syncable_prefs/pref_service_syncable.h" namespace {
diff --git a/components/password_manager/sync/browser/password_manager_setting_migrator_service_unittest.cc b/components/password_manager/sync/browser/password_manager_setting_migrator_service_unittest.cc index 91e90b4c..91dc0b1 100644 --- a/components/password_manager/sync/browser/password_manager_setting_migrator_service_unittest.cc +++ b/components/password_manager/sync/browser/password_manager_setting_migrator_service_unittest.cc
@@ -17,8 +17,8 @@ #include "components/sync/api/sync_error_factory.h" #include "components/sync/api/sync_error_factory_mock.h" #include "components/sync/core/attachments/attachment_service_proxy_for_test.h" +#include "components/sync/driver/fake_sync_service.h" #include "components/sync/protocol/sync.pb.h" -#include "components/sync_driver/fake_sync_service.h" #include "components/syncable_prefs/pref_model_associator_client.h" #include "components/syncable_prefs/pref_service_mock_factory.h" #include "components/syncable_prefs/pref_service_syncable.h"
diff --git a/components/password_manager/sync/browser/password_sync_util.h b/components/password_manager/sync/browser/password_sync_util.h index 6123e40..24e4d9398 100644 --- a/components/password_manager/sync/browser/password_sync_util.h +++ b/components/password_manager/sync/browser/password_sync_util.h
@@ -9,7 +9,7 @@ #include "components/autofill/core/common/password_form.h" #include "components/signin/core/browser/signin_manager.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_service.h" namespace password_manager { namespace sync_util {
diff --git a/components/password_manager/sync/browser/sync_credentials_filter.h b/components/password_manager/sync/browser/sync_credentials_filter.h index 4ad64f3..4047b815 100644 --- a/components/password_manager/sync/browser/sync_credentials_filter.h +++ b/components/password_manager/sync/browser/sync_credentials_filter.h
@@ -13,7 +13,7 @@ #include "components/password_manager/core/browser/credentials_filter.h" #include "components/password_manager/core/browser/password_manager_client.h" #include "components/signin/core/browser/signin_manager.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_service.h" namespace password_manager {
diff --git a/components/password_manager/sync/browser/sync_username_test_base.h b/components/password_manager/sync/browser/sync_username_test_base.h index 1664a7b..975cca8 100644 --- a/components/password_manager/sync/browser/sync_username_test_base.h +++ b/components/password_manager/sync/browser/sync_username_test_base.h
@@ -14,7 +14,7 @@ #include "components/signin/core/browser/signin_manager_base.h" #include "components/signin/core/browser/test_signin_client.h" #include "components/sync/base/model_type.h" -#include "components/sync_driver/fake_sync_service.h" +#include "components/sync/driver/fake_sync_service.h" #include "testing/gtest/include/gtest/gtest.h" namespace password_manager {
diff --git a/components/pdf/renderer/pepper_pdf_host.cc b/components/pdf/renderer/pepper_pdf_host.cc index 4c02e704..c56d78e 100644 --- a/components/pdf/renderer/pepper_pdf_host.cc +++ b/components/pdf/renderer/pepper_pdf_host.cc
@@ -11,7 +11,6 @@ #include "content/public/renderer/pepper_plugin_instance.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_thread.h" -#include "content/public/renderer/render_view.h" #include "content/public/renderer/renderer_ppapi_host.h" #include "ppapi/host/dispatch_host_message.h" #include "ppapi/host/host_message_context.h" @@ -98,33 +97,33 @@ int32_t PepperPDFHost::OnHostMsgDidStartLoading( ppapi::host::HostMessageContext* context) { - content::RenderView* render_view = GetRenderView(); - if (!render_view) + content::RenderFrame* render_frame = GetRenderFrame(); + if (!render_frame) return PP_ERROR_FAILED; - render_view->DidStartLoading(); + render_frame->DidStartLoading(); return PP_OK; } int32_t PepperPDFHost::OnHostMsgDidStopLoading( ppapi::host::HostMessageContext* context) { - content::RenderView* render_view = GetRenderView(); - if (!render_view) + content::RenderFrame* render_frame = GetRenderFrame(); + if (!render_frame) return PP_ERROR_FAILED; - render_view->DidStopLoading(); + render_frame->DidStopLoading(); return PP_OK; } int32_t PepperPDFHost::OnHostMsgSetContentRestriction( ppapi::host::HostMessageContext* context, int restrictions) { - content::RenderView* render_view = GetRenderView(); - if (!render_view) + content::RenderFrame* render_frame = GetRenderFrame(); + if (!render_frame) return PP_ERROR_FAILED; - render_view->Send(new PDFHostMsg_PDFUpdateContentRestrictions( - render_view->GetRoutingID(), restrictions)); + render_frame->Send(new PDFHostMsg_PDFUpdateContentRestrictions( + render_frame->GetRoutingID(), restrictions)); return PP_OK; } @@ -139,12 +138,12 @@ int32_t PepperPDFHost::OnHostMsgHasUnsupportedFeature( ppapi::host::HostMessageContext* context) { - content::RenderView* render_view = GetRenderView(); - if (!render_view) + content::RenderFrame* render_frame = GetRenderFrame(); + if (!render_frame) return PP_ERROR_FAILED; - render_view->Send( - new PDFHostMsg_PDFHasUnsupportedFeature(render_view->GetRoutingID())); + render_frame->Send( + new PDFHostMsg_PDFHasUnsupportedFeature(render_frame->GetRoutingID())); return PP_OK; } @@ -160,8 +159,8 @@ if (!instance) return PP_ERROR_FAILED; - content::RenderView* render_view = instance->GetRenderView(); - if (!render_view) + content::RenderFrame* render_frame = instance->GetRenderFrame(); + if (!render_frame) return PP_ERROR_FAILED; GURL url = instance->GetPluginURL(); @@ -169,8 +168,8 @@ referrer.url = url; referrer.policy = blink::WebReferrerPolicyDefault; referrer = content::Referrer::SanitizeForRequest(url, referrer); - render_view->Send( - new PDFHostMsg_PDFSaveURLAs(render_view->GetRoutingID(), url, referrer)); + render_frame->Send( + new PDFHostMsg_PDFSaveURLAs(render_frame->GetRoutingID(), url, referrer)); return PP_OK; } @@ -236,10 +235,10 @@ } } -content::RenderView* PepperPDFHost::GetRenderView() { +content::RenderFrame* PepperPDFHost::GetRenderFrame() { content::PepperPluginInstance* instance = host_->GetPluginInstance(pp_instance()); - return instance ? instance->GetRenderView() : nullptr; + return instance ? instance->GetRenderFrame() : nullptr; } } // namespace pdf
diff --git a/components/pdf/renderer/pepper_pdf_host.h b/components/pdf/renderer/pepper_pdf_host.h index 5a41e87..5e838c9e 100644 --- a/components/pdf/renderer/pepper_pdf_host.h +++ b/components/pdf/renderer/pepper_pdf_host.h
@@ -26,7 +26,7 @@ namespace content { class PepperPluginInstance; -class RenderView; +class RenderFrame; class RendererPpapiHost; } @@ -108,7 +108,7 @@ void CreatePdfAccessibilityTreeIfNeeded(); - content::RenderView* GetRenderView(); + content::RenderFrame* GetRenderFrame(); std::unique_ptr<PdfAccessibilityTree> pdf_accessibility_tree_;
diff --git a/components/policy/core/browser/cloud/message_util.cc b/components/policy/core/browser/cloud/message_util.cc index 0b203df..82880db 100644 --- a/components/policy/core/browser/cloud/message_util.cc +++ b/components/policy/core/browser/cloud/message_util.cc
@@ -69,8 +69,8 @@ return IDS_POLICY_VALIDATION_WRONG_SETTINGS_ENTITY_ID; case CloudPolicyValidatorBase::VALIDATION_BAD_TIMESTAMP: return IDS_POLICY_VALIDATION_BAD_TIMESTAMP; - case CloudPolicyValidatorBase::VALIDATION_WRONG_TOKEN: - return IDS_POLICY_VALIDATION_WRONG_TOKEN; + case CloudPolicyValidatorBase::VALIDATION_BAD_DM_TOKEN: + return IDS_POLICY_VALIDATION_BAD_DM_TOKEN; case CloudPolicyValidatorBase::VALIDATION_BAD_USERNAME: return IDS_POLICY_VALIDATION_BAD_USERNAME; case CloudPolicyValidatorBase::VALIDATION_POLICY_PARSE_ERROR:
diff --git a/components/policy/core/browser/configuration_policy_handler_list.cc b/components/policy/core/browser/configuration_policy_handler_list.cc index da5d99b..8b5c524 100644 --- a/components/policy/core/browser/configuration_policy_handler_list.cc +++ b/components/policy/core/browser/configuration_policy_handler_list.cc
@@ -20,7 +20,7 @@ details_callback_(details_callback) {} ConfigurationPolicyHandlerList::~ConfigurationPolicyHandlerList() { - STLDeleteElements(&handlers_); + base::STLDeleteElements(&handlers_); } void ConfigurationPolicyHandlerList::AddHandler(
diff --git a/components/policy/core/common/BUILD.gn b/components/policy/core/common/BUILD.gn index 76471377..d892db6 100644 --- a/components/policy/core/common/BUILD.gn +++ b/components/policy/core/common/BUILD.gn
@@ -223,7 +223,6 @@ testonly = true sources = [ "cloud/cloud_policy_client_unittest.cc", - "cloud/cloud_policy_constants_unittest.cc", "cloud/cloud_policy_core_unittest.cc", "cloud/cloud_policy_manager_unittest.cc", "cloud/cloud_policy_refresh_scheduler_unittest.cc",
diff --git a/components/policy/core/common/cloud/cloud_policy_client.cc b/components/policy/core/common/cloud/cloud_policy_client.cc index 4901a1ab..eaee73ca 100644 --- a/components/policy/core/common/cloud/cloud_policy_client.cc +++ b/components/policy/core/common/cloud/cloud_policy_client.cc
@@ -69,7 +69,7 @@ } CloudPolicyClient::~CloudPolicyClient() { - STLDeleteValues(&responses_); + base::STLDeleteValues(&responses_); } void CloudPolicyClient::SetupRegistration(const std::string& dm_token, @@ -82,7 +82,7 @@ client_id_ = client_id; request_jobs_.clear(); policy_fetch_request_job_.reset(); - STLDeleteValues(&responses_); + base::STLDeleteValues(&responses_); NotifyRegistrationStateChanged(); } @@ -520,7 +520,7 @@ if (status == DM_STATUS_SUCCESS) { const em::DevicePolicyResponse& policy_response = response.policy_response(); - STLDeleteValues(&responses_); + base::STLDeleteValues(&responses_); for (int i = 0; i < policy_response.response_size(); ++i) { const em::PolicyFetchResponse& response = policy_response.response(i); em::PolicyData policy_data; @@ -535,7 +535,7 @@ if (policy_data.has_settings_entity_id()) entity_id = policy_data.settings_entity_id(); std::pair<std::string, std::string> key(type, entity_id); - if (ContainsKey(responses_, key)) { + if (base::ContainsKey(responses_, key)) { LOG(WARNING) << "Duplicate PolicyFetchResponse for type: " << type << ", entity: " << entity_id << ", ignoring"; continue;
diff --git a/components/policy/core/common/cloud/cloud_policy_constants.cc b/components/policy/core/common/cloud/cloud_policy_constants.cc index 46ecf6b..8fbc7d72 100644 --- a/components/policy/core/common/cloud/cloud_policy_constants.cc +++ b/components/policy/core/common/cloud/cloud_policy_constants.cc
@@ -102,43 +102,4 @@ } } -void SetManagementMode(em::PolicyData& policy_data, ManagementMode mode) { - switch (mode) { - case MANAGEMENT_MODE_LOCAL_OWNER: - policy_data.set_management_mode(em::PolicyData::LOCAL_OWNER); - return; - - case MANAGEMENT_MODE_ENTERPRISE_MANAGED: - policy_data.set_management_mode(em::PolicyData::ENTERPRISE_MANAGED); - return; - - case MANAGEMENT_MODE_CONSUMER_MANAGED: - policy_data.set_management_mode(em::PolicyData::CONSUMER_MANAGED); - return; - } - NOTREACHED(); -} - -ManagementMode GetManagementMode(const em::PolicyData& policy_data) { - if (policy_data.has_management_mode()) { - switch (policy_data.management_mode()) { - case em::PolicyData::LOCAL_OWNER: - return MANAGEMENT_MODE_LOCAL_OWNER; - - case em::PolicyData::ENTERPRISE_MANAGED: - return MANAGEMENT_MODE_ENTERPRISE_MANAGED; - - case em::PolicyData::CONSUMER_MANAGED: - return MANAGEMENT_MODE_CONSUMER_MANAGED; - - default: - NOTREACHED(); - return MANAGEMENT_MODE_LOCAL_OWNER; - } - } - - return policy_data.has_request_token() ? - MANAGEMENT_MODE_ENTERPRISE_MANAGED : MANAGEMENT_MODE_LOCAL_OWNER; -} - } // namespace policy
diff --git a/components/policy/core/common/cloud/cloud_policy_constants.h b/components/policy/core/common/cloud/cloud_policy_constants.h index 7535eeb..fc75e2d 100644 --- a/components/policy/core/common/cloud/cloud_policy_constants.h +++ b/components/policy/core/common/cloud/cloud_policy_constants.h
@@ -126,27 +126,6 @@ // launch a kiosk webapp. }; -// An enum that indicates if a device that has a local owner, is enterprise- -// managed, or is consumer-managed. This is a copy of ManagementMode in -// PolicyData. See device_management_backend.proto for the explanation of each -// mode. -enum ManagementMode { - MANAGEMENT_MODE_LOCAL_OWNER = 0, - MANAGEMENT_MODE_ENTERPRISE_MANAGED = 1, - MANAGEMENT_MODE_CONSUMER_MANAGED = 2, -}; - -// Sets management mode field in the |policy_data|. -POLICY_EXPORT void SetManagementMode( - enterprise_management::PolicyData& policy_data, - ManagementMode mode); - -// Returns the management mode of |policy_data|. You should use this function -// instead of using |management_mode| in |policy_data| to handle legacy -// |policy_data| that doesn't have |management_mode| set. -POLICY_EXPORT ManagementMode GetManagementMode( - const enterprise_management::PolicyData& policy_data); - } // namespace policy #endif // COMPONENTS_POLICY_CORE_COMMON_CLOUD_CLOUD_POLICY_CONSTANTS_H_
diff --git a/components/policy/core/common/cloud/cloud_policy_constants_unittest.cc b/components/policy/core/common/cloud/cloud_policy_constants_unittest.cc deleted file mode 100644 index 456ed3d4..0000000 --- a/components/policy/core/common/cloud/cloud_policy_constants_unittest.cc +++ /dev/null
@@ -1,48 +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 "components/policy/core/common/cloud/cloud_policy_constants.h" - -#include "policy/proto/device_management_backend.pb.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace em = enterprise_management; - -namespace policy { - -class CloudPolicyConstantsTest : public testing::Test { - public: - em::PolicyData policy_data_; -}; - -TEST_F(CloudPolicyConstantsTest, GetManagementModeForLegacyPolicyData) { - // Legacy PolicyData does not have |management_mode|. - policy_data_.clear_management_mode(); - - // PolicyData with no |request_token| is locally owned. - policy_data_.clear_request_token(); - EXPECT_EQ(MANAGEMENT_MODE_LOCAL_OWNER, GetManagementMode(policy_data_)); - - // PolicyData with |request_token| is enterprise-managed. - policy_data_.set_request_token("fake_request_token"); - EXPECT_EQ(MANAGEMENT_MODE_ENTERPRISE_MANAGED, - GetManagementMode(policy_data_)); -} - -TEST_F(CloudPolicyConstantsTest, - GetManagementModeForPolicyDataWithManagementMode) { - policy_data_.set_request_token("fake_request_token"); - - policy_data_.set_management_mode(em::PolicyData::CONSUMER_MANAGED); - EXPECT_EQ(MANAGEMENT_MODE_CONSUMER_MANAGED, GetManagementMode(policy_data_)); - - policy_data_.set_management_mode(em::PolicyData::ENTERPRISE_MANAGED); - EXPECT_EQ(MANAGEMENT_MODE_ENTERPRISE_MANAGED, - GetManagementMode(policy_data_)); - - policy_data_.set_management_mode(em::PolicyData::LOCAL_OWNER); - EXPECT_EQ(MANAGEMENT_MODE_LOCAL_OWNER, GetManagementMode(policy_data_)); -} - -} // namespace policy
diff --git a/components/policy/core/common/cloud/cloud_policy_validator.cc b/components/policy/core/common/cloud/cloud_policy_validator.cc index 03971e62a..a0624988 100644 --- a/components/policy/core/common/cloud/cloud_policy_validator.cc +++ b/components/policy/core/common/cloud/cloud_policy_validator.cc
@@ -79,10 +79,10 @@ } void CloudPolicyValidatorBase::ValidateDMToken( - const std::string& token, + const std::string& expected_dm_token, ValidateDMTokenOption dm_token_option) { - validation_flags_ |= VALIDATE_TOKEN; - token_ = token; + validation_flags_ |= VALIDATE_DM_TOKEN; + dm_token_ = expected_dm_token; dm_token_option_ = dm_token_option; } @@ -159,7 +159,7 @@ validation_flags_(0), timestamp_not_before_(0), timestamp_not_after_(0), - timestamp_option_(TIMESTAMP_REQUIRED), + timestamp_option_(TIMESTAMP_FULLY_VALIDATED), dm_token_option_(DM_TOKEN_REQUIRED), canonicalize_user_(false), allow_key_rotation_(false), @@ -227,16 +227,16 @@ int flag; Status (CloudPolicyValidatorBase::* checkFunction)(); } kCheckFunctions[] = { - { VALIDATE_SIGNATURE, &CloudPolicyValidatorBase::CheckSignature }, - { VALIDATE_INITIAL_KEY, &CloudPolicyValidatorBase::CheckInitialKey }, - { VALIDATE_CACHED_KEY, &CloudPolicyValidatorBase::CheckCachedKey }, - { VALIDATE_POLICY_TYPE, &CloudPolicyValidatorBase::CheckPolicyType }, - { VALIDATE_ENTITY_ID, &CloudPolicyValidatorBase::CheckEntityId }, - { VALIDATE_TOKEN, &CloudPolicyValidatorBase::CheckToken }, - { VALIDATE_USERNAME, &CloudPolicyValidatorBase::CheckUsername }, - { VALIDATE_DOMAIN, &CloudPolicyValidatorBase::CheckDomain }, - { VALIDATE_TIMESTAMP, &CloudPolicyValidatorBase::CheckTimestamp }, - { VALIDATE_PAYLOAD, &CloudPolicyValidatorBase::CheckPayload }, + { VALIDATE_SIGNATURE, &CloudPolicyValidatorBase::CheckSignature }, + { VALIDATE_INITIAL_KEY, &CloudPolicyValidatorBase::CheckInitialKey }, + { VALIDATE_CACHED_KEY, &CloudPolicyValidatorBase::CheckCachedKey }, + { VALIDATE_POLICY_TYPE, &CloudPolicyValidatorBase::CheckPolicyType }, + { VALIDATE_ENTITY_ID, &CloudPolicyValidatorBase::CheckEntityId }, + { VALIDATE_DM_TOKEN, &CloudPolicyValidatorBase::CheckDMToken }, + { VALIDATE_USERNAME, &CloudPolicyValidatorBase::CheckUsername }, + { VALIDATE_DOMAIN, &CloudPolicyValidatorBase::CheckDomain }, + { VALIDATE_TIMESTAMP, &CloudPolicyValidatorBase::CheckTimestamp }, + { VALIDATE_PAYLOAD, &CloudPolicyValidatorBase::CheckPayload }, }; for (size_t i = 0; i < arraysize(kCheckFunctions); ++i) { @@ -411,7 +411,7 @@ } CloudPolicyValidatorBase::Status CloudPolicyValidatorBase::CheckTimestamp() { - if (timestamp_option_ == TIMESTAMP_NOT_REQUIRED) + if (timestamp_option_ == TIMESTAMP_NOT_VALIDATED) return VALIDATION_OK; if (!policy_data_->has_timestamp()) { @@ -428,7 +428,7 @@ // accidentally sends a time from the distant future, this time is stored // locally and after the server time is corrected, due to rollback prevention // the client could not receive policy updates until that future date. - if (timestamp_option_ == TIMESTAMP_REQUIRED && + if (timestamp_option_ == TIMESTAMP_FULLY_VALIDATED && policy_data_->timestamp() > timestamp_not_after_) { LOG(ERROR) << "Policy from the future: " << policy_data_->timestamp(); return VALIDATION_BAD_TIMESTAMP; @@ -437,19 +437,17 @@ return VALIDATION_OK; } -CloudPolicyValidatorBase::Status CloudPolicyValidatorBase::CheckToken() { - // Make sure the token matches the expected token (if any) and also - // make sure the token itself is valid (non-empty if DM_TOKEN_REQUIRED). +CloudPolicyValidatorBase::Status CloudPolicyValidatorBase::CheckDMToken() { if (dm_token_option_ == DM_TOKEN_REQUIRED && (!policy_data_->has_request_token() || policy_data_->request_token().empty())) { - LOG(ERROR) << "Empty DM token encountered - expected: " << token_; - return VALIDATION_WRONG_TOKEN; + LOG(ERROR) << "Empty DM token encountered - expected: " << dm_token_; + return VALIDATION_BAD_DM_TOKEN; } - if (!token_.empty() && policy_data_->request_token() != token_) { + if (!dm_token_.empty() && policy_data_->request_token() != dm_token_) { LOG(ERROR) << "Invalid DM token: " << policy_data_->request_token() - << " - expected: " << token_; - return VALIDATION_WRONG_TOKEN; + << " - expected: " << dm_token_; + return VALIDATION_BAD_DM_TOKEN; } return VALIDATION_OK;
diff --git a/components/policy/core/common/cloud/cloud_policy_validator.h b/components/policy/core/common/cloud/cloud_policy_validator.h index fd1677b..601ecd86 100644 --- a/components/policy/core/common/cloud/cloud_policy_validator.h +++ b/components/policy/core/common/cloud/cloud_policy_validator.h
@@ -69,10 +69,10 @@ VALIDATION_WRONG_POLICY_TYPE, // Unexpected settings entity id. VALIDATION_WRONG_SETTINGS_ENTITY_ID, - // Time stamp from the future. + // Time stamp outside expected range. VALIDATION_BAD_TIMESTAMP, - // Token doesn't match. - VALIDATION_WRONG_TOKEN, + // DM token is empty or doesn't match. + VALIDATION_BAD_DM_TOKEN, // Username doesn't match. VALIDATION_BAD_USERNAME, // Policy payload protobuf parse error. @@ -84,27 +84,29 @@ }; enum ValidateDMTokenOption { - // The policy must have a non-empty DMToken. + // The DM token from policy must match the expected DM token unless the + // expected DM token is empty. In addition, the DM token from policy must + // not be empty. DM_TOKEN_REQUIRED, - // The policy may have an empty or missing DMToken, if the expected token - // is also empty. + // The DM token from policy must match the expected DM token unless the + // expected DM token is empty. DM_TOKEN_NOT_REQUIRED, }; enum ValidateTimestampOption { - // The policy must have a timestamp field and it should be checked against - // both the start and end times. - TIMESTAMP_REQUIRED, + // The policy must have a timestamp field and the timestamp is checked + // against both start and end times. + TIMESTAMP_FULLY_VALIDATED, - // The timestamp should only be compared vs the |not_before| value (this - // is appropriate for platforms with unreliable system times, where we want - // to ensure that fresh policy is newer than existing policy, but we can't - // do any other validation). + // The timestamp is only checked against the |not_before| value. (This is + // appropriate for platforms with unreliable system times where we want to + // ensure that fresh policy is newer than existing policy, but we can't do + // any other validation). TIMESTAMP_NOT_BEFORE, - // No timestamp field is required. - TIMESTAMP_NOT_REQUIRED, + // The timestamp is not validated. + TIMESTAMP_NOT_VALIDATED, }; virtual ~CloudPolicyValidatorBase(); @@ -122,39 +124,41 @@ return policy_data_; } - // Instructs the validator to check that the policy timestamp is not before - // |not_before| and not after |not_after| + grace interval. If - // |timestamp_option| is set to TIMESTAMP_REQUIRED, then the policy will fail - // validation if it does not have a timestamp field. + // Instruct the validator to check that the policy timestamp is not before + // |not_before| and not after |not_after| + grace interval. Depending on + // |timestamp_option|, some or all of the checks may be waived. void ValidateTimestamp(base::Time not_before, base::Time not_after, ValidateTimestampOption timestamp_option); - // Validates that the username in the policy blob matches |expected_user|. If - // canonicalize is set to true, both values will be canonicalized before - // comparison. + // Instruct the validator to check that the username in the policy blob + // matches |expected_user|. If |canonicalize| is set to true, both values are + // canonicalized before comparison. void ValidateUsername(const std::string& expected_user, bool canonicalize); - // Validates the policy blob is addressed to |expected_domain|. This uses the - // domain part of the username field in the policy for the check. + // Instruct the validator to check that the policy blob is addressed to + // |expected_domain|. This uses the domain part of the username field in the + // policy for the check. void ValidateDomain(const std::string& expected_domain); - // Makes sure the DM token on the policy matches |expected_token|. - // If |dm_token_option| is DM_TOKEN_REQUIRED, then the policy will fail - // validation if it does not have a non-empty request_token field. - void ValidateDMToken(const std::string& dm_token, + // Instruct the validator to check that the DM token from policy matches + // |expected_dm_token| unless |expected_dm_token| is empty. In addition, the + // DM token from policy must not be empty if |dm_token_option| is + // DM_TOKEN_REQUIRED. + void ValidateDMToken(const std::string& expected_dm_token, ValidateDMTokenOption dm_token_option); - // Validates the policy type. + // Instruct the validator to check the policy type. void ValidatePolicyType(const std::string& policy_type); - // Validates the settings_entity_id value. + // Instruct the validator to check the settings_entity_id value. void ValidateSettingsEntityId(const std::string& settings_entity_id); - // Validates that the payload can be decoded successfully. + // Instruct the validator to check that the payload can be decoded + // successfully. void ValidatePayload(); - // Verifies that |cached_key| is valid, by verifying the + // Instruct the validator to check that |cached_key| is valid by verifying the // |cached_key_signature| using the passed |owning_domain| and // |verification_key|. void ValidateCachedKey(const std::string& cached_key, @@ -162,31 +166,32 @@ const std::string& verification_key, const std::string& owning_domain); - // Verifies that the signature on the policy blob verifies against |key|. If - // |allow_key_rotation| is true and there is a key rotation present in the - // policy blob, this checks the signature on the new key against |key| and the - // policy blob against the new key. New key is also validated using the passed - // |verification_key| and |owning_domain|, and the + // Instruct the validator to check that the signature on the policy blob + // verifies against |key|. If |allow_key_rotation| is true and there is a key + // rotation present in the policy blob, this checks the signature on the new + // key against |key| and the policy blob against the new key. New key is also + // validated using the passed |verification_key| and |owning_domain|, and the // |new_public_key_verification_signature| field. void ValidateSignature(const std::string& key, const std::string& verification_key, const std::string& owning_domain, bool allow_key_rotation); - // Similar to ValidateSignature(), this checks the signature on the - // policy blob. However, this variant expects a new policy key set in the - // policy blob and makes sure the policy is signed using that key. This should - // be called at setup time when there is no existing policy key present to - // check against. New key is validated using the passed |verification_key| and - // the new_public_key_verification_signature field. + // Similar to ValidateSignature(), this instructs the validator to check the + // signature on the policy blob. However, this variant expects a new policy + // key set in the policy blob and makes sure the policy is signed using that + // key. This should be called at setup time when there is no existing policy + // key present to check against. New key is validated using the passed + // |verification_key| and the new_public_key_verification_signature field. void ValidateInitialKey(const std::string& verification_key, const std::string& owning_domain); - // Convenience helper that configures timestamp and token validation based on - // the current policy blob. |policy_data| may be NULL, in which case the - // timestamp validation will drop the lower bound. |dm_token_option| - // and |timestamp_option| have the same effect as the corresponding - // parameters for ValidateTimestamp() and ValidateDMToken(). + // Convenience helper that instructs the validator to check timestamp and DM + // token based on the current policy blob. |policy_data| may be nullptr, in + // which case the timestamp lower bound check is waived and the DM token is + // checked against an empty string. |dm_token_option| and |timestamp_option| + // have the same effect as the corresponding parameters for + // ValidateTimestamp() and ValidateDMToken(). void ValidateAgainstCurrentPolicy( const enterprise_management::PolicyData* policy_data, ValidateTimestampOption timestamp_option, @@ -215,7 +220,7 @@ VALIDATE_TIMESTAMP = 1 << 0, VALIDATE_USERNAME = 1 << 1, VALIDATE_DOMAIN = 1 << 2, - VALIDATE_TOKEN = 1 << 3, + VALIDATE_DM_TOKEN = 1 << 3, VALIDATE_POLICY_TYPE = 1 << 4, VALIDATE_ENTITY_ID = 1 << 5, VALIDATE_PAYLOAD = 1 << 6, @@ -266,7 +271,7 @@ Status CheckTimestamp(); Status CheckUsername(); Status CheckDomain(); - Status CheckToken(); + Status CheckDMToken(); Status CheckPolicyType(); Status CheckEntityId(); Status CheckPayload(); @@ -294,7 +299,7 @@ std::string user_; bool canonicalize_user_; std::string domain_; - std::string token_; + std::string dm_token_; std::string policy_type_; std::string settings_entity_id_; std::string key_; @@ -320,7 +325,7 @@ // Creates a new validator. // |background_task_runner| is optional; if RunValidation() is used directly - // and StartValidation() is not used then it can be NULL. + // and StartValidation() is not used then it can be nullptr. static CloudPolicyValidator<PayloadProto>* Create( std::unique_ptr<enterprise_management::PolicyFetchResponse> policy_response,
diff --git a/components/policy/core/common/cloud/cloud_policy_validator_unittest.cc b/components/policy/core/common/cloud/cloud_policy_validator_unittest.cc index 7cce23c..49a09968 100644 --- a/components/policy/core/common/cloud/cloud_policy_validator_unittest.cc +++ b/components/policy/core/common/cloud/cloud_policy_validator_unittest.cc
@@ -45,7 +45,7 @@ : timestamp_(base::Time::UnixEpoch() + base::TimeDelta::FromMilliseconds( PolicyBuilder::kFakeTimestamp)), - timestamp_option_(CloudPolicyValidatorBase::TIMESTAMP_REQUIRED), + timestamp_option_(CloudPolicyValidatorBase::TIMESTAMP_FULLY_VALIDATED), ignore_missing_dm_token_(CloudPolicyValidatorBase::DM_TOKEN_REQUIRED), allow_key_rotation_(true), existing_dm_token_(PolicyBuilder::kFakeToken), @@ -188,7 +188,7 @@ } TEST_F(CloudPolicyValidatorTest, IgnoreMissingTimestamp) { - timestamp_option_ = CloudPolicyValidatorBase::TIMESTAMP_NOT_REQUIRED; + timestamp_option_ = CloudPolicyValidatorBase::TIMESTAMP_NOT_VALIDATED; policy_.policy_data().clear_timestamp(); Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_OK)); } @@ -216,30 +216,30 @@ Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_OK)); } -TEST_F(CloudPolicyValidatorTest, ErrorNoRequestToken) { +TEST_F(CloudPolicyValidatorTest, ErrorNoDMToken) { policy_.policy_data().clear_request_token(); - Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_WRONG_TOKEN)); + Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_BAD_DM_TOKEN)); } -TEST_F(CloudPolicyValidatorTest, ErrorNoRequestTokenNotRequired) { - // Even though DMTokens are not required, if the existing policy has a token, +TEST_F(CloudPolicyValidatorTest, ErrorNoDMTokenNotRequired) { + // Even though DM tokens are not required, if the existing policy has a token, // we should still generate an error if the new policy has none. policy_.policy_data().clear_request_token(); ignore_missing_dm_token_ = CloudPolicyValidatorBase::DM_TOKEN_NOT_REQUIRED; - Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_WRONG_TOKEN)); + Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_BAD_DM_TOKEN)); } -TEST_F(CloudPolicyValidatorTest, ErrorNoRequestTokenNoTokenPassed) { +TEST_F(CloudPolicyValidatorTest, ErrorNoDMTokenNoTokenPassed) { // Mimic the first fetch of policy (no existing DM token) - should still - // complain about not having any DMToken. + // complain about not having any DM token. existing_dm_token_.clear(); policy_.policy_data().clear_request_token(); - Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_WRONG_TOKEN)); + Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_BAD_DM_TOKEN)); } -TEST_F(CloudPolicyValidatorTest, ErrorInvalidRequestToken) { +TEST_F(CloudPolicyValidatorTest, ErrorInvalidDMToken) { policy_.policy_data().set_request_token("invalid"); - Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_WRONG_TOKEN)); + Validate(CheckStatus(CloudPolicyValidatorBase::VALIDATION_BAD_DM_TOKEN)); } TEST_F(CloudPolicyValidatorTest, ErrorNoPolicyValue) {
diff --git a/components/policy/core/common/cloud/component_cloud_policy_service_unittest.cc b/components/policy/core/common/cloud/component_cloud_policy_service_unittest.cc index 80b3734..f92c9024 100644 --- a/components/policy/core/common/cloud/component_cloud_policy_service_unittest.cc +++ b/components/policy/core/common/cloud/component_cloud_policy_service_unittest.cc
@@ -394,7 +394,7 @@ std::map<std::string, std::string> contents; cache_->LoadAllSubkeys("extension-policy", &contents); EXPECT_EQ(1u, contents.size()); - EXPECT_TRUE(ContainsKey(contents, kTestExtension2)); + EXPECT_TRUE(base::ContainsKey(contents, kTestExtension2)); } TEST_F(ComponentCloudPolicyServiceTest, SignInAfterStartup) { @@ -538,8 +538,8 @@ std::map<std::string, std::string> contents; cache_->LoadAllSubkeys("extension-policy", &contents); ASSERT_EQ(2u, contents.size()); - EXPECT_TRUE(ContainsKey(contents, kTestExtension)); - EXPECT_TRUE(ContainsKey(contents, kTestExtension2)); + EXPECT_TRUE(base::ContainsKey(contents, kTestExtension)); + EXPECT_TRUE(base::ContainsKey(contents, kTestExtension2)); PolicyBundle expected_bundle; const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kTestExtension); @@ -566,8 +566,8 @@ contents.clear(); cache_->LoadAllSubkeys("extension-policy", &contents); ASSERT_EQ(1u, contents.size()); - EXPECT_TRUE(ContainsKey(contents, kTestExtension)); - EXPECT_FALSE(ContainsKey(contents, kTestExtension2)); + EXPECT_TRUE(base::ContainsKey(contents, kTestExtension)); + EXPECT_FALSE(base::ContainsKey(contents, kTestExtension2)); // And the service isn't publishing policy for the second extension anymore. expected_bundle.Clear();
diff --git a/components/policy/core/common/cloud/external_policy_data_fetcher.cc b/components/policy/core/common/cloud/external_policy_data_fetcher.cc index e8fc335f..d3474e2 100644 --- a/components/policy/core/common/cloud/external_policy_data_fetcher.cc +++ b/components/policy/core/common/cloud/external_policy_data_fetcher.cc
@@ -160,7 +160,7 @@ ExternalPolicyDataFetcherBackend::~ExternalPolicyDataFetcherBackend() { DCHECK(io_task_runner_->RunsTasksOnCurrentThread()); - STLDeleteContainerPairFirstPointers(job_map_.begin(), job_map_.end()); + base::STLDeleteContainerPairFirstPointers(job_map_.begin(), job_map_.end()); } std::unique_ptr<ExternalPolicyDataFetcher>
diff --git a/components/policy/core/common/cloud/external_policy_data_updater.cc b/components/policy/core/common/cloud/external_policy_data_updater.cc index eebbd9e1..9edec6e2 100644 --- a/components/policy/core/common/cloud/external_policy_data_updater.cc +++ b/components/policy/core/common/cloud/external_policy_data_updater.cc
@@ -306,7 +306,7 @@ ExternalPolicyDataUpdater::~ExternalPolicyDataUpdater() { DCHECK(task_runner_->RunsTasksOnCurrentThread()); shutting_down_ = true; - STLDeleteValues(&job_map_); + base::STLDeleteValues(&job_map_); } void ExternalPolicyDataUpdater::FetchExternalData(
diff --git a/components/policy/core/common/config_dir_policy_loader.cc b/components/policy/core/common/config_dir_policy_loader.cc index 018a12e..e604cf3 100644 --- a/components/policy/core/common/config_dir_policy_loader.cc +++ b/components/policy/core/common/config_dir_policy_loader.cc
@@ -212,7 +212,7 @@ for (base::DictionaryValue::Iterator domains_it(*domains_dictionary); !domains_it.IsAtEnd(); domains_it.Advance()) { - if (!ContainsKey(supported_domains, domains_it.key())) { + if (!base::ContainsKey(supported_domains, domains_it.key())) { LOG(WARNING) << "Unsupported 3rd party policy domain: " << domains_it.key(); continue;
diff --git a/components/policy/core/common/policy_bundle.cc b/components/policy/core/common/policy_bundle.cc index 96d7e82..bb661f84 100644 --- a/components/policy/core/common/policy_bundle.cc +++ b/components/policy/core/common/policy_bundle.cc
@@ -104,7 +104,7 @@ } void PolicyBundle::Clear() { - STLDeleteValues(&policy_bundle_); + base::STLDeleteValues(&policy_bundle_); } } // namespace policy
diff --git a/components/policy/core/common/policy_service_impl.cc b/components/policy/core/common/policy_service_impl.cc index 655f091..4f8a612 100644 --- a/components/policy/core/common/policy_service_impl.cc +++ b/components/policy/core/common/policy_service_impl.cc
@@ -100,7 +100,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); for (Iterator it = providers_.begin(); it != providers_.end(); ++it) (*it)->RemoveObserver(this); - STLDeleteValues(&observers_); + base::STLDeleteValues(&observers_); } void PolicyServiceImpl::AddObserver(PolicyDomain domain,
diff --git a/components/policy/core/common/registry_dict_win.cc b/components/policy/core/common/registry_dict_win.cc index 6451ea8..32d9828 100644 --- a/components/policy/core/common/registry_dict_win.cc +++ b/components/policy/core/common/registry_dict_win.cc
@@ -184,7 +184,7 @@ } void RegistryDict::ClearKeys() { - STLDeleteValues(&keys_); + base::STLDeleteValues(&keys_); } base::Value* RegistryDict::GetValue(const std::string& name) { @@ -221,7 +221,7 @@ } void RegistryDict::ClearValues() { - STLDeleteValues(&values_); + base::STLDeleteValues(&values_); } void RegistryDict::Merge(const RegistryDict& other) {
diff --git a/components/policy/core/common/schema.cc b/components/policy/core/common/schema.cc index 9af816e..f925e02 100644 --- a/components/policy/core/common/schema.cc +++ b/components/policy/core/common/schema.cc
@@ -488,7 +488,7 @@ } std::string id_string; if (schema.GetString(schema::kId, &id_string)) { - if (ContainsKey(*id_map, id_string)) { + if (base::ContainsKey(*id_map, id_string)) { *error = "Duplicated id: " + id_string; return false; }
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 6bd1a9d..71a5c167 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -137,7 +137,7 @@ # persistent IDs for all fields (but not for groups!) are needed. These are # specified by the 'id' keys of each policy. NEVER CHANGE EXISTING IDs, # because doing so would break the deployed wire format! -# For your editing convenience: highest ID currently used: 338 +# For your editing convenience: highest ID currently used: 339 # # Placeholders: # The following placeholder strings are automatically substituted: @@ -8795,6 +8795,23 @@ If this is set to false, automatically-generated content suggestions are not shown on the New Tab page.''', }, + { + 'name': 'WebRtcUdpPortRange', + 'type': 'string', + 'schema': { 'type': 'string' }, + 'supported_on': ['chrome.*:54-', 'chrome_os:54-', 'android:54-'], + 'features': { + 'dynamic_refresh': False, + 'per_profile': True, + }, + 'example_value': '10000-11999', + 'id': 339, + 'caption': '''Restrict the range of local UDP ports used by WebRTC''', + 'tags': [], + 'desc': '''If the policy is set, the UDP port range used by WebRTC is restricted to the specified port interval (endpoints included). + + If the policy is not set, or if it is set to the empty string or an invalid port range, WebRTC is allowed to use any available local UDP port.''', + }, ], 'messages': { # Messages that are not associated to any policies.
diff --git a/components/policy_strings.grdp b/components/policy_strings.grdp index b0763bc..5a6bf1a4 100644 --- a/components/policy_strings.grdp +++ b/components/policy_strings.grdp
@@ -77,8 +77,8 @@ <message name="IDS_POLICY_VALIDATION_BAD_TIMESTAMP" desc="Message indicating the policy timestamp is bad."> Bad policy timestamp </message> - <message name="IDS_POLICY_VALIDATION_WRONG_TOKEN" desc="Message indicating the policy token is different from the one expected."> - Returned policy token doesn't match current token + <message name="IDS_POLICY_VALIDATION_BAD_DM_TOKEN" desc="Message indicating the policy token is empty or different from the one expected."> + Returned policy token is empty or doesn't match current token </message> <message name="IDS_POLICY_VALIDATION_BAD_USERNAME" desc="Message indicating policy validation failed due to bad username/domain."> Wrong policy subject
diff --git a/components/precache.gypi b/components/precache.gypi index c2d2187..218c81e2 100644 --- a/components/precache.gypi +++ b/components/precache.gypi
@@ -64,7 +64,7 @@ 'precache_core', 'precache_core_proto', '../base/base.gyp:base', - '../components/components.gyp:sync_driver', + '../components/sync.gyp:sync', '../content/content.gyp:content_browser', '../url/url.gyp:url_lib', ],
diff --git a/components/precache/content/BUILD.gn b/components/precache/content/BUILD.gn index c22986cc..53f9b51 100644 --- a/components/precache/content/BUILD.gn +++ b/components/precache/content/BUILD.gn
@@ -17,7 +17,7 @@ "//components/precache/core", "//components/precache/core:proto", "//components/prefs", - "//components/sync_driver", + "//components/sync", "//components/variations", "//content/public/browser", "//net",
diff --git a/components/precache/content/DEPS b/components/precache/content/DEPS index 235cc527..25f55a1 100644 --- a/components/precache/content/DEPS +++ b/components/precache/content/DEPS
@@ -1,6 +1,6 @@ include_rules = [ "+components/keyed_service", - "+components/sync_driver", + "+components/sync/driver", "+components/variations", "+content/public/browser", "+net/base",
diff --git a/components/precache/content/precache_manager.cc b/components/precache/content/precache_manager.cc index 8e6e1a6..7951b24 100644 --- a/components/precache/content/precache_manager.cc +++ b/components/precache/content/precache_manager.cc
@@ -19,7 +19,7 @@ #include "components/precache/core/precache_switches.h" #include "components/precache/core/proto/unfinished_work.pb.h" #include "components/prefs/pref_service.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_service.h" #include "components/variations/metrics_util.h" #include "components/variations/variations_associated_data.h" #include "content/public/browser/browser_context.h"
diff --git a/components/prefs/pref_notifier_impl.cc b/components/prefs/pref_notifier_impl.cc index b3d5660..ffb50b4006 100644 --- a/components/prefs/pref_notifier_impl.cc +++ b/components/prefs/pref_notifier_impl.cc
@@ -32,8 +32,8 @@ if (!init_observers_.empty()) LOG(WARNING) << "Init observer found at shutdown."; - STLDeleteContainerPairSecondPointers(pref_observers_.begin(), - pref_observers_.end()); + base::STLDeleteContainerPairSecondPointers(pref_observers_.begin(), + pref_observers_.end()); pref_observers_.clear(); init_observers_.clear(); }
diff --git a/components/prefs/pref_registry.cc b/components/prefs/pref_registry.cc index 92d161e..c42e77f 100644 --- a/components/prefs/pref_registry.cc +++ b/components/prefs/pref_registry.cc
@@ -59,8 +59,8 @@ "invalid preference type: " << orig_type; DCHECK(!defaults_->GetValue(path, NULL)) << "Trying to register a previously registered pref: " << path; - DCHECK(!ContainsKey(registration_flags_, path)) << - "Trying to register a previously registered pref: " << path; + DCHECK(!base::ContainsKey(registration_flags_, path)) + << "Trying to register a previously registered pref: " << path; defaults_->SetDefaultValue(path, base::WrapUnique(default_value)); if (flags != NO_REGISTRATION_FLAGS)
diff --git a/components/proximity_auth/bluetooth_throttler_impl.cc b/components/proximity_auth/bluetooth_throttler_impl.cc index 7f6b105..da4816d 100644 --- a/components/proximity_auth/bluetooth_throttler_impl.cc +++ b/components/proximity_auth/bluetooth_throttler_impl.cc
@@ -42,7 +42,7 @@ } void BluetoothThrottlerImpl::OnConnection(Connection* connection) { - DCHECK(!ContainsKey(connections_, connection)); + DCHECK(!base::ContainsKey(connections_, connection)); connections_.insert(connection); connection->AddObserver(this); } @@ -55,7 +55,7 @@ Connection* connection, Connection::Status old_status, Connection::Status new_status) { - DCHECK(ContainsKey(connections_, connection)); + DCHECK(base::ContainsKey(connections_, connection)); if (new_status == Connection::DISCONNECTED) { last_disconnect_time_ = clock_->NowTicks(); connection->RemoveObserver(this);
diff --git a/components/query_parser/query_parser.cc b/components/query_parser/query_parser.cc index 7b5e4eeb..260a75a 100644 --- a/components/query_parser/query_parser.cc +++ b/components/query_parser/query_parser.cc
@@ -184,7 +184,7 @@ QueryNodeList::QueryNodeList() {} QueryNodeList::~QueryNodeList() { - STLDeleteElements(&children_); + base::STLDeleteElements(&children_); } void QueryNodeList::AddChild(QueryNode* node) {
diff --git a/components/rappor/rappor_service.cc b/components/rappor/rappor_service.cc index f8bbdd6..a572c17 100644 --- a/components/rappor/rappor_service.cc +++ b/components/rappor/rappor_service.cc
@@ -65,7 +65,7 @@ } RapporService::~RapporService() { - STLDeleteValues(&metrics_map_); + base::STLDeleteValues(&metrics_map_); } void RapporService::AddDailyObserver( @@ -136,7 +136,7 @@ void RapporService::CancelNextLogRotation() { DCHECK(thread_checker_.CalledOnValidThread()); - STLDeleteValues(&metrics_map_); + base::STLDeleteValues(&metrics_map_); log_rotation_timer_.Stop(); } @@ -177,7 +177,7 @@ report->set_bits(std::string(bytes.begin(), bytes.end())); DVLOG(2) << "Exporting metric " << kv.first; } - STLDeleteValues(&metrics_map_); + base::STLDeleteValues(&metrics_map_); sampler_.ExportMetrics(secret_, reports);
diff --git a/components/resources/sync_driver_resources.grdp b/components/resources/sync_driver_resources.grdp index bb0caa3..50c1118 100644 --- a/components/resources/sync_driver_resources.grdp +++ b/components/resources/sync_driver_resources.grdp
@@ -1,14 +1,14 @@ <?xml version="1.0" encoding="utf-8"?> <grit-part> - <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_INDEX_HTML" file="../sync_driver/resources/index.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> - <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_INDEX_JS" file="../sync_driver/resources/sync_index.js" type="BINDATA" /> - <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_CHROME_SYNC_JS" file="../sync_driver/resources/chrome_sync.js" type="BINDATA" /> - <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_TYPES_JS" file="../sync_driver/resources/types.js" type="BINDATA" /> - <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SYNC_LOG_JS" file="../sync_driver/resources/sync_log.js" type="BINDATA" /> - <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SYNC_NODE_BROWSER_JS" file="../sync_driver/resources/sync_node_browser.js" type="BINDATA" /> - <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SYNC_SEARCH_JS" file="../sync_driver/resources/sync_search.js" type="BINDATA" /> - <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_ABOUT_JS" file="../sync_driver/resources/about.js" type="BINDATA" /> - <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_DATA_JS" file="../sync_driver/resources/data.js" type="BINDATA" /> - <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_EVENTS_JS" file="../sync_driver/resources/events.js" type="BINDATA" /> - <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SEARCH_JS" file="../sync_driver/resources/search.js" type="BINDATA" /> + <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_INDEX_HTML" file="../sync/driver/resources/index.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> + <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_INDEX_JS" file="../sync/driver/resources/sync_index.js" type="BINDATA" /> + <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_CHROME_SYNC_JS" file="../sync/driver/resources/chrome_sync.js" type="BINDATA" /> + <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_TYPES_JS" file="../sync/driver/resources/types.js" type="BINDATA" /> + <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SYNC_LOG_JS" file="../sync/driver/resources/sync_log.js" type="BINDATA" /> + <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SYNC_NODE_BROWSER_JS" file="../sync/driver/resources/sync_node_browser.js" type="BINDATA" /> + <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SYNC_SEARCH_JS" file="../sync/driver/resources/sync_search.js" type="BINDATA" /> + <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_ABOUT_JS" file="../sync/driver/resources/about.js" type="BINDATA" /> + <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_DATA_JS" file="../sync/driver/resources/data.js" type="BINDATA" /> + <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_EVENTS_JS" file="../sync/driver/resources/events.js" type="BINDATA" /> + <include name="IDR_SYNC_DRIVER_SYNC_INTERNALS_SEARCH_JS" file="../sync/driver/resources/search.js" type="BINDATA" /> </grit-part>
diff --git a/components/safe_browsing_db/BUILD.gn b/components/safe_browsing_db/BUILD.gn index 1e11626..50e96884 100644 --- a/components/safe_browsing_db/BUILD.gn +++ b/components/safe_browsing_db/BUILD.gn
@@ -257,6 +257,7 @@ ":v4_protocol_manager_util", ":v4_rice", "//base", + "//crypto", ] } @@ -304,6 +305,7 @@ ":v4_update_protocol_manager", "//base", "//content/test:test_support", + "//crypto", "//net", "//net:test_support", "//testing/gtest",
diff --git a/components/safe_browsing_db/database_manager.cc b/components/safe_browsing_db/database_manager.cc index b3bb2a6..973beedc 100644 --- a/components/safe_browsing_db/database_manager.cc +++ b/components/safe_browsing_db/database_manager.cc
@@ -101,7 +101,7 @@ OnCheckApiBlacklistUrlResult(check->url(), ThreatMetadata()); } } - STLDeleteElements(&api_checks_); + base::STLDeleteElements(&api_checks_); } SafeBrowsingDatabaseManager::ApiCheckSet::iterator
diff --git a/components/safe_browsing_db/v4_rice.cc b/components/safe_browsing_db/v4_rice.cc index 3016fac..0e71480 100644 --- a/components/safe_browsing_db/v4_rice.cc +++ b/components/safe_browsing_db/v4_rice.cc
@@ -14,7 +14,8 @@ namespace { -const unsigned int kMaxBitIndex = 8 * sizeof(uint32_t); +const int kBitsPerByte = 8; +const unsigned int kMaxBitIndex = kBitsPerByte * sizeof(uint32_t); void GetBytesFromUInt32(uint32_t word, char* bytes) { const size_t mask = 0xFF; @@ -264,10 +265,15 @@ }; std::string V4RiceDecoder::DebugString() const { + // Calculates the total number of bits that we have read from the buffer, + // excluding those that have been read into current_word_ but not yet + // consumed byt GetNextBits(). + unsigned bits_read = (data_byte_index_ - sizeof(uint32_t)) * kBitsPerByte + + current_word_bit_index_; return base::StringPrintf( - "current_word_: %x; data_byte_index_; %x, " + "bits_read: %x; current_word_: %x; data_byte_index_; %x, " "current_word_bit_index_: %x; rice_parameter_: %x", - current_word_, data_byte_index_, current_word_bit_index_, + bits_read, current_word_, data_byte_index_, current_word_bit_index_, rice_parameter_); }
diff --git a/components/safe_browsing_db/v4_store.cc b/components/safe_browsing_db/v4_store.cc index 69d49a2..fd01889 100644 --- a/components/safe_browsing_db/v4_store.cc +++ b/components/safe_browsing_db/v4_store.cc
@@ -8,10 +8,13 @@ #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/sparse_histogram.h" +#include "base/stl_util.h" #include "base/strings/stringprintf.h" #include "components/safe_browsing_db/v4_rice.h" #include "components/safe_browsing_db/v4_store.h" #include "components/safe_browsing_db/v4_store.pb.h" +#include "crypto/secure_hash.h" +#include "crypto/sha2.h" namespace safe_browsing { @@ -113,28 +116,44 @@ return true; } -ApplyUpdateResult V4Store::ProcessFullUpdate( - std::unique_ptr<ListUpdateResponse> response, - const std::unique_ptr<V4Store>& new_store) { - HashPrefixMap hash_prefix_map; - ApplyUpdateResult apply_update_result = - UpdateHashPrefixMapFromAdditions(response->additions(), &hash_prefix_map); - if (apply_update_result == APPLY_UPDATE_SUCCESS) { - new_store->hash_prefix_map_ = hash_prefix_map; - RecordStoreWriteResult(new_store->WriteToDisk(std::move(response))); +ApplyUpdateResult V4Store::ProcessPartialUpdateAndWriteToDisk( + const HashPrefixMap& hash_prefix_map_old, + std::unique_ptr<ListUpdateResponse> response) { + DCHECK(response->has_response_type()); + DCHECK_EQ(ListUpdateResponse::PARTIAL_UPDATE, response->response_type()); + + ApplyUpdateResult result = ProcessUpdate(hash_prefix_map_old, response); + if (result == APPLY_UPDATE_SUCCESS) { + // TODO(vakh): Create a ListUpdateResponse containing RICE encoded + // hash prefixes and response_type as FULL_UPDATE, and write that to disk. } - return apply_update_result; + return result; } -ApplyUpdateResult V4Store::ProcessPartialUpdate( - std::unique_ptr<ListUpdateResponse> response, - const std::unique_ptr<V4Store>& new_store) { - // TODO(vakh): - // 1. Done: Merge the old store and the new update in new_store. - // 2. Create a ListUpdateResponse containing RICE encoded hash-prefixes and - // response_type as FULL_UPDATE, and write that to disk. - // 3. Remove this if condition after completing 1. and 2. +ApplyUpdateResult V4Store::ProcessFullUpdateAndWriteToDisk( + std::unique_ptr<ListUpdateResponse> response) { + ApplyUpdateResult result = ProcessFullUpdate(response); + if (result == APPLY_UPDATE_SUCCESS) { + RecordStoreWriteResult(WriteToDisk(std::move(response))); + } + return result; +} +ApplyUpdateResult V4Store::ProcessFullUpdate( + const std::unique_ptr<ListUpdateResponse>& response) { + DCHECK(response->has_response_type()); + DCHECK_EQ(ListUpdateResponse::FULL_UPDATE, response->response_type()); + // TODO(vakh): For a full update, we don't need to process the update in + // lexographical order to store it, but we do need to do that for calculating + // checksum. It might save some CPU cycles to store the full update as-is and + // walk the list of hash prefixes in lexographical order only for checksum + // calculation. + return ProcessUpdate(HashPrefixMap(), response); +} + +ApplyUpdateResult V4Store::ProcessUpdate( + const HashPrefixMap& hash_prefix_map_old, + const std::unique_ptr<ListUpdateResponse>& response) { const RepeatedField<int32>* raw_removals = nullptr; RepeatedField<int32> rice_removals; size_t removals_size = response->removals_size(); @@ -167,12 +186,23 @@ HashPrefixMap hash_prefix_map; ApplyUpdateResult apply_update_result = UpdateHashPrefixMapFromAdditions(response->additions(), &hash_prefix_map); - - if (apply_update_result == APPLY_UPDATE_SUCCESS) { - apply_update_result = - new_store->MergeUpdate(hash_prefix_map_, hash_prefix_map, raw_removals); + if (apply_update_result != APPLY_UPDATE_SUCCESS) { + return apply_update_result; } - return apply_update_result; + + std::string expected_checksum; + if (response->has_checksum() && response->checksum().has_sha256()) { + expected_checksum = response->checksum().sha256(); + } + + apply_update_result = MergeUpdate(hash_prefix_map_old, hash_prefix_map, + raw_removals, expected_checksum); + if (apply_update_result != APPLY_UPDATE_SUCCESS) { + return apply_update_result; + } + + state_ = response->new_client_state(); + return APPLY_UPDATE_SUCCESS; } void V4Store::ApplyUpdate( @@ -181,13 +211,14 @@ UpdatedStoreReadyCallback callback) { std::unique_ptr<V4Store> new_store( new V4Store(this->task_runner_, this->store_path_)); - new_store->state_ = response->new_client_state(); ApplyUpdateResult apply_update_result; if (response->response_type() == ListUpdateResponse::PARTIAL_UPDATE) { - apply_update_result = ProcessPartialUpdate(std::move(response), new_store); + apply_update_result = new_store->ProcessPartialUpdateAndWriteToDisk( + hash_prefix_map_, std::move(response)); } else if (response->response_type() == ListUpdateResponse::FULL_UPDATE) { - apply_update_result = ProcessFullUpdate(std::move(response), new_store); + apply_update_result = + new_store->ProcessFullUpdateAndWriteToDisk(std::move(response)); } else { apply_update_result = UNEXPECTED_RESPONSE_TYPE_FAILURE; NOTREACHED() << "Unexpected response type: " << response->response_type(); @@ -198,6 +229,8 @@ callback_task_runner->PostTask( FROM_HERE, base::Bind(callback, base::Passed(&new_store))); } else { + DVLOG(1) << "ApplyUpdate failed: reason: " << apply_update_result + << "; store: " << *this; // new_store failed updating. Pass a nullptr to the callback. callback_task_runner->PostTask(FROM_HERE, base::Bind(callback, nullptr)); } @@ -321,10 +354,10 @@ } } -ApplyUpdateResult V4Store::MergeUpdate( - const HashPrefixMap& old_prefixes_map, - const HashPrefixMap& additions_map, - const RepeatedField<int32>* raw_removals) { +ApplyUpdateResult V4Store::MergeUpdate(const HashPrefixMap& old_prefixes_map, + const HashPrefixMap& additions_map, + const RepeatedField<int32>* raw_removals, + const std::string& expected_checksum) { DCHECK(hash_prefix_map_.empty()); hash_prefix_map_.clear(); ReserveSpaceInPrefixMap(old_prefixes_map, &hash_prefix_map_); @@ -347,6 +380,10 @@ // At least one of the maps still has elements that need to be merged into the // new store. + bool calculate_checksum = !expected_checksum.empty(); + std::unique_ptr<crypto::SecureHash> checksum_ctx( + crypto::SecureHash::Create(crypto::SecureHash::SHA256)); + // Keep track of the number of elements picked from the old map. This is used // to determine which elements to drop based on the raw_removals. Note that // picked is not the same as merged. A picked element isn't merged if its @@ -380,6 +417,11 @@ *removals_iter != total_picked_from_old) { // Append the smallest hash to the appropriate list. hash_prefix_map_[next_smallest_prefix_size] += next_smallest_prefix_old; + + if (calculate_checksum) { + checksum_ctx->Update(base::string_as_array(&next_smallest_prefix_old), + next_smallest_prefix_size); + } } else { // Element not added to new map. Move the removals iterator forward. removals_iter++; @@ -397,6 +439,12 @@ hash_prefix_map_[next_smallest_prefix_size] += next_smallest_prefix_additions; + if (calculate_checksum) { + checksum_ctx->Update( + base::string_as_array(&next_smallest_prefix_additions), + next_smallest_prefix_size); + } + // Update the iterator map, which means that we have merged one hash // prefix of size |next_smallest_prefix_size| from the update. additions_iterator_map[next_smallest_prefix_size] += @@ -409,9 +457,24 @@ } } - return (!raw_removals || removals_iter == raw_removals->end()) - ? APPLY_UPDATE_SUCCESS - : REMOVALS_INDEX_TOO_LARGE_FAILURE; + if (raw_removals && removals_iter != raw_removals->end()) { + return REMOVALS_INDEX_TOO_LARGE_FAILURE; + } + + if (calculate_checksum) { + std::string checksum(crypto::kSHA256Length, 0); + checksum_ctx->Finish(base::string_as_array(&checksum), checksum.size()); + if (checksum != expected_checksum) { + std::string checksum_base64, expected_checksum_base64; + base::Base64Encode(checksum, &checksum_base64); + base::Base64Encode(expected_checksum, &expected_checksum_base64); + DVLOG(1) << "Checksum failed: calculated: " << checksum_base64 + << "expected: " << expected_checksum_base64; + return CHECKSUM_MISMATCH_FAILURE; + } + } + + return APPLY_UPDATE_SUCCESS; } StoreReadResult V4Store::ReadFromDisk() { @@ -450,16 +513,15 @@ return HASH_PREFIX_INFO_MISSING_FAILURE; } - const ListUpdateResponse& response = file_format.list_update_response(); - ApplyUpdateResult apply_update_result = UpdateHashPrefixMapFromAdditions( - response.additions(), &hash_prefix_map_); + std::unique_ptr<ListUpdateResponse> response(new ListUpdateResponse); + response->Swap(file_format.mutable_list_update_response()); + ApplyUpdateResult apply_update_result = ProcessFullUpdate(response); RecordApplyUpdateResultWhenReadingFromDisk(apply_update_result); if (apply_update_result != APPLY_UPDATE_SUCCESS) { hash_prefix_map_.clear(); return HASH_PREFIX_MAP_GENERATION_FAILURE; } - state_ = response.new_client_state(); return READ_SUCCESS; }
diff --git a/components/safe_browsing_db/v4_store.h b/components/safe_browsing_db/v4_store.h index 770088b..48fb3e09 100644 --- a/components/safe_browsing_db/v4_store.h +++ b/components/safe_browsing_db/v4_store.h
@@ -138,6 +138,10 @@ // Compression type other than RAW and RICE for removals. UNEXPECTED_COMPRESSION_TYPE_REMOVALS_FAILURE = 10, + // The state of the store did not match the expected checksum sent by the + // server. + CHECKSUM_MISMATCH_FAILURE = 11, + // Memory space for histograms is determined by the max. ALWAYS // ADD NEW VALUES BEFORE THIS ONE. APPLY_UPDATE_RESULT_MAX @@ -245,6 +249,7 @@ TestAdditionsWithRiceEncodingFailsWithInvalidInput); FRIEND_TEST_ALL_PREFIXES(V4StoreTest, TestAdditionsWithRiceEncodingSucceeds); FRIEND_TEST_ALL_PREFIXES(V4StoreTest, TestRemovalsWithRiceEncodingSucceeds); + FRIEND_TEST_ALL_PREFIXES(V4StoreTest, TestMergeUpdatesFailsChecksum); friend class V4StoreTest; // If |prefix_size| is within expected range, and |raw_hashes| is not invalid, @@ -290,24 +295,43 @@ // Merges the prefix map from the old store (|old_hash_prefix_map|) and the // update (additions_map) to populate the prefix map for the current store. // The indices in the |raw_removals| list, which may be NULL, are not merged. + // The SHA256 checksum of the final list of hash prefixes, in lexographically + // sorted order, must match |expected_checksum| (if it's not empty). ApplyUpdateResult MergeUpdate(const HashPrefixMap& old_hash_prefix_map, const HashPrefixMap& additions_map, const ::google::protobuf::RepeatedField< - ::google::protobuf::int32>* raw_removals); + ::google::protobuf::int32>* raw_removals, + const std::string& expected_checksum); - // Processes the FULL_UPDATE |response| from the server and updates the - // V4Store in |new_store| and writes it to disk. If processing the |response| - // succeeds, it returns APPLY_UPDATE_SUCCESS. - ApplyUpdateResult ProcessFullUpdate( - std::unique_ptr<ListUpdateResponse> response, - const std::unique_ptr<V4Store>& new_store); - - // Processes the PARTIAL_UPDATE |response| from the server and updates the - // V4Store in |new_store|. If processing the |response| succeeds, it returns + // Processes the FULL_UPDATE |response| from the server, and writes the + // merged V4Store to disk. If processing the |response| succeeds, it returns // APPLY_UPDATE_SUCCESS. - ApplyUpdateResult ProcessPartialUpdate( - std::unique_ptr<ListUpdateResponse> response, - const std::unique_ptr<V4Store>& new_store); + // This method is only called when we receive a FULL_UPDATE from the server. + ApplyUpdateResult ProcessFullUpdateAndWriteToDisk( + std::unique_ptr<ListUpdateResponse> response); + + // Processes a FULL_UPDATE |response| and updates the V4Store. If processing + // the |response| succeeds, it returns APPLY_UPDATE_SUCCESS. + // This method is called when we receive a FULL_UPDATE from the server, and + // when we read a store file from disk on startup. + ApplyUpdateResult ProcessFullUpdate( + const std::unique_ptr<ListUpdateResponse>& response); + + // Merges the hash prefixes in |hash_prefix_map_old| and |response|, updates + // the |hash_prefix_map_| and |state_| in the V4Store, and writes the merged + // store to disk. If processing succeeds, it returns APPLY_UPDATE_SUCCESS. + // This method is only called when we receive a PARTIAL_UPDATE from the + // server. + ApplyUpdateResult ProcessPartialUpdateAndWriteToDisk( + const HashPrefixMap& hash_prefix_map_old, + std::unique_ptr<ListUpdateResponse> response); + + // Merges the hash prefixes in |hash_prefix_map_old| and |response|, and + // updates the |hash_prefix_map_| and |state_| in the V4Store. If processing + // succeeds, it returns APPLY_UPDATE_SUCCESS. + ApplyUpdateResult ProcessUpdate( + const HashPrefixMap& hash_prefix_map_old, + const std::unique_ptr<ListUpdateResponse>& response); // Reads the state of the store from the file on disk and returns the reason // for the failure or reports success.
diff --git a/components/safe_browsing_db/v4_store_unittest.cc b/components/safe_browsing_db/v4_store_unittest.cc index f9bd1ba..2bd661e7 100644 --- a/components/safe_browsing_db/v4_store_unittest.cc +++ b/components/safe_browsing_db/v4_store_unittest.cc
@@ -12,6 +12,7 @@ #include "components/safe_browsing_db/v4_store.h" #include "components/safe_browsing_db/v4_store.pb.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "crypto/sha2.h" #include "testing/platform_test.h" namespace safe_browsing { @@ -122,6 +123,7 @@ TEST_F(V4StoreTest, TestReadFromNoHashPrefixesFile) { ListUpdateResponse list_update_response; list_update_response.set_platform_type(LINUX_PLATFORM); + list_update_response.set_response_type(ListUpdateResponse::FULL_UPDATE); WriteFileFormatProtoToFile(0x600D71FE, 9, &list_update_response); EXPECT_EQ(READ_SUCCESS, V4Store(task_runner_, store_path_).ReadFromDisk()); } @@ -229,8 +231,21 @@ V4Store::AddUnlumpedHashes(5, "22222bcdef", &prefix_map_additions)); V4Store store(task_runner_, store_path_); + // Proof of checksum validity using python: + // >>> import hashlib + // >>> m = hashlib.sha256() + // >>> m.update("----11112222254321abcdabcdebbbbbcdefefgh") + // >>> m.digest() + // "\xbc\xb3\xedk\xe3x\xd1(\xa9\xedz7]" + // "x\x18\xbdn]\xa5\xa8R\xf7\xab\xcf\xc1\xa3\xa3\xc5Z,\xa6o" + std::string expected_checksum = std::string( + "\xBC\xB3\xEDk\xE3x\xD1(\xA9\xEDz7]x\x18\xBDn]" + "\xA5\xA8R\xF7\xAB\xCF\xC1\xA3\xA3\xC5Z,\xA6o", + crypto::kSHA256Length); EXPECT_EQ(APPLY_UPDATE_SUCCESS, - store.MergeUpdate(prefix_map_old, prefix_map_additions, nullptr)); + store.MergeUpdate(prefix_map_old, prefix_map_additions, nullptr, + expected_checksum)); + const HashPrefixMap& prefix_map = store.hash_prefix_map_; EXPECT_EQ(2u, prefix_map.size()); @@ -261,8 +276,15 @@ V4Store::AddUnlumpedHashes(5, "22222bcdef", &prefix_map_additions)); V4Store store(task_runner_, store_path_); + std::string expected_checksum = std::string( + "\xA5\x8B\xCAsD\xC7\xF9\xCE\xD2\xF4\x4=" + "\xB2\"\x82\x1A\xC1\xB8\x1F\x10\r\v\x9A\x93\xFD\xE1\xB8" + "B\x1Eh\xF7\xB4", + crypto::kSHA256Length); EXPECT_EQ(APPLY_UPDATE_SUCCESS, - store.MergeUpdate(prefix_map_old, prefix_map_additions, nullptr)); + store.MergeUpdate(prefix_map_old, prefix_map_additions, nullptr, + expected_checksum)); + const HashPrefixMap& prefix_map = store.hash_prefix_map_; EXPECT_EQ(2u, prefix_map.size()); @@ -286,8 +308,15 @@ V4Store::AddUnlumpedHashes(4, "2222", &prefix_map_additions)); V4Store store(task_runner_, store_path_); + std::string expected_checksum = std::string( + "\x84\x92\xET\xED\xF7\x97" + "C\xCE}\xFF" + "E\x1\xAB-\b>\xDB\x95\b\xD8H\xD5\x1D\xF9]8x\xA4\xD4\xC2\xFA", + crypto::kSHA256Length); EXPECT_EQ(APPLY_UPDATE_SUCCESS, - store.MergeUpdate(prefix_map_old, prefix_map_additions, nullptr)); + store.MergeUpdate(prefix_map_old, prefix_map_additions, nullptr, + expected_checksum)); + const HashPrefixMap& prefix_map = store.hash_prefix_map_; EXPECT_EQ(1u, prefix_map.size()); @@ -308,8 +337,15 @@ V4Store::AddUnlumpedHashes(4, "00001111", &prefix_map_additions)); V4Store store(task_runner_, store_path_); + std::string expected_checksum = std::string( + "\x84\x92\xET\xED\xF7\x97" + "C\xCE}\xFF" + "E\x1\xAB-\b>\xDB\x95\b\xD8H\xD5\x1D\xF9]8x\xA4\xD4\xC2\xFA", + crypto::kSHA256Length); EXPECT_EQ(APPLY_UPDATE_SUCCESS, - store.MergeUpdate(prefix_map_old, prefix_map_additions, nullptr)); + store.MergeUpdate(prefix_map_old, prefix_map_additions, nullptr, + expected_checksum)); + const HashPrefixMap& prefix_map = store.hash_prefix_map_; EXPECT_EQ(1u, prefix_map.size()); @@ -330,8 +366,10 @@ V4Store::AddUnlumpedHashes(4, "2222", &prefix_map_additions)); V4Store store(task_runner_, store_path_); + std::string expected_checksum; EXPECT_EQ(ADDITIONS_HAS_EXISTING_PREFIX_FAILURE, - store.MergeUpdate(prefix_map_old, prefix_map_additions, nullptr)); + store.MergeUpdate(prefix_map_old, prefix_map_additions, nullptr, + expected_checksum)); } TEST_F(V4StoreTest, TestMergeUpdatesFailsWhenRemovalsIndexTooLarge) { @@ -348,9 +386,10 @@ RepeatedField<int32> raw_removals; // old_store: ["2222"] raw_removals.Add(1); - EXPECT_EQ( - REMOVALS_INDEX_TOO_LARGE_FAILURE, - store.MergeUpdate(prefix_map_old, prefix_map_additions, &raw_removals)); + std::string expected_checksum; + EXPECT_EQ(REMOVALS_INDEX_TOO_LARGE_FAILURE, + store.MergeUpdate(prefix_map_old, prefix_map_additions, + &raw_removals, expected_checksum)); } TEST_F(V4StoreTest, TestMergeUpdatesRemovesOnlyElement) { @@ -365,9 +404,16 @@ RepeatedField<int32> raw_removals; // old_store: ["2222"] raw_removals.Add(0); // Removes "2222" - EXPECT_EQ( - APPLY_UPDATE_SUCCESS, - store.MergeUpdate(prefix_map_old, prefix_map_additions, &raw_removals)); + std::string expected_checksum = std::string( + "\xE6\xB0\x1\x12\x89\x83\xF0/" + "\xE7\xD2\xE6\xDC\x16\xB9\x8C+\xA2\xB3\x9E\x89<,\x88" + "B3\xA5\xB1" + "D\x9E\x9E'\x14", + crypto::kSHA256Length); + EXPECT_EQ(APPLY_UPDATE_SUCCESS, + store.MergeUpdate(prefix_map_old, prefix_map_additions, + &raw_removals, expected_checksum)); + const HashPrefixMap& prefix_map = store.hash_prefix_map_; // The size is 2 since we reserve space anyway. EXPECT_EQ(2u, prefix_map.size()); @@ -387,9 +433,16 @@ RepeatedField<int32> raw_removals; // old_store: ["2222", "4444"] raw_removals.Add(0); // Removes "2222" - EXPECT_EQ( - APPLY_UPDATE_SUCCESS, - store.MergeUpdate(prefix_map_old, prefix_map_additions, &raw_removals)); + std::string expected_checksum = std::string( + "\x9D\xF3\xF2\x82\0\x1E{\xDF\xCD\xC0V\xBE\xD6<\x85" + "D7=\xB5v\xAD\b1\xC9\xB3" + "A\xAC" + "b\xF1lf\xA4", + crypto::kSHA256Length); + EXPECT_EQ(APPLY_UPDATE_SUCCESS, + store.MergeUpdate(prefix_map_old, prefix_map_additions, + &raw_removals, expected_checksum)); + const HashPrefixMap& prefix_map = store.hash_prefix_map_; // The size is 2 since we reserve space anyway. EXPECT_EQ(2u, prefix_map.size()); @@ -409,9 +462,15 @@ RepeatedField<int32> raw_removals; // old_store: ["2222", "3333", 4444"] raw_removals.Add(1); // Removes "3333" - EXPECT_EQ( - APPLY_UPDATE_SUCCESS, - store.MergeUpdate(prefix_map_old, prefix_map_additions, &raw_removals)); + std::string expected_checksum = std::string( + "\xFA-A\x15{\x17\0>\xAE" + "8\xACigR\xD1\x93<\xB2\xC9\xB5\x81\xC0\xFB\xBB\x2\f\xAFpN\xEA" + "44", + crypto::kSHA256Length); + EXPECT_EQ(APPLY_UPDATE_SUCCESS, + store.MergeUpdate(prefix_map_old, prefix_map_additions, + &raw_removals, expected_checksum)); + const HashPrefixMap& prefix_map = store.hash_prefix_map_; // The size is 2 since we reserve space anyway. EXPECT_EQ(2u, prefix_map.size()); @@ -431,9 +490,14 @@ RepeatedField<int32> raw_removals; // old_store: ["2222", "3333", 4444"] raw_removals.Add(2); // Removes "4444" - EXPECT_EQ( - APPLY_UPDATE_SUCCESS, - store.MergeUpdate(prefix_map_old, prefix_map_additions, &raw_removals)); + std::string expected_checksum = std::string( + "a\xE1\xAD\x96\xFE\xA6" + "A\xCA~7W\xF6z\xD8\n\xCA?\x96\x8A\x17U\x5\v\r\x88]\n\xB2JX\xC4S", + crypto::kSHA256Length); + EXPECT_EQ(APPLY_UPDATE_SUCCESS, + store.MergeUpdate(prefix_map_old, prefix_map_additions, + &raw_removals, expected_checksum)); + const HashPrefixMap& prefix_map = store.hash_prefix_map_; // The size is 2 since we reserve space anyway. EXPECT_EQ(2u, prefix_map.size()); @@ -455,9 +519,15 @@ RepeatedField<int32> raw_removals; // old_store: ["2222", "3333", 4444", "aaaaa", "bbbbb"] raw_removals.Add(3); // Removes "aaaaa" - EXPECT_EQ( - APPLY_UPDATE_SUCCESS, - store.MergeUpdate(prefix_map_old, prefix_map_additions, &raw_removals)); + std::string expected_checksum = std::string( + "\xA7OG\x9D\x83.\x9D-f\x8A\xE\x8B\r&\x19" + "6\xE3\xF0\xEFTi\xA7\x5\xEA\xF7" + "ej,\xA8\x9D\xAD\x91", + crypto::kSHA256Length); + EXPECT_EQ(APPLY_UPDATE_SUCCESS, + store.MergeUpdate(prefix_map_old, prefix_map_additions, + &raw_removals, expected_checksum)); + const HashPrefixMap& prefix_map = store.hash_prefix_map_; // The size is 2 since we reserve space anyway. EXPECT_EQ(2u, prefix_map.size()); @@ -480,9 +550,16 @@ // old_store: ["2222", "3333", "33333", "44444", "aaaa", "bbbbb"] raw_removals.Add(1); // Removes "3333" raw_removals.Add(3); // Removes "44444" - EXPECT_EQ( - APPLY_UPDATE_SUCCESS, - store.MergeUpdate(prefix_map_old, prefix_map_additions, &raw_removals)); + std::string expected_checksum = std::string( + "!D\xB7&L\xA7&G0\x85\xB4" + "E\xDD\x10\"\x9A\xCA\xF1" + "3^\x83w\xBBL\x19n\xAD\xBDM\x9D" + "b\x9F", + crypto::kSHA256Length); + EXPECT_EQ(APPLY_UPDATE_SUCCESS, + store.MergeUpdate(prefix_map_old, prefix_map_additions, + &raw_removals, expected_checksum)); + const HashPrefixMap& prefix_map = store.hash_prefix_map_; // The size is 2 since we reserve space anyway. EXPECT_EQ(2u, prefix_map.size()); @@ -667,8 +744,14 @@ V4Store::AddUnlumpedHashes(5, "22222bcdef", &prefix_map_additions)); V4Store store(task_runner_, store_path_); + std::string expected_checksum = std::string( + "\xA5\x8B\xCAsD\xC7\xF9\xCE\xD2\xF4\x4=" + "\xB2\"\x82\x1A\xC1\xB8\x1F\x10\r\v\x9A\x93\xFD\xE1\xB8" + "B\x1Eh\xF7\xB4", + crypto::kSHA256Length); EXPECT_EQ(APPLY_UPDATE_SUCCESS, - store.MergeUpdate(prefix_map_old, prefix_map_additions, nullptr)); + store.MergeUpdate(prefix_map_old, prefix_map_additions, nullptr, + expected_checksum)); // At this point, the store map looks like this: // 4: 1111abcdefgh @@ -698,4 +781,21 @@ EXPECT_TRUE(called_back); } +TEST_F(V4StoreTest, TestMergeUpdatesFailsChecksum) { + // Proof of checksum mismatch using python: + // >>> import hashlib + // >>> m = hashlib.sha256() + // >>> m.update("2222") + // >>> m.digest() + // "\xed\xee)\xf8\x82T;\x95f + // \xb2m\x0e\xe0\xe7\xe9P9\x9b\x1cB"\xf5\xde\x05\xe0d%\xb4\xc9\x95\xe9" + + HashPrefixMap prefix_map_old; + EXPECT_EQ(APPLY_UPDATE_SUCCESS, + V4Store::AddUnlumpedHashes(4, "2222", &prefix_map_old)); + EXPECT_EQ(CHECKSUM_MISMATCH_FAILURE, + V4Store(task_runner_, store_path_) + .MergeUpdate(prefix_map_old, HashPrefixMap(), nullptr, "aawc")); +} + } // namespace safe_browsing
diff --git a/components/search/search.cc b/components/search/search.cc index db31c28..97cdacb9 100644 --- a/components/search/search.cc +++ b/components/search/search.cc
@@ -55,10 +55,6 @@ // be ignored and Instant Extended will not be enabled by default. const char kDisablingSuffix[] = "DISABLED"; -#if !defined(OS_IOS) && !defined(OS_ANDROID) -const char kEnableQueryExtractionFlagName[] = "query_extraction"; -#endif - #if defined(OS_ANDROID) const char kPrefetchSearchResultsFlagName[] = "prefetch_results"; @@ -163,7 +159,8 @@ } std::string InstantExtendedEnabledParam(bool for_search) { - if (for_search && !IsQueryExtractionEnabled()) + // TODO(treib): Remove |for_search| and update callers that set it to true. + if (for_search) return std::string(); return std::string(google_util::kInstantExtendedAPIParam) + "=" + base::Uint64ToString(EmbeddedSearchPageVersion()) + "&"; @@ -174,25 +171,6 @@ : std::string(); } -bool IsQueryExtractionEnabled() { -#if defined(OS_IOS) || defined(OS_ANDROID) - return false; -#else - if (!IsInstantExtendedAPIEnabled()) - return false; - - const base::CommandLine* command_line = - base::CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch(switches::kEnableQueryExtraction)) - return true; - - FieldTrialFlags flags; - return GetFieldTrialInfo(&flags) && - GetBoolValueForFlagWithDefault(kEnableQueryExtractionFlagName, false, - flags); -#endif // defined(OS_IOS) || defined(OS_ANDROID) -} - bool ShouldPrefetchSearchResults() { if (!IsInstantExtendedAPIEnabled()) return false; @@ -235,11 +213,4 @@ google_util::StartsWithCommandLineGoogleBaseURL(url)); } -void EnableQueryExtractionForTesting() { -#if !defined(OS_IOS) && !defined(OS_ANDROID) - base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); - cl->AppendSwitch(switches::kEnableQueryExtraction); -#endif -} - } // namespace search
diff --git a/components/search/search.h b/components/search/search.h index ee7fe8f..a8b21a4 100644 --- a/components/search/search.h +++ b/components/search/search.h
@@ -77,9 +77,6 @@ // the returned string to be non-empty. std::string ForceInstantResultsParam(bool for_prerender); -// Returns whether query extraction is enabled. -bool IsQueryExtractionEnabled(); - // Returns true if 'prefetch_results' flag is set to true in field trials to // prefetch high-confidence search suggestions. bool ShouldPrefetchSearchResults(); @@ -93,13 +90,6 @@ // --google-base-url to point at non-HTTPS servers, which eases testing.) bool IsSuitableURLForInstant(const GURL& url, const TemplateURL* template_url); -// ----------------------------------------------------- -// The following APIs are exposed for use in tests only. -// ----------------------------------------------------- - -// Forces query in the omnibox to be on for tests. -void EnableQueryExtractionForTesting(); - } // namespace search #endif // COMPONENTS_SEARCH_SEARCH_H_
diff --git a/components/search/search_android_unittest.cc b/components/search/search_android_unittest.cc index 063ec1a..387975f3 100644 --- a/components/search/search_android_unittest.cc +++ b/components/search/search_android_unittest.cc
@@ -5,11 +5,8 @@ #include "components/search/search.h" #include "base/command_line.h" -#include "base/metrics/field_trial.h" -#include "base/metrics/statistics_recorder.h" #include "components/search/search.h" #include "components/search/search_switches.h" -#include "components/variations/entropy_provider.h" #include "testing/gtest/include/gtest/gtest.h" namespace search { @@ -25,11 +22,6 @@ EXPECT_TRUE(IsInstantExtendedAPIEnabled()); } -TEST(SearchTest, QueryExtractionEnabled) { - // Query extraction is disabled on mobile. - EXPECT_FALSE(IsQueryExtractionEnabled()); -} - } // namespace } // namespace chrome
diff --git a/components/search/search_switches.cc b/components/search/search_switches.cc index 6d4b47d..b8026033 100644 --- a/components/search/search_switches.cc +++ b/components/search/search_switches.cc
@@ -18,11 +18,4 @@ #endif -#if !defined(OS_ANDROID) && !defined(OS_IOS) - -// Enables query in the omnibox. -const char kEnableQueryExtraction[] = "enable-query-extraction"; - -#endif - } // namespace switches
diff --git a/components/search/search_switches.h b/components/search/search_switches.h index 46208e07..ada2e17 100644 --- a/components/search/search_switches.h +++ b/components/search/search_switches.h
@@ -14,10 +14,6 @@ extern const char kPrefetchSearchResults[]; #endif -#if !defined(OS_ANDROID) && !defined(OS_IOS) -extern const char kEnableQueryExtraction[]; -#endif - } // namespace switches #endif // COMPONENTS_SEARCH_SEARCH_SWITCHES_H_
diff --git a/components/search/search_unittest.cc b/components/search/search_unittest.cc index f11151c..984ccf5 100644 --- a/components/search/search_unittest.cc +++ b/components/search/search_unittest.cc
@@ -166,63 +166,17 @@ "Group1 espv:12")); // Make sure InstantExtendedEnabledParam() returns an empty string for search // requests. - EXPECT_FALSE(IsQueryExtractionEnabled()); EXPECT_EQ("", InstantExtendedEnabledParam(true)); EXPECT_EQ("espv=12&", InstantExtendedEnabledParam(false)); } -TEST_F(InstantExtendedEnabledParamTest, QueryExtractionEnabled) { - ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( - "EmbeddedSearch", "Group1 espv:10 query_extraction:1")); - EXPECT_TRUE(IsQueryExtractionEnabled()); - // Make sure InstantExtendedEnabledParam() returns a non-empty param string - // for search requests. - EXPECT_EQ("espv=10&", InstantExtendedEnabledParam(true)); - EXPECT_EQ("espv=10&", InstantExtendedEnabledParam(false)); -} - TEST_F(InstantExtendedEnabledParamTest, UseDefaultEmbeddedSearchPageVersion) { ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( - "EmbeddedSearch", "Group1 espv:-1 query_extraction:1")); - EXPECT_TRUE(IsQueryExtractionEnabled()); - EXPECT_EQ("espv=2&", InstantExtendedEnabledParam(true)); + "EmbeddedSearch", "Group1 espv:-1")); + EXPECT_EQ("", InstantExtendedEnabledParam(true)); EXPECT_EQ("espv=2&", InstantExtendedEnabledParam(false)); } -typedef EmbeddedSearchFieldTrialTest IsQueryExtractionEnabledTest; - -TEST_F(IsQueryExtractionEnabledTest, NotSet) { - ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial("EmbeddedSearch", - "Group1 espv:2")); - EXPECT_TRUE(IsInstantExtendedAPIEnabled()); - EXPECT_FALSE(IsQueryExtractionEnabled()); - EXPECT_EQ(2ul, EmbeddedSearchPageVersion()); -} - -TEST_F(IsQueryExtractionEnabledTest, EnabledViaFieldTrial) { - ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( - "EmbeddedSearch", "Group1 espv:2 query_extraction:1")); - EXPECT_TRUE(IsInstantExtendedAPIEnabled()); - EXPECT_TRUE(IsQueryExtractionEnabled()); - EXPECT_EQ(2ul, EmbeddedSearchPageVersion()); -} - -TEST_F(IsQueryExtractionEnabledTest, DisabledViaFieldTrial) { - ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( - "EmbeddedSearch", "Group1 espv:2 query_extraction:0")); - EXPECT_TRUE(IsInstantExtendedAPIEnabled()); - EXPECT_FALSE(IsQueryExtractionEnabled()); - EXPECT_EQ(2ul, EmbeddedSearchPageVersion()); -} - -TEST_F(IsQueryExtractionEnabledTest, EnabledViaCommandLine) { - EnableQueryExtractionForTesting(); - ASSERT_TRUE(base::FieldTrialList::CreateFieldTrial( - "EmbeddedSearch", "Group1 espv:2 query_extraction:0")); - EXPECT_TRUE(IsInstantExtendedAPIEnabled()); - EXPECT_TRUE(IsQueryExtractionEnabled()); - EXPECT_EQ(2ul, EmbeddedSearchPageVersion()); -} #endif // !defined(OS_IOS) && !defined(OS_ANDROID) } // namespace search
diff --git a/components/search_engines.gypi b/components/search_engines.gypi index f15ca1b..b36e827 100644 --- a/components/search_engines.gypi +++ b/components/search_engines.gypi
@@ -28,7 +28,6 @@ 'prefs/prefs.gyp:prefs', 'rappor', 'search_engines/prepopulated_engines.gyp:prepopulated_engines', - 'sync_driver', 'url_formatter/url_formatter.gyp:url_formatter', 'webdata_common', ],
diff --git a/components/search_engines/BUILD.gn b/components/search_engines/BUILD.gn index 5e39baf..ad2b330 100644 --- a/components/search_engines/BUILD.gn +++ b/components/search_engines/BUILD.gn
@@ -69,7 +69,6 @@ "//components/rappor", "//components/strings", "//components/sync", - "//components/sync_driver", "//components/url_formatter", "//components/webdata/common", "//google_apis", @@ -131,7 +130,7 @@ "//components/pref_registry:test_support", "//components/prefs", "//components/sync:test_support_sync_api", - "//components/sync_driver:test_support", + "//components/sync:test_support_sync_driver", "//components/syncable_prefs:test_support", "//components/webdata/common", "//sql",
diff --git a/components/search_engines/DEPS b/components/search_engines/DEPS index 3809f38a..d006246 100644 --- a/components/search_engines/DEPS +++ b/components/search_engines/DEPS
@@ -11,7 +11,6 @@ "+components/prefs", "+components/rappor", "+components/sync", - "+components/sync_driver", "+components/syncable_prefs/testing_pref_service_syncable.h", "+components/url_formatter", "+components/webdata",
diff --git a/components/search_engines/default_search_policy_handler.cc b/components/search_engines/default_search_policy_handler.cc index 341f7f00..ddb7e76 100644 --- a/components/search_engines/default_search_policy_handler.cc +++ b/components/search_engines/default_search_policy_handler.cc
@@ -197,7 +197,7 @@ } DefaultSearchPolicyHandler::~DefaultSearchPolicyHandler() { - STLDeleteElements(&handlers_); + base::STLDeleteElements(&handlers_); } bool DefaultSearchPolicyHandler::CheckPolicySettings(const PolicyMap& policies,
diff --git a/components/search_engines/prepopulated_engines.json b/components/search_engines/prepopulated_engines.json index 721bfd6..083a6e9 100644 --- a/components/search_engines/prepopulated_engines.json +++ b/components/search_engines/prepopulated_engines.json
@@ -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": 91 + "kCurrentDataVersion": 92 }, // The following engines are included in country lists and are added to the @@ -163,9 +163,9 @@ "naver": { "name": "\ub124\uc774\ubc84", "keyword": "naver.com", - "favicon_url": "http://sstatic.naver.net/search/favicon/favicon_140327.ico", - "search_url": "http://search.naver.com/search.naver?ie={inputEncoding}&query={searchTerms}", - "suggest_url": "http://ac.search.naver.com/nx/ac?of=os&ie={inputEncoding}&q={searchTerms}&oe={outputEncoding}", + "favicon_url": "https://ssl.pstatic.net/sstatic/search/favicon/favicon_140327.ico", + "search_url": "https://search.naver.com/search.naver?ie={inputEncoding}&query={searchTerms}", + "suggest_url": "https://ac.search.naver.com/nx/ac?of=os&ie={inputEncoding}&q={searchTerms}&oe={outputEncoding}", "type": "SEARCH_ENGINE_NAVER", "id": 67 },
diff --git a/components/search_engines/search_engine_data_type_controller.h b/components/search_engines/search_engine_data_type_controller.h index cc4cb61..62de83c 100644 --- a/components/search_engines/search_engine_data_type_controller.h +++ b/components/search_engines/search_engine_data_type_controller.h
@@ -10,7 +10,7 @@ #include "base/macros.h" #include "components/search_engines/template_url_service.h" -#include "components/sync_driver/ui_data_type_controller.h" +#include "components/sync/driver/ui_data_type_controller.h" class Profile;
diff --git a/components/search_engines/search_engine_data_type_controller_unittest.cc b/components/search_engines/search_engine_data_type_controller_unittest.cc index fb753f0..7e0d1710 100644 --- a/components/search_engines/search_engine_data_type_controller_unittest.cc +++ b/components/search_engines/search_engine_data_type_controller_unittest.cc
@@ -16,10 +16,10 @@ #include "base/tracked_objects.h" #include "components/search_engines/template_url_service.h" #include "components/sync/api/fake_syncable_service.h" -#include "components/sync_driver/data_type_controller_mock.h" -#include "components/sync_driver/fake_generic_change_processor.h" -#include "components/sync_driver/fake_sync_client.h" -#include "components/sync_driver/sync_api_component_factory_mock.h" +#include "components/sync/driver/data_type_controller_mock.h" +#include "components/sync/driver/fake_generic_change_processor.h" +#include "components/sync/driver/fake_sync_client.h" +#include "components/sync/driver/sync_api_component_factory_mock.h" #include "testing/gtest/include/gtest/gtest.h" using testing::_;
diff --git a/components/search_engines/template_url_service.cc b/components/search_engines/template_url_service.cc index d0452a3..e89bfb30 100644 --- a/components/search_engines/template_url_service.cc +++ b/components/search_engines/template_url_service.cc
@@ -277,7 +277,7 @@ TemplateURLService::~TemplateURLService() { // |web_data_service_| should be deleted during Shutdown(). DCHECK(!web_data_service_.get()); - STLDeleteElements(&template_urls_); + base::STLDeleteElements(&template_urls_); } // static
diff --git a/components/search_engines/template_url_service_util_unittest.cc b/components/search_engines/template_url_service_util_unittest.cc index d9a79cad..1ab6321 100644 --- a/components/search_engines/template_url_service_util_unittest.cc +++ b/components/search_engines/template_url_service_util_unittest.cc
@@ -43,8 +43,8 @@ TEST(TemplateURLServiceUtilTest, RemoveDuplicatePrepopulateIDs) { ScopedVector<TemplateURLData> prepopulated_turls; TemplateURLService::TemplateURLVector local_turls; - STLElementDeleter<TemplateURLService::TemplateURLVector> local_turls_deleter( - &local_turls); + base::STLElementDeleter<TemplateURLService::TemplateURLVector> + local_turls_deleter(&local_turls); prepopulated_turls.push_back( CreatePrepopulateTemplateURLData(1, "winner4", 1).release());
diff --git a/components/security_state/security_state_model.cc b/components/security_state/security_state_model.cc index 9b8288f..bf16b01 100644 --- a/components/security_state/security_state_model.cc +++ b/components/security_state/security_state_model.cc
@@ -72,19 +72,14 @@ return SecurityStateModel::NO_DEPRECATED_SHA1; } -SecurityStateModel::MixedContentStatus GetMixedContentStatus( - const SecurityStateModel::VisibleSecurityState& visible_security_state) { - bool ran_insecure_content = visible_security_state.ran_mixed_content; - bool displayed_insecure_content = - visible_security_state.displayed_mixed_content; - if (ran_insecure_content && displayed_insecure_content) - return SecurityStateModel::RAN_AND_DISPLAYED_MIXED_CONTENT; - if (ran_insecure_content) - return SecurityStateModel::RAN_MIXED_CONTENT; - if (displayed_insecure_content) - return SecurityStateModel::DISPLAYED_MIXED_CONTENT; - - return SecurityStateModel::NO_MIXED_CONTENT; +SecurityStateModel::ContentStatus GetContentStatus(bool displayed, bool ran) { + if (ran && displayed) + return SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN; + if (ran) + return SecurityStateModel::CONTENT_STATUS_RAN; + if (displayed) + return SecurityStateModel::CONTENT_STATUS_DISPLAYED; + return SecurityStateModel::CONTENT_STATUS_NONE; } SecurityStateModel::SecurityLevel GetSecurityLevelForRequest( @@ -92,7 +87,8 @@ SecurityStateModelClient* client, const scoped_refptr<net::X509Certificate>& cert, SecurityStateModel::SHA1DeprecationStatus sha1_status, - SecurityStateModel::MixedContentStatus mixed_content_status) { + SecurityStateModel::ContentStatus mixed_content_status, + SecurityStateModel::ContentStatus content_with_cert_errors_status) { DCHECK(visible_security_state.connection_info_initialized || visible_security_state.fails_malware_check); @@ -126,9 +122,13 @@ !net::IsCertStatusMinorError(cert_status)) { return SecurityStateModel::SECURITY_ERROR; } - if (mixed_content_status == SecurityStateModel::RAN_MIXED_CONTENT || + if (mixed_content_status == SecurityStateModel::CONTENT_STATUS_RAN || mixed_content_status == - SecurityStateModel::RAN_AND_DISPLAYED_MIXED_CONTENT) { + SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN || + content_with_cert_errors_status == + SecurityStateModel::CONTENT_STATUS_RAN || + content_with_cert_errors_status == + SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN) { return SecurityStateModel::kRanInsecureContentLevel; } @@ -146,11 +146,16 @@ return SecurityStateModel::NONE; // Active mixed content is handled above. - DCHECK_NE(SecurityStateModel::RAN_MIXED_CONTENT, mixed_content_status); - DCHECK_NE(SecurityStateModel::RAN_AND_DISPLAYED_MIXED_CONTENT, + DCHECK_NE(SecurityStateModel::CONTENT_STATUS_RAN, mixed_content_status); + DCHECK_NE(SecurityStateModel::CONTENT_STATUS_DISPLAYED_AND_RAN, mixed_content_status); - if (mixed_content_status == SecurityStateModel::DISPLAYED_MIXED_CONTENT) + + if (mixed_content_status == + SecurityStateModel::CONTENT_STATUS_DISPLAYED || + content_with_cert_errors_status == + SecurityStateModel::CONTENT_STATUS_DISPLAYED) { return SecurityStateModel::kDisplayedInsecureContentLevel; + } if (net::IsCertStatusError(cert_status)) { // Major cert errors are handled above. @@ -182,10 +187,11 @@ security_info->fails_malware_check = visible_security_state.fails_malware_check; if (security_info->fails_malware_check) { - security_info->security_level = - GetSecurityLevelForRequest(visible_security_state, client, cert, - SecurityStateModel::UNKNOWN_SHA1, - SecurityStateModel::UNKNOWN_MIXED_CONTENT); + security_info->security_level = GetSecurityLevelForRequest( + visible_security_state, client, cert, + SecurityStateModel::UNKNOWN_SHA1, + SecurityStateModel::CONTENT_STATUS_UNKNOWN, + SecurityStateModel::CONTENT_STATUS_UNKNOWN); } return; } @@ -193,7 +199,11 @@ security_info->sha1_deprecation_status = GetSHA1DeprecationStatus(cert, visible_security_state); security_info->mixed_content_status = - GetMixedContentStatus(visible_security_state); + GetContentStatus(visible_security_state.displayed_mixed_content, + visible_security_state.ran_mixed_content); + security_info->content_with_cert_errors_status = GetContentStatus( + visible_security_state.displayed_content_with_cert_errors, + visible_security_state.ran_content_with_cert_errors); security_info->security_bits = visible_security_state.security_bits; security_info->connection_status = visible_security_state.connection_status; security_info->cert_status = visible_security_state.cert_status; @@ -212,10 +222,11 @@ security_info->fails_malware_check = visible_security_state.fails_malware_check; - security_info->security_level = - GetSecurityLevelForRequest(visible_security_state, client, cert, - security_info->sha1_deprecation_status, - security_info->mixed_content_status); + security_info->security_level = GetSecurityLevelForRequest( + visible_security_state, client, cert, + security_info->sha1_deprecation_status, + security_info->mixed_content_status, + security_info->content_with_cert_errors_status); } } // namespace @@ -231,7 +242,8 @@ : security_level(SecurityStateModel::NONE), fails_malware_check(false), sha1_deprecation_status(SecurityStateModel::NO_DEPRECATED_SHA1), - mixed_content_status(SecurityStateModel::NO_MIXED_CONTENT), + mixed_content_status(SecurityStateModel::CONTENT_STATUS_NONE), + content_with_cert_errors_status(SecurityStateModel::CONTENT_STATUS_NONE), scheme_is_cryptographic(false), cert_status(0), cert_id(0), @@ -286,6 +298,8 @@ security_bits(-1), displayed_mixed_content(false), ran_mixed_content(false), + displayed_content_with_cert_errors(false), + ran_content_with_cert_errors(false), pkp_bypassed(false) {} SecurityStateModel::VisibleSecurityState::~VisibleSecurityState() {} @@ -301,6 +315,9 @@ sct_verify_statuses == other.sct_verify_statuses && displayed_mixed_content == other.displayed_mixed_content && ran_mixed_content == other.ran_mixed_content && + displayed_content_with_cert_errors == + other.displayed_content_with_cert_errors && + ran_content_with_cert_errors == other.ran_content_with_cert_errors && pkp_bypassed == other.pkp_bypassed); }
diff --git a/components/security_state/security_state_model.h b/components/security_state/security_state_model.h index 180891df..4cbcce4 100644 --- a/components/security_state/security_state_model.h +++ b/components/security_state/security_state_model.h
@@ -72,17 +72,16 @@ DEPRECATED_SHA1_MAJOR, }; - // Describes the type of mixed content (if any) that a site - // displayed/ran. - enum MixedContentStatus { - UNKNOWN_MIXED_CONTENT, - NO_MIXED_CONTENT, - // The site displayed insecure resources (passive mixed content). - DISPLAYED_MIXED_CONTENT, - // The site ran insecure code (active mixed content). - RAN_MIXED_CONTENT, - // The site both ran and displayed insecure resources. - RAN_AND_DISPLAYED_MIXED_CONTENT, + // The ContentStatus enum is used to describe content on the page that + // has significantly different security properties than the main page + // load. Content can be passive content that is displayed (such as + // images) or active content that is run (such as scripts or iframes). + enum ContentStatus { + CONTENT_STATUS_UNKNOWN, + CONTENT_STATUS_NONE, + CONTENT_STATUS_DISPLAYED, + CONTENT_STATUS_RAN, + CONTENT_STATUS_DISPLAYED_AND_RAN, }; // Describes the security status of a page or request. This is the @@ -94,7 +93,13 @@ // True if the page fails the browser's malware or phishing checks. bool fails_malware_check; SHA1DeprecationStatus sha1_deprecation_status; - MixedContentStatus mixed_content_status; + // |mixed_content_status| describes the presence of content that was + // loaded over a nonsecure (HTTP) connection. + ContentStatus mixed_content_status; + // |content_with_cert_errors_status| describes the presence of + // content that was loaded over an HTTPS connection with + // certificate errors. + ContentStatus content_with_cert_errors_status; // The verification statuses of the signed certificate timestamps // for the connection. std::vector<net::ct::SCTVerifyStatus> sct_verify_statuses; @@ -146,6 +151,10 @@ bool displayed_mixed_content; // True if the page ran active mixed content. bool ran_mixed_content; + // True if the page displayed passive subresources with certificate errors. + bool displayed_content_with_cert_errors; + // True if the page ran active subresources with certificate errors. + bool ran_content_with_cert_errors; // True if PKP was bypassed due to a local trust anchor. bool pkp_bypassed; };
diff --git a/components/security_state/security_state_model_unittest.cc b/components/security_state/security_state_model_unittest.cc index c2580f9..597d532 100644 --- a/components/security_state/security_state_model_unittest.cc +++ b/components/security_state/security_state_model_unittest.cc
@@ -118,7 +118,7 @@ model.GetSecurityInfo(); EXPECT_EQ(SecurityStateModel::DEPRECATED_SHA1_MINOR, security_info1.sha1_deprecation_status); - EXPECT_EQ(SecurityStateModel::DISPLAYED_MIXED_CONTENT, + EXPECT_EQ(SecurityStateModel::CONTENT_STATUS_DISPLAYED, security_info1.mixed_content_status); EXPECT_EQ(SecurityStateModel::NONE, security_info1.security_level); @@ -129,7 +129,7 @@ model.GetSecurityInfo(); EXPECT_EQ(SecurityStateModel::DEPRECATED_SHA1_MINOR, security_info2.sha1_deprecation_status); - EXPECT_EQ(SecurityStateModel::RAN_MIXED_CONTENT, + EXPECT_EQ(SecurityStateModel::CONTENT_STATUS_RAN, security_info2.mixed_content_status); EXPECT_EQ(SecurityStateModel::SECURITY_ERROR, security_info2.security_level); }
diff --git a/components/sessions/core/session_service_commands.cc b/components/sessions/core/session_service_commands.cc index 29b2f28..b074ed6 100644 --- a/components/sessions/core/session_service_commands.cc +++ b/components/sessions/core/session_service_commands.cc
@@ -897,7 +897,7 @@ SortTabsBasedOnVisualOrderAndPrune(&windows, valid_windows); UpdateSelectedTabIndex(valid_windows); } - STLDeleteValues(&tabs); + base::STLDeleteValues(&tabs); // Don't delete contents of windows, that is done by the caller as all // valid windows are added to valid_windows. }
diff --git a/components/sessions/core/session_types.cc b/components/sessions/core/session_types.cc index df2ae12..0451f2d 100644 --- a/components/sessions/core/session_types.cc +++ b/components/sessions/core/session_types.cc
@@ -71,7 +71,7 @@ show_state(ui::SHOW_STATE_DEFAULT) {} SessionWindow::~SessionWindow() { - STLDeleteElements(&tabs); + base::STLDeleteElements(&tabs); } sync_pb::SessionWindow SessionWindow::ToSyncData() const {
diff --git a/components/signin/core/browser/about_signin_internals.cc b/components/signin/core/browser/about_signin_internals.cc index e1ac32c..2ed39cd 100644 --- a/components/signin/core/browser/about_signin_internals.cc +++ b/components/signin/core/browser/about_signin_internals.cc
@@ -481,7 +481,7 @@ for (TokenInfoMap::iterator it = token_info_map.begin(); it != token_info_map.end(); ++it) { - STLDeleteElements(&it->second); + base::STLDeleteElements(&it->second); } }
diff --git a/components/signin/core/browser/account_tracker_service.cc b/components/signin/core/browser/account_tracker_service.cc index b1dc370..e7fea61 100644 --- a/components/signin/core/browser/account_tracker_service.cc +++ b/components/signin/core/browser/account_tracker_service.cc
@@ -185,7 +185,7 @@ void AccountTrackerService::StartTrackingAccount( const std::string& account_id) { - if (!ContainsKey(accounts_, account_id)) { + if (!base::ContainsKey(accounts_, account_id)) { DVLOG(1) << "StartTracking " << account_id; AccountState state; state.info.account_id = account_id; @@ -196,7 +196,7 @@ void AccountTrackerService::StopTrackingAccount(const std::string& account_id) { DVLOG(1) << "StopTracking " << account_id; - if (ContainsKey(accounts_, account_id)) { + if (base::ContainsKey(accounts_, account_id)) { AccountState& state = accounts_[account_id]; RemoveFromPrefs(state); if (!state.info.gaia.empty()) @@ -209,7 +209,7 @@ void AccountTrackerService::SetAccountStateFromUserInfo( const std::string& account_id, const base::DictionaryValue* user_info) { - DCHECK(ContainsKey(accounts_, account_id)); + DCHECK(base::ContainsKey(accounts_, account_id)); AccountState& state = accounts_[account_id]; std::string gaia_id; @@ -244,7 +244,7 @@ void AccountTrackerService::SetIsChildAccount(const std::string& account_id, const bool& is_child_account) { - DCHECK(ContainsKey(accounts_, account_id)); + DCHECK(base::ContainsKey(accounts_, account_id)); AccountState& state = accounts_[account_id]; if (state.info.is_child_account == is_child_account) return; @@ -279,7 +279,7 @@ std::string account_id = it->first; if (account_id != state.info.gaia) { std::string new_account_id = state.info.gaia; - if (!ContainsKey(accounts_, new_account_id)) { + if (!base::ContainsKey(accounts_, new_account_id)) { AccountState new_state = state; new_state.info.account_id = new_account_id; migrated_accounts.insert(make_pair(new_account_id, new_state)); @@ -291,7 +291,7 @@ // Remove any obsolete account. for (auto account_id : to_remove) { - if (ContainsKey(accounts_, account_id)) { + if (base::ContainsKey(accounts_, account_id)) { AccountState& state = accounts_[account_id]; RemoveFromPrefs(state); accounts_.erase(account_id); @@ -469,7 +469,7 @@ std::string AccountTrackerService::SeedAccountInfo(const std::string& gaia, const std::string& email) { const std::string account_id = PickAccountIdForAccount(gaia, email); - const bool already_exists = ContainsKey(accounts_, account_id); + const bool already_exists = base::ContainsKey(accounts_, account_id); StartTrackingAccount(account_id); AccountState& state = accounts_[account_id]; DCHECK(!already_exists || state.info.gaia.empty() || state.info.gaia == gaia); @@ -488,7 +488,7 @@ std::string AccountTrackerService::SeedAccountInfo(AccountInfo info) { info.account_id = PickAccountIdForAccount(info.gaia, info.email); - if (!ContainsKey(accounts_, info.account_id)) { + if (!base::ContainsKey(accounts_, info.account_id)) { StartTrackingAccount(info.account_id); }
diff --git a/components/spellcheck.gypi b/components/spellcheck.gypi index d19873a..4615ec7 100644 --- a/components/spellcheck.gypi +++ b/components/spellcheck.gypi
@@ -16,17 +16,67 @@ '..', ], 'sources': [ - "spellcheck/common/spellcheck_bdict_language.h", - "spellcheck/common/spellcheck_common.cc", - "spellcheck/common/spellcheck_common.h", - "spellcheck/common/spellcheck_marker.h", - "spellcheck/common/spellcheck_message_generator.cc", - "spellcheck/common/spellcheck_message_generator.h", - "spellcheck/common/spellcheck_messages.h", - "spellcheck/common/spellcheck_result.h", + 'spellcheck/common/spellcheck_bdict_language.h', + 'spellcheck/common/spellcheck_common.cc', + 'spellcheck/common/spellcheck_common.h', + 'spellcheck/common/spellcheck_marker.h', + 'spellcheck/common/spellcheck_message_generator.cc', + 'spellcheck/common/spellcheck_message_generator.h', + 'spellcheck/common/spellcheck_messages.h', + 'spellcheck/common/spellcheck_result.h', 'spellcheck/common/spellcheck_switches.cc', 'spellcheck/common/spellcheck_switches.h', ], }, + { + # GN version: //components/spellcheck/renderer + 'target_name': 'spellcheck_renderer', + 'type': 'static_library', + 'dependencies': [ + 'spellcheck_common', + '../third_party/icu/icu.gyp:icui18n', + '../third_party/icu/icu.gyp:icuuc', + '../third_party/WebKit/public/blink.gyp:blink', + ], + 'include_dirs': [ + '..', + ], + 'sources': [ + 'spellcheck/renderer/custom_dictionary_engine.cc', + 'spellcheck/renderer/custom_dictionary_engine.h', + 'spellcheck/renderer/hunspell_engine.cc', + 'spellcheck/renderer/hunspell_engine.h', + 'spellcheck/renderer/platform_spelling_engine.cc', + 'spellcheck/renderer/platform_spelling_engine.h', + 'spellcheck/renderer/spellcheck.cc', + 'spellcheck/renderer/spellcheck.h', + 'spellcheck/renderer/spellcheck_language.cc', + 'spellcheck/renderer/spellcheck_language.h', + 'spellcheck/renderer/spellcheck_provider.cc', + 'spellcheck/renderer/spellcheck_provider.h', + 'spellcheck/renderer/spellcheck_worditerator.cc', + 'spellcheck/renderer/spellcheck_worditerator.h', + 'spellcheck/renderer/spelling_engine.h', + ], + 'conditions': [ + ['OS=="android"', { + 'sources!': [ + 'spellcheck/hunspell_engine.cc', + 'spellcheck/hunspell_engine.h', + ] + }], + ['OS!="android"', { + 'dependencies': [ + '../third_party/hunspell/hunspell.gyp:hunspell', + ], + }], + ['use_browser_spellchecker==0', { + 'sources!': [ + 'spellcheck/platform_spelling_engine.cc', + 'spellcheck/platform_spelling_engine.h', + ] + }], + ], + }, ], }
diff --git a/components/spellcheck/common/BUILD.gn b/components/spellcheck/common/BUILD.gn index 80188cd..d6a4678 100644 --- a/components/spellcheck/common/BUILD.gn +++ b/components/spellcheck/common/BUILD.gn
@@ -17,7 +17,7 @@ ] deps = [ - "//base", + "//base:i18n", "//ipc", "//third_party/icu", ]
diff --git a/components/spellcheck/renderer/BUILD.gn b/components/spellcheck/renderer/BUILD.gn new file mode 100644 index 0000000..96663628 --- /dev/null +++ b/components/spellcheck/renderer/BUILD.gn
@@ -0,0 +1,107 @@ +# Copyright 2016 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/features.gni") + +source_set("renderer") { + sources = [ + "custom_dictionary_engine.cc", + "custom_dictionary_engine.h", + "hunspell_engine.cc", + "hunspell_engine.h", + "platform_spelling_engine.cc", + "platform_spelling_engine.h", + "spellcheck.cc", + "spellcheck.h", + "spellcheck_language.cc", + "spellcheck_language.h", + "spellcheck_provider.cc", + "spellcheck_provider.h", + "spellcheck_worditerator.cc", + "spellcheck_worditerator.h", + "spelling_engine.h", + ] + + if (!use_browser_spellchecker) { + sources -= [ + "platform_spelling_engine.cc", + "platform_spelling_engine.h", + ] + } + + if (is_android) { + sources -= [ + "hunspell_engine.cc", + "hunspell_engine.h", + ] + } + + deps = [ + "//base:i18n", + "//components/spellcheck/common", + "//content/public/renderer", + "//ipc", + "//third_party/WebKit/public:blink", + "//third_party/icu", + ] + + if (!is_android) { + deps += [ "//third_party/hunspell" ] + } + + if (is_win) { + cflags = [ "/wd4267" ] # conversion from 'size_t' to 'int' on x64 (crbug.com/633312) + } +} + +source_set("unit_tests") { + testonly = true + sources = [ + "custom_dictionary_engine_unittest.cc", + "spellcheck_multilingual_unittest.cc", + "spellcheck_provider_hunspell_unittest.cc", + "spellcheck_provider_mac_unittest.cc", + "spellcheck_provider_test.cc", + "spellcheck_provider_test.h", + "spellcheck_unittest.cc", + "spellcheck_worditerator_unittest.cc", + ] + data = [ + "//third_party/hunspell_dictionaries/", + ] + + if (is_mac) { + sources -= [ + # This tests Chrome's spellchecker which Mac doesn't use. + "spellcheck_multilingual_unittest.cc", + "spellcheck_provider_hunspell_unittest.cc", + ] + } + + if (is_android) { + sources -= [ + "spellcheck_multilingual_unittest.cc", + "spellcheck_provider_hunspell_unittest.cc", + "spellcheck_unittest.cc", + ] + } + + deps = [ + ":renderer", + "//base:i18n", + "//components/spellcheck/common", + "//ipc:ipc", + "//testing/gtest", + "//third_party/WebKit/public:blink", + "//third_party/icu", + ] + + if (is_mac && !is_ios) { + deps += [ "//third_party/hunspell" ] + } + + if (is_win) { + cflags = [ "/wd4267" ] # conversion from 'size_t' to 'int' on x64 (crbug.com/633312) + } +}
diff --git a/components/spellcheck/renderer/DEPS b/components/spellcheck/renderer/DEPS new file mode 100644 index 0000000..16305c7 --- /dev/null +++ b/components/spellcheck/renderer/DEPS
@@ -0,0 +1,6 @@ +include_rules = [ + "+content/public/renderer", + "+ipc", + "+third_party/WebKit/public", + "+third_party/hunspell", +]
diff --git a/components/spellcheck/renderer/custom_dictionary_engine.cc b/components/spellcheck/renderer/custom_dictionary_engine.cc new file mode 100644 index 0000000..e00b7ec --- /dev/null +++ b/components/spellcheck/renderer/custom_dictionary_engine.cc
@@ -0,0 +1,49 @@ +// 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/spellcheck/renderer/custom_dictionary_engine.h" + +#include <stddef.h> + +#include "base/strings/utf_string_conversions.h" + +CustomDictionaryEngine::CustomDictionaryEngine() { +} + +CustomDictionaryEngine::~CustomDictionaryEngine() { +} + +void CustomDictionaryEngine::Init(const std::set<std::string>& custom_words) { + dictionary_.clear(); + + // SpellingMenuOberver calls UTF16ToUTF8(word) to convert words for storage, + // synchronization, and use in the custom dictionary engine. Since + // (UTF8ToUTF16(UTF16ToUTF8(word)) == word) holds, the engine does not need to + // normalize the strings. + for (const std::string& word : custom_words) + dictionary_.insert(base::UTF8ToUTF16(word)); +} + +void CustomDictionaryEngine::OnCustomDictionaryChanged( + const std::set<std::string>& words_added, + const std::set<std::string>& words_removed) { + for (const std::string& word : words_added) + dictionary_.insert(base::UTF8ToUTF16(word)); + + for (const std::string& word : words_removed) + dictionary_.erase(base::UTF8ToUTF16(word)); +} + +bool CustomDictionaryEngine::SpellCheckWord( + const base::string16& text, + int misspelling_start, + int misspelling_len) { + // The text to be checked is empty on OSX(async) right now. + // TODO(groby): Fix as part of async hook-up. (http://crbug.com/178241) + return + misspelling_start >= 0 && + misspelling_len > 0 && + size_t(misspelling_start + misspelling_len) <= text.length() && + dictionary_.count(text.substr(misspelling_start, misspelling_len)) > 0; +}
diff --git a/components/spellcheck/renderer/custom_dictionary_engine.h b/components/spellcheck/renderer/custom_dictionary_engine.h new file mode 100644 index 0000000..52e37e6 --- /dev/null +++ b/components/spellcheck/renderer/custom_dictionary_engine.h
@@ -0,0 +1,43 @@ +// 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 COMPONENTS_SPELLCHECK_RENDERER_CUSTOM_DICTIONARY_ENGINE_H_ +#define COMPONENTS_SPELLCHECK_RENDERER_CUSTOM_DICTIONARY_ENGINE_H_ + +#include <set> +#include <string> + +#include "base/macros.h" +#include "base/strings/string16.h" + +// Custom spellcheck dictionary. Words in this dictionary are always correctly +// spelled. Words that are not in this dictionary may or may not be correctly +// spelled. +class CustomDictionaryEngine { + public: + CustomDictionaryEngine(); + ~CustomDictionaryEngine(); + + // Initialize the custom dictionary engine. + void Init(const std::set<std::string>& words); + + // Spellcheck |text|. Assumes that another spelling engine has set + // |misspelling_start| and |misspelling_len| to indicate a misspelling. + // Returns true if there are no misspellings, otherwise returns false. + bool SpellCheckWord(const base::string16& text, + int misspelling_start, + int misspelling_len); + + // Update custom dictionary words. + void OnCustomDictionaryChanged(const std::set<std::string>& words_added, + const std::set<std::string>& words_removed); + + private: + // Correctly spelled words. + std::set<base::string16> dictionary_; + + DISALLOW_COPY_AND_ASSIGN(CustomDictionaryEngine); +}; + +#endif // COMPONENTS_SPELLCHECK_RENDERER_CUSTOM_DICTIONARY_ENGINE_H_
diff --git a/components/spellcheck/renderer/custom_dictionary_engine_unittest.cc b/components/spellcheck/renderer/custom_dictionary_engine_unittest.cc new file mode 100644 index 0000000..635316c --- /dev/null +++ b/components/spellcheck/renderer/custom_dictionary_engine_unittest.cc
@@ -0,0 +1,30 @@ +// 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. + +#include "base/strings/utf_string_conversions.h" +#include "components/spellcheck/renderer/custom_dictionary_engine.h" +#include "testing/gtest/include/gtest/gtest.h" + +TEST(CustomDictionaryTest, HandlesEmptyWordWithInvalidSubstring) { + CustomDictionaryEngine engine; + std::set<std::string> custom_words; + engine.Init(custom_words); + EXPECT_FALSE(engine.SpellCheckWord(base::string16().c_str(), 15, 23)); +} + +TEST(CustomDictionaryTest, Basic) { + CustomDictionaryEngine engine; + EXPECT_FALSE(engine.SpellCheckWord(base::ASCIIToUTF16("helllo").c_str(), + 0, 6)); + std::set<std::string> custom_words; + custom_words.insert("helllo"); + engine.Init(custom_words); + EXPECT_TRUE(engine.SpellCheckWord(base::ASCIIToUTF16("helllo").c_str(), + 0, 6)); +} + +TEST(CustomDictionaryTest, HandlesNullCharacters) { + base::char16 data[4] = {'a', 0, 'b', 'c'}; + EXPECT_FALSE(CustomDictionaryEngine().SpellCheckWord(data, 1, 1)); +}
diff --git a/components/spellcheck/renderer/hunspell_engine.cc b/components/spellcheck/renderer/hunspell_engine.cc new file mode 100644 index 0000000..1918565 --- /dev/null +++ b/components/spellcheck/renderer/hunspell_engine.cc
@@ -0,0 +1,140 @@ +// 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/spellcheck/renderer/hunspell_engine.h" + +#include <stddef.h> +#include <algorithm> +#include <iterator> +#include <utility> + +#include "base/files/memory_mapped_file.h" +#include "base/time/time.h" +#include "components/spellcheck/common/spellcheck_common.h" +#include "components/spellcheck/common/spellcheck_messages.h" +#include "content/public/renderer/render_thread.h" +#include "third_party/hunspell/src/hunspell/hunspell.hxx" + +using content::RenderThread; + +namespace { + // Maximum length of words we actually check. + // 64 is the observed limits for OSX system checker. + const size_t kMaxCheckedLen = 64; + + // Maximum length of words we provide suggestions for. + // 24 is the observed limits for OSX system checker. + const size_t kMaxSuggestLen = 24; + + static_assert(kMaxCheckedLen <= size_t(MAXWORDLEN), + "MaxCheckedLen too long"); + static_assert(kMaxSuggestLen <= kMaxCheckedLen, + "MaxSuggestLen too long"); +} // namespace + +#if !defined(USE_BROWSER_SPELLCHECKER) +SpellingEngine* CreateNativeSpellingEngine() { + return new HunspellEngine(); +} +#endif + +HunspellEngine::HunspellEngine() + : hunspell_enabled_(false), + initialized_(false), + dictionary_requested_(false) { + // Wait till we check the first word before doing any initializing. +} + +HunspellEngine::~HunspellEngine() { +} + +void HunspellEngine::Init(base::File file) { + initialized_ = true; + hunspell_.reset(); + bdict_file_.reset(); + file_ = std::move(file); + hunspell_enabled_ = file_.IsValid(); + // Delay the actual initialization of hunspell until it is needed. +} + +void HunspellEngine::InitializeHunspell() { + if (hunspell_.get()) + return; + + bdict_file_.reset(new base::MemoryMappedFile); + + if (bdict_file_->Initialize(std::move(file_))) { + hunspell_.reset(new Hunspell(bdict_file_->data(), bdict_file_->length())); + } else { + NOTREACHED() << "Could not mmap spellchecker dictionary."; + } +} + +bool HunspellEngine::CheckSpelling(const base::string16& word_to_check, + int tag) { + // Assume all words that cannot be checked are valid. Since Chrome can't + // offer suggestions on them, either, there's no point in flagging them to + // the user. + bool word_correct = true; + std::string word_to_check_utf8(base::UTF16ToUTF8(word_to_check)); + + // Limit the size of checked words. + if (word_to_check_utf8.length() <= kMaxCheckedLen) { + // If |hunspell_| is NULL here, an error has occurred, but it's better + // to check rather than crash. + if (hunspell_.get()) { + // |hunspell_->spell| returns 0 if the word is misspelled. + word_correct = (hunspell_->spell(word_to_check_utf8.c_str()) != 0); + } + } + + return word_correct; +} + +void HunspellEngine::FillSuggestionList( + const base::string16& wrong_word, + std::vector<base::string16>* optional_suggestions) { + std::string wrong_word_utf8(base::UTF16ToUTF8(wrong_word)); + if (wrong_word_utf8.length() > kMaxSuggestLen) + return; + + // If |hunspell_| is NULL here, an error has occurred, but it's better + // to check rather than crash. + // TODO(groby): Technically, it's not. We should track down the issue. + if (!hunspell_.get()) + return; + + char** suggestions = NULL; + int number_of_suggestions = + hunspell_->suggest(&suggestions, wrong_word_utf8.c_str()); + + // Populate the vector of WideStrings. + for (int i = 0; i < number_of_suggestions; ++i) { + if (i < spellcheck::kMaxSuggestions) + optional_suggestions->push_back(base::UTF8ToUTF16(suggestions[i])); + free(suggestions[i]); + } + if (suggestions != NULL) + free(suggestions); +} + +bool HunspellEngine::InitializeIfNeeded() { + if (!initialized_ && !dictionary_requested_) { + // RenderThread will not exist in test. + if (RenderThread::Get()) + RenderThread::Get()->Send(new SpellCheckHostMsg_RequestDictionary); + dictionary_requested_ = true; + return true; + } + + // Don't initialize if hunspell is disabled. + if (file_.IsValid()) + InitializeHunspell(); + + return !initialized_; +} + +bool HunspellEngine::IsEnabled() { + return hunspell_enabled_; +}
diff --git a/components/spellcheck/renderer/hunspell_engine.h b/components/spellcheck/renderer/hunspell_engine.h new file mode 100644 index 0000000..02adcee0 --- /dev/null +++ b/components/spellcheck/renderer/hunspell_engine.h
@@ -0,0 +1,63 @@ +// 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 COMPONENTS_SPELLCHECK_RENDERER_HUNSPELL_ENGINE_H_ +#define COMPONENTS_SPELLCHECK_RENDERER_HUNSPELL_ENGINE_H_ + +#include <memory> +#include <string> +#include <vector> + +#include "base/strings/string16.h" +#include "base/strings/utf_string_conversions.h" +#include "components/spellcheck/common/spellcheck_common.h" +#include "components/spellcheck/renderer/spelling_engine.h" + +class Hunspell; + +namespace base { +class MemoryMappedFile; +} + +class HunspellEngine : public SpellingEngine { + public: + HunspellEngine(); + ~HunspellEngine() override; + + void Init(base::File file) override; + + bool InitializeIfNeeded() override; + bool IsEnabled() override; + bool CheckSpelling(const base::string16& word_to_check, int tag) override; + void FillSuggestionList( + const base::string16& wrong_word, + std::vector<base::string16>* optional_suggestions) override; + + private: + // Initializes the Hunspell dictionary, or does nothing if |hunspell_| is + // non-null. This blocks. + void InitializeHunspell(); + + // We memory-map the BDict file. + std::unique_ptr<base::MemoryMappedFile> bdict_file_; + + // The hunspell dictionary in use. + std::unique_ptr<Hunspell> hunspell_; + + base::File file_; + + // This flag is true if hunspell is enabled. + bool hunspell_enabled_; + + // This flag is true if we have been initialized. + // The value indicates whether we should request a + // dictionary from the browser when the render view asks us to check the + // spelling of a word. + bool initialized_; + + // This flag is true if we have requested dictionary. + bool dictionary_requested_; +}; + +#endif // COMPONENTS_SPELLCHECK_RENDERER_HUNSPELL_ENGINE_H_
diff --git a/components/spellcheck/renderer/platform_spelling_engine.cc b/components/spellcheck/renderer/platform_spelling_engine.cc new file mode 100644 index 0000000..6c9176a --- /dev/null +++ b/components/spellcheck/renderer/platform_spelling_engine.cc
@@ -0,0 +1,47 @@ +// 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/spellcheck/renderer/platform_spelling_engine.h" + +#include "components/spellcheck/common/spellcheck_messages.h" +#include "content/public/renderer/render_thread.h" + +using content::RenderThread; + +SpellingEngine* CreateNativeSpellingEngine() { + return new PlatformSpellingEngine(); +} + +void PlatformSpellingEngine::Init(base::File bdict_file) { + DCHECK(!bdict_file.IsValid()); +} + +bool PlatformSpellingEngine::InitializeIfNeeded() { + return false; +} + +bool PlatformSpellingEngine::IsEnabled() { + return true; +} + +// Synchronously query against the platform's spellchecker. +// TODO(groby): We might want async support here, too. Ideally, +// all engines share a similar path for async requests. +bool PlatformSpellingEngine::CheckSpelling(const base::string16& word_to_check, + int tag) { + bool word_correct = false; + RenderThread::Get()->Send(new SpellCheckHostMsg_CheckSpelling( + word_to_check, tag, &word_correct)); + return word_correct; +} + +// Synchronously query against the platform's spellchecker. +// TODO(groby): We might want async support here, too. Ideally, +// all engines share a similar path for async requests. +void PlatformSpellingEngine::FillSuggestionList( + const base::string16& wrong_word, + std::vector<base::string16>* optional_suggestions) { + RenderThread::Get()->Send(new SpellCheckHostMsg_FillSuggestionList( + wrong_word, optional_suggestions)); +}
diff --git a/components/spellcheck/renderer/platform_spelling_engine.h b/components/spellcheck/renderer/platform_spelling_engine.h new file mode 100644 index 0000000..294d8262 --- /dev/null +++ b/components/spellcheck/renderer/platform_spelling_engine.h
@@ -0,0 +1,23 @@ +// 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 COMPONENTS_SPELLCHECK_RENDERER_PLATFORM_SPELLING_ENGINE_H_ +#define COMPONENTS_SPELLCHECK_RENDERER_PLATFORM_SPELLING_ENGINE_H_ + +#include "base/compiler_specific.h" +#include "components/spellcheck/renderer/spelling_engine.h" + +class PlatformSpellingEngine : public SpellingEngine { + public: + void Init(base::File bdict_file) override; + bool InitializeIfNeeded() override; + bool IsEnabled() override; + bool CheckSpelling(const base::string16& word_to_check, int tag) override; + void FillSuggestionList( + const base::string16& wrong_word, + std::vector<base::string16>* optional_suggestions) override; +}; + +#endif // COMPONENTS_SPELLCHECK_RENDERER_PLATFORM_SPELLING_ENGINE_H_ +
diff --git a/components/spellcheck/renderer/spellcheck.cc b/components/spellcheck/renderer/spellcheck.cc new file mode 100644 index 0000000..af6603b --- /dev/null +++ b/components/spellcheck/renderer/spellcheck.cc
@@ -0,0 +1,547 @@ +// 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/spellcheck/renderer/spellcheck.h" + +#include <stddef.h> +#include <stdint.h> +#include <algorithm> +#include <utility> + +#include "base/bind.h" +#include "base/command_line.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/single_thread_task_runner.h" +#include "base/stl_util.h" +#include "base/threading/thread_task_runner_handle.h" +#include "build/build_config.h" +//#include "chrome/common/channel_info.h" +#include "components/spellcheck/common/spellcheck_common.h" +#include "components/spellcheck/common/spellcheck_messages.h" +#include "components/spellcheck/common/spellcheck_result.h" +#include "components/spellcheck/common/spellcheck_switches.h" +#include "components/spellcheck/renderer/spellcheck_language.h" +#include "components/spellcheck/renderer/spellcheck_provider.h" +#include "content/public/renderer/render_thread.h" +#include "content/public/renderer/render_view.h" +#include "content/public/renderer/render_view_visitor.h" +#include "ipc/ipc_platform_file.h" +#include "third_party/WebKit/public/platform/WebString.h" +#include "third_party/WebKit/public/platform/WebVector.h" +#include "third_party/WebKit/public/web/WebTextCheckingCompletion.h" +#include "third_party/WebKit/public/web/WebTextCheckingResult.h" +#include "third_party/WebKit/public/web/WebTextDecorationType.h" +#include "third_party/WebKit/public/web/WebView.h" + +using blink::WebVector; +using blink::WebString; +using blink::WebTextCheckingResult; +using blink::WebTextDecorationType; + +namespace { +const int kNoOffset = 0; +const int kNoTag = 0; + +class UpdateSpellcheckEnabled : public content::RenderViewVisitor { + public: + explicit UpdateSpellcheckEnabled(bool enabled) : enabled_(enabled) {} + bool Visit(content::RenderView* render_view) override; + + private: + bool enabled_; // New spellcheck-enabled state. + DISALLOW_COPY_AND_ASSIGN(UpdateSpellcheckEnabled); +}; + +bool UpdateSpellcheckEnabled::Visit(content::RenderView* render_view) { + SpellCheckProvider* provider = SpellCheckProvider::Get(render_view); + DCHECK(provider); + provider->EnableSpellcheck(enabled_); + return true; +} + +class DocumentMarkersCollector : public content::RenderViewVisitor { + public: + DocumentMarkersCollector() {} + ~DocumentMarkersCollector() override {} + const std::vector<uint32_t>& markers() const { return markers_; } + bool Visit(content::RenderView* render_view) override; + + private: + std::vector<uint32_t> markers_; + DISALLOW_COPY_AND_ASSIGN(DocumentMarkersCollector); +}; + +bool DocumentMarkersCollector::Visit(content::RenderView* render_view) { + if (!render_view || !render_view->GetWebView()) + return true; + WebVector<uint32_t> markers; + render_view->GetWebView()->spellingMarkers(&markers); + for (size_t i = 0; i < markers.size(); ++i) + markers_.push_back(markers[i]); + // Visit all render views. + return true; +} + +class DocumentMarkersRemover : public content::RenderViewVisitor { + public: + explicit DocumentMarkersRemover(const std::set<std::string>& words); + ~DocumentMarkersRemover() override {} + bool Visit(content::RenderView* render_view) override; + + private: + WebVector<WebString> words_; + DISALLOW_COPY_AND_ASSIGN(DocumentMarkersRemover); +}; + +DocumentMarkersRemover::DocumentMarkersRemover( + const std::set<std::string>& words) + : words_(words.size()) { + std::transform(words.begin(), words.end(), words_.begin(), + [](const std::string& w) { return WebString::fromUTF8(w); }); +} + +bool DocumentMarkersRemover::Visit(content::RenderView* render_view) { + if (render_view && render_view->GetWebView()) + render_view->GetWebView()->removeSpellingMarkersUnderWords(words_); + return true; +} + +bool IsApostrophe(base::char16 c) { + const base::char16 kApostrophe = 0x27; + const base::char16 kRightSingleQuotationMark = 0x2019; + return c == kApostrophe || c == kRightSingleQuotationMark; +} + +// Makes sure that the apostrophes in the |spelling_suggestion| are the same +// type as in the |misspelled_word| and in the same order. Ignore differences in +// the number of apostrophes. +void PreserveOriginalApostropheTypes(const base::string16& misspelled_word, + base::string16* spelling_suggestion) { + auto it = spelling_suggestion->begin(); + for (const base::char16& c : misspelled_word) { + if (IsApostrophe(c)) { + it = std::find_if(it, spelling_suggestion->end(), IsApostrophe); + if (it == spelling_suggestion->end()) + return; + + *it++ = c; + } + } +} + +} // namespace + +class SpellCheck::SpellcheckRequest { + public: + SpellcheckRequest(const base::string16& text, + blink::WebTextCheckingCompletion* completion) + : text_(text), completion_(completion) { + DCHECK(completion); + } + ~SpellcheckRequest() {} + + base::string16 text() { return text_; } + blink::WebTextCheckingCompletion* completion() { return completion_; } + + private: + base::string16 text_; // Text to be checked in this task. + + // The interface to send the misspelled ranges to WebKit. + blink::WebTextCheckingCompletion* completion_; + + DISALLOW_COPY_AND_ASSIGN(SpellcheckRequest); +}; + + +// Initializes SpellCheck object. +// spellcheck_enabled_ currently MUST be set to true, due to peculiarities of +// the initialization sequence. +// Since it defaults to true, newly created SpellCheckProviders will enable +// spellchecking. After the first word is typed, the provider requests a check, +// which in turn triggers the delayed initialization sequence in SpellCheck. +// This does send a message to the browser side, which triggers the creation +// of the SpellcheckService. That does create the observer for the preference +// responsible for enabling/disabling checking, which allows subsequent changes +// to that preference to be sent to all SpellCheckProviders. +// Setting |spellcheck_enabled_| to false by default prevents that mechanism, +// and as such the SpellCheckProviders will never be notified of different +// values. +// TODO(groby): Simplify this. +SpellCheck::SpellCheck() : spellcheck_enabled_(true) {} + +SpellCheck::~SpellCheck() { +} + +void SpellCheck::FillSuggestions( + const std::vector<std::vector<base::string16>>& suggestions_list, + std::vector<base::string16>* optional_suggestions) { + DCHECK(optional_suggestions); + size_t num_languages = suggestions_list.size(); + + // Compute maximum number of suggestions in a single language. + size_t max_suggestions = 0; + for (const auto& suggestions : suggestions_list) + max_suggestions = std::max(max_suggestions, suggestions.size()); + + for (size_t count = 0; count < (max_suggestions * num_languages); ++count) { + size_t language = count % num_languages; + size_t index = count / num_languages; + + if (suggestions_list[language].size() <= index) + continue; + + const base::string16& suggestion = suggestions_list[language][index]; + // Only add the suggestion if it's unique. + if (!base::ContainsValue(*optional_suggestions, suggestion)) { + optional_suggestions->push_back(suggestion); + } + if (optional_suggestions->size() >= spellcheck::kMaxSuggestions) { + break; + } + } +} + +bool SpellCheck::OnControlMessageReceived(const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(SpellCheck, message) + IPC_MESSAGE_HANDLER(SpellCheckMsg_Init, OnInit) + IPC_MESSAGE_HANDLER(SpellCheckMsg_CustomDictionaryChanged, + OnCustomDictionaryChanged) + IPC_MESSAGE_HANDLER(SpellCheckMsg_EnableSpellCheck, OnEnableSpellCheck) + IPC_MESSAGE_HANDLER(SpellCheckMsg_RequestDocumentMarkers, + OnRequestDocumentMarkers) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + + return handled; +} + +void SpellCheck::OnInit( + const std::vector<SpellCheckBDictLanguage>& bdict_languages, + const std::set<std::string>& custom_words) { + languages_.clear(); + for (const auto& bdict_language : bdict_languages) { + AddSpellcheckLanguage( + IPC::PlatformFileForTransitToFile(bdict_language.file), + bdict_language.language); + } + + custom_dictionary_.Init(custom_words); +#if !defined(USE_BROWSER_SPELLCHECKER) + PostDelayedSpellCheckTask(pending_request_param_.release()); +#endif +} + +void SpellCheck::OnCustomDictionaryChanged( + const std::set<std::string>& words_added, + const std::set<std::string>& words_removed) { + custom_dictionary_.OnCustomDictionaryChanged(words_added, words_removed); + if (words_added.empty()) + return; + DocumentMarkersRemover markersRemover(words_added); + content::RenderView::ForEach(&markersRemover); +} + +void SpellCheck::OnEnableSpellCheck(bool enable) { + spellcheck_enabled_ = enable; + UpdateSpellcheckEnabled updater(enable); + content::RenderView::ForEach(&updater); +} + +void SpellCheck::OnRequestDocumentMarkers() { + DocumentMarkersCollector collector; + content::RenderView::ForEach(&collector); + content::RenderThread::Get()->Send( + new SpellCheckHostMsg_RespondDocumentMarkers(collector.markers())); +} + +// TODO(groby): Make sure we always have a spelling engine, even before +// AddSpellcheckLanguage() is called. +void SpellCheck::AddSpellcheckLanguage(base::File file, + const std::string& language) { + languages_.push_back(new SpellcheckLanguage()); + languages_.back()->Init(std::move(file), language); +} + +bool SpellCheck::SpellCheckWord( + const base::char16* text_begin, + int position_in_text, + int text_length, + int tag, + int* misspelling_start, + int* misspelling_len, + std::vector<base::string16>* optional_suggestions) { + DCHECK(text_length >= position_in_text); + DCHECK(misspelling_start && misspelling_len) << "Out vars must be given."; + + // Do nothing if we need to delay initialization. (Rather than blocking, + // report the word as correctly spelled.) + if (InitializeIfNeeded()) + return true; + + // These are for holding misspelling or skippable word positions and lengths + // between calls to SpellcheckLanguage::SpellCheckWord. + int possible_misspelling_start; + int possible_misspelling_len; + // The longest sequence of text that all languages agree is skippable. + int agreed_skippable_len; + // A vector of vectors containing spelling suggestions from different + // languages. + std::vector<std::vector<base::string16>> suggestions_list; + // A vector to hold a language's misspelling suggestions between spellcheck + // calls. + std::vector<base::string16> language_suggestions; + + // This loop only advances if all languages agree that a sequence of text is + // skippable. + for (; position_in_text <= text_length; + position_in_text += agreed_skippable_len) { + // Reseting |agreed_skippable_len| to the worst-case length each time + // prevents some unnecessary iterations. + agreed_skippable_len = text_length; + *misspelling_start = 0; + *misspelling_len = 0; + suggestions_list.clear(); + + for (ScopedVector<SpellcheckLanguage>::iterator language = + languages_.begin(); + language != languages_.end();) { + language_suggestions.clear(); + SpellcheckLanguage::SpellcheckWordResult result = + (*language)->SpellCheckWord( + text_begin, position_in_text, text_length, tag, + &possible_misspelling_start, &possible_misspelling_len, + optional_suggestions ? &language_suggestions : nullptr); + + switch (result) { + case SpellcheckLanguage::SpellcheckWordResult::IS_CORRECT: + *misspelling_start = 0; + *misspelling_len = 0; + return true; + case SpellcheckLanguage::SpellcheckWordResult::IS_SKIPPABLE: + agreed_skippable_len = + std::min(agreed_skippable_len, possible_misspelling_len); + // If true, this means the spellchecker moved past a word that was + // previously determined to be misspelled or skippable, which means + // another spellcheck language marked it as correct. + if (position_in_text != possible_misspelling_start) { + *misspelling_len = 0; + position_in_text = possible_misspelling_start; + suggestions_list.clear(); + language = languages_.begin(); + } else { + language++; + } + break; + case SpellcheckLanguage::SpellcheckWordResult::IS_MISSPELLED: + *misspelling_start = possible_misspelling_start; + *misspelling_len = possible_misspelling_len; + // If true, this means the spellchecker moved past a word that was + // previously determined to be misspelled or skippable, which means + // another spellcheck language marked it as correct. + if (position_in_text != *misspelling_start) { + suggestions_list.clear(); + language = languages_.begin(); + position_in_text = *misspelling_start; + } else { + suggestions_list.push_back(language_suggestions); + language++; + } + break; + } + } + + // If |*misspelling_len| is non-zero, that means at least one language + // marked a word misspelled and no other language considered it correct. + if (*misspelling_len != 0) { + if (optional_suggestions) + FillSuggestions(suggestions_list, optional_suggestions); + return false; + } + } + + NOTREACHED(); + return true; +} + +bool SpellCheck::SpellCheckParagraph( + const base::string16& text, + WebVector<WebTextCheckingResult>* results) { +#if !defined(USE_BROWSER_SPELLCHECKER) + // Mac and Android have their own spell checkers,so this method won't be used + DCHECK(results); + std::vector<WebTextCheckingResult> textcheck_results; + size_t length = text.length(); + size_t position_in_text = 0; + + // Spellcheck::SpellCheckWord() automatically breaks text into words and + // checks the spellings of the extracted words. This function sets the + // position and length of the first misspelled word and returns false when + // the text includes misspelled words. Therefore, we just repeat calling the + // function until it returns true to check the whole text. + int misspelling_start = 0; + int misspelling_length = 0; + while (position_in_text <= length) { + if (SpellCheckWord(text.c_str(), + position_in_text, + length, + kNoTag, + &misspelling_start, + &misspelling_length, + NULL)) { + results->assign(textcheck_results); + return true; + } + + if (!custom_dictionary_.SpellCheckWord( + text, misspelling_start, misspelling_length)) { + base::string16 replacement; + textcheck_results.push_back(WebTextCheckingResult( + blink::WebTextDecorationTypeSpelling, + misspelling_start, + misspelling_length, + replacement)); + } + position_in_text = misspelling_start + misspelling_length; + } + results->assign(textcheck_results); + return false; +#else + // This function is only invoked for spell checker functionality that runs + // on the render thread. OSX and Android builds don't have that. + NOTREACHED(); + return true; +#endif +} + +// OSX and Android use their own spell checkers +#if !defined(USE_BROWSER_SPELLCHECKER) +void SpellCheck::RequestTextChecking( + const base::string16& text, + blink::WebTextCheckingCompletion* completion) { + // Clean up the previous request before starting a new request. + if (pending_request_param_.get()) + pending_request_param_->completion()->didCancelCheckingText(); + + pending_request_param_.reset(new SpellcheckRequest( + text, completion)); + // We will check this text after we finish loading the hunspell dictionary. + if (InitializeIfNeeded()) + return; + + PostDelayedSpellCheckTask(pending_request_param_.release()); +} +#endif + +bool SpellCheck::InitializeIfNeeded() { + if (languages_.empty()) + return true; + + bool initialize_if_needed = false; + for (SpellcheckLanguage* language : languages_) + initialize_if_needed |= language->InitializeIfNeeded(); + + return initialize_if_needed; +} + +// OSX and Android don't have |pending_request_param_| +#if !defined(USE_BROWSER_SPELLCHECKER) +void SpellCheck::PostDelayedSpellCheckTask(SpellcheckRequest* request) { + if (!request) + return; + + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(&SpellCheck::PerformSpellCheck, AsWeakPtr(), + base::Owned(request))); +} +#endif + +// Mac and Android use their platform engines instead. +#if !defined(USE_BROWSER_SPELLCHECKER) +void SpellCheck::PerformSpellCheck(SpellcheckRequest* param) { + DCHECK(param); + + if (languages_.empty() || + std::find_if(languages_.begin(), languages_.end(), + [](SpellcheckLanguage* language) { + return !language->IsEnabled(); + }) != languages_.end()) { + param->completion()->didCancelCheckingText(); + } else { + WebVector<blink::WebTextCheckingResult> results; + SpellCheckParagraph(param->text(), &results); + param->completion()->didFinishCheckingText(results); + } +} +#endif + +void SpellCheck::CreateTextCheckingResults( + ResultFilter filter, + int line_offset, + const base::string16& line_text, + const std::vector<SpellCheckResult>& spellcheck_results, + WebVector<WebTextCheckingResult>* textcheck_results) { + DCHECK(!line_text.empty()); + + std::vector<WebTextCheckingResult> results; + for (const SpellCheckResult& spellcheck_result : spellcheck_results) { + DCHECK_LE(static_cast<size_t>(spellcheck_result.location), + line_text.length()); + DCHECK_LE(static_cast<size_t>(spellcheck_result.location + + spellcheck_result.length), + line_text.length()); + + const base::string16& misspelled_word = + line_text.substr(spellcheck_result.location, spellcheck_result.length); + base::string16 replacement = spellcheck_result.replacement; + SpellCheckResult::Decoration decoration = spellcheck_result.decoration; + + // Ignore words in custom dictionary. + if (custom_dictionary_.SpellCheckWord(misspelled_word, 0, + misspelled_word.length())) { + continue; + } + + // Use the same types of appostrophes as in the mispelled word. + PreserveOriginalApostropheTypes(misspelled_word, &replacement); + + // Ignore misspellings due the typographical apostrophe. + if (misspelled_word == replacement) + continue; + + if (filter == USE_NATIVE_CHECKER) { + // Double-check misspelled words with out spellchecker and attach grammar + // markers to them if our spellchecker tells us they are correct words, + // i.e. they are probably contextually-misspelled words. + int unused_misspelling_start = 0; + int unused_misspelling_length = 0; + if (decoration == SpellCheckResult::SPELLING && + SpellCheckWord(misspelled_word.c_str(), kNoOffset, + misspelled_word.length(), kNoTag, + &unused_misspelling_start, &unused_misspelling_length, + nullptr)) { + decoration = SpellCheckResult::GRAMMAR; + } + } + + results.push_back(WebTextCheckingResult( + static_cast<WebTextDecorationType>(decoration), + line_offset + spellcheck_result.location, spellcheck_result.length, + replacement, spellcheck_result.hash)); + } + + textcheck_results->assign(results); +} + +bool SpellCheck::IsSpellcheckEnabled() { +#if defined(OS_ANDROID) + if (!base::CommandLine::ForCurrentProcess()->HasSwitch( + spellcheck::switches::kEnableAndroidSpellChecker)) { + return false; + } +#endif + return spellcheck_enabled_; +}
diff --git a/components/spellcheck/renderer/spellcheck.h b/components/spellcheck/renderer/spellcheck.h new file mode 100644 index 0000000..9bcd1ce --- /dev/null +++ b/components/spellcheck/renderer/spellcheck.h
@@ -0,0 +1,164 @@ +// 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 COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_H_ +#define COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_H_ + +#include <memory> +#include <set> +#include <string> +#include <vector> + +#include "base/files/file.h" +#include "base/gtest_prod_util.h" +#include "base/macros.h" +#include "base/memory/scoped_vector.h" +#include "base/memory/weak_ptr.h" +#include "base/strings/string16.h" +#include "components/spellcheck/renderer/custom_dictionary_engine.h" +#include "content/public/renderer/render_thread_observer.h" + +struct SpellCheckBDictLanguage; +class SpellcheckLanguage; +struct SpellCheckResult; + +namespace blink { +class WebTextCheckingCompletion; +struct WebTextCheckingResult; +template <typename T> class WebVector; +} + +namespace IPC { +class Message; +} + +// TODO(morrita): Needs reorg with SpellCheckProvider. +// See http://crbug.com/73699. +// Shared spellchecking logic/data for a RenderProcess. All RenderViews use +// this object to perform spellchecking tasks. +class SpellCheck : public content::RenderThreadObserver, + public base::SupportsWeakPtr<SpellCheck> { + public: + // TODO(groby): I wonder if this can be private, non-mac only. + class SpellcheckRequest; + enum ResultFilter { + DO_NOT_MODIFY = 1, // Do not modify results. + USE_NATIVE_CHECKER, // Use native checker to double-check. + }; + + SpellCheck(); + ~SpellCheck() override; + + void AddSpellcheckLanguage(base::File file, const std::string& language); + + // If there are no dictionary files, then this requests them from the browser + // and does not block. In this case it returns true. + // If there are dictionary files, but their Hunspell has not been loaded, then + // this loads their Hunspell. + // If each dictionary file's Hunspell is already loaded, this does nothing. In + // both the latter cases it returns false, meaning that it is OK to continue + // spellchecking. + bool InitializeIfNeeded(); + + // SpellCheck a word. + // Returns true if spelled correctly for any language in |languages_|, false + // otherwise. + // If any spellcheck languages failed to initialize, always returns true. + // The |tag| parameter should either be a unique identifier for the document + // that the word came from (if the current platform requires it), or 0. + // In addition, finds the suggested words for a given word + // and puts them into |*optional_suggestions|. + // If the word is spelled correctly, the vector is empty. + // If optional_suggestions is NULL, suggested words will not be looked up. + // Note that doing suggest lookups can be slow. + bool SpellCheckWord(const base::char16* text_begin, + int position_in_text, + int text_length, + int tag, + int* misspelling_start, + int* misspelling_len, + std::vector<base::string16>* optional_suggestions); + + // SpellCheck a paragraph. + // Returns true if |text| is correctly spelled, false otherwise. + // If the spellchecker failed to initialize, always returns true. + bool SpellCheckParagraph( + const base::string16& text, + blink::WebVector<blink::WebTextCheckingResult>* results); + + // Requests to spellcheck the specified text in the background. This function + // posts a background task and calls SpellCheckParagraph() in the task. +#if !defined (USE_BROWSER_SPELLCHECKER) + void RequestTextChecking(const base::string16& text, + blink::WebTextCheckingCompletion* completion); +#endif + + // Creates a list of WebTextCheckingResult objects (used by WebKit) from a + // list of SpellCheckResult objects (used by Chrome). This function also + // checks misspelled words returned by the Spelling service and changes the + // underline colors of contextually-misspelled words. + void CreateTextCheckingResults( + ResultFilter filter, + int line_offset, + const base::string16& line_text, + const std::vector<SpellCheckResult>& spellcheck_results, + blink::WebVector<blink::WebTextCheckingResult>* textcheck_results); + + bool IsSpellcheckEnabled(); + + private: + friend class SpellCheckTest; + FRIEND_TEST_ALL_PREFIXES(SpellCheckTest, GetAutoCorrectionWord_EN_US); + FRIEND_TEST_ALL_PREFIXES(SpellCheckTest, + RequestSpellCheckMultipleTimesWithoutInitialization); + + // Evenly fill |optional_suggestions| with a maximum of |kMaxSuggestions| + // suggestions from |suggestions_list|. suggestions_list[i][j] is the j-th + // suggestion from the i-th language's suggestions. |optional_suggestions| + // cannot be null. + static void FillSuggestions( + const std::vector<std::vector<base::string16>>& suggestions_list, + std::vector<base::string16>* optional_suggestions); + + // RenderThreadObserver implementation: + bool OnControlMessageReceived(const IPC::Message& message) override; + + // Message handlers. + void OnInit(const std::vector<SpellCheckBDictLanguage>& bdict_languages, + const std::set<std::string>& custom_words); + void OnCustomDictionaryChanged(const std::set<std::string>& words_added, + const std::set<std::string>& words_removed); + void OnEnableSpellCheck(bool enable); + void OnRequestDocumentMarkers(); + +#if !defined (USE_BROWSER_SPELLCHECKER) + // Posts delayed spellcheck task and clear it if any. + // Takes ownership of |request|. + void PostDelayedSpellCheckTask(SpellcheckRequest* request); + + // Performs spell checking from the request queue. + void PerformSpellCheck(SpellcheckRequest* request); + + // The parameters of a pending background-spellchecking request. When WebKit + // sends a background-spellchecking request before initializing hunspell, + // we save its parameters and start spellchecking after we finish initializing + // hunspell. (When WebKit sends two or more requests, we cancel the previous + // requests so we do not have to use vectors.) + std::unique_ptr<SpellcheckRequest> pending_request_param_; +#endif + + // A vector of objects used to actually check spelling, one for each enabled + // language. + ScopedVector<SpellcheckLanguage> languages_; + + // Custom dictionary spelling engine. + CustomDictionaryEngine custom_dictionary_; + + // Remember state for spellchecking. + bool spellcheck_enabled_; + + DISALLOW_COPY_AND_ASSIGN(SpellCheck); +}; + +#endif // COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_H_
diff --git a/components/spellcheck/renderer/spellcheck_language.cc b/components/spellcheck/renderer/spellcheck_language.cc new file mode 100644 index 0000000..994ac792 --- /dev/null +++ b/components/spellcheck/renderer/spellcheck_language.cc
@@ -0,0 +1,151 @@ +// 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/spellcheck/renderer/spellcheck_language.h" + +#include <utility> + +#include "base/logging.h" +#include "components/spellcheck/renderer/spellcheck_worditerator.h" +#include "components/spellcheck/renderer/spelling_engine.h" + + +SpellcheckLanguage::SpellcheckLanguage() + : platform_spelling_engine_(CreateNativeSpellingEngine()) { +} + +SpellcheckLanguage::~SpellcheckLanguage() { +} + +void SpellcheckLanguage::Init(base::File file, const std::string& language) { + DCHECK(platform_spelling_engine_.get()); + platform_spelling_engine_->Init(std::move(file)); + + character_attributes_.SetDefaultLanguage(language); + text_iterator_.Reset(); + contraction_iterator_.Reset(); +} + +bool SpellcheckLanguage::InitializeIfNeeded() { + DCHECK(platform_spelling_engine_.get()); + return platform_spelling_engine_->InitializeIfNeeded(); +} + +SpellcheckLanguage::SpellcheckWordResult SpellcheckLanguage::SpellCheckWord( + const base::char16* text_begin, + int position_in_text, + int text_length, + int tag, + int* skip_or_misspelling_start, + int* skip_or_misspelling_len, + std::vector<base::string16>* optional_suggestions) { + int remaining_text_len = text_length - position_in_text; + DCHECK(remaining_text_len >= 0); + DCHECK(skip_or_misspelling_start && skip_or_misspelling_len) + << "Out vars must be given."; + + // Do nothing if we need to delay initialization. (Rather than blocking, + // report the word as correctly spelled.) + if (InitializeIfNeeded()) + return IS_CORRECT; + + // Do nothing if spell checking is disabled. + if (!platform_spelling_engine_.get() || + !platform_spelling_engine_->IsEnabled()) + return IS_CORRECT; + + *skip_or_misspelling_start = 0; + *skip_or_misspelling_len = 0; + if (remaining_text_len == 0) + return IS_CORRECT; // No input means always spelled correctly. + + base::string16 word; + int word_start; + int word_length; + if (!text_iterator_.IsInitialized() && + !text_iterator_.Initialize(&character_attributes_, true)) { + // We failed to initialize text_iterator_, return as spelled correctly. + VLOG(1) << "Failed to initialize SpellcheckWordIterator"; + return IS_CORRECT; + } + + text_iterator_.SetText(text_begin + position_in_text, remaining_text_len); + DCHECK(platform_spelling_engine_.get()); + for (SpellcheckWordIterator::WordIteratorStatus status = + text_iterator_.GetNextWord(&word, &word_start, &word_length); + status != SpellcheckWordIterator::IS_END_OF_TEXT; + status = text_iterator_.GetNextWord(&word, &word_start, &word_length)) { + // Found a character that is not able to be spellchecked so determine how + // long the sequence of uncheckable characters is and then return. + if (status == SpellcheckWordIterator::IS_SKIPPABLE) { + *skip_or_misspelling_start = position_in_text + word_start; + while (status == SpellcheckWordIterator::IS_SKIPPABLE) { + *skip_or_misspelling_len += word_length; + status = text_iterator_.GetNextWord(&word, &word_start, &word_length); + } + return IS_SKIPPABLE; + } + + // Found a word (or a contraction) that the spellchecker can check the + // spelling of. + if (platform_spelling_engine_->CheckSpelling(word, tag)) + continue; + + // If the given word is a concatenated word of two or more valid words + // (e.g. "hello:hello"), we should treat it as a valid word. + if (IsValidContraction(word, tag)) + continue; + + *skip_or_misspelling_start = position_in_text + word_start; + *skip_or_misspelling_len = word_length; + + // Get the list of suggested words. + if (optional_suggestions) { + platform_spelling_engine_->FillSuggestionList(word, + optional_suggestions); + } + return IS_MISSPELLED; + } + + return IS_CORRECT; +} + +// Returns whether or not the given string is a valid contraction. +// This function is a fall-back when the SpellcheckWordIterator class +// returns a concatenated word which is not in the selected dictionary +// (e.g. "in'n'out") but each word is valid. +bool SpellcheckLanguage::IsValidContraction(const base::string16& contraction, + int tag) { + if (!contraction_iterator_.IsInitialized() && + !contraction_iterator_.Initialize(&character_attributes_, false)) { + // We failed to initialize the word iterator, return as spelled correctly. + VLOG(1) << "Failed to initialize contraction_iterator_"; + return true; + } + + contraction_iterator_.SetText(contraction.c_str(), contraction.length()); + + base::string16 word; + int word_start; + int word_length; + + DCHECK(platform_spelling_engine_.get()); + for (SpellcheckWordIterator::WordIteratorStatus status = + contraction_iterator_.GetNextWord(&word, &word_start, &word_length); + status != SpellcheckWordIterator::IS_END_OF_TEXT; + status = contraction_iterator_.GetNextWord(&word, &word_start, + &word_length)) { + if (status == SpellcheckWordIterator::IS_SKIPPABLE) + continue; + + if (!platform_spelling_engine_->CheckSpelling(word, tag)) + return false; + } + return true; +} + +bool SpellcheckLanguage::IsEnabled() { + DCHECK(platform_spelling_engine_.get()); + return platform_spelling_engine_->IsEnabled(); +}
diff --git a/components/spellcheck/renderer/spellcheck_language.h b/components/spellcheck/renderer/spellcheck_language.h new file mode 100644 index 0000000..0843a45 --- /dev/null +++ b/components/spellcheck/renderer/spellcheck_language.h
@@ -0,0 +1,99 @@ +// 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 COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_LANGUAGE_H_ +#define COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_LANGUAGE_H_ + +#include <memory> +#include <queue> +#include <string> +#include <vector> + +#include "base/files/file.h" +#include "base/macros.h" +#include "base/strings/string16.h" +#include "components/spellcheck/renderer/spellcheck_worditerator.h" + +class SpellingEngine; + +class SpellcheckLanguage { + public: + enum SpellcheckWordResult { + // Denotes that every recognized word is spelled correctly, from the point + // of spellchecking to the end of the text. + IS_CORRECT, + // A sequence of skippable characters, such as punctuation, spaces, or + // characters not recognized by the current spellchecking language. + IS_SKIPPABLE, + // A misspelled word has been found in the text. + IS_MISSPELLED + }; + + SpellcheckLanguage(); + ~SpellcheckLanguage(); + + void Init(base::File file, const std::string& language); + + // Spellcheck a sequence of text. + // |text_length| is the length of the text being spellchecked. The |tag| + // parameter should either be a unique identifier for the document that the + // word came from (if the current platform requires it), or 0. + // + // - Returns IS_CORRECT if every word from |position_in_text| to the end of + // the text is recognized and spelled correctly. Also, returns IS_CORRECT if + // the spellchecker failed to initialize. + // + // - Returns IS_SKIPPABLE if a sequence of skippable characters, such as + // punctuation, spaces, or unrecognized characters, is found. + // |skip_or_misspelling_start| and |skip_or_misspelling_len| are then set to + // the position and the length of the sequence of skippable characters. + // + // - Returns IS_MISSPELLED if a misspelled word is found. + // |skip_or_misspelling_start| and |skip_or_misspelling_len| are then set to + // the position and length of the misspelled word. In addition, finds the + // suggested words for a given misspelled word and puts them into + // |*optional_suggestions|. If optional_suggestions is NULL, suggested words + // will not be looked up. Note that doing suggest lookups can be slow. + SpellcheckWordResult SpellCheckWord( + const base::char16* text_begin, + int position_in_text, + int text_length, + int tag, + int* skip_or_misspelling_start, + int* skip_or_misspelling_len, + std::vector<base::string16>* optional_suggestions); + + // Initialize |spellcheck_| if that hasn't happened yet. + bool InitializeIfNeeded(); + + // Return true if the underlying spellcheck engine is enabled. + bool IsEnabled(); + + private: + friend class SpellCheckTest; + + // Returns whether or not the given word is a contraction of valid words + // (e.g. "word:word"). + bool IsValidContraction(const base::string16& word, int tag); + + // Represents character attributes used for filtering out characters which + // are not supported by this SpellCheck object. + SpellcheckCharAttribute character_attributes_; + + // Represents word iterators used in this spellchecker. The |text_iterator_| + // splits text provided by WebKit into words, contractions, or concatenated + // words. The |contraction_iterator_| splits a concatenated word extracted by + // |text_iterator_| into word components so we can treat a concatenated word + // consisting only of correct words as a correct word. + SpellcheckWordIterator text_iterator_; + SpellcheckWordIterator contraction_iterator_; + + // Pointer to a platform-specific spelling engine, if it is in use. This + // should only be set if hunspell is not used. (I.e. on OSX, for now) + std::unique_ptr<SpellingEngine> platform_spelling_engine_; + + DISALLOW_COPY_AND_ASSIGN(SpellcheckLanguage); +}; + +#endif // COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_LANGUAGE_H_
diff --git a/components/spellcheck/renderer/spellcheck_multilingual_unittest.cc b/components/spellcheck/renderer/spellcheck_multilingual_unittest.cc new file mode 100644 index 0000000..1eda249 --- /dev/null +++ b/components/spellcheck/renderer/spellcheck_multilingual_unittest.cc
@@ -0,0 +1,256 @@ +// 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 <stddef.h> + +#include <algorithm> +#include <memory> +#include <utility> + +#include "base/macros.h" +#include "base/path_service.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "base/strings/utf_string_conversions.h" +#include "components/spellcheck/common/spellcheck_common.h" +#include "components/spellcheck/common/spellcheck_result.h" +#include "components/spellcheck/renderer/spellcheck.h" +#include "components/spellcheck/renderer/spellcheck_provider_test.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/public/platform/WebString.h" +#include "third_party/WebKit/public/platform/WebVector.h" +#include "third_party/WebKit/public/web/WebTextCheckingResult.h" + +namespace { + +struct SpellcheckTestCase { + // A string of text for checking. + const wchar_t* input; + // The position and the length of the first misspelled word, if any. + int expected_misspelling_start; + int expected_misspelling_length; +}; + +base::FilePath GetHunspellDirectory() { + base::FilePath hunspell_directory; + if (!PathService::Get(base::DIR_SOURCE_ROOT, &hunspell_directory)) + return base::FilePath(); + + hunspell_directory = hunspell_directory.AppendASCII("third_party"); + hunspell_directory = hunspell_directory.AppendASCII("hunspell_dictionaries"); + return hunspell_directory; +} + +} // namespace + +class MultilingualSpellCheckTest : public testing::Test { + public: + MultilingualSpellCheckTest() {} + + void ReinitializeSpellCheck(const std::string& unsplit_languages) { + spellcheck_ = new SpellCheck(); + provider_.reset(new TestingSpellCheckProvider(spellcheck_)); + InitializeSpellCheck(unsplit_languages); + } + + void InitializeSpellCheck(const std::string& unsplit_languages) { + base::FilePath hunspell_directory = GetHunspellDirectory(); + EXPECT_FALSE(hunspell_directory.empty()); + std::vector<std::string> languages = base::SplitString( + unsplit_languages, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + + for (const auto& language : languages) { + base::File file( + spellcheck::GetVersionedFileName(language, hunspell_directory), + base::File::FLAG_OPEN | base::File::FLAG_READ); + spellcheck_->AddSpellcheckLanguage(std::move(file), language); + } + } + + ~MultilingualSpellCheckTest() override {} + TestingSpellCheckProvider* provider() { return provider_.get(); } + + protected: + void ExpectSpellCheckWordResults(const std::string& languages, + const SpellcheckTestCase* test_cases, + size_t num_test_cases) { + ReinitializeSpellCheck(languages); + + for (size_t i = 0; i < num_test_cases; ++i) { + int misspelling_start = 0; + int misspelling_length = 0; + static_cast<blink::WebSpellCheckClient*>(provider()) + ->spellCheck(blink::WebString(base::WideToUTF16(test_cases[i].input)), + misspelling_start, misspelling_length, nullptr); + + EXPECT_EQ(test_cases[i].expected_misspelling_start, misspelling_start) + << "Improper misspelling location found with the languages " + << languages << " when checking \"" << test_cases[i].input << "\"."; + EXPECT_EQ(test_cases[i].expected_misspelling_length, misspelling_length) + << "Improper misspelling length found with the languages " + << languages << " when checking \"" << test_cases[i].input << "\"."; + } + } + + void ExpectSpellCheckParagraphResults( + const base::string16& input, + const std::vector<SpellCheckResult>& expected) { + blink::WebVector<blink::WebTextCheckingResult> results; + spellcheck_->SpellCheckParagraph(blink::WebString(input), &results); + + EXPECT_EQ(expected.size(), results.size()); + size_t size = std::min(results.size(), expected.size()); + for (size_t i = 0; i < size; ++i) { + EXPECT_EQ(blink::WebTextDecorationTypeSpelling, results[i].decoration); + EXPECT_EQ(expected[i].location, results[i].location); + EXPECT_EQ(expected[i].length, results[i].length); + } + } + + private: + // Owned by |provider_|. + SpellCheck* spellcheck_; + std::unique_ptr<TestingSpellCheckProvider> provider_; +}; + +// Check that a string of different words is properly spellchecked for different +// combinations of different languages. +TEST_F(MultilingualSpellCheckTest, MultilingualSpellCheckWord) { + static const SpellcheckTestCase kTestCases[] = { + // An English, Spanish, Russian, and Greek word, all spelled correctly. + {L"rocket destruyan \x0432\x0441\x0435\x0445 \x03C4\x03B9\x03C2", 0, 0}, + // A misspelled English word. + {L"rocktt destruyan \x0432\x0441\x0435\x0445 \x03C4\x03B9\x03C2", 0, 6}, + // A misspelled Spanish word. + {L"rocket destruynn \x0432\x0441\x0435\x0445 \x03C4\x03B9\x03C2", 7, 9}, + // A misspelled Russian word. + {L"rocket destruyan \x0430\x0430\x0430\x0430 \x03C4\x03B9\x03C2", 17, 4}, + // A misspelled Greek word. + {L"rocket destruyan \x0432\x0441\x0435\x0445 \x03B1\x03B1\x03B1\x03B1", + 22, 4}, + // An English word, then Russian, and then a misspelled English word. + {L"rocket \x0432\x0441\x0435\x0445 rocktt", 12, 6}, + }; + + // A sorted list of languages. This must start sorted to get all possible + // permutations. + std::string languages = "el-GR,en-US,es-ES,ru-RU"; + std::vector<std::string> permuted_languages = base::SplitString( + languages, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + + do { + languages = base::JoinString(permuted_languages, ","); + ExpectSpellCheckWordResults(languages, kTestCases, arraysize(kTestCases)); + } while (std::next_permutation(permuted_languages.begin(), + permuted_languages.end())); +} + +TEST_F(MultilingualSpellCheckTest, MultilingualSpellCheckWordEnglishSpanish) { + static const SpellcheckTestCase kTestCases[] = { + {L"", 0, 0}, + {L"head hand foot legs arms", 0, 0}, + {L"head hand foot legs arms zzzz", 25, 4}, + {L"head hand zzzz foot legs arms", 10, 4}, + {L"zzzz head hand foot legs arms", 0, 4}, + {L"zzzz head zzzz foot zzzz arms", 0, 4}, + {L"head hand foot arms zzzz zzzz", 20, 4}, + {L"I do not want a monstrous snake near me.", 0, 0}, + {L"zz do not want a monstrous snake near me.", 0, 2}, + {L"I do not want zz monstrous snake near me.", 14, 2}, + {L"I do not want a monstrous zz near me.", 26, 2}, + {L"I do not want a monstrou snake near me.", 16, 8}, + {L"I do not want a monstrous snake near zz.", 37, 2}, + {L"Partially Spanish is very bueno.", 0, 0}, + {L"Sleeping in the biblioteca is good.", 0, 0}, + {L"Hermano is my favorite name.", 0, 0}, + {L"hola hola hola hola hola hola", 0, 0}, + {L"sand hola hola hola hola hola", 0, 0}, + {L"hola sand sand sand sand sand", 0, 0}, + {L"sand sand sand sand sand hola", 0, 0}, + {L"sand hola sand hola sand hola", 0, 0}, + {L"hola sand hola sand hola sand", 0, 0}, + {L"hola:legs", 0, 9}, + {L"legs:hola", 0, 9}}; + ExpectSpellCheckWordResults("en-US,es-ES", kTestCases, arraysize(kTestCases)); +} + +// If there are no spellcheck languages, no text should be marked as misspelled. +TEST_F(MultilingualSpellCheckTest, MultilingualSpellCheckParagraphBlank) { + ReinitializeSpellCheck(std::string()); + + ExpectSpellCheckParagraphResults( + // English, German, Spanish, and a misspelled word. + base::UTF8ToUTF16("rocket Schwarzkommando destruyan pcnyhon"), + std::vector<SpellCheckResult>()); +} + +// Make sure nothing is considered misspelled when at least one of the selected +// languages determines that a word is correctly spelled. +TEST_F(MultilingualSpellCheckTest, MultilingualSpellCheckParagraphCorrect) { + ReinitializeSpellCheck("en-US,es-ES,de-DE"); + + ExpectSpellCheckParagraphResults( + // English, German, and Spanish words, all spelled correctly. + base::UTF8ToUTF16("rocket Schwarzkommando destruyan"), + std::vector<SpellCheckResult>()); +} + +// Make sure that all the misspellings in the text are found. +TEST_F(MultilingualSpellCheckTest, MultilingualSpellCheckParagraph) { + ReinitializeSpellCheck("en-US,es-ES"); + std::vector<SpellCheckResult> expected; + expected.push_back(SpellCheckResult(SpellCheckResult::SPELLING, 7, 15)); + expected.push_back(SpellCheckResult(SpellCheckResult::SPELLING, 33, 7)); + + ExpectSpellCheckParagraphResults( + // English, German, Spanish, and a misspelled word. + base::UTF8ToUTF16("rocket Schwarzkommando destruyan pcnyhon"), expected); +} + +// Ensure that suggestions are handled properly for multiple languages. +TEST_F(MultilingualSpellCheckTest, MultilingualSpellCheckSuggestions) { + ReinitializeSpellCheck("en-US,es-ES"); + static const struct { + // A string of text for checking. + const wchar_t* input; + // The position and the length of the first invalid word. + int expected_misspelling_start; + int expected_misspelling_length; + // A comma separated string of suggested words that should occur, in their + // expected order. + const wchar_t* expected_suggestions; + } kTestCases[] = { + {L"rocket", 0, 0}, + {L"destruyan", 0, 0}, + {L"rocet", 0, 5, L"rocket,roce,crochet,troce,rocen"}, + {L"jum", 0, 3, L"hum,jun,ju,um,juma"}, + {L"asdne", 0, 5, L"sadness,desasne"}, + }; + + for (size_t i = 0; i < arraysize(kTestCases); ++i) { + blink::WebVector<blink::WebString> suggestions; + int misspelling_start; + int misspelling_length; + static_cast<blink::WebSpellCheckClient*>(provider()) + ->spellCheck(blink::WebString(base::WideToUTF16(kTestCases[i].input)), + misspelling_start, misspelling_length, &suggestions); + + EXPECT_EQ(kTestCases[i].expected_misspelling_start, misspelling_start); + EXPECT_EQ(kTestCases[i].expected_misspelling_length, misspelling_length); + if (!kTestCases[i].expected_suggestions) { + EXPECT_EQ(0UL, suggestions.size()); + continue; + } + + std::vector<base::string16> expected_suggestions = base::SplitString( + base::WideToUTF16(kTestCases[i].expected_suggestions), + base::string16(1, ','), base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + + EXPECT_EQ(expected_suggestions.size(), suggestions.size()); + for (size_t j = 0; + j < std::min(expected_suggestions.size(), suggestions.size()); j++) { + EXPECT_EQ(expected_suggestions[j], base::string16(suggestions[j])); + } + } +}
diff --git a/components/spellcheck/renderer/spellcheck_provider.cc b/components/spellcheck/renderer/spellcheck_provider.cc new file mode 100644 index 0000000..0787421 --- /dev/null +++ b/components/spellcheck/renderer/spellcheck_provider.cc
@@ -0,0 +1,350 @@ +// 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/spellcheck/renderer/spellcheck_provider.h" + +#include "base/command_line.h" +#include "base/metrics/histogram.h" +#include "components/spellcheck/common/spellcheck_marker.h" +#include "components/spellcheck/common/spellcheck_messages.h" +#include "components/spellcheck/common/spellcheck_result.h" +#include "components/spellcheck/renderer/spellcheck.h" +#include "components/spellcheck/renderer/spellcheck_language.h" +#include "content/public/renderer/render_view.h" +#include "third_party/WebKit/public/platform/WebVector.h" +#include "third_party/WebKit/public/web/WebDocument.h" +#include "third_party/WebKit/public/web/WebElement.h" +#include "third_party/WebKit/public/web/WebLocalFrame.h" +#include "third_party/WebKit/public/web/WebTextCheckingCompletion.h" +#include "third_party/WebKit/public/web/WebTextCheckingResult.h" +#include "third_party/WebKit/public/web/WebTextDecorationType.h" +#include "third_party/WebKit/public/web/WebView.h" + +using blink::WebElement; +using blink::WebLocalFrame; +using blink::WebString; +using blink::WebTextCheckingCompletion; +using blink::WebTextCheckingResult; +using blink::WebTextDecorationType; +using blink::WebVector; + +static_assert(int(blink::WebTextDecorationTypeSpelling) == + int(SpellCheckResult::SPELLING), "mismatching enums"); +static_assert(int(blink::WebTextDecorationTypeGrammar) == + int(SpellCheckResult::GRAMMAR), "mismatching enums"); +static_assert(int(blink::WebTextDecorationTypeInvisibleSpellcheck) == + int(SpellCheckResult::INVISIBLE), "mismatching enums"); + +SpellCheckProvider::SpellCheckProvider( + content::RenderView* render_view, + SpellCheck* spellcheck) + : content::RenderViewObserver(render_view), + content::RenderViewObserverTracker<SpellCheckProvider>(render_view), + spelling_panel_visible_(false), + spellcheck_(spellcheck) { + DCHECK(spellcheck_); + if (render_view) { // NULL in unit tests. + render_view->GetWebView()->setSpellCheckClient(this); + EnableSpellcheck(spellcheck_->IsSpellcheckEnabled()); + } +} + +SpellCheckProvider::~SpellCheckProvider() { +} + +void SpellCheckProvider::RequestTextChecking( + const base::string16& text, + WebTextCheckingCompletion* completion, + const std::vector<SpellCheckMarker>& markers) { + // Ignore invalid requests. + if (text.empty() || !HasWordCharacters(text, 0)) { + completion->didCancelCheckingText(); + return; + } + + // Try to satisfy check from cache. + if (SatisfyRequestFromCache(text, completion)) + return; + + // Send this text to a browser. A browser checks the user profile and send + // this text to the Spelling service only if a user enables this feature. + last_request_.clear(); + last_results_.assign(blink::WebVector<blink::WebTextCheckingResult>()); + +#if defined(USE_BROWSER_SPELLCHECKER) + // Text check (unified request for grammar and spell check) is only + // available for browser process, so we ask the system spellchecker + // over IPC or return an empty result if the checker is not + // available. + Send(new SpellCheckHostMsg_RequestTextCheck( + routing_id(), + text_check_completions_.Add(completion), + text, + markers)); +#else + Send(new SpellCheckHostMsg_CallSpellingService( + routing_id(), + text_check_completions_.Add(completion), + base::string16(text), + markers)); +#endif // !USE_BROWSER_SPELLCHECKER +} + +bool SpellCheckProvider::OnMessageReceived(const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(SpellCheckProvider, message) +#if !defined(USE_BROWSER_SPELLCHECKER) + IPC_MESSAGE_HANDLER(SpellCheckMsg_RespondSpellingService, + OnRespondSpellingService) +#endif +#if defined(USE_BROWSER_SPELLCHECKER) + IPC_MESSAGE_HANDLER(SpellCheckMsg_AdvanceToNextMisspelling, + OnAdvanceToNextMisspelling) + IPC_MESSAGE_HANDLER(SpellCheckMsg_RespondTextCheck, OnRespondTextCheck) + IPC_MESSAGE_HANDLER(SpellCheckMsg_ToggleSpellPanel, OnToggleSpellPanel) +#endif + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void SpellCheckProvider::FocusedNodeChanged(const blink::WebNode& unused) { +#if defined(USE_BROWSER_SPELLCHECKER) + WebLocalFrame* frame = render_view()->GetWebView()->focusedFrame(); + WebElement element = frame->document().isNull() ? WebElement() : + frame->document().focusedElement(); + bool enabled = !element.isNull() && element.isEditable(); + bool checked = enabled && frame->isContinuousSpellCheckingEnabled(); + + Send(new SpellCheckHostMsg_ToggleSpellCheck(routing_id(), enabled, checked)); +#endif // USE_BROWSER_SPELLCHECKER +} + +void SpellCheckProvider::spellCheck( + const WebString& text, + int& offset, + int& length, + WebVector<WebString>* optional_suggestions) { + base::string16 word(text); + std::vector<base::string16> suggestions; + const int kWordStart = 0; + spellcheck_->SpellCheckWord( + word.c_str(), kWordStart, word.size(), routing_id(), + &offset, &length, optional_suggestions ? & suggestions : NULL); + if (optional_suggestions) { + *optional_suggestions = suggestions; + UMA_HISTOGRAM_COUNTS("SpellCheck.api.check.suggestions", word.size()); + } else { + UMA_HISTOGRAM_COUNTS("SpellCheck.api.check", word.size()); + // If optional_suggestions is not requested, the API is called + // for marking. So we use this for counting markable words. + Send(new SpellCheckHostMsg_NotifyChecked(routing_id(), word, 0 < length)); + } +} + +void SpellCheckProvider::requestCheckingOfText( + const WebString& text, + const WebVector<uint32_t>& markers, + const WebVector<unsigned>& marker_offsets, + WebTextCheckingCompletion* completion) { + std::vector<SpellCheckMarker> spellcheck_markers; + for (size_t i = 0; i < markers.size(); ++i) { + spellcheck_markers.push_back( + SpellCheckMarker(markers[i], marker_offsets[i])); + } + RequestTextChecking(text, completion, spellcheck_markers); + UMA_HISTOGRAM_COUNTS("SpellCheck.api.async", text.length()); +} + +void SpellCheckProvider::cancelAllPendingRequests() { + for (WebTextCheckCompletions::iterator iter(&text_check_completions_); + !iter.IsAtEnd(); iter.Advance()) { + iter.GetCurrentValue()->didCancelCheckingText(); + } + text_check_completions_.Clear(); +} + +void SpellCheckProvider::showSpellingUI(bool show) { +#if defined(USE_BROWSER_SPELLCHECKER) + UMA_HISTOGRAM_BOOLEAN("SpellCheck.api.showUI", show); + Send(new SpellCheckHostMsg_ShowSpellingPanel(routing_id(), show)); +#endif +} + +bool SpellCheckProvider::isShowingSpellingUI() { + return spelling_panel_visible_; +} + +void SpellCheckProvider::updateSpellingUIWithMisspelledWord( + const WebString& word) { +#if defined(USE_BROWSER_SPELLCHECKER) + Send(new SpellCheckHostMsg_UpdateSpellingPanelWithMisspelledWord(routing_id(), + word)); +#endif +} + +#if !defined(USE_BROWSER_SPELLCHECKER) +void SpellCheckProvider::OnRespondSpellingService( + int identifier, + bool succeeded, + const base::string16& line, + const std::vector<SpellCheckResult>& results) { + WebTextCheckingCompletion* completion = + text_check_completions_.Lookup(identifier); + if (!completion) + return; + text_check_completions_.Remove(identifier); + + // If |succeeded| is false, we use local spellcheck as a fallback. + if (!succeeded) { + spellcheck_->RequestTextChecking(line, completion); + return; + } + + // Double-check the returned spellchecking results with our spellchecker to + // visualize the differences between ours and the on-line spellchecker. + blink::WebVector<blink::WebTextCheckingResult> textcheck_results; + spellcheck_->CreateTextCheckingResults(SpellCheck::USE_NATIVE_CHECKER, + 0, + line, + results, + &textcheck_results); + completion->didFinishCheckingText(textcheck_results); + + // Cache the request and the converted results. + last_request_ = line; + last_results_.swap(textcheck_results); +} +#endif + +bool SpellCheckProvider::HasWordCharacters( + const base::string16& text, + int index) const { + const base::char16* data = text.data(); + int length = text.length(); + while (index < length) { + uint32_t code = 0; + U16_NEXT(data, index, length, code); + UErrorCode error = U_ZERO_ERROR; + if (uscript_getScript(code, &error) != USCRIPT_COMMON) + return true; + } + return false; +} + +#if defined(USE_BROWSER_SPELLCHECKER) +void SpellCheckProvider::OnAdvanceToNextMisspelling() { + if (!render_view()->GetWebView()) + return; + render_view()->GetWebView()->focusedFrame()->executeCommand( + WebString::fromUTF8("AdvanceToNextMisspelling")); +} + +void SpellCheckProvider::OnRespondTextCheck( + int identifier, + const base::string16& line, + const std::vector<SpellCheckResult>& results) { + // TODO(groby): Unify with SpellCheckProvider::OnRespondSpellingService + DCHECK(spellcheck_); + WebTextCheckingCompletion* completion = + text_check_completions_.Lookup(identifier); + if (!completion) + return; + text_check_completions_.Remove(identifier); + blink::WebVector<blink::WebTextCheckingResult> textcheck_results; + spellcheck_->CreateTextCheckingResults(SpellCheck::DO_NOT_MODIFY, + 0, + line, + results, + &textcheck_results); + completion->didFinishCheckingText(textcheck_results); + + // TODO(groby): Add request caching once OSX reports back original request. + // (cf. SpellCheckProvider::OnRespondSpellingService) + // Cache the request and the converted results. +} + +void SpellCheckProvider::OnToggleSpellPanel(bool is_currently_visible) { + if (!render_view()->GetWebView()) + return; + // We need to tell the webView whether the spelling panel is visible or not so + // that it won't need to make ipc calls later. + spelling_panel_visible_ = is_currently_visible; + render_view()->GetWebView()->focusedFrame()->executeCommand( + WebString::fromUTF8("ToggleSpellPanel")); +} +#endif + +void SpellCheckProvider::EnableSpellcheck(bool enable) { + if (!render_view()->GetWebView()) + return; + + WebLocalFrame* frame = render_view()->GetWebView()->focusedFrame(); + // TODO(yabinh): The null check should be unnecessary. + // See crbug.com/625068 + if (!frame) + return; + + frame->enableContinuousSpellChecking(enable); + if (!enable) + frame->removeSpellingMarkers(); +} + +bool SpellCheckProvider::SatisfyRequestFromCache( + const base::string16& text, + WebTextCheckingCompletion* completion) { + size_t last_length = last_request_.length(); + + // Send back the |last_results_| if the |last_request_| is a substring of + // |text| and |text| does not have more words to check. Provider cannot cancel + // the spellcheck request here, because WebKit might have discarded the + // previous spellcheck results and erased the spelling markers in response to + // the user editing the text. + base::string16 request(text); + size_t text_length = request.length(); + if (text_length >= last_length && + !request.compare(0, last_length, last_request_)) { + if (text_length == last_length || !HasWordCharacters(text, last_length)) { + completion->didFinishCheckingText(last_results_); + return true; + } + int code = 0; + int length = static_cast<int>(text_length); + U16_PREV(text.data(), 0, length, code); + UErrorCode error = U_ZERO_ERROR; + if (uscript_getScript(code, &error) != USCRIPT_COMMON) { + completion->didCancelCheckingText(); + return true; + } + } + // Create a subset of the cached results and return it if the given text is a + // substring of the cached text. + if (text_length < last_length && + !last_request_.compare(0, text_length, request)) { + size_t result_size = 0; + for (size_t i = 0; i < last_results_.size(); ++i) { + size_t start = last_results_[i].location; + size_t end = start + last_results_[i].length; + if (start <= text_length && end <= text_length) + ++result_size; + } + if (result_size > 0) { + blink::WebVector<blink::WebTextCheckingResult> results(result_size); + for (size_t i = 0; i < result_size; ++i) { + results[i].decoration = last_results_[i].decoration; + results[i].location = last_results_[i].location; + results[i].length = last_results_[i].length; + results[i].replacement = last_results_[i].replacement; + } + completion->didFinishCheckingText(results); + return true; + } + } + + return false; +} + +void SpellCheckProvider::OnDestruct() { + delete this; +}
diff --git a/components/spellcheck/renderer/spellcheck_provider.h b/components/spellcheck/renderer/spellcheck_provider.h new file mode 100644 index 0000000..46e1606 --- /dev/null +++ b/components/spellcheck/renderer/spellcheck_provider.h
@@ -0,0 +1,134 @@ +// 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 COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_PROVIDER_H_ +#define COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_PROVIDER_H_ + +#include <stddef.h> +#include <stdint.h> + +#include <vector> + +#include "base/id_map.h" +#include "base/macros.h" +#include "content/public/renderer/render_view_observer.h" +#include "content/public/renderer/render_view_observer_tracker.h" +#include "third_party/WebKit/public/web/WebSpellCheckClient.h" + +class RenderView; +class SpellCheck; +class SpellCheckMarker; +struct SpellCheckResult; + +namespace blink { +class WebString; +class WebTextCheckingCompletion; +struct WebTextCheckingResult; +} + +// This class deals with invoking browser-side spellcheck mechanism +// which is done asynchronously. +class SpellCheckProvider + : public content::RenderViewObserver, + public content::RenderViewObserverTracker<SpellCheckProvider>, + public blink::WebSpellCheckClient { + public: + typedef IDMap<blink::WebTextCheckingCompletion> WebTextCheckCompletions; + + SpellCheckProvider(content::RenderView* render_view, + SpellCheck* spellcheck); + ~SpellCheckProvider() override; + + // Requests async spell and grammar checker to the platform text + // checker, which is available on the browser process. + void RequestTextChecking( + const base::string16& text, + blink::WebTextCheckingCompletion* completion, + const std::vector<SpellCheckMarker>& markers); + + // The number of ongoing IPC requests. + size_t pending_text_request_size() const { + return text_check_completions_.size(); + } + + // Replace shared spellcheck data. + void set_spellcheck(SpellCheck* spellcheck) { spellcheck_ = spellcheck; } + + // Enables document-wide spellchecking. + void EnableSpellcheck(bool enabled); + + // RenderViewObserver implementation. + bool OnMessageReceived(const IPC::Message& message) override; + void FocusedNodeChanged(const blink::WebNode& node) override; + + private: + friend class TestingSpellCheckProvider; + + // Tries to satisfy a spell check request from the cache in |last_request_|. + // Returns true (and cancels/finishes the completion) if it can, false + // if the provider should forward the query on. + bool SatisfyRequestFromCache(const base::string16& text, + blink::WebTextCheckingCompletion* completion); + + // RenderViewObserver implementation. + void OnDestruct() override; + + // blink::WebSpellCheckClient implementation. + void spellCheck( + const blink::WebString& text, + int& offset, + int& length, + blink::WebVector<blink::WebString>* optional_suggestions) override; + + void requestCheckingOfText( + const blink::WebString& text, + const blink::WebVector<uint32_t>& markers, + const blink::WebVector<unsigned>& marker_offsets, + blink::WebTextCheckingCompletion* completion) override; + + void cancelAllPendingRequests() override; + void showSpellingUI(bool show) override; + bool isShowingSpellingUI() override; + void updateSpellingUIWithMisspelledWord( + const blink::WebString& word) override; + +#if !defined(USE_BROWSER_SPELLCHECKER) + void OnRespondSpellingService( + int identifier, + bool succeeded, + const base::string16& text, + const std::vector<SpellCheckResult>& results); +#endif + + // Returns whether |text| has word characters, i.e. whether a spellchecker + // needs to check this text. + bool HasWordCharacters(const base::string16& text, int index) const; + +#if defined(USE_BROWSER_SPELLCHECKER) + void OnAdvanceToNextMisspelling(); + void OnRespondTextCheck( + int identifier, + const base::string16& line, + const std::vector<SpellCheckResult>& results); + void OnToggleSpellPanel(bool is_currently_visible); +#endif + + // Holds ongoing spellchecking operations, assigns IDs for the IPC routing. + WebTextCheckCompletions text_check_completions_; + + // The last text sent to the browser process to spellcheck it and its + // spellchecking results. + base::string16 last_request_; + blink::WebVector<blink::WebTextCheckingResult> last_results_; + + // True if the browser is showing the spelling panel for us. + bool spelling_panel_visible_; + + // Weak pointer to shared (per RenderView) spellcheck data. + SpellCheck* spellcheck_; + + DISALLOW_COPY_AND_ASSIGN(SpellCheckProvider); +}; + +#endif // COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_PROVIDER_H_
diff --git a/components/spellcheck/renderer/spellcheck_provider_hunspell_unittest.cc b/components/spellcheck/renderer/spellcheck_provider_hunspell_unittest.cc new file mode 100644 index 0000000..84022a0 --- /dev/null +++ b/components/spellcheck/renderer/spellcheck_provider_hunspell_unittest.cc
@@ -0,0 +1,183 @@ +// 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 <vector> + +#include "base/stl_util.h" +#include "base/strings/utf_string_conversions.h" +#include "components/spellcheck/common/spellcheck_marker.h" +#include "components/spellcheck/renderer/spellcheck_provider_test.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/public/platform/WebString.h" + +// Tests for Hunspell functionality in SpellcheckingProvider + +using base::ASCIIToUTF16; +using base::WideToUTF16; + +namespace { + +TEST_F(SpellCheckProviderTest, UsingHunspell) { + FakeTextCheckingCompletion completion; + provider_.RequestTextChecking(blink::WebString("hello"), + &completion, + std::vector<SpellCheckMarker>()); + EXPECT_EQ(completion.completion_count_, 1U); + EXPECT_EQ(provider_.messages_.size(), 0U); + EXPECT_EQ(provider_.pending_text_request_size(), 0U); +} + +// Tests that the SpellCheckProvider object sends a spellcheck request when a +// user finishes typing a word. Also this test verifies that this object checks +// only a line being edited by the user. +TEST_F(SpellCheckProviderTest, MultiLineText) { + FakeTextCheckingCompletion completion; + + // Verify that the SpellCheckProvider class does not spellcheck empty text. + provider_.ResetResult(); + provider_.RequestTextChecking( + blink::WebString(), &completion, std::vector<SpellCheckMarker>()); + EXPECT_TRUE(provider_.text_.empty()); + + // Verify that the SpellCheckProvider class does not spellcheck text while we + // are typing a word. + provider_.ResetResult(); + provider_.RequestTextChecking( + blink::WebString("First"), &completion, std::vector<SpellCheckMarker>()); + EXPECT_TRUE(provider_.text_.empty()); + + // Verify that the SpellCheckProvider class spellcheck the first word when we + // type a space key, i.e. when we finish typing a word. + provider_.ResetResult(); + provider_.RequestTextChecking(blink::WebString("First "), + &completion, + std::vector<SpellCheckMarker>()); + EXPECT_EQ(ASCIIToUTF16("First "), provider_.text_); + + // Verify that the SpellCheckProvider class spellcheck the first line when we + // type a return key, i.e. when we finish typing a line. + provider_.ResetResult(); + provider_.RequestTextChecking(blink::WebString("First Second\n"), + &completion, + std::vector<SpellCheckMarker>()); + EXPECT_EQ(ASCIIToUTF16("First Second\n"), provider_.text_); + + // Verify that the SpellCheckProvider class spellcheck the lines when we + // finish typing a word "Third" to the second line. + provider_.ResetResult(); + provider_.RequestTextChecking(blink::WebString("First Second\nThird "), + &completion, + std::vector<SpellCheckMarker>()); + EXPECT_EQ(ASCIIToUTF16("First Second\nThird "), provider_.text_); + + // Verify that the SpellCheckProvider class does not send a spellcheck request + // when a user inserts whitespace characters. + provider_.ResetResult(); + provider_.RequestTextChecking(blink::WebString("First Second\nThird "), + &completion, + std::vector<SpellCheckMarker>()); + EXPECT_TRUE(provider_.text_.empty()); + + // Verify that the SpellCheckProvider class spellcheck the lines when we type + // a period. + provider_.ResetResult(); + provider_.RequestTextChecking( + blink::WebString("First Second\nThird Fourth."), + &completion, + std::vector<SpellCheckMarker>()); + EXPECT_EQ(ASCIIToUTF16("First Second\nThird Fourth."), provider_.text_); +} + +// Tests that the SpellCheckProvider class does not send requests to the +// spelling service when not necessary. +TEST_F(SpellCheckProviderTest, CancelUnnecessaryRequests) { + FakeTextCheckingCompletion completion; + provider_.RequestTextChecking(blink::WebString("hello."), + &completion, + std::vector<SpellCheckMarker>()); + EXPECT_EQ(completion.completion_count_, 1U); + EXPECT_EQ(completion.cancellation_count_, 0U); + EXPECT_EQ(provider_.spelling_service_call_count_, 1U); + + // Test that the SpellCheckProvider does not send a request with the same text + // as above. + provider_.RequestTextChecking(blink::WebString("hello."), + &completion, + std::vector<SpellCheckMarker>()); + EXPECT_EQ(completion.completion_count_, 2U); + EXPECT_EQ(completion.cancellation_count_, 0U); + EXPECT_EQ(provider_.spelling_service_call_count_, 1U); + + // Test that the SpellCheckProvider class cancels an incoming request that + // does not include any words. + provider_.RequestTextChecking(blink::WebString(":-)"), + &completion, + std::vector<SpellCheckMarker>()); + EXPECT_EQ(completion.completion_count_, 3U); + EXPECT_EQ(completion.cancellation_count_, 1U); + EXPECT_EQ(provider_.spelling_service_call_count_, 1U); + + // Test that the SpellCheckProvider class sends a request when it receives a + // Russian word. + const wchar_t kRussianWord[] = L"\x0431\x0451\x0434\x0440\x0430"; + provider_.RequestTextChecking(blink::WebString(WideToUTF16(kRussianWord)), + &completion, + std::vector<SpellCheckMarker>()); + EXPECT_EQ(completion.completion_count_, 4U); + EXPECT_EQ(completion.cancellation_count_, 1U); + EXPECT_EQ(provider_.spelling_service_call_count_, 2U); +} + +// Tests that the SpellCheckProvider calls didFinishCheckingText() when +// necessary. +TEST_F(SpellCheckProviderTest, CompleteNecessaryRequests) { + FakeTextCheckingCompletion completion; + + base::string16 text = ASCIIToUTF16("Icland is an icland "); + provider_.RequestTextChecking( + blink::WebString(text), &completion, std::vector<SpellCheckMarker>()); + EXPECT_EQ(0U, completion.cancellation_count_) << "Should finish checking \"" + << text << "\""; + + const int kSubstringLength = 18; + base::string16 substring = text.substr(0, kSubstringLength); + provider_.RequestTextChecking(blink::WebString(substring), + &completion, + std::vector<SpellCheckMarker>()); + EXPECT_EQ(0U, completion.cancellation_count_) << "Should finish checking \"" + << substring << "\""; + + provider_.RequestTextChecking( + blink::WebString(text), &completion, std::vector<SpellCheckMarker>()); + EXPECT_EQ(0U, completion.cancellation_count_) << "Should finish checking \"" + << text << "\""; +} + +// Tests that the SpellCheckProvider cancels spelling requests in the middle of +// a word. +TEST_F(SpellCheckProviderTest, CancelMidWordRequests) { + FakeTextCheckingCompletion completion; + provider_.RequestTextChecking(blink::WebString("hello "), + &completion, + std::vector<SpellCheckMarker>()); + EXPECT_EQ(completion.completion_count_, 1U); + EXPECT_EQ(completion.cancellation_count_, 0U); + EXPECT_EQ(provider_.spelling_service_call_count_, 1U); + + provider_.RequestTextChecking(blink::WebString("hello world"), + &completion, + std::vector<SpellCheckMarker>()); + EXPECT_EQ(completion.completion_count_, 2U); + EXPECT_EQ(completion.cancellation_count_, 1U); + EXPECT_EQ(provider_.spelling_service_call_count_, 1U); + + provider_.RequestTextChecking(blink::WebString("hello world."), + &completion, + std::vector<SpellCheckMarker>()); + EXPECT_EQ(completion.completion_count_, 3U); + EXPECT_EQ(completion.cancellation_count_, 1U); + EXPECT_EQ(provider_.spelling_service_call_count_, 2U); +} + +} // namespace
diff --git a/components/spellcheck/renderer/spellcheck_provider_mac_unittest.cc b/components/spellcheck/renderer/spellcheck_provider_mac_unittest.cc new file mode 100644 index 0000000..1440313 --- /dev/null +++ b/components/spellcheck/renderer/spellcheck_provider_mac_unittest.cc
@@ -0,0 +1,92 @@ +// 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 <tuple> +#include <vector> + +#include "base/strings/utf_string_conversions.h" +#include "components/spellcheck/common/spellcheck_marker.h" +#include "components/spellcheck/common/spellcheck_messages.h" +#include "components/spellcheck/common/spellcheck_result.h" +#include "components/spellcheck/renderer/spellcheck_provider_test.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/public/platform/WebString.h" + +namespace { + +class SpellCheckProviderMacTest : public SpellCheckProviderTest {}; + +void FakeMessageArrival( + SpellCheckProvider* provider, + const SpellCheckHostMsg_RequestTextCheck::Param& parameters) { + std::vector<SpellCheckResult> fake_result; + bool handled = provider->OnMessageReceived( + SpellCheckMsg_RespondTextCheck( + 0, + std::get<1>(parameters), + base::ASCIIToUTF16("test"), + fake_result)); + EXPECT_TRUE(handled); +} + +TEST_F(SpellCheckProviderMacTest, SingleRoundtripSuccess) { + FakeTextCheckingCompletion completion; + + provider_.RequestTextChecking(blink::WebString("hello "), + &completion, + std::vector<SpellCheckMarker>()); + EXPECT_EQ(completion.completion_count_, 0U); + EXPECT_EQ(provider_.messages_.size(), 1U); + EXPECT_EQ(provider_.pending_text_request_size(), 1U); + + SpellCheckHostMsg_RequestTextCheck::Param read_parameters1; + bool ok = SpellCheckHostMsg_RequestTextCheck::Read( + provider_.messages_[0], &read_parameters1); + EXPECT_TRUE(ok); + EXPECT_EQ(std::get<2>(read_parameters1), base::UTF8ToUTF16("hello ")); + + FakeMessageArrival(&provider_, read_parameters1); + EXPECT_EQ(completion.completion_count_, 1U); + EXPECT_EQ(provider_.pending_text_request_size(), 0U); +} + +TEST_F(SpellCheckProviderMacTest, TwoRoundtripSuccess) { + FakeTextCheckingCompletion completion1; + provider_.RequestTextChecking(blink::WebString("hello "), + &completion1, + std::vector<SpellCheckMarker>()); + FakeTextCheckingCompletion completion2; + provider_.RequestTextChecking(blink::WebString("bye "), + &completion2, + std::vector<SpellCheckMarker>()); + + EXPECT_EQ(completion1.completion_count_, 0U); + EXPECT_EQ(completion2.completion_count_, 0U); + EXPECT_EQ(provider_.messages_.size(), 2U); + EXPECT_EQ(provider_.pending_text_request_size(), 2U); + + SpellCheckHostMsg_RequestTextCheck::Param read_parameters1; + bool ok = SpellCheckHostMsg_RequestTextCheck::Read( + provider_.messages_[0], &read_parameters1); + EXPECT_TRUE(ok); + EXPECT_EQ(std::get<2>(read_parameters1), base::UTF8ToUTF16("hello ")); + + SpellCheckHostMsg_RequestTextCheck::Param read_parameters2; + ok = SpellCheckHostMsg_RequestTextCheck::Read( + provider_.messages_[1], &read_parameters2); + EXPECT_TRUE(ok); + EXPECT_EQ(std::get<2>(read_parameters2), base::UTF8ToUTF16("bye ")); + + FakeMessageArrival(&provider_, read_parameters1); + EXPECT_EQ(completion1.completion_count_, 1U); + EXPECT_EQ(completion2.completion_count_, 0U); + EXPECT_EQ(provider_.pending_text_request_size(), 1U); + + FakeMessageArrival(&provider_, read_parameters2); + EXPECT_EQ(completion1.completion_count_, 1U); + EXPECT_EQ(completion2.completion_count_, 1U); + EXPECT_EQ(provider_.pending_text_request_size(), 0U); +} + +} // namespace
diff --git a/components/spellcheck/renderer/spellcheck_provider_test.cc b/components/spellcheck/renderer/spellcheck_provider_test.cc new file mode 100644 index 0000000..71a6c6d --- /dev/null +++ b/components/spellcheck/renderer/spellcheck_provider_test.cc
@@ -0,0 +1,100 @@ +// 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/spellcheck/renderer/spellcheck_provider_test.h" + +#include "base/stl_util.h" +#include "components/spellcheck/common/spellcheck_marker.h" +#include "components/spellcheck/common/spellcheck_messages.h" +#include "components/spellcheck/renderer/spellcheck.h" +#include "ipc/ipc_message_macros.h" + +class MockSpellcheck: public SpellCheck { +}; + +FakeTextCheckingCompletion::FakeTextCheckingCompletion() +: completion_count_(0), + cancellation_count_(0) { +} + +FakeTextCheckingCompletion::~FakeTextCheckingCompletion() {} + +void FakeTextCheckingCompletion::didFinishCheckingText( + const blink::WebVector<blink::WebTextCheckingResult>& results) { + ++completion_count_; +} + +void FakeTextCheckingCompletion::didCancelCheckingText() { + ++completion_count_; + ++cancellation_count_; +} + +TestingSpellCheckProvider::TestingSpellCheckProvider() + : SpellCheckProvider(NULL, new MockSpellcheck), + spelling_service_call_count_(0) { +} + +TestingSpellCheckProvider::TestingSpellCheckProvider( + SpellCheck* spellcheck) + : SpellCheckProvider(nullptr, spellcheck), + spelling_service_call_count_(0) { +} + +TestingSpellCheckProvider::~TestingSpellCheckProvider() { + delete spellcheck_; +} + +bool TestingSpellCheckProvider::Send(IPC::Message* message) { +#if !defined(USE_BROWSER_SPELLCHECKER) + // Call our mock message handlers. + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(TestingSpellCheckProvider, *message) + IPC_MESSAGE_HANDLER(SpellCheckHostMsg_CallSpellingService, + OnCallSpellingService) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + + if (handled) { + delete message; + return true; + } +#endif + + messages_.push_back(message); + return true; +} + +void TestingSpellCheckProvider::OnCallSpellingService(int route_id, + int identifier, + const base::string16& text, + const std::vector<SpellCheckMarker>& markers) { +#if defined (USE_BROWSER_SPELLCHECKER) + NOTREACHED(); +#else + ++spelling_service_call_count_; + blink::WebTextCheckingCompletion* completion = + text_check_completions_.Lookup(identifier); + if (!completion) { + ResetResult(); + return; + } + text_.assign(text); + text_check_completions_.Remove(identifier); + std::vector<blink::WebTextCheckingResult> results; + results.push_back(blink::WebTextCheckingResult( + blink::WebTextDecorationTypeSpelling, + 0, 5, blink::WebString("hello"))); + completion->didFinishCheckingText(results); + last_request_ = text; + last_results_ = results; +#endif +} + +void TestingSpellCheckProvider::ResetResult() { + text_.clear(); +} + +SpellCheckProviderTest::SpellCheckProviderTest() {} +SpellCheckProviderTest::~SpellCheckProviderTest() {} +
diff --git a/components/spellcheck/renderer/spellcheck_provider_test.h b/components/spellcheck/renderer/spellcheck_provider_test.h new file mode 100644 index 0000000..3ef9d96 --- /dev/null +++ b/components/spellcheck/renderer/spellcheck_provider_test.h
@@ -0,0 +1,68 @@ +// 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 COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_PROVIDER_TEST_H_ +#define COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_PROVIDER_TEST_H_ + +#include <stddef.h> + +#include <vector> + +#include "base/memory/scoped_vector.h" +#include "base/strings/string16.h" +#include "components/spellcheck/renderer/spellcheck_provider.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/public/platform/WebVector.h" +#include "third_party/WebKit/public/web/WebTextCheckingCompletion.h" +#include "third_party/WebKit/public/web/WebTextCheckingResult.h" + +namespace IPC { + class Message; +} + +// A fake completion object for verification. +class FakeTextCheckingCompletion : public blink::WebTextCheckingCompletion { + public: + FakeTextCheckingCompletion(); + ~FakeTextCheckingCompletion(); + + void didFinishCheckingText( + const blink::WebVector<blink::WebTextCheckingResult>& results) override; + void didCancelCheckingText() override; + + size_t completion_count_; + size_t cancellation_count_; +}; + +// Faked test target, which stores sent message for verification. +class TestingSpellCheckProvider : public SpellCheckProvider { + public: + TestingSpellCheckProvider(); + // Takes ownership of |spellcheck|. + explicit TestingSpellCheckProvider(SpellCheck* spellcheck); + + ~TestingSpellCheckProvider() override; + bool Send(IPC::Message* message) override; + void OnCallSpellingService(int route_id, + int identifier, + const base::string16& text, + const std::vector<SpellCheckMarker>& markers); + void ResetResult(); + + base::string16 text_; + ScopedVector<IPC::Message> messages_; + size_t spelling_service_call_count_; +}; + +// SpellCheckProvider test fixture. +class SpellCheckProviderTest : public testing::Test { + public: + SpellCheckProviderTest(); + ~SpellCheckProviderTest() override; + + protected: + TestingSpellCheckProvider provider_; +}; + +#endif // COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_PROVIDER_TEST_H_
diff --git a/components/spellcheck/renderer/spellcheck_unittest.cc b/components/spellcheck/renderer/spellcheck_unittest.cc new file mode 100644 index 0000000..5d0e6c9 --- /dev/null +++ b/components/spellcheck/renderer/spellcheck_unittest.cc
@@ -0,0 +1,1570 @@ +// 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/spellcheck/renderer/spellcheck.h" + +#include <stddef.h> + +#include <memory> +#include <utility> + +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/macros.h" +#include "base/message_loop/message_loop.h" +#include "base/path_service.h" +#include "base/run_loop.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" +#include "components/spellcheck/common/spellcheck_common.h" +#include "components/spellcheck/common/spellcheck_result.h" +#include "components/spellcheck/renderer/hunspell_engine.h" +#include "components/spellcheck/renderer/spellcheck_language.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/public/platform/WebVector.h" +#include "third_party/WebKit/public/web/WebTextCheckingCompletion.h" +#include "third_party/WebKit/public/web/WebTextCheckingResult.h" + +#define TYPOGRAPHICAL_APOSTROPHE L"\x2019" + +namespace { +const int kNoOffset = 0; +const int kNoTag = 0; + +base::FilePath GetHunspellDirectory() { + base::FilePath hunspell_directory; + if (!PathService::Get(base::DIR_SOURCE_ROOT, &hunspell_directory)) + return base::FilePath(); + + hunspell_directory = hunspell_directory.AppendASCII("third_party"); + hunspell_directory = hunspell_directory.AppendASCII("hunspell_dictionaries"); + return hunspell_directory; +} + +} // namespace + +// TODO(groby): This needs to be a BrowserTest for OSX. +class SpellCheckTest : public testing::Test { + public: + SpellCheckTest() { + ReinitializeSpellCheck("en-US"); + } + + void ReinitializeSpellCheck(const std::string& language) { + spell_check_.reset(new SpellCheck()); + InitializeSpellCheck(language); + } + + void UninitializeSpellCheck() { + spell_check_.reset(new SpellCheck()); + } + + bool InitializeIfNeeded() { + return spell_check()->InitializeIfNeeded(); + } + + void InitializeSpellCheck(const std::string& language) { + base::FilePath hunspell_directory = GetHunspellDirectory(); + EXPECT_FALSE(hunspell_directory.empty()); + base::File file( + spellcheck::GetVersionedFileName(language, hunspell_directory), + base::File::FLAG_OPEN | base::File::FLAG_READ); +#if defined(OS_MACOSX) + // TODO(groby): Forcing spellcheck to use hunspell, even on OSX. + // Instead, tests should exercise individual spelling engines. + spell_check_->languages_.push_back(new SpellcheckLanguage()); + spell_check_->languages_.front()->platform_spelling_engine_.reset( + new HunspellEngine); + spell_check_->languages_.front()->Init(std::move(file), language); +#else + spell_check_->AddSpellcheckLanguage(std::move(file), language); +#endif + } + + ~SpellCheckTest() override {} + + SpellCheck* spell_check() { return spell_check_.get(); } + + bool CheckSpelling(const std::string& word, int tag) { + return spell_check_->languages_.front() + ->platform_spelling_engine_->CheckSpelling(base::ASCIIToUTF16(word), + tag); + } + + bool IsValidContraction(const base::string16& word, int tag) { + return spell_check_->languages_.front()->IsValidContraction(word, tag); + } + + static void FillSuggestions( + const std::vector<std::vector<base::string16>>& suggestions_list, + std::vector<base::string16>* optional_suggestions) { + SpellCheck::FillSuggestions(suggestions_list, optional_suggestions); + } + +#if !defined(OS_MACOSX) + protected: + void TestSpellCheckParagraph( + const base::string16& input, + const std::vector<SpellCheckResult>& expected) { + blink::WebVector<blink::WebTextCheckingResult> results; + spell_check()->SpellCheckParagraph(input, + &results); + + EXPECT_EQ(results.size(), expected.size()); + size_t size = std::min(results.size(), expected.size()); + for (size_t j = 0; j < size; ++j) { + EXPECT_EQ(results[j].decoration, blink::WebTextDecorationTypeSpelling); + EXPECT_EQ(results[j].location, expected[j].location); + EXPECT_EQ(results[j].length, expected[j].length); + } + } +#endif + + private: + std::unique_ptr<SpellCheck> spell_check_; + base::MessageLoop loop; +}; + +// A fake completion object for verification. +class MockTextCheckingCompletion : public blink::WebTextCheckingCompletion { + public: + MockTextCheckingCompletion() + : completion_count_(0) { + } + + void didFinishCheckingText( + const blink::WebVector<blink::WebTextCheckingResult>& results) override { + completion_count_++; + last_results_ = results; + } + + void didCancelCheckingText() override { + completion_count_++; + } + + size_t completion_count_; + blink::WebVector<blink::WebTextCheckingResult> last_results_; +}; + +// Operates unit tests for the content::SpellCheck::SpellCheckWord() function +// with the US English dictionary. +// The unit tests in this function consist of: +// * Tests for the function with empty strings; +// * Tests for the function with a valid English word; +// * Tests for the function with a valid non-English word; +// * Tests for the function with a valid English word with a preceding +// space character; +// * Tests for the function with a valid English word with a preceding +// non-English word; +// * Tests for the function with a valid English word with a following +// space character; +// * Tests for the function with a valid English word with a following +// non-English word; +// * Tests for the function with two valid English words concatenated +// with space characters or non-English words; +// * Tests for the function with an invalid English word; +// * Tests for the function with an invalid English word with a preceding +// space character; +// * Tests for the function with an invalid English word with a preceding +// non-English word; +// * Tests for the function with an invalid English word with a following +// space character; +// * Tests for the function with an invalid English word with a following +// non-English word, and; +// * Tests for the function with two invalid English words concatenated +// with space characters or non-English words. +// A test with a "[ROBUSTNESS]" mark shows it is a robustness test and it uses +// grammatically incorrect string. +// TODO(groby): Please feel free to add more tests. +TEST_F(SpellCheckTest, SpellCheckStrings_EN_US) { + static const struct { + // A string to be tested. + const wchar_t* input; + // An expected result for this test case. + // * true: the input string does not have any invalid words. + // * false: the input string has one or more invalid words. + bool expected_result; + // The position and the length of the first invalid word. + int misspelling_start; + int misspelling_length; + } kTestCases[] = { + // Empty strings. + {L"", true}, + {L" ", true}, + {L"\xA0", true}, + {L"\x3000", true}, + + // A valid English word "hello". + {L"hello", true}, + // A valid Chinese word (meaning "hello") consisting of two CJKV + // ideographs + {L"\x4F60\x597D", true}, + // A valid Korean word (meaning "hello") consisting of five hangul + // syllables + {L"\xC548\xB155\xD558\xC138\xC694", true}, + // A valid Japanese word (meaning "hello") consisting of five Hiragana + // letters + {L"\x3053\x3093\x306B\x3061\x306F", true}, + // A valid Hindi word (meaning ?) consisting of six Devanagari letters + // (This word is copied from "http://b/issue?id=857583".) + {L"\x0930\x093E\x091C\x0927\x093E\x0928", true}, + // A valid English word "affix" using a Latin ligature 'ffi' + {L"a\xFB03x", true}, + // A valid English word "hello" (fullwidth version) + {L"\xFF28\xFF45\xFF4C\xFF4C\xFF4F", true}, + // Two valid Greek words (meaning "hello") consisting of seven Greek + // letters + {L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5", true}, + // A valid Russian word (meaning "hello") consisting of twelve Cyrillic + // letters + {L"\x0437\x0434\x0440\x0430\x0432\x0441" + L"\x0442\x0432\x0443\x0439\x0442\x0435", true}, + // A valid English contraction + {L"isn't", true}, + // A valid English contraction with a typographical apostrophe. + {L"isn" TYPOGRAPHICAL_APOSTROPHE L"t", true}, + // A valid English word enclosed with underscores. + {L"_hello_", true}, + + // A valid English word with a preceding whitespace + {L" " L"hello", true}, + // A valid English word with a preceding no-break space + {L"\xA0" L"hello", true}, + // A valid English word with a preceding ideographic space + {L"\x3000" L"hello", true}, + // A valid English word with a preceding Chinese word + {L"\x4F60\x597D" L"hello", true}, + // [ROBUSTNESS] A valid English word with a preceding Korean word + {L"\xC548\xB155\xD558\xC138\xC694" L"hello", true}, + // A valid English word with a preceding Japanese word + {L"\x3053\x3093\x306B\x3061\x306F" L"hello", true}, + // [ROBUSTNESS] A valid English word with a preceding Hindi word + {L"\x0930\x093E\x091C\x0927\x093E\x0928" L"hello", true}, + // [ROBUSTNESS] A valid English word with two preceding Greek words + {L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5" + L"hello", true}, + // [ROBUSTNESS] A valid English word with a preceding Russian word + {L"\x0437\x0434\x0440\x0430\x0432\x0441" + L"\x0442\x0432\x0443\x0439\x0442\x0435" L"hello", true}, + + // A valid English word with a following whitespace + {L"hello" L" ", true}, + // A valid English word with a following no-break space + {L"hello" L"\xA0", true}, + // A valid English word with a following ideographic space + {L"hello" L"\x3000", true}, + // A valid English word with a following Chinese word + {L"hello" L"\x4F60\x597D", true}, + // [ROBUSTNESS] A valid English word with a following Korean word + {L"hello" L"\xC548\xB155\xD558\xC138\xC694", true}, + // A valid English word with a following Japanese word + {L"hello" L"\x3053\x3093\x306B\x3061\x306F", true}, + // [ROBUSTNESS] A valid English word with a following Hindi word + {L"hello" L"\x0930\x093E\x091C\x0927\x093E\x0928", true}, + // [ROBUSTNESS] A valid English word with two following Greek words + {L"hello" + L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5", true}, + // [ROBUSTNESS] A valid English word with a following Russian word + {L"hello" L"\x0437\x0434\x0440\x0430\x0432\x0441" + L"\x0442\x0432\x0443\x0439\x0442\x0435", true}, + + // Two valid English words concatenated with a whitespace + {L"hello" L" " L"hello", true}, + // Two valid English words concatenated with a no-break space + {L"hello" L"\xA0" L"hello", true}, + // Two valid English words concatenated with an ideographic space + {L"hello" L"\x3000" L"hello", true}, + // Two valid English words concatenated with a Chinese word + {L"hello" L"\x4F60\x597D" L"hello", true}, + // [ROBUSTNESS] Two valid English words concatenated with a Korean word + {L"hello" L"\xC548\xB155\xD558\xC138\xC694" L"hello", true}, + // Two valid English words concatenated with a Japanese word + {L"hello" L"\x3053\x3093\x306B\x3061\x306F" L"hello", true}, + // [ROBUSTNESS] Two valid English words concatenated with a Hindi word + {L"hello" L"\x0930\x093E\x091C\x0927\x093E\x0928" L"hello" , true}, + // [ROBUSTNESS] Two valid English words concatenated with two Greek words + {L"hello" L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5" + L"hello", true}, + // [ROBUSTNESS] Two valid English words concatenated with a Russian word + {L"hello" L"\x0437\x0434\x0440\x0430\x0432\x0441" + L"\x0442\x0432\x0443\x0439\x0442\x0435" L"hello", true}, + // [ROBUSTNESS] Two valid English words concatenated with a contraction + // character. + {L"hello:hello", true}, + + // An invalid English word + {L"ifmmp", false, 0, 5}, + // An invalid English word "bffly" containing a Latin ligature 'ffl' + {L"b\xFB04y", false, 0, 3}, + // An invalid English word "ifmmp" (fullwidth version) + {L"\xFF29\xFF46\xFF4D\xFF4D\xFF50", false, 0, 5}, + // An invalid English contraction + {L"jtm'u", false, 0, 5}, + // An invalid English word enclosed with underscores. + {L"_ifmmp_", false, 1, 5}, + + // An invalid English word with a preceding whitespace + {L" " L"ifmmp", false, 1, 5}, + // An invalid English word with a preceding no-break space + {L"\xA0" L"ifmmp", false, 1, 5}, + // An invalid English word with a preceding ideographic space + {L"\x3000" L"ifmmp", false, 1, 5}, + // An invalid English word with a preceding Chinese word + {L"\x4F60\x597D" L"ifmmp", false, 2, 5}, + // [ROBUSTNESS] An invalid English word with a preceding Korean word + {L"\xC548\xB155\xD558\xC138\xC694" L"ifmmp", false, 5, 5}, + // An invalid English word with a preceding Japanese word + {L"\x3053\x3093\x306B\x3061\x306F" L"ifmmp", false, 5, 5}, + // [ROBUSTNESS] An invalid English word with a preceding Hindi word + {L"\x0930\x093E\x091C\x0927\x093E\x0928" L"ifmmp", false, 6, 5}, + // [ROBUSTNESS] An invalid English word with two preceding Greek words + {L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5" + L"ifmmp", false, 8, 5}, + // [ROBUSTNESS] An invalid English word with a preceding Russian word + {L"\x0437\x0434\x0440\x0430\x0432\x0441" + L"\x0442\x0432\x0443\x0439\x0442\x0435" L"ifmmp", false, 12, 5}, + + // An invalid English word with a following whitespace + {L"ifmmp" L" ", false, 0, 5}, + // An invalid English word with a following no-break space + {L"ifmmp" L"\xA0", false, 0, 5}, + // An invalid English word with a following ideographic space + {L"ifmmp" L"\x3000", false, 0, 5}, + // An invalid English word with a following Chinese word + {L"ifmmp" L"\x4F60\x597D", false, 0, 5}, + // [ROBUSTNESS] An invalid English word with a following Korean word + {L"ifmmp" L"\xC548\xB155\xD558\xC138\xC694", false, 0, 5}, + // An invalid English word with a following Japanese word + {L"ifmmp" L"\x3053\x3093\x306B\x3061\x306F", false, 0, 5}, + // [ROBUSTNESS] An invalid English word with a following Hindi word + {L"ifmmp" L"\x0930\x093E\x091C\x0927\x093E\x0928", false, 0, 5}, + // [ROBUSTNESS] An invalid English word with two following Greek words + {L"ifmmp" + L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5", false, 0, 5}, + // [ROBUSTNESS] An invalid English word with a following Russian word + {L"ifmmp" L"\x0437\x0434\x0440\x0430\x0432\x0441" + L"\x0442\x0432\x0443\x0439\x0442\x0435", false, 0, 5}, + + // Two invalid English words concatenated with a whitespace + {L"ifmmp" L" " L"ifmmp", false, 0, 5}, + // Two invalid English words concatenated with a no-break space + {L"ifmmp" L"\xA0" L"ifmmp", false, 0, 5}, + // Two invalid English words concatenated with an ideographic space + {L"ifmmp" L"\x3000" L"ifmmp", false, 0, 5}, + // Two invalid English words concatenated with a Chinese word + {L"ifmmp" L"\x4F60\x597D" L"ifmmp", false, 0, 5}, + // [ROBUSTNESS] Two invalid English words concatenated with a Korean word + {L"ifmmp" L"\xC548\xB155\xD558\xC138\xC694" L"ifmmp", false, 0, 5}, + // Two invalid English words concatenated with a Japanese word + {L"ifmmp" L"\x3053\x3093\x306B\x3061\x306F" L"ifmmp", false, 0, 5}, + // [ROBUSTNESS] Two invalid English words concatenated with a Hindi word + {L"ifmmp" L"\x0930\x093E\x091C\x0927\x093E\x0928" L"ifmmp" , false, 0, 5}, + // [ROBUSTNESS] Two invalid English words concatenated with two Greek words + {L"ifmmp" L"\x03B3\x03B5\x03B9\x03AC" L" " L"\x03C3\x03BF\x03C5" + L"ifmmp", false, 0, 5}, + // [ROBUSTNESS] Two invalid English words concatenated with a Russian word + {L"ifmmp" L"\x0437\x0434\x0440\x0430\x0432\x0441" + L"\x0442\x0432\x0443\x0439\x0442\x0435" L"ifmmp", false, 0, 5}, + // [ROBUSTNESS] Two invalid English words concatenated with a contraction + // character. + {L"ifmmp:ifmmp", false, 0, 11}, + + // [REGRESSION] Issue 13432: "Any word of 13 or 14 characters is not + // spellcheck" <http://crbug.com/13432>. + {L"qwertyuiopasd", false, 0, 13}, + {L"qwertyuiopasdf", false, 0, 14}, + + // [REGRESSION] Issue 128896: "en_US hunspell dictionary includes + // acknowledgement but not acknowledgements" <http://crbug.com/128896> + {L"acknowledgement", true}, + {L"acknowledgements", true}, + + // Issue 123290: "Spellchecker should treat numbers as word characters" + {L"0th", true}, + {L"1st", true}, + {L"2nd", true}, + {L"3rd", true}, + {L"4th", true}, + {L"5th", true}, + {L"6th", true}, + {L"7th", true}, + {L"8th", true}, + {L"9th", true}, + {L"10th", true}, + {L"100th", true}, + {L"1000th", true}, + {L"25", true}, + {L"2012", true}, + {L"100,000,000", true}, + {L"3.141592653", true}, + }; + + for (size_t i = 0; i < arraysize(kTestCases); ++i) { + size_t input_length = 0; + if (kTestCases[i].input != NULL) { + input_length = wcslen(kTestCases[i].input); + } + int misspelling_start; + int misspelling_length; + bool result = spell_check()->SpellCheckWord( + base::WideToUTF16(kTestCases[i].input).c_str(), + kNoOffset, + static_cast<int>(input_length), + kNoTag, + &misspelling_start, + &misspelling_length, NULL); + + EXPECT_EQ(kTestCases[i].expected_result, result); + EXPECT_EQ(kTestCases[i].misspelling_start, misspelling_start); + EXPECT_EQ(kTestCases[i].misspelling_length, misspelling_length); + } +} + +TEST_F(SpellCheckTest, SpellCheckSuggestions_EN_US) { + static const struct { + // A string to be tested. + const wchar_t* input; + // An expected result for this test case. + // * true: the input string does not have any invalid words. + // * false: the input string has one or more invalid words. + bool expected_result; + // The position and the length of the first invalid word. + int misspelling_start; + int misspelling_length; + + // A suggested word that should occur. + const wchar_t* suggested_word; + } kTestCases[] = { + {L"ello", false, 0, 0, L"hello"}, + {L"ello", false, 0, 0, L"cello"}, + {L"wate", false, 0, 0, L"water"}, + {L"wate", false, 0, 0, L"waste"}, + {L"wate", false, 0, 0, L"sate"}, + {L"wate", false, 0, 0, L"ate"}, + {L"jum", false, 0, 0, L"jump"}, + {L"jum", false, 0, 0, L"hum"}, + {L"jum", false, 0, 0, L"sum"}, + {L"jum", false, 0, 0, L"um"}, + {L"alot", false, 0, 0, L"a lot"}, + // A regression test for Issue 36523. + {L"privliged", false, 0, 0, L"privileged"}, + // TODO (Sidchat): add many more examples. + }; + + for (size_t i = 0; i < arraysize(kTestCases); ++i) { + std::vector<base::string16> suggestions; + size_t input_length = 0; + if (kTestCases[i].input != NULL) { + input_length = wcslen(kTestCases[i].input); + } + int misspelling_start; + int misspelling_length; + bool result = spell_check()->SpellCheckWord( + base::WideToUTF16(kTestCases[i].input).c_str(), + kNoOffset, + static_cast<int>(input_length), + kNoTag, + &misspelling_start, + &misspelling_length, + &suggestions); + + // Check for spelling. + EXPECT_EQ(kTestCases[i].expected_result, result); + + // Check if the suggested words occur. + bool suggested_word_is_present = false; + for (int j = 0; j < static_cast<int>(suggestions.size()); j++) { + if (suggestions.at(j).compare( + base::WideToUTF16(kTestCases[i].suggested_word)) == 0) { + suggested_word_is_present = true; + break; + } + } + + EXPECT_TRUE(suggested_word_is_present); + } +} + +// This test verifies our spellchecker can split a text into words and check +// the spelling of each word in the text. +#if defined(THREAD_SANITIZER) +// SpellCheckTest.SpellCheckText fails under ThreadSanitizer v2. +// See http://crbug.com/217909. +#define MAYBE_SpellCheckText DISABLED_SpellCheckText +#else +#define MAYBE_SpellCheckText SpellCheckText +#endif // THREAD_SANITIZER +TEST_F(SpellCheckTest, MAYBE_SpellCheckText) { + static const struct { + const char* language; + const wchar_t* input; + } kTestCases[] = { + { + // Afrikaans + "af-ZA", + L"Google se missie is om die w\x00EAreld se inligting te organiseer en " + L"dit bruikbaar en toeganklik te maak." + }, { + // Bulgarian + "bg-BG", + L"\x041c\x0438\x0441\x0438\x044f\x0442\x0430 " + L"\x043d\x0430 Google \x0435 \x0434\x0430 \x043e" + L"\x0440\x0433\x0430\x043d\x0438\x0437\x0438\x0440" + L"\x0430 \x0441\x0432\x0435\x0442\x043e\x0432" + L"\x043d\x0430\x0442\x0430 \x0438\x043d\x0444" + L"\x043e\x0440\x043c\x0430\x0446\x0438\x044f " + L"\x0438 \x0434\x0430 \x044f \x043d" + L"\x0430\x043f\x0440\x0430\x0432\x0438 \x0443" + L"\x043d\x0438\x0432\x0435\x0440\x0441\x0430\x043b" + L"\x043d\x043e \x0434\x043e\x0441\x0442\x044a" + L"\x043f\x043d\x0430 \x0438 \x043f\x043e" + L"\x043b\x0435\x0437\x043d\x0430." + }, { + // Catalan + "ca-ES", + L"La missi\x00F3 de Google \x00E9s organitzar la informaci\x00F3 " + L"del m\x00F3n i fer que sigui \x00FAtil i accessible universalment." + }, { + // Czech + "cs-CZ", + L"Posl\x00E1n\x00EDm spole\x010Dnosti Google je " + L"uspo\x0159\x00E1\x0064\x0061t informace z cel\x00E9ho sv\x011Bta " + L"tak, aby byly v\x0161\x0065obecn\x011B p\x0159\x00EDstupn\x00E9 " + L"a u\x017Eite\x010Dn\x00E9." + }, { + // Danish + "da-DK", + L"Googles " + L"mission er at organisere verdens information og g\x00F8re den " + L"almindeligt tilg\x00E6ngelig og nyttig." + }, { + // German + "de-DE", + L"Das Ziel von Google besteht darin, die auf der Welt vorhandenen " + L"Informationen zu organisieren und allgemein zug\x00E4nglich und " + L"nutzbar zu machen." + }, { + // Greek + "el-GR", + L"\x0391\x03C0\x03BF\x03C3\x03C4\x03BF\x03BB\x03AE " + L"\x03C4\x03B7\x03C2 Google \x03B5\x03AF\x03BD\x03B1\x03B9 " + L"\x03BD\x03B1 \x03BF\x03C1\x03B3\x03B1\x03BD\x03CE\x03BD\x03B5\x03B9 " + L"\x03C4\x03B9\x03C2 " + L"\x03C0\x03BB\x03B7\x03C1\x03BF\x03C6\x03BF\x03C1\x03AF\x03B5\x03C2 " + L"\x03C4\x03BF\x03C5 \x03BA\x03CC\x03C3\x03BC\x03BF\x03C5 " + L"\x03BA\x03B1\x03B9 \x03BD\x03B1 \x03C4\x03B9\x03C2 " + L"\x03BA\x03B1\x03B8\x03B9\x03C3\x03C4\x03AC " + L"\x03C0\x03C1\x03BF\x03C3\x03B2\x03AC\x03C3\x03B9\x03BC\x03B5\x03C2 " + L"\x03BA\x03B1\x03B9 \x03C7\x03C1\x03AE\x03C3\x03B9\x03BC\x03B5\x03C2." + }, { + // English (Australia) + "en-AU", + L"Google's mission is to organise the world's information and make it " + L"universally accessible and useful." + }, { + // English (Canada) + "en-CA", + L"Google's mission is to organize the world's information and make it " + L"universally accessible and useful." + }, { + // English (United Kingdom) + "en-GB", + L"Google's mission is to organise the world's information and make it " + L"universally accessible and useful." + }, { + // English (United States) + "en-US", + L"Google's mission is to organize the world's information and make it " + L"universally accessible and useful." + }, { + // Spanish + "es-ES", + L"La misi\x00F3n de " + // L"Google" - to be added. + L" es organizar la informaci\x00F3n mundial " + L"para que resulte universalmente accesible y \x00FAtil." + }, { + // Estonian + "et-EE", + // L"Google'ile " - to be added. + L"\x00FClesanne on korraldada maailma teavet ja teeb selle " + L"k\x00F5igile k\x00E4ttesaadavaks ja kasulikuks.", + }, { + // Persian + "fa", + L"\x0686\x0647 \x0637\x0648\x0631 \x0622\x06cc\x0627 \x0634\x0645\x0627 " + L"\x0627\x06cc\x0631\x0627\x0646\x06cc \x0647\x0633\x062a\x06cc\x062f" + }, { + // Faroese + "fo-FO", + L"Google er at samskipa alla vitan \x00ED heiminum og gera hana alment " + L"atkomiliga og n\x00FDtiliga." + }, { + // French + "fr-FR", + L"Google a pour mission d'organiser les informations \x00E0 " + L"l'\x00E9\x0063helle mondiale dans le but de les rendre accessibles " + L"et utiles \x00E0 tous." + }, { + // Hebrew + "he-IL", + L"\x05D4\x05DE\x05E9\x05D9\x05DE\x05D4 \x05E9\x05DC Google " + L"\x05D4\x05D9\x05D0 \x05DC\x05D0\x05E8\x05D2\x05DF " + L"\x05D0\x05EA \x05D4\x05DE\x05D9\x05D3\x05E2 " + L"\x05D4\x05E2\x05D5\x05DC\x05DE\x05D9 " + L"\x05D5\x05DC\x05D4\x05E4\x05D5\x05DA \x05D0\x05D5\x05EA\x05D5 " + L"\x05DC\x05D6\x05DE\x05D9\x05DF " + L"\x05D5\x05E9\x05D9\x05DE\x05D5\x05E9\x05D9 \x05D1\x05DB\x05DC " + L"\x05D4\x05E2\x05D5\x05DC\x05DD. " + // Two words with ASCII double/single quoation marks. + L"\x05DE\x05E0\x05DB\x0022\x05DC \x05E6\x0027\x05D9\x05E4\x05E1" + }, { + // Hindi + "hi-IN", + L"Google \x0915\x093E \x092E\x093F\x0936\x0928 " + L"\x0926\x0941\x0928\x093F\x092F\x093E \x0915\x0940 " + L"\x091C\x093E\x0928\x0915\x093E\x0930\x0940 \x0915\x094B " + L"\x0935\x094D\x092F\x0935\x0938\x094D\x0925\x093F\x0924 " + L"\x0915\x0930\x0928\x093E \x0914\x0930 \x0909\x0938\x0947 " + L"\x0938\x093E\x0930\x094D\x0935\x092D\x094C\x092E\x093F\x0915 " + L"\x0930\x0942\x092A \x0938\x0947 \x092A\x0939\x0941\x0901\x091A " + L"\x092E\x0947\x0902 \x0914\x0930 \x0909\x092A\x092F\x094B\x0917\x0940 " + L"\x092C\x0928\x093E\x0928\x093E \x0939\x0948." + }, { + // Hungarian + "hu-HU", + L"A Google azt a k\x00FCldet\x00E9st v\x00E1llalta mag\x00E1ra, " + L"hogy a vil\x00E1gon fellelhet\x0151 inform\x00E1\x0063i\x00F3kat " + L"rendszerezze \x00E9s \x00E1ltal\x00E1nosan el\x00E9rhet\x0151v\x00E9, " + L"illetve haszn\x00E1lhat\x00F3v\x00E1 tegye." + }, { + // Croatian + "hr-HR", + // L"Googleova " - to be added. + L"je misija organizirati svjetske informacije i u\x010Diniti ih " + // L"univerzalno " - to be added. + L"pristupa\x010Dnima i korisnima." + }, { + // Indonesian + "id-ID", + L"Misi Google adalah untuk mengelola informasi dunia dan membuatnya " + L"dapat diakses dan bermanfaat secara universal." + }, { + // Italian + "it-IT", + L"La missione di Google \x00E8 organizzare le informazioni a livello " + L"mondiale e renderle universalmente accessibili e fruibili." + }, { + // Lithuanian + "lt-LT", + L"\x201EGoogle\x201C tikslas \x2013 rinkti ir sisteminti pasaulio " + L"informacij\x0105 bei padaryti j\x0105 prieinam\x0105 ir " + L"nauding\x0105 visiems." + }, { + // Latvian + "lv-LV", + L"Google uzdevums ir k\x0101rtot pasaules inform\x0101" + L"ciju un padar\x012Bt to univers\x0101li pieejamu un noder\x012Bgu." + }, { + // Norwegian + "nb-NO", + // L"Googles " - to be added. + L"m\x00E5l er \x00E5 organisere informasjonen i verden og " + L"gj\x00F8re den tilgjengelig og nyttig for alle." + }, { + // Dutch + "nl-NL", + L"Het doel van Google is om alle informatie wereldwijd toegankelijk " + L"en bruikbaar te maken." + }, { + // Polish + "pl-PL", + L"Misj\x0105 Google jest uporz\x0105" L"dkowanie \x015Bwiatowych " + L"zasob\x00F3w informacji, aby sta\x0142y si\x0119 one powszechnie " + L"dost\x0119pne i u\x017Cyteczne." + }, { + // Portuguese (Brazil) + "pt-BR", + L"A miss\x00E3o do " +#if !defined(OS_MACOSX) + L"Google " +#endif + L"\x00E9 organizar as informa\x00E7\x00F5" + L"es do mundo todo e " +#if !defined(OS_MACOSX) + L"torn\x00E1-las " +#endif + L"acess\x00EDveis e \x00FAteis em car\x00E1ter universal." + }, { + // Portuguese (Portugal) + "pt-PT", + L"O " +#if !defined(OS_MACOSX) + L"Google " +#endif + L"tem por miss\x00E3o organizar a informa\x00E7\x00E3o do " + L"mundo e " +#if !defined(OS_MACOSX) + L"torn\x00E1-la " +#endif + L"universalmente acess\x00EDvel e \x00FAtil" + }, { + // Romanian + "ro-RO", + L"Misiunea Google este de a organiza informa\x021B3iile lumii \x0219i de " + L"a le face accesibile \x0219i utile la nivel universal." + }, { + // Russian + "ru-RU", + L"\x041C\x0438\x0441\x0441\x0438\x044F Google " + L"\x0441\x043E\x0441\x0442\x043E\x0438\x0442 \x0432 " + L"\x043E\x0440\x0433\x0430\x043D\x0438\x0437\x0430\x0446\x0438\x0438 " + L"\x043C\x0438\x0440\x043E\x0432\x043E\x0439 " + L"\x0438\x043D\x0444\x043E\x0440\x043C\x0430\x0446\x0438\x0438, " + L"\x043E\x0431\x0435\x0441\x043F\x0435\x0447\x0435\x043D\x0438\x0438 " + L"\x0435\x0435 " + L"\x0434\x043E\x0441\x0442\x0443\x043F\x043D\x043E\x0441\x0442\x0438 " + L"\x0438 \x043F\x043E\x043B\x044C\x0437\x044B \x0434\x043B\x044F " + L"\x0432\x0441\x0435\x0445." + // A Russian word including U+0451. (Bug 15558 <http://crbug.com/15558>) + L"\x0451\x043B\x043A\x0430" + }, { + // Serbo-Croatian (Serbian Latin) + "sh", + L"Google-ova misija je da organizuje sve informacije na svetu i " + L"u\x010dini ih univerzal-no dostupnim i korisnim." + }, { + // Serbian + "sr", + L"\x0047\x006f\x006f\x0067\x006c\x0065\x002d\x043e\x0432\x0430 " + L"\x043c\x0438\x0441\x0438\x0458\x0430 \x0458\x0435 \x0434\x0430 " + L"\x043e\x0440\x0433\x0430\x043d\x0438\x0437\x0443\x0458\x0435 " + L"\x0441\x0432\x0435 " + L"\x0438\x043d\x0444\x043e\x0440\x043c\x0430\x0446\x0438\x0458\x0435 " + L"\x043d\x0430 \x0441\x0432\x0435\x0442\x0443 \x0438 " + L"\x0443\x0447\x0438\x043d\x0438 \x0438\x0445 " + L"\x0443\x043d\x0438\x0432\x0435\x0440\x0437\x0430\x043b\x043d\x043e " + L"\x0434\x043e\x0441\x0442\x0443\x043f\x043d\x0438\x043c \x0438 " + L"\x043a\x043e\x0440\x0438\x0441\x043d\x0438\x043c." + }, { + // Slovak + "sk-SK", + L"Spolo\x010Dnos\x0165 Google si dala za \x00FAlohu usporiada\x0165 " + L"inform\x00E1\x0063ie " + L"z cel\x00E9ho sveta a zabezpe\x010Di\x0165, " + L"aby boli v\x0161eobecne dostupn\x00E9 a u\x017Eito\x010Dn\x00E9." + }, { + // Slovenian + "sl-SI", + // L"Googlovo " - to be added. + L"poslanstvo je organizirati svetovne informacije in " + L"omogo\x010Diti njihovo dostopnost in s tem uporabnost za vse." + }, { + // Swedish + "sv-SE", + L"Googles m\x00E5ls\x00E4ttning \x00E4r att ordna v\x00E4rldens " + L"samlade information och g\x00F6ra den tillg\x00E4nglig f\x00F6r alla." + }, { + // Turkish + "tr-TR", + // L"Google\x2019\x0131n " - to be added. + L"misyonu, d\x00FCnyadaki t\x00FCm bilgileri " + L"organize etmek ve evrensel olarak eri\x015Filebilir ve " + L"kullan\x0131\x015Fl\x0131 k\x0131lmakt\x0131r." + }, { + // Ukranian + "uk-UA", + L"\x041c\x0456\x0441\x0456\x044f " + L"\x043a\x043e\x043c\x043f\x0430\x043d\x0456\x0457 Google " + L"\x043f\x043e\x043b\x044f\x0433\x0430\x0454 \x0432 " + L"\x0442\x043e\x043c\x0443, \x0449\x043e\x0431 " + L"\x0443\x043f\x043e\x0440\x044f\x0434\x043a\x0443\x0432\x0430\x0442" + L"\x0438 \x0456\x043d\x0444\x043e\x0440\x043c\x0430\x0446\x0456\x044e " + L"\x0437 \x0443\x0441\x044c\x043e\x0433\x043e " + L"\x0441\x0432\x0456\x0442\x0443 \x0442\x0430 " + L"\x0437\x0440\x043e\x0431\x0438\x0442\x0438 \x0457\x0457 " + L"\x0443\x043d\x0456\x0432\x0435\x0440\x0441\x0430\x043b\x044c\x043d" + L"\x043e \x0434\x043e\x0441\x0442\x0443\x043f\x043d\x043e\x044e " + L"\x0442\x0430 \x043a\x043e\x0440\x0438\x0441\x043d\x043e\x044e." + }, { + // Vietnamese + "vi-VN", + L"Nhi\x1EC7m v\x1EE5 c\x1EE7\x0061 " + L"Google la \x0111\x1EC3 t\x1ED5 ch\x1EE9\x0063 " + L"c\x00E1\x0063 th\x00F4ng tin c\x1EE7\x0061 " + L"th\x1EBF gi\x1EDBi va l\x00E0m cho n\x00F3 universal c\x00F3 " + L"th\x1EC3 truy c\x1EADp va h\x1EEFu d\x1EE5ng h\x01A1n." + }, { + // Korean + "ko", + L"Google\xC758 \xBAA9\xD45C\xB294 \xC804\xC138\xACC4\xC758 " + L"\xC815\xBCF4\xB97C \xCCB4\xACC4\xD654\xD558\xC5EC \xBAA8\xB450\xAC00 " + L"\xD3B8\xB9AC\xD558\xAC8C \xC774\xC6A9\xD560 \xC218 " + L"\xC788\xB3C4\xB85D \xD558\xB294 \xAC83\xC785\xB2C8\xB2E4." + }, { + // Albanian + "sq", + L"Misioni i Google \x00EBsht\x00EB q\x00EB t\x00EB organizoj\x00EB " + L"informacionin e bot\x00EBs dhe t\x00EB b\x00EBjn\x00EB at\x00EB " + L"universalisht t\x00EB arritshme dhe t\x00EB dobishme." + }, { + // Tamil + "ta", + L"Google \x0B87\x0BA9\x0BCD " + L"\x0BA8\x0BC7\x0BBE\x0B95\x0BCD\x0B95\x0BAE\x0BCD " + L"\x0B89\x0BB2\x0B95\x0BBF\x0BA9\x0BCD \x0BA4\x0B95\x0BB5\x0BB2\x0BCD " + L"\x0B8F\x0BB1\x0BCD\x0BAA\x0BBE\x0B9F\x0BC1 \x0B87\x0BA4\x0BC1 " + L"\x0B89\x0BB2\x0B95\x0BB3\x0BBE\x0BB5\x0BBF\x0BAF " + L"\x0B85\x0BA3\x0BC1\x0B95\x0B95\x0BCD \x0B95\x0BC2\x0B9F\x0BBF\x0BAF " + L"\x0BAE\x0BB1\x0BCD\x0BB1\x0BC1\x0BAE\x0BCD " + L"\x0BAA\x0BAF\x0BA9\x0BC1\x0BB3\x0BCD\x0BB3 " + L"\x0B9A\x0BC6\x0BAF\x0BCD\x0BAF \x0B89\x0BB3\x0BCD\x0BB3\x0BA4\x0BC1." + }, { + // Tajik + "tg", + L"\x041c\x0438\x0441\x0441\x0438\x044f\x0438 Google \x0438\x043d " + L"\x043c\x0443\x0440\x0430\x0442\x0442\x0430\x0431 " + L"\x0441\x043e\x0445\x0442\x0430\x043d\x0438 " + L"\x043c\x0430\x044a\x043b\x0443\x043c\x043e\x0442\x04b3\x043e\x0438 " + L"\x043c\x0430\x0432\x04b7\x0443\x0434\x0430, \x043e\x0441\x043e\x043d " + L"\x043d\x0430\x043c\x0443\x0434\x0430\x043d\x0438 " + L"\x0438\x0441\x0442\x0438\x0444\x043e\x0434\x0430\x0431\x0430\x0440" + L"\x04e3 \x0432\x0430 \x0434\x0430\x0441\x0442\x0440\x0430\x0441\x0438 " + L"\x0443\x043c\x0443\x043c " + L"\x0433\x0430\x0440\x0434\x043e\x043d\x0438\x0434\x0430\x043d\x0438 " + L"\x043e\x043d\x04b3\x043e \x0430\x0441\x0442." + }, + }; + + for (size_t i = 0; i < arraysize(kTestCases); ++i) { + ReinitializeSpellCheck(kTestCases[i].language); + size_t input_length = 0; + if (kTestCases[i].input != NULL) + input_length = wcslen(kTestCases[i].input); + + int misspelling_start = 0; + int misspelling_length = 0; + bool result = spell_check()->SpellCheckWord( + base::WideToUTF16(kTestCases[i].input).c_str(), + kNoOffset, + static_cast<int>(input_length), + kNoTag, + &misspelling_start, + &misspelling_length, NULL); + + EXPECT_TRUE(result) + << "\"" + << std::wstring(kTestCases[i].input).substr( + misspelling_start, misspelling_length) + << "\" is misspelled in " + << kTestCases[i].language + << "."; + EXPECT_EQ(0, misspelling_start); + EXPECT_EQ(0, misspelling_length); + } +} + +// Verify that our SpellCheck::SpellCheckWord() returns false when it checks +// misspelled words. +TEST_F(SpellCheckTest, MisspelledWords) { + static const struct { + const char* language; + const wchar_t* input; + } kTestCases[] = { + { + // A misspelled word for English + "en-US", + L"aaaaaaaaaa", + }, { + // A misspelled word for Greek. + "el-GR", + L"\x03B1\x03B1\x03B1\x03B1\x03B1\x03B1\x03B1\x03B1\x03B1\x03B1", + }, { + // A misspelled word for Persian. + "fa", + L"\x06cc\x06a9\x06cc\x0634\x0627\x0646", + }, { + // A misspelled word for Hebrew + "he-IL", + L"\x05D0\x05D0\x05D0\x05D0\x05D0\x05D0\x05D0\x05D0\x05D0\x05D0", + }, { + // Hindi + "hi-IN", + L"\x0905\x0905\x0905\x0905\x0905\x0905\x0905\x0905\x0905\x0905", + }, { + // A misspelled word for Russian + "ru-RU", + L"\x0430\x0430\x0430\x0430\x0430\x0430\x0430\x0430\x0430\x0430", + }, + }; + + for (size_t i = 0; i < arraysize(kTestCases); ++i) { + ReinitializeSpellCheck(kTestCases[i].language); + + base::string16 word(base::WideToUTF16(kTestCases[i].input)); + int word_length = static_cast<int>(word.length()); + int misspelling_start = 0; + int misspelling_length = 0; + bool result = spell_check()->SpellCheckWord(word.c_str(), + kNoOffset, + word_length, + kNoTag, + &misspelling_start, + &misspelling_length, + NULL); + EXPECT_FALSE(result); + EXPECT_EQ(0, misspelling_start); + EXPECT_EQ(word_length, misspelling_length); + } +} + +// Since SpellCheck::SpellCheckParagraph is not implemented on Mac, +// we skip these SpellCheckParagraph tests on Mac. +#if !defined(OS_MACOSX) + +// Make sure SpellCheckParagraph does not crash if the input is empty. +TEST_F(SpellCheckTest, SpellCheckParagraphEmptyParagraph) { + std::vector<SpellCheckResult> expected; + TestSpellCheckParagraph(base::UTF8ToUTF16(""), expected); +} + +// A simple test case having no misspellings. +TEST_F(SpellCheckTest, SpellCheckParagraphNoMisspellings) { + const base::string16 text = base::UTF8ToUTF16("apple"); + std::vector<SpellCheckResult> expected; + TestSpellCheckParagraph(text, expected); +} + +// A simple test case having one misspelling. +TEST_F(SpellCheckTest, SpellCheckParagraphSingleMisspellings) { + const base::string16 text = base::UTF8ToUTF16("zz"); + std::vector<SpellCheckResult> expected; + expected.push_back(SpellCheckResult( + SpellCheckResult::SPELLING, 0, 2)); + + TestSpellCheckParagraph(text, expected); +} + +// A simple test case having multiple misspellings. +TEST_F(SpellCheckTest, SpellCheckParagraphMultipleMisspellings) { + const base::string16 text = base::UTF8ToUTF16("zz, zz"); + std::vector<SpellCheckResult> expected; + expected.push_back(SpellCheckResult( + SpellCheckResult::SPELLING, 0, 2)); + expected.push_back(SpellCheckResult( + SpellCheckResult::SPELLING, 4, 2)); + + TestSpellCheckParagraph(text, expected); +} + +// Make sure a relatively long (correct) sentence can be spellchecked. +TEST_F(SpellCheckTest, SpellCheckParagraphLongSentence) { + std::vector<SpellCheckResult> expected; + // The text is taken from US constitution preamble. + const base::string16 text = base::UTF8ToUTF16( + "We the people of the United States, in order to form a more perfect " + "union, establish justice, insure domestic tranquility, provide for " + "the common defense, promote the general welfare, and secure the " + "blessings of liberty to ourselves and our posterity, do ordain and " + "establish this Constitution for the United States of America."); + + TestSpellCheckParagraph(text, expected); +} + +// Make sure all misspellings can be found in a relatively long sentence. +TEST_F(SpellCheckTest, SpellCheckParagraphLongSentenceMultipleMisspellings) { + std::vector<SpellCheckResult> expected; + + // All 'the' are converted to 'hte' in US consitition preamble. + const base::string16 text = base::UTF8ToUTF16( + "We hte people of hte United States, in order to form a more perfect " + "union, establish justice, insure domestic tranquility, provide for " + "hte common defense, promote hte general welfare, and secure hte " + "blessings of liberty to ourselves and our posterity, do ordain and " + "establish this Constitution for hte United States of America."); + + expected.push_back(SpellCheckResult( + SpellCheckResult::SPELLING, 3, 3)); + expected.push_back(SpellCheckResult( + SpellCheckResult::SPELLING, 17, 3)); + expected.push_back(SpellCheckResult( + SpellCheckResult::SPELLING, 135, 3)); + expected.push_back(SpellCheckResult( + SpellCheckResult::SPELLING, 163, 3)); + expected.push_back(SpellCheckResult( + SpellCheckResult::SPELLING, 195, 3)); + expected.push_back(SpellCheckResult( + SpellCheckResult::SPELLING, 298, 3)); + + TestSpellCheckParagraph(text, expected); +} + +// We also skip RequestSpellCheck tests on Mac, because a system spellchecker +// is used on Mac instead of SpellCheck::RequestTextChecking. + +// Make sure RequestTextChecking does not crash if input is empty. +TEST_F(SpellCheckTest, RequestSpellCheckWithEmptyString) { + MockTextCheckingCompletion completion; + + spell_check()->RequestTextChecking(base::string16(), &completion); + + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(completion.completion_count_, 1U); +} + +// A simple test case having no misspellings. +TEST_F(SpellCheckTest, RequestSpellCheckWithoutMisspelling) { + MockTextCheckingCompletion completion; + + const base::string16 text = base::ASCIIToUTF16("hello"); + spell_check()->RequestTextChecking(text, &completion); + + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(completion.completion_count_, 1U); +} + +// A simple test case having one misspelling. +TEST_F(SpellCheckTest, RequestSpellCheckWithSingleMisspelling) { + MockTextCheckingCompletion completion; + + const base::string16 text = base::ASCIIToUTF16("apple, zz"); + spell_check()->RequestTextChecking(text, &completion); + + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(completion.completion_count_, 1U); + EXPECT_EQ(completion.last_results_.size(), 1U); + EXPECT_EQ(completion.last_results_[0].location, 7); + EXPECT_EQ(completion.last_results_[0].length, 2); +} + +// A simple test case having a few misspellings. +TEST_F(SpellCheckTest, RequestSpellCheckWithMisspellings) { + MockTextCheckingCompletion completion; + + const base::string16 text = base::ASCIIToUTF16("apple, zz, orange, zz"); + spell_check()->RequestTextChecking(text, &completion); + + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(completion.completion_count_, 1U); + EXPECT_EQ(completion.last_results_.size(), 2U); + EXPECT_EQ(completion.last_results_[0].location, 7); + EXPECT_EQ(completion.last_results_[0].length, 2); + EXPECT_EQ(completion.last_results_[1].location, 19); + EXPECT_EQ(completion.last_results_[1].length, 2); +} + +// A test case that multiple requests comes at once. Make sure all +// requests are processed. +TEST_F(SpellCheckTest, RequestSpellCheckWithMultipleRequests) { + MockTextCheckingCompletion completion[3]; + + const base::string16 text[3] = { + base::ASCIIToUTF16("what, zz"), + base::ASCIIToUTF16("apple, zz"), + base::ASCIIToUTF16("orange, zz") + }; + + for (int i = 0; i < 3; ++i) + spell_check()->RequestTextChecking(text[i], &completion[i]); + + base::RunLoop().RunUntilIdle(); + + for (int i = 0; i < 3; ++i) { + EXPECT_EQ(completion[i].completion_count_, 1U); + EXPECT_EQ(completion[i].last_results_.size(), 1U); + EXPECT_EQ(completion[i].last_results_[0].location, 6 + i); + EXPECT_EQ(completion[i].last_results_[0].length, 2); + } +} + +// A test case that spellchecking is requested before initializing. +// In this case, we postpone to post a request. +TEST_F(SpellCheckTest, RequestSpellCheckWithoutInitialization) { + UninitializeSpellCheck(); + + MockTextCheckingCompletion completion; + const base::string16 text = base::ASCIIToUTF16("zz"); + + spell_check()->RequestTextChecking(text, &completion); + + // The task will not be posted yet. + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(completion.completion_count_, 0U); +} + +// Requests several spellchecking before initializing. Except the last one, +// posting requests is cancelled and text is rendered as correct one. +TEST_F(SpellCheckTest, RequestSpellCheckMultipleTimesWithoutInitialization) { + UninitializeSpellCheck(); + + MockTextCheckingCompletion completion[3]; + const base::string16 text[3] = { + base::ASCIIToUTF16("what, zz"), + base::ASCIIToUTF16("apple, zz"), + base::ASCIIToUTF16("orange, zz") + }; + + // Calls RequestTextchecking a few times. + for (int i = 0; i < 3; ++i) + spell_check()->RequestTextChecking(text[i], &completion[i]); + + // The last task will be posted after initialization, however the other + // requests should be pressed without spellchecking. + base::RunLoop().RunUntilIdle(); + for (int i = 0; i < 2; ++i) + EXPECT_EQ(completion[i].completion_count_, 1U); + EXPECT_EQ(completion[2].completion_count_, 0U); + + // Checks the last request is processed after initialization. + InitializeSpellCheck("en-US"); + + // Calls PostDelayedSpellCheckTask instead of OnInit here for simplicity. + spell_check()->PostDelayedSpellCheckTask( + spell_check()->pending_request_param_.release()); + base::RunLoop().RunUntilIdle(); + for (int i = 0; i < 3; ++i) + EXPECT_EQ(completion[i].completion_count_, 1U); +} + +#endif + +// Verify that the SpellCheck class keeps the spelling marker added to a +// misspelled word "zz". +TEST_F(SpellCheckTest, CreateTextCheckingResultsKeepsMarkers) { + base::string16 text = base::ASCIIToUTF16("zz"); + std::vector<SpellCheckResult> spellcheck_results; + spellcheck_results.push_back( + SpellCheckResult(SpellCheckResult::SPELLING, 0, 2, base::string16())); + blink::WebVector<blink::WebTextCheckingResult> textcheck_results; + spell_check()->CreateTextCheckingResults(SpellCheck::USE_NATIVE_CHECKER, 0, + text, spellcheck_results, + &textcheck_results); + ASSERT_EQ(spellcheck_results.size(), textcheck_results.size()); + EXPECT_EQ(blink::WebTextDecorationTypeSpelling, + textcheck_results[0].decoration); + EXPECT_EQ(spellcheck_results[0].location, textcheck_results[0].location); + EXPECT_EQ(spellcheck_results[0].length, textcheck_results[0].length); +} + +// Verify that the SpellCheck class replaces the spelling marker added to a +// contextually-misspelled word "bean" with a grammar marker. +TEST_F(SpellCheckTest, CreateTextCheckingResultsAddsGrammarMarkers) { + base::string16 text = base::ASCIIToUTF16("I have bean to USA."); + std::vector<SpellCheckResult> spellcheck_results; + spellcheck_results.push_back( + SpellCheckResult(SpellCheckResult::SPELLING, 7, 4, base::string16())); + blink::WebVector<blink::WebTextCheckingResult> textcheck_results; + spell_check()->CreateTextCheckingResults(SpellCheck::USE_NATIVE_CHECKER, 0, + text, spellcheck_results, + &textcheck_results); + ASSERT_EQ(spellcheck_results.size(), textcheck_results.size()); + EXPECT_EQ(blink::WebTextDecorationTypeGrammar, + textcheck_results[0].decoration); + EXPECT_EQ(spellcheck_results[0].location, textcheck_results[0].location); + EXPECT_EQ(spellcheck_results[0].length, textcheck_results[0].length); +} + +// Verify that the SpellCheck preserves the original apostrophe type in the +// checked text, regardless of the type of apostrophe the browser returns. +TEST_F(SpellCheckTest, CreateTextCheckingResultsKeepsTypographicalApostrophe) { + base::string16 text = base::WideToUTF16( + L"Ik've havn" TYPOGRAPHICAL_APOSTROPHE L"t ni'n" + TYPOGRAPHICAL_APOSTROPHE L"out-s I've I" TYPOGRAPHICAL_APOSTROPHE + L"ve"); + std::vector<SpellCheckResult> spellcheck_results; + + // All typewriter apostrophe results. + spellcheck_results.push_back(SpellCheckResult(SpellCheckResult::SPELLING, 0, + 5, base::UTF8ToUTF16("I've"))); + spellcheck_results.push_back(SpellCheckResult( + SpellCheckResult::SPELLING, 6, 6, base::UTF8ToUTF16("haven't"))); + spellcheck_results.push_back(SpellCheckResult( + SpellCheckResult::SPELLING, 13, 10, base::UTF8ToUTF16("in'n'out's"))); + + // Replacements that differ only by apostrophe type should be ignored. + spellcheck_results.push_back(SpellCheckResult(SpellCheckResult::SPELLING, 24, + 4, base::UTF8ToUTF16("I've"))); + spellcheck_results.push_back(SpellCheckResult(SpellCheckResult::SPELLING, 29, + 4, base::UTF8ToUTF16("I've"))); + + // All typographical apostrophe results. + spellcheck_results.push_back( + SpellCheckResult(SpellCheckResult::SPELLING, 0, 5, + base::WideToUTF16(L"I" TYPOGRAPHICAL_APOSTROPHE L"ve"))); + spellcheck_results.push_back(SpellCheckResult( + SpellCheckResult::SPELLING, 6, 6, + base::WideToUTF16(L"haven" TYPOGRAPHICAL_APOSTROPHE L"t"))); + spellcheck_results.push_back(SpellCheckResult( + SpellCheckResult::SPELLING, 13, 10, base::WideToUTF16( + L"in" TYPOGRAPHICAL_APOSTROPHE L"n" TYPOGRAPHICAL_APOSTROPHE L"out" + TYPOGRAPHICAL_APOSTROPHE L"s"))); + + // Replacements that differ only by apostrophe type should be ignored. + spellcheck_results.push_back( + SpellCheckResult(SpellCheckResult::SPELLING, 24, 4, + base::WideToUTF16(L"I" TYPOGRAPHICAL_APOSTROPHE L"ve"))); + spellcheck_results.push_back( + SpellCheckResult(SpellCheckResult::SPELLING, 29, 4, + base::WideToUTF16(L"I" TYPOGRAPHICAL_APOSTROPHE L"ve"))); + + blink::WebVector<blink::WebTextCheckingResult> textcheck_results; + spell_check()->CreateTextCheckingResults(SpellCheck::USE_NATIVE_CHECKER, 0, + text, spellcheck_results, + &textcheck_results); + + static const wchar_t* kExpectedReplacements[] = { + L"I've", + L"haven" TYPOGRAPHICAL_APOSTROPHE L"t", + L"in'n" TYPOGRAPHICAL_APOSTROPHE L"out's", + L"I've", + L"haven" TYPOGRAPHICAL_APOSTROPHE L"t", + L"in'n" TYPOGRAPHICAL_APOSTROPHE L"out" TYPOGRAPHICAL_APOSTROPHE L"s", + }; + + ASSERT_EQ(arraysize(kExpectedReplacements), textcheck_results.size()); + for (size_t i = 0; i < arraysize(kExpectedReplacements); ++i) { + EXPECT_EQ(base::WideToUTF16(kExpectedReplacements[i]), + textcheck_results[i].replacement) + << "i=" << i << "\nactual: \"" + << base::string16(textcheck_results[i].replacement) << "\""; + } +} + +// Checks some words that should be present in all English dictionaries. +TEST_F(SpellCheckTest, EnglishWords) { + static const struct { + const char* input; + bool should_pass; + } kTestCases[] = { + // Issue 146093: "Chromebook" and "Chromebox" not included in spell-checking + // dictionary. + {"Chromebook", true}, + {"Chromebooks", true}, + {"Chromebox", true}, + {"Chromeboxes", true}, + {"Chromeblade", true}, + {"Chromeblades", true}, + {"Chromebase", true}, + {"Chromebases", true}, + // Issue 94708: Spell-checker incorrectly reports whisky as misspelled. + {"whisky", true}, + {"whiskey", true}, + {"whiskies", true}, + // Issue 98678: "Recency" should be included in client-side dictionary. + {"recency", true}, + {"recencies", false}, + // Issue 140486 + {"movie", true}, + {"movies", true}, + }; + + static const char* const kLocales[] = { "en-GB", "en-US", "en-CA", "en-AU" }; + + for (size_t j = 0; j < arraysize(kLocales); ++j) { + ReinitializeSpellCheck(kLocales[j]); + for (size_t i = 0; i < arraysize(kTestCases); ++i) { + size_t input_length = 0; + if (kTestCases[i].input != NULL) + input_length = strlen(kTestCases[i].input); + + int misspelling_start = 0; + int misspelling_length = 0; + bool result = spell_check()->SpellCheckWord( + base::ASCIIToUTF16(kTestCases[i].input).c_str(), + kNoOffset, + static_cast<int>(input_length), + kNoTag, + &misspelling_start, + &misspelling_length, NULL); + + EXPECT_EQ(kTestCases[i].should_pass, result) << kTestCases[i].input << + " in " << kLocales[j]; + } + } +} + +// Checks that NOSUGGEST works in English dictionaries. +TEST_F(SpellCheckTest, NoSuggest) { + static const struct { + const char* input; + const char* suggestion; + const char* locale; + bool should_pass; + } kTestCases[] = { + {"suckerbert", "cocksucker", "en-GB", true}, + {"suckerbert", "cocksucker", "en-US", true}, + {"suckerbert", "cocksucker", "en-CA", true}, + {"suckerbert", "cocksucker", "en-AU", true}, + {"suckerbert", "cocksuckers", "en-GB", true}, + {"suckerbert", "cocksuckers", "en-US", true}, + {"suckerbert", "cocksuckers", "en-CA", true}, + {"suckerbert", "cocksuckers", "en-AU", true}, + {"Batasunaa", "Batasuna", "ca-ES", true}, + {"pornoo", "porno", "it-IT", true}, + {"catass", "catas", "lt-LT", true}, + {"kuracc", "kurac", "sl-SI", true}, + {"pittt", "pitt", "sv-SE", true}, + }; + + size_t test_cases_size = arraysize(kTestCases); + for (size_t i = 0; i < test_cases_size; ++i) { + ReinitializeSpellCheck(kTestCases[i].locale); + size_t suggestion_length = 0; + if (kTestCases[i].suggestion != NULL) + suggestion_length = strlen(kTestCases[i].suggestion); + + // First check that the NOSUGGEST flag didn't mark this word as not being in + // the dictionary. + int misspelling_start = 0; + int misspelling_length = 0; + bool result = spell_check()->SpellCheckWord( + base::ASCIIToUTF16(kTestCases[i].suggestion).c_str(), + kNoOffset, + static_cast<int>(suggestion_length), + kNoTag, + &misspelling_start, + &misspelling_length, NULL); + + EXPECT_EQ(kTestCases[i].should_pass, result) << kTestCases[i].suggestion << + " in " << kTestCases[i].locale; + + // Now verify that this test case does not show up as a suggestion. + std::vector<base::string16> suggestions; + size_t input_length = 0; + if (kTestCases[i].input != NULL) + input_length = strlen(kTestCases[i].input); + result = spell_check()->SpellCheckWord( + base::ASCIIToUTF16(kTestCases[i].input).c_str(), + kNoOffset, + static_cast<int>(input_length), + kNoTag, + &misspelling_start, + &misspelling_length, + &suggestions); + // Input word should be a misspelling. + EXPECT_FALSE(result) << kTestCases[i].input + << " is not a misspelling in " + << kTestCases[i].locale; + // Check if the suggested words occur. + for (int j = 0; j < static_cast<int>(suggestions.size()); j++) { + for (size_t t = 0; t < test_cases_size; t++) { + int compare_result = suggestions.at(j).compare( + base::ASCIIToUTF16(kTestCases[t].suggestion)); + EXPECT_FALSE(compare_result == 0) << kTestCases[t].suggestion << + " in " << kTestCases[i].locale; + } + } + } +} + +// Check that the correct dictionary files are checked in. +TEST_F(SpellCheckTest, DictionaryFiles) { + std::vector<std::string> spellcheck_languages; + spellcheck::SpellCheckLanguages(&spellcheck_languages); + EXPECT_FALSE(spellcheck_languages.empty()); + + base::FilePath hunspell = GetHunspellDirectory(); + for (size_t i = 0; i < spellcheck_languages.size(); ++i) { + base::FilePath dict = + spellcheck::GetVersionedFileName(spellcheck_languages[i], hunspell); + EXPECT_TRUE(base::PathExists(dict)) << dict.value() << " not found"; + } +} + +// TODO(groby): Add a test for hunspell itself, when MAXWORDLEN is exceeded. +TEST_F(SpellCheckTest, SpellingEngine_CheckSpelling) { + static const struct { + const char* word; + bool expected_result; + } kTestCases[] = { + { "", true }, + { "automatic", true }, + { "hello", true }, + { "forglobantic", false }, + { "xfdssfsdfaasds", false }, + { // 64 chars are the longest word to check - this should fail checking. + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl", + false + }, + { // Any word longer than 64 chars should be exempt from checking. + "reallylongwordthatabsolutelyexceedsthespecifiedcharacterlimitabit", + true + } + }; + + // Initialization magic - call InitializeIfNeeded twice. The first one simply + // flags internal state that a dictionary was requested. The second one will + // take the passed-in file and initialize hunspell with it. (The file was + // passed to hunspell in the ctor for the test fixture). + // This needs to be done since we need to ensure the SpellingEngine objects + // contained in the SpellcheckLanguages in |languages_| from the test fixture + // does get initialized. + // TODO(groby): Clean up this mess. + InitializeIfNeeded(); + ASSERT_FALSE(InitializeIfNeeded()); + + for (size_t i = 0; i < arraysize(kTestCases); ++i) { + bool result = CheckSpelling(kTestCases[i].word, 0); + EXPECT_EQ(kTestCases[i].expected_result, result) << + "Failed test for " << kTestCases[i].word; + } +} + +// Chrome should not suggest "Othello" for "hellllo" or "identically" for +// "accidently". +TEST_F(SpellCheckTest, LogicalSuggestions) { + static const struct { + const char* misspelled; + const char* suggestion; + } kTestCases[] = { + { "hellllo", "hello" }, + { "accidently", "accidentally" } + }; + + for (size_t i = 0; i < arraysize(kTestCases); ++i) { + int misspelling_start = 0; + int misspelling_length = 0; + std::vector<base::string16> suggestions; + EXPECT_FALSE(spell_check()->SpellCheckWord( + base::ASCIIToUTF16(kTestCases[i].misspelled).c_str(), + kNoOffset, + strlen(kTestCases[i].misspelled), + kNoTag, + &misspelling_start, + &misspelling_length, + &suggestions)); + EXPECT_GE(suggestions.size(), static_cast<size_t>(1)); + if (suggestions.size() > 0) + EXPECT_EQ(suggestions[0], base::ASCIIToUTF16(kTestCases[i].suggestion)); + } +} + +// Words with apostrophes should be valid contractions. +TEST_F(SpellCheckTest, IsValidContraction) { + static const char* kLanguages[] = { + "en-AU", + "en-CA", + "en-GB", + "en-US", + }; + + static const wchar_t* kWords[] = { + L"in'n'out", + L"in" TYPOGRAPHICAL_APOSTROPHE L"n" TYPOGRAPHICAL_APOSTROPHE L"out", + }; + + for (size_t i = 0; i < arraysize(kLanguages); ++i) { + ReinitializeSpellCheck(kLanguages[i]); + for (size_t j = 0; j < arraysize(kWords); ++j) + EXPECT_TRUE(IsValidContraction(base::WideToUTF16(kWords[j]), 0)); + } +} + +TEST_F(SpellCheckTest, FillSuggestions_OneLanguageNoSuggestions) { + std::vector<std::vector<base::string16>> suggestions_list; + std::vector<base::string16> suggestion_results; + + suggestions_list.resize(1); + + FillSuggestions(suggestions_list, &suggestion_results); + EXPECT_TRUE(suggestion_results.empty()); +} + +TEST_F(SpellCheckTest, FillSuggestions_OneLanguageFewSuggestions) { + std::vector<std::vector<base::string16>> suggestions_list; + std::vector<base::string16> suggestion_results; + + suggestions_list.resize(1); + suggestions_list[0].push_back(base::ASCIIToUTF16("foo")); + + FillSuggestions(suggestions_list, &suggestion_results); + ASSERT_EQ(1U, suggestion_results.size()); + EXPECT_EQ(base::ASCIIToUTF16("foo"), suggestion_results[0]); +} + +TEST_F(SpellCheckTest, FillSuggestions_OneLanguageManySuggestions) { + std::vector<std::vector<base::string16>> suggestions_list; + std::vector<base::string16> suggestion_results; + + suggestions_list.resize(1); + for (int i = 0; i < spellcheck::kMaxSuggestions + 2; ++i) + suggestions_list[0].push_back(base::ASCIIToUTF16(base::IntToString(i))); + + FillSuggestions(suggestions_list, &suggestion_results); + ASSERT_EQ(static_cast<size_t>(spellcheck::kMaxSuggestions), + suggestion_results.size()); + for (int i = 0; i < spellcheck::kMaxSuggestions; ++i) + EXPECT_EQ(base::ASCIIToUTF16(base::IntToString(i)), suggestion_results[i]); +} + +TEST_F(SpellCheckTest, FillSuggestions_RemoveDuplicates) { + std::vector<std::vector<base::string16>> suggestions_list; + std::vector<base::string16> suggestion_results; + + suggestions_list.resize(2); + for (size_t i = 0; i < 2; ++i) { + suggestions_list[i].push_back(base::ASCIIToUTF16("foo")); + suggestions_list[i].push_back(base::ASCIIToUTF16("bar")); + suggestions_list[i].push_back(base::ASCIIToUTF16("baz")); + } + + FillSuggestions(suggestions_list, &suggestion_results); + ASSERT_EQ(3U, suggestion_results.size()); + EXPECT_EQ(base::ASCIIToUTF16("foo"), suggestion_results[0]); + EXPECT_EQ(base::ASCIIToUTF16("bar"), suggestion_results[1]); + EXPECT_EQ(base::ASCIIToUTF16("baz"), suggestion_results[2]); +} + +TEST_F(SpellCheckTest, FillSuggestions_TwoLanguages) { + std::vector<std::vector<base::string16>> suggestions_list; + std::vector<base::string16> suggestion_results; + + suggestions_list.resize(2); + for (size_t i = 0; i < 2; ++i) { + std::string prefix = base::IntToString(i); + suggestions_list[i].push_back(base::ASCIIToUTF16(prefix + "foo")); + suggestions_list[i].push_back(base::ASCIIToUTF16(prefix + "bar")); + suggestions_list[i].push_back(base::ASCIIToUTF16(prefix + "baz")); + } + + // Yes, this test assumes kMaxSuggestions is 5. If it isn't, the test needs + // to be updated accordingly. + ASSERT_EQ(5, spellcheck::kMaxSuggestions); + FillSuggestions(suggestions_list, &suggestion_results); + ASSERT_EQ(5U, suggestion_results.size()); + EXPECT_EQ(base::ASCIIToUTF16("0foo"), suggestion_results[0]); + EXPECT_EQ(base::ASCIIToUTF16("1foo"), suggestion_results[1]); + EXPECT_EQ(base::ASCIIToUTF16("0bar"), suggestion_results[2]); + EXPECT_EQ(base::ASCIIToUTF16("1bar"), suggestion_results[3]); + EXPECT_EQ(base::ASCIIToUTF16("0baz"), suggestion_results[4]); +} + +TEST_F(SpellCheckTest, FillSuggestions_ThreeLanguages) { + std::vector<std::vector<base::string16>> suggestions_list; + std::vector<base::string16> suggestion_results; + + suggestions_list.resize(3); + for (size_t i = 0; i < 3; ++i) { + std::string prefix = base::IntToString(i); + suggestions_list[i].push_back(base::ASCIIToUTF16(prefix + "foo")); + suggestions_list[i].push_back(base::ASCIIToUTF16(prefix + "bar")); + suggestions_list[i].push_back(base::ASCIIToUTF16(prefix + "baz")); + } + + // Yes, this test assumes kMaxSuggestions is 5. If it isn't, the test needs + // to be updated accordingly. + ASSERT_EQ(5, spellcheck::kMaxSuggestions); + FillSuggestions(suggestions_list, &suggestion_results); + ASSERT_EQ(5U, suggestion_results.size()); + EXPECT_EQ(base::ASCIIToUTF16("0foo"), suggestion_results[0]); + EXPECT_EQ(base::ASCIIToUTF16("1foo"), suggestion_results[1]); + EXPECT_EQ(base::ASCIIToUTF16("2foo"), suggestion_results[2]); + EXPECT_EQ(base::ASCIIToUTF16("0bar"), suggestion_results[3]); + EXPECT_EQ(base::ASCIIToUTF16("1bar"), suggestion_results[4]); +}
diff --git a/components/spellcheck/renderer/spellcheck_worditerator.cc b/components/spellcheck/renderer/spellcheck_worditerator.cc new file mode 100644 index 0000000..8ed1c87f --- /dev/null +++ b/components/spellcheck/renderer/spellcheck_worditerator.cc
@@ -0,0 +1,445 @@ +// 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. + +// Implements a custom word iterator used for our spellchecker. + +#include "components/spellcheck/renderer/spellcheck_worditerator.h" + +#include <map> +#include <memory> +#include <string> +#include <utility> + +#include "base/i18n/break_iterator.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" +#include "components/spellcheck/renderer/spellcheck.h" +#include "third_party/icu/source/common/unicode/normlzr.h" +#include "third_party/icu/source/common/unicode/schriter.h" +#include "third_party/icu/source/common/unicode/uscript.h" +#include "third_party/icu/source/i18n/unicode/ulocdata.h" + +using base::i18n::BreakIterator; + +// SpellcheckCharAttribute implementation: + +SpellcheckCharAttribute::SpellcheckCharAttribute() + : script_code_(USCRIPT_LATIN) { +} + +SpellcheckCharAttribute::~SpellcheckCharAttribute() { +} + +void SpellcheckCharAttribute::SetDefaultLanguage(const std::string& language) { + CreateRuleSets(language); +} + +base::string16 SpellcheckCharAttribute::GetRuleSet( + bool allow_contraction) const { + return allow_contraction ? + ruleset_allow_contraction_ : ruleset_disallow_contraction_; +} + +void SpellcheckCharAttribute::CreateRuleSets(const std::string& language) { + // The template for our custom rule sets, which is based on the word-break + // rules of ICU 4.0: + // <http://source.icu-project.org/repos/icu/icu/tags/release-4-0/source/data/brkitr/word.txt>. + // The major differences from the original one are listed below: + // * It discards comments in the original rules. + // * It discards characters not needed by our spellchecker (e.g. numbers, + // punctuation characters, Hiraganas, Katakanas, CJK Ideographs, and so on). + // * It allows customization of the $ALetter value (i.e. word characters). + // * It allows customization of the $ALetterPlus value (i.e. whether or not to + // use the dictionary data). + // * It allows choosing whether or not to split a text at contraction + // characters. + // This template only changes the forward-iteration rules. So, calling + // ubrk_prev() returns the same results as the original template. + static const char kRuleTemplate[] = + "!!chain;" + "$CR = [\\p{Word_Break = CR}];" + "$LF = [\\p{Word_Break = LF}];" + "$Newline = [\\p{Word_Break = Newline}];" + "$Extend = [\\p{Word_Break = Extend}];" + "$Format = [\\p{Word_Break = Format}];" + "$Katakana = [\\p{Word_Break = Katakana}];" + // Not all the characters in a given script are ALetter. + // For instance, U+05F4 is MidLetter. So, this may be + // better, but it leads to an empty set error in Thai. + // "$ALetter = [[\\p{script=%s}] & [\\p{Word_Break = ALetter}]];" + "$ALetter = [\\p{script=%s}%s];" + // U+0027 (single quote/apostrophe) is not in MidNumLet any more + // in UAX 29 rev 21 or later. For our purpose, U+0027 + // has to be treated as MidNumLet. ( http://crbug.com/364072 ) + "$MidNumLet = [\\p{Word_Break = MidNumLet} \\u0027];" + "$MidLetter = [\\p{Word_Break = MidLetter}%s];" + "$MidNum = [\\p{Word_Break = MidNum}];" + "$Numeric = [\\p{Word_Break = Numeric}];" + "$ExtendNumLet = [\\p{Word_Break = ExtendNumLet}];" + + "$Control = [\\p{Grapheme_Cluster_Break = Control}]; " + "%s" // ALetterPlus + + "$KatakanaEx = $Katakana ($Extend | $Format)*;" + "$ALetterEx = $ALetterPlus ($Extend | $Format)*;" + "$MidNumLetEx = $MidNumLet ($Extend | $Format)*;" + "$MidLetterEx = $MidLetter ($Extend | $Format)*;" + "$MidNumEx = $MidNum ($Extend | $Format)*;" + "$NumericEx = $Numeric ($Extend | $Format)*;" + "$ExtendNumLetEx = $ExtendNumLet ($Extend | $Format)*;" + + "$Hiragana = [\\p{script=Hiragana}];" + "$Ideographic = [\\p{Ideographic}];" + "$HiraganaEx = $Hiragana ($Extend | $Format)*;" + "$IdeographicEx = $Ideographic ($Extend | $Format)*;" + + "!!forward;" + "$CR $LF;" + "[^$CR $LF $Newline]? ($Extend | $Format)+;" + "$ALetterEx {200};" + "$ALetterEx $ALetterEx {200};" + "%s" // (Allow|Disallow) Contraction + + "!!reverse;" + "$BackALetterEx = ($Format | $Extend)* $ALetterPlus;" + "$BackMidNumLetEx = ($Format | $Extend)* $MidNumLet;" + "$BackNumericEx = ($Format | $Extend)* $Numeric;" + "$BackMidNumEx = ($Format | $Extend)* $MidNum;" + "$BackMidLetterEx = ($Format | $Extend)* $MidLetter;" + "$BackKatakanaEx = ($Format | $Extend)* $Katakana;" + "$BackExtendNumLetEx= ($Format | $Extend)* $ExtendNumLet;" + "$LF $CR;" + "($Format | $Extend)* [^$CR $LF $Newline]?;" + "$BackALetterEx $BackALetterEx;" + "$BackALetterEx ($BackMidLetterEx | $BackMidNumLetEx) $BackALetterEx;" + "$BackNumericEx $BackNumericEx;" + "$BackNumericEx $BackALetterEx;" + "$BackALetterEx $BackNumericEx;" + "$BackNumericEx ($BackMidNumEx | $BackMidNumLetEx) $BackNumericEx;" + "$BackKatakanaEx $BackKatakanaEx;" + "$BackExtendNumLetEx ($BackALetterEx | $BackNumericEx |" + " $BackKatakanaEx | $BackExtendNumLetEx);" + "($BackALetterEx | $BackNumericEx | $BackKatakanaEx)" + " $BackExtendNumLetEx;" + + "!!safe_reverse;" + "($Extend | $Format)+ .?;" + "($MidLetter | $MidNumLet) $BackALetterEx;" + "($MidNum | $MidNumLet) $BackNumericEx;" + + "!!safe_forward;" + "($Extend | $Format)+ .?;" + "($MidLetterEx | $MidNumLetEx) $ALetterEx;" + "($MidNumEx | $MidNumLetEx) $NumericEx;"; + + // Retrieve the script codes used by the given language from ICU. When the + // given language consists of two or more scripts, we just use the first + // script. The size of returned script codes is always < 8. Therefore, we use + // an array of size 8 so we can include all script codes without insufficient + // buffer errors. + UErrorCode error = U_ZERO_ERROR; + UScriptCode script_code[8]; + int scripts = uscript_getCode(language.c_str(), script_code, + arraysize(script_code), &error); + if (U_SUCCESS(error) && scripts >= 1) + script_code_ = script_code[0]; + + // Retrieve the values for $ALetter and $ALetterPlus. We use the dictionary + // only for the languages which need it (i.e. Korean and Thai) to prevent ICU + // from returning dictionary words (i.e. Korean or Thai words) for languages + // which don't need them. + const char* aletter = uscript_getName(script_code_); + if (!aletter) + aletter = "Latin"; + + const char kWithDictionary[] = + "$dictionary = [:LineBreak = Complex_Context:];" + "$ALetterPlus = [$ALetter [$dictionary-$Extend-$Control]];"; + const char kWithoutDictionary[] = "$ALetterPlus = $ALetter;"; + const char* aletter_plus = kWithoutDictionary; + if (script_code_ == USCRIPT_HANGUL || script_code_ == USCRIPT_THAI || + script_code_ == USCRIPT_LAO || script_code_ == USCRIPT_KHMER) + aletter_plus = kWithDictionary; + + // Treat numbers as word characters except for Arabic and Hebrew. + const char* aletter_extra = " [0123456789]"; + if (script_code_ == USCRIPT_HEBREW) + aletter_extra = ""; + else if (script_code_ == USCRIPT_ARABIC) + // When "script=Arabic", it does not include tatweel, which is + // "script=Common" so add it back. Otherwise, it creates unwanted + // word breaks. + aletter_extra = " [\\u0640]"; + + const char kMidLetterExtra[] = ""; + // For Hebrew, treat single/double quoation marks as MidLetter. + const char kMidLetterExtraHebrew[] = "\"'"; + const char* midletter_extra = kMidLetterExtra; + if (script_code_ == USCRIPT_HEBREW) + midletter_extra = kMidLetterExtraHebrew; + + // Create two custom rule-sets: one allows contraction and the other does not. + // We save these strings in UTF-16 so we can use it without conversions. (ICU + // needs UTF-16 strings.) + const char kAllowContraction[] = + "$ALetterEx ($MidLetterEx | $MidNumLetEx) $ALetterEx {200};"; + const char kDisallowContraction[] = ""; + + ruleset_allow_contraction_ = base::ASCIIToUTF16( + base::StringPrintf(kRuleTemplate, + aletter, + aletter_extra, + midletter_extra, + aletter_plus, + kAllowContraction)); + ruleset_disallow_contraction_ = base::ASCIIToUTF16( + base::StringPrintf(kRuleTemplate, + aletter, + aletter_extra, + midletter_extra, + aletter_plus, + kDisallowContraction)); +} + +bool SpellcheckCharAttribute::OutputChar(UChar c, + base::string16* output) const { + // Call the language-specific function if necessary. + // Otherwise, we call the default one. + switch (script_code_) { + case USCRIPT_ARABIC: + return OutputArabic(c, output); + + case USCRIPT_HANGUL: + return OutputHangul(c, output); + + case USCRIPT_HEBREW: + return OutputHebrew(c, output); + + default: + return OutputDefault(c, output); + } +} + +bool SpellcheckCharAttribute::OutputArabic(UChar c, + base::string16* output) const { + // Include non-Arabic characters (which should trigger a spelling error) + // and Arabic characters excluding vowel marks and class "Lm". + // We filter the latter because, while they are "letters", they are + // optional and so don't affect the correctness of the rest of the word. + if (!(0x0600 <= c && c <= 0x06FF) || (u_isalpha(c) && c != 0x0640)) + output->push_back(c); + return true; +} + +bool SpellcheckCharAttribute::OutputHangul(UChar c, + base::string16* output) const { + // Decompose a Hangul character to a Hangul vowel and consonants used by our + // spellchecker. A Hangul character of Unicode is a ligature consisting of a + // Hangul vowel and consonants, e.g. U+AC01 "Gag" consists of U+1100 "G", + // U+1161 "a", and U+11A8 "g". That is, we can treat each Hangul character as + // a point of a cubic linear space consisting of (first consonant, vowel, last + // consonant). Therefore, we can compose a Hangul character from a vowel and + // two consonants with linear composition: + // character = 0xAC00 + + // (first consonant - 0x1100) * 28 * 21 + + // (vowel - 0x1161) * 28 + + // (last consonant - 0x11A7); + // We can also decompose a Hangul character with linear decomposition: + // first consonant = (character - 0xAC00) / 28 / 21; + // vowel = (character - 0xAC00) / 28 % 21; + // last consonant = (character - 0xAC00) % 28; + // This code is copied from Unicode Standard Annex #15 + // <http://unicode.org/reports/tr15> and added some comments. + const int kSBase = 0xAC00; // U+AC00: the top of Hangul characters. + const int kLBase = 0x1100; // U+1100: the top of Hangul first consonants. + const int kVBase = 0x1161; // U+1161: the top of Hangul vowels. + const int kTBase = 0x11A7; // U+11A7: the top of Hangul last consonants. + const int kLCount = 19; // The number of Hangul first consonants. + const int kVCount = 21; // The number of Hangul vowels. + const int kTCount = 28; // The number of Hangul last consonants. + const int kNCount = kVCount * kTCount; + const int kSCount = kLCount * kNCount; + + int index = c - kSBase; + if (index < 0 || index >= kSBase + kSCount) { + // This is not a Hangul syllable. Call the default output function since we + // should output this character when it is a Hangul syllable. + return OutputDefault(c, output); + } + + // This is a Hangul character. Decompose this characters into Hangul vowels + // and consonants. + int l = kLBase + index / kNCount; + int v = kVBase + (index % kNCount) / kTCount; + int t = kTBase + index % kTCount; + output->push_back(l); + output->push_back(v); + if (t != kTBase) + output->push_back(t); + return true; +} + +bool SpellcheckCharAttribute::OutputHebrew(UChar c, + base::string16* output) const { + // Discard characters except Hebrew alphabets. We also discard Hebrew niqquds + // to prevent our Hebrew dictionary from marking a Hebrew word including + // niqquds as misspelled. (Same as Arabic vowel marks, we need to check + // niqquds manually and filter them out since their script codes are + // USCRIPT_HEBREW.) + // Pass through ASCII single/double quotation marks and Hebrew Geresh and + // Gershayim. + if ((0x05D0 <= c && c <= 0x05EA) || c == 0x22 || c == 0x27 || + c == 0x05F4 || c == 0x05F3) + output->push_back(c); + return true; +} + +bool SpellcheckCharAttribute::OutputDefault(UChar c, + base::string16* output) const { + // Check the script code of this character and output only if it is the one + // used by the spellchecker language. + UErrorCode status = U_ZERO_ERROR; + UScriptCode script_code = uscript_getScript(c, &status); + if (script_code == script_code_ || script_code == USCRIPT_COMMON) + output->push_back(c); + return true; +} + +// SpellcheckWordIterator implementation: + +SpellcheckWordIterator::SpellcheckWordIterator() + : text_(NULL), + attribute_(NULL), + iterator_() { +} + +SpellcheckWordIterator::~SpellcheckWordIterator() { + Reset(); +} + +bool SpellcheckWordIterator::Initialize( + const SpellcheckCharAttribute* attribute, + bool allow_contraction) { + // Create a custom ICU break iterator with empty text used in this object. (We + // allow setting text later so we can re-use this iterator.) + DCHECK(attribute); + const base::string16 rule(attribute->GetRuleSet(allow_contraction)); + + // If there is no rule set, the attributes were invalid. + if (rule.empty()) + return false; + + std::unique_ptr<BreakIterator> iterator( + new BreakIterator(base::string16(), rule)); + if (!iterator->Init()) { + // Since we're not passing in any text, the only reason this could fail + // is if we fail to parse the rules. Since the rules are hardcoded, + // that would be a bug in this class. + NOTREACHED() << "failed to open iterator (broken rules)"; + return false; + } + iterator_ = std::move(iterator); + + // Set the character attributes so we can normalize the words extracted by + // this iterator. + attribute_ = attribute; + return true; +} + +bool SpellcheckWordIterator::IsInitialized() const { + // Return true iff we have an iterator. + return !!iterator_; +} + +bool SpellcheckWordIterator::SetText(const base::char16* text, size_t length) { + DCHECK(!!iterator_); + + // Set the text to be split by this iterator. + if (!iterator_->SetText(text, length)) { + LOG(ERROR) << "failed to set text"; + return false; + } + + text_ = text; + return true; +} + +SpellcheckWordIterator::WordIteratorStatus SpellcheckWordIterator::GetNextWord( + base::string16* word_string, + int* word_start, + int* word_length) { + DCHECK(!!text_); + + word_string->clear(); + *word_start = 0; + *word_length = 0; + + if (!text_) { + return IS_END_OF_TEXT; + } + + // Find a word that can be checked for spelling or a character that can be + // skipped over. Rather than moving past a skippable character this returns + // IS_SKIPPABLE and defers handling the character to the calling function. + while (iterator_->Advance()) { + const size_t start = iterator_->prev(); + const size_t length = iterator_->pos() - start; + switch (iterator_->GetWordBreakStatus()) { + case BreakIterator::IS_WORD_BREAK: { + if (Normalize(start, length, word_string)) { + *word_start = start; + *word_length = length; + return IS_WORD; + } + break; + } + case BreakIterator::IS_SKIPPABLE_WORD: { + *word_string = iterator_->GetString(); + *word_start = start; + *word_length = length; + return IS_SKIPPABLE; + } + // |iterator_| is RULE_BASED so the break status should never be + // IS_LINE_OR_CHAR_BREAK. + case BreakIterator::IS_LINE_OR_CHAR_BREAK: { + NOTREACHED(); + break; + } + } + } + + // There aren't any more words in the given text. + return IS_END_OF_TEXT; +} + +void SpellcheckWordIterator::Reset() { + iterator_.reset(); +} + +bool SpellcheckWordIterator::Normalize(int input_start, + int input_length, + base::string16* output_string) const { + // We use NFKC (Normalization Form, Compatible decomposition, followed by + // canonical Composition) defined in Unicode Standard Annex #15 to normalize + // this token because it it the most suitable normalization algorithm for our + // spellchecker. Nevertheless, it is not a perfect algorithm for our + // spellchecker and we need manual normalization as well. The normalized + // text does not have to be NUL-terminated since its characters are copied to + // string16, which adds a NUL character when we need. + icu::UnicodeString input(FALSE, &text_[input_start], input_length); + UErrorCode status = U_ZERO_ERROR; + icu::UnicodeString output; + icu::Normalizer::normalize(input, UNORM_NFKC, 0, output, status); + if (status != U_ZERO_ERROR && status != U_STRING_NOT_TERMINATED_WARNING) + return false; + + // Copy the normalized text to the output. + icu::StringCharacterIterator it(output); + for (UChar c = it.first(); c != icu::CharacterIterator::DONE; c = it.next()) + attribute_->OutputChar(c, output_string); + + return !output_string->empty(); +}
diff --git a/components/spellcheck/renderer/spellcheck_worditerator.h b/components/spellcheck/renderer/spellcheck_worditerator.h new file mode 100644 index 0000000..ea2f038 --- /dev/null +++ b/components/spellcheck/renderer/spellcheck_worditerator.h
@@ -0,0 +1,200 @@ +// 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. + +// Defines an iterator class that enumerates words supported by our spellchecker +// from multi-language text. This class is used for filtering out characters +// not supported by our spellchecker. + +#ifndef COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_WORDITERATOR_H_ +#define COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_WORDITERATOR_H_ + +#include <stddef.h> + +#include <memory> +#include <string> + +#include "base/macros.h" +#include "base/strings/string16.h" +#include "third_party/icu/source/common/unicode/uscript.h" + +namespace base { +namespace i18n { +class BreakIterator; +} // namespace i18n +} // namespace base + +// A class which encapsulates language-specific operations used by +// SpellcheckWordIterator. When we set the spellchecker language, this class +// creates rule sets that filter out the characters not supported by the +// spellchecker. (Please read the comment in the SpellcheckWordIterator class +// about how to use this class.) +class SpellcheckCharAttribute { + public: + SpellcheckCharAttribute(); + ~SpellcheckCharAttribute(); + + // Sets the language of the spellchecker. When this function is called with an + // ISO language code, this function creates the custom rule-sets used by + // the ICU break iterator so it can extract only words used by the language. + // GetRuleSet() returns the rule-sets created in this function. + void SetDefaultLanguage(const std::string& language); + + // Returns a custom rule-set string used by the ICU break iterator. This class + // has two rule-sets, one splits a contraction and the other does not, so we + // can split a concaticated word (e.g. "seven-year-old") into words (e.g. + // "seven", "year", and "old") and check their spellings. The result stirng is + // encoded in UTF-16 since ICU needs UTF-16 strings. + base::string16 GetRuleSet(bool allow_contraction) const; + + // Outputs a character only if it is a word character. (Please read the + // comments in CreateRuleSets() why we need this function.) + bool OutputChar(UChar c, base::string16* output) const; + + private: + // Creates the rule-sets that return words possibly used by the given + // language. Unfortunately, these rule-sets are not perfect and have some + // false-positives. For example, they return combined accent marks even though + // we need English words only. We call OutputCharacter() to filter out such + // false-positive characters. + void CreateRuleSets(const std::string& language); + + // Outputs a character only if it is one used by the given language. These + // functions are called from OutputChar(). + bool OutputArabic(UChar c, base::string16* output) const; + bool OutputHangul(UChar c, base::string16* output) const; + bool OutputHebrew(UChar c, base::string16* output) const; + bool OutputDefault(UChar c, base::string16* output) const; + + // The custom rule-set strings used by ICU break iterator. Since it is not so + // easy to create custom rule-sets from an ISO language code, this class + // saves these rule-set strings created when we set the language. + base::string16 ruleset_allow_contraction_; + base::string16 ruleset_disallow_contraction_; + + // The script code used by this language. + UScriptCode script_code_; + + DISALLOW_COPY_AND_ASSIGN(SpellcheckCharAttribute); +}; + +// A class which extracts words that can be checked for spelling from a +// multi-language string. The ICU word-break iterator does not discard some +// punctuation characters attached to a word. For example, when we set a word +// "_hello_" to a word-break iterator, it just returns "_hello_". Neither does +// it discard characters not used by the language. For example, it returns +// Russian words even though we need English words only. To extract only the +// words that our spellchecker can check their spellings, this class uses custom +// rule-sets created by the SpellcheckCharAttribute class. Also, this class +// normalizes extracted words so our spellchecker can check the spellings of +// words that include ligatures, combined characters, full-width characters, +// etc. This class uses UTF-16 strings as its input and output strings since +// UTF-16 is the native encoding of ICU and avoid unnecessary conversions +// when changing the encoding of this string for our spellchecker. (Chrome can +// use two or more spellcheckers and we cannot assume their encodings.) +// The following snippet is an example that extracts words with this class. +// +// // Creates the language-specific attributes for US English. +// SpellcheckCharAttribute attribute; +// attribute.SetDefaultLanguage("en-US"); +// +// // Set up a SpellcheckWordIterator object which extracts English words, +// // and retrieve them. +// SpellcheckWordIterator iterator; +// base::string16 text(base::UTF8ToUTF16("this is a test.")); +// iterator.Initialize(&attribute, true); +// iterator.SetText(text.c_str(), text_.length()); +// +// base::string16 word; +// int offset; +// int length; +// while (iterator.GetNextWord(&word, &offset, &length)) { +// ... +// } +// +class SpellcheckWordIterator { + public: + enum WordIteratorStatus { + // The end of a sequence of text that the iterator recognizes as characters + // that can form a word. + IS_WORD, + // Non-word characters that the iterator can skip past, such as punctuation, + // whitespace, and characters from another character set. + IS_SKIPPABLE, + // The end of the text that the iterator is going over. + IS_END_OF_TEXT + }; + + SpellcheckWordIterator(); + ~SpellcheckWordIterator(); + + // Initializes a word-iterator object with the language-specific attribute. If + // we need to split contractions and concatenated words, call this function + // with its 'allow_contraction' parameter false. (This function uses lots of + // temporal memory to compile a custom word-break rule into an automaton.) + bool Initialize(const SpellcheckCharAttribute* attribute, + bool allow_contraction); + + // Returns whether this word iterator is initialized. + bool IsInitialized() const; + + // Set text to be iterated. (This text does not have to be NULL-terminated.) + // This function also resets internal state so we can reuse this iterator + // without calling Initialize(). + bool SetText(const base::char16* text, size_t length); + + // Advances |iterator_| through |text_| and gets the current status of the + // word iterator within |text|: + // + // - Returns IS_WORD if the iterator just found the end of a sequence of word + // characters and it was able to normalize the sequence. This stores the + // normalized string into |word_string| and stores the position and length + // into |word_start| and |word_length| respectively. Keep in mind that + // since this function normalizes the output word, the length of + // |word_string| may be different from the |word_length|. Therefore, when + // we call functions that change the input text, such as + // string16::replace(), we need to use |word_start| and |word_length| as + // listed in the following snippet: + // + // while(iterator.GetNextWord(&word, &offset, &length)) + // text.replace(offset, length, word); + // + // - Returns IS_SKIPPABLE if the iterator just found a character that the + // iterator can skip past such as punctuation, whitespace, and characters + // from another character set. This stores the character, position, and + // length into |word_string|, |word_start|, and |word_length| respectively. + // + // - Returns IS_END_OF_TEXT if the iterator has reached the end of |text_|. + SpellcheckWordIterator::WordIteratorStatus + GetNextWord(base::string16* word_string, int* word_start, int* word_length); + + // Releases all the resources attached to this object. + void Reset(); + + private: + // Normalizes a non-terminated string returned from an ICU word-break + // iterator. A word returned from an ICU break iterator may include characters + // not supported by our spellchecker, e.g. ligatures, combining/ characters, + // full-width letters, etc. This function replaces such characters with + // alternative characters supported by our spellchecker. This function also + // calls SpellcheckWordIterator::OutputChar() to filter out false-positive + // characters. + bool Normalize(int input_start, + int input_length, + base::string16* output_string) const; + + // The pointer to the input string from which we are extracting words. + const base::char16* text_; + + // The language-specific attributes used for filtering out non-word + // characters. + const SpellcheckCharAttribute* attribute_; + + // The break iterator. + std::unique_ptr<base::i18n::BreakIterator> iterator_; + + DISALLOW_COPY_AND_ASSIGN(SpellcheckWordIterator); +}; + +#endif // COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_WORDITERATOR_H_ +
diff --git a/components/spellcheck/renderer/spellcheck_worditerator_unittest.cc b/components/spellcheck/renderer/spellcheck_worditerator_unittest.cc new file mode 100644 index 0000000..37ac36d --- /dev/null +++ b/components/spellcheck/renderer/spellcheck_worditerator_unittest.cc
@@ -0,0 +1,508 @@ +// 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 <stddef.h> + +#include <string> +#include <vector> + +#include "base/format_macros.h" +#include "base/i18n/break_iterator.h" +#include "base/macros.h" +#include "base/strings/string_split.h" +#include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" +#include "components/spellcheck/renderer/spellcheck_worditerator.h" +#include "testing/gtest/include/gtest/gtest.h" + +using base::i18n::BreakIterator; +using WordIteratorStatus = SpellcheckWordIterator::WordIteratorStatus; + +namespace { + +struct TestCase { + const char* language; + bool allow_contraction; + const wchar_t* expected_words; +}; + +base::string16 GetRulesForLanguage(const std::string& language) { + SpellcheckCharAttribute attribute; + attribute.SetDefaultLanguage(language); + return attribute.GetRuleSet(true); +} + +WordIteratorStatus GetNextNonSkippableWord(SpellcheckWordIterator* iterator, + base::string16* word_string, + int* word_start, + int* word_length) { + WordIteratorStatus status = SpellcheckWordIterator::IS_SKIPPABLE; + while (status == SpellcheckWordIterator::IS_SKIPPABLE) + status = iterator->GetNextWord(word_string, word_start, word_length); + return status; +} + +} // namespace + +// Tests whether or not our SpellcheckWordIterator can extract words used by the +// specified language from a multi-language text. +TEST(SpellcheckWordIteratorTest, SplitWord) { + // An input text. This text includes words of several languages. (Some words + // are not separated with whitespace characters.) Our SpellcheckWordIterator + // should extract the words used by the specified language from this text and + // normalize them so our spell-checker can check their spellings. If + // characters are found that are not from the specified language the test + // skips them. + const wchar_t kTestText[] = + // Graphic characters + L"!@#$%^&*()" + // Latin (including a contraction character and a ligature). + L"hello:hello a\xFB03x" + // Greek + L"\x03B3\x03B5\x03B9\x03AC\x0020\x03C3\x03BF\x03C5" + // Cyrillic + L"\x0437\x0434\x0440\x0430\x0432\x0441\x0442\x0432" + L"\x0443\x0439\x0442\x0435" + // Hebrew (including niqquds) + L"\x05e9\x05c1\x05b8\x05dc\x05d5\x05b9\x05dd " + // Hebrew words with U+0027 and U+05F3 + L"\x05e6\x0027\x05d9\x05e4\x05e1 \x05e6\x05F3\x05d9\x05e4\x05e1 " + // Hebrew words with U+0022 and U+05F4 + L"\x05e6\x05d4\x0022\x05dc \x05e6\x05d4\x05f4\x05dc " + // Hebrew words enclosed with ASCII quotes. + L"\"\x05e6\x05d4\x0022\x05dc\" '\x05e9\x05c1\x05b8\x05dc\x05d5'" + // Arabic (including vowel marks) + L"\x0627\x064e\x0644\x0633\x064e\x0651\x0644\x0627\x0645\x064f " + L"\x0639\x064e\x0644\x064e\x064a\x0652\x0643\x064f\x0645\x0652 " + // Farsi/Persian (including vowel marks) + // Make sure \u064b - \u0652 are removed. + L"\x0647\x0634\x064e\x0631\x062d " + L"\x0647\x062e\x0648\x0627\x0647 " + L"\x0650\x062f\x0631\x062f " + L"\x0631\x0645\x0627\x0646\x0652 " + L"\x0633\x0631\x0651 " + L"\x0646\x0646\x064e\x062c\x064f\x0633 " + L"\x0627\x0644\x062d\x0645\x062f " + // Also make sure that class "Lm" (the \u0640) is filtered out too. + L"\x062c\x062c\x0640\x062c\x062c" + // Hindi + L"\x0930\x093E\x091C\x0927\x093E\x0928" + // Thai + L"\x0e2a\x0e27\x0e31\x0e2a\x0e14\x0e35\x0020\x0e04" + L"\x0e23\x0e31\x0e1a" + // Hiraganas + L"\x3053\x3093\x306B\x3061\x306F" + // CJKV ideographs + L"\x4F60\x597D" + // Hangul Syllables + L"\xC548\xB155\xD558\xC138\xC694" + // Full-width latin : Hello + L"\xFF28\xFF45\xFF4C\xFF4C\xFF4F " + L"e.g.,"; + + // The languages and expected results used in this test. + static const TestCase kTestCases[] = { + { + // English (keep contraction words) + "en-US", true, L"hello:hello affix Hello e.g" + }, { + // English (split contraction words) + "en-US", false, L"hello hello affix Hello e g" + }, { + // Greek + "el-GR", true, + L"\x03B3\x03B5\x03B9\x03AC\x0020\x03C3\x03BF\x03C5" + }, { + // Russian + "ru-RU", true, + L"\x0437\x0434\x0440\x0430\x0432\x0441\x0442\x0432" + L"\x0443\x0439\x0442\x0435" + }, { + // Hebrew + "he-IL", true, + L"\x05e9\x05dc\x05d5\x05dd " + L"\x05e6\x0027\x05d9\x05e4\x05e1 \x05e6\x05F3\x05d9\x05e4\x05e1 " + L"\x05e6\x05d4\x0022\x05dc \x05e6\x05d4\x05f4\x05dc " + L"\x05e6\x05d4\x0022\x05dc \x05e9\x05dc\x05d5" + }, { + // Arabic + "ar", true, + L"\x0627\x0644\x0633\x0644\x0627\x0645 " + L"\x0639\x0644\x064a\x0643\x0645 " + // Farsi/Persian + L"\x0647\x0634\x0631\x062d " + L"\x0647\x062e\x0648\x0627\x0647 " + L"\x062f\x0631\x062f " + L"\x0631\x0645\x0627\x0646 " + L"\x0633\x0631 " + L"\x0646\x0646\x062c\x0633 " + L"\x0627\x0644\x062d\x0645\x062f " + L"\x062c\x062c\x062c\x062c" + }, { + // Hindi + "hi-IN", true, + L"\x0930\x093E\x091C\x0927\x093E\x0928" + }, { + // Thai + "th-TH", true, + L"\x0e2a\x0e27\x0e31\x0e2a\x0e14\x0e35\x0020\x0e04" + L"\x0e23\x0e31\x0e1a" + }, { + // Korean + "ko-KR", true, + L"\x110b\x1161\x11ab\x1102\x1167\x11bc\x1112\x1161" + L"\x1109\x1166\x110b\x116d" + }, + }; + + for (size_t i = 0; i < arraysize(kTestCases); ++i) { + SCOPED_TRACE(base::StringPrintf("kTestCases[%" PRIuS "]: language=%s", i, + kTestCases[i].language)); + + SpellcheckCharAttribute attributes; + attributes.SetDefaultLanguage(kTestCases[i].language); + + base::string16 input(base::WideToUTF16(kTestText)); + SpellcheckWordIterator iterator; + EXPECT_TRUE(iterator.Initialize(&attributes, + kTestCases[i].allow_contraction)); + EXPECT_TRUE(iterator.SetText(input.c_str(), input.length())); + + std::vector<base::string16> expected_words = base::SplitString( + base::WideToUTF16(kTestCases[i].expected_words), + base::string16(1, ' '), base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); + + base::string16 actual_word; + int actual_start, actual_len; + size_t index = 0; + for (SpellcheckWordIterator::WordIteratorStatus status = + iterator.GetNextWord(&actual_word, &actual_start, &actual_len); + status != SpellcheckWordIterator::IS_END_OF_TEXT; + status = + iterator.GetNextWord(&actual_word, &actual_start, &actual_len)) { + if (status == SpellcheckWordIterator::WordIteratorStatus::IS_SKIPPABLE) + continue; + + EXPECT_TRUE(index < expected_words.size()); + if (index < expected_words.size()) + EXPECT_EQ(expected_words[index], actual_word); + ++index; + } + } +} + +// Tests whether our SpellcheckWordIterator extracts an empty word without +// getting stuck in an infinite loop when inputting a Khmer text. (This is a +// regression test for Issue 46278.) +TEST(SpellcheckWordIteratorTest, RuleSetConsistency) { + SpellcheckCharAttribute attributes; + attributes.SetDefaultLanguage("en-US"); + + const wchar_t kTestText[] = L"\x1791\x17c1\x002e"; + base::string16 input(base::WideToUTF16(kTestText)); + + SpellcheckWordIterator iterator; + EXPECT_TRUE(iterator.Initialize(&attributes, true)); + EXPECT_TRUE(iterator.SetText(input.c_str(), input.length())); + + // When SpellcheckWordIterator uses an inconsistent ICU ruleset, the following + // iterator.GetNextWord() calls get stuck in an infinite loop. Therefore, this + // test succeeds if this call returns without timeouts. + base::string16 actual_word; + int actual_start, actual_len; + WordIteratorStatus status = GetNextNonSkippableWord( + &iterator, &actual_word, &actual_start, &actual_len); + + EXPECT_EQ(SpellcheckWordIterator::WordIteratorStatus::IS_END_OF_TEXT, status); + EXPECT_EQ(0, actual_start); + EXPECT_EQ(0, actual_len); +} + +// Vertify our SpellcheckWordIterator can treat ASCII numbers as word characters +// on LTR languages. On the other hand, it should not treat ASCII numbers as +// word characters on RTL languages because they change the text direction from +// RTL to LTR. +TEST(SpellcheckWordIteratorTest, TreatNumbersAsWordCharacters) { + // A set of a language, a dummy word, and a text direction used in this test. + // For each language, this test splits a dummy word, which consists of ASCII + // numbers and an alphabet of the language, into words. When ASCII numbers are + // treated as word characters, the split word becomes equal to the dummy word. + // Otherwise, the split word does not include ASCII numbers. + static const struct { + const char* language; + const wchar_t* text; + bool left_to_right; + } kTestCases[] = { + { + // English + "en-US", L"0123456789" L"a", true, + }, { + // Greek + "el-GR", L"0123456789" L"\x03B1", true, + }, { + // Russian + "ru-RU", L"0123456789" L"\x0430", true, + }, { + // Hebrew + "he-IL", L"0123456789" L"\x05D0", false, + }, { + // Arabic + "ar", L"0123456789" L"\x0627", false, + }, { + // Hindi + "hi-IN", L"0123456789" L"\x0905", true, + }, { + // Thai + "th-TH", L"0123456789" L"\x0e01", true, + }, { + // Korean + "ko-KR", L"0123456789" L"\x1100\x1161", true, + }, + }; + + for (size_t i = 0; i < arraysize(kTestCases); ++i) { + SCOPED_TRACE(base::StringPrintf("kTestCases[%" PRIuS "]: language=%s", i, + kTestCases[i].language)); + + SpellcheckCharAttribute attributes; + attributes.SetDefaultLanguage(kTestCases[i].language); + + base::string16 input_word(base::WideToUTF16(kTestCases[i].text)); + SpellcheckWordIterator iterator; + EXPECT_TRUE(iterator.Initialize(&attributes, true)); + EXPECT_TRUE(iterator.SetText(input_word.c_str(), input_word.length())); + + base::string16 actual_word; + int actual_start, actual_len; + WordIteratorStatus status = GetNextNonSkippableWord( + &iterator, &actual_word, &actual_start, &actual_len); + + EXPECT_EQ(SpellcheckWordIterator::WordIteratorStatus::IS_WORD, status); + if (kTestCases[i].left_to_right) + EXPECT_EQ(input_word, actual_word); + else + EXPECT_NE(input_word, actual_word); + } +} + +// Verify SpellcheckWordIterator treats typographical apostrophe as a part of +// the word. +TEST(SpellcheckWordIteratorTest, TypographicalApostropheIsPartOfWord) { + static const struct { + const char* language; + const wchar_t* input; + const wchar_t* expected; + } kTestCases[] = { + // Typewriter apostrophe: + {"en-AU", L"you're", L"you're"}, + {"en-CA", L"you're", L"you're"}, + {"en-GB", L"you're", L"you're"}, + {"en-US", L"you're", L"you're"}, + {"en-US", L"!!!!you're", L"you're"}, + // Typographical apostrophe: + {"en-AU", L"you\x2019re", L"you\x2019re"}, + {"en-CA", L"you\x2019re", L"you\x2019re"}, + {"en-GB", L"you\x2019re", L"you\x2019re"}, + {"en-US", L"you\x2019re", L"you\x2019re"}, + {"en-US", L"....you\x2019re", L"you\x2019re"}, + }; + + for (size_t i = 0; i < arraysize(kTestCases); ++i) { + SpellcheckCharAttribute attributes; + attributes.SetDefaultLanguage(kTestCases[i].language); + + base::string16 input_word(base::WideToUTF16(kTestCases[i].input)); + base::string16 expected_word(base::WideToUTF16(kTestCases[i].expected)); + SpellcheckWordIterator iterator; + EXPECT_TRUE(iterator.Initialize(&attributes, true)); + EXPECT_TRUE(iterator.SetText(input_word.c_str(), input_word.length())); + + base::string16 actual_word; + int actual_start, actual_len; + WordIteratorStatus status = GetNextNonSkippableWord( + &iterator, &actual_word, &actual_start, &actual_len); + + EXPECT_EQ(SpellcheckWordIterator::WordIteratorStatus::IS_WORD, status); + EXPECT_EQ(expected_word, actual_word); + EXPECT_LE(0, actual_start); + EXPECT_EQ(expected_word.length(), + static_cast<base::string16::size_type>(actual_len)); + } +} + +TEST(SpellcheckWordIteratorTest, Initialization) { + // Test initialization works when a default language is set. + { + SpellcheckCharAttribute attributes; + attributes.SetDefaultLanguage("en-US"); + + SpellcheckWordIterator iterator; + EXPECT_TRUE(iterator.Initialize(&attributes, true)); + } + + // Test initialization fails when no default language is set. + { + SpellcheckCharAttribute attributes; + + SpellcheckWordIterator iterator; + EXPECT_FALSE(iterator.Initialize(&attributes, true)); + } +} + +// This test uses English rules to check that different character set +// combinations properly find word breaks and skippable characters. +TEST(SpellcheckWordIteratorTest, FindSkippableWordsEnglish) { + // A string containing the English word "foo", followed by two Khmer + // characters, the English word "Can", and then two Russian characters and + // punctuation. + base::string16 text( + base::WideToUTF16(L"foo \x1791\x17C1 Can \x041C\x0438...")); + BreakIterator iter(text, GetRulesForLanguage("en-US")); + ASSERT_TRUE(iter.Init()); + + EXPECT_TRUE(iter.Advance()); + // Finds "foo". + EXPECT_EQ(base::UTF8ToUTF16("foo"), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_WORD_BREAK); + EXPECT_TRUE(iter.Advance()); + // Finds the space and then the Khmer characters. + EXPECT_EQ(base::UTF8ToUTF16(" "), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + EXPECT_EQ(base::WideToUTF16(L"\x1791\x17C1"), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + // Finds the next space and "Can". + EXPECT_EQ(base::UTF8ToUTF16(" "), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + EXPECT_EQ(base::UTF8ToUTF16("Can"), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_WORD_BREAK); + EXPECT_TRUE(iter.Advance()); + // Finds the next space and each Russian character. + EXPECT_EQ(base::UTF8ToUTF16(" "), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + EXPECT_EQ(base::WideToUTF16(L"\x041C"), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + EXPECT_EQ(base::WideToUTF16(L"\x0438"), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + // Finds the periods at the end. + EXPECT_EQ(base::UTF8ToUTF16("."), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + EXPECT_EQ(base::UTF8ToUTF16("."), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + EXPECT_EQ(base::UTF8ToUTF16("."), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_FALSE(iter.Advance()); +} + +// This test uses Russian rules to check that different character set +// combinations properly find word breaks and skippable characters. +TEST(SpellcheckWordIteratorTest, FindSkippableWordsRussian) { + // A string containing punctuation followed by two Russian characters, the + // English word "Can", and then two Khmer characters. + base::string16 text(base::WideToUTF16(L".;\x041C\x0438 Can \x1791\x17C1 ")); + BreakIterator iter(text, GetRulesForLanguage("ru-RU")); + ASSERT_TRUE(iter.Init()); + + EXPECT_TRUE(iter.Advance()); + // Finds the period and semicolon. + EXPECT_EQ(base::UTF8ToUTF16("."), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + EXPECT_EQ(base::UTF8ToUTF16(";"), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + // Finds all the Russian characters. + EXPECT_EQ(base::WideToUTF16(L"\x041C\x0438"), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_WORD_BREAK); + EXPECT_TRUE(iter.Advance()); + // Finds the space and each character in "Can". + EXPECT_EQ(base::UTF8ToUTF16(" "), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + EXPECT_EQ(base::UTF8ToUTF16("C"), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + EXPECT_EQ(base::UTF8ToUTF16("a"), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + EXPECT_EQ(base::UTF8ToUTF16("n"), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + // Finds the next space, the Khmer characters, and the last two spaces. + EXPECT_EQ(base::UTF8ToUTF16(" "), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + EXPECT_EQ(base::WideToUTF16(L"\x1791\x17C1"), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + EXPECT_EQ(base::UTF8ToUTF16(" "), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + EXPECT_EQ(base::UTF8ToUTF16(" "), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_FALSE(iter.Advance()); +} + +// This test uses Khmer rules to check that different character set combinations +// properly find word breaks and skippable characters. Khmer does not use spaces +// between words and uses a dictionary to determine word breaks instead. +TEST(SpellcheckWordIteratorTest, FindSkippableWordsKhmer) { + // A string containing two Russian characters followed by two, three, and + // two-character Khmer words, and then English characters and punctuation. + base::string16 text(base::WideToUTF16( + L"\x041C\x0438 \x178F\x17BE\x179B\x17C4\x1780\x1798\x1780zoo. ,")); + BreakIterator iter(text, GetRulesForLanguage("km")); + ASSERT_TRUE(iter.Init()); + + EXPECT_TRUE(iter.Advance()); + // Finds each Russian character and the space. + EXPECT_EQ(base::WideToUTF16(L"\x041C"), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + EXPECT_EQ(base::WideToUTF16(L"\x0438"), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + EXPECT_EQ(base::UTF8ToUTF16(" "), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + // Finds the first two-character Khmer word. + EXPECT_EQ(base::WideToUTF16(L"\x178F\x17BE"), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_WORD_BREAK); + EXPECT_TRUE(iter.Advance()); + // Finds the three-character Khmer word and then the next two-character word. + // Note: Technically these are two different Khmer words so the Khmer language + // rule should find a break between them but due to the heuristic/statistical + // nature of the Khmer word breaker it does not. + EXPECT_EQ(base::WideToUTF16(L"\x179B\x17C4\x1780\x1798\x1780"), + iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_WORD_BREAK); + EXPECT_TRUE(iter.Advance()); + // Finds each character in "zoo". + EXPECT_EQ(base::UTF8ToUTF16("z"), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + EXPECT_EQ(base::UTF8ToUTF16("o"), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + EXPECT_EQ(base::UTF8ToUTF16("o"), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + // Finds the period, space, and comma. + EXPECT_EQ(base::UTF8ToUTF16("."), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + EXPECT_EQ(base::UTF8ToUTF16(" "), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_TRUE(iter.Advance()); + EXPECT_EQ(base::UTF8ToUTF16(","), iter.GetString()); + EXPECT_EQ(iter.GetWordBreakStatus(), BreakIterator::IS_SKIPPABLE_WORD); + EXPECT_FALSE(iter.Advance()); +}
diff --git a/components/spellcheck/renderer/spelling_engine.h b/components/spellcheck/renderer/spelling_engine.h new file mode 100644 index 0000000..2fb32a8 --- /dev/null +++ b/components/spellcheck/renderer/spelling_engine.h
@@ -0,0 +1,34 @@ +// 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 COMPONENTS_SPELLCHECK_RENDERER_SPELLING_ENGINE_H_ +#define COMPONENTS_SPELLCHECK_RENDERER_SPELLING_ENGINE_H_ + +#include <string> +#include <vector> + +#include "base/files/file.h" +#include "base/strings/string16.h" + +// Creates the platform's "native" spelling engine. +class SpellingEngine* CreateNativeSpellingEngine(); + +// Interface to different spelling engines. +class SpellingEngine { + public: + virtual ~SpellingEngine() {} + + // Initialize spelling engine with browser-side info. Must be called before + // any other functions are called. + virtual void Init(base::File bdict_file) = 0; + virtual bool InitializeIfNeeded() = 0; + virtual bool IsEnabled() = 0; + virtual bool CheckSpelling(const base::string16& word_to_check, int tag) = 0; + virtual void FillSuggestionList( + const base::string16& wrong_word, + std::vector<base::string16>* optional_suggestions) = 0; +}; + +#endif // COMPONENTS_SPELLCHECK_RENDERER_SPELLING_ENGINE_H_ +
diff --git a/components/storage_monitor/media_transfer_protocol_device_observer_linux.cc b/components/storage_monitor/media_transfer_protocol_device_observer_linux.cc index 7d093d9..e983bc1 100644 --- a/components/storage_monitor/media_transfer_protocol_device_observer_linux.cc +++ b/components/storage_monitor/media_transfer_protocol_device_observer_linux.cc
@@ -210,7 +210,7 @@ if (device_id.empty() || storage_label.empty()) return; - DCHECK(!ContainsKey(storage_map_, location)); + DCHECK(!base::ContainsKey(storage_map_, location)); StorageInfo storage_info(device_id, location, storage_label, vendor_name, product_name, 0);
diff --git a/components/storage_monitor/portable_device_watcher_win.cc b/components/storage_monitor/portable_device_watcher_win.cc index 421e1126..1fa2e23 100644 --- a/components/storage_monitor/portable_device_watcher_win.cc +++ b/components/storage_monitor/portable_device_watcher_win.cc
@@ -626,11 +626,11 @@ const StorageObjects& storage_objects = device_details->storage_objects; const base::string16& name = device_details->name; const base::string16& location = device_details->location; - DCHECK(!ContainsKey(device_map_, location)); + DCHECK(!base::ContainsKey(device_map_, location)); for (StorageObjects::const_iterator storage_iter = storage_objects.begin(); storage_iter != storage_objects.end(); ++storage_iter) { const std::string& storage_id = storage_iter->object_persistent_id; - DCHECK(!ContainsKey(storage_map_, storage_id)); + DCHECK(!base::ContainsKey(storage_map_, storage_id)); // Keep track of storage id and storage name to see how often we receive // empty values.
diff --git a/components/storage_monitor/storage_monitor.cc b/components/storage_monitor/storage_monitor.cc index 6f2b23c..beb45fd2c 100644 --- a/components/storage_monitor/storage_monitor.cc +++ b/components/storage_monitor/storage_monitor.cc
@@ -162,7 +162,7 @@ void StorageMonitor::ProcessAttach(const StorageInfo& info) { { base::AutoLock lock(storage_lock_); - if (ContainsKey(storage_map_, info.device_id())) { + if (base::ContainsKey(storage_map_, info.device_id())) { // This can happen if our unique id scheme fails. Ignore the incoming // non-unique attachment. return;
diff --git a/components/storage_monitor/storage_monitor_chromeos.cc b/components/storage_monitor/storage_monitor_chromeos.cc index bc1d7c5..e8b5537 100644 --- a/components/storage_monitor/storage_monitor_chromeos.cc +++ b/components/storage_monitor/storage_monitor_chromeos.cc
@@ -162,7 +162,7 @@ switch (event) { case DiskMountManager::MOUNTING: { - if (ContainsKey(mount_map_, mount_info.mount_path)) { + if (base::ContainsKey(mount_map_, mount_info.mount_path)) { NOTREACHED(); return; } @@ -210,7 +210,7 @@ return false; base::FilePath current = path; - while (!ContainsKey(mount_map_, current.value()) && + while (!base::ContainsKey(mount_map_, current.value()) && current != current.DirName()) { current = current.DirName(); } @@ -280,7 +280,7 @@ bool has_dcim) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (ContainsKey(mount_map_, mount_info.mount_path)) { + if (base::ContainsKey(mount_map_, mount_info.mount_path)) { // CheckExistingMountPointsOnUIThread() added the mount point information // in the map before the device attached handler is called. Therefore, an // entry for the device already exists in the map.
diff --git a/components/storage_monitor/storage_monitor_linux.cc b/components/storage_monitor/storage_monitor_linux.cc index 1441eaa5..aba36bbd 100644 --- a/components/storage_monitor/storage_monitor_linux.cc +++ b/components/storage_monitor/storage_monitor_linux.cc
@@ -294,7 +294,8 @@ return false; base::FilePath current = path; - while (!ContainsKey(mount_info_map_, current) && current != current.DirName()) + while (!base::ContainsKey(mount_info_map_, current) && + current != current.DirName()) current = current.DirName(); MountMap::const_iterator mount_info = mount_info_map_.find(current); @@ -468,7 +469,7 @@ bool StorageMonitorLinux::IsDeviceAlreadyMounted( const base::FilePath& mount_device) const { DCHECK_CURRENTLY_ON(BrowserThread::UI); - return ContainsKey(mount_priority_map_, mount_device); + return base::ContainsKey(mount_priority_map_, mount_device); } void StorageMonitorLinux::HandleDeviceMountedMultipleTimes(
diff --git a/components/storage_monitor/transient_device_ids.cc b/components/storage_monitor/transient_device_ids.cc index 3f19302..fdbcecf 100644 --- a/components/storage_monitor/transient_device_ids.cc +++ b/components/storage_monitor/transient_device_ids.cc
@@ -21,11 +21,11 @@ const std::string& device_id) { DCHECK(thread_checker_.CalledOnValidThread()); - if (!ContainsKey(device_id_map_, device_id)) { + if (!base::ContainsKey(device_id_map_, device_id)) { std::string transient_id; do { transient_id = base::GenerateGUID(); - } while (ContainsKey(transient_id_map_, transient_id)); + } while (base::ContainsKey(transient_id_map_, transient_id)); device_id_map_[device_id] = transient_id; transient_id_map_[transient_id] = device_id;
diff --git a/components/storage_monitor/volume_mount_watcher_win.cc b/components/storage_monitor/volume_mount_watcher_win.cc index 2ae52b5..49ccccb 100644 --- a/components/storage_monitor/volume_mount_watcher_win.cc +++ b/components/storage_monitor/volume_mount_watcher_win.cc
@@ -372,7 +372,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); for (size_t i = 0; i < removable_devices.size(); i++) { - if (ContainsKey(pending_device_checks_, removable_devices[i])) + if (base::ContainsKey(pending_device_checks_, removable_devices[i])) continue; pending_device_checks_.insert(removable_devices[i]); device_info_task_runner_->PostTask(
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc b/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc index d8ab2ca51..1d7fa11 100644 --- a/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc +++ b/components/subresource_filter/content/browser/content_subresource_filter_driver_factory.cc
@@ -112,9 +112,7 @@ std::unique_ptr<ContentSubresourceFilterDriver> driver) { auto iterator_and_inserted = frame_drivers_.insert(std::make_pair(render_frame_host, nullptr)); - if (iterator_and_inserted.second) { - iterator_and_inserted.first->second = std::move(driver); - } + iterator_and_inserted.first->second = std::move(driver); } ContentSubresourceFilterDriver* @@ -149,8 +147,10 @@ ContentSubresourceFilterDriver* driver = DriverFromFrameHost(render_frame_host); driver->ActivateForProvisionalLoad(GetMaximumActivationState()); - if (GetMaximumActivationState() == ActivationState::ENABLED) + if (GetMaximumActivationState() == ActivationState::ENABLED && + render_frame_host == web_contents()->GetMainFrame()) { client_->ToggleNotificationVisibility(true /* visible */); + } } } // namespace subresource_filter
diff --git a/components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc b/components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc index 5a45e84..929b98a 100644 --- a/components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc +++ b/components/subresource_filter/content/browser/content_subresource_filter_driver_factory_unittest.cc
@@ -51,20 +51,27 @@ ContentSubresourceFilterDriverFactoryTest() {} ~ContentSubresourceFilterDriverFactoryTest() override {} - // content::RenderViewHostTestHarness: + // content::RenderViewHostImplTestHarness: void SetUp() override { RenderViewHostTestHarness::SetUp(); client_ = new MockSubresourceFilterClient(); ContentSubresourceFilterDriverFactory::CreateForWebContents( web_contents(), base::WrapUnique(client())); - driver_ = new MockSubresourceFilterDriver(web_contents()->GetMainFrame()); - factory()->SetDriverForFrameHostForTesting(main_rfh(), - base::WrapUnique(driver())); + driver_ = new MockSubresourceFilterDriver(main_rfh()); + SetDriverForFrameHostForTesting(main_rfh(), driver()); } - void SendActivationStateAndPromptUser() { - factory()->SendActivationStateAndPromptUser(main_rfh()); + void SendActivationStateAndPromptUser( + content::RenderFrameHost* render_frame_host) { + factory()->SendActivationStateAndPromptUser(render_frame_host); + } + + void SetDriverForFrameHostForTesting( + content::RenderFrameHost* render_frame_host, + ContentSubresourceFilterDriver* driver) { + factory()->SetDriverForFrameHostForTesting(render_frame_host, + base::WrapUnique(driver)); } ContentSubresourceFilterDriverFactory* factory() { @@ -218,7 +225,7 @@ base::FeatureList::OVERRIDE_DISABLE_FEATURE, kActivationStateEnabled, kActivationScopeActivationList); EXPECT_CALL(*client(), ToggleNotificationVisibility(::testing::_)).Times(0); - SendActivationStateAndPromptUser(); + SendActivationStateAndPromptUser(main_rfh()); ::testing::Mock::VerifyAndClearExpectations(client()); } @@ -229,7 +236,7 @@ base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationStateDryRun, kActivationScopeActivationList); EXPECT_CALL(*client(), ToggleNotificationVisibility(::testing::_)).Times(0); - SendActivationStateAndPromptUser(); + SendActivationStateAndPromptUser(main_rfh()); ::testing::Mock::VerifyAndClearExpectations(client()); } @@ -240,10 +247,34 @@ base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationStateEnabled, kActivationScopeActivationList); EXPECT_CALL(*client(), ToggleNotificationVisibility(true)).Times(1); - SendActivationStateAndPromptUser(); + SendActivationStateAndPromptUser(main_rfh()); ::testing::Mock::VerifyAndClearExpectations(client()); } +TEST_F(ContentSubresourceFilterDriverFactoryTest, + ActivationPromptNotShownForNonMainFrames) { + base::FieldTrialList field_trial_list(nullptr); + testing::ScopedSubresourceFilterFeatureToggle scoped_feature_toggle( + base::FeatureList::OVERRIDE_ENABLE_FEATURE, kActivationStateEnabled, + kActivationScopeActivationList); + // Add a subframe. + content::RenderFrameHostTester* rfh_tester = + content::RenderFrameHostTester::For(main_rfh()); + rfh_tester->InitializeRenderFrameIfNeeded(); + content::RenderFrameHost* subframe_rfh = rfh_tester->AppendChild("Child"); + + MockSubresourceFilterDriver* subframe_driver = + new MockSubresourceFilterDriver(subframe_rfh); + SetDriverForFrameHostForTesting(subframe_rfh, subframe_driver); + + EXPECT_CALL(*subframe_driver, ActivateForProvisionalLoad(::testing::_)) + .Times(1); + EXPECT_CALL(*client(), ToggleNotificationVisibility(true)).Times(0); + SendActivationStateAndPromptUser(subframe_rfh); + ::testing::Mock::VerifyAndClearExpectations(client()); + ::testing::Mock::VerifyAndClearExpectations(subframe_driver); +} + INSTANTIATE_TEST_CASE_P( NoSonEngHit, ContentSubresourceFilterDriverFactoryThreatTypeTest,
diff --git a/components/subresource_filter/content/renderer/subresource_filter_agent.cc b/components/subresource_filter/content/renderer/subresource_filter_agent.cc index 0b2d452..b830e71 100644 --- a/components/subresource_filter/content/renderer/subresource_filter_agent.cc +++ b/components/subresource_filter/content/renderer/subresource_filter_agent.cc
@@ -33,10 +33,15 @@ std::vector<GURL> SubresourceFilterAgent::GetAncestorDocumentURLs() { std::vector<GURL> urls; - for (blink::WebFrame* frame = render_frame()->GetWebFrame(); frame; - frame = frame->parent()) { + // As a temporary workaround for --isolate-extensions, ignore the ancestor + // hierarchy after crossing an extension/non-extension boundary. This, + // however, will not be a satisfactory solution for OOPIF in general. + // See: https://crbug.com/637415. + blink::WebFrame* frame = render_frame()->GetWebFrame(); + do { urls.push_back(frame->document().url()); - } + frame = frame->parent(); + } while (frame && frame->isWebLocalFrame()); return urls; }
diff --git a/components/suggestions.gypi b/components/suggestions.gypi index f5fd5fc3..e960d74e 100644 --- a/components/suggestions.gypi +++ b/components/suggestions.gypi
@@ -20,9 +20,9 @@ 'components.gyp:image_fetcher', 'components.gyp:keyed_service_core', 'components.gyp:pref_registry', - 'components.gyp:sync_driver', 'components.gyp:variations', 'components.gyp:variations_net', + 'sync.gyp:sync', ], 'sources': [ 'suggestions/blacklist_store.cc',
diff --git a/components/suggestions/BUILD.gn b/components/suggestions/BUILD.gn index 2dd952f..174726a 100644 --- a/components/suggestions/BUILD.gn +++ b/components/suggestions/BUILD.gn
@@ -33,7 +33,7 @@ "//components/leveldb_proto", "//components/pref_registry", "//components/signin/core/browser", - "//components/sync_driver:sync_driver", + "//components/sync", "//components/variations", "//components/variations/net", "//google_apis", @@ -61,7 +61,7 @@ "//components/leveldb_proto:test_support", "//components/pref_registry:test_support", "//components/signin/core/browser:test_support", - "//components/sync_driver:test_support", + "//components/sync:test_support_sync_driver", "//net:test_support", "//testing/gmock", "//testing/gtest",
diff --git a/components/suggestions/DEPS b/components/suggestions/DEPS index c3f0589..78c8433 100644 --- a/components/suggestions/DEPS +++ b/components/suggestions/DEPS
@@ -7,7 +7,7 @@ "+components/pref_registry", "+components/prefs", "+components/signin/core/browser", - "+components/sync_driver", + "+components/sync/driver", "+components/variations", "+google_apis", "+net",
diff --git a/components/suggestions/suggestions_service.cc b/components/suggestions/suggestions_service.cc index cdf80f3d..01c20a2 100644 --- a/components/suggestions/suggestions_service.cc +++ b/components/suggestions/suggestions_service.cc
@@ -23,7 +23,7 @@ #include "components/suggestions/blacklist_store.h" #include "components/suggestions/image_manager.h" #include "components/suggestions/suggestions_store.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_service.h" #include "components/variations/net/variations_http_headers.h" #include "google_apis/gaia/gaia_constants.h" #include "google_apis/gaia/oauth2_token_service.h"
diff --git a/components/suggestions/suggestions_service.h b/components/suggestions/suggestions_service.h index d29f15ed..8118aa47 100644 --- a/components/suggestions/suggestions_service.h +++ b/components/suggestions/suggestions_service.h
@@ -20,7 +20,7 @@ #include "base/time/time.h" #include "components/keyed_service/core/keyed_service.h" #include "components/suggestions/proto/suggestions.pb.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/sync_service_observer.h" #include "net/url_request/url_fetcher_delegate.h" #include "url/gurl.h"
diff --git a/components/suggestions/suggestions_service_unittest.cc b/components/suggestions/suggestions_service_unittest.cc index c44a118..6066e7e 100644 --- a/components/suggestions/suggestions_service_unittest.cc +++ b/components/suggestions/suggestions_service_unittest.cc
@@ -19,8 +19,8 @@ #include "components/suggestions/image_manager.h" #include "components/suggestions/proto/suggestions.pb.h" #include "components/suggestions/suggestions_store.h" -#include "components/sync_driver/fake_sync_service.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/fake_sync_service.h" +#include "components/sync/driver/sync_service.h" #include "net/base/escape.h" #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h"
diff --git a/components/sync.gyp b/components/sync.gyp index b04de1b8..b2f474b 100644 --- a/components/sync.gyp +++ b/components/sync.gyp
@@ -56,10 +56,18 @@ '../google_apis/google_apis.gyp:google_apis', '../net/net.gyp:net', '../sql/sql.gyp:sql', + '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation', + '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_proto_cpp', '../third_party/leveldatabase/leveldatabase.gyp:leveldatabase', '../third_party/protobuf/protobuf.gyp:protobuf_lite', '../third_party/zlib/zlib.gyp:zlib', '../url/url.gyp:url_lib', + 'components.gyp:data_use_measurement_core', + 'components.gyp:invalidation_public', + 'components.gyp:metrics', + 'components.gyp:os_crypt', + 'components.gyp:signin_core_browser', + 'components.gyp:version_info', 'attachment_store_proto', 'sync_proto', ], @@ -479,6 +487,121 @@ 'sync/base/nigori.h', 'sync/base/time.cc', 'sync/base/time.h', + 'sync/driver/about_sync_util.cc', + 'sync/driver/about_sync_util.h', + 'sync/driver/backend_data_type_configurer.cc', + 'sync/driver/backend_data_type_configurer.h', + 'sync/driver/backend_migrator.cc', + 'sync/driver/backend_migrator.h', + 'sync/driver/change_processor.cc', + 'sync/driver/change_processor.h', + 'sync/driver/data_type_controller.cc', + 'sync/driver/data_type_controller.h', + 'sync/driver/data_type_encryption_handler.cc', + 'sync/driver/data_type_encryption_handler.h', + 'sync/driver/data_type_manager.cc', + 'sync/driver/data_type_manager.h', + 'sync/driver/data_type_manager_impl.cc', + 'sync/driver/data_type_manager_impl.h', + 'sync/driver/data_type_manager_observer.h', + 'sync/driver/data_type_status_table.cc', + 'sync/driver/data_type_status_table.h', + 'sync/driver/device_count_metrics_provider.cc', + 'sync/driver/device_count_metrics_provider.h', + 'sync/driver/device_info.cc', + 'sync/driver/device_info.h', + 'sync/driver/device_info_data_type_controller.cc', + 'sync/driver/device_info_data_type_controller.h', + 'sync/driver/device_info_service.cc', + 'sync/driver/device_info_service.h', + 'sync/driver/device_info_sync_service.cc', + 'sync/driver/device_info_sync_service.h', + 'sync/driver/device_info_tracker.h', + 'sync/driver/device_info_util.cc', + 'sync/driver/device_info_util.h', + 'sync/driver/directory_data_type_controller.cc', + 'sync/driver/directory_data_type_controller.h', + 'sync/driver/frontend_data_type_controller.cc', + 'sync/driver/frontend_data_type_controller.h', + 'sync/driver/generic_change_processor.cc', + 'sync/driver/generic_change_processor.h', + 'sync/driver/generic_change_processor_factory.cc', + 'sync/driver/generic_change_processor_factory.h', + 'sync/driver/glue/browser_thread_model_worker.cc', + 'sync/driver/glue/browser_thread_model_worker.h', + 'sync/driver/glue/chrome_report_unrecoverable_error.cc', + 'sync/driver/glue/chrome_report_unrecoverable_error.h', + 'sync/driver/glue/sync_backend_host.cc', + 'sync/driver/glue/sync_backend_host.h', + 'sync/driver/glue/sync_backend_host_core.cc', + 'sync/driver/glue/sync_backend_host_core.h', + 'sync/driver/glue/sync_backend_host_impl.cc', + 'sync/driver/glue/sync_backend_host_impl.h', + 'sync/driver/glue/sync_backend_registrar.cc', + 'sync/driver/glue/sync_backend_registrar.h', + 'sync/driver/glue/ui_model_worker.cc', + 'sync/driver/glue/ui_model_worker.h', + 'sync/driver/invalidation_adapter.cc', + 'sync/driver/invalidation_adapter.h', + 'sync/driver/invalidation_helper.cc', + 'sync/driver/invalidation_helper.h', + 'sync/driver/local_device_info_provider.h', + 'sync/driver/local_device_info_provider_impl.cc', + 'sync/driver/local_device_info_provider_impl.h', + 'sync/driver/model_association_manager.cc', + 'sync/driver/model_association_manager.h', + 'sync/driver/model_associator.h', + 'sync/driver/non_blocking_data_type_controller.cc', + 'sync/driver/non_blocking_data_type_controller.h', + 'sync/driver/non_ui_data_type_controller.cc', + 'sync/driver/non_ui_data_type_controller.h', + 'sync/driver/non_ui_model_type_controller.cc', + 'sync/driver/non_ui_model_type_controller.h', + 'sync/driver/pref_names.cc', + 'sync/driver/pref_names.h', + 'sync/driver/profile_sync_auth_provider.cc', + 'sync/driver/profile_sync_auth_provider.h', + 'sync/driver/protocol_event_observer.cc', + 'sync/driver/protocol_event_observer.h', + 'sync/driver/proxy_data_type_controller.cc', + 'sync/driver/proxy_data_type_controller.h', + 'sync/driver/shared_change_processor.cc', + 'sync/driver/shared_change_processor.h', + 'sync/driver/shared_change_processor_ref.cc', + 'sync/driver/shared_change_processor_ref.h', + 'sync/driver/signin_manager_wrapper.cc', + 'sync/driver/signin_manager_wrapper.h', + 'sync/driver/startup_controller.cc', + 'sync/driver/startup_controller.h', + 'sync/driver/sync_api_component_factory.h', + 'sync/driver/sync_client.cc', + 'sync/driver/sync_client.h', + 'sync/driver/sync_driver_switches.cc', + 'sync/driver/sync_driver_switches.h', + 'sync/driver/sync_error_controller.cc', + 'sync/driver/sync_error_controller.h', + 'sync/driver/sync_frontend.cc', + 'sync/driver/sync_frontend.h', + 'sync/driver/sync_prefs.cc', + 'sync/driver/sync_prefs.h', + 'sync/driver/sync_service.cc', + 'sync/driver/sync_service.h', + 'sync/driver/sync_service_observer.cc', + 'sync/driver/sync_service_observer.h', + 'sync/driver/sync_service_utils.cc', + 'sync/driver/sync_service_utils.h', + 'sync/driver/sync_stopped_reporter.cc', + 'sync/driver/sync_stopped_reporter.h', + 'sync/driver/sync_type_preference_provider.h', + 'sync/driver/sync_util.cc', + 'sync/driver/sync_util.h', + 'sync/driver/system_encryptor.cc', + 'sync/driver/system_encryptor.h', + 'sync/driver/ui_data_type_controller.cc', + 'sync/driver/ui_data_type_controller.h', + 'sync/driver/ui_model_type_controller.cc', + 'sync/driver/ui_model_type_controller.h', + 'sync/driver/user_selectable_sync_type.h', ], 'conditions': [ @@ -507,6 +630,16 @@ 'sync/android/sync_jni_registrar.h', ], }], + ['configuration_policy==1', { + 'dependencies': [ + 'components.gyp:policy', + 'components.gyp:policy_component', + ], + 'sources': [ + 'sync/driver/sync_policy_handler.cc', + 'sync/driver/sync_policy_handler.h', + ], + }], ], }, {
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn index 0cc8cce68..39d42eb 100644 --- a/components/sync/BUILD.gn +++ b/components/sync/BUILD.gn
@@ -2,19 +2,12 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/buildflag_header.gni") import("//build/config/features.gni") import("//components/sync/protocol/protocol_sources.gni") import("//testing/test.gni") -component("sync") { - public_deps = [ - ":sync_core", - "//components/sync/protocol", - ] -} - -# GYP version: components/sync.gyp:sync_core -source_set("sync_core") { +static_library("sync") { sources = [ "api/attachments/attachment.cc", "api/attachments/attachment.h", @@ -99,7 +92,6 @@ "base/proto_value_ptr.h", "base/stop_source.h", "base/sync_db_util.h", - "base/sync_export.h", "base/sync_string_conversions.cc", "base/sync_string_conversions.h", "base/syncer_error.cc", @@ -227,6 +219,119 @@ "core_impl/syncapi_internal.h", "core_impl/syncapi_server_connection_manager.cc", "core_impl/syncapi_server_connection_manager.h", + "driver/about_sync_util.cc", + "driver/about_sync_util.h", + "driver/backend_data_type_configurer.cc", + "driver/backend_data_type_configurer.h", + "driver/backend_migrator.cc", + "driver/backend_migrator.h", + "driver/change_processor.cc", + "driver/change_processor.h", + "driver/data_type_controller.cc", + "driver/data_type_controller.h", + "driver/data_type_encryption_handler.cc", + "driver/data_type_encryption_handler.h", + "driver/data_type_manager.cc", + "driver/data_type_manager.h", + "driver/data_type_manager_impl.cc", + "driver/data_type_manager_impl.h", + "driver/data_type_manager_observer.h", + "driver/data_type_status_table.cc", + "driver/data_type_status_table.h", + "driver/device_count_metrics_provider.cc", + "driver/device_count_metrics_provider.h", + "driver/device_info.cc", + "driver/device_info.h", + "driver/device_info_data_type_controller.cc", + "driver/device_info_data_type_controller.h", + "driver/device_info_service.cc", + "driver/device_info_service.h", + "driver/device_info_sync_service.cc", + "driver/device_info_sync_service.h", + "driver/device_info_tracker.h", + "driver/device_info_util.cc", + "driver/device_info_util.h", + "driver/directory_data_type_controller.cc", + "driver/directory_data_type_controller.h", + "driver/frontend_data_type_controller.cc", + "driver/frontend_data_type_controller.h", + "driver/generic_change_processor.cc", + "driver/generic_change_processor.h", + "driver/generic_change_processor_factory.cc", + "driver/generic_change_processor_factory.h", + "driver/glue/browser_thread_model_worker.cc", + "driver/glue/browser_thread_model_worker.h", + "driver/glue/chrome_report_unrecoverable_error.cc", + "driver/glue/chrome_report_unrecoverable_error.h", + "driver/glue/sync_backend_host.cc", + "driver/glue/sync_backend_host.h", + "driver/glue/sync_backend_host_core.cc", + "driver/glue/sync_backend_host_core.h", + "driver/glue/sync_backend_host_impl.cc", + "driver/glue/sync_backend_host_impl.h", + "driver/glue/sync_backend_registrar.cc", + "driver/glue/sync_backend_registrar.h", + "driver/glue/ui_model_worker.cc", + "driver/glue/ui_model_worker.h", + "driver/invalidation_adapter.cc", + "driver/invalidation_adapter.h", + "driver/invalidation_helper.cc", + "driver/invalidation_helper.h", + "driver/local_device_info_provider.h", + "driver/local_device_info_provider_impl.cc", + "driver/local_device_info_provider_impl.h", + "driver/model_association_manager.cc", + "driver/model_association_manager.h", + "driver/model_associator.h", + "driver/non_blocking_data_type_controller.cc", + "driver/non_blocking_data_type_controller.h", + "driver/non_ui_data_type_controller.cc", + "driver/non_ui_data_type_controller.h", + "driver/non_ui_model_type_controller.cc", + "driver/non_ui_model_type_controller.h", + "driver/pref_names.cc", + "driver/pref_names.h", + "driver/protocol_event_observer.cc", + "driver/protocol_event_observer.h", + "driver/proxy_data_type_controller.cc", + "driver/proxy_data_type_controller.h", + "driver/shared_change_processor.cc", + "driver/shared_change_processor.h", + "driver/shared_change_processor_ref.cc", + "driver/shared_change_processor_ref.h", + "driver/signin_manager_wrapper.cc", + "driver/signin_manager_wrapper.h", + "driver/startup_controller.cc", + "driver/startup_controller.h", + "driver/sync_api_component_factory.h", + "driver/sync_client.cc", + "driver/sync_client.h", + "driver/sync_driver_switches.cc", + "driver/sync_driver_switches.h", + "driver/sync_error_controller.cc", + "driver/sync_error_controller.h", + "driver/sync_frontend.cc", + "driver/sync_frontend.h", + "driver/sync_prefs.cc", + "driver/sync_prefs.h", + "driver/sync_service.cc", + "driver/sync_service.h", + "driver/sync_service_observer.cc", + "driver/sync_service_observer.h", + "driver/sync_service_utils.cc", + "driver/sync_service_utils.h", + "driver/sync_stopped_reporter.cc", + "driver/sync_stopped_reporter.h", + "driver/sync_type_preference_provider.h", + "driver/sync_util.cc", + "driver/sync_util.h", + "driver/system_encryptor.cc", + "driver/system_encryptor.h", + "driver/ui_data_type_controller.cc", + "driver/ui_data_type_controller.h", + "driver/ui_model_type_controller.cc", + "driver/ui_model_type_controller.h", + "driver/user_selectable_sync_type.h", "engine/events/clear_server_data_request_event.cc", "engine/events/clear_server_data_request_event.h", "engine/events/clear_server_data_response_event.cc", @@ -430,16 +535,25 @@ public_deps = [ "//components/sync/core_impl/attachments/proto", - "//net", + "//components/sync/protocol", ] deps = [ "//base", "//base:i18n", "//base/third_party/dynamic_annotations", - "//components/sync/protocol", + "//components/data_use_measurement/core", + "//components/invalidation/public", + "//components/metrics", + "//components/os_crypt", + "//components/pref_registry", + "//components/prefs", + "//components/signin/core/browser", + "//components/version_info", "//crypto", "//google_apis", + "//net", "//sql", + "//third_party/cacheinvalidation", "//third_party/leveldatabase", "//third_party/zlib", "//url", @@ -467,7 +581,17 @@ ] } - defines = [ "SYNC_IMPLEMENTATION" ] + if (enable_configuration_policy) { + sources += [ + "driver/sync_policy_handler.cc", + "driver/sync_policy_handler.h", + ] + deps += [ + "//components/policy", + "//components/policy:policy_component", + ] + } + configs += [ "//build/config/compiler:wexit_time_destructors" ] } @@ -623,6 +747,52 @@ ] } +static_library("test_support_sync_driver") { + testonly = true + sources = [ + "driver/change_processor_mock.cc", + "driver/change_processor_mock.h", + "driver/data_type_controller_mock.cc", + "driver/data_type_controller_mock.h", + "driver/data_type_manager_mock.cc", + "driver/data_type_manager_mock.h", + "driver/fake_data_type_controller.cc", + "driver/fake_data_type_controller.h", + "driver/fake_generic_change_processor.cc", + "driver/fake_generic_change_processor.h", + "driver/fake_sync_client.cc", + "driver/fake_sync_client.h", + "driver/fake_sync_service.cc", + "driver/fake_sync_service.h", + "driver/frontend_data_type_controller_mock.cc", + "driver/frontend_data_type_controller_mock.h", + "driver/glue/sync_backend_host_mock.cc", + "driver/glue/sync_backend_host_mock.h", + "driver/local_device_info_provider_mock.cc", + "driver/local_device_info_provider_mock.h", + "driver/model_associator_mock.cc", + "driver/model_associator_mock.h", + "driver/non_ui_data_type_controller_mock.cc", + "driver/non_ui_data_type_controller_mock.h", + "driver/sync_api_component_factory_mock.cc", + "driver/sync_api_component_factory_mock.h", + ] + + public_deps = [ + "//components/sync", + ] + + deps = [ + ":test_support_sync_core_impl", + "//base", + "//components/syncable_prefs:test_support", + "//components/version_info", + "//google_apis", + "//testing/gmock", + "//testing/gtest", + ] +} + source_set("unit_tests") { testonly = true sources = [ @@ -677,6 +847,33 @@ "core_impl/sync_encryption_handler_impl_unittest.cc", "core_impl/sync_manager_impl_unittest.cc", "core_impl/syncapi_server_connection_manager_unittest.cc", + "driver/about_sync_util_unittest.cc", + "driver/backend_migrator_unittest.cc", + "driver/data_type_manager_impl_unittest.cc", + "driver/device_count_metrics_provider_unittest.cc", + "driver/device_info_data_type_controller_unittest.cc", + "driver/device_info_service_unittest.cc", + "driver/device_info_sync_service_unittest.cc", + "driver/device_info_util_unittest.cc", + "driver/frontend_data_type_controller_unittest.cc", + "driver/generic_change_processor_unittest.cc", + "driver/glue/browser_thread_model_worker_unittest.cc", + "driver/glue/sync_backend_host_impl_unittest.cc", + "driver/glue/sync_backend_registrar_unittest.cc", + "driver/glue/ui_model_worker_unittest.cc", + "driver/local_device_info_provider_unittest.cc", + "driver/model_association_manager_unittest.cc", + "driver/non_blocking_data_type_controller_unittest.cc", + "driver/non_ui_data_type_controller_unittest.cc", + "driver/non_ui_model_type_controller_unittest.cc", + "driver/shared_change_processor_unittest.cc", + "driver/startup_controller_unittest.cc", + "driver/sync_prefs_unittest.cc", + "driver/sync_stopped_reporter_unittest.cc", + "driver/sync_util_unittest.cc", + "driver/system_encryptor_unittest.cc", + "driver/ui_data_type_controller_unittest.cc", + "driver/ui_model_type_controller_unittest.cc", "engine/model_safe_worker_unittest.cc", "engine_impl/apply_control_data_updates_unittest.cc", "engine_impl/backoff_delay_provider_unittest.cc", @@ -725,9 +922,18 @@ ":test_support_sync_api", ":test_support_sync_core", ":test_support_sync_core_impl", + ":test_support_sync_driver", "//base", + "//base/test:test_support", + "//components/invalidation/impl", + "//components/os_crypt:test_support", + "//components/pref_registry:test_support", + "//components/prefs:test_support", + "//components/signin/core/browser:test_support", "//components/sync", - "//components/sync/protocol", + "//components/syncable_prefs", + "//components/syncable_prefs:test_support", + "//components/version_info", "//google_apis", "//google_apis:test_support", "//net", @@ -738,6 +944,7 @@ "//testing/gtest", "//third_party/leveldatabase", "//third_party/protobuf:protobuf_lite", + "//url", ] if (is_chromeos) { @@ -749,6 +956,14 @@ sources -= [ "core/http_bridge_unittest.cc" ] } + if (enable_configuration_policy) { + sources += [ "driver/sync_policy_handler_unittest.cc" ] + deps += [ + "//components/policy", + "//components/policy:policy_component", + ] + } + defines = [ "SYNC_TEST" ] } @@ -901,10 +1116,9 @@ ] deps = [ ":fake_server_jni", - ":sync_core", + ":sync", ":test_support_sync_fake_server", "//base", - "//components/sync/protocol:protocol", "//testing/gtest", "//url:url", ]
diff --git a/components/sync/android/java/src/org/chromium/components/sync/signin/AccountManagerDelegate.java b/components/sync/android/java/src/org/chromium/components/sync/signin/AccountManagerDelegate.java index c98f33bb..b23b89a3 100644 --- a/components/sync/android/java/src/org/chromium/components/sync/signin/AccountManagerDelegate.java +++ b/components/sync/android/java/src/org/chromium/components/sync/signin/AccountManagerDelegate.java
@@ -6,6 +6,7 @@ import android.accounts.Account; import android.accounts.AuthenticatorDescription; +import android.app.Activity; import org.chromium.base.Callback; @@ -52,4 +53,14 @@ * Check whether the {@code account} has all the features listed in {@code features}. */ void hasFeatures(Account account, String[] features, Callback<Boolean> callback); + + /** + * Asks the user to enter a new password for an account, updating the saved credentials for the + * account. + * @param account The {@link Account} for which the update is requested. + * @param activity The {@link Activity} context to use for launching a new authenticator-defined + * sub-Activity to prompt the user to enter a password. + * @param callback The callback to indicate whether update is succeed or not. + */ + void updateCredentials(Account account, Activity activity, Callback<Boolean> callback); }
diff --git a/components/sync/android/java/src/org/chromium/components/sync/signin/AccountManagerHelper.java b/components/sync/android/java/src/org/chromium/components/sync/signin/AccountManagerHelper.java index 76a725c..aa3152d 100644 --- a/components/sync/android/java/src/org/chromium/components/sync/signin/AccountManagerHelper.java +++ b/components/sync/android/java/src/org/chromium/components/sync/signin/AccountManagerHelper.java
@@ -7,6 +7,7 @@ import android.Manifest; import android.accounts.Account; import android.accounts.AuthenticatorDescription; +import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; import android.os.AsyncTask; @@ -358,6 +359,14 @@ mAccountManager.hasFeatures(account, features, callback); } + /** + * Asks the user to enter a new password for an account, updating the saved credentials for the + * account. + */ + public void updateCredentials(Account account, Activity activity, Callback<Boolean> callback) { + mAccountManager.updateCredentials(account, activity, callback); + } + private interface AuthTask<T> { T run() throws AuthException; void onSuccess(T result);
diff --git a/components/sync/android/java/src/org/chromium/components/sync/signin/SystemAccountManagerDelegate.java b/components/sync/android/java/src/org/chromium/components/sync/signin/SystemAccountManagerDelegate.java index 28a253aa..60821351 100644 --- a/components/sync/android/java/src/org/chromium/components/sync/signin/SystemAccountManagerDelegate.java +++ b/components/sync/android/java/src/org/chromium/components/sync/signin/SystemAccountManagerDelegate.java
@@ -11,8 +11,10 @@ import android.accounts.AuthenticatorDescription; import android.accounts.AuthenticatorException; import android.accounts.OperationCanceledException; +import android.app.Activity; import android.content.Context; import android.os.AsyncTask; +import android.os.Bundle; import android.os.SystemClock; import com.google.android.gms.auth.GoogleAuthException; @@ -146,4 +148,42 @@ if (!LibraryLoader.isInitialized()) return; RecordHistogram.recordTimesHistogram(histogramName, elapsedMs, TimeUnit.MILLISECONDS); } + + @Override + public void updateCredentials( + Account account, Activity activity, final Callback<Boolean> callback) { + ThreadUtils.assertOnUiThread(); + if (!AccountManagerHelper.get(mApplicationContext).hasGetAccountsPermission()) { + ThreadUtils.postOnUiThread(new Runnable() { + @Override + public void run() { + callback.onResult(false); + } + }); + return; + } + + mAccountManager.updateCredentials( + account, "android", null, activity, new AccountManagerCallback<Bundle>() { + @Override + public void run(AccountManagerFuture<Bundle> future) { + assert future.isDone(); + Bundle bundle = null; + try { + bundle = future.getResult(); + } catch (AuthenticatorException | IOException e) { + Log.e(TAG, "Error while update credentials: ", e); + } catch (OperationCanceledException e) { + Log.w(TAG, "Updating credentials was cancelled."); + } + if (bundle != null + && bundle.getString(AccountManager.KEY_ACCOUNT_NAME) != null + && bundle.getString(AccountManager.KEY_ACCOUNT_TYPE) != null) { + callback.onResult(true); + } else { + callback.onResult(false); + } + } + }, null /* handler */); + } }
diff --git a/components/sync/android/sync_jni_registrar.h b/components/sync/android/sync_jni_registrar.h index ba8dd05..f0676c51 100644 --- a/components/sync/android/sync_jni_registrar.h +++ b/components/sync/android/sync_jni_registrar.h
@@ -7,11 +7,10 @@ #include <jni.h> -#include "components/sync/base/sync_export.h" namespace syncer { -SYNC_EXPORT bool RegisterSyncJni(JNIEnv* env); +bool RegisterSyncJni(JNIEnv* env); } // namespace syncer
diff --git a/components/sync/api/attachments/attachment.h b/components/sync/api/attachments/attachment.h index 972babb..57d99b36 100644 --- a/components/sync/api/attachments/attachment.h +++ b/components/sync/api/attachments/attachment.h
@@ -14,7 +14,6 @@ #include "base/memory/ref_counted.h" #include "base/memory/ref_counted_memory.h" #include "components/sync/api/attachments/attachment_id.h" -#include "components/sync/base/sync_export.h" namespace syncer { @@ -24,7 +23,7 @@ // the data they wrap is immutable. // // It is cheap to copy Attachments. Feel free to store and return by value. -class SYNC_EXPORT Attachment { +class Attachment { public: Attachment(const Attachment& other); ~Attachment();
diff --git a/components/sync/api/attachments/attachment_id.h b/components/sync/api/attachments/attachment_id.h index 508f768..4d2ffe8d 100644 --- a/components/sync/api/attachments/attachment_id.h +++ b/components/sync/api/attachments/attachment_id.h
@@ -13,7 +13,6 @@ #include <vector> #include "components/sync/base/immutable.h" -#include "components/sync/base/sync_export.h" namespace sync_pb { class AttachmentIdProto; @@ -25,7 +24,7 @@ // // Two attachments with equal (operator==) AttachmentIds are considered // equivalent. -class SYNC_EXPORT AttachmentId { +class AttachmentId { public: AttachmentId(const AttachmentId& other); ~AttachmentId(); @@ -60,7 +59,7 @@ private: // Necessary since we forward-declare sync_pb::AttachmentIdProto; see comments // in immutable.h. - struct SYNC_EXPORT ImmutableAttachmentIdProtoTraits { + struct ImmutableAttachmentIdProtoTraits { typedef sync_pb::AttachmentIdProto* Wrapper; static void InitializeWrapper(Wrapper* wrapper); static void DestroyWrapper(Wrapper* wrapper);
diff --git a/components/sync/api/attachments/attachment_metadata.h b/components/sync/api/attachments/attachment_metadata.h index 93557377..451c95a 100644 --- a/components/sync/api/attachments/attachment_metadata.h +++ b/components/sync/api/attachments/attachment_metadata.h
@@ -10,14 +10,13 @@ #include <vector> #include "components/sync/api/attachments/attachment_id.h" -#include "components/sync/base/sync_export.h" namespace syncer { // This class represents immutable Attachment metadata. // // It is OK to copy and return AttachmentMetadata by value. -class SYNC_EXPORT AttachmentMetadata { +class AttachmentMetadata { public: AttachmentMetadata(const AttachmentId& id, size_t size); ~AttachmentMetadata();
diff --git a/components/sync/api/attachments/attachment_store.h b/components/sync/api/attachments/attachment_store.h index 8814771..60f8fb3 100644 --- a/components/sync/api/attachments/attachment_store.h +++ b/components/sync/api/attachments/attachment_store.h
@@ -13,7 +13,6 @@ #include "components/sync/api/attachments/attachment.h" #include "components/sync/api/attachments/attachment_id.h" #include "components/sync/api/attachments/attachment_metadata.h" -#include "components/sync/base/sync_export.h" namespace base { class FilePath; @@ -34,7 +33,7 @@ // implementations. // Destroying this object does not necessarily cancel outstanding async // operations. If you need cancel like semantics, use WeakPtr in the callbacks. -class SYNC_EXPORT AttachmentStore { +class AttachmentStore { public: // TODO(maniscalco): Consider udpating Read and Write methods to support // resumable transfers (bug 353292). @@ -171,7 +170,7 @@ // AttachmentService writes attachment on behalf of model type after download // and takes reference on attachment for the duration of upload. // Model type implementation shouldn't use this interface. -class SYNC_EXPORT AttachmentStoreForSync : public AttachmentStore { +class AttachmentStoreForSync : public AttachmentStore { public: ~AttachmentStoreForSync();
diff --git a/components/sync/api/attachments/attachment_store_backend.h b/components/sync/api/attachments/attachment_store_backend.h index 0aae55b..a014d68 100644 --- a/components/sync/api/attachments/attachment_store_backend.h +++ b/components/sync/api/attachments/attachment_store_backend.h
@@ -11,7 +11,6 @@ #include "components/sync/api/attachments/attachment.h" #include "components/sync/api/attachments/attachment_id.h" #include "components/sync/api/attachments/attachment_store.h" -#include "components/sync/base/sync_export.h" namespace base { class SequencedTaskRunner; @@ -29,7 +28,7 @@ // All callbacks and result codes are used directly from AttachmentStore. // AttachmentStoreFrontend only passes callbacks and results without modifying // them, there is no need to declare separate set. -class SYNC_EXPORT AttachmentStoreBackend { +class AttachmentStoreBackend { public: explicit AttachmentStoreBackend( const scoped_refptr<base::SequencedTaskRunner>& callback_task_runner);
diff --git a/components/sync/api/conflict_resolution.h b/components/sync/api/conflict_resolution.h index 592fb54..542910f 100644 --- a/components/sync/api/conflict_resolution.h +++ b/components/sync/api/conflict_resolution.h
@@ -15,7 +15,7 @@ // 1) Use the local client data and update the server. // 2) Use the remote server data and update the client. // 3) Use newly created data and update both. -class SYNC_EXPORT ConflictResolution { +class ConflictResolution { public: // This enum is used in histograms.xml and entries shouldn't be renumbered or // removed. New entries must be added at the end, before TYPE_SIZE.
diff --git a/components/sync/api/data_batch.h b/components/sync/api/data_batch.h index 476f882..43eb187 100644 --- a/components/sync/api/data_batch.h +++ b/components/sync/api/data_batch.h
@@ -11,14 +11,13 @@ #include <utility> #include "components/sync/api/entity_data.h" -#include "components/sync/base/sync_export.h" namespace syncer_v2 { -typedef std::pair<std::string, std::unique_ptr<EntityData>> TagAndData; +typedef std::pair<std::string, std::unique_ptr<EntityData>> KeyAndData; // Interface used by the processor to read data requested from the service. -class SYNC_EXPORT DataBatch { +class DataBatch { public: DataBatch() {} virtual ~DataBatch() {} @@ -29,7 +28,7 @@ // Returns a pair of storage tag and owned entity data object. Invoking this // method will remove the pair from the batch, and should not be called if // HasNext() returns false. - virtual TagAndData Next() = 0; + virtual KeyAndData Next() = 0; }; } // namespace syncer_v2
diff --git a/components/sync/api/entity_change.cc b/components/sync/api/entity_change.cc index 7dc04e2..e0c1f952 100644 --- a/components/sync/api/entity_change.cc +++ b/components/sync/api/entity_change.cc
@@ -7,26 +7,26 @@ namespace syncer_v2 { // static -EntityChange EntityChange::CreateAdd(std::string client_tag, +EntityChange EntityChange::CreateAdd(const std::string& storage_key, EntityDataPtr data) { - return EntityChange(client_tag, ACTION_ADD, data); + return EntityChange(storage_key, ACTION_ADD, data); } // static -EntityChange EntityChange::CreateUpdate(std::string client_tag, +EntityChange EntityChange::CreateUpdate(const std::string& storage_key, EntityDataPtr data) { - return EntityChange(client_tag, ACTION_UPDATE, data); + return EntityChange(storage_key, ACTION_UPDATE, data); } // static -EntityChange EntityChange::CreateDelete(std::string client_tag) { - return EntityChange(client_tag, ACTION_DELETE, EntityDataPtr()); +EntityChange EntityChange::CreateDelete(const std::string& storage_key) { + return EntityChange(storage_key, ACTION_DELETE, EntityDataPtr()); } -EntityChange::EntityChange(std::string client_tag, +EntityChange::EntityChange(const std::string& storage_key, ChangeType type, EntityDataPtr data) - : client_tag_(client_tag), type_(type), data_(data) {} + : storage_key_(storage_key), type_(type), data_(data) {} EntityChange::EntityChange(const EntityChange& other) = default;
diff --git a/components/sync/api/entity_change.h b/components/sync/api/entity_change.h index dd619564..656b7ce6 100644 --- a/components/sync/api/entity_change.h +++ b/components/sync/api/entity_change.h
@@ -9,29 +9,32 @@ #include <vector> #include "components/sync/api/entity_data.h" -#include "components/sync/base/sync_export.h" namespace syncer_v2 { -class SYNC_EXPORT EntityChange { +class EntityChange { public: enum ChangeType { ACTION_ADD, ACTION_UPDATE, ACTION_DELETE }; - static EntityChange CreateAdd(std::string client_tag, EntityDataPtr data); - static EntityChange CreateUpdate(std::string client_tag, EntityDataPtr data); - static EntityChange CreateDelete(std::string client_tag); + static EntityChange CreateAdd(const std::string& storage_key, + EntityDataPtr data); + static EntityChange CreateUpdate(const std::string& storage_key, + EntityDataPtr data); + static EntityChange CreateDelete(const std::string& storage_key); EntityChange(const EntityChange& other); virtual ~EntityChange(); - std::string client_tag() const { return client_tag_; } + std::string storage_key() const { return storage_key_; } ChangeType type() const { return type_; } const EntityData& data() const { return data_.value(); } private: - EntityChange(std::string client_tag, ChangeType type, EntityDataPtr data); + EntityChange(const std::string& storage_key, + ChangeType type, + EntityDataPtr data); - std::string client_tag_; + std::string storage_key_; ChangeType type_; EntityDataPtr data_; };
diff --git a/components/sync/api/entity_data.h b/components/sync/api/entity_data.h index cb33bd57..99249471 100644 --- a/components/sync/api/entity_data.h +++ b/components/sync/api/entity_data.h
@@ -12,14 +12,13 @@ #include "base/macros.h" #include "base/time/time.h" #include "components/sync/base/proto_value_ptr.h" -#include "components/sync/base/sync_export.h" #include "components/sync/protocol/sync.pb.h" namespace syncer_v2 { struct EntityData; -struct SYNC_EXPORT EntityDataTraits { +struct EntityDataTraits { static void SwapValue(EntityData* dest, EntityData* src); static bool HasValue(const EntityData& value); static const EntityData& DefaultValue(); @@ -33,7 +32,7 @@ // local data created on the ModelTypeService side or remote data created // on ModelTypeWorker. // EntityData is supposed to be wrapped and passed by reference. -struct SYNC_EXPORT EntityData { +struct EntityData { public: EntityData(); ~EntityData();
diff --git a/components/sync/api/fake_model_type_service.cc b/components/sync/api/fake_model_type_service.cc index 82ec3d7..aff7362 100644 --- a/components/sync/api/fake_model_type_service.cc +++ b/components/sync/api/fake_model_type_service.cc
@@ -38,7 +38,7 @@ return syncer::SyncError(); } -void FakeModelTypeService::GetData(ClientTagList client_tags, +void FakeModelTypeService::GetData(StorageKeyList storage_keys, DataCallback callback) {} void FakeModelTypeService::GetAllData(DataCallback callback) {} @@ -47,6 +47,10 @@ return std::string(); } +std::string FakeModelTypeService::GetStorageKey(const EntityData& entity_data) { + return std::string(); +} + void FakeModelTypeService::OnChangeProcessorSet() {} bool FakeModelTypeService::HasChangeProcessor() const {
diff --git a/components/sync/api/fake_model_type_service.h b/components/sync/api/fake_model_type_service.h index 2642c93..e02a5e1 100644 --- a/components/sync/api/fake_model_type_service.h +++ b/components/sync/api/fake_model_type_service.h
@@ -5,6 +5,7 @@ #ifndef COMPONENTS_SYNC_API_FAKE_MODEL_TYPE_SERVICE_H_ #define COMPONENTS_SYNC_API_FAKE_MODEL_TYPE_SERVICE_H_ +#include <memory> #include <string> #include "components/sync/api/model_type_service.h" @@ -27,9 +28,10 @@ syncer::SyncError ApplySyncChanges( std::unique_ptr<MetadataChangeList> metadata_change_list, EntityChangeList entity_changes) override; - void GetData(ClientTagList client_tags, DataCallback callback) override; + void GetData(StorageKeyList storage_keys, DataCallback callback) override; void GetAllData(DataCallback callback) override; std::string GetClientTag(const EntityData& entity_data) override; + std::string GetStorageKey(const EntityData& entity_data) override; void OnChangeProcessorSet() override; bool HasChangeProcessor() const;
diff --git a/components/sync/api/metadata_batch.cc b/components/sync/api/metadata_batch.cc index f55ab8e..6402da40 100644 --- a/components/sync/api/metadata_batch.cc +++ b/components/sync/api/metadata_batch.cc
@@ -4,6 +4,8 @@ #include "components/sync/api/metadata_batch.h" +#include <utility> + namespace syncer_v2 { MetadataBatch::MetadataBatch() {} @@ -13,9 +15,9 @@ return std::move(metadata_map_); } -void MetadataBatch::AddMetadata(const std::string& client_tag, +void MetadataBatch::AddMetadata(const std::string& storage_key, const sync_pb::EntityMetadata& metadata) { - metadata_map_.insert(std::make_pair(client_tag, metadata)); + metadata_map_.insert(std::make_pair(storage_key, metadata)); } const sync_pb::DataTypeState& MetadataBatch::GetDataTypeState() const {
diff --git a/components/sync/api/metadata_batch.h b/components/sync/api/metadata_batch.h index 79da85bf..18f772d 100644 --- a/components/sync/api/metadata_batch.h +++ b/components/sync/api/metadata_batch.h
@@ -8,17 +8,16 @@ #include <map> #include <string> -#include "components/sync/base/sync_export.h" #include "components/sync/protocol/data_type_state.pb.h" #include "components/sync/protocol/entity_metadata.pb.h" namespace syncer_v2 { -// Map of client tag to EntityMetadata proto. +// Map of storage keys to EntityMetadata proto. typedef std::map<std::string, sync_pb::EntityMetadata> EntityMetadataMap; // Container used to pass sync metadata from services to their processor. -class SYNC_EXPORT MetadataBatch { +class MetadataBatch { public: MetadataBatch(); virtual ~MetadataBatch(); @@ -28,8 +27,8 @@ // protos from the map for performance reasons. EntityMetadataMap&& TakeAllMetadata(); - // Add |metadata| for |client_tag| to the batch. - void AddMetadata(const std::string& client_tag, + // Add |metadata| for |storage_key| to the batch. + void AddMetadata(const std::string& storage_key, const sync_pb::EntityMetadata& metadata); // Get the DataTypeState for this batch.
diff --git a/components/sync/api/metadata_change_list.h b/components/sync/api/metadata_change_list.h index 13d329998..b79c419 100644 --- a/components/sync/api/metadata_change_list.h +++ b/components/sync/api/metadata_change_list.h
@@ -7,8 +7,6 @@ #include <string> -#include "components/sync/base/sync_export.h" - namespace sync_pb { class DataTypeState; class EntityMetadata; @@ -24,7 +22,7 @@ // updated / deleted metadata records and provide a mechanism to enumerate // them. If there are multiple UpdateMetadata / ClearMetadata calls made for the // same metadata record the last one is supposed to win. -class SYNC_EXPORT MetadataChangeList { +class MetadataChangeList { public: MetadataChangeList() {} virtual ~MetadataChangeList() {} @@ -40,11 +38,11 @@ // Please note that the update might contain a deleted entry if // metadata.is_deleted() is true (as opposed to clearing the entry from the // storage completely by calling the Clear method). - virtual void UpdateMetadata(const std::string& client_tag, + virtual void UpdateMetadata(const std::string& storage_key, const sync_pb::EntityMetadata& metadata) = 0; // Requests metadata entry to be cleared from the storage. - virtual void ClearMetadata(const std::string& client_tag) = 0; + virtual void ClearMetadata(const std::string& storage_key) = 0; }; } // namespace syncer_v2
diff --git a/components/sync/api/model_type_change_processor.h b/components/sync/api/model_type_change_processor.h index 107934f..014d456 100644 --- a/components/sync/api/model_type_change_processor.h +++ b/components/sync/api/model_type_change_processor.h
@@ -10,7 +10,6 @@ #include "components/sync/api/entity_data.h" #include "components/sync/api/sync_error_factory.h" -#include "components/sync/base/sync_export.h" #include "components/sync/core/activation_context.h" namespace syncer { @@ -25,7 +24,7 @@ // Interface used by the ModelTypeService to inform sync of local // changes. -class SYNC_EXPORT ModelTypeChangeProcessor : public syncer::SyncErrorFactory { +class ModelTypeChangeProcessor : public syncer::SyncErrorFactory { public: typedef base::Callback<void(syncer::SyncError, std::unique_ptr<ActivationContext>)> @@ -38,12 +37,12 @@ // does not need to be fully set, but it should at least have specifics and // non-unique name. The processor will fill in the rest if the service does // not have a reason to care. - virtual void Put(const std::string& client_tag, + virtual void Put(const std::string& storage_key, std::unique_ptr<EntityData> entity_data, MetadataChangeList* metadata_change_list) = 0; // Inform the processor of a deleted entity. - virtual void Delete(const std::string& client_tag, + virtual void Delete(const std::string& storage_key, MetadataChangeList* metadata_change_list) = 0; // Accept the initial sync metadata loaded by the service. This should be
diff --git a/components/sync/api/model_type_service.h b/components/sync/api/model_type_service.h index 9b2bec7..49a56e7 100644 --- a/components/sync/api/model_type_service.h +++ b/components/sync/api/model_type_service.h
@@ -15,7 +15,6 @@ #include "components/sync/api/entity_data.h" #include "components/sync/api/model_type_change_processor.h" #include "components/sync/api/sync_error.h" -#include "components/sync/base/sync_export.h" #include "components/sync/core/activation_context.h" namespace syncer { @@ -30,11 +29,11 @@ // Interface implemented by model types to receive updates from sync via the // SharedModelTypeProcessor. Provides a way for sync to update the data and // metadata for entities, as well as the model type state. -class SYNC_EXPORT ModelTypeService { +class ModelTypeService { public: typedef base::Callback<void(syncer::SyncError, std::unique_ptr<DataBatch>)> DataCallback; - typedef std::vector<std::string> ClientTagList; + typedef std::vector<std::string> StorageKeyList; typedef base::Callback<std::unique_ptr<ModelTypeChangeProcessor>( syncer::ModelType type, ModelTypeService* service)> @@ -75,15 +74,29 @@ std::unique_ptr<MetadataChangeList> metadata_change_list, EntityChangeList entity_changes) = 0; - // Asynchronously retrieve the corresponding sync data for |client_tags|. - virtual void GetData(ClientTagList client_tags, DataCallback callback) = 0; + // Asynchronously retrieve the corresponding sync data for |storage_keys|. + virtual void GetData(StorageKeyList storage_keys, DataCallback callback) = 0; // Asynchronously retrieve all of the local sync data. virtual void GetAllData(DataCallback callback) = 0; - // Get or generate a client tag for |entity_data|. + // Get or generate a client tag for |entity_data|. This must be the same tag + // that was/would have been generated in the SyncableService/Directory world + // for backward compatibility with pre-USS clients. The only time this + // theoretically needs to be called is on the creation of local data, however + // it is also used to verify the hash of remote data. If a data type was never + // launched pre-USS, then method does not need to be different from + // GetStorageKey(). virtual std::string GetClientTag(const EntityData& entity_data) = 0; + // Get or generate a storage key for |entity_data|. This will only ever be + // called once when first encountering a remote entity. Local changes will + // provide their storage keys directly to Put instead of using this method. + // Theoretically this function doesn't need to be stable across multiple calls + // on the same or different clients, but to keep things simple, it probably + // should be. + virtual std::string GetStorageKey(const EntityData& entity_data) = 0; + // Overridable notification for when the processor is set. This is typically // when the service should start loading metadata and then subsequently giving // it to the processor.
diff --git a/components/sync/api/model_type_store.h b/components/sync/api/model_type_store.h index 18377b3..f3844a9 100644 --- a/components/sync/api/model_type_store.h +++ b/components/sync/api/model_type_store.h
@@ -12,7 +12,6 @@ #include "base/callback.h" #include "base/macros.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" namespace base { class SequencedTaskRunner; @@ -46,7 +45,7 @@ // Destroying store object doesn't necessarily cancel asynchronous operations // issued previously. You should be prepared to handle callbacks from those // operations. -class SYNC_EXPORT ModelTypeStore { +class ModelTypeStore { public: // Result of store operations. enum class Result { @@ -64,7 +63,7 @@ }; // WriteBatch object is used in all modification operations. - class SYNC_EXPORT WriteBatch { + class WriteBatch { public: virtual ~WriteBatch();
diff --git a/components/sync/api/sync_change.h b/components/sync/api/sync_change.h index 6017a40a..148cedd 100644 --- a/components/sync/api/sync_change.h +++ b/components/sync/api/sync_change.h
@@ -11,7 +11,6 @@ #include "base/location.h" #include "components/sync/api/sync_data.h" -#include "components/sync/base/sync_export.h" namespace syncer { @@ -20,7 +19,7 @@ // is encapsulated within the SyncChange, which, once created, is immutable. // Note: it is safe and cheap to pass these by value or make copies, as they do // not create deep copies of their internal data. -class SYNC_EXPORT SyncChange { +class SyncChange { public: enum SyncChangeType { ACTION_INVALID, @@ -70,7 +69,7 @@ }; // gmock printer helper. -SYNC_EXPORT void PrintTo(const SyncChange& sync_change, std::ostream* os); +void PrintTo(const SyncChange& sync_change, std::ostream* os); } // namespace syncer
diff --git a/components/sync/api/sync_change_processor.h b/components/sync/api/sync_change_processor.h index c0cba42..d5884a2 100644 --- a/components/sync/api/sync_change_processor.h +++ b/components/sync/api/sync_change_processor.h
@@ -11,7 +11,6 @@ #include "components/sync/api/sync_data.h" #include "components/sync/api/sync_error.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" namespace tracked_objects { class Location; @@ -24,7 +23,7 @@ typedef std::vector<SyncChange> SyncChangeList; // An interface for services that handle receiving SyncChanges. -class SYNC_EXPORT SyncChangeProcessor { +class SyncChangeProcessor { public: // Whether a context change should force a datatype refresh or not. enum ContextRefreshStatus { NO_REFRESH, REFRESH_NEEDED };
diff --git a/components/sync/api/sync_data.h b/components/sync/api/sync_data.h index adc205b5..2ebd47e 100644 --- a/components/sync/api/sync_data.h +++ b/components/sync/api/sync_data.h
@@ -18,7 +18,6 @@ #include "components/sync/api/attachments/attachment_id.h" #include "components/sync/base/immutable.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/weak_handle.h" #include "components/sync/core/attachments/attachment_service_proxy.h" @@ -35,7 +34,7 @@ // A light-weight container for immutable sync data. Pass-by-value and storage // in STL containers are supported and encouraged if helpful. -class SYNC_EXPORT SyncData { +class SyncData { public: // Creates an empty and invalid SyncData. SyncData(); @@ -111,7 +110,7 @@ // Necessary since we forward-declare sync_pb::SyncEntity; see // comments in immutable.h. - struct SYNC_EXPORT ImmutableSyncEntityTraits { + struct ImmutableSyncEntityTraits { typedef sync_pb::SyncEntity* Wrapper; static void InitializeWrapper(Wrapper* wrapper); @@ -151,7 +150,7 @@ }; // A SyncData going to the syncer. -class SYNC_EXPORT SyncDataLocal : public SyncData { +class SyncDataLocal : public SyncData { public: // Construct a SyncDataLocal from a SyncData. // @@ -165,7 +164,7 @@ }; // A SyncData that comes from the syncer. -class SYNC_EXPORT SyncDataRemote : public SyncData { +class SyncDataRemote : public SyncData { public: // Construct a SyncDataRemote from a SyncData. // @@ -198,7 +197,7 @@ }; // gmock printer helper. -void SYNC_EXPORT PrintTo(const SyncData& sync_data, std::ostream* os); +void PrintTo(const SyncData& sync_data, std::ostream* os); typedef std::vector<SyncData> SyncDataList;
diff --git a/components/sync/api/sync_error.h b/components/sync/api/sync_error.h index 91fc98a..8800e61 100644 --- a/components/sync/api/sync_error.h +++ b/components/sync/api/sync_error.h
@@ -10,7 +10,6 @@ #include <string> #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" namespace tracked_objects { class Location; @@ -21,7 +20,7 @@ // Sync errors are used for debug purposes and handled internally and/or // exposed through Chrome's "about:sync" internal page. // This class is copy-friendly and thread-safe. -class SYNC_EXPORT SyncError { +class SyncError { public: // Error types are used to distinguish general datatype errors (which result // in the datatype being disabled) from actionable sync errors (which might @@ -122,7 +121,7 @@ }; // gmock printer helper. -SYNC_EXPORT void PrintTo(const SyncError& sync_error, std::ostream* os); +void PrintTo(const SyncError& sync_error, std::ostream* os); } // namespace syncer
diff --git a/components/sync/api/sync_error_factory.h b/components/sync/api/sync_error_factory.h index 95fe6748..b0466d0 100644 --- a/components/sync/api/sync_error_factory.h +++ b/components/sync/api/sync_error_factory.h
@@ -9,11 +9,10 @@ #include "base/location.h" #include "components/sync/api/sync_error.h" -#include "components/sync/base/sync_export.h" namespace syncer { -class SYNC_EXPORT SyncErrorFactory { +class SyncErrorFactory { public: SyncErrorFactory(); virtual ~SyncErrorFactory();
diff --git a/components/sync/api/sync_merge_result.h b/components/sync/api/sync_merge_result.h index 8a0e2db1..4630217 100644 --- a/components/sync/api/sync_merge_result.h +++ b/components/sync/api/sync_merge_result.h
@@ -9,7 +9,6 @@ #include "components/sync/api/sync_error.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" namespace syncer { @@ -20,7 +19,7 @@ // by the local SyncableService, all values correspond to the local state before // and after merging, and the delta's applied to that state. Sync's change // processor will create a separate merge result. -class SYNC_EXPORT SyncMergeResult { +class SyncMergeResult { public: // Initialize an empty merge result for model type |type|. explicit SyncMergeResult(ModelType type);
diff --git a/components/sync/api/syncable_service.h b/components/sync/api/syncable_service.h index 7d2114e0..5a7c7db8 100644 --- a/components/sync/api/syncable_service.h +++ b/components/sync/api/syncable_service.h
@@ -17,7 +17,6 @@ #include "components/sync/api/sync_error.h" #include "components/sync/api/sync_merge_result.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" namespace syncer { @@ -27,9 +26,8 @@ // TODO(zea): remove SupportsWeakPtr in favor of having all SyncableService // implementers provide a way of getting a weak pointer to themselves. // See crbug.com/100114. -class SYNC_EXPORT SyncableService - : public SyncChangeProcessor, - public base::SupportsWeakPtr<SyncableService> { +class SyncableService : public SyncChangeProcessor, + public base::SupportsWeakPtr<SyncableService> { public: // A StartSyncFlare is useful when your SyncableService has a need for sync // to start ASAP, typically because a local change event has occurred but
diff --git a/components/sync/base/attachment_id_proto.h b/components/sync/base/attachment_id_proto.h index 2d8c541..fe41bb3c 100644 --- a/components/sync/base/attachment_id_proto.h +++ b/components/sync/base/attachment_id_proto.h
@@ -8,7 +8,6 @@ #include <stddef.h> #include <stdint.h> -#include "components/sync/base/sync_export.h" #include "components/sync/protocol/sync.pb.h" namespace syncer { @@ -20,15 +19,15 @@ // |size| is the size in bytes of the attachment identified by this proto. // // |crc32c| is the crc32c of the attachment identified by this proto. -SYNC_EXPORT sync_pb::AttachmentIdProto CreateAttachmentIdProto(size_t size, - uint32_t crc32c); +sync_pb::AttachmentIdProto CreateAttachmentIdProto(size_t size, + uint32_t crc32c); // Creates an AttachmentMetadata object from a repeated field of // AttachmentIdProto objects. // // Note: each record in the AttachmentMetadata will be marked as "on the // server". -SYNC_EXPORT sync_pb::AttachmentMetadata CreateAttachmentMetadata( +sync_pb::AttachmentMetadata CreateAttachmentMetadata( const google::protobuf::RepeatedPtrField<sync_pb::AttachmentIdProto>& ids); } // namespace syncer
diff --git a/components/sync/base/cancelation_observer.h b/components/sync/base/cancelation_observer.h index bf6b39f..898c8902 100644 --- a/components/sync/base/cancelation_observer.h +++ b/components/sync/base/cancelation_observer.h
@@ -5,12 +5,10 @@ #ifndef COMPONENTS_SYNC_BASE_CANCELATION_OBSERVER_H_ #define COMPONENTS_SYNC_BASE_CANCELATION_OBSERVER_H_ -#include "components/sync/base/sync_export.h" - namespace syncer { // Interface for classes that handle signals from the CancelationSignal. -class SYNC_EXPORT CancelationObserver { +class CancelationObserver { public: CancelationObserver(); virtual ~CancelationObserver() = 0;
diff --git a/components/sync/base/cancelation_signal.h b/components/sync/base/cancelation_signal.h index 9189b47..6740743 100644 --- a/components/sync/base/cancelation_signal.h +++ b/components/sync/base/cancelation_signal.h
@@ -6,7 +6,6 @@ #define COMPONENTS_SYNC_BASE_CANCELATION_SIGNAL_H_ #include "base/synchronization/lock.h" -#include "components/sync/base/sync_export.h" namespace syncer { @@ -31,7 +30,7 @@ // // This class supports only one handler, though it could easily support multiple // observers if we found a use case for such a feature. -class SYNC_EXPORT CancelationSignal { +class CancelationSignal { public: CancelationSignal(); ~CancelationSignal();
diff --git a/components/sync/base/cryptographer.h b/components/sync/base/cryptographer.h index 9ddad9e..1ef81d3 100644 --- a/components/sync/base/cryptographer.h +++ b/components/sync/base/cryptographer.h
@@ -12,7 +12,6 @@ #include "base/macros.h" #include "base/memory/linked_ptr.h" #include "components/sync/base/nigori.h" -#include "components/sync/base/sync_export.h" #include "components/sync/protocol/encryption.pb.h" namespace sync_pb { @@ -24,7 +23,7 @@ class Encryptor; -SYNC_EXPORT extern const char kNigoriTag[]; +extern const char kNigoriTag[]; // The parameters used to initialize a Nigori instance. struct KeyParams { @@ -47,7 +46,7 @@ // CanDecrypt should be used to verify whether the Cryptographer can decrypt // that node. If it cannot, then the application of that update should be // delayed until after it can be decrypted. -class SYNC_EXPORT Cryptographer { +class Cryptographer { public: // Does not take ownership of |encryptor|. explicit Cryptographer(Encryptor* encryptor);
diff --git a/components/sync/base/extensions_activity.h b/components/sync/base/extensions_activity.h index 6b8e8dd..1d3c8848 100644 --- a/components/sync/base/extensions_activity.h +++ b/components/sync/base/extensions_activity.h
@@ -12,18 +12,17 @@ #include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" -#include "components/sync/base/sync_export.h" namespace syncer { // A storage to record usage of extensions APIs to send to sync // servers, with the ability to purge data once sync servers have // acknowledged it (successful commit response). -class SYNC_EXPORT ExtensionsActivity +class ExtensionsActivity : public base::RefCountedThreadSafe<ExtensionsActivity> { public: // A data record of activity performed by extension |extension_id|. - struct SYNC_EXPORT Record { + struct Record { Record(); ~Record();
diff --git a/components/sync/base/get_session_name.h b/components/sync/base/get_session_name.h index ce7026c..cc4cfef5 100644 --- a/components/sync/base/get_session_name.h +++ b/components/sync/base/get_session_name.h
@@ -9,7 +9,6 @@ #include "base/callback_forward.h" #include "base/memory/ref_counted.h" -#include "components/sync/base/sync_export.h" namespace base { class TaskRunner; @@ -18,11 +17,11 @@ namespace syncer { // Invokes |done_callback| with the session name, a UTF-8 string. -SYNC_EXPORT void GetSessionName( +void GetSessionName( const scoped_refptr<base::TaskRunner>& task_runner, const base::Callback<void(const std::string&)>& done_callback); -SYNC_EXPORT std::string GetSessionNameSynchronouslyForTesting(); +std::string GetSessionNameSynchronouslyForTesting(); } // namespace syncer
diff --git a/components/sync/base/invalidation_interface.h b/components/sync/base/invalidation_interface.h index aacfb03..8481749 100644 --- a/components/sync/base/invalidation_interface.h +++ b/components/sync/base/invalidation_interface.h
@@ -9,13 +9,11 @@ #include <string> -#include "components/sync/base/sync_export.h" - namespace syncer { // An interface that wraps sync's interactions with the component that provides // it with invalidations. -class SYNC_EXPORT InvalidationInterface { +class InvalidationInterface { public: // Orders invalidations based on version number and IsUnknownVersion(). static bool LessThanByVersion(const InvalidationInterface& a,
diff --git a/components/sync/base/model_type.h b/components/sync/base/model_type.h index 004f7bb9..55edf93 100644 --- a/components/sync/base/model_type.h +++ b/components/sync/base/model_type.h
@@ -17,7 +17,6 @@ #include "base/logging.h" #include "components/sync/base/enum_set.h" -#include "components/sync/base/sync_export.h" namespace base { class ListValue; @@ -157,7 +156,7 @@ // If you are adding a new sync datatype that is exposed to the user via the // sync preferences UI, be sure to update the list in - // components/sync_driver/user_selectable_sync_type.h so that the UMA + // components/sync/driver/user_selectable_sync_type.h so that the UMA // histograms for sync include your new type. In this case, be sure to also // update the UserSelectableTypes() definition in // sync/syncable/model_type.cc. @@ -176,47 +175,46 @@ } // Used by tests outside of sync/. -SYNC_EXPORT void AddDefaultFieldValue(ModelType datatype, - sync_pb::EntitySpecifics* specifics); +void AddDefaultFieldValue(ModelType datatype, + sync_pb::EntitySpecifics* specifics); // Extract the model type of a SyncEntity protocol buffer. ModelType is a // local concept: the enum is not in the protocol. The SyncEntity's ModelType // is inferred from the presence of particular datatype field in the // entity specifics. -SYNC_EXPORT ModelType GetModelType(const sync_pb::SyncEntity& sync_entity); +ModelType GetModelType(const sync_pb::SyncEntity& sync_entity); // Extract the model type from an EntitySpecifics field. Note that there // are some ModelTypes (like TOP_LEVEL_FOLDER) that can't be inferred this way; // prefer using GetModelType where possible. -SYNC_EXPORT ModelType -GetModelTypeFromSpecifics(const sync_pb::EntitySpecifics& specifics); +ModelType GetModelTypeFromSpecifics(const sync_pb::EntitySpecifics& specifics); // Protocol types are those types that have actual protocol buffer // representations. This distinguishes them from Proxy types, which have no // protocol representation and are never sent to the server. -SYNC_EXPORT ModelTypeSet ProtocolTypes(); +ModelTypeSet ProtocolTypes(); // These are the normal user-controlled types. This is to distinguish from // ControlTypes which are always enabled. Note that some of these share a // preference flag, so not all of them are individually user-selectable. -SYNC_EXPORT ModelTypeSet UserTypes(); +ModelTypeSet UserTypes(); // These are the user-selectable data types. -SYNC_EXPORT ModelTypeSet UserSelectableTypes(); -SYNC_EXPORT bool IsUserSelectableType(ModelType model_type); -SYNC_EXPORT ModelTypeNameMap GetUserSelectableTypeNameMap(); +ModelTypeSet UserSelectableTypes(); +bool IsUserSelectableType(ModelType model_type); +ModelTypeNameMap GetUserSelectableTypeNameMap(); // This is the subset of UserTypes() that can be encrypted. -SYNC_EXPORT ModelTypeSet EncryptableUserTypes(); +ModelTypeSet EncryptableUserTypes(); // This is the subset of UserTypes() that have priority over other types. These // types are synced before other user types and are never encrypted. -SYNC_EXPORT ModelTypeSet PriorityUserTypes(); +ModelTypeSet PriorityUserTypes(); // Proxy types are placeholder types for handling implicitly enabling real // types. They do not exist at the server, and are simply used for // UI/Configuration logic. -SYNC_EXPORT ModelTypeSet ProxyTypes(); +ModelTypeSet ProxyTypes(); // Returns a list of all control types. // @@ -228,20 +226,20 @@ // - Their contents are not encrypted automatically. // - They support custom update application and conflict resolution logic. // - All change processing occurs on the sync thread (GROUP_PASSIVE). -SYNC_EXPORT ModelTypeSet ControlTypes(); +ModelTypeSet ControlTypes(); // Returns true if this is a control type. // // See comment above for more information on what makes these types special. -SYNC_EXPORT bool IsControlType(ModelType model_type); +bool IsControlType(ModelType model_type); // Core types are those data types used by sync's core functionality (i.e. not // user data types). These types are always enabled, and include ControlTypes(). // // The set of all core types. -SYNC_EXPORT ModelTypeSet CoreTypes(); +ModelTypeSet CoreTypes(); // Those core types that have high priority (includes ControlTypes()). -SYNC_EXPORT ModelTypeSet PriorityCoreTypes(); +ModelTypeSet PriorityCoreTypes(); // Determine a model type from the field number of its associated // EntitySpecifics field. Returns UNSPECIFIED if the field number is @@ -263,11 +261,11 @@ // } // model_types.Put(model_type); // } -SYNC_EXPORT ModelType GetModelTypeFromSpecificsFieldNumber(int field_number); +ModelType GetModelTypeFromSpecificsFieldNumber(int field_number); // Return the field number of the EntitySpecifics field associated with // a model type. -SYNC_EXPORT int GetSpecificsFieldNumberFromModelType(ModelType model_type); +int GetSpecificsFieldNumberFromModelType(ModelType model_type); FullModelTypeSet ToFullModelTypeSet(ModelTypeSet in); @@ -275,88 +273,83 @@ // Returns a pointer to a string with application lifetime that represents // the name of |model_type|. -SYNC_EXPORT const char* ModelTypeToString(ModelType model_type); +const char* ModelTypeToString(ModelType model_type); // Some histograms take an integer parameter that represents a model type. // The mapping from ModelType to integer is defined here. It should match // the mapping from integer to labels defined in histograms.xml. -SYNC_EXPORT int ModelTypeToHistogramInt(ModelType model_type); +int ModelTypeToHistogramInt(ModelType model_type); // Handles all model types, and not just real ones. // // Caller takes ownership of returned value. -SYNC_EXPORT base::StringValue* ModelTypeToValue(ModelType model_type); +base::StringValue* ModelTypeToValue(ModelType model_type); // Converts a Value into a ModelType - complement to ModelTypeToValue(). -SYNC_EXPORT ModelType ModelTypeFromValue(const base::Value& value); +ModelType ModelTypeFromValue(const base::Value& value); // Returns the ModelType corresponding to the name |model_type_string|. -SYNC_EXPORT ModelType ModelTypeFromString(const std::string& model_type_string); +ModelType ModelTypeFromString(const std::string& model_type_string); // Returns the comma-separated string representation of |model_types|. -SYNC_EXPORT std::string ModelTypeSetToString(ModelTypeSet model_types); +std::string ModelTypeSetToString(ModelTypeSet model_types); // Necessary for compatibility with EXPECT_EQ and the like. -SYNC_EXPORT std::ostream& operator<<(std::ostream& out, - ModelTypeSet model_type_set); +std::ostream& operator<<(std::ostream& out, ModelTypeSet model_type_set); // Returns the set of comma-separated model types from |model_type_string|. -SYNC_EXPORT ModelTypeSet -ModelTypeSetFromString(const std::string& model_type_string); +ModelTypeSet ModelTypeSetFromString(const std::string& model_type_string); -SYNC_EXPORT std::unique_ptr<base::ListValue> ModelTypeSetToValue( - ModelTypeSet model_types); +std::unique_ptr<base::ListValue> ModelTypeSetToValue(ModelTypeSet model_types); -SYNC_EXPORT ModelTypeSet ModelTypeSetFromValue(const base::ListValue& value); +ModelTypeSet ModelTypeSetFromValue(const base::ListValue& value); // Returns a string corresponding to the syncable tag for this datatype. -SYNC_EXPORT std::string ModelTypeToRootTag(ModelType type); +std::string ModelTypeToRootTag(ModelType type); // Returns root_tag for |model_type| in ModelTypeInfo. // Difference with ModelTypeToRootTag(), this just simply return toor_tag in // ModelTypeInfo. -SYNC_EXPORT const char* GetModelTypeRootTag(ModelType model_type); +const char* GetModelTypeRootTag(ModelType model_type); // Convert a real model type to a notification type (used for // subscribing to server-issued notifications). Returns true iff // |model_type| was a real model type and |notification_type| was // filled in. -SYNC_EXPORT bool RealModelTypeToNotificationType( - ModelType model_type, - std::string* notification_type); +bool RealModelTypeToNotificationType(ModelType model_type, + std::string* notification_type); // Converts a notification type to a real model type. Returns true // iff |notification_type| was the notification type of a real model // type and |model_type| was filled in. -SYNC_EXPORT bool NotificationTypeToRealModelType( - const std::string& notification_type, - ModelType* model_type); +bool NotificationTypeToRealModelType(const std::string& notification_type, + ModelType* model_type); // Returns true if |model_type| is a real datatype -SYNC_EXPORT bool IsRealDataType(ModelType model_type); +bool IsRealDataType(ModelType model_type); // Returns true if |model_type| is a proxy type -SYNC_EXPORT bool IsProxyType(ModelType model_type); +bool IsProxyType(ModelType model_type); // Returns true if |model_type| is an act-once type. Act once types drop // entities after applying them. Drops are deletes that are not synced to other // clients. // TODO(haitaol): Make entries of act-once data types immutable. -SYNC_EXPORT bool IsActOnceDataType(ModelType model_type); +bool IsActOnceDataType(ModelType model_type); // Returns true if |model_type| requires its root folder to be explicitly // created on the server during initial sync. -SYNC_EXPORT bool IsTypeWithServerGeneratedRoot(ModelType model_type); +bool IsTypeWithServerGeneratedRoot(ModelType model_type); // Returns true if root folder for |model_type| is created on the client when // that type is initially synced. -SYNC_EXPORT bool IsTypeWithClientGeneratedRoot(ModelType model_type); +bool IsTypeWithClientGeneratedRoot(ModelType model_type); // Returns true if |model_type| supports parent-child hierarchy or entries. -SYNC_EXPORT bool TypeSupportsHierarchy(ModelType model_type); +bool TypeSupportsHierarchy(ModelType model_type); // Returns true if |model_type| supports ordering of sibling entries. -SYNC_EXPORT bool TypeSupportsOrdering(ModelType model_type); +bool TypeSupportsOrdering(ModelType model_type); } // namespace syncer
diff --git a/components/sync/base/nigori.h b/components/sync/base/nigori.h index 85756b34..fe22f85 100644 --- a/components/sync/base/nigori.h +++ b/components/sync/base/nigori.h
@@ -10,8 +10,6 @@ #include <memory> #include <string> -#include "components/sync/base/sync_export.h" - namespace crypto { class SymmetricKey; } // namespace crypto @@ -27,7 +25,7 @@ // and retrieve the secret. // // https://www.cl.cam.ac.uk/~drt24/nigori/nigori-overview.pdf -class SYNC_EXPORT Nigori { +class Nigori { public: enum Type { Password = 1,
diff --git a/components/sync/base/node_ordinal.h b/components/sync/base/node_ordinal.h index 60813288..385ef040 100644 --- a/components/sync/base/node_ordinal.h +++ b/components/sync/base/node_ordinal.h
@@ -9,7 +9,6 @@ #include <stdint.h> #include "components/sync/base/ordinal.h" -#include "components/sync/base/sync_export.h" namespace syncer { @@ -44,13 +43,13 @@ // field of SyncEntity) to a NodeOrdinal. This transformation // preserves the ordering relation: a < b under integer ordering if // and only if Int64ToNodeOrdinal(a) < Int64ToNodeOrdinal(b). -SYNC_EXPORT NodeOrdinal Int64ToNodeOrdinal(int64_t x); +NodeOrdinal Int64ToNodeOrdinal(int64_t x); // The inverse of Int64ToNodeOrdinal. This conversion is, in general, // lossy: NodeOrdinals can have arbitrary fidelity, while numeric // positions contain only 64 bits of information (in fact, this is the // reason we've moved away from them). -SYNC_EXPORT int64_t NodeOrdinalToInt64(const NodeOrdinal& ordinal); +int64_t NodeOrdinalToInt64(const NodeOrdinal& ordinal); } // namespace syncer
diff --git a/components/sync/base/progress_marker_map.h b/components/sync/base/progress_marker_map.h index 500ae471..4b4a732f 100644 --- a/components/sync/base/progress_marker_map.h +++ b/components/sync/base/progress_marker_map.h
@@ -12,7 +12,6 @@ #include <string> #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" // TODO(akalin,mmontgomery): Move the non-exported functions in this file to a // private header. @@ -27,7 +26,7 @@ // DataTypeProgressMarkers. typedef std::map<ModelType, std::string> ProgressMarkerMap; -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> ProgressMarkerMapToValue( +std::unique_ptr<base::DictionaryValue> ProgressMarkerMapToValue( const ProgressMarkerMap& marker_map); } // namespace syncer
diff --git a/components/sync/base/sync_db_util.h b/components/sync/base/sync_db_util.h index 8eb2bab..e5e7342 100644 --- a/components/sync/base/sync_db_util.h +++ b/components/sync/base/sync_db_util.h
@@ -8,7 +8,6 @@ #include "base/callback.h" #include "base/memory/ref_counted.h" #include "base/time/time.h" -#include "components/sync/base/sync_export.h" namespace base { class FilePath; @@ -20,7 +19,7 @@ // Check integrity of sync DB under |sync_dir|. Invoke |callback| with last // modified time if integrity check passes, with NULL time otherwise. This // is called on either sync thread or IO thread. -SYNC_EXPORT void CheckSyncDbLastModifiedTime( +void CheckSyncDbLastModifiedTime( const base::FilePath& sync_dir, scoped_refptr<base::SingleThreadTaskRunner> callback_runner, base::Callback<void(base::Time)> callback);
diff --git a/components/sync/base/sync_export.h b/components/sync/base/sync_export.h deleted file mode 100644 index 1260e25..0000000 --- a/components/sync/base/sync_export.h +++ /dev/null
@@ -1,42 +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 COMPONENTS_SYNC_SYNC_EXPORT_H_ -#define COMPONENTS_SYNC_SYNC_EXPORT_H_ - -#if defined(COMPONENT_BUILD) -#if defined(WIN32) - -// TODO(skym): Remove SYNC_EXPORT_PRIVATE, see crbug/554242. - -#if defined(SYNC_IMPLEMENTATION) -#define SYNC_EXPORT __declspec(dllexport) -#define SYNC_EXPORT_PRIVATE __declspec(dllexport) -#elif defined(SYNC_TEST) -#define SYNC_EXPORT __declspec(dllimport) -#define SYNC_EXPORT_PRIVATE __declspec(dllimport) -#else -#define SYNC_EXPORT __declspec(dllimport) -#define SYNC_EXPORT_PRIVATE -#endif // defined(SYNC_IMPLEMENTATION) - -#else // defined(WIN32) -#if defined(SYNC_IMPLEMENTATION) -#define SYNC_EXPORT __attribute__((visibility("default"))) -#define SYNC_EXPORT_PRIVATE __attribute__((visibility("default"))) -#elif defined(SYNC_TEST) -#define SYNC_EXPORT -#define SYNC_EXPORT_PRIVATE __attribute__((visibility("default"))) -#else -#define SYNC_EXPORT -#define SYNC_EXPORT_PRIVATE -#endif // defined(SYNC_IMPLEMENTATION) -#endif - -#else // defined(COMPONENT_BUILD) -#define SYNC_EXPORT -#define SYNC_EXPORT_PRIVATE -#endif - -#endif // COMPONENTS_SYNC_SYNC_EXPORT_H_
diff --git a/components/sync/base/sync_string_conversions.h b/components/sync/base/sync_string_conversions.h index 072ee654..c9f8d544 100644 --- a/components/sync/base/sync_string_conversions.h +++ b/components/sync/base/sync_string_conversions.h
@@ -5,19 +5,17 @@ #ifndef COMPONENTS_SYNC_BASE_SYNC_STRING_CONVERSIONS_H_ #define COMPONENTS_SYNC_BASE_SYNC_STRING_CONVERSIONS_H_ -#include "components/sync/base/sync_export.h" #include "components/sync/core/connection_status.h" #include "components/sync/core/sync_encryption_handler.h" namespace syncer { -SYNC_EXPORT const char* ConnectionStatusToString(ConnectionStatus status); +const char* ConnectionStatusToString(ConnectionStatus status); // Returns the string representation of a PassphraseRequiredReason value. -SYNC_EXPORT const char* PassphraseRequiredReasonToString( - PassphraseRequiredReason reason); +const char* PassphraseRequiredReasonToString(PassphraseRequiredReason reason); -SYNC_EXPORT const char* PassphraseTypeToString(PassphraseType type); +const char* PassphraseTypeToString(PassphraseType type); const char* BootstrapTokenTypeToString(BootstrapTokenType type); } // namespace syncer
diff --git a/components/sync/base/syncer_error.h b/components/sync/base/syncer_error.h index e6c73a04..99f13882 100644 --- a/components/sync/base/syncer_error.h +++ b/components/sync/base/syncer_error.h
@@ -5,8 +5,6 @@ #ifndef COMPONENTS_SYNC_BASE_SYNCER_ERROR_H_ #define COMPONENTS_SYNC_BASE_SYNCER_ERROR_H_ -#include "components/sync/base/sync_export.h" - namespace syncer { // This enum describes all the possible results of a sync cycle. @@ -42,7 +40,7 @@ SYNCER_OK }; -SYNC_EXPORT const char* GetSyncerErrorString(SyncerError); +const char* GetSyncerErrorString(SyncerError); // Helper to check that |error| is set to something (not UNSET) and is not // SYNCER_OK.
diff --git a/components/sync/base/time.h b/components/sync/base/time.h index 6150f468..6e182ab 100644 --- a/components/sync/base/time.h +++ b/components/sync/base/time.h
@@ -12,18 +12,17 @@ #include <string> #include "base/time/time.h" -#include "components/sync/base/sync_export.h" namespace syncer { // Converts a time object to the format used in sync protobufs (ms // since the Unix epoch). -SYNC_EXPORT int64_t TimeToProtoTime(const base::Time& t); +int64_t TimeToProtoTime(const base::Time& t); // Converts a time field from sync protobufs to a time object. -SYNC_EXPORT base::Time ProtoTimeToTime(int64_t proto_t); +base::Time ProtoTimeToTime(int64_t proto_t); -SYNC_EXPORT std::string GetTimeDebugString(const base::Time& t); +std::string GetTimeDebugString(const base::Time& t); } // namespace syncer
diff --git a/components/sync/base/unique_position.cc b/components/sync/base/unique_position.cc index dc0b310f..1c8cdf8 100644 --- a/components/sync/base/unique_position.cc +++ b/components/sync/base/unique_position.cc
@@ -66,7 +66,7 @@ un_gzipped.resize(uncompressed_len); int result = uncompress( - reinterpret_cast<Bytef*>(string_as_array(&un_gzipped)), + reinterpret_cast<Bytef*>(base::string_as_array(&un_gzipped)), &uncompressed_len, reinterpret_cast<const Bytef*>(proto.compressed_value().data()), proto.compressed_value().size());
diff --git a/components/sync/base/unique_position.h b/components/sync/base/unique_position.h index bfb27f65..f205ce6 100644 --- a/components/sync/base/unique_position.h +++ b/components/sync/base/unique_position.h
@@ -10,8 +10,6 @@ #include <string> -#include "components/sync/base/sync_export.h" - namespace sync_pb { class UniquePosition; } @@ -40,7 +38,7 @@ // // This class currently has several bookmarks-related assumptions built in, // though it could be adapted to be more generally useful. -class SYNC_EXPORT UniquePosition { +class UniquePosition { public: static const size_t kSuffixLength; static const size_t kCompressBytesThreshold;
diff --git a/components/sync/base/weak_handle.h b/components/sync/base/weak_handle.h index 4dda6e9..54fa9d74 100644 --- a/components/sync/base/weak_handle.h +++ b/components/sync/base/weak_handle.h
@@ -59,7 +59,6 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" -#include "components/sync/base/sync_export.h" namespace tracked_objects { class Location; @@ -76,7 +75,7 @@ // Base class for WeakHandleCore<T> to avoid template bloat. Handles // the interaction with the owner thread and its message loop. -class SYNC_EXPORT WeakHandleCoreBase { +class WeakHandleCoreBase { public: // Assumes the current thread is the owner thread. WeakHandleCoreBase();
diff --git a/components/sync/core/activation_context.h b/components/sync/core/activation_context.h index e35ad90..ea904f7 100644 --- a/components/sync/core/activation_context.h +++ b/components/sync/core/activation_context.h
@@ -8,7 +8,6 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/sequenced_task_runner.h" -#include "components/sync/base/sync_export.h" #include "components/sync/core/model_type_processor.h" #include "components/sync/core/non_blocking_sync_common.h" #include "components/sync/protocol/data_type_state.pb.h" @@ -17,7 +16,7 @@ // The state passed from ModelTypeProcessor to Sync thread during DataType // activation. -struct SYNC_EXPORT ActivationContext { +struct ActivationContext { ActivationContext(); ~ActivationContext();
diff --git a/components/sync/core/attachments/attachment_downloader.h b/components/sync/core/attachments/attachment_downloader.h index b9f9fbf..35c67b4 100644 --- a/components/sync/core/attachments/attachment_downloader.h +++ b/components/sync/core/attachments/attachment_downloader.h
@@ -11,7 +11,6 @@ #include "base/callback.h" #include "components/sync/api/attachments/attachment.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "google_apis/gaia/oauth2_token_service_request.h" namespace net { @@ -21,7 +20,7 @@ namespace syncer { // AttachmentDownloader is responsible for downloading attachments from server. -class SYNC_EXPORT AttachmentDownloader { +class AttachmentDownloader { public: // The result of a DownloadAttachment operation. enum DownloadResult {
diff --git a/components/sync/core/attachments/attachment_downloader_impl.h b/components/sync/core/attachments/attachment_downloader_impl.h index 5200c58..41cdb06 100644 --- a/components/sync/core/attachments/attachment_downloader_impl.h +++ b/components/sync/core/attachments/attachment_downloader_impl.h
@@ -104,8 +104,8 @@ // Return true if a crc32c was found and useable for checking data integrity. // "Usable" means headers are present, there is "x-goog-hash" header with // "crc32c" hash in it, this hash is correctly base64 encoded 32 bit integer. - SYNC_EXPORT static bool ExtractCrc32c(const net::HttpResponseHeaders* headers, - uint32_t* crc32c); + static bool ExtractCrc32c(const net::HttpResponseHeaders* headers, + uint32_t* crc32c); GURL sync_service_url_; scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
diff --git a/components/sync/core/attachments/attachment_service.h b/components/sync/core/attachments/attachment_service.h index ec95e39..b590372 100644 --- a/components/sync/core/attachments/attachment_service.h +++ b/components/sync/core/attachments/attachment_service.h
@@ -10,7 +10,6 @@ #include "base/callback.h" #include "base/memory/weak_ptr.h" #include "components/sync/api/attachments/attachment.h" -#include "components/sync/base/sync_export.h" namespace syncer { @@ -24,7 +23,7 @@ // // Destroying this object does not necessarily cancel outstanding async // operations. If you need cancel like semantics, use WeakPtr in the callbacks. -class SYNC_EXPORT AttachmentService { +class AttachmentService { public: // The result of a GetOrDownloadAttachments operation. enum GetOrDownloadResult {
diff --git a/components/sync/core/attachments/attachment_service_impl.h b/components/sync/core/attachments/attachment_service_impl.h index 53aa77c5..2e64218e 100644 --- a/components/sync/core/attachments/attachment_service_impl.h +++ b/components/sync/core/attachments/attachment_service_impl.h
@@ -22,7 +22,7 @@ namespace syncer { // Implementation of AttachmentService. -class SYNC_EXPORT AttachmentServiceImpl +class AttachmentServiceImpl : public AttachmentService, public net::NetworkChangeNotifier::NetworkChangeObserver, public base::NonThreadSafe {
diff --git a/components/sync/core/attachments/attachment_service_proxy.h b/components/sync/core/attachments/attachment_service_proxy.h index d76aea0f..b7a4e73a 100644 --- a/components/sync/core/attachments/attachment_service_proxy.h +++ b/components/sync/core/attachments/attachment_service_proxy.h
@@ -11,7 +11,6 @@ #include "base/sequenced_task_runner.h" #include "base/task_runner.h" #include "components/sync/api/attachments/attachment.h" -#include "components/sync/base/sync_export.h" #include "components/sync/core/attachments/attachment_service.h" namespace syncer { @@ -31,7 +30,7 @@ // correct thread (wrapped_task_runner). // // This class is thread-safe and is designed to be passed by const-ref. -class SYNC_EXPORT AttachmentServiceProxy : public AttachmentService { +class AttachmentServiceProxy : public AttachmentService { public: // Default copy and assignment are welcome. @@ -69,8 +68,8 @@ // // Calls to objects of this class become no-ops once its wrapped object is // destroyed. - class SYNC_EXPORT Core : public AttachmentService, - public base::RefCountedThreadSafe<Core> { + class Core : public AttachmentService, + public base::RefCountedThreadSafe<Core> { public: // Construct an AttachmentServiceProxyCore that forwards calls to |wrapped|. explicit Core(const base::WeakPtr<syncer::AttachmentService>& wrapped);
diff --git a/components/sync/core/attachments/attachment_service_proxy_for_test.h b/components/sync/core/attachments/attachment_service_proxy_for_test.h index f9edcf6..c47aec4 100644 --- a/components/sync/core/attachments/attachment_service_proxy_for_test.h +++ b/components/sync/core/attachments/attachment_service_proxy_for_test.h
@@ -9,7 +9,6 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "components/sync/base/sync_export.h" #include "components/sync/core/attachments/attachment_service_proxy.h" namespace syncer { @@ -19,8 +18,7 @@ // Constructs and owns an AttachmentService suitable for use in tests. // NOTE: This class does not require the current thread to have a MessageLoop, // however all methods will effectively become no-op stubs in that case. -class SYNC_EXPORT AttachmentServiceProxyForTest - : public AttachmentServiceProxy { +class AttachmentServiceProxyForTest : public AttachmentServiceProxy { public: static AttachmentServiceProxy Create(); ~AttachmentServiceProxyForTest() override;
diff --git a/components/sync/core/attachments/attachment_store_frontend.h b/components/sync/core/attachments/attachment_store_frontend.h index 283ff75..fa9e6ce14 100644 --- a/components/sync/core/attachments/attachment_store_frontend.h +++ b/components/sync/core/attachments/attachment_store_frontend.h
@@ -29,7 +29,7 @@ // model thread. // Method signatures of AttachmentStoreFrontend match exactly methods of // AttachmentStoreBackend. -class SYNC_EXPORT AttachmentStoreFrontend +class AttachmentStoreFrontend : public base::RefCounted<AttachmentStoreFrontend>, public base::NonThreadSafe { public:
diff --git a/components/sync/core/attachments/attachment_uploader.h b/components/sync/core/attachments/attachment_uploader.h index b837862..d7c583d 100644 --- a/components/sync/core/attachments/attachment_uploader.h +++ b/components/sync/core/attachments/attachment_uploader.h
@@ -7,12 +7,11 @@ #include "base/callback.h" #include "components/sync/api/attachments/attachment.h" -#include "components/sync/base/sync_export.h" namespace syncer { // AttachmentUploader is responsible for uploading attachments to the server. -class SYNC_EXPORT AttachmentUploader { +class AttachmentUploader { public: // The result of an UploadAttachment operation. enum UploadResult {
diff --git a/components/sync/core/attachments/attachment_uploader_impl.h b/components/sync/core/attachments/attachment_uploader_impl.h index 5c5dea9..4d4373cf 100644 --- a/components/sync/core/attachments/attachment_uploader_impl.h +++ b/components/sync/core/attachments/attachment_uploader_impl.h
@@ -26,8 +26,8 @@ namespace syncer { // An implementation of AttachmentUploader. -class SYNC_EXPORT AttachmentUploaderImpl : public AttachmentUploader, - public base::NonThreadSafe { +class AttachmentUploaderImpl : public AttachmentUploader, + public base::NonThreadSafe { public: // |sync_service_url| is the URL of the sync service. //
diff --git a/components/sync/core/attachments/attachment_util.h b/components/sync/core/attachments/attachment_util.h index 21350ff9..cdf16ca 100644 --- a/components/sync/core/attachments/attachment_util.h +++ b/components/sync/core/attachments/attachment_util.h
@@ -8,7 +8,6 @@ #include <stdint.h> #include "base/memory/ref_counted.h" -#include "components/sync/base/sync_export.h" namespace base { class RefCountedMemory; @@ -22,8 +21,7 @@ // Ideally this function should be static function in Attachment class, but // include_rules from sync/api/DEPS don't allow direct dependency on // third_party. -SYNC_EXPORT uint32_t -ComputeCrc32c(const scoped_refptr<base::RefCountedMemory>& data); +uint32_t ComputeCrc32c(const scoped_refptr<base::RefCountedMemory>& data); } // namespace syncer
diff --git a/components/sync/core/attachments/fake_attachment_downloader.h b/components/sync/core/attachments/fake_attachment_downloader.h index 70543c2..68a224af 100644 --- a/components/sync/core/attachments/fake_attachment_downloader.h +++ b/components/sync/core/attachments/fake_attachment_downloader.h
@@ -13,8 +13,8 @@ // FakeAttachmentDownloader is for tests. For every request it posts a success // callback with empty attachment. -class SYNC_EXPORT FakeAttachmentDownloader : public AttachmentDownloader, - public base::NonThreadSafe { +class FakeAttachmentDownloader : public AttachmentDownloader, + public base::NonThreadSafe { public: FakeAttachmentDownloader(); ~FakeAttachmentDownloader() override;
diff --git a/components/sync/core/attachments/fake_attachment_uploader.h b/components/sync/core/attachments/fake_attachment_uploader.h index b517eda7..f697bd5 100644 --- a/components/sync/core/attachments/fake_attachment_uploader.h +++ b/components/sync/core/attachments/fake_attachment_uploader.h
@@ -12,8 +12,8 @@ namespace syncer { // A fake implementation of AttachmentUploader. -class SYNC_EXPORT FakeAttachmentUploader : public AttachmentUploader, - public base::NonThreadSafe { +class FakeAttachmentUploader : public AttachmentUploader, + public base::NonThreadSafe { public: FakeAttachmentUploader(); ~FakeAttachmentUploader() override;
diff --git a/components/sync/core/attachments/in_memory_attachment_store.h b/components/sync/core/attachments/in_memory_attachment_store.h index c4025ce..d16546ff 100644 --- a/components/sync/core/attachments/in_memory_attachment_store.h +++ b/components/sync/core/attachments/in_memory_attachment_store.h
@@ -15,7 +15,6 @@ #include "components/sync/api/attachments/attachment_id.h" #include "components/sync/api/attachments/attachment_store.h" #include "components/sync/api/attachments/attachment_store_backend.h" -#include "components/sync/base/sync_export.h" namespace base { class SequencedTaskRunner; @@ -26,8 +25,8 @@ // An in-memory implementation of AttachmentStore used for testing. // InMemoryAttachmentStore is not threadsafe, it lives on backend thread and // posts callbacks with results on |callback_task_runner|. -class SYNC_EXPORT InMemoryAttachmentStore : public AttachmentStoreBackend, - public base::NonThreadSafe { +class InMemoryAttachmentStore : public AttachmentStoreBackend, + public base::NonThreadSafe { public: InMemoryAttachmentStore( const scoped_refptr<base::SequencedTaskRunner>& callback_task_runner);
diff --git a/components/sync/core/attachments/on_disk_attachment_store.h b/components/sync/core/attachments/on_disk_attachment_store.h index b0576db..6e08e34 100644 --- a/components/sync/core/attachments/on_disk_attachment_store.h +++ b/components/sync/core/attachments/on_disk_attachment_store.h
@@ -15,7 +15,6 @@ #include "components/sync/api/attachments/attachment_id.h" #include "components/sync/api/attachments/attachment_store.h" #include "components/sync/api/attachments/attachment_store_backend.h" -#include "components/sync/base/sync_export.h" namespace attachment_store_pb { class RecordMetadata; @@ -33,8 +32,8 @@ // On-disk implementation of AttachmentStore. Stores attachments in leveldb // database in |path| directory. -class SYNC_EXPORT OnDiskAttachmentStore : public AttachmentStoreBackend, - public base::NonThreadSafe { +class OnDiskAttachmentStore : public AttachmentStoreBackend, + public base::NonThreadSafe { public: // Constructs attachment store. OnDiskAttachmentStore(
diff --git a/components/sync/core/base_node.h b/components/sync/core/base_node.h index 93394c10..6a362ef 100644 --- a/components/sync/core/base_node.h +++ b/components/sync/core/base_node.h
@@ -17,7 +17,6 @@ #include "base/time/time.h" #include "components/sync/api/attachments/attachment.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/protocol/sync.pb.h" #include "url/gurl.h" @@ -60,7 +59,7 @@ // transaction is necessary to create a BaseNode or any of its children. // Unlike syncable::Entry, a sync API BaseNode is identified primarily by its // int64_t metahandle, which we call an ID here. -class SYNC_EXPORT BaseNode { +class BaseNode { public: // Enumerates the possible outcomes of trying to initialize a sync node. enum InitByLookupResult {
diff --git a/components/sync/core/base_transaction.h b/components/sync/core/base_transaction.h index dfd92c7..ddc33491 100644 --- a/components/sync/core/base_transaction.h +++ b/components/sync/core/base_transaction.h
@@ -8,7 +8,6 @@ #include "base/macros.h" #include "components/sync/base/cryptographer.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/core/user_share.h" namespace syncer { @@ -28,7 +27,7 @@ // // Note, these transactions are not atomic. Individual operations can // fail. There is no built-in rollback or undo mechanism. -class SYNC_EXPORT BaseTransaction { +class BaseTransaction { public: // Provide access to the underlying syncable objects from BaseNode. virtual syncable::BaseTransaction* GetWrappedTrans() const = 0;
diff --git a/components/sync/core/change_record.h b/components/sync/core/change_record.h index f7b1b99..387a1e7 100644 --- a/components/sync/core/change_record.h +++ b/components/sync/core/change_record.h
@@ -12,7 +12,6 @@ #include "base/memory/linked_ptr.h" #include "components/sync/base/immutable.h" -#include "components/sync/base/sync_export.h" #include "components/sync/protocol/password_specifics.pb.h" #include "components/sync/protocol/sync.pb.h" @@ -24,7 +23,7 @@ // TODO(zea): One day get passwords playing nicely with the rest of encryption // and get rid of this. -class SYNC_EXPORT ExtraPasswordChangeRecordData { +class ExtraPasswordChangeRecordData { public: ExtraPasswordChangeRecordData(); explicit ExtraPasswordChangeRecordData( @@ -43,7 +42,7 @@ // operation. This gives the sync id of the node that changed, and the type // of change. To get the actual property values after an ADD or UPDATE, the // client should get the node with InitByIdLookup(), using the provided id. -struct SYNC_EXPORT ChangeRecord { +struct ChangeRecord { enum Action { ACTION_ADD, ACTION_DELETE,
diff --git a/components/sync/core/data_batch_impl.cc b/components/sync/core/data_batch_impl.cc index e67f31621..3eb9e8b 100644 --- a/components/sync/core/data_batch_impl.cc +++ b/components/sync/core/data_batch_impl.cc
@@ -10,18 +10,18 @@ DataBatchImpl::~DataBatchImpl() {} -void DataBatchImpl::Put(const std::string& client_tag, +void DataBatchImpl::Put(const std::string& storage_key, std::unique_ptr<EntityData> specifics) { - tag_data_pairs_.push_back(TagAndData(client_tag, std::move(specifics))); + key_data_pairs_.push_back(KeyAndData(storage_key, std::move(specifics))); } bool DataBatchImpl::HasNext() const { - return tag_data_pairs_.size() > read_index_; + return key_data_pairs_.size() > read_index_; } -TagAndData DataBatchImpl::Next() { +KeyAndData DataBatchImpl::Next() { DCHECK(HasNext()); - return std::move(tag_data_pairs_[read_index_++]); + return std::move(key_data_pairs_[read_index_++]); } } // namespace syncer_v2
diff --git a/components/sync/core/data_batch_impl.h b/components/sync/core/data_batch_impl.h index ad1f73dd..918416d 100644 --- a/components/sync/core/data_batch_impl.h +++ b/components/sync/core/data_batch_impl.h
@@ -21,25 +21,25 @@ // An implementation of DataBatch that's purpose is to transfer ownership of // EntityData objects. As soon as this batch recieves the EntityData, it owns // them until Next() is invoked, when it gives up ownerhsip. Because a vector -// is used internally, this impl is unaware when duplcate client_tags are used, +// is used internally, this impl is unaware when duplcate storage_keys are used, // and it is the caller's job to avoid this. -class SYNC_EXPORT DataBatchImpl : public DataBatch { +class DataBatchImpl : public DataBatch { public: DataBatchImpl(); ~DataBatchImpl() override; - // Takes ownership of the data tied to a given tag used for storage. Put - // should be called at most once for any given client_tag. Data will be + // Takes ownership of the data tied to a given key used for storage. Put + // should be called at most once for any given storfage_key. Data will be // readable in the same order that they are put into the batch. - void Put(const std::string& client_tag, + void Put(const std::string& storage_key, std::unique_ptr<EntityData> entity_data); // DataBatch implementation. bool HasNext() const override; - TagAndData Next() override; + KeyAndData Next() override; private: - std::vector<TagAndData> tag_data_pairs_; + std::vector<KeyAndData> key_data_pairs_; size_t read_index_ = 0; DISALLOW_COPY_AND_ASSIGN(DataBatchImpl);
diff --git a/components/sync/core/data_batch_impl_unittest.cc b/components/sync/core/data_batch_impl_unittest.cc index 3a51a491..86025cb6 100644 --- a/components/sync/core/data_batch_impl_unittest.cc +++ b/components/sync/core/data_batch_impl_unittest.cc
@@ -19,7 +19,7 @@ batch.Put("one", base::WrapUnique(entity1)); EXPECT_TRUE(batch.HasNext()); - const TagAndData& pair1 = batch.Next(); + const KeyAndData& pair1 = batch.Next(); EXPECT_FALSE(batch.HasNext()); EXPECT_EQ("one", pair1.first); EXPECT_EQ(entity1, pair1.second.get()); @@ -27,7 +27,7 @@ batch.Put("two", base::WrapUnique(entity2)); EXPECT_TRUE(batch.HasNext()); - const TagAndData& pair2 = batch.Next(); + const KeyAndData& pair2 = batch.Next(); EXPECT_FALSE(batch.HasNext()); EXPECT_EQ("two", pair2.first); EXPECT_EQ(entity2, pair2.second.get()); @@ -46,7 +46,7 @@ batch.Put("two", base::WrapUnique(entity2)); EXPECT_TRUE(batch.HasNext()); - const TagAndData& pair1 = batch.Next(); + const KeyAndData& pair1 = batch.Next(); EXPECT_TRUE(batch.HasNext()); EXPECT_EQ("one", pair1.first); EXPECT_EQ(entity1, pair1.second.get()); @@ -54,18 +54,18 @@ batch.Put("three", base::WrapUnique(entity3)); EXPECT_TRUE(batch.HasNext()); - const TagAndData& pair2 = batch.Next(); + const KeyAndData& pair2 = batch.Next(); EXPECT_TRUE(batch.HasNext()); EXPECT_EQ("two", pair2.first); EXPECT_EQ(entity2, pair2.second.get()); - const TagAndData& pair3 = batch.Next(); + const KeyAndData& pair3 = batch.Next(); EXPECT_FALSE(batch.HasNext()); EXPECT_EQ("three", pair3.first); EXPECT_EQ(entity3, pair3.second.get()); } -TEST(DataBatchImplTest, PutAndNextSharedTag) { +TEST(DataBatchImplTest, PutAndNextSharedKey) { EntityData* entity1 = new EntityData(); EntityData* entity2 = new EntityData(); @@ -77,12 +77,12 @@ batch.Put("same", base::WrapUnique(entity2)); EXPECT_TRUE(batch.HasNext()); - const TagAndData& pair1 = batch.Next(); + const KeyAndData& pair1 = batch.Next(); EXPECT_TRUE(batch.HasNext()); EXPECT_EQ("same", pair1.first); EXPECT_EQ(entity1, pair1.second.get()); - const TagAndData& pair2 = batch.Next(); + const KeyAndData& pair2 = batch.Next(); EXPECT_FALSE(batch.HasNext()); EXPECT_EQ("same", pair2.first); EXPECT_EQ(entity2, pair2.second.get());
diff --git a/components/sync/core/data_type_association_stats.h b/components/sync/core/data_type_association_stats.h index 33f0e89..a375c02 100644 --- a/components/sync/core/data_type_association_stats.h +++ b/components/sync/core/data_type_association_stats.h
@@ -8,12 +8,11 @@ #include <stdint.h> #include "base/time/time.h" -#include "components/sync/base/sync_export.h" namespace syncer { // Container for datatype association results. -struct SYNC_EXPORT DataTypeAssociationStats { +struct DataTypeAssociationStats { DataTypeAssociationStats(); DataTypeAssociationStats(const DataTypeAssociationStats& other); ~DataTypeAssociationStats();
diff --git a/components/sync/core/data_type_debug_info_listener.h b/components/sync/core/data_type_debug_info_listener.h index 40ca8fde..93c6a16 100644 --- a/components/sync/core/data_type_debug_info_listener.h +++ b/components/sync/core/data_type_debug_info_listener.h
@@ -12,7 +12,7 @@ namespace syncer { -struct SYNC_EXPORT DataTypeConfigurationStats { +struct DataTypeConfigurationStats { DataTypeConfigurationStats(); DataTypeConfigurationStats(const DataTypeConfigurationStats& other); ~DataTypeConfigurationStats();
diff --git a/components/sync/core/delete_journal.h b/components/sync/core/delete_journal.h index 30e1d97..e1bf993 100644 --- a/components/sync/core/delete_journal.h +++ b/components/sync/core/delete_journal.h
@@ -11,7 +11,6 @@ #include <vector> #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/protocol/sync.pb.h" namespace syncer { @@ -28,7 +27,7 @@ // Static APIs for passing delete journals between syncer::syncable namspace // and syncer namespace. -class SYNC_EXPORT DeleteJournal { +class DeleteJournal { public: // Return info about deleted bookmark entries stored in the delete journal // of |trans|'s directory.
diff --git a/components/sync/core/http_bridge.h b/components/sync/core/http_bridge.h index a4d37e6d..88509de 100644 --- a/components/sync/core/http_bridge.h +++ b/components/sync/core/http_bridge.h
@@ -18,7 +18,6 @@ #include "base/threading/thread_checker.h" #include "base/timer/timer.h" #include "components/sync/base/cancelation_observer.h" -#include "components/sync/base/sync_export.h" #include "components/sync/core/http_post_provider_factory.h" #include "components/sync/core/http_post_provider_interface.h" #include "components/sync/core/network_time_update_callback.h" @@ -46,9 +45,9 @@ // This is a one-time use bridge. Create one for each request you want to make. // It is RefCountedThreadSafe because it can PostTask to the io loop, and thus // needs to stick around across context switches, etc. -class SYNC_EXPORT HttpBridge : public base::RefCountedThreadSafe<HttpBridge>, - public HttpPostProviderInterface, - public net::URLFetcherDelegate { +class HttpBridge : public base::RefCountedThreadSafe<HttpBridge>, + public HttpPostProviderInterface, + public net::URLFetcherDelegate { public: HttpBridge(const std::string& user_agent, const scoped_refptr<net::URLRequestContextGetter>& context, @@ -187,8 +186,8 @@ DISALLOW_COPY_AND_ASSIGN(HttpBridge); }; -class SYNC_EXPORT HttpBridgeFactory : public HttpPostProviderFactory, - public CancelationObserver { +class HttpBridgeFactory : public HttpPostProviderFactory, + public CancelationObserver { public: HttpBridgeFactory( const scoped_refptr<net::URLRequestContextGetter>&
diff --git a/components/sync/core/http_bridge_network_resources.h b/components/sync/core/http_bridge_network_resources.h index 0f25fa24..59ecee3 100644 --- a/components/sync/core/http_bridge_network_resources.h +++ b/components/sync/core/http_bridge_network_resources.h
@@ -7,7 +7,6 @@ #include <memory> -#include "components/sync/base/sync_export.h" #include "components/sync/core/network_resources.h" #include "components/sync/core/network_time_update_callback.h" @@ -20,7 +19,7 @@ class CancelationSignal; class HttpPostProviderFactory; -class SYNC_EXPORT HttpBridgeNetworkResources : public NetworkResources { +class HttpBridgeNetworkResources : public NetworkResources { public: ~HttpBridgeNetworkResources() override;
diff --git a/components/sync/core/http_post_provider_factory.h b/components/sync/core/http_post_provider_factory.h index 2f33d485..d49ac39 100644 --- a/components/sync/core/http_post_provider_factory.h +++ b/components/sync/core/http_post_provider_factory.h
@@ -8,7 +8,6 @@ #include <string> #include "base/callback.h" -#include "components/sync/base/sync_export.h" namespace net { class URLFetcher; @@ -24,7 +23,7 @@ // implementations and dependencies. // A factory instance itself should be owned by whomever uses it to create // HttpPostProviders. -class SYNC_EXPORT HttpPostProviderFactory { +class HttpPostProviderFactory { public: virtual ~HttpPostProviderFactory() {}
diff --git a/components/sync/core/http_post_provider_interface.h b/components/sync/core/http_post_provider_interface.h index b1ac384..3a0906f 100644 --- a/components/sync/core/http_post_provider_interface.h +++ b/components/sync/core/http_post_provider_interface.h
@@ -7,15 +7,13 @@ #include <string> -#include "components/sync/base/sync_export.h" - namespace syncer { // An interface the embedding application (e.g. Chromium) implements to provide // required HTTP POST functionality to the syncer backend. This interface is // designed for one-time use. You create one, use it, and create another if you // want to make a subsequent POST. -class SYNC_EXPORT HttpPostProviderInterface { +class HttpPostProviderInterface { public: // Add additional headers to the request. virtual void SetExtraRequestHeaders(const char* headers) = 0;
diff --git a/components/sync/core/internal_components_factory.h b/components/sync/core/internal_components_factory.h index e4b9d2ee..6512d873 100644 --- a/components/sync/core/internal_components_factory.h +++ b/components/sync/core/internal_components_factory.h
@@ -14,7 +14,6 @@ #include <vector> #include "base/files/file_path.h" -#include "components/sync/base/sync_export.h" #include "components/sync/engine/model_safe_worker.h" namespace syncer { @@ -36,7 +35,7 @@ class DirectoryBackingStore; } -class SYNC_EXPORT InternalComponentsFactory { +class InternalComponentsFactory { public: enum EncryptionMethod { ENCRYPTION_LEGACY,
diff --git a/components/sync/core/internal_components_factory_impl.h b/components/sync/core/internal_components_factory_impl.h index 6c7a77a..bb7a9357 100644 --- a/components/sync/core/internal_components_factory_impl.h +++ b/components/sync/core/internal_components_factory_impl.h
@@ -12,13 +12,11 @@ #include <vector> #include "base/macros.h" -#include "components/sync/base/sync_export.h" #include "components/sync/core/internal_components_factory.h" namespace syncer { -class SYNC_EXPORT InternalComponentsFactoryImpl - : public InternalComponentsFactory { +class InternalComponentsFactoryImpl : public InternalComponentsFactory { public: explicit InternalComponentsFactoryImpl(const Switches& switches); ~InternalComponentsFactoryImpl() override;
diff --git a/components/sync/core/model_type_connector.h b/components/sync/core/model_type_connector.h index f078191e..941b382 100644 --- a/components/sync/core/model_type_connector.h +++ b/components/sync/core/model_type_connector.h
@@ -15,7 +15,7 @@ // An interface into the core parts of sync for USS model types. Handles // creating the connection between the ModelTypeWorker (CommitQueue) on the sync // side and the (Shared)ModelTypeProcessor on the model type side. -class SYNC_EXPORT ModelTypeConnector { +class ModelTypeConnector { public: ModelTypeConnector(); virtual ~ModelTypeConnector();
diff --git a/components/sync/core/model_type_processor.h b/components/sync/core/model_type_processor.h index 43ee6f34f..422a1e39 100644 --- a/components/sync/core/model_type_processor.h +++ b/components/sync/core/model_type_processor.h
@@ -7,7 +7,6 @@ #include <memory> -#include "components/sync/base/sync_export.h" #include "components/sync/core/non_blocking_sync_common.h" #include "components/sync/protocol/data_type_state.pb.h" @@ -15,7 +14,7 @@ class CommitQueue; // Interface used by sync backend to issue requests to a synced data type. -class SYNC_EXPORT ModelTypeProcessor { +class ModelTypeProcessor { public: ModelTypeProcessor(); virtual ~ModelTypeProcessor();
diff --git a/components/sync/core/model_type_store_backend.h b/components/sync/core/model_type_store_backend.h index f0aece5..a6e9df1 100644 --- a/components/sync/core/model_type_store_backend.h +++ b/components/sync/core/model_type_store_backend.h
@@ -13,7 +13,6 @@ #include "base/macros.h" #include "base/threading/thread_collision_warner.h" #include "components/sync/api/model_type_store.h" -#include "components/sync/base/sync_export.h" namespace leveldb { class DB; @@ -26,7 +25,7 @@ // ModelTypeStoreBackend handles operations with leveldb. It is oblivious of the // fact that it is called from separate thread (with the exception of ctor), // meaning it shouldn't deal with callbacks and task_runners. -class SYNC_EXPORT ModelTypeStoreBackend +class ModelTypeStoreBackend : public base::RefCountedThreadSafe<ModelTypeStoreBackend> { public: typedef std::unordered_map<std::string, ModelTypeStoreBackend*> BackendMap;
diff --git a/components/sync/core/network_resources.h b/components/sync/core/network_resources.h index b9e05627..db1d2b2 100644 --- a/components/sync/core/network_resources.h +++ b/components/sync/core/network_resources.h
@@ -7,7 +7,6 @@ #include <memory> -#include "components/sync/base/sync_export.h" #include "components/sync/core/network_time_update_callback.h" namespace net { @@ -19,7 +18,7 @@ class CancelationSignal; class HttpPostProviderFactory; -class SYNC_EXPORT NetworkResources { +class NetworkResources { public: virtual ~NetworkResources() {}
diff --git a/components/sync/core/non_blocking_sync_common.h b/components/sync/core/non_blocking_sync_common.h index 5f3c09c..6b8b792 100644 --- a/components/sync/core/non_blocking_sync_common.h +++ b/components/sync/core/non_blocking_sync_common.h
@@ -12,14 +12,13 @@ #include "base/time/time.h" #include "components/sync/api/entity_data.h" -#include "components/sync/base/sync_export.h" #include "components/sync/protocol/sync.pb.h" namespace syncer_v2 { static const int64_t kUncommittedVersion = -1; -struct SYNC_EXPORT CommitRequestData { +struct CommitRequestData { CommitRequestData(); CommitRequestData(const CommitRequestData& other); ~CommitRequestData(); @@ -34,7 +33,7 @@ std::string specifics_hash; }; -struct SYNC_EXPORT CommitResponseData { +struct CommitResponseData { CommitResponseData(); CommitResponseData(const CommitResponseData& other); ~CommitResponseData(); @@ -46,7 +45,7 @@ std::string specifics_hash; }; -struct SYNC_EXPORT UpdateResponseData { +struct UpdateResponseData { UpdateResponseData(); UpdateResponseData(const UpdateResponseData& other); ~UpdateResponseData();
diff --git a/components/sync/core/processor_entity_tracker.cc b/components/sync/core/processor_entity_tracker.cc index 41d3456..13a584bd 100644 --- a/components/sync/core/processor_entity_tracker.cc +++ b/components/sync/core/processor_entity_tracker.cc
@@ -26,7 +26,7 @@ } // namespace std::unique_ptr<ProcessorEntityTracker> ProcessorEntityTracker::CreateNew( - const std::string& client_tag, + const std::string& storage_key, const std::string& client_tag_hash, const std::string& id, base::Time creation_time) { @@ -41,20 +41,20 @@ metadata.set_creation_time(syncer::TimeToProtoTime(creation_time)); return std::unique_ptr<ProcessorEntityTracker>( - new ProcessorEntityTracker(client_tag, &metadata)); + new ProcessorEntityTracker(storage_key, &metadata)); } std::unique_ptr<ProcessorEntityTracker> -ProcessorEntityTracker::CreateFromMetadata(const std::string& client_tag, +ProcessorEntityTracker::CreateFromMetadata(const std::string& storage_key, sync_pb::EntityMetadata* metadata) { return std::unique_ptr<ProcessorEntityTracker>( - new ProcessorEntityTracker(client_tag, metadata)); + new ProcessorEntityTracker(storage_key, metadata)); } ProcessorEntityTracker::ProcessorEntityTracker( - const std::string& client_tag, + const std::string& storage_key, sync_pb::EntityMetadata* metadata) - : client_tag_(client_tag), + : storage_key_(storage_key), commit_requested_sequence_number_(metadata->acked_sequence_number()) { DCHECK(metadata->has_client_tag_hash()); DCHECK(metadata->has_creation_time());
diff --git a/components/sync/core/processor_entity_tracker.h b/components/sync/core/processor_entity_tracker.h index 1a6d3f82..c41819ea 100644 --- a/components/sync/core/processor_entity_tracker.h +++ b/components/sync/core/processor_entity_tracker.h
@@ -12,7 +12,6 @@ #include "base/time/time.h" #include "components/sync/api/entity_data.h" -#include "components/sync/base/sync_export.h" #include "components/sync/protocol/entity_metadata.pb.h" namespace syncer_v2 { @@ -24,11 +23,11 @@ // entity with its type. It can be considered a helper class internal to the // processor. It manages the metadata for its entity and caches entity data // upon a local change until commit confirmation is received. -class SYNC_EXPORT ProcessorEntityTracker { +class ProcessorEntityTracker { public: // Construct an instance representing a new locally-created item. static std::unique_ptr<ProcessorEntityTracker> CreateNew( - const std::string& client_tag, + const std::string& storage_key, const std::string& client_tag_hash, const std::string& id, base::Time creation_time); @@ -36,12 +35,12 @@ // Construct an instance representing an item loaded from storage on init. // This method swaps out the contents of |metadata|. static std::unique_ptr<ProcessorEntityTracker> CreateFromMetadata( - const std::string& client_tag, + const std::string& storage_key, sync_pb::EntityMetadata* metadata); ~ProcessorEntityTracker(); - const std::string& client_tag() const { return client_tag_; } + const std::string& storage_key() const { return storage_key_; } const sync_pb::EntityMetadata& metadata() const { return metadata_; } const EntityDataPtr& commit_data() const { return commit_data_; } @@ -126,7 +125,7 @@ friend class ProcessorEntityTrackerTest; // The constructor swaps the data from the passed metadata. - ProcessorEntityTracker(const std::string& client_tag, + ProcessorEntityTracker(const std::string& storage_key, sync_pb::EntityMetadata* metadata); // Check whether |specifics| matches the stored specifics_hash. @@ -135,8 +134,8 @@ // Update hash string for EntitySpecifics in the metadata. void UpdateSpecificsHash(const sync_pb::EntitySpecifics& specifics); - // Client tag. Should always be available. - std::string client_tag_; + // Storage key. Should always be available. + const std::string storage_key_; // Serializable Sync metadata. sync_pb::EntityMetadata metadata_;
diff --git a/components/sync/core/processor_entity_tracker_unittest.cc b/components/sync/core/processor_entity_tracker_unittest.cc index 244ccae0..c49c122 100644 --- a/components/sync/core/processor_entity_tracker_unittest.cc +++ b/components/sync/core/processor_entity_tracker_unittest.cc
@@ -22,40 +22,40 @@ namespace { -const std::string kTag = "tag"; -const std::string kId = "id"; -const std::string kValue1 = "value1"; -const std::string kValue2 = "value2"; -const std::string kValue3 = "value3"; +const char kKey[] = "key"; +const char kHash[] = "hash"; +const char kId[] = "id"; +const char kName[] = "name"; +const char kValue1[] = "value1"; +const char kValue2[] = "value2"; +const char kValue3[] = "value3"; -std::string GenerateTagHash(const std::string& tag) { - return syncer::syncable::GenerateSyncableHash(syncer::PREFERENCES, tag); -} - -sync_pb::EntitySpecifics GenerateSpecifics(const std::string& tag, +sync_pb::EntitySpecifics GenerateSpecifics(const std::string& name, const std::string& value) { sync_pb::EntitySpecifics specifics; - specifics.mutable_preference()->set_name(tag); + specifics.mutable_preference()->set_name(name); specifics.mutable_preference()->set_value(value); return specifics; } -std::unique_ptr<EntityData> GenerateEntityData(const std::string& tag, +std::unique_ptr<EntityData> GenerateEntityData(const std::string& hash, + const std::string& name, const std::string& value) { std::unique_ptr<EntityData> entity_data(new EntityData()); - entity_data->client_tag_hash = GenerateTagHash(tag); - entity_data->specifics = GenerateSpecifics(tag, value); - entity_data->non_unique_name = tag; + entity_data->client_tag_hash = hash; + entity_data->specifics = GenerateSpecifics(name, value); + entity_data->non_unique_name = name; return entity_data; } UpdateResponseData GenerateUpdate(const ProcessorEntityTracker& entity, + const std::string& hash, const std::string& id, + const std::string& name, const std::string& value, const base::Time& mtime, int64_t version) { - std::unique_ptr<EntityData> data = - GenerateEntityData(entity.client_tag(), value); + std::unique_ptr<EntityData> data = GenerateEntityData(hash, name, value); data->id = id; data->modification_time = mtime; UpdateResponseData update; @@ -65,12 +65,14 @@ } UpdateResponseData GenerateTombstone(const ProcessorEntityTracker& entity, + const std::string& hash, const std::string& id, + const std::string& name, const base::Time& mtime, int64_t version) { std::unique_ptr<EntityData> data = base::WrapUnique(new EntityData()); - data->client_tag_hash = GenerateTagHash(entity.client_tag()); - data->non_unique_name = entity.client_tag(); + data->client_tag_hash = hash; + data->non_unique_name = name; data->id = id; data->modification_time = mtime; UpdateResponseData update; @@ -80,9 +82,10 @@ } CommitResponseData GenerateAckData(const CommitRequestData& request, + const std::string id, int64_t version) { CommitResponseData response; - response.id = kId; + response.id = id; response.client_tag_hash = request.entity->client_tag_hash; response.sequence_number = request.sequence_number; response.response_version = version; @@ -104,22 +107,20 @@ class ProcessorEntityTrackerTest : public ::testing::Test { public: ProcessorEntityTrackerTest() - : tag_hash_(GenerateTagHash(kTag)), - ctime_(base::Time::Now() - base::TimeDelta::FromSeconds(1)){}; + : ctime_(base::Time::Now() - base::TimeDelta::FromSeconds(1)) {} std::unique_ptr<ProcessorEntityTracker> CreateNew() { - return ProcessorEntityTracker::CreateNew(kTag, tag_hash_, "", ctime_); + return ProcessorEntityTracker::CreateNew(kKey, kHash, "", ctime_); } std::unique_ptr<ProcessorEntityTracker> CreateSynced() { std::unique_ptr<ProcessorEntityTracker> entity = CreateNew(); entity->RecordAcceptedUpdate( - GenerateUpdate(*entity, kId, kValue1, ctime_, 1)); + GenerateUpdate(*entity, kHash, kId, kName, kValue1, ctime_, 1)); DCHECK(!entity->IsUnsynced()); return entity; } - const std::string tag_hash_; const base::Time ctime_; }; @@ -127,8 +128,8 @@ TEST_F(ProcessorEntityTrackerTest, DefaultTracker) { std::unique_ptr<ProcessorEntityTracker> entity = CreateNew(); - EXPECT_EQ(kTag, entity->client_tag()); - EXPECT_EQ(tag_hash_, entity->metadata().client_tag_hash()); + EXPECT_EQ(kKey, entity->storage_key()); + EXPECT_EQ(kHash, entity->metadata().client_tag_hash()); EXPECT_EQ("", entity->metadata().server_id()); EXPECT_FALSE(entity->metadata().is_deleted()); EXPECT_EQ(0, entity->metadata().sequence_number()); @@ -151,7 +152,7 @@ // Test creating and commiting a new local item. TEST_F(ProcessorEntityTrackerTest, NewLocalItem) { std::unique_ptr<ProcessorEntityTracker> entity = CreateNew(); - entity->MakeLocalChange(GenerateEntityData(kTag, kValue1)); + entity->MakeLocalChange(GenerateEntityData(kHash, kName, kValue1)); EXPECT_EQ("", entity->metadata().server_id()); EXPECT_FALSE(entity->metadata().is_deleted()); @@ -187,8 +188,8 @@ const EntityData& data = request.entity.value(); EXPECT_EQ("", data.id); - EXPECT_EQ(tag_hash_, data.client_tag_hash); - EXPECT_EQ(kTag, data.non_unique_name); + EXPECT_EQ(kHash, data.client_tag_hash); + EXPECT_EQ(kName, data.non_unique_name); EXPECT_EQ(kValue1, data.specifics.preference().value()); EXPECT_EQ(syncer::TimeToProtoTime(ctime_), syncer::TimeToProtoTime(data.creation_time)); @@ -200,7 +201,7 @@ EXPECT_EQ(entity->metadata().specifics_hash(), request.specifics_hash); // Ack the commit. - entity->ReceiveCommitResponse(GenerateAckData(request, 1)); + entity->ReceiveCommitResponse(GenerateAckData(request, kId, 1)); EXPECT_EQ(kId, entity->metadata().server_id()); EXPECT_FALSE(entity->metadata().is_deleted()); @@ -227,7 +228,7 @@ const base::Time mtime = base::Time::Now(); entity->RecordAcceptedUpdate( - GenerateUpdate(*entity, kId, kValue1, mtime, 10)); + GenerateUpdate(*entity, kHash, kId, kName, kValue1, mtime, 10)); EXPECT_EQ(kId, entity->metadata().server_id()); EXPECT_FALSE(entity->metadata().is_deleted()); @@ -254,7 +255,8 @@ std::unique_ptr<ProcessorEntityTracker> entity = CreateNew(); const base::Time mtime = base::Time::Now(); - entity->RecordAcceptedUpdate(GenerateTombstone(*entity, kId, mtime, 1)); + entity->RecordAcceptedUpdate( + GenerateTombstone(*entity, kHash, kId, kName, mtime, 1)); EXPECT_EQ(kId, entity->metadata().server_id()); EXPECT_TRUE(entity->metadata().is_deleted()); @@ -281,7 +283,8 @@ std::unique_ptr<ProcessorEntityTracker> entity = CreateSynced(); // A deletion update one version later. const base::Time mtime = base::Time::Now(); - entity->RecordAcceptedUpdate(GenerateTombstone(*entity, kId, mtime, 2)); + entity->RecordAcceptedUpdate( + GenerateTombstone(*entity, kHash, kId, kName, mtime, 2)); EXPECT_TRUE(entity->metadata().is_deleted()); EXPECT_EQ(0, entity->metadata().sequence_number()); @@ -308,7 +311,7 @@ const std::string specifics_hash_v0 = entity->metadata().specifics_hash(); // Make a local change with different specifics. - entity->MakeLocalChange(GenerateEntityData(kTag, kValue2)); + entity->MakeLocalChange(GenerateEntityData(kHash, kName, kValue2)); const int64_t mtime_v1 = entity->metadata().modification_time(); const std::string specifics_hash_v1 = entity->metadata().specifics_hash(); @@ -335,7 +338,7 @@ EXPECT_FALSE(entity->RequiresCommitRequest()); // Ack the commit. - entity->ReceiveCommitResponse(GenerateAckData(request, 2)); + entity->ReceiveCommitResponse(GenerateAckData(request, kId, 2)); EXPECT_EQ(1, entity->metadata().sequence_number()); EXPECT_EQ(1, entity->metadata().acked_sequence_number()); @@ -389,7 +392,7 @@ const EntityData& data = request.entity.value(); EXPECT_EQ(kId, data.id); - EXPECT_EQ(tag_hash_, data.client_tag_hash); + EXPECT_EQ(kHash, data.client_tag_hash); EXPECT_EQ("", data.non_unique_name); EXPECT_EQ(syncer::TimeToProtoTime(ctime_), syncer::TimeToProtoTime(data.creation_time)); @@ -401,7 +404,7 @@ EXPECT_EQ(entity->metadata().specifics_hash(), request.specifics_hash); // Ack the deletion. - entity->ReceiveCommitResponse(GenerateAckData(request, 2)); + entity->ReceiveCommitResponse(GenerateAckData(request, kId, 2)); EXPECT_TRUE(entity->metadata().is_deleted()); EXPECT_EQ(1, entity->metadata().sequence_number()); @@ -426,7 +429,7 @@ const std::string specifics_hash_v0 = entity->metadata().specifics_hash(); // Make the first change. - entity->MakeLocalChange(GenerateEntityData(kTag, kValue2)); + entity->MakeLocalChange(GenerateEntityData(kHash, kName, kValue2)); const std::string specifics_hash_v1 = entity->metadata().specifics_hash(); EXPECT_EQ(1, entity->metadata().sequence_number()); @@ -439,7 +442,7 @@ entity->InitializeCommitRequestData(&request_v1); // Make the second change. - entity->MakeLocalChange(GenerateEntityData(kTag, kValue3)); + entity->MakeLocalChange(GenerateEntityData(kHash, kName, kValue3)); const std::string specifics_hash_v2 = entity->metadata().specifics_hash(); EXPECT_EQ(2, entity->metadata().sequence_number()); @@ -458,7 +461,7 @@ EXPECT_TRUE(entity->HasCommitData()); // Ack the first commit. - entity->ReceiveCommitResponse(GenerateAckData(request_v1, 2)); + entity->ReceiveCommitResponse(GenerateAckData(request_v1, kId, 2)); EXPECT_EQ(2, entity->metadata().sequence_number()); EXPECT_EQ(1, entity->metadata().acked_sequence_number()); @@ -467,7 +470,7 @@ EXPECT_EQ(specifics_hash_v1, entity->metadata().base_specifics_hash()); // Ack the second commit. - entity->ReceiveCommitResponse(GenerateAckData(request_v2, 3)); + entity->ReceiveCommitResponse(GenerateAckData(request_v2, kId, 3)); EXPECT_EQ(2, entity->metadata().sequence_number()); EXPECT_EQ(2, entity->metadata().acked_sequence_number());
diff --git a/components/sync/core/read_node.h b/components/sync/core/read_node.h index 938b804f..c1a11fd 100644 --- a/components/sync/core/read_node.h +++ b/components/sync/core/read_node.h
@@ -13,14 +13,13 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/core/base_node.h" namespace syncer { // ReadNode wraps a syncable::Entry to provide the functionality of a // read-only BaseNode. -class SYNC_EXPORT ReadNode : public BaseNode { +class ReadNode : public BaseNode { public: // Create an unpopulated ReadNode on the given transaction. Call some flavor // of Init to populate the ReadNode with a database entry.
diff --git a/components/sync/core/read_transaction.h b/components/sync/core/read_transaction.h index e5cf5a1..f1982b2 100644 --- a/components/sync/core/read_transaction.h +++ b/components/sync/core/read_transaction.h
@@ -13,7 +13,6 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "components/sync/api/attachments/attachment_id.h" -#include "components/sync/base/sync_export.h" #include "components/sync/core/base_transaction.h" namespace tracked_objects { @@ -30,7 +29,7 @@ // Sync API's ReadTransaction is a read-only BaseTransaction. It wraps // a syncable::ReadTransaction. -class SYNC_EXPORT ReadTransaction : public BaseTransaction { +class ReadTransaction : public BaseTransaction { public: // Start a new read-only transaction on the specified repository. ReadTransaction(const tracked_objects::Location& from_here, UserShare* share);
diff --git a/components/sync/core/shared_model_type_processor.cc b/components/sync/core/shared_model_type_processor.cc index 133e23f5..0deff59 100644 --- a/components/sync/core/shared_model_type_processor.cc +++ b/components/sync/core/shared_model_type_processor.cc
@@ -137,8 +137,10 @@ std::unique_ptr<ProcessorEntityTracker> entity = ProcessorEntityTracker::CreateFromMetadata(it->first, &it->second); if (entity->RequiresCommitData()) { - entities_to_commit.push_back(entity->client_tag()); + entities_to_commit.push_back(entity->storage_key()); } + storage_key_to_tag_hash_[entity->storage_key()] = + entity->metadata().client_tag_hash(); entities_[entity->metadata().client_tag_hash()] = std::move(entity); } data_type_state_ = batch->GetDataTypeState(); @@ -193,7 +195,7 @@ std::unique_ptr<MetadataChangeList> change_list = service_->CreateMetadataChangeList(); for (auto it = entities_.begin(); it != entities_.end(); ++it) { - change_list->ClearMetadata(it->second->client_tag()); + change_list->ClearMetadata(it->second->storage_key()); } change_list->ClearDataTypeState(); // Nothing to do if this fails, so just ignore the error it might return. @@ -234,7 +236,7 @@ } } -void SharedModelTypeProcessor::Put(const std::string& tag, +void SharedModelTypeProcessor::Put(const std::string& storage_key, std::unique_ptr<EntityData> data, MetadataChangeList* metadata_change_list) { DCHECK(IsAllowingChanges()); @@ -249,7 +251,7 @@ } // Fill in some data. - data->client_tag_hash = GetHashForTag(tag); + data->client_tag_hash = GetClientTagHash(storage_key, *data); if (data->modification_time.is_null()) { data->modification_time = base::Time::Now(); } @@ -261,20 +263,20 @@ if (data->creation_time.is_null()) { data->creation_time = data->modification_time; } - entity = CreateEntity(tag, *data); + entity = CreateEntity(storage_key, *data); } else if (entity->MatchesData(*data)) { // Ignore changes that don't actually change anything. return; } entity->MakeLocalChange(std::move(data)); - metadata_change_list->UpdateMetadata(tag, entity->metadata()); + metadata_change_list->UpdateMetadata(storage_key, entity->metadata()); FlushPendingCommitRequests(); } void SharedModelTypeProcessor::Delete( - const std::string& tag, + const std::string& storage_key, MetadataChangeList* metadata_change_list) { DCHECK(IsAllowingChanges()); @@ -283,18 +285,18 @@ return; } - ProcessorEntityTracker* entity = GetEntityForTag(tag); + ProcessorEntityTracker* entity = GetEntityForStorageKey(storage_key); if (entity == nullptr) { // That's unusual, but not necessarily a bad thing. // Missing is as good as deleted as far as the model is concerned. DLOG(WARNING) << "Attempted to delete missing item." - << " client tag: " << tag; + << " storage key: " << storage_key; return; } entity->Delete(); - metadata_change_list->UpdateMetadata(tag, entity->metadata()); + metadata_change_list->UpdateMetadata(storage_key, entity->metadata()); FlushPendingCommitRequests(); } @@ -344,10 +346,10 @@ entity->ReceiveCommitResponse(data); if (entity->CanClearMetadata()) { - change_list->ClearMetadata(entity->client_tag()); + change_list->ClearMetadata(entity->storage_key()); entities_.erase(entity->metadata().client_tag_hash()); } else { - change_list->UpdateMetadata(entity->client_tag(), entity->metadata()); + change_list->UpdateMetadata(entity->storage_key(), entity->metadata()); } } @@ -390,15 +392,15 @@ } if (entity->CanClearMetadata()) { - metadata_changes->ClearMetadata(entity->client_tag()); + metadata_changes->ClearMetadata(entity->storage_key()); entities_.erase(entity->metadata().client_tag_hash()); } else { - metadata_changes->UpdateMetadata(entity->client_tag(), + metadata_changes->UpdateMetadata(entity->storage_key(), entity->metadata()); } if (got_new_encryption_requirements) { - already_updated.insert(entity->client_tag()); + already_updated.insert(entity->storage_key()); } } @@ -433,7 +435,7 @@ entity = CreateEntity(data); entity_changes->push_back( - EntityChange::CreateAdd(entity->client_tag(), update.entity)); + EntityChange::CreateAdd(entity->storage_key(), update.entity)); entity->RecordAcceptedUpdate(update); } else if (entity->UpdateIsReflection(update.response_version)) { // Seen this update before; just ignore it. @@ -448,12 +450,13 @@ // can never be deleted at this point because it would have either been // acked (the add case) or pending (the conflict case). DCHECK(!entity->metadata().is_deleted()); - entity_changes->push_back(EntityChange::CreateDelete(entity->client_tag())); + entity_changes->push_back( + EntityChange::CreateDelete(entity->storage_key())); entity->RecordAcceptedUpdate(update); } else if (!entity->MatchesData(data)) { // Specifics have changed, so update the service. entity_changes->push_back( - EntityChange::CreateUpdate(entity->client_tag(), update.entity)); + EntityChange::CreateUpdate(entity->storage_key(), update.entity)); entity->RecordAcceptedUpdate(update); } else { // No data change; still record that the update was received. @@ -529,7 +532,7 @@ entity->RecordForcedUpdate(update); // Update client data to match server. changes->push_back( - EntityChange::CreateUpdate(entity->client_tag(), update.entity)); + EntityChange::CreateUpdate(entity->storage_key(), update.entity)); break; case ConflictResolution::USE_NEW: // Record that we received the update. @@ -537,7 +540,7 @@ // Make a new pending commit to update the server. entity->MakeLocalChange(std::move(new_data)); // Update the client with the new entity. - changes->push_back(EntityChange::CreateUpdate(entity->client_tag(), + changes->push_back(EntityChange::CreateUpdate(entity->storage_key(), entity->commit_data())); break; case ConflictResolution::TYPE_SIZE: @@ -552,18 +555,18 @@ void SharedModelTypeProcessor::RecommitAllForEncryption( std::unordered_set<std::string> already_updated, MetadataChangeList* metadata_changes) { - ModelTypeService::ClientTagList entities_needing_data; + ModelTypeService::StorageKeyList entities_needing_data; for (auto it = entities_.begin(); it != entities_.end(); ++it) { ProcessorEntityTracker* entity = it->second.get(); - if (already_updated.find(entity->client_tag()) != already_updated.end()) { + if (already_updated.find(entity->storage_key()) != already_updated.end()) { continue; } entity->IncrementSequenceNumber(); if (entity->RequiresCommitData()) { - entities_needing_data.push_back(entity->client_tag()); + entities_needing_data.push_back(entity->storage_key()); } - metadata_changes->UpdateMetadata(entity->client_tag(), entity->metadata()); + metadata_changes->UpdateMetadata(entity->storage_key(), entity->metadata()); } if (!entities_needing_data.empty()) { @@ -592,10 +595,10 @@ for (const UpdateResponseData& update : updates) { ProcessorEntityTracker* entity = CreateEntity(update.entity.value()); - const std::string& tag = entity->client_tag(); + const std::string& storage_key = entity->storage_key(); entity->RecordAcceptedUpdate(update); - metadata_changes->UpdateMetadata(tag, entity->metadata()); - data_map[tag] = update.entity; + metadata_changes->UpdateMetadata(storage_key, entity->metadata()); + data_map[storage_key] = update.entity; } // Let the service handle associating and merging the data. @@ -642,8 +645,8 @@ void SharedModelTypeProcessor::ConsumeDataBatch( std::unique_ptr<DataBatch> data_batch) { while (data_batch->HasNext()) { - TagAndData data = data_batch->Next(); - ProcessorEntityTracker* entity = GetEntityForTag(data.first); + KeyAndData data = data_batch->Next(); + ProcessorEntityTracker* entity = GetEntityForStorageKey(data.first); // If the entity wasn't deleted or updated with new commit. if (entity != nullptr && entity->RequiresCommitData()) { entity->CacheCommitData(data.second.get()); @@ -655,9 +658,21 @@ return syncer::syncable::GenerateSyncableHash(type_, tag); } -ProcessorEntityTracker* SharedModelTypeProcessor::GetEntityForTag( - const std::string& tag) { - return GetEntityForTagHash(GetHashForTag(tag)); +std::string SharedModelTypeProcessor::GetClientTagHash( + const std::string& storage_key, + const EntityData& data) { + auto iter = storage_key_to_tag_hash_.find(storage_key); + return iter == storage_key_to_tag_hash_.end() + ? GetHashForTag(service_->GetClientTag(data)) + : iter->second; +} + +ProcessorEntityTracker* SharedModelTypeProcessor::GetEntityForStorageKey( + const std::string& storage_key) { + auto iter = storage_key_to_tag_hash_.find(storage_key); + return iter == storage_key_to_tag_hash_.end() + ? nullptr + : GetEntityForTagHash(iter->second); } ProcessorEntityTracker* SharedModelTypeProcessor::GetEntityForTagHash( @@ -667,24 +682,25 @@ } ProcessorEntityTracker* SharedModelTypeProcessor::CreateEntity( - const std::string& tag, + const std::string& storage_key, const EntityData& data) { DCHECK(entities_.find(data.client_tag_hash) == entities_.end()); + DCHECK(storage_key_to_tag_hash_.find(storage_key) == + storage_key_to_tag_hash_.end()); std::unique_ptr<ProcessorEntityTracker> entity = - ProcessorEntityTracker::CreateNew(tag, data.client_tag_hash, data.id, - data.creation_time); + ProcessorEntityTracker::CreateNew(storage_key, data.client_tag_hash, + data.id, data.creation_time); ProcessorEntityTracker* entity_ptr = entity.get(); entities_[data.client_tag_hash] = std::move(entity); + storage_key_to_tag_hash_[storage_key] = data.client_tag_hash; return entity_ptr; } ProcessorEntityTracker* SharedModelTypeProcessor::CreateEntity( const EntityData& data) { - // Let the service define |client_tag| based on the entity data. - const std::string tag = service_->GetClientTag(data); - // This constraint may be relaxed in the future. - DCHECK_EQ(data.client_tag_hash, GetHashForTag(tag)); - return CreateEntity(tag, data); + // Verify the tag hash matches, may be relaxed in the future. + DCHECK_EQ(data.client_tag_hash, GetHashForTag(service_->GetClientTag(data))); + return CreateEntity(service_->GetStorageKey(data), data); } } // namespace syncer_v2
diff --git a/components/sync/core/shared_model_type_processor.h b/components/sync/core/shared_model_type_processor.h index e037ddc..18bc2e0 100644 --- a/components/sync/core/shared_model_type_processor.h +++ b/components/sync/core/shared_model_type_processor.h
@@ -19,7 +19,6 @@ #include "components/sync/api/model_type_service.h" #include "components/sync/api/sync_error.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/core/data_type_error_handler.h" #include "components/sync/core/model_type_processor.h" #include "components/sync/core/non_blocking_sync_common.h" @@ -33,9 +32,9 @@ // A sync component embedded on the synced type's thread that helps to handle // communication between sync and model type threads. -class SYNC_EXPORT SharedModelTypeProcessor : public ModelTypeProcessor, - public ModelTypeChangeProcessor, - base::NonThreadSafe { +class SharedModelTypeProcessor : public ModelTypeProcessor, + public ModelTypeChangeProcessor, + base::NonThreadSafe { public: SharedModelTypeProcessor(syncer::ModelType type, ModelTypeService* service); ~SharedModelTypeProcessor() override; @@ -53,10 +52,10 @@ bool IsConnected() const; // ModelTypeChangeProcessor implementation. - void Put(const std::string& client_tag, + void Put(const std::string& storage_key, std::unique_ptr<EntityData> entity_data, MetadataChangeList* metadata_change_list) override; - void Delete(const std::string& client_tag, + void Delete(const std::string& storage_key, MetadataChangeList* metadata_change_list) override; void OnMetadataLoaded(syncer::SyncError error, std::unique_ptr<MetadataBatch> batch) override; @@ -121,15 +120,23 @@ // Computes the client tag hash for the given client |tag|. std::string GetHashForTag(const std::string& tag); - // Gets the entity for the given tag, or null if there isn't one. - ProcessorEntityTracker* GetEntityForTag(const std::string& tag); + // Looks up the client tag hash for the given |storage_key|, and regenerates + // with |data| if the lookup finds nothing. Does not update the storage key to + // client tag hash mapping. + std::string GetClientTagHash(const std::string& storage_key, + const EntityData& data); + + // Gets the entity for the given storage key, or null if there isn't one. + ProcessorEntityTracker* GetEntityForStorageKey( + const std::string& storage_key); // Gets the entity for the given tag hash, or null if there isn't one. ProcessorEntityTracker* GetEntityForTagHash(const std::string& tag_hash); - // Create an entity in the entity map for |tag| and return a pointer to it. - // Requires that no entity for |tag| already exists in the map. - ProcessorEntityTracker* CreateEntity(const std::string& tag, + // Create an entity in the entity map for |storage_key| and return a pointer + // to it. + // Requires that no entity for |storage_key| already exists in the map. + ProcessorEntityTracker* CreateEntity(const std::string& storage_key, const EntityData& data); // Version of the above that generates a tag for |data|. @@ -158,9 +165,17 @@ // useful in tests. std::unique_ptr<CommitQueue> worker_; - // The set of sync entities known to this object. + // A map of client tag hash to sync entities known to this processor. This + // should contain entries and metadata for most everything, although the + // entities may not always contain model type data/specifics. EntityMap entities_; + // The service wants to communicate entirly via storage keys that is free to + // define and can understand more easily. All of the sync machinery wants to + // use client tag hash. This mapping allows us to convert from storage key to + // client tag hash. The other direction can use |entities_|. + std::map<std::string, std::string> storage_key_to_tag_hash_; + // ModelTypeService linked to this processor. // The service owns this processor instance so the pointer should never // become invalid.
diff --git a/components/sync/core/shared_model_type_processor_unittest.cc b/components/sync/core/shared_model_type_processor_unittest.cc index 669abf27..86051ce 100644 --- a/components/sync/core/shared_model_type_processor_unittest.cc +++ b/components/sync/core/shared_model_type_processor_unittest.cc
@@ -8,6 +8,7 @@ #include <stdint.h> #include <map> +#include <utility> #include <vector> #include "base/bind.h" @@ -30,35 +31,55 @@ #include "components/sync/test/engine/mock_model_type_worker.h" #include "testing/gtest/include/gtest/gtest.h" +using sync_pb::EntitySpecifics; +using sync_pb::EntityMetadata; +using sync_pb::DataTypeState; + namespace syncer_v2 { namespace { -const std::string kTag1 = "tag1"; -const std::string kTag2 = "tag2"; -const std::string kTag3 = "tag3"; -const std::string kValue1 = "value1"; -const std::string kValue2 = "value2"; -const std::string kValue3 = "value3"; - -std::string GenerateTagHash(const std::string& tag) { - return syncer::syncable::GenerateSyncableHash(syncer::PREFERENCES, tag); +std::string ClientTagFromKey(const std::string& key) { + return "ClientTag_" + key; } -sync_pb::EntitySpecifics GenerateSpecifics(const std::string& tag, - const std::string& value) { - sync_pb::EntitySpecifics specifics; - specifics.mutable_preference()->set_name(tag); +std::string TagHashFromKey(const std::string& key) { + return syncer::syncable::GenerateSyncableHash(syncer::PREFERENCES, + ClientTagFromKey(key)); +} + +const char kKey1[] = "key1"; +const char kKey2[] = "key2"; +const char kKey3[] = "key3"; +const char kKey4[] = "key4"; +const char kKey5[] = "key5"; +const char kValue1[] = "value1"; +const char kValue2[] = "value2"; +const char kValue3[] = "value3"; +const std::string kHash1(TagHashFromKey(kKey1)); +const std::string kHash2(TagHashFromKey(kKey2)); +const std::string kHash3(TagHashFromKey(kKey3)); +const std::string kHash4(TagHashFromKey(kKey4)); +const std::string kHash5(TagHashFromKey(kKey5)); + +// Typically used for verification after a delete. The specifics given to the +// worker/processor will not have been initialized and thus empty. +const EntitySpecifics kEmptySpecifics; + +EntitySpecifics GenerateSpecifics(const std::string& name, + const std::string& value) { + EntitySpecifics specifics; + specifics.mutable_preference()->set_name(name); specifics.mutable_preference()->set_value(value); return specifics; } -std::unique_ptr<EntityData> GenerateEntityData(const std::string& tag, +std::unique_ptr<EntityData> GenerateEntityData(const std::string& key, const std::string& value) { std::unique_ptr<EntityData> entity_data = base::WrapUnique(new EntityData()); - entity_data->client_tag_hash = GenerateTagHash(tag); - entity_data->specifics = GenerateSpecifics(tag, value); - entity_data->non_unique_name = tag; + entity_data->client_tag_hash = TagHashFromKey(key); + entity_data->specifics = GenerateSpecifics(key, value); + entity_data->non_unique_name = key; return entity_data; } @@ -86,49 +107,48 @@ // committed, etc. Having a separate class helps keep the main one cleaner. class SimpleStore { public: - void PutData(const std::string& tag, const EntityData& data) { + void PutData(const std::string& key, const EntityData& data) { data_change_count_++; - data_store_[tag] = CopyEntityData(data); + data_store_[key] = CopyEntityData(data); } - void PutMetadata(const std::string& tag, - const sync_pb::EntityMetadata& metadata) { + void PutMetadata(const std::string& key, const EntityMetadata& metadata) { metadata_change_count_++; - metadata_store_[tag] = metadata; + metadata_store_[key] = metadata; } - void RemoveData(const std::string& tag) { + void RemoveData(const std::string& key) { data_change_count_++; - data_store_.erase(tag); + data_store_.erase(key); } - void RemoveMetadata(const std::string& tag) { + void RemoveMetadata(const std::string& key) { metadata_change_count_++; - metadata_store_.erase(tag); + metadata_store_.erase(key); } - bool HasData(const std::string& tag) const { - return data_store_.find(tag) != data_store_.end(); + bool HasData(const std::string& key) const { + return data_store_.find(key) != data_store_.end(); } - bool HasMetadata(const std::string& tag) const { - return metadata_store_.find(tag) != metadata_store_.end(); + bool HasMetadata(const std::string& key) const { + return metadata_store_.find(key) != metadata_store_.end(); } const std::map<std::string, std::unique_ptr<EntityData>>& GetAllData() const { return data_store_; } - const EntityData& GetData(const std::string& tag) const { - return *data_store_.find(tag)->second; + const EntityData& GetData(const std::string& key) const { + return *data_store_.find(key)->second; } - const std::string& GetValue(const std::string& tag) const { - return GetData(tag).specifics.preference().value(); + const std::string& GetValue(const std::string& key) const { + return GetData(key).specifics.preference().value(); } - const sync_pb::EntityMetadata& GetMetadata(const std::string& tag) const { - return metadata_store_.find(tag)->second; + const EntityMetadata& GetMetadata(const std::string& key) const { + return metadata_store_.find(key)->second; } size_t DataCount() const { return data_store_.size(); } @@ -137,11 +157,9 @@ size_t DataChangeCount() const { return data_change_count_; } size_t MetadataChangeCount() const { return metadata_change_count_; } - const sync_pb::DataTypeState& data_type_state() const { - return data_type_state_; - } + const DataTypeState& data_type_state() const { return data_type_state_; } - void set_data_type_state(const sync_pb::DataTypeState& data_type_state) { + void set_data_type_state(const DataTypeState& data_type_state) { data_type_state_ = data_type_state; } @@ -166,8 +184,8 @@ size_t data_change_count_ = 0; size_t metadata_change_count_ = 0; std::map<std::string, std::unique_ptr<EntityData>> data_store_; - std::map<std::string, sync_pb::EntityMetadata> metadata_store_; - sync_pb::DataTypeState data_type_state_; + std::map<std::string, EntityMetadata> metadata_store_; + DataTypeState data_type_state_; }; } // namespace @@ -198,7 +216,7 @@ void InitializeToMetadataLoaded() { CreateChangeProcessor(); - sync_pb::DataTypeState data_type_state(db_.data_type_state()); + DataTypeState data_type_state(db_.data_type_state()); data_type_state.set_initial_sync_done(true); db_.set_data_type_state(data_type_state); OnMetadataLoaded(); @@ -237,36 +255,41 @@ } // Local data modification. Emulates signals from the model thread. - void WriteItem(const std::string& tag, const std::string& value) { - WriteItem(tag, GenerateEntityData(tag, value)); + EntitySpecifics WriteItem(const std::string& key, const std::string& value) { + std::unique_ptr<EntityData> entity_data = GenerateEntityData(key, value); + EntitySpecifics specifics_copy = entity_data->specifics; + WriteItem(key, std::move(entity_data)); + return specifics_copy; } // Overloaded form to allow passing of custom entity data. - void WriteItem(const std::string& tag, + void WriteItem(const std::string& key, std::unique_ptr<EntityData> entity_data) { - db_.PutData(tag, *entity_data); + db_.PutData(key, *entity_data); if (type_processor()) { std::unique_ptr<MetadataChangeList> change_list( new SimpleMetadataChangeList()); - type_processor()->Put(tag, std::move(entity_data), change_list.get()); + type_processor()->Put(key, std::move(entity_data), change_list.get()); ApplyMetadataChangeList(std::move(change_list)); } } - // Writes data for |tag| and simulates a commit response for it. - void WriteItemAndAck(const std::string& tag, const std::string& value) { - WriteItem(tag, value); - worker()->ExpectPendingCommits({tag}); + // Writes data for |key| and simulates a commit response for it. + EntitySpecifics WriteItemAndAck(const std::string& key, + const std::string& value) { + EntitySpecifics specifics = WriteItem(key, value); + worker()->ExpectPendingCommits({TagHashFromKey(key)}); worker()->AckOnePendingCommit(); EXPECT_EQ(0U, worker()->GetNumPendingCommits()); + return specifics; } - void DeleteItem(const std::string& tag) { - db_.RemoveData(tag); + void DeleteItem(const std::string& key) { + db_.RemoveData(key); if (type_processor()) { std::unique_ptr<MetadataChangeList> change_list( new SimpleMetadataChangeList()); - type_processor()->Delete(tag, change_list.get()); + type_processor()->Delete(key, change_list.get()); ApplyMetadataChangeList(std::move(change_list)); } } @@ -279,25 +302,27 @@ } // Wipes existing DB and simulates a pending update of a server-known item. - void ResetStateWriteItem(const std::string& tag, const std::string& value) { + EntitySpecifics ResetStateWriteItem(const std::string& name, + const std::string& value) { ResetState(); InitializeToReadyState(); EXPECT_EQ(0U, ProcessorEntityCount()); - WriteItemAndAck(tag, "acked-value"); - WriteItem(tag, value); + WriteItemAndAck(name, "acked-value"); + EntitySpecifics specifics = WriteItem(name, value); EXPECT_EQ(1U, ProcessorEntityCount()); clear_change_processor(); worker_ = nullptr; + return specifics; } // Wipes existing DB and simulates a pending deletion of a server-known item. - void ResetStateDeleteItem(const std::string& tag, const std::string& value) { + void ResetStateDeleteItem(const std::string& name, const std::string& value) { ResetState(); InitializeToReadyState(); EXPECT_EQ(0U, ProcessorEntityCount()); - WriteItemAndAck(tag, value); + WriteItemAndAck(name, value); EXPECT_EQ(1U, ProcessorEntityCount()); - DeleteItem(tag); + DeleteItem(name); EXPECT_EQ(1U, ProcessorEntityCount()); clear_change_processor(); worker_ = nullptr; @@ -305,7 +330,7 @@ // Simulates an initial GetUpdates response from the worker with |updates|. void OnInitialSyncDone(UpdateResponseDataList updates) { - sync_pb::DataTypeState data_type_state(db_.data_type_state()); + DataTypeState data_type_state(db_.data_type_state()); data_type_state.set_initial_sync_done(true); type_processor()->OnUpdateReceived(data_type_state, updates); } @@ -314,10 +339,10 @@ void OnInitialSyncDone() { OnInitialSyncDone(UpdateResponseDataList()); } // Overloaded form that constructs an update for a single entity. - void OnInitialSyncDone(const std::string& tag, const std::string& value) { + void OnInitialSyncDone(const std::string& key, const std::string& value) { UpdateResponseDataList updates; UpdateResponseData update; - update.entity = GenerateEntityData(tag, value)->PassToPtr(); + update.entity = GenerateEntityData(key, value)->PassToPtr(); updates.push_back(update); OnInitialSyncDone(updates); } @@ -387,7 +412,10 @@ // FakeModelTypeService overrides. std::string GetClientTag(const EntityData& entity_data) override { - // The tag is the preference name - see GenerateSpecifics. + return ClientTagFromKey(entity_data.specifics.preference().name()); + } + + std::string GetStorageKey(const EntityData& entity_data) override { return entity_data.specifics.preference().name(); } @@ -430,16 +458,16 @@ for (const EntityChange& change : entity_changes) { switch (change.type()) { case EntityChange::ACTION_ADD: - EXPECT_FALSE(db_.HasData(change.client_tag())); - db_.PutData(change.client_tag(), change.data()); + EXPECT_FALSE(db_.HasData(change.storage_key())); + db_.PutData(change.storage_key(), change.data()); break; case EntityChange::ACTION_UPDATE: - EXPECT_TRUE(db_.HasData(change.client_tag())); - db_.PutData(change.client_tag(), change.data()); + EXPECT_TRUE(db_.HasData(change.storage_key())); + db_.PutData(change.storage_key(), change.data()); break; case EntityChange::ACTION_DELETE: - EXPECT_TRUE(db_.HasData(change.client_tag())); - db_.RemoveData(change.client_tag()); + EXPECT_TRUE(db_.HasData(change.storage_key())); + db_.RemoveData(change.storage_key()); break; } } @@ -473,22 +501,22 @@ db_.set_data_type_state(state_change.state); break; case SimpleMetadataChangeList::CLEAR: - db_.set_data_type_state(sync_pb::DataTypeState()); + db_.set_data_type_state(DataTypeState()); break; } } } - void GetData(ClientTagList tags, DataCallback callback) override { + void GetData(StorageKeyList keys, DataCallback callback) override { if (service_error_.IsSet()) { data_callback_ = base::Bind(callback, service_error_, nullptr); service_error_ = syncer::SyncError(); return; } std::unique_ptr<DataBatchImpl> batch(new DataBatchImpl()); - for (const std::string& tag : tags) { - DCHECK(db_.HasData(tag)) << "No data for " << tag; - batch->Put(tag, CopyEntityData(db_.GetData(tag))); + for (const std::string& key : keys) { + DCHECK(db_.HasData(key)) << "No data for " << key; + batch->Put(key, CopyEntityData(db_.GetData(key))); } data_callback_ = base::Bind(callback, syncer::SyncError(), base::Passed(&batch)); @@ -533,7 +561,7 @@ OnSyncStarting(); // Local write before initial sync. - WriteItem(kTag1, kValue1); + WriteItem(kKey1, kValue1); // Has data, but no metadata, entity in the processor, or commit request. EXPECT_EQ(1U, db().DataCount()); @@ -542,16 +570,16 @@ EXPECT_EQ(0U, worker()->GetNumPendingCommits()); // Initial sync with one server item. - OnInitialSyncDone(kTag2, kValue2); + OnInitialSyncDone(kKey2, kValue2); // Now have data and metadata for both items, as well as a commit request for // the local item. EXPECT_EQ(2U, db().DataCount()); EXPECT_EQ(2U, db().MetadataCount()); EXPECT_EQ(2U, ProcessorEntityCount()); - EXPECT_EQ(1, db().GetMetadata(kTag1).sequence_number()); - EXPECT_EQ(0, db().GetMetadata(kTag2).sequence_number()); - worker()->ExpectPendingCommits({kTag1}); + EXPECT_EQ(1, db().GetMetadata(kKey1).sequence_number()); + EXPECT_EQ(0, db().GetMetadata(kKey2).sequence_number()); + worker()->ExpectPendingCommits({kHash1}); } // Test that an error during the merge is propagated to the error handler. @@ -582,7 +610,7 @@ CreateSyncError(syncer::SyncError::DATATYPE_ERROR), nullptr); // Test an error loading pending data. - ResetStateWriteItem(kTag1, kValue1); + ResetStateWriteItem(kKey1, kValue1); SetServiceError(syncer::SyncError::DATATYPE_ERROR); InitializeToMetadataLoaded(); OnPendingCommitDataLoaded(); @@ -602,137 +630,137 @@ // This results in 2 + 12 = 14 orderings of the events. TEST_F(SharedModelTypeProcessorTest, LoadPendingCommit) { // Data, connect. - ResetStateWriteItem(kTag1, kValue1); + EntitySpecifics specifics1 = ResetStateWriteItem(kKey1, kValue1); InitializeToMetadataLoaded(); OnPendingCommitDataLoaded(); OnSyncStarting(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, kValue1); + worker()->ExpectNthPendingCommit(0, kHash1, specifics1); // Connect, data. - ResetStateWriteItem(kTag1, kValue1); + EntitySpecifics specifics2 = ResetStateWriteItem(kKey1, kValue1); InitializeToMetadataLoaded(); OnSyncStarting(); EXPECT_EQ(nullptr, worker()); OnPendingCommitDataLoaded(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, kValue1); + worker()->ExpectNthPendingCommit(0, kHash1, specifics2); // Data, connect, put. - ResetStateWriteItem(kTag1, kValue1); + EntitySpecifics specifics3 = ResetStateWriteItem(kKey1, kValue1); InitializeToMetadataLoaded(); OnPendingCommitDataLoaded(); OnSyncStarting(); - WriteItem(kTag1, kValue2); + EntitySpecifics specifics4 = WriteItem(kKey1, kValue2); EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, kValue1); - worker()->ExpectNthPendingCommit(1, kTag1, kValue2); + worker()->ExpectNthPendingCommit(0, kHash1, specifics3); + worker()->ExpectNthPendingCommit(1, kHash1, specifics4); // Data, put, connect. - ResetStateWriteItem(kTag1, kValue1); + ResetStateWriteItem(kKey1, kValue1); InitializeToMetadataLoaded(); OnPendingCommitDataLoaded(); - WriteItem(kTag1, kValue2); + EntitySpecifics specifics5 = WriteItem(kKey1, kValue2); OnSyncStarting(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, kValue2); + worker()->ExpectNthPendingCommit(0, kHash1, specifics5); // Connect, data, put. - ResetStateWriteItem(kTag1, kValue1); + EntitySpecifics specifics6 = ResetStateWriteItem(kKey1, kValue1); InitializeToMetadataLoaded(); OnSyncStarting(); OnPendingCommitDataLoaded(); - WriteItem(kTag1, kValue2); + EntitySpecifics specifics7 = WriteItem(kKey1, kValue2); EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, kValue1); - worker()->ExpectNthPendingCommit(1, kTag1, kValue2); + worker()->ExpectNthPendingCommit(0, kHash1, specifics6); + worker()->ExpectNthPendingCommit(1, kHash1, specifics7); // Connect, put, data. - ResetStateWriteItem(kTag1, kValue1); + ResetStateWriteItem(kKey1, kValue1); InitializeToMetadataLoaded(); OnSyncStarting(); - WriteItem(kTag1, kValue2); + EntitySpecifics specifics8 = WriteItem(kKey1, kValue2); EXPECT_EQ(nullptr, worker()); OnPendingCommitDataLoaded(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, kValue2); + worker()->ExpectNthPendingCommit(0, kHash1, specifics8); // Put, data, connect. - ResetStateWriteItem(kTag1, kValue1); + ResetStateWriteItem(kKey1, kValue1); InitializeToMetadataLoaded(); - WriteItem(kTag1, kValue2); + EntitySpecifics specifics9 = WriteItem(kKey1, kValue2); OnPendingCommitDataLoaded(); OnSyncStarting(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, kValue2); + worker()->ExpectNthPendingCommit(0, kHash1, specifics9); // Put, connect, data. - ResetStateWriteItem(kTag1, kValue1); + ResetStateWriteItem(kKey1, kValue1); InitializeToMetadataLoaded(); - WriteItem(kTag1, kValue2); + EntitySpecifics specifics10 = WriteItem(kKey1, kValue2); OnSyncStarting(); EXPECT_EQ(nullptr, worker()); OnPendingCommitDataLoaded(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, kValue2); + worker()->ExpectNthPendingCommit(0, kHash1, specifics10); // Data, connect, delete. - ResetStateWriteItem(kTag1, kValue1); + EntitySpecifics specifics11 = ResetStateWriteItem(kKey1, kValue1); InitializeToMetadataLoaded(); OnPendingCommitDataLoaded(); OnSyncStarting(); - DeleteItem(kTag1); + DeleteItem(kKey1); EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, kValue1); - worker()->ExpectNthPendingCommit(1, kTag1, ""); + worker()->ExpectNthPendingCommit(0, kHash1, specifics11); + worker()->ExpectNthPendingCommit(1, kHash1, kEmptySpecifics); // Data, delete, connect. - ResetStateWriteItem(kTag1, kValue1); + ResetStateWriteItem(kKey1, kValue1); InitializeToMetadataLoaded(); OnPendingCommitDataLoaded(); - DeleteItem(kTag1); + DeleteItem(kKey1); OnSyncStarting(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, ""); + worker()->ExpectNthPendingCommit(0, kHash1, kEmptySpecifics); // Connect, data, delete. - ResetStateWriteItem(kTag1, kValue1); + EntitySpecifics specifics12 = ResetStateWriteItem(kKey1, kValue1); InitializeToMetadataLoaded(); OnSyncStarting(); OnPendingCommitDataLoaded(); - DeleteItem(kTag1); + DeleteItem(kKey1); EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, kValue1); - worker()->ExpectNthPendingCommit(1, kTag1, ""); + worker()->ExpectNthPendingCommit(0, kHash1, specifics12); + worker()->ExpectNthPendingCommit(1, kHash1, kEmptySpecifics); // Connect, delete, data. - ResetStateWriteItem(kTag1, kValue1); + ResetStateWriteItem(kKey1, kValue1); InitializeToMetadataLoaded(); OnSyncStarting(); - DeleteItem(kTag1); + DeleteItem(kKey1); EXPECT_EQ(nullptr, worker()); OnPendingCommitDataLoaded(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, ""); + worker()->ExpectNthPendingCommit(0, kHash1, kEmptySpecifics); // Delete, data, connect. - ResetStateWriteItem(kTag1, kValue1); + ResetStateWriteItem(kKey1, kValue1); InitializeToMetadataLoaded(); - DeleteItem(kTag1); + DeleteItem(kKey1); OnPendingCommitDataLoaded(); OnSyncStarting(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, ""); + worker()->ExpectNthPendingCommit(0, kHash1, kEmptySpecifics); // Delete, connect, data. - ResetStateWriteItem(kTag1, kValue1); + ResetStateWriteItem(kKey1, kValue1); InitializeToMetadataLoaded(); - DeleteItem(kTag1); + DeleteItem(kKey1); OnSyncStarting(); EXPECT_EQ(nullptr, worker()); OnPendingCommitDataLoaded(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, ""); + worker()->ExpectNthPendingCommit(0, kHash1, kEmptySpecifics); } // This test covers race conditions during loading a pending delete. All cases @@ -747,53 +775,53 @@ // This results in 1 + 4 = 5 orderings of the events. TEST_F(SharedModelTypeProcessorTest, LoadPendingDelete) { // Connect. - ResetStateDeleteItem(kTag1, kValue1); + ResetStateDeleteItem(kKey1, kValue1); InitializeToMetadataLoaded(); OnSyncStarting(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, ""); + worker()->ExpectNthPendingCommit(0, kHash1, kEmptySpecifics); // Connect, put. - ResetStateDeleteItem(kTag1, kValue1); + ResetStateDeleteItem(kKey1, kValue1); InitializeToMetadataLoaded(); OnSyncStarting(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - WriteItem(kTag1, kValue2); + EntitySpecifics specifics1 = WriteItem(kKey1, kValue2); EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, ""); - worker()->ExpectNthPendingCommit(1, kTag1, kValue2); + worker()->ExpectNthPendingCommit(0, kHash1, kEmptySpecifics); + worker()->ExpectNthPendingCommit(1, kHash1, specifics1); // Put, connect. - ResetStateDeleteItem(kTag1, kValue1); + ResetStateDeleteItem(kKey1, kValue1); InitializeToMetadataLoaded(); - WriteItem(kTag1, kValue2); + EntitySpecifics specifics2 = WriteItem(kKey1, kValue2); OnSyncStarting(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, kValue2); + worker()->ExpectNthPendingCommit(0, kHash1, specifics2); // Connect, delete. - ResetStateDeleteItem(kTag1, kValue1); + ResetStateDeleteItem(kKey1, kValue1); InitializeToMetadataLoaded(); OnSyncStarting(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - DeleteItem(kTag1); + DeleteItem(kKey1); EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, ""); - worker()->ExpectNthPendingCommit(1, kTag1, ""); + worker()->ExpectNthPendingCommit(0, kHash1, kEmptySpecifics); + worker()->ExpectNthPendingCommit(1, kHash1, kEmptySpecifics); // Delete, connect. - ResetStateDeleteItem(kTag1, kValue1); + ResetStateDeleteItem(kKey1, kValue1); InitializeToMetadataLoaded(); - DeleteItem(kTag1); + DeleteItem(kKey1); OnSyncStarting(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, ""); + worker()->ExpectNthPendingCommit(0, kHash1, kEmptySpecifics); } // Test that loading a committed item does not queue another commit. TEST_F(SharedModelTypeProcessorTest, LoadCommited) { InitializeToReadyState(); - WriteItemAndAck(kTag1, kValue1); + WriteItemAndAck(kKey1, kValue1); clear_change_processor(); // Test that a new processor loads the metadata without committing. @@ -808,25 +836,25 @@ InitializeToReadyState(); EXPECT_EQ(0U, worker()->GetNumPendingCommits()); - WriteItem(kTag1, kValue1); + WriteItem(kKey1, kValue1); // Verify the commit request this operation has triggered. - worker()->ExpectPendingCommits({kTag1}); + worker()->ExpectPendingCommits({kHash1}); const CommitRequestData& tag1_request_data = - worker()->GetLatestPendingCommitForTag(kTag1); + worker()->GetLatestPendingCommitForHash(kHash1); const EntityData& tag1_data = tag1_request_data.entity.value(); EXPECT_EQ(kUncommittedVersion, tag1_request_data.base_version); EXPECT_TRUE(tag1_data.id.empty()); EXPECT_FALSE(tag1_data.creation_time.is_null()); EXPECT_FALSE(tag1_data.modification_time.is_null()); - EXPECT_EQ(kTag1, tag1_data.non_unique_name); + EXPECT_EQ(kKey1, tag1_data.non_unique_name); EXPECT_FALSE(tag1_data.is_deleted()); - EXPECT_EQ(kTag1, tag1_data.specifics.preference().name()); + EXPECT_EQ(kKey1, tag1_data.specifics.preference().name()); EXPECT_EQ(kValue1, tag1_data.specifics.preference().value()); EXPECT_EQ(1U, db().MetadataCount()); - const sync_pb::EntityMetadata metadata = db().GetMetadata(kTag1); + const EntityMetadata metadata = db().GetMetadata(kKey1); EXPECT_TRUE(metadata.has_client_tag_hash()); EXPECT_FALSE(metadata.has_server_id()); EXPECT_FALSE(metadata.is_deleted()); @@ -839,7 +867,7 @@ worker()->AckOnePendingCommit(); EXPECT_EQ(1U, db().MetadataCount()); - const sync_pb::EntityMetadata acked_metadata = db().GetMetadata(kTag1); + const EntityMetadata acked_metadata = db().GetMetadata(kKey1); EXPECT_TRUE(acked_metadata.has_server_id()); EXPECT_EQ(1, acked_metadata.sequence_number()); EXPECT_EQ(1, acked_metadata.acked_sequence_number()); @@ -850,7 +878,7 @@ // propagated to the error handler. TEST_F(SharedModelTypeProcessorTest, ErrorApplyingAck) { InitializeToReadyState(); - WriteItem(kTag1, kValue1); + WriteItem(kKey1, kValue1); SetServiceError(syncer::SyncError::DATATYPE_ERROR); error_handler()->ExpectError(syncer::SyncError::DATATYPE_ERROR); worker()->AckOnePendingCommit(); @@ -861,52 +889,51 @@ TEST_F(SharedModelTypeProcessorTest, LocalUpdateItemWithOverrides) { const std::string kId1 = "cid1"; const std::string kId2 = "cid2"; - const std::string kName1 = "name1"; - const std::string kName2 = "name2"; - const std::string kTag3Hash = GenerateTagHash(kTag3); InitializeToReadyState(); EXPECT_EQ(0U, worker()->GetNumPendingCommits()); std::unique_ptr<EntityData> entity_data = base::WrapUnique(new EntityData()); - entity_data->specifics.mutable_preference()->set_name(kName1); + entity_data->specifics.mutable_preference()->set_name(kKey1); entity_data->specifics.mutable_preference()->set_value(kValue1); - entity_data->non_unique_name = kName1; - entity_data->client_tag_hash = kTag3Hash; + entity_data->non_unique_name = kKey1; + entity_data->client_tag_hash = kHash3; entity_data->id = kId1; - WriteItem(kTag1, std::move(entity_data)); + WriteItem(kKey1, std::move(entity_data)); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - ASSERT_FALSE(worker()->HasPendingCommitForTag(kTag3)); - ASSERT_TRUE(worker()->HasPendingCommitForTag(kTag1)); + ASSERT_FALSE(worker()->HasPendingCommitForHash(kHash3)); + ASSERT_TRUE(worker()->HasPendingCommitForHash(kHash1)); EXPECT_EQ(1U, db().MetadataCount()); const EntityData& out_entity1 = - worker()->GetLatestPendingCommitForTag(kTag1).entity.value(); - const sync_pb::EntityMetadata metadata_v1 = db().GetMetadata(kTag1); + worker()->GetLatestPendingCommitForHash(kHash1).entity.value(); + const EntityMetadata metadata_v1 = db().GetMetadata(kKey1); EXPECT_EQ(kId1, out_entity1.id); - EXPECT_NE(kTag3Hash, out_entity1.client_tag_hash); + EXPECT_NE(kHash3, out_entity1.client_tag_hash); EXPECT_EQ(kValue1, out_entity1.specifics.preference().value()); EXPECT_EQ(kId1, metadata_v1.server_id()); EXPECT_EQ(metadata_v1.client_tag_hash(), out_entity1.client_tag_hash); entity_data.reset(new EntityData()); - entity_data->specifics.mutable_preference()->set_name(kName2); + // This is a sketchy move here, changing the name will change the generated + // storage key and client tag values. + entity_data->specifics.mutable_preference()->set_name(kKey2); entity_data->specifics.mutable_preference()->set_value(kValue2); - entity_data->non_unique_name = kName2; - entity_data->client_tag_hash = kTag3Hash; + entity_data->non_unique_name = kKey2; + entity_data->client_tag_hash = kHash3; // Make sure ID isn't overwritten either. entity_data->id = kId2; - WriteItem(kTag1, std::move(entity_data)); + WriteItem(kKey1, std::move(entity_data)); EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - ASSERT_FALSE(worker()->HasPendingCommitForTag(kTag3)); - ASSERT_TRUE(worker()->HasPendingCommitForTag(kTag1)); + ASSERT_FALSE(worker()->HasPendingCommitForHash(kHash3)); + ASSERT_TRUE(worker()->HasPendingCommitForHash(kHash1)); EXPECT_EQ(1U, db().MetadataCount()); const EntityData& out_entity2 = - worker()->GetLatestPendingCommitForTag(kTag1).entity.value(); - const sync_pb::EntityMetadata metadata_v2 = db().GetMetadata(kTag1); + worker()->GetLatestPendingCommitForHash(kHash1).entity.value(); + const EntityMetadata metadata_v2 = db().GetMetadata(kKey1); EXPECT_EQ(kValue2, out_entity2.specifics.preference().value()); // Should still see old cid1 value, override is not respected on update. @@ -923,23 +950,23 @@ TEST_F(SharedModelTypeProcessorTest, LocalUpdateItem) { InitializeToReadyState(); - WriteItem(kTag1, kValue1); + WriteItem(kKey1, kValue1); EXPECT_EQ(1U, db().MetadataCount()); - worker()->ExpectPendingCommits({kTag1}); + worker()->ExpectPendingCommits({kHash1}); const CommitRequestData& request_data_v1 = - worker()->GetLatestPendingCommitForTag(kTag1); + worker()->GetLatestPendingCommitForHash(kHash1); const EntityData& data_v1 = request_data_v1.entity.value(); - const sync_pb::EntityMetadata metadata_v1 = db().GetMetadata(kTag1); + const EntityMetadata metadata_v1 = db().GetMetadata(kKey1); - WriteItem(kTag1, kValue2); + WriteItem(kKey1, kValue2); EXPECT_EQ(1U, db().MetadataCount()); - worker()->ExpectPendingCommits({kTag1, kTag1}); + worker()->ExpectPendingCommits({kHash1, kHash1}); const CommitRequestData& request_data_v2 = - worker()->GetLatestPendingCommitForTag(kTag1); + worker()->GetLatestPendingCommitForHash(kHash1); const EntityData& data_v2 = request_data_v2.entity.value(); - const sync_pb::EntityMetadata metadata_v2 = db().GetMetadata(kTag1); + const EntityMetadata metadata_v2 = db().GetMetadata(kKey1); // Test some of the relations between old and new commit requests. EXPECT_GT(request_data_v2.sequence_number, request_data_v1.sequence_number); @@ -950,9 +977,9 @@ EXPECT_TRUE(data_v2.id.empty()); EXPECT_FALSE(data_v2.creation_time.is_null()); EXPECT_FALSE(data_v2.modification_time.is_null()); - EXPECT_EQ(kTag1, data_v2.non_unique_name); + EXPECT_EQ(kKey1, data_v2.non_unique_name); EXPECT_FALSE(data_v2.is_deleted()); - EXPECT_EQ(kTag1, data_v2.specifics.preference().name()); + EXPECT_EQ(kKey1, data_v2.specifics.preference().name()); EXPECT_EQ(kValue2, data_v2.specifics.preference().value()); EXPECT_FALSE(metadata_v1.has_server_id()); @@ -975,33 +1002,33 @@ // commit request. TEST_F(SharedModelTypeProcessorTest, LocalUpdateItemRedundant) { InitializeToReadyState(); - WriteItem(kTag1, kValue1); + WriteItem(kKey1, kValue1); EXPECT_EQ(1U, db().MetadataCount()); - worker()->ExpectPendingCommits({kTag1}); + worker()->ExpectPendingCommits({kHash1}); - WriteItem(kTag1, kValue1); - worker()->ExpectPendingCommits({kTag1}); + WriteItem(kKey1, kValue1); + worker()->ExpectPendingCommits({kHash1}); } // Thoroughly tests the data generated by a server item creation. TEST_F(SharedModelTypeProcessorTest, ServerCreateItem) { InitializeToReadyState(); - worker()->UpdateFromServer(kTag1, kValue1); + worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue1)); EXPECT_EQ(1U, db().DataCount()); EXPECT_EQ(1U, db().MetadataCount()); EXPECT_EQ(1U, ProcessorEntityCount()); EXPECT_EQ(0U, worker()->GetNumPendingCommits()); - const EntityData& data = db().GetData(kTag1); + const EntityData& data = db().GetData(kKey1); EXPECT_FALSE(data.id.empty()); - EXPECT_EQ(kTag1, data.specifics.preference().name()); + EXPECT_EQ(kKey1, data.specifics.preference().name()); EXPECT_EQ(kValue1, data.specifics.preference().value()); EXPECT_FALSE(data.creation_time.is_null()); EXPECT_FALSE(data.modification_time.is_null()); - EXPECT_EQ(kTag1, data.non_unique_name); + EXPECT_EQ(kKey1, data.non_unique_name); EXPECT_FALSE(data.is_deleted()); - const sync_pb::EntityMetadata metadata = db().GetMetadata(kTag1); + const EntityMetadata metadata = db().GetMetadata(kKey1); EXPECT_TRUE(metadata.has_client_tag_hash()); EXPECT_TRUE(metadata.has_server_id()); EXPECT_FALSE(metadata.is_deleted()); @@ -1019,7 +1046,7 @@ InitializeToReadyState(); SetServiceError(syncer::SyncError::DATATYPE_ERROR); error_handler()->ExpectError(syncer::SyncError::DATATYPE_ERROR); - worker()->UpdateFromServer(kTag1, kValue1); + worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue1)); } // Thoroughly tests the data generated by a server item creation. @@ -1027,17 +1054,18 @@ InitializeToReadyState(); // Local add writes data and metadata; ack writes metadata again. - WriteItemAndAck(kTag1, kValue1); + WriteItemAndAck(kKey1, kValue1); EXPECT_EQ(1U, db().DataChangeCount()); EXPECT_EQ(2U, db().MetadataChangeCount()); // Redundant update from server doesn't write data but updates metadata. - worker()->UpdateFromServer(kTag1, kValue1); + worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue1)); EXPECT_EQ(1U, db().DataChangeCount()); EXPECT_EQ(3U, db().MetadataChangeCount()); // A reflection (update already received) is ignored completely. - worker()->UpdateFromServer(kTag1, kValue1, 0 /* version_offset */); + worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue1), + 0 /* version_offset */); EXPECT_EQ(1U, db().DataChangeCount()); EXPECT_EQ(3U, db().MetadataChangeCount()); } @@ -1045,23 +1073,23 @@ // Tests locally deleting an acknowledged item. TEST_F(SharedModelTypeProcessorTest, LocalDeleteItem) { InitializeToReadyState(); - WriteItemAndAck(kTag1, kValue1); + WriteItemAndAck(kKey1, kValue1); EXPECT_EQ(0U, worker()->GetNumPendingCommits()); - const sync_pb::EntityMetadata metadata_v1 = db().GetMetadata(kTag1); + const EntityMetadata metadata_v1 = db().GetMetadata(kKey1); EXPECT_FALSE(metadata_v1.is_deleted()); EXPECT_EQ(1, metadata_v1.sequence_number()); EXPECT_EQ(1, metadata_v1.acked_sequence_number()); EXPECT_EQ(1, metadata_v1.server_version()); - DeleteItem(kTag1); + DeleteItem(kKey1); EXPECT_EQ(0U, db().DataCount()); // Metadata is not removed until the commit response comes back. EXPECT_EQ(1U, db().MetadataCount()); EXPECT_EQ(1U, ProcessorEntityCount()); - worker()->ExpectPendingCommits({kTag1}); + worker()->ExpectPendingCommits({kHash1}); - const sync_pb::EntityMetadata metadata_v2 = db().GetMetadata(kTag1); + const EntityMetadata metadata_v2 = db().GetMetadata(kKey1); EXPECT_TRUE(metadata_v2.is_deleted()); EXPECT_EQ(2, metadata_v2.sequence_number()); EXPECT_EQ(1, metadata_v2.acked_sequence_number()); @@ -1077,31 +1105,31 @@ // response, then getting the commit responses. TEST_F(SharedModelTypeProcessorTest, LocalDeleteItemInterleaved) { InitializeToReadyState(); - WriteItem(kTag1, kValue1); - worker()->ExpectPendingCommits({kTag1}); + WriteItem(kKey1, kValue1); + worker()->ExpectPendingCommits({kHash1}); const CommitRequestData& data_v1 = - worker()->GetLatestPendingCommitForTag(kTag1); + worker()->GetLatestPendingCommitForHash(kHash1); - const sync_pb::EntityMetadata metadata_v1 = db().GetMetadata(kTag1); + const EntityMetadata metadata_v1 = db().GetMetadata(kKey1); EXPECT_FALSE(metadata_v1.is_deleted()); EXPECT_EQ(1, metadata_v1.sequence_number()); EXPECT_EQ(0, metadata_v1.acked_sequence_number()); EXPECT_EQ(kUncommittedVersion, metadata_v1.server_version()); - DeleteItem(kTag1); + DeleteItem(kKey1); EXPECT_EQ(0U, db().DataCount()); EXPECT_EQ(1U, db().MetadataCount()); EXPECT_EQ(1U, ProcessorEntityCount()); - worker()->ExpectPendingCommits({kTag1, kTag1}); + worker()->ExpectPendingCommits({kHash1, kHash1}); const CommitRequestData& data_v2 = - worker()->GetLatestPendingCommitForTag(kTag1); + worker()->GetLatestPendingCommitForHash(kHash1); EXPECT_GT(data_v2.sequence_number, data_v1.sequence_number); EXPECT_TRUE(data_v2.entity->id.empty()); EXPECT_EQ(kUncommittedVersion, data_v2.base_version); EXPECT_TRUE(data_v2.entity->is_deleted()); - const sync_pb::EntityMetadata metadata_v2 = db().GetMetadata(kTag1); + const EntityMetadata metadata_v2 = db().GetMetadata(kKey1); EXPECT_TRUE(metadata_v2.is_deleted()); EXPECT_EQ(2, metadata_v2.sequence_number()); EXPECT_EQ(0, metadata_v2.acked_sequence_number()); @@ -1113,7 +1141,7 @@ EXPECT_EQ(1U, db().MetadataCount()); EXPECT_EQ(1U, ProcessorEntityCount()); - const sync_pb::EntityMetadata metadata_v3 = db().GetMetadata(kTag1); + const EntityMetadata metadata_v3 = db().GetMetadata(kKey1); EXPECT_TRUE(metadata_v3.is_deleted()); EXPECT_EQ(2, metadata_v3.sequence_number()); EXPECT_EQ(1, metadata_v3.acked_sequence_number()); @@ -1127,13 +1155,13 @@ TEST_F(SharedModelTypeProcessorTest, ServerDeleteItem) { InitializeToReadyState(); - WriteItemAndAck(kTag1, kValue1); + WriteItemAndAck(kKey1, kValue1); EXPECT_EQ(1U, ProcessorEntityCount()); EXPECT_EQ(1U, db().MetadataCount()); EXPECT_EQ(1U, db().DataCount()); EXPECT_EQ(0U, worker()->GetNumPendingCommits()); - worker()->TombstoneFromServer(kTag1); + worker()->TombstoneFromServer(kHash1); // Delete from server should clear the data and all the metadata. EXPECT_EQ(0U, db().DataCount()); EXPECT_EQ(0U, db().MetadataCount()); @@ -1145,7 +1173,7 @@ // Should have no effect and not crash. TEST_F(SharedModelTypeProcessorTest, LocalDeleteUnknown) { InitializeToReadyState(); - DeleteItem(kTag1); + DeleteItem(kKey1); EXPECT_EQ(0U, db().DataCount()); EXPECT_EQ(0U, db().MetadataCount()); EXPECT_EQ(0U, ProcessorEntityCount()); @@ -1156,7 +1184,7 @@ // Should have no effect and not crash. TEST_F(SharedModelTypeProcessorTest, ServerDeleteUnknown) { InitializeToReadyState(); - worker()->TombstoneFromServer(kTag1); + worker()->TombstoneFromServer(kHash1); EXPECT_EQ(0U, db().DataCount()); EXPECT_EQ(0U, db().MetadataCount()); EXPECT_EQ(0U, ProcessorEntityCount()); @@ -1169,21 +1197,21 @@ InitializeToReadyState(); EXPECT_EQ(0U, worker()->GetNumPendingCommits()); - WriteItem(kTag1, kValue1); + WriteItem(kKey1, kValue1); EXPECT_EQ(1U, db().DataCount()); EXPECT_EQ(1U, db().MetadataCount()); - const sync_pb::EntityMetadata metadata1 = db().GetMetadata(kTag1); + const EntityMetadata metadata1 = db().GetMetadata(kKey1); // There should be one commit request for this item only. - worker()->ExpectPendingCommits({kTag1}); + worker()->ExpectPendingCommits({kHash1}); - WriteItem(kTag2, kValue2); + WriteItem(kKey2, kValue2); EXPECT_EQ(2U, db().DataCount()); EXPECT_EQ(2U, db().MetadataCount()); - const sync_pb::EntityMetadata metadata2 = db().GetMetadata(kTag2); + const EntityMetadata metadata2 = db().GetMetadata(kKey2); // The second write should trigger another single-item commit request. - worker()->ExpectPendingCommits({kTag1, kTag2}); + worker()->ExpectPendingCommits({kHash1, kHash2}); EXPECT_FALSE(metadata1.is_deleted()); EXPECT_EQ(1, metadata1.sequence_number()); @@ -1198,65 +1226,66 @@ TEST_F(SharedModelTypeProcessorTest, ConflictResolutionChangesMatch) { InitializeToReadyState(); - WriteItem(kTag1, kValue1); + EntitySpecifics specifics = WriteItem(kKey1, kValue1); EXPECT_EQ(1U, db().DataChangeCount()); - EXPECT_EQ(kValue1, db().GetValue(kTag1)); + EXPECT_EQ(kValue1, db().GetValue(kKey1)); EXPECT_EQ(1U, db().MetadataChangeCount()); - EXPECT_EQ(kUncommittedVersion, db().GetMetadata(kTag1).server_version()); - worker()->ExpectPendingCommits({kTag1}); - worker()->ExpectNthPendingCommit(0, kTag1, kValue1); + EXPECT_EQ(kUncommittedVersion, db().GetMetadata(kKey1).server_version()); + worker()->ExpectPendingCommits({kHash1}); + worker()->ExpectNthPendingCommit(0, kHash1, specifics); // Changes match doesn't call ResolveConflict. - worker()->UpdateFromServer(kTag1, kValue1); + worker()->UpdateFromServer(kHash1, specifics); // Updated metadata but not data; no new commit request. EXPECT_EQ(1U, db().DataChangeCount()); - EXPECT_EQ(1, db().GetMetadata(kTag1).server_version()); - worker()->ExpectPendingCommits({kTag1}); + EXPECT_EQ(1, db().GetMetadata(kKey1).server_version()); + worker()->ExpectPendingCommits({kHash1}); } TEST_F(SharedModelTypeProcessorTest, ConflictResolutionUseLocal) { InitializeToReadyState(); - WriteItem(kTag1, kValue1); + EntitySpecifics specifics = WriteItem(kKey1, kValue1); SetConflictResolution(ConflictResolution::UseLocal()); - worker()->UpdateFromServer(kTag1, kValue2); + worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue2)); // Updated metadata but not data; new commit request. EXPECT_EQ(1U, db().DataChangeCount()); EXPECT_EQ(2U, db().MetadataChangeCount()); - EXPECT_EQ(1, db().GetMetadata(kTag1).server_version()); - worker()->ExpectPendingCommits({kTag1, kTag1}); - worker()->ExpectNthPendingCommit(1, kTag1, kValue1); + EXPECT_EQ(1, db().GetMetadata(kKey1).server_version()); + worker()->ExpectPendingCommits({kHash1, kHash1}); + worker()->ExpectNthPendingCommit(1, kHash1, specifics); } TEST_F(SharedModelTypeProcessorTest, ConflictResolutionUseRemote) { InitializeToReadyState(); - WriteItem(kTag1, kValue1); + WriteItem(kKey1, kValue1); SetConflictResolution(ConflictResolution::UseRemote()); - worker()->UpdateFromServer(kTag1, kValue2); + worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue2)); // Updated client data and metadata; no new commit request. EXPECT_EQ(2U, db().DataChangeCount()); - EXPECT_EQ(kValue2, db().GetValue(kTag1)); + EXPECT_EQ(kValue2, db().GetValue(kKey1)); EXPECT_EQ(2U, db().MetadataChangeCount()); - EXPECT_EQ(1, db().GetMetadata(kTag1).server_version()); - worker()->ExpectPendingCommits({kTag1}); + EXPECT_EQ(1, db().GetMetadata(kKey1).server_version()); + worker()->ExpectPendingCommits({kHash1}); } TEST_F(SharedModelTypeProcessorTest, ConflictResolutionUseNew) { InitializeToReadyState(); - WriteItem(kTag1, kValue1); + WriteItem(kKey1, kValue1); SetConflictResolution( - ConflictResolution::UseNew(GenerateEntityData(kTag1, kValue3))); + ConflictResolution::UseNew(GenerateEntityData(kKey1, kValue3))); - worker()->UpdateFromServer(kTag1, kValue2); + worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue2)); EXPECT_EQ(2U, db().DataChangeCount()); - EXPECT_EQ(kValue3, db().GetValue(kTag1)); + EXPECT_EQ(kValue3, db().GetValue(kKey1)); EXPECT_EQ(2U, db().MetadataChangeCount()); - EXPECT_EQ(1, db().GetMetadata(kTag1).server_version()); - worker()->ExpectPendingCommits({kTag1, kTag1}); - worker()->ExpectNthPendingCommit(1, kTag1, kValue3); + EXPECT_EQ(1, db().GetMetadata(kKey1).server_version()); + worker()->ExpectPendingCommits({kHash1, kHash1}); + worker()->ExpectNthPendingCommit(1, kHash1, + GenerateSpecifics(kKey1, kValue3)); } // Test proper handling of disconnect and reconnect. @@ -1267,16 +1296,16 @@ InitializeToReadyState(); // The first item is fully committed. - WriteItemAndAck(kTag1, kValue1); + WriteItemAndAck(kKey1, kValue1); // The second item has a commit request in progress. - WriteItem(kTag2, kValue2); - EXPECT_TRUE(worker()->HasPendingCommitForTag(kTag2)); + WriteItem(kKey2, kValue2); + EXPECT_TRUE(worker()->HasPendingCommitForHash(kHash2)); DisconnectSync(); // The third item is added after stopping. - WriteItem(kTag3, kValue3); + WriteItem(kKey3, kValue3); // Reconnect. OnSyncStarting(); @@ -1285,13 +1314,13 @@ EXPECT_EQ(2U, worker()->GetNthPendingCommit(0).size()); // The first item was already in sync. - EXPECT_FALSE(worker()->HasPendingCommitForTag(kTag1)); + EXPECT_FALSE(worker()->HasPendingCommitForHash(kHash1)); // The second item's commit was interrupted and should be retried. - EXPECT_TRUE(worker()->HasPendingCommitForTag(kTag2)); + EXPECT_TRUE(worker()->HasPendingCommitForHash(kHash2)); // The third item's commit was not started until the reconnect. - EXPECT_TRUE(worker()->HasPendingCommitForTag(kTag3)); + EXPECT_TRUE(worker()->HasPendingCommitForHash(kHash3)); } // Test proper handling of disable and re-enable. @@ -1302,16 +1331,16 @@ InitializeToReadyState(); // The first item is fully committed. - WriteItemAndAck(kTag1, kValue1); + WriteItemAndAck(kKey1, kValue1); // The second item has a commit request in progress. - WriteItem(kTag2, kValue2); - EXPECT_TRUE(worker()->HasPendingCommitForTag(kTag2)); + WriteItem(kKey2, kValue2); + EXPECT_TRUE(worker()->HasPendingCommitForHash(kHash2)); DisableSync(); // The third item is added after disable. - WriteItem(kTag3, kValue3); + WriteItem(kKey3, kValue3); // Now we re-enable. CreateChangeProcessor(); @@ -1321,7 +1350,7 @@ // Once we're ready to commit, all three local items should consider // themselves uncommitted and pending for commit. - worker()->ExpectPendingCommits({kTag1, kTag2, kTag3}); + worker()->ExpectPendingCommits({kHash1, kHash2, kHash3}); } // Test re-encrypt everything when desired encryption key changes. @@ -1329,33 +1358,33 @@ InitializeToReadyState(); // Commit an item. - WriteItemAndAck(kTag1, kValue1); + EntitySpecifics specifics1 = WriteItemAndAck(kKey1, kValue1); // Create another item and don't wait for its commit response. - WriteItem(kTag2, kValue2); - worker()->ExpectPendingCommits({kTag2}); - EXPECT_EQ(1U, db().GetMetadata(kTag1).sequence_number()); - EXPECT_EQ(1U, db().GetMetadata(kTag2).sequence_number()); + EntitySpecifics specifics2 = WriteItem(kKey2, kValue2); + worker()->ExpectPendingCommits({kHash2}); + EXPECT_EQ(1U, db().GetMetadata(kKey1).sequence_number()); + EXPECT_EQ(1U, db().GetMetadata(kKey2).sequence_number()); // Receive notice that the account's desired encryption key has changed. worker()->UpdateWithEncryptionKey("k1"); // Tag 2 is recommitted immediately because the data was in memory. ASSERT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(1, kTag2, kValue2); + worker()->ExpectNthPendingCommit(1, kHash2, specifics2); // Sequence numbers in the store are updated. - EXPECT_EQ(2U, db().GetMetadata(kTag1).sequence_number()); - EXPECT_EQ(2U, db().GetMetadata(kTag2).sequence_number()); + EXPECT_EQ(2U, db().GetMetadata(kKey1).sequence_number()); + EXPECT_EQ(2U, db().GetMetadata(kKey2).sequence_number()); // Tag 1 needs to go to the store to load its data before recommitting. OnPendingCommitDataLoaded(); ASSERT_EQ(3U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(2, kTag1, kValue1); + worker()->ExpectNthPendingCommit(2, kHash1, specifics1); } // Test that an error loading pending commit data for re-encryption is // propagated to the error handler. TEST_F(SharedModelTypeProcessorTest, ReEncryptErrorLoadingData) { InitializeToReadyState(); - WriteItemAndAck(kTag1, kValue1); + WriteItemAndAck(kKey1, kValue1); SetServiceError(syncer::SyncError::DATATYPE_ERROR); worker()->UpdateWithEncryptionKey("k1"); error_handler()->ExpectError(syncer::SyncError::DATATYPE_ERROR); @@ -1367,99 +1396,106 @@ InitializeToReadyState(); // Receive an unencrypted update. - worker()->UpdateFromServer(kTag1, kValue1); + worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue1)); ASSERT_EQ(0U, worker()->GetNumPendingCommits()); UpdateResponseDataList update; // Receive an entity with old encryption as part of the update. - update.push_back(worker()->GenerateUpdateData(kTag2, kValue2, 1, "k1")); + update.push_back(worker()->GenerateUpdateData( + kHash2, GenerateSpecifics(kKey2, kValue2), 1, "k1")); // Receive an entity with up-to-date encryption as part of the update. - update.push_back(worker()->GenerateUpdateData(kTag3, kValue3, 1, "k2")); + update.push_back(worker()->GenerateUpdateData( + kHash3, GenerateSpecifics(kKey3, kValue3), 1, "k2")); // Set desired encryption key to k2 to force updates to some items. worker()->UpdateWithEncryptionKey("k2", update); - // kTag2 needed to be re-encrypted and had data so it was queued immediately. - worker()->ExpectPendingCommits({kTag2}); + // kKey2 needed to be re-encrypted and had data so it was queued immediately. + worker()->ExpectPendingCommits({kHash2}); OnPendingCommitDataLoaded(); - // kTag1 needed data so once that's loaded, it is also queued. - worker()->ExpectPendingCommits({kTag2, kTag1}); + // kKey1 needed data so once that's loaded, it is also queued. + worker()->ExpectPendingCommits({kHash2, kHash1}); // Receive a separate update that was encrypted with key k1. - worker()->UpdateFromServer("enc_k1", kValue1, 1, "k1"); + worker()->UpdateFromServer(kHash4, GenerateSpecifics(kKey4, kValue1), 1, + "k1"); // Receipt of updates encrypted with old key also forces a re-encrypt commit. - worker()->ExpectPendingCommits({kTag2, kTag1, "enc_k1"}); + worker()->ExpectPendingCommits({kHash2, kHash1, kHash4}); // Receive an update that was encrypted with key k2. - worker()->UpdateFromServer("enc_k2", kValue1, 1, "k2"); + worker()->UpdateFromServer(kHash5, GenerateSpecifics(kKey5, kValue1), 1, + "k2"); // That was the correct key, so no re-encryption is required. - worker()->ExpectPendingCommits({kTag2, kTag1, "enc_k1"}); + worker()->ExpectPendingCommits({kHash2, kHash1, kHash4}); } // Test that re-encrypting enqueues the right data for USE_LOCAL conflicts. TEST_F(SharedModelTypeProcessorTest, ReEncryptConflictResolutionUseLocal) { InitializeToReadyState(); worker()->UpdateWithEncryptionKey("k1"); - WriteItem(kTag1, kValue1); - worker()->ExpectPendingCommits({kTag1}); + EntitySpecifics specifics = WriteItem(kKey1, kValue1); + worker()->ExpectPendingCommits({kHash1}); SetConflictResolution(ConflictResolution::UseLocal()); // Unencrypted update needs to be re-commited with key k1. - worker()->UpdateFromServer(kTag1, kValue2, 1, ""); + worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue2), 1, ""); // Ensure the re-commit has the correct value. EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(1, kTag1, kValue1); - EXPECT_EQ(kValue1, db().GetValue(kTag1)); + worker()->ExpectNthPendingCommit(1, kHash1, specifics); + EXPECT_EQ(kValue1, db().GetValue(kKey1)); } // Test that re-encrypting enqueues the right data for USE_REMOTE conflicts. TEST_F(SharedModelTypeProcessorTest, ReEncryptConflictResolutionUseRemote) { InitializeToReadyState(); worker()->UpdateWithEncryptionKey("k1"); - WriteItem(kTag1, kValue1); + WriteItem(kKey1, kValue1); SetConflictResolution(ConflictResolution::UseRemote()); // Unencrypted update needs to be re-commited with key k1. - worker()->UpdateFromServer(kTag1, kValue2, 1, ""); + EntitySpecifics specifics = GenerateSpecifics(kKey1, kValue2); + worker()->UpdateFromServer(kHash1, specifics, 1, ""); // Ensure the re-commit has the correct value. EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(1, kTag1, kValue2); - EXPECT_EQ(kValue2, db().GetValue(kTag1)); + worker()->ExpectNthPendingCommit(1, kHash1, specifics); + EXPECT_EQ(kValue2, db().GetValue(kKey1)); } // Test that re-encrypting enqueues the right data for USE_NEW conflicts. TEST_F(SharedModelTypeProcessorTest, ReEncryptConflictResolutionUseNew) { InitializeToReadyState(); worker()->UpdateWithEncryptionKey("k1"); - WriteItem(kTag1, kValue1); + WriteItem(kKey1, kValue1); SetConflictResolution( - ConflictResolution::UseNew(GenerateEntityData(kTag1, kValue3))); + ConflictResolution::UseNew(GenerateEntityData(kKey1, kValue3))); // Unencrypted update needs to be re-commited with key k1. - worker()->UpdateFromServer(kTag1, kValue2, 1, ""); + worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue2), 1, ""); // Ensure the re-commit has the correct value. EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(1, kTag1, kValue3); - EXPECT_EQ(kValue3, db().GetValue(kTag1)); + worker()->ExpectNthPendingCommit(1, kHash1, + GenerateSpecifics(kKey1, kValue3)); + EXPECT_EQ(kValue3, db().GetValue(kKey1)); } TEST_F(SharedModelTypeProcessorTest, ReEncryptConflictWhileLoading) { InitializeToReadyState(); // Create item and ack so its data is no longer cached. - WriteItemAndAck(kTag1, kValue1); + WriteItemAndAck(kKey1, kValue1); // Update key so that it needs to fetch data to re-commit. worker()->UpdateWithEncryptionKey("k1"); EXPECT_EQ(0U, worker()->GetNumPendingCommits()); // Unencrypted update needs to be re-commited with key k1. - worker()->UpdateFromServer(kTag1, kValue2, 1, ""); + EntitySpecifics specifics = GenerateSpecifics(kKey1, kValue2); + worker()->UpdateFromServer(kHash1, specifics, 1, ""); // Ensure the re-commit has the correct value. EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, kValue2); - EXPECT_EQ(kValue2, db().GetValue(kTag1)); + worker()->ExpectNthPendingCommit(0, kHash1, specifics); + EXPECT_EQ(kValue2, db().GetValue(kKey1)); // Data load completing shouldn't change anything. OnPendingCommitDataLoaded(); @@ -1469,46 +1505,46 @@ // Tests that a real remote change wins over a local encryption-only change. TEST_F(SharedModelTypeProcessorTest, IgnoreLocalEncryption) { InitializeToReadyState(); - WriteItemAndAck(kTag1, kValue1); + EntitySpecifics specifics = WriteItemAndAck(kKey1, kValue1); worker()->UpdateWithEncryptionKey("k1"); OnPendingCommitDataLoaded(); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, kValue1); + worker()->ExpectNthPendingCommit(0, kHash1, specifics); - worker()->UpdateFromServer(kTag1, kValue2); + worker()->UpdateFromServer(kHash1, GenerateSpecifics(kKey1, kValue2)); EXPECT_EQ(1U, worker()->GetNumPendingCommits()); } // Tests that a real local change wins over a remote encryption-only change. TEST_F(SharedModelTypeProcessorTest, IgnoreRemoteEncryption) { InitializeToReadyState(); - WriteItemAndAck(kTag1, kValue1); + EntitySpecifics specifics1 = WriteItemAndAck(kKey1, kValue1); - WriteItem(kTag1, kValue2); + EntitySpecifics specifics2 = WriteItem(kKey1, kValue2); UpdateResponseDataList update; - update.push_back(worker()->GenerateUpdateData(kTag1, kValue1, 1, "k1")); + update.push_back(worker()->GenerateUpdateData(kHash1, specifics1, 1, "k1")); worker()->UpdateWithEncryptionKey("k1", update); EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(1, kTag1, kValue2); + worker()->ExpectNthPendingCommit(1, kHash1, specifics2); } // Same as above but with two commit requests before one ack. TEST_F(SharedModelTypeProcessorTest, IgnoreRemoteEncryptionInterleaved) { InitializeToReadyState(); - WriteItem(kTag1, kValue1); - WriteItem(kTag1, kValue2); + EntitySpecifics specifics1 = WriteItem(kKey1, kValue1); + EntitySpecifics specifics2 = WriteItem(kKey1, kValue2); worker()->AckOnePendingCommit(); // kValue1 is now the base value. EXPECT_EQ(1U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(0, kTag1, kValue2); + worker()->ExpectNthPendingCommit(0, kHash1, specifics2); UpdateResponseDataList update; - update.push_back(worker()->GenerateUpdateData(kTag1, kValue1, 1, "k1")); + update.push_back(worker()->GenerateUpdateData(kHash1, specifics1, 1, "k1")); worker()->UpdateWithEncryptionKey("k1", update); EXPECT_EQ(2U, worker()->GetNumPendingCommits()); - worker()->ExpectNthPendingCommit(1, kTag1, kValue2); + worker()->ExpectNthPendingCommit(1, kHash1, specifics2); } } // namespace syncer_v2
diff --git a/components/sync/core/shutdown_reason.h b/components/sync/core/shutdown_reason.h index ccf498e..193bf44 100644 --- a/components/sync/core/shutdown_reason.h +++ b/components/sync/core/shutdown_reason.h
@@ -5,8 +5,6 @@ #ifndef COMPONENTS_SYNC_CORE_SHUTDOWN_REASON_H_ #define COMPONENTS_SYNC_CORE_SHUTDOWN_REASON_H_ -#include "components/sync/base/sync_export.h" - namespace syncer { // Reason for shutting down sync engine.
diff --git a/components/sync/core/simple_metadata_change_list.h b/components/sync/core/simple_metadata_change_list.h index 8a130c2..f04562a 100644 --- a/components/sync/core/simple_metadata_change_list.h +++ b/components/sync/core/simple_metadata_change_list.h
@@ -10,7 +10,6 @@ #include "components/sync/api/metadata_change_list.h" #include "components/sync/api/model_type_store.h" -#include "components/sync/base/sync_export.h" #include "components/sync/core/non_blocking_sync_common.h" #include "components/sync/protocol/data_type_state.pb.h" #include "components/sync/protocol/entity_metadata.pb.h" @@ -20,7 +19,7 @@ // A MetadataChangeList implementation that is meant to be used in combination // with a ModelTypeStore. It accumulates changes in member fields, and then when // requested transfers them to the store/write batch. -class SYNC_EXPORT SimpleMetadataChangeList : public MetadataChangeList { +class SimpleMetadataChangeList : public MetadataChangeList { public: enum ChangeType { UPDATE, CLEAR };
diff --git a/components/sync/core/sync_encryption_handler.h b/components/sync/core/sync_encryption_handler.h index 098c974f..45aa304e 100644 --- a/components/sync/core/sync_encryption_handler.h +++ b/components/sync/core/sync_encryption_handler.h
@@ -9,7 +9,6 @@ #include "base/time/time.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/protocol/sync.pb.h" namespace syncer { @@ -51,13 +50,13 @@ // and keeps the nigori node up to date. // Implementations of this class must be assumed to be non-thread-safe. All // methods must be invoked on the sync thread. -class SYNC_EXPORT SyncEncryptionHandler { +class SyncEncryptionHandler { public: class NigoriState; // All Observer methods are done synchronously from within a transaction and // on the sync thread. - class SYNC_EXPORT Observer { + class Observer { public: Observer(); @@ -132,7 +131,7 @@ virtual ~Observer(); }; - class SYNC_EXPORT NigoriState { + class NigoriState { public: NigoriState() {} sync_pb::NigoriSpecifics nigori_specifics;
diff --git a/components/sync/core/sync_manager.h b/components/sync/core/sync_manager.h index e5c1e36..794625a 100644 --- a/components/sync/core/sync_manager.h +++ b/components/sync/core/sync_manager.h
@@ -19,7 +19,6 @@ #include "base/threading/thread_checker.h" #include "components/sync/base/invalidation_interface.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/weak_handle.h" #include "components/sync/core/change_record.h" #include "components/sync/core/configure_reason.h" @@ -64,7 +63,7 @@ } // namespace sessions // Contains everything needed to talk to and identify a user account. -struct SYNC_EXPORT SyncCredentials { +struct SyncCredentials { SyncCredentials(); SyncCredentials(const SyncCredentials& other); ~SyncCredentials(); @@ -90,12 +89,12 @@ // // Unless stated otherwise, all methods of SyncManager should be called on the // same thread. -class SYNC_EXPORT SyncManager { +class SyncManager { public: // An interface the embedding application implements to be notified // on change events. Note that these methods may be called on *any* // thread. - class SYNC_EXPORT ChangeDelegate { + class ChangeDelegate { public: // Notify the delegate that changes have been applied to the sync model. // @@ -147,7 +146,7 @@ // Like ChangeDelegate, except called only on the sync thread and // not while a transaction is held. For objects that want to know // when changes happen, but don't need to process them. - class SYNC_EXPORT ChangeObserver { + class ChangeObserver { public: // Ids referred to in |changes| may or may not be in the write // transaction specified by |write_transaction_id|. If they're @@ -179,7 +178,7 @@ // notifications from the SyncManager. Register an observer via // SyncManager::AddObserver. All methods are called only on the // sync thread. - class SYNC_EXPORT Observer { + class Observer { public: // A round-trip sync-cycle took place and the syncer has resolved any // conflicts that may have arisen. @@ -216,7 +215,7 @@ }; // Arguments for initializing SyncManager. - struct SYNC_EXPORT InitArgs { + struct InitArgs { InitArgs(); ~InitArgs();
diff --git a/components/sync/core/sync_manager_factory.h b/components/sync/core/sync_manager_factory.h index 744deab..827d5b6 100644 --- a/components/sync/core/sync_manager_factory.h +++ b/components/sync/core/sync_manager_factory.h
@@ -9,14 +9,13 @@ #include <string> #include "base/macros.h" -#include "components/sync/base/sync_export.h" namespace syncer { class SyncManager; // Helper class to allow dependency injection of the SyncManager in tests. -class SYNC_EXPORT SyncManagerFactory { +class SyncManagerFactory { public: SyncManagerFactory(); virtual ~SyncManagerFactory();
diff --git a/components/sync/core/user_share.h b/components/sync/core/user_share.h index 668b300..1a97e6b 100644 --- a/components/sync/core/user_share.h +++ b/components/sync/core/user_share.h
@@ -8,7 +8,6 @@ #include <memory> #include <string> -#include "components/sync/base/sync_export.h" #include "components/sync/core/sync_manager.h" namespace syncer { @@ -21,7 +20,7 @@ // user and their data (share). // This encompasses all pieces required to build transaction objects on the // syncable share. -struct SYNC_EXPORT UserShare { +struct UserShare { UserShare(); ~UserShare();
diff --git a/components/sync/core/write_node.h b/components/sync/core/write_node.h index fa8e0b8..1c23cb3 100644 --- a/components/sync/core/write_node.h +++ b/components/sync/core/write_node.h
@@ -15,7 +15,6 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/core/base_node.h" namespace sync_pb { @@ -39,7 +38,7 @@ // WriteNode extends BaseNode to add mutation, and wraps // syncable::MutableEntry. A WriteTransaction is needed to create a WriteNode. -class SYNC_EXPORT WriteNode : public BaseNode { +class WriteNode : public BaseNode { public: enum InitUniqueByCreationResult { INIT_SUCCESS,
diff --git a/components/sync/core/write_transaction.h b/components/sync/core/write_transaction.h index 1854bb2..65f5363 100644 --- a/components/sync/core/write_transaction.h +++ b/components/sync/core/write_transaction.h
@@ -13,7 +13,6 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "components/sync/api/sync_change_processor.h" -#include "components/sync/base/sync_export.h" #include "components/sync/core/base_transaction.h" namespace tracked_objects { @@ -32,7 +31,7 @@ // // NOTE: Only a single model type can be mutated for a given // WriteTransaction. -class SYNC_EXPORT WriteTransaction : public BaseTransaction { +class WriteTransaction : public BaseTransaction { public: // Start a new read/write transaction. WriteTransaction(const tracked_objects::Location& from_here,
diff --git a/components/sync/core_impl/attachments/proto/BUILD.gn b/components/sync/core_impl/attachments/proto/BUILD.gn index 1a8f1b7..6ec4b95 100644 --- a/components/sync/core_impl/attachments/proto/BUILD.gn +++ b/components/sync/core_impl/attachments/proto/BUILD.gn
@@ -6,13 +6,9 @@ proto_library("proto") { # This should only get compiled into the sync component. - visibility = [ "//components/sync:sync_core" ] + visibility = [ "//components/sync" ] sources = [ "attachment_store.proto", ] - cc_generator_options = "dllexport_decl=SYNC_EXPORT:" - cc_include = "components/sync/base/sync_export.h" - - defines = [ "SYNC_IMPLEMENTATION" ] }
diff --git a/components/sync/core_impl/debug_info_event_listener.h b/components/sync/core_impl/debug_info_event_listener.h index 88f46f55..91f521c 100644 --- a/components/sync/core_impl/debug_info_event_listener.h +++ b/components/sync/core_impl/debug_info_event_listener.h
@@ -13,7 +13,6 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/weak_handle.h" #include "components/sync/core/data_type_debug_info_listener.h" #include "components/sync/core/sync_encryption_handler.h" @@ -33,11 +32,10 @@ // Listens to events and records them in a queue. And passes the events to // syncer when requested. // This class is not thread safe and should only be accessed on the sync thread. -class SYNC_EXPORT DebugInfoEventListener - : public SyncManager::Observer, - public SyncEncryptionHandler::Observer, - public sessions::DebugInfoGetter, - public DataTypeDebugInfoListener { +class DebugInfoEventListener : public SyncManager::Observer, + public SyncEncryptionHandler::Observer, + public sessions::DebugInfoGetter, + public DataTypeDebugInfoListener { public: DebugInfoEventListener(); ~DebugInfoEventListener() override;
diff --git a/components/sync/core_impl/js_mutation_event_observer.h b/components/sync/core_impl/js_mutation_event_observer.h index 255b273..e9d4440e 100644 --- a/components/sync/core_impl/js_mutation_event_observer.h +++ b/components/sync/core_impl/js_mutation_event_observer.h
@@ -13,7 +13,6 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/threading/non_thread_safe.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/weak_handle.h" #include "components/sync/core/sync_manager.h" #include "components/sync/syncable/transaction_observer.h" @@ -29,10 +28,9 @@ // Observes all change- and transaction-related events and routes a // summarized version to a JsEventHandler. -class SYNC_EXPORT JsMutationEventObserver - : public SyncManager::ChangeObserver, - public syncable::TransactionObserver, - public base::NonThreadSafe { +class JsMutationEventObserver : public SyncManager::ChangeObserver, + public syncable::TransactionObserver, + public base::NonThreadSafe { public: JsMutationEventObserver();
diff --git a/components/sync/core_impl/js_sync_encryption_handler_observer.h b/components/sync/core_impl/js_sync_encryption_handler_observer.h index 6a0b1577..fc1e831f 100644 --- a/components/sync/core_impl/js_sync_encryption_handler_observer.h +++ b/components/sync/core_impl/js_sync_encryption_handler_observer.h
@@ -9,7 +9,6 @@ #include "base/compiler_specific.h" #include "base/macros.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/weak_handle.h" #include "components/sync/core/sync_encryption_handler.h" #include "components/sync/protocol/sync_protocol_error.h" @@ -24,8 +23,7 @@ class JsEventHandler; // Routes SyncEncryptionHandler events to a JsEventHandler. -class SYNC_EXPORT JsSyncEncryptionHandlerObserver - : public SyncEncryptionHandler::Observer { +class JsSyncEncryptionHandlerObserver : public SyncEncryptionHandler::Observer { public: JsSyncEncryptionHandlerObserver(); ~JsSyncEncryptionHandlerObserver() override;
diff --git a/components/sync/core_impl/js_sync_manager_observer.h b/components/sync/core_impl/js_sync_manager_observer.h index b642dd8..cde3c41 100644 --- a/components/sync/core_impl/js_sync_manager_observer.h +++ b/components/sync/core_impl/js_sync_manager_observer.h
@@ -9,7 +9,6 @@ #include "base/compiler_specific.h" #include "base/macros.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/weak_handle.h" #include "components/sync/core/sync_manager.h" #include "components/sync/protocol/sync_protocol_error.h" @@ -24,7 +23,7 @@ class JsEventHandler; // Routes SyncManager events to a JsEventHandler. -class SYNC_EXPORT JsSyncManagerObserver : public SyncManager::Observer { +class JsSyncManagerObserver : public SyncManager::Observer { public: JsSyncManagerObserver(); ~JsSyncManagerObserver() override;
diff --git a/components/sync/core_impl/model_type_connector_proxy.h b/components/sync/core_impl/model_type_connector_proxy.h index b832cabc..f71f65b 100644 --- a/components/sync/core_impl/model_type_connector_proxy.h +++ b/components/sync/core_impl/model_type_connector_proxy.h
@@ -10,7 +10,6 @@ #include "base/memory/weak_ptr.h" #include "base/sequenced_task_runner.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/core/model_type_connector.h" namespace syncer_v2 { @@ -18,7 +17,7 @@ // Proxies all ModelTypeConnector calls to another thread. Typically used by // the SyncBackend to call from the UI thread to the real ModelTypeConnector on // the sync thread. -class SYNC_EXPORT ModelTypeConnectorProxy : public ModelTypeConnector { +class ModelTypeConnectorProxy : public ModelTypeConnector { public: ModelTypeConnectorProxy( const scoped_refptr<base::SequencedTaskRunner>& task_runner,
diff --git a/components/sync/core_impl/protocol_event_buffer.h b/components/sync/core_impl/protocol_event_buffer.h index ee7ddeee..521cc2f 100644 --- a/components/sync/core_impl/protocol_event_buffer.h +++ b/components/sync/core_impl/protocol_event_buffer.h
@@ -11,7 +11,6 @@ #include "base/macros.h" #include "base/memory/scoped_vector.h" -#include "components/sync/base/sync_export.h" namespace syncer { @@ -20,7 +19,7 @@ // A container for ProtocolEvents. // // Stores at most kBufferSize events, then starts dropping the oldest events. -class SYNC_EXPORT ProtocolEventBuffer { +class ProtocolEventBuffer { public: static const size_t kBufferSize; @@ -35,7 +34,7 @@ private: std::deque<ProtocolEvent*> buffer_; - STLElementDeleter<std::deque<ProtocolEvent*>> buffer_deleter_; + base::STLElementDeleter<std::deque<ProtocolEvent*>> buffer_deleter_; DISALLOW_COPY_AND_ASSIGN(ProtocolEventBuffer); };
diff --git a/components/sync/core_impl/sync_encryption_handler_impl.h b/components/sync/core_impl/sync_encryption_handler_impl.h index 25b4d01..08f99e3 100644 --- a/components/sync/core_impl/sync_encryption_handler_impl.h +++ b/components/sync/core_impl/sync_encryption_handler_impl.h
@@ -16,7 +16,6 @@ #include "base/threading/thread_checker.h" #include "base/time/time.h" #include "components/sync/base/cryptographer.h" -#include "components/sync/base/sync_export.h" #include "components/sync/core/sync_encryption_handler.h" #include "components/sync/syncable/nigori_handler.h" @@ -43,8 +42,8 @@ // sync methods. // All methods are non-thread-safe and should only be called from the sync // thread unless explicitly noted otherwise. -class SYNC_EXPORT SyncEncryptionHandlerImpl : public SyncEncryptionHandler, - public syncable::NigoriHandler { +class SyncEncryptionHandlerImpl : public SyncEncryptionHandler, + public syncable::NigoriHandler { public: SyncEncryptionHandlerImpl( UserShare* user_share,
diff --git a/components/sync/core_impl/sync_manager_impl.h b/components/sync/core_impl/sync_manager_impl.h index 6c584a6..0d7d7d3 100644 --- a/components/sync/core_impl/sync_manager_impl.h +++ b/components/sync/core_impl/sync_manager_impl.h
@@ -14,7 +14,6 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "components/sync/base/cryptographer.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/time.h" #include "components/sync/core/sync_manager.h" #include "components/sync/core/user_share.h" @@ -55,7 +54,7 @@ // // Unless stated otherwise, all methods of SyncManager should be called on the // same thread. -class SYNC_EXPORT SyncManagerImpl +class SyncManagerImpl : public SyncManager, public net::NetworkChangeNotifier::IPAddressObserver, public net::NetworkChangeNotifier::ConnectionTypeObserver,
diff --git a/components/sync/core_impl/syncapi_internal.h b/components/sync/core_impl/syncapi_internal.h index c53467f..443bf35f 100644 --- a/components/sync/core_impl/syncapi_internal.h +++ b/components/sync/core_impl/syncapi_internal.h
@@ -10,8 +10,6 @@ #include <string> -#include "components/sync/base/sync_export.h" - namespace sync_pb { class AttachmentMetadata; class EntitySpecifics; @@ -26,10 +24,8 @@ const sync_pb::EntitySpecifics& specifics, Cryptographer* crypto); -SYNC_EXPORT void SyncAPINameToServerName(const std::string& syncer_name, - std::string* out); -SYNC_EXPORT void ServerNameToSyncAPIName(const std::string& server_name, - std::string* out); +void SyncAPINameToServerName(const std::string& syncer_name, std::string* out); +void ServerNameToSyncAPIName(const std::string& server_name, std::string* out); bool IsNameServerIllegalAfterTrimming(const std::string& name);
diff --git a/components/sync/core_impl/syncapi_server_connection_manager.h b/components/sync/core_impl/syncapi_server_connection_manager.h index 53aa61a..f3aa2d1 100644 --- a/components/sync/core_impl/syncapi_server_connection_manager.h +++ b/components/sync/core_impl/syncapi_server_connection_manager.h
@@ -11,7 +11,6 @@ #include "base/compiler_specific.h" #include "base/gtest_prod_util.h" #include "base/macros.h" -#include "components/sync/base/sync_export.h" #include "components/sync/engine_impl/net/server_connection_manager.h" namespace syncer { @@ -48,8 +47,7 @@ // A ServerConnectionManager subclass used by the syncapi layer. We use a // subclass so that we can override MakePost() to generate a POST object using // an instance of the HttpPostProviderFactory class. -class SYNC_EXPORT SyncAPIServerConnectionManager - : public ServerConnectionManager { +class SyncAPIServerConnectionManager : public ServerConnectionManager { public: // Takes ownership of factory. SyncAPIServerConnectionManager(const std::string& server,
diff --git a/components/sync/driver/DEPS b/components/sync/driver/DEPS new file mode 100644 index 0000000..7d7d943 --- /dev/null +++ b/components/sync/driver/DEPS
@@ -0,0 +1,26 @@ +include_rules = [ + "+components/data_use_measurement/core", + "+components/invalidation", + "+components/metrics", + "+components/os_crypt", + "+components/policy", + "+components/pref_registry", + "+components/prefs", + "+components/signin/core/browser", + "+components/sync/api", + "+components/sync/base", + "+components/sync/core", + "+components/sync/engine", + # TODO(maxbogue): Move commit_queue.h to engine. + "+components/sync/engine_impl", + "+components/sync/protocol", + "+components/sync/sessions", + "+components/sync/syncable", + "+components/sync/test", + "+components/syncable_prefs", + "+components/version_info", + "+google", + "+google_apis", + "+net", + "+policy", +]
diff --git a/components/sync_driver/PRESUBMIT.py b/components/sync/driver/PRESUBMIT.py similarity index 100% rename from components/sync_driver/PRESUBMIT.py rename to components/sync/driver/PRESUBMIT.py
diff --git a/components/sync/driver/about_sync_util.cc b/components/sync/driver/about_sync_util.cc new file mode 100644 index 0000000..fbf96ef --- /dev/null +++ b/components/sync/driver/about_sync_util.cc
@@ -0,0 +1,526 @@ +// 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/sync/driver/about_sync_util.h" + +#include <string> +#include <utility> + +#include "base/location.h" +#include "base/strings/string16.h" +#include "base/strings/stringprintf.h" +#include "base/values.h" +#include "components/signin/core/browser/signin_manager_base.h" +#include "components/sync/api/time.h" +#include "components/sync/base/sync_string_conversions.h" +#include "components/sync/driver/sync_service.h" +#include "components/sync/engine/sync_status.h" +#include "components/sync/protocol/proto_enum_conversions.h" +#include "components/sync/sessions/sync_session_snapshot.h" +#include "components/version_info/version_info.h" + +using base::DictionaryValue; +using base::ListValue; + +namespace sync_driver { + +namespace sync_ui_util { + +const char kIdentityTitle[] = "Identity"; +const char kDetailsKey[] = "details"; + +// Resource paths. +const char kAboutJS[] = "about.js"; +const char kChromeSyncJS[] = "chrome_sync.js"; +const char kDataJS[] = "data.js"; +const char kEventsJS[] = "events.js"; +const char kSearchJS[] = "search.js"; +const char kSyncIndexJS[] = "sync_index.js"; +const char kSyncLogJS[] = "sync_log.js"; +const char kSyncNodeBrowserJS[] = "sync_node_browser.js"; +const char kSyncSearchJS[] = "sync_search.js"; +const char kTypesJS[] = "types.js"; + +// Message handlers. +const char kDispatchEvent[] = "chrome.sync.dispatchEvent"; +const char kGetAllNodes[] = "getAllNodes"; +const char kGetAllNodesCallback[] = "chrome.sync.getAllNodesCallback"; +const char kRegisterForEvents[] = "registerForEvents"; +const char kRegisterForPerTypeCounters[] = "registerForPerTypeCounters"; +const char kRequestListOfTypes[] = "requestListOfTypes"; +const char kRequestUpdatedAboutInfo[] = "requestUpdatedAboutInfo"; + +// Other strings. +const char kCommit[] = "commit"; +const char kCounters[] = "counters"; +const char kCounterType[] = "counterType"; +const char kModelType[] = "modelType"; +const char kOnAboutInfoUpdated[] = "onAboutInfoUpdated"; +const char kOnCountersUpdated[] = "onCountersUpdated"; +const char kOnProtocolEvent[] = "onProtocolEvent"; +const char kOnReceivedListOfTypes[] = "onReceivedListOfTypes"; +const char kStatus[] = "status"; +const char kTypes[] = "types"; +const char kUpdate[] = "update"; + +namespace { + +// Creates a 'section' for display on about:sync, consisting of a title and a +// list of fields. Returns a pointer to the new section. Note that +// |parent_list|, not the caller, owns the newly added section. +base::ListValue* AddSection(base::ListValue* parent_list, + const std::string& title) { + std::unique_ptr<base::DictionaryValue> section(new base::DictionaryValue()); + base::ListValue* section_contents = new base::ListValue(); + section->SetString("title", title); + section->Set("data", section_contents); + section->SetBoolean("is_sensitive", false); + parent_list->Append(std::move(section)); + return section_contents; +} + +// Same as AddSection, but for data that should be elided when dumped into text +// form and posted in a public forum (e.g. unique identifiers). +base::ListValue* AddSensitiveSection(base::ListValue* parent_list, + const std::string& title) { + std::unique_ptr<base::DictionaryValue> section(new base::DictionaryValue()); + base::ListValue* section_contents = new base::ListValue(); + section->SetString("title", title); + section->Set("data", section_contents); + section->SetBoolean("is_sensitive", true); + parent_list->Append(std::move(section)); + return section_contents; +} + +// The following helper classes help manage the about:sync fields which will be +// populated in method in ConstructAboutInformation. +// +// Each instance of one of thse classes indicates a field in about:sync. Each +// field will be serialized to a DictionaryValue with entries for 'stat_name', +// 'stat_value' and 'is_valid'. + +class StringSyncStat { + public: + StringSyncStat(base::ListValue* section, const std::string& key); + void SetValue(const std::string& value); + void SetValue(const base::string16& value); + + private: + // Owned by the |section| passed in during construction. + base::DictionaryValue* stat_; +}; + +StringSyncStat::StringSyncStat(base::ListValue* section, + const std::string& key) { + stat_ = new base::DictionaryValue(); + stat_->SetString("stat_name", key); + stat_->SetString("stat_value", "Uninitialized"); + stat_->SetBoolean("is_valid", false); + section->Append(stat_); +} + +void StringSyncStat::SetValue(const std::string& value) { + stat_->SetString("stat_value", value); + stat_->SetBoolean("is_valid", true); +} + +void StringSyncStat::SetValue(const base::string16& value) { + stat_->SetString("stat_value", value); + stat_->SetBoolean("is_valid", true); +} + +class BoolSyncStat { + public: + BoolSyncStat(base::ListValue* section, const std::string& key); + void SetValue(bool value); + + private: + // Owned by the |section| passed in during construction. + base::DictionaryValue* stat_; +}; + +BoolSyncStat::BoolSyncStat(base::ListValue* section, const std::string& key) { + stat_ = new base::DictionaryValue(); + stat_->SetString("stat_name", key); + stat_->SetBoolean("stat_value", false); + stat_->SetBoolean("is_valid", false); + section->Append(stat_); +} + +void BoolSyncStat::SetValue(bool value) { + stat_->SetBoolean("stat_value", value); + stat_->SetBoolean("is_valid", true); +} + +class IntSyncStat { + public: + IntSyncStat(base::ListValue* section, const std::string& key); + void SetValue(int value); + + private: + // Owned by the |section| passed in during construction. + base::DictionaryValue* stat_; +}; + +IntSyncStat::IntSyncStat(base::ListValue* section, const std::string& key) { + stat_ = new base::DictionaryValue(); + stat_->SetString("stat_name", key); + stat_->SetInteger("stat_value", 0); + stat_->SetBoolean("is_valid", false); + section->Append(stat_); +} + +void IntSyncStat::SetValue(int value) { + stat_->SetInteger("stat_value", value); + stat_->SetBoolean("is_valid", true); +} + +// Returns a string describing the chrome version environment. Version format: +// <Build Info> <OS> <Version number> (<Last change>)<channel or "-devel"> +// If version information is unavailable, returns "invalid." +// TODO(zea): this approximately matches MakeUserAgentForSyncApi in +// sync_backend_host.cc. Unify the two if possible. +std::string GetVersionString(version_info::Channel channel) { + // Build a version string that matches MakeUserAgentForSyncApi with the + // addition of channel info and proper OS names. + // chrome::GetChannelString() returns empty string for stable channel or + // unofficial builds, the channel string otherwise. We want to have "-devel" + // for unofficial builds only. + std::string version_modifier = version_info::GetChannelString(channel); + if (version_modifier.empty()) { + if (channel != version_info::Channel::STABLE) { + version_modifier = "-devel"; + } + } else { + version_modifier = " " + version_modifier; + } + return version_info::GetProductName() + " " + version_info::GetOSType() + + " " + version_info::GetVersionNumber() + " (" + + version_info::GetLastChange() + ")" + version_modifier; +} + +std::string GetTimeStr(base::Time time, const std::string& default_msg) { + std::string time_str; + if (time.is_null()) + time_str = default_msg; + else + time_str = syncer::GetTimeDebugString(time); + return time_str; +} + +std::string GetConnectionStatus( + const sync_driver::SyncService::SyncTokenStatus& status) { + std::string message; + switch (status.connection_status) { + case syncer::CONNECTION_NOT_ATTEMPTED: + base::StringAppendF(&message, "not attempted"); + break; + case syncer::CONNECTION_OK: + base::StringAppendF( + &message, "OK since %s", + GetTimeStr(status.connection_status_update_time, "n/a").c_str()); + break; + case syncer::CONNECTION_AUTH_ERROR: + base::StringAppendF( + &message, "auth error since %s", + GetTimeStr(status.connection_status_update_time, "n/a").c_str()); + break; + case syncer::CONNECTION_SERVER_ERROR: + base::StringAppendF( + &message, "server error since %s", + GetTimeStr(status.connection_status_update_time, "n/a").c_str()); + break; + default: + NOTREACHED(); + } + return message; +} + +} // namespace + +// This function both defines the structure of the message to be returned and +// its contents. Most of the message consists of simple fields in about:sync +// which are grouped into sections and populated with the help of the SyncStat +// classes defined above. +std::unique_ptr<base::DictionaryValue> ConstructAboutInformation( + sync_driver::SyncService* service, + SigninManagerBase* signin, + version_info::Channel channel) { + std::unique_ptr<base::DictionaryValue> about_info( + new base::DictionaryValue()); + + // 'details': A list of sections. + base::ListValue* stats_list = new base::ListValue(); + + // The following lines define the sections and their fields. For each field, + // a class is instantiated, which allows us to reference the fields in + // 'setter' code later on in this function. + base::ListValue* section_summary = AddSection(stats_list, "Summary"); + StringSyncStat summary_string(section_summary, "Summary"); + + base::ListValue* section_version = AddSection(stats_list, "Version Info"); + StringSyncStat client_version(section_version, "Client Version"); + StringSyncStat server_url(section_version, "Server URL"); + + base::ListValue* section_identity = + AddSensitiveSection(stats_list, kIdentityTitle); + StringSyncStat sync_id(section_identity, "Sync Client ID"); + StringSyncStat invalidator_id(section_identity, "Invalidator Client ID"); + StringSyncStat username(section_identity, "Username"); + + base::ListValue* section_credentials = AddSection(stats_list, "Credentials"); + StringSyncStat request_token_time(section_credentials, "Requested Token"); + StringSyncStat receive_token_time(section_credentials, "Received Token"); + StringSyncStat token_request_status(section_credentials, + "Token Request Status"); + StringSyncStat next_token_request(section_credentials, "Next Token Request"); + + base::ListValue* section_local = AddSection(stats_list, "Local State"); + StringSyncStat server_connection(section_local, "Server Connection"); + StringSyncStat last_synced(section_local, "Last Synced"); + BoolSyncStat is_setup_complete(section_local, + "Sync First-Time Setup Complete"); + StringSyncStat backend_initialization(section_local, + "Sync Backend Initialization"); + BoolSyncStat is_syncing(section_local, "Syncing"); + + base::ListValue* section_network = AddSection(stats_list, "Network"); + BoolSyncStat is_throttled(section_network, "Throttled"); + StringSyncStat retry_time(section_network, "Retry time (maybe stale)"); + BoolSyncStat are_notifications_enabled(section_network, + "Notifications Enabled"); + + base::ListValue* section_encryption = AddSection(stats_list, "Encryption"); + BoolSyncStat is_using_explicit_passphrase(section_encryption, + "Explicit Passphrase"); + BoolSyncStat is_passphrase_required(section_encryption, + "Passphrase Required"); + BoolSyncStat is_cryptographer_ready(section_encryption, + "Cryptographer Ready"); + BoolSyncStat has_pending_keys(section_encryption, + "Cryptographer Has Pending Keys"); + StringSyncStat encrypted_types(section_encryption, "Encrypted Types"); + BoolSyncStat has_keystore_key(section_encryption, "Has Keystore Key"); + StringSyncStat keystore_migration_time(section_encryption, + "Keystore Migration Time"); + StringSyncStat passphrase_type(section_encryption, "Passphrase Type"); + StringSyncStat passphrase_time(section_encryption, "Passphrase Time"); + + base::ListValue* section_last_session = + AddSection(stats_list, "Status from Last Completed Session"); + StringSyncStat session_source(section_last_session, "Sync Source"); + StringSyncStat get_key_result(section_last_session, "GetKey Step Result"); + StringSyncStat download_result(section_last_session, "Download Step Result"); + StringSyncStat commit_result(section_last_session, "Commit Step Result"); + + base::ListValue* section_counters = AddSection(stats_list, "Running Totals"); + IntSyncStat notifications_received(section_counters, + "Notifications Received"); + IntSyncStat updates_received(section_counters, "Updates Downloaded"); + IntSyncStat tombstone_updates(section_counters, "Tombstone Updates"); + IntSyncStat reflected_updates(section_counters, "Reflected Updates"); + IntSyncStat successful_commits(section_counters, "Successful Commits"); + IntSyncStat conflicts_resolved_local_wins(section_counters, + "Conflicts Resolved: Client Wins"); + IntSyncStat conflicts_resolved_server_wins(section_counters, + "Conflicts Resolved: Server Wins"); + + base::ListValue* section_this_cycle = + AddSection(stats_list, "Transient Counters (this cycle)"); + IntSyncStat encryption_conflicts(section_this_cycle, "Encryption Conflicts"); + IntSyncStat hierarchy_conflicts(section_this_cycle, "Hierarchy Conflicts"); + IntSyncStat server_conflicts(section_this_cycle, "Server Conflicts"); + IntSyncStat committed_items(section_this_cycle, "Committed Items"); + + base::ListValue* section_that_cycle = AddSection( + stats_list, "Transient Counters (last cycle of last completed session)"); + IntSyncStat updates_downloaded(section_that_cycle, "Updates Downloaded"); + IntSyncStat committed_count(section_that_cycle, "Committed Count"); + IntSyncStat entries(section_that_cycle, "Entries"); + + base::ListValue* section_nudge_info = + AddSection(stats_list, "Nudge Source Counters"); + IntSyncStat nudge_source_notification(section_nudge_info, + "Server Invalidations"); + IntSyncStat nudge_source_local(section_nudge_info, "Local Changes"); + IntSyncStat nudge_source_local_refresh(section_nudge_info, "Local Refreshes"); + + // This list of sections belongs in the 'details' field of the returned + // message. + about_info->Set(kDetailsKey, stats_list); + + // Populate all the fields we declared above. + client_version.SetValue(GetVersionString(channel)); + + if (!service) { + summary_string.SetValue("Sync service does not exist"); + return about_info; + } + + syncer::SyncStatus full_status; + bool is_status_valid = service->QueryDetailedSyncStatus(&full_status); + bool sync_active = service->IsSyncActive(); + const syncer::sessions::SyncSessionSnapshot& snapshot = + service->GetLastSessionSnapshot(); + + if (is_status_valid) + summary_string.SetValue(service->QuerySyncStatusSummaryString()); + + server_url.SetValue(service->sync_service_url().spec()); + + if (is_status_valid && !full_status.sync_id.empty()) + sync_id.SetValue(full_status.sync_id); + if (is_status_valid && !full_status.invalidator_client_id.empty()) + invalidator_id.SetValue(full_status.invalidator_client_id); + if (signin) + username.SetValue(signin->GetAuthenticatedAccountInfo().email); + + const sync_driver::SyncService::SyncTokenStatus& token_status = + service->GetSyncTokenStatus(); + server_connection.SetValue(GetConnectionStatus(token_status)); + request_token_time.SetValue( + GetTimeStr(token_status.token_request_time, "n/a")); + receive_token_time.SetValue( + GetTimeStr(token_status.token_receive_time, "n/a")); + std::string err = token_status.last_get_token_error.error_message(); + token_request_status.SetValue(err.empty() ? "OK" : err); + next_token_request.SetValue( + GetTimeStr(token_status.next_token_request_time, "not scheduled")); + + last_synced.SetValue(service->GetLastSyncedTimeString()); + is_setup_complete.SetValue(service->IsFirstSetupComplete()); + backend_initialization.SetValue( + service->GetBackendInitializationStateString()); + if (is_status_valid) { + is_syncing.SetValue(full_status.syncing); + retry_time.SetValue(GetTimeStr(full_status.retry_time, + "Scheduler is not in backoff or throttled")); + } + + if (snapshot.is_initialized()) + is_throttled.SetValue(snapshot.is_silenced()); + if (is_status_valid) { + are_notifications_enabled.SetValue(full_status.notifications_enabled); + } + + if (sync_active) { + is_using_explicit_passphrase.SetValue( + service->IsUsingSecondaryPassphrase()); + is_passphrase_required.SetValue(service->IsPassphraseRequired()); + passphrase_time.SetValue( + GetTimeStr(service->GetExplicitPassphraseTime(), "No Passphrase Time")); + } + if (is_status_valid) { + is_cryptographer_ready.SetValue(full_status.cryptographer_ready); + has_pending_keys.SetValue(full_status.crypto_has_pending_keys); + encrypted_types.SetValue(ModelTypeSetToString(full_status.encrypted_types)); + has_keystore_key.SetValue(full_status.has_keystore_key); + keystore_migration_time.SetValue( + GetTimeStr(full_status.keystore_migration_time, "Not Migrated")); + passphrase_type.SetValue( + PassphraseTypeToString(full_status.passphrase_type)); + } + + if (snapshot.is_initialized()) { + if (snapshot.legacy_updates_source() != + sync_pb::GetUpdatesCallerInfo::UNKNOWN) { + session_source.SetValue( + syncer::GetUpdatesSourceString(snapshot.legacy_updates_source())); + } + get_key_result.SetValue(GetSyncerErrorString( + snapshot.model_neutral_state().last_get_key_result)); + download_result.SetValue(GetSyncerErrorString( + snapshot.model_neutral_state().last_download_updates_result)); + commit_result.SetValue( + GetSyncerErrorString(snapshot.model_neutral_state().commit_result)); + } + + if (is_status_valid) { + notifications_received.SetValue(full_status.notifications_received); + updates_received.SetValue(full_status.updates_received); + tombstone_updates.SetValue(full_status.tombstone_updates_received); + reflected_updates.SetValue(full_status.reflected_updates_received); + successful_commits.SetValue(full_status.num_commits_total); + conflicts_resolved_local_wins.SetValue( + full_status.num_local_overwrites_total); + conflicts_resolved_server_wins.SetValue( + full_status.num_server_overwrites_total); + } + + if (is_status_valid) { + encryption_conflicts.SetValue(full_status.encryption_conflicts); + hierarchy_conflicts.SetValue(full_status.hierarchy_conflicts); + server_conflicts.SetValue(full_status.server_conflicts); + committed_items.SetValue(full_status.committed_count); + } + + if (is_status_valid) { + nudge_source_notification.SetValue(full_status.nudge_source_notification); + nudge_source_local.SetValue(full_status.nudge_source_local); + nudge_source_local_refresh.SetValue(full_status.nudge_source_local_refresh); + } + + if (snapshot.is_initialized()) { + updates_downloaded.SetValue( + snapshot.model_neutral_state().num_updates_downloaded_total); + committed_count.SetValue( + snapshot.model_neutral_state().num_successful_commits); + entries.SetValue(snapshot.num_entries()); + } + + // The values set from this point onwards do not belong in the + // details list. + + // We don't need to check is_status_valid here. + // full_status.sync_protocol_error is exported directly from the + // ProfileSyncService, even if the backend doesn't exist. + const bool actionable_error_detected = + full_status.sync_protocol_error.error_type != syncer::UNKNOWN_ERROR && + full_status.sync_protocol_error.error_type != syncer::SYNC_SUCCESS; + + about_info->SetBoolean("actionable_error_detected", + actionable_error_detected); + + // NOTE: We won't bother showing any of the following values unless + // actionable_error_detected is set. + + base::ListValue* actionable_error = new base::ListValue(); + about_info->Set("actionable_error", actionable_error); + + StringSyncStat error_type(actionable_error, "Error Type"); + StringSyncStat action(actionable_error, "Action"); + StringSyncStat url(actionable_error, "URL"); + StringSyncStat description(actionable_error, "Error Description"); + + if (actionable_error_detected) { + error_type.SetValue(syncer::GetSyncErrorTypeString( + full_status.sync_protocol_error.error_type)); + action.SetValue( + syncer::GetClientActionString(full_status.sync_protocol_error.action)); + url.SetValue(full_status.sync_protocol_error.url); + description.SetValue(full_status.sync_protocol_error.error_description); + } + + about_info->SetBoolean("unrecoverable_error_detected", + service->HasUnrecoverableError()); + + if (service->HasUnrecoverableError()) { + tracked_objects::Location loc(service->unrecoverable_error_location()); + std::string location_str; + loc.Write(true, true, &location_str); + std::string unrecoverable_error_message = + "Unrecoverable error detected at " + location_str + ": " + + service->unrecoverable_error_message(); + about_info->SetString("unrecoverable_error_message", + unrecoverable_error_message); + } + + about_info->Set("type_status", service->GetTypeStatusMap()); + + return about_info; +} + +} // namespace sync_ui_util + +} // namespace sync_driver
diff --git a/components/sync_driver/about_sync_util.h b/components/sync/driver/about_sync_util.h similarity index 100% rename from components/sync_driver/about_sync_util.h rename to components/sync/driver/about_sync_util.h
diff --git a/components/sync/driver/about_sync_util_unittest.cc b/components/sync/driver/about_sync_util_unittest.cc new file mode 100644 index 0000000..37bfd05 --- /dev/null +++ b/components/sync/driver/about_sync_util_unittest.cc
@@ -0,0 +1,53 @@ +// 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/sync/driver/about_sync_util.h" + +#include "base/strings/utf_string_conversions.h" +#include "components/sync/driver/fake_sync_service.h" +#include "components/sync/engine/sync_status.h" +#include "components/version_info/version_info.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::NiceMock; +using ::testing::Return; +using ::testing::_; + +namespace sync_driver { +namespace sync_ui_util { +namespace { + +class SyncServiceMock : public sync_driver::FakeSyncService { + public: + bool IsFirstSetupComplete() const override { return true; } + + bool HasUnrecoverableError() const override { return true; } + + bool QueryDetailedSyncStatus(syncer::SyncStatus* result) override { + return false; + } + + base::string16 GetLastSyncedTimeString() const override { + return base::string16(base::ASCIIToUTF16("none")); + } + + syncer::sessions::SyncSessionSnapshot GetLastSessionSnapshot() + const override { + return syncer::sessions::SyncSessionSnapshot(); + } +}; + +TEST(SyncUIUtilTestAbout, ConstructAboutInformationWithUnrecoverableErrorTest) { + SyncServiceMock service; + + std::unique_ptr<base::DictionaryValue> strings(ConstructAboutInformation( + &service, NULL, version_info::Channel::UNKNOWN)); + + EXPECT_TRUE(strings->HasKey("unrecoverable_error_detected")); +} + +} // namespace +} // namespace sync_ui_util +} // namespace sync_driver
diff --git a/components/sync/driver/backend_data_type_configurer.cc b/components/sync/driver/backend_data_type_configurer.cc new file mode 100644 index 0000000..e6d1637 --- /dev/null +++ b/components/sync/driver/backend_data_type_configurer.cc
@@ -0,0 +1,32 @@ +// 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 "components/sync/driver/backend_data_type_configurer.h" + +namespace sync_driver { + +// static +syncer::ModelTypeSet BackendDataTypeConfigurer::GetDataTypesInState( + DataTypeConfigState state, + const DataTypeConfigStateMap& state_map) { + syncer::ModelTypeSet types; + for (DataTypeConfigStateMap::const_iterator type_it = state_map.begin(); + type_it != state_map.end(); ++type_it) { + if (type_it->second == state) + types.Put(type_it->first); + } + return types; +} + +// static +void BackendDataTypeConfigurer::SetDataTypesState( + DataTypeConfigState state, + syncer::ModelTypeSet types, + DataTypeConfigStateMap* state_map) { + for (syncer::ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) { + (*state_map)[it.Get()] = state; + } +} + +} // namespace sync_driver
diff --git a/components/sync/driver/backend_data_type_configurer.h b/components/sync/driver/backend_data_type_configurer.h new file mode 100644 index 0000000..01c08796 --- /dev/null +++ b/components/sync/driver/backend_data_type_configurer.h
@@ -0,0 +1,101 @@ +// 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 COMPONENTS_SYNC_DRIVER_BACKEND_DATA_TYPE_CONFIGURER_H_ +#define COMPONENTS_SYNC_DRIVER_BACKEND_DATA_TYPE_CONFIGURER_H_ + +#include <map> +#include <memory> + +#include "base/callback.h" +#include "components/sync/base/model_type.h" +#include "components/sync/core/configure_reason.h" +#include "components/sync/engine/model_safe_worker.h" + +namespace syncer_v2 { +struct ActivationContext; +} + +namespace sync_driver { + +class ChangeProcessor; + +// The DataTypeConfigurer interface abstracts out the action of +// configuring a set of new data types and cleaning up after a set of +// removed data types. +class BackendDataTypeConfigurer { + public: + enum DataTypeConfigState { + CONFIGURE_ACTIVE, // Actively being configured. Data of such types + // will be downloaded if not present locally. + CONFIGURE_INACTIVE, // Already configured or to be configured in future. + // Data of such types is left as it is, no + // downloading or purging. + CONFIGURE_CLEAN, // Actively being configured but requiring unapply + // and GetUpdates first (e.g. for persistence errors). + DISABLED, // Not syncing. Disabled by user. + FATAL, // Not syncing due to unrecoverable error. + CRYPTO, // Not syncing due to a cryptographer error. + UNREADY, // Not syncing due to transient error. + }; + typedef std::map<syncer::ModelType, DataTypeConfigState> + DataTypeConfigStateMap; + + // Configures sync for data types in config_state_map according to the states. + // |ready_task| is called on the same thread as ConfigureDataTypes + // is called when configuration is done with the set of data types + // that succeeded/failed configuration (i.e., configuration succeeded iff + // the failed set is empty). + // Returns: the set of types that are already configured and are ready to + // start. + // + // TODO(akalin): Use a Delegate class with + // OnConfigureSuccess/OnConfigureFailure/OnConfigureRetry instead of + // a pair of callbacks. The awkward part is handling when + // SyncBackendHost calls ConfigureDataTypes on itself to configure + // Nigori. + virtual syncer::ModelTypeSet ConfigureDataTypes( + syncer::ConfigureReason reason, + const DataTypeConfigStateMap& config_state_map, + const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& + ready_task, + const base::Callback<void()>& retry_callback) = 0; + + // Return model types in |state_map| that match |state|. + static syncer::ModelTypeSet GetDataTypesInState( + DataTypeConfigState state, + const DataTypeConfigStateMap& state_map); + + // Activates change processing for the given directory data type. This must + // be called synchronously with the data type's model association so + // no changes are dropped between model association and change + // processor activation. + virtual void ActivateDirectoryDataType(syncer::ModelType type, + syncer::ModelSafeGroup group, + ChangeProcessor* change_processor) = 0; + + // Deactivates change processing for the given data type. + virtual void DeactivateDirectoryDataType(syncer::ModelType type) = 0; + + // Activates change processing for the given non-blocking data type. + // This must be called before initial sync for data type. + virtual void ActivateNonBlockingDataType( + syncer::ModelType type, + std::unique_ptr<syncer_v2::ActivationContext> activation_context) = 0; + + // Deactivates change processing for the given non-blocking data type. + virtual void DeactivateNonBlockingDataType(syncer::ModelType type) = 0; + + // Set state of |types| in |state_map| to |state|. + static void SetDataTypesState(DataTypeConfigState state, + syncer::ModelTypeSet types, + DataTypeConfigStateMap* state_map); + + protected: + virtual ~BackendDataTypeConfigurer() {} +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_BACKEND_DATA_TYPE_CONFIGURER_H_
diff --git a/components/sync/driver/backend_migrator.cc b/components/sync/driver/backend_migrator.cc new file mode 100644 index 0000000..9b95781 --- /dev/null +++ b/components/sync/driver/backend_migrator.cc
@@ -0,0 +1,224 @@ +// 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/sync/driver/backend_migrator.h" + +#include "base/location.h" +#include "base/single_thread_task_runner.h" +#include "base/strings/string_number_conversions.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/tracked_objects.h" +#include "components/sync/core/configure_reason.h" +#include "components/sync/core/read_transaction.h" +#include "components/sync/driver/sync_service.h" +#include "components/sync/protocol/sync.pb.h" +#include "components/sync/syncable/directory.h" // TODO(tim): Bug 131130. + +using syncer::ModelTypeSet; + +namespace browser_sync { + +using syncer::ModelTypeToString; + +MigrationObserver::~MigrationObserver() {} + +BackendMigrator::BackendMigrator(const std::string& name, + syncer::UserShare* user_share, + sync_driver::SyncService* service, + sync_driver::DataTypeManager* manager, + const base::Closure& migration_done_callback) + : name_(name), + user_share_(user_share), + service_(service), + manager_(manager), + state_(IDLE), + migration_done_callback_(migration_done_callback), + weak_ptr_factory_(this) {} + +BackendMigrator::~BackendMigrator() {} + +// Helper macros to log with the syncer thread name; useful when there +// are multiple syncer threads involved. + +#define SLOG(severity) LOG(severity) << name_ << ": " + +#define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": " + +void BackendMigrator::MigrateTypes(syncer::ModelTypeSet types) { + const ModelTypeSet old_to_migrate = to_migrate_; + to_migrate_.PutAll(types); + SDVLOG(1) << "MigrateTypes called with " << ModelTypeSetToString(types) + << ", old_to_migrate = " << ModelTypeSetToString(old_to_migrate) + << ", to_migrate_ = " << ModelTypeSetToString(to_migrate_); + if (old_to_migrate == to_migrate_) { + SDVLOG(1) << "MigrateTypes called with no new types; ignoring"; + return; + } + + if (state_ == IDLE) + ChangeState(WAITING_TO_START); + + if (state_ == WAITING_TO_START) { + if (!TryStart()) + SDVLOG(1) << "Manager not configured; waiting"; + return; + } + + DCHECK_GT(state_, WAITING_TO_START); + // If we're already migrating, interrupt the current migration. + RestartMigration(); +} + +void BackendMigrator::AddMigrationObserver(MigrationObserver* observer) { + migration_observers_.AddObserver(observer); +} + +bool BackendMigrator::HasMigrationObserver( + const MigrationObserver* observer) const { + return migration_observers_.HasObserver(observer); +} + +void BackendMigrator::RemoveMigrationObserver(MigrationObserver* observer) { + migration_observers_.RemoveObserver(observer); +} + +void BackendMigrator::ChangeState(State new_state) { + state_ = new_state; + FOR_EACH_OBSERVER(MigrationObserver, migration_observers_, + OnMigrationStateChange()); +} + +bool BackendMigrator::TryStart() { + DCHECK_EQ(state_, WAITING_TO_START); + if (manager_->state() == sync_driver::DataTypeManager::CONFIGURED) { + RestartMigration(); + return true; + } + return false; +} + +void BackendMigrator::RestartMigration() { + // We'll now disable any running types that need to be migrated. + ChangeState(DISABLING_TYPES); + SDVLOG(1) << "BackendMigrator disabling types " + << ModelTypeSetToString(to_migrate_); + + manager_->PurgeForMigration(to_migrate_, syncer::CONFIGURE_REASON_MIGRATION); +} + +void BackendMigrator::OnConfigureDone( + const sync_driver::DataTypeManager::ConfigureResult& result) { + if (state_ == IDLE) + return; + + // |manager_|'s methods aren't re-entrant, and we're notified from + // them, so post a task to avoid problems. + SDVLOG(1) << "Posting OnConfigureDoneImpl"; + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(&BackendMigrator::OnConfigureDoneImpl, + weak_ptr_factory_.GetWeakPtr(), result)); +} + +namespace { + +syncer::ModelTypeSet GetUnsyncedDataTypes(syncer::UserShare* user_share) { + syncer::ReadTransaction trans(FROM_HERE, user_share); + syncer::ModelTypeSet unsynced_data_types; + for (int i = syncer::FIRST_REAL_MODEL_TYPE; i < syncer::MODEL_TYPE_COUNT; + ++i) { + syncer::ModelType type = syncer::ModelTypeFromInt(i); + sync_pb::DataTypeProgressMarker progress_marker; + trans.GetDirectory()->GetDownloadProgress(type, &progress_marker); + if (progress_marker.token().empty()) { + unsynced_data_types.Put(type); + } + } + return unsynced_data_types; +} + +} // namespace + +void BackendMigrator::OnConfigureDoneImpl( + const sync_driver::DataTypeManager::ConfigureResult& result) { + SDVLOG(1) << "OnConfigureDone with requested types " + << ModelTypeSetToString(result.requested_types) << ", status " + << result.status + << ", and to_migrate_ = " << ModelTypeSetToString(to_migrate_); + if (state_ == WAITING_TO_START) { + if (!TryStart()) + SDVLOG(1) << "Manager still not configured; still waiting"; + return; + } + + DCHECK_GT(state_, WAITING_TO_START); + + const ModelTypeSet intersection = + Intersection(result.requested_types, to_migrate_); + // This intersection check is to determine if our disable request + // was interrupted by a user changing preferred types. + if (state_ == DISABLING_TYPES && !intersection.Empty()) { + SDVLOG(1) << "Disable request interrupted by user changing types"; + RestartMigration(); + return; + } + + if (result.status != sync_driver::DataTypeManager::OK) { + // If this fails, and we're disabling types, a type may or may not be + // disabled until the user restarts the browser. If this wasn't an abort, + // any failure will be reported as an unrecoverable error to the UI. If it + // was an abort, then typically things are shutting down anyway. There isn't + // much we can do in any case besides wait until a restart to try again. + // The server will send down MIGRATION_DONE again for types needing + // migration as the type will still be enabled on restart. + SLOG(WARNING) << "Unable to migrate, configuration failed!"; + ChangeState(IDLE); + to_migrate_.Clear(); + return; + } + + if (state_ == DISABLING_TYPES) { + const syncer::ModelTypeSet unsynced_types = + GetUnsyncedDataTypes(user_share_); + if (!unsynced_types.HasAll(to_migrate_)) { + SLOG(WARNING) << "Set of unsynced types: " + << syncer::ModelTypeSetToString(unsynced_types) + << " does not contain types to migrate: " + << syncer::ModelTypeSetToString(to_migrate_) + << "; not re-enabling yet"; + return; + } + + ChangeState(REENABLING_TYPES); + // Don't use |to_migrate_| for the re-enabling because the user + // may have chosen to disable types during the migration. + const ModelTypeSet full_set = service_->GetPreferredDataTypes(); + SDVLOG(1) << "BackendMigrator re-enabling types: " + << syncer::ModelTypeSetToString(full_set); + manager_->Configure(full_set, syncer::CONFIGURE_REASON_MIGRATION); + } else if (state_ == REENABLING_TYPES) { + // We're done! + ChangeState(IDLE); + + SDVLOG(1) << "BackendMigrator: Migration complete for: " + << syncer::ModelTypeSetToString(to_migrate_); + to_migrate_.Clear(); + + if (!migration_done_callback_.is_null()) + migration_done_callback_.Run(); + } +} + +BackendMigrator::State BackendMigrator::state() const { + return state_; +} + +syncer::ModelTypeSet BackendMigrator::GetPendingMigrationTypesForTest() const { + return to_migrate_; +} + +#undef SDVLOG + +#undef SLOG + +}; // namespace browser_sync
diff --git a/components/sync/driver/backend_migrator.h b/components/sync/driver/backend_migrator.h new file mode 100644 index 0000000..38a03be --- /dev/null +++ b/components/sync/driver/backend_migrator.h
@@ -0,0 +1,113 @@ +// 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 COMPONENTS_SYNC_DRIVER_BACKEND_MIGRATOR_H_ +#define COMPONENTS_SYNC_DRIVER_BACKEND_MIGRATOR_H_ + +#include <string> + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "components/sync/base/model_type.h" +#include "components/sync/driver/data_type_manager.h" + +namespace syncer { +struct UserShare; +} // namespace syncer + +namespace sync_driver { +class SyncService; +} + +namespace browser_sync { + +// Interface for anything that wants to know when the migrator's state +// changes. +class MigrationObserver { + public: + virtual void OnMigrationStateChange() = 0; + + protected: + virtual ~MigrationObserver(); +}; + +// A class to perform migration of a datatype pursuant to the 'MIGRATION_DONE' +// code in the sync protocol definition (protocol/sync.proto). +class BackendMigrator { + public: + enum State { + IDLE, + WAITING_TO_START, // Waiting for previous configuration to finish. + DISABLING_TYPES, // Exit criteria: SYNC_CONFIGURE_DONE for + // enabled types _excluding_ |to_migrate_| and + // empty download progress markers for types + // in |to_migrate_|. + REENABLING_TYPES, // Exit criteria: SYNC_CONFIGURE_DONE for enabled + // types. + }; + + // TODO(akalin): Remove the dependency on |user_share|. + BackendMigrator(const std::string& name, + syncer::UserShare* user_share, + sync_driver::SyncService* service, + sync_driver::DataTypeManager* manager, + const base::Closure& migration_done_callback); + virtual ~BackendMigrator(); + + // Starts a sequence of events that will disable and reenable |types|. + void MigrateTypes(syncer::ModelTypeSet types); + + void AddMigrationObserver(MigrationObserver* observer); + bool HasMigrationObserver(const MigrationObserver* observer) const; + void RemoveMigrationObserver(MigrationObserver* observer); + + State state() const; + + // Called from ProfileSyncService to notify us of configure done. + // Note: We receive these notificiations only when our state is not IDLE. + void OnConfigureDone( + const sync_driver::DataTypeManager::ConfigureResult& result); + + // Returns the types that are currently pending migration (if any). + syncer::ModelTypeSet GetPendingMigrationTypesForTest() const; + + private: + void ChangeState(State new_state); + + // Must be called only in state WAITING_TO_START. If ready to + // start, meaning the data type manager is configured, calls + // RestartMigration() and returns true. Otherwise, does nothing and + // returns false. + bool TryStart(); + + // Restarts migration, interrupting any existing migration. + void RestartMigration(); + + // Called by OnConfigureDone(). + void OnConfigureDoneImpl( + const sync_driver::DataTypeManager::ConfigureResult& result); + + const std::string name_; + syncer::UserShare* user_share_; + sync_driver::SyncService* service_; + sync_driver::DataTypeManager* manager_; + + State state_; + + base::ObserverList<MigrationObserver> migration_observers_; + + syncer::ModelTypeSet to_migrate_; + + base::Closure migration_done_callback_; + + base::WeakPtrFactory<BackendMigrator> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(BackendMigrator); +}; + +} // namespace browser_sync + +#endif // COMPONENTS_SYNC_DRIVER_BACKEND_MIGRATOR_H_
diff --git a/components/sync/driver/backend_migrator_unittest.cc b/components/sync/driver/backend_migrator_unittest.cc new file mode 100644 index 0000000..ea6f700 --- /dev/null +++ b/components/sync/driver/backend_migrator_unittest.cc
@@ -0,0 +1,326 @@ +// 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/sync/driver/backend_migrator.h" + +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/tracked_objects.h" +#include "components/sync/base/model_type_test_util.h" +#include "components/sync/core/test/test_user_share.h" +#include "components/sync/core/write_transaction.h" +#include "components/sync/driver/data_type_manager_mock.h" +#include "components/sync/driver/fake_sync_service.h" +#include "components/sync/protocol/sync.pb.h" +#include "components/sync/syncable/directory.h" // TODO(tim): Remove. Bug 131130. +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::_; +using ::testing::Eq; +using ::testing::Mock; +using ::testing::NiceMock; +using ::testing::Return; +using sync_driver::DataTypeManager; +using sync_driver::DataTypeManagerMock; + +namespace browser_sync { + +using syncer::sessions::SyncSessionSnapshot; + +class SyncBackendMigratorTest : public testing::Test { + public: + SyncBackendMigratorTest() {} + virtual ~SyncBackendMigratorTest() {} + + virtual void SetUp() { + test_user_share_.SetUp(); + Mock::VerifyAndClear(manager()); + preferred_types_.Put(syncer::BOOKMARKS); + preferred_types_.Put(syncer::PREFERENCES); + preferred_types_.Put(syncer::AUTOFILL); + + migrator_.reset(new BackendMigrator("Profile0", + test_user_share_.user_share(), + service(), manager(), base::Closure())); + SetUnsyncedTypes(syncer::ModelTypeSet()); + } + + virtual void TearDown() { + migrator_.reset(); + test_user_share_.TearDown(); + } + + // Marks all types in |unsynced_types| as unsynced and all other + // types as synced. + void SetUnsyncedTypes(syncer::ModelTypeSet unsynced_types) { + syncer::WriteTransaction trans(FROM_HERE, test_user_share_.user_share()); + for (int i = syncer::FIRST_REAL_MODEL_TYPE; i < syncer::MODEL_TYPE_COUNT; + ++i) { + syncer::ModelType type = syncer::ModelTypeFromInt(i); + sync_pb::DataTypeProgressMarker progress_marker; + if (!unsynced_types.Has(type)) { + progress_marker.set_token("dummy"); + } + trans.GetDirectory()->SetDownloadProgress(type, progress_marker); + } + } + + void SendConfigureDone(DataTypeManager::ConfigureStatus status, + syncer::ModelTypeSet requested_types) { + if (status == DataTypeManager::OK) { + DataTypeManager::ConfigureResult result(status, requested_types); + migrator_->OnConfigureDone(result); + } else { + DataTypeManager::ConfigureResult result(status, requested_types); + migrator_->OnConfigureDone(result); + } + base::RunLoop run_loop; + run_loop.RunUntilIdle(); + } + + sync_driver::SyncService* service() { return &service_; } + DataTypeManagerMock* manager() { return &manager_; } + syncer::ModelTypeSet preferred_types() { return preferred_types_; } + BackendMigrator* migrator() { return migrator_.get(); } + void RemovePreferredType(syncer::ModelType type) { + preferred_types_.Remove(type); + } + + private: + base::MessageLoop message_loop_; + syncer::ModelTypeSet preferred_types_; + sync_driver::FakeSyncService service_; + NiceMock<DataTypeManagerMock> manager_; + syncer::TestUserShare test_user_share_; + std::unique_ptr<BackendMigrator> migrator_; +}; + +class MockMigrationObserver : public MigrationObserver { + public: + virtual ~MockMigrationObserver() {} + + MOCK_METHOD0(OnMigrationStateChange, void()); +}; + +// Test that in the normal case a migration does transition through each state +// and wind up back in IDLE. +TEST_F(SyncBackendMigratorTest, Sanity) { + MockMigrationObserver migration_observer; + migrator()->AddMigrationObserver(&migration_observer); + EXPECT_CALL(migration_observer, OnMigrationStateChange()).Times(4); + + syncer::ModelTypeSet to_migrate, difference; + to_migrate.Put(syncer::PREFERENCES); + difference.Put(syncer::AUTOFILL); + difference.Put(syncer::BOOKMARKS); + + EXPECT_CALL(*manager(), state()) + .WillOnce(Return(DataTypeManager::CONFIGURED)); + EXPECT_CALL(*manager(), + PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)) + .Times(1); + EXPECT_CALL(*manager(), Configure(_, syncer::CONFIGURE_REASON_MIGRATION)) + .Times(1); + + migrator()->MigrateTypes(to_migrate); + EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state()); + + SetUnsyncedTypes(to_migrate); + SendConfigureDone(DataTypeManager::OK, difference); + EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state()); + + SetUnsyncedTypes(syncer::ModelTypeSet()); + SendConfigureDone(DataTypeManager::OK, preferred_types()); + EXPECT_EQ(BackendMigrator::IDLE, migrator()->state()); + + migrator()->RemoveMigrationObserver(&migration_observer); +} + +// Test that in the normal case with Nigori a migration transitions through +// each state and wind up back in IDLE. +TEST_F(SyncBackendMigratorTest, MigrateNigori) { + syncer::ModelTypeSet to_migrate, difference; + to_migrate.Put(syncer::NIGORI); + difference.Put(syncer::AUTOFILL); + difference.Put(syncer::BOOKMARKS); + + EXPECT_CALL(*manager(), state()) + .WillOnce(Return(DataTypeManager::CONFIGURED)); + + EXPECT_CALL(*manager(), + PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)); + + migrator()->MigrateTypes(to_migrate); + EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state()); + + SetUnsyncedTypes(to_migrate); + SendConfigureDone(DataTypeManager::OK, difference); + EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state()); + + SetUnsyncedTypes(syncer::ModelTypeSet()); + SendConfigureDone(DataTypeManager::OK, preferred_types()); + EXPECT_EQ(BackendMigrator::IDLE, migrator()->state()); +} + +// Test that the migrator waits for the data type manager to be idle before +// starting a migration. +TEST_F(SyncBackendMigratorTest, WaitToStart) { + syncer::ModelTypeSet to_migrate; + to_migrate.Put(syncer::PREFERENCES); + + EXPECT_CALL(*manager(), state()) + .WillOnce(Return(DataTypeManager::CONFIGURING)); + EXPECT_CALL(*manager(), Configure(_, _)).Times(0); + migrator()->MigrateTypes(to_migrate); + EXPECT_EQ(BackendMigrator::WAITING_TO_START, migrator()->state()); + + Mock::VerifyAndClearExpectations(manager()); + EXPECT_CALL(*manager(), state()) + .WillOnce(Return(DataTypeManager::CONFIGURED)); + EXPECT_CALL(*manager(), + PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)); + SetUnsyncedTypes(syncer::ModelTypeSet()); + SendConfigureDone(DataTypeManager::OK, syncer::ModelTypeSet()); + + EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state()); +} + +// Test that the migrator can cope with a migration request while a migration +// is in progress. +TEST_F(SyncBackendMigratorTest, RestartMigration) { + syncer::ModelTypeSet to_migrate1, to_migrate2, to_migrate_union, bookmarks; + to_migrate1.Put(syncer::PREFERENCES); + to_migrate2.Put(syncer::AUTOFILL); + to_migrate_union.Put(syncer::PREFERENCES); + to_migrate_union.Put(syncer::AUTOFILL); + bookmarks.Put(syncer::BOOKMARKS); + + EXPECT_CALL(*manager(), state()) + .WillOnce(Return(DataTypeManager::CONFIGURED)); + EXPECT_CALL(*manager(), + PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)) + .Times(2); + migrator()->MigrateTypes(to_migrate1); + + EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state()); + migrator()->MigrateTypes(to_migrate2); + + const syncer::ModelTypeSet difference1 = + Difference(preferred_types(), to_migrate1); + + Mock::VerifyAndClearExpectations(manager()); + EXPECT_CALL(*manager(), + PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)) + .Times(1); + EXPECT_CALL(*manager(), Configure(_, syncer::CONFIGURE_REASON_MIGRATION)) + .Times(1); + SetUnsyncedTypes(to_migrate1); + SendConfigureDone(DataTypeManager::OK, difference1); + EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state()); + + SetUnsyncedTypes(to_migrate_union); + SendConfigureDone(DataTypeManager::OK, bookmarks); + EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state()); +} + +// Test that an external invocation of Configure(...) during a migration results +// in a migration reattempt. +TEST_F(SyncBackendMigratorTest, InterruptedWhileDisablingTypes) { + syncer::ModelTypeSet to_migrate; + syncer::ModelTypeSet difference; + to_migrate.Put(syncer::PREFERENCES); + difference.Put(syncer::AUTOFILL); + difference.Put(syncer::BOOKMARKS); + + EXPECT_CALL(*manager(), state()) + .WillOnce(Return(DataTypeManager::CONFIGURED)); + EXPECT_CALL(*manager(), + PurgeForMigration(HasModelTypes(to_migrate), + syncer::CONFIGURE_REASON_MIGRATION)); + migrator()->MigrateTypes(to_migrate); + EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state()); + + Mock::VerifyAndClearExpectations(manager()); + EXPECT_CALL(*manager(), + PurgeForMigration(HasModelTypes(to_migrate), + syncer::CONFIGURE_REASON_MIGRATION)); + SetUnsyncedTypes(syncer::ModelTypeSet()); + SendConfigureDone(DataTypeManager::OK, preferred_types()); + + EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state()); +} + +// Test that spurious OnConfigureDone events don't confuse the +// migrator while it's waiting for disabled types to have been purged +// from the sync db. +TEST_F(SyncBackendMigratorTest, WaitingForPurge) { + syncer::ModelTypeSet to_migrate, difference; + to_migrate.Put(syncer::PREFERENCES); + to_migrate.Put(syncer::AUTOFILL); + difference.Put(syncer::BOOKMARKS); + + EXPECT_CALL(*manager(), state()) + .WillOnce(Return(DataTypeManager::CONFIGURED)); + EXPECT_CALL(*manager(), + PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)) + .Times(1); + EXPECT_CALL(*manager(), Configure(_, syncer::CONFIGURE_REASON_MIGRATION)) + .Times(1); + + migrator()->MigrateTypes(to_migrate); + EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state()); + + SendConfigureDone(DataTypeManager::OK, difference); + EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state()); + + syncer::ModelTypeSet prefs; + prefs.Put(syncer::PREFERENCES); + SetUnsyncedTypes(prefs); + SendConfigureDone(DataTypeManager::OK, difference); + EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state()); + + SetUnsyncedTypes(to_migrate); + SendConfigureDone(DataTypeManager::OK, difference); + EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state()); +} + +TEST_F(SyncBackendMigratorTest, MigratedTypeDisabledByUserDuringMigration) { + syncer::ModelTypeSet to_migrate; + to_migrate.Put(syncer::PREFERENCES); + + EXPECT_CALL(*manager(), state()) + .WillOnce(Return(DataTypeManager::CONFIGURED)); + EXPECT_CALL(*manager(), + PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)) + .Times(1); + EXPECT_CALL(*manager(), Configure(_, syncer::CONFIGURE_REASON_MIGRATION)) + .Times(1); + migrator()->MigrateTypes(to_migrate); + + RemovePreferredType(syncer::PREFERENCES); + SetUnsyncedTypes(to_migrate); + SendConfigureDone(DataTypeManager::OK, preferred_types()); + EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state()); + SetUnsyncedTypes(syncer::ModelTypeSet()); + SendConfigureDone(DataTypeManager::OK, preferred_types()); + EXPECT_EQ(BackendMigrator::IDLE, migrator()->state()); +} + +TEST_F(SyncBackendMigratorTest, ConfigureFailure) { + syncer::ModelTypeSet to_migrate; + to_migrate.Put(syncer::PREFERENCES); + + EXPECT_CALL(*manager(), state()) + .WillOnce(Return(DataTypeManager::CONFIGURED)); + EXPECT_CALL(*manager(), + PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)) + .Times(1); + migrator()->MigrateTypes(to_migrate); + SetUnsyncedTypes(syncer::ModelTypeSet()); + SendConfigureDone(DataTypeManager::ABORTED, syncer::ModelTypeSet()); + EXPECT_EQ(BackendMigrator::IDLE, migrator()->state()); +} + +}; // namespace browser_sync
diff --git a/components/sync/driver/change_processor.cc b/components/sync/driver/change_processor.cc new file mode 100644 index 0000000..c0d7915a --- /dev/null +++ b/components/sync/driver/change_processor.cc
@@ -0,0 +1,31 @@ +// 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 "components/sync/driver/change_processor.h" + +namespace sync_driver { + +ChangeProcessor::ChangeProcessor(syncer::DataTypeErrorHandler* error_handler) + : error_handler_(error_handler), share_handle_(NULL) {} + +ChangeProcessor::~ChangeProcessor() {} + +void ChangeProcessor::Start(syncer::UserShare* share_handle) { + DCHECK(!share_handle_); + share_handle_ = share_handle; + StartImpl(); +} + +// Not implemented by default. +void ChangeProcessor::CommitChangesFromSyncModel() {} + +syncer::DataTypeErrorHandler* ChangeProcessor::error_handler() const { + return error_handler_; +} + +syncer::UserShare* ChangeProcessor::share_handle() const { + return share_handle_; +} + +} // namespace sync_driver
diff --git a/components/sync_driver/change_processor.h b/components/sync/driver/change_processor.h similarity index 100% rename from components/sync_driver/change_processor.h rename to components/sync/driver/change_processor.h
diff --git a/components/sync/driver/change_processor_mock.cc b/components/sync/driver/change_processor_mock.cc new file mode 100644 index 0000000..e5000a6c --- /dev/null +++ b/components/sync/driver/change_processor_mock.cc
@@ -0,0 +1,15 @@ +// 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 "components/sync/driver/change_processor_mock.h" + +#include "base/compiler_specific.h" + +namespace sync_driver { + +ChangeProcessorMock::ChangeProcessorMock() : ChangeProcessor(this) {} + +ChangeProcessorMock::~ChangeProcessorMock() {} + +} // namespace sync_driver
diff --git a/components/sync/driver/change_processor_mock.h b/components/sync/driver/change_processor_mock.h new file mode 100644 index 0000000..14813a95 --- /dev/null +++ b/components/sync/driver/change_processor_mock.h
@@ -0,0 +1,44 @@ +// 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 COMPONENTS_SYNC_DRIVER_CHANGE_PROCESSOR_MOCK_H_ +#define COMPONENTS_SYNC_DRIVER_CHANGE_PROCESSOR_MOCK_H_ + +#include <stdint.h> + +#include <string> + +#include "components/sync/base/model_type.h" +#include "components/sync/base/unrecoverable_error_handler.h" +#include "components/sync/core/data_type_error_handler.h" +#include "components/sync/driver/change_processor.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace sync_driver { + +class ChangeProcessorMock : public ChangeProcessor, + public syncer::DataTypeErrorHandler { + public: + ChangeProcessorMock(); + virtual ~ChangeProcessorMock(); + MOCK_METHOD3(ApplyChangesFromSyncModel, + void(const syncer::BaseTransaction*, + int64_t, + const syncer::ImmutableChangeRecordList&)); + MOCK_METHOD0(CommitChangesFromSyncModel, void()); + MOCK_METHOD0(StartImpl, void()); + MOCK_CONST_METHOD0(IsRunning, bool()); + MOCK_METHOD2(OnUnrecoverableError, + void(const tracked_objects::Location&, const std::string&)); + MOCK_METHOD1(OnSingleDataTypeUnrecoverableError, + void(const syncer::SyncError&)); + MOCK_METHOD3(CreateAndUploadError, + syncer::SyncError(const tracked_objects::Location&, + const std::string&, + syncer::ModelType)); +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_CHANGE_PROCESSOR_MOCK_H_
diff --git a/components/sync/driver/data_type_controller.cc b/components/sync/driver/data_type_controller.cc new file mode 100644 index 0000000..b15e8c32 --- /dev/null +++ b/components/sync/driver/data_type_controller.cc
@@ -0,0 +1,44 @@ +// 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 "components/sync/driver/data_type_controller.h" + +#include "components/sync/base/data_type_histogram.h" +#include "components/sync/base/model_type.h" +#include "components/sync/core/user_share.h" + +namespace sync_driver { + +DataTypeController::DataTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const base::Closure& error_callback) + : base::RefCountedDeleteOnMessageLoop<DataTypeController>(ui_thread), + error_callback_(error_callback), + ui_thread_(ui_thread) {} + +DataTypeController::~DataTypeController() {} + +bool DataTypeController::IsUnrecoverableResult(ConfigureResult result) { + return (result == UNRECOVERABLE_ERROR); +} + +bool DataTypeController::IsSuccessfulResult(ConfigureResult result) { + return (result == OK || result == OK_FIRST_RUN); +} + +syncer::SyncError DataTypeController::CreateAndUploadError( + const tracked_objects::Location& location, + const std::string& message, + syncer::ModelType type) { + if (!error_callback_.is_null()) + error_callback_.Run(); + return syncer::SyncError(location, syncer::SyncError::DATATYPE_ERROR, message, + type); +} + +bool DataTypeController::ReadyForStart() const { + return true; +} + +} // namespace sync_driver
diff --git a/components/sync/driver/data_type_controller.h b/components/sync/driver/data_type_controller.h new file mode 100644 index 0000000..7035b5dc --- /dev/null +++ b/components/sync/driver/data_type_controller.h
@@ -0,0 +1,180 @@ +// 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 COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_H__ +#define COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_H__ + +#include <map> +#include <string> + +#include "base/callback.h" +#include "base/location.h" +#include "base/memory/ref_counted.h" +#include "base/memory/ref_counted_delete_on_message_loop.h" +#include "base/sequenced_task_runner_helpers.h" +#include "components/sync/base/model_type.h" +#include "components/sync/base/unrecoverable_error_handler.h" +#include "components/sync/core/data_type_error_handler.h" + +namespace base { +class SingleThreadTaskRunner; +} + +namespace syncer { +class SyncError; +class SyncMergeResult; +} + +namespace sync_driver { +class BackendDataTypeConfigurer; + +// Data type controllers need to be refcounted threadsafe, as they may +// need to run model associator or change processor on other threads. +class DataTypeController + : public base::RefCountedDeleteOnMessageLoop<DataTypeController>, + public syncer::DataTypeErrorHandler { + public: + enum State { + NOT_RUNNING, // The controller has never been started or has previously + // been stopped. Must be in this state to start. + MODEL_STARTING, // The controller is waiting on dependent services + // that need to be available before model + // association. + MODEL_LOADED, // The model has finished loading and can start + // associating now. + ASSOCIATING, // Model association is in progress. + RUNNING, // The controller is running and the data type is + // in sync with the cloud. + STOPPING, // The controller is in the process of stopping + // and is waiting for dependent services to stop. + DISABLED // The controller was started but encountered an error + // so it is disabled waiting for it to be stopped. + }; + + // This enum is used for "Sync.*ConfigureFailre" histograms so the order + // of is important. Any changes need to be reflected in histograms.xml. + enum ConfigureResult { + OK, // The data type has started normally. + OK_FIRST_RUN, // Same as OK, but sent on first successful + // start for this type for this user as + // determined by cloud state. + ASSOCIATION_FAILED, // An error occurred during model association. + ABORTED, // Start was aborted by calling Stop(). + UNRECOVERABLE_ERROR, // An unrecoverable error occured. + NEEDS_CRYPTO, // The data type cannot be started yet because it + // depends on the cryptographer. + RUNTIME_ERROR, // After starting, a runtime error was encountered. + MAX_CONFIGURE_RESULT + }; + + typedef base::Callback<void(ConfigureResult, + const syncer::SyncMergeResult&, + const syncer::SyncMergeResult&)> + StartCallback; + + typedef base::Callback<void(syncer::ModelType, syncer::SyncError)> + ModelLoadCallback; + + typedef std::map<syncer::ModelType, scoped_refptr<DataTypeController>> + TypeMap; + typedef std::map<syncer::ModelType, DataTypeController::State> StateMap; + + // Returns true if the start result should trigger an unrecoverable error. + // Public so unit tests can use this function as well. + static bool IsUnrecoverableResult(ConfigureResult result); + + // Returns true if the datatype started successfully. + static bool IsSuccessfulResult(ConfigureResult result); + + // Returns true if DataTypeManager should wait for LoadModels to complete + // successfully before starting configuration. Directory based types should + // return false while USS datatypes should return true. + virtual bool ShouldLoadModelBeforeConfigure() const = 0; + + // Begins asynchronous operation of loading the model to get it ready for + // model association. Once the models are loaded the callback will be invoked + // with the result. If the models are already loaded it is safe to call the + // callback right away. Else the callback needs to be stored and called when + // the models are ready. + virtual void LoadModels(const ModelLoadCallback& model_load_callback) = 0; + + // Registers with sync backend if needed. This function is called by + // DataTypeManager before downloading initial data. Non-blocking types need to + // pass activation context containing progress marker to sync backend before + // initial download starts. + virtual void RegisterWithBackend(BackendDataTypeConfigurer* configurer) = 0; + + // Will start a potentially asynchronous operation to perform the + // model association. Once the model association is done the callback will + // be invoked. + virtual void StartAssociating(const StartCallback& start_callback) = 0; + + // Called by DataTypeManager to activate the controlled data type using + // one of the implementation specific methods provided by the |configurer|. + // This is called (on UI thread) after the data type configuration has + // completed successfully. + virtual void ActivateDataType(BackendDataTypeConfigurer* configurer) = 0; + + // Called by DataTypeManager to deactivate the controlled data type. + // See comments for ModelAssociationManager::OnSingleDataTypeWillStop. + virtual void DeactivateDataType(BackendDataTypeConfigurer* configurer) = 0; + + // Synchronously stops the data type. If StartAssociating has already been + // called but is not done yet it will be aborted. Similarly if LoadModels + // has not completed it will also be aborted. + // NOTE: Stop() should be called after sync backend machinery has stopped + // routing changes to this data type. Stop() should ensure the data type + // logic shuts down gracefully by flushing remaining changes and calling + // StopSyncing on the SyncableService. This assumes no changes will ever + // propagate from sync again from point where Stop() is called. + virtual void Stop() = 0; + + // Unique model type for this data type controller. + virtual syncer::ModelType type() const = 0; + + // Name of this data type. For logging purposes only. + virtual std::string name() const = 0; + + // Current state of the data type controller. + virtual State state() const = 0; + + // Partial implementation of DataTypeErrorHandler. + // This is thread safe. + syncer::SyncError CreateAndUploadError( + const tracked_objects::Location& location, + const std::string& message, + syncer::ModelType type) override; + + // Whether the DataTypeController is ready to start. This is useful if the + // datatype itself must make the decision about whether it should be enabled + // at all (and therefore whether the initial download of the sync data for + // the type should be performed). + // Returns true by default. + virtual bool ReadyForStart() const; + + protected: + friend class base::RefCountedDeleteOnMessageLoop<DataTypeController>; + friend class base::DeleteHelper<DataTypeController>; + + DataTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const base::Closure& error_callback); + + ~DataTypeController() override; + + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread() const { + return ui_thread_; + } + + // The callback that will be invoked when an unrecoverable error occurs. + // TODO(sync): protected for use by legacy controllers. + base::Closure error_callback_; + + private: + const scoped_refptr<base::SingleThreadTaskRunner> ui_thread_; +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_H__
diff --git a/components/sync/driver/data_type_controller_mock.cc b/components/sync/driver/data_type_controller_mock.cc new file mode 100644 index 0000000..17ea6bea0 --- /dev/null +++ b/components/sync/driver/data_type_controller_mock.cc
@@ -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. + +#include "components/sync/driver/data_type_controller_mock.h" + +namespace sync_driver { + +StartCallbackMock::StartCallbackMock() {} + +StartCallbackMock::~StartCallbackMock() {} + +ModelLoadCallbackMock::ModelLoadCallbackMock() {} + +ModelLoadCallbackMock::~ModelLoadCallbackMock() {} + +} // namespace sync_driver
diff --git a/components/sync/driver/data_type_controller_mock.h b/components/sync/driver/data_type_controller_mock.h new file mode 100644 index 0000000..7c37a7e --- /dev/null +++ b/components/sync/driver/data_type_controller_mock.h
@@ -0,0 +1,36 @@ +// 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 COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_MOCK_H__ +#define COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_MOCK_H__ + +#include "components/sync/api/sync_error.h" +#include "components/sync/api/sync_merge_result.h" +#include "components/sync/driver/data_type_controller.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace sync_driver { + +class StartCallbackMock { + public: + StartCallbackMock(); + virtual ~StartCallbackMock(); + + MOCK_METHOD3(Run, + void(DataTypeController::ConfigureResult result, + const syncer::SyncMergeResult& local_merge_result, + const syncer::SyncMergeResult& syncer_merge_result)); +}; + +class ModelLoadCallbackMock { + public: + ModelLoadCallbackMock(); + virtual ~ModelLoadCallbackMock(); + + MOCK_METHOD2(Run, void(syncer::ModelType, syncer::SyncError)); +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_MOCK_H__
diff --git a/components/sync/driver/data_type_encryption_handler.cc b/components/sync/driver/data_type_encryption_handler.cc new file mode 100644 index 0000000..c01469fe --- /dev/null +++ b/components/sync/driver/data_type_encryption_handler.cc
@@ -0,0 +1,11 @@ +// 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 "components/sync/driver/data_type_encryption_handler.h" + +namespace sync_driver { + +DataTypeEncryptionHandler::DataTypeEncryptionHandler() {} +DataTypeEncryptionHandler::~DataTypeEncryptionHandler() {} +}
diff --git a/components/sync_driver/data_type_encryption_handler.h b/components/sync/driver/data_type_encryption_handler.h similarity index 100% rename from components/sync_driver/data_type_encryption_handler.h rename to components/sync/driver/data_type_encryption_handler.h
diff --git a/components/sync/driver/data_type_manager.cc b/components/sync/driver/data_type_manager.cc new file mode 100644 index 0000000..a95f1667 --- /dev/null +++ b/components/sync/driver/data_type_manager.cc
@@ -0,0 +1,37 @@ +// 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 "components/sync/driver/data_type_manager.h" + +namespace sync_driver { + +DataTypeManager::ConfigureResult::ConfigureResult() : status(UNKNOWN) {} + +DataTypeManager::ConfigureResult::ConfigureResult( + ConfigureStatus status, + syncer::ModelTypeSet requested_types) + : status(status), requested_types(requested_types) {} + +DataTypeManager::ConfigureResult::ConfigureResult( + const ConfigureResult& other) = default; + +DataTypeManager::ConfigureResult::~ConfigureResult() {} + +// Static. +std::string DataTypeManager::ConfigureStatusToString(ConfigureStatus status) { + switch (status) { + case OK: + return "Ok"; + case ABORTED: + return "Aborted"; + case UNRECOVERABLE_ERROR: + return "Unrecoverable Error"; + case UNKNOWN: + NOTREACHED(); + return std::string(); + } + return std::string(); +} + +} // namespace sync_driver
diff --git a/components/sync/driver/data_type_manager.h b/components/sync/driver/data_type_manager.h new file mode 100644 index 0000000..ecf2c67 --- /dev/null +++ b/components/sync/driver/data_type_manager.h
@@ -0,0 +1,98 @@ +// 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 COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_H__ +#define COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_H__ + +#include <list> +#include <set> +#include <string> + +#include "components/sync/api/sync_error.h" +#include "components/sync/base/model_type.h" +#include "components/sync/core/configure_reason.h" +#include "components/sync/driver/data_type_controller.h" +#include "components/sync/driver/data_type_status_table.h" + +namespace sync_driver { + +// This interface is for managing the start up and shut down life cycle +// of many different syncable data types. +class DataTypeManager { + public: + enum State { + STOPPED, // No data types are currently running. + CONFIGURING, // Data types are being started. + RETRYING, // Retrying a pending reconfiguration. + + CONFIGURED, // All enabled data types are running. + STOPPING // Data types are being stopped. + }; + + // Update NotifyDone() in data_type_manager_impl.cc if you update + // this. + enum ConfigureStatus { + UNKNOWN = -1, + OK, // Configuration finished some or all types. + ABORTED, // Start was aborted by calling Stop() before + // all types were started. + UNRECOVERABLE_ERROR // We got an unrecoverable error during startup. + }; + + // Note: |errors| is only filled when status is not OK. + struct ConfigureResult { + ConfigureResult(); + ConfigureResult(ConfigureStatus status, + syncer::ModelTypeSet requested_types); + ConfigureResult(const ConfigureResult& other); + ~ConfigureResult(); + + ConfigureStatus status; + syncer::ModelTypeSet requested_types; + DataTypeStatusTable data_type_status_table; + }; + + virtual ~DataTypeManager() {} + + // Convert a ConfigureStatus to string for debug purposes. + static std::string ConfigureStatusToString(ConfigureStatus status); + + // Begins asynchronous configuration of data types. Any currently + // running data types that are not in the desired_types set will be + // stopped. Any stopped data types that are in the desired_types + // set will be started. All other data types are left in their + // current state. A SYNC_CONFIGURE_START notification will be sent + // to the UI thread when configuration is started and a + // SYNC_CONFIGURE_DONE notification will be sent (with a + // ConfigureResult detail) when configuration is complete. + // + // Note that you may call Configure() while configuration is in + // progress. Configuration will be complete only when the + // desired_types supplied in the last call to Configure is achieved. + virtual void Configure(syncer::ModelTypeSet desired_types, + syncer::ConfigureReason reason) = 0; + + // Resets the error state for |type| and triggers a reconfiguration if + // necessary. + virtual void ReenableType(syncer::ModelType type) = 0; + + // Resets all data type error state. + virtual void ResetDataTypeErrors() = 0; + + virtual void PurgeForMigration(syncer::ModelTypeSet undesired_types, + syncer::ConfigureReason reason) = 0; + + // Synchronously stops all registered data types. If called after + // Configure() is called but before it finishes, it will abort the + // configure and any data types that have been started will be + // stopped. + virtual void Stop() = 0; + + // The current state of the data type manager. + virtual State state() const = 0; +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_H__
diff --git a/components/sync/driver/data_type_manager_impl.cc b/components/sync/driver/data_type_manager_impl.cc new file mode 100644 index 0000000..56df367 --- /dev/null +++ b/components/sync/driver/data_type_manager_impl.cc
@@ -0,0 +1,690 @@ +// 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 "components/sync/driver/data_type_manager_impl.h" + +#include <algorithm> +#include <functional> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/callback.h" +#include "base/compiler_specific.h" +#include "base/logging.h" +#include "base/metrics/histogram_macros.h" +#include "base/profiler/scoped_tracker.h" +#include "base/strings/stringprintf.h" +#include "base/trace_event/trace_event.h" +#include "components/sync/core/data_type_debug_info_listener.h" +#include "components/sync/driver/data_type_encryption_handler.h" +#include "components/sync/driver/data_type_manager_observer.h" +#include "components/sync/driver/data_type_status_table.h" + +namespace sync_driver { + +namespace { + +DataTypeStatusTable::TypeErrorMap GenerateCryptoErrorsForTypes( + syncer::ModelTypeSet encrypted_types) { + DataTypeStatusTable::TypeErrorMap crypto_errors; + for (syncer::ModelTypeSet::Iterator iter = encrypted_types.First(); + iter.Good(); iter.Inc()) { + crypto_errors[iter.Get()] = syncer::SyncError( + FROM_HERE, syncer::SyncError::CRYPTO_ERROR, "", iter.Get()); + } + return crypto_errors; +} + +} // namespace + +DataTypeManagerImpl::AssociationTypesInfo::AssociationTypesInfo() {} +DataTypeManagerImpl::AssociationTypesInfo::AssociationTypesInfo( + const AssociationTypesInfo& other) = default; +DataTypeManagerImpl::AssociationTypesInfo::~AssociationTypesInfo() {} + +DataTypeManagerImpl::DataTypeManagerImpl( + const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& + debug_info_listener, + const DataTypeController::TypeMap* controllers, + const DataTypeEncryptionHandler* encryption_handler, + BackendDataTypeConfigurer* configurer, + DataTypeManagerObserver* observer) + : configurer_(configurer), + controllers_(controllers), + state_(DataTypeManager::STOPPED), + needs_reconfigure_(false), + last_configure_reason_(syncer::CONFIGURE_REASON_UNKNOWN), + debug_info_listener_(debug_info_listener), + model_association_manager_(controllers, this), + observer_(observer), + encryption_handler_(encryption_handler), + catch_up_in_progress_(false), + download_started_(false), + weak_ptr_factory_(this) { + DCHECK(configurer_); + DCHECK(observer_); +} + +DataTypeManagerImpl::~DataTypeManagerImpl() {} + +void DataTypeManagerImpl::Configure(syncer::ModelTypeSet desired_types, + syncer::ConfigureReason reason) { + // Once requested, we will remain in "catch up" mode until we notify the + // caller (see NotifyDone). We do this to ensure that once started, subsequent + // calls to Configure won't take us out of "catch up" mode. + if (reason == syncer::CONFIGURE_REASON_CATCH_UP) + catch_up_in_progress_ = true; + + desired_types.PutAll(syncer::CoreTypes()); + + // Only allow control types and types that have controllers. + syncer::ModelTypeSet filtered_desired_types; + for (syncer::ModelTypeSet::Iterator type = desired_types.First(); type.Good(); + type.Inc()) { + DataTypeController::TypeMap::const_iterator iter = + controllers_->find(type.Get()); + if (syncer::IsControlType(type.Get()) || iter != controllers_->end()) { + if (iter != controllers_->end()) { + if (!iter->second->ReadyForStart() && + !data_type_status_table_.GetUnreadyErrorTypes().Has(type.Get())) { + // Add the type to the unready types set to prevent purging it. It's + // up to the datatype controller to, if necessary, explicitly + // mark the type as broken to trigger a purge. + syncer::SyncError error(FROM_HERE, syncer::SyncError::UNREADY_ERROR, + "Datatype not ready at config time.", + type.Get()); + std::map<syncer::ModelType, syncer::SyncError> errors; + errors[type.Get()] = error; + data_type_status_table_.UpdateFailedDataTypes(errors); + } else if (iter->second->ReadyForStart()) { + data_type_status_table_.ResetUnreadyErrorFor(type.Get()); + } + } + filtered_desired_types.Put(type.Get()); + } + } + ConfigureImpl(filtered_desired_types, reason); +} + +void DataTypeManagerImpl::ReenableType(syncer::ModelType type) { + // TODO(zea): move the "should we reconfigure" logic into the datatype handler + // itself. + // Only reconfigure if the type actually had a data type or unready error. + if (!data_type_status_table_.ResetDataTypeErrorFor(type) && + !data_type_status_table_.ResetUnreadyErrorFor(type)) { + return; + } + + // Only reconfigure if the type is actually desired. + if (!last_requested_types_.Has(type)) + return; + + DVLOG(1) << "Reenabling " << syncer::ModelTypeToString(type); + needs_reconfigure_ = true; + last_configure_reason_ = syncer::CONFIGURE_REASON_PROGRAMMATIC; + ProcessReconfigure(); +} + +void DataTypeManagerImpl::ResetDataTypeErrors() { + data_type_status_table_.Reset(); +} + +void DataTypeManagerImpl::PurgeForMigration( + syncer::ModelTypeSet undesired_types, + syncer::ConfigureReason reason) { + syncer::ModelTypeSet remainder = + Difference(last_requested_types_, undesired_types); + ConfigureImpl(remainder, reason); +} + +void DataTypeManagerImpl::ConfigureImpl(syncer::ModelTypeSet desired_types, + syncer::ConfigureReason reason) { + DCHECK_NE(reason, syncer::CONFIGURE_REASON_UNKNOWN); + DVLOG(1) << "Configuring for " << syncer::ModelTypeSetToString(desired_types) + << " with reason " << reason; + if (state_ == STOPPING) { + // You can not set a configuration while stopping. + LOG(ERROR) << "Configuration set while stopping."; + return; + } + + // TODO(zea): consider not performing a full configuration once there's a + // reliable way to determine if the requested set of enabled types matches the + // current set. + + last_requested_types_ = desired_types; + last_configure_reason_ = reason; + // Only proceed if we're in a steady state or retrying. + if (state_ != STOPPED && state_ != CONFIGURED && state_ != RETRYING) { + DVLOG(1) << "Received configure request while configuration in flight. " + << "Postponing until current configuration complete."; + needs_reconfigure_ = true; + return; + } + + Restart(reason); +} + +void DataTypeManagerImpl::RegisterTypesWithBackend() { + for (syncer::ModelTypeSet::Iterator type_iter = last_requested_types_.First(); + type_iter.Good(); type_iter.Inc()) { + const auto& dtc_iter = controllers_->find(type_iter.Get()); + if (dtc_iter != controllers_->end()) + dtc_iter->second->RegisterWithBackend(configurer_); + } +} + +BackendDataTypeConfigurer::DataTypeConfigStateMap +DataTypeManagerImpl::BuildDataTypeConfigStateMap( + const syncer::ModelTypeSet& types_being_configured) const { + // 1. Get the failed types (due to fatal, crypto, and unready errors). + // 2. Add the difference between last_requested_types_ and the failed types + // as CONFIGURE_INACTIVE. + // 3. Flip |types_being_configured| to CONFIGURE_ACTIVE. + // 4. Set non-enabled user types as DISABLED. + // 5. Set the fatal, crypto, and unready types to their respective states. + syncer::ModelTypeSet error_types = data_type_status_table_.GetFailedTypes(); + syncer::ModelTypeSet fatal_types = + data_type_status_table_.GetFatalErrorTypes(); + syncer::ModelTypeSet crypto_types = + data_type_status_table_.GetCryptoErrorTypes(); + syncer::ModelTypeSet unready_types = + data_type_status_table_.GetUnreadyErrorTypes(); + + // Types with persistence errors are only purged/resynced when they're + // actively being configured. + syncer::ModelTypeSet clean_types = + data_type_status_table_.GetPersistenceErrorTypes(); + clean_types.RetainAll(types_being_configured); + + // Types with unready errors do not count as unready if they've been disabled. + unready_types.RetainAll(last_requested_types_); + + syncer::ModelTypeSet enabled_types = last_requested_types_; + enabled_types.RemoveAll(error_types); + + // If we're catching up, add all enabled (non-error) types to the clean set to + // ensure we download and apply them to the model types. + if (catch_up_in_progress_) + clean_types.PutAll(enabled_types); + + syncer::ModelTypeSet disabled_types = syncer::Difference( + syncer::Union(syncer::UserTypes(), syncer::ControlTypes()), + enabled_types); + syncer::ModelTypeSet to_configure = + syncer::Intersection(enabled_types, types_being_configured); + DVLOG(1) << "Enabling: " << syncer::ModelTypeSetToString(enabled_types); + DVLOG(1) << "Configuring: " << syncer::ModelTypeSetToString(to_configure); + DVLOG(1) << "Disabling: " << syncer::ModelTypeSetToString(disabled_types); + + BackendDataTypeConfigurer::DataTypeConfigStateMap config_state_map; + BackendDataTypeConfigurer::SetDataTypesState( + BackendDataTypeConfigurer::CONFIGURE_INACTIVE, enabled_types, + &config_state_map); + BackendDataTypeConfigurer::SetDataTypesState( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, to_configure, + &config_state_map); + BackendDataTypeConfigurer::SetDataTypesState( + BackendDataTypeConfigurer::CONFIGURE_CLEAN, clean_types, + &config_state_map); + BackendDataTypeConfigurer::SetDataTypesState( + BackendDataTypeConfigurer::DISABLED, disabled_types, &config_state_map); + BackendDataTypeConfigurer::SetDataTypesState(BackendDataTypeConfigurer::FATAL, + fatal_types, &config_state_map); + BackendDataTypeConfigurer::SetDataTypesState( + BackendDataTypeConfigurer::CRYPTO, crypto_types, &config_state_map); + BackendDataTypeConfigurer::SetDataTypesState( + BackendDataTypeConfigurer::UNREADY, unready_types, &config_state_map); + return config_state_map; +} + +void DataTypeManagerImpl::Restart(syncer::ConfigureReason reason) { + DVLOG(1) << "Restarting..."; + + // Only record the type histograms for user-triggered configurations or + // restarts. + if (reason == syncer::CONFIGURE_REASON_RECONFIGURATION || + reason == syncer::CONFIGURE_REASON_NEW_CLIENT || + reason == syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE) { + for (syncer::ModelTypeSet::Iterator iter = last_requested_types_.First(); + iter.Good(); iter.Inc()) { + UMA_HISTOGRAM_ENUMERATION("Sync.ConfigureDataTypes", + syncer::ModelTypeToHistogramInt(iter.Get()), + syncer::MODEL_TYPE_COUNT); + } + } + + // Check for new or resolved data type crypto errors. + if (encryption_handler_->IsPassphraseRequired()) { + syncer::ModelTypeSet encrypted_types = + encryption_handler_->GetEncryptedDataTypes(); + encrypted_types.RetainAll(last_requested_types_); + encrypted_types.RemoveAll(data_type_status_table_.GetCryptoErrorTypes()); + DataTypeStatusTable::TypeErrorMap crypto_errors = + GenerateCryptoErrorsForTypes(encrypted_types); + data_type_status_table_.UpdateFailedDataTypes(crypto_errors); + } else { + data_type_status_table_.ResetCryptoErrors(); + } + + syncer::ModelTypeSet failed_types = data_type_status_table_.GetFailedTypes(); + syncer::ModelTypeSet enabled_types = + syncer::Difference(last_requested_types_, failed_types); + + last_restart_time_ = base::Time::Now(); + configuration_stats_.clear(); + + DCHECK(state_ == STOPPED || state_ == CONFIGURED || state_ == RETRYING); + + const State old_state = state_; + state_ = CONFIGURING; + + // Starting from a "steady state" (stopped or configured) state + // should send a start notification. + // Note: NotifyStart() must be called with the updated (non-idle) state, + // otherwise logic listening for the configuration start might not be aware + // of the fact that the DTM is in a configuration state. + if (old_state == STOPPED || old_state == CONFIGURED) + NotifyStart(); + + download_types_queue_ = PrioritizeTypes(enabled_types); + association_types_queue_ = std::queue<AssociationTypesInfo>(); + + // If we're performing a "catch up", first stop the model types to ensure the + // call to Initialize triggers model association. + if (catch_up_in_progress_) + model_association_manager_.Stop(); + download_started_ = false; + model_association_manager_.Initialize(enabled_types); +} + +void DataTypeManagerImpl::OnAllDataTypesReadyForConfigure() { + DCHECK(!download_started_); + download_started_ = true; + UMA_HISTOGRAM_LONG_TIMES("Sync.USSLoadModelsTime", + base::Time::Now() - last_restart_time_); + // TODO(pavely): By now some of datatypes in download_types_queue_ could have + // failed loading and should be excluded from configuration. I need to adjust + // download_types_queue_ for such types. + RegisterTypesWithBackend(); + StartNextDownload(syncer::ModelTypeSet()); +} + +syncer::ModelTypeSet DataTypeManagerImpl::GetPriorityTypes() const { + syncer::ModelTypeSet high_priority_types; + high_priority_types.PutAll(syncer::PriorityCoreTypes()); + high_priority_types.PutAll(syncer::PriorityUserTypes()); + return high_priority_types; +} + +TypeSetPriorityList DataTypeManagerImpl::PrioritizeTypes( + const syncer::ModelTypeSet& types) { + syncer::ModelTypeSet high_priority_types = GetPriorityTypes(); + high_priority_types.RetainAll(types); + + syncer::ModelTypeSet low_priority_types = + syncer::Difference(types, high_priority_types); + + TypeSetPriorityList result; + if (!high_priority_types.Empty()) + result.push(high_priority_types); + if (!low_priority_types.Empty()) + result.push(low_priority_types); + + // Could be empty in case of purging for migration, sync nothing, etc. + // Configure empty set to purge data from backend. + if (result.empty()) + result.push(syncer::ModelTypeSet()); + + return result; +} + +void DataTypeManagerImpl::ProcessReconfigure() { + DCHECK(needs_reconfigure_); + + // Wait for current download and association to finish. + if (!download_types_queue_.empty() || + model_association_manager_.state() == + ModelAssociationManager::ASSOCIATING) { + return; + } + + association_types_queue_ = std::queue<AssociationTypesInfo>(); + + // An attempt was made to reconfigure while we were already configuring. + // This can be because a passphrase was accepted or the user changed the + // set of desired types. Either way, |last_requested_types_| will contain + // the most recent set of desired types, so we just call configure. + // Note: we do this whether or not GetControllersNeedingStart is true, + // because we may need to stop datatypes. + DVLOG(1) << "Reconfiguring due to previous configure attempt occuring while" + << " busy."; + + // Note: ConfigureImpl is called directly, rather than posted, in order to + // ensure that any purging/unapplying/journaling happens while the set of + // failed types is still up to date. If stack unwinding were to be done + // via PostTask, the failed data types may be reset before the purging was + // performed. + state_ = RETRYING; + needs_reconfigure_ = false; + ConfigureImpl(last_requested_types_, last_configure_reason_); +} + +void DataTypeManagerImpl::OnDownloadRetry() { + DCHECK_EQ(CONFIGURING, state_); +} + +void DataTypeManagerImpl::DownloadReady( + syncer::ModelTypeSet types_to_download, + syncer::ModelTypeSet first_sync_types, + syncer::ModelTypeSet failed_configuration_types) { + DCHECK_EQ(CONFIGURING, state_); + + // Persistence errors are reset after each backend configuration attempt + // during which they would have been purged. + data_type_status_table_.ResetPersistenceErrorsFrom(types_to_download); + + if (!failed_configuration_types.Empty()) { + DataTypeStatusTable::TypeErrorMap errors; + for (syncer::ModelTypeSet::Iterator iter = + failed_configuration_types.First(); + iter.Good(); iter.Inc()) { + syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Backend failed to download type.", iter.Get()); + errors[iter.Get()] = error; + } + data_type_status_table_.UpdateFailedDataTypes(errors); + needs_reconfigure_ = true; + } + + if (needs_reconfigure_) { + download_types_queue_ = TypeSetPriorityList(); + ProcessReconfigure(); + return; + } + + CHECK(!download_types_queue_.empty()); + download_types_queue_.pop(); + + // Those types that were already downloaded (non first sync/error types) + // should already be associating. Just kick off association of the newly + // downloaded types if necessary. + if (!association_types_queue_.empty()) { + association_types_queue_.back().first_sync_types = first_sync_types; + association_types_queue_.back().download_ready_time = base::Time::Now(); + StartNextAssociation(UNREADY_AT_CONFIG); + } else if (download_types_queue_.empty() && + model_association_manager_.state() != + ModelAssociationManager::ASSOCIATING) { + // There's nothing more to download or associate (implying either there were + // no types to associate or they associated as part of |ready_types|). + // If the model association manager is also finished, then we're done + // configuring. + state_ = CONFIGURED; + ConfigureResult result(OK, last_requested_types_); + NotifyDone(result); + return; + } + + StartNextDownload(types_to_download); +} + +void DataTypeManagerImpl::StartNextDownload( + syncer::ModelTypeSet high_priority_types_before) { + if (download_types_queue_.empty()) + return; + + // Tell the backend about the new set of data types we wish to sync. + // The task will be invoked when updates are downloaded. + syncer::ModelTypeSet ready_types = configurer_->ConfigureDataTypes( + last_configure_reason_, + BuildDataTypeConfigStateMap(download_types_queue_.front()), + base::Bind(&DataTypeManagerImpl::DownloadReady, + weak_ptr_factory_.GetWeakPtr(), download_types_queue_.front()), + base::Bind(&DataTypeManagerImpl::OnDownloadRetry, + weak_ptr_factory_.GetWeakPtr())); + + AssociationTypesInfo association_info; + association_info.types = download_types_queue_.front(); + association_info.ready_types = ready_types; + association_info.download_start_time = base::Time::Now(); + association_info.high_priority_types_before = high_priority_types_before; + association_types_queue_.push(association_info); + + // Start associating those types that are already downloaded (does nothing + // if model associator is busy). + StartNextAssociation(READY_AT_CONFIG); +} + +void DataTypeManagerImpl::StartNextAssociation(AssociationGroup group) { + CHECK(!association_types_queue_.empty()); + + // If the model association manager is already associating, let it finish. + // The model association done event will result in associating any remaining + // association groups. + if (model_association_manager_.state() != + ModelAssociationManager::INITIALIZED) { + return; + } + + syncer::ModelTypeSet types_to_associate; + if (group == READY_AT_CONFIG) { + association_types_queue_.front().ready_association_request_time = + base::Time::Now(); + types_to_associate = association_types_queue_.front().ready_types; + } else { + DCHECK_EQ(UNREADY_AT_CONFIG, group); + // Only start associating the rest of the types if they have all finished + // downloading. + if (association_types_queue_.front().download_ready_time.is_null()) + return; + association_types_queue_.front().full_association_request_time = + base::Time::Now(); + // We request the full set of types here for completeness sake. All types + // within the READY_AT_CONFIG set will already be started and should be + // no-ops. + types_to_associate = association_types_queue_.front().types; + } + + DVLOG(1) << "Associating " + << syncer::ModelTypeSetToString(types_to_associate); + model_association_manager_.StartAssociationAsync(types_to_associate); +} + +void DataTypeManagerImpl::OnSingleDataTypeWillStop( + syncer::ModelType type, + const syncer::SyncError& error) { + DataTypeController::TypeMap::const_iterator c_it = controllers_->find(type); + DCHECK(c_it != controllers_->end()); + // Delegate deactivation to the controller. + c_it->second->DeactivateDataType(configurer_); + + if (error.IsSet()) { + DataTypeStatusTable::TypeErrorMap failed_types; + failed_types[type] = error; + data_type_status_table_.UpdateFailedDataTypes(failed_types); + + // Unrecoverable errors will shut down the entire backend, so no need to + // reconfigure. + if (error.error_type() != syncer::SyncError::UNRECOVERABLE_ERROR) { + needs_reconfigure_ = true; + last_configure_reason_ = syncer::CONFIGURE_REASON_PROGRAMMATIC; + ProcessReconfigure(); + } + } +} + +void DataTypeManagerImpl::OnSingleDataTypeAssociationDone( + syncer::ModelType type, + const syncer::DataTypeAssociationStats& association_stats) { + DCHECK(!association_types_queue_.empty()); + DataTypeController::TypeMap::const_iterator c_it = controllers_->find(type); + DCHECK(c_it != controllers_->end()); + if (c_it->second->state() == DataTypeController::RUNNING) { + // Delegate activation to the controller. + c_it->second->ActivateDataType(configurer_); + } + + if (!debug_info_listener_.IsInitialized()) + return; + + AssociationTypesInfo& info = association_types_queue_.front(); + configuration_stats_.push_back(syncer::DataTypeConfigurationStats()); + configuration_stats_.back().model_type = type; + configuration_stats_.back().association_stats = association_stats; + if (info.types.Has(type)) { + // Times in |info| only apply to non-slow types. + configuration_stats_.back().download_wait_time = + info.download_start_time - last_restart_time_; + if (info.first_sync_types.Has(type)) { + configuration_stats_.back().download_time = + info.download_ready_time - info.download_start_time; + } + if (info.ready_types.Has(type)) { + configuration_stats_.back().association_wait_time_for_high_priority = + info.ready_association_request_time - info.download_start_time; + } else { + configuration_stats_.back().association_wait_time_for_high_priority = + info.full_association_request_time - info.download_ready_time; + } + configuration_stats_.back().high_priority_types_configured_before = + info.high_priority_types_before; + configuration_stats_.back().same_priority_types_configured_before = + info.configured_types; + info.configured_types.Put(type); + } +} + +void DataTypeManagerImpl::OnModelAssociationDone( + const DataTypeManager::ConfigureResult& result) { + DCHECK(state_ == STOPPING || state_ == CONFIGURING); + + if (state_ == STOPPING) + return; + + // Ignore abort/unrecoverable error if we need to reconfigure anyways. + if (needs_reconfigure_) { + ProcessReconfigure(); + return; + } + + if (result.status == ABORTED || result.status == UNRECOVERABLE_ERROR) { + Abort(result.status); + return; + } + + DCHECK(result.status == OK); + + CHECK(!association_types_queue_.empty()); + + // If this model association was for the full set of types, then this priority + // set is done. Otherwise it was just the ready types and the unready types + // still need to be associated. + if (result.requested_types == association_types_queue_.front().types) { + association_types_queue_.pop(); + if (!association_types_queue_.empty()) { + StartNextAssociation(READY_AT_CONFIG); + } else if (download_types_queue_.empty()) { + state_ = CONFIGURED; + NotifyDone(result); + } + } else { + DCHECK_EQ(association_types_queue_.front().ready_types, + result.requested_types); + // Will do nothing if the types are still downloading. + StartNextAssociation(UNREADY_AT_CONFIG); + } +} + +void DataTypeManagerImpl::Stop() { + if (state_ == STOPPED) + return; + + bool need_to_notify = state_ == CONFIGURING; + StopImpl(); + + if (need_to_notify) { + ConfigureResult result(ABORTED, last_requested_types_); + NotifyDone(result); + } +} + +void DataTypeManagerImpl::Abort(ConfigureStatus status) { + DCHECK_EQ(CONFIGURING, state_); + + StopImpl(); + + DCHECK_NE(OK, status); + ConfigureResult result(status, last_requested_types_); + NotifyDone(result); +} + +void DataTypeManagerImpl::StopImpl() { + state_ = STOPPING; + + // Invalidate weak pointer to drop download callbacks. + weak_ptr_factory_.InvalidateWeakPtrs(); + + // Stop all data types. This may trigger association callback but the + // callback will do nothing because state is set to STOPPING above. + model_association_manager_.Stop(); + + state_ = STOPPED; +} + +void DataTypeManagerImpl::NotifyStart() { + observer_->OnConfigureStart(); +} + +void DataTypeManagerImpl::NotifyDone(const ConfigureResult& raw_result) { + catch_up_in_progress_ = false; + + AddToConfigureTime(); + + ConfigureResult result = raw_result; + result.data_type_status_table = data_type_status_table_; + + DVLOG(1) << "Total time spent configuring: " + << configure_time_delta_.InSecondsF() << "s"; + switch (result.status) { + case DataTypeManager::OK: + DVLOG(1) << "NotifyDone called with result: OK"; + UMA_HISTOGRAM_LONG_TIMES("Sync.ConfigureTime_Long.OK", + configure_time_delta_); + if (debug_info_listener_.IsInitialized() && + !configuration_stats_.empty()) { + debug_info_listener_.Call( + FROM_HERE, + &syncer::DataTypeDebugInfoListener::OnDataTypeConfigureComplete, + configuration_stats_); + } + configuration_stats_.clear(); + break; + case DataTypeManager::ABORTED: + DVLOG(1) << "NotifyDone called with result: ABORTED"; + UMA_HISTOGRAM_LONG_TIMES("Sync.ConfigureTime_Long.ABORTED", + configure_time_delta_); + break; + case DataTypeManager::UNRECOVERABLE_ERROR: + DVLOG(1) << "NotifyDone called with result: UNRECOVERABLE_ERROR"; + UMA_HISTOGRAM_LONG_TIMES("Sync.ConfigureTime_Long.UNRECOVERABLE_ERROR", + configure_time_delta_); + break; + case DataTypeManager::UNKNOWN: + NOTREACHED(); + break; + } + observer_->OnConfigureDone(result); +} + +DataTypeManager::State DataTypeManagerImpl::state() const { + return state_; +} + +void DataTypeManagerImpl::AddToConfigureTime() { + DCHECK(!last_restart_time_.is_null()); + configure_time_delta_ += (base::Time::Now() - last_restart_time_); +} + +} // namespace sync_driver
diff --git a/components/sync/driver/data_type_manager_impl.h b/components/sync/driver/data_type_manager_impl.h new file mode 100644 index 0000000..27d9da4 --- /dev/null +++ b/components/sync/driver/data_type_manager_impl.h
@@ -0,0 +1,243 @@ +// 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 COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_IMPL_H__ +#define COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_IMPL_H__ + +#include "components/sync/driver/data_type_manager.h" + +#include <map> +#include <queue> +#include <vector> + +#include "base/callback_forward.h" +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/time/time.h" +#include "components/sync/driver/backend_data_type_configurer.h" +#include "components/sync/driver/model_association_manager.h" + +namespace syncer { +struct DataTypeConfigurationStats; +class DataTypeDebugInfoListener; +template <typename T> +class WeakHandle; +} + +namespace sync_driver { + +class DataTypeController; +class DataTypeEncryptionHandler; +class DataTypeManagerObserver; + +// List of data types grouped by priority and ordered from high priority to +// low priority. +typedef std::queue<syncer::ModelTypeSet> TypeSetPriorityList; + +class DataTypeManagerImpl : public DataTypeManager, + public ModelAssociationManagerDelegate { + public: + DataTypeManagerImpl( + const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& + debug_info_listener, + const DataTypeController::TypeMap* controllers, + const DataTypeEncryptionHandler* encryption_handler, + BackendDataTypeConfigurer* configurer, + DataTypeManagerObserver* observer); + ~DataTypeManagerImpl() override; + + // DataTypeManager interface. + void Configure(syncer::ModelTypeSet desired_types, + syncer::ConfigureReason reason) override; + void ReenableType(syncer::ModelType type) override; + void ResetDataTypeErrors() override; + + // Needed only for backend migration. + void PurgeForMigration(syncer::ModelTypeSet undesired_types, + syncer::ConfigureReason reason) override; + + void Stop() override; + State state() const override; + + // |ModelAssociationManagerDelegate| implementation. + void OnAllDataTypesReadyForConfigure() override; + void OnSingleDataTypeAssociationDone( + syncer::ModelType type, + const syncer::DataTypeAssociationStats& association_stats) override; + void OnModelAssociationDone( + const DataTypeManager::ConfigureResult& result) override; + void OnSingleDataTypeWillStop(syncer::ModelType type, + const syncer::SyncError& error) override; + + // Used by unit tests. TODO(sync) : This would go away if we made + // this class be able to do Dependency injection. crbug.com/129212. + ModelAssociationManager* GetModelAssociationManagerForTesting() { + return &model_association_manager_; + } + + private: + // Helper enum for identifying which types within a priority group to + // associate. + enum AssociationGroup { + // Those types that were already downloaded and didn't have an error at + // configuration time. Corresponds with AssociationTypesInfo's + // |ready_types|. These types can start associating as soon as the + // ModelAssociationManager is not busy. + READY_AT_CONFIG, + // All other types, including first time sync types and those that have + // encountered an error. These types must wait until the syncer has done + // any db changes and/or downloads before associating. + UNREADY_AT_CONFIG, + }; + + friend class TestDataTypeManager; + + // Abort configuration and stop all data types due to configuration errors. + void Abort(ConfigureStatus status); + + // Returns the priority types (control + priority user types). + // Virtual for overriding during tests. + virtual syncer::ModelTypeSet GetPriorityTypes() const; + + // Divide |types| into sets by their priorities and return the sets from + // high priority to low priority. + TypeSetPriorityList PrioritizeTypes(const syncer::ModelTypeSet& types); + + // Post a task to reconfigure when no downloading or association are running. + void ProcessReconfigure(); + + void Restart(syncer::ConfigureReason reason); + void DownloadReady(syncer::ModelTypeSet types_to_download, + syncer::ModelTypeSet first_sync_types, + syncer::ModelTypeSet failed_configuration_types); + + // Notification from the SBH that download failed due to a transient + // error and it will be retried. + void OnDownloadRetry(); + void NotifyStart(); + void NotifyDone(const ConfigureResult& result); + + // Add to |configure_time_delta_| the time since we last called + // Restart(). + void AddToConfigureTime(); + + void ConfigureImpl(syncer::ModelTypeSet desired_types, + syncer::ConfigureReason reason); + + // Calls data type controllers of requested types to register with backend. + void RegisterTypesWithBackend(); + + BackendDataTypeConfigurer::DataTypeConfigStateMap BuildDataTypeConfigStateMap( + const syncer::ModelTypeSet& types_being_configured) const; + + // Start download of next set of types in |download_types_queue_| (if + // any exist, does nothing otherwise). + // Will kick off association of any new ready types. + void StartNextDownload(syncer::ModelTypeSet high_priority_types_before); + + // Start association of next batch of data types after association of + // previous batch finishes. |group| controls which set of types within + // an AssociationTypesInfo to associate. Does nothing if model associator + // is busy performing association. + void StartNextAssociation(AssociationGroup group); + + void StopImpl(); + + BackendDataTypeConfigurer* configurer_; + // Map of all data type controllers that are available for sync. + // This list is determined at startup by various command line flags. + const DataTypeController::TypeMap* controllers_; + State state_; + syncer::ModelTypeSet last_requested_types_; + + // Whether an attempt to reconfigure was made while we were busy configuring. + // The |last_requested_types_| will reflect the newest set of requested types. + bool needs_reconfigure_; + + // The reason for the last reconfigure attempt. Note: this will be set to a + // valid value only when |needs_reconfigure_| is set. + syncer::ConfigureReason last_configure_reason_; + + // The last time Restart() was called. + base::Time last_restart_time_; + + // The accumulated time spent between calls to Restart() and going + // to the DONE state. + base::TimeDelta configure_time_delta_; + + // Sync's datatype debug info listener, which we pass model association + // statistics to. + const syncer::WeakHandle<syncer::DataTypeDebugInfoListener> + debug_info_listener_; + + // The manager that handles the model association of the individual types. + ModelAssociationManager model_association_manager_; + + // DataTypeManager must have only one observer -- the ProfileSyncService that + // created it and manages its lifetime. + DataTypeManagerObserver* const observer_; + + // For querying failed data types (having unrecoverable error) when + // configuring backend. + DataTypeStatusTable data_type_status_table_; + + // Types waiting to be downloaded. + TypeSetPriorityList download_types_queue_; + + // Types waiting for association and related time tracking info. + struct AssociationTypesInfo { + AssociationTypesInfo(); + AssociationTypesInfo(const AssociationTypesInfo& other); + ~AssociationTypesInfo(); + + // Types to associate. + syncer::ModelTypeSet types; + // Types that have just been downloaded and are being associated for the + // first time. This includes types that had previously encountered an error + // and had to be purged/unapplied from the sync db. + // This is a subset of |types|. + syncer::ModelTypeSet first_sync_types; + // Types that were already ready for association at configuration time. + syncer::ModelTypeSet ready_types; + // Time at which |types| began downloading. + base::Time download_start_time; + // Time at which |types| finished downloading. + base::Time download_ready_time; + // Time at which the association for |read_types| began. + base::Time ready_association_request_time; + // Time at which the association for |types| began (not relevant to + // |ready_types|. + base::Time full_association_request_time; + // The set of types that are higher priority (and were therefore blocking) + // the association of |types|. + syncer::ModelTypeSet high_priority_types_before; + // The subset of |types| that were successfully configured. + syncer::ModelTypeSet configured_types; + }; + std::queue<AssociationTypesInfo> association_types_queue_; + + // The encryption handler lets the DataTypeManager know the state of sync + // datatype encryption. + const DataTypeEncryptionHandler* encryption_handler_; + + // Association and time stats of data type configuration. + std::vector<syncer::DataTypeConfigurationStats> configuration_stats_; + + // True iff we are in the process of catching up datatypes. + bool catch_up_in_progress_; + + // Configuration process is started when ModelAssociationManager notifies + // DataTypeManager that all types are ready for configure. + // This flag ensures that this process is started only once. + bool download_started_; + + base::WeakPtrFactory<DataTypeManagerImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(DataTypeManagerImpl); +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_IMPL_H__
diff --git a/components/sync/driver/data_type_manager_impl_unittest.cc b/components/sync/driver/data_type_manager_impl_unittest.cc new file mode 100644 index 0000000..ea42b30 --- /dev/null +++ b/components/sync/driver/data_type_manager_impl_unittest.cc
@@ -0,0 +1,1658 @@ +// 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 "components/sync/driver/data_type_manager_impl.h" + +#include "base/compiler_specific.h" +#include "base/message_loop/message_loop.h" +#include "components/sync/base/model_type.h" +#include "components/sync/core/activation_context.h" +#include "components/sync/core/configure_reason.h" +#include "components/sync/driver/backend_data_type_configurer.h" +#include "components/sync/driver/data_type_encryption_handler.h" +#include "components/sync/driver/data_type_manager_observer.h" +#include "components/sync/driver/data_type_status_table.h" +#include "components/sync/driver/fake_data_type_controller.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace sync_driver { + +using syncer::SyncError; +using syncer::ModelType; +using syncer::ModelTypeSet; +using syncer::ModelTypeToString; +using syncer::BOOKMARKS; +using syncer::APPS; +using syncer::PASSWORDS; +using syncer::PREFERENCES; +using syncer::NIGORI; + +namespace { + +// Helper for unioning with control types. +ModelTypeSet AddControlTypesTo(ModelTypeSet types) { + ModelTypeSet result = syncer::ControlTypes(); + result.PutAll(types); + return result; +} + +DataTypeStatusTable BuildStatusTable(ModelTypeSet crypto_errors, + ModelTypeSet association_errors, + ModelTypeSet unready_errors, + ModelTypeSet unrecoverable_errors) { + DataTypeStatusTable::TypeErrorMap error_map; + for (ModelTypeSet::Iterator iter = crypto_errors.First(); iter.Good(); + iter.Inc()) { + error_map[iter.Get()] = SyncError(FROM_HERE, SyncError::CRYPTO_ERROR, + "crypto error expected", iter.Get()); + } + for (ModelTypeSet::Iterator iter = association_errors.First(); iter.Good(); + iter.Inc()) { + error_map[iter.Get()] = SyncError(FROM_HERE, SyncError::DATATYPE_ERROR, + "association error expected", iter.Get()); + } + for (ModelTypeSet::Iterator iter = unready_errors.First(); iter.Good(); + iter.Inc()) { + error_map[iter.Get()] = SyncError(FROM_HERE, SyncError::UNREADY_ERROR, + "unready error expected", iter.Get()); + } + for (ModelTypeSet::Iterator iter = unrecoverable_errors.First(); iter.Good(); + iter.Inc()) { + error_map[iter.Get()] = + SyncError(FROM_HERE, SyncError::UNRECOVERABLE_ERROR, + "unrecoverable error expected", iter.Get()); + } + DataTypeStatusTable status_table; + status_table.UpdateFailedDataTypes(error_map); + return status_table; +} + +// Fake BackendDataTypeConfigurer implementation that simply stores away the +// callback passed into ConfigureDataTypes. +class FakeBackendDataTypeConfigurer : public BackendDataTypeConfigurer { + public: + FakeBackendDataTypeConfigurer() : configure_call_count_(0) {} + ~FakeBackendDataTypeConfigurer() override {} + + syncer::ModelTypeSet ConfigureDataTypes( + syncer::ConfigureReason reason, + const DataTypeConfigStateMap& config_state_map, + const base::Callback<void(ModelTypeSet, ModelTypeSet)>& ready_task, + const base::Callback<void()>& retry_callback) override { + configure_call_count_++; + last_ready_task_ = ready_task; + + for (auto iter = expected_configure_types_.begin(); + iter != expected_configure_types_.end(); ++iter) { + if (!iter->second.Empty()) { + EXPECT_TRUE(iter->second == + GetDataTypesInState(iter->first, config_state_map)) + << "State " << iter->first << " : " + << ModelTypeSetToString(iter->second) << " v.s. " + << ModelTypeSetToString( + GetDataTypesInState(iter->first, config_state_map)); + } + } + return ready_types_; + } + + void ActivateDirectoryDataType(syncer::ModelType type, + syncer::ModelSafeGroup group, + ChangeProcessor* change_processor) override { + activated_types_.Put(type); + } + void DeactivateDirectoryDataType(syncer::ModelType type) override { + activated_types_.Remove(type); + } + + void ActivateNonBlockingDataType(syncer::ModelType type, + std::unique_ptr<syncer_v2::ActivationContext> + activation_context) override { + // TODO(stanisc): crbug.com/515962: Add test coverage. + } + + void DeactivateNonBlockingDataType(syncer::ModelType type) override { + // TODO(stanisc): crbug.com/515962: Add test coverage. + } + + base::Callback<void(ModelTypeSet, ModelTypeSet)> last_ready_task() const { + return last_ready_task_; + } + + void set_expected_configure_types(DataTypeConfigState config_state, + ModelTypeSet types) { + expected_configure_types_[config_state] = types; + } + + void set_ready_types(ModelTypeSet types) { ready_types_ = types; } + + const ModelTypeSet activated_types() { return activated_types_; } + + int configure_call_count() const { return configure_call_count_; } + + private: + base::Callback<void(ModelTypeSet, ModelTypeSet)> last_ready_task_; + std::map<DataTypeConfigState, ModelTypeSet> expected_configure_types_; + ModelTypeSet activated_types_; + ModelTypeSet ready_types_; + int configure_call_count_; +}; + +// DataTypeManagerObserver implementation. +class FakeDataTypeManagerObserver : public DataTypeManagerObserver { + public: + FakeDataTypeManagerObserver() { ResetExpectations(); } + ~FakeDataTypeManagerObserver() override { + EXPECT_FALSE(start_expected_); + DataTypeManager::ConfigureResult default_result; + EXPECT_EQ(done_expectation_.status, default_result.status); + EXPECT_TRUE( + done_expectation_.data_type_status_table.GetFailedTypes().Empty()); + } + + void ExpectStart() { start_expected_ = true; } + void ExpectDone(const DataTypeManager::ConfigureResult& result) { + done_expectation_ = result; + } + void ResetExpectations() { + start_expected_ = false; + done_expectation_ = DataTypeManager::ConfigureResult(); + } + + void OnConfigureDone( + const DataTypeManager::ConfigureResult& result) override { + EXPECT_EQ(done_expectation_.status, result.status); + DataTypeStatusTable::TypeErrorMap errors = + result.data_type_status_table.GetAllErrors(); + DataTypeStatusTable::TypeErrorMap expected_errors = + done_expectation_.data_type_status_table.GetAllErrors(); + ASSERT_EQ(expected_errors.size(), errors.size()); + for (DataTypeStatusTable::TypeErrorMap::const_iterator iter = + expected_errors.begin(); + iter != expected_errors.end(); ++iter) { + ASSERT_TRUE(errors.find(iter->first) != errors.end()); + ASSERT_EQ(iter->second.error_type(), + errors.find(iter->first)->second.error_type()); + } + done_expectation_ = DataTypeManager::ConfigureResult(); + } + + void OnConfigureStart() override { + EXPECT_TRUE(start_expected_); + start_expected_ = false; + } + + private: + bool start_expected_ = true; + DataTypeManager::ConfigureResult done_expectation_; +}; + +class FakeDataTypeEncryptionHandler : public DataTypeEncryptionHandler { + public: + FakeDataTypeEncryptionHandler(); + ~FakeDataTypeEncryptionHandler() override; + + bool IsPassphraseRequired() const override; + ModelTypeSet GetEncryptedDataTypes() const override; + + void set_passphrase_required(bool passphrase_required) { + passphrase_required_ = passphrase_required; + } + void set_encrypted_types(ModelTypeSet encrypted_types) { + encrypted_types_ = encrypted_types; + } + + private: + bool passphrase_required_; + ModelTypeSet encrypted_types_; +}; + +FakeDataTypeEncryptionHandler::FakeDataTypeEncryptionHandler() + : passphrase_required_(false) {} +FakeDataTypeEncryptionHandler::~FakeDataTypeEncryptionHandler() {} + +bool FakeDataTypeEncryptionHandler::IsPassphraseRequired() const { + return passphrase_required_; +} + +ModelTypeSet FakeDataTypeEncryptionHandler::GetEncryptedDataTypes() const { + return encrypted_types_; +} + +} // namespace + +class TestDataTypeManager : public DataTypeManagerImpl { + public: + TestDataTypeManager( + const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& + debug_info_listener, + BackendDataTypeConfigurer* configurer, + const DataTypeController::TypeMap* controllers, + const DataTypeEncryptionHandler* encryption_handler, + DataTypeManagerObserver* observer) + : DataTypeManagerImpl(debug_info_listener, + controllers, + encryption_handler, + configurer, + observer), + custom_priority_types_(syncer::ControlTypes()) {} + + void set_priority_types(const ModelTypeSet& priority_types) { + custom_priority_types_ = priority_types; + } + + DataTypeManager::ConfigureResult configure_result() const { + return configure_result_; + } + + void OnModelAssociationDone( + const DataTypeManager::ConfigureResult& result) override { + configure_result_ = result; + DataTypeManagerImpl::OnModelAssociationDone(result); + } + + private: + ModelTypeSet GetPriorityTypes() const override { + return custom_priority_types_; + } + + ModelTypeSet custom_priority_types_; + DataTypeManager::ConfigureResult configure_result_; +}; + +// The actual test harness class, parametrized on nigori state (i.e., tests are +// run both configuring with nigori, and configuring without). +class SyncDataTypeManagerImplTest : public testing::Test { + public: + SyncDataTypeManagerImplTest() {} + + ~SyncDataTypeManagerImplTest() override {} + + protected: + void SetUp() override { + dtm_.reset(new TestDataTypeManager( + syncer::WeakHandle<syncer::DataTypeDebugInfoListener>(), &configurer_, + &controllers_, &encryption_handler_, &observer_)); + } + + void SetConfigureStartExpectation() { observer_.ExpectStart(); } + + void SetConfigureDoneExpectation(DataTypeManager::ConfigureStatus status, + const DataTypeStatusTable& status_table) { + DataTypeManager::ConfigureResult result; + result.status = status; + result.data_type_status_table = status_table; + observer_.ExpectDone(result); + } + + // Configure the given DTM with the given desired types. + void Configure(DataTypeManagerImpl* dtm, const ModelTypeSet& desired_types) { + dtm->Configure(desired_types, syncer::CONFIGURE_REASON_RECONFIGURATION); + } + + // Finish downloading for the given DTM. Should be done only after + // a call to Configure(). + void FinishDownload(const DataTypeManager& dtm, + ModelTypeSet types_to_configure, + ModelTypeSet failed_download_types) { + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm.state()); + ASSERT_FALSE(configurer_.last_ready_task().is_null()); + configurer_.last_ready_task().Run( + syncer::Difference(types_to_configure, failed_download_types), + failed_download_types); + } + + // Adds a fake controller for the given type to |controllers_|. + // Should be called only before setting up the DTM. + void AddController(ModelType model_type) { + controllers_[model_type] = new FakeDataTypeController(model_type); + } + + // Gets the fake controller for the given type, which should have + // been previously added via AddController(). + scoped_refptr<FakeDataTypeController> GetController( + ModelType model_type) const { + DataTypeController::TypeMap::const_iterator it = + controllers_.find(model_type); + if (it == controllers_.end()) { + return NULL; + } + return make_scoped_refptr( + static_cast<FakeDataTypeController*>(it->second.get())); + } + + void FailEncryptionFor(ModelTypeSet encrypted_types) { + encryption_handler_.set_passphrase_required(true); + encryption_handler_.set_encrypted_types(encrypted_types); + } + + base::MessageLoopForUI ui_loop_; + DataTypeController::TypeMap controllers_; + FakeBackendDataTypeConfigurer configurer_; + FakeDataTypeManagerObserver observer_; + std::unique_ptr<TestDataTypeManager> dtm_; + FakeDataTypeEncryptionHandler encryption_handler_; +}; + +// Set up a DTM with no controllers, configure it, finish downloading, +// and then stop it. +TEST_F(SyncDataTypeManagerImplTest, NoControllers) { + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + + Configure(dtm_.get(), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + + dtm_->Stop(); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); +} + +// Set up a DTM with a single controller, configure it, finish +// downloading, finish starting the controller, and then stop the DTM. +TEST_F(SyncDataTypeManagerImplTest, ConfigureOne) { + AddController(BOOKMARKS); + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(1U, configurer_.activated_types().Size()); + + dtm_->Stop(); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + EXPECT_TRUE(configurer_.activated_types().Empty()); +} + +// Set up a DTM with a single controller, configure it, but stop it +// before finishing the download. It should still be safe to run the +// download callback even after the DTM is stopped and destroyed. +TEST_F(SyncDataTypeManagerImplTest, ConfigureOneStopWhileDownloadPending) { + AddController(BOOKMARKS); + + { + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::ABORTED, + DataTypeStatusTable()); + + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + dtm_->Stop(); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + } + + configurer_.last_ready_task().Run(ModelTypeSet(BOOKMARKS), ModelTypeSet()); + EXPECT_TRUE(configurer_.activated_types().Empty()); +} + +// Set up a DTM with a single controller, configure it, finish +// downloading, but stop the DTM before the controller finishes +// starting up. It should still be safe to finish starting up the +// controller even after the DTM is stopped and destroyed. +TEST_F(SyncDataTypeManagerImplTest, ConfigureOneStopWhileStartingModel) { + AddController(BOOKMARKS); + + { + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::ABORTED, + DataTypeStatusTable()); + + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + dtm_->Stop(); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + dtm_.reset(); + } + + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_TRUE(configurer_.activated_types().Empty()); +} + +// Set up a DTM with a single controller, configure it, finish +// downloading, start the controller's model, but stop the DTM before +// the controller finishes starting up. It should still be safe to +// finish starting up the controller even after the DTM is stopped and +// destroyed. +TEST_F(SyncDataTypeManagerImplTest, ConfigureOneStopWhileAssociating) { + AddController(BOOKMARKS); + + { + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::ABORTED, + DataTypeStatusTable()); + + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + EXPECT_TRUE(configurer_.activated_types().Empty()); + + dtm_->Stop(); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + dtm_.reset(); + } + + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_TRUE(configurer_.activated_types().Empty()); +} + +// Set up a DTM with a single controller. Then: +// +// 1) Configure. +// 2) Finish the download for step 1. +// 3) Finish starting the controller with the NEEDS_CRYPTO status. +// 4) Complete download for the reconfiguration without the controller. +// 5) Stop the DTM. +TEST_F(SyncDataTypeManagerImplTest, OneWaitingForCrypto) { + AddController(PASSWORDS); + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation( + DataTypeManager::OK, + BuildStatusTable(ModelTypeSet(PASSWORDS), ModelTypeSet(), ModelTypeSet(), + ModelTypeSet())); + + const ModelTypeSet types(PASSWORDS); + dtm_->set_priority_types(AddControlTypesTo(types)); + + // Step 1. + Configure(dtm_.get(), types); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 2. + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 3. + FailEncryptionFor(types); + GetController(PASSWORDS)->FinishStart(DataTypeController::NEEDS_CRYPTO); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 4. + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + + // Step 5. + dtm_->Stop(); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); +} + +// Set up a DTM with two controllers. Then: +// +// 1) Configure with first controller. +// 2) Finish the download for step 1. +// 3) Finish starting the first controller. +// 4) Configure with both controllers. +// 5) Finish the download for step 4. +// 6) Finish starting the second controller. +// 7) Stop the DTM. +TEST_F(SyncDataTypeManagerImplTest, ConfigureOneThenBoth) { + AddController(BOOKMARKS); + AddController(PREFERENCES); + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + + // Step 1. + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 2. + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 3. + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + + observer_.ResetExpectations(); + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + + // Step 4. + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 5. + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 6. + GetController(PREFERENCES)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(2U, configurer_.activated_types().Size()); + + // Step 7. + dtm_->Stop(); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + EXPECT_TRUE(configurer_.activated_types().Empty()); +} + +// Set up a DTM with two controllers. Then: +// +// 1) Configure with first controller. +// 2) Finish the download for step 1. +// 3) Finish starting the first controller. +// 4) Configure with second controller. +// 5) Finish the download for step 4. +// 6) Finish starting the second controller. +// 7) Stop the DTM. +TEST_F(SyncDataTypeManagerImplTest, ConfigureOneThenSwitch) { + AddController(BOOKMARKS); + AddController(PREFERENCES); + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + + // Step 1. + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 2. + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 3. + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + + observer_.ResetExpectations(); + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + + // Step 4. + Configure(dtm_.get(), ModelTypeSet(PREFERENCES)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 5. + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 6. + GetController(PREFERENCES)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(1U, configurer_.activated_types().Size()); + + // Step 7. + dtm_->Stop(); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + EXPECT_TRUE(configurer_.activated_types().Empty()); +} + +// Set up a DTM with two controllers. Then: +// +// 1) Configure with first controller. +// 2) Finish the download for step 1. +// 3) Configure with both controllers. +// 4) Finish starting the first controller. +// 5) Finish the download for step 3. +// 6) Finish starting the second controller. +// 7) Stop the DTM. +TEST_F(SyncDataTypeManagerImplTest, ConfigureWhileOneInFlight) { + AddController(BOOKMARKS); + AddController(PREFERENCES); + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + + // Step 1. + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 2. + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 3. + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 4. + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 5. + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 6. + GetController(PREFERENCES)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(2U, configurer_.activated_types().Size()); + + // Step 7. + dtm_->Stop(); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + EXPECT_TRUE(configurer_.activated_types().Empty()); +} + +// Set up a DTM with one controller. Then configure, finish +// downloading, and start the controller with an unrecoverable error. +// The unrecoverable error should cause the DTM to stop. +TEST_F(SyncDataTypeManagerImplTest, OneFailingController) { + AddController(BOOKMARKS); + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation( + DataTypeManager::UNRECOVERABLE_ERROR, + BuildStatusTable(ModelTypeSet(), ModelTypeSet(), ModelTypeSet(), + ModelTypeSet(BOOKMARKS))); + + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + EXPECT_TRUE(configurer_.activated_types().Empty()); + + GetController(BOOKMARKS)->FinishStart( + DataTypeController::UNRECOVERABLE_ERROR); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + EXPECT_TRUE(configurer_.activated_types().Empty()); +} + +// Set up a DTM with two controllers. Then: +// +// 1) Configure with both controllers. +// 2) Finish the download for step 1. +// 3) Finish starting the first controller successfully. +// 4) Finish starting the second controller with an unrecoverable error. +// +// The failure from step 4 should cause the DTM to stop. +TEST_F(SyncDataTypeManagerImplTest, SecondControllerFails) { + AddController(BOOKMARKS); + AddController(PREFERENCES); + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation( + DataTypeManager::UNRECOVERABLE_ERROR, + BuildStatusTable(ModelTypeSet(), ModelTypeSet(), ModelTypeSet(), + ModelTypeSet(PREFERENCES))); + + // Step 1. + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 2. + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 3. + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 4. + GetController(PREFERENCES) + ->FinishStart(DataTypeController::UNRECOVERABLE_ERROR); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); +} + +// Set up a DTM with two controllers. Then: +// +// 1) Configure with both controllers. +// 2) Finish the download for step 1. +// 3) Finish starting the first controller successfully. +// 4) Finish starting the second controller with an association failure. +// 5) Finish the purge/reconfigure without the failed type. +// 6) Stop the DTM. +// +// The association failure from step 3 should be ignored. +// +// TODO(akalin): Check that the data type that failed association is +// recorded in the CONFIGURE_DONE notification. +TEST_F(SyncDataTypeManagerImplTest, OneControllerFailsAssociation) { + AddController(BOOKMARKS); + AddController(PREFERENCES); + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation( + DataTypeManager::OK, + BuildStatusTable(ModelTypeSet(), ModelTypeSet(PREFERENCES), + ModelTypeSet(), ModelTypeSet())); + + // Step 1. + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 2. + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 3. + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 4. + GetController(PREFERENCES) + ->FinishStart(DataTypeController::ASSOCIATION_FAILED); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 5. + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(1U, configurer_.activated_types().Size()); + + // Step 6. + dtm_->Stop(); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + EXPECT_TRUE(configurer_.activated_types().Empty()); +} + +// Set up a DTM with two controllers. Then: +// +// 1) Configure with first controller. +// 2) Configure with both controllers. +// 3) Finish the download for step 1. +// 4) Finish the download for step 2. +// 5) Finish starting both controllers. +// 6) Stop the DTM. +TEST_F(SyncDataTypeManagerImplTest, ConfigureWhileDownloadPending) { + AddController(BOOKMARKS); + AddController(PREFERENCES); + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + + // Step 1. + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 2. + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 3. + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 4. + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 5. + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + GetController(PREFERENCES)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + + // Step 6. + dtm_->Stop(); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); +} + +// Set up a DTM with two controllers. Then: +// +// 1) Configure with first controller. +// 2) Configure with both controllers. +// 3) Finish the download for step 1 with a failed data type. +// 4) Finish the download for step 2 successfully. +// 5) Finish starting both controllers. +// 6) Stop the DTM. +// +// The failure from step 3 should be ignored since there's a +// reconfigure pending from step 2. +TEST_F(SyncDataTypeManagerImplTest, ConfigureWhileDownloadPendingWithFailure) { + AddController(BOOKMARKS); + AddController(PREFERENCES); + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + + // Step 1. + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 2. + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 3. + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 4. + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Step 5. + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + GetController(PREFERENCES)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + + // Step 6. + dtm_->Stop(); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); +} + +// Tests a Purge then Configure. This is similar to the sequence of +// operations that would be invoked by the BackendMigrator. +TEST_F(SyncDataTypeManagerImplTest, MigrateAll) { + AddController(BOOKMARKS); + dtm_->set_priority_types(AddControlTypesTo(ModelTypeSet(BOOKMARKS))); + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + + // Initial setup. + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + + // We've now configured bookmarks and (implicitly) the control types. + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + observer_.ResetExpectations(); + + // Pretend we were told to migrate all types. + ModelTypeSet to_migrate; + to_migrate.Put(BOOKMARKS); + to_migrate.PutAll(syncer::ControlTypes()); + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + dtm_->PurgeForMigration(to_migrate, syncer::CONFIGURE_REASON_MIGRATION); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // The DTM will call ConfigureDataTypes(), even though it is unnecessary. + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + observer_.ResetExpectations(); + + // Re-enable the migrated types. + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + Configure(dtm_.get(), to_migrate); + FinishDownload(*dtm_, to_migrate, ModelTypeSet()); + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); +} + +// Test receipt of a Configure request while a purge is in flight. +TEST_F(SyncDataTypeManagerImplTest, ConfigureDuringPurge) { + AddController(BOOKMARKS); + AddController(PREFERENCES); + + // Initial configure. + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + observer_.ResetExpectations(); + + // Purge the Nigori type. + SetConfigureStartExpectation(); + dtm_->PurgeForMigration(ModelTypeSet(NIGORI), + syncer::CONFIGURE_REASON_MIGRATION); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + observer_.ResetExpectations(); + + // Before the backend configuration completes, ask for a different + // set of types. This request asks for + // - BOOKMARKS: which is redundant because it was already enabled, + // - PREFERENCES: which is new and will need to be downloaded, and + // - NIGORI: (added implicitly because it is a control type) which + // the DTM is part-way through purging. + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Invoke the callback we've been waiting for since we asked to purge NIGORI. + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + observer_.ResetExpectations(); + + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Now invoke the callback for the second configure request. + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Start the preferences controller. We don't need to start controller for + // the NIGORI because it has none. We don't need to start the controller for + // the BOOKMARKS because it was never stopped. + GetController(PREFERENCES)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); +} + +TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfiguration) { + AddController(BOOKMARKS); + AddController(PREFERENCES); + + dtm_->set_priority_types(AddControlTypesTo(ModelTypeSet(PREFERENCES))); + + // Initial configure. + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + + // Initially only PREFERENCES is configured. + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, + AddControlTypesTo(ModelTypeSet(PREFERENCES))); + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // BOOKMARKS is configured after download of PREFERENCES finishes. + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, ModelTypeSet(BOOKMARKS)); + FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + GetController(PREFERENCES)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); +} + +TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfigurationReconfigure) { + AddController(BOOKMARKS); + AddController(PREFERENCES); + AddController(APPS); + + dtm_->set_priority_types(AddControlTypesTo(ModelTypeSet(PREFERENCES))); + + // Initial configure. + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + + // Reconfigure while associating PREFERENCES and downloading BOOKMARKS. + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, + AddControlTypesTo(ModelTypeSet(PREFERENCES))); + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, ModelTypeSet(BOOKMARKS)); + FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Enable syncing for APPS. + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES, APPS)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Reconfiguration starts after downloading and association of previous + // types finish. + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, + AddControlTypesTo(ModelTypeSet(PREFERENCES))); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + GetController(PREFERENCES)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, + ModelTypeSet(BOOKMARKS, APPS)); + FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, APPS), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Skip calling FinishStart() for PREFENCES because it's already started in + // first configuration. + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + GetController(APPS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); +} + +TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfigurationStop) { + AddController(BOOKMARKS); + AddController(PREFERENCES); + + dtm_->set_priority_types(AddControlTypesTo(ModelTypeSet(PREFERENCES))); + + // Initial configure. + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::ABORTED, DataTypeStatusTable()); + + // Initially only PREFERENCES is configured. + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, + AddControlTypesTo(ModelTypeSet(PREFERENCES))); + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // BOOKMARKS is configured after download of PREFERENCES finishes. + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, ModelTypeSet(BOOKMARKS)); + FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // PREFERENCES controller is associating while BOOKMARKS is downloading. + EXPECT_EQ(DataTypeController::ASSOCIATING, + GetController(PREFERENCES)->state()); + EXPECT_EQ(DataTypeController::MODEL_LOADED, + GetController(BOOKMARKS)->state()); + + dtm_->Stop(); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + EXPECT_EQ(DataTypeController::NOT_RUNNING, + GetController(PREFERENCES)->state()); + EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); +} + +TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfigurationDownloadError) { + AddController(BOOKMARKS); + AddController(PREFERENCES); + + dtm_->set_priority_types(AddControlTypesTo(ModelTypeSet(PREFERENCES))); + + // Initial configure. Bookmarks will fail to associate due to the download + // failure. + SetConfigureStartExpectation(); + SetConfigureDoneExpectation( + DataTypeManager::OK, + BuildStatusTable(ModelTypeSet(), ModelTypeSet(BOOKMARKS), ModelTypeSet(), + ModelTypeSet())); + + // Initially only PREFERENCES is configured. + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, + AddControlTypesTo(ModelTypeSet(PREFERENCES))); + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // BOOKMARKS is configured after download of PREFERENCES finishes. + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, ModelTypeSet(BOOKMARKS)); + FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // PREFERENCES controller is associating while BOOKMARKS is downloading. + EXPECT_EQ(DataTypeController::ASSOCIATING, + GetController(PREFERENCES)->state()); + EXPECT_EQ(DataTypeController::MODEL_LOADED, + GetController(BOOKMARKS)->state()); + + // Make BOOKMARKS download fail. Preferences is still associating. + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet(BOOKMARKS)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + EXPECT_EQ(DataTypeController::ASSOCIATING, + GetController(PREFERENCES)->state()); + + // Finish association of PREFERENCES. This will trigger a reconfiguration to + // disable bookmarks. + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, + AddControlTypesTo(ModelTypeSet(PREFERENCES))); + GetController(PREFERENCES)->FinishStart(DataTypeController::OK); + FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(DataTypeController::RUNNING, GetController(PREFERENCES)->state()); + EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); +} + +TEST_F(SyncDataTypeManagerImplTest, HighPriorityAssociationFailure) { + AddController(PREFERENCES); // Will fail. + AddController(BOOKMARKS); // Will succeed. + + dtm_->set_priority_types(AddControlTypesTo(ModelTypeSet(PREFERENCES))); + + // Initial configure. + SetConfigureStartExpectation(); + SetConfigureDoneExpectation( + DataTypeManager::OK, + BuildStatusTable(ModelTypeSet(), ModelTypeSet(PREFERENCES), + ModelTypeSet(), ModelTypeSet())); + + // Initially only PREFERENCES is configured. + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, + AddControlTypesTo(ModelTypeSet(PREFERENCES))); + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // BOOKMARKS is configured after download of PREFERENCES finishes. + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, ModelTypeSet(BOOKMARKS)); + FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // PREFERENCES controller is associating while BOOKMARKS is downloading. + EXPECT_EQ(DataTypeController::ASSOCIATING, + GetController(PREFERENCES)->state()); + EXPECT_EQ(DataTypeController::MODEL_LOADED, + GetController(BOOKMARKS)->state()); + + // Make PREFERENCES association fail. + GetController(PREFERENCES) + ->FinishStart(DataTypeController::ASSOCIATION_FAILED); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Reconfigure without PREFERENCES after the BOOKMARKS download completes, + // then reconfigure with BOOKMARKS. + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, syncer::ControlTypes()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, ModelTypeSet(BOOKMARKS)); + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + + // Reconfigure with BOOKMARKS. + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + EXPECT_EQ(DataTypeController::ASSOCIATING, GetController(BOOKMARKS)->state()); + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(DataTypeController::NOT_RUNNING, + GetController(PREFERENCES)->state()); + EXPECT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state()); +} + +TEST_F(SyncDataTypeManagerImplTest, LowPriorityAssociationFailure) { + AddController(PREFERENCES); // Will succeed. + AddController(BOOKMARKS); // Will fail. + + dtm_->set_priority_types(AddControlTypesTo(ModelTypeSet(PREFERENCES))); + + // Initial configure. + SetConfigureStartExpectation(); + SetConfigureDoneExpectation( + DataTypeManager::OK, + BuildStatusTable(ModelTypeSet(), ModelTypeSet(BOOKMARKS), ModelTypeSet(), + ModelTypeSet())); + + // Initially only PREFERENCES is configured. + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, + AddControlTypesTo(ModelTypeSet(PREFERENCES))); + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // BOOKMARKS is configured after download of PREFERENCES finishes. + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, ModelTypeSet(BOOKMARKS)); + FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // PREFERENCES controller is associating while BOOKMARKS is downloading. + EXPECT_EQ(DataTypeController::ASSOCIATING, + GetController(PREFERENCES)->state()); + EXPECT_EQ(DataTypeController::MODEL_LOADED, + GetController(BOOKMARKS)->state()); + + // BOOKMARKS finishes downloading and PREFERENCES finishes associating. + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + GetController(PREFERENCES)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeController::RUNNING, GetController(PREFERENCES)->state()); + + // Make BOOKMARKS association fail, which triggers reconfigure with only + // PREFERENCES. + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, + AddControlTypesTo(ModelTypeSet(PREFERENCES))); + GetController(BOOKMARKS)->FinishStart(DataTypeController::ASSOCIATION_FAILED); + EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Finish configuration with only PREFERENCES. + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(DataTypeController::RUNNING, GetController(PREFERENCES)->state()); + EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); +} + +TEST_F(SyncDataTypeManagerImplTest, FilterDesiredTypes) { + AddController(BOOKMARKS); + + ModelTypeSet types(BOOKMARKS, APPS); + dtm_->set_priority_types(AddControlTypesTo(types)); + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + + ModelTypeSet expected_types = syncer::ControlTypes(); + expected_types.Put(BOOKMARKS); + // APPS is filtered out because there's no controller for it. + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_ACTIVE, expected_types); + Configure(dtm_.get(), types); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + + dtm_->Stop(); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); +} + +TEST_F(SyncDataTypeManagerImplTest, ReenableAfterDataTypeError) { + AddController(PREFERENCES); // Will succeed. + AddController(BOOKMARKS); // Will be disabled due to datatype error. + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation( + DataTypeManager::OK, + BuildStatusTable(ModelTypeSet(), ModelTypeSet(BOOKMARKS), ModelTypeSet(), + ModelTypeSet())); + + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(PREFERENCES, BOOKMARKS), ModelTypeSet()); + GetController(PREFERENCES)->FinishStart(DataTypeController::OK); + GetController(BOOKMARKS)->FinishStart(DataTypeController::ASSOCIATION_FAILED); + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); // Reconfig for error. + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); // Reconfig for error. + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(DataTypeController::RUNNING, GetController(PREFERENCES)->state()); + EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); + + observer_.ResetExpectations(); + + // Re-enable bookmarks. + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + dtm_->ReenableType(syncer::BOOKMARKS); + + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(DataTypeController::RUNNING, GetController(PREFERENCES)->state()); + EXPECT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state()); + + // Should do nothing. + dtm_->ReenableType(syncer::BOOKMARKS); +} + +TEST_F(SyncDataTypeManagerImplTest, UnreadyType) { + AddController(BOOKMARKS); + GetController(BOOKMARKS)->SetReadyForStart(false); + + // Bookmarks is never started due to being unready. + SetConfigureStartExpectation(); + SetConfigureDoneExpectation( + DataTypeManager::OK, + BuildStatusTable(ModelTypeSet(), ModelTypeSet(), ModelTypeSet(BOOKMARKS), + ModelTypeSet())); + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(0U, configurer_.activated_types().Size()); + observer_.ResetExpectations(); + + // Bookmarks should start normally now. + GetController(BOOKMARKS)->SetReadyForStart(true); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + dtm_->ReenableType(BOOKMARKS); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(1U, configurer_.activated_types().Size()); + + // Should do nothing. + observer_.ResetExpectations(); + dtm_->ReenableType(BOOKMARKS); + + dtm_->Stop(); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + EXPECT_TRUE(configurer_.activated_types().Empty()); +} + +TEST_F(SyncDataTypeManagerImplTest, ModelLoadError) { + AddController(BOOKMARKS); + GetController(BOOKMARKS)->SetModelLoadError(syncer::SyncError( + FROM_HERE, SyncError::DATATYPE_ERROR, "load error", BOOKMARKS)); + + // Bookmarks is never started due to hitting a model load error. + SetConfigureStartExpectation(); + SetConfigureDoneExpectation( + DataTypeManager::OK, + BuildStatusTable(ModelTypeSet(), ModelTypeSet(BOOKMARKS), ModelTypeSet(), + ModelTypeSet())); + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); + + EXPECT_EQ(0U, configurer_.activated_types().Size()); +} + +TEST_F(SyncDataTypeManagerImplTest, ErrorBeforeAssociation) { + AddController(BOOKMARKS); + + // Bookmarks is never started due to hitting a datatype error while the DTM + // is still downloading types. + SetConfigureStartExpectation(); + SetConfigureDoneExpectation( + DataTypeManager::OK, + BuildStatusTable(ModelTypeSet(), ModelTypeSet(BOOKMARKS), ModelTypeSet(), + ModelTypeSet())); + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + GetController(BOOKMARKS)->OnSingleDataTypeUnrecoverableError( + syncer::SyncError(FROM_HERE, SyncError::DATATYPE_ERROR, "bookmarks error", + BOOKMARKS)); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); // Reconfig for error. + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); + + EXPECT_EQ(0U, configurer_.activated_types().Size()); +} + +TEST_F(SyncDataTypeManagerImplTest, AssociationNeverCompletes) { + AddController(BOOKMARKS); + + // Bookmarks times out during association and so it's never started. + SetConfigureStartExpectation(); + SetConfigureDoneExpectation( + DataTypeManager::OK, + BuildStatusTable(ModelTypeSet(), ModelTypeSet(BOOKMARKS), ModelTypeSet(), + ModelTypeSet())); + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); + + GetController(BOOKMARKS)->SetDelayModelLoad(); + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Simulate timeout by firing the timer. + dtm_->GetModelAssociationManagerForTesting() + ->GetTimerForTesting() + ->user_task() + .Run(); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); + + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(0U, configurer_.activated_types().Size()); +} + +// Test that sync configures properly if all low priority types are ready. +TEST_F(SyncDataTypeManagerImplTest, AllLowPriorityTypesReady) { + AddController(PREFERENCES); + AddController(BOOKMARKS); + + dtm_->set_priority_types(AddControlTypesTo(ModelTypeSet(PREFERENCES))); + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + + Configure(dtm_.get(), ModelTypeSet(PREFERENCES, BOOKMARKS)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + configurer_.set_ready_types(ModelTypeSet(BOOKMARKS)); + FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); + + // Association of Bookmarks can't happen until higher priority types are + // finished. + EXPECT_EQ(DataTypeController::ASSOCIATING, + GetController(PREFERENCES)->state()); + EXPECT_EQ(DataTypeController::MODEL_LOADED, + GetController(BOOKMARKS)->state()); + + // Because Bookmarks are a ready type, once Preference finishes, Bookmarks + // can start associating immediately (even before the + // BackendDataTypeConfigurer calls back). + GetController(PREFERENCES)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeController::ASSOCIATING, GetController(BOOKMARKS)->state()); + + // Once the association finishes, the DTM should still be waiting for the + // Sync configurer to call back. + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Finishing the download should complete the configuration. + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + EXPECT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state()); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(2U, configurer_.activated_types().Size()); + + dtm_->Stop(); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + EXPECT_TRUE(configurer_.activated_types().Empty()); +} + +// Test that sync configures properly if all high priority types are ready. +TEST_F(SyncDataTypeManagerImplTest, AllHighPriorityTypesReady) { + AddController(PREFERENCES); + AddController(BOOKMARKS); + + dtm_->set_priority_types(AddControlTypesTo(ModelTypeSet(PREFERENCES))); + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + + configurer_.set_ready_types(ModelTypeSet(PREFERENCES)); + Configure(dtm_.get(), ModelTypeSet(PREFERENCES, BOOKMARKS)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Association of Bookmarks can't happen until higher priority types are + // finished, but Preferences should start associating immediately. + EXPECT_EQ(DataTypeController::ASSOCIATING, + GetController(PREFERENCES)->state()); + EXPECT_EQ(DataTypeController::MODEL_LOADED, + GetController(BOOKMARKS)->state()); + + // When Prefs finish associating, configuration should still be waiting for + // the high priority download to finish. + GetController(PREFERENCES)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeController::MODEL_LOADED, + GetController(BOOKMARKS)->state()); + + // Because Bookmarks aren't a ready type, they'll need to wait until the + // low priority download also finishes. + FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); + EXPECT_EQ(DataTypeController::MODEL_LOADED, + GetController(BOOKMARKS)->state()); + + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + EXPECT_EQ(DataTypeController::ASSOCIATING, GetController(BOOKMARKS)->state()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Finishing the Bookmarks association ends the configuration. + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state()); + + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(2U, configurer_.activated_types().Size()); + + dtm_->Stop(); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + EXPECT_TRUE(configurer_.activated_types().Empty()); +} + +// Test that sync configures properly if all types are ready. +TEST_F(SyncDataTypeManagerImplTest, AllTypesReady) { + AddController(PREFERENCES); + AddController(BOOKMARKS); + + dtm_->set_priority_types(AddControlTypesTo(ModelTypeSet(PREFERENCES))); + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + + configurer_.set_ready_types(ModelTypeSet(PREFERENCES)); + Configure(dtm_.get(), ModelTypeSet(PREFERENCES, BOOKMARKS)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Association of Bookmarks can't happen until higher priority types are + // finished, but Preferences should start associating immediately. + EXPECT_EQ(DataTypeController::ASSOCIATING, + GetController(PREFERENCES)->state()); + EXPECT_EQ(DataTypeController::MODEL_LOADED, + GetController(BOOKMARKS)->state()); + + // When Prefs finish associating, configuration should still be waiting for + // the high priority download to finish. + GetController(PREFERENCES)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeController::MODEL_LOADED, + GetController(BOOKMARKS)->state()); + + // Because Bookmarks are a ready type, it can start associating immediately + // after the high priority types finish downloading. + configurer_.set_ready_types(ModelTypeSet(BOOKMARKS)); + FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); + EXPECT_EQ(DataTypeController::ASSOCIATING, GetController(BOOKMARKS)->state()); + + // Finishing the Bookmarks association leaves the DTM waiting for the low + // priority download to finish. + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Finishing the low priority download ends the configuration. + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(2U, configurer_.activated_types().Size()); + + dtm_->Stop(); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + EXPECT_TRUE(configurer_.activated_types().Empty()); +} + +// Test that "catching up" type puts them in the CONFIGURE_CLEAN state. +TEST_F(SyncDataTypeManagerImplTest, CatchUpTypeAddedToConfigureClean) { + AddController(BOOKMARKS); + AddController(PASSWORDS); + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_CLEAN, + AddControlTypesTo(ModelTypeSet(BOOKMARKS, PASSWORDS))); + + dtm_->Configure(ModelTypeSet(BOOKMARKS, PASSWORDS), + syncer::CONFIGURE_REASON_CATCH_UP); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PASSWORDS), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + EXPECT_EQ(1U, configurer_.activated_types().Size()); + GetController(PASSWORDS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(2U, configurer_.activated_types().Size()); + + dtm_->Stop(); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); + EXPECT_TRUE(configurer_.activated_types().Empty()); +} + +// Test that once we start a catch up cycle for a type, the type ends up in the +// clean state and DataTypeManager remains in catch up mode for subsequent +// overlapping cycles. +TEST_F(SyncDataTypeManagerImplTest, CatchUpMultipleConfigureCalls) { + AddController(BOOKMARKS); + AddController(PASSWORDS); + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + + // Configure (catch up) with one type. + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_CLEAN, + AddControlTypesTo(ModelTypeSet(BOOKMARKS))); + dtm_->Configure(ModelTypeSet(BOOKMARKS), syncer::CONFIGURE_REASON_CATCH_UP); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + // Configure with both types before the first one completes. Both types should + // end up in CONFIGURE_CLEAN. + configurer_.set_expected_configure_types( + BackendDataTypeConfigurer::CONFIGURE_CLEAN, + AddControlTypesTo(ModelTypeSet(BOOKMARKS, PASSWORDS))); + dtm_->Configure(ModelTypeSet(BOOKMARKS, PASSWORDS), + syncer::CONFIGURE_REASON_RECONFIGURATION); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PASSWORDS), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + GetController(PASSWORDS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + + dtm_->Stop(); + EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); +} + +// Test that DataTypeManagerImpl delays configuration until all datatypes for +// which ShouldLoadModelBeforeConfigure() returns true loaded their models. +TEST_F(SyncDataTypeManagerImplTest, DelayConfigureForUSSTypes) { + AddController(BOOKMARKS); + GetController(BOOKMARKS)->SetShouldLoadModelBeforeConfigure(true); + GetController(BOOKMARKS)->SetDelayModelLoad(); + + SetConfigureStartExpectation(); + SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); + + Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + // Bookmarks model isn't loaded yet and it is required to complete before + // call to configure. Ensure that configure wasn't called. + EXPECT_EQ(0, configurer_.configure_call_count()); + EXPECT_EQ(0, GetController(BOOKMARKS)->register_with_backend_call_count()); + + // Finishing model load should trigger configure. + GetController(BOOKMARKS)->SimulateModelLoadFinishing(); + EXPECT_EQ(1, configurer_.configure_call_count()); + EXPECT_EQ(1, GetController(BOOKMARKS)->register_with_backend_call_count()); + + FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); + FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); + EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); + + GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); + EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); + EXPECT_EQ(1U, configurer_.activated_types().Size()); +} + +} // namespace sync_driver
diff --git a/components/sync/driver/data_type_manager_mock.cc b/components/sync/driver/data_type_manager_mock.cc new file mode 100644 index 0000000..058c135 --- /dev/null +++ b/components/sync/driver/data_type_manager_mock.cc
@@ -0,0 +1,15 @@ +// 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/location.h" +#include "components/sync/driver/data_type_manager_mock.h" + +namespace sync_driver { + +DataTypeManagerMock::DataTypeManagerMock() + : result_(OK, syncer::ModelTypeSet()) {} + +DataTypeManagerMock::~DataTypeManagerMock() {} + +} // namespace sync_driver
diff --git a/components/sync/driver/data_type_manager_mock.h b/components/sync/driver/data_type_manager_mock.h new file mode 100644 index 0000000..92a54b8 --- /dev/null +++ b/components/sync/driver/data_type_manager_mock.h
@@ -0,0 +1,34 @@ +// 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 COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_MOCK_H__ +#define COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_MOCK_H__ + +#include "components/sync/api/sync_error.h" +#include "components/sync/driver/data_type_manager.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace sync_driver { + +class DataTypeManagerMock : public DataTypeManager { + public: + DataTypeManagerMock(); + virtual ~DataTypeManagerMock(); + + MOCK_METHOD2(Configure, void(syncer::ModelTypeSet, syncer::ConfigureReason)); + MOCK_METHOD1(ReenableType, void(syncer::ModelType)); + MOCK_METHOD0(ResetDataTypeErrors, void()); + MOCK_METHOD2(PurgeForMigration, + void(syncer::ModelTypeSet, syncer::ConfigureReason)); + MOCK_METHOD0(Stop, void()); + MOCK_METHOD0(controllers, const DataTypeController::TypeMap&()); + MOCK_CONST_METHOD0(state, State()); + + private: + DataTypeManager::ConfigureResult result_; +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_MOCK_H__
diff --git a/components/sync/driver/data_type_manager_observer.h b/components/sync/driver/data_type_manager_observer.h new file mode 100644 index 0000000..f6904b6 --- /dev/null +++ b/components/sync/driver/data_type_manager_observer.h
@@ -0,0 +1,26 @@ +// 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 COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_OBSERVER_H_ +#define COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_OBSERVER_H_ + +#include "components/sync/driver/data_type_manager.h" + +namespace sync_driver { + +// Various data type configuration events can be consumed by observing the +// DataTypeManager through this interface. +class DataTypeManagerObserver { + public: + virtual void OnConfigureDone( + const DataTypeManager::ConfigureResult& result) = 0; + virtual void OnConfigureStart() = 0; + + protected: + virtual ~DataTypeManagerObserver() {} +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_OBSERVER_H_
diff --git a/components/sync/driver/data_type_status_table.cc b/components/sync/driver/data_type_status_table.cc new file mode 100644 index 0000000..85d5a2b --- /dev/null +++ b/components/sync/driver/data_type_status_table.cc
@@ -0,0 +1,144 @@ +// 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 "components/sync/driver/data_type_manager.h" +#include "components/sync/driver/data_type_status_table.h" + +namespace sync_driver { + +namespace { + +syncer::ModelTypeSet GetTypesFromErrorMap( + const DataTypeStatusTable::TypeErrorMap& errors) { + syncer::ModelTypeSet result; + for (DataTypeStatusTable::TypeErrorMap::const_iterator it = errors.begin(); + it != errors.end(); ++it) { + DCHECK(!result.Has(it->first)); + result.Put(it->first); + } + return result; +} + +} // namespace + +DataTypeStatusTable::DataTypeStatusTable() {} + +DataTypeStatusTable::DataTypeStatusTable(const DataTypeStatusTable& other) = + default; + +DataTypeStatusTable::~DataTypeStatusTable() {} + +void DataTypeStatusTable::UpdateFailedDataTypes(const TypeErrorMap& errors) { + DVLOG(1) << "Setting " << errors.size() << " new failed types."; + + for (TypeErrorMap::const_iterator iter = errors.begin(); iter != errors.end(); + ++iter) { + syncer::SyncError::ErrorType failure_type = iter->second.error_type(); + switch (failure_type) { + case syncer::SyncError::UNSET: + NOTREACHED(); + break; + case syncer::SyncError::UNRECOVERABLE_ERROR: + unrecoverable_errors_.insert(*iter); + break; + case syncer::SyncError::DATATYPE_ERROR: + case syncer::SyncError::DATATYPE_POLICY_ERROR: + data_type_errors_.insert(*iter); + break; + case syncer::SyncError::CRYPTO_ERROR: + crypto_errors_.insert(*iter); + break; + case syncer::SyncError::PERSISTENCE_ERROR: + persistence_errors_.insert(*iter); + break; + case syncer::SyncError::UNREADY_ERROR: + unready_errors_.insert(*iter); + break; + } + } +} + +void DataTypeStatusTable::Reset() { + DVLOG(1) << "Resetting data type errors."; + unrecoverable_errors_.clear(); + data_type_errors_.clear(); + crypto_errors_.clear(); + persistence_errors_.clear(); + unready_errors_.clear(); +} + +void DataTypeStatusTable::ResetCryptoErrors() { + crypto_errors_.clear(); +} + +void DataTypeStatusTable::ResetPersistenceErrorsFrom( + syncer::ModelTypeSet purged_types) { + for (syncer::ModelTypeSet::Iterator iter = purged_types.First(); iter.Good(); + iter.Inc()) { + persistence_errors_.erase(iter.Get()); + } +} + +bool DataTypeStatusTable::ResetDataTypeErrorFor(syncer::ModelType type) { + return data_type_errors_.erase(type) > 0; +} + +bool DataTypeStatusTable::ResetUnreadyErrorFor(syncer::ModelType type) { + return unready_errors_.erase(type) > 0; +} + +DataTypeStatusTable::TypeErrorMap DataTypeStatusTable::GetAllErrors() const { + TypeErrorMap result; + result.insert(data_type_errors_.begin(), data_type_errors_.end()); + result.insert(crypto_errors_.begin(), crypto_errors_.end()); + result.insert(persistence_errors_.begin(), persistence_errors_.end()); + result.insert(unready_errors_.begin(), unready_errors_.end()); + result.insert(unrecoverable_errors_.begin(), unrecoverable_errors_.end()); + return result; +} + +syncer::ModelTypeSet DataTypeStatusTable::GetFailedTypes() const { + syncer::ModelTypeSet result = GetFatalErrorTypes(); + result.PutAll(GetCryptoErrorTypes()); + result.PutAll(GetUnreadyErrorTypes()); + return result; +} + +syncer::ModelTypeSet DataTypeStatusTable::GetFatalErrorTypes() const { + syncer::ModelTypeSet result; + result.PutAll(GetTypesFromErrorMap(data_type_errors_)); + result.PutAll(GetTypesFromErrorMap(unrecoverable_errors_)); + return result; +} + +syncer::ModelTypeSet DataTypeStatusTable::GetCryptoErrorTypes() const { + syncer::ModelTypeSet result = GetTypesFromErrorMap(crypto_errors_); + return result; +} + +syncer::ModelTypeSet DataTypeStatusTable::GetPersistenceErrorTypes() const { + syncer::ModelTypeSet result = GetTypesFromErrorMap(persistence_errors_); + return result; +} + +syncer::ModelTypeSet DataTypeStatusTable::GetUnreadyErrorTypes() const { + syncer::ModelTypeSet result = GetTypesFromErrorMap(unready_errors_); + return result; +} + +syncer::ModelTypeSet DataTypeStatusTable::GetUnrecoverableErrorTypes() const { + syncer::ModelTypeSet result = GetTypesFromErrorMap(unrecoverable_errors_); + return result; +} + +syncer::SyncError DataTypeStatusTable::GetUnrecoverableError() const { + // Just return the first one. It is assumed all the unrecoverable errors + // have the same cause. The others are just tracked to know which types + // were involved. + return (unrecoverable_errors_.empty() + ? syncer::SyncError() + : unrecoverable_errors_.begin()->second); +} + +} // namespace sync_driver
diff --git a/components/sync/driver/data_type_status_table.h b/components/sync/driver/data_type_status_table.h new file mode 100644 index 0000000..d367b91 --- /dev/null +++ b/components/sync/driver/data_type_status_table.h
@@ -0,0 +1,98 @@ +// 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 COMPONENTS_SYNC_DRIVER_DATA_TYPE_STATUS_TABLE_H_ +#define COMPONENTS_SYNC_DRIVER_DATA_TYPE_STATUS_TABLE_H_ + +#include <map> +#include <string> + +#include "components/sync/driver/data_type_manager.h" + +namespace sync_driver { + +// Class to keep track of data types that have encountered an error during sync. +class DataTypeStatusTable { + public: + typedef std::map<syncer::ModelType, syncer::SyncError> TypeErrorMap; + + DataTypeStatusTable(); + DataTypeStatusTable(const DataTypeStatusTable& other); + ~DataTypeStatusTable(); + + // Copy and assign welcome. + + // Update the failed datatypes. Types will be added to their corresponding + // error map based on their |error_type()|. + void UpdateFailedDataTypes(const TypeErrorMap& errors); + + // Resets the current set of data type errors. + void Reset(); + + // Resets the set of types with cryptographer errors. + void ResetCryptoErrors(); + + // Resets those persistence errors that intersect with |purged_types|. + void ResetPersistenceErrorsFrom(syncer::ModelTypeSet purged_types); + + // Removes |type| from the data_type_errors_ set. Returns true if the type + // was removed from the error set, false if the type did not have a data type + // error to begin with. + bool ResetDataTypeErrorFor(syncer::ModelType type); + + // Removes |type| from the unread_errors_ set. Returns true if the type + // was removed from the error set, false if the type did not have an unready + // error to begin with. + bool ResetUnreadyErrorFor(syncer::ModelType type); + + // Returns a list of all the errors this class has recorded. + TypeErrorMap GetAllErrors() const; + + // Returns all types with failure errors. This includes, fatal, crypto, and + // unready types.` + syncer::ModelTypeSet GetFailedTypes() const; + + // Returns the types that are failing due to unrecoverable or datatype errors. + syncer::ModelTypeSet GetFatalErrorTypes() const; + + // Returns the types that are failing due to cryptographer errors. + syncer::ModelTypeSet GetCryptoErrorTypes() const; + + // Returns the types that are failing due to persistence errors. + syncer::ModelTypeSet GetPersistenceErrorTypes() const; + + // Returns the types that cannot be configured due to not being ready. + syncer::ModelTypeSet GetUnreadyErrorTypes() const; + + // Returns the types that triggered the unrecoverable error. + syncer::ModelTypeSet GetUnrecoverableErrorTypes() const; + + // Returns the current unrecoverable error, if there is one. + syncer::SyncError GetUnrecoverableError() const; + + private: + // The current unrecoverable errors. Only one unrecoverable error can be + // active at a time, but it may apply to more than one type. + TypeErrorMap unrecoverable_errors_; + + // List of data types that failed due to runtime errors and should be + // disabled. These are different from unrecoverable_errors_ in that + // ResetDataTypeError can remove them from this list. + TypeErrorMap data_type_errors_; + + // List of data types that failed due to the cryptographer not being ready. + TypeErrorMap crypto_errors_; + + // List of data types that failed because sync did not persist the newest + // version of their data. + TypeErrorMap persistence_errors_; + + // List of data types that could not start due to not being ready. These can + // be marked as ready by calling ResetUnreadyErrorFor(..). + TypeErrorMap unready_errors_; +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_DATA_TYPE_STATUS_TABLE_H_
diff --git a/components/sync/driver/device_count_metrics_provider.cc b/components/sync/driver/device_count_metrics_provider.cc new file mode 100644 index 0000000..eae31dd --- /dev/null +++ b/components/sync/driver/device_count_metrics_provider.cc
@@ -0,0 +1,36 @@ +// Copyright 2016 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/sync/driver/device_count_metrics_provider.h" + +#include <algorithm> + +#include "base/metrics/sparse_histogram.h" +#include "components/sync/driver/device_info_tracker.h" + +namespace sync_driver { + +DeviceCountMetricsProvider::DeviceCountMetricsProvider( + const ProvideTrackersCallback& provide_trackers) + : provide_trackers_(provide_trackers) {} + +DeviceCountMetricsProvider::~DeviceCountMetricsProvider() {} + +int DeviceCountMetricsProvider::MaxActiveDeviceCount() const { + std::vector<const sync_driver::DeviceInfoTracker*> trackers; + provide_trackers_.Run(&trackers); + int max = 0; + for (auto* tracker : trackers) { + max = std::max(max, tracker->CountActiveDevices()); + } + return max; +} + +void DeviceCountMetricsProvider::ProvideGeneralMetrics( + metrics::ChromeUserMetricsExtension* uma_proto) { + UMA_HISTOGRAM_SPARSE_SLOWLY("Sync.DeviceCount", + std::min(MaxActiveDeviceCount(), 100)); +} + +} // namespace sync_driver
diff --git a/components/sync_driver/device_count_metrics_provider.h b/components/sync/driver/device_count_metrics_provider.h similarity index 100% rename from components/sync_driver/device_count_metrics_provider.h rename to components/sync/driver/device_count_metrics_provider.h
diff --git a/components/sync/driver/device_count_metrics_provider_unittest.cc b/components/sync/driver/device_count_metrics_provider_unittest.cc new file mode 100644 index 0000000..40635f3 --- /dev/null +++ b/components/sync/driver/device_count_metrics_provider_unittest.cc
@@ -0,0 +1,104 @@ +// Copyright 2016 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/sync/driver/device_count_metrics_provider.h" + +#include <memory> +#include <string> +#include <vector> + +#include "base/bind.h" +#include "base/test/histogram_tester.h" +#include "components/sync/driver/device_info.h" +#include "components/sync/driver/device_info_tracker.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace sync_driver { + +namespace { + +class FakeTracker : public DeviceInfoTracker { + public: + explicit FakeTracker(const int count) : count_(count) {} + + // DeviceInfoTracker + bool IsSyncing() const override { return false; } + std::unique_ptr<DeviceInfo> GetDeviceInfo( + const std::string& client_id) const override { + return std::unique_ptr<DeviceInfo>(); + } + ScopedVector<DeviceInfo> GetAllDeviceInfo() const override { + return ScopedVector<DeviceInfo>(); + } + void AddObserver(Observer* observer) override {} + void RemoveObserver(Observer* observer) override {} + int CountActiveDevices() const override { return count_; } + + private: + int count_; +}; + +} // namespace + +class DeviceCountMetricsProviderTest : public testing::Test { + public: + DeviceCountMetricsProviderTest() + : metrics_provider_( + base::Bind(&DeviceCountMetricsProviderTest::GetTrackers, + base::Unretained(this))) {} + + void AddTracker(const int count) { + trackers_.push_back( + std::unique_ptr<DeviceInfoTracker>(new FakeTracker(count))); + } + void GetTrackers(std::vector<const DeviceInfoTracker*>* trackers) { + for (const auto& tracker : trackers_) { + trackers->push_back(tracker.get()); + } + } + + void TestProvider(int expected_device_count) { + base::HistogramTester histogram_tester; + metrics_provider_.ProvideGeneralMetrics(nullptr); + histogram_tester.ExpectUniqueSample("Sync.DeviceCount", + expected_device_count, 1); + } + + private: + DeviceCountMetricsProvider metrics_provider_; + std::vector<std::unique_ptr<DeviceInfoTracker>> trackers_; +}; + +namespace { + +TEST_F(DeviceCountMetricsProviderTest, NoTrackers) { + TestProvider(0); +} + +TEST_F(DeviceCountMetricsProviderTest, SingleTracker) { + AddTracker(2); + TestProvider(2); +} + +TEST_F(DeviceCountMetricsProviderTest, MultipileTrackers) { + AddTracker(1); + AddTracker(5); + AddTracker(-123); + AddTracker(0); + TestProvider(5); +} + +TEST_F(DeviceCountMetricsProviderTest, OnlyNegative) { + AddTracker(-123); + TestProvider(0); +} + +TEST_F(DeviceCountMetricsProviderTest, VeryLarge) { + AddTracker(123456789); + TestProvider(100); +} + +} // namespace + +} // namespace sync_driver
diff --git a/components/sync/driver/device_info.cc b/components/sync/driver/device_info.cc new file mode 100644 index 0000000..e7a7f83 --- /dev/null +++ b/components/sync/driver/device_info.cc
@@ -0,0 +1,113 @@ +// 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/sync/driver/device_info.h" + +#include "base/values.h" + +namespace sync_driver { + +DeviceInfo::DeviceInfo(const std::string& guid, + const std::string& client_name, + const std::string& chrome_version, + const std::string& sync_user_agent, + const sync_pb::SyncEnums::DeviceType device_type, + const std::string& signin_scoped_device_id) + : guid_(guid), + client_name_(client_name), + chrome_version_(chrome_version), + sync_user_agent_(sync_user_agent), + device_type_(device_type), + signin_scoped_device_id_(signin_scoped_device_id) {} + +DeviceInfo::~DeviceInfo() {} + +const std::string& DeviceInfo::guid() const { + return guid_; +} + +const std::string& DeviceInfo::client_name() const { + return client_name_; +} + +const std::string& DeviceInfo::chrome_version() const { + return chrome_version_; +} + +const std::string& DeviceInfo::sync_user_agent() const { + return sync_user_agent_; +} + +const std::string& DeviceInfo::public_id() const { + return public_id_; +} + +sync_pb::SyncEnums::DeviceType DeviceInfo::device_type() const { + return device_type_; +} + +const std::string& DeviceInfo::signin_scoped_device_id() const { + return signin_scoped_device_id_; +} + +std::string DeviceInfo::GetOSString() const { + switch (device_type_) { + case sync_pb::SyncEnums_DeviceType_TYPE_WIN: + return "win"; + case sync_pb::SyncEnums_DeviceType_TYPE_MAC: + return "mac"; + case sync_pb::SyncEnums_DeviceType_TYPE_LINUX: + return "linux"; + case sync_pb::SyncEnums_DeviceType_TYPE_CROS: + return "chrome_os"; + case sync_pb::SyncEnums_DeviceType_TYPE_PHONE: + case sync_pb::SyncEnums_DeviceType_TYPE_TABLET: + // TODO(lipalani): crbug.com/170375. Add support for ios + // phones and tablets. + return "android"; + default: + return "unknown"; + } +} + +std::string DeviceInfo::GetDeviceTypeString() const { + switch (device_type_) { + case sync_pb::SyncEnums_DeviceType_TYPE_WIN: + case sync_pb::SyncEnums_DeviceType_TYPE_MAC: + case sync_pb::SyncEnums_DeviceType_TYPE_LINUX: + case sync_pb::SyncEnums_DeviceType_TYPE_CROS: + return "desktop_or_laptop"; + case sync_pb::SyncEnums_DeviceType_TYPE_PHONE: + return "phone"; + case sync_pb::SyncEnums_DeviceType_TYPE_TABLET: + return "tablet"; + default: + return "unknown"; + } +} + +bool DeviceInfo::Equals(const DeviceInfo& other) const { + return this->guid() == other.guid() && + this->client_name() == other.client_name() && + this->chrome_version() == other.chrome_version() && + this->sync_user_agent() == other.sync_user_agent() && + this->device_type() == other.device_type() && + this->signin_scoped_device_id() == other.signin_scoped_device_id(); +} + +base::DictionaryValue* DeviceInfo::ToValue() { + base::DictionaryValue* value = new base::DictionaryValue(); + value->SetString("name", client_name_); + value->SetString("id", public_id_); + value->SetString("os", GetOSString()); + value->SetString("type", GetDeviceTypeString()); + value->SetString("chromeVersion", chrome_version_); + return value; +} + +void DeviceInfo::set_public_id(const std::string& id) { + public_id_ = id; +} + +} // namespace sync_driver
diff --git a/components/sync_driver/device_info.h b/components/sync/driver/device_info.h similarity index 100% rename from components/sync_driver/device_info.h rename to components/sync/driver/device_info.h
diff --git a/components/sync/driver/device_info_data_type_controller.cc b/components/sync/driver/device_info_data_type_controller.cc new file mode 100644 index 0000000..f42735a --- /dev/null +++ b/components/sync/driver/device_info_data_type_controller.cc
@@ -0,0 +1,49 @@ +// 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 "components/sync/driver/device_info_data_type_controller.h" + +#include "base/callback.h" +#include "components/sync/driver/local_device_info_provider.h" + +namespace sync_driver { + +DeviceInfoDataTypeController::DeviceInfoDataTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const base::Closure& error_callback, + SyncClient* sync_client, + LocalDeviceInfoProvider* local_device_info_provider) + : UIDataTypeController(ui_thread, + error_callback, + syncer::DEVICE_INFO, + sync_client), + local_device_info_provider_(local_device_info_provider) {} + +DeviceInfoDataTypeController::~DeviceInfoDataTypeController() {} + +bool DeviceInfoDataTypeController::StartModels() { + // Start the data type as soon as the local device info gets available. + if (local_device_info_provider_->GetLocalDeviceInfo()) { + return true; + } + + subscription_ = local_device_info_provider_->RegisterOnInitializedCallback( + base::Bind(&DeviceInfoDataTypeController::OnLocalDeviceInfoLoaded, this)); + + return false; +} + +void DeviceInfoDataTypeController::StopModels() { + subscription_.reset(); +} + +void DeviceInfoDataTypeController::OnLocalDeviceInfoLoaded() { + DCHECK_EQ(state_, MODEL_STARTING); + DCHECK(local_device_info_provider_->GetLocalDeviceInfo()); + + subscription_.reset(); + OnModelLoaded(); +} + +} // namespace sync_driver
diff --git a/components/sync/driver/device_info_data_type_controller.h b/components/sync/driver/device_info_data_type_controller.h new file mode 100644 index 0000000..f45dc4b --- /dev/null +++ b/components/sync/driver/device_info_data_type_controller.h
@@ -0,0 +1,44 @@ +// 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 COMPONENTS_SYNC_DRIVER_DEVICE_INFO_DATA_TYPE_CONTROLLER_H_ +#define COMPONENTS_SYNC_DRIVER_DEVICE_INFO_DATA_TYPE_CONTROLLER_H_ + +#include <memory> + +#include "base/macros.h" +#include "base/single_thread_task_runner.h" +#include "components/sync/driver/local_device_info_provider.h" +#include "components/sync/driver/ui_data_type_controller.h" + +namespace sync_driver { + +// DataTypeController for DEVICE_INFO model type. +class DeviceInfoDataTypeController : public UIDataTypeController { + public: + DeviceInfoDataTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const base::Closure& error_callback, + SyncClient* sync_client, + LocalDeviceInfoProvider* local_device_info_provider); + + private: + ~DeviceInfoDataTypeController() override; + + // UIDataTypeController implementations. + bool StartModels() override; + void StopModels() override; + + // Called by LocalDeviceInfoProvider when the local device into becomes + // available. + void OnLocalDeviceInfoLoaded(); + + LocalDeviceInfoProvider* const local_device_info_provider_; + std::unique_ptr<LocalDeviceInfoProvider::Subscription> subscription_; + DISALLOW_COPY_AND_ASSIGN(DeviceInfoDataTypeController); +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_DEVICE_INFO_DATA_TYPE_CONTROLLER_H_
diff --git a/components/sync/driver/device_info_data_type_controller_unittest.cc b/components/sync/driver/device_info_data_type_controller_unittest.cc new file mode 100644 index 0000000..062a409 --- /dev/null +++ b/components/sync/driver/device_info_data_type_controller_unittest.cc
@@ -0,0 +1,126 @@ +// 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 "components/sync/driver/device_info_data_type_controller.h" + +#include "base/bind.h" +#include "base/callback.h" +#include "base/memory/weak_ptr.h" +#include "base/run_loop.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/sync/base/model_type.h" +#include "components/sync/driver/fake_sync_client.h" +#include "components/sync/driver/local_device_info_provider_mock.h" +#include "components/sync/driver/sync_api_component_factory.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace sync_driver { + +namespace { + +class DeviceInfoDataTypeControllerTest : public testing::Test { + public: + DeviceInfoDataTypeControllerTest() + : load_finished_(false), + last_type_(syncer::UNSPECIFIED), + weak_ptr_factory_(this) {} + ~DeviceInfoDataTypeControllerTest() override {} + + void SetUp() override { + local_device_.reset(new LocalDeviceInfoProviderMock( + "cache_guid", "Wayne Gretzky's Hacking Box", "Chromium 10k", + "Chrome 10k", sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id")); + + controller_ = new DeviceInfoDataTypeController( + base::ThreadTaskRunnerHandle::Get(), base::Closure(), &sync_client_, + local_device_.get()); + + load_finished_ = false; + last_type_ = syncer::UNSPECIFIED; + last_error_ = syncer::SyncError(); + } + + void TearDown() override { + controller_ = NULL; + local_device_.reset(); + } + + void Start() { + controller_->LoadModels( + base::Bind(&DeviceInfoDataTypeControllerTest::OnLoadFinished, + weak_ptr_factory_.GetWeakPtr())); + } + + void OnLoadFinished(syncer::ModelType type, syncer::SyncError error) { + load_finished_ = true; + last_type_ = type; + last_error_ = error; + } + + testing::AssertionResult LoadResult() { + if (!load_finished_) { + return testing::AssertionFailure() << "OnLoadFinished wasn't called"; + } + + if (last_error_.IsSet()) { + return testing::AssertionFailure() + << "OnLoadFinished was called with a SyncError: " + << last_error_.ToString(); + } + + if (last_type_ != syncer::DEVICE_INFO) { + return testing::AssertionFailure() + << "OnLoadFinished was called with a wrong sync type: " + << last_type_; + } + + return testing::AssertionSuccess(); + } + + protected: + scoped_refptr<DeviceInfoDataTypeController> controller_; + std::unique_ptr<LocalDeviceInfoProviderMock> local_device_; + bool load_finished_; + + private: + base::MessageLoopForUI message_loop_; + syncer::ModelType last_type_; + syncer::SyncError last_error_; + FakeSyncClient sync_client_; + base::WeakPtrFactory<DeviceInfoDataTypeControllerTest> weak_ptr_factory_; +}; + +TEST_F(DeviceInfoDataTypeControllerTest, StartModels) { + Start(); + EXPECT_EQ(DataTypeController::MODEL_LOADED, controller_->state()); + EXPECT_TRUE(LoadResult()); +} + +TEST_F(DeviceInfoDataTypeControllerTest, StartModelsDelayedByLocalDevice) { + local_device_->SetInitialized(false); + Start(); + EXPECT_FALSE(load_finished_); + EXPECT_EQ(DataTypeController::MODEL_STARTING, controller_->state()); + + local_device_->SetInitialized(true); + EXPECT_EQ(DataTypeController::MODEL_LOADED, controller_->state()); + EXPECT_TRUE(LoadResult()); +} + +// Tests that DeviceInfoDataTypeControllerTest handles the situation +// when everything stops before the start gets a chance to finish. +TEST_F(DeviceInfoDataTypeControllerTest, DestructionWithDelayedStart) { + local_device_->SetInitialized(false); + Start(); + + controller_->Stop(); + // Destroy |local_device_| and |controller_| out of order + // to verify that the controller doesn't crash in the destructor. + local_device_.reset(); + controller_ = NULL; +} + +} // namespace + +} // namespace sync_driver
diff --git a/components/sync/driver/device_info_service.cc b/components/sync/driver/device_info_service.cc new file mode 100644 index 0000000..1b6c5040 --- /dev/null +++ b/components/sync/driver/device_info_service.cc
@@ -0,0 +1,538 @@ +// 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/sync/driver/device_info_service.h" + +#include <set> +#include <utility> +#include <vector> + +#include "base/bind.h" +#include "base/location.h" +#include "base/memory/ptr_util.h" +#include "base/strings/string_util.h" +#include "components/sync/api/entity_change.h" +#include "components/sync/api/metadata_batch.h" +#include "components/sync/api/sync_error.h" +#include "components/sync/base/time.h" +#include "components/sync/core/data_batch_impl.h" +#include "components/sync/core/simple_metadata_change_list.h" +#include "components/sync/driver/device_info_util.h" +#include "components/sync/protocol/data_type_state.pb.h" +#include "components/sync/protocol/sync.pb.h" + +namespace sync_driver_v2 { + +using base::Time; +using base::TimeDelta; +using syncer::SyncError; +using syncer_v2::DataBatchImpl; +using syncer_v2::EntityChange; +using syncer_v2::EntityChangeList; +using syncer_v2::EntityData; +using syncer_v2::EntityDataMap; +using syncer_v2::MetadataBatch; +using syncer_v2::MetadataChangeList; +using syncer_v2::ModelTypeStore; +using syncer_v2::SimpleMetadataChangeList; +using sync_driver::DeviceInfo; +using sync_driver::DeviceInfoUtil; +using sync_pb::DataTypeState; +using sync_pb::DeviceInfoSpecifics; +using sync_pb::EntitySpecifics; + +using Record = ModelTypeStore::Record; +using RecordList = ModelTypeStore::RecordList; +using Result = ModelTypeStore::Result; +using WriteBatch = ModelTypeStore::WriteBatch; + +DeviceInfoService::DeviceInfoService( + sync_driver::LocalDeviceInfoProvider* local_device_info_provider, + const StoreFactoryFunction& callback, + const ChangeProcessorFactory& change_processor_factory) + : ModelTypeService(change_processor_factory, syncer::DEVICE_INFO), + local_device_info_provider_(local_device_info_provider), + weak_factory_(this) { + DCHECK(local_device_info_provider); + + // This is not threadsafe, but presuably the provider initializes on the same + // thread as us so we're okay. + if (local_device_info_provider->GetLocalDeviceInfo()) { + OnProviderInitialized(); + } else { + subscription_ = + local_device_info_provider->RegisterOnInitializedCallback(base::Bind( + &DeviceInfoService::OnProviderInitialized, base::Unretained(this))); + } + + callback.Run(base::Bind(&DeviceInfoService::OnStoreCreated, + weak_factory_.GetWeakPtr())); +} + +DeviceInfoService::~DeviceInfoService() {} + +std::unique_ptr<MetadataChangeList> +DeviceInfoService::CreateMetadataChangeList() { + return base::WrapUnique(new SimpleMetadataChangeList()); +} + +SyncError DeviceInfoService::MergeSyncData( + std::unique_ptr<MetadataChangeList> metadata_change_list, + EntityDataMap entity_data_map) { + DCHECK(has_provider_initialized_); + DCHECK(has_metadata_loaded_); + DCHECK(change_processor()); + + // Local data should typically be near empty, with the only possible value + // corresponding to this device. This is because on signout all device info + // data is blown away. However, this simplification is being ignored here and + // a full difference is going to be calculated to explore what other service + // implementations may look like. + std::set<std::string> local_guids_to_put; + for (const auto& kv : all_data_) { + local_guids_to_put.insert(kv.first); + } + + bool has_changes = false; + const DeviceInfo* local_info = + local_device_info_provider_->GetLocalDeviceInfo(); + std::string local_guid = local_info->guid(); + std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch(); + for (const auto& kv : entity_data_map) { + const DeviceInfoSpecifics& specifics = + kv.second.value().specifics.device_info(); + DCHECK_EQ(kv.first, specifics.cache_guid()); + if (specifics.cache_guid() == local_guid) { + // Don't Put local data if it's the same as the remote copy. + if (local_info->Equals(*CopyToModel(specifics))) { + local_guids_to_put.erase(local_guid); + } else { + // This device is valid right now and this entry is about to be + // committed, use this as an opportunity to refresh the timestamp. + all_data_[local_guid]->set_last_updated_timestamp( + syncer::TimeToProtoTime(Time::Now())); + } + } else { + // Remote data wins conflicts. + local_guids_to_put.erase(specifics.cache_guid()); + has_changes = true; + StoreSpecifics(base::WrapUnique(new DeviceInfoSpecifics(specifics)), + batch.get()); + } + } + + for (const std::string& guid : local_guids_to_put) { + change_processor()->Put(guid, CopyToEntityData(*all_data_[guid]), + metadata_change_list.get()); + } + + CommitAndNotify(std::move(batch), std::move(metadata_change_list), + has_changes); + return SyncError(); +} + +SyncError DeviceInfoService::ApplySyncChanges( + std::unique_ptr<MetadataChangeList> metadata_change_list, + EntityChangeList entity_changes) { + DCHECK(has_provider_initialized_); + DCHECK(has_metadata_loaded_); + + std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch(); + bool has_changes = false; + for (EntityChange& change : entity_changes) { + const std::string guid = change.storage_key(); + // Each device is the authoritative source for itself, ignore any remote + // changes that have our local cache guid. + if (guid == local_device_info_provider_->GetLocalDeviceInfo()->guid()) { + continue; + } + + if (change.type() == EntityChange::ACTION_DELETE) { + has_changes |= DeleteSpecifics(guid, batch.get()); + } else { + const DeviceInfoSpecifics& specifics = + change.data().specifics.device_info(); + DCHECK(guid == specifics.cache_guid()); + StoreSpecifics(base::WrapUnique(new DeviceInfoSpecifics(specifics)), + batch.get()); + has_changes = true; + } + } + + CommitAndNotify(std::move(batch), std::move(metadata_change_list), + has_changes); + return SyncError(); +} + +void DeviceInfoService::GetData(StorageKeyList storage_keys, + DataCallback callback) { + DCHECK(has_metadata_loaded_); + + std::unique_ptr<DataBatchImpl> batch(new DataBatchImpl()); + for (const auto& key : storage_keys) { + const auto& iter = all_data_.find(key); + if (iter != all_data_.end()) { + DCHECK_EQ(key, iter->second->cache_guid()); + batch->Put(key, CopyToEntityData(*iter->second)); + } + } + + callback.Run(SyncError(), std::move(batch)); +} + +void DeviceInfoService::GetAllData(DataCallback callback) { + DCHECK(has_metadata_loaded_); + + std::unique_ptr<DataBatchImpl> batch(new DataBatchImpl()); + for (const auto& kv : all_data_) { + batch->Put(kv.first, CopyToEntityData(*kv.second)); + } + + callback.Run(SyncError(), std::move(batch)); +} + +std::string DeviceInfoService::GetClientTag(const EntityData& entity_data) { + DCHECK(entity_data.specifics.has_device_info()); + return DeviceInfoUtil::SpecificsToTag(entity_data.specifics.device_info()); +} + +std::string DeviceInfoService::GetStorageKey( + const syncer_v2::EntityData& entity_data) { + DCHECK(entity_data.specifics.has_device_info()); + return entity_data.specifics.device_info().cache_guid(); +} + +void DeviceInfoService::OnChangeProcessorSet() { + // We've recieved a new processor that needs metadata. If we're still in the + // process of loading data and/or metadata, then |has_metadata_loaded_| is + // false and we'll wait for those async reads to happen. If we've already + // loaded metadata and then subsequently we get a new processor, we must not + // have created the processor ourselves because we had no metadata. So there + // must not be any metadata on disk. + if (has_metadata_loaded_) { + change_processor()->OnMetadataLoaded(SyncError(), + base::WrapUnique(new MetadataBatch())); + ReconcileLocalAndStored(); + } +} + +bool DeviceInfoService::IsSyncing() const { + return !all_data_.empty(); +} + +std::unique_ptr<DeviceInfo> DeviceInfoService::GetDeviceInfo( + const std::string& client_id) const { + const ClientIdToSpecifics::const_iterator iter = all_data_.find(client_id); + if (iter == all_data_.end()) { + return std::unique_ptr<DeviceInfo>(); + } + + return CopyToModel(*iter->second); +} + +ScopedVector<DeviceInfo> DeviceInfoService::GetAllDeviceInfo() const { + ScopedVector<DeviceInfo> list; + + for (ClientIdToSpecifics::const_iterator iter = all_data_.begin(); + iter != all_data_.end(); ++iter) { + list.push_back(CopyToModel(*iter->second)); + } + + return list; +} + +void DeviceInfoService::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void DeviceInfoService::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +int DeviceInfoService::CountActiveDevices() const { + return CountActiveDevices(Time::Now()); +} + +void DeviceInfoService::NotifyObservers() { + FOR_EACH_OBSERVER(Observer, observers_, OnDeviceInfoChange()); +} + +// Static. +std::unique_ptr<DeviceInfoSpecifics> DeviceInfoService::CopyToSpecifics( + const DeviceInfo& info) { + std::unique_ptr<DeviceInfoSpecifics> specifics = + base::WrapUnique(new DeviceInfoSpecifics); + specifics->set_cache_guid(info.guid()); + specifics->set_client_name(info.client_name()); + specifics->set_chrome_version(info.chrome_version()); + specifics->set_sync_user_agent(info.sync_user_agent()); + specifics->set_device_type(info.device_type()); + specifics->set_signin_scoped_device_id(info.signin_scoped_device_id()); + return specifics; +} + +// Static. +std::unique_ptr<DeviceInfo> DeviceInfoService::CopyToModel( + const DeviceInfoSpecifics& specifics) { + return base::WrapUnique(new DeviceInfo( + specifics.cache_guid(), specifics.client_name(), + specifics.chrome_version(), specifics.sync_user_agent(), + specifics.device_type(), specifics.signin_scoped_device_id())); +} + +// Static. +std::unique_ptr<EntityData> DeviceInfoService::CopyToEntityData( + const DeviceInfoSpecifics& specifics) { + std::unique_ptr<EntityData> entity_data(new EntityData()); + *entity_data->specifics.mutable_device_info() = specifics; + entity_data->non_unique_name = specifics.client_name(); + return entity_data; +} + +void DeviceInfoService::StoreSpecifics( + std::unique_ptr<DeviceInfoSpecifics> specifics, + WriteBatch* batch) { + const std::string guid = specifics->cache_guid(); + DVLOG(1) << "Storing DEVICE_INFO for " << specifics->client_name() + << " with ID " << guid; + store_->WriteData(batch, guid, specifics->SerializeAsString()); + all_data_[guid] = std::move(specifics); +} + +bool DeviceInfoService::DeleteSpecifics(const std::string& guid, + WriteBatch* batch) { + ClientIdToSpecifics::const_iterator iter = all_data_.find(guid); + if (iter != all_data_.end()) { + DVLOG(1) << "Deleting DEVICE_INFO for " << iter->second->client_name() + << " with ID " << guid; + store_->DeleteData(batch, guid); + all_data_.erase(iter); + return true; + } else { + return false; + } +} + +void DeviceInfoService::OnProviderInitialized() { + has_provider_initialized_ = true; + LoadMetadataIfReady(); +} + +void DeviceInfoService::OnStoreCreated(Result result, + std::unique_ptr<ModelTypeStore> store) { + if (result == Result::SUCCESS) { + std::swap(store_, store); + store_->ReadAllData(base::Bind(&DeviceInfoService::OnReadAllData, + weak_factory_.GetWeakPtr())); + } else { + ReportStartupErrorToSync("ModelTypeStore creation failed."); + // TODO(skym, crbug.com/582460): Handle unrecoverable initialization + // failure. + } +} + +void DeviceInfoService::OnReadAllData(Result result, + std::unique_ptr<RecordList> record_list) { + if (result != Result::SUCCESS) { + ReportStartupErrorToSync("Initial load of data failed."); + // TODO(skym, crbug.com/582460): Handle unrecoverable initialization + // failure. + return; + } + + for (const Record& r : *record_list.get()) { + std::unique_ptr<DeviceInfoSpecifics> specifics( + base::WrapUnique(new DeviceInfoSpecifics())); + if (specifics->ParseFromString(r.value)) { + all_data_[specifics->cache_guid()] = std::move(specifics); + } else { + ReportStartupErrorToSync("Failed to deserialize specifics."); + // TODO(skym, crbug.com/582460): Handle unrecoverable initialization + // failure. + } + } + + has_data_loaded_ = true; + LoadMetadataIfReady(); +} + +void DeviceInfoService::LoadMetadataIfReady() { + if (has_data_loaded_ && has_provider_initialized_) { + store_->ReadAllMetadata(base::Bind(&DeviceInfoService::OnReadAllMetadata, + weak_factory_.GetWeakPtr())); + } +} + +void DeviceInfoService::OnReadAllMetadata( + Result result, + std::unique_ptr<RecordList> metadata_records, + const std::string& global_metadata) { + DCHECK(!has_metadata_loaded_); + + if (result != Result::SUCCESS) { + // Store has encountered some serious error. We should still be able to + // continue as a read only service, since if we got this far we must have + // loaded all data out succesfully. + ReportStartupErrorToSync("Load of metadata completely failed."); + return; + } + + // If we have no metadata then we don't want to create a processor. The idea + // is that by not having a processor, the services will suffer less of a + // performance hit. This isn't terribly applicable for this model type, but + // we want this class to be as similar to other services as possible so follow + // the convention. + if (metadata_records->size() > 0 || !global_metadata.empty()) { + CreateChangeProcessor(); + } + + // Set this after OnChangeProcessorSet so that we can correctly avoid giving + // the processor empty metadata. We always want to set |has_metadata_loaded_| + // at this point so that we'll know to give a processor empty metadata if it + // is created later. + has_metadata_loaded_ = true; + + if (!change_processor()) { + // This means we haven't been told to start syncing and we don't have any + // local metadata. + return; + } + + std::unique_ptr<MetadataBatch> batch(new MetadataBatch()); + DataTypeState state; + if (state.ParseFromString(global_metadata)) { + batch->SetDataTypeState(state); + } else { + // TODO(skym): How bad is this scenario? We may be able to just give an + // empty batch to the processor and we'll treat corrupted data type state + // as no data type state at all. The question is do we want to add any of + // the entity metadata to the batch or completely skip that step? We're + // going to have to perform a merge shortly. Does this decision/logic even + // belong in this service? + change_processor()->OnMetadataLoaded( + change_processor()->CreateAndUploadError( + FROM_HERE, "Failed to deserialize global metadata."), + nullptr); + } + for (const Record& r : *metadata_records.get()) { + sync_pb::EntityMetadata entity_metadata; + if (entity_metadata.ParseFromString(r.value)) { + batch->AddMetadata(r.id, entity_metadata); + } else { + // TODO(skym): This really isn't too bad. We just want to regenerate + // metadata for this particular entity. Unfortunately there isn't a + // convenient way to tell the processor to do this. + LOG(WARNING) << "Failed to deserialize entity metadata."; + } + } + change_processor()->OnMetadataLoaded(SyncError(), std::move(batch)); + ReconcileLocalAndStored(); +} + +void DeviceInfoService::OnCommit(Result result) { + if (result != Result::SUCCESS) { + LOG(WARNING) << "Failed a write to store."; + } +} + +void DeviceInfoService::ReconcileLocalAndStored() { + // On initial syncing we will have a change processor here, but it will not be + // tracking changes. We need to persist a copy of our local device info to + // disk, but the Put call to the processor will be ignored. That should be + // fine however, as the discrepancy will be picked up later in merge. We don't + // bother trying to track this case and act intelligently because simply not + // much of a benefit in doing so. + DCHECK(has_provider_initialized_); + DCHECK(has_metadata_loaded_); + DCHECK(change_processor()); + const DeviceInfo* current_info = + local_device_info_provider_->GetLocalDeviceInfo(); + auto iter = all_data_.find(current_info->guid()); + + // Convert to DeviceInfo for Equals function. + if (iter != all_data_.end() && + current_info->Equals(*CopyToModel(*iter->second))) { + const TimeDelta pulse_delay(DeviceInfoUtil::CalculatePulseDelay( + GetLastUpdateTime(*iter->second), Time::Now())); + if (!pulse_delay.is_zero()) { + pulse_timer_.Start(FROM_HERE, pulse_delay, + base::Bind(&DeviceInfoService::SendLocalData, + base::Unretained(this))); + return; + } + } + SendLocalData(); +} + +void DeviceInfoService::SendLocalData() { + DCHECK(has_provider_initialized_); + // TODO(skym): Handle disconnecting and reconnecting, this will currently halt + // the pulse timer and never restart it. + if (!change_processor()) { + return; + } + + std::unique_ptr<DeviceInfoSpecifics> specifics = + CopyToSpecifics(*local_device_info_provider_->GetLocalDeviceInfo()); + specifics->set_last_updated_timestamp(syncer::TimeToProtoTime(Time::Now())); + + std::unique_ptr<MetadataChangeList> metadata_change_list = + CreateMetadataChangeList(); + change_processor()->Put(specifics->cache_guid(), CopyToEntityData(*specifics), + metadata_change_list.get()); + + std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch(); + StoreSpecifics(std::move(specifics), batch.get()); + + CommitAndNotify(std::move(batch), std::move(metadata_change_list), true); + pulse_timer_.Start( + FROM_HERE, DeviceInfoUtil::kPulseInterval, + base::Bind(&DeviceInfoService::SendLocalData, base::Unretained(this))); +} + +void DeviceInfoService::CommitAndNotify( + std::unique_ptr<WriteBatch> batch, + std::unique_ptr<MetadataChangeList> metadata_change_list, + bool should_notify) { + static_cast<SimpleMetadataChangeList*>(metadata_change_list.get()) + ->TransferChanges(store_.get(), batch.get()); + store_->CommitWriteBatch( + std::move(batch), + base::Bind(&DeviceInfoService::OnCommit, weak_factory_.GetWeakPtr())); + if (should_notify) { + NotifyObservers(); + } +} + +int DeviceInfoService::CountActiveDevices(const Time now) const { + return std::count_if(all_data_.begin(), all_data_.end(), + [now](ClientIdToSpecifics::const_reference pair) { + return DeviceInfoUtil::IsActive( + GetLastUpdateTime(*pair.second), now); + }); +} + +void DeviceInfoService::ReportStartupErrorToSync(const std::string& msg) { + DCHECK(!has_metadata_loaded_); + LOG(WARNING) << msg; + + // Create a processor and give it the error in case sync tries to start. + if (!change_processor()) { + CreateChangeProcessor(); + } + change_processor()->OnMetadataLoaded( + change_processor()->CreateAndUploadError(FROM_HERE, msg), nullptr); +} + +// static +Time DeviceInfoService::GetLastUpdateTime( + const DeviceInfoSpecifics& specifics) { + if (specifics.has_last_updated_timestamp()) { + return syncer::ProtoTimeToTime(specifics.last_updated_timestamp()); + } else { + return Time(); + } +} + +} // namespace sync_driver_v2
diff --git a/components/sync/driver/device_info_service.h b/components/sync/driver/device_info_service.h new file mode 100644 index 0000000..23511f1 --- /dev/null +++ b/components/sync/driver/device_info_service.h
@@ -0,0 +1,191 @@ +// 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_SYNC_DRIVER_DEVICE_INFO_SERVICE_H_ +#define COMPONENTS_SYNC_DRIVER_DEVICE_INFO_SERVICE_H_ + +#include <stdint.h> + +#include <map> +#include <memory> +#include <string> +#include <vector> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/observer_list.h" +#include "base/time/time.h" +#include "base/timer/timer.h" +#include "components/sync/api/model_type_service.h" +#include "components/sync/api/model_type_store.h" +#include "components/sync/core/simple_metadata_change_list.h" +#include "components/sync/driver/device_info_tracker.h" +#include "components/sync/driver/local_device_info_provider.h" + +namespace syncer { +class SyncError; +} // namespace syncer + +namespace syncer_v2 { +class ModelTypeChangeProcessor; +} // namespace syncer_v2 + +namespace sync_pb { +class DeviceInfoSpecifics; +} // namespace sync_pb + +namespace sync_driver_v2 { + +// USS service implementation for DEVICE_INFO model type. Handles storage of +// device info and associated sync metadata, applying/merging foreign changes, +// and allows public read access. +class DeviceInfoService : public syncer_v2::ModelTypeService, + public sync_driver::DeviceInfoTracker { + public: + typedef base::Callback<void( + const syncer_v2::ModelTypeStore::InitCallback& callback)> + StoreFactoryFunction; + + DeviceInfoService( + sync_driver::LocalDeviceInfoProvider* local_device_info_provider, + const StoreFactoryFunction& callback, + const ChangeProcessorFactory& change_processor_factory); + ~DeviceInfoService() override; + + // ModelTypeService implementation. + std::unique_ptr<syncer_v2::MetadataChangeList> CreateMetadataChangeList() + override; + syncer::SyncError MergeSyncData( + std::unique_ptr<syncer_v2::MetadataChangeList> metadata_change_list, + syncer_v2::EntityDataMap entity_data_map) override; + syncer::SyncError ApplySyncChanges( + std::unique_ptr<syncer_v2::MetadataChangeList> metadata_change_list, + syncer_v2::EntityChangeList entity_changes) override; + void GetData(StorageKeyList storage_keys, DataCallback callback) override; + void GetAllData(DataCallback callback) override; + std::string GetClientTag(const syncer_v2::EntityData& entity_data) override; + std::string GetStorageKey(const syncer_v2::EntityData& entity_data) override; + void OnChangeProcessorSet() override; + + // DeviceInfoTracker implementation. + bool IsSyncing() const override; + std::unique_ptr<sync_driver::DeviceInfo> GetDeviceInfo( + const std::string& client_id) const override; + ScopedVector<sync_driver::DeviceInfo> GetAllDeviceInfo() const override; + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + int CountActiveDevices() const override; + + private: + friend class DeviceInfoServiceTest; + + // Cache of all syncable and local data, stored by device cache guid. + using ClientIdToSpecifics = + std::map<std::string, std::unique_ptr<sync_pb::DeviceInfoSpecifics>>; + + static std::unique_ptr<sync_pb::DeviceInfoSpecifics> CopyToSpecifics( + const sync_driver::DeviceInfo& info); + + // Allocate new DeviceInfo from SyncData. + static std::unique_ptr<sync_driver::DeviceInfo> CopyToModel( + const sync_pb::DeviceInfoSpecifics& specifics); + // Conversion as we prepare to hand data to the processor. + static std::unique_ptr<syncer_v2::EntityData> CopyToEntityData( + const sync_pb::DeviceInfoSpecifics& specifics); + + // Store SyncData in the cache and durable storage. + void StoreSpecifics(std::unique_ptr<sync_pb::DeviceInfoSpecifics> specifics, + syncer_v2::ModelTypeStore::WriteBatch* batch); + // Delete SyncData from the cache and durable storage, returns true if there + // was actually anything at the given tag. + bool DeleteSpecifics(const std::string& tag, + syncer_v2::ModelTypeStore::WriteBatch* batch); + + // Notify all registered observers. + void NotifyObservers(); + + // Used as callback given to LocalDeviceInfoProvider. + void OnProviderInitialized(); + + // Methods used as callbacks given to DataTypeStore. + void OnStoreCreated(syncer_v2::ModelTypeStore::Result result, + std::unique_ptr<syncer_v2::ModelTypeStore> store); + void OnReadAllData( + syncer_v2::ModelTypeStore::Result result, + std::unique_ptr<syncer_v2::ModelTypeStore::RecordList> record_list); + void OnReadAllMetadata( + syncer_v2::ModelTypeStore::Result result, + std::unique_ptr<syncer_v2::ModelTypeStore::RecordList> metadata_records, + const std::string& global_metadata); + void OnCommit(syncer_v2::ModelTypeStore::Result result); + + // Load metadata if the data is loaded and the provider is initialized. + void LoadMetadataIfReady(); + + // Performs reconciliation between the locally provided device info and the + // stored device info data. If the sets of data differ, then we consider this + // a local change and we send it to the processor. + void ReconcileLocalAndStored(); + + // Stores the updated version of the local copy of device info in durable + // storage, in memory, and informs sync of the change. Should not be called + // before the provider and processor have initialized. + void SendLocalData(); + + // Persists the changes in the given aggregators and notifies observers if + // indicated to do as such. + void CommitAndNotify( + std::unique_ptr<syncer_v2::ModelTypeStore::WriteBatch> batch, + std::unique_ptr<syncer_v2::MetadataChangeList> metadata_change_list, + bool should_notify); + + // Counts the number of active devices relative to |now|. The activeness of a + // device depends on the amount of time since it was updated, which means + // comparing it against the current time. |now| is passed into this method to + // allow unit tests to control expected results. + int CountActiveDevices(const base::Time now) const; + + // Report an error starting up to sync if it tries to connect to this + // datatype, since these errors prevent us from knowing if sync is enabled. + void ReportStartupErrorToSync(const std::string& msg); + + // Find the timestamp for the last time this |device_info| was edited. + static base::Time GetLastUpdateTime( + const sync_pb::DeviceInfoSpecifics& specifics); + + // |local_device_info_provider_| isn't owned. + const sync_driver::LocalDeviceInfoProvider* const local_device_info_provider_; + + ClientIdToSpecifics all_data_; + + // Registered observers, not owned. + base::ObserverList<Observer, true> observers_; + + // Used to listen for provider initialization. If the provider is already + // initialized during our constructor then the subscription is never used. + std::unique_ptr<sync_driver::LocalDeviceInfoProvider::Subscription> + subscription_; + + // In charge of actually persiting changes to disk, or loading previous data. + std::unique_ptr<syncer_v2::ModelTypeStore> store_; + + // If |local_device_info_provider_| has initialized. + bool has_provider_initialized_ = false; + // If data has been loaded from the store. + bool has_data_loaded_ = false; + // if |change_processor()| has been given metadata. + bool has_metadata_loaded_ = false; + + // Used to update our local device info once every pulse interval. + base::OneShotTimer pulse_timer_; + + // Should always be last member. + base::WeakPtrFactory<DeviceInfoService> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(DeviceInfoService); +}; + +} // namespace sync_driver_v2 + +#endif // COMPONENTS_SYNC_DRIVER_DEVICE_INFO_SERVICE_H_
diff --git a/components/sync/driver/device_info_service_unittest.cc b/components/sync/driver/device_info_service_unittest.cc new file mode 100644 index 0000000..e59aa69 --- /dev/null +++ b/components/sync/driver/device_info_service_unittest.cc
@@ -0,0 +1,780 @@ +// 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/sync/driver/device_info_service.h" + +#include <map> +#include <memory> +#include <set> +#include <string> +#include <utility> + +#include "base/bind.h" +#include "base/memory/ptr_util.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/strings/stringprintf.h" +#include "components/sync/api/data_batch.h" +#include "components/sync/api/entity_data.h" +#include "components/sync/api/fake_model_type_change_processor.h" +#include "components/sync/api/metadata_batch.h" +#include "components/sync/api/model_type_store.h" +#include "components/sync/base/time.h" +#include "components/sync/core/test/data_type_error_handler_mock.h" +#include "components/sync/core/test/model_type_store_test_util.h" +#include "components/sync/driver/local_device_info_provider_mock.h" +#include "components/sync/protocol/data_type_state.pb.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace sync_driver_v2 { + +using base::Time; +using base::TimeDelta; +using syncer::SyncError; +using syncer_v2::DataBatch; +using syncer_v2::EntityChange; +using syncer_v2::EntityChangeList; +using syncer_v2::EntityData; +using syncer_v2::EntityDataMap; +using syncer_v2::EntityDataPtr; +using syncer_v2::MetadataBatch; +using syncer_v2::MetadataChangeList; +using syncer_v2::ModelTypeChangeProcessor; +using syncer_v2::ModelTypeService; +using syncer_v2::ModelTypeStore; +using syncer_v2::ModelTypeStoreTestUtil; +using syncer_v2::KeyAndData; +using sync_driver::DeviceInfo; +using sync_driver::DeviceInfoTracker; +using sync_driver::LocalDeviceInfoProviderMock; +using sync_pb::DataTypeState; +using sync_pb::DeviceInfoSpecifics; +using sync_pb::EntitySpecifics; + +using StorageKeyList = ModelTypeService::StorageKeyList; +using RecordList = ModelTypeStore::RecordList; +using Result = ModelTypeStore::Result; +using StartCallback = ModelTypeChangeProcessor::StartCallback; +using WriteBatch = ModelTypeStore::WriteBatch; + +namespace { + +std::unique_ptr<DeviceInfo> CreateDeviceInfo() { + return base::MakeUnique<DeviceInfo>( + "guid_1", "client_1", "Chromium 10k", "Chrome 10k", + sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id"); +} + +void AssertResultIsSuccess(Result result) { + ASSERT_EQ(Result::SUCCESS, result); +} + +void AssertEqual(const DeviceInfoSpecifics& s1, const DeviceInfoSpecifics& s2) { + ASSERT_EQ(s1.cache_guid(), s2.cache_guid()); + ASSERT_EQ(s1.client_name(), s2.client_name()); + ASSERT_EQ(s1.device_type(), s2.device_type()); + ASSERT_EQ(s1.sync_user_agent(), s2.sync_user_agent()); + ASSERT_EQ(s1.chrome_version(), s2.chrome_version()); + ASSERT_EQ(s1.signin_scoped_device_id(), s2.signin_scoped_device_id()); +} + +void AssertEqual(const DeviceInfoSpecifics& specifics, + const DeviceInfo& model) { + ASSERT_EQ(specifics.cache_guid(), model.guid()); + ASSERT_EQ(specifics.client_name(), model.client_name()); + ASSERT_EQ(specifics.device_type(), model.device_type()); + ASSERT_EQ(specifics.sync_user_agent(), model.sync_user_agent()); + ASSERT_EQ(specifics.chrome_version(), model.chrome_version()); + ASSERT_EQ(specifics.signin_scoped_device_id(), + model.signin_scoped_device_id()); +} + +void AssertExpectedFromDataBatch( + std::map<std::string, DeviceInfoSpecifics> expected, + SyncError error, + std::unique_ptr<DataBatch> batch) { + ASSERT_FALSE(error.IsSet()); + while (batch->HasNext()) { + const KeyAndData& pair = batch->Next(); + std::map<std::string, DeviceInfoSpecifics>::iterator iter = + expected.find(pair.first); + ASSERT_NE(iter, expected.end()); + AssertEqual(iter->second, pair.second->specifics.device_info()); + // Removing allows us to verify we don't see the same item multiple times, + // and that we saw everything we expected. + expected.erase(iter); + } + ASSERT_TRUE(expected.empty()); +} + +// Creates an EntityData/EntityDataPtr around a copy of the given specifics. +EntityDataPtr SpecificsToEntity(const DeviceInfoSpecifics& specifics) { + EntityData data; + // These tests do not care about the tag hash, but EntityData and friends + // cannot differentiate between the default EntityData object if the hash + // is unset, which causes pass/copy operations to no-op and things start to + // break, so we throw in a junk value and forget about it. + data.client_tag_hash = "junk"; + *data.specifics.mutable_device_info() = specifics; + return data.PassToPtr(); +} + +std::string CacheGuidToTag(const std::string& guid) { + return "DeviceInfo_" + guid; +} + +// Helper method to reduce duplicated code between tests. Wraps the given +// specifics object in an EntityData and EntityChange of type ACTION_ADD, and +// pushes them onto the given change list. The corresponding guid of the data +// is returned, which happens to be the storage key. +std::string PushBackEntityChangeAdd(const DeviceInfoSpecifics& specifics, + EntityChangeList* changes) { + EntityDataPtr ptr = SpecificsToEntity(specifics); + changes->push_back(EntityChange::CreateAdd(specifics.cache_guid(), ptr)); + return specifics.cache_guid(); +} + +// Instead of actually processing anything, simply accumulates all instructions +// in members that can then be accessed. TODO(skym): If this ends up being +// useful for other model type unittests it should be moved out to a shared +// location. +class RecordingModelTypeChangeProcessor + : public syncer_v2::FakeModelTypeChangeProcessor { + public: + RecordingModelTypeChangeProcessor() {} + ~RecordingModelTypeChangeProcessor() override {} + + void Put(const std::string& storage_key, + std::unique_ptr<EntityData> entity_data, + MetadataChangeList* metadata_changes) override { + put_map_.insert(std::make_pair(storage_key, std::move(entity_data))); + } + + void Delete(const std::string& storage_key, + MetadataChangeList* metadata_changes) override { + delete_set_.insert(storage_key); + } + + void OnMetadataLoaded(syncer::SyncError error, + std::unique_ptr<MetadataBatch> batch) override { + std::swap(metadata_, batch); + } + + const std::map<std::string, std::unique_ptr<EntityData>>& put_map() const { + return put_map_; + } + const std::set<std::string>& delete_set() const { return delete_set_; } + const MetadataBatch* metadata() const { return metadata_.get(); } + + private: + std::map<std::string, std::unique_ptr<EntityData>> put_map_; + std::set<std::string> delete_set_; + std::unique_ptr<MetadataBatch> metadata_; +}; + +} // namespace + +class DeviceInfoServiceTest : public testing::Test, + public DeviceInfoTracker::Observer { + protected: + DeviceInfoServiceTest() + : change_count_(0), + store_(ModelTypeStoreTestUtil::CreateInMemoryStoreForTest()), + local_device_(new LocalDeviceInfoProviderMock()) { + local_device_->Initialize(CreateDeviceInfo()); + } + + ~DeviceInfoServiceTest() override { + // Some tests may never initialize the service. + if (service_) + service_->RemoveObserver(this); + + // Force all remaining (store) tasks to execute so we don't leak memory. + base::RunLoop().RunUntilIdle(); + } + + void OnDeviceInfoChange() override { change_count_++; } + + std::unique_ptr<ModelTypeChangeProcessor> CreateModelTypeChangeProcessor( + syncer::ModelType type, + ModelTypeService* service) { + processor_ = new RecordingModelTypeChangeProcessor(); + return base::WrapUnique(processor_); + } + + // Initialized the service based on the current local device and store. Can + // only be called once per run, as it passes |store_|. + void InitializeService() { + ASSERT_TRUE(store_); + service_.reset(new DeviceInfoService( + local_device_.get(), + base::Bind(&ModelTypeStoreTestUtil::MoveStoreToCallback, + base::Passed(&store_)), + base::Bind(&DeviceInfoServiceTest::CreateModelTypeChangeProcessor, + base::Unretained(this)))); + service_->AddObserver(this); + } + + void OnSyncStarting() { + service()->OnSyncStarting(&error_handler_, StartCallback()); + } + + // Creates the service and runs any outstanding tasks. This will typically + // cause all initialization callbacks between the sevice and store to fire. + void InitializeAndPump() { + InitializeService(); + base::RunLoop().RunUntilIdle(); + } + + // Creates the service, runs any outstanding tasks, and then indicates to the + // service that sync wants to start and forces the processor to be created. + void InitializeAndPumpAndStart() { + InitializeAndPump(); + OnSyncStarting(); + ASSERT_TRUE(processor_); + } + + // Generates a specifics object with slightly differing values. Will generate + // the same values on each run of a test because a simple counter is used to + // vary field values. + DeviceInfoSpecifics GenerateTestSpecifics() { + int label = ++generated_count_; + DeviceInfoSpecifics specifics; + specifics.set_cache_guid(base::StringPrintf("cache guid %d", label)); + specifics.set_client_name(base::StringPrintf("client name %d", label)); + specifics.set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_LINUX); + specifics.set_sync_user_agent( + base::StringPrintf("sync user agent %d", label)); + specifics.set_chrome_version( + base::StringPrintf("chrome version %d", label)); + specifics.set_signin_scoped_device_id( + base::StringPrintf("signin scoped device id %d", label)); + return specifics; + } + + std::unique_ptr<DeviceInfoSpecifics> CopyToSpecifics(const DeviceInfo& info) { + return DeviceInfoService::CopyToSpecifics(info); + } + + // Override to allow specific cache guids. + DeviceInfoSpecifics GenerateTestSpecifics(const std::string& guid) { + DeviceInfoSpecifics specifics(GenerateTestSpecifics()); + specifics.set_cache_guid(guid); + return specifics; + } + + // Allows access to the store before that will ultimately be used to + // initialize the service. + ModelTypeStore* store() { + EXPECT_TRUE(store_); + return store_.get(); + } + + // Get the number of times the service notifies observers of changes. + int change_count() { return change_count_; } + + // Allows overriding the provider before the service is initialized. + void set_local_device(std::unique_ptr<LocalDeviceInfoProviderMock> provider) { + ASSERT_FALSE(service_); + std::swap(local_device_, provider); + } + LocalDeviceInfoProviderMock* local_device() { return local_device_.get(); } + + // Allows access to the service after InitializeService() is called. + DeviceInfoService* service() { + EXPECT_TRUE(service_); + return service_.get(); + } + + RecordingModelTypeChangeProcessor* processor() { + EXPECT_TRUE(processor_); + return processor_; + } + + // Should only be called after the service has been initialized. Will first + // recover the service's store, so another can be initialized later, and then + // deletes the service. + void PumpAndShutdown() { + ASSERT_TRUE(service_); + base::RunLoop().RunUntilIdle(); + std::swap(store_, service_->store_); + service_->RemoveObserver(this); + service_.reset(); + } + + void RestartService() { + PumpAndShutdown(); + InitializeAndPump(); + } + + Time GetLastUpdateTime(const DeviceInfoSpecifics& specifics) { + return DeviceInfoService::GetLastUpdateTime(specifics); + } + + private: + int change_count_; + + // In memory model type store needs a MessageLoop. + base::MessageLoop message_loop_; + + // Holds the store while the service is not initialized. + std::unique_ptr<ModelTypeStore> store_; + + std::unique_ptr<LocalDeviceInfoProviderMock> local_device_; + + // Mock error handler passed to the processor. + syncer::DataTypeErrorHandlerMock error_handler_; + + // Not initialized immediately (upon test's constructor). This allows each + // test case to modify the dependencies the service will be constructed with. + std::unique_ptr<DeviceInfoService> service_; + + // A non-owning pointer to the processor given to the service. Will be nullptr + // before being given to the service, to make ownership easier. + RecordingModelTypeChangeProcessor* processor_ = nullptr; + + // A monotonically increasing label for generated specifics objects with data + // that is slightly different from eachother. + int generated_count_ = 0; +}; + +namespace { + +TEST_F(DeviceInfoServiceTest, EmptyDataReconciliation) { + InitializeAndPump(); + ASSERT_EQ(0u, service()->GetAllDeviceInfo().size()); + OnSyncStarting(); + ScopedVector<DeviceInfo> all_device_info(service()->GetAllDeviceInfo()); + ASSERT_EQ(1u, all_device_info.size()); + ASSERT_TRUE( + local_device()->GetLocalDeviceInfo()->Equals(*all_device_info[0])); +} + +TEST_F(DeviceInfoServiceTest, EmptyDataReconciliationSlowLoad) { + InitializeService(); + OnSyncStarting(); + ASSERT_EQ(0u, service()->GetAllDeviceInfo().size()); + base::RunLoop().RunUntilIdle(); + ScopedVector<DeviceInfo> all_device_info(service()->GetAllDeviceInfo()); + ASSERT_EQ(1u, all_device_info.size()); + ASSERT_TRUE( + local_device()->GetLocalDeviceInfo()->Equals(*all_device_info[0])); +} + +TEST_F(DeviceInfoServiceTest, LocalProviderSubscription) { + set_local_device(base::WrapUnique(new LocalDeviceInfoProviderMock())); + InitializeAndPumpAndStart(); + + ASSERT_EQ(0u, service()->GetAllDeviceInfo().size()); + local_device()->Initialize(CreateDeviceInfo()); + base::RunLoop().RunUntilIdle(); + + ScopedVector<DeviceInfo> all_device_info(service()->GetAllDeviceInfo()); + ASSERT_EQ(1u, all_device_info.size()); + ASSERT_TRUE( + local_device()->GetLocalDeviceInfo()->Equals(*all_device_info[0])); +} + +// Metadata shouldn't be loaded before the provider is initialized. +TEST_F(DeviceInfoServiceTest, LocalProviderInitRace) { + set_local_device(base::WrapUnique(new LocalDeviceInfoProviderMock())); + InitializeAndPump(); + OnSyncStarting(); + EXPECT_FALSE(processor()->metadata()); + + ASSERT_EQ(0u, service()->GetAllDeviceInfo().size()); + local_device()->Initialize(CreateDeviceInfo()); + base::RunLoop().RunUntilIdle(); + + ScopedVector<DeviceInfo> all_device_info(service()->GetAllDeviceInfo()); + ASSERT_EQ(1u, all_device_info.size()); + ASSERT_TRUE( + local_device()->GetLocalDeviceInfo()->Equals(*all_device_info[0])); + + EXPECT_TRUE(processor()->metadata()); +} + +TEST_F(DeviceInfoServiceTest, GetClientTagNormal) { + InitializeService(); + const std::string guid = "abc"; + EntitySpecifics entity_specifics; + entity_specifics.mutable_device_info()->set_cache_guid(guid); + EntityData entity_data; + entity_data.specifics = entity_specifics; + EXPECT_EQ(CacheGuidToTag(guid), service()->GetClientTag(entity_data)); +} + +TEST_F(DeviceInfoServiceTest, GetClientTagEmpty) { + InitializeService(); + EntitySpecifics entity_specifics; + entity_specifics.mutable_device_info(); + EntityData entity_data; + entity_data.specifics = entity_specifics; + EXPECT_EQ(CacheGuidToTag(""), service()->GetClientTag(entity_data)); +} + +TEST_F(DeviceInfoServiceTest, TestWithLocalData) { + std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch(); + DeviceInfoSpecifics specifics(GenerateTestSpecifics()); + store()->WriteData(batch.get(), specifics.cache_guid(), + specifics.SerializeAsString()); + store()->CommitWriteBatch(std::move(batch), + base::Bind(&AssertResultIsSuccess)); + + InitializeAndPump(); + + ScopedVector<DeviceInfo> all_device_info(service()->GetAllDeviceInfo()); + ASSERT_EQ(1u, all_device_info.size()); + AssertEqual(specifics, *all_device_info[0]); + AssertEqual(specifics, + *service()->GetDeviceInfo(specifics.cache_guid()).get()); +} + +TEST_F(DeviceInfoServiceTest, TestWithLocalMetadata) { + std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch(); + DataTypeState state; + state.set_encryption_key_name("ekn"); + store()->WriteGlobalMetadata(batch.get(), state.SerializeAsString()); + store()->CommitWriteBatch(std::move(batch), + base::Bind(&AssertResultIsSuccess)); + InitializeAndPump(); + ScopedVector<DeviceInfo> all_device_info(service()->GetAllDeviceInfo()); + ASSERT_EQ(1u, all_device_info.size()); + ASSERT_TRUE( + local_device()->GetLocalDeviceInfo()->Equals(*all_device_info[0])); + EXPECT_EQ(1u, processor()->put_map().size()); +} + +TEST_F(DeviceInfoServiceTest, TestWithLocalDataAndMetadata) { + std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch(); + DeviceInfoSpecifics specifics(GenerateTestSpecifics()); + store()->WriteData(batch.get(), specifics.cache_guid(), + specifics.SerializeAsString()); + DataTypeState state; + state.set_encryption_key_name("ekn"); + store()->WriteGlobalMetadata(batch.get(), state.SerializeAsString()); + store()->CommitWriteBatch(std::move(batch), + base::Bind(&AssertResultIsSuccess)); + + InitializeAndPump(); + + ScopedVector<DeviceInfo> all_device_info(service()->GetAllDeviceInfo()); + ASSERT_EQ(2u, all_device_info.size()); + AssertEqual(specifics, + *service()->GetDeviceInfo(specifics.cache_guid()).get()); + ASSERT_TRUE(processor()->metadata()); + ASSERT_EQ(state.encryption_key_name(), + processor()->metadata()->GetDataTypeState().encryption_key_name()); +} + +TEST_F(DeviceInfoServiceTest, GetData) { + std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch(); + DeviceInfoSpecifics specifics1(GenerateTestSpecifics()); + DeviceInfoSpecifics specifics2(GenerateTestSpecifics()); + DeviceInfoSpecifics specifics3(GenerateTestSpecifics()); + store()->WriteData(batch.get(), specifics1.cache_guid(), + specifics1.SerializeAsString()); + store()->WriteData(batch.get(), specifics2.cache_guid(), + specifics2.SerializeAsString()); + store()->WriteData(batch.get(), specifics3.cache_guid(), + specifics3.SerializeAsString()); + store()->CommitWriteBatch(std::move(batch), + base::Bind(&AssertResultIsSuccess)); + + InitializeAndPump(); + + std::map<std::string, DeviceInfoSpecifics> expected; + expected[specifics1.cache_guid()] = specifics1; + expected[specifics3.cache_guid()] = specifics3; + StorageKeyList storage_keys; + storage_keys.push_back(specifics1.cache_guid()); + storage_keys.push_back(specifics3.cache_guid()); + service()->GetData(storage_keys, + base::Bind(&AssertExpectedFromDataBatch, expected)); +} + +TEST_F(DeviceInfoServiceTest, GetDataMissing) { + InitializeAndPump(); + std::map<std::string, DeviceInfoSpecifics> expected; + StorageKeyList storage_keys; + storage_keys.push_back("does_not_exist"); + service()->GetData(storage_keys, + base::Bind(&AssertExpectedFromDataBatch, expected)); +} + +TEST_F(DeviceInfoServiceTest, GetAllData) { + std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch(); + DeviceInfoSpecifics specifics1(GenerateTestSpecifics()); + DeviceInfoSpecifics specifics2(GenerateTestSpecifics()); + const std::string& guid1 = specifics1.cache_guid(); + const std::string& guid2 = specifics2.cache_guid(); + store()->WriteData(batch.get(), specifics1.cache_guid(), + specifics1.SerializeAsString()); + store()->WriteData(batch.get(), specifics2.cache_guid(), + specifics2.SerializeAsString()); + store()->CommitWriteBatch(std::move(batch), + base::Bind(&AssertResultIsSuccess)); + + InitializeAndPump(); + + std::map<std::string, DeviceInfoSpecifics> expected; + expected[guid1] = specifics1; + expected[guid2] = specifics2; + StorageKeyList storage_keys; + storage_keys.push_back(guid1); + storage_keys.push_back(guid2); + service()->GetData(storage_keys, + base::Bind(&AssertExpectedFromDataBatch, expected)); +} + +TEST_F(DeviceInfoServiceTest, ApplySyncChangesEmpty) { + InitializeAndPump(); + const SyncError error = service()->ApplySyncChanges( + service()->CreateMetadataChangeList(), EntityChangeList()); + EXPECT_FALSE(error.IsSet()); + EXPECT_EQ(0, change_count()); +} + +TEST_F(DeviceInfoServiceTest, ApplySyncChangesInMemory) { + InitializeAndPump(); + + DeviceInfoSpecifics specifics = GenerateTestSpecifics(); + EntityChangeList add_changes; + PushBackEntityChangeAdd(specifics, &add_changes); + SyncError error = service()->ApplySyncChanges( + service()->CreateMetadataChangeList(), add_changes); + + EXPECT_FALSE(error.IsSet()); + std::unique_ptr<DeviceInfo> info = + service()->GetDeviceInfo(specifics.cache_guid()); + ASSERT_TRUE(info); + AssertEqual(specifics, *info.get()); + EXPECT_EQ(1, change_count()); + + EntityChangeList delete_changes; + delete_changes.push_back(EntityChange::CreateDelete(specifics.cache_guid())); + error = service()->ApplySyncChanges(service()->CreateMetadataChangeList(), + delete_changes); + + EXPECT_FALSE(error.IsSet()); + EXPECT_FALSE(service()->GetDeviceInfo(specifics.cache_guid())); + EXPECT_EQ(2, change_count()); +} + +TEST_F(DeviceInfoServiceTest, ApplySyncChangesStore) { + InitializeAndPump(); + + DeviceInfoSpecifics specifics = GenerateTestSpecifics(); + EntityChangeList data_changes; + PushBackEntityChangeAdd(specifics, &data_changes); + DataTypeState state; + state.set_encryption_key_name("ekn"); + std::unique_ptr<MetadataChangeList> metadata_changes( + service()->CreateMetadataChangeList()); + metadata_changes->UpdateDataTypeState(state); + + const SyncError error = + service()->ApplySyncChanges(std::move(metadata_changes), data_changes); + EXPECT_FALSE(error.IsSet()); + EXPECT_EQ(1, change_count()); + + RestartService(); + + std::unique_ptr<DeviceInfo> info = + service()->GetDeviceInfo(specifics.cache_guid()); + ASSERT_TRUE(info); + AssertEqual(specifics, *info.get()); + + EXPECT_TRUE(processor()->metadata()); + EXPECT_EQ(state.encryption_key_name(), + processor()->metadata()->GetDataTypeState().encryption_key_name()); +} + +TEST_F(DeviceInfoServiceTest, ApplySyncChangesWithLocalGuid) { + InitializeAndPumpAndStart(); + + // The point of this test is to try to apply remote changes that have the same + // cache guid as the local device. The service should ignore these changes + // since only it should be performing writes on its data. + DeviceInfoSpecifics specifics = + GenerateTestSpecifics(local_device()->GetLocalDeviceInfo()->guid()); + EntityChangeList change_list; + PushBackEntityChangeAdd(specifics, &change_list); + + // Should have a single change from reconciliation. + EXPECT_TRUE( + service()->GetDeviceInfo(local_device()->GetLocalDeviceInfo()->guid())); + EXPECT_EQ(1, change_count()); + // Ensure |last_updated| is about now, plus or minus a little bit. + Time last_updated( + syncer::ProtoTimeToTime(processor() + ->put_map() + .begin() + ->second->specifics.device_info() + .last_updated_timestamp())); + EXPECT_LT(Time::Now() - TimeDelta::FromMinutes(1), last_updated); + EXPECT_GT(Time::Now() + TimeDelta::FromMinutes(1), last_updated); + + EXPECT_FALSE( + service() + ->ApplySyncChanges(service()->CreateMetadataChangeList(), change_list) + .IsSet()); + EXPECT_EQ(1, change_count()); + + change_list.clear(); + change_list.push_back(EntityChange::CreateDelete(specifics.cache_guid())); + EXPECT_FALSE( + service() + ->ApplySyncChanges(service()->CreateMetadataChangeList(), change_list) + .IsSet()); + EXPECT_EQ(1, change_count()); +} + +TEST_F(DeviceInfoServiceTest, ApplyDeleteNonexistent) { + InitializeAndPumpAndStart(); + EXPECT_EQ(1, change_count()); + EntityChangeList delete_changes; + delete_changes.push_back(EntityChange::CreateDelete("guid")); + const SyncError error = service()->ApplySyncChanges( + service()->CreateMetadataChangeList(), delete_changes); + EXPECT_FALSE(error.IsSet()); + EXPECT_EQ(1, change_count()); +} + +TEST_F(DeviceInfoServiceTest, MergeEmpty) { + InitializeAndPumpAndStart(); + EXPECT_EQ(1, change_count()); + const SyncError error = service()->MergeSyncData( + service()->CreateMetadataChangeList(), EntityDataMap()); + EXPECT_FALSE(error.IsSet()); + EXPECT_EQ(1, change_count()); + EXPECT_EQ(1u, processor()->put_map().size()); + EXPECT_EQ(0u, processor()->delete_set().size()); +} + +TEST_F(DeviceInfoServiceTest, MergeWithData) { + const std::string conflict_guid = "conflict_guid"; + const DeviceInfoSpecifics unique_local( + GenerateTestSpecifics("unique_local_guid")); + const DeviceInfoSpecifics conflict_local( + GenerateTestSpecifics(conflict_guid)); + const DeviceInfoSpecifics conflict_remote( + GenerateTestSpecifics(conflict_guid)); + const DeviceInfoSpecifics unique_remote( + GenerateTestSpecifics("unique_remote_guid")); + + std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch(); + store()->WriteData(batch.get(), unique_local.cache_guid(), + unique_local.SerializeAsString()); + store()->WriteData(batch.get(), conflict_local.cache_guid(), + conflict_local.SerializeAsString()); + store()->CommitWriteBatch(std::move(batch), + base::Bind(&AssertResultIsSuccess)); + + InitializeAndPumpAndStart(); + EXPECT_EQ(1, change_count()); + + EntityDataMap remote_input; + remote_input[conflict_remote.cache_guid()] = + SpecificsToEntity(conflict_remote); + remote_input[unique_remote.cache_guid()] = SpecificsToEntity(unique_remote); + + DataTypeState state; + state.set_encryption_key_name("ekn"); + std::unique_ptr<MetadataChangeList> metadata_changes( + service()->CreateMetadataChangeList()); + metadata_changes->UpdateDataTypeState(state); + + const SyncError error = + service()->MergeSyncData(std::move(metadata_changes), remote_input); + EXPECT_FALSE(error.IsSet()); + EXPECT_EQ(2, change_count()); + + // The remote should beat the local in conflict. + EXPECT_EQ(4u, service()->GetAllDeviceInfo().size()); + AssertEqual(unique_local, + *service()->GetDeviceInfo(unique_local.cache_guid()).get()); + AssertEqual(unique_remote, + *service()->GetDeviceInfo(unique_remote.cache_guid()).get()); + AssertEqual(conflict_remote, *service()->GetDeviceInfo(conflict_guid).get()); + + // Service should have told the processor about the existance of unique_local. + EXPECT_TRUE(processor()->delete_set().empty()); + EXPECT_EQ(2u, processor()->put_map().size()); + const auto& it = processor()->put_map().find(unique_local.cache_guid()); + ASSERT_NE(processor()->put_map().end(), it); + AssertEqual(unique_local, it->second->specifics.device_info()); + + RestartService(); + ASSERT_EQ(state.encryption_key_name(), + processor()->metadata()->GetDataTypeState().encryption_key_name()); +} + +TEST_F(DeviceInfoServiceTest, MergeLocalGuid) { + const DeviceInfo* local_device_info = local_device()->GetLocalDeviceInfo(); + std::unique_ptr<DeviceInfoSpecifics> specifics( + CopyToSpecifics(*local_device_info)); + specifics->set_last_updated_timestamp(syncer::TimeToProtoTime(Time::Now())); + const std::string guid = local_device_info->guid(); + + std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch(); + store()->WriteData(batch.get(), guid, specifics->SerializeAsString()); + store()->CommitWriteBatch(std::move(batch), + base::Bind(&AssertResultIsSuccess)); + + InitializeAndPumpAndStart(); + + EntityDataMap remote_input; + remote_input[guid] = SpecificsToEntity(*specifics); + + const SyncError error = service()->MergeSyncData( + service()->CreateMetadataChangeList(), remote_input); + EXPECT_FALSE(error.IsSet()); + EXPECT_EQ(0, change_count()); + EXPECT_EQ(1u, service()->GetAllDeviceInfo().size()); + EXPECT_TRUE(processor()->delete_set().empty()); + EXPECT_TRUE(processor()->put_map().empty()); +} + +TEST_F(DeviceInfoServiceTest, GetLastUpdateTime) { + Time time1(Time() + TimeDelta::FromDays(1)); + + DeviceInfoSpecifics specifics1(GenerateTestSpecifics()); + DeviceInfoSpecifics specifics2(GenerateTestSpecifics()); + specifics2.set_last_updated_timestamp(syncer::TimeToProtoTime(time1)); + + EXPECT_EQ(Time(), GetLastUpdateTime(specifics1)); + EXPECT_EQ(time1, GetLastUpdateTime(specifics2)); +} + +TEST_F(DeviceInfoServiceTest, CountActiveDevices) { + InitializeAndPump(); + EXPECT_EQ(0, service()->CountActiveDevices()); + + DeviceInfoSpecifics specifics = + GenerateTestSpecifics(local_device()->GetLocalDeviceInfo()->guid()); + EntityChangeList change_list; + PushBackEntityChangeAdd(specifics, &change_list); + service()->ApplySyncChanges(service()->CreateMetadataChangeList(), + change_list); + EXPECT_EQ(0, service()->CountActiveDevices()); + + change_list.clear(); + specifics.set_last_updated_timestamp(syncer::TimeToProtoTime(Time::Now())); + PushBackEntityChangeAdd(specifics, &change_list); + service()->ApplySyncChanges(service()->CreateMetadataChangeList(), + change_list); + EXPECT_EQ(0, service()->CountActiveDevices()); + + change_list.clear(); + specifics.set_cache_guid("non-local"); + PushBackEntityChangeAdd(specifics, &change_list); + service()->ApplySyncChanges(service()->CreateMetadataChangeList(), + change_list); + EXPECT_EQ(1, service()->CountActiveDevices()); +} + +} // namespace + +} // namespace sync_driver_v2
diff --git a/components/sync/driver/device_info_sync_service.cc b/components/sync/driver/device_info_sync_service.cc new file mode 100644 index 0000000..cfc4d305 --- /dev/null +++ b/components/sync/driver/device_info_sync_service.cc
@@ -0,0 +1,335 @@ +// 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 "components/sync/driver/device_info_sync_service.h" + +#include <stddef.h> + +#include <algorithm> +#include <utility> + +#include "base/memory/ptr_util.h" +#include "base/time/time.h" +#include "components/sync/api/sync_change.h" +#include "components/sync/base/time.h" +#include "components/sync/driver/device_info_util.h" +#include "components/sync/driver/local_device_info_provider.h" +#include "components/sync/protocol/sync.pb.h" + +namespace sync_driver { + +using base::Time; +using base::TimeDelta; +using syncer::ModelType; +using syncer::SyncChange; +using syncer::SyncChangeList; +using syncer::SyncChangeProcessor; +using syncer::SyncData; +using syncer::SyncDataList; +using syncer::SyncErrorFactory; +using syncer::SyncMergeResult; + +DeviceInfoSyncService::DeviceInfoSyncService( + LocalDeviceInfoProvider* local_device_info_provider) + : local_device_info_provider_(local_device_info_provider) { + DCHECK(local_device_info_provider); +} + +DeviceInfoSyncService::~DeviceInfoSyncService() {} + +SyncMergeResult DeviceInfoSyncService::MergeDataAndStartSyncing( + ModelType type, + const SyncDataList& initial_sync_data, + std::unique_ptr<SyncChangeProcessor> sync_processor, + std::unique_ptr<SyncErrorFactory> error_handler) { + DCHECK(sync_processor.get()); + DCHECK(error_handler.get()); + DCHECK_EQ(type, syncer::DEVICE_INFO); + + DCHECK(!IsSyncing()); + + sync_processor_ = std::move(sync_processor); + error_handler_ = std::move(error_handler); + + // Initialization should be completed before this type is enabled + // and local device info must be available. + const DeviceInfo* local_device_info = + local_device_info_provider_->GetLocalDeviceInfo(); + DCHECK(local_device_info != NULL); + + // Indicates whether a local device has been added or updated. + // |change_type| defaults to ADD and might be changed to + // UPDATE to INVALID down below if the initial data contains + // data matching the local device ID. + SyncChange::SyncChangeType change_type = SyncChange::ACTION_ADD; + TimeDelta pulse_delay; + size_t num_items_new = 0; + size_t num_items_updated = 0; + + // Iterate over all initial sync data and copy it to the cache. + for (SyncDataList::const_iterator iter = initial_sync_data.begin(); + iter != initial_sync_data.end(); ++iter) { + DCHECK_EQ(syncer::DEVICE_INFO, iter->GetDataType()); + + const std::string& id = iter->GetSpecifics().device_info().cache_guid(); + + if (id == local_device_info->guid()) { + // |initial_sync_data| contains data matching the local device. + std::unique_ptr<DeviceInfo> synced_local_device_info = + base::WrapUnique(CreateDeviceInfo(*iter)); + + pulse_delay = DeviceInfoUtil::CalculatePulseDelay( + GetLastUpdateTime(*iter), Time::Now()); + // Store the synced device info for the local device only if + // it is the same as the local info. Otherwise store the local + // device info and issue a change further below after finishing + // processing the |initial_sync_data|. + if (synced_local_device_info->Equals(*local_device_info) && + !pulse_delay.is_zero()) { + change_type = SyncChange::ACTION_INVALID; + } else { + num_items_updated++; + change_type = SyncChange::ACTION_UPDATE; + continue; + } + } else { + // A new device that doesn't match the local device. + num_items_new++; + } + + StoreSyncData(id, *iter); + } + + syncer::SyncMergeResult result(type); + + // If the SyncData for the local device is new or different then send it + // immediately, otherwise wait until the pulse interval has elapsed from the + // previous update. Regardless of the branch here we setup a timer loop with + // SendLocalData such that we continue pulsing every interval. + if (change_type == SyncChange::ACTION_INVALID) { + pulse_timer_.Start( + FROM_HERE, pulse_delay, + base::Bind(&DeviceInfoSyncService::SendLocalData, + base::Unretained(this), SyncChange::ACTION_UPDATE)); + } else { + SendLocalData(change_type); + } + + result.set_num_items_before_association(1); + result.set_num_items_after_association(all_data_.size()); + result.set_num_items_added(num_items_new); + result.set_num_items_modified(num_items_updated); + result.set_num_items_deleted(0); + + NotifyObservers(); + + return result; +} + +bool DeviceInfoSyncService::IsSyncing() const { + return !all_data_.empty(); +} + +void DeviceInfoSyncService::StopSyncing(syncer::ModelType type) { + bool was_syncing = IsSyncing(); + + pulse_timer_.Stop(); + all_data_.clear(); + sync_processor_.reset(); + error_handler_.reset(); + + if (was_syncing) { + NotifyObservers(); + } +} + +SyncDataList DeviceInfoSyncService::GetAllSyncData( + syncer::ModelType type) const { + SyncDataList list; + + for (SyncDataMap::const_iterator iter = all_data_.begin(); + iter != all_data_.end(); ++iter) { + list.push_back(iter->second); + } + + return list; +} + +syncer::SyncError DeviceInfoSyncService::ProcessSyncChanges( + const tracked_objects::Location& from_here, + const SyncChangeList& change_list) { + syncer::SyncError error; + + DCHECK(local_device_info_provider_->GetLocalDeviceInfo()); + const std::string& local_device_id = + local_device_info_provider_->GetLocalDeviceInfo()->guid(); + + bool has_changes = false; + + // Iterate over all chanages and merge entries. + for (SyncChangeList::const_iterator iter = change_list.begin(); + iter != change_list.end(); ++iter) { + const SyncData& sync_data = iter->sync_data(); + DCHECK_EQ(syncer::DEVICE_INFO, sync_data.GetDataType()); + + const std::string& client_id = + sync_data.GetSpecifics().device_info().cache_guid(); + // Ignore device info matching the local device. + if (local_device_id == client_id) { + DVLOG(1) << "Ignoring sync changes for the local DEVICE_INFO"; + continue; + } + + if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) { + has_changes = true; + DeleteSyncData(client_id); + } else if (iter->change_type() == syncer::SyncChange::ACTION_UPDATE || + iter->change_type() == syncer::SyncChange::ACTION_ADD) { + has_changes = true; + StoreSyncData(client_id, sync_data); + } else { + error.Reset(FROM_HERE, "Invalid action received.", syncer::DEVICE_INFO); + } + } + + if (has_changes) { + NotifyObservers(); + } + + return error; +} + +std::unique_ptr<DeviceInfo> DeviceInfoSyncService::GetDeviceInfo( + const std::string& client_id) const { + SyncDataMap::const_iterator iter = all_data_.find(client_id); + if (iter == all_data_.end()) { + return std::unique_ptr<DeviceInfo>(); + } + + return base::WrapUnique(CreateDeviceInfo(iter->second)); +} + +ScopedVector<DeviceInfo> DeviceInfoSyncService::GetAllDeviceInfo() const { + ScopedVector<DeviceInfo> list; + + for (SyncDataMap::const_iterator iter = all_data_.begin(); + iter != all_data_.end(); ++iter) { + list.push_back(CreateDeviceInfo(iter->second)); + } + + return list; +} + +void DeviceInfoSyncService::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void DeviceInfoSyncService::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +int DeviceInfoSyncService::CountActiveDevices() const { + return CountActiveDevices(Time::Now()); +} + +void DeviceInfoSyncService::NotifyObservers() { + FOR_EACH_OBSERVER(Observer, observers_, OnDeviceInfoChange()); +} + +SyncData DeviceInfoSyncService::CreateLocalData(const DeviceInfo* info) { + sync_pb::EntitySpecifics entity; + sync_pb::DeviceInfoSpecifics& specifics = *entity.mutable_device_info(); + + specifics.set_cache_guid(info->guid()); + specifics.set_client_name(info->client_name()); + specifics.set_chrome_version(info->chrome_version()); + specifics.set_sync_user_agent(info->sync_user_agent()); + specifics.set_device_type(info->device_type()); + specifics.set_signin_scoped_device_id(info->signin_scoped_device_id()); + specifics.set_last_updated_timestamp(syncer::TimeToProtoTime(Time::Now())); + + return CreateLocalData(entity); +} + +SyncData DeviceInfoSyncService::CreateLocalData( + const sync_pb::EntitySpecifics& entity) { + const sync_pb::DeviceInfoSpecifics& specifics = entity.device_info(); + return SyncData::CreateLocalData(DeviceInfoUtil::SpecificsToTag(specifics), + specifics.client_name(), entity); +} + +DeviceInfo* DeviceInfoSyncService::CreateDeviceInfo( + const syncer::SyncData& sync_data) { + const sync_pb::DeviceInfoSpecifics& specifics = + sync_data.GetSpecifics().device_info(); + + return new DeviceInfo(specifics.cache_guid(), specifics.client_name(), + specifics.chrome_version(), specifics.sync_user_agent(), + specifics.device_type(), + specifics.signin_scoped_device_id()); +} + +void DeviceInfoSyncService::StoreSyncData(const std::string& client_id, + const SyncData& sync_data) { + DVLOG(1) << "Storing DEVICE_INFO for " + << sync_data.GetSpecifics().device_info().client_name() + << " with ID " << client_id; + all_data_[client_id] = sync_data; +} + +void DeviceInfoSyncService::DeleteSyncData(const std::string& client_id) { + SyncDataMap::iterator iter = all_data_.find(client_id); + if (iter != all_data_.end()) { + DVLOG(1) << "Deleting DEVICE_INFO for " + << iter->second.GetSpecifics().device_info().client_name() + << " with ID " << client_id; + all_data_.erase(iter); + } +} + +void DeviceInfoSyncService::SendLocalData( + const SyncChange::SyncChangeType change_type) { + DCHECK_NE(change_type, SyncChange::ACTION_INVALID); + DCHECK(sync_processor_); + + const DeviceInfo* device_info = + local_device_info_provider_->GetLocalDeviceInfo(); + const SyncData& data = CreateLocalData(device_info); + StoreSyncData(device_info->guid(), data); + + SyncChangeList change_list; + change_list.push_back(SyncChange(FROM_HERE, change_type, data)); + sync_processor_->ProcessSyncChanges(FROM_HERE, change_list); + + pulse_timer_.Start( + FROM_HERE, DeviceInfoUtil::kPulseInterval, + base::Bind(&DeviceInfoSyncService::SendLocalData, base::Unretained(this), + SyncChange::ACTION_UPDATE)); +} + +int DeviceInfoSyncService::CountActiveDevices(const Time now) const { + return std::count_if(all_data_.begin(), all_data_.end(), + [now](SyncDataMap::const_reference pair) { + return DeviceInfoUtil::IsActive( + GetLastUpdateTime(pair.second), now); + }); +} + +// static +Time DeviceInfoSyncService::GetLastUpdateTime(const SyncData& device_info) { + if (device_info.GetSpecifics().device_info().has_last_updated_timestamp()) { + return syncer::ProtoTimeToTime( + device_info.GetSpecifics().device_info().last_updated_timestamp()); + } else if (!device_info.IsLocal()) { + // If there is no |last_updated_timestamp| present, fallback to mod time. + return syncer::SyncDataRemote(device_info).GetModifiedTime(); + } else { + // We shouldn't reach this point for remote data, so this means we're likely + // looking at the local device info. Using a long ago time is perfect, since + // the desired behavior is to update/pulse our data as soon as possible. + return Time(); + } +} + +} // namespace sync_driver
diff --git a/components/sync/driver/device_info_sync_service.h b/components/sync/driver/device_info_sync_service.h new file mode 100644 index 0000000..aed9e12 --- /dev/null +++ b/components/sync/driver/device_info_sync_service.h
@@ -0,0 +1,111 @@ +// 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 COMPONENTS_SYNC_DRIVER_DEVICE_INFO_SYNC_SERVICE_H_ +#define COMPONENTS_SYNC_DRIVER_DEVICE_INFO_SYNC_SERVICE_H_ + +#include <stdint.h> + +#include <map> +#include <memory> +#include <string> + +#include "base/macros.h" +#include "base/memory/scoped_vector.h" +#include "base/observer_list.h" +#include "base/time/time.h" +#include "base/timer/timer.h" +#include "components/sync/api/sync_change.h" +#include "components/sync/api/sync_change_processor.h" +#include "components/sync/api/sync_data.h" +#include "components/sync/api/sync_error_factory.h" +#include "components/sync/api/syncable_service.h" +#include "components/sync/driver/device_info_tracker.h" + +namespace sync_driver { + +class LocalDeviceInfoProvider; + +// SyncableService implementation for DEVICE_INFO model type. +class DeviceInfoSyncService : public syncer::SyncableService, + public DeviceInfoTracker { + public: + explicit DeviceInfoSyncService( + LocalDeviceInfoProvider* local_device_info_provider); + ~DeviceInfoSyncService() override; + + // syncer::SyncableService implementation. + syncer::SyncMergeResult MergeDataAndStartSyncing( + syncer::ModelType type, + const syncer::SyncDataList& initial_sync_data, + std::unique_ptr<syncer::SyncChangeProcessor> sync_processor, + std::unique_ptr<syncer::SyncErrorFactory> error_handler) override; + void StopSyncing(syncer::ModelType type) override; + syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override; + syncer::SyncError ProcessSyncChanges( + const tracked_objects::Location& from_here, + const syncer::SyncChangeList& change_list) override; + + // DeviceInfoTracker implementation. + bool IsSyncing() const override; + std::unique_ptr<DeviceInfo> GetDeviceInfo( + const std::string& client_id) const override; + ScopedVector<DeviceInfo> GetAllDeviceInfo() const override; + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + int CountActiveDevices() const override; + + private: + friend class DeviceInfoSyncServiceTest; + + // Create SyncData from local DeviceInfo. + syncer::SyncData CreateLocalData(const DeviceInfo* info); + // Create SyncData from EntitySpecifics. + static syncer::SyncData CreateLocalData( + const sync_pb::EntitySpecifics& entity); + + // Allocate new DeviceInfo from SyncData. + static DeviceInfo* CreateDeviceInfo(const syncer::SyncData& sync_data); + // Store SyncData in the cache. + void StoreSyncData(const std::string& client_id, + const syncer::SyncData& sync_data); + // Delete SyncData from the cache. + void DeleteSyncData(const std::string& client_id); + // Notify all registered observers. + void NotifyObservers(); + + // Sends a copy of the current device's state to the processor/sync. + void SendLocalData(const syncer::SyncChange::SyncChangeType change_type); + + // Finds the number of active devices give the current time, which allows for + // better unit tests. + int CountActiveDevices(const base::Time now) const; + + // Find the timestamp for the last time this |device_info| was edited. + static base::Time GetLastUpdateTime(const syncer::SyncData& device_info); + + // |local_device_info_provider_| isn't owned. + const LocalDeviceInfoProvider* const local_device_info_provider_; + + // Receives ownership of |sync_processor_| and |error_handler_| in + // MergeDataAndStartSyncing() and destroy them in StopSyncing(). + std::unique_ptr<syncer::SyncChangeProcessor> sync_processor_; + std::unique_ptr<syncer::SyncErrorFactory> error_handler_; + + // Cache of all syncable and local data. + typedef std::map<std::string, syncer::SyncData> SyncDataMap; + SyncDataMap all_data_; + + // Registered observers, not owned. + base::ObserverList<Observer, true> observers_; + + // Used to update our local device info once every pulse interval. + base::OneShotTimer pulse_timer_; + + DISALLOW_COPY_AND_ASSIGN(DeviceInfoSyncService); +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_DEVICE_INFO_SYNC_SERVICE_H_
diff --git a/components/sync/driver/device_info_sync_service_unittest.cc b/components/sync/driver/device_info_sync_service_unittest.cc new file mode 100644 index 0000000..48ed8305 --- /dev/null +++ b/components/sync/driver/device_info_sync_service_unittest.cc
@@ -0,0 +1,581 @@ +// 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 "components/sync/driver/device_info_sync_service.h" + +#include <stddef.h> +#include <stdint.h> + +#include <string> + +#include "base/message_loop/message_loop.h" +#include "components/sync/api/sync_change.h" +#include "components/sync/api/sync_change_processor.h" +#include "components/sync/api/sync_change_processor_wrapper_for_test.h" +#include "components/sync/api/sync_error_factory_mock.h" +#include "components/sync/base/time.h" +#include "components/sync/core/attachments/attachment_service_proxy_for_test.h" +#include "components/sync/driver/device_info_util.h" +#include "components/sync/driver/local_device_info_provider_mock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using base::Time; +using base::TimeDelta; +using syncer::AttachmentIdList; +using syncer::AttachmentServiceProxyForTest; +using syncer::ModelType; +using syncer::SyncChange; +using syncer::SyncChangeList; +using syncer::SyncChangeProcessor; +using syncer::SyncChangeProcessorWrapperForTest; +using syncer::SyncData; +using syncer::SyncDataList; +using syncer::SyncError; +using syncer::SyncErrorFactory; +using syncer::SyncErrorFactoryMock; +using syncer::SyncMergeResult; +using sync_pb::EntitySpecifics; + +namespace sync_driver { + +namespace { + +class TestChangeProcessor : public SyncChangeProcessor { + public: + TestChangeProcessor() {} + ~TestChangeProcessor() override {} + + // SyncChangeProcessor implementation. + // Store a copy of all the changes passed in so we can examine them later. + SyncError ProcessSyncChanges(const tracked_objects::Location& from_here, + const SyncChangeList& change_list) override { + change_list_ = change_list; + return SyncError(); + } + + // This method isn't used in these tests. + SyncDataList GetAllSyncData(ModelType type) const override { + return SyncDataList(); + } + + size_t change_list_size() const { return change_list_.size(); } + + SyncChange::SyncChangeType change_type_at(size_t index) const { + CHECK_LT(index, change_list_size()); + return change_list_[index].change_type(); + } + + const sync_pb::DeviceInfoSpecifics& device_info_at(size_t index) const { + CHECK_LT(index, change_list_size()); + return change_list_[index].sync_data().GetSpecifics().device_info(); + } + + const std::string& cache_guid_at(size_t index) const { + return device_info_at(index).cache_guid(); + } + + const std::string& client_name_at(size_t index) const { + return device_info_at(index).client_name(); + } + + private: + SyncChangeList change_list_; +}; + +} // namespace + +class DeviceInfoSyncServiceTest : public testing::Test, + public DeviceInfoTracker::Observer { + public: + DeviceInfoSyncServiceTest() : num_device_info_changed_callbacks_(0) {} + ~DeviceInfoSyncServiceTest() override {} + + void SetUp() override { + local_device_.reset(new LocalDeviceInfoProviderMock( + "guid_1", "client_1", "Chromium 10k", "Chrome 10k", + sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id")); + sync_service_.reset(new DeviceInfoSyncService(local_device_.get())); + sync_processor_.reset(new TestChangeProcessor()); + // Register observer + sync_service_->AddObserver(this); + } + + void TearDown() override { sync_service_->RemoveObserver(this); } + + void OnDeviceInfoChange() override { num_device_info_changed_callbacks_++; } + + std::unique_ptr<SyncChangeProcessor> PassProcessor() { + return std::unique_ptr<SyncChangeProcessor>( + new SyncChangeProcessorWrapperForTest(sync_processor_.get())); + } + + std::unique_ptr<SyncErrorFactory> CreateAndPassSyncErrorFactory() { + return std::unique_ptr<SyncErrorFactory>(new SyncErrorFactoryMock()); + } + + sync_pb::EntitySpecifics CreateEntitySpecifics( + const std::string& client_id, + const std::string& client_name) { + sync_pb::EntitySpecifics entity; + sync_pb::DeviceInfoSpecifics& specifics = *entity.mutable_device_info(); + + specifics.set_cache_guid(client_id); + specifics.set_client_name(client_name); + specifics.set_chrome_version("Chromium 10k"); + specifics.set_sync_user_agent("Chrome 10k"); + specifics.set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_LINUX); + specifics.set_signin_scoped_device_id("device_id"); + return entity; + } + + // Default |last_updated_timestamp| to now to avoid pulse update on merge. + SyncData CreateRemoteData(const std::string& client_id, + const std::string& client_name, + Time last_updated_timestamp = Time::Now()) { + sync_pb::EntitySpecifics entity( + CreateEntitySpecifics(client_id, client_name)); + entity.mutable_device_info()->set_last_updated_timestamp( + syncer::TimeToProtoTime(last_updated_timestamp)); + return SyncData::CreateRemoteData(1, entity, Time(), AttachmentIdList(), + AttachmentServiceProxyForTest::Create()); + } + + void AddInitialData(SyncDataList* sync_data_list, + const std::string& client_id, + const std::string& client_name) { + SyncData sync_data = CreateRemoteData(client_id, client_name); + sync_data_list->push_back(sync_data); + } + + void AddChange(SyncChangeList* change_list, + SyncChange::SyncChangeType change_type, + const std::string& client_id, + const std::string& client_name) { + SyncData sync_data = CreateRemoteData(client_id, client_name); + SyncChange sync_change(FROM_HERE, change_type, sync_data); + change_list->push_back(sync_change); + } + + protected: + // Private method wrappers through friend class. + Time GetLastUpdateTime(const syncer::SyncData& data) { + return sync_service_->GetLastUpdateTime(data); + } + int CountActiveDevices(const Time now) { + return sync_service_->CountActiveDevices(now); + } + void StoreSyncData(const std::string& client_id, + const syncer::SyncData& sync_data) { + sync_service_->StoreSyncData(client_id, sync_data); + } + bool IsPulseTimerRunning() { return sync_service_->pulse_timer_.IsRunning(); } + + // Needs to be created for OneShotTimer to grab the current task runner. + base::MessageLoop message_loop_; + + int num_device_info_changed_callbacks_; + std::unique_ptr<LocalDeviceInfoProviderMock> local_device_; + std::unique_ptr<DeviceInfoSyncService> sync_service_; + std::unique_ptr<TestChangeProcessor> sync_processor_; +}; + +namespace { + +// Sync with empty initial data. +TEST_F(DeviceInfoSyncServiceTest, StartSyncEmptyInitialData) { + EXPECT_FALSE(sync_service_->IsSyncing()); + + SyncMergeResult merge_result = sync_service_->MergeDataAndStartSyncing( + syncer::DEVICE_INFO, SyncDataList(), PassProcessor(), + CreateAndPassSyncErrorFactory()); + + EXPECT_TRUE(sync_service_->IsSyncing()); + EXPECT_EQ(0, merge_result.num_items_added()); + EXPECT_EQ(0, merge_result.num_items_modified()); + EXPECT_EQ(0, merge_result.num_items_deleted()); + EXPECT_EQ(1, merge_result.num_items_before_association()); + EXPECT_EQ(1, merge_result.num_items_after_association()); + EXPECT_EQ(SyncChange::ACTION_ADD, sync_processor_->change_type_at(0)); + + EXPECT_EQ(1U, sync_processor_->change_list_size()); + EXPECT_EQ("guid_1", sync_processor_->cache_guid_at(0)); + + // Should have one device info corresponding to local device info. + EXPECT_EQ(1U, sync_service_->GetAllSyncData(syncer::DEVICE_INFO).size()); + EXPECT_EQ(1U, sync_service_->GetAllDeviceInfo().size()); + EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_1")); + EXPECT_FALSE(sync_service_->GetDeviceInfo("guid_0")); +} + +TEST_F(DeviceInfoSyncServiceTest, StopSyncing) { + SyncMergeResult merge_result = sync_service_->MergeDataAndStartSyncing( + syncer::DEVICE_INFO, SyncDataList(), PassProcessor(), + CreateAndPassSyncErrorFactory()); + EXPECT_TRUE(sync_service_->IsSyncing()); + EXPECT_EQ(1, num_device_info_changed_callbacks_); + EXPECT_TRUE(IsPulseTimerRunning()); + sync_service_->StopSyncing(syncer::DEVICE_INFO); + EXPECT_FALSE(sync_service_->IsSyncing()); + EXPECT_EQ(2, num_device_info_changed_callbacks_); + EXPECT_FALSE(IsPulseTimerRunning()); +} + +// Sync with initial data matching the local device data. +TEST_F(DeviceInfoSyncServiceTest, StartSyncMatchingInitialData) { + SyncDataList sync_data; + AddInitialData(&sync_data, "guid_1", "client_1"); + + SyncMergeResult merge_result = sync_service_->MergeDataAndStartSyncing( + syncer::DEVICE_INFO, sync_data, PassProcessor(), + CreateAndPassSyncErrorFactory()); + EXPECT_EQ(0, merge_result.num_items_added()); + EXPECT_EQ(0, merge_result.num_items_modified()); + EXPECT_EQ(0, merge_result.num_items_deleted()); + EXPECT_EQ(1, merge_result.num_items_before_association()); + EXPECT_EQ(1, merge_result.num_items_after_association()); + + // No changes expected because the device info matches. + EXPECT_EQ(0U, sync_processor_->change_list_size()); + + EXPECT_EQ(1U, sync_service_->GetAllSyncData(syncer::DEVICE_INFO).size()); + EXPECT_EQ(1U, sync_service_->GetAllDeviceInfo().size()); + EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_1")); + EXPECT_FALSE(sync_service_->GetDeviceInfo("guid_0")); +} + +// Sync with misc initial data. +TEST_F(DeviceInfoSyncServiceTest, StartSync) { + SyncDataList sync_data; + AddInitialData(&sync_data, "guid_2", "foo"); + AddInitialData(&sync_data, "guid_3", "bar"); + // This guid matches the local device but the client name is different. + AddInitialData(&sync_data, "guid_1", "baz"); + + SyncMergeResult merge_result = sync_service_->MergeDataAndStartSyncing( + syncer::DEVICE_INFO, sync_data, PassProcessor(), + CreateAndPassSyncErrorFactory()); + + EXPECT_EQ(2, merge_result.num_items_added()); + EXPECT_EQ(1, merge_result.num_items_modified()); + EXPECT_EQ(0, merge_result.num_items_deleted()); + EXPECT_EQ(1, merge_result.num_items_before_association()); + EXPECT_EQ(3, merge_result.num_items_after_association()); + + EXPECT_EQ(1U, sync_processor_->change_list_size()); + EXPECT_EQ(SyncChange::ACTION_UPDATE, sync_processor_->change_type_at(0)); + EXPECT_EQ("client_1", sync_processor_->client_name_at(0)); + + EXPECT_EQ(3U, sync_service_->GetAllSyncData(syncer::DEVICE_INFO).size()); + EXPECT_EQ(3U, sync_service_->GetAllDeviceInfo().size()); + EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_1")); + EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_2")); + EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_3")); + EXPECT_FALSE(sync_service_->GetDeviceInfo("guid_0")); +} + +// Process sync change with ACTION_ADD. +// Verify callback. +TEST_F(DeviceInfoSyncServiceTest, ProcessAddChange) { + EXPECT_EQ(0, num_device_info_changed_callbacks_); + + // Start with an empty initial data. + SyncMergeResult merge_result = sync_service_->MergeDataAndStartSyncing( + syncer::DEVICE_INFO, SyncDataList(), PassProcessor(), + CreateAndPassSyncErrorFactory()); + // There should be only one item corresponding to the local device + EXPECT_EQ(1, merge_result.num_items_after_association()); + EXPECT_EQ(1, num_device_info_changed_callbacks_); + + // Add a new device info with a non-matching guid. + SyncChangeList change_list; + AddChange(&change_list, SyncChange::ACTION_ADD, "guid_2", "foo"); + + SyncError error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list); + EXPECT_FALSE(error.IsSet()); + EXPECT_EQ(2, num_device_info_changed_callbacks_); + + EXPECT_EQ(2U, sync_service_->GetAllDeviceInfo().size()); + + EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_1")); + EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_2")); + EXPECT_FALSE(sync_service_->GetDeviceInfo("guid_0")); +} + +// Process multiple sync change with ACTION_UPDATE and ACTION_ADD. +// Verify that callback is called multiple times. +TEST_F(DeviceInfoSyncServiceTest, ProcessMultipleChanges) { + SyncDataList sync_data; + AddInitialData(&sync_data, "guid_2", "foo"); + AddInitialData(&sync_data, "guid_3", "bar"); + + SyncMergeResult merge_result = sync_service_->MergeDataAndStartSyncing( + syncer::DEVICE_INFO, sync_data, PassProcessor(), + CreateAndPassSyncErrorFactory()); + EXPECT_EQ(3, merge_result.num_items_after_association()); + // reset callbacks counter + num_device_info_changed_callbacks_ = 0; + + SyncChangeList change_list; + AddChange(&change_list, SyncChange::ACTION_UPDATE, "guid_2", "foo_2"); + + SyncError error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list); + EXPECT_FALSE(error.IsSet()); + + EXPECT_EQ(1, num_device_info_changed_callbacks_); + EXPECT_EQ(3U, sync_service_->GetAllDeviceInfo().size()); + EXPECT_EQ("foo_2", sync_service_->GetDeviceInfo("guid_2")->client_name()); + + change_list.clear(); + AddChange(&change_list, SyncChange::ACTION_UPDATE, "guid_3", "bar_3"); + AddChange(&change_list, SyncChange::ACTION_ADD, "guid_4", "baz_4"); + + error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list); + EXPECT_FALSE(error.IsSet()); + + EXPECT_EQ(2, num_device_info_changed_callbacks_); + EXPECT_EQ(4U, sync_service_->GetAllDeviceInfo().size()); + EXPECT_EQ("bar_3", sync_service_->GetDeviceInfo("guid_3")->client_name()); + EXPECT_EQ("baz_4", sync_service_->GetDeviceInfo("guid_4")->client_name()); +} + +// Process update to the local device info and verify that it is ignored. +TEST_F(DeviceInfoSyncServiceTest, ProcessUpdateChangeMatchingLocalDevice) { + SyncMergeResult merge_result = sync_service_->MergeDataAndStartSyncing( + syncer::DEVICE_INFO, SyncDataList(), PassProcessor(), + CreateAndPassSyncErrorFactory()); + EXPECT_EQ(1, merge_result.num_items_after_association()); + // reset callbacks counter + num_device_info_changed_callbacks_ = 0; + + SyncChangeList change_list; + AddChange(&change_list, SyncChange::ACTION_UPDATE, "guid_1", "foo_1"); + + SyncError error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list); + EXPECT_FALSE(error.IsSet()); + // Callback shouldn't be sent in this case. + EXPECT_EQ(0, num_device_info_changed_callbacks_); + // Should still have the old local device Info. + EXPECT_EQ(1U, sync_service_->GetAllDeviceInfo().size()); + EXPECT_EQ("client_1", sync_service_->GetDeviceInfo("guid_1")->client_name()); +} + +// Process sync change with ACTION_DELETE. +TEST_F(DeviceInfoSyncServiceTest, ProcessDeleteChange) { + SyncDataList sync_data; + AddInitialData(&sync_data, "guid_2", "foo"); + AddInitialData(&sync_data, "guid_3", "bar"); + + SyncMergeResult merge_result = sync_service_->MergeDataAndStartSyncing( + syncer::DEVICE_INFO, sync_data, PassProcessor(), + CreateAndPassSyncErrorFactory()); + EXPECT_EQ(3, merge_result.num_items_after_association()); + // reset callbacks counter + num_device_info_changed_callbacks_ = 0; + + SyncChangeList change_list; + AddChange(&change_list, SyncChange::ACTION_DELETE, "guid_2", "foo_2"); + + SyncError error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list); + EXPECT_FALSE(error.IsSet()); + + EXPECT_EQ(1, num_device_info_changed_callbacks_); + EXPECT_EQ(2U, sync_service_->GetAllDeviceInfo().size()); + EXPECT_FALSE(sync_service_->GetDeviceInfo("guid_2")); +} + +// Process sync change with unexpected action. +TEST_F(DeviceInfoSyncServiceTest, ProcessInvalidChange) { + SyncMergeResult merge_result = sync_service_->MergeDataAndStartSyncing( + syncer::DEVICE_INFO, SyncDataList(), PassProcessor(), + CreateAndPassSyncErrorFactory()); + EXPECT_EQ(1, merge_result.num_items_after_association()); + // reset callbacks counter + num_device_info_changed_callbacks_ = 0; + + SyncChangeList change_list; + AddChange(&change_list, (SyncChange::SyncChangeType)100, "guid_2", "foo_2"); + + SyncError error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list); + EXPECT_TRUE(error.IsSet()); + + // The number of callback should still be zero. + EXPECT_EQ(0, num_device_info_changed_callbacks_); + EXPECT_EQ(1U, sync_service_->GetAllDeviceInfo().size()); +} + +// Process sync change after unsubscribing from notifications. +TEST_F(DeviceInfoSyncServiceTest, ProcessChangesAfterUnsubscribing) { + SyncMergeResult merge_result = sync_service_->MergeDataAndStartSyncing( + syncer::DEVICE_INFO, SyncDataList(), PassProcessor(), + CreateAndPassSyncErrorFactory()); + EXPECT_EQ(1, merge_result.num_items_after_association()); + // reset callbacks counter + num_device_info_changed_callbacks_ = 0; + + SyncChangeList change_list; + AddChange(&change_list, SyncChange::ACTION_ADD, "guid_2", "foo_2"); + + // Unsubscribe observer before processing changes. + sync_service_->RemoveObserver(this); + + SyncError error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list); + EXPECT_FALSE(error.IsSet()); + + // The number of callback should still be zero. + EXPECT_EQ(0, num_device_info_changed_callbacks_); +} + +// While the initial data will match the current device, the last modified time +// should be greater than the threshold and cause an update anyways. +TEST_F(DeviceInfoSyncServiceTest, StartSyncMatchingButStale) { + SyncDataList sync_data; + sync_data.push_back(CreateRemoteData("guid_1", "foo_1", Time())); + SyncMergeResult merge_result = sync_service_->MergeDataAndStartSyncing( + syncer::DEVICE_INFO, sync_data, PassProcessor(), + CreateAndPassSyncErrorFactory()); + + EXPECT_EQ(1U, sync_processor_->change_list_size()); + EXPECT_EQ(SyncChange::ACTION_UPDATE, sync_processor_->change_type_at(0)); + EXPECT_EQ("guid_1", sync_processor_->cache_guid_at(0)); + EXPECT_EQ("client_1", sync_processor_->client_name_at(0)); +} + +TEST_F(DeviceInfoSyncServiceTest, GetLastUpdateTime) { + Time time1(Time() + TimeDelta::FromDays(1)); + Time time2(Time() + TimeDelta::FromDays(2)); + + SyncData localA( + SyncData::CreateLocalData("a", "a", CreateEntitySpecifics("a", "a"))); + + EntitySpecifics entityB(CreateEntitySpecifics("b", "b")); + entityB.mutable_device_info()->set_last_updated_timestamp( + syncer::TimeToProtoTime(time1)); + SyncData localB(SyncData::CreateLocalData("b", "b", entityB)); + + SyncData remoteC(SyncData::CreateRemoteData( + 1, CreateEntitySpecifics("c", "c"), time2, AttachmentIdList(), + AttachmentServiceProxyForTest::Create())); + + EntitySpecifics entityD(CreateEntitySpecifics("d", "d")); + entityD.mutable_device_info()->set_last_updated_timestamp( + syncer::TimeToProtoTime(time1)); + SyncData remoteD( + SyncData::CreateRemoteData(1, entityD, time2, AttachmentIdList(), + AttachmentServiceProxyForTest::Create())); + + EXPECT_EQ(Time(), GetLastUpdateTime(localA)); + EXPECT_EQ(time1, GetLastUpdateTime(localB)); + EXPECT_EQ(time2, GetLastUpdateTime(remoteC)); + EXPECT_EQ(time1, GetLastUpdateTime(remoteD)); +} + +// Verifies the number of active devices is 0 when there is no data. +TEST_F(DeviceInfoSyncServiceTest, CountActiveDevicesNone) { + EXPECT_EQ(0, CountActiveDevices(Time())); +} + +// Verifies the number of active devices when we have one active device info. +TEST_F(DeviceInfoSyncServiceTest, CountActiveDevicesOneActive) { + StoreSyncData("active", CreateRemoteData("active", "active", Time())); + EXPECT_EQ( + 1, CountActiveDevices(Time() + (DeviceInfoUtil::kActiveThreshold / 2))); +} + +// Verifies the number of active devices when we have one stale that hasn't been +// updated for exactly the threshold is considered stale. +TEST_F(DeviceInfoSyncServiceTest, CountActiveDevicesExactlyStale) { + StoreSyncData("stale", CreateRemoteData("stale", "stale", Time())); + EXPECT_EQ(0, CountActiveDevices(Time() + DeviceInfoUtil::kActiveThreshold)); +} + +// Verifies the number of active devices when we have a mix of active and stale +// device infos. +TEST_F(DeviceInfoSyncServiceTest, CountActiveDevicesManyMix) { + StoreSyncData("stale", CreateRemoteData("stale", "stale", Time())); + StoreSyncData("active1", CreateRemoteData( + "active1", "active1", + Time() + DeviceInfoUtil::kActiveThreshold / 2)); + StoreSyncData("active2", + CreateRemoteData("active2", "active2", + Time() + DeviceInfoUtil::kActiveThreshold)); + EXPECT_EQ(2, CountActiveDevices(Time() + DeviceInfoUtil::kActiveThreshold)); +} + +// Verifies the number of active devices when we have many that are stale. +TEST_F(DeviceInfoSyncServiceTest, CountActiveDevicesManyStale) { + StoreSyncData("stale1", CreateRemoteData("stale1", "stale1", Time())); + StoreSyncData("stale2", + CreateRemoteData("stale2", "stale2", + Time() + DeviceInfoUtil::kActiveThreshold)); + StoreSyncData("stale3", CreateRemoteData( + "stale3", "stale3", + Time() + (DeviceInfoUtil::kActiveThreshold * 2))); + EXPECT_EQ( + 0, CountActiveDevices(Time() + (DeviceInfoUtil::kActiveThreshold * 3))); +} + +// Verifies the number of active devices when we have devices that claim to have +// been updated in the future. +TEST_F(DeviceInfoSyncServiceTest, CountActiveDevicesFuture) { + StoreSyncData("now", + CreateRemoteData("now", "now", + Time() + DeviceInfoUtil::kActiveThreshold)); + StoreSyncData( + "future", + CreateRemoteData("future", "future", + Time() + (DeviceInfoUtil::kActiveThreshold * 10))); + EXPECT_EQ(2, CountActiveDevices(Time() + DeviceInfoUtil::kActiveThreshold)); +} + +// Verifies the number of active devices when they don't have an updated time +// set, and fallback to checking the SyncData's last modified time. +TEST_F(DeviceInfoSyncServiceTest, CountActiveDevicesModifiedTime) { + sync_pb::EntitySpecifics stale_entity; + sync_pb::DeviceInfoSpecifics& stale_specifics = + *stale_entity.mutable_device_info(); + stale_specifics.set_cache_guid("stale"); + StoreSyncData("stale", SyncData::CreateRemoteData( + 1, stale_entity, Time(), AttachmentIdList(), + AttachmentServiceProxyForTest::Create())); + + sync_pb::EntitySpecifics active_entity; + sync_pb::DeviceInfoSpecifics& active_specifics = + *active_entity.mutable_device_info(); + active_specifics.set_cache_guid("active"); + StoreSyncData( + "active", + SyncData::CreateRemoteData( + 1, active_entity, Time() + (DeviceInfoUtil::kActiveThreshold / 2), + AttachmentIdList(), AttachmentServiceProxyForTest::Create())); + + EXPECT_EQ(1, CountActiveDevices(Time() + DeviceInfoUtil::kActiveThreshold)); +} + +// Verifies the number of active devices when they don't have an updated time +// and they're not remote, which means we cannot use SyncData's last modified +// time. If now is close to uninitialized time, should still be active. +TEST_F(DeviceInfoSyncServiceTest, CountActiveDevicesLocalActive) { + sync_pb::EntitySpecifics entity; + sync_pb::DeviceInfoSpecifics& specifics = *entity.mutable_device_info(); + specifics.set_cache_guid("active"); + StoreSyncData("active", + SyncData::CreateLocalData("active", "active", entity)); + EXPECT_EQ( + 1, CountActiveDevices(Time() + (DeviceInfoUtil::kActiveThreshold / 2))); +} + +// Verifies the number of active devices when they don't have an updated time +// and they're not remote, which means we cannot use SyncData's last modified +// time. If now is far from uninitialized time, should be stale. +TEST_F(DeviceInfoSyncServiceTest, CountActiveDevicesLocalStale) { + sync_pb::EntitySpecifics entity; + sync_pb::DeviceInfoSpecifics& specifics = *entity.mutable_device_info(); + specifics.set_cache_guid("stale"); + StoreSyncData("stale", SyncData::CreateLocalData("stale", "stale", entity)); + EXPECT_EQ(0, CountActiveDevices(Time() + DeviceInfoUtil::kActiveThreshold)); +} + +} // namespace + +} // namespace sync_driver
diff --git a/components/sync/driver/device_info_tracker.h b/components/sync/driver/device_info_tracker.h new file mode 100644 index 0000000..e861aa0 --- /dev/null +++ b/components/sync/driver/device_info_tracker.h
@@ -0,0 +1,46 @@ +// 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 COMPONENTS_SYNC_DRIVER_DEVICE_INFO_TRACKER_H_ +#define COMPONENTS_SYNC_DRIVER_DEVICE_INFO_TRACKER_H_ + +#include <memory> +#include <string> + +#include "base/memory/scoped_vector.h" +#include "components/sync/driver/device_info.h" + +namespace sync_driver { + +// Interface for tracking synced DeviceInfo. +class DeviceInfoTracker { + public: + virtual ~DeviceInfoTracker() {} + + // Observer class for listening to device info changes. + class Observer { + public: + virtual void OnDeviceInfoChange() = 0; + }; + + // Returns true when DeviceInfo datatype is enabled and syncing. + virtual bool IsSyncing() const = 0; + // Gets DeviceInfo the synced device with specified client ID. + // Returns an empty unique_ptr if device with the given |client_id| hasn't + // been synced. + virtual std::unique_ptr<DeviceInfo> GetDeviceInfo( + const std::string& client_id) const = 0; + // Gets DeviceInfo for all synced devices (including the local one). + virtual ScopedVector<DeviceInfo> GetAllDeviceInfo() const = 0; + // Registers an observer to be called on syncing any updated DeviceInfo. + virtual void AddObserver(Observer* observer) = 0; + // Unregisters an observer. + virtual void RemoveObserver(Observer* observer) = 0; + // Returns the count of active devices. + virtual int CountActiveDevices() const = 0; +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_DEVICE_INFO_TRACKER_H_
diff --git a/components/sync/driver/device_info_util.cc b/components/sync/driver/device_info_util.cc new file mode 100644 index 0000000..32be76c3 --- /dev/null +++ b/components/sync/driver/device_info_util.cc
@@ -0,0 +1,56 @@ +// Copyright 2016 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/sync/driver/device_info_util.h" + +#include <algorithm> + +#include "base/strings/string_util.h" +#include "components/sync/protocol/sync.pb.h" + +namespace sync_driver { + +using base::Time; +using base::TimeDelta; +using sync_pb::DeviceInfoSpecifics; + +const char DeviceInfoUtil::kClientTagPrefix[] = "DeviceInfo_"; +const TimeDelta DeviceInfoUtil::kPulseInterval = TimeDelta::FromDays(1); +const TimeDelta DeviceInfoUtil::kActiveThreshold = TimeDelta::FromDays(14); + +namespace { + +base::TimeDelta Age(const base::Time last_update, const base::Time now) { + // Don't allow negative age for things somehow updated in the future. + return std::max(base::TimeDelta(), now - last_update); +} + +} // namespace + +// static +base::TimeDelta DeviceInfoUtil::CalculatePulseDelay( + const base::Time last_update, + const base::Time now) { + // Don't allow negative delays for very stale data, use delay of 0. + return std::max(base::TimeDelta(), kPulseInterval - Age(last_update, now)); +} + +// static +bool DeviceInfoUtil::IsActive(const Time last_update, const Time now) { + return Age(last_update, now) < kActiveThreshold; +} + +// static +std::string DeviceInfoUtil::SpecificsToTag( + const sync_pb::DeviceInfoSpecifics& specifics) { + return kClientTagPrefix + specifics.cache_guid(); +} + +// static +std::string DeviceInfoUtil::TagToCacheGuid(const std::string& tag) { + DCHECK(base::StartsWith(tag, kClientTagPrefix, base::CompareCase::SENSITIVE)); + return tag.substr(strlen(kClientTagPrefix)); +} + +} // namespace sync_driver
diff --git a/components/sync_driver/device_info_util.h b/components/sync/driver/device_info_util.h similarity index 100% rename from components/sync_driver/device_info_util.h rename to components/sync/driver/device_info_util.h
diff --git a/components/sync/driver/device_info_util_unittest.cc b/components/sync/driver/device_info_util_unittest.cc new file mode 100644 index 0000000..464258a --- /dev/null +++ b/components/sync/driver/device_info_util_unittest.cc
@@ -0,0 +1,113 @@ +// Copyright 2016 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/sync/driver/device_info_util.h" + +#include <string> + +#include "components/sync/protocol/sync.pb.h" +#include "testing/gtest/include/gtest/gtest.h" + +using base::Time; +using base::TimeDelta; +using sync_pb::DeviceInfoSpecifics; + +namespace sync_driver { + +namespace { + +class DeviceInfoUtilTest : public testing::Test { + protected: + DeviceInfoUtilTest() { + // Test cases assume |small_| and |big_| are smaller and bigger, + // respectively, + // than both constants. + EXPECT_LT(small_, DeviceInfoUtil::kActiveThreshold); + EXPECT_LT(small_, DeviceInfoUtil::kPulseInterval); + EXPECT_GT(big_, DeviceInfoUtil::kActiveThreshold); + EXPECT_GT(big_, DeviceInfoUtil::kPulseInterval); + } + + const Time now_ = Time::Now(); + const TimeDelta small_ = TimeDelta::FromMilliseconds(1); + const TimeDelta big_ = TimeDelta::FromDays(1000); +}; + +} // namespace + +TEST_F(DeviceInfoUtilTest, CalculatePulseDelaySame) { + EXPECT_EQ(DeviceInfoUtil::kPulseInterval, + DeviceInfoUtil::CalculatePulseDelay(Time(), Time())); + EXPECT_EQ(DeviceInfoUtil::kPulseInterval, + DeviceInfoUtil::CalculatePulseDelay(now_, now_)); + EXPECT_EQ(DeviceInfoUtil::kPulseInterval, + DeviceInfoUtil::CalculatePulseDelay(now_ + big_, now_ + big_)); +} + +TEST_F(DeviceInfoUtilTest, CalculatePulseDelayMiddle) { + EXPECT_EQ(DeviceInfoUtil::kPulseInterval - small_, + DeviceInfoUtil::CalculatePulseDelay(Time(), Time() + small_)); + EXPECT_EQ(small_, + DeviceInfoUtil::CalculatePulseDelay( + Time(), Time() + DeviceInfoUtil::kPulseInterval - small_)); +} + +TEST_F(DeviceInfoUtilTest, CalculatePulseDelayStale) { + EXPECT_EQ(TimeDelta(), DeviceInfoUtil::CalculatePulseDelay( + Time(), Time() + DeviceInfoUtil::kPulseInterval)); + EXPECT_EQ(TimeDelta(), + DeviceInfoUtil::CalculatePulseDelay( + Time(), Time() + DeviceInfoUtil::kPulseInterval + small_)); + EXPECT_EQ(TimeDelta(), + DeviceInfoUtil::CalculatePulseDelay( + Time(), Time() + DeviceInfoUtil::kPulseInterval + small_)); + EXPECT_EQ(TimeDelta(), DeviceInfoUtil::CalculatePulseDelay( + now_, now_ + DeviceInfoUtil::kPulseInterval)); +} + +TEST_F(DeviceInfoUtilTest, CalculatePulseDelayFuture) { + EXPECT_EQ(DeviceInfoUtil::kPulseInterval, + DeviceInfoUtil::CalculatePulseDelay(Time() + small_, Time())); + EXPECT_EQ(DeviceInfoUtil::kPulseInterval, + DeviceInfoUtil::CalculatePulseDelay( + Time() + DeviceInfoUtil::kPulseInterval, Time())); + EXPECT_EQ(DeviceInfoUtil::kPulseInterval, + DeviceInfoUtil::CalculatePulseDelay(Time() + big_, Time())); + EXPECT_EQ(DeviceInfoUtil::kPulseInterval, + DeviceInfoUtil::CalculatePulseDelay(now_ + big_, now_)); +} + +TEST_F(DeviceInfoUtilTest, IsActive) { + EXPECT_TRUE(DeviceInfoUtil::IsActive(Time(), Time())); + EXPECT_TRUE(DeviceInfoUtil::IsActive(now_, now_)); + EXPECT_TRUE(DeviceInfoUtil::IsActive(now_, now_ + small_)); + EXPECT_TRUE(DeviceInfoUtil::IsActive( + now_, now_ + DeviceInfoUtil::kActiveThreshold - small_)); + EXPECT_FALSE( + DeviceInfoUtil::IsActive(now_, now_ + DeviceInfoUtil::kActiveThreshold)); + EXPECT_FALSE(DeviceInfoUtil::IsActive( + now_, now_ + DeviceInfoUtil::kActiveThreshold + small_)); + EXPECT_FALSE(DeviceInfoUtil::IsActive( + now_, now_ + DeviceInfoUtil::kActiveThreshold + big_)); + EXPECT_TRUE(DeviceInfoUtil::IsActive(now_ + small_, now_)); + EXPECT_TRUE(DeviceInfoUtil::IsActive(now_ + big_, now_)); +} + +TEST_F(DeviceInfoUtilTest, TagRoundTrip) { + DeviceInfoSpecifics specifics; + ASSERT_EQ("", DeviceInfoUtil::TagToCacheGuid( + DeviceInfoUtil::SpecificsToTag(specifics))); + + std::string cache_guid("guid"); + specifics.set_cache_guid(cache_guid); + ASSERT_EQ(cache_guid, DeviceInfoUtil::TagToCacheGuid( + DeviceInfoUtil::SpecificsToTag(specifics))); + + specifics.set_cache_guid(DeviceInfoUtil::kClientTagPrefix); + ASSERT_EQ(DeviceInfoUtil::kClientTagPrefix, + DeviceInfoUtil::TagToCacheGuid( + DeviceInfoUtil::SpecificsToTag(specifics))); +} + +} // namespace sync_driver
diff --git a/components/sync/driver/directory_data_type_controller.cc b/components/sync/driver/directory_data_type_controller.cc new file mode 100644 index 0000000..2a4c332c --- /dev/null +++ b/components/sync/driver/directory_data_type_controller.cc
@@ -0,0 +1,41 @@ +// 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 "components/sync/driver/directory_data_type_controller.h" + +#include "components/sync/driver/backend_data_type_configurer.h" + +namespace sync_driver { + +DirectoryDataTypeController::DirectoryDataTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const base::Closure& error_callback) + : DataTypeController(ui_thread, error_callback) {} + +DirectoryDataTypeController::~DirectoryDataTypeController() {} + +bool DirectoryDataTypeController::ShouldLoadModelBeforeConfigure() const { + // Directory datatypes don't require loading models before configure. Their + // progress markers are stored in directory and can be extracted without + // datatype participation. + return false; +} + +void DirectoryDataTypeController::RegisterWithBackend( + BackendDataTypeConfigurer* configurer) {} + +void DirectoryDataTypeController::ActivateDataType( + BackendDataTypeConfigurer* configurer) { + // Tell the backend about the change processor for this type so it can + // begin routing changes to it. + configurer->ActivateDirectoryDataType(type(), model_safe_group(), + GetChangeProcessor()); +} + +void DirectoryDataTypeController::DeactivateDataType( + BackendDataTypeConfigurer* configurer) { + configurer->DeactivateDirectoryDataType(type()); +} + +} // namespace sync_driver
diff --git a/components/sync/driver/directory_data_type_controller.h b/components/sync/driver/directory_data_type_controller.h new file mode 100644 index 0000000..be2c364 --- /dev/null +++ b/components/sync/driver/directory_data_type_controller.h
@@ -0,0 +1,59 @@ +// 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_SYNC_DRIVER_DIRECTORY_DATA_TYPE_CONTROLLER_H__ +#define COMPONENTS_SYNC_DRIVER_DIRECTORY_DATA_TYPE_CONTROLLER_H__ + +#include "components/sync/driver/data_type_controller.h" + +#include "components/sync/engine/model_safe_worker.h" + +namespace sync_driver { +class ChangeProcessor; + +// Base class for Directory based Data type controllers. +class DirectoryDataTypeController : public DataTypeController { + public: + // DataTypeController implementation. + bool ShouldLoadModelBeforeConfigure() const override; + + // Directory based data types don't need to register with backend. + // ModelTypeRegistry will create all necessary objects in + // SetEnabledDirectoryTypes based on routing info. + void RegisterWithBackend(BackendDataTypeConfigurer* configurer) override; + + // Directory specific implementation of ActivateDataType with the + // type specific ChangeProcessor and ModelSafeGroup. + // Activates change processing on the controlled data type. + // This is called by DataTypeManager, synchronously with data type's + // model association. + // See BackendDataTypeConfigurer::ActivateDataType for more details. + void ActivateDataType(BackendDataTypeConfigurer* configurer) override; + + // Directory specific implementation of DeactivateDataType. + // Deactivates change processing on the controlled data type (by removing + // the data type's ChangeProcessor registration with the backend). + // See BackendDataTypeConfigurer::DeactivateDataType for more details. + void DeactivateDataType(BackendDataTypeConfigurer* configurer) override; + + protected: + // The model safe group of this data type. This should reflect the + // thread that should be used to modify the data type's native + // model. + virtual syncer::ModelSafeGroup model_safe_group() const = 0; + + // Access to the ChangeProcessor for the type being controlled by |this|. + // Returns NULL if the ChangeProcessor isn't created or connected. + virtual ChangeProcessor* GetChangeProcessor() const = 0; + + DirectoryDataTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const base::Closure& error_callback); + + ~DirectoryDataTypeController() override; +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_DIRECTORY_DATA_TYPE_CONTROLLER_H__
diff --git a/components/sync/driver/fake_data_type_controller.cc b/components/sync/driver/fake_data_type_controller.cc new file mode 100644 index 0000000..38159a8 --- /dev/null +++ b/components/sync/driver/fake_data_type_controller.cc
@@ -0,0 +1,163 @@ +// 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 "components/sync/driver/fake_data_type_controller.h" + +#include "base/threading/thread_task_runner_handle.h" +#include "components/sync/api/sync_merge_result.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using syncer::ModelType; + +namespace sync_driver { + +FakeDataTypeController::FakeDataTypeController(ModelType type) + : DirectoryDataTypeController(base::ThreadTaskRunnerHandle::Get(), + base::Closure()), + state_(NOT_RUNNING), + model_load_delayed_(false), + type_(type), + ready_for_start_(true), + should_load_model_before_configure_(false), + register_with_backend_call_count_(0) {} + +FakeDataTypeController::~FakeDataTypeController() {} + +bool FakeDataTypeController::ShouldLoadModelBeforeConfigure() const { + return should_load_model_before_configure_; +} + +// NOT_RUNNING ->MODEL_LOADED |MODEL_STARTING. +void FakeDataTypeController::LoadModels( + const ModelLoadCallback& model_load_callback) { + model_load_callback_ = model_load_callback; + if (state_ != NOT_RUNNING) { + ADD_FAILURE(); + return; + } + + if (model_load_delayed_ == false) { + if (load_error_.IsSet()) + state_ = DISABLED; + else + state_ = MODEL_LOADED; + model_load_callback.Run(type(), load_error_); + } else { + state_ = MODEL_STARTING; + } +} + +void FakeDataTypeController::RegisterWithBackend( + BackendDataTypeConfigurer* configurer) { + ++register_with_backend_call_count_; +} + +// MODEL_LOADED -> MODEL_STARTING. +void FakeDataTypeController::StartAssociating( + const StartCallback& start_callback) { + last_start_callback_ = start_callback; + state_ = ASSOCIATING; +} + +// MODEL_STARTING | ASSOCIATING -> RUNNING | DISABLED | NOT_RUNNING +// (depending on |result|) +void FakeDataTypeController::FinishStart(ConfigureResult result) { + // We should have a callback from Start(). + if (last_start_callback_.is_null()) { + ADD_FAILURE(); + return; + } + + // Set |state_| first below since the callback may call state(). + syncer::SyncMergeResult local_merge_result(type()); + syncer::SyncMergeResult syncer_merge_result(type()); + if (result <= OK_FIRST_RUN) { + state_ = RUNNING; + } else if (result == ASSOCIATION_FAILED) { + state_ = DISABLED; + local_merge_result.set_error( + syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Association failed", type())); + } else if (result == UNRECOVERABLE_ERROR) { + state_ = NOT_RUNNING; + local_merge_result.set_error( + syncer::SyncError(FROM_HERE, syncer::SyncError::UNRECOVERABLE_ERROR, + "Unrecoverable error", type())); + } else if (result == NEEDS_CRYPTO) { + state_ = NOT_RUNNING; + local_merge_result.set_error(syncer::SyncError( + FROM_HERE, syncer::SyncError::CRYPTO_ERROR, "Crypto error", type())); + } else { + NOTREACHED(); + } + last_start_callback_.Run(result, local_merge_result, syncer_merge_result); +} + +// * -> NOT_RUNNING +void FakeDataTypeController::Stop() { + if (!model_load_callback_.is_null()) { + // Real data type controllers run the callback and specify "ABORTED" as an + // error. We should probably find a way to use the real code and mock out + // unnecessary pieces. + SimulateModelLoadFinishing(); + } + state_ = NOT_RUNNING; +} + +ModelType FakeDataTypeController::type() const { + return type_; +} + +std::string FakeDataTypeController::name() const { + return ModelTypeToString(type_); +} + +syncer::ModelSafeGroup FakeDataTypeController::model_safe_group() const { + return syncer::GROUP_PASSIVE; +} + +ChangeProcessor* FakeDataTypeController::GetChangeProcessor() const { + return NULL; +} + +DataTypeController::State FakeDataTypeController::state() const { + return state_; +} + +void FakeDataTypeController::OnSingleDataTypeUnrecoverableError( + const syncer::SyncError& error) { + if (!model_load_callback_.is_null()) + model_load_callback_.Run(type(), error); +} + +bool FakeDataTypeController::ReadyForStart() const { + return ready_for_start_; +} + +void FakeDataTypeController::SetDelayModelLoad() { + model_load_delayed_ = true; +} + +void FakeDataTypeController::SetModelLoadError(syncer::SyncError error) { + load_error_ = error; +} + +void FakeDataTypeController::SimulateModelLoadFinishing() { + if (load_error_.IsSet()) + state_ = DISABLED; + else + state_ = MODEL_LOADED; + model_load_callback_.Run(type(), load_error_); +} + +void FakeDataTypeController::SetReadyForStart(bool ready) { + ready_for_start_ = ready; +} + +void FakeDataTypeController::SetShouldLoadModelBeforeConfigure(bool value) { + should_load_model_before_configure_ = value; +} + +} // namespace sync_driver
diff --git a/components/sync/driver/fake_data_type_controller.h b/components/sync/driver/fake_data_type_controller.h new file mode 100644 index 0000000..e05d430 --- /dev/null +++ b/components/sync/driver/fake_data_type_controller.h
@@ -0,0 +1,76 @@ +// 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 COMPONENTS_SYNC_DRIVER_FAKE_DATA_TYPE_CONTROLLER_H__ +#define COMPONENTS_SYNC_DRIVER_FAKE_DATA_TYPE_CONTROLLER_H__ + +#include <string> + +#include "components/sync/driver/data_type_manager.h" +#include "components/sync/driver/directory_data_type_controller.h" + +namespace sync_driver { + +// Fake DataTypeController implementation that simulates the state +// machine of a typical asynchronous data type. +// +// TODO(akalin): Consider using subclasses of +// {Frontend,NonFrontend,NewNonFrontend}DataTypeController instead, so +// that we don't have to update this class if we change the expected +// behavior of controllers. (It would be easier of the above classes +// used delegation instead of subclassing for per-data-type +// functionality.) +class FakeDataTypeController : public DirectoryDataTypeController { + public: + explicit FakeDataTypeController(syncer::ModelType type); + + // DirectoryDataTypeController implementation. + bool ShouldLoadModelBeforeConfigure() const override; + void LoadModels(const ModelLoadCallback& model_load_callback) override; + void RegisterWithBackend(BackendDataTypeConfigurer* configurer) override; + void StartAssociating(const StartCallback& start_callback) override; + void Stop() override; + syncer::ModelType type() const override; + std::string name() const override; + syncer::ModelSafeGroup model_safe_group() const override; + ChangeProcessor* GetChangeProcessor() const override; + State state() const override; + void OnSingleDataTypeUnrecoverableError( + const syncer::SyncError& error) override; + bool ReadyForStart() const override; + + void FinishStart(ConfigureResult result); + + void SetDelayModelLoad(); + + void SetModelLoadError(syncer::SyncError error); + + void SimulateModelLoadFinishing(); + + void SetReadyForStart(bool ready); + + void SetShouldLoadModelBeforeConfigure(bool value); + + int register_with_backend_call_count() const { + return register_with_backend_call_count_; + } + + protected: + ~FakeDataTypeController() override; + + private: + DataTypeController::State state_; + bool model_load_delayed_; + syncer::ModelType type_; + StartCallback last_start_callback_; + ModelLoadCallback model_load_callback_; + syncer::SyncError load_error_; + bool ready_for_start_; + bool should_load_model_before_configure_; + int register_with_backend_call_count_; +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_FAKE_DATA_TYPE_CONTROLLER_H__
diff --git a/components/sync/driver/fake_generic_change_processor.cc b/components/sync/driver/fake_generic_change_processor.cc new file mode 100644 index 0000000..9104119b --- /dev/null +++ b/components/sync/driver/fake_generic_change_processor.cc
@@ -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. + +#include "components/sync/driver/fake_generic_change_processor.h" + +#include <utility> + +#include "base/location.h" +#include "base/memory/weak_ptr.h" +#include "components/sync/api/syncable_service.h" +#include "components/sync/core/attachments/attachment_service_impl.h" + +namespace sync_driver { + +FakeGenericChangeProcessor::FakeGenericChangeProcessor(syncer::ModelType type, + SyncClient* sync_client) + : GenericChangeProcessor(type, + NULL, + base::WeakPtr<syncer::SyncableService>(), + base::WeakPtr<syncer::SyncMergeResult>(), + NULL, + sync_client, + nullptr), + sync_model_has_user_created_nodes_(true), + sync_model_has_user_created_nodes_success_(true) {} + +FakeGenericChangeProcessor::~FakeGenericChangeProcessor() {} + +void FakeGenericChangeProcessor::set_sync_model_has_user_created_nodes( + bool has_nodes) { + sync_model_has_user_created_nodes_ = has_nodes; +} +void FakeGenericChangeProcessor::set_sync_model_has_user_created_nodes_success( + bool success) { + sync_model_has_user_created_nodes_success_ = success; +} + +syncer::SyncError FakeGenericChangeProcessor::ProcessSyncChanges( + const tracked_objects::Location& from_here, + const syncer::SyncChangeList& change_list) { + return syncer::SyncError(); +} + +syncer::SyncError FakeGenericChangeProcessor::GetAllSyncDataReturnError( + syncer::SyncDataList* current_sync_data) const { + return syncer::SyncError(); +} + +bool FakeGenericChangeProcessor::GetDataTypeContext( + std::string* context) const { + return false; +} + +int FakeGenericChangeProcessor::GetSyncCount() { + return 0; +} + +bool FakeGenericChangeProcessor::SyncModelHasUserCreatedNodes(bool* has_nodes) { + *has_nodes = sync_model_has_user_created_nodes_; + return sync_model_has_user_created_nodes_success_; +} + +bool FakeGenericChangeProcessor::CryptoReadyIfNecessary() { + return true; +} + +FakeGenericChangeProcessorFactory::FakeGenericChangeProcessorFactory( + std::unique_ptr<FakeGenericChangeProcessor> processor) + : processor_(std::move(processor)) {} + +FakeGenericChangeProcessorFactory::~FakeGenericChangeProcessorFactory() {} + +std::unique_ptr<GenericChangeProcessor> +FakeGenericChangeProcessorFactory::CreateGenericChangeProcessor( + syncer::ModelType type, + syncer::UserShare* user_share, + syncer::DataTypeErrorHandler* error_handler, + const base::WeakPtr<syncer::SyncableService>& local_service, + const base::WeakPtr<syncer::SyncMergeResult>& merge_result, + SyncClient* sync_client) { + return std::move(processor_); +} + +} // namespace sync_driver
diff --git a/components/sync/driver/fake_generic_change_processor.h b/components/sync/driver/fake_generic_change_processor.h new file mode 100644 index 0000000..88b817e --- /dev/null +++ b/components/sync/driver/fake_generic_change_processor.h
@@ -0,0 +1,66 @@ +// 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 COMPONENTS_SYNC_DRIVER_FAKE_GENERIC_CHANGE_PROCESSOR_H_ +#define COMPONENTS_SYNC_DRIVER_FAKE_GENERIC_CHANGE_PROCESSOR_H_ + +#include <string> + +#include "base/macros.h" +#include "components/sync/api/sync_error.h" +#include "components/sync/base/model_type.h" +#include "components/sync/driver/generic_change_processor.h" +#include "components/sync/driver/generic_change_processor_factory.h" +#include "components/sync/driver/sync_api_component_factory.h" + +namespace sync_driver { + +// A fake GenericChangeProcessor that can return arbitrary values. +class FakeGenericChangeProcessor : public GenericChangeProcessor { + public: + FakeGenericChangeProcessor(syncer::ModelType type, SyncClient* sync_client); + ~FakeGenericChangeProcessor() override; + + // Setters for GenericChangeProcessor implementation results. + void set_sync_model_has_user_created_nodes(bool has_nodes); + void set_sync_model_has_user_created_nodes_success(bool success); + + // GenericChangeProcessor implementations. + syncer::SyncError ProcessSyncChanges( + const tracked_objects::Location& from_here, + const syncer::SyncChangeList& change_list) override; + syncer::SyncError GetAllSyncDataReturnError( + syncer::SyncDataList* data) const override; + bool GetDataTypeContext(std::string* context) const override; + int GetSyncCount() override; + bool SyncModelHasUserCreatedNodes(bool* has_nodes) override; + bool CryptoReadyIfNecessary() override; + + private: + bool sync_model_has_user_created_nodes_; + bool sync_model_has_user_created_nodes_success_; +}; + +// Define a factory for FakeGenericChangeProcessor for convenience. +class FakeGenericChangeProcessorFactory : public GenericChangeProcessorFactory { + public: + explicit FakeGenericChangeProcessorFactory( + std::unique_ptr<FakeGenericChangeProcessor> processor); + ~FakeGenericChangeProcessorFactory() override; + std::unique_ptr<GenericChangeProcessor> CreateGenericChangeProcessor( + syncer::ModelType type, + syncer::UserShare* user_share, + syncer::DataTypeErrorHandler* error_handler, + const base::WeakPtr<syncer::SyncableService>& local_service, + const base::WeakPtr<syncer::SyncMergeResult>& merge_result, + SyncClient* sync_client) override; + + private: + std::unique_ptr<FakeGenericChangeProcessor> processor_; + DISALLOW_COPY_AND_ASSIGN(FakeGenericChangeProcessorFactory); +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_FAKE_GENERIC_CHANGE_PROCESSOR_H_
diff --git a/components/sync/driver/fake_sync_client.cc b/components/sync/driver/fake_sync_client.cc new file mode 100644 index 0000000..9e5ee43 --- /dev/null +++ b/components/sync/driver/fake_sync_client.cc
@@ -0,0 +1,120 @@ +// 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/sync/driver/fake_sync_client.h" + +#include "base/bind.h" +#include "base/memory/ptr_util.h" +#include "components/sync/base/extensions_activity.h" +#include "components/sync/driver/fake_sync_service.h" +#include "components/sync/driver/sync_prefs.h" + +namespace sync_driver { + +namespace { + +void DummyRegisterPlatformTypesCallback(SyncService* sync_service, + syncer::ModelTypeSet, + syncer::ModelTypeSet) {} + +} // namespace + +FakeSyncClient::FakeSyncClient() + : model_type_service_(nullptr), + factory_(nullptr), + sync_service_(base::WrapUnique(new FakeSyncService())) { + // Register sync preferences and set them to "Sync everything" state. + sync_driver::SyncPrefs::RegisterProfilePrefs(pref_service_.registry()); + sync_driver::SyncPrefs sync_prefs(GetPrefService()); + sync_prefs.SetFirstSetupComplete(); + sync_prefs.SetKeepEverythingSynced(true); +} + +FakeSyncClient::FakeSyncClient(SyncApiComponentFactory* factory) + : factory_(factory), + sync_service_(base::WrapUnique(new FakeSyncService())) { + sync_driver::SyncPrefs::RegisterProfilePrefs(pref_service_.registry()); +} + +FakeSyncClient::~FakeSyncClient() {} + +void FakeSyncClient::Initialize() {} + +SyncService* FakeSyncClient::GetSyncService() { + return sync_service_.get(); +} + +PrefService* FakeSyncClient::GetPrefService() { + return &pref_service_; +} + +bookmarks::BookmarkModel* FakeSyncClient::GetBookmarkModel() { + return nullptr; +} + +favicon::FaviconService* FakeSyncClient::GetFaviconService() { + return nullptr; +} + +history::HistoryService* FakeSyncClient::GetHistoryService() { + return nullptr; +} + +base::Closure FakeSyncClient::GetPasswordStateChangedCallback() { + return base::Bind(&base::DoNothing); +} + +sync_driver::SyncApiComponentFactory::RegisterDataTypesMethod +FakeSyncClient::GetRegisterPlatformTypesCallback() { + return base::Bind(&DummyRegisterPlatformTypesCallback); +} + +autofill::PersonalDataManager* FakeSyncClient::GetPersonalDataManager() { + return nullptr; +} + +BookmarkUndoService* FakeSyncClient::GetBookmarkUndoServiceIfExists() { + return nullptr; +} + +invalidation::InvalidationService* FakeSyncClient::GetInvalidationService() { + return nullptr; +} + +scoped_refptr<syncer::ExtensionsActivity> +FakeSyncClient::GetExtensionsActivity() { + return scoped_refptr<syncer::ExtensionsActivity>(); +} + +sync_sessions::SyncSessionsClient* FakeSyncClient::GetSyncSessionsClient() { + return nullptr; +} + +base::WeakPtr<syncer::SyncableService> +FakeSyncClient::GetSyncableServiceForType(syncer::ModelType type) { + return base::WeakPtr<syncer::SyncableService>(); +} + +syncer_v2::ModelTypeService* FakeSyncClient::GetModelTypeServiceForType( + syncer::ModelType type) { + return model_type_service_; +} + +scoped_refptr<syncer::ModelSafeWorker> +FakeSyncClient::CreateModelWorkerForGroup( + syncer::ModelSafeGroup group, + syncer::WorkerLoopDestructionObserver* observer) { + return scoped_refptr<syncer::ModelSafeWorker>(); +} + +SyncApiComponentFactory* FakeSyncClient::GetSyncApiComponentFactory() { + return factory_; +} + +void FakeSyncClient::SetModelTypeService( + syncer_v2::ModelTypeService* model_type_service) { + model_type_service_ = model_type_service; +} + +} // namespace sync_driver
diff --git a/components/sync/driver/fake_sync_client.h b/components/sync/driver/fake_sync_client.h new file mode 100644 index 0000000..4bc9f92 --- /dev/null +++ b/components/sync/driver/fake_sync_client.h
@@ -0,0 +1,61 @@ +// 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_SYNC_DRIVER_FAKE_SYNC_CLIENT_H_ +#define COMPONENTS_SYNC_DRIVER_FAKE_SYNC_CLIENT_H_ + +#include <memory> + +#include "base/macros.h" +#include "components/sync/driver/sync_client.h" +#include "components/syncable_prefs/testing_pref_service_syncable.h" + +namespace sync_driver { +class FakeSyncService; + +// Fake implementation of SyncClient interface for tests. +class FakeSyncClient : public SyncClient { + public: + FakeSyncClient(); + explicit FakeSyncClient(SyncApiComponentFactory* factory); + ~FakeSyncClient() override; + + void Initialize() override; + + SyncService* GetSyncService() override; + PrefService* GetPrefService() override; + bookmarks::BookmarkModel* GetBookmarkModel() override; + favicon::FaviconService* GetFaviconService() override; + history::HistoryService* GetHistoryService() override; + base::Closure GetPasswordStateChangedCallback() override; + sync_driver::SyncApiComponentFactory::RegisterDataTypesMethod + GetRegisterPlatformTypesCallback() override; + autofill::PersonalDataManager* GetPersonalDataManager() override; + BookmarkUndoService* GetBookmarkUndoServiceIfExists() override; + invalidation::InvalidationService* GetInvalidationService() override; + scoped_refptr<syncer::ExtensionsActivity> GetExtensionsActivity() override; + sync_sessions::SyncSessionsClient* GetSyncSessionsClient() override; + base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType( + syncer::ModelType type) override; + syncer_v2::ModelTypeService* GetModelTypeServiceForType( + syncer::ModelType type) override; + scoped_refptr<syncer::ModelSafeWorker> CreateModelWorkerForGroup( + syncer::ModelSafeGroup group, + syncer::WorkerLoopDestructionObserver* observer) override; + SyncApiComponentFactory* GetSyncApiComponentFactory() override; + + void SetModelTypeService(syncer_v2::ModelTypeService* model_type_service); + + private: + syncable_prefs::TestingPrefServiceSyncable pref_service_; + syncer_v2::ModelTypeService* model_type_service_; + SyncApiComponentFactory* factory_; + std::unique_ptr<FakeSyncService> sync_service_; + + DISALLOW_COPY_AND_ASSIGN(FakeSyncClient); +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_FAKE_SYNC_CLIENT_H_
diff --git a/components/sync/driver/fake_sync_service.cc b/components/sync/driver/fake_sync_service.cc new file mode 100644 index 0000000..fd67df1 --- /dev/null +++ b/components/sync/driver/fake_sync_service.cc
@@ -0,0 +1,216 @@ +// 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/sync/driver/fake_sync_service.h" + +#include "base/memory/ptr_util.h" +#include "base/values.h" +#include "components/sync/core/base_transaction.h" +#include "components/sync/core/user_share.h" +#include "components/sync/sessions/sync_session_snapshot.h" + +namespace sync_driver { + +FakeSyncService::FakeSyncService() + : error_(GoogleServiceAuthError::NONE), + user_share_(base::WrapUnique(new syncer::UserShare())) {} + +FakeSyncService::~FakeSyncService() {} + +bool FakeSyncService::IsFirstSetupComplete() const { + return false; +} + +bool FakeSyncService::IsSyncAllowed() const { + return false; +} + +bool FakeSyncService::IsSyncActive() const { + return false; +} + +void FakeSyncService::TriggerRefresh(const syncer::ModelTypeSet& types) {} + +syncer::ModelTypeSet FakeSyncService::GetActiveDataTypes() const { + return syncer::ModelTypeSet(); +} + +SyncClient* FakeSyncService::GetSyncClient() const { + return nullptr; +} + +void FakeSyncService::AddObserver(SyncServiceObserver* observer) {} + +void FakeSyncService::RemoveObserver(SyncServiceObserver* observer) {} + +bool FakeSyncService::HasObserver(const SyncServiceObserver* observer) const { + return false; +} + +bool FakeSyncService::CanSyncStart() const { + return false; +} + +void FakeSyncService::OnDataTypeRequestsSyncStartup(syncer::ModelType type) {} + +void FakeSyncService::RequestStop( + sync_driver::SyncService::SyncStopDataFate data_fate) {} + +void FakeSyncService::RequestStart() {} + +syncer::ModelTypeSet FakeSyncService::GetPreferredDataTypes() const { + return syncer::ModelTypeSet(); +} + +void FakeSyncService::OnUserChoseDatatypes(bool sync_everything, + syncer::ModelTypeSet chosen_types) {} + +void FakeSyncService::SetFirstSetupComplete() {} + +bool FakeSyncService::IsFirstSetupInProgress() const { + return false; +} + +std::unique_ptr<SyncSetupInProgressHandle> +FakeSyncService::GetSetupInProgressHandle() { + return nullptr; +} + +bool FakeSyncService::IsSetupInProgress() const { + return false; +} + +bool FakeSyncService::ConfigurationDone() const { + return false; +} + +const GoogleServiceAuthError& FakeSyncService::GetAuthError() const { + return error_; +} + +bool FakeSyncService::HasUnrecoverableError() const { + return false; +} + +bool FakeSyncService::IsBackendInitialized() const { + return false; +} + +OpenTabsUIDelegate* FakeSyncService::GetOpenTabsUIDelegate() { + return nullptr; +} + +bool FakeSyncService::IsPassphraseRequiredForDecryption() const { + return false; +} + +base::Time FakeSyncService::GetExplicitPassphraseTime() const { + return base::Time(); +} + +bool FakeSyncService::IsUsingSecondaryPassphrase() const { + return false; +} + +void FakeSyncService::EnableEncryptEverything() {} + +bool FakeSyncService::IsEncryptEverythingEnabled() const { + return false; +} + +void FakeSyncService::SetEncryptionPassphrase(const std::string& passphrase, + PassphraseType type) {} + +bool FakeSyncService::SetDecryptionPassphrase(const std::string& passphrase) { + return false; +} + +bool FakeSyncService::IsCryptographerReady( + const syncer::BaseTransaction* trans) const { + return false; +} + +syncer::UserShare* FakeSyncService::GetUserShare() const { + return user_share_.get(); +} + +LocalDeviceInfoProvider* FakeSyncService::GetLocalDeviceInfoProvider() const { + return nullptr; +} + +void FakeSyncService::RegisterDataTypeController( + sync_driver::DataTypeController* data_type_controller) {} + +void FakeSyncService::ReenableDatatype(syncer::ModelType type) {} + +bool FakeSyncService::IsPassphraseRequired() const { + return false; +} + +syncer::ModelTypeSet FakeSyncService::GetEncryptedDataTypes() const { + return syncer::ModelTypeSet(); +} + +FakeSyncService::SyncTokenStatus FakeSyncService::GetSyncTokenStatus() const { + return FakeSyncService::SyncTokenStatus(); +} + +std::string FakeSyncService::QuerySyncStatusSummaryString() { + return ""; +} + +bool FakeSyncService::QueryDetailedSyncStatus(syncer::SyncStatus* result) { + return false; +} + +base::string16 FakeSyncService::GetLastSyncedTimeString() const { + return base::string16(); +} + +std::string FakeSyncService::GetBackendInitializationStateString() const { + return std::string(); +} + +syncer::sessions::SyncSessionSnapshot FakeSyncService::GetLastSessionSnapshot() + const { + return syncer::sessions::SyncSessionSnapshot(); +} + +base::Value* FakeSyncService::GetTypeStatusMap() const { + return new base::ListValue(); +} + +const GURL& FakeSyncService::sync_service_url() const { + return sync_service_url_; +} + +std::string FakeSyncService::unrecoverable_error_message() const { + return unrecoverable_error_message_; +} + +tracked_objects::Location FakeSyncService::unrecoverable_error_location() + const { + return tracked_objects::Location(); +} + +void FakeSyncService::AddProtocolEventObserver( + browser_sync::ProtocolEventObserver* observer) {} + +void FakeSyncService::RemoveProtocolEventObserver( + browser_sync::ProtocolEventObserver* observer) {} + +void FakeSyncService::AddTypeDebugInfoObserver( + syncer::TypeDebugInfoObserver* observer) {} + +void FakeSyncService::RemoveTypeDebugInfoObserver( + syncer::TypeDebugInfoObserver* observer) {} + +base::WeakPtr<syncer::JsController> FakeSyncService::GetJsController() { + return base::WeakPtr<syncer::JsController>(); +} + +void FakeSyncService::GetAllNodes( + const base::Callback<void(std::unique_ptr<base::ListValue>)>& callback) {} + +} // namespace sync_driver
diff --git a/components/sync/driver/fake_sync_service.h b/components/sync/driver/fake_sync_service.h new file mode 100644 index 0000000..f8eacba --- /dev/null +++ b/components/sync/driver/fake_sync_service.h
@@ -0,0 +1,105 @@ +// 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_SYNC_DRIVER_FAKE_SYNC_SERVICE_H_ +#define COMPONENTS_SYNC_DRIVER_FAKE_SYNC_SERVICE_H_ + +#include <string> + +#include "components/sync/driver/sync_service.h" +#include "components/sync/sessions/sync_session_snapshot.h" +#include "google_apis/gaia/google_service_auth_error.h" + +namespace syncer { +class BaseTransaction; +struct UserShare; +} + +namespace sync_driver { + +// Fake implementation of sync_driver::SyncService, used for testing. +class FakeSyncService : public sync_driver::SyncService { + public: + FakeSyncService(); + ~FakeSyncService() override; + + private: + // sync_driver::SyncService: + bool IsFirstSetupComplete() const override; + bool IsSyncAllowed() const override; + bool IsSyncActive() const override; + void TriggerRefresh(const syncer::ModelTypeSet& types) override; + syncer::ModelTypeSet GetActiveDataTypes() const override; + SyncClient* GetSyncClient() const override; + void AddObserver(SyncServiceObserver* observer) override; + void RemoveObserver(SyncServiceObserver* observer) override; + bool HasObserver(const SyncServiceObserver* observer) const override; + void OnDataTypeRequestsSyncStartup(syncer::ModelType type) override; + bool CanSyncStart() const override; + void RequestStop( + sync_driver::SyncService::SyncStopDataFate data_fate) override; + void RequestStart() override; + syncer::ModelTypeSet GetPreferredDataTypes() const override; + void OnUserChoseDatatypes(bool sync_everything, + syncer::ModelTypeSet chosen_types) override; + void SetFirstSetupComplete() override; + bool IsFirstSetupInProgress() const override; + std::unique_ptr<SyncSetupInProgressHandle> GetSetupInProgressHandle() + override; + bool IsSetupInProgress() const override; + bool ConfigurationDone() const override; + const GoogleServiceAuthError& GetAuthError() const override; + bool HasUnrecoverableError() const override; + bool IsBackendInitialized() const override; + OpenTabsUIDelegate* GetOpenTabsUIDelegate() override; + bool IsPassphraseRequiredForDecryption() const override; + base::Time GetExplicitPassphraseTime() const override; + bool IsUsingSecondaryPassphrase() const override; + void EnableEncryptEverything() override; + bool IsEncryptEverythingEnabled() const override; + void SetEncryptionPassphrase(const std::string& passphrase, + PassphraseType type) override; + bool SetDecryptionPassphrase(const std::string& passphrase) override; + bool IsCryptographerReady( + const syncer::BaseTransaction* trans) const override; + syncer::UserShare* GetUserShare() const override; + LocalDeviceInfoProvider* GetLocalDeviceInfoProvider() const override; + void RegisterDataTypeController( + sync_driver::DataTypeController* data_type_controller) override; + void ReenableDatatype(syncer::ModelType type) override; + SyncTokenStatus GetSyncTokenStatus() const override; + std::string QuerySyncStatusSummaryString() override; + bool QueryDetailedSyncStatus(syncer::SyncStatus* result) override; + base::string16 GetLastSyncedTimeString() const override; + std::string GetBackendInitializationStateString() const override; + syncer::sessions::SyncSessionSnapshot GetLastSessionSnapshot() const override; + base::Value* GetTypeStatusMap() const override; + const GURL& sync_service_url() const override; + std::string unrecoverable_error_message() const override; + tracked_objects::Location unrecoverable_error_location() const override; + void AddProtocolEventObserver( + browser_sync::ProtocolEventObserver* observer) override; + void RemoveProtocolEventObserver( + browser_sync::ProtocolEventObserver* observer) override; + void AddTypeDebugInfoObserver( + syncer::TypeDebugInfoObserver* observer) override; + void RemoveTypeDebugInfoObserver( + syncer::TypeDebugInfoObserver* observer) override; + base::WeakPtr<syncer::JsController> GetJsController() override; + void GetAllNodes(const base::Callback<void(std::unique_ptr<base::ListValue>)>& + callback) override; + + // DataTypeEncryptionHandler: + bool IsPassphraseRequired() const override; + syncer::ModelTypeSet GetEncryptedDataTypes() const override; + + GoogleServiceAuthError error_; + GURL sync_service_url_; + std::string unrecoverable_error_message_; + std::unique_ptr<syncer::UserShare> user_share_; +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_FAKE_SYNC_SERVICE_H_
diff --git a/components/sync/driver/frontend_data_type_controller.cc b/components/sync/driver/frontend_data_type_controller.cc new file mode 100644 index 0000000..fbd9f8e6 --- /dev/null +++ b/components/sync/driver/frontend_data_type_controller.cc
@@ -0,0 +1,286 @@ +// 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/sync/driver/frontend_data_type_controller.h" + +#include "base/logging.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/sync/api/sync_error.h" +#include "components/sync/api/sync_merge_result.h" +#include "components/sync/base/data_type_histogram.h" +#include "components/sync/base/model_type.h" +#include "components/sync/driver/change_processor.h" +#include "components/sync/driver/model_associator.h" +#include "components/sync/driver/sync_client.h" +#include "components/sync/driver/sync_service.h" + +namespace browser_sync { + +FrontendDataTypeController::FrontendDataTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const base::Closure& error_callback, + sync_driver::SyncClient* sync_client) + : DirectoryDataTypeController(ui_thread, error_callback), + sync_client_(sync_client), + state_(NOT_RUNNING) { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(sync_client); +} + +void FrontendDataTypeController::LoadModels( + const ModelLoadCallback& model_load_callback) { + DCHECK(thread_checker_.CalledOnValidThread()); + model_load_callback_ = model_load_callback; + + if (state_ != NOT_RUNNING) { + model_load_callback.Run( + type(), syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Model already running", type())); + return; + } + + state_ = MODEL_STARTING; + if (!StartModels()) { + // If we are waiting for some external service to load before associating + // or we failed to start the models, we exit early. state_ will control + // what we perform next. + DCHECK(state_ == NOT_RUNNING || state_ == MODEL_STARTING); + return; + } + + OnModelLoaded(); +} + +void FrontendDataTypeController::OnModelLoaded() { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_EQ(state_, MODEL_STARTING); + + state_ = MODEL_LOADED; + model_load_callback_.Run(type(), syncer::SyncError()); +} + +void FrontendDataTypeController::StartAssociating( + const StartCallback& start_callback) { + DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(!start_callback.is_null()); + DCHECK_EQ(state_, MODEL_LOADED); + + start_callback_ = start_callback; + state_ = ASSOCIATING; + + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(&FrontendDataTypeController::Associate, this)); +} + +void FrontendDataTypeController::Stop() { + DCHECK(thread_checker_.CalledOnValidThread()); + + if (state_ == NOT_RUNNING) + return; + + State prev_state = state_; + state_ = STOPPING; + + // If Stop() is called while Start() is waiting for the datatype model to + // load, abort the start. + if (prev_state == MODEL_STARTING) { + AbortModelLoad(); + // We can just return here since we haven't performed association if we're + // still in MODEL_STARTING. + return; + } + + CleanUpState(); + + if (model_associator()) { + syncer::SyncError error; // Not used. + error = model_associator()->DisassociateModels(); + } + + set_model_associator(NULL); + change_processor_.reset(); + + state_ = NOT_RUNNING; +} + +syncer::ModelSafeGroup FrontendDataTypeController::model_safe_group() const { + return syncer::GROUP_UI; +} + +std::string FrontendDataTypeController::name() const { + // For logging only. + return syncer::ModelTypeToString(type()); +} + +sync_driver::DataTypeController::State FrontendDataTypeController::state() + const { + return state_; +} + +void FrontendDataTypeController::OnSingleDataTypeUnrecoverableError( + const syncer::SyncError& error) { + DCHECK_EQ(type(), error.model_type()); + RecordUnrecoverableError(error.location(), error.message()); + if (!model_load_callback_.is_null()) { + syncer::SyncMergeResult local_merge_result(type()); + local_merge_result.set_error(error); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(model_load_callback_, type(), error)); + } +} + +FrontendDataTypeController::FrontendDataTypeController() + : DirectoryDataTypeController(base::ThreadTaskRunnerHandle::Get(), + base::Closure()), + sync_client_(NULL), + state_(NOT_RUNNING) {} + +FrontendDataTypeController::~FrontendDataTypeController() { + DCHECK(thread_checker_.CalledOnValidThread()); +} + +bool FrontendDataTypeController::StartModels() { + DCHECK_EQ(state_, MODEL_STARTING); + // By default, no additional services need to be started before we can proceed + // with model association. + return true; +} + +void FrontendDataTypeController::RecordUnrecoverableError( + const tracked_objects::Location& from_here, + const std::string& message) { + DVLOG(1) << "Datatype Controller failed for type " + << ModelTypeToString(type()) << " " << message << " at location " + << from_here.ToString(); + UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeRunFailures", + ModelTypeToHistogramInt(type()), + syncer::MODEL_TYPE_COUNT); + + if (!error_callback_.is_null()) + error_callback_.Run(); +} + +void FrontendDataTypeController::Associate() { + if (state_ != ASSOCIATING) { + // Stop() must have been called while Associate() task have been waiting. + DCHECK_EQ(state_, NOT_RUNNING); + return; + } + + syncer::SyncMergeResult local_merge_result(type()); + syncer::SyncMergeResult syncer_merge_result(type()); + CreateSyncComponents(); + if (!model_associator()->CryptoReadyIfNecessary()) { + StartDone(NEEDS_CRYPTO, local_merge_result, syncer_merge_result); + return; + } + + bool sync_has_nodes = false; + if (!model_associator()->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { + syncer::SyncError error(FROM_HERE, syncer::SyncError::UNRECOVERABLE_ERROR, + "Failed to load sync nodes", type()); + local_merge_result.set_error(error); + StartDone(UNRECOVERABLE_ERROR, local_merge_result, syncer_merge_result); + return; + } + + // TODO(zea): Have AssociateModels fill the local and syncer merge results. + base::TimeTicks start_time = base::TimeTicks::Now(); + syncer::SyncError error; + error = model_associator()->AssociateModels(&local_merge_result, + &syncer_merge_result); + // TODO(lipalani): crbug.com/122690 - handle abort. + RecordAssociationTime(base::TimeTicks::Now() - start_time); + if (error.IsSet()) { + local_merge_result.set_error(error); + StartDone(ASSOCIATION_FAILED, local_merge_result, syncer_merge_result); + return; + } + + state_ = RUNNING; + // FinishStart() invokes the DataTypeManager callback, which can lead to a + // call to Stop() if one of the other data types being started generates an + // error. + StartDone(!sync_has_nodes ? OK_FIRST_RUN : OK, local_merge_result, + syncer_merge_result); +} + +void FrontendDataTypeController::CleanUpState() { + // Do nothing by default. +} + +void FrontendDataTypeController::CleanUp() { + CleanUpState(); + set_model_associator(NULL); + change_processor_.reset(); +} + +void FrontendDataTypeController::AbortModelLoad() { + DCHECK(thread_checker_.CalledOnValidThread()); + CleanUp(); + state_ = NOT_RUNNING; +} + +void FrontendDataTypeController::StartDone( + ConfigureResult start_result, + const syncer::SyncMergeResult& local_merge_result, + const syncer::SyncMergeResult& syncer_merge_result) { + DCHECK(thread_checker_.CalledOnValidThread()); + if (!IsSuccessfulResult(start_result)) { + if (IsUnrecoverableResult(start_result)) + RecordUnrecoverableError(FROM_HERE, "StartFailed"); + + CleanUp(); + if (start_result == ASSOCIATION_FAILED) { + state_ = DISABLED; + } else { + state_ = NOT_RUNNING; + } + RecordStartFailure(start_result); + } + + start_callback_.Run(start_result, local_merge_result, syncer_merge_result); +} + +void FrontendDataTypeController::RecordAssociationTime(base::TimeDelta time) { + DCHECK(thread_checker_.CalledOnValidThread()); +#define PER_DATA_TYPE_MACRO(type_str) \ + UMA_HISTOGRAM_TIMES("Sync." type_str "AssociationTime", time); + SYNC_DATA_TYPE_HISTOGRAM(type()); +#undef PER_DATA_TYPE_MACRO +} + +void FrontendDataTypeController::RecordStartFailure(ConfigureResult result) { + DCHECK(thread_checker_.CalledOnValidThread()); + UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", + ModelTypeToHistogramInt(type()), + syncer::MODEL_TYPE_COUNT); +#define PER_DATA_TYPE_MACRO(type_str) \ + UMA_HISTOGRAM_ENUMERATION("Sync." type_str "ConfigureFailure", result, \ + MAX_CONFIGURE_RESULT); + SYNC_DATA_TYPE_HISTOGRAM(type()); +#undef PER_DATA_TYPE_MACRO +} + +sync_driver::AssociatorInterface* FrontendDataTypeController::model_associator() + const { + return model_associator_.get(); +} + +void FrontendDataTypeController::set_model_associator( + sync_driver::AssociatorInterface* model_associator) { + model_associator_.reset(model_associator); +} + +sync_driver::ChangeProcessor* FrontendDataTypeController::GetChangeProcessor() + const { + return change_processor_.get(); +} + +void FrontendDataTypeController::set_change_processor( + sync_driver::ChangeProcessor* change_processor) { + change_processor_.reset(change_processor); +} + +} // namespace browser_sync
diff --git a/components/sync/driver/frontend_data_type_controller.h b/components/sync/driver/frontend_data_type_controller.h new file mode 100644 index 0000000..d5b6ad6 --- /dev/null +++ b/components/sync/driver/frontend_data_type_controller.h
@@ -0,0 +1,144 @@ +// 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 COMPONENTS_SYNC_DRIVER_FRONTEND_DATA_TYPE_CONTROLLER_H__ +#define COMPONENTS_SYNC_DRIVER_FRONTEND_DATA_TYPE_CONTROLLER_H__ + +#include <memory> +#include <string> + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/threading/thread_checker.h" +#include "components/sync/core/data_type_error_handler.h" +#include "components/sync/driver/directory_data_type_controller.h" + +namespace base { +class SingleThreadTaskRunner; +class TimeDelta; +} + +namespace syncer { +class SyncError; +} + +namespace sync_driver { +class AssociatorInterface; +class ChangeProcessor; +class SyncClient; +} + +namespace browser_sync { + +// Implementation for datatypes that reside on the frontend thread +// (UI thread). This is the same thread we perform initialization on, so we +// don't have to worry about thread safety. The main start/stop funtionality is +// implemented by default. +// Derived classes must implement (at least): +// syncer::ModelType type() const +// void CreateSyncComponents(); +// NOTE: This class is deprecated! New sync datatypes should be using the +// syncer::SyncableService API and the UIDataTypeController instead. +// TODO(zea): Delete this once all types are on the new API. +class FrontendDataTypeController + : public sync_driver::DirectoryDataTypeController { + public: + FrontendDataTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const base::Closure& error_callback, + sync_driver::SyncClient* sync_client); + + // DataTypeController interface. + void LoadModels(const ModelLoadCallback& model_load_callback) override; + void StartAssociating(const StartCallback& start_callback) override; + void Stop() override; + syncer::ModelType type() const override = 0; + syncer::ModelSafeGroup model_safe_group() const override; + std::string name() const override; + State state() const override; + + // DataTypeErrorHandler interface. + void OnSingleDataTypeUnrecoverableError( + const syncer::SyncError& error) override; + + protected: + friend class FrontendDataTypeControllerMock; + + // For testing only. + FrontendDataTypeController(); + ~FrontendDataTypeController() override; + + // Kick off any dependent services that need to be running before we can + // associate models. The default implementation is a no-op. + // Return value: + // True - if models are ready and association can proceed. + // False - if models are not ready. Associate() should be called when the + // models are ready. Refer to Start(_) implementation. + virtual bool StartModels(); + + // Datatype specific creation of sync components. + virtual void CreateSyncComponents() = 0; + + // Perform any DataType controller specific state cleanup before stopping + // the datatype controller. The default implementation is a no-op. + virtual void CleanUpState(); + + // Helper method for cleaning up state and running the start callback. + virtual void StartDone(ConfigureResult start_result, + const syncer::SyncMergeResult& local_merge_result, + const syncer::SyncMergeResult& syncer_merge_result); + + // Record association time. + virtual void RecordAssociationTime(base::TimeDelta time); + // Record causes of start failure. + virtual void RecordStartFailure(ConfigureResult result); + + virtual sync_driver::AssociatorInterface* model_associator() const; + virtual void set_model_associator( + sync_driver::AssociatorInterface* associator); + sync_driver::ChangeProcessor* GetChangeProcessor() const override; + virtual void set_change_processor(sync_driver::ChangeProcessor* processor); + + // Handles the reporting of unrecoverable error. It records stuff in + // UMA and reports to breakpad. + // Virtual for testing purpose. + virtual void RecordUnrecoverableError( + const tracked_objects::Location& from_here, + const std::string& message); + + // If the DTC is waiting for models to load, once the models are + // loaded the datatype service will call this function on DTC to let + // us know that it is safe to start associating. + void OnModelLoaded(); + + sync_driver::SyncClient* const sync_client_; + + State state_; + + StartCallback start_callback_; + ModelLoadCallback model_load_callback_; + + // TODO(sync): transition all datatypes to SyncableService and deprecate + // AssociatorInterface. + std::unique_ptr<sync_driver::AssociatorInterface> model_associator_; + std::unique_ptr<sync_driver::ChangeProcessor> change_processor_; + + private: + // Build sync components and associate models. + virtual void Associate(); + + void AbortModelLoad(); + + // Clean up our state and state variables. Called in response + // to a failure or abort or stop. + void CleanUp(); + + base::ThreadChecker thread_checker_; + + DISALLOW_COPY_AND_ASSIGN(FrontendDataTypeController); +}; + +} // namespace browser_sync + +#endif // COMPONENTS_SYNC_DRIVER_FRONTEND_DATA_TYPE_CONTROLLER_H__
diff --git a/components/sync/driver/frontend_data_type_controller_mock.cc b/components/sync/driver/frontend_data_type_controller_mock.cc new file mode 100644 index 0000000..83adc31 --- /dev/null +++ b/components/sync/driver/frontend_data_type_controller_mock.cc
@@ -0,0 +1,13 @@ +// 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. + +#include "components/sync/driver/frontend_data_type_controller_mock.h" + +namespace browser_sync { + +FrontendDataTypeControllerMock::FrontendDataTypeControllerMock() {} + +FrontendDataTypeControllerMock::~FrontendDataTypeControllerMock() {} + +} // namespace browser_sync
diff --git a/components/sync/driver/frontend_data_type_controller_mock.h b/components/sync/driver/frontend_data_type_controller_mock.h new file mode 100644 index 0000000..c6512ff --- /dev/null +++ b/components/sync/driver/frontend_data_type_controller_mock.h
@@ -0,0 +1,58 @@ +// 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 COMPONENTS_SYNC_DRIVER_FRONTEND_DATA_TYPE_CONTROLLER_MOCK_H__ +#define COMPONENTS_SYNC_DRIVER_FRONTEND_DATA_TYPE_CONTROLLER_MOCK_H__ + +#include <string> + +#include "components/sync/api/sync_error.h" +#include "components/sync/driver/frontend_data_type_controller.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace browser_sync { + +class FrontendDataTypeControllerMock : public FrontendDataTypeController { + public: + FrontendDataTypeControllerMock(); + + // DataTypeController mocks. + MOCK_METHOD1(StartAssociating, void(const StartCallback& start_callback)); + MOCK_METHOD1(LoadModels, void(const ModelLoadCallback& model_load_callback)); + + MOCK_METHOD0(Stop, void()); + MOCK_METHOD0(enabled, bool()); + MOCK_CONST_METHOD0(type, syncer::ModelType()); + MOCK_CONST_METHOD0(name, std::string()); + MOCK_CONST_METHOD0(model_safe_group, syncer::ModelSafeGroup()); + MOCK_CONST_METHOD0(state, State()); + MOCK_METHOD2(OnUnrecoverableError, + void(const tracked_objects::Location&, const std::string&)); + + // FrontendDataTypeController mocks. + MOCK_METHOD0(StartModels, bool()); + MOCK_METHOD0(Associate, void()); + MOCK_METHOD0(CreateSyncComponents, void()); + MOCK_METHOD2(StartFailed, + void(ConfigureResult result, const syncer::SyncError& error)); + MOCK_METHOD1(FinishStart, void(ConfigureResult result)); + MOCK_METHOD0(CleanUpState, void()); + MOCK_CONST_METHOD0(model_associator, sync_driver::AssociatorInterface*()); + MOCK_METHOD1(set_model_associator, + void(sync_driver::AssociatorInterface* associator)); + MOCK_CONST_METHOD0(change_processor, sync_driver::ChangeProcessor*()); + MOCK_METHOD1(set_change_processor, + void(sync_driver::ChangeProcessor* processor)); + MOCK_METHOD2(RecordUnrecoverableError, + void(const tracked_objects::Location&, const std::string&)); + MOCK_METHOD1(RecordAssociationTime, void(base::TimeDelta time)); + MOCK_METHOD1(RecordStartFailure, void(ConfigureResult result)); + + protected: + virtual ~FrontendDataTypeControllerMock(); +}; + +} // namespace browser_sync + +#endif // COMPONENTS_SYNC_DRIVER_FRONTEND_DATA_TYPE_CONTROLLER_MOCK_H__
diff --git a/components/sync/driver/frontend_data_type_controller_unittest.cc b/components/sync/driver/frontend_data_type_controller_unittest.cc new file mode 100644 index 0000000..9d7e6ac0 --- /dev/null +++ b/components/sync/driver/frontend_data_type_controller_unittest.cc
@@ -0,0 +1,260 @@ +// 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/sync/driver/frontend_data_type_controller.h" + +#include <memory> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/callback.h" +#include "base/location.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/single_thread_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/tracked_objects.h" +#include "components/sync/driver/change_processor_mock.h" +#include "components/sync/driver/data_type_controller_mock.h" +#include "components/sync/driver/fake_sync_client.h" +#include "components/sync/driver/fake_sync_service.h" +#include "components/sync/driver/frontend_data_type_controller_mock.h" +#include "components/sync/driver/model_associator_mock.h" +#include "components/sync/driver/sync_api_component_factory_mock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using browser_sync::FrontendDataTypeController; +using browser_sync::FrontendDataTypeControllerMock; +using sync_driver::ChangeProcessorMock; +using sync_driver::DataTypeController; +using sync_driver::ModelAssociatorMock; +using sync_driver::ModelLoadCallbackMock; +using sync_driver::StartCallbackMock; +using testing::_; +using testing::DoAll; +using testing::InvokeWithoutArgs; +using testing::Return; +using testing::SetArgumentPointee; +using testing::StrictMock; + +namespace { + +class FrontendDataTypeControllerFake : public FrontendDataTypeController { + public: + FrontendDataTypeControllerFake(sync_driver::SyncClient* sync_client, + FrontendDataTypeControllerMock* mock) + : FrontendDataTypeController(base::ThreadTaskRunnerHandle::Get(), + base::Closure(), + sync_client), + mock_(mock), + sync_client_(sync_client) {} + syncer::ModelType type() const override { return syncer::BOOKMARKS; } + + private: + ~FrontendDataTypeControllerFake() override {} + + void CreateSyncComponents() override { + sync_driver::SyncApiComponentFactory::SyncComponents sync_components = + sync_client_->GetSyncApiComponentFactory() + ->CreateBookmarkSyncComponents(nullptr, this); + model_associator_.reset(sync_components.model_associator); + change_processor_.reset(sync_components.change_processor); + } + + // We mock the following methods because their default implementations do + // nothing, but we still want to make sure they're called appropriately. + bool StartModels() override { return mock_->StartModels(); } + void CleanUpState() override { mock_->CleanUpState(); } + void RecordUnrecoverableError(const tracked_objects::Location& from_here, + const std::string& message) override { + mock_->RecordUnrecoverableError(from_here, message); + } + void RecordAssociationTime(base::TimeDelta time) override { + mock_->RecordAssociationTime(time); + } + void RecordStartFailure(DataTypeController::ConfigureResult result) override { + mock_->RecordStartFailure(result); + } + + FrontendDataTypeControllerMock* mock_; + sync_driver::SyncClient* sync_client_; +}; + +class SyncFrontendDataTypeControllerTest : public testing::Test, + public sync_driver::FakeSyncClient { + public: + SyncFrontendDataTypeControllerTest() + : sync_driver::FakeSyncClient(&profile_sync_factory_), service_() {} + + // FakeSyncClient overrides. + sync_driver::SyncService* GetSyncService() override { return &service_; } + + void SetUp() override { + dtc_mock_ = new StrictMock<FrontendDataTypeControllerMock>(); + frontend_dtc_ = new FrontendDataTypeControllerFake(this, dtc_mock_.get()); + } + + protected: + void SetStartExpectations() { + EXPECT_CALL(*dtc_mock_.get(), StartModels()).WillOnce(Return(true)); + EXPECT_CALL(model_load_callback_, Run(_, _)); + model_associator_ = new ModelAssociatorMock(); + change_processor_ = new ChangeProcessorMock(); + EXPECT_CALL(profile_sync_factory_, CreateBookmarkSyncComponents(_, _)) + .WillOnce(Return(sync_driver::SyncApiComponentFactory::SyncComponents( + model_associator_, change_processor_))); + } + + void SetAssociateExpectations() { + EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()) + .WillOnce(Return(true)); + EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)) + .WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true))); + EXPECT_CALL(*model_associator_, AssociateModels(_, _)) + .WillOnce(Return(syncer::SyncError())); + EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_)); + } + + void SetActivateExpectations(DataTypeController::ConfigureResult result) { + EXPECT_CALL(start_callback_, Run(result, _, _)); + } + + void SetStopExpectations() { + EXPECT_CALL(*dtc_mock_.get(), CleanUpState()); + EXPECT_CALL(*model_associator_, DisassociateModels()) + .WillOnce(Return(syncer::SyncError())); + } + + void SetStartFailExpectations(DataTypeController::ConfigureResult result) { + if (DataTypeController::IsUnrecoverableResult(result)) + EXPECT_CALL(*dtc_mock_.get(), RecordUnrecoverableError(_, _)); + EXPECT_CALL(*dtc_mock_.get(), CleanUpState()); + EXPECT_CALL(*dtc_mock_.get(), RecordStartFailure(result)); + EXPECT_CALL(start_callback_, Run(result, _, _)); + } + + void Start() { + frontend_dtc_->LoadModels(base::Bind( + &ModelLoadCallbackMock::Run, base::Unretained(&model_load_callback_))); + frontend_dtc_->StartAssociating(base::Bind( + &StartCallbackMock::Run, base::Unretained(&start_callback_))); + PumpLoop(); + } + + void PumpLoop() { base::RunLoop().RunUntilIdle(); } + + base::MessageLoop message_loop_; + scoped_refptr<FrontendDataTypeControllerFake> frontend_dtc_; + SyncApiComponentFactoryMock profile_sync_factory_; + scoped_refptr<FrontendDataTypeControllerMock> dtc_mock_; + sync_driver::FakeSyncService service_; + ModelAssociatorMock* model_associator_; + ChangeProcessorMock* change_processor_; + StartCallbackMock start_callback_; + ModelLoadCallbackMock model_load_callback_; +}; + +TEST_F(SyncFrontendDataTypeControllerTest, StartOk) { + SetStartExpectations(); + SetAssociateExpectations(); + SetActivateExpectations(DataTypeController::OK); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); + Start(); + EXPECT_EQ(DataTypeController::RUNNING, frontend_dtc_->state()); +} + +TEST_F(SyncFrontendDataTypeControllerTest, StartFirstRun) { + SetStartExpectations(); + EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()) + .WillOnce(Return(true)); + EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)) + .WillOnce(DoAll(SetArgumentPointee<0>(false), Return(true))); + EXPECT_CALL(*model_associator_, AssociateModels(_, _)) + .WillOnce(Return(syncer::SyncError())); + EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_)); + SetActivateExpectations(DataTypeController::OK_FIRST_RUN); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); + Start(); + EXPECT_EQ(DataTypeController::RUNNING, frontend_dtc_->state()); +} + +TEST_F(SyncFrontendDataTypeControllerTest, StartStopBeforeAssociation) { + EXPECT_CALL(*dtc_mock_.get(), StartModels()).WillOnce(Return(true)); + EXPECT_CALL(*dtc_mock_.get(), CleanUpState()); + EXPECT_CALL(model_load_callback_, Run(_, _)); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(&FrontendDataTypeController::Stop, frontend_dtc_)); + Start(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); +} + +TEST_F(SyncFrontendDataTypeControllerTest, AbortDuringStartModels) { + EXPECT_CALL(*dtc_mock_.get(), StartModels()).WillOnce(Return(false)); + EXPECT_CALL(*dtc_mock_.get(), CleanUpState()); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); + frontend_dtc_->LoadModels(base::Bind( + &ModelLoadCallbackMock::Run, base::Unretained(&model_load_callback_))); + EXPECT_EQ(DataTypeController::MODEL_STARTING, frontend_dtc_->state()); + frontend_dtc_->Stop(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); +} + +TEST_F(SyncFrontendDataTypeControllerTest, StartAssociationFailed) { + SetStartExpectations(); + EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()) + .WillOnce(Return(true)); + EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)) + .WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true))); + EXPECT_CALL(*model_associator_, AssociateModels(_, _)) + .WillOnce( + Return(syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "error", syncer::BOOKMARKS))); + + EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_)); + SetStartFailExpectations(DataTypeController::ASSOCIATION_FAILED); + // Set up association to fail with an association failed error. + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); + Start(); + EXPECT_EQ(DataTypeController::DISABLED, frontend_dtc_->state()); +} + +TEST_F(SyncFrontendDataTypeControllerTest, + StartAssociationTriggersUnrecoverableError) { + SetStartExpectations(); + SetStartFailExpectations(DataTypeController::UNRECOVERABLE_ERROR); + // Set up association to fail with an unrecoverable error. + EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()) + .WillRepeatedly(Return(true)); + EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)) + .WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(false))); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); + Start(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); +} + +TEST_F(SyncFrontendDataTypeControllerTest, StartAssociationCryptoNotReady) { + SetStartExpectations(); + SetStartFailExpectations(DataTypeController::NEEDS_CRYPTO); + // Set up association to fail with a NEEDS_CRYPTO error. + EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()) + .WillRepeatedly(Return(false)); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); + Start(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); +} + +TEST_F(SyncFrontendDataTypeControllerTest, Stop) { + SetStartExpectations(); + SetAssociateExpectations(); + SetActivateExpectations(DataTypeController::OK); + SetStopExpectations(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); + Start(); + EXPECT_EQ(DataTypeController::RUNNING, frontend_dtc_->state()); + frontend_dtc_->Stop(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); +} + +} // namespace
diff --git a/components/sync/driver/generic_change_processor.cc b/components/sync/driver/generic_change_processor.cc new file mode 100644 index 0000000..f7abe0506 --- /dev/null +++ b/components/sync/driver/generic_change_processor.cc
@@ -0,0 +1,692 @@ +// 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 "components/sync/driver/generic_change_processor.h" + +#include <stddef.h> + +#include <algorithm> +#include <string> +#include <utility> + +#include "base/location.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/sync/api/sync_change.h" +#include "components/sync/api/sync_error.h" +#include "components/sync/api/syncable_service.h" +#include "components/sync/base/unrecoverable_error_handler.h" +#include "components/sync/core/base_node.h" +#include "components/sync/core/change_record.h" +#include "components/sync/core/data_type_error_handler.h" +#include "components/sync/core/read_node.h" +#include "components/sync/core/read_transaction.h" +#include "components/sync/core/write_node.h" +#include "components/sync/core/write_transaction.h" +#include "components/sync/driver/sync_api_component_factory.h" +#include "components/sync/driver/sync_client.h" +#include "components/sync/syncable/entry.h" // TODO(tim): Bug 123674. + +namespace sync_driver { + +namespace { + +const int kContextSizeLimit = 1024; // Datatype context size limit. + +void SetNodeSpecifics(const sync_pb::EntitySpecifics& entity_specifics, + syncer::WriteNode* write_node) { + if (syncer::GetModelTypeFromSpecifics(entity_specifics) == + syncer::PASSWORDS) { + write_node->SetPasswordSpecifics( + entity_specifics.password().client_only_encrypted_data()); + } else { + write_node->SetEntitySpecifics(entity_specifics); + } +} + +// Helper function to convert AttachmentId to AttachmentMetadataRecord. +sync_pb::AttachmentMetadataRecord AttachmentIdToRecord( + const syncer::AttachmentId& attachment_id) { + sync_pb::AttachmentMetadataRecord record; + *record.mutable_id() = attachment_id.GetProto(); + return record; +} + +// Replace |write_nodes|'s attachment ids with |attachment_ids|. +void SetAttachmentMetadata(const syncer::AttachmentIdList& attachment_ids, + syncer::WriteNode* write_node) { + DCHECK(write_node); + sync_pb::AttachmentMetadata attachment_metadata; + std::transform( + attachment_ids.begin(), attachment_ids.end(), + RepeatedFieldBackInserter(attachment_metadata.mutable_record()), + AttachmentIdToRecord); + write_node->SetAttachmentMetadata(attachment_metadata); +} + +syncer::SyncData BuildRemoteSyncData( + int64_t sync_id, + const syncer::ReadNode& read_node, + const syncer::AttachmentServiceProxy& attachment_service_proxy) { + const syncer::AttachmentIdList& attachment_ids = read_node.GetAttachmentIds(); + switch (read_node.GetModelType()) { + case syncer::PASSWORDS: { + // Passwords must be accessed differently, to account for their + // encryption, and stored into a temporary EntitySpecifics. + sync_pb::EntitySpecifics password_holder; + password_holder.mutable_password() + ->mutable_client_only_encrypted_data() + ->CopyFrom(read_node.GetPasswordSpecifics()); + return syncer::SyncData::CreateRemoteData( + sync_id, password_holder, read_node.GetModificationTime(), + attachment_ids, attachment_service_proxy); + } + case syncer::SESSIONS: + // Include tag hashes for sessions data type to allow discarding during + // merge if re-hashing by the service gives a different value. This is to + // allow removal of incorrectly hashed values, see crbug.com/604657. This + // cannot be done in the processor because only the service knows how to + // generate a tag from the specifics. We don't set this value for other + // data types because they shouldn't need it and it costs memory to hold + // another copy of this string around. + return syncer::SyncData::CreateRemoteData( + sync_id, read_node.GetEntitySpecifics(), + read_node.GetModificationTime(), attachment_ids, + attachment_service_proxy, read_node.GetEntry()->GetUniqueClientTag()); + default: + // Use the specifics directly, encryption has already been handled. + return syncer::SyncData::CreateRemoteData( + sync_id, read_node.GetEntitySpecifics(), + read_node.GetModificationTime(), attachment_ids, + attachment_service_proxy); + } +} + +} // namespace + +GenericChangeProcessor::GenericChangeProcessor( + syncer::ModelType type, + syncer::DataTypeErrorHandler* error_handler, + const base::WeakPtr<syncer::SyncableService>& local_service, + const base::WeakPtr<syncer::SyncMergeResult>& merge_result, + syncer::UserShare* user_share, + SyncClient* sync_client, + std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store) + : ChangeProcessor(error_handler), + type_(type), + local_service_(local_service), + merge_result_(merge_result), + share_handle_(user_share), + weak_ptr_factory_(this) { + DCHECK(CalledOnValidThread()); + DCHECK_NE(type_, syncer::UNSPECIFIED); + if (attachment_store) { + std::string store_birthday; + { + syncer::ReadTransaction trans(FROM_HERE, share_handle()); + store_birthday = trans.GetStoreBirthday(); + } + attachment_service_ = + sync_client->GetSyncApiComponentFactory()->CreateAttachmentService( + std::move(attachment_store), *user_share, store_birthday, type, + this); + attachment_service_weak_ptr_factory_.reset( + new base::WeakPtrFactory<syncer::AttachmentService>( + attachment_service_.get())); + attachment_service_proxy_ = syncer::AttachmentServiceProxy( + base::ThreadTaskRunnerHandle::Get(), + attachment_service_weak_ptr_factory_->GetWeakPtr()); + UploadAllAttachmentsNotOnServer(); + } else { + attachment_service_proxy_ = syncer::AttachmentServiceProxy( + base::ThreadTaskRunnerHandle::Get(), + base::WeakPtr<syncer::AttachmentService>()); + } +} + +GenericChangeProcessor::~GenericChangeProcessor() { + DCHECK(CalledOnValidThread()); +} + +void GenericChangeProcessor::ApplyChangesFromSyncModel( + const syncer::BaseTransaction* trans, + int64_t model_version, + const syncer::ImmutableChangeRecordList& changes) { + DCHECK(CalledOnValidThread()); + DCHECK(syncer_changes_.empty()); + for (syncer::ChangeRecordList::const_iterator it = changes.Get().begin(); + it != changes.Get().end(); ++it) { + if (it->action == syncer::ChangeRecord::ACTION_DELETE) { + std::unique_ptr<sync_pb::EntitySpecifics> specifics; + if (it->specifics.has_password()) { + DCHECK(it->extra.get()); + specifics.reset(new sync_pb::EntitySpecifics(it->specifics)); + specifics->mutable_password() + ->mutable_client_only_encrypted_data() + ->CopyFrom(it->extra->unencrypted()); + } + const syncer::AttachmentIdList empty_list_of_attachment_ids; + syncer_changes_.push_back(syncer::SyncChange( + FROM_HERE, syncer::SyncChange::ACTION_DELETE, + syncer::SyncData::CreateRemoteData( + it->id, specifics ? *specifics : it->specifics, base::Time(), + empty_list_of_attachment_ids, attachment_service_proxy_))); + } else { + syncer::SyncChange::SyncChangeType action = + (it->action == syncer::ChangeRecord::ACTION_ADD) + ? syncer::SyncChange::ACTION_ADD + : syncer::SyncChange::ACTION_UPDATE; + // Need to load specifics from node. + syncer::ReadNode read_node(trans); + if (read_node.InitByIdLookup(it->id) != syncer::BaseNode::INIT_OK) { + syncer::SyncError error( + FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Failed to look up data for received change with id " + + base::Int64ToString(it->id), + syncer::GetModelTypeFromSpecifics(it->specifics)); + error_handler()->OnSingleDataTypeUnrecoverableError(error); + return; + } + syncer_changes_.push_back(syncer::SyncChange( + FROM_HERE, action, + BuildRemoteSyncData(it->id, read_node, attachment_service_proxy_))); + } + } +} + +void GenericChangeProcessor::CommitChangesFromSyncModel() { + DCHECK(CalledOnValidThread()); + if (syncer_changes_.empty()) + return; + if (!local_service_.get()) { + syncer::ModelType type = syncer_changes_[0].sync_data().GetDataType(); + syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Local service destroyed.", type); + error_handler()->OnSingleDataTypeUnrecoverableError(error); + return; + } + syncer::SyncError error = + local_service_->ProcessSyncChanges(FROM_HERE, syncer_changes_); + syncer_changes_.clear(); + if (error.IsSet()) + error_handler()->OnSingleDataTypeUnrecoverableError(error); +} + +syncer::SyncDataList GenericChangeProcessor::GetAllSyncData( + syncer::ModelType type) const { + DCHECK_EQ(type_, type); + // This is slow / memory intensive. Should be used sparingly by datatypes. + syncer::SyncDataList data; + GetAllSyncDataReturnError(&data); + return data; +} + +syncer::SyncError GenericChangeProcessor::UpdateDataTypeContext( + syncer::ModelType type, + syncer::SyncChangeProcessor::ContextRefreshStatus refresh_status, + const std::string& context) { + DCHECK(syncer::ProtocolTypes().Has(type)); + DCHECK_EQ(type_, type); + + if (context.size() > static_cast<size_t>(kContextSizeLimit)) { + return syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Context size limit exceeded.", type); + } + + syncer::WriteTransaction trans(FROM_HERE, share_handle()); + trans.SetDataTypeContext(type, refresh_status, context); + + // TODO(zea): plumb a pointer to the PSS or SyncManagerImpl here so we can + // trigger a datatype nudge if |refresh_status == REFRESH_NEEDED|. + + return syncer::SyncError(); +} + +void GenericChangeProcessor::OnAttachmentUploaded( + const syncer::AttachmentId& attachment_id) { + syncer::WriteTransaction trans(FROM_HERE, share_handle()); + trans.UpdateEntriesMarkAttachmentAsOnServer(attachment_id); +} + +syncer::SyncError GenericChangeProcessor::GetAllSyncDataReturnError( + syncer::SyncDataList* current_sync_data) const { + DCHECK(CalledOnValidThread()); + std::string type_name = syncer::ModelTypeToString(type_); + syncer::ReadTransaction trans(FROM_HERE, share_handle()); + syncer::ReadNode root(&trans); + if (root.InitTypeRoot(type_) != syncer::BaseNode::INIT_OK) { + syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Server did not create the top-level " + type_name + + " node. We might be running against an out-of-" + "date server.", + type_); + return error; + } + + // TODO(akalin): We'll have to do a tree traversal for bookmarks. + DCHECK_NE(type_, syncer::BOOKMARKS); + + std::vector<int64_t> child_ids; + root.GetChildIds(&child_ids); + + for (std::vector<int64_t>::iterator it = child_ids.begin(); + it != child_ids.end(); ++it) { + syncer::ReadNode sync_child_node(&trans); + if (sync_child_node.InitByIdLookup(*it) != syncer::BaseNode::INIT_OK) { + syncer::SyncError error( + FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Failed to fetch child node for type " + type_name + ".", type_); + return error; + } + current_sync_data->push_back(BuildRemoteSyncData( + sync_child_node.GetId(), sync_child_node, attachment_service_proxy_)); + } + return syncer::SyncError(); +} + +bool GenericChangeProcessor::GetDataTypeContext(std::string* context) const { + syncer::ReadTransaction trans(FROM_HERE, share_handle()); + sync_pb::DataTypeContext context_proto; + trans.GetDataTypeContext(type_, &context_proto); + if (!context_proto.has_context()) + return false; + + DCHECK_EQ(type_, syncer::GetModelTypeFromSpecificsFieldNumber( + context_proto.data_type_id())); + *context = context_proto.context(); + return true; +} + +int GenericChangeProcessor::GetSyncCount() { + syncer::ReadTransaction trans(FROM_HERE, share_handle()); + syncer::ReadNode root(&trans); + if (root.InitTypeRoot(type_) != syncer::BaseNode::INIT_OK) + return 0; + + // Subtract one to account for type's root node. + return root.GetTotalNodeCount() - 1; +} + +namespace { + +// WARNING: this code is sensitive to compiler optimizations. Be careful +// modifying any code around an OnSingleDataTypeUnrecoverableError call, else +// the compiler attempts to merge it with other calls, losing useful information +// in breakpad uploads. +syncer::SyncError LogLookupFailure( + syncer::BaseNode::InitByLookupResult lookup_result, + const tracked_objects::Location& from_here, + const std::string& error_prefix, + syncer::ModelType type, + syncer::DataTypeErrorHandler* error_handler) { + switch (lookup_result) { + case syncer::BaseNode::INIT_FAILED_ENTRY_NOT_GOOD: { + syncer::SyncError error; + error.Reset( + from_here, + error_prefix + "could not find entry matching the lookup criteria.", + type); + error_handler->OnSingleDataTypeUnrecoverableError(error); + LOG(ERROR) << "Delete: Bad entry."; + return error; + } + case syncer::BaseNode::INIT_FAILED_ENTRY_IS_DEL: { + syncer::SyncError error; + error.Reset(from_here, error_prefix + "entry is already deleted.", type); + error_handler->OnSingleDataTypeUnrecoverableError(error); + LOG(ERROR) << "Delete: Deleted entry."; + return error; + } + case syncer::BaseNode::INIT_FAILED_DECRYPT_IF_NECESSARY: { + syncer::SyncError error; + error.Reset(from_here, error_prefix + "unable to decrypt", type); + error_handler->OnSingleDataTypeUnrecoverableError(error); + LOG(ERROR) << "Delete: Undecryptable entry."; + return error; + } + case syncer::BaseNode::INIT_FAILED_PRECONDITION: { + syncer::SyncError error; + error.Reset(from_here, + error_prefix + "a precondition was not met for calling init.", + type); + error_handler->OnSingleDataTypeUnrecoverableError(error); + LOG(ERROR) << "Delete: Failed precondition."; + return error; + } + default: { + syncer::SyncError error; + // Should have listed all the possible error cases above. + error.Reset(from_here, error_prefix + "unknown error", type); + error_handler->OnSingleDataTypeUnrecoverableError(error); + LOG(ERROR) << "Delete: Unknown error."; + return error; + } + } +} + +syncer::SyncError AttemptDelete(const syncer::SyncChange& change, + syncer::ModelType type, + const std::string& type_str, + syncer::WriteNode* node, + syncer::DataTypeErrorHandler* error_handler) { + DCHECK_EQ(change.change_type(), syncer::SyncChange::ACTION_DELETE); + if (change.sync_data().IsLocal()) { + const std::string& tag = syncer::SyncDataLocal(change.sync_data()).GetTag(); + if (tag.empty()) { + syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Failed to delete " + type_str + + " node. Local data, empty tag. " + + change.location().ToString(), + type); + error_handler->OnSingleDataTypeUnrecoverableError(error); + NOTREACHED(); + return error; + } + + syncer::BaseNode::InitByLookupResult result = + node->InitByClientTagLookup(change.sync_data().GetDataType(), tag); + if (result != syncer::BaseNode::INIT_OK) { + return LogLookupFailure(result, FROM_HERE, + "Failed to delete " + type_str + + " node. Local data. " + + change.location().ToString(), + type, error_handler); + } + } else { + syncer::BaseNode::InitByLookupResult result = node->InitByIdLookup( + syncer::SyncDataRemote(change.sync_data()).GetId()); + if (result != syncer::BaseNode::INIT_OK) { + return LogLookupFailure(result, FROM_HERE, + "Failed to delete " + type_str + + " node. Non-local data. " + + change.location().ToString(), + type, error_handler); + } + } + if (IsActOnceDataType(type)) + node->Drop(); + else + node->Tombstone(); + return syncer::SyncError(); +} + +} // namespace + +syncer::SyncError GenericChangeProcessor::ProcessSyncChanges( + const tracked_objects::Location& from_here, + const syncer::SyncChangeList& list_of_changes) { + DCHECK(CalledOnValidThread()); + + if (list_of_changes.empty()) { + // No work. Exit without entering WriteTransaction. + return syncer::SyncError(); + } + + // Keep track of brand new attachments so we can persist them on this device + // and upload them to the server. + syncer::AttachmentIdSet new_attachments; + + syncer::WriteTransaction trans(from_here, share_handle()); + + for (syncer::SyncChangeList::const_iterator iter = list_of_changes.begin(); + iter != list_of_changes.end(); ++iter) { + const syncer::SyncChange& change = *iter; + DCHECK_EQ(change.sync_data().GetDataType(), type_); + std::string type_str = syncer::ModelTypeToString(type_); + syncer::WriteNode sync_node(&trans); + if (change.change_type() == syncer::SyncChange::ACTION_DELETE) { + syncer::SyncError error = + AttemptDelete(change, type_, type_str, &sync_node, error_handler()); + if (error.IsSet()) { + NOTREACHED(); + return error; + } + if (merge_result_.get()) { + merge_result_->set_num_items_deleted( + merge_result_->num_items_deleted() + 1); + } + } else if (change.change_type() == syncer::SyncChange::ACTION_ADD) { + syncer::SyncError error = HandleActionAdd(change, type_str, trans, + &sync_node, &new_attachments); + if (error.IsSet()) { + return error; + } + } else if (change.change_type() == syncer::SyncChange::ACTION_UPDATE) { + syncer::SyncError error = HandleActionUpdate( + change, type_str, trans, &sync_node, &new_attachments); + if (error.IsSet()) { + return error; + } + } else { + syncer::SyncError error( + FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Received unset SyncChange in the change processor, " + + change.location().ToString(), + type_); + error_handler()->OnSingleDataTypeUnrecoverableError(error); + NOTREACHED(); + LOG(ERROR) << "Unset sync change."; + return error; + } + } + + if (!new_attachments.empty()) { + // If datatype uses attachments it should have supplied attachment store + // which would initialize attachment_service_. Fail if it isn't so. + if (!attachment_service_.get()) { + syncer::SyncError error( + FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Datatype performs attachment operation without initializing " + "attachment store", + type_); + error_handler()->OnSingleDataTypeUnrecoverableError(error); + NOTREACHED(); + return error; + } + syncer::AttachmentIdList ids_to_upload; + ids_to_upload.reserve(new_attachments.size()); + std::copy(new_attachments.begin(), new_attachments.end(), + std::back_inserter(ids_to_upload)); + attachment_service_->UploadAttachments(ids_to_upload); + } + + return syncer::SyncError(); +} + +// WARNING: this code is sensitive to compiler optimizations. Be careful +// modifying any code around an OnSingleDataTypeUnrecoverableError call, else +// the compiler attempts to merge it with other calls, losing useful information +// in breakpad uploads. +syncer::SyncError GenericChangeProcessor::HandleActionAdd( + const syncer::SyncChange& change, + const std::string& type_str, + const syncer::WriteTransaction& trans, + syncer::WriteNode* sync_node, + syncer::AttachmentIdSet* new_attachments) { + // TODO(sync): Handle other types of creation (custom parents, folders, + // etc.). + const syncer::SyncDataLocal sync_data_local(change.sync_data()); + syncer::WriteNode::InitUniqueByCreationResult result = + sync_node->InitUniqueByCreation(sync_data_local.GetDataType(), + sync_data_local.GetTag()); + if (result != syncer::WriteNode::INIT_SUCCESS) { + std::string error_prefix = "Failed to create " + type_str + " node: " + + change.location().ToString() + ", "; + switch (result) { + case syncer::WriteNode::INIT_FAILED_EMPTY_TAG: { + syncer::SyncError error; + error.Reset(FROM_HERE, error_prefix + "empty tag", type_); + error_handler()->OnSingleDataTypeUnrecoverableError(error); + LOG(ERROR) << "Create: Empty tag."; + return error; + } + case syncer::WriteNode::INIT_FAILED_COULD_NOT_CREATE_ENTRY: { + syncer::SyncError error; + error.Reset(FROM_HERE, error_prefix + "failed to create entry", type_); + error_handler()->OnSingleDataTypeUnrecoverableError(error); + LOG(ERROR) << "Create: Could not create entry."; + return error; + } + case syncer::WriteNode::INIT_FAILED_SET_PREDECESSOR: { + syncer::SyncError error; + error.Reset(FROM_HERE, error_prefix + "failed to set predecessor", + type_); + error_handler()->OnSingleDataTypeUnrecoverableError(error); + LOG(ERROR) << "Create: Bad predecessor."; + return error; + } + case syncer::WriteNode::INIT_FAILED_DECRYPT_EXISTING_ENTRY: { + syncer::SyncError error; + error.Reset(FROM_HERE, error_prefix + "failed to decrypt", type_); + error_handler()->OnSingleDataTypeUnrecoverableError(error); + LOG(ERROR) << "Create: Failed to decrypt."; + return error; + } + default: { + syncer::SyncError error; + error.Reset(FROM_HERE, error_prefix + "unknown error", type_); + error_handler()->OnSingleDataTypeUnrecoverableError(error); + LOG(ERROR) << "Create: Unknown error."; + return error; + } + } + } + sync_node->SetTitle(change.sync_data().GetTitle()); + SetNodeSpecifics(sync_data_local.GetSpecifics(), sync_node); + + syncer::AttachmentIdList attachment_ids = sync_data_local.GetAttachmentIds(); + SetAttachmentMetadata(attachment_ids, sync_node); + + // Return any newly added attachments. + new_attachments->insert(attachment_ids.begin(), attachment_ids.end()); + if (merge_result_.get()) { + merge_result_->set_num_items_added(merge_result_->num_items_added() + 1); + } + return syncer::SyncError(); +} +// WARNING: this code is sensitive to compiler optimizations. Be careful +// modifying any code around an OnSingleDataTypeUnrecoverableError call, else +// the compiler attempts to merge it with other calls, losing useful information +// in breakpad uploads. +syncer::SyncError GenericChangeProcessor::HandleActionUpdate( + const syncer::SyncChange& change, + const std::string& type_str, + const syncer::WriteTransaction& trans, + syncer::WriteNode* sync_node, + syncer::AttachmentIdSet* new_attachments) { + const syncer::SyncDataLocal sync_data_local(change.sync_data()); + syncer::BaseNode::InitByLookupResult result = + sync_node->InitByClientTagLookup(sync_data_local.GetDataType(), + sync_data_local.GetTag()); + if (result != syncer::BaseNode::INIT_OK) { + std::string error_prefix = "Failed to load " + type_str + " node. " + + change.location().ToString() + ", "; + if (result == syncer::BaseNode::INIT_FAILED_PRECONDITION) { + syncer::SyncError error; + error.Reset(FROM_HERE, error_prefix + "empty tag", type_); + error_handler()->OnSingleDataTypeUnrecoverableError(error); + LOG(ERROR) << "Update: Empty tag."; + return error; + } else if (result == syncer::BaseNode::INIT_FAILED_ENTRY_NOT_GOOD) { + syncer::SyncError error; + error.Reset(FROM_HERE, error_prefix + "bad entry", type_); + error_handler()->OnSingleDataTypeUnrecoverableError(error); + LOG(ERROR) << "Update: bad entry."; + return error; + } else if (result == syncer::BaseNode::INIT_FAILED_ENTRY_IS_DEL) { + syncer::SyncError error; + error.Reset(FROM_HERE, error_prefix + "deleted entry", type_); + error_handler()->OnSingleDataTypeUnrecoverableError(error); + LOG(ERROR) << "Update: deleted entry."; + return error; + } else if (result == syncer::BaseNode::INIT_FAILED_DECRYPT_IF_NECESSARY) { + syncer::SyncError error; + error.Reset(FROM_HERE, error_prefix + "failed to decrypt", type_); + error_handler()->OnSingleDataTypeUnrecoverableError(error); + LOG(ERROR) << "Update: Failed to decrypt."; + return error; + } else { + NOTREACHED(); + syncer::SyncError error; + error.Reset(FROM_HERE, error_prefix + "unknown error", type_); + error_handler()->OnSingleDataTypeUnrecoverableError(error); + LOG(ERROR) << "Update: Unknown error."; + return error; + } + } + + sync_node->SetTitle(change.sync_data().GetTitle()); + SetNodeSpecifics(sync_data_local.GetSpecifics(), sync_node); + syncer::AttachmentIdList attachment_ids = sync_data_local.GetAttachmentIds(); + SetAttachmentMetadata(attachment_ids, sync_node); + + // Return any newly added attachments. + new_attachments->insert(attachment_ids.begin(), attachment_ids.end()); + + if (merge_result_.get()) { + merge_result_->set_num_items_modified(merge_result_->num_items_modified() + + 1); + } + // TODO(sync): Support updating other parts of the sync node (title, + // successor, parent, etc.). + return syncer::SyncError(); +} + +bool GenericChangeProcessor::SyncModelHasUserCreatedNodes(bool* has_nodes) { + DCHECK(CalledOnValidThread()); + DCHECK(has_nodes); + std::string type_name = syncer::ModelTypeToString(type_); + std::string err_str = + "Server did not create the top-level " + type_name + + " node. We might be running against an out-of-date server."; + *has_nodes = false; + syncer::ReadTransaction trans(FROM_HERE, share_handle()); + syncer::ReadNode type_root_node(&trans); + if (type_root_node.InitTypeRoot(type_) != syncer::BaseNode::INIT_OK) { + LOG(ERROR) << err_str; + return false; + } + + // The sync model has user created nodes if the type's root node has any + // children. + *has_nodes = type_root_node.HasChildren(); + return true; +} + +bool GenericChangeProcessor::CryptoReadyIfNecessary() { + DCHECK(CalledOnValidThread()); + // We only access the cryptographer while holding a transaction. + syncer::ReadTransaction trans(FROM_HERE, share_handle()); + const syncer::ModelTypeSet encrypted_types = trans.GetEncryptedTypes(); + return !encrypted_types.Has(type_) || trans.GetCryptographer()->is_ready(); +} + +void GenericChangeProcessor::StartImpl() {} + +syncer::UserShare* GenericChangeProcessor::share_handle() const { + DCHECK(CalledOnValidThread()); + return share_handle_; +} + +void GenericChangeProcessor::UploadAllAttachmentsNotOnServer() { + DCHECK(CalledOnValidThread()); + DCHECK(attachment_service_.get()); + syncer::AttachmentIdList ids; + { + syncer::ReadTransaction trans(FROM_HERE, share_handle()); + trans.GetAttachmentIdsToUpload(type_, &ids); + } + if (!ids.empty()) { + attachment_service_->UploadAttachments(ids); + } +} + +std::unique_ptr<syncer::AttachmentService> +GenericChangeProcessor::GetAttachmentService() const { + return std::unique_ptr<syncer::AttachmentService>( + new syncer::AttachmentServiceProxy(attachment_service_proxy_)); +} + +} // namespace sync_driver
diff --git a/components/sync/driver/generic_change_processor.h b/components/sync/driver/generic_change_processor.h new file mode 100644 index 0000000..67af8ad --- /dev/null +++ b/components/sync/driver/generic_change_processor.h
@@ -0,0 +1,182 @@ +// 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 COMPONENTS_SYNC_DRIVER_GENERIC_CHANGE_PROCESSOR_H_ +#define COMPONENTS_SYNC_DRIVER_GENERIC_CHANGE_PROCESSOR_H_ + +#include <stdint.h> + +#include <memory> +#include <string> +#include <vector> + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/threading/non_thread_safe.h" +#include "components/sync/api/attachments/attachment_store.h" +#include "components/sync/api/sync_change_processor.h" +#include "components/sync/api/sync_merge_result.h" +#include "components/sync/core/attachments/attachment_service.h" +#include "components/sync/core/attachments/attachment_service_proxy.h" +#include "components/sync/driver/change_processor.h" + +namespace syncer { +class DataTypeErrorHandler; +class SyncData; +class SyncableService; +class WriteNode; +class WriteTransaction; + +typedef std::vector<syncer::SyncData> SyncDataList; +} // namespace syncer + +namespace sync_driver { + +class SyncApiComponentFactory; +class SyncClient; + +// Datatype agnostic change processor. One instance of GenericChangeProcessor +// is created for each datatype and lives on the datatype's thread. It then +// handles all interaction with the sync api, both translating pushes from the +// local service into transactions and receiving changes from the sync model, +// which then get converted into SyncChange's and sent to the local service. +// +// As a rule, the GenericChangeProcessor is not thread safe, and should only +// be used on the same thread in which it was created. +class GenericChangeProcessor : public ChangeProcessor, + public syncer::SyncChangeProcessor, + public syncer::AttachmentService::Delegate, + public base::NonThreadSafe { + public: + // Create a change processor for |type| and connect it to the syncer. + // |attachment_store| can be NULL which means that datatype will not use sync + // attachments. + GenericChangeProcessor( + syncer::ModelType type, + syncer::DataTypeErrorHandler* error_handler, + const base::WeakPtr<syncer::SyncableService>& local_service, + const base::WeakPtr<syncer::SyncMergeResult>& merge_result, + syncer::UserShare* user_share, + SyncClient* sync_client, + std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store); + ~GenericChangeProcessor() override; + + // ChangeProcessor interface. + // Build and store a list of all changes into |syncer_changes_|. + void ApplyChangesFromSyncModel( + const syncer::BaseTransaction* trans, + int64_t version, + const syncer::ImmutableChangeRecordList& changes) override; + // Passes |syncer_changes_|, built in ApplyChangesFromSyncModel, onto + // |local_service_| by way of its ProcessSyncChanges method. + void CommitChangesFromSyncModel() override; + + // syncer::SyncChangeProcessor implementation. + syncer::SyncError ProcessSyncChanges( + const tracked_objects::Location& from_here, + const syncer::SyncChangeList& change_list) override; + syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override; + syncer::SyncError UpdateDataTypeContext( + syncer::ModelType type, + syncer::SyncChangeProcessor::ContextRefreshStatus refresh_status, + const std::string& context) override; + + // syncer::AttachmentService::Delegate implementation. + void OnAttachmentUploaded(const syncer::AttachmentId& attachment_id) override; + + // Similar to above, but returns a SyncError for use by direct clients + // of GenericChangeProcessor that may need more error visibility. + virtual syncer::SyncError GetAllSyncDataReturnError( + syncer::SyncDataList* data) const; + + // If a datatype context associated with this GenericChangeProcessor's type + // exists, fills |context| and returns true. Otheriwse, if there has not been + // a context set, returns false. + virtual bool GetDataTypeContext(std::string* context) const; + + // Returns the number of items for this type. + virtual int GetSyncCount(); + + // Generic versions of AssociatorInterface methods. Called by + // syncer::SyncableServiceAdapter or the DataTypeController. + virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes); + virtual bool CryptoReadyIfNecessary(); + + // Gets AttachmentService proxy for datatype. + std::unique_ptr<syncer::AttachmentService> GetAttachmentService() const; + + protected: + // ChangeProcessor interface. + void StartImpl() override; // Does nothing. + syncer::UserShare* share_handle() const override; + + private: + // Logically part of ProcessSyncChanges. + // + // |new_attachments| is an output parameter containing newly added attachments + // that need to be stored. This method will append to it. + syncer::SyncError HandleActionAdd(const syncer::SyncChange& change, + const std::string& type_str, + const syncer::WriteTransaction& trans, + syncer::WriteNode* sync_node, + syncer::AttachmentIdSet* new_attachments); + + // Logically part of ProcessSyncChanges. + // + // |new_attachments| is an output parameter containing newly added attachments + // that need to be stored. This method will append to it. + syncer::SyncError HandleActionUpdate( + const syncer::SyncChange& change, + const std::string& type_str, + const syncer::WriteTransaction& trans, + syncer::WriteNode* sync_node, + syncer::AttachmentIdSet* new_attachments); + + // Begin uploading attachments that have not yet been uploaded to the sync + // server. + void UploadAllAttachmentsNotOnServer(); + + const syncer::ModelType type_; + + // The SyncableService this change processor will forward changes on to. + const base::WeakPtr<syncer::SyncableService> local_service_; + + // A SyncMergeResult used to track the changes made during association. The + // owner will invalidate the weak pointer when association is complete. While + // the pointer is valid though, we increment it with any changes received + // via ProcessSyncChanges. + const base::WeakPtr<syncer::SyncMergeResult> merge_result_; + + // The current list of changes received from the syncer. We buffer because + // we must ensure no syncapi transaction is held when we pass it on to + // |local_service_|. + // Set in ApplyChangesFromSyncModel, consumed in CommitChangesFromSyncModel. + syncer::SyncChangeList syncer_changes_; + + // Our handle to the sync model. Unlike normal ChangeProcessors, we need to + // be able to access the sync model before the change processor begins + // listening to changes (the local_service_ will be interacting with us + // when it starts up). As such we can't wait until Start(_) has been called, + // and have to keep a local pointer to the user_share. + syncer::UserShare* const share_handle_; + + // AttachmentService for datatype. Can be NULL if datatype doesn't use + // attachments. + std::unique_ptr<syncer::AttachmentService> attachment_service_; + + // Must be destroyed before attachment_service_ to ensure WeakPtrs are + // invalidated before attachment_service_ is destroyed. + // Can be NULL if attachment_service_ is NULL; + std::unique_ptr<base::WeakPtrFactory<syncer::AttachmentService>> + attachment_service_weak_ptr_factory_; + syncer::AttachmentServiceProxy attachment_service_proxy_; + base::WeakPtrFactory<GenericChangeProcessor> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(GenericChangeProcessor); +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_GENERIC_CHANGE_PROCESSOR_H_
diff --git a/components/sync/driver/generic_change_processor_factory.cc b/components/sync/driver/generic_change_processor_factory.cc new file mode 100644 index 0000000..6ba36cb1 --- /dev/null +++ b/components/sync/driver/generic_change_processor_factory.cc
@@ -0,0 +1,31 @@ +// 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 "components/sync/driver/generic_change_processor_factory.h" + +#include "base/memory/ptr_util.h" +#include "components/sync/api/syncable_service.h" +#include "components/sync/driver/generic_change_processor.h" + +namespace sync_driver { + +GenericChangeProcessorFactory::GenericChangeProcessorFactory() {} + +GenericChangeProcessorFactory::~GenericChangeProcessorFactory() {} + +std::unique_ptr<GenericChangeProcessor> +GenericChangeProcessorFactory::CreateGenericChangeProcessor( + syncer::ModelType type, + syncer::UserShare* user_share, + syncer::DataTypeErrorHandler* error_handler, + const base::WeakPtr<syncer::SyncableService>& local_service, + const base::WeakPtr<syncer::SyncMergeResult>& merge_result, + SyncClient* sync_client) { + DCHECK(user_share); + return base::WrapUnique(new GenericChangeProcessor( + type, error_handler, local_service, merge_result, user_share, sync_client, + local_service->GetAttachmentStoreForSync())); +} + +} // namespace sync_driver
diff --git a/components/sync_driver/generic_change_processor_factory.h b/components/sync/driver/generic_change_processor_factory.h similarity index 100% rename from components/sync_driver/generic_change_processor_factory.h rename to components/sync/driver/generic_change_processor_factory.h
diff --git a/components/sync/driver/generic_change_processor_unittest.cc b/components/sync/driver/generic_change_processor_unittest.cc new file mode 100644 index 0000000..cd6e9a4 --- /dev/null +++ b/components/sync/driver/generic_change_processor_unittest.cc
@@ -0,0 +1,543 @@ +// 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 "components/sync/driver/generic_change_processor.h" + +#include <stddef.h> + +#include <memory> +#include <string> +#include <utility> + +#include "base/memory/weak_ptr.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/strings/stringprintf.h" +#include "components/sync/api/attachments/attachment_id.h" +#include "components/sync/api/attachments/attachment_store.h" +#include "components/sync/api/fake_syncable_service.h" +#include "components/sync/api/sync_change.h" +#include "components/sync/api/sync_merge_result.h" +#include "components/sync/base/model_type.h" +#include "components/sync/core/attachments/attachment_service_impl.h" +#include "components/sync/core/attachments/fake_attachment_downloader.h" +#include "components/sync/core/attachments/fake_attachment_uploader.h" +#include "components/sync/core/read_node.h" +#include "components/sync/core/read_transaction.h" +#include "components/sync/core/sync_encryption_handler.h" +#include "components/sync/core/test/data_type_error_handler_mock.h" +#include "components/sync/core/test/test_user_share.h" +#include "components/sync/core/user_share.h" +#include "components/sync/core/write_node.h" +#include "components/sync/core/write_transaction.h" +#include "components/sync/driver/fake_sync_client.h" +#include "components/sync/driver/local_device_info_provider.h" +#include "components/sync/driver/sync_api_component_factory.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace sync_driver { + +namespace { + +// A mock that keeps track of attachments passed to UploadAttachments. +class MockAttachmentService : public syncer::AttachmentServiceImpl { + public: + MockAttachmentService( + std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store); + ~MockAttachmentService() override; + void UploadAttachments( + const syncer::AttachmentIdList& attachment_ids) override; + std::vector<syncer::AttachmentIdList>* attachment_id_lists(); + + private: + std::vector<syncer::AttachmentIdList> attachment_id_lists_; +}; + +MockAttachmentService::MockAttachmentService( + std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store) + : AttachmentServiceImpl(std::move(attachment_store), + std::unique_ptr<syncer::AttachmentUploader>( + new syncer::FakeAttachmentUploader), + std::unique_ptr<syncer::AttachmentDownloader>( + new syncer::FakeAttachmentDownloader), + NULL, + base::TimeDelta(), + base::TimeDelta()) {} + +MockAttachmentService::~MockAttachmentService() {} + +void MockAttachmentService::UploadAttachments( + const syncer::AttachmentIdList& attachment_ids) { + attachment_id_lists_.push_back(attachment_ids); + AttachmentServiceImpl::UploadAttachments(attachment_ids); +} + +std::vector<syncer::AttachmentIdList>* +MockAttachmentService::attachment_id_lists() { + return &attachment_id_lists_; +} + +// MockSyncApiComponentFactory needed to initialize GenericChangeProcessor and +// pass MockAttachmentService to it. +class MockSyncApiComponentFactory : public SyncApiComponentFactory { + public: + MockSyncApiComponentFactory() {} + + // SyncApiComponentFactory implementation. + void RegisterDataTypes( + sync_driver::SyncService* sync_service, + const RegisterDataTypesMethod& register_platform_types_method) override {} + sync_driver::DataTypeManager* CreateDataTypeManager( + const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& + debug_info_listener, + const sync_driver::DataTypeController::TypeMap* controllers, + const sync_driver::DataTypeEncryptionHandler* encryption_handler, + browser_sync::SyncBackendHost* backend, + sync_driver::DataTypeManagerObserver* observer) override { + return nullptr; + }; + browser_sync::SyncBackendHost* CreateSyncBackendHost( + const std::string& name, + invalidation::InvalidationService* invalidator, + const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs, + const base::FilePath& sync_folder) override { + return nullptr; + } + std::unique_ptr<sync_driver::LocalDeviceInfoProvider> + CreateLocalDeviceInfoProvider() override { + return nullptr; + } + SyncComponents CreateBookmarkSyncComponents( + sync_driver::SyncService* sync_service, + syncer::DataTypeErrorHandler* error_handler) override { + return SyncComponents(nullptr, nullptr); + } + + std::unique_ptr<syncer::AttachmentService> CreateAttachmentService( + std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store, + const syncer::UserShare& user_share, + const std::string& store_birthday, + syncer::ModelType model_type, + syncer::AttachmentService::Delegate* delegate) override { + std::unique_ptr<MockAttachmentService> attachment_service( + new MockAttachmentService(std::move(attachment_store))); + // GenericChangeProcessor takes ownership of the AttachmentService, but we + // need to have a pointer to it so we can see that it was used properly. + // Take a pointer and trust that GenericChangeProcessor does not prematurely + // destroy it. + mock_attachment_service_ = attachment_service.get(); + return std::move(attachment_service); + } + + MockAttachmentService* GetMockAttachmentService() { + return mock_attachment_service_; + } + + private: + MockAttachmentService* mock_attachment_service_; +}; + +class SyncGenericChangeProcessorTest : public testing::Test { + public: + // Most test cases will use this type. For those that need a + // GenericChangeProcessor for a different type, use |InitializeForType|. + static const syncer::ModelType kType = syncer::PREFERENCES; + + SyncGenericChangeProcessorTest() + : syncable_service_ptr_factory_(&fake_syncable_service_), + mock_attachment_service_(NULL), + sync_client_(&sync_factory_) {} + + void SetUp() override { + // Use kType by default, but allow test cases to re-initialize with whatever + // type they choose. Therefore, it's important that all type dependent + // initialization occurs in InitializeForType. + InitializeForType(kType); + } + + void TearDown() override { + mock_attachment_service_ = NULL; + if (test_user_share_) { + test_user_share_->TearDown(); + } + } + + // Initialize GenericChangeProcessor and related classes for testing with + // model type |type|. + void InitializeForType(syncer::ModelType type) { + TearDown(); + test_user_share_.reset(new syncer::TestUserShare); + test_user_share_->SetUp(); + sync_merge_result_.reset(new syncer::SyncMergeResult(type)); + merge_result_ptr_factory_.reset( + new base::WeakPtrFactory<syncer::SyncMergeResult>( + sync_merge_result_.get())); + + syncer::ModelTypeSet types = syncer::ProtocolTypes(); + for (syncer::ModelTypeSet::Iterator iter = types.First(); iter.Good(); + iter.Inc()) { + syncer::TestUserShare::CreateRoot(iter.Get(), + test_user_share_->user_share()); + } + test_user_share_->encryption_handler()->Init(); + ConstructGenericChangeProcessor(type); + } + + void ConstructGenericChangeProcessor(syncer::ModelType type) { + std::unique_ptr<syncer::AttachmentStore> attachment_store = + syncer::AttachmentStore::CreateInMemoryStore(); + change_processor_.reset(new GenericChangeProcessor( + type, &data_type_error_handler_, + syncable_service_ptr_factory_.GetWeakPtr(), + merge_result_ptr_factory_->GetWeakPtr(), test_user_share_->user_share(), + &sync_client_, attachment_store->CreateAttachmentStoreForSync())); + mock_attachment_service_ = sync_factory_.GetMockAttachmentService(); + } + + void BuildChildNodes(syncer::ModelType type, int n) { + syncer::WriteTransaction trans(FROM_HERE, user_share()); + for (int i = 0; i < n; ++i) { + syncer::WriteNode node(&trans); + node.InitUniqueByCreation(type, base::StringPrintf("node%05d", i)); + } + } + + GenericChangeProcessor* change_processor() { return change_processor_.get(); } + + syncer::UserShare* user_share() { return test_user_share_->user_share(); } + + MockAttachmentService* mock_attachment_service() { + return mock_attachment_service_; + } + + void RunLoop() { + base::RunLoop run_loop; + run_loop.RunUntilIdle(); + } + + private: + base::MessageLoopForUI loop_; + + std::unique_ptr<syncer::SyncMergeResult> sync_merge_result_; + std::unique_ptr<base::WeakPtrFactory<syncer::SyncMergeResult>> + merge_result_ptr_factory_; + + syncer::FakeSyncableService fake_syncable_service_; + base::WeakPtrFactory<syncer::FakeSyncableService> + syncable_service_ptr_factory_; + + syncer::DataTypeErrorHandlerMock data_type_error_handler_; + std::unique_ptr<syncer::TestUserShare> test_user_share_; + MockAttachmentService* mock_attachment_service_; + FakeSyncClient sync_client_; + MockSyncApiComponentFactory sync_factory_; + + std::unique_ptr<GenericChangeProcessor> change_processor_; +}; + +// Similar to above, but focused on the method that implements sync/api +// interfaces and is hence exposed to datatypes directly. +TEST_F(SyncGenericChangeProcessorTest, StressGetAllSyncData) { + const int kNumChildNodes = 1000; + const int kRepeatCount = 1; + + ASSERT_NO_FATAL_FAILURE(BuildChildNodes(kType, kNumChildNodes)); + + for (int i = 0; i < kRepeatCount; ++i) { + syncer::SyncDataList sync_data = change_processor()->GetAllSyncData(kType); + + // Start with a simple test. We can add more in-depth testing later. + EXPECT_EQ(static_cast<size_t>(kNumChildNodes), sync_data.size()); + } +} + +TEST_F(SyncGenericChangeProcessorTest, SetGetPasswords) { + InitializeForType(syncer::PASSWORDS); + const int kNumPasswords = 10; + sync_pb::PasswordSpecificsData password_data; + password_data.set_username_value("user"); + + sync_pb::EntitySpecifics password_holder; + + syncer::SyncChangeList change_list; + for (int i = 0; i < kNumPasswords; ++i) { + password_data.set_password_value(base::StringPrintf("password%i", i)); + password_holder.mutable_password() + ->mutable_client_only_encrypted_data() + ->CopyFrom(password_data); + change_list.push_back(syncer::SyncChange( + FROM_HERE, syncer::SyncChange::ACTION_ADD, + syncer::SyncData::CreateLocalData(base::StringPrintf("tag%i", i), + base::StringPrintf("title%i", i), + password_holder))); + } + + ASSERT_FALSE( + change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet()); + + syncer::SyncDataList password_list( + change_processor()->GetAllSyncData(syncer::PASSWORDS)); + + ASSERT_EQ(password_list.size(), change_list.size()); + for (int i = 0; i < kNumPasswords; ++i) { + // Verify the password is returned properly. + ASSERT_TRUE(password_list[i].GetSpecifics().has_password()); + ASSERT_TRUE(password_list[i] + .GetSpecifics() + .password() + .has_client_only_encrypted_data()); + ASSERT_FALSE(password_list[i].GetSpecifics().password().has_encrypted()); + const sync_pb::PasswordSpecificsData& sync_password = + password_list[i].GetSpecifics().password().client_only_encrypted_data(); + const sync_pb::PasswordSpecificsData& change_password = + change_list[i] + .sync_data() + .GetSpecifics() + .password() + .client_only_encrypted_data(); + ASSERT_EQ(sync_password.password_value(), change_password.password_value()); + ASSERT_EQ(sync_password.username_value(), change_password.username_value()); + + // Verify the raw sync data was stored securely. + syncer::ReadTransaction read_transaction(FROM_HERE, user_share()); + syncer::ReadNode node(&read_transaction); + ASSERT_EQ(node.InitByClientTagLookup(syncer::PASSWORDS, + base::StringPrintf("tag%i", i)), + syncer::BaseNode::INIT_OK); + ASSERT_EQ(node.GetTitle(), "encrypted"); + const sync_pb::EntitySpecifics& raw_specifics = node.GetEntitySpecifics(); + ASSERT_TRUE(raw_specifics.has_password()); + ASSERT_TRUE(raw_specifics.password().has_encrypted()); + ASSERT_FALSE(raw_specifics.password().has_client_only_encrypted_data()); + } +} + +TEST_F(SyncGenericChangeProcessorTest, UpdatePasswords) { + InitializeForType(syncer::PASSWORDS); + const int kNumPasswords = 10; + sync_pb::PasswordSpecificsData password_data; + password_data.set_username_value("user"); + + sync_pb::EntitySpecifics password_holder; + + syncer::SyncChangeList change_list; + syncer::SyncChangeList change_list2; + for (int i = 0; i < kNumPasswords; ++i) { + password_data.set_password_value(base::StringPrintf("password%i", i)); + password_holder.mutable_password() + ->mutable_client_only_encrypted_data() + ->CopyFrom(password_data); + change_list.push_back(syncer::SyncChange( + FROM_HERE, syncer::SyncChange::ACTION_ADD, + syncer::SyncData::CreateLocalData(base::StringPrintf("tag%i", i), + base::StringPrintf("title%i", i), + password_holder))); + password_data.set_password_value(base::StringPrintf("password_m%i", i)); + password_holder.mutable_password() + ->mutable_client_only_encrypted_data() + ->CopyFrom(password_data); + change_list2.push_back(syncer::SyncChange( + FROM_HERE, syncer::SyncChange::ACTION_UPDATE, + syncer::SyncData::CreateLocalData(base::StringPrintf("tag%i", i), + base::StringPrintf("title_m%i", i), + password_holder))); + } + + ASSERT_FALSE( + change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet()); + ASSERT_FALSE( + change_processor()->ProcessSyncChanges(FROM_HERE, change_list2).IsSet()); + + syncer::SyncDataList password_list( + change_processor()->GetAllSyncData(syncer::PASSWORDS)); + + ASSERT_EQ(password_list.size(), change_list2.size()); + for (int i = 0; i < kNumPasswords; ++i) { + // Verify the password is returned properly. + ASSERT_TRUE(password_list[i].GetSpecifics().has_password()); + ASSERT_TRUE(password_list[i] + .GetSpecifics() + .password() + .has_client_only_encrypted_data()); + ASSERT_FALSE(password_list[i].GetSpecifics().password().has_encrypted()); + const sync_pb::PasswordSpecificsData& sync_password = + password_list[i].GetSpecifics().password().client_only_encrypted_data(); + const sync_pb::PasswordSpecificsData& change_password = + change_list2[i] + .sync_data() + .GetSpecifics() + .password() + .client_only_encrypted_data(); + ASSERT_EQ(sync_password.password_value(), change_password.password_value()); + ASSERT_EQ(sync_password.username_value(), change_password.username_value()); + + // Verify the raw sync data was stored securely. + syncer::ReadTransaction read_transaction(FROM_HERE, user_share()); + syncer::ReadNode node(&read_transaction); + ASSERT_EQ(node.InitByClientTagLookup(syncer::PASSWORDS, + base::StringPrintf("tag%i", i)), + syncer::BaseNode::INIT_OK); + ASSERT_EQ(node.GetTitle(), "encrypted"); + const sync_pb::EntitySpecifics& raw_specifics = node.GetEntitySpecifics(); + ASSERT_TRUE(raw_specifics.has_password()); + ASSERT_TRUE(raw_specifics.password().has_encrypted()); + ASSERT_FALSE(raw_specifics.password().has_client_only_encrypted_data()); + } +} + +// Verify that attachments on newly added or updated SyncData are passed to the +// AttachmentService. +TEST_F(SyncGenericChangeProcessorTest, + ProcessSyncChanges_AddUpdateWithAttachment) { + std::string tag = "client_tag"; + std::string title = "client_title"; + sync_pb::EntitySpecifics specifics; + sync_pb::PreferenceSpecifics* pref_specifics = specifics.mutable_preference(); + pref_specifics->set_name("test"); + + syncer::AttachmentIdList attachment_ids; + attachment_ids.push_back(syncer::AttachmentId::Create(0, 0)); + attachment_ids.push_back(syncer::AttachmentId::Create(0, 0)); + + // Add a SyncData with two attachments. + syncer::SyncChangeList change_list; + change_list.push_back( + syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, + syncer::SyncData::CreateLocalDataWithAttachments( + tag, title, specifics, attachment_ids))); + ASSERT_FALSE( + change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet()); + RunLoop(); + + // Check that the AttachmentService received the new attachments. + ASSERT_EQ(mock_attachment_service()->attachment_id_lists()->size(), 1U); + const syncer::AttachmentIdList& attachments_added = + mock_attachment_service()->attachment_id_lists()->front(); + ASSERT_THAT(attachments_added, testing::UnorderedElementsAre( + attachment_ids[0], attachment_ids[1])); + + // Update the SyncData, replacing its two attachments with one new attachment. + syncer::AttachmentIdList new_attachment_ids; + new_attachment_ids.push_back(syncer::AttachmentId::Create(0, 0)); + mock_attachment_service()->attachment_id_lists()->clear(); + change_list.clear(); + change_list.push_back( + syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_UPDATE, + syncer::SyncData::CreateLocalDataWithAttachments( + tag, title, specifics, new_attachment_ids))); + ASSERT_FALSE( + change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet()); + RunLoop(); + + // Check that the AttachmentService received it. + ASSERT_EQ(mock_attachment_service()->attachment_id_lists()->size(), 1U); + const syncer::AttachmentIdList& new_attachments_added = + mock_attachment_service()->attachment_id_lists()->front(); + ASSERT_THAT(new_attachments_added, + testing::UnorderedElementsAre(new_attachment_ids[0])); +} + +// Verify that after attachment is uploaded GenericChangeProcessor updates +// corresponding entries +TEST_F(SyncGenericChangeProcessorTest, AttachmentUploaded) { + std::string tag = "client_tag"; + std::string title = "client_title"; + sync_pb::EntitySpecifics specifics; + sync_pb::PreferenceSpecifics* pref_specifics = specifics.mutable_preference(); + pref_specifics->set_name("test"); + + syncer::AttachmentIdList attachment_ids; + attachment_ids.push_back(syncer::AttachmentId::Create(0, 0)); + + // Add a SyncData with two attachments. + syncer::SyncChangeList change_list; + change_list.push_back( + syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, + syncer::SyncData::CreateLocalDataWithAttachments( + tag, title, specifics, attachment_ids))); + ASSERT_FALSE( + change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet()); + + sync_pb::AttachmentIdProto attachment_id_proto = attachment_ids[0].GetProto(); + syncer::AttachmentId attachment_id = + syncer::AttachmentId::CreateFromProto(attachment_id_proto); + + change_processor()->OnAttachmentUploaded(attachment_id); + syncer::ReadTransaction read_transaction(FROM_HERE, user_share()); + syncer::ReadNode node(&read_transaction); + ASSERT_EQ(node.InitByClientTagLookup(kType, tag), syncer::BaseNode::INIT_OK); + attachment_ids = node.GetAttachmentIds(); + EXPECT_EQ(1U, attachment_ids.size()); +} + +// Verify that upon construction, all attachments not yet on the server are +// scheduled for upload. +TEST_F(SyncGenericChangeProcessorTest, UploadAllAttachmentsNotOnServer) { + // Create two attachment ids. id2 will be marked as "on server". + syncer::AttachmentId id1 = syncer::AttachmentId::Create(0, 0); + syncer::AttachmentId id2 = syncer::AttachmentId::Create(0, 0); + { + // Write an entry containing these two attachment ids. + syncer::WriteTransaction trans(FROM_HERE, user_share()); + syncer::ReadNode root(&trans); + ASSERT_EQ(syncer::BaseNode::INIT_OK, root.InitTypeRoot(kType)); + syncer::WriteNode node(&trans); + node.InitUniqueByCreation(kType, root, "some node"); + sync_pb::AttachmentMetadata metadata; + sync_pb::AttachmentMetadataRecord* record1 = metadata.add_record(); + *record1->mutable_id() = id1.GetProto(); + sync_pb::AttachmentMetadataRecord* record2 = metadata.add_record(); + *record2->mutable_id() = id2.GetProto(); + record2->set_is_on_server(true); + node.SetAttachmentMetadata(metadata); + } + + // Construct the GenericChangeProcessor and see that it asks the + // AttachmentService to upload id1 only. + ConstructGenericChangeProcessor(kType); + ASSERT_EQ(1U, mock_attachment_service()->attachment_id_lists()->size()); + ASSERT_THAT(mock_attachment_service()->attachment_id_lists()->front(), + testing::UnorderedElementsAre(id1)); +} + +// Test that attempting to add an entry that already exists still works. +TEST_F(SyncGenericChangeProcessorTest, AddExistingEntry) { + InitializeForType(syncer::SESSIONS); + sync_pb::EntitySpecifics sessions_specifics; + sessions_specifics.mutable_session()->set_session_tag("session tag"); + syncer::SyncChangeList changes; + + // First add it normally. + changes.push_back(syncer::SyncChange( + FROM_HERE, syncer::SyncChange::ACTION_ADD, + syncer::SyncData::CreateLocalData(base::StringPrintf("tag"), + base::StringPrintf("title"), + sessions_specifics))); + ASSERT_FALSE( + change_processor()->ProcessSyncChanges(FROM_HERE, changes).IsSet()); + + // Now attempt to add it again, but with different specifics. Should not + // result in an error and should still update the specifics. + sessions_specifics.mutable_session()->set_session_tag("session tag 2"); + changes[0] = + syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, + syncer::SyncData::CreateLocalData( + base::StringPrintf("tag"), + base::StringPrintf("title"), sessions_specifics)); + ASSERT_FALSE( + change_processor()->ProcessSyncChanges(FROM_HERE, changes).IsSet()); + + // Verify the data was updated properly. + syncer::SyncDataList sync_data = + change_processor()->GetAllSyncData(syncer::SESSIONS); + ASSERT_EQ(sync_data.size(), 1U); + ASSERT_EQ("session tag 2", + sync_data[0].GetSpecifics().session().session_tag()); + EXPECT_FALSE(syncer::SyncDataRemote(sync_data[0]).GetClientTagHash().empty()); +} + +} // namespace + +} // namespace sync_driver
diff --git a/components/sync/driver/glue/browser_thread_model_worker.cc b/components/sync/driver/glue/browser_thread_model_worker.cc new file mode 100644 index 0000000..8b8567c --- /dev/null +++ b/components/sync/driver/glue/browser_thread_model_worker.cc
@@ -0,0 +1,68 @@ +// 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. + +#include "components/sync/driver/glue/browser_thread_model_worker.h" + +#include "base/bind.h" +#include "base/single_thread_task_runner.h" +#include "base/synchronization/waitable_event.h" + +using base::SingleThreadTaskRunner; +using base::WaitableEvent; + +namespace browser_sync { + +BrowserThreadModelWorker::BrowserThreadModelWorker( + const scoped_refptr<SingleThreadTaskRunner>& runner, + syncer::ModelSafeGroup group, + syncer::WorkerLoopDestructionObserver* observer) + : ModelSafeWorker(observer), runner_(runner), group_(group) {} + +syncer::SyncerError BrowserThreadModelWorker::DoWorkAndWaitUntilDoneImpl( + const syncer::WorkCallback& work) { + syncer::SyncerError error = syncer::UNSET; + if (runner_->BelongsToCurrentThread()) { + DLOG(WARNING) << "Already on thread " << runner_; + return work.Run(); + } + + if (!runner_->PostTask( + FROM_HERE, + base::Bind(&BrowserThreadModelWorker::CallDoWorkAndSignalTask, this, + work, work_done_or_stopped(), &error))) { + DLOG(WARNING) << "Failed to post task to runner " << runner_; + error = syncer::CANNOT_DO_WORK; + return error; + } + work_done_or_stopped()->Wait(); + return error; +} + +syncer::ModelSafeGroup BrowserThreadModelWorker::GetModelSafeGroup() { + return group_; +} + +BrowserThreadModelWorker::~BrowserThreadModelWorker() {} + +void BrowserThreadModelWorker::RegisterForLoopDestruction() { + if (runner_->BelongsToCurrentThread()) { + SetWorkingLoopToCurrent(); + } else { + runner_->PostTask( + FROM_HERE, + Bind(&BrowserThreadModelWorker::RegisterForLoopDestruction, this)); + } +} + +void BrowserThreadModelWorker::CallDoWorkAndSignalTask( + const syncer::WorkCallback& work, + WaitableEvent* done, + syncer::SyncerError* error) { + DCHECK(runner_->BelongsToCurrentThread()); + if (!IsStopped()) + *error = work.Run(); + done->Signal(); +} + +} // namespace browser_sync
diff --git a/components/sync_driver/glue/browser_thread_model_worker.h b/components/sync/driver/glue/browser_thread_model_worker.h similarity index 100% rename from components/sync_driver/glue/browser_thread_model_worker.h rename to components/sync/driver/glue/browser_thread_model_worker.h
diff --git a/components/sync/driver/glue/browser_thread_model_worker_unittest.cc b/components/sync/driver/glue/browser_thread_model_worker_unittest.cc new file mode 100644 index 0000000..883cae2b --- /dev/null +++ b/components/sync/driver/glue/browser_thread_model_worker_unittest.cc
@@ -0,0 +1,100 @@ +// 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/sync/driver/glue/browser_thread_model_worker.h" + +#include "base/bind.h" +#include "base/callback.h" +#include "base/location.h" +#include "base/memory/weak_ptr.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/single_thread_task_runner.h" +#include "base/test/test_timeouts.h" +#include "base/threading/thread.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/timer/timer.h" +#include "testing/gtest/include/gtest/gtest.h" + +using base::Thread; +using base::TimeDelta; + +namespace browser_sync { + +namespace { + +class SyncBrowserThreadModelWorkerTest : public testing::Test { + public: + SyncBrowserThreadModelWorkerTest() + : db_thread_("DB_Thread"), did_do_work_(false), weak_factory_(this) {} + + bool did_do_work() { return did_do_work_; } + BrowserThreadModelWorker* worker() { return worker_.get(); } + base::OneShotTimer* timer() { return &timer_; } + base::WeakPtrFactory<SyncBrowserThreadModelWorkerTest>* factory() { + return &weak_factory_; + } + + // Schedule DoWork to be executed on the DB thread and have the test fail if + // DoWork hasn't executed within action_timeout(). + void ScheduleWork() { + // We wait until the callback is done. So it is safe to use unretained. + syncer::WorkCallback c = base::Bind( + &SyncBrowserThreadModelWorkerTest::DoWork, base::Unretained(this)); + timer()->Start(FROM_HERE, TestTimeouts::action_timeout(), this, + &SyncBrowserThreadModelWorkerTest::Timeout); + worker()->DoWorkAndWaitUntilDone(c); + } + + // This is the work that will be scheduled to be done on the DB thread. + syncer::SyncerError DoWork() { + EXPECT_TRUE(db_thread_.task_runner()->BelongsToCurrentThread()); + timer_.Stop(); // Stop the failure timer so the test succeeds. + main_message_loop_.task_runner()->PostTask( + FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); + did_do_work_ = true; + return syncer::SYNCER_OK; + } + + // This will be called by the OneShotTimer and make the test fail unless + // DoWork is called first. + void Timeout() { + ADD_FAILURE() << "Timed out waiting for work to be done on the DB thread."; + main_message_loop_.task_runner()->PostTask( + FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); + } + + protected: + void SetUp() override { + db_thread_.Start(); + worker_ = new BrowserThreadModelWorker(db_thread_.task_runner(), + syncer::GROUP_DB, NULL); + } + + virtual void Teardown() { + worker_ = NULL; + db_thread_.Stop(); + } + + private: + base::MessageLoop main_message_loop_; + Thread db_thread_; + bool did_do_work_; + scoped_refptr<BrowserThreadModelWorker> worker_; + base::OneShotTimer timer_; + + base::WeakPtrFactory<SyncBrowserThreadModelWorkerTest> weak_factory_; +}; + +TEST_F(SyncBrowserThreadModelWorkerTest, DoesWorkOnDatabaseThread) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(&SyncBrowserThreadModelWorkerTest::ScheduleWork, + factory()->GetWeakPtr())); + base::RunLoop().Run(); + EXPECT_TRUE(did_do_work()); +} + +} // namespace + +} // namespace browser_sync
diff --git a/components/sync/driver/glue/chrome_report_unrecoverable_error.cc b/components/sync/driver/glue/chrome_report_unrecoverable_error.cc new file mode 100644 index 0000000..ee29ed0 --- /dev/null +++ b/components/sync/driver/glue/chrome_report_unrecoverable_error.cc
@@ -0,0 +1,30 @@ +// 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/sync/driver/glue/chrome_report_unrecoverable_error.h" + +#include "base/debug/dump_without_crashing.h" +#include "base/rand_util.h" + +namespace browser_sync { + +void ChromeReportUnrecoverableError(version_info::Channel channel) { + // Only upload on canary/dev builds to avoid overwhelming crash server. + if (channel != version_info::Channel::CANARY && + channel != version_info::Channel::DEV) { + return; + } + + // We only want to upload |kErrorUploadRatio| ratio of errors. + const double kErrorUploadRatio = 0.01; + if (kErrorUploadRatio <= 0.0) + return; // We are not allowed to upload errors. + double random_number = base::RandDouble(); + if (random_number > kErrorUploadRatio) + return; + + base::debug::DumpWithoutCrashing(); +} + +} // namespace browser_sync
diff --git a/components/sync_driver/glue/chrome_report_unrecoverable_error.h b/components/sync/driver/glue/chrome_report_unrecoverable_error.h similarity index 100% rename from components/sync_driver/glue/chrome_report_unrecoverable_error.h rename to components/sync/driver/glue/chrome_report_unrecoverable_error.h
diff --git a/components/sync/driver/glue/sync_backend_host.cc b/components/sync/driver/glue/sync_backend_host.cc new file mode 100644 index 0000000..3e9d70f --- /dev/null +++ b/components/sync/driver/glue/sync_backend_host.cc
@@ -0,0 +1,13 @@ +// 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. + +#include "components/sync/driver/glue/sync_backend_host.h" + +namespace browser_sync { + +SyncBackendHost::SyncBackendHost() {} + +SyncBackendHost::~SyncBackendHost() {} + +} // namespace browser_sync
diff --git a/components/sync/driver/glue/sync_backend_host.h b/components/sync/driver/glue/sync_backend_host.h new file mode 100644 index 0000000..a78e522e --- /dev/null +++ b/components/sync/driver/glue/sync_backend_host.h
@@ -0,0 +1,241 @@ +// 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. + +#ifndef COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_H_ +#define COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_H_ + +#include <memory> +#include <string> + +#include "base/callback.h" +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/threading/thread.h" +#include "components/sync/base/model_type.h" +#include "components/sync/base/weak_handle.h" +#include "components/sync/core/configure_reason.h" +#include "components/sync/core/shutdown_reason.h" +#include "components/sync/core/sync_manager.h" +#include "components/sync/core/sync_manager_factory.h" +#include "components/sync/driver/backend_data_type_configurer.h" +#include "components/sync/sessions/sync_session_snapshot.h" + +class GURL; + +namespace base { +class MessageLoop; +} + +namespace syncer { +class CancelationSignal; +class HttpPostProviderFactory; +class SyncManagerFactory; +class UnrecoverableErrorHandler; +} + +namespace sync_driver { +class ChangeProcessor; +class SyncFrontend; +} + +namespace browser_sync { + +// An API to "host" the top level SyncAPI element. +// +// This class handles dispatch of potentially blocking calls to appropriate +// threads and ensures that the SyncFrontend is only accessed on the UI loop. +class SyncBackendHost : public sync_driver::BackendDataTypeConfigurer { + public: + typedef syncer::SyncStatus Status; + typedef base::Callback<std::unique_ptr<syncer::HttpPostProviderFactory>( + syncer::CancelationSignal*)> + HttpPostProviderFactoryGetter; + + // Stubs used by implementing classes. + SyncBackendHost(); + ~SyncBackendHost() override; + + // Called on the frontend's thread to kick off asynchronous initialization. + // Optionally deletes the "Sync Data" folder during init in order to make + // sure we're starting fresh. + // + // |saved_nigori_state| is optional nigori state to restore from a previous + // backend instance. May be null. + virtual void Initialize( + sync_driver::SyncFrontend* frontend, + std::unique_ptr<base::Thread> sync_thread, + const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, + const scoped_refptr<base::SingleThreadTaskRunner>& file_thread, + const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, + const GURL& service_url, + const std::string& sync_user_agent, + const syncer::SyncCredentials& credentials, + bool delete_sync_data_folder, + std::unique_ptr<syncer::SyncManagerFactory> sync_manager_factory, + const syncer::WeakHandle<syncer::UnrecoverableErrorHandler>& + unrecoverable_error_handler, + const base::Closure& report_unrecoverable_error_function, + const HttpPostProviderFactoryGetter& http_post_provider_factory_getter, + std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> + saved_nigori_state) = 0; + + // Called on the frontend's thread to trigger a refresh. + virtual void TriggerRefresh(const syncer::ModelTypeSet& types) = 0; + + // Called on the frontend's thread to update SyncCredentials. + virtual void UpdateCredentials( + const syncer::SyncCredentials& credentials) = 0; + + // This starts the SyncerThread running a Syncer object to communicate with + // sync servers. Until this is called, no changes will leave or enter this + // browser from the cloud / sync servers. + // Called on |frontend_loop_|. + virtual void StartSyncingWithServer() = 0; + + // Called on |frontend_loop_| to asynchronously set a new passphrase for + // encryption. Note that it is an error to call SetEncryptionPassphrase under + // the following circumstances: + // - An explicit passphrase has already been set + // - |is_explicit| is true and we have pending keys. + // When |is_explicit| is false, a couple of things could happen: + // - If there are pending keys, we try to decrypt them. If decryption works, + // this acts like a call to SetDecryptionPassphrase. If not, the GAIA + // passphrase passed in is cached so we can re-encrypt with it in future. + // - If there are no pending keys, data is encrypted with |passphrase| (this + // is a no-op if data was already encrypted with |passphrase|.) + virtual void SetEncryptionPassphrase(const std::string& passphrase, + bool is_explicit) = 0; + + // Called on |frontend_loop_| to use the provided passphrase to asynchronously + // attempt decryption. Returns false immediately if the passphrase could not + // be used to decrypt a locally cached copy of encrypted keys; returns true + // otherwise. If new encrypted keys arrive during the asynchronous call, + // OnPassphraseRequired may be triggered at a later time. It is an error to + // call this when there are no pending keys. + virtual bool SetDecryptionPassphrase(const std::string& passphrase) + WARN_UNUSED_RESULT = 0; + + // Called on |frontend_loop_| to kick off shutdown procedure. Attempts to cut + // short any long-lived or blocking sync thread tasks so that the shutdown on + // sync thread task that we're about to post won't have to wait very long. + virtual void StopSyncingForShutdown() = 0; + + // Called on |frontend_loop_| to kick off shutdown. + // See the implementation and Core::DoShutdown for details. + // Must be called *after* StopSyncingForShutdown. + // For any reason other than BROWSER_SHUTDOWN, caller should claim sync + // thread because: + // * during browser shutdown sync thread is not claimed to avoid blocking + // browser shutdown on sync shutdown. + // * otherwise sync thread is claimed so that if sync backend is recreated + // later, initialization of new backend is serialized on previous sync + // thread after cleanup of previous backend to avoid old/new backends + // interfere with each other. + virtual std::unique_ptr<base::Thread> Shutdown( + syncer::ShutdownReason reason) = 0; + + // Removes all current registrations from the backend on the + // InvalidationService. + virtual void UnregisterInvalidationIds() = 0; + + // Changes the set of data types that are currently being synced. + // The ready_task will be run when configuration is done with the + // set of all types that failed configuration (i.e., if its argument + // is non-empty, then an error was encountered). + // Returns the set of types that are ready to start without needing any + // further sync activity. + // BackendDataTypeConfigurer implementation. + syncer::ModelTypeSet ConfigureDataTypes( + syncer::ConfigureReason reason, + const DataTypeConfigStateMap& config_state_map, + const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& + ready_task, + const base::Callback<void()>& retry_callback) override = 0; + + // Turns on encryption of all present and future sync data. + virtual void EnableEncryptEverything() = 0; + + // Called on |frontend_loop_| to obtain a handle to the UserShare needed for + // creating transactions. Should not be called before we signal + // initialization is complete with OnBackendInitialized(). + virtual syncer::UserShare* GetUserShare() const = 0; + + // Called from any thread to obtain current status information in detailed or + // summarized form. + virtual Status GetDetailedStatus() = 0; + virtual syncer::sessions::SyncSessionSnapshot GetLastSessionSnapshot() + const = 0; + + // Determines if the underlying sync engine has made any local changes to + // items that have not yet been synced with the server. + // ONLY CALL THIS IF OnInitializationComplete was called! + virtual bool HasUnsyncedItems() const = 0; + + // Whether or not we are syncing encryption keys. + virtual bool IsNigoriEnabled() const = 0; + + // Returns the type of passphrase being used to encrypt data. See + // sync_encryption_handler.h. + virtual syncer::PassphraseType GetPassphraseType() const = 0; + + // If an explicit passphrase is in use, returns the time at which that + // passphrase was set (if available). + virtual base::Time GetExplicitPassphraseTime() const = 0; + + // True if the cryptographer has any keys available to attempt decryption. + // Could mean we've downloaded and loaded Nigori objects, or we bootstrapped + // using a token previously received. + virtual bool IsCryptographerReady( + const syncer::BaseTransaction* trans) const = 0; + + virtual void GetModelSafeRoutingInfo( + syncer::ModelSafeRoutingInfo* out) const = 0; + + // Send a message to the sync thread to persist the Directory to disk. + virtual void FlushDirectory() const = 0; + + // Requests that the backend forward to the fronent any protocol events in + // its buffer and begin forwarding automatically from now on. Repeated calls + // to this function may result in the same events being emitted several + // times. + virtual void RequestBufferedProtocolEventsAndEnableForwarding() = 0; + + // Disables protocol event forwarding. + virtual void DisableProtocolEventForwarding() = 0; + + // Returns a ListValue representing all nodes for the specified types through + // |callback| on this thread. + virtual void GetAllNodesForTypes( + syncer::ModelTypeSet types, + base::Callback<void(const std::vector<syncer::ModelType>&, + ScopedVector<base::ListValue>)> type) = 0; + + // Enables the sending of directory type debug counters. Also, for every + // time it is called, it makes an explicit request that updates to an update + // for all counters be emitted. + virtual void EnableDirectoryTypeDebugInfoForwarding() = 0; + + // Disables the sending of directory type debug counters. + virtual void DisableDirectoryTypeDebugInfoForwarding() = 0; + + virtual base::MessageLoop* GetSyncLoopForTesting() = 0; + + // Triggers sync cycle to update |types|. + virtual void RefreshTypesForTest(syncer::ModelTypeSet types) = 0; + + // See SyncManager::ClearServerData. + virtual void ClearServerData( + const syncer::SyncManager::ClearServerDataCallback& callback) = 0; + + // Notify the syncer that the cookie jar has changed. + // See SyncManager::OnCookieJarChanged. + virtual void OnCookieJarChanged(bool account_mismatch, bool empty_jar) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(SyncBackendHost); +}; + +} // namespace browser_sync + +#endif // COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_H_
diff --git a/components/sync/driver/glue/sync_backend_host_core.cc b/components/sync/driver/glue/sync_backend_host_core.cc new file mode 100644 index 0000000..e0710aa --- /dev/null +++ b/components/sync/driver/glue/sync_backend_host_core.cc
@@ -0,0 +1,732 @@ +// 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 "components/sync/driver/glue/sync_backend_host_core.h" + +#include <utility> + +#include "base/bind.h" +#include "base/files/file_util.h" +#include "base/location.h" +#include "base/single_thread_task_runner.h" +#include "components/data_use_measurement/core/data_use_user_data.h" +#include "components/invalidation/public/invalidation_util.h" +#include "components/invalidation/public/object_id_invalidation_map.h" +#include "components/sync/core/http_post_provider_factory.h" +#include "components/sync/core/internal_components_factory.h" +#include "components/sync/core/sync_manager.h" +#include "components/sync/core/sync_manager_factory.h" +#include "components/sync/driver/glue/sync_backend_registrar.h" +#include "components/sync/driver/invalidation_adapter.h" +#include "components/sync/driver/local_device_info_provider_impl.h" +#include "components/sync/engine/events/protocol_event.h" +#include "components/sync/sessions/commit_counters.h" +#include "components/sync/sessions/status_counters.h" +#include "components/sync/sessions/sync_session_snapshot.h" +#include "components/sync/sessions/update_counters.h" +#include "url/gurl.h" + +// Helper macros to log with the syncer thread name; useful when there +// are multiple syncers involved. + +#define SLOG(severity) LOG(severity) << name_ << ": " + +#define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": " + +static const int kSaveChangesIntervalSeconds = 10; + +namespace syncer { +class InternalComponentsFactory; +} // namespace syncer + +namespace net { +class URLFetcher; +} + +namespace { + +void BindFetcherToDataTracker(net::URLFetcher* fetcher) { + data_use_measurement::DataUseUserData::AttachToFetcher( + fetcher, data_use_measurement::DataUseUserData::SYNC); +} + +} // namespace + +namespace browser_sync { + +DoInitializeOptions::DoInitializeOptions( + base::MessageLoop* sync_loop, + SyncBackendRegistrar* registrar, + const std::vector<scoped_refptr<syncer::ModelSafeWorker>>& workers, + const scoped_refptr<syncer::ExtensionsActivity>& extensions_activity, + const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, + const GURL& service_url, + const std::string& sync_user_agent, + std::unique_ptr<syncer::HttpPostProviderFactory> http_bridge_factory, + const syncer::SyncCredentials& credentials, + const std::string& invalidator_client_id, + std::unique_ptr<syncer::SyncManagerFactory> sync_manager_factory, + bool delete_sync_data_folder, + const std::string& restored_key_for_bootstrapping, + const std::string& restored_keystore_key_for_bootstrapping, + std::unique_ptr<syncer::InternalComponentsFactory> + internal_components_factory, + const syncer::WeakHandle<syncer::UnrecoverableErrorHandler>& + unrecoverable_error_handler, + const base::Closure& report_unrecoverable_error_function, + std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> + saved_nigori_state, + const std::map<syncer::ModelType, int64_t>& invalidation_versions) + : sync_loop(sync_loop), + registrar(registrar), + workers(workers), + extensions_activity(extensions_activity), + event_handler(event_handler), + service_url(service_url), + sync_user_agent(sync_user_agent), + http_bridge_factory(std::move(http_bridge_factory)), + credentials(credentials), + invalidator_client_id(invalidator_client_id), + sync_manager_factory(std::move(sync_manager_factory)), + delete_sync_data_folder(delete_sync_data_folder), + restored_key_for_bootstrapping(restored_key_for_bootstrapping), + restored_keystore_key_for_bootstrapping( + restored_keystore_key_for_bootstrapping), + internal_components_factory(std::move(internal_components_factory)), + unrecoverable_error_handler(unrecoverable_error_handler), + report_unrecoverable_error_function(report_unrecoverable_error_function), + saved_nigori_state(std::move(saved_nigori_state)), + invalidation_versions(invalidation_versions) {} + +DoInitializeOptions::~DoInitializeOptions() {} + +DoConfigureSyncerTypes::DoConfigureSyncerTypes() {} + +DoConfigureSyncerTypes::DoConfigureSyncerTypes( + const DoConfigureSyncerTypes& other) = default; + +DoConfigureSyncerTypes::~DoConfigureSyncerTypes() {} + +SyncBackendHostCore::SyncBackendHostCore( + const std::string& name, + const base::FilePath& sync_data_folder_path, + bool has_sync_setup_completed, + const base::WeakPtr<SyncBackendHostImpl>& backend) + : name_(name), + sync_data_folder_path_(sync_data_folder_path), + host_(backend), + sync_loop_(NULL), + registrar_(NULL), + has_sync_setup_completed_(has_sync_setup_completed), + forward_protocol_events_(false), + forward_type_info_(false), + weak_ptr_factory_(this) { + DCHECK(backend.get()); +} + +SyncBackendHostCore::~SyncBackendHostCore() { + DCHECK(!sync_manager_.get()); +} + +void SyncBackendHostCore::OnSyncCycleCompleted( + const syncer::sessions::SyncSessionSnapshot& snapshot) { + if (!sync_loop_) + return; + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + + host_.Call(FROM_HERE, + &SyncBackendHostImpl::HandleSyncCycleCompletedOnFrontendLoop, + snapshot); +} + +void SyncBackendHostCore::DoRefreshTypes(syncer::ModelTypeSet types) { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + sync_manager_->RefreshTypes(types); +} + +void SyncBackendHostCore::OnInitializationComplete( + const syncer::WeakHandle<syncer::JsBackend>& js_backend, + const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& + debug_info_listener, + bool success, + const syncer::ModelTypeSet restored_types) { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + + if (!success) { + DoDestroySyncManager(syncer::STOP_SYNC); + host_.Call(FROM_HERE, + &SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop); + return; + } + + // Register for encryption related changes now. We have to do this before + // the initializing downloading control types or initializing the encryption + // handler in order to receive notifications triggered during encryption + // startup. + sync_manager_->GetEncryptionHandler()->AddObserver(this); + + // Sync manager initialization is complete, so we can schedule recurring + // SaveChanges. + sync_loop_->task_runner()->PostTask( + FROM_HERE, base::Bind(&SyncBackendHostCore::StartSavingChanges, + weak_ptr_factory_.GetWeakPtr())); + + // Hang on to these for a while longer. We're not ready to hand them back to + // the UI thread yet. + js_backend_ = js_backend; + debug_info_listener_ = debug_info_listener; + + // Before proceeding any further, we need to download the control types and + // purge any partial data (ie. data downloaded for a type that was on its way + // to being initially synced, but didn't quite make it.). The following + // configure cycle will take care of this. It depends on the registrar state + // which we initialize below to ensure that we don't perform any downloads if + // all control types have already completed their initial sync. + registrar_->SetInitialTypes(restored_types); + + syncer::ConfigureReason reason = + restored_types.Empty() ? syncer::CONFIGURE_REASON_NEW_CLIENT + : syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE; + + syncer::ModelTypeSet new_control_types = registrar_->ConfigureDataTypes( + syncer::ControlTypes(), syncer::ModelTypeSet()); + syncer::ModelSafeRoutingInfo routing_info; + registrar_->GetModelSafeRoutingInfo(&routing_info); + SDVLOG(1) << "Control Types " + << syncer::ModelTypeSetToString(new_control_types) + << " added; calling ConfigureSyncer"; + + syncer::ModelTypeSet types_to_purge = syncer::Difference( + syncer::ModelTypeSet::All(), GetRoutingInfoTypes(routing_info)); + + sync_manager_->ConfigureSyncer( + reason, new_control_types, types_to_purge, syncer::ModelTypeSet(), + syncer::ModelTypeSet(), routing_info, + base::Bind(&SyncBackendHostCore::DoInitialProcessControlTypes, + weak_ptr_factory_.GetWeakPtr()), + base::Closure()); +} + +void SyncBackendHostCore::OnConnectionStatusChange( + syncer::ConnectionStatus status) { + if (!sync_loop_) + return; + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + host_.Call(FROM_HERE, + &SyncBackendHostImpl::HandleConnectionStatusChangeOnFrontendLoop, + status); +} + +void SyncBackendHostCore::OnPassphraseRequired( + syncer::PassphraseRequiredReason reason, + const sync_pb::EncryptedData& pending_keys) { + if (!sync_loop_) + return; + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + host_.Call(FROM_HERE, &SyncBackendHostImpl::NotifyPassphraseRequired, reason, + pending_keys); +} + +void SyncBackendHostCore::OnPassphraseAccepted() { + if (!sync_loop_) + return; + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + host_.Call(FROM_HERE, &SyncBackendHostImpl::NotifyPassphraseAccepted); +} + +void SyncBackendHostCore::OnBootstrapTokenUpdated( + const std::string& bootstrap_token, + syncer::BootstrapTokenType type) { + if (!sync_loop_) + return; + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + host_.Call(FROM_HERE, &SyncBackendHostImpl::PersistEncryptionBootstrapToken, + bootstrap_token, type); +} + +void SyncBackendHostCore::OnEncryptedTypesChanged( + syncer::ModelTypeSet encrypted_types, + bool encrypt_everything) { + if (!sync_loop_) + return; + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + // NOTE: We're in a transaction. + host_.Call(FROM_HERE, &SyncBackendHostImpl::NotifyEncryptedTypesChanged, + encrypted_types, encrypt_everything); +} + +void SyncBackendHostCore::OnEncryptionComplete() { + if (!sync_loop_) + return; + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + // NOTE: We're in a transaction. + host_.Call(FROM_HERE, &SyncBackendHostImpl::NotifyEncryptionComplete); +} + +void SyncBackendHostCore::OnCryptographerStateChanged( + syncer::Cryptographer* cryptographer) { + // Do nothing. +} + +void SyncBackendHostCore::OnPassphraseTypeChanged(syncer::PassphraseType type, + base::Time passphrase_time) { + host_.Call(FROM_HERE, + &SyncBackendHostImpl::HandlePassphraseTypeChangedOnFrontendLoop, + type, passphrase_time); +} + +void SyncBackendHostCore::OnLocalSetPassphraseEncryption( + const syncer::SyncEncryptionHandler::NigoriState& nigori_state) { + host_.Call( + FROM_HERE, + &SyncBackendHostImpl::HandleLocalSetPassphraseEncryptionOnFrontendLoop, + nigori_state); +} + +void SyncBackendHostCore::OnCommitCountersUpdated( + syncer::ModelType type, + const syncer::CommitCounters& counters) { + host_.Call( + FROM_HERE, + &SyncBackendHostImpl::HandleDirectoryCommitCountersUpdatedOnFrontendLoop, + type, counters); +} + +void SyncBackendHostCore::OnUpdateCountersUpdated( + syncer::ModelType type, + const syncer::UpdateCounters& counters) { + host_.Call( + FROM_HERE, + &SyncBackendHostImpl::HandleDirectoryUpdateCountersUpdatedOnFrontendLoop, + type, counters); +} + +void SyncBackendHostCore::OnStatusCountersUpdated( + syncer::ModelType type, + const syncer::StatusCounters& counters) { + host_.Call( + FROM_HERE, + &SyncBackendHostImpl::HandleDirectoryStatusCountersUpdatedOnFrontendLoop, + type, counters); +} + +void SyncBackendHostCore::OnActionableError( + const syncer::SyncProtocolError& sync_error) { + if (!sync_loop_) + return; + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + host_.Call(FROM_HERE, + &SyncBackendHostImpl::HandleActionableErrorEventOnFrontendLoop, + sync_error); +} + +void SyncBackendHostCore::OnMigrationRequested(syncer::ModelTypeSet types) { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + host_.Call(FROM_HERE, + &SyncBackendHostImpl::HandleMigrationRequestedOnFrontendLoop, + types); +} + +void SyncBackendHostCore::OnProtocolEvent(const syncer::ProtocolEvent& event) { + // TODO(rlarocque): Find a way to pass event_clone as a scoped_ptr. + if (forward_protocol_events_) { + std::unique_ptr<syncer::ProtocolEvent> event_clone(event.Clone()); + host_.Call(FROM_HERE, + &SyncBackendHostImpl::HandleProtocolEventOnFrontendLoop, + event_clone.release()); + } +} + +void SyncBackendHostCore::DoOnInvalidatorStateChange( + syncer::InvalidatorState state) { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + sync_manager_->SetInvalidatorEnabled(state == syncer::INVALIDATIONS_ENABLED); +} + +void SyncBackendHostCore::DoOnIncomingInvalidation( + const syncer::ObjectIdInvalidationMap& invalidation_map) { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + + syncer::ObjectIdSet ids = invalidation_map.GetObjectIds(); + for (const invalidation::ObjectId& object_id : ids) { + syncer::ModelType type; + if (!NotificationTypeToRealModelType(object_id.name(), &type)) { + DLOG(WARNING) << "Notification has invalid id: " + << syncer::ObjectIdToString(object_id); + } else { + syncer::SingleObjectInvalidationSet invalidation_set = + invalidation_map.ForObject(object_id); + for (syncer::Invalidation invalidation : invalidation_set) { + auto last_invalidation = last_invalidation_versions_.find(type); + if (!invalidation.is_unknown_version() && + last_invalidation != last_invalidation_versions_.end() && + invalidation.version() <= last_invalidation->second) { + DVLOG(1) << "Ignoring redundant invalidation for " + << syncer::ModelTypeToString(type) << " with version " + << invalidation.version() << ", last seen version was " + << last_invalidation->second; + continue; + } + std::unique_ptr<syncer::InvalidationInterface> inv_adapter( + new InvalidationAdapter(invalidation)); + sync_manager_->OnIncomingInvalidation(type, std::move(inv_adapter)); + if (!invalidation.is_unknown_version()) + last_invalidation_versions_[type] = invalidation.version(); + } + } + } + + host_.Call(FROM_HERE, &SyncBackendHostImpl::UpdateInvalidationVersions, + last_invalidation_versions_); +} + +void SyncBackendHostCore::DoInitialize( + std::unique_ptr<DoInitializeOptions> options) { + DCHECK(!sync_loop_); + sync_loop_ = options->sync_loop; + DCHECK(sync_loop_); + + // Finish initializing the HttpBridgeFactory. We do this here because + // building the user agent may block on some platforms. + options->http_bridge_factory->Init(options->sync_user_agent, + base::Bind(&BindFetcherToDataTracker)); + + // Blow away the partial or corrupt sync data folder before doing any more + // initialization, if necessary. + if (options->delete_sync_data_folder) { + DeleteSyncDataFolder(); + } + + // Make sure that the directory exists before initializing the backend. + // If it already exists, this will do no harm. + if (!base::CreateDirectory(sync_data_folder_path_)) { + DLOG(FATAL) << "Sync Data directory creation failed."; + } + + // Load the previously persisted set of invalidation versions into memory. + last_invalidation_versions_ = options->invalidation_versions; + + DCHECK(!registrar_); + registrar_ = options->registrar; + DCHECK(registrar_); + + sync_manager_ = options->sync_manager_factory->CreateSyncManager(name_); + sync_manager_->AddObserver(this); + + syncer::SyncManager::InitArgs args; + args.database_location = sync_data_folder_path_; + args.event_handler = options->event_handler; + args.service_url = options->service_url; + args.post_factory = std::move(options->http_bridge_factory); + args.workers = options->workers; + args.extensions_activity = options->extensions_activity.get(); + args.change_delegate = options->registrar; // as SyncManager::ChangeDelegate + args.credentials = options->credentials; + args.invalidator_client_id = options->invalidator_client_id; + args.restored_key_for_bootstrapping = options->restored_key_for_bootstrapping; + args.restored_keystore_key_for_bootstrapping = + options->restored_keystore_key_for_bootstrapping; + args.internal_components_factory = + std::move(options->internal_components_factory); + args.encryptor = &encryptor_; + args.unrecoverable_error_handler = options->unrecoverable_error_handler; + args.report_unrecoverable_error_function = + options->report_unrecoverable_error_function; + args.cancelation_signal = &stop_syncing_signal_; + args.saved_nigori_state = std::move(options->saved_nigori_state); + sync_manager_->Init(&args); +} + +void SyncBackendHostCore::DoUpdateCredentials( + const syncer::SyncCredentials& credentials) { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + // UpdateCredentials can be called during backend initialization, possibly + // when backend initialization has failed but hasn't notified the UI thread + // yet. In that case, the sync manager may have been destroyed on the sync + // thread before this task was executed, so we do nothing. + if (sync_manager_) { + sync_manager_->UpdateCredentials(credentials); + } +} + +void SyncBackendHostCore::DoStartSyncing( + const syncer::ModelSafeRoutingInfo& routing_info, + base::Time last_poll_time) { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + sync_manager_->StartSyncingNormally(routing_info, last_poll_time); +} + +void SyncBackendHostCore::DoSetEncryptionPassphrase( + const std::string& passphrase, + bool is_explicit) { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + sync_manager_->GetEncryptionHandler()->SetEncryptionPassphrase(passphrase, + is_explicit); +} + +void SyncBackendHostCore::DoInitialProcessControlTypes() { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + + DVLOG(1) << "Initilalizing Control Types"; + + // Initialize encryption. + sync_manager_->GetEncryptionHandler()->Init(); + + // Note: experiments are currently handled via SBH::AddExperimentalTypes, + // which is called at the end of every sync cycle. + // TODO(zea): eventually add an experiment handler and initialize it here. + + if (!sync_manager_->GetUserShare()) { // NULL in some tests. + DVLOG(1) << "Skipping initialization of DeviceInfo"; + host_.Call(FROM_HERE, + &SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop); + return; + } + + if (!sync_manager_->InitialSyncEndedTypes().HasAll(syncer::ControlTypes())) { + LOG(ERROR) << "Failed to download control types"; + host_.Call(FROM_HERE, + &SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop); + return; + } + + host_.Call(FROM_HERE, + &SyncBackendHostImpl::HandleInitializationSuccessOnFrontendLoop, + js_backend_, debug_info_listener_, + base::Passed(sync_manager_->GetModelTypeConnectorProxy()), + sync_manager_->cache_guid()); + + js_backend_.Reset(); + debug_info_listener_.Reset(); +} + +void SyncBackendHostCore::DoSetDecryptionPassphrase( + const std::string& passphrase) { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + sync_manager_->GetEncryptionHandler()->SetDecryptionPassphrase(passphrase); +} + +void SyncBackendHostCore::DoEnableEncryptEverything() { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + sync_manager_->GetEncryptionHandler()->EnableEncryptEverything(); +} + +void SyncBackendHostCore::ShutdownOnUIThread() { + // This will cut short any blocking network tasks, cut short any in-progress + // sync cycles, and prevent the creation of new blocking network tasks and new + // sync cycles. If there was an in-progress network request, it would have + // had a reference to the RequestContextGetter. This reference will be + // dropped by the time this function returns. + // + // It is safe to call this even if Sync's backend classes have not been + // initialized yet. Those classes will receive the message when the sync + // thread finally getes around to constructing them. + stop_syncing_signal_.Signal(); + + // This will drop the HttpBridgeFactory's reference to the + // RequestContextGetter. Once this has been called, the HttpBridgeFactory can + // no longer be used to create new HttpBridge instances. We can get away with + // this because the stop_syncing_signal_ has already been signalled, which + // guarantees that the ServerConnectionManager will no longer attempt to + // create new connections. + release_request_context_signal_.Signal(); +} + +void SyncBackendHostCore::DoShutdown(syncer::ShutdownReason reason) { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + + DoDestroySyncManager(reason); + + registrar_ = NULL; + + if (reason == syncer::DISABLE_SYNC) + DeleteSyncDataFolder(); + + host_.Reset(); + weak_ptr_factory_.InvalidateWeakPtrs(); +} + +void SyncBackendHostCore::DoDestroySyncManager(syncer::ShutdownReason reason) { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + if (sync_manager_) { + DisableDirectoryTypeDebugInfoForwarding(); + save_changes_timer_.reset(); + sync_manager_->RemoveObserver(this); + sync_manager_->ShutdownOnSyncThread(reason); + sync_manager_.reset(); + } +} + +void SyncBackendHostCore::DoConfigureSyncer( + syncer::ConfigureReason reason, + const DoConfigureSyncerTypes& config_types, + const syncer::ModelSafeRoutingInfo routing_info, + const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& + ready_task, + const base::Closure& retry_callback) { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + DCHECK(!ready_task.is_null()); + DCHECK(!retry_callback.is_null()); + base::Closure chained_ready_task(base::Bind( + &SyncBackendHostCore::DoFinishConfigureDataTypes, + weak_ptr_factory_.GetWeakPtr(), config_types.to_download, ready_task)); + base::Closure chained_retry_task( + base::Bind(&SyncBackendHostCore::DoRetryConfiguration, + weak_ptr_factory_.GetWeakPtr(), retry_callback)); + sync_manager_->ConfigureSyncer(reason, config_types.to_download, + config_types.to_purge, config_types.to_journal, + config_types.to_unapply, routing_info, + chained_ready_task, chained_retry_task); +} + +void SyncBackendHostCore::DoFinishConfigureDataTypes( + syncer::ModelTypeSet types_to_config, + const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& + ready_task) { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + + // Update the enabled types for the bridge and sync manager. + syncer::ModelSafeRoutingInfo routing_info; + registrar_->GetModelSafeRoutingInfo(&routing_info); + syncer::ModelTypeSet enabled_types = GetRoutingInfoTypes(routing_info); + enabled_types.RemoveAll(syncer::ProxyTypes()); + + const syncer::ModelTypeSet failed_configuration_types = + Difference(types_to_config, sync_manager_->InitialSyncEndedTypes()); + const syncer::ModelTypeSet succeeded_configuration_types = + Difference(types_to_config, failed_configuration_types); + host_.Call(FROM_HERE, + &SyncBackendHostImpl::FinishConfigureDataTypesOnFrontendLoop, + enabled_types, succeeded_configuration_types, + failed_configuration_types, ready_task); +} + +void SyncBackendHostCore::DoRetryConfiguration( + const base::Closure& retry_callback) { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + host_.Call(FROM_HERE, &SyncBackendHostImpl::RetryConfigurationOnFrontendLoop, + retry_callback); +} + +void SyncBackendHostCore::SendBufferedProtocolEventsAndEnableForwarding() { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + forward_protocol_events_ = true; + + if (sync_manager_) { + // Grab our own copy of the buffered events. + // The buffer is not modified by this operation. + std::vector<syncer::ProtocolEvent*> buffered_events; + sync_manager_->GetBufferedProtocolEvents().release(&buffered_events); + + // Send them all over the fence to the host. + for (std::vector<syncer::ProtocolEvent*>::iterator it = + buffered_events.begin(); + it != buffered_events.end(); ++it) { + // TODO(rlarocque): Make it explicit that host_ takes ownership. + host_.Call(FROM_HERE, + &SyncBackendHostImpl::HandleProtocolEventOnFrontendLoop, *it); + } + } +} + +void SyncBackendHostCore::DisableProtocolEventForwarding() { + forward_protocol_events_ = false; +} + +void SyncBackendHostCore::EnableDirectoryTypeDebugInfoForwarding() { + DCHECK(sync_manager_); + + forward_type_info_ = true; + + if (!sync_manager_->HasDirectoryTypeDebugInfoObserver(this)) + sync_manager_->RegisterDirectoryTypeDebugInfoObserver(this); + sync_manager_->RequestEmitDebugInfo(); +} + +void SyncBackendHostCore::DisableDirectoryTypeDebugInfoForwarding() { + DCHECK(sync_manager_); + + if (!forward_type_info_) + return; + + forward_type_info_ = false; + + if (sync_manager_->HasDirectoryTypeDebugInfoObserver(this)) + sync_manager_->UnregisterDirectoryTypeDebugInfoObserver(this); +} + +void SyncBackendHostCore::DeleteSyncDataFolder() { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + if (base::DirectoryExists(sync_data_folder_path_)) { + if (!base::DeleteFile(sync_data_folder_path_, true)) + SLOG(DFATAL) << "Could not delete the Sync Data folder."; + } +} + +void SyncBackendHostCore::GetAllNodesForTypes( + syncer::ModelTypeSet types, + scoped_refptr<base::SequencedTaskRunner> task_runner, + base::Callback<void(const std::vector<syncer::ModelType>& type, + ScopedVector<base::ListValue>)> callback) { + std::vector<syncer::ModelType> types_vector; + ScopedVector<base::ListValue> node_lists; + + syncer::ModelSafeRoutingInfo routes; + registrar_->GetModelSafeRoutingInfo(&routes); + syncer::ModelTypeSet enabled_types = GetRoutingInfoTypes(routes); + + for (syncer::ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) { + types_vector.push_back(it.Get()); + if (!enabled_types.Has(it.Get())) { + node_lists.push_back(new base::ListValue()); + } else { + node_lists.push_back( + sync_manager_->GetAllNodesForType(it.Get()).release()); + } + } + + task_runner->PostTask( + FROM_HERE, base::Bind(callback, types_vector, base::Passed(&node_lists))); +} + +void SyncBackendHostCore::StartSavingChanges() { + // We may already be shut down. + if (!sync_loop_) + return; + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + DCHECK(!save_changes_timer_.get()); + save_changes_timer_.reset(new base::RepeatingTimer()); + save_changes_timer_->Start( + FROM_HERE, base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds), + this, &SyncBackendHostCore::SaveChanges); +} + +void SyncBackendHostCore::SaveChanges() { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + sync_manager_->SaveChanges(); +} + +void SyncBackendHostCore::DoClearServerData( + const syncer::SyncManager::ClearServerDataCallback& frontend_callback) { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + const syncer::SyncManager::ClearServerDataCallback callback = + base::Bind(&SyncBackendHostCore::ClearServerDataDone, + weak_ptr_factory_.GetWeakPtr(), frontend_callback); + sync_manager_->ClearServerData(callback); +} + +void SyncBackendHostCore::DoOnCookieJarChanged(bool account_mismatch, + bool empty_jar) { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + sync_manager_->OnCookieJarChanged(account_mismatch, empty_jar); +} + +void SyncBackendHostCore::ClearServerDataDone( + const base::Closure& frontend_callback) { + DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); + host_.Call(FROM_HERE, &SyncBackendHostImpl::ClearServerDataDoneOnFrontendLoop, + frontend_callback); +} + +} // namespace browser_sync
diff --git a/components/sync/driver/glue/sync_backend_host_core.h b/components/sync/driver/glue/sync_backend_host_core.h new file mode 100644 index 0000000..1fc7348 --- /dev/null +++ b/components/sync/driver/glue/sync_backend_host_core.h
@@ -0,0 +1,341 @@ +// 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 COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_CORE_H_ +#define COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_CORE_H_ + +#include <stdint.h> + +#include <map> +#include <string> +#include <vector> + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/timer/timer.h" +#include "components/invalidation/public/invalidation.h" +#include "components/sync/base/cancelation_signal.h" +#include "components/sync/core/shutdown_reason.h" +#include "components/sync/core/sync_encryption_handler.h" +#include "components/sync/driver/glue/sync_backend_host_impl.h" +#include "components/sync/driver/system_encryptor.h" +#include "components/sync/sessions/type_debug_info_observer.h" +#include "url/gurl.h" + +namespace browser_sync { + +class SyncBackendHostImpl; + +// Utility struct for holding initialization options. +struct DoInitializeOptions { + DoInitializeOptions( + base::MessageLoop* sync_loop, + SyncBackendRegistrar* registrar, + const std::vector<scoped_refptr<syncer::ModelSafeWorker>>& workers, + const scoped_refptr<syncer::ExtensionsActivity>& extensions_activity, + const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, + const GURL& service_url, + const std::string& sync_user_agent, + std::unique_ptr<syncer::HttpPostProviderFactory> http_bridge_factory, + const syncer::SyncCredentials& credentials, + const std::string& invalidator_client_id, + std::unique_ptr<syncer::SyncManagerFactory> sync_manager_factory, + bool delete_sync_data_folder, + const std::string& restored_key_for_bootstrapping, + const std::string& restored_keystore_key_for_bootstrapping, + std::unique_ptr<syncer::InternalComponentsFactory> + internal_components_factory, + const syncer::WeakHandle<syncer::UnrecoverableErrorHandler>& + unrecoverable_error_handler, + const base::Closure& report_unrecoverable_error_function, + std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> + saved_nigori_state, + const std::map<syncer::ModelType, int64_t>& invalidation_versions); + ~DoInitializeOptions(); + + base::MessageLoop* sync_loop; + SyncBackendRegistrar* registrar; + std::vector<scoped_refptr<syncer::ModelSafeWorker>> workers; + scoped_refptr<syncer::ExtensionsActivity> extensions_activity; + syncer::WeakHandle<syncer::JsEventHandler> event_handler; + GURL service_url; + std::string sync_user_agent; + // Overridden by tests. + std::unique_ptr<syncer::HttpPostProviderFactory> http_bridge_factory; + syncer::SyncCredentials credentials; + const std::string invalidator_client_id; + std::unique_ptr<syncer::SyncManagerFactory> sync_manager_factory; + std::string lsid; + bool delete_sync_data_folder; + std::string restored_key_for_bootstrapping; + std::string restored_keystore_key_for_bootstrapping; + std::unique_ptr<syncer::InternalComponentsFactory> + internal_components_factory; + const syncer::WeakHandle<syncer::UnrecoverableErrorHandler> + unrecoverable_error_handler; + base::Closure report_unrecoverable_error_function; + std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> + saved_nigori_state; + const std::map<syncer::ModelType, int64_t> invalidation_versions; +}; + +// Helper struct to handle currying params to +// SyncBackendHost::Core::DoConfigureSyncer. +struct DoConfigureSyncerTypes { + DoConfigureSyncerTypes(); + DoConfigureSyncerTypes(const DoConfigureSyncerTypes& other); + ~DoConfigureSyncerTypes(); + syncer::ModelTypeSet to_download; + syncer::ModelTypeSet to_purge; + syncer::ModelTypeSet to_journal; + syncer::ModelTypeSet to_unapply; +}; + +class SyncBackendHostCore + : public base::RefCountedThreadSafe<SyncBackendHostCore>, + public syncer::SyncEncryptionHandler::Observer, + public syncer::SyncManager::Observer, + public syncer::TypeDebugInfoObserver { + public: + SyncBackendHostCore(const std::string& name, + const base::FilePath& sync_data_folder_path, + bool has_sync_setup_completed, + const base::WeakPtr<SyncBackendHostImpl>& backend); + + // SyncManager::Observer implementation. The Core just acts like an air + // traffic controller here, forwarding incoming messages to appropriate + // landing threads. + void OnSyncCycleCompleted( + const syncer::sessions::SyncSessionSnapshot& snapshot) override; + void OnInitializationComplete( + const syncer::WeakHandle<syncer::JsBackend>& js_backend, + const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& + debug_info_listener, + bool success, + syncer::ModelTypeSet restored_types) override; + void OnConnectionStatusChange(syncer::ConnectionStatus status) override; + void OnActionableError(const syncer::SyncProtocolError& sync_error) override; + void OnMigrationRequested(syncer::ModelTypeSet types) override; + void OnProtocolEvent(const syncer::ProtocolEvent& event) override; + + // SyncEncryptionHandler::Observer implementation. + void OnPassphraseRequired( + syncer::PassphraseRequiredReason reason, + const sync_pb::EncryptedData& pending_keys) override; + void OnPassphraseAccepted() override; + void OnBootstrapTokenUpdated(const std::string& bootstrap_token, + syncer::BootstrapTokenType type) override; + void OnEncryptedTypesChanged(syncer::ModelTypeSet encrypted_types, + bool encrypt_everything) override; + void OnEncryptionComplete() override; + void OnCryptographerStateChanged( + syncer::Cryptographer* cryptographer) override; + void OnPassphraseTypeChanged(syncer::PassphraseType type, + base::Time passphrase_time) override; + void OnLocalSetPassphraseEncryption( + const syncer::SyncEncryptionHandler::NigoriState& nigori_state) override; + + // TypeDebugInfoObserver implementation + void OnCommitCountersUpdated(syncer::ModelType type, + const syncer::CommitCounters& counters) override; + void OnUpdateCountersUpdated(syncer::ModelType type, + const syncer::UpdateCounters& counters) override; + void OnStatusCountersUpdated(syncer::ModelType type, + const syncer::StatusCounters& counters) override; + + // Forwards an invalidation state change to the sync manager. + void DoOnInvalidatorStateChange(syncer::InvalidatorState state); + + // Forwards an invalidation to the sync manager. + void DoOnIncomingInvalidation( + const syncer::ObjectIdInvalidationMap& invalidation_map); + + // Note: + // + // The Do* methods are the various entry points from our + // SyncBackendHost. They are all called on the sync thread to + // actually perform synchronous (and potentially blocking) syncapi + // operations. + // + // Called to perform initialization of the syncapi on behalf of + // SyncBackendHost::Initialize. + void DoInitialize(std::unique_ptr<DoInitializeOptions> options); + + // Called to perform credential update on behalf of + // SyncBackendHost::UpdateCredentials. + void DoUpdateCredentials(const syncer::SyncCredentials& credentials); + + // Called to tell the syncapi to start syncing (generally after + // initialization and authentication). + void DoStartSyncing(const syncer::ModelSafeRoutingInfo& routing_info, + base::Time last_poll_time); + + // Called to set the passphrase for encryption. + void DoSetEncryptionPassphrase(const std::string& passphrase, + bool is_explicit); + + // Called to decrypt the pending keys. + void DoSetDecryptionPassphrase(const std::string& passphrase); + + // Called to turn on encryption of all sync data as well as + // reencrypt everything. + void DoEnableEncryptEverything(); + + // Ask the syncer to check for updates for the specified types. + void DoRefreshTypes(syncer::ModelTypeSet types); + + // Invoked if we failed to download the necessary control types at startup. + // Invokes SyncBackendHost::HandleControlTypesDownloadRetry. + void OnControlTypesDownloadRetry(); + + // Called to perform tasks which require the control data to be downloaded. + // This includes refreshing encryption, etc. + void DoInitialProcessControlTypes(); + + // The shutdown order is a bit complicated: + // 1) Call ShutdownOnUIThread() from |frontend_loop_| to request sync manager + // to stop as soon as possible. + // 2) Post DoShutdown() to sync loop to clean up backend state, save + // directory and destroy sync manager. + void ShutdownOnUIThread(); + void DoShutdown(syncer::ShutdownReason reason); + void DoDestroySyncManager(syncer::ShutdownReason reason); + + // Configuration methods that must execute on sync loop. + void DoConfigureSyncer( + syncer::ConfigureReason reason, + const DoConfigureSyncerTypes& config_types, + const syncer::ModelSafeRoutingInfo routing_info, + const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& + ready_task, + const base::Closure& retry_callback); + void DoFinishConfigureDataTypes( + syncer::ModelTypeSet types_to_config, + const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& + ready_task); + void DoRetryConfiguration(const base::Closure& retry_callback); + + // Set the base request context to use when making HTTP calls. + // This method will add a reference to the context to persist it + // on the IO thread. Must be removed from IO thread. + + syncer::SyncManager* sync_manager() { return sync_manager_.get(); } + + void SendBufferedProtocolEventsAndEnableForwarding(); + void DisableProtocolEventForwarding(); + + // Enables the forwarding of directory type debug counters to the + // SyncBackendHost. Also requests that updates to all counters be + // emitted right away to initialize any new listeners' states. + void EnableDirectoryTypeDebugInfoForwarding(); + + // Disables forwarding of directory type debug counters. + void DisableDirectoryTypeDebugInfoForwarding(); + + // Delete the sync data folder to cleanup backend data. Happens the first + // time sync is enabled for a user (to prevent accidentally reusing old + // sync databases), as well as shutdown when you're no longer syncing. + void DeleteSyncDataFolder(); + + // We expose this member because it's required in the construction of the + // HttpBridgeFactory. + syncer::CancelationSignal* GetRequestContextCancelationSignal() { + return &release_request_context_signal_; + } + + void GetAllNodesForTypes( + syncer::ModelTypeSet types, + scoped_refptr<base::SequencedTaskRunner> task_runner, + base::Callback<void(const std::vector<syncer::ModelType>& type, + ScopedVector<base::ListValue>)> callback); + + // Tell the sync manager to persist its state by writing to disk. + // Called on the sync thread, both by a timer and, on Android, when the + // application is backgrounded. + void SaveChanges(); + + void DoClearServerData( + const syncer::SyncManager::ClearServerDataCallback& frontend_callback); + + // Notify the syncer that the cookie jar has changed. + void DoOnCookieJarChanged(bool account_mismatch, bool empty_jar); + + private: + friend class base::RefCountedThreadSafe<SyncBackendHostCore>; + friend class SyncBackendHostForProfileSyncTest; + + ~SyncBackendHostCore() override; + + // Invoked when initialization of syncapi is complete and we can start + // our timer. + // This must be called from the thread on which SaveChanges is intended to + // be run on; the host's |registrar_->sync_thread()|. + void StartSavingChanges(); + + void ClearServerDataDone(const base::Closure& frontend_callback); + + // Name used for debugging. + const std::string name_; + + // Path of the folder that stores the sync data files. + const base::FilePath sync_data_folder_path_; + + // Our parent SyncBackendHost. + syncer::WeakHandle<SyncBackendHostImpl> host_; + + // The loop where all the sync backend operations happen. + // Non-NULL only between calls to DoInitialize() and ~Core(). + base::MessageLoop* sync_loop_; + + // Our parent's registrar (not owned). Non-NULL only between + // calls to DoInitialize() and DoShutdown(). + SyncBackendRegistrar* registrar_; + + // The timer used to periodically call SaveChanges. + std::unique_ptr<base::RepeatingTimer> save_changes_timer_; + + // Our encryptor, which uses Chrome's encryption functions. + sync_driver::SystemEncryptor encryptor_; + + // The top-level syncapi entry point. Lives on the sync thread. + std::unique_ptr<syncer::SyncManager> sync_manager_; + + // Temporary holder of sync manager's initialization results. Set by + // OnInitializeComplete, and consumed when we pass it via OnBackendInitialized + // in the final state of HandleInitializationSuccessOnFrontendLoop. + syncer::WeakHandle<syncer::JsBackend> js_backend_; + syncer::WeakHandle<syncer::DataTypeDebugInfoListener> debug_info_listener_; + + // These signals allow us to send requests to shut down the HttpBridgeFactory + // and ServerConnectionManager without having to wait for those classes to + // finish initializing first. + // + // See comments in SyncBackendHostCore::ShutdownOnUIThread() for more details. + syncer::CancelationSignal release_request_context_signal_; + syncer::CancelationSignal stop_syncing_signal_; + + // Matches the value of SyncPref's IsFirstSetupComplete() flag at init time. + // Should not be used for anything except for UMAs and logging. + const bool has_sync_setup_completed_; + + // Set when we've been asked to forward sync protocol events to the frontend. + bool forward_protocol_events_; + + // Set when the forwarding of per-type debug counters is enabled. + bool forward_type_info_; + + // A map of data type -> invalidation version to track the most recently + // received invalidation version for each type. + // This allows dropping any invalidations with versions older than those + // most recently received for that data type. + std::map<syncer::ModelType, int64_t> last_invalidation_versions_; + + base::WeakPtrFactory<SyncBackendHostCore> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(SyncBackendHostCore); +}; + +} // namespace browser_sync + +#endif // COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_CORE_H_
diff --git a/components/sync/driver/glue/sync_backend_host_impl.cc b/components/sync/driver/glue/sync_backend_host_impl.cc new file mode 100644 index 0000000..c53242be --- /dev/null +++ b/components/sync/driver/glue/sync_backend_host_impl.cc
@@ -0,0 +1,859 @@ +// 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 "components/sync/driver/glue/sync_backend_host_impl.h" + +#include <map> +#include <utility> +#include <vector> + +#include "base/command_line.h" +#include "base/feature_list.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/invalidation/public/invalidation_service.h" +#include "components/invalidation/public/object_id_invalidation_map.h" +#include "components/signin/core/browser/signin_client.h" +#include "components/sync/base/experiments.h" +#include "components/sync/base/sync_string_conversions.h" +#include "components/sync/core/activation_context.h" +#include "components/sync/core/base_transaction.h" +#include "components/sync/core/http_bridge.h" +#include "components/sync/core/internal_components_factory.h" +#include "components/sync/core/internal_components_factory_impl.h" +#include "components/sync/core/sync_manager.h" +#include "components/sync/core/sync_manager_factory.h" +#include "components/sync/driver/glue/sync_backend_host_core.h" +#include "components/sync/driver/glue/sync_backend_registrar.h" +#include "components/sync/driver/invalidation_helper.h" +#include "components/sync/driver/sync_client.h" +#include "components/sync/driver/sync_driver_switches.h" +#include "components/sync/driver/sync_frontend.h" +#include "components/sync/driver/sync_prefs.h" +#include "components/sync/engine/events/protocol_event.h" + +// Helper macros to log with the syncer thread name; useful when there +// are multiple syncers involved. + +#define SLOG(severity) LOG(severity) << name_ << ": " + +#define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": " + +using syncer::InternalComponentsFactory; + +namespace browser_sync { + +SyncBackendHostImpl::SyncBackendHostImpl( + const std::string& name, + sync_driver::SyncClient* sync_client, + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + invalidation::InvalidationService* invalidator, + const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs, + const base::FilePath& sync_folder) + : frontend_task_runner_(base::ThreadTaskRunnerHandle::Get()), + sync_client_(sync_client), + ui_thread_(ui_thread), + name_(name), + initialized_(false), + sync_prefs_(sync_prefs), + frontend_(NULL), + cached_passphrase_type_(syncer::IMPLICIT_PASSPHRASE), + invalidator_(invalidator), + invalidation_handler_registered_(false), + weak_ptr_factory_(this) { + core_ = new SyncBackendHostCore(name_, sync_folder, + sync_prefs_->IsFirstSetupComplete(), + weak_ptr_factory_.GetWeakPtr()); +} + +SyncBackendHostImpl::~SyncBackendHostImpl() { + DCHECK(!core_.get() && !frontend_) << "Must call Shutdown before destructor."; + DCHECK(!registrar_.get()); +} + +void SyncBackendHostImpl::Initialize( + sync_driver::SyncFrontend* frontend, + std::unique_ptr<base::Thread> sync_thread, + const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, + const scoped_refptr<base::SingleThreadTaskRunner>& file_thread, + const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, + const GURL& sync_service_url, + const std::string& sync_user_agent, + const syncer::SyncCredentials& credentials, + bool delete_sync_data_folder, + std::unique_ptr<syncer::SyncManagerFactory> sync_manager_factory, + const syncer::WeakHandle<syncer::UnrecoverableErrorHandler>& + unrecoverable_error_handler, + const base::Closure& report_unrecoverable_error_function, + const HttpPostProviderFactoryGetter& http_post_provider_factory_getter, + std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> + saved_nigori_state) { + registrar_.reset(new browser_sync::SyncBackendRegistrar( + name_, sync_client_, std::move(sync_thread), ui_thread_, db_thread, + file_thread)); + CHECK(registrar_->sync_thread()); + + frontend_ = frontend; + DCHECK(frontend); + + std::vector<scoped_refptr<syncer::ModelSafeWorker>> workers; + registrar_->GetWorkers(&workers); + + InternalComponentsFactory::Switches factory_switches = { + InternalComponentsFactory::ENCRYPTION_KEYSTORE, + InternalComponentsFactory::BACKOFF_NORMAL}; + + base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); + if (cl->HasSwitch(switches::kSyncShortInitialRetryOverride)) { + factory_switches.backoff_override = + InternalComponentsFactory::BACKOFF_SHORT_INITIAL_RETRY_OVERRIDE; + } + if (cl->HasSwitch(switches::kSyncEnableGetUpdateAvoidance)) { + factory_switches.pre_commit_updates_policy = + InternalComponentsFactory::FORCE_ENABLE_PRE_COMMIT_UPDATE_AVOIDANCE; + } + + std::map<syncer::ModelType, int64_t> invalidation_versions; + sync_prefs_->GetInvalidationVersions(&invalidation_versions); + + std::unique_ptr<DoInitializeOptions> init_opts(new DoInitializeOptions( + registrar_->sync_thread()->message_loop(), registrar_.get(), workers, + sync_client_->GetExtensionsActivity(), event_handler, sync_service_url, + sync_user_agent, http_post_provider_factory_getter.Run( + core_->GetRequestContextCancelationSignal()), + credentials, invalidator_ ? invalidator_->GetInvalidatorClientId() : "", + std::move(sync_manager_factory), delete_sync_data_folder, + sync_prefs_->GetEncryptionBootstrapToken(), + sync_prefs_->GetKeystoreEncryptionBootstrapToken(), + std::unique_ptr<InternalComponentsFactory>( + new syncer::InternalComponentsFactoryImpl(factory_switches)), + unrecoverable_error_handler, report_unrecoverable_error_function, + std::move(saved_nigori_state), invalidation_versions)); + InitCore(std::move(init_opts)); +} + +void SyncBackendHostImpl::TriggerRefresh(const syncer::ModelTypeSet& types) { + DCHECK(ui_thread_->BelongsToCurrentThread()); + registrar_->sync_thread()->task_runner()->PostTask( + FROM_HERE, + base::Bind(&SyncBackendHostCore::DoRefreshTypes, core_.get(), types)); +} + +void SyncBackendHostImpl::UpdateCredentials( + const syncer::SyncCredentials& credentials) { + DCHECK(registrar_->sync_thread()->IsRunning()); + registrar_->sync_thread()->task_runner()->PostTask( + FROM_HERE, base::Bind(&SyncBackendHostCore::DoUpdateCredentials, + core_.get(), credentials)); +} + +void SyncBackendHostImpl::StartSyncingWithServer() { + SDVLOG(1) << "SyncBackendHostImpl::StartSyncingWithServer called."; + + syncer::ModelSafeRoutingInfo routing_info; + registrar_->GetModelSafeRoutingInfo(&routing_info); + + registrar_->sync_thread()->task_runner()->PostTask( + FROM_HERE, base::Bind(&SyncBackendHostCore::DoStartSyncing, core_.get(), + routing_info, sync_prefs_->GetLastPollTime())); +} + +void SyncBackendHostImpl::SetEncryptionPassphrase(const std::string& passphrase, + bool is_explicit) { + DCHECK(registrar_->sync_thread()->IsRunning()); + if (!IsNigoriEnabled()) { + NOTREACHED() << "SetEncryptionPassphrase must never be called when nigori" + " is disabled."; + return; + } + + // We should never be called with an empty passphrase. + DCHECK(!passphrase.empty()); + + // This should only be called by the frontend. + DCHECK(frontend_task_runner_->BelongsToCurrentThread()); + + // SetEncryptionPassphrase should never be called if we are currently + // encrypted with an explicit passphrase. + DCHECK(cached_passphrase_type_ == syncer::KEYSTORE_PASSPHRASE || + cached_passphrase_type_ == syncer::IMPLICIT_PASSPHRASE); + + // Post an encryption task on the syncer thread. + registrar_->sync_thread()->task_runner()->PostTask( + FROM_HERE, base::Bind(&SyncBackendHostCore::DoSetEncryptionPassphrase, + core_.get(), passphrase, is_explicit)); +} + +bool SyncBackendHostImpl::SetDecryptionPassphrase( + const std::string& passphrase) { + if (!IsNigoriEnabled()) { + NOTREACHED() << "SetDecryptionPassphrase must never be called when nigori" + " is disabled."; + return false; + } + + // We should never be called with an empty passphrase. + DCHECK(!passphrase.empty()); + + // This should only be called by the frontend. + DCHECK(frontend_task_runner_->BelongsToCurrentThread()); + + // This should only be called when we have cached pending keys. + DCHECK(cached_pending_keys_.has_blob()); + + // Check the passphrase that was provided against our local cache of the + // cryptographer's pending keys. If this was unsuccessful, the UI layer can + // immediately call OnPassphraseRequired without showing the user a spinner. + if (!CheckPassphraseAgainstCachedPendingKeys(passphrase)) + return false; + + // Post a decryption task on the syncer thread. + registrar_->sync_thread()->task_runner()->PostTask( + FROM_HERE, base::Bind(&SyncBackendHostCore::DoSetDecryptionPassphrase, + core_.get(), passphrase)); + + // Since we were able to decrypt the cached pending keys with the passphrase + // provided, we immediately alert the UI layer that the passphrase was + // accepted. This will avoid the situation where a user enters a passphrase, + // clicks OK, immediately reopens the advanced settings dialog, and gets an + // unnecessary prompt for a passphrase. + // Note: It is not guaranteed that the passphrase will be accepted by the + // syncer thread, since we could receive a new nigori node while the task is + // pending. This scenario is a valid race, and SetDecryptionPassphrase can + // trigger a new OnPassphraseRequired if it needs to. + NotifyPassphraseAccepted(); + return true; +} + +void SyncBackendHostImpl::StopSyncingForShutdown() { + DCHECK(frontend_task_runner_->BelongsToCurrentThread()); + + // Immediately stop sending messages to the frontend. + frontend_ = NULL; + + DCHECK(registrar_->sync_thread()->IsRunning()); + + registrar_->RequestWorkerStopOnUIThread(); + + core_->ShutdownOnUIThread(); +} + +std::unique_ptr<base::Thread> SyncBackendHostImpl::Shutdown( + syncer::ShutdownReason reason) { + // StopSyncingForShutdown() (which nulls out |frontend_|) should be + // called first. + DCHECK(!frontend_); + DCHECK(registrar_->sync_thread()->IsRunning()); + + bool sync_thread_claimed = (reason != syncer::BROWSER_SHUTDOWN); + + if (invalidation_handler_registered_) { + if (reason == syncer::DISABLE_SYNC) { + UnregisterInvalidationIds(); + } + invalidator_->UnregisterInvalidationHandler(this); + invalidator_ = NULL; + } + invalidation_handler_registered_ = false; + + model_type_connector_.reset(); + + // Shut down and destroy sync manager. + registrar_->sync_thread()->task_runner()->PostTask( + FROM_HERE, + base::Bind(&SyncBackendHostCore::DoShutdown, core_.get(), reason)); + core_ = NULL; + + // Worker cleanup. + SyncBackendRegistrar* detached_registrar = registrar_.release(); + detached_registrar->sync_thread()->task_runner()->PostTask( + FROM_HERE, base::Bind(&SyncBackendRegistrar::Shutdown, + base::Unretained(detached_registrar))); + + if (sync_thread_claimed) + return detached_registrar->ReleaseSyncThread(); + else + return std::unique_ptr<base::Thread>(); +} + +void SyncBackendHostImpl::UnregisterInvalidationIds() { + if (invalidation_handler_registered_) { + CHECK(invalidator_->UpdateRegisteredInvalidationIds(this, + syncer::ObjectIdSet())); + } +} + +syncer::ModelTypeSet SyncBackendHostImpl::ConfigureDataTypes( + syncer::ConfigureReason reason, + const DataTypeConfigStateMap& config_state_map, + const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& + ready_task, + const base::Callback<void()>& retry_callback) { + // Only one configure is allowed at a time. This is guaranteed by our + // callers. The SyncBackendHostImpl requests one configure as the backend is + // initializing and waits for it to complete. After initialization, all + // configurations will pass through the DataTypeManager, which is careful to + // never send a new configure request until the current request succeeds. + + // The SyncBackendRegistrar's routing info will be updated by adding the + // types_to_add to the list then removing types_to_remove. Any types which + // are not in either of those sets will remain untouched. + // + // Types which were not in the list previously are not fully downloaded, so we + // must ask the syncer to download them. Any newly supported datatypes will + // not have been in that routing info list, so they will be among the types + // downloaded if they are enabled. + // + // The SyncBackendRegistrar's state was initially derived from the types + // detected to have been downloaded in the database. Afterwards it is + // modified only by this function. We expect it to remain in sync with the + // backend because configuration requests are never aborted; they are retried + // until they succeed or the backend is shut down. + + syncer::ModelTypeSet disabled_types = + GetDataTypesInState(DISABLED, config_state_map); + syncer::ModelTypeSet fatal_types = + GetDataTypesInState(FATAL, config_state_map); + syncer::ModelTypeSet crypto_types = + GetDataTypesInState(CRYPTO, config_state_map); + syncer::ModelTypeSet unready_types = + GetDataTypesInState(UNREADY, config_state_map); + + disabled_types.PutAll(fatal_types); + disabled_types.PutAll(crypto_types); + disabled_types.PutAll(unready_types); + + syncer::ModelTypeSet active_types = + GetDataTypesInState(CONFIGURE_ACTIVE, config_state_map); + syncer::ModelTypeSet clean_first_types = + GetDataTypesInState(CONFIGURE_CLEAN, config_state_map); + syncer::ModelTypeSet types_to_download = registrar_->ConfigureDataTypes( + syncer::Union(active_types, clean_first_types), disabled_types); + types_to_download.PutAll(clean_first_types); + types_to_download.RemoveAll(syncer::ProxyTypes()); + if (!types_to_download.Empty()) + types_to_download.Put(syncer::NIGORI); + + // TODO(sync): crbug.com/137550. + // It's dangerous to configure types that have progress markers. Types with + // progress markers can trigger a MIGRATION_DONE response. We are not + // prepared to handle a migration during a configure, so we must ensure that + // all our types_to_download actually contain no data before we sync them. + // + // One common way to end up in this situation used to be types which + // downloaded some or all of their data but have not applied it yet. We avoid + // problems with those types by purging the data of any such partially synced + // types soon after we load the directory. + // + // Another possible scenario is that we have newly supported or newly enabled + // data types being downloaded here but the nigori type, which is always + // included in any GetUpdates request, requires migration. The server has + // code to detect this scenario based on the configure reason, the fact that + // the nigori type is the only requested type which requires migration, and + // that the requested types list includes at least one non-nigori type. It + // will not send a MIGRATION_DONE response in that case. We still need to be + // careful to not send progress markers for non-nigori types, though. If a + // non-nigori type in the request requires migration, a MIGRATION_DONE + // response will be sent. + + syncer::ModelSafeRoutingInfo routing_info; + registrar_->GetModelSafeRoutingInfo(&routing_info); + + syncer::ModelTypeSet current_types = registrar_->GetLastConfiguredTypes(); + syncer::ModelTypeSet types_to_purge = + syncer::Difference(syncer::ModelTypeSet::All(), current_types); + syncer::ModelTypeSet inactive_types = + GetDataTypesInState(CONFIGURE_INACTIVE, config_state_map); + types_to_purge.RemoveAll(inactive_types); + types_to_purge.RemoveAll(unready_types); + + // If a type has already been disabled and unapplied or journaled, it will + // not be part of the |types_to_purge| set, and therefore does not need + // to be acted on again. + fatal_types.RetainAll(types_to_purge); + syncer::ModelTypeSet unapply_types = + syncer::Union(crypto_types, clean_first_types); + unapply_types.RetainAll(types_to_purge); + + DCHECK(syncer::Intersection(current_types, fatal_types).Empty()); + DCHECK(syncer::Intersection(current_types, crypto_types).Empty()); + DCHECK(current_types.HasAll(types_to_download)); + + SDVLOG(1) << "Types " << syncer::ModelTypeSetToString(types_to_download) + << " added; calling DoConfigureSyncer"; + // Divide up the types into their corresponding actions (each is mutually + // exclusive): + // - Types which have just been added to the routing info (types_to_download): + // are downloaded. + // - Types which have encountered a fatal error (fatal_types) are deleted + // from the directory and journaled in the delete journal. + // - Types which have encountered a cryptographer error (crypto_types) are + // unapplied (local state is purged but sync state is not). + // - All other types not in the routing info (types just disabled) are deleted + // from the directory. + // - Everything else (enabled types and already disabled types) is not + // touched. + RequestConfigureSyncer(reason, types_to_download, types_to_purge, fatal_types, + unapply_types, inactive_types, routing_info, + ready_task, retry_callback); + + DCHECK(syncer::Intersection(active_types, types_to_purge).Empty()); + DCHECK(syncer::Intersection(active_types, fatal_types).Empty()); + DCHECK(syncer::Intersection(active_types, unapply_types).Empty()); + DCHECK(syncer::Intersection(active_types, inactive_types).Empty()); + return syncer::Difference(active_types, types_to_download); +} + +void SyncBackendHostImpl::EnableEncryptEverything() { + registrar_->sync_thread()->task_runner()->PostTask( + FROM_HERE, + base::Bind(&SyncBackendHostCore::DoEnableEncryptEverything, core_.get())); +} + +void SyncBackendHostImpl::ActivateDirectoryDataType( + syncer::ModelType type, + syncer::ModelSafeGroup group, + sync_driver::ChangeProcessor* change_processor) { + registrar_->ActivateDataType(type, group, change_processor, GetUserShare()); +} + +void SyncBackendHostImpl::DeactivateDirectoryDataType(syncer::ModelType type) { + registrar_->DeactivateDataType(type); +} + +void SyncBackendHostImpl::ActivateNonBlockingDataType( + syncer::ModelType type, + std::unique_ptr<syncer_v2::ActivationContext> activation_context) { + registrar_->RegisterNonBlockingType(type); + if (activation_context->data_type_state.initial_sync_done()) + registrar_->AddRestoredNonBlockingType(type); + model_type_connector_->ConnectType(type, std::move(activation_context)); +} + +void SyncBackendHostImpl::DeactivateNonBlockingDataType( + syncer::ModelType type) { + model_type_connector_->DisconnectType(type); +} + +syncer::UserShare* SyncBackendHostImpl::GetUserShare() const { + return core_->sync_manager()->GetUserShare(); +} + +SyncBackendHostImpl::Status SyncBackendHostImpl::GetDetailedStatus() { + DCHECK(initialized()); + return core_->sync_manager()->GetDetailedStatus(); +} + +syncer::sessions::SyncSessionSnapshot +SyncBackendHostImpl::GetLastSessionSnapshot() const { + return last_snapshot_; +} + +bool SyncBackendHostImpl::HasUnsyncedItems() const { + DCHECK(initialized()); + return core_->sync_manager()->HasUnsyncedItems(); +} + +bool SyncBackendHostImpl::IsNigoriEnabled() const { + return registrar_.get() && registrar_->IsNigoriEnabled(); +} + +syncer::PassphraseType SyncBackendHostImpl::GetPassphraseType() const { + return cached_passphrase_type_; +} + +base::Time SyncBackendHostImpl::GetExplicitPassphraseTime() const { + return cached_explicit_passphrase_time_; +} + +bool SyncBackendHostImpl::IsCryptographerReady( + const syncer::BaseTransaction* trans) const { + return initialized() && trans->GetCryptographer() && + trans->GetCryptographer()->is_ready(); +} + +void SyncBackendHostImpl::GetModelSafeRoutingInfo( + syncer::ModelSafeRoutingInfo* out) const { + if (initialized()) { + CHECK(registrar_.get()); + registrar_->GetModelSafeRoutingInfo(out); + } else { + NOTREACHED(); + } +} + +void SyncBackendHostImpl::FlushDirectory() const { + DCHECK(initialized()); + registrar_->sync_thread()->task_runner()->PostTask( + FROM_HERE, base::Bind(&SyncBackendHostCore::SaveChanges, core_)); +} + +void SyncBackendHostImpl::RequestBufferedProtocolEventsAndEnableForwarding() { + registrar_->sync_thread()->task_runner()->PostTask( + FROM_HERE, + base::Bind( + &SyncBackendHostCore::SendBufferedProtocolEventsAndEnableForwarding, + core_)); +} + +void SyncBackendHostImpl::DisableProtocolEventForwarding() { + registrar_->sync_thread()->task_runner()->PostTask( + FROM_HERE, + base::Bind(&SyncBackendHostCore::DisableProtocolEventForwarding, core_)); +} + +void SyncBackendHostImpl::EnableDirectoryTypeDebugInfoForwarding() { + DCHECK(initialized()); + registrar_->sync_thread()->task_runner()->PostTask( + FROM_HERE, + base::Bind(&SyncBackendHostCore::EnableDirectoryTypeDebugInfoForwarding, + core_)); +} + +void SyncBackendHostImpl::DisableDirectoryTypeDebugInfoForwarding() { + DCHECK(initialized()); + registrar_->sync_thread()->task_runner()->PostTask( + FROM_HERE, + base::Bind(&SyncBackendHostCore::DisableDirectoryTypeDebugInfoForwarding, + core_)); +} + +void SyncBackendHostImpl::GetAllNodesForTypes( + syncer::ModelTypeSet types, + base::Callback<void(const std::vector<syncer::ModelType>&, + ScopedVector<base::ListValue>)> callback) { + DCHECK(initialized()); + registrar_->sync_thread()->task_runner()->PostTask( + FROM_HERE, base::Bind(&SyncBackendHostCore::GetAllNodesForTypes, core_, + types, frontend_task_runner_, callback)); +} + +void SyncBackendHostImpl::InitCore( + std::unique_ptr<DoInitializeOptions> options) { + registrar_->sync_thread()->task_runner()->PostTask( + FROM_HERE, base::Bind(&SyncBackendHostCore::DoInitialize, core_.get(), + base::Passed(&options))); +} + +void SyncBackendHostImpl::RequestConfigureSyncer( + syncer::ConfigureReason reason, + syncer::ModelTypeSet to_download, + syncer::ModelTypeSet to_purge, + syncer::ModelTypeSet to_journal, + syncer::ModelTypeSet to_unapply, + syncer::ModelTypeSet to_ignore, + const syncer::ModelSafeRoutingInfo& routing_info, + const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& + ready_task, + const base::Closure& retry_callback) { + DoConfigureSyncerTypes config_types; + config_types.to_download = to_download; + config_types.to_purge = to_purge; + config_types.to_journal = to_journal; + config_types.to_unapply = to_unapply; + registrar_->sync_thread()->task_runner()->PostTask( + FROM_HERE, + base::Bind(&SyncBackendHostCore::DoConfigureSyncer, core_.get(), reason, + config_types, routing_info, ready_task, retry_callback)); +} + +void SyncBackendHostImpl::FinishConfigureDataTypesOnFrontendLoop( + const syncer::ModelTypeSet enabled_types, + const syncer::ModelTypeSet succeeded_configuration_types, + const syncer::ModelTypeSet failed_configuration_types, + const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& + ready_task) { + if (!frontend_) + return; + + if (invalidator_) { + CHECK(invalidator_->UpdateRegisteredInvalidationIds( + this, ModelTypeSetToObjectIdSet(enabled_types))); + } + + if (!ready_task.is_null()) + ready_task.Run(succeeded_configuration_types, failed_configuration_types); +} + +void SyncBackendHostImpl::AddExperimentalTypes() { + CHECK(initialized()); + syncer::Experiments experiments; + if (core_->sync_manager()->ReceivedExperiment(&experiments)) + frontend_->OnExperimentsChanged(experiments); +} + +void SyncBackendHostImpl::HandleInitializationSuccessOnFrontendLoop( + const syncer::WeakHandle<syncer::JsBackend> js_backend, + const syncer::WeakHandle<syncer::DataTypeDebugInfoListener> + debug_info_listener, + std::unique_ptr<syncer_v2::ModelTypeConnector> model_type_connector, + const std::string& cache_guid) { + DCHECK(frontend_task_runner_->BelongsToCurrentThread()); + + model_type_connector_ = std::move(model_type_connector); + + if (!frontend_) + return; + + initialized_ = true; + + if (invalidator_) { + invalidator_->RegisterInvalidationHandler(this); + invalidation_handler_registered_ = true; + + // Fake a state change to initialize the SyncManager's cached invalidator + // state. + OnInvalidatorStateChange(invalidator_->GetInvalidatorState()); + } + + // Now that we've downloaded the control types, we can see if there are any + // experimental types to enable. This should be done before we inform + // the frontend to ensure they're visible in the customize screen. + AddExperimentalTypes(); + frontend_->OnBackendInitialized(js_backend, debug_info_listener, cache_guid, + true); +} + +void SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop() { + DCHECK(frontend_task_runner_->BelongsToCurrentThread()); + if (!frontend_) + return; + + frontend_->OnBackendInitialized( + syncer::WeakHandle<syncer::JsBackend>(), + syncer::WeakHandle<syncer::DataTypeDebugInfoListener>(), "", false); +} + +void SyncBackendHostImpl::HandleSyncCycleCompletedOnFrontendLoop( + const syncer::sessions::SyncSessionSnapshot& snapshot) { + if (!frontend_) + return; + DCHECK(frontend_task_runner_->BelongsToCurrentThread()); + + last_snapshot_ = snapshot; + + SDVLOG(1) << "Got snapshot " << snapshot.ToString(); + + if (!snapshot.poll_finish_time().is_null()) + sync_prefs_->SetLastPollTime(snapshot.poll_finish_time()); + + // Process any changes to the datatypes we're syncing. + // TODO(sync): add support for removing types. + if (initialized()) + AddExperimentalTypes(); + + if (initialized()) + frontend_->OnSyncCycleCompleted(); +} + +void SyncBackendHostImpl::RetryConfigurationOnFrontendLoop( + const base::Closure& retry_callback) { + SDVLOG(1) << "Failed to complete configuration, informing of retry."; + retry_callback.Run(); +} + +void SyncBackendHostImpl::PersistEncryptionBootstrapToken( + const std::string& token, + syncer::BootstrapTokenType token_type) { + CHECK(sync_prefs_.get()); + if (token_type == syncer::PASSPHRASE_BOOTSTRAP_TOKEN) + sync_prefs_->SetEncryptionBootstrapToken(token); + else + sync_prefs_->SetKeystoreEncryptionBootstrapToken(token); +} + +void SyncBackendHostImpl::HandleActionableErrorEventOnFrontendLoop( + const syncer::SyncProtocolError& sync_error) { + if (!frontend_) + return; + DCHECK(frontend_task_runner_->BelongsToCurrentThread()); + frontend_->OnActionableError(sync_error); +} + +void SyncBackendHostImpl::HandleMigrationRequestedOnFrontendLoop( + syncer::ModelTypeSet types) { + if (!frontend_) + return; + DCHECK(frontend_task_runner_->BelongsToCurrentThread()); + frontend_->OnMigrationNeededForTypes(types); +} + +void SyncBackendHostImpl::OnInvalidatorStateChange( + syncer::InvalidatorState state) { + registrar_->sync_thread()->task_runner()->PostTask( + FROM_HERE, base::Bind(&SyncBackendHostCore::DoOnInvalidatorStateChange, + core_.get(), state)); +} + +void SyncBackendHostImpl::OnIncomingInvalidation( + const syncer::ObjectIdInvalidationMap& invalidation_map) { + registrar_->sync_thread()->task_runner()->PostTask( + FROM_HERE, base::Bind(&SyncBackendHostCore::DoOnIncomingInvalidation, + core_.get(), invalidation_map)); +} + +std::string SyncBackendHostImpl::GetOwnerName() const { + return "SyncBackendHostImpl"; +} + +bool SyncBackendHostImpl::CheckPassphraseAgainstCachedPendingKeys( + const std::string& passphrase) const { + DCHECK(cached_pending_keys_.has_blob()); + DCHECK(!passphrase.empty()); + syncer::Nigori nigori; + nigori.InitByDerivation("localhost", "dummy", passphrase); + std::string plaintext; + bool result = nigori.Decrypt(cached_pending_keys_.blob(), &plaintext); + DVLOG_IF(1, result) << "Passphrase failed to decrypt pending keys."; + return result; +} + +void SyncBackendHostImpl::NotifyPassphraseRequired( + syncer::PassphraseRequiredReason reason, + sync_pb::EncryptedData pending_keys) { + if (!frontend_) + return; + + DCHECK(frontend_task_runner_->BelongsToCurrentThread()); + + // Update our cache of the cryptographer's pending keys. + cached_pending_keys_ = pending_keys; + + frontend_->OnPassphraseRequired(reason, pending_keys); +} + +void SyncBackendHostImpl::NotifyPassphraseAccepted() { + if (!frontend_) + return; + + DCHECK(frontend_task_runner_->BelongsToCurrentThread()); + + // Clear our cache of the cryptographer's pending keys. + cached_pending_keys_.clear_blob(); + frontend_->OnPassphraseAccepted(); +} + +void SyncBackendHostImpl::NotifyEncryptedTypesChanged( + syncer::ModelTypeSet encrypted_types, + bool encrypt_everything) { + if (!frontend_) + return; + + DCHECK(frontend_task_runner_->BelongsToCurrentThread()); + frontend_->OnEncryptedTypesChanged(encrypted_types, encrypt_everything); +} + +void SyncBackendHostImpl::NotifyEncryptionComplete() { + if (!frontend_) + return; + + DCHECK(frontend_task_runner_->BelongsToCurrentThread()); + frontend_->OnEncryptionComplete(); +} + +void SyncBackendHostImpl::HandlePassphraseTypeChangedOnFrontendLoop( + syncer::PassphraseType type, + base::Time explicit_passphrase_time) { + DCHECK(frontend_task_runner_->BelongsToCurrentThread()); + DVLOG(1) << "Passphrase type changed to " + << syncer::PassphraseTypeToString(type); + cached_passphrase_type_ = type; + cached_explicit_passphrase_time_ = explicit_passphrase_time; +} + +void SyncBackendHostImpl::HandleLocalSetPassphraseEncryptionOnFrontendLoop( + const syncer::SyncEncryptionHandler::NigoriState& nigori_state) { + DCHECK(frontend_task_runner_->BelongsToCurrentThread()); + frontend_->OnLocalSetPassphraseEncryption(nigori_state); +} + +void SyncBackendHostImpl::HandleConnectionStatusChangeOnFrontendLoop( + syncer::ConnectionStatus status) { + if (!frontend_) + return; + + DCHECK(frontend_task_runner_->BelongsToCurrentThread()); + + DVLOG(1) << "Connection status changed: " + << syncer::ConnectionStatusToString(status); + frontend_->OnConnectionStatusChange(status); +} + +void SyncBackendHostImpl::HandleProtocolEventOnFrontendLoop( + syncer::ProtocolEvent* event) { + std::unique_ptr<syncer::ProtocolEvent> scoped_event(event); + if (!frontend_) + return; + frontend_->OnProtocolEvent(*scoped_event); +} + +void SyncBackendHostImpl::HandleDirectoryCommitCountersUpdatedOnFrontendLoop( + syncer::ModelType type, + const syncer::CommitCounters& counters) { + if (!frontend_) + return; + frontend_->OnDirectoryTypeCommitCounterUpdated(type, counters); +} + +void SyncBackendHostImpl::HandleDirectoryUpdateCountersUpdatedOnFrontendLoop( + syncer::ModelType type, + const syncer::UpdateCounters& counters) { + if (!frontend_) + return; + frontend_->OnDirectoryTypeUpdateCounterUpdated(type, counters); +} + +void SyncBackendHostImpl::HandleDirectoryStatusCountersUpdatedOnFrontendLoop( + syncer::ModelType type, + const syncer::StatusCounters& counters) { + if (!frontend_) + return; + frontend_->OnDirectoryTypeStatusCounterUpdated(type, counters); +} + +void SyncBackendHostImpl::UpdateInvalidationVersions( + const std::map<syncer::ModelType, int64_t>& invalidation_versions) { + sync_prefs_->UpdateInvalidationVersions(invalidation_versions); +} + +base::MessageLoop* SyncBackendHostImpl::GetSyncLoopForTesting() { + return registrar_->sync_thread()->message_loop(); +} + +void SyncBackendHostImpl::RefreshTypesForTest(syncer::ModelTypeSet types) { + DCHECK(ui_thread_->BelongsToCurrentThread()); + + registrar_->sync_thread()->task_runner()->PostTask( + FROM_HERE, + base::Bind(&SyncBackendHostCore::DoRefreshTypes, core_.get(), types)); +} + +void SyncBackendHostImpl::ClearServerData( + const syncer::SyncManager::ClearServerDataCallback& callback) { + DCHECK(ui_thread_->BelongsToCurrentThread()); + registrar_->sync_thread()->task_runner()->PostTask( + FROM_HERE, base::Bind(&SyncBackendHostCore::DoClearServerData, + core_.get(), callback)); +} + +void SyncBackendHostImpl::OnCookieJarChanged(bool account_mismatch, + bool empty_jar) { + DCHECK(ui_thread_->BelongsToCurrentThread()); + registrar_->sync_thread()->task_runner()->PostTask( + FROM_HERE, base::Bind(&SyncBackendHostCore::DoOnCookieJarChanged, + core_.get(), account_mismatch, empty_jar)); +} + +void SyncBackendHostImpl::ClearServerDataDoneOnFrontendLoop( + const syncer::SyncManager::ClearServerDataCallback& frontend_callback) { + DCHECK(ui_thread_->BelongsToCurrentThread()); + frontend_callback.Run(); +} + +} // namespace browser_sync + +#undef SDVLOG + +#undef SLOG
diff --git a/components/sync/driver/glue/sync_backend_host_impl.h b/components/sync/driver/glue/sync_backend_host_impl.h new file mode 100644 index 0000000..1345b9f --- /dev/null +++ b/components/sync/driver/glue/sync_backend_host_impl.h
@@ -0,0 +1,381 @@ +// 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 COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_IMPL_H_ +#define COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_IMPL_H_ + +#include <stdint.h> + +#include <map> +#include <memory> +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/single_thread_task_runner.h" +#include "base/threading/thread.h" +#include "components/invalidation/public/invalidation_handler.h" +#include "components/sync/base/extensions_activity.h" +#include "components/sync/base/model_type.h" +#include "components/sync/base/weak_handle.h" +#include "components/sync/core/configure_reason.h" +#include "components/sync/core/sync_manager.h" +#include "components/sync/driver/backend_data_type_configurer.h" +#include "components/sync/driver/glue/sync_backend_host.h" +#include "components/sync/protocol/encryption.pb.h" +#include "components/sync/protocol/sync_protocol_error.h" +#include "components/sync/sessions/sync_session_snapshot.h" +#include "components/sync/sessions/type_debug_info_observer.h" + +class GURL; + +namespace base { +class MessageLoop; +} + +namespace invalidation { +class InvalidationService; +} + +namespace syncer { +class SyncManagerFactory; +class UnrecoverableErrorHandler; +} + +namespace sync_driver { +class SyncClient; +class SyncPrefs; +} + +namespace browser_sync { + +class ChangeProcessor; +class SyncBackendHostCore; +class SyncBackendRegistrar; +struct DoInitializeOptions; + +// The only real implementation of the SyncBackendHost. See that interface's +// definition for documentation of public methods. +class SyncBackendHostImpl : public SyncBackendHost, + public syncer::InvalidationHandler { + public: + typedef syncer::SyncStatus Status; + + // Create a SyncBackendHost with a reference to the |frontend| that + // it serves and communicates to via the SyncFrontend interface (on + // the same thread it used to call the constructor). Must outlive + // |sync_prefs|. + SyncBackendHostImpl( + const std::string& name, + sync_driver::SyncClient* sync_client, + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + invalidation::InvalidationService* invalidator, + const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs, + const base::FilePath& sync_folder); + ~SyncBackendHostImpl() override; + + // SyncBackendHost implementation. + void Initialize( + sync_driver::SyncFrontend* frontend, + std::unique_ptr<base::Thread> sync_thread, + const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, + const scoped_refptr<base::SingleThreadTaskRunner>& file_thread, + const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, + const GURL& service_url, + const std::string& sync_user_agent, + const syncer::SyncCredentials& credentials, + bool delete_sync_data_folder, + std::unique_ptr<syncer::SyncManagerFactory> sync_manager_factory, + const syncer::WeakHandle<syncer::UnrecoverableErrorHandler>& + unrecoverable_error_handler, + const base::Closure& report_unrecoverable_error_function, + const HttpPostProviderFactoryGetter& http_post_provider_factory_getter, + std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> + saved_nigori_state) override; + void TriggerRefresh(const syncer::ModelTypeSet& types) override; + void UpdateCredentials(const syncer::SyncCredentials& credentials) override; + void StartSyncingWithServer() override; + void SetEncryptionPassphrase(const std::string& passphrase, + bool is_explicit) override; + bool SetDecryptionPassphrase(const std::string& passphrase) override + WARN_UNUSED_RESULT; + void StopSyncingForShutdown() override; + std::unique_ptr<base::Thread> Shutdown( + syncer::ShutdownReason reason) override; + void UnregisterInvalidationIds() override; + syncer::ModelTypeSet ConfigureDataTypes( + syncer::ConfigureReason reason, + const DataTypeConfigStateMap& config_state_map, + const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& + ready_task, + const base::Callback<void()>& retry_callback) override; + void ActivateDirectoryDataType( + syncer::ModelType type, + syncer::ModelSafeGroup group, + sync_driver::ChangeProcessor* change_processor) override; + void DeactivateDirectoryDataType(syncer::ModelType type) override; + void ActivateNonBlockingDataType( + syncer::ModelType type, + std::unique_ptr<syncer_v2::ActivationContext>) override; + void DeactivateNonBlockingDataType(syncer::ModelType type) override; + void EnableEncryptEverything() override; + syncer::UserShare* GetUserShare() const override; + Status GetDetailedStatus() override; + syncer::sessions::SyncSessionSnapshot GetLastSessionSnapshot() const override; + bool HasUnsyncedItems() const override; + bool IsNigoriEnabled() const override; + syncer::PassphraseType GetPassphraseType() const override; + base::Time GetExplicitPassphraseTime() const override; + bool IsCryptographerReady( + const syncer::BaseTransaction* trans) const override; + void GetModelSafeRoutingInfo( + syncer::ModelSafeRoutingInfo* out) const override; + void FlushDirectory() const override; + void RequestBufferedProtocolEventsAndEnableForwarding() override; + void DisableProtocolEventForwarding() override; + void EnableDirectoryTypeDebugInfoForwarding() override; + void DisableDirectoryTypeDebugInfoForwarding() override; + void GetAllNodesForTypes( + syncer::ModelTypeSet types, + base::Callback<void(const std::vector<syncer::ModelType>&, + ScopedVector<base::ListValue>)> type) override; + base::MessageLoop* GetSyncLoopForTesting() override; + void RefreshTypesForTest(syncer::ModelTypeSet types) override; + void ClearServerData( + const syncer::SyncManager::ClearServerDataCallback& callback) override; + void OnCookieJarChanged(bool account_mismatch, bool empty_jar) override; + + // InvalidationHandler implementation. + void OnInvalidatorStateChange(syncer::InvalidatorState state) override; + void OnIncomingInvalidation( + const syncer::ObjectIdInvalidationMap& invalidation_map) override; + std::string GetOwnerName() const override; + + protected: + // The types and functions below are protected so that test + // subclasses can use them. + + // Allows tests to perform alternate core initialization work. + virtual void InitCore(std::unique_ptr<DoInitializeOptions> options); + + // Request the syncer to reconfigure with the specfied params. + // Virtual for testing. + virtual void RequestConfigureSyncer( + syncer::ConfigureReason reason, + syncer::ModelTypeSet to_download, + syncer::ModelTypeSet to_purge, + syncer::ModelTypeSet to_journal, + syncer::ModelTypeSet to_unapply, + syncer::ModelTypeSet to_ignore, + const syncer::ModelSafeRoutingInfo& routing_info, + const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& + ready_task, + const base::Closure& retry_callback); + + // Called when the syncer has finished performing a configuration. + void FinishConfigureDataTypesOnFrontendLoop( + const syncer::ModelTypeSet enabled_types, + const syncer::ModelTypeSet succeeded_configuration_types, + const syncer::ModelTypeSet failed_configuration_types, + const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& + ready_task); + + // Reports backend initialization success. Includes some objects from sync + // manager initialization to be passed back to the UI thread. + // + // |model_type_connector| is our ModelTypeConnector, which is owned because in + // production it is a proxy object to the real ModelTypeConnector. + virtual void HandleInitializationSuccessOnFrontendLoop( + const syncer::WeakHandle<syncer::JsBackend> js_backend, + const syncer::WeakHandle<syncer::DataTypeDebugInfoListener> + debug_info_listener, + std::unique_ptr<syncer_v2::ModelTypeConnector> model_type_connector, + const std::string& cache_guid); + + // Forwards a ProtocolEvent to the frontend. Will not be called unless a + // call to SetForwardProtocolEvents() explicitly requested that we start + // forwarding these events. + void HandleProtocolEventOnFrontendLoop(syncer::ProtocolEvent* event); + + // Forwards a directory commit counter update to the frontend loop. Will not + // be called unless a call to EnableDirectoryTypeDebugInfoForwarding() + // explicitly requested that we start forwarding these events. + void HandleDirectoryCommitCountersUpdatedOnFrontendLoop( + syncer::ModelType type, + const syncer::CommitCounters& counters); + + // Forwards a directory update counter update to the frontend loop. Will not + // be called unless a call to EnableDirectoryTypeDebugInfoForwarding() + // explicitly requested that we start forwarding these events. + void HandleDirectoryUpdateCountersUpdatedOnFrontendLoop( + syncer::ModelType type, + const syncer::UpdateCounters& counters); + + // Forwards a directory status counter update to the frontend loop. Will not + // be called unless a call to EnableDirectoryTypeDebugInfoForwarding() + // explicitly requested that we start forwarding these events. + void HandleDirectoryStatusCountersUpdatedOnFrontendLoop( + syncer::ModelType type, + const syncer::StatusCounters& counters); + + // Overwrites the kSyncInvalidationVersions preference with the most recent + // set of invalidation versions for each type. + void UpdateInvalidationVersions( + const std::map<syncer::ModelType, int64_t>& invalidation_versions); + + sync_driver::SyncFrontend* frontend() { return frontend_; } + + private: + friend class SyncBackendHostCore; + + // Checks if we have received a notice to turn on experimental datatypes + // (via the nigori node) and informs the frontend if that is the case. + // Note: it is illegal to call this before the backend is initialized. + void AddExperimentalTypes(); + + // Handles backend initialization failure. + void HandleInitializationFailureOnFrontendLoop(); + + // Called from Core::OnSyncCycleCompleted to handle updating frontend + // thread components. + void HandleSyncCycleCompletedOnFrontendLoop( + const syncer::sessions::SyncSessionSnapshot& snapshot); + + // Called when the syncer failed to perform a configuration and will + // eventually retry. FinishingConfigurationOnFrontendLoop(..) will be called + // on successful completion. + void RetryConfigurationOnFrontendLoop(const base::Closure& retry_callback); + + // Helpers to persist a token that can be used to bootstrap sync encryption + // across browser restart to avoid requiring the user to re-enter their + // passphrase. |token| must be valid UTF-8 as we use the PrefService for + // storage. + void PersistEncryptionBootstrapToken(const std::string& token, + syncer::BootstrapTokenType token_type); + + // For convenience, checks if initialization state is INITIALIZED. + bool initialized() const { return initialized_; } + + // Let the front end handle the actionable error event. + void HandleActionableErrorEventOnFrontendLoop( + const syncer::SyncProtocolError& sync_error); + + // Handle a migration request. + void HandleMigrationRequestedOnFrontendLoop(const syncer::ModelTypeSet types); + + // Checks if |passphrase| can be used to decrypt the cryptographer's pending + // keys that were cached during NotifyPassphraseRequired. Returns true if + // decryption was successful. Returns false otherwise. Must be called with a + // non-empty pending keys cache. + bool CheckPassphraseAgainstCachedPendingKeys( + const std::string& passphrase) const; + + // Invoked when a passphrase is required to decrypt a set of Nigori keys, + // or for encrypting. |reason| denotes why the passphrase was required. + // |pending_keys| is a copy of the cryptographer's pending keys, that are + // cached by the frontend. If there are no pending keys, or if the passphrase + // required reason is REASON_ENCRYPTION, an empty EncryptedData object is + // passed. + void NotifyPassphraseRequired(syncer::PassphraseRequiredReason reason, + sync_pb::EncryptedData pending_keys); + + // Invoked when the passphrase provided by the user has been accepted. + void NotifyPassphraseAccepted(); + + // Invoked when the set of encrypted types or the encrypt + // everything flag changes. + void NotifyEncryptedTypesChanged(syncer::ModelTypeSet encrypted_types, + bool encrypt_everything); + + // Invoked when sync finishes encrypting new datatypes. + void NotifyEncryptionComplete(); + + // Invoked when the passphrase state has changed. Caches the passphrase state + // for later use on the UI thread. + // If |type| is FROZEN_IMPLICIT_PASSPHRASE or CUSTOM_PASSPHRASE, + // |explicit_passphrase_time| is the time at which that passphrase was set + // (if available). + void HandlePassphraseTypeChangedOnFrontendLoop( + syncer::PassphraseType type, + base::Time explicit_passphrase_time); + + void HandleLocalSetPassphraseEncryptionOnFrontendLoop( + const syncer::SyncEncryptionHandler::NigoriState& nigori_state); + + // Dispatched to from OnConnectionStatusChange to handle updating + // frontend UI components. + void HandleConnectionStatusChangeOnFrontendLoop( + syncer::ConnectionStatus status); + + void ClearServerDataDoneOnFrontendLoop( + const syncer::SyncManager::ClearServerDataCallback& frontend_callback); + + // A reference to the TaskRUnner used to construct |this|, so we know how to + // safely talk back to the SyncFrontend. + scoped_refptr<base::SingleThreadTaskRunner> const frontend_task_runner_; + + sync_driver::SyncClient* const sync_client_; + + // The UI thread's task runner. + const scoped_refptr<base::SingleThreadTaskRunner> ui_thread_; + + // Name used for debugging (set from profile_->GetDebugName()). + const std::string name_; + + // Our core, which communicates directly to the syncapi. Use refptr instead + // of WeakHandle because |core_| is created on UI loop but released on + // sync loop. + scoped_refptr<SyncBackendHostCore> core_; + + // A handle referencing the main interface for non-blocking sync types. This + // object is owned because in production code it is a proxy object. + std::unique_ptr<syncer_v2::ModelTypeConnector> model_type_connector_; + + bool initialized_; + + const base::WeakPtr<sync_driver::SyncPrefs> sync_prefs_; + + std::unique_ptr<SyncBackendRegistrar> registrar_; + + // The frontend which we serve (and are owned by). + sync_driver::SyncFrontend* frontend_; + + // We cache the cryptographer's pending keys whenever NotifyPassphraseRequired + // is called. This way, before the UI calls SetDecryptionPassphrase on the + // syncer, it can avoid the overhead of an asynchronous decryption call and + // give the user immediate feedback about the passphrase entered by first + // trying to decrypt the cached pending keys on the UI thread. Note that + // SetDecryptionPassphrase can still fail after the cached pending keys are + // successfully decrypted if the pending keys have changed since the time they + // were cached. + sync_pb::EncryptedData cached_pending_keys_; + + // The state of the passphrase required to decrypt the bag of encryption keys + // in the nigori node. Updated whenever a new nigori node arrives or the user + // manually changes their passphrase state. Cached so we can synchronously + // check it from the UI thread. + syncer::PassphraseType cached_passphrase_type_; + + // If an explicit passphrase is in use, the time at which the passphrase was + // first set (if available). + base::Time cached_explicit_passphrase_time_; + + // UI-thread cache of the last SyncSessionSnapshot received from syncapi. + syncer::sessions::SyncSessionSnapshot last_snapshot_; + + invalidation::InvalidationService* invalidator_; + bool invalidation_handler_registered_; + + base::WeakPtrFactory<SyncBackendHostImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(SyncBackendHostImpl); +}; + +} // namespace browser_sync + +#endif // COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_IMPL_H_
diff --git a/components/sync/driver/glue/sync_backend_host_impl_unittest.cc b/components/sync/driver/glue/sync_backend_host_impl_unittest.cc new file mode 100644 index 0000000..ec9f8b4 --- /dev/null +++ b/components/sync/driver/glue/sync_backend_host_impl_unittest.cc
@@ -0,0 +1,870 @@ +// 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 "components/sync/driver/glue/sync_backend_host_impl.h" + +#include <stdint.h> + +#include <cstddef> +#include <map> +#include <memory> +#include <utility> + +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/location.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/synchronization/waitable_event.h" +#include "base/test/test_timeouts.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/time/time.h" +#include "components/invalidation/impl/invalidator_storage.h" +#include "components/invalidation/impl/profile_invalidation_provider.h" +#include "components/invalidation/public/invalidator_state.h" +#include "components/invalidation/public/object_id_invalidation_map.h" +#include "components/sync/base/experiments.h" +#include "components/sync/base/model_type.h" +#include "components/sync/base/test_unrecoverable_error_handler.h" +#include "components/sync/core/http_bridge_network_resources.h" +#include "components/sync/core/network_resources.h" +#include "components/sync/core/sync_manager_factory.h" +#include "components/sync/core/test/fake_sync_manager.h" +#include "components/sync/driver/device_info.h" +#include "components/sync/driver/fake_sync_client.h" +#include "components/sync/driver/sync_frontend.h" +#include "components/sync/driver/sync_prefs.h" +#include "components/sync/engine/model_safe_worker.h" +#include "components/sync/engine/passive_model_worker.h" +#include "components/sync/protocol/encryption.pb.h" +#include "components/sync/protocol/sync_protocol_error.h" +#include "components/sync/sessions/commit_counters.h" +#include "components/sync/sessions/status_counters.h" +#include "components/sync/sessions/update_counters.h" +#include "components/sync/test/callback_counter.h" +#include "components/syncable_prefs/pref_service_syncable.h" +#include "components/syncable_prefs/testing_pref_service_syncable.h" +#include "google/cacheinvalidation/include/types.h" +#include "google_apis/gaia/gaia_constants.h" +#include "net/url_request/test_url_fetcher_factory.h" +#include "net/url_request/url_request_context_getter.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +using syncer::FakeSyncManager; +using syncer::SyncManager; +using ::testing::InvokeWithoutArgs; +using ::testing::StrictMock; +using ::testing::_; + +namespace browser_sync { + +namespace { + +static const base::FilePath::CharType kTestSyncDir[] = + FILE_PATH_LITERAL("sync-test"); + +ACTION_P(Signal, event) { + event->Signal(); +} + +void EmptyNetworkTimeUpdate(const base::Time&, + const base::TimeDelta&, + const base::TimeDelta&) {} + +void QuitMessageLoop() { + base::MessageLoop::current()->QuitWhenIdle(); +} + +class MockSyncFrontend : public sync_driver::SyncFrontend { + public: + virtual ~MockSyncFrontend() {} + + MOCK_METHOD4( + OnBackendInitialized, + void(const syncer::WeakHandle<syncer::JsBackend>&, + const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&, + const std::string&, + bool)); + MOCK_METHOD0(OnSyncCycleCompleted, void()); + MOCK_METHOD1(OnConnectionStatusChange, void(syncer::ConnectionStatus status)); + MOCK_METHOD0(OnClearServerDataSucceeded, void()); + MOCK_METHOD0(OnClearServerDataFailed, void()); + MOCK_METHOD2(OnPassphraseRequired, + void(syncer::PassphraseRequiredReason, + const sync_pb::EncryptedData&)); + MOCK_METHOD0(OnPassphraseAccepted, void()); + MOCK_METHOD2(OnEncryptedTypesChanged, void(syncer::ModelTypeSet, bool)); + MOCK_METHOD0(OnEncryptionComplete, void()); + MOCK_METHOD1(OnMigrationNeededForTypes, void(syncer::ModelTypeSet)); + MOCK_METHOD1(OnProtocolEvent, void(const syncer::ProtocolEvent&)); + MOCK_METHOD2(OnDirectoryTypeCommitCounterUpdated, + void(syncer::ModelType, const syncer::CommitCounters&)); + MOCK_METHOD2(OnDirectoryTypeUpdateCounterUpdated, + void(syncer::ModelType, const syncer::UpdateCounters&)); + MOCK_METHOD2(OnDirectoryTypeStatusCounterUpdated, + void(syncer::ModelType, const syncer::StatusCounters&)); + MOCK_METHOD1(OnExperimentsChanged, void(const syncer::Experiments&)); + MOCK_METHOD1(OnActionableError, + void(const syncer::SyncProtocolError& sync_error)); + MOCK_METHOD0(OnSyncConfigureRetry, void()); + MOCK_METHOD1( + OnLocalSetPassphraseEncryption, + void(const syncer::SyncEncryptionHandler::NigoriState& nigori_state)); +}; + +class FakeSyncManagerFactory : public syncer::SyncManagerFactory { + public: + explicit FakeSyncManagerFactory(FakeSyncManager** fake_manager) + : fake_manager_(fake_manager) { + *fake_manager_ = NULL; + } + ~FakeSyncManagerFactory() override {} + + // SyncManagerFactory implementation. Called on the sync thread. + std::unique_ptr<SyncManager> CreateSyncManager( + const std::string& /* name */) override { + *fake_manager_ = + new FakeSyncManager(initial_sync_ended_types_, progress_marker_types_, + configure_fail_types_); + return std::unique_ptr<SyncManager>(*fake_manager_); + } + + void set_initial_sync_ended_types(syncer::ModelTypeSet types) { + initial_sync_ended_types_ = types; + } + + void set_progress_marker_types(syncer::ModelTypeSet types) { + progress_marker_types_ = types; + } + + void set_configure_fail_types(syncer::ModelTypeSet types) { + configure_fail_types_ = types; + } + + private: + syncer::ModelTypeSet initial_sync_ended_types_; + syncer::ModelTypeSet progress_marker_types_; + syncer::ModelTypeSet configure_fail_types_; + FakeSyncManager** fake_manager_; +}; + +class BackendSyncClient : public sync_driver::FakeSyncClient { + public: + scoped_refptr<syncer::ModelSafeWorker> CreateModelWorkerForGroup( + syncer::ModelSafeGroup group, + syncer::WorkerLoopDestructionObserver* observer) override { + switch (group) { + case syncer::GROUP_PASSIVE: + return new syncer::PassiveModelWorker(observer); + default: + return nullptr; + } + } +}; + +class SyncBackendHostTest : public testing::Test { + protected: + SyncBackendHostTest() : fake_manager_(NULL) {} + + ~SyncBackendHostTest() override {} + + void SetUp() override { + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + + sync_driver::SyncPrefs::RegisterProfilePrefs(pref_service_.registry()); + + sync_prefs_.reset(new sync_driver::SyncPrefs(&pref_service_)); + backend_.reset(new SyncBackendHostImpl( + "dummyDebugName", &sync_client_, base::ThreadTaskRunnerHandle::Get(), + nullptr, sync_prefs_->AsWeakPtr(), + temp_dir_.path().Append(base::FilePath(kTestSyncDir)))); + credentials_.account_id = "user@example.com"; + credentials_.email = "user@example.com"; + credentials_.sync_token = "sync_token"; + credentials_.scope_set.insert(GaiaConstants::kChromeSyncOAuth2Scope); + + fake_manager_factory_.reset(new FakeSyncManagerFactory(&fake_manager_)); + + // These types are always implicitly enabled. + enabled_types_.PutAll(syncer::ControlTypes()); + + // NOTE: We can't include Passwords or Typed URLs due to the Sync Backend + // Registrar removing them if it can't find their model workers. + enabled_types_.Put(syncer::BOOKMARKS); + enabled_types_.Put(syncer::PREFERENCES); + enabled_types_.Put(syncer::SESSIONS); + enabled_types_.Put(syncer::SEARCH_ENGINES); + enabled_types_.Put(syncer::AUTOFILL); + + network_resources_.reset(new syncer::HttpBridgeNetworkResources()); + } + + void TearDown() override { + if (backend_) { + backend_->StopSyncingForShutdown(); + backend_->Shutdown(syncer::STOP_SYNC); + } + backend_.reset(); + sync_prefs_.reset(); + // Pump messages posted by the sync thread. + base::RunLoop().RunUntilIdle(); + } + + // Synchronously initializes the backend. + void InitializeBackend(bool expect_success) { + EXPECT_CALL(mock_frontend_, OnBackendInitialized(_, _, _, expect_success)) + .WillOnce(InvokeWithoutArgs(QuitMessageLoop)); + SyncBackendHost::HttpPostProviderFactoryGetter + http_post_provider_factory_getter = + base::Bind(&syncer::NetworkResources::GetHttpPostProviderFactory, + base::Unretained(network_resources_.get()), nullptr, + base::Bind(&EmptyNetworkTimeUpdate)); + backend_->Initialize( + &mock_frontend_, std::unique_ptr<base::Thread>(), + base::ThreadTaskRunnerHandle::Get(), + base::ThreadTaskRunnerHandle::Get(), + syncer::WeakHandle<syncer::JsEventHandler>(), GURL(std::string()), + std::string(), credentials_, true, std::move(fake_manager_factory_), + MakeWeakHandle(test_unrecoverable_error_handler_.GetWeakPtr()), + base::Closure(), http_post_provider_factory_getter, + std::move(saved_nigori_state_)); + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, run_loop.QuitClosure(), TestTimeouts::action_timeout()); + run_loop.Run(); + // |fake_manager_factory_|'s fake_manager() is set on the sync + // thread, but we can rely on the message loop barriers to + // guarantee that we see the updated value. + DCHECK(fake_manager_); + } + + // Synchronously configures the backend's datatypes. + syncer::ModelTypeSet ConfigureDataTypes( + syncer::ModelTypeSet types_to_add, + syncer::ModelTypeSet types_to_remove, + syncer::ModelTypeSet types_to_unapply) { + sync_driver::BackendDataTypeConfigurer::DataTypeConfigStateMap + config_state_map; + sync_driver::BackendDataTypeConfigurer::SetDataTypesState( + sync_driver::BackendDataTypeConfigurer::CONFIGURE_ACTIVE, types_to_add, + &config_state_map); + sync_driver::BackendDataTypeConfigurer::SetDataTypesState( + sync_driver::BackendDataTypeConfigurer::DISABLED, types_to_remove, + &config_state_map); + sync_driver::BackendDataTypeConfigurer::SetDataTypesState( + sync_driver::BackendDataTypeConfigurer::UNREADY, types_to_unapply, + &config_state_map); + + types_to_add.PutAll(syncer::ControlTypes()); + syncer::ModelTypeSet ready_types = backend_->ConfigureDataTypes( + syncer::CONFIGURE_REASON_RECONFIGURATION, config_state_map, + base::Bind(&SyncBackendHostTest::DownloadReady, base::Unretained(this)), + base::Bind(&SyncBackendHostTest::OnDownloadRetry, + base::Unretained(this))); + base::RunLoop run_loop; + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, run_loop.QuitClosure(), TestTimeouts::action_timeout()); + run_loop.Run(); + return ready_types; + } + + protected: + void DownloadReady(syncer::ModelTypeSet succeeded_types, + syncer::ModelTypeSet failed_types) { + base::MessageLoop::current()->QuitWhenIdle(); + } + + void OnDownloadRetry() { NOTIMPLEMENTED(); } + + base::MessageLoop message_loop_; + base::ScopedTempDir temp_dir_; + syncable_prefs::TestingPrefServiceSyncable pref_service_; + StrictMock<MockSyncFrontend> mock_frontend_; + syncer::SyncCredentials credentials_; + BackendSyncClient sync_client_; + syncer::TestUnrecoverableErrorHandler test_unrecoverable_error_handler_; + std::unique_ptr<sync_driver::SyncPrefs> sync_prefs_; + std::unique_ptr<SyncBackendHostImpl> backend_; + std::unique_ptr<FakeSyncManagerFactory> fake_manager_factory_; + FakeSyncManager* fake_manager_; + syncer::ModelTypeSet enabled_types_; + std::unique_ptr<syncer::NetworkResources> network_resources_; + std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> + saved_nigori_state_; +}; + +// Test basic initialization with no initial types (first time initialization). +// Only the nigori should be configured. +TEST_F(SyncBackendHostTest, InitShutdown) { + InitializeBackend(true); + EXPECT_EQ(syncer::ControlTypes(), + fake_manager_->GetAndResetDownloadedTypes()); + EXPECT_EQ(syncer::ControlTypes(), fake_manager_->InitialSyncEndedTypes()); + EXPECT_TRUE(fake_manager_ + ->GetTypesWithEmptyProgressMarkerToken(syncer::ControlTypes()) + .Empty()); +} + +// Test first time sync scenario. All types should be properly configured. +TEST_F(SyncBackendHostTest, FirstTimeSync) { + InitializeBackend(true); + EXPECT_EQ(syncer::ControlTypes(), + fake_manager_->GetAndResetDownloadedTypes()); + EXPECT_EQ(syncer::ControlTypes(), fake_manager_->InitialSyncEndedTypes()); + EXPECT_TRUE(fake_manager_ + ->GetTypesWithEmptyProgressMarkerToken(syncer::ControlTypes()) + .Empty()); + + syncer::ModelTypeSet ready_types = ConfigureDataTypes( + enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), + syncer::ModelTypeSet()); + // Nigori is always downloaded so won't be ready. + EXPECT_EQ(syncer::Difference(syncer::ControlTypes(), + syncer::ModelTypeSet(syncer::NIGORI)), + ready_types); + EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll( + Difference(enabled_types_, syncer::ControlTypes()))); + EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); + EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); + EXPECT_TRUE( + fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) + .Empty()); +} + +// Test the restart after setting up sync scenario. No enabled types should be +// downloaded or cleaned. +TEST_F(SyncBackendHostTest, Restart) { + sync_prefs_->SetFirstSetupComplete(); + syncer::ModelTypeSet all_but_nigori = enabled_types_; + fake_manager_factory_->set_progress_marker_types(enabled_types_); + fake_manager_factory_->set_initial_sync_ended_types(enabled_types_); + InitializeBackend(true); + EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty()); + EXPECT_TRUE( + Intersection(fake_manager_->GetAndResetCleanedTypes(), enabled_types_) + .Empty()); + EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); + EXPECT_TRUE( + fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) + .Empty()); + + syncer::ModelTypeSet ready_types = ConfigureDataTypes( + enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), + syncer::ModelTypeSet()); + EXPECT_EQ(enabled_types_, ready_types); + EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty()); + EXPECT_TRUE( + Intersection(fake_manager_->GetAndResetCleanedTypes(), enabled_types_) + .Empty()); + EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); + EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); + EXPECT_TRUE( + fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) + .Empty()); +} + +// Test a sync restart scenario where some types had never finished configuring. +// The partial types should be purged, then reconfigured properly. +TEST_F(SyncBackendHostTest, PartialTypes) { + sync_prefs_->SetFirstSetupComplete(); + // Set sync manager behavior before passing it down. All types have progress + // markers, but nigori and bookmarks are missing initial sync ended. + syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS); + syncer::ModelTypeSet full_types = Difference(enabled_types_, partial_types); + fake_manager_factory_->set_progress_marker_types(enabled_types_); + fake_manager_factory_->set_initial_sync_ended_types(full_types); + + // Bringing up the backend should purge all partial types, then proceed to + // download the Nigori. + InitializeBackend(true); + EXPECT_EQ(syncer::ModelTypeSet(syncer::NIGORI), + fake_manager_->GetAndResetDownloadedTypes()); + EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types)); + EXPECT_EQ(Union(full_types, syncer::ModelTypeSet(syncer::NIGORI)), + fake_manager_->InitialSyncEndedTypes()); + EXPECT_EQ( + Difference(partial_types, syncer::ModelTypeSet(syncer::NIGORI)), + fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_)); + + // Now do the actual configuration, which should download and apply bookmarks. + syncer::ModelTypeSet ready_types = ConfigureDataTypes( + enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), + syncer::ModelTypeSet()); + EXPECT_EQ(full_types, ready_types); + EXPECT_TRUE( + Intersection(fake_manager_->GetAndResetCleanedTypes(), enabled_types_) + .Empty()); + EXPECT_EQ(partial_types, fake_manager_->GetAndResetDownloadedTypes()); + EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); + EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); + EXPECT_TRUE( + fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) + .Empty()); +} + +// Test the behavior when we lose the sync db. Although we already have types +// enabled, we should re-download all of them because we lost their data. +TEST_F(SyncBackendHostTest, LostDB) { + sync_prefs_->SetFirstSetupComplete(); + // Initialization should fetch the Nigori node. Everything else should be + // left untouched. + InitializeBackend(true); + EXPECT_EQ(syncer::ModelTypeSet(syncer::ControlTypes()), + fake_manager_->GetAndResetDownloadedTypes()); + EXPECT_EQ(syncer::ModelTypeSet(syncer::ControlTypes()), + fake_manager_->InitialSyncEndedTypes()); + EXPECT_EQ( + Difference(enabled_types_, syncer::ControlTypes()), + fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_)); + + // The database was empty, so any cleaning is entirely optional. We want to + // reset this value before running the next part of the test, though. + fake_manager_->GetAndResetCleanedTypes(); + + // The actual configuration should redownload and apply all the enabled types. + syncer::ModelTypeSet ready_types = ConfigureDataTypes( + enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), + syncer::ModelTypeSet()); + // Nigori is always downloaded so won't be ready. + EXPECT_EQ(syncer::Difference(syncer::ControlTypes(), + syncer::ModelTypeSet(syncer::NIGORI)), + ready_types); + EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll( + Difference(enabled_types_, syncer::ControlTypes()))); + EXPECT_TRUE( + Intersection(fake_manager_->GetAndResetCleanedTypes(), enabled_types_) + .Empty()); + EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); + EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); + EXPECT_TRUE( + fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) + .Empty()); +} + +TEST_F(SyncBackendHostTest, DisableTypes) { + // Simulate first time sync. + InitializeBackend(true); + fake_manager_->GetAndResetCleanedTypes(); + syncer::ModelTypeSet ready_types = ConfigureDataTypes( + enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), + syncer::ModelTypeSet()); + // Nigori is always downloaded so won't be ready. + EXPECT_EQ(syncer::Difference(syncer::ControlTypes(), + syncer::ModelTypeSet(syncer::NIGORI)), + ready_types); + EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetDownloadedTypes()); + EXPECT_TRUE( + Intersection(fake_manager_->GetAndResetCleanedTypes(), enabled_types_) + .Empty()); + EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); + EXPECT_TRUE( + fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) + .Empty()); + + // Then disable two datatypes. + syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS, + syncer::SEARCH_ENGINES); + syncer::ModelTypeSet old_types = enabled_types_; + enabled_types_.RemoveAll(disabled_types); + ready_types = ConfigureDataTypes( + enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), + syncer::ModelTypeSet()); + + // Only those datatypes disabled should be cleaned. Nothing should be + // downloaded. + EXPECT_EQ(enabled_types_, ready_types); + EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty()); + EXPECT_EQ(disabled_types, + Intersection(fake_manager_->GetAndResetCleanedTypes(), old_types)); + EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); + EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); + EXPECT_TRUE( + fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) + .Empty()); +} + +TEST_F(SyncBackendHostTest, AddTypes) { + // Simulate first time sync. + InitializeBackend(true); + fake_manager_->GetAndResetCleanedTypes(); + syncer::ModelTypeSet ready_types = ConfigureDataTypes( + enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), + syncer::ModelTypeSet()); + // Nigori is always downloaded so won't be ready. + EXPECT_EQ(syncer::Difference(syncer::ControlTypes(), + syncer::ModelTypeSet(syncer::NIGORI)), + ready_types); + EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetDownloadedTypes()); + EXPECT_TRUE( + Intersection(fake_manager_->GetAndResetCleanedTypes(), enabled_types_) + .Empty()); + EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); + EXPECT_TRUE( + fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) + .Empty()); + + // Then add two datatypes. + syncer::ModelTypeSet new_types(syncer::EXTENSIONS, syncer::APPS); + enabled_types_.PutAll(new_types); + ready_types = ConfigureDataTypes( + enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), + syncer::ModelTypeSet()); + + // Only those datatypes added should be downloaded (plus nigori). Nothing + // should be cleaned aside from the disabled types. + new_types.Put(syncer::NIGORI); + EXPECT_EQ(syncer::Difference(enabled_types_, new_types), ready_types); + EXPECT_EQ(new_types, fake_manager_->GetAndResetDownloadedTypes()); + EXPECT_TRUE( + Intersection(fake_manager_->GetAndResetCleanedTypes(), enabled_types_) + .Empty()); + EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); + EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); + EXPECT_TRUE( + fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) + .Empty()); +} + +// And and disable in the same configuration. +TEST_F(SyncBackendHostTest, AddDisableTypes) { + // Simulate first time sync. + InitializeBackend(true); + fake_manager_->GetAndResetCleanedTypes(); + syncer::ModelTypeSet ready_types = ConfigureDataTypes( + enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), + syncer::ModelTypeSet()); + // Nigori is always downloaded so won't be ready. + EXPECT_EQ(syncer::Difference(syncer::ControlTypes(), + syncer::ModelTypeSet(syncer::NIGORI)), + ready_types); + EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetDownloadedTypes()); + EXPECT_TRUE( + Intersection(fake_manager_->GetAndResetCleanedTypes(), enabled_types_) + .Empty()); + EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); + EXPECT_TRUE( + fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) + .Empty()); + + // Then add two datatypes. + syncer::ModelTypeSet old_types = enabled_types_; + syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS, + syncer::SEARCH_ENGINES); + syncer::ModelTypeSet new_types(syncer::EXTENSIONS, syncer::APPS); + enabled_types_.PutAll(new_types); + enabled_types_.RemoveAll(disabled_types); + ready_types = ConfigureDataTypes( + enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), + syncer::ModelTypeSet()); + + // Only those datatypes added should be downloaded (plus nigori). Nothing + // should be cleaned aside from the disabled types. + new_types.Put(syncer::NIGORI); + EXPECT_EQ(syncer::Difference(enabled_types_, new_types), ready_types); + EXPECT_EQ(new_types, fake_manager_->GetAndResetDownloadedTypes()); + EXPECT_EQ(disabled_types, + Intersection(fake_manager_->GetAndResetCleanedTypes(), old_types)); + EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); + EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); + EXPECT_EQ(disabled_types, + fake_manager_->GetTypesWithEmptyProgressMarkerToken(old_types)); +} + +// Test restarting the browser to newly supported datatypes. The new datatypes +// should be downloaded on the configuration after backend initialization. +TEST_F(SyncBackendHostTest, NewlySupportedTypes) { + sync_prefs_->SetFirstSetupComplete(); + // Set sync manager behavior before passing it down. All types have progress + // markers and initial sync ended except the new types. + syncer::ModelTypeSet old_types = enabled_types_; + fake_manager_factory_->set_progress_marker_types(old_types); + fake_manager_factory_->set_initial_sync_ended_types(old_types); + syncer::ModelTypeSet new_types(syncer::APP_SETTINGS, + syncer::EXTENSION_SETTINGS); + enabled_types_.PutAll(new_types); + + // Does nothing. + InitializeBackend(true); + EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty()); + EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), old_types) + .Empty()); + EXPECT_EQ(old_types, fake_manager_->InitialSyncEndedTypes()); + EXPECT_EQ(new_types, fake_manager_->GetTypesWithEmptyProgressMarkerToken( + enabled_types_)); + + // Downloads and applies the new types (plus nigori). + syncer::ModelTypeSet ready_types = ConfigureDataTypes( + enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), + syncer::ModelTypeSet()); + + new_types.Put(syncer::NIGORI); + EXPECT_EQ(syncer::Difference(old_types, syncer::ModelTypeSet(syncer::NIGORI)), + ready_types); + EXPECT_EQ(new_types, fake_manager_->GetAndResetDownloadedTypes()); + EXPECT_TRUE( + Intersection(fake_manager_->GetAndResetCleanedTypes(), enabled_types_) + .Empty()); + EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); + EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); + EXPECT_TRUE( + fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) + .Empty()); +} + +// Test the newly supported types scenario, but with the presence of partial +// types as well. Both partial and newly supported types should be downloaded +// the configuration. +TEST_F(SyncBackendHostTest, NewlySupportedTypesWithPartialTypes) { + sync_prefs_->SetFirstSetupComplete(); + // Set sync manager behavior before passing it down. All types have progress + // markers and initial sync ended except the new types. + syncer::ModelTypeSet old_types = enabled_types_; + syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS); + syncer::ModelTypeSet full_types = Difference(enabled_types_, partial_types); + fake_manager_factory_->set_progress_marker_types(old_types); + fake_manager_factory_->set_initial_sync_ended_types(full_types); + syncer::ModelTypeSet new_types(syncer::APP_SETTINGS, + syncer::EXTENSION_SETTINGS); + enabled_types_.PutAll(new_types); + + // Purge the partial types. The nigori will be among the purged types, but + // the syncer will re-download it by the time the initialization is complete. + InitializeBackend(true); + EXPECT_EQ(syncer::ModelTypeSet(syncer::NIGORI), + fake_manager_->GetAndResetDownloadedTypes()); + EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types)); + EXPECT_EQ(syncer::Union(full_types, syncer::ModelTypeSet(syncer::NIGORI)), + fake_manager_->InitialSyncEndedTypes()); + EXPECT_EQ( + Union(new_types, + Difference(partial_types, syncer::ModelTypeSet(syncer::NIGORI))), + fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_)); + + // Downloads and applies the new types and partial types (which includes + // nigori anyways). + syncer::ModelTypeSet ready_types = ConfigureDataTypes( + enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), + syncer::ModelTypeSet()); + EXPECT_EQ(full_types, ready_types); + EXPECT_EQ(Union(new_types, partial_types), + fake_manager_->GetAndResetDownloadedTypes()); + EXPECT_TRUE( + Intersection(fake_manager_->GetAndResetCleanedTypes(), enabled_types_) + .Empty()); + EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); + EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); + EXPECT_TRUE( + fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) + .Empty()); +} + +// Verify that downloading control types only downloads those types that do +// not have initial sync ended set. +TEST_F(SyncBackendHostTest, DownloadControlTypes) { + sync_prefs_->SetFirstSetupComplete(); + // Set sync manager behavior before passing it down. Experiments and device + // info are new types without progress markers or initial sync ended, while + // all other types have been fully downloaded and applied. + syncer::ModelTypeSet new_types(syncer::EXPERIMENTS, syncer::NIGORI); + syncer::ModelTypeSet old_types = Difference(enabled_types_, new_types); + fake_manager_factory_->set_progress_marker_types(old_types); + fake_manager_factory_->set_initial_sync_ended_types(old_types); + + // Bringing up the backend should download the new types without downloading + // any old types. + InitializeBackend(true); + EXPECT_EQ(new_types, fake_manager_->GetAndResetDownloadedTypes()); + EXPECT_EQ(Difference(syncer::ModelTypeSet::All(), enabled_types_), + fake_manager_->GetAndResetCleanedTypes()); + EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); + EXPECT_TRUE( + fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_) + .Empty()); +} + +// Fail to download control types. It's believed that there is a server bug +// which can allow this to happen (crbug.com/164288). The sync backend host +// should detect this condition and fail to initialize the backend. +// +// The failure is "silent" in the sense that the GetUpdates request appears to +// be successful, but it returned no results. This means that the usual +// download retry logic will not be invoked. +TEST_F(SyncBackendHostTest, SilentlyFailToDownloadControlTypes) { + fake_manager_factory_->set_configure_fail_types(syncer::ModelTypeSet::All()); + InitializeBackend(false); +} + +// Test that local refresh requests are delivered to sync. +TEST_F(SyncBackendHostTest, ForwardLocalRefreshRequest) { + InitializeBackend(true); + + syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All(); + backend_->TriggerRefresh(set1); + fake_manager_->WaitForSyncThread(); + EXPECT_EQ(set1, fake_manager_->GetLastRefreshRequestTypes()); + + syncer::ModelTypeSet set2 = syncer::ModelTypeSet(syncer::SESSIONS); + backend_->TriggerRefresh(set2); + fake_manager_->WaitForSyncThread(); + EXPECT_EQ(set2, fake_manager_->GetLastRefreshRequestTypes()); +} + +// Test that configuration on signin sends the proper GU source. +TEST_F(SyncBackendHostTest, DownloadControlTypesNewClient) { + InitializeBackend(true); + EXPECT_EQ(syncer::CONFIGURE_REASON_NEW_CLIENT, + fake_manager_->GetAndResetConfigureReason()); +} + +// Test that configuration on restart sends the proper GU source. +TEST_F(SyncBackendHostTest, DownloadControlTypesRestart) { + sync_prefs_->SetFirstSetupComplete(); + fake_manager_factory_->set_progress_marker_types(enabled_types_); + fake_manager_factory_->set_initial_sync_ended_types(enabled_types_); + InitializeBackend(true); + EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE, + fake_manager_->GetAndResetConfigureReason()); +} + +// It is SyncBackendHostCore responsibility to cleanup Sync Data folder if sync +// setup hasn't been completed. This test ensures that cleanup happens. +TEST_F(SyncBackendHostTest, TestStartupWithOldSyncData) { + const char* nonsense = "slon"; + base::FilePath temp_directory = + temp_dir_.path().Append(base::FilePath(kTestSyncDir)); + base::FilePath sync_file = temp_directory.AppendASCII("SyncData.sqlite3"); + ASSERT_TRUE(base::CreateDirectory(temp_directory)); + ASSERT_NE(-1, base::WriteFile(sync_file, nonsense, strlen(nonsense))); + + InitializeBackend(true); + + EXPECT_FALSE(base::PathExists(sync_file)); +} + +// If bookmarks encounter an error that results in disabling without purging +// (such as when the type is unready), and then is explicitly disabled, the +// SyncBackendHost needs to tell the manager to purge the type, even though +// it's already disabled (crbug.com/386778). +TEST_F(SyncBackendHostTest, DisableThenPurgeType) { + syncer::ModelTypeSet error_types(syncer::BOOKMARKS); + + InitializeBackend(true); + + // First enable the types. + syncer::ModelTypeSet ready_types = ConfigureDataTypes( + enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), + syncer::ModelTypeSet()); + + // Nigori is always downloaded so won't be ready. + EXPECT_EQ(syncer::Difference(syncer::ControlTypes(), + syncer::ModelTypeSet(syncer::NIGORI)), + ready_types); + + // Then mark the error types as unready (disables without purging). + ready_types = ConfigureDataTypes( + enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), + error_types); + EXPECT_EQ(syncer::Difference(enabled_types_, error_types), ready_types); + EXPECT_TRUE( + fake_manager_->GetTypesWithEmptyProgressMarkerToken(error_types).Empty()); + + // Lastly explicitly disable the error types, which should result in a purge. + enabled_types_.RemoveAll(error_types); + ready_types = ConfigureDataTypes( + enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), + syncer::ModelTypeSet()); + EXPECT_EQ(syncer::Difference(enabled_types_, error_types), ready_types); + EXPECT_FALSE( + fake_manager_->GetTypesWithEmptyProgressMarkerToken(error_types).Empty()); +} + +// Test that a call to ClearServerData is forwarded to the underlying +// SyncManager. +TEST_F(SyncBackendHostTest, ClearServerDataCallsAreForwarded) { + InitializeBackend(true); + syncer::CallbackCounter callback_counter; + backend_->ClearServerData(base::Bind(&syncer::CallbackCounter::Callback, + base::Unretained(&callback_counter))); + fake_manager_->WaitForSyncThread(); + EXPECT_EQ(1, callback_counter.times_called()); +} + +// Ensure that redundant invalidations are ignored and that the most recent +// set of invalidation version is persisted across restarts. +TEST_F(SyncBackendHostTest, IgnoreOldInvalidations) { + // Set up some old persisted invalidations. + std::map<syncer::ModelType, int64_t> invalidation_versions; + invalidation_versions[syncer::BOOKMARKS] = 20; + sync_prefs_->UpdateInvalidationVersions(invalidation_versions); + InitializeBackend(true); + EXPECT_EQ(0, fake_manager_->GetInvalidationCount()); + + // Receiving an invalidation with an old version should do nothing. + syncer::ObjectIdInvalidationMap invalidation_map; + std::string notification_type; + syncer::RealModelTypeToNotificationType(syncer::BOOKMARKS, + ¬ification_type); + invalidation_map.Insert(syncer::Invalidation::Init( + invalidation::ObjectId(0, notification_type), 10, "payload")); + backend_->OnIncomingInvalidation(invalidation_map); + fake_manager_->WaitForSyncThread(); + EXPECT_EQ(0, fake_manager_->GetInvalidationCount()); + + // Invalidations with new versions should be acted upon. + invalidation_map.Insert(syncer::Invalidation::Init( + invalidation::ObjectId(0, notification_type), 30, "payload")); + backend_->OnIncomingInvalidation(invalidation_map); + fake_manager_->WaitForSyncThread(); + EXPECT_EQ(1, fake_manager_->GetInvalidationCount()); + + // Invalidation for new data types should be acted on. + syncer::RealModelTypeToNotificationType(syncer::SESSIONS, ¬ification_type); + invalidation_map.Insert(syncer::Invalidation::Init( + invalidation::ObjectId(0, notification_type), 10, "payload")); + backend_->OnIncomingInvalidation(invalidation_map); + fake_manager_->WaitForSyncThread(); + EXPECT_EQ(2, fake_manager_->GetInvalidationCount()); + + // But redelivering that same invalidation should be ignored. + backend_->OnIncomingInvalidation(invalidation_map); + fake_manager_->WaitForSyncThread(); + EXPECT_EQ(2, fake_manager_->GetInvalidationCount()); + + // If an invalidation with an unknown version is received, it should be + // acted on, but should not affect the persisted versions. + invalidation_map.Insert(syncer::Invalidation::InitUnknownVersion( + invalidation::ObjectId(0, notification_type))); + backend_->OnIncomingInvalidation(invalidation_map); + fake_manager_->WaitForSyncThread(); + EXPECT_EQ(3, fake_manager_->GetInvalidationCount()); + + // Verify that the invalidation versions were updated in the prefs. + invalidation_versions[syncer::BOOKMARKS] = 30; + invalidation_versions[syncer::SESSIONS] = 10; + std::map<syncer::ModelType, int64_t> persisted_invalidation_versions; + sync_prefs_->GetInvalidationVersions(&persisted_invalidation_versions); + EXPECT_EQ(invalidation_versions.size(), + persisted_invalidation_versions.size()); + for (auto iter : persisted_invalidation_versions) { + EXPECT_EQ(invalidation_versions[iter.first], iter.second); + } +} + +// Tests that SyncBackendHostImpl retains ModelTypeConnector after call to +// StopSyncingForShutdown. This is needed for datatype deactivation during +// DataTypeManager shutdown. +TEST_F(SyncBackendHostTest, ModelTypeConnectorValidDuringShutdown) { + InitializeBackend(true); + backend_->StopSyncingForShutdown(); + // Verify that call to DeactivateNonBlockingDataType doesn't assert. + backend_->DeactivateNonBlockingDataType(syncer::AUTOFILL); + backend_->Shutdown(syncer::STOP_SYNC); + backend_.reset(); +} + +} // namespace + +} // namespace browser_sync
diff --git a/components/sync/driver/glue/sync_backend_host_mock.cc b/components/sync/driver/glue/sync_backend_host_mock.cc new file mode 100644 index 0000000..5264dfdc --- /dev/null +++ b/components/sync/driver/glue/sync_backend_host_mock.cc
@@ -0,0 +1,158 @@ +// 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 "components/sync/driver/glue/sync_backend_host_mock.h" + +#include "components/sync/core/activation_context.h" +#include "components/sync/driver/sync_frontend.h" + +namespace browser_sync { + +const char kTestCacheGuid[] = "test-guid"; + +SyncBackendHostMock::SyncBackendHostMock() : fail_initial_download_(false) {} +SyncBackendHostMock::~SyncBackendHostMock() {} + +void SyncBackendHostMock::Initialize( + sync_driver::SyncFrontend* frontend, + std::unique_ptr<base::Thread> sync_thread, + const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, + const scoped_refptr<base::SingleThreadTaskRunner>& file_thread, + const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, + const GURL& service_url, + const std::string& sync_user_agent, + const syncer::SyncCredentials& credentials, + bool delete_sync_data_folder, + std::unique_ptr<syncer::SyncManagerFactory> sync_manager_factory, + const syncer::WeakHandle<syncer::UnrecoverableErrorHandler>& + unrecoverable_error_handler, + const base::Closure& report_unrecoverable_error_function, + const HttpPostProviderFactoryGetter& http_post_provider_factory_getter, + std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> + saved_nigori_state) { + frontend->OnBackendInitialized( + syncer::WeakHandle<syncer::JsBackend>(), + syncer::WeakHandle<syncer::DataTypeDebugInfoListener>(), kTestCacheGuid, + !fail_initial_download_); +} + +void SyncBackendHostMock::TriggerRefresh(const syncer::ModelTypeSet& types) {} + +void SyncBackendHostMock::UpdateCredentials( + const syncer::SyncCredentials& credentials) {} + +void SyncBackendHostMock::StartSyncingWithServer() {} + +void SyncBackendHostMock::SetEncryptionPassphrase(const std::string& passphrase, + bool is_explicit) {} + +bool SyncBackendHostMock::SetDecryptionPassphrase( + const std::string& passphrase) { + return false; +} + +void SyncBackendHostMock::StopSyncingForShutdown() {} + +std::unique_ptr<base::Thread> SyncBackendHostMock::Shutdown( + syncer::ShutdownReason reason) { + return std::unique_ptr<base::Thread>(); +} + +void SyncBackendHostMock::UnregisterInvalidationIds() {} + +syncer::ModelTypeSet SyncBackendHostMock::ConfigureDataTypes( + syncer::ConfigureReason reason, + const DataTypeConfigStateMap& config_state_map, + const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& + ready_task, + const base::Callback<void()>& retry_callback) { + return syncer::ModelTypeSet(); +} + +void SyncBackendHostMock::EnableEncryptEverything() {} + +void SyncBackendHostMock::ActivateDirectoryDataType( + syncer::ModelType type, + syncer::ModelSafeGroup group, + sync_driver::ChangeProcessor* change_processor) {} +void SyncBackendHostMock::DeactivateDirectoryDataType(syncer::ModelType type) {} + +void SyncBackendHostMock::ActivateNonBlockingDataType( + syncer::ModelType type, + std::unique_ptr<syncer_v2::ActivationContext> activation_context) {} + +void SyncBackendHostMock::DeactivateNonBlockingDataType( + syncer::ModelType type) {} + +syncer::UserShare* SyncBackendHostMock::GetUserShare() const { + return NULL; +} + +SyncBackendHost::Status SyncBackendHostMock::GetDetailedStatus() { + return SyncBackendHost::Status(); +} + +syncer::sessions::SyncSessionSnapshot +SyncBackendHostMock::GetLastSessionSnapshot() const { + return syncer::sessions::SyncSessionSnapshot(); +} + +bool SyncBackendHostMock::HasUnsyncedItems() const { + return false; +} + +bool SyncBackendHostMock::IsNigoriEnabled() const { + return true; +} + +syncer::PassphraseType SyncBackendHostMock::GetPassphraseType() const { + return syncer::IMPLICIT_PASSPHRASE; +} + +base::Time SyncBackendHostMock::GetExplicitPassphraseTime() const { + return base::Time(); +} + +bool SyncBackendHostMock::IsCryptographerReady( + const syncer::BaseTransaction* trans) const { + return false; +} + +void SyncBackendHostMock::GetModelSafeRoutingInfo( + syncer::ModelSafeRoutingInfo* out) const {} + +void SyncBackendHostMock::FlushDirectory() const {} + +base::MessageLoop* SyncBackendHostMock::GetSyncLoopForTesting() { + return NULL; +} + +void SyncBackendHostMock::RefreshTypesForTest(syncer::ModelTypeSet types) {} + +void SyncBackendHostMock::RequestBufferedProtocolEventsAndEnableForwarding() {} + +void SyncBackendHostMock::DisableProtocolEventForwarding() {} + +void SyncBackendHostMock::EnableDirectoryTypeDebugInfoForwarding() {} + +void SyncBackendHostMock::DisableDirectoryTypeDebugInfoForwarding() {} + +void SyncBackendHostMock::GetAllNodesForTypes( + syncer::ModelTypeSet types, + base::Callback<void(const std::vector<syncer::ModelType>& type, + ScopedVector<base::ListValue>)> callback) {} + +void SyncBackendHostMock::set_fail_initial_download(bool should_fail) { + fail_initial_download_ = should_fail; +} + +void SyncBackendHostMock::ClearServerData( + const syncer::SyncManager::ClearServerDataCallback& callback) { + callback.Run(); +} + +void SyncBackendHostMock::OnCookieJarChanged(bool account_mismatch, + bool empty_jar) {} + +} // namespace browser_sync
diff --git a/components/sync/driver/glue/sync_backend_host_mock.h b/components/sync/driver/glue/sync_backend_host_mock.h new file mode 100644 index 0000000..784a859 --- /dev/null +++ b/components/sync/driver/glue/sync_backend_host_mock.h
@@ -0,0 +1,134 @@ +// 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 COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_MOCK_H_ +#define COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_MOCK_H_ + +#include <string> + +#include "base/callback.h" +#include "base/compiler_specific.h" +#include "components/sync/base/weak_handle.h" +#include "components/sync/driver/glue/sync_backend_host.h" + +namespace browser_sync { + +// A mock of the SyncBackendHost. +// +// This class implements the bare minimum required for the ProfileSyncService to +// get through initialization. It often returns NULL pointers or nonesense +// values; it is not intended to be used in tests that depend on SyncBackendHost +// behavior. +class SyncBackendHostMock : public SyncBackendHost { + public: + SyncBackendHostMock(); + ~SyncBackendHostMock() override; + + void Initialize( + sync_driver::SyncFrontend* frontend, + std::unique_ptr<base::Thread> sync_thread, + const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, + const scoped_refptr<base::SingleThreadTaskRunner>& file_thread, + const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, + const GURL& service_url, + const std::string& sync_user_agent, + const syncer::SyncCredentials& credentials, + bool delete_sync_data_folder, + std::unique_ptr<syncer::SyncManagerFactory> sync_manager_factory, + const syncer::WeakHandle<syncer::UnrecoverableErrorHandler>& + unrecoverable_error_handler, + const base::Closure& report_unrecoverable_error_function, + const HttpPostProviderFactoryGetter& http_post_provider_factory_getter, + std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> + saved_nigori_state) override; + + void TriggerRefresh(const syncer::ModelTypeSet& types) override; + + void UpdateCredentials(const syncer::SyncCredentials& credentials) override; + + void StartSyncingWithServer() override; + + void SetEncryptionPassphrase(const std::string& passphrase, + bool is_explicit) override; + + bool SetDecryptionPassphrase(const std::string& passphrase) override; + + void StopSyncingForShutdown() override; + + std::unique_ptr<base::Thread> Shutdown( + syncer::ShutdownReason reason) override; + + void UnregisterInvalidationIds() override; + + syncer::ModelTypeSet ConfigureDataTypes( + syncer::ConfigureReason reason, + const DataTypeConfigStateMap& config_state_map, + const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& + ready_task, + const base::Callback<void()>& retry_callback) override; + + void EnableEncryptEverything() override; + + void ActivateDirectoryDataType( + syncer::ModelType type, + syncer::ModelSafeGroup group, + sync_driver::ChangeProcessor* change_processor) override; + void DeactivateDirectoryDataType(syncer::ModelType type) override; + + void ActivateNonBlockingDataType( + syncer::ModelType type, + std::unique_ptr<syncer_v2::ActivationContext>) override; + void DeactivateNonBlockingDataType(syncer::ModelType type) override; + + syncer::UserShare* GetUserShare() const override; + + Status GetDetailedStatus() override; + + syncer::sessions::SyncSessionSnapshot GetLastSessionSnapshot() const override; + + bool HasUnsyncedItems() const override; + + bool IsNigoriEnabled() const override; + + syncer::PassphraseType GetPassphraseType() const override; + + base::Time GetExplicitPassphraseTime() const override; + + bool IsCryptographerReady( + const syncer::BaseTransaction* trans) const override; + + void GetModelSafeRoutingInfo( + syncer::ModelSafeRoutingInfo* out) const override; + + void FlushDirectory() const override; + + void RequestBufferedProtocolEventsAndEnableForwarding() override; + void DisableProtocolEventForwarding() override; + + void EnableDirectoryTypeDebugInfoForwarding() override; + void DisableDirectoryTypeDebugInfoForwarding() override; + + void GetAllNodesForTypes( + syncer::ModelTypeSet types, + base::Callback<void(const std::vector<syncer::ModelType>& type, + ScopedVector<base::ListValue>)> callback) override; + + base::MessageLoop* GetSyncLoopForTesting() override; + + void RefreshTypesForTest(syncer::ModelTypeSet types) override; + + void ClearServerData( + const syncer::SyncManager::ClearServerDataCallback& callback) override; + + void OnCookieJarChanged(bool account_mismatch, bool empty_jar) override; + + void set_fail_initial_download(bool should_fail); + + private: + bool fail_initial_download_; +}; + +} // namespace browser_sync + +#endif // COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_MOCK_H_
diff --git a/components/sync/driver/glue/sync_backend_registrar.cc b/components/sync/driver/glue/sync_backend_registrar.cc new file mode 100644 index 0000000..02fe1c42 --- /dev/null +++ b/components/sync/driver/glue/sync_backend_registrar.cc
@@ -0,0 +1,381 @@ +// 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. + +#include "components/sync/driver/glue/sync_backend_registrar.h" + +#include <cstddef> +#include <utility> + +#include "base/compiler_specific.h" +#include "base/logging.h" +#include "base/message_loop/message_loop.h" +#include "components/sync/core/user_share.h" +#include "components/sync/driver/change_processor.h" +#include "components/sync/driver/sync_client.h" + +namespace browser_sync { + +SyncBackendRegistrar::SyncBackendRegistrar( + const std::string& name, + sync_driver::SyncClient* sync_client, + std::unique_ptr<base::Thread> sync_thread, + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, + const scoped_refptr<base::SingleThreadTaskRunner>& file_thread) + : name_(name), + sync_client_(sync_client), + ui_thread_(ui_thread), + db_thread_(db_thread), + file_thread_(file_thread) { + DCHECK(ui_thread_->BelongsToCurrentThread()); + DCHECK(sync_client_); + + sync_thread_ = std::move(sync_thread); + if (!sync_thread_) { + sync_thread_.reset(new base::Thread("Chrome_SyncThread")); + base::Thread::Options options; + options.timer_slack = base::TIMER_SLACK_MAXIMUM; + CHECK(sync_thread_->StartWithOptions(options)); + } + + MaybeAddWorker(syncer::GROUP_DB); + MaybeAddWorker(syncer::GROUP_FILE); + MaybeAddWorker(syncer::GROUP_UI); + MaybeAddWorker(syncer::GROUP_PASSIVE); + MaybeAddWorker(syncer::GROUP_HISTORY); + MaybeAddWorker(syncer::GROUP_PASSWORD); + + // Must have at least one worker for SyncBackendRegistrar to be destroyed + // correctly, as it is destroyed after the last worker dies. + DCHECK_GT(workers_.size(), 0u); +} + +void SyncBackendRegistrar::RegisterNonBlockingType(syncer::ModelType type) { + DCHECK(ui_thread_->BelongsToCurrentThread()); + base::AutoLock lock(lock_); + DCHECK(routing_info_.find(type) == routing_info_.end() || + routing_info_[type] == syncer::GROUP_NON_BLOCKING); + non_blocking_types_.Put(type); +} + +void SyncBackendRegistrar::SetInitialTypes(syncer::ModelTypeSet initial_types) { + base::AutoLock lock(lock_); + + // This function should be called only once, shortly after construction. The + // routing info at that point is expected to be empty. + DCHECK(routing_info_.empty()); + + // Set our initial state to reflect the current status of the sync directory. + // This will ensure that our calculations in ConfigureDataTypes() will always + // return correct results. + for (syncer::ModelTypeSet::Iterator it = initial_types.First(); it.Good(); + it.Inc()) { + routing_info_[it.Get()] = GetInitialGroupForType(it.Get()); + } + + if (!workers_.count(syncer::GROUP_HISTORY)) { + LOG_IF(WARNING, initial_types.Has(syncer::TYPED_URLS)) + << "History store disabled, cannot sync Omnibox History"; + routing_info_.erase(syncer::TYPED_URLS); + } + + if (!workers_.count(syncer::GROUP_PASSWORD)) { + LOG_IF(WARNING, initial_types.Has(syncer::PASSWORDS)) + << "Password store not initialized, cannot sync passwords"; + routing_info_.erase(syncer::PASSWORDS); + } + + last_configured_types_ = syncer::GetRoutingInfoTypes(routing_info_); +} + +void SyncBackendRegistrar::AddRestoredNonBlockingType(syncer::ModelType type) { + DCHECK(ui_thread_->BelongsToCurrentThread()); + base::AutoLock lock(lock_); + DCHECK(non_blocking_types_.Has(type)); + DCHECK(routing_info_.find(type) == routing_info_.end()); + routing_info_[type] = syncer::GROUP_NON_BLOCKING; + last_configured_types_.Put(type); +} + +bool SyncBackendRegistrar::IsNigoriEnabled() const { + DCHECK(ui_thread_->BelongsToCurrentThread()); + base::AutoLock lock(lock_); + return routing_info_.find(syncer::NIGORI) != routing_info_.end(); +} + +syncer::ModelTypeSet SyncBackendRegistrar::ConfigureDataTypes( + syncer::ModelTypeSet types_to_add, + syncer::ModelTypeSet types_to_remove) { + DCHECK(Intersection(types_to_add, types_to_remove).Empty()); + syncer::ModelTypeSet filtered_types_to_add = types_to_add; + if (workers_.count(syncer::GROUP_HISTORY) == 0) { + LOG(WARNING) << "No history worker -- removing TYPED_URLS"; + filtered_types_to_add.Remove(syncer::TYPED_URLS); + } + if (workers_.count(syncer::GROUP_PASSWORD) == 0) { + LOG(WARNING) << "No password worker -- removing PASSWORDS"; + filtered_types_to_add.Remove(syncer::PASSWORDS); + } + + base::AutoLock lock(lock_); + syncer::ModelTypeSet newly_added_types; + for (syncer::ModelTypeSet::Iterator it = filtered_types_to_add.First(); + it.Good(); it.Inc()) { + // Add a newly specified data type as syncer::GROUP_PASSIVE into the + // routing_info, if it does not already exist. + if (routing_info_.count(it.Get()) == 0) { + routing_info_[it.Get()] = GetInitialGroupForType(it.Get()); + newly_added_types.Put(it.Get()); + } + } + for (syncer::ModelTypeSet::Iterator it = types_to_remove.First(); it.Good(); + it.Inc()) { + routing_info_.erase(it.Get()); + } + + // TODO(akalin): Use SVLOG/SLOG if we add any more logging. + DVLOG(1) << name_ << ": Adding types " + << syncer::ModelTypeSetToString(types_to_add) + << " (with newly-added types " + << syncer::ModelTypeSetToString(newly_added_types) + << ") and removing types " + << syncer::ModelTypeSetToString(types_to_remove) + << " to get new routing info " + << syncer::ModelSafeRoutingInfoToString(routing_info_); + last_configured_types_ = syncer::GetRoutingInfoTypes(routing_info_); + + return newly_added_types; +} + +syncer::ModelTypeSet SyncBackendRegistrar::GetLastConfiguredTypes() const { + return last_configured_types_; +} + +void SyncBackendRegistrar::RequestWorkerStopOnUIThread() { + DCHECK(ui_thread_->BelongsToCurrentThread()); + base::AutoLock lock(lock_); + for (WorkerMap::const_iterator it = workers_.begin(); it != workers_.end(); + ++it) { + it->second->RequestStop(); + } +} + +void SyncBackendRegistrar::ActivateDataType( + syncer::ModelType type, + syncer::ModelSafeGroup group, + sync_driver::ChangeProcessor* change_processor, + syncer::UserShare* user_share) { + DVLOG(1) << "Activate: " << syncer::ModelTypeToString(type); + + base::AutoLock lock(lock_); + // Ensure that the given data type is in the PASSIVE group. + syncer::ModelSafeRoutingInfo::iterator i = routing_info_.find(type); + DCHECK(i != routing_info_.end()); + DCHECK_EQ(i->second, syncer::GROUP_PASSIVE); + routing_info_[type] = group; + + // Add the data type's change processor to the list of change + // processors so it can receive updates. + DCHECK_EQ(processors_.count(type), 0U); + processors_[type] = change_processor; + + // Start the change processor. + change_processor->Start(user_share); + DCHECK(GetProcessorUnsafe(type)); +} + +void SyncBackendRegistrar::DeactivateDataType(syncer::ModelType type) { + DVLOG(1) << "Deactivate: " << syncer::ModelTypeToString(type); + + DCHECK(ui_thread_->BelongsToCurrentThread() || IsControlType(type)); + base::AutoLock lock(lock_); + + routing_info_.erase(type); + ignore_result(processors_.erase(type)); + DCHECK(!GetProcessorUnsafe(type)); +} + +bool SyncBackendRegistrar::IsTypeActivatedForTest( + syncer::ModelType type) const { + return GetProcessor(type) != NULL; +} + +void SyncBackendRegistrar::OnChangesApplied( + syncer::ModelType model_type, + int64_t model_version, + const syncer::BaseTransaction* trans, + const syncer::ImmutableChangeRecordList& changes) { + sync_driver::ChangeProcessor* processor = GetProcessor(model_type); + if (!processor) + return; + + processor->ApplyChangesFromSyncModel(trans, model_version, changes); +} + +void SyncBackendRegistrar::OnChangesComplete(syncer::ModelType model_type) { + sync_driver::ChangeProcessor* processor = GetProcessor(model_type); + if (!processor) + return; + + // This call just notifies the processor that it can commit; it + // already buffered any changes it plans to makes so needs no + // further information. + processor->CommitChangesFromSyncModel(); +} + +void SyncBackendRegistrar::GetWorkers( + std::vector<scoped_refptr<syncer::ModelSafeWorker>>* out) { + base::AutoLock lock(lock_); + out->clear(); + for (WorkerMap::const_iterator it = workers_.begin(); it != workers_.end(); + ++it) { + out->push_back(it->second.get()); + } +} + +void SyncBackendRegistrar::GetModelSafeRoutingInfo( + syncer::ModelSafeRoutingInfo* out) { + base::AutoLock lock(lock_); + syncer::ModelSafeRoutingInfo copy(routing_info_); + out->swap(copy); +} + +sync_driver::ChangeProcessor* SyncBackendRegistrar::GetProcessor( + syncer::ModelType type) const { + base::AutoLock lock(lock_); + sync_driver::ChangeProcessor* processor = GetProcessorUnsafe(type); + if (!processor) + return NULL; + + // We can only check if |processor| exists, as otherwise the type is + // mapped to syncer::GROUP_PASSIVE. + CHECK(IsCurrentThreadSafeForModel(type)); + return processor; +} + +sync_driver::ChangeProcessor* SyncBackendRegistrar::GetProcessorUnsafe( + syncer::ModelType type) const { + lock_.AssertAcquired(); + std::map<syncer::ModelType, sync_driver::ChangeProcessor*>::const_iterator + it = processors_.find(type); + + // Until model association happens for a datatype, it will not + // appear in the processors list. During this time, it is OK to + // drop changes on the floor (since model association has not + // happened yet). When the data type is activated, model + // association takes place then the change processor is added to the + // |processors_| list. + if (it == processors_.end()) + return NULL; + + return it->second; +} + +bool SyncBackendRegistrar::IsCurrentThreadSafeForModel( + syncer::ModelType model_type) const { + lock_.AssertAcquired(); + return IsOnThreadForGroup(model_type, + GetGroupForModelType(model_type, routing_info_)); +} + +bool SyncBackendRegistrar::IsOnThreadForGroup( + syncer::ModelType type, + syncer::ModelSafeGroup group) const { + switch (group) { + case syncer::GROUP_PASSIVE: + return IsControlType(type); + case syncer::GROUP_UI: + return ui_thread_->BelongsToCurrentThread(); + case syncer::GROUP_DB: + return db_thread_->BelongsToCurrentThread(); + case syncer::GROUP_FILE: + return file_thread_->BelongsToCurrentThread(); + case syncer::GROUP_HISTORY: + // TODO(sync): How to check we're on the right thread? + return type == syncer::TYPED_URLS; + case syncer::GROUP_PASSWORD: + // TODO(sync): How to check we're on the right thread? + return type == syncer::PASSWORDS; + case syncer::GROUP_NON_BLOCKING: + // IsOnThreadForGroup shouldn't be called for non-blocking types. + return false; + } + NOTREACHED(); + return false; +} + +SyncBackendRegistrar::~SyncBackendRegistrar() { + DCHECK(workers_.empty()); +} + +void SyncBackendRegistrar::OnWorkerLoopDestroyed(syncer::ModelSafeGroup group) { + RemoveWorker(group); +} + +void SyncBackendRegistrar::MaybeAddWorker(syncer::ModelSafeGroup group) { + const scoped_refptr<syncer::ModelSafeWorker> worker = + sync_client_->CreateModelWorkerForGroup(group, this); + if (worker) { + DCHECK(workers_.find(group) == workers_.end()); + workers_[group] = worker; + workers_[group]->RegisterForLoopDestruction(); + } +} + +void SyncBackendRegistrar::OnWorkerUnregistrationDone( + syncer::ModelSafeGroup group) { + RemoveWorker(group); +} + +void SyncBackendRegistrar::RemoveWorker(syncer::ModelSafeGroup group) { + DVLOG(1) << "Remove " << ModelSafeGroupToString(group) << " worker."; + + bool last_worker = false; + { + base::AutoLock al(lock_); + WorkerMap::iterator it = workers_.find(group); + CHECK(it != workers_.end()); + stopped_workers_.push_back(it->second); + workers_.erase(it); + last_worker = workers_.empty(); + } + + if (last_worker) { + // Self-destruction after last worker. + DVLOG(1) << "Destroy registrar on loop of " + << ModelSafeGroupToString(group); + delete this; + } +} + +std::unique_ptr<base::Thread> SyncBackendRegistrar::ReleaseSyncThread() { + return std::move(sync_thread_); +} + +void SyncBackendRegistrar::Shutdown() { + // All data types should have been deactivated by now. + DCHECK(processors_.empty()); + + // Unregister worker from observing loop destruction. + base::AutoLock al(lock_); + for (WorkerMap::iterator it = workers_.begin(); it != workers_.end(); ++it) { + it->second->UnregisterForLoopDestruction( + base::Bind(&SyncBackendRegistrar::OnWorkerUnregistrationDone, + base::Unretained(this))); + } +} + +base::Thread* SyncBackendRegistrar::sync_thread() { + return sync_thread_.get(); +} + +syncer::ModelSafeGroup SyncBackendRegistrar::GetInitialGroupForType( + syncer::ModelType type) const { + if (non_blocking_types_.Has(type)) + return syncer::GROUP_NON_BLOCKING; + else + return syncer::GROUP_PASSIVE; +} + +} // namespace browser_sync
diff --git a/components/sync/driver/glue/sync_backend_registrar.h b/components/sync/driver/glue/sync_backend_registrar.h new file mode 100644 index 0000000..6879f53f --- /dev/null +++ b/components/sync/driver/glue/sync_backend_registrar.h
@@ -0,0 +1,240 @@ +// 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. + +#ifndef COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_REGISTRAR_H_ +#define COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_REGISTRAR_H_ + +#include <stdint.h> + +#include <map> +#include <memory> +#include <string> +#include <vector> + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/synchronization/lock.h" +#include "base/threading/thread.h" +#include "components/sync/base/model_type.h" +#include "components/sync/core/sync_manager.h" +#include "components/sync/engine/model_safe_worker.h" + +class Profile; + +namespace base { +class MessageLoop; +} + +namespace syncer { +struct UserShare; +} // namespace syncer + +namespace sync_driver { +class ChangeProcessor; +class SyncClient; +} + +namespace browser_sync { + +class UIModelWorker; + +// A class that keep track of the workers, change processors, and +// routing info for the enabled sync types, and also routes change +// events to the right processors. +class SyncBackendRegistrar : public syncer::SyncManager::ChangeDelegate, + public syncer::WorkerLoopDestructionObserver { + public: + // |name| is used for debugging. Does not take ownership of |profile|. + // Must be created on the UI thread. + SyncBackendRegistrar( + const std::string& name, + sync_driver::SyncClient* sync_client, + std::unique_ptr<base::Thread> sync_thread, + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, + const scoped_refptr<base::SingleThreadTaskRunner>& file_thread); + + // SyncBackendRegistrar must be destroyed as follows: + // + // 1) On the UI thread, call RequestWorkerStopOnUIThread(). + // 2) UI posts task to shut down syncer on sync thread. + // 3) If sync is disabled, call ReleaseSyncThread() on the UI thread. + // 3) UI posts SyncBackendRegistrar::ShutDown() on sync thread to + // unregister workers from observing destruction of their working loops. + // 4) Workers notify registrar when unregistration finishes or working + // loops are destroyed. Registrar destroys itself on last worker + // notification. Sync thread will be stopped if ownership was not + // released. + ~SyncBackendRegistrar() override; + + // Adds |type| to set of non-blocking types. These types are assigned to + // GROUP_NON_BLOCKING model safe group and will be treated differently in + // ModelTypeRegistry. Unlike directory types, non-blocking types always stay + // assigned to GROUP_NON_BLOCKING group. + void RegisterNonBlockingType(syncer::ModelType type); + + // Informs the SyncBackendRegistrar of the currently enabled set of types. + // These types will be placed in the passive group. This function should be + // called exactly once during startup. + void SetInitialTypes(syncer::ModelTypeSet initial_types); + + // Informs SyncBackendRegistrar about non-blocking type loaded from local + // storage. Initial sync was already performed for this type, therefore its + // data shouldn't be downloaded as part of configuration. + void AddRestoredNonBlockingType(syncer::ModelType type); + + // Returns whether or not we are currently syncing encryption keys. + // Must be called on the UI thread. + bool IsNigoriEnabled() const; + + // Removes all types in |types_to_remove| from the routing info and + // adds all the types in |types_to_add| to the routing info that are + // not already there (initially put in the passive group). + // |types_to_remove| and |types_to_add| must be disjoint. Returns + // the set of newly-added types. Must be called on the UI thread. + syncer::ModelTypeSet ConfigureDataTypes(syncer::ModelTypeSet types_to_add, + syncer::ModelTypeSet types_to_remove); + + // Returns the set of enabled types as of the last configuration. Note that + // this might be different from the current types in the routing info due + // to DeactiveDataType being called separately from ConfigureDataTypes. + syncer::ModelTypeSet GetLastConfiguredTypes() const; + + // Must be called from the UI thread. (See destructor comment.) + void RequestWorkerStopOnUIThread(); + + // Activates the given data type (which should belong to the given + // group) and starts the given change processor. Must be called + // from |group|'s native thread. + void ActivateDataType(syncer::ModelType type, + syncer::ModelSafeGroup group, + sync_driver::ChangeProcessor* change_processor, + syncer::UserShare* user_share); + + // Deactivates the given type if necessary. Must be called from the + // UI thread and not |type|'s native thread. Yes, this is + // surprising: see http://crbug.com/92804. + void DeactivateDataType(syncer::ModelType type); + + // Returns true only between calls to ActivateDataType(type, ...) + // and DeactivateDataType(type). Used only by tests. + bool IsTypeActivatedForTest(syncer::ModelType type) const; + + // SyncManager::ChangeDelegate implementation. May be called from + // any thread. + void OnChangesApplied( + syncer::ModelType model_type, + int64_t model_version, + const syncer::BaseTransaction* trans, + const syncer::ImmutableChangeRecordList& changes) override; + void OnChangesComplete(syncer::ModelType model_type) override; + + void GetWorkers(std::vector<scoped_refptr<syncer::ModelSafeWorker>>* out); + void GetModelSafeRoutingInfo(syncer::ModelSafeRoutingInfo* out); + + // syncer::WorkerLoopDestructionObserver implementation. + void OnWorkerLoopDestroyed(syncer::ModelSafeGroup group) override; + + // Release ownership of |sync_thread_|. Called when sync is disabled. + std::unique_ptr<base::Thread> ReleaseSyncThread(); + + // Unregister workers from loop destruction observation. + void Shutdown(); + + base::Thread* sync_thread(); + + private: + typedef std::map<syncer::ModelSafeGroup, + scoped_refptr<syncer::ModelSafeWorker>> + WorkerMap; + typedef std::map<syncer::ModelType, sync_driver::ChangeProcessor*> + ProcessorMap; + + // Add a worker for |group| to the worker map if one can be created. + void MaybeAddWorker(syncer::ModelSafeGroup group); + + // Callback after workers unregister from observing destruction of their + // working loops. + void OnWorkerUnregistrationDone(syncer::ModelSafeGroup group); + + void RemoveWorker(syncer::ModelSafeGroup group); + + // Returns the change processor for the given model, or NULL if none + // exists. Must be called from |group|'s native thread. + sync_driver::ChangeProcessor* GetProcessor(syncer::ModelType type) const; + + // Must be called with |lock_| held. Simply returns the change + // processor for the given type, if it exists. May be called from + // any thread. + sync_driver::ChangeProcessor* GetProcessorUnsafe( + syncer::ModelType type) const; + + // Return true if |model_type| lives on the current thread. Must be + // called with |lock_| held. May be called on any thread. + bool IsCurrentThreadSafeForModel(syncer::ModelType model_type) const; + + // Returns true if the current thread is the native thread for the + // given group (or if it is undeterminable). + bool IsOnThreadForGroup(syncer::ModelType type, + syncer::ModelSafeGroup group) const; + + // Returns model safe group that should be assigned to type when it is first + // configured (before activation). Returns GROUP_PASSIVE for directory types + // and GROUP_NON_BLOCKING for non-blocking types. + syncer::ModelSafeGroup GetInitialGroupForType(syncer::ModelType type) const; + + // Name used for debugging. + const std::string name_; + + // A pointer to the sync client. + sync_driver::SyncClient* const sync_client_; + + // Protects all variables below. + mutable base::Lock lock_; + + // We maintain ownership of all workers. In some cases, we need to + // ensure shutdown occurs in an expected sequence by Stop()ing + // certain workers. They are guaranteed to be valid because we only + // destroy elements of |workers_| after the syncapi has been + // destroyed. Unless a worker is no longer needed because all types + // that get routed to it have been disabled (from syncing). In that + // case, we'll destroy on demand *after* routing any dependent types + // to syncer::GROUP_PASSIVE, so that the syncapi doesn't call into garbage. + // If a key is present, it means at least one ModelType that routes + // to that model safe group is being synced. + WorkerMap workers_; + syncer::ModelSafeRoutingInfo routing_info_; + + // The change processors that handle the different data types. + ProcessorMap processors_; + + // The types that were enabled as of the last configuration. Updated on each + // call to ConfigureDataTypes as well as SetInitialTypes. + syncer::ModelTypeSet last_configured_types_; + + // Parks stopped workers because they may still be referenced by syncer. + std::vector<scoped_refptr<syncer::ModelSafeWorker>> stopped_workers_; + + // References to the thread task runners that sync depends on. + const scoped_refptr<base::SingleThreadTaskRunner> ui_thread_; + const scoped_refptr<base::SingleThreadTaskRunner> db_thread_; + const scoped_refptr<base::SingleThreadTaskRunner> file_thread_; + + // Declare |sync_thread_| at the end so that it will be destroyed before + // objects above because tasks on sync thread depend on those objects, + // e.g. Shutdown() depends on |lock_|, SyncManager::Init() depends on + // workers, etc. + std::unique_ptr<base::Thread> sync_thread_; + + // Set of types with non-blocking implementation (as opposed to directory + // based). + syncer::ModelTypeSet non_blocking_types_; + + DISALLOW_COPY_AND_ASSIGN(SyncBackendRegistrar); +}; + +} // namespace browser_sync + +#endif // COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_REGISTRAR_H_
diff --git a/components/sync/driver/glue/sync_backend_registrar_unittest.cc b/components/sync/driver/glue/sync_backend_registrar_unittest.cc new file mode 100644 index 0000000..d24424db --- /dev/null +++ b/components/sync/driver/glue/sync_backend_registrar_unittest.cc
@@ -0,0 +1,461 @@ +// 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. + +#include "components/sync/driver/glue/sync_backend_registrar.h" + +#include "base/location.h" +#include "base/run_loop.h" +#include "base/single_thread_task_runner.h" +#include "components/sync/base/model_type.h" +#include "components/sync/core/test/test_user_share.h" +#include "components/sync/driver/change_processor_mock.h" +#include "components/sync/driver/fake_sync_client.h" +#include "components/sync/driver/glue/browser_thread_model_worker.h" +#include "components/sync/driver/sync_api_component_factory_mock.h" +#include "components/sync/engine/passive_model_worker.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace browser_sync { + +namespace { + +using ::testing::_; +using ::testing::InSequence; +using ::testing::Return; +using ::testing::StrictMock; +using syncer::FIRST_REAL_MODEL_TYPE; +using syncer::AUTOFILL; +using syncer::BOOKMARKS; +using syncer::PREFERENCES; +using syncer::THEMES; +using syncer::NIGORI; +using syncer::PASSWORDS; +using syncer::MODEL_TYPE_COUNT; +using syncer::ModelTypeSet; +using syncer::ModelType; +using syncer::ModelTypeFromInt; + +void TriggerChanges(SyncBackendRegistrar* registrar, ModelType type) { + registrar->OnChangesApplied(type, 0, NULL, + syncer::ImmutableChangeRecordList()); + registrar->OnChangesComplete(type); +} + +class RegistrarSyncClient : public sync_driver::FakeSyncClient { + public: + RegistrarSyncClient( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner, + const scoped_refptr<base::SingleThreadTaskRunner>& db_task_runner, + const scoped_refptr<base::SingleThreadTaskRunner>& file_task_runner) + : ui_task_runner_(ui_task_runner), + db_task_runner_(db_task_runner), + file_task_runner_(file_task_runner) {} + + scoped_refptr<syncer::ModelSafeWorker> CreateModelWorkerForGroup( + syncer::ModelSafeGroup group, + syncer::WorkerLoopDestructionObserver* observer) override { + switch (group) { + case syncer::GROUP_UI: + return new BrowserThreadModelWorker(ui_task_runner_, group, observer); + case syncer::GROUP_DB: + return new BrowserThreadModelWorker(db_task_runner_, group, observer); + case syncer::GROUP_FILE: + return new BrowserThreadModelWorker(file_task_runner_, group, observer); + case syncer::GROUP_PASSIVE: + return new syncer::PassiveModelWorker(observer); + default: + return nullptr; + } + } + + private: + const scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; + const scoped_refptr<base::SingleThreadTaskRunner> db_task_runner_; + const scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_; +}; + +// Flaky: https://crbug.com/498238 +class SyncBackendRegistrarTest : public testing::Test { + public: + void TestNonUIDataTypeActivationAsync(sync_driver::ChangeProcessor* processor, + base::WaitableEvent* done) { + registrar_->ActivateDataType(AUTOFILL, syncer::GROUP_DB, processor, + test_user_share_.user_share()); + syncer::ModelSafeRoutingInfo expected_routing_info; + expected_routing_info[AUTOFILL] = syncer::GROUP_DB; + ExpectRoutingInfo(registrar_.get(), expected_routing_info); + ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet(AUTOFILL)); + TriggerChanges(registrar_.get(), AUTOFILL); + done->Signal(); + } + + protected: + SyncBackendRegistrarTest() + : db_thread_("DBThreadForTest"), + file_thread_("FileThreadForTest"), + sync_thread_(NULL) {} + + ~SyncBackendRegistrarTest() override {} + + void SetUp() override { + db_thread_.StartAndWaitForTesting(); + file_thread_.StartAndWaitForTesting(); + test_user_share_.SetUp(); + sync_client_.reset(new RegistrarSyncClient( + ui_task_runner(), db_task_runner(), file_task_runner())); + registrar_.reset(new SyncBackendRegistrar( + "test", sync_client_.get(), std::unique_ptr<base::Thread>(), + ui_task_runner(), db_task_runner(), file_task_runner())); + sync_thread_ = registrar_->sync_thread(); + } + + void TearDown() override { + registrar_->RequestWorkerStopOnUIThread(); + test_user_share_.TearDown(); + sync_thread_->task_runner()->PostTask( + FROM_HERE, base::Bind(&SyncBackendRegistrar::Shutdown, + base::Unretained(registrar_.release()))); + sync_thread_->WaitUntilThreadStarted(); + base::RunLoop().RunUntilIdle(); + } + + void ExpectRoutingInfo( + SyncBackendRegistrar* registrar, + const syncer::ModelSafeRoutingInfo& expected_routing_info) { + syncer::ModelSafeRoutingInfo routing_info; + registrar->GetModelSafeRoutingInfo(&routing_info); + EXPECT_EQ(expected_routing_info, routing_info); + } + + void ExpectHasProcessorsForTypes(const SyncBackendRegistrar& registrar, + ModelTypeSet types) { + for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { + ModelType model_type = ModelTypeFromInt(i); + EXPECT_EQ(types.Has(model_type), + registrar_->IsTypeActivatedForTest(model_type)); + } + } + + const scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner() { + return message_loop_.task_runner(); + } + + const scoped_refptr<base::SingleThreadTaskRunner> db_task_runner() { + return db_thread_.task_runner(); + } + + const scoped_refptr<base::SingleThreadTaskRunner> file_task_runner() { + return db_thread_.task_runner(); + } + + base::MessageLoop message_loop_; + base::Thread db_thread_; + base::Thread file_thread_; + + syncer::TestUserShare test_user_share_; + std::unique_ptr<RegistrarSyncClient> sync_client_; + std::unique_ptr<SyncBackendRegistrar> registrar_; + + base::Thread* sync_thread_; +}; + +TEST_F(SyncBackendRegistrarTest, ConstructorEmpty) { + registrar_->SetInitialTypes(ModelTypeSet()); + EXPECT_FALSE(registrar_->IsNigoriEnabled()); + { + std::vector<scoped_refptr<syncer::ModelSafeWorker>> workers; + registrar_->GetWorkers(&workers); + EXPECT_EQ(4u, workers.size()); + } + ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo()); + ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet()); +} + +TEST_F(SyncBackendRegistrarTest, ConstructorNonEmpty) { + const ModelTypeSet initial_types(BOOKMARKS, NIGORI, PASSWORDS); + registrar_->RegisterNonBlockingType(BOOKMARKS); + registrar_->SetInitialTypes(initial_types); + EXPECT_TRUE(registrar_->IsNigoriEnabled()); + { + std::vector<scoped_refptr<syncer::ModelSafeWorker>> workers; + registrar_->GetWorkers(&workers); + EXPECT_EQ(4u, workers.size()); + } + { + syncer::ModelSafeRoutingInfo expected_routing_info; + expected_routing_info[BOOKMARKS] = syncer::GROUP_NON_BLOCKING; + expected_routing_info[NIGORI] = syncer::GROUP_PASSIVE; + // Passwords dropped because of no password store. + ExpectRoutingInfo(registrar_.get(), expected_routing_info); + } + ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet()); +} + +TEST_F(SyncBackendRegistrarTest, ConfigureDataTypes) { + registrar_->RegisterNonBlockingType(BOOKMARKS); + registrar_->SetInitialTypes(ModelTypeSet()); + + // Add. + const ModelTypeSet types1(BOOKMARKS, NIGORI, AUTOFILL); + EXPECT_EQ(types1, registrar_->ConfigureDataTypes(types1, ModelTypeSet())); + { + syncer::ModelSafeRoutingInfo expected_routing_info; + expected_routing_info[BOOKMARKS] = syncer::GROUP_NON_BLOCKING; + expected_routing_info[NIGORI] = syncer::GROUP_PASSIVE; + expected_routing_info[AUTOFILL] = syncer::GROUP_PASSIVE; + ExpectRoutingInfo(registrar_.get(), expected_routing_info); + } + ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet()); + EXPECT_EQ(types1, registrar_->GetLastConfiguredTypes()); + + // Add and remove. + const ModelTypeSet types2(PREFERENCES, THEMES); + EXPECT_EQ(types2, registrar_->ConfigureDataTypes(types2, types1)); + { + syncer::ModelSafeRoutingInfo expected_routing_info; + expected_routing_info[PREFERENCES] = syncer::GROUP_PASSIVE; + expected_routing_info[THEMES] = syncer::GROUP_PASSIVE; + ExpectRoutingInfo(registrar_.get(), expected_routing_info); + } + ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet()); + EXPECT_EQ(types2, registrar_->GetLastConfiguredTypes()); + + // Remove. + EXPECT_TRUE(registrar_->ConfigureDataTypes(ModelTypeSet(), types2).Empty()); + ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo()); + ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet()); + EXPECT_EQ(ModelTypeSet(), registrar_->GetLastConfiguredTypes()); +} + +TEST_F(SyncBackendRegistrarTest, ActivateDeactivateUIDataType) { + InSequence in_sequence; + registrar_->SetInitialTypes(ModelTypeSet()); + + // Should do nothing. + TriggerChanges(registrar_.get(), BOOKMARKS); + + StrictMock<sync_driver::ChangeProcessorMock> change_processor_mock; + EXPECT_CALL(change_processor_mock, StartImpl()); + EXPECT_CALL(change_processor_mock, IsRunning()).WillRepeatedly(Return(true)); + EXPECT_CALL(change_processor_mock, ApplyChangesFromSyncModel(NULL, _, _)); + EXPECT_CALL(change_processor_mock, IsRunning()).WillRepeatedly(Return(true)); + EXPECT_CALL(change_processor_mock, CommitChangesFromSyncModel()); + EXPECT_CALL(change_processor_mock, IsRunning()).WillRepeatedly(Return(false)); + + const ModelTypeSet types(BOOKMARKS); + EXPECT_EQ(types, registrar_->ConfigureDataTypes(types, ModelTypeSet())); + registrar_->ActivateDataType(BOOKMARKS, syncer::GROUP_UI, + &change_processor_mock, + test_user_share_.user_share()); + { + syncer::ModelSafeRoutingInfo expected_routing_info; + expected_routing_info[BOOKMARKS] = syncer::GROUP_UI; + ExpectRoutingInfo(registrar_.get(), expected_routing_info); + } + ExpectHasProcessorsForTypes(*registrar_, types); + + TriggerChanges(registrar_.get(), BOOKMARKS); + + registrar_->DeactivateDataType(BOOKMARKS); + ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo()); + ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet()); + + // Should do nothing. + TriggerChanges(registrar_.get(), BOOKMARKS); +} + +TEST_F(SyncBackendRegistrarTest, ActivateDeactivateNonUIDataType) { + InSequence in_sequence; + registrar_->SetInitialTypes(ModelTypeSet()); + + // Should do nothing. + TriggerChanges(registrar_.get(), AUTOFILL); + + StrictMock<sync_driver::ChangeProcessorMock> change_processor_mock; + EXPECT_CALL(change_processor_mock, StartImpl()); + EXPECT_CALL(change_processor_mock, IsRunning()).WillRepeatedly(Return(true)); + EXPECT_CALL(change_processor_mock, ApplyChangesFromSyncModel(NULL, _, _)); + EXPECT_CALL(change_processor_mock, IsRunning()).WillRepeatedly(Return(true)); + EXPECT_CALL(change_processor_mock, CommitChangesFromSyncModel()); + EXPECT_CALL(change_processor_mock, IsRunning()).WillRepeatedly(Return(false)); + + const ModelTypeSet types(AUTOFILL); + EXPECT_EQ(types, registrar_->ConfigureDataTypes(types, ModelTypeSet())); + + base::WaitableEvent done(base::WaitableEvent::ResetPolicy::AUTOMATIC, + base::WaitableEvent::InitialState::NOT_SIGNALED); + db_task_runner()->PostTask( + FROM_HERE, + base::Bind(&SyncBackendRegistrarTest::TestNonUIDataTypeActivationAsync, + base::Unretained(this), &change_processor_mock, &done)); + done.Wait(); + + registrar_->DeactivateDataType(AUTOFILL); + ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo()); + ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet()); + + // Should do nothing. + TriggerChanges(registrar_.get(), AUTOFILL); +} + +// Tests that registration and configuration of non-blocking data types is +// handled correctly in SyncBackendRegistrar. +TEST_F(SyncBackendRegistrarTest, ConfigureNonBlockingDataType) { + registrar_->RegisterNonBlockingType(AUTOFILL); + registrar_->RegisterNonBlockingType(BOOKMARKS); + + ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo()); + // Simulate that initial sync was already done for AUTOFILL. + registrar_->AddRestoredNonBlockingType(AUTOFILL); + // It should be added to routing info and set of configured types. + EXPECT_EQ(ModelTypeSet(AUTOFILL), registrar_->GetLastConfiguredTypes()); + { + syncer::ModelSafeRoutingInfo expected_routing_info; + expected_routing_info[AUTOFILL] = syncer::GROUP_NON_BLOCKING; + ExpectRoutingInfo(registrar_.get(), expected_routing_info); + } + + // Configure two non-blocking types. Initial sync wasn't done for BOOKMARKS so + // it should be included in types to be downloaded. + ModelTypeSet types_to_add(AUTOFILL, BOOKMARKS); + ModelTypeSet newly_added_types = + registrar_->ConfigureDataTypes(types_to_add, ModelTypeSet()); + EXPECT_EQ(ModelTypeSet(BOOKMARKS), newly_added_types); + EXPECT_EQ(types_to_add, registrar_->GetLastConfiguredTypes()); + { + syncer::ModelSafeRoutingInfo expected_routing_info; + expected_routing_info[AUTOFILL] = syncer::GROUP_NON_BLOCKING; + expected_routing_info[BOOKMARKS] = syncer::GROUP_NON_BLOCKING; + ExpectRoutingInfo(registrar_.get(), expected_routing_info); + } +} + +class SyncBackendRegistrarShutdownTest : public testing::Test { + public: + void BlockDBThread() { + EXPECT_FALSE(db_thread_lock_.Try()); + + db_thread_blocked_.Signal(); + base::AutoLock l(db_thread_lock_); + } + + protected: + friend class TestRegistrar; + + SyncBackendRegistrarShutdownTest() + : db_thread_("DBThreadForTest"), + file_thread_("FileThreadForTest"), + db_thread_blocked_(base::WaitableEvent::ResetPolicy::AUTOMATIC, + base::WaitableEvent::InitialState::NOT_SIGNALED) { + quit_closure_ = run_loop_.QuitClosure(); + } + + ~SyncBackendRegistrarShutdownTest() override {} + + void SetUp() override { + db_thread_.StartAndWaitForTesting(); + file_thread_.StartAndWaitForTesting(); + sync_client_.reset(new RegistrarSyncClient( + ui_task_runner(), db_task_runner(), file_task_runner())); + } + + void PostQuitOnUIMessageLoop() { + ui_task_runner()->PostTask(FROM_HERE, quit_closure_); + } + + const scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner() { + return message_loop_.task_runner(); + } + + const scoped_refptr<base::SingleThreadTaskRunner> db_task_runner() { + return db_thread_.task_runner(); + } + + const scoped_refptr<base::SingleThreadTaskRunner> file_task_runner() { + return file_thread_.task_runner(); + } + + base::MessageLoop message_loop_; + base::Thread db_thread_; + base::Thread file_thread_; + + std::unique_ptr<RegistrarSyncClient> sync_client_; + base::WaitableEvent db_thread_blocked_; + + base::Lock db_thread_lock_; + base::RunLoop run_loop_; + base::Closure quit_closure_; +}; + +// Wrap SyncBackendRegistrar so that we can monitor its lifetime. +class TestRegistrar : public SyncBackendRegistrar { + public: + explicit TestRegistrar( + sync_driver::SyncClient* sync_client, + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, + const scoped_refptr<base::SingleThreadTaskRunner>& file_thread, + SyncBackendRegistrarShutdownTest* test) + : SyncBackendRegistrar("test", + sync_client, + std::unique_ptr<base::Thread>(), + ui_thread, + db_thread, + file_thread), + test_(test) {} + + ~TestRegistrar() override { test_->PostQuitOnUIMessageLoop(); } + + private: + SyncBackendRegistrarShutdownTest* test_; +}; + +TEST_F(SyncBackendRegistrarShutdownTest, BlockingShutdown) { + // Take ownership of |db_thread_lock_| so that the DB thread can't acquire it. + db_thread_lock_.Acquire(); + + // This will block the DB thread by waiting on |db_thread_lock_|. + db_task_runner()->PostTask( + FROM_HERE, base::Bind(&SyncBackendRegistrarShutdownTest::BlockDBThread, + base::Unretained(this))); + + std::unique_ptr<TestRegistrar> registrar( + new TestRegistrar(sync_client_.get(), ui_task_runner(), db_task_runner(), + file_task_runner(), this)); + base::Thread* sync_thread = registrar->sync_thread(); + + // Stop here until the DB thread gets a chance to run and block on the lock. + // Please note that since the task above didn't finish, the task to + // initialize the worker on the DB thread hasn't had a chance to run yet too. + // Which means ModelSafeWorker::SetWorkingLoopToCurrent hasn't been called + // for the DB worker. + db_thread_blocked_.Wait(); + + registrar->SetInitialTypes(ModelTypeSet()); + + // Start the shutdown. + registrar->RequestWorkerStopOnUIThread(); + + sync_thread->task_runner()->PostTask( + FROM_HERE, base::Bind(&SyncBackendRegistrar::Shutdown, + base::Unretained(registrar.release()))); + + // Make sure the thread starts running. + sync_thread->WaitUntilThreadStarted(); + + // The test verifies that the sync thread doesn't block because + // of the blocked DB thread and can finish the shutdown. + base::RunLoop().RunUntilIdle(); + + db_thread_lock_.Release(); + + // Run the main thread loop until all workers have been removed and the + // registrar destroyed. + run_loop_.Run(); +} + +} // namespace + +} // namespace browser_sync
diff --git a/components/sync/driver/glue/ui_model_worker.cc b/components/sync/driver/glue/ui_model_worker.cc new file mode 100644 index 0000000..9df8711 --- /dev/null +++ b/components/sync/driver/glue/ui_model_worker.cc
@@ -0,0 +1,78 @@ +// 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/sync/driver/glue/ui_model_worker.h" + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/message_loop/message_loop.h" +#include "base/synchronization/waitable_event.h" +#include "base/third_party/dynamic_annotations/dynamic_annotations.h" +#include "base/threading/thread_restrictions.h" + +namespace browser_sync { + +namespace { + +// A simple callback to signal a waitable event after running a closure. +void CallDoWorkAndSignalCallback(const syncer::WorkCallback& work, + base::WaitableEvent* work_done, + syncer::SyncerError* error_info) { + if (work.is_null()) { + // This can happen during tests or cases where there are more than just the + // default UIModelWorker in existence and it gets destroyed before + // the main UI loop has terminated. There is no easy way to assert the + // loop is running / not running at the moment, so we just provide cancel + // semantics here and short-circuit. + // TODO(timsteele): Maybe we should have the message loop destruction + // observer fire when the loop has ended, just a bit before it + // actually gets destroyed. + return; + } + + *error_info = work.Run(); + + work_done->Signal(); // Unblock the syncer thread that scheduled us. +} + +} // namespace + +UIModelWorker::UIModelWorker( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + syncer::WorkerLoopDestructionObserver* observer) + : syncer::ModelSafeWorker(observer), ui_thread_(ui_thread) {} + +void UIModelWorker::RegisterForLoopDestruction() { + CHECK(ui_thread_->BelongsToCurrentThread()); + SetWorkingLoopToCurrent(); +} + +syncer::SyncerError UIModelWorker::DoWorkAndWaitUntilDoneImpl( + const syncer::WorkCallback& work) { + syncer::SyncerError error_info; + if (ui_thread_->BelongsToCurrentThread()) { + DLOG(WARNING) << "DoWorkAndWaitUntilDone called from " + << "ui_loop_. Probably a nested invocation?"; + return work.Run(); + } + + if (!ui_thread_->PostTask(FROM_HERE, + base::Bind(&CallDoWorkAndSignalCallback, work, + work_done_or_stopped(), &error_info))) { + DLOG(WARNING) << "Could not post work to UI loop."; + error_info = syncer::CANNOT_DO_WORK; + return error_info; + } + work_done_or_stopped()->Wait(); + + return error_info; +} + +syncer::ModelSafeGroup UIModelWorker::GetModelSafeGroup() { + return syncer::GROUP_UI; +} + +UIModelWorker::~UIModelWorker() {} + +} // namespace browser_sync
diff --git a/components/sync_driver/glue/ui_model_worker.h b/components/sync/driver/glue/ui_model_worker.h similarity index 100% rename from components/sync_driver/glue/ui_model_worker.h rename to components/sync/driver/glue/ui_model_worker.h
diff --git a/components/sync/driver/glue/ui_model_worker_unittest.cc b/components/sync/driver/glue/ui_model_worker_unittest.cc new file mode 100644 index 0000000..7ad15d9 --- /dev/null +++ b/components/sync/driver/glue/ui_model_worker_unittest.cc
@@ -0,0 +1,102 @@ +// 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/sync/driver/glue/ui_model_worker.h" + +#include <memory> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/callback.h" +#include "base/location.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/run_loop.h" +#include "base/single_thread_task_runner.h" +#include "base/synchronization/waitable_event.h" +#include "base/threading/thread.h" +#include "base/threading/thread_task_runner_handle.h" +#include "testing/gtest/include/gtest/gtest.h" + +using browser_sync::UIModelWorker; +using syncer::SyncerError; + +class UIModelWorkerVisitor { + public: + UIModelWorkerVisitor(base::WaitableEvent* was_run, bool quit_loop) + : quit_loop_when_run_(quit_loop), was_run_(was_run) {} + virtual ~UIModelWorkerVisitor() {} + + virtual syncer::SyncerError DoWork() { + was_run_->Signal(); + if (quit_loop_when_run_) + base::MessageLoop::current()->QuitWhenIdle(); + return syncer::SYNCER_OK; + } + + private: + bool quit_loop_when_run_; + base::WaitableEvent* was_run_; + DISALLOW_COPY_AND_ASSIGN(UIModelWorkerVisitor); +}; + +// A faux-syncer that only interacts with its model safe worker. +class Syncer { + public: + explicit Syncer(UIModelWorker* worker) : worker_(worker) {} + ~Syncer() {} + + void SyncShare(UIModelWorkerVisitor* visitor) { + // We wait until the callback is executed. So it is safe to use Unretained. + syncer::WorkCallback c = + base::Bind(&UIModelWorkerVisitor::DoWork, base::Unretained(visitor)); + worker_->DoWorkAndWaitUntilDone(c); + } + + private: + scoped_refptr<UIModelWorker> worker_; + DISALLOW_COPY_AND_ASSIGN(Syncer); +}; + +class SyncUIModelWorkerTest : public testing::Test { + public: + SyncUIModelWorkerTest() + : faux_syncer_thread_("FauxSyncerThread"), + faux_core_thread_("FauxCoreThread") {} + + void SetUp() override { + faux_syncer_thread_.Start(); + bmw_ = new UIModelWorker(base::ThreadTaskRunnerHandle::Get(), nullptr); + syncer_.reset(new Syncer(bmw_.get())); + } + + Syncer* syncer() { return syncer_.get(); } + UIModelWorker* bmw() { return bmw_.get(); } + base::Thread* core_thread() { return &faux_core_thread_; } + base::Thread* syncer_thread() { return &faux_syncer_thread_; } + + private: + base::MessageLoop faux_ui_loop_; + base::Thread faux_syncer_thread_; + base::Thread faux_core_thread_; + scoped_refptr<UIModelWorker> bmw_; + std::unique_ptr<Syncer> syncer_; +}; + +TEST_F(SyncUIModelWorkerTest, ScheduledWorkRunsOnUILoop) { + base::WaitableEvent v_was_run( + base::WaitableEvent::ResetPolicy::AUTOMATIC, + base::WaitableEvent::InitialState::NOT_SIGNALED); + std::unique_ptr<UIModelWorkerVisitor> v( + new UIModelWorkerVisitor(&v_was_run, true)); + + syncer_thread()->task_runner()->PostTask( + FROM_HERE, + base::Bind(&Syncer::SyncShare, base::Unretained(syncer()), v.get())); + + // We are on the UI thread, so run our loop to process the + // (hopefully) scheduled task from a SyncShare invocation. + base::RunLoop().Run(); + syncer_thread()->Stop(); +}
diff --git a/components/sync/driver/invalidation_adapter.cc b/components/sync/driver/invalidation_adapter.cc new file mode 100644 index 0000000..2142641 --- /dev/null +++ b/components/sync/driver/invalidation_adapter.cc
@@ -0,0 +1,37 @@ +// 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 "components/sync/driver/invalidation_adapter.h" + +#include <string> + +namespace browser_sync { + +InvalidationAdapter::InvalidationAdapter( + const syncer::Invalidation& invalidation) + : invalidation_(invalidation) {} + +InvalidationAdapter::~InvalidationAdapter() {} + +bool InvalidationAdapter::IsUnknownVersion() const { + return invalidation_.is_unknown_version(); +} + +const std::string& InvalidationAdapter::GetPayload() const { + return invalidation_.payload(); +} + +int64_t InvalidationAdapter::GetVersion() const { + return invalidation_.version(); +} + +void InvalidationAdapter::Acknowledge() { + invalidation_.Acknowledge(); +} + +void InvalidationAdapter::Drop() { + invalidation_.Drop(); +} + +} // namespace browser_sync
diff --git a/components/sync_driver/invalidation_adapter.h b/components/sync/driver/invalidation_adapter.h similarity index 100% rename from components/sync_driver/invalidation_adapter.h rename to components/sync/driver/invalidation_adapter.h
diff --git a/components/sync/driver/invalidation_helper.cc b/components/sync/driver/invalidation_helper.cc new file mode 100644 index 0000000..e28cd1d5 --- /dev/null +++ b/components/sync/driver/invalidation_helper.cc
@@ -0,0 +1,37 @@ +// 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 "components/sync/driver/invalidation_helper.h" + +#include <string> + +#include "google/cacheinvalidation/types.pb.h" + +namespace syncer { + +bool RealModelTypeToObjectId(ModelType model_type, + invalidation::ObjectId* object_id) { + std::string notification_type; + if (!RealModelTypeToNotificationType(model_type, ¬ification_type)) { + return false; + } + object_id->Init(ipc::invalidation::ObjectSource::CHROME_SYNC, + notification_type); + return true; +} + +ObjectIdSet ModelTypeSetToObjectIdSet(ModelTypeSet model_types) { + ObjectIdSet ids; + for (ModelTypeSet::Iterator it = model_types.First(); it.Good(); it.Inc()) { + invalidation::ObjectId model_type_as_id; + if (!RealModelTypeToObjectId(it.Get(), &model_type_as_id)) { + DLOG(WARNING) << "Invalid model type " << it.Get(); + continue; + } + ids.insert(model_type_as_id); + } + return ids; +} + +} // namespace syncer
diff --git a/components/sync/driver/invalidation_helper.h b/components/sync/driver/invalidation_helper.h new file mode 100644 index 0000000..69b6a66 --- /dev/null +++ b/components/sync/driver/invalidation_helper.h
@@ -0,0 +1,21 @@ +// 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 COMPONENTS_SYNC_DRIVER_INVALIDATION_HELPER_H_ +#define COMPONENTS_SYNC_DRIVER_INVALIDATION_HELPER_H_ + +#include "components/invalidation/public/invalidation_util.h" +#include "components/sync/base/model_type.h" +#include "google/cacheinvalidation/include/types.h" + +namespace syncer { + +bool RealModelTypeToObjectId(ModelType model_type, + invalidation::ObjectId* object_id); + +ObjectIdSet ModelTypeSetToObjectIdSet(ModelTypeSet model_types); + +} // namespace syncer + +#endif // COMPONENTS_SYNC_DRIVER_INVALIDATION_HELPER_H_
diff --git a/components/sync_driver/local_device_info_provider.h b/components/sync/driver/local_device_info_provider.h similarity index 100% rename from components/sync_driver/local_device_info_provider.h rename to components/sync/driver/local_device_info_provider.h
diff --git a/components/sync/driver/local_device_info_provider_impl.cc b/components/sync/driver/local_device_info_provider_impl.cc new file mode 100644 index 0000000..33ba395 --- /dev/null +++ b/components/sync/driver/local_device_info_provider_impl.cc
@@ -0,0 +1,112 @@ +// 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 "components/sync/driver/local_device_info_provider_impl.h" + +#include "base/bind.h" +#include "base/task_runner.h" +#include "build/build_config.h" +#include "components/sync/base/get_session_name.h" +#include "components/sync/driver/sync_util.h" + +namespace browser_sync { + +namespace { + +sync_pb::SyncEnums::DeviceType GetLocalDeviceType(bool is_tablet) { +#if defined(OS_CHROMEOS) + return sync_pb::SyncEnums_DeviceType_TYPE_CROS; +#elif defined(OS_LINUX) + return sync_pb::SyncEnums_DeviceType_TYPE_LINUX; +#elif defined(OS_ANDROID) || defined(OS_IOS) + return is_tablet ? sync_pb::SyncEnums_DeviceType_TYPE_TABLET + : sync_pb::SyncEnums_DeviceType_TYPE_PHONE; +#elif defined(OS_MACOSX) + return sync_pb::SyncEnums_DeviceType_TYPE_MAC; +#elif defined(OS_WIN) + return sync_pb::SyncEnums_DeviceType_TYPE_WIN; +#else + return sync_pb::SyncEnums_DeviceType_TYPE_OTHER; +#endif +} + +} // namespace + +LocalDeviceInfoProviderImpl::LocalDeviceInfoProviderImpl( + version_info::Channel channel, + const std::string& version, + bool is_tablet) + : channel_(channel), + version_(version), + is_tablet_(is_tablet), + weak_factory_(this) { + DCHECK(CalledOnValidThread()); +} + +LocalDeviceInfoProviderImpl::~LocalDeviceInfoProviderImpl() {} + +const sync_driver::DeviceInfo* LocalDeviceInfoProviderImpl::GetLocalDeviceInfo() + const { + DCHECK(CalledOnValidThread()); + return local_device_info_.get(); +} + +std::string LocalDeviceInfoProviderImpl::GetSyncUserAgent() const { + DCHECK(CalledOnValidThread()); + return MakeUserAgentForSync(channel_, is_tablet_); +} + +std::string LocalDeviceInfoProviderImpl::GetLocalSyncCacheGUID() const { + DCHECK(CalledOnValidThread()); + return cache_guid_; +} + +std::unique_ptr<sync_driver::LocalDeviceInfoProvider::Subscription> +LocalDeviceInfoProviderImpl::RegisterOnInitializedCallback( + const base::Closure& callback) { + DCHECK(CalledOnValidThread()); + DCHECK(!local_device_info_.get()); + return callback_list_.Add(callback); +} + +void LocalDeviceInfoProviderImpl::Initialize( + const std::string& cache_guid, + const std::string& signin_scoped_device_id, + const scoped_refptr<base::TaskRunner>& blocking_task_runner) { + DCHECK(CalledOnValidThread()); + DCHECK(!cache_guid.empty()); + cache_guid_ = cache_guid; + + syncer::GetSessionName( + blocking_task_runner, + base::Bind(&LocalDeviceInfoProviderImpl::InitializeContinuation, + weak_factory_.GetWeakPtr(), cache_guid, + signin_scoped_device_id)); +} + +void LocalDeviceInfoProviderImpl::InitializeContinuation( + const std::string& guid, + const std::string& signin_scoped_device_id, + const std::string& session_name) { + DCHECK(CalledOnValidThread()); + if (guid != cache_guid_) { + // Clear() happened before this callback; abort. + return; + } + + local_device_info_.reset(new sync_driver::DeviceInfo( + guid, session_name, version_, GetSyncUserAgent(), + GetLocalDeviceType(is_tablet_), signin_scoped_device_id)); + + // Notify observers. + callback_list_.Notify(); +} + +void LocalDeviceInfoProviderImpl::Clear() { + DCHECK(CalledOnValidThread()); + cache_guid_ = ""; + local_device_info_.reset(); +} + +} // namespace browser_sync
diff --git a/components/sync/driver/local_device_info_provider_impl.h b/components/sync/driver/local_device_info_provider_impl.h new file mode 100644 index 0000000..51eaaf17 --- /dev/null +++ b/components/sync/driver/local_device_info_provider_impl.h
@@ -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. + +#ifndef COMPONENTS_SYNC_DRIVER_LOCAL_DEVICE_INFO_PROVIDER_IMPL_H_ +#define COMPONENTS_SYNC_DRIVER_LOCAL_DEVICE_INFO_PROVIDER_IMPL_H_ + +#include <string> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/threading/non_thread_safe.h" +#include "components/sync/driver/device_info.h" +#include "components/sync/driver/local_device_info_provider.h" +#include "components/version_info/version_info.h" + +namespace browser_sync { + +class LocalDeviceInfoProviderImpl : public sync_driver::LocalDeviceInfoProvider, + public base::NonThreadSafe { + public: + LocalDeviceInfoProviderImpl(version_info::Channel channel, + const std::string& version, + bool is_tablet); + ~LocalDeviceInfoProviderImpl() override; + + // LocalDeviceInfoProvider implementation. + const sync_driver::DeviceInfo* GetLocalDeviceInfo() const override; + std::string GetSyncUserAgent() const override; + std::string GetLocalSyncCacheGUID() const override; + void Initialize( + const std::string& cache_guid, + const std::string& signin_scoped_device_id, + const scoped_refptr<base::TaskRunner>& blocking_task_runner) override; + std::unique_ptr<Subscription> RegisterOnInitializedCallback( + const base::Closure& callback) override; + void Clear() override; + + private: + void InitializeContinuation(const std::string& guid, + const std::string& signin_scoped_device_id, + const std::string& session_name); + + // The channel (CANARY, DEV, BETA, etc.) of the current client. + const version_info::Channel channel_; + + // The version string for the current client. + const std::string version_; + + // Whether this device has a tablet form factor (only used on Android + // devices). + const bool is_tablet_; + + std::string cache_guid_; + std::unique_ptr<sync_driver::DeviceInfo> local_device_info_; + base::CallbackList<void(void)> callback_list_; + base::WeakPtrFactory<LocalDeviceInfoProviderImpl> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(LocalDeviceInfoProviderImpl); +}; + +} // namespace browser_sync + +#endif // COMPONENTS_SYNC_DRIVER_LOCAL_DEVICE_INFO_PROVIDER_IMPL_H_
diff --git a/components/sync/driver/local_device_info_provider_mock.cc b/components/sync/driver/local_device_info_provider_mock.cc new file mode 100644 index 0000000..c52297f --- /dev/null +++ b/components/sync/driver/local_device_info_provider_mock.cc
@@ -0,0 +1,74 @@ +// 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 "components/sync/driver/local_device_info_provider_mock.h" + +namespace sync_driver { + +LocalDeviceInfoProviderMock::LocalDeviceInfoProviderMock() + : is_initialized_(false) {} + +LocalDeviceInfoProviderMock::LocalDeviceInfoProviderMock( + const std::string& guid, + const std::string& client_name, + const std::string& chrome_version, + const std::string& sync_user_agent, + const sync_pb::SyncEnums::DeviceType device_type, + const std::string& signin_scoped_device_id) + : is_initialized_(true) { + local_device_info_.reset(new DeviceInfo(guid, client_name, chrome_version, + sync_user_agent, device_type, + signin_scoped_device_id)); +} + +LocalDeviceInfoProviderMock::~LocalDeviceInfoProviderMock() {} + +const DeviceInfo* LocalDeviceInfoProviderMock::GetLocalDeviceInfo() const { + return is_initialized_ ? local_device_info_.get() : nullptr; +} + +std::string LocalDeviceInfoProviderMock::GetSyncUserAgent() const { + return "useragent"; +} + +std::string LocalDeviceInfoProviderMock::GetLocalSyncCacheGUID() const { + return local_device_info_.get() ? local_device_info_->guid() : ""; +} + +void LocalDeviceInfoProviderMock::Initialize( + const std::string& cache_guid, + const std::string& signin_scoped_device_id, + const scoped_refptr<base::TaskRunner>& blocking_task_runner) { + local_device_info_.reset(new DeviceInfo( + cache_guid, "client_name", "chrome_version", GetSyncUserAgent(), + sync_pb::SyncEnums_DeviceType_TYPE_LINUX, signin_scoped_device_id)); + SetInitialized(true); +} + +void LocalDeviceInfoProviderMock::Initialize( + std::unique_ptr<DeviceInfo> local_device_info) { + local_device_info_.swap(local_device_info); + SetInitialized(true); +} + +std::unique_ptr<LocalDeviceInfoProvider::Subscription> +LocalDeviceInfoProviderMock::RegisterOnInitializedCallback( + const base::Closure& callback) { + DCHECK(!is_initialized_); + return callback_list_.Add(callback); +} + +void LocalDeviceInfoProviderMock::Clear() { + local_device_info_.reset(); + is_initialized_ = false; +} + +void LocalDeviceInfoProviderMock::SetInitialized(bool is_initialized) { + is_initialized_ = is_initialized; + if (is_initialized_) { + callback_list_.Notify(); + } +} + +} // namespace sync_driver
diff --git a/components/sync/driver/local_device_info_provider_mock.h b/components/sync/driver/local_device_info_provider_mock.h new file mode 100644 index 0000000..af332407 --- /dev/null +++ b/components/sync/driver/local_device_info_provider_mock.h
@@ -0,0 +1,52 @@ +// 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 COMPONENTS_SYNC_DRIVER_LOCAL_DEVICE_INFO_PROVIDER_MOCK_H_ +#define COMPONENTS_SYNC_DRIVER_LOCAL_DEVICE_INFO_PROVIDER_MOCK_H_ + +#include <string> + +#include "components/sync/driver/device_info.h" +#include "components/sync/driver/local_device_info_provider.h" + +namespace sync_driver { + +class LocalDeviceInfoProviderMock + : public sync_driver::LocalDeviceInfoProvider { + public: + // Creates uninitialized provider. + LocalDeviceInfoProviderMock(); + // Creates initialized provider with the specified device info. + LocalDeviceInfoProviderMock(const std::string& guid, + const std::string& client_name, + const std::string& chrome_version, + const std::string& sync_user_agent, + const sync_pb::SyncEnums::DeviceType device_type, + const std::string& signin_scoped_device_id); + ~LocalDeviceInfoProviderMock() override; + + const DeviceInfo* GetLocalDeviceInfo() const override; + std::string GetSyncUserAgent() const override; + std::string GetLocalSyncCacheGUID() const override; + void Initialize( + const std::string& cache_guid, + const std::string& signin_scoped_device_id, + const scoped_refptr<base::TaskRunner>& blocking_task_runner) override; + std::unique_ptr<Subscription> RegisterOnInitializedCallback( + const base::Closure& callback) override; + void Clear() override; + + void Initialize(std::unique_ptr<DeviceInfo> local_device_info); + void SetInitialized(bool is_initialized); + + private: + bool is_initialized_; + + std::unique_ptr<DeviceInfo> local_device_info_; + base::CallbackList<void(void)> callback_list_; +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_LOCAL_DEVICE_INFO_PROVIDER_MOCK_H_
diff --git a/components/sync/driver/local_device_info_provider_unittest.cc b/components/sync/driver/local_device_info_provider_unittest.cc new file mode 100644 index 0000000..a58e211f --- /dev/null +++ b/components/sync/driver/local_device_info_provider_unittest.cc
@@ -0,0 +1,146 @@ +// 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/bind.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "components/sync/base/get_session_name.h" +#include "components/sync/driver/local_device_info_provider_impl.h" +#include "components/version_info/version_info.h" +#include "testing/gtest/include/gtest/gtest.h" + +using sync_driver::DeviceInfo; +using sync_driver::LocalDeviceInfoProvider; + +namespace browser_sync { + +const char kLocalDeviceGuid[] = "foo"; +const char kSigninScopedDeviceId[] = "device_id"; + +class LocalDeviceInfoProviderTest : public testing::Test { + public: + LocalDeviceInfoProviderTest() : called_back_(false) {} + ~LocalDeviceInfoProviderTest() override {} + + void SetUp() override { + provider_.reset(new LocalDeviceInfoProviderImpl( + version_info::Channel::UNKNOWN, + version_info::GetVersionStringWithModifier("UNKNOWN"), false)); + } + + void TearDown() override { + provider_.reset(); + called_back_ = false; + } + + protected: + void StartInitializeProvider() { StartInitializeProvider(kLocalDeviceGuid); } + + void StartInitializeProvider(const std::string& guid) { + provider_->Initialize(guid, kSigninScopedDeviceId, + message_loop_.task_runner()); + } + + void FinishInitializeProvider() { + // Subscribe to the notification and wait until the callback + // is called. The callback will quit the loop. + base::RunLoop run_loop; + std::unique_ptr<LocalDeviceInfoProvider::Subscription> subscription = + provider_->RegisterOnInitializedCallback( + base::Bind(&LocalDeviceInfoProviderTest::QuitLoopOnInitialized, + base::Unretained(this), &run_loop)); + run_loop.Run(); + } + + void InitializeProvider() { + StartInitializeProvider(); + FinishInitializeProvider(); + } + + void QuitLoopOnInitialized(base::RunLoop* loop) { + called_back_ = true; + loop->Quit(); + } + + std::unique_ptr<LocalDeviceInfoProviderImpl> provider_; + + bool called_back_; + + private: + base::MessageLoop message_loop_; +}; + +TEST_F(LocalDeviceInfoProviderTest, OnInitializedCallback) { + ASSERT_FALSE(called_back_); + StartInitializeProvider(); + ASSERT_FALSE(called_back_); + FinishInitializeProvider(); + EXPECT_TRUE(called_back_); +} + +TEST_F(LocalDeviceInfoProviderTest, GetLocalDeviceInfo) { + ASSERT_EQ(nullptr, provider_->GetLocalDeviceInfo()); + StartInitializeProvider(); + ASSERT_EQ(nullptr, provider_->GetLocalDeviceInfo()); + FinishInitializeProvider(); + + const DeviceInfo* local_device_info = provider_->GetLocalDeviceInfo(); + ASSERT_NE(nullptr, local_device_info); + EXPECT_EQ(std::string(kLocalDeviceGuid), local_device_info->guid()); + EXPECT_EQ(std::string(kSigninScopedDeviceId), + local_device_info->signin_scoped_device_id()); + EXPECT_EQ(syncer::GetSessionNameSynchronouslyForTesting(), + local_device_info->client_name()); + + EXPECT_EQ(provider_->GetSyncUserAgent(), + local_device_info->sync_user_agent()); + + provider_->Clear(); + ASSERT_EQ(nullptr, provider_->GetLocalDeviceInfo()); +} + +TEST_F(LocalDeviceInfoProviderTest, GetLocalSyncCacheGUID) { + EXPECT_TRUE(provider_->GetLocalSyncCacheGUID().empty()); + + StartInitializeProvider(); + EXPECT_EQ(std::string(kLocalDeviceGuid), provider_->GetLocalSyncCacheGUID()); + + FinishInitializeProvider(); + EXPECT_EQ(std::string(kLocalDeviceGuid), provider_->GetLocalSyncCacheGUID()); + + provider_->Clear(); + EXPECT_TRUE(provider_->GetLocalSyncCacheGUID().empty()); +} + +TEST_F(LocalDeviceInfoProviderTest, InitClearRace) { + EXPECT_TRUE(provider_->GetLocalSyncCacheGUID().empty()); + StartInitializeProvider(); + + provider_->Clear(); + ASSERT_EQ(nullptr, provider_->GetLocalDeviceInfo()); + EXPECT_TRUE(provider_->GetLocalSyncCacheGUID().empty()); + + base::RunLoop().RunUntilIdle(); + ASSERT_EQ(nullptr, provider_->GetLocalDeviceInfo()); + EXPECT_TRUE(provider_->GetLocalSyncCacheGUID().empty()); +} + +TEST_F(LocalDeviceInfoProviderTest, InitClearInitRace) { + EXPECT_TRUE(provider_->GetLocalSyncCacheGUID().empty()); + StartInitializeProvider(); + provider_->Clear(); + + const std::string guid2 = "guid2"; + StartInitializeProvider(guid2); + ASSERT_EQ(nullptr, provider_->GetLocalDeviceInfo()); + EXPECT_EQ(guid2, provider_->GetLocalSyncCacheGUID()); + + FinishInitializeProvider(); + const DeviceInfo* local_device_info = provider_->GetLocalDeviceInfo(); + ASSERT_NE(nullptr, local_device_info); + EXPECT_EQ(guid2, local_device_info->guid()); + EXPECT_EQ(guid2, provider_->GetLocalSyncCacheGUID()); +} + +} // namespace browser_sync
diff --git a/components/sync/driver/model_association_manager.cc b/components/sync/driver/model_association_manager.cc new file mode 100644 index 0000000..55d5928 --- /dev/null +++ b/components/sync/driver/model_association_manager.cc
@@ -0,0 +1,426 @@ +// 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 "components/sync/driver/model_association_manager.h" + +#include <stddef.h> +#include <stdint.h> + +#include <algorithm> +#include <functional> + +#include "base/logging.h" +#include "base/macros.h" +#include "base/message_loop/message_loop.h" +#include "base/metrics/histogram_macros.h" +#include "base/trace_event/trace_event.h" +#include "components/sync/api/sync_merge_result.h" +#include "components/sync/base/model_type.h" + +using syncer::ModelTypeSet; + +namespace sync_driver { + +namespace { + +static const syncer::ModelType kStartOrder[] = { + syncer::NIGORI, // Listed for completeness. + syncer::DEVICE_INFO, // Listed for completeness. + syncer::EXPERIMENTS, // Listed for completeness. + syncer::PROXY_TABS, // Listed for completeness. + + // Kick off the association of the non-UI types first so they can associate + // in parallel with the UI types. + syncer::PASSWORDS, syncer::AUTOFILL, syncer::AUTOFILL_PROFILE, + syncer::AUTOFILL_WALLET_DATA, syncer::AUTOFILL_WALLET_METADATA, + syncer::EXTENSION_SETTINGS, syncer::APP_SETTINGS, syncer::TYPED_URLS, + syncer::HISTORY_DELETE_DIRECTIVES, syncer::SYNCED_NOTIFICATIONS, + syncer::SYNCED_NOTIFICATION_APP_INFO, + + // UI thread data types. + syncer::BOOKMARKS, + syncer::SUPERVISED_USERS, // Syncing supervised users on initial login + // might block creating a new supervised user, + // so we want to do it early. + syncer::PREFERENCES, syncer::PRIORITY_PREFERENCES, syncer::EXTENSIONS, + syncer::APPS, syncer::APP_LIST, syncer::ARC_PACKAGE, syncer::THEMES, + syncer::SEARCH_ENGINES, syncer::SESSIONS, syncer::APP_NOTIFICATIONS, + syncer::DICTIONARY, syncer::FAVICON_IMAGES, syncer::FAVICON_TRACKING, + syncer::SUPERVISED_USER_SETTINGS, syncer::SUPERVISED_USER_SHARED_SETTINGS, + syncer::SUPERVISED_USER_WHITELISTS, syncer::ARTICLES, + syncer::WIFI_CREDENTIALS, +}; + +static_assert(arraysize(kStartOrder) == + syncer::MODEL_TYPE_COUNT - syncer::FIRST_REAL_MODEL_TYPE, + "kStartOrder must have MODEL_TYPE_COUNT - " + "FIRST_REAL_MODEL_TYPE elements"); + +// The amount of time we wait for association to finish. If some types haven't +// finished association by the time, DataTypeManager is notified of the +// unfinished types. +const int64_t kAssociationTimeOutInSeconds = 600; + +syncer::DataTypeAssociationStats BuildAssociationStatsFromMergeResults( + const syncer::SyncMergeResult& local_merge_result, + const syncer::SyncMergeResult& syncer_merge_result, + const base::TimeDelta& association_wait_time, + const base::TimeDelta& association_time) { + DCHECK_EQ(local_merge_result.model_type(), syncer_merge_result.model_type()); + syncer::DataTypeAssociationStats stats; + stats.had_error = + local_merge_result.error().IsSet() || syncer_merge_result.error().IsSet(); + stats.num_local_items_before_association = + local_merge_result.num_items_before_association(); + stats.num_sync_items_before_association = + syncer_merge_result.num_items_before_association(); + stats.num_local_items_after_association = + local_merge_result.num_items_after_association(); + stats.num_sync_items_after_association = + syncer_merge_result.num_items_after_association(); + stats.num_local_items_added = local_merge_result.num_items_added(); + stats.num_local_items_deleted = local_merge_result.num_items_deleted(); + stats.num_local_items_modified = local_merge_result.num_items_modified(); + stats.local_version_pre_association = + local_merge_result.pre_association_version(); + stats.num_sync_items_added = syncer_merge_result.num_items_added(); + stats.num_sync_items_deleted = syncer_merge_result.num_items_deleted(); + stats.num_sync_items_modified = syncer_merge_result.num_items_modified(); + stats.sync_version_pre_association = + syncer_merge_result.pre_association_version(); + stats.association_wait_time = association_wait_time; + stats.association_time = association_time; + return stats; +} + +} // namespace + +ModelAssociationManager::ModelAssociationManager( + const DataTypeController::TypeMap* controllers, + ModelAssociationManagerDelegate* processor) + : state_(IDLE), + controllers_(controllers), + delegate_(processor), + configure_status_(DataTypeManager::UNKNOWN), + notified_about_ready_for_configure_(false), + weak_ptr_factory_(this) { + // Ensure all data type controllers are stopped. + for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); + it != controllers_->end(); ++it) { + DCHECK_EQ(DataTypeController::NOT_RUNNING, (*it).second->state()); + } +} + +ModelAssociationManager::~ModelAssociationManager() {} + +void ModelAssociationManager::Initialize(syncer::ModelTypeSet desired_types) { + // state_ can be INITIALIZED if types are reconfigured when + // data is being downloaded, so StartAssociationAsync() is never called for + // the first configuration. + DCHECK_NE(ASSOCIATING, state_); + + // Only keep types that have controllers. + desired_types_.Clear(); + for (syncer::ModelTypeSet::Iterator it = desired_types.First(); it.Good(); + it.Inc()) { + if (controllers_->find(it.Get()) != controllers_->end()) + desired_types_.Put(it.Get()); + } + + DVLOG(1) << "ModelAssociationManager: Initializing for " + << syncer::ModelTypeSetToString(desired_types_); + + state_ = INITIALIZED; + notified_about_ready_for_configure_ = false; + + StopDisabledTypes(); + LoadEnabledTypes(); +} + +void ModelAssociationManager::StopDatatype(const syncer::SyncError& error, + DataTypeController* dtc) { + loaded_types_.Remove(dtc->type()); + associated_types_.Remove(dtc->type()); + associating_types_.Remove(dtc->type()); + + if (error.IsSet() || dtc->state() != DataTypeController::NOT_RUNNING) { + // If an error was set, the delegate must be informed of the error. + delegate_->OnSingleDataTypeWillStop(dtc->type(), error); + dtc->Stop(); + } +} + +void ModelAssociationManager::StopDisabledTypes() { + DVLOG(1) << "ModelAssociationManager: Stopping disabled types."; + for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); + it != controllers_->end(); ++it) { + DataTypeController* dtc = (*it).second.get(); + if (dtc->state() != DataTypeController::NOT_RUNNING && + !desired_types_.Has(dtc->type())) { + DVLOG(1) << "ModelAssociationManager: stop " << dtc->name(); + StopDatatype(syncer::SyncError(), dtc); + } + } +} + +void ModelAssociationManager::LoadEnabledTypes() { + // Load in kStartOrder. + for (size_t i = 0; i < arraysize(kStartOrder); i++) { + syncer::ModelType type = kStartOrder[i]; + if (!desired_types_.Has(type)) + continue; + + DCHECK(controllers_->find(type) != controllers_->end()); + DataTypeController* dtc = controllers_->find(type)->second.get(); + if (dtc->state() == DataTypeController::NOT_RUNNING) { + DCHECK(!loaded_types_.Has(dtc->type())); + DCHECK(!associated_types_.Has(dtc->type())); + dtc->LoadModels(base::Bind(&ModelAssociationManager::ModelLoadCallback, + weak_ptr_factory_.GetWeakPtr())); + } + } + NotifyDelegateIfReadyForConfigure(); +} + +void ModelAssociationManager::StartAssociationAsync( + const syncer::ModelTypeSet& types_to_associate) { + DCHECK_EQ(INITIALIZED, state_); + DVLOG(1) << "Starting association for " + << syncer::ModelTypeSetToString(types_to_associate); + state_ = ASSOCIATING; + + association_start_time_ = base::TimeTicks::Now(); + + requested_types_ = types_to_associate; + + associating_types_ = types_to_associate; + associating_types_.RetainAll(desired_types_); + associating_types_.RemoveAll(associated_types_); + + // Assume success. + configure_status_ = DataTypeManager::OK; + + // Done if no types to associate. + if (associating_types_.Empty()) { + ModelAssociationDone(INITIALIZED); + return; + } + + timer_.Start(FROM_HERE, + base::TimeDelta::FromSeconds(kAssociationTimeOutInSeconds), + base::Bind(&ModelAssociationManager::ModelAssociationDone, + weak_ptr_factory_.GetWeakPtr(), INITIALIZED)); + + // Start association of types that are loaded in specified order. + for (size_t i = 0; i < arraysize(kStartOrder); i++) { + syncer::ModelType type = kStartOrder[i]; + if (!associating_types_.Has(type) || !loaded_types_.Has(type)) + continue; + + DataTypeController* dtc = controllers_->find(type)->second.get(); + DCHECK(DataTypeController::MODEL_LOADED == dtc->state() || + DataTypeController::ASSOCIATING == dtc->state()); + if (dtc->state() == DataTypeController::MODEL_LOADED) { + TRACE_EVENT_ASYNC_BEGIN1("sync", "ModelAssociation", dtc, "DataType", + ModelTypeToString(type)); + + dtc->StartAssociating(base::Bind( + &ModelAssociationManager::TypeStartCallback, + weak_ptr_factory_.GetWeakPtr(), type, base::TimeTicks::Now())); + } + } +} + +void ModelAssociationManager::Stop() { + // Ignore callbacks from controllers. + weak_ptr_factory_.InvalidateWeakPtrs(); + + // Stop started data types. + for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); + it != controllers_->end(); ++it) { + DataTypeController* dtc = (*it).second.get(); + if (dtc->state() != DataTypeController::NOT_RUNNING) { + StopDatatype(syncer::SyncError(), dtc); + DVLOG(1) << "ModelAssociationManager: Stopped " << dtc->name(); + } + } + + desired_types_.Clear(); + loaded_types_.Clear(); + associated_types_.Clear(); + + if (state_ == ASSOCIATING) { + if (configure_status_ == DataTypeManager::OK) + configure_status_ = DataTypeManager::ABORTED; + DVLOG(1) << "ModelAssociationManager: Calling OnModelAssociationDone"; + ModelAssociationDone(IDLE); + } else { + DCHECK(associating_types_.Empty()); + DCHECK(requested_types_.Empty()); + state_ = IDLE; + } +} + +void ModelAssociationManager::ModelLoadCallback(syncer::ModelType type, + syncer::SyncError error) { + DVLOG(1) << "ModelAssociationManager: ModelLoadCallback for " + << syncer::ModelTypeToString(type); + + if (error.IsSet()) { + syncer::SyncMergeResult local_merge_result(type); + local_merge_result.set_error(error); + TypeStartCallback(type, base::TimeTicks::Now(), + DataTypeController::ASSOCIATION_FAILED, + local_merge_result, syncer::SyncMergeResult(type)); + return; + } + + // This happens when slow loading type is disabled by new configuration. + if (!desired_types_.Has(type)) + return; + + DCHECK(!loaded_types_.Has(type)); + loaded_types_.Put(type); + NotifyDelegateIfReadyForConfigure(); + if (associating_types_.Has(type)) { + DataTypeController* dtc = controllers_->find(type)->second.get(); + // If initial sync was done for this datatype then + // NotifyDelegateIfReadyForConfigure possibly already triggered model + // association and StartAssociating was already called for this type. To + // ensure StartAssociating is called only once only make a call if state is + // MODEL_LOADED. + // TODO(pavely): Add test for this scenario in DataTypeManagerImpl + // unittests. + if (dtc->state() == DataTypeController::MODEL_LOADED) { + dtc->StartAssociating(base::Bind( + &ModelAssociationManager::TypeStartCallback, + weak_ptr_factory_.GetWeakPtr(), type, base::TimeTicks::Now())); + } + } +} + +void ModelAssociationManager::TypeStartCallback( + syncer::ModelType type, + base::TimeTicks type_start_time, + DataTypeController::ConfigureResult start_result, + const syncer::SyncMergeResult& local_merge_result, + const syncer::SyncMergeResult& syncer_merge_result) { + if (desired_types_.Has(type) && + !DataTypeController::IsSuccessfulResult(start_result)) { + DVLOG(1) << "ModelAssociationManager: Type encountered an error."; + desired_types_.Remove(type); + DataTypeController* dtc = controllers_->find(type)->second.get(); + StopDatatype(local_merge_result.error(), dtc); + NotifyDelegateIfReadyForConfigure(); + + // Update configuration result. + if (start_result == DataTypeController::UNRECOVERABLE_ERROR) + configure_status_ = DataTypeManager::UNRECOVERABLE_ERROR; + } + + // This happens when a slow associating type is disabled or if a type + // disables itself after initial configuration. + if (!desired_types_.Has(type)) { + // It's possible all types failed to associate, in which case association + // is complete. + if (state_ == ASSOCIATING && associating_types_.Empty()) + ModelAssociationDone(INITIALIZED); + return; + } + + DCHECK(!associated_types_.Has(type)); + DCHECK(DataTypeController::IsSuccessfulResult(start_result)); + associated_types_.Put(type); + + if (state_ != ASSOCIATING) + return; + + TRACE_EVENT_ASYNC_END1("sync", "ModelAssociation", + controllers_->find(type)->second.get(), "DataType", + ModelTypeToString(type)); + + // Track the merge results if we succeeded or an association failure + // occurred. + if (syncer::ProtocolTypes().Has(type)) { + base::TimeDelta association_wait_time = + std::max(base::TimeDelta(), type_start_time - association_start_time_); + base::TimeDelta association_time = base::TimeTicks::Now() - type_start_time; + syncer::DataTypeAssociationStats stats = + BuildAssociationStatsFromMergeResults( + local_merge_result, syncer_merge_result, association_wait_time, + association_time); + delegate_->OnSingleDataTypeAssociationDone(type, stats); + } + + associating_types_.Remove(type); + + if (associating_types_.Empty()) + ModelAssociationDone(INITIALIZED); +} + +void ModelAssociationManager::ModelAssociationDone(State new_state) { + DCHECK_NE(IDLE, state_); + + if (state_ == INITIALIZED) { + // No associations are currently happening. Just reset the state. + state_ = new_state; + return; + } + + DVLOG(1) << "Model association complete for " + << syncer::ModelTypeSetToString(requested_types_); + + timer_.Stop(); + + // Treat any unfinished types as having errors. + desired_types_.RemoveAll(associating_types_); + for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); + it != controllers_->end(); ++it) { + DataTypeController* dtc = (*it).second.get(); + if (associating_types_.Has(dtc->type()) && + dtc->state() != DataTypeController::NOT_RUNNING) { + UMA_HISTOGRAM_ENUMERATION("Sync.ConfigureFailed", + ModelTypeToHistogramInt(dtc->type()), + syncer::MODEL_TYPE_COUNT); + StopDatatype( + syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Association timed out.", dtc->type()), + dtc); + } + } + + DataTypeManager::ConfigureResult result(configure_status_, requested_types_); + + // Need to reset state before invoking delegate in order to avoid re-entrancy + // issues (delegate may trigger a reconfiguration). + associating_types_.Clear(); + requested_types_.Clear(); + state_ = new_state; + + delegate_->OnModelAssociationDone(result); +} + +base::OneShotTimer* ModelAssociationManager::GetTimerForTesting() { + return &timer_; +} + +void ModelAssociationManager::NotifyDelegateIfReadyForConfigure() { + if (notified_about_ready_for_configure_) + return; + for (const auto& type_dtc_pair : *controllers_) { + syncer::ModelType type = type_dtc_pair.first; + if (!desired_types_.Has(type)) + continue; + DataTypeController* dtc = type_dtc_pair.second.get(); + if (dtc->ShouldLoadModelBeforeConfigure() && !loaded_types_.Has(type)) { + // At least one type is not ready. + return; + } + } + + notified_about_ready_for_configure_ = true; + delegate_->OnAllDataTypesReadyForConfigure(); +} + +} // namespace sync_driver
diff --git a/components/sync/driver/model_association_manager.h b/components/sync/driver/model_association_manager.h new file mode 100644 index 0000000..89095d4 --- /dev/null +++ b/components/sync/driver/model_association_manager.h
@@ -0,0 +1,182 @@ +// 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 COMPONENTS_SYNC_DRIVER_MODEL_ASSOCIATION_MANAGER_H__ +#define COMPONENTS_SYNC_DRIVER_MODEL_ASSOCIATION_MANAGER_H__ + +#include <map> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/timer/timer.h" + +#include "components/sync/base/weak_handle.h" +#include "components/sync/core/data_type_association_stats.h" +#include "components/sync/driver/data_type_manager.h" + +namespace sync_driver { + +class DataTypeController; + +// |ModelAssociationManager| does the heavy lifting for doing the actual model +// association. It instructs DataTypeControllers to load models, start +// associating and stopping. Since the operations are async it uses an +// interface to inform DataTypeManager the results of the operations. +// This class is owned by DataTypeManager. +// |ModelAssociationManager| association functions are async. The results of +// those operations are passed back via this interface. +class ModelAssociationManagerDelegate { + public: + // Called when all desired types are ready to be configured with + // BackendDataTypeConfigurer. Data type is ready when its progress marker is + // available to configurer. Directory data types are always ready, their + // progress markers are read from directory. USS data type controllers need to + // load model and read data type context first. + // This function is called at most once after each call to + // ModelAssociationManager::Initialize(). + virtual void OnAllDataTypesReadyForConfigure() = 0; + + // Called when model association (MergeDataAndStartSyncing) has completed + // for |type|, regardless of success or failure. + virtual void OnSingleDataTypeAssociationDone( + syncer::ModelType type, + const syncer::DataTypeAssociationStats& association_stats) = 0; + + // Called when the ModelAssociationManager has decided it must stop |type|, + // likely because it is no longer a desired data type or sync is shutting + // down. + virtual void OnSingleDataTypeWillStop(syncer::ModelType type, + const syncer::SyncError& error) = 0; + + // Called when the ModelAssociationManager has tried to perform model + // association for all desired types and has nothing left to do. + virtual void OnModelAssociationDone( + const DataTypeManager::ConfigureResult& result) = 0; + virtual ~ModelAssociationManagerDelegate() {} +}; + +// The class that is responsible for model association. +class ModelAssociationManager { + public: + enum State { + // No configuration is in progress. + IDLE, + // The model association manager has been initialized with a set of desired + // types, but is not actively associating any. + INITIALIZED, + // One or more types from |desired_types_| are in the process of + // associating. + ASSOCIATING, + }; + + ModelAssociationManager(const DataTypeController::TypeMap* controllers, + ModelAssociationManagerDelegate* delegate); + virtual ~ModelAssociationManager(); + + // Initializes the state to do the model association in future. This + // should be called before communicating with sync server. A subsequent call + // of Initialize is only allowed if the ModelAssociationManager has invoked + // |OnModelAssociationDone| on the |ModelAssociationManagerDelegate|. After + // this call, there should be several calls to StartAssociationAsync() + // to associate subset of |desired_types|. + void Initialize(syncer::ModelTypeSet desired_types); + + // Can be called at any time. Synchronously stops all datatypes. + void Stop(); + + // Should only be called after Initialize to start the actual association. + // |types_to_associate| should be subset of |desired_types| in Initialize(). + // When this is completed, |OnModelAssociationDone| will be invoked. + void StartAssociationAsync(const syncer::ModelTypeSet& types_to_associate); + + // This is used for TESTING PURPOSE ONLY. The test case can inspect + // and modify the timer. + // TODO(sync) : This would go away if we made this class be able to do + // Dependency injection. crbug.com/129212. + base::OneShotTimer* GetTimerForTesting(); + + State state() const { return state_; } + + private: + // Called at the end of association to reset state to prepare for next + // round of association. + void ResetForNextAssociation(); + + // Called by Initialize() to stop types that are not in |desired_types_|. + void StopDisabledTypes(); + + // Start loading non-running types that are in |desired_types_|. + void LoadEnabledTypes(); + + // Callback passed to each data type controller on starting association. This + // callback will be invoked when the model association is done. + void TypeStartCallback(syncer::ModelType type, + base::TimeTicks type_start_time, + DataTypeController::ConfigureResult start_result, + const syncer::SyncMergeResult& local_merge_result, + const syncer::SyncMergeResult& syncer_merge_result); + + // Callback that will be invoked when the models finish loading. This callback + // will be passed to |LoadModels| function. + void ModelLoadCallback(syncer::ModelType type, syncer::SyncError error); + + // Called when all requested types are associated or association times out. + // Will clean up any unfinished types, and update |state_| to be |new_state| + // Finally, it will notify |delegate_| of the configuration result. + void ModelAssociationDone(State new_state); + + // A helper to stop an individual datatype. + void StopDatatype(const syncer::SyncError& error, DataTypeController* dtc); + + // Calls delegate's OnAllDataTypesReadyForConfigure when all datatypes from + // desired_types_ are ready for configure. Ensures that for every call to + // Initialize callback is called at most once. + // Datatype is ready if either it doesn't require LoadModels before configure + // or LoadModels successfully finished. + void NotifyDelegateIfReadyForConfigure(); + + State state_; + + // Data types that are enabled. + syncer::ModelTypeSet desired_types_; + + // Data types that are requested to associate. + syncer::ModelTypeSet requested_types_; + + // Data types currently being associated, including types waiting for model + // load. + syncer::ModelTypeSet associating_types_; + + // Data types that are loaded, i.e. ready to associate. + syncer::ModelTypeSet loaded_types_; + + // Data types that are associated, i.e. no more action needed during + // reconfiguration if not disabled. + syncer::ModelTypeSet associated_types_; + + // Time when StartAssociationAsync() is called to associate for a set of data + // types. + base::TimeTicks association_start_time_; + + // Set of all registered controllers. + const DataTypeController::TypeMap* controllers_; + + // The processor in charge of handling model association results. + ModelAssociationManagerDelegate* delegate_; + + // Timer to track and limit how long a datatype takes to model associate. + base::OneShotTimer timer_; + + DataTypeManager::ConfigureStatus configure_status_; + + bool notified_about_ready_for_configure_; + + base::WeakPtrFactory<ModelAssociationManager> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(ModelAssociationManager); +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_MODEL_ASSOCIATION_MANAGER_H__
diff --git a/components/sync/driver/model_association_manager_unittest.cc b/components/sync/driver/model_association_manager_unittest.cc new file mode 100644 index 0000000..6965d261 --- /dev/null +++ b/components/sync/driver/model_association_manager_unittest.cc
@@ -0,0 +1,493 @@ +// 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 "components/sync/driver/model_association_manager.h" + +#include "base/callback.h" +#include "base/message_loop/message_loop.h" +#include "components/sync/driver/fake_data_type_controller.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using ::testing::_; + +namespace sync_driver { + +class MockModelAssociationManagerDelegate + : public ModelAssociationManagerDelegate { + public: + MockModelAssociationManagerDelegate() {} + ~MockModelAssociationManagerDelegate() {} + MOCK_METHOD0(OnAllDataTypesReadyForConfigure, void()); + MOCK_METHOD2(OnSingleDataTypeAssociationDone, + void(syncer::ModelType type, + const syncer::DataTypeAssociationStats& association_stats)); + MOCK_METHOD2(OnSingleDataTypeWillStop, + void(syncer::ModelType, const syncer::SyncError& error)); + MOCK_METHOD1(OnModelAssociationDone, + void(const DataTypeManager::ConfigureResult& result)); +}; + +FakeDataTypeController* GetController( + const DataTypeController::TypeMap& controllers, + syncer::ModelType model_type) { + DataTypeController::TypeMap::const_iterator it = controllers.find(model_type); + if (it == controllers.end()) { + return NULL; + } + return static_cast<FakeDataTypeController*>(it->second.get()); +} + +ACTION_P(VerifyResult, expected_result) { + EXPECT_EQ(arg0.status, expected_result.status); + EXPECT_EQ(expected_result.requested_types, arg0.requested_types); +} + +class SyncModelAssociationManagerTest : public testing::Test { + public: + SyncModelAssociationManagerTest() {} + + protected: + base::MessageLoopForUI ui_loop_; + MockModelAssociationManagerDelegate delegate_; + DataTypeController::TypeMap controllers_; +}; + +// Start a type and make sure ModelAssociationManager callst the |Start| +// method and calls the callback when it is done. +TEST_F(SyncModelAssociationManagerTest, SimpleModelStart) { + controllers_[syncer::BOOKMARKS] = + new FakeDataTypeController(syncer::BOOKMARKS); + controllers_[syncer::APPS] = new FakeDataTypeController(syncer::APPS); + ModelAssociationManager model_association_manager(&controllers_, &delegate_); + syncer::ModelTypeSet types(syncer::BOOKMARKS, syncer::APPS); + DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); + EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()); + EXPECT_CALL(delegate_, OnModelAssociationDone(_)) + .WillOnce(VerifyResult(expected_result)); + + EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), + DataTypeController::NOT_RUNNING); + EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), + DataTypeController::NOT_RUNNING); + + // Initialize() kicks off model loading. + model_association_manager.Initialize(types); + + EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), + DataTypeController::MODEL_LOADED); + EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), + DataTypeController::MODEL_LOADED); + + model_association_manager.StartAssociationAsync(types); + + EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), + DataTypeController::ASSOCIATING); + EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), + DataTypeController::ASSOCIATING); + GetController(controllers_, syncer::BOOKMARKS) + ->FinishStart(DataTypeController::OK); + GetController(controllers_, syncer::APPS) + ->FinishStart(DataTypeController::OK); +} + +// Start a type and call stop before it finishes associating. +TEST_F(SyncModelAssociationManagerTest, StopModelBeforeFinish) { + controllers_[syncer::BOOKMARKS] = + new FakeDataTypeController(syncer::BOOKMARKS); + ModelAssociationManager model_association_manager(&controllers_, &delegate_); + + syncer::ModelTypeSet types; + types.Put(syncer::BOOKMARKS); + + DataTypeManager::ConfigureResult expected_result(DataTypeManager::ABORTED, + types); + + EXPECT_CALL(delegate_, OnModelAssociationDone(_)) + .WillOnce(VerifyResult(expected_result)); + EXPECT_CALL(delegate_, OnSingleDataTypeWillStop(syncer::BOOKMARKS, _)); + + model_association_manager.Initialize(types); + model_association_manager.StartAssociationAsync(types); + + EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), + DataTypeController::ASSOCIATING); + model_association_manager.Stop(); + EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), + DataTypeController::NOT_RUNNING); +} + +// Start a type, let it finish and then call stop. +TEST_F(SyncModelAssociationManagerTest, StopAfterFinish) { + controllers_[syncer::BOOKMARKS] = + new FakeDataTypeController(syncer::BOOKMARKS); + ModelAssociationManager model_association_manager(&controllers_, &delegate_); + syncer::ModelTypeSet types; + types.Put(syncer::BOOKMARKS); + DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); + EXPECT_CALL(delegate_, OnModelAssociationDone(_)) + .WillOnce(VerifyResult(expected_result)); + EXPECT_CALL(delegate_, OnSingleDataTypeWillStop(syncer::BOOKMARKS, _)); + + model_association_manager.Initialize(types); + model_association_manager.StartAssociationAsync(types); + + EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), + DataTypeController::ASSOCIATING); + GetController(controllers_, syncer::BOOKMARKS) + ->FinishStart(DataTypeController::OK); + + model_association_manager.Stop(); + EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), + DataTypeController::NOT_RUNNING); +} + +// Make a type fail model association and verify correctness. +TEST_F(SyncModelAssociationManagerTest, TypeFailModelAssociation) { + controllers_[syncer::BOOKMARKS] = + new FakeDataTypeController(syncer::BOOKMARKS); + ModelAssociationManager model_association_manager(&controllers_, &delegate_); + syncer::ModelTypeSet types; + types.Put(syncer::BOOKMARKS); + DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); + EXPECT_CALL(delegate_, OnSingleDataTypeWillStop(syncer::BOOKMARKS, _)); + EXPECT_CALL(delegate_, OnModelAssociationDone(_)) + .WillOnce(VerifyResult(expected_result)); + + model_association_manager.Initialize(types); + model_association_manager.StartAssociationAsync(types); + + EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), + DataTypeController::ASSOCIATING); + GetController(controllers_, syncer::BOOKMARKS) + ->FinishStart(DataTypeController::ASSOCIATION_FAILED); + EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), + DataTypeController::NOT_RUNNING); +} + +// Ensure configuring stops when a type returns a unrecoverable error. +TEST_F(SyncModelAssociationManagerTest, TypeReturnUnrecoverableError) { + controllers_[syncer::BOOKMARKS] = + new FakeDataTypeController(syncer::BOOKMARKS); + ModelAssociationManager model_association_manager(&controllers_, &delegate_); + syncer::ModelTypeSet types; + types.Put(syncer::BOOKMARKS); + DataTypeManager::ConfigureResult expected_result( + DataTypeManager::UNRECOVERABLE_ERROR, types); + EXPECT_CALL(delegate_, OnSingleDataTypeWillStop(syncer::BOOKMARKS, _)); + EXPECT_CALL(delegate_, OnModelAssociationDone(_)) + .WillOnce(VerifyResult(expected_result)); + + model_association_manager.Initialize(types); + + model_association_manager.StartAssociationAsync(types); + + EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), + DataTypeController::ASSOCIATING); + GetController(controllers_, syncer::BOOKMARKS) + ->FinishStart(DataTypeController::UNRECOVERABLE_ERROR); +} + +TEST_F(SyncModelAssociationManagerTest, SlowTypeAsFailedType) { + controllers_[syncer::BOOKMARKS] = + new FakeDataTypeController(syncer::BOOKMARKS); + controllers_[syncer::APPS] = new FakeDataTypeController(syncer::APPS); + GetController(controllers_, syncer::BOOKMARKS)->SetDelayModelLoad(); + ModelAssociationManager model_association_manager(&controllers_, &delegate_); + syncer::ModelTypeSet types; + types.Put(syncer::BOOKMARKS); + types.Put(syncer::APPS); + + DataTypeManager::ConfigureResult expected_result_partially_done( + DataTypeManager::OK, types); + + EXPECT_CALL(delegate_, OnModelAssociationDone(_)) + .WillOnce(VerifyResult(expected_result_partially_done)); + + model_association_manager.Initialize(types); + model_association_manager.StartAssociationAsync(types); + GetController(controllers_, syncer::APPS) + ->FinishStart(DataTypeController::OK); + + EXPECT_CALL(delegate_, OnSingleDataTypeWillStop(syncer::BOOKMARKS, _)); + model_association_manager.GetTimerForTesting()->user_task().Run(); + + EXPECT_EQ(DataTypeController::NOT_RUNNING, + GetController(controllers_, syncer::BOOKMARKS)->state()); +} + +TEST_F(SyncModelAssociationManagerTest, StartMultipleTimes) { + controllers_[syncer::BOOKMARKS] = + new FakeDataTypeController(syncer::BOOKMARKS); + controllers_[syncer::APPS] = new FakeDataTypeController(syncer::APPS); + ModelAssociationManager model_association_manager(&controllers_, &delegate_); + syncer::ModelTypeSet types; + types.Put(syncer::BOOKMARKS); + types.Put(syncer::APPS); + + DataTypeManager::ConfigureResult result_1st( + DataTypeManager::OK, syncer::ModelTypeSet(syncer::BOOKMARKS)); + DataTypeManager::ConfigureResult result_2nd( + DataTypeManager::OK, syncer::ModelTypeSet(syncer::APPS)); + EXPECT_CALL(delegate_, OnModelAssociationDone(_)) + .Times(2) + .WillOnce(VerifyResult(result_1st)) + .WillOnce(VerifyResult(result_2nd)); + + model_association_manager.Initialize(types); + + // Start BOOKMARKS first. + model_association_manager.StartAssociationAsync( + syncer::ModelTypeSet(syncer::BOOKMARKS)); + EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), + DataTypeController::ASSOCIATING); + EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), + DataTypeController::MODEL_LOADED); + + // Finish BOOKMARKS association. + GetController(controllers_, syncer::BOOKMARKS) + ->FinishStart(DataTypeController::OK); + EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), + DataTypeController::RUNNING); + EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), + DataTypeController::MODEL_LOADED); + + // Start APPS next. + model_association_manager.StartAssociationAsync( + syncer::ModelTypeSet(syncer::APPS)); + EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), + DataTypeController::ASSOCIATING); + GetController(controllers_, syncer::APPS) + ->FinishStart(DataTypeController::OK); + EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), + DataTypeController::RUNNING); +} + +// Test that model that failed to load between initialization and association +// is reported and stopped properly. +TEST_F(SyncModelAssociationManagerTest, ModelLoadFailBeforeAssociationStart) { + controllers_[syncer::BOOKMARKS] = + new FakeDataTypeController(syncer::BOOKMARKS); + GetController(controllers_, syncer::BOOKMARKS) + ->SetModelLoadError(syncer::SyncError( + FROM_HERE, syncer::SyncError::DATATYPE_ERROR, "", syncer::BOOKMARKS)); + ModelAssociationManager model_association_manager(&controllers_, &delegate_); + syncer::ModelTypeSet types; + types.Put(syncer::BOOKMARKS); + DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); + EXPECT_CALL(delegate_, OnSingleDataTypeWillStop(syncer::BOOKMARKS, _)); + EXPECT_CALL(delegate_, OnModelAssociationDone(_)) + .WillOnce(VerifyResult(expected_result)); + + model_association_manager.Initialize(types); + EXPECT_EQ(DataTypeController::NOT_RUNNING, + GetController(controllers_, syncer::BOOKMARKS)->state()); + model_association_manager.StartAssociationAsync(types); + EXPECT_EQ(DataTypeController::NOT_RUNNING, + GetController(controllers_, syncer::BOOKMARKS)->state()); +} + +// Test that a runtime error is handled by stopping the type. +TEST_F(SyncModelAssociationManagerTest, StopAfterConfiguration) { + controllers_[syncer::BOOKMARKS] = + new FakeDataTypeController(syncer::BOOKMARKS); + ModelAssociationManager model_association_manager(&controllers_, &delegate_); + syncer::ModelTypeSet types; + types.Put(syncer::BOOKMARKS); + DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); + EXPECT_CALL(delegate_, OnModelAssociationDone(_)) + .WillOnce(VerifyResult(expected_result)); + + model_association_manager.Initialize(types); + model_association_manager.StartAssociationAsync(types); + + EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), + DataTypeController::ASSOCIATING); + GetController(controllers_, syncer::BOOKMARKS) + ->FinishStart(DataTypeController::OK); + EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), + DataTypeController::RUNNING); + + testing::Mock::VerifyAndClearExpectations(&delegate_); + EXPECT_CALL(delegate_, OnSingleDataTypeWillStop(syncer::BOOKMARKS, _)); + syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, "error", + syncer::BOOKMARKS); + GetController(controllers_, syncer::BOOKMARKS) + ->OnSingleDataTypeUnrecoverableError(error); +} + +TEST_F(SyncModelAssociationManagerTest, AbortDuringAssociation) { + controllers_[syncer::BOOKMARKS] = + new FakeDataTypeController(syncer::BOOKMARKS); + controllers_[syncer::APPS] = new FakeDataTypeController(syncer::APPS); + ModelAssociationManager model_association_manager(&controllers_, &delegate_); + syncer::ModelTypeSet types; + types.Put(syncer::BOOKMARKS); + types.Put(syncer::APPS); + + syncer::ModelTypeSet expected_types_unfinished; + expected_types_unfinished.Put(syncer::BOOKMARKS); + DataTypeManager::ConfigureResult expected_result_partially_done( + DataTypeManager::OK, types); + + EXPECT_CALL(delegate_, OnModelAssociationDone(_)) + .WillOnce(VerifyResult(expected_result_partially_done)); + + model_association_manager.Initialize(types); + model_association_manager.StartAssociationAsync(types); + GetController(controllers_, syncer::APPS) + ->FinishStart(DataTypeController::OK); + EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), + DataTypeController::RUNNING); + EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), + DataTypeController::ASSOCIATING); + + EXPECT_CALL(delegate_, OnSingleDataTypeWillStop(syncer::BOOKMARKS, _)); + model_association_manager.GetTimerForTesting()->user_task().Run(); + + EXPECT_EQ(DataTypeController::NOT_RUNNING, + GetController(controllers_, syncer::BOOKMARKS)->state()); +} + +// Test that OnAllDataTypesReadyForConfigure is called when all datatypes that +// require LoadModels before configuration are loaded. +TEST_F(SyncModelAssociationManagerTest, OnAllDataTypesReadyForConfigure) { + // Create two controllers with delayed model load. + controllers_[syncer::BOOKMARKS] = + new FakeDataTypeController(syncer::BOOKMARKS); + controllers_[syncer::APPS] = new FakeDataTypeController(syncer::APPS); + GetController(controllers_, syncer::BOOKMARKS)->SetDelayModelLoad(); + GetController(controllers_, syncer::APPS)->SetDelayModelLoad(); + + // APPS controller requires LoadModels complete before configure. + GetController(controllers_, syncer::APPS) + ->SetShouldLoadModelBeforeConfigure(true); + + ModelAssociationManager model_association_manager(&controllers_, &delegate_); + syncer::ModelTypeSet types(syncer::BOOKMARKS, syncer::APPS); + DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); + // OnAllDataTypesReadyForConfigure shouldn't be called, APPS data type is not + // loaded yet. + EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()).Times(0); + + model_association_manager.Initialize(types); + + EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), + DataTypeController::MODEL_STARTING); + EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), + DataTypeController::MODEL_STARTING); + + testing::Mock::VerifyAndClearExpectations(&delegate_); + + EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()); + // Finish loading APPS. This should trigger OnAllDataTypesReadyForConfigure + // even though BOOKMARKS is not loaded yet. + GetController(controllers_, syncer::APPS)->SimulateModelLoadFinishing(); + EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), + DataTypeController::MODEL_STARTING); + EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), + DataTypeController::MODEL_LOADED); + + // Call ModelAssociationManager::Initialize with reduced set of datatypes. + // All datatypes in reduced set are already loaded. + // OnAllDataTypesReadyForConfigure() should be called. + testing::Mock::VerifyAndClearExpectations(&delegate_); + + EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()); + syncer::ModelTypeSet reduced_types(syncer::APPS); + model_association_manager.Initialize(reduced_types); +} + +// Test that OnAllDataTypesReadyForConfigure() is called correctly after +// LoadModels fails for one of datatypes. +TEST_F(SyncModelAssociationManagerTest, + OnAllDataTypesReadyForConfigure_FailedLoadModels) { + controllers_[syncer::APPS] = new FakeDataTypeController(syncer::APPS); + GetController(controllers_, syncer::APPS)->SetDelayModelLoad(); + + // APPS controller requires LoadModels complete before configure. + GetController(controllers_, syncer::APPS) + ->SetShouldLoadModelBeforeConfigure(true); + + ModelAssociationManager model_association_manager(&controllers_, &delegate_); + syncer::ModelTypeSet types(syncer::APPS); + DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); + // OnAllDataTypesReadyForConfigure shouldn't be called, APPS data type is not + // loaded yet. + EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()).Times(0); + + model_association_manager.Initialize(types); + + EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), + DataTypeController::MODEL_STARTING); + + testing::Mock::VerifyAndClearExpectations(&delegate_); + + EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()); + // Simulate model load error for APPS and finish loading it. This should + // trigger OnAllDataTypesReadyForConfigure. + GetController(controllers_, syncer::APPS) + ->SetModelLoadError(syncer::SyncError( + FROM_HERE, syncer::SyncError::DATATYPE_ERROR, "", syncer::APPS)); + GetController(controllers_, syncer::APPS)->SimulateModelLoadFinishing(); + EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), + DataTypeController::NOT_RUNNING); +} + +// Test that if one of the types fails while another is still being loaded then +// OnAllDataTypesReadyForConfgiure is still called correctly. +TEST_F(SyncModelAssociationManagerTest, + OnAllDataTypesReadyForConfigure_TypeFailedAfterLoadModels) { + // Create two controllers with delayed model load. Both should block + // configuration. + controllers_[syncer::BOOKMARKS] = + new FakeDataTypeController(syncer::BOOKMARKS); + controllers_[syncer::APPS] = new FakeDataTypeController(syncer::APPS); + GetController(controllers_, syncer::BOOKMARKS)->SetDelayModelLoad(); + GetController(controllers_, syncer::APPS)->SetDelayModelLoad(); + + GetController(controllers_, syncer::BOOKMARKS) + ->SetShouldLoadModelBeforeConfigure(true); + GetController(controllers_, syncer::APPS) + ->SetShouldLoadModelBeforeConfigure(true); + + ModelAssociationManager model_association_manager(&controllers_, &delegate_); + syncer::ModelTypeSet types(syncer::BOOKMARKS, syncer::APPS); + DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); + + // Apps will finish loading but bookmarks won't. + // OnAllDataTypesReadyForConfigure shouldn't be called. + EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()).Times(0); + + model_association_manager.Initialize(types); + + GetController(controllers_, syncer::APPS)->SimulateModelLoadFinishing(); + + EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), + DataTypeController::MODEL_STARTING); + EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), + DataTypeController::MODEL_LOADED); + + testing::Mock::VerifyAndClearExpectations(&delegate_); + + EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()).Times(0); + + EXPECT_CALL(delegate_, OnSingleDataTypeWillStop(syncer::APPS, _)); + // Apps datatype reports failure. + syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, "error", + syncer::APPS); + GetController(controllers_, syncer::APPS) + ->OnSingleDataTypeUnrecoverableError(error); + + testing::Mock::VerifyAndClearExpectations(&delegate_); + + EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()); + // Finish loading BOOKMARKS. This should trigger + // OnAllDataTypesReadyForConfigure(). + GetController(controllers_, syncer::BOOKMARKS)->SimulateModelLoadFinishing(); + EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), + DataTypeController::MODEL_LOADED); +} + +} // namespace sync_driver
diff --git a/components/sync/driver/model_associator.h b/components/sync/driver/model_associator.h new file mode 100644 index 0000000..12631619 --- /dev/null +++ b/components/sync/driver/model_associator.h
@@ -0,0 +1,96 @@ +// 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 COMPONENTS_SYNC_DRIVER_MODEL_ASSOCIATOR_H_ +#define COMPONENTS_SYNC_DRIVER_MODEL_ASSOCIATOR_H_ + +#include <stdint.h> + +#include "base/synchronization/lock.h" +#include "components/sync/api/sync_error.h" +#include "components/sync/base/model_type.h" + +namespace syncer { +class BaseNode; +class SyncMergeResult; +} + +namespace sync_driver { + +// This represents the fundamental operations used for model association that +// are common to all ModelAssociators and do not depend on types of the models +// being associated. +class AssociatorInterface { + public: + virtual ~AssociatorInterface() {} + + // Iterates through both the sync and the chrome model looking for + // matched pairs of items. After successful completion, the models + // should be identical and corresponding. Returns true on + // success. On failure of this step, we should abort the sync + // operation and report an error to the user. + virtual syncer::SyncError AssociateModels( + syncer::SyncMergeResult* local_merge_result, + syncer::SyncMergeResult* syncer_merge_result) = 0; + + // Clears all the associations between the chrome and sync models. + virtual syncer::SyncError DisassociateModels() = 0; + + // The has_nodes out parameter is set to true if the sync model has + // nodes other than the permanent tagged nodes. The method may + // return false if an error occurred. + virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes) = 0; + + // Calling this method while AssociateModels() is in progress will + // cause the method to exit early with a "false" return value. This + // is useful for aborting model associations for shutdown. This + // method is only implemented for model associators that are invoked + // off the main thread. + virtual void AbortAssociation() = 0; + + // Returns whether the datatype is ready for encryption/decryption if the + // sync service requires it. + // TODO(zea): This should be implemented automatically for each datatype, see + // http://crbug.com/76232. + virtual bool CryptoReadyIfNecessary() = 0; +}; + +// In addition to the generic methods, association can refer to operations +// that depend on the types of the actual IDs we are associating and the +// underlying node type in the browser. We collect these into a templatized +// interface that encapsulates everything you need to implement to have a model +// associator for a specific data type. +// This template is appropriate for data types where a Node* makes sense for +// referring to a particular item. If we encounter a type that does not fit +// in this world, we may want to have several PerDataType templates. +template <class Node, class IDType> +class PerDataTypeAssociatorInterface : public AssociatorInterface { + public: + virtual ~PerDataTypeAssociatorInterface() {} + // Returns sync id for the given chrome model id. + // Returns syncer::kInvalidId if the sync node is not found for the given + // chrome id. + virtual int64_t GetSyncIdFromChromeId(const IDType& id) = 0; + + // Returns the chrome node for the given sync id. + // Returns NULL if no node is found for the given sync id. + virtual const Node* GetChromeNodeFromSyncId(int64_t sync_id) = 0; + + // Initializes the given sync node from the given chrome node id. + // Returns false if no sync node was found for the given chrome node id or + // if the initialization of sync node fails. + virtual bool InitSyncNodeFromChromeId(const IDType& node_id, + syncer::BaseNode* sync_node) = 0; + + // Associates the given chrome node with the given sync node. + virtual void Associate(const Node* node, + const syncer::BaseNode& sync_node) = 0; + + // Remove the association that corresponds to the given sync id. + virtual void Disassociate(int64_t sync_id) = 0; +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_MODEL_ASSOCIATOR_H_
diff --git a/components/sync/driver/model_associator_mock.cc b/components/sync/driver/model_associator_mock.cc new file mode 100644 index 0000000..581caab --- /dev/null +++ b/components/sync/driver/model_associator_mock.cc
@@ -0,0 +1,13 @@ +// 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 "components/sync/driver/model_associator_mock.h" + +namespace sync_driver { + +ModelAssociatorMock::ModelAssociatorMock() {} + +ModelAssociatorMock::~ModelAssociatorMock() {} + +} // namespace sync_driver
diff --git a/components/sync/driver/model_associator_mock.h b/components/sync/driver/model_associator_mock.h new file mode 100644 index 0000000..8edbf78 --- /dev/null +++ b/components/sync/driver/model_associator_mock.h
@@ -0,0 +1,35 @@ +// 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 COMPONENTS_SYNC_DRIVER_MODEL_ASSOCIATOR_MOCK_H__ +#define COMPONENTS_SYNC_DRIVER_MODEL_ASSOCIATOR_MOCK_H__ + +#include "base/location.h" +#include "components/sync/api/sync_error.h" +#include "components/sync/driver/model_associator.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace sync_driver { + +ACTION_P(SetSyncError, type) { + arg0->Reset(FROM_HERE, "test", type); +} + +class ModelAssociatorMock : public AssociatorInterface { + public: + ModelAssociatorMock(); + virtual ~ModelAssociatorMock(); + + MOCK_METHOD2(AssociateModels, + syncer::SyncError(syncer::SyncMergeResult*, + syncer::SyncMergeResult*)); + MOCK_METHOD0(DisassociateModels, syncer::SyncError()); + MOCK_METHOD1(SyncModelHasUserCreatedNodes, bool(bool* has_nodes)); + MOCK_METHOD0(AbortAssociation, void()); + MOCK_METHOD0(CryptoReadyIfNecessary, bool()); +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_MODEL_ASSOCIATOR_MOCK_H__
diff --git a/components/sync/driver/non_blocking_data_type_controller.cc b/components/sync/driver/non_blocking_data_type_controller.cc new file mode 100644 index 0000000..6f4a6c1 --- /dev/null +++ b/components/sync/driver/non_blocking_data_type_controller.cc
@@ -0,0 +1,267 @@ +// 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 "components/sync/driver/non_blocking_data_type_controller.h" + +#include <utility> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/location.h" +#include "base/single_thread_task_runner.h" +#include "components/sync/api/model_type_change_processor.h" +#include "components/sync/api/model_type_service.h" +#include "components/sync/api/sync_error.h" +#include "components/sync/api/sync_merge_result.h" +#include "components/sync/base/data_type_histogram.h" +#include "components/sync/core/activation_context.h" +#include "components/sync/driver/backend_data_type_configurer.h" +#include "components/sync/driver/sync_client.h" + +namespace sync_driver_v2 { + +NonBlockingDataTypeController::NonBlockingDataTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const base::Closure& error_callback, + syncer::ModelType model_type, + sync_driver::SyncClient* sync_client) + : sync_driver::DataTypeController(ui_thread, error_callback), + model_type_(model_type), + sync_client_(sync_client), + sync_prefs_(sync_client->GetPrefService()), + state_(NOT_RUNNING) { + DCHECK(BelongsToUIThread()); +} + +NonBlockingDataTypeController::~NonBlockingDataTypeController() {} + +bool NonBlockingDataTypeController::ShouldLoadModelBeforeConfigure() const { + // USS datatypes require loading models because model controls storage where + // data type context and progress marker are persisted. + return true; +} + +void NonBlockingDataTypeController::LoadModels( + const ModelLoadCallback& model_load_callback) { + DCHECK(ui_thread()->BelongsToCurrentThread()); + DCHECK(!model_load_callback.is_null()); + model_load_callback_ = model_load_callback; + + if (state() != NOT_RUNNING) { + LoadModelsDone( + RUNTIME_ERROR, + syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Model already running", type())); + return; + } + + state_ = MODEL_STARTING; + + // Start the type processor on the model thread. + if (!RunOnModelThread( + FROM_HERE, + base::Bind(&NonBlockingDataTypeController::LoadModelsOnModelThread, + this))) { + LoadModelsDone( + UNRECOVERABLE_ERROR, + syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Failed to post model Start", type())); + } +} + +void NonBlockingDataTypeController::LoadModelsOnModelThread() { + syncer_v2::ModelTypeService* model_type_service = + sync_client_->GetModelTypeServiceForType(type()); + if (!model_type_service) { + LOG(WARNING) << "ModelTypeService destroyed before " + "ModelTypeController was started."; + // TODO(gangwu): Add SyncError and then call start_callback with it. Also + // set an error state to |state_|. + return; + } + + model_type_service->OnSyncStarting( + this, + base::Bind(&NonBlockingDataTypeController::OnProcessorStarted, this)); +} + +void NonBlockingDataTypeController::LoadModelsDone( + ConfigureResult result, + const syncer::SyncError& error) { + DCHECK(BelongsToUIThread()); + + if (state_ == NOT_RUNNING) { + // The callback arrived on the UI thread after the type has been already + // stopped. + RecordStartFailure(ABORTED); + return; + } + + if (IsSuccessfulResult(result)) { + DCHECK_EQ(MODEL_STARTING, state_); + state_ = MODEL_LOADED; + } else { + RecordStartFailure(result); + } + + if (!model_load_callback_.is_null()) { + model_load_callback_.Run(type(), error); + } +} + +void NonBlockingDataTypeController::OnProcessorStarted( + syncer::SyncError error, + std::unique_ptr<syncer_v2::ActivationContext> activation_context) { + RunOnUIThread( + FROM_HERE, + base::Bind(&NonBlockingDataTypeController::OnProcessorStartedOnUIThread, + this, error, base::Passed(std::move(activation_context)))); +} + +void NonBlockingDataTypeController::OnProcessorStartedOnUIThread( + syncer::SyncError error, + std::unique_ptr<syncer_v2::ActivationContext> activation_context) { + DCHECK(BelongsToUIThread()); + // Hold on to the activation context until ActivateDataType is called. + if (state_ == MODEL_STARTING) { + activation_context_ = std::move(activation_context); + } + // TODO(stanisc): Figure out if UNRECOVERABLE_ERROR is OK in this case. + ConfigureResult result = error.IsSet() ? UNRECOVERABLE_ERROR : OK; + LoadModelsDone(result, error); +} + +void NonBlockingDataTypeController::RegisterWithBackend( + sync_driver::BackendDataTypeConfigurer* configurer) { + DCHECK(BelongsToUIThread()); + DCHECK(configurer); + DCHECK(activation_context_); + DCHECK_EQ(MODEL_LOADED, state_); + configurer->ActivateNonBlockingDataType(type(), + std::move(activation_context_)); +} + +void NonBlockingDataTypeController::StartAssociating( + const StartCallback& start_callback) { + DCHECK(BelongsToUIThread()); + DCHECK(!start_callback.is_null()); + + state_ = RUNNING; + + // There is no association, just call back promptly. + syncer::SyncMergeResult merge_result(type()); + start_callback.Run(OK, merge_result, merge_result); +} + +void NonBlockingDataTypeController::ActivateDataType( + sync_driver::BackendDataTypeConfigurer* configurer) { + DCHECK(BelongsToUIThread()); + DCHECK(configurer); + DCHECK_EQ(RUNNING, state_); + // In contrast with directory datatypes, non-blocking data types should be + // activated in RegisterWithBackend. activation_context_ should be passed + // to backend before call to ActivateDataType. + DCHECK(!activation_context_); +} + +void NonBlockingDataTypeController::DeactivateDataType( + sync_driver::BackendDataTypeConfigurer* configurer) { + DCHECK(BelongsToUIThread()); + DCHECK(configurer); + configurer->DeactivateNonBlockingDataType(type()); +} + +void NonBlockingDataTypeController::Stop() { + DCHECK(ui_thread()->BelongsToCurrentThread()); + + if (state() == NOT_RUNNING) + return; + + // Check preferences if datatype is not in preferred datatypes. Only call + // DisableSync if service is ready to handle it (controller is in loaded + // state). + syncer::ModelTypeSet preferred_types = + sync_prefs_.GetPreferredDataTypes(syncer::ModelTypeSet(type())); + if ((state() == MODEL_LOADED || state() == RUNNING) && + (!sync_prefs_.IsFirstSetupComplete() || !preferred_types.Has(type()))) { + RunOnModelThread( + FROM_HERE, + base::Bind(&NonBlockingDataTypeController::DisableSyncOnModelThread, + this)); + } + + state_ = NOT_RUNNING; +} + +void NonBlockingDataTypeController::DisableSyncOnModelThread() { + syncer_v2::ModelTypeService* model_type_service = + sync_client_->GetModelTypeServiceForType(type()); + DCHECK(model_type_service); + model_type_service->DisableSync(); +} + +std::string NonBlockingDataTypeController::name() const { + // For logging only. + return syncer::ModelTypeToString(type()); +} + +sync_driver::DataTypeController::State NonBlockingDataTypeController::state() + const { + return state_; +} + +bool NonBlockingDataTypeController::BelongsToUIThread() const { + return ui_thread()->BelongsToCurrentThread(); +} + +void NonBlockingDataTypeController::OnSingleDataTypeUnrecoverableError( + const syncer::SyncError& error) { + RecordUnrecoverableError(); + if (!error_callback_.is_null()) + error_callback_.Run(); + + ReportLoadModelError(UNRECOVERABLE_ERROR, error); +} + +void NonBlockingDataTypeController::ReportLoadModelError( + ConfigureResult result, + const syncer::SyncError& error) { + DCHECK(!IsSuccessfulResult(result)); + if (BelongsToUIThread()) { + // Report the error only if the model is starting. + if (state_ == MODEL_STARTING) { + LoadModelsDone(result, error); + } + } else { + RunOnUIThread( + error.location(), + base::Bind(&NonBlockingDataTypeController::ReportLoadModelError, this, + result, error)); + } +} + +void NonBlockingDataTypeController::RecordStartFailure( + ConfigureResult result) const { + DCHECK(BelongsToUIThread()); + UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", + ModelTypeToHistogramInt(type()), + syncer::MODEL_TYPE_COUNT); +#define PER_DATA_TYPE_MACRO(type_str) \ + UMA_HISTOGRAM_ENUMERATION("Sync." type_str "ConfigureFailure", result, \ + MAX_CONFIGURE_RESULT); + SYNC_DATA_TYPE_HISTOGRAM(type()); +#undef PER_DATA_TYPE_MACRO +} + +void NonBlockingDataTypeController::RecordUnrecoverableError() { + UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeRunFailures", + ModelTypeToHistogramInt(type()), + syncer::MODEL_TYPE_COUNT); +} + +syncer::ModelType NonBlockingDataTypeController::type() const { + return model_type_; +} + +} // namespace sync_driver_v2
diff --git a/components/sync/driver/non_blocking_data_type_controller.h b/components/sync/driver/non_blocking_data_type_controller.h new file mode 100644 index 0000000..b8c61d2 --- /dev/null +++ b/components/sync/driver/non_blocking_data_type_controller.h
@@ -0,0 +1,137 @@ +// 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 COMPONENTS_SYNC_DRIVER_NON_BLOCKING_DATA_TYPE_CONTROLLER_H_ +#define COMPONENTS_SYNC_DRIVER_NON_BLOCKING_DATA_TYPE_CONTROLLER_H_ + +#include <memory> +#include <string> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "components/sync/base/model_type.h" +#include "components/sync/driver/data_type_controller.h" +#include "components/sync/driver/sync_prefs.h" + +namespace sync_driver { +class SyncClient; +} + +namespace syncer_v2 { +struct ActivationContext; +} + +namespace sync_driver_v2 { + +// Base class for DataType controllers for Unified Sync and Storage datatypes. +// Derived types must implement the following methods: +// - RunOnModelThread +// - RunOnUIThread +class NonBlockingDataTypeController : public sync_driver::DataTypeController { + public: + NonBlockingDataTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const base::Closure& error_callback, + syncer::ModelType model_type, + sync_driver::SyncClient* sync_client); + + // DataTypeErrorHandler interface. + void OnSingleDataTypeUnrecoverableError( + const syncer::SyncError& error) override; + + // DataTypeController interface. + bool ShouldLoadModelBeforeConfigure() const override; + void LoadModels(const ModelLoadCallback& model_load_callback) override; + + // Registers non-blocking data type with sync backend. In the process the + // activation context is passed to ModelTypeRegistry, where ModelTypeWorker + // gets created and connected with ModelTypeProcessor. + void RegisterWithBackend( + sync_driver::BackendDataTypeConfigurer* configurer) override; + void StartAssociating(const StartCallback& start_callback) override; + void ActivateDataType( + sync_driver::BackendDataTypeConfigurer* configurer) override; + void DeactivateDataType( + sync_driver::BackendDataTypeConfigurer* configurer) override; + void Stop() override; + std::string name() const override; + State state() const override; + syncer::ModelType type() const override; + + protected: + // DataTypeController is RefCounted. + ~NonBlockingDataTypeController() override; + + // Returns true if the call is made on UI thread. + bool BelongsToUIThread() const; + + // Posts the given task to the model thread, i.e. the thread the + // datatype lives on. Return value: True if task posted successfully, + // false otherwise. + virtual bool RunOnModelThread(const tracked_objects::Location& from_here, + const base::Closure& task) = 0; + + // Post the given task on the UI thread. If the call is made on UI thread + // already, make a direct call without posting. + virtual void RunOnUIThread(const tracked_objects::Location& from_here, + const base::Closure& task) = 0; + + private: + void RecordStartFailure(ConfigureResult result) const; + void RecordUnrecoverableError(); + void ReportLoadModelError(ConfigureResult result, + const syncer::SyncError& error); + + // If the DataType controller is waiting for models to load, once the models + // are loaded this function should be called to let the base class + // implementation know that it is safe to continue with the activation. + // The error indicates whether the loading completed successfully. + void LoadModelsDone(ConfigureResult result, const syncer::SyncError& error); + + // Callback passed to the processor to be invoked when the processor has + // started. This is called on the model thread. + void OnProcessorStarted( + syncer::SyncError error, + std::unique_ptr<syncer_v2::ActivationContext> activation_context); + + // The function will do the real work when OnProcessorStarted got called. This + // is called on the UI thread. + void OnProcessorStartedOnUIThread( + syncer::SyncError error, + std::unique_ptr<syncer_v2::ActivationContext> activation_context); + + // The function LoadModels() will call this function to do some works which + // need to be done on model thread. + void LoadModelsOnModelThread(); + + // Stop() posts call to DisableSyncOnModelThread to model thread when it + // decides sync metadata should be cleared. + void DisableSyncOnModelThread(); + + // Model Type for this controller + syncer::ModelType model_type_; + + // Sync client + sync_driver::SyncClient* const sync_client_; + + // Sync prefs. Used for determinig if DisableSync should be called during call + // to Stop(). + sync_driver::SyncPrefs sync_prefs_; + + // State of this datatype controller. + State state_; + + // Callbacks for use when starting the datatype. + ModelLoadCallback model_load_callback_; + + // Controller receives |activation_context_| from SharedModelTypeProcessor + // callback and must temporarily own it until ActivateDataType is called. + std::unique_ptr<syncer_v2::ActivationContext> activation_context_; + + DISALLOW_COPY_AND_ASSIGN(NonBlockingDataTypeController); +}; + +} // namespace sync_driver_v2 + +#endif // COMPONENTS_SYNC_DRIVER_NON_BLOCKING_DATA_TYPE_CONTROLLER_H_
diff --git a/components/sync/driver/non_blocking_data_type_controller_unittest.cc b/components/sync/driver/non_blocking_data_type_controller_unittest.cc new file mode 100644 index 0000000..9e651c28 --- /dev/null +++ b/components/sync/driver/non_blocking_data_type_controller_unittest.cc
@@ -0,0 +1,214 @@ +// Copyright 2016 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/sync/driver/non_blocking_data_type_controller.h" + +#include <memory> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "components/sync/api/fake_model_type_change_processor.h" +#include "components/sync/api/fake_model_type_service.h" +#include "components/sync/base/model_type.h" +#include "components/sync/driver/fake_sync_client.h" +#include "components/sync/driver/sync_prefs.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace sync_driver { +class SyncClient; +} // namespace sync_driver + +namespace sync_driver_v2 { + +namespace { + +syncer::ModelType kTestModelType = syncer::AUTOFILL; + +// Implementation of NonBlockingDataTypeController being tested. +// It posts all tasks to current thread. +class TestDataTypeController : public NonBlockingDataTypeController { + public: + TestDataTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& thread, + sync_driver::SyncClient* sync_client) + : NonBlockingDataTypeController(thread, + base::Closure(), + kTestModelType, + sync_client) {} + + protected: + ~TestDataTypeController() override {} + + bool RunOnModelThread(const tracked_objects::Location& from_here, + const base::Closure& task) override { + ui_thread()->PostTask(from_here, task); + return true; + } + + void RunOnUIThread(const tracked_objects::Location& from_here, + const base::Closure& task) override { + ui_thread()->PostTask(from_here, task); + } +}; + +// Mock change processor to observe calls to DisableSync. +class MockModelTypeChangeProcessor + : public syncer_v2::FakeModelTypeChangeProcessor { + public: + explicit MockModelTypeChangeProcessor(int* disable_sync_call_count) + : disable_sync_call_count_(disable_sync_call_count) {} + + void DisableSync() override { (*disable_sync_call_count_)++; } + + private: + int* disable_sync_call_count_; +}; + +class NonBlockingDataTypeControllerTest : public testing::Test { + public: + NonBlockingDataTypeControllerTest() + : disable_sync_call_count_(0), + sync_prefs_(sync_client_.GetPrefService()), + model_type_service_( + base::Bind(&NonBlockingDataTypeControllerTest::CreateProcessor, + base::Unretained(this))) {} + + void SetUp() override { + sync_client_.SetModelTypeService(&model_type_service_); + controller_ = + new TestDataTypeController(message_loop_.task_runner(), &sync_client_); + } + + void TearDown() override { + controller_ = nullptr; + PumpLoop(); + } + + protected: + std::unique_ptr<syncer_v2::ModelTypeChangeProcessor> CreateProcessor( + syncer::ModelType type, + syncer_v2::ModelTypeService* service) { + auto processor = base::MakeUnique<MockModelTypeChangeProcessor>( + &disable_sync_call_count_); + processor_ = processor.get(); + return std::move(processor); + } + + // Gets controller from NOT_RUNNING to RUNNING state. + void ActivateController() { + EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, + controller_->state()); + controller_->LoadModels( + base::Bind(&NonBlockingDataTypeControllerTest::LoadModelsDone, + base::Unretained(this))); + + EXPECT_EQ(sync_driver::DataTypeController::MODEL_STARTING, + controller_->state()); + PumpLoop(); + EXPECT_EQ(sync_driver::DataTypeController::MODEL_LOADED, + controller_->state()); + controller_->StartAssociating( + base::Bind(&NonBlockingDataTypeControllerTest::AssociationDone, + base::Unretained(this))); + EXPECT_EQ(sync_driver::DataTypeController::RUNNING, controller_->state()); + } + + void LoadModelsDone(syncer::ModelType type, syncer::SyncError error) {} + + void AssociationDone(sync_driver::DataTypeController::ConfigureResult result, + const syncer::SyncMergeResult& local_merge_result, + const syncer::SyncMergeResult& syncer_merge_result) {} + + void PumpLoop() { base::RunLoop().RunUntilIdle(); } + + int disable_sync_call_count_; + base::MessageLoop message_loop_; + sync_driver::FakeSyncClient sync_client_; + sync_driver::SyncPrefs sync_prefs_; + MockModelTypeChangeProcessor* processor_; + syncer_v2::FakeModelTypeService model_type_service_; + scoped_refptr<TestDataTypeController> controller_; +}; + +// Test emulates normal browser shutdown. Ensures that DisableSync is not +// called. +TEST_F(NonBlockingDataTypeControllerTest, StopWhenDatatypeEnabled) { + // Enable datatype through preferences. + sync_prefs_.SetFirstSetupComplete(); + sync_prefs_.SetKeepEverythingSynced(true); + + ActivateController(); + + controller_->Stop(); + PumpLoop(); + EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); + // Ensure that DisableSync is not called and service still has valid change + // processor. + EXPECT_EQ(0, disable_sync_call_count_); + EXPECT_TRUE(model_type_service_.HasChangeProcessor()); +} + +// Test emulates scenario when user disables datatype. DisableSync should be +// called. +TEST_F(NonBlockingDataTypeControllerTest, StopWhenDatatypeDisabled) { + // Enable datatype through preferences. + sync_prefs_.SetFirstSetupComplete(); + sync_prefs_.SetKeepEverythingSynced(true); + ActivateController(); + + // Disable datatype through preferences. + sync_prefs_.SetKeepEverythingSynced(false); + sync_prefs_.SetPreferredDataTypes(syncer::ModelTypeSet(kTestModelType), + syncer::ModelTypeSet()); + + controller_->Stop(); + PumpLoop(); + EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); + // Ensure that DisableSync is called and change processor is reset. + EXPECT_EQ(1, disable_sync_call_count_); + EXPECT_FALSE(model_type_service_.HasChangeProcessor()); +} + +// Test emulates disabling sync by signing out. DisableSync should be called. +TEST_F(NonBlockingDataTypeControllerTest, StopWithInitialSyncPrefs) { + // Enable datatype through preferences. + sync_prefs_.SetFirstSetupComplete(); + sync_prefs_.SetKeepEverythingSynced(true); + ActivateController(); + + // Clearing preferences emulates signing out. + sync_prefs_.ClearPreferences(); + controller_->Stop(); + PumpLoop(); + EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); + // Ensure that DisableSync is called and change processor is reset. + EXPECT_EQ(1, disable_sync_call_count_); + EXPECT_FALSE(model_type_service_.HasChangeProcessor()); +} + +// Test emulates disabling sync when datatype is not loaded yet. DisableSync +// should not be called as service is potentially not ready to handle it. +TEST_F(NonBlockingDataTypeControllerTest, StopBeforeLoadModels) { + // Enable datatype through preferences. + sync_prefs_.SetFirstSetupComplete(); + sync_prefs_.SetKeepEverythingSynced(true); + EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); + + // Clearing preferences emulates signing out. + sync_prefs_.ClearPreferences(); + controller_->Stop(); + PumpLoop(); + EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); + // Ensure that DisableSync is not called. + EXPECT_EQ(0, disable_sync_call_count_); +} + +} // namespace + +} // namespace sync_driver_v2
diff --git a/components/sync/driver/non_ui_data_type_controller.cc b/components/sync/driver/non_ui_data_type_controller.cc new file mode 100644 index 0000000..a3e4f6f --- /dev/null +++ b/components/sync/driver/non_ui_data_type_controller.cc
@@ -0,0 +1,395 @@ +// 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 "components/sync/driver/non_ui_data_type_controller.h" + +#include "base/logging.h" +#include "base/memory/weak_ptr.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/sync/api/sync_error.h" +#include "components/sync/api/sync_merge_result.h" +#include "components/sync/api/syncable_service.h" +#include "components/sync/base/data_type_histogram.h" +#include "components/sync/base/model_type.h" +#include "components/sync/driver/generic_change_processor_factory.h" +#include "components/sync/driver/shared_change_processor_ref.h" +#include "components/sync/driver/sync_api_component_factory.h" +#include "components/sync/driver/sync_client.h" +#include "components/sync/driver/sync_service.h" + +namespace sync_driver { + +SharedChangeProcessor* NonUIDataTypeController::CreateSharedChangeProcessor() { + return new SharedChangeProcessor(); +} + +NonUIDataTypeController::NonUIDataTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const base::Closure& error_callback, + SyncClient* sync_client) + : DirectoryDataTypeController(ui_thread, error_callback), + sync_client_(sync_client), + state_(NOT_RUNNING), + ui_thread_(ui_thread) {} + +void NonUIDataTypeController::LoadModels( + const ModelLoadCallback& model_load_callback) { + DCHECK(ui_thread_->BelongsToCurrentThread()); + model_load_callback_ = model_load_callback; + if (state() != NOT_RUNNING) { + model_load_callback.Run( + type(), syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Model already running", type())); + return; + } + + state_ = MODEL_STARTING; + // Since we can't be called multiple times before Stop() is called, + // |shared_change_processor_| must be NULL here. + DCHECK(!shared_change_processor_.get()); + shared_change_processor_ = CreateSharedChangeProcessor(); + DCHECK(shared_change_processor_.get()); + if (!StartModels()) { + // If we are waiting for some external service to load before associating + // or we failed to start the models, we exit early. + DCHECK(state() == MODEL_STARTING || state() == NOT_RUNNING); + return; + } + + OnModelLoaded(); +} + +void NonUIDataTypeController::OnModelLoaded() { + DCHECK_EQ(state_, MODEL_STARTING); + state_ = MODEL_LOADED; + model_load_callback_.Run(type(), syncer::SyncError()); +} + +bool NonUIDataTypeController::StartModels() { + DCHECK_EQ(state_, MODEL_STARTING); + // By default, no additional services need to be started before we can proceed + // with model association. + return true; +} + +void NonUIDataTypeController::StopModels() { + DCHECK(ui_thread_->BelongsToCurrentThread()); +} + +void NonUIDataTypeController::StartAssociating( + const StartCallback& start_callback) { + DCHECK(ui_thread_->BelongsToCurrentThread()); + DCHECK(!start_callback.is_null()); + DCHECK_EQ(state_, MODEL_LOADED); + state_ = ASSOCIATING; + + // Store UserShare now while on UI thread to avoid potential race + // condition in StartAssociationWithSharedChangeProcessor. + DCHECK(sync_client_->GetSyncService()); + user_share_ = sync_client_->GetSyncService()->GetUserShare(); + + start_callback_ = start_callback; + if (!StartAssociationAsync()) { + syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Failed to post StartAssociation", type()); + syncer::SyncMergeResult local_merge_result(type()); + local_merge_result.set_error(error); + StartDoneImpl(ASSOCIATION_FAILED, NOT_RUNNING, local_merge_result, + syncer::SyncMergeResult(type())); + // StartDoneImpl should have called ClearSharedChangeProcessor(); + DCHECK(!shared_change_processor_.get()); + return; + } +} + +void NonUIDataTypeController::Stop() { + DCHECK(ui_thread_->BelongsToCurrentThread()); + + if (state() == NOT_RUNNING) + return; + + // Disconnect the change processor. At this point, the + // syncer::SyncableService can no longer interact with the Syncer, even if + // it hasn't finished MergeDataAndStartSyncing. + ClearSharedChangeProcessor(); + + // If we haven't finished starting, we need to abort the start. + switch (state()) { + case MODEL_STARTING: + state_ = STOPPING; + AbortModelLoad(); + return; // The datatype was never activated, we're done. + case ASSOCIATING: + state_ = STOPPING; + StopModels(); + // We continue on to deactivate the datatype and stop the local service. + break; + case MODEL_LOADED: + case DISABLED: + // If DTC is loaded or disabled, we never attempted or succeeded + // associating and never activated the datatype. We would have already + // stopped the local service in StartDoneImpl(..). + state_ = NOT_RUNNING; + StopModels(); + return; + default: + // Datatype was fully started. Need to deactivate and stop the local + // service. + DCHECK_EQ(state(), RUNNING); + state_ = STOPPING; + StopModels(); + break; + } + + // Stop the local service and release our references to it and the + // shared change processor (posts a task to the datatype's thread). + StopLocalServiceAsync(); + + state_ = NOT_RUNNING; +} + +std::string NonUIDataTypeController::name() const { + // For logging only. + return syncer::ModelTypeToString(type()); +} + +DataTypeController::State NonUIDataTypeController::state() const { + return state_; +} + +void NonUIDataTypeController::OnSingleDataTypeUnrecoverableError( + const syncer::SyncError& error) { + DCHECK(!ui_thread_->BelongsToCurrentThread()); + // TODO(tim): We double-upload some errors. See bug 383480. + if (!error_callback_.is_null()) + error_callback_.Run(); + ui_thread_->PostTask( + error.location(), + base::Bind(&NonUIDataTypeController::DisableImpl, this, error)); +} + +NonUIDataTypeController::NonUIDataTypeController() + : DirectoryDataTypeController(base::ThreadTaskRunnerHandle::Get(), + base::Closure()), + sync_client_(NULL) {} + +NonUIDataTypeController::~NonUIDataTypeController() {} + +void NonUIDataTypeController::StartDone( + DataTypeController::ConfigureResult start_result, + const syncer::SyncMergeResult& local_merge_result, + const syncer::SyncMergeResult& syncer_merge_result) { + DCHECK(!ui_thread_->BelongsToCurrentThread()); + + DataTypeController::State new_state; + if (IsSuccessfulResult(start_result)) { + new_state = RUNNING; + } else { + new_state = (start_result == ASSOCIATION_FAILED ? DISABLED : NOT_RUNNING); + } + + ui_thread_->PostTask( + FROM_HERE, + base::Bind(&NonUIDataTypeController::StartDoneImpl, this, start_result, + new_state, local_merge_result, syncer_merge_result)); +} + +void NonUIDataTypeController::StartDoneImpl( + DataTypeController::ConfigureResult start_result, + DataTypeController::State new_state, + const syncer::SyncMergeResult& local_merge_result, + const syncer::SyncMergeResult& syncer_merge_result) { + DCHECK(ui_thread_->BelongsToCurrentThread()); + + // If we failed to start up, and we haven't been stopped yet, we need to + // ensure we clean up the local service and shared change processor properly. + if (new_state != RUNNING && state() != NOT_RUNNING && state() != STOPPING) { + ClearSharedChangeProcessor(); + StopLocalServiceAsync(); + } + + // It's possible to have StartDoneImpl called first from the UI thread + // (due to Stop being called) and then posted from the non-UI thread. In + // this case, we drop the second call because we've already been stopped. + if (state_ == NOT_RUNNING) { + return; + } + + state_ = new_state; + if (state_ != RUNNING) { + // Start failed. + StopModels(); + RecordStartFailure(start_result); + } + + start_callback_.Run(start_result, local_merge_result, syncer_merge_result); +} + +void NonUIDataTypeController::RecordAssociationTime(base::TimeDelta time) { + DCHECK(!ui_thread_->BelongsToCurrentThread()); +#define PER_DATA_TYPE_MACRO(type_str) \ + UMA_HISTOGRAM_TIMES("Sync." type_str "AssociationTime", time); + SYNC_DATA_TYPE_HISTOGRAM(type()); +#undef PER_DATA_TYPE_MACRO +} + +void NonUIDataTypeController::RecordStartFailure(ConfigureResult result) { + DCHECK(ui_thread_->BelongsToCurrentThread()); + UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", + ModelTypeToHistogramInt(type()), + syncer::MODEL_TYPE_COUNT); +#define PER_DATA_TYPE_MACRO(type_str) \ + UMA_HISTOGRAM_ENUMERATION("Sync." type_str "ConfigureFailure", result, \ + MAX_CONFIGURE_RESULT); + SYNC_DATA_TYPE_HISTOGRAM(type()); +#undef PER_DATA_TYPE_MACRO +} + +void NonUIDataTypeController::AbortModelLoad() { + state_ = NOT_RUNNING; + StopModels(); +} + +void NonUIDataTypeController::DisableImpl(const syncer::SyncError& error) { + DCHECK(ui_thread_->BelongsToCurrentThread()); + UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeRunFailures", + ModelTypeToHistogramInt(type()), + syncer::MODEL_TYPE_COUNT); + if (!model_load_callback_.is_null()) { + model_load_callback_.Run(type(), error); + } +} + +bool NonUIDataTypeController::StartAssociationAsync() { + DCHECK(ui_thread_->BelongsToCurrentThread()); + DCHECK_EQ(state(), ASSOCIATING); + return PostTaskOnBackendThread( + FROM_HERE, + base::Bind( + &NonUIDataTypeController::StartAssociationWithSharedChangeProcessor, + this, shared_change_processor_)); +} + +ChangeProcessor* NonUIDataTypeController::GetChangeProcessor() const { + DCHECK_EQ(state_, RUNNING); + return shared_change_processor_->generic_change_processor(); +} + +// This method can execute after we've already stopped (and possibly even +// destroyed) both the Syncer and the SyncableService. As a result, all actions +// must either have no side effects outside of the DTC or must be protected +// by |shared_change_processor|, which is guaranteed to have been Disconnected +// if the syncer shut down. +void NonUIDataTypeController::StartAssociationWithSharedChangeProcessor( + const scoped_refptr<SharedChangeProcessor>& shared_change_processor) { + DCHECK(!ui_thread_->BelongsToCurrentThread()); + DCHECK(shared_change_processor.get()); + DCHECK(user_share_); + syncer::SyncMergeResult local_merge_result(type()); + syncer::SyncMergeResult syncer_merge_result(type()); + base::WeakPtrFactory<syncer::SyncMergeResult> weak_ptr_factory( + &syncer_merge_result); + + // Connect |shared_change_processor| to the syncer and get the + // syncer::SyncableService associated with type(). + // Note that it's possible the shared_change_processor has already been + // disconnected at this point, so all our accesses to the syncer from this + // point on are through it. + GenericChangeProcessorFactory factory; + local_service_ = shared_change_processor->Connect( + sync_client_, &factory, user_share_, this, type(), + weak_ptr_factory.GetWeakPtr()); + if (!local_service_.get()) { + syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Failed to connect to syncer.", type()); + local_merge_result.set_error(error); + StartDone(ASSOCIATION_FAILED, local_merge_result, syncer_merge_result); + return; + } + + if (!shared_change_processor->CryptoReadyIfNecessary()) { + syncer::SyncError error(FROM_HERE, syncer::SyncError::CRYPTO_ERROR, "", + type()); + local_merge_result.set_error(error); + StartDone(NEEDS_CRYPTO, local_merge_result, syncer_merge_result); + return; + } + + bool sync_has_nodes = false; + if (!shared_change_processor->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { + syncer::SyncError error(FROM_HERE, syncer::SyncError::UNRECOVERABLE_ERROR, + "Failed to load sync nodes", type()); + local_merge_result.set_error(error); + StartDone(UNRECOVERABLE_ERROR, local_merge_result, syncer_merge_result); + return; + } + + // Scope for |initial_sync_data| which might be expensive, so we don't want + // to keep it in memory longer than necessary. + { + syncer::SyncDataList initial_sync_data; + + base::TimeTicks start_time = base::TimeTicks::Now(); + syncer::SyncError error = + shared_change_processor->GetAllSyncDataReturnError(type(), + &initial_sync_data); + if (error.IsSet()) { + local_merge_result.set_error(error); + StartDone(ASSOCIATION_FAILED, local_merge_result, syncer_merge_result); + return; + } + + std::string datatype_context; + if (shared_change_processor->GetDataTypeContext(&datatype_context)) { + local_service_->UpdateDataTypeContext( + type(), syncer::SyncChangeProcessor::NO_REFRESH, datatype_context); + } + + syncer_merge_result.set_num_items_before_association( + initial_sync_data.size()); + // Passes a reference to |shared_change_processor|. + local_merge_result = local_service_->MergeDataAndStartSyncing( + type(), initial_sync_data, + std::unique_ptr<syncer::SyncChangeProcessor>( + new SharedChangeProcessorRef(shared_change_processor)), + std::unique_ptr<syncer::SyncErrorFactory>( + new SharedChangeProcessorRef(shared_change_processor))); + RecordAssociationTime(base::TimeTicks::Now() - start_time); + if (local_merge_result.error().IsSet()) { + StartDone(ASSOCIATION_FAILED, local_merge_result, syncer_merge_result); + return; + } + } + + syncer_merge_result.set_num_items_after_association( + shared_change_processor->GetSyncCount()); + + StartDone(!sync_has_nodes ? OK_FIRST_RUN : OK, local_merge_result, + syncer_merge_result); +} + +void NonUIDataTypeController::ClearSharedChangeProcessor() { + DCHECK(ui_thread_->BelongsToCurrentThread()); + // |shared_change_processor_| can already be NULL if Stop() is + // called after StartDoneImpl(_, DISABLED, _). + if (shared_change_processor_.get()) { + shared_change_processor_->Disconnect(); + shared_change_processor_ = NULL; + } +} + +void NonUIDataTypeController::StopLocalServiceAsync() { + DCHECK(ui_thread_->BelongsToCurrentThread()); + PostTaskOnBackendThread( + FROM_HERE, base::Bind(&NonUIDataTypeController::StopLocalService, this)); +} + +void NonUIDataTypeController::StopLocalService() { + DCHECK(!ui_thread_->BelongsToCurrentThread()); + if (local_service_.get()) + local_service_->StopSyncing(type()); + local_service_.reset(); +} + +} // namespace sync_driver
diff --git a/components/sync/driver/non_ui_data_type_controller.h b/components/sync/driver/non_ui_data_type_controller.h new file mode 100644 index 0000000..3dcabaa3 --- /dev/null +++ b/components/sync/driver/non_ui_data_type_controller.h
@@ -0,0 +1,167 @@ +// 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 COMPONENTS_SYNC_DRIVER_NON_UI_DATA_TYPE_CONTROLLER_H_ +#define COMPONENTS_SYNC_DRIVER_NON_UI_DATA_TYPE_CONTROLLER_H_ + +#include <string> + +#include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "components/sync/driver/directory_data_type_controller.h" +#include "components/sync/driver/shared_change_processor.h" + +namespace syncer { +class SyncableService; +struct UserShare; +} + +namespace sync_driver { + +class SyncClient; + +class NonUIDataTypeController : public DirectoryDataTypeController { + public: + NonUIDataTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const base::Closure& error_callback, + SyncClient* sync_client); + + // DataTypeController interface. + void LoadModels(const ModelLoadCallback& model_load_callback) override; + void StartAssociating(const StartCallback& start_callback) override; + void Stop() override; + syncer::ModelType type() const override = 0; + syncer::ModelSafeGroup model_safe_group() const override = 0; + ChangeProcessor* GetChangeProcessor() const override; + std::string name() const override; + State state() const override; + void OnSingleDataTypeUnrecoverableError( + const syncer::SyncError& error) override; + + protected: + // For testing only. + NonUIDataTypeController(); + // DataTypeController is RefCounted. + ~NonUIDataTypeController() override; + + // Start any dependent services that need to be running before we can + // associate models. The default implementation is a no-op. + // Return value: + // True - if models are ready and association can proceed. + // False - if models are not ready. StartAssociationAsync should be called + // when the models are ready. + // Note: this is performed on the UI thread. + virtual bool StartModels(); + + // Perform any DataType controller specific state cleanup before stopping + // the datatype controller. The default implementation is a no-op. + // Note: this is performed on the UI thread. + virtual void StopModels(); + + // Posts the given task to the backend thread, i.e. the thread the + // datatype lives on. Return value: True if task posted successfully, + // false otherwise. + virtual bool PostTaskOnBackendThread( + const tracked_objects::Location& from_here, + const base::Closure& task) = 0; + + // Start up complete, update the state and invoke the callback. + // Note: this is performed on the datatype's thread. + virtual void StartDone(DataTypeController::ConfigureResult start_result, + const syncer::SyncMergeResult& local_merge_result, + const syncer::SyncMergeResult& syncer_merge_result); + + // UI thread implementation of StartDone. + virtual void StartDoneImpl( + DataTypeController::ConfigureResult start_result, + DataTypeController::State new_state, + const syncer::SyncMergeResult& local_merge_result, + const syncer::SyncMergeResult& syncer_merge_result); + + // Kick off the association process. + virtual bool StartAssociationAsync(); + + // Record association time. + virtual void RecordAssociationTime(base::TimeDelta time); + + // Record causes of start failure. + virtual void RecordStartFailure(ConfigureResult result); + + // To allow unit tests to control thread interaction during non-ui startup + // and shutdown, use a factory method to create the SharedChangeProcessor. + virtual SharedChangeProcessor* CreateSharedChangeProcessor(); + + // If the DTC is waiting for models to load, once the models are + // loaded the datatype service will call this function on DTC to let + // us know that it is safe to start associating. + void OnModelLoaded(); + + private: + // Posted on the backend thread by StartAssociationAsync(). + void StartAssociationWithSharedChangeProcessor( + const scoped_refptr<SharedChangeProcessor>& shared_change_processor); + + // Calls Disconnect() on |shared_change_processor_|, then sets it to + // NULL. Must be called only by StartDoneImpl() or Stop() (on the + // UI thread) and only after a call to Start() (i.e., + // |shared_change_processor_| must be non-NULL). + void ClearSharedChangeProcessor(); + + // Posts StopLocalService() to the datatype's thread. + void StopLocalServiceAsync(); + + // Calls local_service_->StopSyncing() and releases our references to it. + void StopLocalService(); + + // Abort model loading and trigger the model load callback. + void AbortModelLoad(); + + // Disable this type with the sync service. Should only be invoked in case of + // an unrecoverable error. + // Note: this is performed on the UI thread. + void DisableImpl(const syncer::SyncError& error); + + SyncClient* const sync_client_; + + // UserShare is stored in StartAssociating while on UI thread and + // passed to SharedChangeProcessor::Connect on the model thread. + syncer::UserShare* user_share_; + + // State of this datatype controller. + State state_; + + // Callbacks for use when starting the datatype. + StartCallback start_callback_; + ModelLoadCallback model_load_callback_; + + // The shared change processor is the thread-safe interface to the + // datatype. We hold a reference to it from the UI thread so that + // we can call Disconnect() on it from Stop()/StartDoneImpl(). Most + // of the work is done on the backend thread, and in + // StartAssociationWithSharedChangeProcessor() for this class in + // particular. + // + // Lifetime: The SharedChangeProcessor object is created on the UI + // thread and passed on to the backend thread. This reference is + // released on the UI thread in Stop()/StartDoneImpl(), but the + // backend thread may still have references to it (which is okay, + // since we call Disconnect() before releasing the UI thread + // reference). + scoped_refptr<SharedChangeProcessor> shared_change_processor_; + + // A weak pointer to the actual local syncable service, which performs all the + // real work. We do not own the object, and it is only safe to access on the + // DataType's thread. + // Lifetime: it gets set in StartAssociationWithSharedChangeProcessor(...) + // and released in StopLocalService(). + base::WeakPtr<syncer::SyncableService> local_service_; + + scoped_refptr<base::SingleThreadTaskRunner> ui_thread_; +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_NON_UI_DATA_TYPE_CONTROLLER_H_
diff --git a/components/sync/driver/non_ui_data_type_controller_mock.cc b/components/sync/driver/non_ui_data_type_controller_mock.cc new file mode 100644 index 0000000..e1757001 --- /dev/null +++ b/components/sync/driver/non_ui_data_type_controller_mock.cc
@@ -0,0 +1,13 @@ +// 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 "components/sync/driver/non_ui_data_type_controller_mock.h" + +namespace sync_driver { + +NonUIDataTypeControllerMock::NonUIDataTypeControllerMock() {} + +NonUIDataTypeControllerMock::~NonUIDataTypeControllerMock() {} + +} // namespace sync_driver
diff --git a/components/sync/driver/non_ui_data_type_controller_mock.h b/components/sync/driver/non_ui_data_type_controller_mock.h new file mode 100644 index 0000000..1ff24ec --- /dev/null +++ b/components/sync/driver/non_ui_data_type_controller_mock.h
@@ -0,0 +1,54 @@ +// 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 COMPONENTS_SYNC_DRIVER_NON_UI_DATA_TYPE_CONTROLLER_MOCK_H_ +#define COMPONENTS_SYNC_DRIVER_NON_UI_DATA_TYPE_CONTROLLER_MOCK_H_ + +#include <string> + +#include "components/sync/api/sync_error.h" +#include "components/sync/driver/non_ui_data_type_controller.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace sync_driver { + +class NonUIDataTypeControllerMock : public NonUIDataTypeController { + public: + NonUIDataTypeControllerMock(); + + // DataTypeController mocks. + MOCK_METHOD1(StartAssociating, void(const StartCallback& start_callback)); + MOCK_METHOD1(LoadModels, void(const ModelLoadCallback& model_load_callback)); + MOCK_METHOD0(Stop, void()); + MOCK_CONST_METHOD0(type, syncer::ModelType()); + MOCK_CONST_METHOD0(name, std::string()); + MOCK_CONST_METHOD0(model_safe_group, syncer::ModelSafeGroup()); + MOCK_CONST_METHOD0(state, State()); + MOCK_METHOD1(OnSingleDataTypeUnrecoverableError, + void(const syncer::SyncError& error)); + + // NonUIDataTypeController mocks. + MOCK_METHOD0(StartModels, bool()); + MOCK_METHOD0(StopModels, void()); + MOCK_METHOD2(PostTaskOnBackendThread, + bool(const tracked_objects::Location&, const base::Closure&)); + MOCK_METHOD3(StartDone, + void(DataTypeController::ConfigureResult result, + const syncer::SyncMergeResult& local_merge_result, + const syncer::SyncMergeResult& syncer_merge_result)); + MOCK_METHOD4(StartDoneImpl, + void(DataTypeController::ConfigureResult result, + DataTypeController::State new_state, + const syncer::SyncMergeResult& local_merge_result, + const syncer::SyncMergeResult& syncer_merge_result)); + MOCK_METHOD1(RecordAssociationTime, void(base::TimeDelta time)); + MOCK_METHOD1(RecordStartFailure, void(ConfigureResult result)); + + protected: + virtual ~NonUIDataTypeControllerMock(); +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_NON_UI_DATA_TYPE_CONTROLLER_MOCK_H_
diff --git a/components/sync/driver/non_ui_data_type_controller_unittest.cc b/components/sync/driver/non_ui_data_type_controller_unittest.cc new file mode 100644 index 0000000..f7ab1d5 --- /dev/null +++ b/components/sync/driver/non_ui_data_type_controller_unittest.cc
@@ -0,0 +1,494 @@ +// 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 "components/sync/driver/non_ui_data_type_controller.h" + +#include <memory> +#include <vector> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/callback.h" +#include "base/compiler_specific.h" +#include "base/location.h" +#include "base/macros.h" +#include "base/run_loop.h" +#include "base/single_thread_task_runner.h" +#include "base/synchronization/waitable_event.h" +#include "base/test/test_timeouts.h" +#include "base/threading/thread.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/tracked_objects.h" +#include "components/sync/api/fake_syncable_service.h" +#include "components/sync/api/sync_change.h" +#include "components/sync/driver/data_type_controller_mock.h" +#include "components/sync/driver/fake_sync_client.h" +#include "components/sync/driver/generic_change_processor_factory.h" +#include "components/sync/driver/non_ui_data_type_controller_mock.h" +#include "components/sync/engine/model_safe_worker.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace sync_driver { + +class SyncClient; + +namespace { + +using base::WaitableEvent; +using syncer::AUTOFILL_PROFILE; +using testing::_; +using testing::AtLeast; +using testing::DoAll; +using testing::InvokeWithoutArgs; +using testing::Mock; +using testing::Return; +using testing::SetArgumentPointee; +using testing::StrictMock; + +ACTION_P(WaitOnEvent, event) { + event->Wait(); +} + +ACTION_P(SignalEvent, event) { + event->Signal(); +} + +ACTION_P(SaveChangeProcessor, scoped_change_processor) { + scoped_change_processor->reset(arg2); +} + +ACTION_P(GetWeakPtrToSyncableService, syncable_service) { + // Have to do this within an Action to ensure it's not evaluated on the wrong + // thread. + return syncable_service->AsWeakPtr(); +} + +class SharedChangeProcessorMock : public SharedChangeProcessor { + public: + SharedChangeProcessorMock() {} + + MOCK_METHOD6(Connect, + base::WeakPtr<syncer::SyncableService>( + SyncClient*, + GenericChangeProcessorFactory*, + syncer::UserShare*, + syncer::DataTypeErrorHandler*, + syncer::ModelType, + const base::WeakPtr<syncer::SyncMergeResult>&)); + MOCK_METHOD0(Disconnect, bool()); + MOCK_METHOD2(ProcessSyncChanges, + syncer::SyncError(const tracked_objects::Location&, + const syncer::SyncChangeList&)); + MOCK_CONST_METHOD2(GetAllSyncDataReturnError, + syncer::SyncError(syncer::ModelType, + syncer::SyncDataList*)); + MOCK_METHOD0(GetSyncCount, int()); + MOCK_METHOD1(SyncModelHasUserCreatedNodes, bool(bool*)); + MOCK_METHOD0(CryptoReadyIfNecessary, bool()); + MOCK_CONST_METHOD1(GetDataTypeContext, bool(std::string*)); + + protected: + virtual ~SharedChangeProcessorMock() {} + MOCK_METHOD2(OnUnrecoverableError, + void(const tracked_objects::Location&, const std::string&)); + + private: + DISALLOW_COPY_AND_ASSIGN(SharedChangeProcessorMock); +}; + +class NonUIDataTypeControllerFake : public NonUIDataTypeController { + public: + NonUIDataTypeControllerFake( + SyncClient* sync_client, + NonUIDataTypeControllerMock* mock, + SharedChangeProcessor* change_processor, + scoped_refptr<base::SingleThreadTaskRunner> backend_task_runner) + : NonUIDataTypeController(base::ThreadTaskRunnerHandle::Get(), + base::Closure(), + sync_client), + blocked_(false), + mock_(mock), + change_processor_(change_processor), + backend_task_runner_(backend_task_runner) {} + + syncer::ModelType type() const override { return AUTOFILL_PROFILE; } + syncer::ModelSafeGroup model_safe_group() const override { + return syncer::GROUP_DB; + } + + // Prevent tasks from being posted on the backend thread until + // UnblockBackendTasks() is called. + void BlockBackendTasks() { blocked_ = true; } + + // Post pending tasks on the backend thread and start allowing tasks + // to be posted on the backend thread again. + void UnblockBackendTasks() { + blocked_ = false; + for (std::vector<PendingTask>::const_iterator it = pending_tasks_.begin(); + it != pending_tasks_.end(); ++it) { + PostTaskOnBackendThread(it->from_here, it->task); + } + pending_tasks_.clear(); + } + + SharedChangeProcessor* CreateSharedChangeProcessor() override { + return change_processor_.get(); + } + + protected: + bool PostTaskOnBackendThread(const tracked_objects::Location& from_here, + const base::Closure& task) override { + if (blocked_) { + pending_tasks_.push_back(PendingTask(from_here, task)); + return true; + } else { + return backend_task_runner_->PostTask(from_here, task); + } + } + + // We mock the following methods because their default implementations do + // nothing, but we still want to make sure they're called appropriately. + bool StartModels() override { return mock_->StartModels(); } + void StopModels() override { mock_->StopModels(); } + void RecordAssociationTime(base::TimeDelta time) override { + mock_->RecordAssociationTime(time); + } + void RecordStartFailure(DataTypeController::ConfigureResult result) override { + mock_->RecordStartFailure(result); + } + + private: + ~NonUIDataTypeControllerFake() override {} + + struct PendingTask { + PendingTask(const tracked_objects::Location& from_here, + const base::Closure& task) + : from_here(from_here), task(task) {} + + tracked_objects::Location from_here; + base::Closure task; + }; + + bool blocked_; + std::vector<PendingTask> pending_tasks_; + NonUIDataTypeControllerMock* mock_; + scoped_refptr<SharedChangeProcessor> change_processor_; + scoped_refptr<base::SingleThreadTaskRunner> backend_task_runner_; + + DISALLOW_COPY_AND_ASSIGN(NonUIDataTypeControllerFake); +}; + +class SyncNonUIDataTypeControllerTest : public testing::Test, + public FakeSyncClient { + public: + SyncNonUIDataTypeControllerTest() : backend_thread_("dbthread") {} + + void SetUp() override { + backend_thread_.Start(); + change_processor_ = new SharedChangeProcessorMock(); + // All of these are refcounted, so don't need to be released. + dtc_mock_ = new StrictMock<NonUIDataTypeControllerMock>(); + non_ui_dtc_ = new NonUIDataTypeControllerFake( + this, dtc_mock_.get(), change_processor_.get(), + backend_thread_.task_runner()); + } + + void TearDown() override { backend_thread_.Stop(); } + + void WaitForDTC() { + WaitableEvent done(base::WaitableEvent::ResetPolicy::MANUAL, + base::WaitableEvent::InitialState::NOT_SIGNALED); + backend_thread_.task_runner()->PostTask( + FROM_HERE, + base::Bind(&SyncNonUIDataTypeControllerTest::SignalDone, &done)); + done.TimedWait(TestTimeouts::action_timeout()); + if (!done.IsSignaled()) { + ADD_FAILURE() << "Timed out waiting for DB thread to finish."; + } + base::RunLoop().RunUntilIdle(); + } + + SyncService* GetSyncService() override { + // Make sure this isn't called on backend_thread. + EXPECT_FALSE(backend_thread_.task_runner()->BelongsToCurrentThread()); + return FakeSyncClient::GetSyncService(); + } + + protected: + void SetStartExpectations() { + EXPECT_CALL(*dtc_mock_.get(), StartModels()).WillOnce(Return(true)); + EXPECT_CALL(model_load_callback_, Run(_, _)); + } + + void SetAssociateExpectations() { + EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) + .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); + EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) + .WillOnce(Return(true)); + EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_)) + .WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true))); + EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_, _)) + .WillOnce(Return(syncer::SyncError())); + EXPECT_CALL(*change_processor_.get(), GetSyncCount()).WillOnce(Return(0)); + EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_)); + } + + void SetActivateExpectations(DataTypeController::ConfigureResult result) { + EXPECT_CALL(start_callback_, Run(result, _, _)); + } + + void SetStopExpectations() { + EXPECT_CALL(*dtc_mock_.get(), StopModels()); + EXPECT_CALL(*change_processor_.get(), Disconnect()).WillOnce(Return(true)); + } + + void SetStartFailExpectations(DataTypeController::ConfigureResult result) { + EXPECT_CALL(*dtc_mock_.get(), StopModels()).Times(AtLeast(1)); + EXPECT_CALL(*dtc_mock_.get(), RecordStartFailure(result)); + EXPECT_CALL(start_callback_, Run(result, _, _)); + } + + void Start() { + non_ui_dtc_->LoadModels(base::Bind( + &ModelLoadCallbackMock::Run, base::Unretained(&model_load_callback_))); + non_ui_dtc_->StartAssociating(base::Bind( + &StartCallbackMock::Run, base::Unretained(&start_callback_))); + } + + static void SignalDone(WaitableEvent* done) { done->Signal(); } + + base::MessageLoopForUI message_loop_; + base::Thread backend_thread_; + + StartCallbackMock start_callback_; + ModelLoadCallbackMock model_load_callback_; + // Must be destroyed after non_ui_dtc_. + syncer::FakeSyncableService syncable_service_; + scoped_refptr<NonUIDataTypeControllerFake> non_ui_dtc_; + scoped_refptr<NonUIDataTypeControllerMock> dtc_mock_; + scoped_refptr<SharedChangeProcessorMock> change_processor_; + std::unique_ptr<syncer::SyncChangeProcessor> saved_change_processor_; +}; + +TEST_F(SyncNonUIDataTypeControllerTest, StartOk) { + SetStartExpectations(); + SetAssociateExpectations(); + SetActivateExpectations(DataTypeController::OK); + EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); + Start(); + WaitForDTC(); + EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); +} + +TEST_F(SyncNonUIDataTypeControllerTest, StartFirstRun) { + SetStartExpectations(); + EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) + .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); + EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) + .WillOnce(Return(true)); + EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_)) + .WillOnce(DoAll(SetArgumentPointee<0>(false), Return(true))); + EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_, _)) + .WillOnce(Return(syncer::SyncError())); + EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_)); + SetActivateExpectations(DataTypeController::OK_FIRST_RUN); + EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); + Start(); + WaitForDTC(); + EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); +} + +// Start the DTC and have StartModels() return false. Then, stop the +// DTC without finishing model startup. It should stop cleanly. +TEST_F(SyncNonUIDataTypeControllerTest, AbortDuringStartModels) { + EXPECT_CALL(*dtc_mock_.get(), StartModels()).WillOnce(Return(false)); + EXPECT_CALL(*dtc_mock_.get(), StopModels()); + EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); + non_ui_dtc_->LoadModels(base::Bind(&ModelLoadCallbackMock::Run, + base::Unretained(&model_load_callback_))); + WaitForDTC(); + EXPECT_EQ(DataTypeController::MODEL_STARTING, non_ui_dtc_->state()); + non_ui_dtc_->Stop(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); +} + +// Start the DTC and have MergeDataAndStartSyncing() return an error. +// The DTC should become disabled, and the DTC should still stop +// cleanly. +TEST_F(SyncNonUIDataTypeControllerTest, StartAssociationFailed) { + SetStartExpectations(); + EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) + .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); + EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) + .WillOnce(Return(true)); + EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_)) + .WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true))); + EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_, _)) + .WillOnce(Return(syncer::SyncError())); + EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_)); + SetStartFailExpectations(DataTypeController::ASSOCIATION_FAILED); + // Set up association to fail with an association failed error. + EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); + syncable_service_.set_merge_data_and_start_syncing_error( + syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Sync Error", non_ui_dtc_->type())); + Start(); + WaitForDTC(); + EXPECT_EQ(DataTypeController::DISABLED, non_ui_dtc_->state()); + non_ui_dtc_->Stop(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); +} + +TEST_F(SyncNonUIDataTypeControllerTest, + StartAssociationTriggersUnrecoverableError) { + SetStartExpectations(); + SetStartFailExpectations(DataTypeController::UNRECOVERABLE_ERROR); + // Set up association to fail with an unrecoverable error. + EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) + .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); + EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) + .WillRepeatedly(Return(true)); + EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_)) + .WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(false))); + EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); + Start(); + WaitForDTC(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); +} + +TEST_F(SyncNonUIDataTypeControllerTest, StartAssociationCryptoNotReady) { + SetStartExpectations(); + SetStartFailExpectations(DataTypeController::NEEDS_CRYPTO); + // Set up association to fail with a NEEDS_CRYPTO error. + EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) + .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); + EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) + .WillRepeatedly(Return(false)); + EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); + Start(); + WaitForDTC(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); +} + +// Trigger a Stop() call when we check if the model associator has user created +// nodes. +TEST_F(SyncNonUIDataTypeControllerTest, AbortDuringAssociation) { + WaitableEvent wait_for_db_thread_pause( + base::WaitableEvent::ResetPolicy::AUTOMATIC, + base::WaitableEvent::InitialState::NOT_SIGNALED); + WaitableEvent pause_db_thread( + base::WaitableEvent::ResetPolicy::AUTOMATIC, + base::WaitableEvent::InitialState::NOT_SIGNALED); + + SetStartExpectations(); + EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) + .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); + EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) + .WillOnce(Return(true)); + EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_)) + .WillOnce(DoAll(SignalEvent(&wait_for_db_thread_pause), + WaitOnEvent(&pause_db_thread), + SetArgumentPointee<0>(true), Return(true))); + EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_, _)) + .WillOnce( + Return(syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Disconnected.", AUTOFILL_PROFILE))); + EXPECT_CALL(*dtc_mock_.get(), StopModels()); + EXPECT_CALL(*change_processor_.get(), Disconnect()) + .WillOnce(DoAll(SignalEvent(&pause_db_thread), Return(true))); + EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); + Start(); + wait_for_db_thread_pause.Wait(); + non_ui_dtc_->Stop(); + WaitForDTC(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); +} + +// Start the DTC while the backend tasks are blocked. Then stop the DTC before +// the backend tasks get a chance to run. +TEST_F(SyncNonUIDataTypeControllerTest, StartAfterSyncShutdown) { + non_ui_dtc_->BlockBackendTasks(); + + SetStartExpectations(); + // We don't expect StopSyncing to be called because local_service_ will never + // have been set. + SetStopExpectations(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); + Start(); + non_ui_dtc_->Stop(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); + Mock::VerifyAndClearExpectations(change_processor_.get()); + Mock::VerifyAndClearExpectations(dtc_mock_.get()); + + EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) + .WillOnce(Return(base::WeakPtr<syncer::SyncableService>())); + non_ui_dtc_->UnblockBackendTasks(); + WaitForDTC(); +} + +TEST_F(SyncNonUIDataTypeControllerTest, Stop) { + SetStartExpectations(); + SetAssociateExpectations(); + SetActivateExpectations(DataTypeController::OK); + SetStopExpectations(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); + Start(); + WaitForDTC(); + EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); + non_ui_dtc_->Stop(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); +} + +// Start the DTC then block its backend tasks. While its backend +// tasks are blocked, stop and start it again, then unblock its +// backend tasks. The (delayed) running of the backend tasks from the +// stop after the restart shouldn't cause any problems. +TEST_F(SyncNonUIDataTypeControllerTest, StopStart) { + SetStartExpectations(); + SetAssociateExpectations(); + SetActivateExpectations(DataTypeController::OK); + SetStopExpectations(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); + Start(); + WaitForDTC(); + EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); + + non_ui_dtc_->BlockBackendTasks(); + non_ui_dtc_->Stop(); + SetStartExpectations(); + SetAssociateExpectations(); + SetActivateExpectations(DataTypeController::OK); + EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); + Start(); + non_ui_dtc_->UnblockBackendTasks(); + + WaitForDTC(); + EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); +} + +TEST_F(SyncNonUIDataTypeControllerTest, OnSingleDataTypeUnrecoverableError) { + SetStartExpectations(); + SetAssociateExpectations(); + SetActivateExpectations(DataTypeController::OK); + EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); + Start(); + WaitForDTC(); + EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); + + testing::Mock::VerifyAndClearExpectations(&start_callback_); + EXPECT_CALL(model_load_callback_, Run(_, _)); + syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, "error", + non_ui_dtc_->type()); + backend_thread_.task_runner()->PostTask( + FROM_HERE, + base::Bind( + &NonUIDataTypeControllerFake::OnSingleDataTypeUnrecoverableError, + non_ui_dtc_.get(), error)); + WaitForDTC(); +} + +} // namespace + +} // namespace sync_driver
diff --git a/components/sync/driver/non_ui_model_type_controller.cc b/components/sync/driver/non_ui_model_type_controller.cc new file mode 100644 index 0000000..39967be --- /dev/null +++ b/components/sync/driver/non_ui_model_type_controller.cc
@@ -0,0 +1,35 @@ +// Copyright 2016 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/sync/driver/non_ui_model_type_controller.h" + +#include "components/sync/api/model_type_service.h" +#include "components/sync/base/model_type.h" +#include "components/sync/core/activation_context.h" +#include "components/sync/driver/sync_client.h" + +namespace sync_driver_v2 { + +using sync_driver::SyncClient; + +NonUIModelTypeController::NonUIModelTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const base::Closure& error_callback, + syncer::ModelType model_type, + SyncClient* sync_client) + : NonBlockingDataTypeController(ui_thread, + error_callback, + model_type, + sync_client) {} + +NonUIModelTypeController::~NonUIModelTypeController() {} + +void NonUIModelTypeController::RunOnUIThread( + const tracked_objects::Location& from_here, + const base::Closure& task) { + DCHECK(!BelongsToUIThread()); + ui_thread()->PostTask(from_here, task); +} + +} // namespace sync_driver_v2
diff --git a/components/sync/driver/non_ui_model_type_controller.h b/components/sync/driver/non_ui_model_type_controller.h new file mode 100644 index 0000000..8462af2 --- /dev/null +++ b/components/sync/driver/non_ui_model_type_controller.h
@@ -0,0 +1,40 @@ +// Copyright 2016 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_SYNC_DRIVER_NON_UI_MODEL_TYPE_CONTROLLER_H_ +#define COMPONENTS_SYNC_DRIVER_NON_UI_MODEL_TYPE_CONTROLLER_H_ + +#include "components/sync/driver/non_blocking_data_type_controller.h" + +namespace sync_driver { +class SyncClient; +} + +namespace sync_driver_v2 { + +// Implementation for Unified Sync and Storage datatypes whose model thread is +// not the UI thread. +// Derived types must implement the following methods: +// - RunOnModelThread +class NonUIModelTypeController : public NonBlockingDataTypeController { + public: + NonUIModelTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const base::Closure& error_callback, + syncer::ModelType model_type, + sync_driver::SyncClient* sync_client); + + void RunOnUIThread(const tracked_objects::Location& from_here, + const base::Closure& task) override; + + protected: + ~NonUIModelTypeController() override; + + private: + DISALLOW_COPY_AND_ASSIGN(NonUIModelTypeController); +}; + +} // namespace sync_driver_v2 + +#endif // COMPONENTS_SYNC_DRIVER_NON_UI_MODEL_TYPE_CONTROLLER_H_
diff --git a/components/sync/driver/non_ui_model_type_controller_unittest.cc b/components/sync/driver/non_ui_model_type_controller_unittest.cc new file mode 100644 index 0000000..5a811f3f --- /dev/null +++ b/components/sync/driver/non_ui_model_type_controller_unittest.cc
@@ -0,0 +1,377 @@ +// Copyright 2016 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/sync/driver/non_ui_model_type_controller.h" + +#include <memory> +#include <utility> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/sequenced_task_runner.h" +#include "base/test/test_simple_task_runner.h" +#include "base/threading/thread.h" +#include "components/sync/api/fake_model_type_service.h" +#include "components/sync/core/activation_context.h" +#include "components/sync/core/shared_model_type_processor.h" +#include "components/sync/driver/backend_data_type_configurer.h" +#include "components/sync/driver/fake_sync_client.h" +#include "components/sync/engine_impl/commit_queue.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace sync_driver_v2 { + +namespace { + +// Test controller derived from NonUIModelTypeController. +class TestNonUIModelTypeController : public NonUIModelTypeController { + public: + TestNonUIModelTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const scoped_refptr<base::TaskRunner>& model_task_runner, + const base::Closure& error_callback, + syncer::ModelType model_type, + sync_driver::SyncClient* sync_client) + : NonUIModelTypeController(ui_thread, + error_callback, + model_type, + sync_client), + model_task_runner_(model_task_runner) {} + + bool RunOnModelThread(const tracked_objects::Location& from_here, + const base::Closure& task) override { + DCHECK(model_task_runner_); + return model_task_runner_->PostTask(from_here, task); + } + + private: + ~TestNonUIModelTypeController() override {} + + scoped_refptr<base::TaskRunner> model_task_runner_; +}; + +// A no-op instance of CommitQueue. +class NullCommitQueue : public syncer_v2::CommitQueue { + public: + NullCommitQueue() {} + ~NullCommitQueue() override {} + + void EnqueueForCommit(const syncer_v2::CommitRequestDataList& list) override { + NOTREACHED() << "Not implemented."; + } +}; + +// A class that pretends to be the sync backend. +class MockSyncBackend { + public: + void Connect( + syncer::ModelType type, + std::unique_ptr<syncer_v2::ActivationContext> activation_context) { + enabled_types_.Put(type); + activation_context->type_processor->ConnectSync( + base::WrapUnique(new NullCommitQueue())); + } + + void Disconnect(syncer::ModelType type) { + DCHECK(enabled_types_.Has(type)); + enabled_types_.Remove(type); + } + + private: + syncer::ModelTypeSet enabled_types_; +}; + +// Fake implementation of BackendDataTypeConfigurer that pretends to be Sync +// backend. +class MockBackendDataTypeConfigurer + : public sync_driver::BackendDataTypeConfigurer { + public: + MockBackendDataTypeConfigurer( + MockSyncBackend* backend, + const scoped_refptr<base::TaskRunner>& sync_task_runner) + : backend_(backend), sync_task_runner_(sync_task_runner) {} + ~MockBackendDataTypeConfigurer() override {} + + syncer::ModelTypeSet ConfigureDataTypes( + syncer::ConfigureReason reason, + const DataTypeConfigStateMap& config_state_map, + const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& + ready_task, + const base::Callback<void()>& retry_callback) override { + NOTREACHED() << "Not implemented."; + return syncer::ModelTypeSet(); + } + + void ActivateDirectoryDataType( + syncer::ModelType type, + syncer::ModelSafeGroup group, + sync_driver::ChangeProcessor* change_processor) override { + NOTREACHED() << "Not implemented."; + } + + void DeactivateDirectoryDataType(syncer::ModelType type) override { + NOTREACHED() << "Not implemented."; + } + + void ActivateNonBlockingDataType(syncer::ModelType type, + std::unique_ptr<syncer_v2::ActivationContext> + activation_context) override { + // Post on Sync thread just like the real implementation does. + sync_task_runner_->PostTask( + FROM_HERE, + base::Bind(&MockSyncBackend::Connect, base::Unretained(backend_), type, + base::Passed(std::move(activation_context)))); + } + + void DeactivateNonBlockingDataType(syncer::ModelType type) override { + sync_task_runner_->PostTask(FROM_HERE, + base::Bind(&MockSyncBackend::Disconnect, + base::Unretained(backend_), type)); + } + + private: + MockSyncBackend* backend_; + scoped_refptr<base::TaskRunner> sync_task_runner_; +}; + +} // namespace + +class NonUIModelTypeControllerTest : public testing::Test, + public sync_driver::FakeSyncClient { + public: + NonUIModelTypeControllerTest() + : auto_run_tasks_(true), + load_models_callback_called_(false), + association_callback_called_(false), + model_thread_("modelthread"), + configurer_(&backend_, ui_loop_.task_runner()) {} + + ~NonUIModelTypeControllerTest() override {} + + void SetUp() override { + model_thread_.Start(); + model_thread_runner_ = model_thread_.task_runner(); + InitializeModelTypeService(); + controller_ = new TestNonUIModelTypeController( + ui_loop_.task_runner(), model_thread_runner_, base::Closure(), + syncer::DICTIONARY, this); + } + + void TearDown() override { + ClearModelTypeService(); + controller_ = NULL; + RunQueuedUIThreadTasks(); + } + + syncer_v2::ModelTypeService* GetModelTypeServiceForType( + syncer::ModelType type) override { + return service_.get(); + } + + protected: + std::unique_ptr<syncer_v2::ModelTypeChangeProcessor> CreateProcessor( + syncer::ModelType type, + syncer_v2::ModelTypeService* service) { + std::unique_ptr<syncer_v2::SharedModelTypeProcessor> processor = + base::WrapUnique( + new syncer_v2::SharedModelTypeProcessor(type, service)); + type_processor_ = processor.get(); + return std::move(processor); + } + + void InitializeModelTypeService() { + if (!model_thread_runner_ || + model_thread_runner_->BelongsToCurrentThread()) { + service_.reset(new syncer_v2::FakeModelTypeService( + base::Bind(&NonUIModelTypeControllerTest::CreateProcessor, + base::Unretained(this)))); + } else { + model_thread_runner_->PostTask( + FROM_HERE, + base::Bind(&NonUIModelTypeControllerTest::InitializeModelTypeService, + base::Unretained(this))); + RunQueuedModelThreadTasks(); + } + } + + void ClearModelTypeService() { + if (!model_thread_runner_ || + model_thread_runner_->BelongsToCurrentThread()) { + service_.reset(); + } else { + model_thread_runner_->PostTask( + FROM_HERE, + base::Bind(&NonUIModelTypeControllerTest::ClearModelTypeService, + base::Unretained(this))); + RunQueuedModelThreadTasks(); + } + } + + void ExpectProcessorConnected(bool isConnected) { + if (model_thread_runner_->BelongsToCurrentThread()) { + DCHECK(type_processor_); + EXPECT_EQ(isConnected, type_processor_->IsConnected()); + } else { + model_thread_runner_->PostTask( + FROM_HERE, + base::Bind(&NonUIModelTypeControllerTest::ExpectProcessorConnected, + base::Unretained(this), isConnected)); + RunQueuedModelThreadTasks(); + } + } + + void OnMetadataLoaded() { + if (model_thread_runner_->BelongsToCurrentThread()) { + if (!type_processor_->IsAllowingChanges()) { + type_processor_->OnMetadataLoaded( + syncer::SyncError(), + base::WrapUnique(new syncer_v2::MetadataBatch())); + } + } else { + model_thread_runner_->PostTask( + FROM_HERE, base::Bind(&NonUIModelTypeControllerTest::OnMetadataLoaded, + base::Unretained(this))); + } + } + + void LoadModels() { + controller_->LoadModels(base::Bind( + &NonUIModelTypeControllerTest::LoadModelsDone, base::Unretained(this))); + OnMetadataLoaded(); + + if (auto_run_tasks_) { + RunAllTasks(); + } + } + + void RegisterWithBackend() { + controller_->RegisterWithBackend(&configurer_); + if (auto_run_tasks_) { + RunAllTasks(); + } + } + + void StartAssociating() { + controller_->StartAssociating( + base::Bind(&NonUIModelTypeControllerTest::AssociationDone, + base::Unretained(this))); + // The callback is expected to be promptly called. + EXPECT_TRUE(association_callback_called_); + } + + void DeactivateDataTypeAndStop() { + controller_->DeactivateDataType(&configurer_); + controller_->Stop(); + if (auto_run_tasks_) { + RunAllTasks(); + } + } + + // These threads can ping-pong for a bit so we run the model thread twice. + void RunAllTasks() { + RunQueuedModelThreadTasks(); + RunQueuedUIThreadTasks(); + RunQueuedModelThreadTasks(); + } + + // Runs any tasks posted on UI thread. + void RunQueuedUIThreadTasks() { ui_loop_.RunUntilIdle(); } + + // Runs any tasks posted on model thread. + void RunQueuedModelThreadTasks() { + base::RunLoop run_loop; + model_thread_runner_->PostTaskAndReply( + FROM_HERE, base::Bind(&base::DoNothing), + base::Bind(&base::RunLoop::Quit, base::Unretained(&run_loop))); + run_loop.Run(); + } + + void SetAutoRunTasks(bool auto_run_tasks) { + auto_run_tasks_ = auto_run_tasks; + } + + void LoadModelsDone(syncer::ModelType type, syncer::SyncError error) { + load_models_callback_called_ = true; + load_models_error_ = error; + } + + void AssociationDone(sync_driver::DataTypeController::ConfigureResult result, + const syncer::SyncMergeResult& local_merge_result, + const syncer::SyncMergeResult& syncer_merge_result) { + EXPECT_EQ(sync_driver::DataTypeController::OK, result); + association_callback_called_ = true; + } + + syncer_v2::SharedModelTypeProcessor* type_processor_; + scoped_refptr<TestNonUIModelTypeController> controller_; + + bool auto_run_tasks_; + bool load_models_callback_called_; + syncer::SyncError load_models_error_; + bool association_callback_called_; + base::MessageLoopForUI ui_loop_; + base::Thread model_thread_; + scoped_refptr<base::SingleThreadTaskRunner> model_thread_runner_; + MockSyncBackend backend_; + MockBackendDataTypeConfigurer configurer_; + std::unique_ptr<syncer_v2::FakeModelTypeService> service_; +}; + +TEST_F(NonUIModelTypeControllerTest, InitialState) { + EXPECT_EQ(syncer::DICTIONARY, controller_->type()); + EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); +} + +TEST_F(NonUIModelTypeControllerTest, LoadModelsOnBackendThread) { + SetAutoRunTasks(false); + LoadModels(); + EXPECT_EQ(sync_driver::DataTypeController::MODEL_STARTING, + controller_->state()); + RunAllTasks(); + EXPECT_EQ(sync_driver::DataTypeController::MODEL_LOADED, + controller_->state()); + EXPECT_TRUE(load_models_callback_called_); + EXPECT_FALSE(load_models_error_.IsSet()); + ExpectProcessorConnected(false); +} + +TEST_F(NonUIModelTypeControllerTest, LoadModelsTwice) { + LoadModels(); + SetAutoRunTasks(false); + LoadModels(); + EXPECT_EQ(sync_driver::DataTypeController::MODEL_LOADED, + controller_->state()); + // The second LoadModels call should set the error. + EXPECT_TRUE(load_models_error_.IsSet()); +} + +TEST_F(NonUIModelTypeControllerTest, ActivateDataTypeOnBackendThread) { + LoadModels(); + EXPECT_EQ(sync_driver::DataTypeController::MODEL_LOADED, + controller_->state()); + RegisterWithBackend(); + ExpectProcessorConnected(true); + + StartAssociating(); + EXPECT_EQ(sync_driver::DataTypeController::RUNNING, controller_->state()); +} + +TEST_F(NonUIModelTypeControllerTest, Stop) { + LoadModels(); + RegisterWithBackend(); + ExpectProcessorConnected(true); + + StartAssociating(); + + DeactivateDataTypeAndStop(); + EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); +} + +} // namespace sync_driver_v2
diff --git a/components/sync/driver/pref_names.cc b/components/sync/driver/pref_names.cc new file mode 100644 index 0000000..b973029 --- /dev/null +++ b/components/sync/driver/pref_names.cc
@@ -0,0 +1,128 @@ +// 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 "build/build_config.h" +#include "components/sync/driver/pref_names.h" + +namespace sync_driver { + +namespace prefs { + +// 64-bit integer serialization of the base::Time when the last sync occurred. +const char kSyncLastSyncedTime[] = "sync.last_synced_time"; + +// 64-bit integer serialization of the base::Time of the last sync poll. +const char kSyncLastPollTime[] = "sync.last_poll_time"; + +// Boolean specifying whether the user finished setting up sync at least once. +const char kSyncFirstSetupComplete[] = "sync.has_setup_completed"; + +// Boolean specifying whether sync has an auth error. +const char kSyncHasAuthError[] = "sync.has_auth_error"; + +// Boolean specifying whether to automatically sync all data types (including +// future ones, as they're added). If this is true, the following preferences +// (kSyncBookmarks, kSyncPasswords, etc.) can all be ignored. +const char kSyncKeepEverythingSynced[] = "sync.keep_everything_synced"; + +// Booleans specifying whether the user has selected to sync the following +// datatypes. +const char kSyncAppList[] = "sync.app_list"; +const char kSyncAppNotifications[] = "sync.app_notifications"; +const char kSyncAppSettings[] = "sync.app_settings"; +const char kSyncApps[] = "sync.apps"; +const char kSyncArcPackage[] = "sync.arc_package"; +const char kSyncArticles[] = "sync.articles"; +const char kSyncAutofillProfile[] = "sync.autofill_profile"; +const char kSyncAutofillWallet[] = "sync.autofill_wallet"; +const char kSyncAutofillWalletMetadata[] = "sync.autofill_wallet_metadata"; +const char kSyncAutofill[] = "sync.autofill"; +const char kSyncBookmarks[] = "sync.bookmarks"; +const char kSyncDeviceInfo[] = "sync.device_info"; +const char kSyncDictionary[] = "sync.dictionary"; +const char kSyncExtensionSettings[] = "sync.extension_settings"; +const char kSyncExtensions[] = "sync.extensions"; +const char kSyncFaviconImages[] = "sync.favicon_images"; +const char kSyncFaviconTracking[] = "sync.favicon_tracking"; +const char kSyncHistoryDeleteDirectives[] = "sync.history_delete_directives"; +const char kSyncPasswords[] = "sync.passwords"; +const char kSyncPreferences[] = "sync.preferences"; +const char kSyncPriorityPreferences[] = "sync.priority_preferences"; +const char kSyncSearchEngines[] = "sync.search_engines"; +const char kSyncSessions[] = "sync.sessions"; +const char kSyncSupervisedUserSettings[] = "sync.managed_user_settings"; +const char kSyncSupervisedUserSharedSettings[] = + "sync.managed_user_shared_settings"; +const char kSyncSupervisedUserWhitelists[] = "sync.managed_user_whitelists"; +const char kSyncSupervisedUsers[] = "sync.managed_users"; +const char kSyncSyncedNotificationAppInfo[] = + "sync.synced_notification_app_info"; +const char kSyncSyncedNotifications[] = "sync.synced_notifications"; +const char kSyncTabs[] = "sync.tabs"; +const char kSyncThemes[] = "sync.themes"; +const char kSyncTypedUrls[] = "sync.typed_urls"; +const char kSyncWifiCredentials[] = "sync.wifi_credentials"; + +// Boolean used by enterprise configuration management in order to lock down +// sync. +const char kSyncManaged[] = "sync.managed"; + +// Boolean to prevent sync from automatically starting up. This is +// used when sync is disabled by the user via the privacy dashboard. +const char kSyncSuppressStart[] = "sync.suppress_start"; + +// A string that can be used to restore sync encryption infrastructure on +// startup so that the user doesn't need to provide credentials on each start. +const char kSyncEncryptionBootstrapToken[] = "sync.encryption_bootstrap_token"; + +// Same as kSyncEncryptionBootstrapToken, but derived from the keystore key, +// so we don't have to do a GetKey command at restart. +const char kSyncKeystoreEncryptionBootstrapToken[] = + "sync.keystore_encryption_bootstrap_token"; + +// The GUID session sync will use to identify this client, even across sync +// disable/enable events. +const char kSyncSessionsGUID[] = "sync.session_sync_guid"; + +#if defined(OS_CHROMEOS) +// A string that is used to store first-time sync startup after once sync is +// disabled. This will be refreshed every sign-in. +const char kSyncSpareBootstrapToken[] = "sync.spare_bootstrap_token"; +#endif // defined(OS_CHROMEOS) + +// Stores the timestamp of first sync. +const char kSyncFirstSyncTime[] = "sync.first_sync_time"; + +// Stores whether a platform specific passphrase error prompt has been shown to +// the user (e.g. an Android system notification). Used for out of band prompts +// that we only want to use once. +const char kSyncPassphrasePrompted[] = "sync.passphrase_prompted"; + +// Stores how many times received MEMORY_PRESSURE_LEVEL_CRITICAL. +const char kSyncMemoryPressureWarningCount[] = "sync.memory_warning_count"; + +// Stores if sync shutdown cleanly. +const char kSyncShutdownCleanly[] = "sync.shutdown_cleanly"; + +// Dictionary of last seen invalidation versions for each model type. +const char kSyncInvalidationVersions[] = "sync.invalidation_versions"; + +// The product version from the last restart of Chrome. +const char kSyncLastRunVersion[] = "sync.last_run_version"; + +// Flag indicating that passphrase encryption transition is in progress. +// Transition involves multiple steps and should continue across restarts. +const char kSyncPassphraseEncryptionTransitionInProgress[] = + "sync.passphrase_encryption_transition_in_progress"; + +// Updated Nigori state after user entering passphrase. This Nigori state should +// be persisted across restarts and passed to backend when it is initialized +// after directory cleanup. Preference contains base64 encoded serialized +// sync_pb::NigoriSpecifics. +const char kSyncNigoriStateForPassphraseTransition[] = + "sync.nigori_state_for_passphrase_transition"; + +} // namespace prefs + +} // namespace sync_driver
diff --git a/components/sync_driver/pref_names.h b/components/sync/driver/pref_names.h similarity index 100% rename from components/sync_driver/pref_names.h rename to components/sync/driver/pref_names.h
diff --git a/components/sync/driver/protocol_event_observer.cc b/components/sync/driver/protocol_event_observer.cc new file mode 100644 index 0000000..e7e9512d --- /dev/null +++ b/components/sync/driver/protocol_event_observer.cc
@@ -0,0 +1,13 @@ +// 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 "components/sync/driver/protocol_event_observer.h" + +namespace browser_sync { + +ProtocolEventObserver::ProtocolEventObserver() {} + +ProtocolEventObserver::~ProtocolEventObserver() {} + +} // namespace browser_sync
diff --git a/components/sync_driver/protocol_event_observer.h b/components/sync/driver/protocol_event_observer.h similarity index 100% rename from components/sync_driver/protocol_event_observer.h rename to components/sync/driver/protocol_event_observer.h
diff --git a/components/sync/driver/proxy_data_type_controller.cc b/components/sync/driver/proxy_data_type_controller.cc new file mode 100644 index 0000000..99c74b78 --- /dev/null +++ b/components/sync/driver/proxy_data_type_controller.cc
@@ -0,0 +1,73 @@ +// 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 "components/sync/driver/proxy_data_type_controller.h" + +#include "components/sync/api/sync_merge_result.h" + +namespace sync_driver { + +ProxyDataTypeController::ProxyDataTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + syncer::ModelType type) + : DataTypeController(ui_thread, base::Closure()), + state_(NOT_RUNNING), + type_(type) { + DCHECK(syncer::ProxyTypes().Has(type_)); +} + +ProxyDataTypeController::~ProxyDataTypeController() {} + +bool ProxyDataTypeController::ShouldLoadModelBeforeConfigure() const { + return false; +} + +void ProxyDataTypeController::LoadModels( + const ModelLoadCallback& model_load_callback) { + state_ = MODEL_LOADED; + model_load_callback.Run(type(), syncer::SyncError()); +} + +void ProxyDataTypeController::RegisterWithBackend( + BackendDataTypeConfigurer* configurer) {} + +void ProxyDataTypeController::StartAssociating( + const StartCallback& start_callback) { + syncer::SyncMergeResult local_merge_result(type_); + syncer::SyncMergeResult syncer_merge_result(type_); + state_ = RUNNING; + start_callback.Run(DataTypeController::OK, local_merge_result, + syncer_merge_result); +} + +void ProxyDataTypeController::Stop() { + state_ = NOT_RUNNING; +} + +syncer::ModelType ProxyDataTypeController::type() const { + DCHECK(syncer::ProxyTypes().Has(type_)); + return type_; +} + +std::string ProxyDataTypeController::name() const { + // For logging only. + return syncer::ModelTypeToString(type()); +} + +DataTypeController::State ProxyDataTypeController::state() const { + return state_; +} + +void ProxyDataTypeController::OnSingleDataTypeUnrecoverableError( + const syncer::SyncError& error) { + NOTIMPLEMENTED(); +} + +void ProxyDataTypeController::ActivateDataType( + BackendDataTypeConfigurer* configurer) {} + +void ProxyDataTypeController::DeactivateDataType( + BackendDataTypeConfigurer* configurer) {} + +} // namespace sync_driver
diff --git a/components/sync/driver/proxy_data_type_controller.h b/components/sync/driver/proxy_data_type_controller.h new file mode 100644 index 0000000..40e6f8d3 --- /dev/null +++ b/components/sync/driver/proxy_data_type_controller.h
@@ -0,0 +1,57 @@ +// 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 COMPONENTS_SYNC_DRIVER_PROXY_DATA_TYPE_CONTROLLER_H__ +#define COMPONENTS_SYNC_DRIVER_PROXY_DATA_TYPE_CONTROLLER_H__ + +#include <string> + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/single_thread_task_runner.h" +#include "components/sync/driver/data_type_controller.h" + +namespace sync_driver { + +// Implementation for proxy datatypes. These are datatype that have no +// representation in sync, and therefore no change processor or syncable +// service. +class ProxyDataTypeController : public DataTypeController { + public: + explicit ProxyDataTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + syncer::ModelType type); + + // DataTypeController interface. + bool ShouldLoadModelBeforeConfigure() const override; + void LoadModels(const ModelLoadCallback& model_load_callback) override; + void RegisterWithBackend(BackendDataTypeConfigurer* configurer) override; + void StartAssociating(const StartCallback& start_callback) override; + void Stop() override; + syncer::ModelType type() const override; + std::string name() const override; + State state() const override; + void ActivateDataType(BackendDataTypeConfigurer* configurer) override; + void DeactivateDataType(BackendDataTypeConfigurer* configurer) override; + + // DataTypeErrorHandler interface. + void OnSingleDataTypeUnrecoverableError( + const syncer::SyncError& error) override; + + protected: + // DataTypeController is RefCounted. + ~ProxyDataTypeController() override; + + private: + State state_; + + // The actual type for this controller. + syncer::ModelType type_; + + DISALLOW_COPY_AND_ASSIGN(ProxyDataTypeController); +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_PROXY_DATA_TYPE_CONTROLLER_H__
diff --git a/components/sync_driver/resources/about.css b/components/sync/driver/resources/about.css similarity index 100% rename from components/sync_driver/resources/about.css rename to components/sync/driver/resources/about.css
diff --git a/components/sync_driver/resources/about.html b/components/sync/driver/resources/about.html similarity index 100% rename from components/sync_driver/resources/about.html rename to components/sync/driver/resources/about.html
diff --git a/components/sync_driver/resources/about.js b/components/sync/driver/resources/about.js similarity index 100% rename from components/sync_driver/resources/about.js rename to components/sync/driver/resources/about.js
diff --git a/components/sync_driver/resources/chrome_sync.js b/components/sync/driver/resources/chrome_sync.js similarity index 100% rename from components/sync_driver/resources/chrome_sync.js rename to components/sync/driver/resources/chrome_sync.js
diff --git a/components/sync_driver/resources/data.html b/components/sync/driver/resources/data.html similarity index 100% rename from components/sync_driver/resources/data.html rename to components/sync/driver/resources/data.html
diff --git a/components/sync_driver/resources/data.js b/components/sync/driver/resources/data.js similarity index 100% rename from components/sync_driver/resources/data.js rename to components/sync/driver/resources/data.js
diff --git a/components/sync_driver/resources/events.css b/components/sync/driver/resources/events.css similarity index 100% rename from components/sync_driver/resources/events.css rename to components/sync/driver/resources/events.css
diff --git a/components/sync_driver/resources/events.html b/components/sync/driver/resources/events.html similarity index 100% rename from components/sync_driver/resources/events.html rename to components/sync/driver/resources/events.html
diff --git a/components/sync_driver/resources/events.js b/components/sync/driver/resources/events.js similarity index 100% rename from components/sync_driver/resources/events.js rename to components/sync/driver/resources/events.js
diff --git a/components/sync_driver/resources/index.html b/components/sync/driver/resources/index.html similarity index 100% rename from components/sync_driver/resources/index.html rename to components/sync/driver/resources/index.html
diff --git a/components/sync_driver/resources/node_browser.html b/components/sync/driver/resources/node_browser.html similarity index 100% rename from components/sync_driver/resources/node_browser.html rename to components/sync/driver/resources/node_browser.html
diff --git a/components/sync_driver/resources/search.html b/components/sync/driver/resources/search.html similarity index 100% rename from components/sync_driver/resources/search.html rename to components/sync/driver/resources/search.html
diff --git a/components/sync_driver/resources/search.js b/components/sync/driver/resources/search.js similarity index 100% rename from components/sync_driver/resources/search.js rename to components/sync/driver/resources/search.js
diff --git a/components/sync_driver/resources/sync_index.js b/components/sync/driver/resources/sync_index.js similarity index 100% rename from components/sync_driver/resources/sync_index.js rename to components/sync/driver/resources/sync_index.js
diff --git a/components/sync_driver/resources/sync_log.js b/components/sync/driver/resources/sync_log.js similarity index 100% rename from components/sync_driver/resources/sync_log.js rename to components/sync/driver/resources/sync_log.js
diff --git a/components/sync/driver/resources/sync_node_browser.css b/components/sync/driver/resources/sync_node_browser.css new file mode 100644 index 0000000..daebf69 --- /dev/null +++ b/components/sync/driver/resources/sync_node_browser.css
@@ -0,0 +1,68 @@ +/* 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. */ + +#sync-node-browser-refresher { + border-bottom: 1px rgb(160,160,160) solid; +} + +#sync-node-browser-refresher > * { + display: inline-block; +} + +#sync-node-browser-container { + display: flex; + height: 750px; +} + +#sync-node-tree-container { + -webkit-padding-start: 10px; + box-sizing: border-box; + height: 100%; + /* min-width and max-width are used by the split pane. */ + max-width: 50%; + min-width: 200px; + overflow: auto; + width: 200px; +} + +#sync-node-tree { + display: inline-block; + min-width: 100%; + overflow: visible; /* let the container do the scrolling */ +} + +/* TODO(akalin): Find a better icon to use for leaf nodes. */ +#sync-node-tree .leaf .tree-label { + background-image: url(../../../../ui/webui/resources/images/star_small.png); +} + +#sync-node-splitter { + background-color: rgb(235, 239, 249); + cursor: col-resize; + min-width: 5px; +<if expr="is_win"> + /* TODO(akalin): Make the BMM also use this style. */ + cursor: e-resize; +</if> +} + +#sync-node-details-container { + flex: 1; + height: 100%; + overflow: auto; + visibility: hidden; /* Element is invisible until first refresh. */ +} + +#node-details { + flex-grow: 1; +} + +#node-details td { + vertical-align: top; + white-space: nowrap; +} + +#node-details tr:nth-child(odd) { + background: rgb(239, 243, 255); +}
diff --git a/components/sync_driver/resources/sync_node_browser.js b/components/sync/driver/resources/sync_node_browser.js similarity index 100% rename from components/sync_driver/resources/sync_node_browser.js rename to components/sync/driver/resources/sync_node_browser.js
diff --git a/components/sync_driver/resources/sync_search.css b/components/sync/driver/resources/sync_search.css similarity index 100% rename from components/sync_driver/resources/sync_search.css rename to components/sync/driver/resources/sync_search.css
diff --git a/components/sync_driver/resources/sync_search.js b/components/sync/driver/resources/sync_search.js similarity index 100% rename from components/sync_driver/resources/sync_search.js rename to components/sync/driver/resources/sync_search.js
diff --git a/components/sync_driver/resources/types.css b/components/sync/driver/resources/types.css similarity index 100% rename from components/sync_driver/resources/types.css rename to components/sync/driver/resources/types.css
diff --git a/components/sync_driver/resources/types.html b/components/sync/driver/resources/types.html similarity index 100% rename from components/sync_driver/resources/types.html rename to components/sync/driver/resources/types.html
diff --git a/components/sync_driver/resources/types.js b/components/sync/driver/resources/types.js similarity index 100% rename from components/sync_driver/resources/types.js rename to components/sync/driver/resources/types.js
diff --git a/components/sync/driver/shared_change_processor.cc b/components/sync/driver/shared_change_processor.cc new file mode 100644 index 0000000..51471c1 --- /dev/null +++ b/components/sync/driver/shared_change_processor.cc
@@ -0,0 +1,214 @@ +// 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 "components/sync/driver/shared_change_processor.h" + +#include <utility> + +#include "base/threading/thread_task_runner_handle.h" +#include "components/sync/api/sync_change.h" +#include "components/sync/api/syncable_service.h" +#include "components/sync/core/data_type_error_handler.h" +#include "components/sync/driver/generic_change_processor.h" +#include "components/sync/driver/generic_change_processor_factory.h" +#include "components/sync/driver/sync_client.h" + +using base::AutoLock; + +namespace syncer { +class AttachmentService; +} + +namespace sync_driver { + +SharedChangeProcessor::SharedChangeProcessor() + : disconnected_(false), + type_(syncer::UNSPECIFIED), + frontend_task_runner_(base::ThreadTaskRunnerHandle::Get()), + generic_change_processor_(NULL), + error_handler_(NULL) {} + +SharedChangeProcessor::~SharedChangeProcessor() { + // We can either be deleted when the DTC is destroyed (on UI + // thread), or when the syncer::SyncableService stops syncing (datatype + // thread). |generic_change_processor_|, if non-NULL, must be + // deleted on |backend_loop_|. + if (backend_task_runner_.get()) { + if (backend_task_runner_->BelongsToCurrentThread()) { + delete generic_change_processor_; + } else { + DCHECK(frontend_task_runner_->BelongsToCurrentThread()); + if (!backend_task_runner_->DeleteSoon(FROM_HERE, + generic_change_processor_)) { + NOTREACHED(); + } + } + } else { + DCHECK(!generic_change_processor_); + } +} + +base::WeakPtr<syncer::SyncableService> SharedChangeProcessor::Connect( + SyncClient* sync_client, + GenericChangeProcessorFactory* processor_factory, + syncer::UserShare* user_share, + syncer::DataTypeErrorHandler* error_handler, + syncer::ModelType type, + const base::WeakPtr<syncer::SyncMergeResult>& merge_result) { + DCHECK(sync_client); + DCHECK(error_handler); + DCHECK_NE(type, syncer::UNSPECIFIED); + backend_task_runner_ = base::ThreadTaskRunnerHandle::Get(); + AutoLock lock(monitor_lock_); + if (disconnected_) + return base::WeakPtr<syncer::SyncableService>(); + type_ = type; + error_handler_ = error_handler; + base::WeakPtr<syncer::SyncableService> local_service = + sync_client->GetSyncableServiceForType(type); + if (!local_service.get()) { + LOG(WARNING) << "SyncableService destroyed before DTC was stopped."; + disconnected_ = true; + return base::WeakPtr<syncer::SyncableService>(); + } + + generic_change_processor_ = processor_factory + ->CreateGenericChangeProcessor( + type, user_share, error_handler, + local_service, merge_result, sync_client) + .release(); + // If available, propagate attachment service to the syncable service. + std::unique_ptr<syncer::AttachmentService> attachment_service = + generic_change_processor_->GetAttachmentService(); + if (attachment_service) { + local_service->SetAttachmentService(std::move(attachment_service)); + } + return local_service; +} + +bool SharedChangeProcessor::Disconnect() { + // May be called from any thread. + DVLOG(1) << "Disconnecting change processor."; + AutoLock lock(monitor_lock_); + bool was_connected = !disconnected_; + disconnected_ = true; + error_handler_ = NULL; + return was_connected; +} + +ChangeProcessor* SharedChangeProcessor::generic_change_processor() { + return generic_change_processor_; +} + +int SharedChangeProcessor::GetSyncCount() { + DCHECK(backend_task_runner_.get()); + DCHECK(backend_task_runner_->BelongsToCurrentThread()); + AutoLock lock(monitor_lock_); + if (disconnected_) { + LOG(ERROR) << "Change processor disconnected."; + return 0; + } + return generic_change_processor_->GetSyncCount(); +} + +syncer::SyncError SharedChangeProcessor::ProcessSyncChanges( + const tracked_objects::Location& from_here, + const syncer::SyncChangeList& list_of_changes) { + DCHECK(backend_task_runner_.get()); + DCHECK(backend_task_runner_->BelongsToCurrentThread()); + AutoLock lock(monitor_lock_); + if (disconnected_) { + // The DTC that disconnects us must ensure it posts a StopSyncing task. + // If we reach this, it means it just hasn't executed yet. + syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Change processor disconnected.", type_); + return error; + } + return generic_change_processor_->ProcessSyncChanges(from_here, + list_of_changes); +} + +syncer::SyncDataList SharedChangeProcessor::GetAllSyncData( + syncer::ModelType type) const { + syncer::SyncDataList data; + GetAllSyncDataReturnError(type, &data); // Handles the disconnect case. + return data; +} + +syncer::SyncError SharedChangeProcessor::GetAllSyncDataReturnError( + syncer::ModelType type, + syncer::SyncDataList* data) const { + DCHECK(backend_task_runner_.get()); + DCHECK(backend_task_runner_->BelongsToCurrentThread()); + AutoLock lock(monitor_lock_); + if (disconnected_) { + syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Change processor disconnected.", type_); + return error; + } + return generic_change_processor_->GetAllSyncDataReturnError(data); +} + +syncer::SyncError SharedChangeProcessor::UpdateDataTypeContext( + syncer::ModelType type, + syncer::SyncChangeProcessor::ContextRefreshStatus refresh_status, + const std::string& context) { + DCHECK(backend_task_runner_.get()); + DCHECK(backend_task_runner_->BelongsToCurrentThread()); + AutoLock lock(monitor_lock_); + if (disconnected_) { + syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Change processor disconnected.", type_); + return error; + } + return generic_change_processor_->UpdateDataTypeContext(type, refresh_status, + context); +} + +bool SharedChangeProcessor::SyncModelHasUserCreatedNodes(bool* has_nodes) { + DCHECK(backend_task_runner_.get()); + DCHECK(backend_task_runner_->BelongsToCurrentThread()); + AutoLock lock(monitor_lock_); + if (disconnected_) { + LOG(ERROR) << "Change processor disconnected."; + return false; + } + return generic_change_processor_->SyncModelHasUserCreatedNodes(has_nodes); +} + +bool SharedChangeProcessor::CryptoReadyIfNecessary() { + DCHECK(backend_task_runner_.get()); + DCHECK(backend_task_runner_->BelongsToCurrentThread()); + AutoLock lock(monitor_lock_); + if (disconnected_) { + LOG(ERROR) << "Change processor disconnected."; + return true; // Otherwise we get into infinite spin waiting. + } + return generic_change_processor_->CryptoReadyIfNecessary(); +} + +bool SharedChangeProcessor::GetDataTypeContext(std::string* context) const { + DCHECK(backend_task_runner_.get()); + DCHECK(backend_task_runner_->BelongsToCurrentThread()); + AutoLock lock(monitor_lock_); + if (disconnected_) { + LOG(ERROR) << "Change processor disconnected."; + return false; + } + return generic_change_processor_->GetDataTypeContext(context); +} + +syncer::SyncError SharedChangeProcessor::CreateAndUploadError( + const tracked_objects::Location& location, + const std::string& message) { + AutoLock lock(monitor_lock_); + if (!disconnected_) { + return error_handler_->CreateAndUploadError(location, message, type_); + } else { + return syncer::SyncError(location, syncer::SyncError::DATATYPE_ERROR, + message, type_); + } +} + +} // namespace sync_driver
diff --git a/components/sync_driver/shared_change_processor.h b/components/sync/driver/shared_change_processor.h similarity index 100% rename from components/sync_driver/shared_change_processor.h rename to components/sync/driver/shared_change_processor.h
diff --git a/components/sync/driver/shared_change_processor_ref.cc b/components/sync/driver/shared_change_processor_ref.cc new file mode 100644 index 0000000..49df65eb --- /dev/null +++ b/components/sync/driver/shared_change_processor_ref.cc
@@ -0,0 +1,42 @@ +// 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 "components/sync/driver/shared_change_processor_ref.h" + +namespace sync_driver { + +SharedChangeProcessorRef::SharedChangeProcessorRef( + const scoped_refptr<SharedChangeProcessor>& change_processor) + : change_processor_(change_processor) { + DCHECK(change_processor_.get()); +} + +SharedChangeProcessorRef::~SharedChangeProcessorRef() {} + +syncer::SyncError SharedChangeProcessorRef::ProcessSyncChanges( + const tracked_objects::Location& from_here, + const syncer::SyncChangeList& change_list) { + return change_processor_->ProcessSyncChanges(from_here, change_list); +} + +syncer::SyncDataList SharedChangeProcessorRef::GetAllSyncData( + syncer::ModelType type) const { + return change_processor_->GetAllSyncData(type); +} + +syncer::SyncError SharedChangeProcessorRef::UpdateDataTypeContext( + syncer::ModelType type, + syncer::SyncChangeProcessor::ContextRefreshStatus refresh_status, + const std::string& context) { + return change_processor_->UpdateDataTypeContext(type, refresh_status, + context); +} + +syncer::SyncError SharedChangeProcessorRef::CreateAndUploadError( + const tracked_objects::Location& from_here, + const std::string& message) { + return change_processor_->CreateAndUploadError(from_here, message); +} + +} // namespace sync_driver
diff --git a/components/sync/driver/shared_change_processor_ref.h b/components/sync/driver/shared_change_processor_ref.h new file mode 100644 index 0000000..c0167b27 --- /dev/null +++ b/components/sync/driver/shared_change_processor_ref.h
@@ -0,0 +1,50 @@ +// 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 COMPONENTS_SYNC_DRIVER_SHARED_CHANGE_PROCESSOR_REF_H_ +#define COMPONENTS_SYNC_DRIVER_SHARED_CHANGE_PROCESSOR_REF_H_ + +#include <string> + +#include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" +#include "components/sync/api/sync_change_processor.h" +#include "components/sync/api/sync_error_factory.h" +#include "components/sync/driver/shared_change_processor.h" + +namespace sync_driver { + +// A syncer::SyncChangeProcessor stub for interacting with a refcounted +// SharedChangeProcessor. +class SharedChangeProcessorRef : public syncer::SyncChangeProcessor, + public syncer::SyncErrorFactory { + public: + SharedChangeProcessorRef( + const scoped_refptr<SharedChangeProcessor>& change_processor); + ~SharedChangeProcessorRef() override; + + // syncer::SyncChangeProcessor implementation. + syncer::SyncError ProcessSyncChanges( + const tracked_objects::Location& from_here, + const syncer::SyncChangeList& change_list) override; + syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override; + syncer::SyncError UpdateDataTypeContext( + syncer::ModelType type, + syncer::SyncChangeProcessor::ContextRefreshStatus refresh_status, + const std::string& context) override; + + // syncer::SyncErrorFactory implementation. + syncer::SyncError CreateAndUploadError( + const tracked_objects::Location& from_here, + const std::string& message) override; + + // Default copy and assign welcome (and safe due to refcounted-ness). + + private: + scoped_refptr<SharedChangeProcessor> change_processor_; +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_SHARED_CHANGE_PROCESSOR_REF_H_
diff --git a/components/sync/driver/shared_change_processor_unittest.cc b/components/sync/driver/shared_change_processor_unittest.cc new file mode 100644 index 0000000..ccfd987 --- /dev/null +++ b/components/sync/driver/shared_change_processor_unittest.cc
@@ -0,0 +1,237 @@ +// 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 "components/sync/driver/shared_change_processor.h" + +#include <cstddef> +#include <string> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/compiler_specific.h" +#include "base/location.h" +#include "base/single_thread_task_runner.h" +#include "base/synchronization/waitable_event.h" +#include "base/threading/thread.h" +#include "components/sync/api/attachments/attachment_id.h" +#include "components/sync/api/attachments/attachment_store.h" +#include "components/sync/api/fake_syncable_service.h" +#include "components/sync/base/model_type.h" +#include "components/sync/core/attachments/attachment_service_impl.h" +#include "components/sync/core/test/data_type_error_handler_mock.h" +#include "components/sync/core/test/test_user_share.h" +#include "components/sync/driver/fake_sync_client.h" +#include "components/sync/driver/generic_change_processor.h" +#include "components/sync/driver/generic_change_processor_factory.h" +#include "components/sync/driver/local_device_info_provider.h" +#include "components/sync/driver/sync_api_component_factory.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace sync_driver { + +namespace { + +using ::testing::NiceMock; +using ::testing::StrictMock; + +class TestSyncApiComponentFactory : public SyncApiComponentFactory { + public: + TestSyncApiComponentFactory() {} + ~TestSyncApiComponentFactory() override {} + + // SyncApiComponentFactory implementation. + void RegisterDataTypes( + sync_driver::SyncService* sync_service, + const RegisterDataTypesMethod& register_platform_types_method) override {} + sync_driver::DataTypeManager* CreateDataTypeManager( + const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& + debug_info_listener, + const sync_driver::DataTypeController::TypeMap* controllers, + const sync_driver::DataTypeEncryptionHandler* encryption_handler, + browser_sync::SyncBackendHost* backend, + sync_driver::DataTypeManagerObserver* observer) override { + return nullptr; + } + browser_sync::SyncBackendHost* CreateSyncBackendHost( + const std::string& name, + invalidation::InvalidationService* invalidator, + const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs, + const base::FilePath& sync_folder) override { + return nullptr; + } + std::unique_ptr<sync_driver::LocalDeviceInfoProvider> + CreateLocalDeviceInfoProvider() override { + return nullptr; + } + SyncApiComponentFactory::SyncComponents CreateBookmarkSyncComponents( + sync_driver::SyncService* sync_service, + syncer::DataTypeErrorHandler* error_handler) override { + return SyncApiComponentFactory::SyncComponents(nullptr, nullptr); + } + std::unique_ptr<syncer::AttachmentService> CreateAttachmentService( + std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store, + const syncer::UserShare& user_share, + const std::string& store_birthday, + syncer::ModelType model_type, + syncer::AttachmentService::Delegate* delegate) override { + return syncer::AttachmentServiceImpl::CreateForTest(); + } +}; + +class SyncSharedChangeProcessorTest : public testing::Test, + public FakeSyncClient { + public: + SyncSharedChangeProcessorTest() + : FakeSyncClient(&factory_), + backend_thread_("dbthread"), + did_connect_(false), + has_attachment_service_(false) {} + + ~SyncSharedChangeProcessorTest() override { + EXPECT_FALSE(db_syncable_service_.get()); + } + + // FakeSyncClient override. + base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType( + syncer::ModelType type) override { + return db_syncable_service_->AsWeakPtr(); + } + + protected: + void SetUp() override { + test_user_share_.SetUp(); + shared_change_processor_ = new SharedChangeProcessor(); + ASSERT_TRUE(backend_thread_.Start()); + ASSERT_TRUE(backend_thread_.task_runner()->PostTask( + FROM_HERE, + base::Bind(&SyncSharedChangeProcessorTest::SetUpDBSyncableService, + base::Unretained(this)))); + } + + void TearDown() override { + EXPECT_TRUE(backend_thread_.task_runner()->PostTask( + FROM_HERE, + base::Bind(&SyncSharedChangeProcessorTest::TearDownDBSyncableService, + base::Unretained(this)))); + // This must happen before the DB thread is stopped since + // |shared_change_processor_| may post tasks to delete its members + // on the correct thread. + // + // TODO(akalin): Write deterministic tests for the destruction of + // |shared_change_processor_| on the UI and DB threads. + shared_change_processor_ = NULL; + backend_thread_.Stop(); + + // Note: Stop() joins the threads, and that barrier prevents this read + // from being moved (e.g by compiler optimization) in such a way that it + // would race with the write in ConnectOnDBThread (because by this time, + // everything that could have run on |backend_thread_| has done so). + ASSERT_TRUE(did_connect_); + test_user_share_.TearDown(); + } + + // Connect |shared_change_processor_| on the DB thread. + void Connect() { + EXPECT_TRUE(backend_thread_.task_runner()->PostTask( + FROM_HERE, + base::Bind(&SyncSharedChangeProcessorTest::ConnectOnDBThread, + base::Unretained(this), shared_change_processor_))); + } + + void SetAttachmentStore() { + EXPECT_TRUE(backend_thread_.task_runner()->PostTask( + FROM_HERE, + base::Bind(&SyncSharedChangeProcessorTest::SetAttachmentStoreOnDBThread, + base::Unretained(this)))); + } + + bool HasAttachmentService() { + base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, + base::WaitableEvent::InitialState::NOT_SIGNALED); + EXPECT_TRUE(backend_thread_.task_runner()->PostTask( + FROM_HERE, + base::Bind( + &SyncSharedChangeProcessorTest::CheckAttachmentServiceOnDBThread, + base::Unretained(this), base::Unretained(&event)))); + event.Wait(); + return has_attachment_service_; + } + + private: + // Used by SetUp(). + void SetUpDBSyncableService() { + DCHECK(backend_thread_.task_runner()->BelongsToCurrentThread()); + DCHECK(!db_syncable_service_.get()); + db_syncable_service_.reset(new syncer::FakeSyncableService()); + } + + // Used by TearDown(). + void TearDownDBSyncableService() { + DCHECK(backend_thread_.task_runner()->BelongsToCurrentThread()); + DCHECK(db_syncable_service_.get()); + db_syncable_service_.reset(); + } + + void SetAttachmentStoreOnDBThread() { + DCHECK(backend_thread_.task_runner()->BelongsToCurrentThread()); + DCHECK(db_syncable_service_.get()); + db_syncable_service_->set_attachment_store( + syncer::AttachmentStore::CreateInMemoryStore()); + } + + // Used by Connect(). The SharedChangeProcessor is passed in + // because we modify |shared_change_processor_| on the main thread + // (in TearDown()). + void ConnectOnDBThread( + const scoped_refptr<SharedChangeProcessor>& shared_change_processor) { + DCHECK(backend_thread_.task_runner()->BelongsToCurrentThread()); + EXPECT_TRUE(shared_change_processor->Connect( + this, &processor_factory_, test_user_share_.user_share(), + &error_handler_, syncer::AUTOFILL, + base::WeakPtr<syncer::SyncMergeResult>())); + did_connect_ = true; + } + + void CheckAttachmentServiceOnDBThread(base::WaitableEvent* event) { + DCHECK(backend_thread_.task_runner()->BelongsToCurrentThread()); + DCHECK(db_syncable_service_.get()); + has_attachment_service_ = !!db_syncable_service_->attachment_service(); + event->Signal(); + } + + base::MessageLoop frontend_loop_; + base::Thread backend_thread_; + syncer::TestUserShare test_user_share_; + TestSyncApiComponentFactory factory_; + + scoped_refptr<SharedChangeProcessor> shared_change_processor_; + StrictMock<syncer::DataTypeErrorHandlerMock> error_handler_; + + GenericChangeProcessorFactory processor_factory_; + bool did_connect_; + bool has_attachment_service_; + + // Used only on DB thread. + std::unique_ptr<syncer::FakeSyncableService> db_syncable_service_; +}; + +// Simply connect the shared change processor. It should succeed, and +// nothing further should happen. +TEST_F(SyncSharedChangeProcessorTest, Basic) { + Connect(); +} + +// Connect the shared change processor to a syncable service with +// AttachmentStore. Verify that shared change processor implementation +// creates AttachmentService and passes it back to the syncable service. +TEST_F(SyncSharedChangeProcessorTest, ConnectWithAttachmentStore) { + SetAttachmentStore(); + Connect(); + EXPECT_TRUE(HasAttachmentService()); +} + +} // namespace + +} // namespace sync_driver
diff --git a/components/sync/driver/signin_manager_wrapper.cc b/components/sync/driver/signin_manager_wrapper.cc new file mode 100644 index 0000000..bf96127 --- /dev/null +++ b/components/sync/driver/signin_manager_wrapper.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 "components/sync/driver/signin_manager_wrapper.h" + +#include "components/signin/core/browser/signin_manager_base.h" +#include "google_apis/gaia/gaia_constants.h" + +SigninManagerWrapper::SigninManagerWrapper(SigninManagerBase* original) + : original_(original) {} + +SigninManagerWrapper::~SigninManagerWrapper() {} + +SigninManagerBase* SigninManagerWrapper::GetOriginal() { + return original_; +} + +std::string SigninManagerWrapper::GetEffectiveUsername() const { + return original_->GetAuthenticatedAccountInfo().email; +} + +std::string SigninManagerWrapper::GetAccountIdToUse() const { + return original_->GetAuthenticatedAccountId(); +} + +std::string SigninManagerWrapper::GetSyncScopeToUse() const { + return GaiaConstants::kChromeSyncOAuth2Scope; +}
diff --git a/components/sync_driver/signin_manager_wrapper.h b/components/sync/driver/signin_manager_wrapper.h similarity index 100% rename from components/sync_driver/signin_manager_wrapper.h rename to components/sync/driver/signin_manager_wrapper.h
diff --git a/components/sync/driver/startup_controller.cc b/components/sync/driver/startup_controller.cc new file mode 100644 index 0000000..9a5b33b4 --- /dev/null +++ b/components/sync/driver/startup_controller.cc
@@ -0,0 +1,205 @@ +// 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 "components/sync/driver/startup_controller.h" + +#include <string> + +#include "base/command_line.h" +#include "base/location.h" +#include "base/metrics/histogram.h" +#include "base/single_thread_task_runner.h" +#include "base/strings/string_number_conversions.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/sync/driver/sync_driver_switches.h" +#include "components/sync/driver/sync_prefs.h" + +namespace browser_sync { + +namespace { + +// The amount of time we'll wait to initialize sync if no data type triggers +// initialization via a StartSyncFlare. +const int kDeferredInitFallbackSeconds = 10; + +// Enum (for UMA, primarily) defining different events that cause us to +// exit the "deferred" state of initialization and invoke start_backend. +enum DeferredInitTrigger { + // We have received a signal from a SyncableService requesting that sync + // starts as soon as possible. + TRIGGER_DATA_TYPE_REQUEST, + // No data type requested sync to start and our fallback timer expired. + TRIGGER_FALLBACK_TIMER, + MAX_TRIGGER_VALUE +}; + +} // namespace + +StartupController::StartupController(const sync_driver::SyncPrefs* sync_prefs, + base::Callback<bool()> can_start, + base::Closure start_backend) + : bypass_setup_complete_(false), + received_start_request_(false), + setup_in_progress_(false), + sync_prefs_(sync_prefs), + can_start_(can_start), + start_backend_(start_backend), + fallback_timeout_( + base::TimeDelta::FromSeconds(kDeferredInitFallbackSeconds)), + weak_factory_(this) { + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kSyncDeferredStartupTimeoutSeconds)) { + int timeout = kDeferredInitFallbackSeconds; + if (base::StringToInt( + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( + switches::kSyncDeferredStartupTimeoutSeconds), + &timeout)) { + DCHECK_GE(timeout, 0); + DVLOG(2) << "Sync StartupController overriding startup timeout to " + << timeout << " seconds."; + fallback_timeout_ = base::TimeDelta::FromSeconds(timeout); + } + } +} + +StartupController::~StartupController() {} + +void StartupController::Reset(const syncer::ModelTypeSet registered_types) { + received_start_request_ = false; + bypass_setup_complete_ = false; + start_up_time_ = base::Time(); + start_backend_time_ = base::Time(); + // Don't let previous timers affect us post-reset. + weak_factory_.InvalidateWeakPtrs(); + registered_types_ = registered_types; +} + +void StartupController::SetSetupInProgress(bool setup_in_progress) { + setup_in_progress_ = setup_in_progress; + if (setup_in_progress_) { + TryStart(); + } +} + +bool StartupController::StartUp(StartUpDeferredOption deferred_option) { + const bool first_start = start_up_time_.is_null(); + if (first_start) + start_up_time_ = base::Time::Now(); + + if (deferred_option == STARTUP_BACKEND_DEFERRED && + !base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kSyncDisableDeferredStartup) && + sync_prefs_->GetPreferredDataTypes(registered_types_) + .Has(syncer::SESSIONS)) { + if (first_start) { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&StartupController::OnFallbackStartupTimerExpired, + weak_factory_.GetWeakPtr()), + fallback_timeout_); + } + return false; + } + + if (start_backend_time_.is_null()) { + start_backend_time_ = base::Time::Now(); + start_backend_.Run(); + } + + return true; +} + +void StartupController::OverrideFallbackTimeoutForTest( + const base::TimeDelta& timeout) { + fallback_timeout_ = timeout; +} + +bool StartupController::TryStart() { + if (!can_start_.Run()) + return false; + + // For performance reasons, defer the heavy lifting for sync init unless: + // + // - a datatype has requested an immediate start of sync, or + // - sync needs to start up the backend immediately to provide control state + // and encryption information to the UI. + // Do not start up the sync backend if setup has not completed and isn't + // in progress, unless told to otherwise. + if (setup_in_progress_) { + return StartUp(STARTUP_IMMEDIATE); + } else if (sync_prefs_->IsFirstSetupComplete() || bypass_setup_complete_) { + return StartUp(received_start_request_ ? STARTUP_IMMEDIATE + : STARTUP_BACKEND_DEFERRED); + } else { + return false; + } +} + +bool StartupController::TryStartImmediately() { + received_start_request_ = true; + bypass_setup_complete_ = true; + return TryStart(); +} + +void StartupController::RecordTimeDeferred() { + DCHECK(!start_up_time_.is_null()); + base::TimeDelta time_deferred = base::Time::Now() - start_up_time_; + UMA_HISTOGRAM_CUSTOM_TIMES("Sync.Startup.TimeDeferred2", time_deferred, + base::TimeDelta::FromSeconds(0), + base::TimeDelta::FromMinutes(2), 60); +} + +void StartupController::OnFallbackStartupTimerExpired() { + DCHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kSyncDisableDeferredStartup)); + + if (!start_backend_time_.is_null()) + return; + + DVLOG(2) << "Sync deferred init fallback timer expired, starting backend."; + RecordTimeDeferred(); + UMA_HISTOGRAM_ENUMERATION("Sync.Startup.DeferredInitTrigger", + TRIGGER_FALLBACK_TIMER, MAX_TRIGGER_VALUE); + received_start_request_ = true; + TryStart(); +} + +std::string StartupController::GetBackendInitializationStateString() const { + if (!start_backend_time_.is_null()) + return "Started"; + else if (!start_up_time_.is_null()) + return "Deferred"; + else + return "Not started"; +} + +void StartupController::OnDataTypeRequestsSyncStartup(syncer::ModelType type) { + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kSyncDisableDeferredStartup)) { + DVLOG(2) << "Ignoring data type request for sync startup: " + << syncer::ModelTypeToString(type); + return; + } + + if (!start_backend_time_.is_null()) + return; + + DVLOG(2) << "Data type requesting sync startup: " + << syncer::ModelTypeToString(type); + // Measure the time spent waiting for init and the type that triggered it. + // We could measure the time spent deferred on a per-datatype basis, but + // for now this is probably sufficient. + if (!start_up_time_.is_null()) { + RecordTimeDeferred(); + UMA_HISTOGRAM_ENUMERATION("Sync.Startup.TypeTriggeringInit", + ModelTypeToHistogramInt(type), + syncer::MODEL_TYPE_COUNT); + UMA_HISTOGRAM_ENUMERATION("Sync.Startup.DeferredInitTrigger", + TRIGGER_DATA_TYPE_REQUEST, MAX_TRIGGER_VALUE); + } + received_start_request_ = true; + TryStart(); +} + +} // namespace browser_sync
diff --git a/components/sync/driver/startup_controller.h b/components/sync/driver/startup_controller.h new file mode 100644 index 0000000..3bee4862 --- /dev/null +++ b/components/sync/driver/startup_controller.h
@@ -0,0 +1,114 @@ +// 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 COMPONENTS_SYNC_DRIVER_STARTUP_CONTROLLER_H_ +#define COMPONENTS_SYNC_DRIVER_STARTUP_CONTROLLER_H_ + +#include "base/callback.h" +#include "base/memory/weak_ptr.h" +#include "base/time/time.h" +#include "components/sync/base/model_type.h" + +namespace sync_driver { +class SyncPrefs; +} + +namespace browser_sync { + +// This class is used by ProfileSyncService to manage all logic and state +// pertaining to initialization of the SyncBackendHost (colloquially referred +// to as "the backend"). +class StartupController { + public: + StartupController(const sync_driver::SyncPrefs* sync_prefs, + base::Callback<bool()> can_start, + base::Closure start_backend); + ~StartupController(); + + // Starts up sync if it is requested by the user and preconditions are met. + // Returns true if these preconditions are met, although does not imply + // the backend was started. + bool TryStart(); + + // Same as TryStart() above, but bypasses deferred startup and the first setup + // complete check. + bool TryStartImmediately(); + + // Called when a datatype (SyncableService) has a need for sync to start + // ASAP, presumably because a local change event has occurred but we're + // still in deferred start mode, meaning the SyncableService hasn't been + // told to MergeDataAndStartSyncing yet. + // It is expected that |type| is a currently active datatype. + void OnDataTypeRequestsSyncStartup(syncer::ModelType type); + + // Prepares this object for a new attempt to start sync, forgetting + // whether or not preconditions were previously met. + // NOTE: This resets internal state managed by this class, but does not + // touch values that are explicitly set and reset by higher layers to + // tell this class whether a setup UI dialog is being shown to the user. + // See setup_in_progress_. + void Reset(const syncer::ModelTypeSet registered_types); + + // Sets the setup in progress flag and tries to start sync if it's true. + void SetSetupInProgress(bool setup_in_progress); + + bool IsSetupInProgress() const { return setup_in_progress_; } + base::Time start_backend_time() const { return start_backend_time_; } + std::string GetBackendInitializationStateString() const; + + void OverrideFallbackTimeoutForTest(const base::TimeDelta& timeout); + + private: + enum StartUpDeferredOption { STARTUP_BACKEND_DEFERRED, STARTUP_IMMEDIATE }; + // Returns true if all conditions to start the backend are met. + bool StartUp(StartUpDeferredOption deferred_option); + void OnFallbackStartupTimerExpired(); + + // Records time spent in deferred state with UMA histograms. + void RecordTimeDeferred(); + + // If true, will bypass the FirstSetupComplete check when triggering sync + // startup. + bool bypass_setup_complete_; + + // True if we should start sync ASAP because either a SyncableService has + // requested it, or we're done waiting for a sign and decided to go ahead. + bool received_start_request_; + + // The time that StartUp() is called. This is used to calculate time spent + // in the deferred state; that is, after StartUp and before invoking the + // start_backend_ callback. + base::Time start_up_time_; + + // If |true|, there is setup UI visible so we should not start downloading + // data types. + // Note: this is explicitly controlled by higher layers (UI) and is meant to + // reflect what the UI claims the setup state to be. Therefore, only set this + // due to explicit requests to do so via SetSetupInProgress. + bool setup_in_progress_; + + const sync_driver::SyncPrefs* sync_prefs_; + + // A function that can be invoked repeatedly to determine whether sync can be + // started. |start_backend_| should not be invoked unless this returns true. + base::Callback<bool()> can_start_; + + // The callback we invoke when it's time to call expensive + // startup routines for the sync backend. + base::Closure start_backend_; + + // The time at which we invoked the start_backend_ callback. + base::Time start_backend_time_; + + base::TimeDelta fallback_timeout_; + + // Used to compute preferred_types from SyncPrefs as-needed. + syncer::ModelTypeSet registered_types_; + + base::WeakPtrFactory<StartupController> weak_factory_; +}; + +} // namespace browser_sync + +#endif // COMPONENTS_SYNC_DRIVER_STARTUP_CONTROLLER_H_
diff --git a/components/sync/driver/startup_controller_unittest.cc b/components/sync/driver/startup_controller_unittest.cc new file mode 100644 index 0000000..fbc0ec49 --- /dev/null +++ b/components/sync/driver/startup_controller_unittest.cc
@@ -0,0 +1,213 @@ +// 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 "components/sync/driver/startup_controller.h" + +#include <string> + +#include "base/command_line.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/time/time.h" +#include "components/sync/driver/sync_driver_switches.h" +#include "components/sync/driver/sync_prefs.h" +#include "components/syncable_prefs/testing_pref_service_syncable.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace browser_sync { + +// These are coupled to the implementation of StartupController's +// GetBackendInitializationStateString which is used by about:sync. We use it +// as a convenient way to verify internal state and that the class is +// outputting the correct values for the debug string. +static const char kStateStringStarted[] = "Started"; +static const char kStateStringDeferred[] = "Deferred"; +static const char kStateStringNotStarted[] = "Not started"; + +class StartupControllerTest : public testing::Test { + public: + StartupControllerTest() : can_start_(false), started_(false) {} + + void SetUp() override { + sync_driver::SyncPrefs::RegisterProfilePrefs(pref_service_.registry()); + sync_prefs_.reset(new sync_driver::SyncPrefs(&pref_service_)); + controller_.reset(new StartupController( + sync_prefs_.get(), + base::Bind(&StartupControllerTest::CanStart, base::Unretained(this)), + base::Bind(&StartupControllerTest::FakeStartBackend, + base::Unretained(this)))); + controller_->Reset(syncer::UserTypes()); + controller_->OverrideFallbackTimeoutForTest( + base::TimeDelta::FromSeconds(0)); + } + + bool CanStart() { return can_start_; } + + void SetCanStart(bool can_start) { can_start_ = can_start; } + + void FakeStartBackend() { + started_ = true; + sync_prefs()->SetFirstSetupComplete(); + } + + void ExpectStarted() { + EXPECT_TRUE(started()); + EXPECT_EQ(kStateStringStarted, + controller()->GetBackendInitializationStateString()); + } + + void ExpectStartDeferred() { + const bool deferred_start = + !base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kSyncDisableDeferredStartup); + EXPECT_EQ(!deferred_start, started()); + EXPECT_EQ(deferred_start ? kStateStringDeferred : kStateStringStarted, + controller()->GetBackendInitializationStateString()); + } + + void ExpectNotStarted() { + EXPECT_FALSE(started()); + EXPECT_EQ(kStateStringNotStarted, + controller()->GetBackendInitializationStateString()); + } + + bool started() const { return started_; } + void clear_started() { started_ = false; } + StartupController* controller() { return controller_.get(); } + sync_driver::SyncPrefs* sync_prefs() { return sync_prefs_.get(); } + + private: + bool can_start_; + bool started_; + base::MessageLoop message_loop_; + syncable_prefs::TestingPrefServiceSyncable pref_service_; + std::unique_ptr<sync_driver::SyncPrefs> sync_prefs_; + std::unique_ptr<StartupController> controller_; +}; + +// Test that sync doesn't start if setup is not in progress or complete. +TEST_F(StartupControllerTest, NoSetupComplete) { + controller()->TryStart(); + ExpectNotStarted(); + + SetCanStart(true); + controller()->TryStart(); + ExpectNotStarted(); +} + +// Test that sync defers if first setup is complete. +TEST_F(StartupControllerTest, DefersAfterFirstSetupComplete) { + sync_prefs()->SetFirstSetupComplete(); + SetCanStart(true); + controller()->TryStart(); + ExpectStartDeferred(); +} + +// Test that a data type triggering startup starts sync immediately. +TEST_F(StartupControllerTest, NoDeferralDataTypeTrigger) { + sync_prefs()->SetFirstSetupComplete(); + SetCanStart(true); + controller()->OnDataTypeRequestsSyncStartup(syncer::SESSIONS); + ExpectStarted(); +} + +// Test that a data type trigger interrupts the deferral timer and starts +// sync immediately. +TEST_F(StartupControllerTest, DataTypeTriggerInterruptsDeferral) { + sync_prefs()->SetFirstSetupComplete(); + SetCanStart(true); + controller()->TryStart(); + ExpectStartDeferred(); + + controller()->OnDataTypeRequestsSyncStartup(syncer::SESSIONS); + ExpectStarted(); + + // The fallback timer shouldn't result in another invocation of the closure + // we passed to the StartupController. + clear_started(); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(started()); +} + +// Test that the fallback timer starts sync in the event all +// conditions are met and no data type requests sync. +TEST_F(StartupControllerTest, FallbackTimer) { + sync_prefs()->SetFirstSetupComplete(); + SetCanStart(true); + controller()->TryStart(); + ExpectStartDeferred(); + + base::RunLoop().RunUntilIdle(); + ExpectStarted(); +} + +// Test that we start immediately if sessions is disabled. +TEST_F(StartupControllerTest, NoDeferralWithoutSessionsSync) { + syncer::ModelTypeSet types(syncer::UserTypes()); + // Disabling sessions means disabling 4 types due to groupings. + types.Remove(syncer::SESSIONS); + types.Remove(syncer::PROXY_TABS); + types.Remove(syncer::TYPED_URLS); + types.Remove(syncer::SUPERVISED_USER_SETTINGS); + sync_prefs()->SetKeepEverythingSynced(false); + sync_prefs()->SetPreferredDataTypes(syncer::UserTypes(), types); + controller()->Reset(syncer::UserTypes()); + + sync_prefs()->SetFirstSetupComplete(); + SetCanStart(true); + controller()->TryStart(); + ExpectStarted(); +} + +// Sanity check that the fallback timer doesn't fire before startup +// conditions are met. +TEST_F(StartupControllerTest, FallbackTimerWaits) { + controller()->TryStart(); + ExpectNotStarted(); + base::RunLoop().RunUntilIdle(); + ExpectNotStarted(); +} + +// Test that sync starts immediately when setup in progress is true. +TEST_F(StartupControllerTest, NoDeferralSetupInProgressTrigger) { + sync_prefs()->SetFirstSetupComplete(); + SetCanStart(true); + controller()->SetSetupInProgress(true); + ExpectStarted(); +} + +// Test that setup in progress being set to true interrupts the deferral timer +// and starts sync immediately. +TEST_F(StartupControllerTest, SetupInProgressTriggerInterruptsDeferral) { + sync_prefs()->SetFirstSetupComplete(); + SetCanStart(true); + controller()->TryStart(); + ExpectStartDeferred(); + + controller()->SetSetupInProgress(true); + ExpectStarted(); +} + +// Test that immediate startup can be forced. +TEST_F(StartupControllerTest, ForceImmediateStartup) { + SetCanStart(true); + controller()->TryStartImmediately(); + ExpectStarted(); +} + +// Test that setup-in-progress tracking is persistent across a Reset. +TEST_F(StartupControllerTest, ResetDuringSetup) { + SetCanStart(true); + + // Simulate UI telling us setup is in progress. + controller()->SetSetupInProgress(true); + + // This could happen if the UI triggers a stop-syncing permanently call. + controller()->Reset(syncer::UserTypes()); + + // From the UI's point of view, setup is still in progress. + EXPECT_TRUE(controller()->IsSetupInProgress()); +} + +} // namespace browser_sync
diff --git a/components/sync/driver/sync_api_component_factory.h b/components/sync/driver/sync_api_component_factory.h new file mode 100644 index 0000000..530fc8c --- /dev/null +++ b/components/sync/driver/sync_api_component_factory.h
@@ -0,0 +1,143 @@ +// 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 COMPONENTS_SYNC_DRIVER_SYNC_API_COMPONENT_FACTORY_H_ +#define COMPONENTS_SYNC_DRIVER_SYNC_API_COMPONENT_FACTORY_H_ + +#include <memory> +#include <string> + +#include "base/memory/weak_ptr.h" +#include "components/sync/api/syncable_service.h" +#include "components/sync/base/model_type.h" +#include "components/sync/core/attachments/attachment_service.h" +#include "components/sync/driver/data_type_controller.h" + +namespace base { +class FilePath; +} // namespace base + +namespace browser_sync { +class SyncBackendHost; +} // namespace browser_sync + +namespace history { +class HistoryBackend; +} + +namespace invalidation { +class InvalidationService; +} // namespace invalidation + +namespace syncer { +class DataTypeDebugInfoListener; +class DataTypeErrorHandler; +class SyncableService; + +struct UserShare; +} // namespace syncer + +namespace sync_driver { + +class AssociatorInterface; +class ChangeProcessor; +class DataTypeEncryptionHandler; +class DataTypeManager; +class DataTypeManagerObserver; +class DataTypeStatusTable; +class GenericChangeProcessor; +class LocalDeviceInfoProvider; +class SyncPrefs; +class SyncClient; +class SyncService; + +// This factory provides sync driver code with the model type specific sync/api +// service (like SyncableService) implementations. +class SyncApiComponentFactory { + public: + virtual ~SyncApiComponentFactory() {} + // Callback to allow platform-specific datatypes to register themselves as + // data type controllers. + // |disabled_types| and |enabled_types| control the disable/enable state of + // types that are on or off by default (respectively). + typedef base::Callback<void(sync_driver::SyncService* sync_service, + syncer::ModelTypeSet disabled_types, + syncer::ModelTypeSet enabled_types)> + RegisterDataTypesMethod; + + // The various factory methods for the data type model associators + // and change processors all return this struct. This is needed + // because the change processors typically require a type-specific + // model associator at construction time. + // + // Note: This interface is deprecated in favor of the SyncableService API. + // New datatypes that do not live on the UI thread should directly return a + // weak pointer to a syncer::SyncableService. All others continue to return + // SyncComponents. It is safe to assume that the factory methods below are + // called on the same thread in which the datatype resides. + // + // TODO(zea): Have all datatypes using the new API switch to returning + // SyncableService weak pointers instead of SyncComponents (crbug.com/100114). + struct SyncComponents { + sync_driver::AssociatorInterface* model_associator; + sync_driver::ChangeProcessor* change_processor; + SyncComponents(sync_driver::AssociatorInterface* ma, + sync_driver::ChangeProcessor* cp) + : model_associator(ma), change_processor(cp) {} + }; + + // Creates and registers enabled datatypes with the provided SyncClient. + virtual void RegisterDataTypes( + sync_driver::SyncService* sync_service, + const RegisterDataTypesMethod& register_platform_types_method) = 0; + + // Instantiates a new DataTypeManager with a SyncBackendHost, a list of data + // type controllers and a DataTypeManagerObserver. The return pointer is + // owned by the caller. + virtual sync_driver::DataTypeManager* CreateDataTypeManager( + const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& + debug_info_listener, + const sync_driver::DataTypeController::TypeMap* controllers, + const sync_driver::DataTypeEncryptionHandler* encryption_handler, + browser_sync::SyncBackendHost* backend, + sync_driver::DataTypeManagerObserver* observer) = 0; + + // Creating this in the factory helps us mock it out in testing. + virtual browser_sync::SyncBackendHost* CreateSyncBackendHost( + const std::string& name, + invalidation::InvalidationService* invalidator, + const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs, + const base::FilePath& sync_folder) = 0; + + // Creating this in the factory helps us mock it out in testing. + virtual std::unique_ptr<sync_driver::LocalDeviceInfoProvider> + CreateLocalDeviceInfoProvider() = 0; + + // Legacy datatypes that need to be converted to the SyncableService API. + virtual SyncComponents CreateBookmarkSyncComponents( + sync_driver::SyncService* sync_service, + syncer::DataTypeErrorHandler* error_handler) = 0; + + // Creates attachment service. + // Note: Should only be called from the model type thread. + // + // |store_birthday| is the store birthday. Must not be empty. + // + // |model_type| is the model type this AttachmentService will be used with. + // + // |delegate| is optional delegate for AttachmentService to notify about + // asynchronous events (AttachmentUploaded). Pass NULL if delegate is not + // provided. AttachmentService doesn't take ownership of delegate, the pointer + // must be valid throughout AttachmentService lifetime. + virtual std::unique_ptr<syncer::AttachmentService> CreateAttachmentService( + std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store, + const syncer::UserShare& user_share, + const std::string& store_birthday, + syncer::ModelType model_type, + syncer::AttachmentService::Delegate* delegate) = 0; +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_SYNC_API_COMPONENT_FACTORY_H_
diff --git a/components/sync/driver/sync_api_component_factory_mock.cc b/components/sync/driver/sync_api_component_factory_mock.cc new file mode 100644 index 0000000..f11cf13 --- /dev/null +++ b/components/sync/driver/sync_api_component_factory_mock.cc
@@ -0,0 +1,61 @@ +// 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/sync/driver/sync_api_component_factory_mock.h" + +#include <utility> + +#include "components/sync/api/attachments/attachment_store.h" +#include "components/sync/core/attachments/attachment_service_impl.h" +#include "components/sync/driver/change_processor.h" +#include "components/sync/driver/local_device_info_provider_mock.h" +#include "components/sync/driver/model_associator.h" + +using sync_driver::AssociatorInterface; +using sync_driver::ChangeProcessor; +using testing::_; +using testing::InvokeWithoutArgs; +using testing::Return; + +SyncApiComponentFactoryMock::SyncApiComponentFactoryMock() + : local_device_(new sync_driver::LocalDeviceInfoProviderMock()) {} + +SyncApiComponentFactoryMock::SyncApiComponentFactoryMock( + AssociatorInterface* model_associator, + ChangeProcessor* change_processor) + : model_associator_(model_associator), + change_processor_(change_processor), + local_device_(new sync_driver::LocalDeviceInfoProviderMock()) { + ON_CALL(*this, CreateBookmarkSyncComponents(_, _)) + .WillByDefault(InvokeWithoutArgs( + this, &SyncApiComponentFactoryMock::MakeSyncComponents)); +} + +SyncApiComponentFactoryMock::~SyncApiComponentFactoryMock() {} + +std::unique_ptr<syncer::AttachmentService> +SyncApiComponentFactoryMock::CreateAttachmentService( + std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store, + const syncer::UserShare& user_share, + const std::string& store_birthday, + syncer::ModelType model_type, + syncer::AttachmentService::Delegate* delegate) { + return syncer::AttachmentServiceImpl::CreateForTest(); +} + +sync_driver::SyncApiComponentFactory::SyncComponents +SyncApiComponentFactoryMock::MakeSyncComponents() { + return sync_driver::SyncApiComponentFactory::SyncComponents( + model_associator_.release(), change_processor_.release()); +} + +std::unique_ptr<sync_driver::LocalDeviceInfoProvider> +SyncApiComponentFactoryMock::CreateLocalDeviceInfoProvider() { + return std::move(local_device_); +} + +void SyncApiComponentFactoryMock::SetLocalDeviceInfoProvider( + std::unique_ptr<sync_driver::LocalDeviceInfoProvider> local_device) { + local_device_ = std::move(local_device); +}
diff --git a/components/sync/driver/sync_api_component_factory_mock.h b/components/sync/driver/sync_api_component_factory_mock.h new file mode 100644 index 0000000..b768e68 --- /dev/null +++ b/components/sync/driver/sync_api_component_factory_mock.h
@@ -0,0 +1,79 @@ +// 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 COMPONENTS_SYNC_DRIVER_SYNC_API_COMPONENT_FACTORY_MOCK_H__ +#define COMPONENTS_SYNC_DRIVER_SYNC_API_COMPONENT_FACTORY_MOCK_H__ + +#include <memory> + +#include "components/sync/base/model_type.h" +#include "components/sync/core/data_type_error_handler.h" +#include "components/sync/driver/data_type_controller.h" +#include "components/sync/driver/sync_api_component_factory.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace sync_driver { +class AssociatorInterface; +class ChangeProcessor; +class DataTypeEncryptionHandler; +class DataTypeStatusTable; +class SyncClient; +} + +class SyncApiComponentFactoryMock + : public sync_driver::SyncApiComponentFactory { + public: + SyncApiComponentFactoryMock(); + SyncApiComponentFactoryMock( + sync_driver::AssociatorInterface* model_associator, + sync_driver::ChangeProcessor* change_processor); + ~SyncApiComponentFactoryMock() override; + + MOCK_METHOD2(RegisterDataTypes, + void(sync_driver::SyncService* sync_service, + const RegisterDataTypesMethod&)); + MOCK_METHOD5(CreateDataTypeManager, + sync_driver::DataTypeManager*( + const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&, + const sync_driver::DataTypeController::TypeMap*, + const sync_driver::DataTypeEncryptionHandler*, + browser_sync::SyncBackendHost*, + sync_driver::DataTypeManagerObserver* observer)); + MOCK_METHOD4(CreateSyncBackendHost, + browser_sync::SyncBackendHost*( + const std::string& name, + invalidation::InvalidationService* invalidator, + const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs, + const base::FilePath& sync_folder)); + + std::unique_ptr<sync_driver::LocalDeviceInfoProvider> + CreateLocalDeviceInfoProvider() override; + void SetLocalDeviceInfoProvider( + std::unique_ptr<sync_driver::LocalDeviceInfoProvider> local_device); + + std::unique_ptr<syncer::AttachmentService> CreateAttachmentService( + std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store, + const syncer::UserShare& user_share, + const std::string& store_birthday, + syncer::ModelType model_type, + syncer::AttachmentService::Delegate* delegate) override; + MOCK_METHOD2(CreateBookmarkSyncComponents, + SyncComponents(sync_driver::SyncService* sync_service, + syncer::DataTypeErrorHandler* error_handler)); + MOCK_METHOD3(CreateTypedUrlSyncComponents, + SyncComponents(sync_driver::SyncService* sync_service, + history::HistoryBackend* history_backend, + syncer::DataTypeErrorHandler* error_handler)); + + private: + sync_driver::SyncApiComponentFactory::SyncComponents MakeSyncComponents(); + + std::unique_ptr<sync_driver::AssociatorInterface> model_associator_; + std::unique_ptr<sync_driver::ChangeProcessor> change_processor_; + // LocalDeviceInfoProvider is initially owned by this class, + // transferred to caller when CreateLocalDeviceInfoProvider is called. + std::unique_ptr<sync_driver::LocalDeviceInfoProvider> local_device_; +}; + +#endif // COMPONENTS_SYNC_DRIVER_SYNC_API_COMPONENT_FACTORY_MOCK_H__
diff --git a/components/sync/driver/sync_client.cc b/components/sync/driver/sync_client.cc new file mode 100644 index 0000000..cb83180 --- /dev/null +++ b/components/sync/driver/sync_client.cc
@@ -0,0 +1,12 @@ +// 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/sync/driver/sync_client.h" + +namespace sync_driver { + +SyncClient::SyncClient() {} +SyncClient::~SyncClient() {} + +} // namespace sync_driver
diff --git a/components/sync/driver/sync_client.h b/components/sync/driver/sync_client.h new file mode 100644 index 0000000..141b2a7 --- /dev/null +++ b/components/sync/driver/sync_client.h
@@ -0,0 +1,124 @@ +// 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_SYNC_DRIVER_SYNC_CLIENT_H_ +#define COMPONENTS_SYNC_DRIVER_SYNC_CLIENT_H_ + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "components/sync/base/extensions_activity.h" +#include "components/sync/base/model_type.h" +#include "components/sync/core/shared_model_type_processor.h" +#include "components/sync/driver/sync_api_component_factory.h" +#include "components/sync/engine/model_safe_worker.h" + +class BookmarkUndoService; +class PrefService; + +namespace autofill { +class AutocompleteSyncableService; +class PersonalDataManager; +} // namespace autofill + +namespace bookmarks { +class BookmarkModel; +} // namespace bookmarks + +namespace favicon { +class FaviconService; +} // namespace favicon + +namespace history { +class HistoryService; +} // namespace history + +namespace invalidation { +class InvalidationService; +} // namespace invalidation + +namespace syncer { +class SyncableService; +} // namespace syncer + +namespace sync_sessions { +class SyncSessionsClient; +} // namespace sync_sessions + +namespace sync_driver { + +class SyncService; + +// Interface for clients of the Sync API to plumb through necessary dependent +// components. This interface is purely for abstracting dependencies, and +// should not contain any non-trivial functional logic. +// +// Note: on some platforms, getters might return nullptr. Callers are expected +// to handle these scenarios gracefully. +class SyncClient { + public: + SyncClient(); + virtual ~SyncClient(); + + // Initializes the sync client with the specified sync service. + virtual void Initialize() = 0; + + // Returns the current SyncService instance. + virtual SyncService* GetSyncService() = 0; + + // Returns the current profile's preference service. + virtual PrefService* GetPrefService() = 0; + + // DataType specific service getters. + virtual bookmarks::BookmarkModel* GetBookmarkModel() = 0; + virtual favicon::FaviconService* GetFaviconService() = 0; + virtual history::HistoryService* GetHistoryService() = 0; + + // Returns a callback that will register the types specific to the current + // platform. + virtual sync_driver::SyncApiComponentFactory::RegisterDataTypesMethod + GetRegisterPlatformTypesCallback() = 0; + + // Returns a callback that will be invoked when password sync state has + // potentially been changed. + virtual base::Closure GetPasswordStateChangedCallback() = 0; + + virtual autofill::PersonalDataManager* GetPersonalDataManager() = 0; + virtual BookmarkUndoService* GetBookmarkUndoServiceIfExists() = 0; + virtual invalidation::InvalidationService* GetInvalidationService() = 0; + virtual scoped_refptr<syncer::ExtensionsActivity> GetExtensionsActivity() = 0; + virtual sync_sessions::SyncSessionsClient* GetSyncSessionsClient() = 0; + + // Returns a weak pointer to the syncable service specified by |type|. + // Weak pointer may be unset if service is already destroyed. + // Note: Should only be called from the model type thread. + virtual base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType( + syncer::ModelType type) = 0; + + // Returns a non-owning pointer to the service specified by |type|. Service + // lifetime is independent from sync thread therefore pointer should not be + // retained across tasks. + // Note: Should only be called from the model type thread. + // Note: should only be called by USS. + virtual syncer_v2::ModelTypeService* GetModelTypeServiceForType( + syncer::ModelType type) = 0; + + // Creates and returns a new ModelSafeWorker for the group, or null if one + // cannot be created. + // TODO(maxbogue): Move this inside SyncApiComponentFactory. + virtual scoped_refptr<syncer::ModelSafeWorker> CreateModelWorkerForGroup( + syncer::ModelSafeGroup group, + syncer::WorkerLoopDestructionObserver* observer) = 0; + + // Returns the current SyncApiComponentFactory instance. + virtual SyncApiComponentFactory* GetSyncApiComponentFactory() = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(SyncClient); +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_SYNC_CLIENT_H_
diff --git a/components/sync/driver/sync_driver_switches.cc b/components/sync/driver/sync_driver_switches.cc new file mode 100644 index 0000000..6927393 --- /dev/null +++ b/components/sync/driver/sync_driver_switches.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/sync/driver/sync_driver_switches.h" + +namespace switches { + +// Allows overriding the deferred init fallback timeout. +const char kSyncDeferredStartupTimeoutSeconds[] = + "sync-deferred-startup-timeout-seconds"; + +// Enables deferring sync backend initialization until user initiated changes +// occur. +const char kSyncDisableDeferredStartup[] = "sync-disable-deferred-startup"; + +// Enables feature to avoid unnecessary GetUpdate requests. +const char kSyncEnableGetUpdateAvoidance[] = "sync-enable-get-update-avoidance"; + +// Enables USS implementation of DeviceInfo datatype. This flag controls whether +// SyncableService based or ModelTypeService based implementation is used for +// DeviceInfo type. +const char kSyncEnableUSSDeviceInfo[] = "sync-enable-uss-device-info"; + +// Overrides the default server used for profile sync. +const char kSyncServiceURL[] = "sync-url"; + +// This flag causes sync to retry very quickly (see polling_constants.h) the +// when it encounters an error, as the first step towards exponential backoff. +const char kSyncShortInitialRetryOverride[] = + "sync-short-initial-retry-override"; + +// Enables clearing of sync data when a user enables passphrase encryption. +const base::Feature kSyncClearDataOnPassphraseEncryption{ + "ClearSyncDataOnPassphraseEncryption", base::FEATURE_DISABLED_BY_DEFAULT}; + +} // namespace switches
diff --git a/components/sync_driver/sync_driver_switches.h b/components/sync/driver/sync_driver_switches.h similarity index 100% rename from components/sync_driver/sync_driver_switches.h rename to components/sync/driver/sync_driver_switches.h
diff --git a/components/sync/driver/sync_error_controller.cc b/components/sync/driver/sync_error_controller.cc new file mode 100644 index 0000000..2badb4e --- /dev/null +++ b/components/sync/driver/sync_error_controller.cc
@@ -0,0 +1,31 @@ +// 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 "components/sync/driver/sync_error_controller.h" + +#include "components/sync/driver/sync_service.h" + +SyncErrorController::SyncErrorController(sync_driver::SyncService* service) + : service_(service) { + DCHECK(service_); +} + +SyncErrorController::~SyncErrorController() {} + +bool SyncErrorController::HasError() { + return service_->IsFirstSetupComplete() && service_->IsPassphraseRequired() && + service_->IsPassphraseRequiredForDecryption(); +} + +void SyncErrorController::AddObserver(Observer* observer) { + observer_list_.AddObserver(observer); +} + +void SyncErrorController::RemoveObserver(Observer* observer) { + observer_list_.RemoveObserver(observer); +} + +void SyncErrorController::OnStateChanged() { + FOR_EACH_OBSERVER(Observer, observer_list_, OnErrorChanged()); +}
diff --git a/components/sync/driver/sync_error_controller.h b/components/sync/driver/sync_error_controller.h new file mode 100644 index 0000000..4aceeab --- /dev/null +++ b/components/sync/driver/sync_error_controller.h
@@ -0,0 +1,47 @@ +// 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 COMPONENTS_SYNC_DRIVER_SYNC_ERROR_CONTROLLER_H_ +#define COMPONENTS_SYNC_DRIVER_SYNC_ERROR_CONTROLLER_H_ + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/observer_list.h" +#include "components/sync/driver/sync_service_observer.h" + +namespace sync_driver { +class SyncService; +} + +// Keep track of sync errors and expose them to observers in the UI. +class SyncErrorController : public sync_driver::SyncServiceObserver { + public: + // The observer class for SyncErrorController lets the controller notify + // observers when an error arises or changes. + class Observer { + public: + virtual ~Observer() {} + virtual void OnErrorChanged() = 0; + }; + + explicit SyncErrorController(sync_driver::SyncService* service); + ~SyncErrorController() override; + + // True if there exists an error worth elevating to the user. + bool HasError(); + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + // sync_driver::SyncServiceObserver: + void OnStateChanged() override; + + private: + sync_driver::SyncService* service_; + base::ObserverList<Observer, true> observer_list_; + + DISALLOW_COPY_AND_ASSIGN(SyncErrorController); +}; + +#endif // COMPONENTS_SYNC_DRIVER_SYNC_ERROR_CONTROLLER_H_
diff --git a/components/sync/driver/sync_frontend.cc b/components/sync/driver/sync_frontend.cc new file mode 100644 index 0000000..8f81f86 --- /dev/null +++ b/components/sync/driver/sync_frontend.cc
@@ -0,0 +1,13 @@ +// 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 "components/sync/driver/sync_frontend.h" + +namespace sync_driver { + +SyncFrontend::SyncFrontend() {} + +SyncFrontend::~SyncFrontend() {} + +} // namespace sync_driver
diff --git a/components/sync/driver/sync_frontend.h b/components/sync/driver/sync_frontend.h new file mode 100644 index 0000000..ae2239a --- /dev/null +++ b/components/sync/driver/sync_frontend.h
@@ -0,0 +1,147 @@ +// 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 COMPONENTS_SYNC_DRIVER_SYNC_FRONTEND_H_ +#define COMPONENTS_SYNC_DRIVER_SYNC_FRONTEND_H_ + +#include <string> + +#include "components/sync/base/model_type.h" +#include "components/sync/base/weak_handle.h" +#include "components/sync/core/sync_encryption_handler.h" +#include "components/sync/core/sync_manager.h" +#include "components/sync/protocol/sync_protocol_error.h" + +namespace syncer { +class DataTypeDebugInfoListener; +class JsBackend; +class ProtocolEvent; +struct CommitCounters; +struct StatusCounters; +struct UpdateCounters; +} // namespace syncer + +namespace sync_pb { +class EncryptedData; +} // namespace sync_pb + +namespace sync_driver { + +// SyncFrontend is the interface used by SyncBackendHost to communicate with +// the entity that created it and, presumably, is interested in sync-related +// activity. +// NOTE: All methods will be invoked by a SyncBackendHost on the same thread +// used to create that SyncBackendHost. +class SyncFrontend { + public: + SyncFrontend(); + virtual ~SyncFrontend(); + + // The backend has completed initialization and it is now ready to + // accept and process changes. If success is false, initialization + // wasn't able to be completed and should be retried. + // + // |js_backend| is what about:sync interacts with; it's different + // from the 'Backend' in 'OnBackendInitialized' (unfortunately). It + // is initialized only if |success| is true. + virtual void OnBackendInitialized( + const syncer::WeakHandle<syncer::JsBackend>& js_backend, + const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& + debug_info_listener, + const std::string& cache_guid, + bool success) = 0; + + // The backend queried the server recently and received some updates. + virtual void OnSyncCycleCompleted() = 0; + + // Informs the frontned of some network event. These notifications are + // disabled by default and must be enabled through an explicit request to the + // SyncBackendHost. + // + // It's disabld by default to avoid copying data across threads when no one + // is listening for it. + virtual void OnProtocolEvent(const syncer::ProtocolEvent& event) = 0; + + // Called when we receive an updated commit counter for a directory type. + // + // Disabled by default. Enable by calling + // EnableDirectoryTypeDebugInfoForwarding() on the backend. + virtual void OnDirectoryTypeCommitCounterUpdated( + syncer::ModelType type, + const syncer::CommitCounters& counters) = 0; + + // Called when we receive an updated update counter for a directory type. + // + // Disabled by default. Enable by calling + // EnableDirectoryTypeDebugInfoForwarding() on the backend. + virtual void OnDirectoryTypeUpdateCounterUpdated( + syncer::ModelType type, + const syncer::UpdateCounters& counters) = 0; + + // Called when we receive an updated status counter for a directory type. + // + // Disabled by default. Enable by calling + // EnableDirectoryTypeDebugInfoForwarding() on the backend. + virtual void OnDirectoryTypeStatusCounterUpdated( + syncer::ModelType type, + const syncer::StatusCounters& counters) = 0; + + // The status of the connection to the sync server has changed. + virtual void OnConnectionStatusChange(syncer::ConnectionStatus status) = 0; + + // The syncer requires a passphrase to decrypt sensitive updates. This is + // called when the first sensitive data type is setup by the user and anytime + // the passphrase is changed by another synced client. |reason| denotes why + // the passphrase was required. |pending_keys| is a copy of the + // cryptographer's pending keys to be passed on to the frontend in order to + // be cached. + virtual void OnPassphraseRequired( + syncer::PassphraseRequiredReason reason, + const sync_pb::EncryptedData& pending_keys) = 0; + + // Called when the passphrase provided by the user is + // accepted. After this is called, updates to sensitive nodes are + // encrypted using the accepted passphrase. + virtual void OnPassphraseAccepted() = 0; + + // Called when the set of encrypted types or the encrypt everything + // flag has been changed. Note that encryption isn't complete until + // the OnEncryptionComplete() notification has been sent (see + // below). + // + // |encrypted_types| will always be a superset of + // syncer::Cryptographer::SensitiveTypes(). If |encrypt_everything| is + // true, |encrypted_types| will be the set of all known types. + // + // Until this function is called, observers can assume that the set + // of encrypted types is syncer::Cryptographer::SensitiveTypes() and that + // the encrypt everything flag is false. + virtual void OnEncryptedTypesChanged(syncer::ModelTypeSet encrypted_types, + bool encrypt_everything) = 0; + + // Called after we finish encrypting the current set of encrypted + // types. + virtual void OnEncryptionComplete() = 0; + + // Called to perform migration of |types|. + virtual void OnMigrationNeededForTypes(syncer::ModelTypeSet types) = 0; + + // Inform the Frontend that new datatypes are available for registration. + virtual void OnExperimentsChanged(const syncer::Experiments& experiments) = 0; + + // Called when the sync cycle returns there is an user actionable error. + virtual void OnActionableError(const syncer::SyncProtocolError& error) = 0; + + // Called when the user of this device enables passphrase encryption. + // + // |nigori_state| contains the new (post custom passphrase) encryption keys + // and can be used to restore SyncEncryptionHandler's state across sync + // backend instances. See also SyncEncryptionHandlerImpl::RestoreNigori. + virtual void OnLocalSetPassphraseEncryption( + const syncer::SyncEncryptionHandler::NigoriState& nigori_state) = 0; +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_SYNC_FRONTEND_H_
diff --git a/components/sync/driver/sync_policy_handler.cc b/components/sync/driver/sync_policy_handler.cc new file mode 100644 index 0000000..945469f5 --- /dev/null +++ b/components/sync/driver/sync_policy_handler.cc
@@ -0,0 +1,29 @@ +// 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 "components/sync/driver/sync_policy_handler.h" + +#include "base/values.h" +#include "components/policy/core/common/policy_map.h" +#include "components/prefs/pref_value_map.h" +#include "components/sync/driver/pref_names.h" +#include "policy/policy_constants.h" + +namespace sync_driver { + +SyncPolicyHandler::SyncPolicyHandler() + : policy::TypeCheckingPolicyHandler(policy::key::kSyncDisabled, + base::Value::TYPE_BOOLEAN) {} + +SyncPolicyHandler::~SyncPolicyHandler() {} + +void SyncPolicyHandler::ApplyPolicySettings(const policy::PolicyMap& policies, + PrefValueMap* prefs) { + const base::Value* value = policies.GetValue(policy_name()); + bool disable_sync; + if (value && value->GetAsBoolean(&disable_sync) && disable_sync) + prefs->SetValue(sync_driver::prefs::kSyncManaged, value->CreateDeepCopy()); +} + +} // namespace sync_driver
diff --git a/components/sync_driver/sync_policy_handler.h b/components/sync/driver/sync_policy_handler.h similarity index 100% rename from components/sync_driver/sync_policy_handler.h rename to components/sync/driver/sync_policy_handler.h
diff --git a/components/sync/driver/sync_policy_handler_unittest.cc b/components/sync/driver/sync_policy_handler_unittest.cc new file mode 100644 index 0000000..a6a58094 --- /dev/null +++ b/components/sync/driver/sync_policy_handler_unittest.cc
@@ -0,0 +1,61 @@ +// 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 "components/sync/driver/sync_policy_handler.h" + +#include "base/memory/ptr_util.h" +#include "base/values.h" +#include "components/policy/core/common/policy_map.h" +#include "components/policy/core/common/policy_types.h" +#include "components/prefs/pref_value_map.h" +#include "components/sync/driver/pref_names.h" +#include "policy/policy_constants.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace sync_driver { + +// Test cases for the Sync policy setting. +class SyncPolicyHandlerTest : public testing::Test {}; + +TEST_F(SyncPolicyHandlerTest, Default) { + policy::PolicyMap policy; + SyncPolicyHandler handler; + PrefValueMap prefs; + handler.ApplyPolicySettings(policy, &prefs); + EXPECT_FALSE(prefs.GetValue(sync_driver::prefs::kSyncManaged, NULL)); +} + +TEST_F(SyncPolicyHandlerTest, Enabled) { + policy::PolicyMap policy; + policy.Set(policy::key::kSyncDisabled, policy::POLICY_LEVEL_MANDATORY, + policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD, + base::WrapUnique(new base::FundamentalValue(false)), nullptr); + SyncPolicyHandler handler; + PrefValueMap prefs; + handler.ApplyPolicySettings(policy, &prefs); + + // Enabling Sync should not set the pref. + EXPECT_FALSE(prefs.GetValue(sync_driver::prefs::kSyncManaged, NULL)); +} + +TEST_F(SyncPolicyHandlerTest, Disabled) { + policy::PolicyMap policy; + policy.Set(policy::key::kSyncDisabled, policy::POLICY_LEVEL_MANDATORY, + policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD, + base::WrapUnique(new base::FundamentalValue(true)), nullptr); + SyncPolicyHandler handler; + PrefValueMap prefs; + handler.ApplyPolicySettings(policy, &prefs); + + // Sync should be flagged as managed. + const base::Value* value = NULL; + EXPECT_TRUE(prefs.GetValue(sync_driver::prefs::kSyncManaged, &value)); + ASSERT_TRUE(value); + bool sync_managed = false; + bool result = value->GetAsBoolean(&sync_managed); + ASSERT_TRUE(result); + EXPECT_TRUE(sync_managed); +} + +} // namespace sync_driver
diff --git a/components/sync/driver/sync_prefs.cc b/components/sync/driver/sync_prefs.cc new file mode 100644 index 0000000..4f1eed6 --- /dev/null +++ b/components/sync/driver/sync_prefs.cc
@@ -0,0 +1,555 @@ +// 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/sync/driver/sync_prefs.h" + +#include "base/base64.h" +#include "base/logging.h" +#include "base/strings/string_number_conversions.h" +#include "base/values.h" +#include "build/build_config.h" +#include "components/pref_registry/pref_registry_syncable.h" +#include "components/prefs/pref_member.h" +#include "components/prefs/pref_service.h" +#include "components/sync/driver/pref_names.h" + +namespace sync_driver { + +SyncPrefObserver::~SyncPrefObserver() {} + +SyncPrefs::SyncPrefs(PrefService* pref_service) : pref_service_(pref_service) { + DCHECK(pref_service); + RegisterPrefGroups(); + // Watch the preference that indicates sync is managed so we can take + // appropriate action. + pref_sync_managed_.Init( + prefs::kSyncManaged, pref_service_, + base::Bind(&SyncPrefs::OnSyncManagedPrefChanged, base::Unretained(this))); +} + +SyncPrefs::SyncPrefs() : pref_service_(NULL) {} + +SyncPrefs::~SyncPrefs() { + DCHECK(CalledOnValidThread()); +} + +// static +void SyncPrefs::RegisterProfilePrefs( + user_prefs::PrefRegistrySyncable* registry) { + registry->RegisterBooleanPref(prefs::kSyncFirstSetupComplete, false); + registry->RegisterBooleanPref(prefs::kSyncSuppressStart, false); + registry->RegisterInt64Pref(prefs::kSyncLastSyncedTime, 0); + registry->RegisterInt64Pref(prefs::kSyncLastPollTime, 0); + registry->RegisterInt64Pref(prefs::kSyncFirstSyncTime, 0); + + // All datatypes are on by default, but this gets set explicitly + // when you configure sync (when turning it on), in + // ProfileSyncService::OnUserChoseDatatypes. + registry->RegisterBooleanPref(prefs::kSyncKeepEverythingSynced, true); + + syncer::ModelTypeSet user_types = syncer::UserTypes(); + + // Include proxy types as well, as they can be individually selected, + // although they don't have sync representations. + user_types.PutAll(syncer::ProxyTypes()); + + // Treat bookmarks and device info specially. + RegisterDataTypePreferredPref(registry, syncer::BOOKMARKS, true); + RegisterDataTypePreferredPref(registry, syncer::DEVICE_INFO, true); + user_types.Remove(syncer::BOOKMARKS); + user_types.Remove(syncer::DEVICE_INFO); + + // All types are set to off by default, which forces a configuration to + // explicitly enable them. GetPreferredTypes() will ensure that any new + // implicit types are enabled when their pref group is, or via + // KeepEverythingSynced. + for (syncer::ModelTypeSet::Iterator it = user_types.First(); it.Good(); + it.Inc()) { + RegisterDataTypePreferredPref(registry, it.Get(), false); + } + + registry->RegisterBooleanPref(prefs::kSyncManaged, false); + registry->RegisterStringPref(prefs::kSyncEncryptionBootstrapToken, + std::string()); + registry->RegisterStringPref(prefs::kSyncKeystoreEncryptionBootstrapToken, + std::string()); +#if defined(OS_CHROMEOS) + registry->RegisterStringPref(prefs::kSyncSpareBootstrapToken, ""); +#endif + + registry->RegisterBooleanPref(prefs::kSyncHasAuthError, false); + registry->RegisterStringPref(prefs::kSyncSessionsGUID, std::string()); + registry->RegisterBooleanPref(prefs::kSyncPassphrasePrompted, false); + registry->RegisterIntegerPref(prefs::kSyncMemoryPressureWarningCount, -1); + registry->RegisterBooleanPref(prefs::kSyncShutdownCleanly, false); + registry->RegisterDictionaryPref(prefs::kSyncInvalidationVersions); + registry->RegisterStringPref(prefs::kSyncLastRunVersion, std::string()); + registry->RegisterBooleanPref( + prefs::kSyncPassphraseEncryptionTransitionInProgress, false); + registry->RegisterStringPref(prefs::kSyncNigoriStateForPassphraseTransition, + std::string()); +} + +void SyncPrefs::AddSyncPrefObserver(SyncPrefObserver* sync_pref_observer) { + DCHECK(CalledOnValidThread()); + sync_pref_observers_.AddObserver(sync_pref_observer); +} + +void SyncPrefs::RemoveSyncPrefObserver(SyncPrefObserver* sync_pref_observer) { + DCHECK(CalledOnValidThread()); + sync_pref_observers_.RemoveObserver(sync_pref_observer); +} + +void SyncPrefs::ClearPreferences() { + DCHECK(CalledOnValidThread()); + pref_service_->ClearPref(prefs::kSyncLastSyncedTime); + pref_service_->ClearPref(prefs::kSyncLastPollTime); + pref_service_->ClearPref(prefs::kSyncFirstSetupComplete); + pref_service_->ClearPref(prefs::kSyncEncryptionBootstrapToken); + pref_service_->ClearPref(prefs::kSyncKeystoreEncryptionBootstrapToken); + pref_service_->ClearPref(prefs::kSyncPassphrasePrompted); + pref_service_->ClearPref(prefs::kSyncMemoryPressureWarningCount); + pref_service_->ClearPref(prefs::kSyncShutdownCleanly); + pref_service_->ClearPref(prefs::kSyncInvalidationVersions); + pref_service_->ClearPref(prefs::kSyncLastRunVersion); + pref_service_->ClearPref( + prefs::kSyncPassphraseEncryptionTransitionInProgress); + pref_service_->ClearPref(prefs::kSyncNigoriStateForPassphraseTransition); + + // TODO(nick): The current behavior does not clear + // e.g. prefs::kSyncBookmarks. Is that really what we want? +} + +bool SyncPrefs::IsFirstSetupComplete() const { + DCHECK(CalledOnValidThread()); + return pref_service_->GetBoolean(prefs::kSyncFirstSetupComplete); +} + +void SyncPrefs::SetFirstSetupComplete() { + DCHECK(CalledOnValidThread()); + pref_service_->SetBoolean(prefs::kSyncFirstSetupComplete, true); +} + +bool SyncPrefs::SyncHasAuthError() const { + DCHECK(CalledOnValidThread()); + return pref_service_->GetBoolean(prefs::kSyncHasAuthError); +} + +void SyncPrefs::SetSyncAuthError(bool error) { + DCHECK(CalledOnValidThread()); + pref_service_->SetBoolean(prefs::kSyncHasAuthError, error); +} + +bool SyncPrefs::IsSyncRequested() const { + DCHECK(CalledOnValidThread()); + // IsSyncRequested is the inverse of the old SuppressStart pref. + // Since renaming a pref value is hard, here we still use the old one. + return !pref_service_->GetBoolean(prefs::kSyncSuppressStart); +} + +void SyncPrefs::SetSyncRequested(bool is_requested) { + DCHECK(CalledOnValidThread()); + // See IsSyncRequested for why we use this pref and !is_requested. + pref_service_->SetBoolean(prefs::kSyncSuppressStart, !is_requested); +} + +base::Time SyncPrefs::GetLastSyncedTime() const { + DCHECK(CalledOnValidThread()); + return base::Time::FromInternalValue( + pref_service_->GetInt64(prefs::kSyncLastSyncedTime)); +} + +void SyncPrefs::SetLastSyncedTime(base::Time time) { + DCHECK(CalledOnValidThread()); + pref_service_->SetInt64(prefs::kSyncLastSyncedTime, time.ToInternalValue()); +} + +base::Time SyncPrefs::GetLastPollTime() const { + DCHECK(CalledOnValidThread()); + return base::Time::FromInternalValue( + pref_service_->GetInt64(prefs::kSyncLastSyncedTime)); +} + +void SyncPrefs::SetLastPollTime(base::Time time) { + DCHECK(CalledOnValidThread()); + pref_service_->SetInt64(prefs::kSyncLastPollTime, time.ToInternalValue()); +} + +bool SyncPrefs::HasKeepEverythingSynced() const { + DCHECK(CalledOnValidThread()); + return pref_service_->GetBoolean(prefs::kSyncKeepEverythingSynced); +} + +void SyncPrefs::SetKeepEverythingSynced(bool keep_everything_synced) { + DCHECK(CalledOnValidThread()); + pref_service_->SetBoolean(prefs::kSyncKeepEverythingSynced, + keep_everything_synced); +} + +syncer::ModelTypeSet SyncPrefs::GetPreferredDataTypes( + syncer::ModelTypeSet registered_types) const { + DCHECK(CalledOnValidThread()); + + if (pref_service_->GetBoolean(prefs::kSyncKeepEverythingSynced)) { + return registered_types; + } + + syncer::ModelTypeSet preferred_types; + for (syncer::ModelTypeSet::Iterator it = registered_types.First(); it.Good(); + it.Inc()) { + if (GetDataTypePreferred(it.Get())) { + preferred_types.Put(it.Get()); + } + } + return ResolvePrefGroups(registered_types, preferred_types); +} + +void SyncPrefs::SetPreferredDataTypes(syncer::ModelTypeSet registered_types, + syncer::ModelTypeSet preferred_types) { + DCHECK(CalledOnValidThread()); + preferred_types = ResolvePrefGroups(registered_types, preferred_types); + DCHECK(registered_types.HasAll(preferred_types)); + for (syncer::ModelTypeSet::Iterator i = registered_types.First(); i.Good(); + i.Inc()) { + SetDataTypePreferred(i.Get(), preferred_types.Has(i.Get())); + } +} + +bool SyncPrefs::IsManaged() const { + DCHECK(CalledOnValidThread()); + return pref_service_->GetBoolean(prefs::kSyncManaged); +} + +std::string SyncPrefs::GetEncryptionBootstrapToken() const { + DCHECK(CalledOnValidThread()); + return pref_service_->GetString(prefs::kSyncEncryptionBootstrapToken); +} + +void SyncPrefs::SetEncryptionBootstrapToken(const std::string& token) { + DCHECK(CalledOnValidThread()); + pref_service_->SetString(prefs::kSyncEncryptionBootstrapToken, token); +} + +std::string SyncPrefs::GetKeystoreEncryptionBootstrapToken() const { + DCHECK(CalledOnValidThread()); + return pref_service_->GetString(prefs::kSyncKeystoreEncryptionBootstrapToken); +} + +void SyncPrefs::SetKeystoreEncryptionBootstrapToken(const std::string& token) { + DCHECK(CalledOnValidThread()); + pref_service_->SetString(prefs::kSyncKeystoreEncryptionBootstrapToken, token); +} + +std::string SyncPrefs::GetSyncSessionsGUID() const { + DCHECK(CalledOnValidThread()); + return pref_service_->GetString(prefs::kSyncSessionsGUID); +} + +void SyncPrefs::SetSyncSessionsGUID(const std::string& guid) { + DCHECK(CalledOnValidThread()); + pref_service_->SetString(prefs::kSyncSessionsGUID, guid); +} + +// static +const char* SyncPrefs::GetPrefNameForDataType(syncer::ModelType data_type) { + switch (data_type) { + case syncer::BOOKMARKS: + return prefs::kSyncBookmarks; + case syncer::PASSWORDS: + return prefs::kSyncPasswords; + case syncer::PREFERENCES: + return prefs::kSyncPreferences; + case syncer::AUTOFILL: + return prefs::kSyncAutofill; + case syncer::AUTOFILL_PROFILE: + return prefs::kSyncAutofillProfile; + case syncer::AUTOFILL_WALLET_DATA: + return prefs::kSyncAutofillWallet; + case syncer::AUTOFILL_WALLET_METADATA: + return prefs::kSyncAutofillWalletMetadata; + case syncer::THEMES: + return prefs::kSyncThemes; + case syncer::TYPED_URLS: + return prefs::kSyncTypedUrls; + case syncer::EXTENSION_SETTINGS: + return prefs::kSyncExtensionSettings; + case syncer::EXTENSIONS: + return prefs::kSyncExtensions; + case syncer::APP_LIST: + return prefs::kSyncAppList; + case syncer::APP_SETTINGS: + return prefs::kSyncAppSettings; + case syncer::APPS: + return prefs::kSyncApps; + case syncer::SEARCH_ENGINES: + return prefs::kSyncSearchEngines; + case syncer::SESSIONS: + return prefs::kSyncSessions; + case syncer::APP_NOTIFICATIONS: + return prefs::kSyncAppNotifications; + case syncer::HISTORY_DELETE_DIRECTIVES: + return prefs::kSyncHistoryDeleteDirectives; + case syncer::SYNCED_NOTIFICATIONS: + return prefs::kSyncSyncedNotifications; + case syncer::SYNCED_NOTIFICATION_APP_INFO: + return prefs::kSyncSyncedNotificationAppInfo; + case syncer::DICTIONARY: + return prefs::kSyncDictionary; + case syncer::FAVICON_IMAGES: + return prefs::kSyncFaviconImages; + case syncer::FAVICON_TRACKING: + return prefs::kSyncFaviconTracking; + case syncer::SUPERVISED_USER_SETTINGS: + return prefs::kSyncSupervisedUserSettings; + case syncer::PROXY_TABS: + return prefs::kSyncTabs; + case syncer::PRIORITY_PREFERENCES: + return prefs::kSyncPriorityPreferences; + case syncer::SUPERVISED_USERS: + return prefs::kSyncSupervisedUsers; + case syncer::ARTICLES: + return prefs::kSyncArticles; + case syncer::SUPERVISED_USER_SHARED_SETTINGS: + return prefs::kSyncSupervisedUserSharedSettings; + case syncer::SUPERVISED_USER_WHITELISTS: + return prefs::kSyncSupervisedUserWhitelists; + case syncer::DEVICE_INFO: + return prefs::kSyncDeviceInfo; + case syncer::WIFI_CREDENTIALS: + return prefs::kSyncWifiCredentials; + case syncer::ARC_PACKAGE: + return prefs::kSyncArcPackage; + default: + break; + } + NOTREACHED() << "Type is " << data_type; + return NULL; +} + +#if defined(OS_CHROMEOS) +std::string SyncPrefs::GetSpareBootstrapToken() const { + DCHECK(CalledOnValidThread()); + return pref_service_->GetString(prefs::kSyncSpareBootstrapToken); +} + +void SyncPrefs::SetSpareBootstrapToken(const std::string& token) { + DCHECK(CalledOnValidThread()); + pref_service_->SetString(prefs::kSyncSpareBootstrapToken, token); +} +#endif + +void SyncPrefs::OnSyncManagedPrefChanged() { + DCHECK(CalledOnValidThread()); + FOR_EACH_OBSERVER(SyncPrefObserver, sync_pref_observers_, + OnSyncManagedPrefChange(*pref_sync_managed_)); +} + +void SyncPrefs::SetManagedForTest(bool is_managed) { + DCHECK(CalledOnValidThread()); + pref_service_->SetBoolean(prefs::kSyncManaged, is_managed); +} + +void SyncPrefs::RegisterPrefGroups() { + pref_groups_[syncer::APPS].Put(syncer::APP_NOTIFICATIONS); + pref_groups_[syncer::APPS].Put(syncer::APP_SETTINGS); + pref_groups_[syncer::APPS].Put(syncer::APP_LIST); + + pref_groups_[syncer::AUTOFILL].Put(syncer::AUTOFILL_PROFILE); + pref_groups_[syncer::AUTOFILL].Put(syncer::AUTOFILL_WALLET_DATA); + pref_groups_[syncer::AUTOFILL].Put(syncer::AUTOFILL_WALLET_METADATA); + + pref_groups_[syncer::EXTENSIONS].Put(syncer::EXTENSION_SETTINGS); + + pref_groups_[syncer::PREFERENCES].Put(syncer::DICTIONARY); + pref_groups_[syncer::PREFERENCES].Put(syncer::PRIORITY_PREFERENCES); + pref_groups_[syncer::PREFERENCES].Put(syncer::SEARCH_ENGINES); + + pref_groups_[syncer::TYPED_URLS].Put(syncer::HISTORY_DELETE_DIRECTIVES); + pref_groups_[syncer::TYPED_URLS].Put(syncer::SESSIONS); + pref_groups_[syncer::TYPED_URLS].Put(syncer::FAVICON_IMAGES); + pref_groups_[syncer::TYPED_URLS].Put(syncer::FAVICON_TRACKING); + + pref_groups_[syncer::PROXY_TABS].Put(syncer::SESSIONS); + pref_groups_[syncer::PROXY_TABS].Put(syncer::FAVICON_IMAGES); + pref_groups_[syncer::PROXY_TABS].Put(syncer::FAVICON_TRACKING); + + // TODO(zea): put favicons in the bookmarks group as well once it handles + // those favicons. +} + +// static +void SyncPrefs::RegisterDataTypePreferredPref( + user_prefs::PrefRegistrySyncable* registry, + syncer::ModelType type, + bool is_preferred) { + const char* pref_name = GetPrefNameForDataType(type); + if (!pref_name) { + NOTREACHED(); + return; + } + registry->RegisterBooleanPref(pref_name, is_preferred); +} + +bool SyncPrefs::GetDataTypePreferred(syncer::ModelType type) const { + DCHECK(CalledOnValidThread()); + const char* pref_name = GetPrefNameForDataType(type); + if (!pref_name) { + NOTREACHED(); + return false; + } + + // Device info is always enabled. + if (pref_name == prefs::kSyncDeviceInfo) + return true; + + if (type == syncer::PROXY_TABS && + pref_service_->GetUserPrefValue(pref_name) == NULL && + pref_service_->IsUserModifiablePreference(pref_name)) { + // If there is no tab sync preference yet (i.e. newly enabled type), + // default to the session sync preference value. + pref_name = GetPrefNameForDataType(syncer::SESSIONS); + } + + return pref_service_->GetBoolean(pref_name); +} + +void SyncPrefs::SetDataTypePreferred(syncer::ModelType type, + bool is_preferred) { + DCHECK(CalledOnValidThread()); + const char* pref_name = GetPrefNameForDataType(type); + if (!pref_name) { + NOTREACHED(); + return; + } + + // Device info is always preferred. + if (type == syncer::DEVICE_INFO) + return; + + pref_service_->SetBoolean(pref_name, is_preferred); +} + +syncer::ModelTypeSet SyncPrefs::ResolvePrefGroups( + syncer::ModelTypeSet registered_types, + syncer::ModelTypeSet types) const { + syncer::ModelTypeSet types_with_groups = types; + for (PrefGroupsMap::const_iterator i = pref_groups_.begin(); + i != pref_groups_.end(); ++i) { + if (types.Has(i->first)) + types_with_groups.PutAll(i->second); + } + types_with_groups.RetainAll(registered_types); + return types_with_groups; +} + +base::Time SyncPrefs::GetFirstSyncTime() const { + return base::Time::FromInternalValue( + pref_service_->GetInt64(prefs::kSyncFirstSyncTime)); +} + +void SyncPrefs::SetFirstSyncTime(base::Time time) { + pref_service_->SetInt64(prefs::kSyncFirstSyncTime, time.ToInternalValue()); +} + +void SyncPrefs::ClearFirstSyncTime() { + pref_service_->ClearPref(prefs::kSyncFirstSyncTime); +} + +bool SyncPrefs::IsPassphrasePrompted() const { + return pref_service_->GetBoolean(prefs::kSyncPassphrasePrompted); +} + +void SyncPrefs::SetPassphrasePrompted(bool value) { + pref_service_->SetBoolean(prefs::kSyncPassphrasePrompted, value); +} + +int SyncPrefs::GetMemoryPressureWarningCount() const { + return pref_service_->GetInteger(prefs::kSyncMemoryPressureWarningCount); +} + +void SyncPrefs::SetMemoryPressureWarningCount(int value) { + pref_service_->SetInteger(prefs::kSyncMemoryPressureWarningCount, value); +} + +bool SyncPrefs::DidSyncShutdownCleanly() const { + return pref_service_->GetBoolean(prefs::kSyncShutdownCleanly); +} + +void SyncPrefs::SetCleanShutdown(bool value) { + pref_service_->SetBoolean(prefs::kSyncShutdownCleanly, value); +} + +void SyncPrefs::GetInvalidationVersions( + std::map<syncer::ModelType, int64_t>* invalidation_versions) const { + const base::DictionaryValue* invalidation_dictionary = + pref_service_->GetDictionary(prefs::kSyncInvalidationVersions); + syncer::ModelTypeSet protocol_types = syncer::ProtocolTypes(); + for (auto iter = protocol_types.First(); iter.Good(); iter.Inc()) { + std::string key = syncer::ModelTypeToString(iter.Get()); + std::string version_str; + if (!invalidation_dictionary->GetString(key, &version_str)) + continue; + int64_t version = 0; + if (!base::StringToInt64(version_str, &version)) + continue; + (*invalidation_versions)[iter.Get()] = version; + } +} + +void SyncPrefs::UpdateInvalidationVersions( + const std::map<syncer::ModelType, int64_t>& invalidation_versions) { + std::unique_ptr<base::DictionaryValue> invalidation_dictionary( + new base::DictionaryValue()); + for (const auto& map_iter : invalidation_versions) { + std::string version_str = base::Int64ToString(map_iter.second); + invalidation_dictionary->SetString( + syncer::ModelTypeToString(map_iter.first), version_str); + } + pref_service_->Set(prefs::kSyncInvalidationVersions, + *invalidation_dictionary); +} + +std::string SyncPrefs::GetLastRunVersion() const { + return pref_service_->GetString(prefs::kSyncLastRunVersion); +} + +void SyncPrefs::SetLastRunVersion(const std::string& current_version) { + pref_service_->SetString(prefs::kSyncLastRunVersion, current_version); +} + +void SyncPrefs::SetPassphraseEncryptionTransitionInProgress(bool value) { + pref_service_->SetBoolean( + prefs::kSyncPassphraseEncryptionTransitionInProgress, value); +} + +bool SyncPrefs::GetPassphraseEncryptionTransitionInProgress() const { + return pref_service_->GetBoolean( + prefs::kSyncPassphraseEncryptionTransitionInProgress); +} + +void SyncPrefs::SetSavedNigoriStateForPassphraseEncryptionTransition( + const syncer::SyncEncryptionHandler::NigoriState& nigori_state) { + std::string encoded; + base::Base64Encode(nigori_state.nigori_specifics.SerializeAsString(), + &encoded); + pref_service_->SetString(prefs::kSyncNigoriStateForPassphraseTransition, + encoded); +} + +std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> +SyncPrefs::GetSavedNigoriStateForPassphraseEncryptionTransition() const { + const std::string encoded = + pref_service_->GetString(prefs::kSyncNigoriStateForPassphraseTransition); + std::string decoded; + if (!base::Base64Decode(encoded, &decoded)) + return std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState>(); + + std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> result( + new syncer::SyncEncryptionHandler::NigoriState()); + if (!result->nigori_specifics.ParseFromString(decoded)) + return std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState>(); + return result; +} + +} // namespace sync_driver
diff --git a/components/sync_driver/sync_prefs.h b/components/sync/driver/sync_prefs.h similarity index 100% rename from components/sync_driver/sync_prefs.h rename to components/sync/driver/sync_prefs.h
diff --git a/components/sync/driver/sync_prefs_unittest.cc b/components/sync/driver/sync_prefs_unittest.cc new file mode 100644 index 0000000..16c9899 --- /dev/null +++ b/components/sync/driver/sync_prefs_unittest.cc
@@ -0,0 +1,262 @@ +// 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/sync/driver/sync_prefs.h" + +#include <stdint.h> + +#include <map> + +#include "base/command_line.h" +#include "base/message_loop/message_loop.h" +#include "base/time/time.h" +#include "components/pref_registry/testing_pref_service_syncable.h" +#include "components/prefs/pref_notifier_impl.h" +#include "components/prefs/pref_value_store.h" +#include "components/prefs/testing_pref_service.h" +#include "components/sync/base/model_type.h" +#include "components/sync/driver/pref_names.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace sync_driver { + +namespace { + +using ::testing::InSequence; +using ::testing::StrictMock; + +class SyncPrefsTest : public testing::Test { + protected: + void SetUp() override { + SyncPrefs::RegisterProfilePrefs(pref_service_.registry()); + } + + user_prefs::TestingPrefServiceSyncable pref_service_; + + private: + base::MessageLoop loop_; +}; + +TEST_F(SyncPrefsTest, Basic) { + SyncPrefs sync_prefs(&pref_service_); + + EXPECT_FALSE(sync_prefs.IsFirstSetupComplete()); + sync_prefs.SetFirstSetupComplete(); + EXPECT_TRUE(sync_prefs.IsFirstSetupComplete()); + + EXPECT_TRUE(sync_prefs.IsSyncRequested()); + sync_prefs.SetSyncRequested(false); + EXPECT_FALSE(sync_prefs.IsSyncRequested()); + sync_prefs.SetSyncRequested(true); + EXPECT_TRUE(sync_prefs.IsSyncRequested()); + + EXPECT_EQ(base::Time(), sync_prefs.GetLastSyncedTime()); + const base::Time& now = base::Time::Now(); + sync_prefs.SetLastSyncedTime(now); + EXPECT_EQ(now, sync_prefs.GetLastSyncedTime()); + + EXPECT_TRUE(sync_prefs.HasKeepEverythingSynced()); + sync_prefs.SetKeepEverythingSynced(false); + EXPECT_FALSE(sync_prefs.HasKeepEverythingSynced()); + sync_prefs.SetKeepEverythingSynced(true); + EXPECT_TRUE(sync_prefs.HasKeepEverythingSynced()); + + EXPECT_TRUE(sync_prefs.GetEncryptionBootstrapToken().empty()); + sync_prefs.SetEncryptionBootstrapToken("token"); + EXPECT_EQ("token", sync_prefs.GetEncryptionBootstrapToken()); +} + +TEST_F(SyncPrefsTest, DefaultTypes) { + SyncPrefs sync_prefs(&pref_service_); + sync_prefs.SetKeepEverythingSynced(false); + + // Only bookmarks and device info are enabled by default. + syncer::ModelTypeSet expected(syncer::BOOKMARKS, syncer::DEVICE_INFO); + syncer::ModelTypeSet preferred_types = + sync_prefs.GetPreferredDataTypes(syncer::UserTypes()); + EXPECT_EQ(expected, preferred_types); + + // Simulate an upgrade to delete directives + proxy tabs support. None of the + // new types or their pref group types should be registering, ensuring they + // don't have pref values. + syncer::ModelTypeSet registered_types = syncer::UserTypes(); + registered_types.Remove(syncer::PROXY_TABS); + registered_types.Remove(syncer::TYPED_URLS); + registered_types.Remove(syncer::SESSIONS); + registered_types.Remove(syncer::HISTORY_DELETE_DIRECTIVES); + + // Enable all other types. + sync_prefs.SetPreferredDataTypes(registered_types, registered_types); + + // Manually enable typed urls (to simulate the old world). + pref_service_.SetBoolean(prefs::kSyncTypedUrls, true); + + // Proxy tabs should not be enabled (since sessions wasn't), but history + // delete directives should (since typed urls was). + preferred_types = sync_prefs.GetPreferredDataTypes(syncer::UserTypes()); + EXPECT_FALSE(preferred_types.Has(syncer::PROXY_TABS)); + EXPECT_TRUE(preferred_types.Has(syncer::HISTORY_DELETE_DIRECTIVES)); + + // Now manually enable sessions, which should result in proxy tabs also being + // enabled. Also, manually disable typed urls, which should mean that history + // delete directives are not enabled. + pref_service_.SetBoolean(prefs::kSyncTypedUrls, false); + pref_service_.SetBoolean(prefs::kSyncSessions, true); + preferred_types = sync_prefs.GetPreferredDataTypes(syncer::UserTypes()); + EXPECT_TRUE(preferred_types.Has(syncer::PROXY_TABS)); + EXPECT_FALSE(preferred_types.Has(syncer::HISTORY_DELETE_DIRECTIVES)); +} + +TEST_F(SyncPrefsTest, PreferredTypesKeepEverythingSynced) { + SyncPrefs sync_prefs(&pref_service_); + + EXPECT_TRUE(sync_prefs.HasKeepEverythingSynced()); + + const syncer::ModelTypeSet user_types = syncer::UserTypes(); + EXPECT_EQ(user_types, sync_prefs.GetPreferredDataTypes(user_types)); + const syncer::ModelTypeSet user_visible_types = syncer::UserSelectableTypes(); + for (syncer::ModelTypeSet::Iterator it = user_visible_types.First(); + it.Good(); it.Inc()) { + syncer::ModelTypeSet preferred_types; + preferred_types.Put(it.Get()); + sync_prefs.SetPreferredDataTypes(user_types, preferred_types); + EXPECT_EQ(user_types, sync_prefs.GetPreferredDataTypes(user_types)); + } +} + +TEST_F(SyncPrefsTest, PreferredTypesNotKeepEverythingSynced) { + SyncPrefs sync_prefs(&pref_service_); + + sync_prefs.SetKeepEverythingSynced(false); + + const syncer::ModelTypeSet user_types = syncer::UserTypes(); + EXPECT_NE(user_types, sync_prefs.GetPreferredDataTypes(user_types)); + const syncer::ModelTypeSet user_visible_types = syncer::UserSelectableTypes(); + for (syncer::ModelTypeSet::Iterator it = user_visible_types.First(); + it.Good(); it.Inc()) { + syncer::ModelTypeSet preferred_types; + preferred_types.Put(it.Get()); + syncer::ModelTypeSet expected_preferred_types(preferred_types); + if (it.Get() == syncer::AUTOFILL) { + expected_preferred_types.Put(syncer::AUTOFILL_PROFILE); + expected_preferred_types.Put(syncer::AUTOFILL_WALLET_DATA); + expected_preferred_types.Put(syncer::AUTOFILL_WALLET_METADATA); + } + if (it.Get() == syncer::PREFERENCES) { + expected_preferred_types.Put(syncer::DICTIONARY); + expected_preferred_types.Put(syncer::PRIORITY_PREFERENCES); + expected_preferred_types.Put(syncer::SEARCH_ENGINES); + } + if (it.Get() == syncer::APPS) { + expected_preferred_types.Put(syncer::APP_LIST); + expected_preferred_types.Put(syncer::APP_NOTIFICATIONS); + expected_preferred_types.Put(syncer::APP_SETTINGS); + } + if (it.Get() == syncer::EXTENSIONS) { + expected_preferred_types.Put(syncer::EXTENSION_SETTINGS); + } + if (it.Get() == syncer::TYPED_URLS) { + expected_preferred_types.Put(syncer::HISTORY_DELETE_DIRECTIVES); + expected_preferred_types.Put(syncer::SESSIONS); + expected_preferred_types.Put(syncer::FAVICON_IMAGES); + expected_preferred_types.Put(syncer::FAVICON_TRACKING); + } + if (it.Get() == syncer::PROXY_TABS) { + expected_preferred_types.Put(syncer::SESSIONS); + expected_preferred_types.Put(syncer::FAVICON_IMAGES); + expected_preferred_types.Put(syncer::FAVICON_TRACKING); + } + + // Device info is always preferred. + expected_preferred_types.Put(syncer::DEVICE_INFO); + + sync_prefs.SetPreferredDataTypes(user_types, preferred_types); + EXPECT_EQ(expected_preferred_types, + sync_prefs.GetPreferredDataTypes(user_types)); + } +} + +class MockSyncPrefObserver : public SyncPrefObserver { + public: + MOCK_METHOD1(OnSyncManagedPrefChange, void(bool)); +}; + +TEST_F(SyncPrefsTest, ObservedPrefs) { + SyncPrefs sync_prefs(&pref_service_); + + StrictMock<MockSyncPrefObserver> mock_sync_pref_observer; + InSequence dummy; + EXPECT_CALL(mock_sync_pref_observer, OnSyncManagedPrefChange(true)); + EXPECT_CALL(mock_sync_pref_observer, OnSyncManagedPrefChange(false)); + + EXPECT_FALSE(sync_prefs.IsManaged()); + + sync_prefs.AddSyncPrefObserver(&mock_sync_pref_observer); + + sync_prefs.SetManagedForTest(true); + EXPECT_TRUE(sync_prefs.IsManaged()); + sync_prefs.SetManagedForTest(false); + EXPECT_FALSE(sync_prefs.IsManaged()); + + sync_prefs.RemoveSyncPrefObserver(&mock_sync_pref_observer); +} + +TEST_F(SyncPrefsTest, ClearPreferences) { + SyncPrefs sync_prefs(&pref_service_); + + EXPECT_FALSE(sync_prefs.IsFirstSetupComplete()); + EXPECT_EQ(base::Time(), sync_prefs.GetLastSyncedTime()); + EXPECT_TRUE(sync_prefs.GetEncryptionBootstrapToken().empty()); + + sync_prefs.SetFirstSetupComplete(); + sync_prefs.SetLastSyncedTime(base::Time::Now()); + sync_prefs.SetEncryptionBootstrapToken("token"); + + EXPECT_TRUE(sync_prefs.IsFirstSetupComplete()); + EXPECT_NE(base::Time(), sync_prefs.GetLastSyncedTime()); + EXPECT_EQ("token", sync_prefs.GetEncryptionBootstrapToken()); + + sync_prefs.ClearPreferences(); + + EXPECT_FALSE(sync_prefs.IsFirstSetupComplete()); + EXPECT_EQ(base::Time(), sync_prefs.GetLastSyncedTime()); + EXPECT_TRUE(sync_prefs.GetEncryptionBootstrapToken().empty()); +} + +// Device info should always be enabled. +TEST_F(SyncPrefsTest, DeviceInfo) { + SyncPrefs sync_prefs(&pref_service_); + EXPECT_TRUE(sync_prefs.GetPreferredDataTypes(syncer::UserTypes()) + .Has(syncer::DEVICE_INFO)); + sync_prefs.SetKeepEverythingSynced(true); + EXPECT_TRUE(sync_prefs.GetPreferredDataTypes(syncer::UserTypes()) + .Has(syncer::DEVICE_INFO)); + sync_prefs.SetKeepEverythingSynced(false); + EXPECT_TRUE(sync_prefs.GetPreferredDataTypes(syncer::UserTypes()) + .Has(syncer::DEVICE_INFO)); +} + +// Verify that invalidation versions are persisted and loaded correctly. +TEST_F(SyncPrefsTest, InvalidationVersions) { + std::map<syncer::ModelType, int64_t> versions; + versions[syncer::BOOKMARKS] = 10; + versions[syncer::SESSIONS] = 20; + versions[syncer::PREFERENCES] = 30; + + SyncPrefs sync_prefs(&pref_service_); + sync_prefs.UpdateInvalidationVersions(versions); + + std::map<syncer::ModelType, int64_t> versions2; + sync_prefs.GetInvalidationVersions(&versions2); + + EXPECT_EQ(versions.size(), versions2.size()); + for (auto map_iter : versions2) { + EXPECT_EQ(versions[map_iter.first], map_iter.second); + } +} + +} // namespace + +} // namespace sync_driver
diff --git a/components/sync/driver/sync_service.cc b/components/sync/driver/sync_service.cc new file mode 100644 index 0000000..866cf6c --- /dev/null +++ b/components/sync/driver/sync_service.cc
@@ -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. + +#include "components/sync/driver/sync_service.h" + +#include "components/sync/core/sync_manager.h" +#include "google_apis/gaia/google_service_auth_error.h" + +namespace sync_driver { + +SyncSetupInProgressHandle::SyncSetupInProgressHandle(base::Closure on_destroy) + : on_destroy_(on_destroy) {} + +SyncSetupInProgressHandle::~SyncSetupInProgressHandle() { + on_destroy_.Run(); +} + +SyncService::SyncTokenStatus::SyncTokenStatus() + : connection_status(syncer::CONNECTION_NOT_ATTEMPTED), + last_get_token_error(GoogleServiceAuthError::AuthErrorNone()) {} + +} // namespace sync_driver
diff --git a/components/sync/driver/sync_service.h b/components/sync/driver/sync_service.h new file mode 100644 index 0000000..96637b61 --- /dev/null +++ b/components/sync/driver/sync_service.h
@@ -0,0 +1,351 @@ +// 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_SYNC_DRIVER_SYNC_SERVICE_H_ +#define COMPONENTS_SYNC_DRIVER_SYNC_SERVICE_H_ + +#include <memory> +#include <string> + +#include "base/callback.h" +#include "base/location.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/time/time.h" +#include "components/sync/base/model_type.h" +#include "components/sync/core/connection_status.h" +#include "components/sync/driver/data_type_encryption_handler.h" +#include "components/sync/driver/sync_service_observer.h" +#include "google_apis/gaia/google_service_auth_error.h" + +class GoogleServiceAuthError; + +namespace browser_sync { +class ProtocolEventObserver; +} + +namespace syncer { + +class BaseTransaction; +class JsController; +class TypeDebugInfoObserver; +struct SyncStatus; +struct UserShare; + +namespace sessions { +class SyncSessionSnapshot; +} // namespace sessions + +} // namespace syncer + +namespace sync_driver { + +class DataTypeController; +class LocalDeviceInfoProvider; +class OpenTabsUIDelegate; +class SyncClient; + +// UIs that need to prevent Sync startup should hold an instance of this class +// until the user has finished modifying sync settings. This is not an inner +// class of SyncService to enable forward declarations. +class SyncSetupInProgressHandle { + public: + // UIs should not construct this directly, but instead call + // SyncService::GetSetupInProgress(). + explicit SyncSetupInProgressHandle(base::Closure on_destroy); + + ~SyncSetupInProgressHandle(); + + private: + base::Closure on_destroy_; +}; + +class SyncService : public DataTypeEncryptionHandler { + public: + // Used to specify the kind of passphrase with which sync data is encrypted. + enum PassphraseType { + IMPLICIT, // The user did not provide a custom passphrase for encryption. + // We implicitly use the GAIA password in such cases. + EXPLICIT, // The user selected the "use custom passphrase" radio button + // during sync setup and provided a passphrase. + }; + + // Passed as an argument to RequestStop to control whether or not the sync + // backend should clear its data directory when it shuts down. See + // RequestStop for more information. + enum SyncStopDataFate { + KEEP_DATA, + CLEAR_DATA, + }; + + // Status of sync server connection, sync token and token request. + struct SyncTokenStatus { + SyncTokenStatus(); + + // Sync server connection status reported by sync backend. + base::Time connection_status_update_time; + syncer::ConnectionStatus connection_status; + + // Times when OAuth2 access token is requested and received. + base::Time token_request_time; + base::Time token_receive_time; + + // Error returned by OAuth2TokenService for token request and time when + // next request is scheduled. + GoogleServiceAuthError last_get_token_error; + base::Time next_token_request_time; + }; + + ~SyncService() override {} + + // Whether sync is enabled by user or not. This does not necessarily mean + // that sync is currently running (due to delayed startup, unrecoverable + // errors, or shutdown). See IsSyncActive below for checking whether sync + // is actually running. + virtual bool IsFirstSetupComplete() const = 0; + + // Whether sync is allowed to start. Command line flags, platform-level + // overrides, and account-level overrides are examples of reasons this + // might be false. + virtual bool IsSyncAllowed() const = 0; + + // Returns true if sync is fully initialized and active. This implies that + // an initial configuration has successfully completed, although there may + // be datatype specific, auth, or other transient errors. To see which + // datetypes are actually syncing, see GetActiveTypes() below. + virtual bool IsSyncActive() const = 0; + + // Triggers a GetUpdates call for the specified |types|, pulling any new data + // from the sync server. + virtual void TriggerRefresh(const syncer::ModelTypeSet& types) = 0; + + // Get the set of current active data types (those chosen or configured by + // the user which have not also encountered a runtime error). + // Note that if the Sync engine is in the middle of a configuration, this + // will the the empty set. Once the configuration completes the set will + // be updated. + virtual syncer::ModelTypeSet GetActiveDataTypes() const = 0; + + // Returns the SyncClient instance associated with this service. + virtual SyncClient* GetSyncClient() const = 0; + + // Adds/removes an observer. SyncService does not take ownership of the + // observer. + virtual void AddObserver(SyncServiceObserver* observer) = 0; + virtual void RemoveObserver(SyncServiceObserver* observer) = 0; + + // Returns true if |observer| has already been added as an observer. + virtual bool HasObserver(const SyncServiceObserver* observer) const = 0; + + // --------------------------------------------------------------------------- + // TODO(sync): The methods below were pulled from ProfileSyncService, and + // should be evaluated to see if they should stay. + + // Called when a datatype (SyncableService) has a need for sync to start + // ASAP, presumably because a local change event has occurred but we're + // still in deferred start mode, meaning the SyncableService hasn't been + // told to MergeDataAndStartSyncing yet. + virtual void OnDataTypeRequestsSyncStartup(syncer::ModelType type) = 0; + + // Returns true if sync is allowed, requested, and the user is logged in. + // (being logged in does not mean that tokens are available - tokens may + // be missing because they have not loaded yet, or because they were deleted + // due to http://crbug.com/121755). + virtual bool CanSyncStart() const = 0; + + // Stops sync at the user's request. |data_fate| controls whether the sync + // backend should clear its data directory when it shuts down. Generally + // KEEP_DATA is used when the user just stops sync, and CLEAR_DATA is used + // when they sign out of the profile entirely. + virtual void RequestStop(SyncStopDataFate data_fate) = 0; + + // The user requests that sync start. This only actually starts sync if + // IsSyncAllowed is true and the user is signed in. Once sync starts, + // other things such as IsFirstSetupComplete being false can still prevent + // it from moving into the "active" state. + virtual void RequestStart() = 0; + + // Returns the set of types which are preferred for enabling. This is a + // superset of the active types (see GetActiveDataTypes()). + virtual syncer::ModelTypeSet GetPreferredDataTypes() const = 0; + + // Called when a user chooses which data types to sync. |sync_everything| + // represents whether they chose the "keep everything synced" option; if + // true, |chosen_types| will be ignored and all data types will be synced. + // |sync_everything| means "sync all current and future data types." + // |chosen_types| must be a subset of syncer::UserSelectableTypes(). + virtual void OnUserChoseDatatypes(bool sync_everything, + syncer::ModelTypeSet chosen_types) = 0; + + // Called whe Sync has been setup by the user and can be started. + virtual void SetFirstSetupComplete() = 0; + + // Returns true if initial sync setup is in progress (does not return true + // if the user is customizing sync after already completing setup once). + // SyncService uses this to determine if it's OK to start syncing, or if the + // user is still setting up the initial sync configuration. + virtual bool IsFirstSetupInProgress() const = 0; + + // Called by the UI to notify the SyncService that UI is visible so it will + // not start syncing. This tells sync whether it's safe to start downloading + // data types yet (we don't start syncing until after sync setup is complete). + // The UI calls this and holds onto the instance for as long as any part of + // the signin wizard is displayed (even just the login UI). + // When the last outstanding handle is deleted, this kicks off the sync engine + // to ensure that data download starts. In this case, + // |ReconfigureDatatypeManager| will get triggered. + virtual std::unique_ptr<SyncSetupInProgressHandle> + GetSetupInProgressHandle() = 0; + + // Used by tests. + virtual bool IsSetupInProgress() const = 0; + + // Whether the data types active for the current mode have finished + // configuration. + virtual bool ConfigurationDone() const = 0; + + virtual const GoogleServiceAuthError& GetAuthError() const = 0; + virtual bool HasUnrecoverableError() const = 0; + + // Returns true if the SyncBackendHost has told us it's ready to accept + // changes. This should only be used for sync's internal configuration logic + // (such as deciding when to prompt for an encryption passphrase). + virtual bool IsBackendInitialized() const = 0; + + // Return the active OpenTabsUIDelegate. If sessions is not enabled or not + // currently syncing, returns nullptr. + virtual OpenTabsUIDelegate* GetOpenTabsUIDelegate() = 0; + + // Returns true if OnPassphraseRequired has been called for decryption and + // we have an encrypted data type enabled. + virtual bool IsPassphraseRequiredForDecryption() const = 0; + + // Returns the time the current explicit passphrase (if any), was set. + // If no secondary passphrase is in use, or no time is available, returns an + // unset base::Time. + virtual base::Time GetExplicitPassphraseTime() const = 0; + + // Returns true if a secondary (explicit) passphrase is being used. It is not + // legal to call this method before the backend is initialized. + virtual bool IsUsingSecondaryPassphrase() const = 0; + + // Turns on encryption for all data. Callers must call OnUserChoseDatatypes() + // after calling this to force the encryption to occur. + virtual void EnableEncryptEverything() = 0; + + // Returns true if we are currently set to encrypt all the sync data. + virtual bool IsEncryptEverythingEnabled() const = 0; + + // Asynchronously sets the passphrase to |passphrase| for encryption. |type| + // specifies whether the passphrase is a custom passphrase or the GAIA + // password being reused as a passphrase. + // TODO(atwilson): Change this so external callers can only set an EXPLICIT + // passphrase with this API. + virtual void SetEncryptionPassphrase(const std::string& passphrase, + PassphraseType type) = 0; + + // Asynchronously decrypts pending keys using |passphrase|. Returns false + // immediately if the passphrase could not be used to decrypt a locally cached + // copy of encrypted keys; returns true otherwise. + virtual bool SetDecryptionPassphrase(const std::string& passphrase) + WARN_UNUSED_RESULT = 0; + + // Checks whether the Cryptographer is ready to encrypt and decrypt updates + // for sensitive data types. Caller must be holding a + // syncapi::BaseTransaction to ensure thread safety. + virtual bool IsCryptographerReady( + const syncer::BaseTransaction* trans) const = 0; + + // TODO(akalin): This is called mostly by ModelAssociators and + // tests. Figure out how to pass the handle to the ModelAssociators + // directly, figure out how to expose this to tests, and remove this + // function. + virtual syncer::UserShare* GetUserShare() const = 0; + + // Returns DeviceInfo provider for the local device. + virtual LocalDeviceInfoProvider* GetLocalDeviceInfoProvider() const = 0; + + // Registers a data type controller with the sync service. This + // makes the data type controller available for use, it does not + // enable or activate the synchronization of the data type (see + // ActivateDataType). Takes ownership of the pointer. + virtual void RegisterDataTypeController( + DataTypeController* data_type_controller) = 0; + + // Called to re-enable a type disabled by DisableDatatype(..). Note, this does + // not change the preferred state of a datatype, and is not persisted across + // restarts. + virtual void ReenableDatatype(syncer::ModelType type) = 0; + + // Return sync token status. + virtual SyncTokenStatus GetSyncTokenStatus() const = 0; + + // Get a description of the sync status for displaying in the user interface. + virtual std::string QuerySyncStatusSummaryString() = 0; + + // Initializes a struct of status indicators with data from the backend. + // Returns false if the backend was not available for querying; in that case + // the struct will be filled with default data. + virtual bool QueryDetailedSyncStatus(syncer::SyncStatus* result) = 0; + + // Returns a user-friendly string form of last synced time (in minutes). + virtual base::string16 GetLastSyncedTimeString() const = 0; + + // Returns a human readable string describing backend initialization state. + virtual std::string GetBackendInitializationStateString() const = 0; + + virtual syncer::sessions::SyncSessionSnapshot GetLastSessionSnapshot() + const = 0; + + // Returns a ListValue indicating the status of all registered types. + // + // The format is: + // [ {"name": <name>, "value": <value>, "status": <status> }, ... ] + // where <name> is a type's name, <value> is a string providing details for + // the type's status, and <status> is one of "error", "warning" or "ok" + // depending on the type's current status. + // + // This function is used by about_sync_util.cc to help populate the about:sync + // page. It returns a ListValue rather than a DictionaryValue in part to make + // it easier to iterate over its elements when constructing that page. + virtual base::Value* GetTypeStatusMap() const = 0; + + virtual const GURL& sync_service_url() const = 0; + + virtual std::string unrecoverable_error_message() const = 0; + virtual tracked_objects::Location unrecoverable_error_location() const = 0; + + virtual void AddProtocolEventObserver( + browser_sync::ProtocolEventObserver* observer) = 0; + virtual void RemoveProtocolEventObserver( + browser_sync::ProtocolEventObserver* observer) = 0; + + virtual void AddTypeDebugInfoObserver( + syncer::TypeDebugInfoObserver* observer) = 0; + virtual void RemoveTypeDebugInfoObserver( + syncer::TypeDebugInfoObserver* observer) = 0; + + // Returns a weak pointer to the service's JsController. + virtual base::WeakPtr<syncer::JsController> GetJsController() = 0; + + // Asynchronously fetches base::Value representations of all sync nodes and + // returns them to the specified callback on this thread. + // + // These requests can live a long time and return when you least expect it. + // For safety, the callback should be bound to some sort of WeakPtr<> or + // scoped_refptr<>. + virtual void GetAllNodes( + const base::Callback<void(std::unique_ptr<base::ListValue>)>& + callback) = 0; + + protected: + SyncService() {} + + private: + DISALLOW_COPY_AND_ASSIGN(SyncService); +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_SYNC_SERVICE_H_
diff --git a/components/sync/driver/sync_service_observer.cc b/components/sync/driver/sync_service_observer.cc new file mode 100644 index 0000000..3e033c75 --- /dev/null +++ b/components/sync/driver/sync_service_observer.cc
@@ -0,0 +1,13 @@ +// 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 "components/sync/driver/sync_service_observer.h" + +namespace sync_driver { + +void SyncServiceObserver::OnSyncCycleCompleted() { + OnStateChanged(); +} + +} // namespace sync_driver
diff --git a/components/sync_driver/sync_service_observer.h b/components/sync/driver/sync_service_observer.h similarity index 100% rename from components/sync_driver/sync_service_observer.h rename to components/sync/driver/sync_service_observer.h
diff --git a/components/sync/driver/sync_service_utils.cc b/components/sync/driver/sync_service_utils.cc new file mode 100644 index 0000000..c2aeafe --- /dev/null +++ b/components/sync/driver/sync_service_utils.cc
@@ -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. + +#include "components/sync/driver/sync_service_utils.h" + +#include "components/sync/driver/sync_prefs.h" +#include "components/sync/driver/sync_service.h" + +namespace sync_driver { + +bool IsTabSyncEnabledAndUnencrypted(SyncService* sync_service, + PrefService* pref_service) { + // Check field trials and settings allow sending the URL on suggest requests. + sync_driver::SyncPrefs sync_prefs(pref_service); + return sync_service && sync_service->CanSyncStart() && + sync_prefs.GetPreferredDataTypes(syncer::UserTypes()) + .Has(syncer::PROXY_TABS) && + !sync_service->GetEncryptedDataTypes().Has(syncer::SESSIONS); +} + +} // namespace sync_driver
diff --git a/components/sync_driver/sync_service_utils.h b/components/sync/driver/sync_service_utils.h similarity index 100% rename from components/sync_driver/sync_service_utils.h rename to components/sync/driver/sync_service_utils.h
diff --git a/components/sync/driver/sync_stopped_reporter.cc b/components/sync/driver/sync_stopped_reporter.cc new file mode 100644 index 0000000..ac84642 --- /dev/null +++ b/components/sync/driver/sync_stopped_reporter.cc
@@ -0,0 +1,119 @@ +// 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/sync/driver/sync_stopped_reporter.h" + +#include "base/location.h" +#include "base/logging.h" +#include "base/single_thread_task_runner.h" +#include "base/strings/stringprintf.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/timer/timer.h" +#include "components/sync/protocol/sync.pb.h" +#include "net/base/load_flags.h" +#include "net/http/http_status_code.h" +#include "net/url_request/url_fetcher.h" +#include "net/url_request/url_request_context_getter.h" + +namespace { + +const char kEventEndpoint[] = "event"; + +// The request is tiny, so even on poor connections 10 seconds should be +// plenty of time. Since sync is off when this request is started, we don't +// want anything sync-related hanging around for very long from a human +// perspective either. This seems like a good compromise. +const int kRequestTimeoutSeconds = 10; + +} // namespace + +namespace browser_sync { + +SyncStoppedReporter::SyncStoppedReporter( + const GURL& sync_service_url, + const std::string& user_agent, + const scoped_refptr<net::URLRequestContextGetter>& request_context, + const ResultCallback& callback) + : sync_event_url_(GetSyncEventURL(sync_service_url)), + user_agent_(user_agent), + request_context_(request_context), + callback_(callback) { + DCHECK(!sync_service_url.is_empty()); + DCHECK(!user_agent_.empty()); + DCHECK(request_context); +} + +SyncStoppedReporter::~SyncStoppedReporter() {} + +void SyncStoppedReporter::ReportSyncStopped(const std::string& access_token, + const std::string& cache_guid, + const std::string& birthday) { + DCHECK(!access_token.empty()); + DCHECK(!cache_guid.empty()); + DCHECK(!birthday.empty()); + + // Make the request proto with the GUID identifying this client. + sync_pb::EventRequest event_request; + sync_pb::SyncDisabledEvent* sync_disabled_event = + event_request.mutable_sync_disabled(); + sync_disabled_event->set_cache_guid(cache_guid); + sync_disabled_event->set_store_birthday(birthday); + + std::string msg; + event_request.SerializeToString(&msg); + + fetcher_ = + net::URLFetcher::Create(sync_event_url_, net::URLFetcher::POST, this); + fetcher_->AddExtraRequestHeader(base::StringPrintf( + "%s: Bearer %s", net::HttpRequestHeaders::kAuthorization, + access_token.c_str())); + fetcher_->AddExtraRequestHeader(base::StringPrintf( + "%s: %s", net::HttpRequestHeaders::kUserAgent, user_agent_.c_str())); + fetcher_->SetRequestContext(request_context_.get()); + fetcher_->SetUploadData("application/octet-stream", msg); + fetcher_->SetLoadFlags(net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE | + net::LOAD_DO_NOT_SAVE_COOKIES | + net::LOAD_DO_NOT_SEND_COOKIES); + fetcher_->Start(); + timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(kRequestTimeoutSeconds), + this, &SyncStoppedReporter::OnTimeout); +} + +void SyncStoppedReporter::OnURLFetchComplete(const net::URLFetcher* source) { + Result result = + source->GetResponseCode() == net::HTTP_OK ? RESULT_SUCCESS : RESULT_ERROR; + fetcher_.reset(); + timer_.Stop(); + if (!callback_.is_null()) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(callback_, result)); + } +} + +void SyncStoppedReporter::OnTimeout() { + fetcher_.reset(); + if (!callback_.is_null()) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(callback_, RESULT_TIMEOUT)); + } +} + +// Static. +GURL SyncStoppedReporter::GetSyncEventURL(const GURL& sync_service_url) { + std::string path = sync_service_url.path(); + if (path.empty() || *path.rbegin() != '/') { + path += '/'; + } + path += kEventEndpoint; + GURL::Replacements replacements; + replacements.SetPathStr(path); + return sync_service_url.ReplaceComponents(replacements); +} + +void SyncStoppedReporter::SetTimerTaskRunnerForTest( + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) { + timer_.SetTaskRunner(task_runner); +} + +} // namespace browser_sync
diff --git a/components/sync/driver/sync_stopped_reporter.h b/components/sync/driver/sync_stopped_reporter.h new file mode 100644 index 0000000..27ab60ec --- /dev/null +++ b/components/sync/driver/sync_stopped_reporter.h
@@ -0,0 +1,80 @@ +// 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_SYNC_DRIVER_SYNC_STOPPED_REPORTER_H_ +#define COMPONENTS_SYNC_DRIVER_SYNC_STOPPED_REPORTER_H_ + +#include <memory> +#include <string> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/timer/timer.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" +#include "url/gurl.h" + +namespace browser_sync { + +// Manages informing the sync server that sync has been disabled. +// An implementation of URLFetcherDelegate was needed in order to +// clean up the fetcher_ pointer when the request completes. +class SyncStoppedReporter : public net::URLFetcherDelegate { + public: + enum Result { RESULT_SUCCESS, RESULT_ERROR, RESULT_TIMEOUT }; + + typedef base::Callback<void(const Result&)> ResultCallback; + + SyncStoppedReporter( + const GURL& sync_service_url, + const std::string& user_agent, + const scoped_refptr<net::URLRequestContextGetter>& request_context, + const ResultCallback& callback); + ~SyncStoppedReporter() override; + + // Inform the sync server that sync was stopped on this device. + // |access_token|, |cache_guid|, and |birthday| must not be empty. + void ReportSyncStopped(const std::string& access_token, + const std::string& cache_guid, + const std::string& birthday); + + // net::URLFetcherDelegate implementation. + void OnURLFetchComplete(const net::URLFetcher* source) override; + + // Override the timer's task runner so it can be triggered in tests. + void SetTimerTaskRunnerForTest( + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner); + + private: + // Convert the base sync URL into the sync event URL. + static GURL GetSyncEventURL(const GURL& sync_service_url); + + // Callback for a request timing out. + void OnTimeout(); + + // Handles timing out requests. + base::OneShotTimer timer_; + + // The URL for the sync server's event RPC. + const GURL sync_event_url_; + + // The user agent for the browser. + const std::string user_agent_; + + // Stored to simplify the API; needed for URLFetcher::Create(). + scoped_refptr<net::URLRequestContextGetter> request_context_; + + // The current URLFetcher. Null unless a request is in progress. + std::unique_ptr<net::URLFetcher> fetcher_; + + // A callback for request completion or timeout. + ResultCallback callback_; + + DISALLOW_COPY_AND_ASSIGN(SyncStoppedReporter); +}; + +} // namespace browser_sync + +#endif // COMPONENTS_SYNC_DRIVER_SYNC_STOPPED_REPORTER_H_
diff --git a/components/sync/driver/sync_stopped_reporter_unittest.cc b/components/sync/driver/sync_stopped_reporter_unittest.cc new file mode 100644 index 0000000..501c2b7 --- /dev/null +++ b/components/sync/driver/sync_stopped_reporter_unittest.cc
@@ -0,0 +1,204 @@ +// 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/sync/driver/sync_stopped_reporter.h" + +#include <string> + +#include "base/macros.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/test/test_simple_task_runner.h" +#include "base/threading/non_thread_safe.h" +#include "components/sync/protocol/sync.pb.h" +#include "net/http/http_status_code.h" +#include "net/url_request/test_url_fetcher_factory.h" +#include "net/url_request/url_request_test_util.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +using browser_sync::SyncStoppedReporter; + +const char kTestURL[] = "http://chromium.org/test"; +const char kTestURLTrailingSlash[] = "http://chromium.org/test/"; +const char kEventURL[] = "http://chromium.org/test/event"; + +const char kTestUserAgent[] = "the_fifth_element"; +const char kAuthToken[] = "multipass"; +const char kCacheGuid[] = "leeloo"; +const char kBirthday[] = "2263"; + +const char kAuthHeaderPrefix[] = "Bearer "; + +class SyncStoppedReporterTest : public testing::Test { + public: + SyncStoppedReporterTest() {} + ~SyncStoppedReporterTest() override {} + + void SetUp() override { + request_context_ = + new net::TestURLRequestContextGetter(message_loop_.task_runner()); + } + + void RequestFinishedCallback(const SyncStoppedReporter::Result& result) { + request_result_ = result; + } + + GURL test_url() { return GURL(kTestURL); } + + std::string user_agent() const { return std::string(kTestUserAgent); } + + SyncStoppedReporter::ResultCallback callback() { + return base::Bind(&SyncStoppedReporterTest::RequestFinishedCallback, + base::Unretained(this)); + } + + const SyncStoppedReporter::Result& request_result() const { + return request_result_; + } + + net::URLRequestContextGetter* request_context() { + return request_context_.get(); + } + + private: + base::MessageLoop message_loop_; + scoped_refptr<net::URLRequestContextGetter> request_context_; + SyncStoppedReporter::Result request_result_; + + DISALLOW_COPY_AND_ASSIGN(SyncStoppedReporterTest); +}; + +// Test that the event URL gets constructed correctly. +TEST_F(SyncStoppedReporterTest, EventURL) { + net::TestURLFetcherFactory factory; + SyncStoppedReporter ssr(GURL(kTestURL), user_agent(), request_context(), + callback()); + ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); + net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); + EXPECT_EQ(kEventURL, fetcher->GetOriginalURL().spec()); +} + +// Test that the event URL gets constructed correctly with a trailing slash. +TEST_F(SyncStoppedReporterTest, EventURLWithSlash) { + net::TestURLFetcherFactory factory; + SyncStoppedReporter ssr(GURL(kTestURLTrailingSlash), user_agent(), + request_context(), callback()); + ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); + net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); + EXPECT_EQ(kEventURL, fetcher->GetOriginalURL().spec()); +} + +// Test that the URLFetcher gets configured correctly. +TEST_F(SyncStoppedReporterTest, FetcherConfiguration) { + net::TestURLFetcherFactory factory; + SyncStoppedReporter ssr(test_url(), user_agent(), request_context(), + callback()); + ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); + net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); + + // Ensure the headers are set correctly. + net::HttpRequestHeaders headers; + std::string header; + fetcher->GetExtraRequestHeaders(&headers); + headers.GetHeader(net::HttpRequestHeaders::kAuthorization, &header); + std::string auth_header(kAuthHeaderPrefix); + auth_header.append(kAuthToken); + EXPECT_EQ(auth_header, header); + headers.GetHeader(net::HttpRequestHeaders::kUserAgent, &header); + EXPECT_EQ(user_agent(), header); + + sync_pb::EventRequest event_request; + event_request.ParseFromString(fetcher->upload_data()); + + EXPECT_EQ(kCacheGuid, event_request.sync_disabled().cache_guid()); + EXPECT_EQ(kBirthday, event_request.sync_disabled().store_birthday()); + EXPECT_EQ(kEventURL, fetcher->GetOriginalURL().spec()); +} + +TEST_F(SyncStoppedReporterTest, HappyCase) { + net::TestURLFetcherFactory factory; + SyncStoppedReporter ssr(test_url(), user_agent(), request_context(), + callback()); + ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); + net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); + fetcher->set_response_code(net::HTTP_OK); + ssr.OnURLFetchComplete(fetcher); + base::RunLoop run_loop; + run_loop.RunUntilIdle(); + EXPECT_EQ(SyncStoppedReporter::RESULT_SUCCESS, request_result()); +} + +TEST_F(SyncStoppedReporterTest, ServerNotFound) { + net::TestURLFetcherFactory factory; + SyncStoppedReporter ssr(test_url(), user_agent(), request_context(), + callback()); + ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); + net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); + fetcher->set_response_code(net::HTTP_NOT_FOUND); + ssr.OnURLFetchComplete(fetcher); + base::RunLoop run_loop; + run_loop.RunUntilIdle(); + EXPECT_EQ(SyncStoppedReporter::RESULT_ERROR, request_result()); +} + +TEST_F(SyncStoppedReporterTest, DestructionDuringRequestHandler) { + net::TestURLFetcherFactory factory; + factory.set_remove_fetcher_on_delete(true); + { + SyncStoppedReporter ssr(test_url(), user_agent(), request_context(), + callback()); + ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); + EXPECT_FALSE(factory.GetFetcherByID(0) == nullptr); + } + EXPECT_TRUE(factory.GetFetcherByID(0) == nullptr); +} + +TEST_F(SyncStoppedReporterTest, Timeout) { + SyncStoppedReporter ssr(test_url(), user_agent(), request_context(), + callback()); + + // A task runner that can trigger the timeout immediately. + scoped_refptr<base::TestSimpleTaskRunner> task_runner( + new base::TestSimpleTaskRunner()); + ssr.SetTimerTaskRunnerForTest(task_runner); + + // Begin request. + ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); + + // Trigger the timeout. + ASSERT_TRUE(task_runner->HasPendingTask()); + task_runner->RunPendingTasks(); + + base::RunLoop run_loop; + run_loop.RunUntilIdle(); + EXPECT_EQ(SyncStoppedReporter::RESULT_TIMEOUT, request_result()); +} + +TEST_F(SyncStoppedReporterTest, NoCallback) { + net::TestURLFetcherFactory factory; + SyncStoppedReporter ssr(GURL(kTestURL), user_agent(), request_context(), + SyncStoppedReporter::ResultCallback()); + ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); + net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); + fetcher->set_response_code(net::HTTP_OK); + ssr.OnURLFetchComplete(fetcher); +} + +TEST_F(SyncStoppedReporterTest, NoCallbackTimeout) { + SyncStoppedReporter ssr(GURL(kTestURL), user_agent(), request_context(), + SyncStoppedReporter::ResultCallback()); + + // A task runner that can trigger the timeout immediately. + scoped_refptr<base::TestSimpleTaskRunner> task_runner( + new base::TestSimpleTaskRunner()); + ssr.SetTimerTaskRunnerForTest(task_runner); + + // Begin request. + ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); + + // Trigger the timeout. + ASSERT_TRUE(task_runner->HasPendingTask()); + task_runner->RunPendingTasks(); +}
diff --git a/components/sync_driver/sync_type_preference_provider.h b/components/sync/driver/sync_type_preference_provider.h similarity index 100% rename from components/sync_driver/sync_type_preference_provider.h rename to components/sync/driver/sync_type_preference_provider.h
diff --git a/components/sync/driver/sync_util.cc b/components/sync/driver/sync_util.cc new file mode 100644 index 0000000..b3535c50 --- /dev/null +++ b/components/sync/driver/sync_util.cc
@@ -0,0 +1,106 @@ +// 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/sync/driver/sync_util.h" + +#include "base/command_line.h" +#include "base/logging.h" +#include "build/build_config.h" +#include "components/sync/driver/sync_driver_switches.h" +#include "url/gurl.h" + +namespace { + +// Returns string that represents system in UserAgent. +std::string GetSystemString(bool is_tablet) { + std::string system; +#if defined(OS_CHROMEOS) + system = "CROS "; +#elif defined(OS_ANDROID) + if (is_tablet) { + system = "ANDROID-TABLET "; + } else { + system = "ANDROID-PHONE "; + } +#elif defined(OS_IOS) + if (is_tablet) { + system = "IOS-TABLET "; + } else { + system = "IOS-PHONE "; + } +#elif defined(OS_WIN) + system = "WIN "; +#elif defined(OS_LINUX) + system = "LINUX "; +#elif defined(OS_FREEBSD) + system = "FREEBSD "; +#elif defined(OS_OPENBSD) + system = "OPENBSD "; +#elif defined(OS_MACOSX) + system = "MAC "; +#endif + return system; +} + +} // namespace + +namespace internal { + +const char* kSyncServerUrl = "https://clients4.google.com/chrome-sync"; + +const char* kSyncDevServerUrl = "https://clients4.google.com/chrome-sync/dev"; + +std::string FormatUserAgentForSync(const std::string& system, + version_info::Channel channel) { + std::string user_agent; + user_agent = "Chrome "; + user_agent += system; + user_agent += version_info::GetVersionNumber(); + user_agent += " (" + version_info::GetLastChange() + ")"; + if (!version_info::IsOfficialBuild()) { + user_agent += "-devel"; + } else { + user_agent += " channel(" + version_info::GetChannelString(channel) + ")"; + } + return user_agent; +} + +} // namespace internal + +GURL GetSyncServiceURL(const base::CommandLine& command_line, + version_info::Channel channel) { + // By default, dev, canary, and unbranded Chromium users will go to the + // development servers. Development servers have more features than standard + // sync servers. Users with officially-branded Chrome stable and beta builds + // will go to the standard sync servers. + GURL result(internal::kSyncDevServerUrl); + + if (channel == version_info::Channel::STABLE || + channel == version_info::Channel::BETA) { + result = GURL(internal::kSyncServerUrl); + } + + // Override the sync server URL from the command-line, if sync server + // command-line argument exists. + if (command_line.HasSwitch(switches::kSyncServiceURL)) { + std::string value( + command_line.GetSwitchValueASCII(switches::kSyncServiceURL)); + if (!value.empty()) { + GURL custom_sync_url(value); + if (custom_sync_url.is_valid()) { + result = custom_sync_url; + } else { + LOG(WARNING) << "The following sync URL specified at the command-line " + << "is invalid: " << value; + } + } + } + return result; +} + +std::string MakeUserAgentForSync(version_info::Channel channel, + bool is_tablet) { + std::string system = GetSystemString(is_tablet); + return internal::FormatUserAgentForSync(system, channel); +}
diff --git a/components/sync_driver/sync_util.h b/components/sync/driver/sync_util.h similarity index 100% rename from components/sync_driver/sync_util.h rename to components/sync/driver/sync_util.h
diff --git a/components/sync/driver/sync_util_unittest.cc b/components/sync/driver/sync_util_unittest.cc new file mode 100644 index 0000000..282cb0c --- /dev/null +++ b/components/sync/driver/sync_util_unittest.cc
@@ -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. + +#include "components/sync/driver/sync_util.h" + +#include "base/command_line.h" +#include "base/strings/string_util.h" +#include "components/sync/driver/sync_driver_switches.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace { + +TEST(SyncUtilTest, GetSyncServiceURLWithoutCommandLineSwitch) { + // If the command line is not set the url is one of two constants chosen based + // on the channel (e.g. beta). + base::CommandLine command_line(base::CommandLine::NO_PROGRAM); + std::string url = + GetSyncServiceURL(command_line, version_info::Channel::BETA).spec(); + ASSERT_TRUE(internal::kSyncServerUrl == url || + internal::kSyncDevServerUrl == url); +} + +TEST(SyncUtilTest, GetSyncServiceURLWithCommandLineSwitch) { + // See that we can set the URL via the command line. + base::CommandLine command_line(base::CommandLine::NO_PROGRAM); + command_line.AppendSwitchASCII(switches::kSyncServiceURL, "https://foo/bar"); + ASSERT_EQ( + "https://foo/bar", + GetSyncServiceURL(command_line, version_info::Channel::UNKNOWN).spec()); +} + +TEST(SyncUtilTest, GetSyncServiceURLWithBadCommandLineSwitch) { + // If the command line value is not a valid url it is ignored. + base::CommandLine command_line(base::CommandLine::NO_PROGRAM); + command_line.AppendSwitchASCII(switches::kSyncServiceURL, "invalid_url"); + std::string url = + GetSyncServiceURL(command_line, version_info::Channel::UNKNOWN).spec(); + ASSERT_TRUE(internal::kSyncServerUrl == url || + internal::kSyncDevServerUrl == url); +} + +TEST(SyncUtilTest, FormatUserAgentForSync) { + std::string user_agent = + internal::FormatUserAgentForSync("TEST", version_info::Channel::UNKNOWN); + ASSERT_TRUE(base::StartsWith(user_agent, "Chrome TEST", + base::CompareCase::SENSITIVE)); +} + +} // namespace
diff --git a/components/sync/driver/system_encryptor.cc b/components/sync/driver/system_encryptor.cc new file mode 100644 index 0000000..b634aaa --- /dev/null +++ b/components/sync/driver/system_encryptor.cc
@@ -0,0 +1,23 @@ +// 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 "components/sync/driver/system_encryptor.h" + +#include "components/os_crypt/os_crypt.h" + +namespace sync_driver { + +SystemEncryptor::~SystemEncryptor() {} + +bool SystemEncryptor::EncryptString(const std::string& plaintext, + std::string* ciphertext) { + return ::OSCrypt::EncryptString(plaintext, ciphertext); +} + +bool SystemEncryptor::DecryptString(const std::string& ciphertext, + std::string* plaintext) { + return ::OSCrypt::DecryptString(ciphertext, plaintext); +} + +} // namespace sync_driver
diff --git a/components/sync_driver/system_encryptor.h b/components/sync/driver/system_encryptor.h similarity index 100% rename from components/sync_driver/system_encryptor.h rename to components/sync/driver/system_encryptor.h
diff --git a/components/sync/driver/system_encryptor_unittest.cc b/components/sync/driver/system_encryptor_unittest.cc new file mode 100644 index 0000000..369d94e8 --- /dev/null +++ b/components/sync/driver/system_encryptor_unittest.cc
@@ -0,0 +1,39 @@ +// 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 "components/sync/driver/system_encryptor.h" + +#include <string> + +#include "build/build_config.h" +#include "components/os_crypt/os_crypt_mocker.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace sync_driver { + +namespace { + +const char kPlaintext[] = "The Magic Words are Squeamish Ossifrage"; + +class SystemEncryptorTest : public testing::Test { + protected: + SystemEncryptor encryptor_; +}; + +TEST_F(SystemEncryptorTest, EncryptDecrypt) { + // SystemEncryptor ends up needing access to the keychain on OS X, + // so use the mock keychain to prevent prompts. + ::OSCryptMocker::SetUpWithSingleton(); + std::string ciphertext; + EXPECT_TRUE(encryptor_.EncryptString(kPlaintext, &ciphertext)); + EXPECT_NE(kPlaintext, ciphertext); + std::string plaintext; + EXPECT_TRUE(encryptor_.DecryptString(ciphertext, &plaintext)); + EXPECT_EQ(kPlaintext, plaintext); + ::OSCryptMocker::TearDown(); +} + +} // namespace + +} // namespace sync_driver
diff --git a/components/sync/driver/ui_data_type_controller.cc b/components/sync/driver/ui_data_type_controller.cc new file mode 100644 index 0000000..584610ee --- /dev/null +++ b/components/sync/driver/ui_data_type_controller.cc
@@ -0,0 +1,380 @@ +// 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 "components/sync/driver/ui_data_type_controller.h" + +#include <utility> + +#include "base/location.h" +#include "base/logging.h" +#include "base/memory/weak_ptr.h" +#include "base/profiler/scoped_tracker.h" +#include "base/single_thread_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" +#include "components/sync/api/sync_error.h" +#include "components/sync/api/sync_merge_result.h" +#include "components/sync/api/syncable_service.h" +#include "components/sync/base/data_type_histogram.h" +#include "components/sync/base/model_type.h" +#include "components/sync/driver/generic_change_processor_factory.h" +#include "components/sync/driver/shared_change_processor_ref.h" +#include "components/sync/driver/sync_client.h" +#include "components/sync/driver/sync_service.h" + +namespace sync_driver { + +UIDataTypeController::UIDataTypeController() + : DirectoryDataTypeController(base::ThreadTaskRunnerHandle::Get(), + base::Closure()), + sync_client_(NULL), + state_(NOT_RUNNING), + type_(syncer::UNSPECIFIED) {} + +UIDataTypeController::UIDataTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const base::Closure& error_callback, + syncer::ModelType type, + SyncClient* sync_client) + : DirectoryDataTypeController(ui_thread, error_callback), + sync_client_(sync_client), + state_(NOT_RUNNING), + type_(type), + processor_factory_(new GenericChangeProcessorFactory()), + ui_thread_(ui_thread) { + DCHECK(ui_thread_->BelongsToCurrentThread()); + DCHECK(syncer::IsRealDataType(type_)); +} + +void UIDataTypeController::SetGenericChangeProcessorFactoryForTest( + std::unique_ptr<GenericChangeProcessorFactory> factory) { + DCHECK_EQ(state_, NOT_RUNNING); + processor_factory_ = std::move(factory); +} + +UIDataTypeController::~UIDataTypeController() { + DCHECK(ui_thread_->BelongsToCurrentThread()); +} + +void UIDataTypeController::LoadModels( + const ModelLoadCallback& model_load_callback) { + DCHECK(ui_thread_->BelongsToCurrentThread()); + DCHECK(syncer::IsRealDataType(type_)); + model_load_callback_ = model_load_callback; + if (state_ != NOT_RUNNING) { + model_load_callback.Run( + type(), syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Model already loaded", type())); + return; + } + // Since we can't be called multiple times before Stop() is called, + // |shared_change_processor_| must be NULL here. + DCHECK(!shared_change_processor_.get()); + shared_change_processor_ = new SharedChangeProcessor(); + + state_ = MODEL_STARTING; + if (!StartModels()) { + // If we are waiting for some external service to load before associating + // or we failed to start the models, we exit early. state_ will control + // what we perform next. + DCHECK(state_ == NOT_RUNNING || state_ == MODEL_STARTING); + return; + } + + state_ = MODEL_LOADED; + model_load_callback_.Run(type(), syncer::SyncError()); +} + +void UIDataTypeController::OnModelLoaded() { + DCHECK(ui_thread_->BelongsToCurrentThread()); + DCHECK_EQ(state_, MODEL_STARTING); + + state_ = MODEL_LOADED; + model_load_callback_.Run(type(), syncer::SyncError()); +} + +void UIDataTypeController::StartAssociating( + const StartCallback& start_callback) { + DCHECK(ui_thread_->BelongsToCurrentThread()); + DCHECK(!start_callback.is_null()); + DCHECK_EQ(state_, MODEL_LOADED); + + start_callback_ = start_callback; + state_ = ASSOCIATING; + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(&UIDataTypeController::Associate, this)); +} + +bool UIDataTypeController::StartModels() { + DCHECK_EQ(state_, MODEL_STARTING); + // By default, no additional services need to be started before we can proceed + // with model association. + return true; +} + +void UIDataTypeController::Associate() { + if (state_ != ASSOCIATING) { + // Stop() must have been called while Associate() task have been waiting. + DCHECK_EQ(state_, NOT_RUNNING); + return; + } + + syncer::SyncMergeResult local_merge_result(type()); + syncer::SyncMergeResult syncer_merge_result(type()); + base::WeakPtrFactory<syncer::SyncMergeResult> weak_ptr_factory( + &syncer_merge_result); + + // TODO(robliao): Remove ScopedTracker below once https://crbug.com/471403 is + // fixed. + tracked_objects::ScopedTracker tracking_profile1( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "471403 UIDataTypeController::Associate1")); + + // Connect |shared_change_processor_| to the syncer and get the + // syncer::SyncableService associated with type(). + DCHECK(sync_client_->GetSyncService()); + local_service_ = shared_change_processor_->Connect( + sync_client_, processor_factory_.get(), + sync_client_->GetSyncService()->GetUserShare(), this, type(), + weak_ptr_factory.GetWeakPtr()); + if (!local_service_.get()) { + syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, + "Failed to connect to syncer.", type()); + local_merge_result.set_error(error); + StartDone(ASSOCIATION_FAILED, local_merge_result, syncer_merge_result); + return; + } + + // TODO(robliao): Remove ScopedTracker below once https://crbug.com/471403 is + // fixed. + tracked_objects::ScopedTracker tracking_profile2( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "471403 UIDataTypeController::Associate2")); + if (!shared_change_processor_->CryptoReadyIfNecessary()) { + syncer::SyncError error(FROM_HERE, syncer::SyncError::CRYPTO_ERROR, "", + type()); + local_merge_result.set_error(error); + StartDone(NEEDS_CRYPTO, local_merge_result, syncer_merge_result); + return; + } + + // TODO(robliao): Remove ScopedTracker below once https://crbug.com/471403 is + // fixed. + tracked_objects::ScopedTracker tracking_profile3( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "471403 UIDataTypeController::Associate3")); + bool sync_has_nodes = false; + if (!shared_change_processor_->SyncModelHasUserCreatedNodes( + &sync_has_nodes)) { + syncer::SyncError error(FROM_HERE, syncer::SyncError::UNRECOVERABLE_ERROR, + "Failed to load sync nodes", type()); + local_merge_result.set_error(error); + StartDone(UNRECOVERABLE_ERROR, local_merge_result, syncer_merge_result); + return; + } + + // Scope for |initial_sync_data| which might be expensive, so we don't want + // to keep it in memory longer than necessary. + { + syncer::SyncDataList initial_sync_data; + + // TODO(robliao): Remove ScopedTracker below once https://crbug.com/471403 + // is fixed. + tracked_objects::ScopedTracker tracking_profile4( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "471403 UIDataTypeController::Associate4")); + base::TimeTicks start_time = base::TimeTicks::Now(); + syncer::SyncError error = + shared_change_processor_->GetAllSyncDataReturnError(type(), + &initial_sync_data); + if (error.IsSet()) { + local_merge_result.set_error(error); + StartDone(ASSOCIATION_FAILED, local_merge_result, syncer_merge_result); + return; + } + + // TODO(robliao): Remove ScopedTracker below once https://crbug.com/471403 + // is fixed. + tracked_objects::ScopedTracker tracking_profile5( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "471403 UIDataTypeController::Associate5")); + std::string datatype_context; + if (shared_change_processor_->GetDataTypeContext(&datatype_context)) { + local_service_->UpdateDataTypeContext( + type(), syncer::SyncChangeProcessor::NO_REFRESH, datatype_context); + } + + // TODO(robliao): Remove ScopedTracker below once https://crbug.com/471403 + // is fixed. + tracked_objects::ScopedTracker tracking_profile6( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "471403 UIDataTypeController::Associate6")); + syncer_merge_result.set_num_items_before_association( + initial_sync_data.size()); + // Passes a reference to |shared_change_processor_|. + local_merge_result = local_service_->MergeDataAndStartSyncing( + type(), initial_sync_data, + std::unique_ptr<syncer::SyncChangeProcessor>( + new SharedChangeProcessorRef(shared_change_processor_)), + std::unique_ptr<syncer::SyncErrorFactory>( + new SharedChangeProcessorRef(shared_change_processor_))); + RecordAssociationTime(base::TimeTicks::Now() - start_time); + if (local_merge_result.error().IsSet()) { + StartDone(ASSOCIATION_FAILED, local_merge_result, syncer_merge_result); + return; + } + } + + // TODO(robliao): Remove ScopedTracker below once https://crbug.com/471403 is + // fixed. + tracked_objects::ScopedTracker tracking_profile7( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "471403 UIDataTypeController::Associate7")); + syncer_merge_result.set_num_items_after_association( + shared_change_processor_->GetSyncCount()); + + state_ = RUNNING; + StartDone(sync_has_nodes ? OK : OK_FIRST_RUN, local_merge_result, + syncer_merge_result); +} + +ChangeProcessor* UIDataTypeController::GetChangeProcessor() const { + DCHECK_EQ(state_, RUNNING); + return shared_change_processor_->generic_change_processor(); +} + +void UIDataTypeController::AbortModelLoad() { + DCHECK(ui_thread_->BelongsToCurrentThread()); + state_ = NOT_RUNNING; + + if (shared_change_processor_.get()) { + shared_change_processor_ = NULL; + } + + // We don't want to continue loading models (e.g OnModelLoaded should never be + // called after we've decided to abort). + StopModels(); +} + +void UIDataTypeController::StartDone( + ConfigureResult start_result, + const syncer::SyncMergeResult& local_merge_result, + const syncer::SyncMergeResult& syncer_merge_result) { + DCHECK(ui_thread_->BelongsToCurrentThread()); + + // TODO(robliao): Remove ScopedTracker below once https://crbug.com/471403 is + // fixed. + tracked_objects::ScopedTracker tracking_profile( + FROM_HERE_WITH_EXPLICIT_FUNCTION( + "471403 UIDataTypeController::StartDone")); + + if (!IsSuccessfulResult(start_result)) { + StopModels(); + if (start_result == ASSOCIATION_FAILED) { + state_ = DISABLED; + } else { + state_ = NOT_RUNNING; + } + RecordStartFailure(start_result); + + if (shared_change_processor_.get()) { + shared_change_processor_->Disconnect(); + shared_change_processor_ = NULL; + } + } + + start_callback_.Run(start_result, local_merge_result, syncer_merge_result); +} + +void UIDataTypeController::Stop() { + DCHECK(ui_thread_->BelongsToCurrentThread()); + DCHECK(syncer::IsRealDataType(type_)); + + if (state_ == NOT_RUNNING) + return; + + State prev_state = state_; + state_ = STOPPING; + + if (shared_change_processor_.get()) { + shared_change_processor_->Disconnect(); + shared_change_processor_ = NULL; + } + + // If Stop() is called while Start() is waiting for the datatype model to + // load, abort the start. + if (prev_state == MODEL_STARTING) { + AbortModelLoad(); + // We can just return here since we haven't performed association if we're + // still in MODEL_STARTING. + return; + } + + StopModels(); + + if (local_service_.get()) { + local_service_->StopSyncing(type()); + } + + state_ = NOT_RUNNING; +} + +syncer::ModelType UIDataTypeController::type() const { + DCHECK(syncer::IsRealDataType(type_)); + return type_; +} + +void UIDataTypeController::StopModels() { + // Do nothing by default. +} + +syncer::ModelSafeGroup UIDataTypeController::model_safe_group() const { + DCHECK(syncer::IsRealDataType(type_)); + return syncer::GROUP_UI; +} + +std::string UIDataTypeController::name() const { + // For logging only. + return syncer::ModelTypeToString(type()); +} + +DataTypeController::State UIDataTypeController::state() const { + return state_; +} + +void UIDataTypeController::OnSingleDataTypeUnrecoverableError( + const syncer::SyncError& error) { + DCHECK_EQ(type(), error.model_type()); + UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeRunFailures", + ModelTypeToHistogramInt(type()), + syncer::MODEL_TYPE_COUNT); + // TODO(tim): We double-upload some errors. See bug 383480. + if (!error_callback_.is_null()) + error_callback_.Run(); + if (!model_load_callback_.is_null()) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(model_load_callback_, type(), error)); + } +} + +void UIDataTypeController::RecordAssociationTime(base::TimeDelta time) { + DCHECK(ui_thread_->BelongsToCurrentThread()); +#define PER_DATA_TYPE_MACRO(type_str) \ + UMA_HISTOGRAM_TIMES("Sync." type_str "AssociationTime", time); + SYNC_DATA_TYPE_HISTOGRAM(type()); +#undef PER_DATA_TYPE_MACRO +} + +void UIDataTypeController::RecordStartFailure(ConfigureResult result) { + DCHECK(ui_thread_->BelongsToCurrentThread()); + UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", + ModelTypeToHistogramInt(type()), + syncer::MODEL_TYPE_COUNT); +#define PER_DATA_TYPE_MACRO(type_str) \ + UMA_HISTOGRAM_ENUMERATION("Sync." type_str "ConfigureFailure", result, \ + MAX_CONFIGURE_RESULT); + SYNC_DATA_TYPE_HISTOGRAM(type()); +#undef PER_DATA_TYPE_MACRO +} + +} // namespace sync_driver
diff --git a/components/sync/driver/ui_data_type_controller.h b/components/sync/driver/ui_data_type_controller.h new file mode 100644 index 0000000..2211adf --- /dev/null +++ b/components/sync/driver/ui_data_type_controller.h
@@ -0,0 +1,140 @@ +// 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 COMPONENTS_SYNC_DRIVER_UI_DATA_TYPE_CONTROLLER_H_ +#define COMPONENTS_SYNC_DRIVER_UI_DATA_TYPE_CONTROLLER_H_ + +#include <memory> +#include <string> + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "components/sync/driver/directory_data_type_controller.h" +#include "components/sync/driver/shared_change_processor.h" + +namespace base { +class TimeDelta; +} + +namespace syncer { +class SyncableService; +class SyncClient; +class SyncError; +} + +namespace sync_driver { + +// Implementation for datatypes that reside on the (UI thread). This is the same +// thread we perform initialization on, so we don't have to worry about thread +// safety. The main start/stop funtionality is implemented by default. +// Note: RefCountedThreadSafe by way of DataTypeController. +class UIDataTypeController : public DirectoryDataTypeController { + public: + UIDataTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const base::Closure& error_callback, + syncer::ModelType type, + SyncClient* sync_client); + + // DataTypeController interface. + void LoadModels(const ModelLoadCallback& model_load_callback) override; + void StartAssociating(const StartCallback& start_callback) override; + void Stop() override; + syncer::ModelType type() const override; + syncer::ModelSafeGroup model_safe_group() const override; + ChangeProcessor* GetChangeProcessor() const override; + std::string name() const override; + State state() const override; + + // DataTypeErrorHandler interface. + void OnSingleDataTypeUnrecoverableError( + const syncer::SyncError& error) override; + + // Used by tests to override the factory used to create + // GenericChangeProcessors. + void SetGenericChangeProcessorFactoryForTest( + std::unique_ptr<GenericChangeProcessorFactory> factory); + + protected: + // For testing only. + UIDataTypeController(); + // DataTypeController is RefCounted. + ~UIDataTypeController() override; + + // Start any dependent services that need to be running before we can + // associate models. The default implementation is a no-op. + // Return value: + // True - if models are ready and association can proceed. + // False - if models are not ready. OnModelLoaded() should be called when + // the models are ready. + virtual bool StartModels(); + + // Perform any DataType controller specific state cleanup before stopping + // the datatype controller. The default implementation is a no-op. + virtual void StopModels(); + + // Helper method for cleaning up state and invoking the start callback. + virtual void StartDone(ConfigureResult result, + const syncer::SyncMergeResult& local_merge_result, + const syncer::SyncMergeResult& syncer_merge_result); + + // Record association time. + virtual void RecordAssociationTime(base::TimeDelta time); + // Record causes of start failure. + virtual void RecordStartFailure(ConfigureResult result); + + // If the DTC is waiting for models to load, once the models are + // loaded the datatype service will call this function on DTC to let + // us know that it is safe to start associating. + void OnModelLoaded(); + + SyncClient* const sync_client_; + + State state_; + + StartCallback start_callback_; + ModelLoadCallback model_load_callback_; + + // The sync datatype being controlled. + syncer::ModelType type_; + + // Sync's interface to the datatype. All sync changes for |type_| are pushed + // through it to the datatype as well as vice versa. + // + // Lifetime: it gets created when Start()) is called, and a reference to it + // is passed to |local_service_| during Associate(). We release our reference + // when Stop() or StartFailed() is called, and |local_service_| releases its + // reference when local_service_->StopSyncing() is called or when it is + // destroyed. + // + // Note: we use refcounting here primarily so that we can keep a uniform + // SyncableService API, whether the datatype lives on the UI thread or not + // (a syncer::SyncableService takes ownership of its SyncChangeProcessor when + // MergeDataAndStartSyncing is called). This will help us eventually merge the + // two datatype controller implementations (for ui and non-ui thread + // datatypes). + scoped_refptr<SharedChangeProcessor> shared_change_processor_; + + std::unique_ptr<GenericChangeProcessorFactory> processor_factory_; + + // A weak pointer to the actual local syncable service, which performs all the + // real work. We do not own the object. + base::WeakPtr<syncer::SyncableService> local_service_; + + scoped_refptr<base::SingleThreadTaskRunner> ui_thread_; + + private: + // Associate the sync model with the service's model, then start syncing. + virtual void Associate(); + + virtual void AbortModelLoad(); + + DISALLOW_COPY_AND_ASSIGN(UIDataTypeController); +}; + +} // namespace sync_driver + +#endif // COMPONENTS_SYNC_DRIVER_UI_DATA_TYPE_CONTROLLER_H_
diff --git a/components/sync/driver/ui_data_type_controller_unittest.cc b/components/sync/driver/ui_data_type_controller_unittest.cc new file mode 100644 index 0000000..e7e2bec --- /dev/null +++ b/components/sync/driver/ui_data_type_controller_unittest.cc
@@ -0,0 +1,198 @@ +// 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 "components/sync/driver/ui_data_type_controller.h" + +#include <memory> +#include <utility> + +#include "base/bind.h" +#include "base/location.h" +#include "base/single_thread_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/tracked_objects.h" +#include "components/sync/api/fake_syncable_service.h" +#include "components/sync/base/model_type.h" +#include "components/sync/driver/data_type_controller_mock.h" +#include "components/sync/driver/fake_generic_change_processor.h" +#include "components/sync/driver/fake_sync_client.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::_; +using testing::Invoke; +using testing::InvokeWithoutArgs; +using testing::Return; + +namespace sync_driver { +namespace { + +// TODO(zea): Expand this to make the dtc type paramterizable. This will let us +// test the basic functionality of all UIDataTypeControllers. We'll need to have +// intelligent default values for the methods queried in the dependent services +// (e.g. those queried in StartModels). +class SyncUIDataTypeControllerTest : public testing::Test, + public FakeSyncClient { + public: + SyncUIDataTypeControllerTest() + : type_(syncer::PREFERENCES), change_processor_(NULL) {} + + // FakeSyncClient overrides. + base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType( + syncer::ModelType type) override { + return syncable_service_.AsWeakPtr(); + } + + void SetUp() override { + preference_dtc_ = new UIDataTypeController( + base::ThreadTaskRunnerHandle::Get(), base::Closure(), type_, this); + SetStartExpectations(); + } + + void TearDown() override { + // Must be done before we pump the loop. + syncable_service_.StopSyncing(type_); + preference_dtc_ = NULL; + PumpLoop(); + } + + protected: + void SetStartExpectations() { + std::unique_ptr<FakeGenericChangeProcessor> p( + new FakeGenericChangeProcessor(type_, this)); + change_processor_ = p.get(); + std::unique_ptr<GenericChangeProcessorFactory> f( + new FakeGenericChangeProcessorFactory(std::move(p))); + preference_dtc_->SetGenericChangeProcessorFactoryForTest(std::move(f)); + EXPECT_CALL(model_load_callback_, Run(_, _)); + } + + void Start() { + preference_dtc_->LoadModels(base::Bind( + &ModelLoadCallbackMock::Run, base::Unretained(&model_load_callback_))); + preference_dtc_->StartAssociating(base::Bind( + &StartCallbackMock::Run, base::Unretained(&start_callback_))); + PumpLoop(); + } + + void PumpLoop() { message_loop_.RunUntilIdle(); } + + base::MessageLoopForUI message_loop_; + const syncer::ModelType type_; + StartCallbackMock start_callback_; + ModelLoadCallbackMock model_load_callback_; + scoped_refptr<UIDataTypeController> preference_dtc_; + FakeGenericChangeProcessor* change_processor_; + syncer::FakeSyncableService syncable_service_; +}; + +// Start the DTC. Verify that the callback is called with OK, the +// service has been told to start syncing and that the DTC is now in RUNNING +// state. +TEST_F(SyncUIDataTypeControllerTest, Start) { + EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _)); + + EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); + EXPECT_FALSE(syncable_service_.syncing()); + Start(); + EXPECT_EQ(DataTypeController::RUNNING, preference_dtc_->state()); + EXPECT_TRUE(syncable_service_.syncing()); +} + +// Start and then stop the DTC. Verify that the service started and stopped +// syncing, and that the DTC went from RUNNING to NOT_RUNNING. +TEST_F(SyncUIDataTypeControllerTest, StartStop) { + EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _)); + + EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); + EXPECT_FALSE(syncable_service_.syncing()); + Start(); + EXPECT_EQ(DataTypeController::RUNNING, preference_dtc_->state()); + EXPECT_TRUE(syncable_service_.syncing()); + preference_dtc_->Stop(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); + EXPECT_FALSE(syncable_service_.syncing()); +} + +// Start and then stop the DTC before the Start had a chance to perform +// association. Verify that the service never started and is NOT_RUNNING. +TEST_F(SyncUIDataTypeControllerTest, StartStopBeforeAssociation) { + EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); + EXPECT_FALSE(syncable_service_.syncing()); + message_loop_.task_runner()->PostTask( + FROM_HERE, base::Bind(&UIDataTypeController::Stop, preference_dtc_)); + Start(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); + EXPECT_FALSE(syncable_service_.syncing()); +} + +// Start the DTC when no user nodes are created. Verify that the callback +// is called with OK_FIRST_RUN. Stop the DTC. +TEST_F(SyncUIDataTypeControllerTest, StartStopFirstRun) { + EXPECT_CALL(start_callback_, Run(DataTypeController::OK_FIRST_RUN, _, _)); + change_processor_->set_sync_model_has_user_created_nodes(false); + + EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); + EXPECT_FALSE(syncable_service_.syncing()); + Start(); + EXPECT_EQ(DataTypeController::RUNNING, preference_dtc_->state()); + EXPECT_TRUE(syncable_service_.syncing()); + preference_dtc_->Stop(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); + EXPECT_FALSE(syncable_service_.syncing()); +} + +// Start the DTC, but have the service fail association. Verify the callback +// is called with ASSOCIATION_FAILED, the DTC goes to state DISABLED, and the +// service is not syncing. Then stop the DTC. +TEST_F(SyncUIDataTypeControllerTest, StartAssociationFailed) { + EXPECT_CALL(start_callback_, + Run(DataTypeController::ASSOCIATION_FAILED, _, _)); + syncable_service_.set_merge_data_and_start_syncing_error(syncer::SyncError( + FROM_HERE, syncer::SyncError::DATATYPE_ERROR, "Error", type_)); + + EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); + EXPECT_FALSE(syncable_service_.syncing()); + Start(); + EXPECT_EQ(DataTypeController::DISABLED, preference_dtc_->state()); + EXPECT_FALSE(syncable_service_.syncing()); + preference_dtc_->Stop(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); + EXPECT_FALSE(syncable_service_.syncing()); +} + +// Start the DTC but fail to check if there are user created nodes. Verify the +// DTC calls the callback with UNRECOVERABLE_ERROR and that it goes into +// NOT_RUNNING state. Verify the syncable service is not syncing. +TEST_F(SyncUIDataTypeControllerTest, + StartAssociationTriggersUnrecoverableError) { + EXPECT_CALL(start_callback_, + Run(DataTypeController::UNRECOVERABLE_ERROR, _, _)); + change_processor_->set_sync_model_has_user_created_nodes_success(false); + + EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); + EXPECT_FALSE(syncable_service_.syncing()); + Start(); + EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); + EXPECT_FALSE(syncable_service_.syncing()); +} + +// Start the DTC, but then trigger an unrecoverable error. Verify the syncer +// gets stopped and the DTC is in NOT_RUNNING state. +TEST_F(SyncUIDataTypeControllerTest, OnSingleDatatypeUnrecoverableError) { + EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _)); + + EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); + EXPECT_FALSE(syncable_service_.syncing()); + Start(); + EXPECT_TRUE(syncable_service_.syncing()); + + testing::Mock::VerifyAndClearExpectations(&start_callback_); + EXPECT_CALL(model_load_callback_, Run(_, _)); + syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, "error", + syncer::PREFERENCES); + preference_dtc_->OnSingleDataTypeUnrecoverableError(error); +} + +} // namespace +} // namespace sync_driver
diff --git a/components/sync/driver/ui_model_type_controller.cc b/components/sync/driver/ui_model_type_controller.cc new file mode 100644 index 0000000..7e42040 --- /dev/null +++ b/components/sync/driver/ui_model_type_controller.cc
@@ -0,0 +1,42 @@ +// Copyright 2016 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/sync/driver/ui_model_type_controller.h" + +#include "components/sync/api/model_type_service.h" +#include "components/sync/base/model_type.h" +#include "components/sync/core/activation_context.h" +#include "components/sync/driver/sync_client.h" + +namespace sync_driver_v2 { + +using sync_driver::SyncClient; + +UIModelTypeController::UIModelTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const base::Closure& error_callback, + syncer::ModelType model_type, + SyncClient* sync_client) + : NonBlockingDataTypeController(ui_thread, + error_callback, + model_type, + sync_client) {} + +UIModelTypeController::~UIModelTypeController() {} + +bool UIModelTypeController::RunOnModelThread( + const tracked_objects::Location& from_here, + const base::Closure& task) { + RunOnUIThread(from_here, task); + return true; +} + +void UIModelTypeController::RunOnUIThread( + const tracked_objects::Location& from_here, + const base::Closure& task) { + DCHECK(BelongsToUIThread()); + task.Run(); +} + +} // namespace sync_driver_v2
diff --git a/components/sync/driver/ui_model_type_controller.h b/components/sync/driver/ui_model_type_controller.h new file mode 100644 index 0000000..b9378416 --- /dev/null +++ b/components/sync/driver/ui_model_type_controller.h
@@ -0,0 +1,43 @@ +// Copyright 2016 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_SYNC_DRIVER_UI_MODEL_TYPE_CONTROLLER_H_ +#define COMPONENTS_SYNC_DRIVER_UI_MODEL_TYPE_CONTROLLER_H_ + +#include "components/sync/driver/non_blocking_data_type_controller.h" + +namespace sync_driver { +class SyncClient; +} + +namespace sync_driver_v2 { + +// Implementation for Unified Sync and Storage datatypes that reside on the UI +// thread. +class UIModelTypeController : public NonBlockingDataTypeController { + public: + UIModelTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const base::Closure& error_callback, + syncer::ModelType model_type, + sync_driver::SyncClient* sync_client); + + protected: + ~UIModelTypeController() override; + + void RunOnUIThread(const tracked_objects::Location& from_here, + const base::Closure& task) override; + + private: + // NonBlockingDataTypeController implementations. + // Since this is UI model type controller, we hide this function here. + bool RunOnModelThread(const tracked_objects::Location& from_here, + const base::Closure& task) override; + + DISALLOW_COPY_AND_ASSIGN(UIModelTypeController); +}; + +} // namespace sync_driver_v2 + +#endif // COMPONENTS_SYNC_DRIVER_UI_MODEL_TYPE_CONTROLLER_H_
diff --git a/components/sync/driver/ui_model_type_controller_unittest.cc b/components/sync/driver/ui_model_type_controller_unittest.cc new file mode 100644 index 0000000..2a7668f --- /dev/null +++ b/components/sync/driver/ui_model_type_controller_unittest.cc
@@ -0,0 +1,290 @@ +// Copyright 2016 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/sync/driver/ui_model_type_controller.h" + +#include "base/bind.h" +#include "base/callback.h" +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/message_loop/message_loop.h" +#include "base/run_loop.h" +#include "base/sequenced_task_runner.h" +#include "base/test/test_simple_task_runner.h" +#include "base/threading/thread.h" +#include "components/sync/api/fake_model_type_service.h" +#include "components/sync/core/activation_context.h" +#include "components/sync/core/shared_model_type_processor.h" +#include "components/sync/driver/backend_data_type_configurer.h" +#include "components/sync/driver/fake_sync_client.h" +#include "components/sync/engine_impl/commit_queue.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace sync_driver_v2 { + +namespace { + +// Test controller derived from UIModelTypeController. +class TestUIModelTypeController : public UIModelTypeController { + public: + TestUIModelTypeController( + const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, + const base::Closure& error_callback, + syncer::ModelType model_type, + sync_driver::SyncClient* sync_client) + : UIModelTypeController(ui_thread, + error_callback, + model_type, + sync_client) {} + + private: + ~TestUIModelTypeController() override {} +}; + +// A no-op instance of CommitQueue. +class NullCommitQueue : public syncer_v2::CommitQueue { + public: + NullCommitQueue() {} + ~NullCommitQueue() override {} + + void EnqueueForCommit(const syncer_v2::CommitRequestDataList& list) override { + NOTREACHED() << "Not implemented."; + } +}; + +// A class that pretends to be the sync backend. +class MockSyncBackend { + public: + void Connect( + syncer::ModelType type, + std::unique_ptr<syncer_v2::ActivationContext> activation_context) { + enabled_types_.Put(type); + activation_context->type_processor->ConnectSync( + base::WrapUnique(new NullCommitQueue())); + } + + void Disconnect(syncer::ModelType type) { + DCHECK(enabled_types_.Has(type)); + enabled_types_.Remove(type); + } + + private: + syncer::ModelTypeSet enabled_types_; +}; + +// Fake implementation of BackendDataTypeConfigurer that pretends to be Sync +// backend. +class MockBackendDataTypeConfigurer + : public sync_driver::BackendDataTypeConfigurer { + public: + MockBackendDataTypeConfigurer( + MockSyncBackend* backend, + const scoped_refptr<base::TaskRunner>& sync_task_runner) + : backend_(backend), sync_task_runner_(sync_task_runner) {} + ~MockBackendDataTypeConfigurer() override {} + + syncer::ModelTypeSet ConfigureDataTypes( + syncer::ConfigureReason reason, + const DataTypeConfigStateMap& config_state_map, + const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& + ready_task, + const base::Callback<void()>& retry_callback) override { + NOTREACHED() << "Not implemented."; + return syncer::ModelTypeSet(); + } + + void ActivateDirectoryDataType( + syncer::ModelType type, + syncer::ModelSafeGroup group, + sync_driver::ChangeProcessor* change_processor) override { + NOTREACHED() << "Not implemented."; + } + + void DeactivateDirectoryDataType(syncer::ModelType type) override { + NOTREACHED() << "Not implemented."; + } + + void ActivateNonBlockingDataType(syncer::ModelType type, + std::unique_ptr<syncer_v2::ActivationContext> + activation_context) override { + // Post on Sync thread just like the real implementation does. + sync_task_runner_->PostTask( + FROM_HERE, + base::Bind(&MockSyncBackend::Connect, base::Unretained(backend_), type, + base::Passed(std::move(activation_context)))); + } + + void DeactivateNonBlockingDataType(syncer::ModelType type) override { + sync_task_runner_->PostTask(FROM_HERE, + base::Bind(&MockSyncBackend::Disconnect, + base::Unretained(backend_), type)); + } + + private: + MockSyncBackend* backend_; + scoped_refptr<base::TaskRunner> sync_task_runner_; +}; + +} // namespace + +class UIModelTypeControllerTest : public testing::Test, + public sync_driver::FakeSyncClient { + public: + UIModelTypeControllerTest() + : auto_run_tasks_(true), + load_models_callback_called_(false), + association_callback_called_(false), + configurer_(&backend_, ui_loop_.task_runner()) {} + + ~UIModelTypeControllerTest() override {} + + void SetUp() override { + controller_ = new TestUIModelTypeController( + ui_loop_.task_runner(), base::Closure(), syncer::DEVICE_INFO, this); + service_.reset(new syncer_v2::FakeModelTypeService(base::Bind( + &UIModelTypeControllerTest::CreateProcessor, base::Unretained(this)))); + } + + void TearDown() override { + controller_ = NULL; + RunAllTasks(); + } + + syncer_v2::ModelTypeService* GetModelTypeServiceForType( + syncer::ModelType type) override { + return service_.get(); + } + + protected: + std::unique_ptr<syncer_v2::ModelTypeChangeProcessor> CreateProcessor( + syncer::ModelType type, + syncer_v2::ModelTypeService* service) { + std::unique_ptr<syncer_v2::SharedModelTypeProcessor> processor = + base::WrapUnique( + new syncer_v2::SharedModelTypeProcessor(type, service)); + type_processor_ = processor.get(); + return std::move(processor); + } + + void ExpectProcessorConnected(bool isConnected) { + DCHECK(type_processor_); + EXPECT_EQ(isConnected, type_processor_->IsConnected()); + } + + void LoadModels() { + controller_->LoadModels(base::Bind( + &UIModelTypeControllerTest::LoadModelsDone, base::Unretained(this))); + if (!type_processor_->IsAllowingChanges()) { + type_processor_->OnMetadataLoaded( + syncer::SyncError(), + base::WrapUnique(new syncer_v2::MetadataBatch())); + } + + if (auto_run_tasks_) { + RunAllTasks(); + } + } + + void RegisterWithBackend() { + controller_->RegisterWithBackend(&configurer_); + if (auto_run_tasks_) { + RunAllTasks(); + } + } + + void StartAssociating() { + controller_->StartAssociating(base::Bind( + &UIModelTypeControllerTest::AssociationDone, base::Unretained(this))); + // The callback is expected to be promptly called. + EXPECT_TRUE(association_callback_called_); + } + + void DeactivateDataTypeAndStop() { + controller_->DeactivateDataType(&configurer_); + controller_->Stop(); + if (auto_run_tasks_) { + RunAllTasks(); + } + } + + // These threads can ping-pong for a bit so we run the UI thread twice. + void RunAllTasks() { base::RunLoop().RunUntilIdle(); } + + void SetAutoRunTasks(bool auto_run_tasks) { + auto_run_tasks_ = auto_run_tasks; + } + + void LoadModelsDone(syncer::ModelType type, syncer::SyncError error) { + load_models_callback_called_ = true; + load_models_error_ = error; + } + + void AssociationDone(sync_driver::DataTypeController::ConfigureResult result, + const syncer::SyncMergeResult& local_merge_result, + const syncer::SyncMergeResult& syncer_merge_result) { + EXPECT_EQ(sync_driver::DataTypeController::OK, result); + association_callback_called_ = true; + } + + syncer_v2::SharedModelTypeProcessor* type_processor_; + scoped_refptr<TestUIModelTypeController> controller_; + + bool auto_run_tasks_; + bool load_models_callback_called_; + syncer::SyncError load_models_error_; + bool association_callback_called_; + base::MessageLoopForUI ui_loop_; + MockSyncBackend backend_; + MockBackendDataTypeConfigurer configurer_; + std::unique_ptr<syncer_v2::FakeModelTypeService> service_; +}; + +TEST_F(UIModelTypeControllerTest, InitialState) { + EXPECT_EQ(syncer::DEVICE_INFO, controller_->type()); + EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); +} + +TEST_F(UIModelTypeControllerTest, LoadModelsOnUIThread) { + LoadModels(); + EXPECT_EQ(sync_driver::DataTypeController::MODEL_LOADED, + controller_->state()); + EXPECT_TRUE(load_models_callback_called_); + EXPECT_FALSE(load_models_error_.IsSet()); + ExpectProcessorConnected(false); +} + +TEST_F(UIModelTypeControllerTest, LoadModelsTwice) { + LoadModels(); + SetAutoRunTasks(false); + LoadModels(); + EXPECT_EQ(sync_driver::DataTypeController::MODEL_LOADED, + controller_->state()); + // The second LoadModels call should set the error. + EXPECT_TRUE(load_models_error_.IsSet()); +} + +TEST_F(UIModelTypeControllerTest, ActivateDataTypeOnUIThread) { + LoadModels(); + EXPECT_EQ(sync_driver::DataTypeController::MODEL_LOADED, + controller_->state()); + RegisterWithBackend(); + ExpectProcessorConnected(true); + + StartAssociating(); + EXPECT_EQ(sync_driver::DataTypeController::RUNNING, controller_->state()); +} + +TEST_F(UIModelTypeControllerTest, Stop) { + LoadModels(); + RegisterWithBackend(); + ExpectProcessorConnected(true); + StartAssociating(); + + DeactivateDataTypeAndStop(); + EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); +} + +} // namespace sync_driver_v2
diff --git a/components/sync_driver/user_selectable_sync_type.h b/components/sync/driver/user_selectable_sync_type.h similarity index 100% rename from components/sync_driver/user_selectable_sync_type.h rename to components/sync/driver/user_selectable_sync_type.h
diff --git a/components/sync/engine/events/clear_server_data_request_event.h b/components/sync/engine/events/clear_server_data_request_event.h index 2bc7b70..fd2b2554 100644 --- a/components/sync/engine/events/clear_server_data_request_event.h +++ b/components/sync/engine/events/clear_server_data_request_event.h
@@ -11,14 +11,13 @@ #include "base/macros.h" #include "base/time/time.h" #include "base/values.h" -#include "components/sync/base/sync_export.h" #include "components/sync/engine/events/protocol_event.h" #include "components/sync/protocol/sync.pb.h" namespace syncer { // An event representing a ClearServerData request message sent to the server. -class SYNC_EXPORT ClearServerDataRequestEvent : public ProtocolEvent { +class ClearServerDataRequestEvent : public ProtocolEvent { public: ClearServerDataRequestEvent(base::Time timestamp, const sync_pb::ClientToServerMessage& request);
diff --git a/components/sync/engine/events/clear_server_data_response_event.h b/components/sync/engine/events/clear_server_data_response_event.h index af7b23e..5844c851 100644 --- a/components/sync/engine/events/clear_server_data_response_event.h +++ b/components/sync/engine/events/clear_server_data_response_event.h
@@ -11,7 +11,6 @@ #include "base/macros.h" #include "base/time/time.h" #include "base/values.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/syncer_error.h" #include "components/sync/engine/events/protocol_event.h" #include "components/sync/protocol/sync.pb.h" @@ -19,7 +18,7 @@ namespace syncer { // An event representing a ClearServerData response event from the server. -class SYNC_EXPORT ClearServerDataResponseEvent : public ProtocolEvent { +class ClearServerDataResponseEvent : public ProtocolEvent { public: ClearServerDataResponseEvent(base::Time timestamp, SyncerError result,
diff --git a/components/sync/engine/events/commit_request_event.h b/components/sync/engine/events/commit_request_event.h index af91ecd..13ac7ab 100644 --- a/components/sync/engine/events/commit_request_event.h +++ b/components/sync/engine/events/commit_request_event.h
@@ -13,14 +13,13 @@ #include "base/time/time.h" #include "base/values.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/engine/events/protocol_event.h" #include "components/sync/protocol/sync.pb.h" namespace syncer { // An event representing a commit request message sent to the server. -class SYNC_EXPORT CommitRequestEvent : public ProtocolEvent { +class CommitRequestEvent : public ProtocolEvent { public: CommitRequestEvent(base::Time timestamp, size_t num_items,
diff --git a/components/sync/engine/events/commit_response_event.h b/components/sync/engine/events/commit_response_event.h index b31cd191..fa166804 100644 --- a/components/sync/engine/events/commit_response_event.h +++ b/components/sync/engine/events/commit_response_event.h
@@ -12,7 +12,6 @@ #include "base/macros.h" #include "base/time/time.h" #include "base/values.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/syncer_error.h" #include "components/sync/engine/events/protocol_event.h" #include "components/sync/protocol/sync.pb.h" @@ -20,7 +19,7 @@ namespace syncer { // An event representing a commit response event from the server. -class SYNC_EXPORT CommitResponseEvent : public ProtocolEvent { +class CommitResponseEvent : public ProtocolEvent { public: CommitResponseEvent(base::Time timestamp, SyncerError result,
diff --git a/components/sync/engine/events/configure_get_updates_request_event.h b/components/sync/engine/events/configure_get_updates_request_event.h index c60ed51..d004499 100644 --- a/components/sync/engine/events/configure_get_updates_request_event.h +++ b/components/sync/engine/events/configure_get_updates_request_event.h
@@ -11,14 +11,13 @@ #include "base/macros.h" #include "base/time/time.h" #include "base/values.h" -#include "components/sync/base/sync_export.h" #include "components/sync/engine/events/protocol_event.h" #include "components/sync/protocol/sync.pb.h" namespace syncer { // An event representing a configure GetUpdates request to the server. -class SYNC_EXPORT ConfigureGetUpdatesRequestEvent : public ProtocolEvent { +class ConfigureGetUpdatesRequestEvent : public ProtocolEvent { public: ConfigureGetUpdatesRequestEvent( base::Time timestamp,
diff --git a/components/sync/engine/events/get_updates_response_event.h b/components/sync/engine/events/get_updates_response_event.h index 43cf0788..9534aea 100644 --- a/components/sync/engine/events/get_updates_response_event.h +++ b/components/sync/engine/events/get_updates_response_event.h
@@ -11,7 +11,6 @@ #include "base/macros.h" #include "base/time/time.h" #include "base/values.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/syncer_error.h" #include "components/sync/engine/events/protocol_event.h" #include "components/sync/protocol/sync.pb.h" @@ -22,7 +21,7 @@ // // Unlike the events for the request message, the response events are generic // and do not vary for each type of GetUpdate cycle. -class SYNC_EXPORT GetUpdatesResponseEvent : public ProtocolEvent { +class GetUpdatesResponseEvent : public ProtocolEvent { public: GetUpdatesResponseEvent(base::Time timestamp, const sync_pb::ClientToServerResponse& response,
diff --git a/components/sync/engine/events/normal_get_updates_request_event.h b/components/sync/engine/events/normal_get_updates_request_event.h index a38d2584..e6babbda 100644 --- a/components/sync/engine/events/normal_get_updates_request_event.h +++ b/components/sync/engine/events/normal_get_updates_request_event.h
@@ -12,7 +12,6 @@ #include "base/time/time.h" #include "base/values.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/engine/events/protocol_event.h" #include "components/sync/protocol/sync.pb.h" @@ -23,7 +22,7 @@ } // namespace sessions // An event representing a 'normal mode' GetUpdate request to the server. -class SYNC_EXPORT NormalGetUpdatesRequestEvent : public ProtocolEvent { +class NormalGetUpdatesRequestEvent : public ProtocolEvent { public: NormalGetUpdatesRequestEvent(base::Time timestamp, const sessions::NudgeTracker& nudge_tracker,
diff --git a/components/sync/engine/events/poll_get_updates_request_event.h b/components/sync/engine/events/poll_get_updates_request_event.h index 0c2076b..1e5962c 100644 --- a/components/sync/engine/events/poll_get_updates_request_event.h +++ b/components/sync/engine/events/poll_get_updates_request_event.h
@@ -12,7 +12,6 @@ #include "base/time/time.h" #include "base/values.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/engine/events/protocol_event.h" #include "components/sync/protocol/sync.pb.h" @@ -23,7 +22,7 @@ } // namespace sessions // An event representing a poll request sent to the server. -class SYNC_EXPORT PollGetUpdatesRequestEvent : public ProtocolEvent { +class PollGetUpdatesRequestEvent : public ProtocolEvent { public: PollGetUpdatesRequestEvent(base::Time timestamp, const sync_pb::ClientToServerMessage& request);
diff --git a/components/sync/engine/events/protocol_event.h b/components/sync/engine/events/protocol_event.h index 41a06acd..ba767e1 100644 --- a/components/sync/engine/events/protocol_event.h +++ b/components/sync/engine/events/protocol_event.h
@@ -10,7 +10,6 @@ #include "base/time/time.h" #include "base/values.h" -#include "components/sync/base/sync_export.h" namespace syncer { @@ -28,7 +27,7 @@ // its own custom serialization routines. For example, the "configure" // GetUpdates request will include information about its "origin" in its debug // info. -class SYNC_EXPORT ProtocolEvent { +class ProtocolEvent { public: ProtocolEvent(); virtual ~ProtocolEvent();
diff --git a/components/sync/engine/model_safe_worker.h b/components/sync/engine/model_safe_worker.h index df29630..42eb29c 100644 --- a/components/sync/engine/model_safe_worker.h +++ b/components/sync/engine/model_safe_worker.h
@@ -17,7 +17,6 @@ #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/syncer_error.h" namespace base { @@ -49,7 +48,7 @@ // SyncBackendRegistrar involvement. }; -SYNC_EXPORT std::string ModelSafeGroupToString(ModelSafeGroup group); +std::string ModelSafeGroupToString(ModelSafeGroup group); // WorkerLoopDestructionObserver is notified when the thread where it works // is going to be destroyed. @@ -68,9 +67,8 @@ // a thread and does actual work on that thread. On the destruction of that // thread, the affiliated worker is effectively disabled to do more // work and will notify its observer. -class SYNC_EXPORT ModelSafeWorker - : public base::RefCountedThreadSafe<ModelSafeWorker>, - public base::MessageLoop::DestructionObserver { +class ModelSafeWorker : public base::RefCountedThreadSafe<ModelSafeWorker>, + public base::MessageLoop::DestructionObserver { public: // Subclass should implement to observe destruction of the loop where // it actually does work. Called on UI thread immediately after worker is @@ -151,17 +149,16 @@ typedef std::map<ModelType, ModelSafeGroup> ModelSafeRoutingInfo; // Caller takes ownership of return value. -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> ModelSafeRoutingInfoToValue( +std::unique_ptr<base::DictionaryValue> ModelSafeRoutingInfoToValue( const ModelSafeRoutingInfo& routing_info); -SYNC_EXPORT std::string ModelSafeRoutingInfoToString( +std::string ModelSafeRoutingInfoToString( const ModelSafeRoutingInfo& routing_info); -SYNC_EXPORT ModelTypeSet -GetRoutingInfoTypes(const ModelSafeRoutingInfo& routing_info); +ModelTypeSet GetRoutingInfoTypes(const ModelSafeRoutingInfo& routing_info); -SYNC_EXPORT ModelSafeGroup -GetGroupForModelType(const ModelType type, const ModelSafeRoutingInfo& routes); +ModelSafeGroup GetGroupForModelType(const ModelType type, + const ModelSafeRoutingInfo& routes); } // namespace syncer
diff --git a/components/sync/engine/passive_model_worker.h b/components/sync/engine/passive_model_worker.h index 71d47d1d..a8ddcfd 100644 --- a/components/sync/engine/passive_model_worker.h +++ b/components/sync/engine/passive_model_worker.h
@@ -7,7 +7,6 @@ #include "base/compiler_specific.h" #include "base/macros.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/syncer_error.h" #include "components/sync/engine/model_safe_worker.h" @@ -16,7 +15,7 @@ // Implementation of ModelSafeWorker for passive types. All work is // done on the same thread DoWorkAndWaitUntilDone (i.e., the sync // thread). -class SYNC_EXPORT PassiveModelWorker : public ModelSafeWorker { +class PassiveModelWorker : public ModelSafeWorker { public: explicit PassiveModelWorker(WorkerLoopDestructionObserver* observer);
diff --git a/components/sync/engine/polling_constants.h b/components/sync/engine/polling_constants.h index 2690a74..1d72848e 100644 --- a/components/sync/engine/polling_constants.h +++ b/components/sync/engine/polling_constants.h
@@ -9,17 +9,15 @@ #include <stdint.h> -#include "components/sync/base/sync_export.h" - namespace syncer { -SYNC_EXPORT extern const int64_t kDefaultShortPollIntervalSeconds; -SYNC_EXPORT extern const int64_t kDefaultLongPollIntervalSeconds; -SYNC_EXPORT extern const int64_t kMaxBackoffSeconds; -SYNC_EXPORT extern const int kBackoffRandomizationFactor; -SYNC_EXPORT extern const int kInitialBackoffRetrySeconds; -SYNC_EXPORT extern const int kInitialBackoffShortRetrySeconds; -SYNC_EXPORT extern const int kInitialBackoffImmediateRetrySeconds; +extern const int64_t kDefaultShortPollIntervalSeconds; +extern const int64_t kDefaultLongPollIntervalSeconds; +extern const int64_t kMaxBackoffSeconds; +extern const int kBackoffRandomizationFactor; +extern const int kInitialBackoffRetrySeconds; +extern const int kInitialBackoffShortRetrySeconds; +extern const int kInitialBackoffImmediateRetrySeconds; } // namespace syncer
diff --git a/components/sync/engine/sync_status.h b/components/sync/engine/sync_status.h index 7f6f38f..0ccf6443 100644 --- a/components/sync/engine/sync_status.h +++ b/components/sync/engine/sync_status.h
@@ -10,7 +10,6 @@ #include "base/time/time.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/core/sync_encryption_handler.h" #include "components/sync/protocol/sync_protocol_error.h" @@ -22,7 +21,7 @@ // it to track and report on the sync engine's internal state, and the functions // in sync_ui_util.cc which convert the contents of this struct into a // DictionaryValue used to populate the about:sync summary tab. -struct SYNC_EXPORT SyncStatus { +struct SyncStatus { SyncStatus(); SyncStatus(const SyncStatus& other); ~SyncStatus();
diff --git a/components/sync/engine_impl/apply_control_data_updates.h b/components/sync/engine_impl/apply_control_data_updates.h index 868eb15..29a2c8a 100644 --- a/components/sync/engine_impl/apply_control_data_updates.h +++ b/components/sync/engine_impl/apply_control_data_updates.h
@@ -5,8 +5,6 @@ #ifndef COMPONENTS_SYNC_ENGINE_IMPL_APPLY_CONTROL_DATA_UPDATES_H_ #define COMPONENTS_SYNC_ENGINE_IMPL_APPLY_CONTROL_DATA_UPDATES_H_ -#include "components/sync/base/sync_export.h" - namespace syncer { class Cryptographer; @@ -17,7 +15,7 @@ class WriteTransaction; } -SYNC_EXPORT void ApplyControlDataUpdates(syncable::Directory* dir); +void ApplyControlDataUpdates(syncable::Directory* dir); void ApplyNigoriUpdate(syncable::WriteTransaction* trans, syncable::MutableEntry* const entry, Cryptographer* cryptographer);
diff --git a/components/sync/engine_impl/backoff_delay_provider.h b/components/sync/engine_impl/backoff_delay_provider.h index 7f599e2..454340b 100644 --- a/components/sync/engine_impl/backoff_delay_provider.h +++ b/components/sync/engine_impl/backoff_delay_provider.h
@@ -7,7 +7,6 @@ #include "base/macros.h" #include "base/time/time.h" -#include "components/sync/base/sync_export.h" namespace syncer { @@ -16,7 +15,7 @@ } // A component used to get time delays associated with exponential backoff. -class SYNC_EXPORT BackoffDelayProvider { +class BackoffDelayProvider { public: // Factory function to create a standard BackoffDelayProvider. static BackoffDelayProvider* FromDefaults();
diff --git a/components/sync/engine_impl/clear_server_data.h b/components/sync/engine_impl/clear_server_data.h index f0e11ba..74f57aa0 100644 --- a/components/sync/engine_impl/clear_server_data.h +++ b/components/sync/engine_impl/clear_server_data.h
@@ -7,7 +7,6 @@ #include <string> -#include "components/sync/base/sync_export.h" #include "components/sync/base/syncer_error.h" #include "components/sync/protocol/sync.pb.h" @@ -22,7 +21,7 @@ // An instance of this class corresponds to a single operation and is // responsible for building a request, sending it, and interpreting the // response. -class SYNC_EXPORT ClearServerData { +class ClearServerData { public: explicit ClearServerData(const std::string& account_name); ~ClearServerData();
diff --git a/components/sync/engine_impl/commit.h b/components/sync/engine_impl/commit.h index aec6809..fcab48b 100644 --- a/components/sync/engine_impl/commit.h +++ b/components/sync/engine_impl/commit.h
@@ -14,7 +14,6 @@ #include "base/macros.h" #include "components/sync/base/extensions_activity.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/syncer_error.h" #include "components/sync/engine/model_safe_worker.h" #include "components/sync/engine_impl/commit_contribution.h" @@ -39,7 +38,7 @@ // been acceptable to let this class be a dumb container object, it turns out // that there was no other convenient place to put the Init() and // PostAndProcessCommitResponse() functions. So they ended up here. -class SYNC_EXPORT Commit { +class Commit { public: typedef std::map<ModelType, std::unique_ptr<CommitContribution>> ContributionMap;
diff --git a/components/sync/engine_impl/commit_contribution.h b/components/sync/engine_impl/commit_contribution.h index 8163606c..714ae8a 100644 --- a/components/sync/engine_impl/commit_contribution.h +++ b/components/sync/engine_impl/commit_contribution.h
@@ -7,7 +7,6 @@ #include <stddef.h> -#include "components/sync/base/sync_export.h" #include "components/sync/base/syncer_error.h" #include "components/sync/protocol/sync.pb.h" #include "components/sync/sessions_impl/status_controller.h" @@ -22,7 +21,7 @@ // have been selected from a CommitContributor and prepared for commit. // // This class handles the bookkeeping related to the commit of these items. -class SYNC_EXPORT CommitContribution { +class CommitContribution { public: CommitContribution(); virtual ~CommitContribution() = 0;
diff --git a/components/sync/engine_impl/commit_contributor.h b/components/sync/engine_impl/commit_contributor.h index 71de069..503acfe 100644 --- a/components/sync/engine_impl/commit_contributor.h +++ b/components/sync/engine_impl/commit_contributor.h
@@ -8,7 +8,6 @@ #include <cstddef> #include <memory> -#include "components/sync/base/sync_export.h" namespace syncer { @@ -22,7 +21,7 @@ // // When asked, it can return CommitContribution objects that contain a set of // items to be committed from this source. -class SYNC_EXPORT CommitContributor { +class CommitContributor { public: CommitContributor(); virtual ~CommitContributor() = 0;
diff --git a/components/sync/engine_impl/commit_processor.h b/components/sync/engine_impl/commit_processor.h index ce6ddd2..af1b70b 100644 --- a/components/sync/engine_impl/commit_processor.h +++ b/components/sync/engine_impl/commit_processor.h
@@ -12,7 +12,6 @@ #include "base/macros.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/engine/model_safe_worker.h" #include "components/sync/engine_impl/commit.h" #include "components/sync/sessions_impl/model_type_registry.h" @@ -32,7 +31,7 @@ // Many methods allow the caller to specify a subset of types on which the // operation is to be applied. It is a logic error if the supplied set of types // contains a type which was not previously registered. -class SYNC_EXPORT CommitProcessor { +class CommitProcessor { public: // Contructs a CommitProcessor from a map of CommitContributors. // The CommitProcessor does not own this map.
diff --git a/components/sync/engine_impl/commit_queue.h b/components/sync/engine_impl/commit_queue.h index 7001a25..cbe90eb 100644 --- a/components/sync/engine_impl/commit_queue.h +++ b/components/sync/engine_impl/commit_queue.h
@@ -10,7 +10,7 @@ namespace syncer_v2 { // Interface used by a synced data type to issue requests to the sync backend. -class SYNC_EXPORT CommitQueue { +class CommitQueue { public: CommitQueue(); virtual ~CommitQueue();
diff --git a/components/sync/engine_impl/commit_util.h b/components/sync/engine_impl/commit_util.h index acc86a2..f3d06735 100644 --- a/components/sync/engine_impl/commit_util.h +++ b/components/sync/engine_impl/commit_util.h
@@ -11,7 +11,6 @@ #include "components/sync/base/extensions_activity.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/protocol/sync.pb.h" namespace sync_pb { @@ -31,21 +30,20 @@ namespace commit_util { // Adds bookmark extensions activity report to |message|. -SYNC_EXPORT void AddExtensionsActivityToMessage( +void AddExtensionsActivityToMessage( ExtensionsActivity* activity, ExtensionsActivity::Records* extensions_activity_buffer, sync_pb::CommitMessage* message); // Fills the config_params field of |message|. -SYNC_EXPORT void AddClientConfigParamsToMessage( - ModelTypeSet enabled_types, - bool cookie_jar_mismatch, - sync_pb::CommitMessage* message); +void AddClientConfigParamsToMessage(ModelTypeSet enabled_types, + bool cookie_jar_mismatch, + sync_pb::CommitMessage* message); // Takes a snapshot of |meta_entry| and puts it into a protobuf suitable for use // in a commit request message. -SYNC_EXPORT void BuildCommitItem(const syncable::Entry& meta_entry, - sync_pb::SyncEntity* sync_entry); +void BuildCommitItem(const syncable::Entry& meta_entry, + sync_pb::SyncEntity* sync_entry); // Process a single commit response. Updates the entry's SERVER fields using // |pb_commit_response| and |pb_committed_entry|. @@ -53,7 +51,6 @@ // The |deleted_folders| parameter is a set of IDs that represent deleted // folders. This function will add its entry's ID to this set if it finds // itself processing a folder deletion. -SYNC_EXPORT sync_pb::CommitResponse::ResponseType ProcessSingleCommitResponse( syncable::BaseWriteTransaction* trans, const sync_pb::CommitResponse_EntryResponse& server_entry,
diff --git a/components/sync/engine_impl/directory_commit_contribution.h b/components/sync/engine_impl/directory_commit_contribution.h index 84a31425..ecdd36a 100644 --- a/components/sync/engine_impl/directory_commit_contribution.h +++ b/components/sync/engine_impl/directory_commit_contribution.h
@@ -14,7 +14,6 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/syncer_error.h" #include "components/sync/engine_impl/commit_contribution.h" #include "components/sync/protocol/sync.pb.h" @@ -37,7 +36,7 @@ // This class handles the bookkeeping related to the commit of these items, // including processing the commit response message and setting and unsetting // the SYNCING bits. -class SYNC_EXPORT DirectoryCommitContribution : public CommitContribution { +class DirectoryCommitContribution : public CommitContribution { public: // This destructor will DCHECK if UnsetSyncingBits() has not been called yet. ~DirectoryCommitContribution() override;
diff --git a/components/sync/engine_impl/directory_update_handler.h b/components/sync/engine_impl/directory_update_handler.h index 29ce2dc..6749653 100644 --- a/components/sync/engine_impl/directory_update_handler.h +++ b/components/sync/engine_impl/directory_update_handler.h
@@ -11,7 +11,6 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/syncer_error.h" #include "components/sync/engine_impl/process_updates_util.h" #include "components/sync/engine_impl/update_handler.h" @@ -41,7 +40,7 @@ // Each instance of this class represents a particular type in the // syncable::Directory. It can store and retreive that type's progress markers. // It can also process a set of received SyncEntities and store their data. -class SYNC_EXPORT DirectoryUpdateHandler : public UpdateHandler { +class DirectoryUpdateHandler : public UpdateHandler { public: DirectoryUpdateHandler(syncable::Directory* dir, ModelType type,
diff --git a/components/sync/engine_impl/get_commit_ids.h b/components/sync/engine_impl/get_commit_ids.h index fa318b3..9ba4214 100644 --- a/components/sync/engine_impl/get_commit_ids.h +++ b/components/sync/engine_impl/get_commit_ids.h
@@ -11,7 +11,6 @@ #include <vector> #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/syncable/directory.h" using std::vector; @@ -31,10 +30,10 @@ // // This function also enforces some position ordering constraints that are no // longer necessary. We should relax those constraints. See crbug.com/287938. -SYNC_EXPORT void GetCommitIdsForType(syncable::BaseTransaction* trans, - ModelType type, - size_t max_entries, - std::vector<int64_t>* out); +void GetCommitIdsForType(syncable::BaseTransaction* trans, + ModelType type, + size_t max_entries, + std::vector<int64_t>* out); } // namespace syncer
diff --git a/components/sync/engine_impl/get_updates_delegate.h b/components/sync/engine_impl/get_updates_delegate.h index 73ad808..376b1e1 100644 --- a/components/sync/engine_impl/get_updates_delegate.h +++ b/components/sync/engine_impl/get_updates_delegate.h
@@ -22,7 +22,7 @@ // GetUpdate type (normal, configuration, poll). The GetUpdatesProcessor is // given an appropriate GetUpdatesDelegate to handle type specific functionality // on construction. -class SYNC_EXPORT GetUpdatesDelegate { +class GetUpdatesDelegate { public: GetUpdatesDelegate(); virtual ~GetUpdatesDelegate() = 0; @@ -42,7 +42,7 @@ }; // Functionality specific to the normal GetUpdate request. -class SYNC_EXPORT NormalGetUpdatesDelegate : public GetUpdatesDelegate { +class NormalGetUpdatesDelegate : public GetUpdatesDelegate { public: explicit NormalGetUpdatesDelegate( const sessions::NudgeTracker& nudge_tracker); @@ -68,7 +68,7 @@ }; // Functionality specific to the configure GetUpdate request. -class SYNC_EXPORT ConfigureGetUpdatesDelegate : public GetUpdatesDelegate { +class ConfigureGetUpdatesDelegate : public GetUpdatesDelegate { public: ConfigureGetUpdatesDelegate( sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source); @@ -100,7 +100,7 @@ }; // Functionality specific to the poll GetUpdate request. -class SYNC_EXPORT PollGetUpdatesDelegate : public GetUpdatesDelegate { +class PollGetUpdatesDelegate : public GetUpdatesDelegate { public: PollGetUpdatesDelegate(); ~PollGetUpdatesDelegate() override;
diff --git a/components/sync/engine_impl/get_updates_processor.h b/components/sync/engine_impl/get_updates_processor.h index 3695fc58..8a079d3 100644 --- a/components/sync/engine_impl/get_updates_processor.h +++ b/components/sync/engine_impl/get_updates_processor.h
@@ -11,7 +11,6 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/engine/model_safe_worker.h" #include "components/sync/protocol/sync.pb.h" #include "components/sync/sessions_impl/model_type_registry.h" @@ -42,7 +41,7 @@ // Most methods allow the caller to specify a subset of types on which the // operation is to be applied. It is a logic error if the supplied set of types // contains a type which was not previously registered with the manager. -class SYNC_EXPORT GetUpdatesProcessor { +class GetUpdatesProcessor { public: explicit GetUpdatesProcessor(UpdateHandlerMap* update_handler_map, const GetUpdatesDelegate& delegate);
diff --git a/components/sync/engine_impl/get_updates_processor_unittest.cc b/components/sync/engine_impl/get_updates_processor_unittest.cc index cc3be1c7..d4b9e67 100644 --- a/components/sync/engine_impl/get_updates_processor_unittest.cc +++ b/components/sync/engine_impl/get_updates_processor_unittest.cc
@@ -91,7 +91,7 @@ private: ModelTypeSet enabled_types_; UpdateHandlerMap update_handler_map_; - STLValueDeleter<UpdateHandlerMap> update_handler_deleter_; + base::STLValueDeleter<UpdateHandlerMap> update_handler_deleter_; std::unique_ptr<GetUpdatesProcessor> get_updates_processor_; DISALLOW_COPY_AND_ASSIGN(GetUpdatesProcessorTest);
diff --git a/components/sync/engine_impl/model_type_worker.h b/components/sync/engine_impl/model_type_worker.h index 5b6f5294..b2014ab 100644 --- a/components/sync/engine_impl/model_type_worker.h +++ b/components/sync/engine_impl/model_type_worker.h
@@ -15,7 +15,6 @@ #include "base/threading/non_thread_safe.h" #include "components/sync/base/cryptographer.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/core/non_blocking_sync_common.h" #include "components/sync/core/sync_encryption_handler.h" #include "components/sync/engine_impl/commit_contributor.h" @@ -54,10 +53,10 @@ // example, if the sync server sends down an update for a sync entity that is // currently pending for commit, this object will detect this condition and // cancel the pending commit. -class SYNC_EXPORT ModelTypeWorker : public syncer::UpdateHandler, - public syncer::CommitContributor, - public CommitQueue, - public base::NonThreadSafe { +class ModelTypeWorker : public syncer::UpdateHandler, + public syncer::CommitContributor, + public CommitQueue, + public base::NonThreadSafe { public: ModelTypeWorker(syncer::ModelType type, const sync_pb::DataTypeState& initial_state,
diff --git a/components/sync/engine_impl/net/server_connection_manager.h b/components/sync/engine_impl/net/server_connection_manager.h index ba35d1d..53ad716a 100644 --- a/components/sync/engine_impl/net/server_connection_manager.h +++ b/components/sync/engine_impl/net/server_connection_manager.h
@@ -19,7 +19,6 @@ #include "base/threading/non_thread_safe.h" #include "base/threading/thread_checker.h" #include "components/sync/base/cancelation_observer.h" -#include "components/sync/base/sync_export.h" #include "components/sync/syncable/syncable_id.h" namespace sync_pb { @@ -41,7 +40,7 @@ // HttpResponse gathers the relevant output properties of an HTTP request. // Depending on the value of the server_status code, response_code, and // content_length may not be valid. -struct SYNC_EXPORT HttpResponse { +struct HttpResponse { enum ServerConnectionCode { // For uninitialized state. NONE, @@ -98,7 +97,7 @@ : connection_code(code) {} }; -class SYNC_EXPORT ServerConnectionEventListener { +class ServerConnectionEventListener { public: virtual void OnServerConnectionEvent(const ServerConnectionEvent& event) = 0; @@ -109,7 +108,7 @@ // Use this class to interact with the sync server. // The ServerConnectionManager currently supports POSTing protocol buffers. // -class SYNC_EXPORT ServerConnectionManager : public CancelationObserver { +class ServerConnectionManager : public CancelationObserver { public: // buffer_in - will be POSTed // buffer_out - string will be overwritten with response
diff --git a/components/sync/engine_impl/nudge_handler.h b/components/sync/engine_impl/nudge_handler.h index f6233b1..ce992ce5 100644 --- a/components/sync/engine_impl/nudge_handler.h +++ b/components/sync/engine_impl/nudge_handler.h
@@ -7,11 +7,10 @@ #include "base/compiler_specific.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" namespace syncer { -class SYNC_EXPORT NudgeHandler { +class NudgeHandler { public: NudgeHandler(); virtual ~NudgeHandler();
diff --git a/components/sync/engine_impl/sync_cycle_event.h b/components/sync/engine_impl/sync_cycle_event.h index a3d51e73..53b99b3 100644 --- a/components/sync/engine_impl/sync_cycle_event.h +++ b/components/sync/engine_impl/sync_cycle_event.h
@@ -5,14 +5,13 @@ #ifndef COMPONENTS_SYNC_ENGINE_IMPL_SYNC_CYCLE_EVENT_H_ #define COMPONENTS_SYNC_ENGINE_IMPL_SYNC_CYCLE_EVENT_H_ -#include "components/sync/base/sync_export.h" #include "components/sync/sessions/sync_session_snapshot.h" namespace syncer { struct SyncProtocolError; -struct SYNC_EXPORT SyncCycleEvent { +struct SyncCycleEvent { enum EventCause { //////////////////////////////////////////////////////////////// // Sent on entry of Syncer state machine
diff --git a/components/sync/engine_impl/sync_engine_event_listener.h b/components/sync/engine_impl/sync_engine_event_listener.h index 1f33efc..b590ffe 100644 --- a/components/sync/engine_impl/sync_engine_event_listener.h +++ b/components/sync/engine_impl/sync_engine_event_listener.h
@@ -7,7 +7,6 @@ #include "base/time/time.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" namespace syncer { @@ -15,7 +14,7 @@ struct SyncCycleEvent; class ProtocolEvent; -class SYNC_EXPORT SyncEngineEventListener { +class SyncEngineEventListener { public: SyncEngineEventListener();
diff --git a/components/sync/engine_impl/sync_scheduler.h b/components/sync/engine_impl/sync_scheduler.h index 81bcca0..97d9211 100644 --- a/components/sync/engine_impl/sync_scheduler.h +++ b/components/sync/engine_impl/sync_scheduler.h
@@ -13,7 +13,6 @@ #include "base/compiler_specific.h" #include "base/time/time.h" #include "components/sync/base/invalidation_interface.h" -#include "components/sync/base/sync_export.h" #include "components/sync/engine_impl/nudge_source.h" #include "components/sync/sessions_impl/sync_session.h" @@ -25,7 +24,7 @@ struct ServerConnectionEvent; -struct SYNC_EXPORT ConfigurationParams { +struct ConfigurationParams { ConfigurationParams(); ConfigurationParams( const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource& source, @@ -48,7 +47,7 @@ base::Closure retry_task; }; -struct SYNC_EXPORT ClearParams { +struct ClearParams { explicit ClearParams(const base::Closure& report_success_task); ClearParams(const ClearParams& other); ~ClearParams(); @@ -57,7 +56,7 @@ base::Closure report_success_task; }; -class SYNC_EXPORT SyncScheduler : public sessions::SyncSession::Delegate { +class SyncScheduler : public sessions::SyncSession::Delegate { public: enum Mode { // In this mode, the thread only performs configuration tasks. This is
diff --git a/components/sync/engine_impl/sync_scheduler_impl.h b/components/sync/engine_impl/sync_scheduler_impl.h index 7db93f1..5d8e572 100644 --- a/components/sync/engine_impl/sync_scheduler_impl.h +++ b/components/sync/engine_impl/sync_scheduler_impl.h
@@ -19,7 +19,6 @@ #include "base/threading/non_thread_safe.h" #include "base/time/time.h" #include "base/timer/timer.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/weak_handle.h" #include "components/sync/engine/polling_constants.h" #include "components/sync/engine_impl/net/server_connection_manager.h" @@ -38,8 +37,7 @@ struct ModelNeutralState; } -class SYNC_EXPORT SyncSchedulerImpl : public SyncScheduler, - public base::NonThreadSafe { +class SyncSchedulerImpl : public SyncScheduler, public base::NonThreadSafe { public: // |name| is a display string to identify the syncer thread. Takes // |ownership of |syncer| and |delay_provider|. @@ -121,7 +119,7 @@ FRIEND_TEST_ALL_PREFIXES(SyncSchedulerTest, FailedRetry); FRIEND_TEST_ALL_PREFIXES(SyncSchedulerTest, ReceiveNewRetryDelay); - struct SYNC_EXPORT WaitInterval { + struct WaitInterval { enum Mode { // Uninitialized state, should not be set in practice. UNKNOWN = -1,
diff --git a/components/sync/engine_impl/syncer.h b/components/sync/engine_impl/syncer.h index 71c7e4eb..8953bc57 100644 --- a/components/sync/engine_impl/syncer.h +++ b/components/sync/engine_impl/syncer.h
@@ -16,7 +16,6 @@ #include "base/synchronization/lock.h" #include "components/sync/base/extensions_activity.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/engine_impl/conflict_resolver.h" #include "components/sync/engine_impl/syncer_types.h" #include "components/sync/sessions_impl/sync_session.h" @@ -36,7 +35,7 @@ // A Syncer instance expects to run on a dedicated thread. Calls to SyncShare() // may take an unbounded amount of time because it may block on network I/O, on // lock contention, or on tasks posted to other threads. -class SYNC_EXPORT Syncer { +class Syncer { public: typedef std::vector<int64_t> UnsyncedMetaHandles;
diff --git a/components/sync/engine_impl/syncer_proto_util.h b/components/sync/engine_impl/syncer_proto_util.h index 9f71b62..4365822 100644 --- a/components/sync/engine_impl/syncer_proto_util.h +++ b/components/sync/engine_impl/syncer_proto_util.h
@@ -11,7 +11,6 @@ #include "base/macros.h" #include "base/time/time.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/syncer_error.h" #include "components/sync/sessions_impl/sync_session.h" @@ -39,14 +38,13 @@ } // Returns the types to migrate from the data in |response|. -SYNC_EXPORT ModelTypeSet -GetTypesToMigrate(const sync_pb::ClientToServerResponse& response); +ModelTypeSet GetTypesToMigrate(const sync_pb::ClientToServerResponse& response); // Builds a SyncProtocolError from the data in |error|. -SYNC_EXPORT SyncProtocolError ConvertErrorPBToSyncProtocolError( +SyncProtocolError ConvertErrorPBToSyncProtocolError( const sync_pb::ClientToServerResponse_Error& error); -class SYNC_EXPORT SyncerProtoUtil { +class SyncerProtoUtil { public: // Posts the given message and fills the buffer with the returned value. // Returns true on success. Also handles store birthday verification: will
diff --git a/components/sync/engine_impl/syncer_util.h b/components/sync/engine_impl/syncer_util.h index 5c4d10c..42abcb1b 100644 --- a/components/sync/engine_impl/syncer_util.h +++ b/components/sync/engine_impl/syncer_util.h
@@ -14,7 +14,6 @@ #include <string> #include <vector> -#include "components/sync/base/sync_export.h" #include "components/sync/engine_impl/syncer.h" #include "components/sync/engine_impl/syncer_types.h" #include "components/sync/syncable/entry_kernel.h" @@ -60,16 +59,15 @@ // // Will return an invalid position if no valid position can be constructed, or // if this type does not support positioning. -SYNC_EXPORT UniquePosition GetUpdatePosition(const sync_pb::SyncEntity& update, - const std::string& suffix); +UniquePosition GetUpdatePosition(const sync_pb::SyncEntity& update, + const std::string& suffix); // Fetch the cache_guid and item_id-based unique bookmark tag from an update. // Will return an empty string if someting unexpected happens. -SYNC_EXPORT std::string GetUniqueBookmarkTagFromUpdate( - const sync_pb::SyncEntity& update); +std::string GetUniqueBookmarkTagFromUpdate(const sync_pb::SyncEntity& update); // Pass in name to avoid redundant UTF8 conversion. -SYNC_EXPORT void UpdateServerFieldsFromUpdate( +void UpdateServerFieldsFromUpdate( syncable::ModelNeutralMutableEntry* local_entry, const sync_pb::SyncEntity& server_entry, const std::string& name);
diff --git a/components/sync/engine_impl/update_handler.h b/components/sync/engine_impl/update_handler.h index 01db6190..df3b6e13 100644 --- a/components/sync/engine_impl/update_handler.h +++ b/components/sync/engine_impl/update_handler.h
@@ -7,7 +7,6 @@ #include <vector> -#include "components/sync/base/sync_export.h" #include "components/sync/base/syncer_error.h" namespace sync_pb { @@ -28,7 +27,7 @@ // This class represents an entity that can request, receive, and apply updates // from the sync server. -class SYNC_EXPORT UpdateHandler { +class UpdateHandler { public: UpdateHandler(); virtual ~UpdateHandler() = 0;
diff --git a/components/sync/engine_impl/worker_entity_tracker.h b/components/sync/engine_impl/worker_entity_tracker.h index d8d2f5a..354502ad 100644 --- a/components/sync/engine_impl/worker_entity_tracker.h +++ b/components/sync/engine_impl/worker_entity_tracker.h
@@ -12,7 +12,6 @@ #include "base/macros.h" #include "base/time/time.h" -#include "components/sync/base/sync_export.h" #include "components/sync/protocol/sync.pb.h" namespace syncer_v2 { @@ -32,7 +31,7 @@ // // This object may contain state associated with a pending commit, pending // update, or both. -class SYNC_EXPORT WorkerEntityTracker { +class WorkerEntityTracker { public: // Initializes the entity tracker's main fields. Does not initialize state // related to a pending commit.
diff --git a/components/sync/js/js_backend.h b/components/sync/js/js_backend.h index 1f6d32e3..9ad2393 100644 --- a/components/sync/js/js_backend.h +++ b/components/sync/js/js_backend.h
@@ -9,8 +9,6 @@ #include <string> -#include "components/sync/base/sync_export.h" - namespace syncer { class JsEventHandler; @@ -20,7 +18,7 @@ // Interface representing the backend of chrome://sync-internals. A // JsBackend can handle messages and can emit events to a // JsEventHandler. -class SYNC_EXPORT JsBackend { +class JsBackend { public: // Starts emitting events to the given handler, if initialized. virtual void SetJsEventHandler(
diff --git a/components/sync/js/js_controller.h b/components/sync/js/js_controller.h index 7daa263..ad991a5e 100644 --- a/components/sync/js/js_controller.h +++ b/components/sync/js/js_controller.h
@@ -9,8 +9,6 @@ #include <string> -#include "components/sync/base/sync_export.h" - namespace syncer { class JsEventHandler; @@ -20,7 +18,7 @@ // An interface for objects that JsEventHandlers directly interact // with. JsEventHandlers can add themselves to receive events and // also send messages which will eventually reach the backend. -class SYNC_EXPORT JsController { +class JsController { public: // Adds an event handler which will start receiving JS events (not // immediately, so this can be called in the handler's constructor).
diff --git a/components/sync/js/js_event_details.h b/components/sync/js/js_event_details.h index e140974..91e6460 100644 --- a/components/sync/js/js_event_details.h +++ b/components/sync/js/js_event_details.h
@@ -11,13 +11,12 @@ #include "base/values.h" #include "components/sync/base/immutable.h" -#include "components/sync/base/sync_export.h" namespace syncer { // A thin wrapper around Immutable<DictionaryValue>. Used for passing // around event details to different threads. -class SYNC_EXPORT JsEventDetails { +class JsEventDetails { public: // Uses an empty dictionary. JsEventDetails();
diff --git a/components/sync/js/js_event_handler.h b/components/sync/js/js_event_handler.h index ec5a3e9..f1df13e 100644 --- a/components/sync/js/js_event_handler.h +++ b/components/sync/js/js_event_handler.h
@@ -9,15 +9,13 @@ #include <string> -#include "components/sync/base/sync_export.h" - namespace syncer { class JsEventDetails; // An interface for objects that handle Javascript events (e.g., // WebUIs). -class SYNC_EXPORT JsEventHandler { +class JsEventHandler { public: virtual void HandleJsEvent(const std::string& name, const JsEventDetails& details) = 0;
diff --git a/components/sync/js/sync_js_controller.h b/components/sync/js/sync_js_controller.h index 13b757e..79a8400 100644 --- a/components/sync/js/sync_js_controller.h +++ b/components/sync/js/sync_js_controller.h
@@ -12,7 +12,6 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/weak_handle.h" #include "components/sync/js/js_controller.h" #include "components/sync/js/js_event_handler.h" @@ -23,10 +22,9 @@ // A class that mediates between the sync JsEventHandlers and the sync // JsBackend. -class SYNC_EXPORT SyncJsController - : public JsController, - public JsEventHandler, - public base::SupportsWeakPtr<SyncJsController> { +class SyncJsController : public JsController, + public JsEventHandler, + public base::SupportsWeakPtr<SyncJsController> { public: SyncJsController();
diff --git a/components/sync/protocol/BUILD.gn b/components/sync/protocol/BUILD.gn index 209f26c..50c3e7f 100644 --- a/components/sync/protocol/BUILD.gn +++ b/components/sync/protocol/BUILD.gn
@@ -5,24 +5,7 @@ import("//third_party/protobuf/proto_library.gni") import("protocol_sources.gni") -# This must be a component for the dependency structure we have now, but the -# proto_library generates a source set. Link those into a component. -component("protocol") { - public_deps = [ - ":protocol_internal", - ] -} - -proto_library("protocol_internal") { - visibility = [ ":protocol" ] - +proto_library("protocol") { sources = sync_protocol_sources - - cc_generator_options = "dllexport_decl=SYNC_PROTO_EXPORT:" - cc_include = "components/sync/protocol/sync_proto_export.h" - component_build_force_source_set = true - - defines = [ "SYNC_PROTO_IMPLEMENTATION" ] - extra_configs = [ "//build/config/compiler:wexit_time_destructors" ] }
diff --git a/components/sync/protocol/proto_enum_conversions.h b/components/sync/protocol/proto_enum_conversions.h index f5cb756e..8a74b55 100644 --- a/components/sync/protocol/proto_enum_conversions.h +++ b/components/sync/protocol/proto_enum_conversions.h
@@ -7,7 +7,6 @@ // Keep this file in sync with the .proto files in this directory. -#include "components/sync/base/sync_export.h" #include "components/sync/protocol/app_list_specifics.pb.h" #include "components/sync/protocol/app_specifics.pb.h" #include "components/sync/protocol/client_debug_info.pb.h" @@ -22,48 +21,45 @@ // The returned strings (which don't have to be freed) are in ASCII. // The result of passing in an invalid enum value is undefined. -SYNC_EXPORT const char* GetAppListItemTypeString( +const char* GetAppListItemTypeString( sync_pb::AppListSpecifics::AppListItemType item_type); -SYNC_EXPORT const char* GetBrowserTypeString( +const char* GetBrowserTypeString( sync_pb::SessionWindow::BrowserType browser_type); -SYNC_EXPORT const char* GetPageTransitionString( +const char* GetPageTransitionString( sync_pb::SyncEnums::PageTransition page_transition); -SYNC_EXPORT const char* GetPageTransitionRedirectTypeString( +const char* GetPageTransitionRedirectTypeString( sync_pb::SyncEnums::PageTransitionRedirectType redirect_type); -SYNC_EXPORT const char* GetWifiCredentialSecurityClassString( +const char* GetWifiCredentialSecurityClassString( sync_pb::WifiCredentialSpecifics::SecurityClass security_class); -SYNC_EXPORT const char* GetUpdatesSourceString( +const char* GetUpdatesSourceString( sync_pb::GetUpdatesCallerInfo::GetUpdatesSource updates_source); -SYNC_EXPORT const char* GetUpdatesOriginString( - sync_pb::SyncEnums::GetUpdatesOrigin origin); +const char* GetUpdatesOriginString(sync_pb::SyncEnums::GetUpdatesOrigin origin); -SYNC_EXPORT const char* GetResponseTypeString( +const char* GetResponseTypeString( sync_pb::CommitResponse::ResponseType response_type); -SYNC_EXPORT const char* GetErrorTypeString( - sync_pb::SyncEnums::ErrorType error_type); +const char* GetErrorTypeString(sync_pb::SyncEnums::ErrorType error_type); -SYNC_EXPORT const char* GetActionString(sync_pb::SyncEnums::Action action); +const char* GetActionString(sync_pb::SyncEnums::Action action); -SYNC_EXPORT const char* GetLaunchTypeString( - sync_pb::AppSpecifics::LaunchType launch_type); +const char* GetLaunchTypeString(sync_pb::AppSpecifics::LaunchType launch_type); -SYNC_EXPORT const char* GetWalletInfoTypeString( +const char* GetWalletInfoTypeString( sync_pb::AutofillWalletSpecifics::WalletInfoType wallet_info_type); -SYNC_EXPORT const char* GetWalletMetadataTypeString( +const char* GetWalletMetadataTypeString( sync_pb::WalletMetadataSpecifics::Type wallet_metadata_type); -SYNC_EXPORT const char* GetWalletCardStatusString( +const char* GetWalletCardStatusString( sync_pb::WalletMaskedCreditCard::WalletCardStatus wallet_card_status); -SYNC_EXPORT const char* GetWalletCardTypeString( +const char* GetWalletCardTypeString( sync_pb::WalletMaskedCreditCard::WalletCardType wallet_card_type); const char* GetDeviceTypeString(sync_pb::SyncEnums::DeviceType device_type);
diff --git a/components/sync/protocol/proto_value_conversions.h b/components/sync/protocol/proto_value_conversions.h index 36731f3c..1391a887 100644 --- a/components/sync/protocol/proto_value_conversions.h +++ b/components/sync/protocol/proto_value_conversions.h
@@ -9,8 +9,6 @@ #include <memory> -#include "components/sync/base/sync_export.h" - namespace base { class DictionaryValue; } @@ -97,44 +95,44 @@ // caller. // TODO(akalin): Perhaps extend this to decrypt? -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> EncryptedDataToValue( +std::unique_ptr<base::DictionaryValue> EncryptedDataToValue( const sync_pb::EncryptedData& encrypted_data); // Sub-protocol of AppListSpecifics. -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> AppListSpecificsToValue( +std::unique_ptr<base::DictionaryValue> AppListSpecificsToValue( const sync_pb::AppListSpecifics& proto); // Sub-protocols of AppSpecifics. -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> AppSettingsToValue( +std::unique_ptr<base::DictionaryValue> AppSettingsToValue( const sync_pb::AppNotificationSettings& app_notification_settings); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> LinkedAppIconInfoToValue( +std::unique_ptr<base::DictionaryValue> LinkedAppIconInfoToValue( const sync_pb::LinkedAppIconInfo& linked_app_icon_info); // Sub-protocol of ArcPackageSpecifics. -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> ArcPackageSpecificsToValue( +std::unique_ptr<base::DictionaryValue> ArcPackageSpecificsToValue( const sync_pb::ArcPackageSpecifics& proto); // Sub-protocols of SessionSpecifics. -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> SessionHeaderToValue( +std::unique_ptr<base::DictionaryValue> SessionHeaderToValue( const sync_pb::SessionHeader& session_header); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> SessionTabToValue( +std::unique_ptr<base::DictionaryValue> SessionTabToValue( const sync_pb::SessionTab& session_tab); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> SessionWindowToValue( +std::unique_ptr<base::DictionaryValue> SessionWindowToValue( const sync_pb::SessionWindow& session_window); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> TabNavigationToValue( +std::unique_ptr<base::DictionaryValue> TabNavigationToValue( const sync_pb::TabNavigation& tab_navigation); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> NavigationRedirectToValue( +std::unique_ptr<base::DictionaryValue> NavigationRedirectToValue( const sync_pb::NavigationRedirect& navigation_redirect); // Sub-protocol of PasswordSpecifics. -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> PasswordSpecificsDataToValue( +std::unique_ptr<base::DictionaryValue> PasswordSpecificsDataToValue( const sync_pb::PasswordSpecificsData& password_specifics_data); // Sub-protocol of NigoriSpecifics. @@ -155,147 +153,134 @@ std::unique_ptr<base::DictionaryValue> KeystoreEncryptionToValue( const sync_pb::KeystoreEncryptionFlagsSpecifics& proto); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> SessionSpecificsToValue( +std::unique_ptr<base::DictionaryValue> SessionSpecificsToValue( const sync_pb::SessionSpecifics& session_specifics); // Main *SpecificsToValue functions. -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> AppNotificationToValue( +std::unique_ptr<base::DictionaryValue> AppNotificationToValue( const sync_pb::AppNotification& app_notification_specifics); std::unique_ptr<base::DictionaryValue> AppSettingSpecificsToValue( const sync_pb::AppSettingSpecifics& app_setting_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> AppSpecificsToValue( +std::unique_ptr<base::DictionaryValue> AppSpecificsToValue( const sync_pb::AppSpecifics& app_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> ArticleSpecificsToValue( +std::unique_ptr<base::DictionaryValue> ArticleSpecificsToValue( const sync_pb::ArticleSpecifics& article_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> AutofillSpecificsToValue( +std::unique_ptr<base::DictionaryValue> AutofillSpecificsToValue( const sync_pb::AutofillSpecifics& autofill_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> -AutofillProfileSpecificsToValue( +std::unique_ptr<base::DictionaryValue> AutofillProfileSpecificsToValue( const sync_pb::AutofillProfileSpecifics& autofill_profile_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> -WalletMetadataSpecificsToValue( +std::unique_ptr<base::DictionaryValue> WalletMetadataSpecificsToValue( const sync_pb::WalletMetadataSpecifics& wallet_metadata_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> -AutofillWalletSpecificsToValue( +std::unique_ptr<base::DictionaryValue> AutofillWalletSpecificsToValue( const sync_pb::AutofillWalletSpecifics& autofill_wallet_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> BookmarkSpecificsToValue( +std::unique_ptr<base::DictionaryValue> BookmarkSpecificsToValue( const sync_pb::BookmarkSpecifics& bookmark_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> DeviceInfoSpecificsToValue( +std::unique_ptr<base::DictionaryValue> DeviceInfoSpecificsToValue( const sync_pb::DeviceInfoSpecifics& device_info_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> DictionarySpecificsToValue( +std::unique_ptr<base::DictionaryValue> DictionarySpecificsToValue( const sync_pb::DictionarySpecifics& dictionary_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> ExperimentsSpecificsToValue( +std::unique_ptr<base::DictionaryValue> ExperimentsSpecificsToValue( const sync_pb::ExperimentsSpecifics& proto); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> -PriorityPreferenceSpecificsToValue( +std::unique_ptr<base::DictionaryValue> PriorityPreferenceSpecificsToValue( const sync_pb::PriorityPreferenceSpecifics& proto); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> -ExtensionSettingSpecificsToValue( +std::unique_ptr<base::DictionaryValue> ExtensionSettingSpecificsToValue( const sync_pb::ExtensionSettingSpecifics& extension_setting_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> ExtensionSpecificsToValue( +std::unique_ptr<base::DictionaryValue> ExtensionSpecificsToValue( const sync_pb::ExtensionSpecifics& extension_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> FaviconImageSpecificsToValue( +std::unique_ptr<base::DictionaryValue> FaviconImageSpecificsToValue( const sync_pb::FaviconImageSpecifics& favicon_image_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> -FaviconTrackingSpecificsToValue( +std::unique_ptr<base::DictionaryValue> FaviconTrackingSpecificsToValue( const sync_pb::FaviconTrackingSpecifics& favicon_tracking_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> -HistoryDeleteDirectiveSpecificsToValue( +std::unique_ptr<base::DictionaryValue> HistoryDeleteDirectiveSpecificsToValue( const sync_pb::HistoryDeleteDirectiveSpecifics& history_delete_directive_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> -ManagedUserSettingSpecificsToValue( +std::unique_ptr<base::DictionaryValue> ManagedUserSettingSpecificsToValue( const sync_pb::ManagedUserSettingSpecifics& managed_user_setting_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> ManagedUserSpecificsToValue( +std::unique_ptr<base::DictionaryValue> ManagedUserSpecificsToValue( const sync_pb::ManagedUserSpecifics& managed_user_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> -ManagedUserSharedSettingSpecificsToValue( +std::unique_ptr<base::DictionaryValue> ManagedUserSharedSettingSpecificsToValue( const sync_pb::ManagedUserSharedSettingSpecifics& managed_user_shared_setting_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> -ManagedUserWhitelistSpecificsToValue( +std::unique_ptr<base::DictionaryValue> ManagedUserWhitelistSpecificsToValue( const sync_pb::ManagedUserWhitelistSpecifics& managed_user_whitelist_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> MediaToValue( +std::unique_ptr<base::DictionaryValue> MediaToValue( const sync_pb::Media& media); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> NigoriSpecificsToValue( +std::unique_ptr<base::DictionaryValue> NigoriSpecificsToValue( const sync_pb::NigoriSpecifics& nigori_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> PasswordSpecificsToValue( +std::unique_ptr<base::DictionaryValue> PasswordSpecificsToValue( const sync_pb::PasswordSpecifics& password_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> PreferenceSpecificsToValue( +std::unique_ptr<base::DictionaryValue> PreferenceSpecificsToValue( const sync_pb::PreferenceSpecifics& password_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> +std::unique_ptr<base::DictionaryValue> SyncedNotificationAppInfoSpecificsToValue( const sync_pb::SyncedNotificationAppInfoSpecifics& synced_notification_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> -SyncedNotificationSpecificsToValue( +std::unique_ptr<base::DictionaryValue> SyncedNotificationSpecificsToValue( const sync_pb::SyncedNotificationSpecifics& synced_notification_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> SearchEngineSpecificsToValue( +std::unique_ptr<base::DictionaryValue> SearchEngineSpecificsToValue( const sync_pb::SearchEngineSpecifics& search_engine_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> ThemeSpecificsToValue( +std::unique_ptr<base::DictionaryValue> ThemeSpecificsToValue( const sync_pb::ThemeSpecifics& theme_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> TypedUrlSpecificsToValue( +std::unique_ptr<base::DictionaryValue> TypedUrlSpecificsToValue( const sync_pb::TypedUrlSpecifics& typed_url_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> -WalletMaskedCreditCardToValue( +std::unique_ptr<base::DictionaryValue> WalletMaskedCreditCardToValue( const sync_pb::WalletMaskedCreditCard& wallet_masked_card); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> WalletPostalAddressToValue( +std::unique_ptr<base::DictionaryValue> WalletPostalAddressToValue( const sync_pb::WalletPostalAddress& wallet_postal_address); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> -WifiCredentialSpecificsToValue( +std::unique_ptr<base::DictionaryValue> WifiCredentialSpecificsToValue( const sync_pb::WifiCredentialSpecifics& wifi_credential_specifics); // Any present extensions are mapped to sub-dictionary values with the // key equal to the extension name. -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> EntitySpecificsToValue( +std::unique_ptr<base::DictionaryValue> EntitySpecificsToValue( const sync_pb::EntitySpecifics& specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> SyncEntityToValue( +std::unique_ptr<base::DictionaryValue> SyncEntityToValue( const sync_pb::SyncEntity& entity, bool include_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> ClientToServerMessageToValue( +std::unique_ptr<base::DictionaryValue> ClientToServerMessageToValue( const sync_pb::ClientToServerMessage& proto, bool include_specifics); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> -ClientToServerResponseToValue(const sync_pb::ClientToServerResponse& proto, - bool include_specifics); +std::unique_ptr<base::DictionaryValue> ClientToServerResponseToValue( + const sync_pb::ClientToServerResponse& proto, + bool include_specifics); std::unique_ptr<base::DictionaryValue> DatatypeAssociationStatsToValue( const sync_pb::DatatypeAssociationStats& proto); @@ -312,7 +297,7 @@ std::unique_ptr<base::DictionaryValue> ClientConfigParamsToValue( const sync_pb::ClientConfigParams& proto); -SYNC_EXPORT std::unique_ptr<base::DictionaryValue> AttachmentIdProtoToValue( +std::unique_ptr<base::DictionaryValue> AttachmentIdProtoToValue( const sync_pb::AttachmentIdProto& proto); } // namespace syncer
diff --git a/components/sync/protocol/sync_proto_export.h b/components/sync/protocol/sync_proto_export.h deleted file mode 100644 index 7670ffa..0000000 --- a/components/sync/protocol/sync_proto_export.h +++ /dev/null
@@ -1,29 +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 COMPONENTS_SYNC_PROTOCOL_SYNC_PROTO_EXPORT_H_ -#define COMPONENTS_SYNC_PROTOCOL_SYNC_PROTO_EXPORT_H_ - -#if defined(COMPONENT_BUILD) -#if defined(WIN32) - -#if defined(SYNC_PROTO_IMPLEMENTATION) -#define SYNC_PROTO_EXPORT __declspec(dllexport) -#else -#define SYNC_PROTO_EXPORT __declspec(dllimport) -#endif // defined(SYNC_PROTO_IMPLEMENTATION) - -#else // defined(WIN32) -#if defined(SYNC_PROTO_IMPLEMENTATION) -#define SYNC_PROTO_EXPORT __attribute__((visibility("default"))) -#else -#define SYNC_PROTO_EXPORT -#endif // defined(SYNC_IMPLEMENTATION) -#endif - -#else // defined(COMPONENT_BUILD) -#define SYNC_PROTO_EXPORT -#endif - -#endif // COMPONENTS_SYNC_PROTOCOL_SYNC_PROTO_EXPORT_H_
diff --git a/components/sync/protocol/sync_protocol_error.h b/components/sync/protocol/sync_protocol_error.h index dfd5f8c..fc6eda4d 100644 --- a/components/sync/protocol/sync_protocol_error.h +++ b/components/sync/protocol/sync_protocol_error.h
@@ -8,7 +8,6 @@ #include "base/values.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" namespace syncer { @@ -77,7 +76,7 @@ UNKNOWN_ACTION }; -struct SYNC_EXPORT SyncProtocolError { +struct SyncProtocolError { SyncProtocolErrorType error_type; std::string error_description; std::string url; @@ -89,7 +88,7 @@ base::DictionaryValue* ToValue() const; }; -SYNC_EXPORT const char* GetSyncErrorTypeString(SyncProtocolErrorType type); -SYNC_EXPORT const char* GetClientActionString(ClientAction action); +const char* GetSyncErrorTypeString(SyncProtocolErrorType type); +const char* GetClientActionString(ClientAction action); } // namespace syncer #endif // COMPONENTS_SYNC_PROTOCOL_SYNC_PROTOCOL_ERROR_H_
diff --git a/components/sync/sessions/commit_counters.h b/components/sync/sessions/commit_counters.h index 97d22f6..2164fad4 100644 --- a/components/sync/sessions/commit_counters.h +++ b/components/sync/sessions/commit_counters.h
@@ -9,12 +9,11 @@ #include <string> #include "base/values.h" -#include "components/sync/base/sync_export.h" namespace syncer { // A class to maintain counts related to sync commit requests and responses. -struct SYNC_EXPORT CommitCounters { +struct CommitCounters { CommitCounters(); ~CommitCounters();
diff --git a/components/sync/sessions/model_neutral_state.h b/components/sync/sessions/model_neutral_state.h index c1632cf..660948d 100644 --- a/components/sync/sessions/model_neutral_state.h +++ b/components/sync/sessions/model_neutral_state.h
@@ -6,7 +6,6 @@ #define COMPONENTS_SYNC_SESSIONS_MODEL_NEUTRAL_STATE_H_ #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/syncer_error.h" #include "components/sync/protocol/sync.pb.h" @@ -17,7 +16,7 @@ // components of the global grouping can internally implement finer grained // scope control, but the top level entity is still a singleton with respect to // model types. -struct SYNC_EXPORT ModelNeutralState { +struct ModelNeutralState { ModelNeutralState(); ModelNeutralState(const ModelNeutralState& other); ~ModelNeutralState(); @@ -58,7 +57,7 @@ bool items_committed; }; -SYNC_EXPORT bool HasSyncerError(const ModelNeutralState& state); +bool HasSyncerError(const ModelNeutralState& state); } // namespace sessions } // namespace syncer
diff --git a/components/sync/sessions/status_counters.h b/components/sync/sessions/status_counters.h index c40175de..ddb3b861 100644 --- a/components/sync/sessions/status_counters.h +++ b/components/sync/sessions/status_counters.h
@@ -11,12 +11,11 @@ #include <string> #include "base/values.h" -#include "components/sync/base/sync_export.h" namespace syncer { // A class to maintain counts related to the current status of a sync type. -struct SYNC_EXPORT StatusCounters { +struct StatusCounters { StatusCounters(); ~StatusCounters();
diff --git a/components/sync/sessions/sync_session_snapshot.h b/components/sync/sessions/sync_session_snapshot.h index 9ff4d7c..2a21d83 100644 --- a/components/sync/sessions/sync_session_snapshot.h +++ b/components/sync/sessions/sync_session_snapshot.h
@@ -13,7 +13,6 @@ #include "base/time/time.h" #include "components/sync/base/model_type.h" #include "components/sync/base/progress_marker_map.h" -#include "components/sync/base/sync_export.h" #include "components/sync/sessions/model_neutral_state.h" namespace base { @@ -28,7 +27,7 @@ // TODO(zea): if copying this all over the place starts getting expensive, // consider passing around immutable references instead of values. // Default copy and assign welcome. -class SYNC_EXPORT SyncSessionSnapshot { +class SyncSessionSnapshot { public: SyncSessionSnapshot(); SyncSessionSnapshot(
diff --git a/components/sync/sessions/type_debug_info_observer.h b/components/sync/sessions/type_debug_info_observer.h index 861a165..b67d4d0 100644 --- a/components/sync/sessions/type_debug_info_observer.h +++ b/components/sync/sessions/type_debug_info_observer.h
@@ -14,7 +14,7 @@ struct UpdateCounters; // Interface for classes that observe per-type sync debug counters. -class SYNC_EXPORT TypeDebugInfoObserver { +class TypeDebugInfoObserver { public: TypeDebugInfoObserver(); virtual ~TypeDebugInfoObserver();
diff --git a/components/sync/sessions/update_counters.h b/components/sync/sessions/update_counters.h index 2cb2f2c..1d73248 100644 --- a/components/sync/sessions/update_counters.h +++ b/components/sync/sessions/update_counters.h
@@ -9,13 +9,12 @@ #include <string> #include "base/values.h" -#include "components/sync/base/sync_export.h" namespace syncer { // A class to maintain counts related to the update requests and responses for // a particular sync type. -struct SYNC_EXPORT UpdateCounters { +struct UpdateCounters { UpdateCounters(); ~UpdateCounters();
diff --git a/components/sync/sessions_impl/debug_info_getter.h b/components/sync/sessions_impl/debug_info_getter.h index 9988209..537d4956 100644 --- a/components/sync/sessions_impl/debug_info_getter.h +++ b/components/sync/sessions_impl/debug_info_getter.h
@@ -5,7 +5,6 @@ #ifndef COMPONENTS_SYNC_SESSIONS_IMPL_DEBUG_INFO_GETTER_H_ #define COMPONENTS_SYNC_SESSIONS_IMPL_DEBUG_INFO_GETTER_H_ -#include "components/sync/base/sync_export.h" #include "components/sync/protocol/sync.pb.h" namespace syncer { @@ -13,7 +12,7 @@ // This is the interface that needs to be implemented by the event listener // to communicate the debug info data to the syncer. -class SYNC_EXPORT DebugInfoGetter { +class DebugInfoGetter { public: // Gets the client debug info. Be sure to clear the info to ensure the data // isn't sent multiple times.
diff --git a/components/sync/sessions_impl/directory_type_debug_info_emitter.h b/components/sync/sessions_impl/directory_type_debug_info_emitter.h index b702724..636d927 100644 --- a/components/sync/sessions_impl/directory_type_debug_info_emitter.h +++ b/components/sync/sessions_impl/directory_type_debug_info_emitter.h
@@ -10,7 +10,6 @@ #include "base/macros.h" #include "base/observer_list.h" #include "base/values.h" -#include "components/sync/base/sync_export.h" #include "components/sync/sessions/commit_counters.h" #include "components/sync/sessions/update_counters.h" #include "components/sync/syncable/directory.h" @@ -34,7 +33,7 @@ // is delegated to the UpdateHandler and CommitContributors. For the Stats // counters, the emitter will use its type_ and directory_ members to fetch all // the required information on demand. -class SYNC_EXPORT DirectoryTypeDebugInfoEmitter { +class DirectoryTypeDebugInfoEmitter { public: // Standard constructor for non-tests. //
diff --git a/components/sync/sessions_impl/model_type_registry.h b/components/sync/sessions_impl/model_type_registry.h index 01f2f260..fb8d1b2 100644 --- a/components/sync/sessions_impl/model_type_registry.h +++ b/components/sync/sessions_impl/model_type_registry.h
@@ -14,7 +14,6 @@ #include "base/memory/scoped_vector.h" #include "base/memory/weak_ptr.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/core/model_type_connector.h" #include "components/sync/core/non_blocking_sync_common.h" #include "components/sync/core/sync_encryption_handler.h" @@ -46,8 +45,8 @@ DirectoryTypeDebugInfoEmitterMap; // Keeps track of the sets of active update handlers and commit contributors. -class SYNC_EXPORT ModelTypeRegistry : public syncer_v2::ModelTypeConnector, - public SyncEncryptionHandler::Observer { +class ModelTypeRegistry : public syncer_v2::ModelTypeConnector, + public SyncEncryptionHandler::Observer { public: // Constructs a ModelTypeRegistry that supports directory types. ModelTypeRegistry(const std::vector<scoped_refptr<ModelSafeWorker>>& workers,
diff --git a/components/sync/sessions_impl/nudge_tracker.h b/components/sync/sessions_impl/nudge_tracker.h index d33785b..798a95e5 100644 --- a/components/sync/sessions_impl/nudge_tracker.h +++ b/components/sync/sessions_impl/nudge_tracker.h
@@ -18,7 +18,6 @@ #include "base/time/time.h" #include "components/sync/base/invalidation_interface.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/protocol/sync.pb.h" #include "components/sync/sessions_impl/data_type_tracker.h" @@ -28,7 +27,7 @@ namespace sessions { -class SYNC_EXPORT NudgeTracker { +class NudgeTracker { public: static size_t kDefaultMaxPayloadsPerType;
diff --git a/components/sync/sessions_impl/status_controller.h b/components/sync/sessions_impl/status_controller.h index 53bf8e6f..88de5913 100644 --- a/components/sync/sessions_impl/status_controller.h +++ b/components/sync/sessions_impl/status_controller.h
@@ -24,14 +24,13 @@ #include "base/macros.h" #include "base/stl_util.h" #include "base/time/time.h" -#include "components/sync/base/sync_export.h" #include "components/sync/engine/model_safe_worker.h" #include "components/sync/sessions/model_neutral_state.h" namespace syncer { namespace sessions { -class SYNC_EXPORT StatusController { +class StatusController { public: StatusController(); ~StatusController();
diff --git a/components/sync/sessions_impl/sync_session.h b/components/sync/sessions_impl/sync_session.h index 10f0a310..1d633347 100644 --- a/components/sync/sessions_impl/sync_session.h +++ b/components/sync/sessions_impl/sync_session.h
@@ -20,7 +20,6 @@ #include "base/macros.h" #include "base/time/time.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/engine/model_safe_worker.h" #include "components/sync/engine_impl/sync_cycle_event.h" #include "components/sync/protocol/sync_protocol_error.h" @@ -36,12 +35,12 @@ class NudgeTracker; -class SYNC_EXPORT SyncSession { +class SyncSession { public: // The Delegate services events that occur during the session requiring an // explicit (and session-global) action, as opposed to events that are simply // recorded in per-session state. - class SYNC_EXPORT Delegate { + class Delegate { public: // The client was throttled and should cease-and-desist syncing activity // until the specified time.
diff --git a/components/sync/sessions_impl/sync_session_context.h b/components/sync/sessions_impl/sync_session_context.h index 81bec415..c258b6e 100644 --- a/components/sync/sessions_impl/sync_session_context.h +++ b/components/sync/sessions_impl/sync_session_context.h
@@ -21,7 +21,6 @@ #include <vector> #include "base/macros.h" -#include "components/sync/base/sync_export.h" #include "components/sync/engine_impl/sync_engine_event_listener.h" #include "components/sync/sessions_impl/debug_info_getter.h" #include "components/sync/sessions_impl/model_type_registry.h" @@ -42,7 +41,7 @@ namespace sessions { class TestScopedSessionEventListener; -class SYNC_EXPORT SyncSessionContext { +class SyncSessionContext { public: SyncSessionContext(ServerConnectionManager* connection_manager, syncable::Directory* directory,
diff --git a/components/sync/sync_tests.gypi b/components/sync/sync_tests.gypi index 7a3ad9d..0ca14f1 100644 --- a/components/sync/sync_tests.gypi +++ b/components/sync/sync_tests.gypi
@@ -242,6 +242,49 @@ 'api/sync_error_factory_mock.h', ], }, + { + 'target_name': 'test_support_sync_driver', + 'type': 'static_library', + 'dependencies': [ + 'sync', + 'test_support_sync_core_impl', + 'components.gyp:version_info', + '../base/base.gyp:base', + '../testing/gmock.gyp:gmock', + '../testing/gtest.gyp:gtest', + ], + 'include_dirs': [ + '..', + ], + 'sources': [ + 'driver/change_processor_mock.cc', + 'driver/change_processor_mock.h', + 'driver/data_type_controller_mock.cc', + 'driver/data_type_controller_mock.h', + 'driver/data_type_manager_mock.cc', + 'driver/data_type_manager_mock.h', + 'driver/fake_data_type_controller.cc', + 'driver/fake_data_type_controller.h', + 'driver/fake_generic_change_processor.cc', + 'driver/fake_generic_change_processor.h', + 'driver/fake_sync_client.cc', + 'driver/fake_sync_client.h', + 'driver/fake_sync_service.cc', + 'driver/fake_sync_service.h', + 'driver/frontend_data_type_controller_mock.cc', + 'driver/frontend_data_type_controller_mock.h', + 'driver/glue/sync_backend_host_mock.cc', + 'driver/glue/sync_backend_host_mock.h', + 'driver/local_device_info_provider_mock.cc', + 'driver/local_device_info_provider_mock.h', + 'driver/model_associator_mock.cc', + 'driver/model_associator_mock.h', + 'driver/non_ui_data_type_controller_mock.cc', + 'driver/non_ui_data_type_controller_mock.h', + 'driver/sync_api_component_factory_mock.cc', + 'driver/sync_api_component_factory_mock.h', + ], + }, ], 'conditions': [ ['OS != "ios"', {
diff --git a/components/sync/syncable/directory.cc b/components/sync/syncable/directory.cc index c17e025..1ed94ca 100644 --- a/components/sync/syncable/directory.cc +++ b/components/sync/syncable/directory.cc
@@ -76,8 +76,8 @@ : kernel_info_status(KERNEL_SHARE_INFO_INVALID) {} Directory::SaveChangesSnapshot::~SaveChangesSnapshot() { - STLDeleteElements(&dirty_metas); - STLDeleteElements(&delete_journals); + base::STLDeleteElements(&dirty_metas); + base::STLDeleteElements(&delete_journals); } bool Directory::SaveChangesSnapshot::HasUnsavedMetahandleChanges() const { @@ -103,8 +103,8 @@ } Directory::Kernel::~Kernel() { - STLDeleteContainerPairSecondPointers(metahandles_map.begin(), - metahandles_map.end()); + base::STLDeleteContainerPairSecondPointers(metahandles_map.begin(), + metahandles_map.end()); } Directory::Directory( @@ -187,7 +187,7 @@ // Avoids mem leaks on failure. Harmlessly deletes the empty hash map after // the swap in the success case. - STLValueDeleter<MetahandlesMap> deleter(&tmp_handles_map); + base::STLValueDeleter<MetahandlesMap> deleter(&tmp_handles_map); JournalIndex delete_journals; MetahandleSet metahandles_to_purge; @@ -739,7 +739,8 @@ WriteTransaction trans(FROM_HERE, PURGE_ENTRIES, this); EntryKernelSet entries_to_journal; - STLElementDeleter<EntryKernelSet> journal_deleter(&entries_to_journal); + base::STLElementDeleter<EntryKernelSet> journal_deleter( + &entries_to_journal); { ScopedKernelLock lock(this);
diff --git a/components/sync/syncable/directory.h b/components/sync/syncable/directory.h index ba8738e8..6100d00 100644 --- a/components/sync/syncable/directory.h +++ b/components/sync/syncable/directory.h
@@ -21,7 +21,6 @@ #include "base/macros.h" #include "base/values.h" #include "components/sync/api/attachments/attachment_id.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/weak_handle.h" #include "components/sync/syncable/dir_open_result.h" #include "components/sync/syncable/entry.h" @@ -59,7 +58,7 @@ // This class is tightly coupled to several other classes via Directory::Kernel. // Although Directory's kernel_ is exposed via public accessor it should be // treated as pseudo-private. -class SYNC_EXPORT Directory { +class Directory { public: typedef std::vector<int64_t> Metahandles; @@ -82,7 +81,7 @@ // Various data that the Directory::Kernel we are backing (persisting data // for) needs saved across runs of the application. - struct SYNC_EXPORT PersistedKernelInfo { + struct PersistedKernelInfo { PersistedKernelInfo(); ~PersistedKernelInfo(); @@ -126,7 +125,7 @@ // When the Directory is told to SaveChanges, a SaveChangesSnapshot is // constructed and forms a consistent snapshot of what needs to be sent to // the backing store. - struct SYNC_EXPORT SaveChangesSnapshot { + struct SaveChangesSnapshot { SaveChangesSnapshot(); ~SaveChangesSnapshot();
diff --git a/components/sync/syncable/directory_backing_store.h b/components/sync/syncable/directory_backing_store.h index 1dd16ee4..1c0cdde78 100644 --- a/components/sync/syncable/directory_backing_store.h +++ b/components/sync/syncable/directory_backing_store.h
@@ -14,7 +14,6 @@ #include "base/macros.h" #include "base/threading/non_thread_safe.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/syncable/dir_open_result.h" #include "components/sync/syncable/directory.h" #include "components/sync/syncable/metahandle_set.h" @@ -28,8 +27,8 @@ namespace syncer { namespace syncable { -SYNC_EXPORT extern const int32_t kCurrentDBVersion; -SYNC_EXPORT extern const int32_t kCurrentPageSizeKB; +extern const int32_t kCurrentDBVersion; +extern const int32_t kCurrentPageSizeKB; struct ColumnSpec; @@ -48,7 +47,7 @@ // This class is abstract so that we can extend it in interesting ways for use // in tests. The concrete class used in non-test scenarios is // OnDiskDirectoryBackingStore. -class SYNC_EXPORT DirectoryBackingStore : public base::NonThreadSafe { +class DirectoryBackingStore : public base::NonThreadSafe { public: explicit DirectoryBackingStore(const std::string& dir_name); virtual ~DirectoryBackingStore();
diff --git a/components/sync/syncable/directory_backing_store_unittest.cc b/components/sync/syncable/directory_backing_store_unittest.cc index 21c3ebd..62fddce 100644 --- a/components/sync/syncable/directory_backing_store_unittest.cc +++ b/components/sync/syncable/directory_backing_store_unittest.cc
@@ -20,7 +20,6 @@ #include "base/strings/stringprintf.h" #include "build/build_config.h" #include "components/sync/base/node_ordinal.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/time.h" #include "components/sync/protocol/bookmark_specifics.pb.h" #include "components/sync/protocol/sync.pb.h" @@ -56,8 +55,8 @@ } // namespace -SYNC_EXPORT extern const int32_t kCurrentPageSizeKB; -SYNC_EXPORT extern const int32_t kCurrentDBVersion; +extern const int32_t kCurrentPageSizeKB; +extern const int32_t kCurrentDBVersion; class MigrationTest : public testing::TestWithParam<int> { public: @@ -76,7 +75,7 @@ Directory::MetahandlesMap tmp_handles_map; JournalIndex delete_journals; MetahandleSet metahandles_to_purge; - STLValueDeleter<Directory::MetahandlesMap> deleter(&tmp_handles_map); + base::STLValueDeleter<Directory::MetahandlesMap> deleter(&tmp_handles_map); Directory::KernelLoadInfo kernel_load_info; return dbs->Load(&tmp_handles_map, &delete_journals, &metahandles_to_purge, &kernel_load_info) == OPENED; @@ -3330,7 +3329,7 @@ Directory::MetahandlesMap handles_map; JournalIndex delete_journals; MetahandleSet metahandles_to_purge; - STLValueDeleter<Directory::MetahandlesMap> deleter(&handles_map); + base::STLValueDeleter<Directory::MetahandlesMap> deleter(&handles_map); Directory::KernelLoadInfo load_info; ASSERT_TRUE(dbs->Load(&handles_map, &delete_journals, &metahandles_to_purge, @@ -3569,7 +3568,7 @@ Directory::MetahandlesMap handles_map; JournalIndex delete_journals; MetahandleSet metahandles_to_purge; - STLValueDeleter<Directory::MetahandlesMap> deleter(&handles_map); + base::STLValueDeleter<Directory::MetahandlesMap> deleter(&handles_map); Directory::KernelLoadInfo kernel_load_info; ASSERT_EQ(FAILED_DATABASE_CORRUPT, dbs->Load(&handles_map, &delete_journals, &metahandles_to_purge, @@ -3668,7 +3667,7 @@ Directory::MetahandlesMap handles_map; JournalIndex delete_journals; MetahandleSet metahandles_to_purge; - STLValueDeleter<Directory::MetahandlesMap> index_deleter(&handles_map); + base::STLValueDeleter<Directory::MetahandlesMap> index_deleter(&handles_map); { std::unique_ptr<OnDiskDirectoryBackingStore> dbs( @@ -4086,7 +4085,7 @@ JournalIndex delete_journals; MetahandleSet metahandles_to_purge; Directory::KernelLoadInfo kernel_load_info; - STLValueDeleter<Directory::MetahandlesMap> index_deleter(&handles_map); + base::STLValueDeleter<Directory::MetahandlesMap> index_deleter(&handles_map); dbs->Load(&handles_map, &delete_journals, &metahandles_to_purge, &kernel_load_info); @@ -4097,7 +4096,7 @@ to_delete.insert(first_to_die); EXPECT_TRUE(dbs->DeleteEntries(to_delete)); - STLDeleteValues(&handles_map); + base::STLDeleteValues(&handles_map); metahandles_to_purge.clear(); dbs->LoadEntries(&handles_map, &metahandles_to_purge); @@ -4120,7 +4119,7 @@ EXPECT_TRUE(dbs->DeleteEntries(to_delete)); - STLDeleteValues(&handles_map); + base::STLDeleteValues(&handles_map); metahandles_to_purge.clear(); dbs->LoadEntries(&handles_map, &metahandles_to_purge); EXPECT_EQ(0U, handles_map.size()); @@ -4147,7 +4146,7 @@ JournalIndex delete_journals; MetahandleSet metahandles_to_purge; Directory::KernelLoadInfo kernel_load_info; - STLValueDeleter<Directory::MetahandlesMap> index_deleter(&handles_map); + base::STLValueDeleter<Directory::MetahandlesMap> index_deleter(&handles_map); DirOpenResult open_result = dbs->Load( &handles_map, &delete_journals, &metahandles_to_purge, &kernel_load_info);
diff --git a/components/sync/syncable/directory_change_delegate.h b/components/sync/syncable/directory_change_delegate.h index ed7ffe7..b7c69222 100644 --- a/components/sync/syncable/directory_change_delegate.h +++ b/components/sync/syncable/directory_change_delegate.h
@@ -10,7 +10,6 @@ #include <vector> #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/syncable/write_transaction_info.h" namespace syncer { @@ -26,7 +25,7 @@ // (HandleTransactionCompleteChangeEvent). // // Note that these methods may be called on *any* thread. -class SYNC_EXPORT DirectoryChangeDelegate { +class DirectoryChangeDelegate { public: // Returns the handles of changed entries in |entry_changed|. virtual void HandleCalculateChangesChangeEventFromSyncApi(
diff --git a/components/sync/syncable/entry.h b/components/sync/syncable/entry.h index 367cde5..38b6fed 100644 --- a/components/sync/syncable/entry.h +++ b/components/sync/syncable/entry.h
@@ -12,7 +12,6 @@ #include <vector> #include "base/macros.h" -#include "components/sync/base/sync_export.h" #include "components/sync/syncable/entry_kernel.h" namespace syncer { @@ -46,7 +45,7 @@ enum GetByHandle { GET_BY_HANDLE }; -class SYNC_EXPORT Entry { +class Entry { public: // After constructing, you must check good() to test whether the Get // succeeded.
diff --git a/components/sync/syncable/entry_kernel.h b/components/sync/syncable/entry_kernel.h index 4895b28..03a2ff1e 100644 --- a/components/sync/syncable/entry_kernel.h +++ b/components/sync/syncable/entry_kernel.h
@@ -17,7 +17,6 @@ #include "components/sync/base/immutable.h" #include "components/sync/base/model_type.h" #include "components/sync/base/proto_value_ptr.h" -#include "components/sync/base/sync_export.h" #include "components/sync/base/time.h" #include "components/sync/base/unique_position.h" #include "components/sync/protocol/attachments.pb.h" @@ -193,7 +192,7 @@ enum { BIT_TEMPS_COUNT = BIT_TEMPS_END - BIT_TEMPS_BEGIN }; -struct SYNC_EXPORT EntryKernel { +struct EntryKernel { private: typedef syncer::ProtoValuePtr<sync_pb::EntitySpecifics> EntitySpecificsPtr; typedef syncer::ProtoValuePtr<sync_pb::AttachmentMetadata>
diff --git a/components/sync/syncable/in_memory_directory_backing_store.h b/components/sync/syncable/in_memory_directory_backing_store.h index ae29a40..472f0666 100644 --- a/components/sync/syncable/in_memory_directory_backing_store.h +++ b/components/sync/syncable/in_memory_directory_backing_store.h
@@ -8,7 +8,6 @@ #include <string> #include "base/macros.h" -#include "components/sync/base/sync_export.h" #include "components/sync/syncable/directory_backing_store.h" namespace syncer { @@ -23,7 +22,7 @@ // When an InMemoryDirectoryBackingStore is destroyed, all data stored in this // database is lost. If these limitations are a problem for you, consider using // TestDirectoryBackingStore. -class SYNC_EXPORT InMemoryDirectoryBackingStore : public DirectoryBackingStore { +class InMemoryDirectoryBackingStore : public DirectoryBackingStore { public: explicit InMemoryDirectoryBackingStore(const std::string& dir_name); DirOpenResult Load(Directory::MetahandlesMap* handles_map,
diff --git a/components/sync/syncable/invalid_directory_backing_store.h b/components/sync/syncable/invalid_directory_backing_store.h index 77270ae..cb5d599 100644 --- a/components/sync/syncable/invalid_directory_backing_store.h +++ b/components/sync/syncable/invalid_directory_backing_store.h
@@ -6,14 +6,13 @@ #define COMPONENTS_SYNC_SYNCABLE_INVALID_DIRECTORY_BACKING_STORE_H_ #include "base/macros.h" -#include "components/sync/base/sync_export.h" #include "components/sync/syncable/directory_backing_store.h" namespace syncer { namespace syncable { // A class used to test scenarios where loading a directory fails. -class SYNC_EXPORT InvalidDirectoryBackingStore : public DirectoryBackingStore { +class InvalidDirectoryBackingStore : public DirectoryBackingStore { public: InvalidDirectoryBackingStore(); ~InvalidDirectoryBackingStore() override;
diff --git a/components/sync/syncable/model_neutral_mutable_entry.h b/components/sync/syncable/model_neutral_mutable_entry.h index 005dfea..c33aa6f 100644 --- a/components/sync/syncable/model_neutral_mutable_entry.h +++ b/components/sync/syncable/model_neutral_mutable_entry.h
@@ -12,7 +12,6 @@ #include "base/macros.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/syncable/entry.h" namespace syncer { @@ -31,7 +30,7 @@ // to be communicated to the model (and the model's thread). It is not possible // to change an entry's SPECIFICS or UNIQUE_POSITION fields with this kind of // entry. -class SYNC_EXPORT ModelNeutralMutableEntry : public Entry { +class ModelNeutralMutableEntry : public Entry { public: ModelNeutralMutableEntry(BaseWriteTransaction* trans, CreateNewUpdateItem,
diff --git a/components/sync/syncable/mutable_entry.h b/components/sync/syncable/mutable_entry.h index ce25a293..bc39063 100644 --- a/components/sync/syncable/mutable_entry.h +++ b/components/sync/syncable/mutable_entry.h
@@ -11,7 +11,6 @@ #include "base/macros.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/syncable/entry.h" #include "components/sync/syncable/metahandle_set.h" #include "components/sync/syncable/model_neutral_mutable_entry.h" @@ -27,7 +26,7 @@ // A mutable meta entry. Changes get committed to the database when the // WriteTransaction is destroyed. -class SYNC_EXPORT MutableEntry : public ModelNeutralMutableEntry { +class MutableEntry : public ModelNeutralMutableEntry { void Init(WriteTransaction* trans, ModelType model_type, const Id& parent_id,
diff --git a/components/sync/syncable/nigori_handler.h b/components/sync/syncable/nigori_handler.h index 04ab29a..2f9682c 100644 --- a/components/sync/syncable/nigori_handler.h +++ b/components/sync/syncable/nigori_handler.h
@@ -8,7 +8,6 @@ #include <string> #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" namespace google { namespace protobuf { @@ -29,7 +28,7 @@ // Sync internal interface for dealing with nigori node and querying // the current set of encrypted types. Not thread safe, so a sync transaction // must be held by a caller whenever invoking methods. -class SYNC_EXPORT NigoriHandler { +class NigoriHandler { public: NigoriHandler(); virtual ~NigoriHandler();
diff --git a/components/sync/syncable/nigori_util.h b/components/sync/syncable/nigori_util.h index 344689d..e8cf670 100644 --- a/components/sync/syncable/nigori_util.h +++ b/components/sync/syncable/nigori_util.h
@@ -9,7 +9,6 @@ #include "base/compiler_specific.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/protocol/nigori_specifics.pb.h" namespace sync_pb { @@ -34,9 +33,8 @@ // false if some unsynced changes need to be encrypted. // This method is similar to ProcessUnsyncedChangesForEncryption but does not // modify the data and does not care if data is unnecessarily encrypted. -SYNC_EXPORT bool VerifyUnsyncedChangesAreEncrypted( - BaseTransaction* const trans, - ModelTypeSet encrypted_types); +bool VerifyUnsyncedChangesAreEncrypted(BaseTransaction* const trans, + ModelTypeSet encrypted_types); // Processes all unsynced changes and ensures they are appropriately encrypted // or unencrypted, based on |encrypted_types|. @@ -48,15 +46,13 @@ bool EntryNeedsEncryption(ModelTypeSet encrypted_types, const Entry& entry); // Same as EntryNeedsEncryption, but looks at specifics. -SYNC_EXPORT bool SpecificsNeedsEncryption( - ModelTypeSet encrypted_types, - const sync_pb::EntitySpecifics& specifics); +bool SpecificsNeedsEncryption(ModelTypeSet encrypted_types, + const sync_pb::EntitySpecifics& specifics); // Verifies all data of type |type| is encrypted appropriately. -SYNC_EXPORT bool VerifyDataTypeEncryptionForTest(BaseTransaction* const trans, - ModelType type, - bool is_encrypted) - WARN_UNUSED_RESULT; +bool VerifyDataTypeEncryptionForTest(BaseTransaction* const trans, + ModelType type, + bool is_encrypted) WARN_UNUSED_RESULT; // Stores |new_specifics| into |entry|, encrypting if necessary. // Returns false if an error encrypting occurred (does not modify |entry|). @@ -67,10 +63,9 @@ // Updates |nigori| to match the encryption state specified by |encrypted_types| // and |encrypt_everything|. -SYNC_EXPORT void UpdateNigoriFromEncryptedTypes( - ModelTypeSet encrypted_types, - bool encrypt_everything, - sync_pb::NigoriSpecifics* nigori); +void UpdateNigoriFromEncryptedTypes(ModelTypeSet encrypted_types, + bool encrypt_everything, + sync_pb::NigoriSpecifics* nigori); // Extracts the set of encrypted types from a nigori node. ModelTypeSet GetEncryptedTypesFromNigori(
diff --git a/components/sync/syncable/on_disk_directory_backing_store.cc b/components/sync/syncable/on_disk_directory_backing_store.cc index d7b025ec..2b9a723 100644 --- a/components/sync/syncable/on_disk_directory_backing_store.cc +++ b/components/sync/syncable/on_disk_directory_backing_store.cc
@@ -77,8 +77,8 @@ // The fallback: delete the current database and return a fresh one. We can // fetch the user's data from the cloud. - STLDeleteValues(handles_map); - STLDeleteElements(delete_journals); + base::STLDeleteValues(handles_map); + base::STLDeleteElements(delete_journals); ResetAndCreateConnection();
diff --git a/components/sync/syncable/on_disk_directory_backing_store.h b/components/sync/syncable/on_disk_directory_backing_store.h index 3036bc679..d48f97f 100644 --- a/components/sync/syncable/on_disk_directory_backing_store.h +++ b/components/sync/syncable/on_disk_directory_backing_store.h
@@ -9,7 +9,6 @@ #include "base/files/file_path.h" #include "base/macros.h" -#include "components/sync/base/sync_export.h" #include "components/sync/syncable/directory_backing_store.h" namespace syncer { @@ -17,7 +16,7 @@ // This is the concrete class that provides a useful implementation of // DirectoryBackingStore. -class SYNC_EXPORT OnDiskDirectoryBackingStore : public DirectoryBackingStore { +class OnDiskDirectoryBackingStore : public DirectoryBackingStore { public: OnDiskDirectoryBackingStore(const std::string& dir_name, const base::FilePath& backing_file_path);
diff --git a/components/sync/syncable/parent_child_index.h b/components/sync/syncable/parent_child_index.h index 2cff9cb..47a1ee5 100644 --- a/components/sync/syncable/parent_child_index.h +++ b/components/sync/syncable/parent_child_index.h
@@ -12,7 +12,6 @@ #include "base/macros.h" #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/syncable/syncable_id.h" namespace syncer { @@ -22,7 +21,7 @@ class ParentChildIndex; // A node ordering function. -struct SYNC_EXPORT ChildComparator { +struct ChildComparator { bool operator()(const EntryKernel* a, const EntryKernel* b) const; }; @@ -32,7 +31,7 @@ // Container that tracks parent-child relationships. // Provides fast lookup of all items under a given parent. -class SYNC_EXPORT ParentChildIndex { +class ParentChildIndex { public: ParentChildIndex(); ~ParentChildIndex();
diff --git a/components/sync/syncable/parent_child_index_unittest.cc b/components/sync/syncable/parent_child_index_unittest.cc index dc2cdcd3..8119c377 100644 --- a/components/sync/syncable/parent_child_index_unittest.cc +++ b/components/sync/syncable/parent_child_index_unittest.cc
@@ -27,7 +27,7 @@ void TearDown() override { // To make memory management easier, we take ownership of all EntryKernels // returned by our factory methods and delete them here. - STLDeleteElements(&owned_entry_kernels_); + base::STLDeleteElements(&owned_entry_kernels_); } // Unfortunately, we can't use the regular Entry factory methods, because the
diff --git a/components/sync/syncable/scoped_parent_child_index_updater.h b/components/sync/syncable/scoped_parent_child_index_updater.h index d6085df..75b26f2 100644 --- a/components/sync/syncable/scoped_parent_child_index_updater.h +++ b/components/sync/syncable/scoped_parent_child_index_updater.h
@@ -6,7 +6,6 @@ #define COMPONENTS_SYNC_SYNCABLE_SCOPED_PARENT_CHILD_INDEX_UPDATER_H_ #include "base/macros.h" -#include "components/sync/base/sync_export.h" namespace syncer { namespace syncable {
diff --git a/components/sync/syncable/syncable_base_transaction.h b/components/sync/syncable/syncable_base_transaction.h index 5312d13..fe232a8 100644 --- a/components/sync/syncable/syncable_base_transaction.h +++ b/components/sync/syncable/syncable_base_transaction.h
@@ -9,7 +9,6 @@ #include "base/location.h" #include "base/macros.h" -#include "components/sync/base/sync_export.h" #include "components/sync/syncable/syncable_id.h" namespace syncer { @@ -34,7 +33,7 @@ // Make sure to update this if you update WriterTag. std::string WriterTagToString(WriterTag writer_tag); -class SYNC_EXPORT BaseTransaction { +class BaseTransaction { public: static Id root_id();
diff --git a/components/sync/syncable/syncable_base_write_transaction.h b/components/sync/syncable/syncable_base_write_transaction.h index a0c24f00..a74b336 100644 --- a/components/sync/syncable/syncable_base_write_transaction.h +++ b/components/sync/syncable/syncable_base_write_transaction.h
@@ -6,7 +6,6 @@ #define COMPONENTS_SYNC_SYNCABLE_SYNCABLE_BASE_WRITE_TRANSACTION_H_ #include "base/macros.h" -#include "components/sync/base/sync_export.h" #include "components/sync/syncable/syncable_base_transaction.h" namespace syncer { @@ -14,7 +13,7 @@ // A base class shared by both ModelNeutralWriteTransaction and // WriteTransaction. -class SYNC_EXPORT BaseWriteTransaction : public BaseTransaction { +class BaseWriteTransaction : public BaseTransaction { public: virtual void TrackChangesTo(const EntryKernel* entry) = 0;
diff --git a/components/sync/syncable/syncable_delete_journal.cc b/components/sync/syncable/syncable_delete_journal.cc index a66da469..b8835ada 100644 --- a/components/sync/syncable/syncable_delete_journal.cc +++ b/components/sync/syncable/syncable_delete_journal.cc
@@ -19,7 +19,7 @@ } DeleteJournal::~DeleteJournal() { - STLDeleteElements(&delete_journals_); + base::STLDeleteElements(&delete_journals_); } size_t DeleteJournal::GetDeleteJournalSize(BaseTransaction* trans) const {
diff --git a/components/sync/syncable/syncable_delete_journal.h b/components/sync/syncable/syncable_delete_journal.h index 10558089..218f516 100644 --- a/components/sync/syncable/syncable_delete_journal.h +++ b/components/sync/syncable/syncable_delete_journal.h
@@ -12,7 +12,6 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/synchronization/lock.h" -#include "components/sync/base/sync_export.h" #include "components/sync/syncable/metahandle_set.h" #include "components/sync/syncable/syncable-inl.h" @@ -29,7 +28,7 @@ // DeleteJournal is thread-safe and can be accessed on any thread. Has to hold // a valid transaction object when calling methods of DeleteJournal, thus each // method requires a non-null |trans| parameter. -class SYNC_EXPORT DeleteJournal { +class DeleteJournal { public: // Initialize |delete_journals_| using |intitial_journal|, whose content is // destroyed during initialization.
diff --git a/components/sync/syncable/syncable_enum_conversions.h b/components/sync/syncable/syncable_enum_conversions.h index 18fc23f..c883580 100644 --- a/components/sync/syncable/syncable_enum_conversions.h +++ b/components/sync/syncable/syncable_enum_conversions.h
@@ -7,7 +7,6 @@ // Keep this file in sync with entry_kernel.h. -#include "components/sync/base/sync_export.h" #include "components/sync/syncable/entry_kernel.h" // Utility functions to get the string equivalent for some syncable @@ -19,35 +18,32 @@ // The returned strings (which don't have to be freed) are in ASCII. // The result of passing in an invalid enum value is undefined. -SYNC_EXPORT const char* GetMetahandleFieldString( - MetahandleField metahandle_field); +const char* GetMetahandleFieldString(MetahandleField metahandle_field); -SYNC_EXPORT const char* GetBaseVersionString(BaseVersion base_version); +const char* GetBaseVersionString(BaseVersion base_version); -SYNC_EXPORT const char* GetInt64FieldString(Int64Field int64_field); +const char* GetInt64FieldString(Int64Field int64_field); -SYNC_EXPORT const char* GetTimeFieldString(TimeField time_field); +const char* GetTimeFieldString(TimeField time_field); -SYNC_EXPORT const char* GetIdFieldString(IdField id_field); +const char* GetIdFieldString(IdField id_field); -SYNC_EXPORT const char* GetIndexedBitFieldString( - IndexedBitField indexed_bit_field); +const char* GetIndexedBitFieldString(IndexedBitField indexed_bit_field); -SYNC_EXPORT const char* GetIsDelFieldString(IsDelField is_del_field); +const char* GetIsDelFieldString(IsDelField is_del_field); -SYNC_EXPORT const char* GetBitFieldString(BitField bit_field); +const char* GetBitFieldString(BitField bit_field); -SYNC_EXPORT const char* GetStringFieldString(StringField string_field); +const char* GetStringFieldString(StringField string_field); -SYNC_EXPORT const char* GetProtoFieldString(ProtoField proto_field); +const char* GetProtoFieldString(ProtoField proto_field); -SYNC_EXPORT const char* GetUniquePositionFieldString( - UniquePositionField position_field); +const char* GetUniquePositionFieldString(UniquePositionField position_field); -SYNC_EXPORT const char* GetAttachmentMetadataFieldString( +const char* GetAttachmentMetadataFieldString( AttachmentMetadataField attachment_metadata_field); -SYNC_EXPORT const char* GetBitTempString(BitTemp bit_temp); +const char* GetBitTempString(BitTemp bit_temp); } // namespace syncable } // namespace syncer
diff --git a/components/sync/syncable/syncable_id.h b/components/sync/syncable/syncable_id.h index 569757b..f96fb83f1 100644 --- a/components/sync/syncable/syncable_id.h +++ b/components/sync/syncable/syncable_id.h
@@ -12,7 +12,6 @@ #include <string> #include "base/containers/hash_tables.h" -#include "components/sync/base/sync_export.h" namespace base { class StringValue; @@ -27,7 +26,7 @@ struct EntryKernel; class Id; -SYNC_EXPORT std::ostream& operator<<(std::ostream& out, const Id& id); +std::ostream& operator<<(std::ostream& out, const Id& id); // For historical reasons, 3 concepts got everloaded into the Id: // 1. A unique, opaque identifier for the object. @@ -39,7 +38,7 @@ // 1. c<client only opaque id> for client items that have not been committed. // 2. r for the root item. // 3. s<server provided opaque id> for items that the server knows about. -class SYNC_EXPORT Id { +class Id { public: inline Id() {} inline Id(const Id& that) { Copy(that); } @@ -91,7 +90,7 @@ friend std::unique_ptr<EntryKernel> UnpackEntry(sql::Statement* statement, int* total_created_entries); friend void BindFields(const EntryKernel& entry, sql::Statement* statement); - SYNC_EXPORT friend std::ostream& operator<<(std::ostream& out, const Id& id); + friend std::ostream& operator<<(std::ostream& out, const Id& id); friend class SyncableIdTest; std::string s_;
diff --git a/components/sync/syncable/syncable_model_neutral_write_transaction.h b/components/sync/syncable/syncable_model_neutral_write_transaction.h index 915c60b5b..fddadd61 100644 --- a/components/sync/syncable/syncable_model_neutral_write_transaction.h +++ b/components/sync/syncable/syncable_model_neutral_write_transaction.h
@@ -6,7 +6,6 @@ #define COMPONENTS_SYNC_SYNCABLE_SYNCABLE_MODEL_NEUTRAL_WRITE_TRANSACTION_H_ #include "base/macros.h" -#include "components/sync/base/sync_export.h" #include "components/sync/syncable/metahandle_set.h" #include "components/sync/syncable/syncable_base_write_transaction.h" @@ -22,7 +21,7 @@ // good job of tracking and reporting on changes to the entries modified within // its scope. This is because its changes do not need to be reported to the // DirectoryChangeDelegate. -class SYNC_EXPORT ModelNeutralWriteTransaction : public BaseWriteTransaction { +class ModelNeutralWriteTransaction : public BaseWriteTransaction { public: ModelNeutralWriteTransaction(const tracked_objects::Location& location, WriterTag writer,
diff --git a/components/sync/syncable/syncable_proto_util.h b/components/sync/syncable/syncable_proto_util.h index 49ba6b10..14a7353e 100644 --- a/components/sync/syncable/syncable_proto_util.h +++ b/components/sync/syncable/syncable_proto_util.h
@@ -7,7 +7,6 @@ #include <string> -#include "components/sync/base/sync_export.h" #include "components/sync/syncable/syncable_id.h" namespace sync_pb { @@ -22,7 +21,7 @@ // Converts from a syncable::Id to a formatted std::string. This is useful for // populating the fields of a protobuf which will be sent to the server. -SYNC_EXPORT std::string SyncableIdToProto(const syncable::Id& syncable_id); +std::string SyncableIdToProto(const syncable::Id& syncable_id); // Helper function to determine if this SyncEntity's properties indicate that it // is a folder.
diff --git a/components/sync/syncable/syncable_read_transaction.h b/components/sync/syncable/syncable_read_transaction.h index 10652a4..71c500f 100644 --- a/components/sync/syncable/syncable_read_transaction.h +++ b/components/sync/syncable/syncable_read_transaction.h
@@ -8,7 +8,6 @@ #include <stddef.h> #include "base/macros.h" -#include "components/sync/base/sync_export.h" #include "components/sync/syncable/syncable_base_transaction.h" namespace syncer { @@ -16,7 +15,7 @@ namespace syncable { // Locks db in constructor, unlocks in destructor. -class SYNC_EXPORT ReadTransaction : public BaseTransaction { +class ReadTransaction : public BaseTransaction { public: ReadTransaction(const tracked_objects::Location& from_here, Directory* directory);
diff --git a/components/sync/syncable/syncable_util.h b/components/sync/syncable/syncable_util.h index 323e532..37dbbe95 100644 --- a/components/sync/syncable/syncable_util.h +++ b/components/sync/syncable/syncable_util.h
@@ -11,7 +11,6 @@ #include <vector> #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" namespace tracked_objects { class Location; @@ -25,30 +24,27 @@ class ModelNeutralMutableEntry; class Id; -SYNC_EXPORT void ChangeEntryIDAndUpdateChildren(BaseWriteTransaction* trans, - ModelNeutralMutableEntry* entry, - const Id& new_id); +void ChangeEntryIDAndUpdateChildren(BaseWriteTransaction* trans, + ModelNeutralMutableEntry* entry, + const Id& new_id); -SYNC_EXPORT bool IsLegalNewParent(BaseTransaction* trans, - const Id& id, - const Id& parentid); +bool IsLegalNewParent(BaseTransaction* trans, const Id& id, const Id& parentid); bool SyncAssert(bool condition, const tracked_objects::Location& location, const char* msg, BaseTransaction* trans); -SYNC_EXPORT int GetUnsyncedEntries(BaseTransaction* trans, - std::vector<int64_t>* handles); +int GetUnsyncedEntries(BaseTransaction* trans, std::vector<int64_t>* handles); // Generates a fixed-length tag for the given string under the given model_type. -SYNC_EXPORT std::string GenerateSyncableHash(ModelType model_type, - const std::string& client_tag); +std::string GenerateSyncableHash(ModelType model_type, + const std::string& client_tag); // A helper for generating the bookmark type's tag. This is required in more // than one place, so we define the algorithm here to make sure the // implementation is consistent. -SYNC_EXPORT std::string GenerateSyncableBookmarkHash( +std::string GenerateSyncableBookmarkHash( const std::string& originator_cache_guid, const std::string& originator_client_item_id);
diff --git a/components/sync/syncable/syncable_write_transaction.h b/components/sync/syncable/syncable_write_transaction.h index 05a2fe52..57135a6 100644 --- a/components/sync/syncable/syncable_write_transaction.h +++ b/components/sync/syncable/syncable_write_transaction.h
@@ -10,17 +10,16 @@ #include <vector> #include "base/macros.h" -#include "components/sync/base/sync_export.h" #include "components/sync/syncable/entry_kernel.h" #include "components/sync/syncable/syncable_base_write_transaction.h" namespace syncer { namespace syncable { -SYNC_EXPORT extern const int64_t kInvalidTransactionVersion; +extern const int64_t kInvalidTransactionVersion; // Locks db in constructor, unlocks in destructor. -class SYNC_EXPORT WriteTransaction : public BaseWriteTransaction { +class WriteTransaction : public BaseWriteTransaction { public: WriteTransaction(const tracked_objects::Location& from_here, WriterTag writer,
diff --git a/components/sync/syncable/transaction_observer.h b/components/sync/syncable/transaction_observer.h index 536b7cf..d96e894 100644 --- a/components/sync/syncable/transaction_observer.h +++ b/components/sync/syncable/transaction_observer.h
@@ -6,13 +6,12 @@ #define COMPONENTS_SYNC_SYNCABLE_TRANSACTION_OBSERVER_H_ #include "components/sync/base/model_type.h" -#include "components/sync/base/sync_export.h" #include "components/sync/syncable/write_transaction_info.h" namespace syncer { namespace syncable { -class SYNC_EXPORT TransactionObserver { +class TransactionObserver { public: virtual void OnTransactionWrite( const ImmutableWriteTransactionInfo& write_transaction_info,
diff --git a/components/sync/test/android/javatests/src/org/chromium/components/sync/test/util/MockAccountManager.java b/components/sync/test/android/javatests/src/org/chromium/components/sync/test/util/MockAccountManager.java index 787889f..ad4db3e00 100644 --- a/components/sync/test/android/javatests/src/org/chromium/components/sync/test/util/MockAccountManager.java +++ b/components/sync/test/android/javatests/src/org/chromium/components/sync/test/util/MockAccountManager.java
@@ -7,12 +7,14 @@ import android.accounts.Account; import android.accounts.AccountManager; import android.accounts.AuthenticatorDescription; +import android.app.Activity; import android.content.Context; import android.content.Intent; import android.os.AsyncTask; import org.chromium.base.Callback; import org.chromium.base.Log; +import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.components.sync.signin.AccountManagerDelegate; import org.chromium.components.sync.signin.AccountManagerHelper; @@ -216,6 +218,18 @@ }); } + @Override + public void updateCredentials( + Account account, Activity activity, final Callback<Boolean> callback) { + ThreadUtils.assertOnUiThread(); + ThreadUtils.postOnUiThread(new Runnable() { + @Override + public void run() { + callback.onResult(true); + } + }); + } + private AccountHolder getAccountHolder(Account account) { if (account == null) { throw new IllegalArgumentException("Account can not be null");
diff --git a/components/sync/test/engine/mock_model_type_worker.cc b/components/sync/test/engine/mock_model_type_worker.cc index af40a23..34620a3 100644 --- a/components/sync/test/engine/mock_model_type_worker.cc +++ b/components/sync/test/engine/mock_model_type_worker.cc
@@ -16,18 +16,6 @@ namespace { -std::string GenerateTagHash(const std::string& tag) { - return syncer::syncable::GenerateSyncableHash(syncer::PREFERENCES, tag); -} - -sync_pb::EntitySpecifics GenerateSpecifics(const std::string& tag, - const std::string& value) { - sync_pb::EntitySpecifics specifics; - specifics.mutable_preference()->set_name(tag); - specifics.mutable_preference()->set_value(value); - return specifics; -} - } // namespace MockModelTypeWorker::MockModelTypeWorker( @@ -50,8 +38,8 @@ return pending_commits_[n]; } -bool MockModelTypeWorker::HasPendingCommitForTag(const std::string& tag) const { - const std::string tag_hash = GenerateTagHash(tag); +bool MockModelTypeWorker::HasPendingCommitForHash( + const std::string& tag_hash) const { for (const CommitRequestDataList& commit : pending_commits_) { for (const CommitRequestData& data : commit) { if (data.entity->client_tag_hash == tag_hash) { @@ -62,9 +50,8 @@ return false; } -CommitRequestData MockModelTypeWorker::GetLatestPendingCommitForTag( - const std::string& tag) const { - const std::string tag_hash = GenerateTagHash(tag); +CommitRequestData MockModelTypeWorker::GetLatestPendingCommitForHash( + const std::string& tag_hash) const { // Iterate backward through the sets of commit requests to find the most // recent one that applies to the specified tag_hash. for (auto rev_it = pending_commits_.rbegin(); @@ -79,54 +66,58 @@ return CommitRequestData(); } -void MockModelTypeWorker::ExpectNthPendingCommit(size_t n, - const std::string& tag, - const std::string& value) { +void MockModelTypeWorker::ExpectNthPendingCommit( + size_t n, + const std::string& tag_hash, + const sync_pb::EntitySpecifics& specifics) { const CommitRequestDataList& list = GetNthPendingCommit(n); ASSERT_EQ(1U, list.size()); const EntityData& data = list[0].entity.value(); - EXPECT_EQ(GenerateTagHash(tag), data.client_tag_hash); - EXPECT_EQ(value, data.specifics.preference().value()); + EXPECT_EQ(tag_hash, data.client_tag_hash); + EXPECT_EQ(specifics.SerializeAsString(), data.specifics.SerializeAsString()); } void MockModelTypeWorker::ExpectPendingCommits( - const std::vector<std::string>& tags) { - EXPECT_EQ(tags.size(), GetNumPendingCommits()); - for (size_t i = 0; i < tags.size(); i++) { + const std::vector<std::string>& tag_hashes) { + EXPECT_EQ(tag_hashes.size(), GetNumPendingCommits()); + for (size_t i = 0; i < tag_hashes.size(); i++) { const CommitRequestDataList& commits = GetNthPendingCommit(i); EXPECT_EQ(1U, commits.size()); - EXPECT_EQ(GenerateTagHash(tags[i]), commits[0].entity->client_tag_hash) - << "Hash for tag " << tags[i] << " doesn't match."; + EXPECT_EQ(tag_hashes[i], commits[0].entity->client_tag_hash) + << "Hash for tag " << tag_hashes[i] << " doesn't match."; } } -void MockModelTypeWorker::UpdateFromServer(const std::string& tag, - const std::string& value) { - UpdateFromServer(tag, value, 1); +void MockModelTypeWorker::UpdateFromServer( + const std::string& tag_hash, + const sync_pb::EntitySpecifics& specifics) { + UpdateFromServer(tag_hash, specifics, 1); } -void MockModelTypeWorker::UpdateFromServer(const std::string& tag, - const std::string& value, - int64_t version_offset) { - UpdateFromServer(tag, value, version_offset, +void MockModelTypeWorker::UpdateFromServer( + const std::string& tag_hash, + const sync_pb::EntitySpecifics& specifics, + int64_t version_offset) { + UpdateFromServer(tag_hash, specifics, version_offset, data_type_state_.encryption_key_name()); } -void MockModelTypeWorker::UpdateFromServer(const std::string& tag, - const std::string& value, - int64_t version_offset, - const std::string& ekn) { +void MockModelTypeWorker::UpdateFromServer( + const std::string& tag_hash, + const sync_pb::EntitySpecifics& specifics, + int64_t version_offset, + const std::string& ekn) { UpdateResponseDataList update; - update.push_back(GenerateUpdateData(tag, value, version_offset, ekn)); + update.push_back( + GenerateUpdateData(tag_hash, specifics, version_offset, ekn)); processor_->OnUpdateReceived(data_type_state_, update); } UpdateResponseData MockModelTypeWorker::GenerateUpdateData( - const std::string& tag, - const std::string& value, + const std::string& tag_hash, + const sync_pb::EntitySpecifics& specifics, int64_t version_offset, const std::string& ekn) { - const std::string tag_hash = GenerateTagHash(tag); // Overwrite the existing server version if this is the new highest version. int64_t old_version = GetServerVersion(tag_hash); int64_t version = old_version + version_offset; @@ -137,7 +128,7 @@ EntityData data; data.id = GenerateId(tag_hash); data.client_tag_hash = tag_hash; - data.specifics = GenerateSpecifics(tag, value); + data.specifics = specifics; // These elements should have no effect on behavior, but we set them anyway // so we can test they are properly copied around the system if we want to. data.creation_time = base::Time::UnixEpoch() + base::TimeDelta::FromDays(1); @@ -153,8 +144,7 @@ return response_data; } -void MockModelTypeWorker::TombstoneFromServer(const std::string& tag) { - const std::string tag_hash = GenerateTagHash(tag); +void MockModelTypeWorker::TombstoneFromServer(const std::string& tag_hash) { int64_t old_version = GetServerVersion(tag_hash); int64_t version = old_version + 1; SetServerVersion(tag_hash, version);
diff --git a/components/sync/test/engine/mock_model_type_worker.h b/components/sync/test/engine/mock_model_type_worker.h index b4a9879..7f9e090 100644 --- a/components/sync/test/engine/mock_model_type_worker.h +++ b/components/sync/test/engine/mock_model_type_worker.h
@@ -18,6 +18,7 @@ #include "components/sync/core/non_blocking_sync_common.h" #include "components/sync/engine_impl/commit_queue.h" #include "components/sync/protocol/data_type_state.pb.h" +#include "components/sync/protocol/sync.pb.h" namespace syncer_v2 { @@ -38,47 +39,50 @@ // Getters to inspect the requests sent to this object. size_t GetNumPendingCommits() const; CommitRequestDataList GetNthPendingCommit(size_t n) const; - bool HasPendingCommitForTag(const std::string& tag) const; - CommitRequestData GetLatestPendingCommitForTag(const std::string& tag) const; + bool HasPendingCommitForHash(const std::string& tag_hash) const; + CommitRequestData GetLatestPendingCommitForHash( + const std::string& tag_hash) const; // Expect that the |n|th commit request list has one commit request for |tag| // with |value| set. void ExpectNthPendingCommit(size_t n, - const std::string& tag, - const std::string& value); + const std::string& tag_hash, + const sync_pb::EntitySpecifics& specifics); - // For each tag in |tags|, expect a corresponding request list of length one. - void ExpectPendingCommits(const std::vector<std::string>& tags); + // For each hash in |tag_hashes|, expect a corresponding request list of + // length one. + void ExpectPendingCommits(const std::vector<std::string>& tag_hashes); // Trigger an update from the server containing a single entity. See // GenerateUpdateData for parameter descriptions. |version_offset| defaults to // 1 and |ekn| defaults to the current encryption key name the worker has. - void UpdateFromServer(const std::string& tag, const std::string& value); - void UpdateFromServer(const std::string& tag, - const std::string& value, + void UpdateFromServer(const std::string& tag_hash, + const sync_pb::EntitySpecifics& specifics); + void UpdateFromServer(const std::string& tag_hash, + const sync_pb::EntitySpecifics& specifics, int64_t version_offset); - void UpdateFromServer(const std::string& tag, - const std::string& value, + void UpdateFromServer(const std::string& tag_hash, + const sync_pb::EntitySpecifics& specifics, int64_t version_offset, const std::string& ekn); // Returns an UpdateResponseData representing an update received from - // the server. Updates server state accordingly. |tag| is used to generate the - // tag hash and the specifics along with |value|. + // the server. Updates server state accordingly. // // The |version_offset| field can be used to emulate stale data (ie. versions // going backwards), reflections and redeliveries (ie. several instances of // the same version) or new updates. // // |ekn| is the encryption key name this item will fake having. - UpdateResponseData GenerateUpdateData(const std::string& tag, - const std::string& value, - int64_t version_offset, - const std::string& ekn); + UpdateResponseData GenerateUpdateData( + const std::string& tag_hash, + const sync_pb::EntitySpecifics& specifics, + int64_t version_offset, + const std::string& ekn); - // Triggers a server-side deletion of the entity with |tag|; updates server - // state accordingly. - void TombstoneFromServer(const std::string& tag); + // Triggers a server-side deletion of the entity with |tag_hash|; updates + // server state accordingly. + void TombstoneFromServer(const std::string& tag_hash); // Pops one pending commit from the front of the queue and send a commit // response to the processor for it. @@ -111,7 +115,7 @@ // A record of past commits requests. std::deque<CommitRequestDataList> pending_commits_; - // Map of versions by client tag. + // Map of versions by client tag hash. // This is an essential part of the mocked server state. std::map<const std::string, int64_t> server_versions_;
diff --git a/components/sync/test/sessions/mock_debug_info_getter.h b/components/sync/test/sessions/mock_debug_info_getter.h index f9a2df6..5ecc421 100644 --- a/components/sync/test/sessions/mock_debug_info_getter.h +++ b/components/sync/test/sessions/mock_debug_info_getter.h
@@ -7,7 +7,6 @@ #include "base/compiler_specific.h" #include "base/macros.h" -#include "components/sync/base/sync_export.h" #include "components/sync/protocol/sync.pb.h" #include "components/sync/sessions_impl/debug_info_getter.h"
diff --git a/components/sync/tools/BUILD.gn b/components/sync/tools/BUILD.gn index 8d45608..8951abfb 100644 --- a/components/sync/tools/BUILD.gn +++ b/components/sync/tools/BUILD.gn
@@ -16,7 +16,6 @@ "//base", "//components/invalidation/impl", "//components/sync", - "//components/sync_driver", ] } @@ -32,7 +31,6 @@ "//base", "//components/invalidation/impl", "//components/sync:test_support_sync_core", - "//components/sync_driver", "//jingle:notifier", "//net:test_support", ] @@ -50,7 +48,6 @@ "//base", "//components/invalidation/impl", "//components/sync:test_support_sync_core", - "//components/sync_driver", "//jingle:notifier", "//net:test_support", ]
diff --git a/components/sync/tools/DEPS b/components/sync/tools/DEPS index 121f092..46378d32 100644 --- a/components/sync/tools/DEPS +++ b/components/sync/tools/DEPS
@@ -2,11 +2,11 @@ "+components/invalidation", "+components/sync/base", "+components/sync/core", + "+components/sync/driver", "+components/sync/engine", "+components/sync/js", # TODO(maxbogue): Move to base. "+components/sync/test/fake_encryptor.h", - "+components/sync_driver", "+google/cacheinvalidation", "+jingle/notifier/base", "+net",
diff --git a/components/sync/tools/sync_client.cc b/components/sync/tools/sync_client.cc index e6e12ef..14071296 100644 --- a/components/sync/tools/sync_client.cc +++ b/components/sync/tools/sync_client.cc
@@ -39,12 +39,12 @@ #include "components/sync/core/read_node.h" #include "components/sync/core/sync_manager.h" #include "components/sync/core/sync_manager_factory.h" +#include "components/sync/driver/invalidation_helper.h" #include "components/sync/engine/passive_model_worker.h" #include "components/sync/js/js_event_details.h" #include "components/sync/js/js_event_handler.h" #include "components/sync/test/fake_encryptor.h" #include "components/sync/tools/null_invalidation_state_tracker.h" -#include "components/sync_driver/invalidation_helper.h" #include "jingle/notifier/base/notification_method.h" #include "jingle/notifier/base/notifier_options.h" #include "net/base/host_port_pair.h"
diff --git a/components/sync/tools/sync_listen_notifications.cc b/components/sync/tools/sync_listen_notifications.cc index ab5ad57..0c150cd3 100644 --- a/components/sync/tools/sync_listen_notifications.cc +++ b/components/sync/tools/sync_listen_notifications.cc
@@ -26,8 +26,8 @@ #include "components/invalidation/public/invalidation_util.h" #include "components/invalidation/public/object_id_invalidation_map.h" #include "components/sync/base/model_type.h" +#include "components/sync/driver/invalidation_helper.h" #include "components/sync/tools/null_invalidation_state_tracker.h" -#include "components/sync_driver/invalidation_helper.h" #include "jingle/notifier/base/notification_method.h" #include "jingle/notifier/base/notifier_options.h" #include "net/base/host_port_pair.h"
diff --git a/components/sync/tools/sync_tools.gyp b/components/sync/tools/sync_tools.gyp index 982c96b..c5bf2776 100644 --- a/components/sync/tools/sync_tools.gyp +++ b/components/sync/tools/sync_tools.gyp
@@ -40,7 +40,6 @@ 'dependencies': [ '../../../base/base.gyp:base', '../../../components/components.gyp:invalidation_impl', - '../../../components/components.gyp:sync_driver', '../../../jingle/jingle.gyp:notifier', '../../../net/net.gyp:net', '../../../net/net.gyp:net_test_support', @@ -63,7 +62,6 @@ 'dependencies': [ '../../../base/base.gyp:base', '../../../components/components.gyp:invalidation_impl', - '../../../components/components.gyp:sync_driver', '../../../jingle/jingle.gyp:notifier', '../../../net/net.gyp:net', '../../../net/net.gyp:net_test_support',
diff --git a/components/sync_bookmarks.gypi b/components/sync_bookmarks.gypi index 73061da3..cea0e3b 100644 --- a/components/sync_bookmarks.gypi +++ b/components/sync_bookmarks.gypi
@@ -15,7 +15,7 @@ 'bookmarks_browser', 'favicon_core', 'history_core_browser', - 'sync_driver', + 'sync.gyp:sync', 'undo_component', ], 'include_dirs': [
diff --git a/components/sync_bookmarks/BUILD.gn b/components/sync_bookmarks/BUILD.gn index 7a1a40c..12b3607 100644 --- a/components/sync_bookmarks/BUILD.gn +++ b/components/sync_bookmarks/BUILD.gn
@@ -20,7 +20,6 @@ "//components/favicon/core", "//components/history/core/browser", "//components/sync", - "//components/sync_driver", "//components/undo", "//ui/gfx", ] @@ -41,8 +40,7 @@ "//components/history/core/browser", "//components/prefs:test_support", "//components/sync", - "//components/sync_driver", - "//components/sync_driver:test_support", + "//components/sync:test_support_sync_driver", "//testing/gmock", "//testing/gtest", ]
diff --git a/components/sync_bookmarks/DEPS b/components/sync_bookmarks/DEPS index a22632f..0d5798c 100644 --- a/components/sync_bookmarks/DEPS +++ b/components/sync_bookmarks/DEPS
@@ -5,7 +5,6 @@ "+components/history/core/browser", "+components/prefs", "+components/sync", - "+components/sync_driver", "+components/undo", "+ui/gfx", ]
diff --git a/components/sync_bookmarks/bookmark_change_processor.cc b/components/sync_bookmarks/bookmark_change_processor.cc index fdd9c68..b7dbe87 100644 --- a/components/sync_bookmarks/bookmark_change_processor.cc +++ b/components/sync_bookmarks/bookmark_change_processor.cc
@@ -25,9 +25,9 @@ #include "components/sync/core/read_node.h" #include "components/sync/core/write_node.h" #include "components/sync/core/write_transaction.h" +#include "components/sync/driver/sync_client.h" #include "components/sync/syncable/entry.h" // TODO(tim): Investigating bug 121587. #include "components/sync/syncable/syncable_write_transaction.h" -#include "components/sync_driver/sync_client.h" #include "components/undo/bookmark_undo_service.h" #include "components/undo/bookmark_undo_utils.h" #include "ui/gfx/favicon_size.h"
diff --git a/components/sync_bookmarks/bookmark_change_processor.h b/components/sync_bookmarks/bookmark_change_processor.h index 57139b03..4102b788 100644 --- a/components/sync_bookmarks/bookmark_change_processor.h +++ b/components/sync_bookmarks/bookmark_change_processor.h
@@ -16,8 +16,8 @@ #include "components/bookmarks/browser/bookmark_model_observer.h" #include "components/bookmarks/browser/bookmark_node.h" #include "components/sync/core/data_type_error_handler.h" +#include "components/sync/driver/change_processor.h" #include "components/sync_bookmarks/bookmark_model_associator.h" -#include "components/sync_driver/change_processor.h" class Profile;
diff --git a/components/sync_bookmarks/bookmark_data_type_controller.cc b/components/sync_bookmarks/bookmark_data_type_controller.cc index 85e71fa..54a80617 100644 --- a/components/sync_bookmarks/bookmark_data_type_controller.cc +++ b/components/sync_bookmarks/bookmark_data_type_controller.cc
@@ -7,8 +7,8 @@ #include "base/metrics/histogram.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/history/core/browser/history_service.h" -#include "components/sync_driver/sync_api_component_factory.h" -#include "components/sync_driver/sync_client.h" +#include "components/sync/driver/sync_api_component_factory.h" +#include "components/sync/driver/sync_client.h" using bookmarks::BookmarkModel;
diff --git a/components/sync_bookmarks/bookmark_data_type_controller.h b/components/sync_bookmarks/bookmark_data_type_controller.h index 578e2de..9b7fce4 100644 --- a/components/sync_bookmarks/bookmark_data_type_controller.h +++ b/components/sync_bookmarks/bookmark_data_type_controller.h
@@ -12,7 +12,7 @@ #include "base/scoped_observer.h" #include "components/bookmarks/browser/base_bookmark_model_observer.h" #include "components/history/core/browser/history_service_observer.h" -#include "components/sync_driver/frontend_data_type_controller.h" +#include "components/sync/driver/frontend_data_type_controller.h" namespace browser_sync {
diff --git a/components/sync_bookmarks/bookmark_data_type_controller_unittest.cc b/components/sync_bookmarks/bookmark_data_type_controller_unittest.cc index 0cc618a..8a196141 100644 --- a/components/sync_bookmarks/bookmark_data_type_controller_unittest.cc +++ b/components/sync_bookmarks/bookmark_data_type_controller_unittest.cc
@@ -19,12 +19,12 @@ #include "components/history/core/browser/history_service.h" #include "components/prefs/testing_pref_service.h" #include "components/sync/api/sync_error.h" -#include "components/sync_driver/change_processor_mock.h" -#include "components/sync_driver/data_type_controller_mock.h" -#include "components/sync_driver/fake_sync_client.h" -#include "components/sync_driver/fake_sync_service.h" -#include "components/sync_driver/model_associator_mock.h" -#include "components/sync_driver/sync_api_component_factory_mock.h" +#include "components/sync/driver/change_processor_mock.h" +#include "components/sync/driver/data_type_controller_mock.h" +#include "components/sync/driver/fake_sync_client.h" +#include "components/sync/driver/fake_sync_service.h" +#include "components/sync/driver/model_associator_mock.h" +#include "components/sync/driver/sync_api_component_factory_mock.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/components/sync_bookmarks/bookmark_model_associator.cc b/components/sync_bookmarks/bookmark_model_associator.cc index 7f23837..e49f91f5 100644 --- a/components/sync_bookmarks/bookmark_model_associator.cc +++ b/components/sync_bookmarks/bookmark_model_associator.cc
@@ -30,10 +30,10 @@ #include "components/sync/core/write_node.h" #include "components/sync/core/write_transaction.h" #include "components/sync/core_impl/syncapi_internal.h" +#include "components/sync/driver/sync_client.h" #include "components/sync/syncable/entry.h" #include "components/sync/syncable/syncable_write_transaction.h" #include "components/sync_bookmarks/bookmark_change_processor.h" -#include "components/sync_driver/sync_client.h" #include "components/undo/bookmark_undo_service.h" #include "components/undo/bookmark_undo_utils.h"
diff --git a/components/sync_bookmarks/bookmark_model_associator.h b/components/sync_bookmarks/bookmark_model_associator.h index 70ae0a3..37c8276 100644 --- a/components/sync_bookmarks/bookmark_model_associator.h +++ b/components/sync_bookmarks/bookmark_model_associator.h
@@ -23,7 +23,7 @@ #include "base/threading/thread_checker.h" #include "components/sync/base/unrecoverable_error_handler.h" #include "components/sync/core/data_type_error_handler.h" -#include "components/sync_driver/model_associator.h" +#include "components/sync/driver/model_associator.h" class GURL;
diff --git a/components/sync_driver.gypi b/components/sync_driver.gypi deleted file mode 100644 index 48c0a9b4..0000000 --- a/components/sync_driver.gypi +++ /dev/null
@@ -1,207 +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. - -{ - 'targets': [ - { - # GN version: //components/sync_driver - 'target_name': 'sync_driver', - 'type': 'static_library', - 'dependencies': [ - '../base/base.gyp:base', - '../net/net.gyp:net', - '../components/sync.gyp:sync', - '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation', - '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_proto_cpp', - 'data_use_measurement_core', - 'invalidation_public', - 'metrics', - 'os_crypt', - 'signin_core_browser', - 'version_info', - ], - 'export_dependent_settings': [ - '../components/sync.gyp:sync', - '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation', - ], - 'include_dirs': [ - '..', - ], - 'sources': [ - # Note: file list duplicated in GN build. - 'sync_driver/about_sync_util.cc', - 'sync_driver/about_sync_util.h', - 'sync_driver/backend_data_type_configurer.cc', - 'sync_driver/backend_data_type_configurer.h', - 'sync_driver/backend_migrator.cc', - 'sync_driver/backend_migrator.h', - 'sync_driver/change_processor.cc', - 'sync_driver/change_processor.h', - 'sync_driver/data_type_controller.cc', - 'sync_driver/data_type_controller.h', - 'sync_driver/data_type_encryption_handler.cc', - 'sync_driver/data_type_encryption_handler.h', - 'sync_driver/data_type_manager.cc', - 'sync_driver/data_type_manager.h', - 'sync_driver/data_type_manager_impl.cc', - 'sync_driver/data_type_manager_impl.h', - 'sync_driver/data_type_manager_observer.h', - 'sync_driver/data_type_status_table.cc', - 'sync_driver/data_type_status_table.h', - 'sync_driver/device_count_metrics_provider.cc', - 'sync_driver/device_count_metrics_provider.h', - 'sync_driver/device_info.cc', - 'sync_driver/device_info.h', - 'sync_driver/device_info_data_type_controller.cc', - 'sync_driver/device_info_data_type_controller.h', - 'sync_driver/device_info_service.cc', - 'sync_driver/device_info_service.h', - 'sync_driver/device_info_sync_service.cc', - 'sync_driver/device_info_sync_service.h', - 'sync_driver/device_info_tracker.h', - 'sync_driver/device_info_util.cc', - 'sync_driver/device_info_util.h', - 'sync_driver/directory_data_type_controller.cc', - 'sync_driver/directory_data_type_controller.h', - 'sync_driver/frontend_data_type_controller.cc', - 'sync_driver/frontend_data_type_controller.h', - 'sync_driver/generic_change_processor.cc', - 'sync_driver/generic_change_processor.h', - 'sync_driver/generic_change_processor_factory.cc', - 'sync_driver/generic_change_processor_factory.h', - 'sync_driver/glue/browser_thread_model_worker.cc', - 'sync_driver/glue/browser_thread_model_worker.h', - 'sync_driver/glue/chrome_report_unrecoverable_error.cc', - 'sync_driver/glue/chrome_report_unrecoverable_error.h', - 'sync_driver/glue/sync_backend_host.cc', - 'sync_driver/glue/sync_backend_host.h', - 'sync_driver/glue/sync_backend_host_core.cc', - 'sync_driver/glue/sync_backend_host_core.h', - 'sync_driver/glue/sync_backend_host_impl.cc', - 'sync_driver/glue/sync_backend_host_impl.h', - 'sync_driver/glue/sync_backend_registrar.cc', - 'sync_driver/glue/sync_backend_registrar.h', - 'sync_driver/glue/ui_model_worker.cc', - 'sync_driver/glue/ui_model_worker.h', - 'sync_driver/invalidation_adapter.cc', - 'sync_driver/invalidation_adapter.h', - 'sync_driver/invalidation_helper.cc', - 'sync_driver/invalidation_helper.h', - 'sync_driver/local_device_info_provider.h', - 'sync_driver/local_device_info_provider_impl.cc', - 'sync_driver/local_device_info_provider_impl.h', - 'sync_driver/model_association_manager.cc', - 'sync_driver/model_association_manager.h', - 'sync_driver/model_associator.h', - 'sync_driver/non_blocking_data_type_controller.cc', - 'sync_driver/non_blocking_data_type_controller.h', - 'sync_driver/non_ui_data_type_controller.cc', - 'sync_driver/non_ui_data_type_controller.h', - 'sync_driver/non_ui_model_type_controller.cc', - 'sync_driver/non_ui_model_type_controller.h', - 'sync_driver/pref_names.cc', - 'sync_driver/pref_names.h', - 'sync_driver/profile_sync_auth_provider.cc', - 'sync_driver/profile_sync_auth_provider.h', - 'sync_driver/protocol_event_observer.cc', - 'sync_driver/protocol_event_observer.h', - 'sync_driver/proxy_data_type_controller.cc', - 'sync_driver/proxy_data_type_controller.h', - 'sync_driver/shared_change_processor.cc', - 'sync_driver/shared_change_processor.h', - 'sync_driver/shared_change_processor_ref.cc', - 'sync_driver/shared_change_processor_ref.h', - 'sync_driver/signin_manager_wrapper.cc', - 'sync_driver/signin_manager_wrapper.h', - 'sync_driver/startup_controller.cc', - 'sync_driver/startup_controller.h', - 'sync_driver/sync_api_component_factory.h', - 'sync_driver/sync_client.cc', - 'sync_driver/sync_client.h', - 'sync_driver/sync_driver_switches.cc', - 'sync_driver/sync_driver_switches.h', - 'sync_driver/sync_error_controller.cc', - 'sync_driver/sync_error_controller.h', - 'sync_driver/sync_frontend.cc', - 'sync_driver/sync_frontend.h', - 'sync_driver/sync_prefs.cc', - 'sync_driver/sync_prefs.h', - 'sync_driver/sync_service.cc', - 'sync_driver/sync_service.h', - 'sync_driver/sync_service_observer.cc', - 'sync_driver/sync_service_observer.h', - 'sync_driver/sync_service_utils.cc', - 'sync_driver/sync_service_utils.h', - 'sync_driver/sync_stopped_reporter.cc', - 'sync_driver/sync_stopped_reporter.h', - 'sync_driver/sync_type_preference_provider.h', - 'sync_driver/sync_util.cc', - 'sync_driver/sync_util.h', - 'sync_driver/system_encryptor.cc', - 'sync_driver/system_encryptor.h', - 'sync_driver/ui_data_type_controller.cc', - 'sync_driver/ui_data_type_controller.h', - 'sync_driver/ui_model_type_controller.cc', - 'sync_driver/ui_model_type_controller.h', - 'sync_driver/user_selectable_sync_type.h', - ], - 'conditions': [ - ['configuration_policy==1', { - 'dependencies': [ - 'policy', - 'policy_component', - ], - 'sources': [ - 'sync_driver/sync_policy_handler.cc', - 'sync_driver/sync_policy_handler.h', - ], - }], - ], - }, - { - 'target_name': 'sync_driver_test_support', - 'type': 'static_library', - 'dependencies': [ - 'sync_driver', - 'version_info', - '../base/base.gyp:base', - '../components/sync.gyp:sync', - '../components/sync.gyp:test_support_sync_core_impl', - '../testing/gmock.gyp:gmock', - '../testing/gtest.gyp:gtest', - ], - 'include_dirs': [ - '..', - ], - 'sources': [ - 'sync_driver/change_processor_mock.cc', - 'sync_driver/change_processor_mock.h', - 'sync_driver/data_type_controller_mock.cc', - 'sync_driver/data_type_controller_mock.h', - 'sync_driver/data_type_manager_mock.cc', - 'sync_driver/data_type_manager_mock.h', - 'sync_driver/fake_data_type_controller.cc', - 'sync_driver/fake_data_type_controller.h', - 'sync_driver/fake_generic_change_processor.cc', - 'sync_driver/fake_generic_change_processor.h', - 'sync_driver/fake_sync_client.cc', - 'sync_driver/fake_sync_client.h', - 'sync_driver/fake_sync_service.cc', - 'sync_driver/fake_sync_service.h', - 'sync_driver/frontend_data_type_controller_mock.cc', - 'sync_driver/frontend_data_type_controller_mock.h', - 'sync_driver/glue/sync_backend_host_mock.cc', - 'sync_driver/glue/sync_backend_host_mock.h', - 'sync_driver/local_device_info_provider_mock.cc', - 'sync_driver/local_device_info_provider_mock.h', - 'sync_driver/model_associator_mock.cc', - 'sync_driver/model_associator_mock.h', - 'sync_driver/non_ui_data_type_controller_mock.cc', - 'sync_driver/non_ui_data_type_controller_mock.h', - 'sync_driver/sync_api_component_factory_mock.cc', - 'sync_driver/sync_api_component_factory_mock.h', - ], - }, - ], -}
diff --git a/components/sync_driver/BUILD.gn b/components/sync_driver/BUILD.gn deleted file mode 100644 index 9d610f4..0000000 --- a/components/sync_driver/BUILD.gn +++ /dev/null
@@ -1,262 +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. - -import("//build/buildflag_header.gni") -import("//build/config/features.gni") - -static_library("sync_driver") { - sources = [ - "about_sync_util.cc", - "about_sync_util.h", - "backend_data_type_configurer.cc", - "backend_data_type_configurer.h", - "backend_migrator.cc", - "backend_migrator.h", - "change_processor.cc", - "change_processor.h", - "data_type_controller.cc", - "data_type_controller.h", - "data_type_encryption_handler.cc", - "data_type_encryption_handler.h", - "data_type_manager.cc", - "data_type_manager.h", - "data_type_manager_impl.cc", - "data_type_manager_impl.h", - "data_type_manager_observer.h", - "data_type_status_table.cc", - "data_type_status_table.h", - "device_count_metrics_provider.cc", - "device_count_metrics_provider.h", - "device_info.cc", - "device_info.h", - "device_info_data_type_controller.cc", - "device_info_data_type_controller.h", - "device_info_service.cc", - "device_info_service.h", - "device_info_sync_service.cc", - "device_info_sync_service.h", - "device_info_tracker.h", - "device_info_util.cc", - "device_info_util.h", - "directory_data_type_controller.cc", - "directory_data_type_controller.h", - "frontend_data_type_controller.cc", - "frontend_data_type_controller.h", - "generic_change_processor.cc", - "generic_change_processor.h", - "generic_change_processor_factory.cc", - "generic_change_processor_factory.h", - "glue/browser_thread_model_worker.cc", - "glue/browser_thread_model_worker.h", - "glue/chrome_report_unrecoverable_error.cc", - "glue/chrome_report_unrecoverable_error.h", - "glue/sync_backend_host.cc", - "glue/sync_backend_host.h", - "glue/sync_backend_host_core.cc", - "glue/sync_backend_host_core.h", - "glue/sync_backend_host_impl.cc", - "glue/sync_backend_host_impl.h", - "glue/sync_backend_registrar.cc", - "glue/sync_backend_registrar.h", - "glue/ui_model_worker.cc", - "glue/ui_model_worker.h", - "invalidation_adapter.cc", - "invalidation_adapter.h", - "invalidation_helper.cc", - "invalidation_helper.h", - "local_device_info_provider.h", - "local_device_info_provider_impl.cc", - "local_device_info_provider_impl.h", - "model_association_manager.cc", - "model_association_manager.h", - "model_associator.h", - "non_blocking_data_type_controller.cc", - "non_blocking_data_type_controller.h", - "non_ui_data_type_controller.cc", - "non_ui_data_type_controller.h", - "non_ui_model_type_controller.cc", - "non_ui_model_type_controller.h", - "pref_names.cc", - "pref_names.h", - "protocol_event_observer.cc", - "protocol_event_observer.h", - "proxy_data_type_controller.cc", - "proxy_data_type_controller.h", - "shared_change_processor.cc", - "shared_change_processor.h", - "shared_change_processor_ref.cc", - "shared_change_processor_ref.h", - "signin_manager_wrapper.cc", - "signin_manager_wrapper.h", - "startup_controller.cc", - "startup_controller.h", - "sync_api_component_factory.h", - "sync_client.cc", - "sync_client.h", - "sync_driver_switches.cc", - "sync_driver_switches.h", - "sync_error_controller.cc", - "sync_error_controller.h", - "sync_frontend.cc", - "sync_frontend.h", - "sync_prefs.cc", - "sync_prefs.h", - "sync_service.cc", - "sync_service.h", - "sync_service_observer.cc", - "sync_service_observer.h", - "sync_service_utils.cc", - "sync_service_utils.h", - "sync_stopped_reporter.cc", - "sync_stopped_reporter.h", - "sync_type_preference_provider.h", - "sync_util.cc", - "sync_util.h", - "system_encryptor.cc", - "system_encryptor.h", - "ui_data_type_controller.cc", - "ui_data_type_controller.h", - "ui_model_type_controller.cc", - "ui_model_type_controller.h", - "user_selectable_sync_type.h", - ] - - public_deps = [ - "//components/sync", - "//third_party/cacheinvalidation", - ] - - deps = [ - "//base", - "//base/third_party/dynamic_annotations", - "//components/data_use_measurement/core", - "//components/invalidation/public", - "//components/metrics", - "//components/os_crypt", - "//components/pref_registry", - "//components/prefs", - "//components/signin/core/browser", - "//components/version_info", - "//google_apis", - "//net", - ] - - if (enable_configuration_policy) { - sources += [ - "sync_policy_handler.cc", - "sync_policy_handler.h", - ] - deps += [ - "//components/policy", - "//components/policy:policy_component", - ] - } -} - -static_library("test_support") { - testonly = true - sources = [ - "change_processor_mock.cc", - "change_processor_mock.h", - "data_type_controller_mock.cc", - "data_type_controller_mock.h", - "data_type_manager_mock.cc", - "data_type_manager_mock.h", - "fake_data_type_controller.cc", - "fake_data_type_controller.h", - "fake_generic_change_processor.cc", - "fake_generic_change_processor.h", - "fake_sync_client.cc", - "fake_sync_client.h", - "fake_sync_service.cc", - "fake_sync_service.h", - "frontend_data_type_controller_mock.cc", - "frontend_data_type_controller_mock.h", - "glue/sync_backend_host_mock.cc", - "glue/sync_backend_host_mock.h", - "local_device_info_provider_mock.cc", - "local_device_info_provider_mock.h", - "model_associator_mock.cc", - "model_associator_mock.h", - "non_ui_data_type_controller_mock.cc", - "non_ui_data_type_controller_mock.h", - "sync_api_component_factory_mock.cc", - "sync_api_component_factory_mock.h", - ] - - public_deps = [ - ":sync_driver", - "//components/sync", - ] - - deps = [ - "//base", - "//components/sync:test_support_sync_core_impl", - "//components/syncable_prefs:test_support", - "//components/version_info", - "//google_apis", - "//testing/gmock", - "//testing/gtest", - ] -} - -source_set("unit_tests") { - testonly = true - sources = [ - "about_sync_util_unittest.cc", - "backend_migrator_unittest.cc", - "data_type_manager_impl_unittest.cc", - "device_count_metrics_provider_unittest.cc", - "device_info_data_type_controller_unittest.cc", - "device_info_service_unittest.cc", - "device_info_sync_service_unittest.cc", - "device_info_util_unittest.cc", - "frontend_data_type_controller_unittest.cc", - "generic_change_processor_unittest.cc", - "glue/browser_thread_model_worker_unittest.cc", - "glue/sync_backend_host_impl_unittest.cc", - "glue/sync_backend_registrar_unittest.cc", - "glue/ui_model_worker_unittest.cc", - "local_device_info_provider_unittest.cc", - "model_association_manager_unittest.cc", - "non_blocking_data_type_controller_unittest.cc", - "non_ui_data_type_controller_unittest.cc", - "non_ui_model_type_controller_unittest.cc", - "shared_change_processor_unittest.cc", - "startup_controller_unittest.cc", - "sync_prefs_unittest.cc", - "sync_stopped_reporter_unittest.cc", - "sync_util_unittest.cc", - "system_encryptor_unittest.cc", - "ui_data_type_controller_unittest.cc", - "ui_model_type_controller_unittest.cc", - ] - deps = [ - ":test_support", - "//base", - "//base/test:test_support", - "//components/invalidation/impl", - "//components/os_crypt:test_support", - "//components/pref_registry:test_support", - "//components/prefs:test_support", - "//components/signin/core/browser:test_support", - "//components/sync:test_support_sync_api", - "//components/sync:test_support_sync_core_impl", - "//components/syncable_prefs", - "//components/syncable_prefs:test_support", - "//components/version_info", - "//net:test_support", - "//testing/gmock", - "//testing/gtest", - "//url", - ] - - if (enable_configuration_policy) { - sources += [ "sync_policy_handler_unittest.cc" ] - deps += [ - "//components/policy", - "//components/policy:policy_component", - ] - } -}
diff --git a/components/sync_driver/DEPS b/components/sync_driver/DEPS deleted file mode 100644 index 730d63ad..0000000 --- a/components/sync_driver/DEPS +++ /dev/null
@@ -1,17 +0,0 @@ -include_rules = [ - "+components/data_use_measurement/core", - "+components/invalidation", - "+components/metrics", - "+components/os_crypt", - "+components/policy", - "+components/pref_registry", - "+components/prefs", - "+components/signin/core/browser", - "+components/sync", - "+components/syncable_prefs", - "+components/version_info", - "+google", - "+google_apis", - "+net", - "+policy", -]
diff --git a/components/sync_driver/OWNERS b/components/sync_driver/OWNERS deleted file mode 100644 index 7da50ed..0000000 --- a/components/sync_driver/OWNERS +++ /dev/null
@@ -1,4 +0,0 @@ -maxbogue@chromium.org -pavely@chromium.org -stanisc@chromium.org -zea@chromium.org
diff --git a/components/sync_driver/about_sync_util.cc b/components/sync_driver/about_sync_util.cc deleted file mode 100644 index 812e17cf..0000000 --- a/components/sync_driver/about_sync_util.cc +++ /dev/null
@@ -1,535 +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 "components/sync_driver/about_sync_util.h" - -#include <string> -#include <utility> - -#include "base/location.h" -#include "base/strings/string16.h" -#include "base/strings/stringprintf.h" -#include "base/values.h" -#include "components/signin/core/browser/signin_manager_base.h" -#include "components/sync/api/time.h" -#include "components/sync/base/sync_string_conversions.h" -#include "components/sync/engine/sync_status.h" -#include "components/sync/protocol/proto_enum_conversions.h" -#include "components/sync/sessions/sync_session_snapshot.h" -#include "components/sync_driver/sync_service.h" -#include "components/version_info/version_info.h" - -using base::DictionaryValue; -using base::ListValue; - -namespace sync_driver { - -namespace sync_ui_util { - -const char kIdentityTitle[] = "Identity"; -const char kDetailsKey[] = "details"; - -// Resource paths. -const char kAboutJS[] = "about.js"; -const char kChromeSyncJS[] = "chrome_sync.js"; -const char kDataJS[] = "data.js"; -const char kEventsJS[] = "events.js"; -const char kSearchJS[] = "search.js"; -const char kSyncIndexJS[] = "sync_index.js"; -const char kSyncLogJS[] = "sync_log.js"; -const char kSyncNodeBrowserJS[] = "sync_node_browser.js"; -const char kSyncSearchJS[] = "sync_search.js"; -const char kTypesJS[] = "types.js"; - -// Message handlers. -const char kDispatchEvent[] = "chrome.sync.dispatchEvent"; -const char kGetAllNodes[] = "getAllNodes"; -const char kGetAllNodesCallback[] = "chrome.sync.getAllNodesCallback"; -const char kRegisterForEvents[] = "registerForEvents"; -const char kRegisterForPerTypeCounters[] = "registerForPerTypeCounters"; -const char kRequestListOfTypes[] = "requestListOfTypes"; -const char kRequestUpdatedAboutInfo[] = "requestUpdatedAboutInfo"; - -// Other strings. -const char kCommit[] = "commit"; -const char kCounters[] = "counters"; -const char kCounterType[] = "counterType"; -const char kModelType[] = "modelType"; -const char kOnAboutInfoUpdated[] = "onAboutInfoUpdated"; -const char kOnCountersUpdated[] = "onCountersUpdated"; -const char kOnProtocolEvent[] = "onProtocolEvent"; -const char kOnReceivedListOfTypes[] = "onReceivedListOfTypes"; -const char kStatus[] = "status"; -const char kTypes[] = "types"; -const char kUpdate[] = "update"; - -namespace { - -// Creates a 'section' for display on about:sync, consisting of a title and a -// list of fields. Returns a pointer to the new section. Note that -// |parent_list|, not the caller, owns the newly added section. -base::ListValue* AddSection(base::ListValue* parent_list, - const std::string& title) { - std::unique_ptr<base::DictionaryValue> section(new base::DictionaryValue()); - base::ListValue* section_contents = new base::ListValue(); - section->SetString("title", title); - section->Set("data", section_contents); - section->SetBoolean("is_sensitive", false); - parent_list->Append(std::move(section)); - return section_contents; -} - -// Same as AddSection, but for data that should be elided when dumped into text -// form and posted in a public forum (e.g. unique identifiers). -base::ListValue* AddSensitiveSection(base::ListValue* parent_list, - const std::string& title) { - std::unique_ptr<base::DictionaryValue> section(new base::DictionaryValue()); - base::ListValue* section_contents = new base::ListValue(); - section->SetString("title", title); - section->Set("data", section_contents); - section->SetBoolean("is_sensitive", true); - parent_list->Append(std::move(section)); - return section_contents; -} - -// The following helper classes help manage the about:sync fields which will be -// populated in method in ConstructAboutInformation. -// -// Each instance of one of thse classes indicates a field in about:sync. Each -// field will be serialized to a DictionaryValue with entries for 'stat_name', -// 'stat_value' and 'is_valid'. - -class StringSyncStat { - public: - StringSyncStat(base::ListValue* section, const std::string& key); - void SetValue(const std::string& value); - void SetValue(const base::string16& value); - - private: - // Owned by the |section| passed in during construction. - base::DictionaryValue* stat_; -}; - -StringSyncStat::StringSyncStat(base::ListValue* section, - const std::string& key) { - stat_ = new base::DictionaryValue(); - stat_->SetString("stat_name", key); - stat_->SetString("stat_value", "Uninitialized"); - stat_->SetBoolean("is_valid", false); - section->Append(stat_); -} - -void StringSyncStat::SetValue(const std::string& value) { - stat_->SetString("stat_value", value); - stat_->SetBoolean("is_valid", true); -} - -void StringSyncStat::SetValue(const base::string16& value) { - stat_->SetString("stat_value", value); - stat_->SetBoolean("is_valid", true); -} - -class BoolSyncStat { - public: - BoolSyncStat(base::ListValue* section, const std::string& key); - void SetValue(bool value); - - private: - // Owned by the |section| passed in during construction. - base::DictionaryValue* stat_; -}; - -BoolSyncStat::BoolSyncStat(base::ListValue* section, const std::string& key) { - stat_ = new base::DictionaryValue(); - stat_->SetString("stat_name", key); - stat_->SetBoolean("stat_value", false); - stat_->SetBoolean("is_valid", false); - section->Append(stat_); -} - -void BoolSyncStat::SetValue(bool value) { - stat_->SetBoolean("stat_value", value); - stat_->SetBoolean("is_valid", true); -} - -class IntSyncStat { - public: - IntSyncStat(base::ListValue* section, const std::string& key); - void SetValue(int value); - - private: - // Owned by the |section| passed in during construction. - base::DictionaryValue* stat_; -}; - -IntSyncStat::IntSyncStat(base::ListValue* section, const std::string& key) { - stat_ = new base::DictionaryValue(); - stat_->SetString("stat_name", key); - stat_->SetInteger("stat_value", 0); - stat_->SetBoolean("is_valid", false); - section->Append(stat_); -} - -void IntSyncStat::SetValue(int value) { - stat_->SetInteger("stat_value", value); - stat_->SetBoolean("is_valid", true); -} - -// Returns a string describing the chrome version environment. Version format: -// <Build Info> <OS> <Version number> (<Last change>)<channel or "-devel"> -// If version information is unavailable, returns "invalid." -// TODO(zea): this approximately matches MakeUserAgentForSyncApi in -// sync_backend_host.cc. Unify the two if possible. -std::string GetVersionString(version_info::Channel channel) { - // Build a version string that matches MakeUserAgentForSyncApi with the - // addition of channel info and proper OS names. - // chrome::GetChannelString() returns empty string for stable channel or - // unofficial builds, the channel string otherwise. We want to have "-devel" - // for unofficial builds only. - std::string version_modifier = version_info::GetChannelString(channel); - if (version_modifier.empty()) { - if (channel != version_info::Channel::STABLE) { - version_modifier = "-devel"; - } - } else { - version_modifier = " " + version_modifier; - } - return version_info::GetProductName() + " " + version_info::GetOSType() + - " " + version_info::GetVersionNumber() + " (" + - version_info::GetLastChange() + ")" + version_modifier; -} - -std::string GetTimeStr(base::Time time, const std::string& default_msg) { - std::string time_str; - if (time.is_null()) - time_str = default_msg; - else - time_str = syncer::GetTimeDebugString(time); - return time_str; -} - -std::string GetConnectionStatus( - const sync_driver::SyncService::SyncTokenStatus& status) { - std::string message; - switch (status.connection_status) { - case syncer::CONNECTION_NOT_ATTEMPTED: - base::StringAppendF(&message, "not attempted"); - break; - case syncer::CONNECTION_OK: - base::StringAppendF( - &message, "OK since %s", - GetTimeStr(status.connection_status_update_time, "n/a").c_str()); - break; - case syncer::CONNECTION_AUTH_ERROR: - base::StringAppendF( - &message, "auth error since %s", - GetTimeStr(status.connection_status_update_time, "n/a").c_str()); - break; - case syncer::CONNECTION_SERVER_ERROR: - base::StringAppendF( - &message, "server error since %s", - GetTimeStr(status.connection_status_update_time, "n/a").c_str()); - break; - default: - NOTREACHED(); - } - return message; -} - -} // namespace - -// This function both defines the structure of the message to be returned and -// its contents. Most of the message consists of simple fields in about:sync -// which are grouped into sections and populated with the help of the SyncStat -// classes defined above. -std::unique_ptr<base::DictionaryValue> ConstructAboutInformation( - sync_driver::SyncService* service, - SigninManagerBase* signin, - version_info::Channel channel) { - std::unique_ptr<base::DictionaryValue> about_info( - new base::DictionaryValue()); - - // 'details': A list of sections. - base::ListValue* stats_list = new base::ListValue(); - - // The following lines define the sections and their fields. For each field, - // a class is instantiated, which allows us to reference the fields in - // 'setter' code later on in this function. - base::ListValue* section_summary = AddSection(stats_list, "Summary"); - StringSyncStat summary_string(section_summary, "Summary"); - - base::ListValue* section_version = AddSection(stats_list, "Version Info"); - StringSyncStat client_version(section_version, "Client Version"); - StringSyncStat server_url(section_version, "Server URL"); - - base::ListValue* section_identity = - AddSensitiveSection(stats_list, kIdentityTitle); - StringSyncStat sync_id(section_identity, "Sync Client ID"); - StringSyncStat invalidator_id(section_identity, "Invalidator Client ID"); - StringSyncStat username(section_identity, "Username"); - - base::ListValue* section_credentials = AddSection(stats_list, "Credentials"); - StringSyncStat request_token_time(section_credentials, "Requested Token"); - StringSyncStat receive_token_time(section_credentials, "Received Token"); - StringSyncStat token_request_status(section_credentials, - "Token Request Status"); - StringSyncStat next_token_request(section_credentials, - "Next Token Request"); - - base::ListValue* section_local = AddSection(stats_list, "Local State"); - StringSyncStat server_connection(section_local, - "Server Connection"); - StringSyncStat last_synced(section_local, "Last Synced"); - BoolSyncStat is_setup_complete(section_local, - "Sync First-Time Setup Complete"); - StringSyncStat backend_initialization(section_local, - "Sync Backend Initialization"); - BoolSyncStat is_syncing(section_local, "Syncing"); - - base::ListValue* section_network = AddSection(stats_list, "Network"); - BoolSyncStat is_throttled(section_network, "Throttled"); - StringSyncStat retry_time(section_network, "Retry time (maybe stale)"); - BoolSyncStat are_notifications_enabled(section_network, - "Notifications Enabled"); - - base::ListValue* section_encryption = AddSection(stats_list, "Encryption"); - BoolSyncStat is_using_explicit_passphrase(section_encryption, - "Explicit Passphrase"); - BoolSyncStat is_passphrase_required(section_encryption, - "Passphrase Required"); - BoolSyncStat is_cryptographer_ready(section_encryption, - "Cryptographer Ready"); - BoolSyncStat has_pending_keys(section_encryption, - "Cryptographer Has Pending Keys"); - StringSyncStat encrypted_types(section_encryption, "Encrypted Types"); - BoolSyncStat has_keystore_key(section_encryption, "Has Keystore Key"); - StringSyncStat keystore_migration_time(section_encryption, - "Keystore Migration Time"); - StringSyncStat passphrase_type(section_encryption, - "Passphrase Type"); - StringSyncStat passphrase_time(section_encryption, - "Passphrase Time"); - - base::ListValue* section_last_session = AddSection( - stats_list, "Status from Last Completed Session"); - StringSyncStat session_source(section_last_session, "Sync Source"); - StringSyncStat get_key_result(section_last_session, "GetKey Step Result"); - StringSyncStat download_result(section_last_session, "Download Step Result"); - StringSyncStat commit_result(section_last_session, "Commit Step Result"); - - base::ListValue* section_counters = AddSection(stats_list, "Running Totals"); - IntSyncStat notifications_received(section_counters, - "Notifications Received"); - IntSyncStat updates_received(section_counters, "Updates Downloaded"); - IntSyncStat tombstone_updates(section_counters, "Tombstone Updates"); - IntSyncStat reflected_updates(section_counters, "Reflected Updates"); - IntSyncStat successful_commits(section_counters, "Successful Commits"); - IntSyncStat conflicts_resolved_local_wins(section_counters, - "Conflicts Resolved: Client Wins"); - IntSyncStat conflicts_resolved_server_wins(section_counters, - "Conflicts Resolved: Server Wins"); - - base::ListValue *section_this_cycle = AddSection(stats_list, - "Transient Counters (this cycle)"); - IntSyncStat encryption_conflicts(section_this_cycle, "Encryption Conflicts"); - IntSyncStat hierarchy_conflicts(section_this_cycle, "Hierarchy Conflicts"); - IntSyncStat server_conflicts(section_this_cycle, "Server Conflicts"); - IntSyncStat committed_items(section_this_cycle, "Committed Items"); - - base::ListValue* section_that_cycle = AddSection( - stats_list, "Transient Counters (last cycle of last completed session)"); - IntSyncStat updates_downloaded(section_that_cycle, "Updates Downloaded"); - IntSyncStat committed_count(section_that_cycle, "Committed Count"); - IntSyncStat entries(section_that_cycle, "Entries"); - - base::ListValue* section_nudge_info = AddSection( - stats_list, "Nudge Source Counters"); - IntSyncStat nudge_source_notification( - section_nudge_info, "Server Invalidations"); - IntSyncStat nudge_source_local(section_nudge_info, "Local Changes"); - IntSyncStat nudge_source_local_refresh(section_nudge_info, "Local Refreshes"); - - // This list of sections belongs in the 'details' field of the returned - // message. - about_info->Set(kDetailsKey, stats_list); - - // Populate all the fields we declared above. - client_version.SetValue(GetVersionString(channel)); - - if (!service) { - summary_string.SetValue("Sync service does not exist"); - return about_info; - } - - syncer::SyncStatus full_status; - bool is_status_valid = service->QueryDetailedSyncStatus(&full_status); - bool sync_active = service->IsSyncActive(); - const syncer::sessions::SyncSessionSnapshot& snapshot = - service->GetLastSessionSnapshot(); - - if (is_status_valid) - summary_string.SetValue(service->QuerySyncStatusSummaryString()); - - server_url.SetValue(service->sync_service_url().spec()); - - if (is_status_valid && !full_status.sync_id.empty()) - sync_id.SetValue(full_status.sync_id); - if (is_status_valid && !full_status.invalidator_client_id.empty()) - invalidator_id.SetValue(full_status.invalidator_client_id); - if (signin) - username.SetValue(signin->GetAuthenticatedAccountInfo().email); - - const sync_driver::SyncService::SyncTokenStatus& token_status = - service->GetSyncTokenStatus(); - server_connection.SetValue(GetConnectionStatus(token_status)); - request_token_time.SetValue(GetTimeStr(token_status.token_request_time, - "n/a")); - receive_token_time.SetValue(GetTimeStr(token_status.token_receive_time, - "n/a")); - std::string err = token_status.last_get_token_error.error_message(); - token_request_status.SetValue(err.empty() ? "OK" : err); - next_token_request.SetValue( - GetTimeStr(token_status.next_token_request_time, "not scheduled")); - - last_synced.SetValue(service->GetLastSyncedTimeString()); - is_setup_complete.SetValue(service->IsFirstSetupComplete()); - backend_initialization.SetValue( - service->GetBackendInitializationStateString()); - if (is_status_valid) { - is_syncing.SetValue(full_status.syncing); - retry_time.SetValue(GetTimeStr(full_status.retry_time, - "Scheduler is not in backoff or throttled")); - } - - if (snapshot.is_initialized()) - is_throttled.SetValue(snapshot.is_silenced()); - if (is_status_valid) { - are_notifications_enabled.SetValue( - full_status.notifications_enabled); - } - - if (sync_active) { - is_using_explicit_passphrase.SetValue( - service->IsUsingSecondaryPassphrase()); - is_passphrase_required.SetValue(service->IsPassphraseRequired()); - passphrase_time.SetValue( - GetTimeStr(service->GetExplicitPassphraseTime(), "No Passphrase Time")); - } - if (is_status_valid) { - is_cryptographer_ready.SetValue(full_status.cryptographer_ready); - has_pending_keys.SetValue(full_status.crypto_has_pending_keys); - encrypted_types.SetValue( - ModelTypeSetToString(full_status.encrypted_types)); - has_keystore_key.SetValue(full_status.has_keystore_key); - keystore_migration_time.SetValue( - GetTimeStr(full_status.keystore_migration_time, "Not Migrated")); - passphrase_type.SetValue( - PassphraseTypeToString(full_status.passphrase_type)); - } - - if (snapshot.is_initialized()) { - if (snapshot.legacy_updates_source() != - sync_pb::GetUpdatesCallerInfo::UNKNOWN) { - session_source.SetValue( - syncer::GetUpdatesSourceString(snapshot.legacy_updates_source())); - } - get_key_result.SetValue( - GetSyncerErrorString( - snapshot.model_neutral_state().last_get_key_result)); - download_result.SetValue( - GetSyncerErrorString( - snapshot.model_neutral_state().last_download_updates_result)); - commit_result.SetValue( - GetSyncerErrorString( - snapshot.model_neutral_state().commit_result)); - } - - if (is_status_valid) { - notifications_received.SetValue(full_status.notifications_received); - updates_received.SetValue(full_status.updates_received); - tombstone_updates.SetValue(full_status.tombstone_updates_received); - reflected_updates.SetValue(full_status.reflected_updates_received); - successful_commits.SetValue(full_status.num_commits_total); - conflicts_resolved_local_wins.SetValue( - full_status.num_local_overwrites_total); - conflicts_resolved_server_wins.SetValue( - full_status.num_server_overwrites_total); - } - - if (is_status_valid) { - encryption_conflicts.SetValue(full_status.encryption_conflicts); - hierarchy_conflicts.SetValue(full_status.hierarchy_conflicts); - server_conflicts.SetValue(full_status.server_conflicts); - committed_items.SetValue(full_status.committed_count); - } - - if (is_status_valid) { - nudge_source_notification.SetValue(full_status.nudge_source_notification); - nudge_source_local.SetValue(full_status.nudge_source_local); - nudge_source_local_refresh.SetValue(full_status.nudge_source_local_refresh); - } - - if (snapshot.is_initialized()) { - updates_downloaded.SetValue( - snapshot.model_neutral_state().num_updates_downloaded_total); - committed_count.SetValue( - snapshot.model_neutral_state().num_successful_commits); - entries.SetValue(snapshot.num_entries()); - } - - // The values set from this point onwards do not belong in the - // details list. - - // We don't need to check is_status_valid here. - // full_status.sync_protocol_error is exported directly from the - // ProfileSyncService, even if the backend doesn't exist. - const bool actionable_error_detected = - full_status.sync_protocol_error.error_type != syncer::UNKNOWN_ERROR && - full_status.sync_protocol_error.error_type != syncer::SYNC_SUCCESS; - - about_info->SetBoolean("actionable_error_detected", - actionable_error_detected); - - // NOTE: We won't bother showing any of the following values unless - // actionable_error_detected is set. - - base::ListValue* actionable_error = new base::ListValue(); - about_info->Set("actionable_error", actionable_error); - - StringSyncStat error_type(actionable_error, "Error Type"); - StringSyncStat action(actionable_error, "Action"); - StringSyncStat url(actionable_error, "URL"); - StringSyncStat description(actionable_error, "Error Description"); - - if (actionable_error_detected) { - error_type.SetValue(syncer::GetSyncErrorTypeString( - full_status.sync_protocol_error.error_type)); - action.SetValue(syncer::GetClientActionString( - full_status.sync_protocol_error.action)); - url.SetValue(full_status.sync_protocol_error.url); - description.SetValue(full_status.sync_protocol_error.error_description); - } - - about_info->SetBoolean("unrecoverable_error_detected", - service->HasUnrecoverableError()); - - if (service->HasUnrecoverableError()) { - tracked_objects::Location loc(service->unrecoverable_error_location()); - std::string location_str; - loc.Write(true, true, &location_str); - std::string unrecoverable_error_message = - "Unrecoverable error detected at " + location_str + - ": " + service->unrecoverable_error_message(); - about_info->SetString("unrecoverable_error_message", - unrecoverable_error_message); - } - - about_info->Set("type_status", service->GetTypeStatusMap()); - - return about_info; -} - -} // namespace sync_ui_util - -} // namespace sync_driver
diff --git a/components/sync_driver/about_sync_util_unittest.cc b/components/sync_driver/about_sync_util_unittest.cc deleted file mode 100644 index ef37457..0000000 --- a/components/sync_driver/about_sync_util_unittest.cc +++ /dev/null
@@ -1,55 +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 "components/sync_driver/about_sync_util.h" - -#include "base/strings/utf_string_conversions.h" -#include "components/sync/engine/sync_status.h" -#include "components/sync_driver/fake_sync_service.h" -#include "components/version_info/version_info.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using ::testing::NiceMock; -using ::testing::Return; -using ::testing::_; - -namespace sync_driver { -namespace sync_ui_util { -namespace { - -class SyncServiceMock : public sync_driver::FakeSyncService { - public: - bool IsFirstSetupComplete() const override { return true; } - - bool HasUnrecoverableError() const override { - return true; - } - - bool QueryDetailedSyncStatus(syncer::SyncStatus* result) override { - return false; - } - - base::string16 GetLastSyncedTimeString() const override { - return base::string16(base::ASCIIToUTF16("none")); - } - - syncer::sessions::SyncSessionSnapshot GetLastSessionSnapshot() - const override { - return syncer::sessions::SyncSessionSnapshot(); - } -}; - -TEST(SyncUIUtilTestAbout, ConstructAboutInformationWithUnrecoverableErrorTest) { - SyncServiceMock service; - - std::unique_ptr<base::DictionaryValue> strings(ConstructAboutInformation( - &service, NULL, version_info::Channel::UNKNOWN)); - - EXPECT_TRUE(strings->HasKey("unrecoverable_error_detected")); -} - -} // namespace -} // namespace sync_ui_util -} // namespace sync_driver
diff --git a/components/sync_driver/backend_data_type_configurer.cc b/components/sync_driver/backend_data_type_configurer.cc deleted file mode 100644 index 52b3f9be..0000000 --- a/components/sync_driver/backend_data_type_configurer.cc +++ /dev/null
@@ -1,32 +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 "components/sync_driver/backend_data_type_configurer.h" - -namespace sync_driver { - -// static -syncer::ModelTypeSet -BackendDataTypeConfigurer::GetDataTypesInState( - DataTypeConfigState state, const DataTypeConfigStateMap& state_map) { - syncer::ModelTypeSet types; - for (DataTypeConfigStateMap::const_iterator type_it = state_map.begin(); - type_it != state_map.end(); ++type_it) { - if (type_it->second == state) - types.Put(type_it->first); - } - return types; -} - -// static -void BackendDataTypeConfigurer::SetDataTypesState( - DataTypeConfigState state, syncer::ModelTypeSet types, - DataTypeConfigStateMap* state_map) { - for (syncer::ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) { - (*state_map)[it.Get()] = state; - } -} - -} // namespace sync_driver
diff --git a/components/sync_driver/backend_data_type_configurer.h b/components/sync_driver/backend_data_type_configurer.h deleted file mode 100644 index 2fb935c..0000000 --- a/components/sync_driver/backend_data_type_configurer.h +++ /dev/null
@@ -1,100 +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 COMPONENTS_SYNC_DRIVER_BACKEND_DATA_TYPE_CONFIGURER_H_ -#define COMPONENTS_SYNC_DRIVER_BACKEND_DATA_TYPE_CONFIGURER_H_ - -#include <map> -#include <memory> - -#include "base/callback.h" -#include "components/sync/base/model_type.h" -#include "components/sync/core/configure_reason.h" -#include "components/sync/engine/model_safe_worker.h" - -namespace syncer_v2 { -struct ActivationContext; -} - -namespace sync_driver { - -class ChangeProcessor; - -// The DataTypeConfigurer interface abstracts out the action of -// configuring a set of new data types and cleaning up after a set of -// removed data types. -class BackendDataTypeConfigurer { - public: - enum DataTypeConfigState { - CONFIGURE_ACTIVE, // Actively being configured. Data of such types - // will be downloaded if not present locally. - CONFIGURE_INACTIVE, // Already configured or to be configured in future. - // Data of such types is left as it is, no - // downloading or purging. - CONFIGURE_CLEAN, // Actively being configured but requiring unapply - // and GetUpdates first (e.g. for persistence errors). - DISABLED, // Not syncing. Disabled by user. - FATAL, // Not syncing due to unrecoverable error. - CRYPTO, // Not syncing due to a cryptographer error. - UNREADY, // Not syncing due to transient error. - }; - typedef std::map<syncer::ModelType, DataTypeConfigState> - DataTypeConfigStateMap; - - // Configures sync for data types in config_state_map according to the states. - // |ready_task| is called on the same thread as ConfigureDataTypes - // is called when configuration is done with the set of data types - // that succeeded/failed configuration (i.e., configuration succeeded iff - // the failed set is empty). - // Returns: the set of types that are already configured and are ready to - // start. - // - // TODO(akalin): Use a Delegate class with - // OnConfigureSuccess/OnConfigureFailure/OnConfigureRetry instead of - // a pair of callbacks. The awkward part is handling when - // SyncBackendHost calls ConfigureDataTypes on itself to configure - // Nigori. - virtual syncer::ModelTypeSet ConfigureDataTypes( - syncer::ConfigureReason reason, - const DataTypeConfigStateMap& config_state_map, - const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& - ready_task, - const base::Callback<void()>& retry_callback) = 0; - - // Return model types in |state_map| that match |state|. - static syncer::ModelTypeSet GetDataTypesInState( - DataTypeConfigState state, const DataTypeConfigStateMap& state_map); - - // Activates change processing for the given directory data type. This must - // be called synchronously with the data type's model association so - // no changes are dropped between model association and change - // processor activation. - virtual void ActivateDirectoryDataType(syncer::ModelType type, - syncer::ModelSafeGroup group, - ChangeProcessor* change_processor) = 0; - - // Deactivates change processing for the given data type. - virtual void DeactivateDirectoryDataType(syncer::ModelType type) = 0; - - // Activates change processing for the given non-blocking data type. - // This must be called before initial sync for data type. - virtual void ActivateNonBlockingDataType( - syncer::ModelType type, - std::unique_ptr<syncer_v2::ActivationContext> activation_context) = 0; - - // Deactivates change processing for the given non-blocking data type. - virtual void DeactivateNonBlockingDataType(syncer::ModelType type) = 0; - - // Set state of |types| in |state_map| to |state|. - static void SetDataTypesState(DataTypeConfigState state, - syncer::ModelTypeSet types, - DataTypeConfigStateMap* state_map); - - protected: - virtual ~BackendDataTypeConfigurer() {} -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_BACKEND_DATA_TYPE_CONFIGURER_H_
diff --git a/components/sync_driver/backend_migrator.cc b/components/sync_driver/backend_migrator.cc deleted file mode 100644 index 3398bd5..0000000 --- a/components/sync_driver/backend_migrator.cc +++ /dev/null
@@ -1,223 +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 "components/sync_driver/backend_migrator.h" - -#include "base/location.h" -#include "base/single_thread_task_runner.h" -#include "base/strings/string_number_conversions.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/tracked_objects.h" -#include "components/sync/core/configure_reason.h" -#include "components/sync/core/read_transaction.h" -#include "components/sync/protocol/sync.pb.h" -#include "components/sync/syncable/directory.h" // TODO(tim): Bug 131130. -#include "components/sync_driver/sync_service.h" - -using syncer::ModelTypeSet; - -namespace browser_sync { - -using syncer::ModelTypeToString; - -MigrationObserver::~MigrationObserver() {} - -BackendMigrator::BackendMigrator(const std::string& name, - syncer::UserShare* user_share, - sync_driver::SyncService* service, - sync_driver::DataTypeManager* manager, - const base::Closure &migration_done_callback) - : name_(name), user_share_(user_share), service_(service), - manager_(manager), state_(IDLE), - migration_done_callback_(migration_done_callback), - weak_ptr_factory_(this) { -} - -BackendMigrator::~BackendMigrator() { -} - -// Helper macros to log with the syncer thread name; useful when there -// are multiple syncer threads involved. - -#define SLOG(severity) LOG(severity) << name_ << ": " - -#define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": " - -void BackendMigrator::MigrateTypes(syncer::ModelTypeSet types) { - const ModelTypeSet old_to_migrate = to_migrate_; - to_migrate_.PutAll(types); - SDVLOG(1) << "MigrateTypes called with " << ModelTypeSetToString(types) - << ", old_to_migrate = " << ModelTypeSetToString(old_to_migrate) - << ", to_migrate_ = " << ModelTypeSetToString(to_migrate_); - if (old_to_migrate == to_migrate_) { - SDVLOG(1) << "MigrateTypes called with no new types; ignoring"; - return; - } - - if (state_ == IDLE) - ChangeState(WAITING_TO_START); - - if (state_ == WAITING_TO_START) { - if (!TryStart()) - SDVLOG(1) << "Manager not configured; waiting"; - return; - } - - DCHECK_GT(state_, WAITING_TO_START); - // If we're already migrating, interrupt the current migration. - RestartMigration(); -} - -void BackendMigrator::AddMigrationObserver(MigrationObserver* observer) { - migration_observers_.AddObserver(observer); -} - -bool BackendMigrator::HasMigrationObserver( - const MigrationObserver* observer) const { - return migration_observers_.HasObserver(observer); -} - -void BackendMigrator::RemoveMigrationObserver(MigrationObserver* observer) { - migration_observers_.RemoveObserver(observer); -} - -void BackendMigrator::ChangeState(State new_state) { - state_ = new_state; - FOR_EACH_OBSERVER(MigrationObserver, migration_observers_, - OnMigrationStateChange()); -} - -bool BackendMigrator::TryStart() { - DCHECK_EQ(state_, WAITING_TO_START); - if (manager_->state() == sync_driver::DataTypeManager::CONFIGURED) { - RestartMigration(); - return true; - } - return false; -} - -void BackendMigrator::RestartMigration() { - // We'll now disable any running types that need to be migrated. - ChangeState(DISABLING_TYPES); - SDVLOG(1) << "BackendMigrator disabling types " - << ModelTypeSetToString(to_migrate_); - - manager_->PurgeForMigration(to_migrate_, syncer::CONFIGURE_REASON_MIGRATION); -} - -void BackendMigrator::OnConfigureDone( - const sync_driver::DataTypeManager::ConfigureResult& result) { - if (state_ == IDLE) - return; - - // |manager_|'s methods aren't re-entrant, and we're notified from - // them, so post a task to avoid problems. - SDVLOG(1) << "Posting OnConfigureDoneImpl"; - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&BackendMigrator::OnConfigureDoneImpl, - weak_ptr_factory_.GetWeakPtr(), result)); -} - -namespace { - -syncer::ModelTypeSet GetUnsyncedDataTypes(syncer::UserShare* user_share) { - syncer::ReadTransaction trans(FROM_HERE, user_share); - syncer::ModelTypeSet unsynced_data_types; - for (int i = syncer::FIRST_REAL_MODEL_TYPE; - i < syncer::MODEL_TYPE_COUNT; ++i) { - syncer::ModelType type = syncer::ModelTypeFromInt(i); - sync_pb::DataTypeProgressMarker progress_marker; - trans.GetDirectory()->GetDownloadProgress(type, &progress_marker); - if (progress_marker.token().empty()) { - unsynced_data_types.Put(type); - } - } - return unsynced_data_types; -} - -} // namespace - -void BackendMigrator::OnConfigureDoneImpl( - const sync_driver::DataTypeManager::ConfigureResult& result) { - SDVLOG(1) << "OnConfigureDone with requested types " - << ModelTypeSetToString(result.requested_types) - << ", status " << result.status - << ", and to_migrate_ = " << ModelTypeSetToString(to_migrate_); - if (state_ == WAITING_TO_START) { - if (!TryStart()) - SDVLOG(1) << "Manager still not configured; still waiting"; - return; - } - - DCHECK_GT(state_, WAITING_TO_START); - - const ModelTypeSet intersection = - Intersection(result.requested_types, to_migrate_); - // This intersection check is to determine if our disable request - // was interrupted by a user changing preferred types. - if (state_ == DISABLING_TYPES && !intersection.Empty()) { - SDVLOG(1) << "Disable request interrupted by user changing types"; - RestartMigration(); - return; - } - - if (result.status != sync_driver::DataTypeManager::OK) { - // If this fails, and we're disabling types, a type may or may not be - // disabled until the user restarts the browser. If this wasn't an abort, - // any failure will be reported as an unrecoverable error to the UI. If it - // was an abort, then typically things are shutting down anyway. There isn't - // much we can do in any case besides wait until a restart to try again. - // The server will send down MIGRATION_DONE again for types needing - // migration as the type will still be enabled on restart. - SLOG(WARNING) << "Unable to migrate, configuration failed!"; - ChangeState(IDLE); - to_migrate_.Clear(); - return; - } - - if (state_ == DISABLING_TYPES) { - const syncer::ModelTypeSet unsynced_types = - GetUnsyncedDataTypes(user_share_); - if (!unsynced_types.HasAll(to_migrate_)) { - SLOG(WARNING) << "Set of unsynced types: " - << syncer::ModelTypeSetToString(unsynced_types) - << " does not contain types to migrate: " - << syncer::ModelTypeSetToString(to_migrate_) - << "; not re-enabling yet"; - return; - } - - ChangeState(REENABLING_TYPES); - // Don't use |to_migrate_| for the re-enabling because the user - // may have chosen to disable types during the migration. - const ModelTypeSet full_set = service_->GetPreferredDataTypes(); - SDVLOG(1) << "BackendMigrator re-enabling types: " - << syncer::ModelTypeSetToString(full_set); - manager_->Configure(full_set, syncer::CONFIGURE_REASON_MIGRATION); - } else if (state_ == REENABLING_TYPES) { - // We're done! - ChangeState(IDLE); - - SDVLOG(1) << "BackendMigrator: Migration complete for: " - << syncer::ModelTypeSetToString(to_migrate_); - to_migrate_.Clear(); - - if (!migration_done_callback_.is_null()) - migration_done_callback_.Run(); - } -} - -BackendMigrator::State BackendMigrator::state() const { - return state_; -} - -syncer::ModelTypeSet BackendMigrator::GetPendingMigrationTypesForTest() const { - return to_migrate_; -} - -#undef SDVLOG - -#undef SLOG - -}; // namespace browser_sync
diff --git a/components/sync_driver/backend_migrator.h b/components/sync_driver/backend_migrator.h deleted file mode 100644 index 3fc2e3e9..0000000 --- a/components/sync_driver/backend_migrator.h +++ /dev/null
@@ -1,113 +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 COMPONENTS_SYNC_DRIVER_BACKEND_MIGRATOR_H_ -#define COMPONENTS_SYNC_DRIVER_BACKEND_MIGRATOR_H_ - -#include <string> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/observer_list.h" -#include "components/sync/base/model_type.h" -#include "components/sync_driver/data_type_manager.h" - -namespace syncer { -struct UserShare; -} // namespace syncer - -namespace sync_driver { -class SyncService; -} - -namespace browser_sync { - -// Interface for anything that wants to know when the migrator's state -// changes. -class MigrationObserver { - public: - virtual void OnMigrationStateChange() = 0; - - protected: - virtual ~MigrationObserver(); -}; - -// A class to perform migration of a datatype pursuant to the 'MIGRATION_DONE' -// code in the sync protocol definition (protocol/sync.proto). -class BackendMigrator { - public: - enum State { - IDLE, - WAITING_TO_START, // Waiting for previous configuration to finish. - DISABLING_TYPES, // Exit criteria: SYNC_CONFIGURE_DONE for - // enabled types _excluding_ |to_migrate_| and - // empty download progress markers for types - // in |to_migrate_|. - REENABLING_TYPES, // Exit criteria: SYNC_CONFIGURE_DONE for enabled - // types. - }; - - // TODO(akalin): Remove the dependency on |user_share|. - BackendMigrator(const std::string& name, - syncer::UserShare* user_share, - sync_driver::SyncService* service, - sync_driver::DataTypeManager* manager, - const base::Closure &migration_done_callback); - virtual ~BackendMigrator(); - - // Starts a sequence of events that will disable and reenable |types|. - void MigrateTypes(syncer::ModelTypeSet types); - - void AddMigrationObserver(MigrationObserver* observer); - bool HasMigrationObserver(const MigrationObserver* observer) const; - void RemoveMigrationObserver(MigrationObserver* observer); - - State state() const; - - // Called from ProfileSyncService to notify us of configure done. - // Note: We receive these notificiations only when our state is not IDLE. - void OnConfigureDone( - const sync_driver::DataTypeManager::ConfigureResult& result); - - // Returns the types that are currently pending migration (if any). - syncer::ModelTypeSet GetPendingMigrationTypesForTest() const; - - private: - void ChangeState(State new_state); - - // Must be called only in state WAITING_TO_START. If ready to - // start, meaning the data type manager is configured, calls - // RestartMigration() and returns true. Otherwise, does nothing and - // returns false. - bool TryStart(); - - // Restarts migration, interrupting any existing migration. - void RestartMigration(); - - // Called by OnConfigureDone(). - void OnConfigureDoneImpl( - const sync_driver::DataTypeManager::ConfigureResult& result); - - const std::string name_; - syncer::UserShare* user_share_; - sync_driver::SyncService* service_; - sync_driver::DataTypeManager* manager_; - - State state_; - - base::ObserverList<MigrationObserver> migration_observers_; - - syncer::ModelTypeSet to_migrate_; - - base::Closure migration_done_callback_; - - base::WeakPtrFactory<BackendMigrator> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(BackendMigrator); -}; - -} // namespace browser_sync - -#endif // COMPONENTS_SYNC_DRIVER_BACKEND_MIGRATOR_H_
diff --git a/components/sync_driver/backend_migrator_unittest.cc b/components/sync_driver/backend_migrator_unittest.cc deleted file mode 100644 index 2a84b90..0000000 --- a/components/sync_driver/backend_migrator_unittest.cc +++ /dev/null
@@ -1,332 +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 "components/sync_driver/backend_migrator.h" - -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/tracked_objects.h" -#include "components/sync/base/model_type_test_util.h" -#include "components/sync/core/test/test_user_share.h" -#include "components/sync/core/write_transaction.h" -#include "components/sync/protocol/sync.pb.h" -#include "components/sync/syncable/directory.h" // TODO(tim): Remove. Bug 131130. -#include "components/sync_driver/data_type_manager_mock.h" -#include "components/sync_driver/fake_sync_service.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using ::testing::_; -using ::testing::Eq; -using ::testing::Mock; -using ::testing::NiceMock; -using ::testing::Return; -using sync_driver::DataTypeManager; -using sync_driver::DataTypeManagerMock; - -namespace browser_sync { - -using syncer::sessions::SyncSessionSnapshot; - -class SyncBackendMigratorTest : public testing::Test { - public: - SyncBackendMigratorTest() { } - virtual ~SyncBackendMigratorTest() { } - - virtual void SetUp() { - test_user_share_.SetUp(); - Mock::VerifyAndClear(manager()); - preferred_types_.Put(syncer::BOOKMARKS); - preferred_types_.Put(syncer::PREFERENCES); - preferred_types_.Put(syncer::AUTOFILL); - - migrator_.reset( - new BackendMigrator( - "Profile0", test_user_share_.user_share(), service(), manager(), - base::Closure())); - SetUnsyncedTypes(syncer::ModelTypeSet()); - } - - virtual void TearDown() { - migrator_.reset(); - test_user_share_.TearDown(); - } - - // Marks all types in |unsynced_types| as unsynced and all other - // types as synced. - void SetUnsyncedTypes(syncer::ModelTypeSet unsynced_types) { - syncer::WriteTransaction trans(FROM_HERE, - test_user_share_.user_share()); - for (int i = syncer::FIRST_REAL_MODEL_TYPE; - i < syncer::MODEL_TYPE_COUNT; ++i) { - syncer::ModelType type = syncer::ModelTypeFromInt(i); - sync_pb::DataTypeProgressMarker progress_marker; - if (!unsynced_types.Has(type)) { - progress_marker.set_token("dummy"); - } - trans.GetDirectory()->SetDownloadProgress(type, progress_marker); - } - } - - void SendConfigureDone(DataTypeManager::ConfigureStatus status, - syncer::ModelTypeSet requested_types) { - if (status == DataTypeManager::OK) { - DataTypeManager::ConfigureResult result(status, requested_types); - migrator_->OnConfigureDone(result); - } else { - DataTypeManager::ConfigureResult result( - status, - requested_types); - migrator_->OnConfigureDone(result); - } - base::RunLoop run_loop; - run_loop.RunUntilIdle(); - } - - sync_driver::SyncService* service() { return &service_; } - DataTypeManagerMock* manager() { return &manager_; } - syncer::ModelTypeSet preferred_types() { return preferred_types_; } - BackendMigrator* migrator() { return migrator_.get(); } - void RemovePreferredType(syncer::ModelType type) { - preferred_types_.Remove(type); - } - - private: - base::MessageLoop message_loop_; - syncer::ModelTypeSet preferred_types_; - sync_driver::FakeSyncService service_; - NiceMock<DataTypeManagerMock> manager_; - syncer::TestUserShare test_user_share_; - std::unique_ptr<BackendMigrator> migrator_; -}; - -class MockMigrationObserver : public MigrationObserver { - public: - virtual ~MockMigrationObserver() {} - - MOCK_METHOD0(OnMigrationStateChange, void()); -}; - -// Test that in the normal case a migration does transition through each state -// and wind up back in IDLE. -TEST_F(SyncBackendMigratorTest, Sanity) { - MockMigrationObserver migration_observer; - migrator()->AddMigrationObserver(&migration_observer); - EXPECT_CALL(migration_observer, OnMigrationStateChange()).Times(4); - - syncer::ModelTypeSet to_migrate, difference; - to_migrate.Put(syncer::PREFERENCES); - difference.Put(syncer::AUTOFILL); - difference.Put(syncer::BOOKMARKS); - - EXPECT_CALL(*manager(), state()) - .WillOnce(Return(DataTypeManager::CONFIGURED)); - EXPECT_CALL( - *manager(), - PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1); - EXPECT_CALL( - *manager(), - Configure(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1); - - migrator()->MigrateTypes(to_migrate); - EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state()); - - SetUnsyncedTypes(to_migrate); - SendConfigureDone(DataTypeManager::OK, difference); - EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state()); - - SetUnsyncedTypes(syncer::ModelTypeSet()); - SendConfigureDone(DataTypeManager::OK, preferred_types()); - EXPECT_EQ(BackendMigrator::IDLE, migrator()->state()); - - migrator()->RemoveMigrationObserver(&migration_observer); -} - -// Test that in the normal case with Nigori a migration transitions through -// each state and wind up back in IDLE. -TEST_F(SyncBackendMigratorTest, MigrateNigori) { - syncer::ModelTypeSet to_migrate, difference; - to_migrate.Put(syncer::NIGORI); - difference.Put(syncer::AUTOFILL); - difference.Put(syncer::BOOKMARKS); - - EXPECT_CALL(*manager(), state()) - .WillOnce(Return(DataTypeManager::CONFIGURED)); - - EXPECT_CALL(*manager(), PurgeForMigration(_, - syncer::CONFIGURE_REASON_MIGRATION)); - - migrator()->MigrateTypes(to_migrate); - EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state()); - - SetUnsyncedTypes(to_migrate); - SendConfigureDone(DataTypeManager::OK, difference); - EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state()); - - SetUnsyncedTypes(syncer::ModelTypeSet()); - SendConfigureDone(DataTypeManager::OK, preferred_types()); - EXPECT_EQ(BackendMigrator::IDLE, migrator()->state()); -} - - -// Test that the migrator waits for the data type manager to be idle before -// starting a migration. -TEST_F(SyncBackendMigratorTest, WaitToStart) { - syncer::ModelTypeSet to_migrate; - to_migrate.Put(syncer::PREFERENCES); - - EXPECT_CALL(*manager(), state()) - .WillOnce(Return(DataTypeManager::CONFIGURING)); - EXPECT_CALL(*manager(), Configure(_, _)).Times(0); - migrator()->MigrateTypes(to_migrate); - EXPECT_EQ(BackendMigrator::WAITING_TO_START, migrator()->state()); - - Mock::VerifyAndClearExpectations(manager()); - EXPECT_CALL(*manager(), state()) - .WillOnce(Return(DataTypeManager::CONFIGURED)); - EXPECT_CALL(*manager(), - PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)); - SetUnsyncedTypes(syncer::ModelTypeSet()); - SendConfigureDone(DataTypeManager::OK, syncer::ModelTypeSet()); - - EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state()); -} - -// Test that the migrator can cope with a migration request while a migration -// is in progress. -TEST_F(SyncBackendMigratorTest, RestartMigration) { - syncer::ModelTypeSet to_migrate1, to_migrate2, to_migrate_union, bookmarks; - to_migrate1.Put(syncer::PREFERENCES); - to_migrate2.Put(syncer::AUTOFILL); - to_migrate_union.Put(syncer::PREFERENCES); - to_migrate_union.Put(syncer::AUTOFILL); - bookmarks.Put(syncer::BOOKMARKS); - - EXPECT_CALL(*manager(), state()) - .WillOnce(Return(DataTypeManager::CONFIGURED)); - EXPECT_CALL( - *manager(), - PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(2); - migrator()->MigrateTypes(to_migrate1); - - EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state()); - migrator()->MigrateTypes(to_migrate2); - - const syncer::ModelTypeSet difference1 = - Difference(preferred_types(), to_migrate1); - - Mock::VerifyAndClearExpectations(manager()); - EXPECT_CALL( - *manager(), - PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1); - EXPECT_CALL(*manager(), Configure(_, syncer::CONFIGURE_REASON_MIGRATION)) - .Times(1); - SetUnsyncedTypes(to_migrate1); - SendConfigureDone(DataTypeManager::OK, difference1); - EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state()); - - SetUnsyncedTypes(to_migrate_union); - SendConfigureDone(DataTypeManager::OK, bookmarks); - EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state()); -} - -// Test that an external invocation of Configure(...) during a migration results -// in a migration reattempt. -TEST_F(SyncBackendMigratorTest, InterruptedWhileDisablingTypes) { - syncer::ModelTypeSet to_migrate; - syncer::ModelTypeSet difference; - to_migrate.Put(syncer::PREFERENCES); - difference.Put(syncer::AUTOFILL); - difference.Put(syncer::BOOKMARKS); - - EXPECT_CALL(*manager(), state()) - .WillOnce(Return(DataTypeManager::CONFIGURED)); - EXPECT_CALL(*manager(), PurgeForMigration(HasModelTypes(to_migrate), - syncer::CONFIGURE_REASON_MIGRATION)); - migrator()->MigrateTypes(to_migrate); - EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state()); - - Mock::VerifyAndClearExpectations(manager()); - EXPECT_CALL(*manager(), PurgeForMigration(HasModelTypes(to_migrate), - syncer::CONFIGURE_REASON_MIGRATION)); - SetUnsyncedTypes(syncer::ModelTypeSet()); - SendConfigureDone(DataTypeManager::OK, preferred_types()); - - EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state()); -} - -// Test that spurious OnConfigureDone events don't confuse the -// migrator while it's waiting for disabled types to have been purged -// from the sync db. -TEST_F(SyncBackendMigratorTest, WaitingForPurge) { - syncer::ModelTypeSet to_migrate, difference; - to_migrate.Put(syncer::PREFERENCES); - to_migrate.Put(syncer::AUTOFILL); - difference.Put(syncer::BOOKMARKS); - - EXPECT_CALL(*manager(), state()) - .WillOnce(Return(DataTypeManager::CONFIGURED)); - EXPECT_CALL( - *manager(), - PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1); - EXPECT_CALL( - *manager(), - Configure(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1); - - migrator()->MigrateTypes(to_migrate); - EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state()); - - SendConfigureDone(DataTypeManager::OK, difference); - EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state()); - - syncer::ModelTypeSet prefs; - prefs.Put(syncer::PREFERENCES); - SetUnsyncedTypes(prefs); - SendConfigureDone(DataTypeManager::OK, difference); - EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator()->state()); - - SetUnsyncedTypes(to_migrate); - SendConfigureDone(DataTypeManager::OK, difference); - EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state()); -} - -TEST_F(SyncBackendMigratorTest, MigratedTypeDisabledByUserDuringMigration) { - syncer::ModelTypeSet to_migrate; - to_migrate.Put(syncer::PREFERENCES); - - EXPECT_CALL(*manager(), state()) - .WillOnce(Return(DataTypeManager::CONFIGURED)); - EXPECT_CALL( - *manager(), - PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1); - EXPECT_CALL( - *manager(), - Configure(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1); - migrator()->MigrateTypes(to_migrate); - - RemovePreferredType(syncer::PREFERENCES); - SetUnsyncedTypes(to_migrate); - SendConfigureDone(DataTypeManager::OK, preferred_types()); - EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator()->state()); - SetUnsyncedTypes(syncer::ModelTypeSet()); - SendConfigureDone(DataTypeManager::OK, preferred_types()); - EXPECT_EQ(BackendMigrator::IDLE, migrator()->state()); -} - -TEST_F(SyncBackendMigratorTest, ConfigureFailure) { - syncer::ModelTypeSet to_migrate; - to_migrate.Put(syncer::PREFERENCES); - - EXPECT_CALL(*manager(), state()) - .WillOnce(Return(DataTypeManager::CONFIGURED)); - EXPECT_CALL( - *manager(), - PurgeForMigration(_, syncer::CONFIGURE_REASON_MIGRATION)).Times(1); - migrator()->MigrateTypes(to_migrate); - SetUnsyncedTypes(syncer::ModelTypeSet()); - SendConfigureDone(DataTypeManager::ABORTED, syncer::ModelTypeSet()); - EXPECT_EQ(BackendMigrator::IDLE, migrator()->state()); -} - -}; // namespace browser_sync
diff --git a/components/sync_driver/change_processor.cc b/components/sync_driver/change_processor.cc deleted file mode 100644 index 868af42c..0000000 --- a/components/sync_driver/change_processor.cc +++ /dev/null
@@ -1,32 +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 "components/sync_driver/change_processor.h" - -namespace sync_driver { - -ChangeProcessor::ChangeProcessor(syncer::DataTypeErrorHandler* error_handler) - : error_handler_(error_handler), share_handle_(NULL) {} - -ChangeProcessor::~ChangeProcessor() { -} - -void ChangeProcessor::Start(syncer::UserShare* share_handle) { - DCHECK(!share_handle_); - share_handle_ = share_handle; - StartImpl(); -} - -// Not implemented by default. -void ChangeProcessor::CommitChangesFromSyncModel() {} - -syncer::DataTypeErrorHandler* ChangeProcessor::error_handler() const { - return error_handler_; -} - -syncer::UserShare* ChangeProcessor::share_handle() const { - return share_handle_; -} - -} // namespace sync_driver
diff --git a/components/sync_driver/change_processor_mock.cc b/components/sync_driver/change_processor_mock.cc deleted file mode 100644 index 1529859..0000000 --- a/components/sync_driver/change_processor_mock.cc +++ /dev/null
@@ -1,16 +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 "components/sync_driver/change_processor_mock.h" - -#include "base/compiler_specific.h" - -namespace sync_driver { - -ChangeProcessorMock::ChangeProcessorMock() - : ChangeProcessor(this) {} - -ChangeProcessorMock::~ChangeProcessorMock() {} - -} // namespace sync_driver
diff --git a/components/sync_driver/change_processor_mock.h b/components/sync_driver/change_processor_mock.h deleted file mode 100644 index 981d3f78..0000000 --- a/components/sync_driver/change_processor_mock.h +++ /dev/null
@@ -1,44 +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 COMPONENTS_SYNC_DRIVER_CHANGE_PROCESSOR_MOCK_H_ -#define COMPONENTS_SYNC_DRIVER_CHANGE_PROCESSOR_MOCK_H_ - -#include <stdint.h> - -#include <string> - -#include "components/sync/base/model_type.h" -#include "components/sync/base/unrecoverable_error_handler.h" -#include "components/sync/core/data_type_error_handler.h" -#include "components/sync_driver/change_processor.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace sync_driver { - -class ChangeProcessorMock : public ChangeProcessor, - public syncer::DataTypeErrorHandler { - public: - ChangeProcessorMock(); - virtual ~ChangeProcessorMock(); - MOCK_METHOD3(ApplyChangesFromSyncModel, - void(const syncer::BaseTransaction*, - int64_t, - const syncer::ImmutableChangeRecordList&)); - MOCK_METHOD0(CommitChangesFromSyncModel, void()); - MOCK_METHOD0(StartImpl, void()); - MOCK_CONST_METHOD0(IsRunning, bool()); - MOCK_METHOD2(OnUnrecoverableError, void(const tracked_objects::Location&, - const std::string&)); - MOCK_METHOD1(OnSingleDataTypeUnrecoverableError, - void(const syncer::SyncError&)); - MOCK_METHOD3(CreateAndUploadError, - syncer::SyncError(const tracked_objects::Location&, - const std::string&, - syncer::ModelType)); -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_CHANGE_PROCESSOR_MOCK_H_
diff --git a/components/sync_driver/data_type_controller.cc b/components/sync_driver/data_type_controller.cc deleted file mode 100644 index f1a138d..0000000 --- a/components/sync_driver/data_type_controller.cc +++ /dev/null
@@ -1,47 +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 "components/sync_driver/data_type_controller.h" - -#include "components/sync/base/data_type_histogram.h" -#include "components/sync/base/model_type.h" -#include "components/sync/core/user_share.h" - -namespace sync_driver { - -DataTypeController::DataTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const base::Closure& error_callback) - : base::RefCountedDeleteOnMessageLoop<DataTypeController>(ui_thread), - error_callback_(error_callback), - ui_thread_(ui_thread) {} - -DataTypeController::~DataTypeController() { -} - -bool DataTypeController::IsUnrecoverableResult(ConfigureResult result) { - return (result == UNRECOVERABLE_ERROR); -} - -bool DataTypeController::IsSuccessfulResult(ConfigureResult result) { - return (result == OK || result == OK_FIRST_RUN); -} - -syncer::SyncError DataTypeController::CreateAndUploadError( - const tracked_objects::Location& location, - const std::string& message, - syncer::ModelType type) { - if (!error_callback_.is_null()) - error_callback_.Run(); - return syncer::SyncError(location, - syncer::SyncError::DATATYPE_ERROR, - message, - type); -} - -bool DataTypeController::ReadyForStart() const { - return true; -} - -} // namespace sync_driver
diff --git a/components/sync_driver/data_type_controller.h b/components/sync_driver/data_type_controller.h deleted file mode 100644 index 2d9f70b..0000000 --- a/components/sync_driver/data_type_controller.h +++ /dev/null
@@ -1,179 +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 COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_H__ -#define COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_H__ - -#include <map> -#include <string> - -#include "base/callback.h" -#include "base/location.h" -#include "base/memory/ref_counted.h" -#include "base/memory/ref_counted_delete_on_message_loop.h" -#include "base/sequenced_task_runner_helpers.h" -#include "components/sync/base/model_type.h" -#include "components/sync/base/unrecoverable_error_handler.h" -#include "components/sync/core/data_type_error_handler.h" - -namespace base { -class SingleThreadTaskRunner; -} - -namespace syncer { -class SyncError; -class SyncMergeResult; -} - -namespace sync_driver { -class BackendDataTypeConfigurer; - -// Data type controllers need to be refcounted threadsafe, as they may -// need to run model associator or change processor on other threads. -class DataTypeController - : public base::RefCountedDeleteOnMessageLoop<DataTypeController>, - public syncer::DataTypeErrorHandler { - public: - enum State { - NOT_RUNNING, // The controller has never been started or has previously - // been stopped. Must be in this state to start. - MODEL_STARTING, // The controller is waiting on dependent services - // that need to be available before model - // association. - MODEL_LOADED, // The model has finished loading and can start - // associating now. - ASSOCIATING, // Model association is in progress. - RUNNING, // The controller is running and the data type is - // in sync with the cloud. - STOPPING, // The controller is in the process of stopping - // and is waiting for dependent services to stop. - DISABLED // The controller was started but encountered an error - // so it is disabled waiting for it to be stopped. - }; - - // This enum is used for "Sync.*ConfigureFailre" histograms so the order - // of is important. Any changes need to be reflected in histograms.xml. - enum ConfigureResult { - OK, // The data type has started normally. - OK_FIRST_RUN, // Same as OK, but sent on first successful - // start for this type for this user as - // determined by cloud state. - ASSOCIATION_FAILED, // An error occurred during model association. - ABORTED, // Start was aborted by calling Stop(). - UNRECOVERABLE_ERROR, // An unrecoverable error occured. - NEEDS_CRYPTO, // The data type cannot be started yet because it - // depends on the cryptographer. - RUNTIME_ERROR, // After starting, a runtime error was encountered. - MAX_CONFIGURE_RESULT - }; - - typedef base::Callback<void(ConfigureResult, - const syncer::SyncMergeResult&, - const syncer::SyncMergeResult&)> StartCallback; - - typedef base::Callback<void(syncer::ModelType, - syncer::SyncError)> ModelLoadCallback; - - typedef std::map<syncer::ModelType, - scoped_refptr<DataTypeController> > TypeMap; - typedef std::map<syncer::ModelType, DataTypeController::State> StateMap; - - // Returns true if the start result should trigger an unrecoverable error. - // Public so unit tests can use this function as well. - static bool IsUnrecoverableResult(ConfigureResult result); - - // Returns true if the datatype started successfully. - static bool IsSuccessfulResult(ConfigureResult result); - - // Returns true if DataTypeManager should wait for LoadModels to complete - // successfully before starting configuration. Directory based types should - // return false while USS datatypes should return true. - virtual bool ShouldLoadModelBeforeConfigure() const = 0; - - // Begins asynchronous operation of loading the model to get it ready for - // model association. Once the models are loaded the callback will be invoked - // with the result. If the models are already loaded it is safe to call the - // callback right away. Else the callback needs to be stored and called when - // the models are ready. - virtual void LoadModels(const ModelLoadCallback& model_load_callback) = 0; - - // Registers with sync backend if needed. This function is called by - // DataTypeManager before downloading initial data. Non-blocking types need to - // pass activation context containing progress marker to sync backend before - // initial download starts. - virtual void RegisterWithBackend(BackendDataTypeConfigurer* configurer) = 0; - - // Will start a potentially asynchronous operation to perform the - // model association. Once the model association is done the callback will - // be invoked. - virtual void StartAssociating(const StartCallback& start_callback) = 0; - - // Called by DataTypeManager to activate the controlled data type using - // one of the implementation specific methods provided by the |configurer|. - // This is called (on UI thread) after the data type configuration has - // completed successfully. - virtual void ActivateDataType(BackendDataTypeConfigurer* configurer) = 0; - - // Called by DataTypeManager to deactivate the controlled data type. - // See comments for ModelAssociationManager::OnSingleDataTypeWillStop. - virtual void DeactivateDataType(BackendDataTypeConfigurer* configurer) = 0; - - // Synchronously stops the data type. If StartAssociating has already been - // called but is not done yet it will be aborted. Similarly if LoadModels - // has not completed it will also be aborted. - // NOTE: Stop() should be called after sync backend machinery has stopped - // routing changes to this data type. Stop() should ensure the data type - // logic shuts down gracefully by flushing remaining changes and calling - // StopSyncing on the SyncableService. This assumes no changes will ever - // propagate from sync again from point where Stop() is called. - virtual void Stop() = 0; - - // Unique model type for this data type controller. - virtual syncer::ModelType type() const = 0; - - // Name of this data type. For logging purposes only. - virtual std::string name() const = 0; - - // Current state of the data type controller. - virtual State state() const = 0; - - // Partial implementation of DataTypeErrorHandler. - // This is thread safe. - syncer::SyncError CreateAndUploadError( - const tracked_objects::Location& location, - const std::string& message, - syncer::ModelType type) override; - - // Whether the DataTypeController is ready to start. This is useful if the - // datatype itself must make the decision about whether it should be enabled - // at all (and therefore whether the initial download of the sync data for - // the type should be performed). - // Returns true by default. - virtual bool ReadyForStart() const; - - protected: - friend class base::RefCountedDeleteOnMessageLoop<DataTypeController>; - friend class base::DeleteHelper<DataTypeController>; - - DataTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const base::Closure& error_callback); - - ~DataTypeController() override; - - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread() const { - return ui_thread_; - } - - // The callback that will be invoked when an unrecoverable error occurs. - // TODO(sync): protected for use by legacy controllers. - base::Closure error_callback_; - - private: - const scoped_refptr<base::SingleThreadTaskRunner> ui_thread_; -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_H__
diff --git a/components/sync_driver/data_type_controller_mock.cc b/components/sync_driver/data_type_controller_mock.cc deleted file mode 100644 index 5dc24c7..0000000 --- a/components/sync_driver/data_type_controller_mock.cc +++ /dev/null
@@ -1,17 +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 "components/sync_driver/data_type_controller_mock.h" - -namespace sync_driver { - -StartCallbackMock::StartCallbackMock() {} - -StartCallbackMock::~StartCallbackMock() {} - -ModelLoadCallbackMock::ModelLoadCallbackMock() {} - -ModelLoadCallbackMock::~ModelLoadCallbackMock() {} - -} // namespace sync_driver
diff --git a/components/sync_driver/data_type_controller_mock.h b/components/sync_driver/data_type_controller_mock.h deleted file mode 100644 index 516fe93..0000000 --- a/components/sync_driver/data_type_controller_mock.h +++ /dev/null
@@ -1,35 +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 COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_MOCK_H__ -#define COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_MOCK_H__ - -#include "components/sync/api/sync_error.h" -#include "components/sync/api/sync_merge_result.h" -#include "components/sync_driver/data_type_controller.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace sync_driver { - -class StartCallbackMock { - public: - StartCallbackMock(); - virtual ~StartCallbackMock(); - - MOCK_METHOD3(Run, void(DataTypeController::ConfigureResult result, - const syncer::SyncMergeResult& local_merge_result, - const syncer::SyncMergeResult& syncer_merge_result)); -}; - -class ModelLoadCallbackMock { - public: - ModelLoadCallbackMock(); - virtual ~ModelLoadCallbackMock(); - - MOCK_METHOD2(Run, void(syncer::ModelType, syncer::SyncError)); -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_DATA_TYPE_CONTROLLER_MOCK_H__
diff --git a/components/sync_driver/data_type_encryption_handler.cc b/components/sync_driver/data_type_encryption_handler.cc deleted file mode 100644 index 4325d56..0000000 --- a/components/sync_driver/data_type_encryption_handler.cc +++ /dev/null
@@ -1,12 +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 "components/sync_driver/data_type_encryption_handler.h" - -namespace sync_driver { - -DataTypeEncryptionHandler::DataTypeEncryptionHandler() {} -DataTypeEncryptionHandler::~DataTypeEncryptionHandler() {} - -}
diff --git a/components/sync_driver/data_type_manager.cc b/components/sync_driver/data_type_manager.cc deleted file mode 100644 index 1288b23..0000000 --- a/components/sync_driver/data_type_manager.cc +++ /dev/null
@@ -1,41 +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 "components/sync_driver/data_type_manager.h" - -namespace sync_driver { - -DataTypeManager::ConfigureResult::ConfigureResult() - : status(UNKNOWN) { -} - -DataTypeManager::ConfigureResult::ConfigureResult( - ConfigureStatus status, - syncer::ModelTypeSet requested_types) - : status(status), requested_types(requested_types) { -} - -DataTypeManager::ConfigureResult::ConfigureResult( - const ConfigureResult& other) = default; - -DataTypeManager::ConfigureResult::~ConfigureResult() { -} - -// Static. -std::string DataTypeManager::ConfigureStatusToString(ConfigureStatus status) { - switch (status) { - case OK: - return "Ok"; - case ABORTED: - return "Aborted"; - case UNRECOVERABLE_ERROR: - return "Unrecoverable Error"; - case UNKNOWN: - NOTREACHED(); - return std::string(); - } - return std::string(); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/data_type_manager.h b/components/sync_driver/data_type_manager.h deleted file mode 100644 index 75747fc..0000000 --- a/components/sync_driver/data_type_manager.h +++ /dev/null
@@ -1,98 +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 COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_H__ -#define COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_H__ - -#include <list> -#include <set> -#include <string> - -#include "components/sync/api/sync_error.h" -#include "components/sync/base/model_type.h" -#include "components/sync/core/configure_reason.h" -#include "components/sync_driver/data_type_controller.h" -#include "components/sync_driver/data_type_status_table.h" - -namespace sync_driver { - -// This interface is for managing the start up and shut down life cycle -// of many different syncable data types. -class DataTypeManager { - public: - enum State { - STOPPED, // No data types are currently running. - CONFIGURING, // Data types are being started. - RETRYING, // Retrying a pending reconfiguration. - - CONFIGURED, // All enabled data types are running. - STOPPING // Data types are being stopped. - }; - - // Update NotifyDone() in data_type_manager_impl.cc if you update - // this. - enum ConfigureStatus { - UNKNOWN = -1, - OK, // Configuration finished some or all types. - ABORTED, // Start was aborted by calling Stop() before - // all types were started. - UNRECOVERABLE_ERROR // We got an unrecoverable error during startup. - }; - - // Note: |errors| is only filled when status is not OK. - struct ConfigureResult { - ConfigureResult(); - ConfigureResult(ConfigureStatus status, - syncer::ModelTypeSet requested_types); - ConfigureResult(const ConfigureResult& other); - ~ConfigureResult(); - - ConfigureStatus status; - syncer::ModelTypeSet requested_types; - DataTypeStatusTable data_type_status_table; - }; - - virtual ~DataTypeManager() {} - - // Convert a ConfigureStatus to string for debug purposes. - static std::string ConfigureStatusToString(ConfigureStatus status); - - // Begins asynchronous configuration of data types. Any currently - // running data types that are not in the desired_types set will be - // stopped. Any stopped data types that are in the desired_types - // set will be started. All other data types are left in their - // current state. A SYNC_CONFIGURE_START notification will be sent - // to the UI thread when configuration is started and a - // SYNC_CONFIGURE_DONE notification will be sent (with a - // ConfigureResult detail) when configuration is complete. - // - // Note that you may call Configure() while configuration is in - // progress. Configuration will be complete only when the - // desired_types supplied in the last call to Configure is achieved. - virtual void Configure(syncer::ModelTypeSet desired_types, - syncer::ConfigureReason reason) = 0; - - // Resets the error state for |type| and triggers a reconfiguration if - // necessary. - virtual void ReenableType(syncer::ModelType type) = 0; - - // Resets all data type error state. - virtual void ResetDataTypeErrors() = 0; - - virtual void PurgeForMigration(syncer::ModelTypeSet undesired_types, - syncer::ConfigureReason reason) = 0; - - // Synchronously stops all registered data types. If called after - // Configure() is called but before it finishes, it will abort the - // configure and any data types that have been started will be - // stopped. - virtual void Stop() = 0; - - // The current state of the data type manager. - virtual State state() const = 0; -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_H__
diff --git a/components/sync_driver/data_type_manager_impl.cc b/components/sync_driver/data_type_manager_impl.cc deleted file mode 100644 index 9d2033c..0000000 --- a/components/sync_driver/data_type_manager_impl.cc +++ /dev/null
@@ -1,710 +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 "components/sync_driver/data_type_manager_impl.h" - -#include <algorithm> -#include <functional> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/callback.h" -#include "base/compiler_specific.h" -#include "base/logging.h" -#include "base/metrics/histogram_macros.h" -#include "base/profiler/scoped_tracker.h" -#include "base/strings/stringprintf.h" -#include "base/trace_event/trace_event.h" -#include "components/sync/core/data_type_debug_info_listener.h" -#include "components/sync_driver/data_type_encryption_handler.h" -#include "components/sync_driver/data_type_manager_observer.h" -#include "components/sync_driver/data_type_status_table.h" - -namespace sync_driver { - -namespace { - -DataTypeStatusTable::TypeErrorMap -GenerateCryptoErrorsForTypes(syncer::ModelTypeSet encrypted_types) { - DataTypeStatusTable::TypeErrorMap crypto_errors; - for (syncer::ModelTypeSet::Iterator iter = encrypted_types.First(); - iter.Good(); iter.Inc()) { - crypto_errors[iter.Get()] = syncer::SyncError( - FROM_HERE, - syncer::SyncError::CRYPTO_ERROR, - "", - iter.Get()); - } - return crypto_errors; -} - -} // namespace - -DataTypeManagerImpl::AssociationTypesInfo::AssociationTypesInfo() {} -DataTypeManagerImpl::AssociationTypesInfo::AssociationTypesInfo( - const AssociationTypesInfo& other) = default; -DataTypeManagerImpl::AssociationTypesInfo::~AssociationTypesInfo() {} - -DataTypeManagerImpl::DataTypeManagerImpl( - const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& - debug_info_listener, - const DataTypeController::TypeMap* controllers, - const DataTypeEncryptionHandler* encryption_handler, - BackendDataTypeConfigurer* configurer, - DataTypeManagerObserver* observer) - : configurer_(configurer), - controllers_(controllers), - state_(DataTypeManager::STOPPED), - needs_reconfigure_(false), - last_configure_reason_(syncer::CONFIGURE_REASON_UNKNOWN), - debug_info_listener_(debug_info_listener), - model_association_manager_(controllers, this), - observer_(observer), - encryption_handler_(encryption_handler), - catch_up_in_progress_(false), - download_started_(false), - weak_ptr_factory_(this) { - DCHECK(configurer_); - DCHECK(observer_); -} - -DataTypeManagerImpl::~DataTypeManagerImpl() {} - -void DataTypeManagerImpl::Configure(syncer::ModelTypeSet desired_types, - syncer::ConfigureReason reason) { - // Once requested, we will remain in "catch up" mode until we notify the - // caller (see NotifyDone). We do this to ensure that once started, subsequent - // calls to Configure won't take us out of "catch up" mode. - if (reason == syncer::CONFIGURE_REASON_CATCH_UP) - catch_up_in_progress_ = true; - - desired_types.PutAll(syncer::CoreTypes()); - - // Only allow control types and types that have controllers. - syncer::ModelTypeSet filtered_desired_types; - for (syncer::ModelTypeSet::Iterator type = desired_types.First(); - type.Good(); type.Inc()) { - DataTypeController::TypeMap::const_iterator iter = - controllers_->find(type.Get()); - if (syncer::IsControlType(type.Get()) || iter != controllers_->end()) { - if (iter != controllers_->end()) { - if (!iter->second->ReadyForStart() && - !data_type_status_table_.GetUnreadyErrorTypes().Has( - type.Get())) { - // Add the type to the unready types set to prevent purging it. It's - // up to the datatype controller to, if necessary, explicitly - // mark the type as broken to trigger a purge. - syncer::SyncError error(FROM_HERE, - syncer::SyncError::UNREADY_ERROR, - "Datatype not ready at config time.", - type.Get()); - std::map<syncer::ModelType, syncer::SyncError> errors; - errors[type.Get()] = error; - data_type_status_table_.UpdateFailedDataTypes(errors); - } else if (iter->second->ReadyForStart()) { - data_type_status_table_.ResetUnreadyErrorFor(type.Get()); - } - } - filtered_desired_types.Put(type.Get()); - } - } - ConfigureImpl(filtered_desired_types, reason); -} - -void DataTypeManagerImpl::ReenableType(syncer::ModelType type) { - // TODO(zea): move the "should we reconfigure" logic into the datatype handler - // itself. - // Only reconfigure if the type actually had a data type or unready error. - if (!data_type_status_table_.ResetDataTypeErrorFor(type) && - !data_type_status_table_.ResetUnreadyErrorFor(type)) { - return; - } - - // Only reconfigure if the type is actually desired. - if (!last_requested_types_.Has(type)) - return; - - DVLOG(1) << "Reenabling " << syncer::ModelTypeToString(type); - needs_reconfigure_ = true; - last_configure_reason_ = syncer::CONFIGURE_REASON_PROGRAMMATIC; - ProcessReconfigure(); -} - -void DataTypeManagerImpl::ResetDataTypeErrors() { - data_type_status_table_.Reset(); -} - -void DataTypeManagerImpl::PurgeForMigration( - syncer::ModelTypeSet undesired_types, - syncer::ConfigureReason reason) { - syncer::ModelTypeSet remainder = Difference(last_requested_types_, - undesired_types); - ConfigureImpl(remainder, reason); -} - -void DataTypeManagerImpl::ConfigureImpl( - syncer::ModelTypeSet desired_types, - syncer::ConfigureReason reason) { - DCHECK_NE(reason, syncer::CONFIGURE_REASON_UNKNOWN); - DVLOG(1) << "Configuring for " << syncer::ModelTypeSetToString(desired_types) - << " with reason " << reason; - if (state_ == STOPPING) { - // You can not set a configuration while stopping. - LOG(ERROR) << "Configuration set while stopping."; - return; - } - - // TODO(zea): consider not performing a full configuration once there's a - // reliable way to determine if the requested set of enabled types matches the - // current set. - - last_requested_types_ = desired_types; - last_configure_reason_ = reason; - // Only proceed if we're in a steady state or retrying. - if (state_ != STOPPED && state_ != CONFIGURED && state_ != RETRYING) { - DVLOG(1) << "Received configure request while configuration in flight. " - << "Postponing until current configuration complete."; - needs_reconfigure_ = true; - return; - } - - Restart(reason); -} - -void DataTypeManagerImpl::RegisterTypesWithBackend() { - for (syncer::ModelTypeSet::Iterator type_iter = last_requested_types_.First(); - type_iter.Good(); type_iter.Inc()) { - const auto& dtc_iter = controllers_->find(type_iter.Get()); - if (dtc_iter != controllers_->end()) - dtc_iter->second->RegisterWithBackend(configurer_); - } -} - -BackendDataTypeConfigurer::DataTypeConfigStateMap -DataTypeManagerImpl::BuildDataTypeConfigStateMap( - const syncer::ModelTypeSet& types_being_configured) const { - // 1. Get the failed types (due to fatal, crypto, and unready errors). - // 2. Add the difference between last_requested_types_ and the failed types - // as CONFIGURE_INACTIVE. - // 3. Flip |types_being_configured| to CONFIGURE_ACTIVE. - // 4. Set non-enabled user types as DISABLED. - // 5. Set the fatal, crypto, and unready types to their respective states. - syncer::ModelTypeSet error_types = - data_type_status_table_.GetFailedTypes(); - syncer::ModelTypeSet fatal_types = - data_type_status_table_.GetFatalErrorTypes(); - syncer::ModelTypeSet crypto_types = - data_type_status_table_.GetCryptoErrorTypes(); - syncer::ModelTypeSet unready_types = - data_type_status_table_.GetUnreadyErrorTypes(); - - // Types with persistence errors are only purged/resynced when they're - // actively being configured. - syncer::ModelTypeSet clean_types = - data_type_status_table_.GetPersistenceErrorTypes(); - clean_types.RetainAll(types_being_configured); - - // Types with unready errors do not count as unready if they've been disabled. - unready_types.RetainAll(last_requested_types_); - - syncer::ModelTypeSet enabled_types = last_requested_types_; - enabled_types.RemoveAll(error_types); - - // If we're catching up, add all enabled (non-error) types to the clean set to - // ensure we download and apply them to the model types. - if (catch_up_in_progress_) - clean_types.PutAll(enabled_types); - - syncer::ModelTypeSet disabled_types = - syncer::Difference( - syncer::Union(syncer::UserTypes(), syncer::ControlTypes()), - enabled_types); - syncer::ModelTypeSet to_configure = syncer::Intersection( - enabled_types, types_being_configured); - DVLOG(1) << "Enabling: " << syncer::ModelTypeSetToString(enabled_types); - DVLOG(1) << "Configuring: " << syncer::ModelTypeSetToString(to_configure); - DVLOG(1) << "Disabling: " << syncer::ModelTypeSetToString(disabled_types); - - BackendDataTypeConfigurer::DataTypeConfigStateMap config_state_map; - BackendDataTypeConfigurer::SetDataTypesState( - BackendDataTypeConfigurer::CONFIGURE_INACTIVE, enabled_types, - &config_state_map); - BackendDataTypeConfigurer::SetDataTypesState( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, to_configure, - &config_state_map); - BackendDataTypeConfigurer::SetDataTypesState( - BackendDataTypeConfigurer::CONFIGURE_CLEAN, clean_types, - &config_state_map); - BackendDataTypeConfigurer::SetDataTypesState( - BackendDataTypeConfigurer::DISABLED, disabled_types, - &config_state_map); - BackendDataTypeConfigurer::SetDataTypesState( - BackendDataTypeConfigurer::FATAL, fatal_types, - &config_state_map); - BackendDataTypeConfigurer::SetDataTypesState( - BackendDataTypeConfigurer::CRYPTO, crypto_types, - &config_state_map); - BackendDataTypeConfigurer::SetDataTypesState( - BackendDataTypeConfigurer::UNREADY, unready_types, - &config_state_map); - return config_state_map; -} - -void DataTypeManagerImpl::Restart(syncer::ConfigureReason reason) { - DVLOG(1) << "Restarting..."; - - // Only record the type histograms for user-triggered configurations or - // restarts. - if (reason == syncer::CONFIGURE_REASON_RECONFIGURATION || - reason == syncer::CONFIGURE_REASON_NEW_CLIENT || - reason == syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE) { - for (syncer::ModelTypeSet::Iterator iter = last_requested_types_.First(); - iter.Good(); iter.Inc()) { - UMA_HISTOGRAM_ENUMERATION("Sync.ConfigureDataTypes", - syncer::ModelTypeToHistogramInt(iter.Get()), - syncer::MODEL_TYPE_COUNT); - } - } - - // Check for new or resolved data type crypto errors. - if (encryption_handler_->IsPassphraseRequired()) { - syncer::ModelTypeSet encrypted_types = - encryption_handler_->GetEncryptedDataTypes(); - encrypted_types.RetainAll(last_requested_types_); - encrypted_types.RemoveAll( - data_type_status_table_.GetCryptoErrorTypes()); - DataTypeStatusTable::TypeErrorMap crypto_errors = - GenerateCryptoErrorsForTypes(encrypted_types); - data_type_status_table_.UpdateFailedDataTypes(crypto_errors); - } else { - data_type_status_table_.ResetCryptoErrors(); - } - - syncer::ModelTypeSet failed_types = - data_type_status_table_.GetFailedTypes(); - syncer::ModelTypeSet enabled_types = - syncer::Difference(last_requested_types_, failed_types); - - last_restart_time_ = base::Time::Now(); - configuration_stats_.clear(); - - DCHECK(state_ == STOPPED || state_ == CONFIGURED || state_ == RETRYING); - - const State old_state = state_; - state_ = CONFIGURING; - - // Starting from a "steady state" (stopped or configured) state - // should send a start notification. - // Note: NotifyStart() must be called with the updated (non-idle) state, - // otherwise logic listening for the configuration start might not be aware - // of the fact that the DTM is in a configuration state. - if (old_state == STOPPED || old_state == CONFIGURED) - NotifyStart(); - - download_types_queue_ = PrioritizeTypes(enabled_types); - association_types_queue_ = std::queue<AssociationTypesInfo>(); - - // If we're performing a "catch up", first stop the model types to ensure the - // call to Initialize triggers model association. - if (catch_up_in_progress_) - model_association_manager_.Stop(); - download_started_ = false; - model_association_manager_.Initialize(enabled_types); -} - -void DataTypeManagerImpl::OnAllDataTypesReadyForConfigure() { - DCHECK(!download_started_); - download_started_ = true; - UMA_HISTOGRAM_LONG_TIMES("Sync.USSLoadModelsTime", - base::Time::Now() - last_restart_time_); - // TODO(pavely): By now some of datatypes in download_types_queue_ could have - // failed loading and should be excluded from configuration. I need to adjust - // download_types_queue_ for such types. - RegisterTypesWithBackend(); - StartNextDownload(syncer::ModelTypeSet()); -} - -syncer::ModelTypeSet DataTypeManagerImpl::GetPriorityTypes() const { - syncer::ModelTypeSet high_priority_types; - high_priority_types.PutAll(syncer::PriorityCoreTypes()); - high_priority_types.PutAll(syncer::PriorityUserTypes()); - return high_priority_types; -} - -TypeSetPriorityList DataTypeManagerImpl::PrioritizeTypes( - const syncer::ModelTypeSet& types) { - syncer::ModelTypeSet high_priority_types = GetPriorityTypes(); - high_priority_types.RetainAll(types); - - syncer::ModelTypeSet low_priority_types = - syncer::Difference(types, high_priority_types); - - TypeSetPriorityList result; - if (!high_priority_types.Empty()) - result.push(high_priority_types); - if (!low_priority_types.Empty()) - result.push(low_priority_types); - - // Could be empty in case of purging for migration, sync nothing, etc. - // Configure empty set to purge data from backend. - if (result.empty()) - result.push(syncer::ModelTypeSet()); - - return result; -} - -void DataTypeManagerImpl::ProcessReconfigure() { - DCHECK(needs_reconfigure_); - - // Wait for current download and association to finish. - if (!download_types_queue_.empty() || - model_association_manager_.state() == - ModelAssociationManager::ASSOCIATING) { - return; - } - - association_types_queue_ = std::queue<AssociationTypesInfo>(); - - // An attempt was made to reconfigure while we were already configuring. - // This can be because a passphrase was accepted or the user changed the - // set of desired types. Either way, |last_requested_types_| will contain - // the most recent set of desired types, so we just call configure. - // Note: we do this whether or not GetControllersNeedingStart is true, - // because we may need to stop datatypes. - DVLOG(1) << "Reconfiguring due to previous configure attempt occuring while" - << " busy."; - - // Note: ConfigureImpl is called directly, rather than posted, in order to - // ensure that any purging/unapplying/journaling happens while the set of - // failed types is still up to date. If stack unwinding were to be done - // via PostTask, the failed data types may be reset before the purging was - // performed. - state_ = RETRYING; - needs_reconfigure_ = false; - ConfigureImpl(last_requested_types_, last_configure_reason_); -} - -void DataTypeManagerImpl::OnDownloadRetry() { - DCHECK_EQ(CONFIGURING, state_); -} - -void DataTypeManagerImpl::DownloadReady( - syncer::ModelTypeSet types_to_download, - syncer::ModelTypeSet first_sync_types, - syncer::ModelTypeSet failed_configuration_types) { - DCHECK_EQ(CONFIGURING, state_); - - // Persistence errors are reset after each backend configuration attempt - // during which they would have been purged. - data_type_status_table_.ResetPersistenceErrorsFrom(types_to_download); - - if (!failed_configuration_types.Empty()) { - DataTypeStatusTable::TypeErrorMap errors; - for (syncer::ModelTypeSet::Iterator iter = - failed_configuration_types.First(); iter.Good(); iter.Inc()) { - syncer::SyncError error( - FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Backend failed to download type.", - iter.Get()); - errors[iter.Get()] = error; - } - data_type_status_table_.UpdateFailedDataTypes(errors); - needs_reconfigure_ = true; - } - - if (needs_reconfigure_) { - download_types_queue_ = TypeSetPriorityList(); - ProcessReconfigure(); - return; - } - - CHECK(!download_types_queue_.empty()); - download_types_queue_.pop(); - - // Those types that were already downloaded (non first sync/error types) - // should already be associating. Just kick off association of the newly - // downloaded types if necessary. - if (!association_types_queue_.empty()) { - association_types_queue_.back().first_sync_types = first_sync_types; - association_types_queue_.back().download_ready_time = base::Time::Now(); - StartNextAssociation(UNREADY_AT_CONFIG); - } else if (download_types_queue_.empty() && - model_association_manager_.state() != - ModelAssociationManager::ASSOCIATING) { - // There's nothing more to download or associate (implying either there were - // no types to associate or they associated as part of |ready_types|). - // If the model association manager is also finished, then we're done - // configuring. - state_ = CONFIGURED; - ConfigureResult result(OK, last_requested_types_); - NotifyDone(result); - return; - } - - StartNextDownload(types_to_download); -} - -void DataTypeManagerImpl::StartNextDownload( - syncer::ModelTypeSet high_priority_types_before) { - if (download_types_queue_.empty()) - return; - - // Tell the backend about the new set of data types we wish to sync. - // The task will be invoked when updates are downloaded. - syncer::ModelTypeSet ready_types = configurer_->ConfigureDataTypes( - last_configure_reason_, - BuildDataTypeConfigStateMap(download_types_queue_.front()), - base::Bind(&DataTypeManagerImpl::DownloadReady, - weak_ptr_factory_.GetWeakPtr(), - download_types_queue_.front()), - base::Bind(&DataTypeManagerImpl::OnDownloadRetry, - weak_ptr_factory_.GetWeakPtr())); - - AssociationTypesInfo association_info; - association_info.types = download_types_queue_.front(); - association_info.ready_types = ready_types; - association_info.download_start_time = base::Time::Now(); - association_info.high_priority_types_before = high_priority_types_before; - association_types_queue_.push(association_info); - - // Start associating those types that are already downloaded (does nothing - // if model associator is busy). - StartNextAssociation(READY_AT_CONFIG); -} - -void DataTypeManagerImpl::StartNextAssociation(AssociationGroup group) { - CHECK(!association_types_queue_.empty()); - - // If the model association manager is already associating, let it finish. - // The model association done event will result in associating any remaining - // association groups. - if (model_association_manager_.state() != - ModelAssociationManager::INITIALIZED) { - return; - } - - syncer::ModelTypeSet types_to_associate; - if (group == READY_AT_CONFIG) { - association_types_queue_.front().ready_association_request_time = - base::Time::Now(); - types_to_associate = association_types_queue_.front().ready_types; - } else { - DCHECK_EQ(UNREADY_AT_CONFIG, group); - // Only start associating the rest of the types if they have all finished - // downloading. - if (association_types_queue_.front().download_ready_time.is_null()) - return; - association_types_queue_.front().full_association_request_time = - base::Time::Now(); - // We request the full set of types here for completeness sake. All types - // within the READY_AT_CONFIG set will already be started and should be - // no-ops. - types_to_associate = association_types_queue_.front().types; - } - - DVLOG(1) << "Associating " - << syncer::ModelTypeSetToString(types_to_associate); - model_association_manager_.StartAssociationAsync(types_to_associate); -} - -void DataTypeManagerImpl::OnSingleDataTypeWillStop( - syncer::ModelType type, - const syncer::SyncError& error) { - DataTypeController::TypeMap::const_iterator c_it = controllers_->find(type); - DCHECK(c_it != controllers_->end()); - // Delegate deactivation to the controller. - c_it->second->DeactivateDataType(configurer_); - - if (error.IsSet()) { - DataTypeStatusTable::TypeErrorMap failed_types; - failed_types[type] = error; - data_type_status_table_.UpdateFailedDataTypes( - failed_types); - - // Unrecoverable errors will shut down the entire backend, so no need to - // reconfigure. - if (error.error_type() != syncer::SyncError::UNRECOVERABLE_ERROR) { - needs_reconfigure_ = true; - last_configure_reason_ = syncer::CONFIGURE_REASON_PROGRAMMATIC; - ProcessReconfigure(); - } - } -} - -void DataTypeManagerImpl::OnSingleDataTypeAssociationDone( - syncer::ModelType type, - const syncer::DataTypeAssociationStats& association_stats) { - DCHECK(!association_types_queue_.empty()); - DataTypeController::TypeMap::const_iterator c_it = controllers_->find(type); - DCHECK(c_it != controllers_->end()); - if (c_it->second->state() == DataTypeController::RUNNING) { - // Delegate activation to the controller. - c_it->second->ActivateDataType(configurer_); - } - - if (!debug_info_listener_.IsInitialized()) - return; - - AssociationTypesInfo& info = association_types_queue_.front(); - configuration_stats_.push_back(syncer::DataTypeConfigurationStats()); - configuration_stats_.back().model_type = type; - configuration_stats_.back().association_stats = association_stats; - if (info.types.Has(type)) { - // Times in |info| only apply to non-slow types. - configuration_stats_.back().download_wait_time = - info.download_start_time - last_restart_time_; - if (info.first_sync_types.Has(type)) { - configuration_stats_.back().download_time = - info.download_ready_time - info.download_start_time; - } - if (info.ready_types.Has(type)) { - configuration_stats_.back().association_wait_time_for_high_priority = - info.ready_association_request_time - info.download_start_time; - } else { - configuration_stats_.back().association_wait_time_for_high_priority = - info.full_association_request_time - info.download_ready_time; - } - configuration_stats_.back().high_priority_types_configured_before = - info.high_priority_types_before; - configuration_stats_.back().same_priority_types_configured_before = - info.configured_types; - info.configured_types.Put(type); - } -} - -void DataTypeManagerImpl::OnModelAssociationDone( - const DataTypeManager::ConfigureResult& result) { - DCHECK(state_ == STOPPING || state_ == CONFIGURING); - - if (state_ == STOPPING) - return; - - // Ignore abort/unrecoverable error if we need to reconfigure anyways. - if (needs_reconfigure_) { - ProcessReconfigure(); - return; - } - - if (result.status == ABORTED || result.status == UNRECOVERABLE_ERROR) { - Abort(result.status); - return; - } - - DCHECK(result.status == OK); - - CHECK(!association_types_queue_.empty()); - - // If this model association was for the full set of types, then this priority - // set is done. Otherwise it was just the ready types and the unready types - // still need to be associated. - if (result.requested_types == association_types_queue_.front().types) { - association_types_queue_.pop(); - if (!association_types_queue_.empty()) { - StartNextAssociation(READY_AT_CONFIG); - } else if (download_types_queue_.empty()) { - state_ = CONFIGURED; - NotifyDone(result); - } - } else { - DCHECK_EQ(association_types_queue_.front().ready_types, - result.requested_types); - // Will do nothing if the types are still downloading. - StartNextAssociation(UNREADY_AT_CONFIG); - } -} - -void DataTypeManagerImpl::Stop() { - if (state_ == STOPPED) - return; - - bool need_to_notify = state_ == CONFIGURING; - StopImpl(); - - if (need_to_notify) { - ConfigureResult result(ABORTED, - last_requested_types_); - NotifyDone(result); - } -} - -void DataTypeManagerImpl::Abort(ConfigureStatus status) { - DCHECK_EQ(CONFIGURING, state_); - - StopImpl(); - - DCHECK_NE(OK, status); - ConfigureResult result(status, - last_requested_types_); - NotifyDone(result); -} - -void DataTypeManagerImpl::StopImpl() { - state_ = STOPPING; - - // Invalidate weak pointer to drop download callbacks. - weak_ptr_factory_.InvalidateWeakPtrs(); - - // Stop all data types. This may trigger association callback but the - // callback will do nothing because state is set to STOPPING above. - model_association_manager_.Stop(); - - state_ = STOPPED; -} - -void DataTypeManagerImpl::NotifyStart() { - observer_->OnConfigureStart(); -} - -void DataTypeManagerImpl::NotifyDone(const ConfigureResult& raw_result) { - catch_up_in_progress_ = false; - - AddToConfigureTime(); - - ConfigureResult result = raw_result; - result.data_type_status_table = data_type_status_table_; - - DVLOG(1) << "Total time spent configuring: " - << configure_time_delta_.InSecondsF() << "s"; - switch (result.status) { - case DataTypeManager::OK: - DVLOG(1) << "NotifyDone called with result: OK"; - UMA_HISTOGRAM_LONG_TIMES("Sync.ConfigureTime_Long.OK", - configure_time_delta_); - if (debug_info_listener_.IsInitialized() && - !configuration_stats_.empty()) { - debug_info_listener_.Call( - FROM_HERE, - &syncer::DataTypeDebugInfoListener::OnDataTypeConfigureComplete, - configuration_stats_); - } - configuration_stats_.clear(); - break; - case DataTypeManager::ABORTED: - DVLOG(1) << "NotifyDone called with result: ABORTED"; - UMA_HISTOGRAM_LONG_TIMES("Sync.ConfigureTime_Long.ABORTED", - configure_time_delta_); - break; - case DataTypeManager::UNRECOVERABLE_ERROR: - DVLOG(1) << "NotifyDone called with result: UNRECOVERABLE_ERROR"; - UMA_HISTOGRAM_LONG_TIMES("Sync.ConfigureTime_Long.UNRECOVERABLE_ERROR", - configure_time_delta_); - break; - case DataTypeManager::UNKNOWN: - NOTREACHED(); - break; - } - observer_->OnConfigureDone(result); -} - -DataTypeManager::State DataTypeManagerImpl::state() const { - return state_; -} - -void DataTypeManagerImpl::AddToConfigureTime() { - DCHECK(!last_restart_time_.is_null()); - configure_time_delta_ += (base::Time::Now() - last_restart_time_); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/data_type_manager_impl.h b/components/sync_driver/data_type_manager_impl.h deleted file mode 100644 index 781d4f3..0000000 --- a/components/sync_driver/data_type_manager_impl.h +++ /dev/null
@@ -1,243 +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 COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_IMPL_H__ -#define COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_IMPL_H__ - -#include "components/sync_driver/data_type_manager.h" - -#include <map> -#include <queue> -#include <vector> - -#include "base/callback_forward.h" -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/time/time.h" -#include "components/sync_driver/backend_data_type_configurer.h" -#include "components/sync_driver/model_association_manager.h" - -namespace syncer { -struct DataTypeConfigurationStats; -class DataTypeDebugInfoListener; -template <typename T> class WeakHandle; -} - -namespace sync_driver { - -class DataTypeController; -class DataTypeEncryptionHandler; -class DataTypeManagerObserver; - -// List of data types grouped by priority and ordered from high priority to -// low priority. -typedef std::queue<syncer::ModelTypeSet> TypeSetPriorityList; - -class DataTypeManagerImpl : public DataTypeManager, - public ModelAssociationManagerDelegate { - public: - DataTypeManagerImpl( - const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& - debug_info_listener, - const DataTypeController::TypeMap* controllers, - const DataTypeEncryptionHandler* encryption_handler, - BackendDataTypeConfigurer* configurer, - DataTypeManagerObserver* observer); - ~DataTypeManagerImpl() override; - - // DataTypeManager interface. - void Configure(syncer::ModelTypeSet desired_types, - syncer::ConfigureReason reason) override; - void ReenableType(syncer::ModelType type) override; - void ResetDataTypeErrors() override; - - // Needed only for backend migration. - void PurgeForMigration(syncer::ModelTypeSet undesired_types, - syncer::ConfigureReason reason) override; - - void Stop() override; - State state() const override; - - // |ModelAssociationManagerDelegate| implementation. - void OnAllDataTypesReadyForConfigure() override; - void OnSingleDataTypeAssociationDone( - syncer::ModelType type, - const syncer::DataTypeAssociationStats& association_stats) override; - void OnModelAssociationDone( - const DataTypeManager::ConfigureResult& result) override; - void OnSingleDataTypeWillStop(syncer::ModelType type, - const syncer::SyncError& error) override; - - // Used by unit tests. TODO(sync) : This would go away if we made - // this class be able to do Dependency injection. crbug.com/129212. - ModelAssociationManager* GetModelAssociationManagerForTesting() { - return &model_association_manager_; - } - - private: - // Helper enum for identifying which types within a priority group to - // associate. - enum AssociationGroup { - // Those types that were already downloaded and didn't have an error at - // configuration time. Corresponds with AssociationTypesInfo's - // |ready_types|. These types can start associating as soon as the - // ModelAssociationManager is not busy. - READY_AT_CONFIG, - // All other types, including first time sync types and those that have - // encountered an error. These types must wait until the syncer has done - // any db changes and/or downloads before associating. - UNREADY_AT_CONFIG, - }; - - friend class TestDataTypeManager; - - // Abort configuration and stop all data types due to configuration errors. - void Abort(ConfigureStatus status); - - // Returns the priority types (control + priority user types). - // Virtual for overriding during tests. - virtual syncer::ModelTypeSet GetPriorityTypes() const; - - // Divide |types| into sets by their priorities and return the sets from - // high priority to low priority. - TypeSetPriorityList PrioritizeTypes(const syncer::ModelTypeSet& types); - - // Post a task to reconfigure when no downloading or association are running. - void ProcessReconfigure(); - - void Restart(syncer::ConfigureReason reason); - void DownloadReady(syncer::ModelTypeSet types_to_download, - syncer::ModelTypeSet first_sync_types, - syncer::ModelTypeSet failed_configuration_types); - - // Notification from the SBH that download failed due to a transient - // error and it will be retried. - void OnDownloadRetry(); - void NotifyStart(); - void NotifyDone(const ConfigureResult& result); - - // Add to |configure_time_delta_| the time since we last called - // Restart(). - void AddToConfigureTime(); - - void ConfigureImpl(syncer::ModelTypeSet desired_types, - syncer::ConfigureReason reason); - - // Calls data type controllers of requested types to register with backend. - void RegisterTypesWithBackend(); - - BackendDataTypeConfigurer::DataTypeConfigStateMap - BuildDataTypeConfigStateMap( - const syncer::ModelTypeSet& types_being_configured) const; - - // Start download of next set of types in |download_types_queue_| (if - // any exist, does nothing otherwise). - // Will kick off association of any new ready types. - void StartNextDownload(syncer::ModelTypeSet high_priority_types_before); - - // Start association of next batch of data types after association of - // previous batch finishes. |group| controls which set of types within - // an AssociationTypesInfo to associate. Does nothing if model associator - // is busy performing association. - void StartNextAssociation(AssociationGroup group); - - void StopImpl(); - - BackendDataTypeConfigurer* configurer_; - // Map of all data type controllers that are available for sync. - // This list is determined at startup by various command line flags. - const DataTypeController::TypeMap* controllers_; - State state_; - syncer::ModelTypeSet last_requested_types_; - - // Whether an attempt to reconfigure was made while we were busy configuring. - // The |last_requested_types_| will reflect the newest set of requested types. - bool needs_reconfigure_; - - // The reason for the last reconfigure attempt. Note: this will be set to a - // valid value only when |needs_reconfigure_| is set. - syncer::ConfigureReason last_configure_reason_; - - // The last time Restart() was called. - base::Time last_restart_time_; - - // The accumulated time spent between calls to Restart() and going - // to the DONE state. - base::TimeDelta configure_time_delta_; - - // Sync's datatype debug info listener, which we pass model association - // statistics to. - const syncer::WeakHandle<syncer::DataTypeDebugInfoListener> - debug_info_listener_; - - // The manager that handles the model association of the individual types. - ModelAssociationManager model_association_manager_; - - // DataTypeManager must have only one observer -- the ProfileSyncService that - // created it and manages its lifetime. - DataTypeManagerObserver* const observer_; - - // For querying failed data types (having unrecoverable error) when - // configuring backend. - DataTypeStatusTable data_type_status_table_; - - // Types waiting to be downloaded. - TypeSetPriorityList download_types_queue_; - - // Types waiting for association and related time tracking info. - struct AssociationTypesInfo { - AssociationTypesInfo(); - AssociationTypesInfo(const AssociationTypesInfo& other); - ~AssociationTypesInfo(); - - // Types to associate. - syncer::ModelTypeSet types; - // Types that have just been downloaded and are being associated for the - // first time. This includes types that had previously encountered an error - // and had to be purged/unapplied from the sync db. - // This is a subset of |types|. - syncer::ModelTypeSet first_sync_types; - // Types that were already ready for association at configuration time. - syncer::ModelTypeSet ready_types; - // Time at which |types| began downloading. - base::Time download_start_time; - // Time at which |types| finished downloading. - base::Time download_ready_time; - // Time at which the association for |read_types| began. - base::Time ready_association_request_time; - // Time at which the association for |types| began (not relevant to - // |ready_types|. - base::Time full_association_request_time; - // The set of types that are higher priority (and were therefore blocking) - // the association of |types|. - syncer::ModelTypeSet high_priority_types_before; - // The subset of |types| that were successfully configured. - syncer::ModelTypeSet configured_types; - }; - std::queue<AssociationTypesInfo> association_types_queue_; - - // The encryption handler lets the DataTypeManager know the state of sync - // datatype encryption. - const DataTypeEncryptionHandler* encryption_handler_; - - // Association and time stats of data type configuration. - std::vector<syncer::DataTypeConfigurationStats> configuration_stats_; - - // True iff we are in the process of catching up datatypes. - bool catch_up_in_progress_; - - // Configuration process is started when ModelAssociationManager notifies - // DataTypeManager that all types are ready for configure. - // This flag ensures that this process is started only once. - bool download_started_; - - base::WeakPtrFactory<DataTypeManagerImpl> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(DataTypeManagerImpl); -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_IMPL_H__
diff --git a/components/sync_driver/data_type_manager_impl_unittest.cc b/components/sync_driver/data_type_manager_impl_unittest.cc deleted file mode 100644 index e32db87..0000000 --- a/components/sync_driver/data_type_manager_impl_unittest.cc +++ /dev/null
@@ -1,1714 +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 "components/sync_driver/data_type_manager_impl.h" - -#include "base/compiler_specific.h" -#include "base/message_loop/message_loop.h" -#include "components/sync/base/model_type.h" -#include "components/sync/core/activation_context.h" -#include "components/sync/core/configure_reason.h" -#include "components/sync_driver/backend_data_type_configurer.h" -#include "components/sync_driver/data_type_encryption_handler.h" -#include "components/sync_driver/data_type_manager_observer.h" -#include "components/sync_driver/data_type_status_table.h" -#include "components/sync_driver/fake_data_type_controller.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sync_driver { - -using syncer::SyncError; -using syncer::ModelType; -using syncer::ModelTypeSet; -using syncer::ModelTypeToString; -using syncer::BOOKMARKS; -using syncer::APPS; -using syncer::PASSWORDS; -using syncer::PREFERENCES; -using syncer::NIGORI; - -namespace { - -// Helper for unioning with control types. -ModelTypeSet AddControlTypesTo(ModelTypeSet types) { - ModelTypeSet result = syncer::ControlTypes(); - result.PutAll(types); - return result; -} - -DataTypeStatusTable BuildStatusTable(ModelTypeSet crypto_errors, - ModelTypeSet association_errors, - ModelTypeSet unready_errors, - ModelTypeSet unrecoverable_errors) { - DataTypeStatusTable::TypeErrorMap error_map; - for (ModelTypeSet::Iterator iter = crypto_errors.First(); iter.Good(); - iter.Inc()) { - error_map[iter.Get()] = SyncError(FROM_HERE, - SyncError::CRYPTO_ERROR, - "crypto error expected", - iter.Get()); - } - for (ModelTypeSet::Iterator iter = association_errors.First(); iter.Good(); - iter.Inc()) { - error_map[iter.Get()] = SyncError(FROM_HERE, - SyncError::DATATYPE_ERROR, - "association error expected", - iter.Get()); - } - for (ModelTypeSet::Iterator iter = unready_errors.First(); iter.Good(); - iter.Inc()) { - error_map[iter.Get()] = SyncError(FROM_HERE, - SyncError::UNREADY_ERROR, - "unready error expected", - iter.Get()); - } - for (ModelTypeSet::Iterator iter = unrecoverable_errors.First(); iter.Good(); - iter.Inc()) { - error_map[iter.Get()] = SyncError(FROM_HERE, - SyncError::UNRECOVERABLE_ERROR, - "unrecoverable error expected", - iter.Get()); - } - DataTypeStatusTable status_table; - status_table.UpdateFailedDataTypes(error_map); - return status_table; -} - -// Fake BackendDataTypeConfigurer implementation that simply stores away the -// callback passed into ConfigureDataTypes. -class FakeBackendDataTypeConfigurer : public BackendDataTypeConfigurer { - public: - FakeBackendDataTypeConfigurer() : configure_call_count_(0) {} - ~FakeBackendDataTypeConfigurer() override {} - - syncer::ModelTypeSet ConfigureDataTypes( - syncer::ConfigureReason reason, - const DataTypeConfigStateMap& config_state_map, - const base::Callback<void(ModelTypeSet, ModelTypeSet)>& ready_task, - const base::Callback<void()>& retry_callback) override { - configure_call_count_++; - last_ready_task_ = ready_task; - - for (auto iter = expected_configure_types_.begin(); - iter != expected_configure_types_.end(); ++iter) { - if (!iter->second.Empty()) { - EXPECT_TRUE(iter->second == - GetDataTypesInState(iter->first, config_state_map)) - << "State " << iter->first << " : " - << ModelTypeSetToString(iter->second) << " v.s. " - << ModelTypeSetToString( - GetDataTypesInState(iter->first, config_state_map)); - } - } - return ready_types_; - } - - void ActivateDirectoryDataType(syncer::ModelType type, - syncer::ModelSafeGroup group, - ChangeProcessor* change_processor) override { - activated_types_.Put(type); - } - void DeactivateDirectoryDataType(syncer::ModelType type) override { - activated_types_.Remove(type); - } - - void ActivateNonBlockingDataType(syncer::ModelType type, - std::unique_ptr<syncer_v2::ActivationContext> - activation_context) override { - // TODO(stanisc): crbug.com/515962: Add test coverage. - } - - void DeactivateNonBlockingDataType(syncer::ModelType type) override { - // TODO(stanisc): crbug.com/515962: Add test coverage. - } - - base::Callback<void(ModelTypeSet, ModelTypeSet)> last_ready_task() const { - return last_ready_task_; - } - - void set_expected_configure_types(DataTypeConfigState config_state, - ModelTypeSet types) { - expected_configure_types_[config_state] = types; - } - - void set_ready_types(ModelTypeSet types) { - ready_types_ = types; - } - - const ModelTypeSet activated_types() { return activated_types_; } - - int configure_call_count() const { return configure_call_count_; } - - private: - base::Callback<void(ModelTypeSet, ModelTypeSet)> last_ready_task_; - std::map<DataTypeConfigState, ModelTypeSet> expected_configure_types_; - ModelTypeSet activated_types_; - ModelTypeSet ready_types_; - int configure_call_count_; -}; - -// DataTypeManagerObserver implementation. -class FakeDataTypeManagerObserver : public DataTypeManagerObserver { - public: - FakeDataTypeManagerObserver() { ResetExpectations(); } - ~FakeDataTypeManagerObserver() override { - EXPECT_FALSE(start_expected_); - DataTypeManager::ConfigureResult default_result; - EXPECT_EQ(done_expectation_.status, default_result.status); - EXPECT_TRUE( - done_expectation_.data_type_status_table.GetFailedTypes().Empty()); - } - - void ExpectStart() { - start_expected_ = true; - } - void ExpectDone(const DataTypeManager::ConfigureResult& result) { - done_expectation_ = result; - } - void ResetExpectations() { - start_expected_ = false; - done_expectation_ = DataTypeManager::ConfigureResult(); - } - - void OnConfigureDone( - const DataTypeManager::ConfigureResult& result) override { - EXPECT_EQ(done_expectation_.status, result.status); - DataTypeStatusTable::TypeErrorMap errors = - result.data_type_status_table.GetAllErrors(); - DataTypeStatusTable::TypeErrorMap expected_errors = - done_expectation_.data_type_status_table.GetAllErrors(); - ASSERT_EQ(expected_errors.size(), errors.size()); - for (DataTypeStatusTable::TypeErrorMap::const_iterator iter = - expected_errors.begin(); - iter != expected_errors.end(); - ++iter) { - ASSERT_TRUE(errors.find(iter->first) != errors.end()); - ASSERT_EQ(iter->second.error_type(), - errors.find(iter->first)->second.error_type()); - } - done_expectation_ = DataTypeManager::ConfigureResult(); - } - - void OnConfigureStart() override { - EXPECT_TRUE(start_expected_); - start_expected_ = false; - } - - private: - bool start_expected_ = true; - DataTypeManager::ConfigureResult done_expectation_; -}; - -class FakeDataTypeEncryptionHandler : public DataTypeEncryptionHandler { - public: - FakeDataTypeEncryptionHandler(); - ~FakeDataTypeEncryptionHandler() override; - - bool IsPassphraseRequired() const override; - ModelTypeSet GetEncryptedDataTypes() const override; - - void set_passphrase_required(bool passphrase_required) { - passphrase_required_ = passphrase_required; - } - void set_encrypted_types(ModelTypeSet encrypted_types) { - encrypted_types_ = encrypted_types; - } - private: - bool passphrase_required_; - ModelTypeSet encrypted_types_; -}; - -FakeDataTypeEncryptionHandler::FakeDataTypeEncryptionHandler() - : passphrase_required_(false) {} -FakeDataTypeEncryptionHandler::~FakeDataTypeEncryptionHandler() {} - -bool FakeDataTypeEncryptionHandler::IsPassphraseRequired() const { - return passphrase_required_; -} - -ModelTypeSet -FakeDataTypeEncryptionHandler::GetEncryptedDataTypes() const { - return encrypted_types_; -} - -} // namespace - -class TestDataTypeManager : public DataTypeManagerImpl { - public: - TestDataTypeManager( - const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& - debug_info_listener, - BackendDataTypeConfigurer* configurer, - const DataTypeController::TypeMap* controllers, - const DataTypeEncryptionHandler* encryption_handler, - DataTypeManagerObserver* observer) - : DataTypeManagerImpl(debug_info_listener, - controllers, - encryption_handler, - configurer, - observer), - custom_priority_types_(syncer::ControlTypes()) {} - - void set_priority_types(const ModelTypeSet& priority_types) { - custom_priority_types_ = priority_types; - } - - DataTypeManager::ConfigureResult configure_result() const { - return configure_result_; - } - - void OnModelAssociationDone( - const DataTypeManager::ConfigureResult& result) override { - configure_result_ = result; - DataTypeManagerImpl::OnModelAssociationDone(result); - } - - private: - ModelTypeSet GetPriorityTypes() const override { - return custom_priority_types_; - } - - ModelTypeSet custom_priority_types_; - DataTypeManager::ConfigureResult configure_result_; -}; - -// The actual test harness class, parametrized on nigori state (i.e., tests are -// run both configuring with nigori, and configuring without). -class SyncDataTypeManagerImplTest : public testing::Test { - public: - SyncDataTypeManagerImplTest() {} - - ~SyncDataTypeManagerImplTest() override {} - - protected: - void SetUp() override { - dtm_.reset( - new TestDataTypeManager( - syncer::WeakHandle<syncer::DataTypeDebugInfoListener>(), - &configurer_, - &controllers_, - &encryption_handler_, - &observer_)); - } - - void SetConfigureStartExpectation() { - observer_.ExpectStart(); - } - - void SetConfigureDoneExpectation(DataTypeManager::ConfigureStatus status, - const DataTypeStatusTable& status_table) { - DataTypeManager::ConfigureResult result; - result.status = status; - result.data_type_status_table = status_table; - observer_.ExpectDone(result); - } - - // Configure the given DTM with the given desired types. - void Configure(DataTypeManagerImpl* dtm, - const ModelTypeSet& desired_types) { - dtm->Configure(desired_types, syncer::CONFIGURE_REASON_RECONFIGURATION); - } - - // Finish downloading for the given DTM. Should be done only after - // a call to Configure(). - void FinishDownload(const DataTypeManager& dtm, - ModelTypeSet types_to_configure, - ModelTypeSet failed_download_types) { - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm.state()); - ASSERT_FALSE(configurer_.last_ready_task().is_null()); - configurer_.last_ready_task().Run( - syncer::Difference(types_to_configure, failed_download_types), - failed_download_types); - } - - // Adds a fake controller for the given type to |controllers_|. - // Should be called only before setting up the DTM. - void AddController(ModelType model_type) { - controllers_[model_type] = new FakeDataTypeController(model_type); - } - - // Gets the fake controller for the given type, which should have - // been previously added via AddController(). - scoped_refptr<FakeDataTypeController> GetController( - ModelType model_type) const { - DataTypeController::TypeMap::const_iterator it = - controllers_.find(model_type); - if (it == controllers_.end()) { - return NULL; - } - return make_scoped_refptr( - static_cast<FakeDataTypeController*>(it->second.get())); - } - - void FailEncryptionFor(ModelTypeSet encrypted_types) { - encryption_handler_.set_passphrase_required(true); - encryption_handler_.set_encrypted_types(encrypted_types); - } - - base::MessageLoopForUI ui_loop_; - DataTypeController::TypeMap controllers_; - FakeBackendDataTypeConfigurer configurer_; - FakeDataTypeManagerObserver observer_; - std::unique_ptr<TestDataTypeManager> dtm_; - FakeDataTypeEncryptionHandler encryption_handler_; -}; - -// Set up a DTM with no controllers, configure it, finish downloading, -// and then stop it. -TEST_F(SyncDataTypeManagerImplTest, NoControllers) { - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - - Configure(dtm_.get(), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - - dtm_->Stop(); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); -} - -// Set up a DTM with a single controller, configure it, finish -// downloading, finish starting the controller, and then stop the DTM. -TEST_F(SyncDataTypeManagerImplTest, ConfigureOne) { - AddController(BOOKMARKS); - - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - EXPECT_EQ(1U, configurer_.activated_types().Size()); - - dtm_->Stop(); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); - EXPECT_TRUE(configurer_.activated_types().Empty()); -} - -// Set up a DTM with a single controller, configure it, but stop it -// before finishing the download. It should still be safe to run the -// download callback even after the DTM is stopped and destroyed. -TEST_F(SyncDataTypeManagerImplTest, ConfigureOneStopWhileDownloadPending) { - AddController(BOOKMARKS); - - { - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::ABORTED, - DataTypeStatusTable()); - - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - dtm_->Stop(); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); - } - - configurer_.last_ready_task().Run(ModelTypeSet(BOOKMARKS), ModelTypeSet()); - EXPECT_TRUE(configurer_.activated_types().Empty()); -} - -// Set up a DTM with a single controller, configure it, finish -// downloading, but stop the DTM before the controller finishes -// starting up. It should still be safe to finish starting up the -// controller even after the DTM is stopped and destroyed. -TEST_F(SyncDataTypeManagerImplTest, ConfigureOneStopWhileStartingModel) { - AddController(BOOKMARKS); - - { - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::ABORTED, - DataTypeStatusTable()); - - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - dtm_->Stop(); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); - dtm_.reset(); - } - - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_TRUE(configurer_.activated_types().Empty()); -} - -// Set up a DTM with a single controller, configure it, finish -// downloading, start the controller's model, but stop the DTM before -// the controller finishes starting up. It should still be safe to -// finish starting up the controller even after the DTM is stopped and -// destroyed. -TEST_F(SyncDataTypeManagerImplTest, ConfigureOneStopWhileAssociating) { - AddController(BOOKMARKS); - - { - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::ABORTED, - DataTypeStatusTable()); - - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - EXPECT_TRUE(configurer_.activated_types().Empty()); - - dtm_->Stop(); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); - dtm_.reset(); - } - - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_TRUE(configurer_.activated_types().Empty()); -} - -// Set up a DTM with a single controller. Then: -// -// 1) Configure. -// 2) Finish the download for step 1. -// 3) Finish starting the controller with the NEEDS_CRYPTO status. -// 4) Complete download for the reconfiguration without the controller. -// 5) Stop the DTM. -TEST_F(SyncDataTypeManagerImplTest, OneWaitingForCrypto) { - AddController(PASSWORDS); - - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, - BuildStatusTable(ModelTypeSet(PASSWORDS), - ModelTypeSet(), - ModelTypeSet(), - ModelTypeSet())); - - const ModelTypeSet types(PASSWORDS); - dtm_->set_priority_types(AddControlTypesTo(types)); - - // Step 1. - Configure(dtm_.get(), types); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 2. - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 3. - FailEncryptionFor(types); - GetController(PASSWORDS)->FinishStart(DataTypeController::NEEDS_CRYPTO); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 4. - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - - // Step 5. - dtm_->Stop(); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); -} - -// Set up a DTM with two controllers. Then: -// -// 1) Configure with first controller. -// 2) Finish the download for step 1. -// 3) Finish starting the first controller. -// 4) Configure with both controllers. -// 5) Finish the download for step 4. -// 6) Finish starting the second controller. -// 7) Stop the DTM. -TEST_F(SyncDataTypeManagerImplTest, ConfigureOneThenBoth) { - AddController(BOOKMARKS); - AddController(PREFERENCES); - - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - - // Step 1. - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 2. - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 3. - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - - observer_.ResetExpectations(); - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - - // Step 4. - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 5. - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 6. - GetController(PREFERENCES)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - EXPECT_EQ(2U, configurer_.activated_types().Size()); - - // Step 7. - dtm_->Stop(); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); - EXPECT_TRUE(configurer_.activated_types().Empty()); -} - -// Set up a DTM with two controllers. Then: -// -// 1) Configure with first controller. -// 2) Finish the download for step 1. -// 3) Finish starting the first controller. -// 4) Configure with second controller. -// 5) Finish the download for step 4. -// 6) Finish starting the second controller. -// 7) Stop the DTM. -TEST_F(SyncDataTypeManagerImplTest, ConfigureOneThenSwitch) { - AddController(BOOKMARKS); - AddController(PREFERENCES); - - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - - // Step 1. - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 2. - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 3. - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - - observer_.ResetExpectations(); - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - - // Step 4. - Configure(dtm_.get(), ModelTypeSet(PREFERENCES)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 5. - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 6. - GetController(PREFERENCES)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - EXPECT_EQ(1U, configurer_.activated_types().Size()); - - // Step 7. - dtm_->Stop(); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); - EXPECT_TRUE(configurer_.activated_types().Empty()); -} - -// Set up a DTM with two controllers. Then: -// -// 1) Configure with first controller. -// 2) Finish the download for step 1. -// 3) Configure with both controllers. -// 4) Finish starting the first controller. -// 5) Finish the download for step 3. -// 6) Finish starting the second controller. -// 7) Stop the DTM. -TEST_F(SyncDataTypeManagerImplTest, ConfigureWhileOneInFlight) { - AddController(BOOKMARKS); - AddController(PREFERENCES); - - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - - // Step 1. - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 2. - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 3. - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 4. - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 5. - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 6. - GetController(PREFERENCES)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - EXPECT_EQ(2U, configurer_.activated_types().Size()); - - // Step 7. - dtm_->Stop(); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); - EXPECT_TRUE(configurer_.activated_types().Empty()); -} - -// Set up a DTM with one controller. Then configure, finish -// downloading, and start the controller with an unrecoverable error. -// The unrecoverable error should cause the DTM to stop. -TEST_F(SyncDataTypeManagerImplTest, OneFailingController) { - AddController(BOOKMARKS); - - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::UNRECOVERABLE_ERROR, - BuildStatusTable(ModelTypeSet(), - ModelTypeSet(), - ModelTypeSet(), - ModelTypeSet(BOOKMARKS))); - - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - EXPECT_TRUE(configurer_.activated_types().Empty()); - - GetController(BOOKMARKS)->FinishStart( - DataTypeController::UNRECOVERABLE_ERROR); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); - EXPECT_TRUE(configurer_.activated_types().Empty()); -} - -// Set up a DTM with two controllers. Then: -// -// 1) Configure with both controllers. -// 2) Finish the download for step 1. -// 3) Finish starting the first controller successfully. -// 4) Finish starting the second controller with an unrecoverable error. -// -// The failure from step 4 should cause the DTM to stop. -TEST_F(SyncDataTypeManagerImplTest, SecondControllerFails) { - AddController(BOOKMARKS); - AddController(PREFERENCES); - - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::UNRECOVERABLE_ERROR, - BuildStatusTable(ModelTypeSet(), - ModelTypeSet(), - ModelTypeSet(), - ModelTypeSet(PREFERENCES))); - - // Step 1. - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 2. - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 3. - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 4. - GetController(PREFERENCES)->FinishStart( - DataTypeController::UNRECOVERABLE_ERROR); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); -} - -// Set up a DTM with two controllers. Then: -// -// 1) Configure with both controllers. -// 2) Finish the download for step 1. -// 3) Finish starting the first controller successfully. -// 4) Finish starting the second controller with an association failure. -// 5) Finish the purge/reconfigure without the failed type. -// 6) Stop the DTM. -// -// The association failure from step 3 should be ignored. -// -// TODO(akalin): Check that the data type that failed association is -// recorded in the CONFIGURE_DONE notification. -TEST_F(SyncDataTypeManagerImplTest, OneControllerFailsAssociation) { - AddController(BOOKMARKS); - AddController(PREFERENCES); - - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, - BuildStatusTable(ModelTypeSet(), - ModelTypeSet(PREFERENCES), - ModelTypeSet(), - ModelTypeSet())); - - // Step 1. - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 2. - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 3. - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 4. - GetController(PREFERENCES)->FinishStart( - DataTypeController::ASSOCIATION_FAILED); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 5. - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - EXPECT_EQ(1U, configurer_.activated_types().Size()); - - // Step 6. - dtm_->Stop(); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); - EXPECT_TRUE(configurer_.activated_types().Empty()); -} - -// Set up a DTM with two controllers. Then: -// -// 1) Configure with first controller. -// 2) Configure with both controllers. -// 3) Finish the download for step 1. -// 4) Finish the download for step 2. -// 5) Finish starting both controllers. -// 6) Stop the DTM. -TEST_F(SyncDataTypeManagerImplTest, ConfigureWhileDownloadPending) { - AddController(BOOKMARKS); - AddController(PREFERENCES); - - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - - // Step 1. - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 2. - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 3. - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 4. - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 5. - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - GetController(PREFERENCES)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - - // Step 6. - dtm_->Stop(); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); -} - -// Set up a DTM with two controllers. Then: -// -// 1) Configure with first controller. -// 2) Configure with both controllers. -// 3) Finish the download for step 1 with a failed data type. -// 4) Finish the download for step 2 successfully. -// 5) Finish starting both controllers. -// 6) Stop the DTM. -// -// The failure from step 3 should be ignored since there's a -// reconfigure pending from step 2. -TEST_F(SyncDataTypeManagerImplTest, ConfigureWhileDownloadPendingWithFailure) { - AddController(BOOKMARKS); - AddController(PREFERENCES); - - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - - // Step 1. - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 2. - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 3. - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 4. - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Step 5. - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - GetController(PREFERENCES)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - - // Step 6. - dtm_->Stop(); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); -} - -// Tests a Purge then Configure. This is similar to the sequence of -// operations that would be invoked by the BackendMigrator. -TEST_F(SyncDataTypeManagerImplTest, MigrateAll) { - AddController(BOOKMARKS); - dtm_->set_priority_types(AddControlTypesTo(ModelTypeSet(BOOKMARKS))); - - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - - // Initial setup. - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - - // We've now configured bookmarks and (implicitly) the control types. - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - observer_.ResetExpectations(); - - // Pretend we were told to migrate all types. - ModelTypeSet to_migrate; - to_migrate.Put(BOOKMARKS); - to_migrate.PutAll(syncer::ControlTypes()); - - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - dtm_->PurgeForMigration(to_migrate, - syncer::CONFIGURE_REASON_MIGRATION); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // The DTM will call ConfigureDataTypes(), even though it is unnecessary. - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - observer_.ResetExpectations(); - - // Re-enable the migrated types. - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - Configure(dtm_.get(), to_migrate); - FinishDownload(*dtm_, to_migrate, ModelTypeSet()); - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); -} - -// Test receipt of a Configure request while a purge is in flight. -TEST_F(SyncDataTypeManagerImplTest, ConfigureDuringPurge) { - AddController(BOOKMARKS); - AddController(PREFERENCES); - - // Initial configure. - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - observer_.ResetExpectations(); - - // Purge the Nigori type. - SetConfigureStartExpectation(); - dtm_->PurgeForMigration(ModelTypeSet(NIGORI), - syncer::CONFIGURE_REASON_MIGRATION); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - observer_.ResetExpectations(); - - // Before the backend configuration completes, ask for a different - // set of types. This request asks for - // - BOOKMARKS: which is redundant because it was already enabled, - // - PREFERENCES: which is new and will need to be downloaded, and - // - NIGORI: (added implicitly because it is a control type) which - // the DTM is part-way through purging. - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Invoke the callback we've been waiting for since we asked to purge NIGORI. - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - observer_.ResetExpectations(); - - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Now invoke the callback for the second configure request. - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PREFERENCES), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Start the preferences controller. We don't need to start controller for - // the NIGORI because it has none. We don't need to start the controller for - // the BOOKMARKS because it was never stopped. - GetController(PREFERENCES)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); -} - -TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfiguration) { - AddController(BOOKMARKS); - AddController(PREFERENCES); - - dtm_->set_priority_types( - AddControlTypesTo(ModelTypeSet(PREFERENCES))); - - // Initial configure. - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - - // Initially only PREFERENCES is configured. - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, - AddControlTypesTo(ModelTypeSet(PREFERENCES))); - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // BOOKMARKS is configured after download of PREFERENCES finishes. - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, ModelTypeSet(BOOKMARKS)); - FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - GetController(PREFERENCES)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); -} - -TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfigurationReconfigure) { - AddController(BOOKMARKS); - AddController(PREFERENCES); - AddController(APPS); - - dtm_->set_priority_types( - AddControlTypesTo(ModelTypeSet(PREFERENCES))); - - // Initial configure. - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - - // Reconfigure while associating PREFERENCES and downloading BOOKMARKS. - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, - AddControlTypesTo(ModelTypeSet(PREFERENCES))); - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, ModelTypeSet(BOOKMARKS)); - FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Enable syncing for APPS. - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES, APPS)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Reconfiguration starts after downloading and association of previous - // types finish. - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, - AddControlTypesTo(ModelTypeSet(PREFERENCES))); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - GetController(PREFERENCES)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, - ModelTypeSet(BOOKMARKS, APPS)); - FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, APPS), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Skip calling FinishStart() for PREFENCES because it's already started in - // first configuration. - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - GetController(APPS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); -} - -TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfigurationStop) { - AddController(BOOKMARKS); - AddController(PREFERENCES); - - dtm_->set_priority_types( - AddControlTypesTo(ModelTypeSet(PREFERENCES))); - - // Initial configure. - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::ABORTED, DataTypeStatusTable()); - - // Initially only PREFERENCES is configured. - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, - AddControlTypesTo(ModelTypeSet(PREFERENCES))); - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // BOOKMARKS is configured after download of PREFERENCES finishes. - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, ModelTypeSet(BOOKMARKS)); - FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // PREFERENCES controller is associating while BOOKMARKS is downloading. - EXPECT_EQ(DataTypeController::ASSOCIATING, - GetController(PREFERENCES)->state()); - EXPECT_EQ(DataTypeController::MODEL_LOADED, - GetController(BOOKMARKS)->state()); - - dtm_->Stop(); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); - EXPECT_EQ(DataTypeController::NOT_RUNNING, - GetController(PREFERENCES)->state()); - EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); -} - -TEST_F(SyncDataTypeManagerImplTest, PrioritizedConfigurationDownloadError) { - AddController(BOOKMARKS); - AddController(PREFERENCES); - - dtm_->set_priority_types( - AddControlTypesTo(ModelTypeSet(PREFERENCES))); - - // Initial configure. Bookmarks will fail to associate due to the download - // failure. - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, - BuildStatusTable(ModelTypeSet(), - ModelTypeSet(BOOKMARKS), - ModelTypeSet(), - ModelTypeSet())); - - // Initially only PREFERENCES is configured. - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, - AddControlTypesTo(ModelTypeSet(PREFERENCES))); - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // BOOKMARKS is configured after download of PREFERENCES finishes. - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, ModelTypeSet(BOOKMARKS)); - FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // PREFERENCES controller is associating while BOOKMARKS is downloading. - EXPECT_EQ(DataTypeController::ASSOCIATING, - GetController(PREFERENCES)->state()); - EXPECT_EQ(DataTypeController::MODEL_LOADED, - GetController(BOOKMARKS)->state()); - - // Make BOOKMARKS download fail. Preferences is still associating. - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet(BOOKMARKS)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - EXPECT_EQ(DataTypeController::ASSOCIATING, - GetController(PREFERENCES)->state()); - - // Finish association of PREFERENCES. This will trigger a reconfiguration to - // disable bookmarks. - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, - AddControlTypesTo(ModelTypeSet(PREFERENCES))); - GetController(PREFERENCES)->FinishStart(DataTypeController::OK); - FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - EXPECT_EQ(DataTypeController::RUNNING, - GetController(PREFERENCES)->state()); - EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); -} - -TEST_F(SyncDataTypeManagerImplTest, HighPriorityAssociationFailure) { - AddController(PREFERENCES); // Will fail. - AddController(BOOKMARKS); // Will succeed. - - dtm_->set_priority_types( - AddControlTypesTo(ModelTypeSet(PREFERENCES))); - - // Initial configure. - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, - BuildStatusTable(ModelTypeSet(), - ModelTypeSet(PREFERENCES), - ModelTypeSet(), - ModelTypeSet())); - - // Initially only PREFERENCES is configured. - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, - AddControlTypesTo(ModelTypeSet(PREFERENCES))); - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // BOOKMARKS is configured after download of PREFERENCES finishes. - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, ModelTypeSet(BOOKMARKS)); - FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // PREFERENCES controller is associating while BOOKMARKS is downloading. - EXPECT_EQ(DataTypeController::ASSOCIATING, - GetController(PREFERENCES)->state()); - EXPECT_EQ(DataTypeController::MODEL_LOADED, - GetController(BOOKMARKS)->state()); - - // Make PREFERENCES association fail. - GetController(PREFERENCES)->FinishStart( - DataTypeController::ASSOCIATION_FAILED); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Reconfigure without PREFERENCES after the BOOKMARKS download completes, - // then reconfigure with BOOKMARKS. - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, syncer::ControlTypes()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, ModelTypeSet(BOOKMARKS)); - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - - // Reconfigure with BOOKMARKS. - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - EXPECT_EQ(DataTypeController::ASSOCIATING, - GetController(BOOKMARKS)->state()); - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - EXPECT_EQ(DataTypeController::NOT_RUNNING, - GetController(PREFERENCES)->state()); - EXPECT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state()); -} - -TEST_F(SyncDataTypeManagerImplTest, LowPriorityAssociationFailure) { - AddController(PREFERENCES); // Will succeed. - AddController(BOOKMARKS); // Will fail. - - dtm_->set_priority_types( - AddControlTypesTo(ModelTypeSet(PREFERENCES))); - - // Initial configure. - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, - BuildStatusTable(ModelTypeSet(), - ModelTypeSet(BOOKMARKS), - ModelTypeSet(), - ModelTypeSet())); - - // Initially only PREFERENCES is configured. - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, - AddControlTypesTo(ModelTypeSet(PREFERENCES))); - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // BOOKMARKS is configured after download of PREFERENCES finishes. - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, ModelTypeSet(BOOKMARKS)); - FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // PREFERENCES controller is associating while BOOKMARKS is downloading. - EXPECT_EQ(DataTypeController::ASSOCIATING, - GetController(PREFERENCES)->state()); - EXPECT_EQ(DataTypeController::MODEL_LOADED, - GetController(BOOKMARKS)->state()); - - // BOOKMARKS finishes downloading and PREFERENCES finishes associating. - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - GetController(PREFERENCES)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeController::RUNNING, GetController(PREFERENCES)->state()); - - // Make BOOKMARKS association fail, which triggers reconfigure with only - // PREFERENCES. - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, - AddControlTypesTo(ModelTypeSet(PREFERENCES))); - GetController(BOOKMARKS)->FinishStart(DataTypeController::ASSOCIATION_FAILED); - EXPECT_EQ(DataTypeController::NOT_RUNNING, - GetController(BOOKMARKS)->state()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Finish configuration with only PREFERENCES. - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - EXPECT_EQ(DataTypeController::RUNNING, GetController(PREFERENCES)->state()); - EXPECT_EQ(DataTypeController::NOT_RUNNING, - GetController(BOOKMARKS)->state()); -} - -TEST_F(SyncDataTypeManagerImplTest, FilterDesiredTypes) { - AddController(BOOKMARKS); - - ModelTypeSet types(BOOKMARKS, APPS); - dtm_->set_priority_types(AddControlTypesTo(types)); - - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - - ModelTypeSet expected_types = syncer::ControlTypes(); - expected_types.Put(BOOKMARKS); - // APPS is filtered out because there's no controller for it. - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_ACTIVE, expected_types); - Configure(dtm_.get(), types); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - - dtm_->Stop(); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); -} - -TEST_F(SyncDataTypeManagerImplTest, ReenableAfterDataTypeError) { - AddController(PREFERENCES); // Will succeed. - AddController(BOOKMARKS); // Will be disabled due to datatype error. - - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, - BuildStatusTable(ModelTypeSet(), - ModelTypeSet(BOOKMARKS), - ModelTypeSet(), - ModelTypeSet())); - - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS, PREFERENCES)); - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(PREFERENCES, BOOKMARKS), ModelTypeSet()); - GetController(PREFERENCES)->FinishStart(DataTypeController::OK); - GetController(BOOKMARKS) - ->FinishStart(DataTypeController::ASSOCIATION_FAILED); - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); // Reconfig for error. - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); // Reconfig for error. - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - EXPECT_EQ(DataTypeController::RUNNING, GetController(PREFERENCES)->state()); - EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); - - observer_.ResetExpectations(); - - // Re-enable bookmarks. - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - dtm_->ReenableType(syncer::BOOKMARKS); - - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - EXPECT_EQ(DataTypeController::RUNNING, GetController(PREFERENCES)->state()); - EXPECT_EQ(DataTypeController::RUNNING, GetController(BOOKMARKS)->state()); - - // Should do nothing. - dtm_->ReenableType(syncer::BOOKMARKS); -} - -TEST_F(SyncDataTypeManagerImplTest, UnreadyType) { - AddController(BOOKMARKS); - GetController(BOOKMARKS)->SetReadyForStart(false); - - // Bookmarks is never started due to being unready. - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, - BuildStatusTable(ModelTypeSet(), - ModelTypeSet(), - ModelTypeSet(BOOKMARKS), - ModelTypeSet())); - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - EXPECT_EQ(0U, configurer_.activated_types().Size()); - observer_.ResetExpectations(); - - // Bookmarks should start normally now. - GetController(BOOKMARKS)->SetReadyForStart(true); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - dtm_->ReenableType(BOOKMARKS); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - EXPECT_EQ(1U, configurer_.activated_types().Size()); - - // Should do nothing. - observer_.ResetExpectations(); - dtm_->ReenableType(BOOKMARKS); - - dtm_->Stop(); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); - EXPECT_TRUE(configurer_.activated_types().Empty()); -} - -TEST_F(SyncDataTypeManagerImplTest, ModelLoadError) { - AddController(BOOKMARKS); - GetController(BOOKMARKS)->SetModelLoadError(syncer::SyncError( - FROM_HERE, SyncError::DATATYPE_ERROR, "load error", BOOKMARKS)); - - // Bookmarks is never started due to hitting a model load error. - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, - BuildStatusTable(ModelTypeSet(), - ModelTypeSet(BOOKMARKS), - ModelTypeSet(), - ModelTypeSet())); - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); - - EXPECT_EQ(0U, configurer_.activated_types().Size()); -} - - -TEST_F(SyncDataTypeManagerImplTest, ErrorBeforeAssociation) { - AddController(BOOKMARKS); - - // Bookmarks is never started due to hitting a datatype error while the DTM - // is still downloading types. - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, - BuildStatusTable(ModelTypeSet(), - ModelTypeSet(BOOKMARKS), - ModelTypeSet(), - ModelTypeSet())); - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - GetController(BOOKMARKS)->OnSingleDataTypeUnrecoverableError( - syncer::SyncError(FROM_HERE, - SyncError::DATATYPE_ERROR, - "bookmarks error", - BOOKMARKS)); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); // Reconfig for error. - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); - - EXPECT_EQ(0U, configurer_.activated_types().Size()); -} - -TEST_F(SyncDataTypeManagerImplTest, AssociationNeverCompletes) { - AddController(BOOKMARKS); - - // Bookmarks times out during association and so it's never started. - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, - BuildStatusTable(ModelTypeSet(), - ModelTypeSet(BOOKMARKS), - ModelTypeSet(), - ModelTypeSet())); - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); - - GetController(BOOKMARKS)->SetDelayModelLoad(); - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Simulate timeout by firing the timer. - dtm_->GetModelAssociationManagerForTesting() - ->GetTimerForTesting() - ->user_task() - .Run(); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - EXPECT_EQ(DataTypeController::NOT_RUNNING, GetController(BOOKMARKS)->state()); - - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - EXPECT_EQ(0U, configurer_.activated_types().Size()); -} - -// Test that sync configures properly if all low priority types are ready. -TEST_F(SyncDataTypeManagerImplTest, AllLowPriorityTypesReady) { - AddController(PREFERENCES); - AddController(BOOKMARKS); - - dtm_->set_priority_types( - AddControlTypesTo(ModelTypeSet(PREFERENCES))); - - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - - Configure(dtm_.get(), ModelTypeSet(PREFERENCES, BOOKMARKS)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - configurer_.set_ready_types(ModelTypeSet(BOOKMARKS)); - FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); - - // Association of Bookmarks can't happen until higher priority types are - // finished. - EXPECT_EQ(DataTypeController::ASSOCIATING, - GetController(PREFERENCES)->state()); - EXPECT_EQ(DataTypeController::MODEL_LOADED, - GetController(BOOKMARKS)->state()); - - // Because Bookmarks are a ready type, once Preference finishes, Bookmarks - // can start associating immediately (even before the - // BackendDataTypeConfigurer calls back). - GetController(PREFERENCES)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeController::ASSOCIATING, - GetController(BOOKMARKS)->state()); - - // Once the association finishes, the DTM should still be waiting for the - // Sync configurer to call back. - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeController::RUNNING, - GetController(BOOKMARKS)->state()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Finishing the download should complete the configuration. - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - EXPECT_EQ(DataTypeController::RUNNING, - GetController(BOOKMARKS)->state()); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - EXPECT_EQ(2U, configurer_.activated_types().Size()); - - dtm_->Stop(); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); - EXPECT_TRUE(configurer_.activated_types().Empty()); -} - -// Test that sync configures properly if all high priority types are ready. -TEST_F(SyncDataTypeManagerImplTest, AllHighPriorityTypesReady) { - AddController(PREFERENCES); - AddController(BOOKMARKS); - - dtm_->set_priority_types( - AddControlTypesTo(ModelTypeSet(PREFERENCES))); - - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - - configurer_.set_ready_types(ModelTypeSet(PREFERENCES)); - Configure(dtm_.get(), ModelTypeSet(PREFERENCES, BOOKMARKS)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Association of Bookmarks can't happen until higher priority types are - // finished, but Preferences should start associating immediately. - EXPECT_EQ(DataTypeController::ASSOCIATING, - GetController(PREFERENCES)->state()); - EXPECT_EQ(DataTypeController::MODEL_LOADED, - GetController(BOOKMARKS)->state()); - - // When Prefs finish associating, configuration should still be waiting for - // the high priority download to finish. - GetController(PREFERENCES)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeController::MODEL_LOADED, - GetController(BOOKMARKS)->state()); - - // Because Bookmarks aren't a ready type, they'll need to wait until the - // low priority download also finishes. - FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); - EXPECT_EQ(DataTypeController::MODEL_LOADED, - GetController(BOOKMARKS)->state()); - - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - EXPECT_EQ(DataTypeController::ASSOCIATING, - GetController(BOOKMARKS)->state()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Finishing the Bookmarks association ends the configuration. - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeController::RUNNING, - GetController(BOOKMARKS)->state()); - - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - EXPECT_EQ(2U, configurer_.activated_types().Size()); - - dtm_->Stop(); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); - EXPECT_TRUE(configurer_.activated_types().Empty()); -} - -// Test that sync configures properly if all types are ready. -TEST_F(SyncDataTypeManagerImplTest, AllTypesReady) { - AddController(PREFERENCES); - AddController(BOOKMARKS); - - dtm_->set_priority_types( - AddControlTypesTo(ModelTypeSet(PREFERENCES))); - - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - - configurer_.set_ready_types(ModelTypeSet(PREFERENCES)); - Configure(dtm_.get(), ModelTypeSet(PREFERENCES, BOOKMARKS)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Association of Bookmarks can't happen until higher priority types are - // finished, but Preferences should start associating immediately. - EXPECT_EQ(DataTypeController::ASSOCIATING, - GetController(PREFERENCES)->state()); - EXPECT_EQ(DataTypeController::MODEL_LOADED, - GetController(BOOKMARKS)->state()); - - // When Prefs finish associating, configuration should still be waiting for - // the high priority download to finish. - GetController(PREFERENCES)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeController::MODEL_LOADED, - GetController(BOOKMARKS)->state()); - - // Because Bookmarks are a ready type, it can start associating immediately - // after the high priority types finish downloading. - configurer_.set_ready_types(ModelTypeSet(BOOKMARKS)); - FinishDownload(*dtm_, ModelTypeSet(PREFERENCES), ModelTypeSet()); - EXPECT_EQ(DataTypeController::ASSOCIATING, - GetController(BOOKMARKS)->state()); - - // Finishing the Bookmarks association leaves the DTM waiting for the low - // priority download to finish. - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeController::RUNNING, - GetController(BOOKMARKS)->state()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Finishing the low priority download ends the configuration. - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - EXPECT_EQ(2U, configurer_.activated_types().Size()); - - dtm_->Stop(); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); - EXPECT_TRUE(configurer_.activated_types().Empty()); -} - -// Test that "catching up" type puts them in the CONFIGURE_CLEAN state. -TEST_F(SyncDataTypeManagerImplTest, CatchUpTypeAddedToConfigureClean) { - AddController(BOOKMARKS); - AddController(PASSWORDS); - - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_CLEAN, - AddControlTypesTo(ModelTypeSet(BOOKMARKS, PASSWORDS))); - - dtm_->Configure(ModelTypeSet(BOOKMARKS, PASSWORDS), - syncer::CONFIGURE_REASON_CATCH_UP); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PASSWORDS), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - EXPECT_EQ(1U, configurer_.activated_types().Size()); - GetController(PASSWORDS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - EXPECT_EQ(2U, configurer_.activated_types().Size()); - - dtm_->Stop(); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); - EXPECT_TRUE(configurer_.activated_types().Empty()); -} - -// Test that once we start a catch up cycle for a type, the type ends up in the -// clean state and DataTypeManager remains in catch up mode for subsequent -// overlapping cycles. -TEST_F(SyncDataTypeManagerImplTest, CatchUpMultipleConfigureCalls) { - AddController(BOOKMARKS); - AddController(PASSWORDS); - - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - - // Configure (catch up) with one type. - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_CLEAN, - AddControlTypesTo(ModelTypeSet(BOOKMARKS))); - dtm_->Configure(ModelTypeSet(BOOKMARKS), syncer::CONFIGURE_REASON_CATCH_UP); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - // Configure with both types before the first one completes. Both types should - // end up in CONFIGURE_CLEAN. - configurer_.set_expected_configure_types( - BackendDataTypeConfigurer::CONFIGURE_CLEAN, - AddControlTypesTo(ModelTypeSet(BOOKMARKS, PASSWORDS))); - dtm_->Configure(ModelTypeSet(BOOKMARKS, PASSWORDS), - syncer::CONFIGURE_REASON_RECONFIGURATION); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS, PASSWORDS), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - GetController(PASSWORDS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - - dtm_->Stop(); - EXPECT_EQ(DataTypeManager::STOPPED, dtm_->state()); -} - -// Test that DataTypeManagerImpl delays configuration until all datatypes for -// which ShouldLoadModelBeforeConfigure() returns true loaded their models. -TEST_F(SyncDataTypeManagerImplTest, DelayConfigureForUSSTypes) { - AddController(BOOKMARKS); - GetController(BOOKMARKS)->SetShouldLoadModelBeforeConfigure(true); - GetController(BOOKMARKS)->SetDelayModelLoad(); - - SetConfigureStartExpectation(); - SetConfigureDoneExpectation(DataTypeManager::OK, DataTypeStatusTable()); - - Configure(dtm_.get(), ModelTypeSet(BOOKMARKS)); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - // Bookmarks model isn't loaded yet and it is required to complete before - // call to configure. Ensure that configure wasn't called. - EXPECT_EQ(0, configurer_.configure_call_count()); - EXPECT_EQ(0, GetController(BOOKMARKS)->register_with_backend_call_count()); - - // Finishing model load should trigger configure. - GetController(BOOKMARKS)->SimulateModelLoadFinishing(); - EXPECT_EQ(1, configurer_.configure_call_count()); - EXPECT_EQ(1, GetController(BOOKMARKS)->register_with_backend_call_count()); - - FinishDownload(*dtm_, ModelTypeSet(), ModelTypeSet()); - FinishDownload(*dtm_, ModelTypeSet(BOOKMARKS), ModelTypeSet()); - EXPECT_EQ(DataTypeManager::CONFIGURING, dtm_->state()); - - GetController(BOOKMARKS)->FinishStart(DataTypeController::OK); - EXPECT_EQ(DataTypeManager::CONFIGURED, dtm_->state()); - EXPECT_EQ(1U, configurer_.activated_types().Size()); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/data_type_manager_mock.cc b/components/sync_driver/data_type_manager_mock.cc deleted file mode 100644 index c1ce5ca7..0000000 --- a/components/sync_driver/data_type_manager_mock.cc +++ /dev/null
@@ -1,16 +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 "base/location.h" -#include "components/sync_driver/data_type_manager_mock.h" - -namespace sync_driver { - -DataTypeManagerMock::DataTypeManagerMock() - : result_(OK, syncer::ModelTypeSet()) { -} - -DataTypeManagerMock::~DataTypeManagerMock() {} - -} // namespace sync_driver
diff --git a/components/sync_driver/data_type_manager_mock.h b/components/sync_driver/data_type_manager_mock.h deleted file mode 100644 index 11a37dbd..0000000 --- a/components/sync_driver/data_type_manager_mock.h +++ /dev/null
@@ -1,34 +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 COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_MOCK_H__ -#define COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_MOCK_H__ - -#include "components/sync/api/sync_error.h" -#include "components/sync_driver/data_type_manager.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace sync_driver { - -class DataTypeManagerMock : public DataTypeManager { - public: - DataTypeManagerMock(); - virtual ~DataTypeManagerMock(); - - MOCK_METHOD2(Configure, void(syncer::ModelTypeSet, syncer::ConfigureReason)); - MOCK_METHOD1(ReenableType, void(syncer::ModelType)); - MOCK_METHOD0(ResetDataTypeErrors, void()); - MOCK_METHOD2(PurgeForMigration, void(syncer::ModelTypeSet, - syncer::ConfigureReason)); - MOCK_METHOD0(Stop, void()); - MOCK_METHOD0(controllers, const DataTypeController::TypeMap&()); - MOCK_CONST_METHOD0(state, State()); - - private: - DataTypeManager::ConfigureResult result_; -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_MOCK_H__
diff --git a/components/sync_driver/data_type_manager_observer.h b/components/sync_driver/data_type_manager_observer.h deleted file mode 100644 index c5081d5..0000000 --- a/components/sync_driver/data_type_manager_observer.h +++ /dev/null
@@ -1,26 +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 COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_OBSERVER_H_ -#define COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_OBSERVER_H_ - -#include "components/sync_driver/data_type_manager.h" - -namespace sync_driver { - -// Various data type configuration events can be consumed by observing the -// DataTypeManager through this interface. -class DataTypeManagerObserver { - public: - virtual void OnConfigureDone( - const DataTypeManager::ConfigureResult& result) = 0; - virtual void OnConfigureStart() = 0; - - protected: - virtual ~DataTypeManagerObserver() { } -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_DATA_TYPE_MANAGER_OBSERVER_H_
diff --git a/components/sync_driver/data_type_status_table.cc b/components/sync_driver/data_type_status_table.cc deleted file mode 100644 index 666b7b4..0000000 --- a/components/sync_driver/data_type_status_table.cc +++ /dev/null
@@ -1,149 +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 "components/sync_driver/data_type_manager.h" -#include "components/sync_driver/data_type_status_table.h" - -namespace sync_driver { - -namespace { - -syncer::ModelTypeSet GetTypesFromErrorMap( - const DataTypeStatusTable::TypeErrorMap& errors) { - syncer::ModelTypeSet result; - for (DataTypeStatusTable::TypeErrorMap::const_iterator it = errors.begin(); - it != errors.end(); ++it) { - DCHECK(!result.Has(it->first)); - result.Put(it->first); - } - return result; -} - -} // namespace - -DataTypeStatusTable::DataTypeStatusTable() { -} - -DataTypeStatusTable::DataTypeStatusTable(const DataTypeStatusTable& other) = - default; - -DataTypeStatusTable::~DataTypeStatusTable() { -} - -void DataTypeStatusTable::UpdateFailedDataTypes(const TypeErrorMap& errors) { - DVLOG(1) << "Setting " << errors.size() << " new failed types."; - - for (TypeErrorMap::const_iterator iter = errors.begin(); iter != errors.end(); - ++iter) { - syncer::SyncError::ErrorType failure_type = iter->second.error_type(); - switch (failure_type) { - case syncer::SyncError::UNSET: - NOTREACHED(); - break; - case syncer::SyncError::UNRECOVERABLE_ERROR: - unrecoverable_errors_.insert(*iter); - break; - case syncer::SyncError::DATATYPE_ERROR: - case syncer::SyncError::DATATYPE_POLICY_ERROR: - data_type_errors_.insert(*iter); - break; - case syncer::SyncError::CRYPTO_ERROR: - crypto_errors_.insert(*iter); - break; - case syncer::SyncError::PERSISTENCE_ERROR: - persistence_errors_.insert(*iter); - break; - case syncer::SyncError::UNREADY_ERROR: - unready_errors_.insert(*iter); - break; - } - } -} - -void DataTypeStatusTable::Reset() { - DVLOG(1) << "Resetting data type errors."; - unrecoverable_errors_.clear(); - data_type_errors_.clear(); - crypto_errors_.clear(); - persistence_errors_.clear(); - unready_errors_.clear(); -} - -void DataTypeStatusTable::ResetCryptoErrors() { - crypto_errors_.clear(); -} - -void DataTypeStatusTable::ResetPersistenceErrorsFrom( - syncer::ModelTypeSet purged_types) { - for (syncer::ModelTypeSet::Iterator iter = purged_types.First(); iter.Good(); - iter.Inc()) { - persistence_errors_.erase(iter.Get()); - } -} - -bool DataTypeStatusTable::ResetDataTypeErrorFor(syncer::ModelType type) { - return data_type_errors_.erase(type) > 0; -} - -bool DataTypeStatusTable::ResetUnreadyErrorFor(syncer::ModelType type) { - return unready_errors_.erase(type) > 0; -} - -DataTypeStatusTable::TypeErrorMap DataTypeStatusTable::GetAllErrors() - const { - TypeErrorMap result; - result.insert(data_type_errors_.begin(), data_type_errors_.end()); - result.insert(crypto_errors_.begin(), crypto_errors_.end()); - result.insert(persistence_errors_.begin(), persistence_errors_.end()); - result.insert(unready_errors_.begin(), unready_errors_.end()); - result.insert(unrecoverable_errors_.begin(), unrecoverable_errors_.end()); - return result; -} - -syncer::ModelTypeSet DataTypeStatusTable::GetFailedTypes() const { - syncer::ModelTypeSet result = GetFatalErrorTypes(); - result.PutAll(GetCryptoErrorTypes()); - result.PutAll(GetUnreadyErrorTypes()); - return result; -} - -syncer::ModelTypeSet DataTypeStatusTable::GetFatalErrorTypes() - const { - syncer::ModelTypeSet result; - result.PutAll(GetTypesFromErrorMap(data_type_errors_)); - result.PutAll(GetTypesFromErrorMap(unrecoverable_errors_)); - return result; -} - -syncer::ModelTypeSet DataTypeStatusTable::GetCryptoErrorTypes() const { - syncer::ModelTypeSet result = GetTypesFromErrorMap(crypto_errors_); - return result; -} - -syncer::ModelTypeSet DataTypeStatusTable::GetPersistenceErrorTypes() const { - syncer::ModelTypeSet result = GetTypesFromErrorMap(persistence_errors_); - return result; -} - -syncer::ModelTypeSet DataTypeStatusTable::GetUnreadyErrorTypes() const { - syncer::ModelTypeSet result = GetTypesFromErrorMap(unready_errors_); - return result; -} - -syncer::ModelTypeSet DataTypeStatusTable::GetUnrecoverableErrorTypes() - const { - syncer::ModelTypeSet result = GetTypesFromErrorMap(unrecoverable_errors_); - return result; -} - -syncer::SyncError DataTypeStatusTable::GetUnrecoverableError() const { - // Just return the first one. It is assumed all the unrecoverable errors - // have the same cause. The others are just tracked to know which types - // were involved. - return (unrecoverable_errors_.empty() - ? syncer::SyncError() - : unrecoverable_errors_.begin()->second); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/data_type_status_table.h b/components/sync_driver/data_type_status_table.h deleted file mode 100644 index 4cb1005..0000000 --- a/components/sync_driver/data_type_status_table.h +++ /dev/null
@@ -1,98 +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 COMPONENTS_SYNC_DRIVER_DATA_TYPE_STATUS_TABLE_H_ -#define COMPONENTS_SYNC_DRIVER_DATA_TYPE_STATUS_TABLE_H_ - -#include <map> -#include <string> - -#include "components/sync_driver/data_type_manager.h" - -namespace sync_driver { - -// Class to keep track of data types that have encountered an error during sync. -class DataTypeStatusTable { - public: - typedef std::map<syncer::ModelType, syncer::SyncError> TypeErrorMap; - - DataTypeStatusTable(); - DataTypeStatusTable(const DataTypeStatusTable& other); - ~DataTypeStatusTable(); - - // Copy and assign welcome. - - // Update the failed datatypes. Types will be added to their corresponding - // error map based on their |error_type()|. - void UpdateFailedDataTypes(const TypeErrorMap& errors); - - // Resets the current set of data type errors. - void Reset(); - - // Resets the set of types with cryptographer errors. - void ResetCryptoErrors(); - - // Resets those persistence errors that intersect with |purged_types|. - void ResetPersistenceErrorsFrom(syncer::ModelTypeSet purged_types); - - // Removes |type| from the data_type_errors_ set. Returns true if the type - // was removed from the error set, false if the type did not have a data type - // error to begin with. - bool ResetDataTypeErrorFor(syncer::ModelType type); - - // Removes |type| from the unread_errors_ set. Returns true if the type - // was removed from the error set, false if the type did not have an unready - // error to begin with. - bool ResetUnreadyErrorFor(syncer::ModelType type); - - // Returns a list of all the errors this class has recorded. - TypeErrorMap GetAllErrors() const; - - // Returns all types with failure errors. This includes, fatal, crypto, and - // unready types.` - syncer::ModelTypeSet GetFailedTypes() const; - - // Returns the types that are failing due to unrecoverable or datatype errors. - syncer::ModelTypeSet GetFatalErrorTypes() const; - - // Returns the types that are failing due to cryptographer errors. - syncer::ModelTypeSet GetCryptoErrorTypes() const; - - // Returns the types that are failing due to persistence errors. - syncer::ModelTypeSet GetPersistenceErrorTypes() const; - - // Returns the types that cannot be configured due to not being ready. - syncer::ModelTypeSet GetUnreadyErrorTypes() const; - - // Returns the types that triggered the unrecoverable error. - syncer::ModelTypeSet GetUnrecoverableErrorTypes() const; - - // Returns the current unrecoverable error, if there is one. - syncer::SyncError GetUnrecoverableError() const; - - private: - // The current unrecoverable errors. Only one unrecoverable error can be - // active at a time, but it may apply to more than one type. - TypeErrorMap unrecoverable_errors_; - - // List of data types that failed due to runtime errors and should be - // disabled. These are different from unrecoverable_errors_ in that - // ResetDataTypeError can remove them from this list. - TypeErrorMap data_type_errors_; - - // List of data types that failed due to the cryptographer not being ready. - TypeErrorMap crypto_errors_; - - // List of data types that failed because sync did not persist the newest - // version of their data. - TypeErrorMap persistence_errors_; - - // List of data types that could not start due to not being ready. These can - // be marked as ready by calling ResetUnreadyErrorFor(..). - TypeErrorMap unready_errors_; -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_DATA_TYPE_STATUS_TABLE_H_
diff --git a/components/sync_driver/device_count_metrics_provider.cc b/components/sync_driver/device_count_metrics_provider.cc deleted file mode 100644 index 7467bc6..0000000 --- a/components/sync_driver/device_count_metrics_provider.cc +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2016 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/sync_driver/device_count_metrics_provider.h" - -#include <algorithm> - -#include "base/metrics/sparse_histogram.h" -#include "components/sync_driver/device_info_tracker.h" - -namespace sync_driver { - -DeviceCountMetricsProvider::DeviceCountMetricsProvider( - const ProvideTrackersCallback& provide_trackers) - : provide_trackers_(provide_trackers) {} - -DeviceCountMetricsProvider::~DeviceCountMetricsProvider() {} - -int DeviceCountMetricsProvider::MaxActiveDeviceCount() const { - std::vector<const sync_driver::DeviceInfoTracker*> trackers; - provide_trackers_.Run(&trackers); - int max = 0; - for (auto* tracker : trackers) { - max = std::max(max, tracker->CountActiveDevices()); - } - return max; -} - -void DeviceCountMetricsProvider::ProvideGeneralMetrics( - metrics::ChromeUserMetricsExtension* uma_proto) { - UMA_HISTOGRAM_SPARSE_SLOWLY("Sync.DeviceCount", - std::min(MaxActiveDeviceCount(), 100)); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/device_count_metrics_provider_unittest.cc b/components/sync_driver/device_count_metrics_provider_unittest.cc deleted file mode 100644 index 702b439..0000000 --- a/components/sync_driver/device_count_metrics_provider_unittest.cc +++ /dev/null
@@ -1,104 +0,0 @@ -// Copyright 2016 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/sync_driver/device_count_metrics_provider.h" - -#include <memory> -#include <string> -#include <vector> - -#include "base/bind.h" -#include "base/test/histogram_tester.h" -#include "components/sync_driver/device_info.h" -#include "components/sync_driver/device_info_tracker.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sync_driver { - -namespace { - -class FakeTracker : public DeviceInfoTracker { - public: - explicit FakeTracker(const int count) : count_(count) {} - - // DeviceInfoTracker - bool IsSyncing() const override { return false; } - std::unique_ptr<DeviceInfo> GetDeviceInfo( - const std::string& client_id) const override { - return std::unique_ptr<DeviceInfo>(); - } - ScopedVector<DeviceInfo> GetAllDeviceInfo() const override { - return ScopedVector<DeviceInfo>(); - } - void AddObserver(Observer* observer) override {} - void RemoveObserver(Observer* observer) override {} - int CountActiveDevices() const override { return count_; } - - private: - int count_; -}; - -} // namespace - -class DeviceCountMetricsProviderTest : public testing::Test { - public: - DeviceCountMetricsProviderTest() - : metrics_provider_( - base::Bind(&DeviceCountMetricsProviderTest::GetTrackers, - base::Unretained(this))) {} - - void AddTracker(const int count) { - trackers_.push_back( - std::unique_ptr<DeviceInfoTracker>(new FakeTracker(count))); - } - void GetTrackers(std::vector<const DeviceInfoTracker*>* trackers) { - for (const auto& tracker : trackers_) { - trackers->push_back(tracker.get()); - } - } - - void TestProvider(int expected_device_count) { - base::HistogramTester histogram_tester; - metrics_provider_.ProvideGeneralMetrics(nullptr); - histogram_tester.ExpectUniqueSample("Sync.DeviceCount", - expected_device_count, 1); - } - - private: - DeviceCountMetricsProvider metrics_provider_; - std::vector<std::unique_ptr<DeviceInfoTracker>> trackers_; -}; - -namespace { - -TEST_F(DeviceCountMetricsProviderTest, NoTrackers) { - TestProvider(0); -} - -TEST_F(DeviceCountMetricsProviderTest, SingleTracker) { - AddTracker(2); - TestProvider(2); -} - -TEST_F(DeviceCountMetricsProviderTest, MultipileTrackers) { - AddTracker(1); - AddTracker(5); - AddTracker(-123); - AddTracker(0); - TestProvider(5); -} - -TEST_F(DeviceCountMetricsProviderTest, OnlyNegative) { - AddTracker(-123); - TestProvider(0); -} - -TEST_F(DeviceCountMetricsProviderTest, VeryLarge) { - AddTracker(123456789); - TestProvider(100); -} - -} // namespace - -} // namespace sync_driver
diff --git a/components/sync_driver/device_info.cc b/components/sync_driver/device_info.cc deleted file mode 100644 index efbd4d1..0000000 --- a/components/sync_driver/device_info.cc +++ /dev/null
@@ -1,114 +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 "components/sync_driver/device_info.h" - -#include "base/values.h" - -namespace sync_driver { - -DeviceInfo::DeviceInfo(const std::string& guid, - const std::string& client_name, - const std::string& chrome_version, - const std::string& sync_user_agent, - const sync_pb::SyncEnums::DeviceType device_type, - const std::string& signin_scoped_device_id) - : guid_(guid), - client_name_(client_name), - chrome_version_(chrome_version), - sync_user_agent_(sync_user_agent), - device_type_(device_type), - signin_scoped_device_id_(signin_scoped_device_id) { -} - -DeviceInfo::~DeviceInfo() { } - -const std::string& DeviceInfo::guid() const { - return guid_; -} - -const std::string& DeviceInfo::client_name() const { - return client_name_; -} - -const std::string& DeviceInfo::chrome_version() const { - return chrome_version_; -} - -const std::string& DeviceInfo::sync_user_agent() const { - return sync_user_agent_; -} - -const std::string& DeviceInfo::public_id() const { - return public_id_; -} - -sync_pb::SyncEnums::DeviceType DeviceInfo::device_type() const { - return device_type_; -} - -const std::string& DeviceInfo::signin_scoped_device_id() const { - return signin_scoped_device_id_; -} - -std::string DeviceInfo::GetOSString() const { - switch (device_type_) { - case sync_pb::SyncEnums_DeviceType_TYPE_WIN: - return "win"; - case sync_pb::SyncEnums_DeviceType_TYPE_MAC: - return "mac"; - case sync_pb::SyncEnums_DeviceType_TYPE_LINUX: - return "linux"; - case sync_pb::SyncEnums_DeviceType_TYPE_CROS: - return "chrome_os"; - case sync_pb::SyncEnums_DeviceType_TYPE_PHONE: - case sync_pb::SyncEnums_DeviceType_TYPE_TABLET: - // TODO(lipalani): crbug.com/170375. Add support for ios - // phones and tablets. - return "android"; - default: - return "unknown"; - } -} - -std::string DeviceInfo::GetDeviceTypeString() const { - switch (device_type_) { - case sync_pb::SyncEnums_DeviceType_TYPE_WIN: - case sync_pb::SyncEnums_DeviceType_TYPE_MAC: - case sync_pb::SyncEnums_DeviceType_TYPE_LINUX: - case sync_pb::SyncEnums_DeviceType_TYPE_CROS: - return "desktop_or_laptop"; - case sync_pb::SyncEnums_DeviceType_TYPE_PHONE: - return "phone"; - case sync_pb::SyncEnums_DeviceType_TYPE_TABLET: - return "tablet"; - default: - return "unknown"; - } -} - -bool DeviceInfo::Equals(const DeviceInfo& other) const { - return this->guid() == other.guid() && - this->client_name() == other.client_name() && - this->chrome_version() == other.chrome_version() && - this->sync_user_agent() == other.sync_user_agent() && - this->device_type() == other.device_type() && - this->signin_scoped_device_id() == other.signin_scoped_device_id(); -} - -base::DictionaryValue* DeviceInfo::ToValue() { - base::DictionaryValue* value = new base::DictionaryValue(); - value->SetString("name", client_name_); - value->SetString("id", public_id_); - value->SetString("os", GetOSString()); - value->SetString("type", GetDeviceTypeString()); - value->SetString("chromeVersion", chrome_version_); - return value; -} - -void DeviceInfo::set_public_id(const std::string& id) { - public_id_ = id; -} - -} // namespace sync_driver
diff --git a/components/sync_driver/device_info_data_type_controller.cc b/components/sync_driver/device_info_data_type_controller.cc deleted file mode 100644 index d17e3ca..0000000 --- a/components/sync_driver/device_info_data_type_controller.cc +++ /dev/null
@@ -1,50 +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 "components/sync_driver/device_info_data_type_controller.h" - -#include "base/callback.h" -#include "components/sync_driver/local_device_info_provider.h" - -namespace sync_driver { - -DeviceInfoDataTypeController::DeviceInfoDataTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const base::Closure& error_callback, - SyncClient* sync_client, - LocalDeviceInfoProvider* local_device_info_provider) - : UIDataTypeController(ui_thread, - error_callback, - syncer::DEVICE_INFO, - sync_client), - local_device_info_provider_(local_device_info_provider) {} - -DeviceInfoDataTypeController::~DeviceInfoDataTypeController() { -} - -bool DeviceInfoDataTypeController::StartModels() { - // Start the data type as soon as the local device info gets available. - if (local_device_info_provider_->GetLocalDeviceInfo()) { - return true; - } - - subscription_ = local_device_info_provider_->RegisterOnInitializedCallback( - base::Bind(&DeviceInfoDataTypeController::OnLocalDeviceInfoLoaded, this)); - - return false; -} - -void DeviceInfoDataTypeController::StopModels() { - subscription_.reset(); -} - -void DeviceInfoDataTypeController::OnLocalDeviceInfoLoaded() { - DCHECK_EQ(state_, MODEL_STARTING); - DCHECK(local_device_info_provider_->GetLocalDeviceInfo()); - - subscription_.reset(); - OnModelLoaded(); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/device_info_data_type_controller.h b/components/sync_driver/device_info_data_type_controller.h deleted file mode 100644 index 87e5b27..0000000 --- a/components/sync_driver/device_info_data_type_controller.h +++ /dev/null
@@ -1,44 +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 COMPONENTS_SYNC_DRIVER_DEVICE_INFO_DATA_TYPE_CONTROLLER_H_ -#define COMPONENTS_SYNC_DRIVER_DEVICE_INFO_DATA_TYPE_CONTROLLER_H_ - -#include <memory> - -#include "base/macros.h" -#include "base/single_thread_task_runner.h" -#include "components/sync_driver/local_device_info_provider.h" -#include "components/sync_driver/ui_data_type_controller.h" - -namespace sync_driver { - -// DataTypeController for DEVICE_INFO model type. -class DeviceInfoDataTypeController : public UIDataTypeController { - public: - DeviceInfoDataTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const base::Closure& error_callback, - SyncClient* sync_client, - LocalDeviceInfoProvider* local_device_info_provider); - - private: - ~DeviceInfoDataTypeController() override; - - // UIDataTypeController implementations. - bool StartModels() override; - void StopModels() override; - - // Called by LocalDeviceInfoProvider when the local device into becomes - // available. - void OnLocalDeviceInfoLoaded(); - - LocalDeviceInfoProvider* const local_device_info_provider_; - std::unique_ptr<LocalDeviceInfoProvider::Subscription> subscription_; - DISALLOW_COPY_AND_ASSIGN(DeviceInfoDataTypeController); -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_DEVICE_INFO_DATA_TYPE_CONTROLLER_H_
diff --git a/components/sync_driver/device_info_data_type_controller_unittest.cc b/components/sync_driver/device_info_data_type_controller_unittest.cc deleted file mode 100644 index c4705d7e..0000000 --- a/components/sync_driver/device_info_data_type_controller_unittest.cc +++ /dev/null
@@ -1,130 +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 "components/sync_driver/device_info_data_type_controller.h" - -#include "base/bind.h" -#include "base/callback.h" -#include "base/memory/weak_ptr.h" -#include "base/run_loop.h" -#include "base/threading/thread_task_runner_handle.h" -#include "components/sync/base/model_type.h" -#include "components/sync_driver/fake_sync_client.h" -#include "components/sync_driver/local_device_info_provider_mock.h" -#include "components/sync_driver/sync_api_component_factory.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sync_driver { - -namespace { - -class DeviceInfoDataTypeControllerTest : public testing::Test { - public: - DeviceInfoDataTypeControllerTest() - : load_finished_(false), - last_type_(syncer::UNSPECIFIED), - weak_ptr_factory_(this) {} - ~DeviceInfoDataTypeControllerTest() override {} - - void SetUp() override { - local_device_.reset(new LocalDeviceInfoProviderMock( - "cache_guid", - "Wayne Gretzky's Hacking Box", - "Chromium 10k", - "Chrome 10k", - sync_pb::SyncEnums_DeviceType_TYPE_LINUX, - "device_id")); - - controller_ = new DeviceInfoDataTypeController( - base::ThreadTaskRunnerHandle::Get(), base::Closure(), &sync_client_, - local_device_.get()); - - load_finished_ = false; - last_type_ = syncer::UNSPECIFIED; - last_error_ = syncer::SyncError(); - } - - void TearDown() override { - controller_ = NULL; - local_device_.reset(); - } - - void Start() { - controller_->LoadModels( - base::Bind(&DeviceInfoDataTypeControllerTest::OnLoadFinished, - weak_ptr_factory_.GetWeakPtr())); - } - - void OnLoadFinished(syncer::ModelType type, syncer::SyncError error) { - load_finished_ = true; - last_type_ = type; - last_error_ = error; - } - - testing::AssertionResult LoadResult() { - if (!load_finished_) { - return testing::AssertionFailure() << "OnLoadFinished wasn't called"; - } - - if (last_error_.IsSet()) { - return testing::AssertionFailure() - << "OnLoadFinished was called with a SyncError: " - << last_error_.ToString(); - } - - if (last_type_ != syncer::DEVICE_INFO) { - return testing::AssertionFailure() - << "OnLoadFinished was called with a wrong sync type: " - << last_type_; - } - - return testing::AssertionSuccess(); - } - - protected: - scoped_refptr<DeviceInfoDataTypeController> controller_; - std::unique_ptr<LocalDeviceInfoProviderMock> local_device_; - bool load_finished_; - - private: - base::MessageLoopForUI message_loop_; - syncer::ModelType last_type_; - syncer::SyncError last_error_; - FakeSyncClient sync_client_; - base::WeakPtrFactory<DeviceInfoDataTypeControllerTest> weak_ptr_factory_; -}; - -TEST_F(DeviceInfoDataTypeControllerTest, StartModels) { - Start(); - EXPECT_EQ(DataTypeController::MODEL_LOADED, controller_->state()); - EXPECT_TRUE(LoadResult()); -} - -TEST_F(DeviceInfoDataTypeControllerTest, StartModelsDelayedByLocalDevice) { - local_device_->SetInitialized(false); - Start(); - EXPECT_FALSE(load_finished_); - EXPECT_EQ(DataTypeController::MODEL_STARTING, controller_->state()); - - local_device_->SetInitialized(true); - EXPECT_EQ(DataTypeController::MODEL_LOADED, controller_->state()); - EXPECT_TRUE(LoadResult()); -} - -// Tests that DeviceInfoDataTypeControllerTest handles the situation -// when everything stops before the start gets a chance to finish. -TEST_F(DeviceInfoDataTypeControllerTest, DestructionWithDelayedStart) { - local_device_->SetInitialized(false); - Start(); - - controller_->Stop(); - // Destroy |local_device_| and |controller_| out of order - // to verify that the controller doesn't crash in the destructor. - local_device_.reset(); - controller_ = NULL; -} - -} // namespace - -} // namespace sync_driver
diff --git a/components/sync_driver/device_info_service.cc b/components/sync_driver/device_info_service.cc deleted file mode 100644 index 72fcd2c..0000000 --- a/components/sync_driver/device_info_service.cc +++ /dev/null
@@ -1,536 +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. - -#include "components/sync_driver/device_info_service.h" - -#include <set> -#include <utility> -#include <vector> - -#include "base/bind.h" -#include "base/location.h" -#include "base/memory/ptr_util.h" -#include "base/strings/string_util.h" -#include "components/sync/api/entity_change.h" -#include "components/sync/api/metadata_batch.h" -#include "components/sync/api/sync_error.h" -#include "components/sync/base/time.h" -#include "components/sync/core/data_batch_impl.h" -#include "components/sync/core/simple_metadata_change_list.h" -#include "components/sync/protocol/data_type_state.pb.h" -#include "components/sync/protocol/sync.pb.h" -#include "components/sync_driver/device_info_util.h" - -namespace sync_driver_v2 { - -using base::Time; -using base::TimeDelta; -using syncer::SyncError; -using syncer_v2::DataBatchImpl; -using syncer_v2::EntityChange; -using syncer_v2::EntityChangeList; -using syncer_v2::EntityData; -using syncer_v2::EntityDataMap; -using syncer_v2::MetadataBatch; -using syncer_v2::MetadataChangeList; -using syncer_v2::ModelTypeStore; -using syncer_v2::SimpleMetadataChangeList; -using sync_driver::DeviceInfo; -using sync_driver::DeviceInfoUtil; -using sync_pb::DataTypeState; -using sync_pb::DeviceInfoSpecifics; -using sync_pb::EntitySpecifics; - -using Record = ModelTypeStore::Record; -using RecordList = ModelTypeStore::RecordList; -using Result = ModelTypeStore::Result; -using WriteBatch = ModelTypeStore::WriteBatch; - -DeviceInfoService::DeviceInfoService( - sync_driver::LocalDeviceInfoProvider* local_device_info_provider, - const StoreFactoryFunction& callback, - const ChangeProcessorFactory& change_processor_factory) - : ModelTypeService(change_processor_factory, syncer::DEVICE_INFO), - local_device_info_provider_(local_device_info_provider), - weak_factory_(this) { - DCHECK(local_device_info_provider); - - // This is not threadsafe, but presuably the provider initializes on the same - // thread as us so we're okay. - if (local_device_info_provider->GetLocalDeviceInfo()) { - OnProviderInitialized(); - } else { - subscription_ = - local_device_info_provider->RegisterOnInitializedCallback(base::Bind( - &DeviceInfoService::OnProviderInitialized, base::Unretained(this))); - } - - callback.Run(base::Bind(&DeviceInfoService::OnStoreCreated, - weak_factory_.GetWeakPtr())); -} - -DeviceInfoService::~DeviceInfoService() {} - -std::unique_ptr<MetadataChangeList> -DeviceInfoService::CreateMetadataChangeList() { - return base::WrapUnique(new SimpleMetadataChangeList()); -} - -SyncError DeviceInfoService::MergeSyncData( - std::unique_ptr<MetadataChangeList> metadata_change_list, - EntityDataMap entity_data_map) { - DCHECK(has_provider_initialized_); - DCHECK(has_metadata_loaded_); - DCHECK(change_processor()); - - // Local data should typically be near empty, with the only possible value - // corresponding to this device. This is because on signout all device info - // data is blown away. However, this simplification is being ignored here and - // a full difference is going to be calculated to explore what other service - // implementations may look like. - std::set<std::string> local_guids_to_put; - for (const auto& kv : all_data_) { - local_guids_to_put.insert(kv.first); - } - - bool has_changes = false; - const DeviceInfo* local_info = - local_device_info_provider_->GetLocalDeviceInfo(); - std::string local_guid = local_info->guid(); - std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch(); - for (const auto& kv : entity_data_map) { - const DeviceInfoSpecifics& specifics = - kv.second.value().specifics.device_info(); - DCHECK_EQ(kv.first, DeviceInfoUtil::SpecificsToTag(specifics)); - if (specifics.cache_guid() == local_guid) { - // Don't Put local data if it's the same as the remote copy. - if (local_info->Equals(*CopyToModel(specifics))) { - local_guids_to_put.erase(local_guid); - } else { - // This device is valid right now and this entry is about to be - // committed, use this as an opportunity to refresh the timestamp. - all_data_[local_guid]->set_last_updated_timestamp( - syncer::TimeToProtoTime(Time::Now())); - } - } else { - // Remote data wins conflicts. - local_guids_to_put.erase(specifics.cache_guid()); - has_changes = true; - StoreSpecifics(base::WrapUnique(new DeviceInfoSpecifics(specifics)), - batch.get()); - } - } - - for (const std::string& guid : local_guids_to_put) { - change_processor()->Put(DeviceInfoUtil::SpecificsToTag(*all_data_[guid]), - CopyToEntityData(*all_data_[guid]), - metadata_change_list.get()); - } - - CommitAndNotify(std::move(batch), std::move(metadata_change_list), - has_changes); - return SyncError(); -} - -SyncError DeviceInfoService::ApplySyncChanges( - std::unique_ptr<MetadataChangeList> metadata_change_list, - EntityChangeList entity_changes) { - DCHECK(has_provider_initialized_); - DCHECK(has_metadata_loaded_); - - std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch(); - bool has_changes = false; - for (EntityChange& change : entity_changes) { - const std::string guid = - DeviceInfoUtil::TagToCacheGuid(change.client_tag()); - // Each device is the authoritative source for itself, ignore any remote - // changes that have our local cache guid. - if (guid == local_device_info_provider_->GetLocalDeviceInfo()->guid()) { - continue; - } - - if (change.type() == EntityChange::ACTION_DELETE) { - has_changes |= DeleteSpecifics(guid, batch.get()); - } else { - const DeviceInfoSpecifics& specifics = - change.data().specifics.device_info(); - DCHECK(guid == specifics.cache_guid()); - StoreSpecifics(base::WrapUnique(new DeviceInfoSpecifics(specifics)), - batch.get()); - has_changes = true; - } - } - - CommitAndNotify(std::move(batch), std::move(metadata_change_list), - has_changes); - return SyncError(); -} - -void DeviceInfoService::GetData(ClientTagList client_tags, - DataCallback callback) { - DCHECK(has_metadata_loaded_); - - std::unique_ptr<DataBatchImpl> batch(new DataBatchImpl()); - for (const auto& tag : client_tags) { - const auto& iter = all_data_.find(DeviceInfoUtil::TagToCacheGuid(tag)); - if (iter != all_data_.end()) { - DCHECK_EQ(tag, DeviceInfoUtil::SpecificsToTag(*iter->second)); - batch->Put(tag, CopyToEntityData(*iter->second)); - } - } - - callback.Run(SyncError(), std::move(batch)); -} - -void DeviceInfoService::GetAllData(DataCallback callback) { - DCHECK(has_metadata_loaded_); - - std::unique_ptr<DataBatchImpl> batch(new DataBatchImpl()); - for (const auto& kv : all_data_) { - batch->Put(DeviceInfoUtil::SpecificsToTag(*kv.second), - CopyToEntityData(*kv.second)); - } - - callback.Run(SyncError(), std::move(batch)); -} - -std::string DeviceInfoService::GetClientTag(const EntityData& entity_data) { - DCHECK(entity_data.specifics.has_device_info()); - return DeviceInfoUtil::SpecificsToTag(entity_data.specifics.device_info()); -} - -void DeviceInfoService::OnChangeProcessorSet() { - // We've recieved a new processor that needs metadata. If we're still in the - // process of loading data and/or metadata, then |has_metadata_loaded_| is - // false and we'll wait for those async reads to happen. If we've already - // loaded metadata and then subsequently we get a new processor, we must not - // have created the processor ourselves because we had no metadata. So there - // must not be any metadata on disk. - if (has_metadata_loaded_) { - change_processor()->OnMetadataLoaded(SyncError(), - base::WrapUnique(new MetadataBatch())); - ReconcileLocalAndStored(); - } -} - -bool DeviceInfoService::IsSyncing() const { - return !all_data_.empty(); -} - -std::unique_ptr<DeviceInfo> DeviceInfoService::GetDeviceInfo( - const std::string& client_id) const { - const ClientIdToSpecifics::const_iterator iter = all_data_.find(client_id); - if (iter == all_data_.end()) { - return std::unique_ptr<DeviceInfo>(); - } - - return CopyToModel(*iter->second); -} - -ScopedVector<DeviceInfo> DeviceInfoService::GetAllDeviceInfo() const { - ScopedVector<DeviceInfo> list; - - for (ClientIdToSpecifics::const_iterator iter = all_data_.begin(); - iter != all_data_.end(); ++iter) { - list.push_back(CopyToModel(*iter->second)); - } - - return list; -} - -void DeviceInfoService::AddObserver(Observer* observer) { - observers_.AddObserver(observer); -} - -void DeviceInfoService::RemoveObserver(Observer* observer) { - observers_.RemoveObserver(observer); -} - -int DeviceInfoService::CountActiveDevices() const { - return CountActiveDevices(Time::Now()); -} - -void DeviceInfoService::NotifyObservers() { - FOR_EACH_OBSERVER(Observer, observers_, OnDeviceInfoChange()); -} - -// Static. -std::unique_ptr<DeviceInfoSpecifics> DeviceInfoService::CopyToSpecifics( - const DeviceInfo& info) { - std::unique_ptr<DeviceInfoSpecifics> specifics = - base::WrapUnique(new DeviceInfoSpecifics); - specifics->set_cache_guid(info.guid()); - specifics->set_client_name(info.client_name()); - specifics->set_chrome_version(info.chrome_version()); - specifics->set_sync_user_agent(info.sync_user_agent()); - specifics->set_device_type(info.device_type()); - specifics->set_signin_scoped_device_id(info.signin_scoped_device_id()); - return specifics; -} - -// Static. -std::unique_ptr<DeviceInfo> DeviceInfoService::CopyToModel( - const DeviceInfoSpecifics& specifics) { - return base::WrapUnique(new DeviceInfo( - specifics.cache_guid(), specifics.client_name(), - specifics.chrome_version(), specifics.sync_user_agent(), - specifics.device_type(), specifics.signin_scoped_device_id())); -} - -// Static. -std::unique_ptr<EntityData> DeviceInfoService::CopyToEntityData( - const DeviceInfoSpecifics& specifics) { - std::unique_ptr<EntityData> entity_data(new EntityData()); - *entity_data->specifics.mutable_device_info() = specifics; - entity_data->non_unique_name = specifics.client_name(); - return entity_data; -} - -void DeviceInfoService::StoreSpecifics( - std::unique_ptr<DeviceInfoSpecifics> specifics, - WriteBatch* batch) { - const std::string guid = specifics->cache_guid(); - DVLOG(1) << "Storing DEVICE_INFO for " << specifics->client_name() - << " with ID " << guid; - store_->WriteData(batch, guid, specifics->SerializeAsString()); - all_data_[guid] = std::move(specifics); -} - -bool DeviceInfoService::DeleteSpecifics(const std::string& guid, - WriteBatch* batch) { - ClientIdToSpecifics::const_iterator iter = all_data_.find(guid); - if (iter != all_data_.end()) { - DVLOG(1) << "Deleting DEVICE_INFO for " << iter->second->client_name() - << " with ID " << guid; - store_->DeleteData(batch, guid); - all_data_.erase(iter); - return true; - } else { - return false; - } -} - -void DeviceInfoService::OnProviderInitialized() { - has_provider_initialized_ = true; - LoadMetadataIfReady(); -} - -void DeviceInfoService::OnStoreCreated(Result result, - std::unique_ptr<ModelTypeStore> store) { - if (result == Result::SUCCESS) { - std::swap(store_, store); - store_->ReadAllData(base::Bind(&DeviceInfoService::OnReadAllData, - weak_factory_.GetWeakPtr())); - } else { - ReportStartupErrorToSync("ModelTypeStore creation failed."); - // TODO(skym, crbug.com/582460): Handle unrecoverable initialization - // failure. - } -} - -void DeviceInfoService::OnReadAllData(Result result, - std::unique_ptr<RecordList> record_list) { - if (result != Result::SUCCESS) { - ReportStartupErrorToSync("Initial load of data failed."); - // TODO(skym, crbug.com/582460): Handle unrecoverable initialization - // failure. - return; - } - - for (const Record& r : *record_list.get()) { - std::unique_ptr<DeviceInfoSpecifics> specifics( - base::WrapUnique(new DeviceInfoSpecifics())); - if (specifics->ParseFromString(r.value)) { - all_data_[specifics->cache_guid()] = std::move(specifics); - } else { - ReportStartupErrorToSync("Failed to deserialize specifics."); - // TODO(skym, crbug.com/582460): Handle unrecoverable initialization - // failure. - } - } - - has_data_loaded_ = true; - LoadMetadataIfReady(); -} - -void DeviceInfoService::LoadMetadataIfReady() { - if (has_data_loaded_ && has_provider_initialized_) { - store_->ReadAllMetadata(base::Bind(&DeviceInfoService::OnReadAllMetadata, - weak_factory_.GetWeakPtr())); - } -} - -void DeviceInfoService::OnReadAllMetadata( - Result result, - std::unique_ptr<RecordList> metadata_records, - const std::string& global_metadata) { - DCHECK(!has_metadata_loaded_); - - if (result != Result::SUCCESS) { - // Store has encountered some serious error. We should still be able to - // continue as a read only service, since if we got this far we must have - // loaded all data out succesfully. - ReportStartupErrorToSync("Load of metadata completely failed."); - return; - } - - // If we have no metadata then we don't want to create a processor. The idea - // is that by not having a processor, the services will suffer less of a - // performance hit. This isn't terribly applicable for this model type, but - // we want this class to be as similar to other services as possible so follow - // the convention. - if (metadata_records->size() > 0 || !global_metadata.empty()) { - CreateChangeProcessor(); - } - - // Set this after OnChangeProcessorSet so that we can correctly avoid giving - // the processor empty metadata. We always want to set |has_metadata_loaded_| - // at this point so that we'll know to give a processor empty metadata if it - // is created later. - has_metadata_loaded_ = true; - - if (!change_processor()) { - // This means we haven't been told to start syncing and we don't have any - // local metadata. - return; - } - - std::unique_ptr<MetadataBatch> batch(new MetadataBatch()); - DataTypeState state; - if (state.ParseFromString(global_metadata)) { - batch->SetDataTypeState(state); - } else { - // TODO(skym): How bad is this scenario? We may be able to just give an - // empty batch to the processor and we'll treat corrupted data type state - // as no data type state at all. The question is do we want to add any of - // the entity metadata to the batch or completely skip that step? We're - // going to have to perform a merge shortly. Does this decision/logic even - // belong in this service? - change_processor()->OnMetadataLoaded( - change_processor()->CreateAndUploadError( - FROM_HERE, "Failed to deserialize global metadata."), - nullptr); - } - for (const Record& r : *metadata_records.get()) { - sync_pb::EntityMetadata entity_metadata; - if (entity_metadata.ParseFromString(r.value)) { - batch->AddMetadata(r.id, entity_metadata); - } else { - // TODO(skym): This really isn't too bad. We just want to regenerate - // metadata for this particular entity. Unfortunately there isn't a - // convenient way to tell the processor to do this. - LOG(WARNING) << "Failed to deserialize entity metadata."; - } - } - change_processor()->OnMetadataLoaded(SyncError(), std::move(batch)); - ReconcileLocalAndStored(); -} - -void DeviceInfoService::OnCommit(Result result) { - if (result != Result::SUCCESS) { - LOG(WARNING) << "Failed a write to store."; - } -} - -void DeviceInfoService::ReconcileLocalAndStored() { - // On initial syncing we will have a change processor here, but it will not be - // tracking changes. We need to persist a copy of our local device info to - // disk, but the Put call to the processor will be ignored. That should be - // fine however, as the discrepancy will be picked up later in merge. We don't - // bother trying to track this case and act intelligently because simply not - // much of a benefit in doing so. - DCHECK(has_provider_initialized_); - DCHECK(has_metadata_loaded_); - DCHECK(change_processor()); - const DeviceInfo* current_info = - local_device_info_provider_->GetLocalDeviceInfo(); - auto iter = all_data_.find(current_info->guid()); - - // Convert to DeviceInfo for Equals function. - if (iter != all_data_.end() && - current_info->Equals(*CopyToModel(*iter->second))) { - const TimeDelta pulse_delay(DeviceInfoUtil::CalculatePulseDelay( - GetLastUpdateTime(*iter->second), Time::Now())); - if (!pulse_delay.is_zero()) { - pulse_timer_.Start(FROM_HERE, pulse_delay, - base::Bind(&DeviceInfoService::SendLocalData, - base::Unretained(this))); - return; - } - } - SendLocalData(); -} - -void DeviceInfoService::SendLocalData() { - DCHECK(has_provider_initialized_); - // TODO(skym): Handle disconnecting and reconnecting, this will currently halt - // the pulse timer and never restart it. - if (!change_processor()) { - return; - } - - std::unique_ptr<DeviceInfoSpecifics> specifics = - CopyToSpecifics(*local_device_info_provider_->GetLocalDeviceInfo()); - specifics->set_last_updated_timestamp(syncer::TimeToProtoTime(Time::Now())); - - std::unique_ptr<MetadataChangeList> metadata_change_list = - CreateMetadataChangeList(); - change_processor()->Put(DeviceInfoUtil::SpecificsToTag(*specifics), - CopyToEntityData(*specifics), - metadata_change_list.get()); - - std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch(); - StoreSpecifics(std::move(specifics), batch.get()); - - CommitAndNotify(std::move(batch), std::move(metadata_change_list), true); - pulse_timer_.Start( - FROM_HERE, DeviceInfoUtil::kPulseInterval, - base::Bind(&DeviceInfoService::SendLocalData, base::Unretained(this))); -} - -void DeviceInfoService::CommitAndNotify( - std::unique_ptr<WriteBatch> batch, - std::unique_ptr<MetadataChangeList> metadata_change_list, - bool should_notify) { - static_cast<SimpleMetadataChangeList*>(metadata_change_list.get()) - ->TransferChanges(store_.get(), batch.get()); - store_->CommitWriteBatch( - std::move(batch), - base::Bind(&DeviceInfoService::OnCommit, weak_factory_.GetWeakPtr())); - if (should_notify) { - NotifyObservers(); - } -} - -int DeviceInfoService::CountActiveDevices(const Time now) const { - return std::count_if(all_data_.begin(), all_data_.end(), - [now](ClientIdToSpecifics::const_reference pair) { - return DeviceInfoUtil::IsActive( - GetLastUpdateTime(*pair.second), now); - }); -} - -void DeviceInfoService::ReportStartupErrorToSync(const std::string& msg) { - DCHECK(!has_metadata_loaded_); - LOG(WARNING) << msg; - - // Create a processor and give it the error in case sync tries to start. - if (!change_processor()) { - CreateChangeProcessor(); - } - change_processor()->OnMetadataLoaded( - change_processor()->CreateAndUploadError(FROM_HERE, msg), nullptr); -} - -// static -Time DeviceInfoService::GetLastUpdateTime( - const DeviceInfoSpecifics& specifics) { - if (specifics.has_last_updated_timestamp()) { - return syncer::ProtoTimeToTime(specifics.last_updated_timestamp()); - } else { - return Time(); - } -} - -} // namespace sync_driver_v2
diff --git a/components/sync_driver/device_info_service.h b/components/sync_driver/device_info_service.h deleted file mode 100644 index 2e6103fe..0000000 --- a/components/sync_driver/device_info_service.h +++ /dev/null
@@ -1,190 +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. - -#ifndef COMPONENTS_SYNC_DRIVER_DEVICE_INFO_SERVICE_H_ -#define COMPONENTS_SYNC_DRIVER_DEVICE_INFO_SERVICE_H_ - -#include <stdint.h> - -#include <map> -#include <memory> -#include <string> -#include <vector> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/observer_list.h" -#include "base/time/time.h" -#include "base/timer/timer.h" -#include "components/sync/api/model_type_service.h" -#include "components/sync/api/model_type_store.h" -#include "components/sync/core/simple_metadata_change_list.h" -#include "components/sync_driver/device_info_tracker.h" -#include "components/sync_driver/local_device_info_provider.h" - -namespace syncer { -class SyncError; -} // namespace syncer - -namespace syncer_v2 { -class ModelTypeChangeProcessor; -} // namespace syncer_v2 - -namespace sync_pb { -class DeviceInfoSpecifics; -} // namespace sync_pb - -namespace sync_driver_v2 { - -// USS service implementation for DEVICE_INFO model type. Handles storage of -// device info and associated sync metadata, applying/merging foreign changes, -// and allows public read access. -class DeviceInfoService : public syncer_v2::ModelTypeService, - public sync_driver::DeviceInfoTracker { - public: - typedef base::Callback<void( - const syncer_v2::ModelTypeStore::InitCallback& callback)> - StoreFactoryFunction; - - DeviceInfoService( - sync_driver::LocalDeviceInfoProvider* local_device_info_provider, - const StoreFactoryFunction& callback, - const ChangeProcessorFactory& change_processor_factory); - ~DeviceInfoService() override; - - // ModelTypeService implementation. - std::unique_ptr<syncer_v2::MetadataChangeList> CreateMetadataChangeList() - override; - syncer::SyncError MergeSyncData( - std::unique_ptr<syncer_v2::MetadataChangeList> metadata_change_list, - syncer_v2::EntityDataMap entity_data_map) override; - syncer::SyncError ApplySyncChanges( - std::unique_ptr<syncer_v2::MetadataChangeList> metadata_change_list, - syncer_v2::EntityChangeList entity_changes) override; - void GetData(ClientTagList client_tags, DataCallback callback) override; - void GetAllData(DataCallback callback) override; - std::string GetClientTag(const syncer_v2::EntityData& entity_data) override; - void OnChangeProcessorSet() override; - - // DeviceInfoTracker implementation. - bool IsSyncing() const override; - std::unique_ptr<sync_driver::DeviceInfo> GetDeviceInfo( - const std::string& client_id) const override; - ScopedVector<sync_driver::DeviceInfo> GetAllDeviceInfo() const override; - void AddObserver(Observer* observer) override; - void RemoveObserver(Observer* observer) override; - int CountActiveDevices() const override; - - private: - friend class DeviceInfoServiceTest; - - // Cache of all syncable and local data, stored by device cache guid. - using ClientIdToSpecifics = - std::map<std::string, std::unique_ptr<sync_pb::DeviceInfoSpecifics>>; - - static std::unique_ptr<sync_pb::DeviceInfoSpecifics> CopyToSpecifics( - const sync_driver::DeviceInfo& info); - - // Allocate new DeviceInfo from SyncData. - static std::unique_ptr<sync_driver::DeviceInfo> CopyToModel( - const sync_pb::DeviceInfoSpecifics& specifics); - // Conversion as we prepare to hand data to the processor. - static std::unique_ptr<syncer_v2::EntityData> CopyToEntityData( - const sync_pb::DeviceInfoSpecifics& specifics); - - // Store SyncData in the cache and durable storage. - void StoreSpecifics(std::unique_ptr<sync_pb::DeviceInfoSpecifics> specifics, - syncer_v2::ModelTypeStore::WriteBatch* batch); - // Delete SyncData from the cache and durable storage, returns true if there - // was actually anything at the given tag. - bool DeleteSpecifics(const std::string& tag, - syncer_v2::ModelTypeStore::WriteBatch* batch); - - // Notify all registered observers. - void NotifyObservers(); - - // Used as callback given to LocalDeviceInfoProvider. - void OnProviderInitialized(); - - // Methods used as callbacks given to DataTypeStore. - void OnStoreCreated(syncer_v2::ModelTypeStore::Result result, - std::unique_ptr<syncer_v2::ModelTypeStore> store); - void OnReadAllData( - syncer_v2::ModelTypeStore::Result result, - std::unique_ptr<syncer_v2::ModelTypeStore::RecordList> record_list); - void OnReadAllMetadata( - syncer_v2::ModelTypeStore::Result result, - std::unique_ptr<syncer_v2::ModelTypeStore::RecordList> metadata_records, - const std::string& global_metadata); - void OnCommit(syncer_v2::ModelTypeStore::Result result); - - // Load metadata if the data is loaded and the provider is initialized. - void LoadMetadataIfReady(); - - // Performs reconciliation between the locally provided device info and the - // stored device info data. If the sets of data differ, then we consider this - // a local change and we send it to the processor. - void ReconcileLocalAndStored(); - - // Stores the updated version of the local copy of device info in durable - // storage, in memory, and informs sync of the change. Should not be called - // before the provider and processor have initialized. - void SendLocalData(); - - // Persists the changes in the given aggregators and notifies observers if - // indicated to do as such. - void CommitAndNotify( - std::unique_ptr<syncer_v2::ModelTypeStore::WriteBatch> batch, - std::unique_ptr<syncer_v2::MetadataChangeList> metadata_change_list, - bool should_notify); - - // Counts the number of active devices relative to |now|. The activeness of a - // device depends on the amount of time since it was updated, which means - // comparing it against the current time. |now| is passed into this method to - // allow unit tests to control expected results. - int CountActiveDevices(const base::Time now) const; - - // Report an error starting up to sync if it tries to connect to this - // datatype, since these errors prevent us from knowing if sync is enabled. - void ReportStartupErrorToSync(const std::string& msg); - - // Find the timestamp for the last time this |device_info| was edited. - static base::Time GetLastUpdateTime( - const sync_pb::DeviceInfoSpecifics& specifics); - - // |local_device_info_provider_| isn't owned. - const sync_driver::LocalDeviceInfoProvider* const local_device_info_provider_; - - ClientIdToSpecifics all_data_; - - // Registered observers, not owned. - base::ObserverList<Observer, true> observers_; - - // Used to listen for provider initialization. If the provider is already - // initialized during our constructor then the subscription is never used. - std::unique_ptr<sync_driver::LocalDeviceInfoProvider::Subscription> - subscription_; - - // In charge of actually persiting changes to disk, or loading previous data. - std::unique_ptr<syncer_v2::ModelTypeStore> store_; - - // If |local_device_info_provider_| has initialized. - bool has_provider_initialized_ = false; - // If data has been loaded from the store. - bool has_data_loaded_ = false; - // if |change_processor()| has been given metadata. - bool has_metadata_loaded_ = false; - - // Used to update our local device info once every pulse interval. - base::OneShotTimer pulse_timer_; - - // Should always be last member. - base::WeakPtrFactory<DeviceInfoService> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(DeviceInfoService); -}; - -} // namespace sync_driver_v2 - -#endif // COMPONENTS_SYNC_DRIVER_DEVICE_INFO_SERVICE_H_
diff --git a/components/sync_driver/device_info_service_unittest.cc b/components/sync_driver/device_info_service_unittest.cc deleted file mode 100644 index 9b38f46..0000000 --- a/components/sync_driver/device_info_service_unittest.cc +++ /dev/null
@@ -1,776 +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. - -#include "components/sync_driver/device_info_service.h" - -#include <map> -#include <memory> -#include <set> -#include <string> -#include <utility> - -#include "base/bind.h" -#include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/strings/stringprintf.h" -#include "components/sync/api/data_batch.h" -#include "components/sync/api/entity_data.h" -#include "components/sync/api/fake_model_type_change_processor.h" -#include "components/sync/api/metadata_batch.h" -#include "components/sync/api/model_type_store.h" -#include "components/sync/base/time.h" -#include "components/sync/core/test/data_type_error_handler_mock.h" -#include "components/sync/core/test/model_type_store_test_util.h" -#include "components/sync/protocol/data_type_state.pb.h" -#include "components/sync_driver/local_device_info_provider_mock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sync_driver_v2 { - -using base::Time; -using base::TimeDelta; -using syncer::SyncError; -using syncer_v2::DataBatch; -using syncer_v2::EntityChange; -using syncer_v2::EntityChangeList; -using syncer_v2::EntityData; -using syncer_v2::EntityDataMap; -using syncer_v2::EntityDataPtr; -using syncer_v2::MetadataBatch; -using syncer_v2::MetadataChangeList; -using syncer_v2::ModelTypeChangeProcessor; -using syncer_v2::ModelTypeService; -using syncer_v2::ModelTypeStore; -using syncer_v2::ModelTypeStoreTestUtil; -using syncer_v2::TagAndData; -using sync_driver::DeviceInfo; -using sync_driver::DeviceInfoTracker; -using sync_driver::LocalDeviceInfoProviderMock; -using sync_pb::DataTypeState; -using sync_pb::DeviceInfoSpecifics; -using sync_pb::EntitySpecifics; - -using ClientTagList = ModelTypeService::ClientTagList; -using RecordList = ModelTypeStore::RecordList; -using Result = ModelTypeStore::Result; -using StartCallback = ModelTypeChangeProcessor::StartCallback; -using WriteBatch = ModelTypeStore::WriteBatch; - -namespace { - -std::unique_ptr<DeviceInfo> CreateDeviceInfo() { - return base::MakeUnique<DeviceInfo>( - "guid_1", "client_1", "Chromium 10k", "Chrome 10k", - sync_pb::SyncEnums_DeviceType_TYPE_LINUX, "device_id"); -} - -void AssertResultIsSuccess(Result result) { - ASSERT_EQ(Result::SUCCESS, result); -} - -void AssertEqual(const DeviceInfoSpecifics& s1, const DeviceInfoSpecifics& s2) { - ASSERT_EQ(s1.cache_guid(), s2.cache_guid()); - ASSERT_EQ(s1.client_name(), s2.client_name()); - ASSERT_EQ(s1.device_type(), s2.device_type()); - ASSERT_EQ(s1.sync_user_agent(), s2.sync_user_agent()); - ASSERT_EQ(s1.chrome_version(), s2.chrome_version()); - ASSERT_EQ(s1.signin_scoped_device_id(), s2.signin_scoped_device_id()); -} - -void AssertEqual(const DeviceInfoSpecifics& specifics, - const DeviceInfo& model) { - ASSERT_EQ(specifics.cache_guid(), model.guid()); - ASSERT_EQ(specifics.client_name(), model.client_name()); - ASSERT_EQ(specifics.device_type(), model.device_type()); - ASSERT_EQ(specifics.sync_user_agent(), model.sync_user_agent()); - ASSERT_EQ(specifics.chrome_version(), model.chrome_version()); - ASSERT_EQ(specifics.signin_scoped_device_id(), - model.signin_scoped_device_id()); -} - -void AssertExpectedFromDataBatch( - std::map<std::string, DeviceInfoSpecifics> expected, - SyncError error, - std::unique_ptr<DataBatch> batch) { - ASSERT_FALSE(error.IsSet()); - while (batch->HasNext()) { - const TagAndData& pair = batch->Next(); - std::map<std::string, DeviceInfoSpecifics>::iterator iter = - expected.find(pair.first); - ASSERT_NE(iter, expected.end()); - AssertEqual(iter->second, pair.second->specifics.device_info()); - // Removing allows us to verify we don't see the same item multiple times, - // and that we saw everything we expected. - expected.erase(iter); - } - ASSERT_TRUE(expected.empty()); -} - -// Creates an EntityData/EntityDataPtr around a copy of the given specifics. -EntityDataPtr SpecificsToEntity(const DeviceInfoSpecifics& specifics) { - EntityData data; - // These tests do not care about the tag hash, but EntityData and friends - // cannot differentiate between the default EntityData object if the hash - // is unset, which causes pass/copy operations to no-op and things start to - // break, so we throw in a junk value and forget about it. - data.client_tag_hash = "junk"; - *data.specifics.mutable_device_info() = specifics; - return data.PassToPtr(); -} - -std::string CacheGuidToTag(const std::string& guid) { - return "DeviceInfo_" + guid; -} - -// Instead of actually processing anything, simply accumulates all instructions -// in members that can then be accessed. TODO(skym): If this ends up being -// useful for other model type unittests it should be moved out to a shared -// location. -class RecordingModelTypeChangeProcessor - : public syncer_v2::FakeModelTypeChangeProcessor { - public: - RecordingModelTypeChangeProcessor() {} - ~RecordingModelTypeChangeProcessor() override {} - - void Put(const std::string& client_tag, - std::unique_ptr<EntityData> entity_data, - MetadataChangeList* metadata_changes) override { - put_map_.insert(std::make_pair(client_tag, std::move(entity_data))); - } - - void Delete(const std::string& client_tag, - MetadataChangeList* metadata_changes) override { - delete_set_.insert(client_tag); - } - - void OnMetadataLoaded(syncer::SyncError error, - std::unique_ptr<MetadataBatch> batch) override { - std::swap(metadata_, batch); - } - - const std::map<std::string, std::unique_ptr<EntityData>>& put_map() const { - return put_map_; - } - const std::set<std::string>& delete_set() const { return delete_set_; } - const MetadataBatch* metadata() const { return metadata_.get(); } - - private: - std::map<std::string, std::unique_ptr<EntityData>> put_map_; - std::set<std::string> delete_set_; - std::unique_ptr<MetadataBatch> metadata_; -}; - -} // namespace - -class DeviceInfoServiceTest : public testing::Test, - public DeviceInfoTracker::Observer { - protected: - DeviceInfoServiceTest() - : change_count_(0), - store_(ModelTypeStoreTestUtil::CreateInMemoryStoreForTest()), - local_device_(new LocalDeviceInfoProviderMock()) { - local_device_->Initialize(CreateDeviceInfo()); - } - - ~DeviceInfoServiceTest() override { - // Some tests may never initialize the service. - if (service_) - service_->RemoveObserver(this); - - // Force all remaining (store) tasks to execute so we don't leak memory. - base::RunLoop().RunUntilIdle(); - } - - void OnDeviceInfoChange() override { change_count_++; } - - std::unique_ptr<ModelTypeChangeProcessor> CreateModelTypeChangeProcessor( - syncer::ModelType type, - ModelTypeService* service) { - processor_ = new RecordingModelTypeChangeProcessor(); - return base::WrapUnique(processor_); - } - - // Initialized the service based on the current local device and store. Can - // only be called once per run, as it passes |store_|. - void InitializeService() { - ASSERT_TRUE(store_); - service_.reset(new DeviceInfoService( - local_device_.get(), - base::Bind(&ModelTypeStoreTestUtil::MoveStoreToCallback, - base::Passed(&store_)), - base::Bind(&DeviceInfoServiceTest::CreateModelTypeChangeProcessor, - base::Unretained(this)))); - service_->AddObserver(this); - } - - void OnSyncStarting() { - service()->OnSyncStarting(&error_handler_, StartCallback()); - } - - // Creates the service and runs any outstanding tasks. This will typically - // cause all initialization callbacks between the sevice and store to fire. - void InitializeAndPump() { - InitializeService(); - base::RunLoop().RunUntilIdle(); - } - - // Creates the service, runs any outstanding tasks, and then indicates to the - // service that sync wants to start and forces the processor to be created. - void InitializeAndPumpAndStart() { - InitializeAndPump(); - OnSyncStarting(); - ASSERT_TRUE(processor_); - } - - // Generates a specifics object with slightly differing values. Will generate - // the same values on each run of a test because a simple counter is used to - // vary field values. - DeviceInfoSpecifics GenerateTestSpecifics() { - int label = ++generated_count_; - DeviceInfoSpecifics specifics; - specifics.set_cache_guid(base::StringPrintf("cache guid %d", label)); - specifics.set_client_name(base::StringPrintf("client name %d", label)); - specifics.set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_LINUX); - specifics.set_sync_user_agent( - base::StringPrintf("sync user agent %d", label)); - specifics.set_chrome_version( - base::StringPrintf("chrome version %d", label)); - specifics.set_signin_scoped_device_id( - base::StringPrintf("signin scoped device id %d", label)); - return specifics; - } - - std::unique_ptr<DeviceInfoSpecifics> CopyToSpecifics(const DeviceInfo& info) { - return DeviceInfoService::CopyToSpecifics(info); - } - - // Override to allow specific cache guids. - DeviceInfoSpecifics GenerateTestSpecifics(const std::string& guid) { - DeviceInfoSpecifics specifics(GenerateTestSpecifics()); - specifics.set_cache_guid(guid); - return specifics; - } - - // Helper method to reduce duplicated code between tests. Wraps the given - // specifics object in an EntityData and EntityChange of type ACTION_ADD, and - // pushes them onto the given change list. The corresponding client tag the - // service determines is returned. Instance method because we need access to - // service to generate the tag. - std::string PushBackEntityChangeAdd(const DeviceInfoSpecifics& specifics, - EntityChangeList* changes) { - EntityDataPtr ptr = SpecificsToEntity(specifics); - const std::string tag = service()->GetClientTag(ptr.value()); - changes->push_back(EntityChange::CreateAdd(tag, ptr)); - return tag; - } - - // Allows access to the store before that will ultimately be used to - // initialize the service. - ModelTypeStore* store() { - EXPECT_TRUE(store_); - return store_.get(); - } - - // Get the number of times the service notifies observers of changes. - int change_count() { return change_count_; } - - // Allows overriding the provider before the service is initialized. - void set_local_device(std::unique_ptr<LocalDeviceInfoProviderMock> provider) { - ASSERT_FALSE(service_); - std::swap(local_device_, provider); - } - LocalDeviceInfoProviderMock* local_device() { return local_device_.get(); } - - // Allows access to the service after InitializeService() is called. - DeviceInfoService* service() { - EXPECT_TRUE(service_); - return service_.get(); - } - - RecordingModelTypeChangeProcessor* processor() { - EXPECT_TRUE(processor_); - return processor_; - } - - // Should only be called after the service has been initialized. Will first - // recover the service's store, so another can be initialized later, and then - // deletes the service. - void PumpAndShutdown() { - ASSERT_TRUE(service_); - base::RunLoop().RunUntilIdle(); - std::swap(store_, service_->store_); - service_->RemoveObserver(this); - service_.reset(); - } - - void RestartService() { - PumpAndShutdown(); - InitializeAndPump(); - } - - Time GetLastUpdateTime(const DeviceInfoSpecifics& specifics) { - return DeviceInfoService::GetLastUpdateTime(specifics); - } - - private: - int change_count_; - - // In memory model type store needs a MessageLoop. - base::MessageLoop message_loop_; - - // Holds the store while the service is not initialized. - std::unique_ptr<ModelTypeStore> store_; - - std::unique_ptr<LocalDeviceInfoProviderMock> local_device_; - - // Mock error handler passed to the processor. - syncer::DataTypeErrorHandlerMock error_handler_; - - // Not initialized immediately (upon test's constructor). This allows each - // test case to modify the dependencies the service will be constructed with. - std::unique_ptr<DeviceInfoService> service_; - - // A non-owning pointer to the processor given to the service. Will be nullptr - // before being given to the service, to make ownership easier. - RecordingModelTypeChangeProcessor* processor_ = nullptr; - - // A monotonically increasing label for generated specifics objects with data - // that is slightly different from eachother. - int generated_count_ = 0; -}; - -namespace { - -TEST_F(DeviceInfoServiceTest, EmptyDataReconciliation) { - InitializeAndPump(); - ASSERT_EQ(0u, service()->GetAllDeviceInfo().size()); - OnSyncStarting(); - ScopedVector<DeviceInfo> all_device_info(service()->GetAllDeviceInfo()); - ASSERT_EQ(1u, all_device_info.size()); - ASSERT_TRUE( - local_device()->GetLocalDeviceInfo()->Equals(*all_device_info[0])); -} - -TEST_F(DeviceInfoServiceTest, EmptyDataReconciliationSlowLoad) { - InitializeService(); - OnSyncStarting(); - ASSERT_EQ(0u, service()->GetAllDeviceInfo().size()); - base::RunLoop().RunUntilIdle(); - ScopedVector<DeviceInfo> all_device_info(service()->GetAllDeviceInfo()); - ASSERT_EQ(1u, all_device_info.size()); - ASSERT_TRUE( - local_device()->GetLocalDeviceInfo()->Equals(*all_device_info[0])); -} - -TEST_F(DeviceInfoServiceTest, LocalProviderSubscription) { - set_local_device(base::WrapUnique(new LocalDeviceInfoProviderMock())); - InitializeAndPumpAndStart(); - - ASSERT_EQ(0u, service()->GetAllDeviceInfo().size()); - local_device()->Initialize(CreateDeviceInfo()); - base::RunLoop().RunUntilIdle(); - - ScopedVector<DeviceInfo> all_device_info(service()->GetAllDeviceInfo()); - ASSERT_EQ(1u, all_device_info.size()); - ASSERT_TRUE( - local_device()->GetLocalDeviceInfo()->Equals(*all_device_info[0])); -} - -// Metadata shouldn't be loaded before the provider is initialized. -TEST_F(DeviceInfoServiceTest, LocalProviderInitRace) { - set_local_device(base::WrapUnique(new LocalDeviceInfoProviderMock())); - InitializeAndPump(); - OnSyncStarting(); - EXPECT_FALSE(processor()->metadata()); - - ASSERT_EQ(0u, service()->GetAllDeviceInfo().size()); - local_device()->Initialize(CreateDeviceInfo()); - base::RunLoop().RunUntilIdle(); - - ScopedVector<DeviceInfo> all_device_info(service()->GetAllDeviceInfo()); - ASSERT_EQ(1u, all_device_info.size()); - ASSERT_TRUE( - local_device()->GetLocalDeviceInfo()->Equals(*all_device_info[0])); - - EXPECT_TRUE(processor()->metadata()); -} - -TEST_F(DeviceInfoServiceTest, GetClientTagNormal) { - InitializeService(); - const std::string guid = "abc"; - EntitySpecifics entity_specifics; - entity_specifics.mutable_device_info()->set_cache_guid(guid); - EntityData entity_data; - entity_data.specifics = entity_specifics; - EXPECT_EQ(CacheGuidToTag(guid), service()->GetClientTag(entity_data)); -} - -TEST_F(DeviceInfoServiceTest, GetClientTagEmpty) { - InitializeService(); - EntitySpecifics entity_specifics; - entity_specifics.mutable_device_info(); - EntityData entity_data; - entity_data.specifics = entity_specifics; - EXPECT_EQ(CacheGuidToTag(""), service()->GetClientTag(entity_data)); -} - -TEST_F(DeviceInfoServiceTest, TestWithLocalData) { - std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch(); - DeviceInfoSpecifics specifics(GenerateTestSpecifics()); - store()->WriteData(batch.get(), specifics.cache_guid(), - specifics.SerializeAsString()); - store()->CommitWriteBatch(std::move(batch), - base::Bind(&AssertResultIsSuccess)); - - InitializeAndPump(); - - ScopedVector<DeviceInfo> all_device_info(service()->GetAllDeviceInfo()); - ASSERT_EQ(1u, all_device_info.size()); - AssertEqual(specifics, *all_device_info[0]); - AssertEqual(specifics, - *service()->GetDeviceInfo(specifics.cache_guid()).get()); -} - -TEST_F(DeviceInfoServiceTest, TestWithLocalMetadata) { - std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch(); - DataTypeState state; - state.set_encryption_key_name("ekn"); - store()->WriteGlobalMetadata(batch.get(), state.SerializeAsString()); - store()->CommitWriteBatch(std::move(batch), - base::Bind(&AssertResultIsSuccess)); - InitializeAndPump(); - ScopedVector<DeviceInfo> all_device_info(service()->GetAllDeviceInfo()); - ASSERT_EQ(1u, all_device_info.size()); - ASSERT_TRUE( - local_device()->GetLocalDeviceInfo()->Equals(*all_device_info[0])); - EXPECT_EQ(1u, processor()->put_map().size()); -} - -TEST_F(DeviceInfoServiceTest, TestWithLocalDataAndMetadata) { - std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch(); - DeviceInfoSpecifics specifics(GenerateTestSpecifics()); - store()->WriteData(batch.get(), specifics.cache_guid(), - specifics.SerializeAsString()); - DataTypeState state; - state.set_encryption_key_name("ekn"); - store()->WriteGlobalMetadata(batch.get(), state.SerializeAsString()); - store()->CommitWriteBatch(std::move(batch), - base::Bind(&AssertResultIsSuccess)); - - InitializeAndPump(); - - ScopedVector<DeviceInfo> all_device_info(service()->GetAllDeviceInfo()); - ASSERT_EQ(2u, all_device_info.size()); - AssertEqual(specifics, - *service()->GetDeviceInfo(specifics.cache_guid()).get()); - ASSERT_TRUE(processor()->metadata()); - ASSERT_EQ(state.encryption_key_name(), - processor()->metadata()->GetDataTypeState().encryption_key_name()); -} - -TEST_F(DeviceInfoServiceTest, GetData) { - std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch(); - DeviceInfoSpecifics specifics1(GenerateTestSpecifics()); - DeviceInfoSpecifics specifics2(GenerateTestSpecifics()); - DeviceInfoSpecifics specifics3(GenerateTestSpecifics()); - store()->WriteData(batch.get(), specifics1.cache_guid(), - specifics1.SerializeAsString()); - store()->WriteData(batch.get(), specifics2.cache_guid(), - specifics2.SerializeAsString()); - store()->WriteData(batch.get(), specifics3.cache_guid(), - specifics3.SerializeAsString()); - store()->CommitWriteBatch(std::move(batch), - base::Bind(&AssertResultIsSuccess)); - - InitializeAndPump(); - - std::map<std::string, DeviceInfoSpecifics> expected; - expected[CacheGuidToTag(specifics1.cache_guid())] = specifics1; - expected[CacheGuidToTag(specifics3.cache_guid())] = specifics3; - ClientTagList client_tags; - client_tags.push_back(CacheGuidToTag(specifics1.cache_guid())); - client_tags.push_back(CacheGuidToTag(specifics3.cache_guid())); - service()->GetData(client_tags, - base::Bind(&AssertExpectedFromDataBatch, expected)); -} - -TEST_F(DeviceInfoServiceTest, GetDataMissing) { - InitializeAndPump(); - std::map<std::string, DeviceInfoSpecifics> expected; - ClientTagList client_tags; - client_tags.push_back(CacheGuidToTag("tag1")); - service()->GetData(client_tags, - base::Bind(&AssertExpectedFromDataBatch, expected)); -} - -TEST_F(DeviceInfoServiceTest, GetAllData) { - std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch(); - DeviceInfoSpecifics specifics1(GenerateTestSpecifics()); - DeviceInfoSpecifics specifics2(GenerateTestSpecifics()); - const std::string& tag1 = CacheGuidToTag(specifics1.cache_guid()); - const std::string& tag2 = CacheGuidToTag(specifics2.cache_guid()); - store()->WriteData(batch.get(), specifics1.cache_guid(), - specifics1.SerializeAsString()); - store()->WriteData(batch.get(), specifics2.cache_guid(), - specifics2.SerializeAsString()); - store()->CommitWriteBatch(std::move(batch), - base::Bind(&AssertResultIsSuccess)); - - InitializeAndPump(); - - std::map<std::string, DeviceInfoSpecifics> expected; - expected[tag1] = specifics1; - expected[tag2] = specifics2; - ClientTagList client_tags; - client_tags.push_back(tag1); - client_tags.push_back(tag2); - service()->GetData(client_tags, - base::Bind(&AssertExpectedFromDataBatch, expected)); -} - -TEST_F(DeviceInfoServiceTest, ApplySyncChangesEmpty) { - InitializeAndPump(); - const SyncError error = service()->ApplySyncChanges( - service()->CreateMetadataChangeList(), EntityChangeList()); - EXPECT_FALSE(error.IsSet()); - EXPECT_EQ(0, change_count()); -} - -TEST_F(DeviceInfoServiceTest, ApplySyncChangesInMemory) { - InitializeAndPump(); - - DeviceInfoSpecifics specifics = GenerateTestSpecifics(); - EntityChangeList add_changes; - const std::string tag = PushBackEntityChangeAdd(specifics, &add_changes); - SyncError error = service()->ApplySyncChanges( - service()->CreateMetadataChangeList(), add_changes); - - EXPECT_FALSE(error.IsSet()); - std::unique_ptr<DeviceInfo> info = - service()->GetDeviceInfo(specifics.cache_guid()); - ASSERT_TRUE(info); - AssertEqual(specifics, *info.get()); - EXPECT_EQ(1, change_count()); - - EntityChangeList delete_changes; - delete_changes.push_back(EntityChange::CreateDelete(tag)); - error = service()->ApplySyncChanges(service()->CreateMetadataChangeList(), - delete_changes); - - EXPECT_FALSE(error.IsSet()); - EXPECT_FALSE(service()->GetDeviceInfo(specifics.cache_guid())); - EXPECT_EQ(2, change_count()); -} - -TEST_F(DeviceInfoServiceTest, ApplySyncChangesStore) { - InitializeAndPump(); - - DeviceInfoSpecifics specifics = GenerateTestSpecifics(); - EntityChangeList data_changes; - const std::string tag = PushBackEntityChangeAdd(specifics, &data_changes); - DataTypeState state; - state.set_encryption_key_name("ekn"); - std::unique_ptr<MetadataChangeList> metadata_changes( - service()->CreateMetadataChangeList()); - metadata_changes->UpdateDataTypeState(state); - - const SyncError error = - service()->ApplySyncChanges(std::move(metadata_changes), data_changes); - EXPECT_FALSE(error.IsSet()); - EXPECT_EQ(1, change_count()); - - RestartService(); - - std::unique_ptr<DeviceInfo> info = - service()->GetDeviceInfo(specifics.cache_guid()); - ASSERT_TRUE(info); - AssertEqual(specifics, *info.get()); - - EXPECT_TRUE(processor()->metadata()); - EXPECT_EQ(state.encryption_key_name(), - processor()->metadata()->GetDataTypeState().encryption_key_name()); -} - -TEST_F(DeviceInfoServiceTest, ApplySyncChangesWithLocalGuid) { - InitializeAndPumpAndStart(); - - // The point of this test is to try to apply remote changes that have the same - // cache guid as the local device. The service should ignore these changes - // since only it should be performing writes on its data. - DeviceInfoSpecifics specifics = - GenerateTestSpecifics(local_device()->GetLocalDeviceInfo()->guid()); - EntityChangeList change_list; - const std::string tag = PushBackEntityChangeAdd(specifics, &change_list); - - // Should have a single change from reconciliation. - EXPECT_TRUE( - service()->GetDeviceInfo(local_device()->GetLocalDeviceInfo()->guid())); - EXPECT_EQ(1, change_count()); - // Ensure |last_updated| is about now, plus or minus a little bit. - Time last_updated( - syncer::ProtoTimeToTime(processor() - ->put_map() - .begin() - ->second->specifics.device_info() - .last_updated_timestamp())); - EXPECT_LT(Time::Now() - TimeDelta::FromMinutes(1), last_updated); - EXPECT_GT(Time::Now() + TimeDelta::FromMinutes(1), last_updated); - - EXPECT_FALSE( - service() - ->ApplySyncChanges(service()->CreateMetadataChangeList(), change_list) - .IsSet()); - EXPECT_EQ(1, change_count()); - - change_list.clear(); - change_list.push_back(EntityChange::CreateDelete(tag)); - EXPECT_FALSE( - service() - ->ApplySyncChanges(service()->CreateMetadataChangeList(), change_list) - .IsSet()); - EXPECT_EQ(1, change_count()); -} - -TEST_F(DeviceInfoServiceTest, ApplyDeleteNonexistent) { - InitializeAndPumpAndStart(); - EXPECT_EQ(1, change_count()); - EntityChangeList delete_changes; - delete_changes.push_back(EntityChange::CreateDelete(CacheGuidToTag("tag"))); - const SyncError error = service()->ApplySyncChanges( - service()->CreateMetadataChangeList(), delete_changes); - EXPECT_FALSE(error.IsSet()); - EXPECT_EQ(1, change_count()); -} - -TEST_F(DeviceInfoServiceTest, MergeEmpty) { - InitializeAndPumpAndStart(); - EXPECT_EQ(1, change_count()); - const SyncError error = service()->MergeSyncData( - service()->CreateMetadataChangeList(), EntityDataMap()); - EXPECT_FALSE(error.IsSet()); - EXPECT_EQ(1, change_count()); - EXPECT_EQ(1u, processor()->put_map().size()); - EXPECT_EQ(0u, processor()->delete_set().size()); -} - -TEST_F(DeviceInfoServiceTest, MergeWithData) { - const DeviceInfoSpecifics unique_local(GenerateTestSpecifics("unique_local")); - const DeviceInfoSpecifics conflict_local(GenerateTestSpecifics("conflict")); - DeviceInfoSpecifics conflict_remote(GenerateTestSpecifics("conflict")); - DeviceInfoSpecifics unique_remote(GenerateTestSpecifics("unique_remote")); - - std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch(); - store()->WriteData(batch.get(), unique_local.cache_guid(), - unique_local.SerializeAsString()); - store()->WriteData(batch.get(), conflict_local.cache_guid(), - conflict_local.SerializeAsString()); - store()->CommitWriteBatch(std::move(batch), - base::Bind(&AssertResultIsSuccess)); - - InitializeAndPumpAndStart(); - EXPECT_EQ(1, change_count()); - - EntityDataMap remote_input; - remote_input[CacheGuidToTag(conflict_remote.cache_guid())] = - SpecificsToEntity(conflict_remote); - remote_input[CacheGuidToTag(unique_remote.cache_guid())] = - SpecificsToEntity(unique_remote); - - DataTypeState state; - state.set_encryption_key_name("ekn"); - std::unique_ptr<MetadataChangeList> metadata_changes( - service()->CreateMetadataChangeList()); - metadata_changes->UpdateDataTypeState(state); - - const SyncError error = - service()->MergeSyncData(std::move(metadata_changes), remote_input); - EXPECT_FALSE(error.IsSet()); - EXPECT_EQ(2, change_count()); - - // The remote should beat the local in conflict. - EXPECT_EQ(4u, service()->GetAllDeviceInfo().size()); - AssertEqual(unique_local, *service()->GetDeviceInfo("unique_local").get()); - AssertEqual(unique_remote, *service()->GetDeviceInfo("unique_remote").get()); - AssertEqual(conflict_remote, *service()->GetDeviceInfo("conflict").get()); - - // Service should have told the processor about the existance of unique_local. - EXPECT_TRUE(processor()->delete_set().empty()); - EXPECT_EQ(2u, processor()->put_map().size()); - const auto& it = processor()->put_map().find(CacheGuidToTag("unique_local")); - ASSERT_NE(processor()->put_map().end(), it); - AssertEqual(unique_local, it->second->specifics.device_info()); - - RestartService(); - ASSERT_EQ(state.encryption_key_name(), - processor()->metadata()->GetDataTypeState().encryption_key_name()); -} - -TEST_F(DeviceInfoServiceTest, MergeLocalGuid) { - const DeviceInfo* local_device_info = local_device()->GetLocalDeviceInfo(); - std::unique_ptr<DeviceInfoSpecifics> specifics( - CopyToSpecifics(*local_device_info)); - specifics->set_last_updated_timestamp(syncer::TimeToProtoTime(Time::Now())); - const std::string guid = local_device_info->guid(); - - std::unique_ptr<WriteBatch> batch = store()->CreateWriteBatch(); - store()->WriteData(batch.get(), guid, specifics->SerializeAsString()); - store()->CommitWriteBatch(std::move(batch), - base::Bind(&AssertResultIsSuccess)); - - InitializeAndPumpAndStart(); - - EntityDataMap remote_input; - remote_input[CacheGuidToTag(guid)] = SpecificsToEntity(*specifics); - - const SyncError error = service()->MergeSyncData( - service()->CreateMetadataChangeList(), remote_input); - EXPECT_FALSE(error.IsSet()); - EXPECT_EQ(0, change_count()); - EXPECT_EQ(1u, service()->GetAllDeviceInfo().size()); - EXPECT_TRUE(processor()->delete_set().empty()); - EXPECT_TRUE(processor()->put_map().empty()); -} - -TEST_F(DeviceInfoServiceTest, GetLastUpdateTime) { - Time time1(Time() + TimeDelta::FromDays(1)); - - DeviceInfoSpecifics specifics1(GenerateTestSpecifics()); - DeviceInfoSpecifics specifics2(GenerateTestSpecifics()); - specifics2.set_last_updated_timestamp(syncer::TimeToProtoTime(time1)); - - EXPECT_EQ(Time(), GetLastUpdateTime(specifics1)); - EXPECT_EQ(time1, GetLastUpdateTime(specifics2)); -} - -TEST_F(DeviceInfoServiceTest, CountActiveDevices) { - InitializeAndPump(); - EXPECT_EQ(0, service()->CountActiveDevices()); - - DeviceInfoSpecifics specifics = - GenerateTestSpecifics(local_device()->GetLocalDeviceInfo()->guid()); - EntityChangeList change_list; - PushBackEntityChangeAdd(specifics, &change_list); - service()->ApplySyncChanges(service()->CreateMetadataChangeList(), - change_list); - EXPECT_EQ(0, service()->CountActiveDevices()); - - change_list.clear(); - specifics.set_last_updated_timestamp(syncer::TimeToProtoTime(Time::Now())); - PushBackEntityChangeAdd(specifics, &change_list); - service()->ApplySyncChanges(service()->CreateMetadataChangeList(), - change_list); - EXPECT_EQ(0, service()->CountActiveDevices()); - - change_list.clear(); - specifics.set_cache_guid("non-local"); - PushBackEntityChangeAdd(specifics, &change_list); - service()->ApplySyncChanges(service()->CreateMetadataChangeList(), - change_list); - EXPECT_EQ(1, service()->CountActiveDevices()); -} - -} // namespace - -} // namespace sync_driver_v2
diff --git a/components/sync_driver/device_info_sync_service.cc b/components/sync_driver/device_info_sync_service.cc deleted file mode 100644 index e0520c2..0000000 --- a/components/sync_driver/device_info_sync_service.cc +++ /dev/null
@@ -1,342 +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 "components/sync_driver/device_info_sync_service.h" - -#include <stddef.h> - -#include <algorithm> -#include <utility> - -#include "base/memory/ptr_util.h" -#include "base/time/time.h" -#include "components/sync/api/sync_change.h" -#include "components/sync/base/time.h" -#include "components/sync/protocol/sync.pb.h" -#include "components/sync_driver/device_info_util.h" -#include "components/sync_driver/local_device_info_provider.h" - -namespace sync_driver { - -using base::Time; -using base::TimeDelta; -using syncer::ModelType; -using syncer::SyncChange; -using syncer::SyncChangeList; -using syncer::SyncChangeProcessor; -using syncer::SyncData; -using syncer::SyncDataList; -using syncer::SyncErrorFactory; -using syncer::SyncMergeResult; - -DeviceInfoSyncService::DeviceInfoSyncService( - LocalDeviceInfoProvider* local_device_info_provider) - : local_device_info_provider_(local_device_info_provider) { - DCHECK(local_device_info_provider); -} - -DeviceInfoSyncService::~DeviceInfoSyncService() { -} - -SyncMergeResult DeviceInfoSyncService::MergeDataAndStartSyncing( - ModelType type, - const SyncDataList& initial_sync_data, - std::unique_ptr<SyncChangeProcessor> sync_processor, - std::unique_ptr<SyncErrorFactory> error_handler) { - DCHECK(sync_processor.get()); - DCHECK(error_handler.get()); - DCHECK_EQ(type, syncer::DEVICE_INFO); - - DCHECK(!IsSyncing()); - - sync_processor_ = std::move(sync_processor); - error_handler_ = std::move(error_handler); - - // Initialization should be completed before this type is enabled - // and local device info must be available. - const DeviceInfo* local_device_info = - local_device_info_provider_->GetLocalDeviceInfo(); - DCHECK(local_device_info != NULL); - - // Indicates whether a local device has been added or updated. - // |change_type| defaults to ADD and might be changed to - // UPDATE to INVALID down below if the initial data contains - // data matching the local device ID. - SyncChange::SyncChangeType change_type = SyncChange::ACTION_ADD; - TimeDelta pulse_delay; - size_t num_items_new = 0; - size_t num_items_updated = 0; - - // Iterate over all initial sync data and copy it to the cache. - for (SyncDataList::const_iterator iter = initial_sync_data.begin(); - iter != initial_sync_data.end(); - ++iter) { - DCHECK_EQ(syncer::DEVICE_INFO, iter->GetDataType()); - - const std::string& id = iter->GetSpecifics().device_info().cache_guid(); - - if (id == local_device_info->guid()) { - // |initial_sync_data| contains data matching the local device. - std::unique_ptr<DeviceInfo> synced_local_device_info = - base::WrapUnique(CreateDeviceInfo(*iter)); - - pulse_delay = DeviceInfoUtil::CalculatePulseDelay( - GetLastUpdateTime(*iter), Time::Now()); - // Store the synced device info for the local device only if - // it is the same as the local info. Otherwise store the local - // device info and issue a change further below after finishing - // processing the |initial_sync_data|. - if (synced_local_device_info->Equals(*local_device_info) && - !pulse_delay.is_zero()) { - change_type = SyncChange::ACTION_INVALID; - } else { - num_items_updated++; - change_type = SyncChange::ACTION_UPDATE; - continue; - } - } else { - // A new device that doesn't match the local device. - num_items_new++; - } - - StoreSyncData(id, *iter); - } - - syncer::SyncMergeResult result(type); - - // If the SyncData for the local device is new or different then send it - // immediately, otherwise wait until the pulse interval has elapsed from the - // previous update. Regardless of the branch here we setup a timer loop with - // SendLocalData such that we continue pulsing every interval. - if (change_type == SyncChange::ACTION_INVALID) { - pulse_timer_.Start( - FROM_HERE, pulse_delay, - base::Bind(&DeviceInfoSyncService::SendLocalData, - base::Unretained(this), SyncChange::ACTION_UPDATE)); - } else { - SendLocalData(change_type); - } - - result.set_num_items_before_association(1); - result.set_num_items_after_association(all_data_.size()); - result.set_num_items_added(num_items_new); - result.set_num_items_modified(num_items_updated); - result.set_num_items_deleted(0); - - NotifyObservers(); - - return result; -} - -bool DeviceInfoSyncService::IsSyncing() const { - return !all_data_.empty(); -} - -void DeviceInfoSyncService::StopSyncing(syncer::ModelType type) { - bool was_syncing = IsSyncing(); - - pulse_timer_.Stop(); - all_data_.clear(); - sync_processor_.reset(); - error_handler_.reset(); - - if (was_syncing) { - NotifyObservers(); - } -} - -SyncDataList DeviceInfoSyncService::GetAllSyncData( - syncer::ModelType type) const { - SyncDataList list; - - for (SyncDataMap::const_iterator iter = all_data_.begin(); - iter != all_data_.end(); - ++iter) { - list.push_back(iter->second); - } - - return list; -} - -syncer::SyncError DeviceInfoSyncService::ProcessSyncChanges( - const tracked_objects::Location& from_here, - const SyncChangeList& change_list) { - syncer::SyncError error; - - DCHECK(local_device_info_provider_->GetLocalDeviceInfo()); - const std::string& local_device_id = - local_device_info_provider_->GetLocalDeviceInfo()->guid(); - - bool has_changes = false; - - // Iterate over all chanages and merge entries. - for (SyncChangeList::const_iterator iter = change_list.begin(); - iter != change_list.end(); - ++iter) { - const SyncData& sync_data = iter->sync_data(); - DCHECK_EQ(syncer::DEVICE_INFO, sync_data.GetDataType()); - - const std::string& client_id = - sync_data.GetSpecifics().device_info().cache_guid(); - // Ignore device info matching the local device. - if (local_device_id == client_id) { - DVLOG(1) << "Ignoring sync changes for the local DEVICE_INFO"; - continue; - } - - if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) { - has_changes = true; - DeleteSyncData(client_id); - } else if (iter->change_type() == syncer::SyncChange::ACTION_UPDATE || - iter->change_type() == syncer::SyncChange::ACTION_ADD) { - has_changes = true; - StoreSyncData(client_id, sync_data); - } else { - error.Reset(FROM_HERE, "Invalid action received.", syncer::DEVICE_INFO); - } - } - - if (has_changes) { - NotifyObservers(); - } - - return error; -} - -std::unique_ptr<DeviceInfo> DeviceInfoSyncService::GetDeviceInfo( - const std::string& client_id) const { - SyncDataMap::const_iterator iter = all_data_.find(client_id); - if (iter == all_data_.end()) { - return std::unique_ptr<DeviceInfo>(); - } - - return base::WrapUnique(CreateDeviceInfo(iter->second)); -} - -ScopedVector<DeviceInfo> DeviceInfoSyncService::GetAllDeviceInfo() const { - ScopedVector<DeviceInfo> list; - - for (SyncDataMap::const_iterator iter = all_data_.begin(); - iter != all_data_.end(); - ++iter) { - list.push_back(CreateDeviceInfo(iter->second)); - } - - return list; -} - -void DeviceInfoSyncService::AddObserver(Observer* observer) { - observers_.AddObserver(observer); -} - -void DeviceInfoSyncService::RemoveObserver(Observer* observer) { - observers_.RemoveObserver(observer); -} - -int DeviceInfoSyncService::CountActiveDevices() const { - return CountActiveDevices(Time::Now()); -} - -void DeviceInfoSyncService::NotifyObservers() { - FOR_EACH_OBSERVER(Observer, observers_, OnDeviceInfoChange()); -} - -SyncData DeviceInfoSyncService::CreateLocalData(const DeviceInfo* info) { - sync_pb::EntitySpecifics entity; - sync_pb::DeviceInfoSpecifics& specifics = *entity.mutable_device_info(); - - specifics.set_cache_guid(info->guid()); - specifics.set_client_name(info->client_name()); - specifics.set_chrome_version(info->chrome_version()); - specifics.set_sync_user_agent(info->sync_user_agent()); - specifics.set_device_type(info->device_type()); - specifics.set_signin_scoped_device_id(info->signin_scoped_device_id()); - specifics.set_last_updated_timestamp(syncer::TimeToProtoTime(Time::Now())); - - return CreateLocalData(entity); -} - -SyncData DeviceInfoSyncService::CreateLocalData( - const sync_pb::EntitySpecifics& entity) { - const sync_pb::DeviceInfoSpecifics& specifics = entity.device_info(); - return SyncData::CreateLocalData(DeviceInfoUtil::SpecificsToTag(specifics), - specifics.client_name(), entity); -} - -DeviceInfo* DeviceInfoSyncService::CreateDeviceInfo( - const syncer::SyncData& sync_data) { - const sync_pb::DeviceInfoSpecifics& specifics = - sync_data.GetSpecifics().device_info(); - - return new DeviceInfo(specifics.cache_guid(), - specifics.client_name(), - specifics.chrome_version(), - specifics.sync_user_agent(), - specifics.device_type(), - specifics.signin_scoped_device_id()); -} - -void DeviceInfoSyncService::StoreSyncData(const std::string& client_id, - const SyncData& sync_data) { - DVLOG(1) << "Storing DEVICE_INFO for " - << sync_data.GetSpecifics().device_info().client_name() - << " with ID " << client_id; - all_data_[client_id] = sync_data; -} - -void DeviceInfoSyncService::DeleteSyncData(const std::string& client_id) { - SyncDataMap::iterator iter = all_data_.find(client_id); - if (iter != all_data_.end()) { - DVLOG(1) << "Deleting DEVICE_INFO for " - << iter->second.GetSpecifics().device_info().client_name() - << " with ID " << client_id; - all_data_.erase(iter); - } -} - -void DeviceInfoSyncService::SendLocalData( - const SyncChange::SyncChangeType change_type) { - DCHECK_NE(change_type, SyncChange::ACTION_INVALID); - DCHECK(sync_processor_); - - const DeviceInfo* device_info = - local_device_info_provider_->GetLocalDeviceInfo(); - const SyncData& data = CreateLocalData(device_info); - StoreSyncData(device_info->guid(), data); - - SyncChangeList change_list; - change_list.push_back(SyncChange(FROM_HERE, change_type, data)); - sync_processor_->ProcessSyncChanges(FROM_HERE, change_list); - - pulse_timer_.Start( - FROM_HERE, DeviceInfoUtil::kPulseInterval, - base::Bind(&DeviceInfoSyncService::SendLocalData, base::Unretained(this), - SyncChange::ACTION_UPDATE)); -} - -int DeviceInfoSyncService::CountActiveDevices(const Time now) const { - return std::count_if(all_data_.begin(), all_data_.end(), - [now](SyncDataMap::const_reference pair) { - return DeviceInfoUtil::IsActive( - GetLastUpdateTime(pair.second), now); - }); -} - -// static -Time DeviceInfoSyncService::GetLastUpdateTime(const SyncData& device_info) { - if (device_info.GetSpecifics().device_info().has_last_updated_timestamp()) { - return syncer::ProtoTimeToTime( - device_info.GetSpecifics().device_info().last_updated_timestamp()); - } else if (!device_info.IsLocal()) { - // If there is no |last_updated_timestamp| present, fallback to mod time. - return syncer::SyncDataRemote(device_info).GetModifiedTime(); - } else { - // We shouldn't reach this point for remote data, so this means we're likely - // looking at the local device info. Using a long ago time is perfect, since - // the desired behavior is to update/pulse our data as soon as possible. - return Time(); - } -} - -} // namespace sync_driver
diff --git a/components/sync_driver/device_info_sync_service.h b/components/sync_driver/device_info_sync_service.h deleted file mode 100644 index a831ce9b..0000000 --- a/components/sync_driver/device_info_sync_service.h +++ /dev/null
@@ -1,111 +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 COMPONENTS_SYNC_DRIVER_DEVICE_INFO_SYNC_SERVICE_H_ -#define COMPONENTS_SYNC_DRIVER_DEVICE_INFO_SYNC_SERVICE_H_ - -#include <stdint.h> - -#include <map> -#include <memory> -#include <string> - -#include "base/macros.h" -#include "base/memory/scoped_vector.h" -#include "base/observer_list.h" -#include "base/time/time.h" -#include "base/timer/timer.h" -#include "components/sync/api/sync_change.h" -#include "components/sync/api/sync_change_processor.h" -#include "components/sync/api/sync_data.h" -#include "components/sync/api/sync_error_factory.h" -#include "components/sync/api/syncable_service.h" -#include "components/sync_driver/device_info_tracker.h" - -namespace sync_driver { - -class LocalDeviceInfoProvider; - -// SyncableService implementation for DEVICE_INFO model type. -class DeviceInfoSyncService : public syncer::SyncableService, - public DeviceInfoTracker { - public: - explicit DeviceInfoSyncService( - LocalDeviceInfoProvider* local_device_info_provider); - ~DeviceInfoSyncService() override; - - // syncer::SyncableService implementation. - syncer::SyncMergeResult MergeDataAndStartSyncing( - syncer::ModelType type, - const syncer::SyncDataList& initial_sync_data, - std::unique_ptr<syncer::SyncChangeProcessor> sync_processor, - std::unique_ptr<syncer::SyncErrorFactory> error_handler) override; - void StopSyncing(syncer::ModelType type) override; - syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override; - syncer::SyncError ProcessSyncChanges( - const tracked_objects::Location& from_here, - const syncer::SyncChangeList& change_list) override; - - // DeviceInfoTracker implementation. - bool IsSyncing() const override; - std::unique_ptr<DeviceInfo> GetDeviceInfo( - const std::string& client_id) const override; - ScopedVector<DeviceInfo> GetAllDeviceInfo() const override; - void AddObserver(Observer* observer) override; - void RemoveObserver(Observer* observer) override; - int CountActiveDevices() const override; - - private: - friend class DeviceInfoSyncServiceTest; - - // Create SyncData from local DeviceInfo. - syncer::SyncData CreateLocalData(const DeviceInfo* info); - // Create SyncData from EntitySpecifics. - static syncer::SyncData CreateLocalData( - const sync_pb::EntitySpecifics& entity); - - // Allocate new DeviceInfo from SyncData. - static DeviceInfo* CreateDeviceInfo(const syncer::SyncData& sync_data); - // Store SyncData in the cache. - void StoreSyncData(const std::string& client_id, - const syncer::SyncData& sync_data); - // Delete SyncData from the cache. - void DeleteSyncData(const std::string& client_id); - // Notify all registered observers. - void NotifyObservers(); - - // Sends a copy of the current device's state to the processor/sync. - void SendLocalData(const syncer::SyncChange::SyncChangeType change_type); - - // Finds the number of active devices give the current time, which allows for - // better unit tests. - int CountActiveDevices(const base::Time now) const; - - // Find the timestamp for the last time this |device_info| was edited. - static base::Time GetLastUpdateTime(const syncer::SyncData& device_info); - - // |local_device_info_provider_| isn't owned. - const LocalDeviceInfoProvider* const local_device_info_provider_; - - // Receives ownership of |sync_processor_| and |error_handler_| in - // MergeDataAndStartSyncing() and destroy them in StopSyncing(). - std::unique_ptr<syncer::SyncChangeProcessor> sync_processor_; - std::unique_ptr<syncer::SyncErrorFactory> error_handler_; - - // Cache of all syncable and local data. - typedef std::map<std::string, syncer::SyncData> SyncDataMap; - SyncDataMap all_data_; - - // Registered observers, not owned. - base::ObserverList<Observer, true> observers_; - - // Used to update our local device info once every pulse interval. - base::OneShotTimer pulse_timer_; - - DISALLOW_COPY_AND_ASSIGN(DeviceInfoSyncService); -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_DEVICE_INFO_SYNC_SERVICE_H_
diff --git a/components/sync_driver/device_info_sync_service_unittest.cc b/components/sync_driver/device_info_sync_service_unittest.cc deleted file mode 100644 index c6f449b..0000000 --- a/components/sync_driver/device_info_sync_service_unittest.cc +++ /dev/null
@@ -1,603 +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 "components/sync_driver/device_info_sync_service.h" - -#include <stddef.h> -#include <stdint.h> - -#include <string> - -#include "base/message_loop/message_loop.h" -#include "components/sync/api/sync_change.h" -#include "components/sync/api/sync_change_processor.h" -#include "components/sync/api/sync_change_processor_wrapper_for_test.h" -#include "components/sync/api/sync_error_factory_mock.h" -#include "components/sync/base/time.h" -#include "components/sync/core/attachments/attachment_service_proxy_for_test.h" -#include "components/sync_driver/device_info_util.h" -#include "components/sync_driver/local_device_info_provider_mock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using base::Time; -using base::TimeDelta; -using syncer::AttachmentIdList; -using syncer::AttachmentServiceProxyForTest; -using syncer::ModelType; -using syncer::SyncChange; -using syncer::SyncChangeList; -using syncer::SyncChangeProcessor; -using syncer::SyncChangeProcessorWrapperForTest; -using syncer::SyncData; -using syncer::SyncDataList; -using syncer::SyncError; -using syncer::SyncErrorFactory; -using syncer::SyncErrorFactoryMock; -using syncer::SyncMergeResult; -using sync_pb::EntitySpecifics; - -namespace sync_driver { - -namespace { - -class TestChangeProcessor : public SyncChangeProcessor { - public: - TestChangeProcessor() {} - ~TestChangeProcessor() override {} - - // SyncChangeProcessor implementation. - // Store a copy of all the changes passed in so we can examine them later. - SyncError ProcessSyncChanges(const tracked_objects::Location& from_here, - const SyncChangeList& change_list) override { - change_list_ = change_list; - return SyncError(); - } - - // This method isn't used in these tests. - SyncDataList GetAllSyncData(ModelType type) const override { - return SyncDataList(); - } - - size_t change_list_size() const { return change_list_.size(); } - - SyncChange::SyncChangeType change_type_at(size_t index) const { - CHECK_LT(index, change_list_size()); - return change_list_[index].change_type(); - } - - const sync_pb::DeviceInfoSpecifics& device_info_at(size_t index) const { - CHECK_LT(index, change_list_size()); - return change_list_[index].sync_data().GetSpecifics().device_info(); - } - - const std::string& cache_guid_at(size_t index) const { - return device_info_at(index).cache_guid(); - } - - const std::string& client_name_at(size_t index) const { - return device_info_at(index).client_name(); - } - - private: - SyncChangeList change_list_; -}; - -} // namespace - -class DeviceInfoSyncServiceTest : public testing::Test, - public DeviceInfoTracker::Observer { - public: - DeviceInfoSyncServiceTest() : num_device_info_changed_callbacks_(0) {} - ~DeviceInfoSyncServiceTest() override {} - - void SetUp() override { - local_device_.reset(new LocalDeviceInfoProviderMock( - "guid_1", - "client_1", - "Chromium 10k", - "Chrome 10k", - sync_pb::SyncEnums_DeviceType_TYPE_LINUX, - "device_id")); - sync_service_.reset(new DeviceInfoSyncService(local_device_.get())); - sync_processor_.reset(new TestChangeProcessor()); - // Register observer - sync_service_->AddObserver(this); - } - - void TearDown() override { sync_service_->RemoveObserver(this); } - - void OnDeviceInfoChange() override { num_device_info_changed_callbacks_++; } - - std::unique_ptr<SyncChangeProcessor> PassProcessor() { - return std::unique_ptr<SyncChangeProcessor>( - new SyncChangeProcessorWrapperForTest(sync_processor_.get())); - } - - std::unique_ptr<SyncErrorFactory> CreateAndPassSyncErrorFactory() { - return std::unique_ptr<SyncErrorFactory>(new SyncErrorFactoryMock()); - } - - sync_pb::EntitySpecifics CreateEntitySpecifics( - const std::string& client_id, - const std::string& client_name) { - sync_pb::EntitySpecifics entity; - sync_pb::DeviceInfoSpecifics& specifics = *entity.mutable_device_info(); - - specifics.set_cache_guid(client_id); - specifics.set_client_name(client_name); - specifics.set_chrome_version("Chromium 10k"); - specifics.set_sync_user_agent("Chrome 10k"); - specifics.set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_LINUX); - specifics.set_signin_scoped_device_id("device_id"); - return entity; - } - - // Default |last_updated_timestamp| to now to avoid pulse update on merge. - SyncData CreateRemoteData(const std::string& client_id, - const std::string& client_name, - Time last_updated_timestamp = Time::Now()) { - sync_pb::EntitySpecifics entity( - CreateEntitySpecifics(client_id, client_name)); - entity.mutable_device_info()->set_last_updated_timestamp( - syncer::TimeToProtoTime(last_updated_timestamp)); - return SyncData::CreateRemoteData(1, entity, Time(), AttachmentIdList(), - AttachmentServiceProxyForTest::Create()); - } - - void AddInitialData(SyncDataList* sync_data_list, - const std::string& client_id, - const std::string& client_name) { - SyncData sync_data = CreateRemoteData(client_id, client_name); - sync_data_list->push_back(sync_data); - } - - void AddChange(SyncChangeList* change_list, - SyncChange::SyncChangeType change_type, - const std::string& client_id, - const std::string& client_name) { - SyncData sync_data = CreateRemoteData(client_id, client_name); - SyncChange sync_change(FROM_HERE, change_type, sync_data); - change_list->push_back(sync_change); - } - - protected: - // Private method wrappers through friend class. - Time GetLastUpdateTime(const syncer::SyncData& data) { - return sync_service_->GetLastUpdateTime(data); - } - int CountActiveDevices(const Time now) { - return sync_service_->CountActiveDevices(now); - } - void StoreSyncData(const std::string& client_id, - const syncer::SyncData& sync_data) { - sync_service_->StoreSyncData(client_id, sync_data); - } - bool IsPulseTimerRunning() { return sync_service_->pulse_timer_.IsRunning(); } - - // Needs to be created for OneShotTimer to grab the current task runner. - base::MessageLoop message_loop_; - - int num_device_info_changed_callbacks_; - std::unique_ptr<LocalDeviceInfoProviderMock> local_device_; - std::unique_ptr<DeviceInfoSyncService> sync_service_; - std::unique_ptr<TestChangeProcessor> sync_processor_; -}; - -namespace { - -// Sync with empty initial data. -TEST_F(DeviceInfoSyncServiceTest, StartSyncEmptyInitialData) { - EXPECT_FALSE(sync_service_->IsSyncing()); - - SyncMergeResult merge_result = - sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO, - SyncDataList(), - PassProcessor(), - CreateAndPassSyncErrorFactory()); - - EXPECT_TRUE(sync_service_->IsSyncing()); - EXPECT_EQ(0, merge_result.num_items_added()); - EXPECT_EQ(0, merge_result.num_items_modified()); - EXPECT_EQ(0, merge_result.num_items_deleted()); - EXPECT_EQ(1, merge_result.num_items_before_association()); - EXPECT_EQ(1, merge_result.num_items_after_association()); - EXPECT_EQ(SyncChange::ACTION_ADD, sync_processor_->change_type_at(0)); - - EXPECT_EQ(1U, sync_processor_->change_list_size()); - EXPECT_EQ("guid_1", sync_processor_->cache_guid_at(0)); - - // Should have one device info corresponding to local device info. - EXPECT_EQ(1U, sync_service_->GetAllSyncData(syncer::DEVICE_INFO).size()); - EXPECT_EQ(1U, sync_service_->GetAllDeviceInfo().size()); - EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_1")); - EXPECT_FALSE(sync_service_->GetDeviceInfo("guid_0")); -} - -TEST_F(DeviceInfoSyncServiceTest, StopSyncing) { - SyncMergeResult merge_result = sync_service_->MergeDataAndStartSyncing( - syncer::DEVICE_INFO, SyncDataList(), PassProcessor(), - CreateAndPassSyncErrorFactory()); - EXPECT_TRUE(sync_service_->IsSyncing()); - EXPECT_EQ(1, num_device_info_changed_callbacks_); - EXPECT_TRUE(IsPulseTimerRunning()); - sync_service_->StopSyncing(syncer::DEVICE_INFO); - EXPECT_FALSE(sync_service_->IsSyncing()); - EXPECT_EQ(2, num_device_info_changed_callbacks_); - EXPECT_FALSE(IsPulseTimerRunning()); -} - -// Sync with initial data matching the local device data. -TEST_F(DeviceInfoSyncServiceTest, StartSyncMatchingInitialData) { - SyncDataList sync_data; - AddInitialData(&sync_data, "guid_1", "client_1"); - - SyncMergeResult merge_result = - sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO, - sync_data, - PassProcessor(), - CreateAndPassSyncErrorFactory()); - EXPECT_EQ(0, merge_result.num_items_added()); - EXPECT_EQ(0, merge_result.num_items_modified()); - EXPECT_EQ(0, merge_result.num_items_deleted()); - EXPECT_EQ(1, merge_result.num_items_before_association()); - EXPECT_EQ(1, merge_result.num_items_after_association()); - - // No changes expected because the device info matches. - EXPECT_EQ(0U, sync_processor_->change_list_size()); - - EXPECT_EQ(1U, sync_service_->GetAllSyncData(syncer::DEVICE_INFO).size()); - EXPECT_EQ(1U, sync_service_->GetAllDeviceInfo().size()); - EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_1")); - EXPECT_FALSE(sync_service_->GetDeviceInfo("guid_0")); -} - -// Sync with misc initial data. -TEST_F(DeviceInfoSyncServiceTest, StartSync) { - SyncDataList sync_data; - AddInitialData(&sync_data, "guid_2", "foo"); - AddInitialData(&sync_data, "guid_3", "bar"); - // This guid matches the local device but the client name is different. - AddInitialData(&sync_data, "guid_1", "baz"); - - SyncMergeResult merge_result = - sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO, - sync_data, - PassProcessor(), - CreateAndPassSyncErrorFactory()); - - EXPECT_EQ(2, merge_result.num_items_added()); - EXPECT_EQ(1, merge_result.num_items_modified()); - EXPECT_EQ(0, merge_result.num_items_deleted()); - EXPECT_EQ(1, merge_result.num_items_before_association()); - EXPECT_EQ(3, merge_result.num_items_after_association()); - - EXPECT_EQ(1U, sync_processor_->change_list_size()); - EXPECT_EQ(SyncChange::ACTION_UPDATE, sync_processor_->change_type_at(0)); - EXPECT_EQ("client_1", sync_processor_->client_name_at(0)); - - EXPECT_EQ(3U, sync_service_->GetAllSyncData(syncer::DEVICE_INFO).size()); - EXPECT_EQ(3U, sync_service_->GetAllDeviceInfo().size()); - EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_1")); - EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_2")); - EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_3")); - EXPECT_FALSE(sync_service_->GetDeviceInfo("guid_0")); -} - -// Process sync change with ACTION_ADD. -// Verify callback. -TEST_F(DeviceInfoSyncServiceTest, ProcessAddChange) { - EXPECT_EQ(0, num_device_info_changed_callbacks_); - - // Start with an empty initial data. - SyncMergeResult merge_result = - sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO, - SyncDataList(), - PassProcessor(), - CreateAndPassSyncErrorFactory()); - // There should be only one item corresponding to the local device - EXPECT_EQ(1, merge_result.num_items_after_association()); - EXPECT_EQ(1, num_device_info_changed_callbacks_); - - // Add a new device info with a non-matching guid. - SyncChangeList change_list; - AddChange(&change_list, SyncChange::ACTION_ADD, "guid_2", "foo"); - - SyncError error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list); - EXPECT_FALSE(error.IsSet()); - EXPECT_EQ(2, num_device_info_changed_callbacks_); - - EXPECT_EQ(2U, sync_service_->GetAllDeviceInfo().size()); - - EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_1")); - EXPECT_TRUE(sync_service_->GetDeviceInfo("guid_2")); - EXPECT_FALSE(sync_service_->GetDeviceInfo("guid_0")); -} - -// Process multiple sync change with ACTION_UPDATE and ACTION_ADD. -// Verify that callback is called multiple times. -TEST_F(DeviceInfoSyncServiceTest, ProcessMultipleChanges) { - SyncDataList sync_data; - AddInitialData(&sync_data, "guid_2", "foo"); - AddInitialData(&sync_data, "guid_3", "bar"); - - SyncMergeResult merge_result = - sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO, - sync_data, - PassProcessor(), - CreateAndPassSyncErrorFactory()); - EXPECT_EQ(3, merge_result.num_items_after_association()); - // reset callbacks counter - num_device_info_changed_callbacks_ = 0; - - SyncChangeList change_list; - AddChange(&change_list, SyncChange::ACTION_UPDATE, "guid_2", "foo_2"); - - SyncError error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list); - EXPECT_FALSE(error.IsSet()); - - EXPECT_EQ(1, num_device_info_changed_callbacks_); - EXPECT_EQ(3U, sync_service_->GetAllDeviceInfo().size()); - EXPECT_EQ("foo_2", sync_service_->GetDeviceInfo("guid_2")->client_name()); - - change_list.clear(); - AddChange(&change_list, SyncChange::ACTION_UPDATE, "guid_3", "bar_3"); - AddChange(&change_list, SyncChange::ACTION_ADD, "guid_4", "baz_4"); - - error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list); - EXPECT_FALSE(error.IsSet()); - - EXPECT_EQ(2, num_device_info_changed_callbacks_); - EXPECT_EQ(4U, sync_service_->GetAllDeviceInfo().size()); - EXPECT_EQ("bar_3", sync_service_->GetDeviceInfo("guid_3")->client_name()); - EXPECT_EQ("baz_4", sync_service_->GetDeviceInfo("guid_4")->client_name()); -} - -// Process update to the local device info and verify that it is ignored. -TEST_F(DeviceInfoSyncServiceTest, ProcessUpdateChangeMatchingLocalDevice) { - SyncMergeResult merge_result = - sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO, - SyncDataList(), - PassProcessor(), - CreateAndPassSyncErrorFactory()); - EXPECT_EQ(1, merge_result.num_items_after_association()); - // reset callbacks counter - num_device_info_changed_callbacks_ = 0; - - SyncChangeList change_list; - AddChange(&change_list, SyncChange::ACTION_UPDATE, "guid_1", "foo_1"); - - SyncError error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list); - EXPECT_FALSE(error.IsSet()); - // Callback shouldn't be sent in this case. - EXPECT_EQ(0, num_device_info_changed_callbacks_); - // Should still have the old local device Info. - EXPECT_EQ(1U, sync_service_->GetAllDeviceInfo().size()); - EXPECT_EQ("client_1", sync_service_->GetDeviceInfo("guid_1")->client_name()); -} - -// Process sync change with ACTION_DELETE. -TEST_F(DeviceInfoSyncServiceTest, ProcessDeleteChange) { - SyncDataList sync_data; - AddInitialData(&sync_data, "guid_2", "foo"); - AddInitialData(&sync_data, "guid_3", "bar"); - - SyncMergeResult merge_result = - sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO, - sync_data, - PassProcessor(), - CreateAndPassSyncErrorFactory()); - EXPECT_EQ(3, merge_result.num_items_after_association()); - // reset callbacks counter - num_device_info_changed_callbacks_ = 0; - - SyncChangeList change_list; - AddChange(&change_list, SyncChange::ACTION_DELETE, "guid_2", "foo_2"); - - SyncError error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list); - EXPECT_FALSE(error.IsSet()); - - EXPECT_EQ(1, num_device_info_changed_callbacks_); - EXPECT_EQ(2U, sync_service_->GetAllDeviceInfo().size()); - EXPECT_FALSE(sync_service_->GetDeviceInfo("guid_2")); -} - -// Process sync change with unexpected action. -TEST_F(DeviceInfoSyncServiceTest, ProcessInvalidChange) { - SyncMergeResult merge_result = - sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO, - SyncDataList(), - PassProcessor(), - CreateAndPassSyncErrorFactory()); - EXPECT_EQ(1, merge_result.num_items_after_association()); - // reset callbacks counter - num_device_info_changed_callbacks_ = 0; - - SyncChangeList change_list; - AddChange(&change_list, (SyncChange::SyncChangeType)100, "guid_2", "foo_2"); - - SyncError error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list); - EXPECT_TRUE(error.IsSet()); - - // The number of callback should still be zero. - EXPECT_EQ(0, num_device_info_changed_callbacks_); - EXPECT_EQ(1U, sync_service_->GetAllDeviceInfo().size()); -} - -// Process sync change after unsubscribing from notifications. -TEST_F(DeviceInfoSyncServiceTest, ProcessChangesAfterUnsubscribing) { - SyncMergeResult merge_result = - sync_service_->MergeDataAndStartSyncing(syncer::DEVICE_INFO, - SyncDataList(), - PassProcessor(), - CreateAndPassSyncErrorFactory()); - EXPECT_EQ(1, merge_result.num_items_after_association()); - // reset callbacks counter - num_device_info_changed_callbacks_ = 0; - - SyncChangeList change_list; - AddChange(&change_list, SyncChange::ACTION_ADD, "guid_2", "foo_2"); - - // Unsubscribe observer before processing changes. - sync_service_->RemoveObserver(this); - - SyncError error = sync_service_->ProcessSyncChanges(FROM_HERE, change_list); - EXPECT_FALSE(error.IsSet()); - - // The number of callback should still be zero. - EXPECT_EQ(0, num_device_info_changed_callbacks_); -} - -// While the initial data will match the current device, the last modified time -// should be greater than the threshold and cause an update anyways. -TEST_F(DeviceInfoSyncServiceTest, StartSyncMatchingButStale) { - SyncDataList sync_data; - sync_data.push_back(CreateRemoteData("guid_1", "foo_1", Time())); - SyncMergeResult merge_result = sync_service_->MergeDataAndStartSyncing( - syncer::DEVICE_INFO, sync_data, PassProcessor(), - CreateAndPassSyncErrorFactory()); - - EXPECT_EQ(1U, sync_processor_->change_list_size()); - EXPECT_EQ(SyncChange::ACTION_UPDATE, sync_processor_->change_type_at(0)); - EXPECT_EQ("guid_1", sync_processor_->cache_guid_at(0)); - EXPECT_EQ("client_1", sync_processor_->client_name_at(0)); -} - -TEST_F(DeviceInfoSyncServiceTest, GetLastUpdateTime) { - Time time1(Time() + TimeDelta::FromDays(1)); - Time time2(Time() + TimeDelta::FromDays(2)); - - SyncData localA( - SyncData::CreateLocalData("a", "a", CreateEntitySpecifics("a", "a"))); - - EntitySpecifics entityB(CreateEntitySpecifics("b", "b")); - entityB.mutable_device_info()->set_last_updated_timestamp( - syncer::TimeToProtoTime(time1)); - SyncData localB(SyncData::CreateLocalData("b", "b", entityB)); - - SyncData remoteC(SyncData::CreateRemoteData( - 1, CreateEntitySpecifics("c", "c"), time2, AttachmentIdList(), - AttachmentServiceProxyForTest::Create())); - - EntitySpecifics entityD(CreateEntitySpecifics("d", "d")); - entityD.mutable_device_info()->set_last_updated_timestamp( - syncer::TimeToProtoTime(time1)); - SyncData remoteD( - SyncData::CreateRemoteData(1, entityD, time2, AttachmentIdList(), - AttachmentServiceProxyForTest::Create())); - - EXPECT_EQ(Time(), GetLastUpdateTime(localA)); - EXPECT_EQ(time1, GetLastUpdateTime(localB)); - EXPECT_EQ(time2, GetLastUpdateTime(remoteC)); - EXPECT_EQ(time1, GetLastUpdateTime(remoteD)); -} - -// Verifies the number of active devices is 0 when there is no data. -TEST_F(DeviceInfoSyncServiceTest, CountActiveDevicesNone) { - EXPECT_EQ(0, CountActiveDevices(Time())); -} - -// Verifies the number of active devices when we have one active device info. -TEST_F(DeviceInfoSyncServiceTest, CountActiveDevicesOneActive) { - StoreSyncData("active", CreateRemoteData("active", "active", Time())); - EXPECT_EQ( - 1, CountActiveDevices(Time() + (DeviceInfoUtil::kActiveThreshold / 2))); -} - -// Verifies the number of active devices when we have one stale that hasn't been -// updated for exactly the threshold is considered stale. -TEST_F(DeviceInfoSyncServiceTest, CountActiveDevicesExactlyStale) { - StoreSyncData("stale", CreateRemoteData("stale", "stale", Time())); - EXPECT_EQ(0, CountActiveDevices(Time() + DeviceInfoUtil::kActiveThreshold)); -} - -// Verifies the number of active devices when we have a mix of active and stale -// device infos. -TEST_F(DeviceInfoSyncServiceTest, CountActiveDevicesManyMix) { - StoreSyncData("stale", CreateRemoteData("stale", "stale", Time())); - StoreSyncData("active1", CreateRemoteData( - "active1", "active1", - Time() + DeviceInfoUtil::kActiveThreshold / 2)); - StoreSyncData("active2", - CreateRemoteData("active2", "active2", - Time() + DeviceInfoUtil::kActiveThreshold)); - EXPECT_EQ(2, CountActiveDevices(Time() + DeviceInfoUtil::kActiveThreshold)); -} - -// Verifies the number of active devices when we have many that are stale. -TEST_F(DeviceInfoSyncServiceTest, CountActiveDevicesManyStale) { - StoreSyncData("stale1", CreateRemoteData("stale1", "stale1", Time())); - StoreSyncData("stale2", - CreateRemoteData("stale2", "stale2", - Time() + DeviceInfoUtil::kActiveThreshold)); - StoreSyncData("stale3", CreateRemoteData( - "stale3", "stale3", - Time() + (DeviceInfoUtil::kActiveThreshold * 2))); - EXPECT_EQ( - 0, CountActiveDevices(Time() + (DeviceInfoUtil::kActiveThreshold * 3))); -} - -// Verifies the number of active devices when we have devices that claim to have -// been updated in the future. -TEST_F(DeviceInfoSyncServiceTest, CountActiveDevicesFuture) { - StoreSyncData("now", - CreateRemoteData("now", "now", - Time() + DeviceInfoUtil::kActiveThreshold)); - StoreSyncData( - "future", - CreateRemoteData("future", "future", - Time() + (DeviceInfoUtil::kActiveThreshold * 10))); - EXPECT_EQ(2, CountActiveDevices(Time() + DeviceInfoUtil::kActiveThreshold)); -} - -// Verifies the number of active devices when they don't have an updated time -// set, and fallback to checking the SyncData's last modified time. -TEST_F(DeviceInfoSyncServiceTest, CountActiveDevicesModifiedTime) { - sync_pb::EntitySpecifics stale_entity; - sync_pb::DeviceInfoSpecifics& stale_specifics = - *stale_entity.mutable_device_info(); - stale_specifics.set_cache_guid("stale"); - StoreSyncData("stale", SyncData::CreateRemoteData( - 1, stale_entity, Time(), AttachmentIdList(), - AttachmentServiceProxyForTest::Create())); - - sync_pb::EntitySpecifics active_entity; - sync_pb::DeviceInfoSpecifics& active_specifics = - *active_entity.mutable_device_info(); - active_specifics.set_cache_guid("active"); - StoreSyncData( - "active", - SyncData::CreateRemoteData( - 1, active_entity, Time() + (DeviceInfoUtil::kActiveThreshold / 2), - AttachmentIdList(), AttachmentServiceProxyForTest::Create())); - - EXPECT_EQ(1, CountActiveDevices(Time() + DeviceInfoUtil::kActiveThreshold)); -} - -// Verifies the number of active devices when they don't have an updated time -// and they're not remote, which means we cannot use SyncData's last modified -// time. If now is close to uninitialized time, should still be active. -TEST_F(DeviceInfoSyncServiceTest, CountActiveDevicesLocalActive) { - sync_pb::EntitySpecifics entity; - sync_pb::DeviceInfoSpecifics& specifics = *entity.mutable_device_info(); - specifics.set_cache_guid("active"); - StoreSyncData("active", - SyncData::CreateLocalData("active", "active", entity)); - EXPECT_EQ( - 1, CountActiveDevices(Time() + (DeviceInfoUtil::kActiveThreshold / 2))); -} - -// Verifies the number of active devices when they don't have an updated time -// and they're not remote, which means we cannot use SyncData's last modified -// time. If now is far from uninitialized time, should be stale. -TEST_F(DeviceInfoSyncServiceTest, CountActiveDevicesLocalStale) { - sync_pb::EntitySpecifics entity; - sync_pb::DeviceInfoSpecifics& specifics = *entity.mutable_device_info(); - specifics.set_cache_guid("stale"); - StoreSyncData("stale", SyncData::CreateLocalData("stale", "stale", entity)); - EXPECT_EQ(0, CountActiveDevices(Time() + DeviceInfoUtil::kActiveThreshold)); -} - -} // namespace - -} // namespace sync_driver
diff --git a/components/sync_driver/device_info_tracker.h b/components/sync_driver/device_info_tracker.h deleted file mode 100644 index d19069b9..0000000 --- a/components/sync_driver/device_info_tracker.h +++ /dev/null
@@ -1,46 +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 COMPONENTS_SYNC_DRIVER_DEVICE_INFO_TRACKER_H_ -#define COMPONENTS_SYNC_DRIVER_DEVICE_INFO_TRACKER_H_ - -#include <memory> -#include <string> - -#include "base/memory/scoped_vector.h" -#include "components/sync_driver/device_info.h" - -namespace sync_driver { - -// Interface for tracking synced DeviceInfo. -class DeviceInfoTracker { - public: - virtual ~DeviceInfoTracker() {} - - // Observer class for listening to device info changes. - class Observer { - public: - virtual void OnDeviceInfoChange() = 0; - }; - - // Returns true when DeviceInfo datatype is enabled and syncing. - virtual bool IsSyncing() const = 0; - // Gets DeviceInfo the synced device with specified client ID. - // Returns an empty unique_ptr if device with the given |client_id| hasn't - // been synced. - virtual std::unique_ptr<DeviceInfo> GetDeviceInfo( - const std::string& client_id) const = 0; - // Gets DeviceInfo for all synced devices (including the local one). - virtual ScopedVector<DeviceInfo> GetAllDeviceInfo() const = 0; - // Registers an observer to be called on syncing any updated DeviceInfo. - virtual void AddObserver(Observer* observer) = 0; - // Unregisters an observer. - virtual void RemoveObserver(Observer* observer) = 0; - // Returns the count of active devices. - virtual int CountActiveDevices() const = 0; -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_DEVICE_INFO_TRACKER_H_
diff --git a/components/sync_driver/device_info_util.cc b/components/sync_driver/device_info_util.cc deleted file mode 100644 index fa5c240..0000000 --- a/components/sync_driver/device_info_util.cc +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright 2016 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/sync_driver/device_info_util.h" - -#include <algorithm> - -#include "base/strings/string_util.h" -#include "components/sync/protocol/sync.pb.h" - -namespace sync_driver { - -using base::Time; -using base::TimeDelta; -using sync_pb::DeviceInfoSpecifics; - -const char DeviceInfoUtil::kClientTagPrefix[] = "DeviceInfo_"; -const TimeDelta DeviceInfoUtil::kPulseInterval = TimeDelta::FromDays(1); -const TimeDelta DeviceInfoUtil::kActiveThreshold = TimeDelta::FromDays(14); - -namespace { - -base::TimeDelta Age(const base::Time last_update, const base::Time now) { - // Don't allow negative age for things somehow updated in the future. - return std::max(base::TimeDelta(), now - last_update); -} - -} // namespace - -// static -base::TimeDelta DeviceInfoUtil::CalculatePulseDelay( - const base::Time last_update, - const base::Time now) { - // Don't allow negative delays for very stale data, use delay of 0. - return std::max(base::TimeDelta(), kPulseInterval - Age(last_update, now)); -} - -// static -bool DeviceInfoUtil::IsActive(const Time last_update, const Time now) { - return Age(last_update, now) < kActiveThreshold; -} - -// static -std::string DeviceInfoUtil::SpecificsToTag( - const sync_pb::DeviceInfoSpecifics& specifics) { - return kClientTagPrefix + specifics.cache_guid(); -} - -// static -std::string DeviceInfoUtil::TagToCacheGuid(const std::string& tag) { - DCHECK(base::StartsWith(tag, kClientTagPrefix, base::CompareCase::SENSITIVE)); - return tag.substr(strlen(kClientTagPrefix)); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/device_info_util_unittest.cc b/components/sync_driver/device_info_util_unittest.cc deleted file mode 100644 index e63b881..0000000 --- a/components/sync_driver/device_info_util_unittest.cc +++ /dev/null
@@ -1,113 +0,0 @@ -// Copyright 2016 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/sync_driver/device_info_util.h" - -#include <string> - -#include "components/sync/protocol/sync.pb.h" -#include "testing/gtest/include/gtest/gtest.h" - -using base::Time; -using base::TimeDelta; -using sync_pb::DeviceInfoSpecifics; - -namespace sync_driver { - -namespace { - -class DeviceInfoUtilTest : public testing::Test { - protected: - DeviceInfoUtilTest() { - // Test cases assume |small_| and |big_| are smaller and bigger, - // respectively, - // than both constants. - EXPECT_LT(small_, DeviceInfoUtil::kActiveThreshold); - EXPECT_LT(small_, DeviceInfoUtil::kPulseInterval); - EXPECT_GT(big_, DeviceInfoUtil::kActiveThreshold); - EXPECT_GT(big_, DeviceInfoUtil::kPulseInterval); - } - - const Time now_ = Time::Now(); - const TimeDelta small_ = TimeDelta::FromMilliseconds(1); - const TimeDelta big_ = TimeDelta::FromDays(1000); -}; - -} // namespace - -TEST_F(DeviceInfoUtilTest, CalculatePulseDelaySame) { - EXPECT_EQ(DeviceInfoUtil::kPulseInterval, - DeviceInfoUtil::CalculatePulseDelay(Time(), Time())); - EXPECT_EQ(DeviceInfoUtil::kPulseInterval, - DeviceInfoUtil::CalculatePulseDelay(now_, now_)); - EXPECT_EQ(DeviceInfoUtil::kPulseInterval, - DeviceInfoUtil::CalculatePulseDelay(now_ + big_, now_ + big_)); -} - -TEST_F(DeviceInfoUtilTest, CalculatePulseDelayMiddle) { - EXPECT_EQ(DeviceInfoUtil::kPulseInterval - small_, - DeviceInfoUtil::CalculatePulseDelay(Time(), Time() + small_)); - EXPECT_EQ(small_, - DeviceInfoUtil::CalculatePulseDelay( - Time(), Time() + DeviceInfoUtil::kPulseInterval - small_)); -} - -TEST_F(DeviceInfoUtilTest, CalculatePulseDelayStale) { - EXPECT_EQ(TimeDelta(), DeviceInfoUtil::CalculatePulseDelay( - Time(), Time() + DeviceInfoUtil::kPulseInterval)); - EXPECT_EQ(TimeDelta(), - DeviceInfoUtil::CalculatePulseDelay( - Time(), Time() + DeviceInfoUtil::kPulseInterval + small_)); - EXPECT_EQ(TimeDelta(), - DeviceInfoUtil::CalculatePulseDelay( - Time(), Time() + DeviceInfoUtil::kPulseInterval + small_)); - EXPECT_EQ(TimeDelta(), DeviceInfoUtil::CalculatePulseDelay( - now_, now_ + DeviceInfoUtil::kPulseInterval)); -} - -TEST_F(DeviceInfoUtilTest, CalculatePulseDelayFuture) { - EXPECT_EQ(DeviceInfoUtil::kPulseInterval, - DeviceInfoUtil::CalculatePulseDelay(Time() + small_, Time())); - EXPECT_EQ(DeviceInfoUtil::kPulseInterval, - DeviceInfoUtil::CalculatePulseDelay( - Time() + DeviceInfoUtil::kPulseInterval, Time())); - EXPECT_EQ(DeviceInfoUtil::kPulseInterval, - DeviceInfoUtil::CalculatePulseDelay(Time() + big_, Time())); - EXPECT_EQ(DeviceInfoUtil::kPulseInterval, - DeviceInfoUtil::CalculatePulseDelay(now_ + big_, now_)); -} - -TEST_F(DeviceInfoUtilTest, IsActive) { - EXPECT_TRUE(DeviceInfoUtil::IsActive(Time(), Time())); - EXPECT_TRUE(DeviceInfoUtil::IsActive(now_, now_)); - EXPECT_TRUE(DeviceInfoUtil::IsActive(now_, now_ + small_)); - EXPECT_TRUE(DeviceInfoUtil::IsActive( - now_, now_ + DeviceInfoUtil::kActiveThreshold - small_)); - EXPECT_FALSE( - DeviceInfoUtil::IsActive(now_, now_ + DeviceInfoUtil::kActiveThreshold)); - EXPECT_FALSE(DeviceInfoUtil::IsActive( - now_, now_ + DeviceInfoUtil::kActiveThreshold + small_)); - EXPECT_FALSE(DeviceInfoUtil::IsActive( - now_, now_ + DeviceInfoUtil::kActiveThreshold + big_)); - EXPECT_TRUE(DeviceInfoUtil::IsActive(now_ + small_, now_)); - EXPECT_TRUE(DeviceInfoUtil::IsActive(now_ + big_, now_)); -} - -TEST_F(DeviceInfoUtilTest, TagRoundTrip) { - DeviceInfoSpecifics specifics; - ASSERT_EQ("", DeviceInfoUtil::TagToCacheGuid( - DeviceInfoUtil::SpecificsToTag(specifics))); - - std::string cache_guid("guid"); - specifics.set_cache_guid(cache_guid); - ASSERT_EQ(cache_guid, DeviceInfoUtil::TagToCacheGuid( - DeviceInfoUtil::SpecificsToTag(specifics))); - - specifics.set_cache_guid(DeviceInfoUtil::kClientTagPrefix); - ASSERT_EQ(DeviceInfoUtil::kClientTagPrefix, - DeviceInfoUtil::TagToCacheGuid( - DeviceInfoUtil::SpecificsToTag(specifics))); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/directory_data_type_controller.cc b/components/sync_driver/directory_data_type_controller.cc deleted file mode 100644 index 9fa22b1..0000000 --- a/components/sync_driver/directory_data_type_controller.cc +++ /dev/null
@@ -1,41 +0,0 @@ -// 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 "components/sync_driver/directory_data_type_controller.h" - -#include "components/sync_driver/backend_data_type_configurer.h" - -namespace sync_driver { - -DirectoryDataTypeController::DirectoryDataTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const base::Closure& error_callback) - : DataTypeController(ui_thread, error_callback) {} - -DirectoryDataTypeController::~DirectoryDataTypeController() {} - -bool DirectoryDataTypeController::ShouldLoadModelBeforeConfigure() const { - // Directory datatypes don't require loading models before configure. Their - // progress markers are stored in directory and can be extracted without - // datatype participation. - return false; -} - -void DirectoryDataTypeController::RegisterWithBackend( - BackendDataTypeConfigurer* configurer) {} - -void DirectoryDataTypeController::ActivateDataType( - BackendDataTypeConfigurer* configurer) { - // Tell the backend about the change processor for this type so it can - // begin routing changes to it. - configurer->ActivateDirectoryDataType(type(), model_safe_group(), - GetChangeProcessor()); -} - -void DirectoryDataTypeController::DeactivateDataType( - BackendDataTypeConfigurer* configurer) { - configurer->DeactivateDirectoryDataType(type()); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/directory_data_type_controller.h b/components/sync_driver/directory_data_type_controller.h deleted file mode 100644 index 6b25a6e..0000000 --- a/components/sync_driver/directory_data_type_controller.h +++ /dev/null
@@ -1,59 +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. - -#ifndef COMPONENTS_SYNC_DRIVER_DIRECTORY_DATA_TYPE_CONTROLLER_H__ -#define COMPONENTS_SYNC_DRIVER_DIRECTORY_DATA_TYPE_CONTROLLER_H__ - -#include "components/sync_driver/data_type_controller.h" - -#include "components/sync/engine/model_safe_worker.h" - -namespace sync_driver { -class ChangeProcessor; - -// Base class for Directory based Data type controllers. -class DirectoryDataTypeController : public DataTypeController { - public: - // DataTypeController implementation. - bool ShouldLoadModelBeforeConfigure() const override; - - // Directory based data types don't need to register with backend. - // ModelTypeRegistry will create all necessary objects in - // SetEnabledDirectoryTypes based on routing info. - void RegisterWithBackend(BackendDataTypeConfigurer* configurer) override; - - // Directory specific implementation of ActivateDataType with the - // type specific ChangeProcessor and ModelSafeGroup. - // Activates change processing on the controlled data type. - // This is called by DataTypeManager, synchronously with data type's - // model association. - // See BackendDataTypeConfigurer::ActivateDataType for more details. - void ActivateDataType(BackendDataTypeConfigurer* configurer) override; - - // Directory specific implementation of DeactivateDataType. - // Deactivates change processing on the controlled data type (by removing - // the data type's ChangeProcessor registration with the backend). - // See BackendDataTypeConfigurer::DeactivateDataType for more details. - void DeactivateDataType(BackendDataTypeConfigurer* configurer) override; - - protected: - // The model safe group of this data type. This should reflect the - // thread that should be used to modify the data type's native - // model. - virtual syncer::ModelSafeGroup model_safe_group() const = 0; - - // Access to the ChangeProcessor for the type being controlled by |this|. - // Returns NULL if the ChangeProcessor isn't created or connected. - virtual ChangeProcessor* GetChangeProcessor() const = 0; - - DirectoryDataTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const base::Closure& error_callback); - - ~DirectoryDataTypeController() override; -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_DIRECTORY_DATA_TYPE_CONTROLLER_H__
diff --git a/components/sync_driver/fake_data_type_controller.cc b/components/sync_driver/fake_data_type_controller.cc deleted file mode 100644 index 18c02ca..0000000 --- a/components/sync_driver/fake_data_type_controller.cc +++ /dev/null
@@ -1,171 +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 "components/sync_driver/fake_data_type_controller.h" - -#include "base/threading/thread_task_runner_handle.h" -#include "components/sync/api/sync_merge_result.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using syncer::ModelType; - -namespace sync_driver { - -FakeDataTypeController::FakeDataTypeController(ModelType type) - : DirectoryDataTypeController(base::ThreadTaskRunnerHandle::Get(), - base::Closure()), - state_(NOT_RUNNING), - model_load_delayed_(false), - type_(type), - ready_for_start_(true), - should_load_model_before_configure_(false), - register_with_backend_call_count_(0) {} - -FakeDataTypeController::~FakeDataTypeController() { -} - -bool FakeDataTypeController::ShouldLoadModelBeforeConfigure() const { - return should_load_model_before_configure_; -} - -// NOT_RUNNING ->MODEL_LOADED |MODEL_STARTING. -void FakeDataTypeController::LoadModels( - const ModelLoadCallback& model_load_callback) { - model_load_callback_ = model_load_callback; - if (state_ != NOT_RUNNING) { - ADD_FAILURE(); - return; - } - - if (model_load_delayed_ == false) { - if (load_error_.IsSet()) - state_ = DISABLED; - else - state_ = MODEL_LOADED; - model_load_callback.Run(type(), load_error_); - } else { - state_ = MODEL_STARTING; - } -} - -void FakeDataTypeController::RegisterWithBackend( - BackendDataTypeConfigurer* configurer) { - ++register_with_backend_call_count_; -} - -// MODEL_LOADED -> MODEL_STARTING. -void FakeDataTypeController::StartAssociating( - const StartCallback& start_callback) { - last_start_callback_ = start_callback; - state_ = ASSOCIATING; -} - -// MODEL_STARTING | ASSOCIATING -> RUNNING | DISABLED | NOT_RUNNING -// (depending on |result|) -void FakeDataTypeController::FinishStart(ConfigureResult result) { - // We should have a callback from Start(). - if (last_start_callback_.is_null()) { - ADD_FAILURE(); - return; - } - - // Set |state_| first below since the callback may call state(). - syncer::SyncMergeResult local_merge_result(type()); - syncer::SyncMergeResult syncer_merge_result(type()); - if (result <= OK_FIRST_RUN) { - state_ = RUNNING; - } else if (result == ASSOCIATION_FAILED) { - state_ = DISABLED; - local_merge_result.set_error( - syncer::SyncError(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Association failed", - type())); - } else if (result == UNRECOVERABLE_ERROR) { - state_ = NOT_RUNNING; - local_merge_result.set_error( - syncer::SyncError(FROM_HERE, - syncer::SyncError::UNRECOVERABLE_ERROR, - "Unrecoverable error", - type())); - } else if (result == NEEDS_CRYPTO) { - state_ = NOT_RUNNING; - local_merge_result.set_error( - syncer::SyncError(FROM_HERE, - syncer::SyncError::CRYPTO_ERROR, - "Crypto error", - type())); - } else { - NOTREACHED(); - } - last_start_callback_.Run(result, local_merge_result, syncer_merge_result); -} - -// * -> NOT_RUNNING -void FakeDataTypeController::Stop() { - if (!model_load_callback_.is_null()) { - // Real data type controllers run the callback and specify "ABORTED" as an - // error. We should probably find a way to use the real code and mock out - // unnecessary pieces. - SimulateModelLoadFinishing(); - } - state_ = NOT_RUNNING; -} - -ModelType FakeDataTypeController::type() const { - return type_; -} - -std::string FakeDataTypeController::name() const { - return ModelTypeToString(type_); -} - -syncer::ModelSafeGroup FakeDataTypeController::model_safe_group() const { - return syncer::GROUP_PASSIVE; -} - -ChangeProcessor* FakeDataTypeController::GetChangeProcessor() const { - return NULL; -} - -DataTypeController::State FakeDataTypeController::state() const { - return state_; -} - -void FakeDataTypeController::OnSingleDataTypeUnrecoverableError( - const syncer::SyncError& error) { - if (!model_load_callback_.is_null()) - model_load_callback_.Run(type(), error); -} - -bool FakeDataTypeController::ReadyForStart() const { - return ready_for_start_; -} - -void FakeDataTypeController::SetDelayModelLoad() { - model_load_delayed_ = true; -} - -void FakeDataTypeController::SetModelLoadError(syncer::SyncError error) { - load_error_ = error; -} - -void FakeDataTypeController::SimulateModelLoadFinishing() { - if (load_error_.IsSet()) - state_ = DISABLED; - else - state_ = MODEL_LOADED; - model_load_callback_.Run(type(), load_error_); -} - -void FakeDataTypeController::SetReadyForStart(bool ready) { - ready_for_start_ = ready; -} - -void FakeDataTypeController::SetShouldLoadModelBeforeConfigure(bool value) { - should_load_model_before_configure_ = value; -} - -} // namespace sync_driver
diff --git a/components/sync_driver/fake_data_type_controller.h b/components/sync_driver/fake_data_type_controller.h deleted file mode 100644 index 0b84374e..0000000 --- a/components/sync_driver/fake_data_type_controller.h +++ /dev/null
@@ -1,76 +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 COMPONENTS_SYNC_DRIVER_FAKE_DATA_TYPE_CONTROLLER_H__ -#define COMPONENTS_SYNC_DRIVER_FAKE_DATA_TYPE_CONTROLLER_H__ - -#include <string> - -#include "components/sync_driver/data_type_manager.h" -#include "components/sync_driver/directory_data_type_controller.h" - -namespace sync_driver { - -// Fake DataTypeController implementation that simulates the state -// machine of a typical asynchronous data type. -// -// TODO(akalin): Consider using subclasses of -// {Frontend,NonFrontend,NewNonFrontend}DataTypeController instead, so -// that we don't have to update this class if we change the expected -// behavior of controllers. (It would be easier of the above classes -// used delegation instead of subclassing for per-data-type -// functionality.) -class FakeDataTypeController : public DirectoryDataTypeController { - public: - explicit FakeDataTypeController(syncer::ModelType type); - - // DirectoryDataTypeController implementation. - bool ShouldLoadModelBeforeConfigure() const override; - void LoadModels(const ModelLoadCallback& model_load_callback) override; - void RegisterWithBackend(BackendDataTypeConfigurer* configurer) override; - void StartAssociating(const StartCallback& start_callback) override; - void Stop() override; - syncer::ModelType type() const override; - std::string name() const override; - syncer::ModelSafeGroup model_safe_group() const override; - ChangeProcessor* GetChangeProcessor() const override; - State state() const override; - void OnSingleDataTypeUnrecoverableError( - const syncer::SyncError& error) override; - bool ReadyForStart() const override; - - void FinishStart(ConfigureResult result); - - void SetDelayModelLoad(); - - void SetModelLoadError(syncer::SyncError error); - - void SimulateModelLoadFinishing(); - - void SetReadyForStart(bool ready); - - void SetShouldLoadModelBeforeConfigure(bool value); - - int register_with_backend_call_count() const { - return register_with_backend_call_count_; - } - - protected: - ~FakeDataTypeController() override; - - private: - DataTypeController::State state_; - bool model_load_delayed_; - syncer::ModelType type_; - StartCallback last_start_callback_; - ModelLoadCallback model_load_callback_; - syncer::SyncError load_error_; - bool ready_for_start_; - bool should_load_model_before_configure_; - int register_with_backend_call_count_; -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_FAKE_DATA_TYPE_CONTROLLER_H__
diff --git a/components/sync_driver/fake_generic_change_processor.cc b/components/sync_driver/fake_generic_change_processor.cc deleted file mode 100644 index 241d31f3..0000000 --- a/components/sync_driver/fake_generic_change_processor.cc +++ /dev/null
@@ -1,87 +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 "components/sync_driver/fake_generic_change_processor.h" - -#include <utility> - -#include "base/location.h" -#include "base/memory/weak_ptr.h" -#include "components/sync/api/syncable_service.h" -#include "components/sync/core/attachments/attachment_service_impl.h" - -namespace sync_driver { - -FakeGenericChangeProcessor::FakeGenericChangeProcessor( - syncer::ModelType type, - SyncClient* sync_client) - : GenericChangeProcessor(type, - NULL, - base::WeakPtr<syncer::SyncableService>(), - base::WeakPtr<syncer::SyncMergeResult>(), - NULL, - sync_client, - nullptr), - sync_model_has_user_created_nodes_(true), - sync_model_has_user_created_nodes_success_(true) { -} - -FakeGenericChangeProcessor::~FakeGenericChangeProcessor() {} - -void FakeGenericChangeProcessor::set_sync_model_has_user_created_nodes( - bool has_nodes) { - sync_model_has_user_created_nodes_ = has_nodes; -} -void FakeGenericChangeProcessor::set_sync_model_has_user_created_nodes_success( - bool success) { - sync_model_has_user_created_nodes_success_ = success; -} - -syncer::SyncError FakeGenericChangeProcessor::ProcessSyncChanges( - const tracked_objects::Location& from_here, - const syncer::SyncChangeList& change_list) { - return syncer::SyncError(); -} - -syncer::SyncError FakeGenericChangeProcessor::GetAllSyncDataReturnError( - syncer::SyncDataList* current_sync_data) const { - return syncer::SyncError(); -} - -bool FakeGenericChangeProcessor::GetDataTypeContext( - std::string* context) const { - return false; -} - -int FakeGenericChangeProcessor::GetSyncCount() { - return 0; -} - -bool FakeGenericChangeProcessor::SyncModelHasUserCreatedNodes(bool* has_nodes) { - *has_nodes = sync_model_has_user_created_nodes_; - return sync_model_has_user_created_nodes_success_; -} - -bool FakeGenericChangeProcessor::CryptoReadyIfNecessary() { - return true; -} - -FakeGenericChangeProcessorFactory::FakeGenericChangeProcessorFactory( - std::unique_ptr<FakeGenericChangeProcessor> processor) - : processor_(std::move(processor)) {} - -FakeGenericChangeProcessorFactory::~FakeGenericChangeProcessorFactory() {} - -std::unique_ptr<GenericChangeProcessor> -FakeGenericChangeProcessorFactory::CreateGenericChangeProcessor( - syncer::ModelType type, - syncer::UserShare* user_share, - syncer::DataTypeErrorHandler* error_handler, - const base::WeakPtr<syncer::SyncableService>& local_service, - const base::WeakPtr<syncer::SyncMergeResult>& merge_result, - SyncClient* sync_client) { - return std::move(processor_); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/fake_generic_change_processor.h b/components/sync_driver/fake_generic_change_processor.h deleted file mode 100644 index dbf6d13..0000000 --- a/components/sync_driver/fake_generic_change_processor.h +++ /dev/null
@@ -1,67 +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 COMPONENTS_SYNC_DRIVER_FAKE_GENERIC_CHANGE_PROCESSOR_H_ -#define COMPONENTS_SYNC_DRIVER_FAKE_GENERIC_CHANGE_PROCESSOR_H_ - -#include <string> - -#include "base/macros.h" -#include "components/sync/api/sync_error.h" -#include "components/sync/base/model_type.h" -#include "components/sync_driver/generic_change_processor.h" -#include "components/sync_driver/generic_change_processor_factory.h" -#include "components/sync_driver/sync_api_component_factory.h" - -namespace sync_driver { - -// A fake GenericChangeProcessor that can return arbitrary values. -class FakeGenericChangeProcessor : public GenericChangeProcessor { - public: - FakeGenericChangeProcessor(syncer::ModelType type, - SyncClient* sync_client); - ~FakeGenericChangeProcessor() override; - - // Setters for GenericChangeProcessor implementation results. - void set_sync_model_has_user_created_nodes(bool has_nodes); - void set_sync_model_has_user_created_nodes_success(bool success); - - // GenericChangeProcessor implementations. - syncer::SyncError ProcessSyncChanges( - const tracked_objects::Location& from_here, - const syncer::SyncChangeList& change_list) override; - syncer::SyncError GetAllSyncDataReturnError( - syncer::SyncDataList* data) const override; - bool GetDataTypeContext(std::string* context) const override; - int GetSyncCount() override; - bool SyncModelHasUserCreatedNodes(bool* has_nodes) override; - bool CryptoReadyIfNecessary() override; - - private: - bool sync_model_has_user_created_nodes_; - bool sync_model_has_user_created_nodes_success_; -}; - -// Define a factory for FakeGenericChangeProcessor for convenience. -class FakeGenericChangeProcessorFactory : public GenericChangeProcessorFactory { - public: - explicit FakeGenericChangeProcessorFactory( - std::unique_ptr<FakeGenericChangeProcessor> processor); - ~FakeGenericChangeProcessorFactory() override; - std::unique_ptr<GenericChangeProcessor> CreateGenericChangeProcessor( - syncer::ModelType type, - syncer::UserShare* user_share, - syncer::DataTypeErrorHandler* error_handler, - const base::WeakPtr<syncer::SyncableService>& local_service, - const base::WeakPtr<syncer::SyncMergeResult>& merge_result, - SyncClient* sync_client) override; - - private: - std::unique_ptr<FakeGenericChangeProcessor> processor_; - DISALLOW_COPY_AND_ASSIGN(FakeGenericChangeProcessorFactory); -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_FAKE_GENERIC_CHANGE_PROCESSOR_H_
diff --git a/components/sync_driver/fake_sync_client.cc b/components/sync_driver/fake_sync_client.cc deleted file mode 100644 index 678bb6a..0000000 --- a/components/sync_driver/fake_sync_client.cc +++ /dev/null
@@ -1,120 +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. - -#include "components/sync_driver/fake_sync_client.h" - -#include "base/bind.h" -#include "base/memory/ptr_util.h" -#include "components/sync/base/extensions_activity.h" -#include "components/sync_driver/fake_sync_service.h" -#include "components/sync_driver/sync_prefs.h" - -namespace sync_driver { - -namespace { - -void DummyRegisterPlatformTypesCallback(SyncService* sync_service, - syncer::ModelTypeSet, - syncer::ModelTypeSet) {} - -} // namespace - -FakeSyncClient::FakeSyncClient() - : model_type_service_(nullptr), - factory_(nullptr), - sync_service_(base::WrapUnique(new FakeSyncService())) { - // Register sync preferences and set them to "Sync everything" state. - sync_driver::SyncPrefs::RegisterProfilePrefs(pref_service_.registry()); - sync_driver::SyncPrefs sync_prefs(GetPrefService()); - sync_prefs.SetFirstSetupComplete(); - sync_prefs.SetKeepEverythingSynced(true); -} - -FakeSyncClient::FakeSyncClient(SyncApiComponentFactory* factory) - : factory_(factory), - sync_service_(base::WrapUnique(new FakeSyncService())) { - sync_driver::SyncPrefs::RegisterProfilePrefs(pref_service_.registry()); -} - -FakeSyncClient::~FakeSyncClient() {} - -void FakeSyncClient::Initialize() {} - -SyncService* FakeSyncClient::GetSyncService() { - return sync_service_.get(); -} - -PrefService* FakeSyncClient::GetPrefService() { - return &pref_service_; -} - -bookmarks::BookmarkModel* FakeSyncClient::GetBookmarkModel() { - return nullptr; -} - -favicon::FaviconService* FakeSyncClient::GetFaviconService() { - return nullptr; -} - -history::HistoryService* FakeSyncClient::GetHistoryService() { - return nullptr; -} - -base::Closure FakeSyncClient::GetPasswordStateChangedCallback() { - return base::Bind(&base::DoNothing); -} - -sync_driver::SyncApiComponentFactory::RegisterDataTypesMethod -FakeSyncClient::GetRegisterPlatformTypesCallback() { - return base::Bind(&DummyRegisterPlatformTypesCallback); -} - -autofill::PersonalDataManager* FakeSyncClient::GetPersonalDataManager() { - return nullptr; -} - -BookmarkUndoService* FakeSyncClient::GetBookmarkUndoServiceIfExists() { - return nullptr; -} - -invalidation::InvalidationService* FakeSyncClient::GetInvalidationService() { - return nullptr; -} - -scoped_refptr<syncer::ExtensionsActivity> -FakeSyncClient::GetExtensionsActivity() { - return scoped_refptr<syncer::ExtensionsActivity>(); -} - -sync_sessions::SyncSessionsClient* FakeSyncClient::GetSyncSessionsClient() { - return nullptr; -} - -base::WeakPtr<syncer::SyncableService> -FakeSyncClient::GetSyncableServiceForType(syncer::ModelType type) { - return base::WeakPtr<syncer::SyncableService>(); -} - -syncer_v2::ModelTypeService* FakeSyncClient::GetModelTypeServiceForType( - syncer::ModelType type) { - return model_type_service_; -} - -scoped_refptr<syncer::ModelSafeWorker> -FakeSyncClient::CreateModelWorkerForGroup( - syncer::ModelSafeGroup group, - syncer::WorkerLoopDestructionObserver* observer) { - return scoped_refptr<syncer::ModelSafeWorker>(); -} - -SyncApiComponentFactory* FakeSyncClient::GetSyncApiComponentFactory() { - return factory_; -} - -void FakeSyncClient::SetModelTypeService( - syncer_v2::ModelTypeService* model_type_service) { - model_type_service_ = model_type_service; -} - -} // namespace sync_driver
diff --git a/components/sync_driver/fake_sync_client.h b/components/sync_driver/fake_sync_client.h deleted file mode 100644 index 00a58bc..0000000 --- a/components/sync_driver/fake_sync_client.h +++ /dev/null
@@ -1,61 +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. - -#ifndef COMPONENTS_SYNC_DRIVER_FAKE_SYNC_CLIENT_H_ -#define COMPONENTS_SYNC_DRIVER_FAKE_SYNC_CLIENT_H_ - -#include <memory> - -#include "base/macros.h" -#include "components/sync_driver/sync_client.h" -#include "components/syncable_prefs/testing_pref_service_syncable.h" - -namespace sync_driver { -class FakeSyncService; - -// Fake implementation of SyncClient interface for tests. -class FakeSyncClient : public SyncClient { - public: - FakeSyncClient(); - explicit FakeSyncClient(SyncApiComponentFactory* factory); - ~FakeSyncClient() override; - - void Initialize() override; - - SyncService* GetSyncService() override; - PrefService* GetPrefService() override; - bookmarks::BookmarkModel* GetBookmarkModel() override; - favicon::FaviconService* GetFaviconService() override; - history::HistoryService* GetHistoryService() override; - base::Closure GetPasswordStateChangedCallback() override; - sync_driver::SyncApiComponentFactory::RegisterDataTypesMethod - GetRegisterPlatformTypesCallback() override; - autofill::PersonalDataManager* GetPersonalDataManager() override; - BookmarkUndoService* GetBookmarkUndoServiceIfExists() override; - invalidation::InvalidationService* GetInvalidationService() override; - scoped_refptr<syncer::ExtensionsActivity> GetExtensionsActivity() override; - sync_sessions::SyncSessionsClient* GetSyncSessionsClient() override; - base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType( - syncer::ModelType type) override; - syncer_v2::ModelTypeService* GetModelTypeServiceForType( - syncer::ModelType type) override; - scoped_refptr<syncer::ModelSafeWorker> CreateModelWorkerForGroup( - syncer::ModelSafeGroup group, - syncer::WorkerLoopDestructionObserver* observer) override; - SyncApiComponentFactory* GetSyncApiComponentFactory() override; - - void SetModelTypeService(syncer_v2::ModelTypeService* model_type_service); - - private: - syncable_prefs::TestingPrefServiceSyncable pref_service_; - syncer_v2::ModelTypeService* model_type_service_; - SyncApiComponentFactory* factory_; - std::unique_ptr<FakeSyncService> sync_service_; - - DISALLOW_COPY_AND_ASSIGN(FakeSyncClient); -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_FAKE_SYNC_CLIENT_H_
diff --git a/components/sync_driver/fake_sync_service.cc b/components/sync_driver/fake_sync_service.cc deleted file mode 100644 index 6b99074..0000000 --- a/components/sync_driver/fake_sync_service.cc +++ /dev/null
@@ -1,226 +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. - -#include "components/sync_driver/fake_sync_service.h" - -#include "base/memory/ptr_util.h" -#include "base/values.h" -#include "components/sync/core/base_transaction.h" -#include "components/sync/core/user_share.h" -#include "components/sync/sessions/sync_session_snapshot.h" - -namespace sync_driver { - -FakeSyncService::FakeSyncService() - : error_(GoogleServiceAuthError::NONE), - user_share_(base::WrapUnique(new syncer::UserShare())) {} - -FakeSyncService::~FakeSyncService() { -} - -bool FakeSyncService::IsFirstSetupComplete() const { - return false; -} - -bool FakeSyncService::IsSyncAllowed() const { - return false; -} - -bool FakeSyncService::IsSyncActive() const { - return false; -} - -void FakeSyncService::TriggerRefresh(const syncer::ModelTypeSet& types) {} - -syncer::ModelTypeSet FakeSyncService::GetActiveDataTypes() const { - return syncer::ModelTypeSet(); -} - -SyncClient* FakeSyncService::GetSyncClient() const { - return nullptr; -} - -void FakeSyncService::AddObserver(SyncServiceObserver* observer) { -} - -void FakeSyncService::RemoveObserver(SyncServiceObserver* observer) { -} - -bool FakeSyncService::HasObserver(const SyncServiceObserver* observer) const { - return false; -} - -bool FakeSyncService::CanSyncStart() const { - return false; -} - -void FakeSyncService::OnDataTypeRequestsSyncStartup(syncer::ModelType type) { -} - -void FakeSyncService::RequestStop( - sync_driver::SyncService::SyncStopDataFate data_fate) { -} - -void FakeSyncService::RequestStart() { -} - -syncer::ModelTypeSet FakeSyncService::GetPreferredDataTypes() const { - return syncer::ModelTypeSet(); -} - -void FakeSyncService::OnUserChoseDatatypes(bool sync_everything, - syncer::ModelTypeSet chosen_types) { -} - -void FakeSyncService::SetFirstSetupComplete() {} - -bool FakeSyncService::IsFirstSetupInProgress() const { - return false; -} - -std::unique_ptr<SyncSetupInProgressHandle> -FakeSyncService::GetSetupInProgressHandle() { - return nullptr; -} - -bool FakeSyncService::IsSetupInProgress() const { - return false; -} - -bool FakeSyncService::ConfigurationDone() const { - return false; -} - -const GoogleServiceAuthError& FakeSyncService::GetAuthError() const { - return error_; -} - -bool FakeSyncService::HasUnrecoverableError() const { - return false; -} - -bool FakeSyncService::IsBackendInitialized() const { - return false; -} - -OpenTabsUIDelegate* FakeSyncService::GetOpenTabsUIDelegate() { - return nullptr; -} - -bool FakeSyncService::IsPassphraseRequiredForDecryption() const { - return false; -} - -base::Time FakeSyncService::GetExplicitPassphraseTime() const { - return base::Time(); -} - -bool FakeSyncService::IsUsingSecondaryPassphrase() const { - return false; -} - -void FakeSyncService::EnableEncryptEverything() { -} - -bool FakeSyncService::IsEncryptEverythingEnabled() const { - return false; -} - -void FakeSyncService::SetEncryptionPassphrase(const std::string& passphrase, - PassphraseType type) { -} - -bool FakeSyncService::SetDecryptionPassphrase(const std::string& passphrase) { - return false; -} - -bool FakeSyncService::IsCryptographerReady( - const syncer::BaseTransaction* trans) const { - return false; -} - -syncer::UserShare* FakeSyncService::GetUserShare() const { - return user_share_.get(); -} - -LocalDeviceInfoProvider* FakeSyncService::GetLocalDeviceInfoProvider() const { - return nullptr; -} - -void FakeSyncService::RegisterDataTypeController( - sync_driver::DataTypeController* data_type_controller) { -} - -void FakeSyncService::ReenableDatatype(syncer::ModelType type) {} - -bool FakeSyncService::IsPassphraseRequired() const { - return false; -} - -syncer::ModelTypeSet FakeSyncService::GetEncryptedDataTypes() const { - return syncer::ModelTypeSet(); -} - -FakeSyncService::SyncTokenStatus FakeSyncService::GetSyncTokenStatus() const { - return FakeSyncService::SyncTokenStatus(); -} - -std::string FakeSyncService::QuerySyncStatusSummaryString() { - return ""; -} - -bool FakeSyncService::QueryDetailedSyncStatus(syncer::SyncStatus* result) { - return false; -} - -base::string16 FakeSyncService::GetLastSyncedTimeString() const { - return base::string16(); -} - -std::string FakeSyncService::GetBackendInitializationStateString() const { - return std::string(); -} - -syncer::sessions::SyncSessionSnapshot FakeSyncService::GetLastSessionSnapshot() - const { - return syncer::sessions::SyncSessionSnapshot(); -} - -base::Value* FakeSyncService::GetTypeStatusMap() const { - return new base::ListValue(); -} - -const GURL& FakeSyncService::sync_service_url() const { - return sync_service_url_; -} - -std::string FakeSyncService::unrecoverable_error_message() const { - return unrecoverable_error_message_; -} - -tracked_objects::Location FakeSyncService::unrecoverable_error_location() - const { - return tracked_objects::Location(); -} - -void FakeSyncService::AddProtocolEventObserver( - browser_sync::ProtocolEventObserver* observer) {} - -void FakeSyncService::RemoveProtocolEventObserver( - browser_sync::ProtocolEventObserver* observer) {} - -void FakeSyncService::AddTypeDebugInfoObserver( - syncer::TypeDebugInfoObserver* observer) {} - -void FakeSyncService::RemoveTypeDebugInfoObserver( - syncer::TypeDebugInfoObserver* observer) {} - -base::WeakPtr<syncer::JsController> FakeSyncService::GetJsController() { - return base::WeakPtr<syncer::JsController>(); -} - -void FakeSyncService::GetAllNodes( - const base::Callback<void(std::unique_ptr<base::ListValue>)>& callback) {} - -} // namespace sync_driver
diff --git a/components/sync_driver/fake_sync_service.h b/components/sync_driver/fake_sync_service.h deleted file mode 100644 index d104d92..0000000 --- a/components/sync_driver/fake_sync_service.h +++ /dev/null
@@ -1,105 +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. - -#ifndef COMPONENTS_SYNC_DRIVER_FAKE_SYNC_SERVICE_H_ -#define COMPONENTS_SYNC_DRIVER_FAKE_SYNC_SERVICE_H_ - -#include <string> - -#include "components/sync/sessions/sync_session_snapshot.h" -#include "components/sync_driver/sync_service.h" -#include "google_apis/gaia/google_service_auth_error.h" - -namespace syncer { -class BaseTransaction; -struct UserShare; -} - -namespace sync_driver { - -// Fake implementation of sync_driver::SyncService, used for testing. -class FakeSyncService : public sync_driver::SyncService { - public: - FakeSyncService(); - ~FakeSyncService() override; - - private: - // sync_driver::SyncService: - bool IsFirstSetupComplete() const override; - bool IsSyncAllowed() const override; - bool IsSyncActive() const override; - void TriggerRefresh(const syncer::ModelTypeSet& types) override; - syncer::ModelTypeSet GetActiveDataTypes() const override; - SyncClient* GetSyncClient() const override; - void AddObserver(SyncServiceObserver* observer) override; - void RemoveObserver(SyncServiceObserver* observer) override; - bool HasObserver(const SyncServiceObserver* observer) const override; - void OnDataTypeRequestsSyncStartup(syncer::ModelType type) override; - bool CanSyncStart() const override; - void RequestStop( - sync_driver::SyncService::SyncStopDataFate data_fate) override; - void RequestStart() override; - syncer::ModelTypeSet GetPreferredDataTypes() const override; - void OnUserChoseDatatypes(bool sync_everything, - syncer::ModelTypeSet chosen_types) override; - void SetFirstSetupComplete() override; - bool IsFirstSetupInProgress() const override; - std::unique_ptr<SyncSetupInProgressHandle> GetSetupInProgressHandle() - override; - bool IsSetupInProgress() const override; - bool ConfigurationDone() const override; - const GoogleServiceAuthError& GetAuthError() const override; - bool HasUnrecoverableError() const override; - bool IsBackendInitialized() const override; - OpenTabsUIDelegate* GetOpenTabsUIDelegate() override; - bool IsPassphraseRequiredForDecryption() const override; - base::Time GetExplicitPassphraseTime() const override; - bool IsUsingSecondaryPassphrase() const override; - void EnableEncryptEverything() override; - bool IsEncryptEverythingEnabled() const override; - void SetEncryptionPassphrase(const std::string& passphrase, - PassphraseType type) override; - bool SetDecryptionPassphrase(const std::string& passphrase) override; - bool IsCryptographerReady( - const syncer::BaseTransaction* trans) const override; - syncer::UserShare* GetUserShare() const override; - LocalDeviceInfoProvider* GetLocalDeviceInfoProvider() const override; - void RegisterDataTypeController( - sync_driver::DataTypeController* data_type_controller) override; - void ReenableDatatype(syncer::ModelType type) override; - SyncTokenStatus GetSyncTokenStatus() const override; - std::string QuerySyncStatusSummaryString() override; - bool QueryDetailedSyncStatus(syncer::SyncStatus* result) override; - base::string16 GetLastSyncedTimeString() const override; - std::string GetBackendInitializationStateString() const override; - syncer::sessions::SyncSessionSnapshot GetLastSessionSnapshot() const override; - base::Value* GetTypeStatusMap() const override; - const GURL& sync_service_url() const override; - std::string unrecoverable_error_message() const override; - tracked_objects::Location unrecoverable_error_location() const override; - void AddProtocolEventObserver( - browser_sync::ProtocolEventObserver* observer) override; - void RemoveProtocolEventObserver( - browser_sync::ProtocolEventObserver* observer) override; - void AddTypeDebugInfoObserver( - syncer::TypeDebugInfoObserver* observer) override; - void RemoveTypeDebugInfoObserver( - syncer::TypeDebugInfoObserver* observer) override; - base::WeakPtr<syncer::JsController> GetJsController() override; - void GetAllNodes(const base::Callback<void(std::unique_ptr<base::ListValue>)>& - callback) override; - - // DataTypeEncryptionHandler: - bool IsPassphraseRequired() const override; - syncer::ModelTypeSet GetEncryptedDataTypes() const override; - - GoogleServiceAuthError error_; - GURL sync_service_url_; - std::string unrecoverable_error_message_; - std::unique_ptr<syncer::UserShare> user_share_; -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_FAKE_SYNC_SERVICE_H_
diff --git a/components/sync_driver/frontend_data_type_controller.cc b/components/sync_driver/frontend_data_type_controller.cc deleted file mode 100644 index ab7dffd..0000000 --- a/components/sync_driver/frontend_data_type_controller.cc +++ /dev/null
@@ -1,295 +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 "components/sync_driver/frontend_data_type_controller.h" - -#include "base/logging.h" -#include "base/threading/thread_task_runner_handle.h" -#include "components/sync/api/sync_error.h" -#include "components/sync/api/sync_merge_result.h" -#include "components/sync/base/data_type_histogram.h" -#include "components/sync/base/model_type.h" -#include "components/sync_driver/change_processor.h" -#include "components/sync_driver/model_associator.h" -#include "components/sync_driver/sync_client.h" -#include "components/sync_driver/sync_service.h" - -namespace browser_sync { - -FrontendDataTypeController::FrontendDataTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const base::Closure& error_callback, - sync_driver::SyncClient* sync_client) - : DirectoryDataTypeController(ui_thread, error_callback), - sync_client_(sync_client), - state_(NOT_RUNNING) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(sync_client); -} - -void FrontendDataTypeController::LoadModels( - const ModelLoadCallback& model_load_callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - model_load_callback_ = model_load_callback; - - if (state_ != NOT_RUNNING) { - model_load_callback.Run(type(), - syncer::SyncError(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Model already running", - type())); - return; - } - - state_ = MODEL_STARTING; - if (!StartModels()) { - // If we are waiting for some external service to load before associating - // or we failed to start the models, we exit early. state_ will control - // what we perform next. - DCHECK(state_ == NOT_RUNNING || state_ == MODEL_STARTING); - return; - } - - OnModelLoaded(); -} - -void FrontendDataTypeController::OnModelLoaded() { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK_EQ(state_, MODEL_STARTING); - - state_ = MODEL_LOADED; - model_load_callback_.Run(type(), syncer::SyncError()); -} - -void FrontendDataTypeController::StartAssociating( - const StartCallback& start_callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!start_callback.is_null()); - DCHECK_EQ(state_, MODEL_LOADED); - - start_callback_ = start_callback; - state_ = ASSOCIATING; - - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&FrontendDataTypeController::Associate, this)); -} - -void FrontendDataTypeController::Stop() { - DCHECK(thread_checker_.CalledOnValidThread()); - - if (state_ == NOT_RUNNING) - return; - - State prev_state = state_; - state_ = STOPPING; - - // If Stop() is called while Start() is waiting for the datatype model to - // load, abort the start. - if (prev_state == MODEL_STARTING) { - AbortModelLoad(); - // We can just return here since we haven't performed association if we're - // still in MODEL_STARTING. - return; - } - - CleanUpState(); - - if (model_associator()) { - syncer::SyncError error; // Not used. - error = model_associator()->DisassociateModels(); - } - - set_model_associator(NULL); - change_processor_.reset(); - - state_ = NOT_RUNNING; -} - -syncer::ModelSafeGroup FrontendDataTypeController::model_safe_group() - const { - return syncer::GROUP_UI; -} - -std::string FrontendDataTypeController::name() const { - // For logging only. - return syncer::ModelTypeToString(type()); -} - -sync_driver::DataTypeController::State FrontendDataTypeController::state() - const { - return state_; -} - -void FrontendDataTypeController::OnSingleDataTypeUnrecoverableError( - const syncer::SyncError& error) { - DCHECK_EQ(type(), error.model_type()); - RecordUnrecoverableError(error.location(), error.message()); - if (!model_load_callback_.is_null()) { - syncer::SyncMergeResult local_merge_result(type()); - local_merge_result.set_error(error); - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::Bind(model_load_callback_, type(), error)); - } -} - -FrontendDataTypeController::FrontendDataTypeController() - : DirectoryDataTypeController(base::ThreadTaskRunnerHandle::Get(), - base::Closure()), - sync_client_(NULL), - state_(NOT_RUNNING) {} - -FrontendDataTypeController::~FrontendDataTypeController() { - DCHECK(thread_checker_.CalledOnValidThread()); -} - -bool FrontendDataTypeController::StartModels() { - DCHECK_EQ(state_, MODEL_STARTING); - // By default, no additional services need to be started before we can proceed - // with model association. - return true; -} - -void FrontendDataTypeController::RecordUnrecoverableError( - const tracked_objects::Location& from_here, - const std::string& message) { - DVLOG(1) << "Datatype Controller failed for type " - << ModelTypeToString(type()) << " " - << message << " at location " - << from_here.ToString(); - UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeRunFailures", - ModelTypeToHistogramInt(type()), - syncer::MODEL_TYPE_COUNT); - - if (!error_callback_.is_null()) - error_callback_.Run(); -} - -void FrontendDataTypeController::Associate() { - if (state_ != ASSOCIATING) { - // Stop() must have been called while Associate() task have been waiting. - DCHECK_EQ(state_, NOT_RUNNING); - return; - } - - syncer::SyncMergeResult local_merge_result(type()); - syncer::SyncMergeResult syncer_merge_result(type()); - CreateSyncComponents(); - if (!model_associator()->CryptoReadyIfNecessary()) { - StartDone(NEEDS_CRYPTO, local_merge_result, syncer_merge_result); - return; - } - - bool sync_has_nodes = false; - if (!model_associator()->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { - syncer::SyncError error(FROM_HERE, - syncer::SyncError::UNRECOVERABLE_ERROR, - "Failed to load sync nodes", - type()); - local_merge_result.set_error(error); - StartDone(UNRECOVERABLE_ERROR, local_merge_result, syncer_merge_result); - return; - } - - // TODO(zea): Have AssociateModels fill the local and syncer merge results. - base::TimeTicks start_time = base::TimeTicks::Now(); - syncer::SyncError error; - error = model_associator()->AssociateModels( - &local_merge_result, - &syncer_merge_result); - // TODO(lipalani): crbug.com/122690 - handle abort. - RecordAssociationTime(base::TimeTicks::Now() - start_time); - if (error.IsSet()) { - local_merge_result.set_error(error); - StartDone(ASSOCIATION_FAILED, local_merge_result, syncer_merge_result); - return; - } - - state_ = RUNNING; - // FinishStart() invokes the DataTypeManager callback, which can lead to a - // call to Stop() if one of the other data types being started generates an - // error. - StartDone(!sync_has_nodes ? OK_FIRST_RUN : OK, - local_merge_result, - syncer_merge_result); -} - -void FrontendDataTypeController::CleanUpState() { - // Do nothing by default. -} - -void FrontendDataTypeController::CleanUp() { - CleanUpState(); - set_model_associator(NULL); - change_processor_.reset(); -} - -void FrontendDataTypeController::AbortModelLoad() { - DCHECK(thread_checker_.CalledOnValidThread()); - CleanUp(); - state_ = NOT_RUNNING; -} - -void FrontendDataTypeController::StartDone( - ConfigureResult start_result, - const syncer::SyncMergeResult& local_merge_result, - const syncer::SyncMergeResult& syncer_merge_result) { - DCHECK(thread_checker_.CalledOnValidThread()); - if (!IsSuccessfulResult(start_result)) { - if (IsUnrecoverableResult(start_result)) - RecordUnrecoverableError(FROM_HERE, "StartFailed"); - - CleanUp(); - if (start_result == ASSOCIATION_FAILED) { - state_ = DISABLED; - } else { - state_ = NOT_RUNNING; - } - RecordStartFailure(start_result); - } - - start_callback_.Run(start_result, local_merge_result, syncer_merge_result); -} - -void FrontendDataTypeController::RecordAssociationTime(base::TimeDelta time) { - DCHECK(thread_checker_.CalledOnValidThread()); -#define PER_DATA_TYPE_MACRO(type_str) \ - UMA_HISTOGRAM_TIMES("Sync." type_str "AssociationTime", time); - SYNC_DATA_TYPE_HISTOGRAM(type()); -#undef PER_DATA_TYPE_MACRO -} - -void FrontendDataTypeController::RecordStartFailure(ConfigureResult result) { - DCHECK(thread_checker_.CalledOnValidThread()); - UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", - ModelTypeToHistogramInt(type()), - syncer::MODEL_TYPE_COUNT); -#define PER_DATA_TYPE_MACRO(type_str) \ - UMA_HISTOGRAM_ENUMERATION("Sync." type_str "ConfigureFailure", result, \ - MAX_CONFIGURE_RESULT); - SYNC_DATA_TYPE_HISTOGRAM(type()); -#undef PER_DATA_TYPE_MACRO -} - -sync_driver::AssociatorInterface* FrontendDataTypeController::model_associator() - const { - return model_associator_.get(); -} - -void FrontendDataTypeController::set_model_associator( - sync_driver::AssociatorInterface* model_associator) { - model_associator_.reset(model_associator); -} - -sync_driver::ChangeProcessor* FrontendDataTypeController::GetChangeProcessor() - const { - return change_processor_.get(); -} - -void FrontendDataTypeController::set_change_processor( - sync_driver::ChangeProcessor* change_processor) { - change_processor_.reset(change_processor); -} - -} // namespace browser_sync
diff --git a/components/sync_driver/frontend_data_type_controller.h b/components/sync_driver/frontend_data_type_controller.h deleted file mode 100644 index ec875c6..0000000 --- a/components/sync_driver/frontend_data_type_controller.h +++ /dev/null
@@ -1,145 +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 COMPONENTS_SYNC_DRIVER_FRONTEND_DATA_TYPE_CONTROLLER_H__ -#define COMPONENTS_SYNC_DRIVER_FRONTEND_DATA_TYPE_CONTROLLER_H__ - -#include <memory> -#include <string> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/threading/thread_checker.h" -#include "components/sync/core/data_type_error_handler.h" -#include "components/sync_driver/directory_data_type_controller.h" - -namespace base { -class SingleThreadTaskRunner; -class TimeDelta; -} - -namespace syncer { -class SyncError; -} - -namespace sync_driver { -class AssociatorInterface; -class ChangeProcessor; -class SyncClient; -} - -namespace browser_sync { - -// Implementation for datatypes that reside on the frontend thread -// (UI thread). This is the same thread we perform initialization on, so we -// don't have to worry about thread safety. The main start/stop funtionality is -// implemented by default. -// Derived classes must implement (at least): -// syncer::ModelType type() const -// void CreateSyncComponents(); -// NOTE: This class is deprecated! New sync datatypes should be using the -// syncer::SyncableService API and the UIDataTypeController instead. -// TODO(zea): Delete this once all types are on the new API. -class FrontendDataTypeController - : public sync_driver::DirectoryDataTypeController { - public: - FrontendDataTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const base::Closure& error_callback, - sync_driver::SyncClient* sync_client); - - // DataTypeController interface. - void LoadModels(const ModelLoadCallback& model_load_callback) override; - void StartAssociating(const StartCallback& start_callback) override; - void Stop() override; - syncer::ModelType type() const override = 0; - syncer::ModelSafeGroup model_safe_group() const override; - std::string name() const override; - State state() const override; - - // DataTypeErrorHandler interface. - void OnSingleDataTypeUnrecoverableError( - const syncer::SyncError& error) override; - - protected: - friend class FrontendDataTypeControllerMock; - - // For testing only. - FrontendDataTypeController(); - ~FrontendDataTypeController() override; - - // Kick off any dependent services that need to be running before we can - // associate models. The default implementation is a no-op. - // Return value: - // True - if models are ready and association can proceed. - // False - if models are not ready. Associate() should be called when the - // models are ready. Refer to Start(_) implementation. - virtual bool StartModels(); - - // Datatype specific creation of sync components. - virtual void CreateSyncComponents() = 0; - - // Perform any DataType controller specific state cleanup before stopping - // the datatype controller. The default implementation is a no-op. - virtual void CleanUpState(); - - // Helper method for cleaning up state and running the start callback. - virtual void StartDone( - ConfigureResult start_result, - const syncer::SyncMergeResult& local_merge_result, - const syncer::SyncMergeResult& syncer_merge_result); - - // Record association time. - virtual void RecordAssociationTime(base::TimeDelta time); - // Record causes of start failure. - virtual void RecordStartFailure(ConfigureResult result); - - virtual sync_driver::AssociatorInterface* model_associator() const; - virtual void set_model_associator( - sync_driver::AssociatorInterface* associator); - sync_driver::ChangeProcessor* GetChangeProcessor() const override; - virtual void set_change_processor(sync_driver::ChangeProcessor* processor); - - // Handles the reporting of unrecoverable error. It records stuff in - // UMA and reports to breakpad. - // Virtual for testing purpose. - virtual void RecordUnrecoverableError( - const tracked_objects::Location& from_here, - const std::string& message); - - // If the DTC is waiting for models to load, once the models are - // loaded the datatype service will call this function on DTC to let - // us know that it is safe to start associating. - void OnModelLoaded(); - - sync_driver::SyncClient* const sync_client_; - - State state_; - - StartCallback start_callback_; - ModelLoadCallback model_load_callback_; - - // TODO(sync): transition all datatypes to SyncableService and deprecate - // AssociatorInterface. - std::unique_ptr<sync_driver::AssociatorInterface> model_associator_; - std::unique_ptr<sync_driver::ChangeProcessor> change_processor_; - - private: - // Build sync components and associate models. - virtual void Associate(); - - void AbortModelLoad(); - - // Clean up our state and state variables. Called in response - // to a failure or abort or stop. - void CleanUp(); - - base::ThreadChecker thread_checker_; - - DISALLOW_COPY_AND_ASSIGN(FrontendDataTypeController); -}; - -} // namespace browser_sync - -#endif // COMPONENTS_SYNC_DRIVER_FRONTEND_DATA_TYPE_CONTROLLER_H__
diff --git a/components/sync_driver/frontend_data_type_controller_mock.cc b/components/sync_driver/frontend_data_type_controller_mock.cc deleted file mode 100644 index c2fcd03..0000000 --- a/components/sync_driver/frontend_data_type_controller_mock.cc +++ /dev/null
@@ -1,13 +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. - -#include "components/sync_driver/frontend_data_type_controller_mock.h" - -namespace browser_sync { - -FrontendDataTypeControllerMock::FrontendDataTypeControllerMock() {} - -FrontendDataTypeControllerMock::~FrontendDataTypeControllerMock() {} - -} // namespace browser_sync
diff --git a/components/sync_driver/frontend_data_type_controller_mock.h b/components/sync_driver/frontend_data_type_controller_mock.h deleted file mode 100644 index f2c00f7b..0000000 --- a/components/sync_driver/frontend_data_type_controller_mock.h +++ /dev/null
@@ -1,59 +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 COMPONENTS_SYNC_DRIVER_FRONTEND_DATA_TYPE_CONTROLLER_MOCK_H__ -#define COMPONENTS_SYNC_DRIVER_FRONTEND_DATA_TYPE_CONTROLLER_MOCK_H__ - -#include <string> - -#include "components/sync/api/sync_error.h" -#include "components/sync_driver/frontend_data_type_controller.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace browser_sync { - -class FrontendDataTypeControllerMock : public FrontendDataTypeController { - public: - FrontendDataTypeControllerMock(); - - // DataTypeController mocks. - MOCK_METHOD1(StartAssociating, - void(const StartCallback& start_callback)); - MOCK_METHOD1(LoadModels, void(const ModelLoadCallback& model_load_callback)); - - MOCK_METHOD0(Stop, void()); - MOCK_METHOD0(enabled, bool()); - MOCK_CONST_METHOD0(type, syncer::ModelType()); - MOCK_CONST_METHOD0(name, std::string()); - MOCK_CONST_METHOD0(model_safe_group, syncer::ModelSafeGroup()); - MOCK_CONST_METHOD0(state, State()); - MOCK_METHOD2(OnUnrecoverableError, void(const tracked_objects::Location&, - const std::string&)); - - // FrontendDataTypeController mocks. - MOCK_METHOD0(StartModels, bool()); - MOCK_METHOD0(Associate, void()); - MOCK_METHOD0(CreateSyncComponents, void()); - MOCK_METHOD2(StartFailed, void(ConfigureResult result, - const syncer::SyncError& error)); - MOCK_METHOD1(FinishStart, void(ConfigureResult result)); - MOCK_METHOD0(CleanUpState, void()); - MOCK_CONST_METHOD0(model_associator, sync_driver::AssociatorInterface*()); - MOCK_METHOD1(set_model_associator, - void(sync_driver::AssociatorInterface* associator)); - MOCK_CONST_METHOD0(change_processor, sync_driver::ChangeProcessor*()); - MOCK_METHOD1(set_change_processor, - void(sync_driver::ChangeProcessor* processor)); - MOCK_METHOD2(RecordUnrecoverableError, void(const tracked_objects::Location&, - const std::string&)); - MOCK_METHOD1(RecordAssociationTime, void(base::TimeDelta time)); - MOCK_METHOD1(RecordStartFailure, void(ConfigureResult result)); - - protected: - virtual ~FrontendDataTypeControllerMock(); -}; - -} // namespace browser_sync - -#endif // COMPONENTS_SYNC_DRIVER_FRONTEND_DATA_TYPE_CONTROLLER_MOCK_H__
diff --git a/components/sync_driver/frontend_data_type_controller_unittest.cc b/components/sync_driver/frontend_data_type_controller_unittest.cc deleted file mode 100644 index a64ccc8..0000000 --- a/components/sync_driver/frontend_data_type_controller_unittest.cc +++ /dev/null
@@ -1,270 +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 "components/sync_driver/frontend_data_type_controller.h" - -#include <memory> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/callback.h" -#include "base/location.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/single_thread_task_runner.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/tracked_objects.h" -#include "components/sync_driver/change_processor_mock.h" -#include "components/sync_driver/data_type_controller_mock.h" -#include "components/sync_driver/fake_sync_client.h" -#include "components/sync_driver/fake_sync_service.h" -#include "components/sync_driver/frontend_data_type_controller_mock.h" -#include "components/sync_driver/model_associator_mock.h" -#include "components/sync_driver/sync_api_component_factory_mock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using browser_sync::FrontendDataTypeController; -using browser_sync::FrontendDataTypeControllerMock; -using sync_driver::ChangeProcessorMock; -using sync_driver::DataTypeController; -using sync_driver::ModelAssociatorMock; -using sync_driver::ModelLoadCallbackMock; -using sync_driver::StartCallbackMock; -using testing::_; -using testing::DoAll; -using testing::InvokeWithoutArgs; -using testing::Return; -using testing::SetArgumentPointee; -using testing::StrictMock; - -namespace { - -class FrontendDataTypeControllerFake : public FrontendDataTypeController { - public: - FrontendDataTypeControllerFake( - sync_driver::SyncClient* sync_client, - FrontendDataTypeControllerMock* mock) - : FrontendDataTypeController(base::ThreadTaskRunnerHandle::Get(), - base::Closure(), - sync_client), - mock_(mock), - sync_client_(sync_client) {} - syncer::ModelType type() const override { return syncer::BOOKMARKS; } - - private: - ~FrontendDataTypeControllerFake() override {} - - void CreateSyncComponents() override { - sync_driver::SyncApiComponentFactory::SyncComponents sync_components = - sync_client_->GetSyncApiComponentFactory()-> - CreateBookmarkSyncComponents(nullptr, this); - model_associator_.reset(sync_components.model_associator); - change_processor_.reset(sync_components.change_processor); - } - - // We mock the following methods because their default implementations do - // nothing, but we still want to make sure they're called appropriately. - bool StartModels() override { return mock_->StartModels(); } - void CleanUpState() override { mock_->CleanUpState(); } - void RecordUnrecoverableError(const tracked_objects::Location& from_here, - const std::string& message) override { - mock_->RecordUnrecoverableError(from_here, message); - } - void RecordAssociationTime(base::TimeDelta time) override { - mock_->RecordAssociationTime(time); - } - void RecordStartFailure(DataTypeController::ConfigureResult result) override { - mock_->RecordStartFailure(result); - } - - FrontendDataTypeControllerMock* mock_; - sync_driver::SyncClient* sync_client_; -}; - -class SyncFrontendDataTypeControllerTest : public testing::Test, - public sync_driver::FakeSyncClient { - public: - SyncFrontendDataTypeControllerTest() - : sync_driver::FakeSyncClient(&profile_sync_factory_), - service_() {} - - // FakeSyncClient overrides. - sync_driver::SyncService* GetSyncService() override { - return &service_; - } - - void SetUp() override { - dtc_mock_ = new StrictMock<FrontendDataTypeControllerMock>(); - frontend_dtc_ = - new FrontendDataTypeControllerFake(this, - dtc_mock_.get()); - } - - protected: - void SetStartExpectations() { - EXPECT_CALL(*dtc_mock_.get(), StartModels()).WillOnce(Return(true)); - EXPECT_CALL(model_load_callback_, Run(_, _)); - model_associator_ = new ModelAssociatorMock(); - change_processor_ = new ChangeProcessorMock(); - EXPECT_CALL(profile_sync_factory_, CreateBookmarkSyncComponents(_, _)). - WillOnce(Return(sync_driver::SyncApiComponentFactory::SyncComponents( - model_associator_, change_processor_))); - } - - void SetAssociateExpectations() { - EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()). - WillOnce(Return(true)); - EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)). - WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true))); - EXPECT_CALL(*model_associator_, AssociateModels(_, _)). - WillOnce(Return(syncer::SyncError())); - EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_)); - } - - void SetActivateExpectations(DataTypeController::ConfigureResult result) { - EXPECT_CALL(start_callback_, Run(result, _, _)); - } - - void SetStopExpectations() { - EXPECT_CALL(*dtc_mock_.get(), CleanUpState()); - EXPECT_CALL(*model_associator_, DisassociateModels()). - WillOnce(Return(syncer::SyncError())); - } - - void SetStartFailExpectations(DataTypeController::ConfigureResult result) { - if (DataTypeController::IsUnrecoverableResult(result)) - EXPECT_CALL(*dtc_mock_.get(), RecordUnrecoverableError(_, _)); - EXPECT_CALL(*dtc_mock_.get(), CleanUpState()); - EXPECT_CALL(*dtc_mock_.get(), RecordStartFailure(result)); - EXPECT_CALL(start_callback_, Run(result, _, _)); - } - - void Start() { - frontend_dtc_->LoadModels( - base::Bind(&ModelLoadCallbackMock::Run, - base::Unretained(&model_load_callback_))); - frontend_dtc_->StartAssociating( - base::Bind(&StartCallbackMock::Run, - base::Unretained(&start_callback_))); - PumpLoop(); - } - - void PumpLoop() { base::RunLoop().RunUntilIdle(); } - - base::MessageLoop message_loop_; - scoped_refptr<FrontendDataTypeControllerFake> frontend_dtc_; - SyncApiComponentFactoryMock profile_sync_factory_; - scoped_refptr<FrontendDataTypeControllerMock> dtc_mock_; - sync_driver::FakeSyncService service_; - ModelAssociatorMock* model_associator_; - ChangeProcessorMock* change_processor_; - StartCallbackMock start_callback_; - ModelLoadCallbackMock model_load_callback_; -}; - -TEST_F(SyncFrontendDataTypeControllerTest, StartOk) { - SetStartExpectations(); - SetAssociateExpectations(); - SetActivateExpectations(DataTypeController::OK); - EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); - Start(); - EXPECT_EQ(DataTypeController::RUNNING, frontend_dtc_->state()); -} - -TEST_F(SyncFrontendDataTypeControllerTest, StartFirstRun) { - SetStartExpectations(); - EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()). - WillOnce(Return(true)); - EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)). - WillOnce(DoAll(SetArgumentPointee<0>(false), Return(true))); - EXPECT_CALL(*model_associator_, AssociateModels(_, _)). - WillOnce(Return(syncer::SyncError())); - EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_)); - SetActivateExpectations(DataTypeController::OK_FIRST_RUN); - EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); - Start(); - EXPECT_EQ(DataTypeController::RUNNING, frontend_dtc_->state()); -} - -TEST_F(SyncFrontendDataTypeControllerTest, StartStopBeforeAssociation) { - EXPECT_CALL(*dtc_mock_.get(), StartModels()).WillOnce(Return(true)); - EXPECT_CALL(*dtc_mock_.get(), CleanUpState()); - EXPECT_CALL(model_load_callback_, Run(_, _)); - EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&FrontendDataTypeController::Stop, frontend_dtc_)); - Start(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); -} - -TEST_F(SyncFrontendDataTypeControllerTest, AbortDuringStartModels) { - EXPECT_CALL(*dtc_mock_.get(), StartModels()).WillOnce(Return(false)); - EXPECT_CALL(*dtc_mock_.get(), CleanUpState()); - EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); - frontend_dtc_->LoadModels( - base::Bind(&ModelLoadCallbackMock::Run, - base::Unretained(&model_load_callback_))); - EXPECT_EQ(DataTypeController::MODEL_STARTING, frontend_dtc_->state()); - frontend_dtc_->Stop(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); -} - -TEST_F(SyncFrontendDataTypeControllerTest, StartAssociationFailed) { - SetStartExpectations(); - EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()). - WillOnce(Return(true)); - EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)). - WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true))); - EXPECT_CALL(*model_associator_, AssociateModels(_, _)). - WillOnce(Return(syncer::SyncError(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "error", - syncer::BOOKMARKS))); - - EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_)); - SetStartFailExpectations(DataTypeController::ASSOCIATION_FAILED); - // Set up association to fail with an association failed error. - EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); - Start(); - EXPECT_EQ(DataTypeController::DISABLED, frontend_dtc_->state()); -} - -TEST_F(SyncFrontendDataTypeControllerTest, - StartAssociationTriggersUnrecoverableError) { - SetStartExpectations(); - SetStartFailExpectations(DataTypeController::UNRECOVERABLE_ERROR); - // Set up association to fail with an unrecoverable error. - EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()). - WillRepeatedly(Return(true)); - EXPECT_CALL(*model_associator_, SyncModelHasUserCreatedNodes(_)). - WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(false))); - EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); - Start(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); -} - -TEST_F(SyncFrontendDataTypeControllerTest, StartAssociationCryptoNotReady) { - SetStartExpectations(); - SetStartFailExpectations(DataTypeController::NEEDS_CRYPTO); - // Set up association to fail with a NEEDS_CRYPTO error. - EXPECT_CALL(*model_associator_, CryptoReadyIfNecessary()). - WillRepeatedly(Return(false)); - EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); - Start(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); -} - -TEST_F(SyncFrontendDataTypeControllerTest, Stop) { - SetStartExpectations(); - SetAssociateExpectations(); - SetActivateExpectations(DataTypeController::OK); - SetStopExpectations(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); - Start(); - EXPECT_EQ(DataTypeController::RUNNING, frontend_dtc_->state()); - frontend_dtc_->Stop(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, frontend_dtc_->state()); -} - -} // namespace
diff --git a/components/sync_driver/generic_change_processor.cc b/components/sync_driver/generic_change_processor.cc deleted file mode 100644 index 581b565..0000000 --- a/components/sync_driver/generic_change_processor.cc +++ /dev/null
@@ -1,705 +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 "components/sync_driver/generic_change_processor.h" - -#include <stddef.h> - -#include <algorithm> -#include <string> -#include <utility> - -#include "base/location.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/utf_string_conversions.h" -#include "base/threading/thread_task_runner_handle.h" -#include "components/sync/api/sync_change.h" -#include "components/sync/api/sync_error.h" -#include "components/sync/api/syncable_service.h" -#include "components/sync/base/unrecoverable_error_handler.h" -#include "components/sync/core/base_node.h" -#include "components/sync/core/change_record.h" -#include "components/sync/core/data_type_error_handler.h" -#include "components/sync/core/read_node.h" -#include "components/sync/core/read_transaction.h" -#include "components/sync/core/write_node.h" -#include "components/sync/core/write_transaction.h" -#include "components/sync/syncable/entry.h" // TODO(tim): Bug 123674. -#include "components/sync_driver/sync_api_component_factory.h" -#include "components/sync_driver/sync_client.h" - -namespace sync_driver { - -namespace { - -const int kContextSizeLimit = 1024; // Datatype context size limit. - -void SetNodeSpecifics(const sync_pb::EntitySpecifics& entity_specifics, - syncer::WriteNode* write_node) { - if (syncer::GetModelTypeFromSpecifics(entity_specifics) == - syncer::PASSWORDS) { - write_node->SetPasswordSpecifics( - entity_specifics.password().client_only_encrypted_data()); - } else { - write_node->SetEntitySpecifics(entity_specifics); - } -} - -// Helper function to convert AttachmentId to AttachmentMetadataRecord. -sync_pb::AttachmentMetadataRecord AttachmentIdToRecord( - const syncer::AttachmentId& attachment_id) { - sync_pb::AttachmentMetadataRecord record; - *record.mutable_id() = attachment_id.GetProto(); - return record; -} - -// Replace |write_nodes|'s attachment ids with |attachment_ids|. -void SetAttachmentMetadata(const syncer::AttachmentIdList& attachment_ids, - syncer::WriteNode* write_node) { - DCHECK(write_node); - sync_pb::AttachmentMetadata attachment_metadata; - std::transform( - attachment_ids.begin(), - attachment_ids.end(), - RepeatedFieldBackInserter(attachment_metadata.mutable_record()), - AttachmentIdToRecord); - write_node->SetAttachmentMetadata(attachment_metadata); -} - -syncer::SyncData BuildRemoteSyncData( - int64_t sync_id, - const syncer::ReadNode& read_node, - const syncer::AttachmentServiceProxy& attachment_service_proxy) { - const syncer::AttachmentIdList& attachment_ids = read_node.GetAttachmentIds(); - switch (read_node.GetModelType()) { - case syncer::PASSWORDS: { - // Passwords must be accessed differently, to account for their - // encryption, and stored into a temporary EntitySpecifics. - sync_pb::EntitySpecifics password_holder; - password_holder.mutable_password() - ->mutable_client_only_encrypted_data() - ->CopyFrom(read_node.GetPasswordSpecifics()); - return syncer::SyncData::CreateRemoteData( - sync_id, password_holder, read_node.GetModificationTime(), - attachment_ids, attachment_service_proxy); - } - case syncer::SESSIONS: - // Include tag hashes for sessions data type to allow discarding during - // merge if re-hashing by the service gives a different value. This is to - // allow removal of incorrectly hashed values, see crbug.com/604657. This - // cannot be done in the processor because only the service knows how to - // generate a tag from the specifics. We don't set this value for other - // data types because they shouldn't need it and it costs memory to hold - // another copy of this string around. - return syncer::SyncData::CreateRemoteData( - sync_id, read_node.GetEntitySpecifics(), - read_node.GetModificationTime(), attachment_ids, - attachment_service_proxy, read_node.GetEntry()->GetUniqueClientTag()); - default: - // Use the specifics directly, encryption has already been handled. - return syncer::SyncData::CreateRemoteData( - sync_id, read_node.GetEntitySpecifics(), - read_node.GetModificationTime(), attachment_ids, - attachment_service_proxy); - } -} - -} // namespace - -GenericChangeProcessor::GenericChangeProcessor( - syncer::ModelType type, - syncer::DataTypeErrorHandler* error_handler, - const base::WeakPtr<syncer::SyncableService>& local_service, - const base::WeakPtr<syncer::SyncMergeResult>& merge_result, - syncer::UserShare* user_share, - SyncClient* sync_client, - std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store) - : ChangeProcessor(error_handler), - type_(type), - local_service_(local_service), - merge_result_(merge_result), - share_handle_(user_share), - weak_ptr_factory_(this) { - DCHECK(CalledOnValidThread()); - DCHECK_NE(type_, syncer::UNSPECIFIED); - if (attachment_store) { - std::string store_birthday; - { - syncer::ReadTransaction trans(FROM_HERE, share_handle()); - store_birthday = trans.GetStoreBirthday(); - } - attachment_service_ = - sync_client->GetSyncApiComponentFactory()->CreateAttachmentService( - std::move(attachment_store), *user_share, store_birthday, type, - this); - attachment_service_weak_ptr_factory_.reset( - new base::WeakPtrFactory<syncer::AttachmentService>( - attachment_service_.get())); - attachment_service_proxy_ = syncer::AttachmentServiceProxy( - base::ThreadTaskRunnerHandle::Get(), - attachment_service_weak_ptr_factory_->GetWeakPtr()); - UploadAllAttachmentsNotOnServer(); - } else { - attachment_service_proxy_ = syncer::AttachmentServiceProxy( - base::ThreadTaskRunnerHandle::Get(), - base::WeakPtr<syncer::AttachmentService>()); - } -} - -GenericChangeProcessor::~GenericChangeProcessor() { - DCHECK(CalledOnValidThread()); -} - -void GenericChangeProcessor::ApplyChangesFromSyncModel( - const syncer::BaseTransaction* trans, - int64_t model_version, - const syncer::ImmutableChangeRecordList& changes) { - DCHECK(CalledOnValidThread()); - DCHECK(syncer_changes_.empty()); - for (syncer::ChangeRecordList::const_iterator it = - changes.Get().begin(); it != changes.Get().end(); ++it) { - if (it->action == syncer::ChangeRecord::ACTION_DELETE) { - std::unique_ptr<sync_pb::EntitySpecifics> specifics; - if (it->specifics.has_password()) { - DCHECK(it->extra.get()); - specifics.reset(new sync_pb::EntitySpecifics(it->specifics)); - specifics->mutable_password()->mutable_client_only_encrypted_data()-> - CopyFrom(it->extra->unencrypted()); - } - const syncer::AttachmentIdList empty_list_of_attachment_ids; - syncer_changes_.push_back(syncer::SyncChange( - FROM_HERE, syncer::SyncChange::ACTION_DELETE, - syncer::SyncData::CreateRemoteData( - it->id, specifics ? *specifics : it->specifics, base::Time(), - empty_list_of_attachment_ids, attachment_service_proxy_))); - } else { - syncer::SyncChange::SyncChangeType action = - (it->action == syncer::ChangeRecord::ACTION_ADD) ? - syncer::SyncChange::ACTION_ADD : syncer::SyncChange::ACTION_UPDATE; - // Need to load specifics from node. - syncer::ReadNode read_node(trans); - if (read_node.InitByIdLookup(it->id) != syncer::BaseNode::INIT_OK) { - syncer::SyncError error( - FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Failed to look up data for received change with id " + - base::Int64ToString(it->id), - syncer::GetModelTypeFromSpecifics(it->specifics)); - error_handler()->OnSingleDataTypeUnrecoverableError(error); - return; - } - syncer_changes_.push_back(syncer::SyncChange( - FROM_HERE, action, - BuildRemoteSyncData(it->id, read_node, attachment_service_proxy_))); - } - } -} - -void GenericChangeProcessor::CommitChangesFromSyncModel() { - DCHECK(CalledOnValidThread()); - if (syncer_changes_.empty()) - return; - if (!local_service_.get()) { - syncer::ModelType type = syncer_changes_[0].sync_data().GetDataType(); - syncer::SyncError error(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Local service destroyed.", - type); - error_handler()->OnSingleDataTypeUnrecoverableError(error); - return; - } - syncer::SyncError error = local_service_->ProcessSyncChanges(FROM_HERE, - syncer_changes_); - syncer_changes_.clear(); - if (error.IsSet()) - error_handler()->OnSingleDataTypeUnrecoverableError(error); -} - -syncer::SyncDataList GenericChangeProcessor::GetAllSyncData( - syncer::ModelType type) const { - DCHECK_EQ(type_, type); - // This is slow / memory intensive. Should be used sparingly by datatypes. - syncer::SyncDataList data; - GetAllSyncDataReturnError(&data); - return data; -} - -syncer::SyncError GenericChangeProcessor::UpdateDataTypeContext( - syncer::ModelType type, - syncer::SyncChangeProcessor::ContextRefreshStatus refresh_status, - const std::string& context) { - DCHECK(syncer::ProtocolTypes().Has(type)); - DCHECK_EQ(type_, type); - - if (context.size() > static_cast<size_t>(kContextSizeLimit)) { - return syncer::SyncError(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Context size limit exceeded.", - type); - } - - syncer::WriteTransaction trans(FROM_HERE, share_handle()); - trans.SetDataTypeContext(type, refresh_status, context); - - // TODO(zea): plumb a pointer to the PSS or SyncManagerImpl here so we can - // trigger a datatype nudge if |refresh_status == REFRESH_NEEDED|. - - return syncer::SyncError(); -} - -void GenericChangeProcessor::OnAttachmentUploaded( - const syncer::AttachmentId& attachment_id) { - syncer::WriteTransaction trans(FROM_HERE, share_handle()); - trans.UpdateEntriesMarkAttachmentAsOnServer(attachment_id); -} - -syncer::SyncError GenericChangeProcessor::GetAllSyncDataReturnError( - syncer::SyncDataList* current_sync_data) const { - DCHECK(CalledOnValidThread()); - std::string type_name = syncer::ModelTypeToString(type_); - syncer::ReadTransaction trans(FROM_HERE, share_handle()); - syncer::ReadNode root(&trans); - if (root.InitTypeRoot(type_) != syncer::BaseNode::INIT_OK) { - syncer::SyncError error(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Server did not create the top-level " + type_name + - " node. We might be running against an out-of-" - "date server.", - type_); - return error; - } - - // TODO(akalin): We'll have to do a tree traversal for bookmarks. - DCHECK_NE(type_, syncer::BOOKMARKS); - - std::vector<int64_t> child_ids; - root.GetChildIds(&child_ids); - - for (std::vector<int64_t>::iterator it = child_ids.begin(); - it != child_ids.end(); ++it) { - syncer::ReadNode sync_child_node(&trans); - if (sync_child_node.InitByIdLookup(*it) != - syncer::BaseNode::INIT_OK) { - syncer::SyncError error( - FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Failed to fetch child node for type " + type_name + ".", - type_); - return error; - } - current_sync_data->push_back(BuildRemoteSyncData( - sync_child_node.GetId(), sync_child_node, attachment_service_proxy_)); - } - return syncer::SyncError(); -} - -bool GenericChangeProcessor::GetDataTypeContext(std::string* context) const { - syncer::ReadTransaction trans(FROM_HERE, share_handle()); - sync_pb::DataTypeContext context_proto; - trans.GetDataTypeContext(type_, &context_proto); - if (!context_proto.has_context()) - return false; - - DCHECK_EQ(type_, - syncer::GetModelTypeFromSpecificsFieldNumber( - context_proto.data_type_id())); - *context = context_proto.context(); - return true; -} - -int GenericChangeProcessor::GetSyncCount() { - syncer::ReadTransaction trans(FROM_HERE, share_handle()); - syncer::ReadNode root(&trans); - if (root.InitTypeRoot(type_) != syncer::BaseNode::INIT_OK) - return 0; - - // Subtract one to account for type's root node. - return root.GetTotalNodeCount() - 1; -} - -namespace { - -// WARNING: this code is sensitive to compiler optimizations. Be careful -// modifying any code around an OnSingleDataTypeUnrecoverableError call, else -// the compiler attempts to merge it with other calls, losing useful information -// in breakpad uploads. -syncer::SyncError LogLookupFailure( - syncer::BaseNode::InitByLookupResult lookup_result, - const tracked_objects::Location& from_here, - const std::string& error_prefix, - syncer::ModelType type, - syncer::DataTypeErrorHandler* error_handler) { - switch (lookup_result) { - case syncer::BaseNode::INIT_FAILED_ENTRY_NOT_GOOD: { - syncer::SyncError error; - error.Reset(from_here, - error_prefix + - "could not find entry matching the lookup criteria.", - type); - error_handler->OnSingleDataTypeUnrecoverableError(error); - LOG(ERROR) << "Delete: Bad entry."; - return error; - } - case syncer::BaseNode::INIT_FAILED_ENTRY_IS_DEL: { - syncer::SyncError error; - error.Reset(from_here, error_prefix + "entry is already deleted.", type); - error_handler->OnSingleDataTypeUnrecoverableError(error); - LOG(ERROR) << "Delete: Deleted entry."; - return error; - } - case syncer::BaseNode::INIT_FAILED_DECRYPT_IF_NECESSARY: { - syncer::SyncError error; - error.Reset(from_here, error_prefix + "unable to decrypt", type); - error_handler->OnSingleDataTypeUnrecoverableError(error); - LOG(ERROR) << "Delete: Undecryptable entry."; - return error; - } - case syncer::BaseNode::INIT_FAILED_PRECONDITION: { - syncer::SyncError error; - error.Reset(from_here, - error_prefix + "a precondition was not met for calling init.", - type); - error_handler->OnSingleDataTypeUnrecoverableError(error); - LOG(ERROR) << "Delete: Failed precondition."; - return error; - } - default: { - syncer::SyncError error; - // Should have listed all the possible error cases above. - error.Reset(from_here, error_prefix + "unknown error", type); - error_handler->OnSingleDataTypeUnrecoverableError(error); - LOG(ERROR) << "Delete: Unknown error."; - return error; - } - } -} - -syncer::SyncError AttemptDelete(const syncer::SyncChange& change, - syncer::ModelType type, - const std::string& type_str, - syncer::WriteNode* node, - syncer::DataTypeErrorHandler* error_handler) { - DCHECK_EQ(change.change_type(), syncer::SyncChange::ACTION_DELETE); - if (change.sync_data().IsLocal()) { - const std::string& tag = syncer::SyncDataLocal(change.sync_data()).GetTag(); - if (tag.empty()) { - syncer::SyncError error( - FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Failed to delete " + type_str + " node. Local data, empty tag. " + - change.location().ToString(), - type); - error_handler->OnSingleDataTypeUnrecoverableError(error); - NOTREACHED(); - return error; - } - - syncer::BaseNode::InitByLookupResult result = - node->InitByClientTagLookup(change.sync_data().GetDataType(), tag); - if (result != syncer::BaseNode::INIT_OK) { - return LogLookupFailure( - result, FROM_HERE, - "Failed to delete " + type_str + " node. Local data. " + - change.location().ToString(), - type, error_handler); - } - } else { - syncer::BaseNode::InitByLookupResult result = node->InitByIdLookup( - syncer::SyncDataRemote(change.sync_data()).GetId()); - if (result != syncer::BaseNode::INIT_OK) { - return LogLookupFailure( - result, FROM_HERE, - "Failed to delete " + type_str + " node. Non-local data. " + - change.location().ToString(), - type, error_handler); - } - } - if (IsActOnceDataType(type)) - node->Drop(); - else - node->Tombstone(); - return syncer::SyncError(); -} - -} // namespace - -syncer::SyncError GenericChangeProcessor::ProcessSyncChanges( - const tracked_objects::Location& from_here, - const syncer::SyncChangeList& list_of_changes) { - DCHECK(CalledOnValidThread()); - - if (list_of_changes.empty()) { - // No work. Exit without entering WriteTransaction. - return syncer::SyncError(); - } - - // Keep track of brand new attachments so we can persist them on this device - // and upload them to the server. - syncer::AttachmentIdSet new_attachments; - - syncer::WriteTransaction trans(from_here, share_handle()); - - for (syncer::SyncChangeList::const_iterator iter = list_of_changes.begin(); - iter != list_of_changes.end(); - ++iter) { - const syncer::SyncChange& change = *iter; - DCHECK_EQ(change.sync_data().GetDataType(), type_); - std::string type_str = syncer::ModelTypeToString(type_); - syncer::WriteNode sync_node(&trans); - if (change.change_type() == syncer::SyncChange::ACTION_DELETE) { - syncer::SyncError error = - AttemptDelete(change, type_, type_str, &sync_node, error_handler()); - if (error.IsSet()) { - NOTREACHED(); - return error; - } - if (merge_result_.get()) { - merge_result_->set_num_items_deleted( - merge_result_->num_items_deleted() + 1); - } - } else if (change.change_type() == syncer::SyncChange::ACTION_ADD) { - syncer::SyncError error = HandleActionAdd( - change, type_str, trans, &sync_node, &new_attachments); - if (error.IsSet()) { - return error; - } - } else if (change.change_type() == syncer::SyncChange::ACTION_UPDATE) { - syncer::SyncError error = HandleActionUpdate( - change, type_str, trans, &sync_node, &new_attachments); - if (error.IsSet()) { - return error; - } - } else { - syncer::SyncError error( - FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Received unset SyncChange in the change processor, " + - change.location().ToString(), - type_); - error_handler()->OnSingleDataTypeUnrecoverableError(error); - NOTREACHED(); - LOG(ERROR) << "Unset sync change."; - return error; - } - } - - if (!new_attachments.empty()) { - // If datatype uses attachments it should have supplied attachment store - // which would initialize attachment_service_. Fail if it isn't so. - if (!attachment_service_.get()) { - syncer::SyncError error( - FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Datatype performs attachment operation without initializing " - "attachment store", - type_); - error_handler()->OnSingleDataTypeUnrecoverableError(error); - NOTREACHED(); - return error; - } - syncer::AttachmentIdList ids_to_upload; - ids_to_upload.reserve(new_attachments.size()); - std::copy(new_attachments.begin(), new_attachments.end(), - std::back_inserter(ids_to_upload)); - attachment_service_->UploadAttachments(ids_to_upload); - } - - return syncer::SyncError(); -} - -// WARNING: this code is sensitive to compiler optimizations. Be careful -// modifying any code around an OnSingleDataTypeUnrecoverableError call, else -// the compiler attempts to merge it with other calls, losing useful information -// in breakpad uploads. -syncer::SyncError GenericChangeProcessor::HandleActionAdd( - const syncer::SyncChange& change, - const std::string& type_str, - const syncer::WriteTransaction& trans, - syncer::WriteNode* sync_node, - syncer::AttachmentIdSet* new_attachments) { - // TODO(sync): Handle other types of creation (custom parents, folders, - // etc.). - const syncer::SyncDataLocal sync_data_local(change.sync_data()); - syncer::WriteNode::InitUniqueByCreationResult result = - sync_node->InitUniqueByCreation(sync_data_local.GetDataType(), - sync_data_local.GetTag()); - if (result != syncer::WriteNode::INIT_SUCCESS) { - std::string error_prefix = "Failed to create " + type_str + " node: " + - change.location().ToString() + ", "; - switch (result) { - case syncer::WriteNode::INIT_FAILED_EMPTY_TAG: { - syncer::SyncError error; - error.Reset(FROM_HERE, error_prefix + "empty tag", type_); - error_handler()->OnSingleDataTypeUnrecoverableError(error); - LOG(ERROR) << "Create: Empty tag."; - return error; - } - case syncer::WriteNode::INIT_FAILED_COULD_NOT_CREATE_ENTRY: { - syncer::SyncError error; - error.Reset(FROM_HERE, error_prefix + "failed to create entry", type_); - error_handler()->OnSingleDataTypeUnrecoverableError(error); - LOG(ERROR) << "Create: Could not create entry."; - return error; - } - case syncer::WriteNode::INIT_FAILED_SET_PREDECESSOR: { - syncer::SyncError error; - error.Reset( - FROM_HERE, error_prefix + "failed to set predecessor", type_); - error_handler()->OnSingleDataTypeUnrecoverableError(error); - LOG(ERROR) << "Create: Bad predecessor."; - return error; - } - case syncer::WriteNode::INIT_FAILED_DECRYPT_EXISTING_ENTRY: { - syncer::SyncError error; - error.Reset(FROM_HERE, error_prefix + "failed to decrypt", type_); - error_handler()->OnSingleDataTypeUnrecoverableError(error); - LOG(ERROR) << "Create: Failed to decrypt."; - return error; - } - default: { - syncer::SyncError error; - error.Reset(FROM_HERE, error_prefix + "unknown error", type_); - error_handler()->OnSingleDataTypeUnrecoverableError(error); - LOG(ERROR) << "Create: Unknown error."; - return error; - } - } - } - sync_node->SetTitle(change.sync_data().GetTitle()); - SetNodeSpecifics(sync_data_local.GetSpecifics(), sync_node); - - syncer::AttachmentIdList attachment_ids = sync_data_local.GetAttachmentIds(); - SetAttachmentMetadata(attachment_ids, sync_node); - - // Return any newly added attachments. - new_attachments->insert(attachment_ids.begin(), attachment_ids.end()); - if (merge_result_.get()) { - merge_result_->set_num_items_added(merge_result_->num_items_added() + 1); - } - return syncer::SyncError(); -} -// WARNING: this code is sensitive to compiler optimizations. Be careful -// modifying any code around an OnSingleDataTypeUnrecoverableError call, else -// the compiler attempts to merge it with other calls, losing useful information -// in breakpad uploads. -syncer::SyncError GenericChangeProcessor::HandleActionUpdate( - const syncer::SyncChange& change, - const std::string& type_str, - const syncer::WriteTransaction& trans, - syncer::WriteNode* sync_node, - syncer::AttachmentIdSet* new_attachments) { - const syncer::SyncDataLocal sync_data_local(change.sync_data()); - syncer::BaseNode::InitByLookupResult result = - sync_node->InitByClientTagLookup(sync_data_local.GetDataType(), - sync_data_local.GetTag()); - if (result != syncer::BaseNode::INIT_OK) { - std::string error_prefix = "Failed to load " + type_str + " node. " + - change.location().ToString() + ", "; - if (result == syncer::BaseNode::INIT_FAILED_PRECONDITION) { - syncer::SyncError error; - error.Reset(FROM_HERE, error_prefix + "empty tag", type_); - error_handler()->OnSingleDataTypeUnrecoverableError(error); - LOG(ERROR) << "Update: Empty tag."; - return error; - } else if (result == syncer::BaseNode::INIT_FAILED_ENTRY_NOT_GOOD) { - syncer::SyncError error; - error.Reset(FROM_HERE, error_prefix + "bad entry", type_); - error_handler()->OnSingleDataTypeUnrecoverableError(error); - LOG(ERROR) << "Update: bad entry."; - return error; - } else if (result == syncer::BaseNode::INIT_FAILED_ENTRY_IS_DEL) { - syncer::SyncError error; - error.Reset(FROM_HERE, error_prefix + "deleted entry", type_); - error_handler()->OnSingleDataTypeUnrecoverableError(error); - LOG(ERROR) << "Update: deleted entry."; - return error; - } else if (result == syncer::BaseNode::INIT_FAILED_DECRYPT_IF_NECESSARY) { - syncer::SyncError error; - error.Reset(FROM_HERE, error_prefix + "failed to decrypt", type_); - error_handler()->OnSingleDataTypeUnrecoverableError(error); - LOG(ERROR) << "Update: Failed to decrypt."; - return error; - } else { - NOTREACHED(); - syncer::SyncError error; - error.Reset(FROM_HERE, error_prefix + "unknown error", type_); - error_handler()->OnSingleDataTypeUnrecoverableError(error); - LOG(ERROR) << "Update: Unknown error."; - return error; - } - } - - sync_node->SetTitle(change.sync_data().GetTitle()); - SetNodeSpecifics(sync_data_local.GetSpecifics(), sync_node); - syncer::AttachmentIdList attachment_ids = sync_data_local.GetAttachmentIds(); - SetAttachmentMetadata(attachment_ids, sync_node); - - // Return any newly added attachments. - new_attachments->insert(attachment_ids.begin(), attachment_ids.end()); - - if (merge_result_.get()) { - merge_result_->set_num_items_modified(merge_result_->num_items_modified() + - 1); - } - // TODO(sync): Support updating other parts of the sync node (title, - // successor, parent, etc.). - return syncer::SyncError(); -} - -bool GenericChangeProcessor::SyncModelHasUserCreatedNodes(bool* has_nodes) { - DCHECK(CalledOnValidThread()); - DCHECK(has_nodes); - std::string type_name = syncer::ModelTypeToString(type_); - std::string err_str = "Server did not create the top-level " + type_name + - " node. We might be running against an out-of-date server."; - *has_nodes = false; - syncer::ReadTransaction trans(FROM_HERE, share_handle()); - syncer::ReadNode type_root_node(&trans); - if (type_root_node.InitTypeRoot(type_) != syncer::BaseNode::INIT_OK) { - LOG(ERROR) << err_str; - return false; - } - - // The sync model has user created nodes if the type's root node has any - // children. - *has_nodes = type_root_node.HasChildren(); - return true; -} - -bool GenericChangeProcessor::CryptoReadyIfNecessary() { - DCHECK(CalledOnValidThread()); - // We only access the cryptographer while holding a transaction. - syncer::ReadTransaction trans(FROM_HERE, share_handle()); - const syncer::ModelTypeSet encrypted_types = trans.GetEncryptedTypes(); - return !encrypted_types.Has(type_) || trans.GetCryptographer()->is_ready(); -} - -void GenericChangeProcessor::StartImpl() { -} - -syncer::UserShare* GenericChangeProcessor::share_handle() const { - DCHECK(CalledOnValidThread()); - return share_handle_; -} - -void GenericChangeProcessor::UploadAllAttachmentsNotOnServer() { - DCHECK(CalledOnValidThread()); - DCHECK(attachment_service_.get()); - syncer::AttachmentIdList ids; - { - syncer::ReadTransaction trans(FROM_HERE, share_handle()); - trans.GetAttachmentIdsToUpload(type_, &ids); - } - if (!ids.empty()) { - attachment_service_->UploadAttachments(ids); - } -} - -std::unique_ptr<syncer::AttachmentService> -GenericChangeProcessor::GetAttachmentService() const { - return std::unique_ptr<syncer::AttachmentService>( - new syncer::AttachmentServiceProxy(attachment_service_proxy_)); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/generic_change_processor.h b/components/sync_driver/generic_change_processor.h deleted file mode 100644 index f9b1c1b..0000000 --- a/components/sync_driver/generic_change_processor.h +++ /dev/null
@@ -1,182 +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 COMPONENTS_SYNC_DRIVER_GENERIC_CHANGE_PROCESSOR_H_ -#define COMPONENTS_SYNC_DRIVER_GENERIC_CHANGE_PROCESSOR_H_ - -#include <stdint.h> - -#include <memory> -#include <string> -#include <vector> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/threading/non_thread_safe.h" -#include "components/sync/api/attachments/attachment_store.h" -#include "components/sync/api/sync_change_processor.h" -#include "components/sync/api/sync_merge_result.h" -#include "components/sync/core/attachments/attachment_service.h" -#include "components/sync/core/attachments/attachment_service_proxy.h" -#include "components/sync_driver/change_processor.h" - -namespace syncer { -class DataTypeErrorHandler; -class SyncData; -class SyncableService; -class WriteNode; -class WriteTransaction; - -typedef std::vector<syncer::SyncData> SyncDataList; -} // namespace syncer - -namespace sync_driver { - -class SyncApiComponentFactory; -class SyncClient; - -// Datatype agnostic change processor. One instance of GenericChangeProcessor -// is created for each datatype and lives on the datatype's thread. It then -// handles all interaction with the sync api, both translating pushes from the -// local service into transactions and receiving changes from the sync model, -// which then get converted into SyncChange's and sent to the local service. -// -// As a rule, the GenericChangeProcessor is not thread safe, and should only -// be used on the same thread in which it was created. -class GenericChangeProcessor : public ChangeProcessor, - public syncer::SyncChangeProcessor, - public syncer::AttachmentService::Delegate, - public base::NonThreadSafe { - public: - // Create a change processor for |type| and connect it to the syncer. - // |attachment_store| can be NULL which means that datatype will not use sync - // attachments. - GenericChangeProcessor( - syncer::ModelType type, - syncer::DataTypeErrorHandler* error_handler, - const base::WeakPtr<syncer::SyncableService>& local_service, - const base::WeakPtr<syncer::SyncMergeResult>& merge_result, - syncer::UserShare* user_share, - SyncClient* sync_client, - std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store); - ~GenericChangeProcessor() override; - - // ChangeProcessor interface. - // Build and store a list of all changes into |syncer_changes_|. - void ApplyChangesFromSyncModel( - const syncer::BaseTransaction* trans, - int64_t version, - const syncer::ImmutableChangeRecordList& changes) override; - // Passes |syncer_changes_|, built in ApplyChangesFromSyncModel, onto - // |local_service_| by way of its ProcessSyncChanges method. - void CommitChangesFromSyncModel() override; - - // syncer::SyncChangeProcessor implementation. - syncer::SyncError ProcessSyncChanges( - const tracked_objects::Location& from_here, - const syncer::SyncChangeList& change_list) override; - syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override; - syncer::SyncError UpdateDataTypeContext( - syncer::ModelType type, - syncer::SyncChangeProcessor::ContextRefreshStatus refresh_status, - const std::string& context) override; - - // syncer::AttachmentService::Delegate implementation. - void OnAttachmentUploaded(const syncer::AttachmentId& attachment_id) override; - - // Similar to above, but returns a SyncError for use by direct clients - // of GenericChangeProcessor that may need more error visibility. - virtual syncer::SyncError GetAllSyncDataReturnError( - syncer::SyncDataList* data) const; - - // If a datatype context associated with this GenericChangeProcessor's type - // exists, fills |context| and returns true. Otheriwse, if there has not been - // a context set, returns false. - virtual bool GetDataTypeContext(std::string* context) const; - - // Returns the number of items for this type. - virtual int GetSyncCount(); - - // Generic versions of AssociatorInterface methods. Called by - // syncer::SyncableServiceAdapter or the DataTypeController. - virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes); - virtual bool CryptoReadyIfNecessary(); - - // Gets AttachmentService proxy for datatype. - std::unique_ptr<syncer::AttachmentService> GetAttachmentService() const; - - protected: - // ChangeProcessor interface. - void StartImpl() override; // Does nothing. - syncer::UserShare* share_handle() const override; - - private: - // Logically part of ProcessSyncChanges. - // - // |new_attachments| is an output parameter containing newly added attachments - // that need to be stored. This method will append to it. - syncer::SyncError HandleActionAdd(const syncer::SyncChange& change, - const std::string& type_str, - const syncer::WriteTransaction& trans, - syncer::WriteNode* sync_node, - syncer::AttachmentIdSet* new_attachments); - - // Logically part of ProcessSyncChanges. - // - // |new_attachments| is an output parameter containing newly added attachments - // that need to be stored. This method will append to it. - syncer::SyncError HandleActionUpdate( - const syncer::SyncChange& change, - const std::string& type_str, - const syncer::WriteTransaction& trans, - syncer::WriteNode* sync_node, - syncer::AttachmentIdSet* new_attachments); - - // Begin uploading attachments that have not yet been uploaded to the sync - // server. - void UploadAllAttachmentsNotOnServer(); - - const syncer::ModelType type_; - - // The SyncableService this change processor will forward changes on to. - const base::WeakPtr<syncer::SyncableService> local_service_; - - // A SyncMergeResult used to track the changes made during association. The - // owner will invalidate the weak pointer when association is complete. While - // the pointer is valid though, we increment it with any changes received - // via ProcessSyncChanges. - const base::WeakPtr<syncer::SyncMergeResult> merge_result_; - - // The current list of changes received from the syncer. We buffer because - // we must ensure no syncapi transaction is held when we pass it on to - // |local_service_|. - // Set in ApplyChangesFromSyncModel, consumed in CommitChangesFromSyncModel. - syncer::SyncChangeList syncer_changes_; - - // Our handle to the sync model. Unlike normal ChangeProcessors, we need to - // be able to access the sync model before the change processor begins - // listening to changes (the local_service_ will be interacting with us - // when it starts up). As such we can't wait until Start(_) has been called, - // and have to keep a local pointer to the user_share. - syncer::UserShare* const share_handle_; - - // AttachmentService for datatype. Can be NULL if datatype doesn't use - // attachments. - std::unique_ptr<syncer::AttachmentService> attachment_service_; - - // Must be destroyed before attachment_service_ to ensure WeakPtrs are - // invalidated before attachment_service_ is destroyed. - // Can be NULL if attachment_service_ is NULL; - std::unique_ptr<base::WeakPtrFactory<syncer::AttachmentService>> - attachment_service_weak_ptr_factory_; - syncer::AttachmentServiceProxy attachment_service_proxy_; - base::WeakPtrFactory<GenericChangeProcessor> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(GenericChangeProcessor); -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_GENERIC_CHANGE_PROCESSOR_H_
diff --git a/components/sync_driver/generic_change_processor_factory.cc b/components/sync_driver/generic_change_processor_factory.cc deleted file mode 100644 index 44b54146..0000000 --- a/components/sync_driver/generic_change_processor_factory.cc +++ /dev/null
@@ -1,32 +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 "components/sync_driver/generic_change_processor_factory.h" - -#include "base/memory/ptr_util.h" -#include "components/sync/api/syncable_service.h" -#include "components/sync_driver/generic_change_processor.h" - -namespace sync_driver { - - -GenericChangeProcessorFactory::GenericChangeProcessorFactory() {} - -GenericChangeProcessorFactory::~GenericChangeProcessorFactory() {} - -std::unique_ptr<GenericChangeProcessor> -GenericChangeProcessorFactory::CreateGenericChangeProcessor( - syncer::ModelType type, - syncer::UserShare* user_share, - syncer::DataTypeErrorHandler* error_handler, - const base::WeakPtr<syncer::SyncableService>& local_service, - const base::WeakPtr<syncer::SyncMergeResult>& merge_result, - SyncClient* sync_client) { - DCHECK(user_share); - return base::WrapUnique(new GenericChangeProcessor( - type, error_handler, local_service, merge_result, user_share, sync_client, - local_service->GetAttachmentStoreForSync())); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/generic_change_processor_unittest.cc b/components/sync_driver/generic_change_processor_unittest.cc deleted file mode 100644 index dfaf95a..0000000 --- a/components/sync_driver/generic_change_processor_unittest.cc +++ /dev/null
@@ -1,549 +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 "components/sync_driver/generic_change_processor.h" - -#include <stddef.h> - -#include <memory> -#include <string> -#include <utility> - -#include "base/memory/weak_ptr.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/strings/stringprintf.h" -#include "components/sync/api/attachments/attachment_id.h" -#include "components/sync/api/attachments/attachment_store.h" -#include "components/sync/api/fake_syncable_service.h" -#include "components/sync/api/sync_change.h" -#include "components/sync/api/sync_merge_result.h" -#include "components/sync/base/model_type.h" -#include "components/sync/core/attachments/attachment_service_impl.h" -#include "components/sync/core/attachments/fake_attachment_downloader.h" -#include "components/sync/core/attachments/fake_attachment_uploader.h" -#include "components/sync/core/read_node.h" -#include "components/sync/core/read_transaction.h" -#include "components/sync/core/sync_encryption_handler.h" -#include "components/sync/core/test/data_type_error_handler_mock.h" -#include "components/sync/core/test/test_user_share.h" -#include "components/sync/core/user_share.h" -#include "components/sync/core/write_node.h" -#include "components/sync/core/write_transaction.h" -#include "components/sync_driver/fake_sync_client.h" -#include "components/sync_driver/local_device_info_provider.h" -#include "components/sync_driver/sync_api_component_factory.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sync_driver { - -namespace { - -// A mock that keeps track of attachments passed to UploadAttachments. -class MockAttachmentService : public syncer::AttachmentServiceImpl { - public: - MockAttachmentService( - std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store); - ~MockAttachmentService() override; - void UploadAttachments( - const syncer::AttachmentIdList& attachment_ids) override; - std::vector<syncer::AttachmentIdList>* attachment_id_lists(); - - private: - std::vector<syncer::AttachmentIdList> attachment_id_lists_; -}; - -MockAttachmentService::MockAttachmentService( - std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store) - : AttachmentServiceImpl(std::move(attachment_store), - std::unique_ptr<syncer::AttachmentUploader>( - new syncer::FakeAttachmentUploader), - std::unique_ptr<syncer::AttachmentDownloader>( - new syncer::FakeAttachmentDownloader), - NULL, - base::TimeDelta(), - base::TimeDelta()) {} - -MockAttachmentService::~MockAttachmentService() { -} - -void MockAttachmentService::UploadAttachments( - const syncer::AttachmentIdList& attachment_ids) { - attachment_id_lists_.push_back(attachment_ids); - AttachmentServiceImpl::UploadAttachments(attachment_ids); -} - -std::vector<syncer::AttachmentIdList>* -MockAttachmentService::attachment_id_lists() { - return &attachment_id_lists_; -} - -// MockSyncApiComponentFactory needed to initialize GenericChangeProcessor and -// pass MockAttachmentService to it. -class MockSyncApiComponentFactory : public SyncApiComponentFactory { - public: - MockSyncApiComponentFactory() {} - - // SyncApiComponentFactory implementation. - void RegisterDataTypes( - sync_driver::SyncService* sync_service, - const RegisterDataTypesMethod& register_platform_types_method) override {} - sync_driver::DataTypeManager* CreateDataTypeManager( - const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& - debug_info_listener, - const sync_driver::DataTypeController::TypeMap* controllers, - const sync_driver::DataTypeEncryptionHandler* encryption_handler, - browser_sync::SyncBackendHost* backend, - sync_driver::DataTypeManagerObserver* observer) override{ - return nullptr; - }; - browser_sync::SyncBackendHost* CreateSyncBackendHost( - const std::string& name, - invalidation::InvalidationService* invalidator, - const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs, - const base::FilePath& sync_folder) override { - return nullptr; - } - std::unique_ptr<sync_driver::LocalDeviceInfoProvider> - CreateLocalDeviceInfoProvider() override { - return nullptr; - } - SyncComponents CreateBookmarkSyncComponents( - sync_driver::SyncService* sync_service, - syncer::DataTypeErrorHandler* error_handler) override { - return SyncComponents(nullptr, nullptr); - } - - std::unique_ptr<syncer::AttachmentService> CreateAttachmentService( - std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store, - const syncer::UserShare& user_share, - const std::string& store_birthday, - syncer::ModelType model_type, - syncer::AttachmentService::Delegate* delegate) override { - std::unique_ptr<MockAttachmentService> attachment_service( - new MockAttachmentService(std::move(attachment_store))); - // GenericChangeProcessor takes ownership of the AttachmentService, but we - // need to have a pointer to it so we can see that it was used properly. - // Take a pointer and trust that GenericChangeProcessor does not prematurely - // destroy it. - mock_attachment_service_ = attachment_service.get(); - return std::move(attachment_service); - } - - MockAttachmentService* GetMockAttachmentService() { - return mock_attachment_service_; - } - - private: - MockAttachmentService* mock_attachment_service_; -}; - -class SyncGenericChangeProcessorTest : public testing::Test { - public: - // Most test cases will use this type. For those that need a - // GenericChangeProcessor for a different type, use |InitializeForType|. - static const syncer::ModelType kType = syncer::PREFERENCES; - - SyncGenericChangeProcessorTest() - : syncable_service_ptr_factory_(&fake_syncable_service_), - mock_attachment_service_(NULL), - sync_client_(&sync_factory_) {} - - void SetUp() override { - // Use kType by default, but allow test cases to re-initialize with whatever - // type they choose. Therefore, it's important that all type dependent - // initialization occurs in InitializeForType. - InitializeForType(kType); - } - - void TearDown() override { - mock_attachment_service_ = NULL; - if (test_user_share_) { - test_user_share_->TearDown(); - } - } - - // Initialize GenericChangeProcessor and related classes for testing with - // model type |type|. - void InitializeForType(syncer::ModelType type) { - TearDown(); - test_user_share_.reset(new syncer::TestUserShare); - test_user_share_->SetUp(); - sync_merge_result_.reset(new syncer::SyncMergeResult(type)); - merge_result_ptr_factory_.reset( - new base::WeakPtrFactory<syncer::SyncMergeResult>( - sync_merge_result_.get())); - - syncer::ModelTypeSet types = syncer::ProtocolTypes(); - for (syncer::ModelTypeSet::Iterator iter = types.First(); iter.Good(); - iter.Inc()) { - syncer::TestUserShare::CreateRoot(iter.Get(), - test_user_share_->user_share()); - } - test_user_share_->encryption_handler()->Init(); - ConstructGenericChangeProcessor(type); - } - - void ConstructGenericChangeProcessor(syncer::ModelType type) { - std::unique_ptr<syncer::AttachmentStore> attachment_store = - syncer::AttachmentStore::CreateInMemoryStore(); - change_processor_.reset(new GenericChangeProcessor( - type, &data_type_error_handler_, - syncable_service_ptr_factory_.GetWeakPtr(), - merge_result_ptr_factory_->GetWeakPtr(), test_user_share_->user_share(), - &sync_client_, attachment_store->CreateAttachmentStoreForSync())); - mock_attachment_service_ = sync_factory_.GetMockAttachmentService(); - } - - void BuildChildNodes(syncer::ModelType type, int n) { - syncer::WriteTransaction trans(FROM_HERE, user_share()); - for (int i = 0; i < n; ++i) { - syncer::WriteNode node(&trans); - node.InitUniqueByCreation(type, base::StringPrintf("node%05d", i)); - } - } - - GenericChangeProcessor* change_processor() { - return change_processor_.get(); - } - - syncer::UserShare* user_share() { - return test_user_share_->user_share(); - } - - MockAttachmentService* mock_attachment_service() { - return mock_attachment_service_; - } - - void RunLoop() { - base::RunLoop run_loop; - run_loop.RunUntilIdle(); - } - - private: - base::MessageLoopForUI loop_; - - std::unique_ptr<syncer::SyncMergeResult> sync_merge_result_; - std::unique_ptr<base::WeakPtrFactory<syncer::SyncMergeResult>> - merge_result_ptr_factory_; - - syncer::FakeSyncableService fake_syncable_service_; - base::WeakPtrFactory<syncer::FakeSyncableService> - syncable_service_ptr_factory_; - - syncer::DataTypeErrorHandlerMock data_type_error_handler_; - std::unique_ptr<syncer::TestUserShare> test_user_share_; - MockAttachmentService* mock_attachment_service_; - FakeSyncClient sync_client_; - MockSyncApiComponentFactory sync_factory_; - - std::unique_ptr<GenericChangeProcessor> change_processor_; -}; - -// Similar to above, but focused on the method that implements sync/api -// interfaces and is hence exposed to datatypes directly. -TEST_F(SyncGenericChangeProcessorTest, StressGetAllSyncData) { - const int kNumChildNodes = 1000; - const int kRepeatCount = 1; - - ASSERT_NO_FATAL_FAILURE(BuildChildNodes(kType, kNumChildNodes)); - - for (int i = 0; i < kRepeatCount; ++i) { - syncer::SyncDataList sync_data = - change_processor()->GetAllSyncData(kType); - - // Start with a simple test. We can add more in-depth testing later. - EXPECT_EQ(static_cast<size_t>(kNumChildNodes), sync_data.size()); - } -} - -TEST_F(SyncGenericChangeProcessorTest, SetGetPasswords) { - InitializeForType(syncer::PASSWORDS); - const int kNumPasswords = 10; - sync_pb::PasswordSpecificsData password_data; - password_data.set_username_value("user"); - - sync_pb::EntitySpecifics password_holder; - - syncer::SyncChangeList change_list; - for (int i = 0; i < kNumPasswords; ++i) { - password_data.set_password_value( - base::StringPrintf("password%i", i)); - password_holder.mutable_password()->mutable_client_only_encrypted_data()-> - CopyFrom(password_data); - change_list.push_back( - syncer::SyncChange(FROM_HERE, - syncer::SyncChange::ACTION_ADD, - syncer::SyncData::CreateLocalData( - base::StringPrintf("tag%i", i), - base::StringPrintf("title%i", i), - password_holder))); - } - - ASSERT_FALSE( - change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet()); - - syncer::SyncDataList password_list( - change_processor()->GetAllSyncData(syncer::PASSWORDS)); - - ASSERT_EQ(password_list.size(), change_list.size()); - for (int i = 0; i < kNumPasswords; ++i) { - // Verify the password is returned properly. - ASSERT_TRUE(password_list[i].GetSpecifics().has_password()); - ASSERT_TRUE(password_list[i].GetSpecifics().password(). - has_client_only_encrypted_data()); - ASSERT_FALSE(password_list[i].GetSpecifics().password().has_encrypted()); - const sync_pb::PasswordSpecificsData& sync_password = - password_list[i].GetSpecifics().password().client_only_encrypted_data(); - const sync_pb::PasswordSpecificsData& change_password = - change_list[i].sync_data().GetSpecifics().password(). - client_only_encrypted_data(); - ASSERT_EQ(sync_password.password_value(), change_password.password_value()); - ASSERT_EQ(sync_password.username_value(), change_password.username_value()); - - // Verify the raw sync data was stored securely. - syncer::ReadTransaction read_transaction(FROM_HERE, user_share()); - syncer::ReadNode node(&read_transaction); - ASSERT_EQ(node.InitByClientTagLookup(syncer::PASSWORDS, - base::StringPrintf("tag%i", i)), - syncer::BaseNode::INIT_OK); - ASSERT_EQ(node.GetTitle(), "encrypted"); - const sync_pb::EntitySpecifics& raw_specifics = node.GetEntitySpecifics(); - ASSERT_TRUE(raw_specifics.has_password()); - ASSERT_TRUE(raw_specifics.password().has_encrypted()); - ASSERT_FALSE(raw_specifics.password().has_client_only_encrypted_data()); - } -} - -TEST_F(SyncGenericChangeProcessorTest, UpdatePasswords) { - InitializeForType(syncer::PASSWORDS); - const int kNumPasswords = 10; - sync_pb::PasswordSpecificsData password_data; - password_data.set_username_value("user"); - - sync_pb::EntitySpecifics password_holder; - - syncer::SyncChangeList change_list; - syncer::SyncChangeList change_list2; - for (int i = 0; i < kNumPasswords; ++i) { - password_data.set_password_value( - base::StringPrintf("password%i", i)); - password_holder.mutable_password()->mutable_client_only_encrypted_data()-> - CopyFrom(password_data); - change_list.push_back( - syncer::SyncChange(FROM_HERE, - syncer::SyncChange::ACTION_ADD, - syncer::SyncData::CreateLocalData( - base::StringPrintf("tag%i", i), - base::StringPrintf("title%i", i), - password_holder))); - password_data.set_password_value( - base::StringPrintf("password_m%i", i)); - password_holder.mutable_password()->mutable_client_only_encrypted_data()-> - CopyFrom(password_data); - change_list2.push_back( - syncer::SyncChange(FROM_HERE, - syncer::SyncChange::ACTION_UPDATE, - syncer::SyncData::CreateLocalData( - base::StringPrintf("tag%i", i), - base::StringPrintf("title_m%i", i), - password_holder))); - } - - ASSERT_FALSE( - change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet()); - ASSERT_FALSE( - change_processor()->ProcessSyncChanges(FROM_HERE, change_list2).IsSet()); - - syncer::SyncDataList password_list( - change_processor()->GetAllSyncData(syncer::PASSWORDS)); - - ASSERT_EQ(password_list.size(), change_list2.size()); - for (int i = 0; i < kNumPasswords; ++i) { - // Verify the password is returned properly. - ASSERT_TRUE(password_list[i].GetSpecifics().has_password()); - ASSERT_TRUE(password_list[i].GetSpecifics().password(). - has_client_only_encrypted_data()); - ASSERT_FALSE(password_list[i].GetSpecifics().password().has_encrypted()); - const sync_pb::PasswordSpecificsData& sync_password = - password_list[i].GetSpecifics().password().client_only_encrypted_data(); - const sync_pb::PasswordSpecificsData& change_password = - change_list2[i].sync_data().GetSpecifics().password(). - client_only_encrypted_data(); - ASSERT_EQ(sync_password.password_value(), change_password.password_value()); - ASSERT_EQ(sync_password.username_value(), change_password.username_value()); - - // Verify the raw sync data was stored securely. - syncer::ReadTransaction read_transaction(FROM_HERE, user_share()); - syncer::ReadNode node(&read_transaction); - ASSERT_EQ(node.InitByClientTagLookup(syncer::PASSWORDS, - base::StringPrintf("tag%i", i)), - syncer::BaseNode::INIT_OK); - ASSERT_EQ(node.GetTitle(), "encrypted"); - const sync_pb::EntitySpecifics& raw_specifics = node.GetEntitySpecifics(); - ASSERT_TRUE(raw_specifics.has_password()); - ASSERT_TRUE(raw_specifics.password().has_encrypted()); - ASSERT_FALSE(raw_specifics.password().has_client_only_encrypted_data()); - } -} - -// Verify that attachments on newly added or updated SyncData are passed to the -// AttachmentService. -TEST_F(SyncGenericChangeProcessorTest, - ProcessSyncChanges_AddUpdateWithAttachment) { - std::string tag = "client_tag"; - std::string title = "client_title"; - sync_pb::EntitySpecifics specifics; - sync_pb::PreferenceSpecifics* pref_specifics = specifics.mutable_preference(); - pref_specifics->set_name("test"); - - syncer::AttachmentIdList attachment_ids; - attachment_ids.push_back(syncer::AttachmentId::Create(0, 0)); - attachment_ids.push_back(syncer::AttachmentId::Create(0, 0)); - - // Add a SyncData with two attachments. - syncer::SyncChangeList change_list; - change_list.push_back( - syncer::SyncChange(FROM_HERE, - syncer::SyncChange::ACTION_ADD, - syncer::SyncData::CreateLocalDataWithAttachments( - tag, title, specifics, attachment_ids))); - ASSERT_FALSE( - change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet()); - RunLoop(); - - // Check that the AttachmentService received the new attachments. - ASSERT_EQ(mock_attachment_service()->attachment_id_lists()->size(), 1U); - const syncer::AttachmentIdList& attachments_added = - mock_attachment_service()->attachment_id_lists()->front(); - ASSERT_THAT( - attachments_added, - testing::UnorderedElementsAre(attachment_ids[0], attachment_ids[1])); - - // Update the SyncData, replacing its two attachments with one new attachment. - syncer::AttachmentIdList new_attachment_ids; - new_attachment_ids.push_back(syncer::AttachmentId::Create(0, 0)); - mock_attachment_service()->attachment_id_lists()->clear(); - change_list.clear(); - change_list.push_back( - syncer::SyncChange(FROM_HERE, - syncer::SyncChange::ACTION_UPDATE, - syncer::SyncData::CreateLocalDataWithAttachments( - tag, title, specifics, new_attachment_ids))); - ASSERT_FALSE( - change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet()); - RunLoop(); - - // Check that the AttachmentService received it. - ASSERT_EQ(mock_attachment_service()->attachment_id_lists()->size(), 1U); - const syncer::AttachmentIdList& new_attachments_added = - mock_attachment_service()->attachment_id_lists()->front(); - ASSERT_THAT(new_attachments_added, - testing::UnorderedElementsAre(new_attachment_ids[0])); -} - -// Verify that after attachment is uploaded GenericChangeProcessor updates -// corresponding entries -TEST_F(SyncGenericChangeProcessorTest, AttachmentUploaded) { - std::string tag = "client_tag"; - std::string title = "client_title"; - sync_pb::EntitySpecifics specifics; - sync_pb::PreferenceSpecifics* pref_specifics = specifics.mutable_preference(); - pref_specifics->set_name("test"); - - syncer::AttachmentIdList attachment_ids; - attachment_ids.push_back(syncer::AttachmentId::Create(0, 0)); - - // Add a SyncData with two attachments. - syncer::SyncChangeList change_list; - change_list.push_back( - syncer::SyncChange(FROM_HERE, - syncer::SyncChange::ACTION_ADD, - syncer::SyncData::CreateLocalDataWithAttachments( - tag, title, specifics, attachment_ids))); - ASSERT_FALSE( - change_processor()->ProcessSyncChanges(FROM_HERE, change_list).IsSet()); - - sync_pb::AttachmentIdProto attachment_id_proto = attachment_ids[0].GetProto(); - syncer::AttachmentId attachment_id = - syncer::AttachmentId::CreateFromProto(attachment_id_proto); - - change_processor()->OnAttachmentUploaded(attachment_id); - syncer::ReadTransaction read_transaction(FROM_HERE, user_share()); - syncer::ReadNode node(&read_transaction); - ASSERT_EQ(node.InitByClientTagLookup(kType, tag), syncer::BaseNode::INIT_OK); - attachment_ids = node.GetAttachmentIds(); - EXPECT_EQ(1U, attachment_ids.size()); -} - -// Verify that upon construction, all attachments not yet on the server are -// scheduled for upload. -TEST_F(SyncGenericChangeProcessorTest, UploadAllAttachmentsNotOnServer) { - // Create two attachment ids. id2 will be marked as "on server". - syncer::AttachmentId id1 = syncer::AttachmentId::Create(0, 0); - syncer::AttachmentId id2 = syncer::AttachmentId::Create(0, 0); - { - // Write an entry containing these two attachment ids. - syncer::WriteTransaction trans(FROM_HERE, user_share()); - syncer::ReadNode root(&trans); - ASSERT_EQ(syncer::BaseNode::INIT_OK, root.InitTypeRoot(kType)); - syncer::WriteNode node(&trans); - node.InitUniqueByCreation(kType, root, "some node"); - sync_pb::AttachmentMetadata metadata; - sync_pb::AttachmentMetadataRecord* record1 = metadata.add_record(); - *record1->mutable_id() = id1.GetProto(); - sync_pb::AttachmentMetadataRecord* record2 = metadata.add_record(); - *record2->mutable_id() = id2.GetProto(); - record2->set_is_on_server(true); - node.SetAttachmentMetadata(metadata); - } - - // Construct the GenericChangeProcessor and see that it asks the - // AttachmentService to upload id1 only. - ConstructGenericChangeProcessor(kType); - ASSERT_EQ(1U, mock_attachment_service()->attachment_id_lists()->size()); - ASSERT_THAT(mock_attachment_service()->attachment_id_lists()->front(), - testing::UnorderedElementsAre(id1)); -} - -// Test that attempting to add an entry that already exists still works. -TEST_F(SyncGenericChangeProcessorTest, AddExistingEntry) { - InitializeForType(syncer::SESSIONS); - sync_pb::EntitySpecifics sessions_specifics; - sessions_specifics.mutable_session()->set_session_tag("session tag"); - syncer::SyncChangeList changes; - - // First add it normally. - changes.push_back(syncer::SyncChange( - FROM_HERE, syncer::SyncChange::ACTION_ADD, - syncer::SyncData::CreateLocalData(base::StringPrintf("tag"), - base::StringPrintf("title"), - sessions_specifics))); - ASSERT_FALSE( - change_processor()->ProcessSyncChanges(FROM_HERE, changes).IsSet()); - - // Now attempt to add it again, but with different specifics. Should not - // result in an error and should still update the specifics. - sessions_specifics.mutable_session()->set_session_tag("session tag 2"); - changes[0] = - syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_ADD, - syncer::SyncData::CreateLocalData( - base::StringPrintf("tag"), - base::StringPrintf("title"), sessions_specifics)); - ASSERT_FALSE( - change_processor()->ProcessSyncChanges(FROM_HERE, changes).IsSet()); - - // Verify the data was updated properly. - syncer::SyncDataList sync_data = - change_processor()->GetAllSyncData(syncer::SESSIONS); - ASSERT_EQ(sync_data.size(), 1U); - ASSERT_EQ("session tag 2", - sync_data[0].GetSpecifics().session().session_tag()); - EXPECT_FALSE(syncer::SyncDataRemote(sync_data[0]).GetClientTagHash().empty()); -} - -} // namespace - -} // namespace sync_driver
diff --git a/components/sync_driver/glue/browser_thread_model_worker.cc b/components/sync_driver/glue/browser_thread_model_worker.cc deleted file mode 100644 index faf53fc4..0000000 --- a/components/sync_driver/glue/browser_thread_model_worker.cc +++ /dev/null
@@ -1,68 +0,0 @@ -// 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. - -#include "components/sync_driver/glue/browser_thread_model_worker.h" - -#include "base/bind.h" -#include "base/single_thread_task_runner.h" -#include "base/synchronization/waitable_event.h" - -using base::SingleThreadTaskRunner; -using base::WaitableEvent; - -namespace browser_sync { - -BrowserThreadModelWorker::BrowserThreadModelWorker( - const scoped_refptr<SingleThreadTaskRunner>& runner, - syncer::ModelSafeGroup group, - syncer::WorkerLoopDestructionObserver* observer) - : ModelSafeWorker(observer), runner_(runner), group_(group) {} - -syncer::SyncerError BrowserThreadModelWorker::DoWorkAndWaitUntilDoneImpl( - const syncer::WorkCallback& work) { - syncer::SyncerError error = syncer::UNSET; - if (runner_->BelongsToCurrentThread()) { - DLOG(WARNING) << "Already on thread " << runner_; - return work.Run(); - } - - if (!runner_->PostTask( - FROM_HERE, - base::Bind(&BrowserThreadModelWorker::CallDoWorkAndSignalTask, this, - work, work_done_or_stopped(), &error))) { - DLOG(WARNING) << "Failed to post task to runner " << runner_; - error = syncer::CANNOT_DO_WORK; - return error; - } - work_done_or_stopped()->Wait(); - return error; -} - -syncer::ModelSafeGroup BrowserThreadModelWorker::GetModelSafeGroup() { - return group_; -} - -BrowserThreadModelWorker::~BrowserThreadModelWorker() {} - -void BrowserThreadModelWorker::RegisterForLoopDestruction() { - if (runner_->BelongsToCurrentThread()) { - SetWorkingLoopToCurrent(); - } else { - runner_->PostTask( - FROM_HERE, - Bind(&BrowserThreadModelWorker::RegisterForLoopDestruction, this)); - } -} - -void BrowserThreadModelWorker::CallDoWorkAndSignalTask( - const syncer::WorkCallback& work, - WaitableEvent* done, - syncer::SyncerError* error) { - DCHECK(runner_->BelongsToCurrentThread()); - if (!IsStopped()) - *error = work.Run(); - done->Signal(); -} - -} // namespace browser_sync
diff --git a/components/sync_driver/glue/browser_thread_model_worker_unittest.cc b/components/sync_driver/glue/browser_thread_model_worker_unittest.cc deleted file mode 100644 index f7d6670..0000000 --- a/components/sync_driver/glue/browser_thread_model_worker_unittest.cc +++ /dev/null
@@ -1,100 +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 "components/sync_driver/glue/browser_thread_model_worker.h" - -#include "base/bind.h" -#include "base/callback.h" -#include "base/location.h" -#include "base/memory/weak_ptr.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/single_thread_task_runner.h" -#include "base/test/test_timeouts.h" -#include "base/threading/thread.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/timer/timer.h" -#include "testing/gtest/include/gtest/gtest.h" - -using base::Thread; -using base::TimeDelta; - -namespace browser_sync { - -namespace { - -class SyncBrowserThreadModelWorkerTest : public testing::Test { - public: - SyncBrowserThreadModelWorkerTest() - : db_thread_("DB_Thread"), did_do_work_(false), weak_factory_(this) {} - - bool did_do_work() { return did_do_work_; } - BrowserThreadModelWorker* worker() { return worker_.get(); } - base::OneShotTimer* timer() { return &timer_; } - base::WeakPtrFactory<SyncBrowserThreadModelWorkerTest>* factory() { - return &weak_factory_; - } - - // Schedule DoWork to be executed on the DB thread and have the test fail if - // DoWork hasn't executed within action_timeout(). - void ScheduleWork() { - // We wait until the callback is done. So it is safe to use unretained. - syncer::WorkCallback c = base::Bind( - &SyncBrowserThreadModelWorkerTest::DoWork, base::Unretained(this)); - timer()->Start(FROM_HERE, TestTimeouts::action_timeout(), this, - &SyncBrowserThreadModelWorkerTest::Timeout); - worker()->DoWorkAndWaitUntilDone(c); - } - - // This is the work that will be scheduled to be done on the DB thread. - syncer::SyncerError DoWork() { - EXPECT_TRUE(db_thread_.task_runner()->BelongsToCurrentThread()); - timer_.Stop(); // Stop the failure timer so the test succeeds. - main_message_loop_.task_runner()->PostTask( - FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); - did_do_work_ = true; - return syncer::SYNCER_OK; - } - - // This will be called by the OneShotTimer and make the test fail unless - // DoWork is called first. - void Timeout() { - ADD_FAILURE() << "Timed out waiting for work to be done on the DB thread."; - main_message_loop_.task_runner()->PostTask( - FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); - } - - protected: - void SetUp() override { - db_thread_.Start(); - worker_ = new BrowserThreadModelWorker(db_thread_.task_runner(), - syncer::GROUP_DB, NULL); - } - - virtual void Teardown() { - worker_ = NULL; - db_thread_.Stop(); - } - - private: - base::MessageLoop main_message_loop_; - Thread db_thread_; - bool did_do_work_; - scoped_refptr<BrowserThreadModelWorker> worker_; - base::OneShotTimer timer_; - - base::WeakPtrFactory<SyncBrowserThreadModelWorkerTest> weak_factory_; -}; - -TEST_F(SyncBrowserThreadModelWorkerTest, DoesWorkOnDatabaseThread) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&SyncBrowserThreadModelWorkerTest::ScheduleWork, - factory()->GetWeakPtr())); - base::RunLoop().Run(); - EXPECT_TRUE(did_do_work()); -} - -} // namespace - -} // namespace browser_sync
diff --git a/components/sync_driver/glue/chrome_report_unrecoverable_error.cc b/components/sync_driver/glue/chrome_report_unrecoverable_error.cc deleted file mode 100644 index c824bd5..0000000 --- a/components/sync_driver/glue/chrome_report_unrecoverable_error.cc +++ /dev/null
@@ -1,30 +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 "components/sync_driver/glue/chrome_report_unrecoverable_error.h" - -#include "base/debug/dump_without_crashing.h" -#include "base/rand_util.h" - -namespace browser_sync { - -void ChromeReportUnrecoverableError(version_info::Channel channel) { - // Only upload on canary/dev builds to avoid overwhelming crash server. - if (channel != version_info::Channel::CANARY && - channel != version_info::Channel::DEV) { - return; - } - - // We only want to upload |kErrorUploadRatio| ratio of errors. - const double kErrorUploadRatio = 0.01; - if (kErrorUploadRatio <= 0.0) - return; // We are not allowed to upload errors. - double random_number = base::RandDouble(); - if (random_number > kErrorUploadRatio) - return; - - base::debug::DumpWithoutCrashing(); -} - -} // namespace browser_sync
diff --git a/components/sync_driver/glue/sync_backend_host.cc b/components/sync_driver/glue/sync_backend_host.cc deleted file mode 100644 index d9ffea6b..0000000 --- a/components/sync_driver/glue/sync_backend_host.cc +++ /dev/null
@@ -1,13 +0,0 @@ -// 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. - -#include "components/sync_driver/glue/sync_backend_host.h" - -namespace browser_sync { - -SyncBackendHost::SyncBackendHost() {} - -SyncBackendHost::~SyncBackendHost() {} - -} // namespace browser_sync
diff --git a/components/sync_driver/glue/sync_backend_host.h b/components/sync_driver/glue/sync_backend_host.h deleted file mode 100644 index 7dbe2b1a..0000000 --- a/components/sync_driver/glue/sync_backend_host.h +++ /dev/null
@@ -1,242 +0,0 @@ -// 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. - -#ifndef COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_H_ -#define COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_H_ - -#include <memory> -#include <string> - -#include "base/callback.h" -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/threading/thread.h" -#include "components/sync/base/model_type.h" -#include "components/sync/base/weak_handle.h" -#include "components/sync/core/configure_reason.h" -#include "components/sync/core/shutdown_reason.h" -#include "components/sync/core/sync_manager.h" -#include "components/sync/core/sync_manager_factory.h" -#include "components/sync/sessions/sync_session_snapshot.h" -#include "components/sync_driver/backend_data_type_configurer.h" - -class GURL; - -namespace base { -class MessageLoop; -} - -namespace syncer { -class CancelationSignal; -class HttpPostProviderFactory; -class SyncManagerFactory; -class UnrecoverableErrorHandler; -} - -namespace sync_driver { -class ChangeProcessor; -class SyncFrontend; -} - -namespace browser_sync { - -// An API to "host" the top level SyncAPI element. -// -// This class handles dispatch of potentially blocking calls to appropriate -// threads and ensures that the SyncFrontend is only accessed on the UI loop. -class SyncBackendHost : public sync_driver::BackendDataTypeConfigurer { - public: - typedef syncer::SyncStatus Status; - typedef base::Callback<std::unique_ptr<syncer::HttpPostProviderFactory>( - syncer::CancelationSignal*)> - HttpPostProviderFactoryGetter; - - // Stubs used by implementing classes. - SyncBackendHost(); - ~SyncBackendHost() override; - - // Called on the frontend's thread to kick off asynchronous initialization. - // Optionally deletes the "Sync Data" folder during init in order to make - // sure we're starting fresh. - // - // |saved_nigori_state| is optional nigori state to restore from a previous - // backend instance. May be null. - virtual void Initialize( - sync_driver::SyncFrontend* frontend, - std::unique_ptr<base::Thread> sync_thread, - const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, - const scoped_refptr<base::SingleThreadTaskRunner>& file_thread, - const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, - const GURL& service_url, - const std::string& sync_user_agent, - const syncer::SyncCredentials& credentials, - bool delete_sync_data_folder, - std::unique_ptr<syncer::SyncManagerFactory> sync_manager_factory, - const syncer::WeakHandle<syncer::UnrecoverableErrorHandler>& - unrecoverable_error_handler, - const base::Closure& report_unrecoverable_error_function, - const HttpPostProviderFactoryGetter& http_post_provider_factory_getter, - std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> - saved_nigori_state) = 0; - - // Called on the frontend's thread to trigger a refresh. - virtual void TriggerRefresh(const syncer::ModelTypeSet& types) = 0; - - // Called on the frontend's thread to update SyncCredentials. - virtual void UpdateCredentials( - const syncer::SyncCredentials& credentials) = 0; - - // This starts the SyncerThread running a Syncer object to communicate with - // sync servers. Until this is called, no changes will leave or enter this - // browser from the cloud / sync servers. - // Called on |frontend_loop_|. - virtual void StartSyncingWithServer() = 0; - - // Called on |frontend_loop_| to asynchronously set a new passphrase for - // encryption. Note that it is an error to call SetEncryptionPassphrase under - // the following circumstances: - // - An explicit passphrase has already been set - // - |is_explicit| is true and we have pending keys. - // When |is_explicit| is false, a couple of things could happen: - // - If there are pending keys, we try to decrypt them. If decryption works, - // this acts like a call to SetDecryptionPassphrase. If not, the GAIA - // passphrase passed in is cached so we can re-encrypt with it in future. - // - If there are no pending keys, data is encrypted with |passphrase| (this - // is a no-op if data was already encrypted with |passphrase|.) - virtual void SetEncryptionPassphrase( - const std::string& passphrase, - bool is_explicit) = 0; - - // Called on |frontend_loop_| to use the provided passphrase to asynchronously - // attempt decryption. Returns false immediately if the passphrase could not - // be used to decrypt a locally cached copy of encrypted keys; returns true - // otherwise. If new encrypted keys arrive during the asynchronous call, - // OnPassphraseRequired may be triggered at a later time. It is an error to - // call this when there are no pending keys. - virtual bool SetDecryptionPassphrase(const std::string& passphrase) - WARN_UNUSED_RESULT = 0; - - // Called on |frontend_loop_| to kick off shutdown procedure. Attempts to cut - // short any long-lived or blocking sync thread tasks so that the shutdown on - // sync thread task that we're about to post won't have to wait very long. - virtual void StopSyncingForShutdown() = 0; - - // Called on |frontend_loop_| to kick off shutdown. - // See the implementation and Core::DoShutdown for details. - // Must be called *after* StopSyncingForShutdown. - // For any reason other than BROWSER_SHUTDOWN, caller should claim sync - // thread because: - // * during browser shutdown sync thread is not claimed to avoid blocking - // browser shutdown on sync shutdown. - // * otherwise sync thread is claimed so that if sync backend is recreated - // later, initialization of new backend is serialized on previous sync - // thread after cleanup of previous backend to avoid old/new backends - // interfere with each other. - virtual std::unique_ptr<base::Thread> Shutdown( - syncer::ShutdownReason reason) = 0; - - // Removes all current registrations from the backend on the - // InvalidationService. - virtual void UnregisterInvalidationIds() = 0; - - // Changes the set of data types that are currently being synced. - // The ready_task will be run when configuration is done with the - // set of all types that failed configuration (i.e., if its argument - // is non-empty, then an error was encountered). - // Returns the set of types that are ready to start without needing any - // further sync activity. - // BackendDataTypeConfigurer implementation. - syncer::ModelTypeSet ConfigureDataTypes( - syncer::ConfigureReason reason, - const DataTypeConfigStateMap& config_state_map, - const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& - ready_task, - const base::Callback<void()>& retry_callback) override = 0; - - // Turns on encryption of all present and future sync data. - virtual void EnableEncryptEverything() = 0; - - // Called on |frontend_loop_| to obtain a handle to the UserShare needed for - // creating transactions. Should not be called before we signal - // initialization is complete with OnBackendInitialized(). - virtual syncer::UserShare* GetUserShare() const = 0; - - // Called from any thread to obtain current status information in detailed or - // summarized form. - virtual Status GetDetailedStatus() = 0; - virtual syncer::sessions::SyncSessionSnapshot - GetLastSessionSnapshot() const = 0; - - // Determines if the underlying sync engine has made any local changes to - // items that have not yet been synced with the server. - // ONLY CALL THIS IF OnInitializationComplete was called! - virtual bool HasUnsyncedItems() const = 0; - - // Whether or not we are syncing encryption keys. - virtual bool IsNigoriEnabled() const = 0; - - // Returns the type of passphrase being used to encrypt data. See - // sync_encryption_handler.h. - virtual syncer::PassphraseType GetPassphraseType() const = 0; - - // If an explicit passphrase is in use, returns the time at which that - // passphrase was set (if available). - virtual base::Time GetExplicitPassphraseTime() const = 0; - - // True if the cryptographer has any keys available to attempt decryption. - // Could mean we've downloaded and loaded Nigori objects, or we bootstrapped - // using a token previously received. - virtual bool IsCryptographerReady( - const syncer::BaseTransaction* trans) const = 0; - - virtual void GetModelSafeRoutingInfo( - syncer::ModelSafeRoutingInfo* out) const = 0; - - // Send a message to the sync thread to persist the Directory to disk. - virtual void FlushDirectory() const = 0; - - // Requests that the backend forward to the fronent any protocol events in - // its buffer and begin forwarding automatically from now on. Repeated calls - // to this function may result in the same events being emitted several - // times. - virtual void RequestBufferedProtocolEventsAndEnableForwarding() = 0; - - // Disables protocol event forwarding. - virtual void DisableProtocolEventForwarding() = 0; - - // Returns a ListValue representing all nodes for the specified types through - // |callback| on this thread. - virtual void GetAllNodesForTypes( - syncer::ModelTypeSet types, - base::Callback<void(const std::vector<syncer::ModelType>&, - ScopedVector<base::ListValue>)> type) = 0; - - // Enables the sending of directory type debug counters. Also, for every - // time it is called, it makes an explicit request that updates to an update - // for all counters be emitted. - virtual void EnableDirectoryTypeDebugInfoForwarding() = 0; - - // Disables the sending of directory type debug counters. - virtual void DisableDirectoryTypeDebugInfoForwarding() = 0; - - virtual base::MessageLoop* GetSyncLoopForTesting() = 0; - - // Triggers sync cycle to update |types|. - virtual void RefreshTypesForTest(syncer::ModelTypeSet types) = 0; - - // See SyncManager::ClearServerData. - virtual void ClearServerData( - const syncer::SyncManager::ClearServerDataCallback& callback) = 0; - - // Notify the syncer that the cookie jar has changed. - // See SyncManager::OnCookieJarChanged. - virtual void OnCookieJarChanged(bool account_mismatch, bool empty_jar) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(SyncBackendHost); -}; - -} // namespace browser_sync - -#endif // COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_H_
diff --git a/components/sync_driver/glue/sync_backend_host_core.cc b/components/sync_driver/glue/sync_backend_host_core.cc deleted file mode 100644 index 81ee0f76..0000000 --- a/components/sync_driver/glue/sync_backend_host_core.cc +++ /dev/null
@@ -1,771 +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 "components/sync_driver/glue/sync_backend_host_core.h" - -#include <utility> - -#include "base/bind.h" -#include "base/files/file_util.h" -#include "base/location.h" -#include "base/single_thread_task_runner.h" -#include "components/data_use_measurement/core/data_use_user_data.h" -#include "components/invalidation/public/invalidation_util.h" -#include "components/invalidation/public/object_id_invalidation_map.h" -#include "components/sync/core/http_post_provider_factory.h" -#include "components/sync/core/internal_components_factory.h" -#include "components/sync/core/sync_manager.h" -#include "components/sync/core/sync_manager_factory.h" -#include "components/sync/engine/events/protocol_event.h" -#include "components/sync/sessions/commit_counters.h" -#include "components/sync/sessions/status_counters.h" -#include "components/sync/sessions/sync_session_snapshot.h" -#include "components/sync/sessions/update_counters.h" -#include "components/sync_driver/glue/sync_backend_registrar.h" -#include "components/sync_driver/invalidation_adapter.h" -#include "components/sync_driver/local_device_info_provider_impl.h" -#include "url/gurl.h" - -// Helper macros to log with the syncer thread name; useful when there -// are multiple syncers involved. - -#define SLOG(severity) LOG(severity) << name_ << ": " - -#define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": " - -static const int kSaveChangesIntervalSeconds = 10; - -namespace syncer { -class InternalComponentsFactory; -} // namespace syncer - -namespace net { -class URLFetcher; -} - -namespace { - -void BindFetcherToDataTracker(net::URLFetcher* fetcher) { - data_use_measurement::DataUseUserData::AttachToFetcher( - fetcher, data_use_measurement::DataUseUserData::SYNC); -} - -} // namespace - -namespace browser_sync { - -DoInitializeOptions::DoInitializeOptions( - base::MessageLoop* sync_loop, - SyncBackendRegistrar* registrar, - const std::vector<scoped_refptr<syncer::ModelSafeWorker>>& workers, - const scoped_refptr<syncer::ExtensionsActivity>& extensions_activity, - const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, - const GURL& service_url, - const std::string& sync_user_agent, - std::unique_ptr<syncer::HttpPostProviderFactory> http_bridge_factory, - const syncer::SyncCredentials& credentials, - const std::string& invalidator_client_id, - std::unique_ptr<syncer::SyncManagerFactory> sync_manager_factory, - bool delete_sync_data_folder, - const std::string& restored_key_for_bootstrapping, - const std::string& restored_keystore_key_for_bootstrapping, - std::unique_ptr<syncer::InternalComponentsFactory> - internal_components_factory, - const syncer::WeakHandle<syncer::UnrecoverableErrorHandler>& - unrecoverable_error_handler, - const base::Closure& report_unrecoverable_error_function, - std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> - saved_nigori_state, - const std::map<syncer::ModelType, int64_t>& invalidation_versions) - : sync_loop(sync_loop), - registrar(registrar), - workers(workers), - extensions_activity(extensions_activity), - event_handler(event_handler), - service_url(service_url), - sync_user_agent(sync_user_agent), - http_bridge_factory(std::move(http_bridge_factory)), - credentials(credentials), - invalidator_client_id(invalidator_client_id), - sync_manager_factory(std::move(sync_manager_factory)), - delete_sync_data_folder(delete_sync_data_folder), - restored_key_for_bootstrapping(restored_key_for_bootstrapping), - restored_keystore_key_for_bootstrapping( - restored_keystore_key_for_bootstrapping), - internal_components_factory(std::move(internal_components_factory)), - unrecoverable_error_handler(unrecoverable_error_handler), - report_unrecoverable_error_function(report_unrecoverable_error_function), - saved_nigori_state(std::move(saved_nigori_state)), - invalidation_versions(invalidation_versions) {} - -DoInitializeOptions::~DoInitializeOptions() {} - -DoConfigureSyncerTypes::DoConfigureSyncerTypes() {} - -DoConfigureSyncerTypes::DoConfigureSyncerTypes( - const DoConfigureSyncerTypes& other) = default; - -DoConfigureSyncerTypes::~DoConfigureSyncerTypes() {} - -SyncBackendHostCore::SyncBackendHostCore( - const std::string& name, - const base::FilePath& sync_data_folder_path, - bool has_sync_setup_completed, - const base::WeakPtr<SyncBackendHostImpl>& backend) - : name_(name), - sync_data_folder_path_(sync_data_folder_path), - host_(backend), - sync_loop_(NULL), - registrar_(NULL), - has_sync_setup_completed_(has_sync_setup_completed), - forward_protocol_events_(false), - forward_type_info_(false), - weak_ptr_factory_(this) { - DCHECK(backend.get()); -} - -SyncBackendHostCore::~SyncBackendHostCore() { - DCHECK(!sync_manager_.get()); -} - -void SyncBackendHostCore::OnSyncCycleCompleted( - const syncer::sessions::SyncSessionSnapshot& snapshot) { - if (!sync_loop_) - return; - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - - host_.Call( - FROM_HERE, - &SyncBackendHostImpl::HandleSyncCycleCompletedOnFrontendLoop, - snapshot); -} - -void SyncBackendHostCore::DoRefreshTypes(syncer::ModelTypeSet types) { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - sync_manager_->RefreshTypes(types); -} - -void SyncBackendHostCore::OnInitializationComplete( - const syncer::WeakHandle<syncer::JsBackend>& js_backend, - const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& - debug_info_listener, - bool success, - const syncer::ModelTypeSet restored_types) { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - - if (!success) { - DoDestroySyncManager(syncer::STOP_SYNC); - host_.Call(FROM_HERE, - &SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop); - return; - } - - // Register for encryption related changes now. We have to do this before - // the initializing downloading control types or initializing the encryption - // handler in order to receive notifications triggered during encryption - // startup. - sync_manager_->GetEncryptionHandler()->AddObserver(this); - - // Sync manager initialization is complete, so we can schedule recurring - // SaveChanges. - sync_loop_->task_runner()->PostTask( - FROM_HERE, base::Bind(&SyncBackendHostCore::StartSavingChanges, - weak_ptr_factory_.GetWeakPtr())); - - // Hang on to these for a while longer. We're not ready to hand them back to - // the UI thread yet. - js_backend_ = js_backend; - debug_info_listener_ = debug_info_listener; - - // Before proceeding any further, we need to download the control types and - // purge any partial data (ie. data downloaded for a type that was on its way - // to being initially synced, but didn't quite make it.). The following - // configure cycle will take care of this. It depends on the registrar state - // which we initialize below to ensure that we don't perform any downloads if - // all control types have already completed their initial sync. - registrar_->SetInitialTypes(restored_types); - - syncer::ConfigureReason reason = - restored_types.Empty() ? - syncer::CONFIGURE_REASON_NEW_CLIENT : - syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE; - - syncer::ModelTypeSet new_control_types = registrar_->ConfigureDataTypes( - syncer::ControlTypes(), syncer::ModelTypeSet()); - syncer::ModelSafeRoutingInfo routing_info; - registrar_->GetModelSafeRoutingInfo(&routing_info); - SDVLOG(1) << "Control Types " - << syncer::ModelTypeSetToString(new_control_types) - << " added; calling ConfigureSyncer"; - - syncer::ModelTypeSet types_to_purge = - syncer::Difference(syncer::ModelTypeSet::All(), - GetRoutingInfoTypes(routing_info)); - - sync_manager_->ConfigureSyncer( - reason, - new_control_types, - types_to_purge, - syncer::ModelTypeSet(), - syncer::ModelTypeSet(), - routing_info, - base::Bind(&SyncBackendHostCore::DoInitialProcessControlTypes, - weak_ptr_factory_.GetWeakPtr()), - base::Closure()); -} - -void SyncBackendHostCore::OnConnectionStatusChange( - syncer::ConnectionStatus status) { - if (!sync_loop_) - return; - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - host_.Call( - FROM_HERE, - &SyncBackendHostImpl::HandleConnectionStatusChangeOnFrontendLoop, status); -} - -void SyncBackendHostCore::OnPassphraseRequired( - syncer::PassphraseRequiredReason reason, - const sync_pb::EncryptedData& pending_keys) { - if (!sync_loop_) - return; - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - host_.Call( - FROM_HERE, - &SyncBackendHostImpl::NotifyPassphraseRequired, reason, pending_keys); -} - -void SyncBackendHostCore::OnPassphraseAccepted() { - if (!sync_loop_) - return; - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - host_.Call( - FROM_HERE, - &SyncBackendHostImpl::NotifyPassphraseAccepted); -} - -void SyncBackendHostCore::OnBootstrapTokenUpdated( - const std::string& bootstrap_token, - syncer::BootstrapTokenType type) { - if (!sync_loop_) - return; - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - host_.Call(FROM_HERE, - &SyncBackendHostImpl::PersistEncryptionBootstrapToken, - bootstrap_token, - type); -} - -void SyncBackendHostCore::OnEncryptedTypesChanged( - syncer::ModelTypeSet encrypted_types, - bool encrypt_everything) { - if (!sync_loop_) - return; - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - // NOTE: We're in a transaction. - host_.Call( - FROM_HERE, - &SyncBackendHostImpl::NotifyEncryptedTypesChanged, - encrypted_types, encrypt_everything); -} - -void SyncBackendHostCore::OnEncryptionComplete() { - if (!sync_loop_) - return; - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - // NOTE: We're in a transaction. - host_.Call( - FROM_HERE, - &SyncBackendHostImpl::NotifyEncryptionComplete); -} - -void SyncBackendHostCore::OnCryptographerStateChanged( - syncer::Cryptographer* cryptographer) { - // Do nothing. -} - -void SyncBackendHostCore::OnPassphraseTypeChanged( - syncer::PassphraseType type, base::Time passphrase_time) { - host_.Call( - FROM_HERE, - &SyncBackendHostImpl::HandlePassphraseTypeChangedOnFrontendLoop, - type, passphrase_time); -} - -void SyncBackendHostCore::OnLocalSetPassphraseEncryption( - const syncer::SyncEncryptionHandler::NigoriState& nigori_state) { - host_.Call( - FROM_HERE, - &SyncBackendHostImpl::HandleLocalSetPassphraseEncryptionOnFrontendLoop, - nigori_state); -} - -void SyncBackendHostCore::OnCommitCountersUpdated( - syncer::ModelType type, - const syncer::CommitCounters& counters) { - host_.Call( - FROM_HERE, - &SyncBackendHostImpl::HandleDirectoryCommitCountersUpdatedOnFrontendLoop, - type, counters); -} - -void SyncBackendHostCore::OnUpdateCountersUpdated( - syncer::ModelType type, - const syncer::UpdateCounters& counters) { - host_.Call( - FROM_HERE, - &SyncBackendHostImpl::HandleDirectoryUpdateCountersUpdatedOnFrontendLoop, - type, counters); -} - -void SyncBackendHostCore::OnStatusCountersUpdated( - syncer::ModelType type, - const syncer::StatusCounters& counters) { - host_.Call( - FROM_HERE, - &SyncBackendHostImpl::HandleDirectoryStatusCountersUpdatedOnFrontendLoop, - type, counters); -} - -void SyncBackendHostCore::OnActionableError( - const syncer::SyncProtocolError& sync_error) { - if (!sync_loop_) - return; - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - host_.Call( - FROM_HERE, - &SyncBackendHostImpl::HandleActionableErrorEventOnFrontendLoop, - sync_error); -} - -void SyncBackendHostCore::OnMigrationRequested(syncer::ModelTypeSet types) { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - host_.Call( - FROM_HERE, - &SyncBackendHostImpl::HandleMigrationRequestedOnFrontendLoop, - types); -} - -void SyncBackendHostCore::OnProtocolEvent( - const syncer::ProtocolEvent& event) { - // TODO(rlarocque): Find a way to pass event_clone as a scoped_ptr. - if (forward_protocol_events_) { - std::unique_ptr<syncer::ProtocolEvent> event_clone(event.Clone()); - host_.Call( - FROM_HERE, - &SyncBackendHostImpl::HandleProtocolEventOnFrontendLoop, - event_clone.release()); - } -} - -void SyncBackendHostCore::DoOnInvalidatorStateChange( - syncer::InvalidatorState state) { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - sync_manager_->SetInvalidatorEnabled(state == syncer::INVALIDATIONS_ENABLED); -} - -void SyncBackendHostCore::DoOnIncomingInvalidation( - const syncer::ObjectIdInvalidationMap& invalidation_map) { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - - syncer::ObjectIdSet ids = invalidation_map.GetObjectIds(); - for (const invalidation::ObjectId& object_id : ids) { - syncer::ModelType type; - if (!NotificationTypeToRealModelType(object_id.name(), &type)) { - DLOG(WARNING) << "Notification has invalid id: " - << syncer::ObjectIdToString(object_id); - } else { - syncer::SingleObjectInvalidationSet invalidation_set = - invalidation_map.ForObject(object_id); - for (syncer::Invalidation invalidation : invalidation_set) { - auto last_invalidation = last_invalidation_versions_.find(type); - if (!invalidation.is_unknown_version() && - last_invalidation != last_invalidation_versions_.end() && - invalidation.version() <= last_invalidation->second) { - DVLOG(1) << "Ignoring redundant invalidation for " - << syncer::ModelTypeToString(type) << " with version " - << invalidation.version() << ", last seen version was " - << last_invalidation->second; - continue; - } - std::unique_ptr<syncer::InvalidationInterface> inv_adapter( - new InvalidationAdapter(invalidation)); - sync_manager_->OnIncomingInvalidation(type, std::move(inv_adapter)); - if (!invalidation.is_unknown_version()) - last_invalidation_versions_[type] = invalidation.version(); - } - } - } - - host_.Call( - FROM_HERE, - &SyncBackendHostImpl::UpdateInvalidationVersions, - last_invalidation_versions_); -} - -void SyncBackendHostCore::DoInitialize( - std::unique_ptr<DoInitializeOptions> options) { - DCHECK(!sync_loop_); - sync_loop_ = options->sync_loop; - DCHECK(sync_loop_); - - // Finish initializing the HttpBridgeFactory. We do this here because - // building the user agent may block on some platforms. - options->http_bridge_factory->Init(options->sync_user_agent, - base::Bind(&BindFetcherToDataTracker)); - - // Blow away the partial or corrupt sync data folder before doing any more - // initialization, if necessary. - if (options->delete_sync_data_folder) { - DeleteSyncDataFolder(); - } - - // Make sure that the directory exists before initializing the backend. - // If it already exists, this will do no harm. - if (!base::CreateDirectory(sync_data_folder_path_)) { - DLOG(FATAL) << "Sync Data directory creation failed."; - } - - // Load the previously persisted set of invalidation versions into memory. - last_invalidation_versions_ = options->invalidation_versions; - - DCHECK(!registrar_); - registrar_ = options->registrar; - DCHECK(registrar_); - - sync_manager_ = options->sync_manager_factory->CreateSyncManager(name_); - sync_manager_->AddObserver(this); - - syncer::SyncManager::InitArgs args; - args.database_location = sync_data_folder_path_; - args.event_handler = options->event_handler; - args.service_url = options->service_url; - args.post_factory = std::move(options->http_bridge_factory); - args.workers = options->workers; - args.extensions_activity = options->extensions_activity.get(); - args.change_delegate = options->registrar; // as SyncManager::ChangeDelegate - args.credentials = options->credentials; - args.invalidator_client_id = options->invalidator_client_id; - args.restored_key_for_bootstrapping = options->restored_key_for_bootstrapping; - args.restored_keystore_key_for_bootstrapping = - options->restored_keystore_key_for_bootstrapping; - args.internal_components_factory = - std::move(options->internal_components_factory); - args.encryptor = &encryptor_; - args.unrecoverable_error_handler = options->unrecoverable_error_handler; - args.report_unrecoverable_error_function = - options->report_unrecoverable_error_function; - args.cancelation_signal = &stop_syncing_signal_; - args.saved_nigori_state = std::move(options->saved_nigori_state); - sync_manager_->Init(&args); -} - -void SyncBackendHostCore::DoUpdateCredentials( - const syncer::SyncCredentials& credentials) { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - // UpdateCredentials can be called during backend initialization, possibly - // when backend initialization has failed but hasn't notified the UI thread - // yet. In that case, the sync manager may have been destroyed on the sync - // thread before this task was executed, so we do nothing. - if (sync_manager_) { - sync_manager_->UpdateCredentials(credentials); - } -} - -void SyncBackendHostCore::DoStartSyncing( - const syncer::ModelSafeRoutingInfo& routing_info, - base::Time last_poll_time) { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - sync_manager_->StartSyncingNormally(routing_info, last_poll_time); -} - -void SyncBackendHostCore::DoSetEncryptionPassphrase( - const std::string& passphrase, - bool is_explicit) { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - sync_manager_->GetEncryptionHandler()->SetEncryptionPassphrase( - passphrase, is_explicit); -} - -void SyncBackendHostCore::DoInitialProcessControlTypes() { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - - DVLOG(1) << "Initilalizing Control Types"; - - // Initialize encryption. - sync_manager_->GetEncryptionHandler()->Init(); - - // Note: experiments are currently handled via SBH::AddExperimentalTypes, - // which is called at the end of every sync cycle. - // TODO(zea): eventually add an experiment handler and initialize it here. - - if (!sync_manager_->GetUserShare()) { // NULL in some tests. - DVLOG(1) << "Skipping initialization of DeviceInfo"; - host_.Call( - FROM_HERE, - &SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop); - return; - } - - if (!sync_manager_->InitialSyncEndedTypes().HasAll(syncer::ControlTypes())) { - LOG(ERROR) << "Failed to download control types"; - host_.Call( - FROM_HERE, - &SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop); - return; - } - - host_.Call(FROM_HERE, - &SyncBackendHostImpl::HandleInitializationSuccessOnFrontendLoop, - js_backend_, debug_info_listener_, - base::Passed(sync_manager_->GetModelTypeConnectorProxy()), - sync_manager_->cache_guid()); - - js_backend_.Reset(); - debug_info_listener_.Reset(); -} - -void SyncBackendHostCore::DoSetDecryptionPassphrase( - const std::string& passphrase) { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - sync_manager_->GetEncryptionHandler()->SetDecryptionPassphrase( - passphrase); -} - -void SyncBackendHostCore::DoEnableEncryptEverything() { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - sync_manager_->GetEncryptionHandler()->EnableEncryptEverything(); -} - -void SyncBackendHostCore::ShutdownOnUIThread() { - // This will cut short any blocking network tasks, cut short any in-progress - // sync cycles, and prevent the creation of new blocking network tasks and new - // sync cycles. If there was an in-progress network request, it would have - // had a reference to the RequestContextGetter. This reference will be - // dropped by the time this function returns. - // - // It is safe to call this even if Sync's backend classes have not been - // initialized yet. Those classes will receive the message when the sync - // thread finally getes around to constructing them. - stop_syncing_signal_.Signal(); - - // This will drop the HttpBridgeFactory's reference to the - // RequestContextGetter. Once this has been called, the HttpBridgeFactory can - // no longer be used to create new HttpBridge instances. We can get away with - // this because the stop_syncing_signal_ has already been signalled, which - // guarantees that the ServerConnectionManager will no longer attempt to - // create new connections. - release_request_context_signal_.Signal(); -} - -void SyncBackendHostCore::DoShutdown(syncer::ShutdownReason reason) { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - - DoDestroySyncManager(reason); - - registrar_ = NULL; - - if (reason == syncer::DISABLE_SYNC) - DeleteSyncDataFolder(); - - host_.Reset(); - weak_ptr_factory_.InvalidateWeakPtrs(); -} - -void SyncBackendHostCore::DoDestroySyncManager(syncer::ShutdownReason reason) { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - if (sync_manager_) { - DisableDirectoryTypeDebugInfoForwarding(); - save_changes_timer_.reset(); - sync_manager_->RemoveObserver(this); - sync_manager_->ShutdownOnSyncThread(reason); - sync_manager_.reset(); - } -} - -void SyncBackendHostCore::DoConfigureSyncer( - syncer::ConfigureReason reason, - const DoConfigureSyncerTypes& config_types, - const syncer::ModelSafeRoutingInfo routing_info, - const base::Callback<void(syncer::ModelTypeSet, - syncer::ModelTypeSet)>& ready_task, - const base::Closure& retry_callback) { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - DCHECK(!ready_task.is_null()); - DCHECK(!retry_callback.is_null()); - base::Closure chained_ready_task( - base::Bind(&SyncBackendHostCore::DoFinishConfigureDataTypes, - weak_ptr_factory_.GetWeakPtr(), - config_types.to_download, - ready_task)); - base::Closure chained_retry_task( - base::Bind(&SyncBackendHostCore::DoRetryConfiguration, - weak_ptr_factory_.GetWeakPtr(), - retry_callback)); - sync_manager_->ConfigureSyncer(reason, - config_types.to_download, - config_types.to_purge, - config_types.to_journal, - config_types.to_unapply, - routing_info, - chained_ready_task, - chained_retry_task); -} - -void SyncBackendHostCore::DoFinishConfigureDataTypes( - syncer::ModelTypeSet types_to_config, - const base::Callback<void(syncer::ModelTypeSet, - syncer::ModelTypeSet)>& ready_task) { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - - // Update the enabled types for the bridge and sync manager. - syncer::ModelSafeRoutingInfo routing_info; - registrar_->GetModelSafeRoutingInfo(&routing_info); - syncer::ModelTypeSet enabled_types = GetRoutingInfoTypes(routing_info); - enabled_types.RemoveAll(syncer::ProxyTypes()); - - const syncer::ModelTypeSet failed_configuration_types = - Difference(types_to_config, sync_manager_->InitialSyncEndedTypes()); - const syncer::ModelTypeSet succeeded_configuration_types = - Difference(types_to_config, failed_configuration_types); - host_.Call(FROM_HERE, - &SyncBackendHostImpl::FinishConfigureDataTypesOnFrontendLoop, - enabled_types, - succeeded_configuration_types, - failed_configuration_types, - ready_task); -} - -void SyncBackendHostCore::DoRetryConfiguration( - const base::Closure& retry_callback) { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - host_.Call(FROM_HERE, - &SyncBackendHostImpl::RetryConfigurationOnFrontendLoop, - retry_callback); -} - -void SyncBackendHostCore::SendBufferedProtocolEventsAndEnableForwarding() { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - forward_protocol_events_ = true; - - if (sync_manager_) { - // Grab our own copy of the buffered events. - // The buffer is not modified by this operation. - std::vector<syncer::ProtocolEvent*> buffered_events; - sync_manager_->GetBufferedProtocolEvents().release(&buffered_events); - - // Send them all over the fence to the host. - for (std::vector<syncer::ProtocolEvent*>::iterator it = - buffered_events.begin(); it != buffered_events.end(); ++it) { - // TODO(rlarocque): Make it explicit that host_ takes ownership. - host_.Call( - FROM_HERE, - &SyncBackendHostImpl::HandleProtocolEventOnFrontendLoop, - *it); - } - } -} - -void SyncBackendHostCore::DisableProtocolEventForwarding() { - forward_protocol_events_ = false; -} - -void SyncBackendHostCore::EnableDirectoryTypeDebugInfoForwarding() { - DCHECK(sync_manager_); - - forward_type_info_ = true; - - if (!sync_manager_->HasDirectoryTypeDebugInfoObserver(this)) - sync_manager_->RegisterDirectoryTypeDebugInfoObserver(this); - sync_manager_->RequestEmitDebugInfo(); -} - -void SyncBackendHostCore::DisableDirectoryTypeDebugInfoForwarding() { - DCHECK(sync_manager_); - - if (!forward_type_info_) - return; - - forward_type_info_ = false; - - if (sync_manager_->HasDirectoryTypeDebugInfoObserver(this)) - sync_manager_->UnregisterDirectoryTypeDebugInfoObserver(this); -} - -void SyncBackendHostCore::DeleteSyncDataFolder() { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - if (base::DirectoryExists(sync_data_folder_path_)) { - if (!base::DeleteFile(sync_data_folder_path_, true)) - SLOG(DFATAL) << "Could not delete the Sync Data folder."; - } -} - -void SyncBackendHostCore::GetAllNodesForTypes( - syncer::ModelTypeSet types, - scoped_refptr<base::SequencedTaskRunner> task_runner, - base::Callback<void(const std::vector<syncer::ModelType>& type, - ScopedVector<base::ListValue>)> callback) { - std::vector<syncer::ModelType> types_vector; - ScopedVector<base::ListValue> node_lists; - - syncer::ModelSafeRoutingInfo routes; - registrar_->GetModelSafeRoutingInfo(&routes); - syncer::ModelTypeSet enabled_types = GetRoutingInfoTypes(routes); - - for (syncer::ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) { - types_vector.push_back(it.Get()); - if (!enabled_types.Has(it.Get())) { - node_lists.push_back(new base::ListValue()); - } else { - node_lists.push_back( - sync_manager_->GetAllNodesForType(it.Get()).release()); - } - } - - task_runner->PostTask( - FROM_HERE, - base::Bind(callback, types_vector, base::Passed(&node_lists))); -} - -void SyncBackendHostCore::StartSavingChanges() { - // We may already be shut down. - if (!sync_loop_) - return; - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - DCHECK(!save_changes_timer_.get()); - save_changes_timer_.reset(new base::RepeatingTimer()); - save_changes_timer_->Start(FROM_HERE, - base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds), - this, &SyncBackendHostCore::SaveChanges); -} - -void SyncBackendHostCore::SaveChanges() { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - sync_manager_->SaveChanges(); -} - -void SyncBackendHostCore::DoClearServerData( - const syncer::SyncManager::ClearServerDataCallback& frontend_callback) { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - const syncer::SyncManager::ClearServerDataCallback callback = - base::Bind(&SyncBackendHostCore::ClearServerDataDone, - weak_ptr_factory_.GetWeakPtr(), frontend_callback); - sync_manager_->ClearServerData(callback); -} - -void SyncBackendHostCore::DoOnCookieJarChanged(bool account_mismatch, - bool empty_jar) { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - sync_manager_->OnCookieJarChanged(account_mismatch, empty_jar); -} - -void SyncBackendHostCore::ClearServerDataDone( - const base::Closure& frontend_callback) { - DCHECK(sync_loop_->task_runner()->BelongsToCurrentThread()); - host_.Call(FROM_HERE, &SyncBackendHostImpl::ClearServerDataDoneOnFrontendLoop, - frontend_callback); -} - - -} // namespace browser_sync
diff --git a/components/sync_driver/glue/sync_backend_host_core.h b/components/sync_driver/glue/sync_backend_host_core.h deleted file mode 100644 index 4e8bf43d..0000000 --- a/components/sync_driver/glue/sync_backend_host_core.h +++ /dev/null
@@ -1,342 +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 COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_CORE_H_ -#define COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_CORE_H_ - -#include <stdint.h> - -#include <map> -#include <string> -#include <vector> - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/timer/timer.h" -#include "components/invalidation/public/invalidation.h" -#include "components/sync/base/cancelation_signal.h" -#include "components/sync/core/shutdown_reason.h" -#include "components/sync/core/sync_encryption_handler.h" -#include "components/sync/sessions/type_debug_info_observer.h" -#include "components/sync_driver/glue/sync_backend_host_impl.h" -#include "components/sync_driver/system_encryptor.h" -#include "url/gurl.h" - -namespace browser_sync { - -class SyncBackendHostImpl; - -// Utility struct for holding initialization options. -struct DoInitializeOptions { - DoInitializeOptions( - base::MessageLoop* sync_loop, - SyncBackendRegistrar* registrar, - const std::vector<scoped_refptr<syncer::ModelSafeWorker>>& workers, - const scoped_refptr<syncer::ExtensionsActivity>& extensions_activity, - const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, - const GURL& service_url, - const std::string& sync_user_agent, - std::unique_ptr<syncer::HttpPostProviderFactory> http_bridge_factory, - const syncer::SyncCredentials& credentials, - const std::string& invalidator_client_id, - std::unique_ptr<syncer::SyncManagerFactory> sync_manager_factory, - bool delete_sync_data_folder, - const std::string& restored_key_for_bootstrapping, - const std::string& restored_keystore_key_for_bootstrapping, - std::unique_ptr<syncer::InternalComponentsFactory> - internal_components_factory, - const syncer::WeakHandle<syncer::UnrecoverableErrorHandler>& - unrecoverable_error_handler, - const base::Closure& report_unrecoverable_error_function, - std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> - saved_nigori_state, - const std::map<syncer::ModelType, int64_t>& invalidation_versions); - ~DoInitializeOptions(); - - base::MessageLoop* sync_loop; - SyncBackendRegistrar* registrar; - std::vector<scoped_refptr<syncer::ModelSafeWorker> > workers; - scoped_refptr<syncer::ExtensionsActivity> extensions_activity; - syncer::WeakHandle<syncer::JsEventHandler> event_handler; - GURL service_url; - std::string sync_user_agent; - // Overridden by tests. - std::unique_ptr<syncer::HttpPostProviderFactory> http_bridge_factory; - syncer::SyncCredentials credentials; - const std::string invalidator_client_id; - std::unique_ptr<syncer::SyncManagerFactory> sync_manager_factory; - std::string lsid; - bool delete_sync_data_folder; - std::string restored_key_for_bootstrapping; - std::string restored_keystore_key_for_bootstrapping; - std::unique_ptr<syncer::InternalComponentsFactory> - internal_components_factory; - const syncer::WeakHandle<syncer::UnrecoverableErrorHandler> - unrecoverable_error_handler; - base::Closure report_unrecoverable_error_function; - std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> - saved_nigori_state; - const std::map<syncer::ModelType, int64_t> invalidation_versions; -}; - -// Helper struct to handle currying params to -// SyncBackendHost::Core::DoConfigureSyncer. -struct DoConfigureSyncerTypes { - DoConfigureSyncerTypes(); - DoConfigureSyncerTypes(const DoConfigureSyncerTypes& other); - ~DoConfigureSyncerTypes(); - syncer::ModelTypeSet to_download; - syncer::ModelTypeSet to_purge; - syncer::ModelTypeSet to_journal; - syncer::ModelTypeSet to_unapply; -}; - -class SyncBackendHostCore - : public base::RefCountedThreadSafe<SyncBackendHostCore>, - public syncer::SyncEncryptionHandler::Observer, - public syncer::SyncManager::Observer, - public syncer::TypeDebugInfoObserver { - public: - SyncBackendHostCore(const std::string& name, - const base::FilePath& sync_data_folder_path, - bool has_sync_setup_completed, - const base::WeakPtr<SyncBackendHostImpl>& backend); - - // SyncManager::Observer implementation. The Core just acts like an air - // traffic controller here, forwarding incoming messages to appropriate - // landing threads. - void OnSyncCycleCompleted( - const syncer::sessions::SyncSessionSnapshot& snapshot) override; - void OnInitializationComplete( - const syncer::WeakHandle<syncer::JsBackend>& js_backend, - const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& - debug_info_listener, - bool success, - syncer::ModelTypeSet restored_types) override; - void OnConnectionStatusChange(syncer::ConnectionStatus status) override; - void OnActionableError(const syncer::SyncProtocolError& sync_error) override; - void OnMigrationRequested(syncer::ModelTypeSet types) override; - void OnProtocolEvent(const syncer::ProtocolEvent& event) override; - - // SyncEncryptionHandler::Observer implementation. - void OnPassphraseRequired( - syncer::PassphraseRequiredReason reason, - const sync_pb::EncryptedData& pending_keys) override; - void OnPassphraseAccepted() override; - void OnBootstrapTokenUpdated(const std::string& bootstrap_token, - syncer::BootstrapTokenType type) override; - void OnEncryptedTypesChanged(syncer::ModelTypeSet encrypted_types, - bool encrypt_everything) override; - void OnEncryptionComplete() override; - void OnCryptographerStateChanged( - syncer::Cryptographer* cryptographer) override; - void OnPassphraseTypeChanged(syncer::PassphraseType type, - base::Time passphrase_time) override; - void OnLocalSetPassphraseEncryption( - const syncer::SyncEncryptionHandler::NigoriState& nigori_state) override; - - // TypeDebugInfoObserver implementation - void OnCommitCountersUpdated(syncer::ModelType type, - const syncer::CommitCounters& counters) override; - void OnUpdateCountersUpdated(syncer::ModelType type, - const syncer::UpdateCounters& counters) override; - void OnStatusCountersUpdated(syncer::ModelType type, - const syncer::StatusCounters& counters) override; - - // Forwards an invalidation state change to the sync manager. - void DoOnInvalidatorStateChange(syncer::InvalidatorState state); - - // Forwards an invalidation to the sync manager. - void DoOnIncomingInvalidation( - const syncer::ObjectIdInvalidationMap& invalidation_map); - - // Note: - // - // The Do* methods are the various entry points from our - // SyncBackendHost. They are all called on the sync thread to - // actually perform synchronous (and potentially blocking) syncapi - // operations. - // - // Called to perform initialization of the syncapi on behalf of - // SyncBackendHost::Initialize. - void DoInitialize(std::unique_ptr<DoInitializeOptions> options); - - // Called to perform credential update on behalf of - // SyncBackendHost::UpdateCredentials. - void DoUpdateCredentials(const syncer::SyncCredentials& credentials); - - // Called to tell the syncapi to start syncing (generally after - // initialization and authentication). - void DoStartSyncing(const syncer::ModelSafeRoutingInfo& routing_info, - base::Time last_poll_time); - - // Called to set the passphrase for encryption. - void DoSetEncryptionPassphrase(const std::string& passphrase, - bool is_explicit); - - // Called to decrypt the pending keys. - void DoSetDecryptionPassphrase(const std::string& passphrase); - - // Called to turn on encryption of all sync data as well as - // reencrypt everything. - void DoEnableEncryptEverything(); - - // Ask the syncer to check for updates for the specified types. - void DoRefreshTypes(syncer::ModelTypeSet types); - - // Invoked if we failed to download the necessary control types at startup. - // Invokes SyncBackendHost::HandleControlTypesDownloadRetry. - void OnControlTypesDownloadRetry(); - - // Called to perform tasks which require the control data to be downloaded. - // This includes refreshing encryption, etc. - void DoInitialProcessControlTypes(); - - // The shutdown order is a bit complicated: - // 1) Call ShutdownOnUIThread() from |frontend_loop_| to request sync manager - // to stop as soon as possible. - // 2) Post DoShutdown() to sync loop to clean up backend state, save - // directory and destroy sync manager. - void ShutdownOnUIThread(); - void DoShutdown(syncer::ShutdownReason reason); - void DoDestroySyncManager(syncer::ShutdownReason reason); - - // Configuration methods that must execute on sync loop. - void DoConfigureSyncer( - syncer::ConfigureReason reason, - const DoConfigureSyncerTypes& config_types, - const syncer::ModelSafeRoutingInfo routing_info, - const base::Callback<void(syncer::ModelTypeSet, - syncer::ModelTypeSet)>& ready_task, - const base::Closure& retry_callback); - void DoFinishConfigureDataTypes( - syncer::ModelTypeSet types_to_config, - const base::Callback<void(syncer::ModelTypeSet, - syncer::ModelTypeSet)>& ready_task); - void DoRetryConfiguration( - const base::Closure& retry_callback); - - // Set the base request context to use when making HTTP calls. - // This method will add a reference to the context to persist it - // on the IO thread. Must be removed from IO thread. - - syncer::SyncManager* sync_manager() { return sync_manager_.get(); } - - void SendBufferedProtocolEventsAndEnableForwarding(); - void DisableProtocolEventForwarding(); - - // Enables the forwarding of directory type debug counters to the - // SyncBackendHost. Also requests that updates to all counters be - // emitted right away to initialize any new listeners' states. - void EnableDirectoryTypeDebugInfoForwarding(); - - // Disables forwarding of directory type debug counters. - void DisableDirectoryTypeDebugInfoForwarding(); - - // Delete the sync data folder to cleanup backend data. Happens the first - // time sync is enabled for a user (to prevent accidentally reusing old - // sync databases), as well as shutdown when you're no longer syncing. - void DeleteSyncDataFolder(); - - // We expose this member because it's required in the construction of the - // HttpBridgeFactory. - syncer::CancelationSignal* GetRequestContextCancelationSignal() { - return &release_request_context_signal_; - } - - void GetAllNodesForTypes( - syncer::ModelTypeSet types, - scoped_refptr<base::SequencedTaskRunner> task_runner, - base::Callback<void(const std::vector<syncer::ModelType>& type, - ScopedVector<base::ListValue>) > callback); - - // Tell the sync manager to persist its state by writing to disk. - // Called on the sync thread, both by a timer and, on Android, when the - // application is backgrounded. - void SaveChanges(); - - void DoClearServerData( - const syncer::SyncManager::ClearServerDataCallback& frontend_callback); - - // Notify the syncer that the cookie jar has changed. - void DoOnCookieJarChanged(bool account_mismatch, bool empty_jar); - - private: - friend class base::RefCountedThreadSafe<SyncBackendHostCore>; - friend class SyncBackendHostForProfileSyncTest; - - ~SyncBackendHostCore() override; - - // Invoked when initialization of syncapi is complete and we can start - // our timer. - // This must be called from the thread on which SaveChanges is intended to - // be run on; the host's |registrar_->sync_thread()|. - void StartSavingChanges(); - - void ClearServerDataDone(const base::Closure& frontend_callback); - - // Name used for debugging. - const std::string name_; - - // Path of the folder that stores the sync data files. - const base::FilePath sync_data_folder_path_; - - // Our parent SyncBackendHost. - syncer::WeakHandle<SyncBackendHostImpl> host_; - - // The loop where all the sync backend operations happen. - // Non-NULL only between calls to DoInitialize() and ~Core(). - base::MessageLoop* sync_loop_; - - // Our parent's registrar (not owned). Non-NULL only between - // calls to DoInitialize() and DoShutdown(). - SyncBackendRegistrar* registrar_; - - // The timer used to periodically call SaveChanges. - std::unique_ptr<base::RepeatingTimer> save_changes_timer_; - - // Our encryptor, which uses Chrome's encryption functions. - sync_driver::SystemEncryptor encryptor_; - - // The top-level syncapi entry point. Lives on the sync thread. - std::unique_ptr<syncer::SyncManager> sync_manager_; - - // Temporary holder of sync manager's initialization results. Set by - // OnInitializeComplete, and consumed when we pass it via OnBackendInitialized - // in the final state of HandleInitializationSuccessOnFrontendLoop. - syncer::WeakHandle<syncer::JsBackend> js_backend_; - syncer::WeakHandle<syncer::DataTypeDebugInfoListener> debug_info_listener_; - - // These signals allow us to send requests to shut down the HttpBridgeFactory - // and ServerConnectionManager without having to wait for those classes to - // finish initializing first. - // - // See comments in SyncBackendHostCore::ShutdownOnUIThread() for more details. - syncer::CancelationSignal release_request_context_signal_; - syncer::CancelationSignal stop_syncing_signal_; - - // Matches the value of SyncPref's IsFirstSetupComplete() flag at init time. - // Should not be used for anything except for UMAs and logging. - const bool has_sync_setup_completed_; - - // Set when we've been asked to forward sync protocol events to the frontend. - bool forward_protocol_events_; - - // Set when the forwarding of per-type debug counters is enabled. - bool forward_type_info_; - - // A map of data type -> invalidation version to track the most recently - // received invalidation version for each type. - // This allows dropping any invalidations with versions older than those - // most recently received for that data type. - std::map<syncer::ModelType, int64_t> last_invalidation_versions_; - - base::WeakPtrFactory<SyncBackendHostCore> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(SyncBackendHostCore); -}; - -} // namespace browser_sync - -#endif // COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_CORE_H_
diff --git a/components/sync_driver/glue/sync_backend_host_impl.cc b/components/sync_driver/glue/sync_backend_host_impl.cc deleted file mode 100644 index 5b0ae62..0000000 --- a/components/sync_driver/glue/sync_backend_host_impl.cc +++ /dev/null
@@ -1,873 +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 "components/sync_driver/glue/sync_backend_host_impl.h" - -#include <map> -#include <utility> -#include <vector> - -#include "base/command_line.h" -#include "base/feature_list.h" -#include "base/location.h" -#include "base/logging.h" -#include "base/threading/thread_task_runner_handle.h" -#include "components/invalidation/public/invalidation_service.h" -#include "components/invalidation/public/object_id_invalidation_map.h" -#include "components/signin/core/browser/signin_client.h" -#include "components/sync/base/experiments.h" -#include "components/sync/base/sync_string_conversions.h" -#include "components/sync/core/activation_context.h" -#include "components/sync/core/base_transaction.h" -#include "components/sync/core/http_bridge.h" -#include "components/sync/core/internal_components_factory.h" -#include "components/sync/core/internal_components_factory_impl.h" -#include "components/sync/core/sync_manager.h" -#include "components/sync/core/sync_manager_factory.h" -#include "components/sync/engine/events/protocol_event.h" -#include "components/sync_driver/glue/sync_backend_host_core.h" -#include "components/sync_driver/glue/sync_backend_registrar.h" -#include "components/sync_driver/invalidation_helper.h" -#include "components/sync_driver/sync_client.h" -#include "components/sync_driver/sync_driver_switches.h" -#include "components/sync_driver/sync_frontend.h" -#include "components/sync_driver/sync_prefs.h" - -// Helper macros to log with the syncer thread name; useful when there -// are multiple syncers involved. - -#define SLOG(severity) LOG(severity) << name_ << ": " - -#define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": " - -using syncer::InternalComponentsFactory; - -namespace browser_sync { - -SyncBackendHostImpl::SyncBackendHostImpl( - const std::string& name, - sync_driver::SyncClient* sync_client, - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - invalidation::InvalidationService* invalidator, - const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs, - const base::FilePath& sync_folder) - : frontend_task_runner_(base::ThreadTaskRunnerHandle::Get()), - sync_client_(sync_client), - ui_thread_(ui_thread), - name_(name), - initialized_(false), - sync_prefs_(sync_prefs), - frontend_(NULL), - cached_passphrase_type_(syncer::IMPLICIT_PASSPHRASE), - invalidator_(invalidator), - invalidation_handler_registered_(false), - weak_ptr_factory_(this) { - core_ = new SyncBackendHostCore(name_, sync_folder, - sync_prefs_->IsFirstSetupComplete(), - weak_ptr_factory_.GetWeakPtr()); -} - -SyncBackendHostImpl::~SyncBackendHostImpl() { - DCHECK(!core_.get() && !frontend_) << "Must call Shutdown before destructor."; - DCHECK(!registrar_.get()); -} - -void SyncBackendHostImpl::Initialize( - sync_driver::SyncFrontend* frontend, - std::unique_ptr<base::Thread> sync_thread, - const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, - const scoped_refptr<base::SingleThreadTaskRunner>& file_thread, - const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, - const GURL& sync_service_url, - const std::string& sync_user_agent, - const syncer::SyncCredentials& credentials, - bool delete_sync_data_folder, - std::unique_ptr<syncer::SyncManagerFactory> sync_manager_factory, - const syncer::WeakHandle<syncer::UnrecoverableErrorHandler>& - unrecoverable_error_handler, - const base::Closure& report_unrecoverable_error_function, - const HttpPostProviderFactoryGetter& http_post_provider_factory_getter, - std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> - saved_nigori_state) { - registrar_.reset(new browser_sync::SyncBackendRegistrar( - name_, sync_client_, std::move(sync_thread), ui_thread_, db_thread, - file_thread)); - CHECK(registrar_->sync_thread()); - - frontend_ = frontend; - DCHECK(frontend); - - std::vector<scoped_refptr<syncer::ModelSafeWorker> > workers; - registrar_->GetWorkers(&workers); - - InternalComponentsFactory::Switches factory_switches = { - InternalComponentsFactory::ENCRYPTION_KEYSTORE, - InternalComponentsFactory::BACKOFF_NORMAL - }; - - base::CommandLine* cl = base::CommandLine::ForCurrentProcess(); - if (cl->HasSwitch(switches::kSyncShortInitialRetryOverride)) { - factory_switches.backoff_override = - InternalComponentsFactory::BACKOFF_SHORT_INITIAL_RETRY_OVERRIDE; - } - if (cl->HasSwitch(switches::kSyncEnableGetUpdateAvoidance)) { - factory_switches.pre_commit_updates_policy = - InternalComponentsFactory::FORCE_ENABLE_PRE_COMMIT_UPDATE_AVOIDANCE; - } - - std::map<syncer::ModelType, int64_t> invalidation_versions; - sync_prefs_->GetInvalidationVersions(&invalidation_versions); - - std::unique_ptr<DoInitializeOptions> init_opts(new DoInitializeOptions( - registrar_->sync_thread()->message_loop(), registrar_.get(), workers, - sync_client_->GetExtensionsActivity(), event_handler, sync_service_url, - sync_user_agent, http_post_provider_factory_getter.Run( - core_->GetRequestContextCancelationSignal()), - credentials, invalidator_ ? invalidator_->GetInvalidatorClientId() : "", - std::move(sync_manager_factory), delete_sync_data_folder, - sync_prefs_->GetEncryptionBootstrapToken(), - sync_prefs_->GetKeystoreEncryptionBootstrapToken(), - std::unique_ptr<InternalComponentsFactory>( - new syncer::InternalComponentsFactoryImpl(factory_switches)), - unrecoverable_error_handler, report_unrecoverable_error_function, - std::move(saved_nigori_state), invalidation_versions)); - InitCore(std::move(init_opts)); -} - -void SyncBackendHostImpl::TriggerRefresh(const syncer::ModelTypeSet& types) { - DCHECK(ui_thread_->BelongsToCurrentThread()); - registrar_->sync_thread()->task_runner()->PostTask( - FROM_HERE, - base::Bind(&SyncBackendHostCore::DoRefreshTypes, core_.get(), types)); -} - -void SyncBackendHostImpl::UpdateCredentials( - const syncer::SyncCredentials& credentials) { - DCHECK(registrar_->sync_thread()->IsRunning()); - registrar_->sync_thread()->task_runner()->PostTask( - FROM_HERE, base::Bind(&SyncBackendHostCore::DoUpdateCredentials, - core_.get(), credentials)); -} - -void SyncBackendHostImpl::StartSyncingWithServer() { - SDVLOG(1) << "SyncBackendHostImpl::StartSyncingWithServer called."; - - syncer::ModelSafeRoutingInfo routing_info; - registrar_->GetModelSafeRoutingInfo(&routing_info); - - registrar_->sync_thread()->task_runner()->PostTask( - FROM_HERE, base::Bind(&SyncBackendHostCore::DoStartSyncing, core_.get(), - routing_info, sync_prefs_->GetLastPollTime())); -} - -void SyncBackendHostImpl::SetEncryptionPassphrase(const std::string& passphrase, - bool is_explicit) { - DCHECK(registrar_->sync_thread()->IsRunning()); - if (!IsNigoriEnabled()) { - NOTREACHED() << "SetEncryptionPassphrase must never be called when nigori" - " is disabled."; - return; - } - - // We should never be called with an empty passphrase. - DCHECK(!passphrase.empty()); - - // This should only be called by the frontend. - DCHECK(frontend_task_runner_->BelongsToCurrentThread()); - - // SetEncryptionPassphrase should never be called if we are currently - // encrypted with an explicit passphrase. - DCHECK(cached_passphrase_type_ == syncer::KEYSTORE_PASSPHRASE || - cached_passphrase_type_ == syncer::IMPLICIT_PASSPHRASE); - - // Post an encryption task on the syncer thread. - registrar_->sync_thread()->task_runner()->PostTask( - FROM_HERE, base::Bind(&SyncBackendHostCore::DoSetEncryptionPassphrase, - core_.get(), passphrase, is_explicit)); -} - -bool SyncBackendHostImpl::SetDecryptionPassphrase( - const std::string& passphrase) { - if (!IsNigoriEnabled()) { - NOTREACHED() << "SetDecryptionPassphrase must never be called when nigori" - " is disabled."; - return false; - } - - // We should never be called with an empty passphrase. - DCHECK(!passphrase.empty()); - - // This should only be called by the frontend. - DCHECK(frontend_task_runner_->BelongsToCurrentThread()); - - // This should only be called when we have cached pending keys. - DCHECK(cached_pending_keys_.has_blob()); - - // Check the passphrase that was provided against our local cache of the - // cryptographer's pending keys. If this was unsuccessful, the UI layer can - // immediately call OnPassphraseRequired without showing the user a spinner. - if (!CheckPassphraseAgainstCachedPendingKeys(passphrase)) - return false; - - // Post a decryption task on the syncer thread. - registrar_->sync_thread()->task_runner()->PostTask( - FROM_HERE, base::Bind(&SyncBackendHostCore::DoSetDecryptionPassphrase, - core_.get(), passphrase)); - - // Since we were able to decrypt the cached pending keys with the passphrase - // provided, we immediately alert the UI layer that the passphrase was - // accepted. This will avoid the situation where a user enters a passphrase, - // clicks OK, immediately reopens the advanced settings dialog, and gets an - // unnecessary prompt for a passphrase. - // Note: It is not guaranteed that the passphrase will be accepted by the - // syncer thread, since we could receive a new nigori node while the task is - // pending. This scenario is a valid race, and SetDecryptionPassphrase can - // trigger a new OnPassphraseRequired if it needs to. - NotifyPassphraseAccepted(); - return true; -} - -void SyncBackendHostImpl::StopSyncingForShutdown() { - DCHECK(frontend_task_runner_->BelongsToCurrentThread()); - - // Immediately stop sending messages to the frontend. - frontend_ = NULL; - - DCHECK(registrar_->sync_thread()->IsRunning()); - - registrar_->RequestWorkerStopOnUIThread(); - - core_->ShutdownOnUIThread(); -} - -std::unique_ptr<base::Thread> SyncBackendHostImpl::Shutdown( - syncer::ShutdownReason reason) { - // StopSyncingForShutdown() (which nulls out |frontend_|) should be - // called first. - DCHECK(!frontend_); - DCHECK(registrar_->sync_thread()->IsRunning()); - - bool sync_thread_claimed = (reason != syncer::BROWSER_SHUTDOWN); - - if (invalidation_handler_registered_) { - if (reason == syncer::DISABLE_SYNC) { - UnregisterInvalidationIds(); - } - invalidator_->UnregisterInvalidationHandler(this); - invalidator_ = NULL; - } - invalidation_handler_registered_ = false; - - model_type_connector_.reset(); - - // Shut down and destroy sync manager. - registrar_->sync_thread()->task_runner()->PostTask( - FROM_HERE, - base::Bind(&SyncBackendHostCore::DoShutdown, core_.get(), reason)); - core_ = NULL; - - // Worker cleanup. - SyncBackendRegistrar* detached_registrar = registrar_.release(); - detached_registrar->sync_thread()->task_runner()->PostTask( - FROM_HERE, base::Bind(&SyncBackendRegistrar::Shutdown, - base::Unretained(detached_registrar))); - - if (sync_thread_claimed) - return detached_registrar->ReleaseSyncThread(); - else - return std::unique_ptr<base::Thread>(); -} - -void SyncBackendHostImpl::UnregisterInvalidationIds() { - if (invalidation_handler_registered_) { - CHECK(invalidator_->UpdateRegisteredInvalidationIds(this, - syncer::ObjectIdSet())); - } -} - -syncer::ModelTypeSet SyncBackendHostImpl::ConfigureDataTypes( - syncer::ConfigureReason reason, - const DataTypeConfigStateMap& config_state_map, - const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& - ready_task, - const base::Callback<void()>& retry_callback) { - // Only one configure is allowed at a time. This is guaranteed by our - // callers. The SyncBackendHostImpl requests one configure as the backend is - // initializing and waits for it to complete. After initialization, all - // configurations will pass through the DataTypeManager, which is careful to - // never send a new configure request until the current request succeeds. - - // The SyncBackendRegistrar's routing info will be updated by adding the - // types_to_add to the list then removing types_to_remove. Any types which - // are not in either of those sets will remain untouched. - // - // Types which were not in the list previously are not fully downloaded, so we - // must ask the syncer to download them. Any newly supported datatypes will - // not have been in that routing info list, so they will be among the types - // downloaded if they are enabled. - // - // The SyncBackendRegistrar's state was initially derived from the types - // detected to have been downloaded in the database. Afterwards it is - // modified only by this function. We expect it to remain in sync with the - // backend because configuration requests are never aborted; they are retried - // until they succeed or the backend is shut down. - - syncer::ModelTypeSet disabled_types = - GetDataTypesInState(DISABLED, config_state_map); - syncer::ModelTypeSet fatal_types = - GetDataTypesInState(FATAL, config_state_map); - syncer::ModelTypeSet crypto_types = - GetDataTypesInState(CRYPTO, config_state_map); - syncer::ModelTypeSet unready_types = - GetDataTypesInState(UNREADY, config_state_map); - - disabled_types.PutAll(fatal_types); - disabled_types.PutAll(crypto_types); - disabled_types.PutAll(unready_types); - - syncer::ModelTypeSet active_types = - GetDataTypesInState(CONFIGURE_ACTIVE, config_state_map); - syncer::ModelTypeSet clean_first_types = - GetDataTypesInState(CONFIGURE_CLEAN, config_state_map); - syncer::ModelTypeSet types_to_download = registrar_->ConfigureDataTypes( - syncer::Union(active_types, clean_first_types), - disabled_types); - types_to_download.PutAll(clean_first_types); - types_to_download.RemoveAll(syncer::ProxyTypes()); - if (!types_to_download.Empty()) - types_to_download.Put(syncer::NIGORI); - - // TODO(sync): crbug.com/137550. - // It's dangerous to configure types that have progress markers. Types with - // progress markers can trigger a MIGRATION_DONE response. We are not - // prepared to handle a migration during a configure, so we must ensure that - // all our types_to_download actually contain no data before we sync them. - // - // One common way to end up in this situation used to be types which - // downloaded some or all of their data but have not applied it yet. We avoid - // problems with those types by purging the data of any such partially synced - // types soon after we load the directory. - // - // Another possible scenario is that we have newly supported or newly enabled - // data types being downloaded here but the nigori type, which is always - // included in any GetUpdates request, requires migration. The server has - // code to detect this scenario based on the configure reason, the fact that - // the nigori type is the only requested type which requires migration, and - // that the requested types list includes at least one non-nigori type. It - // will not send a MIGRATION_DONE response in that case. We still need to be - // careful to not send progress markers for non-nigori types, though. If a - // non-nigori type in the request requires migration, a MIGRATION_DONE - // response will be sent. - - syncer::ModelSafeRoutingInfo routing_info; - registrar_->GetModelSafeRoutingInfo(&routing_info); - - syncer::ModelTypeSet current_types = registrar_->GetLastConfiguredTypes(); - syncer::ModelTypeSet types_to_purge = - syncer::Difference(syncer::ModelTypeSet::All(), current_types); - syncer::ModelTypeSet inactive_types = - GetDataTypesInState(CONFIGURE_INACTIVE, config_state_map); - types_to_purge.RemoveAll(inactive_types); - types_to_purge.RemoveAll(unready_types); - - // If a type has already been disabled and unapplied or journaled, it will - // not be part of the |types_to_purge| set, and therefore does not need - // to be acted on again. - fatal_types.RetainAll(types_to_purge); - syncer::ModelTypeSet unapply_types = - syncer::Union(crypto_types, clean_first_types); - unapply_types.RetainAll(types_to_purge); - - DCHECK(syncer::Intersection(current_types, fatal_types).Empty()); - DCHECK(syncer::Intersection(current_types, crypto_types).Empty()); - DCHECK(current_types.HasAll(types_to_download)); - - SDVLOG(1) << "Types " - << syncer::ModelTypeSetToString(types_to_download) - << " added; calling DoConfigureSyncer"; - // Divide up the types into their corresponding actions (each is mutually - // exclusive): - // - Types which have just been added to the routing info (types_to_download): - // are downloaded. - // - Types which have encountered a fatal error (fatal_types) are deleted - // from the directory and journaled in the delete journal. - // - Types which have encountered a cryptographer error (crypto_types) are - // unapplied (local state is purged but sync state is not). - // - All other types not in the routing info (types just disabled) are deleted - // from the directory. - // - Everything else (enabled types and already disabled types) is not - // touched. - RequestConfigureSyncer(reason, - types_to_download, - types_to_purge, - fatal_types, - unapply_types, - inactive_types, - routing_info, - ready_task, - retry_callback); - - DCHECK(syncer::Intersection(active_types, types_to_purge).Empty()); - DCHECK(syncer::Intersection(active_types, fatal_types).Empty()); - DCHECK(syncer::Intersection(active_types, unapply_types).Empty()); - DCHECK(syncer::Intersection(active_types, inactive_types).Empty()); - return syncer::Difference(active_types, types_to_download); -} - -void SyncBackendHostImpl::EnableEncryptEverything() { - registrar_->sync_thread()->task_runner()->PostTask( - FROM_HERE, - base::Bind(&SyncBackendHostCore::DoEnableEncryptEverything, core_.get())); -} - -void SyncBackendHostImpl::ActivateDirectoryDataType( - syncer::ModelType type, - syncer::ModelSafeGroup group, - sync_driver::ChangeProcessor* change_processor) { - registrar_->ActivateDataType(type, group, change_processor, GetUserShare()); -} - -void SyncBackendHostImpl::DeactivateDirectoryDataType(syncer::ModelType type) { - registrar_->DeactivateDataType(type); -} - -void SyncBackendHostImpl::ActivateNonBlockingDataType( - syncer::ModelType type, - std::unique_ptr<syncer_v2::ActivationContext> activation_context) { - registrar_->RegisterNonBlockingType(type); - if (activation_context->data_type_state.initial_sync_done()) - registrar_->AddRestoredNonBlockingType(type); - model_type_connector_->ConnectType(type, std::move(activation_context)); -} - -void SyncBackendHostImpl::DeactivateNonBlockingDataType( - syncer::ModelType type) { - model_type_connector_->DisconnectType(type); -} - -syncer::UserShare* SyncBackendHostImpl::GetUserShare() const { - return core_->sync_manager()->GetUserShare(); -} - -SyncBackendHostImpl::Status SyncBackendHostImpl::GetDetailedStatus() { - DCHECK(initialized()); - return core_->sync_manager()->GetDetailedStatus(); -} - -syncer::sessions::SyncSessionSnapshot -SyncBackendHostImpl::GetLastSessionSnapshot() const { - return last_snapshot_; -} - -bool SyncBackendHostImpl::HasUnsyncedItems() const { - DCHECK(initialized()); - return core_->sync_manager()->HasUnsyncedItems(); -} - -bool SyncBackendHostImpl::IsNigoriEnabled() const { - return registrar_.get() && registrar_->IsNigoriEnabled(); -} - -syncer::PassphraseType SyncBackendHostImpl::GetPassphraseType() const { - return cached_passphrase_type_; -} - -base::Time SyncBackendHostImpl::GetExplicitPassphraseTime() const { - return cached_explicit_passphrase_time_; -} - -bool SyncBackendHostImpl::IsCryptographerReady( - const syncer::BaseTransaction* trans) const { - return initialized() && trans->GetCryptographer() && - trans->GetCryptographer()->is_ready(); -} - -void SyncBackendHostImpl::GetModelSafeRoutingInfo( - syncer::ModelSafeRoutingInfo* out) const { - if (initialized()) { - CHECK(registrar_.get()); - registrar_->GetModelSafeRoutingInfo(out); - } else { - NOTREACHED(); - } -} - -void SyncBackendHostImpl::FlushDirectory() const { - DCHECK(initialized()); - registrar_->sync_thread()->task_runner()->PostTask( - FROM_HERE, base::Bind(&SyncBackendHostCore::SaveChanges, core_)); -} - -void SyncBackendHostImpl::RequestBufferedProtocolEventsAndEnableForwarding() { - registrar_->sync_thread()->task_runner()->PostTask( - FROM_HERE, - base::Bind( - &SyncBackendHostCore::SendBufferedProtocolEventsAndEnableForwarding, - core_)); -} - -void SyncBackendHostImpl::DisableProtocolEventForwarding() { - registrar_->sync_thread()->task_runner()->PostTask( - FROM_HERE, - base::Bind(&SyncBackendHostCore::DisableProtocolEventForwarding, core_)); -} - -void SyncBackendHostImpl::EnableDirectoryTypeDebugInfoForwarding() { - DCHECK(initialized()); - registrar_->sync_thread()->task_runner()->PostTask( - FROM_HERE, - base::Bind(&SyncBackendHostCore::EnableDirectoryTypeDebugInfoForwarding, - core_)); -} - -void SyncBackendHostImpl::DisableDirectoryTypeDebugInfoForwarding() { - DCHECK(initialized()); - registrar_->sync_thread()->task_runner()->PostTask( - FROM_HERE, - base::Bind(&SyncBackendHostCore::DisableDirectoryTypeDebugInfoForwarding, - core_)); -} - -void SyncBackendHostImpl::GetAllNodesForTypes( - syncer::ModelTypeSet types, - base::Callback<void(const std::vector<syncer::ModelType>&, - ScopedVector<base::ListValue>)> callback) { - DCHECK(initialized()); - registrar_->sync_thread()->task_runner()->PostTask( - FROM_HERE, base::Bind(&SyncBackendHostCore::GetAllNodesForTypes, core_, - types, frontend_task_runner_, callback)); -} - -void SyncBackendHostImpl::InitCore( - std::unique_ptr<DoInitializeOptions> options) { - registrar_->sync_thread()->task_runner()->PostTask( - FROM_HERE, base::Bind(&SyncBackendHostCore::DoInitialize, core_.get(), - base::Passed(&options))); -} - -void SyncBackendHostImpl::RequestConfigureSyncer( - syncer::ConfigureReason reason, - syncer::ModelTypeSet to_download, - syncer::ModelTypeSet to_purge, - syncer::ModelTypeSet to_journal, - syncer::ModelTypeSet to_unapply, - syncer::ModelTypeSet to_ignore, - const syncer::ModelSafeRoutingInfo& routing_info, - const base::Callback<void(syncer::ModelTypeSet, - syncer::ModelTypeSet)>& ready_task, - const base::Closure& retry_callback) { - DoConfigureSyncerTypes config_types; - config_types.to_download = to_download; - config_types.to_purge = to_purge; - config_types.to_journal = to_journal; - config_types.to_unapply = to_unapply; - registrar_->sync_thread()->task_runner()->PostTask( - FROM_HERE, - base::Bind(&SyncBackendHostCore::DoConfigureSyncer, core_.get(), reason, - config_types, routing_info, ready_task, retry_callback)); -} - -void SyncBackendHostImpl::FinishConfigureDataTypesOnFrontendLoop( - const syncer::ModelTypeSet enabled_types, - const syncer::ModelTypeSet succeeded_configuration_types, - const syncer::ModelTypeSet failed_configuration_types, - const base::Callback<void(syncer::ModelTypeSet, - syncer::ModelTypeSet)>& ready_task) { - if (!frontend_) - return; - - if (invalidator_) { - CHECK(invalidator_->UpdateRegisteredInvalidationIds( - this, ModelTypeSetToObjectIdSet(enabled_types))); - } - - if (!ready_task.is_null()) - ready_task.Run(succeeded_configuration_types, failed_configuration_types); -} - -void SyncBackendHostImpl::AddExperimentalTypes() { - CHECK(initialized()); - syncer::Experiments experiments; - if (core_->sync_manager()->ReceivedExperiment(&experiments)) - frontend_->OnExperimentsChanged(experiments); -} - -void SyncBackendHostImpl::HandleInitializationSuccessOnFrontendLoop( - const syncer::WeakHandle<syncer::JsBackend> js_backend, - const syncer::WeakHandle<syncer::DataTypeDebugInfoListener> - debug_info_listener, - std::unique_ptr<syncer_v2::ModelTypeConnector> model_type_connector, - const std::string& cache_guid) { - DCHECK(frontend_task_runner_->BelongsToCurrentThread()); - - model_type_connector_ = std::move(model_type_connector); - - if (!frontend_) - return; - - initialized_ = true; - - if (invalidator_) { - invalidator_->RegisterInvalidationHandler(this); - invalidation_handler_registered_ = true; - - // Fake a state change to initialize the SyncManager's cached invalidator - // state. - OnInvalidatorStateChange(invalidator_->GetInvalidatorState()); - } - - // Now that we've downloaded the control types, we can see if there are any - // experimental types to enable. This should be done before we inform - // the frontend to ensure they're visible in the customize screen. - AddExperimentalTypes(); - frontend_->OnBackendInitialized(js_backend, - debug_info_listener, - cache_guid, - true); -} - -void SyncBackendHostImpl::HandleInitializationFailureOnFrontendLoop() { - DCHECK(frontend_task_runner_->BelongsToCurrentThread()); - if (!frontend_) - return; - - frontend_->OnBackendInitialized( - syncer::WeakHandle<syncer::JsBackend>(), - syncer::WeakHandle<syncer::DataTypeDebugInfoListener>(), - "", - false); -} - -void SyncBackendHostImpl::HandleSyncCycleCompletedOnFrontendLoop( - const syncer::sessions::SyncSessionSnapshot& snapshot) { - if (!frontend_) - return; - DCHECK(frontend_task_runner_->BelongsToCurrentThread()); - - last_snapshot_ = snapshot; - - SDVLOG(1) << "Got snapshot " << snapshot.ToString(); - - if (!snapshot.poll_finish_time().is_null()) - sync_prefs_->SetLastPollTime(snapshot.poll_finish_time()); - - // Process any changes to the datatypes we're syncing. - // TODO(sync): add support for removing types. - if (initialized()) - AddExperimentalTypes(); - - if (initialized()) - frontend_->OnSyncCycleCompleted(); -} - -void SyncBackendHostImpl::RetryConfigurationOnFrontendLoop( - const base::Closure& retry_callback) { - SDVLOG(1) << "Failed to complete configuration, informing of retry."; - retry_callback.Run(); -} - -void SyncBackendHostImpl::PersistEncryptionBootstrapToken( - const std::string& token, - syncer::BootstrapTokenType token_type) { - CHECK(sync_prefs_.get()); - if (token_type == syncer::PASSPHRASE_BOOTSTRAP_TOKEN) - sync_prefs_->SetEncryptionBootstrapToken(token); - else - sync_prefs_->SetKeystoreEncryptionBootstrapToken(token); -} - -void SyncBackendHostImpl::HandleActionableErrorEventOnFrontendLoop( - const syncer::SyncProtocolError& sync_error) { - if (!frontend_) - return; - DCHECK(frontend_task_runner_->BelongsToCurrentThread()); - frontend_->OnActionableError(sync_error); -} - -void SyncBackendHostImpl::HandleMigrationRequestedOnFrontendLoop( - syncer::ModelTypeSet types) { - if (!frontend_) - return; - DCHECK(frontend_task_runner_->BelongsToCurrentThread()); - frontend_->OnMigrationNeededForTypes(types); -} - -void SyncBackendHostImpl::OnInvalidatorStateChange( - syncer::InvalidatorState state) { - registrar_->sync_thread()->task_runner()->PostTask( - FROM_HERE, base::Bind(&SyncBackendHostCore::DoOnInvalidatorStateChange, - core_.get(), state)); -} - -void SyncBackendHostImpl::OnIncomingInvalidation( - const syncer::ObjectIdInvalidationMap& invalidation_map) { - registrar_->sync_thread()->task_runner()->PostTask( - FROM_HERE, base::Bind(&SyncBackendHostCore::DoOnIncomingInvalidation, - core_.get(), invalidation_map)); -} - -std::string SyncBackendHostImpl::GetOwnerName() const { - return "SyncBackendHostImpl"; -} - -bool SyncBackendHostImpl::CheckPassphraseAgainstCachedPendingKeys( - const std::string& passphrase) const { - DCHECK(cached_pending_keys_.has_blob()); - DCHECK(!passphrase.empty()); - syncer::Nigori nigori; - nigori.InitByDerivation("localhost", "dummy", passphrase); - std::string plaintext; - bool result = nigori.Decrypt(cached_pending_keys_.blob(), &plaintext); - DVLOG_IF(1, result) << "Passphrase failed to decrypt pending keys."; - return result; -} - -void SyncBackendHostImpl::NotifyPassphraseRequired( - syncer::PassphraseRequiredReason reason, - sync_pb::EncryptedData pending_keys) { - if (!frontend_) - return; - - DCHECK(frontend_task_runner_->BelongsToCurrentThread()); - - // Update our cache of the cryptographer's pending keys. - cached_pending_keys_ = pending_keys; - - frontend_->OnPassphraseRequired(reason, pending_keys); -} - -void SyncBackendHostImpl::NotifyPassphraseAccepted() { - if (!frontend_) - return; - - DCHECK(frontend_task_runner_->BelongsToCurrentThread()); - - // Clear our cache of the cryptographer's pending keys. - cached_pending_keys_.clear_blob(); - frontend_->OnPassphraseAccepted(); -} - -void SyncBackendHostImpl::NotifyEncryptedTypesChanged( - syncer::ModelTypeSet encrypted_types, - bool encrypt_everything) { - if (!frontend_) - return; - - DCHECK(frontend_task_runner_->BelongsToCurrentThread()); - frontend_->OnEncryptedTypesChanged( - encrypted_types, encrypt_everything); -} - -void SyncBackendHostImpl::NotifyEncryptionComplete() { - if (!frontend_) - return; - - DCHECK(frontend_task_runner_->BelongsToCurrentThread()); - frontend_->OnEncryptionComplete(); -} - -void SyncBackendHostImpl::HandlePassphraseTypeChangedOnFrontendLoop( - syncer::PassphraseType type, - base::Time explicit_passphrase_time) { - DCHECK(frontend_task_runner_->BelongsToCurrentThread()); - DVLOG(1) << "Passphrase type changed to " - << syncer::PassphraseTypeToString(type); - cached_passphrase_type_ = type; - cached_explicit_passphrase_time_ = explicit_passphrase_time; -} - -void SyncBackendHostImpl::HandleLocalSetPassphraseEncryptionOnFrontendLoop( - const syncer::SyncEncryptionHandler::NigoriState& nigori_state) { - DCHECK(frontend_task_runner_->BelongsToCurrentThread()); - frontend_->OnLocalSetPassphraseEncryption(nigori_state); -} - -void SyncBackendHostImpl::HandleConnectionStatusChangeOnFrontendLoop( - syncer::ConnectionStatus status) { - if (!frontend_) - return; - - DCHECK(frontend_task_runner_->BelongsToCurrentThread()); - - DVLOG(1) << "Connection status changed: " - << syncer::ConnectionStatusToString(status); - frontend_->OnConnectionStatusChange(status); -} - -void SyncBackendHostImpl::HandleProtocolEventOnFrontendLoop( - syncer::ProtocolEvent* event) { - std::unique_ptr<syncer::ProtocolEvent> scoped_event(event); - if (!frontend_) - return; - frontend_->OnProtocolEvent(*scoped_event); -} - -void SyncBackendHostImpl::HandleDirectoryCommitCountersUpdatedOnFrontendLoop( - syncer::ModelType type, - const syncer::CommitCounters& counters) { - if (!frontend_) - return; - frontend_->OnDirectoryTypeCommitCounterUpdated(type, counters); -} - -void SyncBackendHostImpl::HandleDirectoryUpdateCountersUpdatedOnFrontendLoop( - syncer::ModelType type, - const syncer::UpdateCounters& counters) { - if (!frontend_) - return; - frontend_->OnDirectoryTypeUpdateCounterUpdated(type, counters); -} - -void SyncBackendHostImpl::HandleDirectoryStatusCountersUpdatedOnFrontendLoop( - syncer::ModelType type, - const syncer::StatusCounters& counters) { - if (!frontend_) - return; - frontend_->OnDirectoryTypeStatusCounterUpdated(type, counters); -} - -void SyncBackendHostImpl::UpdateInvalidationVersions( - const std::map<syncer::ModelType, int64_t>& invalidation_versions) { - sync_prefs_->UpdateInvalidationVersions(invalidation_versions); -} - -base::MessageLoop* SyncBackendHostImpl::GetSyncLoopForTesting() { - return registrar_->sync_thread()->message_loop(); -} - -void SyncBackendHostImpl::RefreshTypesForTest(syncer::ModelTypeSet types) { - DCHECK(ui_thread_->BelongsToCurrentThread()); - - registrar_->sync_thread()->task_runner()->PostTask( - FROM_HERE, - base::Bind(&SyncBackendHostCore::DoRefreshTypes, core_.get(), types)); -} - -void SyncBackendHostImpl::ClearServerData( - const syncer::SyncManager::ClearServerDataCallback& callback) { - DCHECK(ui_thread_->BelongsToCurrentThread()); - registrar_->sync_thread()->task_runner()->PostTask( - FROM_HERE, base::Bind(&SyncBackendHostCore::DoClearServerData, - core_.get(), callback)); -} - -void SyncBackendHostImpl::OnCookieJarChanged(bool account_mismatch, - bool empty_jar) { - DCHECK(ui_thread_->BelongsToCurrentThread()); - registrar_->sync_thread()->task_runner()->PostTask( - FROM_HERE, base::Bind(&SyncBackendHostCore::DoOnCookieJarChanged, - core_.get(), account_mismatch, empty_jar)); -} - -void SyncBackendHostImpl::ClearServerDataDoneOnFrontendLoop( - const syncer::SyncManager::ClearServerDataCallback& frontend_callback) { - DCHECK(ui_thread_->BelongsToCurrentThread()); - frontend_callback.Run(); -} - -} // namespace browser_sync - -#undef SDVLOG - -#undef SLOG
diff --git a/components/sync_driver/glue/sync_backend_host_impl.h b/components/sync_driver/glue/sync_backend_host_impl.h deleted file mode 100644 index cb89961..0000000 --- a/components/sync_driver/glue/sync_backend_host_impl.h +++ /dev/null
@@ -1,386 +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 COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_IMPL_H_ -#define COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_IMPL_H_ - -#include <stdint.h> - -#include <map> -#include <memory> -#include <string> -#include <vector> - -#include "base/callback.h" -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "base/single_thread_task_runner.h" -#include "base/threading/thread.h" -#include "components/invalidation/public/invalidation_handler.h" -#include "components/sync/base/extensions_activity.h" -#include "components/sync/base/model_type.h" -#include "components/sync/base/weak_handle.h" -#include "components/sync/core/configure_reason.h" -#include "components/sync/core/sync_manager.h" -#include "components/sync/protocol/encryption.pb.h" -#include "components/sync/protocol/sync_protocol_error.h" -#include "components/sync/sessions/sync_session_snapshot.h" -#include "components/sync/sessions/type_debug_info_observer.h" -#include "components/sync_driver/backend_data_type_configurer.h" -#include "components/sync_driver/glue/sync_backend_host.h" - -class GURL; - -namespace base { -class MessageLoop; -} - -namespace invalidation { -class InvalidationService; -} - -namespace syncer { -class SyncManagerFactory; -class UnrecoverableErrorHandler; -} - -namespace sync_driver { -class SyncClient; -class SyncPrefs; -} - -namespace browser_sync { - -class ChangeProcessor; -class SyncBackendHostCore; -class SyncBackendRegistrar; -struct DoInitializeOptions; - -// The only real implementation of the SyncBackendHost. See that interface's -// definition for documentation of public methods. -class SyncBackendHostImpl - : public SyncBackendHost, - public syncer::InvalidationHandler { - public: - typedef syncer::SyncStatus Status; - - // Create a SyncBackendHost with a reference to the |frontend| that - // it serves and communicates to via the SyncFrontend interface (on - // the same thread it used to call the constructor). Must outlive - // |sync_prefs|. - SyncBackendHostImpl( - const std::string& name, - sync_driver::SyncClient* sync_client, - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - invalidation::InvalidationService* invalidator, - const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs, - const base::FilePath& sync_folder); - ~SyncBackendHostImpl() override; - - // SyncBackendHost implementation. - void Initialize( - sync_driver::SyncFrontend* frontend, - std::unique_ptr<base::Thread> sync_thread, - const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, - const scoped_refptr<base::SingleThreadTaskRunner>& file_thread, - const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, - const GURL& service_url, - const std::string& sync_user_agent, - const syncer::SyncCredentials& credentials, - bool delete_sync_data_folder, - std::unique_ptr<syncer::SyncManagerFactory> sync_manager_factory, - const syncer::WeakHandle<syncer::UnrecoverableErrorHandler>& - unrecoverable_error_handler, - const base::Closure& report_unrecoverable_error_function, - const HttpPostProviderFactoryGetter& http_post_provider_factory_getter, - std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> - saved_nigori_state) override; - void TriggerRefresh(const syncer::ModelTypeSet& types) override; - void UpdateCredentials(const syncer::SyncCredentials& credentials) override; - void StartSyncingWithServer() override; - void SetEncryptionPassphrase(const std::string& passphrase, - bool is_explicit) override; - bool SetDecryptionPassphrase(const std::string& passphrase) override - WARN_UNUSED_RESULT; - void StopSyncingForShutdown() override; - std::unique_ptr<base::Thread> Shutdown( - syncer::ShutdownReason reason) override; - void UnregisterInvalidationIds() override; - syncer::ModelTypeSet ConfigureDataTypes( - syncer::ConfigureReason reason, - const DataTypeConfigStateMap& config_state_map, - const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& - ready_task, - const base::Callback<void()>& retry_callback) override; - void ActivateDirectoryDataType( - syncer::ModelType type, - syncer::ModelSafeGroup group, - sync_driver::ChangeProcessor* change_processor) override; - void DeactivateDirectoryDataType(syncer::ModelType type) override; - void ActivateNonBlockingDataType( - syncer::ModelType type, - std::unique_ptr<syncer_v2::ActivationContext>) override; - void DeactivateNonBlockingDataType(syncer::ModelType type) override; - void EnableEncryptEverything() override; - syncer::UserShare* GetUserShare() const override; - Status GetDetailedStatus() override; - syncer::sessions::SyncSessionSnapshot GetLastSessionSnapshot() const override; - bool HasUnsyncedItems() const override; - bool IsNigoriEnabled() const override; - syncer::PassphraseType GetPassphraseType() const override; - base::Time GetExplicitPassphraseTime() const override; - bool IsCryptographerReady( - const syncer::BaseTransaction* trans) const override; - void GetModelSafeRoutingInfo( - syncer::ModelSafeRoutingInfo* out) const override; - void FlushDirectory() const override; - void RequestBufferedProtocolEventsAndEnableForwarding() override; - void DisableProtocolEventForwarding() override; - void EnableDirectoryTypeDebugInfoForwarding() override; - void DisableDirectoryTypeDebugInfoForwarding() override; - void GetAllNodesForTypes( - syncer::ModelTypeSet types, - base::Callback<void(const std::vector<syncer::ModelType>&, - ScopedVector<base::ListValue>)> type) override; - base::MessageLoop* GetSyncLoopForTesting() override; - void RefreshTypesForTest(syncer::ModelTypeSet types) override; - void ClearServerData( - const syncer::SyncManager::ClearServerDataCallback& callback) override; - void OnCookieJarChanged(bool account_mismatch, bool empty_jar) override; - - // InvalidationHandler implementation. - void OnInvalidatorStateChange(syncer::InvalidatorState state) override; - void OnIncomingInvalidation( - const syncer::ObjectIdInvalidationMap& invalidation_map) override; - std::string GetOwnerName() const override; - - protected: - // The types and functions below are protected so that test - // subclasses can use them. - - // Allows tests to perform alternate core initialization work. - virtual void InitCore(std::unique_ptr<DoInitializeOptions> options); - - // Request the syncer to reconfigure with the specfied params. - // Virtual for testing. - virtual void RequestConfigureSyncer( - syncer::ConfigureReason reason, - syncer::ModelTypeSet to_download, - syncer::ModelTypeSet to_purge, - syncer::ModelTypeSet to_journal, - syncer::ModelTypeSet to_unapply, - syncer::ModelTypeSet to_ignore, - const syncer::ModelSafeRoutingInfo& routing_info, - const base::Callback<void(syncer::ModelTypeSet, - syncer::ModelTypeSet)>& ready_task, - const base::Closure& retry_callback); - - // Called when the syncer has finished performing a configuration. - void FinishConfigureDataTypesOnFrontendLoop( - const syncer::ModelTypeSet enabled_types, - const syncer::ModelTypeSet succeeded_configuration_types, - const syncer::ModelTypeSet failed_configuration_types, - const base::Callback<void(syncer::ModelTypeSet, - syncer::ModelTypeSet)>& ready_task); - - // Reports backend initialization success. Includes some objects from sync - // manager initialization to be passed back to the UI thread. - // - // |model_type_connector| is our ModelTypeConnector, which is owned because in - // production it is a proxy object to the real ModelTypeConnector. - virtual void HandleInitializationSuccessOnFrontendLoop( - const syncer::WeakHandle<syncer::JsBackend> js_backend, - const syncer::WeakHandle<syncer::DataTypeDebugInfoListener> - debug_info_listener, - std::unique_ptr<syncer_v2::ModelTypeConnector> model_type_connector, - const std::string& cache_guid); - - // Forwards a ProtocolEvent to the frontend. Will not be called unless a - // call to SetForwardProtocolEvents() explicitly requested that we start - // forwarding these events. - void HandleProtocolEventOnFrontendLoop(syncer::ProtocolEvent* event); - - // Forwards a directory commit counter update to the frontend loop. Will not - // be called unless a call to EnableDirectoryTypeDebugInfoForwarding() - // explicitly requested that we start forwarding these events. - void HandleDirectoryCommitCountersUpdatedOnFrontendLoop( - syncer::ModelType type, - const syncer::CommitCounters& counters); - - // Forwards a directory update counter update to the frontend loop. Will not - // be called unless a call to EnableDirectoryTypeDebugInfoForwarding() - // explicitly requested that we start forwarding these events. - void HandleDirectoryUpdateCountersUpdatedOnFrontendLoop( - syncer::ModelType type, - const syncer::UpdateCounters& counters); - - // Forwards a directory status counter update to the frontend loop. Will not - // be called unless a call to EnableDirectoryTypeDebugInfoForwarding() - // explicitly requested that we start forwarding these events. - void HandleDirectoryStatusCountersUpdatedOnFrontendLoop( - syncer::ModelType type, - const syncer::StatusCounters& counters); - - // Overwrites the kSyncInvalidationVersions preference with the most recent - // set of invalidation versions for each type. - void UpdateInvalidationVersions( - const std::map<syncer::ModelType, int64_t>& invalidation_versions); - - sync_driver::SyncFrontend* frontend() { - return frontend_; - } - - private: - friend class SyncBackendHostCore; - - // Checks if we have received a notice to turn on experimental datatypes - // (via the nigori node) and informs the frontend if that is the case. - // Note: it is illegal to call this before the backend is initialized. - void AddExperimentalTypes(); - - // Handles backend initialization failure. - void HandleInitializationFailureOnFrontendLoop(); - - // Called from Core::OnSyncCycleCompleted to handle updating frontend - // thread components. - void HandleSyncCycleCompletedOnFrontendLoop( - const syncer::sessions::SyncSessionSnapshot& snapshot); - - // Called when the syncer failed to perform a configuration and will - // eventually retry. FinishingConfigurationOnFrontendLoop(..) will be called - // on successful completion. - void RetryConfigurationOnFrontendLoop(const base::Closure& retry_callback); - - // Helpers to persist a token that can be used to bootstrap sync encryption - // across browser restart to avoid requiring the user to re-enter their - // passphrase. |token| must be valid UTF-8 as we use the PrefService for - // storage. - void PersistEncryptionBootstrapToken( - const std::string& token, - syncer::BootstrapTokenType token_type); - - // For convenience, checks if initialization state is INITIALIZED. - bool initialized() const { return initialized_; } - - // Let the front end handle the actionable error event. - void HandleActionableErrorEventOnFrontendLoop( - const syncer::SyncProtocolError& sync_error); - - // Handle a migration request. - void HandleMigrationRequestedOnFrontendLoop(const syncer::ModelTypeSet types); - - // Checks if |passphrase| can be used to decrypt the cryptographer's pending - // keys that were cached during NotifyPassphraseRequired. Returns true if - // decryption was successful. Returns false otherwise. Must be called with a - // non-empty pending keys cache. - bool CheckPassphraseAgainstCachedPendingKeys( - const std::string& passphrase) const; - - // Invoked when a passphrase is required to decrypt a set of Nigori keys, - // or for encrypting. |reason| denotes why the passphrase was required. - // |pending_keys| is a copy of the cryptographer's pending keys, that are - // cached by the frontend. If there are no pending keys, or if the passphrase - // required reason is REASON_ENCRYPTION, an empty EncryptedData object is - // passed. - void NotifyPassphraseRequired(syncer::PassphraseRequiredReason reason, - sync_pb::EncryptedData pending_keys); - - // Invoked when the passphrase provided by the user has been accepted. - void NotifyPassphraseAccepted(); - - // Invoked when the set of encrypted types or the encrypt - // everything flag changes. - void NotifyEncryptedTypesChanged( - syncer::ModelTypeSet encrypted_types, - bool encrypt_everything); - - // Invoked when sync finishes encrypting new datatypes. - void NotifyEncryptionComplete(); - - // Invoked when the passphrase state has changed. Caches the passphrase state - // for later use on the UI thread. - // If |type| is FROZEN_IMPLICIT_PASSPHRASE or CUSTOM_PASSPHRASE, - // |explicit_passphrase_time| is the time at which that passphrase was set - // (if available). - void HandlePassphraseTypeChangedOnFrontendLoop( - syncer::PassphraseType type, - base::Time explicit_passphrase_time); - - void HandleLocalSetPassphraseEncryptionOnFrontendLoop( - const syncer::SyncEncryptionHandler::NigoriState& nigori_state); - - // Dispatched to from OnConnectionStatusChange to handle updating - // frontend UI components. - void HandleConnectionStatusChangeOnFrontendLoop( - syncer::ConnectionStatus status); - - void ClearServerDataDoneOnFrontendLoop( - const syncer::SyncManager::ClearServerDataCallback& frontend_callback); - - // A reference to the TaskRUnner used to construct |this|, so we know how to - // safely talk back to the SyncFrontend. - scoped_refptr<base::SingleThreadTaskRunner> const frontend_task_runner_; - - sync_driver::SyncClient* const sync_client_; - - // The UI thread's task runner. - const scoped_refptr<base::SingleThreadTaskRunner> ui_thread_; - - // Name used for debugging (set from profile_->GetDebugName()). - const std::string name_; - - // Our core, which communicates directly to the syncapi. Use refptr instead - // of WeakHandle because |core_| is created on UI loop but released on - // sync loop. - scoped_refptr<SyncBackendHostCore> core_; - - // A handle referencing the main interface for non-blocking sync types. This - // object is owned because in production code it is a proxy object. - std::unique_ptr<syncer_v2::ModelTypeConnector> model_type_connector_; - - bool initialized_; - - const base::WeakPtr<sync_driver::SyncPrefs> sync_prefs_; - - std::unique_ptr<SyncBackendRegistrar> registrar_; - - // The frontend which we serve (and are owned by). - sync_driver::SyncFrontend* frontend_; - - // We cache the cryptographer's pending keys whenever NotifyPassphraseRequired - // is called. This way, before the UI calls SetDecryptionPassphrase on the - // syncer, it can avoid the overhead of an asynchronous decryption call and - // give the user immediate feedback about the passphrase entered by first - // trying to decrypt the cached pending keys on the UI thread. Note that - // SetDecryptionPassphrase can still fail after the cached pending keys are - // successfully decrypted if the pending keys have changed since the time they - // were cached. - sync_pb::EncryptedData cached_pending_keys_; - - // The state of the passphrase required to decrypt the bag of encryption keys - // in the nigori node. Updated whenever a new nigori node arrives or the user - // manually changes their passphrase state. Cached so we can synchronously - // check it from the UI thread. - syncer::PassphraseType cached_passphrase_type_; - - // If an explicit passphrase is in use, the time at which the passphrase was - // first set (if available). - base::Time cached_explicit_passphrase_time_; - - // UI-thread cache of the last SyncSessionSnapshot received from syncapi. - syncer::sessions::SyncSessionSnapshot last_snapshot_; - - invalidation::InvalidationService* invalidator_; - bool invalidation_handler_registered_; - - base::WeakPtrFactory<SyncBackendHostImpl> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(SyncBackendHostImpl); -}; - -} // namespace browser_sync - -#endif // COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_IMPL_H_
diff --git a/components/sync_driver/glue/sync_backend_host_impl_unittest.cc b/components/sync_driver/glue/sync_backend_host_impl_unittest.cc deleted file mode 100644 index 106666bc..0000000 --- a/components/sync_driver/glue/sync_backend_host_impl_unittest.cc +++ /dev/null
@@ -1,862 +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 "components/sync_driver/glue/sync_backend_host_impl.h" - -#include <stdint.h> - -#include <cstddef> -#include <map> -#include <memory> -#include <utility> - -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "base/location.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/synchronization/waitable_event.h" -#include "base/test/test_timeouts.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/time/time.h" -#include "components/invalidation/impl/invalidator_storage.h" -#include "components/invalidation/impl/profile_invalidation_provider.h" -#include "components/invalidation/public/invalidator_state.h" -#include "components/invalidation/public/object_id_invalidation_map.h" -#include "components/sync/base/experiments.h" -#include "components/sync/base/model_type.h" -#include "components/sync/base/test_unrecoverable_error_handler.h" -#include "components/sync/core/http_bridge_network_resources.h" -#include "components/sync/core/network_resources.h" -#include "components/sync/core/sync_manager_factory.h" -#include "components/sync/core/test/fake_sync_manager.h" -#include "components/sync/engine/model_safe_worker.h" -#include "components/sync/engine/passive_model_worker.h" -#include "components/sync/protocol/encryption.pb.h" -#include "components/sync/protocol/sync_protocol_error.h" -#include "components/sync/sessions/commit_counters.h" -#include "components/sync/sessions/status_counters.h" -#include "components/sync/sessions/update_counters.h" -#include "components/sync/test/callback_counter.h" -#include "components/sync_driver/device_info.h" -#include "components/sync_driver/fake_sync_client.h" -#include "components/sync_driver/sync_frontend.h" -#include "components/sync_driver/sync_prefs.h" -#include "components/syncable_prefs/pref_service_syncable.h" -#include "components/syncable_prefs/testing_pref_service_syncable.h" -#include "google/cacheinvalidation/include/types.h" -#include "google_apis/gaia/gaia_constants.h" -#include "net/url_request/test_url_fetcher_factory.h" -#include "net/url_request/url_request_context_getter.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -using syncer::FakeSyncManager; -using syncer::SyncManager; -using ::testing::InvokeWithoutArgs; -using ::testing::StrictMock; -using ::testing::_; - -namespace browser_sync { - -namespace { - -static const base::FilePath::CharType kTestSyncDir[] = - FILE_PATH_LITERAL("sync-test"); - -ACTION_P(Signal, event) { - event->Signal(); -} - -void EmptyNetworkTimeUpdate(const base::Time&, - const base::TimeDelta&, - const base::TimeDelta&) {} - -void QuitMessageLoop() { - base::MessageLoop::current()->QuitWhenIdle(); -} - -class MockSyncFrontend : public sync_driver::SyncFrontend { - public: - virtual ~MockSyncFrontend() {} - - MOCK_METHOD4( - OnBackendInitialized, - void(const syncer::WeakHandle<syncer::JsBackend>&, - const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&, - const std::string&, - bool)); - MOCK_METHOD0(OnSyncCycleCompleted, void()); - MOCK_METHOD1(OnConnectionStatusChange, - void(syncer::ConnectionStatus status)); - MOCK_METHOD0(OnClearServerDataSucceeded, void()); - MOCK_METHOD0(OnClearServerDataFailed, void()); - MOCK_METHOD2(OnPassphraseRequired, - void(syncer::PassphraseRequiredReason, - const sync_pb::EncryptedData&)); - MOCK_METHOD0(OnPassphraseAccepted, void()); - MOCK_METHOD2(OnEncryptedTypesChanged, - void(syncer::ModelTypeSet, bool)); - MOCK_METHOD0(OnEncryptionComplete, void()); - MOCK_METHOD1(OnMigrationNeededForTypes, void(syncer::ModelTypeSet)); - MOCK_METHOD1(OnProtocolEvent, void(const syncer::ProtocolEvent&)); - MOCK_METHOD2(OnDirectoryTypeCommitCounterUpdated, - void(syncer::ModelType, const syncer::CommitCounters&)); - MOCK_METHOD2(OnDirectoryTypeUpdateCounterUpdated, - void(syncer::ModelType, const syncer::UpdateCounters&)); - MOCK_METHOD2(OnDirectoryTypeStatusCounterUpdated, - void(syncer::ModelType, const syncer::StatusCounters&)); - MOCK_METHOD1(OnExperimentsChanged, - void(const syncer::Experiments&)); - MOCK_METHOD1(OnActionableError, - void(const syncer::SyncProtocolError& sync_error)); - MOCK_METHOD0(OnSyncConfigureRetry, void()); - MOCK_METHOD1( - OnLocalSetPassphraseEncryption, - void(const syncer::SyncEncryptionHandler::NigoriState& nigori_state)); -}; - -class FakeSyncManagerFactory : public syncer::SyncManagerFactory { - public: - explicit FakeSyncManagerFactory(FakeSyncManager** fake_manager) - : fake_manager_(fake_manager) { - *fake_manager_ = NULL; - } - ~FakeSyncManagerFactory() override {} - - // SyncManagerFactory implementation. Called on the sync thread. - std::unique_ptr<SyncManager> CreateSyncManager( - const std::string& /* name */) override { - *fake_manager_ = new FakeSyncManager(initial_sync_ended_types_, - progress_marker_types_, - configure_fail_types_); - return std::unique_ptr<SyncManager>(*fake_manager_); - } - - void set_initial_sync_ended_types(syncer::ModelTypeSet types) { - initial_sync_ended_types_ = types; - } - - void set_progress_marker_types(syncer::ModelTypeSet types) { - progress_marker_types_ = types; - } - - void set_configure_fail_types(syncer::ModelTypeSet types) { - configure_fail_types_ = types; - } - - private: - syncer::ModelTypeSet initial_sync_ended_types_; - syncer::ModelTypeSet progress_marker_types_; - syncer::ModelTypeSet configure_fail_types_; - FakeSyncManager** fake_manager_; -}; - -class BackendSyncClient : public sync_driver::FakeSyncClient { - public: - scoped_refptr<syncer::ModelSafeWorker> CreateModelWorkerForGroup( - syncer::ModelSafeGroup group, - syncer::WorkerLoopDestructionObserver* observer) override { - switch (group) { - case syncer::GROUP_PASSIVE: - return new syncer::PassiveModelWorker(observer); - default: - return nullptr; - } - } -}; - -class SyncBackendHostTest : public testing::Test { - protected: - SyncBackendHostTest() - : fake_manager_(NULL) {} - - ~SyncBackendHostTest() override {} - - void SetUp() override { - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - - sync_driver::SyncPrefs::RegisterProfilePrefs(pref_service_.registry()); - - sync_prefs_.reset(new sync_driver::SyncPrefs(&pref_service_)); - backend_.reset(new SyncBackendHostImpl( - "dummyDebugName", &sync_client_, - base::ThreadTaskRunnerHandle::Get(), - nullptr, - sync_prefs_->AsWeakPtr(), - temp_dir_.path().Append(base::FilePath(kTestSyncDir)))); - credentials_.account_id = "user@example.com"; - credentials_.email = "user@example.com"; - credentials_.sync_token = "sync_token"; - credentials_.scope_set.insert(GaiaConstants::kChromeSyncOAuth2Scope); - - fake_manager_factory_.reset(new FakeSyncManagerFactory(&fake_manager_)); - - // These types are always implicitly enabled. - enabled_types_.PutAll(syncer::ControlTypes()); - - // NOTE: We can't include Passwords or Typed URLs due to the Sync Backend - // Registrar removing them if it can't find their model workers. - enabled_types_.Put(syncer::BOOKMARKS); - enabled_types_.Put(syncer::PREFERENCES); - enabled_types_.Put(syncer::SESSIONS); - enabled_types_.Put(syncer::SEARCH_ENGINES); - enabled_types_.Put(syncer::AUTOFILL); - - network_resources_.reset(new syncer::HttpBridgeNetworkResources()); - } - - void TearDown() override { - if (backend_) { - backend_->StopSyncingForShutdown(); - backend_->Shutdown(syncer::STOP_SYNC); - } - backend_.reset(); - sync_prefs_.reset(); - // Pump messages posted by the sync thread. - base::RunLoop().RunUntilIdle(); - } - - // Synchronously initializes the backend. - void InitializeBackend(bool expect_success) { - EXPECT_CALL(mock_frontend_, OnBackendInitialized(_, _, _, expect_success)). - WillOnce(InvokeWithoutArgs(QuitMessageLoop)); - SyncBackendHost::HttpPostProviderFactoryGetter - http_post_provider_factory_getter = - base::Bind(&syncer::NetworkResources::GetHttpPostProviderFactory, - base::Unretained(network_resources_.get()), - nullptr, - base::Bind(&EmptyNetworkTimeUpdate)); - backend_->Initialize( - &mock_frontend_, std::unique_ptr<base::Thread>(), - base::ThreadTaskRunnerHandle::Get(), - base::ThreadTaskRunnerHandle::Get(), - syncer::WeakHandle<syncer::JsEventHandler>(), GURL(std::string()), - std::string(), credentials_, true, std::move(fake_manager_factory_), - MakeWeakHandle(test_unrecoverable_error_handler_.GetWeakPtr()), - base::Closure(), http_post_provider_factory_getter, - std::move(saved_nigori_state_)); - base::RunLoop run_loop; - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, - run_loop.QuitClosure(), - TestTimeouts::action_timeout()); - run_loop.Run(); - // |fake_manager_factory_|'s fake_manager() is set on the sync - // thread, but we can rely on the message loop barriers to - // guarantee that we see the updated value. - DCHECK(fake_manager_); - } - - // Synchronously configures the backend's datatypes. - syncer::ModelTypeSet ConfigureDataTypes( - syncer::ModelTypeSet types_to_add, - syncer::ModelTypeSet types_to_remove, - syncer::ModelTypeSet types_to_unapply) { - sync_driver::BackendDataTypeConfigurer::DataTypeConfigStateMap - config_state_map; - sync_driver::BackendDataTypeConfigurer::SetDataTypesState( - sync_driver::BackendDataTypeConfigurer::CONFIGURE_ACTIVE, - types_to_add, - &config_state_map); - sync_driver::BackendDataTypeConfigurer::SetDataTypesState( - sync_driver::BackendDataTypeConfigurer::DISABLED, - types_to_remove, &config_state_map); - sync_driver::BackendDataTypeConfigurer::SetDataTypesState( - sync_driver::BackendDataTypeConfigurer::UNREADY, - types_to_unapply, &config_state_map); - - types_to_add.PutAll(syncer::ControlTypes()); - syncer::ModelTypeSet ready_types = backend_->ConfigureDataTypes( - syncer::CONFIGURE_REASON_RECONFIGURATION, config_state_map, - base::Bind(&SyncBackendHostTest::DownloadReady, base::Unretained(this)), - base::Bind(&SyncBackendHostTest::OnDownloadRetry, - base::Unretained(this))); - base::RunLoop run_loop; - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(FROM_HERE, - run_loop.QuitClosure(), - TestTimeouts::action_timeout()); - run_loop.Run(); - return ready_types; - } - - protected: - void DownloadReady(syncer::ModelTypeSet succeeded_types, - syncer::ModelTypeSet failed_types) { - base::MessageLoop::current()->QuitWhenIdle(); - } - - void OnDownloadRetry() { - NOTIMPLEMENTED(); - } - - base::MessageLoop message_loop_; - base::ScopedTempDir temp_dir_; - syncable_prefs::TestingPrefServiceSyncable pref_service_; - StrictMock<MockSyncFrontend> mock_frontend_; - syncer::SyncCredentials credentials_; - BackendSyncClient sync_client_; - syncer::TestUnrecoverableErrorHandler test_unrecoverable_error_handler_; - std::unique_ptr<sync_driver::SyncPrefs> sync_prefs_; - std::unique_ptr<SyncBackendHostImpl> backend_; - std::unique_ptr<FakeSyncManagerFactory> fake_manager_factory_; - FakeSyncManager* fake_manager_; - syncer::ModelTypeSet enabled_types_; - std::unique_ptr<syncer::NetworkResources> network_resources_; - std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> - saved_nigori_state_; -}; - -// Test basic initialization with no initial types (first time initialization). -// Only the nigori should be configured. -TEST_F(SyncBackendHostTest, InitShutdown) { - InitializeBackend(true); - EXPECT_EQ(syncer::ControlTypes(), - fake_manager_->GetAndResetDownloadedTypes()); - EXPECT_EQ(syncer::ControlTypes(), fake_manager_->InitialSyncEndedTypes()); - EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( - syncer::ControlTypes()).Empty()); -} - -// Test first time sync scenario. All types should be properly configured. -TEST_F(SyncBackendHostTest, FirstTimeSync) { - InitializeBackend(true); - EXPECT_EQ(syncer::ControlTypes(), - fake_manager_->GetAndResetDownloadedTypes()); - EXPECT_EQ(syncer::ControlTypes(), fake_manager_->InitialSyncEndedTypes()); - EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( - syncer::ControlTypes()).Empty()); - - syncer::ModelTypeSet ready_types = ConfigureDataTypes( - enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), - syncer::ModelTypeSet()); - // Nigori is always downloaded so won't be ready. - EXPECT_EQ(syncer::Difference(syncer::ControlTypes(), - syncer::ModelTypeSet(syncer::NIGORI)), - ready_types); - EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll( - Difference(enabled_types_, syncer::ControlTypes()))); - EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); - EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( - enabled_types_).Empty()); -} - -// Test the restart after setting up sync scenario. No enabled types should be -// downloaded or cleaned. -TEST_F(SyncBackendHostTest, Restart) { - sync_prefs_->SetFirstSetupComplete(); - syncer::ModelTypeSet all_but_nigori = enabled_types_; - fake_manager_factory_->set_progress_marker_types(enabled_types_); - fake_manager_factory_->set_initial_sync_ended_types(enabled_types_); - InitializeBackend(true); - EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty()); - EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), - enabled_types_).Empty()); - EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( - enabled_types_).Empty()); - - syncer::ModelTypeSet ready_types = ConfigureDataTypes( - enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), - syncer::ModelTypeSet()); - EXPECT_EQ(enabled_types_, ready_types); - EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty()); - EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), - enabled_types_).Empty()); - EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); - EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( - enabled_types_).Empty()); -} - -// Test a sync restart scenario where some types had never finished configuring. -// The partial types should be purged, then reconfigured properly. -TEST_F(SyncBackendHostTest, PartialTypes) { - sync_prefs_->SetFirstSetupComplete(); - // Set sync manager behavior before passing it down. All types have progress - // markers, but nigori and bookmarks are missing initial sync ended. - syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS); - syncer::ModelTypeSet full_types = - Difference(enabled_types_, partial_types); - fake_manager_factory_->set_progress_marker_types(enabled_types_); - fake_manager_factory_->set_initial_sync_ended_types(full_types); - - // Bringing up the backend should purge all partial types, then proceed to - // download the Nigori. - InitializeBackend(true); - EXPECT_EQ(syncer::ModelTypeSet(syncer::NIGORI), - fake_manager_->GetAndResetDownloadedTypes()); - EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types)); - EXPECT_EQ(Union(full_types, syncer::ModelTypeSet(syncer::NIGORI)), - fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ( - Difference(partial_types, syncer::ModelTypeSet(syncer::NIGORI)), - fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_)); - - // Now do the actual configuration, which should download and apply bookmarks. - syncer::ModelTypeSet ready_types = ConfigureDataTypes( - enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), - syncer::ModelTypeSet()); - EXPECT_EQ(full_types, ready_types); - EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), - enabled_types_).Empty()); - EXPECT_EQ(partial_types, fake_manager_->GetAndResetDownloadedTypes()); - EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); - EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( - enabled_types_).Empty()); -} - -// Test the behavior when we lose the sync db. Although we already have types -// enabled, we should re-download all of them because we lost their data. -TEST_F(SyncBackendHostTest, LostDB) { - sync_prefs_->SetFirstSetupComplete(); - // Initialization should fetch the Nigori node. Everything else should be - // left untouched. - InitializeBackend(true); - EXPECT_EQ(syncer::ModelTypeSet(syncer::ControlTypes()), - fake_manager_->GetAndResetDownloadedTypes()); - EXPECT_EQ(syncer::ModelTypeSet(syncer::ControlTypes()), - fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ( - Difference(enabled_types_, syncer::ControlTypes()), - fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_)); - - // The database was empty, so any cleaning is entirely optional. We want to - // reset this value before running the next part of the test, though. - fake_manager_->GetAndResetCleanedTypes(); - - // The actual configuration should redownload and apply all the enabled types. - syncer::ModelTypeSet ready_types = ConfigureDataTypes( - enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), - syncer::ModelTypeSet()); - // Nigori is always downloaded so won't be ready. - EXPECT_EQ(syncer::Difference(syncer::ControlTypes(), - syncer::ModelTypeSet(syncer::NIGORI)), - ready_types); - EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().HasAll( - Difference(enabled_types_, syncer::ControlTypes()))); - EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), - enabled_types_).Empty()); - EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); - EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( - enabled_types_).Empty()); -} - -TEST_F(SyncBackendHostTest, DisableTypes) { - // Simulate first time sync. - InitializeBackend(true); - fake_manager_->GetAndResetCleanedTypes(); - syncer::ModelTypeSet ready_types = ConfigureDataTypes( - enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), - syncer::ModelTypeSet()); - // Nigori is always downloaded so won't be ready. - EXPECT_EQ(syncer::Difference(syncer::ControlTypes(), - syncer::ModelTypeSet(syncer::NIGORI)), - ready_types); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetDownloadedTypes()); - EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), - enabled_types_).Empty()); - EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( - enabled_types_).Empty()); - - // Then disable two datatypes. - syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS, - syncer::SEARCH_ENGINES); - syncer::ModelTypeSet old_types = enabled_types_; - enabled_types_.RemoveAll(disabled_types); - ready_types = ConfigureDataTypes( - enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), - syncer::ModelTypeSet()); - - // Only those datatypes disabled should be cleaned. Nothing should be - // downloaded. - EXPECT_EQ(enabled_types_, ready_types); - EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty()); - EXPECT_EQ(disabled_types, - Intersection(fake_manager_->GetAndResetCleanedTypes(), old_types)); - EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); - EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( - enabled_types_).Empty()); -} - -TEST_F(SyncBackendHostTest, AddTypes) { - // Simulate first time sync. - InitializeBackend(true); - fake_manager_->GetAndResetCleanedTypes(); - syncer::ModelTypeSet ready_types = ConfigureDataTypes( - enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), - syncer::ModelTypeSet()); - // Nigori is always downloaded so won't be ready. - EXPECT_EQ(syncer::Difference(syncer::ControlTypes(), - syncer::ModelTypeSet(syncer::NIGORI)), - ready_types); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetDownloadedTypes()); - EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), - enabled_types_).Empty()); - EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( - enabled_types_).Empty()); - - // Then add two datatypes. - syncer::ModelTypeSet new_types(syncer::EXTENSIONS, - syncer::APPS); - enabled_types_.PutAll(new_types); - ready_types = ConfigureDataTypes( - enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), - syncer::ModelTypeSet()); - - // Only those datatypes added should be downloaded (plus nigori). Nothing - // should be cleaned aside from the disabled types. - new_types.Put(syncer::NIGORI); - EXPECT_EQ(syncer::Difference(enabled_types_, new_types), ready_types); - EXPECT_EQ(new_types, fake_manager_->GetAndResetDownloadedTypes()); - EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), - enabled_types_).Empty()); - EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); - EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( - enabled_types_).Empty()); -} - -// And and disable in the same configuration. -TEST_F(SyncBackendHostTest, AddDisableTypes) { - // Simulate first time sync. - InitializeBackend(true); - fake_manager_->GetAndResetCleanedTypes(); - syncer::ModelTypeSet ready_types = ConfigureDataTypes( - enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), - syncer::ModelTypeSet()); - // Nigori is always downloaded so won't be ready. - EXPECT_EQ(syncer::Difference(syncer::ControlTypes(), - syncer::ModelTypeSet(syncer::NIGORI)), - ready_types); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetDownloadedTypes()); - EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), - enabled_types_).Empty()); - EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( - enabled_types_).Empty()); - - // Then add two datatypes. - syncer::ModelTypeSet old_types = enabled_types_; - syncer::ModelTypeSet disabled_types(syncer::BOOKMARKS, - syncer::SEARCH_ENGINES); - syncer::ModelTypeSet new_types(syncer::EXTENSIONS, - syncer::APPS); - enabled_types_.PutAll(new_types); - enabled_types_.RemoveAll(disabled_types); - ready_types = ConfigureDataTypes( - enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), - syncer::ModelTypeSet()); - - // Only those datatypes added should be downloaded (plus nigori). Nothing - // should be cleaned aside from the disabled types. - new_types.Put(syncer::NIGORI); - EXPECT_EQ(syncer::Difference(enabled_types_, new_types), ready_types); - EXPECT_EQ(new_types, fake_manager_->GetAndResetDownloadedTypes()); - EXPECT_EQ(disabled_types, - Intersection(fake_manager_->GetAndResetCleanedTypes(), old_types)); - EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); - EXPECT_EQ(disabled_types, - fake_manager_->GetTypesWithEmptyProgressMarkerToken(old_types)); -} - -// Test restarting the browser to newly supported datatypes. The new datatypes -// should be downloaded on the configuration after backend initialization. -TEST_F(SyncBackendHostTest, NewlySupportedTypes) { - sync_prefs_->SetFirstSetupComplete(); - // Set sync manager behavior before passing it down. All types have progress - // markers and initial sync ended except the new types. - syncer::ModelTypeSet old_types = enabled_types_; - fake_manager_factory_->set_progress_marker_types(old_types); - fake_manager_factory_->set_initial_sync_ended_types(old_types); - syncer::ModelTypeSet new_types(syncer::APP_SETTINGS, - syncer::EXTENSION_SETTINGS); - enabled_types_.PutAll(new_types); - - // Does nothing. - InitializeBackend(true); - EXPECT_TRUE(fake_manager_->GetAndResetDownloadedTypes().Empty()); - EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), - old_types).Empty()); - EXPECT_EQ(old_types, fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ(new_types, fake_manager_->GetTypesWithEmptyProgressMarkerToken( - enabled_types_)); - - // Downloads and applies the new types (plus nigori). - syncer::ModelTypeSet ready_types = ConfigureDataTypes( - enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), - syncer::ModelTypeSet()); - - new_types.Put(syncer::NIGORI); - EXPECT_EQ(syncer::Difference(old_types, syncer::ModelTypeSet(syncer::NIGORI)), - ready_types); - EXPECT_EQ(new_types, fake_manager_->GetAndResetDownloadedTypes()); - EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), - enabled_types_).Empty()); - EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); - EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( - enabled_types_).Empty()); -} - -// Test the newly supported types scenario, but with the presence of partial -// types as well. Both partial and newly supported types should be downloaded -// the configuration. -TEST_F(SyncBackendHostTest, NewlySupportedTypesWithPartialTypes) { - sync_prefs_->SetFirstSetupComplete(); - // Set sync manager behavior before passing it down. All types have progress - // markers and initial sync ended except the new types. - syncer::ModelTypeSet old_types = enabled_types_; - syncer::ModelTypeSet partial_types(syncer::NIGORI, syncer::BOOKMARKS); - syncer::ModelTypeSet full_types = - Difference(enabled_types_, partial_types); - fake_manager_factory_->set_progress_marker_types(old_types); - fake_manager_factory_->set_initial_sync_ended_types(full_types); - syncer::ModelTypeSet new_types(syncer::APP_SETTINGS, - syncer::EXTENSION_SETTINGS); - enabled_types_.PutAll(new_types); - - // Purge the partial types. The nigori will be among the purged types, but - // the syncer will re-download it by the time the initialization is complete. - InitializeBackend(true); - EXPECT_EQ(syncer::ModelTypeSet(syncer::NIGORI), - fake_manager_->GetAndResetDownloadedTypes()); - EXPECT_TRUE(fake_manager_->GetAndResetCleanedTypes().HasAll(partial_types)); - EXPECT_EQ(syncer::Union(full_types, syncer::ModelTypeSet(syncer::NIGORI)), - fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ( - Union(new_types, - Difference(partial_types, syncer::ModelTypeSet(syncer::NIGORI))), - fake_manager_->GetTypesWithEmptyProgressMarkerToken(enabled_types_)); - - // Downloads and applies the new types and partial types (which includes - // nigori anyways). - syncer::ModelTypeSet ready_types = ConfigureDataTypes( - enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), - syncer::ModelTypeSet()); - EXPECT_EQ(full_types, ready_types); - EXPECT_EQ(Union(new_types, partial_types), - fake_manager_->GetAndResetDownloadedTypes()); - EXPECT_TRUE(Intersection(fake_manager_->GetAndResetCleanedTypes(), - enabled_types_).Empty()); - EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_EQ(enabled_types_, fake_manager_->GetAndResetEnabledTypes()); - EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( - enabled_types_).Empty()); -} - -// Verify that downloading control types only downloads those types that do -// not have initial sync ended set. -TEST_F(SyncBackendHostTest, DownloadControlTypes) { - sync_prefs_->SetFirstSetupComplete(); - // Set sync manager behavior before passing it down. Experiments and device - // info are new types without progress markers or initial sync ended, while - // all other types have been fully downloaded and applied. - syncer::ModelTypeSet new_types(syncer::EXPERIMENTS, syncer::NIGORI); - syncer::ModelTypeSet old_types = - Difference(enabled_types_, new_types); - fake_manager_factory_->set_progress_marker_types(old_types); - fake_manager_factory_->set_initial_sync_ended_types(old_types); - - // Bringing up the backend should download the new types without downloading - // any old types. - InitializeBackend(true); - EXPECT_EQ(new_types, fake_manager_->GetAndResetDownloadedTypes()); - EXPECT_EQ(Difference(syncer::ModelTypeSet::All(), enabled_types_), - fake_manager_->GetAndResetCleanedTypes()); - EXPECT_EQ(enabled_types_, fake_manager_->InitialSyncEndedTypes()); - EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( - enabled_types_).Empty()); -} - -// Fail to download control types. It's believed that there is a server bug -// which can allow this to happen (crbug.com/164288). The sync backend host -// should detect this condition and fail to initialize the backend. -// -// The failure is "silent" in the sense that the GetUpdates request appears to -// be successful, but it returned no results. This means that the usual -// download retry logic will not be invoked. -TEST_F(SyncBackendHostTest, SilentlyFailToDownloadControlTypes) { - fake_manager_factory_->set_configure_fail_types(syncer::ModelTypeSet::All()); - InitializeBackend(false); -} - -// Test that local refresh requests are delivered to sync. -TEST_F(SyncBackendHostTest, ForwardLocalRefreshRequest) { - InitializeBackend(true); - - syncer::ModelTypeSet set1 = syncer::ModelTypeSet::All(); - backend_->TriggerRefresh(set1); - fake_manager_->WaitForSyncThread(); - EXPECT_EQ(set1, fake_manager_->GetLastRefreshRequestTypes()); - - syncer::ModelTypeSet set2 = syncer::ModelTypeSet(syncer::SESSIONS); - backend_->TriggerRefresh(set2); - fake_manager_->WaitForSyncThread(); - EXPECT_EQ(set2, fake_manager_->GetLastRefreshRequestTypes()); -} - -// Test that configuration on signin sends the proper GU source. -TEST_F(SyncBackendHostTest, DownloadControlTypesNewClient) { - InitializeBackend(true); - EXPECT_EQ(syncer::CONFIGURE_REASON_NEW_CLIENT, - fake_manager_->GetAndResetConfigureReason()); -} - -// Test that configuration on restart sends the proper GU source. -TEST_F(SyncBackendHostTest, DownloadControlTypesRestart) { - sync_prefs_->SetFirstSetupComplete(); - fake_manager_factory_->set_progress_marker_types(enabled_types_); - fake_manager_factory_->set_initial_sync_ended_types(enabled_types_); - InitializeBackend(true); - EXPECT_EQ(syncer::CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE, - fake_manager_->GetAndResetConfigureReason()); -} - -// It is SyncBackendHostCore responsibility to cleanup Sync Data folder if sync -// setup hasn't been completed. This test ensures that cleanup happens. -TEST_F(SyncBackendHostTest, TestStartupWithOldSyncData) { - const char* nonsense = "slon"; - base::FilePath temp_directory = temp_dir_.path().Append( - base::FilePath(kTestSyncDir)); - base::FilePath sync_file = temp_directory.AppendASCII("SyncData.sqlite3"); - ASSERT_TRUE(base::CreateDirectory(temp_directory)); - ASSERT_NE(-1, base::WriteFile(sync_file, nonsense, strlen(nonsense))); - - InitializeBackend(true); - - EXPECT_FALSE(base::PathExists(sync_file)); -} - -// If bookmarks encounter an error that results in disabling without purging -// (such as when the type is unready), and then is explicitly disabled, the -// SyncBackendHost needs to tell the manager to purge the type, even though -// it's already disabled (crbug.com/386778). -TEST_F(SyncBackendHostTest, DisableThenPurgeType) { - syncer::ModelTypeSet error_types(syncer::BOOKMARKS); - - InitializeBackend(true); - - // First enable the types. - syncer::ModelTypeSet ready_types = ConfigureDataTypes( - enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), - syncer::ModelTypeSet()); - - // Nigori is always downloaded so won't be ready. - EXPECT_EQ(syncer::Difference(syncer::ControlTypes(), - syncer::ModelTypeSet(syncer::NIGORI)), - ready_types); - - // Then mark the error types as unready (disables without purging). - ready_types = ConfigureDataTypes( - enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), - error_types); - EXPECT_EQ(syncer::Difference(enabled_types_, error_types), ready_types); - EXPECT_TRUE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( - error_types).Empty()); - - // Lastly explicitly disable the error types, which should result in a purge. - enabled_types_.RemoveAll(error_types); - ready_types = ConfigureDataTypes( - enabled_types_, Difference(syncer::ModelTypeSet::All(), enabled_types_), - syncer::ModelTypeSet()); - EXPECT_EQ(syncer::Difference(enabled_types_, error_types), ready_types); - EXPECT_FALSE(fake_manager_->GetTypesWithEmptyProgressMarkerToken( - error_types).Empty()); -} - -// Test that a call to ClearServerData is forwarded to the underlying -// SyncManager. -TEST_F(SyncBackendHostTest, ClearServerDataCallsAreForwarded) { - InitializeBackend(true); - syncer::CallbackCounter callback_counter; - backend_->ClearServerData(base::Bind(&syncer::CallbackCounter::Callback, - base::Unretained(&callback_counter))); - fake_manager_->WaitForSyncThread(); - EXPECT_EQ(1, callback_counter.times_called()); -} - -// Ensure that redundant invalidations are ignored and that the most recent -// set of invalidation version is persisted across restarts. -TEST_F(SyncBackendHostTest, IgnoreOldInvalidations) { - // Set up some old persisted invalidations. - std::map<syncer::ModelType, int64_t> invalidation_versions; - invalidation_versions[syncer::BOOKMARKS] = 20; - sync_prefs_->UpdateInvalidationVersions(invalidation_versions); - InitializeBackend(true); - EXPECT_EQ(0, fake_manager_->GetInvalidationCount()); - - // Receiving an invalidation with an old version should do nothing. - syncer::ObjectIdInvalidationMap invalidation_map; - std::string notification_type; - syncer::RealModelTypeToNotificationType(syncer::BOOKMARKS, - ¬ification_type); - invalidation_map.Insert(syncer::Invalidation::Init( - invalidation::ObjectId(0, notification_type), 10, "payload")); - backend_->OnIncomingInvalidation(invalidation_map); - fake_manager_->WaitForSyncThread(); - EXPECT_EQ(0, fake_manager_->GetInvalidationCount()); - - // Invalidations with new versions should be acted upon. - invalidation_map.Insert(syncer::Invalidation::Init( - invalidation::ObjectId(0, notification_type), 30, "payload")); - backend_->OnIncomingInvalidation(invalidation_map); - fake_manager_->WaitForSyncThread(); - EXPECT_EQ(1, fake_manager_->GetInvalidationCount()); - - // Invalidation for new data types should be acted on. - syncer::RealModelTypeToNotificationType(syncer::SESSIONS, ¬ification_type); - invalidation_map.Insert(syncer::Invalidation::Init( - invalidation::ObjectId(0, notification_type), 10, "payload")); - backend_->OnIncomingInvalidation(invalidation_map); - fake_manager_->WaitForSyncThread(); - EXPECT_EQ(2, fake_manager_->GetInvalidationCount()); - - // But redelivering that same invalidation should be ignored. - backend_->OnIncomingInvalidation(invalidation_map); - fake_manager_->WaitForSyncThread(); - EXPECT_EQ(2, fake_manager_->GetInvalidationCount()); - - // If an invalidation with an unknown version is received, it should be - // acted on, but should not affect the persisted versions. - invalidation_map.Insert(syncer::Invalidation::InitUnknownVersion( - invalidation::ObjectId(0, notification_type))); - backend_->OnIncomingInvalidation(invalidation_map); - fake_manager_->WaitForSyncThread(); - EXPECT_EQ(3, fake_manager_->GetInvalidationCount()); - - // Verify that the invalidation versions were updated in the prefs. - invalidation_versions[syncer::BOOKMARKS] = 30; - invalidation_versions[syncer::SESSIONS] = 10; - std::map<syncer::ModelType, int64_t> persisted_invalidation_versions; - sync_prefs_->GetInvalidationVersions(&persisted_invalidation_versions); - EXPECT_EQ(invalidation_versions.size(), - persisted_invalidation_versions.size()); - for (auto iter : persisted_invalidation_versions) { - EXPECT_EQ(invalidation_versions[iter.first], iter.second); - } -} - -// Tests that SyncBackendHostImpl retains ModelTypeConnector after call to -// StopSyncingForShutdown. This is needed for datatype deactivation during -// DataTypeManager shutdown. -TEST_F(SyncBackendHostTest, ModelTypeConnectorValidDuringShutdown) { - InitializeBackend(true); - backend_->StopSyncingForShutdown(); - // Verify that call to DeactivateNonBlockingDataType doesn't assert. - backend_->DeactivateNonBlockingDataType(syncer::AUTOFILL); - backend_->Shutdown(syncer::STOP_SYNC); - backend_.reset(); -} - -} // namespace - -} // namespace browser_sync
diff --git a/components/sync_driver/glue/sync_backend_host_mock.cc b/components/sync_driver/glue/sync_backend_host_mock.cc deleted file mode 100644 index 613f4fb..0000000 --- a/components/sync_driver/glue/sync_backend_host_mock.cc +++ /dev/null
@@ -1,160 +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 "components/sync_driver/glue/sync_backend_host_mock.h" - -#include "components/sync/core/activation_context.h" -#include "components/sync_driver/sync_frontend.h" - -namespace browser_sync { - -const char kTestCacheGuid[] = "test-guid"; - -SyncBackendHostMock::SyncBackendHostMock() : fail_initial_download_(false) {} -SyncBackendHostMock::~SyncBackendHostMock() {} - -void SyncBackendHostMock::Initialize( - sync_driver::SyncFrontend* frontend, - std::unique_ptr<base::Thread> sync_thread, - const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, - const scoped_refptr<base::SingleThreadTaskRunner>& file_thread, - const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, - const GURL& service_url, - const std::string& sync_user_agent, - const syncer::SyncCredentials& credentials, - bool delete_sync_data_folder, - std::unique_ptr<syncer::SyncManagerFactory> sync_manager_factory, - const syncer::WeakHandle<syncer::UnrecoverableErrorHandler>& - unrecoverable_error_handler, - const base::Closure& report_unrecoverable_error_function, - const HttpPostProviderFactoryGetter& http_post_provider_factory_getter, - std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> - saved_nigori_state) { - frontend->OnBackendInitialized( - syncer::WeakHandle<syncer::JsBackend>(), - syncer::WeakHandle<syncer::DataTypeDebugInfoListener>(), - kTestCacheGuid, - !fail_initial_download_); -} - -void SyncBackendHostMock::TriggerRefresh(const syncer::ModelTypeSet& types) {} - -void SyncBackendHostMock::UpdateCredentials( - const syncer::SyncCredentials& credentials) {} - -void SyncBackendHostMock::StartSyncingWithServer() {} - -void SyncBackendHostMock::SetEncryptionPassphrase( - const std::string& passphrase, - bool is_explicit) {} - -bool SyncBackendHostMock::SetDecryptionPassphrase( - const std::string& passphrase) { - return false; -} - -void SyncBackendHostMock::StopSyncingForShutdown() {} - -std::unique_ptr<base::Thread> SyncBackendHostMock::Shutdown( - syncer::ShutdownReason reason) { - return std::unique_ptr<base::Thread>(); -} - -void SyncBackendHostMock::UnregisterInvalidationIds() {} - -syncer::ModelTypeSet SyncBackendHostMock::ConfigureDataTypes( - syncer::ConfigureReason reason, - const DataTypeConfigStateMap& config_state_map, - const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& - ready_task, - const base::Callback<void()>& retry_callback) { - return syncer::ModelTypeSet(); -} - -void SyncBackendHostMock::EnableEncryptEverything() {} - -void SyncBackendHostMock::ActivateDirectoryDataType( - syncer::ModelType type, - syncer::ModelSafeGroup group, - sync_driver::ChangeProcessor* change_processor) {} -void SyncBackendHostMock::DeactivateDirectoryDataType(syncer::ModelType type) {} - -void SyncBackendHostMock::ActivateNonBlockingDataType( - syncer::ModelType type, - std::unique_ptr<syncer_v2::ActivationContext> activation_context) {} - -void SyncBackendHostMock::DeactivateNonBlockingDataType( - syncer::ModelType type) {} - -syncer::UserShare* SyncBackendHostMock::GetUserShare() const { - return NULL; -} - -SyncBackendHost::Status SyncBackendHostMock::GetDetailedStatus() { - return SyncBackendHost::Status(); -} - -syncer::sessions::SyncSessionSnapshot - SyncBackendHostMock::GetLastSessionSnapshot() const { - return syncer::sessions::SyncSessionSnapshot(); -} - -bool SyncBackendHostMock::HasUnsyncedItems() const { - return false; -} - -bool SyncBackendHostMock::IsNigoriEnabled() const { - return true; -} - -syncer::PassphraseType SyncBackendHostMock::GetPassphraseType() const { - return syncer::IMPLICIT_PASSPHRASE; -} - -base::Time SyncBackendHostMock::GetExplicitPassphraseTime() const { - return base::Time(); -} - -bool SyncBackendHostMock::IsCryptographerReady( - const syncer::BaseTransaction* trans) const { - return false; -} - -void SyncBackendHostMock::GetModelSafeRoutingInfo( - syncer::ModelSafeRoutingInfo* out) const {} - -void SyncBackendHostMock::FlushDirectory() const {} - -base::MessageLoop* SyncBackendHostMock::GetSyncLoopForTesting() { - return NULL; -} - -void SyncBackendHostMock::RefreshTypesForTest(syncer::ModelTypeSet types) {} - -void SyncBackendHostMock::RequestBufferedProtocolEventsAndEnableForwarding() {} - -void SyncBackendHostMock::DisableProtocolEventForwarding() {} - -void SyncBackendHostMock::EnableDirectoryTypeDebugInfoForwarding() {} - -void SyncBackendHostMock::DisableDirectoryTypeDebugInfoForwarding() {} - -void SyncBackendHostMock::GetAllNodesForTypes( - syncer::ModelTypeSet types, - base::Callback<void(const std::vector<syncer::ModelType>& type, - ScopedVector<base::ListValue>) > callback) {} - -void SyncBackendHostMock::set_fail_initial_download(bool should_fail) { - fail_initial_download_ = should_fail; -} - -void SyncBackendHostMock::ClearServerData( - const syncer::SyncManager::ClearServerDataCallback& callback) { - callback.Run(); -} - -void SyncBackendHostMock::OnCookieJarChanged(bool account_mismatch, - bool empty_jar) {} - -} // namespace browser_sync
diff --git a/components/sync_driver/glue/sync_backend_host_mock.h b/components/sync_driver/glue/sync_backend_host_mock.h deleted file mode 100644 index e0828a27..0000000 --- a/components/sync_driver/glue/sync_backend_host_mock.h +++ /dev/null
@@ -1,134 +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 COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_MOCK_H_ -#define COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_MOCK_H_ - -#include <string> - -#include "base/callback.h" -#include "base/compiler_specific.h" -#include "components/sync/base/weak_handle.h" -#include "components/sync_driver/glue/sync_backend_host.h" - -namespace browser_sync { - -// A mock of the SyncBackendHost. -// -// This class implements the bare minimum required for the ProfileSyncService to -// get through initialization. It often returns NULL pointers or nonesense -// values; it is not intended to be used in tests that depend on SyncBackendHost -// behavior. -class SyncBackendHostMock : public SyncBackendHost { - public: - SyncBackendHostMock(); - ~SyncBackendHostMock() override; - - void Initialize( - sync_driver::SyncFrontend* frontend, - std::unique_ptr<base::Thread> sync_thread, - const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, - const scoped_refptr<base::SingleThreadTaskRunner>& file_thread, - const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, - const GURL& service_url, - const std::string& sync_user_agent, - const syncer::SyncCredentials& credentials, - bool delete_sync_data_folder, - std::unique_ptr<syncer::SyncManagerFactory> sync_manager_factory, - const syncer::WeakHandle<syncer::UnrecoverableErrorHandler>& - unrecoverable_error_handler, - const base::Closure& report_unrecoverable_error_function, - const HttpPostProviderFactoryGetter& http_post_provider_factory_getter, - std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> - saved_nigori_state) override; - - void TriggerRefresh(const syncer::ModelTypeSet& types) override; - - void UpdateCredentials(const syncer::SyncCredentials& credentials) override; - - void StartSyncingWithServer() override; - - void SetEncryptionPassphrase(const std::string& passphrase, - bool is_explicit) override; - - bool SetDecryptionPassphrase(const std::string& passphrase) override; - - void StopSyncingForShutdown() override; - - std::unique_ptr<base::Thread> Shutdown( - syncer::ShutdownReason reason) override; - - void UnregisterInvalidationIds() override; - - syncer::ModelTypeSet ConfigureDataTypes( - syncer::ConfigureReason reason, - const DataTypeConfigStateMap& config_state_map, - const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& - ready_task, - const base::Callback<void()>& retry_callback) override; - - void EnableEncryptEverything() override; - - void ActivateDirectoryDataType( - syncer::ModelType type, - syncer::ModelSafeGroup group, - sync_driver::ChangeProcessor* change_processor) override; - void DeactivateDirectoryDataType(syncer::ModelType type) override; - - void ActivateNonBlockingDataType( - syncer::ModelType type, - std::unique_ptr<syncer_v2::ActivationContext>) override; - void DeactivateNonBlockingDataType(syncer::ModelType type) override; - - syncer::UserShare* GetUserShare() const override; - - Status GetDetailedStatus() override; - - syncer::sessions::SyncSessionSnapshot GetLastSessionSnapshot() const override; - - bool HasUnsyncedItems() const override; - - bool IsNigoriEnabled() const override; - - syncer::PassphraseType GetPassphraseType() const override; - - base::Time GetExplicitPassphraseTime() const override; - - bool IsCryptographerReady( - const syncer::BaseTransaction* trans) const override; - - void GetModelSafeRoutingInfo( - syncer::ModelSafeRoutingInfo* out) const override; - - void FlushDirectory() const override; - - void RequestBufferedProtocolEventsAndEnableForwarding() override; - void DisableProtocolEventForwarding() override; - - void EnableDirectoryTypeDebugInfoForwarding() override; - void DisableDirectoryTypeDebugInfoForwarding() override; - - void GetAllNodesForTypes( - syncer::ModelTypeSet types, - base::Callback<void(const std::vector<syncer::ModelType>& type, - ScopedVector<base::ListValue>)> callback) override; - - base::MessageLoop* GetSyncLoopForTesting() override; - - void RefreshTypesForTest(syncer::ModelTypeSet types) override; - - void ClearServerData( - const syncer::SyncManager::ClearServerDataCallback& callback) override; - - void OnCookieJarChanged(bool account_mismatch, bool empty_jar) override; - - void set_fail_initial_download(bool should_fail); - - private: - bool fail_initial_download_; -}; - -} // namespace browser_sync - -#endif // COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_HOST_MOCK_H_
diff --git a/components/sync_driver/glue/sync_backend_registrar.cc b/components/sync_driver/glue/sync_backend_registrar.cc deleted file mode 100644 index e17a7f6..0000000 --- a/components/sync_driver/glue/sync_backend_registrar.cc +++ /dev/null
@@ -1,381 +0,0 @@ -// 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. - -#include "components/sync_driver/glue/sync_backend_registrar.h" - -#include <cstddef> -#include <utility> - -#include "base/compiler_specific.h" -#include "base/logging.h" -#include "base/message_loop/message_loop.h" -#include "components/sync/core/user_share.h" -#include "components/sync_driver/change_processor.h" -#include "components/sync_driver/sync_client.h" - -namespace browser_sync { - -SyncBackendRegistrar::SyncBackendRegistrar( - const std::string& name, - sync_driver::SyncClient* sync_client, - std::unique_ptr<base::Thread> sync_thread, - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, - const scoped_refptr<base::SingleThreadTaskRunner>& file_thread) - : name_(name), - sync_client_(sync_client), - ui_thread_(ui_thread), - db_thread_(db_thread), - file_thread_(file_thread) { - DCHECK(ui_thread_->BelongsToCurrentThread()); - DCHECK(sync_client_); - - sync_thread_ = std::move(sync_thread); - if (!sync_thread_) { - sync_thread_.reset(new base::Thread("Chrome_SyncThread")); - base::Thread::Options options; - options.timer_slack = base::TIMER_SLACK_MAXIMUM; - CHECK(sync_thread_->StartWithOptions(options)); - } - - MaybeAddWorker(syncer::GROUP_DB); - MaybeAddWorker(syncer::GROUP_FILE); - MaybeAddWorker(syncer::GROUP_UI); - MaybeAddWorker(syncer::GROUP_PASSIVE); - MaybeAddWorker(syncer::GROUP_HISTORY); - MaybeAddWorker(syncer::GROUP_PASSWORD); - - // Must have at least one worker for SyncBackendRegistrar to be destroyed - // correctly, as it is destroyed after the last worker dies. - DCHECK_GT(workers_.size(), 0u); -} - -void SyncBackendRegistrar::RegisterNonBlockingType(syncer::ModelType type) { - DCHECK(ui_thread_->BelongsToCurrentThread()); - base::AutoLock lock(lock_); - DCHECK(routing_info_.find(type) == routing_info_.end() || - routing_info_[type] == syncer::GROUP_NON_BLOCKING); - non_blocking_types_.Put(type); -} - -void SyncBackendRegistrar::SetInitialTypes(syncer::ModelTypeSet initial_types) { - base::AutoLock lock(lock_); - - // This function should be called only once, shortly after construction. The - // routing info at that point is expected to be empty. - DCHECK(routing_info_.empty()); - - // Set our initial state to reflect the current status of the sync directory. - // This will ensure that our calculations in ConfigureDataTypes() will always - // return correct results. - for (syncer::ModelTypeSet::Iterator it = initial_types.First(); it.Good(); - it.Inc()) { - routing_info_[it.Get()] = GetInitialGroupForType(it.Get()); - } - - if (!workers_.count(syncer::GROUP_HISTORY)) { - LOG_IF(WARNING, initial_types.Has(syncer::TYPED_URLS)) - << "History store disabled, cannot sync Omnibox History"; - routing_info_.erase(syncer::TYPED_URLS); - } - - if (!workers_.count(syncer::GROUP_PASSWORD)) { - LOG_IF(WARNING, initial_types.Has(syncer::PASSWORDS)) - << "Password store not initialized, cannot sync passwords"; - routing_info_.erase(syncer::PASSWORDS); - } - - last_configured_types_ = syncer::GetRoutingInfoTypes(routing_info_); -} - -void SyncBackendRegistrar::AddRestoredNonBlockingType(syncer::ModelType type) { - DCHECK(ui_thread_->BelongsToCurrentThread()); - base::AutoLock lock(lock_); - DCHECK(non_blocking_types_.Has(type)); - DCHECK(routing_info_.find(type) == routing_info_.end()); - routing_info_[type] = syncer::GROUP_NON_BLOCKING; - last_configured_types_.Put(type); -} - -bool SyncBackendRegistrar::IsNigoriEnabled() const { - DCHECK(ui_thread_->BelongsToCurrentThread()); - base::AutoLock lock(lock_); - return routing_info_.find(syncer::NIGORI) != routing_info_.end(); -} - -syncer::ModelTypeSet SyncBackendRegistrar::ConfigureDataTypes( - syncer::ModelTypeSet types_to_add, - syncer::ModelTypeSet types_to_remove) { - DCHECK(Intersection(types_to_add, types_to_remove).Empty()); - syncer::ModelTypeSet filtered_types_to_add = types_to_add; - if (workers_.count(syncer::GROUP_HISTORY) == 0) { - LOG(WARNING) << "No history worker -- removing TYPED_URLS"; - filtered_types_to_add.Remove(syncer::TYPED_URLS); - } - if (workers_.count(syncer::GROUP_PASSWORD) == 0) { - LOG(WARNING) << "No password worker -- removing PASSWORDS"; - filtered_types_to_add.Remove(syncer::PASSWORDS); - } - - base::AutoLock lock(lock_); - syncer::ModelTypeSet newly_added_types; - for (syncer::ModelTypeSet::Iterator it = filtered_types_to_add.First(); - it.Good(); it.Inc()) { - // Add a newly specified data type as syncer::GROUP_PASSIVE into the - // routing_info, if it does not already exist. - if (routing_info_.count(it.Get()) == 0) { - routing_info_[it.Get()] = GetInitialGroupForType(it.Get()); - newly_added_types.Put(it.Get()); - } - } - for (syncer::ModelTypeSet::Iterator it = types_to_remove.First(); it.Good(); - it.Inc()) { - routing_info_.erase(it.Get()); - } - - // TODO(akalin): Use SVLOG/SLOG if we add any more logging. - DVLOG(1) << name_ << ": Adding types " - << syncer::ModelTypeSetToString(types_to_add) - << " (with newly-added types " - << syncer::ModelTypeSetToString(newly_added_types) - << ") and removing types " - << syncer::ModelTypeSetToString(types_to_remove) - << " to get new routing info " - << syncer::ModelSafeRoutingInfoToString(routing_info_); - last_configured_types_ = syncer::GetRoutingInfoTypes(routing_info_); - - return newly_added_types; -} - -syncer::ModelTypeSet SyncBackendRegistrar::GetLastConfiguredTypes() const { - return last_configured_types_; -} - -void SyncBackendRegistrar::RequestWorkerStopOnUIThread() { - DCHECK(ui_thread_->BelongsToCurrentThread()); - base::AutoLock lock(lock_); - for (WorkerMap::const_iterator it = workers_.begin(); it != workers_.end(); - ++it) { - it->second->RequestStop(); - } -} - -void SyncBackendRegistrar::ActivateDataType( - syncer::ModelType type, - syncer::ModelSafeGroup group, - sync_driver::ChangeProcessor* change_processor, - syncer::UserShare* user_share) { - DVLOG(1) << "Activate: " << syncer::ModelTypeToString(type); - - base::AutoLock lock(lock_); - // Ensure that the given data type is in the PASSIVE group. - syncer::ModelSafeRoutingInfo::iterator i = routing_info_.find(type); - DCHECK(i != routing_info_.end()); - DCHECK_EQ(i->second, syncer::GROUP_PASSIVE); - routing_info_[type] = group; - - // Add the data type's change processor to the list of change - // processors so it can receive updates. - DCHECK_EQ(processors_.count(type), 0U); - processors_[type] = change_processor; - - // Start the change processor. - change_processor->Start(user_share); - DCHECK(GetProcessorUnsafe(type)); -} - -void SyncBackendRegistrar::DeactivateDataType(syncer::ModelType type) { - DVLOG(1) << "Deactivate: " << syncer::ModelTypeToString(type); - - DCHECK(ui_thread_->BelongsToCurrentThread() || IsControlType(type)); - base::AutoLock lock(lock_); - - routing_info_.erase(type); - ignore_result(processors_.erase(type)); - DCHECK(!GetProcessorUnsafe(type)); -} - -bool SyncBackendRegistrar::IsTypeActivatedForTest( - syncer::ModelType type) const { - return GetProcessor(type) != NULL; -} - -void SyncBackendRegistrar::OnChangesApplied( - syncer::ModelType model_type, - int64_t model_version, - const syncer::BaseTransaction* trans, - const syncer::ImmutableChangeRecordList& changes) { - sync_driver::ChangeProcessor* processor = GetProcessor(model_type); - if (!processor) - return; - - processor->ApplyChangesFromSyncModel(trans, model_version, changes); -} - -void SyncBackendRegistrar::OnChangesComplete(syncer::ModelType model_type) { - sync_driver::ChangeProcessor* processor = GetProcessor(model_type); - if (!processor) - return; - - // This call just notifies the processor that it can commit; it - // already buffered any changes it plans to makes so needs no - // further information. - processor->CommitChangesFromSyncModel(); -} - -void SyncBackendRegistrar::GetWorkers( - std::vector<scoped_refptr<syncer::ModelSafeWorker>>* out) { - base::AutoLock lock(lock_); - out->clear(); - for (WorkerMap::const_iterator it = workers_.begin(); it != workers_.end(); - ++it) { - out->push_back(it->second.get()); - } -} - -void SyncBackendRegistrar::GetModelSafeRoutingInfo( - syncer::ModelSafeRoutingInfo* out) { - base::AutoLock lock(lock_); - syncer::ModelSafeRoutingInfo copy(routing_info_); - out->swap(copy); -} - -sync_driver::ChangeProcessor* SyncBackendRegistrar::GetProcessor( - syncer::ModelType type) const { - base::AutoLock lock(lock_); - sync_driver::ChangeProcessor* processor = GetProcessorUnsafe(type); - if (!processor) - return NULL; - - // We can only check if |processor| exists, as otherwise the type is - // mapped to syncer::GROUP_PASSIVE. - CHECK(IsCurrentThreadSafeForModel(type)); - return processor; -} - -sync_driver::ChangeProcessor* SyncBackendRegistrar::GetProcessorUnsafe( - syncer::ModelType type) const { - lock_.AssertAcquired(); - std::map<syncer::ModelType, sync_driver::ChangeProcessor*>::const_iterator - it = processors_.find(type); - - // Until model association happens for a datatype, it will not - // appear in the processors list. During this time, it is OK to - // drop changes on the floor (since model association has not - // happened yet). When the data type is activated, model - // association takes place then the change processor is added to the - // |processors_| list. - if (it == processors_.end()) - return NULL; - - return it->second; -} - -bool SyncBackendRegistrar::IsCurrentThreadSafeForModel( - syncer::ModelType model_type) const { - lock_.AssertAcquired(); - return IsOnThreadForGroup(model_type, - GetGroupForModelType(model_type, routing_info_)); -} - -bool SyncBackendRegistrar::IsOnThreadForGroup( - syncer::ModelType type, - syncer::ModelSafeGroup group) const { - switch (group) { - case syncer::GROUP_PASSIVE: - return IsControlType(type); - case syncer::GROUP_UI: - return ui_thread_->BelongsToCurrentThread(); - case syncer::GROUP_DB: - return db_thread_->BelongsToCurrentThread(); - case syncer::GROUP_FILE: - return file_thread_->BelongsToCurrentThread(); - case syncer::GROUP_HISTORY: - // TODO(sync): How to check we're on the right thread? - return type == syncer::TYPED_URLS; - case syncer::GROUP_PASSWORD: - // TODO(sync): How to check we're on the right thread? - return type == syncer::PASSWORDS; - case syncer::GROUP_NON_BLOCKING: - // IsOnThreadForGroup shouldn't be called for non-blocking types. - return false; - } - NOTREACHED(); - return false; -} - -SyncBackendRegistrar::~SyncBackendRegistrar() { - DCHECK(workers_.empty()); -} - -void SyncBackendRegistrar::OnWorkerLoopDestroyed(syncer::ModelSafeGroup group) { - RemoveWorker(group); -} - -void SyncBackendRegistrar::MaybeAddWorker(syncer::ModelSafeGroup group) { - const scoped_refptr<syncer::ModelSafeWorker> worker = - sync_client_->CreateModelWorkerForGroup(group, this); - if (worker) { - DCHECK(workers_.find(group) == workers_.end()); - workers_[group] = worker; - workers_[group]->RegisterForLoopDestruction(); - } -} - -void SyncBackendRegistrar::OnWorkerUnregistrationDone( - syncer::ModelSafeGroup group) { - RemoveWorker(group); -} - -void SyncBackendRegistrar::RemoveWorker(syncer::ModelSafeGroup group) { - DVLOG(1) << "Remove " << ModelSafeGroupToString(group) << " worker."; - - bool last_worker = false; - { - base::AutoLock al(lock_); - WorkerMap::iterator it = workers_.find(group); - CHECK(it != workers_.end()); - stopped_workers_.push_back(it->second); - workers_.erase(it); - last_worker = workers_.empty(); - } - - if (last_worker) { - // Self-destruction after last worker. - DVLOG(1) << "Destroy registrar on loop of " - << ModelSafeGroupToString(group); - delete this; - } -} - -std::unique_ptr<base::Thread> SyncBackendRegistrar::ReleaseSyncThread() { - return std::move(sync_thread_); -} - -void SyncBackendRegistrar::Shutdown() { - // All data types should have been deactivated by now. - DCHECK(processors_.empty()); - - // Unregister worker from observing loop destruction. - base::AutoLock al(lock_); - for (WorkerMap::iterator it = workers_.begin(); it != workers_.end(); ++it) { - it->second->UnregisterForLoopDestruction( - base::Bind(&SyncBackendRegistrar::OnWorkerUnregistrationDone, - base::Unretained(this))); - } -} - -base::Thread* SyncBackendRegistrar::sync_thread() { - return sync_thread_.get(); -} - -syncer::ModelSafeGroup SyncBackendRegistrar::GetInitialGroupForType( - syncer::ModelType type) const { - if (non_blocking_types_.Has(type)) - return syncer::GROUP_NON_BLOCKING; - else - return syncer::GROUP_PASSIVE; -} - -} // namespace browser_sync
diff --git a/components/sync_driver/glue/sync_backend_registrar.h b/components/sync_driver/glue/sync_backend_registrar.h deleted file mode 100644 index 732ca06..0000000 --- a/components/sync_driver/glue/sync_backend_registrar.h +++ /dev/null
@@ -1,239 +0,0 @@ -// 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. - -#ifndef COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_REGISTRAR_H_ -#define COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_REGISTRAR_H_ - -#include <stdint.h> - -#include <map> -#include <memory> -#include <string> -#include <vector> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/synchronization/lock.h" -#include "base/threading/thread.h" -#include "components/sync/base/model_type.h" -#include "components/sync/core/sync_manager.h" -#include "components/sync/engine/model_safe_worker.h" - -class Profile; - -namespace base { -class MessageLoop; -} - -namespace syncer { -struct UserShare; -} // namespace syncer - -namespace sync_driver { -class ChangeProcessor; -class SyncClient; -} - -namespace browser_sync { - -class UIModelWorker; - -// A class that keep track of the workers, change processors, and -// routing info for the enabled sync types, and also routes change -// events to the right processors. -class SyncBackendRegistrar : public syncer::SyncManager::ChangeDelegate, - public syncer::WorkerLoopDestructionObserver { - public: - // |name| is used for debugging. Does not take ownership of |profile|. - // Must be created on the UI thread. - SyncBackendRegistrar( - const std::string& name, - sync_driver::SyncClient* sync_client, - std::unique_ptr<base::Thread> sync_thread, - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, - const scoped_refptr<base::SingleThreadTaskRunner>& file_thread); - - // SyncBackendRegistrar must be destroyed as follows: - // - // 1) On the UI thread, call RequestWorkerStopOnUIThread(). - // 2) UI posts task to shut down syncer on sync thread. - // 3) If sync is disabled, call ReleaseSyncThread() on the UI thread. - // 3) UI posts SyncBackendRegistrar::ShutDown() on sync thread to - // unregister workers from observing destruction of their working loops. - // 4) Workers notify registrar when unregistration finishes or working - // loops are destroyed. Registrar destroys itself on last worker - // notification. Sync thread will be stopped if ownership was not - // released. - ~SyncBackendRegistrar() override; - - // Adds |type| to set of non-blocking types. These types are assigned to - // GROUP_NON_BLOCKING model safe group and will be treated differently in - // ModelTypeRegistry. Unlike directory types, non-blocking types always stay - // assigned to GROUP_NON_BLOCKING group. - void RegisterNonBlockingType(syncer::ModelType type); - - // Informs the SyncBackendRegistrar of the currently enabled set of types. - // These types will be placed in the passive group. This function should be - // called exactly once during startup. - void SetInitialTypes(syncer::ModelTypeSet initial_types); - - // Informs SyncBackendRegistrar about non-blocking type loaded from local - // storage. Initial sync was already performed for this type, therefore its - // data shouldn't be downloaded as part of configuration. - void AddRestoredNonBlockingType(syncer::ModelType type); - - // Returns whether or not we are currently syncing encryption keys. - // Must be called on the UI thread. - bool IsNigoriEnabled() const; - - // Removes all types in |types_to_remove| from the routing info and - // adds all the types in |types_to_add| to the routing info that are - // not already there (initially put in the passive group). - // |types_to_remove| and |types_to_add| must be disjoint. Returns - // the set of newly-added types. Must be called on the UI thread. - syncer::ModelTypeSet ConfigureDataTypes(syncer::ModelTypeSet types_to_add, - syncer::ModelTypeSet types_to_remove); - - // Returns the set of enabled types as of the last configuration. Note that - // this might be different from the current types in the routing info due - // to DeactiveDataType being called separately from ConfigureDataTypes. - syncer::ModelTypeSet GetLastConfiguredTypes() const; - - // Must be called from the UI thread. (See destructor comment.) - void RequestWorkerStopOnUIThread(); - - // Activates the given data type (which should belong to the given - // group) and starts the given change processor. Must be called - // from |group|'s native thread. - void ActivateDataType(syncer::ModelType type, - syncer::ModelSafeGroup group, - sync_driver::ChangeProcessor* change_processor, - syncer::UserShare* user_share); - - // Deactivates the given type if necessary. Must be called from the - // UI thread and not |type|'s native thread. Yes, this is - // surprising: see http://crbug.com/92804. - void DeactivateDataType(syncer::ModelType type); - - // Returns true only between calls to ActivateDataType(type, ...) - // and DeactivateDataType(type). Used only by tests. - bool IsTypeActivatedForTest(syncer::ModelType type) const; - - // SyncManager::ChangeDelegate implementation. May be called from - // any thread. - void OnChangesApplied( - syncer::ModelType model_type, - int64_t model_version, - const syncer::BaseTransaction* trans, - const syncer::ImmutableChangeRecordList& changes) override; - void OnChangesComplete(syncer::ModelType model_type) override; - - void GetWorkers(std::vector<scoped_refptr<syncer::ModelSafeWorker>>* out); - void GetModelSafeRoutingInfo(syncer::ModelSafeRoutingInfo* out); - - // syncer::WorkerLoopDestructionObserver implementation. - void OnWorkerLoopDestroyed(syncer::ModelSafeGroup group) override; - - // Release ownership of |sync_thread_|. Called when sync is disabled. - std::unique_ptr<base::Thread> ReleaseSyncThread(); - - // Unregister workers from loop destruction observation. - void Shutdown(); - - base::Thread* sync_thread(); - - private: - typedef std::map<syncer::ModelSafeGroup, - scoped_refptr<syncer::ModelSafeWorker>> WorkerMap; - typedef std::map<syncer::ModelType, sync_driver::ChangeProcessor*> - ProcessorMap; - - // Add a worker for |group| to the worker map if one can be created. - void MaybeAddWorker(syncer::ModelSafeGroup group); - - // Callback after workers unregister from observing destruction of their - // working loops. - void OnWorkerUnregistrationDone(syncer::ModelSafeGroup group); - - void RemoveWorker(syncer::ModelSafeGroup group); - - // Returns the change processor for the given model, or NULL if none - // exists. Must be called from |group|'s native thread. - sync_driver::ChangeProcessor* GetProcessor(syncer::ModelType type) const; - - // Must be called with |lock_| held. Simply returns the change - // processor for the given type, if it exists. May be called from - // any thread. - sync_driver::ChangeProcessor* GetProcessorUnsafe( - syncer::ModelType type) const; - - // Return true if |model_type| lives on the current thread. Must be - // called with |lock_| held. May be called on any thread. - bool IsCurrentThreadSafeForModel(syncer::ModelType model_type) const; - - // Returns true if the current thread is the native thread for the - // given group (or if it is undeterminable). - bool IsOnThreadForGroup(syncer::ModelType type, - syncer::ModelSafeGroup group) const; - - // Returns model safe group that should be assigned to type when it is first - // configured (before activation). Returns GROUP_PASSIVE for directory types - // and GROUP_NON_BLOCKING for non-blocking types. - syncer::ModelSafeGroup GetInitialGroupForType(syncer::ModelType type) const; - - // Name used for debugging. - const std::string name_; - - // A pointer to the sync client. - sync_driver::SyncClient* const sync_client_; - - // Protects all variables below. - mutable base::Lock lock_; - - // We maintain ownership of all workers. In some cases, we need to - // ensure shutdown occurs in an expected sequence by Stop()ing - // certain workers. They are guaranteed to be valid because we only - // destroy elements of |workers_| after the syncapi has been - // destroyed. Unless a worker is no longer needed because all types - // that get routed to it have been disabled (from syncing). In that - // case, we'll destroy on demand *after* routing any dependent types - // to syncer::GROUP_PASSIVE, so that the syncapi doesn't call into garbage. - // If a key is present, it means at least one ModelType that routes - // to that model safe group is being synced. - WorkerMap workers_; - syncer::ModelSafeRoutingInfo routing_info_; - - // The change processors that handle the different data types. - ProcessorMap processors_; - - // The types that were enabled as of the last configuration. Updated on each - // call to ConfigureDataTypes as well as SetInitialTypes. - syncer::ModelTypeSet last_configured_types_; - - // Parks stopped workers because they may still be referenced by syncer. - std::vector<scoped_refptr<syncer::ModelSafeWorker>> stopped_workers_; - - // References to the thread task runners that sync depends on. - const scoped_refptr<base::SingleThreadTaskRunner> ui_thread_; - const scoped_refptr<base::SingleThreadTaskRunner> db_thread_; - const scoped_refptr<base::SingleThreadTaskRunner> file_thread_; - - // Declare |sync_thread_| at the end so that it will be destroyed before - // objects above because tasks on sync thread depend on those objects, - // e.g. Shutdown() depends on |lock_|, SyncManager::Init() depends on - // workers, etc. - std::unique_ptr<base::Thread> sync_thread_; - - // Set of types with non-blocking implementation (as opposed to directory - // based). - syncer::ModelTypeSet non_blocking_types_; - - DISALLOW_COPY_AND_ASSIGN(SyncBackendRegistrar); -}; - -} // namespace browser_sync - -#endif // COMPONENTS_SYNC_DRIVER_GLUE_SYNC_BACKEND_REGISTRAR_H_
diff --git a/components/sync_driver/glue/sync_backend_registrar_unittest.cc b/components/sync_driver/glue/sync_backend_registrar_unittest.cc deleted file mode 100644 index 82ec5f24..0000000 --- a/components/sync_driver/glue/sync_backend_registrar_unittest.cc +++ /dev/null
@@ -1,469 +0,0 @@ -// 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. - -#include "components/sync_driver/glue/sync_backend_registrar.h" - -#include "base/location.h" -#include "base/run_loop.h" -#include "base/single_thread_task_runner.h" -#include "components/sync/base/model_type.h" -#include "components/sync/core/test/test_user_share.h" -#include "components/sync/engine/passive_model_worker.h" -#include "components/sync_driver/change_processor_mock.h" -#include "components/sync_driver/fake_sync_client.h" -#include "components/sync_driver/glue/browser_thread_model_worker.h" -#include "components/sync_driver/sync_api_component_factory_mock.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace browser_sync { - -namespace { - -using ::testing::_; -using ::testing::InSequence; -using ::testing::Return; -using ::testing::StrictMock; -using syncer::FIRST_REAL_MODEL_TYPE; -using syncer::AUTOFILL; -using syncer::BOOKMARKS; -using syncer::PREFERENCES; -using syncer::THEMES; -using syncer::NIGORI; -using syncer::PASSWORDS; -using syncer::MODEL_TYPE_COUNT; -using syncer::ModelTypeSet; -using syncer::ModelType; -using syncer::ModelTypeFromInt; - -void TriggerChanges(SyncBackendRegistrar* registrar, ModelType type) { - registrar->OnChangesApplied(type, 0, NULL, - syncer::ImmutableChangeRecordList()); - registrar->OnChangesComplete(type); -} - -class RegistrarSyncClient : public sync_driver::FakeSyncClient { - public: - RegistrarSyncClient( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner, - const scoped_refptr<base::SingleThreadTaskRunner>& db_task_runner, - const scoped_refptr<base::SingleThreadTaskRunner>& file_task_runner) - : ui_task_runner_(ui_task_runner), - db_task_runner_(db_task_runner), - file_task_runner_(file_task_runner) {} - - scoped_refptr<syncer::ModelSafeWorker> CreateModelWorkerForGroup( - syncer::ModelSafeGroup group, - syncer::WorkerLoopDestructionObserver* observer) override { - switch (group) { - case syncer::GROUP_UI: - return new BrowserThreadModelWorker(ui_task_runner_, group, observer); - case syncer::GROUP_DB: - return new BrowserThreadModelWorker(db_task_runner_, group, observer); - case syncer::GROUP_FILE: - return new BrowserThreadModelWorker(file_task_runner_, group, observer); - case syncer::GROUP_PASSIVE: - return new syncer::PassiveModelWorker(observer); - default: - return nullptr; - } - } - - private: - const scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_; - const scoped_refptr<base::SingleThreadTaskRunner> db_task_runner_; - const scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_; -}; - -// Flaky: https://crbug.com/498238 -class SyncBackendRegistrarTest : public testing::Test { - public: - void TestNonUIDataTypeActivationAsync(sync_driver::ChangeProcessor* processor, - base::WaitableEvent* done) { - registrar_->ActivateDataType(AUTOFILL, - syncer::GROUP_DB, - processor, - test_user_share_.user_share()); - syncer::ModelSafeRoutingInfo expected_routing_info; - expected_routing_info[AUTOFILL] = syncer::GROUP_DB; - ExpectRoutingInfo(registrar_.get(), expected_routing_info); - ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet(AUTOFILL)); - TriggerChanges(registrar_.get(), AUTOFILL); - done->Signal(); - } - - protected: - SyncBackendRegistrarTest() - : db_thread_("DBThreadForTest"), - file_thread_("FileThreadForTest"), - sync_thread_(NULL) {} - - ~SyncBackendRegistrarTest() override {} - - void SetUp() override { - db_thread_.StartAndWaitForTesting(); - file_thread_.StartAndWaitForTesting(); - test_user_share_.SetUp(); - sync_client_.reset(new RegistrarSyncClient( - ui_task_runner(), db_task_runner(), file_task_runner())); - registrar_.reset(new SyncBackendRegistrar( - "test", sync_client_.get(), std::unique_ptr<base::Thread>(), - ui_task_runner(), db_task_runner(), file_task_runner())); - sync_thread_ = registrar_->sync_thread(); - } - - void TearDown() override { - registrar_->RequestWorkerStopOnUIThread(); - test_user_share_.TearDown(); - sync_thread_->task_runner()->PostTask( - FROM_HERE, base::Bind(&SyncBackendRegistrar::Shutdown, - base::Unretained(registrar_.release()))); - sync_thread_->WaitUntilThreadStarted(); - base::RunLoop().RunUntilIdle(); - } - - void ExpectRoutingInfo( - SyncBackendRegistrar* registrar, - const syncer::ModelSafeRoutingInfo& expected_routing_info) { - syncer::ModelSafeRoutingInfo routing_info; - registrar->GetModelSafeRoutingInfo(&routing_info); - EXPECT_EQ(expected_routing_info, routing_info); - } - - void ExpectHasProcessorsForTypes(const SyncBackendRegistrar& registrar, - ModelTypeSet types) { - for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { - ModelType model_type = ModelTypeFromInt(i); - EXPECT_EQ(types.Has(model_type), - registrar_->IsTypeActivatedForTest(model_type)); - } - } - - const scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner() { - return message_loop_.task_runner(); - } - - const scoped_refptr<base::SingleThreadTaskRunner> db_task_runner() { - return db_thread_.task_runner(); - } - - const scoped_refptr<base::SingleThreadTaskRunner> file_task_runner() { - return db_thread_.task_runner(); - } - - base::MessageLoop message_loop_; - base::Thread db_thread_; - base::Thread file_thread_; - - syncer::TestUserShare test_user_share_; - std::unique_ptr<RegistrarSyncClient> sync_client_; - std::unique_ptr<SyncBackendRegistrar> registrar_; - - base::Thread* sync_thread_; -}; - -TEST_F(SyncBackendRegistrarTest, ConstructorEmpty) { - registrar_->SetInitialTypes(ModelTypeSet()); - EXPECT_FALSE(registrar_->IsNigoriEnabled()); - { - std::vector<scoped_refptr<syncer::ModelSafeWorker> > workers; - registrar_->GetWorkers(&workers); - EXPECT_EQ(4u, workers.size()); - } - ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo()); - ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet()); -} - -TEST_F(SyncBackendRegistrarTest, ConstructorNonEmpty) { - const ModelTypeSet initial_types(BOOKMARKS, NIGORI, PASSWORDS); - registrar_->RegisterNonBlockingType(BOOKMARKS); - registrar_->SetInitialTypes(initial_types); - EXPECT_TRUE(registrar_->IsNigoriEnabled()); - { - std::vector<scoped_refptr<syncer::ModelSafeWorker> > workers; - registrar_->GetWorkers(&workers); - EXPECT_EQ(4u, workers.size()); - } - { - syncer::ModelSafeRoutingInfo expected_routing_info; - expected_routing_info[BOOKMARKS] = syncer::GROUP_NON_BLOCKING; - expected_routing_info[NIGORI] = syncer::GROUP_PASSIVE; - // Passwords dropped because of no password store. - ExpectRoutingInfo(registrar_.get(), expected_routing_info); - } - ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet()); -} - -TEST_F(SyncBackendRegistrarTest, ConfigureDataTypes) { - registrar_->RegisterNonBlockingType(BOOKMARKS); - registrar_->SetInitialTypes(ModelTypeSet()); - - // Add. - const ModelTypeSet types1(BOOKMARKS, NIGORI, AUTOFILL); - EXPECT_EQ(types1, registrar_->ConfigureDataTypes(types1, ModelTypeSet())); - { - syncer::ModelSafeRoutingInfo expected_routing_info; - expected_routing_info[BOOKMARKS] = syncer::GROUP_NON_BLOCKING; - expected_routing_info[NIGORI] = syncer::GROUP_PASSIVE; - expected_routing_info[AUTOFILL] = syncer::GROUP_PASSIVE; - ExpectRoutingInfo(registrar_.get(), expected_routing_info); - } - ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet()); - EXPECT_EQ(types1, registrar_->GetLastConfiguredTypes()); - - // Add and remove. - const ModelTypeSet types2(PREFERENCES, THEMES); - EXPECT_EQ(types2, registrar_->ConfigureDataTypes(types2, types1)); - { - syncer::ModelSafeRoutingInfo expected_routing_info; - expected_routing_info[PREFERENCES] = syncer::GROUP_PASSIVE; - expected_routing_info[THEMES] = syncer::GROUP_PASSIVE; - ExpectRoutingInfo(registrar_.get(), expected_routing_info); - } - ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet()); - EXPECT_EQ(types2, registrar_->GetLastConfiguredTypes()); - - // Remove. - EXPECT_TRUE(registrar_->ConfigureDataTypes(ModelTypeSet(), types2).Empty()); - ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo()); - ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet()); - EXPECT_EQ(ModelTypeSet(), registrar_->GetLastConfiguredTypes()); -} - -TEST_F(SyncBackendRegistrarTest, ActivateDeactivateUIDataType) { - InSequence in_sequence; - registrar_->SetInitialTypes(ModelTypeSet()); - - // Should do nothing. - TriggerChanges(registrar_.get(), BOOKMARKS); - - StrictMock<sync_driver::ChangeProcessorMock> change_processor_mock; - EXPECT_CALL(change_processor_mock, StartImpl()); - EXPECT_CALL(change_processor_mock, IsRunning()) - .WillRepeatedly(Return(true)); - EXPECT_CALL(change_processor_mock, ApplyChangesFromSyncModel(NULL, _, _)); - EXPECT_CALL(change_processor_mock, IsRunning()) - .WillRepeatedly(Return(true)); - EXPECT_CALL(change_processor_mock, CommitChangesFromSyncModel()); - EXPECT_CALL(change_processor_mock, IsRunning()) - .WillRepeatedly(Return(false)); - - const ModelTypeSet types(BOOKMARKS); - EXPECT_EQ(types, registrar_->ConfigureDataTypes(types, ModelTypeSet())); - registrar_->ActivateDataType(BOOKMARKS, syncer::GROUP_UI, - &change_processor_mock, - test_user_share_.user_share()); - { - syncer::ModelSafeRoutingInfo expected_routing_info; - expected_routing_info[BOOKMARKS] = syncer::GROUP_UI; - ExpectRoutingInfo(registrar_.get(), expected_routing_info); - } - ExpectHasProcessorsForTypes(*registrar_, types); - - TriggerChanges(registrar_.get(), BOOKMARKS); - - registrar_->DeactivateDataType(BOOKMARKS); - ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo()); - ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet()); - - // Should do nothing. - TriggerChanges(registrar_.get(), BOOKMARKS); -} - -TEST_F(SyncBackendRegistrarTest, ActivateDeactivateNonUIDataType) { - InSequence in_sequence; - registrar_->SetInitialTypes(ModelTypeSet()); - - // Should do nothing. - TriggerChanges(registrar_.get(), AUTOFILL); - - StrictMock<sync_driver::ChangeProcessorMock> change_processor_mock; - EXPECT_CALL(change_processor_mock, StartImpl()); - EXPECT_CALL(change_processor_mock, IsRunning()) - .WillRepeatedly(Return(true)); - EXPECT_CALL(change_processor_mock, ApplyChangesFromSyncModel(NULL, _, _)); - EXPECT_CALL(change_processor_mock, IsRunning()) - .WillRepeatedly(Return(true)); - EXPECT_CALL(change_processor_mock, CommitChangesFromSyncModel()); - EXPECT_CALL(change_processor_mock, IsRunning()) - .WillRepeatedly(Return(false)); - - const ModelTypeSet types(AUTOFILL); - EXPECT_EQ(types, registrar_->ConfigureDataTypes(types, ModelTypeSet())); - - base::WaitableEvent done(base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED); - db_task_runner()->PostTask( - FROM_HERE, - base::Bind(&SyncBackendRegistrarTest::TestNonUIDataTypeActivationAsync, - base::Unretained(this), &change_processor_mock, &done)); - done.Wait(); - - registrar_->DeactivateDataType(AUTOFILL); - ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo()); - ExpectHasProcessorsForTypes(*registrar_, ModelTypeSet()); - - // Should do nothing. - TriggerChanges(registrar_.get(), AUTOFILL); -} - -// Tests that registration and configuration of non-blocking data types is -// handled correctly in SyncBackendRegistrar. -TEST_F(SyncBackendRegistrarTest, ConfigureNonBlockingDataType) { - registrar_->RegisterNonBlockingType(AUTOFILL); - registrar_->RegisterNonBlockingType(BOOKMARKS); - - ExpectRoutingInfo(registrar_.get(), syncer::ModelSafeRoutingInfo()); - // Simulate that initial sync was already done for AUTOFILL. - registrar_->AddRestoredNonBlockingType(AUTOFILL); - // It should be added to routing info and set of configured types. - EXPECT_EQ(ModelTypeSet(AUTOFILL), registrar_->GetLastConfiguredTypes()); - { - syncer::ModelSafeRoutingInfo expected_routing_info; - expected_routing_info[AUTOFILL] = syncer::GROUP_NON_BLOCKING; - ExpectRoutingInfo(registrar_.get(), expected_routing_info); - } - - // Configure two non-blocking types. Initial sync wasn't done for BOOKMARKS so - // it should be included in types to be downloaded. - ModelTypeSet types_to_add(AUTOFILL, BOOKMARKS); - ModelTypeSet newly_added_types = - registrar_->ConfigureDataTypes(types_to_add, ModelTypeSet()); - EXPECT_EQ(ModelTypeSet(BOOKMARKS), newly_added_types); - EXPECT_EQ(types_to_add, registrar_->GetLastConfiguredTypes()); - { - syncer::ModelSafeRoutingInfo expected_routing_info; - expected_routing_info[AUTOFILL] = syncer::GROUP_NON_BLOCKING; - expected_routing_info[BOOKMARKS] = syncer::GROUP_NON_BLOCKING; - ExpectRoutingInfo(registrar_.get(), expected_routing_info); - } -} - -class SyncBackendRegistrarShutdownTest : public testing::Test { - public: - void BlockDBThread() { - EXPECT_FALSE(db_thread_lock_.Try()); - - db_thread_blocked_.Signal(); - base::AutoLock l(db_thread_lock_); - } - - protected: - friend class TestRegistrar; - - SyncBackendRegistrarShutdownTest() - : db_thread_("DBThreadForTest"), - file_thread_("FileThreadForTest"), - db_thread_blocked_(base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED) { - quit_closure_ = run_loop_.QuitClosure(); - } - - ~SyncBackendRegistrarShutdownTest() override {} - - void SetUp() override { - db_thread_.StartAndWaitForTesting(); - file_thread_.StartAndWaitForTesting(); - sync_client_.reset(new RegistrarSyncClient( - ui_task_runner(), db_task_runner(), file_task_runner())); - } - - void PostQuitOnUIMessageLoop() { - ui_task_runner()->PostTask(FROM_HERE, quit_closure_); - } - - const scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner() { - return message_loop_.task_runner(); - } - - const scoped_refptr<base::SingleThreadTaskRunner> db_task_runner() { - return db_thread_.task_runner(); - } - - const scoped_refptr<base::SingleThreadTaskRunner> file_task_runner() { - return file_thread_.task_runner(); - } - - base::MessageLoop message_loop_; - base::Thread db_thread_; - base::Thread file_thread_; - - std::unique_ptr<RegistrarSyncClient> sync_client_; - base::WaitableEvent db_thread_blocked_; - - base::Lock db_thread_lock_; - base::RunLoop run_loop_; - base::Closure quit_closure_; -}; - -// Wrap SyncBackendRegistrar so that we can monitor its lifetime. -class TestRegistrar : public SyncBackendRegistrar { - public: - explicit TestRegistrar( - sync_driver::SyncClient* sync_client, - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const scoped_refptr<base::SingleThreadTaskRunner>& db_thread, - const scoped_refptr<base::SingleThreadTaskRunner>& file_thread, - SyncBackendRegistrarShutdownTest* test) - : SyncBackendRegistrar("test", - sync_client, - std::unique_ptr<base::Thread>(), - ui_thread, - db_thread, - file_thread), - test_(test) {} - - ~TestRegistrar() override { test_->PostQuitOnUIMessageLoop(); } - - private: - SyncBackendRegistrarShutdownTest* test_; -}; - -TEST_F(SyncBackendRegistrarShutdownTest, BlockingShutdown) { - // Take ownership of |db_thread_lock_| so that the DB thread can't acquire it. - db_thread_lock_.Acquire(); - - // This will block the DB thread by waiting on |db_thread_lock_|. - db_task_runner()->PostTask( - FROM_HERE, base::Bind(&SyncBackendRegistrarShutdownTest::BlockDBThread, - base::Unretained(this))); - - std::unique_ptr<TestRegistrar> registrar( - new TestRegistrar(sync_client_.get(), ui_task_runner(), db_task_runner(), - file_task_runner(), this)); - base::Thread* sync_thread = registrar->sync_thread(); - - // Stop here until the DB thread gets a chance to run and block on the lock. - // Please note that since the task above didn't finish, the task to - // initialize the worker on the DB thread hasn't had a chance to run yet too. - // Which means ModelSafeWorker::SetWorkingLoopToCurrent hasn't been called - // for the DB worker. - db_thread_blocked_.Wait(); - - registrar->SetInitialTypes(ModelTypeSet()); - - // Start the shutdown. - registrar->RequestWorkerStopOnUIThread(); - - sync_thread->task_runner()->PostTask( - FROM_HERE, base::Bind(&SyncBackendRegistrar::Shutdown, - base::Unretained(registrar.release()))); - - // Make sure the thread starts running. - sync_thread->WaitUntilThreadStarted(); - - // The test verifies that the sync thread doesn't block because - // of the blocked DB thread and can finish the shutdown. - base::RunLoop().RunUntilIdle(); - - db_thread_lock_.Release(); - - // Run the main thread loop until all workers have been removed and the - // registrar destroyed. - run_loop_.Run(); -} - -} // namespace - -} // namespace browser_sync
diff --git a/components/sync_driver/glue/ui_model_worker.cc b/components/sync_driver/glue/ui_model_worker.cc deleted file mode 100644 index 7dfb5f0..0000000 --- a/components/sync_driver/glue/ui_model_worker.cc +++ /dev/null
@@ -1,78 +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 "components/sync_driver/glue/ui_model_worker.h" - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/message_loop/message_loop.h" -#include "base/synchronization/waitable_event.h" -#include "base/third_party/dynamic_annotations/dynamic_annotations.h" -#include "base/threading/thread_restrictions.h" - -namespace browser_sync { - -namespace { - -// A simple callback to signal a waitable event after running a closure. -void CallDoWorkAndSignalCallback(const syncer::WorkCallback& work, - base::WaitableEvent* work_done, - syncer::SyncerError* error_info) { - if (work.is_null()) { - // This can happen during tests or cases where there are more than just the - // default UIModelWorker in existence and it gets destroyed before - // the main UI loop has terminated. There is no easy way to assert the - // loop is running / not running at the moment, so we just provide cancel - // semantics here and short-circuit. - // TODO(timsteele): Maybe we should have the message loop destruction - // observer fire when the loop has ended, just a bit before it - // actually gets destroyed. - return; - } - - *error_info = work.Run(); - - work_done->Signal(); // Unblock the syncer thread that scheduled us. -} - -} // namespace - -UIModelWorker::UIModelWorker( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - syncer::WorkerLoopDestructionObserver* observer) - : syncer::ModelSafeWorker(observer), ui_thread_(ui_thread) {} - -void UIModelWorker::RegisterForLoopDestruction() { - CHECK(ui_thread_->BelongsToCurrentThread()); - SetWorkingLoopToCurrent(); -} - -syncer::SyncerError UIModelWorker::DoWorkAndWaitUntilDoneImpl( - const syncer::WorkCallback& work) { - syncer::SyncerError error_info; - if (ui_thread_->BelongsToCurrentThread()) { - DLOG(WARNING) << "DoWorkAndWaitUntilDone called from " - << "ui_loop_. Probably a nested invocation?"; - return work.Run(); - } - - if (!ui_thread_->PostTask(FROM_HERE, - base::Bind(&CallDoWorkAndSignalCallback, work, - work_done_or_stopped(), &error_info))) { - DLOG(WARNING) << "Could not post work to UI loop."; - error_info = syncer::CANNOT_DO_WORK; - return error_info; - } - work_done_or_stopped()->Wait(); - - return error_info; -} - -syncer::ModelSafeGroup UIModelWorker::GetModelSafeGroup() { - return syncer::GROUP_UI; -} - -UIModelWorker::~UIModelWorker() {} - -} // namespace browser_sync
diff --git a/components/sync_driver/glue/ui_model_worker_unittest.cc b/components/sync_driver/glue/ui_model_worker_unittest.cc deleted file mode 100644 index 821bb8e..0000000 --- a/components/sync_driver/glue/ui_model_worker_unittest.cc +++ /dev/null
@@ -1,101 +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 "components/sync_driver/glue/ui_model_worker.h" - -#include <memory> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/callback.h" -#include "base/location.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/run_loop.h" -#include "base/single_thread_task_runner.h" -#include "base/synchronization/waitable_event.h" -#include "base/threading/thread.h" -#include "base/threading/thread_task_runner_handle.h" -#include "testing/gtest/include/gtest/gtest.h" - -using browser_sync::UIModelWorker; -using syncer::SyncerError; - -class UIModelWorkerVisitor { - public: - UIModelWorkerVisitor(base::WaitableEvent* was_run, - bool quit_loop) - : quit_loop_when_run_(quit_loop), - was_run_(was_run) { } - virtual ~UIModelWorkerVisitor() { } - - virtual syncer::SyncerError DoWork() { - was_run_->Signal(); - if (quit_loop_when_run_) - base::MessageLoop::current()->QuitWhenIdle(); - return syncer::SYNCER_OK; - } - - private: - bool quit_loop_when_run_; - base::WaitableEvent* was_run_; - DISALLOW_COPY_AND_ASSIGN(UIModelWorkerVisitor); -}; - -// A faux-syncer that only interacts with its model safe worker. -class Syncer { - public: - explicit Syncer(UIModelWorker* worker) : worker_(worker) {} - ~Syncer() {} - - void SyncShare(UIModelWorkerVisitor* visitor) { - // We wait until the callback is executed. So it is safe to use Unretained. - syncer::WorkCallback c = base::Bind(&UIModelWorkerVisitor::DoWork, - base::Unretained(visitor)); - worker_->DoWorkAndWaitUntilDone(c); - } - private: - scoped_refptr<UIModelWorker> worker_; - DISALLOW_COPY_AND_ASSIGN(Syncer); -}; - -class SyncUIModelWorkerTest : public testing::Test { - public: - SyncUIModelWorkerTest() : faux_syncer_thread_("FauxSyncerThread"), - faux_core_thread_("FauxCoreThread") { } - - void SetUp() override { - faux_syncer_thread_.Start(); - bmw_ = new UIModelWorker(base::ThreadTaskRunnerHandle::Get(), nullptr); - syncer_.reset(new Syncer(bmw_.get())); - } - - Syncer* syncer() { return syncer_.get(); } - UIModelWorker* bmw() { return bmw_.get(); } - base::Thread* core_thread() { return &faux_core_thread_; } - base::Thread* syncer_thread() { return &faux_syncer_thread_; } - private: - base::MessageLoop faux_ui_loop_; - base::Thread faux_syncer_thread_; - base::Thread faux_core_thread_; - scoped_refptr<UIModelWorker> bmw_; - std::unique_ptr<Syncer> syncer_; -}; - -TEST_F(SyncUIModelWorkerTest, ScheduledWorkRunsOnUILoop) { - base::WaitableEvent v_was_run( - base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED); - std::unique_ptr<UIModelWorkerVisitor> v( - new UIModelWorkerVisitor(&v_was_run, true)); - - syncer_thread()->task_runner()->PostTask( - FROM_HERE, - base::Bind(&Syncer::SyncShare, base::Unretained(syncer()), v.get())); - - // We are on the UI thread, so run our loop to process the - // (hopefully) scheduled task from a SyncShare invocation. - base::RunLoop().Run(); - syncer_thread()->Stop(); -}
diff --git a/components/sync_driver/invalidation_adapter.cc b/components/sync_driver/invalidation_adapter.cc deleted file mode 100644 index dcc14d6..0000000 --- a/components/sync_driver/invalidation_adapter.cc +++ /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. - -#include "components/sync_driver/invalidation_adapter.h" - -#include <string> - -namespace browser_sync { - -InvalidationAdapter::InvalidationAdapter( - const syncer::Invalidation& invalidation) - : invalidation_(invalidation) { -} - -InvalidationAdapter::~InvalidationAdapter() { -} - -bool InvalidationAdapter::IsUnknownVersion() const { - return invalidation_.is_unknown_version(); -} - -const std::string& InvalidationAdapter::GetPayload() const { - return invalidation_.payload(); -} - -int64_t InvalidationAdapter::GetVersion() const { - return invalidation_.version(); -} - -void InvalidationAdapter::Acknowledge() { - invalidation_.Acknowledge(); -} - -void InvalidationAdapter::Drop() { - invalidation_.Drop(); -} - -} // namespace browser_sync
diff --git a/components/sync_driver/invalidation_helper.cc b/components/sync_driver/invalidation_helper.cc deleted file mode 100644 index d60f947..0000000 --- a/components/sync_driver/invalidation_helper.cc +++ /dev/null
@@ -1,37 +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 "components/sync_driver/invalidation_helper.h" - -#include <string> - -#include "google/cacheinvalidation/types.pb.h" - -namespace syncer { - -bool RealModelTypeToObjectId(ModelType model_type, - invalidation::ObjectId* object_id) { - std::string notification_type; - if (!RealModelTypeToNotificationType(model_type, ¬ification_type)) { - return false; - } - object_id->Init(ipc::invalidation::ObjectSource::CHROME_SYNC, - notification_type); - return true; -} - -ObjectIdSet ModelTypeSetToObjectIdSet(ModelTypeSet model_types) { - ObjectIdSet ids; - for (ModelTypeSet::Iterator it = model_types.First(); it.Good(); it.Inc()) { - invalidation::ObjectId model_type_as_id; - if (!RealModelTypeToObjectId(it.Get(), &model_type_as_id)) { - DLOG(WARNING) << "Invalid model type " << it.Get(); - continue; - } - ids.insert(model_type_as_id); - } - return ids; -} - -} // namespace syncer
diff --git a/components/sync_driver/invalidation_helper.h b/components/sync_driver/invalidation_helper.h deleted file mode 100644 index 8f8adbe8..0000000 --- a/components/sync_driver/invalidation_helper.h +++ /dev/null
@@ -1,20 +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 COMPONENTS_SYNC_DRIVER_INVALIDATION_HELPER_H_ -#define COMPONENTS_SYNC_DRIVER_INVALIDATION_HELPER_H_ - -#include "components/invalidation/public/invalidation_util.h" -#include "components/sync/base/model_type.h" -#include "google/cacheinvalidation/include/types.h" - -namespace syncer { - -bool RealModelTypeToObjectId(ModelType model_type, - invalidation::ObjectId* object_id); - -ObjectIdSet ModelTypeSetToObjectIdSet(ModelTypeSet model_types); -} - -#endif // COMPONENTS_SYNC_DRIVER_INVALIDATION_HELPER_H_
diff --git a/components/sync_driver/local_device_info_provider_impl.cc b/components/sync_driver/local_device_info_provider_impl.cc deleted file mode 100644 index 70bbf51..0000000 --- a/components/sync_driver/local_device_info_provider_impl.cc +++ /dev/null
@@ -1,112 +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 "components/sync_driver/local_device_info_provider_impl.h" - -#include "base/bind.h" -#include "base/task_runner.h" -#include "build/build_config.h" -#include "components/sync/base/get_session_name.h" -#include "components/sync_driver/sync_util.h" - -namespace browser_sync { - -namespace { - -sync_pb::SyncEnums::DeviceType GetLocalDeviceType(bool is_tablet) { -#if defined(OS_CHROMEOS) - return sync_pb::SyncEnums_DeviceType_TYPE_CROS; -#elif defined(OS_LINUX) - return sync_pb::SyncEnums_DeviceType_TYPE_LINUX; -#elif defined(OS_ANDROID) || defined(OS_IOS) - return is_tablet ? sync_pb::SyncEnums_DeviceType_TYPE_TABLET - : sync_pb::SyncEnums_DeviceType_TYPE_PHONE; -#elif defined(OS_MACOSX) - return sync_pb::SyncEnums_DeviceType_TYPE_MAC; -#elif defined(OS_WIN) - return sync_pb::SyncEnums_DeviceType_TYPE_WIN; -#else - return sync_pb::SyncEnums_DeviceType_TYPE_OTHER; -#endif -} - -} // namespace - -LocalDeviceInfoProviderImpl::LocalDeviceInfoProviderImpl( - version_info::Channel channel, - const std::string& version, - bool is_tablet) - : channel_(channel), - version_(version), - is_tablet_(is_tablet), - weak_factory_(this) { - DCHECK(CalledOnValidThread()); -} - -LocalDeviceInfoProviderImpl::~LocalDeviceInfoProviderImpl() {} - -const sync_driver::DeviceInfo* LocalDeviceInfoProviderImpl::GetLocalDeviceInfo() - const { - DCHECK(CalledOnValidThread()); - return local_device_info_.get(); -} - -std::string LocalDeviceInfoProviderImpl::GetSyncUserAgent() const { - DCHECK(CalledOnValidThread()); - return MakeUserAgentForSync(channel_, is_tablet_); -} - -std::string LocalDeviceInfoProviderImpl::GetLocalSyncCacheGUID() const { - DCHECK(CalledOnValidThread()); - return cache_guid_; -} - -std::unique_ptr<sync_driver::LocalDeviceInfoProvider::Subscription> -LocalDeviceInfoProviderImpl::RegisterOnInitializedCallback( - const base::Closure& callback) { - DCHECK(CalledOnValidThread()); - DCHECK(!local_device_info_.get()); - return callback_list_.Add(callback); -} - -void LocalDeviceInfoProviderImpl::Initialize( - const std::string& cache_guid, - const std::string& signin_scoped_device_id, - const scoped_refptr<base::TaskRunner>& blocking_task_runner) { - DCHECK(CalledOnValidThread()); - DCHECK(!cache_guid.empty()); - cache_guid_ = cache_guid; - - syncer::GetSessionName( - blocking_task_runner, - base::Bind(&LocalDeviceInfoProviderImpl::InitializeContinuation, - weak_factory_.GetWeakPtr(), cache_guid, - signin_scoped_device_id)); -} - -void LocalDeviceInfoProviderImpl::InitializeContinuation( - const std::string& guid, - const std::string& signin_scoped_device_id, - const std::string& session_name) { - DCHECK(CalledOnValidThread()); - if (guid != cache_guid_) { - // Clear() happened before this callback; abort. - return; - } - - local_device_info_.reset(new sync_driver::DeviceInfo( - guid, session_name, version_, GetSyncUserAgent(), - GetLocalDeviceType(is_tablet_), signin_scoped_device_id)); - - // Notify observers. - callback_list_.Notify(); -} - -void LocalDeviceInfoProviderImpl::Clear() { - DCHECK(CalledOnValidThread()); - cache_guid_ = ""; - local_device_info_.reset(); -} - -} // namespace browser_sync
diff --git a/components/sync_driver/local_device_info_provider_impl.h b/components/sync_driver/local_device_info_provider_impl.h deleted file mode 100644 index c146784b..0000000 --- a/components/sync_driver/local_device_info_provider_impl.h +++ /dev/null
@@ -1,65 +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 COMPONENTS_SYNC_DRIVER_LOCAL_DEVICE_INFO_PROVIDER_IMPL_H_ -#define COMPONENTS_SYNC_DRIVER_LOCAL_DEVICE_INFO_PROVIDER_IMPL_H_ - -#include <string> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/threading/non_thread_safe.h" -#include "components/sync_driver/device_info.h" -#include "components/sync_driver/local_device_info_provider.h" -#include "components/version_info/version_info.h" - -namespace browser_sync { - -class LocalDeviceInfoProviderImpl - : public sync_driver::LocalDeviceInfoProvider, - public base::NonThreadSafe { - public: - LocalDeviceInfoProviderImpl(version_info::Channel channel, - const std::string& version, - bool is_tablet); - ~LocalDeviceInfoProviderImpl() override; - - // LocalDeviceInfoProvider implementation. - const sync_driver::DeviceInfo* GetLocalDeviceInfo() const override; - std::string GetSyncUserAgent() const override; - std::string GetLocalSyncCacheGUID() const override; - void Initialize( - const std::string& cache_guid, - const std::string& signin_scoped_device_id, - const scoped_refptr<base::TaskRunner>& blocking_task_runner) override; - std::unique_ptr<Subscription> RegisterOnInitializedCallback( - const base::Closure& callback) override; - void Clear() override; - - private: - void InitializeContinuation(const std::string& guid, - const std::string& signin_scoped_device_id, - const std::string& session_name); - - // The channel (CANARY, DEV, BETA, etc.) of the current client. - const version_info::Channel channel_; - - // The version string for the current client. - const std::string version_; - - // Whether this device has a tablet form factor (only used on Android - // devices). - const bool is_tablet_; - - std::string cache_guid_; - std::unique_ptr<sync_driver::DeviceInfo> local_device_info_; - base::CallbackList<void(void)> callback_list_; - base::WeakPtrFactory<LocalDeviceInfoProviderImpl> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(LocalDeviceInfoProviderImpl); -}; - -} // namespace browser_sync - -#endif // COMPONENTS_SYNC_DRIVER_LOCAL_DEVICE_INFO_PROVIDER_IMPL_H_
diff --git a/components/sync_driver/local_device_info_provider_mock.cc b/components/sync_driver/local_device_info_provider_mock.cc deleted file mode 100644 index 3ab5ce9..0000000 --- a/components/sync_driver/local_device_info_provider_mock.cc +++ /dev/null
@@ -1,79 +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 "components/sync_driver/local_device_info_provider_mock.h" - -namespace sync_driver { - -LocalDeviceInfoProviderMock::LocalDeviceInfoProviderMock() - : is_initialized_(false) {} - -LocalDeviceInfoProviderMock::LocalDeviceInfoProviderMock( - const std::string& guid, - const std::string& client_name, - const std::string& chrome_version, - const std::string& sync_user_agent, - const sync_pb::SyncEnums::DeviceType device_type, - const std::string& signin_scoped_device_id) - : is_initialized_(true) { - local_device_info_.reset( - new DeviceInfo( - guid, - client_name, - chrome_version, - sync_user_agent, - device_type, - signin_scoped_device_id)); -} - -LocalDeviceInfoProviderMock::~LocalDeviceInfoProviderMock() {} - -const DeviceInfo* LocalDeviceInfoProviderMock::GetLocalDeviceInfo() const { - return is_initialized_ ? local_device_info_.get() : nullptr; -} - -std::string LocalDeviceInfoProviderMock::GetSyncUserAgent() const { - return "useragent"; -} - -std::string LocalDeviceInfoProviderMock::GetLocalSyncCacheGUID() const { - return local_device_info_.get() ? local_device_info_->guid() : ""; -} - -void LocalDeviceInfoProviderMock::Initialize( - const std::string& cache_guid, - const std::string& signin_scoped_device_id, - const scoped_refptr<base::TaskRunner>& blocking_task_runner) { - local_device_info_.reset(new DeviceInfo( - cache_guid, "client_name", "chrome_version", GetSyncUserAgent(), - sync_pb::SyncEnums_DeviceType_TYPE_LINUX, signin_scoped_device_id)); - SetInitialized(true); -} - -void LocalDeviceInfoProviderMock::Initialize( - std::unique_ptr<DeviceInfo> local_device_info) { - local_device_info_.swap(local_device_info); - SetInitialized(true); -} - -std::unique_ptr<LocalDeviceInfoProvider::Subscription> -LocalDeviceInfoProviderMock::RegisterOnInitializedCallback( - const base::Closure& callback) { - DCHECK(!is_initialized_); - return callback_list_.Add(callback); -} - -void LocalDeviceInfoProviderMock::Clear() { - local_device_info_.reset(); - is_initialized_ = false; -} - -void LocalDeviceInfoProviderMock::SetInitialized(bool is_initialized) { - is_initialized_ = is_initialized; - if (is_initialized_) { - callback_list_.Notify(); - } -} - -} // namespace sync_driver
diff --git a/components/sync_driver/local_device_info_provider_mock.h b/components/sync_driver/local_device_info_provider_mock.h deleted file mode 100644 index 3aec235d..0000000 --- a/components/sync_driver/local_device_info_provider_mock.h +++ /dev/null
@@ -1,53 +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 COMPONENTS_SYNC_DRIVER_LOCAL_DEVICE_INFO_PROVIDER_MOCK_H_ -#define COMPONENTS_SYNC_DRIVER_LOCAL_DEVICE_INFO_PROVIDER_MOCK_H_ - -#include <string> - -#include "components/sync_driver/device_info.h" -#include "components/sync_driver/local_device_info_provider.h" - -namespace sync_driver { - -class LocalDeviceInfoProviderMock - : public sync_driver::LocalDeviceInfoProvider { - public: - // Creates uninitialized provider. - LocalDeviceInfoProviderMock(); - // Creates initialized provider with the specified device info. - LocalDeviceInfoProviderMock( - const std::string& guid, - const std::string& client_name, - const std::string& chrome_version, - const std::string& sync_user_agent, - const sync_pb::SyncEnums::DeviceType device_type, - const std::string& signin_scoped_device_id); - ~LocalDeviceInfoProviderMock() override; - - const DeviceInfo* GetLocalDeviceInfo() const override; - std::string GetSyncUserAgent() const override; - std::string GetLocalSyncCacheGUID() const override; - void Initialize( - const std::string& cache_guid, - const std::string& signin_scoped_device_id, - const scoped_refptr<base::TaskRunner>& blocking_task_runner) override; - std::unique_ptr<Subscription> RegisterOnInitializedCallback( - const base::Closure& callback) override; - void Clear() override; - - void Initialize(std::unique_ptr<DeviceInfo> local_device_info); - void SetInitialized(bool is_initialized); - - private: - bool is_initialized_; - - std::unique_ptr<DeviceInfo> local_device_info_; - base::CallbackList<void(void)> callback_list_; -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_LOCAL_DEVICE_INFO_PROVIDER_MOCK_H_
diff --git a/components/sync_driver/local_device_info_provider_unittest.cc b/components/sync_driver/local_device_info_provider_unittest.cc deleted file mode 100644 index 7712ec2..0000000 --- a/components/sync_driver/local_device_info_provider_unittest.cc +++ /dev/null
@@ -1,146 +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 "base/bind.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "components/sync/base/get_session_name.h" -#include "components/sync_driver/local_device_info_provider_impl.h" -#include "components/version_info/version_info.h" -#include "testing/gtest/include/gtest/gtest.h" - -using sync_driver::DeviceInfo; -using sync_driver::LocalDeviceInfoProvider; - -namespace browser_sync { - -const char kLocalDeviceGuid[] = "foo"; -const char kSigninScopedDeviceId[] = "device_id"; - -class LocalDeviceInfoProviderTest : public testing::Test { - public: - LocalDeviceInfoProviderTest() : called_back_(false) {} - ~LocalDeviceInfoProviderTest() override {} - - void SetUp() override { - provider_.reset(new LocalDeviceInfoProviderImpl( - version_info::Channel::UNKNOWN, - version_info::GetVersionStringWithModifier("UNKNOWN"), false)); - } - - void TearDown() override { - provider_.reset(); - called_back_ = false; - } - - protected: - void StartInitializeProvider() { StartInitializeProvider(kLocalDeviceGuid); } - - void StartInitializeProvider(const std::string& guid) { - provider_->Initialize(guid, kSigninScopedDeviceId, - message_loop_.task_runner()); - } - - void FinishInitializeProvider() { - // Subscribe to the notification and wait until the callback - // is called. The callback will quit the loop. - base::RunLoop run_loop; - std::unique_ptr<LocalDeviceInfoProvider::Subscription> subscription = - provider_->RegisterOnInitializedCallback( - base::Bind(&LocalDeviceInfoProviderTest::QuitLoopOnInitialized, - base::Unretained(this), &run_loop)); - run_loop.Run(); - } - - void InitializeProvider() { - StartInitializeProvider(); - FinishInitializeProvider(); - } - - void QuitLoopOnInitialized(base::RunLoop* loop) { - called_back_ = true; - loop->Quit(); - } - - std::unique_ptr<LocalDeviceInfoProviderImpl> provider_; - - bool called_back_; - - private: - base::MessageLoop message_loop_; -}; - -TEST_F(LocalDeviceInfoProviderTest, OnInitializedCallback) { - ASSERT_FALSE(called_back_); - StartInitializeProvider(); - ASSERT_FALSE(called_back_); - FinishInitializeProvider(); - EXPECT_TRUE(called_back_); -} - -TEST_F(LocalDeviceInfoProviderTest, GetLocalDeviceInfo) { - ASSERT_EQ(nullptr, provider_->GetLocalDeviceInfo()); - StartInitializeProvider(); - ASSERT_EQ(nullptr, provider_->GetLocalDeviceInfo()); - FinishInitializeProvider(); - - const DeviceInfo* local_device_info = provider_->GetLocalDeviceInfo(); - ASSERT_NE(nullptr, local_device_info); - EXPECT_EQ(std::string(kLocalDeviceGuid), local_device_info->guid()); - EXPECT_EQ(std::string(kSigninScopedDeviceId), - local_device_info->signin_scoped_device_id()); - EXPECT_EQ(syncer::GetSessionNameSynchronouslyForTesting(), - local_device_info->client_name()); - - EXPECT_EQ(provider_->GetSyncUserAgent(), - local_device_info->sync_user_agent()); - - provider_->Clear(); - ASSERT_EQ(nullptr, provider_->GetLocalDeviceInfo()); -} - -TEST_F(LocalDeviceInfoProviderTest, GetLocalSyncCacheGUID) { - EXPECT_TRUE(provider_->GetLocalSyncCacheGUID().empty()); - - StartInitializeProvider(); - EXPECT_EQ(std::string(kLocalDeviceGuid), provider_->GetLocalSyncCacheGUID()); - - FinishInitializeProvider(); - EXPECT_EQ(std::string(kLocalDeviceGuid), provider_->GetLocalSyncCacheGUID()); - - provider_->Clear(); - EXPECT_TRUE(provider_->GetLocalSyncCacheGUID().empty()); -} - -TEST_F(LocalDeviceInfoProviderTest, InitClearRace) { - EXPECT_TRUE(provider_->GetLocalSyncCacheGUID().empty()); - StartInitializeProvider(); - - provider_->Clear(); - ASSERT_EQ(nullptr, provider_->GetLocalDeviceInfo()); - EXPECT_TRUE(provider_->GetLocalSyncCacheGUID().empty()); - - base::RunLoop().RunUntilIdle(); - ASSERT_EQ(nullptr, provider_->GetLocalDeviceInfo()); - EXPECT_TRUE(provider_->GetLocalSyncCacheGUID().empty()); -} - -TEST_F(LocalDeviceInfoProviderTest, InitClearInitRace) { - EXPECT_TRUE(provider_->GetLocalSyncCacheGUID().empty()); - StartInitializeProvider(); - provider_->Clear(); - - const std::string guid2 = "guid2"; - StartInitializeProvider(guid2); - ASSERT_EQ(nullptr, provider_->GetLocalDeviceInfo()); - EXPECT_EQ(guid2, provider_->GetLocalSyncCacheGUID()); - - FinishInitializeProvider(); - const DeviceInfo* local_device_info = provider_->GetLocalDeviceInfo(); - ASSERT_NE(nullptr, local_device_info); - EXPECT_EQ(guid2, local_device_info->guid()); - EXPECT_EQ(guid2, provider_->GetLocalSyncCacheGUID()); -} - -} // namespace browser_sync
diff --git a/components/sync_driver/model_association_manager.cc b/components/sync_driver/model_association_manager.cc deleted file mode 100644 index 0c69b7b..0000000 --- a/components/sync_driver/model_association_manager.cc +++ /dev/null
@@ -1,462 +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 "components/sync_driver/model_association_manager.h" - -#include <stddef.h> -#include <stdint.h> - -#include <algorithm> -#include <functional> - -#include "base/logging.h" -#include "base/macros.h" -#include "base/message_loop/message_loop.h" -#include "base/metrics/histogram_macros.h" -#include "base/trace_event/trace_event.h" -#include "components/sync/api/sync_merge_result.h" -#include "components/sync/base/model_type.h" - -using syncer::ModelTypeSet; - -namespace sync_driver { - -namespace { - -static const syncer::ModelType kStartOrder[] = { - syncer::NIGORI, // Listed for completeness. - syncer::DEVICE_INFO, // Listed for completeness. - syncer::EXPERIMENTS, // Listed for completeness. - syncer::PROXY_TABS, // Listed for completeness. - - // Kick off the association of the non-UI types first so they can associate - // in parallel with the UI types. - syncer::PASSWORDS, - syncer::AUTOFILL, - syncer::AUTOFILL_PROFILE, - syncer::AUTOFILL_WALLET_DATA, - syncer::AUTOFILL_WALLET_METADATA, - syncer::EXTENSION_SETTINGS, - syncer::APP_SETTINGS, - syncer::TYPED_URLS, - syncer::HISTORY_DELETE_DIRECTIVES, - syncer::SYNCED_NOTIFICATIONS, - syncer::SYNCED_NOTIFICATION_APP_INFO, - - // UI thread data types. - syncer::BOOKMARKS, - syncer::SUPERVISED_USERS, // Syncing supervised users on initial login - // might block creating a new supervised user, - // so we want to do it early. - syncer::PREFERENCES, - syncer::PRIORITY_PREFERENCES, - syncer::EXTENSIONS, - syncer::APPS, - syncer::APP_LIST, - syncer::ARC_PACKAGE, - syncer::THEMES, - syncer::SEARCH_ENGINES, - syncer::SESSIONS, - syncer::APP_NOTIFICATIONS, - syncer::DICTIONARY, - syncer::FAVICON_IMAGES, - syncer::FAVICON_TRACKING, - syncer::SUPERVISED_USER_SETTINGS, - syncer::SUPERVISED_USER_SHARED_SETTINGS, - syncer::SUPERVISED_USER_WHITELISTS, - syncer::ARTICLES, - syncer::WIFI_CREDENTIALS, -}; - -static_assert(arraysize(kStartOrder) == - syncer::MODEL_TYPE_COUNT - syncer::FIRST_REAL_MODEL_TYPE, - "kStartOrder must have MODEL_TYPE_COUNT - " - "FIRST_REAL_MODEL_TYPE elements"); - -// The amount of time we wait for association to finish. If some types haven't -// finished association by the time, DataTypeManager is notified of the -// unfinished types. -const int64_t kAssociationTimeOutInSeconds = 600; - -syncer::DataTypeAssociationStats BuildAssociationStatsFromMergeResults( - const syncer::SyncMergeResult& local_merge_result, - const syncer::SyncMergeResult& syncer_merge_result, - const base::TimeDelta& association_wait_time, - const base::TimeDelta& association_time) { - DCHECK_EQ(local_merge_result.model_type(), syncer_merge_result.model_type()); - syncer::DataTypeAssociationStats stats; - stats.had_error = local_merge_result.error().IsSet() || - syncer_merge_result.error().IsSet(); - stats.num_local_items_before_association = - local_merge_result.num_items_before_association(); - stats.num_sync_items_before_association = - syncer_merge_result.num_items_before_association(); - stats.num_local_items_after_association = - local_merge_result.num_items_after_association(); - stats.num_sync_items_after_association = - syncer_merge_result.num_items_after_association(); - stats.num_local_items_added = - local_merge_result.num_items_added(); - stats.num_local_items_deleted = - local_merge_result.num_items_deleted(); - stats.num_local_items_modified = - local_merge_result.num_items_modified(); - stats.local_version_pre_association = - local_merge_result.pre_association_version(); - stats.num_sync_items_added = - syncer_merge_result.num_items_added(); - stats.num_sync_items_deleted = - syncer_merge_result.num_items_deleted(); - stats.num_sync_items_modified = - syncer_merge_result.num_items_modified(); - stats.sync_version_pre_association = - syncer_merge_result.pre_association_version(); - stats.association_wait_time = association_wait_time; - stats.association_time = association_time; - return stats; -} - -} // namespace - -ModelAssociationManager::ModelAssociationManager( - const DataTypeController::TypeMap* controllers, - ModelAssociationManagerDelegate* processor) - : state_(IDLE), - controllers_(controllers), - delegate_(processor), - configure_status_(DataTypeManager::UNKNOWN), - notified_about_ready_for_configure_(false), - weak_ptr_factory_(this) { - // Ensure all data type controllers are stopped. - for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); - it != controllers_->end(); ++it) { - DCHECK_EQ(DataTypeController::NOT_RUNNING, (*it).second->state()); - } -} - -ModelAssociationManager::~ModelAssociationManager() { -} - -void ModelAssociationManager::Initialize(syncer::ModelTypeSet desired_types) { - // state_ can be INITIALIZED if types are reconfigured when - // data is being downloaded, so StartAssociationAsync() is never called for - // the first configuration. - DCHECK_NE(ASSOCIATING, state_); - - // Only keep types that have controllers. - desired_types_.Clear(); - for (syncer::ModelTypeSet::Iterator it = desired_types.First(); - it.Good(); it.Inc()) { - if (controllers_->find(it.Get()) != controllers_->end()) - desired_types_.Put(it.Get()); - } - - DVLOG(1) << "ModelAssociationManager: Initializing for " - << syncer::ModelTypeSetToString(desired_types_); - - state_ = INITIALIZED; - notified_about_ready_for_configure_ = false; - - StopDisabledTypes(); - LoadEnabledTypes(); -} - -void ModelAssociationManager::StopDatatype( - const syncer::SyncError& error, - DataTypeController* dtc) { - loaded_types_.Remove(dtc->type()); - associated_types_.Remove(dtc->type()); - associating_types_.Remove(dtc->type()); - - if (error.IsSet() || dtc->state() != DataTypeController::NOT_RUNNING) { - // If an error was set, the delegate must be informed of the error. - delegate_->OnSingleDataTypeWillStop(dtc->type(), error); - dtc->Stop(); - } -} - -void ModelAssociationManager::StopDisabledTypes() { - DVLOG(1) << "ModelAssociationManager: Stopping disabled types."; - for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); - it != controllers_->end(); ++it) { - DataTypeController* dtc = (*it).second.get(); - if (dtc->state() != DataTypeController::NOT_RUNNING && - !desired_types_.Has(dtc->type())) { - DVLOG(1) << "ModelAssociationManager: stop " << dtc->name(); - StopDatatype(syncer::SyncError(), dtc); - } - } -} - -void ModelAssociationManager::LoadEnabledTypes() { - // Load in kStartOrder. - for (size_t i = 0; i < arraysize(kStartOrder); i++) { - syncer::ModelType type = kStartOrder[i]; - if (!desired_types_.Has(type)) - continue; - - DCHECK(controllers_->find(type) != controllers_->end()); - DataTypeController* dtc = controllers_->find(type)->second.get(); - if (dtc->state() == DataTypeController::NOT_RUNNING) { - DCHECK(!loaded_types_.Has(dtc->type())); - DCHECK(!associated_types_.Has(dtc->type())); - dtc->LoadModels(base::Bind(&ModelAssociationManager::ModelLoadCallback, - weak_ptr_factory_.GetWeakPtr())); - } - } - NotifyDelegateIfReadyForConfigure(); -} - -void ModelAssociationManager::StartAssociationAsync( - const syncer::ModelTypeSet& types_to_associate) { - DCHECK_EQ(INITIALIZED, state_); - DVLOG(1) << "Starting association for " - << syncer::ModelTypeSetToString(types_to_associate); - state_ = ASSOCIATING; - - association_start_time_ = base::TimeTicks::Now(); - - requested_types_ = types_to_associate; - - associating_types_ = types_to_associate; - associating_types_.RetainAll(desired_types_); - associating_types_.RemoveAll(associated_types_); - - // Assume success. - configure_status_ = DataTypeManager::OK; - - // Done if no types to associate. - if (associating_types_.Empty()) { - ModelAssociationDone(INITIALIZED); - return; - } - - timer_.Start(FROM_HERE, - base::TimeDelta::FromSeconds(kAssociationTimeOutInSeconds), - base::Bind(&ModelAssociationManager::ModelAssociationDone, - weak_ptr_factory_.GetWeakPtr(), - INITIALIZED)); - - // Start association of types that are loaded in specified order. - for (size_t i = 0; i < arraysize(kStartOrder); i++) { - syncer::ModelType type = kStartOrder[i]; - if (!associating_types_.Has(type) || !loaded_types_.Has(type)) - continue; - - DataTypeController* dtc = controllers_->find(type)->second.get(); - DCHECK(DataTypeController::MODEL_LOADED == dtc->state() || - DataTypeController::ASSOCIATING == dtc->state()); - if (dtc->state() == DataTypeController::MODEL_LOADED) { - TRACE_EVENT_ASYNC_BEGIN1("sync", "ModelAssociation", - dtc, - "DataType", - ModelTypeToString(type)); - - dtc->StartAssociating( - base::Bind(&ModelAssociationManager::TypeStartCallback, - weak_ptr_factory_.GetWeakPtr(), - type, base::TimeTicks::Now())); - } - } -} - -void ModelAssociationManager::Stop() { - // Ignore callbacks from controllers. - weak_ptr_factory_.InvalidateWeakPtrs(); - - // Stop started data types. - for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); - it != controllers_->end(); ++it) { - DataTypeController* dtc = (*it).second.get(); - if (dtc->state() != DataTypeController::NOT_RUNNING) { - StopDatatype(syncer::SyncError(), dtc); - DVLOG(1) << "ModelAssociationManager: Stopped " << dtc->name(); - } - } - - desired_types_.Clear(); - loaded_types_.Clear(); - associated_types_.Clear(); - - if (state_ == ASSOCIATING) { - if (configure_status_ == DataTypeManager::OK) - configure_status_ = DataTypeManager::ABORTED; - DVLOG(1) << "ModelAssociationManager: Calling OnModelAssociationDone"; - ModelAssociationDone(IDLE); - } else { - DCHECK(associating_types_.Empty()); - DCHECK(requested_types_.Empty()); - state_ = IDLE; - } -} - -void ModelAssociationManager::ModelLoadCallback(syncer::ModelType type, - syncer::SyncError error) { - DVLOG(1) << "ModelAssociationManager: ModelLoadCallback for " - << syncer::ModelTypeToString(type); - - if (error.IsSet()) { - syncer::SyncMergeResult local_merge_result(type); - local_merge_result.set_error(error); - TypeStartCallback(type, - base::TimeTicks::Now(), - DataTypeController::ASSOCIATION_FAILED, - local_merge_result, - syncer::SyncMergeResult(type)); - return; - } - - // This happens when slow loading type is disabled by new configuration. - if (!desired_types_.Has(type)) - return; - - DCHECK(!loaded_types_.Has(type)); - loaded_types_.Put(type); - NotifyDelegateIfReadyForConfigure(); - if (associating_types_.Has(type)) { - DataTypeController* dtc = controllers_->find(type)->second.get(); - // If initial sync was done for this datatype then - // NotifyDelegateIfReadyForConfigure possibly already triggered model - // association and StartAssociating was already called for this type. To - // ensure StartAssociating is called only once only make a call if state is - // MODEL_LOADED. - // TODO(pavely): Add test for this scenario in DataTypeManagerImpl - // unittests. - if (dtc->state() == DataTypeController::MODEL_LOADED) { - dtc->StartAssociating(base::Bind( - &ModelAssociationManager::TypeStartCallback, - weak_ptr_factory_.GetWeakPtr(), type, base::TimeTicks::Now())); - } - } -} - -void ModelAssociationManager::TypeStartCallback( - syncer::ModelType type, - base::TimeTicks type_start_time, - DataTypeController::ConfigureResult start_result, - const syncer::SyncMergeResult& local_merge_result, - const syncer::SyncMergeResult& syncer_merge_result) { - if (desired_types_.Has(type) && - !DataTypeController::IsSuccessfulResult(start_result)) { - DVLOG(1) << "ModelAssociationManager: Type encountered an error."; - desired_types_.Remove(type); - DataTypeController* dtc = controllers_->find(type)->second.get(); - StopDatatype(local_merge_result.error(), dtc); - NotifyDelegateIfReadyForConfigure(); - - // Update configuration result. - if (start_result == DataTypeController::UNRECOVERABLE_ERROR) - configure_status_ = DataTypeManager::UNRECOVERABLE_ERROR; - } - - // This happens when a slow associating type is disabled or if a type - // disables itself after initial configuration. - if (!desired_types_.Has(type)) { - // It's possible all types failed to associate, in which case association - // is complete. - if (state_ == ASSOCIATING && associating_types_.Empty()) - ModelAssociationDone(INITIALIZED); - return; - } - - DCHECK(!associated_types_.Has(type)); - DCHECK(DataTypeController::IsSuccessfulResult(start_result)); - associated_types_.Put(type); - - if (state_ != ASSOCIATING) - return; - - TRACE_EVENT_ASYNC_END1("sync", "ModelAssociation", - controllers_->find(type)->second.get(), - "DataType", - ModelTypeToString(type)); - - // Track the merge results if we succeeded or an association failure - // occurred. - if (syncer::ProtocolTypes().Has(type)) { - base::TimeDelta association_wait_time = - std::max(base::TimeDelta(), type_start_time - association_start_time_); - base::TimeDelta association_time = - base::TimeTicks::Now() - type_start_time; - syncer::DataTypeAssociationStats stats = - BuildAssociationStatsFromMergeResults(local_merge_result, - syncer_merge_result, - association_wait_time, - association_time); - delegate_->OnSingleDataTypeAssociationDone(type, stats); - } - - associating_types_.Remove(type); - - if (associating_types_.Empty()) - ModelAssociationDone(INITIALIZED); -} - -void ModelAssociationManager::ModelAssociationDone(State new_state) { - DCHECK_NE(IDLE, state_); - - if (state_ == INITIALIZED) { - // No associations are currently happening. Just reset the state. - state_ = new_state; - return; - } - - DVLOG(1) << "Model association complete for " - << syncer::ModelTypeSetToString(requested_types_); - - timer_.Stop(); - - // Treat any unfinished types as having errors. - desired_types_.RemoveAll(associating_types_); - for (DataTypeController::TypeMap::const_iterator it = controllers_->begin(); - it != controllers_->end(); ++it) { - DataTypeController* dtc = (*it).second.get(); - if (associating_types_.Has(dtc->type()) && - dtc->state() != DataTypeController::NOT_RUNNING) { - UMA_HISTOGRAM_ENUMERATION("Sync.ConfigureFailed", - ModelTypeToHistogramInt(dtc->type()), - syncer::MODEL_TYPE_COUNT); - StopDatatype(syncer::SyncError(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Association timed out.", - dtc->type()), - dtc); - } - } - - DataTypeManager::ConfigureResult result(configure_status_, - requested_types_); - - // Need to reset state before invoking delegate in order to avoid re-entrancy - // issues (delegate may trigger a reconfiguration). - associating_types_.Clear(); - requested_types_.Clear(); - state_ = new_state; - - delegate_->OnModelAssociationDone(result); -} - -base::OneShotTimer* ModelAssociationManager::GetTimerForTesting() { - return &timer_; -} - -void ModelAssociationManager::NotifyDelegateIfReadyForConfigure() { - if (notified_about_ready_for_configure_) - return; - for (const auto& type_dtc_pair : *controllers_) { - syncer::ModelType type = type_dtc_pair.first; - if (!desired_types_.Has(type)) - continue; - DataTypeController* dtc = type_dtc_pair.second.get(); - if (dtc->ShouldLoadModelBeforeConfigure() && !loaded_types_.Has(type)) { - // At least one type is not ready. - return; - } - } - - notified_about_ready_for_configure_ = true; - delegate_->OnAllDataTypesReadyForConfigure(); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/model_association_manager.h b/components/sync_driver/model_association_manager.h deleted file mode 100644 index 46f14829..0000000 --- a/components/sync_driver/model_association_manager.h +++ /dev/null
@@ -1,182 +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 COMPONENTS_SYNC_DRIVER_MODEL_ASSOCIATION_MANAGER_H__ -#define COMPONENTS_SYNC_DRIVER_MODEL_ASSOCIATION_MANAGER_H__ - -#include <map> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/timer/timer.h" - -#include "components/sync/base/weak_handle.h" -#include "components/sync/core/data_type_association_stats.h" -#include "components/sync_driver/data_type_manager.h" - -namespace sync_driver { - -class DataTypeController; - -// |ModelAssociationManager| does the heavy lifting for doing the actual model -// association. It instructs DataTypeControllers to load models, start -// associating and stopping. Since the operations are async it uses an -// interface to inform DataTypeManager the results of the operations. -// This class is owned by DataTypeManager. -// |ModelAssociationManager| association functions are async. The results of -// those operations are passed back via this interface. -class ModelAssociationManagerDelegate { - public: - // Called when all desired types are ready to be configured with - // BackendDataTypeConfigurer. Data type is ready when its progress marker is - // available to configurer. Directory data types are always ready, their - // progress markers are read from directory. USS data type controllers need to - // load model and read data type context first. - // This function is called at most once after each call to - // ModelAssociationManager::Initialize(). - virtual void OnAllDataTypesReadyForConfigure() = 0; - - // Called when model association (MergeDataAndStartSyncing) has completed - // for |type|, regardless of success or failure. - virtual void OnSingleDataTypeAssociationDone( - syncer::ModelType type, - const syncer::DataTypeAssociationStats& association_stats) = 0; - - // Called when the ModelAssociationManager has decided it must stop |type|, - // likely because it is no longer a desired data type or sync is shutting - // down. - virtual void OnSingleDataTypeWillStop(syncer::ModelType type, - const syncer::SyncError& error) = 0; - - // Called when the ModelAssociationManager has tried to perform model - // association for all desired types and has nothing left to do. - virtual void OnModelAssociationDone( - const DataTypeManager::ConfigureResult& result) = 0; - virtual ~ModelAssociationManagerDelegate() {} -}; - -// The class that is responsible for model association. -class ModelAssociationManager { - public: - enum State { - // No configuration is in progress. - IDLE, - // The model association manager has been initialized with a set of desired - // types, but is not actively associating any. - INITIALIZED, - // One or more types from |desired_types_| are in the process of - // associating. - ASSOCIATING, - }; - - ModelAssociationManager(const DataTypeController::TypeMap* controllers, - ModelAssociationManagerDelegate* delegate); - virtual ~ModelAssociationManager(); - - // Initializes the state to do the model association in future. This - // should be called before communicating with sync server. A subsequent call - // of Initialize is only allowed if the ModelAssociationManager has invoked - // |OnModelAssociationDone| on the |ModelAssociationManagerDelegate|. After - // this call, there should be several calls to StartAssociationAsync() - // to associate subset of |desired_types|. - void Initialize(syncer::ModelTypeSet desired_types); - - // Can be called at any time. Synchronously stops all datatypes. - void Stop(); - - // Should only be called after Initialize to start the actual association. - // |types_to_associate| should be subset of |desired_types| in Initialize(). - // When this is completed, |OnModelAssociationDone| will be invoked. - void StartAssociationAsync(const syncer::ModelTypeSet& types_to_associate); - - // This is used for TESTING PURPOSE ONLY. The test case can inspect - // and modify the timer. - // TODO(sync) : This would go away if we made this class be able to do - // Dependency injection. crbug.com/129212. - base::OneShotTimer* GetTimerForTesting(); - - State state() const { return state_; } - - private: - // Called at the end of association to reset state to prepare for next - // round of association. - void ResetForNextAssociation(); - - // Called by Initialize() to stop types that are not in |desired_types_|. - void StopDisabledTypes(); - - // Start loading non-running types that are in |desired_types_|. - void LoadEnabledTypes(); - - // Callback passed to each data type controller on starting association. This - // callback will be invoked when the model association is done. - void TypeStartCallback(syncer::ModelType type, - base::TimeTicks type_start_time, - DataTypeController::ConfigureResult start_result, - const syncer::SyncMergeResult& local_merge_result, - const syncer::SyncMergeResult& syncer_merge_result); - - // Callback that will be invoked when the models finish loading. This callback - // will be passed to |LoadModels| function. - void ModelLoadCallback(syncer::ModelType type, syncer::SyncError error); - - // Called when all requested types are associated or association times out. - // Will clean up any unfinished types, and update |state_| to be |new_state| - // Finally, it will notify |delegate_| of the configuration result. - void ModelAssociationDone(State new_state); - - // A helper to stop an individual datatype. - void StopDatatype(const syncer::SyncError& error, DataTypeController* dtc); - - // Calls delegate's OnAllDataTypesReadyForConfigure when all datatypes from - // desired_types_ are ready for configure. Ensures that for every call to - // Initialize callback is called at most once. - // Datatype is ready if either it doesn't require LoadModels before configure - // or LoadModels successfully finished. - void NotifyDelegateIfReadyForConfigure(); - - State state_; - - // Data types that are enabled. - syncer::ModelTypeSet desired_types_; - - // Data types that are requested to associate. - syncer::ModelTypeSet requested_types_; - - // Data types currently being associated, including types waiting for model - // load. - syncer::ModelTypeSet associating_types_; - - // Data types that are loaded, i.e. ready to associate. - syncer::ModelTypeSet loaded_types_; - - // Data types that are associated, i.e. no more action needed during - // reconfiguration if not disabled. - syncer::ModelTypeSet associated_types_; - - // Time when StartAssociationAsync() is called to associate for a set of data - // types. - base::TimeTicks association_start_time_; - - // Set of all registered controllers. - const DataTypeController::TypeMap* controllers_; - - // The processor in charge of handling model association results. - ModelAssociationManagerDelegate* delegate_; - - // Timer to track and limit how long a datatype takes to model associate. - base::OneShotTimer timer_; - - DataTypeManager::ConfigureStatus configure_status_; - - bool notified_about_ready_for_configure_; - - base::WeakPtrFactory<ModelAssociationManager> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(ModelAssociationManager); -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_MODEL_ASSOCIATION_MANAGER_H__
diff --git a/components/sync_driver/model_association_manager_unittest.cc b/components/sync_driver/model_association_manager_unittest.cc deleted file mode 100644 index f573752..0000000 --- a/components/sync_driver/model_association_manager_unittest.cc +++ /dev/null
@@ -1,527 +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 "components/sync_driver/model_association_manager.h" - -#include "base/callback.h" -#include "base/message_loop/message_loop.h" -#include "components/sync_driver/fake_data_type_controller.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using ::testing::_; - -namespace sync_driver { - -class MockModelAssociationManagerDelegate : - public ModelAssociationManagerDelegate { - public: - MockModelAssociationManagerDelegate() {} - ~MockModelAssociationManagerDelegate() {} - MOCK_METHOD0(OnAllDataTypesReadyForConfigure, void()); - MOCK_METHOD2(OnSingleDataTypeAssociationDone, - void(syncer::ModelType type, - const syncer::DataTypeAssociationStats& association_stats)); - MOCK_METHOD2(OnSingleDataTypeWillStop, - void(syncer::ModelType, const syncer::SyncError& error)); - MOCK_METHOD1(OnModelAssociationDone, void( - const DataTypeManager::ConfigureResult& result)); -}; - -FakeDataTypeController* GetController( - const DataTypeController::TypeMap& controllers, - syncer::ModelType model_type) { - DataTypeController::TypeMap::const_iterator it = - controllers.find(model_type); - if (it == controllers.end()) { - return NULL; - } - return static_cast<FakeDataTypeController*>(it->second.get()); -} - -ACTION_P(VerifyResult, expected_result) { - EXPECT_EQ(arg0.status, expected_result.status); - EXPECT_EQ(expected_result.requested_types, arg0.requested_types); -} - -class SyncModelAssociationManagerTest : public testing::Test { - public: - SyncModelAssociationManagerTest() { - } - - protected: - base::MessageLoopForUI ui_loop_; - MockModelAssociationManagerDelegate delegate_; - DataTypeController::TypeMap controllers_; -}; - -// Start a type and make sure ModelAssociationManager callst the |Start| -// method and calls the callback when it is done. -TEST_F(SyncModelAssociationManagerTest, SimpleModelStart) { - controllers_[syncer::BOOKMARKS] = - new FakeDataTypeController(syncer::BOOKMARKS); - controllers_[syncer::APPS] = - new FakeDataTypeController(syncer::APPS); - ModelAssociationManager model_association_manager(&controllers_, - &delegate_); - syncer::ModelTypeSet types(syncer::BOOKMARKS, syncer::APPS); - DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); - EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()); - EXPECT_CALL(delegate_, OnModelAssociationDone(_)). - WillOnce(VerifyResult(expected_result)); - - EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), - DataTypeController::NOT_RUNNING); - EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), - DataTypeController::NOT_RUNNING); - - // Initialize() kicks off model loading. - model_association_manager.Initialize(types); - - EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), - DataTypeController::MODEL_LOADED); - EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), - DataTypeController::MODEL_LOADED); - - model_association_manager.StartAssociationAsync(types); - - EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), - DataTypeController::ASSOCIATING); - EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), - DataTypeController::ASSOCIATING); - GetController(controllers_, syncer::BOOKMARKS)->FinishStart( - DataTypeController::OK); - GetController(controllers_, syncer::APPS)->FinishStart( - DataTypeController::OK); -} - -// Start a type and call stop before it finishes associating. -TEST_F(SyncModelAssociationManagerTest, StopModelBeforeFinish) { - controllers_[syncer::BOOKMARKS] = - new FakeDataTypeController(syncer::BOOKMARKS); - ModelAssociationManager model_association_manager( - &controllers_, - &delegate_); - - syncer::ModelTypeSet types; - types.Put(syncer::BOOKMARKS); - - DataTypeManager::ConfigureResult expected_result(DataTypeManager::ABORTED, - types); - - EXPECT_CALL(delegate_, OnModelAssociationDone(_)). - WillOnce(VerifyResult(expected_result)); - EXPECT_CALL(delegate_, - OnSingleDataTypeWillStop(syncer::BOOKMARKS, _)); - - model_association_manager.Initialize(types); - model_association_manager.StartAssociationAsync(types); - - EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), - DataTypeController::ASSOCIATING); - model_association_manager.Stop(); - EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), - DataTypeController::NOT_RUNNING); -} - -// Start a type, let it finish and then call stop. -TEST_F(SyncModelAssociationManagerTest, StopAfterFinish) { - controllers_[syncer::BOOKMARKS] = - new FakeDataTypeController(syncer::BOOKMARKS); - ModelAssociationManager model_association_manager( - &controllers_, - &delegate_); - syncer::ModelTypeSet types; - types.Put(syncer::BOOKMARKS); - DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); - EXPECT_CALL(delegate_, OnModelAssociationDone(_)). - WillOnce(VerifyResult(expected_result)); - EXPECT_CALL(delegate_, - OnSingleDataTypeWillStop(syncer::BOOKMARKS, _)); - - model_association_manager.Initialize(types); - model_association_manager.StartAssociationAsync(types); - - EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), - DataTypeController::ASSOCIATING); - GetController(controllers_, syncer::BOOKMARKS)->FinishStart( - DataTypeController::OK); - - model_association_manager.Stop(); - EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), - DataTypeController::NOT_RUNNING); -} - -// Make a type fail model association and verify correctness. -TEST_F(SyncModelAssociationManagerTest, TypeFailModelAssociation) { - controllers_[syncer::BOOKMARKS] = - new FakeDataTypeController(syncer::BOOKMARKS); - ModelAssociationManager model_association_manager( - &controllers_, - &delegate_); - syncer::ModelTypeSet types; - types.Put(syncer::BOOKMARKS); - DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); - EXPECT_CALL(delegate_, - OnSingleDataTypeWillStop(syncer::BOOKMARKS, _)); - EXPECT_CALL(delegate_, OnModelAssociationDone(_)). - WillOnce(VerifyResult(expected_result)); - - model_association_manager.Initialize(types); - model_association_manager.StartAssociationAsync(types); - - EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), - DataTypeController::ASSOCIATING); - GetController(controllers_, syncer::BOOKMARKS)->FinishStart( - DataTypeController::ASSOCIATION_FAILED); - EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), - DataTypeController::NOT_RUNNING); -} - -// Ensure configuring stops when a type returns a unrecoverable error. -TEST_F(SyncModelAssociationManagerTest, TypeReturnUnrecoverableError) { - controllers_[syncer::BOOKMARKS] = - new FakeDataTypeController(syncer::BOOKMARKS); - ModelAssociationManager model_association_manager( - &controllers_, - &delegate_); - syncer::ModelTypeSet types; - types.Put(syncer::BOOKMARKS); - DataTypeManager::ConfigureResult expected_result( - DataTypeManager::UNRECOVERABLE_ERROR, types); - EXPECT_CALL(delegate_, - OnSingleDataTypeWillStop(syncer::BOOKMARKS, _)); - EXPECT_CALL(delegate_, OnModelAssociationDone(_)). - WillOnce(VerifyResult(expected_result)); - - model_association_manager.Initialize(types); - - model_association_manager.StartAssociationAsync(types); - - EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), - DataTypeController::ASSOCIATING); - GetController(controllers_, syncer::BOOKMARKS)->FinishStart( - DataTypeController::UNRECOVERABLE_ERROR); -} - -TEST_F(SyncModelAssociationManagerTest, SlowTypeAsFailedType) { - controllers_[syncer::BOOKMARKS] = - new FakeDataTypeController(syncer::BOOKMARKS); - controllers_[syncer::APPS] = - new FakeDataTypeController(syncer::APPS); - GetController(controllers_, syncer::BOOKMARKS)->SetDelayModelLoad(); - ModelAssociationManager model_association_manager(&controllers_, - &delegate_); - syncer::ModelTypeSet types; - types.Put(syncer::BOOKMARKS); - types.Put(syncer::APPS); - - DataTypeManager::ConfigureResult expected_result_partially_done( - DataTypeManager::OK, types); - - EXPECT_CALL(delegate_, OnModelAssociationDone(_)). - WillOnce(VerifyResult(expected_result_partially_done)); - - model_association_manager.Initialize(types); - model_association_manager.StartAssociationAsync(types); - GetController(controllers_, syncer::APPS)->FinishStart( - DataTypeController::OK); - - EXPECT_CALL(delegate_, - OnSingleDataTypeWillStop(syncer::BOOKMARKS, _)); - model_association_manager.GetTimerForTesting()->user_task().Run(); - - EXPECT_EQ(DataTypeController::NOT_RUNNING, - GetController(controllers_, syncer::BOOKMARKS)->state()); -} - -TEST_F(SyncModelAssociationManagerTest, StartMultipleTimes) { - controllers_[syncer::BOOKMARKS] = - new FakeDataTypeController(syncer::BOOKMARKS); - controllers_[syncer::APPS] = - new FakeDataTypeController(syncer::APPS); - ModelAssociationManager model_association_manager(&controllers_, - &delegate_); - syncer::ModelTypeSet types; - types.Put(syncer::BOOKMARKS); - types.Put(syncer::APPS); - - DataTypeManager::ConfigureResult result_1st( - DataTypeManager::OK, - syncer::ModelTypeSet(syncer::BOOKMARKS)); - DataTypeManager::ConfigureResult result_2nd( - DataTypeManager::OK, - syncer::ModelTypeSet(syncer::APPS)); - EXPECT_CALL(delegate_, OnModelAssociationDone(_)). - Times(2). - WillOnce(VerifyResult(result_1st)). - WillOnce(VerifyResult(result_2nd)); - - model_association_manager.Initialize(types); - - // Start BOOKMARKS first. - model_association_manager.StartAssociationAsync( - syncer::ModelTypeSet(syncer::BOOKMARKS)); - EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), - DataTypeController::ASSOCIATING); - EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), - DataTypeController::MODEL_LOADED); - - // Finish BOOKMARKS association. - GetController(controllers_, syncer::BOOKMARKS)->FinishStart( - DataTypeController::OK); - EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), - DataTypeController::RUNNING); - EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), - DataTypeController::MODEL_LOADED); - - // Start APPS next. - model_association_manager.StartAssociationAsync( - syncer::ModelTypeSet(syncer::APPS)); - EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), - DataTypeController::ASSOCIATING); - GetController(controllers_, syncer::APPS)->FinishStart( - DataTypeController::OK); - EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), - DataTypeController::RUNNING); -} - -// Test that model that failed to load between initialization and association -// is reported and stopped properly. -TEST_F(SyncModelAssociationManagerTest, ModelLoadFailBeforeAssociationStart) { - controllers_[syncer::BOOKMARKS] = - new FakeDataTypeController(syncer::BOOKMARKS); - GetController(controllers_, syncer::BOOKMARKS)->SetModelLoadError( - syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, - "", syncer::BOOKMARKS)); - ModelAssociationManager model_association_manager( - &controllers_, - &delegate_); - syncer::ModelTypeSet types; - types.Put(syncer::BOOKMARKS); - DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); - EXPECT_CALL(delegate_, - OnSingleDataTypeWillStop(syncer::BOOKMARKS, _)); - EXPECT_CALL(delegate_, OnModelAssociationDone(_)). - WillOnce(VerifyResult(expected_result)); - - model_association_manager.Initialize(types); - EXPECT_EQ(DataTypeController::NOT_RUNNING, - GetController(controllers_, syncer::BOOKMARKS)->state()); - model_association_manager.StartAssociationAsync(types); - EXPECT_EQ(DataTypeController::NOT_RUNNING, - GetController(controllers_, syncer::BOOKMARKS)->state()); -} - -// Test that a runtime error is handled by stopping the type. -TEST_F(SyncModelAssociationManagerTest, StopAfterConfiguration) { - controllers_[syncer::BOOKMARKS] = - new FakeDataTypeController(syncer::BOOKMARKS); - ModelAssociationManager model_association_manager( - &controllers_, - &delegate_); - syncer::ModelTypeSet types; - types.Put(syncer::BOOKMARKS); - DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); - EXPECT_CALL(delegate_, OnModelAssociationDone(_)). - WillOnce(VerifyResult(expected_result)); - - model_association_manager.Initialize(types); - model_association_manager.StartAssociationAsync(types); - - EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), - DataTypeController::ASSOCIATING); - GetController(controllers_, syncer::BOOKMARKS)->FinishStart( - DataTypeController::OK); - EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), - DataTypeController::RUNNING); - - testing::Mock::VerifyAndClearExpectations(&delegate_); - EXPECT_CALL(delegate_, - OnSingleDataTypeWillStop(syncer::BOOKMARKS, _)); - syncer::SyncError error(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "error", - syncer::BOOKMARKS); - GetController(controllers_, syncer::BOOKMARKS) - ->OnSingleDataTypeUnrecoverableError(error); -} - -TEST_F(SyncModelAssociationManagerTest, AbortDuringAssociation) { - controllers_[syncer::BOOKMARKS] = - new FakeDataTypeController(syncer::BOOKMARKS); - controllers_[syncer::APPS] = - new FakeDataTypeController(syncer::APPS); - ModelAssociationManager model_association_manager(&controllers_, - &delegate_); - syncer::ModelTypeSet types; - types.Put(syncer::BOOKMARKS); - types.Put(syncer::APPS); - - syncer::ModelTypeSet expected_types_unfinished; - expected_types_unfinished.Put(syncer::BOOKMARKS); - DataTypeManager::ConfigureResult expected_result_partially_done( - DataTypeManager::OK, types); - - EXPECT_CALL(delegate_, OnModelAssociationDone(_)). - WillOnce(VerifyResult(expected_result_partially_done)); - - model_association_manager.Initialize(types); - model_association_manager.StartAssociationAsync(types); - GetController(controllers_, syncer::APPS)->FinishStart( - DataTypeController::OK); - EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), - DataTypeController::RUNNING); - EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), - DataTypeController::ASSOCIATING); - - EXPECT_CALL(delegate_, - OnSingleDataTypeWillStop(syncer::BOOKMARKS, _)); - model_association_manager.GetTimerForTesting()->user_task().Run(); - - EXPECT_EQ(DataTypeController::NOT_RUNNING, - GetController(controllers_, syncer::BOOKMARKS)->state()); -} - -// Test that OnAllDataTypesReadyForConfigure is called when all datatypes that -// require LoadModels before configuration are loaded. -TEST_F(SyncModelAssociationManagerTest, OnAllDataTypesReadyForConfigure) { - // Create two controllers with delayed model load. - controllers_[syncer::BOOKMARKS] = - new FakeDataTypeController(syncer::BOOKMARKS); - controllers_[syncer::APPS] = new FakeDataTypeController(syncer::APPS); - GetController(controllers_, syncer::BOOKMARKS)->SetDelayModelLoad(); - GetController(controllers_, syncer::APPS)->SetDelayModelLoad(); - - // APPS controller requires LoadModels complete before configure. - GetController(controllers_, syncer::APPS) - ->SetShouldLoadModelBeforeConfigure(true); - - ModelAssociationManager model_association_manager(&controllers_, &delegate_); - syncer::ModelTypeSet types(syncer::BOOKMARKS, syncer::APPS); - DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); - // OnAllDataTypesReadyForConfigure shouldn't be called, APPS data type is not - // loaded yet. - EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()).Times(0); - - model_association_manager.Initialize(types); - - EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), - DataTypeController::MODEL_STARTING); - EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), - DataTypeController::MODEL_STARTING); - - testing::Mock::VerifyAndClearExpectations(&delegate_); - - EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()); - // Finish loading APPS. This should trigger OnAllDataTypesReadyForConfigure - // even though BOOKMARKS is not loaded yet. - GetController(controllers_, syncer::APPS)->SimulateModelLoadFinishing(); - EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), - DataTypeController::MODEL_STARTING); - EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), - DataTypeController::MODEL_LOADED); - - // Call ModelAssociationManager::Initialize with reduced set of datatypes. - // All datatypes in reduced set are already loaded. - // OnAllDataTypesReadyForConfigure() should be called. - testing::Mock::VerifyAndClearExpectations(&delegate_); - - EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()); - syncer::ModelTypeSet reduced_types(syncer::APPS); - model_association_manager.Initialize(reduced_types); -} - -// Test that OnAllDataTypesReadyForConfigure() is called correctly after -// LoadModels fails for one of datatypes. -TEST_F(SyncModelAssociationManagerTest, - OnAllDataTypesReadyForConfigure_FailedLoadModels) { - controllers_[syncer::APPS] = new FakeDataTypeController(syncer::APPS); - GetController(controllers_, syncer::APPS)->SetDelayModelLoad(); - - // APPS controller requires LoadModels complete before configure. - GetController(controllers_, syncer::APPS) - ->SetShouldLoadModelBeforeConfigure(true); - - ModelAssociationManager model_association_manager(&controllers_, &delegate_); - syncer::ModelTypeSet types(syncer::APPS); - DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); - // OnAllDataTypesReadyForConfigure shouldn't be called, APPS data type is not - // loaded yet. - EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()).Times(0); - - model_association_manager.Initialize(types); - - EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), - DataTypeController::MODEL_STARTING); - - testing::Mock::VerifyAndClearExpectations(&delegate_); - - EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()); - // Simulate model load error for APPS and finish loading it. This should - // trigger OnAllDataTypesReadyForConfigure. - GetController(controllers_, syncer::APPS) - ->SetModelLoadError(syncer::SyncError( - FROM_HERE, syncer::SyncError::DATATYPE_ERROR, "", syncer::APPS)); - GetController(controllers_, syncer::APPS)->SimulateModelLoadFinishing(); - EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), - DataTypeController::NOT_RUNNING); -} - -// Test that if one of the types fails while another is still being loaded then -// OnAllDataTypesReadyForConfgiure is still called correctly. -TEST_F(SyncModelAssociationManagerTest, - OnAllDataTypesReadyForConfigure_TypeFailedAfterLoadModels) { - // Create two controllers with delayed model load. Both should block - // configuration. - controllers_[syncer::BOOKMARKS] = - new FakeDataTypeController(syncer::BOOKMARKS); - controllers_[syncer::APPS] = new FakeDataTypeController(syncer::APPS); - GetController(controllers_, syncer::BOOKMARKS)->SetDelayModelLoad(); - GetController(controllers_, syncer::APPS)->SetDelayModelLoad(); - - GetController(controllers_, syncer::BOOKMARKS) - ->SetShouldLoadModelBeforeConfigure(true); - GetController(controllers_, syncer::APPS) - ->SetShouldLoadModelBeforeConfigure(true); - - ModelAssociationManager model_association_manager(&controllers_, &delegate_); - syncer::ModelTypeSet types(syncer::BOOKMARKS, syncer::APPS); - DataTypeManager::ConfigureResult expected_result(DataTypeManager::OK, types); - - // Apps will finish loading but bookmarks won't. - // OnAllDataTypesReadyForConfigure shouldn't be called. - EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()).Times(0); - - model_association_manager.Initialize(types); - - GetController(controllers_, syncer::APPS)->SimulateModelLoadFinishing(); - - EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), - DataTypeController::MODEL_STARTING); - EXPECT_EQ(GetController(controllers_, syncer::APPS)->state(), - DataTypeController::MODEL_LOADED); - - testing::Mock::VerifyAndClearExpectations(&delegate_); - - EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()).Times(0); - - EXPECT_CALL(delegate_, OnSingleDataTypeWillStop(syncer::APPS, _)); - // Apps datatype reports failure. - syncer::SyncError error(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, "error", - syncer::APPS); - GetController(controllers_, syncer::APPS) - ->OnSingleDataTypeUnrecoverableError(error); - - testing::Mock::VerifyAndClearExpectations(&delegate_); - - EXPECT_CALL(delegate_, OnAllDataTypesReadyForConfigure()); - // Finish loading BOOKMARKS. This should trigger - // OnAllDataTypesReadyForConfigure(). - GetController(controllers_, syncer::BOOKMARKS)->SimulateModelLoadFinishing(); - EXPECT_EQ(GetController(controllers_, syncer::BOOKMARKS)->state(), - DataTypeController::MODEL_LOADED); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/model_associator.h b/components/sync_driver/model_associator.h deleted file mode 100644 index 506007a..0000000 --- a/components/sync_driver/model_associator.h +++ /dev/null
@@ -1,97 +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 COMPONENTS_SYNC_DRIVER_MODEL_ASSOCIATOR_H_ -#define COMPONENTS_SYNC_DRIVER_MODEL_ASSOCIATOR_H_ - -#include <stdint.h> - -#include "base/synchronization/lock.h" -#include "components/sync/api/sync_error.h" -#include "components/sync/base/model_type.h" - -namespace syncer { -class BaseNode; -class SyncMergeResult; -} - -namespace sync_driver { - -// This represents the fundamental operations used for model association that -// are common to all ModelAssociators and do not depend on types of the models -// being associated. -class AssociatorInterface { - public: - virtual ~AssociatorInterface() {} - - // Iterates through both the sync and the chrome model looking for - // matched pairs of items. After successful completion, the models - // should be identical and corresponding. Returns true on - // success. On failure of this step, we should abort the sync - // operation and report an error to the user. - virtual syncer::SyncError AssociateModels( - syncer::SyncMergeResult* local_merge_result, - syncer::SyncMergeResult* syncer_merge_result) = 0; - - // Clears all the associations between the chrome and sync models. - virtual syncer::SyncError DisassociateModels() = 0; - - // The has_nodes out parameter is set to true if the sync model has - // nodes other than the permanent tagged nodes. The method may - // return false if an error occurred. - virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes) = 0; - - // Calling this method while AssociateModels() is in progress will - // cause the method to exit early with a "false" return value. This - // is useful for aborting model associations for shutdown. This - // method is only implemented for model associators that are invoked - // off the main thread. - virtual void AbortAssociation() = 0; - - // Returns whether the datatype is ready for encryption/decryption if the - // sync service requires it. - // TODO(zea): This should be implemented automatically for each datatype, see - // http://crbug.com/76232. - virtual bool CryptoReadyIfNecessary() = 0; -}; - -// In addition to the generic methods, association can refer to operations -// that depend on the types of the actual IDs we are associating and the -// underlying node type in the browser. We collect these into a templatized -// interface that encapsulates everything you need to implement to have a model -// associator for a specific data type. -// This template is appropriate for data types where a Node* makes sense for -// referring to a particular item. If we encounter a type that does not fit -// in this world, we may want to have several PerDataType templates. -template <class Node, class IDType> -class PerDataTypeAssociatorInterface : public AssociatorInterface { - public: - virtual ~PerDataTypeAssociatorInterface() {} - // Returns sync id for the given chrome model id. - // Returns syncer::kInvalidId if the sync node is not found for the given - // chrome id. - virtual int64_t GetSyncIdFromChromeId(const IDType& id) = 0; - - // Returns the chrome node for the given sync id. - // Returns NULL if no node is found for the given sync id. - virtual const Node* GetChromeNodeFromSyncId(int64_t sync_id) = 0; - - // Initializes the given sync node from the given chrome node id. - // Returns false if no sync node was found for the given chrome node id or - // if the initialization of sync node fails. - virtual bool InitSyncNodeFromChromeId( - const IDType& node_id, - syncer::BaseNode* sync_node) = 0; - - // Associates the given chrome node with the given sync node. - virtual void Associate(const Node* node, - const syncer::BaseNode& sync_node) = 0; - - // Remove the association that corresponds to the given sync id. - virtual void Disassociate(int64_t sync_id) = 0; -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_MODEL_ASSOCIATOR_H_
diff --git a/components/sync_driver/model_associator_mock.cc b/components/sync_driver/model_associator_mock.cc deleted file mode 100644 index 24b5955..0000000 --- a/components/sync_driver/model_associator_mock.cc +++ /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. - -#include "components/sync_driver/model_associator_mock.h" - -namespace sync_driver { - -ModelAssociatorMock::ModelAssociatorMock() {} - -ModelAssociatorMock::~ModelAssociatorMock() {} - -} // namespace sync_driver
diff --git a/components/sync_driver/model_associator_mock.h b/components/sync_driver/model_associator_mock.h deleted file mode 100644 index f5006fd..0000000 --- a/components/sync_driver/model_associator_mock.h +++ /dev/null
@@ -1,35 +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 COMPONENTS_SYNC_DRIVER_MODEL_ASSOCIATOR_MOCK_H__ -#define COMPONENTS_SYNC_DRIVER_MODEL_ASSOCIATOR_MOCK_H__ - -#include "base/location.h" -#include "components/sync/api/sync_error.h" -#include "components/sync_driver/model_associator.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace sync_driver { - -ACTION_P(SetSyncError, type) { - arg0->Reset(FROM_HERE, "test", type); -} - -class ModelAssociatorMock : public AssociatorInterface { - public: - ModelAssociatorMock(); - virtual ~ModelAssociatorMock(); - - MOCK_METHOD2(AssociateModels, - syncer::SyncError(syncer::SyncMergeResult*, - syncer::SyncMergeResult*)); - MOCK_METHOD0(DisassociateModels, syncer::SyncError()); - MOCK_METHOD1(SyncModelHasUserCreatedNodes, bool(bool* has_nodes)); - MOCK_METHOD0(AbortAssociation, void()); - MOCK_METHOD0(CryptoReadyIfNecessary, bool()); -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_MODEL_ASSOCIATOR_MOCK_H__
diff --git a/components/sync_driver/non_blocking_data_type_controller.cc b/components/sync_driver/non_blocking_data_type_controller.cc deleted file mode 100644 index d669d08d..0000000 --- a/components/sync_driver/non_blocking_data_type_controller.cc +++ /dev/null
@@ -1,265 +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 "components/sync_driver/non_blocking_data_type_controller.h" - -#include <utility> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/location.h" -#include "base/single_thread_task_runner.h" -#include "components/sync/api/model_type_change_processor.h" -#include "components/sync/api/model_type_service.h" -#include "components/sync/api/sync_error.h" -#include "components/sync/api/sync_merge_result.h" -#include "components/sync/base/data_type_histogram.h" -#include "components/sync/core/activation_context.h" -#include "components/sync_driver/backend_data_type_configurer.h" -#include "components/sync_driver/sync_client.h" - -namespace sync_driver_v2 { - -NonBlockingDataTypeController::NonBlockingDataTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const base::Closure& error_callback, - syncer::ModelType model_type, - sync_driver::SyncClient* sync_client) - : sync_driver::DataTypeController(ui_thread, error_callback), - model_type_(model_type), - sync_client_(sync_client), - sync_prefs_(sync_client->GetPrefService()), - state_(NOT_RUNNING) { - DCHECK(BelongsToUIThread()); -} - -NonBlockingDataTypeController::~NonBlockingDataTypeController() {} - -bool NonBlockingDataTypeController::ShouldLoadModelBeforeConfigure() const { - // USS datatypes require loading models because model controls storage where - // data type context and progress marker are persisted. - return true; -} - -void NonBlockingDataTypeController::LoadModels( - const ModelLoadCallback& model_load_callback) { - DCHECK(ui_thread()->BelongsToCurrentThread()); - DCHECK(!model_load_callback.is_null()); - model_load_callback_ = model_load_callback; - - if (state() != NOT_RUNNING) { - LoadModelsDone( - RUNTIME_ERROR, - syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, - "Model already running", type())); - return; - } - - state_ = MODEL_STARTING; - - // Start the type processor on the model thread. - if (!RunOnModelThread( - FROM_HERE, - base::Bind(&NonBlockingDataTypeController::LoadModelsOnModelThread, - this))) { - LoadModelsDone( - UNRECOVERABLE_ERROR, - syncer::SyncError(FROM_HERE, syncer::SyncError::DATATYPE_ERROR, - "Failed to post model Start", type())); - } -} - -void NonBlockingDataTypeController::LoadModelsOnModelThread() { - syncer_v2::ModelTypeService* model_type_service = - sync_client_->GetModelTypeServiceForType(type()); - if (!model_type_service) { - LOG(WARNING) << "ModelTypeService destroyed before " - "ModelTypeController was started."; - // TODO(gangwu): Add SyncError and then call start_callback with it. Also - // set an error state to |state_|. - return; - } - - model_type_service->OnSyncStarting( - this, - base::Bind(&NonBlockingDataTypeController::OnProcessorStarted, this)); -} - -void NonBlockingDataTypeController::LoadModelsDone( - ConfigureResult result, - const syncer::SyncError& error) { - DCHECK(BelongsToUIThread()); - - if (state_ == NOT_RUNNING) { - // The callback arrived on the UI thread after the type has been already - // stopped. - RecordStartFailure(ABORTED); - return; - } - - if (IsSuccessfulResult(result)) { - DCHECK_EQ(MODEL_STARTING, state_); - state_ = MODEL_LOADED; - } else { - RecordStartFailure(result); - } - - if (!model_load_callback_.is_null()) { - model_load_callback_.Run(type(), error); - } -} - -void NonBlockingDataTypeController::OnProcessorStarted( - syncer::SyncError error, - std::unique_ptr<syncer_v2::ActivationContext> activation_context) { - RunOnUIThread( - FROM_HERE, - base::Bind(&NonBlockingDataTypeController::OnProcessorStartedOnUIThread, - this, error, base::Passed(std::move(activation_context)))); -} - -void NonBlockingDataTypeController::OnProcessorStartedOnUIThread( - syncer::SyncError error, - std::unique_ptr<syncer_v2::ActivationContext> activation_context) { - DCHECK(BelongsToUIThread()); - // Hold on to the activation context until ActivateDataType is called. - if (state_ == MODEL_STARTING) { - activation_context_ = std::move(activation_context); - } - // TODO(stanisc): Figure out if UNRECOVERABLE_ERROR is OK in this case. - ConfigureResult result = error.IsSet() ? UNRECOVERABLE_ERROR : OK; - LoadModelsDone(result, error); -} - -void NonBlockingDataTypeController::RegisterWithBackend( - sync_driver::BackendDataTypeConfigurer* configurer) { - DCHECK(BelongsToUIThread()); - DCHECK(configurer); - DCHECK(activation_context_); - DCHECK_EQ(MODEL_LOADED, state_); - configurer->ActivateNonBlockingDataType(type(), - std::move(activation_context_)); -} - -void NonBlockingDataTypeController::StartAssociating( - const StartCallback& start_callback) { - DCHECK(BelongsToUIThread()); - DCHECK(!start_callback.is_null()); - - state_ = RUNNING; - - // There is no association, just call back promptly. - syncer::SyncMergeResult merge_result(type()); - start_callback.Run(OK, merge_result, merge_result); -} - -void NonBlockingDataTypeController::ActivateDataType( - sync_driver::BackendDataTypeConfigurer* configurer) { - DCHECK(BelongsToUIThread()); - DCHECK(configurer); - DCHECK_EQ(RUNNING, state_); - // In contrast with directory datatypes, non-blocking data types should be - // activated in RegisterWithBackend. activation_context_ should be passed - // to backend before call to ActivateDataType. - DCHECK(!activation_context_); -} - -void NonBlockingDataTypeController::DeactivateDataType( - sync_driver::BackendDataTypeConfigurer* configurer) { - DCHECK(BelongsToUIThread()); - DCHECK(configurer); - configurer->DeactivateNonBlockingDataType(type()); -} - -void NonBlockingDataTypeController::Stop() { - DCHECK(ui_thread()->BelongsToCurrentThread()); - - if (state() == NOT_RUNNING) - return; - - // Check preferences if datatype is not in preferred datatypes. Only call - // DisableSync if service is ready to handle it (controller is in loaded - // state). - syncer::ModelTypeSet preferred_types = - sync_prefs_.GetPreferredDataTypes(syncer::ModelTypeSet(type())); - if ((state() == MODEL_LOADED || state() == RUNNING) && - (!sync_prefs_.IsFirstSetupComplete() || !preferred_types.Has(type()))) { - RunOnModelThread(FROM_HERE, base::Bind( - &NonBlockingDataTypeController::DisableSyncOnModelThread, this)); - } - - state_ = NOT_RUNNING; -} - -void NonBlockingDataTypeController::DisableSyncOnModelThread() { - syncer_v2::ModelTypeService* model_type_service = - sync_client_->GetModelTypeServiceForType(type()); - DCHECK(model_type_service); - model_type_service->DisableSync(); -} - -std::string NonBlockingDataTypeController::name() const { - // For logging only. - return syncer::ModelTypeToString(type()); -} - -sync_driver::DataTypeController::State NonBlockingDataTypeController::state() - const { - return state_; -} - -bool NonBlockingDataTypeController::BelongsToUIThread() const { - return ui_thread()->BelongsToCurrentThread(); -} - -void NonBlockingDataTypeController::OnSingleDataTypeUnrecoverableError( - const syncer::SyncError& error) { - RecordUnrecoverableError(); - if (!error_callback_.is_null()) - error_callback_.Run(); - - ReportLoadModelError(UNRECOVERABLE_ERROR, error); -} - -void NonBlockingDataTypeController::ReportLoadModelError( - ConfigureResult result, - const syncer::SyncError& error) { - DCHECK(!IsSuccessfulResult(result)); - if (BelongsToUIThread()) { - // Report the error only if the model is starting. - if (state_ == MODEL_STARTING) { - LoadModelsDone(result, error); - } - } else { - RunOnUIThread( - error.location(), - base::Bind(&NonBlockingDataTypeController::ReportLoadModelError, this, - result, error)); - } -} - -void NonBlockingDataTypeController::RecordStartFailure( - ConfigureResult result) const { - DCHECK(BelongsToUIThread()); - UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", - ModelTypeToHistogramInt(type()), - syncer::MODEL_TYPE_COUNT); -#define PER_DATA_TYPE_MACRO(type_str) \ - UMA_HISTOGRAM_ENUMERATION("Sync." type_str "ConfigureFailure", result, \ - MAX_CONFIGURE_RESULT); - SYNC_DATA_TYPE_HISTOGRAM(type()); -#undef PER_DATA_TYPE_MACRO -} - -void NonBlockingDataTypeController::RecordUnrecoverableError() { - UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeRunFailures", - ModelTypeToHistogramInt(type()), - syncer::MODEL_TYPE_COUNT); -} - -syncer::ModelType NonBlockingDataTypeController::type() const { - return model_type_; -} - -} // namespace sync_driver_v2
diff --git a/components/sync_driver/non_blocking_data_type_controller.h b/components/sync_driver/non_blocking_data_type_controller.h deleted file mode 100644 index 61d98ddfb..0000000 --- a/components/sync_driver/non_blocking_data_type_controller.h +++ /dev/null
@@ -1,137 +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 COMPONENTS_SYNC_DRIVER_NON_BLOCKING_DATA_TYPE_CONTROLLER_H_ -#define COMPONENTS_SYNC_DRIVER_NON_BLOCKING_DATA_TYPE_CONTROLLER_H_ - -#include <memory> -#include <string> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "components/sync/base/model_type.h" -#include "components/sync_driver/data_type_controller.h" -#include "components/sync_driver/sync_prefs.h" - -namespace sync_driver { -class SyncClient; -} - -namespace syncer_v2 { -struct ActivationContext; -} - -namespace sync_driver_v2 { - -// Base class for DataType controllers for Unified Sync and Storage datatypes. -// Derived types must implement the following methods: -// - RunOnModelThread -// - RunOnUIThread -class NonBlockingDataTypeController : public sync_driver::DataTypeController { - public: - NonBlockingDataTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const base::Closure& error_callback, - syncer::ModelType model_type, - sync_driver::SyncClient* sync_client); - - // DataTypeErrorHandler interface. - void OnSingleDataTypeUnrecoverableError( - const syncer::SyncError& error) override; - - // DataTypeController interface. - bool ShouldLoadModelBeforeConfigure() const override; - void LoadModels(const ModelLoadCallback& model_load_callback) override; - - // Registers non-blocking data type with sync backend. In the process the - // activation context is passed to ModelTypeRegistry, where ModelTypeWorker - // gets created and connected with ModelTypeProcessor. - void RegisterWithBackend( - sync_driver::BackendDataTypeConfigurer* configurer) override; - void StartAssociating(const StartCallback& start_callback) override; - void ActivateDataType( - sync_driver::BackendDataTypeConfigurer* configurer) override; - void DeactivateDataType( - sync_driver::BackendDataTypeConfigurer* configurer) override; - void Stop() override; - std::string name() const override; - State state() const override; - syncer::ModelType type() const override; - - protected: - // DataTypeController is RefCounted. - ~NonBlockingDataTypeController() override; - - // Returns true if the call is made on UI thread. - bool BelongsToUIThread() const; - - // Posts the given task to the model thread, i.e. the thread the - // datatype lives on. Return value: True if task posted successfully, - // false otherwise. - virtual bool RunOnModelThread(const tracked_objects::Location& from_here, - const base::Closure& task) = 0; - - // Post the given task on the UI thread. If the call is made on UI thread - // already, make a direct call without posting. - virtual void RunOnUIThread(const tracked_objects::Location& from_here, - const base::Closure& task) = 0; - - private: - void RecordStartFailure(ConfigureResult result) const; - void RecordUnrecoverableError(); - void ReportLoadModelError(ConfigureResult result, - const syncer::SyncError& error); - - // If the DataType controller is waiting for models to load, once the models - // are loaded this function should be called to let the base class - // implementation know that it is safe to continue with the activation. - // The error indicates whether the loading completed successfully. - void LoadModelsDone(ConfigureResult result, const syncer::SyncError& error); - - // Callback passed to the processor to be invoked when the processor has - // started. This is called on the model thread. - void OnProcessorStarted( - syncer::SyncError error, - std::unique_ptr<syncer_v2::ActivationContext> activation_context); - - // The function will do the real work when OnProcessorStarted got called. This - // is called on the UI thread. - void OnProcessorStartedOnUIThread( - syncer::SyncError error, - std::unique_ptr<syncer_v2::ActivationContext> activation_context); - - // The function LoadModels() will call this function to do some works which - // need to be done on model thread. - void LoadModelsOnModelThread(); - - // Stop() posts call to DisableSyncOnModelThread to model thread when it - // decides sync metadata should be cleared. - void DisableSyncOnModelThread(); - - // Model Type for this controller - syncer::ModelType model_type_; - - // Sync client - sync_driver::SyncClient* const sync_client_; - - // Sync prefs. Used for determinig if DisableSync should be called during call - // to Stop(). - sync_driver::SyncPrefs sync_prefs_; - - // State of this datatype controller. - State state_; - - // Callbacks for use when starting the datatype. - ModelLoadCallback model_load_callback_; - - // Controller receives |activation_context_| from SharedModelTypeProcessor - // callback and must temporarily own it until ActivateDataType is called. - std::unique_ptr<syncer_v2::ActivationContext> activation_context_; - - DISALLOW_COPY_AND_ASSIGN(NonBlockingDataTypeController); -}; - -} // namespace sync_driver_v2 - -#endif // COMPONENTS_SYNC_DRIVER_NON_BLOCKING_DATA_TYPE_CONTROLLER_H_
diff --git a/components/sync_driver/non_blocking_data_type_controller_unittest.cc b/components/sync_driver/non_blocking_data_type_controller_unittest.cc deleted file mode 100644 index 08f22f6..0000000 --- a/components/sync_driver/non_blocking_data_type_controller_unittest.cc +++ /dev/null
@@ -1,214 +0,0 @@ -// Copyright 2016 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/sync_driver/non_blocking_data_type_controller.h" - -#include <memory> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/location.h" -#include "base/logging.h" -#include "base/memory/ref_counted.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "components/sync/api/fake_model_type_change_processor.h" -#include "components/sync/api/fake_model_type_service.h" -#include "components/sync/base/model_type.h" -#include "components/sync_driver/fake_sync_client.h" -#include "components/sync_driver/sync_prefs.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sync_driver { -class SyncClient; -} // namespace sync_driver - -namespace sync_driver_v2 { - -namespace { - -syncer::ModelType kTestModelType = syncer::AUTOFILL; - -// Implementation of NonBlockingDataTypeController being tested. -// It posts all tasks to current thread. -class TestDataTypeController : public NonBlockingDataTypeController { - public: - TestDataTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& thread, - sync_driver::SyncClient* sync_client) - : NonBlockingDataTypeController(thread, - base::Closure(), - kTestModelType, - sync_client) {} - - protected: - ~TestDataTypeController() override {} - - bool RunOnModelThread(const tracked_objects::Location& from_here, - const base::Closure& task) override { - ui_thread()->PostTask(from_here, task); - return true; - } - - void RunOnUIThread(const tracked_objects::Location& from_here, - const base::Closure& task) override { - ui_thread()->PostTask(from_here, task); - } -}; - -// Mock change processor to observe calls to DisableSync. -class MockModelTypeChangeProcessor - : public syncer_v2::FakeModelTypeChangeProcessor { - public: - explicit MockModelTypeChangeProcessor(int* disable_sync_call_count) - : disable_sync_call_count_(disable_sync_call_count) {} - - void DisableSync() override { (*disable_sync_call_count_)++; } - - private: - int* disable_sync_call_count_; -}; - -class NonBlockingDataTypeControllerTest : public testing::Test { - public: - NonBlockingDataTypeControllerTest() - : disable_sync_call_count_(0), - sync_prefs_(sync_client_.GetPrefService()), - model_type_service_( - base::Bind(&NonBlockingDataTypeControllerTest::CreateProcessor, - base::Unretained(this))) {} - - void SetUp() override { - sync_client_.SetModelTypeService(&model_type_service_); - controller_ = - new TestDataTypeController(message_loop_.task_runner(), &sync_client_); - } - - void TearDown() override { - controller_ = nullptr; - PumpLoop(); - } - - protected: - std::unique_ptr<syncer_v2::ModelTypeChangeProcessor> CreateProcessor( - syncer::ModelType type, - syncer_v2::ModelTypeService* service) { - auto processor = base::MakeUnique<MockModelTypeChangeProcessor>( - &disable_sync_call_count_); - processor_ = processor.get(); - return std::move(processor); - } - - // Gets controller from NOT_RUNNING to RUNNING state. - void ActivateController() { - EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, - controller_->state()); - controller_->LoadModels( - base::Bind(&NonBlockingDataTypeControllerTest::LoadModelsDone, - base::Unretained(this))); - - EXPECT_EQ(sync_driver::DataTypeController::MODEL_STARTING, - controller_->state()); - PumpLoop(); - EXPECT_EQ(sync_driver::DataTypeController::MODEL_LOADED, - controller_->state()); - controller_->StartAssociating( - base::Bind(&NonBlockingDataTypeControllerTest::AssociationDone, - base::Unretained(this))); - EXPECT_EQ(sync_driver::DataTypeController::RUNNING, controller_->state()); - } - - void LoadModelsDone(syncer::ModelType type, syncer::SyncError error) {} - - void AssociationDone(sync_driver::DataTypeController::ConfigureResult result, - const syncer::SyncMergeResult& local_merge_result, - const syncer::SyncMergeResult& syncer_merge_result) {} - - void PumpLoop() { base::RunLoop().RunUntilIdle(); } - - int disable_sync_call_count_; - base::MessageLoop message_loop_; - sync_driver::FakeSyncClient sync_client_; - sync_driver::SyncPrefs sync_prefs_; - MockModelTypeChangeProcessor* processor_; - syncer_v2::FakeModelTypeService model_type_service_; - scoped_refptr<TestDataTypeController> controller_; -}; - -// Test emulates normal browser shutdown. Ensures that DisableSync is not -// called. -TEST_F(NonBlockingDataTypeControllerTest, StopWhenDatatypeEnabled) { - // Enable datatype through preferences. - sync_prefs_.SetFirstSetupComplete(); - sync_prefs_.SetKeepEverythingSynced(true); - - ActivateController(); - - controller_->Stop(); - PumpLoop(); - EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); - // Ensure that DisableSync is not called and service still has valid change - // processor. - EXPECT_EQ(0, disable_sync_call_count_); - EXPECT_TRUE(model_type_service_.HasChangeProcessor()); -} - -// Test emulates scenario when user disables datatype. DisableSync should be -// called. -TEST_F(NonBlockingDataTypeControllerTest, StopWhenDatatypeDisabled) { - // Enable datatype through preferences. - sync_prefs_.SetFirstSetupComplete(); - sync_prefs_.SetKeepEverythingSynced(true); - ActivateController(); - - // Disable datatype through preferences. - sync_prefs_.SetKeepEverythingSynced(false); - sync_prefs_.SetPreferredDataTypes(syncer::ModelTypeSet(kTestModelType), - syncer::ModelTypeSet()); - - controller_->Stop(); - PumpLoop(); - EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); - // Ensure that DisableSync is called and change processor is reset. - EXPECT_EQ(1, disable_sync_call_count_); - EXPECT_FALSE(model_type_service_.HasChangeProcessor()); -} - -// Test emulates disabling sync by signing out. DisableSync should be called. -TEST_F(NonBlockingDataTypeControllerTest, StopWithInitialSyncPrefs) { - // Enable datatype through preferences. - sync_prefs_.SetFirstSetupComplete(); - sync_prefs_.SetKeepEverythingSynced(true); - ActivateController(); - - // Clearing preferences emulates signing out. - sync_prefs_.ClearPreferences(); - controller_->Stop(); - PumpLoop(); - EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); - // Ensure that DisableSync is called and change processor is reset. - EXPECT_EQ(1, disable_sync_call_count_); - EXPECT_FALSE(model_type_service_.HasChangeProcessor()); -} - -// Test emulates disabling sync when datatype is not loaded yet. DisableSync -// should not be called as service is potentially not ready to handle it. -TEST_F(NonBlockingDataTypeControllerTest, StopBeforeLoadModels) { - // Enable datatype through preferences. - sync_prefs_.SetFirstSetupComplete(); - sync_prefs_.SetKeepEverythingSynced(true); - EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); - - // Clearing preferences emulates signing out. - sync_prefs_.ClearPreferences(); - controller_->Stop(); - PumpLoop(); - EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); - // Ensure that DisableSync is not called. - EXPECT_EQ(0, disable_sync_call_count_); -} - -} // namespace - -} // namespace sync_driver_v2
diff --git a/components/sync_driver/non_ui_data_type_controller.cc b/components/sync_driver/non_ui_data_type_controller.cc deleted file mode 100644 index 7fd33176..0000000 --- a/components/sync_driver/non_ui_data_type_controller.cc +++ /dev/null
@@ -1,424 +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 "components/sync_driver/non_ui_data_type_controller.h" - -#include "base/logging.h" -#include "base/memory/weak_ptr.h" -#include "base/threading/thread_task_runner_handle.h" -#include "components/sync/api/sync_error.h" -#include "components/sync/api/sync_merge_result.h" -#include "components/sync/api/syncable_service.h" -#include "components/sync/base/data_type_histogram.h" -#include "components/sync/base/model_type.h" -#include "components/sync_driver/generic_change_processor_factory.h" -#include "components/sync_driver/shared_change_processor_ref.h" -#include "components/sync_driver/sync_api_component_factory.h" -#include "components/sync_driver/sync_client.h" -#include "components/sync_driver/sync_service.h" - -namespace sync_driver { - -SharedChangeProcessor* -NonUIDataTypeController::CreateSharedChangeProcessor() { - return new SharedChangeProcessor(); -} - -NonUIDataTypeController::NonUIDataTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const base::Closure& error_callback, - SyncClient* sync_client) - : DirectoryDataTypeController(ui_thread, error_callback), - sync_client_(sync_client), - state_(NOT_RUNNING), - ui_thread_(ui_thread) {} - -void NonUIDataTypeController::LoadModels( - const ModelLoadCallback& model_load_callback) { - DCHECK(ui_thread_->BelongsToCurrentThread()); - model_load_callback_ = model_load_callback; - if (state() != NOT_RUNNING) { - model_load_callback.Run(type(), - syncer::SyncError(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Model already running", - type())); - return; - } - - state_ = MODEL_STARTING; - // Since we can't be called multiple times before Stop() is called, - // |shared_change_processor_| must be NULL here. - DCHECK(!shared_change_processor_.get()); - shared_change_processor_ = CreateSharedChangeProcessor(); - DCHECK(shared_change_processor_.get()); - if (!StartModels()) { - // If we are waiting for some external service to load before associating - // or we failed to start the models, we exit early. - DCHECK(state() == MODEL_STARTING || state() == NOT_RUNNING); - return; - } - - OnModelLoaded(); -} - -void NonUIDataTypeController::OnModelLoaded() { - DCHECK_EQ(state_, MODEL_STARTING); - state_ = MODEL_LOADED; - model_load_callback_.Run(type(), syncer::SyncError()); -} - -bool NonUIDataTypeController::StartModels() { - DCHECK_EQ(state_, MODEL_STARTING); - // By default, no additional services need to be started before we can proceed - // with model association. - return true; -} - -void NonUIDataTypeController::StopModels() { - DCHECK(ui_thread_->BelongsToCurrentThread()); -} - -void NonUIDataTypeController::StartAssociating( - const StartCallback& start_callback) { - DCHECK(ui_thread_->BelongsToCurrentThread()); - DCHECK(!start_callback.is_null()); - DCHECK_EQ(state_, MODEL_LOADED); - state_ = ASSOCIATING; - - // Store UserShare now while on UI thread to avoid potential race - // condition in StartAssociationWithSharedChangeProcessor. - DCHECK(sync_client_->GetSyncService()); - user_share_ = sync_client_->GetSyncService()->GetUserShare(); - - start_callback_ = start_callback; - if (!StartAssociationAsync()) { - syncer::SyncError error( - FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Failed to post StartAssociation", - type()); - syncer::SyncMergeResult local_merge_result(type()); - local_merge_result.set_error(error); - StartDoneImpl(ASSOCIATION_FAILED, - NOT_RUNNING, - local_merge_result, - syncer::SyncMergeResult(type())); - // StartDoneImpl should have called ClearSharedChangeProcessor(); - DCHECK(!shared_change_processor_.get()); - return; - } -} - -void NonUIDataTypeController::Stop() { - DCHECK(ui_thread_->BelongsToCurrentThread()); - - if (state() == NOT_RUNNING) - return; - - // Disconnect the change processor. At this point, the - // syncer::SyncableService can no longer interact with the Syncer, even if - // it hasn't finished MergeDataAndStartSyncing. - ClearSharedChangeProcessor(); - - // If we haven't finished starting, we need to abort the start. - switch (state()) { - case MODEL_STARTING: - state_ = STOPPING; - AbortModelLoad(); - return; // The datatype was never activated, we're done. - case ASSOCIATING: - state_ = STOPPING; - StopModels(); - // We continue on to deactivate the datatype and stop the local service. - break; - case MODEL_LOADED: - case DISABLED: - // If DTC is loaded or disabled, we never attempted or succeeded - // associating and never activated the datatype. We would have already - // stopped the local service in StartDoneImpl(..). - state_ = NOT_RUNNING; - StopModels(); - return; - default: - // Datatype was fully started. Need to deactivate and stop the local - // service. - DCHECK_EQ(state(), RUNNING); - state_ = STOPPING; - StopModels(); - break; - } - - // Stop the local service and release our references to it and the - // shared change processor (posts a task to the datatype's thread). - StopLocalServiceAsync(); - - state_ = NOT_RUNNING; -} - -std::string NonUIDataTypeController::name() const { - // For logging only. - return syncer::ModelTypeToString(type()); -} - -DataTypeController::State NonUIDataTypeController::state() const { - return state_; -} - -void NonUIDataTypeController::OnSingleDataTypeUnrecoverableError( - const syncer::SyncError& error) { - DCHECK(!ui_thread_->BelongsToCurrentThread()); - // TODO(tim): We double-upload some errors. See bug 383480. - if (!error_callback_.is_null()) - error_callback_.Run(); - ui_thread_->PostTask(error.location(), - base::Bind(&NonUIDataTypeController::DisableImpl, - this, - error)); -} - -NonUIDataTypeController::NonUIDataTypeController() - : DirectoryDataTypeController(base::ThreadTaskRunnerHandle::Get(), - base::Closure()), - sync_client_(NULL) {} - -NonUIDataTypeController::~NonUIDataTypeController() {} - -void NonUIDataTypeController::StartDone( - DataTypeController::ConfigureResult start_result, - const syncer::SyncMergeResult& local_merge_result, - const syncer::SyncMergeResult& syncer_merge_result) { - DCHECK(!ui_thread_->BelongsToCurrentThread()); - - DataTypeController::State new_state; - if (IsSuccessfulResult(start_result)) { - new_state = RUNNING; - } else { - new_state = (start_result == ASSOCIATION_FAILED ? DISABLED : NOT_RUNNING); - } - - ui_thread_->PostTask(FROM_HERE, - base::Bind(&NonUIDataTypeController::StartDoneImpl, - this, - start_result, - new_state, - local_merge_result, - syncer_merge_result)); -} - -void NonUIDataTypeController::StartDoneImpl( - DataTypeController::ConfigureResult start_result, - DataTypeController::State new_state, - const syncer::SyncMergeResult& local_merge_result, - const syncer::SyncMergeResult& syncer_merge_result) { - DCHECK(ui_thread_->BelongsToCurrentThread()); - - // If we failed to start up, and we haven't been stopped yet, we need to - // ensure we clean up the local service and shared change processor properly. - if (new_state != RUNNING && state() != NOT_RUNNING && state() != STOPPING) { - ClearSharedChangeProcessor(); - StopLocalServiceAsync(); - } - - // It's possible to have StartDoneImpl called first from the UI thread - // (due to Stop being called) and then posted from the non-UI thread. In - // this case, we drop the second call because we've already been stopped. - if (state_ == NOT_RUNNING) { - return; - } - - state_ = new_state; - if (state_ != RUNNING) { - // Start failed. - StopModels(); - RecordStartFailure(start_result); - } - - start_callback_.Run(start_result, local_merge_result, syncer_merge_result); -} - -void NonUIDataTypeController::RecordAssociationTime(base::TimeDelta time) { - DCHECK(!ui_thread_->BelongsToCurrentThread()); -#define PER_DATA_TYPE_MACRO(type_str) \ - UMA_HISTOGRAM_TIMES("Sync." type_str "AssociationTime", time); - SYNC_DATA_TYPE_HISTOGRAM(type()); -#undef PER_DATA_TYPE_MACRO -} - -void NonUIDataTypeController::RecordStartFailure(ConfigureResult result) { - DCHECK(ui_thread_->BelongsToCurrentThread()); - UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", - ModelTypeToHistogramInt(type()), - syncer::MODEL_TYPE_COUNT); -#define PER_DATA_TYPE_MACRO(type_str) \ - UMA_HISTOGRAM_ENUMERATION("Sync." type_str "ConfigureFailure", result, \ - MAX_CONFIGURE_RESULT); - SYNC_DATA_TYPE_HISTOGRAM(type()); -#undef PER_DATA_TYPE_MACRO -} - -void NonUIDataTypeController::AbortModelLoad() { - state_ = NOT_RUNNING; - StopModels(); -} - -void NonUIDataTypeController::DisableImpl( - const syncer::SyncError& error) { - DCHECK(ui_thread_->BelongsToCurrentThread()); - UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeRunFailures", - ModelTypeToHistogramInt(type()), - syncer::MODEL_TYPE_COUNT); - if (!model_load_callback_.is_null()) { - model_load_callback_.Run(type(), error); - } -} - -bool NonUIDataTypeController::StartAssociationAsync() { - DCHECK(ui_thread_->BelongsToCurrentThread()); - DCHECK_EQ(state(), ASSOCIATING); - return PostTaskOnBackendThread( - FROM_HERE, - base::Bind( - &NonUIDataTypeController::StartAssociationWithSharedChangeProcessor, - this, - shared_change_processor_)); -} - -ChangeProcessor* NonUIDataTypeController::GetChangeProcessor() const { - DCHECK_EQ(state_, RUNNING); - return shared_change_processor_->generic_change_processor(); -} - -// This method can execute after we've already stopped (and possibly even -// destroyed) both the Syncer and the SyncableService. As a result, all actions -// must either have no side effects outside of the DTC or must be protected -// by |shared_change_processor|, which is guaranteed to have been Disconnected -// if the syncer shut down. -void NonUIDataTypeController:: - StartAssociationWithSharedChangeProcessor( - const scoped_refptr<SharedChangeProcessor>& shared_change_processor) { - DCHECK(!ui_thread_->BelongsToCurrentThread()); - DCHECK(shared_change_processor.get()); - DCHECK(user_share_); - syncer::SyncMergeResult local_merge_result(type()); - syncer::SyncMergeResult syncer_merge_result(type()); - base::WeakPtrFactory<syncer::SyncMergeResult> weak_ptr_factory( - &syncer_merge_result); - - // Connect |shared_change_processor| to the syncer and get the - // syncer::SyncableService associated with type(). - // Note that it's possible the shared_change_processor has already been - // disconnected at this point, so all our accesses to the syncer from this - // point on are through it. - GenericChangeProcessorFactory factory; - local_service_ = shared_change_processor->Connect( - sync_client_, &factory, user_share_, this, type(), - weak_ptr_factory.GetWeakPtr()); - if (!local_service_.get()) { - syncer::SyncError error(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Failed to connect to syncer.", - type()); - local_merge_result.set_error(error); - StartDone(ASSOCIATION_FAILED, - local_merge_result, - syncer_merge_result); - return; - } - - if (!shared_change_processor->CryptoReadyIfNecessary()) { - syncer::SyncError error(FROM_HERE, - syncer::SyncError::CRYPTO_ERROR, - "", - type()); - local_merge_result.set_error(error); - StartDone(NEEDS_CRYPTO, - local_merge_result, - syncer_merge_result); - return; - } - - bool sync_has_nodes = false; - if (!shared_change_processor->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { - syncer::SyncError error(FROM_HERE, - syncer::SyncError::UNRECOVERABLE_ERROR, - "Failed to load sync nodes", - type()); - local_merge_result.set_error(error); - StartDone(UNRECOVERABLE_ERROR, - local_merge_result, - syncer_merge_result); - return; - } - - // Scope for |initial_sync_data| which might be expensive, so we don't want - // to keep it in memory longer than necessary. - { - syncer::SyncDataList initial_sync_data; - - base::TimeTicks start_time = base::TimeTicks::Now(); - syncer::SyncError error = - shared_change_processor->GetAllSyncDataReturnError(type(), - &initial_sync_data); - if (error.IsSet()) { - local_merge_result.set_error(error); - StartDone(ASSOCIATION_FAILED, local_merge_result, syncer_merge_result); - return; - } - - std::string datatype_context; - if (shared_change_processor->GetDataTypeContext(&datatype_context)) { - local_service_->UpdateDataTypeContext( - type(), syncer::SyncChangeProcessor::NO_REFRESH, datatype_context); - } - - syncer_merge_result.set_num_items_before_association( - initial_sync_data.size()); - // Passes a reference to |shared_change_processor|. - local_merge_result = local_service_->MergeDataAndStartSyncing( - type(), initial_sync_data, - std::unique_ptr<syncer::SyncChangeProcessor>( - new SharedChangeProcessorRef(shared_change_processor)), - std::unique_ptr<syncer::SyncErrorFactory>( - new SharedChangeProcessorRef(shared_change_processor))); - RecordAssociationTime(base::TimeTicks::Now() - start_time); - if (local_merge_result.error().IsSet()) { - StartDone(ASSOCIATION_FAILED, local_merge_result, syncer_merge_result); - return; - } - } - - syncer_merge_result.set_num_items_after_association( - shared_change_processor->GetSyncCount()); - - StartDone(!sync_has_nodes ? OK_FIRST_RUN : OK, - local_merge_result, - syncer_merge_result); -} - -void NonUIDataTypeController::ClearSharedChangeProcessor() { - DCHECK(ui_thread_->BelongsToCurrentThread()); - // |shared_change_processor_| can already be NULL if Stop() is - // called after StartDoneImpl(_, DISABLED, _). - if (shared_change_processor_.get()) { - shared_change_processor_->Disconnect(); - shared_change_processor_ = NULL; - } -} - -void NonUIDataTypeController::StopLocalServiceAsync() { - DCHECK(ui_thread_->BelongsToCurrentThread()); - PostTaskOnBackendThread( - FROM_HERE, - base::Bind(&NonUIDataTypeController::StopLocalService, this)); -} - -void NonUIDataTypeController::StopLocalService() { - DCHECK(!ui_thread_->BelongsToCurrentThread()); - if (local_service_.get()) - local_service_->StopSyncing(type()); - local_service_.reset(); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/non_ui_data_type_controller.h b/components/sync_driver/non_ui_data_type_controller.h deleted file mode 100644 index d3c850b..0000000 --- a/components/sync_driver/non_ui_data_type_controller.h +++ /dev/null
@@ -1,168 +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 COMPONENTS_SYNC_DRIVER_NON_UI_DATA_TYPE_CONTROLLER_H_ -#define COMPONENTS_SYNC_DRIVER_NON_UI_DATA_TYPE_CONTROLLER_H_ - -#include <string> - -#include "base/compiler_specific.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "components/sync_driver/directory_data_type_controller.h" -#include "components/sync_driver/shared_change_processor.h" - -namespace syncer { -class SyncableService; -struct UserShare; -} - -namespace sync_driver { - -class SyncClient; - -class NonUIDataTypeController : public DirectoryDataTypeController { - public: - NonUIDataTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const base::Closure& error_callback, - SyncClient* sync_client); - - // DataTypeController interface. - void LoadModels(const ModelLoadCallback& model_load_callback) override; - void StartAssociating(const StartCallback& start_callback) override; - void Stop() override; - syncer::ModelType type() const override = 0; - syncer::ModelSafeGroup model_safe_group() const override = 0; - ChangeProcessor* GetChangeProcessor() const override; - std::string name() const override; - State state() const override; - void OnSingleDataTypeUnrecoverableError( - const syncer::SyncError& error) override; - - protected: - // For testing only. - NonUIDataTypeController(); - // DataTypeController is RefCounted. - ~NonUIDataTypeController() override; - - // Start any dependent services that need to be running before we can - // associate models. The default implementation is a no-op. - // Return value: - // True - if models are ready and association can proceed. - // False - if models are not ready. StartAssociationAsync should be called - // when the models are ready. - // Note: this is performed on the UI thread. - virtual bool StartModels(); - - // Perform any DataType controller specific state cleanup before stopping - // the datatype controller. The default implementation is a no-op. - // Note: this is performed on the UI thread. - virtual void StopModels(); - - // Posts the given task to the backend thread, i.e. the thread the - // datatype lives on. Return value: True if task posted successfully, - // false otherwise. - virtual bool PostTaskOnBackendThread( - const tracked_objects::Location& from_here, - const base::Closure& task) = 0; - - // Start up complete, update the state and invoke the callback. - // Note: this is performed on the datatype's thread. - virtual void StartDone( - DataTypeController::ConfigureResult start_result, - const syncer::SyncMergeResult& local_merge_result, - const syncer::SyncMergeResult& syncer_merge_result); - - // UI thread implementation of StartDone. - virtual void StartDoneImpl( - DataTypeController::ConfigureResult start_result, - DataTypeController::State new_state, - const syncer::SyncMergeResult& local_merge_result, - const syncer::SyncMergeResult& syncer_merge_result); - - // Kick off the association process. - virtual bool StartAssociationAsync(); - - // Record association time. - virtual void RecordAssociationTime(base::TimeDelta time); - - // Record causes of start failure. - virtual void RecordStartFailure(ConfigureResult result); - - // To allow unit tests to control thread interaction during non-ui startup - // and shutdown, use a factory method to create the SharedChangeProcessor. - virtual SharedChangeProcessor* CreateSharedChangeProcessor(); - - // If the DTC is waiting for models to load, once the models are - // loaded the datatype service will call this function on DTC to let - // us know that it is safe to start associating. - void OnModelLoaded(); - - private: - // Posted on the backend thread by StartAssociationAsync(). - void StartAssociationWithSharedChangeProcessor( - const scoped_refptr<SharedChangeProcessor>& shared_change_processor); - - // Calls Disconnect() on |shared_change_processor_|, then sets it to - // NULL. Must be called only by StartDoneImpl() or Stop() (on the - // UI thread) and only after a call to Start() (i.e., - // |shared_change_processor_| must be non-NULL). - void ClearSharedChangeProcessor(); - - // Posts StopLocalService() to the datatype's thread. - void StopLocalServiceAsync(); - - // Calls local_service_->StopSyncing() and releases our references to it. - void StopLocalService(); - - // Abort model loading and trigger the model load callback. - void AbortModelLoad(); - - // Disable this type with the sync service. Should only be invoked in case of - // an unrecoverable error. - // Note: this is performed on the UI thread. - void DisableImpl(const syncer::SyncError& error); - - SyncClient* const sync_client_; - - // UserShare is stored in StartAssociating while on UI thread and - // passed to SharedChangeProcessor::Connect on the model thread. - syncer::UserShare* user_share_; - - // State of this datatype controller. - State state_; - - // Callbacks for use when starting the datatype. - StartCallback start_callback_; - ModelLoadCallback model_load_callback_; - - // The shared change processor is the thread-safe interface to the - // datatype. We hold a reference to it from the UI thread so that - // we can call Disconnect() on it from Stop()/StartDoneImpl(). Most - // of the work is done on the backend thread, and in - // StartAssociationWithSharedChangeProcessor() for this class in - // particular. - // - // Lifetime: The SharedChangeProcessor object is created on the UI - // thread and passed on to the backend thread. This reference is - // released on the UI thread in Stop()/StartDoneImpl(), but the - // backend thread may still have references to it (which is okay, - // since we call Disconnect() before releasing the UI thread - // reference). - scoped_refptr<SharedChangeProcessor> shared_change_processor_; - - // A weak pointer to the actual local syncable service, which performs all the - // real work. We do not own the object, and it is only safe to access on the - // DataType's thread. - // Lifetime: it gets set in StartAssociationWithSharedChangeProcessor(...) - // and released in StopLocalService(). - base::WeakPtr<syncer::SyncableService> local_service_; - - scoped_refptr<base::SingleThreadTaskRunner> ui_thread_; -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_NON_UI_DATA_TYPE_CONTROLLER_H_
diff --git a/components/sync_driver/non_ui_data_type_controller_mock.cc b/components/sync_driver/non_ui_data_type_controller_mock.cc deleted file mode 100644 index f68ea42..0000000 --- a/components/sync_driver/non_ui_data_type_controller_mock.cc +++ /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. - -#include "components/sync_driver/non_ui_data_type_controller_mock.h" - -namespace sync_driver { - -NonUIDataTypeControllerMock::NonUIDataTypeControllerMock() {} - -NonUIDataTypeControllerMock::~NonUIDataTypeControllerMock() {} - -} // namespace sync_driver
diff --git a/components/sync_driver/non_ui_data_type_controller_mock.h b/components/sync_driver/non_ui_data_type_controller_mock.h deleted file mode 100644 index 1bbc194..0000000 --- a/components/sync_driver/non_ui_data_type_controller_mock.h +++ /dev/null
@@ -1,57 +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 COMPONENTS_SYNC_DRIVER_NON_UI_DATA_TYPE_CONTROLLER_MOCK_H_ -#define COMPONENTS_SYNC_DRIVER_NON_UI_DATA_TYPE_CONTROLLER_MOCK_H_ - -#include <string> - -#include "components/sync/api/sync_error.h" -#include "components/sync_driver/non_ui_data_type_controller.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace sync_driver { - -class NonUIDataTypeControllerMock - : public NonUIDataTypeController { - public: - NonUIDataTypeControllerMock(); - - // DataTypeController mocks. - MOCK_METHOD1(StartAssociating, - void(const StartCallback& start_callback)); - MOCK_METHOD1(LoadModels, void(const ModelLoadCallback& model_load_callback)); - MOCK_METHOD0(Stop, void()); - MOCK_CONST_METHOD0(type, syncer::ModelType()); - MOCK_CONST_METHOD0(name, std::string()); - MOCK_CONST_METHOD0(model_safe_group, syncer::ModelSafeGroup()); - MOCK_CONST_METHOD0(state, State()); - MOCK_METHOD1(OnSingleDataTypeUnrecoverableError, - void(const syncer::SyncError& error)); - - // NonUIDataTypeController mocks. - MOCK_METHOD0(StartModels, bool()); - MOCK_METHOD0(StopModels, void()); - MOCK_METHOD2(PostTaskOnBackendThread, - bool(const tracked_objects::Location&, - const base::Closure&)); - MOCK_METHOD3(StartDone, - void(DataTypeController::ConfigureResult result, - const syncer::SyncMergeResult& local_merge_result, - const syncer::SyncMergeResult& syncer_merge_result)); - MOCK_METHOD4(StartDoneImpl, - void(DataTypeController::ConfigureResult result, - DataTypeController::State new_state, - const syncer::SyncMergeResult& local_merge_result, - const syncer::SyncMergeResult& syncer_merge_result)); - MOCK_METHOD1(RecordAssociationTime, void(base::TimeDelta time)); - MOCK_METHOD1(RecordStartFailure, void(ConfigureResult result)); - - protected: - virtual ~NonUIDataTypeControllerMock(); -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_NON_UI_DATA_TYPE_CONTROLLER_MOCK_H_
diff --git a/components/sync_driver/non_ui_data_type_controller_unittest.cc b/components/sync_driver/non_ui_data_type_controller_unittest.cc deleted file mode 100644 index e041f32..0000000 --- a/components/sync_driver/non_ui_data_type_controller_unittest.cc +++ /dev/null
@@ -1,512 +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 "components/sync_driver/non_ui_data_type_controller.h" - -#include <memory> -#include <vector> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/callback.h" -#include "base/compiler_specific.h" -#include "base/location.h" -#include "base/macros.h" -#include "base/run_loop.h" -#include "base/single_thread_task_runner.h" -#include "base/synchronization/waitable_event.h" -#include "base/test/test_timeouts.h" -#include "base/threading/thread.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/tracked_objects.h" -#include "components/sync/api/fake_syncable_service.h" -#include "components/sync/api/sync_change.h" -#include "components/sync/engine/model_safe_worker.h" -#include "components/sync_driver/data_type_controller_mock.h" -#include "components/sync_driver/fake_sync_client.h" -#include "components/sync_driver/generic_change_processor_factory.h" -#include "components/sync_driver/non_ui_data_type_controller_mock.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sync_driver { - -class SyncClient; - -namespace { - -using base::WaitableEvent; -using syncer::AUTOFILL_PROFILE; -using testing::_; -using testing::AtLeast; -using testing::DoAll; -using testing::InvokeWithoutArgs; -using testing::Mock; -using testing::Return; -using testing::SetArgumentPointee; -using testing::StrictMock; - -ACTION_P(WaitOnEvent, event) { - event->Wait(); -} - -ACTION_P(SignalEvent, event) { - event->Signal(); -} - -ACTION_P(SaveChangeProcessor, scoped_change_processor) { - scoped_change_processor->reset(arg2); -} - -ACTION_P(GetWeakPtrToSyncableService, syncable_service) { - // Have to do this within an Action to ensure it's not evaluated on the wrong - // thread. - return syncable_service->AsWeakPtr(); -} - -class SharedChangeProcessorMock : public SharedChangeProcessor { - public: - SharedChangeProcessorMock() {} - - MOCK_METHOD6(Connect, - base::WeakPtr<syncer::SyncableService>( - SyncClient*, - GenericChangeProcessorFactory*, - syncer::UserShare*, - syncer::DataTypeErrorHandler*, - syncer::ModelType, - const base::WeakPtr<syncer::SyncMergeResult>&)); - MOCK_METHOD0(Disconnect, bool()); - MOCK_METHOD2(ProcessSyncChanges, - syncer::SyncError(const tracked_objects::Location&, - const syncer::SyncChangeList&)); - MOCK_CONST_METHOD2(GetAllSyncDataReturnError, - syncer::SyncError(syncer::ModelType, - syncer::SyncDataList*)); - MOCK_METHOD0(GetSyncCount, int()); - MOCK_METHOD1(SyncModelHasUserCreatedNodes, - bool(bool*)); - MOCK_METHOD0(CryptoReadyIfNecessary, bool()); - MOCK_CONST_METHOD1(GetDataTypeContext, bool(std::string*)); - - protected: - virtual ~SharedChangeProcessorMock() {} - MOCK_METHOD2(OnUnrecoverableError, void(const tracked_objects::Location&, - const std::string&)); - - private: - DISALLOW_COPY_AND_ASSIGN(SharedChangeProcessorMock); -}; - -class NonUIDataTypeControllerFake - : public NonUIDataTypeController { - public: - NonUIDataTypeControllerFake( - SyncClient* sync_client, - NonUIDataTypeControllerMock* mock, - SharedChangeProcessor* change_processor, - scoped_refptr<base::SingleThreadTaskRunner> backend_task_runner) - : NonUIDataTypeController(base::ThreadTaskRunnerHandle::Get(), - base::Closure(), - sync_client), - blocked_(false), - mock_(mock), - change_processor_(change_processor), - backend_task_runner_(backend_task_runner) {} - - syncer::ModelType type() const override { return AUTOFILL_PROFILE; } - syncer::ModelSafeGroup model_safe_group() const override { - return syncer::GROUP_DB; - } - - // Prevent tasks from being posted on the backend thread until - // UnblockBackendTasks() is called. - void BlockBackendTasks() { - blocked_ = true; - } - - // Post pending tasks on the backend thread and start allowing tasks - // to be posted on the backend thread again. - void UnblockBackendTasks() { - blocked_ = false; - for (std::vector<PendingTask>::const_iterator it = pending_tasks_.begin(); - it != pending_tasks_.end(); ++it) { - PostTaskOnBackendThread(it->from_here, it->task); - } - pending_tasks_.clear(); - } - - SharedChangeProcessor* CreateSharedChangeProcessor() override { - return change_processor_.get(); - } - - protected: - bool PostTaskOnBackendThread(const tracked_objects::Location& from_here, - const base::Closure& task) override { - if (blocked_) { - pending_tasks_.push_back(PendingTask(from_here, task)); - return true; - } else { - return backend_task_runner_->PostTask(from_here, task); - } - } - - // We mock the following methods because their default implementations do - // nothing, but we still want to make sure they're called appropriately. - bool StartModels() override { return mock_->StartModels(); } - void StopModels() override { mock_->StopModels(); } - void RecordAssociationTime(base::TimeDelta time) override { - mock_->RecordAssociationTime(time); - } - void RecordStartFailure(DataTypeController::ConfigureResult result) override { - mock_->RecordStartFailure(result); - } - - private: - ~NonUIDataTypeControllerFake() override {} - - struct PendingTask { - PendingTask(const tracked_objects::Location& from_here, - const base::Closure& task) - : from_here(from_here), task(task) {} - - tracked_objects::Location from_here; - base::Closure task; - }; - - bool blocked_; - std::vector<PendingTask> pending_tasks_; - NonUIDataTypeControllerMock* mock_; - scoped_refptr<SharedChangeProcessor> change_processor_; - scoped_refptr<base::SingleThreadTaskRunner> backend_task_runner_; - - DISALLOW_COPY_AND_ASSIGN(NonUIDataTypeControllerFake); -}; - -class SyncNonUIDataTypeControllerTest : public testing::Test, - public FakeSyncClient { - public: - SyncNonUIDataTypeControllerTest() - : backend_thread_("dbthread") {} - - void SetUp() override { - backend_thread_.Start(); - change_processor_ = new SharedChangeProcessorMock(); - // All of these are refcounted, so don't need to be released. - dtc_mock_ = new StrictMock<NonUIDataTypeControllerMock>(); - non_ui_dtc_ = new NonUIDataTypeControllerFake( - this, dtc_mock_.get(), change_processor_.get(), - backend_thread_.task_runner()); - } - - void TearDown() override { backend_thread_.Stop(); } - - void WaitForDTC() { - WaitableEvent done(base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED); - backend_thread_.task_runner()->PostTask( - FROM_HERE, - base::Bind(&SyncNonUIDataTypeControllerTest::SignalDone, &done)); - done.TimedWait(TestTimeouts::action_timeout()); - if (!done.IsSignaled()) { - ADD_FAILURE() << "Timed out waiting for DB thread to finish."; - } - base::RunLoop().RunUntilIdle(); - } - - SyncService* GetSyncService() override { - // Make sure this isn't called on backend_thread. - EXPECT_FALSE(backend_thread_.task_runner()->BelongsToCurrentThread()); - return FakeSyncClient::GetSyncService(); - } - - protected: - void SetStartExpectations() { - EXPECT_CALL(*dtc_mock_.get(), StartModels()).WillOnce(Return(true)); - EXPECT_CALL(model_load_callback_, Run(_, _)); - } - - void SetAssociateExpectations() { - EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) - .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); - EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) - .WillOnce(Return(true)); - EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_)) - .WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true))); - EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_, _)) - .WillOnce(Return(syncer::SyncError())); - EXPECT_CALL(*change_processor_.get(), GetSyncCount()).WillOnce(Return(0)); - EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_)); - } - - void SetActivateExpectations(DataTypeController::ConfigureResult result) { - EXPECT_CALL(start_callback_, Run(result, _, _)); - } - - void SetStopExpectations() { - EXPECT_CALL(*dtc_mock_.get(), StopModels()); - EXPECT_CALL(*change_processor_.get(), Disconnect()).WillOnce(Return(true)); - } - - void SetStartFailExpectations(DataTypeController::ConfigureResult result) { - EXPECT_CALL(*dtc_mock_.get(), StopModels()).Times(AtLeast(1)); - EXPECT_CALL(*dtc_mock_.get(), RecordStartFailure(result)); - EXPECT_CALL(start_callback_, Run(result, _, _)); - } - - void Start() { - non_ui_dtc_->LoadModels( - base::Bind(&ModelLoadCallbackMock::Run, - base::Unretained(&model_load_callback_))); - non_ui_dtc_->StartAssociating( - base::Bind(&StartCallbackMock::Run, - base::Unretained(&start_callback_))); - } - - static void SignalDone(WaitableEvent* done) { - done->Signal(); - } - - base::MessageLoopForUI message_loop_; - base::Thread backend_thread_; - - StartCallbackMock start_callback_; - ModelLoadCallbackMock model_load_callback_; - // Must be destroyed after non_ui_dtc_. - syncer::FakeSyncableService syncable_service_; - scoped_refptr<NonUIDataTypeControllerFake> non_ui_dtc_; - scoped_refptr<NonUIDataTypeControllerMock> dtc_mock_; - scoped_refptr<SharedChangeProcessorMock> change_processor_; - std::unique_ptr<syncer::SyncChangeProcessor> saved_change_processor_; -}; - -TEST_F(SyncNonUIDataTypeControllerTest, StartOk) { - SetStartExpectations(); - SetAssociateExpectations(); - SetActivateExpectations(DataTypeController::OK); - EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); - Start(); - WaitForDTC(); - EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); -} - -TEST_F(SyncNonUIDataTypeControllerTest, StartFirstRun) { - SetStartExpectations(); - EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) - .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); - EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) - .WillOnce(Return(true)); - EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_)) - .WillOnce(DoAll(SetArgumentPointee<0>(false), Return(true))); - EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_, _)) - .WillOnce(Return(syncer::SyncError())); - EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_)); - SetActivateExpectations(DataTypeController::OK_FIRST_RUN); - EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); - Start(); - WaitForDTC(); - EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); -} - -// Start the DTC and have StartModels() return false. Then, stop the -// DTC without finishing model startup. It should stop cleanly. -TEST_F(SyncNonUIDataTypeControllerTest, AbortDuringStartModels) { - EXPECT_CALL(*dtc_mock_.get(), StartModels()).WillOnce(Return(false)); - EXPECT_CALL(*dtc_mock_.get(), StopModels()); - EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); - non_ui_dtc_->LoadModels( - base::Bind(&ModelLoadCallbackMock::Run, - base::Unretained(&model_load_callback_))); - WaitForDTC(); - EXPECT_EQ(DataTypeController::MODEL_STARTING, non_ui_dtc_->state()); - non_ui_dtc_->Stop(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); -} - -// Start the DTC and have MergeDataAndStartSyncing() return an error. -// The DTC should become disabled, and the DTC should still stop -// cleanly. -TEST_F(SyncNonUIDataTypeControllerTest, StartAssociationFailed) { - SetStartExpectations(); - EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) - .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); - EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) - .WillOnce(Return(true)); - EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_)) - .WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true))); - EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_, _)) - .WillOnce(Return(syncer::SyncError())); - EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_)); - SetStartFailExpectations(DataTypeController::ASSOCIATION_FAILED); - // Set up association to fail with an association failed error. - EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); - syncable_service_.set_merge_data_and_start_syncing_error( - syncer::SyncError(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Sync Error", - non_ui_dtc_->type())); - Start(); - WaitForDTC(); - EXPECT_EQ(DataTypeController::DISABLED, non_ui_dtc_->state()); - non_ui_dtc_->Stop(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); -} - -TEST_F(SyncNonUIDataTypeControllerTest, - StartAssociationTriggersUnrecoverableError) { - SetStartExpectations(); - SetStartFailExpectations(DataTypeController::UNRECOVERABLE_ERROR); - // Set up association to fail with an unrecoverable error. - EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) - .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); - EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) - .WillRepeatedly(Return(true)); - EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_)) - .WillRepeatedly(DoAll(SetArgumentPointee<0>(false), Return(false))); - EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); - Start(); - WaitForDTC(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); -} - -TEST_F(SyncNonUIDataTypeControllerTest, - StartAssociationCryptoNotReady) { - SetStartExpectations(); - SetStartFailExpectations(DataTypeController::NEEDS_CRYPTO); - // Set up association to fail with a NEEDS_CRYPTO error. - EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) - .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); - EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) - .WillRepeatedly(Return(false)); - EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); - Start(); - WaitForDTC(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); -} - -// Trigger a Stop() call when we check if the model associator has user created -// nodes. -TEST_F(SyncNonUIDataTypeControllerTest, AbortDuringAssociation) { - WaitableEvent wait_for_db_thread_pause( - base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED); - WaitableEvent pause_db_thread( - base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED); - - SetStartExpectations(); - EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) - .WillOnce(GetWeakPtrToSyncableService(&syncable_service_)); - EXPECT_CALL(*change_processor_.get(), CryptoReadyIfNecessary()) - .WillOnce(Return(true)); - EXPECT_CALL(*change_processor_.get(), SyncModelHasUserCreatedNodes(_)) - .WillOnce(DoAll(SignalEvent(&wait_for_db_thread_pause), - WaitOnEvent(&pause_db_thread), - SetArgumentPointee<0>(true), - Return(true))); - EXPECT_CALL(*change_processor_.get(), GetAllSyncDataReturnError(_, _)) - .WillOnce( - Return(syncer::SyncError(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Disconnected.", - AUTOFILL_PROFILE))); - EXPECT_CALL(*dtc_mock_.get(), StopModels()); - EXPECT_CALL(*change_processor_.get(), Disconnect()) - .WillOnce(DoAll(SignalEvent(&pause_db_thread), Return(true))); - EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); - Start(); - wait_for_db_thread_pause.Wait(); - non_ui_dtc_->Stop(); - WaitForDTC(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); -} - -// Start the DTC while the backend tasks are blocked. Then stop the DTC before -// the backend tasks get a chance to run. -TEST_F(SyncNonUIDataTypeControllerTest, StartAfterSyncShutdown) { - non_ui_dtc_->BlockBackendTasks(); - - SetStartExpectations(); - // We don't expect StopSyncing to be called because local_service_ will never - // have been set. - SetStopExpectations(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); - Start(); - non_ui_dtc_->Stop(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); - Mock::VerifyAndClearExpectations(change_processor_.get()); - Mock::VerifyAndClearExpectations(dtc_mock_.get()); - - EXPECT_CALL(*change_processor_.get(), Connect(_, _, _, _, _, _)) - .WillOnce(Return(base::WeakPtr<syncer::SyncableService>())); - non_ui_dtc_->UnblockBackendTasks(); - WaitForDTC(); -} - -TEST_F(SyncNonUIDataTypeControllerTest, Stop) { - SetStartExpectations(); - SetAssociateExpectations(); - SetActivateExpectations(DataTypeController::OK); - SetStopExpectations(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); - Start(); - WaitForDTC(); - EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); - non_ui_dtc_->Stop(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); -} - -// Start the DTC then block its backend tasks. While its backend -// tasks are blocked, stop and start it again, then unblock its -// backend tasks. The (delayed) running of the backend tasks from the -// stop after the restart shouldn't cause any problems. -TEST_F(SyncNonUIDataTypeControllerTest, StopStart) { - SetStartExpectations(); - SetAssociateExpectations(); - SetActivateExpectations(DataTypeController::OK); - SetStopExpectations(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); - Start(); - WaitForDTC(); - EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); - - non_ui_dtc_->BlockBackendTasks(); - non_ui_dtc_->Stop(); - SetStartExpectations(); - SetAssociateExpectations(); - SetActivateExpectations(DataTypeController::OK); - EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); - Start(); - non_ui_dtc_->UnblockBackendTasks(); - - WaitForDTC(); - EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); -} - -TEST_F(SyncNonUIDataTypeControllerTest, OnSingleDataTypeUnrecoverableError) { - SetStartExpectations(); - SetAssociateExpectations(); - SetActivateExpectations(DataTypeController::OK); - EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); - Start(); - WaitForDTC(); - EXPECT_EQ(DataTypeController::RUNNING, non_ui_dtc_->state()); - - testing::Mock::VerifyAndClearExpectations(&start_callback_); - EXPECT_CALL(model_load_callback_, Run(_, _)); - syncer::SyncError error(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "error", - non_ui_dtc_->type()); - backend_thread_.task_runner()->PostTask( - FROM_HERE, - base::Bind( - &NonUIDataTypeControllerFake::OnSingleDataTypeUnrecoverableError, - non_ui_dtc_.get(), error)); - WaitForDTC(); -} - -} // namespace - -} // namespace sync_driver
diff --git a/components/sync_driver/non_ui_model_type_controller.cc b/components/sync_driver/non_ui_model_type_controller.cc deleted file mode 100644 index 7f0a84c..0000000 --- a/components/sync_driver/non_ui_model_type_controller.cc +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2016 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/sync_driver/non_ui_model_type_controller.h" - -#include "components/sync/api/model_type_service.h" -#include "components/sync/base/model_type.h" -#include "components/sync/core/activation_context.h" -#include "components/sync_driver/sync_client.h" - -namespace sync_driver_v2 { - -using sync_driver::SyncClient; - -NonUIModelTypeController::NonUIModelTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const base::Closure& error_callback, - syncer::ModelType model_type, - SyncClient* sync_client) - : NonBlockingDataTypeController(ui_thread, - error_callback, - model_type, - sync_client) {} - -NonUIModelTypeController::~NonUIModelTypeController() {} - -void NonUIModelTypeController::RunOnUIThread( - const tracked_objects::Location& from_here, - const base::Closure& task) { - DCHECK(!BelongsToUIThread()); - ui_thread()->PostTask(from_here, task); -} - -} // namespace sync_driver_v2
diff --git a/components/sync_driver/non_ui_model_type_controller.h b/components/sync_driver/non_ui_model_type_controller.h deleted file mode 100644 index 1bb5997..0000000 --- a/components/sync_driver/non_ui_model_type_controller.h +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2016 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_SYNC_DRIVER_NON_UI_MODEL_TYPE_CONTROLLER_H_ -#define COMPONENTS_SYNC_DRIVER_NON_UI_MODEL_TYPE_CONTROLLER_H_ - -#include "components/sync_driver/non_blocking_data_type_controller.h" - -namespace sync_driver { -class SyncClient; -} - -namespace sync_driver_v2 { - -// Implementation for Unified Sync and Storage datatypes whose model thread is -// not the UI thread. -// Derived types must implement the following methods: -// - RunOnModelThread -class NonUIModelTypeController : public NonBlockingDataTypeController { - public: - NonUIModelTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const base::Closure& error_callback, - syncer::ModelType model_type, - sync_driver::SyncClient* sync_client); - - void RunOnUIThread(const tracked_objects::Location& from_here, - const base::Closure& task) override; - - protected: - ~NonUIModelTypeController() override; - - private: - DISALLOW_COPY_AND_ASSIGN(NonUIModelTypeController); -}; - -} // namespace sync_driver_v2 - -#endif // COMPONENTS_SYNC_DRIVER_NON_UI_MODEL_TYPE_CONTROLLER_H_
diff --git a/components/sync_driver/non_ui_model_type_controller_unittest.cc b/components/sync_driver/non_ui_model_type_controller_unittest.cc deleted file mode 100644 index 0db3f98..0000000 --- a/components/sync_driver/non_ui_model_type_controller_unittest.cc +++ /dev/null
@@ -1,377 +0,0 @@ -// Copyright 2016 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/sync_driver/non_ui_model_type_controller.h" - -#include <memory> -#include <utility> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/logging.h" -#include "base/memory/ptr_util.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/sequenced_task_runner.h" -#include "base/test/test_simple_task_runner.h" -#include "base/threading/thread.h" -#include "components/sync/api/fake_model_type_service.h" -#include "components/sync/core/activation_context.h" -#include "components/sync/core/shared_model_type_processor.h" -#include "components/sync/engine_impl/commit_queue.h" -#include "components/sync_driver/backend_data_type_configurer.h" -#include "components/sync_driver/fake_sync_client.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sync_driver_v2 { - -namespace { - -// Test controller derived from NonUIModelTypeController. -class TestNonUIModelTypeController : public NonUIModelTypeController { - public: - TestNonUIModelTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const scoped_refptr<base::TaskRunner>& model_task_runner, - const base::Closure& error_callback, - syncer::ModelType model_type, - sync_driver::SyncClient* sync_client) - : NonUIModelTypeController(ui_thread, - error_callback, - model_type, - sync_client), - model_task_runner_(model_task_runner) {} - - bool RunOnModelThread(const tracked_objects::Location& from_here, - const base::Closure& task) override { - DCHECK(model_task_runner_); - return model_task_runner_->PostTask(from_here, task); - } - - private: - ~TestNonUIModelTypeController() override {} - - scoped_refptr<base::TaskRunner> model_task_runner_; -}; - -// A no-op instance of CommitQueue. -class NullCommitQueue : public syncer_v2::CommitQueue { - public: - NullCommitQueue() {} - ~NullCommitQueue() override {} - - void EnqueueForCommit(const syncer_v2::CommitRequestDataList& list) override { - NOTREACHED() << "Not implemented."; - } -}; - -// A class that pretends to be the sync backend. -class MockSyncBackend { - public: - void Connect( - syncer::ModelType type, - std::unique_ptr<syncer_v2::ActivationContext> activation_context) { - enabled_types_.Put(type); - activation_context->type_processor->ConnectSync( - base::WrapUnique(new NullCommitQueue())); - } - - void Disconnect(syncer::ModelType type) { - DCHECK(enabled_types_.Has(type)); - enabled_types_.Remove(type); - } - - private: - syncer::ModelTypeSet enabled_types_; -}; - -// Fake implementation of BackendDataTypeConfigurer that pretends to be Sync -// backend. -class MockBackendDataTypeConfigurer - : public sync_driver::BackendDataTypeConfigurer { - public: - MockBackendDataTypeConfigurer( - MockSyncBackend* backend, - const scoped_refptr<base::TaskRunner>& sync_task_runner) - : backend_(backend), sync_task_runner_(sync_task_runner) {} - ~MockBackendDataTypeConfigurer() override {} - - syncer::ModelTypeSet ConfigureDataTypes( - syncer::ConfigureReason reason, - const DataTypeConfigStateMap& config_state_map, - const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& - ready_task, - const base::Callback<void()>& retry_callback) override { - NOTREACHED() << "Not implemented."; - return syncer::ModelTypeSet(); - } - - void ActivateDirectoryDataType( - syncer::ModelType type, - syncer::ModelSafeGroup group, - sync_driver::ChangeProcessor* change_processor) override { - NOTREACHED() << "Not implemented."; - } - - void DeactivateDirectoryDataType(syncer::ModelType type) override { - NOTREACHED() << "Not implemented."; - } - - void ActivateNonBlockingDataType(syncer::ModelType type, - std::unique_ptr<syncer_v2::ActivationContext> - activation_context) override { - // Post on Sync thread just like the real implementation does. - sync_task_runner_->PostTask( - FROM_HERE, - base::Bind(&MockSyncBackend::Connect, base::Unretained(backend_), type, - base::Passed(std::move(activation_context)))); - } - - void DeactivateNonBlockingDataType(syncer::ModelType type) override { - sync_task_runner_->PostTask(FROM_HERE, - base::Bind(&MockSyncBackend::Disconnect, - base::Unretained(backend_), type)); - } - - private: - MockSyncBackend* backend_; - scoped_refptr<base::TaskRunner> sync_task_runner_; -}; - -} // namespace - -class NonUIModelTypeControllerTest : public testing::Test, - public sync_driver::FakeSyncClient { - public: - NonUIModelTypeControllerTest() - : auto_run_tasks_(true), - load_models_callback_called_(false), - association_callback_called_(false), - model_thread_("modelthread"), - configurer_(&backend_, ui_loop_.task_runner()) {} - - ~NonUIModelTypeControllerTest() override {} - - void SetUp() override { - model_thread_.Start(); - model_thread_runner_ = model_thread_.task_runner(); - InitializeModelTypeService(); - controller_ = new TestNonUIModelTypeController( - ui_loop_.task_runner(), model_thread_runner_, base::Closure(), - syncer::DICTIONARY, this); - } - - void TearDown() override { - ClearModelTypeService(); - controller_ = NULL; - RunQueuedUIThreadTasks(); - } - - syncer_v2::ModelTypeService* GetModelTypeServiceForType( - syncer::ModelType type) override { - return service_.get(); - } - - protected: - std::unique_ptr<syncer_v2::ModelTypeChangeProcessor> CreateProcessor( - syncer::ModelType type, - syncer_v2::ModelTypeService* service) { - std::unique_ptr<syncer_v2::SharedModelTypeProcessor> processor = - base::WrapUnique( - new syncer_v2::SharedModelTypeProcessor(type, service)); - type_processor_ = processor.get(); - return std::move(processor); - } - - void InitializeModelTypeService() { - if (!model_thread_runner_ || - model_thread_runner_->BelongsToCurrentThread()) { - service_.reset(new syncer_v2::FakeModelTypeService( - base::Bind(&NonUIModelTypeControllerTest::CreateProcessor, - base::Unretained(this)))); - } else { - model_thread_runner_->PostTask( - FROM_HERE, - base::Bind(&NonUIModelTypeControllerTest::InitializeModelTypeService, - base::Unretained(this))); - RunQueuedModelThreadTasks(); - } - } - - void ClearModelTypeService() { - if (!model_thread_runner_ || - model_thread_runner_->BelongsToCurrentThread()) { - service_.reset(); - } else { - model_thread_runner_->PostTask( - FROM_HERE, - base::Bind(&NonUIModelTypeControllerTest::ClearModelTypeService, - base::Unretained(this))); - RunQueuedModelThreadTasks(); - } - } - - void ExpectProcessorConnected(bool isConnected) { - if (model_thread_runner_->BelongsToCurrentThread()) { - DCHECK(type_processor_); - EXPECT_EQ(isConnected, type_processor_->IsConnected()); - } else { - model_thread_runner_->PostTask( - FROM_HERE, - base::Bind(&NonUIModelTypeControllerTest::ExpectProcessorConnected, - base::Unretained(this), isConnected)); - RunQueuedModelThreadTasks(); - } - } - - void OnMetadataLoaded() { - if (model_thread_runner_->BelongsToCurrentThread()) { - if (!type_processor_->IsAllowingChanges()) { - type_processor_->OnMetadataLoaded( - syncer::SyncError(), - base::WrapUnique(new syncer_v2::MetadataBatch())); - } - } else { - model_thread_runner_->PostTask( - FROM_HERE, base::Bind(&NonUIModelTypeControllerTest::OnMetadataLoaded, - base::Unretained(this))); - } - } - - void LoadModels() { - controller_->LoadModels(base::Bind( - &NonUIModelTypeControllerTest::LoadModelsDone, base::Unretained(this))); - OnMetadataLoaded(); - - if (auto_run_tasks_) { - RunAllTasks(); - } - } - - void RegisterWithBackend() { - controller_->RegisterWithBackend(&configurer_); - if (auto_run_tasks_) { - RunAllTasks(); - } - } - - void StartAssociating() { - controller_->StartAssociating( - base::Bind(&NonUIModelTypeControllerTest::AssociationDone, - base::Unretained(this))); - // The callback is expected to be promptly called. - EXPECT_TRUE(association_callback_called_); - } - - void DeactivateDataTypeAndStop() { - controller_->DeactivateDataType(&configurer_); - controller_->Stop(); - if (auto_run_tasks_) { - RunAllTasks(); - } - } - - // These threads can ping-pong for a bit so we run the model thread twice. - void RunAllTasks() { - RunQueuedModelThreadTasks(); - RunQueuedUIThreadTasks(); - RunQueuedModelThreadTasks(); - } - - // Runs any tasks posted on UI thread. - void RunQueuedUIThreadTasks() { ui_loop_.RunUntilIdle(); } - - // Runs any tasks posted on model thread. - void RunQueuedModelThreadTasks() { - base::RunLoop run_loop; - model_thread_runner_->PostTaskAndReply( - FROM_HERE, base::Bind(&base::DoNothing), - base::Bind(&base::RunLoop::Quit, base::Unretained(&run_loop))); - run_loop.Run(); - } - - void SetAutoRunTasks(bool auto_run_tasks) { - auto_run_tasks_ = auto_run_tasks; - } - - void LoadModelsDone(syncer::ModelType type, syncer::SyncError error) { - load_models_callback_called_ = true; - load_models_error_ = error; - } - - void AssociationDone(sync_driver::DataTypeController::ConfigureResult result, - const syncer::SyncMergeResult& local_merge_result, - const syncer::SyncMergeResult& syncer_merge_result) { - EXPECT_EQ(sync_driver::DataTypeController::OK, result); - association_callback_called_ = true; - } - - syncer_v2::SharedModelTypeProcessor* type_processor_; - scoped_refptr<TestNonUIModelTypeController> controller_; - - bool auto_run_tasks_; - bool load_models_callback_called_; - syncer::SyncError load_models_error_; - bool association_callback_called_; - base::MessageLoopForUI ui_loop_; - base::Thread model_thread_; - scoped_refptr<base::SingleThreadTaskRunner> model_thread_runner_; - MockSyncBackend backend_; - MockBackendDataTypeConfigurer configurer_; - std::unique_ptr<syncer_v2::FakeModelTypeService> service_; -}; - -TEST_F(NonUIModelTypeControllerTest, InitialState) { - EXPECT_EQ(syncer::DICTIONARY, controller_->type()); - EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); -} - -TEST_F(NonUIModelTypeControllerTest, LoadModelsOnBackendThread) { - SetAutoRunTasks(false); - LoadModels(); - EXPECT_EQ(sync_driver::DataTypeController::MODEL_STARTING, - controller_->state()); - RunAllTasks(); - EXPECT_EQ(sync_driver::DataTypeController::MODEL_LOADED, - controller_->state()); - EXPECT_TRUE(load_models_callback_called_); - EXPECT_FALSE(load_models_error_.IsSet()); - ExpectProcessorConnected(false); -} - -TEST_F(NonUIModelTypeControllerTest, LoadModelsTwice) { - LoadModels(); - SetAutoRunTasks(false); - LoadModels(); - EXPECT_EQ(sync_driver::DataTypeController::MODEL_LOADED, - controller_->state()); - // The second LoadModels call should set the error. - EXPECT_TRUE(load_models_error_.IsSet()); -} - -TEST_F(NonUIModelTypeControllerTest, ActivateDataTypeOnBackendThread) { - LoadModels(); - EXPECT_EQ(sync_driver::DataTypeController::MODEL_LOADED, - controller_->state()); - RegisterWithBackend(); - ExpectProcessorConnected(true); - - StartAssociating(); - EXPECT_EQ(sync_driver::DataTypeController::RUNNING, controller_->state()); -} - -TEST_F(NonUIModelTypeControllerTest, Stop) { - LoadModels(); - RegisterWithBackend(); - ExpectProcessorConnected(true); - - StartAssociating(); - - DeactivateDataTypeAndStop(); - EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); -} - -} // namespace sync_driver_v2
diff --git a/components/sync_driver/pref_names.cc b/components/sync_driver/pref_names.cc deleted file mode 100644 index a2cee32..0000000 --- a/components/sync_driver/pref_names.cc +++ /dev/null
@@ -1,129 +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 "build/build_config.h" -#include "components/sync_driver/pref_names.h" - -namespace sync_driver { - -namespace prefs { - -// 64-bit integer serialization of the base::Time when the last sync occurred. -const char kSyncLastSyncedTime[] = "sync.last_synced_time"; - -// 64-bit integer serialization of the base::Time of the last sync poll. -const char kSyncLastPollTime[] = "sync.last_poll_time"; - -// Boolean specifying whether the user finished setting up sync at least once. -const char kSyncFirstSetupComplete[] = "sync.has_setup_completed"; - -// Boolean specifying whether sync has an auth error. -const char kSyncHasAuthError[] = "sync.has_auth_error"; - -// Boolean specifying whether to automatically sync all data types (including -// future ones, as they're added). If this is true, the following preferences -// (kSyncBookmarks, kSyncPasswords, etc.) can all be ignored. -const char kSyncKeepEverythingSynced[] = "sync.keep_everything_synced"; - -// Booleans specifying whether the user has selected to sync the following -// datatypes. -const char kSyncAppList[] = "sync.app_list"; -const char kSyncAppNotifications[] = "sync.app_notifications"; -const char kSyncAppSettings[] = "sync.app_settings"; -const char kSyncApps[] = "sync.apps"; -const char kSyncArcPackage[] = "sync.arc_package"; -const char kSyncArticles[] = "sync.articles"; -const char kSyncAutofillProfile[] = "sync.autofill_profile"; -const char kSyncAutofillWallet[] = "sync.autofill_wallet"; -const char kSyncAutofillWalletMetadata[] = "sync.autofill_wallet_metadata"; -const char kSyncAutofill[] = "sync.autofill"; -const char kSyncBookmarks[] = "sync.bookmarks"; -const char kSyncDeviceInfo[] = "sync.device_info"; -const char kSyncDictionary[] = "sync.dictionary"; -const char kSyncExtensionSettings[] = "sync.extension_settings"; -const char kSyncExtensions[] = "sync.extensions"; -const char kSyncFaviconImages[] = "sync.favicon_images"; -const char kSyncFaviconTracking[] = "sync.favicon_tracking"; -const char kSyncHistoryDeleteDirectives[] = "sync.history_delete_directives"; -const char kSyncPasswords[] = "sync.passwords"; -const char kSyncPreferences[] = "sync.preferences"; -const char kSyncPriorityPreferences[] = "sync.priority_preferences"; -const char kSyncSearchEngines[] = "sync.search_engines"; -const char kSyncSessions[] = "sync.sessions"; -const char kSyncSupervisedUserSettings[] = "sync.managed_user_settings"; -const char kSyncSupervisedUserSharedSettings[] = - "sync.managed_user_shared_settings"; -const char kSyncSupervisedUserWhitelists[] = - "sync.managed_user_whitelists"; -const char kSyncSupervisedUsers[] = "sync.managed_users"; -const char kSyncSyncedNotificationAppInfo[] = - "sync.synced_notification_app_info"; -const char kSyncSyncedNotifications[] = "sync.synced_notifications"; -const char kSyncTabs[] = "sync.tabs"; -const char kSyncThemes[] = "sync.themes"; -const char kSyncTypedUrls[] = "sync.typed_urls"; -const char kSyncWifiCredentials[] = "sync.wifi_credentials"; - -// Boolean used by enterprise configuration management in order to lock down -// sync. -const char kSyncManaged[] = "sync.managed"; - -// Boolean to prevent sync from automatically starting up. This is -// used when sync is disabled by the user via the privacy dashboard. -const char kSyncSuppressStart[] = "sync.suppress_start"; - -// A string that can be used to restore sync encryption infrastructure on -// startup so that the user doesn't need to provide credentials on each start. -const char kSyncEncryptionBootstrapToken[] = "sync.encryption_bootstrap_token"; - -// Same as kSyncEncryptionBootstrapToken, but derived from the keystore key, -// so we don't have to do a GetKey command at restart. -const char kSyncKeystoreEncryptionBootstrapToken[] = - "sync.keystore_encryption_bootstrap_token"; - -// The GUID session sync will use to identify this client, even across sync -// disable/enable events. -const char kSyncSessionsGUID[] = "sync.session_sync_guid"; - -#if defined(OS_CHROMEOS) -// A string that is used to store first-time sync startup after once sync is -// disabled. This will be refreshed every sign-in. -const char kSyncSpareBootstrapToken[] = "sync.spare_bootstrap_token"; -#endif // defined(OS_CHROMEOS) - -// Stores the timestamp of first sync. -const char kSyncFirstSyncTime[] = "sync.first_sync_time"; - -// Stores whether a platform specific passphrase error prompt has been shown to -// the user (e.g. an Android system notification). Used for out of band prompts -// that we only want to use once. -const char kSyncPassphrasePrompted[] = "sync.passphrase_prompted"; - -// Stores how many times received MEMORY_PRESSURE_LEVEL_CRITICAL. -const char kSyncMemoryPressureWarningCount[] = "sync.memory_warning_count"; - -// Stores if sync shutdown cleanly. -const char kSyncShutdownCleanly[] = "sync.shutdown_cleanly"; - -// Dictionary of last seen invalidation versions for each model type. -const char kSyncInvalidationVersions[] = "sync.invalidation_versions"; - -// The product version from the last restart of Chrome. -const char kSyncLastRunVersion[] = "sync.last_run_version"; - -// Flag indicating that passphrase encryption transition is in progress. -// Transition involves multiple steps and should continue across restarts. -const char kSyncPassphraseEncryptionTransitionInProgress[] = - "sync.passphrase_encryption_transition_in_progress"; - -// Updated Nigori state after user entering passphrase. This Nigori state should -// be persisted across restarts and passed to backend when it is initialized -// after directory cleanup. Preference contains base64 encoded serialized -// sync_pb::NigoriSpecifics. -const char kSyncNigoriStateForPassphraseTransition[] = - "sync.nigori_state_for_passphrase_transition"; - -} // namespace prefs - -} // namespace sync_driver
diff --git a/components/sync_driver/protocol_event_observer.cc b/components/sync_driver/protocol_event_observer.cc deleted file mode 100644 index 8a3277a..0000000 --- a/components/sync_driver/protocol_event_observer.cc +++ /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. - -#include "components/sync_driver/protocol_event_observer.h" - -namespace browser_sync { - -ProtocolEventObserver::ProtocolEventObserver() {} - -ProtocolEventObserver::~ProtocolEventObserver() {} - -} // namespace browser_sync
diff --git a/components/sync_driver/proxy_data_type_controller.cc b/components/sync_driver/proxy_data_type_controller.cc deleted file mode 100644 index b0e3824..0000000 --- a/components/sync_driver/proxy_data_type_controller.cc +++ /dev/null
@@ -1,75 +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 "components/sync_driver/proxy_data_type_controller.h" - -#include "components/sync/api/sync_merge_result.h" - -namespace sync_driver { - -ProxyDataTypeController::ProxyDataTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - syncer::ModelType type) - : DataTypeController(ui_thread, base::Closure()), - state_(NOT_RUNNING), - type_(type) { - DCHECK(syncer::ProxyTypes().Has(type_)); -} - -ProxyDataTypeController::~ProxyDataTypeController() { -} - -bool ProxyDataTypeController::ShouldLoadModelBeforeConfigure() const { - return false; -} - -void ProxyDataTypeController::LoadModels( - const ModelLoadCallback& model_load_callback) { - state_ = MODEL_LOADED; - model_load_callback.Run(type(), syncer::SyncError()); -} - -void ProxyDataTypeController::RegisterWithBackend( - BackendDataTypeConfigurer* configurer) {} - -void ProxyDataTypeController::StartAssociating( - const StartCallback& start_callback) { - syncer::SyncMergeResult local_merge_result(type_); - syncer::SyncMergeResult syncer_merge_result(type_); - state_ = RUNNING; - start_callback.Run(DataTypeController::OK, - local_merge_result, - syncer_merge_result); -} - -void ProxyDataTypeController::Stop() { - state_ = NOT_RUNNING; -} - -syncer::ModelType ProxyDataTypeController::type() const { - DCHECK(syncer::ProxyTypes().Has(type_)); - return type_; -} - -std::string ProxyDataTypeController::name() const { - // For logging only. - return syncer::ModelTypeToString(type()); -} - -DataTypeController::State ProxyDataTypeController::state() const { - return state_; -} - -void ProxyDataTypeController::OnSingleDataTypeUnrecoverableError( - const syncer::SyncError& error) { - NOTIMPLEMENTED(); -} - -void ProxyDataTypeController::ActivateDataType( - BackendDataTypeConfigurer* configurer) {} - -void ProxyDataTypeController::DeactivateDataType( - BackendDataTypeConfigurer* configurer) {} - -} // namespace sync_driver
diff --git a/components/sync_driver/proxy_data_type_controller.h b/components/sync_driver/proxy_data_type_controller.h deleted file mode 100644 index 5e075e2..0000000 --- a/components/sync_driver/proxy_data_type_controller.h +++ /dev/null
@@ -1,57 +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 COMPONENTS_SYNC_DRIVER_PROXY_DATA_TYPE_CONTROLLER_H__ -#define COMPONENTS_SYNC_DRIVER_PROXY_DATA_TYPE_CONTROLLER_H__ - -#include <string> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/single_thread_task_runner.h" -#include "components/sync_driver/data_type_controller.h" - -namespace sync_driver { - -// Implementation for proxy datatypes. These are datatype that have no -// representation in sync, and therefore no change processor or syncable -// service. -class ProxyDataTypeController : public DataTypeController { - public: - explicit ProxyDataTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - syncer::ModelType type); - - // DataTypeController interface. - bool ShouldLoadModelBeforeConfigure() const override; - void LoadModels(const ModelLoadCallback& model_load_callback) override; - void RegisterWithBackend(BackendDataTypeConfigurer* configurer) override; - void StartAssociating(const StartCallback& start_callback) override; - void Stop() override; - syncer::ModelType type() const override; - std::string name() const override; - State state() const override; - void ActivateDataType(BackendDataTypeConfigurer* configurer) override; - void DeactivateDataType(BackendDataTypeConfigurer* configurer) override; - - // DataTypeErrorHandler interface. - void OnSingleDataTypeUnrecoverableError( - const syncer::SyncError& error) override; - - protected: - // DataTypeController is RefCounted. - ~ProxyDataTypeController() override; - - private: - State state_; - - // The actual type for this controller. - syncer::ModelType type_; - - DISALLOW_COPY_AND_ASSIGN(ProxyDataTypeController); -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_PROXY_DATA_TYPE_CONTROLLER_H__
diff --git a/components/sync_driver/resources/sync_node_browser.css b/components/sync_driver/resources/sync_node_browser.css deleted file mode 100644 index 8d41d51..0000000 --- a/components/sync_driver/resources/sync_node_browser.css +++ /dev/null
@@ -1,68 +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. */ - -#sync-node-browser-refresher { - border-bottom: 1px rgb(160,160,160) solid; -} - -#sync-node-browser-refresher > * { - display: inline-block; -} - -#sync-node-browser-container { - display: flex; - height: 750px; -} - -#sync-node-tree-container { - -webkit-padding-start: 10px; - box-sizing: border-box; - height: 100%; - /* min-width and max-width are used by the split pane. */ - max-width: 50%; - min-width: 200px; - overflow: auto; - width: 200px; -} - -#sync-node-tree { - display: inline-block; - min-width: 100%; - overflow: visible; /* let the container do the scrolling */ -} - -/* TODO(akalin): Find a better icon to use for leaf nodes. */ -#sync-node-tree .leaf .tree-label { - background-image: url(../../../ui/webui/resources/images/star_small.png); -} - -#sync-node-splitter { - background-color: rgb(235, 239, 249); - cursor: col-resize; - min-width: 5px; -<if expr="is_win"> - /* TODO(akalin): Make the BMM also use this style. */ - cursor: e-resize; -</if> -} - -#sync-node-details-container { - flex: 1; - height: 100%; - overflow: auto; - visibility: hidden; /* Element is invisible until first refresh. */ -} - -#node-details { - flex-grow: 1; -} - -#node-details td { - vertical-align: top; - white-space: nowrap; -} - -#node-details tr:nth-child(odd) { - background: rgb(239, 243, 255); -}
diff --git a/components/sync_driver/shared_change_processor.cc b/components/sync_driver/shared_change_processor.cc deleted file mode 100644 index eee40d2..0000000 --- a/components/sync_driver/shared_change_processor.cc +++ /dev/null
@@ -1,225 +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 "components/sync_driver/shared_change_processor.h" - -#include <utility> - -#include "base/threading/thread_task_runner_handle.h" -#include "components/sync/api/sync_change.h" -#include "components/sync/api/syncable_service.h" -#include "components/sync/core/data_type_error_handler.h" -#include "components/sync_driver/generic_change_processor.h" -#include "components/sync_driver/generic_change_processor_factory.h" -#include "components/sync_driver/sync_client.h" - -using base::AutoLock; - -namespace syncer { -class AttachmentService; -} - -namespace sync_driver { - -SharedChangeProcessor::SharedChangeProcessor() - : disconnected_(false), - type_(syncer::UNSPECIFIED), - frontend_task_runner_(base::ThreadTaskRunnerHandle::Get()), - generic_change_processor_(NULL), - error_handler_(NULL) { -} - -SharedChangeProcessor::~SharedChangeProcessor() { - // We can either be deleted when the DTC is destroyed (on UI - // thread), or when the syncer::SyncableService stops syncing (datatype - // thread). |generic_change_processor_|, if non-NULL, must be - // deleted on |backend_loop_|. - if (backend_task_runner_.get()) { - if (backend_task_runner_->BelongsToCurrentThread()) { - delete generic_change_processor_; - } else { - DCHECK(frontend_task_runner_->BelongsToCurrentThread()); - if (!backend_task_runner_->DeleteSoon(FROM_HERE, - generic_change_processor_)) { - NOTREACHED(); - } - } - } else { - DCHECK(!generic_change_processor_); - } -} - -base::WeakPtr<syncer::SyncableService> SharedChangeProcessor::Connect( - SyncClient* sync_client, - GenericChangeProcessorFactory* processor_factory, - syncer::UserShare* user_share, - syncer::DataTypeErrorHandler* error_handler, - syncer::ModelType type, - const base::WeakPtr<syncer::SyncMergeResult>& merge_result) { - DCHECK(sync_client); - DCHECK(error_handler); - DCHECK_NE(type, syncer::UNSPECIFIED); - backend_task_runner_ = base::ThreadTaskRunnerHandle::Get(); - AutoLock lock(monitor_lock_); - if (disconnected_) - return base::WeakPtr<syncer::SyncableService>(); - type_ = type; - error_handler_ = error_handler; - base::WeakPtr<syncer::SyncableService> local_service = - sync_client->GetSyncableServiceForType(type); - if (!local_service.get()) { - LOG(WARNING) << "SyncableService destroyed before DTC was stopped."; - disconnected_ = true; - return base::WeakPtr<syncer::SyncableService>(); - } - - generic_change_processor_ = - processor_factory->CreateGenericChangeProcessor(type, - user_share, - error_handler, - local_service, - merge_result, - sync_client).release(); - // If available, propagate attachment service to the syncable service. - std::unique_ptr<syncer::AttachmentService> attachment_service = - generic_change_processor_->GetAttachmentService(); - if (attachment_service) { - local_service->SetAttachmentService(std::move(attachment_service)); - } - return local_service; -} - -bool SharedChangeProcessor::Disconnect() { - // May be called from any thread. - DVLOG(1) << "Disconnecting change processor."; - AutoLock lock(monitor_lock_); - bool was_connected = !disconnected_; - disconnected_ = true; - error_handler_ = NULL; - return was_connected; -} - -ChangeProcessor* SharedChangeProcessor::generic_change_processor() { - return generic_change_processor_; -} - -int SharedChangeProcessor::GetSyncCount() { - DCHECK(backend_task_runner_.get()); - DCHECK(backend_task_runner_->BelongsToCurrentThread()); - AutoLock lock(monitor_lock_); - if (disconnected_) { - LOG(ERROR) << "Change processor disconnected."; - return 0; - } - return generic_change_processor_->GetSyncCount(); -} - -syncer::SyncError SharedChangeProcessor::ProcessSyncChanges( - const tracked_objects::Location& from_here, - const syncer::SyncChangeList& list_of_changes) { - DCHECK(backend_task_runner_.get()); - DCHECK(backend_task_runner_->BelongsToCurrentThread()); - AutoLock lock(monitor_lock_); - if (disconnected_) { - // The DTC that disconnects us must ensure it posts a StopSyncing task. - // If we reach this, it means it just hasn't executed yet. - syncer::SyncError error(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Change processor disconnected.", - type_); - return error; - } - return generic_change_processor_->ProcessSyncChanges( - from_here, list_of_changes); -} - -syncer::SyncDataList SharedChangeProcessor::GetAllSyncData( - syncer::ModelType type) const { - syncer::SyncDataList data; - GetAllSyncDataReturnError(type, &data); // Handles the disconnect case. - return data; -} - -syncer::SyncError SharedChangeProcessor::GetAllSyncDataReturnError( - syncer::ModelType type, - syncer::SyncDataList* data) const { - DCHECK(backend_task_runner_.get()); - DCHECK(backend_task_runner_->BelongsToCurrentThread()); - AutoLock lock(monitor_lock_); - if (disconnected_) { - syncer::SyncError error(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Change processor disconnected.", - type_); - return error; - } - return generic_change_processor_->GetAllSyncDataReturnError(data); -} - -syncer::SyncError SharedChangeProcessor::UpdateDataTypeContext( - syncer::ModelType type, - syncer::SyncChangeProcessor::ContextRefreshStatus refresh_status, - const std::string& context) { - DCHECK(backend_task_runner_.get()); - DCHECK(backend_task_runner_->BelongsToCurrentThread()); - AutoLock lock(monitor_lock_); - if (disconnected_) { - syncer::SyncError error(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Change processor disconnected.", - type_); - return error; - } - return generic_change_processor_->UpdateDataTypeContext( - type, refresh_status, context); -} - -bool SharedChangeProcessor::SyncModelHasUserCreatedNodes(bool* has_nodes) { - DCHECK(backend_task_runner_.get()); - DCHECK(backend_task_runner_->BelongsToCurrentThread()); - AutoLock lock(monitor_lock_); - if (disconnected_) { - LOG(ERROR) << "Change processor disconnected."; - return false; - } - return generic_change_processor_->SyncModelHasUserCreatedNodes(has_nodes); -} - -bool SharedChangeProcessor::CryptoReadyIfNecessary() { - DCHECK(backend_task_runner_.get()); - DCHECK(backend_task_runner_->BelongsToCurrentThread()); - AutoLock lock(monitor_lock_); - if (disconnected_) { - LOG(ERROR) << "Change processor disconnected."; - return true; // Otherwise we get into infinite spin waiting. - } - return generic_change_processor_->CryptoReadyIfNecessary(); -} - -bool SharedChangeProcessor::GetDataTypeContext(std::string* context) const { - DCHECK(backend_task_runner_.get()); - DCHECK(backend_task_runner_->BelongsToCurrentThread()); - AutoLock lock(monitor_lock_); - if (disconnected_) { - LOG(ERROR) << "Change processor disconnected."; - return false; - } - return generic_change_processor_->GetDataTypeContext(context); -} - -syncer::SyncError SharedChangeProcessor::CreateAndUploadError( - const tracked_objects::Location& location, - const std::string& message) { - AutoLock lock(monitor_lock_); - if (!disconnected_) { - return error_handler_->CreateAndUploadError(location, message, type_); - } else { - return syncer::SyncError(location, - syncer::SyncError::DATATYPE_ERROR, - message, - type_); - } -} - -} // namespace sync_driver
diff --git a/components/sync_driver/shared_change_processor_ref.cc b/components/sync_driver/shared_change_processor_ref.cc deleted file mode 100644 index 0ba2605..0000000 --- a/components/sync_driver/shared_change_processor_ref.cc +++ /dev/null
@@ -1,42 +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 "components/sync_driver/shared_change_processor_ref.h" - -namespace sync_driver { - -SharedChangeProcessorRef::SharedChangeProcessorRef( - const scoped_refptr<SharedChangeProcessor>& change_processor) - : change_processor_(change_processor) { - DCHECK(change_processor_.get()); -} - -SharedChangeProcessorRef::~SharedChangeProcessorRef() {} - -syncer::SyncError SharedChangeProcessorRef::ProcessSyncChanges( - const tracked_objects::Location& from_here, - const syncer::SyncChangeList& change_list) { - return change_processor_->ProcessSyncChanges(from_here, change_list); -} - -syncer::SyncDataList SharedChangeProcessorRef::GetAllSyncData( - syncer::ModelType type) const { - return change_processor_->GetAllSyncData(type); -} - -syncer::SyncError SharedChangeProcessorRef::UpdateDataTypeContext( - syncer::ModelType type, - syncer::SyncChangeProcessor::ContextRefreshStatus refresh_status, - const std::string& context) { - return change_processor_->UpdateDataTypeContext( - type, refresh_status, context); -} - -syncer::SyncError SharedChangeProcessorRef::CreateAndUploadError( - const tracked_objects::Location& from_here, - const std::string& message) { - return change_processor_->CreateAndUploadError(from_here, message); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/shared_change_processor_ref.h b/components/sync_driver/shared_change_processor_ref.h deleted file mode 100644 index 638c4b7..0000000 --- a/components/sync_driver/shared_change_processor_ref.h +++ /dev/null
@@ -1,51 +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 COMPONENTS_SYNC_DRIVER_SHARED_CHANGE_PROCESSOR_REF_H_ -#define COMPONENTS_SYNC_DRIVER_SHARED_CHANGE_PROCESSOR_REF_H_ - -#include <string> - -#include "base/compiler_specific.h" -#include "base/memory/ref_counted.h" -#include "components/sync/api/sync_change_processor.h" -#include "components/sync/api/sync_error_factory.h" -#include "components/sync_driver/shared_change_processor.h" - -namespace sync_driver { - -// A syncer::SyncChangeProcessor stub for interacting with a refcounted -// SharedChangeProcessor. -class SharedChangeProcessorRef : public syncer::SyncChangeProcessor, - public syncer::SyncErrorFactory { - public: - SharedChangeProcessorRef( - const scoped_refptr<SharedChangeProcessor>& - change_processor); - ~SharedChangeProcessorRef() override; - - // syncer::SyncChangeProcessor implementation. - syncer::SyncError ProcessSyncChanges( - const tracked_objects::Location& from_here, - const syncer::SyncChangeList& change_list) override; - syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override; - syncer::SyncError UpdateDataTypeContext( - syncer::ModelType type, - syncer::SyncChangeProcessor::ContextRefreshStatus refresh_status, - const std::string& context) override; - - // syncer::SyncErrorFactory implementation. - syncer::SyncError CreateAndUploadError( - const tracked_objects::Location& from_here, - const std::string& message) override; - - // Default copy and assign welcome (and safe due to refcounted-ness). - - private: - scoped_refptr<SharedChangeProcessor> change_processor_; -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_SHARED_CHANGE_PROCESSOR_REF_H_
diff --git a/components/sync_driver/shared_change_processor_unittest.cc b/components/sync_driver/shared_change_processor_unittest.cc deleted file mode 100644 index 9e2bc20c..0000000 --- a/components/sync_driver/shared_change_processor_unittest.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 "components/sync_driver/shared_change_processor.h" - -#include <cstddef> -#include <string> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/compiler_specific.h" -#include "base/location.h" -#include "base/single_thread_task_runner.h" -#include "base/synchronization/waitable_event.h" -#include "base/threading/thread.h" -#include "components/sync/api/attachments/attachment_id.h" -#include "components/sync/api/attachments/attachment_store.h" -#include "components/sync/api/fake_syncable_service.h" -#include "components/sync/base/model_type.h" -#include "components/sync/core/attachments/attachment_service_impl.h" -#include "components/sync/core/test/data_type_error_handler_mock.h" -#include "components/sync/core/test/test_user_share.h" -#include "components/sync_driver/fake_sync_client.h" -#include "components/sync_driver/generic_change_processor.h" -#include "components/sync_driver/generic_change_processor_factory.h" -#include "components/sync_driver/local_device_info_provider.h" -#include "components/sync_driver/sync_api_component_factory.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sync_driver { - -namespace { - -using ::testing::NiceMock; -using ::testing::StrictMock; - -class TestSyncApiComponentFactory : public SyncApiComponentFactory { - public: - TestSyncApiComponentFactory() {} - ~TestSyncApiComponentFactory() override {} - - // SyncApiComponentFactory implementation. - void RegisterDataTypes( - sync_driver::SyncService* sync_service, - const RegisterDataTypesMethod& register_platform_types_method) override {} - sync_driver::DataTypeManager* CreateDataTypeManager( - const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& - debug_info_listener, - const sync_driver::DataTypeController::TypeMap* controllers, - const sync_driver::DataTypeEncryptionHandler* encryption_handler, - browser_sync::SyncBackendHost* backend, - sync_driver::DataTypeManagerObserver* observer) override { - return nullptr; - } - browser_sync::SyncBackendHost* CreateSyncBackendHost( - const std::string& name, - invalidation::InvalidationService* invalidator, - const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs, - const base::FilePath& sync_folder) override { - return nullptr; - } - std::unique_ptr<sync_driver::LocalDeviceInfoProvider> - CreateLocalDeviceInfoProvider() override { - return nullptr; - } - SyncApiComponentFactory::SyncComponents CreateBookmarkSyncComponents( - sync_driver::SyncService* sync_service, - syncer::DataTypeErrorHandler* error_handler) override { - return SyncApiComponentFactory::SyncComponents(nullptr, nullptr); - } - std::unique_ptr<syncer::AttachmentService> CreateAttachmentService( - std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store, - const syncer::UserShare& user_share, - const std::string& store_birthday, - syncer::ModelType model_type, - syncer::AttachmentService::Delegate* delegate) override { - return syncer::AttachmentServiceImpl::CreateForTest(); - } -}; - -class SyncSharedChangeProcessorTest : - public testing::Test, - public FakeSyncClient { - public: - SyncSharedChangeProcessorTest() - : FakeSyncClient(&factory_), - backend_thread_("dbthread"), - did_connect_(false), - has_attachment_service_(false) {} - - ~SyncSharedChangeProcessorTest() override { - EXPECT_FALSE(db_syncable_service_.get()); - } - - // FakeSyncClient override. - base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType( - syncer::ModelType type) override { - return db_syncable_service_->AsWeakPtr(); - } - - protected: - void SetUp() override { - test_user_share_.SetUp(); - shared_change_processor_ = new SharedChangeProcessor(); - ASSERT_TRUE(backend_thread_.Start()); - ASSERT_TRUE(backend_thread_.task_runner()->PostTask( - FROM_HERE, - base::Bind(&SyncSharedChangeProcessorTest::SetUpDBSyncableService, - base::Unretained(this)))); - } - - void TearDown() override { - EXPECT_TRUE(backend_thread_.task_runner()->PostTask( - FROM_HERE, - base::Bind(&SyncSharedChangeProcessorTest::TearDownDBSyncableService, - base::Unretained(this)))); - // This must happen before the DB thread is stopped since - // |shared_change_processor_| may post tasks to delete its members - // on the correct thread. - // - // TODO(akalin): Write deterministic tests for the destruction of - // |shared_change_processor_| on the UI and DB threads. - shared_change_processor_ = NULL; - backend_thread_.Stop(); - - // Note: Stop() joins the threads, and that barrier prevents this read - // from being moved (e.g by compiler optimization) in such a way that it - // would race with the write in ConnectOnDBThread (because by this time, - // everything that could have run on |backend_thread_| has done so). - ASSERT_TRUE(did_connect_); - test_user_share_.TearDown(); - } - - // Connect |shared_change_processor_| on the DB thread. - void Connect() { - EXPECT_TRUE(backend_thread_.task_runner()->PostTask( - FROM_HERE, - base::Bind(&SyncSharedChangeProcessorTest::ConnectOnDBThread, - base::Unretained(this), shared_change_processor_))); - } - - void SetAttachmentStore() { - EXPECT_TRUE(backend_thread_.task_runner()->PostTask( - FROM_HERE, - base::Bind(&SyncSharedChangeProcessorTest::SetAttachmentStoreOnDBThread, - base::Unretained(this)))); - } - - bool HasAttachmentService() { - base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED); - EXPECT_TRUE(backend_thread_.task_runner()->PostTask( - FROM_HERE, - base::Bind( - &SyncSharedChangeProcessorTest::CheckAttachmentServiceOnDBThread, - base::Unretained(this), base::Unretained(&event)))); - event.Wait(); - return has_attachment_service_; - } - - private: - // Used by SetUp(). - void SetUpDBSyncableService() { - DCHECK(backend_thread_.task_runner()->BelongsToCurrentThread()); - DCHECK(!db_syncable_service_.get()); - db_syncable_service_.reset(new syncer::FakeSyncableService()); - } - - // Used by TearDown(). - void TearDownDBSyncableService() { - DCHECK(backend_thread_.task_runner()->BelongsToCurrentThread()); - DCHECK(db_syncable_service_.get()); - db_syncable_service_.reset(); - } - - void SetAttachmentStoreOnDBThread() { - DCHECK(backend_thread_.task_runner()->BelongsToCurrentThread()); - DCHECK(db_syncable_service_.get()); - db_syncable_service_->set_attachment_store( - syncer::AttachmentStore::CreateInMemoryStore()); - } - - // Used by Connect(). The SharedChangeProcessor is passed in - // because we modify |shared_change_processor_| on the main thread - // (in TearDown()). - void ConnectOnDBThread( - const scoped_refptr<SharedChangeProcessor>& shared_change_processor) { - DCHECK(backend_thread_.task_runner()->BelongsToCurrentThread()); - EXPECT_TRUE(shared_change_processor->Connect( - this, &processor_factory_, test_user_share_.user_share(), - &error_handler_, syncer::AUTOFILL, - base::WeakPtr<syncer::SyncMergeResult>())); - did_connect_ = true; - } - - void CheckAttachmentServiceOnDBThread(base::WaitableEvent* event) { - DCHECK(backend_thread_.task_runner()->BelongsToCurrentThread()); - DCHECK(db_syncable_service_.get()); - has_attachment_service_ = !!db_syncable_service_->attachment_service(); - event->Signal(); - } - - base::MessageLoop frontend_loop_; - base::Thread backend_thread_; - syncer::TestUserShare test_user_share_; - TestSyncApiComponentFactory factory_; - - scoped_refptr<SharedChangeProcessor> shared_change_processor_; - StrictMock<syncer::DataTypeErrorHandlerMock> error_handler_; - - GenericChangeProcessorFactory processor_factory_; - bool did_connect_; - bool has_attachment_service_; - - // Used only on DB thread. - std::unique_ptr<syncer::FakeSyncableService> db_syncable_service_; -}; - -// Simply connect the shared change processor. It should succeed, and -// nothing further should happen. -TEST_F(SyncSharedChangeProcessorTest, Basic) { - Connect(); -} - -// Connect the shared change processor to a syncable service with -// AttachmentStore. Verify that shared change processor implementation -// creates AttachmentService and passes it back to the syncable service. -TEST_F(SyncSharedChangeProcessorTest, ConnectWithAttachmentStore) { - SetAttachmentStore(); - Connect(); - EXPECT_TRUE(HasAttachmentService()); -} - -} // namespace - -} // namespace sync_driver
diff --git a/components/sync_driver/signin_manager_wrapper.cc b/components/sync_driver/signin_manager_wrapper.cc deleted file mode 100644 index 4468027..0000000 --- a/components/sync_driver/signin_manager_wrapper.cc +++ /dev/null
@@ -1,29 +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. - -#include "components/sync_driver/signin_manager_wrapper.h" - -#include "components/signin/core/browser/signin_manager_base.h" -#include "google_apis/gaia/gaia_constants.h" - -SigninManagerWrapper::SigninManagerWrapper(SigninManagerBase* original) - : original_(original) {} - -SigninManagerWrapper::~SigninManagerWrapper() {} - -SigninManagerBase* SigninManagerWrapper::GetOriginal() { - return original_; -} - -std::string SigninManagerWrapper::GetEffectiveUsername() const { - return original_->GetAuthenticatedAccountInfo().email; -} - -std::string SigninManagerWrapper::GetAccountIdToUse() const { - return original_->GetAuthenticatedAccountId(); -} - -std::string SigninManagerWrapper::GetSyncScopeToUse() const { - return GaiaConstants::kChromeSyncOAuth2Scope; -}
diff --git a/components/sync_driver/startup_controller.cc b/components/sync_driver/startup_controller.cc deleted file mode 100644 index 26b4ef7..0000000 --- a/components/sync_driver/startup_controller.cc +++ /dev/null
@@ -1,209 +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 "components/sync_driver/startup_controller.h" - -#include <string> - -#include "base/command_line.h" -#include "base/location.h" -#include "base/metrics/histogram.h" -#include "base/single_thread_task_runner.h" -#include "base/strings/string_number_conversions.h" -#include "base/threading/thread_task_runner_handle.h" -#include "components/sync_driver/sync_driver_switches.h" -#include "components/sync_driver/sync_prefs.h" - -namespace browser_sync { - -namespace { - -// The amount of time we'll wait to initialize sync if no data type triggers -// initialization via a StartSyncFlare. -const int kDeferredInitFallbackSeconds = 10; - -// Enum (for UMA, primarily) defining different events that cause us to -// exit the "deferred" state of initialization and invoke start_backend. -enum DeferredInitTrigger { - // We have received a signal from a SyncableService requesting that sync - // starts as soon as possible. - TRIGGER_DATA_TYPE_REQUEST, - // No data type requested sync to start and our fallback timer expired. - TRIGGER_FALLBACK_TIMER, - MAX_TRIGGER_VALUE -}; - -} // namespace - -StartupController::StartupController(const sync_driver::SyncPrefs* sync_prefs, - base::Callback<bool()> can_start, - base::Closure start_backend) - : bypass_setup_complete_(false), - received_start_request_(false), - setup_in_progress_(false), - sync_prefs_(sync_prefs), - can_start_(can_start), - start_backend_(start_backend), - fallback_timeout_( - base::TimeDelta::FromSeconds(kDeferredInitFallbackSeconds)), - weak_factory_(this) { - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kSyncDeferredStartupTimeoutSeconds)) { - int timeout = kDeferredInitFallbackSeconds; - if (base::StringToInt( - base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - switches::kSyncDeferredStartupTimeoutSeconds), - &timeout)) { - DCHECK_GE(timeout, 0); - DVLOG(2) << "Sync StartupController overriding startup timeout to " - << timeout << " seconds."; - fallback_timeout_ = base::TimeDelta::FromSeconds(timeout); - } - } -} - -StartupController::~StartupController() {} - -void StartupController::Reset(const syncer::ModelTypeSet registered_types) { - received_start_request_ = false; - bypass_setup_complete_ = false; - start_up_time_ = base::Time(); - start_backend_time_ = base::Time(); - // Don't let previous timers affect us post-reset. - weak_factory_.InvalidateWeakPtrs(); - registered_types_ = registered_types; -} - -void StartupController::SetSetupInProgress(bool setup_in_progress) { - setup_in_progress_ = setup_in_progress; - if (setup_in_progress_) { - TryStart(); - } -} - -bool StartupController::StartUp(StartUpDeferredOption deferred_option) { - const bool first_start = start_up_time_.is_null(); - if (first_start) - start_up_time_ = base::Time::Now(); - - if (deferred_option == STARTUP_BACKEND_DEFERRED && - !base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kSyncDisableDeferredStartup) && - sync_prefs_->GetPreferredDataTypes(registered_types_) - .Has(syncer::SESSIONS)) { - if (first_start) { - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - base::Bind(&StartupController::OnFallbackStartupTimerExpired, - weak_factory_.GetWeakPtr()), - fallback_timeout_); - } - return false; - } - - if (start_backend_time_.is_null()) { - start_backend_time_ = base::Time::Now(); - start_backend_.Run(); - } - - return true; -} - -void StartupController::OverrideFallbackTimeoutForTest( - const base::TimeDelta& timeout) { - fallback_timeout_ = timeout; -} - -bool StartupController::TryStart() { - if (!can_start_.Run()) - return false; - - // For performance reasons, defer the heavy lifting for sync init unless: - // - // - a datatype has requested an immediate start of sync, or - // - sync needs to start up the backend immediately to provide control state - // and encryption information to the UI. - // Do not start up the sync backend if setup has not completed and isn't - // in progress, unless told to otherwise. - if (setup_in_progress_) { - return StartUp(STARTUP_IMMEDIATE); - } else if (sync_prefs_->IsFirstSetupComplete() || bypass_setup_complete_) { - return StartUp(received_start_request_ ? STARTUP_IMMEDIATE - : STARTUP_BACKEND_DEFERRED); - } else { - return false; - } -} - -bool StartupController::TryStartImmediately() { - received_start_request_ = true; - bypass_setup_complete_ = true; - return TryStart(); -} - -void StartupController::RecordTimeDeferred() { - DCHECK(!start_up_time_.is_null()); - base::TimeDelta time_deferred = base::Time::Now() - start_up_time_; - UMA_HISTOGRAM_CUSTOM_TIMES("Sync.Startup.TimeDeferred2", - time_deferred, - base::TimeDelta::FromSeconds(0), - base::TimeDelta::FromMinutes(2), - 60); -} - -void StartupController::OnFallbackStartupTimerExpired() { - DCHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kSyncDisableDeferredStartup)); - - if (!start_backend_time_.is_null()) - return; - - DVLOG(2) << "Sync deferred init fallback timer expired, starting backend."; - RecordTimeDeferred(); - UMA_HISTOGRAM_ENUMERATION("Sync.Startup.DeferredInitTrigger", - TRIGGER_FALLBACK_TIMER, - MAX_TRIGGER_VALUE); - received_start_request_ = true; - TryStart(); -} - -std::string StartupController::GetBackendInitializationStateString() const { - if (!start_backend_time_.is_null()) - return "Started"; - else if (!start_up_time_.is_null()) - return "Deferred"; - else - return "Not started"; -} - -void StartupController::OnDataTypeRequestsSyncStartup(syncer::ModelType type) { - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kSyncDisableDeferredStartup)) { - DVLOG(2) << "Ignoring data type request for sync startup: " - << syncer::ModelTypeToString(type); - return; - } - - if (!start_backend_time_.is_null()) - return; - - DVLOG(2) << "Data type requesting sync startup: " - << syncer::ModelTypeToString(type); - // Measure the time spent waiting for init and the type that triggered it. - // We could measure the time spent deferred on a per-datatype basis, but - // for now this is probably sufficient. - if (!start_up_time_.is_null()) { - RecordTimeDeferred(); - UMA_HISTOGRAM_ENUMERATION("Sync.Startup.TypeTriggeringInit", - ModelTypeToHistogramInt(type), - syncer::MODEL_TYPE_COUNT); - UMA_HISTOGRAM_ENUMERATION("Sync.Startup.DeferredInitTrigger", - TRIGGER_DATA_TYPE_REQUEST, - MAX_TRIGGER_VALUE); - } - received_start_request_ = true; - TryStart(); -} - -} // namespace browser_sync
diff --git a/components/sync_driver/startup_controller.h b/components/sync_driver/startup_controller.h deleted file mode 100644 index 4f63b0b..0000000 --- a/components/sync_driver/startup_controller.h +++ /dev/null
@@ -1,117 +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 COMPONENTS_SYNC_DRIVER_STARTUP_CONTROLLER_H_ -#define COMPONENTS_SYNC_DRIVER_STARTUP_CONTROLLER_H_ - -#include "base/callback.h" -#include "base/memory/weak_ptr.h" -#include "base/time/time.h" -#include "components/sync/base/model_type.h" - -namespace sync_driver { -class SyncPrefs; -} - -namespace browser_sync { - -// This class is used by ProfileSyncService to manage all logic and state -// pertaining to initialization of the SyncBackendHost (colloquially referred -// to as "the backend"). -class StartupController { - public: - StartupController(const sync_driver::SyncPrefs* sync_prefs, - base::Callback<bool()> can_start, - base::Closure start_backend); - ~StartupController(); - - // Starts up sync if it is requested by the user and preconditions are met. - // Returns true if these preconditions are met, although does not imply - // the backend was started. - bool TryStart(); - - // Same as TryStart() above, but bypasses deferred startup and the first setup - // complete check. - bool TryStartImmediately(); - - // Called when a datatype (SyncableService) has a need for sync to start - // ASAP, presumably because a local change event has occurred but we're - // still in deferred start mode, meaning the SyncableService hasn't been - // told to MergeDataAndStartSyncing yet. - // It is expected that |type| is a currently active datatype. - void OnDataTypeRequestsSyncStartup(syncer::ModelType type); - - // Prepares this object for a new attempt to start sync, forgetting - // whether or not preconditions were previously met. - // NOTE: This resets internal state managed by this class, but does not - // touch values that are explicitly set and reset by higher layers to - // tell this class whether a setup UI dialog is being shown to the user. - // See setup_in_progress_. - void Reset(const syncer::ModelTypeSet registered_types); - - // Sets the setup in progress flag and tries to start sync if it's true. - void SetSetupInProgress(bool setup_in_progress); - - bool IsSetupInProgress() const { return setup_in_progress_; } - base::Time start_backend_time() const { return start_backend_time_; } - std::string GetBackendInitializationStateString() const; - - void OverrideFallbackTimeoutForTest(const base::TimeDelta& timeout); - - private: - enum StartUpDeferredOption { - STARTUP_BACKEND_DEFERRED, - STARTUP_IMMEDIATE - }; - // Returns true if all conditions to start the backend are met. - bool StartUp(StartUpDeferredOption deferred_option); - void OnFallbackStartupTimerExpired(); - - // Records time spent in deferred state with UMA histograms. - void RecordTimeDeferred(); - - // If true, will bypass the FirstSetupComplete check when triggering sync - // startup. - bool bypass_setup_complete_; - - // True if we should start sync ASAP because either a SyncableService has - // requested it, or we're done waiting for a sign and decided to go ahead. - bool received_start_request_; - - // The time that StartUp() is called. This is used to calculate time spent - // in the deferred state; that is, after StartUp and before invoking the - // start_backend_ callback. - base::Time start_up_time_; - - // If |true|, there is setup UI visible so we should not start downloading - // data types. - // Note: this is explicitly controlled by higher layers (UI) and is meant to - // reflect what the UI claims the setup state to be. Therefore, only set this - // due to explicit requests to do so via SetSetupInProgress. - bool setup_in_progress_; - - const sync_driver::SyncPrefs* sync_prefs_; - - // A function that can be invoked repeatedly to determine whether sync can be - // started. |start_backend_| should not be invoked unless this returns true. - base::Callback<bool()> can_start_; - - // The callback we invoke when it's time to call expensive - // startup routines for the sync backend. - base::Closure start_backend_; - - // The time at which we invoked the start_backend_ callback. - base::Time start_backend_time_; - - base::TimeDelta fallback_timeout_; - - // Used to compute preferred_types from SyncPrefs as-needed. - syncer::ModelTypeSet registered_types_; - - base::WeakPtrFactory<StartupController> weak_factory_; -}; - -} // namespace browser_sync - -#endif // COMPONENTS_SYNC_DRIVER_STARTUP_CONTROLLER_H_
diff --git a/components/sync_driver/startup_controller_unittest.cc b/components/sync_driver/startup_controller_unittest.cc deleted file mode 100644 index cb6ac3e..0000000 --- a/components/sync_driver/startup_controller_unittest.cc +++ /dev/null
@@ -1,213 +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 "components/sync_driver/startup_controller.h" - -#include <string> - -#include "base/command_line.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/time/time.h" -#include "components/sync_driver/sync_driver_switches.h" -#include "components/sync_driver/sync_prefs.h" -#include "components/syncable_prefs/testing_pref_service_syncable.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace browser_sync { - -// These are coupled to the implementation of StartupController's -// GetBackendInitializationStateString which is used by about:sync. We use it -// as a convenient way to verify internal state and that the class is -// outputting the correct values for the debug string. -static const char kStateStringStarted[] = "Started"; -static const char kStateStringDeferred[] = "Deferred"; -static const char kStateStringNotStarted[] = "Not started"; - -class StartupControllerTest : public testing::Test { - public: - StartupControllerTest() : can_start_(false), started_(false) {} - - void SetUp() override { - sync_driver::SyncPrefs::RegisterProfilePrefs(pref_service_.registry()); - sync_prefs_.reset(new sync_driver::SyncPrefs(&pref_service_)); - controller_.reset(new StartupController( - sync_prefs_.get(), - base::Bind(&StartupControllerTest::CanStart, base::Unretained(this)), - base::Bind(&StartupControllerTest::FakeStartBackend, - base::Unretained(this)))); - controller_->Reset(syncer::UserTypes()); - controller_->OverrideFallbackTimeoutForTest( - base::TimeDelta::FromSeconds(0)); - } - - bool CanStart() { return can_start_; } - - void SetCanStart(bool can_start) { can_start_ = can_start; } - - void FakeStartBackend() { - started_ = true; - sync_prefs()->SetFirstSetupComplete(); - } - - void ExpectStarted() { - EXPECT_TRUE(started()); - EXPECT_EQ(kStateStringStarted, - controller()->GetBackendInitializationStateString()); - } - - void ExpectStartDeferred() { - const bool deferred_start = - !base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kSyncDisableDeferredStartup); - EXPECT_EQ(!deferred_start, started()); - EXPECT_EQ(deferred_start ? kStateStringDeferred : kStateStringStarted, - controller()->GetBackendInitializationStateString()); - } - - void ExpectNotStarted() { - EXPECT_FALSE(started()); - EXPECT_EQ(kStateStringNotStarted, - controller()->GetBackendInitializationStateString()); - } - - bool started() const { return started_; } - void clear_started() { started_ = false; } - StartupController* controller() { return controller_.get(); } - sync_driver::SyncPrefs* sync_prefs() { return sync_prefs_.get(); } - - private: - bool can_start_; - bool started_; - base::MessageLoop message_loop_; - syncable_prefs::TestingPrefServiceSyncable pref_service_; - std::unique_ptr<sync_driver::SyncPrefs> sync_prefs_; - std::unique_ptr<StartupController> controller_; -}; - -// Test that sync doesn't start if setup is not in progress or complete. -TEST_F(StartupControllerTest, NoSetupComplete) { - controller()->TryStart(); - ExpectNotStarted(); - - SetCanStart(true); - controller()->TryStart(); - ExpectNotStarted(); -} - -// Test that sync defers if first setup is complete. -TEST_F(StartupControllerTest, DefersAfterFirstSetupComplete) { - sync_prefs()->SetFirstSetupComplete(); - SetCanStart(true); - controller()->TryStart(); - ExpectStartDeferred(); -} - -// Test that a data type triggering startup starts sync immediately. -TEST_F(StartupControllerTest, NoDeferralDataTypeTrigger) { - sync_prefs()->SetFirstSetupComplete(); - SetCanStart(true); - controller()->OnDataTypeRequestsSyncStartup(syncer::SESSIONS); - ExpectStarted(); -} - -// Test that a data type trigger interrupts the deferral timer and starts -// sync immediately. -TEST_F(StartupControllerTest, DataTypeTriggerInterruptsDeferral) { - sync_prefs()->SetFirstSetupComplete(); - SetCanStart(true); - controller()->TryStart(); - ExpectStartDeferred(); - - controller()->OnDataTypeRequestsSyncStartup(syncer::SESSIONS); - ExpectStarted(); - - // The fallback timer shouldn't result in another invocation of the closure - // we passed to the StartupController. - clear_started(); - base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(started()); -} - -// Test that the fallback timer starts sync in the event all -// conditions are met and no data type requests sync. -TEST_F(StartupControllerTest, FallbackTimer) { - sync_prefs()->SetFirstSetupComplete(); - SetCanStart(true); - controller()->TryStart(); - ExpectStartDeferred(); - - base::RunLoop().RunUntilIdle(); - ExpectStarted(); -} - -// Test that we start immediately if sessions is disabled. -TEST_F(StartupControllerTest, NoDeferralWithoutSessionsSync) { - syncer::ModelTypeSet types(syncer::UserTypes()); - // Disabling sessions means disabling 4 types due to groupings. - types.Remove(syncer::SESSIONS); - types.Remove(syncer::PROXY_TABS); - types.Remove(syncer::TYPED_URLS); - types.Remove(syncer::SUPERVISED_USER_SETTINGS); - sync_prefs()->SetKeepEverythingSynced(false); - sync_prefs()->SetPreferredDataTypes(syncer::UserTypes(), types); - controller()->Reset(syncer::UserTypes()); - - sync_prefs()->SetFirstSetupComplete(); - SetCanStart(true); - controller()->TryStart(); - ExpectStarted(); -} - -// Sanity check that the fallback timer doesn't fire before startup -// conditions are met. -TEST_F(StartupControllerTest, FallbackTimerWaits) { - controller()->TryStart(); - ExpectNotStarted(); - base::RunLoop().RunUntilIdle(); - ExpectNotStarted(); -} - -// Test that sync starts immediately when setup in progress is true. -TEST_F(StartupControllerTest, NoDeferralSetupInProgressTrigger) { - sync_prefs()->SetFirstSetupComplete(); - SetCanStart(true); - controller()->SetSetupInProgress(true); - ExpectStarted(); -} - -// Test that setup in progress being set to true interrupts the deferral timer -// and starts sync immediately. -TEST_F(StartupControllerTest, SetupInProgressTriggerInterruptsDeferral) { - sync_prefs()->SetFirstSetupComplete(); - SetCanStart(true); - controller()->TryStart(); - ExpectStartDeferred(); - - controller()->SetSetupInProgress(true); - ExpectStarted(); -} - -// Test that immediate startup can be forced. -TEST_F(StartupControllerTest, ForceImmediateStartup) { - SetCanStart(true); - controller()->TryStartImmediately(); - ExpectStarted(); -} - -// Test that setup-in-progress tracking is persistent across a Reset. -TEST_F(StartupControllerTest, ResetDuringSetup) { - SetCanStart(true); - - // Simulate UI telling us setup is in progress. - controller()->SetSetupInProgress(true); - - // This could happen if the UI triggers a stop-syncing permanently call. - controller()->Reset(syncer::UserTypes()); - - // From the UI's point of view, setup is still in progress. - EXPECT_TRUE(controller()->IsSetupInProgress()); -} - -} // namespace browser_sync
diff --git a/components/sync_driver/sync_api_component_factory.h b/components/sync_driver/sync_api_component_factory.h deleted file mode 100644 index efcb35f4..0000000 --- a/components/sync_driver/sync_api_component_factory.h +++ /dev/null
@@ -1,143 +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 COMPONENTS_SYNC_DRIVER_SYNC_API_COMPONENT_FACTORY_H_ -#define COMPONENTS_SYNC_DRIVER_SYNC_API_COMPONENT_FACTORY_H_ - -#include <memory> -#include <string> - -#include "base/memory/weak_ptr.h" -#include "components/sync/api/syncable_service.h" -#include "components/sync/base/model_type.h" -#include "components/sync/core/attachments/attachment_service.h" -#include "components/sync_driver/data_type_controller.h" - -namespace base { -class FilePath; -} // namespace base - -namespace browser_sync { -class SyncBackendHost; -} // namespace browser_sync - -namespace history { -class HistoryBackend; -} - -namespace invalidation { -class InvalidationService; -} // namespace invalidation - -namespace syncer { -class DataTypeDebugInfoListener; -class DataTypeErrorHandler; -class SyncableService; - -struct UserShare; -} // namespace syncer - -namespace sync_driver { - -class AssociatorInterface; -class ChangeProcessor; -class DataTypeEncryptionHandler; -class DataTypeManager; -class DataTypeManagerObserver; -class DataTypeStatusTable; -class GenericChangeProcessor; -class LocalDeviceInfoProvider; -class SyncPrefs; -class SyncClient; -class SyncService; - -// This factory provides sync driver code with the model type specific sync/api -// service (like SyncableService) implementations. -class SyncApiComponentFactory { - public: - virtual ~SyncApiComponentFactory() {} - // Callback to allow platform-specific datatypes to register themselves as - // data type controllers. - // |disabled_types| and |enabled_types| control the disable/enable state of - // types that are on or off by default (respectively). - typedef base::Callback<void(sync_driver::SyncService* sync_service, - syncer::ModelTypeSet disabled_types, - syncer::ModelTypeSet enabled_types)> - RegisterDataTypesMethod; - - // The various factory methods for the data type model associators - // and change processors all return this struct. This is needed - // because the change processors typically require a type-specific - // model associator at construction time. - // - // Note: This interface is deprecated in favor of the SyncableService API. - // New datatypes that do not live on the UI thread should directly return a - // weak pointer to a syncer::SyncableService. All others continue to return - // SyncComponents. It is safe to assume that the factory methods below are - // called on the same thread in which the datatype resides. - // - // TODO(zea): Have all datatypes using the new API switch to returning - // SyncableService weak pointers instead of SyncComponents (crbug.com/100114). - struct SyncComponents { - sync_driver::AssociatorInterface* model_associator; - sync_driver::ChangeProcessor* change_processor; - SyncComponents(sync_driver::AssociatorInterface* ma, - sync_driver::ChangeProcessor* cp) - : model_associator(ma), change_processor(cp) {} - }; - - // Creates and registers enabled datatypes with the provided SyncClient. - virtual void RegisterDataTypes( - sync_driver::SyncService* sync_service, - const RegisterDataTypesMethod& register_platform_types_method) = 0; - - // Instantiates a new DataTypeManager with a SyncBackendHost, a list of data - // type controllers and a DataTypeManagerObserver. The return pointer is - // owned by the caller. - virtual sync_driver::DataTypeManager* CreateDataTypeManager( - const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& - debug_info_listener, - const sync_driver::DataTypeController::TypeMap* controllers, - const sync_driver::DataTypeEncryptionHandler* encryption_handler, - browser_sync::SyncBackendHost* backend, - sync_driver::DataTypeManagerObserver* observer) = 0; - - // Creating this in the factory helps us mock it out in testing. - virtual browser_sync::SyncBackendHost* CreateSyncBackendHost( - const std::string& name, - invalidation::InvalidationService* invalidator, - const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs, - const base::FilePath& sync_folder) = 0; - - // Creating this in the factory helps us mock it out in testing. - virtual std::unique_ptr<sync_driver::LocalDeviceInfoProvider> - CreateLocalDeviceInfoProvider() = 0; - - // Legacy datatypes that need to be converted to the SyncableService API. - virtual SyncComponents CreateBookmarkSyncComponents( - sync_driver::SyncService* sync_service, - syncer::DataTypeErrorHandler* error_handler) = 0; - - // Creates attachment service. - // Note: Should only be called from the model type thread. - // - // |store_birthday| is the store birthday. Must not be empty. - // - // |model_type| is the model type this AttachmentService will be used with. - // - // |delegate| is optional delegate for AttachmentService to notify about - // asynchronous events (AttachmentUploaded). Pass NULL if delegate is not - // provided. AttachmentService doesn't take ownership of delegate, the pointer - // must be valid throughout AttachmentService lifetime. - virtual std::unique_ptr<syncer::AttachmentService> CreateAttachmentService( - std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store, - const syncer::UserShare& user_share, - const std::string& store_birthday, - syncer::ModelType model_type, - syncer::AttachmentService::Delegate* delegate) = 0; -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_SYNC_API_COMPONENT_FACTORY_H_
diff --git a/components/sync_driver/sync_api_component_factory_mock.cc b/components/sync_driver/sync_api_component_factory_mock.cc deleted file mode 100644 index 8950986..0000000 --- a/components/sync_driver/sync_api_component_factory_mock.cc +++ /dev/null
@@ -1,63 +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 "components/sync_driver/sync_api_component_factory_mock.h" - -#include <utility> - -#include "components/sync/api/attachments/attachment_store.h" -#include "components/sync/core/attachments/attachment_service_impl.h" -#include "components/sync_driver/change_processor.h" -#include "components/sync_driver/local_device_info_provider_mock.h" -#include "components/sync_driver/model_associator.h" - -using sync_driver::AssociatorInterface; -using sync_driver::ChangeProcessor; -using testing::_; -using testing::InvokeWithoutArgs; -using testing::Return; - -SyncApiComponentFactoryMock::SyncApiComponentFactoryMock() - : local_device_(new sync_driver::LocalDeviceInfoProviderMock()) { -} - -SyncApiComponentFactoryMock::SyncApiComponentFactoryMock( - AssociatorInterface* model_associator, ChangeProcessor* change_processor) - : model_associator_(model_associator), - change_processor_(change_processor), - local_device_(new sync_driver::LocalDeviceInfoProviderMock()) { - ON_CALL(*this, CreateBookmarkSyncComponents(_, _)). - WillByDefault( - InvokeWithoutArgs( - this, - &SyncApiComponentFactoryMock::MakeSyncComponents)); -} - -SyncApiComponentFactoryMock::~SyncApiComponentFactoryMock() {} - -std::unique_ptr<syncer::AttachmentService> -SyncApiComponentFactoryMock::CreateAttachmentService( - std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store, - const syncer::UserShare& user_share, - const std::string& store_birthday, - syncer::ModelType model_type, - syncer::AttachmentService::Delegate* delegate) { - return syncer::AttachmentServiceImpl::CreateForTest(); -} - -sync_driver::SyncApiComponentFactory::SyncComponents -SyncApiComponentFactoryMock::MakeSyncComponents() { - return sync_driver::SyncApiComponentFactory::SyncComponents( - model_associator_.release(), change_processor_.release()); -} - -std::unique_ptr<sync_driver::LocalDeviceInfoProvider> -SyncApiComponentFactoryMock::CreateLocalDeviceInfoProvider() { - return std::move(local_device_); -} - -void SyncApiComponentFactoryMock::SetLocalDeviceInfoProvider( - std::unique_ptr<sync_driver::LocalDeviceInfoProvider> local_device) { - local_device_ = std::move(local_device); -}
diff --git a/components/sync_driver/sync_api_component_factory_mock.h b/components/sync_driver/sync_api_component_factory_mock.h deleted file mode 100644 index 14ce5ae..0000000 --- a/components/sync_driver/sync_api_component_factory_mock.h +++ /dev/null
@@ -1,79 +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 COMPONENTS_SYNC_DRIVER_SYNC_API_COMPONENT_FACTORY_MOCK_H__ -#define COMPONENTS_SYNC_DRIVER_SYNC_API_COMPONENT_FACTORY_MOCK_H__ - -#include <memory> - -#include "components/sync/base/model_type.h" -#include "components/sync/core/data_type_error_handler.h" -#include "components/sync_driver/data_type_controller.h" -#include "components/sync_driver/sync_api_component_factory.h" -#include "testing/gmock/include/gmock/gmock.h" - -namespace sync_driver { -class AssociatorInterface; -class ChangeProcessor; -class DataTypeEncryptionHandler; -class DataTypeStatusTable; -class SyncClient; -} - -class SyncApiComponentFactoryMock - : public sync_driver::SyncApiComponentFactory { - public: - SyncApiComponentFactoryMock(); - SyncApiComponentFactoryMock( - sync_driver::AssociatorInterface* model_associator, - sync_driver::ChangeProcessor* change_processor); - ~SyncApiComponentFactoryMock() override; - - MOCK_METHOD2(RegisterDataTypes, - void(sync_driver::SyncService* sync_service, - const RegisterDataTypesMethod&)); - MOCK_METHOD5(CreateDataTypeManager, - sync_driver::DataTypeManager*( - const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>&, - const sync_driver::DataTypeController::TypeMap*, - const sync_driver::DataTypeEncryptionHandler*, - browser_sync::SyncBackendHost*, - sync_driver::DataTypeManagerObserver* observer)); - MOCK_METHOD4(CreateSyncBackendHost, - browser_sync::SyncBackendHost*( - const std::string& name, - invalidation::InvalidationService* invalidator, - const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs, - const base::FilePath& sync_folder)); - - std::unique_ptr<sync_driver::LocalDeviceInfoProvider> - CreateLocalDeviceInfoProvider() override; - void SetLocalDeviceInfoProvider( - std::unique_ptr<sync_driver::LocalDeviceInfoProvider> local_device); - - std::unique_ptr<syncer::AttachmentService> CreateAttachmentService( - std::unique_ptr<syncer::AttachmentStoreForSync> attachment_store, - const syncer::UserShare& user_share, - const std::string& store_birthday, - syncer::ModelType model_type, - syncer::AttachmentService::Delegate* delegate) override; - MOCK_METHOD2(CreateBookmarkSyncComponents, - SyncComponents(sync_driver::SyncService* sync_service, - syncer::DataTypeErrorHandler* error_handler)); - MOCK_METHOD3(CreateTypedUrlSyncComponents, - SyncComponents(sync_driver::SyncService* sync_service, - history::HistoryBackend* history_backend, - syncer::DataTypeErrorHandler* error_handler)); - - private: - sync_driver::SyncApiComponentFactory::SyncComponents MakeSyncComponents(); - - std::unique_ptr<sync_driver::AssociatorInterface> model_associator_; - std::unique_ptr<sync_driver::ChangeProcessor> change_processor_; - // LocalDeviceInfoProvider is initially owned by this class, - // transferred to caller when CreateLocalDeviceInfoProvider is called. - std::unique_ptr<sync_driver::LocalDeviceInfoProvider> local_device_; -}; - -#endif // COMPONENTS_SYNC_DRIVER_SYNC_API_COMPONENT_FACTORY_MOCK_H__
diff --git a/components/sync_driver/sync_client.cc b/components/sync_driver/sync_client.cc deleted file mode 100644 index d4122ad0..0000000 --- a/components/sync_driver/sync_client.cc +++ /dev/null
@@ -1,12 +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. - -#include "components/sync_driver/sync_client.h" - -namespace sync_driver { - -SyncClient::SyncClient() {} -SyncClient::~SyncClient() {} - -} // namespace sync_driver
diff --git a/components/sync_driver/sync_client.h b/components/sync_driver/sync_client.h deleted file mode 100644 index 74c7e7ae..0000000 --- a/components/sync_driver/sync_client.h +++ /dev/null
@@ -1,124 +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. - -#ifndef COMPONENTS_SYNC_DRIVER_SYNC_CLIENT_H_ -#define COMPONENTS_SYNC_DRIVER_SYNC_CLIENT_H_ - -#include "base/callback_forward.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "components/sync/base/extensions_activity.h" -#include "components/sync/base/model_type.h" -#include "components/sync/core/shared_model_type_processor.h" -#include "components/sync/engine/model_safe_worker.h" -#include "components/sync_driver/sync_api_component_factory.h" - -class BookmarkUndoService; -class PrefService; - -namespace autofill { -class AutocompleteSyncableService; -class PersonalDataManager; -} // namespace autofill - -namespace bookmarks { -class BookmarkModel; -} // namespace bookmarks - -namespace favicon { -class FaviconService; -} // namespace favicon - -namespace history { -class HistoryService; -} // namespace history - -namespace invalidation { -class InvalidationService; -} // namespace invalidation - -namespace syncer { -class SyncableService; -} // namespace syncer - -namespace sync_sessions { -class SyncSessionsClient; -} // namespace sync_sessions - -namespace sync_driver { - -class SyncService; - -// Interface for clients of the Sync API to plumb through necessary dependent -// components. This interface is purely for abstracting dependencies, and -// should not contain any non-trivial functional logic. -// -// Note: on some platforms, getters might return nullptr. Callers are expected -// to handle these scenarios gracefully. -class SyncClient { - public: - SyncClient(); - virtual ~SyncClient(); - - // Initializes the sync client with the specified sync service. - virtual void Initialize() = 0; - - // Returns the current SyncService instance. - virtual SyncService* GetSyncService() = 0; - - // Returns the current profile's preference service. - virtual PrefService* GetPrefService() = 0; - - // DataType specific service getters. - virtual bookmarks::BookmarkModel* GetBookmarkModel() = 0; - virtual favicon::FaviconService* GetFaviconService() = 0; - virtual history::HistoryService* GetHistoryService() = 0; - - // Returns a callback that will register the types specific to the current - // platform. - virtual sync_driver::SyncApiComponentFactory::RegisterDataTypesMethod - GetRegisterPlatformTypesCallback() = 0; - - // Returns a callback that will be invoked when password sync state has - // potentially been changed. - virtual base::Closure GetPasswordStateChangedCallback() = 0; - - virtual autofill::PersonalDataManager* GetPersonalDataManager() = 0; - virtual BookmarkUndoService* GetBookmarkUndoServiceIfExists() = 0; - virtual invalidation::InvalidationService* GetInvalidationService() = 0; - virtual scoped_refptr<syncer::ExtensionsActivity> GetExtensionsActivity() = 0; - virtual sync_sessions::SyncSessionsClient* GetSyncSessionsClient() = 0; - - // Returns a weak pointer to the syncable service specified by |type|. - // Weak pointer may be unset if service is already destroyed. - // Note: Should only be called from the model type thread. - virtual base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType( - syncer::ModelType type) = 0; - - // Returns a non-owning pointer to the service specified by |type|. Service - // lifetime is independent from sync thread therefore pointer should not be - // retained across tasks. - // Note: Should only be called from the model type thread. - // Note: should only be called by USS. - virtual syncer_v2::ModelTypeService* GetModelTypeServiceForType( - syncer::ModelType type) = 0; - - // Creates and returns a new ModelSafeWorker for the group, or null if one - // cannot be created. - // TODO(maxbogue): Move this inside SyncApiComponentFactory. - virtual scoped_refptr<syncer::ModelSafeWorker> CreateModelWorkerForGroup( - syncer::ModelSafeGroup group, - syncer::WorkerLoopDestructionObserver* observer) = 0; - - // Returns the current SyncApiComponentFactory instance. - virtual SyncApiComponentFactory* GetSyncApiComponentFactory() = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(SyncClient); -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_SYNC_CLIENT_H_
diff --git a/components/sync_driver/sync_driver_switches.cc b/components/sync_driver/sync_driver_switches.cc deleted file mode 100644 index ec030be..0000000 --- a/components/sync_driver/sync_driver_switches.cc +++ /dev/null
@@ -1,38 +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. - -#include "components/sync_driver/sync_driver_switches.h" - -namespace switches { - -// Allows overriding the deferred init fallback timeout. -const char kSyncDeferredStartupTimeoutSeconds[] = - "sync-deferred-startup-timeout-seconds"; - -// Enables deferring sync backend initialization until user initiated changes -// occur. -const char kSyncDisableDeferredStartup[] = "sync-disable-deferred-startup"; - -// Enables feature to avoid unnecessary GetUpdate requests. -const char kSyncEnableGetUpdateAvoidance[] = - "sync-enable-get-update-avoidance"; - -// Enables USS implementation of DeviceInfo datatype. This flag controls whether -// SyncableService based or ModelTypeService based implementation is used for -// DeviceInfo type. -const char kSyncEnableUSSDeviceInfo[] = "sync-enable-uss-device-info"; - -// Overrides the default server used for profile sync. -const char kSyncServiceURL[] = "sync-url"; - -// This flag causes sync to retry very quickly (see polling_constants.h) the -// when it encounters an error, as the first step towards exponential backoff. -const char kSyncShortInitialRetryOverride[] = - "sync-short-initial-retry-override"; - -// Enables clearing of sync data when a user enables passphrase encryption. -const base::Feature kSyncClearDataOnPassphraseEncryption{ - "ClearSyncDataOnPassphraseEncryption", base::FEATURE_DISABLED_BY_DEFAULT}; - -} // namespace switches
diff --git a/components/sync_driver/sync_error_controller.cc b/components/sync_driver/sync_error_controller.cc deleted file mode 100644 index 48c9ee42..0000000 --- a/components/sync_driver/sync_error_controller.cc +++ /dev/null
@@ -1,34 +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 "components/sync_driver/sync_error_controller.h" - -#include "components/sync_driver/sync_service.h" - -SyncErrorController::SyncErrorController(sync_driver::SyncService* service) - : service_(service) { - DCHECK(service_); -} - -SyncErrorController::~SyncErrorController() { -} - -bool SyncErrorController::HasError() { - return service_->IsFirstSetupComplete() && service_->IsPassphraseRequired() && - service_->IsPassphraseRequiredForDecryption(); -} - -void SyncErrorController::AddObserver(Observer* observer) { - observer_list_.AddObserver(observer); -} - -void SyncErrorController::RemoveObserver(Observer* observer) { - observer_list_.RemoveObserver(observer); -} - -void SyncErrorController::OnStateChanged() { - FOR_EACH_OBSERVER(Observer, - observer_list_, - OnErrorChanged()); -}
diff --git a/components/sync_driver/sync_error_controller.h b/components/sync_driver/sync_error_controller.h deleted file mode 100644 index ce623c6..0000000 --- a/components/sync_driver/sync_error_controller.h +++ /dev/null
@@ -1,47 +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 COMPONENTS_SYNC_DRIVER_SYNC_ERROR_CONTROLLER_H_ -#define COMPONENTS_SYNC_DRIVER_SYNC_ERROR_CONTROLLER_H_ - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/observer_list.h" -#include "components/sync_driver/sync_service_observer.h" - -namespace sync_driver { -class SyncService; -} - -// Keep track of sync errors and expose them to observers in the UI. -class SyncErrorController : public sync_driver::SyncServiceObserver { - public: - // The observer class for SyncErrorController lets the controller notify - // observers when an error arises or changes. - class Observer { - public: - virtual ~Observer() {} - virtual void OnErrorChanged() = 0; - }; - - explicit SyncErrorController(sync_driver::SyncService* service); - ~SyncErrorController() override; - - // True if there exists an error worth elevating to the user. - bool HasError(); - - void AddObserver(Observer* observer); - void RemoveObserver(Observer* observer); - - // sync_driver::SyncServiceObserver: - void OnStateChanged() override; - - private: - sync_driver::SyncService* service_; - base::ObserverList<Observer, true> observer_list_; - - DISALLOW_COPY_AND_ASSIGN(SyncErrorController); -}; - -#endif // COMPONENTS_SYNC_DRIVER_SYNC_ERROR_CONTROLLER_H_
diff --git a/components/sync_driver/sync_frontend.cc b/components/sync_driver/sync_frontend.cc deleted file mode 100644 index 7ea84e1..0000000 --- a/components/sync_driver/sync_frontend.cc +++ /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. - -#include "components/sync_driver/sync_frontend.h" - -namespace sync_driver { - -SyncFrontend::SyncFrontend() {} - -SyncFrontend::~SyncFrontend() {} - -} // namespace sync_driver
diff --git a/components/sync_driver/sync_frontend.h b/components/sync_driver/sync_frontend.h deleted file mode 100644 index c81a253d..0000000 --- a/components/sync_driver/sync_frontend.h +++ /dev/null
@@ -1,150 +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 COMPONENTS_SYNC_DRIVER_SYNC_FRONTEND_H_ -#define COMPONENTS_SYNC_DRIVER_SYNC_FRONTEND_H_ - -#include <string> - -#include "components/sync/base/model_type.h" -#include "components/sync/base/weak_handle.h" -#include "components/sync/core/sync_encryption_handler.h" -#include "components/sync/core/sync_manager.h" -#include "components/sync/protocol/sync_protocol_error.h" - -namespace syncer { -class DataTypeDebugInfoListener; -class JsBackend; -class ProtocolEvent; -struct CommitCounters; -struct StatusCounters; -struct UpdateCounters; -} // namespace syncer - -namespace sync_pb { -class EncryptedData; -} // namespace sync_pb - -namespace sync_driver { - -// SyncFrontend is the interface used by SyncBackendHost to communicate with -// the entity that created it and, presumably, is interested in sync-related -// activity. -// NOTE: All methods will be invoked by a SyncBackendHost on the same thread -// used to create that SyncBackendHost. -class SyncFrontend { - public: - SyncFrontend(); - virtual ~SyncFrontend(); - - // The backend has completed initialization and it is now ready to - // accept and process changes. If success is false, initialization - // wasn't able to be completed and should be retried. - // - // |js_backend| is what about:sync interacts with; it's different - // from the 'Backend' in 'OnBackendInitialized' (unfortunately). It - // is initialized only if |success| is true. - virtual void OnBackendInitialized( - const syncer::WeakHandle<syncer::JsBackend>& js_backend, - const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& - debug_info_listener, - const std::string& cache_guid, - bool success) = 0; - - // The backend queried the server recently and received some updates. - virtual void OnSyncCycleCompleted() = 0; - - // Informs the frontned of some network event. These notifications are - // disabled by default and must be enabled through an explicit request to the - // SyncBackendHost. - // - // It's disabld by default to avoid copying data across threads when no one - // is listening for it. - virtual void OnProtocolEvent(const syncer::ProtocolEvent& event) = 0; - - // Called when we receive an updated commit counter for a directory type. - // - // Disabled by default. Enable by calling - // EnableDirectoryTypeDebugInfoForwarding() on the backend. - virtual void OnDirectoryTypeCommitCounterUpdated( - syncer::ModelType type, - const syncer::CommitCounters& counters) = 0; - - // Called when we receive an updated update counter for a directory type. - // - // Disabled by default. Enable by calling - // EnableDirectoryTypeDebugInfoForwarding() on the backend. - virtual void OnDirectoryTypeUpdateCounterUpdated( - syncer::ModelType type, - const syncer::UpdateCounters& counters) = 0; - - // Called when we receive an updated status counter for a directory type. - // - // Disabled by default. Enable by calling - // EnableDirectoryTypeDebugInfoForwarding() on the backend. - virtual void OnDirectoryTypeStatusCounterUpdated( - syncer::ModelType type, - const syncer::StatusCounters& counters) = 0; - - // The status of the connection to the sync server has changed. - virtual void OnConnectionStatusChange( - syncer::ConnectionStatus status) = 0; - - // The syncer requires a passphrase to decrypt sensitive updates. This is - // called when the first sensitive data type is setup by the user and anytime - // the passphrase is changed by another synced client. |reason| denotes why - // the passphrase was required. |pending_keys| is a copy of the - // cryptographer's pending keys to be passed on to the frontend in order to - // be cached. - virtual void OnPassphraseRequired( - syncer::PassphraseRequiredReason reason, - const sync_pb::EncryptedData& pending_keys) = 0; - - // Called when the passphrase provided by the user is - // accepted. After this is called, updates to sensitive nodes are - // encrypted using the accepted passphrase. - virtual void OnPassphraseAccepted() = 0; - - // Called when the set of encrypted types or the encrypt everything - // flag has been changed. Note that encryption isn't complete until - // the OnEncryptionComplete() notification has been sent (see - // below). - // - // |encrypted_types| will always be a superset of - // syncer::Cryptographer::SensitiveTypes(). If |encrypt_everything| is - // true, |encrypted_types| will be the set of all known types. - // - // Until this function is called, observers can assume that the set - // of encrypted types is syncer::Cryptographer::SensitiveTypes() and that - // the encrypt everything flag is false. - virtual void OnEncryptedTypesChanged( - syncer::ModelTypeSet encrypted_types, - bool encrypt_everything) = 0; - - // Called after we finish encrypting the current set of encrypted - // types. - virtual void OnEncryptionComplete() = 0; - - // Called to perform migration of |types|. - virtual void OnMigrationNeededForTypes(syncer::ModelTypeSet types) = 0; - - // Inform the Frontend that new datatypes are available for registration. - virtual void OnExperimentsChanged( - const syncer::Experiments& experiments) = 0; - - // Called when the sync cycle returns there is an user actionable error. - virtual void OnActionableError(const syncer::SyncProtocolError& error) = 0; - - // Called when the user of this device enables passphrase encryption. - // - // |nigori_state| contains the new (post custom passphrase) encryption keys - // and can be used to restore SyncEncryptionHandler's state across sync - // backend instances. See also SyncEncryptionHandlerImpl::RestoreNigori. - virtual void OnLocalSetPassphraseEncryption( - const syncer::SyncEncryptionHandler::NigoriState& nigori_state) = 0; -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_SYNC_FRONTEND_H_
diff --git a/components/sync_driver/sync_policy_handler.cc b/components/sync_driver/sync_policy_handler.cc deleted file mode 100644 index e70b155..0000000 --- a/components/sync_driver/sync_policy_handler.cc +++ /dev/null
@@ -1,30 +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 "components/sync_driver/sync_policy_handler.h" - -#include "base/values.h" -#include "components/policy/core/common/policy_map.h" -#include "components/prefs/pref_value_map.h" -#include "components/sync_driver/pref_names.h" -#include "policy/policy_constants.h" - -namespace sync_driver { - -SyncPolicyHandler::SyncPolicyHandler() - : policy::TypeCheckingPolicyHandler(policy::key::kSyncDisabled, - base::Value::TYPE_BOOLEAN) {} - -SyncPolicyHandler::~SyncPolicyHandler() { -} - -void SyncPolicyHandler::ApplyPolicySettings(const policy::PolicyMap& policies, - PrefValueMap* prefs) { - const base::Value* value = policies.GetValue(policy_name()); - bool disable_sync; - if (value && value->GetAsBoolean(&disable_sync) && disable_sync) - prefs->SetValue(sync_driver::prefs::kSyncManaged, value->CreateDeepCopy()); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/sync_policy_handler_unittest.cc b/components/sync_driver/sync_policy_handler_unittest.cc deleted file mode 100644 index b3754cb..0000000 --- a/components/sync_driver/sync_policy_handler_unittest.cc +++ /dev/null
@@ -1,61 +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 "components/sync_driver/sync_policy_handler.h" - -#include "base/memory/ptr_util.h" -#include "base/values.h" -#include "components/policy/core/common/policy_map.h" -#include "components/policy/core/common/policy_types.h" -#include "components/prefs/pref_value_map.h" -#include "components/sync_driver/pref_names.h" -#include "policy/policy_constants.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sync_driver { - -// Test cases for the Sync policy setting. -class SyncPolicyHandlerTest : public testing::Test {}; - -TEST_F(SyncPolicyHandlerTest, Default) { - policy::PolicyMap policy; - SyncPolicyHandler handler; - PrefValueMap prefs; - handler.ApplyPolicySettings(policy, &prefs); - EXPECT_FALSE(prefs.GetValue(sync_driver::prefs::kSyncManaged, NULL)); -} - -TEST_F(SyncPolicyHandlerTest, Enabled) { - policy::PolicyMap policy; - policy.Set(policy::key::kSyncDisabled, policy::POLICY_LEVEL_MANDATORY, - policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD, - base::WrapUnique(new base::FundamentalValue(false)), nullptr); - SyncPolicyHandler handler; - PrefValueMap prefs; - handler.ApplyPolicySettings(policy, &prefs); - - // Enabling Sync should not set the pref. - EXPECT_FALSE(prefs.GetValue(sync_driver::prefs::kSyncManaged, NULL)); -} - -TEST_F(SyncPolicyHandlerTest, Disabled) { - policy::PolicyMap policy; - policy.Set(policy::key::kSyncDisabled, policy::POLICY_LEVEL_MANDATORY, - policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD, - base::WrapUnique(new base::FundamentalValue(true)), nullptr); - SyncPolicyHandler handler; - PrefValueMap prefs; - handler.ApplyPolicySettings(policy, &prefs); - - // Sync should be flagged as managed. - const base::Value* value = NULL; - EXPECT_TRUE(prefs.GetValue(sync_driver::prefs::kSyncManaged, &value)); - ASSERT_TRUE(value); - bool sync_managed = false; - bool result = value->GetAsBoolean(&sync_managed); - ASSERT_TRUE(result); - EXPECT_TRUE(sync_managed); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/sync_prefs.cc b/components/sync_driver/sync_prefs.cc deleted file mode 100644 index 9081633..0000000 --- a/components/sync_driver/sync_prefs.cc +++ /dev/null
@@ -1,556 +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 "components/sync_driver/sync_prefs.h" - -#include "base/base64.h" -#include "base/logging.h" -#include "base/strings/string_number_conversions.h" -#include "base/values.h" -#include "build/build_config.h" -#include "components/pref_registry/pref_registry_syncable.h" -#include "components/prefs/pref_member.h" -#include "components/prefs/pref_service.h" -#include "components/sync_driver/pref_names.h" - -namespace sync_driver { - -SyncPrefObserver::~SyncPrefObserver() {} - -SyncPrefs::SyncPrefs(PrefService* pref_service) : pref_service_(pref_service) { - DCHECK(pref_service); - RegisterPrefGroups(); - // Watch the preference that indicates sync is managed so we can take - // appropriate action. - pref_sync_managed_.Init( - prefs::kSyncManaged, - pref_service_, - base::Bind(&SyncPrefs::OnSyncManagedPrefChanged, base::Unretained(this))); -} - -SyncPrefs::SyncPrefs() : pref_service_(NULL) {} - -SyncPrefs::~SyncPrefs() { DCHECK(CalledOnValidThread()); } - -// static -void SyncPrefs::RegisterProfilePrefs( - user_prefs::PrefRegistrySyncable* registry) { - registry->RegisterBooleanPref(prefs::kSyncFirstSetupComplete, false); - registry->RegisterBooleanPref(prefs::kSyncSuppressStart, false); - registry->RegisterInt64Pref(prefs::kSyncLastSyncedTime, 0); - registry->RegisterInt64Pref(prefs::kSyncLastPollTime, 0); - registry->RegisterInt64Pref(prefs::kSyncFirstSyncTime, 0); - - // All datatypes are on by default, but this gets set explicitly - // when you configure sync (when turning it on), in - // ProfileSyncService::OnUserChoseDatatypes. - registry->RegisterBooleanPref(prefs::kSyncKeepEverythingSynced, true); - - syncer::ModelTypeSet user_types = syncer::UserTypes(); - - // Include proxy types as well, as they can be individually selected, - // although they don't have sync representations. - user_types.PutAll(syncer::ProxyTypes()); - - // Treat bookmarks and device info specially. - RegisterDataTypePreferredPref(registry, syncer::BOOKMARKS, true); - RegisterDataTypePreferredPref(registry, syncer::DEVICE_INFO, true); - user_types.Remove(syncer::BOOKMARKS); - user_types.Remove(syncer::DEVICE_INFO); - - // All types are set to off by default, which forces a configuration to - // explicitly enable them. GetPreferredTypes() will ensure that any new - // implicit types are enabled when their pref group is, or via - // KeepEverythingSynced. - for (syncer::ModelTypeSet::Iterator it = user_types.First(); it.Good(); - it.Inc()) { - RegisterDataTypePreferredPref(registry, it.Get(), false); - } - - registry->RegisterBooleanPref(prefs::kSyncManaged, false); - registry->RegisterStringPref(prefs::kSyncEncryptionBootstrapToken, - std::string()); - registry->RegisterStringPref(prefs::kSyncKeystoreEncryptionBootstrapToken, - std::string()); -#if defined(OS_CHROMEOS) - registry->RegisterStringPref(prefs::kSyncSpareBootstrapToken, ""); -#endif - - registry->RegisterBooleanPref(prefs::kSyncHasAuthError, false); - registry->RegisterStringPref(prefs::kSyncSessionsGUID, std::string()); - registry->RegisterBooleanPref(prefs::kSyncPassphrasePrompted, false); - registry->RegisterIntegerPref(prefs::kSyncMemoryPressureWarningCount, -1); - registry->RegisterBooleanPref(prefs::kSyncShutdownCleanly, false); - registry->RegisterDictionaryPref(prefs::kSyncInvalidationVersions); - registry->RegisterStringPref(prefs::kSyncLastRunVersion, std::string()); - registry->RegisterBooleanPref( - prefs::kSyncPassphraseEncryptionTransitionInProgress, false); - registry->RegisterStringPref(prefs::kSyncNigoriStateForPassphraseTransition, - std::string()); -} - -void SyncPrefs::AddSyncPrefObserver(SyncPrefObserver* sync_pref_observer) { - DCHECK(CalledOnValidThread()); - sync_pref_observers_.AddObserver(sync_pref_observer); -} - -void SyncPrefs::RemoveSyncPrefObserver(SyncPrefObserver* sync_pref_observer) { - DCHECK(CalledOnValidThread()); - sync_pref_observers_.RemoveObserver(sync_pref_observer); -} - -void SyncPrefs::ClearPreferences() { - DCHECK(CalledOnValidThread()); - pref_service_->ClearPref(prefs::kSyncLastSyncedTime); - pref_service_->ClearPref(prefs::kSyncLastPollTime); - pref_service_->ClearPref(prefs::kSyncFirstSetupComplete); - pref_service_->ClearPref(prefs::kSyncEncryptionBootstrapToken); - pref_service_->ClearPref(prefs::kSyncKeystoreEncryptionBootstrapToken); - pref_service_->ClearPref(prefs::kSyncPassphrasePrompted); - pref_service_->ClearPref(prefs::kSyncMemoryPressureWarningCount); - pref_service_->ClearPref(prefs::kSyncShutdownCleanly); - pref_service_->ClearPref(prefs::kSyncInvalidationVersions); - pref_service_->ClearPref(prefs::kSyncLastRunVersion); - pref_service_->ClearPref( - prefs::kSyncPassphraseEncryptionTransitionInProgress); - pref_service_->ClearPref(prefs::kSyncNigoriStateForPassphraseTransition); - - // TODO(nick): The current behavior does not clear - // e.g. prefs::kSyncBookmarks. Is that really what we want? -} - -bool SyncPrefs::IsFirstSetupComplete() const { - DCHECK(CalledOnValidThread()); - return pref_service_->GetBoolean(prefs::kSyncFirstSetupComplete); -} - -void SyncPrefs::SetFirstSetupComplete() { - DCHECK(CalledOnValidThread()); - pref_service_->SetBoolean(prefs::kSyncFirstSetupComplete, true); -} - -bool SyncPrefs::SyncHasAuthError() const { - DCHECK(CalledOnValidThread()); - return pref_service_->GetBoolean(prefs::kSyncHasAuthError); -} - -void SyncPrefs::SetSyncAuthError(bool error) { - DCHECK(CalledOnValidThread()); - pref_service_->SetBoolean(prefs::kSyncHasAuthError, error); -} - -bool SyncPrefs::IsSyncRequested() const { - DCHECK(CalledOnValidThread()); - // IsSyncRequested is the inverse of the old SuppressStart pref. - // Since renaming a pref value is hard, here we still use the old one. - return !pref_service_->GetBoolean(prefs::kSyncSuppressStart); -} - -void SyncPrefs::SetSyncRequested(bool is_requested) { - DCHECK(CalledOnValidThread()); - // See IsSyncRequested for why we use this pref and !is_requested. - pref_service_->SetBoolean(prefs::kSyncSuppressStart, !is_requested); -} - -base::Time SyncPrefs::GetLastSyncedTime() const { - DCHECK(CalledOnValidThread()); - return base::Time::FromInternalValue( - pref_service_->GetInt64(prefs::kSyncLastSyncedTime)); -} - -void SyncPrefs::SetLastSyncedTime(base::Time time) { - DCHECK(CalledOnValidThread()); - pref_service_->SetInt64(prefs::kSyncLastSyncedTime, time.ToInternalValue()); -} - -base::Time SyncPrefs::GetLastPollTime() const { - DCHECK(CalledOnValidThread()); - return base::Time::FromInternalValue( - pref_service_->GetInt64(prefs::kSyncLastSyncedTime)); -} - -void SyncPrefs::SetLastPollTime(base::Time time) { - DCHECK(CalledOnValidThread()); - pref_service_->SetInt64(prefs::kSyncLastPollTime, time.ToInternalValue()); -} - -bool SyncPrefs::HasKeepEverythingSynced() const { - DCHECK(CalledOnValidThread()); - return pref_service_->GetBoolean(prefs::kSyncKeepEverythingSynced); -} - -void SyncPrefs::SetKeepEverythingSynced(bool keep_everything_synced) { - DCHECK(CalledOnValidThread()); - pref_service_->SetBoolean(prefs::kSyncKeepEverythingSynced, - keep_everything_synced); -} - -syncer::ModelTypeSet SyncPrefs::GetPreferredDataTypes( - syncer::ModelTypeSet registered_types) const { - DCHECK(CalledOnValidThread()); - - if (pref_service_->GetBoolean(prefs::kSyncKeepEverythingSynced)) { - return registered_types; - } - - syncer::ModelTypeSet preferred_types; - for (syncer::ModelTypeSet::Iterator it = registered_types.First(); it.Good(); - it.Inc()) { - if (GetDataTypePreferred(it.Get())) { - preferred_types.Put(it.Get()); - } - } - return ResolvePrefGroups(registered_types, preferred_types); -} - -void SyncPrefs::SetPreferredDataTypes(syncer::ModelTypeSet registered_types, - syncer::ModelTypeSet preferred_types) { - DCHECK(CalledOnValidThread()); - preferred_types = ResolvePrefGroups(registered_types, preferred_types); - DCHECK(registered_types.HasAll(preferred_types)); - for (syncer::ModelTypeSet::Iterator i = registered_types.First(); i.Good(); - i.Inc()) { - SetDataTypePreferred(i.Get(), preferred_types.Has(i.Get())); - } -} - -bool SyncPrefs::IsManaged() const { - DCHECK(CalledOnValidThread()); - return pref_service_->GetBoolean(prefs::kSyncManaged); -} - -std::string SyncPrefs::GetEncryptionBootstrapToken() const { - DCHECK(CalledOnValidThread()); - return pref_service_->GetString(prefs::kSyncEncryptionBootstrapToken); -} - -void SyncPrefs::SetEncryptionBootstrapToken(const std::string& token) { - DCHECK(CalledOnValidThread()); - pref_service_->SetString(prefs::kSyncEncryptionBootstrapToken, token); -} - -std::string SyncPrefs::GetKeystoreEncryptionBootstrapToken() const { - DCHECK(CalledOnValidThread()); - return pref_service_->GetString(prefs::kSyncKeystoreEncryptionBootstrapToken); -} - -void SyncPrefs::SetKeystoreEncryptionBootstrapToken(const std::string& token) { - DCHECK(CalledOnValidThread()); - pref_service_->SetString(prefs::kSyncKeystoreEncryptionBootstrapToken, token); -} - -std::string SyncPrefs::GetSyncSessionsGUID() const { - DCHECK(CalledOnValidThread()); - return pref_service_->GetString(prefs::kSyncSessionsGUID); -} - -void SyncPrefs::SetSyncSessionsGUID(const std::string& guid) { - DCHECK(CalledOnValidThread()); - pref_service_->SetString(prefs::kSyncSessionsGUID, guid); -} - -// static -const char* SyncPrefs::GetPrefNameForDataType(syncer::ModelType data_type) { - switch (data_type) { - case syncer::BOOKMARKS: - return prefs::kSyncBookmarks; - case syncer::PASSWORDS: - return prefs::kSyncPasswords; - case syncer::PREFERENCES: - return prefs::kSyncPreferences; - case syncer::AUTOFILL: - return prefs::kSyncAutofill; - case syncer::AUTOFILL_PROFILE: - return prefs::kSyncAutofillProfile; - case syncer::AUTOFILL_WALLET_DATA: - return prefs::kSyncAutofillWallet; - case syncer::AUTOFILL_WALLET_METADATA: - return prefs::kSyncAutofillWalletMetadata; - case syncer::THEMES: - return prefs::kSyncThemes; - case syncer::TYPED_URLS: - return prefs::kSyncTypedUrls; - case syncer::EXTENSION_SETTINGS: - return prefs::kSyncExtensionSettings; - case syncer::EXTENSIONS: - return prefs::kSyncExtensions; - case syncer::APP_LIST: - return prefs::kSyncAppList; - case syncer::APP_SETTINGS: - return prefs::kSyncAppSettings; - case syncer::APPS: - return prefs::kSyncApps; - case syncer::SEARCH_ENGINES: - return prefs::kSyncSearchEngines; - case syncer::SESSIONS: - return prefs::kSyncSessions; - case syncer::APP_NOTIFICATIONS: - return prefs::kSyncAppNotifications; - case syncer::HISTORY_DELETE_DIRECTIVES: - return prefs::kSyncHistoryDeleteDirectives; - case syncer::SYNCED_NOTIFICATIONS: - return prefs::kSyncSyncedNotifications; - case syncer::SYNCED_NOTIFICATION_APP_INFO: - return prefs::kSyncSyncedNotificationAppInfo; - case syncer::DICTIONARY: - return prefs::kSyncDictionary; - case syncer::FAVICON_IMAGES: - return prefs::kSyncFaviconImages; - case syncer::FAVICON_TRACKING: - return prefs::kSyncFaviconTracking; - case syncer::SUPERVISED_USER_SETTINGS: - return prefs::kSyncSupervisedUserSettings; - case syncer::PROXY_TABS: - return prefs::kSyncTabs; - case syncer::PRIORITY_PREFERENCES: - return prefs::kSyncPriorityPreferences; - case syncer::SUPERVISED_USERS: - return prefs::kSyncSupervisedUsers; - case syncer::ARTICLES: - return prefs::kSyncArticles; - case syncer::SUPERVISED_USER_SHARED_SETTINGS: - return prefs::kSyncSupervisedUserSharedSettings; - case syncer::SUPERVISED_USER_WHITELISTS: - return prefs::kSyncSupervisedUserWhitelists; - case syncer::DEVICE_INFO: - return prefs::kSyncDeviceInfo; - case syncer::WIFI_CREDENTIALS: - return prefs::kSyncWifiCredentials; - case syncer::ARC_PACKAGE: - return prefs::kSyncArcPackage; - default: - break; - } - NOTREACHED() << "Type is " << data_type; - return NULL; -} - -#if defined(OS_CHROMEOS) -std::string SyncPrefs::GetSpareBootstrapToken() const { - DCHECK(CalledOnValidThread()); - return pref_service_->GetString(prefs::kSyncSpareBootstrapToken); -} - -void SyncPrefs::SetSpareBootstrapToken(const std::string& token) { - DCHECK(CalledOnValidThread()); - pref_service_->SetString(prefs::kSyncSpareBootstrapToken, token); -} -#endif - -void SyncPrefs::OnSyncManagedPrefChanged() { - DCHECK(CalledOnValidThread()); - FOR_EACH_OBSERVER(SyncPrefObserver, - sync_pref_observers_, - OnSyncManagedPrefChange(*pref_sync_managed_)); -} - -void SyncPrefs::SetManagedForTest(bool is_managed) { - DCHECK(CalledOnValidThread()); - pref_service_->SetBoolean(prefs::kSyncManaged, is_managed); -} - -void SyncPrefs::RegisterPrefGroups() { - pref_groups_[syncer::APPS].Put(syncer::APP_NOTIFICATIONS); - pref_groups_[syncer::APPS].Put(syncer::APP_SETTINGS); - pref_groups_[syncer::APPS].Put(syncer::APP_LIST); - - pref_groups_[syncer::AUTOFILL].Put(syncer::AUTOFILL_PROFILE); - pref_groups_[syncer::AUTOFILL].Put(syncer::AUTOFILL_WALLET_DATA); - pref_groups_[syncer::AUTOFILL].Put(syncer::AUTOFILL_WALLET_METADATA); - - pref_groups_[syncer::EXTENSIONS].Put(syncer::EXTENSION_SETTINGS); - - pref_groups_[syncer::PREFERENCES].Put(syncer::DICTIONARY); - pref_groups_[syncer::PREFERENCES].Put(syncer::PRIORITY_PREFERENCES); - pref_groups_[syncer::PREFERENCES].Put(syncer::SEARCH_ENGINES); - - pref_groups_[syncer::TYPED_URLS].Put(syncer::HISTORY_DELETE_DIRECTIVES); - pref_groups_[syncer::TYPED_URLS].Put(syncer::SESSIONS); - pref_groups_[syncer::TYPED_URLS].Put(syncer::FAVICON_IMAGES); - pref_groups_[syncer::TYPED_URLS].Put(syncer::FAVICON_TRACKING); - - pref_groups_[syncer::PROXY_TABS].Put(syncer::SESSIONS); - pref_groups_[syncer::PROXY_TABS].Put(syncer::FAVICON_IMAGES); - pref_groups_[syncer::PROXY_TABS].Put(syncer::FAVICON_TRACKING); - - // TODO(zea): put favicons in the bookmarks group as well once it handles - // those favicons. -} - -// static -void SyncPrefs::RegisterDataTypePreferredPref( - user_prefs::PrefRegistrySyncable* registry, - syncer::ModelType type, - bool is_preferred) { - const char* pref_name = GetPrefNameForDataType(type); - if (!pref_name) { - NOTREACHED(); - return; - } - registry->RegisterBooleanPref(pref_name, is_preferred); -} - -bool SyncPrefs::GetDataTypePreferred(syncer::ModelType type) const { - DCHECK(CalledOnValidThread()); - const char* pref_name = GetPrefNameForDataType(type); - if (!pref_name) { - NOTREACHED(); - return false; - } - - // Device info is always enabled. - if (pref_name == prefs::kSyncDeviceInfo) - return true; - - if (type == syncer::PROXY_TABS && - pref_service_->GetUserPrefValue(pref_name) == NULL && - pref_service_->IsUserModifiablePreference(pref_name)) { - // If there is no tab sync preference yet (i.e. newly enabled type), - // default to the session sync preference value. - pref_name = GetPrefNameForDataType(syncer::SESSIONS); - } - - return pref_service_->GetBoolean(pref_name); -} - -void SyncPrefs::SetDataTypePreferred(syncer::ModelType type, - bool is_preferred) { - DCHECK(CalledOnValidThread()); - const char* pref_name = GetPrefNameForDataType(type); - if (!pref_name) { - NOTREACHED(); - return; - } - - // Device info is always preferred. - if (type == syncer::DEVICE_INFO) - return; - - pref_service_->SetBoolean(pref_name, is_preferred); -} - -syncer::ModelTypeSet SyncPrefs::ResolvePrefGroups( - syncer::ModelTypeSet registered_types, - syncer::ModelTypeSet types) const { - syncer::ModelTypeSet types_with_groups = types; - for (PrefGroupsMap::const_iterator i = pref_groups_.begin(); - i != pref_groups_.end(); - ++i) { - if (types.Has(i->first)) - types_with_groups.PutAll(i->second); - } - types_with_groups.RetainAll(registered_types); - return types_with_groups; -} - -base::Time SyncPrefs::GetFirstSyncTime() const { - return base::Time::FromInternalValue( - pref_service_->GetInt64(prefs::kSyncFirstSyncTime)); -} - -void SyncPrefs::SetFirstSyncTime(base::Time time) { - pref_service_->SetInt64(prefs::kSyncFirstSyncTime, time.ToInternalValue()); -} - -void SyncPrefs::ClearFirstSyncTime() { - pref_service_->ClearPref(prefs::kSyncFirstSyncTime); -} - -bool SyncPrefs::IsPassphrasePrompted() const { - return pref_service_->GetBoolean(prefs::kSyncPassphrasePrompted); -} - -void SyncPrefs::SetPassphrasePrompted(bool value) { - pref_service_->SetBoolean(prefs::kSyncPassphrasePrompted, value); -} - -int SyncPrefs::GetMemoryPressureWarningCount() const { - return pref_service_->GetInteger(prefs::kSyncMemoryPressureWarningCount); -} - -void SyncPrefs::SetMemoryPressureWarningCount(int value) { - pref_service_->SetInteger(prefs::kSyncMemoryPressureWarningCount, value); -} - -bool SyncPrefs::DidSyncShutdownCleanly() const { - return pref_service_->GetBoolean(prefs::kSyncShutdownCleanly); -} - -void SyncPrefs::SetCleanShutdown(bool value) { - pref_service_->SetBoolean(prefs::kSyncShutdownCleanly, value); -} - -void SyncPrefs::GetInvalidationVersions( - std::map<syncer::ModelType, int64_t>* invalidation_versions) const { - const base::DictionaryValue* invalidation_dictionary = - pref_service_->GetDictionary(prefs::kSyncInvalidationVersions); - syncer::ModelTypeSet protocol_types = syncer::ProtocolTypes(); - for (auto iter = protocol_types.First(); iter.Good(); iter.Inc()) { - std::string key = syncer::ModelTypeToString(iter.Get()); - std::string version_str; - if (!invalidation_dictionary->GetString(key, &version_str)) - continue; - int64_t version = 0; - if (!base::StringToInt64(version_str, &version)) - continue; - (*invalidation_versions)[iter.Get()] = version; - } -} - -void SyncPrefs::UpdateInvalidationVersions( - const std::map<syncer::ModelType, int64_t>& invalidation_versions) { - std::unique_ptr<base::DictionaryValue> invalidation_dictionary( - new base::DictionaryValue()); - for (const auto& map_iter : invalidation_versions) { - std::string version_str = base::Int64ToString(map_iter.second); - invalidation_dictionary->SetString( - syncer::ModelTypeToString(map_iter.first), version_str); - } - pref_service_->Set(prefs::kSyncInvalidationVersions, - *invalidation_dictionary); -} - -std::string SyncPrefs::GetLastRunVersion() const { - return pref_service_->GetString(prefs::kSyncLastRunVersion); -} - -void SyncPrefs::SetLastRunVersion(const std::string& current_version) { - pref_service_->SetString(prefs::kSyncLastRunVersion, current_version); -} - -void SyncPrefs::SetPassphraseEncryptionTransitionInProgress(bool value) { - pref_service_->SetBoolean( - prefs::kSyncPassphraseEncryptionTransitionInProgress, value); -} - -bool SyncPrefs::GetPassphraseEncryptionTransitionInProgress() const { - return pref_service_->GetBoolean( - prefs::kSyncPassphraseEncryptionTransitionInProgress); -} - -void SyncPrefs::SetSavedNigoriStateForPassphraseEncryptionTransition( - const syncer::SyncEncryptionHandler::NigoriState& nigori_state) { - std::string encoded; - base::Base64Encode(nigori_state.nigori_specifics.SerializeAsString(), - &encoded); - pref_service_->SetString(prefs::kSyncNigoriStateForPassphraseTransition, - encoded); -} - -std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> -SyncPrefs::GetSavedNigoriStateForPassphraseEncryptionTransition() const { - const std::string encoded = - pref_service_->GetString(prefs::kSyncNigoriStateForPassphraseTransition); - std::string decoded; - if (!base::Base64Decode(encoded, &decoded)) - return std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState>(); - - std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState> result( - new syncer::SyncEncryptionHandler::NigoriState()); - if (!result->nigori_specifics.ParseFromString(decoded)) - return std::unique_ptr<syncer::SyncEncryptionHandler::NigoriState>(); - return result; -} - -} // namespace sync_driver
diff --git a/components/sync_driver/sync_prefs_unittest.cc b/components/sync_driver/sync_prefs_unittest.cc deleted file mode 100644 index 04b86c5..0000000 --- a/components/sync_driver/sync_prefs_unittest.cc +++ /dev/null
@@ -1,264 +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 "components/sync_driver/sync_prefs.h" - -#include <stdint.h> - -#include <map> - -#include "base/command_line.h" -#include "base/message_loop/message_loop.h" -#include "base/time/time.h" -#include "components/pref_registry/testing_pref_service_syncable.h" -#include "components/prefs/pref_notifier_impl.h" -#include "components/prefs/pref_value_store.h" -#include "components/prefs/testing_pref_service.h" -#include "components/sync/base/model_type.h" -#include "components/sync_driver/pref_names.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sync_driver { - -namespace { - -using ::testing::InSequence; -using ::testing::StrictMock; - -class SyncPrefsTest : public testing::Test { - protected: - void SetUp() override { - SyncPrefs::RegisterProfilePrefs(pref_service_.registry()); - } - - user_prefs::TestingPrefServiceSyncable pref_service_; - - private: - base::MessageLoop loop_; -}; - -TEST_F(SyncPrefsTest, Basic) { - SyncPrefs sync_prefs(&pref_service_); - - EXPECT_FALSE(sync_prefs.IsFirstSetupComplete()); - sync_prefs.SetFirstSetupComplete(); - EXPECT_TRUE(sync_prefs.IsFirstSetupComplete()); - - EXPECT_TRUE(sync_prefs.IsSyncRequested()); - sync_prefs.SetSyncRequested(false); - EXPECT_FALSE(sync_prefs.IsSyncRequested()); - sync_prefs.SetSyncRequested(true); - EXPECT_TRUE(sync_prefs.IsSyncRequested()); - - EXPECT_EQ(base::Time(), sync_prefs.GetLastSyncedTime()); - const base::Time& now = base::Time::Now(); - sync_prefs.SetLastSyncedTime(now); - EXPECT_EQ(now, sync_prefs.GetLastSyncedTime()); - - EXPECT_TRUE(sync_prefs.HasKeepEverythingSynced()); - sync_prefs.SetKeepEverythingSynced(false); - EXPECT_FALSE(sync_prefs.HasKeepEverythingSynced()); - sync_prefs.SetKeepEverythingSynced(true); - EXPECT_TRUE(sync_prefs.HasKeepEverythingSynced()); - - EXPECT_TRUE(sync_prefs.GetEncryptionBootstrapToken().empty()); - sync_prefs.SetEncryptionBootstrapToken("token"); - EXPECT_EQ("token", sync_prefs.GetEncryptionBootstrapToken()); -} - -TEST_F(SyncPrefsTest, DefaultTypes) { - SyncPrefs sync_prefs(&pref_service_); - sync_prefs.SetKeepEverythingSynced(false); - - // Only bookmarks and device info are enabled by default. - syncer::ModelTypeSet expected(syncer::BOOKMARKS, syncer::DEVICE_INFO); - syncer::ModelTypeSet preferred_types = - sync_prefs.GetPreferredDataTypes(syncer::UserTypes()); - EXPECT_EQ(expected, preferred_types); - - // Simulate an upgrade to delete directives + proxy tabs support. None of the - // new types or their pref group types should be registering, ensuring they - // don't have pref values. - syncer::ModelTypeSet registered_types = syncer::UserTypes(); - registered_types.Remove(syncer::PROXY_TABS); - registered_types.Remove(syncer::TYPED_URLS); - registered_types.Remove(syncer::SESSIONS); - registered_types.Remove(syncer::HISTORY_DELETE_DIRECTIVES); - - // Enable all other types. - sync_prefs.SetPreferredDataTypes(registered_types, registered_types); - - // Manually enable typed urls (to simulate the old world). - pref_service_.SetBoolean(prefs::kSyncTypedUrls, true); - - // Proxy tabs should not be enabled (since sessions wasn't), but history - // delete directives should (since typed urls was). - preferred_types = sync_prefs.GetPreferredDataTypes(syncer::UserTypes()); - EXPECT_FALSE(preferred_types.Has(syncer::PROXY_TABS)); - EXPECT_TRUE(preferred_types.Has(syncer::HISTORY_DELETE_DIRECTIVES)); - - // Now manually enable sessions, which should result in proxy tabs also being - // enabled. Also, manually disable typed urls, which should mean that history - // delete directives are not enabled. - pref_service_.SetBoolean(prefs::kSyncTypedUrls, false); - pref_service_.SetBoolean(prefs::kSyncSessions, true); - preferred_types = sync_prefs.GetPreferredDataTypes(syncer::UserTypes()); - EXPECT_TRUE(preferred_types.Has(syncer::PROXY_TABS)); - EXPECT_FALSE(preferred_types.Has(syncer::HISTORY_DELETE_DIRECTIVES)); -} - -TEST_F(SyncPrefsTest, PreferredTypesKeepEverythingSynced) { - SyncPrefs sync_prefs(&pref_service_); - - EXPECT_TRUE(sync_prefs.HasKeepEverythingSynced()); - - const syncer::ModelTypeSet user_types = syncer::UserTypes(); - EXPECT_EQ(user_types, sync_prefs.GetPreferredDataTypes(user_types)); - const syncer::ModelTypeSet user_visible_types = syncer::UserSelectableTypes(); - for (syncer::ModelTypeSet::Iterator it = user_visible_types.First(); - it.Good(); - it.Inc()) { - syncer::ModelTypeSet preferred_types; - preferred_types.Put(it.Get()); - sync_prefs.SetPreferredDataTypes(user_types, preferred_types); - EXPECT_EQ(user_types, sync_prefs.GetPreferredDataTypes(user_types)); - } -} - -TEST_F(SyncPrefsTest, PreferredTypesNotKeepEverythingSynced) { - SyncPrefs sync_prefs(&pref_service_); - - sync_prefs.SetKeepEverythingSynced(false); - - const syncer::ModelTypeSet user_types = syncer::UserTypes(); - EXPECT_NE(user_types, sync_prefs.GetPreferredDataTypes(user_types)); - const syncer::ModelTypeSet user_visible_types = syncer::UserSelectableTypes(); - for (syncer::ModelTypeSet::Iterator it = user_visible_types.First(); - it.Good(); - it.Inc()) { - syncer::ModelTypeSet preferred_types; - preferred_types.Put(it.Get()); - syncer::ModelTypeSet expected_preferred_types(preferred_types); - if (it.Get() == syncer::AUTOFILL) { - expected_preferred_types.Put(syncer::AUTOFILL_PROFILE); - expected_preferred_types.Put(syncer::AUTOFILL_WALLET_DATA); - expected_preferred_types.Put(syncer::AUTOFILL_WALLET_METADATA); - } - if (it.Get() == syncer::PREFERENCES) { - expected_preferred_types.Put(syncer::DICTIONARY); - expected_preferred_types.Put(syncer::PRIORITY_PREFERENCES); - expected_preferred_types.Put(syncer::SEARCH_ENGINES); - } - if (it.Get() == syncer::APPS) { - expected_preferred_types.Put(syncer::APP_LIST); - expected_preferred_types.Put(syncer::APP_NOTIFICATIONS); - expected_preferred_types.Put(syncer::APP_SETTINGS); - } - if (it.Get() == syncer::EXTENSIONS) { - expected_preferred_types.Put(syncer::EXTENSION_SETTINGS); - } - if (it.Get() == syncer::TYPED_URLS) { - expected_preferred_types.Put(syncer::HISTORY_DELETE_DIRECTIVES); - expected_preferred_types.Put(syncer::SESSIONS); - expected_preferred_types.Put(syncer::FAVICON_IMAGES); - expected_preferred_types.Put(syncer::FAVICON_TRACKING); - } - if (it.Get() == syncer::PROXY_TABS) { - expected_preferred_types.Put(syncer::SESSIONS); - expected_preferred_types.Put(syncer::FAVICON_IMAGES); - expected_preferred_types.Put(syncer::FAVICON_TRACKING); - } - - // Device info is always preferred. - expected_preferred_types.Put(syncer::DEVICE_INFO); - - sync_prefs.SetPreferredDataTypes(user_types, preferred_types); - EXPECT_EQ(expected_preferred_types, - sync_prefs.GetPreferredDataTypes(user_types)); - } -} - -class MockSyncPrefObserver : public SyncPrefObserver { - public: - MOCK_METHOD1(OnSyncManagedPrefChange, void(bool)); -}; - -TEST_F(SyncPrefsTest, ObservedPrefs) { - SyncPrefs sync_prefs(&pref_service_); - - StrictMock<MockSyncPrefObserver> mock_sync_pref_observer; - InSequence dummy; - EXPECT_CALL(mock_sync_pref_observer, OnSyncManagedPrefChange(true)); - EXPECT_CALL(mock_sync_pref_observer, OnSyncManagedPrefChange(false)); - - EXPECT_FALSE(sync_prefs.IsManaged()); - - sync_prefs.AddSyncPrefObserver(&mock_sync_pref_observer); - - sync_prefs.SetManagedForTest(true); - EXPECT_TRUE(sync_prefs.IsManaged()); - sync_prefs.SetManagedForTest(false); - EXPECT_FALSE(sync_prefs.IsManaged()); - - sync_prefs.RemoveSyncPrefObserver(&mock_sync_pref_observer); -} - -TEST_F(SyncPrefsTest, ClearPreferences) { - SyncPrefs sync_prefs(&pref_service_); - - EXPECT_FALSE(sync_prefs.IsFirstSetupComplete()); - EXPECT_EQ(base::Time(), sync_prefs.GetLastSyncedTime()); - EXPECT_TRUE(sync_prefs.GetEncryptionBootstrapToken().empty()); - - sync_prefs.SetFirstSetupComplete(); - sync_prefs.SetLastSyncedTime(base::Time::Now()); - sync_prefs.SetEncryptionBootstrapToken("token"); - - EXPECT_TRUE(sync_prefs.IsFirstSetupComplete()); - EXPECT_NE(base::Time(), sync_prefs.GetLastSyncedTime()); - EXPECT_EQ("token", sync_prefs.GetEncryptionBootstrapToken()); - - sync_prefs.ClearPreferences(); - - EXPECT_FALSE(sync_prefs.IsFirstSetupComplete()); - EXPECT_EQ(base::Time(), sync_prefs.GetLastSyncedTime()); - EXPECT_TRUE(sync_prefs.GetEncryptionBootstrapToken().empty()); -} - -// Device info should always be enabled. -TEST_F(SyncPrefsTest, DeviceInfo) { - SyncPrefs sync_prefs(&pref_service_); - EXPECT_TRUE(sync_prefs.GetPreferredDataTypes(syncer::UserTypes()) - .Has(syncer::DEVICE_INFO)); - sync_prefs.SetKeepEverythingSynced(true); - EXPECT_TRUE(sync_prefs.GetPreferredDataTypes(syncer::UserTypes()) - .Has(syncer::DEVICE_INFO)); - sync_prefs.SetKeepEverythingSynced(false); - EXPECT_TRUE(sync_prefs.GetPreferredDataTypes(syncer::UserTypes()) - .Has(syncer::DEVICE_INFO)); -} - -// Verify that invalidation versions are persisted and loaded correctly. -TEST_F(SyncPrefsTest, InvalidationVersions) { - std::map<syncer::ModelType, int64_t> versions; - versions[syncer::BOOKMARKS] = 10; - versions[syncer::SESSIONS] = 20; - versions[syncer::PREFERENCES] = 30; - - SyncPrefs sync_prefs(&pref_service_); - sync_prefs.UpdateInvalidationVersions(versions); - - std::map<syncer::ModelType, int64_t> versions2; - sync_prefs.GetInvalidationVersions(&versions2); - - EXPECT_EQ(versions.size(), versions2.size()); - for (auto map_iter : versions2) { - EXPECT_EQ(versions[map_iter.first], map_iter.second); - } -} - -} // namespace - -} // namespace sync_driver
diff --git a/components/sync_driver/sync_service.cc b/components/sync_driver/sync_service.cc deleted file mode 100644 index f9c1317..0000000 --- a/components/sync_driver/sync_service.cc +++ /dev/null
@@ -1,23 +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. - -#include "components/sync_driver/sync_service.h" - -#include "components/sync/core/sync_manager.h" -#include "google_apis/gaia/google_service_auth_error.h" - -namespace sync_driver { - -SyncSetupInProgressHandle::SyncSetupInProgressHandle(base::Closure on_destroy) - : on_destroy_(on_destroy) {} - -SyncSetupInProgressHandle::~SyncSetupInProgressHandle() { - on_destroy_.Run(); -} - -SyncService::SyncTokenStatus::SyncTokenStatus() - : connection_status(syncer::CONNECTION_NOT_ATTEMPTED), - last_get_token_error(GoogleServiceAuthError::AuthErrorNone()) {} - -} // namespace sync_driver
diff --git a/components/sync_driver/sync_service.h b/components/sync_driver/sync_service.h deleted file mode 100644 index 0f131b37..0000000 --- a/components/sync_driver/sync_service.h +++ /dev/null
@@ -1,351 +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. - -#ifndef COMPONENTS_SYNC_DRIVER_SYNC_SERVICE_H_ -#define COMPONENTS_SYNC_DRIVER_SYNC_SERVICE_H_ - -#include <memory> -#include <string> - -#include "base/callback.h" -#include "base/location.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/time/time.h" -#include "components/sync/base/model_type.h" -#include "components/sync/core/connection_status.h" -#include "components/sync_driver/data_type_encryption_handler.h" -#include "components/sync_driver/sync_service_observer.h" -#include "google_apis/gaia/google_service_auth_error.h" - -class GoogleServiceAuthError; - -namespace browser_sync { -class ProtocolEventObserver; -} - -namespace syncer { - -class BaseTransaction; -class JsController; -class TypeDebugInfoObserver; -struct SyncStatus; -struct UserShare; - -namespace sessions { -class SyncSessionSnapshot; -} // namespace sessions - -} // namespace syncer - -namespace sync_driver { - -class DataTypeController; -class LocalDeviceInfoProvider; -class OpenTabsUIDelegate; -class SyncClient; - -// UIs that need to prevent Sync startup should hold an instance of this class -// until the user has finished modifying sync settings. This is not an inner -// class of SyncService to enable forward declarations. -class SyncSetupInProgressHandle { - public: - // UIs should not construct this directly, but instead call - // SyncService::GetSetupInProgress(). - explicit SyncSetupInProgressHandle(base::Closure on_destroy); - - ~SyncSetupInProgressHandle(); - - private: - base::Closure on_destroy_; -}; - -class SyncService : public DataTypeEncryptionHandler { - public: - // Used to specify the kind of passphrase with which sync data is encrypted. - enum PassphraseType { - IMPLICIT, // The user did not provide a custom passphrase for encryption. - // We implicitly use the GAIA password in such cases. - EXPLICIT, // The user selected the "use custom passphrase" radio button - // during sync setup and provided a passphrase. - }; - - // Passed as an argument to RequestStop to control whether or not the sync - // backend should clear its data directory when it shuts down. See - // RequestStop for more information. - enum SyncStopDataFate { - KEEP_DATA, - CLEAR_DATA, - }; - - // Status of sync server connection, sync token and token request. - struct SyncTokenStatus { - SyncTokenStatus(); - - // Sync server connection status reported by sync backend. - base::Time connection_status_update_time; - syncer::ConnectionStatus connection_status; - - // Times when OAuth2 access token is requested and received. - base::Time token_request_time; - base::Time token_receive_time; - - // Error returned by OAuth2TokenService for token request and time when - // next request is scheduled. - GoogleServiceAuthError last_get_token_error; - base::Time next_token_request_time; - }; - - ~SyncService() override {} - - // Whether sync is enabled by user or not. This does not necessarily mean - // that sync is currently running (due to delayed startup, unrecoverable - // errors, or shutdown). See IsSyncActive below for checking whether sync - // is actually running. - virtual bool IsFirstSetupComplete() const = 0; - - // Whether sync is allowed to start. Command line flags, platform-level - // overrides, and account-level overrides are examples of reasons this - // might be false. - virtual bool IsSyncAllowed() const = 0; - - // Returns true if sync is fully initialized and active. This implies that - // an initial configuration has successfully completed, although there may - // be datatype specific, auth, or other transient errors. To see which - // datetypes are actually syncing, see GetActiveTypes() below. - virtual bool IsSyncActive() const = 0; - - // Triggers a GetUpdates call for the specified |types|, pulling any new data - // from the sync server. - virtual void TriggerRefresh(const syncer::ModelTypeSet& types) = 0; - - // Get the set of current active data types (those chosen or configured by - // the user which have not also encountered a runtime error). - // Note that if the Sync engine is in the middle of a configuration, this - // will the the empty set. Once the configuration completes the set will - // be updated. - virtual syncer::ModelTypeSet GetActiveDataTypes() const = 0; - - // Returns the SyncClient instance associated with this service. - virtual SyncClient* GetSyncClient() const = 0; - - // Adds/removes an observer. SyncService does not take ownership of the - // observer. - virtual void AddObserver(SyncServiceObserver* observer) = 0; - virtual void RemoveObserver(SyncServiceObserver* observer) = 0; - - // Returns true if |observer| has already been added as an observer. - virtual bool HasObserver(const SyncServiceObserver* observer) const = 0; - - // --------------------------------------------------------------------------- - // TODO(sync): The methods below were pulled from ProfileSyncService, and - // should be evaluated to see if they should stay. - - // Called when a datatype (SyncableService) has a need for sync to start - // ASAP, presumably because a local change event has occurred but we're - // still in deferred start mode, meaning the SyncableService hasn't been - // told to MergeDataAndStartSyncing yet. - virtual void OnDataTypeRequestsSyncStartup(syncer::ModelType type) = 0; - - // Returns true if sync is allowed, requested, and the user is logged in. - // (being logged in does not mean that tokens are available - tokens may - // be missing because they have not loaded yet, or because they were deleted - // due to http://crbug.com/121755). - virtual bool CanSyncStart() const = 0; - - // Stops sync at the user's request. |data_fate| controls whether the sync - // backend should clear its data directory when it shuts down. Generally - // KEEP_DATA is used when the user just stops sync, and CLEAR_DATA is used - // when they sign out of the profile entirely. - virtual void RequestStop(SyncStopDataFate data_fate) = 0; - - // The user requests that sync start. This only actually starts sync if - // IsSyncAllowed is true and the user is signed in. Once sync starts, - // other things such as IsFirstSetupComplete being false can still prevent - // it from moving into the "active" state. - virtual void RequestStart() = 0; - - // Returns the set of types which are preferred for enabling. This is a - // superset of the active types (see GetActiveDataTypes()). - virtual syncer::ModelTypeSet GetPreferredDataTypes() const = 0; - - // Called when a user chooses which data types to sync. |sync_everything| - // represents whether they chose the "keep everything synced" option; if - // true, |chosen_types| will be ignored and all data types will be synced. - // |sync_everything| means "sync all current and future data types." - // |chosen_types| must be a subset of syncer::UserSelectableTypes(). - virtual void OnUserChoseDatatypes(bool sync_everything, - syncer::ModelTypeSet chosen_types) = 0; - - // Called whe Sync has been setup by the user and can be started. - virtual void SetFirstSetupComplete() = 0; - - // Returns true if initial sync setup is in progress (does not return true - // if the user is customizing sync after already completing setup once). - // SyncService uses this to determine if it's OK to start syncing, or if the - // user is still setting up the initial sync configuration. - virtual bool IsFirstSetupInProgress() const = 0; - - // Called by the UI to notify the SyncService that UI is visible so it will - // not start syncing. This tells sync whether it's safe to start downloading - // data types yet (we don't start syncing until after sync setup is complete). - // The UI calls this and holds onto the instance for as long as any part of - // the signin wizard is displayed (even just the login UI). - // When the last outstanding handle is deleted, this kicks off the sync engine - // to ensure that data download starts. In this case, - // |ReconfigureDatatypeManager| will get triggered. - virtual std::unique_ptr<SyncSetupInProgressHandle> - GetSetupInProgressHandle() = 0; - - // Used by tests. - virtual bool IsSetupInProgress() const = 0; - - // Whether the data types active for the current mode have finished - // configuration. - virtual bool ConfigurationDone() const = 0; - - virtual const GoogleServiceAuthError& GetAuthError() const = 0; - virtual bool HasUnrecoverableError() const = 0; - - // Returns true if the SyncBackendHost has told us it's ready to accept - // changes. This should only be used for sync's internal configuration logic - // (such as deciding when to prompt for an encryption passphrase). - virtual bool IsBackendInitialized() const = 0; - - // Return the active OpenTabsUIDelegate. If sessions is not enabled or not - // currently syncing, returns nullptr. - virtual OpenTabsUIDelegate* GetOpenTabsUIDelegate() = 0; - - // Returns true if OnPassphraseRequired has been called for decryption and - // we have an encrypted data type enabled. - virtual bool IsPassphraseRequiredForDecryption() const = 0; - - // Returns the time the current explicit passphrase (if any), was set. - // If no secondary passphrase is in use, or no time is available, returns an - // unset base::Time. - virtual base::Time GetExplicitPassphraseTime() const = 0; - - // Returns true if a secondary (explicit) passphrase is being used. It is not - // legal to call this method before the backend is initialized. - virtual bool IsUsingSecondaryPassphrase() const = 0; - - // Turns on encryption for all data. Callers must call OnUserChoseDatatypes() - // after calling this to force the encryption to occur. - virtual void EnableEncryptEverything() = 0; - - // Returns true if we are currently set to encrypt all the sync data. - virtual bool IsEncryptEverythingEnabled() const = 0; - - // Asynchronously sets the passphrase to |passphrase| for encryption. |type| - // specifies whether the passphrase is a custom passphrase or the GAIA - // password being reused as a passphrase. - // TODO(atwilson): Change this so external callers can only set an EXPLICIT - // passphrase with this API. - virtual void SetEncryptionPassphrase(const std::string& passphrase, - PassphraseType type) = 0; - - // Asynchronously decrypts pending keys using |passphrase|. Returns false - // immediately if the passphrase could not be used to decrypt a locally cached - // copy of encrypted keys; returns true otherwise. - virtual bool SetDecryptionPassphrase(const std::string& passphrase) - WARN_UNUSED_RESULT = 0; - - // Checks whether the Cryptographer is ready to encrypt and decrypt updates - // for sensitive data types. Caller must be holding a - // syncapi::BaseTransaction to ensure thread safety. - virtual bool IsCryptographerReady( - const syncer::BaseTransaction* trans) const = 0; - - // TODO(akalin): This is called mostly by ModelAssociators and - // tests. Figure out how to pass the handle to the ModelAssociators - // directly, figure out how to expose this to tests, and remove this - // function. - virtual syncer::UserShare* GetUserShare() const = 0; - - // Returns DeviceInfo provider for the local device. - virtual LocalDeviceInfoProvider* GetLocalDeviceInfoProvider() const = 0; - - // Registers a data type controller with the sync service. This - // makes the data type controller available for use, it does not - // enable or activate the synchronization of the data type (see - // ActivateDataType). Takes ownership of the pointer. - virtual void RegisterDataTypeController( - DataTypeController* data_type_controller) = 0; - - // Called to re-enable a type disabled by DisableDatatype(..). Note, this does - // not change the preferred state of a datatype, and is not persisted across - // restarts. - virtual void ReenableDatatype(syncer::ModelType type) = 0; - - // Return sync token status. - virtual SyncTokenStatus GetSyncTokenStatus() const = 0; - - // Get a description of the sync status for displaying in the user interface. - virtual std::string QuerySyncStatusSummaryString() = 0; - - // Initializes a struct of status indicators with data from the backend. - // Returns false if the backend was not available for querying; in that case - // the struct will be filled with default data. - virtual bool QueryDetailedSyncStatus(syncer::SyncStatus* result) = 0; - - // Returns a user-friendly string form of last synced time (in minutes). - virtual base::string16 GetLastSyncedTimeString() const = 0; - - // Returns a human readable string describing backend initialization state. - virtual std::string GetBackendInitializationStateString() const = 0; - - virtual syncer::sessions::SyncSessionSnapshot GetLastSessionSnapshot() - const = 0; - - // Returns a ListValue indicating the status of all registered types. - // - // The format is: - // [ {"name": <name>, "value": <value>, "status": <status> }, ... ] - // where <name> is a type's name, <value> is a string providing details for - // the type's status, and <status> is one of "error", "warning" or "ok" - // depending on the type's current status. - // - // This function is used by about_sync_util.cc to help populate the about:sync - // page. It returns a ListValue rather than a DictionaryValue in part to make - // it easier to iterate over its elements when constructing that page. - virtual base::Value* GetTypeStatusMap() const = 0; - - virtual const GURL& sync_service_url() const = 0; - - virtual std::string unrecoverable_error_message() const = 0; - virtual tracked_objects::Location unrecoverable_error_location() const = 0; - - virtual void AddProtocolEventObserver( - browser_sync::ProtocolEventObserver* observer) = 0; - virtual void RemoveProtocolEventObserver( - browser_sync::ProtocolEventObserver* observer) = 0; - - virtual void AddTypeDebugInfoObserver( - syncer::TypeDebugInfoObserver* observer) = 0; - virtual void RemoveTypeDebugInfoObserver( - syncer::TypeDebugInfoObserver* observer) = 0; - - // Returns a weak pointer to the service's JsController. - virtual base::WeakPtr<syncer::JsController> GetJsController() = 0; - - // Asynchronously fetches base::Value representations of all sync nodes and - // returns them to the specified callback on this thread. - // - // These requests can live a long time and return when you least expect it. - // For safety, the callback should be bound to some sort of WeakPtr<> or - // scoped_refptr<>. - virtual void GetAllNodes( - const base::Callback<void(std::unique_ptr<base::ListValue>)>& - callback) = 0; - - protected: - SyncService() {} - - private: - DISALLOW_COPY_AND_ASSIGN(SyncService); -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_SYNC_SERVICE_H_
diff --git a/components/sync_driver/sync_service_observer.cc b/components/sync_driver/sync_service_observer.cc deleted file mode 100644 index 00a04ad..0000000 --- a/components/sync_driver/sync_service_observer.cc +++ /dev/null
@@ -1,13 +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 "components/sync_driver/sync_service_observer.h" - -namespace sync_driver { - -void SyncServiceObserver::OnSyncCycleCompleted() { - OnStateChanged(); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/sync_service_utils.cc b/components/sync_driver/sync_service_utils.cc deleted file mode 100644 index 55ee907..0000000 --- a/components/sync_driver/sync_service_utils.cc +++ /dev/null
@@ -1,22 +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. - -#include "components/sync_driver/sync_service_utils.h" - -#include "components/sync_driver/sync_prefs.h" -#include "components/sync_driver/sync_service.h" - -namespace sync_driver { - -bool IsTabSyncEnabledAndUnencrypted(SyncService* sync_service, - PrefService* pref_service) { - // Check field trials and settings allow sending the URL on suggest requests. - sync_driver::SyncPrefs sync_prefs(pref_service); - return sync_service && sync_service->CanSyncStart() && - sync_prefs.GetPreferredDataTypes(syncer::UserTypes()) - .Has(syncer::PROXY_TABS) && - !sync_service->GetEncryptedDataTypes().Has(syncer::SESSIONS); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/sync_stopped_reporter.cc b/components/sync_driver/sync_stopped_reporter.cc deleted file mode 100644 index 37b8fcc..0000000 --- a/components/sync_driver/sync_stopped_reporter.cc +++ /dev/null
@@ -1,120 +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. - -#include "components/sync_driver/sync_stopped_reporter.h" - -#include "base/location.h" -#include "base/logging.h" -#include "base/single_thread_task_runner.h" -#include "base/strings/stringprintf.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/timer/timer.h" -#include "components/sync/protocol/sync.pb.h" -#include "net/base/load_flags.h" -#include "net/http/http_status_code.h" -#include "net/url_request/url_fetcher.h" -#include "net/url_request/url_request_context_getter.h" - -namespace { - -const char kEventEndpoint[] = "event"; - -// The request is tiny, so even on poor connections 10 seconds should be -// plenty of time. Since sync is off when this request is started, we don't -// want anything sync-related hanging around for very long from a human -// perspective either. This seems like a good compromise. -const int kRequestTimeoutSeconds = 10; - -} // namespace - -namespace browser_sync { - -SyncStoppedReporter::SyncStoppedReporter( - const GURL& sync_service_url, - const std::string& user_agent, - const scoped_refptr<net::URLRequestContextGetter>& request_context, - const ResultCallback& callback) - : sync_event_url_(GetSyncEventURL(sync_service_url)), - user_agent_(user_agent), - request_context_(request_context), - callback_(callback) { - DCHECK(!sync_service_url.is_empty()); - DCHECK(!user_agent_.empty()); - DCHECK(request_context); -} - -SyncStoppedReporter::~SyncStoppedReporter() {} - -void SyncStoppedReporter::ReportSyncStopped(const std::string& access_token, - const std::string& cache_guid, - const std::string& birthday) { - DCHECK(!access_token.empty()); - DCHECK(!cache_guid.empty()); - DCHECK(!birthday.empty()); - - // Make the request proto with the GUID identifying this client. - sync_pb::EventRequest event_request; - sync_pb::SyncDisabledEvent* sync_disabled_event = - event_request.mutable_sync_disabled(); - sync_disabled_event->set_cache_guid(cache_guid); - sync_disabled_event->set_store_birthday(birthday); - - std::string msg; - event_request.SerializeToString(&msg); - - fetcher_ = - net::URLFetcher::Create(sync_event_url_, net::URLFetcher::POST, this); - fetcher_->AddExtraRequestHeader(base::StringPrintf( - "%s: Bearer %s", net::HttpRequestHeaders::kAuthorization, - access_token.c_str())); - fetcher_->AddExtraRequestHeader(base::StringPrintf( - "%s: %s", net::HttpRequestHeaders::kUserAgent, user_agent_.c_str())); - fetcher_->SetRequestContext(request_context_.get()); - fetcher_->SetUploadData("application/octet-stream", msg); - fetcher_->SetLoadFlags(net::LOAD_BYPASS_CACHE | - net::LOAD_DISABLE_CACHE | - net::LOAD_DO_NOT_SAVE_COOKIES | - net::LOAD_DO_NOT_SEND_COOKIES); - fetcher_->Start(); - timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(kRequestTimeoutSeconds), - this, &SyncStoppedReporter::OnTimeout); -} - -void SyncStoppedReporter::OnURLFetchComplete(const net::URLFetcher* source) { - Result result = source->GetResponseCode() == net::HTTP_OK - ? RESULT_SUCCESS : RESULT_ERROR; - fetcher_.reset(); - timer_.Stop(); - if (!callback_.is_null()) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(callback_, result)); - } -} - -void SyncStoppedReporter::OnTimeout() { - fetcher_.reset(); - if (!callback_.is_null()) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(callback_, RESULT_TIMEOUT)); - } -} - -// Static. -GURL SyncStoppedReporter::GetSyncEventURL(const GURL& sync_service_url) { - std::string path = sync_service_url.path(); - if (path.empty() || *path.rbegin() != '/') { - path += '/'; - } - path += kEventEndpoint; - GURL::Replacements replacements; - replacements.SetPathStr(path); - return sync_service_url.ReplaceComponents(replacements); -} - -void SyncStoppedReporter::SetTimerTaskRunnerForTest( - const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) { - timer_.SetTaskRunner(task_runner); -} - -} // namespace browser_sync
diff --git a/components/sync_driver/sync_stopped_reporter.h b/components/sync_driver/sync_stopped_reporter.h deleted file mode 100644 index 0d527c8..0000000 --- a/components/sync_driver/sync_stopped_reporter.h +++ /dev/null
@@ -1,83 +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. - -#ifndef COMPONENTS_SYNC_DRIVER_SYNC_STOPPED_REPORTER_H_ -#define COMPONENTS_SYNC_DRIVER_SYNC_STOPPED_REPORTER_H_ - -#include <memory> -#include <string> - -#include "base/callback.h" -#include "base/macros.h" -#include "base/timer/timer.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" -#include "url/gurl.h" - -namespace browser_sync { - -// Manages informing the sync server that sync has been disabled. -// An implementation of URLFetcherDelegate was needed in order to -// clean up the fetcher_ pointer when the request completes. -class SyncStoppedReporter : public net::URLFetcherDelegate { - public: - enum Result { - RESULT_SUCCESS, - RESULT_ERROR, - RESULT_TIMEOUT - }; - - typedef base::Callback<void(const Result&)> ResultCallback; - - SyncStoppedReporter(const GURL& sync_service_url, - const std::string& user_agent, - const scoped_refptr<net::URLRequestContextGetter>& request_context, - const ResultCallback& callback); - ~SyncStoppedReporter() override; - - // Inform the sync server that sync was stopped on this device. - // |access_token|, |cache_guid|, and |birthday| must not be empty. - void ReportSyncStopped(const std::string& access_token, - const std::string& cache_guid, - const std::string& birthday); - - // net::URLFetcherDelegate implementation. - void OnURLFetchComplete(const net::URLFetcher* source) override; - - // Override the timer's task runner so it can be triggered in tests. - void SetTimerTaskRunnerForTest( - const scoped_refptr<base::SingleThreadTaskRunner>& task_runner); - - private: - // Convert the base sync URL into the sync event URL. - static GURL GetSyncEventURL(const GURL& sync_service_url); - - // Callback for a request timing out. - void OnTimeout(); - - // Handles timing out requests. - base::OneShotTimer timer_; - - // The URL for the sync server's event RPC. - const GURL sync_event_url_; - - // The user agent for the browser. - const std::string user_agent_; - - // Stored to simplify the API; needed for URLFetcher::Create(). - scoped_refptr<net::URLRequestContextGetter> request_context_; - - // The current URLFetcher. Null unless a request is in progress. - std::unique_ptr<net::URLFetcher> fetcher_; - - // A callback for request completion or timeout. - ResultCallback callback_; - - DISALLOW_COPY_AND_ASSIGN(SyncStoppedReporter); -}; - -} // namespace browser_sync - -#endif // COMPONENTS_SYNC_DRIVER_SYNC_STOPPED_REPORTER_H_
diff --git a/components/sync_driver/sync_stopped_reporter_unittest.cc b/components/sync_driver/sync_stopped_reporter_unittest.cc deleted file mode 100644 index 88a13b8..0000000 --- a/components/sync_driver/sync_stopped_reporter_unittest.cc +++ /dev/null
@@ -1,208 +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. - -#include "components/sync_driver/sync_stopped_reporter.h" - -#include <string> - -#include "base/macros.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/test/test_simple_task_runner.h" -#include "base/threading/non_thread_safe.h" -#include "components/sync/protocol/sync.pb.h" -#include "net/http/http_status_code.h" -#include "net/url_request/test_url_fetcher_factory.h" -#include "net/url_request/url_request_test_util.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -using browser_sync::SyncStoppedReporter; - -const char kTestURL[] = "http://chromium.org/test"; -const char kTestURLTrailingSlash[] = "http://chromium.org/test/"; -const char kEventURL[] = "http://chromium.org/test/event"; - -const char kTestUserAgent[] = "the_fifth_element"; -const char kAuthToken[] = "multipass"; -const char kCacheGuid[] = "leeloo"; -const char kBirthday[] = "2263"; - -const char kAuthHeaderPrefix[] = "Bearer "; - -class SyncStoppedReporterTest : public testing::Test { - public: - SyncStoppedReporterTest() {} - ~SyncStoppedReporterTest() override {} - - void SetUp() override { - request_context_ = new net::TestURLRequestContextGetter( - message_loop_.task_runner()); - } - - void RequestFinishedCallback(const SyncStoppedReporter::Result& result) { - request_result_ = result; - } - - GURL test_url() { - return GURL(kTestURL); - } - - std::string user_agent() const { - return std::string(kTestUserAgent); - } - - SyncStoppedReporter::ResultCallback callback() { - return base::Bind(&SyncStoppedReporterTest::RequestFinishedCallback, - base::Unretained(this)); - } - - const SyncStoppedReporter::Result& request_result() const { - return request_result_; - } - - net::URLRequestContextGetter* request_context() { - return request_context_.get(); - } - - private: - base::MessageLoop message_loop_; - scoped_refptr<net::URLRequestContextGetter> request_context_; - SyncStoppedReporter::Result request_result_; - - DISALLOW_COPY_AND_ASSIGN(SyncStoppedReporterTest); -}; - -// Test that the event URL gets constructed correctly. -TEST_F(SyncStoppedReporterTest, EventURL) { - net::TestURLFetcherFactory factory; - SyncStoppedReporter ssr(GURL(kTestURL), user_agent(), - request_context(), callback()); - ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); - net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); - EXPECT_EQ(kEventURL, fetcher->GetOriginalURL().spec()); -} - -// Test that the event URL gets constructed correctly with a trailing slash. -TEST_F(SyncStoppedReporterTest, EventURLWithSlash) { - net::TestURLFetcherFactory factory; - SyncStoppedReporter ssr(GURL(kTestURLTrailingSlash), user_agent(), - request_context(), callback()); - ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); - net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); - EXPECT_EQ(kEventURL, fetcher->GetOriginalURL().spec()); -} - -// Test that the URLFetcher gets configured correctly. -TEST_F(SyncStoppedReporterTest, FetcherConfiguration) { - net::TestURLFetcherFactory factory; - SyncStoppedReporter ssr(test_url(), user_agent(), - request_context(), callback()); - ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); - net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); - - // Ensure the headers are set correctly. - net::HttpRequestHeaders headers; - std::string header; - fetcher->GetExtraRequestHeaders(&headers); - headers.GetHeader(net::HttpRequestHeaders::kAuthorization, &header); - std::string auth_header(kAuthHeaderPrefix); - auth_header.append(kAuthToken); - EXPECT_EQ(auth_header, header); - headers.GetHeader(net::HttpRequestHeaders::kUserAgent, &header); - EXPECT_EQ(user_agent(), header); - - sync_pb::EventRequest event_request; - event_request.ParseFromString(fetcher->upload_data()); - - EXPECT_EQ(kCacheGuid, event_request.sync_disabled().cache_guid()); - EXPECT_EQ(kBirthday, event_request.sync_disabled().store_birthday()); - EXPECT_EQ(kEventURL, fetcher->GetOriginalURL().spec()); -} - -TEST_F(SyncStoppedReporterTest, HappyCase) { - net::TestURLFetcherFactory factory; - SyncStoppedReporter ssr(test_url(), user_agent(), - request_context(), callback()); - ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); - net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); - fetcher->set_response_code(net::HTTP_OK); - ssr.OnURLFetchComplete(fetcher); - base::RunLoop run_loop; - run_loop.RunUntilIdle(); - EXPECT_EQ(SyncStoppedReporter::RESULT_SUCCESS, request_result()); -} - -TEST_F(SyncStoppedReporterTest, ServerNotFound) { - net::TestURLFetcherFactory factory; - SyncStoppedReporter ssr(test_url(), user_agent(), - request_context(), callback()); - ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); - net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); - fetcher->set_response_code(net::HTTP_NOT_FOUND); - ssr.OnURLFetchComplete(fetcher); - base::RunLoop run_loop; - run_loop.RunUntilIdle(); - EXPECT_EQ(SyncStoppedReporter::RESULT_ERROR, request_result()); -} - -TEST_F(SyncStoppedReporterTest, DestructionDuringRequestHandler) { - net::TestURLFetcherFactory factory; - factory.set_remove_fetcher_on_delete(true); - { - SyncStoppedReporter ssr(test_url(), user_agent(), - request_context(), callback()); - ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); - EXPECT_FALSE(factory.GetFetcherByID(0) == nullptr); - } - EXPECT_TRUE(factory.GetFetcherByID(0) == nullptr); -} - -TEST_F(SyncStoppedReporterTest, Timeout) { - SyncStoppedReporter ssr(test_url(), user_agent(), - request_context(), callback()); - - // A task runner that can trigger the timeout immediately. - scoped_refptr<base::TestSimpleTaskRunner> task_runner( - new base::TestSimpleTaskRunner()); - ssr.SetTimerTaskRunnerForTest(task_runner); - - // Begin request. - ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); - - // Trigger the timeout. - ASSERT_TRUE(task_runner->HasPendingTask()); - task_runner->RunPendingTasks(); - - base::RunLoop run_loop; - run_loop.RunUntilIdle(); - EXPECT_EQ(SyncStoppedReporter::RESULT_TIMEOUT, request_result()); -} - -TEST_F(SyncStoppedReporterTest, NoCallback) { - net::TestURLFetcherFactory factory; - SyncStoppedReporter ssr(GURL(kTestURL), user_agent(), request_context(), - SyncStoppedReporter::ResultCallback()); - ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); - net::TestURLFetcher* fetcher = factory.GetFetcherByID(0); - fetcher->set_response_code(net::HTTP_OK); - ssr.OnURLFetchComplete(fetcher); -} - -TEST_F(SyncStoppedReporterTest, NoCallbackTimeout) { - SyncStoppedReporter ssr(GURL(kTestURL), user_agent(), request_context(), - SyncStoppedReporter::ResultCallback()); - - // A task runner that can trigger the timeout immediately. - scoped_refptr<base::TestSimpleTaskRunner> task_runner( - new base::TestSimpleTaskRunner()); - ssr.SetTimerTaskRunnerForTest(task_runner); - - // Begin request. - ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday); - - // Trigger the timeout. - ASSERT_TRUE(task_runner->HasPendingTask()); - task_runner->RunPendingTasks(); -}
diff --git a/components/sync_driver/sync_util.cc b/components/sync_driver/sync_util.cc deleted file mode 100644 index 29606df..0000000 --- a/components/sync_driver/sync_util.cc +++ /dev/null
@@ -1,106 +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. - -#include "components/sync_driver/sync_util.h" - -#include "base/command_line.h" -#include "base/logging.h" -#include "build/build_config.h" -#include "components/sync_driver/sync_driver_switches.h" -#include "url/gurl.h" - -namespace { - -// Returns string that represents system in UserAgent. -std::string GetSystemString(bool is_tablet) { - std::string system; -#if defined(OS_CHROMEOS) - system = "CROS "; -#elif defined(OS_ANDROID) - if (is_tablet) { - system = "ANDROID-TABLET "; - } else { - system = "ANDROID-PHONE "; - } -#elif defined(OS_IOS) - if (is_tablet) { - system = "IOS-TABLET "; - } else { - system = "IOS-PHONE "; - } -#elif defined(OS_WIN) - system = "WIN "; -#elif defined(OS_LINUX) - system = "LINUX "; -#elif defined(OS_FREEBSD) - system = "FREEBSD "; -#elif defined(OS_OPENBSD) - system = "OPENBSD "; -#elif defined(OS_MACOSX) - system = "MAC "; -#endif - return system; -} - -} // namespace - -namespace internal { - -const char* kSyncServerUrl = "https://clients4.google.com/chrome-sync"; - -const char* kSyncDevServerUrl = "https://clients4.google.com/chrome-sync/dev"; - -std::string FormatUserAgentForSync(const std::string& system, - version_info::Channel channel) { - std::string user_agent; - user_agent = "Chrome "; - user_agent += system; - user_agent += version_info::GetVersionNumber(); - user_agent += " (" + version_info::GetLastChange() + ")"; - if (!version_info::IsOfficialBuild()) { - user_agent += "-devel"; - } else { - user_agent += " channel(" + version_info::GetChannelString(channel) + ")"; - } - return user_agent; -} - -} // namespace internal - -GURL GetSyncServiceURL(const base::CommandLine& command_line, - version_info::Channel channel) { - // By default, dev, canary, and unbranded Chromium users will go to the - // development servers. Development servers have more features than standard - // sync servers. Users with officially-branded Chrome stable and beta builds - // will go to the standard sync servers. - GURL result(internal::kSyncDevServerUrl); - - if (channel == version_info::Channel::STABLE || - channel == version_info::Channel::BETA) { - result = GURL(internal::kSyncServerUrl); - } - - // Override the sync server URL from the command-line, if sync server - // command-line argument exists. - if (command_line.HasSwitch(switches::kSyncServiceURL)) { - std::string value( - command_line.GetSwitchValueASCII(switches::kSyncServiceURL)); - if (!value.empty()) { - GURL custom_sync_url(value); - if (custom_sync_url.is_valid()) { - result = custom_sync_url; - } else { - LOG(WARNING) << "The following sync URL specified at the command-line " - << "is invalid: " << value; - } - } - } - return result; -} - -std::string MakeUserAgentForSync(version_info::Channel channel, - bool is_tablet) { - std::string system = GetSystemString(is_tablet); - return internal::FormatUserAgentForSync(system, channel); -}
diff --git a/components/sync_driver/sync_util_unittest.cc b/components/sync_driver/sync_util_unittest.cc deleted file mode 100644 index eb58f1b7..0000000 --- a/components/sync_driver/sync_util_unittest.cc +++ /dev/null
@@ -1,51 +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. - -#include "components/sync_driver/sync_util.h" - -#include "base/command_line.h" -#include "base/strings/string_util.h" -#include "components/sync_driver/sync_driver_switches.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -namespace { - -TEST(SyncUtilTest, GetSyncServiceURLWithoutCommandLineSwitch) { - // If the command line is not set the url is one of two constants chosen based - // on the channel (e.g. beta). - base::CommandLine command_line(base::CommandLine::NO_PROGRAM); - std::string url = - GetSyncServiceURL(command_line, version_info::Channel::BETA).spec(); - ASSERT_TRUE(internal::kSyncServerUrl == url || - internal::kSyncDevServerUrl == url); -} - -TEST(SyncUtilTest, GetSyncServiceURLWithCommandLineSwitch) { - // See that we can set the URL via the command line. - base::CommandLine command_line(base::CommandLine::NO_PROGRAM); - command_line.AppendSwitchASCII(switches::kSyncServiceURL, "https://foo/bar"); - ASSERT_EQ( - "https://foo/bar", - GetSyncServiceURL(command_line, version_info::Channel::UNKNOWN).spec()); -} - -TEST(SyncUtilTest, GetSyncServiceURLWithBadCommandLineSwitch) { - // If the command line value is not a valid url it is ignored. - base::CommandLine command_line(base::CommandLine::NO_PROGRAM); - command_line.AppendSwitchASCII(switches::kSyncServiceURL, "invalid_url"); - std::string url = - GetSyncServiceURL(command_line, version_info::Channel::UNKNOWN).spec(); - ASSERT_TRUE(internal::kSyncServerUrl == url || - internal::kSyncDevServerUrl == url); -} - -TEST(SyncUtilTest, FormatUserAgentForSync) { - std::string user_agent = - internal::FormatUserAgentForSync("TEST", version_info::Channel::UNKNOWN); - ASSERT_TRUE(base::StartsWith(user_agent, "Chrome TEST", - base::CompareCase::SENSITIVE)); -} - -} // namespace
diff --git a/components/sync_driver/system_encryptor.cc b/components/sync_driver/system_encryptor.cc deleted file mode 100644 index 083227f..0000000 --- a/components/sync_driver/system_encryptor.cc +++ /dev/null
@@ -1,23 +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 "components/sync_driver/system_encryptor.h" - -#include "components/os_crypt/os_crypt.h" - -namespace sync_driver { - -SystemEncryptor::~SystemEncryptor() {} - -bool SystemEncryptor::EncryptString(const std::string& plaintext, - std::string* ciphertext) { - return ::OSCrypt::EncryptString(plaintext, ciphertext); -} - -bool SystemEncryptor::DecryptString(const std::string& ciphertext, - std::string* plaintext) { - return ::OSCrypt::DecryptString(ciphertext, plaintext); -} - -} // namespace sync_driver
diff --git a/components/sync_driver/system_encryptor_unittest.cc b/components/sync_driver/system_encryptor_unittest.cc deleted file mode 100644 index bc4d7670..0000000 --- a/components/sync_driver/system_encryptor_unittest.cc +++ /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. - -#include "components/sync_driver/system_encryptor.h" - -#include <string> - -#include "build/build_config.h" -#include "components/os_crypt/os_crypt_mocker.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sync_driver { - -namespace { - -const char kPlaintext[] = "The Magic Words are Squeamish Ossifrage"; - -class SystemEncryptorTest : public testing::Test { - protected: - SystemEncryptor encryptor_; -}; - -TEST_F(SystemEncryptorTest, EncryptDecrypt) { - // SystemEncryptor ends up needing access to the keychain on OS X, - // so use the mock keychain to prevent prompts. - ::OSCryptMocker::SetUpWithSingleton(); - std::string ciphertext; - EXPECT_TRUE(encryptor_.EncryptString(kPlaintext, &ciphertext)); - EXPECT_NE(kPlaintext, ciphertext); - std::string plaintext; - EXPECT_TRUE(encryptor_.DecryptString(ciphertext, &plaintext)); - EXPECT_EQ(kPlaintext, plaintext); - ::OSCryptMocker::TearDown(); -} - -} // namespace - -} // namespace sync_driver
diff --git a/components/sync_driver/ui_data_type_controller.cc b/components/sync_driver/ui_data_type_controller.cc deleted file mode 100644 index 89a4317..0000000 --- a/components/sync_driver/ui_data_type_controller.cc +++ /dev/null
@@ -1,395 +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 "components/sync_driver/ui_data_type_controller.h" - -#include <utility> - -#include "base/location.h" -#include "base/logging.h" -#include "base/memory/weak_ptr.h" -#include "base/profiler/scoped_tracker.h" -#include "base/single_thread_task_runner.h" -#include "base/threading/thread_task_runner_handle.h" -#include "components/sync/api/sync_error.h" -#include "components/sync/api/sync_merge_result.h" -#include "components/sync/api/syncable_service.h" -#include "components/sync/base/data_type_histogram.h" -#include "components/sync/base/model_type.h" -#include "components/sync_driver/generic_change_processor_factory.h" -#include "components/sync_driver/shared_change_processor_ref.h" -#include "components/sync_driver/sync_client.h" -#include "components/sync_driver/sync_service.h" - -namespace sync_driver { - -UIDataTypeController::UIDataTypeController() - : DirectoryDataTypeController(base::ThreadTaskRunnerHandle::Get(), - base::Closure()), - sync_client_(NULL), - state_(NOT_RUNNING), - type_(syncer::UNSPECIFIED) {} - -UIDataTypeController::UIDataTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const base::Closure& error_callback, - syncer::ModelType type, - SyncClient* sync_client) - : DirectoryDataTypeController(ui_thread, error_callback), - sync_client_(sync_client), - state_(NOT_RUNNING), - type_(type), - processor_factory_(new GenericChangeProcessorFactory()), - ui_thread_(ui_thread) { - DCHECK(ui_thread_->BelongsToCurrentThread()); - DCHECK(syncer::IsRealDataType(type_)); -} - -void UIDataTypeController::SetGenericChangeProcessorFactoryForTest( - std::unique_ptr<GenericChangeProcessorFactory> factory) { - DCHECK_EQ(state_, NOT_RUNNING); - processor_factory_ = std::move(factory); -} - -UIDataTypeController::~UIDataTypeController() { - DCHECK(ui_thread_->BelongsToCurrentThread()); -} - -void UIDataTypeController::LoadModels( - const ModelLoadCallback& model_load_callback) { - DCHECK(ui_thread_->BelongsToCurrentThread()); - DCHECK(syncer::IsRealDataType(type_)); - model_load_callback_ = model_load_callback; - if (state_ != NOT_RUNNING) { - model_load_callback.Run(type(), - syncer::SyncError(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Model already loaded", - type())); - return; - } - // Since we can't be called multiple times before Stop() is called, - // |shared_change_processor_| must be NULL here. - DCHECK(!shared_change_processor_.get()); - shared_change_processor_ = new SharedChangeProcessor(); - - state_ = MODEL_STARTING; - if (!StartModels()) { - // If we are waiting for some external service to load before associating - // or we failed to start the models, we exit early. state_ will control - // what we perform next. - DCHECK(state_ == NOT_RUNNING || state_ == MODEL_STARTING); - return; - } - - state_ = MODEL_LOADED; - model_load_callback_.Run(type(), syncer::SyncError()); -} - -void UIDataTypeController::OnModelLoaded() { - DCHECK(ui_thread_->BelongsToCurrentThread()); - DCHECK_EQ(state_, MODEL_STARTING); - - state_ = MODEL_LOADED; - model_load_callback_.Run(type(), syncer::SyncError()); -} - -void UIDataTypeController::StartAssociating( - const StartCallback& start_callback) { - DCHECK(ui_thread_->BelongsToCurrentThread()); - DCHECK(!start_callback.is_null()); - DCHECK_EQ(state_, MODEL_LOADED); - - start_callback_ = start_callback; - state_ = ASSOCIATING; - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&UIDataTypeController::Associate, this)); -} - -bool UIDataTypeController::StartModels() { - DCHECK_EQ(state_, MODEL_STARTING); - // By default, no additional services need to be started before we can proceed - // with model association. - return true; -} - -void UIDataTypeController::Associate() { - if (state_ != ASSOCIATING) { - // Stop() must have been called while Associate() task have been waiting. - DCHECK_EQ(state_, NOT_RUNNING); - return; - } - - syncer::SyncMergeResult local_merge_result(type()); - syncer::SyncMergeResult syncer_merge_result(type()); - base::WeakPtrFactory<syncer::SyncMergeResult> weak_ptr_factory( - &syncer_merge_result); - - // TODO(robliao): Remove ScopedTracker below once https://crbug.com/471403 is - // fixed. - tracked_objects::ScopedTracker tracking_profile1( - FROM_HERE_WITH_EXPLICIT_FUNCTION( - "471403 UIDataTypeController::Associate1")); - - // Connect |shared_change_processor_| to the syncer and get the - // syncer::SyncableService associated with type(). - DCHECK(sync_client_->GetSyncService()); - local_service_ = shared_change_processor_->Connect( - sync_client_, processor_factory_.get(), - sync_client_->GetSyncService()->GetUserShare(), this, type(), - weak_ptr_factory.GetWeakPtr()); - if (!local_service_.get()) { - syncer::SyncError error(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Failed to connect to syncer.", - type()); - local_merge_result.set_error(error); - StartDone(ASSOCIATION_FAILED, - local_merge_result, - syncer_merge_result); - return; - } - - // TODO(robliao): Remove ScopedTracker below once https://crbug.com/471403 is - // fixed. - tracked_objects::ScopedTracker tracking_profile2( - FROM_HERE_WITH_EXPLICIT_FUNCTION( - "471403 UIDataTypeController::Associate2")); - if (!shared_change_processor_->CryptoReadyIfNecessary()) { - syncer::SyncError error(FROM_HERE, - syncer::SyncError::CRYPTO_ERROR, - "", - type()); - local_merge_result.set_error(error); - StartDone(NEEDS_CRYPTO, - local_merge_result, - syncer_merge_result); - return; - } - - // TODO(robliao): Remove ScopedTracker below once https://crbug.com/471403 is - // fixed. - tracked_objects::ScopedTracker tracking_profile3( - FROM_HERE_WITH_EXPLICIT_FUNCTION( - "471403 UIDataTypeController::Associate3")); - bool sync_has_nodes = false; - if (!shared_change_processor_->SyncModelHasUserCreatedNodes( - &sync_has_nodes)) { - syncer::SyncError error(FROM_HERE, - syncer::SyncError::UNRECOVERABLE_ERROR, - "Failed to load sync nodes", - type()); - local_merge_result.set_error(error); - StartDone(UNRECOVERABLE_ERROR, - local_merge_result, - syncer_merge_result); - return; - } - - // Scope for |initial_sync_data| which might be expensive, so we don't want - // to keep it in memory longer than necessary. - { - syncer::SyncDataList initial_sync_data; - - // TODO(robliao): Remove ScopedTracker below once https://crbug.com/471403 - // is fixed. - tracked_objects::ScopedTracker tracking_profile4( - FROM_HERE_WITH_EXPLICIT_FUNCTION( - "471403 UIDataTypeController::Associate4")); - base::TimeTicks start_time = base::TimeTicks::Now(); - syncer::SyncError error = - shared_change_processor_->GetAllSyncDataReturnError(type(), - &initial_sync_data); - if (error.IsSet()) { - local_merge_result.set_error(error); - StartDone(ASSOCIATION_FAILED, local_merge_result, syncer_merge_result); - return; - } - - // TODO(robliao): Remove ScopedTracker below once https://crbug.com/471403 - // is fixed. - tracked_objects::ScopedTracker tracking_profile5( - FROM_HERE_WITH_EXPLICIT_FUNCTION( - "471403 UIDataTypeController::Associate5")); - std::string datatype_context; - if (shared_change_processor_->GetDataTypeContext(&datatype_context)) { - local_service_->UpdateDataTypeContext( - type(), syncer::SyncChangeProcessor::NO_REFRESH, datatype_context); - } - - // TODO(robliao): Remove ScopedTracker below once https://crbug.com/471403 - // is fixed. - tracked_objects::ScopedTracker tracking_profile6( - FROM_HERE_WITH_EXPLICIT_FUNCTION( - "471403 UIDataTypeController::Associate6")); - syncer_merge_result.set_num_items_before_association( - initial_sync_data.size()); - // Passes a reference to |shared_change_processor_|. - local_merge_result = local_service_->MergeDataAndStartSyncing( - type(), initial_sync_data, - std::unique_ptr<syncer::SyncChangeProcessor>( - new SharedChangeProcessorRef(shared_change_processor_)), - std::unique_ptr<syncer::SyncErrorFactory>( - new SharedChangeProcessorRef(shared_change_processor_))); - RecordAssociationTime(base::TimeTicks::Now() - start_time); - if (local_merge_result.error().IsSet()) { - StartDone(ASSOCIATION_FAILED, local_merge_result, syncer_merge_result); - return; - } - } - - // TODO(robliao): Remove ScopedTracker below once https://crbug.com/471403 is - // fixed. - tracked_objects::ScopedTracker tracking_profile7( - FROM_HERE_WITH_EXPLICIT_FUNCTION( - "471403 UIDataTypeController::Associate7")); - syncer_merge_result.set_num_items_after_association( - shared_change_processor_->GetSyncCount()); - - state_ = RUNNING; - StartDone(sync_has_nodes ? OK : OK_FIRST_RUN, - local_merge_result, - syncer_merge_result); -} - -ChangeProcessor* UIDataTypeController::GetChangeProcessor() const { - DCHECK_EQ(state_, RUNNING); - return shared_change_processor_->generic_change_processor(); -} - -void UIDataTypeController::AbortModelLoad() { - DCHECK(ui_thread_->BelongsToCurrentThread()); - state_ = NOT_RUNNING; - - if (shared_change_processor_.get()) { - shared_change_processor_ = NULL; - } - - // We don't want to continue loading models (e.g OnModelLoaded should never be - // called after we've decided to abort). - StopModels(); -} - -void UIDataTypeController::StartDone( - ConfigureResult start_result, - const syncer::SyncMergeResult& local_merge_result, - const syncer::SyncMergeResult& syncer_merge_result) { - DCHECK(ui_thread_->BelongsToCurrentThread()); - - // TODO(robliao): Remove ScopedTracker below once https://crbug.com/471403 is - // fixed. - tracked_objects::ScopedTracker tracking_profile( - FROM_HERE_WITH_EXPLICIT_FUNCTION( - "471403 UIDataTypeController::StartDone")); - - if (!IsSuccessfulResult(start_result)) { - StopModels(); - if (start_result == ASSOCIATION_FAILED) { - state_ = DISABLED; - } else { - state_ = NOT_RUNNING; - } - RecordStartFailure(start_result); - - if (shared_change_processor_.get()) { - shared_change_processor_->Disconnect(); - shared_change_processor_ = NULL; - } - } - - start_callback_.Run(start_result, local_merge_result, syncer_merge_result); -} - -void UIDataTypeController::Stop() { - DCHECK(ui_thread_->BelongsToCurrentThread()); - DCHECK(syncer::IsRealDataType(type_)); - - if (state_ == NOT_RUNNING) - return; - - State prev_state = state_; - state_ = STOPPING; - - if (shared_change_processor_.get()) { - shared_change_processor_->Disconnect(); - shared_change_processor_ = NULL; - } - - // If Stop() is called while Start() is waiting for the datatype model to - // load, abort the start. - if (prev_state == MODEL_STARTING) { - AbortModelLoad(); - // We can just return here since we haven't performed association if we're - // still in MODEL_STARTING. - return; - } - - StopModels(); - - if (local_service_.get()) { - local_service_->StopSyncing(type()); - } - - state_ = NOT_RUNNING; -} - -syncer::ModelType UIDataTypeController::type() const { - DCHECK(syncer::IsRealDataType(type_)); - return type_; -} - -void UIDataTypeController::StopModels() { - // Do nothing by default. -} - -syncer::ModelSafeGroup UIDataTypeController::model_safe_group() const { - DCHECK(syncer::IsRealDataType(type_)); - return syncer::GROUP_UI; -} - -std::string UIDataTypeController::name() const { - // For logging only. - return syncer::ModelTypeToString(type()); -} - -DataTypeController::State UIDataTypeController::state() const { - return state_; -} - -void UIDataTypeController::OnSingleDataTypeUnrecoverableError( - const syncer::SyncError& error) { - DCHECK_EQ(type(), error.model_type()); - UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeRunFailures", - ModelTypeToHistogramInt(type()), - syncer::MODEL_TYPE_COUNT); - // TODO(tim): We double-upload some errors. See bug 383480. - if (!error_callback_.is_null()) - error_callback_.Run(); - if (!model_load_callback_.is_null()) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(model_load_callback_, type(), error)); - } -} - -void UIDataTypeController::RecordAssociationTime(base::TimeDelta time) { - DCHECK(ui_thread_->BelongsToCurrentThread()); -#define PER_DATA_TYPE_MACRO(type_str) \ - UMA_HISTOGRAM_TIMES("Sync." type_str "AssociationTime", time); - SYNC_DATA_TYPE_HISTOGRAM(type()); -#undef PER_DATA_TYPE_MACRO -} - -void UIDataTypeController::RecordStartFailure(ConfigureResult result) { - DCHECK(ui_thread_->BelongsToCurrentThread()); - UMA_HISTOGRAM_ENUMERATION("Sync.DataTypeStartFailures", - ModelTypeToHistogramInt(type()), - syncer::MODEL_TYPE_COUNT); -#define PER_DATA_TYPE_MACRO(type_str) \ - UMA_HISTOGRAM_ENUMERATION("Sync." type_str "ConfigureFailure", result, \ - MAX_CONFIGURE_RESULT); - SYNC_DATA_TYPE_HISTOGRAM(type()); -#undef PER_DATA_TYPE_MACRO -} - -} // namespace sync_driver
diff --git a/components/sync_driver/ui_data_type_controller.h b/components/sync_driver/ui_data_type_controller.h deleted file mode 100644 index 130b851..0000000 --- a/components/sync_driver/ui_data_type_controller.h +++ /dev/null
@@ -1,140 +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 COMPONENTS_SYNC_DRIVER_UI_DATA_TYPE_CONTROLLER_H_ -#define COMPONENTS_SYNC_DRIVER_UI_DATA_TYPE_CONTROLLER_H_ - -#include <memory> -#include <string> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "components/sync_driver/directory_data_type_controller.h" -#include "components/sync_driver/shared_change_processor.h" - -namespace base { -class TimeDelta; -} - -namespace syncer { -class SyncableService; -class SyncClient; -class SyncError; -} - -namespace sync_driver { - -// Implementation for datatypes that reside on the (UI thread). This is the same -// thread we perform initialization on, so we don't have to worry about thread -// safety. The main start/stop funtionality is implemented by default. -// Note: RefCountedThreadSafe by way of DataTypeController. -class UIDataTypeController : public DirectoryDataTypeController { - public: - UIDataTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const base::Closure& error_callback, - syncer::ModelType type, - SyncClient* sync_client); - - // DataTypeController interface. - void LoadModels(const ModelLoadCallback& model_load_callback) override; - void StartAssociating(const StartCallback& start_callback) override; - void Stop() override; - syncer::ModelType type() const override; - syncer::ModelSafeGroup model_safe_group() const override; - ChangeProcessor* GetChangeProcessor() const override; - std::string name() const override; - State state() const override; - - // DataTypeErrorHandler interface. - void OnSingleDataTypeUnrecoverableError( - const syncer::SyncError& error) override; - - // Used by tests to override the factory used to create - // GenericChangeProcessors. - void SetGenericChangeProcessorFactoryForTest( - std::unique_ptr<GenericChangeProcessorFactory> factory); - - protected: - // For testing only. - UIDataTypeController(); - // DataTypeController is RefCounted. - ~UIDataTypeController() override; - - // Start any dependent services that need to be running before we can - // associate models. The default implementation is a no-op. - // Return value: - // True - if models are ready and association can proceed. - // False - if models are not ready. OnModelLoaded() should be called when - // the models are ready. - virtual bool StartModels(); - - // Perform any DataType controller specific state cleanup before stopping - // the datatype controller. The default implementation is a no-op. - virtual void StopModels(); - - // Helper method for cleaning up state and invoking the start callback. - virtual void StartDone(ConfigureResult result, - const syncer::SyncMergeResult& local_merge_result, - const syncer::SyncMergeResult& syncer_merge_result); - - // Record association time. - virtual void RecordAssociationTime(base::TimeDelta time); - // Record causes of start failure. - virtual void RecordStartFailure(ConfigureResult result); - - // If the DTC is waiting for models to load, once the models are - // loaded the datatype service will call this function on DTC to let - // us know that it is safe to start associating. - void OnModelLoaded(); - - SyncClient* const sync_client_; - - State state_; - - StartCallback start_callback_; - ModelLoadCallback model_load_callback_; - - // The sync datatype being controlled. - syncer::ModelType type_; - - // Sync's interface to the datatype. All sync changes for |type_| are pushed - // through it to the datatype as well as vice versa. - // - // Lifetime: it gets created when Start()) is called, and a reference to it - // is passed to |local_service_| during Associate(). We release our reference - // when Stop() or StartFailed() is called, and |local_service_| releases its - // reference when local_service_->StopSyncing() is called or when it is - // destroyed. - // - // Note: we use refcounting here primarily so that we can keep a uniform - // SyncableService API, whether the datatype lives on the UI thread or not - // (a syncer::SyncableService takes ownership of its SyncChangeProcessor when - // MergeDataAndStartSyncing is called). This will help us eventually merge the - // two datatype controller implementations (for ui and non-ui thread - // datatypes). - scoped_refptr<SharedChangeProcessor> shared_change_processor_; - - std::unique_ptr<GenericChangeProcessorFactory> processor_factory_; - - // A weak pointer to the actual local syncable service, which performs all the - // real work. We do not own the object. - base::WeakPtr<syncer::SyncableService> local_service_; - - scoped_refptr<base::SingleThreadTaskRunner> ui_thread_; - - private: - // Associate the sync model with the service's model, then start syncing. - virtual void Associate(); - - virtual void AbortModelLoad(); - - DISALLOW_COPY_AND_ASSIGN(UIDataTypeController); -}; - -} // namespace sync_driver - -#endif // COMPONENTS_SYNC_DRIVER_UI_DATA_TYPE_CONTROLLER_H_
diff --git a/components/sync_driver/ui_data_type_controller_unittest.cc b/components/sync_driver/ui_data_type_controller_unittest.cc deleted file mode 100644 index 98df18a8..0000000 --- a/components/sync_driver/ui_data_type_controller_unittest.cc +++ /dev/null
@@ -1,209 +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 "components/sync_driver/ui_data_type_controller.h" - -#include <memory> -#include <utility> - -#include "base/bind.h" -#include "base/location.h" -#include "base/single_thread_task_runner.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/tracked_objects.h" -#include "components/sync/api/fake_syncable_service.h" -#include "components/sync/base/model_type.h" -#include "components/sync_driver/data_type_controller_mock.h" -#include "components/sync_driver/fake_generic_change_processor.h" -#include "components/sync_driver/fake_sync_client.h" -#include "testing/gtest/include/gtest/gtest.h" - -using testing::_; -using testing::Invoke; -using testing::InvokeWithoutArgs; -using testing::Return; - -namespace sync_driver { -namespace { - -// TODO(zea): Expand this to make the dtc type paramterizable. This will let us -// test the basic functionality of all UIDataTypeControllers. We'll need to have -// intelligent default values for the methods queried in the dependent services -// (e.g. those queried in StartModels). -class SyncUIDataTypeControllerTest : public testing::Test, - public FakeSyncClient { - public: - SyncUIDataTypeControllerTest() - : type_(syncer::PREFERENCES), - change_processor_(NULL) {} - - // FakeSyncClient overrides. - base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType( - syncer::ModelType type) override { - return syncable_service_.AsWeakPtr(); - } - - void SetUp() override { - preference_dtc_ = - new UIDataTypeController(base::ThreadTaskRunnerHandle::Get(), - base::Closure(), type_, this); - SetStartExpectations(); - } - - void TearDown() override { - // Must be done before we pump the loop. - syncable_service_.StopSyncing(type_); - preference_dtc_ = NULL; - PumpLoop(); - } - - protected: - void SetStartExpectations() { - std::unique_ptr<FakeGenericChangeProcessor> p( - new FakeGenericChangeProcessor(type_, this)); - change_processor_ = p.get(); - std::unique_ptr<GenericChangeProcessorFactory> f( - new FakeGenericChangeProcessorFactory(std::move(p))); - preference_dtc_->SetGenericChangeProcessorFactoryForTest(std::move(f)); - EXPECT_CALL(model_load_callback_, Run(_, _)); - } - - void Start() { - preference_dtc_->LoadModels( - base::Bind(&ModelLoadCallbackMock::Run, - base::Unretained(&model_load_callback_))); - preference_dtc_->StartAssociating( - base::Bind(&StartCallbackMock::Run, - base::Unretained(&start_callback_))); - PumpLoop(); - } - - void PumpLoop() { - message_loop_.RunUntilIdle(); - } - - base::MessageLoopForUI message_loop_; - const syncer::ModelType type_; - StartCallbackMock start_callback_; - ModelLoadCallbackMock model_load_callback_; - scoped_refptr<UIDataTypeController> preference_dtc_; - FakeGenericChangeProcessor* change_processor_; - syncer::FakeSyncableService syncable_service_; -}; - -// Start the DTC. Verify that the callback is called with OK, the -// service has been told to start syncing and that the DTC is now in RUNNING -// state. -TEST_F(SyncUIDataTypeControllerTest, Start) { - EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _)); - - EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); - EXPECT_FALSE(syncable_service_.syncing()); - Start(); - EXPECT_EQ(DataTypeController::RUNNING, preference_dtc_->state()); - EXPECT_TRUE(syncable_service_.syncing()); -} - -// Start and then stop the DTC. Verify that the service started and stopped -// syncing, and that the DTC went from RUNNING to NOT_RUNNING. -TEST_F(SyncUIDataTypeControllerTest, StartStop) { - EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _)); - - EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); - EXPECT_FALSE(syncable_service_.syncing()); - Start(); - EXPECT_EQ(DataTypeController::RUNNING, preference_dtc_->state()); - EXPECT_TRUE(syncable_service_.syncing()); - preference_dtc_->Stop(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); - EXPECT_FALSE(syncable_service_.syncing()); -} - -// Start and then stop the DTC before the Start had a chance to perform -// association. Verify that the service never started and is NOT_RUNNING. -TEST_F(SyncUIDataTypeControllerTest, StartStopBeforeAssociation) { - EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); - EXPECT_FALSE(syncable_service_.syncing()); - message_loop_.task_runner()->PostTask( - FROM_HERE, base::Bind(&UIDataTypeController::Stop, preference_dtc_)); - Start(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); - EXPECT_FALSE(syncable_service_.syncing()); -} - -// Start the DTC when no user nodes are created. Verify that the callback -// is called with OK_FIRST_RUN. Stop the DTC. -TEST_F(SyncUIDataTypeControllerTest, StartStopFirstRun) { - EXPECT_CALL(start_callback_, Run(DataTypeController::OK_FIRST_RUN, _, _)); - change_processor_->set_sync_model_has_user_created_nodes(false); - - EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); - EXPECT_FALSE(syncable_service_.syncing()); - Start(); - EXPECT_EQ(DataTypeController::RUNNING, preference_dtc_->state()); - EXPECT_TRUE(syncable_service_.syncing()); - preference_dtc_->Stop(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); - EXPECT_FALSE(syncable_service_.syncing()); -} - -// Start the DTC, but have the service fail association. Verify the callback -// is called with ASSOCIATION_FAILED, the DTC goes to state DISABLED, and the -// service is not syncing. Then stop the DTC. -TEST_F(SyncUIDataTypeControllerTest, StartAssociationFailed) { - EXPECT_CALL(start_callback_, - Run(DataTypeController::ASSOCIATION_FAILED, _, _)); - syncable_service_.set_merge_data_and_start_syncing_error( - syncer::SyncError(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Error", - type_)); - - EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); - EXPECT_FALSE(syncable_service_.syncing()); - Start(); - EXPECT_EQ(DataTypeController::DISABLED, preference_dtc_->state()); - EXPECT_FALSE(syncable_service_.syncing()); - preference_dtc_->Stop(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); - EXPECT_FALSE(syncable_service_.syncing()); -} - -// Start the DTC but fail to check if there are user created nodes. Verify the -// DTC calls the callback with UNRECOVERABLE_ERROR and that it goes into -// NOT_RUNNING state. Verify the syncable service is not syncing. -TEST_F(SyncUIDataTypeControllerTest, - StartAssociationTriggersUnrecoverableError) { - EXPECT_CALL(start_callback_, - Run(DataTypeController::UNRECOVERABLE_ERROR, _, _)); - change_processor_->set_sync_model_has_user_created_nodes_success(false); - - EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); - EXPECT_FALSE(syncable_service_.syncing()); - Start(); - EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); - EXPECT_FALSE(syncable_service_.syncing()); -} - -// Start the DTC, but then trigger an unrecoverable error. Verify the syncer -// gets stopped and the DTC is in NOT_RUNNING state. -TEST_F(SyncUIDataTypeControllerTest, OnSingleDatatypeUnrecoverableError) { - EXPECT_CALL(start_callback_, Run(DataTypeController::OK, _, _)); - - EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); - EXPECT_FALSE(syncable_service_.syncing()); - Start(); - EXPECT_TRUE(syncable_service_.syncing()); - - testing::Mock::VerifyAndClearExpectations(&start_callback_); - EXPECT_CALL(model_load_callback_, Run(_, _)); - syncer::SyncError error(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "error", - syncer::PREFERENCES); - preference_dtc_->OnSingleDataTypeUnrecoverableError(error); -} - -} // namespace -} // namespace sync_driver
diff --git a/components/sync_driver/ui_model_type_controller.cc b/components/sync_driver/ui_model_type_controller.cc deleted file mode 100644 index 8ce824a..0000000 --- a/components/sync_driver/ui_model_type_controller.cc +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2016 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/sync_driver/ui_model_type_controller.h" - -#include "components/sync/api/model_type_service.h" -#include "components/sync/base/model_type.h" -#include "components/sync/core/activation_context.h" -#include "components/sync_driver/sync_client.h" - -namespace sync_driver_v2 { - -using sync_driver::SyncClient; - -UIModelTypeController::UIModelTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const base::Closure& error_callback, - syncer::ModelType model_type, - SyncClient* sync_client) - : NonBlockingDataTypeController(ui_thread, - error_callback, - model_type, - sync_client) {} - -UIModelTypeController::~UIModelTypeController() {} - -bool UIModelTypeController::RunOnModelThread( - const tracked_objects::Location& from_here, - const base::Closure& task) { - RunOnUIThread(from_here, task); - return true; -} - -void UIModelTypeController::RunOnUIThread( - const tracked_objects::Location& from_here, - const base::Closure& task) { - DCHECK(BelongsToUIThread()); - task.Run(); -} - -} // namespace sync_driver_v2
diff --git a/components/sync_driver/ui_model_type_controller.h b/components/sync_driver/ui_model_type_controller.h deleted file mode 100644 index d064851..0000000 --- a/components/sync_driver/ui_model_type_controller.h +++ /dev/null
@@ -1,43 +0,0 @@ -// Copyright 2016 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_SYNC_DRIVER_UI_MODEL_TYPE_CONTROLLER_H_ -#define COMPONENTS_SYNC_DRIVER_UI_MODEL_TYPE_CONTROLLER_H_ - -#include "components/sync_driver/non_blocking_data_type_controller.h" - -namespace sync_driver { -class SyncClient; -} - -namespace sync_driver_v2 { - -// Implementation for Unified Sync and Storage datatypes that reside on the UI -// thread. -class UIModelTypeController : public NonBlockingDataTypeController { - public: - UIModelTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const base::Closure& error_callback, - syncer::ModelType model_type, - sync_driver::SyncClient* sync_client); - - protected: - ~UIModelTypeController() override; - - void RunOnUIThread(const tracked_objects::Location& from_here, - const base::Closure& task) override; - - private: - // NonBlockingDataTypeController implementations. - // Since this is UI model type controller, we hide this function here. - bool RunOnModelThread(const tracked_objects::Location& from_here, - const base::Closure& task) override; - - DISALLOW_COPY_AND_ASSIGN(UIModelTypeController); -}; - -} // namespace sync_driver_v2 - -#endif // COMPONENTS_SYNC_DRIVER_UI_MODEL_TYPE_CONTROLLER_H_
diff --git a/components/sync_driver/ui_model_type_controller_unittest.cc b/components/sync_driver/ui_model_type_controller_unittest.cc deleted file mode 100644 index 08e19f1..0000000 --- a/components/sync_driver/ui_model_type_controller_unittest.cc +++ /dev/null
@@ -1,292 +0,0 @@ -// Copyright 2016 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/sync_driver/ui_model_type_controller.h" - -#include "base/bind.h" -#include "base/callback.h" -#include "base/logging.h" -#include "base/memory/ptr_util.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/sequenced_task_runner.h" -#include "base/test/test_simple_task_runner.h" -#include "base/threading/thread.h" -#include "components/sync/api/fake_model_type_service.h" -#include "components/sync/core/activation_context.h" -#include "components/sync/core/shared_model_type_processor.h" -#include "components/sync/engine_impl/commit_queue.h" -#include "components/sync_driver/backend_data_type_configurer.h" -#include "components/sync_driver/fake_sync_client.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace sync_driver_v2 { - -namespace { - -// Test controller derived from UIModelTypeController. -class TestUIModelTypeController : public UIModelTypeController { - public: - TestUIModelTypeController( - const scoped_refptr<base::SingleThreadTaskRunner>& ui_thread, - const base::Closure& error_callback, - syncer::ModelType model_type, - sync_driver::SyncClient* sync_client) - : UIModelTypeController(ui_thread, - error_callback, - model_type, - sync_client) {} - - private: - ~TestUIModelTypeController() override {} -}; - -// A no-op instance of CommitQueue. -class NullCommitQueue : public syncer_v2::CommitQueue { - public: - NullCommitQueue() {} - ~NullCommitQueue() override {} - - void EnqueueForCommit(const syncer_v2::CommitRequestDataList& list) override { - NOTREACHED() << "Not implemented."; - } -}; - -// A class that pretends to be the sync backend. -class MockSyncBackend { - public: - void Connect( - syncer::ModelType type, - std::unique_ptr<syncer_v2::ActivationContext> activation_context) { - enabled_types_.Put(type); - activation_context->type_processor->ConnectSync( - base::WrapUnique(new NullCommitQueue())); - } - - void Disconnect(syncer::ModelType type) { - DCHECK(enabled_types_.Has(type)); - enabled_types_.Remove(type); - } - - private: - syncer::ModelTypeSet enabled_types_; -}; - -// Fake implementation of BackendDataTypeConfigurer that pretends to be Sync -// backend. -class MockBackendDataTypeConfigurer - : public sync_driver::BackendDataTypeConfigurer { - public: - MockBackendDataTypeConfigurer( - MockSyncBackend* backend, - const scoped_refptr<base::TaskRunner>& sync_task_runner) - : backend_(backend), sync_task_runner_(sync_task_runner) {} - ~MockBackendDataTypeConfigurer() override {} - - syncer::ModelTypeSet ConfigureDataTypes( - syncer::ConfigureReason reason, - const DataTypeConfigStateMap& config_state_map, - const base::Callback<void(syncer::ModelTypeSet, syncer::ModelTypeSet)>& - ready_task, - const base::Callback<void()>& retry_callback) override { - NOTREACHED() << "Not implemented."; - return syncer::ModelTypeSet(); - } - - void ActivateDirectoryDataType( - syncer::ModelType type, - syncer::ModelSafeGroup group, - sync_driver::ChangeProcessor* change_processor) override { - NOTREACHED() << "Not implemented."; - } - - void DeactivateDirectoryDataType(syncer::ModelType type) override { - NOTREACHED() << "Not implemented."; - } - - void ActivateNonBlockingDataType(syncer::ModelType type, - std::unique_ptr<syncer_v2::ActivationContext> - activation_context) override { - // Post on Sync thread just like the real implementation does. - sync_task_runner_->PostTask( - FROM_HERE, - base::Bind(&MockSyncBackend::Connect, base::Unretained(backend_), type, - base::Passed(std::move(activation_context)))); - } - - void DeactivateNonBlockingDataType(syncer::ModelType type) override { - sync_task_runner_->PostTask(FROM_HERE, - base::Bind(&MockSyncBackend::Disconnect, - base::Unretained(backend_), type)); - } - - private: - MockSyncBackend* backend_; - scoped_refptr<base::TaskRunner> sync_task_runner_; -}; - -} // namespace - -class UIModelTypeControllerTest : public testing::Test, - public sync_driver::FakeSyncClient { - public: - UIModelTypeControllerTest() - : auto_run_tasks_(true), - load_models_callback_called_(false), - association_callback_called_(false), - configurer_(&backend_, ui_loop_.task_runner()) {} - - ~UIModelTypeControllerTest() override {} - - void SetUp() override { - controller_ = new TestUIModelTypeController( - ui_loop_.task_runner(), base::Closure(), syncer::DEVICE_INFO, this); - service_.reset(new syncer_v2::FakeModelTypeService(base::Bind( - &UIModelTypeControllerTest::CreateProcessor, base::Unretained(this)))); - } - - void TearDown() override { - controller_ = NULL; - RunAllTasks(); - } - - syncer_v2::ModelTypeService* GetModelTypeServiceForType( - syncer::ModelType type) override { - return service_.get(); - } - - protected: - std::unique_ptr<syncer_v2::ModelTypeChangeProcessor> CreateProcessor( - syncer::ModelType type, - syncer_v2::ModelTypeService* service) { - std::unique_ptr<syncer_v2::SharedModelTypeProcessor> processor = - base::WrapUnique( - new syncer_v2::SharedModelTypeProcessor(type, service)); - type_processor_ = processor.get(); - return std::move(processor); - } - - void ExpectProcessorConnected(bool isConnected) { - DCHECK(type_processor_); - EXPECT_EQ(isConnected, type_processor_->IsConnected()); - } - - void LoadModels() { - controller_->LoadModels(base::Bind( - &UIModelTypeControllerTest::LoadModelsDone, base::Unretained(this))); - if (!type_processor_->IsAllowingChanges()) { - type_processor_->OnMetadataLoaded( - syncer::SyncError(), - base::WrapUnique(new syncer_v2::MetadataBatch())); - } - - if (auto_run_tasks_) { - RunAllTasks(); - } - } - - void RegisterWithBackend() { - controller_->RegisterWithBackend(&configurer_); - if (auto_run_tasks_) { - RunAllTasks(); - } - } - - void StartAssociating() { - controller_->StartAssociating(base::Bind( - &UIModelTypeControllerTest::AssociationDone, base::Unretained(this))); - // The callback is expected to be promptly called. - EXPECT_TRUE(association_callback_called_); - } - - void DeactivateDataTypeAndStop() { - controller_->DeactivateDataType(&configurer_); - controller_->Stop(); - if (auto_run_tasks_) { - RunAllTasks(); - } - } - - // These threads can ping-pong for a bit so we run the UI thread twice. - void RunAllTasks() { - base::RunLoop().RunUntilIdle(); - } - - void SetAutoRunTasks(bool auto_run_tasks) { - auto_run_tasks_ = auto_run_tasks; - } - - void LoadModelsDone(syncer::ModelType type, syncer::SyncError error) { - load_models_callback_called_ = true; - load_models_error_ = error; - } - - void AssociationDone(sync_driver::DataTypeController::ConfigureResult result, - const syncer::SyncMergeResult& local_merge_result, - const syncer::SyncMergeResult& syncer_merge_result) { - EXPECT_EQ(sync_driver::DataTypeController::OK, result); - association_callback_called_ = true; - } - - syncer_v2::SharedModelTypeProcessor* type_processor_; - scoped_refptr<TestUIModelTypeController> controller_; - - bool auto_run_tasks_; - bool load_models_callback_called_; - syncer::SyncError load_models_error_; - bool association_callback_called_; - base::MessageLoopForUI ui_loop_; - MockSyncBackend backend_; - MockBackendDataTypeConfigurer configurer_; - std::unique_ptr<syncer_v2::FakeModelTypeService> service_; -}; - -TEST_F(UIModelTypeControllerTest, InitialState) { - EXPECT_EQ(syncer::DEVICE_INFO, controller_->type()); - EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); -} - -TEST_F(UIModelTypeControllerTest, LoadModelsOnUIThread) { - LoadModels(); - EXPECT_EQ(sync_driver::DataTypeController::MODEL_LOADED, - controller_->state()); - EXPECT_TRUE(load_models_callback_called_); - EXPECT_FALSE(load_models_error_.IsSet()); - ExpectProcessorConnected(false); -} - -TEST_F(UIModelTypeControllerTest, LoadModelsTwice) { - LoadModels(); - SetAutoRunTasks(false); - LoadModels(); - EXPECT_EQ(sync_driver::DataTypeController::MODEL_LOADED, - controller_->state()); - // The second LoadModels call should set the error. - EXPECT_TRUE(load_models_error_.IsSet()); -} - -TEST_F(UIModelTypeControllerTest, ActivateDataTypeOnUIThread) { - LoadModels(); - EXPECT_EQ(sync_driver::DataTypeController::MODEL_LOADED, - controller_->state()); - RegisterWithBackend(); - ExpectProcessorConnected(true); - - StartAssociating(); - EXPECT_EQ(sync_driver::DataTypeController::RUNNING, controller_->state()); -} - -TEST_F(UIModelTypeControllerTest, Stop) { - LoadModels(); - RegisterWithBackend(); - ExpectProcessorConnected(true); - StartAssociating(); - - DeactivateDataTypeAndStop(); - EXPECT_EQ(sync_driver::DataTypeController::NOT_RUNNING, controller_->state()); -} - -} // namespace sync_driver_v2
diff --git a/components/sync_sessions.gypi b/components/sync_sessions.gypi index 4acf40d3..7b10786d 100644 --- a/components/sync_sessions.gypi +++ b/components/sync_sessions.gypi
@@ -18,7 +18,6 @@ 'bookmarks_browser', 'history_core_browser', 'prefs/prefs.gyp:prefs', - 'sync_driver', ], 'sources': [ # Note: sources list duplicated in GN build.
diff --git a/components/sync_sessions/BUILD.gn b/components/sync_sessions/BUILD.gn index b0219b3..1df87ff 100644 --- a/components/sync_sessions/BUILD.gn +++ b/components/sync_sessions/BUILD.gn
@@ -57,7 +57,6 @@ "//components/prefs", "//components/sessions", "//components/sync", - "//components/sync_driver", "//components/variations", "//ui/base:base", "//ui/gfx", @@ -107,8 +106,7 @@ "//components/sessions:test_support", "//components/sync", "//components/sync:test_support_sync_api", - "//components/sync_driver", - "//components/sync_driver:test_support", + "//components/sync:test_support_sync_driver", "//testing/gmock", "//testing/gtest", "//ui/base:base",
diff --git a/components/sync_sessions/DEPS b/components/sync_sessions/DEPS index 30aa1c15..564d4219 100644 --- a/components/sync_sessions/DEPS +++ b/components/sync_sessions/DEPS
@@ -5,7 +5,6 @@ "+components/prefs", "+components/sessions", "+components/sync", - "+components/sync_driver", "+components/variations", "+ui/base/page_transition_types.h", "+ui/gfx",
diff --git a/components/sync_sessions/session_data_type_controller.cc b/components/sync_sessions/session_data_type_controller.cc index 6398cb6..b2a7abc6 100644 --- a/components/sync_sessions/session_data_type_controller.cc +++ b/components/sync_sessions/session_data_type_controller.cc
@@ -5,7 +5,7 @@ #include "components/sync_sessions/session_data_type_controller.h" #include "components/prefs/pref_service.h" -#include "components/sync_driver/sync_client.h" +#include "components/sync/driver/sync_client.h" #include "components/sync_sessions/sync_sessions_client.h" #include "components/sync_sessions/synced_window_delegate.h" #include "components/sync_sessions/synced_window_delegates_getter.h"
diff --git a/components/sync_sessions/session_data_type_controller.h b/components/sync_sessions/session_data_type_controller.h index 601501b..d8442f48 100644 --- a/components/sync_sessions/session_data_type_controller.h +++ b/components/sync_sessions/session_data_type_controller.h
@@ -9,8 +9,8 @@ #include "base/macros.h" #include "components/prefs/pref_change_registrar.h" -#include "components/sync_driver/local_device_info_provider.h" -#include "components/sync_driver/ui_data_type_controller.h" +#include "components/sync/driver/local_device_info_provider.h" +#include "components/sync/driver/ui_data_type_controller.h" namespace browser_sync {
diff --git a/components/sync_sessions/session_data_type_controller_unittest.cc b/components/sync_sessions/session_data_type_controller_unittest.cc index 42f69ae..b18bf17 100644 --- a/components/sync_sessions/session_data_type_controller_unittest.cc +++ b/components/sync_sessions/session_data_type_controller_unittest.cc
@@ -13,9 +13,9 @@ #include "base/threading/thread_task_runner_handle.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/testing_pref_service.h" -#include "components/sync_driver/fake_sync_client.h" -#include "components/sync_driver/local_device_info_provider_mock.h" -#include "components/sync_driver/sync_api_component_factory_mock.h" +#include "components/sync/driver/fake_sync_client.h" +#include "components/sync/driver/local_device_info_provider_mock.h" +#include "components/sync/driver/sync_api_component_factory_mock.h" #include "components/sync_sessions/fake_sync_sessions_client.h" #include "components/sync_sessions/synced_window_delegate.h" #include "components/sync_sessions/synced_window_delegates_getter.h"
diff --git a/components/sync_sessions/sessions_sync_manager.cc b/components/sync_sessions/sessions_sync_manager.cc index 516999d..6f513c5c 100644 --- a/components/sync_sessions/sessions_sync_manager.cc +++ b/components/sync_sessions/sessions_sync_manager.cc
@@ -14,8 +14,8 @@ #include "components/sync/api/sync_error_factory.h" #include "components/sync/api/sync_merge_result.h" #include "components/sync/api/time.h" +#include "components/sync/driver/local_device_info_provider.h" #include "components/sync/syncable/syncable_util.h" -#include "components/sync_driver/local_device_info_provider.h" #include "components/sync_sessions/sync_sessions_client.h" #include "components/sync_sessions/synced_tab_delegate.h" #include "components/sync_sessions/synced_window_delegate.h"
diff --git a/components/sync_sessions/sessions_sync_manager.h b/components/sync_sessions/sessions_sync_manager.h index e759fdc..13452c4 100644 --- a/components/sync_sessions/sessions_sync_manager.h +++ b/components/sync_sessions/sessions_sync_manager.h
@@ -21,8 +21,8 @@ #include "components/sessions/core/session_id.h" #include "components/sessions/core/session_types.h" #include "components/sync/api/syncable_service.h" -#include "components/sync_driver/device_info.h" -#include "components/sync_driver/sync_prefs.h" +#include "components/sync/driver/device_info.h" +#include "components/sync/driver/sync_prefs.h" #include "components/sync_sessions/favicon_cache.h" #include "components/sync_sessions/local_session_event_router.h" #include "components/sync_sessions/open_tabs_ui_delegate.h"
diff --git a/components/sync_sessions/synced_session.cc b/components/sync_sessions/synced_session.cc index 3cb4a54b..c4992b89 100644 --- a/components/sync_sessions/synced_session.cc +++ b/components/sync_sessions/synced_session.cc
@@ -12,7 +12,7 @@ : session_tag("invalid"), device_type(TYPE_UNSET) {} SyncedSession::~SyncedSession() { - STLDeleteContainerPairSecondPointers(windows.begin(), windows.end()); + base::STLDeleteContainerPairSecondPointers(windows.begin(), windows.end()); } sync_pb::SessionHeader SyncedSession::ToSessionHeader() const {
diff --git a/components/sync_sessions/synced_session_tracker.cc b/components/sync_sessions/synced_session_tracker.cc index 527c5a3..1321ddd2 100644 --- a/components/sync_sessions/synced_session_tracker.cc +++ b/components/sync_sessions/synced_session_tracker.cc
@@ -430,11 +430,11 @@ } // Delete SyncedSession objects (which also deletes all their windows/tabs). - STLDeleteValues(&synced_session_map_); + base::STLDeleteValues(&synced_session_map_); // Go through and delete any tabs we had allocated but had not yet placed into // a SyncedSession object. - STLDeleteElements(&unmapped_tabs_); + base::STLDeleteElements(&unmapped_tabs_); // Get rid of our Window/Tab maps (does not delete the actual Window/Tabs // themselves; they should have all been deleted above).
diff --git a/components/sync_ui_strings.grdp b/components/sync_ui_strings.grdp index 0512cb9c2..b5cbb0b02 100644 --- a/components/sync_ui_strings.grdp +++ b/components/sync_ui_strings.grdp
@@ -16,6 +16,9 @@ <message name="IDS_SYNC_DATATYPE_PASSWORDS" desc="Saved passwords, one of the data types that we allow syncing."> Passwords </message> + <message name="IDS_SYNC_DATATYPE_PREFERENCES" desc="Settings, one of the data types that we allow syncing."> + Settings + </message> <message name="IDS_SYNC_DATATYPE_TABS" desc="Open Tabs, one of the data types that we allow syncing."> Open tabs </message>
diff --git a/components/syncable_prefs/pref_model_associator.cc b/components/syncable_prefs/pref_model_associator.cc index ef63b1c..aae6ab77 100644 --- a/components/syncable_prefs/pref_model_associator.cc +++ b/components/syncable_prefs/pref_model_associator.cc
@@ -70,8 +70,8 @@ DCHECK(CalledOnValidThread()); pref_service_ = NULL; - STLDeleteContainerPairSecondPointers(synced_pref_observers_.begin(), - synced_pref_observers_.end()); + base::STLDeleteContainerPairSecondPointers(synced_pref_observers_.begin(), + synced_pref_observers_.end()); synced_pref_observers_.clear(); }
diff --git a/components/test_runner/test_common.cc b/components/test_runner/test_common.cc index 4d295815..3639e7c 100644 --- a/components/test_runner/test_common.cc +++ b/components/test_runner/test_common.cc
@@ -9,9 +9,8 @@ #include "base/lazy_instance.h" #include "base/macros.h" #include "base/rand_util.h" -#include "third_party/WebKit/public/platform/Platform.h" -#include "third_party/WebKit/public/web/WebKit.h" #include "third_party/WebKit/public/web/WebNavigationPolicy.h" +#include "url/gurl.h" namespace test_runner { @@ -25,22 +24,6 @@ const char data_url_pattern[] = "data:"; const std::string::size_type data_url_pattern_size = sizeof(data_url_pattern) - 1; - -// This mock is used to initialize blink. -class MockBlinkPlatform : NON_EXPORTED_BASE(public blink::Platform) { - public: - MockBlinkPlatform() { - blink::Platform::initialize(this); - } - ~MockBlinkPlatform() override {} - - private: - DISALLOW_COPY_AND_ASSIGN(MockBlinkPlatform); -}; - -base::LazyInstance<MockBlinkPlatform>::Leaky g_mock_blink_platform = - LAZY_INSTANCE_INITIALIZER; - const char* kIllegalString = "illegal value"; const char* kPolicyIgnore = "Ignore"; const char* kPolicyDownload = "download"; @@ -102,8 +85,4 @@ return blink::WebString::fromUTF8(chars.get()); } -void EnsureBlinkInitialized() { - g_mock_blink_platform.Get(); -} - } // namespace test_runner
diff --git a/components/test_runner/test_common.h b/components/test_runner/test_common.h index c8477ba..b356c7f2 100644 --- a/components/test_runner/test_common.h +++ b/components/test_runner/test_common.h
@@ -33,10 +33,6 @@ blink::WebString V8StringToWebString(v8::Local<v8::String> v8_str); -// Tests which depend on Blink must call this function on the main thread -// before creating/calling any Blink objects/APIs. -TEST_RUNNER_EXPORT void EnsureBlinkInitialized(); - } // namespace test_runner #endif // COMPONENTS_TEST_RUNNER_TEST_COMMON_H_
diff --git a/components/translate/content/renderer/translate_helper.cc b/components/translate/content/renderer/translate_helper.cc index 330ac9a..0cecaa8 100644 --- a/components/translate/content/renderer/translate_helper.cc +++ b/components/translate/content/renderer/translate_helper.cc
@@ -122,9 +122,8 @@ } void TranslateHelper::PrepareForUrl(const GURL& url) { - // Navigated to a new page, close the binding for previous page. - binding_.Close(); - translate_callback_pending_.Reset(); + // Navigated to a new url, reset current page translation. + ResetPage(); } void TranslateHelper::PageCaptured(const base::string16& contents) { @@ -176,7 +175,7 @@ // For the same render frame with the same url, each time when its texts are // captured, it should be treated as a new page to do translation. - binding_.Close(); + ResetPage(); GetTranslateDriver()->RegisterPage( binding_.CreateInterfacePtrAndBind(), details, !details.has_notranslate && !language.empty()); @@ -471,6 +470,12 @@ return translate_driver_; } +void TranslateHelper::ResetPage() { + binding_.Close(); + translate_callback_pending_.Reset(); + CancelPendingTranslation(); +} + void TranslateHelper::OnDestruct() { delete this; }
diff --git a/components/translate/content/renderer/translate_helper.h b/components/translate/content/renderer/translate_helper.h index bff4756..c4f62560 100644 --- a/components/translate/content/renderer/translate_helper.h +++ b/components/translate/content/renderer/translate_helper.h
@@ -106,6 +106,10 @@ const mojom::ContentTranslateDriverPtr& GetTranslateDriver(); + // Cleanups all states and pending callbacks associated with the current + // running page translation. + void ResetPage(); + // RenderFrameObserver implementation. void OnDestruct() override;
diff --git a/components/translate/core/language_detection/language_detection_util.cc b/components/translate/core/language_detection/language_detection_util.cc index 8318e97e..685214c 100644 --- a/components/translate/core/language_detection/language_detection_util.cc +++ b/components/translate/core/language_detection/language_detection_util.cc
@@ -178,7 +178,7 @@ // Make a prediction. chrome_lang_id::NNetLanguageIdentifier lang_id; const chrome_lang_id::NNetLanguageIdentifier::Result lang_id_result = - lang_id.FindTopNMostLikelyLangs(utf8_text, /*num_langs=*/1).at(0); + lang_id.FindTopNMostFreqLangs(utf8_text, /*num_langs=*/1).at(0); const bool prediction_reliable = lang_id_result.is_reliable; const std::string& predicted_language = lang_id_result.language;
diff --git a/components/translate/ios/browser/js_translate_manager.mm b/components/translate/ios/browser/js_translate_manager.mm index faec724..47f2a4e3 100644 --- a/components/translate/ios/browser/js_translate_manager.mm +++ b/components/translate/ios/browser/js_translate_manager.mm
@@ -47,27 +47,27 @@ } - (void)injectWaitUntilTranslateReadyScript { - [self.receiver evaluateJavaScript:@"__gCrWeb.translate.checkTranslateReady()" - stringResultHandler:nil]; + [self.receiver executeJavaScript:@"__gCrWeb.translate.checkTranslateReady()" + completionHandler:nil]; } - (void)injectTranslateStatusScript { - [self.receiver evaluateJavaScript:@"__gCrWeb.translate.checkTranslateStatus()" - stringResultHandler:nil]; + [self.receiver executeJavaScript:@"__gCrWeb.translate.checkTranslateStatus()" + completionHandler:nil]; } - (void)startTranslationFrom:(const std::string&)source to:(const std::string&)target { - NSString* js = + NSString* script = [NSString stringWithFormat:@"cr.googleTranslate.translate('%s','%s')", source.c_str(), target.c_str()]; - [self.receiver evaluateJavaScript:js stringResultHandler:nil]; + [self.receiver executeJavaScript:script completionHandler:nil]; } - (void)revertTranslation { DCHECK([self hasBeenInjected]); - [self.receiver evaluateJavaScript:@"cr.googleTranslate.revert()" - stringResultHandler:nil]; + [self.receiver executeJavaScript:@"cr.googleTranslate.revert()" + completionHandler:nil]; } #pragma mark -
diff --git a/components/translate/ios/browser/js_translate_manager_unittest.mm b/components/translate/ios/browser/js_translate_manager_unittest.mm index e0115203..c9c6fa0d 100644 --- a/components/translate/ios/browser/js_translate_manager_unittest.mm +++ b/components/translate/ios/browser/js_translate_manager_unittest.mm
@@ -24,8 +24,7 @@ @implementation JsTranslateManager (Testing) // Returns the time in milliseconds. - (double)performanceNow { - NSString* result = - web::EvaluateJavaScriptAsString(self.receiver, @"performance.now()"); + id result = web::ExecuteJavaScript(self.receiver, @"performance.now()"); return [result doubleValue]; } @end @@ -45,7 +44,7 @@ bool IsDefined(NSString* name) { NSString* script = [NSString stringWithFormat:@"typeof %@ != 'undefined'", name]; - return [web::EvaluateJavaScriptAsString(receiver_, script) isEqual:@"true"]; + return [web::ExecuteJavaScript(receiver_, script) boolValue]; } base::scoped_nsobject<CRWTestJSInjectionReceiver> receiver_;
diff --git a/components/update_client/action.cc b/components/update_client/action.cc index cb9d738..c979e2a 100644 --- a/components/update_client/action.cc +++ b/components/update_client/action.cc
@@ -128,7 +128,7 @@ item->update_begin = base::TimeTicks::Now(); if (item->component.supports_group_policy_enable_component_updates && - !update_context_->config->EnabledComponentUpdates()) { + !update_context_->enabled_component_updates) { item->error_category = static_cast<int>(Action::ErrorCategory::kServiceError); item->error_code =
diff --git a/components/update_client/action_update_check.cc b/components/update_client/action_update_check.cc index 6263d165f..8d1cbdb 100644 --- a/components/update_client/action_update_check.cc +++ b/components/update_client/action_update_check.cc
@@ -91,6 +91,7 @@ update_checker_->CheckForUpdates( update_context_->update_items, extra_request_parameters_, + update_context_->enabled_component_updates, base::Bind(&ActionUpdateCheck::UpdateCheckComplete, base::Unretained(this))); }
diff --git a/components/update_client/test_configurator.cc b/components/update_client/test_configurator.cc index 0ccccd0..eb17165a 100644 --- a/components/update_client/test_configurator.cc +++ b/components/update_client/test_configurator.cc
@@ -30,7 +30,7 @@ initial_time_(0), ondemand_time_(0), enabled_cup_signing_(false), - enabled_component_updates_(false), + enabled_component_updates_(true), context_(new net::TestURLRequestContextGetter(network_task_runner)) {} TestConfigurator::~TestConfigurator() {
diff --git a/components/update_client/update_checker.cc b/components/update_client/update_checker.cc index 406e1f06..a5ec266 100644 --- a/components/update_client/update_checker.cc +++ b/components/update_client/update_checker.cc
@@ -72,7 +72,8 @@ std::string BuildUpdateCheckRequest(const Configurator& config, const std::vector<CrxUpdateItem*>& items, PersistedData* metadata, - const std::string& additional_attributes) { + const std::string& additional_attributes, + bool enabled_component_updates) { const std::string brand(SanitizeBrand(config.GetBrand())); std::string app_elements; for (size_t i = 0; i != items.size(); ++i) { @@ -94,7 +95,7 @@ base::StringAppendF(&app, "<updatecheck"); if (item->component.supports_group_policy_enable_component_updates && - !config.EnabledComponentUpdates()) { + !enabled_component_updates) { base::StringAppendF(&app, " updatedisabled=\"true\""); } base::StringAppendF(&app, "/>"); @@ -130,6 +131,7 @@ bool CheckForUpdates( const std::vector<CrxUpdateItem*>& items_to_check, const std::string& additional_attributes, + bool enabled_component_updates, const UpdateCheckCallback& update_check_callback) override; private: @@ -159,6 +161,7 @@ bool UpdateCheckerImpl::CheckForUpdates( const std::vector<CrxUpdateItem*>& items_to_check, const std::string& additional_attributes, + bool enabled_component_updates, const UpdateCheckCallback& update_check_callback) { DCHECK(thread_checker_.CalledOnValidThread()); @@ -181,7 +184,7 @@ request_sender_->Send( config_->EnabledCupSigning(), BuildUpdateCheckRequest(*config_, items_to_check, metadata_, - additional_attributes), + additional_attributes, enabled_component_updates), urls, base::Bind(&UpdateCheckerImpl::OnRequestSenderComplete, base::Unretained(this), base::Passed(&ids_checked))); return true;
diff --git a/components/update_client/update_checker.h b/components/update_client/update_checker.h index 2705018..d3080c3 100644 --- a/components/update_client/update_checker.h +++ b/components/update_client/update_checker.h
@@ -42,6 +42,7 @@ virtual bool CheckForUpdates( const std::vector<CrxUpdateItem*>& items_to_check, const std::string& additional_attributes, + bool enabled_component_updates, const UpdateCheckCallback& update_check_callback) = 0; static std::unique_ptr<UpdateChecker> Create(
diff --git a/components/update_client/update_checker_unittest.cc b/components/update_client/update_checker_unittest.cc index 96889f2..19592c5 100644 --- a/components/update_client/update_checker_unittest.cc +++ b/components/update_client/update_checker_unittest.cc
@@ -175,7 +175,7 @@ items_to_check.push_back(&item); update_checker_->CheckForUpdates( - items_to_check, "extra=\"params\"", + items_to_check, "extra=\"params\"", true, base::Bind(&UpdateCheckerTest::UpdateCheckComplete, base::Unretained(this))); @@ -226,8 +226,9 @@ items_to_check.push_back(&item); update_checker_->CheckForUpdates( - items_to_check, "", base::Bind(&UpdateCheckerTest::UpdateCheckComplete, - base::Unretained(this))); + items_to_check, "", true, + base::Bind(&UpdateCheckerTest::UpdateCheckComplete, + base::Unretained(this))); RunThreads(); @@ -253,8 +254,9 @@ items_to_check.push_back(&item); update_checker_->CheckForUpdates( - items_to_check, "", base::Bind(&UpdateCheckerTest::UpdateCheckComplete, - base::Unretained(this))); + items_to_check, "", true, + base::Bind(&UpdateCheckerTest::UpdateCheckComplete, + base::Unretained(this))); RunThreads(); @@ -280,8 +282,9 @@ items_to_check.push_back(&item); update_checker_->CheckForUpdates( - items_to_check, "", base::Bind(&UpdateCheckerTest::UpdateCheckComplete, - base::Unretained(this))); + items_to_check, "", true, + base::Bind(&UpdateCheckerTest::UpdateCheckComplete, + base::Unretained(this))); RunThreads(); EXPECT_EQ(1, post_interceptor_->GetHitCount()) @@ -306,7 +309,7 @@ items_to_check.push_back(&item); update_checker_->CheckForUpdates( - items_to_check, "extra=\"params\"", + items_to_check, "extra=\"params\"", true, base::Bind(&UpdateCheckerTest::UpdateCheckComplete, base::Unretained(this))); @@ -332,8 +335,9 @@ items_to_check.push_back(&item); update_checker_->CheckForUpdates( - items_to_check, "", base::Bind(&UpdateCheckerTest::UpdateCheckComplete, - base::Unretained(this))); + items_to_check, "", true, + base::Bind(&UpdateCheckerTest::UpdateCheckComplete, + base::Unretained(this))); RunThreads(); @@ -370,8 +374,9 @@ items_to_check.push_back(&item); update_checker_->CheckForUpdates( - items_to_check, "", base::Bind(&UpdateCheckerTest::UpdateCheckComplete, - base::Unretained(this))); + items_to_check, "", true, + base::Bind(&UpdateCheckerTest::UpdateCheckComplete, + base::Unretained(this))); RunThreads(); EXPECT_EQ(-1, error_); @@ -394,13 +399,13 @@ // Do two update-checks. update_checker_->CheckForUpdates( - items_to_check, "extra=\"params\"", + items_to_check, "extra=\"params\"", true, base::Bind(&UpdateCheckerTest::UpdateCheckComplete, base::Unretained(this))); RunThreads(); update_checker_ = UpdateChecker::Create(config_, metadata_.get()); update_checker_->CheckForUpdates( - items_to_check, "extra=\"params\"", + items_to_check, "extra=\"params\"", true, base::Bind(&UpdateCheckerTest::UpdateCheckComplete, base::Unretained(this))); RunThreads(); @@ -430,12 +435,12 @@ // Expects the group policy to be ignored and the update check to not // include the "updatedisabled" attribute. EXPECT_FALSE(item.component.supports_group_policy_enable_component_updates); - config_->SetEnabledComponentUpdates(false); std::vector<CrxUpdateItem*> items_to_check; items_to_check.push_back(&item); update_checker_->CheckForUpdates( - items_to_check, "", base::Bind(&UpdateCheckerTest::UpdateCheckComplete, - base::Unretained(this))); + items_to_check, "", false, + base::Bind(&UpdateCheckerTest::UpdateCheckComplete, + base::Unretained(this))); RunThreads(); EXPECT_NE( string::npos, @@ -448,11 +453,11 @@ // * the component updates are disabled. // Expects the update check to include the "updatedisabled" attribute. item.component.supports_group_policy_enable_component_updates = true; - config_->SetEnabledComponentUpdates(false); update_checker_ = UpdateChecker::Create(config_, metadata_.get()); update_checker_->CheckForUpdates( - items_to_check, "", base::Bind(&UpdateCheckerTest::UpdateCheckComplete, - base::Unretained(this))); + items_to_check, "", false, + base::Bind(&UpdateCheckerTest::UpdateCheckComplete, + base::Unretained(this))); RunThreads(); EXPECT_NE( string::npos, @@ -465,11 +470,11 @@ // * the component updates are enabled. // Expects the update check to not include the "updatedisabled" attribute. item.component.supports_group_policy_enable_component_updates = false; - config_->SetEnabledComponentUpdates(true); update_checker_ = UpdateChecker::Create(config_, metadata_.get()); update_checker_->CheckForUpdates( - items_to_check, "", base::Bind(&UpdateCheckerTest::UpdateCheckComplete, - base::Unretained(this))); + items_to_check, "", true, + base::Bind(&UpdateCheckerTest::UpdateCheckComplete, + base::Unretained(this))); RunThreads(); EXPECT_NE( string::npos, @@ -482,11 +487,11 @@ // * the component updates are enabled. // Expects the update check to not include the "updatedisabled" attribute. item.component.supports_group_policy_enable_component_updates = true; - config_->SetEnabledComponentUpdates(true); update_checker_ = UpdateChecker::Create(config_, metadata_.get()); update_checker_->CheckForUpdates( - items_to_check, "", base::Bind(&UpdateCheckerTest::UpdateCheckComplete, - base::Unretained(this))); + items_to_check, "", true, + base::Bind(&UpdateCheckerTest::UpdateCheckComplete, + base::Unretained(this))); RunThreads(); EXPECT_NE( string::npos,
diff --git a/components/update_client/update_client_unittest.cc b/components/update_client/update_client_unittest.cc index 4dad5e2..68e8dbe 100644 --- a/components/update_client/update_client_unittest.cc +++ b/components/update_client/update_client_unittest.cc
@@ -235,7 +235,9 @@ bool CheckForUpdates( const std::vector<CrxUpdateItem*>& items_to_check, const std::string& additional_attributes, + bool enabled_component_updates, const UpdateCheckCallback& update_check_callback) override { + EXPECT_TRUE(enabled_component_updates); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(update_check_callback, 0, UpdateResponse::Results(), 0)); @@ -342,6 +344,7 @@ bool CheckForUpdates( const std::vector<CrxUpdateItem*>& items_to_check, const std::string& additional_attributes, + bool enabled_component_updates, const UpdateCheckCallback& update_check_callback) override { /* Fake the following response: @@ -528,6 +531,7 @@ bool CheckForUpdates( const std::vector<CrxUpdateItem*>& items_to_check, const std::string& additional_attributes, + bool enabled_component_updates, const UpdateCheckCallback& update_check_callback) override { /* Fake the following response: @@ -776,6 +780,7 @@ bool CheckForUpdates( const std::vector<CrxUpdateItem*>& items_to_check, const std::string& additional_attributes, + bool enabled_component_updates, const UpdateCheckCallback& update_check_callback) override { /* Fake the following response: @@ -1027,6 +1032,7 @@ bool CheckForUpdates( const std::vector<CrxUpdateItem*>& items_to_check, const std::string& additional_attributes, + bool enabled_component_updates, const UpdateCheckCallback& update_check_callback) override { static int num_call = 0; ++num_call; @@ -1319,6 +1325,7 @@ bool CheckForUpdates( const std::vector<CrxUpdateItem*>& items_to_check, const std::string& additional_attributes, + bool enabled_component_updates, const UpdateCheckCallback& update_check_callback) override { /* Fake the following response: @@ -1503,6 +1510,7 @@ bool CheckForUpdates( const std::vector<CrxUpdateItem*>& items_to_check, const std::string& additional_attributes, + bool enabled_component_updates, const UpdateCheckCallback& update_check_callback) override { static int num_call = 0; ++num_call; @@ -1793,6 +1801,7 @@ bool CheckForUpdates( const std::vector<CrxUpdateItem*>& items_to_check, const std::string& additional_attributes, + bool enabled_component_updates, const UpdateCheckCallback& update_check_callback) override { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, @@ -1893,6 +1902,7 @@ bool CheckForUpdates( const std::vector<CrxUpdateItem*>& items_to_check, const std::string& additional_attributes, + bool enabled_component_updates, const UpdateCheckCallback& update_check_callback) override { /* Fake the following response: @@ -2080,6 +2090,7 @@ bool CheckForUpdates( const std::vector<CrxUpdateItem*>& items_to_check, const std::string& additional_attributes, + bool enabled_component_updates, const UpdateCheckCallback& update_check_callback) override { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, @@ -2174,6 +2185,7 @@ bool CheckForUpdates( const std::vector<CrxUpdateItem*>& items_to_check, const std::string& additional_attributes, + bool enabled_component_updates, const UpdateCheckCallback& update_check_callback) override { return false; } @@ -2220,6 +2232,7 @@ bool CheckForUpdates( const std::vector<CrxUpdateItem*>& items_to_check, const std::string& additional_attributes, + bool enabled_component_updates, const UpdateCheckCallback& update_check_callback) override { return false; } @@ -2318,6 +2331,7 @@ bool CheckForUpdates( const std::vector<CrxUpdateItem*>& items_to_check, const std::string& additional_attributes, + bool enabled_component_updates, const UpdateCheckCallback& update_check_callback) override { static int num_call = 0; ++num_call; @@ -2482,6 +2496,7 @@ bool CheckForUpdates( const std::vector<CrxUpdateItem*>& items_to_check, const std::string& additional_attributes, + bool enabled_component_updates, const UpdateCheckCallback& update_check_callback) override { /* Fake the following response: @@ -2518,6 +2533,13 @@ </app> </response> */ + + // UpdateClient reads the state of |enabled_component_updates| from the + // configurator instance, persists its value in the corresponding + // update context, and propagates it down to each of the update actions, + // and further down to the UpdateChecker instance. + EXPECT_FALSE(enabled_component_updates); + UpdateResponse::Result::Manifest::Package package1; package1.name = "jebgalgnebhfojomionfpkfelancnnkf.crx"; package1.hash_sha256 =
diff --git a/components/update_client/update_engine.cc b/components/update_client/update_engine.cc index 106e2c2..adb26de1 100644 --- a/components/update_client/update_engine.cc +++ b/components/update_client/update_engine.cc
@@ -31,6 +31,7 @@ PingManager* ping_manager) : config(config), is_foreground(is_foreground), + enabled_component_updates(config->EnabledComponentUpdates()), ids(ids), crx_data_callback(crx_data_callback), notify_observers_callback(notify_observers_callback), @@ -43,7 +44,7 @@ retry_after_sec_(0) {} UpdateContext::~UpdateContext() { - STLDeleteElements(&update_items); + base::STLDeleteElements(&update_items); } UpdateEngine::UpdateEngine(
diff --git a/components/update_client/update_engine.h b/components/update_client/update_engine.h index a82864c..3ebcc11 100644 --- a/components/update_client/update_engine.h +++ b/components/update_client/update_engine.h
@@ -114,6 +114,9 @@ // True if this update has been initiated by the user. bool is_foreground; + // True if the component updates are enabled in this context. + const bool enabled_component_updates; + // Contains the ids of all CRXs in this context. const std::vector<std::string> ids;
diff --git a/components/url_matcher/regex_set_matcher.cc b/components/url_matcher/regex_set_matcher.cc index d597f0001..ac48123a 100644 --- a/components/url_matcher/regex_set_matcher.cc +++ b/components/url_matcher/regex_set_matcher.cc
@@ -108,7 +108,7 @@ } void RegexSetMatcher::DeleteSubstringPatterns() { - STLDeleteElements(&substring_patterns_); + base::STLDeleteElements(&substring_patterns_); } } // namespace url_matcher
diff --git a/components/url_matcher/regex_set_matcher_unittest.cc b/components/url_matcher/regex_set_matcher_unittest.cc index dd54e51..49d9a57 100644 --- a/components/url_matcher/regex_set_matcher_unittest.cc +++ b/components/url_matcher/regex_set_matcher_unittest.cc
@@ -26,14 +26,14 @@ std::set<StringPattern::ID> result1; matcher.Match("http://abracadabra.com", &result1); EXPECT_EQ(2U, result1.size()); - EXPECT_TRUE(ContainsKey(result1, 42)); - EXPECT_TRUE(ContainsKey(result1, 239)); + EXPECT_TRUE(base::ContainsKey(result1, 42)); + EXPECT_TRUE(base::ContainsKey(result1, 239)); std::set<StringPattern::ID> result2; matcher.Match("https://abfffffffffffffffffffffffffffffff.fi/cf", &result2); EXPECT_EQ(2U, result2.size()); - EXPECT_TRUE(ContainsKey(result2, 17)); - EXPECT_TRUE(ContainsKey(result2, 42)); + EXPECT_TRUE(base::ContainsKey(result2, 17)); + EXPECT_TRUE(base::ContainsKey(result2, 42)); std::set<StringPattern::ID> result3; matcher.Match("http://nothing.com/", &result3); @@ -56,7 +56,7 @@ std::set<StringPattern::ID> result2; matcher.Match("http://aaa.net/quaaACK", &result2); EXPECT_EQ(1U, result2.size()); - EXPECT_TRUE(ContainsKey(result2, 57)); + EXPECT_TRUE(base::ContainsKey(result2, 57)); } } // namespace url_matcher
diff --git a/components/url_matcher/url_matcher.cc b/components/url_matcher/url_matcher.cc index b4a9d21..8e5cd9e 100644 --- a/components/url_matcher/url_matcher.cc +++ b/components/url_matcher/url_matcher.cc
@@ -222,7 +222,7 @@ const std::set<StringPattern::ID>& matching_patterns, const GURL& url) const { DCHECK(string_pattern_); - if (!ContainsKey(matching_patterns, string_pattern_->id())) + if (!base::ContainsKey(matching_patterns, string_pattern_->id())) return false; // The criteria HOST_CONTAINS, PATH_CONTAINS, QUERY_CONTAINS are based on // a substring match on the raw URL. In case of a match, we need to verify @@ -262,9 +262,9 @@ URLMatcherConditionFactory::URLMatcherConditionFactory() : id_counter_(0) {} URLMatcherConditionFactory::~URLMatcherConditionFactory() { - STLDeleteElements(&substring_pattern_singletons_); - STLDeleteElements(®ex_pattern_singletons_); - STLDeleteElements(&origin_and_path_regex_pattern_singletons_); + base::STLDeleteElements(&substring_pattern_singletons_); + base::STLDeleteElements(®ex_pattern_singletons_); + base::STLDeleteElements(&origin_and_path_regex_pattern_singletons_); } std::string URLMatcherConditionFactory::CanonicalizeURLForComponentSearches( @@ -465,7 +465,7 @@ const std::set<StringPattern::ID>& used_patterns) { PatternSingletons::iterator i = substring_pattern_singletons_.begin(); while (i != substring_pattern_singletons_.end()) { - if (ContainsKey(used_patterns, (*i)->id())) { + if (base::ContainsKey(used_patterns, (*i)->id())) { ++i; } else { delete *i; @@ -474,7 +474,7 @@ } i = regex_pattern_singletons_.begin(); while (i != regex_pattern_singletons_.end()) { - if (ContainsKey(used_patterns, (*i)->id())) { + if (base::ContainsKey(used_patterns, (*i)->id())) { ++i; } else { delete *i; @@ -483,7 +483,7 @@ } i = origin_and_path_regex_pattern_singletons_.begin(); while (i != origin_and_path_regex_pattern_singletons_.end()) { - if (ContainsKey(used_patterns, (*i)->id())) { + if (base::ContainsKey(used_patterns, (*i)->id())) { ++i; } else { delete *i; @@ -784,7 +784,7 @@ for (QueryConditions::const_iterator i = query_conditions_.begin(); i != query_conditions_.end(); ++i) { - if (!ContainsKey(matching_patterns, i->string_pattern()->id())) + if (!base::ContainsKey(matching_patterns, i->string_pattern()->id())) return false; } for (QueryConditions::const_iterator i = query_conditions_.begin();
diff --git a/components/user_prefs/tracked/segregated_pref_store.cc b/components/user_prefs/tracked/segregated_pref_store.cc index c5a6e25..af8dfe3 100644 --- a/components/user_prefs/tracked/segregated_pref_store.cc +++ b/components/user_prefs/tracked/segregated_pref_store.cc
@@ -166,14 +166,16 @@ } PersistentPrefStore* SegregatedPrefStore::StoreForKey(const std::string& key) { - return (ContainsKey(selected_preference_names_, key) + return (base::ContainsKey(selected_preference_names_, key) ? selected_pref_store_ - : default_pref_store_).get(); + : default_pref_store_) + .get(); } const PersistentPrefStore* SegregatedPrefStore::StoreForKey( const std::string& key) const { - return (ContainsKey(selected_preference_names_, key) + return (base::ContainsKey(selected_preference_names_, key) ? selected_pref_store_ - : default_pref_store_).get(); + : default_pref_store_) + .get(); }
diff --git a/components/variations/study_filtering.cc b/components/variations/study_filtering.cc index f5b3f26f..479b9e9 100644 --- a/components/variations/study_filtering.cc +++ b/components/variations/study_filtering.cc
@@ -164,10 +164,10 @@ // that this means this overrides the exclude_country in case that ever occurs // (which it shouldn't). if (filter.country_size() > 0) - return ContainsValue(filter.country(), country); + return base::ContainsValue(filter.country(), country); // Omit if matches any of the exclude entries. - return !ContainsValue(filter.exclude_country(), country); + return !base::ContainsValue(filter.exclude_country(), country); } bool IsStudyExpired(const Study& study, const base::Time& date_time) { @@ -288,14 +288,14 @@ if (internal::IsStudyExpired(study, reference_date)) { expired_studies.push_back(&study); - } else if (!ContainsKey(created_studies, study.name())) { + } else if (!base::ContainsKey(created_studies, study.name())) { ProcessedStudy::ValidateAndAppendStudy(&study, false, filtered_studies); created_studies.insert(study.name()); } } for (size_t i = 0; i < expired_studies.size(); ++i) { - if (!ContainsKey(created_studies, expired_studies[i]->name())) { + if (!base::ContainsKey(created_studies, expired_studies[i]->name())) { ProcessedStudy::ValidateAndAppendStudy(expired_studies[i], true, filtered_studies); }
diff --git a/components/variations/variations_associated_data.cc b/components/variations/variations_associated_data.cc index ff330b0..d257d0199 100644 --- a/components/variations/variations_associated_data.cc +++ b/components/variations/variations_associated_data.cc
@@ -128,7 +128,7 @@ return false; const VariationKey key(trial_name, group_name); - if (ContainsKey(variation_params_, key)) + if (base::ContainsKey(variation_params_, key)) return false; variation_params_[key] = params; @@ -142,7 +142,7 @@ const std::string group_name = base::FieldTrialList::FindFullName(trial_name); const VariationKey key(trial_name, group_name); - if (!ContainsKey(variation_params_, key)) + if (!base::ContainsKey(variation_params_, key)) return false; *params = variation_params_[key];
diff --git a/components/webcrypto/BUILD.gn b/components/webcrypto/BUILD.gn index b9a5e63..1b13587 100644 --- a/components/webcrypto/BUILD.gn +++ b/components/webcrypto/BUILD.gn
@@ -110,10 +110,6 @@ "//crypto", "//crypto:platform", "//third_party/WebKit/public:blink", - - # This contains a helper function for initializing Blink (needed for - # PartitionAlloc initialization). - "//components/test_runner:test_runner", ] } @@ -141,6 +137,18 @@ ] } +# Tests the import of raw (X9.62) formatted EC keys. +fuzzer_test("webcrypto_ec_import_key_raw_fuzzer") { + sources = [ + "ec_import_key_raw_fuzzer.cc", + ] + deps = [ + ":fuzzer_support", + ":webcrypto", + "//third_party/WebKit/public:blink_headers", + ] +} + # Tests the import of PKCS8 formatted RSA keys. fuzzer_test("webcrypto_rsa_import_key_pkcs8_fuzzer") { sources = [
diff --git a/components/webcrypto/DEPS b/components/webcrypto/DEPS index 14ca3e0..5cdc8e79 100644 --- a/components/webcrypto/DEPS +++ b/components/webcrypto/DEPS
@@ -1,5 +1,4 @@ include_rules = [ - "+components/test_runner", "+crypto", "+third_party/re2", "+third_party/WebKit/public/platform",
diff --git a/components/webcrypto/algorithms/ec.cc b/components/webcrypto/algorithms/ec.cc index 9aa9bfec..3900d3c 100644 --- a/components/webcrypto/algorithms/ec.cc +++ b/components/webcrypto/algorithms/ec.cc
@@ -19,6 +19,7 @@ #include "components/webcrypto/generate_key_result.h" #include "components/webcrypto/jwk.h" #include "components/webcrypto/status.h" +#include "crypto/auto_cbb.h" #include "crypto/openssl_util.h" #include "crypto/scoped_openssl_types.h" #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" @@ -110,23 +111,23 @@ blink::WebCryptoNamedCurve expected_named_curve) { crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); - crypto::ScopedEC_KEY ec(EVP_PKEY_get1_EC_KEY(pkey)); - if (!ec.get()) + EC_KEY* ec = EVP_PKEY_get0_EC_KEY(pkey); + if (!ec) return Status::ErrorUnexpected(); // When importing an ECPrivateKey, the public key is optional. If it was // omitted then the public key will be calculated by BoringSSL and added into // the EC_KEY. However an encoding flag is set such that when exporting to // PKCS8 format the public key is once again omitted. Remove this flag. - unsigned int enc_flags = EC_KEY_get_enc_flags(ec.get()); + unsigned int enc_flags = EC_KEY_get_enc_flags(ec); enc_flags &= ~EC_PKEY_NO_PUBKEY; - EC_KEY_set_enc_flags(ec.get(), enc_flags); + EC_KEY_set_enc_flags(ec, enc_flags); - if (!EC_KEY_check_key(ec.get())) + if (!EC_KEY_check_key(ec)) return Status::ErrorEcKeyInvalid(); // Make sure the curve matches the expected curve name. - int curve_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec.get())); + int curve_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); blink::WebCryptoNamedCurve named_curve = blink::WebCryptoNamedCurveP256; Status status = NidToWebCryptoCurve(curve_nid, &named_curve); if (status.IsError()) @@ -297,6 +298,8 @@ blink::WebCryptoKeyUsageMask usages, blink::WebCryptoKey* key) const { switch (format) { + case blink::WebCryptoKeyFormatRaw: + return ImportKeyRaw(key_data, algorithm, extractable, usages, key); case blink::WebCryptoKeyFormatPkcs8: return ImportKeyPkcs8(key_data, algorithm, extractable, usages, key); case blink::WebCryptoKeyFormatSpki: @@ -312,6 +315,8 @@ const blink::WebCryptoKey& key, std::vector<uint8_t>* buffer) const { switch (format) { + case blink::WebCryptoKeyFormatRaw: + return ExportKeyRaw(key, buffer); case blink::WebCryptoKeyFormatPkcs8: return ExportKeyPkcs8(key, buffer); case blink::WebCryptoKeyFormatSpki: @@ -323,6 +328,58 @@ } } +Status EcAlgorithm::ImportKeyRaw(const CryptoData& key_data, + const blink::WebCryptoAlgorithm& algorithm, + bool extractable, + blink::WebCryptoKeyUsageMask usages, + blink::WebCryptoKey* key) const { + crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); + + Status status = CheckKeyCreationUsages(all_public_key_usages_, usages); + if (status.IsError()) + return status; + + const blink::WebCryptoEcKeyImportParams* params = + algorithm.ecKeyImportParams(); + + // Create an EC_KEY. + crypto::ScopedEC_KEY ec; + status = CreateEC_KEY(params->namedCurve(), &ec); + if (status.IsError()) + return status; + + crypto::ScopedEC_POINT point(EC_POINT_new(EC_KEY_get0_group(ec.get()))); + if (!point.get()) + return Status::OperationError(); + + // Convert the "raw" input from X9.62 format to an EC_POINT. + if (!EC_POINT_oct2point(EC_KEY_get0_group(ec.get()), point.get(), + key_data.bytes(), key_data.byte_length(), nullptr)) { + return Status::DataError(); + } + + // Copy the point (public key) into the EC_KEY. + if (!EC_KEY_set_public_key(ec.get(), point.get())) + return Status::OperationError(); + + // Verify the key. + if (!EC_KEY_check_key(ec.get())) + return Status::ErrorEcKeyInvalid(); + + // Wrap the EC_KEY into an EVP_PKEY. + crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new()); + if (!pkey || !EVP_PKEY_set1_EC_KEY(pkey.get(), ec.get())) + return Status::OperationError(); + + blink::WebCryptoKeyAlgorithm key_algorithm = + blink::WebCryptoKeyAlgorithm::createEc(algorithm.id(), + params->namedCurve()); + + // Wrap the EVP_PKEY into a WebCryptoKey + return CreateWebCryptoPublicKey(std::move(pkey), key_algorithm, extractable, + usages, key); +} + Status EcAlgorithm::ImportKeyPkcs8(const CryptoData& key_data, const blink::WebCryptoAlgorithm& algorithm, bool extractable, @@ -487,6 +544,36 @@ usages, key); } +Status EcAlgorithm::ExportKeyRaw(const blink::WebCryptoKey& key, + std::vector<uint8_t>* buffer) const { + crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); + + if (key.type() != blink::WebCryptoKeyTypePublic) + return Status::ErrorUnexpectedKeyType(); + + EVP_PKEY* pkey = GetEVP_PKEY(key); + + EC_KEY* ec = EVP_PKEY_get0_EC_KEY(pkey); + if (!ec) + return Status::ErrorUnexpected(); + + // Serialize the public key as an uncompressed point in X9.62 form. + uint8_t* raw; + size_t raw_len; + crypto::AutoCBB cbb; + if (!CBB_init(cbb.get(), 0) || + !EC_POINT_point2cbb(cbb.get(), EC_KEY_get0_group(ec), + EC_KEY_get0_public_key(ec), + POINT_CONVERSION_UNCOMPRESSED, nullptr) || + !CBB_finish(cbb.get(), &raw, &raw_len)) { + return Status::OperationError(); + } + buffer->assign(raw, raw + raw_len); + OPENSSL_free(raw); + + return Status::Success(); +} + Status EcAlgorithm::ExportKeyPkcs8(const blink::WebCryptoKey& key, std::vector<uint8_t>* buffer) const { if (key.type() != blink::WebCryptoKeyTypePrivate) @@ -517,8 +604,8 @@ EVP_PKEY* pkey = GetEVP_PKEY(key); - crypto::ScopedEC_KEY ec(EVP_PKEY_get1_EC_KEY(pkey)); - if (!ec.get()) + EC_KEY* ec = EVP_PKEY_get0_EC_KEY(pkey); + if (!ec) return Status::ErrorUnexpected(); // No "alg" is set for EC keys. @@ -531,13 +618,13 @@ if (status.IsError()) return status; - int degree_bytes = GetGroupDegreeInBytes(ec.get()); + int degree_bytes = GetGroupDegreeInBytes(ec); jwk.SetString("crv", crv); crypto::ScopedBIGNUM x; crypto::ScopedBIGNUM y; - status = GetPublicKey(ec.get(), &x, &y); + status = GetPublicKey(ec, &x, &y); if (status.IsError()) return status; @@ -550,7 +637,7 @@ return status; if (key.type() == blink::WebCryptoKeyTypePrivate) { - const BIGNUM* d = EC_KEY_get0_private_key(ec.get()); + const BIGNUM* d = EC_KEY_get0_private_key(ec); status = WritePaddedBIGNUM("d", d, degree_bytes, &jwk); if (status.IsError()) return status;
diff --git a/components/webcrypto/algorithms/ec.h b/components/webcrypto/algorithms/ec.h index 1484ad8..048bc50e 100644 --- a/components/webcrypto/algorithms/ec.h +++ b/components/webcrypto/algorithms/ec.h
@@ -51,6 +51,12 @@ blink::WebCryptoKey* key) const override; private: + Status ImportKeyRaw(const CryptoData& key_data, + const blink::WebCryptoAlgorithm& algorithm, + bool extractable, + blink::WebCryptoKeyUsageMask usages, + blink::WebCryptoKey* key) const; + Status ImportKeyPkcs8(const CryptoData& key_data, const blink::WebCryptoAlgorithm& algorithm, bool extractable, @@ -69,6 +75,9 @@ blink::WebCryptoKeyUsageMask usages, blink::WebCryptoKey* key) const; + Status ExportKeyRaw(const blink::WebCryptoKey& key, + std::vector<uint8_t>* buffer) const; + Status ExportKeyPkcs8(const blink::WebCryptoKey& key, std::vector<uint8_t>* buffer) const;
diff --git a/components/webcrypto/algorithms/ecdh.cc b/components/webcrypto/algorithms/ecdh.cc index de82db4..8afca5c 100644 --- a/components/webcrypto/algorithms/ecdh.cc +++ b/components/webcrypto/algorithms/ecdh.cc
@@ -79,20 +79,17 @@ return Status::ErrorEcdhCurveMismatch(); } - crypto::ScopedEC_KEY public_key_ec( - EVP_PKEY_get1_EC_KEY(GetEVP_PKEY(public_key))); + EC_KEY* public_key_ec = EVP_PKEY_get0_EC_KEY(GetEVP_PKEY(public_key)); - const EC_POINT* public_key_point = - EC_KEY_get0_public_key(public_key_ec.get()); + const EC_POINT* public_key_point = EC_KEY_get0_public_key(public_key_ec); - crypto::ScopedEC_KEY private_key_ec( - EVP_PKEY_get1_EC_KEY(GetEVP_PKEY(base_key))); + EC_KEY* private_key_ec = EVP_PKEY_get0_EC_KEY(GetEVP_PKEY(base_key)); // The size of the shared secret is the field size in bytes (rounded up). // Note that, if rounding was required, the most significant bits of the // secret are zero. So for P-521, the maximum length is 528 bits, not 521. - int field_size_bytes = NumBitsToBytes( - EC_GROUP_get_degree(EC_KEY_get0_group(private_key_ec.get()))); + int field_size_bytes = + NumBitsToBytes(EC_GROUP_get_degree(EC_KEY_get0_group(private_key_ec))); // If a desired key length was not specified, default to the field size // (rounded up to nearest byte). @@ -115,7 +112,7 @@ derived_bytes->resize(NumBitsToBytes(length_bits)); int result = ECDH_compute_key(derived_bytes->data(), derived_bytes->size(), - public_key_point, private_key_ec.get(), 0); + public_key_point, private_key_ec, 0); if (result < 0 || static_cast<size_t>(result) != derived_bytes->size()) return Status::OperationError();
diff --git a/components/webcrypto/algorithms/ecdsa.cc b/components/webcrypto/algorithms/ecdsa.cc index a77e77d..0b829a8d 100644 --- a/components/webcrypto/algorithms/ecdsa.cc +++ b/components/webcrypto/algorithms/ecdsa.cc
@@ -46,11 +46,11 @@ Status GetEcGroupOrderSize(EVP_PKEY* pkey, size_t* order_size_bytes) { crypto::OpenSSLErrStackTracer err_tracer(FROM_HERE); - crypto::ScopedEC_KEY ec(EVP_PKEY_get1_EC_KEY(pkey)); - if (!ec.get()) + EC_KEY* ec = EVP_PKEY_get0_EC_KEY(pkey); + if (!ec) return Status::ErrorUnexpected(); - const EC_GROUP* group = EC_KEY_get0_group(ec.get()); + const EC_GROUP* group = EC_KEY_get0_group(ec); crypto::ScopedBIGNUM order(BN_new()); if (!EC_GROUP_get_order(group, order.get(), NULL))
diff --git a/components/webcrypto/ec_import_key_raw_fuzzer.cc b/components/webcrypto/ec_import_key_raw_fuzzer.cc new file mode 100644 index 0000000..eeb1a555e --- /dev/null +++ b/components/webcrypto/ec_import_key_raw_fuzzer.cc
@@ -0,0 +1,15 @@ +// Copyright 2016 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 <stddef.h> +#include <stdint.h> + +#include "components/webcrypto/fuzzer_support.h" + +// Entry point for LibFuzzer. +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + webcrypto::ImportEcKeyFromRawFuzzData(data, size); + + return 0; +}
diff --git a/components/webcrypto/fuzzer_support.cc b/components/webcrypto/fuzzer_support.cc index 6b1d4959..4c5efc3 100644 --- a/components/webcrypto/fuzzer_support.cc +++ b/components/webcrypto/fuzzer_support.cc
@@ -7,25 +7,25 @@ #include "base/command_line.h" #include "base/lazy_instance.h" #include "base/numerics/safe_conversions.h" -#include "components/test_runner/test_common.h" #include "components/webcrypto/algorithm_dispatch.h" #include "components/webcrypto/crypto_data.h" #include "components/webcrypto/status.h" +#include "third_party/WebKit/public/platform/Platform.h" #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" +#include "third_party/WebKit/public/web/WebKit.h" namespace webcrypto { namespace { // This mock is used to initialize blink. -class InitOnce { +class InitOnce : NON_EXPORTED_BASE(public blink::Platform) { public: InitOnce() { - // EnsureBlinkInitialized() depends on the command line singleton being - // initialized. base::CommandLine::Init(0, nullptr); - test_runner::EnsureBlinkInitialized(); + blink::Platform::initialize(this); } + ~InitOnce() override {} }; base::LazyInstance<InitOnce>::Leaky g_once = LAZY_INSTANCE_INITIALIZER; @@ -95,6 +95,52 @@ Status::ErrorCreateKeyBadUsages().error_details()); } +void ImportEcKeyFromRawFuzzData(const uint8_t* data, size_t size) { + EnsureInitialized(); + + // There are 3 possible EC named curves. Consume the first byte to decide on + // the curve. + uint8_t curve_index = 0; + if (size > 0) { + curve_index = data[0]; + data++; + size--; + } + + blink::WebCryptoNamedCurve curve; + + switch (curve_index % 3) { + case 0: + curve = blink::WebCryptoNamedCurveP256; + break; + case 1: + curve = blink::WebCryptoNamedCurveP384; + break; + default: + curve = blink::WebCryptoNamedCurveP521; + break; + } + + // Always use ECDSA as the algorithm. Shouldn't make an difference for import. + blink::WebCryptoAlgorithmId algorithm_id = blink::WebCryptoAlgorithmIdEcdsa; + + // Use key usages that are compatible with the chosen algorithm and key type. + blink::WebCryptoKeyUsageMask usages = blink::WebCryptoKeyUsageVerify; + + blink::WebCryptoKey key; + webcrypto::Status status = webcrypto::ImportKey( + blink::WebCryptoKeyFormatRaw, + webcrypto::CryptoData(data, base::checked_cast<uint32_t>(size)), + CreateEcImportAlgorithm(algorithm_id, curve), true, usages, &key); + + // These errors imply a bad setup of parameters, and means ImportKey() may not + // be testing the actual parsing. + DCHECK_NE(status.error_details(), + Status::ErrorUnsupportedImportKeyFormat().error_details()); + DCHECK_NE(status.error_details(), + Status::ErrorCreateKeyBadUsages().error_details()); +} + void ImportRsaKeyFromDerFuzzData(const uint8_t* data, size_t size, blink::WebCryptoKeyFormat format) {
diff --git a/components/webcrypto/fuzzer_support.h b/components/webcrypto/fuzzer_support.h index 43cde78..4ca621b0 100644 --- a/components/webcrypto/fuzzer_support.h +++ b/components/webcrypto/fuzzer_support.h
@@ -16,6 +16,8 @@ size_t size, blink::WebCryptoKeyFormat format); +void ImportEcKeyFromRawFuzzData(const uint8_t* data, size_t size); + void ImportRsaKeyFromDerFuzzData(const uint8_t* data, size_t size, blink::WebCryptoKeyFormat format);
diff --git a/content/DEPS b/content/DEPS index 4bc4a3f..2fd4a2f 100644 --- a/content/DEPS +++ b/content/DEPS
@@ -41,6 +41,7 @@ "+mojo/edk/embedder", "+mojo/edk/js", "+mojo/edk/test", + "+mojo/message_pump", "+mojo/public", "+net", "+ppapi",
diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc index d9e795c..be41018 100644 --- a/content/app/content_main_runner.cc +++ b/content/app/content_main_runner.cc
@@ -467,7 +467,7 @@ // See note at the initialization of ExitManager, below; basically, // only Android builds have the ctor/dtor handlers set up to use // TRACE_EVENT right away. - TRACE_EVENT0("startup,benchmark", "ContentMainRunnerImpl::Initialize"); + TRACE_EVENT0("startup,benchmark,rail", "ContentMainRunnerImpl::Initialize"); #endif // OS_ANDROID base::GlobalDescriptors* g_fds = base::GlobalDescriptors::GetInstance(); @@ -624,7 +624,7 @@ // Android tracing started at the beginning of the method. // Other OSes have to wait till we get here in order for all the memory // management setup to be completed. - TRACE_EVENT0("startup,benchmark", "ContentMainRunnerImpl::Initialize"); + TRACE_EVENT0("startup,benchmark,rail", "ContentMainRunnerImpl::Initialize"); #endif // !OS_ANDROID #if defined(OS_MACOSX)
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 43cc13b..6c463c9 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -84,14 +84,14 @@ "//mojo/public/js", "//net", "//net:extras", + "//services/file:lib", + "//services/file/public/cpp", + "//services/file/public/interfaces", "//services/shell", "//services/shell/public/cpp", "//services/shell/public/interfaces", "//services/shell/runner/common", "//services/shell/runner/host:lib", - "//services/user:lib", - "//services/user/public/cpp", - "//services/user/public/interfaces", "//skia", "//sql", "//storage/browser", @@ -375,7 +375,6 @@ if (use_aura) { deps += [ - "//services/ui/common:mus_common", "//services/ui/public/cpp", "//services/ui/public/interfaces", "//ui/aura",
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index b5b8ccd..0e4e6a81 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -835,6 +835,11 @@ RunHtmlTest(FILE_PATH_LITERAL("footer.html")); } +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, + AccessibilityFooterInsideOtherSection) { + RunHtmlTest(FILE_PATH_LITERAL("footer-inside-other-section.html")); +} + IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityForm) { RunHtmlTest(FILE_PATH_LITERAL("form.html")); } @@ -851,6 +856,11 @@ RunHtmlTest(FILE_PATH_LITERAL("header.html")); } +IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, + AccessibilityHeaderInsideOtherSection) { + RunHtmlTest(FILE_PATH_LITERAL("header-inside-other-section.html")); +} + IN_PROC_BROWSER_TEST_F(DumpAccessibilityTreeTest, AccessibilityHeading) { RunHtmlTest(FILE_PATH_LITERAL("heading.html")); }
diff --git a/content/browser/android/synchronous_compositor_observer.cc b/content/browser/android/synchronous_compositor_observer.cc index c1ed799..bbf7785 100644 --- a/content/browser/android/synchronous_compositor_observer.cc +++ b/content/browser/android/synchronous_compositor_observer.cc
@@ -33,14 +33,14 @@ : render_process_host_(RenderProcessHost::FromID(process_id)), window_android_in_vsync_(nullptr) { DCHECK(render_process_host_); - DCHECK(!ContainsKey(g_instances.Get(), render_process_host_->GetID())); + DCHECK(!base::ContainsKey(g_instances.Get(), render_process_host_->GetID())); g_instances.Get()[render_process_host_->GetID()] = this; render_process_host_->AddObserver(this); } SynchronousCompositorObserver::~SynchronousCompositorObserver() { DCHECK(compositor_host_pending_renderer_state_.empty()); - DCHECK(ContainsKey(g_instances.Get(), render_process_host_->GetID())); + DCHECK(base::ContainsKey(g_instances.Get(), render_process_host_->GetID())); DCHECK_EQ(this, g_instances.Get()[render_process_host_->GetID()]); render_process_host_->RemoveObserver(this); g_instances.Get().erase(render_process_host_->GetID()); @@ -59,8 +59,8 @@ window_android_in_vsync_ == window_android) << !!window_android_in_vsync_; DCHECK(compositor_host); - DCHECK( - !ContainsValue(compositor_host_pending_renderer_state_, compositor_host)); + DCHECK(!base::ContainsValue(compositor_host_pending_renderer_state_, + compositor_host)); compositor_host_pending_renderer_state_.push_back(compositor_host); if (window_android_in_vsync_) return;
diff --git a/content/browser/appcache/appcache.cc b/content/browser/appcache/appcache.cc index 98c9e59..2227197 100644 --- a/content/browser/appcache/appcache.cc +++ b/content/browser/appcache/appcache.cc
@@ -36,8 +36,8 @@ } DCHECK(!owning_group_.get()); storage_->working_set()->RemoveCache(this); - STLDeleteContainerPairSecondPointers( - executable_handlers_.begin(), executable_handlers_.end()); + base::STLDeleteContainerPairSecondPointers(executable_handlers_.begin(), + executable_handlers_.end()); } void AppCache::UnassociateHost(AppCacheHost* host) {
diff --git a/content/browser/appcache/appcache_backend_impl.cc b/content/browser/appcache/appcache_backend_impl.cc index 0ac9bc69..caa0dd59 100644 --- a/content/browser/appcache/appcache_backend_impl.cc +++ b/content/browser/appcache/appcache_backend_impl.cc
@@ -18,7 +18,7 @@ } AppCacheBackendImpl::~AppCacheBackendImpl() { - STLDeleteValues(&hosts_); + base::STLDeleteValues(&hosts_); if (service_) service_->UnregisterBackend(this); }
diff --git a/content/browser/appcache/appcache_service_impl.cc b/content/browser/appcache/appcache_service_impl.cc index 675cf71..fbc0027 100644 --- a/content/browser/appcache/appcache_service_impl.cc +++ b/content/browser/appcache/appcache_service_impl.cc
@@ -415,7 +415,7 @@ FOR_EACH_OBSERVER(Observer, observers_, OnServiceDestructionImminent(this)); for (auto* helper : pending_helpers_) helper->Cancel(); - STLDeleteElements(&pending_helpers_); + base::STLDeleteElements(&pending_helpers_); if (quota_client_) quota_client_->NotifyAppCacheDestroyed();
diff --git a/content/browser/appcache/appcache_storage.cc b/content/browser/appcache/appcache_storage.cc index b710ea2..d5bec16 100644 --- a/content/browser/appcache/appcache_storage.cc +++ b/content/browser/appcache/appcache_storage.cc
@@ -23,7 +23,7 @@ } AppCacheStorage::~AppCacheStorage() { - STLDeleteValues(&pending_info_loads_); + base::STLDeleteValues(&pending_info_loads_); DCHECK(delegate_references_.empty()); }
diff --git a/content/browser/appcache/appcache_update_job.cc b/content/browser/appcache/appcache_update_job.cc index 0913b91..d612dc0a 100644 --- a/content/browser/appcache/appcache_update_job.cc +++ b/content/browser/appcache/appcache_update_job.cc
@@ -435,7 +435,7 @@ DCHECK(!new_master_resource.has_ref()); DCHECK(new_master_resource.GetOrigin() == manifest_url_.GetOrigin()); - if (ContainsKey(failed_master_entries_, new_master_resource)) + if (base::ContainsKey(failed_master_entries_, new_master_resource)) return; // Cannot add more to this update if already terminating.
diff --git a/content/browser/appcache/appcache_update_job_unittest.cc b/content/browser/appcache/appcache_update_job_unittest.cc index d7fae7a..563b0de 100644 --- a/content/browser/appcache/appcache_update_job_unittest.cc +++ b/content/browser/appcache/appcache_update_job_unittest.cc
@@ -3047,8 +3047,8 @@ // Clean up everything that was created on the IO thread. protect_newest_cache_ = NULL; group_ = NULL; - STLDeleteContainerPointers(hosts_.begin(), hosts_.end()); - STLDeleteContainerPointers(frontends_.begin(), frontends_.end()); + base::STLDeleteContainerPointers(hosts_.begin(), hosts_.end()); + base::STLDeleteContainerPointers(frontends_.begin(), frontends_.end()); response_infos_.clear(); service_.reset(NULL);
diff --git a/content/browser/background_sync/background_sync_context.cc b/content/browser/background_sync/background_sync_context.cc index 070a536..6a5166a 100644 --- a/content/browser/background_sync/background_sync_context.cc +++ b/content/browser/background_sync/background_sync_context.cc
@@ -55,7 +55,7 @@ void BackgroundSyncContext::ServiceHadConnectionError( BackgroundSyncServiceImpl* service) { DCHECK_CURRENTLY_ON(BrowserThread::IO); - DCHECK(ContainsValue(services_, service)); + DCHECK(base::ContainsValue(services_, service)); services_.erase(service); delete service; @@ -92,7 +92,7 @@ void BackgroundSyncContext::ShutdownOnIO() { DCHECK_CURRENTLY_ON(BrowserThread::IO); - STLDeleteElements(&services_); + base::STLDeleteElements(&services_); background_sync_manager_.reset(); }
diff --git a/content/browser/bad_message.cc b/content/browser/bad_message.cc index 9e2910f..183b46e7 100644 --- a/content/browser/bad_message.cc +++ b/content/browser/bad_message.cc
@@ -4,11 +4,13 @@ #include "content/browser/bad_message.h" +#include "base/bind.h" #include "base/debug/crash_logging.h" #include "base/logging.h" #include "base/metrics/sparse_histogram.h" #include "base/strings/string_number_conversions.h" #include "content/public/browser/browser_message_filter.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/render_process_host.h" namespace content { @@ -23,6 +25,14 @@ base::IntToString(reason)); } +void ReceivedBadMessageOnUIThread(int render_process_id, + BadMessageReason reason) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + RenderProcessHost* host = RenderProcessHost::FromID(render_process_id); + if (host) + ReceivedBadMessage(host, reason); +} + } // namespace void ReceivedBadMessage(RenderProcessHost* host, BadMessageReason reason) { @@ -30,6 +40,17 @@ host->ShutdownForBadMessage(); } +void ReceivedBadMessage(int render_process_id, BadMessageReason reason) { + if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { + BrowserThread::PostTask( + BrowserThread::UI, + FROM_HERE, + base::Bind(&ReceivedBadMessageOnUIThread, render_process_id, reason)); + return; + } + ReceivedBadMessageOnUIThread(render_process_id, reason); +} + void ReceivedBadMessage(BrowserMessageFilter* filter, BadMessageReason reason) { LogBadMessage(reason); filter->ShutdownForBadMessage();
diff --git a/content/browser/bad_message.h b/content/browser/bad_message.h index c35dfa12..f3e2a8f 100644 --- a/content/browser/bad_message.h +++ b/content/browser/bad_message.h
@@ -112,7 +112,7 @@ SWDH_UPDATE_CANNOT = 88, SWDH_UNREGISTER_BAD_REGISTRATION_ID = 89, BDH_INVALID_WRITE_VALUE_LENGTH = 90, - WC_MEMORY_CACHE_RESOURCE_BAD_SECURITY_INFO = 91, + WC_MEMORY_CACHE_RESOURCE_BAD_SECURITY_INFO = 91, // obsolete; no longer used WC_RENDERER_DID_NAVIGATE_BAD_SECURITY_INFO = 92, OBSOLETE_BDH_DUPLICATE_REQUEST_DEVICE_ID = 93, CSDH_INVALID_ORIGIN = 94, @@ -132,8 +132,8 @@ RDHI_WRONG_STORAGE_PARTITION = 107, RDH_INVALID_REQUEST_ID = 108, BDH_SERVICE_NOT_ALLOWED_FOR_ORIGIN = 109, - WSH_SEND_BLOB_DURING_BLOB_SEND = 110, - WSH_SEND_FRAME_DURING_BLOB_SEND = 111, + WSI_UNEXPECTED_ADD_CHANNEL_REQUEST = 110, + WSI_UNEXPECTED_SEND_FRAME = 111, RFH_UNEXPECTED_LOAD_START = 112, NMF_INVALID_ARGUMENT = 113, RFH_INVALID_ORIGIN_ON_COMMIT = 114, @@ -149,7 +149,7 @@ DBMF_INVALID_ORIGIN_ON_GET_SPACE = 124, DBMF_INVALID_ORIGIN_ON_MODIFIED = 125, DBMF_INVALID_ORIGIN_ON_CLOSED = 126, - WSH_INVALID_HEADER_VALUE = 127, + WSI_INVALID_HEADER_VALUE = 127, SWDH_SET_HOSTED_VERSION_INVALID_HOST = 128, SWDH_SET_HOSTED_VERSION_PROCESS_MISMATCH = 129, MSDH_INVALID_FRAME_ID = 130, @@ -169,6 +169,9 @@ // and terminates the process for |host|. void ReceivedBadMessage(RenderProcessHost* host, BadMessageReason reason); +// Equivalent to the above, but callable from any thread. +void ReceivedBadMessage(int render_process_id, BadMessageReason reason); + // Called when a browser message filter receives a bad IPC message from a // renderer or other child process. Logs the event, records a histogram metric // for the |reason|, and terminates the process for |filter|.
diff --git a/content/browser/bluetooth/bluetooth_allowed_devices_map.cc b/content/browser/bluetooth/bluetooth_allowed_devices_map.cc index b4516642..a340edc 100644 --- a/content/browser/bluetooth/bluetooth_allowed_devices_map.cc +++ b/content/browser/bluetooth/bluetooth_allowed_devices_map.cc
@@ -134,12 +134,12 @@ return id_iter == device_id_to_services_map.end() ? false - : ContainsKey(id_iter->second, service_uuid); + : base::ContainsKey(id_iter->second, service_uuid); } WebBluetoothDeviceId BluetoothAllowedDevicesMap::GenerateUniqueDeviceId() { WebBluetoothDeviceId device_id = WebBluetoothDeviceId::Create(); - while (ContainsKey(device_id_set_, device_id)) { + while (base::ContainsKey(device_id_set_, device_id)) { LOG(WARNING) << "Generated repeated id."; device_id = WebBluetoothDeviceId::Create(); }
diff --git a/content/browser/bluetooth/bluetooth_device_chooser_controller.cc b/content/browser/bluetooth/bluetooth_device_chooser_controller.cc index b2d8792f..b2d6149 100644 --- a/content/browser/bluetooth/bluetooth_device_chooser_controller.cc +++ b/content/browser/bluetooth/bluetooth_device_chooser_controller.cc
@@ -110,7 +110,7 @@ const std::unordered_set<BluetoothUUID, device::BluetoothUUIDHash> device_uuids(device_uuid_list.begin(), device_uuid_list.end()); for (const base::Optional<BluetoothUUID>& service : filter->services) { - if (!ContainsKey(device_uuids, service.value())) { + if (!base::ContainsKey(device_uuids, service.value())) { return false; } } @@ -312,6 +312,7 @@ if (!chooser_.get()) { PostErrorCallback( blink::mojom::WebBluetoothError::WEB_BLUETOOTH_NOT_SUPPORTED); + return; } if (!chooser_->CanAskForScanningPermission()) {
diff --git a/content/browser/bluetooth/web_bluetooth_service_impl.cc b/content/browser/bluetooth/web_bluetooth_service_impl.cc index d559d92..dd558e67 100644 --- a/content/browser/bluetooth/web_bluetooth_service_impl.cc +++ b/content/browser/bluetooth/web_bluetooth_service_impl.cc
@@ -274,7 +274,8 @@ } // Sending get-service responses unexpectedly queued another request. - DCHECK(!ContainsKey(pending_primary_services_requests_, device_address)); + DCHECK( + !base::ContainsKey(pending_primary_services_requests_, device_address)); } void WebBluetoothServiceImpl::GattCharacteristicValueChanged( @@ -282,8 +283,8 @@ device::BluetoothRemoteGattCharacteristic* characteristic, const std::vector<uint8_t>& value) { // Don't notify of characteristics that we haven't returned. - if (!ContainsKey(characteristic_id_to_service_id_, - characteristic->GetIdentifier())) { + if (!base::ContainsKey(characteristic_id_to_service_id_, + characteristic->GetIdentifier())) { return; }
diff --git a/content/browser/browser_context.cc b/content/browser/browser_context.cc index 7cbb5f4..6ca86e7 100644 --- a/content/browser/browser_context.cc +++ b/content/browser/browser_context.cc
@@ -38,12 +38,12 @@ #include "net/ssl/channel_id_store.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" +#include "services/file/file_service.h" +#include "services/file/public/cpp/constants.h" +#include "services/file/user_id_map.h" #include "services/shell/public/cpp/connection.h" #include "services/shell/public/cpp/connector.h" #include "services/shell/public/interfaces/service.mojom.h" -#include "services/user/public/cpp/constants.h" -#include "services/user/user_id_map.h" -#include "services/user/user_shell_client.h" #include "storage/browser/database/database_tracker.h" #include "storage/browser/fileapi/external_mount_points.h" @@ -403,8 +403,8 @@ ShellUserIdHolder* holder = static_cast<ShellUserIdHolder*>( browser_context->GetUserData(kMojoShellUserId)); if (holder) - user_service::ForgetShellUserIdUserDirAssociation(holder->user_id()); - user_service::AssociateShellUserIdWithUserDir(new_id, path); + file::ForgetShellUserIdUserDirAssociation(holder->user_id()); + file::AssociateShellUserIdWithUserDir(new_id, path); RemoveBrowserContextFromUserIdMap(browser_context); g_user_id_to_context.Get()[new_id] = browser_context; browser_context->SetUserData(kMojoShellUserId, @@ -443,10 +443,10 @@ switches::kMojoLocalStorage)) { MojoApplicationInfo info; info.application_factory = - base::Bind(&user_service::CreateUserService, + base::Bind(&file::CreateFileService, BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE), BrowserThread::GetTaskRunnerForThread(BrowserThread::DB)); - connection->AddEmbeddedService(user_service::kUserServiceName, info); + connection->AddEmbeddedService(file::kFileServiceName, info); } } }
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index d6dcc1e..c19822b 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -756,6 +756,14 @@ bool enable_transparent_visuals = !GpuDataManagerImpl::GetInstance()->IsDriverBugWorkaroundActive( gpu::DISABLE_TRANSPARENT_VISUALS); + + // Prevent this flag to be turned off later since it is only used here. + if (!enable_transparent_visuals && + !GpuDataManagerImpl::GetInstance()->IsCompleteGpuInfoAvailable()) { + base::CommandLine::ForCurrentProcess()->AppendSwitch( + "disable_transparent_visuals"); + } + Visual* visual = NULL; int depth = 0; ui::ChooseVisualForWindow(enable_transparent_visuals, &visual, &depth); @@ -826,7 +834,7 @@ } int BrowserMainLoop::CreateThreads() { - TRACE_EVENT0("startup", "BrowserMainLoop::CreateThreads"); + TRACE_EVENT0("startup,rail", "BrowserMainLoop::CreateThreads"); base::Thread::Options io_message_loop_options; io_message_loop_options.message_loop_type = base::MessageLoop::TYPE_IO;
diff --git a/content/browser/cache_storage/cache_storage.cc b/content/browser/cache_storage/cache_storage.cc index 253fc67..1dab242 100644 --- a/content/browser/cache_storage/cache_storage.cc +++ b/content/browser/cache_storage/cache_storage.cc
@@ -196,13 +196,14 @@ void NotifyCacheCreated( const std::string& cache_name, std::unique_ptr<CacheStorageCacheHandle> cache_handle) override { - DCHECK(!ContainsKey(cache_handles_, cache_name)); + DCHECK(!base::ContainsKey(cache_handles_, cache_name)); cache_handles_.insert(std::make_pair(cache_name, std::move(cache_handle))); }; void NotifyCacheDoomed( std::unique_ptr<CacheStorageCacheHandle> cache_handle) override { - DCHECK(ContainsKey(cache_handles_, cache_handle->value()->cache_name())); + DCHECK( + base::ContainsKey(cache_handles_, cache_handle->value()->cache_name())); cache_handles_.erase(cache_handle->value()->cache_name()); }; @@ -238,7 +239,7 @@ std::unique_ptr<CacheStorageCache> CreateCache( const std::string& cache_name) override { DCHECK_CURRENTLY_ON(BrowserThread::IO); - DCHECK(ContainsKey(cache_name_to_cache_dir_, cache_name)); + DCHECK(base::ContainsKey(cache_name_to_cache_dir_, cache_name)); std::string cache_dir = cache_name_to_cache_dir_[cache_name]; base::FilePath cache_path = origin_path_.AppendASCII(cache_dir); @@ -286,7 +287,7 @@ void CleanUpDeletedCache(CacheStorageCache* cache) override { DCHECK_CURRENTLY_ON(BrowserThread::IO); - DCHECK(ContainsKey(doomed_cache_to_path_, cache)); + DCHECK(base::ContainsKey(doomed_cache_to_path_, cache)); base::FilePath cache_path = origin_path_.AppendASCII(doomed_cache_to_path_[cache]); @@ -312,7 +313,7 @@ index.set_origin(origin_.spec()); for (size_t i = 0u, max = cache_names.size(); i < max; ++i) { - DCHECK(ContainsKey(cache_name_to_cache_dir_, cache_names[i])); + DCHECK(base::ContainsKey(cache_name_to_cache_dir_, cache_names[i])); CacheStorageIndex::Cache* index_cache = index.add_cache(); index_cache->set_name(cache_names[i]); @@ -392,8 +393,8 @@ void NotifyCacheDoomed( std::unique_ptr<CacheStorageCacheHandle> cache_handle) override { - DCHECK(ContainsKey(cache_name_to_cache_dir_, - cache_handle->value()->cache_name())); + DCHECK(base::ContainsKey(cache_name_to_cache_dir_, + cache_handle->value()->cache_name())); auto iter = cache_name_to_cache_dir_.find(cache_handle->value()->cache_name()); doomed_cache_to_path_[cache_handle->value()] = iter->second; @@ -414,7 +415,7 @@ std::vector<base::FilePath> dirs_to_delete; base::FilePath cache_path; while (!(cache_path = file_enum.Next()).empty()) { - if (!ContainsKey(*cache_dirs, cache_path.BaseName().AsUTF8Unsafe())) + if (!base::ContainsKey(*cache_dirs, cache_path.BaseName().AsUTF8Unsafe())) dirs_to_delete.push_back(cache_path); } @@ -757,7 +758,7 @@ void CacheStorage::HasCacheImpl(const std::string& cache_name, const BoolAndErrorCallback& callback) { - bool has_cache = ContainsKey(cache_map_, cache_name); + bool has_cache = base::ContainsKey(cache_map_, cache_name); callback.Run(has_cache, CACHE_STORAGE_OK); }
diff --git a/content/browser/cache_storage/cache_storage_dispatcher_host.cc b/content/browser/cache_storage/cache_storage_dispatcher_host.cc index 7d1d229..5b4199e 100644 --- a/content/browser/cache_storage/cache_storage_dispatcher_host.cc +++ b/content/browser/cache_storage/cache_storage_dispatcher_host.cc
@@ -201,7 +201,7 @@ request.headers, request.referrer, request.is_reload)); - if (match_params.cache_name.empty()) { + if (match_params.cache_name.is_null()) { context_->cache_manager()->MatchAllCaches( GURL(origin.Serialize()), std::move(scoped_request), base::Bind(&CacheStorageDispatcherHost::OnCacheStorageMatchCallback, @@ -209,7 +209,8 @@ return; } context_->cache_manager()->MatchCache( - GURL(origin.Serialize()), base::UTF16ToUTF8(match_params.cache_name), + GURL(origin.Serialize()), + base::UTF16ToUTF8(match_params.cache_name.string()), std::move(scoped_request), base::Bind(&CacheStorageDispatcherHost::OnCacheStorageMatchCallback, this, thread_id, request_id));
diff --git a/content/browser/child_process_security_policy_impl.cc b/content/browser/child_process_security_policy_impl.cc index 0def4b5..e9ffa3d 100644 --- a/content/browser/child_process_security_policy_impl.cc +++ b/content/browser/child_process_security_policy_impl.cc
@@ -129,7 +129,7 @@ // Grant certain permissions to a file. void GrantPermissionsForFileSystem(const std::string& filesystem_id, int permissions) { - if (!ContainsKey(filesystem_permissions_, filesystem_id)) + if (!base::ContainsKey(filesystem_permissions_, filesystem_id)) storage::IsolatedContext::GetInstance()->AddReference(filesystem_id); filesystem_permissions_[filesystem_id] |= permissions; } @@ -184,7 +184,7 @@ return scheme_judgment->second; // Otherwise, check for permission for specific origin. - if (ContainsKey(origin_set_, url::Origin(url))) + if (base::ContainsKey(origin_set_, url::Origin(url))) return true; // file:// URLs are more granular. The child may have been given @@ -192,7 +192,7 @@ if (url.SchemeIs(url::kFileScheme)) { base::FilePath path; if (net::FileURLToFilePath(url, &path)) - return ContainsKey(request_file_set_, path); + return base::ContainsKey(request_file_set_, path); } return false; // Unmentioned schemes are disallowed. @@ -313,8 +313,8 @@ ChildProcessSecurityPolicyImpl::~ChildProcessSecurityPolicyImpl() { web_safe_schemes_.clear(); pseudo_schemes_.clear(); - STLDeleteContainerPairSecondPointers(security_state_.begin(), - security_state_.end()); + base::STLDeleteContainerPairSecondPointers(security_state_.begin(), + security_state_.end()); security_state_.clear(); } @@ -364,7 +364,7 @@ const std::string& scheme) { base::AutoLock lock(lock_); - return ContainsKey(web_safe_schemes_, scheme); + return base::ContainsKey(web_safe_schemes_, scheme); } void ChildProcessSecurityPolicyImpl::RegisterPseudoScheme( @@ -381,7 +381,7 @@ const std::string& scheme) { base::AutoLock lock(lock_); - return ContainsKey(pseudo_schemes_, scheme); + return base::ContainsKey(pseudo_schemes_, scheme); } void ChildProcessSecurityPolicyImpl::GrantRequestURL(
diff --git a/content/browser/compositor/DEPS b/content/browser/compositor/DEPS index 562daa27..e40a3bf 100644 --- a/content/browser/compositor/DEPS +++ b/content/browser/compositor/DEPS
@@ -1,6 +1,5 @@ include_rules = [ "+components/display_compositor", - "+services/ui/common", "+services/ui/public/cpp", "+ui/platform_window", ]
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc index c3d27592..334b10c0 100644 --- a/content/browser/compositor/gpu_process_transport_factory.cc +++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -62,7 +62,6 @@ #if defined(USE_AURA) #include "content/browser/compositor/mus_browser_compositor_output_surface.h" #include "content/public/common/mojo_shell_connection.h" -#include "services/ui/common/gpu_service.h" #endif #if defined(OS_WIN)
diff --git a/content/browser/devtools/protocol/color_picker.cc b/content/browser/devtools/protocol/color_picker.cc index 3016caf..5650338 100644 --- a/content/browser/devtools/protocol/color_picker.cc +++ b/content/browser/devtools/protocol/color_picker.cc
@@ -166,7 +166,7 @@ #endif blink::WebScreenInfo screen_info; - view->GetScreenInfo(&screen_info); + host_->GetWebScreenInfo(&screen_info); double device_scale_factor = screen_info.deviceScaleFactor; SkBitmap result;
diff --git a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc index 0c577b65..d29202f 100644 --- a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc +++ b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -652,9 +652,7 @@ std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue()); params->SetString("expression", "window"); SendCommand("Runtime.evaluate", std::move(params), true); - bool wasThrown = true; - EXPECT_TRUE(result_->GetBoolean("wasThrown", &wasThrown)); - EXPECT_FALSE(wasThrown); + EXPECT_FALSE(result_->HasKey("exceptionDetails")); } IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, @@ -667,9 +665,7 @@ std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue()); params->SetString("expression", "window"); SendCommand("Runtime.evaluate", std::move(params), true); - bool wasThrown = true; - EXPECT_TRUE(result_->GetBoolean("wasThrown", &wasThrown)); - EXPECT_FALSE(wasThrown); + EXPECT_FALSE(result_->HasKey("exceptionDetails")); } IN_PROC_BROWSER_TEST_F(DevToolsProtocolTest, JavaScriptDialogNotifications) {
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc index 0e8d29b..f5c5ab2 100644 --- a/content/browser/devtools/protocol/page_handler.cc +++ b/content/browser/devtools/protocol/page_handler.cc
@@ -19,6 +19,7 @@ #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/browser/web_contents/web_contents_impl.h" +#include "content/browser/web_contents/web_contents_view.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/javascript_dialog_manager.h" @@ -318,8 +319,8 @@ if (has_compositor_frame_metadata_) { InnerSwapCompositorFrame(); } else { - widget_host->Send( - new ViewMsg_ForceRedraw(widget_host->GetRoutingID(), 0)); + widget_host->Send(new ViewMsg_ForceRedraw(widget_host->GetRoutingID(), + ui::LatencyInfo())); } } return Response::FallThrough(); @@ -471,7 +472,7 @@ 1 / metadata.device_scale_factor); blink::WebScreenInfo screen_info; - view->GetScreenInfo(&screen_info); + GetWebContents()->GetView()->GetScreenInfo(&screen_info); double device_scale_factor = screen_info.deviceScaleFactor; double scale = 1;
diff --git a/content/browser/devtools/protocol/tethering_handler.cc b/content/browser/devtools/protocol/tethering_handler.cc index 5d07f60a..3f9b8ad 100644 --- a/content/browser/devtools/protocol/tethering_handler.cc +++ b/content/browser/devtools/protocol/tethering_handler.cc
@@ -256,7 +256,7 @@ } TetheringHandler::TetheringImpl::~TetheringImpl() { - STLDeleteValues(&bound_sockets_); + base::STLDeleteValues(&bound_sockets_); } void TetheringHandler::TetheringImpl::Bind(DevToolsCommandId command_id,
diff --git a/content/browser/dom_storage/dom_storage_context_wrapper.cc b/content/browser/dom_storage/dom_storage_context_wrapper.cc index 6c1cef29..9f52d772 100644 --- a/content/browser/dom_storage/dom_storage_context_wrapper.cc +++ b/content/browser/dom_storage/dom_storage_context_wrapper.cc
@@ -27,10 +27,10 @@ #include "content/public/browser/local_storage_usage_info.h" #include "content/public/browser/session_storage_usage_info.h" #include "mojo/common/common_type_converters.h" +#include "services/file/public/cpp/constants.h" +#include "services/file/public/interfaces/file_system.mojom.h" #include "services/shell/public/cpp/connection.h" #include "services/shell/public/cpp/connector.h" -#include "services/user/public/cpp/constants.h" -#include "services/user/public/interfaces/user_service.mojom.h" namespace content { namespace { @@ -100,7 +100,7 @@ void OnUserServiceConnectionComplete() { CHECK_EQ(shell::mojom::ConnectResult::SUCCEEDED, - user_service_connection_->GetResult()); + file_service_connection_->GetResult()); } void OnUserServiceConnectionError() { @@ -129,9 +129,9 @@ CONNECTION_FINISHED } connection_state_; - std::unique_ptr<shell::Connection> user_service_connection_; + std::unique_ptr<shell::Connection> file_service_connection_; - user_service::mojom::UserServicePtr user_service_; + file::mojom::FileSystemPtr file_system_; filesystem::mojom::DirectoryPtr directory_; leveldb::mojom::LevelDBServicePtr leveldb_service_; @@ -149,28 +149,28 @@ // If we don't have a filesystem_connection_, we'll need to establish one. if (connection_state_ == NO_CONNECTION) { CHECK(connector_); - user_service_connection_ = - connector_->Connect(user_service::kUserServiceName); + file_service_connection_ = + connector_->Connect(file::kFileServiceName); connection_state_ = CONNECTION_IN_PROGRESS; - user_service_connection_->AddConnectionCompletedClosure( + file_service_connection_->AddConnectionCompletedClosure( base::Bind(&MojoState::OnUserServiceConnectionComplete, weak_ptr_factory_.GetWeakPtr())); - user_service_connection_->SetConnectionLostClosure( + file_service_connection_->SetConnectionLostClosure( base::Bind(&MojoState::OnUserServiceConnectionError, weak_ptr_factory_.GetWeakPtr())); if (!subdirectory_.empty()) { // We were given a subdirectory to write to. Get it and use a disk backed // database. - user_service_connection_->GetInterface(&user_service_); - user_service_->GetSubDirectory( + file_service_connection_->GetInterface(&file_system_); + file_system_->GetSubDirectory( mojo::String::From(subdirectory_.AsUTF8Unsafe()), GetProxy(&directory_), base::Bind(&MojoState::OnDirectoryOpened, weak_ptr_factory_.GetWeakPtr())); } else { // We were not given a subdirectory. Use a memory backed database. - user_service_connection_->GetInterface(&leveldb_service_); + file_service_connection_->GetInterface(&leveldb_service_); leveldb_service_->OpenInMemory( GetProxy(&database_), base::Bind(&MojoState::OnDatabaseOpened, @@ -200,7 +200,7 @@ // Now that we have a directory, connect to the LevelDB service and get our // database. - user_service_connection_->GetInterface(&leveldb_service_); + file_service_connection_->GetInterface(&leveldb_service_); leveldb_service_->Open( std::move(directory_), "leveldb", GetProxy(&database_), @@ -216,11 +216,10 @@ leveldb_service_.reset(); } - // We no longer need the user service; we've either transferred - // |directory_| to the leveldb service, or we got a file error and no more is - // possible. + // We no longer need the file service; we've either transferred |directory_| + // to the leveldb service, or we got a file error and no more is possible. directory_.reset(); - user_service_.reset(); + file_system_.reset(); // |leveldb_| should be known to either be valid or invalid by now. Run our // delayed bindings.
diff --git a/content/browser/download/download_item_impl_unittest.cc b/content/browser/download/download_item_impl_unittest.cc index a68eca8..578688f 100644 --- a/content/browser/download/download_item_impl_unittest.cc +++ b/content/browser/download/download_item_impl_unittest.cc
@@ -254,7 +254,7 @@ ~DownloadItemTest() { RunAllPendingInMessageLoops(); - STLDeleteElements(&allocated_downloads_); + base::STLDeleteElements(&allocated_downloads_); } DownloadItemImpl* CreateDownloadItemWithCreateInfo(
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc index dd0827e..adf9698 100644 --- a/content/browser/download/download_manager_impl.cc +++ b/content/browser/download/download_manager_impl.cc
@@ -190,7 +190,7 @@ uint32_t id, const DownloadCreateInfo& info) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - DCHECK(!ContainsKey(downloads_, id)); + DCHECK(!base::ContainsKey(downloads_, id)); net::BoundNetLog bound_net_log = net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); DownloadItemImpl* download = @@ -283,7 +283,7 @@ if (download->GetState() == DownloadItem::IN_PROGRESS) download->Cancel(false); } - STLDeleteValues(&downloads_); + base::STLDeleteValues(&downloads_); downloads_by_guid_.clear(); url_downloaders_.clear(); @@ -411,7 +411,7 @@ bool result) { DCHECK_CURRENTLY_ON(BrowserThread::UI); if (!result) { // File does not exist. - if (ContainsKey(downloads_, download_id)) + if (base::ContainsKey(downloads_, download_id)) downloads_[download_id]->OnDownloadedFileRemoved(); } } @@ -442,14 +442,14 @@ uint32_t id) { DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_NE(content::DownloadItem::kInvalidId, id); - DCHECK(!ContainsKey(downloads_, id)); + DCHECK(!base::ContainsKey(downloads_, id)); net::BoundNetLog bound_net_log = net::BoundNetLog::Make(net_log_, net::NetLog::SOURCE_DOWNLOAD); DownloadItemImpl* download_item = item_factory_->CreateSavePageItem( this, id, main_file_path, page_url, mime_type, std::move(request_handle), bound_net_log); downloads_[download_item->GetId()] = download_item; - DCHECK(!ContainsKey(downloads_by_guid_, download_item->GetGuid())); + DCHECK(!base::ContainsKey(downloads_by_guid_, download_item->GetGuid())); downloads_by_guid_[download_item->GetGuid()] = download_item; FOR_EACH_OBSERVER(Observer, observers_, OnDownloadCreated( this, download_item)); @@ -623,11 +623,11 @@ DownloadDangerType danger_type, DownloadInterruptReason interrupt_reason, bool opened) { - if (ContainsKey(downloads_, id)) { + if (base::ContainsKey(downloads_, id)) { NOTREACHED(); return NULL; } - DCHECK(!ContainsKey(downloads_by_guid_, guid)); + DCHECK(!base::ContainsKey(downloads_by_guid_, guid)); DownloadItemImpl* item = item_factory_->CreatePersistedItem( this, guid, id, current_path, target_path, url_chain, referrer_url, site_url, tab_url, tab_refererr_url, mime_type, original_mime_type, @@ -666,14 +666,14 @@ } DownloadItem* DownloadManagerImpl::GetDownload(uint32_t download_id) { - return ContainsKey(downloads_, download_id) ? downloads_[download_id] - : nullptr; + return base::ContainsKey(downloads_, download_id) ? downloads_[download_id] + : nullptr; } DownloadItem* DownloadManagerImpl::GetDownloadByGuid(const std::string& guid) { DCHECK(guid == base::ToUpperASCII(guid)); - return ContainsKey(downloads_by_guid_, guid) ? downloads_by_guid_[guid] - : nullptr; + return base::ContainsKey(downloads_by_guid_, guid) ? downloads_by_guid_[guid] + : nullptr; } void DownloadManagerImpl::GetAllDownloads(DownloadVector* downloads) {
diff --git a/content/browser/download/mhtml_generation_manager.cc b/content/browser/download/mhtml_generation_manager.cc index dc4ef12..f28c86f1c 100644 --- a/content/browser/download/mhtml_generation_manager.cc +++ b/content/browser/download/mhtml_generation_manager.cc
@@ -321,7 +321,7 @@ MHTMLGenerationManager::MHTMLGenerationManager() : next_job_id_(0) {} MHTMLGenerationManager::~MHTMLGenerationManager() { - STLDeleteValues(&id_to_job_); + base::STLDeleteValues(&id_to_job_); } void MHTMLGenerationManager::SaveMHTML(WebContents* web_contents,
diff --git a/content/browser/download/save_file_manager.cc b/content/browser/download/save_file_manager.cc index dc2e1a31c..f70d200 100644 --- a/content/browser/download/save_file_manager.cc +++ b/content/browser/download/save_file_manager.cc
@@ -42,7 +42,7 @@ // Stop file thread operations. void SaveFileManager::OnShutdown() { DCHECK_CURRENTLY_ON(BrowserThread::FILE); - STLDeleteValues(&save_file_map_); + base::STLDeleteValues(&save_file_map_); } SaveFile* SaveFileManager::LookupSaveFile(SaveItemId save_item_id) {
diff --git a/content/browser/download/save_package.cc b/content/browser/download/save_package.cc index 6f6872f63..d37a3f8 100644 --- a/content/browser/download/save_package.cc +++ b/content/browser/download/save_package.cc
@@ -192,10 +192,10 @@ completed_count() + in_process_count()); // Free all SaveItems. - STLDeleteElements(&waiting_item_queue_); - STLDeleteValues(&in_progress_items_); - STLDeleteValues(&saved_success_items_); - STLDeleteValues(&saved_failed_items_); + base::STLDeleteElements(&waiting_item_queue_); + base::STLDeleteValues(&in_progress_items_); + base::STLDeleteValues(&saved_success_items_); + base::STLDeleteValues(&saved_failed_items_); // Clear containers that contain (now dangling/invalid) pointers to the // save items freed above. This is not strictly required (as the containers // will be destructed soon by ~SavePackage), but seems like good code hygiene. @@ -573,7 +573,7 @@ SaveItemIdMap& map = save_item->success() ? saved_success_items_ : saved_failed_items_; - DCHECK(!ContainsKey(map, save_item->id())); + DCHECK(!base::ContainsKey(map, save_item->id())); map[save_item->id()] = save_item; } @@ -783,7 +783,7 @@ waiting_item_queue_.pop_front(); // Add the item to |in_progress_items_|. - DCHECK(!ContainsKey(in_progress_items_, save_item->id())); + DCHECK(!base::ContainsKey(in_progress_items_, save_item->id())); in_progress_items_[save_item->id()] = save_item; save_item->Start(); @@ -1028,7 +1028,7 @@ } } - if (ContainsKey(saved_failed_items_, save_item->id())) + if (base::ContainsKey(saved_failed_items_, save_item->id())) wrote_to_failed_file_ = true; return;
diff --git a/content/browser/file_descriptor_info_impl.cc b/content/browser/file_descriptor_info_impl.cc index 1f33da2..bfab1438 100644 --- a/content/browser/file_descriptor_info_impl.cc +++ b/content/browser/file_descriptor_info_impl.cc
@@ -52,7 +52,7 @@ } bool FileDescriptorInfoImpl::OwnsFD(base::PlatformFile file) const { - return ContainsValue(owned_descriptors_, file); + return base::ContainsValue(owned_descriptors_, file); } base::ScopedFD FileDescriptorInfoImpl::ReleaseFD(base::PlatformFile file) {
diff --git a/content/browser/fileapi/copy_or_move_operation_delegate_unittest.cc b/content/browser/fileapi/copy_or_move_operation_delegate_unittest.cc index 319a5bb..25d65de 100644 --- a/content/browser/fileapi/copy_or_move_operation_delegate_unittest.cc +++ b/content/browser/fileapi/copy_or_move_operation_delegate_unittest.cc
@@ -329,7 +329,7 @@ base::FilePath relative; root.virtual_path().AppendRelativePath(url.virtual_path(), &relative); relative = relative.NormalizePathSeparators(); - ASSERT_TRUE(ContainsKey(test_case_map, relative)); + ASSERT_TRUE(base::ContainsKey(test_case_map, relative)); if (entries[i].is_directory) { EXPECT_TRUE(test_case_map[relative]->is_directory); directories.push(url);
diff --git a/content/browser/find_request_manager_browsertest.cc b/content/browser/find_request_manager_browsertest.cc index b30df8a..d1432d65 100644 --- a/content/browser/find_request_manager_browsertest.cc +++ b/content/browser/find_request_manager_browsertest.cc
@@ -236,25 +236,18 @@ // cross-process. void LoadMultiFramePage(int height, bool cross_process) { LoadAndWait("/find_in_page_multi_frame.html"); - - FrameTreeNode* root = - static_cast<WebContentsImpl*>(shell()->web_contents())-> - GetFrameTree()->root(); - + FrameTreeNode* root = contents()->GetFrameTree()->root(); LoadMultiFramePageChildFrames(height, cross_process, root); } // Reloads the child frame cross-process. void MakeChildFrameCrossProcess() { - FrameTreeNode* root = - static_cast<WebContentsImpl*>(shell()->web_contents())-> - GetFrameTree()->root(); + FrameTreeNode* root = contents()->GetFrameTree()->root(); + FrameTreeNode* child = root->child_at(0); + GURL url(embedded_test_server()->GetURL( + "b.com", child->current_url().path())); TestNavigationObserver observer(shell()->web_contents()); - - FrameTreeNode* child = root->child_at(0); - GURL url(embedded_test_server()->GetURL("b.com", - child->current_url().path())); NavigateFrameToURL(child, url); EXPECT_EQ(url, observer.last_navigation_url()); EXPECT_TRUE(observer.last_navigation_succeeded()); @@ -268,8 +261,8 @@ options); } - WebContents* contents() const { - return shell()->web_contents(); + WebContentsImpl* contents() const { + return static_cast<WebContentsImpl*>(shell()->web_contents()); } TestWebContentsDelegate* delegate() const { @@ -439,9 +432,7 @@ EXPECT_EQ(17, results.active_match_ordinal); // Remove a frame. - FrameTreeNode* root = - static_cast<WebContentsImpl*>(shell()->web_contents())-> - GetFrameTree()->root(); + FrameTreeNode* root = contents()->GetFrameTree()->root(); root->RemoveChild(root->child_at(0)); // The number of matches and active match ordinal should update automatically @@ -468,6 +459,35 @@ EXPECT_EQ(1, results.active_match_ordinal); } +// Tests that new matches can be found in dynamically added text. +IN_PROC_BROWSER_TEST_P(FindRequestManagerTest, MAYBE(FindNewMatches)) { + LoadAndWait("/find_in_dynamic_page.html"); + + blink::WebFindOptions options; + Find("result", options); + options.findNext = true; + Find("result", options); + Find("result", options); + delegate()->WaitForFinalReply(); + + FindResults results = delegate()->GetFindResults(); + EXPECT_EQ(last_request_id(), results.request_id); + EXPECT_EQ(3, results.number_of_matches); + EXPECT_EQ(3, results.active_match_ordinal); + + // Dynamically add new text to the page. This text contains 5 new matches for + // "result". + ASSERT_TRUE(ExecuteScript(contents()->GetMainFrame(), "addNewText()")); + + Find("result", options); + delegate()->WaitForFinalReply(); + + results = delegate()->GetFindResults(); + EXPECT_EQ(last_request_id(), results.request_id); + EXPECT_EQ(8, results.number_of_matches); + EXPECT_EQ(4, results.active_match_ordinal); +} + #if defined(OS_ANDROID) // Tests requesting find match rects. IN_PROC_BROWSER_TEST_F(FindRequestManagerTest, MAYBE(FindMatchRects)) {
diff --git a/content/browser/frame_host/cross_process_frame_connector.cc b/content/browser/frame_host/cross_process_frame_connector.cc index 231bdab..a320bd51 100644 --- a/content/browser/frame_host/cross_process_frame_connector.cc +++ b/content/browser/frame_host/cross_process_frame_connector.cc
@@ -123,13 +123,6 @@ return child_frame_rect_; } -void CrossProcessFrameConnector::GetScreenInfo(blink::WebScreenInfo* results) { - auto* parent_view = GetParentRenderWidgetHostView(); - if (parent_view) { - parent_view->GetScreenInfo(results); - } -} - void CrossProcessFrameConnector::UpdateCursor(const WebCursor& cursor) { RenderWidgetHostViewBase* root_view = GetRootRenderWidgetHostView(); if (root_view)
diff --git a/content/browser/frame_host/cross_process_frame_connector.h b/content/browser/frame_host/cross_process_frame_connector.h index 5111607..a683bd9 100644 --- a/content/browser/frame_host/cross_process_frame_connector.h +++ b/content/browser/frame_host/cross_process_frame_connector.h
@@ -16,7 +16,6 @@ namespace blink { class WebGestureEvent; class WebInputEvent; -struct WebScreenInfo; } namespace cc { @@ -94,7 +93,6 @@ gfx::Rect ChildFrameRect(); float device_scale_factor() const { return device_scale_factor_; } - void GetScreenInfo(blink::WebScreenInfo* results); void UpdateCursor(const WebCursor& cursor); gfx::Point TransformPointToRootCoordSpace(const gfx::Point& point, const cc::SurfaceId& surface_id);
diff --git a/content/browser/frame_host/frame_tree_node_blame_context_unittest.cc b/content/browser/frame_host/frame_tree_node_blame_context_unittest.cc index 7177dab39..83bda69 100644 --- a/content/browser/frame_host/frame_tree_node_blame_context_unittest.cc +++ b/content/browser/frame_host/frame_tree_node_blame_context_unittest.cc
@@ -180,7 +180,7 @@ EXPECT_NE(nullptr, node); if (event->HasArg("snapshot")) { ExpectFrameTreeNodeSnapshot(event); - EXPECT_FALSE(ContainsValue(snapshot_traced, node)); + EXPECT_FALSE(base::ContainsValue(snapshot_traced, node)); snapshot_traced.insert(node); std::string parent_id = GetParentNodeID(event); EXPECT_FALSE(parent_id.empty()); @@ -188,7 +188,7 @@ tree()->FindByID(strtol(parent_id.c_str(), nullptr, 16))); } else { EXPECT_EQ(TRACE_EVENT_PHASE_CREATE_OBJECT, event->phase); - EXPECT_FALSE(ContainsValue(creation_traced, node)); + EXPECT_FALSE(base::ContainsValue(creation_traced, node)); creation_traced.insert(node); } } @@ -229,7 +229,7 @@ for (auto* event : events) { ExpectFrameTreeNodeObject(event); int id = strtol(event->id.c_str(), nullptr, 16); - EXPECT_TRUE(ContainsValue(node_ids, id)); + EXPECT_TRUE(base::ContainsValue(node_ids, id)); node_ids.erase(id); } }
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc index 2b21fd9..1243460 100644 --- a/content/browser/frame_host/navigation_controller_impl.cc +++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -1174,6 +1174,9 @@ // We should only get here for main frame navigations. DCHECK(!rfh->GetParent()); + // TODO(creis): Classify location.replace as NEW_PAGE instead of EXISTING_PAGE + // in https://crbug.com/596707. + NavigationEntryImpl* entry; if (params.intended_as_new_entry) { // This was intended as a new entry but the pending entry was lost in the @@ -1199,38 +1202,24 @@ if (entry->update_virtual_url_with_url()) UpdateVirtualURLToURL(entry, params.url); - // Update the post parameters. - FrameNavigationEntry* frame_entry = - entry->GetFrameEntry(rfh->frame_tree_node()); - frame_entry->set_method(params.method); - frame_entry->set_post_id(params.post_id); + // The site instance will normally be the same except during session restore, + // when no site instance will be assigned. + DCHECK(entry->site_instance() == nullptr || + entry->site_instance() == rfh->GetSiteInstance()); - // If the document sequence number has changed due to redirects or a - // location.replace, then the child FrameNavigationEntries that were there - // before no longer apply. We can leave them around for in-page navigations. - if (frame_entry->document_sequence_number() != - params.document_sequence_number) - entry->ClearChildren(rfh->frame_tree_node()); - - // Update the ISN and DSN in case this was a location.replace, which can cause - // them to change. - // TODO(creis): Classify location.replace as NEW_PAGE instead of EXISTING_PAGE - // in https://crbug.com/596707. - frame_entry->set_item_sequence_number(params.item_sequence_number); - frame_entry->set_document_sequence_number(params.document_sequence_number); + // Update the existing FrameNavigationEntry to ensure all of its members + // reflect the parameters coming from the renderer process. + entry->AddOrUpdateFrameEntry( + rfh->frame_tree_node(), params.item_sequence_number, + params.document_sequence_number, rfh->GetSiteInstance(), nullptr, + params.url, params.referrer, params.page_state, params.method, + params.post_id); // The redirected to page should not inherit the favicon from the previous // page. if (ui::PageTransitionIsRedirect(params.transition)) entry->GetFavicon() = FaviconStatus(); - // The site instance will normally be the same except during session restore, - // when no site instance will be assigned. - DCHECK(entry->site_instance() == nullptr || - entry->site_instance() == rfh->GetSiteInstance()); - entry->set_site_instance( - static_cast<SiteInstanceImpl*>(rfh->GetSiteInstance())); - // The entry we found in the list might be pending if the user hit // back/forward/reload. This load should commit it (since it's already in the // list, we can just discard the pending pointer). We should also discard the @@ -1270,13 +1259,14 @@ if (existing_entry->update_virtual_url_with_url()) UpdateVirtualURLToURL(existing_entry, params.url); existing_entry->SetURL(params.url); - existing_entry->SetReferrer(params.referrer); - // The page may have been requested with a different HTTP method. - FrameNavigationEntry* frame_entry = - existing_entry->GetFrameEntry(rfh->frame_tree_node()); - frame_entry->set_method(params.method); - frame_entry->set_post_id(params.post_id); + // Update the existing FrameNavigationEntry to ensure all of its members + // reflect the parameters coming from the renderer process. + existing_entry->AddOrUpdateFrameEntry( + rfh->frame_tree_node(), params.item_sequence_number, + params.document_sequence_number, rfh->GetSiteInstance(), nullptr, + params.url, params.referrer, params.page_state, params.method, + params.post_id); DiscardNonCommittedEntries(); } @@ -1910,9 +1900,16 @@ new_item->item_sequence_number() != old_item->item_sequence_number() || (new_item->site_instance() != nullptr && new_item->site_instance() != old_item->site_instance())) { + // Same document loads happen if the previous item has the same document + // sequence number. Note that we should treat them as different document if + // the destination RenderFrameHost (which is necessarily the current + // RenderFrameHost for same document navigations) doesn't have a last + // committed page. This case can happen for Ctrl+Back or after a renderer + // crash. if (old_item && new_item->document_sequence_number() == - old_item->document_sequence_number()) { + old_item->document_sequence_number() && + !frame->current_frame_host()->last_committed_url().is_empty()) { same_document_loads->push_back(std::make_pair(frame, new_item)); // TODO(avi, creis): This is a bug; we should not return here. Rather, we
diff --git a/content/browser/frame_host/navigation_controller_impl_browsertest.cc b/content/browser/frame_host/navigation_controller_impl_browsertest.cc index 9007168..5102b79 100644 --- a/content/browser/frame_host/navigation_controller_impl_browsertest.cc +++ b/content/browser/frame_host/navigation_controller_impl_browsertest.cc
@@ -43,6 +43,7 @@ #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/url_request/url_request_failed_job.h" +#include "testing/gmock/include/gmock/gmock-matchers.h" namespace { @@ -66,6 +67,7 @@ void SetUpOnMainThread() override { host_resolver()->AddRule("*", "127.0.0.1"); ASSERT_TRUE(embedded_test_server()->Start()); + content::SetupCrossSiteRedirector(embedded_test_server()); } }; @@ -3738,6 +3740,57 @@ } } +// Ensure that going back/forward to an apparently in-page NavigationEntry works +// when the renderer process hasn't committed anything yet. This can happen +// when using Ctrl+Back or after a crash. See https://crbug.com/635403. +IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, + BackInPageInNewWindow) { + // Start on an initial page. + GURL url_1(embedded_test_server()->GetURL( + "/navigation_controller/simple_page_1.html")); + EXPECT_TRUE(NavigateToURL(shell(), url_1)); + + // Navigate it in-page. + GURL url_2(embedded_test_server()->GetURL( + "/navigation_controller/simple_page_1.html#foo")); + EXPECT_TRUE(NavigateToURL(shell(), url_2)); + + // Clone the tab but don't load last committed page. + std::unique_ptr<WebContentsImpl> new_tab( + static_cast<WebContentsImpl*>(shell()->web_contents()->Clone())); + NavigationController& new_controller = new_tab->GetController(); + EXPECT_TRUE(new_controller.IsInitialNavigation()); + EXPECT_TRUE(new_controller.NeedsReload()); + + // Go back in the new tab. + { + TestNavigationObserver back_load_observer(new_tab.get()); + new_controller.GoBack(); + back_load_observer.Wait(); + } + + // Make sure the new tab isn't still loading. + EXPECT_EQ(url_1, new_controller.GetLastCommittedEntry()->GetURL()); + EXPECT_FALSE(new_tab->IsLoading()); + + // Also check going back in the original tab after a renderer crash. + NavigationController& controller = shell()->web_contents()->GetController(); + RenderProcessHost* process = shell()->web_contents()->GetRenderProcessHost(); + RenderProcessHostWatcher crash_observer( + process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + process->Shutdown(0, false); + crash_observer.Wait(); + { + TestNavigationObserver back_load_observer(shell()->web_contents()); + controller.GoBack(); + back_load_observer.Wait(); + } + + // Make sure the original tab isn't still loading. + EXPECT_EQ(url_1, controller.GetLastCommittedEntry()->GetURL()); + EXPECT_FALSE(shell()->web_contents()->IsLoading()); +} + // Ensures that FrameNavigationEntries for dynamically added iframes can be // found correctly when cloning them during a transfer. If we don't look for // them based on unique name in AddOrUpdateFrameEntry, the FrameTreeNode ID @@ -5708,4 +5761,107 @@ EXPECT_EQ(0U, root->child_count()); } +// Test that navigations classified as SAME_PAGE properly update all the +// members of FrameNavigationEntry. If not, it is possible to get a mismatch +// between the origin and URL of a document as seen in +// https://crbug.com/630103. +IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, + EnsureSamePageNavigationUpdatesFrameNavigationEntry) { + WebContentsImpl* web_contents = + static_cast<WebContentsImpl*>(shell()->web_contents()); + FrameTreeNode* root = web_contents->GetFrameTree()->root(); + + // Navigate to a simple page and then perform an in-page navigation. + GURL start_url(embedded_test_server()->GetURL("a.com", "/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), start_url)); + + GURL same_page_url( + embedded_test_server()->GetURL("a.com", "/title1.html#foo")); + EXPECT_TRUE(NavigateToURL(shell(), same_page_url)); + EXPECT_EQ(2, web_contents->GetController().GetEntryCount()); + + // Replace the URL of the current NavigationEntry with one that will cause + // a server redirect when loaded. + { + GURL redirect_dest_url( + embedded_test_server()->GetURL("sub.a.com", "/simple_page.html")); + TestNavigationObserver observer(web_contents); + std::string script = "history.replaceState({}, '', '/server-redirect?" + + redirect_dest_url.spec() + "')"; + EXPECT_TRUE(ExecuteScript(root, script)); + observer.Wait(); + } + + // Simulate the user hitting Enter in the omnibox without changing the URL. + { + TestNavigationObserver observer(web_contents); + web_contents->GetController().LoadURL(web_contents->GetLastCommittedURL(), + Referrer(), ui::PAGE_TRANSITION_LINK, + std::string()); + observer.Wait(); + } + + // Prior to fixing the issue, the above omnibox navigation (which is + // classified as SAME_PAGE) was leaving the FrameNavigationEntry with the + // same document sequence number as the previous entry but updates the URL. + // Doing a back session history navigation now will cause the browser to + // consider it as in-page because of this matching document sequence number + // and lead to a mismatch of origin and URL in the renderer process. + { + TestNavigationObserver observer(web_contents); + web_contents->GetController().GoBack(); + observer.Wait(); + } + + // Verify the expected origin through JavaScript. It also has the additional + // verification of the process also being still alive. + std::string origin; + EXPECT_TRUE(ExecuteScriptAndExtractString( + web_contents, "domAutomationController.send(document.origin)", &origin)); + EXPECT_EQ(start_url.GetOrigin().spec(), origin + "/"); +} + +// Test that verifies that Referer and Origin http headers are correctly sent +// to the final destination of a cross-site POST with a few redirects thrown in. +// This test is somewhat related to https://crbug.com/635400. +IN_PROC_BROWSER_TEST_F(NavigationControllerBrowserTest, + RefererAndOriginHeadersAfterRedirects) { + // Navigate to the page with form that posts via 307 redirection to + // |redirect_target_url| (cross-site from |form_url|). Using 307 (rather than + // 302) redirection is important to preserve the HTTP method and POST body. + GURL form_url(embedded_test_server()->GetURL( + "a.com", "/form_that_posts_cross_site.html")); + GURL redirect_target_url(embedded_test_server()->GetURL("x.com", "/echoall")); + EXPECT_TRUE(NavigateToURL(shell(), form_url)); + + // Submit the form. The page submitting the form is at 0, and will + // go through 307 redirects from 1 -> 2 and 2 -> 3: + // 0. http://a.com:.../form_that_posts_cross_site.html + // 1. http://a.com:.../cross-site-307/i.com/cross-site-307/x.com/echoall + // 2. http://i.com:.../cross-site-307/x.com/echoall + // 3. http://x.com:.../echoall/ + TestNavigationObserver form_post_observer(shell()->web_contents(), 1); + EXPECT_TRUE( + ExecuteScript(shell(), "document.getElementById('text-form').submit();")); + form_post_observer.Wait(); + + // Verify that we arrived at the expected, redirected location. + EXPECT_EQ(redirect_target_url, + shell()->web_contents()->GetLastCommittedURL()); + + // Get the http request headers. + std::string headers; + EXPECT_TRUE(ExecuteScriptAndExtractString( + shell(), + "window.domAutomationController.send(" + "document.getElementsByTagName('pre')[1].innerText);", + &headers)); + + // Verify the Origin and Referer headers. + EXPECT_THAT(headers, ::testing::HasSubstr("Origin: null")); + EXPECT_THAT(headers, + ::testing::ContainsRegex( + "Referer: http://a.com:.*/form_that_posts_cross_site.html")); +} + } // namespace content
diff --git a/content/browser/frame_host/navigation_entry_impl.cc b/content/browser/frame_host/navigation_entry_impl.cc index 41033a81..e2cdcb8 100644 --- a/content/browser/frame_host/navigation_entry_impl.cc +++ b/content/browser/frame_host/navigation_entry_impl.cc
@@ -774,17 +774,6 @@ const PageState& page_state, const std::string& method, int64_t post_id) { - // We should already have a TreeNode for the parent node by the time this node - // commits. Find it first. - DCHECK(frame_tree_node->parent()); - NavigationEntryImpl::TreeNode* parent_node = - FindFrameEntry(frame_tree_node->parent()); - if (!parent_node) { - // The renderer should not send a commit for a subframe before its parent. - // TODO(creis): Kill the renderer if we get here. - return; - } - // We should only have an empty PageState if the navigation is new, and thus // page ID is -1. if (!page_state.IsValid() && GetPageID() != -1) { @@ -793,6 +782,33 @@ NOTREACHED() << "Shouldn't set an empty PageState."; } + // If this is called for the main frame, the FrameNavigationEntry is + // guaranteed to exist, so just update it directly and return. + if (frame_tree_node->IsMainFrame()) { + // If the document of the FrameNavigationEntry is changing, we must clear + // any child FrameNavigationEntries. + if (root_node()->frame_entry->document_sequence_number() != + document_sequence_number) + root_node()->children.clear(); + + root_node()->frame_entry->UpdateEntry( + frame_tree_node->unique_name(), item_sequence_number, + document_sequence_number, site_instance, + std::move(source_site_instance), url, referrer, page_state, method, + post_id); + return; + } + + // We should already have a TreeNode for the parent node by the time this node + // commits. Find it first. + NavigationEntryImpl::TreeNode* parent_node = + FindFrameEntry(frame_tree_node->parent()); + if (!parent_node) { + // The renderer should not send a commit for a subframe before its parent. + // TODO(creis): Kill the renderer if we get here. + return; + } + // Now check whether we have a TreeNode for the node itself. const std::string& unique_name = frame_tree_node->unique_name(); for (TreeNode* child : parent_node->children) { @@ -830,12 +846,6 @@ return tree_node ? tree_node->frame_entry.get() : nullptr; } -void NavigationEntryImpl::ClearChildren(FrameTreeNode* frame_tree_node) { - NavigationEntryImpl::TreeNode* tree_node = FindFrameEntry(frame_tree_node); - if (tree_node) - tree_node->children.clear(); -} - void NavigationEntryImpl::ClearStaleFrameEntriesForNewFrame( FrameTreeNode* frame_tree_node) { DCHECK(!frame_tree_node->IsMainFrame());
diff --git a/content/browser/frame_host/navigation_entry_impl.h b/content/browser/frame_host/navigation_entry_impl.h index e76f391..04162896b 100644 --- a/content/browser/frame_host/navigation_entry_impl.h +++ b/content/browser/frame_host/navigation_entry_impl.h
@@ -227,11 +227,6 @@ // there is one in this NavigationEntry. FrameNavigationEntry* GetFrameEntry(FrameTreeNode* frame_tree_node) const; - // Removes subframe FrameNavigationEntries below the item corresponding to - // |frame_tree_node| (if any). This is necessary after server redirects - // during session history navigations, when the child items no longer apply. - void ClearChildren(FrameTreeNode* frame_tree_node); - // Removes any subframe FrameNavigationEntries that match the unique name of // |frame_tree_node|, and all of their children. There should be at most one, // since collisions are avoided but leave old FrameNavigationEntries in the
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index ed07b5d..18276c3 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -261,6 +261,14 @@ if (redirect_info.new_method != "POST") common_params_.post_data = nullptr; + // Mark time for the Navigation Timing API. + if (request_params_.navigation_timing.redirect_start.is_null()) { + request_params_.navigation_timing.redirect_start = + request_params_.navigation_timing.fetch_start; + } + request_params_.navigation_timing.redirect_end = base::TimeTicks::Now(); + request_params_.navigation_timing.fetch_start = base::TimeTicks::Now(); + request_params_.redirects.push_back(common_params_.url); common_params_.url = redirect_info.new_url; common_params_.method = redirect_info.new_method; @@ -393,6 +401,9 @@ static_cast<ServiceWorkerContextWrapper*>( partition->GetServiceWorkerContext()); + // Mark the fetch_start (Navigation Timing API). + request_params_.navigation_timing.fetch_start = base::TimeTicks::Now(); + loader_ = NavigationURLLoader::Create( frame_tree_node_->navigator()->GetController()->GetBrowserContext(), std::move(info_), service_worker_context, this);
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index 77f5662..093b902 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc
@@ -313,7 +313,7 @@ // capture the time needed for the RenderFrameHost initialization. base::TimeTicks navigation_start = base::TimeTicks::Now(); TRACE_EVENT_INSTANT_WITH_TIMESTAMP0( - "navigation", "NavigationTiming navigationStart", + "navigation,rail", "NavigationTiming navigationStart", TRACE_EVENT_SCOPE_GLOBAL, navigation_start.ToInternalValue()); // Determine if LoFi should be used for the navigation. @@ -1060,9 +1060,6 @@ SiteInstance* site_instance) { DCHECK(site_instance->HasProcess()); - if (!details.is_in_page) - RecordAction(base::UserMetricsAction("FrameLoad")); - if (!details.is_main_frame || !navigation_data_ || navigation_data_->url_job_start_time_.is_null() || navigation_data_->url_ != params.original_request_url) {
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 7783a26..317829c 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -49,6 +49,7 @@ #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/render_widget_host_view_base.h" #include "content/browser/wake_lock/wake_lock_service_context.h" +#include "content/browser/websockets/websocket_manager.h" #include "content/browser/webui/web_ui_controller_factory_registry.h" #include "content/common/accessibility_messages.h" #include "content/common/frame_messages.h" @@ -2129,6 +2130,14 @@ GetInterfaceRegistry()->AddInterface<media::mojom::ServiceFactory>(this); + // This is to support usage of WebSockets in cases in which there is an + // associated RenderFrame. This is important for showing the correct security + // state of the page and also honoring user override of bad certificates. + GetInterfaceRegistry()->AddInterface( + base::Bind(&WebSocketManager::CreateWebSocket, + process_->GetID(), + routing_id_)); + #if defined(ENABLE_WEBVR) const base::CommandLine& browser_command_line = *base::CommandLine::ForCurrentProcess();
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc index 651c3590..fa53d46 100644 --- a/content/browser/frame_host/render_frame_host_manager.cc +++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -238,10 +238,7 @@ // will add an interface to this RFH's InterfaceRegistry). dest_render_frame_host->SetUpMojoIfNeeded(); - // Recreate the opener chain. - CreateOpenerProxies(dest_render_frame_host->GetSiteInstance(), - frame_tree_node_); - if (!InitRenderView(dest_render_frame_host->render_view_host(), nullptr)) + if (!ReinitializeRenderFrame(dest_render_frame_host)) return nullptr; if (GetNavigatingWebUI()) { @@ -871,10 +868,9 @@ // If the RenderFrame that needs to navigate is not live (its process was just // created or has crashed), initialize it. if (!navigation_rfh->IsRenderFrameLive()) { - // Recreate the opener chain. - CreateOpenerProxies(navigation_rfh->GetSiteInstance(), frame_tree_node_); - if (!InitRenderView(navigation_rfh->render_view_host(), nullptr)) + if (!ReinitializeRenderFrame(navigation_rfh)) return nullptr; + notify_webui_of_rv_creation = true; if (navigation_rfh == render_frame_host_.get()) { @@ -887,7 +883,6 @@ delegate_->NotifyMainFrameSwappedFromRenderManager( nullptr, render_frame_host_->render_view_host()); } - DCHECK(navigation_rfh->IsRenderFrameLive()); } // If a WebUI was created in a speculative RenderFrameHost or a new RenderView @@ -2026,6 +2021,39 @@ previous_sibling_routing_id); } +bool RenderFrameHostManager::ReinitializeRenderFrame( + RenderFrameHostImpl* render_frame_host) { + // This should be used only when the RenderFrame is not live. + DCHECK(!render_frame_host->IsRenderFrameLive()); + + // Recreate the opener chain. + CreateOpenerProxies(render_frame_host->GetSiteInstance(), frame_tree_node_); + + // Main frames need both the RenderView and RenderFrame reinitialized, so + // use InitRenderView. For cross-process subframes, InitRenderView won't + // recreate the RenderFrame, so use InitRenderFrame instead. Note that for + // subframe RenderFrameHosts, the swapped out RenderView in their + // SiteInstance will be recreated as part of CreateOpenerProxies above. + if (!frame_tree_node_->parent()) { + DCHECK(!GetRenderFrameProxyHost(render_frame_host->GetSiteInstance())); + if (!InitRenderView(render_frame_host->render_view_host(), nullptr)) + return false; + } else { + if (!InitRenderFrame(render_frame_host)) + return false; + + // When a subframe renderer dies, its RenderWidgetHostView is cleared in + // its CrossProcessFrameConnector, so we need to restore it now that it + // is re-initialized. + RenderFrameProxyHost* proxy_to_parent = GetProxyToParent(); + if (proxy_to_parent) + GetProxyToParent()->SetChildRWHView(render_frame_host->GetView()); + } + + DCHECK(render_frame_host->IsRenderFrameLive()); + return true; +} + int RenderFrameHostManager::GetRoutingIdForSiteInstance( SiteInstance* site_instance) { if (render_frame_host_->GetSiteInstance() == site_instance) @@ -2145,10 +2173,21 @@ // routing id in the RenderViewHost associated with the old RenderFrameHost // to MSG_ROUTING_NONE. if (is_main_frame) { - render_frame_host_->render_view_host()->set_main_frame_routing_id( - render_frame_host_->routing_id()); - render_frame_host_->render_view_host()->set_is_active(true); - render_frame_host_->render_view_host()->set_is_swapped_out(false); + RenderViewHostImpl* rvh = render_frame_host_->render_view_host(); + rvh->set_main_frame_routing_id(render_frame_host_->routing_id()); + + // If the RenderViewHost is transitioning from swapped out to active state, + // it was reused, so dispatch a RenderViewReady event. For example, this + // is necessary to hide the sad tab if one is currently displayed. See + // https://crbug.com/591984. + // + // TODO(alexmos): Remove this and move RenderViewReady consumers to use + // the main frame's RenderFrameCreated instead. + if (!rvh->is_active()) + rvh->PostRenderViewReady(); + + rvh->set_is_active(true); + rvh->set_is_swapped_out(false); old_render_frame_host->render_view_host()->set_main_frame_routing_id( MSG_ROUTING_NONE); }
diff --git a/content/browser/frame_host/render_frame_host_manager.h b/content/browser/frame_host/render_frame_host_manager.h index 30b96e0..0ffaa0a 100644 --- a/content/browser/frame_host/render_frame_host_manager.h +++ b/content/browser/frame_host/render_frame_host_manager.h
@@ -685,6 +685,11 @@ // above. bool InitRenderFrame(RenderFrameHostImpl* render_frame_host); + // Helper to reinitialize the RenderFrame, RenderView, and the opener chain + // for the provided |render_frame_host|. Used when the |render_frame_host| + // needs to be reused for a new navigation, but it is not live. + bool ReinitializeRenderFrame(RenderFrameHostImpl* render_frame_host); + // Makes the pending WebUI on the current RenderFrameHost active. Call this // when the current RenderFrameHost commits and it has a pending WebUI. void CommitPendingWebUI();
diff --git a/content/browser/frame_host/render_frame_host_manager_browsertest.cc b/content/browser/frame_host/render_frame_host_manager_browsertest.cc index f642981..b4e1d35 100644 --- a/content/browser/frame_host/render_frame_host_manager_browsertest.cc +++ b/content/browser/frame_host/render_frame_host_manager_browsertest.cc
@@ -2768,7 +2768,7 @@ // Ensure that we don't update the wrong NavigationEntry's title after an // ignored commit during a cross-process navigation. -// See https://crbug.con/577449. +// See https://crbug.com/577449. IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, UnloadPushStateOnCrossProcessNavigation) { StartEmbeddedServer(); @@ -2835,4 +2835,46 @@ EXPECT_TRUE(web_contents->GetMainFrame()->IsRenderFrameLive()); } +// Ensure that navigating back from a sad tab to an existing process works +// correctly. See https://crbug.com/591984. +IN_PROC_BROWSER_TEST_F(RenderFrameHostManagerTest, + NavigateBackToExistingProcessFromSadTab) { + StartEmbeddedServer(); + EXPECT_TRUE(NavigateToURL( + shell(), embedded_test_server()->GetURL("a.com", "/title1.html"))); + + // Open a popup and navigate it to b.com. + Shell* popup = OpenPopup( + shell(), embedded_test_server()->GetURL("a.com", "/title2.html"), "foo"); + EXPECT_TRUE(NavigateToURL( + popup, embedded_test_server()->GetURL("b.com", "/title3.html"))); + + // Kill the b.com process. + RenderProcessHost* b_process = + popup->web_contents()->GetMainFrame()->GetProcess(); + RenderProcessHostWatcher crash_observer( + b_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + b_process->Shutdown(0, false); + crash_observer.Wait(); + + // The popup should now be showing the sad tab. Main tab should not be. + EXPECT_NE(base::TERMINATION_STATUS_STILL_RUNNING, + popup->web_contents()->GetCrashedStatus()); + EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING, + shell()->web_contents()->GetCrashedStatus()); + + // Go back in the popup from b.com to a.com/title2.html. + TestNavigationObserver back_observer(popup->web_contents()); + popup->web_contents()->GetController().GoBack(); + back_observer.Wait(); + + // In the bug, after the back navigation the popup was still showing + // the sad tab. Ensure this is not the case. + EXPECT_EQ(base::TERMINATION_STATUS_STILL_RUNNING, + popup->web_contents()->GetCrashedStatus()); + EXPECT_TRUE(popup->web_contents()->GetMainFrame()->IsRenderFrameLive()); + EXPECT_EQ(popup->web_contents()->GetMainFrame()->GetSiteInstance(), + shell()->web_contents()->GetMainFrame()->GetSiteInstance()); +} + } // namespace content
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.cc b/content/browser/frame_host/render_widget_host_view_child_frame.cc index 260eea1c..736d16e9 100644 --- a/content/browser/frame_host/render_widget_host_view_child_frame.cc +++ b/content/browser/frame_host/render_widget_host_view_child_frame.cc
@@ -431,13 +431,6 @@ callback->Run(); } -void RenderWidgetHostViewChildFrame::GetScreenInfo( - blink::WebScreenInfo* results) { - if (!frame_connector_) - return; - frame_connector_->GetScreenInfo(results); -} - gfx::Rect RenderWidgetHostViewChildFrame::GetBoundsInRootWindow() { gfx::Rect rect; if (frame_connector_) {
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.h b/content/browser/frame_host/render_widget_host_view_child_frame.h index e7d11e1..6d51915 100644 --- a/content/browser/frame_host/render_widget_host_view_child_frame.h +++ b/content/browser/frame_host/render_widget_host_view_child_frame.h
@@ -117,7 +117,6 @@ // Since the URL of content rendered by this class is not displayed in // the URL bar, this method does not need an implementation. void ClearCompositorFrame() override {} - void GetScreenInfo(blink::WebScreenInfo* results) override; gfx::Rect GetBoundsInRootWindow() override; void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) override;
diff --git a/content/browser/frame_host/render_widget_host_view_guest.cc b/content/browser/frame_host/render_widget_host_view_guest.cc index 41acb23..9e94364 100644 --- a/content/browser/frame_host/render_widget_host_view_guest.cc +++ b/content/browser/frame_host/render_widget_host_view_guest.cc
@@ -464,14 +464,6 @@ return platform_view_->UnlockMouse(); } -void RenderWidgetHostViewGuest::GetScreenInfo(blink::WebScreenInfo* results) { - if (!guest_) - return; - RenderWidgetHostViewBase* embedder_view = GetOwnerRenderWidgetHostView(); - if (embedder_view) - embedder_view->GetScreenInfo(results); -} - #if defined(OS_MACOSX) void RenderWidgetHostViewGuest::SetActive(bool active) { platform_view_->SetActive(active);
diff --git a/content/browser/frame_host/render_widget_host_view_guest.h b/content/browser/frame_host/render_widget_host_view_guest.h index 338b637d..ff4bd17 100644 --- a/content/browser/frame_host/render_widget_host_view_guest.h +++ b/content/browser/frame_host/render_widget_host_view_guest.h
@@ -105,7 +105,6 @@ bool LockMouse() override; void UnlockMouse() override; - void GetScreenInfo(blink::WebScreenInfo* results) override; #if defined(OS_MACOSX) // RenderWidgetHostView implementation.
diff --git a/content/browser/gamepad/gamepad_service.cc b/content/browser/gamepad/gamepad_service.cc index 86112783..a742cc81 100644 --- a/content/browser/gamepad/gamepad_service.cc +++ b/content/browser/gamepad/gamepad_service.cc
@@ -178,4 +178,8 @@ } } +void GamepadService::SetSanitizationEnabled(bool sanitize) { + provider_->SetSanitizationEnabled(sanitize); +} + } // namespace content
diff --git a/content/browser/gamepad/gamepad_service.h b/content/browser/gamepad/gamepad_service.h index b5c419b..b7d6fbd1 100644 --- a/content/browser/gamepad/gamepad_service.h +++ b/content/browser/gamepad/gamepad_service.h
@@ -106,6 +106,8 @@ int index, const blink::WebGamepad& pad) override; + void SetSanitizationEnabled(bool sanitize); + struct ConsumerInfo { ConsumerInfo(device::GamepadConsumer* consumer) : consumer(consumer), did_observe_user_gesture(false) {}
diff --git a/content/browser/gamepad/gamepad_service_unittest.cc b/content/browser/gamepad/gamepad_service_unittest.cc index 7094345..ea5765d 100644 --- a/content/browser/gamepad/gamepad_service_unittest.cc +++ b/content/browser/gamepad/gamepad_service_unittest.cc
@@ -97,6 +97,7 @@ service_ = new GamepadService( std::unique_ptr<device::GamepadDataFetcher>(fetcher_)); connection_listener_.reset((new ConnectionListener)); + service_->SetSanitizationEnabled(false); service_->ConsumerBecameActive(connection_listener_.get()); }
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.h b/content/browser/gpu/browser_gpu_channel_host_factory.h index 759f936a..64d7c49 100644 --- a/content/browser/gpu/browser_gpu_channel_host_factory.h +++ b/content/browser/gpu/browser_gpu_channel_host_factory.h
@@ -44,6 +44,8 @@ static bool CanUseForTesting(); // Overridden from gpu::GpuChannelEstablishFactory: + // The factory will return a null GpuChannelHost in the callback during + // shutdown. void EstablishGpuChannel( const gpu::GpuChannelEstablishedCallback& callback) override; scoped_refptr<gpu::GpuChannelHost> EstablishGpuChannelSync() override;
diff --git a/content/browser/host_zoom_map_impl.cc b/content/browser/host_zoom_map_impl.cc index edf1f78c..4eab76d5 100644 --- a/content/browser/host_zoom_map_impl.cc +++ b/content/browser/host_zoom_map_impl.cc
@@ -440,14 +440,14 @@ RenderViewKey key(render_process_id, render_view_id); base::AutoLock auto_lock(lock_); - return ContainsKey(temporary_zoom_levels_, key); + return base::ContainsKey(temporary_zoom_levels_, key); } double HostZoomMapImpl::GetTemporaryZoomLevel(int render_process_id, int render_view_id) const { base::AutoLock auto_lock(lock_); RenderViewKey key(render_process_id, render_view_id); - if (!ContainsKey(temporary_zoom_levels_, key)) + if (!base::ContainsKey(temporary_zoom_levels_, key)) return 0; return temporary_zoom_levels_.find(key)->second; @@ -483,7 +483,7 @@ RenderViewKey key(render_process_id, render_view_id); base::AutoLock auto_lock(lock_); - if (ContainsKey(temporary_zoom_levels_, key)) + if (base::ContainsKey(temporary_zoom_levels_, key)) return temporary_zoom_levels_.find(key)->second; return GetZoomLevelForHostAndSchemeInternal(url.scheme(),
diff --git a/content/browser/indexed_db/indexed_db_active_blob_registry.cc b/content/browser/indexed_db/indexed_db_active_blob_registry.cc index 047619c..ea2bde2a 100644 --- a/content/browser/indexed_db/indexed_db_active_blob_registry.cc +++ b/content/browser/indexed_db/indexed_db_active_blob_registry.cc
@@ -26,7 +26,7 @@ DCHECK(backing_store_->task_runner()->RunsTasksOnCurrentThread()); DCHECK(KeyPrefix::IsValidDatabaseId(database_id)); DCHECK(DatabaseMetaDataKey::IsValidBlobKey(blob_key)); - DCHECK(!ContainsKey(deleted_dbs_, database_id)); + DCHECK(!base::ContainsKey(deleted_dbs_, database_id)); bool need_ref = use_tracker_.empty(); SingleDBMap& single_db_map = use_tracker_[database_id]; SingleDBMap::iterator iter = single_db_map.find(blob_key);
diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc index a2dccf46..56543bf 100644 --- a/content/browser/indexed_db/indexed_db_backing_store.cc +++ b/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -770,8 +770,8 @@ for (const auto& pid : child_process_ids_granted_) policy->RevokeAllPermissionsForFile(pid, blob_path_); } - STLDeleteContainerPairSecondPointers(incognito_blob_map_.begin(), - incognito_blob_map_.end()); + base::STLDeleteContainerPairSecondPointers(incognito_blob_map_.begin(), + incognito_blob_map_.end()); // db_'s destructor uses comparator_. The order of destruction is important. db_.reset(); comparator_.reset(); @@ -917,7 +917,8 @@ bool success = false; if (file.IsValid()) { std::string input_js(file_size, '\0'); - if (file_size == file.Read(0, string_as_array(&input_js), file_size)) { + if (file_size == + file.Read(0, base::string_as_array(&input_js), file_size)) { base::JSONReader reader; std::unique_ptr<base::DictionaryValue> val( base::DictionaryValue::From(reader.ReadToValue(input_js))); @@ -4005,10 +4006,10 @@ } IndexedDBBackingStore::Transaction::~Transaction() { - STLDeleteContainerPairSecondPointers( - blob_change_map_.begin(), blob_change_map_.end()); - STLDeleteContainerPairSecondPointers(incognito_blob_map_.begin(), - incognito_blob_map_.end()); + base::STLDeleteContainerPairSecondPointers(blob_change_map_.begin(), + blob_change_map_.end()); + base::STLDeleteContainerPairSecondPointers(incognito_blob_map_.begin(), + incognito_blob_map_.end()); DCHECK(!committing_); }
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc index e6b6bea2..ac8829c9 100644 --- a/content/browser/indexed_db/indexed_db_database.cc +++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -479,7 +479,7 @@ } bool IndexedDBDatabase::ValidateObjectStoreId(int64_t object_store_id) const { - if (!ContainsKey(metadata_.object_stores, object_store_id)) { + if (!base::ContainsKey(metadata_.object_stores, object_store_id)) { DLOG(ERROR) << "Invalid object_store_id"; return false; } @@ -493,7 +493,7 @@ return false; const IndexedDBObjectStoreMetadata& object_store_metadata = metadata_.object_stores.find(object_store_id)->second; - if (!ContainsKey(object_store_metadata.indexes, index_id)) { + if (!base::ContainsKey(object_store_metadata.indexes, index_id)) { DLOG(ERROR) << "Invalid index_id"; return false; } @@ -508,7 +508,7 @@ const IndexedDBObjectStoreMetadata& object_store_metadata = metadata_.object_stores.find(object_store_id)->second; if (index_id != IndexedDBIndexMetadata::kInvalidId && - !ContainsKey(object_store_metadata.indexes, index_id)) { + !base::ContainsKey(object_store_metadata.indexes, index_id)) { DLOG(ERROR) << "Invalid index_id"; return false; } @@ -522,7 +522,7 @@ return false; const IndexedDBObjectStoreMetadata& object_store_metadata = metadata_.object_stores.find(object_store_id)->second; - if (ContainsKey(object_store_metadata.indexes, index_id)) { + if (base::ContainsKey(object_store_metadata.indexes, index_id)) { DLOG(ERROR) << "Invalid index_id"; return false; } @@ -540,7 +540,7 @@ return; DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); - if (ContainsKey(metadata_.object_stores, object_store_id)) { + if (base::ContainsKey(metadata_.object_stores, object_store_id)) { DLOG(ERROR) << "Invalid object_store_id"; return; }
diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host.cc b/content/browser/indexed_db/indexed_db_dispatcher_host.cc index f6e26b5..5db13938 100644 --- a/content/browser/indexed_db/indexed_db_dispatcher_host.cc +++ b/content/browser/indexed_db/indexed_db_dispatcher_host.cc
@@ -260,7 +260,7 @@ blob_data_handle = context->GetBlobDataFromUUID(uuid); } - DCHECK(!ContainsKey(blob_data_handle_map_, uuid)); + DCHECK(!base::ContainsKey(blob_data_handle_map_, uuid)); blob_data_handle_map_[uuid] = std::make_pair(blob_data_handle.release(), 1); return uuid; } @@ -607,7 +607,7 @@ int64_t host_transaction_id = parent_->HostTransactionId(params.transaction_id); - if (ContainsKey(transaction_database_map_, host_transaction_id)) { + if (base::ContainsKey(transaction_database_map_, host_transaction_id)) { DLOG(ERROR) << "Duplicate host_transaction_id."; return; } @@ -911,7 +911,7 @@ int64_t host_transaction_id = parent_->HostTransactionId(transaction_id); // May have been aborted by back end before front-end could request commit. - if (!ContainsKey(transaction_size_map_, host_transaction_id)) + if (!base::ContainsKey(transaction_size_map_, host_transaction_id)) return; int64_t transaction_size = transaction_size_map_[host_transaction_id]; @@ -943,7 +943,7 @@ return; int64_t host_transaction_id = parent_->HostTransactionId(transaction_id); // May have aborted while quota check was pending. - if (!ContainsKey(transaction_size_map_, host_transaction_id)) + if (!base::ContainsKey(transaction_size_map_, host_transaction_id)) return; int64_t transaction_size = transaction_size_map_[host_transaction_id];
diff --git a/content/browser/indexed_db/indexed_db_factory_impl.cc b/content/browser/indexed_db/indexed_db_factory_impl.cc index de072a2..eb112ec 100644 --- a/content/browser/indexed_db/indexed_db_factory_impl.cc +++ b/content/browser/indexed_db/indexed_db_factory_impl.cc
@@ -252,7 +252,7 @@ HandleBackingStoreCorruption(origin, error); return; } - if (!ContainsValue(names, name)) { + if (!base::ContainsValue(names, name)) { const int64_t version = 0; callbacks->OnSuccess(version); backing_store = NULL;
diff --git a/content/browser/indexed_db/indexed_db_observer.h b/content/browser/indexed_db/indexed_db_observer.h index e17b095..2d8f23b7 100644 --- a/content/browser/indexed_db/indexed_db_observer.h +++ b/content/browser/indexed_db/indexed_db_observer.h
@@ -49,7 +49,7 @@ return options_.operation_types[type]; } bool IsRecordingObjectStore(int64_t object_store_id) const { - return ContainsValue(object_store_ids_, object_store_id); + return base::ContainsValue(object_store_ids_, object_store_id); } bool include_transaction() const { return options_.include_transaction; } bool no_records() const { return options_.no_records; }
diff --git a/content/browser/indexed_db/indexed_db_transaction.cc b/content/browser/indexed_db/indexed_db_transaction.cc index 5882276f..6b0df34 100644 --- a/content/browser/indexed_db/indexed_db_transaction.cc +++ b/content/browser/indexed_db/indexed_db_transaction.cc
@@ -477,7 +477,7 @@ const auto& it = std::remove_if( pending_observers_.begin(), pending_observers_.end(), [&pending_observer_ids](const std::unique_ptr<IndexedDBObserver>& o) { - return ContainsValue(pending_observer_ids, o->id()); + return base::ContainsValue(pending_observer_ids, o->id()); }); if (it != pending_observers_.end()) pending_observers_.erase(it, pending_observers_.end());
diff --git a/content/browser/indexed_db/leveldb/leveldb_env.cc b/content/browser/indexed_db/leveldb/leveldb_env.cc index 10c0c070..cdb0a89 100644 --- a/content/browser/indexed_db/leveldb/leveldb_env.cc +++ b/content/browser/indexed_db/leveldb/leveldb_env.cc
@@ -14,9 +14,7 @@ namespace content { -LevelDBEnv::LevelDBEnv() - : ChromiumEnv("LevelDBEnv.IDB", true /* backup tables */) { -} +LevelDBEnv::LevelDBEnv() : ChromiumEnv("LevelDBEnv.IDB") {} LevelDBEnv* LevelDBEnv::Get() { return g_leveldb_env.Pointer();
diff --git a/content/browser/loader/DEPS b/content/browser/loader/DEPS index 672240b..8d4baeb2 100644 --- a/content/browser/loader/DEPS +++ b/content/browser/loader/DEPS
@@ -77,6 +77,42 @@ "+content/browser/loader/resource_handler.h", "+content/common/content_export.h", ], + "mojo_async_resource_handler\.(cc|h)": [ + "-content", + "+content/browser/loader/async_resource_handler.h", + "+content/browser/loader/mojo_async_resource_handler.h", + "+content/browser/loader/test_url_loader_client.h", + "+content/browser/loader/netlog_observer.h", + "+content/browser/loader/resource_dispatcher_host_impl.h", + "+content/browser/loader/resource_handler.h", + "+content/browser/loader/resource_request_info_impl.h", + "+content/common/content_export.h", + "+content/common/resource_request_completion_status.h", + "+content/public/browser/resource_dispatcher_host_delegate.h", + "+content/public/common/resource_response.h", + "+content/common/url_loader.mojom.h", + ], + "mojo_async_resource_handler_unittest\.cc": [ + "-content", + "+content/browser/loader/mojo_async_resource_handler.h", + "+content/browser/loader/test_url_loader_client.h", + "+content/public/browser/navigation_data.h", + "+content/browser/loader/resource_dispatcher_host_impl.h", + "+content/browser/loader/resource_request_info_impl.h", + "+content/common/resource_request.h", + "+content/common/resource_request_completion_status.h", + "+content/common/url_loader.mojom.h", + "+content/public/browser/appcache_service.h", + "+content/public/browser/resource_context.h", + "+content/public/browser/resource_controller.h", + "+content/public/browser/resource_dispatcher_host_delegate.h", + "+content/public/browser/resource_throttle.h", + "+content/public/browser/stream_info.h", + "+content/public/common/resource_response.h", + "+content/public/common/resource_type.h", + "+content/public/test/test_browser_context.h", + "+content/public/test/test_browser_thread_bundle.h", + ], "netlog_observer\.(cc|h)": [ "-content", "+content/browser/loader/netlog_observer.h", @@ -85,7 +121,6 @@ # TODO: These all have to be removed. "+content/public/browser/browser_thread.h", # Only for DCHECK. - "+content/public/browser/content_browser_client.h", # To get NetLog. "+content/public/common/resource_devtools_info.h", ], "power_save_block_resource_throttle\.(cc|h)": [ @@ -100,6 +135,7 @@ "+content/browser/loader/async_revalidation_manager.h", "+content/browser/loader/global_routing_id.h", "+content/browser/loader/loader_delegate.h", + "+content/browser/loader/mojo_async_resource_handler.h", "+content/browser/loader/power_save_block_resource_throttle.h", "+content/browser/loader/resource_dispatcher_host_impl.h", "+content/browser/loader/resource_loader.h", @@ -110,8 +146,10 @@ "+content/browser/loader/stream_resource_handler.h", "+content/browser/loader/sync_resource_handler.h", "+content/browser/loader/throttling_resource_handler.h", + "+content/common/resource_request_body.h", "+content/common/resource_request_body_impl.h", "+content/common/ssl_status_serialization.h", + "+content/common/url_loader.mojom.h", "+content/public/browser/global_request_id.h", "+content/public/browser/resource_dispatcher_host.h", "+content/public/browser/resource_dispatcher_host_delegate.h", @@ -150,7 +188,6 @@ "+content/common/net/url_request_service_worker_data.h", "+content/common/site_isolation_policy.h", "+content/public/browser/browser_thread.h", - "+content/public/browser/content_browser_client.h", "+content/public/browser/plugin_service.h", "+content/public/browser/resource_request_details.h", "+content/public/browser/stream_handle.h", @@ -268,4 +305,40 @@ # TODO: To be replaced by mojo. "+content/common/resource_messages.h", ], + "test_url_loader_client\.(cc|h)": [ + "-content", + "+content/browser/loader/test_url_loader_client.h", + "+content/common/resource_request_completion_status.h", + "+content/common/url_loader.mojom.h", + "+content/public/common/resource_response.h", + ], + "url_loader_factory_impl\.(cc|h)": [ + "-content", + "+content/browser/loader/resource_dispatcher_host_impl.h", + "+content/browser/loader/resource_message_filter.h", + "+content/browser/loader/url_loader_factory_impl.h", + "+content/common/content_export.h", + "+content/common/resource_request.h", + "+content/common/url_loader.mojom.h", + "+content/common/url_loader_factory.mojom.h", + "+content/public/browser/browser_thread.h", + ], + "url_loader_factory_impl_unittest\.cc": [ + "-content", + "+content/browser/loader/mojo_async_resource_handler.h", + "+content/browser/loader/test_url_loader_client.h", + "+content/browser/loader/resource_dispatcher_host_impl.h", + "+content/browser/loader/resource_message_filter.h", + "+content/browser/loader/url_loader_factory_impl.h", + "+content/browser/loader_delegate_impl.h", + "+content/common/resource_request.h", + "+content/common/resource_request_completion_status.h", + "+content/common/url_loader.mojom.h", + "+content/common/url_loader_factory.mojom.h", + "+content/public/browser/resource_context.h", + "+content/public/browser/resource_dispatcher_host_delegate.h", + "+content/public/common/content_paths.h", + "+content/public/test/test_browser_context.h", + "+content/public/test/test_browser_thread_bundle.h", + ], }
diff --git a/content/browser/loader/async_resource_handler.cc b/content/browser/loader/async_resource_handler.cc index 19e0868..4dbe819c 100644 --- a/content/browser/loader/async_resource_handler.cc +++ b/content/browser/loader/async_resource_handler.cc
@@ -308,11 +308,6 @@ *defer = did_defer_ = true; OnDefer(); - if (rdh_->delegate()) { - rdh_->delegate()->OnRequestRedirected( - redirect_info.new_url, request(), info->GetContext(), response); - } - NetLogObserver::PopulateResponseInfo(request(), response); response->head.encoded_data_length = request()->GetTotalReceivedBytes(); reported_transfer_size_ = 0;
diff --git a/content/browser/loader/async_resource_handler_unittest.cc b/content/browser/loader/async_resource_handler_unittest.cc index 7117631f..19e353a6 100644 --- a/content/browser/loader/async_resource_handler_unittest.cc +++ b/content/browser/loader/async_resource_handler_unittest.cc
@@ -144,6 +144,7 @@ void TearDown() override { // Prevent memory leaks. + filter_ = nullptr; rdh_.Shutdown(); base::RunLoop().RunUntilIdle(); } @@ -218,7 +219,8 @@ } void DidStartRequest(ResourceLoader* loader) override {} void DidReceiveRedirect(ResourceLoader* loader, - const GURL& new_url) override {} + const GURL& new_url, + ResourceResponse* response) override {} void DidReceiveResponse(ResourceLoader* loader) override {} void DidFinishLoading(ResourceLoader* loader) override { loader_.reset();
diff --git a/content/browser/loader/mojo_async_resource_handler.cc b/content/browser/loader/mojo_async_resource_handler.cc new file mode 100644 index 0000000..788a67c --- /dev/null +++ b/content/browser/loader/mojo_async_resource_handler.cc
@@ -0,0 +1,400 @@ +// Copyright 2016 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/loader/mojo_async_resource_handler.h" + +#include <utility> + +#include "base/command_line.h" +#include "base/containers/hash_tables.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/strings/string_number_conversions.h" +#include "base/time/time.h" +#include "content/browser/loader/netlog_observer.h" +#include "content/browser/loader/resource_dispatcher_host_impl.h" +#include "content/browser/loader/resource_request_info_impl.h" +#include "content/common/resource_request_completion_status.h" +#include "content/public/browser/resource_dispatcher_host_delegate.h" +#include "content/public/common/resource_response.h" +#include "mojo/public/c/system/data_pipe.h" +#include "mojo/public/cpp/system/data_pipe.h" +#include "net/base/io_buffer.h" +#include "net/base/load_flags.h" +#include "net/base/mime_sniffer.h" +#include "net/log/net_log.h" +#include "net/url_request/redirect_info.h" + +namespace content { +namespace { + +int g_allocation_size = MojoAsyncResourceHandler::kDefaultAllocationSize; + +// MimeTypeResourceHandler *implicitly* requires that the buffer size +// returned from OnWillRead should be larger than certain size. +// TODO(yhirano): Fix MimeTypeResourceHandler. +constexpr size_t kMinAllocationSize = 2 * net::kMaxBytesToSniff; + +constexpr size_t kMaxChunkSize = 32 * 1024; + +void GetNumericArg(const std::string& name, int* result) { + const std::string& value = + base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(name); + if (!value.empty()) + base::StringToInt(value, result); +} + +void InitializeResourceBufferConstants() { + static bool did_init = false; + if (did_init) + return; + did_init = true; + + GetNumericArg("resource-buffer-size", &g_allocation_size); +} + +} // namespace + +// This class is for sharing the ownership of a ScopedDataPipeProducerHandle +// between WriterIOBuffer and MojoAsyncResourceHandler. +class MojoAsyncResourceHandler::SharedWriter final + : public base::RefCountedThreadSafe<SharedWriter> { + public: + explicit SharedWriter(mojo::ScopedDataPipeProducerHandle writer) + : writer_(std::move(writer)) {} + mojo::DataPipeProducerHandle writer() { return writer_.get(); } + + private: + friend class base::RefCountedThreadSafe<SharedWriter>; + ~SharedWriter() {} + + const mojo::ScopedDataPipeProducerHandle writer_; + + DISALLOW_COPY_AND_ASSIGN(SharedWriter); +}; + +// This class is a IOBuffer subclass for data gotten from a +// ScopedDataPipeProducerHandle. +class MojoAsyncResourceHandler::WriterIOBuffer final + : public net::IOBufferWithSize { + public: + // |data| and |size| should be gotten from |writer| via BeginWriteDataRaw. + // They will be accesible via IOBuffer methods. As |writer| is stored in this + // instance, |data| will be kept valid as long as the following conditions + // hold: + // 1. |data| is not invalidated via EndWriteDataRaw. + // 2. |this| instance is alive. + WriterIOBuffer(scoped_refptr<SharedWriter> writer, void* data, size_t size) + : net::IOBufferWithSize(static_cast<char*>(data), size), + writer_(std::move(writer)) {} + + private: + ~WriterIOBuffer() override { + // Avoid deleting |data_| in the IOBuffer destructor. + data_ = nullptr; + } + + // This member is for keeping the writer alive. + scoped_refptr<SharedWriter> writer_; + + DISALLOW_COPY_AND_ASSIGN(WriterIOBuffer); +}; + +MojoAsyncResourceHandler::MojoAsyncResourceHandler( + net::URLRequest* request, + ResourceDispatcherHostImpl* rdh, + mojo::InterfaceRequest<mojom::URLLoader> mojo_request, + mojom::URLLoaderClientPtr url_loader_client) + : ResourceHandler(request), + rdh_(rdh), + binding_(this, std::move(mojo_request)), + url_loader_client_(std::move(url_loader_client)) { + DCHECK(url_loader_client_); + InitializeResourceBufferConstants(); +} + +MojoAsyncResourceHandler::~MojoAsyncResourceHandler() { + if (has_checked_for_sufficient_resources_) + rdh_->FinishedWithResourcesForRequest(request()); +} + +bool MojoAsyncResourceHandler::OnRequestRedirected( + const net::RedirectInfo& redirect_info, + ResourceResponse* response, + bool* defer) { + // Not implemented. + return false; +} + +bool MojoAsyncResourceHandler::OnResponseStarted(ResourceResponse* response, + bool* defer) { + const ResourceRequestInfoImpl* info = GetRequestInfo(); + + if (rdh_->delegate()) { + rdh_->delegate()->OnResponseStarted(request(), info->GetContext(), + response); + } + + NetLogObserver::PopulateResponseInfo(request(), response); + + response->head.request_start = request()->creation_time(); + response->head.response_start = base::TimeTicks::Now(); + sent_received_response_message_ = true; + url_loader_client_->OnReceiveResponse(response->head); + return true; +} + +bool MojoAsyncResourceHandler::OnWillStart(const GURL& url, bool* defer) { + return true; +} + +bool MojoAsyncResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, + int* buf_size, + int min_size) { + DCHECK_EQ(-1, min_size); + + if (!CheckForSufficientResource()) + return false; + + if (!shared_writer_) { + MojoCreateDataPipeOptions options; + options.struct_size = sizeof(MojoCreateDataPipeOptions); + options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE; + options.element_num_bytes = 1; + options.capacity_num_bytes = g_allocation_size; + mojo::DataPipe data_pipe(options); + + url_loader_client_->OnStartLoadingResponseBody( + std::move(data_pipe.consumer_handle)); + if (!data_pipe.producer_handle.is_valid()) + return false; + + shared_writer_ = new SharedWriter(std::move(data_pipe.producer_handle)); + handle_watcher_.Start(shared_writer_->writer(), MOJO_HANDLE_SIGNAL_WRITABLE, + base::Bind(&MojoAsyncResourceHandler::OnWritable, + base::Unretained(this))); + + bool defer = false; + scoped_refptr<net::IOBufferWithSize> buffer; + if (!AllocateWriterIOBuffer(&buffer, &defer)) + return false; + if (!defer) { + if (static_cast<size_t>(buffer->size()) >= kMinAllocationSize) { + *buf = buffer_ = buffer; + *buf_size = buffer_->size(); + return true; + } + + // The allocated buffer is too small. + if (EndWrite(0) != MOJO_RESULT_OK) + return false; + } + DCHECK(!is_using_io_buffer_not_from_writer_); + is_using_io_buffer_not_from_writer_ = true; + buffer_ = new net::IOBufferWithSize(kMinAllocationSize); + } + + DCHECK_EQ(0u, buffer_offset_); + *buf = buffer_; + *buf_size = buffer_->size(); + return true; +} + +bool MojoAsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { + DCHECK_GE(bytes_read, 0); + DCHECK(buffer_); + + if (!bytes_read) + return true; + + if (is_using_io_buffer_not_from_writer_) { + // Couldn't allocate a buffer on the data pipe in OnWillRead. + DCHECK_EQ(0u, buffer_bytes_read_); + buffer_bytes_read_ = bytes_read; + if (!CopyReadDataToDataPipe(defer)) + return false; + if (*defer) + OnDefer(); + return true; + } + + if (EndWrite(bytes_read) != MOJO_RESULT_OK) + return false; + // Allocate a buffer for the next OnWillRead call here, because OnWillRead + // doesn't have |defer| parameter. + if (!AllocateWriterIOBuffer(&buffer_, defer)) + return false; + if (*defer) + OnDefer(); + return true; +} + +void MojoAsyncResourceHandler::OnDataDownloaded(int bytes_downloaded) { + // Not implemented. +} + +void MojoAsyncResourceHandler::FollowRedirect() { + NOTIMPLEMENTED(); +} + +void MojoAsyncResourceHandler::Cancel() { + NOTIMPLEMENTED(); +} + +void MojoAsyncResourceHandler::ResumeForTesting() { + Resume(); +} + +void MojoAsyncResourceHandler::SetAllocationSizeForTesting(size_t size) { + g_allocation_size = size; +} + +MojoResult MojoAsyncResourceHandler::BeginWrite(void** data, + uint32_t* available) { + MojoResult result = mojo::BeginWriteDataRaw( + shared_writer_->writer(), data, available, MOJO_WRITE_DATA_FLAG_NONE); + if (result == MOJO_RESULT_OK) + *available = std::min(*available, static_cast<uint32_t>(kMaxChunkSize)); + return result; +} + +MojoResult MojoAsyncResourceHandler::EndWrite(uint32_t written) { + return mojo::EndWriteDataRaw(shared_writer_->writer(), written); +} + +void MojoAsyncResourceHandler::OnResponseCompleted( + const net::URLRequestStatus& status, + const std::string& security_info, + bool* defer) { + shared_writer_ = nullptr; + buffer_ = nullptr; + handle_watcher_.Cancel(); + + const ResourceRequestInfoImpl* info = GetRequestInfo(); + + // TODO(gavinp): Remove this CHECK when we figure out the cause of + // http://crbug.com/124680 . This check mirrors closely check in + // WebURLLoaderImpl::OnCompletedRequest that routes this message to a WebCore + // ResourceHandleInternal which asserts on its state and crashes. By crashing + // when the message is sent, we should get better crash reports. + CHECK(status.status() != net::URLRequestStatus::SUCCESS || + sent_received_response_message_); + + int error_code = status.error(); + bool was_ignored_by_handler = info->WasIgnoredByHandler(); + + DCHECK_NE(status.status(), net::URLRequestStatus::IO_PENDING); + // If this check fails, then we're in an inconsistent state because all + // requests ignored by the handler should be canceled (which should result in + // the ERR_ABORTED error code). + DCHECK(!was_ignored_by_handler || error_code == net::ERR_ABORTED); + + ResourceRequestCompletionStatus request_complete_data; + request_complete_data.error_code = error_code; + request_complete_data.was_ignored_by_handler = was_ignored_by_handler; + request_complete_data.exists_in_cache = request()->response_info().was_cached; + request_complete_data.security_info = security_info; + request_complete_data.completion_time = base::TimeTicks::Now(); + request_complete_data.encoded_data_length = + request()->GetTotalReceivedBytes(); + + url_loader_client_->OnComplete(request_complete_data); +} + +bool MojoAsyncResourceHandler::CopyReadDataToDataPipe(bool* defer) { + while (true) { + scoped_refptr<net::IOBufferWithSize> dest; + if (!AllocateWriterIOBuffer(&dest, defer)) + return false; + if (*defer) + return true; + if (buffer_bytes_read_ == 0) { + // All bytes are copied. Save the buffer for the next OnWillRead call. + buffer_ = std::move(dest); + return true; + } + + size_t copied_size = + std::min(buffer_bytes_read_, static_cast<size_t>(dest->size())); + memcpy(dest->data(), buffer_->data() + buffer_offset_, copied_size); + buffer_offset_ += copied_size; + buffer_bytes_read_ -= copied_size; + if (EndWrite(copied_size) != MOJO_RESULT_OK) + return false; + + if (buffer_bytes_read_ == 0) { + // All bytes are copied. + buffer_offset_ = 0; + is_using_io_buffer_not_from_writer_ = false; + } + } +} + +bool MojoAsyncResourceHandler::AllocateWriterIOBuffer( + scoped_refptr<net::IOBufferWithSize>* buf, + bool* defer) { + void* data = nullptr; + uint32_t available = 0; + MojoResult result = BeginWrite(&data, &available); + if (result == MOJO_RESULT_SHOULD_WAIT) { + *defer = true; + return true; + } + if (result != MOJO_RESULT_OK) + return false; + *buf = new WriterIOBuffer(shared_writer_, data, available); + return true; +} + +void MojoAsyncResourceHandler::Resume() { + if (!did_defer_) + return; + bool defer = false; + if (is_using_io_buffer_not_from_writer_) { + // |buffer_| is set to a net::IOBufferWithSize. Write the buffer contents + // to the data pipe. + DCHECK_GT(buffer_bytes_read_, 0u); + if (!CopyReadDataToDataPipe(&defer)) { + controller()->CancelWithError(net::ERR_FAILED); + return; + } + } else { + // Allocate a buffer for the next OnWillRead call here. + if (!AllocateWriterIOBuffer(&buffer_, &defer)) { + controller()->CancelWithError(net::ERR_FAILED); + return; + } + } + + if (defer) { + // Continue waiting. + return; + } + did_defer_ = false; + request()->LogUnblocked(); + controller()->Resume(); +} + +void MojoAsyncResourceHandler::OnDefer() { + request()->LogBlockedBy("MojoAsyncResourceHandler"); + did_defer_ = true; +} + +bool MojoAsyncResourceHandler::CheckForSufficientResource() { + if (has_checked_for_sufficient_resources_) + return true; + has_checked_for_sufficient_resources_ = true; + + if (rdh_->HasSufficientResourcesForRequest(request())) + return true; + + controller()->CancelWithError(net::ERR_INSUFFICIENT_RESOURCES); + return false; +} + +void MojoAsyncResourceHandler::OnWritable(MojoResult unused) { + Resume(); +} + +} // namespace content
diff --git a/content/browser/loader/mojo_async_resource_handler.h b/content/browser/loader/mojo_async_resource_handler.h new file mode 100644 index 0000000..1154019 --- /dev/null +++ b/content/browser/loader/mojo_async_resource_handler.h
@@ -0,0 +1,123 @@ +// Copyright 2016 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_LOADER_MOJO_ASYNC_RESOURCE_HANDLER_H_ +#define CONTENT_BROWSER_LOADER_MOJO_ASYNC_RESOURCE_HANDLER_H_ + +#include <stdint.h> + +#include <memory> +#include <string> + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/timer/timer.h" +#include "content/browser/loader/resource_handler.h" +#include "content/common/content_export.h" +#include "content/common/url_loader.mojom.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/system/watcher.h" +#include "net/base/io_buffer.h" +#include "url/gurl.h" + +namespace net { +class URLRequest; +} + +namespace content { +class ResourceDispatcherHostImpl; +class ResourceRequestInfoImpl; +struct ResourceResponse; + +// Used to complete an asynchronous resource request in response to resource +// load events from the resource dispatcher host. This class is used only +// when LoadingWithMojo runtime flag is enabled. +// +// TODO(yhirano): Implement redirects. +// TODO(yhirano): Implement downloading to file. +// TODO(yhirano): Add histograms. +// TODO(yhirano): Set zoom level. +// TODO(yhirano): Send cached metadata. +// +// This class can be inherited only for tests. +class CONTENT_EXPORT MojoAsyncResourceHandler + : public ResourceHandler, + public NON_EXPORTED_BASE(mojom::URLLoader) { + public: + MojoAsyncResourceHandler( + net::URLRequest* request, + ResourceDispatcherHostImpl* rdh, + mojo::InterfaceRequest<mojom::URLLoader> mojo_request, + mojom::URLLoaderClientPtr url_loader_client); + ~MojoAsyncResourceHandler() override; + + // ResourceHandler implementation: + bool OnRequestRedirected(const net::RedirectInfo& redirect_info, + ResourceResponse* response, + bool* defer) override; + bool OnResponseStarted(ResourceResponse* response, bool* defer) override; + bool OnWillStart(const GURL& url, bool* defer) override; + bool OnWillRead(scoped_refptr<net::IOBuffer>* buf, + int* buf_size, + int min_size) override; + bool OnReadCompleted(int bytes_read, bool* defer) override; + void OnResponseCompleted(const net::URLRequestStatus& status, + const std::string& security_info, + bool* defer) override; + void OnDataDownloaded(int bytes_downloaded) override; + + // mojom::URLLoader implementation + void FollowRedirect() override; + void Cancel() override; + + void ResumeForTesting(); + static void SetAllocationSizeForTesting(size_t size); + static constexpr size_t kDefaultAllocationSize = 512 * 1024; + + protected: + // These functions can be overriden only for tests. + virtual MojoResult BeginWrite(void** data, uint32_t* available); + virtual MojoResult EndWrite(uint32_t written); + + private: + class SharedWriter; + class WriterIOBuffer; + + // This funcion copies data stored in |buffer_| to |shared_writer_| and + // resets |buffer_| to a WriterIOBuffer when all bytes are copied. Returns + // true when done successfully. + bool CopyReadDataToDataPipe(bool* defer); + // Allocates a WriterIOBuffer and set it to |*buf|. Returns true when done + // successfully. + bool AllocateWriterIOBuffer(scoped_refptr<net::IOBufferWithSize>* buf, + bool* defer); + + void Resume(); + void OnDefer(); + bool CheckForSufficientResource(); + void OnWritable(MojoResult result); + + ResourceDispatcherHostImpl* rdh_; + mojo::Binding<mojom::URLLoader> binding_; + + bool has_checked_for_sufficient_resources_ = false; + bool sent_received_response_message_ = false; + bool is_using_io_buffer_not_from_writer_ = false; + bool did_defer_ = false; + base::TimeTicks response_started_ticks_; + + mojo::Watcher handle_watcher_; + std::unique_ptr<mojom::URLLoader> url_loader_; + mojom::URLLoaderClientPtr url_loader_client_; + scoped_refptr<net::IOBufferWithSize> buffer_; + size_t buffer_offset_ = 0; + size_t buffer_bytes_read_ = 0; + scoped_refptr<SharedWriter> shared_writer_; + + DISALLOW_COPY_AND_ASSIGN(MojoAsyncResourceHandler); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_LOADER_MOJO_ASYNC_RESOURCE_HANDLER_H_
diff --git a/content/browser/loader/mojo_async_resource_handler_unittest.cc b/content/browser/loader/mojo_async_resource_handler_unittest.cc new file mode 100644 index 0000000..3a642422 --- /dev/null +++ b/content/browser/loader/mojo_async_resource_handler_unittest.cc
@@ -0,0 +1,1151 @@ +// Copyright 2016 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/loader/mojo_async_resource_handler.h" + +#include <string.h> + +#include <utility> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/files/file_path.h" +#include "base/memory/ptr_util.h" +#include "base/memory/scoped_vector.h" +#include "base/memory/weak_ptr.h" +#include "base/run_loop.h" +#include "content/browser/loader/resource_dispatcher_host_impl.h" +#include "content/browser/loader/resource_request_info_impl.h" +#include "content/browser/loader/test_url_loader_client.h" +#include "content/common/resource_request_completion_status.h" +#include "content/common/url_loader.mojom.h" +#include "content/public/browser/appcache_service.h" +#include "content/public/browser/navigation_data.h" +#include "content/public/browser/resource_context.h" +#include "content/public/browser/resource_controller.h" +#include "content/public/browser/resource_dispatcher_host_delegate.h" +#include "content/public/browser/resource_throttle.h" +#include "content/public/browser/stream_info.h" +#include "content/public/common/resource_response.h" +#include "content/public/common/resource_type.h" +#include "content/public/test/test_browser_context.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "mojo/public/c/system/data_pipe.h" +#include "mojo/public/c/system/types.h" +#include "mojo/public/cpp/system/data_pipe.h" +#include "net/base/auth.h" +#include "net/base/net_errors.h" +#include "net/http/http_response_headers.h" +#include "net/http/http_response_info.h" +#include "net/http/http_status_code.h" +#include "net/http/http_util.h" +#include "net/ssl/client_cert_store.h" +#include "net/test/url_request/url_request_failed_job.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_filter.h" +#include "net/url_request/url_request_status.h" +#include "net/url_request/url_request_test_util.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/page_transition_types.h" + +namespace content { +namespace { + +constexpr int kSizeMimeSnifferRequiresForFirstOnWillRead = 2048; + +class TestResourceDispatcherHostDelegate final + : public ResourceDispatcherHostDelegate { + public: + TestResourceDispatcherHostDelegate() = default; + ~TestResourceDispatcherHostDelegate() override { + EXPECT_EQ(num_on_response_started_calls_expectation_, + num_on_response_started_calls_); + } + + bool ShouldBeginRequest(const std::string& method, + const GURL& url, + ResourceType resource_type, + ResourceContext* resource_context) override { + ADD_FAILURE() << "ShouldBeginRequest should not be called."; + return false; + } + + void RequestBeginning(net::URLRequest* request, + ResourceContext* resource_context, + AppCacheService* appcache_service, + ResourceType resource_type, + ScopedVector<ResourceThrottle>* throttles) override { + ADD_FAILURE() << "RequestBeginning should not be called."; + } + + void DownloadStarting(net::URLRequest* request, + ResourceContext* resource_context, + int child_id, + int route_id, + bool is_content_initiated, + bool must_download, + ScopedVector<ResourceThrottle>* throttles) override { + ADD_FAILURE() << "DownloadStarting should not be called."; + } + + ResourceDispatcherHostLoginDelegate* CreateLoginDelegate( + net::AuthChallengeInfo* auth_info, + net::URLRequest* request) override { + ADD_FAILURE() << "CreateLoginDelegate should not be called."; + return nullptr; + } + + bool HandleExternalProtocol( + const GURL& url, + int child_id, + const ResourceRequestInfo::WebContentsGetter& web_contents_getter, + bool is_main_frame, + ui::PageTransition page_transition, + bool has_user_gesture, + ResourceContext* resource_context) override { + ADD_FAILURE() << "HandleExternalProtocol should not be called."; + return false; + } + + bool ShouldForceDownloadResource(const GURL& url, + const std::string& mime_type) override { + ADD_FAILURE() << "ShouldForceDownloadResource should not be called."; + return false; + } + + bool ShouldInterceptResourceAsStream(net::URLRequest* request, + const base::FilePath& plugin_path, + const std::string& mime_type, + GURL* origin, + std::string* payload) override { + ADD_FAILURE() << "ShouldInterceptResourceAsStream should not be called."; + return false; + } + + void OnStreamCreated(net::URLRequest* request, + std::unique_ptr<content::StreamInfo> stream) override { + ADD_FAILURE() << "OnStreamCreated should not be called."; + } + + void OnResponseStarted(net::URLRequest* request, + ResourceContext* resource_context, + ResourceResponse* response) override { + ++num_on_response_started_calls_; + } + + void OnRequestRedirected(const GURL& redirect_url, + net::URLRequest* request, + ResourceContext* resource_context, + ResourceResponse* response) override { + ADD_FAILURE() << "OnRequestRedirected should not be called."; + } + + void RequestComplete(net::URLRequest* url_request) override { + ADD_FAILURE() << "RequestComplete should not be called."; + } + + bool ShouldEnableLoFiMode( + const net::URLRequest& url_request, + content::ResourceContext* resource_context) override { + ADD_FAILURE() << "ShouldEnableLoFiMode should not be called."; + return false; + } + + NavigationData* GetNavigationData(net::URLRequest* request) const override { + ADD_FAILURE() << "GetNavigationData should not be called."; + return nullptr; + } + + std::unique_ptr<net::ClientCertStore> CreateClientCertStore( + ResourceContext* resource_context) override { + ADD_FAILURE() << "CreateClientCertStore should not be called."; + return nullptr; + } + + int num_on_response_started_calls() const { + return num_on_response_started_calls_; + } + void set_num_on_response_started_calls_expectation(int expectation) { + num_on_response_started_calls_expectation_ = expectation; + } + + private: + int num_on_response_started_calls_ = 0; + int num_on_response_started_calls_expectation_ = 0; + + DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherHostDelegate); +}; + +class TestResourceController : public ResourceController { + public: + TestResourceController() {} + ~TestResourceController() override {} + + void Cancel() override { ADD_FAILURE() << "Cancel should not be called."; } + + void CancelAndIgnore() override { + ADD_FAILURE() << "CancelAndIgnore should not be called."; + } + + void CancelWithError(int error_code) override { + is_cancel_with_error_called_ = true; + error_ = error_code; + if (quit_closure_) + quit_closure_.Run(); + } + + void Resume() override { ++num_resume_calls_; } + + void RunUntilCancelWithErrorCalled() { + base::RunLoop run_loop; + quit_closure_ = run_loop.QuitClosure(); + run_loop.Run(); + } + + void set_quit_closure(const base::Closure& quit_closure) { + quit_closure_ = quit_closure; + } + + bool is_cancel_with_error_called() const { + return is_cancel_with_error_called_; + } + int error() const { return error_; } + int num_resume_calls() const { return num_resume_calls_; } + + private: + bool is_cancel_with_error_called_ = false; + int error_ = net::OK; + int num_resume_calls_ = 0; + base::Closure quit_closure_; + + DISALLOW_COPY_AND_ASSIGN(TestResourceController); +}; + +class MojoAsyncResourceHandlerWithCustomDataPipeOperations + : public MojoAsyncResourceHandler { + public: + MojoAsyncResourceHandlerWithCustomDataPipeOperations( + net::URLRequest* request, + ResourceDispatcherHostImpl* rdh, + mojo::InterfaceRequest<mojom::URLLoader> mojo_request, + mojom::URLLoaderClientPtr url_loader_client) + : MojoAsyncResourceHandler(request, + rdh, + std::move(mojo_request), + std::move(url_loader_client)) {} + ~MojoAsyncResourceHandlerWithCustomDataPipeOperations() override {} + + void ResetBeginWriteExpectation() { is_begin_write_expectation_set_ = false; } + + void set_begin_write_expectation(MojoResult begin_write_expectation) { + is_begin_write_expectation_set_ = true; + begin_write_expectation_ = begin_write_expectation; + } + void set_end_write_expectation(MojoResult end_write_expectation) { + is_end_write_expectation_set_ = true; + end_write_expectation_ = end_write_expectation; + } + + private: + MojoResult BeginWrite(void** data, uint32_t* available) override { + if (is_begin_write_expectation_set_) + return begin_write_expectation_; + return MojoAsyncResourceHandler::BeginWrite(data, available); + } + MojoResult EndWrite(uint32_t written) override { + if (is_end_write_expectation_set_) + return end_write_expectation_; + return MojoAsyncResourceHandler::EndWrite(written); + } + + bool is_begin_write_expectation_set_ = false; + bool is_end_write_expectation_set_ = false; + MojoResult begin_write_expectation_ = MOJO_RESULT_UNKNOWN; + MojoResult end_write_expectation_ = MOJO_RESULT_UNKNOWN; + + DISALLOW_COPY_AND_ASSIGN( + MojoAsyncResourceHandlerWithCustomDataPipeOperations); +}; + +class MojoAsyncResourceHandlerTestBase { + public: + MojoAsyncResourceHandlerTestBase() + : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP), + browser_context_(new TestBrowserContext()) { + MojoAsyncResourceHandler::SetAllocationSizeForTesting(32 * 1024); + rdh_.SetDelegate(&rdh_delegate_); + + url_request_delegate_.reset(new net::TestDelegate()); + net::URLRequestContext* request_context = + browser_context_->GetResourceContext()->GetRequestContext(); + request_ = request_context->CreateRequest( + net::URLRequestFailedJob::GetMockHttpUrl(net::ERR_TIMED_OUT), + net::DEFAULT_PRIORITY, url_request_delegate_.get()); + ResourceRequestInfo::AllocateForTesting( + request_.get(), // request + RESOURCE_TYPE_XHR, // resource_type + browser_context_->GetResourceContext(), // context + 2, // render_process_id + 0, // render_view_id + 0, // render_frame_id + true, // is_main_frame + false, // parent_is_main_frame + false, // allow_download + true, // is_async + false // is_using_lofi + ); + handler_.reset(new MojoAsyncResourceHandlerWithCustomDataPipeOperations( + request_.get(), &rdh_, nullptr, + url_loader_client_.CreateInterfacePtrAndBind())); + handler_->SetController(&resource_controller_); + } + + virtual ~MojoAsyncResourceHandlerTestBase() { + net::URLRequestFilter::GetInstance()->ClearHandlers(); + MojoAsyncResourceHandler::SetAllocationSizeForTesting( + MojoAsyncResourceHandler::kDefaultAllocationSize); + base::RunLoop().RunUntilIdle(); + } + + // Returns false if something bad happens. + bool CallOnWillStart() { + bool defer = false; + if (!handler_->OnWillStart(request_->url(), &defer)) { + ADD_FAILURE() << "OnWillStart returns false."; + return false; + } + if (defer) { + ADD_FAILURE() << "OnWillStart sets |defer| true."; + return false; + } + return true; + } + + // Returns false if something bad happens. + bool CallOnWillStartAndOnResponseStarted() { + rdh_delegate_.set_num_on_response_started_calls_expectation(1); + if (!CallOnWillStart()) + return false; + + scoped_refptr<ResourceResponse> response = new ResourceResponse(); + bool defer = false; + if (!handler_->OnResponseStarted(response.get(), &defer)) { + ADD_FAILURE() << "OnResponseStarted returns false."; + return false; + } + if (defer) { + ADD_FAILURE() << "OnResponseStarted sets |defer| true."; + return false; + } + if (url_loader_client_.has_received_response()) { + ADD_FAILURE() << "URLLoaderClient unexpectedly gets a response."; + return false; + } + url_loader_client_.RunUntilResponseReceived(); + return true; + } + + TestBrowserThreadBundle thread_bundle_; + TestResourceDispatcherHostDelegate rdh_delegate_; + ResourceDispatcherHostImpl rdh_; + TestURLLoaderClient url_loader_client_; + TestResourceController resource_controller_; + std::unique_ptr<TestBrowserContext> browser_context_; + std::unique_ptr<net::TestDelegate> url_request_delegate_; + std::unique_ptr<net::URLRequest> request_; + std::unique_ptr<MojoAsyncResourceHandlerWithCustomDataPipeOperations> + handler_; + + DISALLOW_COPY_AND_ASSIGN(MojoAsyncResourceHandlerTestBase); +}; + +class MojoAsyncResourceHandlerTest : public MojoAsyncResourceHandlerTestBase, + public ::testing::Test {}; + +// This test class is parameterized with MojoAsyncResourceHandler's allocation +// size. +class MojoAsyncResourceHandlerWithAllocationSizeTest + : public MojoAsyncResourceHandlerTestBase, + public ::testing::TestWithParam<size_t> { + protected: + MojoAsyncResourceHandlerWithAllocationSizeTest() { + MojoAsyncResourceHandler::SetAllocationSizeForTesting(GetParam()); + } +}; + +TEST_F(MojoAsyncResourceHandlerTest, InFlightRequests) { + EXPECT_EQ(0, rdh_.num_in_flight_requests_for_testing()); + handler_ = nullptr; + EXPECT_EQ(0, rdh_.num_in_flight_requests_for_testing()); +} + +TEST_F(MojoAsyncResourceHandlerTest, OnWillStart) { + bool defer = false; + EXPECT_TRUE(handler_->OnWillStart(request_->url(), &defer)); + EXPECT_FALSE(defer); +} + +TEST_F(MojoAsyncResourceHandlerTest, OnResponseStarted) { + rdh_delegate_.set_num_on_response_started_calls_expectation(1); + ASSERT_TRUE(CallOnWillStart()); + + scoped_refptr<ResourceResponse> response = new ResourceResponse(); + response->head.content_length = 99; + response->head.request_start = + base::TimeTicks::UnixEpoch() + base::TimeDelta::FromDays(14); + response->head.response_start = + base::TimeTicks::UnixEpoch() + base::TimeDelta::FromDays(28); + + bool defer = false; + + EXPECT_EQ(0, rdh_delegate_.num_on_response_started_calls()); + base::TimeTicks now1 = base::TimeTicks::Now(); + ASSERT_TRUE(handler_->OnResponseStarted(response.get(), &defer)); + base::TimeTicks now2 = base::TimeTicks::Now(); + + EXPECT_FALSE(defer); + EXPECT_EQ(request_->creation_time(), response->head.request_start); + EXPECT_LE(now1, response->head.response_start); + EXPECT_LE(response->head.response_start, now2); + EXPECT_EQ(1, rdh_delegate_.num_on_response_started_calls()); + + url_loader_client_.RunUntilResponseReceived(); + EXPECT_EQ(response->head.request_start, + url_loader_client_.response_head().request_start); + EXPECT_EQ(response->head.response_start, + url_loader_client_.response_head().response_start); + EXPECT_EQ(99, url_loader_client_.response_head().content_length); +} + +TEST_F(MojoAsyncResourceHandlerTest, OnWillReadAndInFlightRequests) { + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + EXPECT_EQ(0, rdh_.num_in_flight_requests_for_testing()); + scoped_refptr<net::IOBuffer> io_buffer; + int io_buffer_size = 0; + EXPECT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + EXPECT_EQ(1, rdh_.num_in_flight_requests_for_testing()); + handler_ = nullptr; + EXPECT_EQ(0, rdh_.num_in_flight_requests_for_testing()); +} + +TEST_F(MojoAsyncResourceHandlerTest, OnWillReadWithInsufficientResource) { + rdh_.set_max_num_in_flight_requests_per_process(0); + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + + scoped_refptr<net::IOBuffer> io_buffer; + int io_buffer_size = 0; + EXPECT_FALSE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + EXPECT_FALSE(io_buffer); + EXPECT_EQ(0, io_buffer_size); + EXPECT_EQ(1, rdh_.num_in_flight_requests_for_testing()); + EXPECT_TRUE(resource_controller_.is_cancel_with_error_called()); + EXPECT_EQ(net::ERR_INSUFFICIENT_RESOURCES, resource_controller_.error()); + handler_ = nullptr; + EXPECT_EQ(0, rdh_.num_in_flight_requests_for_testing()); +} + +TEST_F(MojoAsyncResourceHandlerTest, OnWillReadAndOnReadCompleted) { + bool defer = false; + scoped_refptr<net::IOBuffer> io_buffer; + int io_buffer_size = 0; + + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + ASSERT_TRUE(io_buffer); + // The buffer size that the mime sniffer requires implicitly. + ASSERT_GE(io_buffer_size, kSizeMimeSnifferRequiresForFirstOnWillRead); + + url_loader_client_.RunUntilResponseBodyArrived(); + ASSERT_TRUE(url_loader_client_.response_body().is_valid()); + + io_buffer->data()[0] = 'A'; + io_buffer->data()[1] = 'B'; + ASSERT_TRUE(handler_->OnReadCompleted(2, &defer)); + EXPECT_FALSE(defer); + + std::string contents; + while (contents.size() < 2) { + char buffer[16]; + uint32_t read_size = sizeof(buffer); + MojoResult result = + mojo::ReadDataRaw(url_loader_client_.response_body(), buffer, + &read_size, MOJO_READ_DATA_FLAG_NONE); + if (result == MOJO_RESULT_SHOULD_WAIT) { + base::RunLoop().RunUntilIdle(); + continue; + } + contents.append(buffer, read_size); + } + EXPECT_EQ("AB", contents); +} + +TEST_F(MojoAsyncResourceHandlerTest, + OnWillReadAndOnReadCompletedWithInsufficientInitialCapacity) { + MojoAsyncResourceHandler::SetAllocationSizeForTesting(2); + + bool defer = false; + scoped_refptr<net::IOBuffer> io_buffer; + int io_buffer_size = 0; + + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + ASSERT_TRUE(io_buffer); + // The buffer size that the mime sniffer requires implicitly. + ASSERT_GE(io_buffer_size, kSizeMimeSnifferRequiresForFirstOnWillRead); + + url_loader_client_.RunUntilResponseBodyArrived(); + ASSERT_TRUE(url_loader_client_.response_body().is_valid()); + + const std::string data("abcdefgh"); + strcpy(io_buffer->data(), data.c_str()); + ASSERT_TRUE(handler_->OnReadCompleted(data.size(), &defer)); + EXPECT_TRUE(defer); + + std::string contents; + while (contents.size() < data.size()) { + // This is needed for Resume to be called. + base::RunLoop().RunUntilIdle(); + char buffer[16]; + uint32_t read_size = sizeof(buffer); + MojoResult result = + mojo::ReadDataRaw(url_loader_client_.response_body(), buffer, + &read_size, MOJO_READ_DATA_FLAG_NONE); + if (result == MOJO_RESULT_SHOULD_WAIT) + continue; + ASSERT_EQ(MOJO_RESULT_OK, result); + contents.append(buffer, read_size); + } + EXPECT_EQ(data, contents); + EXPECT_EQ(0, resource_controller_.num_resume_calls()); +} + +TEST_F(MojoAsyncResourceHandlerTest, + IOBufferFromOnWillReadShouldRemainValidEvenIfHandlerIsGone) { + scoped_refptr<net::IOBuffer> io_buffer; + int io_buffer_size = 0; + + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + ASSERT_TRUE(io_buffer); + // The io_buffer size that the mime sniffer requires implicitly. + ASSERT_GE(io_buffer_size, kSizeMimeSnifferRequiresForFirstOnWillRead); + + handler_ = nullptr; + url_loader_client_.Unbind(); + base::RunLoop().RunUntilIdle(); + + // Hopefully ASAN checks this operation's validity. + io_buffer->data()[0] = 'A'; +} + +TEST_F(MojoAsyncResourceHandlerTest, OnResponseCompleted) { + bool defer = false; + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + + ResourceRequestInfoImpl::ForRequest(request_.get()) + ->set_was_ignored_by_handler(false); + net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, net::OK); + std::string security_info = "info0"; + + base::TimeTicks now1 = base::TimeTicks::Now(); + handler_->OnResponseCompleted(status, security_info, &defer); + base::TimeTicks now2 = base::TimeTicks::Now(); + EXPECT_FALSE(defer); + + url_loader_client_.RunUntilComplete(); + EXPECT_TRUE(url_loader_client_.has_received_completion()); + EXPECT_EQ(net::OK, url_loader_client_.completion_status().error_code); + EXPECT_FALSE(url_loader_client_.completion_status().was_ignored_by_handler); + EXPECT_EQ("info0", url_loader_client_.completion_status().security_info); + EXPECT_LE(now1, url_loader_client_.completion_status().completion_time); + EXPECT_LE(url_loader_client_.completion_status().completion_time, now2); + EXPECT_EQ(request_->GetTotalReceivedBytes(), + url_loader_client_.completion_status().encoded_data_length); +} + +// This test case sets different status values from OnResponseCompleted. +TEST_F(MojoAsyncResourceHandlerTest, OnResponseCompleted2) { + rdh_.SetDelegate(nullptr); + bool defer = false; + // Don't use CallOnWillStartAndOnResponseStarted as this test case manually + // sets the null delegate. + ASSERT_TRUE(CallOnWillStart()); + scoped_refptr<ResourceResponse> response = new ResourceResponse(); + ASSERT_TRUE(handler_->OnResponseStarted(response.get(), &defer)); + ASSERT_FALSE(defer); + ASSERT_FALSE(url_loader_client_.has_received_response()); + url_loader_client_.RunUntilResponseReceived(); + + ResourceRequestInfoImpl::ForRequest(request_.get()) + ->set_was_ignored_by_handler(true); + net::URLRequestStatus status(net::URLRequestStatus::CANCELED, + net::ERR_ABORTED); + std::string security_info = "info1"; + + base::TimeTicks now1 = base::TimeTicks::Now(); + handler_->OnResponseCompleted(status, security_info, &defer); + base::TimeTicks now2 = base::TimeTicks::Now(); + EXPECT_FALSE(defer); + + url_loader_client_.RunUntilComplete(); + EXPECT_TRUE(url_loader_client_.has_received_completion()); + EXPECT_EQ(net::ERR_ABORTED, + url_loader_client_.completion_status().error_code); + EXPECT_TRUE(url_loader_client_.completion_status().was_ignored_by_handler); + EXPECT_EQ("info1", url_loader_client_.completion_status().security_info); + EXPECT_LE(now1, url_loader_client_.completion_status().completion_time); + EXPECT_LE(url_loader_client_.completion_status().completion_time, now2); + EXPECT_EQ(request_->GetTotalReceivedBytes(), + url_loader_client_.completion_status().encoded_data_length); +} + +TEST_F(MojoAsyncResourceHandlerTest, OnResponseCompletedWithCanceledTimedOut) { + net::URLRequestStatus status(net::URLRequestStatus::CANCELED, + net::ERR_TIMED_OUT); + bool defer = false; + + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + handler_->OnResponseCompleted(status, "security_info", &defer); + EXPECT_FALSE(defer); + + url_loader_client_.RunUntilComplete(); + EXPECT_TRUE(url_loader_client_.has_received_completion()); + EXPECT_EQ(net::ERR_TIMED_OUT, + url_loader_client_.completion_status().error_code); +} + +TEST_F(MojoAsyncResourceHandlerTest, OnResponseCompletedWithFailedTimedOut) { + net::URLRequestStatus status(net::URLRequestStatus::FAILED, + net::ERR_TIMED_OUT); + bool defer = false; + + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + handler_->OnResponseCompleted(status, "security_info", &defer); + EXPECT_FALSE(defer); + + url_loader_client_.RunUntilComplete(); + EXPECT_TRUE(url_loader_client_.has_received_completion()); + EXPECT_EQ(net::ERR_TIMED_OUT, + url_loader_client_.completion_status().error_code); +} + +TEST_F(MojoAsyncResourceHandlerTest, ResponseCompletionShouldCloseDataPipe) { + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + + scoped_refptr<net::IOBuffer> io_buffer; + int io_buffer_size = 0; + bool defer = false; + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + url_loader_client_.RunUntilResponseBodyArrived(); + ASSERT_TRUE(url_loader_client_.response_body().is_valid()); + ASSERT_TRUE(handler_->OnReadCompleted(0, &defer)); + EXPECT_FALSE(defer); + + net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, net::OK); + handler_->OnResponseCompleted(status, "security_info", &defer); + EXPECT_FALSE(defer); + + url_loader_client_.RunUntilComplete(); + EXPECT_TRUE(url_loader_client_.has_received_completion()); + EXPECT_EQ(net::OK, url_loader_client_.completion_status().error_code); + + // This is needed because |*io_buffer| may keep the data producer alive. + io_buffer = nullptr; + + while (true) { + char buffer[16]; + uint32_t read_size = sizeof(buffer); + MojoResult result = + mojo::ReadDataRaw(url_loader_client_.response_body(), buffer, + &read_size, MOJO_READ_DATA_FLAG_NONE); + if (result == MOJO_RESULT_FAILED_PRECONDITION) + break; + ASSERT_EQ(result, MOJO_RESULT_SHOULD_WAIT); + } +} + +TEST_F(MojoAsyncResourceHandlerTest, ResponseErrorDuringBodyTransmission) { + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + + scoped_refptr<net::IOBuffer> io_buffer; + int io_buffer_size = 0; + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + url_loader_client_.RunUntilResponseBodyArrived(); + ASSERT_TRUE(url_loader_client_.response_body().is_valid()); + ASSERT_GT(io_buffer_size, 0); + memset(io_buffer->data(), 'a', io_buffer_size); + bool defer = false; + ASSERT_TRUE(handler_->OnReadCompleted(io_buffer_size, &defer)); + // We don't care |defer|'s value here. + + defer = false; + net::URLRequestStatus status(net::URLRequestStatus::FAILED, net::ERR_FAILED); + handler_->OnResponseCompleted(status, "security_info", &defer); + EXPECT_FALSE(defer); + + url_loader_client_.RunUntilComplete(); + EXPECT_TRUE(url_loader_client_.has_received_completion()); + EXPECT_EQ(net::ERR_FAILED, url_loader_client_.completion_status().error_code); + + // This is needed because |*io_buffer| may keep the data producer alive. + io_buffer = nullptr; + + std::string actual; + while (true) { + char buf[16]; + uint32_t read_size = sizeof(buf); + MojoResult result = + mojo::ReadDataRaw(url_loader_client_.response_body(), buf, &read_size, + MOJO_READ_DATA_FLAG_NONE); + if (result == MOJO_RESULT_FAILED_PRECONDITION) + break; + if (result == MOJO_RESULT_SHOULD_WAIT) { + base::RunLoop().RunUntilIdle(); + continue; + } + EXPECT_EQ(MOJO_RESULT_OK, result); + actual.append(buf, read_size); + } + EXPECT_EQ(std::string(io_buffer_size, 'a'), actual); +} + +// In this case, an error is notified after OnWillRead, before OnReadCompleted. +TEST_F(MojoAsyncResourceHandlerTest, ResponseErrorDuringBodyTransmission2) { + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + + scoped_refptr<net::IOBuffer> io_buffer; + int io_buffer_size = 0; + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + url_loader_client_.RunUntilResponseBodyArrived(); + ASSERT_TRUE(url_loader_client_.response_body().is_valid()); + bool defer = false; + net::URLRequestStatus status(net::URLRequestStatus::FAILED, net::ERR_FAILED); + handler_->OnResponseCompleted(status, "security_info", &defer); + EXPECT_FALSE(defer); + + url_loader_client_.RunUntilComplete(); + EXPECT_TRUE(url_loader_client_.has_received_completion()); + EXPECT_EQ(net::ERR_FAILED, url_loader_client_.completion_status().error_code); + + // This is needed because |*io_buffer| may keep the data producer alive. + io_buffer = nullptr; + + while (true) { + char buf[16]; + uint32_t read_size = sizeof(buf); + MojoResult result = + mojo::ReadDataRaw(url_loader_client_.response_body(), buf, &read_size, + MOJO_READ_DATA_FLAG_NONE); + if (result == MOJO_RESULT_FAILED_PRECONDITION) + break; + ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT, result); + base::RunLoop().RunUntilIdle(); + } +} + +TEST_F(MojoAsyncResourceHandlerTest, BeginWriteFailsOnWillRead) { + handler_->set_begin_write_expectation(MOJO_RESULT_UNKNOWN); + scoped_refptr<net::IOBuffer> io_buffer; + int io_buffer_size = 0; + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + ASSERT_FALSE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + EXPECT_FALSE(resource_controller_.is_cancel_with_error_called()); +} + +TEST_F(MojoAsyncResourceHandlerTest, BeginWriteReturnsShouldWaitOnWillRead) { + handler_->set_begin_write_expectation(MOJO_RESULT_SHOULD_WAIT); + scoped_refptr<net::IOBuffer> io_buffer; + int io_buffer_size = 0; + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + EXPECT_TRUE(io_buffer); + EXPECT_GT(io_buffer_size, 0); +} + +TEST_F(MojoAsyncResourceHandlerTest, + BeginWriteReturnsShouldWaitOnWillReadAndThenReturnsOK) { + handler_->set_begin_write_expectation(MOJO_RESULT_SHOULD_WAIT); + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + size_t written = 0; + while (true) { + scoped_refptr<net::IOBuffer> io_buffer; + int io_buffer_size = 0; + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + EXPECT_TRUE(io_buffer); + EXPECT_GT(io_buffer_size, 0); + memset(io_buffer->data(), 'X', io_buffer_size); + written += io_buffer_size; + bool defer = false; + ASSERT_TRUE(handler_->OnReadCompleted(io_buffer_size, &defer)); + if (defer) + break; + } + + url_loader_client_.RunUntilResponseBodyArrived(); + ASSERT_TRUE(url_loader_client_.response_body().is_valid()); + handler_->ResetBeginWriteExpectation(); + handler_->ResumeForTesting(); + + std::string actual; + while (actual.size() < written) { + char buf[16]; + uint32_t read_size = sizeof(buf); + MojoResult result = + mojo::ReadDataRaw(url_loader_client_.response_body(), buf, &read_size, + MOJO_READ_DATA_FLAG_NONE); + ASSERT_TRUE(result == MOJO_RESULT_OK || result == MOJO_RESULT_SHOULD_WAIT); + if (result == MOJO_RESULT_OK) + actual.append(buf, read_size); + base::RunLoop().RunUntilIdle(); + } + + EXPECT_EQ(std::string(written, 'X'), actual); + EXPECT_EQ(1, resource_controller_.num_resume_calls()); +} + +TEST_F(MojoAsyncResourceHandlerTest, + EndWriteFailsOnWillReadWithInsufficientInitialCapacity) { + MojoAsyncResourceHandler::SetAllocationSizeForTesting(2); + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + handler_->set_end_write_expectation(MOJO_RESULT_UNKNOWN); + scoped_refptr<net::IOBuffer> io_buffer; + int io_buffer_size = 0; + ASSERT_FALSE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); +} + +TEST_F(MojoAsyncResourceHandlerTest, EndWriteFailsOnReadCompleted) { + scoped_refptr<net::IOBuffer> io_buffer; + int io_buffer_size = 0; + bool defer = false; + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + + handler_->set_end_write_expectation(MOJO_RESULT_SHOULD_WAIT); + ASSERT_FALSE(handler_->OnReadCompleted(io_buffer_size, &defer)); +} + +TEST_F(MojoAsyncResourceHandlerTest, + EndWriteFailsOnReadCompletedWithInsufficientInitialCapacity) { + MojoAsyncResourceHandler::SetAllocationSizeForTesting(2); + scoped_refptr<net::IOBuffer> io_buffer; + int io_buffer_size = 0; + bool defer = false; + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + + handler_->set_end_write_expectation(MOJO_RESULT_SHOULD_WAIT); + ASSERT_FALSE(handler_->OnReadCompleted(io_buffer_size, &defer)); +} + +TEST_F(MojoAsyncResourceHandlerTest, + EndWriteFailsOnResumeWithInsufficientInitialCapacity) { + MojoAsyncResourceHandler::SetAllocationSizeForTesting(8); + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + scoped_refptr<net::IOBuffer> io_buffer; + int io_buffer_size = 0; + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + url_loader_client_.RunUntilResponseBodyArrived(); + ASSERT_TRUE(url_loader_client_.response_body().is_valid()); + + while (true) { + bool defer = false; + ASSERT_TRUE(handler_->OnReadCompleted(io_buffer_size, &defer)); + ASSERT_GE(io_buffer_size, 0); + if (defer) + break; + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + } + + while (true) { + char buf[16]; + uint32_t read_size = sizeof(buf); + MojoResult result = + mojo::ReadDataRaw(url_loader_client_.response_body(), buf, &read_size, + MOJO_READ_DATA_FLAG_NONE); + if (result == MOJO_RESULT_SHOULD_WAIT) + break; + ASSERT_EQ(MOJO_RESULT_OK, result); + } + + handler_->set_end_write_expectation(MOJO_RESULT_SHOULD_WAIT); + resource_controller_.RunUntilCancelWithErrorCalled(); + EXPECT_FALSE(url_loader_client_.has_received_completion()); + EXPECT_TRUE(resource_controller_.is_cancel_with_error_called()); + EXPECT_EQ(net::ERR_FAILED, resource_controller_.error()); +} + +TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest, + OnWillReadWithLongContents) { + bool defer = false; + scoped_refptr<net::IOBuffer> io_buffer; + int io_buffer_size = 0; + + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + ASSERT_TRUE(io_buffer); + // The io_buffer size that the mime sniffer requires implicitly. + ASSERT_GE(io_buffer_size, kSizeMimeSnifferRequiresForFirstOnWillRead); + std::string expected; + for (int i = 0; i < 3 * io_buffer_size + 2; ++i) + expected += ('A' + i % 26); + + ASSERT_TRUE(handler_->OnReadCompleted(0, &defer)); + ASSERT_FALSE(defer); + + url_loader_client_.RunUntilResponseBodyArrived(); + ASSERT_TRUE(url_loader_client_.response_body().is_valid()); + + size_t written = 0; + std::string actual; + while (actual.size() < expected.size()) { + while (written < expected.size() && !defer) { + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + const size_t to_be_written = std::min(static_cast<size_t>(io_buffer_size), + expected.size() - written); + memcpy(io_buffer->data(), &expected[written], to_be_written); + ASSERT_TRUE(handler_->OnReadCompleted(to_be_written, &defer)); + written += to_be_written; + } + + char buf[16]; + uint32_t read_size = sizeof(buf); + MojoResult result = + mojo::ReadDataRaw(url_loader_client_.response_body(), buf, &read_size, + MOJO_READ_DATA_FLAG_NONE); + if (result != MOJO_RESULT_SHOULD_WAIT) { + ASSERT_EQ(MOJO_RESULT_OK, result); + actual.append(buf, read_size); + } + int resume_count = resource_controller_.num_resume_calls(); + base::RunLoop().RunUntilIdle(); + // Continue writing if controller->Resume() is called. + defer = (resume_count == resource_controller_.num_resume_calls()); + } + EXPECT_EQ(expected, actual); +} + +TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest, + BeginWriteFailsOnReadCompleted) { + scoped_refptr<net::IOBuffer> io_buffer; + int io_buffer_size = 0; + bool defer = false; + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + + handler_->set_begin_write_expectation(MOJO_RESULT_UNKNOWN); + ASSERT_FALSE(handler_->OnReadCompleted(io_buffer_size, &defer)); +} + +TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest, + BeginWriteReturnsShouldWaitOnReadCompleted) { + scoped_refptr<net::IOBuffer> io_buffer; + int io_buffer_size = 0; + bool defer = false; + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + + handler_->set_begin_write_expectation(MOJO_RESULT_SHOULD_WAIT); + ASSERT_TRUE(handler_->OnReadCompleted(io_buffer_size, &defer)); + EXPECT_TRUE(defer); +} + +TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest, + BeginWriteFailsOnResume) { + bool defer = false; + int io_buffer_size = 0; + scoped_refptr<net::IOBuffer> io_buffer; + + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + ASSERT_TRUE(handler_->OnReadCompleted(0, &defer)); + ASSERT_FALSE(defer); + url_loader_client_.RunUntilResponseBodyArrived(); + ASSERT_TRUE(url_loader_client_.response_body().is_valid()); + + while (!defer) { + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + ASSERT_TRUE(handler_->OnReadCompleted(io_buffer_size, &defer)); + } + handler_->set_begin_write_expectation(MOJO_RESULT_UNKNOWN); + + while (!resource_controller_.is_cancel_with_error_called()) { + char buf[256]; + uint32_t read_size = sizeof(buf); + MojoResult result = + mojo::ReadDataRaw(url_loader_client_.response_body(), buf, &read_size, + MOJO_READ_DATA_FLAG_NONE); + ASSERT_TRUE(result == MOJO_RESULT_OK || result == MOJO_RESULT_SHOULD_WAIT); + base::RunLoop().RunUntilIdle(); + } + + EXPECT_FALSE(url_loader_client_.has_received_completion()); + EXPECT_EQ(net::ERR_FAILED, resource_controller_.error()); + EXPECT_EQ(0, resource_controller_.num_resume_calls()); +} + +TEST_P(MojoAsyncResourceHandlerWithAllocationSizeTest, CancelWhileWaiting) { + bool defer = false; + ASSERT_TRUE(CallOnWillStartAndOnResponseStarted()); + + while (!defer) { + scoped_refptr<net::IOBuffer> io_buffer; + int io_buffer_size = 0; + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + ASSERT_TRUE(handler_->OnReadCompleted(io_buffer_size, &defer)); + } + + url_loader_client_.RunUntilResponseBodyArrived(); + ASSERT_TRUE(url_loader_client_.response_body().is_valid()); + + defer = false; + net::URLRequestStatus status(net::URLRequestStatus::CANCELED, + net::ERR_ABORTED); + handler_->OnResponseCompleted(status, "security_info", &defer); + + ASSERT_FALSE(url_loader_client_.has_received_completion()); + url_loader_client_.RunUntilComplete(); + EXPECT_EQ(net::ERR_ABORTED, + url_loader_client_.completion_status().error_code); + + while (true) { + char buffer[16]; + uint32_t read_size = sizeof(buffer); + MojoResult result = + mojo::ReadDataRaw(url_loader_client_.response_body(), buffer, + &read_size, MOJO_READ_DATA_FLAG_NONE); + if (result == MOJO_RESULT_FAILED_PRECONDITION) + break; + base::RunLoop().RunUntilIdle(); + DCHECK(result == MOJO_RESULT_SHOULD_WAIT || result == MOJO_RESULT_OK); + } + + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(0, resource_controller_.num_resume_calls()); +} + +// Typically ResourceHandler methods are called in this order. +TEST_P( + MojoAsyncResourceHandlerWithAllocationSizeTest, + OnWillStartThenOnResponseStartedThenOnWillReadThenOnReadCompletedThenOnResponseCompleted) { + rdh_delegate_.set_num_on_response_started_calls_expectation(1); + bool defer = false; + + ASSERT_TRUE(handler_->OnWillStart(request_->url(), &defer)); + ASSERT_FALSE(defer); + scoped_refptr<ResourceResponse> response = new ResourceResponse(); + ASSERT_TRUE(handler_->OnResponseStarted(response.get(), &defer)); + ASSERT_FALSE(defer); + + ASSERT_FALSE(url_loader_client_.has_received_response()); + url_loader_client_.RunUntilResponseReceived(); + + int io_buffer_size = 0; + scoped_refptr<net::IOBuffer> io_buffer; + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + ASSERT_TRUE(io_buffer); + ASSERT_GT(io_buffer_size, 0); + io_buffer->data()[0] = 'A'; + + ASSERT_FALSE(url_loader_client_.response_body().is_valid()); + url_loader_client_.RunUntilResponseBodyArrived(); + ASSERT_TRUE(url_loader_client_.response_body().is_valid()); + + ASSERT_TRUE(handler_->OnReadCompleted(1, &defer)); + ASSERT_FALSE(defer); + net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, net::OK); + handler_->OnResponseCompleted(status, "security info", &defer); + ASSERT_FALSE(defer); + + ASSERT_FALSE(url_loader_client_.has_received_completion()); + url_loader_client_.RunUntilComplete(); + EXPECT_EQ(net::OK, url_loader_client_.completion_status().error_code); + + // This is needed because |*io_buffer| may keep the data producer alive. + io_buffer = nullptr; + + std::string body; + while (true) { + char buffer[16]; + uint32_t read_size = sizeof(buffer); + MojoResult result = + mojo::ReadDataRaw(url_loader_client_.response_body(), buffer, + &read_size, MOJO_READ_DATA_FLAG_NONE); + if (result == MOJO_RESULT_FAILED_PRECONDITION) + break; + if (result == MOJO_RESULT_SHOULD_WAIT) { + base::RunLoop().RunUntilIdle(); + } else { + ASSERT_EQ(result, MOJO_RESULT_OK); + body.append(buffer, read_size); + } + } + EXPECT_EQ("A", body); +} + +// MimeResourceHandler calls delegated ResourceHandler's methods in this order. +TEST_P( + MojoAsyncResourceHandlerWithAllocationSizeTest, + OnWillStartThenOnWillReadThenOnResponseStartedThenOnReadCompletedThenOnResponseCompleted) { + rdh_delegate_.set_num_on_response_started_calls_expectation(1); + bool defer = false; + + ASSERT_TRUE(handler_->OnWillStart(request_->url(), &defer)); + ASSERT_FALSE(defer); + + int io_buffer_size = 0; + scoped_refptr<net::IOBuffer> io_buffer; + ASSERT_TRUE(handler_->OnWillRead(&io_buffer, &io_buffer_size, -1)); + ASSERT_TRUE(io_buffer); + ASSERT_GT(io_buffer_size, 0); + io_buffer->data()[0] = 'B'; + + ASSERT_FALSE(url_loader_client_.response_body().is_valid()); + url_loader_client_.RunUntilResponseBodyArrived(); + ASSERT_TRUE(url_loader_client_.response_body().is_valid()); + + scoped_refptr<ResourceResponse> response = new ResourceResponse(); + ASSERT_TRUE(handler_->OnResponseStarted(response.get(), &defer)); + ASSERT_FALSE(defer); + + ASSERT_FALSE(url_loader_client_.has_received_response()); + url_loader_client_.RunUntilResponseReceived(); + + ASSERT_TRUE(handler_->OnReadCompleted(1, &defer)); + ASSERT_FALSE(defer); + net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, net::OK); + handler_->OnResponseCompleted(status, "security info", &defer); + ASSERT_FALSE(defer); + + ASSERT_FALSE(url_loader_client_.has_received_completion()); + url_loader_client_.RunUntilComplete(); + EXPECT_EQ(net::OK, url_loader_client_.completion_status().error_code); + + // This is needed because |*io_buffer| may keep the data producer alive. + io_buffer = nullptr; + + std::string body; + while (true) { + char buffer[16]; + uint32_t read_size = sizeof(buffer); + MojoResult result = + mojo::ReadDataRaw(url_loader_client_.response_body(), buffer, + &read_size, MOJO_READ_DATA_FLAG_NONE); + if (result == MOJO_RESULT_FAILED_PRECONDITION) + break; + if (result == MOJO_RESULT_SHOULD_WAIT) { + base::RunLoop().RunUntilIdle(); + } else { + ASSERT_EQ(result, MOJO_RESULT_OK); + body.append(buffer, read_size); + } + } + EXPECT_EQ("B", body); +} + +INSTANTIATE_TEST_CASE_P(MojoAsyncResourceHandlerWithAllocationSizeTest, + MojoAsyncResourceHandlerWithAllocationSizeTest, + ::testing::Values(8, 32 * 2014)); +} // namespace +} // namespace content
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index b7adcbf..f4ae9b56 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -51,6 +51,7 @@ #include "content/browser/loader/detachable_resource_handler.h" #include "content/browser/loader/loader_delegate.h" #include "content/browser/loader/mime_type_resource_handler.h" +#include "content/browser/loader/mojo_async_resource_handler.h" #include "content/browser/loader/navigation_resource_handler.h" #include "content/browser/loader/navigation_resource_throttle.h" #include "content/browser/loader/navigation_url_loader_impl_core.h" @@ -79,7 +80,6 @@ #include "content/common/ssl_status_serialization.h" #include "content/common/view_messages.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/content_browser_client.h" #include "content/public/browser/global_request_id.h" #include "content/public/browser/plugin_service.h" #include "content/public/browser/resource_dispatcher_host_delegate.h" @@ -225,7 +225,8 @@ // Aborts a request before an URLRequest has actually been created. void AbortRequestBeforeItStarts(ResourceMessageFilter* filter, IPC::Message* sync_result, - int request_id) { + int request_id, + mojom::URLLoaderClientPtr url_loader_client) { if (sync_result) { SyncLoadResult result; result.error_code = net::ERR_ABORTED; @@ -240,8 +241,12 @@ // No security info needed, connection not established. request_complete_data.completion_time = base::TimeTicks(); request_complete_data.encoded_data_length = 0; - filter->Send(new ResourceMsg_RequestComplete( - request_id, request_complete_data)); + if (url_loader_client) { + url_loader_client->OnComplete(request_complete_data); + } else { + filter->Send( + new ResourceMsg_RequestComplete(request_id, request_complete_data)); + } } } @@ -358,17 +363,6 @@ return lofi_state == LOFI_ON; } -// Record RAPPOR for aborted main frame loads. Separate into a fast and -// slow bucket because a shocking number of aborts happen under 100ms. -void RecordAbortRapporOnUI(const GURL& url, - base::TimeDelta request_loading_time) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - if (request_loading_time.InMilliseconds() < 100) - GetContentClient()->browser()->RecordURLMetric("Net.ErrAborted.Fast", url); - else - GetContentClient()->browser()->RecordURLMetric("Net.ErrAborted.Slow", url); -} - // The following functions simplify code paths where the UI thread notifies the // ResourceDispatcherHostImpl of information pertaining to loading behavior of // frame hosts. @@ -487,6 +481,7 @@ ResourceDispatcherHostImpl::~ResourceDispatcherHostImpl() { DCHECK(outstanding_requests_stats_map_.empty()); DCHECK(g_resource_dispatcher_host); + DCHECK_CURRENTLY_ON(BrowserThread::UI); g_resource_dispatcher_host = NULL; } @@ -822,9 +817,15 @@ } } -void ResourceDispatcherHostImpl::DidReceiveRedirect(ResourceLoader* loader, - const GURL& new_url) { +void ResourceDispatcherHostImpl::DidReceiveRedirect( + ResourceLoader* loader, + const GURL& new_url, + ResourceResponse* response) { ResourceRequestInfoImpl* info = loader->GetRequestInfo(); + if (delegate_) { + delegate_->OnRequestRedirected( + new_url, loader->request(), info->GetContext(), response); + } int render_process_id, render_frame_host; if (!info->GetAssociatedRenderFrame(&render_process_id, &render_frame_host)) @@ -953,10 +954,10 @@ request_loading_time); } - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::Bind(&RecordAbortRapporOnUI, loader->request()->url(), - request_loading_time)); + if (delegate_) { + delegate_->OnAbortedFrameLoad(loader->request()->url(), + request_loading_time); + } break; case net::ERR_CONNECTION_RESET: UMA_HISTOGRAM_LONG_TIMES( @@ -1063,6 +1064,7 @@ bool ResourceDispatcherHostImpl::OnMessageReceived( const IPC::Message& message, ResourceMessageFilter* filter) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); filter_ = filter; bool handled = true; IPC_BEGIN_MESSAGE_MAP(ResourceDispatcherHostImpl, message) @@ -1104,6 +1106,16 @@ int routing_id, int request_id, const ResourceRequest& request_data) { + OnRequestResourceInternal(routing_id, request_id, request_data, nullptr, + nullptr); +} + +void ResourceDispatcherHostImpl::OnRequestResourceInternal( + int routing_id, + int request_id, + const ResourceRequest& request_data, + mojo::InterfaceRequest<mojom::URLLoader> mojo_request, + mojom::URLLoaderClientPtr url_loader_client) { // TODO(pkasting): Remove ScopedTracker below once crbug.com/477117 is fixed. tracked_objects::ScopedTracker tracking_profile( FROM_HERE_WITH_EXPLICIT_FUNCTION( @@ -1124,7 +1136,8 @@ request_data.render_frame_id, request_data.url)); } - BeginRequest(request_id, request_data, NULL, routing_id); + BeginRequest(request_id, request_data, NULL, routing_id, + std::move(mojo_request), std::move(url_loader_client)); } // Begins a resource request with the given params on behalf of the specified @@ -1138,8 +1151,8 @@ void ResourceDispatcherHostImpl::OnSyncLoad(int request_id, const ResourceRequest& request_data, IPC::Message* sync_result) { - BeginRequest(request_id, request_data, sync_result, - sync_result->routing_id()); + BeginRequest(request_id, request_data, sync_result, sync_result->routing_id(), + nullptr, nullptr); } bool ResourceDispatcherHostImpl::IsRequestIDInUse( @@ -1254,7 +1267,9 @@ int request_id, const ResourceRequest& request_data, IPC::Message* sync_result, // only valid for sync - int route_id) { + int route_id, + mojo::InterfaceRequest<mojom::URLLoader> mojo_request, + mojom::URLLoaderClientPtr url_loader_client) { int process_type = filter_->process_type(); int child_id = filter_->child_id(); @@ -1294,6 +1309,9 @@ GlobalRequestID(request_data.transferred_request_child_id, request_data.transferred_request_request_id)); if (it != pending_loaders_.end()) { + // TODO(yhirano): Make mojo work for this case. + DCHECK(!url_loader_client); + // If the request is transferring to a new process, we can update our // state and let it resume with its existing ResourceHandlers. if (it->second->is_transferring()) { @@ -1318,25 +1336,44 @@ net::HttpRequestHeaders headers; headers.AddHeadersFromString(request_data.headers); - BeginRequestStatus begin_request_status = CONTINUE; - OnHeaderProcessedCallback callback; - if (!is_shutdown_) { - callback = - base::Bind(&ResourceDispatcherHostImpl::ContinuePendingBeginRequest, - base::Unretained(this), request_id, request_data, - sync_result, route_id, headers); - begin_request_status = - ShouldServiceRequest(process_type, child_id, request_data, headers, - filter_, resource_context, callback); - } else { - begin_request_status = ABORT; - } - if (begin_request_status == ABORT) { - AbortRequestBeforeItStarts(filter_, sync_result, request_id); + if (is_shutdown_ || + !ShouldServiceRequest(process_type, child_id, request_data, headers, + filter_, resource_context)) { + AbortRequestBeforeItStarts(filter_, sync_result, request_id, + std::move(url_loader_client)); return; - } else if (begin_request_status == CONTINUE) { - callback.Run(true, 0); } + // Check if we have a registered interceptor for the headers passed in. If + // yes then we need to mark the current request as pending and wait for the + // interceptor to invoke the callback with a status code indicating whether + // the request needs to be aborted or continued. + for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();) { + HeaderInterceptorMap::iterator index = + http_header_interceptor_map_.find(it.name()); + if (index != http_header_interceptor_map_.end()) { + HeaderInterceptorInfo& interceptor_info = index->second; + + bool call_interceptor = true; + if (!interceptor_info.starts_with.empty()) { + call_interceptor = + base::StartsWith(it.value(), interceptor_info.starts_with, + base::CompareCase::INSENSITIVE_ASCII); + } + if (call_interceptor) { + interceptor_info.interceptor.Run( + it.name(), it.value(), child_id, resource_context, + base::Bind(&ResourceDispatcherHostImpl::ContinuePendingBeginRequest, + base::Unretained(this), request_id, request_data, + sync_result, route_id, headers, + base::Passed(std::move(mojo_request)), + base::Passed(std::move(url_loader_client)))); + return; + } + } + } + ContinuePendingBeginRequest(request_id, request_data, sync_result, route_id, + headers, std::move(mojo_request), + std::move(url_loader_client), true, 0); } void ResourceDispatcherHostImpl::ContinuePendingBeginRequest( @@ -1345,13 +1382,16 @@ IPC::Message* sync_result, // only valid for sync int route_id, const net::HttpRequestHeaders& headers, + mojo::InterfaceRequest<mojom::URLLoader> mojo_request, + mojom::URLLoaderClientPtr url_loader_client, bool continue_request, int error_code) { if (!continue_request) { // TODO(ananta): Find a way to specify the right error code here. Passing // in a non-content error code is not safe. bad_message::ReceivedBadMessage(filter_, bad_message::RDH_ILLEGAL_ORIGIN); - AbortRequestBeforeItStarts(filter_, sync_result, request_id); + AbortRequestBeforeItStarts(filter_, sync_result, request_id, + std::move(url_loader_client)); return; } @@ -1372,7 +1412,8 @@ request_data.url, request_data.resource_type, resource_context)) { - AbortRequestBeforeItStarts(filter_, sync_result, request_id); + AbortRequestBeforeItStarts(filter_, sync_result, request_id, + std::move(url_loader_client)); return; } @@ -1532,17 +1573,14 @@ request_data.fetch_request_context_type, request_data.fetch_frame_type, request_data.request_body); - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableExperimentalWebPlatformFeatures)) { - ForeignFetchRequestHandler::InitializeHandler( - new_request.get(), filter_->service_worker_context(), blob_context, - child_id, request_data.service_worker_provider_id, - should_skip_service_worker, request_data.fetch_request_mode, - request_data.fetch_credentials_mode, request_data.fetch_redirect_mode, - request_data.resource_type, request_data.fetch_request_context_type, - request_data.fetch_frame_type, request_data.request_body, - request_data.initiated_in_secure_context); - } + ForeignFetchRequestHandler::InitializeHandler( + new_request.get(), filter_->service_worker_context(), blob_context, + child_id, request_data.service_worker_provider_id, + should_skip_service_worker, request_data.fetch_request_mode, + request_data.fetch_credentials_mode, request_data.fetch_redirect_mode, + request_data.resource_type, request_data.fetch_request_context_type, + request_data.fetch_frame_type, request_data.request_body, + request_data.initiated_in_secure_context); // Have the appcache associate its extra info with the request. AppCacheInterceptor::SetExtraRequestInfo( @@ -1552,7 +1590,8 @@ std::unique_ptr<ResourceHandler> handler(CreateResourceHandler( new_request.get(), request_data, sync_result, route_id, process_type, - child_id, resource_context)); + child_id, resource_context, std::move(mojo_request), + std::move(url_loader_client))); if (handler) BeginRequestInternal(std::move(new_request), std::move(handler)); @@ -1566,7 +1605,9 @@ int route_id, int process_type, int child_id, - ResourceContext* resource_context) { + ResourceContext* resource_context, + mojo::InterfaceRequest<mojom::URLLoader> mojo_request, + mojom::URLLoaderClientPtr url_loader_client) { // TODO(pkasting): Remove ScopedTracker below once crbug.com/456331 is fixed. tracked_objects::ScopedTracker tracking_profile( FROM_HERE_WITH_EXPLICIT_FUNCTION( @@ -1580,9 +1621,17 @@ return std::unique_ptr<ResourceHandler>(); } + DCHECK(!mojo_request.is_pending()); + DCHECK(!url_loader_client); handler.reset(new SyncResourceHandler(request, sync_result, this)); } else { - handler.reset(new AsyncResourceHandler(request, this)); + if (mojo_request.is_pending()) { + handler.reset(new MojoAsyncResourceHandler(request, this, + std::move(mojo_request), + std::move(url_loader_client))); + } else { + handler.reset(new AsyncResourceHandler(request, this)); + } // The RedirectToFileResourceHandler depends on being next in the chain. if (request_data.download_to_file) { @@ -2282,6 +2331,20 @@ CancelRequestsForRoute(global_routing_id); } +void ResourceDispatcherHostImpl::OnRequestResourceWithMojo( + int routing_id, + int request_id, + const ResourceRequest& request, + mojo::InterfaceRequest<mojom::URLLoader> mojo_request, + mojom::URLLoaderClientPtr url_loader_client, + ResourceMessageFilter* filter) { + filter_ = filter; + OnRequestResourceInternal(routing_id, request_id, request, + std::move(mojo_request), + std::move(url_loader_client)); + filter_ = nullptr; +} + // static int ResourceDispatcherHostImpl::CalculateApproximateMemoryCost( net::URLRequest* request) { @@ -2550,7 +2613,7 @@ void ResourceDispatcherHostImpl::UnregisterResourceMessageDelegate( const GlobalRequestID& id, ResourceMessageDelegate* delegate) { - DCHECK(ContainsKey(delegate_map_, id)); + DCHECK(base::ContainsKey(delegate_map_, id)); DelegateMap::iterator it = delegate_map_.find(id); DCHECK(it->second->HasObserver(delegate)); it->second->RemoveObserver(delegate); @@ -2608,15 +2671,13 @@ : CertStore::GetInstance(); } -ResourceDispatcherHostImpl::BeginRequestStatus -ResourceDispatcherHostImpl::ShouldServiceRequest( +bool ResourceDispatcherHostImpl::ShouldServiceRequest( int process_type, int child_id, const ResourceRequest& request_data, const net::HttpRequestHeaders& headers, ResourceMessageFilter* filter, - ResourceContext* resource_context, - OnHeaderProcessedCallback callback) { + ResourceContext* resource_context) { ChildProcessSecurityPolicyImpl* policy = ChildProcessSecurityPolicyImpl::GetInstance(); @@ -2624,7 +2685,7 @@ if (!policy->CanRequestURL(child_id, request_data.url)) { VLOG(1) << "Denied unauthorized request for " << request_data.url.possibly_invalid_spec(); - return ABORT; + return false; } // Check if the renderer is using an illegal Origin header. If so, kill it. @@ -2636,7 +2697,7 @@ if (!policy->CanCommitURL(child_id, origin)) { VLOG(1) << "Killed renderer for illegal origin: " << origin_string; bad_message::ReceivedBadMessage(filter, bad_message::RDH_ILLEGAL_ORIGIN); - return ABORT; + return false; } } @@ -2650,7 +2711,7 @@ !policy->CanReadFile(child_id, iter->path())) { NOTREACHED() << "Denied unauthorized upload of " << iter->path().value(); - return ABORT; + return false; } if (iter->type() == ResourceRequestBodyImpl::Element::TYPE_FILE_FILESYSTEM) { @@ -2659,36 +2720,12 @@ if (!policy->CanReadFileSystemFile(child_id, url)) { NOTREACHED() << "Denied unauthorized upload of " << iter->filesystem_url().spec(); - return ABORT; + return false; } } } } - - // Check if we have a registered interceptor for the headers passed in. If - // yes then we need to mark the current request as pending and wait for the - // interceptor to invoke the |callback| with a status code indicating whether - // the request needs to be aborted or continued. - for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext();) { - HeaderInterceptorMap::iterator index = - http_header_interceptor_map_.find(it.name()); - if (index != http_header_interceptor_map_.end()) { - HeaderInterceptorInfo& interceptor_info = index->second; - - bool call_interceptor = true; - if (!interceptor_info.starts_with.empty()) { - call_interceptor = - base::StartsWith(it.value(), interceptor_info.starts_with, - base::CompareCase::INSENSITIVE_ASCII); - } - if (call_interceptor) { - interceptor_info.interceptor.Run(it.name(), it.value(), child_id, - resource_context, callback); - return PENDING; - } - } - } - return CONTINUE; + return true; } } // namespace content
diff --git a/content/browser/loader/resource_dispatcher_host_impl.h b/content/browser/loader/resource_dispatcher_host_impl.h index 3e6c504..0eada5f 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.h +++ b/content/browser/loader/resource_dispatcher_host_impl.h
@@ -31,11 +31,13 @@ #include "content/browser/loader/resource_loader_delegate.h" #include "content/browser/loader/resource_scheduler.h" #include "content/common/content_export.h" +#include "content/common/url_loader.mojom.h" #include "content/public/browser/global_request_id.h" #include "content/public/browser/resource_dispatcher_host.h" #include "content/public/common/request_context_type.h" #include "content/public/common/resource_type.h" #include "ipc/ipc_message.h" +#include "mojo/public/cpp/system/data_pipe.h" #include "net/base/request_priority.h" #include "net/cookies/canonical_cookie.h" #include "net/url_request/url_request.h" @@ -74,6 +76,10 @@ struct Referrer; struct ResourceRequest; +namespace mojom { +class URLLoader; +} // namespace mojom + class CONTENT_EXPORT ResourceDispatcherHostImpl : public ResourceDispatcherHost, public ResourceLoaderDelegate { @@ -285,6 +291,10 @@ const NavigationRequestInfo& info, NavigationURLLoaderImplCore* loader); + int num_in_flight_requests_for_testing() const { + return num_in_flight_requests_; + } + // Turns on stale-while-revalidate support, regardless of command-line flags // or experiment status. For unit tests only. void EnableStaleWhileRevalidateForTesting(); @@ -295,6 +305,15 @@ void OnRenderFrameDeleted(const GlobalFrameRoutingId& global_routing_id); + // Called when loading a request with mojo. + void OnRequestResourceWithMojo( + int routing_id, + int request_id, + const ResourceRequest& request, + mojo::InterfaceRequest<mojom::URLLoader> mojo_request, + mojom::URLLoaderClientPtr url_loader_client, + ResourceMessageFilter* filter); + private: friend class ResourceDispatcherHostTest; @@ -351,7 +370,8 @@ net::AuthChallengeInfo* auth_info) override; bool HandleExternalProtocol(ResourceLoader* loader, const GURL& url) override; void DidStartRequest(ResourceLoader* loader) override; - void DidReceiveRedirect(ResourceLoader* loader, const GURL& new_url) override; + void DidReceiveRedirect(ResourceLoader* loader, const GURL& new_url, + ResourceResponse* response) override; void DidReceiveResponse(ResourceLoader* loader) override; void DidFinishLoading(ResourceLoader* loader) override; std::unique_ptr<net::ClientCertStore> CreateClientCertStore( @@ -455,6 +475,14 @@ void OnRequestResource(int routing_id, int request_id, const ResourceRequest& request_data); + + void OnRequestResourceInternal( + int routing_id, + int request_id, + const ResourceRequest& request_data, + mojo::InterfaceRequest<mojom::URLLoader> mojo_request, + mojom::URLLoaderClientPtr url_loader_client); + void OnSyncLoad(int request_id, const ResourceRequest& request_data, IPC::Message* sync_result); @@ -472,7 +500,9 @@ void BeginRequest(int request_id, const ResourceRequest& request_data, IPC::Message* sync_result, // only valid for sync - int route_id); // only valid for async + int route_id, // only valid for async + mojo::InterfaceRequest<mojom::URLLoader> mojo_request, + mojom::URLLoaderClientPtr url_loader_client); // There are requests which need decisions to be made like the following: // Whether the presence of certain HTTP headers like the Origin header are @@ -489,6 +519,8 @@ IPC::Message* sync_result, // only valid for sync int route_id, const net::HttpRequestHeaders& headers, + mojo::InterfaceRequest<mojom::URLLoader> mojo_request, + mojom::URLLoaderClientPtr url_loader_client, bool continue_request, int error_code); @@ -501,7 +533,9 @@ int route_id, int process_type, int child_id, - ResourceContext* resource_context); + ResourceContext* resource_context, + mojo::InterfaceRequest<mojom::URLLoader> mojo_request, + mojom::URLLoaderClientPtr url_loader_client); // Wraps |handler| in the standard resource handlers for normal resource // loading and navigation requests. This adds MimeTypeResourceHandler and @@ -575,27 +609,16 @@ CertStore* GetCertStore(); - // This enum holds values which indicate how we want to proceed with a - // request that is about to be started. - enum BeginRequestStatus { - CONTINUE = 0, // Continue with the request. - ABORT = 1, // Abort. - PENDING = 2, // Wait for the decision to come back. - LAST_SERVICE_REQUEST_STATUS = PENDING, - }; - // Consults the RendererSecurity policy to determine whether the // ResourceDispatcherHostImpl should service this request. A request might // be disallowed if the renderer is not authorized to retrieve the request // URL or if the renderer is attempting to upload an unauthorized file. - BeginRequestStatus ShouldServiceRequest( - int process_type, - int child_id, - const ResourceRequest& request_data, - const net::HttpRequestHeaders& headers, - ResourceMessageFilter* filter, - ResourceContext* resource_context, - OnHeaderProcessedCallback callback); + bool ShouldServiceRequest(int process_type, + int child_id, + const ResourceRequest& request_data, + const net::HttpRequestHeaders& headers, + ResourceMessageFilter* filter, + ResourceContext* resource_context); LoaderMap pending_loaders_;
diff --git a/content/browser/loader/resource_loader.cc b/content/browser/loader/resource_loader.cc index 98938e6..d9a3b8f 100644 --- a/content/browser/loader/resource_loader.cc +++ b/content/browser/loader/resource_loader.cc
@@ -277,8 +277,6 @@ return; } - delegate_->DidReceiveRedirect(this, redirect_info.new_url); - if (delegate_->HandleExternalProtocol(this, redirect_info.new_url)) { // The request is complete so we can remove it. CancelAndIgnore(); @@ -287,6 +285,7 @@ scoped_refptr<ResourceResponse> response = new ResourceResponse(); PopulateResourceResponse(info, request_.get(), cert_store_, response.get()); + delegate_->DidReceiveRedirect(this, redirect_info.new_url, response.get()); if (!handler_->OnRequestRedirected(redirect_info, response.get(), defer)) { Cancel(); } else if (*defer) {
diff --git a/content/browser/loader/resource_loader_delegate.h b/content/browser/loader/resource_loader_delegate.h index 098d391..36702fa 100644 --- a/content/browser/loader/resource_loader_delegate.h +++ b/content/browser/loader/resource_loader_delegate.h
@@ -15,6 +15,7 @@ namespace content { class ResourceDispatcherHostLoginDelegate; class ResourceLoader; +struct ResourceResponse; class CONTENT_EXPORT ResourceLoaderDelegate { public: @@ -27,7 +28,8 @@ virtual void DidStartRequest(ResourceLoader* loader) = 0; virtual void DidReceiveRedirect(ResourceLoader* loader, - const GURL& new_url) = 0; + const GURL& new_url, + ResourceResponse* response) = 0; virtual void DidReceiveResponse(ResourceLoader* loader) = 0; // This method informs the delegate that the loader is done, and the loader
diff --git a/content/browser/loader/resource_loader_unittest.cc b/content/browser/loader/resource_loader_unittest.cc index 3662078d..de9261d0 100644 --- a/content/browser/loader/resource_loader_unittest.cc +++ b/content/browser/loader/resource_loader_unittest.cc
@@ -654,7 +654,8 @@ } void DidStartRequest(ResourceLoader* loader) override {} void DidReceiveRedirect(ResourceLoader* loader, - const GURL& new_url) override {} + const GURL& new_url, + ResourceResponse* response) override {} void DidReceiveResponse(ResourceLoader* loader) override {} void DidFinishLoading(ResourceLoader* loader) override {} std::unique_ptr<net::ClientCertStore> CreateClientCertStore(
diff --git a/content/browser/loader/resource_message_filter.cc b/content/browser/loader/resource_message_filter.cc index eb1993b59..b14afa1 100644 --- a/content/browser/loader/resource_message_filter.cc +++ b/content/browser/loader/resource_message_filter.cc
@@ -49,6 +49,12 @@ return ResourceDispatcherHostImpl::Get()->OnMessageReceived(message, this); } +void ResourceMessageFilter::OnDestruct() const { + // Destroy the filter on the IO thread since that's where its weak pointers + // are being used. + BrowserThread::DeleteOnIOThread::Destruct(this); +} + void ResourceMessageFilter::GetContexts( ResourceType resource_type, ResourceContext** resource_context, @@ -64,6 +70,7 @@ } base::WeakPtr<ResourceMessageFilter> ResourceMessageFilter::GetWeakPtr() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); return weak_ptr_factory_.GetWeakPtr(); }
diff --git a/content/browser/loader/resource_message_filter.h b/content/browser/loader/resource_message_filter.h index 44937a0b..4037826 100644 --- a/content/browser/loader/resource_message_filter.h +++ b/content/browser/loader/resource_message_filter.h
@@ -10,9 +10,11 @@ #include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/sequenced_task_runner_helpers.h" #include "content/browser/host_zoom_level_context.h" #include "content/common/content_export.h" #include "content/public/browser/browser_message_filter.h" +#include "content/public/browser/browser_thread.h" #include "content/public/common/resource_type.h" namespace storage { @@ -58,6 +60,7 @@ // BrowserMessageFilter implementation. void OnChannelClosing() override; bool OnMessageReceived(const IPC::Message& message) override; + void OnDestruct() const override; void GetContexts(ResourceType resource_type, ResourceContext** resource_context, @@ -96,6 +99,9 @@ ~ResourceMessageFilter() override; private: + friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>; + friend class base::DeleteHelper<ResourceMessageFilter>; + // The ID of the child process. int child_id_;
diff --git a/content/browser/loader/resource_scheduler.cc b/content/browser/loader/resource_scheduler.cc index 12e7361..c8eaff4 100644 --- a/content/browser/loader/resource_scheduler.cc +++ b/content/browser/loader/resource_scheduler.cc
@@ -136,7 +136,7 @@ // Returns true if |request| is queued. bool IsQueued(ScheduledResourceRequest* request) const { - return ContainsKey(pointers_, request); + return base::ContainsKey(pointers_, request); } // Returns true if no requests are queued. @@ -302,7 +302,7 @@ void ResourceScheduler::RequestQueue::Insert( ScheduledResourceRequest* request) { - DCHECK(!ContainsKey(pointers_, request)); + DCHECK(!base::ContainsKey(pointers_, request)); request->set_fifo_ordering(MakeFifoOrderingId()); pointers_[request] = queue_.insert(request); } @@ -334,7 +334,7 @@ void RemoveRequest(ScheduledResourceRequest* request) { if (pending_requests_.IsQueued(request)) { pending_requests_.Erase(request); - DCHECK(!ContainsKey(in_flight_requests_, request)); + DCHECK(!base::ContainsKey(in_flight_requests_, request)); } else { EraseInFlightRequest(request); @@ -398,7 +398,7 @@ request->set_request_priority_params(new_priority_params); SetRequestAttributes(request, DetermineRequestAttributes(request)); if (!pending_requests_.IsQueued(request)) { - DCHECK(ContainsKey(in_flight_requests_, request)); + DCHECK(base::ContainsKey(in_flight_requests_, request)); // Request has already started. return; } @@ -458,7 +458,7 @@ } // Account for the current request if it is not in one of the lists yet. if (current_request && - !ContainsKey(in_flight_requests_, current_request) && + !base::ContainsKey(in_flight_requests_, current_request) && !current_request_is_pending) { if (RequestAttributesAreSet(current_request->attributes(), attributes)) matching_request_count++; @@ -504,7 +504,7 @@ ScheduledResourceRequest* request) { RequestAttributes attributes = kAttributeNone; - if (ContainsKey(in_flight_requests_, request)) + if (base::ContainsKey(in_flight_requests_, request)) attributes |= kAttributeInFlight; if (RequestAttributesAreSet(request->attributes(), @@ -771,7 +771,7 @@ void ResourceScheduler::RemoveRequest(ScheduledResourceRequest* request) { DCHECK(CalledOnValidThread()); - if (ContainsKey(unowned_requests_, request)) { + if (base::ContainsKey(unowned_requests_, request)) { unowned_requests_.erase(request); return; } @@ -789,7 +789,7 @@ int route_id) { DCHECK(CalledOnValidThread()); ClientId client_id = MakeClientId(child_id, route_id); - DCHECK(!ContainsKey(client_map_, client_id)); + DCHECK(!base::ContainsKey(client_map_, client_id)); Client* client = new Client(this); client_map_[client_id] = client;
diff --git a/content/browser/loader/test_url_loader_client.cc b/content/browser/loader/test_url_loader_client.cc new file mode 100644 index 0000000..2f7234f --- /dev/null +++ b/content/browser/loader/test_url_loader_client.cc
@@ -0,0 +1,67 @@ +// Copyright 2016 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/loader/test_url_loader_client.h" + +#include "base/run_loop.h" + +namespace content { + +TestURLLoaderClient::TestURLLoaderClient() : binding_(this) {} +TestURLLoaderClient::~TestURLLoaderClient() {} + +void TestURLLoaderClient::OnReceiveResponse( + const ResourceResponseHead& response_head) { + has_received_response_ = true; + response_head_ = response_head; + if (quit_closure_for_on_received_response_) + quit_closure_for_on_received_response_.Run(); +} + +void TestURLLoaderClient::OnStartLoadingResponseBody( + mojo::ScopedDataPipeConsumerHandle body) { + response_body_ = std::move(body); + if (quit_closure_for_on_start_loading_response_body_) + quit_closure_for_on_start_loading_response_body_.Run(); +} + +void TestURLLoaderClient::OnComplete( + const ResourceRequestCompletionStatus& status) { + has_received_completion_ = true; + completion_status_ = status; + if (quit_closure_for_on_complete_) + quit_closure_for_on_complete_.Run(); +} + +mojom::URLLoaderClientPtr TestURLLoaderClient::CreateInterfacePtrAndBind() { + return binding_.CreateInterfacePtrAndBind(); +} + +void TestURLLoaderClient::Unbind() { + binding_.Unbind(); + response_body_.reset(); +} + +void TestURLLoaderClient::RunUntilResponseReceived() { + base::RunLoop run_loop; + quit_closure_for_on_received_response_ = run_loop.QuitClosure(); + run_loop.Run(); + quit_closure_for_on_received_response_.Reset(); +} + +void TestURLLoaderClient::RunUntilResponseBodyArrived() { + base::RunLoop run_loop; + quit_closure_for_on_start_loading_response_body_ = run_loop.QuitClosure(); + run_loop.Run(); + quit_closure_for_on_start_loading_response_body_.Reset(); +} + +void TestURLLoaderClient::RunUntilComplete() { + base::RunLoop run_loop; + quit_closure_for_on_complete_ = run_loop.QuitClosure(); + run_loop.Run(); + quit_closure_for_on_complete_.Reset(); +} + +} // namespace content
diff --git a/content/browser/loader/test_url_loader_client.h b/content/browser/loader/test_url_loader_client.h new file mode 100644 index 0000000..78cb46f --- /dev/null +++ b/content/browser/loader/test_url_loader_client.h
@@ -0,0 +1,63 @@ +// Copyright 2016 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_LOADER_TEST_URL_LOADER_CLIENT_H_ +#define CONTENT_BROWSER_LOADER_TEST_URL_LOADER_CLIENT_H_ + +#include "base/callback.h" +#include "base/macros.h" +#include "content/common/resource_request_completion_status.h" +#include "content/common/url_loader.mojom.h" +#include "content/public/common/resource_response.h" +#include "mojo/public/c/system/data_pipe.h" +#include "mojo/public/cpp/bindings/binding.h" + +namespace content { + +// A TestURLLoaderClient records URLLoaderClient function calls. It also calls +// the closure set via set_quit_closure if set, in order to make it possible to +// create a base::RunLoop, set its quit closure to this client and then run the +// RunLoop. +class TestURLLoaderClient final : public mojom::URLLoaderClient { + public: + TestURLLoaderClient(); + ~TestURLLoaderClient() override; + + void OnReceiveResponse(const ResourceResponseHead& response_head) override; + void OnStartLoadingResponseBody( + mojo::ScopedDataPipeConsumerHandle body) override; + void OnComplete(const ResourceRequestCompletionStatus& status) override; + + bool has_received_response() const { return has_received_response_; } + bool has_received_completion() const { return has_received_completion_; } + const ResourceResponseHead& response_head() const { return response_head_; } + mojo::DataPipeConsumerHandle response_body() { return response_body_.get(); } + const ResourceRequestCompletionStatus& completion_status() const { + return completion_status_; + } + + mojom::URLLoaderClientPtr CreateInterfacePtrAndBind(); + void Unbind(); + + void RunUntilResponseReceived(); + void RunUntilResponseBodyArrived(); + void RunUntilComplete(); + + private: + mojo::Binding<mojom::URLLoaderClient> binding_; + ResourceResponseHead response_head_; + mojo::ScopedDataPipeConsumerHandle response_body_; + ResourceRequestCompletionStatus completion_status_; + bool has_received_response_ = false; + bool has_received_completion_ = false; + base::Closure quit_closure_for_on_received_response_; + base::Closure quit_closure_for_on_start_loading_response_body_; + base::Closure quit_closure_for_on_complete_; + + DISALLOW_COPY_AND_ASSIGN(TestURLLoaderClient); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_LOADER_TEST_URL_LOADER_CLIENT_H_
diff --git a/content/browser/loader/url_loader_factory_impl.cc b/content/browser/loader/url_loader_factory_impl.cc new file mode 100644 index 0000000..2f02691c --- /dev/null +++ b/content/browser/loader/url_loader_factory_impl.cc
@@ -0,0 +1,50 @@ +// Copyright 2016 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/loader/url_loader_factory_impl.h" + +#include "content/browser/loader/resource_dispatcher_host_impl.h" +#include "content/browser/loader/resource_message_filter.h" +#include "content/common/resource_request.h" +#include "content/common/url_loader.mojom.h" +#include "content/public/browser/browser_thread.h" + +namespace content { + +URLLoaderFactoryImpl::URLLoaderFactoryImpl( + scoped_refptr<ResourceMessageFilter> resource_message_filter, + mojo::InterfaceRequest<mojom::URLLoaderFactory> request) + : resource_message_filter_(std::move(resource_message_filter)), + binding_(this, std::move(request)) { + DCHECK(resource_message_filter_); + DCHECK_CURRENTLY_ON(BrowserThread::IO); +} + +URLLoaderFactoryImpl::~URLLoaderFactoryImpl() { + DCHECK_CURRENTLY_ON(BrowserThread::IO); +} + +void URLLoaderFactoryImpl::CreateLoaderAndStart( + mojom::URLLoaderRequest request, + int32_t request_id, + const ResourceRequest& url_request, + mojom::URLLoaderClientPtr client) { + DCHECK_CURRENTLY_ON(BrowserThread::IO); + + // TODO(yhirano): Provide the right routing ID. + const int routing_id = 0; + ResourceDispatcherHostImpl* rdh = ResourceDispatcherHostImpl::Get(); + rdh->OnRequestResourceWithMojo(routing_id, request_id, url_request, + std::move(request), std::move(client), + resource_message_filter_.get()); +} + +void URLLoaderFactoryImpl::Create( + scoped_refptr<ResourceMessageFilter> filter, + mojo::InterfaceRequest<mojom::URLLoaderFactory> request) { + // The created instance is held by the StrongBinding. + new URLLoaderFactoryImpl(std::move(filter), std::move(request)); +} + +} // namespace content
diff --git a/content/browser/loader/url_loader_factory_impl.h b/content/browser/loader/url_loader_factory_impl.h new file mode 100644 index 0000000..28fd1ee --- /dev/null +++ b/content/browser/loader/url_loader_factory_impl.h
@@ -0,0 +1,49 @@ +// Copyright 2016 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_LOADER_URL_LOADER_FACTORY_IMPL_H_ +#define CONTENT_BROWSER_LOADER_URL_LOADER_FACTORY_IMPL_H_ + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "content/common/content_export.h" +#include "content/common/url_loader_factory.mojom.h" +#include "mojo/public/cpp/bindings/interface_request.h" +#include "mojo/public/cpp/bindings/strong_binding.h" + +namespace content { + +class ResourceMessageFilter; + +// This class is an implementation of mojom::URLLoaderFactory that creates +// a mojom::URLLoader. +class URLLoaderFactoryImpl final : public mojom::URLLoaderFactory { + public: + ~URLLoaderFactoryImpl() override; + + void CreateLoaderAndStart(mojom::URLLoaderRequest request, + int32_t request_id, + const ResourceRequest& url_request, + mojom::URLLoaderClientPtr client) override; + + // Creates a URLLoaderFactoryImpl instance. The instance is held by the + // StrongBinding in it, so this function doesn't return the instance. + CONTENT_EXPORT static void Create( + scoped_refptr<ResourceMessageFilter> resource_message_filter, + mojo::InterfaceRequest<mojom::URLLoaderFactory> request); + + private: + URLLoaderFactoryImpl( + scoped_refptr<ResourceMessageFilter> resource_message_filter, + mojo::InterfaceRequest<mojom::URLLoaderFactory> request); + + scoped_refptr<ResourceMessageFilter> resource_message_filter_; + mojo::StrongBinding<mojom::URLLoaderFactory> binding_; + + DISALLOW_COPY_AND_ASSIGN(URLLoaderFactoryImpl); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_LOADER_URL_LOADER_FACTORY_IMPL_H_
diff --git a/content/browser/loader/url_loader_factory_impl_unittest.cc b/content/browser/loader/url_loader_factory_impl_unittest.cc new file mode 100644 index 0000000..70f48d6 --- /dev/null +++ b/content/browser/loader/url_loader_factory_impl_unittest.cc
@@ -0,0 +1,243 @@ +// Copyright 2016 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/loader/url_loader_factory_impl.h" + +#include <memory> +#include <string> +#include <utility> + +#include "base/bind.h" +#include "base/callback.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/location.h" +#include "base/memory/ptr_util.h" +#include "base/memory/weak_ptr.h" +#include "base/message_loop/message_loop.h" +#include "base/path_service.h" +#include "base/run_loop.h" +#include "content/browser/loader/mojo_async_resource_handler.h" +#include "content/browser/loader/resource_dispatcher_host_impl.h" +#include "content/browser/loader/resource_message_filter.h" +#include "content/browser/loader/test_url_loader_client.h" +#include "content/browser/loader_delegate_impl.h" +#include "content/common/resource_request.h" +#include "content/common/resource_request_completion_status.h" +#include "content/common/url_loader.mojom.h" +#include "content/public/browser/resource_context.h" +#include "content/public/browser/resource_dispatcher_host_delegate.h" +#include "content/public/common/content_paths.h" +#include "content/public/test/test_browser_context.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "mojo/public/c/system/data_pipe.h" +#include "mojo/public/c/system/types.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/system/data_pipe.h" +#include "net/base/io_buffer.h" +#include "net/base/net_errors.h" +#include "net/http/http_response_headers.h" +#include "net/http/http_response_info.h" +#include "net/http/http_status_code.h" +#include "net/http/http_util.h" +#include "net/test/url_request/url_request_failed_job.h" +#include "net/test/url_request/url_request_mock_http_job.h" +#include "net/url_request/url_request_filter.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace content { + +namespace { + +class RejectingResourceDispatcherHostDelegate final + : public ResourceDispatcherHostDelegate { + public: + RejectingResourceDispatcherHostDelegate() {} + bool ShouldBeginRequest(const std::string& method, + const GURL& url, + ResourceType resource_type, + ResourceContext* resource_context) override { + return false; + } + + DISALLOW_COPY_AND_ASSIGN(RejectingResourceDispatcherHostDelegate); +}; + +// The test parameter is the number of bytes allocated for the buffer in the +// data pipe, for testing the case where the allocated size is smaller than the +// size the mime sniffer *implicitly* requires. +class URLLoaderFactoryImplTest : public ::testing::TestWithParam<size_t> { + public: + URLLoaderFactoryImplTest() + : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP), + browser_context_(new TestBrowserContext()), + resource_message_filter_(new ResourceMessageFilter( + 0, + 0, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + base::Bind(&URLLoaderFactoryImplTest::GetContexts, + base::Unretained(this)))) { + MojoAsyncResourceHandler::SetAllocationSizeForTesting(GetParam()); + rdh_.SetLoaderDelegate(&loader_deleate_); + + URLLoaderFactoryImpl::Create(resource_message_filter_, + mojo::GetProxy(&factory_)); + + // Calling this function creates a request context. + browser_context_->GetResourceContext()->GetRequestContext(); + base::RunLoop().RunUntilIdle(); + } + + ~URLLoaderFactoryImplTest() override { + rdh_.SetDelegate(nullptr); + net::URLRequestFilter::GetInstance()->ClearHandlers(); + + rdh_.CancelRequestsForProcess(resource_message_filter_->child_id()); + base::RunLoop().RunUntilIdle(); + MojoAsyncResourceHandler::SetAllocationSizeForTesting( + MojoAsyncResourceHandler::kDefaultAllocationSize); + } + + void GetContexts(ResourceType resource_type, + ResourceContext** resource_context, + net::URLRequestContext** request_context) { + *resource_context = browser_context_->GetResourceContext(); + *request_context = + browser_context_->GetResourceContext()->GetRequestContext(); + } + + TestBrowserThreadBundle thread_bundle_; + LoaderDelegateImpl loader_deleate_; + ResourceDispatcherHostImpl rdh_; + std::unique_ptr<TestBrowserContext> browser_context_; + scoped_refptr<ResourceMessageFilter> resource_message_filter_; + mojom::URLLoaderFactoryPtr factory_; + + DISALLOW_COPY_AND_ASSIGN(URLLoaderFactoryImplTest); +}; + +TEST_P(URLLoaderFactoryImplTest, GetResponse) { + mojom::URLLoaderPtr loader; + base::FilePath root; + PathService::Get(DIR_TEST_DATA, &root); + net::URLRequestMockHTTPJob::AddUrlHandlers(root, + BrowserThread::GetBlockingPool()); + ResourceRequest request; + TestURLLoaderClient client; + // Assume the file contents is small enough to be stored in the data pipe. + request.url = net::URLRequestMockHTTPJob::GetMockUrl("hello.html"); + request.method = "GET"; + request.is_main_frame = true; + factory_->CreateLoaderAndStart(mojo::GetProxy(&loader), 1, request, + client.CreateInterfacePtrAndBind()); + + ASSERT_FALSE(client.has_received_response()); + ASSERT_FALSE(client.response_body().is_valid()); + ASSERT_FALSE(client.has_received_completion()); + + client.RunUntilResponseReceived(); + ASSERT_FALSE(client.has_received_completion()); + ASSERT_FALSE(client.has_received_completion()); + + client.RunUntilResponseBodyArrived(); + ASSERT_TRUE(client.response_body().is_valid()); + ASSERT_FALSE(client.has_received_completion()); + + client.RunUntilComplete(); + + EXPECT_EQ(200, client.response_head().headers->response_code()); + std::string content_type; + client.response_head().headers->GetNormalizedHeader("content-type", + &content_type); + EXPECT_EQ("text/html", content_type); + EXPECT_EQ(0, client.completion_status().error_code); + + std::string contents; + while (true) { + char buffer[16]; + uint32_t read_size = sizeof(buffer); + MojoResult r = mojo::ReadDataRaw(client.response_body(), buffer, &read_size, + MOJO_READ_DATA_FLAG_NONE); + if (r == MOJO_RESULT_FAILED_PRECONDITION) + break; + if (r == MOJO_RESULT_SHOULD_WAIT) + continue; + ASSERT_EQ(MOJO_RESULT_OK, r); + contents += std::string(buffer, read_size); + } + std::string expected; + base::ReadFileToString( + root.Append(base::FilePath(FILE_PATH_LITERAL("hello.html"))), &expected); + EXPECT_EQ(expected, contents); +} + +TEST_P(URLLoaderFactoryImplTest, GetFailedResponse) { + mojom::URLLoaderPtr loader; + ResourceRequest request; + TestURLLoaderClient client; + net::URLRequestFailedJob::AddUrlHandler(); + request.url = net::URLRequestFailedJob::GetMockHttpUrlWithFailurePhase( + net::URLRequestFailedJob::START, net::ERR_TIMED_OUT); + request.method = "GET"; + factory_->CreateLoaderAndStart(mojo::GetProxy(&loader), 1, request, + client.CreateInterfacePtrAndBind()); + + client.RunUntilComplete(); + ASSERT_FALSE(client.has_received_response()); + ASSERT_FALSE(client.response_body().is_valid()); + + EXPECT_EQ(net::ERR_TIMED_OUT, client.completion_status().error_code); +} + +// This test tests a case where resource loading is cancelled before started. +TEST_P(URLLoaderFactoryImplTest, InvalidURL) { + mojom::URLLoaderPtr loader; + ResourceRequest request; + TestURLLoaderClient client; + request.url = GURL(); + request.method = "GET"; + ASSERT_FALSE(request.url.is_valid()); + factory_->CreateLoaderAndStart(mojo::GetProxy(&loader), 1, request, + client.CreateInterfacePtrAndBind()); + + client.RunUntilComplete(); + ASSERT_FALSE(client.has_received_response()); + ASSERT_FALSE(client.response_body().is_valid()); + + EXPECT_EQ(net::ERR_ABORTED, client.completion_status().error_code); +} + +// This test tests a case where resource loading is cancelled before started. +TEST_P(URLLoaderFactoryImplTest, ShouldNotRequestURL) { + mojom::URLLoaderPtr loader; + RejectingResourceDispatcherHostDelegate rdh_delegate; + rdh_.SetDelegate(&rdh_delegate); + ResourceRequest request; + TestURLLoaderClient client; + request.url = GURL("http://localhost/"); + request.method = "GET"; + factory_->CreateLoaderAndStart(mojo::GetProxy(&loader), 1, request, + client.CreateInterfacePtrAndBind()); + + client.RunUntilComplete(); + rdh_.SetDelegate(nullptr); + + ASSERT_FALSE(client.has_received_response()); + ASSERT_FALSE(client.response_body().is_valid()); + + EXPECT_EQ(net::ERR_ABORTED, client.completion_status().error_code); +} + +INSTANTIATE_TEST_CASE_P(URLLoaderFactoryImplTest, + URLLoaderFactoryImplTest, + ::testing::Values(128, 32 * 1024)); + +} // namespace + +} // namespace content
diff --git a/content/browser/manifest/manifest_manager_host.cc b/content/browser/manifest/manifest_manager_host.cc index ea6557f..5891affd 100644 --- a/content/browser/manifest/manifest_manager_host.cc +++ b/content/browser/manifest/manifest_manager_host.cc
@@ -33,7 +33,7 @@ } ManifestManagerHost::~ManifestManagerHost() { - STLDeleteValues(&pending_get_callbacks_); + base::STLDeleteValues(&pending_get_callbacks_); } ManifestManagerHost::GetCallbackMap*
diff --git a/content/browser/media/android/media_player_renderer.cc b/content/browser/media/android/media_player_renderer.cc new file mode 100644 index 0000000..3b7708b --- /dev/null +++ b/content/browser/media/android/media_player_renderer.cc
@@ -0,0 +1,228 @@ +// Copyright 2016 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/media/android/media_player_renderer.h" + +#include <memory> + +#include "content/browser/media/android/media_resource_getter_impl.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/content_client.h" + +// TODO(tguilbert): Remove this ID once MediaPlayerManager has been deleted +// and MediaPlayerBridge updated. See comment in header file. +constexpr int kUnusedAndIrrelevantPlayerId = 0; + +namespace content { + +MediaPlayerRenderer::MediaPlayerRenderer(RenderFrameHost* render_frame_host) + : render_frame_host_(render_frame_host), + has_error_(false), + weak_factory_(this) {} + +MediaPlayerRenderer::~MediaPlayerRenderer() {} + +void MediaPlayerRenderer::Initialize( + media::DemuxerStreamProvider* demuxer_stream_provider, + media::RendererClient* client, + const media::PipelineStatusCB& init_cb) { + DVLOG(1) << __func__; + if (demuxer_stream_provider->GetType() != + media::DemuxerStreamProvider::Type::URL) { + DLOG(ERROR) << "DemuxerStreamProvider is not of Type URL"; + init_cb.Run(media::PIPELINE_ERROR_INITIALIZATION_FAILED); + return; + } + + GURL url = demuxer_stream_provider->GetUrl(); + renderer_client_ = client; + + const std::string user_agent = GetContentClient()->GetUserAgent(); + + // TODO(tguilbert): Get the first party cookies from WMPI. See + // crbug.com/636604. + media_player_.reset(new media::MediaPlayerBridge( + kUnusedAndIrrelevantPlayerId, url, + GURL(), // first_party_for_cookies + user_agent, + false, // hide_url_log + this, base::Bind(&MediaPlayerRenderer::OnDecoderResourcesReleased, + weak_factory_.GetWeakPtr()), + GURL(), // frame_url + false, // allow_crendentials + 0)); // media_session_id + + // TODO(tguilbert): Register and Send the proper surface ID. See + // crbug.com/627658 + + media_player_->Initialize(); + init_cb.Run(media::PIPELINE_OK); +} + +void MediaPlayerRenderer::SetCdm(media::CdmContext* cdm_context, + const media::CdmAttachedCB& cdm_attached_cb) { + NOTREACHED(); +} + +void MediaPlayerRenderer::Flush(const base::Closure& flush_cb) { + DVLOG(3) << __func__; + flush_cb.Run(); +} + +void MediaPlayerRenderer::StartPlayingFrom(base::TimeDelta time) { + // MediaPlayerBridge's Start() is idempotent, except when it has encountered + // an error (in which case, calling Start() again is logged as a new error). + if (has_error_) + return; + + media_player_->Start(); + media_player_->SeekTo(time); +} + +void MediaPlayerRenderer::SetPlaybackRate(double playback_rate) { + if (has_error_) + return; + + if (playback_rate == 0) { + media_player_->Pause(true); + } else { + // MediaPlayerBridge's Start() is idempotent. + media_player_->Start(); + + // TODO(tguilbert): MediaPlayer's interface allows variable playback rate, + // but is not currently exposed in the MediaPlayerBridge interface. + // Investigate wether or not we want to add variable playback speed. + } +} + +void MediaPlayerRenderer::SetVolume(float volume) { + media_player_->SetVolume(volume); +} + +base::TimeDelta MediaPlayerRenderer::GetMediaTime() { + return media_player_->GetCurrentTime(); +} + +bool MediaPlayerRenderer::HasAudio() { + return media_player_->HasAudio(); +} + +bool MediaPlayerRenderer::HasVideo() { + return media_player_->HasVideo(); +} + +media::MediaResourceGetter* MediaPlayerRenderer::GetMediaResourceGetter() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); + if (!media_resource_getter_.get()) { + WebContents* web_contents = + WebContents::FromRenderFrameHost(render_frame_host_); + RenderProcessHost* host = web_contents->GetRenderProcessHost(); + BrowserContext* context = host->GetBrowserContext(); + StoragePartition* partition = host->GetStoragePartition(); + storage::FileSystemContext* file_system_context = + partition ? partition->GetFileSystemContext() : nullptr; + media_resource_getter_.reset( + new MediaResourceGetterImpl(context, file_system_context, host->GetID(), + render_frame_host_->GetRoutingID())); + } + return media_resource_getter_.get(); +} + +media::MediaUrlInterceptor* MediaPlayerRenderer::GetMediaUrlInterceptor() { + // TODO(tguilbert): Offer a RegisterMediaUrlInterceptor equivalent for use in + // webview. See crbug.com/636588. + return nullptr; +} + +void MediaPlayerRenderer::OnTimeUpdate(int player_id, + base::TimeDelta current_timestamp, + base::TimeTicks current_time_ticks) {} + +void MediaPlayerRenderer::OnMediaMetadataChanged(int player_id, + base::TimeDelta duration, + int width, + int height, + bool success) { + if (video_size_ != gfx::Size(width, height)) + OnVideoSizeChanged(kUnusedAndIrrelevantPlayerId, width, height); + + if (duration_ != duration) { + duration_ = duration; + renderer_client_->OnDurationChange(duration); + } +} + +void MediaPlayerRenderer::OnPlaybackComplete(int player_id) { + renderer_client_->OnEnded(); +} + +void MediaPlayerRenderer::OnMediaInterrupted(int player_id) {} + +void MediaPlayerRenderer::OnBufferingUpdate(int player_id, int percentage) { + // As per Android documentation, |percentage| actually indicates "percentage + // buffered or played". E.g. if we are at 50% playback and have 1% + // buffered, |percentage| will be equal to 51. + // + // MediaPlayer manages its own buffering and will pause internally if ever it + // runs out of data. Therefore, we can always return BUFFERING_HAVE_ENOUGH. + renderer_client_->OnBufferingStateChange(media::BUFFERING_HAVE_ENOUGH); +} + +void MediaPlayerRenderer::OnSeekComplete(int player_id, + const base::TimeDelta& current_time) {} + +void MediaPlayerRenderer::OnError(int player_id, int error) { + // Some errors are forwarded to the MediaPlayerListener, but are of no + // importance to us. Ignore these errors, which are reported as error 0 by + // MediaPlayerListener. + if (!error) + return; + + LOG(ERROR) << __func__ << " Error: " << error; + has_error_ = true; + renderer_client_->OnError(media::PIPELINE_ERROR_EXTERNAL_RENDERER_FAILED); +} + +void MediaPlayerRenderer::OnVideoSizeChanged(int player_id, + int width, + int height) { + video_size_ = gfx::Size(width, height); + renderer_client_->OnVideoNaturalSizeChange(video_size_); +} + +void MediaPlayerRenderer::OnWaitingForDecryptionKey(int player_id) { + NOTREACHED(); +} + +media::MediaPlayerAndroid* MediaPlayerRenderer::GetFullscreenPlayer() { + NOTREACHED(); + return nullptr; +} + +media::MediaPlayerAndroid* MediaPlayerRenderer::GetPlayer(int player_id) { + NOTREACHED(); + return nullptr; +} + +bool MediaPlayerRenderer::RequestPlay(int player_id, + base::TimeDelta duration, + bool has_audio) { + // TODO(tguilbert): Throttle requests, via exponential backoff. + // See crbug.com/636615. + return true; +} + +void MediaPlayerRenderer::OnDecoderResourcesReleased(int player_id) { + // Since we are not using a pool of MediaPlayerAndroid instances, this + // function is not relevant. + + // TODO(tguilbert): Throttle requests, via exponential backoff. + // See crbug.com/636615. +} + +} // namespace content
diff --git a/content/browser/media/android/media_player_renderer.h b/content/browser/media/android/media_player_renderer.h new file mode 100644 index 0000000..42c2dec --- /dev/null +++ b/content/browser/media/android/media_player_renderer.h
@@ -0,0 +1,115 @@ +// Copyright 2016 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_MEDIA_ANDROID_MEDIA_PLAYER_RENDERER_H_ +#define CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_PLAYER_RENDERER_H_ + +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "content/common/content_export.h" +#include "content/public/browser/render_frame_host.h" +#include "media/base/android/media_player_bridge.h" +#include "media/base/android/media_player_manager.h" +#include "media/base/demuxer_stream_provider.h" +#include "media/base/media_log.h" +#include "media/base/renderer.h" +#include "media/base/renderer_client.h" +#include "url/gurl.h" + +namespace content { + +// MediaPlayerRenderer bridges the media::Renderer and Android MediaPlayer +// interfaces. It owns a MediaPlayerBridge, which exposes c++ methods to call +// into a native Android MediaPlayer. +// +// Each MediaPlayerRenderer is associated with one MediaPlayerRendererClient, +// living in WMPI in the Renderer process. +// +// N.B: MediaPlayerRenderer implements MediaPlayerManager, since +// MediaPlayerBridge is tightly coupled with the manager abstraction. +// |player_id| is ignored in all MediaPlayerManager calls, as there is only one +// MediaPlayer per MediaPlayerRenderer. +// +// TODO(tguilbert): Remove the MediaPlayerManager implementation and update +// MediaPlayerBridge, once WMPA has been deleted. See http://crbug.com/580626 +class CONTENT_EXPORT MediaPlayerRenderer : public media::Renderer, + public media::MediaPlayerManager { + public: + explicit MediaPlayerRenderer(content::RenderFrameHost* render_frame_host); + + ~MediaPlayerRenderer() override; + + // media::Renderer implementation + void Initialize(media::DemuxerStreamProvider* demuxer_stream_provider, + media::RendererClient* client, + const media::PipelineStatusCB& init_cb) override; + void SetCdm(media::CdmContext* cdm_context, + const media::CdmAttachedCB& cdm_attached_cb) override; + void Flush(const base::Closure& flush_cb) override; + void StartPlayingFrom(base::TimeDelta time) override; + + // N.B: MediaPlayerBridge doesn't support variable playback rates (but it + // could be exposed from MediaPlayer in the future). For the moment: + // - If |playback_rate| is 0, we pause the video. + // - For other |playback_rate| values, we start playing at 1x speed. + void SetPlaybackRate(double playback_rate) override; + void SetVolume(float volume) override; + base::TimeDelta GetMediaTime() override; + bool HasAudio() override; + bool HasVideo() override; + + // media::MediaPlayerManager implementation + media::MediaResourceGetter* GetMediaResourceGetter() override; + media::MediaUrlInterceptor* GetMediaUrlInterceptor() override; + void OnTimeUpdate(int player_id, + base::TimeDelta current_timestamp, + base::TimeTicks current_time_ticks) override; + void OnMediaMetadataChanged(int player_id, + base::TimeDelta duration, + int width, + int height, + bool success) override; + void OnPlaybackComplete(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; + void OnWaitingForDecryptionKey(int player_id) override; + media::MediaPlayerAndroid* GetFullscreenPlayer() override; + media::MediaPlayerAndroid* GetPlayer(int player_id) override; + bool RequestPlay(int player_id, + base::TimeDelta duration, + bool has_audio) override; + + private: + // Used when creating |media_player_|. + void OnDecoderResourcesReleased(int player_id); + + RenderFrameHost* render_frame_host_; + media::RendererClient* renderer_client_; + + std::unique_ptr<media::MediaPlayerBridge> media_player_; + + // Current duration of the media. + base::TimeDelta duration_; + + // Indicates if a serious error has been encountered by the |media_player_|. + bool has_error_; + + gfx::Size video_size_; + + std::unique_ptr<media::MediaResourceGetter> media_resource_getter_; + + // NOTE: Weak pointers must be invalidated before all other member variables. + base::WeakPtrFactory<MediaPlayerRenderer> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(MediaPlayerRenderer); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_MEDIA_ANDROID_MEDIA_PLAYER_RENDERER_H_
diff --git a/content/browser/mojo/mojo_child_connection.cc b/content/browser/mojo/mojo_child_connection.cc index 830fac4..1344f3b 100644 --- a/content/browser/mojo/mojo_child_connection.cc +++ b/content/browser/mojo/mojo_child_connection.cc
@@ -23,7 +23,7 @@ void CallBinderOnTaskRunner( const shell::InterfaceRegistry::Binder& binder, scoped_refptr<base::SequencedTaskRunner> task_runner, - const mojo::String& interface_name, + const std::string& interface_name, mojo::ScopedMessagePipeHandle request_handle) { task_runner->PostTask( FROM_HERE, @@ -64,7 +64,7 @@ } void GetRemoteInterfaceOnIOThread( - const mojo::String& interface_name, + const std::string& interface_name, mojo::ScopedMessagePipeHandle request_handle) { if (connection_) { connection_->GetRemoteInterfaces()->GetInterface(
diff --git a/content/browser/mojo/mojo_shell_context.cc b/content/browser/mojo/mojo_shell_context.cc index cb0f5bd2..7ad111d 100644 --- a/content/browser/mojo/mojo_shell_context.cc +++ b/content/browser/mojo/mojo_shell_context.cc
@@ -27,6 +27,7 @@ #include "services/catalog/catalog.h" #include "services/catalog/manifest_provider.h" #include "services/catalog/store.h" +#include "services/file/public/cpp/constants.h" #include "services/shell/connect_params.h" #include "services/shell/native_runner.h" #include "services/shell/public/cpp/connector.h" @@ -35,7 +36,6 @@ #include "services/shell/runner/common/client_util.h" #include "services/shell/runner/host/in_process_native_runner.h" #include "services/shell/service_manager.h" -#include "services/user/public/cpp/constants.h" namespace content { @@ -236,8 +236,8 @@ IDR_MOJO_CONTENT_UTILITY_MANIFEST); manifest_provider->AddManifestResource("mojo:catalog", IDR_MOJO_CATALOG_MANIFEST); - manifest_provider->AddManifestResource(user_service::kUserServiceName, - IDR_MOJO_PROFILE_MANIFEST); + manifest_provider->AddManifestResource(file::kFileServiceName, + IDR_MOJO_FILE_MANIFEST); in_process_context_ = new InProcessServiceManagerContext; request = in_process_context_->Start(std::move(manifest_provider));
diff --git a/content/browser/net/quota_policy_cookie_store_unittest.cc b/content/browser/net/quota_policy_cookie_store_unittest.cc index bb77240..73f8366a 100644 --- a/content/browser/net/quota_policy_cookie_store_unittest.cc +++ b/content/browser/net/quota_policy_cookie_store_unittest.cc
@@ -150,7 +150,7 @@ DestroyStore(); // Reload and test for persistence. - STLDeleteElements(&cookies); + base::STLDeleteElements(&cookies); CreateAndLoad(nullptr, &cookies); EXPECT_EQ(2U, cookies.size()); bool found_foo_cookie = false; @@ -170,10 +170,10 @@ DestroyStore(); // Reload and check if the cookies have been removed. - STLDeleteElements(&cookies); + base::STLDeleteElements(&cookies); CreateAndLoad(nullptr, &cookies); EXPECT_EQ(0U, cookies.size()); - STLDeleteElements(&cookies); + base::STLDeleteElements(&cookies); } // Test if data is stored as expected in the QuotaPolicy database. @@ -201,7 +201,7 @@ net::cookie_util::CookieOriginToURL("nonpersistent.com", false)); // Reload and test for persistence. - STLDeleteElements(&cookies); + base::STLDeleteElements(&cookies); CreateAndLoad(storage_policy.get(), &cookies); EXPECT_EQ(3U, cookies.size()); @@ -212,14 +212,14 @@ // Now close the store, and "nonpersistent.com" should be deleted according to // policy. DestroyStore(); - STLDeleteElements(&cookies); + base::STLDeleteElements(&cookies); CreateAndLoad(nullptr, &cookies); EXPECT_EQ(2U, cookies.size()); for (auto* cookie : cookies) { EXPECT_NE("nonpersistent.com", cookie->Domain()); } - STLDeleteElements(&cookies); + base::STLDeleteElements(&cookies); } TEST_F(QuotaPolicyCookieStoreTest, ForceKeepSessionState) { @@ -239,7 +239,7 @@ net::cookie_util::CookieOriginToURL("nonpersistent.com", false)); // Reload and test for persistence - STLDeleteElements(&cookies); + base::STLDeleteElements(&cookies); CreateAndLoad(storage_policy.get(), &cookies); EXPECT_EQ(1U, cookies.size()); @@ -252,11 +252,11 @@ // deleted. store_->SetForceKeepSessionState(); DestroyStore(); - STLDeleteElements(&cookies); + base::STLDeleteElements(&cookies); CreateAndLoad(nullptr, &cookies); EXPECT_EQ(3U, cookies.size()); - STLDeleteElements(&cookies); + base::STLDeleteElements(&cookies); } // Tests that the special storage policy is properly applied even when the store @@ -282,11 +282,11 @@ DestroyStoreOnBackgroundThread(); // Reload and test for persistence. - STLDeleteElements(&cookies); + base::STLDeleteElements(&cookies); CreateAndLoad(storage_policy.get(), &cookies); EXPECT_EQ(0U, cookies.size()); - STLDeleteElements(&cookies); + base::STLDeleteElements(&cookies); } } // namespace
diff --git a/content/browser/permissions/permission_service_impl.cc b/content/browser/permissions/permission_service_impl.cc index e4506403..7a34dc9 100644 --- a/content/browser/permissions/permission_service_impl.cc +++ b/content/browser/permissions/permission_service_impl.cc
@@ -51,7 +51,7 @@ // with single requests. void PermissionRequestResponseCallbackWrapper( const base::Callback<void(PermissionStatus)>& callback, - mojo::Array<PermissionStatus> vector) { + const std::vector<PermissionStatus>& vector) { DCHECK_EQ(vector.size(), 1ul); callback.Run(vector[0]); } @@ -69,11 +69,8 @@ if (callback.is_null()) return; - mojo::Array<PermissionStatus> result = - mojo::Array<PermissionStatus>::New(request_count); - for (int i = 0; i < request_count; ++i) - result[i] = PermissionStatus::DENIED; - callback.Run(std::move(result)); + std::vector<PermissionStatus> result(request_count, PermissionStatus::DENIED); + callback.Run(result); } PermissionServiceImpl::PendingSubscription::PendingSubscription( @@ -114,7 +111,7 @@ void PermissionServiceImpl::RequestPermission( PermissionName permission, - const mojo::String& origin, + const std::string& origin, bool user_gesture, const PermissionStatusCallback& callback) { // This condition is valid if the call is coming from a ChildThread instead of @@ -128,20 +125,17 @@ DCHECK(browser_context); if (!context_->render_frame_host() || !browser_context->GetPermissionManager()) { - callback.Run(GetPermissionStatusFromName(permission, GURL(origin.get()))); + callback.Run(GetPermissionStatusFromName(permission, GURL(origin))); return; } int pending_request_id = pending_requests_.Add(new PendingRequest( base::Bind(&PermissionRequestResponseCallbackWrapper, callback), 1)); int id = browser_context->GetPermissionManager()->RequestPermission( - PermissionNameToPermissionType(permission), - context_->render_frame_host(), - GURL(origin.get()), - user_gesture, + PermissionNameToPermissionType(permission), context_->render_frame_host(), + GURL(origin), user_gesture, base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse, - weak_factory_.GetWeakPtr(), - pending_request_id)); + weak_factory_.GetWeakPtr(), pending_request_id)); // Check if the request still exists. It might have been removed by the // callback if it was run synchronously. @@ -160,15 +154,10 @@ } void PermissionServiceImpl::RequestPermissions( - mojo::Array<PermissionName> permissions, - const mojo::String& origin, + const std::vector<PermissionName>& permissions, + const std::string& origin, bool user_gesture, const RequestPermissionsCallback& callback) { - if (permissions.is_null()) { - callback.Run(mojo::Array<PermissionStatus>()); - return; - } - // This condition is valid if the call is coming from a ChildThread instead of // a RenderFrame. Some consumers of the service run in Workers and some in // Frames. In the context of a Worker, it is not possible to show a @@ -180,12 +169,11 @@ DCHECK(browser_context); if (!context_->render_frame_host() || !browser_context->GetPermissionManager()) { - mojo::Array<PermissionStatus> result(permissions.size()); + std::vector<PermissionStatus> result(permissions.size()); for (size_t i = 0; i < permissions.size(); ++i) { - result[i] = - GetPermissionStatusFromName(permissions[i], GURL(origin.get())); + result[i] = GetPermissionStatusFromName(permissions[i], GURL(origin)); } - callback.Run(std::move(result)); + callback.Run(result); return; } @@ -196,13 +184,9 @@ int pending_request_id = pending_requests_.Add( new PendingRequest(callback, permissions.size())); int id = browser_context->GetPermissionManager()->RequestPermissions( - types, - context_->render_frame_host(), - GURL(origin.get()), - user_gesture, + types, context_->render_frame_host(), GURL(origin), user_gesture, base::Bind(&PermissionServiceImpl::OnRequestPermissionsResponse, - weak_factory_.GetWeakPtr(), - pending_request_id)); + weak_factory_.GetWeakPtr(), pending_request_id)); // Check if the request still exists. It may have been removed by the // the response callback. @@ -220,7 +204,7 @@ RequestPermissionsCallback callback(request->callback); request->callback.Reset(); pending_requests_.Remove(pending_request_id); - callback.Run(mojo::Array<PermissionStatus>::From(result)); + callback.Run(result); } void PermissionServiceImpl::CancelPendingOperations() { @@ -253,16 +237,16 @@ void PermissionServiceImpl::HasPermission( PermissionName permission, - const mojo::String& origin, + const std::string& origin, const PermissionStatusCallback& callback) { - callback.Run(GetPermissionStatusFromName(permission, GURL(origin.get()))); + callback.Run(GetPermissionStatusFromName(permission, GURL(origin))); } void PermissionServiceImpl::RevokePermission( PermissionName permission, - const mojo::String& origin, + const std::string& origin, const PermissionStatusCallback& callback) { - GURL origin_url(origin.get()); + GURL origin_url(origin); PermissionType permission_type = PermissionNameToPermissionType(permission); PermissionStatus status = GetPermissionStatusFromType(permission_type, origin_url); @@ -281,10 +265,10 @@ void PermissionServiceImpl::GetNextPermissionChange( PermissionName permission, - const mojo::String& mojo_origin, + const std::string& mojo_origin, PermissionStatus last_known_status, const PermissionStatusCallback& callback) { - GURL origin(mojo_origin.get()); + GURL origin(mojo_origin); PermissionStatus current_status = GetPermissionStatusFromName(permission, origin); if (current_status != last_known_status) {
diff --git a/content/browser/permissions/permission_service_impl.h b/content/browser/permissions/permission_service_impl.h index 208c058..d5a3029 100644 --- a/content/browser/permissions/permission_service_impl.h +++ b/content/browser/permissions/permission_service_impl.h
@@ -71,22 +71,23 @@ // blink::mojom::PermissionService. void HasPermission(blink::mojom::PermissionName permission, - const mojo::String& origin, + const std::string& origin, const PermissionStatusCallback& callback) override; void RequestPermission(blink::mojom::PermissionName permission, - const mojo::String& origin, + const std::string& origin, bool user_gesture, const PermissionStatusCallback& callback) override; - void RequestPermissions(mojo::Array<blink::mojom::PermissionName> permissions, - const mojo::String& origin, - bool user_gesture, - const RequestPermissionsCallback& callback) override; + void RequestPermissions( + const std::vector<blink::mojom::PermissionName>& permissions, + const std::string& origin, + bool user_gesture, + const RequestPermissionsCallback& callback) override; void RevokePermission(blink::mojom::PermissionName permission, - const mojo::String& origin, + const std::string& origin, const PermissionStatusCallback& callback) override; void GetNextPermissionChange( blink::mojom::PermissionName permission, - const mojo::String& origin, + const std::string& origin, blink::mojom::PermissionStatus last_known_status, const PermissionStatusCallback& callback) override;
diff --git a/content/browser/plugin_private_storage_helper.cc b/content/browser/plugin_private_storage_helper.cc index d7c6228a..3d241ea 100644 --- a/content/browser/plugin_private_storage_helper.cc +++ b/content/browser/plugin_private_storage_helper.cc
@@ -395,7 +395,7 @@ // If a specific origin is provided, then check that it is in the list // returned and remove all the other origins. if (!storage_origin.is_empty()) { - if (!ContainsKey(origins, storage_origin)) { + if (!base::ContainsKey(origins, storage_origin)) { // Nothing matches, so nothing to do. callback.Run(); return;
diff --git a/content/browser/renderer_host/DEPS b/content/browser/renderer_host/DEPS index e211ee6..49841f3f 100644 --- a/content/browser/renderer_host/DEPS +++ b/content/browser/renderer_host/DEPS
@@ -22,7 +22,6 @@ "+content/public/browser/web_contents_view.h", ], "render_process_host_impl\.cc": [ - "+services/ui/common/switches.h", "+content/browser/frame_host/render_frame_message_filter.h", ], "render_widget_host_view_mac\.mm": [
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index db423cc..bc9028a6 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -404,6 +404,9 @@ DCHECK(root_window); DCHECK(root_window->GetLayer() == nullptr); root_window->SetLayer(cc::Layer::Create()); + readback_layer_tree_ = cc::Layer::Create(); + readback_layer_tree_->SetHideLayerAndSubtree(true); + root_window->GetLayer()->AddChild(readback_layer_tree_); root_window->AttachCompositor(this); CreateLayerTreeHost(); resource_manager_.Init(host_.get()); @@ -514,6 +517,13 @@ TRACE_EVENT1("cc", "CompositorImpl::SetVisible", "visible", visible); if (!visible) { DCHECK(host_->visible()); + + // Make a best effort to try to complete pending readbacks. + // TODO(crbug.com/637035): Consider doing this in a better way, + // ideally with the guarantee of readbacks completing. + if (display_.get() && HavePendingReadbacks()) + display_->ForceImmediateDrawAndSwapIfPossible(); + host_->SetVisible(false); if (!host_->output_surface_lost()) host_->ReleaseOutputSurface(); @@ -750,6 +760,10 @@ root_window_->OnCompositingDidCommit(); } +void CompositorImpl::AttachLayerForReadback(scoped_refptr<cc::Layer> layer) { + readback_layer_tree_->AddChild(layer); +} + void CompositorImpl::RequestCopyOfOutputOnRootLayer( std::unique_ptr<cc::CopyOutputRequest> request) { root_window_->GetLayer()->RequestCopyOfOutput(std::move(request)); @@ -781,4 +795,8 @@ host_->SetNeedsAnimate(); } +bool CompositorImpl::HavePendingReadbacks() { + return !readback_layer_tree_->children().empty(); +} + } // namespace content
diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h index 1b53f8b..6638afd 100644 --- a/content/browser/renderer_host/compositor_impl_android.h +++ b/content/browser/renderer_host/compositor_impl_android.h
@@ -112,6 +112,7 @@ void DidAbortSwapBuffers() override; // WindowAndroidCompositor implementation. + void AttachLayerForReadback(scoped_refptr<cc::Layer> layer) override; void RequestCopyOfOutputOnRootLayer( std::unique_ptr<cc::CopyOutputRequest> request) override; void OnVSync(base::TimeTicks frame_time, @@ -132,10 +133,15 @@ scoped_refptr<cc::VulkanContextProvider> vulkan_context_provider, scoped_refptr<cc::ContextProvider> context_provider); + bool HavePendingReadbacks(); + // root_layer_ is the persistent internal root layer, while subroot_layer_ // is the one attached by the compositor client. scoped_refptr<cc::Layer> subroot_layer_; + // Subtree for hidden layers with CopyOutputRequests on them. + scoped_refptr<cc::Layer> readback_layer_tree_; + // Destruction order matters here: std::unique_ptr<cc::SurfaceIdAllocator> surface_id_allocator_; base::ObserverList<VSyncObserver, true> observer_list_;
diff --git a/content/browser/renderer_host/context_provider_factory_impl_android.cc b/content/browser/renderer_host/context_provider_factory_impl_android.cc index d3db966..40cc97c 100644 --- a/content/browser/renderer_host/context_provider_factory_impl_android.cc +++ b/content/browser/renderer_host/context_provider_factory_impl_android.cc
@@ -235,6 +235,11 @@ scoped_refptr<gpu::GpuChannelHost> gpu_channel) { establish_gpu_channel_timeout_.Stop(); + // This should happen only during shutdown. So early out instead of queuing + // more requests with the factory. + if (!gpu_channel) + return; + // We can queue the Gpu Channel initialization requests multiple times as // we get context requests. So we might have already handled any pending // requests when this callback runs.
diff --git a/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc b/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc index 0e9907a0..eccace7 100644 --- a/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc +++ b/content/browser/renderer_host/dwrite_font_proxy_message_filter_win.cc
@@ -18,6 +18,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/metrics/histogram_macros.h" +#include "base/metrics/sparse_histogram.h" #include "base/strings/string16.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" @@ -432,6 +433,8 @@ DCHECK(SUCCEEDED(hr)); if (!collection_) { + UMA_HISTOGRAM_SPARSE_SLOWLY( + "DirectWrite.Fonts.Proxy.GetSystemFontCollectionResult", hr); LogMessageFilterError(ERROR_NO_COLLECTION); return; } @@ -462,6 +465,8 @@ HRESULT hr; hr = font->CreateFontFace(&font_face); if (FAILED(hr)) { + UMA_HISTOGRAM_SPARSE_SLOWLY("DirectWrite.Fonts.Proxy.CreateFontFaceResult", + hr); LogMessageFilterError(ADD_FILES_FOR_FONT_CREATE_FACE_FAILED); return false; }
diff --git a/content/browser/renderer_host/input/mouse_wheel_event_queue.cc b/content/browser/renderer_host/input/mouse_wheel_event_queue.cc index d1d3bc22..ed307bc 100644 --- a/content/browser/renderer_host/input/mouse_wheel_event_queue.cc +++ b/content/browser/renderer_host/input/mouse_wheel_event_queue.cc
@@ -45,7 +45,7 @@ MouseWheelEventQueue::~MouseWheelEventQueue() { if (!wheel_queue_.empty()) - STLDeleteElements(&wheel_queue_); + base::STLDeleteElements(&wheel_queue_); } void MouseWheelEventQueue::QueueEvent(
diff --git a/content/browser/renderer_host/input/touch_event_queue.cc b/content/browser/renderer_host/input/touch_event_queue.cc index 7fb04c5..817815ac 100644 --- a/content/browser/renderer_host/input/touch_event_queue.cc +++ b/content/browser/renderer_host/input/touch_event_queue.cc
@@ -452,7 +452,7 @@ TouchEventQueue::~TouchEventQueue() { if (!touch_queue_.empty()) - STLDeleteElements(&touch_queue_); + base::STLDeleteElements(&touch_queue_); } void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) {
diff --git a/content/browser/renderer_host/input/web_input_event_builders_mac.mm b/content/browser/renderer_host/input/web_input_event_builders_mac.mm index b0bfa20..91b761d 100644 --- a/content/browser/renderer_host/input/web_input_event_builders_mac.mm +++ b/content/browser/renderer_host/input/web_input_event_builders_mac.mm
@@ -40,6 +40,7 @@ #include "content/browser/renderer_host/input/web_input_event_util.h" #include "third_party/WebKit/public/web/WebInputEvent.h" #include "ui/base/cocoa/cocoa_base_utils.h" +#import "ui/events/cocoa/cocoa_event_utils.h" #include "ui/events/keycodes/keyboard_code_conversion.h" #include "ui/events/keycodes/keyboard_code_conversion_mac.h" @@ -542,20 +543,17 @@ // the point delta data instead, since we cannot distinguish trackpad data // from data from any other continuous device. - // Conversion between wheel delta amounts and number of pixels to scroll. - static const double kScrollbarPixelsPerCocoaTick = 40.0; - if (CGEventGetIntegerValueField(cg_event, kCGScrollWheelEventIsContinuous)) { result.deltaX = CGEventGetIntegerValueField( cg_event, kCGScrollWheelEventPointDeltaAxis2); result.deltaY = CGEventGetIntegerValueField( cg_event, kCGScrollWheelEventPointDeltaAxis1); - result.wheelTicksX = result.deltaX / kScrollbarPixelsPerCocoaTick; - result.wheelTicksY = result.deltaY / kScrollbarPixelsPerCocoaTick; + result.wheelTicksX = result.deltaX / ui::kScrollbarPixelsPerCocoaTick; + result.wheelTicksY = result.deltaY / ui::kScrollbarPixelsPerCocoaTick; result.hasPreciseScrollingDeltas = true; } else { - result.deltaX = [event deltaX] * kScrollbarPixelsPerCocoaTick; - result.deltaY = [event deltaY] * kScrollbarPixelsPerCocoaTick; + result.deltaX = [event deltaX] * ui::kScrollbarPixelsPerCocoaTick; + result.deltaY = [event deltaY] * ui::kScrollbarPixelsPerCocoaTick; result.wheelTicksY = CGEventGetIntegerValueField(cg_event, kCGScrollWheelEventDeltaAxis1); result.wheelTicksX =
diff --git a/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm b/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm index 9b6500a..45e9212 100644 --- a/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm +++ b/content/browser/renderer_host/input/web_input_event_builders_mac_unittest.mm
@@ -10,9 +10,12 @@ #include "base/macros.h" #include "testing/gtest/include/gtest/gtest.h" +#import "ui/events/cocoa/cocoa_event_utils.h" +#include "ui/events/event.h" #include "ui/events/keycodes/dom/dom_code.h" #include "ui/events/keycodes/dom/dom_key.h" #include "ui/events/keycodes/keyboard_codes.h" +#import "ui/events/test/cocoa_test_event_utils.h" using blink::WebKeyboardEvent; using blink::WebInputEvent; @@ -559,3 +562,41 @@ EXPECT_EQ(entry.dom_key, web_event.domKey) << entry.mac_key_code; } } + +// Test that a ui::Event and blink::WebInputEvent made from the same NSEvent +// have the same values for comparable fields. +TEST(WebInputEventBuilderMacTest, ScrollWheelMatchesUIEvent) { + CGFloat delta_x = 123; + CGFloat delta_y = 321; + NSPoint location = NSMakePoint(11, 22); + + // WebMouseWheelEventBuilder requires a non-nil view to map coordinates. So + // create a dummy window, but don't show it. It will be released when closed. + NSWindow* window = + [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 100, 100) + styleMask:NSBorderlessWindowMask + backing:NSBackingStoreBuffered + defer:NO]; + + NSEvent* mac_event = cocoa_test_event_utils::TestScrollEvent( + location, window, delta_x, delta_y); + + blink::WebMouseWheelEvent web_event = + content::WebMouseWheelEventBuilder::Build(mac_event, + [window contentView]); + ui::MouseWheelEvent ui_event(mac_event); + + EXPECT_EQ(delta_x * ui::kScrollbarPixelsPerCocoaTick, web_event.deltaX); + EXPECT_EQ(web_event.deltaX, ui_event.x_offset()); + + EXPECT_EQ(delta_y * ui::kScrollbarPixelsPerCocoaTick, web_event.deltaY); + EXPECT_EQ(web_event.deltaY, ui_event.y_offset()); + + EXPECT_EQ(11, web_event.x); + EXPECT_EQ(web_event.x, ui_event.x()); + + // Both ui:: and blink:: events use an origin at the top-left. + EXPECT_EQ(100 - 22, web_event.y); + EXPECT_EQ(web_event.y, ui_event.y()); + [window close]; +}
diff --git a/content/browser/renderer_host/media/video_capture_buffer_pool.cc b/content/browser/renderer_host/media/video_capture_buffer_pool.cc index 8b6d875b..d484ae7c 100644 --- a/content/browser/renderer_host/media/video_capture_buffer_pool.cc +++ b/content/browser/renderer_host/media/video_capture_buffer_pool.cc
@@ -250,7 +250,7 @@ } VideoCaptureBufferPool::~VideoCaptureBufferPool() { - STLDeleteValues(&trackers_); + base::STLDeleteValues(&trackers_); } bool VideoCaptureBufferPool::ShareToProcess(
diff --git a/content/browser/renderer_host/media/video_capture_controller.cc b/content/browser/renderer_host/media/video_capture_controller.cc index 1094773..35dad20 100644 --- a/content/browser/renderer_host/media/video_capture_controller.cc +++ b/content/browser/renderer_host/media/video_capture_controller.cc
@@ -350,8 +350,8 @@ } VideoCaptureController::~VideoCaptureController() { - STLDeleteContainerPointers(controller_clients_.begin(), - controller_clients_.end()); + base::STLDeleteContainerPointers(controller_clients_.begin(), + controller_clients_.end()); } void VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread(
diff --git a/content/browser/renderer_host/media/video_capture_host_unittest.cc b/content/browser/renderer_host/media/video_capture_host_unittest.cc index d6305b8..274a598 100644 --- a/content/browser/renderer_host/media/video_capture_host_unittest.cc +++ b/content/browser/renderer_host/media/video_capture_host_unittest.cc
@@ -176,8 +176,8 @@ private: ~MockVideoCaptureHost() override { - STLDeleteContainerPairSecondPointers(filled_dib_.begin(), - filled_dib_.end()); + base::STLDeleteContainerPairSecondPointers(filled_dib_.begin(), + filled_dib_.end()); } // This method is used to dispatch IPC messages to the renderer. We intercept
diff --git a/content/browser/renderer_host/p2p/socket_dispatcher_host.cc b/content/browser/renderer_host/p2p/socket_dispatcher_host.cc index 722caa0..7088d3da 100644 --- a/content/browser/renderer_host/p2p/socket_dispatcher_host.cc +++ b/content/browser/renderer_host/p2p/socket_dispatcher_host.cc
@@ -122,10 +122,10 @@ void P2PSocketDispatcherHost::OnChannelClosing() { // Since the IPC sender is gone, close pending connections. - STLDeleteContainerPairSecondPointers(sockets_.begin(), sockets_.end()); + base::STLDeleteContainerPairSecondPointers(sockets_.begin(), sockets_.end()); sockets_.clear(); - STLDeleteContainerPointers(dns_requests_.begin(), dns_requests_.end()); + base::STLDeleteContainerPointers(dns_requests_.begin(), dns_requests_.end()); dns_requests_.clear(); if (monitoring_networks_) {
diff --git a/content/browser/renderer_host/p2p/socket_host_tcp_server.cc b/content/browser/renderer_host/p2p/socket_host_tcp_server.cc index a4af785b..f3c7bc2b 100644 --- a/content/browser/renderer_host/p2p/socket_host_tcp_server.cc +++ b/content/browser/renderer_host/p2p/socket_host_tcp_server.cc
@@ -30,8 +30,8 @@ } P2PSocketHostTcpServer::~P2PSocketHostTcpServer() { - STLDeleteContainerPairSecondPointers(accepted_sockets_.begin(), - accepted_sockets_.end()); + base::STLDeleteContainerPairSecondPointers(accepted_sockets_.begin(), + accepted_sockets_.end()); if (state_ == STATE_OPEN) { DCHECK(socket_.get());
diff --git a/content/browser/renderer_host/p2p/socket_host_udp.cc b/content/browser/renderer_host/p2p/socket_host_udp.cc index 75ea82a..2eb3579 100644 --- a/content/browser/renderer_host/p2p/socket_host_udp.cc +++ b/content/browser/renderer_host/p2p/socket_host_udp.cc
@@ -236,7 +236,7 @@ if (result > 0) { std::vector<char> data(recv_buffer_->data(), recv_buffer_->data() + result); - if (!ContainsKey(connected_peers_, recv_address_)) { + if (!base::ContainsKey(connected_peers_, recv_address_)) { P2PSocketHost::StunMessageType type; bool stun = GetStunPacketType(&*data.begin(), data.size(), &type); if ((stun && IsRequestOrResponse(type))) { @@ -270,7 +270,7 @@ return; } - if (!ContainsKey(connected_peers_, to)) { + if (!base::ContainsKey(connected_peers_, to)) { P2PSocketHost::StunMessageType type = P2PSocketHost::StunMessageType(); bool stun = GetStunPacketType(&*data.begin(), data.size(), &type); if (!stun || type == STUN_DATA_INDICATION) {
diff --git a/content/browser/renderer_host/render_message_filter.cc b/content/browser/renderer_host/render_message_filter.cc index f6b4919..864a1a6 100644 --- a/content/browser/renderer_host/render_message_filter.cc +++ b/content/browser/renderer_host/render_message_filter.cc
@@ -180,6 +180,9 @@ IPC_MESSAGE_HANDLER_GENERIC( ViewHostMsg_UpdateRect, ResizeHelperPostMsgToUIThread(render_process_id_, message)) + IPC_MESSAGE_HANDLER_GENERIC( + ViewHostMsg_SetNeedsBeginFrames, + ResizeHelperPostMsgToUIThread(render_process_id_, message)) #endif // NB: The SyncAllocateSharedMemory, SyncAllocateGpuMemoryBuffer, and // DeletedGpuMemoryBuffer IPCs are handled here for renderer processes. For
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 0ce8b224..423b74e 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -77,6 +77,7 @@ #include "content/browser/indexed_db/indexed_db_dispatcher_host.h" #include "content/browser/loader/resource_message_filter.h" #include "content/browser/loader/resource_scheduler_filter.h" +#include "content/browser/loader/url_loader_factory_impl.h" #include "content/browser/media/capture/audio_mirroring_manager.h" #include "content/browser/media/capture/image_capture_impl.h" #include "content/browser/media/media_internals.h" @@ -110,7 +111,6 @@ #include "content/browser/renderer_host/render_widget_helper.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/renderer_host/text_input_client_message_filter.h" -#include "content/browser/renderer_host/websocket_dispatcher_host.h" #include "content/browser/resolve_proxy_msg_helper.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/service_worker/service_worker_dispatcher_host.h" @@ -120,6 +120,7 @@ #include "content/browser/storage_partition_impl.h" #include "content/browser/streams/stream_context.h" #include "content/browser/tracing/trace_message_filter.h" +#include "content/browser/websockets/websocket_manager.h" #include "content/browser/webui/web_ui_controller_factory_registry.h" #include "content/common/child_process_host_impl.h" #include "content/common/child_process_messages.h" @@ -726,6 +727,7 @@ } RenderProcessHostImpl::~RenderProcessHostImpl() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); #ifndef NDEBUG DCHECK(is_self_deleted_) << "RenderProcessHostImpl is destroyed by something other than itself"; @@ -969,16 +971,16 @@ scoped_refptr<ChromeBlobStorageContext> blob_storage_context = ChromeBlobStorageContext::GetFor(browser_context); - ResourceMessageFilter* resource_message_filter = new ResourceMessageFilter( + resource_message_filter_ = new ResourceMessageFilter( GetID(), PROCESS_TYPE_RENDERER, - storage_partition_impl_->GetAppCacheService(), - blob_storage_context.get(), + storage_partition_impl_->GetAppCacheService(), blob_storage_context.get(), storage_partition_impl_->GetFileSystemContext(), storage_partition_impl_->GetServiceWorkerContext(), storage_partition_impl_->GetHostZoomLevelContext(), get_contexts_callback); - AddFilter(resource_message_filter); + AddFilter(resource_message_filter_.get()); + MediaStreamManager* media_stream_manager = BrowserMainLoop::GetInstance()->media_stream_manager(); // The AudioInputRendererHost and AudioRendererHost needs to be available for @@ -1046,15 +1048,6 @@ AddFilter(new BrowserCdmManager(GetID(), NULL)); #endif - WebSocketDispatcherHost::GetRequestContextCallback - websocket_request_context_callback( - base::Bind(&GetRequestContext, request_context, media_request_context, - RESOURCE_TYPE_SUB_RESOURCE)); - - AddFilter(new WebSocketDispatcherHost( - GetID(), websocket_request_context_callback, blob_storage_context.get(), - storage_partition_impl_)); - message_port_message_filter_ = new MessagePortMessageFilter( base::Bind(&RenderWidgetHelper::GetNextRoutingID, base::Unretained(widget_helper_.get()))); @@ -1180,6 +1173,14 @@ registry->AddInterface(base::Bind(&DeviceMotionHost::Create)); registry->AddInterface(base::Bind(&DeviceOrientationHost::Create)); registry->AddInterface(base::Bind(&DeviceOrientationAbsoluteHost::Create)); + registry->AddInterface( + base::Bind(&URLLoaderFactoryImpl::Create, resource_message_filter_)); + + // This is to support usage of WebSockets in cases in which there is no + // associated RenderFrame (e.g., Shared Workers). + registry->AddInterface( + base::Bind(&WebSocketManager::CreateWebSocket, GetID(), MSG_ROUTING_NONE), + ui_task_runner); GetContentClient()->browser()->ExposeInterfacesToRenderer(registry.get(), this); @@ -1495,6 +1496,7 @@ switches::kDisableV8IdleTasks, switches::kDisableWebGLImageChromium, switches::kDomAutomationController, + switches::kEnableAsmWasm, switches::kEnableBlinkFeatures, switches::kEnableBrowserSideNavigation, switches::kEnableDisplayList2dCanvas, @@ -1531,6 +1533,7 @@ switches::kEnableViewport, switches::kEnableVp9InMp4, switches::kEnableVtune, + switches::kEnableWasm, switches::kEnableWebBluetooth, switches::kEnableWebFontsInterventionTrigger, switches::kEnableWebFontsInterventionV2, @@ -1924,6 +1927,7 @@ } void RenderProcessHostImpl::Cleanup() { + DCHECK_CURRENTLY_ON(BrowserThread::UI); // Keep the one renderer thread around forever in single process mode. if (run_renderer_in_process()) return;
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index a4a331a..340f39e9 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -70,6 +70,7 @@ class RenderWidgetHost; class RenderWidgetHostImpl; class RenderWidgetHostViewFrameSubscriber; +class ResourceMessageFilter; class StoragePartition; class StoragePartitionImpl; @@ -529,6 +530,8 @@ base::WaitableEvent never_signaled_; #endif + scoped_refptr<ResourceMessageFilter> resource_message_filter_; + base::WeakPtrFactory<RenderProcessHostImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(RenderProcessHostImpl);
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index a3a1a6a..c6817b4 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -537,8 +537,8 @@ prefs.main_frame_resizes_are_orientation_changes = command_line.HasSwitch(switches::kMainFrameResizesAreOrientationChanges); - prefs.image_color_profiles_enabled = - command_line.HasSwitch(switches::kEnableImageColorProfiles); + prefs.color_correct_rendering_enabled = + command_line.HasSwitch(switches::kEnableColorCorrectRendering); prefs.spatial_navigation_enabled = command_line.HasSwitch( switches::kEnableSpatialNavigation);
diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h index 017673e6..e550b57 100644 --- a/content/browser/renderer_host/render_view_host_impl.h +++ b/content/browser/renderer_host/render_view_host_impl.h
@@ -241,6 +241,10 @@ // Creates a full screen RenderWidget. void CreateNewFullscreenWidget(int32_t route_id); + // Send RenderViewReady to observers once the process is launched, but not + // re-entrantly. + void PostRenderViewReady(); + // TODO(creis): Remove after debugging https:/crbug.com/575245. int main_frame_routing_id() const { return main_frame_routing_id_; @@ -321,9 +325,6 @@ FRIEND_TEST_ALL_PREFIXES(SitePerProcessBrowserTest, NavigateMainFrameToChildSite); - // Send RenderViewReady to observers once the process is launched, but not - // re-entrantly. - void PostRenderViewReady(); void RenderViewReady(); // TODO(creis): Move to a private namespace on RenderFrameHostImpl.
diff --git a/content/browser/renderer_host/render_widget_host_delegate.cc b/content/browser/renderer_host/render_widget_host_delegate.cc index 0395aee..a3eca1b8 100644 --- a/content/browser/renderer_host/render_widget_host_delegate.cc +++ b/content/browser/renderer_host/render_widget_host_delegate.cc
@@ -8,6 +8,8 @@ namespace content { +void RenderWidgetHostDelegate::GetScreenInfo(blink::WebScreenInfo*) {} + bool RenderWidgetHostDelegate::PreHandleKeyboardEvent( const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) {
diff --git a/content/browser/renderer_host/render_widget_host_delegate.h b/content/browser/renderer_host/render_widget_host_delegate.h index 1aab2bb6..0ac9aa60 100644 --- a/content/browser/renderer_host/render_widget_host_delegate.h +++ b/content/browser/renderer_host/render_widget_host_delegate.h
@@ -18,6 +18,7 @@ namespace blink { class WebMouseWheelEvent; class WebGestureEvent; +struct WebScreenInfo; } namespace gfx { @@ -61,6 +62,12 @@ // The screen info has changed. virtual void ScreenInfoChanged() {} + // Sets the device scale factor for frames associated with this WebContents. + virtual void UpdateDeviceScaleFactor(double device_scale_factor) {} + + // Retrieve screen information. + virtual void GetScreenInfo(blink::WebScreenInfo* web_screen_info); + // Callback to give the browser a chance to handle the specified keyboard // event before sending it to the renderer. // Returns true if the |event| was handled. Otherwise, if the |event| would
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 7054fdd7..3c8beb95 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -591,6 +591,9 @@ if (view_) { resize_params->new_size = view_->GetRequestedRendererSize(); + // TODO(wjmaclean): Can we just get rid of physical_backing_size and just + // deal with it on the renderer side? It seems to always be + // ScaleToCeiledSize(new_size, device_scale_factor) ?? resize_params->physical_backing_size = view_->GetPhysicalBackingSize(); resize_params->top_controls_height = view_->GetTopControlsHeight(); resize_params->top_controls_shrink_blink_size = @@ -1224,10 +1227,11 @@ void RenderWidgetHostImpl::GetWebScreenInfo(blink::WebScreenInfo* result) { TRACE_EVENT0("renderer_host", "RenderWidgetHostImpl::GetWebScreenInfo"); - if (view_) - view_->GetScreenInfo(result); + if (delegate_) + delegate_->GetScreenInfo(result); else - RenderWidgetHostViewBase::GetDefaultScreenInfo(result); + NOTREACHED(); + // TODO(sievers): find a way to make this done another way so the method // can be const. latency_tracker_.set_device_scale_factor(result->deviceScaleFactor); @@ -1269,7 +1273,10 @@ } #endif pending_browser_snapshots_.insert(std::make_pair(id, callback)); - Send(new ViewMsg_ForceRedraw(GetRoutingID(), id)); + ui::LatencyInfo latency_info; + latency_info.AddLatencyNumber(ui::WINDOW_SNAPSHOT_FRAME_NUMBER_COMPONENT, 0, + id); + Send(new ViewMsg_ForceRedraw(GetRoutingID(), latency_info)); } const NativeWebKeyboardEvent*
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc index 367cfd7..6405622 100644 --- a/content/browser/renderer_host/render_widget_host_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -277,9 +277,6 @@ void ClearMockPhysicalBackingSize() { use_fake_physical_backing_size_ = false; } - void SetScreenInfo(const blink::WebScreenInfo& screen_info) { - screen_info_ = screen_info; - } // RenderWidgetHostView override. gfx::Rect GetViewBounds() const override { return bounds_; } @@ -305,9 +302,6 @@ return mock_physical_backing_size_; return TestRenderWidgetHostView::GetPhysicalBackingSize(); } - void GetScreenInfo(blink::WebScreenInfo* screen_info) override { - *screen_info = screen_info_; - } #if defined(USE_AURA) ~TestView() override { // Simulate the mouse exit event dispatched when an aura window is @@ -332,7 +326,6 @@ bool use_fake_physical_backing_size_; gfx::Size mock_physical_backing_size_; InputEventAckState ack_result_; - blink::WebScreenInfo screen_info_; private: DISALLOW_COPY_AND_ASSIGN(TestView); @@ -388,6 +381,15 @@ bool unresponsive_timer_fired() const { return unresponsive_timer_fired_; } + void SetScreenInfo(const blink::WebScreenInfo& screen_info) { + screen_info_ = screen_info; + } + + // RenderWidgetHostDelegate overrides. + void GetScreenInfo(blink::WebScreenInfo* web_screen_info) override { + *web_screen_info = screen_info_; + } + protected: bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) override { @@ -430,6 +432,8 @@ bool handle_wheel_event_called_; bool unresponsive_timer_fired_; + + blink::WebScreenInfo screen_info_; }; // RenderWidgetHostTest -------------------------------------------------------- @@ -792,7 +796,10 @@ screen_info.orientationAngle = 0; screen_info.orientationType = blink::WebScreenOrientationPortraitPrimary; - view_->SetScreenInfo(screen_info); + auto host_delegate = + static_cast<MockRenderWidgetHostDelegate*>(host_->delegate()); + + host_delegate->SetScreenInfo(screen_info); host_->WasResized(); EXPECT_FALSE(host_->resize_ack_pending_); EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID)); @@ -801,7 +808,7 @@ screen_info.orientationAngle = 180; screen_info.orientationType = blink::WebScreenOrientationLandscapePrimary; - view_->SetScreenInfo(screen_info); + host_delegate->SetScreenInfo(screen_info); host_->WasResized(); EXPECT_FALSE(host_->resize_ack_pending_); EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID)); @@ -809,14 +816,14 @@ screen_info.deviceScaleFactor = 2.f; - view_->SetScreenInfo(screen_info); + host_delegate->SetScreenInfo(screen_info); host_->WasResized(); EXPECT_FALSE(host_->resize_ack_pending_); EXPECT_TRUE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID)); process_->sink().ClearMessages(); // No screen change. - view_->SetScreenInfo(screen_info); + host_delegate->SetScreenInfo(screen_info); host_->WasResized(); EXPECT_FALSE(host_->resize_ack_pending_); EXPECT_FALSE(process_->sink().GetUniqueMessageMatching(ViewMsg_Resize::ID));
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 f29806a..0f9ae4ad 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -894,15 +894,19 @@ content_view_core_->GetWindowAndroid()->GetCompositor(); DCHECK(compositor); DCHECK(!surface_id_.is_null()); + scoped_refptr<cc::Layer> layer = + CreateSurfaceLayer(surface_id_, texture_size_in_layer_); + layer->SetHideLayerAndSubtree(true); + compositor->AttachLayerForReadback(layer); + std::unique_ptr<cc::CopyOutputRequest> request = - cc::CopyOutputRequest::CreateRequest(base::Bind( - &PrepareTextureCopyOutputResult, weak_ptr_factory_.GetWeakPtr(), - dst_size_in_pixel, preferred_color_type, start_time, callback)); + cc::CopyOutputRequest::CreateRequest( + base::Bind(&PrepareTextureCopyOutputResult, + weak_ptr_factory_.GetWeakPtr(), layer, dst_size_in_pixel, + preferred_color_type, start_time, callback)); + if (!src_subrect_in_pixel.IsEmpty()) request->set_area(src_subrect_in_pixel); - // Make sure the current frame doesn't get deleted until we fulfill the - // request. - LockCompositingSurface(); surface_factory_->RequestCopyOfSurface(surface_id_, std::move(request)); } @@ -1458,11 +1462,6 @@ return false; } -void RenderWidgetHostViewAndroid::GetScreenInfo(blink::WebScreenInfo* result) { - // ScreenInfo isn't tied to the widget on Android. Always return the default. - RenderWidgetHostViewBase::GetDefaultScreenInfo(result); -} - // TODO(jrg): Find out the implications and answer correctly here, // as we are returning the WebView and not root window bounds. gfx::Rect RenderWidgetHostViewAndroid::GetBoundsInRootWindow() { @@ -1875,6 +1874,7 @@ // static void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult( base::WeakPtr<RenderWidgetHostViewAndroid> rwhva, + scoped_refptr<cc::Layer> readback_layer, const gfx::Size& dst_size_in_pixel, SkColorType color_type, const base::TimeTicks& start_time, @@ -1884,8 +1884,7 @@ base::Bind(callback, SkBitmap(), READBACK_FAILED)); TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult"); - if (rwhva) - rwhva->UnlockCompositingSurface(); + readback_layer->RemoveFromParent(); if (!result->HasTexture() || result->IsEmpty() || result->size().IsEmpty()) return; cc::TextureMailbox texture_mailbox; @@ -1958,24 +1957,6 @@ SendGestureEvent(long_press); } -// static -void RenderWidgetHostViewBase::GetDefaultScreenInfo( - blink::WebScreenInfo* results) { - const display::Display& display = - display::Screen::GetScreen()->GetPrimaryDisplay(); - results->rect = display.bounds(); - // TODO(husky): Remove any system controls from availableRect. - results->availableRect = display.work_area(); - results->deviceScaleFactor = display.device_scale_factor(); - results->orientationAngle = display.RotationAsDegree(); - results->orientationType = - RenderWidgetHostViewBase::GetOrientationTypeForMobile(display); - gfx::DeviceDisplayInfo info; - results->depth = display.color_depth(); - results->depthPerComponent = display.depth_per_component(); - results->isMonochrome = (results->depthPerComponent == 0); -} - void RenderWidgetHostViewAndroid::ComputeEventLatencyOSTouchHistograms( const ui::MotionEvent& event) { base::TimeTicks event_time = event.GetEventTime();
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h index 066c0b7..24712d84 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.h +++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -136,7 +136,6 @@ const scoped_refptr<media::VideoFrame>& target, const base::Callback<void(const gfx::Rect&, bool)>& callback) override; bool CanCopyToVideoFrame() const override; - void GetScreenInfo(blink::WebScreenInfo* results) override; gfx::Rect GetBoundsInRootWindow() override; void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch, InputEventAckState ack_result) override; @@ -271,6 +270,7 @@ // of the copy. static void PrepareTextureCopyOutputResult( base::WeakPtr<RenderWidgetHostViewAndroid> rwhva, + scoped_refptr<cc::Layer> readback_layer, const gfx::Size& dst_size_in_pixel, SkColorType color_type, const base::TimeTicks& start_time,
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index 35364cb2..b5efbca8 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -54,9 +54,9 @@ #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view_frame_subscriber.h" #include "content/public/browser/user_metrics.h" +#include "content/public/common/child_process_host.h" #include "content/public/common/content_switches.h" #include "gpu/ipc/common/gpu_messages.h" -#include "third_party/WebKit/public/platform/WebScreenInfo.h" #include "third_party/WebKit/public/web/WebCompositionUnderline.h" #include "third_party/WebKit/public/web/WebInputEvent.h" #include "ui/aura/client/aura_constants.h" @@ -115,7 +115,6 @@ using gfx::RectToSkIRect; using gfx::SkIRectToRect; -using blink::WebScreenInfo; using blink::WebInputEvent; using blink::WebGestureEvent; using blink::WebTouchEvent; @@ -169,32 +168,6 @@ return false; } -void GetScreenInfoForWindow(WebScreenInfo* results, aura::Window* window) { - display::Screen* screen = display::Screen::GetScreen(); - const display::Display display = window - ? screen->GetDisplayNearestWindow(window) - : screen->GetPrimaryDisplay(); - results->rect = display.bounds(); - results->availableRect = display.work_area(); - // TODO(derat|oshima): Don't hardcode this. Get this from display object. - results->depth = 24; - results->depthPerComponent = 8; - results->deviceScaleFactor = display.device_scale_factor(); - - // The Display rotation and the WebScreenInfo orientation are not the same - // angle. The former is the physical display rotation while the later is the - // rotation required by the content to be shown properly on the screen, in - // other words, relative to the physical display. - results->orientationAngle = display.RotationAsDegree(); - if (results->orientationAngle == 90) - results->orientationAngle = 270; - else if (results->orientationAngle == 270) - results->orientationAngle = 90; - - results->orientationType = - RenderWidgetHostViewBase::GetOrientationTypeForDesktop(display); -} - bool IsFractionalScaleFactor(float scale_factor) { return (scale_factor - static_cast<int>(scale_factor)) > 0; } @@ -468,6 +441,8 @@ set_focus_on_mouse_down_or_key_event_(false), device_scale_factor_(0.0f), disable_input_event_router_for_testing_(false), + last_active_widget_process_id_(ChildProcessHost::kInvalidUniqueID), + last_active_widget_routing_id_(MSG_ROUTING_NONE), weak_ptr_factory_(this) { if (!is_guest_view_hack_) host_->SetView(this); @@ -1116,10 +1091,6 @@ return false; } -void RenderWidgetHostViewAura::GetScreenInfo(WebScreenInfo* results) { - GetScreenInfoForWindow(results, window_->GetRootWindow() ? window_ : NULL); -} - gfx::Rect RenderWidgetHostViewAura::GetBoundsInRootWindow() { aura::Window* top_level = window_->GetToplevelWindow(); gfx::Rect bounds(top_level->GetBoundsInScreen()); @@ -1519,11 +1490,12 @@ if (!text_input_manager_ || !text_input_manager_->GetActiveWidget()) return false; - const std::vector<gfx::Rect>* composition_character_bounds = - text_input_manager_->GetCompositionCharacterBounds(); - if (index >= composition_character_bounds->size()) + const TextInputManager::CompositionRangeInfo* composition_range_info = + text_input_manager_->GetCompositionRangeInfo(); + + if (index >= composition_range_info->character_bounds.size()) return false; - *rect = ConvertRectToScreen(composition_character_bounds->at(index)); + *rect = ConvertRectToScreen(composition_range_info->character_bounds[index]); return true; } @@ -1731,11 +1703,13 @@ void RenderWidgetHostViewAura::OnDeviceScaleFactorChanged( float device_scale_factor) { - // TODO(wjmaclean): can host_ ever be null? - if (!host_ || !window_->GetRootWindow()) + if (!window_->GetRootWindow()) return; - UpdateScreenInfo(window_); + RenderWidgetHostImpl* host = + RenderWidgetHostImpl::From(GetRenderWidgetHost()); + if (host && host->delegate()) + host->delegate()->UpdateDeviceScaleFactor(device_scale_factor); device_scale_factor_ = device_scale_factor; const display::Display display = @@ -2994,24 +2968,30 @@ GetInputMethod()->OnTextInputTypeChanged(this); const TextInputState* state = text_input_manager_->GetTextInputState(); - if (state && state->show_ime_if_needed && state->type != ui::TEXT_INPUT_TYPE_NONE) { GetInputMethod()->ShowImeIfNeeded(); - // Start monitoring the composition information if the focused node is // editable. - host_->Send(new InputMsg_RequestCompositionUpdate( - host_->GetRoutingID(), - false /* immediate request */, + RenderWidgetHostImpl* last_active_widget = + text_input_manager_->GetActiveWidget(); + last_active_widget_routing_id_ = last_active_widget->GetRoutingID(); + last_active_widget_process_id_ = last_active_widget->GetProcess()->GetID(); + last_active_widget->Send(new InputMsg_RequestCompositionUpdate( + last_active_widget->GetRoutingID(), false /* immediate request */, true /* monitor request */)); } else { // Stop monitoring the composition information if the focused node is not // editable. - host_->Send(new InputMsg_RequestCompositionUpdate( - host_->GetRoutingID(), - false /* immediate request */, - false /* monitor request */)); + RenderWidgetHostImpl* last_active_widget = RenderWidgetHostImpl::FromID( + last_active_widget_process_id_, last_active_widget_routing_id_); + if (last_active_widget) { + last_active_widget->Send(new InputMsg_RequestCompositionUpdate( + last_active_widget->GetRoutingID(), false /* immediate request */, + false /* monitor request */)); + } + last_active_widget_routing_id_ = MSG_ROUTING_NONE; + last_active_widget_process_id_ = ChildProcessHost::kInvalidUniqueID; } } @@ -3079,12 +3059,4 @@ #endif // defined(USE_X11) && !defined(OS_CHROMEOS) } -//////////////////////////////////////////////////////////////////////////////// -// RenderWidgetHostViewBase, public: - -// static -void RenderWidgetHostViewBase::GetDefaultScreenInfo(WebScreenInfo* results) { - GetScreenInfoForWindow(results, NULL); -} - } // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index 813265c..6dc5682 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -161,7 +161,6 @@ std::unique_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) override; void EndFrameSubscription() override; bool HasAcceleratedSurface(const gfx::Size& desired_size) override; - void GetScreenInfo(blink::WebScreenInfo* results) override; gfx::Rect GetBoundsInRootWindow() override; void WheelEventAck(const blink::WebMouseWheelEvent& event, InputEventAckState ack_result) override; @@ -687,6 +686,11 @@ // RenderWidgetHostInputEventRouter. bool disable_input_event_router_for_testing_; + // The routing and process IDs for the last RenderWidgetHost which had a + // TextInputState of non-NONE. + int32_t last_active_widget_process_id_; + int32_t last_active_widget_routing_id_; + base::WeakPtrFactory<RenderWidgetHostViewAura> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewAura);
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc index f82453c..a398d55 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -165,7 +165,10 @@ class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate { public: MockRenderWidgetHostDelegate() - : rwh_(nullptr), is_fullscreen_(false), focused_widget_(nullptr) {} + : rwh_(nullptr), + is_fullscreen_(false), + focused_widget_(nullptr), + last_device_scale_factor_(0.0) {} ~MockRenderWidgetHostDelegate() override {} const NativeWebKeyboardEvent* last_event() const { return last_event_.get(); } void set_widget_host(RenderWidgetHostImpl* rwh) { rwh_ = rwh; } @@ -181,6 +184,11 @@ focused_widget_ = focused_widget; } + double get_last_device_scale_factor() { return last_device_scale_factor_; } + void UpdateDeviceScaleFactor(double device_scale_factor) override { + last_device_scale_factor_ = device_scale_factor; + } + protected: // RenderWidgetHostDelegate: bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, @@ -204,6 +212,7 @@ bool is_fullscreen_; TextInputManager text_input_manager_; RenderWidgetHostImpl* focused_widget_; + double last_device_scale_factor_; DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHostDelegate); }; @@ -1463,37 +1472,20 @@ aura_test_helper_->test_screen()->SetDeviceScaleFactor(2.0f); EXPECT_EQ("200x200", view_->GetPhysicalBackingSize().ToString()); // Extra ScreenInfoChanged message for |parent_view_|. - EXPECT_EQ(1u, sink_->message_count()); - { - const IPC::Message* msg = sink_->GetMessageAt(0); - EXPECT_EQ(ViewMsg_Resize::ID, msg->type()); - ViewMsg_Resize::Param params; - ViewMsg_Resize::Read(msg, ¶ms); - EXPECT_EQ(2.0f, std::get<0>(params).screen_info.deviceScaleFactor); - EXPECT_EQ("100x100", std::get<0>(params).new_size.ToString()); // dip size - EXPECT_EQ( - "200x200", - std::get<0>(params).physical_backing_size.ToString()); // backing size - } + EXPECT_EQ(0u, sink_->message_count()); + auto view_delegate = static_cast<MockRenderWidgetHostDelegate*>( + static_cast<RenderWidgetHostImpl*>(view_->GetRenderWidgetHost()) + ->delegate()); + EXPECT_EQ(2.0f, view_delegate->get_last_device_scale_factor()); widget_host_->ResetSizeAndRepaintPendingFlags(); sink_->ClearMessages(); aura_test_helper_->test_screen()->SetDeviceScaleFactor(1.0f); // Extra ScreenInfoChanged message for |parent_view_|. - EXPECT_EQ(1u, sink_->message_count()); + EXPECT_EQ(0u, sink_->message_count()); + EXPECT_EQ(1.0f, view_delegate->get_last_device_scale_factor()); EXPECT_EQ("100x100", view_->GetPhysicalBackingSize().ToString()); - { - const IPC::Message* msg = sink_->GetMessageAt(0); - EXPECT_EQ(ViewMsg_Resize::ID, msg->type()); - ViewMsg_Resize::Param params; - ViewMsg_Resize::Read(msg, ¶ms); - EXPECT_EQ(1.0f, std::get<0>(params).screen_info.deviceScaleFactor); - EXPECT_EQ("100x100", std::get<0>(params).new_size.ToString()); // dip size - EXPECT_EQ( - "100x100", - std::get<0>(params).physical_backing_size.ToString()); // backing size - } } // Checks that InputMsg_CursorVisibilityChange IPC messages are dispatched
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc index 3a295ca..449fcd9 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.cc +++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -455,7 +455,7 @@ const gfx::Range& range, const std::vector<gfx::Rect>& character_bounds) { // TODO(ekaramad): Use TextInputManager code paths for IME on other platforms. -#if defined(USE_AURA) +#if !defined(OS_ANDROID) if (GetTextInputManager()) { GetTextInputManager()->ImeCompositionRangeChanged(this, range, character_bounds);
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h index 620b0eed3c..5bc9178 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.h +++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -16,6 +16,7 @@ #include "base/macros.h" #include "base/observer_list.h" #include "base/process/kill.h" +#include "base/strings/string16.h" #include "base/timer/timer.h" #include "build/build_config.h" #include "cc/output/compositor_frame.h" @@ -286,11 +287,6 @@ const std::vector<gfx::Rect>& character_bounds); //---------------------------------------------------------------------------- - // The following static methods are implemented by each platform. - - static void GetDefaultScreenInfo(blink::WebScreenInfo* results); - - //---------------------------------------------------------------------------- // The following pure virtual methods are implemented by derived classes. // Perform all the initialization steps necessary for this object to represent @@ -371,8 +367,6 @@ static blink::WebScreenOrientationType GetOrientationTypeForDesktop( const display::Display& display); - virtual void GetScreenInfo(blink::WebScreenInfo* results) = 0; - // Gets the bounds of the window, in screen coordinates. virtual gfx::Rect GetBoundsInRootWindow() = 0;
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h index 1021356..6d647c715 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.h +++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -284,9 +284,6 @@ void Focus() override; void UpdateCursor(const WebCursor& cursor) override; void SetIsLoading(bool is_loading) override; - void ImeCompositionRangeChanged( - const gfx::Range& range, - const std::vector<gfx::Rect>& character_bounds) override; void RenderProcessGone(base::TerminationStatus status, int error_code) override; void Destroy() override; @@ -317,7 +314,6 @@ gfx::Point AccessibilityOriginInScreen(const gfx::Rect& bounds) override; bool HasAcceleratedSurface(const gfx::Size& desired_size) override; - void GetScreenInfo(blink::WebScreenInfo* results) override; gfx::Rect GetBoundsInRootWindow() override; void LockCompositingSurface() override; void UnlockCompositingSurface() override; @@ -357,6 +353,9 @@ bool did_update_state) override; void OnImeCancelComposition(TextInputManager* text_input_manager, RenderWidgetHostViewBase* updated_view) override; + void OnImeCompositionRangeChanged( + TextInputManager* text_input_manager, + RenderWidgetHostViewBase* updated_view) override; // IPC::Sender implementation. bool Send(IPC::Message* message) override; @@ -476,6 +475,11 @@ // TextInputManager. ui::TextInputType GetTextInputType(); + // Helper method to obtain the currently active widget from TextInputManager. + // An active widget is a RenderWidget which is currently focused and has a + // |TextInputState.type| which is not ui::TEXT_INPUT_TYPE_NONE. + RenderWidgetHostImpl* GetActiveWidget(); + private: friend class RenderWidgetHostViewMacTest;
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 9ed2ca7a..dcac2b67 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -376,28 +376,6 @@ return enclosing_window; } -blink::WebScreenInfo GetWebScreenInfo(NSView* view) { - display::Display display = - display::Screen::GetScreen()->GetDisplayNearestWindow(view); - - NSScreen* screen = [NSScreen deepestScreen]; - - blink::WebScreenInfo results; - - results.deviceScaleFactor = static_cast<int>(display.device_scale_factor()); - results.depth = NSBitsPerPixelFromDepth([screen depth]); - results.depthPerComponent = NSBitsPerSampleFromDepth([screen depth]); - results.isMonochrome = - [[screen colorSpace] colorSpaceModel] == NSGrayColorSpaceModel; - results.rect = display.bounds(); - results.availableRect = display.work_area(); - results.orientationAngle = display.RotationAsDegree(); - results.orientationType = - content::RenderWidgetHostViewBase::GetOrientationTypeForDesktop(display); - - return results; -} - } // namespace namespace content { @@ -469,15 +447,6 @@ } /////////////////////////////////////////////////////////////////////////////// -// RenderWidgetHostViewBase, public: - -// static -void RenderWidgetHostViewBase::GetDefaultScreenInfo( - blink::WebScreenInfo* results) { - *results = GetWebScreenInfo(NULL); -} - -/////////////////////////////////////////////////////////////////////////////// // RenderWidgetHostViewMac, public: RenderWidgetHostViewMac::RenderWidgetHostViewMac(RenderWidgetHost* widget, @@ -553,6 +522,11 @@ if (!is_guest_view_hack_) render_widget_host_->SetView(NULL); } + + // In case the view is deleted (by cocoa view) before calling destroy, we need + // to remove this view from the observer list of TextInputManager. + if (text_input_manager_ && text_input_manager_->HasObserver(this)) + text_input_manager_->RemoveObserver(this); } void RenderWidgetHostViewMac::SetDelegate( @@ -574,6 +548,11 @@ return GetTextInputManager()->GetTextInputState()->type; } +RenderWidgetHostImpl* RenderWidgetHostViewMac::GetActiveWidget() { + return GetTextInputManager() ? GetTextInputManager()->GetActiveWidget() + : nullptr; +} + /////////////////////////////////////////////////////////////////////////////// // RenderWidgetHostViewMac, RenderWidgetHostView implementation: @@ -920,14 +899,16 @@ [cocoa_view_ cancelComposition]; } -void RenderWidgetHostViewMac::ImeCompositionRangeChanged( - const gfx::Range& range, - const std::vector<gfx::Rect>& character_bounds) { +void RenderWidgetHostViewMac::OnImeCompositionRangeChanged( + TextInputManager* text_input_manager, + RenderWidgetHostViewBase* updated_view) { + const TextInputManager::CompositionRangeInfo* info = + GetTextInputManager()->GetCompositionRangeInfo(); // The RangeChanged message is only sent with valid values. The current // caret position (start == end) will be sent if there is no IME range. - [cocoa_view_ setMarkedRange:range.ToNSRange()]; - composition_range_ = range; - composition_bounds_ = character_bounds; + [cocoa_view_ setMarkedRange:info->range.ToNSRange()]; + composition_range_ = info->range; + composition_bounds_ = info->character_bounds; } void RenderWidgetHostViewMac::RenderProcessGone(base::TerminationStatus status, @@ -1334,10 +1315,6 @@ browser_compositor_->GetDelegatedFrameHost()->ClearDelegatedFrame(); } -void RenderWidgetHostViewMac::GetScreenInfo(blink::WebScreenInfo* results) { - *results = GetWebScreenInfo(GetNativeView()); -} - gfx::Rect RenderWidgetHostViewMac::GetBoundsInRootWindow() { // TODO(shess): In case of !window, the view has been removed from // the view hierarchy because the tab isn't main. Could retrieve @@ -1609,11 +1586,18 @@ void RenderWidgetHostViewMac::OnDisplayMetricsChanged( const display::Display& display, - uint32_t metrics) { + uint32_t changed_metrics) { display::Screen* screen = display::Screen::GetScreen(); if (display.id() != screen->GetDisplayNearestWindow(cocoa_view_).id()) return; + if (changed_metrics & DisplayObserver::DISPLAY_METRIC_DEVICE_SCALE_FACTOR) { + RenderWidgetHostImpl* host = + RenderWidgetHostImpl::From(GetRenderWidgetHost()); + if (host && host->delegate()) + host->delegate()->UpdateDeviceScaleFactor(display.device_scale_factor()); + } + UpdateScreenInfo(cocoa_view_); } @@ -2946,8 +2930,10 @@ // If we are handling a key down event, then ConfirmComposition() will be // called in keyEvent: method. if (!handlingKeyDown_) { - renderWidgetHostView_->render_widget_host_->ImeConfirmComposition( - base::string16(), gfx::Range::InvalidRange(), false); + if (renderWidgetHostView_->GetActiveWidget()) { + renderWidgetHostView_->GetActiveWidget()->ImeConfirmComposition( + base::string16(), gfx::Range::InvalidRange(), false); + } } else { unmarkTextCalled_ = YES; } @@ -2982,15 +2968,17 @@ // called in keyEvent: method. // Input methods of Mac use setMarkedText calls with an empty text to cancel // an ongoing composition. So, we should check whether or not the given text - // is empty to update the input method state. (Our input method backend can + // is empty to update the input method state. (Our input method backend // automatically cancels an ongoing composition when we send an empty text. // So, it is OK to send an empty text to the renderer.) if (handlingKeyDown_) { setMarkedTextReplacementRange_ = gfx::Range(replacementRange); } else { - renderWidgetHostView_->render_widget_host_->ImeSetComposition( - markedText_, underlines_, gfx::Range(replacementRange), - newSelRange.location, NSMaxRange(newSelRange)); + if (renderWidgetHostView_->GetActiveWidget()) { + renderWidgetHostView_->GetActiveWidget()->ImeSetComposition( + markedText_, underlines_, gfx::Range(replacementRange), + newSelRange.location, NSMaxRange(newSelRange)); + } } } @@ -3025,7 +3013,7 @@ - (void)insertText:(id)string replacementRange:(NSRange)replacementRange { // An input method has characters to be inserted. // Same as Linux, Mac calls this method not only: - // * when an input method finishs composing text, but also; + // * when an input method finishes composing text, but also; // * when we type an ASCII character (without using input methods). // When we aren't using input methods, we should send the given character as // a Char event so it is dispatched to an onkeypress() event handler of @@ -3044,8 +3032,10 @@ textToBeInserted_.append(base::SysNSStringToUTF16(im_text)); } else { gfx::Range replacement_range(replacementRange); - renderWidgetHostView_->render_widget_host_->ImeConfirmComposition( - base::SysNSStringToUTF16(im_text), replacement_range, false); + if (renderWidgetHostView_->GetActiveWidget()) { + renderWidgetHostView_->GetActiveWidget()->ImeConfirmComposition( + base::SysNSStringToUTF16(im_text), replacement_range, false); + } } // Inserting text will delete all marked text automatically. @@ -3176,9 +3166,10 @@ if (!hasMarkedText_) return; - if (renderWidgetHostView_->render_widget_host_) - renderWidgetHostView_->render_widget_host_->ImeConfirmComposition( + if (renderWidgetHostView_->GetActiveWidget()) { + renderWidgetHostView_->GetActiveWidget()->ImeConfirmComposition( base::string16(), gfx::Range::InvalidRange(), false); + } [self cancelComposition]; }
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm index 06960dc..b4eecea3 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
@@ -22,8 +22,10 @@ #include "content/browser/frame_host/render_widget_host_view_guest.h" #include "content/browser/gpu/compositor_util.h" #include "content/browser/renderer_host/render_widget_host_delegate.h" +#include "content/browser/renderer_host/text_input_manager.h" #include "content/common/input/web_input_event_traits.h" #include "content/common/input_messages.h" +#include "content/common/text_input_state.h" #include "content/common/view_messages.h" #include "content/public/browser/notification_types.h" #include "content/public/browser/render_widget_host_view_mac_delegate.h" @@ -277,6 +279,13 @@ rwhv_mac_->Destroy(); } + void ActivateViewWithTextInputManager(RenderWidgetHostViewBase* view, + ui::TextInputType type) { + TextInputState state; + state.type = type; + view->TextInputStateChanged(state); + } + private: // This class isn't derived from PlatformTest. base::mac::ScopedNSAutoreleasePool pool_; @@ -532,6 +541,7 @@ } TEST_F(RenderWidgetHostViewMacTest, UpdateCompositionSinglelineCase) { + ActivateViewWithTextInputManager(rwhv_mac_, ui::TEXT_INPUT_TYPE_TEXT); const gfx::Point kOrigin(10, 11); const gfx::Size kBoundsUnit(10, 20); @@ -640,6 +650,7 @@ } TEST_F(RenderWidgetHostViewMacTest, UpdateCompositionMultilineCase) { + ActivateViewWithTextInputManager(rwhv_mac_, ui::TEXT_INPUT_TYPE_TEXT); const gfx::Point kOrigin(10, 11); const gfx::Size kBoundsUnit(10, 20); NSRect rect; @@ -773,6 +784,7 @@ // firstRectForCharacterRange:actualRange] are handled in a sane manner if they // arrive after the C++ RenderWidgetHostView is destroyed. TEST_F(RenderWidgetHostViewMacTest, CompositionEventAfterDestroy) { + ActivateViewWithTextInputManager(rwhv_mac_, ui::TEXT_INPUT_TYPE_TEXT); const gfx::Rect composition_bounds(0, 0, 30, 40); const gfx::Range range(0, 1); rwhv_mac_->ImeCompositionRangeChanged( @@ -1247,22 +1259,191 @@ host->ShutdownAndDestroyWidget(true); } +// This class is used for IME-related unit tests which verify correctness of IME +// for pages with multiple RWHVs. +class InputMethodMacTest : public RenderWidgetHostViewMacTest { + public: + InputMethodMacTest() {} + ~InputMethodMacTest() override {} + void SetUp() override { + RenderWidgetHostViewMacTest::SetUp(); + + // Initializing a child frame's view. + child_process_host_ = new MockRenderProcessHost(&browser_context_); + RenderWidgetHostDelegate* rwh_delegate = + RenderWidgetHostImpl::From(rvh()->GetWidget())->delegate(); + child_widget_ = new RenderWidgetHostImpl( + rwh_delegate, child_process_host_, + child_process_host_->GetNextRoutingID(), false); + child_view_ = new TestRenderWidgetHostView(child_widget_); + text_input_manager_ = rwh_delegate->GetTextInputManager(); + tab_widget_ = RenderWidgetHostImpl::From(rvh()->GetWidget()); + } + + void TearDown() override { + child_widget_->ShutdownAndDestroyWidget(true); + + RenderWidgetHostViewMacTest::TearDown(); + } + + void SetTextInputType(RenderWidgetHostViewBase* view, + ui::TextInputType type) { + TextInputState state; + state.type = type; + view->TextInputStateChanged(state); + } + + IPC::TestSink& tab_sink() { return process()->sink(); } + IPC::TestSink& child_sink() { return child_process_host_->sink(); } + TextInputManager* text_input_manager() { return text_input_manager_; } + RenderWidgetHostViewBase* tab_view() { return rwhv_mac_; } + RenderWidgetHostImpl* tab_widget() { return tab_widget_; } + + protected: + MockRenderProcessHost* child_process_host_; + RenderWidgetHostImpl* child_widget_; + TestRenderWidgetHostView* child_view_; + + private: + TestBrowserContext browser_context_; + TextInputManager* text_input_manager_; + RenderWidgetHostImpl* tab_widget_; + + DISALLOW_COPY_AND_ASSIGN(InputMethodMacTest); +}; + +// This test will verify that calling unmarkText on the cocoa view will lead to +// a confirm composition IPC for the corresponding active widget. +TEST_F(InputMethodMacTest, UnmarkText) { + // Make the child view active and then call unmarkText on the view (Note that + // |RenderWidgetHostViewCocoa::handlingKeyDown_| is false so calling + // unmarkText would lead to an IPC. This assumption is made in other similar + // tests as well). We should observe an IPC being sent to the |child_widget_|. + SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT); + EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget()); + child_sink().ClearMessages(); + [rwhv_cocoa_ unmarkText]; + EXPECT_TRUE(!!child_sink().GetFirstMessageMatching( + InputMsg_ImeConfirmComposition::ID)); + + // Repeat the same steps for the tab's view . + SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT); + EXPECT_EQ(tab_widget(), text_input_manager()->GetActiveWidget()); + tab_sink().ClearMessages(); + [rwhv_cocoa_ unmarkText]; + EXPECT_TRUE( + !!tab_sink().GetFirstMessageMatching(InputMsg_ImeConfirmComposition::ID)); +} + +// This test makes sure that calling setMarkedText on the cocoa view will lead +// to a set composition IPC for the corresponding active widget. +TEST_F(InputMethodMacTest, SetMarkedText) { + // Some values for the call to setMarkedText. + base::scoped_nsobject<NSString> text( + [[NSString alloc] initWithString:@"sample text"]); + NSRange selectedRange = NSMakeRange(0, 4); + NSRange replacementRange = NSMakeRange(0, 1); + + // Make the child view active and then call setMarkedText with some values. We + // should observe an IPC being sent to the |child_widget_|. + SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT); + EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget()); + child_sink().ClearMessages(); + [rwhv_cocoa_ setMarkedText:text + selectedRange:selectedRange + replacementRange:replacementRange]; + EXPECT_TRUE( + !!child_sink().GetFirstMessageMatching(InputMsg_ImeSetComposition::ID)); + + // Repeat the same steps for the tab's view. + SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT); + EXPECT_EQ(tab_widget(), text_input_manager()->GetActiveWidget()); + tab_sink().ClearMessages(); + [rwhv_cocoa_ setMarkedText:text + selectedRange:selectedRange + replacementRange:replacementRange]; + EXPECT_TRUE( + !!tab_sink().GetFirstMessageMatching(InputMsg_ImeSetComposition::ID)); +} + +// This test verifies that calling insertText on the cocoa view will lead to a +// confirm composition IPC sent to the active widget. +TEST_F(InputMethodMacTest, InsetText) { + // Some values for the call to insertText. + base::scoped_nsobject<NSString> text( + [[NSString alloc] initWithString:@"sample text"]); + NSRange replacementRange = NSMakeRange(0, 1); + + // Make the child view active and then call insertText with some values. We + // should observe an IPC being sent to the |child_widget_|. + SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT); + EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget()); + child_sink().ClearMessages(); + [rwhv_cocoa_ insertText:text replacementRange:replacementRange]; + EXPECT_TRUE(!!child_sink().GetFirstMessageMatching( + InputMsg_ImeConfirmComposition::ID)); + + // Repeat the same steps for the tab's view. + SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT); + EXPECT_EQ(tab_widget(), text_input_manager()->GetActiveWidget()); + [rwhv_cocoa_ insertText:text replacementRange:replacementRange]; + EXPECT_TRUE( + !!tab_sink().GetFirstMessageMatching(InputMsg_ImeConfirmComposition::ID)); +} + +// This test makes sure that calling confirmComposition on the cocoa view will +// lead to a confirm composition IPC for a the corresponding active widget. +TEST_F(InputMethodMacTest, ConfirmComposition) { + // Some values for the call to setMarkedText. + base::scoped_nsobject<NSString> text( + [[NSString alloc] initWithString:@"sample text"]); + NSRange selectedRange = NSMakeRange(0, 4); + NSRange replacementRange = NSMakeRange(0, 1); + + // Make child view active and then call confirmComposition. We should observe + // an IPC being sent to the |child_widget_|. + SetTextInputType(child_view_, ui::TEXT_INPUT_TYPE_TEXT); + EXPECT_EQ(child_widget_, text_input_manager()->GetActiveWidget()); + child_sink().ClearMessages(); + // In order to confirm composition, we must first have some marked text. So, + // we will first call setMarkedText on cocoa view. This would lead to a set + // composition IPC in the sink, but it doesn't matter since we will be looking + // for a confirm composition IPC for this test. + [rwhv_cocoa_ setMarkedText:text + selectedRange:selectedRange + replacementRange:replacementRange]; + [rwhv_cocoa_ confirmComposition]; + EXPECT_TRUE(!!child_sink().GetFirstMessageMatching( + InputMsg_ImeConfirmComposition::ID)); + + // Repeat the same steps for the tab's view. + SetTextInputType(tab_view(), ui::TEXT_INPUT_TYPE_TEXT); + EXPECT_EQ(tab_widget(), text_input_manager()->GetActiveWidget()); + tab_sink().ClearMessages(); + [rwhv_cocoa_ setMarkedText:text + selectedRange:selectedRange + replacementRange:replacementRange]; + [rwhv_cocoa_ confirmComposition]; + EXPECT_TRUE( + !!tab_sink().GetFirstMessageMatching(InputMsg_ImeConfirmComposition::ID)); +} + // This test creates a test view to mimic a child frame's view and verifies that // calling ImeCancelComposition on either the child view or the tab's view will // always lead to a call to cancelComposition on the cocoa view. -TEST_F(RenderWidgetHostViewMacTest, ImeCancelCompositionForAllViews) { - TestRenderWidgetHostView* child_view = - new TestRenderWidgetHostView(rvh()->GetWidget()); - // Set the marked test on cocoa view. - NSString* text = [[NSString alloc] initWithString:@"sample text"]; +TEST_F(InputMethodMacTest, ImeCancelCompositionForAllViews) { + // Some values for the call to setMarkedText. + base::scoped_nsobject<NSString> text( + [[NSString alloc] initWithString:@"sample text"]); NSRange selectedRange = NSMakeRange(0, 1); NSRange replacementRange = NSMakeRange(0, 1); + // Make Cocoa view assume there is marked text. [rwhv_cocoa_ setMarkedText:text selectedRange:selectedRange replacementRange:replacementRange]; EXPECT_TRUE([rwhv_cocoa_ hasMarkedText]); - child_view->ImeCancelComposition(); + child_view_->ImeCancelComposition(); EXPECT_FALSE([rwhv_cocoa_ hasMarkedText]); // Repeat for the tab's view.
diff --git a/content/browser/renderer_host/render_widget_host_view_mus.cc b/content/browser/renderer_host/render_widget_host_view_mus.cc index 1603db8c..f0297a48 100644 --- a/content/browser/renderer_host/render_widget_host_view_mus.cc +++ b/content/browser/renderer_host/render_widget_host_view_mus.cc
@@ -22,10 +22,6 @@ #include "ui/aura/window.h" #include "ui/base/hit_test.h" -namespace blink { -struct WebScreenInfo; -} - namespace content { RenderWidgetHostViewMus::RenderWidgetHostViewMus(ui::Window* parent_window, @@ -253,10 +249,6 @@ // TODO(fsamuel): Implement mouse lock in Mus. } -void RenderWidgetHostViewMus::GetScreenInfo(blink::WebScreenInfo* results) { - // TODO(fsamuel): Populate screen info from Mus. -} - gfx::Rect RenderWidgetHostViewMus::GetBoundsInRootWindow() { aura::Window* top_level = aura_window_->GetToplevelWindow(); gfx::Rect bounds(top_level->GetBoundsInScreen());
diff --git a/content/browser/renderer_host/render_widget_host_view_mus.h b/content/browser/renderer_host/render_widget_host_view_mus.h index 83355d9..78c5280 100644 --- a/content/browser/renderer_host/render_widget_host_view_mus.h +++ b/content/browser/renderer_host/render_widget_host_view_mus.h
@@ -100,7 +100,6 @@ void ClearCompositorFrame() override {} bool LockMouse() override; void UnlockMouse() override; - void GetScreenInfo(blink::WebScreenInfo* results) override; gfx::Rect GetBoundsInRootWindow() override; #if defined(OS_MACOSX)
diff --git a/content/browser/renderer_host/text_input_manager.cc b/content/browser/renderer_host/text_input_manager.cc index 3207b921..aa2522f 100644 --- a/content/browser/renderer_host/text_input_manager.cc +++ b/content/browser/renderer_host/text_input_manager.cc
@@ -70,11 +70,13 @@ selection_region_map_.at(active_view_).focus); } -const std::vector<gfx::Rect>* TextInputManager::GetCompositionCharacterBounds() - const { - return !!active_view_ - ? &composition_range_info_map_.at(active_view_).character_bounds - : nullptr; +const TextInputManager::CompositionRangeInfo* +TextInputManager::GetCompositionRangeInfo( + RenderWidgetHostViewBase* view) const { + DCHECK(!view || IsRegistered(view)); + if (!view) + view = active_view_; + return active_view_ ? &composition_range_info_map_.at(active_view_) : nullptr; } const TextInputManager::TextSelection* TextInputManager::GetTextSelection( @@ -197,6 +199,9 @@ #endif } +// TODO(ekaramad): We use |range| only on Mac OS; but we still track its value +// here for other platforms. See if there is a nice way around this with minimal +// #ifdefs for platform specific code (https://crbug.com/602427). void TextInputManager::ImeCompositionRangeChanged( RenderWidgetHostViewBase* view, const gfx::Range& range, @@ -211,6 +216,9 @@ view->TransformPointToRootCoordSpace(rect.origin()), rect.size())); } + composition_range_info_map_[view].range.set_start(range.start()); + composition_range_info_map_[view].range.set_end(range.end()); + FOR_EACH_OBSERVER(Observer, observer_list_, OnImeCompositionRangeChanged(this, view)); } @@ -266,6 +274,10 @@ observer_list_.RemoveObserver(observer); } +bool TextInputManager::HasObserver(Observer* observer) const { + return observer_list_.HasObserver(observer); +} + size_t TextInputManager::GetRegisteredViewsCountForTesting() { return text_input_state_map_.size(); }
diff --git a/content/browser/renderer_host/text_input_manager.h b/content/browser/renderer_host/text_input_manager.h index b09ae506..6af828f8 100644 --- a/content/browser/renderer_host/text_input_manager.h +++ b/content/browser/renderer_host/text_input_manager.h
@@ -79,6 +79,16 @@ base::string16 text; }; + // Composition range information. + struct CompositionRangeInfo { + CompositionRangeInfo(); + CompositionRangeInfo(const CompositionRangeInfo& other); + ~CompositionRangeInfo(); + + std::vector<gfx::Rect> character_bounds; + gfx::Range range; + }; + TextInputManager(); ~TextInputManager(); @@ -100,8 +110,11 @@ // Returns the rect between selection bounds. gfx::Rect GetSelectionBoundsRect() const; - // Returns a vector of rects representing the character bounds. - const std::vector<gfx::Rect>* GetCompositionCharacterBounds() const; + // Returns the composition range and character bounds information for the + // |view|. If |view| == nullptr, it will assume |active_view_| and return its + // state. If |active_view_| == nullptr, this method will return nullptr. + const TextInputManager::CompositionRangeInfo* GetCompositionRangeInfo( + RenderWidgetHostViewBase* view = nullptr) const; // The following method returns the text selection state for the given |view|. // If |view| == nullptr, it will assume |active_view_| and return its state. @@ -161,6 +174,7 @@ // TextInputManager. void AddObserver(Observer* observer); void RemoveObserver(Observer* observer); + bool HasObserver(Observer* observer) const; RenderWidgetHostViewBase* active_view_for_testing() { return active_view_; } size_t GetRegisteredViewsCountForTesting(); @@ -179,15 +193,6 @@ gfx::SelectionBound focus; }; - // Ccomposition range information. - struct CompositionRangeInfo { - CompositionRangeInfo(); - CompositionRangeInfo(const CompositionRangeInfo& other); - ~CompositionRangeInfo(); - - std::vector<gfx::Rect> character_bounds; - }; - // This class is used to create maps which hold specific IME state for a // view. template <class Value>
diff --git a/content/browser/renderer_host/websocket_blob_sender.cc b/content/browser/renderer_host/websocket_blob_sender.cc deleted file mode 100644 index 89bb151..0000000 --- a/content/browser/renderer_host/websocket_blob_sender.cc +++ /dev/null
@@ -1,284 +0,0 @@ -// Copyright 2016 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/renderer_host/websocket_blob_sender.h" - -#include <algorithm> -#include <ostream> -#include <utility> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/callback_helpers.h" -#include "base/logging.h" -#include "base/numerics/safe_conversions.h" -#include "content/browser/renderer_host/websocket_dispatcher_host.h" -#include "content/browser/renderer_host/websocket_host.h" -#include "net/base/io_buffer.h" -#include "net/base/net_errors.h" -#include "net/websockets/websocket_channel.h" -#include "net/websockets/websocket_frame.h" -#include "storage/browser/blob/blob_data_handle.h" -#include "storage/browser/blob/blob_reader.h" -#include "storage/browser/blob/blob_storage_context.h" - -namespace content { - -namespace { - -using storage::BlobReader; -using storage::BlobDataHandle; -using storage::BlobStorageContext; - -// This must be smaller than the send quota high water mark or this class will -// never send anything. -const int kMinimumNonFinalFrameSize = 8 * 1024; - -// The IOBuffer has a fixed size for simplicity. -const size_t kBufferSize = 128 * 1024; - -} // namespace - -// This is needed to make DCHECK_EQ(), etc. compile. -std::ostream& operator<<(std::ostream& os, WebSocketBlobSender::State state) { - static const char* const kStateStrings[] = { - "NONE", - "READ_SIZE", - "READ_SIZE_COMPLETE", - "WAIT_FOR_QUOTA", - "WAIT_FOR_QUOTA_COMPLETE", - "READ", - "READ_COMPLETE", - }; - if (state < WebSocketBlobSender::State::NONE || - state > WebSocketBlobSender::State::READ_COMPLETE) { - return os << "Bad State (" << static_cast<int>(state) << ")"; - } - return os << kStateStrings[static_cast<int>(state)]; -} - -WebSocketBlobSender::WebSocketBlobSender(std::unique_ptr<Channel> channel) - : channel_(std::move(channel)) {} - -WebSocketBlobSender::~WebSocketBlobSender() {} - -int WebSocketBlobSender::Start( - const std::string& uuid, - uint64_t expected_size, - BlobStorageContext* context, - storage::FileSystemContext* file_system_context, - base::SingleThreadTaskRunner* file_task_runner, - net::WebSocketEventInterface::ChannelState* channel_state, - const net::CompletionCallback& callback) { - DCHECK(context); - DCHECK(channel_state); - DCHECK(!reader_); - std::unique_ptr<storage::BlobDataHandle> data_handle( - context->GetBlobDataFromUUID(uuid)); - if (!data_handle) - return net::ERR_INVALID_HANDLE; - reader_ = data_handle->CreateReader(file_system_context, file_task_runner); - expected_size_ = expected_size; - next_state_ = State::READ_SIZE; - int rv = DoLoop(net::OK, channel_state); - if (*channel_state == net::WebSocketEventInterface::CHANNEL_ALIVE && - rv == net::ERR_IO_PENDING) { - callback_ = callback; - } - return rv; -} - -void WebSocketBlobSender::OnNewSendQuota() { - if (next_state_ == State::WAIT_FOR_QUOTA) - DoLoopAsync(net::OK); - // |this| may be deleted. -} - -uint64_t WebSocketBlobSender::ActualSize() const { - return reader_->total_size(); -} - -void WebSocketBlobSender::OnReadComplete(int rv) { - DCHECK_EQ(State::READ_COMPLETE, next_state_); - DoLoopAsync(rv); - // |this| may be deleted. -} - -void WebSocketBlobSender::OnSizeCalculated(int rv) { - DCHECK_EQ(State::READ_SIZE_COMPLETE, next_state_); - DoLoopAsync(rv); - // |this| may be deleted. -} - -int WebSocketBlobSender::DoLoop(int result, - Channel::ChannelState* channel_state) { - DCHECK_NE(State::NONE, next_state_); - int rv = result; - do { - State state = next_state_; - next_state_ = State::NONE; - switch (state) { - case State::READ_SIZE: - DCHECK_EQ(net::OK, rv); - rv = DoReadSize(); - break; - - case State::READ_SIZE_COMPLETE: - rv = DoReadSizeComplete(rv); - break; - - case State::WAIT_FOR_QUOTA: - DCHECK_EQ(net::OK, rv); - rv = DoWaitForQuota(); - break; - - case State::WAIT_FOR_QUOTA_COMPLETE: - DCHECK_EQ(net::OK, rv); - rv = DoWaitForQuotaComplete(); - break; - - case State::READ: - DCHECK_EQ(net::OK, rv); - rv = DoRead(); - break; - - case State::READ_COMPLETE: - rv = DoReadComplete(rv, channel_state); - break; - - default: - NOTREACHED(); - break; - } - } while (*channel_state != net::WebSocketEventInterface::CHANNEL_DELETED && - rv != net::ERR_IO_PENDING && next_state_ != State::NONE); - return rv; -} - -void WebSocketBlobSender::DoLoopAsync(int result) { - Channel::ChannelState channel_state = - net::WebSocketEventInterface::CHANNEL_ALIVE; - int rv = DoLoop(result, &channel_state); - if (channel_state == net::WebSocketEventInterface::CHANNEL_ALIVE && - rv != net::ERR_IO_PENDING) { - ResetAndReturn(&callback_).Run(rv); - } - // |this| may be deleted. -} - -int WebSocketBlobSender::DoReadSize() { - next_state_ = State::READ_SIZE_COMPLETE; - // This use of base::Unretained() is safe because BlobReader cannot call the - // callback after it has been destroyed, and it is owned by this object. - BlobReader::Status status = reader_->CalculateSize(base::Bind( - &WebSocketBlobSender::OnSizeCalculated, base::Unretained(this))); - switch (status) { - case BlobReader::Status::NET_ERROR: - return reader_->net_error(); - - case BlobReader::Status::IO_PENDING: - return net::ERR_IO_PENDING; - - case BlobReader::Status::DONE: - return net::OK; - } - NOTREACHED(); - return net::ERR_UNEXPECTED; -} - -int WebSocketBlobSender::DoReadSizeComplete(int result) { - if (result < 0) - return result; - if (reader_->total_size() != expected_size_) - return net::ERR_UPLOAD_FILE_CHANGED; - bytes_left_ = expected_size_; - // The result of the call to std::min() must fit inside a size_t because - // kBufferSize is type size_t. - size_t buffer_size = static_cast<size_t>( - std::min(bytes_left_, base::strict_cast<uint64_t>(kBufferSize))); - buffer_ = new net::IOBuffer(buffer_size); - next_state_ = State::WAIT_FOR_QUOTA; - return net::OK; -} - -// The WAIT_FOR_QUOTA state has a self-edge; it will wait in this state until -// there is enough quota to send some data. -int WebSocketBlobSender::DoWaitForQuota() { - size_t quota = channel_->GetSendQuota(); - if (kMinimumNonFinalFrameSize <= quota || bytes_left_ <= quota) { - next_state_ = State::WAIT_FOR_QUOTA_COMPLETE; - return net::OK; - } - next_state_ = State::WAIT_FOR_QUOTA; - return net::ERR_IO_PENDING; -} - -// State::WAIT_FOR_QUOTA_COMPLETE exists just to give the state machine the -// expected shape. It should be mostly optimised out. -int WebSocketBlobSender::DoWaitForQuotaComplete() { - next_state_ = State::READ; - return net::OK; -} - -int WebSocketBlobSender::DoRead() { - next_state_ = State::READ_COMPLETE; - size_t quota = channel_->GetSendQuota(); - // |desired_bytes| must fit in a size_t because |quota| is of type - // size_t and so cannot be larger than its maximum value. - size_t desired_bytes = - static_cast<size_t>(std::min(bytes_left_, static_cast<uint64_t>(quota))); - - // For simplicity this method only reads as many bytes as are currently - // needed. - size_t bytes_to_read = std::min(desired_bytes, kBufferSize); - int bytes_read = 0; - DCHECK(reader_); - DCHECK(buffer_); - - // This use of base::Unretained is safe because the BlobReader object won't - // call the callback after it has been destroyed, and it belongs to this - // object. - BlobReader::Status status = reader_->Read( - buffer_.get(), bytes_to_read, &bytes_read, - base::Bind(&WebSocketBlobSender::OnReadComplete, base::Unretained(this))); - - switch (status) { - case BlobReader::Status::NET_ERROR: - return reader_->net_error(); - - case BlobReader::Status::IO_PENDING: - return net::ERR_IO_PENDING; - - case BlobReader::Status::DONE: - return bytes_read; - } - NOTREACHED(); - return net::ERR_UNEXPECTED; -} - -int WebSocketBlobSender::DoReadComplete(int result, - Channel::ChannelState* channel_state) { - if (result < 0) - return result; - DCHECK_GE(channel_->GetSendQuota(), static_cast<size_t>(result)); - uint64_t bytes_read = static_cast<uint64_t>(result); - DCHECK_GE(bytes_left_, bytes_read); - bytes_left_ -= bytes_read; - bool fin = bytes_left_ == 0; - std::vector<char> data(buffer_->data(), buffer_->data() + bytes_read); - DCHECK(fin || data.size() > 0u) << "Non-final frames should be non-empty"; - *channel_state = channel_->SendFrame(fin, data); - if (*channel_state == net::WebSocketEventInterface::CHANNEL_DELETED) { - // |this| is deleted. - return net::ERR_CONNECTION_RESET; - } - - // It is important not to set next_state_ until after the call to SendFrame() - // because SendFrame() will sometimes call OnNewSendQuota() synchronously. - if (!fin) - next_state_ = State::WAIT_FOR_QUOTA; - return net::OK; -} - -} // namespace content
diff --git a/content/browser/renderer_host/websocket_blob_sender.h b/content/browser/renderer_host/websocket_blob_sender.h deleted file mode 100644 index d8131ad..0000000 --- a/content/browser/renderer_host/websocket_blob_sender.h +++ /dev/null
@@ -1,140 +0,0 @@ -// Copyright 2016 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_RENDERER_HOST_WEBSOCKET_BLOB_SENDER_H_ -#define CONTENT_BROWSER_RENDERER_HOST_WEBSOCKET_BLOB_SENDER_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <iosfwd> -#include <memory> -#include <string> -#include <vector> - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "content/common/content_export.h" -#include "net/base/completion_callback.h" -#include "net/websockets/websocket_event_interface.h" - -namespace base { -class SingleThreadTaskRunner; -} - -namespace net { -class IOBuffer; -} - -namespace storage { -class BlobReader; -class BlobStorageContext; -class FileSystemContext; -} - -namespace content { - -class WebSocketHost; - -// Read the contents of a Blob and write it to a WebSocket. Single-use: a new -// object must be created each time a Blob is sent. Destroying the object -// cancels all pending operations. -class CONTENT_EXPORT WebSocketBlobSender final { - public: - // An abstraction of the WebSocketChannel this object will send frames to. - class Channel { - public: - using ChannelState = net::WebSocketEventInterface::ChannelState; - - Channel() {} - virtual ~Channel() {} - - // The currently available quota for sending. It must not decrease without - // SendFrame() being called. - virtual size_t GetSendQuota() const = 0; - - // Send a binary frame. |fin| is true for the final frame of the message. - // |data| is the contents of the frame. data.size() must be less than - // GetSendQuota(). If this call returns CHANNEL_DELETED, WebSocketBlobSender - // will assume that it has been deleted and return without calling any - // callbacks or accessing any other member data. - virtual ChannelState SendFrame(bool fin, const std::vector<char>& data) = 0; - - private: - DISALLOW_COPY_AND_ASSIGN(Channel); - }; - - // |channel| will be destroyed when this object is. - explicit WebSocketBlobSender(std::unique_ptr<Channel> channel); - ~WebSocketBlobSender(); - - // Checks that the blob identified by |uuid| exists, has the size - // |expected_size| and then starts sending it via |channel_|. Returns - // ERR_IO_PENDING to indicate that |callback| will be called later with the - // result. net::OK indicates synchronous success. Any other net error code - // indicates synchronous failure. This method may result in the destruction of - // the channel, in which case |*channel_state| will be set to CHANNEL_DELETED. - int Start(const std::string& uuid, - uint64_t expected_size, - storage::BlobStorageContext* context, - storage::FileSystemContext* file_system_context, - base::SingleThreadTaskRunner* file_task_runner, - net::WebSocketEventInterface::ChannelState* channel_state, - const net::CompletionCallback& callback); - - // Sends more data if the object was waiting for quota and the new value of - // GetSendQuota() is large enough. - void OnNewSendQuota(); - - uint64_t expected_size() const { return expected_size_; } - - // ActualSize() should only be called after completion: ie. Start() returned a - // value other than ERR_IO_PENDING or |callback_| has been called. - uint64_t ActualSize() const; - - private: - // State proceeds through READ_SIZE and READ_SIZE_COMPLETE, then - // loops WAIT_FOR_QUOTA -> WAIT_FOR_QUOTA_COMPLETE -> READ - // -> READ_COMPLETE -> WAIT_FOR_QUOTA until the Blob is completely - // sent. - enum class State { - NONE = 0, - READ_SIZE, - READ_SIZE_COMPLETE, - WAIT_FOR_QUOTA, - WAIT_FOR_QUOTA_COMPLETE, - READ, - READ_COMPLETE, - }; - - // This is needed to make DCHECK_EQ(), etc. compile. - friend std::ostream& operator<<(std::ostream& os, State state); - - void OnReadComplete(int rv); - void OnSizeCalculated(int rv); - // |channel_state| should point to CHANNEL_ALIVE when called. If it is - // CHANNEL_DELETED on return, the object has been deleted. - int DoLoop(int result, Channel::ChannelState* channel_state); - void DoLoopAsync(int result); - int DoReadSize(); - int DoReadSizeComplete(int result); - int DoWaitForQuota(); - int DoWaitForQuotaComplete(); - int DoRead(); - int DoReadComplete(int result, Channel::ChannelState* channel_state); - - State next_state_ = State::NONE; - uint64_t expected_size_ = 0; - uint64_t bytes_left_ = 0; - net::CompletionCallback callback_; - scoped_refptr<net::IOBuffer> buffer_; - std::unique_ptr<storage::BlobReader> reader_; - const std::unique_ptr<Channel> channel_; - - DISALLOW_COPY_AND_ASSIGN(WebSocketBlobSender); -}; - -} // namespace content - -#endif // CONTENT_BROWSER_RENDERER_HOST_WEBSOCKET_BLOB_SENDER_H_
diff --git a/content/browser/renderer_host/websocket_blob_sender_unittest.cc b/content/browser/renderer_host/websocket_blob_sender_unittest.cc deleted file mode 100644 index 590c914b..0000000 --- a/content/browser/renderer_host/websocket_blob_sender_unittest.cc +++ /dev/null
@@ -1,450 +0,0 @@ -// Copyright 2016 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/renderer_host/websocket_blob_sender.h" - -#include <string.h> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/callback.h" -#include "base/files/file.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "base/location.h" -#include "base/memory/ptr_util.h" -#include "base/memory/weak_ptr.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/single_thread_task_runner.h" -#include "base/task_runner.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/time/time.h" -#include "content/browser/blob_storage/chrome_blob_storage_context.h" -#include "content/public/browser/blob_handle.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/storage_partition.h" -#include "content/public/test/test_browser_context.h" -#include "content/public/test/test_browser_thread_bundle.h" -#include "net/base/completion_callback.h" -#include "net/base/net_errors.h" -#include "net/base/test_completion_callback.h" -#include "storage/common/fileapi/file_system_types.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" - -namespace content { - -namespace { - -const char kDummyUrl[] = "http://www.example.com/"; -const char kBanana[] = "banana"; - -// This is small so that the tests do not waste too much time just copying bytes -// around. But it has to be larger than kMinimumNonFinalFrameSize defined in -// websocket_blob_sender.cc. -const size_t kInitialQuota = 16 * 1024; - -using net::TestCompletionCallback; - -// A fake channel for testing. Records the contents of the message that was sent -// through it. Quota is restricted, and is refreshed asynchronously in response -// to calls to SendFrame(). -class FakeChannel : public WebSocketBlobSender::Channel { - public: - // |notify_new_quota| will be run asynchronously on the current MessageLoop - // every time GetSendQuota() increases. - FakeChannel() : weak_factory_(this) {} - - // This method must be called before SendFrame() is. - void set_notify_new_quota(const base::Closure& notify_new_quota) { - notify_new_quota_ = notify_new_quota; - } - - size_t GetSendQuota() const override { return current_send_quota_; } - - ChannelState SendFrame(bool fin, const std::vector<char>& data) override { - ++frames_sent_; - EXPECT_FALSE(got_fin_); - if (fin) - got_fin_ = true; - EXPECT_LE(data.size(), current_send_quota_); - message_.insert(message_.end(), data.begin(), data.end()); - current_send_quota_ -= data.size(); - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::Bind(&FakeChannel::RefreshQuota, weak_factory_.GetWeakPtr())); - return net::WebSocketEventInterface::CHANNEL_ALIVE; - } - - bool got_fin() const { return got_fin_; } - - int frames_sent() const { return frames_sent_; } - - const std::vector<char>& message() const { return message_; } - - private: - void RefreshQuota() { - if (current_send_quota_ == kInitialQuota) - return; - current_send_quota_ = kInitialQuota; - DCHECK(!notify_new_quota_.is_null()); - notify_new_quota_.Run(); - } - - base::Closure notify_new_quota_; - size_t current_send_quota_ = kInitialQuota; - int frames_sent_ = 0; - bool got_fin_ = false; - std::vector<char> message_; - base::WeakPtrFactory<FakeChannel> weak_factory_; -}; - -class WebSocketBlobSenderTest : public ::testing::Test { - protected: - // The Windows implementation of net::FileStream::Context requires a real IO - // MessageLoop. - WebSocketBlobSenderTest() - : threads_(TestBrowserThreadBundle::IO_MAINLOOP), - chrome_blob_storage_context_( - ChromeBlobStorageContext::GetFor(&browser_context_)), - fake_channel_(nullptr), - sender_() {} - ~WebSocketBlobSenderTest() override {} - - void SetUp() override { - // ChromeBlobStorageContext::GetFor() does some work asynchronously. - base::RunLoop().RunUntilIdle(); - SetUpSender(); - } - - // This method can be overriden to use a different channel implementation. - virtual void SetUpSender() { - fake_channel_ = new FakeChannel; - sender_.reset(new WebSocketBlobSender(base::WrapUnique(fake_channel_))); - fake_channel_->set_notify_new_quota(base::Bind( - &WebSocketBlobSender::OnNewSendQuota, base::Unretained(sender_.get()))); - } - - storage::BlobStorageContext* context() { - return chrome_blob_storage_context_->context(); - } - - storage::FileSystemContext* GetFileSystemContext() { - StoragePartition* partition = BrowserContext::GetStoragePartitionForSite( - &browser_context_, GURL(kDummyUrl)); - return partition->GetFileSystemContext(); - } - - // |string| is copied. - std::unique_ptr<BlobHandle> CreateMemoryBackedBlob(const char* string) { - std::unique_ptr<BlobHandle> handle = - chrome_blob_storage_context_->CreateMemoryBackedBlob(string, - strlen(string)); - EXPECT_TRUE(handle); - return handle; - } - - // Call sender_.Start() with the other parameters filled in appropriately for - // this test fixture. - int Start(const std::string& uuid, - uint64_t expected_size, - const net::CompletionCallback& callback) { - net::WebSocketEventInterface::ChannelState channel_state = - net::WebSocketEventInterface::CHANNEL_ALIVE; - return sender_->Start( - uuid, expected_size, context(), GetFileSystemContext(), - BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get(), - &channel_state, callback); - } - - void NotCalledCallbackImpl(int rv) { - ADD_FAILURE() - << "Callback that should not be called was called with argument " << rv; - } - - net::CompletionCallback NotCalled() { - return base::Bind(&WebSocketBlobSenderTest::NotCalledCallbackImpl, - base::Unretained(this)); - } - - void ExpectOkAndQuit(base::RunLoop* run_loop, int result) { - EXPECT_EQ(net::OK, result); - run_loop->Quit(); - } - - net::CompletionCallback ExpectOkAndQuitCallback(base::RunLoop* run_loop) { - return base::Bind(&WebSocketBlobSenderTest::ExpectOkAndQuit, - base::Unretained(this), run_loop); - } - - TestBrowserThreadBundle threads_; - TestBrowserContext browser_context_; - scoped_refptr<ChromeBlobStorageContext> chrome_blob_storage_context_; - // |fake_channel_| is owned by |sender_|. - FakeChannel* fake_channel_; - std::unique_ptr<WebSocketBlobSender> sender_; -}; - -TEST_F(WebSocketBlobSenderTest, Construction) {} - -TEST_F(WebSocketBlobSenderTest, EmptyBlob) { - std::unique_ptr<BlobHandle> handle = CreateMemoryBackedBlob(""); - - // The APIs allow for this to be asynchronous but that is unlikely in - // practice. - int result = Start(handle->GetUUID(), UINT64_C(0), NotCalled()); - // If this fails with result == -1, someone has changed the code to be - // asynchronous and this test should be adapted to match. - EXPECT_EQ(net::OK, result); - EXPECT_TRUE(fake_channel_->got_fin()); - EXPECT_EQ(0U, fake_channel_->message().size()); -} - -TEST_F(WebSocketBlobSenderTest, SmallBlob) { - std::unique_ptr<BlobHandle> handle = CreateMemoryBackedBlob(kBanana); - - EXPECT_EQ(net::OK, Start(handle->GetUUID(), UINT64_C(6), NotCalled())); - EXPECT_TRUE(fake_channel_->got_fin()); - EXPECT_EQ(1, fake_channel_->frames_sent()); - EXPECT_EQ(std::vector<char>(kBanana, kBanana + 6), fake_channel_->message()); -} - -TEST_F(WebSocketBlobSenderTest, SizeMismatch) { - std::unique_ptr<BlobHandle> handle = CreateMemoryBackedBlob(kBanana); - - EXPECT_EQ(net::ERR_UPLOAD_FILE_CHANGED, - Start(handle->GetUUID(), UINT64_C(5), NotCalled())); - EXPECT_EQ(0, fake_channel_->frames_sent()); -} - -TEST_F(WebSocketBlobSenderTest, InvalidUUID) { - EXPECT_EQ(net::ERR_INVALID_HANDLE, - Start("sandwich", UINT64_C(0), NotCalled())); -} - -TEST_F(WebSocketBlobSenderTest, LargeMessage) { - std::string message(kInitialQuota + 10, 'a'); - std::unique_ptr<BlobHandle> handle = CreateMemoryBackedBlob(message.c_str()); - - base::RunLoop run_loop; - int rv = Start(handle->GetUUID(), message.size(), - ExpectOkAndQuitCallback(&run_loop)); - EXPECT_EQ(net::ERR_IO_PENDING, rv); - EXPECT_EQ(1, fake_channel_->frames_sent()); - run_loop.Run(); - EXPECT_EQ(2, fake_channel_->frames_sent()); - EXPECT_TRUE(fake_channel_->got_fin()); - std::vector<char> expected_message(message.begin(), message.end()); - EXPECT_EQ(expected_message, fake_channel_->message()); -} - -// A message exactly equal to the available quota should be sent in one frame. -TEST_F(WebSocketBlobSenderTest, ExactSizeMessage) { - std::string message(kInitialQuota, 'a'); - std::unique_ptr<BlobHandle> handle = CreateMemoryBackedBlob(message.c_str()); - - EXPECT_EQ(net::OK, Start(handle->GetUUID(), message.size(), NotCalled())); - EXPECT_EQ(1, fake_channel_->frames_sent()); - EXPECT_TRUE(fake_channel_->got_fin()); - std::vector<char> expected_message(message.begin(), message.end()); - EXPECT_EQ(expected_message, fake_channel_->message()); -} - -// If the connection is closed while sending a message, the WebSocketBlobSender -// object will be destroyed. It needs to handle this case without error. -TEST_F(WebSocketBlobSenderTest, AbortedSend) { - std::string message(kInitialQuota + 10, 'a'); - std::unique_ptr<BlobHandle> handle = CreateMemoryBackedBlob(message.c_str()); - - int rv = Start(handle->GetUUID(), message.size(), NotCalled()); - EXPECT_EQ(net::ERR_IO_PENDING, rv); - sender_.reset(); -} - -// Invalid file-backed blob. -TEST_F(WebSocketBlobSenderTest, InvalidFileBackedBlob) { - base::FilePath path(FILE_PATH_LITERAL( - "WebSocketBlobSentTest.InvalidFileBackedBlob.NonExistentFile")); - std::unique_ptr<BlobHandle> handle = - chrome_blob_storage_context_->CreateFileBackedBlob(path, 0u, 32u, - base::Time::Now()); - EXPECT_TRUE(handle); - - TestCompletionCallback callback; - int rv = - callback.GetResult(Start(handle->GetUUID(), 5u, callback.callback())); - EXPECT_EQ(net::ERR_FILE_NOT_FOUND, rv); -} - -// A test fixture that does the additional work necessary to create working -// file-backed blobs. -class WebSocketFileBackedBlobSenderTest : public WebSocketBlobSenderTest { - protected: - void SetUp() override { - WebSocketBlobSenderTest::SetUp(); - // temp_dir_ is recursively deleted on destruction. - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - } - - void CreateFile(const std::string& contents, - const base::FilePath& path, - base::File::Info* info) { - ASSERT_EQ(contents.size(), static_cast<size_t>(base::WriteFile( - path, contents.data(), contents.size()))); - ASSERT_TRUE(base::GetFileInfo(path, info)); - } - - std::unique_ptr<BlobHandle> CreateFileBackedBlob( - const std::string& contents) { - base::FilePath path = temp_dir_.path().AppendASCII("blob.dat"); - base::File::Info info; - CreateFile(contents, path, &info); - if (HasFatalFailure()) - return nullptr; - return chrome_blob_storage_context_->CreateFileBackedBlob( - path, 0u, contents.size(), info.last_modified); - } - - base::ScopedTempDir temp_dir_; -}; - -TEST_F(WebSocketFileBackedBlobSenderTest, EmptyBlob) { - std::unique_ptr<BlobHandle> handle = CreateFileBackedBlob(""); - ASSERT_TRUE(handle); - - TestCompletionCallback callback; - int result = callback.GetResult( - Start(handle->GetUUID(), UINT64_C(0), callback.callback())); - EXPECT_EQ(net::OK, result); - EXPECT_TRUE(fake_channel_->got_fin()); - EXPECT_EQ(0U, fake_channel_->message().size()); -} - -TEST_F(WebSocketFileBackedBlobSenderTest, SizeMismatch) { - std::unique_ptr<BlobHandle> handle = CreateFileBackedBlob(kBanana); - ASSERT_TRUE(handle); - - TestCompletionCallback callback; - int result = Start(handle->GetUUID(), UINT64_C(8), callback.callback()); - // This test explicitly aims to test the asynchronous code path, otherwise it - // would be identical to the other SizeMismatch test above. - EXPECT_EQ(net::ERR_IO_PENDING, result); - EXPECT_EQ(net::ERR_UPLOAD_FILE_CHANGED, callback.WaitForResult()); - EXPECT_EQ(0, fake_channel_->frames_sent()); -} - -TEST_F(WebSocketFileBackedBlobSenderTest, LargeMessage) { - std::string message = "the green potato had lunch with the angry cat. "; - while (message.size() <= kInitialQuota) { - message = message + message; - } - std::unique_ptr<BlobHandle> handle = CreateFileBackedBlob(message); - ASSERT_TRUE(handle); - - TestCompletionCallback callback; - int result = Start(handle->GetUUID(), message.size(), callback.callback()); - EXPECT_EQ(net::OK, callback.GetResult(result)); - std::vector<char> expected_message(message.begin(), message.end()); - EXPECT_EQ(expected_message, fake_channel_->message()); -} - -// The WebSocketBlobSender needs to handle a connection close while doing file -// IO cleanly. -TEST_F(WebSocketFileBackedBlobSenderTest, Aborted) { - std::unique_ptr<BlobHandle> handle = CreateFileBackedBlob(kBanana); - - int rv = Start(handle->GetUUID(), UINT64_C(6), NotCalled()); - EXPECT_EQ(net::ERR_IO_PENDING, rv); - sender_.reset(); -} - -class DeletingFakeChannel : public WebSocketBlobSender::Channel { - public: - explicit DeletingFakeChannel( - std::unique_ptr<WebSocketBlobSender>* sender_to_delete) - : sender_(sender_to_delete) {} - - size_t GetSendQuota() const override { return kInitialQuota; } - - ChannelState SendFrame(bool fin, const std::vector<char>& data) override { - sender_->reset(); - // |this| is deleted here. - return net::WebSocketEventInterface::CHANNEL_DELETED; - } - - private: - std::unique_ptr<WebSocketBlobSender>* sender_; -}; - -class WebSocketBlobSenderDeletingTest : public WebSocketBlobSenderTest { - protected: - void SetUpSender() override { - sender_.reset(new WebSocketBlobSender( - base::WrapUnique(new DeletingFakeChannel(&sender_)))); - } -}; - -// This test only does something useful when run under AddressSanitizer or a -// similar tool that can detect use-after-free bugs. -TEST_F(WebSocketBlobSenderDeletingTest, SenderDeleted) { - std::unique_ptr<BlobHandle> handle = CreateMemoryBackedBlob(kBanana); - - EXPECT_EQ(net::ERR_CONNECTION_RESET, - Start(handle->GetUUID(), UINT64_C(6), NotCalled())); - EXPECT_FALSE(sender_); -} - -// SendFrame() calls OnSendNewQuota() synchronously while filling the operating -// system's socket write buffer. The purpose of this Channel implementation is -// to verify that the synchronous case works correctly. -class SynchronousFakeChannel : public WebSocketBlobSender::Channel { - public: - // This method must be called before SendFrame() is. - void set_notify_new_quota(const base::Closure& notify_new_quota) { - notify_new_quota_ = notify_new_quota; - } - - size_t GetSendQuota() const override { return kInitialQuota; } - - ChannelState SendFrame(bool fin, const std::vector<char>& data) override { - message_.insert(message_.end(), data.begin(), data.end()); - notify_new_quota_.Run(); - return net::WebSocketEventInterface::CHANNEL_ALIVE; - } - - const std::vector<char>& message() const { return message_; } - - private: - base::Closure notify_new_quota_; - std::vector<char> message_; -}; - -class WebSocketBlobSenderSynchronousTest : public WebSocketBlobSenderTest { - protected: - void SetUpSender() override { - synchronous_fake_channel_ = new SynchronousFakeChannel; - sender_.reset( - new WebSocketBlobSender(base::WrapUnique(synchronous_fake_channel_))); - synchronous_fake_channel_->set_notify_new_quota(base::Bind( - &WebSocketBlobSender::OnNewSendQuota, base::Unretained(sender_.get()))); - } - - SynchronousFakeChannel* synchronous_fake_channel_ = nullptr; -}; - -TEST_F(WebSocketBlobSenderSynchronousTest, LargeMessage) { - std::string message(kInitialQuota + 10, 'a'); - std::unique_ptr<BlobHandle> handle = CreateMemoryBackedBlob(message.c_str()); - - int rv = Start(handle->GetUUID(), message.size(), NotCalled()); - EXPECT_EQ(net::OK, rv); - std::vector<char> expected_message(message.begin(), message.end()); - EXPECT_EQ(expected_message, synchronous_fake_channel_->message()); -} - -} // namespace - -} // namespace content
diff --git a/content/browser/renderer_host/websocket_dispatcher_host.cc b/content/browser/renderer_host/websocket_dispatcher_host.cc deleted file mode 100644 index b20f54c..0000000 --- a/content/browser/renderer_host/websocket_dispatcher_host.cc +++ /dev/null
@@ -1,310 +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 "content/browser/renderer_host/websocket_dispatcher_host.h" - -#include <stddef.h> - -#include <algorithm> -#include <string> -#include <vector> - -#include "base/callback.h" -#include "base/logging.h" -#include "base/numerics/safe_conversions.h" -#include "base/rand_util.h" -#include "base/stl_util.h" -#include "content/browser/blob_storage/chrome_blob_storage_context.h" -#include "content/browser/child_process_security_policy_impl.h" -#include "content/browser/renderer_host/websocket_host.h" -#include "content/common/websocket_messages.h" - -namespace content { - -namespace { - -// Many methods defined in this file return a WebSocketHostState enum -// value. Make WebSocketHostState visible at file scope so it doesn't have to be -// fully-qualified every time. -typedef WebSocketDispatcherHost::WebSocketHostState WebSocketHostState; - -// Max number of pending connections per WebSocketDispatcherHost -// used for per-renderer WebSocket throttling. -const int kMaxPendingWebSocketConnections = 255; - -} // namespace - -WebSocketDispatcherHost::WebSocketDispatcherHost( - int process_id, - const GetRequestContextCallback& get_context_callback, - ChromeBlobStorageContext* blob_storage_context, - StoragePartition* storage_partition) - : BrowserMessageFilter(WebSocketMsgStart), - process_id_(process_id), - get_context_callback_(get_context_callback), - websocket_host_factory_( - base::Bind(&WebSocketDispatcherHost::CreateWebSocketHost, - base::Unretained(this))), - num_pending_connections_(0), - num_current_succeeded_connections_(0), - num_previous_succeeded_connections_(0), - num_current_failed_connections_(0), - num_previous_failed_connections_(0), - blob_storage_context_(blob_storage_context), - storage_partition_(storage_partition) {} - -WebSocketDispatcherHost::WebSocketDispatcherHost( - int process_id, - const GetRequestContextCallback& get_context_callback, - const WebSocketHostFactory& websocket_host_factory) - : BrowserMessageFilter(WebSocketMsgStart), - process_id_(process_id), - get_context_callback_(get_context_callback), - websocket_host_factory_(websocket_host_factory), - num_pending_connections_(0), - num_current_succeeded_connections_(0), - num_previous_succeeded_connections_(0), - num_current_failed_connections_(0), - num_previous_failed_connections_(0), - storage_partition_(nullptr) {} - -WebSocketHost* WebSocketDispatcherHost::CreateWebSocketHost( - int routing_id, - base::TimeDelta delay) { - return new WebSocketHost( - routing_id, this, get_context_callback_.Run(), delay); -} - -bool WebSocketDispatcherHost::OnMessageReceived(const IPC::Message& message) { - switch (message.type()) { - case WebSocketHostMsg_AddChannelRequest::ID: - case WebSocketHostMsg_SendBlob::ID: - case WebSocketMsg_SendFrame::ID: - case WebSocketMsg_FlowControl::ID: - case WebSocketMsg_DropChannel::ID: - break; - - default: - // Every message that has not been handled by a previous filter passes - // through here, so it is good to pass them on as efficiently as possible. - return false; - } - - int routing_id = message.routing_id(); - WebSocketHost* host = GetHost(routing_id); - if (message.type() == WebSocketHostMsg_AddChannelRequest::ID) { - if (host) { - DVLOG(1) << "routing_id=" << routing_id << " already in use."; - // The websocket multiplexing spec says to should drop the physical - // connection in this case, but there isn't a real physical connection - // to the renderer, and killing the renderer for this would seem to be a - // little extreme. So for now just ignore the bogus request. - return true; // We handled the message (by ignoring it). - } - if (num_pending_connections_ >= kMaxPendingWebSocketConnections) { - if (!Send(new WebSocketMsg_NotifyFailure( - routing_id, - "Error in connection establishment: " - "net::ERR_INSUFFICIENT_RESOURCES"))) { - DVLOG(1) << "Sending of message type " - << "WebSocketMsg_NotifyFailure failed."; - } - return true; - } - host = websocket_host_factory_.Run(routing_id, CalculateDelay()); - hosts_.insert(WebSocketHostTable::value_type(routing_id, host)); - ++num_pending_connections_; - if (!throttling_period_timer_.IsRunning()) - throttling_period_timer_.Start( - FROM_HERE, - base::TimeDelta::FromMinutes(2), - this, - &WebSocketDispatcherHost::ThrottlingPeriodTimerCallback); - } - if (!host) { - DVLOG(1) << "Received invalid routing ID " << routing_id - << " from renderer."; - return true; // We handled the message (by ignoring it). - } - return host->OnMessageReceived(message); -} - -bool WebSocketDispatcherHost::CanReadRawCookies() const { - ChildProcessSecurityPolicyImpl* policy = - ChildProcessSecurityPolicyImpl::GetInstance(); - return policy->CanReadRawCookies(process_id_); -} - -storage::BlobStorageContext* WebSocketDispatcherHost::blob_storage_context() - const { - DCHECK(blob_storage_context_); - return blob_storage_context_->context(); -} - -WebSocketHost* WebSocketDispatcherHost::GetHost(int routing_id) const { - WebSocketHostTable::const_iterator it = hosts_.find(routing_id); - return it == hosts_.end() ? NULL : it->second; -} - -WebSocketHostState WebSocketDispatcherHost::SendOrDrop(IPC::Message* message) { - const uint32_t message_type = message->type(); - const int32_t message_routing_id = message->routing_id(); - if (!Send(message)) { - message = NULL; - DVLOG(1) << "Sending of message type " << message_type - << " failed. Dropping channel."; - DeleteWebSocketHost(message_routing_id); - return WEBSOCKET_HOST_DELETED; - } - return WEBSOCKET_HOST_ALIVE; -} - -WebSocketHostState WebSocketDispatcherHost::SendAddChannelResponse( - int routing_id, - const std::string& selected_protocol, - const std::string& extensions) { - // Update throttling counters (success). - WebSocketHost* host = GetHost(routing_id); - DCHECK(host); - host->OnHandshakeSucceeded(); - --num_pending_connections_; - DCHECK_GE(num_pending_connections_, 0); - ++num_current_succeeded_connections_; - - return SendOrDrop(new WebSocketMsg_AddChannelResponse( - routing_id, selected_protocol, extensions)); -} - -WebSocketHostState WebSocketDispatcherHost::SendFrame( - int routing_id, - bool fin, - WebSocketMessageType type, - const std::vector<char>& data) { - return SendOrDrop(new WebSocketMsg_SendFrame(routing_id, fin, type, data)); -} - -WebSocketHostState WebSocketDispatcherHost::SendFlowControl(int routing_id, - int64_t quota) { - return SendOrDrop(new WebSocketMsg_FlowControl(routing_id, quota)); -} - -WebSocketHostState WebSocketDispatcherHost::NotifyClosingHandshake( - int routing_id) { - return SendOrDrop(new WebSocketMsg_NotifyClosing(routing_id)); -} - -WebSocketHostState WebSocketDispatcherHost::NotifyStartOpeningHandshake( - int routing_id, const WebSocketHandshakeRequest& request) { - return SendOrDrop(new WebSocketMsg_NotifyStartOpeningHandshake( - routing_id, request)); -} - -WebSocketHostState WebSocketDispatcherHost::NotifyFinishOpeningHandshake( - int routing_id, const WebSocketHandshakeResponse& response) { - return SendOrDrop(new WebSocketMsg_NotifyFinishOpeningHandshake( - routing_id, response)); -} - -WebSocketHostState WebSocketDispatcherHost::NotifyFailure( - int routing_id, - const std::string& message) { - if (SendOrDrop(new WebSocketMsg_NotifyFailure( - routing_id, message)) == WEBSOCKET_HOST_DELETED) { - return WEBSOCKET_HOST_DELETED; - } - DeleteWebSocketHost(routing_id); - return WEBSOCKET_HOST_DELETED; -} - -WebSocketHostState WebSocketDispatcherHost::BlobSendComplete(int routing_id) { - return SendOrDrop(new WebSocketMsg_BlobSendComplete(routing_id)); -} - -WebSocketHostState WebSocketDispatcherHost::DoDropChannel( - int routing_id, - bool was_clean, - uint16_t code, - const std::string& reason) { - if (SendOrDrop( - new WebSocketMsg_DropChannel(routing_id, was_clean, code, reason)) == - WEBSOCKET_HOST_DELETED) - return WEBSOCKET_HOST_DELETED; - DeleteWebSocketHost(routing_id); - return WEBSOCKET_HOST_DELETED; -} - -WebSocketDispatcherHost::~WebSocketDispatcherHost() { - std::vector<WebSocketHost*> hosts; - for (base::hash_map<int, WebSocketHost*>::const_iterator i = hosts_.begin(); - i != hosts_.end(); ++i) { - // In order to avoid changing the container while iterating, we copy - // the hosts. - hosts.push_back(i->second); - } - - for (size_t i = 0; i < hosts.size(); ++i) { - // Note that some calls to GoAway could fail. In that case hosts[i] will be - // deleted and removed from |hosts_| in |DoDropChannel|. - hosts[i]->GoAway(); - hosts[i] = NULL; - } - - STLDeleteContainerPairSecondPointers(hosts_.begin(), hosts_.end()); -} - -void WebSocketDispatcherHost::DeleteWebSocketHost(int routing_id) { - WebSocketHostTable::iterator it = hosts_.find(routing_id); - DCHECK(it != hosts_.end()); - DCHECK(it->second); - if (!it->second->handshake_succeeded()) { - // Update throttling counters (failure). - --num_pending_connections_; - DCHECK_GE(num_pending_connections_, 0); - ++num_current_failed_connections_; - } - - delete it->second; - hosts_.erase(it); - - DCHECK_LE(base::checked_cast<size_t>(num_pending_connections_), - hosts_.size()); -} - -int64_t WebSocketDispatcherHost::num_failed_connections() const { - return num_previous_failed_connections_ + - num_current_failed_connections_; -} - -int64_t WebSocketDispatcherHost::num_succeeded_connections() const { - return num_previous_succeeded_connections_ + - num_current_succeeded_connections_; -} - -// Calculate delay as described in -// the per-renderer WebSocket throttling design doc: -// https://docs.google.com/document/d/1aw2oN5PKfk-1gLnBrlv1OwLA8K3-ykM2ckwX2lubTg4/edit?usp=sharing -base::TimeDelta WebSocketDispatcherHost::CalculateDelay() const { - int64_t f = num_failed_connections(); - int64_t s = num_succeeded_connections(); - int p = num_pending_connections(); - return base::TimeDelta::FromMilliseconds( - base::RandInt(1000, 5000) * - (1 << std::min(p + f / (s + 1), INT64_C(16))) / 65536); -} - -void WebSocketDispatcherHost::ThrottlingPeriodTimerCallback() { - num_previous_failed_connections_ = num_current_failed_connections_; - num_current_failed_connections_ = 0; - - num_previous_succeeded_connections_ = num_current_succeeded_connections_; - num_current_succeeded_connections_ = 0; - - if (num_pending_connections_ == 0 && - num_previous_failed_connections_ == 0 && - num_previous_succeeded_connections_ == 0) { - throttling_period_timer_.Stop(); - } -} - -} // namespace content
diff --git a/content/browser/renderer_host/websocket_dispatcher_host.h b/content/browser/renderer_host/websocket_dispatcher_host.h deleted file mode 100644 index 5d5c804..0000000 --- a/content/browser/renderer_host/websocket_dispatcher_host.h +++ /dev/null
@@ -1,212 +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 CONTENT_BROWSER_RENDERER_HOST_WEBSOCKET_DISPATCHER_HOST_H_ -#define CONTENT_BROWSER_RENDERER_HOST_WEBSOCKET_DISPATCHER_HOST_H_ - -#include <stdint.h> -#include <string> -#include <vector> - -#include "base/callback.h" -#include "base/compiler_specific.h" -#include "base/containers/hash_tables.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/time/time.h" -#include "base/timer/timer.h" -#include "content/common/content_export.h" -#include "content/common/websocket.h" -#include "content/public/browser/browser_message_filter.h" - -namespace net { -class URLRequestContext; -} // namespace net - -namespace storage { -class BlobStorageContext; -} - -namespace content { - -class ChromeBlobStorageContext; -class StoragePartition; -struct WebSocketHandshakeRequest; -struct WebSocketHandshakeResponse; -class WebSocketHost; - -// Creates a WebSocketHost object for each WebSocket channel, and dispatches -// WebSocketMsg_* messages sent from renderer to the appropriate WebSocketHost. -class CONTENT_EXPORT WebSocketDispatcherHost : public BrowserMessageFilter { - public: - typedef base::Callback<net::URLRequestContext*()> GetRequestContextCallback; - - // Given a routing_id and delay, WebSocketHostFactory returns a new - // instance of WebSocketHost or its subclass. - typedef base::Callback<WebSocketHost*(int, base::TimeDelta)> - WebSocketHostFactory; - - // Return value for methods that may delete the WebSocketHost. This enum is - // binary-compatible with net::WebSocketEventInterface::ChannelState, to make - // conversion cheap. By using a separate enum including net/ header files can - // be avoided. - enum WebSocketHostState { - WEBSOCKET_HOST_ALIVE, - WEBSOCKET_HOST_DELETED - }; - - WebSocketDispatcherHost(int process_id, - const GetRequestContextCallback& get_context_callback, - ChromeBlobStorageContext* blob_storage_context, - StoragePartition* storage_partition); - - // BrowserMessageFilter: - bool OnMessageReceived(const IPC::Message& message) override; - - // The following methods are used by WebSocketHost::EventInterface to send - // IPCs from the browser to the renderer or child process. Any of them may - // return WEBSOCKET_HOST_DELETED and delete the WebSocketHost on failure, - // leading to the WebSocketChannel and EventInterface also being deleted. - - // Sends a WebSocketMsg_AddChannelResponse IPC. - WebSocketHostState SendAddChannelResponse( - int routing_id, - const std::string& selected_protocol, - const std::string& extensions) WARN_UNUSED_RESULT; - - // Sends a WebSocketMsg_SendFrame IPC. - WebSocketHostState SendFrame(int routing_id, - bool fin, - WebSocketMessageType type, - const std::vector<char>& data); - - // Sends a WebSocketMsg_FlowControl IPC. - WebSocketHostState SendFlowControl(int routing_id, - int64_t quota) WARN_UNUSED_RESULT; - - // Sends a WebSocketMsg_NotifyClosing IPC - WebSocketHostState NotifyClosingHandshake(int routing_id) WARN_UNUSED_RESULT; - - // Sends a WebSocketMsg_NotifyStartOpeningHandshake IPC. - WebSocketHostState NotifyStartOpeningHandshake( - int routing_id, - const WebSocketHandshakeRequest& request) WARN_UNUSED_RESULT; - - // Sends a WebSocketMsg_NotifyFinishOpeningHandshake IPC. - WebSocketHostState NotifyFinishOpeningHandshake( - int routing_id, - const WebSocketHandshakeResponse& response) WARN_UNUSED_RESULT; - - // Sends a WebSocketMsg_NotifyFailure IPC and deletes and unregisters the - // channel. - WebSocketHostState NotifyFailure( - int routing_id, - const std::string& message) WARN_UNUSED_RESULT; - - WebSocketHostState BlobSendComplete(int routing_id); - - // Sends a WebSocketMsg_DropChannel IPC and deletes and unregisters the - // channel. - WebSocketHostState DoDropChannel(int routing_id, - bool was_clean, - uint16_t code, - const std::string& reason) - WARN_UNUSED_RESULT; - - // Returns whether the associated renderer process can read raw cookies. - bool CanReadRawCookies() const; - - int render_process_id() const { return process_id_; } - - // Returns a BlobStorageContext associated with this object's render process. - // The pointer will be valid for as long this object is. - storage::BlobStorageContext* blob_storage_context() const; - - // Returns the StoragePartition associated with this render process. - StoragePartition* storage_partition() const { return storage_partition_; } - - protected: - // For testing. Specify a factory method that creates mock version of - // WebSocketHost. - WebSocketDispatcherHost(int process_id, - const GetRequestContextCallback& get_context_callback, - const WebSocketHostFactory& websocket_host_factory); - - int num_pending_connections() const { return num_pending_connections_; } - - // The number of handshakes that failed/succeeded in the current and - // previous time period, respectively. - int64_t num_failed_connections() const; - int64_t num_succeeded_connections() const; - - ~WebSocketDispatcherHost() override; - - private: - typedef base::hash_map<int, WebSocketHost*> WebSocketHostTable; - - WebSocketHost* CreateWebSocketHost(int routing_id, base::TimeDelta delay); - - // Looks up a WebSocketHost object by |routing_id|. Returns the object if one - // is found, or NULL otherwise. - WebSocketHost* GetHost(int routing_id) const; - - // Sends the passed in IPC::Message via the BrowserMessageFilter::Send() - // method. If sending the IPC fails, assumes that this connection is no - // longer useable, calls DeleteWebSocketHost(), and returns - // WEBSOCKET_HOST_DELETED. The behaviour is the same for all message types. - WebSocketHostState SendOrDrop(IPC::Message* message) WARN_UNUSED_RESULT; - - // Deletes the WebSocketHost object associated with the given |routing_id| and - // removes it from the |hosts_| table. - void DeleteWebSocketHost(int routing_id); - - // Calculates the delay for per-renderer WebSocket throttling. - base::TimeDelta CalculateDelay() const; - - // Rotates the counts of successful and failed connections for current - // and previous time periods. Called every two minutes while the counts - // are non-zero. - void ThrottlingPeriodTimerCallback(); - - // Table of WebSocketHost objects, owned by this object, indexed by - // routing_id. - WebSocketHostTable hosts_; - - // The the process ID of the associated renderer process. - const int process_id_; - - // A callback which returns the appropriate net::URLRequestContext for us to - // use. - GetRequestContextCallback get_context_callback_; - - WebSocketHostFactory websocket_host_factory_; - - // Timer and counters for per-renderer WebSocket throttling. - base::RepeatingTimer throttling_period_timer_; - - // The current number of pending connections. - int num_pending_connections_; - - // The number of handshakes that failed in the current and previous time - // period. - int64_t num_current_succeeded_connections_; - int64_t num_previous_succeeded_connections_; - - // The number of handshakes that succeeded in the current and previous time - // period. - int64_t num_current_failed_connections_; - int64_t num_previous_failed_connections_; - - // Needed to read from blobs for browser-side blob sending. - const scoped_refptr<const ChromeBlobStorageContext> blob_storage_context_; - - // Needed to access to the StoragePartition for browser-side blob sending. - StoragePartition* const storage_partition_; - - DISALLOW_COPY_AND_ASSIGN(WebSocketDispatcherHost); -}; - -} // namespace content - -#endif // CONTENT_BROWSER_RENDERER_HOST_WEBSOCKET_DISPATCHER_HOST_H_
diff --git a/content/browser/renderer_host/websocket_dispatcher_host_unittest.cc b/content/browser/renderer_host/websocket_dispatcher_host_unittest.cc deleted file mode 100644 index 4fd1f5c..0000000 --- a/content/browser/renderer_host/websocket_dispatcher_host_unittest.cc +++ /dev/null
@@ -1,468 +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 "content/browser/renderer_host/websocket_dispatcher_host.h" - -#include <algorithm> -#include <vector> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "base/message_loop/message_loop.h" -#include "content/browser/renderer_host/websocket_host.h" -#include "content/common/websocket.h" -#include "content/common/websocket_messages.h" -#include "ipc/ipc_message.h" -#include "net/websockets/websocket_errors.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "url/gurl.h" -#include "url/origin.h" - -namespace content { -namespace { - -// This number is unlikely to occur by chance. -static const int kMagicRenderProcessId = 506116062; - -class WebSocketDispatcherHostTest; - -// A mock of WebsocketHost which records received messages. -class MockWebSocketHost : public WebSocketHost { - public: - MockWebSocketHost(int routing_id, - WebSocketDispatcherHost* dispatcher, - net::URLRequestContext* url_request_context, - base::TimeDelta delay, - WebSocketDispatcherHostTest* owner); - - ~MockWebSocketHost() override {} - - bool OnMessageReceived(const IPC::Message& message) override { - received_messages_.push_back(message); - switch (message.type()) { - case WebSocketMsg_DropChannel::ID: - // Needed for PerRendererThrottlingFailedHandshakes, because without - // calling WebSocketHost::OnMessageReceived() (and thus - // WebSocketHost::OnDropChannel()), the connection stays pending and - // we cannot test per-renderer throttling with failed connections. - return WebSocketHost::OnMessageReceived(message); - - default: - return true; - } - } - - void GoAway() override; - - std::vector<IPC::Message> received_messages_; - base::WeakPtr<WebSocketDispatcherHostTest> owner_; - base::TimeDelta delay_; -}; - -class TestingWebSocketDispatcherHost : public WebSocketDispatcherHost { - public: - TestingWebSocketDispatcherHost( - int process_id, - const GetRequestContextCallback& get_context_callback, - const WebSocketHostFactory& websocket_host_factory) - : WebSocketDispatcherHost(process_id, - get_context_callback, - websocket_host_factory) {} - - // This is needed because BrowserMessageFilter::Send() tries post the task to - // the IO thread, which doesn't exist in the context of these tests. - bool Send(IPC::Message* message) override { - delete message; - return true; - } - - using WebSocketDispatcherHost::num_pending_connections; - using WebSocketDispatcherHost::num_failed_connections; - using WebSocketDispatcherHost::num_succeeded_connections; - - private: - ~TestingWebSocketDispatcherHost() override {} -}; - -class WebSocketDispatcherHostTest : public ::testing::Test { - public: - WebSocketDispatcherHostTest() - : next_routing_id_(123), - weak_ptr_factory_(this) { - dispatcher_host_ = new TestingWebSocketDispatcherHost( - kMagicRenderProcessId, - base::Bind(&WebSocketDispatcherHostTest::OnGetRequestContext, - base::Unretained(this)), - base::Bind(&WebSocketDispatcherHostTest::CreateWebSocketHost, - base::Unretained(this))); - } - - ~WebSocketDispatcherHostTest() override { - // We need to invalidate the issued WeakPtrs at the beginning of the - // destructor in order not to access destructed member variables. - weak_ptr_factory_.InvalidateWeakPtrs(); - } - - void GoAway(int routing_id) { - gone_hosts_.push_back(routing_id); - } - - base::WeakPtr<WebSocketDispatcherHostTest> GetWeakPtr() { - return weak_ptr_factory_.GetWeakPtr(); - } - - protected: - // Adds |n| connections. Returns true if succeeded. - bool AddMultipleChannels(int number_of_channels) { - for (int i = 0; i < number_of_channels; ++i) { - int routing_id = next_routing_id_++; - - WebSocketHostMsg_AddChannelRequest_Params params; - params.socket_url = GURL("ws://example.com/test"); - params.origin = url::Origin(GURL("http://example.com")); - params.first_party_for_cookies = GURL("http://example.com"); - params.user_agent_override = ""; - params.render_frame_id = -3; - - WebSocketHostMsg_AddChannelRequest message(routing_id, params); - if (!dispatcher_host_->OnMessageReceived(message)) - return false; - } - - return true; - } - - // Adds and cancels |n| connections. Returns true if succeeded. - bool AddAndCancelMultipleChannels(int number_of_channels) { - for (int i = 0; i < number_of_channels; ++i) { - int routing_id = next_routing_id_++; - - WebSocketHostMsg_AddChannelRequest_Params params; - params.socket_url = GURL("ws://example.com/test"); - params.origin = url::Origin(GURL("http://example.com")); - params.first_party_for_cookies = GURL("http://example.com"); - params.user_agent_override = ""; - params.render_frame_id = -3; - - WebSocketHostMsg_AddChannelRequest messageAddChannelRequest( - routing_id, params); - if (!dispatcher_host_->OnMessageReceived(messageAddChannelRequest)) - return false; - - WebSocketMsg_DropChannel messageDropChannel( - routing_id, false, net::kWebSocketErrorAbnormalClosure, ""); - if (!dispatcher_host_->OnMessageReceived(messageDropChannel)) - return false; - } - - return true; - } - - scoped_refptr<TestingWebSocketDispatcherHost> dispatcher_host_; - - // Stores allocated MockWebSocketHost instances. Doesn't take ownership of - // them. - std::vector<MockWebSocketHost*> mock_hosts_; - std::vector<int> gone_hosts_; - - private: - net::URLRequestContext* OnGetRequestContext() { - return NULL; - } - - WebSocketHost* CreateWebSocketHost(int routing_id, base::TimeDelta delay) { - MockWebSocketHost* host = new MockWebSocketHost( - routing_id, dispatcher_host_.get(), NULL, delay, this); - mock_hosts_.push_back(host); - return host; - } - - base::MessageLoop message_loop_; - - int next_routing_id_; - - base::WeakPtrFactory<WebSocketDispatcherHostTest> weak_ptr_factory_; -}; - -MockWebSocketHost::MockWebSocketHost( - int routing_id, - WebSocketDispatcherHost* dispatcher, - net::URLRequestContext* url_request_context, - base::TimeDelta delay, - WebSocketDispatcherHostTest* owner) - : WebSocketHost(routing_id, dispatcher, url_request_context, delay), - owner_(owner->GetWeakPtr()), - delay_(delay) {} - -void MockWebSocketHost::GoAway() { - if (owner_) - owner_->GoAway(routing_id()); -} - -TEST_F(WebSocketDispatcherHostTest, Construct) { - // Do nothing. -} - -TEST_F(WebSocketDispatcherHostTest, UnrelatedMessage) { - IPC::Message message; - EXPECT_FALSE(dispatcher_host_->OnMessageReceived(message)); -} - -TEST_F(WebSocketDispatcherHostTest, RenderProcessIdGetter) { - EXPECT_EQ(kMagicRenderProcessId, dispatcher_host_->render_process_id()); -} - -TEST_F(WebSocketDispatcherHostTest, AddChannelRequest) { - int routing_id = 123; - std::vector<std::string> requested_protocols; - requested_protocols.push_back("hello"); - - WebSocketHostMsg_AddChannelRequest_Params params; - params.socket_url = GURL("ws://example.com/test"); - params.requested_protocols = requested_protocols; - params.origin = url::Origin(GURL("http://example.com")); - params.first_party_for_cookies = GURL("http://example.com"); - params.user_agent_override = ""; - params.render_frame_id = -2; - - WebSocketHostMsg_AddChannelRequest message(routing_id, params); - - ASSERT_TRUE(dispatcher_host_->OnMessageReceived(message)); - - ASSERT_EQ(1U, mock_hosts_.size()); - MockWebSocketHost* host = mock_hosts_[0]; - - ASSERT_EQ(1U, host->received_messages_.size()); - const IPC::Message& forwarded_message = host->received_messages_[0]; - EXPECT_EQ(WebSocketHostMsg_AddChannelRequest::ID, forwarded_message.type()); - EXPECT_EQ(routing_id, forwarded_message.routing_id()); -} - -TEST_F(WebSocketDispatcherHostTest, SendFrameButNoHostYet) { - int routing_id = 123; - std::vector<char> data; - WebSocketMsg_SendFrame message( - routing_id, true, WEB_SOCKET_MESSAGE_TYPE_TEXT, data); - - // Expected to be ignored. - EXPECT_TRUE(dispatcher_host_->OnMessageReceived(message)); - - EXPECT_EQ(0U, mock_hosts_.size()); -} - -TEST_F(WebSocketDispatcherHostTest, SendFrame) { - int routing_id = 123; - - std::vector<std::string> requested_protocols; - requested_protocols.push_back("hello"); - - WebSocketHostMsg_AddChannelRequest_Params params; - params.socket_url = GURL("ws://example.com/test"); - params.requested_protocols = requested_protocols; - params.origin = url::Origin(GURL("http://example.com")); - params.first_party_for_cookies = GURL("http://example.com"); - params.user_agent_override = ""; - params.render_frame_id = -2; - - WebSocketHostMsg_AddChannelRequest add_channel_message(routing_id, params); - - ASSERT_TRUE(dispatcher_host_->OnMessageReceived(add_channel_message)); - - std::vector<char> data; - WebSocketMsg_SendFrame send_frame_message( - routing_id, true, WEB_SOCKET_MESSAGE_TYPE_TEXT, data); - - EXPECT_TRUE(dispatcher_host_->OnMessageReceived(send_frame_message)); - - ASSERT_EQ(1U, mock_hosts_.size()); - MockWebSocketHost* host = mock_hosts_[0]; - - ASSERT_EQ(2U, host->received_messages_.size()); - { - const IPC::Message& forwarded_message = host->received_messages_[0]; - EXPECT_EQ(WebSocketHostMsg_AddChannelRequest::ID, forwarded_message.type()); - EXPECT_EQ(routing_id, forwarded_message.routing_id()); - } - { - const IPC::Message& forwarded_message = host->received_messages_[1]; - EXPECT_EQ(WebSocketMsg_SendFrame::ID, forwarded_message.type()); - EXPECT_EQ(routing_id, forwarded_message.routing_id()); - } -} - -TEST_F(WebSocketDispatcherHostTest, Destruct) { - WebSocketHostMsg_AddChannelRequest_Params params1; - params1.socket_url = GURL("ws://example.com/test"); - params1.requested_protocols = std::vector<std::string>(); - params1.origin = url::Origin(GURL("http://example.com")); - params1.first_party_for_cookies = GURL("http://example.com"); - params1.user_agent_override = ""; - params1.render_frame_id = -1; - - WebSocketHostMsg_AddChannelRequest message1(123, params1); - - WebSocketHostMsg_AddChannelRequest_Params params2; - params2.socket_url = GURL("ws://example.com/test2"); - params2.requested_protocols = std::vector<std::string>(); - params2.origin = url::Origin(GURL("http://example.com")); - params2.first_party_for_cookies = GURL("http://example.com"); - params2.user_agent_override = ""; - params2.render_frame_id = -1; - - WebSocketHostMsg_AddChannelRequest message2(456, params2); - - ASSERT_TRUE(dispatcher_host_->OnMessageReceived(message1)); - ASSERT_TRUE(dispatcher_host_->OnMessageReceived(message2)); - - ASSERT_EQ(2u, mock_hosts_.size()); - - mock_hosts_.clear(); - dispatcher_host_ = NULL; - - ASSERT_EQ(2u, gone_hosts_.size()); - // The gone_hosts_ ordering is not predictable because it depends on the - // hash_map ordering. - std::sort(gone_hosts_.begin(), gone_hosts_.end()); - EXPECT_EQ(123, gone_hosts_[0]); - EXPECT_EQ(456, gone_hosts_[1]); -} - -TEST_F(WebSocketDispatcherHostTest, DelayFor4thPendingConnectionIsZero) { - ASSERT_TRUE(AddMultipleChannels(4)); - - EXPECT_EQ(4, dispatcher_host_->num_pending_connections()); - EXPECT_EQ(0, dispatcher_host_->num_failed_connections()); - EXPECT_EQ(0, dispatcher_host_->num_succeeded_connections()); - - ASSERT_EQ(4U, mock_hosts_.size()); - EXPECT_EQ(base::TimeDelta(), mock_hosts_[3]->delay_); -} - -TEST_F(WebSocketDispatcherHostTest, DelayFor8thPendingConnectionIsNonZero) { - ASSERT_TRUE(AddMultipleChannels(8)); - - EXPECT_EQ(8, dispatcher_host_->num_pending_connections()); - EXPECT_EQ(0, dispatcher_host_->num_failed_connections()); - EXPECT_EQ(0, dispatcher_host_->num_succeeded_connections()); - - ASSERT_EQ(8U, mock_hosts_.size()); - EXPECT_LT(base::TimeDelta(), mock_hosts_[7]->delay_); -} - -TEST_F(WebSocketDispatcherHostTest, DelayFor17thPendingConnection) { - ASSERT_TRUE(AddMultipleChannels(17)); - - EXPECT_EQ(17, dispatcher_host_->num_pending_connections()); - EXPECT_EQ(0, dispatcher_host_->num_failed_connections()); - EXPECT_EQ(0, dispatcher_host_->num_succeeded_connections()); - - ASSERT_EQ(17U, mock_hosts_.size()); - EXPECT_LE(base::TimeDelta::FromMilliseconds(1000), mock_hosts_[16]->delay_); - EXPECT_GE(base::TimeDelta::FromMilliseconds(5000), mock_hosts_[16]->delay_); -} - -// The 256th connection is rejected by per-renderer WebSocket throttling. -// This is not counted as a failure. -TEST_F(WebSocketDispatcherHostTest, Rejects256thPendingConnection) { - ASSERT_TRUE(AddMultipleChannels(256)); - - EXPECT_EQ(255, dispatcher_host_->num_pending_connections()); - EXPECT_EQ(0, dispatcher_host_->num_failed_connections()); - EXPECT_EQ(0, dispatcher_host_->num_succeeded_connections()); - - ASSERT_EQ(255U, mock_hosts_.size()); -} - -TEST_F(WebSocketDispatcherHostTest, DelayIsZeroAfter3FailedConnections) { - ASSERT_TRUE(AddAndCancelMultipleChannels(3)); - - EXPECT_EQ(0, dispatcher_host_->num_pending_connections()); - EXPECT_EQ(3, dispatcher_host_->num_failed_connections()); - EXPECT_EQ(0, dispatcher_host_->num_succeeded_connections()); - - ASSERT_TRUE(AddMultipleChannels(1)); - - ASSERT_EQ(4U, mock_hosts_.size()); - EXPECT_EQ(base::TimeDelta(), mock_hosts_[3]->delay_); -} - -TEST_F(WebSocketDispatcherHostTest, DelayIsNonZeroAfter7FailedConnections) { - ASSERT_TRUE(AddAndCancelMultipleChannels(7)); - - EXPECT_EQ(0, dispatcher_host_->num_pending_connections()); - EXPECT_EQ(7, dispatcher_host_->num_failed_connections()); - EXPECT_EQ(0, dispatcher_host_->num_succeeded_connections()); - - ASSERT_TRUE(AddMultipleChannels(1)); - - ASSERT_EQ(8U, mock_hosts_.size()); - EXPECT_LT(base::TimeDelta(), mock_hosts_[7]->delay_); -} - -TEST_F(WebSocketDispatcherHostTest, DelayAfter16FailedConnections) { - ASSERT_TRUE(AddAndCancelMultipleChannels(16)); - - EXPECT_EQ(0, dispatcher_host_->num_pending_connections()); - EXPECT_EQ(16, dispatcher_host_->num_failed_connections()); - EXPECT_EQ(0, dispatcher_host_->num_succeeded_connections()); - - ASSERT_TRUE(AddMultipleChannels(1)); - - ASSERT_EQ(17U, mock_hosts_.size()); - EXPECT_LE(base::TimeDelta::FromMilliseconds(1000), mock_hosts_[16]->delay_); - EXPECT_GE(base::TimeDelta::FromMilliseconds(5000), mock_hosts_[16]->delay_); -} - -TEST_F(WebSocketDispatcherHostTest, NotRejectedAfter255FailedConnections) { - ASSERT_TRUE(AddAndCancelMultipleChannels(255)); - - EXPECT_EQ(0, dispatcher_host_->num_pending_connections()); - EXPECT_EQ(255, dispatcher_host_->num_failed_connections()); - EXPECT_EQ(0, dispatcher_host_->num_succeeded_connections()); - - ASSERT_TRUE(AddMultipleChannels(1)); - - EXPECT_EQ(1, dispatcher_host_->num_pending_connections()); - EXPECT_EQ(255, dispatcher_host_->num_failed_connections()); - EXPECT_EQ(0, dispatcher_host_->num_succeeded_connections()); -} - -// This is a regression test for https://crrev.com/998173003/. -TEST_F(WebSocketDispatcherHostTest, InvalidScheme) { - int routing_id = 123; - - std::vector<std::string> requested_protocols; - requested_protocols.push_back("hello"); - - WebSocketHostMsg_AddChannelRequest_Params params; - params.socket_url = GURL("http://example.com/test"); - params.requested_protocols = requested_protocols; - params.origin = url::Origin(GURL("http://example.com")); - params.first_party_for_cookies = GURL("http://example.com"); - params.user_agent_override = ""; - params.render_frame_id = -2; - - WebSocketHostMsg_AddChannelRequest message(routing_id, params); - - ASSERT_TRUE(dispatcher_host_->OnMessageReceived(message)); - - ASSERT_EQ(1U, mock_hosts_.size()); - MockWebSocketHost* host = mock_hosts_[0]; - - // Tests that WebSocketHost::OnMessageReceived() doesn't cause a crash and - // the connection with an invalid scheme fails here. - // We call WebSocketHost::OnMessageReceived() here explicitly because - // MockWebSocketHost does not call WebSocketHost::OnMessageReceived() for - // WebSocketHostMsg_AddChannelRequest. - host->WebSocketHost::OnMessageReceived(message); - - EXPECT_EQ(0, dispatcher_host_->num_pending_connections()); - EXPECT_EQ(1, dispatcher_host_->num_failed_connections()); - EXPECT_EQ(0, dispatcher_host_->num_succeeded_connections()); -} - -} // namespace -} // namespace content
diff --git a/content/browser/renderer_host/websocket_host.cc b/content/browser/renderer_host/websocket_host.cc deleted file mode 100644 index 513789a..0000000 --- a/content/browser/renderer_host/websocket_host.cc +++ /dev/null
@@ -1,606 +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 "content/browser/renderer_host/websocket_host.h" - -#include <inttypes.h> - -#include <utility> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/location.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/single_thread_task_runner.h" -#include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" -#include "base/threading/thread_task_runner_handle.h" -#include "content/browser/bad_message.h" -#include "content/browser/renderer_host/websocket_blob_sender.h" -#include "content/browser/renderer_host/websocket_dispatcher_host.h" -#include "content/browser/ssl/ssl_error_handler.h" -#include "content/browser/ssl/ssl_manager.h" -#include "content/common/websocket_messages.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/browser/render_frame_host.h" -#include "content/public/browser/storage_partition.h" -#include "ipc/ipc_message_macros.h" -#include "net/base/net_errors.h" -#include "net/http/http_request_headers.h" -#include "net/http/http_response_headers.h" -#include "net/http/http_util.h" -#include "net/ssl/ssl_info.h" -#include "net/websockets/websocket_channel.h" -#include "net/websockets/websocket_errors.h" -#include "net/websockets/websocket_event_interface.h" -#include "net/websockets/websocket_frame.h" // for WebSocketFrameHeader::OpCode -#include "net/websockets/websocket_handshake_request_info.h" -#include "net/websockets/websocket_handshake_response_info.h" -#include "url/origin.h" - -namespace content { - -namespace { - -typedef net::WebSocketEventInterface::ChannelState ChannelState; - -// Convert a content::WebSocketMessageType to a -// net::WebSocketFrameHeader::OpCode -net::WebSocketFrameHeader::OpCode MessageTypeToOpCode( - WebSocketMessageType type) { - DCHECK(type == WEB_SOCKET_MESSAGE_TYPE_CONTINUATION || - type == WEB_SOCKET_MESSAGE_TYPE_TEXT || - type == WEB_SOCKET_MESSAGE_TYPE_BINARY); - typedef net::WebSocketFrameHeader::OpCode OpCode; - // These compile asserts verify that the same underlying values are used for - // both types, so we can simply cast between them. - static_assert(static_cast<OpCode>(WEB_SOCKET_MESSAGE_TYPE_CONTINUATION) == - net::WebSocketFrameHeader::kOpCodeContinuation, - "enum values must match for opcode continuation"); - static_assert(static_cast<OpCode>(WEB_SOCKET_MESSAGE_TYPE_TEXT) == - net::WebSocketFrameHeader::kOpCodeText, - "enum values must match for opcode text"); - static_assert(static_cast<OpCode>(WEB_SOCKET_MESSAGE_TYPE_BINARY) == - net::WebSocketFrameHeader::kOpCodeBinary, - "enum values must match for opcode binary"); - return static_cast<OpCode>(type); -} - -WebSocketMessageType OpCodeToMessageType( - net::WebSocketFrameHeader::OpCode opCode) { - DCHECK(opCode == net::WebSocketFrameHeader::kOpCodeContinuation || - opCode == net::WebSocketFrameHeader::kOpCodeText || - opCode == net::WebSocketFrameHeader::kOpCodeBinary); - // This cast is guaranteed valid by the static_assert() statements above. - return static_cast<WebSocketMessageType>(opCode); -} - -ChannelState StateCast(WebSocketDispatcherHost::WebSocketHostState host_state) { - const WebSocketDispatcherHost::WebSocketHostState WEBSOCKET_HOST_ALIVE = - WebSocketDispatcherHost::WEBSOCKET_HOST_ALIVE; - const WebSocketDispatcherHost::WebSocketHostState WEBSOCKET_HOST_DELETED = - WebSocketDispatcherHost::WEBSOCKET_HOST_DELETED; - - DCHECK(host_state == WEBSOCKET_HOST_ALIVE || - host_state == WEBSOCKET_HOST_DELETED); - // These compile asserts verify that we can get away with using static_cast<> - // for the conversion. - static_assert(static_cast<ChannelState>(WEBSOCKET_HOST_ALIVE) == - net::WebSocketEventInterface::CHANNEL_ALIVE, - "enum values must match for state_alive"); - static_assert(static_cast<ChannelState>(WEBSOCKET_HOST_DELETED) == - net::WebSocketEventInterface::CHANNEL_DELETED, - "enum values must match for state_deleted"); - return static_cast<ChannelState>(host_state); -} - -// Implementation of WebSocketBlobSender::Channel -class SendChannelImpl final : public WebSocketBlobSender::Channel { - public: - explicit SendChannelImpl(net::WebSocketChannel* channel) - : channel_(channel) {} - - // Implementation of WebSocketBlobSender::Channel - size_t GetSendQuota() const override { - return static_cast<size_t>(channel_->current_send_quota()); - } - - ChannelState SendFrame(bool fin, const std::vector<char>& data) override { - int opcode = first_frame_ ? net::WebSocketFrameHeader::kOpCodeBinary - : net::WebSocketFrameHeader::kOpCodeContinuation; - first_frame_ = false; - return channel_->SendFrame(fin, opcode, data); - } - - private: - net::WebSocketChannel* channel_; - bool first_frame_ = true; - - DISALLOW_COPY_AND_ASSIGN(SendChannelImpl); -}; - -} // namespace - -// Implementation of net::WebSocketEventInterface. Receives events from our -// WebSocketChannel object. Each event is translated to an IPC and sent to the -// renderer or child process via WebSocketDispatcherHost. -class WebSocketHost::WebSocketEventHandler final - : public net::WebSocketEventInterface { - public: - WebSocketEventHandler(WebSocketDispatcherHost* dispatcher, - WebSocketHost* host, - int routing_id, - int render_frame_id); - ~WebSocketEventHandler() override; - - // net::WebSocketEventInterface implementation - - ChannelState OnAddChannelResponse(const std::string& selected_subprotocol, - const std::string& extensions) override; - ChannelState OnDataFrame(bool fin, - WebSocketMessageType type, - const std::vector<char>& data) override; - ChannelState OnClosingHandshake() override; - ChannelState OnFlowControl(int64_t quota) override; - ChannelState OnDropChannel(bool was_clean, - uint16_t code, - const std::string& reason) override; - ChannelState OnFailChannel(const std::string& message) override; - ChannelState OnStartOpeningHandshake( - std::unique_ptr<net::WebSocketHandshakeRequestInfo> request) override; - ChannelState OnFinishOpeningHandshake( - std::unique_ptr<net::WebSocketHandshakeResponseInfo> response) override; - ChannelState OnSSLCertificateError( - std::unique_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> - callbacks, - const GURL& url, - const net::SSLInfo& ssl_info, - bool fatal) override; - - private: - class SSLErrorHandlerDelegate final : public SSLErrorHandler::Delegate { - public: - SSLErrorHandlerDelegate( - std::unique_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> - callbacks); - ~SSLErrorHandlerDelegate() override; - - base::WeakPtr<SSLErrorHandler::Delegate> GetWeakPtr(); - - // SSLErrorHandler::Delegate methods - void CancelSSLRequest(int error, const net::SSLInfo* ssl_info) override; - void ContinueSSLRequest() override; - - private: - std::unique_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks_; - base::WeakPtrFactory<SSLErrorHandlerDelegate> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(SSLErrorHandlerDelegate); - }; - - WebSocketDispatcherHost* const dispatcher_; - WebSocketHost* const host_; - const int routing_id_; - const int render_frame_id_; - std::unique_ptr<SSLErrorHandlerDelegate> ssl_error_handler_delegate_; - - DISALLOW_COPY_AND_ASSIGN(WebSocketEventHandler); -}; - -WebSocketHost::WebSocketEventHandler::WebSocketEventHandler( - WebSocketDispatcherHost* dispatcher, - WebSocketHost* host, - int routing_id, - int render_frame_id) - : dispatcher_(dispatcher), - host_(host), - routing_id_(routing_id), - render_frame_id_(render_frame_id) {} - -WebSocketHost::WebSocketEventHandler::~WebSocketEventHandler() { - DVLOG(1) << "WebSocketEventHandler destroyed routing_id=" << routing_id_; -} - -ChannelState WebSocketHost::WebSocketEventHandler::OnAddChannelResponse( - const std::string& selected_protocol, - const std::string& extensions) { - DVLOG(3) << "WebSocketEventHandler::OnAddChannelResponse" - << " routing_id=" << routing_id_ - << " selected_protocol=\"" << selected_protocol << "\"" - << " extensions=\"" << extensions << "\""; - - return StateCast(dispatcher_->SendAddChannelResponse( - routing_id_, selected_protocol, extensions)); -} - -ChannelState WebSocketHost::WebSocketEventHandler::OnDataFrame( - bool fin, - net::WebSocketFrameHeader::OpCode type, - const std::vector<char>& data) { - DVLOG(3) << "WebSocketEventHandler::OnDataFrame" - << " routing_id=" << routing_id_ << " fin=" << fin - << " type=" << type << " data is " << data.size() << " bytes"; - - return StateCast(dispatcher_->SendFrame(routing_id_, fin, - OpCodeToMessageType(type), data)); -} - -ChannelState WebSocketHost::WebSocketEventHandler::OnClosingHandshake() { - DVLOG(3) << "WebSocketEventHandler::OnClosingHandshake" - << " routing_id=" << routing_id_; - - return StateCast(dispatcher_->NotifyClosingHandshake(routing_id_)); -} - -ChannelState WebSocketHost::WebSocketEventHandler::OnFlowControl( - int64_t quota) { - DVLOG(3) << "WebSocketEventHandler::OnFlowControl" - << " routing_id=" << routing_id_ << " quota=" << quota; - - if (host_->blob_sender_) - host_->blob_sender_->OnNewSendQuota(); - return StateCast(dispatcher_->SendFlowControl(routing_id_, quota)); -} - -ChannelState WebSocketHost::WebSocketEventHandler::OnDropChannel( - bool was_clean, - uint16_t code, - const std::string& reason) { - DVLOG(3) << "WebSocketEventHandler::OnDropChannel" - << " routing_id=" << routing_id_ << " was_clean=" << was_clean - << " code=" << code << " reason=\"" << reason << "\""; - - return StateCast( - dispatcher_->DoDropChannel(routing_id_, was_clean, code, reason)); -} - -ChannelState WebSocketHost::WebSocketEventHandler::OnFailChannel( - const std::string& message) { - DVLOG(3) << "WebSocketEventHandler::OnFailChannel" - << " routing_id=" << routing_id_ << " message=\"" << message << "\""; - - return StateCast(dispatcher_->NotifyFailure(routing_id_, message)); -} - -ChannelState WebSocketHost::WebSocketEventHandler::OnStartOpeningHandshake( - std::unique_ptr<net::WebSocketHandshakeRequestInfo> request) { - bool should_send = dispatcher_->CanReadRawCookies(); - DVLOG(3) << "WebSocketEventHandler::OnStartOpeningHandshake " - << "should_send=" << should_send; - - if (!should_send) - return WebSocketEventInterface::CHANNEL_ALIVE; - - WebSocketHandshakeRequest request_to_pass; - request_to_pass.url.Swap(&request->url); - net::HttpRequestHeaders::Iterator it(request->headers); - while (it.GetNext()) - request_to_pass.headers.push_back(std::make_pair(it.name(), it.value())); - request_to_pass.headers_text = - base::StringPrintf("GET %s HTTP/1.1\r\n", - request_to_pass.url.spec().c_str()) + - request->headers.ToString(); - request_to_pass.request_time = request->request_time; - - return StateCast( - dispatcher_->NotifyStartOpeningHandshake(routing_id_, request_to_pass)); -} - -ChannelState WebSocketHost::WebSocketEventHandler::OnFinishOpeningHandshake( - std::unique_ptr<net::WebSocketHandshakeResponseInfo> response) { - bool should_send = dispatcher_->CanReadRawCookies(); - DVLOG(3) << "WebSocketEventHandler::OnFinishOpeningHandshake " - << "should_send=" << should_send; - - if (!should_send) - return WebSocketEventInterface::CHANNEL_ALIVE; - - WebSocketHandshakeResponse response_to_pass; - response_to_pass.url.Swap(&response->url); - response_to_pass.status_code = response->status_code; - response_to_pass.status_text.swap(response->status_text); - size_t iter = 0; - std::string name, value; - while (response->headers->EnumerateHeaderLines(&iter, &name, &value)) - response_to_pass.headers.push_back(std::make_pair(name, value)); - response_to_pass.headers_text = - net::HttpUtil::ConvertHeadersBackToHTTPResponse( - response->headers->raw_headers()); - response_to_pass.response_time = response->response_time; - - return StateCast( - dispatcher_->NotifyFinishOpeningHandshake(routing_id_, response_to_pass)); -} - -ChannelState WebSocketHost::WebSocketEventHandler::OnSSLCertificateError( - std::unique_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks, - const GURL& url, - const net::SSLInfo& ssl_info, - bool fatal) { - DVLOG(3) << "WebSocketEventHandler::OnSSLCertificateError" - << " routing_id=" << routing_id_ << " url=" << url.spec() - << " cert_status=" << ssl_info.cert_status << " fatal=" << fatal; - ssl_error_handler_delegate_.reset( - new SSLErrorHandlerDelegate(std::move(callbacks))); - SSLManager::OnSSLCertificateSubresourceError( - ssl_error_handler_delegate_->GetWeakPtr(), url, - dispatcher_->render_process_id(), render_frame_id_, ssl_info, fatal); - // The above method is always asynchronous. - return WebSocketEventInterface::CHANNEL_ALIVE; -} - -WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate:: - SSLErrorHandlerDelegate( - std::unique_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> - callbacks) - : callbacks_(std::move(callbacks)), weak_ptr_factory_(this) {} - -WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate:: - ~SSLErrorHandlerDelegate() {} - -base::WeakPtr<SSLErrorHandler::Delegate> -WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate::GetWeakPtr() { - return weak_ptr_factory_.GetWeakPtr(); -} - -void WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate:: - CancelSSLRequest(int error, const net::SSLInfo* ssl_info) { - DVLOG(3) << "SSLErrorHandlerDelegate::CancelSSLRequest" - << " error=" << error - << " cert_status=" << (ssl_info ? ssl_info->cert_status - : static_cast<net::CertStatus>(-1)); - callbacks_->CancelSSLRequest(error, ssl_info); -} - -void WebSocketHost::WebSocketEventHandler::SSLErrorHandlerDelegate:: - ContinueSSLRequest() { - DVLOG(3) << "SSLErrorHandlerDelegate::ContinueSSLRequest"; - callbacks_->ContinueSSLRequest(); -} - -WebSocketHost::WebSocketHost(int routing_id, - WebSocketDispatcherHost* dispatcher, - net::URLRequestContext* url_request_context, - base::TimeDelta delay) - : dispatcher_(dispatcher), - url_request_context_(url_request_context), - routing_id_(routing_id), - delay_(delay), - pending_flow_control_quota_(0), - handshake_succeeded_(false), - weak_ptr_factory_(this) { - DVLOG(1) << "WebSocketHost: created routing_id=" << routing_id; -} - -WebSocketHost::~WebSocketHost() {} - -void WebSocketHost::GoAway() { - OnDropChannel(false, static_cast<uint16_t>(net::kWebSocketErrorGoingAway), - ""); -} - -bool WebSocketHost::OnMessageReceived(const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(WebSocketHost, message) - IPC_MESSAGE_HANDLER(WebSocketHostMsg_AddChannelRequest, OnAddChannelRequest) - IPC_MESSAGE_HANDLER(WebSocketHostMsg_SendBlob, OnSendBlob) - IPC_MESSAGE_HANDLER(WebSocketMsg_SendFrame, OnSendFrame) - IPC_MESSAGE_HANDLER(WebSocketMsg_FlowControl, OnFlowControl) - IPC_MESSAGE_HANDLER(WebSocketMsg_DropChannel, OnDropChannel) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -void WebSocketHost::OnAddChannelRequest( - const WebSocketHostMsg_AddChannelRequest_Params& params) { - DVLOG(3) << "WebSocketHost::OnAddChannelRequest" - << " routing_id=" << routing_id_ << " socket_url=\"" - << params.socket_url << "\" requested_protocols=\"" - << base::JoinString(params.requested_protocols, ", ") - << "\" origin=\"" << params.origin - << "\" first_party_for_cookies=\"" - << params.first_party_for_cookies << "\" user_agent_override=\"" - << params.user_agent_override - << "\""; - - DCHECK(!channel_); - if (delay_ > base::TimeDelta()) { - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - base::Bind(&WebSocketHost::AddChannel, weak_ptr_factory_.GetWeakPtr(), - params.socket_url, params.requested_protocols, - params.origin, params.first_party_for_cookies, - params.user_agent_override, params.render_frame_id), - delay_); - } else { - AddChannel( - params.socket_url, params.requested_protocols, params.origin, - params.first_party_for_cookies, params.user_agent_override, - params.render_frame_id); - } - // |this| may have been deleted here. -} - -void WebSocketHost::AddChannel( - const GURL& socket_url, - const std::vector<std::string>& requested_protocols, - const url::Origin& origin, - const GURL& first_party_for_cookies, - const std::string& user_agent_override, - int render_frame_id) { - DVLOG(3) << "WebSocketHost::AddChannel" - << " routing_id=" << routing_id_ << " socket_url=\"" << socket_url - << "\" requested_protocols=\"" - << base::JoinString(requested_protocols, ", ") << "\" origin=\"" - << origin << "\" first_party_for_cookies=\"" - << first_party_for_cookies << "\" user_agent_override=\"" - << user_agent_override << "\""; - - DCHECK(!channel_); - - std::unique_ptr<net::WebSocketEventInterface> event_interface( - new WebSocketEventHandler(dispatcher_, this, routing_id_, - render_frame_id)); - channel_.reset(new net::WebSocketChannel(std::move(event_interface), - url_request_context_)); - - if (pending_flow_control_quota_ > 0) { - // channel_->SendFlowControl(pending_flow_control_quota_) must be called - // after channel_->SendAddChannelRequest() below. - // We post OnFlowControl() here using |weak_ptr_factory_| instead of - // calling SendFlowControl directly, because |this| may have been deleted - // after channel_->SendAddChannelRequest(). - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&WebSocketHost::OnFlowControl, - weak_ptr_factory_.GetWeakPtr(), - pending_flow_control_quota_)); - pending_flow_control_quota_ = 0; - } - - std::string additional_headers; - if (user_agent_override != "") { - if (!net::HttpUtil::IsValidHeaderValue(user_agent_override)) { - bad_message::ReceivedBadMessage( - dispatcher_, bad_message::WSH_INVALID_HEADER_VALUE); - return; - } - additional_headers = base::StringPrintf("%s:%s", - net::HttpRequestHeaders::kUserAgent, - user_agent_override.c_str()); - } - channel_->SendAddChannelRequest( - socket_url, requested_protocols, origin, first_party_for_cookies, - additional_headers); - // |this| may have been deleted here. -} - -void WebSocketHost::OnSendBlob(const std::string& uuid, - uint64_t expected_size) { - DVLOG(3) << "WebSocketHost::OnSendBlob" - << " routing_id=" << routing_id_ << " uuid=" << uuid - << " expected_size=" << expected_size; - - DCHECK(channel_); - if (blob_sender_) { - bad_message::ReceivedBadMessage( - dispatcher_, bad_message::WSH_SEND_BLOB_DURING_BLOB_SEND); - return; - } - blob_sender_.reset(new WebSocketBlobSender( - base::WrapUnique(new SendChannelImpl(channel_.get())))); - StoragePartition* partition = dispatcher_->storage_partition(); - storage::FileSystemContext* file_system_context = - partition->GetFileSystemContext(); - - net::WebSocketEventInterface::ChannelState channel_state = - net::WebSocketEventInterface::CHANNEL_ALIVE; - - // This use of base::Unretained is safe because the WebSocketBlobSender object - // is owned by this object and will not call it back after destruction. - int rv = blob_sender_->Start( - uuid, expected_size, dispatcher_->blob_storage_context(), - file_system_context, - BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE).get(), - &channel_state, - base::Bind(&WebSocketHost::BlobSendComplete, base::Unretained(this))); - if (channel_state == net::WebSocketEventInterface::CHANNEL_ALIVE && - rv != net::ERR_IO_PENDING) - BlobSendComplete(rv); - // |this| may be destroyed here. -} - -void WebSocketHost::OnSendFrame(bool fin, - WebSocketMessageType type, - const std::vector<char>& data) { - DVLOG(3) << "WebSocketHost::OnSendFrame" - << " routing_id=" << routing_id_ << " fin=" << fin - << " type=" << type << " data is " << data.size() << " bytes"; - - DCHECK(channel_); - if (blob_sender_) { - bad_message::ReceivedBadMessage( - dispatcher_, bad_message::WSH_SEND_FRAME_DURING_BLOB_SEND); - return; - } - channel_->SendFrame(fin, MessageTypeToOpCode(type), data); -} - -void WebSocketHost::OnFlowControl(int64_t quota) { - DVLOG(3) << "WebSocketHost::OnFlowControl" - << " routing_id=" << routing_id_ << " quota=" << quota; - - if (!channel_) { - // WebSocketChannel is not yet created due to the delay introduced by - // per-renderer WebSocket throttling. - // SendFlowControl() is called after WebSocketChannel is created. - pending_flow_control_quota_ += quota; - return; - } - - ignore_result(channel_->SendFlowControl(quota)); -} - -void WebSocketHost::OnDropChannel(bool was_clean, - uint16_t code, - const std::string& reason) { - DVLOG(3) << "WebSocketHost::OnDropChannel" - << " routing_id=" << routing_id_ << " was_clean=" << was_clean - << " code=" << code << " reason=\"" << reason << "\""; - - if (!channel_) { - // WebSocketChannel is not yet created due to the delay introduced by - // per-renderer WebSocket throttling. - WebSocketDispatcherHost::WebSocketHostState result = - dispatcher_->DoDropChannel(routing_id_, false, - net::kWebSocketErrorAbnormalClosure, ""); - DCHECK_EQ(WebSocketDispatcherHost::WEBSOCKET_HOST_DELETED, result); - return; - } - - blob_sender_.reset(); - // TODO(yhirano): Handle |was_clean| appropriately. - ignore_result(channel_->StartClosingHandshake(code, reason)); -} - -void WebSocketHost::BlobSendComplete(int result) { - DVLOG(3) << "WebSocketHost::BlobSendComplete" - << " routing_id=" << routing_id_ - << " result=" << net::ErrorToString(result); - - // All paths through this method must reset blob_sender_, so take ownership - // at the beginning. - std::unique_ptr<WebSocketBlobSender> blob_sender(std::move(blob_sender_)); - switch (result) { - case net::OK: - ignore_result(dispatcher_->BlobSendComplete(routing_id_)); - // |this| may be destroyed here. - return; - - case net::ERR_UPLOAD_FILE_CHANGED: { - uint64_t expected_size = blob_sender->expected_size(); - uint64_t actual_size = blob_sender->ActualSize(); - if (expected_size != actual_size) { - ignore_result(dispatcher_->NotifyFailure( - routing_id_, - base::StringPrintf("Blob size mismatch; renderer size = %" PRIu64 - ", browser size = %" PRIu64, - expected_size, actual_size))); - // |this| is destroyed here. - return; - } // else fallthrough - } - - default: - ignore_result(dispatcher_->NotifyFailure( - routing_id_, - "Failed to load Blob: error code = " + net::ErrorToString(result))); - // |this| is destroyed here. - return; - } -} - -} // namespace content
diff --git a/content/browser/renderer_host/websocket_host.h b/content/browser/renderer_host/websocket_host.h deleted file mode 100644 index 3488ef0..0000000 --- a/content/browser/renderer_host/websocket_host.h +++ /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. - -#ifndef CONTENT_BROWSER_RENDERER_HOST_WEBSOCKET_HOST_H_ -#define CONTENT_BROWSER_RENDERER_HOST_WEBSOCKET_HOST_H_ - -#include <stdint.h> - -#include <memory> -#include <string> -#include <vector> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/time/time.h" -#include "content/common/content_export.h" -#include "content/common/websocket.h" - -class GURL; -struct WebSocketHostMsg_AddChannelRequest_Params; - -namespace url { -class Origin; -} // namespace url - -namespace net { -class WebSocketChannel; -class URLRequestContext; -} // namespace net - -namespace IPC { -class Message; -} // namespace IPC - -namespace content { - -class WebSocketBlobSender; -class WebSocketDispatcherHost; - -// Host of net::WebSocketChannel. The lifetime of an instance of this class is -// completely controlled by the WebSocketDispatcherHost object. -class CONTENT_EXPORT WebSocketHost { - public: - WebSocketHost(int routing_id, - WebSocketDispatcherHost* dispatcher, - net::URLRequestContext* url_request_context, - base::TimeDelta delay); - virtual ~WebSocketHost(); - - // The renderer process is going away. - // This function is virtual for testing. - virtual void GoAway(); - - // General message dispatch. WebSocketDispatcherHost::OnMessageReceived - // delegates to this method after looking up the |routing_id|. - virtual bool OnMessageReceived(const IPC::Message& message); - - int routing_id() const { return routing_id_; } - - bool handshake_succeeded() const { return handshake_succeeded_; } - void OnHandshakeSucceeded() { handshake_succeeded_ = true; } - - private: - class WebSocketEventHandler; - - // Handlers for each message type, dispatched by OnMessageReceived(), as - // defined in content/common/websocket_messages.h - - void OnAddChannelRequest( - const WebSocketHostMsg_AddChannelRequest_Params& request); - - void AddChannel(const GURL& socket_url, - const std::vector<std::string>& requested_protocols, - const url::Origin& origin, - const GURL& first_party_for_cookies, - const std::string& user_agent_override, - int render_frame_id); - - void OnSendBlob(const std::string& uuid, uint64_t expected_size); - - void OnSendFrame(bool fin, - WebSocketMessageType type, - const std::vector<char>& data); - - void OnFlowControl(int64_t quota); - - void OnDropChannel(bool was_clean, uint16_t code, const std::string& reason); - - void BlobSendComplete(int result); - - // non-NULL if and only if this object is currently in "blob sending mode". - std::unique_ptr<WebSocketBlobSender> blob_sender_; - - // The channel we use to send events to the network. - std::unique_ptr<net::WebSocketChannel> channel_; - - // The WebSocketHostDispatcher that created this object. - WebSocketDispatcherHost* const dispatcher_; - - // The URL request context for the channel. - net::URLRequestContext* const url_request_context_; - - // The ID used to route messages. - const int routing_id_; - - // Delay used for per-renderer WebSocket throttling. - base::TimeDelta delay_; - - // SendFlowControl() is delayed when OnFlowControl() is called before - // AddChannel() is called. - // Zero indicates there is no pending SendFlowControl(). - int64_t pending_flow_control_quota_; - - // handshake_succeeded_ is set and used by WebSocketDispatcherHost - // to manage counters for per-renderer WebSocket throttling. - bool handshake_succeeded_; - - base::WeakPtrFactory<WebSocketHost> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(WebSocketHost); -}; - -} // namespace content - -#endif // CONTENT_BROWSER_RENDERER_HOST_WEBSOCKET_HOST_H_
diff --git a/content/browser/service_worker/embedded_worker_registry.cc b/content/browser/service_worker/embedded_worker_registry.cc index 2887a514..51d3c2c 100644 --- a/content/browser/service_worker/embedded_worker_registry.cc +++ b/content/browser/service_worker/embedded_worker_registry.cc
@@ -134,8 +134,8 @@ if (!worker) return; - if (!ContainsKey(worker_process_map_, process_id) || - !ContainsKey(worker_process_map_[process_id], embedded_worker_id)) { + if (!base::ContainsKey(worker_process_map_, process_id) || + !base::ContainsKey(worker_process_map_[process_id], embedded_worker_id)) { return; } @@ -186,7 +186,7 @@ process_sender_map_[process_id] = sender; process_message_port_message_filter_map_[process_id] = message_port_message_filter; - DCHECK(!ContainsKey(worker_process_map_, process_id)); + DCHECK(!base::ContainsKey(worker_process_map_, process_id)); } void EmbeddedWorkerRegistry::RemoveChildProcessSender(int process_id) { @@ -200,7 +200,7 @@ it != worker_set.end(); ++it) { int embedded_worker_id = *it; - DCHECK(ContainsKey(worker_map_, embedded_worker_id)); + DCHECK(base::ContainsKey(worker_map_, embedded_worker_id)); // Somehow the worker thread has lost contact with the browser process. // The renderer may have been killed. Set the worker's status to STOPPED // so a new thread can be created for this version. Use OnDetached rather @@ -253,13 +253,14 @@ // The ServiceWorkerDispatcherHost is supposed to be created when the process // is created, and keep an entry in process_sender_map_ for its whole // lifetime. - DCHECK(ContainsKey(process_sender_map_, process_id)); + DCHECK(base::ContainsKey(process_sender_map_, process_id)); int embedded_worker_id = params->embedded_worker_id; DCHECK(GetWorker(embedded_worker_id)); DCHECK_EQ(GetWorker(embedded_worker_id)->process_id(), process_id); - DCHECK(!ContainsKey(worker_process_map_, process_id) || - !ContainsKey(worker_process_map_[process_id], embedded_worker_id)); + DCHECK( + !base::ContainsKey(worker_process_map_, process_id) || + !base::ContainsKey(worker_process_map_[process_id], embedded_worker_id)); ServiceWorkerStatusCode status = Send(process_id, new EmbeddedWorkerMsg_StartWorker(*params)); @@ -283,9 +284,9 @@ void EmbeddedWorkerRegistry::RemoveWorker(int process_id, int embedded_worker_id) { - DCHECK(ContainsKey(worker_map_, embedded_worker_id)); + DCHECK(base::ContainsKey(worker_map_, embedded_worker_id)); worker_map_.erase(embedded_worker_id); - if (!ContainsKey(worker_process_map_, process_id)) + if (!base::ContainsKey(worker_process_map_, process_id)) return; worker_process_map_[process_id].erase(embedded_worker_id); if (worker_process_map_[process_id].empty())
diff --git a/content/browser/service_worker/foreign_fetch_request_handler.cc b/content/browser/service_worker/foreign_fetch_request_handler.cc index ac99dffe..b4df605c 100644 --- a/content/browser/service_worker/foreign_fetch_request_handler.cc +++ b/content/browser/service_worker/foreign_fetch_request_handler.cc
@@ -6,12 +6,16 @@ #include <string> +#include "base/command_line.h" #include "base/macros.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/service_worker/service_worker_response_info.h" #include "content/browser/service_worker/service_worker_url_request_job.h" #include "content/common/resource_request_body_impl.h" #include "content/common/service_worker/service_worker_utils.h" +#include "content/public/common/content_client.h" +#include "content/public/common/content_switches.h" +#include "content/public/common/origin_trial_policy.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_interceptor.h" #include "storage/browser/blob/blob_storage_context.h" @@ -45,6 +49,17 @@ } // namespace +bool ForeignFetchRequestHandler::IsForeignFetchEnabled() { + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableExperimentalWebPlatformFeatures)) { + return true; + } + OriginTrialPolicy* origin_trial_policy = + GetContentClient()->GetOriginTrialPolicy(); + return origin_trial_policy && + !origin_trial_policy->IsFeatureDisabled("ForeignFetch"); +} + void ForeignFetchRequestHandler::InitializeHandler( net::URLRequest* request, ServiceWorkerContextWrapper* context_wrapper, @@ -60,6 +75,9 @@ RequestContextFrameType frame_type, scoped_refptr<ResourceRequestBodyImpl> body, bool initiated_in_secure_context) { + if (!IsForeignFetchEnabled()) + return; + if (!context_wrapper) return;
diff --git a/content/browser/service_worker/foreign_fetch_request_handler.h b/content/browser/service_worker/foreign_fetch_request_handler.h index 47d0fde..5968f10 100644 --- a/content/browser/service_worker/foreign_fetch_request_handler.h +++ b/content/browser/service_worker/foreign_fetch_request_handler.h
@@ -46,6 +46,12 @@ : public base::SupportsUserData::Data, public ServiceWorkerURLRequestJob::Delegate { public: + // Returns true if Foreign Fetch is enabled. Foreign Fetch is considered to be + // enabled if an OriginTrialPolicy exists, and that policy doesn't disable the + // feature. When the policy does disable the feature, that can be overridden + // with the experimental web platform features command line flag. + static bool IsForeignFetchEnabled(); + // Attaches a newly created handler if the given |request| needs to // be handled by a foreign fetch handling ServiceWorker. static void InitializeHandler(
diff --git a/content/browser/service_worker/link_header_support.cc b/content/browser/service_worker/link_header_support.cc index 92b2d31..6a8df7c 100644 --- a/content/browser/service_worker/link_header_support.cc +++ b/content/browser/service_worker/link_header_support.cc
@@ -12,6 +12,7 @@ #include "content/browser/loader/resource_request_info_impl.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/service_worker/service_worker_request_handler.h" +#include "content/common/origin_trials/trial_token_validator.h" #include "content/common/service_worker/service_worker_utils.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" @@ -39,8 +40,9 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableExperimentalWebPlatformFeatures)) { - // TODO(mek): Integrate with experimental framework. + switches::kEnableExperimentalWebPlatformFeatures) && + !TrialTokenValidator::RequestEnablesFeature(request, "ForeignFetch")) { + // TODO(mek): Log attempt to use without having correct token? return; }
diff --git a/content/browser/service_worker/service_worker_browsertest.cc b/content/browser/service_worker/service_worker_browsertest.cc index 8018c03..5a1100d 100644 --- a/content/browser/service_worker/service_worker_browsertest.cc +++ b/content/browser/service_worker/service_worker_browsertest.cc
@@ -38,6 +38,7 @@ #include "content/browser/service_worker/service_worker_registration.h" #include "content/browser/service_worker/service_worker_test_utils.h" #include "content/browser/service_worker/service_worker_version.h" +#include "content/browser/web_contents/web_contents_impl.h" #include "content/common/service_worker/service_worker_messages.h" #include "content/common/service_worker/service_worker_status_code.h" #include "content/common/service_worker/service_worker_types.h" @@ -1375,7 +1376,8 @@ TitleWatcher title_watcher(shell()->web_contents(), title); NavigateToURL(shell(), https_server.GetURL(kPageUrl)); EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); - EXPECT_FALSE(shell()->web_contents()->DisplayedInsecureContent()); + EXPECT_FALSE(static_cast<WebContentsImpl*>(shell()->web_contents()) + ->DisplayedInsecureContent()); NavigationEntry* entry = shell()->web_contents()->GetController().GetVisibleEntry(); EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, entry->GetSSL().security_style); @@ -1406,7 +1408,8 @@ TitleWatcher title_watcher(shell()->web_contents(), title); NavigateToURL(shell(), embedded_test_server()->GetURL(kPageUrl)); EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); - EXPECT_FALSE(shell()->web_contents()->DisplayedInsecureContent()); + EXPECT_FALSE(static_cast<WebContentsImpl*>(shell()->web_contents()) + ->DisplayedInsecureContent()); NavigationEntry* entry = shell()->web_contents()->GetController().GetVisibleEntry(); EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, entry->GetSSL().security_style);
diff --git a/content/browser/service_worker/service_worker_context_core_unittest.cc b/content/browser/service_worker/service_worker_context_core_unittest.cc index 25f38ec..d5b50705 100644 --- a/content/browser/service_worker/service_worker_context_core_unittest.cc +++ b/content/browser/service_worker/service_worker_context_core_unittest.cc
@@ -55,7 +55,7 @@ context()->UpdateVersionFailureCount(kVersionId, SERVICE_WORKER_OK); EXPECT_EQ(0, context()->GetVersionFailureCount(kVersionId)); - EXPECT_FALSE(ContainsKey(context()->failure_counts_, kVersionId)); + EXPECT_FALSE(base::ContainsKey(context()->failure_counts_, kVersionId)); } } // namespace content
diff --git a/content/browser/service_worker/service_worker_database.cc b/content/browser/service_worker/service_worker_database.cc index a7923bc..61eec0b9 100644 --- a/content/browser/service_worker/service_worker_database.cc +++ b/content/browser/service_worker/service_worker_database.cc
@@ -117,8 +117,7 @@ class ServiceWorkerEnv : public leveldb_env::ChromiumEnv { public: - ServiceWorkerEnv() - : ChromiumEnv("LevelDBEnv.ServiceWorker", false /* make_backup */) {} + ServiceWorkerEnv() : ChromiumEnv("LevelDBEnv.ServiceWorker") {} }; base::LazyInstance<ServiceWorkerEnv>::Leaky g_service_worker_env =
diff --git a/content/browser/service_worker/service_worker_database_unittest.cc b/content/browser/service_worker/service_worker_database_unittest.cc index 39190547..3fd3778 100644 --- a/content/browser/service_worker/service_worker_database_unittest.cc +++ b/content/browser/service_worker/service_worker_database_unittest.cc
@@ -393,9 +393,9 @@ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetOriginsWithRegistrations(&origins)); EXPECT_EQ(3U, origins.size()); - EXPECT_TRUE(ContainsKey(origins, origin1)); - EXPECT_TRUE(ContainsKey(origins, origin2)); - EXPECT_TRUE(ContainsKey(origins, origin3)); + EXPECT_TRUE(base::ContainsKey(origins, origin1)); + EXPECT_TRUE(base::ContainsKey(origins, origin2)); + EXPECT_TRUE(base::ContainsKey(origins, origin3)); // |origin3| has another registration, so should not remove it from the // unique origin list. @@ -410,9 +410,9 @@ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetOriginsWithRegistrations(&origins)); EXPECT_EQ(3U, origins.size()); - EXPECT_TRUE(ContainsKey(origins, origin1)); - EXPECT_TRUE(ContainsKey(origins, origin2)); - EXPECT_TRUE(ContainsKey(origins, origin3)); + EXPECT_TRUE(base::ContainsKey(origins, origin1)); + EXPECT_TRUE(base::ContainsKey(origins, origin2)); + EXPECT_TRUE(base::ContainsKey(origins, origin3)); // |origin3| should be removed from the unique origin list. ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK, @@ -426,8 +426,8 @@ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetOriginsWithRegistrations(&origins)); EXPECT_EQ(2U, origins.size()); - EXPECT_TRUE(ContainsKey(origins, origin1)); - EXPECT_TRUE(ContainsKey(origins, origin2)); + EXPECT_TRUE(base::ContainsKey(origins, origin1)); + EXPECT_TRUE(base::ContainsKey(origins, origin2)); } TEST(ServiceWorkerDatabaseTest, GetRegistrationsForOrigin) { @@ -695,8 +695,8 @@ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetPurgeableResourceIds(&purgeable_ids_out)); EXPECT_EQ(2u, purgeable_ids_out.size()); - EXPECT_TRUE(ContainsKey(purgeable_ids_out, resources[0].resource_id)); - EXPECT_TRUE(ContainsKey(purgeable_ids_out, resources[1].resource_id)); + EXPECT_TRUE(base::ContainsKey(purgeable_ids_out, resources[0].resource_id)); + EXPECT_TRUE(base::ContainsKey(purgeable_ids_out, resources[1].resource_id)); } TEST(ServiceWorkerDatabaseTest, DeleteNonExistentRegistration) { @@ -819,8 +819,8 @@ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetPurgeableResourceIds(&purgeable_ids_out)); EXPECT_EQ(2u, purgeable_ids_out.size()); - EXPECT_TRUE(ContainsKey(purgeable_ids_out, resources1[0].resource_id)); - EXPECT_TRUE(ContainsKey(purgeable_ids_out, resources1[1].resource_id)); + EXPECT_TRUE(base::ContainsKey(purgeable_ids_out, resources1[0].resource_id)); + EXPECT_TRUE(base::ContainsKey(purgeable_ids_out, resources1[1].resource_id)); } TEST(ServiceWorkerDatabaseTest, Registration_Multiple) { @@ -913,8 +913,8 @@ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetPurgeableResourceIds(&purgeable_ids_out)); EXPECT_EQ(2u, purgeable_ids_out.size()); - EXPECT_TRUE(ContainsKey(purgeable_ids_out, resources1[0].resource_id)); - EXPECT_TRUE(ContainsKey(purgeable_ids_out, resources1[1].resource_id)); + EXPECT_TRUE(base::ContainsKey(purgeable_ids_out, resources1[0].resource_id)); + EXPECT_TRUE(base::ContainsKey(purgeable_ids_out, resources1[1].resource_id)); // Make sure that registration2 is still alive. resources_out.clear(); @@ -1561,14 +1561,14 @@ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetOriginsWithRegistrations(&unique_origins)); EXPECT_EQ(1u, unique_origins.size()); - EXPECT_TRUE(ContainsKey(unique_origins, origin2)); + EXPECT_TRUE(base::ContainsKey(unique_origins, origin2)); // |origin1| should be removed from the foreign fetch origin list. unique_origins.clear(); EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetOriginsWithForeignFetchRegistrations(&unique_origins)); EXPECT_EQ(1u, unique_origins.size()); - EXPECT_TRUE(ContainsKey(unique_origins, origin2)); + EXPECT_TRUE(base::ContainsKey(unique_origins, origin2)); // The registrations for |origin1| should be removed. std::vector<RegistrationData> registrations; @@ -1598,10 +1598,10 @@ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetPurgeableResourceIds(&purgeable_ids_out)); EXPECT_EQ(4u, purgeable_ids_out.size()); - EXPECT_TRUE(ContainsKey(purgeable_ids_out, 1)); - EXPECT_TRUE(ContainsKey(purgeable_ids_out, 2)); - EXPECT_TRUE(ContainsKey(purgeable_ids_out, 3)); - EXPECT_TRUE(ContainsKey(purgeable_ids_out, 4)); + EXPECT_TRUE(base::ContainsKey(purgeable_ids_out, 1)); + EXPECT_TRUE(base::ContainsKey(purgeable_ids_out, 2)); + EXPECT_TRUE(base::ContainsKey(purgeable_ids_out, 3)); + EXPECT_TRUE(base::ContainsKey(purgeable_ids_out, 4)); // The user data associated with |origin1| should be removed. std::vector<std::string> user_data_out; @@ -1726,8 +1726,8 @@ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetOriginsWithForeignFetchRegistrations(&origins)); EXPECT_EQ(2U, origins.size()); - EXPECT_TRUE(ContainsKey(origins, origin1)); - EXPECT_TRUE(ContainsKey(origins, origin3)); + EXPECT_TRUE(base::ContainsKey(origins, origin1)); + EXPECT_TRUE(base::ContainsKey(origins, origin3)); // |origin3| has another registration, so should not remove it from the // foreign fetch origin list. @@ -1741,8 +1741,8 @@ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetOriginsWithForeignFetchRegistrations(&origins)); EXPECT_EQ(2U, origins.size()); - EXPECT_TRUE(ContainsKey(origins, origin1)); - EXPECT_TRUE(ContainsKey(origins, origin3)); + EXPECT_TRUE(base::ContainsKey(origins, origin1)); + EXPECT_TRUE(base::ContainsKey(origins, origin3)); // |origin3| should be removed from the foreign fetch origin list, since its // only remaining registration doesn't have foreign fetch scopes. @@ -1756,7 +1756,7 @@ EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK, database->GetOriginsWithForeignFetchRegistrations(&origins)); EXPECT_EQ(1U, origins.size()); - EXPECT_TRUE(ContainsKey(origins, origin1)); + EXPECT_TRUE(base::ContainsKey(origins, origin1)); // |origin1| should be removed from the foreign fetch origin list, since we // replace its registration with one without scopes.
diff --git a/content/browser/service_worker/service_worker_job_coordinator.cc b/content/browser/service_worker/service_worker_job_coordinator.cc index 916d714..28d537db 100644 --- a/content/browser/service_worker/service_worker_job_coordinator.cc +++ b/content/browser/service_worker/service_worker_job_coordinator.cc
@@ -31,7 +31,7 @@ ServiceWorkerJobCoordinator::JobQueue::~JobQueue() { DCHECK(jobs_.empty()) << "Destroying JobQueue with " << jobs_.size() << " unfinished jobs"; - STLDeleteElements(&jobs_); + base::STLDeleteElements(&jobs_); } ServiceWorkerRegisterJobBase* ServiceWorkerJobCoordinator::JobQueue::Push( @@ -82,11 +82,11 @@ void ServiceWorkerJobCoordinator::JobQueue::AbortAll() { for (size_t i = 0; i < jobs_.size(); ++i) jobs_[i]->Abort(); - STLDeleteElements(&jobs_); + base::STLDeleteElements(&jobs_); } void ServiceWorkerJobCoordinator::JobQueue::ClearForShutdown() { - STLDeleteElements(&jobs_); + base::STLDeleteElements(&jobs_); } ServiceWorkerJobCoordinator::ServiceWorkerJobCoordinator(
diff --git a/content/browser/service_worker/service_worker_process_manager.cc b/content/browser/service_worker/service_worker_process_manager.cc index 060c66b7..836297b1 100644 --- a/content/browser/service_worker/service_worker_process_manager.cc +++ b/content/browser/service_worker/service_worker_process_manager.cc
@@ -189,7 +189,7 @@ return; } - DCHECK(!ContainsKey(instance_info_, embedded_worker_id)) + DCHECK(!base::ContainsKey(instance_info_, embedded_worker_id)) << embedded_worker_id << " already has a process allocated"; if (can_use_existing_process) {
diff --git a/content/browser/service_worker/service_worker_process_manager_unittest.cc b/content/browser/service_worker/service_worker_process_manager_unittest.cc index 047bdb37..45dbea4 100644 --- a/content/browser/service_worker/service_worker_process_manager_unittest.cc +++ b/content/browser/service_worker/service_worker_process_manager_unittest.cc
@@ -217,14 +217,14 @@ EXPECT_EQ(2, host1->worker_ref_count()); EXPECT_EQ(0, host2->worker_ref_count()); EXPECT_EQ(2u, instance_info.size()); - EXPECT_TRUE(ContainsKey(instance_info, kEmbeddedWorkerId1)); - EXPECT_TRUE(ContainsKey(instance_info, kEmbeddedWorkerId2)); + EXPECT_TRUE(base::ContainsKey(instance_info, kEmbeddedWorkerId1)); + EXPECT_TRUE(base::ContainsKey(instance_info, kEmbeddedWorkerId2)); process_manager_->ReleaseWorkerProcess(kEmbeddedWorkerId1); EXPECT_EQ(1, host1->worker_ref_count()); EXPECT_EQ(0, host2->worker_ref_count()); EXPECT_EQ(1u, instance_info.size()); - EXPECT_TRUE(ContainsKey(instance_info, kEmbeddedWorkerId2)); + EXPECT_TRUE(base::ContainsKey(instance_info, kEmbeddedWorkerId2)); process_manager_->ReleaseWorkerProcess(kEmbeddedWorkerId2); EXPECT_EQ(0, host1->worker_ref_count());
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc index fe9cd8b4..67b10a7 100644 --- a/content/browser/service_worker/service_worker_provider_host.cc +++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -289,7 +289,7 @@ if (!IsContextSecureForServiceWorker()) return; size_t key = registration->pattern().spec().size(); - if (ContainsKey(matching_registrations_, key)) + if (base::ContainsKey(matching_registrations_, key)) return; IncreaseProcessReference(registration->pattern()); registration->AddListener(this); @@ -300,7 +300,7 @@ void ServiceWorkerProviderHost::RemoveMatchingRegistration( ServiceWorkerRegistration* registration) { size_t key = registration->pattern().spec().size(); - DCHECK(ContainsKey(matching_registrations_, key)); + DCHECK(base::ContainsKey(matching_registrations_, key)); DecreaseProcessReference(registration->pattern()); registration->RemoveListener(this); matching_registrations_.erase(key);
diff --git a/content/browser/service_worker/service_worker_storage.cc b/content/browser/service_worker/service_worker_storage.cc index 8cf5ce3..6c2d57a 100644 --- a/content/browser/service_worker/service_worker_storage.cc +++ b/content/browser/service_worker/service_worker_storage.cc
@@ -154,7 +154,7 @@ DCHECK_EQ(INITIALIZED, state_); // See if there are any stored registrations for the origin. - if (!ContainsKey(registered_origins_, document_url.GetOrigin())) { + if (!base::ContainsKey(registered_origins_, document_url.GetOrigin())) { // Look for something currently being installed. scoped_refptr<ServiceWorkerRegistration> installing_registration = FindInstallingRegistrationForDocument(document_url); @@ -208,7 +208,7 @@ DCHECK_EQ(INITIALIZED, state_); // See if there are any stored registrations for the origin. - if (!ContainsKey(registered_origins_, scope.GetOrigin())) { + if (!base::ContainsKey(registered_origins_, scope.GetOrigin())) { // Look for something currently being installed. scoped_refptr<ServiceWorkerRegistration> installing_registration = FindInstallingRegistrationForPattern(scope); @@ -262,7 +262,7 @@ DCHECK_EQ(INITIALIZED, state_); // See if there are any stored registrations for the origin. - if (!ContainsKey(registered_origins_, origin)) { + if (!base::ContainsKey(registered_origins_, origin)) { // Look for something currently being installed. scoped_refptr<ServiceWorkerRegistration> installing_registration = FindInstallingRegistrationForId(registration_id);
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc index 5b7ff730..c688361 100644 --- a/content/browser/service_worker/service_worker_version.cc +++ b/content/browser/service_worker/service_worker_version.cc
@@ -599,7 +599,7 @@ ServiceWorkerProviderHost* provider_host) { const std::string& uuid = provider_host->client_uuid(); CHECK(!provider_host->client_uuid().empty()); - DCHECK(!ContainsKey(controllee_map_, uuid)); + DCHECK(!base::ContainsKey(controllee_map_, uuid)); controllee_map_[uuid] = provider_host; // Keep the worker alive a bit longer right after a new controllee is added. RestartTick(&idle_time_); @@ -610,7 +610,7 @@ void ServiceWorkerVersion::RemoveControllee( ServiceWorkerProviderHost* provider_host) { const std::string& uuid = provider_host->client_uuid(); - DCHECK(ContainsKey(controllee_map_, uuid)); + DCHECK(base::ContainsKey(controllee_map_, uuid)); controllee_map_.erase(uuid); FOR_EACH_OBSERVER(Listener, listeners_, OnControlleeRemoved(this, provider_host));
diff --git a/content/browser/shared_worker/shared_worker_service_impl.cc b/content/browser/shared_worker/shared_worker_service_impl.cc index cdb4ca49..21202885 100644 --- a/content/browser/shared_worker/shared_worker_service_impl.cc +++ b/content/browser/shared_worker/shared_worker_service_impl.cc
@@ -346,7 +346,7 @@ SharedWorkerMessageFilter* filter) { ScopedWorkerDependencyChecker checker(this); ProcessRouteIdPair key(filter->render_process_id(), worker_route_id); - if (!ContainsKey(worker_hosts_, key)) + if (!base::ContainsKey(worker_hosts_, key)) return; std::unique_ptr<SharedWorkerHost> host(worker_hosts_[key].release()); worker_hosts_.erase(key); @@ -374,7 +374,7 @@ SharedWorkerMessageFilter* filter) { ScopedWorkerDependencyChecker checker(this); ProcessRouteIdPair key(filter->render_process_id(), worker_route_id); - if (!ContainsKey(worker_hosts_, key)) + if (!base::ContainsKey(worker_hosts_, key)) return; std::unique_ptr<SharedWorkerHost> host(worker_hosts_[key].release()); worker_hosts_.erase(key); @@ -530,7 +530,7 @@ ScopedWorkerDependencyChecker checker( this, base::Bind(&DecrementWorkerRefCount, worker_process_id)); - if (!ContainsKey(pending_instances_, pending_instance_id)) + if (!base::ContainsKey(pending_instances_, pending_instance_id)) return; std::unique_ptr<SharedWorkerPendingInstance> pending_instance( pending_instances_[pending_instance_id].release()); @@ -581,7 +581,7 @@ int worker_route_id, bool is_new_worker) { worker_hosts_.erase(std::make_pair(worker_process_id, worker_route_id)); - if (!ContainsKey(pending_instances_, pending_instance_id)) + if (!base::ContainsKey(pending_instances_, pending_instance_id)) return; std::unique_ptr<SharedWorkerPendingInstance> pending_instance( pending_instances_[pending_instance_id].release()); @@ -595,7 +595,7 @@ int render_process_id, int worker_route_id) { ProcessRouteIdPair key = std::make_pair(render_process_id, worker_route_id); - if (!ContainsKey(worker_hosts_, key)) + if (!base::ContainsKey(worker_hosts_, key)) return nullptr; return worker_hosts_[key].get(); }
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc index 31d3eb2b..8fc8598 100644 --- a/content/browser/site_per_process_browsertest.cc +++ b/content/browser/site_per_process_browsertest.cc
@@ -33,6 +33,7 @@ #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/renderer_host/render_widget_host_input_event_router.h" #include "content/browser/renderer_host/render_widget_host_view_aura.h" +#include "content/browser/web_contents/web_contents_impl.h" #include "content/common/child_process_messages.h" #include "content/common/frame_messages.h" #include "content/common/input/synthetic_tap_gesture_params.h" @@ -61,6 +62,7 @@ #include "third_party/WebKit/public/web/WebInputEvent.h" #include "third_party/WebKit/public/web/WebSandboxFlags.h" #include "ui/display/display_switches.h" +#include "ui/display/screen.h" #include "ui/events/event.h" #include "ui/events/event_utils.h" #include "ui/gfx/geometry/point.h" @@ -589,13 +591,16 @@ class SitePerProcessHighDPIBrowserTest : public SitePerProcessBrowserTest { public: + const double kDeviceScaleFactor = 2.0; + SitePerProcessHighDPIBrowserTest() {} protected: void SetUpCommandLine(base::CommandLine* command_line) override { SitePerProcessBrowserTest::SetUpCommandLine(command_line); - command_line->AppendSwitchASCII(switches::kForceDeviceScaleFactor, - base::StringPrintf("2")); + command_line->AppendSwitchASCII( + switches::kForceDeviceScaleFactor, + base::StringPrintf("%f", kDeviceScaleFactor)); } }; @@ -613,6 +618,30 @@ } }; +double GetFrameDeviceScaleFactor(const ToRenderFrameHost& adapter) { + double device_scale_factor; + const char kGetFrameDeviceScaleFactor[] = + "window.domAutomationController.send(window.devicePixelRatio);"; + EXPECT_TRUE(ExecuteScriptAndExtractDouble(adapter, kGetFrameDeviceScaleFactor, + &device_scale_factor)); + return device_scale_factor; +} + +IN_PROC_BROWSER_TEST_F(SitePerProcessHighDPIBrowserTest, + SubframeLoadsWithCorrectDeviceScaleFactor) { + GURL main_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b)")); + NavigateToURL(shell(), main_url); + + EXPECT_EQ(SitePerProcessHighDPIBrowserTest::kDeviceScaleFactor, + GetFrameDeviceScaleFactor(web_contents())); + + FrameTreeNode* root = web_contents()->GetFrameTree()->root(); + FrameTreeNode* child = root->child_at(0); + EXPECT_EQ(SitePerProcessHighDPIBrowserTest::kDeviceScaleFactor, + GetFrameDeviceScaleFactor(child)); +} + // Ensure that navigating subframes in --site-per-process mode works and the // correct documents are committed. #if defined(OS_WIN) @@ -6260,23 +6289,26 @@ ASSERT_TRUE(https_server.Start()); SetupCrossSiteRedirector(&https_server); + WebContentsImpl* web_contents = + static_cast<WebContentsImpl*>(shell()->web_contents()); + GURL iframe_url( https_server.GetURL("/mixed-content/basic-passive-in-iframe.html")); EXPECT_TRUE(NavigateToURL(shell(), iframe_url)); - EXPECT_TRUE(shell()->web_contents()->DisplayedInsecureContent()); + EXPECT_TRUE(web_contents->DisplayedInsecureContent()); // When the subframe navigates, the WebContents should still be marked // as having displayed insecure content. GURL navigate_url(https_server.GetURL("/title1.html")); - FrameTreeNode* root = web_contents()->GetFrameTree()->root(); + FrameTreeNode* root = web_contents->GetFrameTree()->root(); NavigateFrameToURL(root->child_at(0), navigate_url); - EXPECT_TRUE(shell()->web_contents()->DisplayedInsecureContent()); + EXPECT_TRUE(web_contents->DisplayedInsecureContent()); // When the main frame navigates, it should no longer be marked as // displaying insecure content. EXPECT_TRUE( NavigateToURL(shell(), https_server.GetURL("b.com", "/title1.html"))); - EXPECT_FALSE(shell()->web_contents()->DisplayedInsecureContent()); + EXPECT_FALSE(web_contents->DisplayedInsecureContent()); } // Tests that, when a parent frame is set to strictly block mixed @@ -6289,12 +6321,15 @@ ASSERT_TRUE(https_server.Start()); SetupCrossSiteRedirector(&https_server); + WebContentsImpl* web_contents = + static_cast<WebContentsImpl*>(shell()->web_contents()); + GURL iframe_url_with_strict_blocking(https_server.GetURL( "/mixed-content/basic-passive-in-iframe-with-strict-blocking.html")); EXPECT_TRUE(NavigateToURL(shell(), iframe_url_with_strict_blocking)); - EXPECT_FALSE(shell()->web_contents()->DisplayedInsecureContent()); + EXPECT_FALSE(web_contents->DisplayedInsecureContent()); - FrameTreeNode* root = web_contents()->GetFrameTree()->root(); + FrameTreeNode* root = web_contents->GetFrameTree()->root(); EXPECT_EQ(blink::kBlockAllMixedContent, root->current_replication_state().insecure_request_policy); EXPECT_EQ( @@ -6328,12 +6363,15 @@ ASSERT_TRUE(https_server.Start()); SetupCrossSiteRedirector(&https_server); + WebContentsImpl* web_contents = + static_cast<WebContentsImpl*>(shell()->web_contents()); + GURL iframe_url_with_upgrade(https_server.GetURL( "/mixed-content/basic-passive-in-iframe-with-upgrade.html")); EXPECT_TRUE(NavigateToURL(shell(), iframe_url_with_upgrade)); - EXPECT_FALSE(shell()->web_contents()->DisplayedInsecureContent()); + EXPECT_FALSE(web_contents->DisplayedInsecureContent()); - FrameTreeNode* root = web_contents()->GetFrameTree()->root(); + FrameTreeNode* root = web_contents->GetFrameTree()->root(); EXPECT_EQ(blink::kUpgradeInsecureRequests, root->current_replication_state().insecure_request_policy); EXPECT_EQ( @@ -6382,21 +6420,20 @@ EXPECT_FALSE(mixed_child->has_committed_real_load()); } -// Test that subresources with certificate errors that are NOT redundant -// with the main page DO get reported to the browser. That is, if -// https://nonredundant.test frames https://a.com which loads an image -// with certificate errors, the browser should be notified about the -// subresource with certificate errors and downgrade the UI -// appropriately. +// Test that subresources with certificate errors get reported to the +// browser. That is, if https://example.test frames https://a.com which +// loads an image with certificate errors, the browser should be +// notified about the subresource with certificate errors and downgrade +// the UI appropriately. IN_PROC_BROWSER_TEST_F(SitePerProcessIgnoreCertErrorsBrowserTest, - SubresourceWithNonRedundantCertificateErrors) { + SubresourceWithCertificateErrors) { net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); https_server.ServeFilesFromSourceDirectory("content/test/data"); ASSERT_TRUE(https_server.Start()); SetupCrossSiteRedirector(&https_server); GURL url(https_server.GetURL( - "nonredundant.test", + "example.test", "/mixed-content/non-redundant-cert-error-in-iframe.html")); EXPECT_TRUE(NavigateToURL(shell(), url)); @@ -6408,12 +6445,11 @@ EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, entry->GetSSL().security_style); - // The image that the iframe loaded had certificate errors also, and - // they were different than the certificate errors of the main - // resource, so the page should be marked as having displayed insecure - // content. + // The image that the iframe loaded had certificate errors also, so + // the page should be marked as having displayed subresources with + // cert errors. EXPECT_TRUE(entry->GetSSL().content_status & - SSLStatus::DISPLAYED_INSECURE_CONTENT); + SSLStatus::DISPLAYED_CONTENT_WITH_CERT_ERRORS); } // Test setting a cross-origin iframe to display: none. @@ -7202,12 +7238,12 @@ filter2->Wait(); // At this point, we should have two pending WebContents. - EXPECT_TRUE( - ContainsKey(web_contents()->pending_contents_, - std::make_pair(process1->GetID(), filter1->routing_id()))); - EXPECT_TRUE( - ContainsKey(web_contents()->pending_contents_, - std::make_pair(process2->GetID(), filter2->routing_id()))); + EXPECT_TRUE(base::ContainsKey( + web_contents()->pending_contents_, + std::make_pair(process1->GetID(), filter1->routing_id()))); + EXPECT_TRUE(base::ContainsKey( + web_contents()->pending_contents_, + std::make_pair(process2->GetID(), filter2->routing_id()))); // Both subframes were set up in the same way, so the next routing ID for the // new popup windows should match up (this led to the collision in the @@ -7278,12 +7314,12 @@ filter2->Wait(); // At this point, we should have two pending widgets. - EXPECT_TRUE( - ContainsKey(web_contents()->pending_widget_views_, - std::make_pair(process1->GetID(), filter1->routing_id()))); - EXPECT_TRUE( - ContainsKey(web_contents()->pending_widget_views_, - std::make_pair(process2->GetID(), filter2->routing_id()))); + EXPECT_TRUE(base::ContainsKey( + web_contents()->pending_widget_views_, + std::make_pair(process1->GetID(), filter1->routing_id()))); + EXPECT_TRUE(base::ContainsKey( + web_contents()->pending_widget_views_, + std::make_pair(process2->GetID(), filter2->routing_id()))); // Both subframes were set up in the same way, so the next routing ID for the // new popup widgets should match up (this led to the collision in the @@ -7295,12 +7331,12 @@ false, gfx::Rect()); web_contents()->ShowCreatedWidget(process2->GetID(), filter2->routing_id(), false, gfx::Rect()); - EXPECT_FALSE( - ContainsKey(web_contents()->pending_widget_views_, - std::make_pair(process1->GetID(), filter1->routing_id()))); - EXPECT_FALSE( - ContainsKey(web_contents()->pending_widget_views_, - std::make_pair(process2->GetID(), filter2->routing_id()))); + EXPECT_FALSE(base::ContainsKey( + web_contents()->pending_widget_views_, + std::make_pair(process1->GetID(), filter1->routing_id()))); + EXPECT_FALSE(base::ContainsKey( + web_contents()->pending_widget_views_, + std::make_pair(process2->GetID(), filter2->routing_id()))); } #endif @@ -7762,4 +7798,60 @@ EXPECT_FALSE(rvh->is_active()); } +// Test that a crashed subframe can be successfully navigated to the site it +// was on before crashing. See https://crbug.com/634368. +IN_PROC_BROWSER_TEST_F(SitePerProcessBrowserTest, + NavigateCrashedSubframeToSameSite) { + GURL main_url(embedded_test_server()->GetURL( + "a.com", "/cross_site_iframe_factory.html?a(b)")); + EXPECT_TRUE(NavigateToURL(shell(), main_url)); + FrameTreeNode* root = web_contents()->GetFrameTree()->root(); + FrameTreeNode* child = root->child_at(0); + + // Set up a postMessage handler in the main frame for later use. + EXPECT_TRUE(ExecuteScript( + root->current_frame_host(), + "window.addEventListener('message'," + " function(e) { document.title = e.data; });")); + + // Crash the subframe process. + RenderProcessHost* child_process = child->current_frame_host()->GetProcess(); + RenderProcessHostWatcher crash_observer( + child_process, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + child_process->Shutdown(0, false); + crash_observer.Wait(); + EXPECT_FALSE(child->current_frame_host()->IsRenderFrameLive()); + + // When the subframe dies, its RenderWidgetHostView should be cleared and + // reset in the CrossProcessFrameConnector. + EXPECT_FALSE(child->current_frame_host()->GetView()); + RenderFrameProxyHost* proxy_to_parent = + child->render_manager()->GetProxyToParent(); + EXPECT_FALSE( + proxy_to_parent->cross_process_frame_connector()->get_view_for_testing()); + + // Navigate the subframe to the same site it was on before crashing. This + // should reuse the subframe's current RenderFrameHost and reinitialize the + // RenderFrame in a new process. + NavigateFrameToURL(child, + embedded_test_server()->GetURL("b.com", "/title1.html")); + EXPECT_TRUE(child->current_frame_host()->IsRenderFrameLive()); + + // The RenderWidgetHostView for the child should be recreated and set to be + // used in the CrossProcessFrameConnector. Without this, the frame won't be + // rendered properly. + EXPECT_TRUE(child->current_frame_host()->GetView()); + EXPECT_EQ( + child->current_frame_host()->GetView(), + proxy_to_parent->cross_process_frame_connector()->get_view_for_testing()); + + // Send a postMessage from the child to its parent. This verifies that the + // parent's proxy in the child's SiteInstance was also restored. + base::string16 expected_title(base::UTF8ToUTF16("I am alive!")); + TitleWatcher title_watcher(shell()->web_contents(), expected_title); + EXPECT_TRUE(ExecuteScript(child->current_frame_host(), + "parent.postMessage('I am alive!', '*');")); + EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle()); +} + } // namespace content
diff --git a/content/browser/ssl/ssl_manager.cc b/content/browser/ssl/ssl_manager.cc index f50efb2..cb2e540 100644 --- a/content/browser/ssl/ssl_manager.cc +++ b/content/browser/ssl/ssl_manager.cc
@@ -166,6 +166,12 @@ UpdateEntry(navigation_entry); } +void SSLManager::DidRunContentWithCertErrors(const GURL& security_origin) { + NavigationEntryImpl* navigation_entry = controller_->GetLastCommittedEntry(); + policy()->DidRunContentWithCertErrors(navigation_entry, security_origin); + UpdateEntry(navigation_entry); +} + void SSLManager::DidStartResourceResponse( const ResourceRequestDetails& details) { // Notify our policy that we started a resource request. Ideally, the
diff --git a/content/browser/ssl/ssl_manager.h b/content/browser/ssl/ssl_manager.h index b6dbd62..493d0ba 100644 --- a/content/browser/ssl/ssl_manager.h +++ b/content/browser/ssl/ssl_manager.h
@@ -85,9 +85,12 @@ void DidStartResourceResponse(const ResourceRequestDetails& details); void DidReceiveResourceRedirect(const ResourceRedirectDetails& details); - // Insecure content entry point. + // Entry point for insecure mixed content (loaded over HTTP). void DidRunInsecureContent(const GURL& security_origin); + // Entry point for content loaded with HTTPS certificate errors. + void DidRunContentWithCertErrors(const GURL& security_origin); + private: // Updates the NavigationEntry with our current state. This will // notify the WebContents of an SSL state change if a change was
diff --git a/content/browser/ssl/ssl_policy.cc b/content/browser/ssl/ssl_policy.cc index 9d60c36..f94d0c6 100644 --- a/content/browser/ssl/ssl_policy.cc +++ b/content/browser/ssl/ssl_policy.cc
@@ -148,6 +148,19 @@ site_instance->GetProcess()->GetID()); } +void SSLPolicy::DidRunContentWithCertErrors(NavigationEntryImpl* entry, + const GURL& security_origin) { + if (!entry) + return; + + SiteInstance* site_instance = entry->site_instance(); + if (!site_instance) + return; + + backend_->HostRanContentWithCertErrors(security_origin.host(), + site_instance->GetProcess()->GetID()); +} + void SSLPolicy::OnRequestStarted(const GURL& url, int cert_id, net::CertStatus cert_status) { @@ -177,17 +190,28 @@ WebContents* web_contents) { DCHECK(entry); + WebContentsImpl* web_contents_impl = + static_cast<WebContentsImpl*>(web_contents); + InitializeEntryIfNeeded(entry); if (entry->GetSSL().security_style == SECURITY_STYLE_UNAUTHENTICATED) return; - if (!web_contents->DisplayedInsecureContent()) + if (!web_contents_impl->DisplayedInsecureContent()) entry->GetSSL().content_status &= ~SSLStatus::DISPLAYED_INSECURE_CONTENT; - if (web_contents->DisplayedInsecureContent()) + if (web_contents_impl->DisplayedInsecureContent()) entry->GetSSL().content_status |= SSLStatus::DISPLAYED_INSECURE_CONTENT; + if (!web_contents_impl->DisplayedContentWithCertErrors()) + entry->GetSSL().content_status &= + ~SSLStatus::DISPLAYED_CONTENT_WITH_CERT_ERRORS; + + if (web_contents_impl->DisplayedContentWithCertErrors()) + entry->GetSSL().content_status |= + SSLStatus::DISPLAYED_CONTENT_WITH_CERT_ERRORS; + SiteInstance* site_instance = entry->site_instance(); // Note that |site_instance| can be NULL here because NavigationEntries don't // necessarily have site instances. Without a process, the entry can't @@ -199,6 +223,13 @@ SECURITY_STYLE_AUTHENTICATION_BROKEN; entry->GetSSL().content_status |= SSLStatus::RAN_INSECURE_CONTENT; } + + if (site_instance && + backend_->DidHostRunContentWithCertErrors( + entry->GetURL().host(), site_instance->GetProcess()->GetID())) { + entry->GetSSL().security_style = SECURITY_STYLE_AUTHENTICATION_BROKEN; + entry->GetSSL().content_status |= SSLStatus::RAN_CONTENT_WITH_CERT_ERRORS; + } } // Static
diff --git a/content/browser/ssl/ssl_policy.h b/content/browser/ssl/ssl_policy.h index 0ba7869..c96c0ed 100644 --- a/content/browser/ssl/ssl_policy.h +++ b/content/browser/ssl/ssl_policy.h
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "content/common/content_export.h" #include "content/public/browser/certificate_request_result_type.h" #include "content/public/common/resource_type.h" #include "content/public/common/security_style.h" @@ -28,7 +29,7 @@ // SSL trust indicators. It relies on the SSLPolicyBackend to actually enact // the decisions it reaches. // -class SSLPolicy { +class CONTENT_EXPORT SSLPolicy { public: explicit SSLPolicy(SSLPolicyBackend* backend); @@ -38,6 +39,9 @@ void DidRunInsecureContent(NavigationEntryImpl* entry, const GURL& security_origin); + void DidRunContentWithCertErrors(NavigationEntryImpl* entry, + const GURL& security_origin); + // We have started a resource request for |url| with the given |cert_id| and // |cert_status|. void OnRequestStarted(const GURL& url,
diff --git a/content/browser/ssl/ssl_policy_backend.cc b/content/browser/ssl/ssl_policy_backend.cc index a2626da..34fa2e4b 100644 --- a/content/browser/ssl/ssl_policy_backend.cc +++ b/content/browser/ssl/ssl_policy_backend.cc
@@ -19,7 +19,8 @@ void SSLPolicyBackend::HostRanInsecureContent(const std::string& host, int id) { if (ssl_host_state_delegate_) - ssl_host_state_delegate_->HostRanInsecureContent(host, id); + ssl_host_state_delegate_->HostRanInsecureContent( + host, id, SSLHostStateDelegate::MIXED_CONTENT); SSLManager::NotifySSLInternalStateChanged(controller_->GetBrowserContext()); } @@ -28,7 +29,25 @@ if (!ssl_host_state_delegate_) return false; - return ssl_host_state_delegate_->DidHostRunInsecureContent(host, pid); + return ssl_host_state_delegate_->DidHostRunInsecureContent( + host, pid, SSLHostStateDelegate::MIXED_CONTENT); +} + +void SSLPolicyBackend::HostRanContentWithCertErrors(const std::string& host, + int id) { + if (ssl_host_state_delegate_) + ssl_host_state_delegate_->HostRanInsecureContent( + host, id, SSLHostStateDelegate::CERT_ERRORS_CONTENT); + SSLManager::NotifySSLInternalStateChanged(controller_->GetBrowserContext()); +} + +bool SSLPolicyBackend::DidHostRunContentWithCertErrors(const std::string& host, + int pid) const { + if (!ssl_host_state_delegate_) + return false; + + return ssl_host_state_delegate_->DidHostRunInsecureContent( + host, pid, SSLHostStateDelegate::CERT_ERRORS_CONTENT); } void SSLPolicyBackend::RevokeUserAllowExceptions(const std::string& host) {
diff --git a/content/browser/ssl/ssl_policy_backend.h b/content/browser/ssl/ssl_policy_backend.h index 3de3462..84c38af4 100644 --- a/content/browser/ssl/ssl_policy_backend.h +++ b/content/browser/ssl/ssl_policy_backend.h
@@ -21,12 +21,19 @@ public: explicit SSLPolicyBackend(NavigationControllerImpl* controller); - // Records that a host has run insecure content. + // Records that a host has run mixed content loaded over HTTP. void HostRanInsecureContent(const std::string& host, int pid); - // Returns whether the specified host ran insecure content. + // Returns whether the specified host ran insecure content loaded over HTTP. bool DidHostRunInsecureContent(const std::string& host, int pid) const; + // Records that a host has run subresources loaded with certificate errors. + void HostRanContentWithCertErrors(const std::string& host, int pid); + + // Returns whether the specified host ran subresources loaded with certificate + // errors. + bool DidHostRunContentWithCertErrors(const std::string& host, int pid) const; + // Revokes all allow exceptions by the user for |host|. void RevokeUserAllowExceptions(const std::string& host);
diff --git a/content/browser/storage_partition_impl_map.cc b/content/browser/storage_partition_impl_map.cc index 5100cbd..c46b959 100644 --- a/content/browser/storage_partition_impl_map.cc +++ b/content/browser/storage_partition_impl_map.cc
@@ -42,6 +42,7 @@ #include "content/public/browser/storage_partition.h" #include "content/public/common/content_constants.h" #include "content/public/common/content_switches.h" +#include "content/public/common/origin_trial_policy.h" #include "content/public/common/url_constants.h" #include "crypto/sha2.h" #include "net/url_request/url_request_context.h" @@ -376,8 +377,8 @@ } StoragePartitionImplMap::~StoragePartitionImplMap() { - STLDeleteContainerPairSecondPointers(partitions_.begin(), - partitions_.end()); + base::STLDeleteContainerPairSecondPointers(partitions_.begin(), + partitions_.end()); } StoragePartitionImpl* StoragePartitionImplMap::Get( @@ -445,8 +446,7 @@ request_interceptors.push_back( ServiceWorkerRequestHandler::CreateInterceptor( browser_context_->GetResourceContext()).release()); - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableExperimentalWebPlatformFeatures)) { + if (ForeignFetchRequestHandler::IsForeignFetchEnabled()) { request_interceptors.push_back( ForeignFetchRequestHandler::CreateInterceptor( browser_context_->GetResourceContext())
diff --git a/content/browser/time_zone_monitor_linux.cc b/content/browser/time_zone_monitor_linux.cc index 952e2e88..88a59188 100644 --- a/content/browser/time_zone_monitor_linux.cc +++ b/content/browser/time_zone_monitor_linux.cc
@@ -74,7 +74,7 @@ ~TimeZoneMonitorLinuxImpl() { DCHECK(!owner_); - STLDeleteElements(&file_path_watchers_); + base::STLDeleteElements(&file_path_watchers_); } void StartWatchingOnFileThread() { @@ -104,7 +104,7 @@ void StopWatchingOnFileThread() { DCHECK_CURRENTLY_ON(BrowserThread::FILE); - STLDeleteElements(&file_path_watchers_); + base::STLDeleteElements(&file_path_watchers_); } void OnTimeZoneFileChanged(const base::FilePath& path, bool error) {
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index a25b0a0..40ec7e78 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -84,7 +84,6 @@ #include "content/common/page_messages.h" #include "content/common/page_state_serialization.h" #include "content/common/site_isolation_policy.h" -#include "content/common/ssl_status_serialization.h" #include "content/common/view_messages.h" #include "content/public/browser/ax_event_notification_details.h" #include "content/public/browser/browser_context.h" @@ -95,7 +94,6 @@ #include "content/public/browser/download_url_parameters.h" #include "content/public/browser/invalidate_type.h" #include "content/public/browser/javascript_dialog_manager.h" -#include "content/public/browser/load_from_memory_cache_details.h" #include "content/public/browser/load_notification_details.h" #include "content/public/browser/navigation_details.h" #include "content/public/browser/notification_details.h" @@ -116,7 +114,6 @@ #include "content/public/common/content_switches.h" #include "content/public/common/page_zoom.h" #include "content/public/common/result_codes.h" -#include "content/public/common/security_style.h" #include "content/public/common/url_constants.h" #include "content/public/common/url_utils.h" #include "content/public/common/web_preferences.h" @@ -407,6 +404,7 @@ upload_position_(0), is_resume_pending_(false), displayed_insecure_content_(false), + displayed_content_with_cert_errors_(false), has_accessed_initial_document_(false), theme_color_(SK_ColorTRANSPARENT), last_sent_theme_color_(SK_ColorTRANSPARENT), @@ -552,9 +550,6 @@ ResetWebContents()); SetDelegate(NULL); - - STLDeleteContainerPairSecondPointers(destruction_observers_.begin(), - destruction_observers_.end()); } WebContentsImpl* WebContentsImpl::CreateWithOpener( @@ -991,6 +986,16 @@ UpdateZoom(level); } +void WebContentsImpl::UpdateDeviceScaleFactor(double device_scale_factor) { + SendPageMessage( + new PageMsg_SetDeviceScaleFactor(MSG_ROUTING_NONE, device_scale_factor)); +} + +void WebContentsImpl::GetScreenInfo(blink::WebScreenInfo* web_screen_info) { + if (GetView()) + GetView()->GetScreenInfo(web_screen_info); +} + WebUI* WebContentsImpl::CreateSubframeWebUI(const GURL& url, const std::string& frame_name) { DCHECK(!frame_name.empty()); @@ -1181,10 +1186,6 @@ return canonical_encoding_; } -bool WebContentsImpl::DisplayedInsecureContent() const { - return displayed_insecure_content_; -} - void WebContentsImpl::IncrementCapturerCount(const gfx::Size& capture_size) { DCHECK(!is_being_destroyed_); ++capturer_count_; @@ -1647,17 +1648,12 @@ void WebContentsImpl::AddDestructionObserver(WebContentsImpl* web_contents) { if (!ContainsKey(destruction_observers_, web_contents)) { destruction_observers_[web_contents] = - new DestructionObserver(this, web_contents); + base::MakeUnique<DestructionObserver>(this, web_contents); } } void WebContentsImpl::RemoveDestructionObserver(WebContentsImpl* web_contents) { - DestructionObservers::iterator iter = - destruction_observers_.find(web_contents); - if (iter != destruction_observers_.end()) { - delete destruction_observers_[web_contents]; - destruction_observers_.erase(iter); - } + destruction_observers_.erase(web_contents); } void WebContentsImpl::AddObserver(WebContentsObserver* observer) { @@ -2507,6 +2503,14 @@ delegate_->ResizeDueToAutoResize(this, new_size); } +bool WebContentsImpl::DisplayedInsecureContent() const { + return displayed_insecure_content_; +} + +bool WebContentsImpl::DisplayedContentWithCertErrors() const { + return displayed_content_with_cert_errors_; +} + WebContents* WebContentsImpl::OpenURL(const OpenURLParams& params) { if (!delegate_) return NULL; @@ -3443,25 +3447,12 @@ void WebContentsImpl::OnDidLoadResourceFromMemoryCache( const GURL& url, - const std::string& security_info, const std::string& http_method, const std::string& mime_type, ResourceType resource_type) { - SSLStatus status; - if (!DeserializeSecurityInfo(security_info, &status)) { - bad_message::ReceivedBadMessage( - GetRenderProcessHost(), - bad_message::WC_MEMORY_CACHE_RESOURCE_BAD_SECURITY_INFO); - return; - } - - // Send out a notification that we loaded a resource from our memory cache. - // TODO(alcutter,eranm): Pass signed_certificate_timestamp_ids into details. - LoadFromMemoryCacheDetails details( - url, status.cert_id, status.cert_status, http_method, mime_type, - resource_type); FOR_EACH_OBSERVER(WebContentsObserver, observers_, - DidLoadResourceFromMemoryCache(details)); + DidLoadResourceFromMemoryCache(url, mime_type, + resource_type)); if (url.is_valid() && url.SchemeIsHTTPOrHTTPS()) { scoped_refptr<net::URLRequestContextGetter> request_context( @@ -3499,32 +3490,21 @@ void WebContentsImpl::OnDidDisplayContentWithCertificateErrors( const GURL& url) { - // Check that the main frame navigation entry has a cryptographic - // scheme; the security UI is associated with the main frame rather - // than the subframe (if any) that actually displayed the subresource - // with errors. - NavigationEntry* entry = controller_.GetLastCommittedEntry(); - if (!entry || !entry->GetURL().SchemeIsCryptographic()) - return; - - displayed_insecure_content_ = true; + displayed_content_with_cert_errors_ = true; SSLManager::NotifySSLInternalStateChanged( GetController().GetBrowserContext()); } void WebContentsImpl::OnDidRunContentWithCertificateErrors( const GURL& url) { - // Check that the main frame navigation entry has a cryptographic - // scheme; the security UI is associated with the main frame rather - // than the subframe (if any) that actually displayed the subresource - // with errors. - NavigationEntry* entry = controller_.GetLastCommittedEntry(); - if (!entry || !entry->GetURL().SchemeIsCryptographic()) + NavigationEntry* entry = controller_.GetVisibleEntry(); + if (!entry) return; // TODO(estark): check that this does something reasonable for // about:blank and sandboxed origins. https://crbug.com/609527 - controller_.ssl_manager()->DidRunInsecureContent(entry->GetURL().GetOrigin()); + controller_.ssl_manager()->DidRunContentWithCertErrors( + entry->GetURL().GetOrigin()); SSLManager::NotifySSLInternalStateChanged( GetController().GetBrowserContext()); }
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 91226f8..65d1a9b 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h
@@ -291,7 +291,6 @@ uint64_t GetUploadSize() const override; uint64_t GetUploadPosition() const override; const std::string& GetEncoding() const override; - bool DisplayedInsecureContent() const override; void IncrementCapturerCount(const gfx::Size& capture_size) override; void DecrementCapturerCount() override; int GetCapturerCount() const override; @@ -408,6 +407,14 @@ bool GetAllowOtherViews() override; #endif + // Returns true if this is a secure page which has displayed content + // loaded over insecure HTTP. + bool DisplayedInsecureContent() const; + + // Returns true if this page has displayed content loaded over HTTPS + // with certificate errors. + bool DisplayedContentWithCertErrors() const; + // Implementation of PageNavigator. WebContents* OpenURL(const OpenURLParams& params) override; @@ -595,6 +602,8 @@ void ResizeDueToAutoResize(RenderWidgetHostImpl* render_widget_host, const gfx::Size& new_size) override; void ScreenInfoChanged() override; + void UpdateDeviceScaleFactor(double device_scale_factor) override; + void GetScreenInfo(blink::WebScreenInfo* web_screen_info) override; bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) override; void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) override; @@ -788,7 +797,7 @@ FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest, LoadResourceFromMemoryCacheWithBadSecurityInfo); FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest, - LoadResourceFromMemoryCacheWithEmptySecurityInfo); + LoadResourceWithEmptySecurityInfo); FRIEND_TEST_ALL_PREFIXES(WebContentsImplTest, ResetJavaScriptDialogOnUserNavigate); FRIEND_TEST_ALL_PREFIXES(FormStructureBrowserTest, HTMLFiles); @@ -905,7 +914,6 @@ // IPC message handlers. void OnThemeColorChanged(SkColor theme_color); void OnDidLoadResourceFromMemoryCache(const GURL& url, - const std::string& security_info, const std::string& http_request, const std::string& mime_type, ResourceType resource_type); @@ -1121,8 +1129,8 @@ // haven't been shown yet. std::map<ProcessRoutingIdPair, RenderWidgetHostView*> pending_widget_views_; - typedef std::map<WebContentsImpl*, DestructionObserver*> DestructionObservers; - DestructionObservers destruction_observers_; + std::map<WebContentsImpl*, std::unique_ptr<DestructionObserver>> + destruction_observers_; // A list of observers notified when page state changes. Weak references. // This MUST be listed above frame_tree_ since at destruction time the @@ -1199,9 +1207,14 @@ // The canonicalized character encoding. std::string canonical_encoding_; - // True if this is a secure page which displayed insecure content. + // True if this is a secure page which displayed mixed content (loaded + // over HTTP). bool displayed_insecure_content_; + // True if this page displayed subresources loaded with HTTPS + // certificate errors. + bool displayed_content_with_cert_errors_; + // Whether the initial empty page has been accessed by another page, making it // unsafe to show the pending URL. Usually false unless another window tries // to modify the blank page. Always false after the first commit.
diff --git a/content/browser/web_contents/web_contents_impl_unittest.cc b/content/browser/web_contents/web_contents_impl_unittest.cc index 0c13e06..af25105e 100644 --- a/content/browser/web_contents/web_contents_impl_unittest.cc +++ b/content/browser/web_contents/web_contents_impl_unittest.cc
@@ -19,6 +19,7 @@ #include "content/browser/media/media_web_contents_observer.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/site_instance_impl.h" +#include "content/browser/ssl/ssl_policy.h" #include "content/browser/webui/content_web_ui_controller_factory.h" #include "content/browser/webui/web_ui_controller_factory_registry.h" #include "content/common/frame_messages.h" @@ -3371,23 +3372,10 @@ EXPECT_EQ(SK_ColorGREEN, observer.last_theme_color()); } -// Test that if a renderer reports that it has loaded a resource from -// memory cache with bad security info (i.e. can't be deserialized), the -// renderer gets killed. -TEST_F(WebContentsImplTest, LoadResourceFromMemoryCacheWithBadSecurityInfo) { - MockRenderProcessHost* rph = contents()->GetMainFrame()->GetProcess(); - EXPECT_EQ(0, rph->bad_msg_count()); - - contents()->OnDidLoadResourceFromMemoryCache( - GURL("http://example.test"), "not valid security info", "GET", - "mime type", RESOURCE_TYPE_MAIN_FRAME); - EXPECT_EQ(1, rph->bad_msg_count()); -} - // Test that if a resource is loaded with empty security info, the SSLManager // does not mistakenly think it has seen a good certificate and thus forget any // user exceptions for that host. See https://crbug.com/516808. -TEST_F(WebContentsImplTest, LoadResourceFromMemoryCacheWithEmptySecurityInfo) { +TEST_F(WebContentsImplTest, LoadResourceWithEmptySecurityInfo) { WebContentsImplTestBrowserClient browser_client; SetBrowserClientForTesting(&browser_client); @@ -3399,8 +3387,8 @@ backend->AllowCertForHost(*cert, test_url.host(), 1); EXPECT_TRUE(backend->HasAllowException(test_url.host())); - contents()->OnDidLoadResourceFromMemoryCache(test_url, "", "GET", "mime type", - RESOURCE_TYPE_MAIN_FRAME); + contents()->controller_.ssl_manager()->policy()->OnRequestStarted( + test_url, 0, 0); EXPECT_TRUE(backend->HasAllowException(test_url.host()));
diff --git a/content/browser/web_contents/web_contents_view.h b/content/browser/web_contents/web_contents_view.h index cbca384..090ea993 100644 --- a/content/browser/web_contents/web_contents_view.h +++ b/content/browser/web_contents/web_contents_view.h
@@ -14,6 +14,10 @@ #include "ui/gfx/geometry/size.h" #include "ui/gfx/native_widget_types.h" +namespace blink { + struct WebScreenInfo; +} + namespace content { class RenderViewHost; class RenderWidgetHost; @@ -39,6 +43,12 @@ // dialog boxes. virtual gfx::NativeWindow GetTopLevelNativeWindow() const = 0; + // The following static method is implemented by each platform. + static void GetDefaultScreenInfo(blink::WebScreenInfo* results); + + // Gets screen information for the window associated with this view. + virtual void GetScreenInfo(blink::WebScreenInfo* web_screen_info) const = 0; + // Computes the rectangle for the native widget that contains the contents of // the tab in the screen coordinate system. virtual void GetContainerBounds(gfx::Rect* out) const = 0;
diff --git a/content/browser/web_contents/web_contents_view_android.cc b/content/browser/web_contents/web_contents_view_android.cc index 36ce67b..33e714ea 100644 --- a/content/browser/web_contents/web_contents_view_android.cc +++ b/content/browser/web_contents/web_contents_view_android.cc
@@ -16,6 +16,9 @@ #include "content/public/browser/render_widget_host.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/common/drop_data.h" +#include "third_party/WebKit/public/platform/WebScreenInfo.h" +#include "ui/display/screen.h" +#include "ui/gfx/android/device_display_info.h" #include "ui/gfx/android/java_bitmap.h" #include "ui/gfx/image/image_skia.h" @@ -26,6 +29,24 @@ namespace content { +// static +void WebContentsView::GetDefaultScreenInfo( + blink::WebScreenInfo* results) { + const display::Display& display = + display::Screen::GetScreen()->GetPrimaryDisplay(); + results->rect = display.bounds(); + // TODO(husky): Remove any system controls from availableRect. + results->availableRect = display.work_area(); + results->deviceScaleFactor = display.device_scale_factor(); + results->orientationAngle = display.RotationAsDegree(); + results->orientationType = + RenderWidgetHostViewBase::GetOrientationTypeForMobile(display); + gfx::DeviceDisplayInfo info; + results->depth = display.color_depth(); + results->depthPerComponent = display.depth_per_component(); + results->isMonochrome = (results->depthPerComponent == 0); +} + WebContentsView* CreateWebContentsView( WebContentsImpl* web_contents, WebContentsViewDelegate* delegate, @@ -84,6 +105,11 @@ return content_view_core_ ? content_view_core_->GetWindowAndroid() : nullptr; } +void WebContentsViewAndroid::GetScreenInfo(blink::WebScreenInfo* result) const { + // ScreenInfo isn't tied to the widget on Android. Always return the default. + WebContentsView::GetDefaultScreenInfo(result); +} + void WebContentsViewAndroid::GetContainerBounds(gfx::Rect* out) const { *out = content_view_core_ ? gfx::Rect(content_view_core_->GetViewSize()) : gfx::Rect();
diff --git a/content/browser/web_contents/web_contents_view_android.h b/content/browser/web_contents/web_contents_view_android.h index 8e8f47c..1d4f78af 100644 --- a/content/browser/web_contents/web_contents_view_android.h +++ b/content/browser/web_contents/web_contents_view_android.h
@@ -36,6 +36,7 @@ gfx::NativeView GetNativeView() const override; gfx::NativeView GetContentNativeView() const override; gfx::NativeWindow GetTopLevelNativeWindow() const override; + void GetScreenInfo(blink::WebScreenInfo* web_screen_info) const override; void GetContainerBounds(gfx::Rect* out) const override; void SizeContents(const gfx::Size& size) override; void Focus() override;
diff --git a/content/browser/web_contents/web_contents_view_aura.cc b/content/browser/web_contents/web_contents_view_aura.cc index f426d94..57b401c6 100644 --- a/content/browser/web_contents/web_contents_view_aura.cc +++ b/content/browser/web_contents/web_contents_view_aura.cc
@@ -45,6 +45,7 @@ #include "content/public/common/content_switches.h" #include "content/public/common/drop_data.h" #include "net/base/filename_util.h" +#include "third_party/WebKit/public/platform/WebScreenInfo.h" #include "third_party/WebKit/public/web/WebInputEvent.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/client/screen_position_client.h" @@ -625,6 +626,47 @@ return window ? window : delegate_->GetNativeWindow(); } +namespace { + +void GetScreenInfoForWindow(blink::WebScreenInfo* results, + aura::Window* window) { + display::Screen* screen = display::Screen::GetScreen(); + const display::Display display = window + ? screen->GetDisplayNearestWindow(window) + : screen->GetPrimaryDisplay(); + results->rect = display.bounds(); + results->availableRect = display.work_area(); + // TODO(derat|oshima): Don't hardcode this. Get this from display object. + results->depth = 24; + results->depthPerComponent = 8; + results->deviceScaleFactor = display.device_scale_factor(); + + // The Display rotation and the WebScreenInfo orientation are not the same + // angle. The former is the physical display rotation while the later is the + // rotation required by the content to be shown properly on the screen, in + // other words, relative to the physical display. + results->orientationAngle = display.RotationAsDegree(); + if (results->orientationAngle == 90) + results->orientationAngle = 270; + else if (results->orientationAngle == 270) + results->orientationAngle = 90; + + results->orientationType = + RenderWidgetHostViewBase::GetOrientationTypeForDesktop(display); +} + +} // namespace + +// Static. +void WebContentsView::GetDefaultScreenInfo(blink::WebScreenInfo* results) { + GetScreenInfoForWindow(results, NULL); +} + +void WebContentsViewAura::GetScreenInfo( + blink::WebScreenInfo* web_screen_info) const { + GetScreenInfoForWindow(web_screen_info, window_.get()); +} + void WebContentsViewAura::GetContainerBounds(gfx::Rect *out) const { *out = window_->GetBoundsInScreen(); }
diff --git a/content/browser/web_contents/web_contents_view_aura.h b/content/browser/web_contents/web_contents_view_aura.h index 18a3ec27..2dd8b81 100644 --- a/content/browser/web_contents/web_contents_view_aura.h +++ b/content/browser/web_contents/web_contents_view_aura.h
@@ -91,6 +91,7 @@ gfx::NativeView GetNativeView() const override; gfx::NativeView GetContentNativeView() const override; gfx::NativeWindow GetTopLevelNativeWindow() const override; + void GetScreenInfo(blink::WebScreenInfo* web_screen_info) const override; void GetContainerBounds(gfx::Rect* out) const override; void SizeContents(const gfx::Size& size) override; void Focus() override;
diff --git a/content/browser/web_contents/web_contents_view_child_frame.cc b/content/browser/web_contents/web_contents_view_child_frame.cc index a92a0846..62f85703 100644 --- a/content/browser/web_contents/web_contents_view_child_frame.cc +++ b/content/browser/web_contents/web_contents_view_child_frame.cc
@@ -47,6 +47,18 @@ return GetOuterView()->GetTopLevelNativeWindow(); } +void WebContentsViewChildFrame::GetScreenInfo( + blink::WebScreenInfo* web_screen_info) const { + // TODO(wjmaclean): falling back to the default screen info is not what used + // to happen in RenderWidgetHostViewChildFrame, but it seems like the right + // thing to do. We should keep an eye on this in case the else-clause below + // causes problems. + if (web_contents_->GetOuterWebContents()) + GetOuterView()->GetScreenInfo(web_screen_info); + else + WebContentsView::GetDefaultScreenInfo(web_screen_info); +} + void WebContentsViewChildFrame::GetContainerBounds(gfx::Rect* out) const { RenderWidgetHostView* view = web_contents_->GetRenderWidgetHostView(); if (view)
diff --git a/content/browser/web_contents/web_contents_view_child_frame.h b/content/browser/web_contents/web_contents_view_child_frame.h index 0f34907..a2a69f3 100644 --- a/content/browser/web_contents/web_contents_view_child_frame.h +++ b/content/browser/web_contents/web_contents_view_child_frame.h
@@ -28,6 +28,7 @@ gfx::NativeView GetNativeView() const override; gfx::NativeView GetContentNativeView() const override; gfx::NativeWindow GetTopLevelNativeWindow() const override; + void GetScreenInfo(blink::WebScreenInfo* web_screen_info) const override; void GetContainerBounds(gfx::Rect* out) const override; void SizeContents(const gfx::Size& size) override; void Focus() override;
diff --git a/content/browser/web_contents/web_contents_view_guest.cc b/content/browser/web_contents/web_contents_view_guest.cc index f6d6cf41..234cac3b 100644 --- a/content/browser/web_contents/web_contents_view_guest.cc +++ b/content/browser/web_contents/web_contents_view_guest.cc
@@ -63,6 +63,14 @@ return guest_->embedder_web_contents()->GetTopLevelNativeWindow(); } +void WebContentsViewGuest::GetScreenInfo( + blink::WebScreenInfo* web_screen_info) const { + if (guest_->embedder_web_contents()) + guest_->embedder_web_contents()->GetView()->GetScreenInfo(web_screen_info); + else + WebContentsView::GetDefaultScreenInfo(web_screen_info); +} + void WebContentsViewGuest::OnGuestAttached(WebContentsView* parent_view) { #if defined(USE_AURA) // In aura, ScreenPositionClient doesn't work properly if we do
diff --git a/content/browser/web_contents/web_contents_view_guest.h b/content/browser/web_contents/web_contents_view_guest.h index e814410..3dfd1c8 100644 --- a/content/browser/web_contents/web_contents_view_guest.h +++ b/content/browser/web_contents/web_contents_view_guest.h
@@ -45,6 +45,7 @@ gfx::NativeView GetNativeView() const override; gfx::NativeView GetContentNativeView() const override; gfx::NativeWindow GetTopLevelNativeWindow() const override; + void GetScreenInfo(blink::WebScreenInfo* web_screen_info) const override; void GetContainerBounds(gfx::Rect* out) const override; void SizeContents(const gfx::Size& size) override; void Focus() override;
diff --git a/content/browser/web_contents/web_contents_view_mac.h b/content/browser/web_contents/web_contents_view_mac.h index b4e597b..96115ab 100644 --- a/content/browser/web_contents/web_contents_view_mac.h +++ b/content/browser/web_contents/web_contents_view_mac.h
@@ -75,6 +75,7 @@ gfx::NativeView GetNativeView() const override; gfx::NativeView GetContentNativeView() const override; gfx::NativeWindow GetTopLevelNativeWindow() const override; + void GetScreenInfo(blink::WebScreenInfo* web_screen_info) const override; void GetContainerBounds(gfx::Rect* out) const override; void SizeContents(const gfx::Size& size) override; void Focus() override;
diff --git a/content/browser/web_contents/web_contents_view_mac.mm b/content/browser/web_contents/web_contents_view_mac.mm index 90e950a..9ba342a 100644 --- a/content/browser/web_contents/web_contents_view_mac.mm +++ b/content/browser/web_contents/web_contents_view_mac.mm
@@ -30,6 +30,7 @@ #include "ui/base/clipboard/custom_data_helper.h" #import "ui/base/cocoa/focus_tracker.h" #include "ui/base/dragdrop/cocoa_dnd_util.h" +#include "ui/display/screen.h" #include "ui/gfx/image/image_skia_util_mac.h" using blink::WebDragOperation; @@ -74,8 +75,40 @@ - (content::WebContentsImpl*)webContents; @end +namespace { + +blink::WebScreenInfo GetWebScreenInfo(NSView* view) { + display::Display display = + display::Screen::GetScreen()->GetDisplayNearestWindow(view); + + NSScreen* screen = [NSScreen deepestScreen]; + + blink::WebScreenInfo results; + + results.deviceScaleFactor = static_cast<int>(display.device_scale_factor()); + results.depth = NSBitsPerPixelFromDepth([screen depth]); + results.depthPerComponent = NSBitsPerSampleFromDepth([screen depth]); + results.isMonochrome = + [[screen colorSpace] colorSpaceModel] == NSGrayColorSpaceModel; + results.rect = display.bounds(); + results.availableRect = display.work_area(); + results.orientationAngle = display.RotationAsDegree(); + results.orientationType = + content::RenderWidgetHostViewBase::GetOrientationTypeForDesktop(display); + + return results; +} + +} // namespace + namespace content { +// static +void WebContentsView::GetDefaultScreenInfo( + blink::WebScreenInfo* results) { + *results = GetWebScreenInfo(NULL); +} + WebContentsView* CreateWebContentsView( WebContentsImpl* web_contents, WebContentsViewDelegate* delegate, @@ -117,6 +150,10 @@ return window ? window : delegate_->GetNativeWindow(); } +void WebContentsViewMac::GetScreenInfo(blink::WebScreenInfo* results) const { + *results = GetWebScreenInfo(GetNativeView()); +} + void WebContentsViewMac::GetContainerBounds(gfx::Rect* out) const { NSWindow* window = [cocoa_view_.get() window]; NSRect bounds = [cocoa_view_.get() bounds];
diff --git a/content/browser/web_contents/web_contents_view_mus.cc b/content/browser/web_contents/web_contents_view_mus.cc index 98700f0..f5527d3 100644 --- a/content/browser/web_contents/web_contents_view_mus.cc +++ b/content/browser/web_contents/web_contents_view_mus.cc
@@ -62,6 +62,11 @@ return window ? window : delegate_->GetNativeWindow(); } +void WebContentsViewMus::GetScreenInfo( + blink::WebScreenInfo* web_screen_info) const { + // TODO(wjmaclean) Figure out what goes here. +} + void WebContentsViewMus::GetContainerBounds(gfx::Rect* out) const { *out = aura_window_->GetBoundsInScreen(); }
diff --git a/content/browser/web_contents/web_contents_view_mus.h b/content/browser/web_contents/web_contents_view_mus.h index 48b62db..2cc3497 100644 --- a/content/browser/web_contents/web_contents_view_mus.h +++ b/content/browser/web_contents/web_contents_view_mus.h
@@ -46,6 +46,7 @@ gfx::NativeView GetNativeView() const override; gfx::NativeView GetContentNativeView() const override; gfx::NativeWindow GetTopLevelNativeWindow() const override; + void GetScreenInfo(blink::WebScreenInfo* web_screen_info) const override; void GetContainerBounds(gfx::Rect* out) const override; void SizeContents(const gfx::Size& size) override; void Focus() override;
diff --git a/content/browser/webrtc/webrtc_constraints_browsertest.cc b/content/browser/webrtc/webrtc_constraints_browsertest.cc new file mode 100644 index 0000000..2a19b39 --- /dev/null +++ b/content/browser/webrtc/webrtc_constraints_browsertest.cc
@@ -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. + +#include <stddef.h> + +#include "base/command_line.h" +#include "content/browser/webrtc/webrtc_content_browsertest_base.h" +#include "content/public/test/browser_test_utils.h" +#include "content/public/test/content_browser_test_utils.h" +#include "content/public/test/test_utils.h" +#include "content/shell/browser/shell.h" +#include "net/test/embedded_test_server/embedded_test_server.h" + +#if defined(OS_WIN) +#include "base/win/windows_version.h" +#endif + +namespace { + +static const char kGetUserMediaAndStop[] = "getUserMediaAndStop"; + +static struct UserMediaSizes { + int min_width; + int max_width; + int min_height; + int max_height; + int min_frame_rate; + int max_frame_rate; +} const kAllUserMediaSizes[] = { + {320, 320, 180, 180, 10, 30}, + {320, 320, 240, 240, 10, 30}, + {640, 640, 360, 360, 10, 30}, + {640, 640, 480, 480, 10, 30}, + {960, 960, 720, 720, 10, 30}, + {1280, 1280, 720, 720, 10, 30}}; + +} // namespace + +namespace content { + +class WebRtcConstraintsBrowserTest + : public WebRtcContentBrowserTestBase, + public testing::WithParamInterface<UserMediaSizes> { + public: + WebRtcConstraintsBrowserTest() : user_media_(GetParam()) { + // Automatically grant device permission. + AppendUseFakeUIForMediaStreamFlag(); + } + const UserMediaSizes& user_media() const { return user_media_; } + + private: + const UserMediaSizes user_media_; +}; + +// Test fails under MSan, http://crbug.com/445745 +#if defined(MEMORY_SANITIZER) +#define MAYBE_GetUserMediaConstraints DISABLED_GetUserMediaConstraints +#else +#define MAYBE_GetUserMediaConstraints GetUserMediaConstraints +#endif +// This test calls getUserMedia in sequence with different constraints. +IN_PROC_BROWSER_TEST_P(WebRtcConstraintsBrowserTest, + MAYBE_GetUserMediaConstraints) { + ASSERT_TRUE(embedded_test_server()->Start()); + + GURL url(embedded_test_server()->GetURL("/media/getusermedia.html")); + + std::string call = GenerateGetUserMediaCall(kGetUserMediaAndStop, + user_media().min_width, + user_media().max_width, + user_media().min_height, + user_media().max_height, + user_media().min_frame_rate, + user_media().max_frame_rate); + DVLOG(1) << "Calling getUserMedia: " << call; + NavigateToURL(shell(), url); + ExecuteJavascriptAndWaitForOk(call); +} + +INSTANTIATE_TEST_CASE_P(UserMedia, + WebRtcConstraintsBrowserTest, + testing::ValuesIn(kAllUserMediaSizes)); + +} // namespace content
diff --git a/content/browser/webrtc/webrtc_getusermedia_browsertest.cc b/content/browser/webrtc/webrtc_getusermedia_browsertest.cc index 8d60451..10c17d0 100644 --- a/content/browser/webrtc/webrtc_getusermedia_browsertest.cc +++ b/content/browser/webrtc/webrtc_getusermedia_browsertest.cc
@@ -724,68 +724,4 @@ ExecuteJavascriptAndWaitForOk(call); } -namespace { - -struct UserMediaSizes { - int min_width; - int max_width; - int min_height; - int max_height; - int min_frame_rate; - int max_frame_rate; -}; - -} // namespace - -class WebRtcConstraintsBrowserTest - : public WebRtcContentBrowserTestBase, - public testing::WithParamInterface<UserMediaSizes> { - public: - WebRtcConstraintsBrowserTest() : user_media_(GetParam()) { - // Automatically grant device permission. - AppendUseFakeUIForMediaStreamFlag(); - } - const UserMediaSizes& user_media() const { return user_media_; } - - private: - UserMediaSizes user_media_; -}; - -// Test fails under MSan, http://crbug.com/445745 -#if defined(MEMORY_SANITIZER) -#define MAYBE_GetUserMediaConstraints DISABLED_GetUserMediaConstraints -#else -#define MAYBE_GetUserMediaConstraints GetUserMediaConstraints -#endif -// This test calls getUserMedia in sequence with different constraints. -IN_PROC_BROWSER_TEST_P(WebRtcConstraintsBrowserTest, - MAYBE_GetUserMediaConstraints) { - ASSERT_TRUE(embedded_test_server()->Start()); - - GURL url(embedded_test_server()->GetURL("/media/getusermedia.html")); - - std::string call = GenerateGetUserMediaCall(kGetUserMediaAndStop, - user_media().min_width, - user_media().max_width, - user_media().min_height, - user_media().max_height, - user_media().min_frame_rate, - user_media().max_frame_rate); - DVLOG(1) << "Calling getUserMedia: " << call; - NavigateToURL(shell(), url); - ExecuteJavascriptAndWaitForOk(call); -} - -static const UserMediaSizes kAllUserMediaSizes[] = { - {320, 320, 180, 180, 10, 30}, - {320, 320, 240, 240, 10, 30}, - {640, 640, 360, 360, 10, 30}, - {640, 640, 480, 480, 10, 30}, - {960, 960, 720, 720, 10, 30}, - {1280, 1280, 720, 720, 10, 30}}; - -INSTANTIATE_TEST_CASE_P(UserMedia, - WebRtcConstraintsBrowserTest, - testing::ValuesIn(kAllUserMediaSizes)); - } // namespace content
diff --git a/content/browser/websockets/websocket_impl.cc b/content/browser/websockets/websocket_impl.cc new file mode 100644 index 0000000..d391005 --- /dev/null +++ b/content/browser/websockets/websocket_impl.cc
@@ -0,0 +1,536 @@ +// 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 "content/browser/websockets/websocket_impl.h" + +#include <inttypes.h> + +#include <utility> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/single_thread_task_runner.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "base/threading/thread_task_runner_handle.h" +#include "content/browser/bad_message.h" +#include "content/browser/child_process_security_policy_impl.h" +#include "content/browser/ssl/ssl_error_handler.h" +#include "content/browser/ssl/ssl_manager.h" +#include "content/public/browser/storage_partition.h" +#include "ipc/ipc_message.h" +#include "net/base/net_errors.h" +#include "net/http/http_request_headers.h" +#include "net/http/http_response_headers.h" +#include "net/http/http_util.h" +#include "net/ssl/ssl_info.h" +#include "net/url_request/url_request_context_getter.h" +#include "net/websockets/websocket_channel.h" +#include "net/websockets/websocket_errors.h" +#include "net/websockets/websocket_event_interface.h" +#include "net/websockets/websocket_frame.h" // for WebSocketFrameHeader::OpCode +#include "net/websockets/websocket_handshake_request_info.h" +#include "net/websockets/websocket_handshake_response_info.h" +#include "url/origin.h" + +namespace content { +namespace { + +typedef net::WebSocketEventInterface::ChannelState ChannelState; + +// Convert a mojom::WebSocketMessageType to a +// net::WebSocketFrameHeader::OpCode +net::WebSocketFrameHeader::OpCode MessageTypeToOpCode( + mojom::WebSocketMessageType type) { + DCHECK(type == mojom::WebSocketMessageType::CONTINUATION || + type == mojom::WebSocketMessageType::TEXT || + type == mojom::WebSocketMessageType::BINARY); + typedef net::WebSocketFrameHeader::OpCode OpCode; + // These compile asserts verify that the same underlying values are used for + // both types, so we can simply cast between them. + static_assert( + static_cast<OpCode>(mojom::WebSocketMessageType::CONTINUATION) == + net::WebSocketFrameHeader::kOpCodeContinuation, + "enum values must match for opcode continuation"); + static_assert( + static_cast<OpCode>(mojom::WebSocketMessageType::TEXT) == + net::WebSocketFrameHeader::kOpCodeText, + "enum values must match for opcode text"); + static_assert( + static_cast<OpCode>(mojom::WebSocketMessageType::BINARY) == + net::WebSocketFrameHeader::kOpCodeBinary, + "enum values must match for opcode binary"); + return static_cast<OpCode>(type); +} + +mojom::WebSocketMessageType OpCodeToMessageType( + net::WebSocketFrameHeader::OpCode opCode) { + DCHECK(opCode == net::WebSocketFrameHeader::kOpCodeContinuation || + opCode == net::WebSocketFrameHeader::kOpCodeText || + opCode == net::WebSocketFrameHeader::kOpCodeBinary); + // This cast is guaranteed valid by the static_assert() statements above. + return static_cast<mojom::WebSocketMessageType>(opCode); +} + +} // namespace + +// Implementation of net::WebSocketEventInterface. Receives events from our +// WebSocketChannel object. +class WebSocketImpl::WebSocketEventHandler final + : public net::WebSocketEventInterface { + public: + explicit WebSocketEventHandler(WebSocketImpl* impl); + ~WebSocketEventHandler() override; + + // net::WebSocketEventInterface implementation + + ChannelState OnAddChannelResponse(const std::string& selected_subprotocol, + const std::string& extensions) override; + ChannelState OnDataFrame(bool fin, + WebSocketMessageType type, + const std::vector<char>& data) override; + ChannelState OnClosingHandshake() override; + ChannelState OnFlowControl(int64_t quota) override; + ChannelState OnDropChannel(bool was_clean, + uint16_t code, + const std::string& reason) override; + ChannelState OnFailChannel(const std::string& message) override; + ChannelState OnStartOpeningHandshake( + std::unique_ptr<net::WebSocketHandshakeRequestInfo> request) override; + ChannelState OnFinishOpeningHandshake( + std::unique_ptr<net::WebSocketHandshakeResponseInfo> response) override; + ChannelState OnSSLCertificateError( + std::unique_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> + callbacks, + const GURL& url, + const net::SSLInfo& ssl_info, + bool fatal) override; + + private: + class SSLErrorHandlerDelegate final : public SSLErrorHandler::Delegate { + public: + SSLErrorHandlerDelegate( + std::unique_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> + callbacks); + ~SSLErrorHandlerDelegate() override; + + base::WeakPtr<SSLErrorHandler::Delegate> GetWeakPtr(); + + // SSLErrorHandler::Delegate methods + void CancelSSLRequest(int error, const net::SSLInfo* ssl_info) override; + void ContinueSSLRequest() override; + + private: + std::unique_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks_; + base::WeakPtrFactory<SSLErrorHandlerDelegate> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(SSLErrorHandlerDelegate); + }; + + WebSocketImpl* const impl_; + std::unique_ptr<SSLErrorHandlerDelegate> ssl_error_handler_delegate_; + + DISALLOW_COPY_AND_ASSIGN(WebSocketEventHandler); +}; + +WebSocketImpl::WebSocketEventHandler::WebSocketEventHandler(WebSocketImpl* impl) + : impl_(impl) { + DVLOG(1) << "WebSocketEventHandler created @" + << reinterpret_cast<void*>(this); +} + +WebSocketImpl::WebSocketEventHandler::~WebSocketEventHandler() { + DVLOG(1) << "WebSocketEventHandler destroyed @" + << reinterpret_cast<void*>(this); +} + +ChannelState WebSocketImpl::WebSocketEventHandler::OnAddChannelResponse( + const std::string& selected_protocol, + const std::string& extensions) { + DVLOG(3) << "WebSocketEventHandler::OnAddChannelResponse @" + << reinterpret_cast<void*>(this) + << " selected_protocol=\"" << selected_protocol << "\"" + << " extensions=\"" << extensions << "\""; + + impl_->delegate_->OnReceivedResponseFromServer(impl_); + + impl_->client_->OnAddChannelResponse(selected_protocol, extensions); + + return net::WebSocketEventInterface::CHANNEL_ALIVE; +} + +ChannelState WebSocketImpl::WebSocketEventHandler::OnDataFrame( + bool fin, + net::WebSocketFrameHeader::OpCode type, + const std::vector<char>& data) { + DVLOG(3) << "WebSocketEventHandler::OnDataFrame @" + << reinterpret_cast<void*>(this) + << " fin=" << fin + << " type=" << type << " data is " << data.size() << " bytes"; + + // TODO(darin): Avoid this copy. + mojo::Array<uint8_t> data_to_pass(data.size()); + std::copy(data.begin(), data.end(), data_to_pass.begin()); + + impl_->client_->OnDataFrame(fin, OpCodeToMessageType(type), + std::move(data_to_pass)); + + return net::WebSocketEventInterface::CHANNEL_ALIVE; +} + +ChannelState WebSocketImpl::WebSocketEventHandler::OnClosingHandshake() { + DVLOG(3) << "WebSocketEventHandler::OnClosingHandshake @" + << reinterpret_cast<void*>(this); + + impl_->client_->OnClosingHandshake(); + + return net::WebSocketEventInterface::CHANNEL_ALIVE; +} + +ChannelState WebSocketImpl::WebSocketEventHandler::OnFlowControl( + int64_t quota) { + DVLOG(3) << "WebSocketEventHandler::OnFlowControl @" + << reinterpret_cast<void*>(this) + << " quota=" << quota; + + impl_->client_->OnFlowControl(quota); + + return net::WebSocketEventInterface::CHANNEL_ALIVE; +} + +ChannelState WebSocketImpl::WebSocketEventHandler::OnDropChannel( + bool was_clean, + uint16_t code, + const std::string& reason) { + DVLOG(3) << "WebSocketEventHandler::OnDropChannel @" + << reinterpret_cast<void*>(this) + << " was_clean=" << was_clean << " code=" << code + << " reason=\"" << reason << "\""; + + impl_->client_->OnDropChannel(was_clean, code, reason); + + // net::WebSocketChannel requires that we delete it at this point. + impl_->channel_.reset(); + + return net::WebSocketEventInterface::CHANNEL_DELETED; +} + +ChannelState WebSocketImpl::WebSocketEventHandler::OnFailChannel( + const std::string& message) { + DVLOG(3) << "WebSocketEventHandler::OnFailChannel @" + << reinterpret_cast<void*>(this) << " message=\"" << message << "\""; + + impl_->client_->OnFailChannel(message); + + // net::WebSocketChannel requires that we delete it at this point. + impl_->channel_.reset(); + + return net::WebSocketEventInterface::CHANNEL_DELETED; +} + +ChannelState WebSocketImpl::WebSocketEventHandler::OnStartOpeningHandshake( + std::unique_ptr<net::WebSocketHandshakeRequestInfo> request) { + bool should_send = + ChildProcessSecurityPolicyImpl::GetInstance()->CanReadRawCookies( + impl_->delegate_->GetClientProcessId()); + + DVLOG(3) << "WebSocketEventHandler::OnStartOpeningHandshake @" + << reinterpret_cast<void*>(this) << " should_send=" << should_send; + + if (!should_send) + return WebSocketEventInterface::CHANNEL_ALIVE; + + mojom::WebSocketHandshakeRequestPtr request_to_pass( + mojom::WebSocketHandshakeRequest::New()); + request_to_pass->url.Swap(&request->url); + net::HttpRequestHeaders::Iterator it(request->headers); + while (it.GetNext()) { + mojom::HttpHeaderPtr header(mojom::HttpHeader::New()); + header->name = it.name(); + header->value = it.value(); + request_to_pass->headers.push_back(std::move(header)); + } + request_to_pass->headers_text = + base::StringPrintf("GET %s HTTP/1.1\r\n", + request_to_pass->url.spec().c_str()) + + request->headers.ToString(); + + impl_->client_->OnStartOpeningHandshake(std::move(request_to_pass)); + + return WebSocketEventInterface::CHANNEL_ALIVE; +} + +ChannelState WebSocketImpl::WebSocketEventHandler::OnFinishOpeningHandshake( + std::unique_ptr<net::WebSocketHandshakeResponseInfo> response) { + bool should_send = + ChildProcessSecurityPolicyImpl::GetInstance()->CanReadRawCookies( + impl_->delegate_->GetClientProcessId()); + + DVLOG(3) << "WebSocketEventHandler::OnFinishOpeningHandshake " + << reinterpret_cast<void*>(this) << " should_send=" << should_send; + + if (!should_send) + return WebSocketEventInterface::CHANNEL_ALIVE; + + mojom::WebSocketHandshakeResponsePtr response_to_pass( + mojom::WebSocketHandshakeResponse::New()); + response_to_pass->url.Swap(&response->url); + response_to_pass->status_code = response->status_code; + response_to_pass->status_text = response->status_text; + size_t iter = 0; + std::string name, value; + while (response->headers->EnumerateHeaderLines(&iter, &name, &value)) { + mojom::HttpHeaderPtr header(mojom::HttpHeader::New()); + header->name = name; + header->value = value; + response_to_pass->headers.push_back(std::move(header)); + } + response_to_pass->headers_text = + net::HttpUtil::ConvertHeadersBackToHTTPResponse( + response->headers->raw_headers()); + + impl_->client_->OnFinishOpeningHandshake(std::move(response_to_pass)); + + return WebSocketEventInterface::CHANNEL_ALIVE; +} + +ChannelState WebSocketImpl::WebSocketEventHandler::OnSSLCertificateError( + std::unique_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> callbacks, + const GURL& url, + const net::SSLInfo& ssl_info, + bool fatal) { + DVLOG(3) << "WebSocketEventHandler::OnSSLCertificateError" + << reinterpret_cast<void*>(this) << " url=" << url.spec() + << " cert_status=" << ssl_info.cert_status << " fatal=" << fatal; + ssl_error_handler_delegate_.reset( + new SSLErrorHandlerDelegate(std::move(callbacks))); + SSLManager::OnSSLCertificateSubresourceError( + ssl_error_handler_delegate_->GetWeakPtr(), + url, + impl_->delegate_->GetClientProcessId(), + impl_->frame_id_, + ssl_info, + fatal); + // The above method is always asynchronous. + return WebSocketEventInterface::CHANNEL_ALIVE; +} + +WebSocketImpl::WebSocketEventHandler::SSLErrorHandlerDelegate:: + SSLErrorHandlerDelegate( + std::unique_ptr<net::WebSocketEventInterface::SSLErrorCallbacks> + callbacks) + : callbacks_(std::move(callbacks)), weak_ptr_factory_(this) {} + +WebSocketImpl::WebSocketEventHandler::SSLErrorHandlerDelegate:: + ~SSLErrorHandlerDelegate() {} + +base::WeakPtr<SSLErrorHandler::Delegate> +WebSocketImpl::WebSocketEventHandler::SSLErrorHandlerDelegate::GetWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); +} + +void WebSocketImpl::WebSocketEventHandler::SSLErrorHandlerDelegate:: + CancelSSLRequest(int error, const net::SSLInfo* ssl_info) { + DVLOG(3) << "SSLErrorHandlerDelegate::CancelSSLRequest" + << " error=" << error + << " cert_status=" << (ssl_info ? ssl_info->cert_status + : static_cast<net::CertStatus>(-1)); + callbacks_->CancelSSLRequest(error, ssl_info); +} + +void WebSocketImpl::WebSocketEventHandler::SSLErrorHandlerDelegate:: + ContinueSSLRequest() { + DVLOG(3) << "SSLErrorHandlerDelegate::ContinueSSLRequest"; + callbacks_->ContinueSSLRequest(); +} + +WebSocketImpl::WebSocketImpl( + Delegate* delegate, + mojom::WebSocketRequest request, + int frame_id, + base::TimeDelta delay) + : delegate_(delegate), + binding_(this, std::move(request)), + delay_(delay), + pending_flow_control_quota_(0), + frame_id_(frame_id), + handshake_succeeded_(false), + weak_ptr_factory_(this) { + binding_.set_connection_error_handler( + base::Bind(&WebSocketImpl::OnConnectionError, base::Unretained(this))); +} + +WebSocketImpl::~WebSocketImpl() {} + +void WebSocketImpl::GoAway() { + StartClosingHandshake(static_cast<uint16_t>(net::kWebSocketErrorGoingAway), + ""); +} + +void WebSocketImpl::AddChannelRequest( + const GURL& socket_url, + mojo::Array<mojo::String> requested_protocols_mojo, + const url::Origin& origin, + const GURL& first_party_for_cookies, + const mojo::String& user_agent_override, + mojom::WebSocketClientPtr client) { + // Convert to STL types. + std::vector<std::string> requested_protocols( + requested_protocols_mojo.begin(), + requested_protocols_mojo.end()); + + DVLOG(3) << "WebSocketImpl::AddChannelRequest @" + << reinterpret_cast<void*>(this) + << " socket_url=\"" << socket_url << "\" requested_protocols=\"" + << base::JoinString(requested_protocols, ", ") + << "\" origin=\"" << origin + << "\" first_party_for_cookies=\"" << first_party_for_cookies + << "\" user_agent_override=\"" << user_agent_override + << "\""; + + if (client_ || !client) { + bad_message::ReceivedBadMessage( + delegate_->GetClientProcessId(), + bad_message::WSI_UNEXPECTED_ADD_CHANNEL_REQUEST); + return; + } + + client_ = std::move(client); + + DCHECK(!channel_); + if (delay_ > base::TimeDelta()) { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::Bind(&WebSocketImpl::AddChannel, + weak_ptr_factory_.GetWeakPtr(), + socket_url, + requested_protocols, + origin, + first_party_for_cookies, + user_agent_override), + delay_); + } else { + AddChannel(socket_url, requested_protocols, origin, first_party_for_cookies, + user_agent_override); + } +} + +void WebSocketImpl::SendFrame(bool fin, mojom::WebSocketMessageType type, + mojo::Array<uint8_t> data) { + DVLOG(3) << "WebSocketImpl::SendFrame @" + << reinterpret_cast<void*>(this) << " fin=" << fin + << " type=" << type << " data is " << data.size() << " bytes"; + + if (!channel_) { + // The client should not be sending us frames until after we've informed + // it that the channel has been opened (OnAddChannelResponse). + if (handshake_succeeded_) { + DVLOG(1) << "Dropping frame sent to closed websocket"; + } else { + bad_message::ReceivedBadMessage( + delegate_->GetClientProcessId(), + bad_message::WSI_UNEXPECTED_SEND_FRAME); + } + return; + } + + // TODO(darin): Avoid this copy. + std::vector<char> data_to_pass(data.size()); + std::copy(data.begin(), data.end(), data_to_pass.begin()); + + channel_->SendFrame(fin, MessageTypeToOpCode(type), data_to_pass); +} + +void WebSocketImpl::SendFlowControl(int64_t quota) { + DVLOG(3) << "WebSocketImpl::OnFlowControl @" + << reinterpret_cast<void*>(this) << " quota=" << quota; + + if (!channel_) { + // WebSocketChannel is not yet created due to the delay introduced by + // per-renderer WebSocket throttling. + // SendFlowControl() is called after WebSocketChannel is created. + pending_flow_control_quota_ += quota; + return; + } + + ignore_result(channel_->SendFlowControl(quota)); +} + +void WebSocketImpl::StartClosingHandshake(uint16_t code, + const mojo::String& reason) { + DVLOG(3) << "WebSocketImpl::StartClosingHandshake @" + << reinterpret_cast<void*>(this) + << " code=" << code << " reason=\"" << reason << "\""; + + if (!channel_) { + // WebSocketChannel is not yet created due to the delay introduced by + // per-renderer WebSocket throttling. + if (client_) + client_->OnDropChannel(false, net::kWebSocketErrorAbnormalClosure, ""); + return; + } + + ignore_result(channel_->StartClosingHandshake(code, reason)); +} + +void WebSocketImpl::OnConnectionError() { + DVLOG(3) << "WebSocketImpl::OnConnectionError @" + << reinterpret_cast<void*>(this); + + delegate_->OnLostConnectionToClient(this); +} + +void WebSocketImpl::AddChannel( + const GURL& socket_url, + const std::vector<std::string>& requested_protocols, + const url::Origin& origin, + const GURL& first_party_for_cookies, + const std::string& user_agent_override) { + DVLOG(3) << "WebSocketImpl::AddChannel @" + << reinterpret_cast<void*>(this) + << " socket_url=\"" << socket_url + << "\" requested_protocols=\"" + << base::JoinString(requested_protocols, ", ") + << "\" origin=\"" << origin + << "\" first_party_for_cookies=\"" << first_party_for_cookies + << "\" user_agent_override=\"" << user_agent_override + << "\""; + + DCHECK(!channel_); + + StoragePartition* partition = delegate_->GetStoragePartition(); + + std::unique_ptr<net::WebSocketEventInterface> event_interface( + new WebSocketEventHandler(this)); + channel_.reset( + new net::WebSocketChannel( + std::move(event_interface), + partition->GetURLRequestContext()->GetURLRequestContext())); + + int64_t quota = pending_flow_control_quota_; + pending_flow_control_quota_ = 0; + + std::string additional_headers; + if (!user_agent_override.empty()) { + if (!net::HttpUtil::IsValidHeaderValue(user_agent_override)) { + bad_message::ReceivedBadMessage( + delegate_->GetClientProcessId(), + bad_message::WSI_INVALID_HEADER_VALUE); + return; + } + additional_headers = base::StringPrintf("%s:%s", + net::HttpRequestHeaders::kUserAgent, + user_agent_override.c_str()); + } + channel_->SendAddChannelRequest(socket_url, requested_protocols, origin, + first_party_for_cookies, additional_headers); + if (quota > 0) + SendFlowControl(quota); +} + +} // namespace content
diff --git a/content/browser/websockets/websocket_impl.h b/content/browser/websockets/websocket_impl.h new file mode 100644 index 0000000..fa3b5d8 --- /dev/null +++ b/content/browser/websockets/websocket_impl.h
@@ -0,0 +1,112 @@ +// 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 CONTENT_BROWSER_WEBSOCKETS_WEBSOCKET_IMPL_H_ +#define CONTENT_BROWSER_WEBSOCKETS_WEBSOCKET_IMPL_H_ + +#include <stdint.h> + +#include <memory> +#include <string> +#include <vector> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/time/time.h" +#include "content/common/content_export.h" +#include "content/common/websocket.mojom.h" +#include "mojo/public/cpp/bindings/binding.h" + +class GURL; + +namespace url { +class Origin; +} // namespace url + +namespace net { +class WebSocketChannel; +} // namespace net + +namespace content { +class StoragePartition; + +// Host of net::WebSocketChannel. +class CONTENT_EXPORT WebSocketImpl + : NON_EXPORTED_BASE(public mojom::WebSocket) { + public: + class Delegate { + public: + virtual ~Delegate() {} + virtual int GetClientProcessId() = 0; + virtual StoragePartition* GetStoragePartition() = 0; + virtual void OnReceivedResponseFromServer(WebSocketImpl* impl) = 0; + virtual void OnLostConnectionToClient(WebSocketImpl* impl) = 0; + }; + + WebSocketImpl(Delegate* delegate, + mojom::WebSocketRequest request, + int frame_id, + base::TimeDelta delay); + ~WebSocketImpl() override; + + // The renderer process is going away. + // This function is virtual for testing. + virtual void GoAway(); + + // mojom::WebSocket methods: + void AddChannelRequest(const GURL& url, + mojo::Array<mojo::String> requested_protocols, + const url::Origin& origin, + const GURL& first_party_for_cookies, + const mojo::String& user_agent_override, + mojom::WebSocketClientPtr client) override; + void SendFrame(bool fin, mojom::WebSocketMessageType type, + mojo::Array<uint8_t> data) override; + void SendFlowControl(int64_t quota) override; + void StartClosingHandshake(uint16_t code, + const mojo::String& reason) override; + + bool handshake_succeeded() const { return handshake_succeeded_; } + void OnHandshakeSucceeded() { handshake_succeeded_ = true; } + + protected: + class WebSocketEventHandler; + + void OnConnectionError(); + void AddChannel(const GURL& socket_url, + const std::vector<std::string>& requested_protocols, + const url::Origin& origin, + const GURL& first_party_for_cookies, + const std::string& user_agent_override); + + Delegate* delegate_; + mojo::Binding<mojom::WebSocket> binding_; + + mojom::WebSocketClientPtr client_; + + // The channel we use to send events to the network. + std::unique_ptr<net::WebSocketChannel> channel_; + + // Delay used for per-renderer WebSocket throttling. + base::TimeDelta delay_; + + // SendFlowControl() is delayed when OnFlowControl() is called before + // AddChannel() is called. + // Zero indicates there is no pending SendFlowControl(). + int64_t pending_flow_control_quota_; + + int frame_id_; + + // handshake_succeeded_ is set and used by WebSocketManager to manage + // counters for per-renderer WebSocket throttling. + bool handshake_succeeded_; + + base::WeakPtrFactory<WebSocketImpl> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(WebSocketImpl); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_WEBSOCKETS_WEBSOCKET_IMPL_H_
diff --git a/content/browser/websockets/websocket_manager.cc b/content/browser/websockets/websocket_manager.cc new file mode 100644 index 0000000..1d98ba42 --- /dev/null +++ b/content/browser/websockets/websocket_manager.cc
@@ -0,0 +1,195 @@ +// 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 "content/browser/websockets/websocket_manager.h" + +#include <algorithm> +#include <string> +#include <vector> + +#include "base/callback.h" +#include "base/logging.h" +#include "base/numerics/safe_conversions.h" +#include "base/rand_util.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/render_process_host_observer.h" +#include "services/shell/public/cpp/interface_registry.h" + +namespace content { + +namespace { + +const char kWebSocketManagerKeyName[] = "web_socket_manager"; + +// Max number of pending connections per WebSocketManager used for per-renderer +// WebSocket throttling. +const int kMaxPendingWebSocketConnections = 255; + +} // namespace + +class WebSocketManager::Handle : public base::SupportsUserData::Data, + public RenderProcessHostObserver { + public: + explicit Handle(WebSocketManager* manager) : manager_(manager) {} + + ~Handle() override { + DCHECK(!manager_) << "Should have received RenderProcessHostDestroyed"; + } + + WebSocketManager* manager() const { return manager_; } + + // The network stack could be shutdown after this notification, so be sure to + // stop using it before then. + void RenderProcessHostDestroyed(RenderProcessHost* host) override { + BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, manager_); + manager_ = nullptr; + } + + private: + WebSocketManager* manager_; +}; + +// static +void WebSocketManager::CreateWebSocket(int process_id, int frame_id, + mojom::WebSocketRequest request) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + RenderProcessHost* host = RenderProcessHost::FromID(process_id); + DCHECK(host); + + // Maintain a WebSocketManager per RenderProcessHost. While the instance of + // WebSocketManager is allocated on the UI thread, it must only be used and + // deleted from the IO thread. + + Handle* handle = + static_cast<Handle*>(host->GetUserData(kWebSocketManagerKeyName)); + if (!handle) { + handle = new Handle( + new WebSocketManager(process_id, host->GetStoragePartition())); + host->SetUserData(kWebSocketManagerKeyName, handle); + host->AddObserver(handle); + } else { + DCHECK(handle->manager()); + } + + BrowserThread::PostTask( + BrowserThread::IO, + FROM_HERE, + base::Bind(&WebSocketManager::DoCreateWebSocket, + base::Unretained(handle->manager()), + frame_id, + base::Passed(&request))); +} + +WebSocketManager::WebSocketManager(int process_id, + StoragePartition* storage_partition) + : process_id_(process_id), + storage_partition_(storage_partition), + num_pending_connections_(0), + num_current_succeeded_connections_(0), + num_previous_succeeded_connections_(0), + num_current_failed_connections_(0), + num_previous_failed_connections_(0) {} + +WebSocketManager::~WebSocketManager() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + for (auto impl : impls_) { + impl->GoAway(); + delete impl; + } +} + +void WebSocketManager::DoCreateWebSocket(int frame_id, + mojom::WebSocketRequest request) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + if (num_pending_connections_ >= kMaxPendingWebSocketConnections) { + // Too many websockets! By returning here, we let |request| die, which + // will be observed by the client as Mojo connection error. + return; + } + + // Keep all WebSocketImpls alive until either the client drops its + // connection (see OnLostConnectionToClient) or we need to shutdown. + + impls_.insert(CreateWebSocketImpl(this, std::move(request), frame_id, + CalculateDelay())); + ++num_pending_connections_; + + if (!throttling_period_timer_.IsRunning()) { + throttling_period_timer_.Start( + FROM_HERE, + base::TimeDelta::FromMinutes(2), + this, + &WebSocketManager::ThrottlingPeriodTimerCallback); + } +} + +// Calculate delay as described in the per-renderer WebSocket throttling +// design doc: https://goo.gl/tldFNn +base::TimeDelta WebSocketManager::CalculateDelay() const { + int64_t f = num_previous_failed_connections_ + + num_current_failed_connections_; + int64_t s = num_previous_succeeded_connections_ + + num_current_succeeded_connections_; + int p = num_pending_connections_; + return base::TimeDelta::FromMilliseconds( + base::RandInt(1000, 5000) * + (1 << std::min(p + f / (s + 1), INT64_C(16))) / 65536); +} + +void WebSocketManager::ThrottlingPeriodTimerCallback() { + num_previous_failed_connections_ = num_current_failed_connections_; + num_current_failed_connections_ = 0; + + num_previous_succeeded_connections_ = num_current_succeeded_connections_; + num_current_succeeded_connections_ = 0; + + if (num_pending_connections_ == 0 && + num_previous_failed_connections_ == 0 && + num_previous_succeeded_connections_ == 0) { + throttling_period_timer_.Stop(); + } +} + +WebSocketImpl* WebSocketManager::CreateWebSocketImpl( + WebSocketImpl::Delegate* delegate, + mojom::WebSocketRequest request, + int frame_id, + base::TimeDelta delay) { + return new WebSocketImpl(delegate, std::move(request), frame_id, delay); +} + +int WebSocketManager::GetClientProcessId() { + return process_id_; +} + +StoragePartition* WebSocketManager::GetStoragePartition() { + return storage_partition_; +} + +void WebSocketManager::OnReceivedResponseFromServer(WebSocketImpl* impl) { + // The server accepted this WebSocket connection. + impl->OnHandshakeSucceeded(); + --num_pending_connections_; + DCHECK_GE(num_pending_connections_, 0); + ++num_current_succeeded_connections_; +} + +void WebSocketManager::OnLostConnectionToClient(WebSocketImpl* impl) { + // The client is no longer interested in this WebSocket. + if (!impl->handshake_succeeded()) { + // Update throttling counters (failure). + --num_pending_connections_; + DCHECK_GE(num_pending_connections_, 0); + ++num_current_failed_connections_; + } + impl->GoAway(); + impls_.erase(impl); + delete impl; +} + +} // namespace content
diff --git a/content/browser/websockets/websocket_manager.h b/content/browser/websockets/websocket_manager.h new file mode 100644 index 0000000..4047e435 --- /dev/null +++ b/content/browser/websockets/websocket_manager.h
@@ -0,0 +1,86 @@ +// 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 CONTENT_BROWSER_WEBSOCKETS_WEBSOCKET_MANAGER_H_ +#define CONTENT_BROWSER_WEBSOCKETS_WEBSOCKET_MANAGER_H_ + +#include <set> + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/timer/timer.h" +#include "content/browser/websockets/websocket_impl.h" +#include "content/common/content_export.h" + +namespace shell { +class InterfaceRegistry; +} // namespace shell + +namespace content { +class StoragePartition; + +// The WebSocketManager is a per child process instance that manages the +// lifecycle of WebSocketImpl objects. It is responsible for creating +// WebSocketImpl objects for each WebSocketRequest and throttling the number of +// WebSocketImpl objects in use. +class CONTENT_EXPORT WebSocketManager + : NON_EXPORTED_BASE(public WebSocketImpl::Delegate) { + public: + // Called on the UI thread: + static void CreateWebSocket(int process_id, int frame_id, + mojom::WebSocketRequest request); + + protected: + class Handle; + friend class base::DeleteHelper<WebSocketManager>; + + // Called on the UI thread: + WebSocketManager(int process_id, StoragePartition* storage_partition); + + // All other methods must run on the IO thread. + + ~WebSocketManager() override; + void DoCreateWebSocket(int frame_id, mojom::WebSocketRequest request); + base::TimeDelta CalculateDelay() const; + void ThrottlingPeriodTimerCallback(); + + // This is virtual to support testing. + virtual WebSocketImpl* CreateWebSocketImpl(WebSocketImpl::Delegate* delegate, + mojom::WebSocketRequest request, + int frame_id, + base::TimeDelta delay); + + // WebSocketImpl::Delegate methods: + int GetClientProcessId() override; + StoragePartition* GetStoragePartition() override; + void OnReceivedResponseFromServer(WebSocketImpl* impl) override; + void OnLostConnectionToClient(WebSocketImpl* impl) override; + + int process_id_; + StoragePartition* storage_partition_; + + std::set<WebSocketImpl*> impls_; + + // Timer and counters for per-renderer WebSocket throttling. + base::RepeatingTimer throttling_period_timer_; + + // The current number of pending connections. + int num_pending_connections_; + + // The number of handshakes that failed in the current and previous time + // period. + int64_t num_current_succeeded_connections_; + int64_t num_previous_succeeded_connections_; + + // The number of handshakes that succeeded in the current and previous time + // period. + int64_t num_current_failed_connections_; + int64_t num_previous_failed_connections_; + + DISALLOW_COPY_AND_ASSIGN(WebSocketManager); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_WEBSOCKETS_WEBSOCKET_MANAGER_H_
diff --git a/content/browser/websockets/websocket_manager_unittest.cc b/content/browser/websockets/websocket_manager_unittest.cc new file mode 100644 index 0000000..fc5f94f --- /dev/null +++ b/content/browser/websockets/websocket_manager_unittest.cc
@@ -0,0 +1,242 @@ +// 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 <algorithm> +#include <memory> +#include <vector> + +#include "content/browser/websockets/websocket_manager.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "ipc/ipc_message.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" +#include "url/origin.h" + +namespace content { +namespace { + +// This number is unlikely to occur by chance. +static const int kMagicRenderProcessId = 506116062; + +class TestWebSocketImpl : public WebSocketImpl { + public: + TestWebSocketImpl(Delegate* delegate, + mojom::WebSocketRequest request, + int frame_id, + base::TimeDelta delay) + : WebSocketImpl(delegate, std::move(request), frame_id, delay) {} + + base::TimeDelta delay() const { return delay_; } + + void SimulateConnectionError() { + OnConnectionError(); + } +}; + +class TestWebSocketManager : public WebSocketManager { + public: + TestWebSocketManager() + : WebSocketManager(kMagicRenderProcessId, nullptr) {} + + const std::vector<TestWebSocketImpl*>& sockets() const { + return sockets_; + } + + int num_pending_connections() const { + return num_pending_connections_; + } + int64_t num_failed_connections() const { + return num_current_failed_connections_ + num_previous_failed_connections_; + } + int64_t num_succeeded_connections() const { + return num_current_succeeded_connections_ + + num_previous_succeeded_connections_; + } + + void DoCreateWebSocket(mojom::WebSocketRequest request) { + WebSocketManager::DoCreateWebSocket(MSG_ROUTING_NONE, std::move(request)); + } + + private: + WebSocketImpl* CreateWebSocketImpl(WebSocketImpl::Delegate* delegate, + mojom::WebSocketRequest request, + int frame_id, + base::TimeDelta delay) override { + TestWebSocketImpl* impl = + new TestWebSocketImpl(delegate, std::move(request), frame_id, delay); + // We keep a vector of sockets here to track their creation order. + sockets_.push_back(impl); + return impl; + } + + void OnLostConnectionToClient(WebSocketImpl* impl) override { + auto it = std::find(sockets_.begin(), sockets_.end(), + static_cast<TestWebSocketImpl*>(impl)); + ASSERT_TRUE(it != sockets_.end()); + sockets_.erase(it); + + WebSocketManager::OnLostConnectionToClient(impl); + } + + std::vector<TestWebSocketImpl*> sockets_; +}; + +class WebSocketManagerTest : public ::testing::Test { + public: + WebSocketManagerTest() + : thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) { + websocket_manager_.reset(new TestWebSocketManager()); + } + + void AddMultipleChannels(int number_of_channels) { + for (int i = 0; i < number_of_channels; ++i) { + mojom::WebSocketPtr websocket; + websocket_manager_->DoCreateWebSocket(mojo::GetProxy(&websocket)); + } + } + + void AddAndCancelMultipleChannels(int number_of_channels) { + for (int i = 0; i < number_of_channels; ++i) { + mojom::WebSocketPtr websocket; + websocket_manager_->DoCreateWebSocket(mojo::GetProxy(&websocket)); + websocket_manager_->sockets().back()->SimulateConnectionError(); + } + } + + TestWebSocketManager* websocket_manager() { return websocket_manager_.get(); } + + private: + TestBrowserThreadBundle thread_bundle_; + std::unique_ptr<TestWebSocketManager> websocket_manager_; +}; + +TEST_F(WebSocketManagerTest, Construct) { + // Do nothing. +} + +TEST_F(WebSocketManagerTest, CreateWebSocket) { + mojom::WebSocketPtr websocket; + + websocket_manager()->DoCreateWebSocket(mojo::GetProxy(&websocket)); + + EXPECT_EQ(1U, websocket_manager()->sockets().size()); +} + +TEST_F(WebSocketManagerTest, SendFrameButNotConnectedYet) { + mojom::WebSocketPtr websocket; + + websocket_manager()->DoCreateWebSocket(mojo::GetProxy(&websocket)); + + // This should not crash. + mojo::Array<uint8_t> data; + websocket->SendFrame( + true, mojom::WebSocketMessageType::TEXT, std::move(data)); +} + +TEST_F(WebSocketManagerTest, DelayFor4thPendingConnectionIsZero) { + AddMultipleChannels(4); + + EXPECT_EQ(4, websocket_manager()->num_pending_connections()); + EXPECT_EQ(0, websocket_manager()->num_failed_connections()); + EXPECT_EQ(0, websocket_manager()->num_succeeded_connections()); + + ASSERT_EQ(4U, websocket_manager()->sockets().size()); + EXPECT_EQ(base::TimeDelta(), websocket_manager()->sockets()[3]->delay()); +} + +TEST_F(WebSocketManagerTest, DelayFor8thPendingConnectionIsNonZero) { + AddMultipleChannels(8); + + EXPECT_EQ(8, websocket_manager()->num_pending_connections()); + EXPECT_EQ(0, websocket_manager()->num_failed_connections()); + EXPECT_EQ(0, websocket_manager()->num_succeeded_connections()); + + ASSERT_EQ(8U, websocket_manager()->sockets().size()); + EXPECT_LT(base::TimeDelta(), websocket_manager()->sockets()[7]->delay()); +} + +TEST_F(WebSocketManagerTest, DelayFor17thPendingConnection) { + AddMultipleChannels(17); + + EXPECT_EQ(17, websocket_manager()->num_pending_connections()); + EXPECT_EQ(0, websocket_manager()->num_failed_connections()); + EXPECT_EQ(0, websocket_manager()->num_succeeded_connections()); + + ASSERT_EQ(17U, websocket_manager()->sockets().size()); + EXPECT_LE(base::TimeDelta::FromMilliseconds(1000), + websocket_manager()->sockets()[16]->delay()); + EXPECT_GE(base::TimeDelta::FromMilliseconds(5000), + websocket_manager()->sockets()[16]->delay()); +} + +// The 256th connection is rejected by per-renderer WebSocket throttling. +// This is not counted as a failure. +TEST_F(WebSocketManagerTest, Rejects256thPendingConnection) { + AddMultipleChannels(256); + + EXPECT_EQ(255, websocket_manager()->num_pending_connections()); + EXPECT_EQ(0, websocket_manager()->num_failed_connections()); + EXPECT_EQ(0, websocket_manager()->num_succeeded_connections()); + + ASSERT_EQ(255U, websocket_manager()->sockets().size()); +} + +TEST_F(WebSocketManagerTest, DelayIsZeroAfter3FailedConnections) { + AddAndCancelMultipleChannels(3); + + EXPECT_EQ(0, websocket_manager()->num_pending_connections()); + EXPECT_EQ(3, websocket_manager()->num_failed_connections()); + EXPECT_EQ(0, websocket_manager()->num_succeeded_connections()); + + AddMultipleChannels(1); + + ASSERT_EQ(1U, websocket_manager()->sockets().size()); + EXPECT_EQ(base::TimeDelta(), websocket_manager()->sockets()[0]->delay()); +} + +TEST_F(WebSocketManagerTest, DelayIsNonZeroAfter7FailedConnections) { + AddAndCancelMultipleChannels(7); + + EXPECT_EQ(0, websocket_manager()->num_pending_connections()); + EXPECT_EQ(7, websocket_manager()->num_failed_connections()); + EXPECT_EQ(0, websocket_manager()->num_succeeded_connections()); + + AddMultipleChannels(1); + + ASSERT_EQ(1U, websocket_manager()->sockets().size()); + EXPECT_LT(base::TimeDelta(), websocket_manager()->sockets()[0]->delay()); +} + +TEST_F(WebSocketManagerTest, DelayAfter16FailedConnections) { + AddAndCancelMultipleChannels(16); + + EXPECT_EQ(0, websocket_manager()->num_pending_connections()); + EXPECT_EQ(16, websocket_manager()->num_failed_connections()); + EXPECT_EQ(0, websocket_manager()->num_succeeded_connections()); + + AddMultipleChannels(1); + + ASSERT_EQ(1U, websocket_manager()->sockets().size()); + EXPECT_LE(base::TimeDelta::FromMilliseconds(1000), + websocket_manager()->sockets()[0]->delay()); + EXPECT_GE(base::TimeDelta::FromMilliseconds(5000), + websocket_manager()->sockets()[0]->delay()); +} + +TEST_F(WebSocketManagerTest, NotRejectedAfter255FailedConnections) { + AddAndCancelMultipleChannels(255); + + EXPECT_EQ(0, websocket_manager()->num_pending_connections()); + EXPECT_EQ(255, websocket_manager()->num_failed_connections()); + EXPECT_EQ(0, websocket_manager()->num_succeeded_connections()); + + AddMultipleChannels(1); + + EXPECT_EQ(1, websocket_manager()->num_pending_connections()); + EXPECT_EQ(255, websocket_manager()->num_failed_connections()); + EXPECT_EQ(0, websocket_manager()->num_succeeded_connections()); +} + +} // namespace +} // namespace content
diff --git a/content/child/OWNERS b/content/child/OWNERS index 3d62269f..f04dee2 100644 --- a/content/child/OWNERS +++ b/content/child/OWNERS
@@ -4,11 +4,6 @@ # AppCache per-file appcache*=michaeln@chromium.org -# WebSocket -per-file *websocket*=ricea@chromium.org -per-file *websocket*=tyoshino@chromium.org -per-file *websocket*=yhirano@chromium.org - # WebSQL per-file database_*=jsbell@chromium.org per-file database_*=michaeln@chromium.org
diff --git a/content/child/blink_platform_impl.cc b/content/child/blink_platform_impl.cc index 2123110..55fefec9 100644 --- a/content/child/blink_platform_impl.cc +++ b/content/child/blink_platform_impl.cc
@@ -47,7 +47,6 @@ #include "content/child/thread_safe_sender.h" #include "content/child/web_url_loader_impl.h" #include "content/child/web_url_request_util.h" -#include "content/child/websocket_bridge.h" #include "content/child/worker_thread_registry.h" #include "content/public/common/content_client.h" #include "net/base/data_url.h" @@ -409,10 +408,6 @@ BlinkPlatformImpl::~BlinkPlatformImpl() { } -blink::WebSocketHandle* BlinkPlatformImpl::createWebSocketHandle() { - return new WebSocketBridge; -} - WebString BlinkPlatformImpl::userAgent() { return blink::WebString::fromUTF8(GetContentClient()->GetUserAgent()); }
diff --git a/content/child/blink_platform_impl.h b/content/child/blink_platform_impl.h index ed2839e9..acd1f85 100644 --- a/content/child/blink_platform_impl.h +++ b/content/child/blink_platform_impl.h
@@ -85,7 +85,6 @@ size_t maxDecodedImageBytes() override; uint32_t getUniqueIdForProcess() override; - blink::WebSocketHandle* createWebSocketHandle() override; blink::WebString userAgent() override; blink::WebData parseDataURL(const blink::WebURL& url, blink::WebString& mimetype,
diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc index 562ebf8..8d3bd6c 100644 --- a/content/child/child_thread_impl.cc +++ b/content/child/child_thread_impl.cc
@@ -49,8 +49,6 @@ #include "content/child/resource_dispatcher.h" #include "content/child/service_worker/service_worker_message_filter.h" #include "content/child/thread_safe_sender.h" -#include "content/child/websocket_dispatcher.h" -#include "content/child/websocket_message_filter.h" #include "content/common/child_process_messages.h" #include "content/common/in_process_child_thread_params.h" #include "content/common/mojo/constants.h" @@ -514,7 +512,6 @@ resource_dispatcher_.reset(new ResourceDispatcher( this, message_loop()->task_runner())); - websocket_dispatcher_.reset(new WebSocketDispatcher); file_system_dispatcher_.reset(new FileSystemDispatcher()); histogram_message_filter_ = new ChildHistogramMessageFilter(); @@ -532,16 +529,12 @@ new NotificationDispatcher(thread_safe_sender_.get()); push_dispatcher_ = new PushDispatcher(thread_safe_sender_.get()); - websocket_message_filter_ = - new WebSocketMessageFilter(websocket_dispatcher_.get()); - channel_->AddFilter(histogram_message_filter_.get()); channel_->AddFilter(resource_message_filter_.get()); channel_->AddFilter(quota_message_filter_->GetFilter()); channel_->AddFilter(notification_dispatcher_->GetFilter()); channel_->AddFilter(push_dispatcher_->GetFilter()); channel_->AddFilter(service_worker_message_filter_->GetFilter()); - channel_->AddFilter(websocket_message_filter_.get()); if (!IsInBrowserProcess()) { // In single process mode, browser-side tracing and memory will cover the
diff --git a/content/child/child_thread_impl.h b/content/child/child_thread_impl.h index 783d12b..3a9bf39 100644 --- a/content/child/child_thread_impl.h +++ b/content/child/child_thread_impl.h
@@ -65,8 +65,6 @@ class QuotaMessageFilter; class ResourceDispatcher; class ThreadSafeSender; -class WebSocketDispatcher; -class WebSocketMessageFilter; struct RequestInfo; // The main thread of a child process derives from this class. @@ -140,10 +138,6 @@ return resource_dispatcher_.get(); } - WebSocketDispatcher* websocket_dispatcher() const { - return websocket_dispatcher_.get(); - } - FileSystemDispatcher* file_system_dispatcher() const { return file_system_dispatcher_.get(); } @@ -187,10 +181,6 @@ return resource_message_filter_.get(); } - WebSocketMessageFilter* websocket_message_filter() const { - return websocket_message_filter_.get(); - } - base::MessageLoop* message_loop() const { return message_loop_; } // Returns the one child thread. Can only be called on the main thread. @@ -277,8 +267,6 @@ // Handles resource loads for this process. std::unique_ptr<ResourceDispatcher> resource_dispatcher_; - std::unique_ptr<WebSocketDispatcher> websocket_dispatcher_; - // The OnChannelError() callback was invoked - the channel is dead, don't // attempt to communicate. bool on_channel_error_called_; @@ -297,8 +285,6 @@ scoped_refptr<QuotaMessageFilter> quota_message_filter_; - scoped_refptr<WebSocketMessageFilter> websocket_message_filter_; - scoped_refptr<NotificationDispatcher> notification_dispatcher_; scoped_refptr<PushDispatcher> push_dispatcher_;
diff --git a/content/child/resource_dispatcher.cc b/content/child/resource_dispatcher.cc index 1662cd9..ba2e76b 100644 --- a/content/child/resource_dispatcher.cc +++ b/content/child/resource_dispatcher.cc
@@ -28,6 +28,7 @@ #include "content/child/shared_memory_received_data_factory.h" #include "content/child/site_isolation_stats_gatherer.h" #include "content/child/sync_load_response.h" +#include "content/child/url_response_body_consumer.h" #include "content/common/inter_process_time_ticks_converter.h" #include "content/common/navigation_params.h" #include "content/common/resource_messages.h" @@ -39,6 +40,7 @@ #include "content/public/common/content_features.h" #include "content/public/common/resource_response.h" #include "content/public/common/resource_type.h" +#include "mojo/public/cpp/bindings/binding.h" #include "net/base/net_errors.h" #include "net/base/request_priority.h" #include "net/http/http_response_headers.h" @@ -73,6 +75,48 @@ return next_request_id++; } +class URLLoaderClientImpl final : public mojom::URLLoaderClient { + public: + URLLoaderClientImpl(int request_id, + ResourceDispatcher* resource_dispatcher, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) + : binding_(this), + request_id_(request_id), + resource_dispatcher_(resource_dispatcher), + task_runner_(std::move(task_runner)) {} + ~URLLoaderClientImpl() override { + if (body_consumer_) + body_consumer_->Cancel(); + } + + void OnReceiveResponse(const ResourceResponseHead& response_head) override { + resource_dispatcher_->OnMessageReceived( + ResourceMsg_ReceivedResponse(request_id_, response_head)); + } + + void OnStartLoadingResponseBody( + mojo::ScopedDataPipeConsumerHandle body) override { + DCHECK(!body_consumer_); + body_consumer_ = new URLResponseBodyConsumer( + request_id_, resource_dispatcher_, std::move(body), task_runner_.get()); + } + + void OnComplete(const ResourceRequestCompletionStatus& status) override { + body_consumer_->OnComplete(status); + } + + mojom::URLLoaderClientPtr CreateInterfacePtrAndBind() { + return binding_.CreateInterfacePtrAndBind(); + } + + private: + mojo::Binding<mojom::URLLoaderClient> binding_; + scoped_refptr<URLResponseBodyConsumer> body_consumer_; + const int request_id_; + ResourceDispatcher* const resource_dispatcher_; + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; +}; + } // namespace ResourceDispatcher::ResourceDispatcher( @@ -474,7 +518,7 @@ void ResourceDispatcher::DidChangePriority(int request_id, net::RequestPriority new_priority, int intra_priority_value) { - DCHECK(ContainsKey(pending_requests_, request_id)); + DCHECK(base::ContainsKey(pending_requests_, request_id)); message_sender_->Send(new ResourceHostMsg_DidChangePriority( request_id, new_priority, intra_priority_value)); } @@ -545,11 +589,16 @@ } } -void ResourceDispatcher::StartSync(const RequestInfo& request_info, - ResourceRequestBodyImpl* request_body, - SyncLoadResponse* response) { +void ResourceDispatcher::StartSync( + const RequestInfo& request_info, + ResourceRequestBodyImpl* request_body, + SyncLoadResponse* response, + blink::WebURLRequest::LoadingIPCType ipc_type, + mojom::URLLoaderFactory* url_loader_factory) { std::unique_ptr<ResourceRequest> request = CreateRequest(request_info, request_body, NULL); + // TODO(yhirano): Use url_loader_factory otherwise. + DCHECK_EQ(blink::WebURLRequest::LoadingIPCType::ChromeIPC, ipc_type); SyncLoadResult result; IPC::SyncMessage* msg = new ResourceHostMsg_SyncLoad( @@ -578,9 +627,12 @@ response->encoded_body_length = result.encoded_body_length; } -int ResourceDispatcher::StartAsync(const RequestInfo& request_info, - ResourceRequestBodyImpl* request_body, - std::unique_ptr<RequestPeer> peer) { +int ResourceDispatcher::StartAsync( + const RequestInfo& request_info, + ResourceRequestBodyImpl* request_body, + std::unique_ptr<RequestPeer> peer, + blink::WebURLRequest::LoadingIPCType ipc_type, + mojom::URLLoaderFactory* url_loader_factory) { GURL frame_origin; std::unique_ptr<ResourceRequest> request = CreateRequest(request_info, request_body, &frame_origin); @@ -596,8 +648,19 @@ request_id, request_info.loading_task_runner); } - message_sender_->Send(new ResourceHostMsg_RequestResource( - request_info.routing_id, request_id, *request)); + if (ipc_type == blink::WebURLRequest::LoadingIPCType::Mojo) { + std::unique_ptr<URLLoaderClientImpl> client( + new URLLoaderClientImpl(request_id, this, main_thread_task_runner_)); + mojom::URLLoaderPtr url_loader; + url_loader_factory->CreateLoaderAndStart( + GetProxy(&url_loader), request_id, *request, + client->CreateInterfacePtrAndBind()); + pending_requests_[request_id]->url_loader = std::move(url_loader); + pending_requests_[request_id]->url_loader_client = std::move(client); + } else { + message_sender_->Send(new ResourceHostMsg_RequestResource( + request_info.routing_id, request_id, *request)); + } return request_id; }
diff --git a/content/child/resource_dispatcher.h b/content/child/resource_dispatcher.h index 11485286..5ef632f 100644 --- a/content/child/resource_dispatcher.h +++ b/content/child/resource_dispatcher.h
@@ -22,10 +22,12 @@ #include "base/single_thread_task_runner.h" #include "base/time/time.h" #include "content/common/content_export.h" +#include "content/common/url_loader.mojom.h" #include "content/public/common/resource_type.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_sender.h" #include "net/base/request_priority.h" +#include "third_party/WebKit/public/platform/WebURLRequest.h" #include "url/gurl.h" namespace net { @@ -46,6 +48,10 @@ struct SiteIsolationResponseMetaData; struct SyncLoadResponse; +namespace mojom { +class URLLoaderFactory; +} // namespace mojom + // This class serves as a communication interface to the ResourceDispatcherHost // in the browser process. It can be used from any child process. // Virtual methods are for tests. @@ -68,14 +74,19 @@ // response parameter. virtual void StartSync(const RequestInfo& request_info, ResourceRequestBodyImpl* request_body, - SyncLoadResponse* response); + SyncLoadResponse* response, + blink::WebURLRequest::LoadingIPCType ipc_type, + mojom::URLLoaderFactory* url_loader_factory); // Call this method to initiate the request. If this method succeeds, then // the peer's methods will be called asynchronously to report various events. - // Returns the request id. + // Returns the request id. |url_loader_factory| must be non-null if and only + // if |ipc_type| is LoadingIPCType::Mojo. virtual int StartAsync(const RequestInfo& request_info, ResourceRequestBodyImpl* request_body, - std::unique_ptr<RequestPeer> peer); + std::unique_ptr<RequestPeer> peer, + blink::WebURLRequest::LoadingIPCType ipc_type, + mojom::URLLoaderFactory* url_loader_factory); // Removes a request from the |pending_requests_| list, returning true if the // request was found and removed. @@ -119,6 +130,7 @@ scoped_refptr<ResourceSchedulingFilter> resource_scheduling_filter); private: + friend class URLResponseBodyConsumer; friend class ResourceDispatcherTest; typedef std::deque<IPC::Message*> MessageQueue; @@ -155,6 +167,10 @@ scoped_refptr<SharedMemoryReceivedDataFactory> received_data_factory; std::unique_ptr<SiteIsolationResponseMetaData> site_isolation_metadata; int buffer_size; + + // For mojo loading. + mojom::URLLoaderPtr url_loader; + std::unique_ptr<mojom::URLLoaderClient> url_loader_client; }; using PendingRequestMap = std::map<int, std::unique_ptr<PendingRequestInfo>>;
diff --git a/content/child/resource_dispatcher_unittest.cc b/content/child/resource_dispatcher_unittest.cc index 141e316..391f937 100644 --- a/content/child/resource_dispatcher_unittest.cc +++ b/content/child/resource_dispatcher_unittest.cc
@@ -147,8 +147,8 @@ } ~ResourceDispatcherTest() override { - STLDeleteContainerPairSecondPointers(shared_memory_map_.begin(), - shared_memory_map_.end()); + base::STLDeleteContainerPairSecondPointers(shared_memory_map_.begin(), + shared_memory_map_.end()); dispatcher_.reset(); base::RunLoop().RunUntilIdle(); } @@ -331,8 +331,9 @@ TestRequestPeer::Context* peer_context) { std::unique_ptr<TestRequestPeer> peer( new TestRequestPeer(dispatcher(), peer_context)); - int request_id = - dispatcher()->StartAsync(request_info, request_body, std::move(peer)); + int request_id = dispatcher()->StartAsync( + request_info, request_body, std::move(peer), + blink::WebURLRequest::LoadingIPCType::ChromeIPC, nullptr); peer_context->request_id = request_id; return request_id; }
diff --git a/content/child/service_factory.cc b/content/child/service_factory.cc index 936d4b7..dc9832e 100644 --- a/content/child/service_factory.cc +++ b/content/child/service_factory.cc
@@ -17,7 +17,7 @@ ServiceFactory::~ServiceFactory() {} void ServiceFactory::CreateService(shell::mojom::ServiceRequest request, - const mojo::String& name) { + const std::string& name) { // Only register services on first run. if (!has_registered_services_) { DCHECK(services_.empty());
diff --git a/content/child/service_factory.h b/content/child/service_factory.h index 1502da22..a520415 100644 --- a/content/child/service_factory.h +++ b/content/child/service_factory.h
@@ -31,7 +31,7 @@ // shell::mojom::ServiceFactory: void CreateService(shell::mojom::ServiceRequest request, - const mojo::String& name) override; + const std::string& name) override; private: // Called if CreateService fails to find a registered service.
diff --git a/content/child/service_worker/service_worker_dispatcher.cc b/content/child/service_worker/service_worker_dispatcher.cc index 025f26ec..984468a72 100644 --- a/content/child/service_worker/service_worker_dispatcher.cc +++ b/content/child/service_worker/service_worker_dispatcher.cc
@@ -210,14 +210,15 @@ ServiceWorkerProviderContext* provider_context) { DCHECK(provider_context); int provider_id = provider_context->provider_id(); - DCHECK(!ContainsKey(provider_contexts_, provider_id)); + DCHECK(!base::ContainsKey(provider_contexts_, provider_id)); provider_contexts_[provider_id] = provider_context; } void ServiceWorkerDispatcher::RemoveProviderContext( ServiceWorkerProviderContext* provider_context) { DCHECK(provider_context); - DCHECK(ContainsKey(provider_contexts_, provider_context->provider_id())); + DCHECK( + base::ContainsKey(provider_contexts_, provider_context->provider_id())); provider_contexts_.erase(provider_context->provider_id()); } @@ -225,13 +226,13 @@ int provider_id, blink::WebServiceWorkerProviderClient* client) { DCHECK(client); - DCHECK(!ContainsKey(provider_clients_, provider_id)); + DCHECK(!base::ContainsKey(provider_clients_, provider_id)); provider_clients_[provider_id] = client; } void ServiceWorkerDispatcher::RemoveProviderClient(int provider_id) { // This could be possibly called multiple times to ensure termination. - if (ContainsKey(provider_clients_, provider_id)) + if (base::ContainsKey(provider_clients_, provider_id)) provider_clients_.erase(provider_id); } @@ -746,25 +747,25 @@ void ServiceWorkerDispatcher::AddServiceWorker( int handle_id, WebServiceWorkerImpl* worker) { - DCHECK(!ContainsKey(service_workers_, handle_id)); + DCHECK(!base::ContainsKey(service_workers_, handle_id)); service_workers_[handle_id] = worker; } void ServiceWorkerDispatcher::RemoveServiceWorker(int handle_id) { - DCHECK(ContainsKey(service_workers_, handle_id)); + DCHECK(base::ContainsKey(service_workers_, handle_id)); service_workers_.erase(handle_id); } void ServiceWorkerDispatcher::AddServiceWorkerRegistration( int registration_handle_id, WebServiceWorkerRegistrationImpl* registration) { - DCHECK(!ContainsKey(registrations_, registration_handle_id)); + DCHECK(!base::ContainsKey(registrations_, registration_handle_id)); registrations_[registration_handle_id] = registration; } void ServiceWorkerDispatcher::RemoveServiceWorkerRegistration( int registration_handle_id) { - DCHECK(ContainsKey(registrations_, registration_handle_id)); + DCHECK(base::ContainsKey(registrations_, registration_handle_id)); registrations_.erase(registration_handle_id); }
diff --git a/content/child/url_response_body_consumer.cc b/content/child/url_response_body_consumer.cc new file mode 100644 index 0000000..44b1300 --- /dev/null +++ b/content/child/url_response_body_consumer.cc
@@ -0,0 +1,127 @@ +// Copyright 2016 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/child/url_response_body_consumer.h" + +#include "base/bind.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "content/child/resource_dispatcher.h" +#include "content/common/resource_messages.h" +#include "content/common/resource_request_completion_status.h" +#include "content/public/child/request_peer.h" + +namespace content { + +class URLResponseBodyConsumer::ReceivedData final + : public RequestPeer::ReceivedData { + public: + ReceivedData(const char* payload, + int length, + scoped_refptr<URLResponseBodyConsumer> consumer) + : payload_(payload), length_(length), consumer_(consumer) {} + + ~ReceivedData() override { consumer_->Reclaim(length_); } + + const char* payload() const override { return payload_; } + int length() const override { return length_; } + // TODO(yhirano): These return incorrect values. Remove these from + // ReceivedData before enabling Mojo-Loading. + int encoded_data_length() const override { return length_; } + int encoded_body_length() const override { return length_; } + + private: + const char* const payload_; + const uint32_t length_; + + scoped_refptr<URLResponseBodyConsumer> consumer_; + + DISALLOW_COPY_AND_ASSIGN(ReceivedData); +}; + +URLResponseBodyConsumer::URLResponseBodyConsumer( + int request_id, + ResourceDispatcher* resource_dispatcher, + mojo::ScopedDataPipeConsumerHandle handle, + base::SingleThreadTaskRunner* task_runner) + : request_id_(request_id), + resource_dispatcher_(resource_dispatcher), + handle_(std::move(handle)), + has_seen_end_of_data_(!handle_.is_valid()) { + handle_watcher_.Start( + handle_.get(), MOJO_HANDLE_SIGNAL_READABLE, + base::Bind(&URLResponseBodyConsumer::OnReadable, base::Unretained(this))); + task_runner->PostTask( + FROM_HERE, base::Bind(&URLResponseBodyConsumer::OnReadable, AsWeakPtr(), + MOJO_RESULT_OK)); +} + +URLResponseBodyConsumer::~URLResponseBodyConsumer() {} + +void URLResponseBodyConsumer::OnComplete( + const ResourceRequestCompletionStatus& status) { + if (has_been_cancelled_) + return; + has_received_completion_ = true; + completion_status_ = status; + NotifyCompletionIfAppropriate(); +} + +void URLResponseBodyConsumer::Cancel() { + has_been_cancelled_ = true; + handle_watcher_.Cancel(); +} + +void URLResponseBodyConsumer::Reclaim(uint32_t size) { + MojoResult result = mojo::EndReadDataRaw(handle_.get(), size); + DCHECK_EQ(MOJO_RESULT_OK, result); +} + +void URLResponseBodyConsumer::OnReadable(MojoResult unused) { + if (has_been_cancelled_ || has_seen_end_of_data_) + return; + + // TODO(yhirano): Suppress notification when deferred. + // TODO(yhirano): Run this operation on the loading task runner. + while (!has_been_cancelled_) { + const void* buffer = nullptr; + uint32_t available = 0; + MojoResult result = mojo::BeginReadDataRaw( + handle_.get(), &buffer, &available, MOJO_READ_DATA_FLAG_NONE); + if (result == MOJO_RESULT_SHOULD_WAIT) + return; + if (result == MOJO_RESULT_FAILED_PRECONDITION) { + has_seen_end_of_data_ = true; + NotifyCompletionIfAppropriate(); + return; + } + if (result != MOJO_RESULT_OK) { + completion_status_.error_code = net::ERR_FAILED; + has_seen_end_of_data_ = true; + has_received_completion_ = true; + NotifyCompletionIfAppropriate(); + return; + } + ResourceDispatcher::PendingRequestInfo* request_info = + resource_dispatcher_->GetPendingRequestInfo(request_id_); + DCHECK(request_info); + request_info->peer->OnReceivedData(base::WrapUnique( + new ReceivedData(static_cast<const char*>(buffer), available, this))); + } +} + +void URLResponseBodyConsumer::NotifyCompletionIfAppropriate() { + if (has_been_cancelled_) + return; + if (!has_received_completion_ || !has_seen_end_of_data_) + return; + // Cancel this instance in order not to notify twice. + Cancel(); + + resource_dispatcher_->OnMessageReceived( + ResourceMsg_RequestComplete(request_id_, completion_status_)); + // |this| may be deleted. +} + +} // namespace content
diff --git a/content/child/url_response_body_consumer.h b/content/child/url_response_body_consumer.h new file mode 100644 index 0000000..f7fb232 --- /dev/null +++ b/content/child/url_response_body_consumer.h
@@ -0,0 +1,75 @@ +// Copyright 2016 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_CHILD_URL_RESPONSE_BODY_CONSUMER_H_ +#define CONTENT_CHILD_URL_RESPONSE_BODY_CONSUMER_H_ + +#include <stddef.h> +#include <stdint.h> + +#include <utility> +#include <vector> + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/single_thread_task_runner.h" +#include "content/common/content_export.h" +#include "content/common/url_loader.mojom.h" +#include "mojo/public/cpp/system/data_pipe.h" +#include "mojo/public/cpp/system/watcher.h" + +namespace content { + +class ResourceDispatcher; +struct ResourceRequestCompletionStatus; + +// This class pulls data from a data pipe and dispatches it to the +// ResourceDispatcher. This class is used only for mojo-enabled requests. +class CONTENT_EXPORT URLResponseBodyConsumer final + : public base::RefCounted<URLResponseBodyConsumer>, + public base::SupportsWeakPtr<URLResponseBodyConsumer> { + public: + URLResponseBodyConsumer(int request_id, + ResourceDispatcher* resource_dispatcher, + mojo::ScopedDataPipeConsumerHandle handle, + base::SingleThreadTaskRunner* task_runner); + + // Sets the completion status. The completion status is dispatched to the + // ResourceDispatcher when the both following conditions hold: + // 1) This function has been called and the completion status is set, and + // 2) All data is read from the handle. + void OnComplete(const ResourceRequestCompletionStatus& status); + + // Cancels watching the handle and dispatches an error to the + // ResourceDispatcher. This function does nothing if the reading is already + // cancelled or done. + void Cancel(); + + private: + friend class base::RefCounted<URLResponseBodyConsumer>; + ~URLResponseBodyConsumer(); + + class ReceivedData; + void Reclaim(uint32_t size); + + void OnReadable(MojoResult unused); + void NotifyCompletionIfAppropriate(); + + const int request_id_; + ResourceDispatcher* resource_dispatcher_; + mojo::ScopedDataPipeConsumerHandle handle_; + mojo::Watcher handle_watcher_; + ResourceRequestCompletionStatus completion_status_; + + bool has_received_completion_ = false; + bool has_been_cancelled_ = false; + bool has_seen_end_of_data_; + + DISALLOW_COPY_AND_ASSIGN(URLResponseBodyConsumer); +}; + +} // namespace content + +#endif // CONTENT_CHILD_URL_RESPONSE_BODY_CONSUMER_H_
diff --git a/content/child/url_response_body_consumer_unittest.cc b/content/child/url_response_body_consumer_unittest.cc new file mode 100644 index 0000000..cd17dd7 --- /dev/null +++ b/content/child/url_response_body_consumer_unittest.cc
@@ -0,0 +1,211 @@ +// Copyright 2016 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/child/url_response_body_consumer.h" + +#include "base/bind.h" +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/run_loop.h" +#include "content/child/request_info.h" +#include "content/child/resource_dispatcher.h" +#include "content/common/resource_messages.h" +#include "content/common/resource_request_completion_status.h" +#include "content/public/child/request_peer.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace content { + +namespace { + +class TestRequestPeer : public RequestPeer { + public: + struct Context; + explicit TestRequestPeer(Context* context) : context_(context) {} + + void OnUploadProgress(uint64_t position, uint64_t size) override { + ADD_FAILURE() << "OnUploadProgress should not be called."; + } + + bool OnReceivedRedirect(const net::RedirectInfo& redirect_info, + const ResourceResponseInfo& info) override { + ADD_FAILURE() << "OnReceivedRedirect should not be called."; + return false; + } + + void OnReceivedResponse(const ResourceResponseInfo& info) override { + ADD_FAILURE() << "OnReceivedResponse should not be called."; + } + + void OnDownloadedData(int len, int encoded_data_length) override { + ADD_FAILURE() << "OnDownloadedData should not be called."; + } + + void OnReceivedData(std::unique_ptr<ReceivedData> data) override { + EXPECT_FALSE(context_->complete); + context_->data.append(data->payload(), data->length()); + context_->run_loop_quit_closure.Run(); + } + + void OnCompletedRequest(int error_code, + bool was_ignored_by_handler, + bool stale_copy_in_cache, + const std::string& security_info, + const base::TimeTicks& completion_time, + int64_t total_transfer_size) override { + EXPECT_FALSE(context_->complete); + context_->complete = true; + context_->error_code = error_code; + context_->run_loop_quit_closure.Run(); + } + + struct Context { + // Data received. If downloading to file, remains empty. + std::string data; + bool complete = false; + base::Closure run_loop_quit_closure; + int error_code = net::OK; + }; + + private: + Context* context_; + + DISALLOW_COPY_AND_ASSIGN(TestRequestPeer); +}; + +class URLResponseBodyConsumerTest : public ::testing::Test, + public ::IPC::Sender { + protected: + URLResponseBodyConsumerTest() + : dispatcher_(new ResourceDispatcher(this, message_loop_.task_runner())) { + } + + ~URLResponseBodyConsumerTest() override { + dispatcher_.reset(); + base::RunLoop().RunUntilIdle(); + } + + bool Send(IPC::Message* message) override { + delete message; + return true; + } + + std::unique_ptr<RequestInfo> CreateRequestInfo() { + std::unique_ptr<RequestInfo> request_info(new RequestInfo); + request_info->method = "GET"; + request_info->url = GURL("http://www.example.com/"); + return request_info; + } + + MojoCreateDataPipeOptions CreateDataPipeOptions() { + MojoCreateDataPipeOptions options; + options.struct_size = sizeof(MojoCreateDataPipeOptions); + options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE; + options.element_num_bytes = 1; + options.capacity_num_bytes = 1024; + return options; + } + + // Returns the request id. + int SetUpRequestPeer(const RequestInfo& request_info, + TestRequestPeer::Context* context) { + return dispatcher_->StartAsync( + request_info, nullptr, base::WrapUnique(new TestRequestPeer(context)), + blink::WebURLRequest::LoadingIPCType::ChromeIPC, nullptr); + } + + void Run(TestRequestPeer::Context* context) { + base::RunLoop run_loop; + context->run_loop_quit_closure = run_loop.QuitClosure(); + run_loop.Run(); + } + + base::MessageLoop message_loop_; + std::unique_ptr<ResourceDispatcher> dispatcher_; + static const MojoWriteDataFlags kNone = MOJO_WRITE_DATA_FLAG_NONE; +}; + +TEST_F(URLResponseBodyConsumerTest, ReceiveData) { + TestRequestPeer::Context context; + std::unique_ptr<RequestInfo> request_info(CreateRequestInfo()); + int request_id = SetUpRequestPeer(*request_info, &context); + mojo::DataPipe data_pipe(CreateDataPipeOptions()); + + scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer( + request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle), + message_loop_.task_runner().get())); + + mojo::ScopedDataPipeProducerHandle writer = + std::move(data_pipe.producer_handle); + std::string buffer = "hello"; + uint32_t size = buffer.size(); + MojoResult result = + mojo::WriteDataRaw(writer.get(), buffer.c_str(), &size, kNone); + ASSERT_EQ(MOJO_RESULT_OK, result); + ASSERT_EQ(buffer.size(), size); + + Run(&context); + + EXPECT_FALSE(context.complete); + EXPECT_EQ("hello", context.data); +} + +TEST_F(URLResponseBodyConsumerTest, OnCompleteThenClose) { + TestRequestPeer::Context context; + std::unique_ptr<RequestInfo> request_info(CreateRequestInfo()); + int request_id = SetUpRequestPeer(*request_info, &context); + mojo::DataPipe data_pipe(CreateDataPipeOptions()); + + scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer( + request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle), + message_loop_.task_runner().get())); + + consumer->OnComplete(ResourceRequestCompletionStatus()); + mojo::ScopedDataPipeProducerHandle writer = + std::move(data_pipe.producer_handle); + std::string buffer = "hello"; + uint32_t size = buffer.size(); + MojoResult result = + mojo::WriteDataRaw(writer.get(), buffer.c_str(), &size, kNone); + ASSERT_EQ(MOJO_RESULT_OK, result); + ASSERT_EQ(buffer.size(), size); + + Run(&context); + + writer.reset(); + EXPECT_FALSE(context.complete); + EXPECT_EQ("hello", context.data); + + Run(&context); + + EXPECT_TRUE(context.complete); + EXPECT_EQ("hello", context.data); +} + +TEST_F(URLResponseBodyConsumerTest, CloseThenOnComplete) { + TestRequestPeer::Context context; + std::unique_ptr<RequestInfo> request_info(CreateRequestInfo()); + int request_id = SetUpRequestPeer(*request_info, &context); + mojo::DataPipe data_pipe(CreateDataPipeOptions()); + + scoped_refptr<URLResponseBodyConsumer> consumer(new URLResponseBodyConsumer( + request_id, dispatcher_.get(), std::move(data_pipe.consumer_handle), + message_loop_.task_runner().get())); + + ResourceRequestCompletionStatus status; + status.error_code = net::ERR_FAILED; + data_pipe.producer_handle.reset(); + consumer->OnComplete(status); + + Run(&context); + + EXPECT_TRUE(context.complete); + EXPECT_EQ(net::ERR_FAILED, context.error_code); + EXPECT_EQ("", context.data); +} + +} // namespace + +} // namespace content
diff --git a/content/child/web_url_loader_impl.cc b/content/child/web_url_loader_impl.cc index 518feec4..98e9fa4 100644 --- a/content/child/web_url_loader_impl.cc +++ b/content/child/web_url_loader_impl.cc
@@ -35,6 +35,7 @@ #include "content/common/resource_request_body_impl.h" #include "content/common/service_worker/service_worker_types.h" #include "content/common/ssl_status_serialization.h" +#include "content/common/url_loader.mojom.h" #include "content/public/child/fixed_received_data.h" #include "content/public/child/request_peer.h" #include "content/public/common/browser_side_navigation_policy.h" @@ -300,7 +301,9 @@ public: using ReceivedData = RequestPeer::ReceivedData; - Context(WebURLLoaderImpl* loader, ResourceDispatcher* resource_dispatcher); + Context(WebURLLoaderImpl* loader, + ResourceDispatcher* resource_dispatcher, + mojom::URLLoaderFactory* factory); WebURLLoaderClient* client() const { return client_; } void set_client(WebURLLoaderClient* client) { client_ = client; } @@ -350,6 +353,8 @@ enum DeferState {NOT_DEFERRING, SHOULD_DEFER, DEFERRED_DATA}; DeferState defers_loading_; int request_id_; + + mojom::URLLoaderFactory* url_loader_factory_; }; // A thin wrapper class for Context to ensure its lifetime while it is @@ -382,14 +387,16 @@ // WebURLLoaderImpl::Context -------------------------------------------------- WebURLLoaderImpl::Context::Context(WebURLLoaderImpl* loader, - ResourceDispatcher* resource_dispatcher) + ResourceDispatcher* resource_dispatcher, + mojom::URLLoaderFactory* url_loader_factory) : loader_(loader), client_(NULL), resource_dispatcher_(resource_dispatcher), task_runner_(base::ThreadTaskRunnerHandle::Get()), referrer_policy_(blink::WebReferrerPolicyDefault), defers_loading_(NOT_DEFERRING), - request_id_(-1) {} + request_id_(-1), + url_loader_factory_(url_loader_factory) {} void WebURLLoaderImpl::Context::Cancel() { TRACE_EVENT_WITH_FLOW0("loading", "WebURLLoaderImpl::Context::Cancel", this, @@ -542,7 +549,8 @@ if (sync_load_response) { DCHECK(defers_loading_ == NOT_DEFERRING); resource_dispatcher_->StartSync( - request_info, request_body.get(), sync_load_response); + request_info, request_body.get(), sync_load_response, + request.getLoadingIPCType(), url_loader_factory_); return; } @@ -550,7 +558,8 @@ TRACE_EVENT_FLAG_FLOW_OUT); request_id_ = resource_dispatcher_->StartAsync( request_info, request_body.get(), - base::WrapUnique(new WebURLLoaderImpl::RequestPeerImpl(this))); + base::WrapUnique(new WebURLLoaderImpl::RequestPeerImpl(this)), + request.getLoadingIPCType(), url_loader_factory_); if (defers_loading_ != NOT_DEFERRING) resource_dispatcher_->SetDefersLoading(request_id_, true); @@ -921,8 +930,9 @@ // WebURLLoaderImpl ----------------------------------------------------------- -WebURLLoaderImpl::WebURLLoaderImpl(ResourceDispatcher* resource_dispatcher) - : context_(new Context(this, resource_dispatcher)) {} +WebURLLoaderImpl::WebURLLoaderImpl(ResourceDispatcher* resource_dispatcher, + mojom::URLLoaderFactory* url_loader_factory) + : context_(new Context(this, resource_dispatcher, url_loader_factory)) {} WebURLLoaderImpl::~WebURLLoaderImpl() { cancel();
diff --git a/content/child/web_url_loader_impl.h b/content/child/web_url_loader_impl.h index 79c81ad..20f8b581 100644 --- a/content/child/web_url_loader_impl.h +++ b/content/child/web_url_loader_impl.h
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "content/common/content_export.h" +#include "content/common/url_loader_factory.mojom.h" #include "content/public/common/resource_response.h" #include "net/url_request/redirect_info.h" #include "third_party/WebKit/public/platform/WebURLLoader.h" @@ -38,7 +39,8 @@ public: // Takes ownership of |web_task_runner|. - WebURLLoaderImpl(ResourceDispatcher* resource_dispatcher); + WebURLLoaderImpl(ResourceDispatcher* resource_dispatcher, + mojom::URLLoaderFactory* url_loader_factory); ~WebURLLoaderImpl() override; static void PopulateURLResponse(const GURL& url,
diff --git a/content/child/web_url_loader_impl_unittest.cc b/content/child/web_url_loader_impl_unittest.cc index 57ca624..b5340f5 100644 --- a/content/child/web_url_loader_impl_unittest.cc +++ b/content/child/web_url_loader_impl_unittest.cc
@@ -68,14 +68,19 @@ void StartSync(const RequestInfo& request_info, ResourceRequestBodyImpl* request_body, - SyncLoadResponse* response) override { + SyncLoadResponse* response, + blink::WebURLRequest::LoadingIPCType ipc_type, + mojom::URLLoaderFactory* url_loader_factory) override { *response = sync_load_response_; } int StartAsync(const RequestInfo& request_info, ResourceRequestBodyImpl* request_body, - std::unique_ptr<RequestPeer> peer) override { + std::unique_ptr<RequestPeer> peer, + blink::WebURLRequest::LoadingIPCType ipc_type, + mojom::URLLoaderFactory* url_loader_factory) override { EXPECT_FALSE(peer_); + EXPECT_EQ(blink::WebURLRequest::LoadingIPCType::ChromeIPC, ipc_type); peer_ = std::move(peer); url_ = request_info.url; stream_url_ = request_info.resource_body_stream_url; @@ -117,7 +122,7 @@ class TestWebURLLoaderClient : public blink::WebURLLoaderClient { public: TestWebURLLoaderClient(ResourceDispatcher* dispatcher) - : loader_(new WebURLLoaderImpl(dispatcher)), + : loader_(new WebURLLoaderImpl(dispatcher, nullptr)), delete_on_receive_redirect_(false), delete_on_receive_response_(false), delete_on_receive_data_(false),
diff --git a/content/child/websocket_bridge.cc b/content/child/websocket_bridge.cc deleted file mode 100644 index bd94b42..0000000 --- a/content/child/websocket_bridge.cc +++ /dev/null
@@ -1,304 +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 "content/child/websocket_bridge.h" - -#include <stdint.h> -#include <string> -#include <utility> -#include <vector> - -#include "base/logging.h" -#include "base/strings/string_util.h" -#include "content/child/child_thread_impl.h" -#include "content/child/websocket_dispatcher.h" -#include "content/common/websocket.h" -#include "content/common/websocket_messages.h" -#include "ipc/ipc_message.h" -#include "ipc/ipc_message_macros.h" -#include "third_party/WebKit/public/platform/WebSecurityOrigin.h" -#include "third_party/WebKit/public/platform/WebString.h" -#include "third_party/WebKit/public/platform/WebURL.h" -#include "third_party/WebKit/public/platform/WebVector.h" -#include "third_party/WebKit/public/platform/modules/websockets/WebSocketHandle.h" -#include "third_party/WebKit/public/platform/modules/websockets/WebSocketHandleClient.h" -#include "third_party/WebKit/public/platform/modules/websockets/WebSocketHandshakeRequestInfo.h" -#include "third_party/WebKit/public/platform/modules/websockets/WebSocketHandshakeResponseInfo.h" -#include "url/gurl.h" -#include "url/origin.h" - -using blink::WebSecurityOrigin; -using blink::WebSocketHandle; -using blink::WebSocketHandleClient; -using blink::WebString; -using blink::WebURL; -using blink::WebVector; - -namespace content { - -namespace { - -const unsigned short kAbnormalShutdownOpCode = 1006; - -} // namespace - -WebSocketBridge::WebSocketBridge() - : channel_id_(kInvalidChannelId), - render_frame_id_(MSG_ROUTING_NONE), - client_(NULL) {} - -WebSocketBridge::~WebSocketBridge() { - if (channel_id_ != kInvalidChannelId) { - // The connection is abruptly disconnected by the renderer without - // closing handshake. - ChildThreadImpl::current()->Send( - new WebSocketMsg_DropChannel(channel_id_, - false, - kAbnormalShutdownOpCode, - std::string())); - } - Disconnect(); -} - -bool WebSocketBridge::OnMessageReceived(const IPC::Message& msg) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(WebSocketBridge, msg) - IPC_MESSAGE_HANDLER(WebSocketMsg_AddChannelResponse, DidConnect) - IPC_MESSAGE_HANDLER(WebSocketMsg_NotifyStartOpeningHandshake, - DidStartOpeningHandshake) - IPC_MESSAGE_HANDLER(WebSocketMsg_NotifyFinishOpeningHandshake, - DidFinishOpeningHandshake) - IPC_MESSAGE_HANDLER(WebSocketMsg_NotifyFailure, DidFail) - IPC_MESSAGE_HANDLER(WebSocketMsg_SendFrame, DidReceiveData) - IPC_MESSAGE_HANDLER(WebSocketMsg_FlowControl, DidReceiveFlowControl) - IPC_MESSAGE_HANDLER(WebSocketMsg_DropChannel, DidClose) - IPC_MESSAGE_HANDLER(WebSocketMsg_NotifyClosing, - DidStartClosingHandshake) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -void WebSocketBridge::DidConnect(const std::string& selected_protocol, - const std::string& extensions) { - WebSocketHandleClient* client = client_; - DVLOG(1) << "WebSocketBridge::DidConnect(" - << selected_protocol << ", " - << extensions << ")"; - if (!client) - return; - - WebString protocol_to_pass = WebString::fromUTF8(selected_protocol); - WebString extensions_to_pass = WebString::fromUTF8(extensions); - client->didConnect(this, protocol_to_pass, extensions_to_pass); - // |this| can be deleted here. -} - -void WebSocketBridge::DidStartOpeningHandshake( - const WebSocketHandshakeRequest& request) { - DVLOG(1) << "WebSocketBridge::DidStartOpeningHandshake(" - << request.url << ")"; - // All strings are already encoded to ASCII in the browser. - blink::WebSocketHandshakeRequestInfo request_to_pass; - request_to_pass.setURL(WebURL(request.url)); - for (size_t i = 0; i < request.headers.size(); ++i) { - const std::pair<std::string, std::string>& header = request.headers[i]; - request_to_pass.addHeaderField(WebString::fromLatin1(header.first), - WebString::fromLatin1(header.second)); - } - request_to_pass.setHeadersText(WebString::fromLatin1(request.headers_text)); - client_->didStartOpeningHandshake(this, request_to_pass); -} - -void WebSocketBridge::DidFinishOpeningHandshake( - const WebSocketHandshakeResponse& response) { - DVLOG(1) << "WebSocketBridge::DidFinishOpeningHandshake(" - << response.url << ")"; - // All strings are already encoded to ASCII in the browser. - blink::WebSocketHandshakeResponseInfo response_to_pass; - response_to_pass.setStatusCode(response.status_code); - response_to_pass.setStatusText(WebString::fromLatin1(response.status_text)); - for (size_t i = 0; i < response.headers.size(); ++i) { - const std::pair<std::string, std::string>& header = response.headers[i]; - response_to_pass.addHeaderField(WebString::fromLatin1(header.first), - WebString::fromLatin1(header.second)); - } - response_to_pass.setHeadersText(WebString::fromLatin1(response.headers_text)); - client_->didFinishOpeningHandshake(this, response_to_pass); -} - -void WebSocketBridge::DidFail(const std::string& message) { - DVLOG(1) << "WebSocketBridge::DidFail(" << message << ")"; - WebSocketHandleClient* client = client_; - Disconnect(); - if (!client) - return; - - WebString message_to_pass = WebString::fromUTF8(message); - client->didFail(this, message_to_pass); - // |this| can be deleted here. -} - -void WebSocketBridge::DidReceiveData(bool fin, - WebSocketMessageType type, - const std::vector<char>& data) { - DVLOG(1) << "WebSocketBridge::DidReceiveData(" - << fin << ", " - << type << ", " - << "(data size = " << data.size() << "))"; - if (!client_) - return; - - WebSocketHandle::MessageType type_to_pass = - WebSocketHandle::MessageTypeContinuation; - switch (type) { - case WEB_SOCKET_MESSAGE_TYPE_CONTINUATION: - type_to_pass = WebSocketHandle::MessageTypeContinuation; - break; - case WEB_SOCKET_MESSAGE_TYPE_TEXT: - type_to_pass = WebSocketHandle::MessageTypeText; - break; - case WEB_SOCKET_MESSAGE_TYPE_BINARY: - type_to_pass = WebSocketHandle::MessageTypeBinary; - break; - } - const char* data_to_pass = data.empty() ? NULL : &data[0]; - client_->didReceiveData(this, fin, type_to_pass, data_to_pass, data.size()); - // |this| can be deleted here. -} - -void WebSocketBridge::DidReceiveFlowControl(int64_t quota) { - DVLOG(1) << "WebSocketBridge::DidReceiveFlowControl(" << quota << ")"; - if (!client_) - return; - - client_->didReceiveFlowControl(this, quota); - // |this| can be deleted here. -} - -void WebSocketBridge::DidClose(bool was_clean, - unsigned short code, - const std::string& reason) { - DVLOG(1) << "WebSocketBridge::DidClose(" - << was_clean << ", " - << code << ", " - << reason << ")"; - WebSocketHandleClient* client = client_; - Disconnect(); - if (!client) - return; - - WebString reason_to_pass = WebString::fromUTF8(reason); - client->didClose(this, was_clean, code, reason_to_pass); - // |this| can be deleted here. -} - -void WebSocketBridge::DidStartClosingHandshake() { - DVLOG(1) << "WebSocketBridge::DidStartClosingHandshake()"; - if (!client_) - return; - - client_->didStartClosingHandshake(this); - // |this| can be deleted here. -} - -void WebSocketBridge::connect(const WebURL& url, - const WebVector<WebString>& protocols, - const WebSecurityOrigin& origin, - const WebURL& first_party_for_cookies, - const WebString& user_agent_override, - WebSocketHandleClient* client) { - DCHECK_EQ(kInvalidChannelId, channel_id_); - WebSocketDispatcher* dispatcher = - ChildThreadImpl::current()->websocket_dispatcher(); - channel_id_ = dispatcher->AddBridge(this); - client_ = client; - - std::vector<std::string> protocols_to_pass; - for (size_t i = 0; i < protocols.size(); ++i) - protocols_to_pass.push_back(protocols[i].utf8()); - - DVLOG(1) << "Bridge#" << channel_id_ << " Connect(" << url << ", (" - << base::JoinString(protocols_to_pass, ", ") << "), " - << origin.toString().utf8() << ")"; - - WebSocketHostMsg_AddChannelRequest_Params params; - params.socket_url = url; - params.requested_protocols = protocols_to_pass; - params.origin = origin; - params.first_party_for_cookies = first_party_for_cookies; - params.user_agent_override = user_agent_override.latin1(); - params.render_frame_id = render_frame_id_; - - // Headers (ie: User-Agent) are ISO Latin 1. - ChildThreadImpl::current()->Send(new WebSocketHostMsg_AddChannelRequest( - channel_id_, params)); -} - -void WebSocketBridge::send(bool fin, - WebSocketHandle::MessageType type, - const char* data, - size_t size) { - if (channel_id_ == kInvalidChannelId) - return; - - WebSocketMessageType type_to_pass = WEB_SOCKET_MESSAGE_TYPE_CONTINUATION; - switch (type) { - case WebSocketHandle::MessageTypeContinuation: - type_to_pass = WEB_SOCKET_MESSAGE_TYPE_CONTINUATION; - break; - case WebSocketHandle::MessageTypeText: - type_to_pass = WEB_SOCKET_MESSAGE_TYPE_TEXT; - break; - case WebSocketHandle::MessageTypeBinary: - type_to_pass = WEB_SOCKET_MESSAGE_TYPE_BINARY; - break; - } - - DVLOG(1) << "Bridge #" << channel_id_ << " Send(" - << fin << ", " << type_to_pass << ", " - << "(data size = " << size << "))"; - - ChildThreadImpl::current()->Send( - new WebSocketMsg_SendFrame(channel_id_, - fin, - type_to_pass, - std::vector<char>(data, data + size))); -} - -void WebSocketBridge::flowControl(int64_t quota) { - if (channel_id_ == kInvalidChannelId) - return; - - DVLOG(1) << "Bridge #" << channel_id_ << " FlowControl(" << quota << ")"; - - ChildThreadImpl::current()->Send( - new WebSocketMsg_FlowControl(channel_id_, quota)); -} - -void WebSocketBridge::close(unsigned short code, - const WebString& reason) { - if (channel_id_ == kInvalidChannelId) - return; - - std::string reason_to_pass = reason.utf8(); - DVLOG(1) << "Bridge #" << channel_id_ << " Close(" - << code << ", " << reason_to_pass << ")"; - // This method is for closing handshake and hence |was_clean| shall be true. - ChildThreadImpl::current()->Send( - new WebSocketMsg_DropChannel(channel_id_, true, code, reason_to_pass)); -} - -void WebSocketBridge::Disconnect() { - if (channel_id_ == kInvalidChannelId) - return; - WebSocketDispatcher* dispatcher = - ChildThreadImpl::current()->websocket_dispatcher(); - dispatcher->RemoveBridge(channel_id_); - - channel_id_ = kInvalidChannelId; - client_ = NULL; -} - -} // namespace content
diff --git a/content/child/websocket_bridge.h b/content/child/websocket_bridge.h deleted file mode 100644 index d8ccc2b..0000000 --- a/content/child/websocket_bridge.h +++ /dev/null
@@ -1,77 +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 CONTENT_CHILD_WEBSOCKET_BRIDGE_H_ -#define CONTENT_CHILD_WEBSOCKET_BRIDGE_H_ - -#include <stddef.h> -#include <stdint.h> -#include <string> -#include <vector> - -#include "content/common/websocket.h" -#include "ipc/ipc_message.h" -#include "third_party/WebKit/public/platform/WebVector.h" -#include "third_party/WebKit/public/platform/modules/websockets/WebSocketHandle.h" - -namespace blink { -class WebSecurityOrigin; -class WebString; -class WebURL; -} // namespace blink - -namespace content { - -class WebSocketBridge : public blink::WebSocketHandle { - public: - WebSocketBridge(); - - // Handles an IPC message from the browser process. - bool OnMessageReceived(const IPC::Message& message); - - // WebSocketHandle functions. - void connect(const blink::WebURL& url, - const blink::WebVector<blink::WebString>& protocols, - const blink::WebSecurityOrigin& origin, - const blink::WebURL& first_party_for_cookies, - const blink::WebString& user_agent_override, - blink::WebSocketHandleClient* client) override; - void send(bool fin, - WebSocketHandle::MessageType type, - const char* data, - size_t size) override; - void flowControl(int64_t quota) override; - void close(unsigned short code, const blink::WebString& reason) override; - - void Disconnect(); - - void set_render_frame_id(int id) { - render_frame_id_ = id; - } - - private: - ~WebSocketBridge() override; - - void DidConnect(const std::string& selected_protocol, - const std::string& extensions); - void DidStartOpeningHandshake(const WebSocketHandshakeRequest& request); - void DidFinishOpeningHandshake(const WebSocketHandshakeResponse& response); - void DidFail(const std::string& message); - void DidReceiveData(bool fin, - WebSocketMessageType type, - const std::vector<char>& data); - void DidReceiveFlowControl(int64_t quota); - void DidClose(bool was_clean, unsigned short code, const std::string& reason); - void DidStartClosingHandshake(); - - int channel_id_; - int render_frame_id_; - blink::WebSocketHandleClient* client_; - - static const int kInvalidChannelId = -1; -}; - -} // namespace content - -#endif // CONTENT_CHILD_WEBSOCKET_BRIDGE_H_
diff --git a/content/child/websocket_dispatcher.cc b/content/child/websocket_dispatcher.cc deleted file mode 100644 index 13535eb..0000000 --- a/content/child/websocket_dispatcher.cc +++ /dev/null
@@ -1,74 +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 "content/child/websocket_dispatcher.h" - -#include <stdint.h> -#include <map> - -#include "base/logging.h" -#include "content/child/websocket_bridge.h" -#include "content/common/websocket_messages.h" -#include "ipc/ipc_message.h" -#include "url/gurl.h" - -namespace content { - -WebSocketDispatcher::WebSocketDispatcher() - : channel_id_max_(0), - weak_ptr_factory_(this) {} - -WebSocketDispatcher::~WebSocketDispatcher() {} - -bool WebSocketDispatcher::CanHandleMessage(const IPC::Message& msg) { - switch (msg.type()) { - case WebSocketMsg_AddChannelResponse::ID: - case WebSocketMsg_NotifyStartOpeningHandshake::ID: - case WebSocketMsg_NotifyFinishOpeningHandshake::ID: - case WebSocketMsg_NotifyFailure::ID: - case WebSocketMsg_SendFrame::ID: - case WebSocketMsg_FlowControl::ID: - case WebSocketMsg_DropChannel::ID: - case WebSocketMsg_NotifyClosing::ID: - return true; - default: - return false; - } -} - -int WebSocketDispatcher::AddBridge(WebSocketBridge* bridge) { - ++channel_id_max_; - bridges_.insert(std::make_pair(channel_id_max_, bridge)); - return channel_id_max_; -} - -void WebSocketDispatcher::RemoveBridge(int channel_id) { - std::map<int, WebSocketBridge*>::iterator iter = bridges_.find(channel_id); - if (iter == bridges_.end()) { - DVLOG(1) << "Remove a non-existent bridge(" << channel_id << ")"; - return; - } - bridges_.erase(iter); -} - -bool WebSocketDispatcher::OnMessageReceived(const IPC::Message& msg) { - if (!CanHandleMessage(msg)) - return false; - WebSocketBridge* bridge = GetBridge(msg.routing_id(), msg.type()); - if (!bridge) - return true; - return bridge->OnMessageReceived(msg); -} - -WebSocketBridge* WebSocketDispatcher::GetBridge(int channel_id, uint32_t type) { - std::map<int, WebSocketBridge*>::iterator iter = bridges_.find(channel_id); - if (iter == bridges_.end()) { - DVLOG(1) << "No bridge for channel_id=" << channel_id - << ", type=" << type; - return NULL; - } - return iter->second; -} - -} // namespace content
diff --git a/content/child/websocket_dispatcher.h b/content/child/websocket_dispatcher.h deleted file mode 100644 index bd2fd50..0000000 --- a/content/child/websocket_dispatcher.h +++ /dev/null
@@ -1,56 +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 CONTENT_CHILD_WEBSOCKET_DISPATCHER_H_ -#define CONTENT_CHILD_WEBSOCKET_DISPATCHER_H_ - -#include <stdint.h> -#include <map> -#include <string> -#include <vector> - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "ipc/ipc_listener.h" - -namespace content { - -class WebSocketBridge; - -// Dispatches WebSocket related messages sent to a child process from the -// main browser process. There is one instance per child process. Messages -// are dispatched on the main child thread. The ChildThread class -// creates an instance of WebSocketDispatcher and delegates calls to it. -class WebSocketDispatcher : public IPC::Listener { - public: - WebSocketDispatcher(); - ~WebSocketDispatcher() override; - - static bool CanHandleMessage(const IPC::Message& msg); - - // Returns a unique channel id - int AddBridge(WebSocketBridge* bridge); - void RemoveBridge(int channel_id); - - // IPC::Listener implementation. - bool OnMessageReceived(const IPC::Message& msg) override; - - base::WeakPtr<WebSocketDispatcher> GetWeakPtr() { - return weak_ptr_factory_.GetWeakPtr(); - } - - private: - WebSocketBridge* GetBridge(int channel_id, uint32_t type); - - std::map<int, WebSocketBridge*> bridges_; - int channel_id_max_; - base::WeakPtrFactory<WebSocketDispatcher> weak_ptr_factory_; - - DISALLOW_COPY_AND_ASSIGN(WebSocketDispatcher); -}; - -} // namespace content - -#endif // CONTENT_CHILD_WEBSOCKET_DISPATCHER_H_
diff --git a/content/child/websocket_message_filter.cc b/content/child/websocket_message_filter.cc deleted file mode 100644 index b2e54c0..0000000 --- a/content/child/websocket_message_filter.cc +++ /dev/null
@@ -1,36 +0,0 @@ -// Copyright 2016 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/child/websocket_message_filter.h" - -#include "base/bind.h" -#include "base/single_thread_task_runner.h" -#include "content/child/websocket_dispatcher.h" -#include "ipc/ipc_message.h" - -namespace content { - -WebSocketMessageFilter::WebSocketMessageFilter( - WebSocketDispatcher* websocket_dispatcher) - : websocket_dispatcher_(websocket_dispatcher->GetWeakPtr()) {} - -WebSocketMessageFilter::~WebSocketMessageFilter() {} - -bool WebSocketMessageFilter::OnMessageReceived(const IPC::Message& message) { - if (!WebSocketDispatcher::CanHandleMessage(message)) - return false; - loading_task_runner_->PostTask(FROM_HERE, base::Bind( - &WebSocketMessageFilter::OnMessageReceivedOnMainThread, - this, message)); - return true; -} - -void WebSocketMessageFilter::OnMessageReceivedOnMainThread( - const IPC::Message& message) { - if (!websocket_dispatcher_.get()) - return; - websocket_dispatcher_->OnMessageReceived(message); -} - -} // namespace content
diff --git a/content/child/websocket_message_filter.h b/content/child/websocket_message_filter.h deleted file mode 100644 index 00efbb2..0000000 --- a/content/child/websocket_message_filter.h +++ /dev/null
@@ -1,50 +0,0 @@ -// Copyright 2016 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_CHILD_WEBSOCKET_MESSAGE_FILTER_H_ -#define CONTENT_CHILD_WEBSOCKET_MESSAGE_FILTER_H_ - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "ipc/message_filter.h" - -namespace base { -class SingleThreadTaskRunner; -} - -namespace content { - -class WebSocketDispatcher; - -// Delegates IPC messages to a WebSocketDispatcher on the loading task queue -// instead of the default task queue. -class WebSocketMessageFilter : public IPC::MessageFilter { - public: - explicit WebSocketMessageFilter(WebSocketDispatcher* websocket_dispatcher); - - // IPC::MessageFilter implementation. - bool OnMessageReceived(const IPC::Message& message) override; - - void SetLoadingTaskRunner( - scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner) { - loading_task_runner_ = loading_task_runner; - } - - private: - ~WebSocketMessageFilter() override; - void OnMessageReceivedOnMainThread(const IPC::Message& message); - - scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_; - - // This actual object is owned by a ChildThreadImpl and is derefed only on the - // main thread. - base::WeakPtr<WebSocketDispatcher> websocket_dispatcher_; - - DISALLOW_COPY_AND_ASSIGN(WebSocketMessageFilter); -}; - -} // namespace content - -#endif // CONTENT_CHILD_WEBSOCKET_MESSAGE_FILTER_H_
diff --git a/content/child/worker_thread_registry.cc b/content/child/worker_thread_registry.cc index 2ca217f..cfc9d837 100644 --- a/content/child/worker_thread_registry.cc +++ b/content/child/worker_thread_registry.cc
@@ -119,7 +119,7 @@ base::TaskRunner* WorkerThreadRegistry::GetTaskRunnerFor(int worker_id) { base::AutoLock locker(task_runner_map_lock_); - return ContainsKey(task_runner_map_, worker_id) + return base::ContainsKey(task_runner_map_, worker_id) ? task_runner_map_[worker_id] : task_runner_for_dead_worker_.get(); }
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index 3078d4d9..df1add11 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -37,6 +37,9 @@ "//third_party/WebKit/public:blink_headers", ] deps = [ + # This looks needless as we have :mojo_bindings in public_deps, but it's + # needed because of allow_circular_includes_from. + ":mojo_bindings_cpp_sources", "//base", "//base/third_party/dynamic_annotations", "//build/util:webkit_version", @@ -104,6 +107,8 @@ libs = [] ldflags = [] + allow_circular_includes_from = [ ":mojo_bindings_cpp_sources" ] + if (is_android && use_seccomp_bpf) { set_sources_assignment_filter([]) sources += [ @@ -245,6 +250,9 @@ "render_widget_window_tree_client_factory.mojom", "service_worker/embedded_worker_setup.mojom", "storage_partition_service.mojom", + "url_loader.mojom", + "url_loader_factory.mojom", + "websocket.mojom", ] import_dirs = [ "//mojo/services" ]
diff --git a/content/common/cache_storage/cache_storage_types.h b/content/common/cache_storage/cache_storage_types.h index 22e91c0..3db2ab0 100644 --- a/content/common/cache_storage/cache_storage_types.h +++ b/content/common/cache_storage/cache_storage_types.h
@@ -8,7 +8,7 @@ #include <map> #include <string> -#include "base/strings/string16.h" +#include "base/strings/nullable_string16.h" #include "content/common/content_export.h" #include "content/common/service_worker/service_worker_types.h" @@ -24,7 +24,7 @@ bool ignore_search; bool ignore_method; bool ignore_vary; - base::string16 cache_name; + base::NullableString16 cache_name; }; // The type of a single batch operation in the Cache API.
diff --git a/content/common/content_message_generator.h b/content/common/content_message_generator.h index e436f93..7b8c0c8 100644 --- a/content/common/content_message_generator.h +++ b/content/common/content_message_generator.h
@@ -52,7 +52,6 @@ #include "content/common/text_input_client_messages.h" #include "content/common/utility_messages.h" #include "content/common/view_messages.h" -#include "content/common/websocket_messages.h" #include "content/common/worker_messages.h" #if defined(ENABLE_WEBRTC)
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index 5a649f33..2fa1b54 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -367,6 +367,12 @@ IPC_STRUCT_TRAITS_MEMBER(transferred_request_request_id) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(content::NavigationTiming) + IPC_STRUCT_TRAITS_MEMBER(redirect_start) + IPC_STRUCT_TRAITS_MEMBER(redirect_end) + IPC_STRUCT_TRAITS_MEMBER(fetch_start) +IPC_STRUCT_TRAITS_END() + IPC_STRUCT_TRAITS_BEGIN(content::RequestNavigationParams) IPC_STRUCT_TRAITS_MEMBER(is_overriding_user_agent) IPC_STRUCT_TRAITS_MEMBER(redirects) @@ -385,6 +391,7 @@ IPC_STRUCT_TRAITS_MEMBER(is_view_source) IPC_STRUCT_TRAITS_MEMBER(should_clear_history_list) IPC_STRUCT_TRAITS_MEMBER(should_create_service_worker) + IPC_STRUCT_TRAITS_MEMBER(navigation_timing) #if defined(OS_ANDROID) IPC_STRUCT_TRAITS_MEMBER(data_url_as_string) #endif @@ -1431,9 +1438,8 @@ // The security info is non empty if the resource was originally loaded over // a secure connection. // Note: May only be sent once per URL per frame per committed load. -IPC_MESSAGE_ROUTED5(FrameHostMsg_DidLoadResourceFromMemoryCache, +IPC_MESSAGE_ROUTED4(FrameHostMsg_DidLoadResourceFromMemoryCache, GURL /* url */, - std::string /* security info */, std::string /* http method */, std::string /* mime type */, content::ResourceType /* resource type */)
diff --git a/content/common/input/event_with_latency_info.cc b/content/common/input/event_with_latency_info.cc index 49359a1..0fc592be 100644 --- a/content/common/input/event_with_latency_info.cc +++ b/content/common/input/event_with_latency_info.cc
@@ -254,9 +254,10 @@ } // namespace internal ScopedWebInputEventWithLatencyInfo::ScopedWebInputEventWithLatencyInfo( - const WebInputEvent& event, + ScopedWebInputEvent event, const ui::LatencyInfo& latency_info) - : event_(WebInputEventTraits::Clone(event)), latency_(latency_info) {} + : event_(std::move(event)), latency_(latency_info) { +} ScopedWebInputEventWithLatencyInfo::~ScopedWebInputEventWithLatencyInfo() {}
diff --git a/content/common/input/event_with_latency_info.h b/content/common/input/event_with_latency_info.h index b9ee6a4..e4ddc29a 100644 --- a/content/common/input/event_with_latency_info.h +++ b/content/common/input/event_with_latency_info.h
@@ -37,7 +37,7 @@ class ScopedWebInputEventWithLatencyInfo { public: - ScopedWebInputEventWithLatencyInfo(const blink::WebInputEvent&, + ScopedWebInputEventWithLatencyInfo(ScopedWebInputEvent, const ui::LatencyInfo&); ~ScopedWebInputEventWithLatencyInfo();
diff --git a/content/common/mojo/mojo_shell_connection_impl.cc b/content/common/mojo/mojo_shell_connection_impl.cc index ac66294..248c69c 100644 --- a/content/common/mojo/mojo_shell_connection_impl.cc +++ b/content/common/mojo/mojo_shell_connection_impl.cc
@@ -44,7 +44,7 @@ public: using InitializeCallback = base::Callback<void(const shell::Identity&)>; using ServiceFactoryCallback = - base::Callback<void(shell::mojom::ServiceRequest, const mojo::String&)>; + base::Callback<void(shell::mojom::ServiceRequest, const std::string&)>; IOThreadContext(shell::mojom::ServiceRequest service_request, scoped_refptr<base::SequencedTaskRunner> io_task_runner, @@ -198,7 +198,7 @@ // shell::mojom::ServiceFactory implementation void CreateService(shell::mojom::ServiceRequest request, - const mojo::String& name) override { + const std::string& name) override { DCHECK(io_thread_checker_.CalledOnValidThread()); callback_task_runner_->PostTask( FROM_HERE, @@ -208,7 +208,7 @@ static void CallBinderOnTaskRunner( scoped_refptr<base::SequencedTaskRunner> task_runner, const shell::InterfaceRegistry::Binder& binder, - const mojo::String& interface_name, + const std::string& interface_name, mojo::ScopedMessagePipeHandle request_handle) { task_runner->PostTask(FROM_HERE, base::Bind(binder, interface_name, base::Passed(&request_handle))); @@ -391,7 +391,7 @@ void MojoShellConnectionImpl::CreateService( shell::mojom::ServiceRequest request, - const mojo::String& name) { + const std::string& name) { auto it = request_handlers_.find(name); if (it != request_handlers_.end()) it->second.Run(std::move(request)); @@ -411,7 +411,7 @@ void MojoShellConnectionImpl::GetInterface( shell::mojom::InterfaceProvider* provider, - const mojo::String& interface_name, + const std::string& interface_name, mojo::ScopedMessagePipeHandle request_handle) { provider->GetInterface(interface_name, std::move(request_handle)); }
diff --git a/content/common/mojo/mojo_shell_connection_impl.h b/content/common/mojo/mojo_shell_connection_impl.h index 00d3c660..37f2a0a0 100644 --- a/content/common/mojo/mojo_shell_connection_impl.h +++ b/content/common/mojo/mojo_shell_connection_impl.h
@@ -56,9 +56,9 @@ void OnContextInitialized(const shell::Identity& identity); void OnConnectionLost(); void CreateService(shell::mojom::ServiceRequest request, - const mojo::String& name); + const std::string& name); void GetInterface(shell::mojom::InterfaceProvider* provider, - const mojo::String& interface_name, + const std::string& interface_name, mojo::ScopedMessagePipeHandle request_handle); shell::Identity identity_;
diff --git a/content/common/navigation_params.h b/content/common/navigation_params.h index 1fbbcec..f288a14 100644 --- a/content/common/navigation_params.h +++ b/content/common/navigation_params.h
@@ -203,6 +203,16 @@ int transferred_request_request_id; }; +// PlzNavigate +// Timings collected in the browser during navigation for the +// Navigation Timing API. Sent to Blink in RequestNavigationParams when +// the navigation is ready to be committed. +struct CONTENT_EXPORT NavigationTiming { + base::TimeTicks redirect_start; + base::TimeTicks redirect_end; + base::TimeTicks fetch_start; +}; + // Used by FrameMsg_Navigate. Holds the parameters needed by the renderer to // start a browser-initiated navigation besides those in CommonNavigationParams. // PlzNavigate: sent to the renderer to make it issue a stream request for a @@ -304,6 +314,10 @@ // Whether a ServiceWorkerProviderHost should be created for the window. bool should_create_service_worker; + // PlzNavigate + // Timing of navigation events. + NavigationTiming navigation_timing; + #if defined(OS_ANDROID) // The real content of the data: URL. Only used in Android WebView for // implementing LoadDataWithBaseUrl API method to circumvent the restriction
diff --git a/content/common/origin_trials/trial_token_validator.cc b/content/common/origin_trials/trial_token_validator.cc index 95812b7..34ae304 100644 --- a/content/common/origin_trials/trial_token_validator.cc +++ b/content/common/origin_trials/trial_token_validator.cc
@@ -4,10 +4,15 @@ #include "content/common/origin_trials/trial_token_validator.h" +#include "base/feature_list.h" #include "base/time/time.h" #include "content/common/origin_trials/trial_token.h" #include "content/public/common/content_client.h" +#include "content/public/common/content_features.h" #include "content/public/common/origin_trial_policy.h" +#include "content/public/common/origin_util.h" +#include "net/http/http_response_headers.h" +#include "net/url_request/url_request.h" #include "third_party/WebKit/public/platform/WebOriginTrialTokenStatus.h" namespace content { @@ -45,4 +50,37 @@ return blink::WebOriginTrialTokenStatus::Success; } +bool TrialTokenValidator::RequestEnablesFeature( + const net::URLRequest* request, + base::StringPiece feature_name) { + // TODO(mek): Possibly cache the features that are availble for request in + // UserData associated with the request. + return RequestEnablesFeature(request->url(), request->response_headers(), + feature_name); +} + +bool TrialTokenValidator::RequestEnablesFeature( + const GURL& request_url, + const net::HttpResponseHeaders* response_headers, + base::StringPiece feature_name) { + if (!base::FeatureList::IsEnabled(features::kOriginTrials)) + return false; + + if (!IsOriginSecure(request_url)) + return false; + + url::Origin origin(request_url); + size_t iter = 0; + std::string token; + while (response_headers->EnumerateHeader(&iter, "Origin-Trial", &token)) { + std::string token_feature; + // TODO(mek): Log the validation errors to histograms? + if (ValidateToken(token, origin, &token_feature) == + blink::WebOriginTrialTokenStatus::Success) + if (token_feature == feature_name) + return true; + } + return false; +} + } // namespace content
diff --git a/content/common/origin_trials/trial_token_validator.h b/content/common/origin_trials/trial_token_validator.h index ec74e9a..1997985 100644 --- a/content/common/origin_trials/trial_token_validator.h +++ b/content/common/origin_trials/trial_token_validator.h
@@ -14,6 +14,11 @@ enum class WebOriginTrialTokenStatus; } +namespace net { +class HttpResponseHeaders; +class URLRequest; +} + namespace content { namespace TrialTokenValidator { @@ -26,6 +31,14 @@ const url::Origin& origin, std::string* feature_name); +CONTENT_EXPORT bool RequestEnablesFeature(const net::URLRequest* request, + base::StringPiece feature_name); + +CONTENT_EXPORT bool RequestEnablesFeature( + const GURL& request_url, + const net::HttpResponseHeaders* response_headers, + base::StringPiece feature_name); + } // namespace TrialTokenValidator } // namespace content
diff --git a/content/common/origin_trials/trial_token_validator_unittest.cc b/content/common/origin_trials/trial_token_validator_unittest.cc index e3c4482..19b5d44c 100644 --- a/content/common/origin_trials/trial_token_validator_unittest.cc +++ b/content/common/origin_trials/trial_token_validator_unittest.cc
@@ -14,6 +14,7 @@ #include "base/time/time.h" #include "content/public/common/content_client.h" #include "content/public/common/origin_trial_policy.h" +#include "net/http/http_response_headers.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/public/platform/WebOriginTrialTokenStatus.h" #include "url/gurl.h" @@ -87,6 +88,16 @@ const char kUnparsableToken[] = "abcde"; +// Well-formed token, for an insecure origin. +// Generate this token with the command (in tools/origin_trials): +// generate_token.py http://valid.example.com Frobulate +// --expire-timestamp=2000000000 +const char kInsecureOriginToken[] = + "AjfC47H1q8/Ho5ALFkjkwf9CBK6oUUeRTlFc50Dj+eZEyGGKFIY2WTxMBfy8cLc3" + "E0nmFroDA3OmABmO5jMCFgkAAABXeyJvcmlnaW4iOiAiaHR0cDovL3ZhbGlkLmV4" + "YW1wbGUuY29tOjgwIiwgImZlYXR1cmUiOiAiRnJvYnVsYXRlIiwgImV4cGlyeSI6" + "IDIwMDAwMDAwMDB9"; + class TestOriginTrialPolicy : public OriginTrialPolicy { public: base::StringPiece GetPublicKey() const override { @@ -133,7 +144,8 @@ TrialTokenValidatorTest() : appropriate_origin_(GURL(kAppropriateOrigin)), inappropriate_origin_(GURL(kInappropriateOrigin)), - insecure_origin_(GURL(kInsecureOrigin)) { + insecure_origin_(GURL(kInsecureOrigin)), + response_headers_(new net::HttpResponseHeaders("")) { SetPublicKey(kTestPublicKey); SetContentClient(&test_content_client_); } @@ -152,6 +164,8 @@ const url::Origin inappropriate_origin_; const url::Origin insecure_origin_; + scoped_refptr<net::HttpResponseHeaders> response_headers_; + private: TestContentClient test_content_client_; }; @@ -218,4 +232,52 @@ appropriate_origin_, &feature)); } +TEST_F(TrialTokenValidatorTest, ValidateRequestInsecure) { + response_headers_->AddHeader(std::string("Origin-Trial: ") + + kInsecureOriginToken); + EXPECT_FALSE(TrialTokenValidator::RequestEnablesFeature( + GURL(kInsecureOrigin), response_headers_.get(), kAppropriateFeatureName)); +} + +TEST_F(TrialTokenValidatorTest, ValidateRequestValidToken) { + response_headers_->AddHeader(std::string("Origin-Trial: ") + kSampleToken); + EXPECT_TRUE(TrialTokenValidator::RequestEnablesFeature( + GURL(kAppropriateOrigin), response_headers_.get(), + kAppropriateFeatureName)); +} + +TEST_F(TrialTokenValidatorTest, ValidateRequestNoTokens) { + EXPECT_FALSE(TrialTokenValidator::RequestEnablesFeature( + GURL(kAppropriateOrigin), response_headers_.get(), + kAppropriateFeatureName)); +} + +TEST_F(TrialTokenValidatorTest, ValidateRequestMultipleHeaders) { + response_headers_->AddHeader(std::string("Origin-Trial: ") + kSampleToken); + response_headers_->AddHeader(std::string("Origin-Trial: ") + kExpiredToken); + EXPECT_TRUE(TrialTokenValidator::RequestEnablesFeature( + GURL(kAppropriateOrigin), response_headers_.get(), + kAppropriateFeatureName)); + EXPECT_FALSE(TrialTokenValidator::RequestEnablesFeature( + GURL(kAppropriateOrigin), response_headers_.get(), + kInappropriateFeatureName)); + EXPECT_FALSE(TrialTokenValidator::RequestEnablesFeature( + GURL(kInappropriateOrigin), response_headers_.get(), + kAppropriateFeatureName)); +} + +TEST_F(TrialTokenValidatorTest, ValidateRequestMultipleHeaderValues) { + response_headers_->AddHeader(std::string("Origin-Trial: ") + kExpiredToken + + ", " + kSampleToken); + EXPECT_TRUE(TrialTokenValidator::RequestEnablesFeature( + GURL(kAppropriateOrigin), response_headers_.get(), + kAppropriateFeatureName)); + EXPECT_FALSE(TrialTokenValidator::RequestEnablesFeature( + GURL(kAppropriateOrigin), response_headers_.get(), + kInappropriateFeatureName)); + EXPECT_FALSE(TrialTokenValidator::RequestEnablesFeature( + GURL(kInappropriateOrigin), response_headers_.get(), + kAppropriateFeatureName)); +} + } // namespace content
diff --git a/content/common/origin_util.cc b/content/common/origin_util.cc index 275d28f0..11873d6 100644 --- a/content/common/origin_util.cc +++ b/content/common/origin_util.cc
@@ -62,11 +62,12 @@ if (net::IsLocalhost(hostname)) return true; - if (ContainsKey(g_trustworthy_whitelist.Get().secure_schemes(), url.scheme())) + if (base::ContainsKey(g_trustworthy_whitelist.Get().secure_schemes(), + url.scheme())) return true; - if (ContainsKey(g_trustworthy_whitelist.Get().secure_origins(), - url.GetOrigin())) { + if (base::ContainsKey(g_trustworthy_whitelist.Get().secure_origins(), + url.GetOrigin())) { return true; } @@ -77,8 +78,8 @@ if (url.SchemeIsHTTPOrHTTPS() && IsOriginSecure(url)) return true; - if (ContainsKey(g_trustworthy_whitelist.Get().service_worker_schemes(), - url.scheme())) { + if (base::ContainsKey(g_trustworthy_whitelist.Get().service_worker_schemes(), + url.scheme())) { return true; }
diff --git a/content/common/page_messages.h b/content/common/page_messages.h index 77aa978c..0c9b84e 100644 --- a/content/common/page_messages.h +++ b/content/common/page_messages.h
@@ -27,6 +27,9 @@ PageMsg_SetZoomLevel_Command /* command */, double /* zoom_level */) +IPC_MESSAGE_ROUTED1(PageMsg_SetDeviceScaleFactor, + double /* device_scale_factor */) + // Informs the renderer that the page was hidden. IPC_MESSAGE_ROUTED0(PageMsg_WasHidden)
diff --git a/content/common/typemaps.gni b/content/common/typemaps.gni new file mode 100644 index 0000000..2dd3ed67 --- /dev/null +++ b/content/common/typemaps.gni
@@ -0,0 +1,9 @@ +# Copyright 2016 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. + +typemaps = [ + "//content/common/url_loader_status.typemap", + "//content/common/url_request.typemap", + "//content/common/url_response_head.typemap", +]
diff --git a/content/common/url_loader.mojom b/content/common/url_loader.mojom new file mode 100644 index 0000000..bdb7258 --- /dev/null +++ b/content/common/url_loader.mojom
@@ -0,0 +1,39 @@ +// Copyright 2016 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 content.mojom; + +[Native] +struct URLRequest; + +[Native] +struct URLResponseHead; + +[Native] +struct URLLoaderStatus; + +interface URLLoader { + // If the associated request has |auto_follow_redirects| set to false, + // then upon receiving an URLResponse with a non-NULL |redirect_url| field, + // |FollowRedirect| may be called to load the URL indicated by the redirect. + FollowRedirect(); + + // Cancels the request. The service will cancel loading, but there may be some + // time lag and it is possible that the client gets some notification after + // calling this method for a while. + Cancel(); +}; + +interface URLLoaderClient { + // Called when the response head is received. + OnReceiveResponse(URLResponseHead head); + + // Called when the loader starts loading response body. + OnStartLoadingResponseBody(handle<data_pipe_consumer> body); + + // Called when the loading completes. No notification will be dispatched for + // this client after this message arrives. + OnComplete(URLLoaderStatus completion_status); +}; +
diff --git a/content/common/url_loader_factory.mojom b/content/common/url_loader_factory.mojom new file mode 100644 index 0000000..4b69303e --- /dev/null +++ b/content/common/url_loader_factory.mojom
@@ -0,0 +1,18 @@ +// Copyright 2016 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 content.mojom; + +import "url_loader.mojom"; + +interface URLLoaderFactory { + // Creats a URLLoader and starts loading with the given |request|. |client|'s + // method will be called when certain events related to that loading + // (e.g., response arrival) happen. |request_id| is for compatibility with + // the existing Chrome IPC. + CreateLoaderAndStart(URLLoader& loader, + int32 request_id, + URLRequest request, + URLLoaderClient client); +}; \ No newline at end of file
diff --git a/content/common/url_loader_status.typemap b/content/common/url_loader_status.typemap new file mode 100644 index 0000000..12d4bd3 --- /dev/null +++ b/content/common/url_loader_status.typemap
@@ -0,0 +1,14 @@ +# Copyright 2016 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. + +mojom = "//content/common/url_loader.mojom" +public_headers = [ "//content/common/resource_request_completion_status.h" ] +traits_headers = [ "//content/common/resource_messages.h" ] +deps = [ + "//content:export", + "//net:net", + "//third_party/WebKit/public:blink_minimal", +] +type_mappings = + [ "content.mojom.URLLoaderStatus=content::ResourceRequestCompletionStatus" ]
diff --git a/content/common/url_request.typemap b/content/common/url_request.typemap new file mode 100644 index 0000000..8e46a0b --- /dev/null +++ b/content/common/url_request.typemap
@@ -0,0 +1,14 @@ +# Copyright 2016 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. + +mojom = "//content/common/url_loader.mojom" +public_headers = [ "//content/common/resource_request.h" ] +traits_headers = [ "//content/common/resource_messages.h" ] +deps = [ + "//content:export", + "//net:net", + "//third_party/WebKit/public:blink_minimal", + "//ui/base", +] +type_mappings = [ "content.mojom.URLRequest=content::ResourceRequest" ]
diff --git a/content/common/url_response_head.typemap b/content/common/url_response_head.typemap new file mode 100644 index 0000000..f5c17ce3 --- /dev/null +++ b/content/common/url_response_head.typemap
@@ -0,0 +1,14 @@ +# Copyright 2016 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. + +mojom = "//content/common/url_loader.mojom" +public_headers = [ "//content/public/common/resource_response.h" ] +traits_headers = [ "//content/common/resource_messages.h" ] +deps = [ + "//content:export", + "//net:net", + "//third_party/WebKit/public:blink_minimal", +] +type_mappings = + [ "content.mojom.URLResponseHead=content::ResourceResponseHead" ]
diff --git a/content/common/view_messages.h b/content/common/view_messages.h index 562ec44..7cd7683 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h
@@ -233,6 +233,8 @@ IPC_STRUCT_TRAITS_MEMBER(enable_referrers) IPC_STRUCT_TRAITS_MEMBER(enable_do_not_track) IPC_STRUCT_TRAITS_MEMBER(webrtc_ip_handling_policy) + IPC_STRUCT_TRAITS_MEMBER(webrtc_udp_min_port) + IPC_STRUCT_TRAITS_MEMBER(webrtc_udp_max_port) IPC_STRUCT_TRAITS_MEMBER(user_agent_override) IPC_STRUCT_TRAITS_MEMBER(accept_languages) IPC_STRUCT_TRAITS_MEMBER(report_frame_name_changes) @@ -819,11 +821,11 @@ IPC_MESSAGE_ROUTED0(ViewMsg_SelectWordAroundCaret) -// Sent by the browser to ask the renderer to redraw. -// If |request_id| is not zero, it is added to the forced frame's latency info -// as ui::WINDOW_SNAPSHOT_FRAME_NUMBER_COMPONENT. +// Sent by the browser to ask the renderer to redraw. Robust to events that can +// happen in renderer (abortion of the commit or draw, loss of output surface +// etc.). IPC_MESSAGE_ROUTED1(ViewMsg_ForceRedraw, - int /* request_id */) + ui::LatencyInfo /* latency_info */) // Let renderer know begin frame messages won't be sent even if requested. IPC_MESSAGE_ROUTED1(ViewMsg_SetBeginFramePaused, bool /* paused */)
diff --git a/content/common/websocket.cc b/content/common/websocket.cc deleted file mode 100644 index b1d57611..0000000 --- a/content/common/websocket.cc +++ /dev/null
@@ -1,18 +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 "content/common/websocket.h" - -namespace content { - -WebSocketHandshakeRequest::WebSocketHandshakeRequest() {} - -WebSocketHandshakeRequest::~WebSocketHandshakeRequest() {} - -WebSocketHandshakeResponse::WebSocketHandshakeResponse() - : status_code(0) {} - -WebSocketHandshakeResponse::~WebSocketHandshakeResponse() {} - -} // namespace content
diff --git a/content/common/websocket.h b/content/common/websocket.h deleted file mode 100644 index 324e9a10..0000000 --- a/content/common/websocket.h +++ /dev/null
@@ -1,64 +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 CONTENT_COMMON_WEBSOCKET_H_ -#define CONTENT_COMMON_WEBSOCKET_H_ - -#include <string> -#include <utility> -#include <vector> - -#include "base/strings/string_split.h" -#include "base/time/time.h" -#include "url/gurl.h" - -namespace content { - -// WebSocket data message types sent between the browser and renderer processes. -enum WebSocketMessageType { - WEB_SOCKET_MESSAGE_TYPE_CONTINUATION = 0x0, - WEB_SOCKET_MESSAGE_TYPE_TEXT = 0x1, - WEB_SOCKET_MESSAGE_TYPE_BINARY = 0x2, - WEB_SOCKET_MESSAGE_TYPE_LAST = WEB_SOCKET_MESSAGE_TYPE_BINARY -}; - -// Opening handshake request information which will be shown in the inspector. -// All string data should be encoded to ASCII in the browser process. -struct WebSocketHandshakeRequest { - WebSocketHandshakeRequest(); - ~WebSocketHandshakeRequest(); - - // The request URL - GURL url; - // Additional HTTP request headers - base::StringPairs headers; - // HTTP request headers raw string - std::string headers_text; - // The time that this request is sent - base::Time request_time; -}; - -// Opening handshake response information which will be shown in the inspector. -// All string data should be encoded to ASCII in the browser process. -struct WebSocketHandshakeResponse { - WebSocketHandshakeResponse(); - ~WebSocketHandshakeResponse(); - - // The request URL - GURL url; - // HTTP status code - int status_code; - // HTTP status text - std::string status_text; - // Additional HTTP response headers - base::StringPairs headers; - // HTTP response headers raw string - std::string headers_text; - // The time that this response arrives - base::Time response_time; -}; - -} // namespace content - -#endif // CONTENT_COMMON_WEBSOCKET_H_
diff --git a/content/common/websocket.mojom b/content/common/websocket.mojom new file mode 100644 index 0000000..120f4e96 --- /dev/null +++ b/content/common/websocket.mojom
@@ -0,0 +1,138 @@ +// Copyright 2016 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 content.mojom; + +import "url/mojo/origin.mojom"; +import "url/mojo/url.mojom"; + +enum WebSocketMessageType { + CONTINUATION, + TEXT, + BINARY, + LAST = BINARY +}; + +// TODO(darin): Move to a more general location. +struct HttpHeader { + string name; + string value; +}; + +// TODO(darin): Remove redundancy b/w |headers| and |headers_text|. + +struct WebSocketHandshakeRequest { + url.mojom.Url url; + array<HttpHeader> headers; + string headers_text; +}; + +struct WebSocketHandshakeResponse { + url.mojom.Url url; + int32 status_code; + string status_text; + array<HttpHeader> headers; + string headers_text; +}; + +interface WebSocketClient { + OnFailChannel(string reason); + + // Notify the renderer that the browser has started an opening handshake. + // This message is for showing the request in the inspector and + // can be omitted if the inspector is not active. + OnStartOpeningHandshake(WebSocketHandshakeRequest request); + + // Notify the renderer that the browser has finished an opening handshake. + // This message precedes AddChannelResponse. + // This message is for showing the response in the inspector and + // can be omitted if the inspector is not active. + OnFinishOpeningHandshake(WebSocketHandshakeResponse response); + + // Response to an AddChannelRequest. |selected_protocol| is the sub-protocol + // the server selected, or empty if no sub-protocol was selected. + // |extensions| is the list of extensions negotiated for the connection. + OnAddChannelResponse(string selected_protocol, string extensions); + + // Receive a non-control frame from the remote server. + // - |fin| indicates that this frame is the last in the current message. + // - |type| is the type of the message. On the first frame of a message, it + // must be set to either WebSocketMessageType.TEXT or + // WebSocketMessageType.BINARY. On subsequent frames, it must be set to + // WebSocketMessageType.CONTINUATION, and the type is the same as that of + // the first message. If |type| is WebSocketMessageType.TEXT, then the + // concatenation of the |data| from every frame in the message must be valid + // UTF-8. If |fin| is not set, |data| must be non-empty. + OnDataFrame(bool fin, WebSocketMessageType type, array<uint8> data); + + // Add |quota| tokens of send quota for the channel. |quota| must be a + // positive integer. Both the browser and the renderer set send quota for the + // other side, and check that quota has not been exceeded when receiving + // messages. Both sides start a new channel with a quota of 0, and must wait + // for a FlowControl message before calling SendFrame. The total available + // quota on one side must never exceed 0x7FFFFFFFFFFFFFFF tokens. + OnFlowControl(int64 quota); + + // Drop the channel. + // + // When sent by the renderer, this will cause a Close message will be sent and + // the TCP/IP connection will be closed. + // + // When sent by the browser, this indicates that a Close has been received, + // the connection was closed, or a network or protocol error occurred. + // + // - |code| is one of the reason codes specified in RFC6455. + // - |reason|, if non-empty, is a UTF-8 encoded string which may be useful + // for debugging but is not necessarily human-readable, as supplied by the + // server in the Close message. + // - If |was_clean| is false, then the WebSocket connection was not closed + // cleanly. + OnDropChannel(bool was_clean, uint16 code, string reason); + + // Notify the renderer that a closing handshake has been initiated by the + // server, so that it can set the Javascript readyState to CLOSING. + OnClosingHandshake(); +}; + +interface WebSocket { + // Open new WebSocket connection to |socket_url|. |requested_protocols| is a + // list of tokens identifying sub-protocols the renderer would like to use, + // as described in RFC6455 "Subprotocols Using the WebSocket Protocol". + AddChannelRequest(url.mojom.Url url, + array<string> requested_protocols, + url.mojom.Origin origin, + url.mojom.Url first_party_for_cookies, + string user_agent_override, + WebSocketClient client); + + // Send a non-control frame to the remote server. + // - |fin| indicates that this frame is the last in the current message. + // - |type| is the type of the message. On the first frame of a message, it + // must be set to either WebSocketMessageType.TEXT or + // WebSocketMessageType.BINARY. On subsequent frames, it must be set to + // WebSocketMessageType.CONTINUATION, and the type is the same as that of + // the first message. If |type| is WebSocketMessageType.TEXT, then the + // concatenation of the |data| from every frame in the message must be valid + // UTF-8. If |fin| is not set, |data| must be non-empty. + SendFrame(bool fin, WebSocketMessageType type, array<uint8> data); + + // Add |quota| tokens of send quota for the channel. |quota| must be a + // positive integer. Both the browser and the renderer set send quota for the + // other side, and check that quota has not been exceeded when receiving + // messages. Both sides start a new channel with a quota of 0, and must wait + // for a FlowControl message before calling SendFrame. The total available + // quota on one side must never exceed 0x7FFFFFFFFFFFFFFF tokens. + SendFlowControl(int64 quota); + + // Close the channel gracefully. + // + // When sent by the renderer, this will cause a Close message will be sent and + // the TCP/IP connection will be closed. + // + // - |code| is one of the reason codes specified in RFC6455. + // - |reason|, if non-empty, is a UTF-8 encoded string which may be useful for + // debugging but is not necessarily human-readable, as supplied by the + // server in the Close message. + StartClosingHandshake(uint16 code, string reason); +};
diff --git a/content/common/websocket_messages.h b/content/common/websocket_messages.h deleted file mode 100644 index ce250780b..0000000 --- a/content/common/websocket_messages.h +++ /dev/null
@@ -1,201 +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. - -// Multiply-included message file, hence no include guard. - -// This file defines the IPCs for the browser-side implementation of -// WebSockets. -// -// This IPC interface was originally desined based on the WebSocket -// multiplexing draft spec, -// http://tools.ietf.org/html/draft-ietf-hybi-websocket-multiplexing-09. So, -// some of them are given names correspond to the concepts defined in the spec. -// -// A WebSocketBridge object in the renderer and the corresponding WebSocketHost -// object in the browser are associated using an identifier named channel ID. -// The channel id is chosen by the renderer for a new channel. While the -// channel id is unique per-renderer, the browser may have multiple renderers -// using the same channel id. -// -// There're WebSocketDispatcherHost objects for each renderer. Each of -// WebSocketDispatcherHost holds a channel id to WebSocketHost map. -// -// Received messages are routed to the corresponding object by -// WebSocketDispatcher in the renderer and WebSocketDispatcherHost in the -// browser using the channel ID. -// -// The channel ID value is stored in the routing ID member which is available -// when we use the IPC_MESSAGE_ROUTED macro though it's unintended use. - -#include <stdint.h> - -#include <string> -#include <vector> - -#include "content/common/content_export.h" -#include "content/common/websocket.h" -#include "ipc/ipc_message_macros.h" -#include "url/gurl.h" -#include "url/origin.h" - -#undef IPC_MESSAGE_EXPORT -#define IPC_MESSAGE_EXPORT CONTENT_EXPORT -#define IPC_MESSAGE_START WebSocketMsgStart - -IPC_ENUM_TRAITS_MAX_VALUE(content::WebSocketMessageType, - content::WEB_SOCKET_MESSAGE_TYPE_LAST) - -IPC_STRUCT_BEGIN(WebSocketHostMsg_AddChannelRequest_Params) - IPC_STRUCT_MEMBER(GURL, socket_url) - IPC_STRUCT_MEMBER(std::vector<std::string>, requested_protocols) - IPC_STRUCT_MEMBER(url::Origin, origin) - IPC_STRUCT_MEMBER(GURL, first_party_for_cookies) - IPC_STRUCT_MEMBER(std::string, user_agent_override) - IPC_STRUCT_MEMBER(int, render_frame_id) -IPC_STRUCT_END() - -IPC_STRUCT_TRAITS_BEGIN(content::WebSocketHandshakeRequest) - IPC_STRUCT_TRAITS_MEMBER(url) - IPC_STRUCT_TRAITS_MEMBER(headers) - IPC_STRUCT_TRAITS_MEMBER(headers_text) - IPC_STRUCT_TRAITS_MEMBER(request_time) -IPC_STRUCT_TRAITS_END() - -IPC_STRUCT_TRAITS_BEGIN(content::WebSocketHandshakeResponse) - IPC_STRUCT_TRAITS_MEMBER(url) - IPC_STRUCT_TRAITS_MEMBER(status_code) - IPC_STRUCT_TRAITS_MEMBER(status_text) - IPC_STRUCT_TRAITS_MEMBER(headers) - IPC_STRUCT_TRAITS_MEMBER(headers_text) - IPC_STRUCT_TRAITS_MEMBER(response_time) -IPC_STRUCT_TRAITS_END() - -// WebSocket messages sent from the renderer to the browser. - -// Open new WebSocket connection to |socket_url|. |requested_protocols| is a -// list of tokens identifying sub-protocols the renderer would like to use, as -// described in RFC6455 "Subprotocols Using the WebSocket Protocol". -IPC_MESSAGE_ROUTED1(WebSocketHostMsg_AddChannelRequest, - WebSocketHostMsg_AddChannelRequest_Params) - -// Send a complete binary WebSocket message consisting of the Blob identified by -// |uuid|. The message will be split into frames as necessary. |expected_size| -// must match the browser's idea of the size of the Blob to prevent flow control -// from becoming desynchronised. If it does not match the connection will be -// terminated with a WebSocketMsg_NotifyFailure message. On success, the browser -// will have consumed |expected_size| bytes of flow control send quota and the -// renderer needs to subtract that from its running total of flow control send -// quota. See the design doc at -// https://docs.google.com/document/d/1CDiXB9pBumhFVVfmIn1CRI6v6byxyqWu2urEE9xp714/edit -// SendFrame or SendBlob IPCs must not be sent by the renderer until the -// BlobSendComplete message has been received from the browser. The renderer -// should retain a reference to the Blob until either a BlobSendComplete or -// NotifyFailure IPC is received. -IPC_MESSAGE_ROUTED2(WebSocketHostMsg_SendBlob, - std::string /* uuid */, - uint64_t /* expected_size */) - -// WebSocket messages sent from the browser to the renderer. - -// Respond to an AddChannelRequest. |selected_protocol| is the sub-protocol the -// server selected, or empty if no sub-protocol was selected. |extensions| is -// the list of extensions negotiated for the connection. -IPC_MESSAGE_ROUTED2(WebSocketMsg_AddChannelResponse, - std::string /* selected_protocol */, - std::string /* extensions */) - -// Notify the renderer that the browser has started an opening handshake. -// This message is for showing the request in the inspector and -// can be omitted if the inspector is not active. -IPC_MESSAGE_ROUTED1(WebSocketMsg_NotifyStartOpeningHandshake, - content::WebSocketHandshakeRequest /* request */) - -// Notify the renderer that the browser has finished an opening handshake. -// This message precedes AddChannelResponse. -// This message is for showing the response in the inspector and -// can be omitted if the inspector is not active. -IPC_MESSAGE_ROUTED1(WebSocketMsg_NotifyFinishOpeningHandshake, - content::WebSocketHandshakeResponse /* response */) - -// Notify the renderer that either: -// - the connection open request (WebSocketHostMsg_AddChannelRequest) failed. -// - the browser is required to fail the connection -// (see RFC6455 7.1.7 for details). -// -// When the renderer process receives this messages it does the following: -// 1. Fire an error event. -// 2. Show |message| to the inspector. -// 3. Close the channel immediately uncleanly, as if it received -// DropChannel(was_clean = false, code = 1006, reason = ""). -// |message| will be shown in the inspector and won't be passed to the script. -// TODO(yhirano): Find the way to pass |message| directly to the inspector -// process. -IPC_MESSAGE_ROUTED1(WebSocketMsg_NotifyFailure, - std::string /* message */) - -// Indicates tbat the current Blob has finished sending. The renderer can -// release its reference on the Blob, and may now use SendFrame or SendBlob to -// send more messages. -IPC_MESSAGE_ROUTED0(WebSocketMsg_BlobSendComplete) - -// WebSocket messages that can be sent in either direction. - -// Send a non-control frame to the channel. -// - If the sender is the renderer, it will be sent to the remote server. -// - If the sender is the browser, it comes from the remote server. -// -// - |fin| indicates that this frame is the last in the current message. -// - |type| is the type of the message. On the first frame of a message, it -// must be set to either WEB_SOCKET_MESSAGE_TYPE_TEXT or -// WEB_SOCKET_MESSAGE_TYPE_BINARY. On subsequent frames, it must be set to -// WEB_SOCKET_MESSAGE_TYPE_CONTINUATION, and the type is the same as that of -// the first message. If |type| is WEB_SOCKET_MESSAGE_TYPE_TEXT, then the -// concatenation of the |data| from every frame in the message must be valid -// UTF-8. If |fin| is not set, |data| must be non-empty. -IPC_MESSAGE_ROUTED3(WebSocketMsg_SendFrame, - bool /* fin */, - content::WebSocketMessageType /* type */, - std::vector<char> /* data */) - -// Add |quota| tokens of send quota for the channel. |quota| must be a positive -// integer. Both the browser and the renderer set send quota for the other -// side, and check that quota has not been exceeded when receiving messages. -// Both sides start a new channel with a quota of 0, and must wait for a -// FlowControl message before calling SendFrame. The total available quota on -// one side must never exceed 0x7FFFFFFFFFFFFFFF tokens. -// -// During "blob sending mode", ie. between the renderer sending a -// WebSocketHostMsg_SendBlob IPC and receiving a WebSocketMsg_BlobSendComplete -// IPC, quota is used up in the browser process to send the blob, but -// FlowControl IPCs for that quota are still sent to the renderer. The render -// process needs to take into account that quota equal to the size of the Blob -// has already been used when calculating how much send quota it has left after -// receiving BlobSendComplete. -IPC_MESSAGE_ROUTED1(WebSocketMsg_FlowControl, int64_t /* quota */) - -// Drop the channel. -// -// When sent by the renderer, this will cause a Close message will be sent and -// the TCP/IP connection will be closed. -// -// When sent by the browser, this indicates that a Close has been received, the -// connection was closed, or a network or protocol error occurred. -// -// - |code| is one of the reason codes specified in RFC6455. -// - |reason|, if non-empty, is a UTF-8 encoded string which may be useful for -// debugging but is not necessarily human-readable, as supplied by the server -// in the Close message. -// - If |was_clean| is false on a message from the browser, then the WebSocket -// connection was not closed cleanly. If |was_clean| is false on a message -// from the renderer, then the connection should be closed immediately without -// a closing handshake and the renderer cannot accept any new messages on this -// connection. -IPC_MESSAGE_ROUTED3(WebSocketMsg_DropChannel, - bool /* was_clean */, - unsigned short /* code */, - std::string /* reason */) - -// Notify the renderer that a closing handshake has been initiated by the -// server, so that it can set the Javascript readyState to CLOSING. -IPC_MESSAGE_ROUTED0(WebSocketMsg_NotifyClosing)
diff --git a/content/content_browser.gypi b/content/content_browser.gypi index aa88064..8ad04a7 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi
@@ -30,6 +30,7 @@ '../media/mojo/interfaces/mojo_bindings.gyp:image_capture_mojo_bindings', '../mojo/mojo_public.gyp:mojo_cpp_bindings', '../mojo/mojo_public.gyp:mojo_js_bindings', + '../mojo/mojo_public.gyp:mojo_message_pump_lib', '../net/net.gyp:http_server', '../net/net.gyp:net', '../net/net.gyp:net_extras', @@ -208,8 +209,6 @@ 'public/browser/invalidate_type.h', 'public/browser/javascript_dialog_manager.cc', 'public/browser/javascript_dialog_manager.h', - 'public/browser/load_from_memory_cache_details.cc', - 'public/browser/load_from_memory_cache_details.h', 'public/browser/load_notification_details.h', 'public/browser/local_storage_usage_info.h', 'public/browser/media_capture_devices.h', @@ -930,6 +929,8 @@ 'browser/loader/loader_io_thread_notifier.h', 'browser/loader/mime_type_resource_handler.cc', 'browser/loader/mime_type_resource_handler.h', + 'browser/loader/mojo_async_resource_handler.cc', + 'browser/loader/mojo_async_resource_handler.h', 'browser/loader/navigation_resource_handler.cc', 'browser/loader/navigation_resource_handler.h', 'browser/loader/navigation_resource_throttle.cc', @@ -978,6 +979,8 @@ 'browser/loader/temporary_file_stream.h', 'browser/loader/throttling_resource_handler.cc', 'browser/loader/throttling_resource_handler.h', + 'browser/loader/url_loader_factory_impl.cc', + 'browser/loader/url_loader_factory_impl.h', 'browser/loader/upload_data_stream_builder.cc', 'browser/loader/upload_data_stream_builder.h', 'browser/loader_delegate_impl.cc', @@ -994,6 +997,8 @@ 'browser/media/android/browser_media_session_manager.h', 'browser/media/android/browser_surface_view_manager.cc', 'browser/media/android/browser_surface_view_manager.h', + 'browser/media/android/media_player_renderer.h', + 'browser/media/android/media_player_renderer.cc', 'browser/media/android/media_resource_getter_impl.cc', 'browser/media/android/media_resource_getter_impl.h', 'browser/media/android/media_throttler.cc', @@ -1332,12 +1337,6 @@ 'browser/renderer_host/web_input_event_aurawin.cc', 'browser/renderer_host/webmenurunner_mac.h', 'browser/renderer_host/webmenurunner_mac.mm', - 'browser/renderer_host/websocket_blob_sender.cc', - 'browser/renderer_host/websocket_blob_sender.h', - 'browser/renderer_host/websocket_dispatcher_host.cc', - 'browser/renderer_host/websocket_dispatcher_host.h', - 'browser/renderer_host/websocket_host.cc', - 'browser/renderer_host/websocket_host.h', 'browser/resolve_proxy_msg_helper.cc', 'browser/resolve_proxy_msg_helper.h', 'browser/resource_context_impl.cc', @@ -1571,6 +1570,10 @@ 'browser/webui/web_ui_impl.cc', 'browser/webui/web_ui_impl.h', 'browser/webui/web_ui_message_handler.cc', + 'browser/websockets/websocket_impl.cc', + 'browser/websockets/websocket_impl.h', + 'browser/websockets/websocket_manager.cc', + 'browser/websockets/websocket_manager.h', 'browser/zygote_host/zygote_communication_linux.cc', 'browser/zygote_host/zygote_communication_linux.h', 'browser/zygote_host/zygote_handle_linux.cc',
diff --git a/content/content_child.gypi b/content/content_child.gypi index 742c8cb..755d5283 100644 --- a/content/content_child.gypi +++ b/content/content_child.gypi
@@ -194,6 +194,8 @@ 'child/sync_load_response.h', 'child/thread_safe_sender.cc', 'child/thread_safe_sender.h', + 'child/url_response_body_consumer.cc', + 'child/url_response_body_consumer.h', 'child/v8_value_converter_impl.cc', 'child/v8_value_converter_impl.h', 'child/web_data_consumer_handle_impl.cc', @@ -210,12 +212,6 @@ 'child/webfileutilities_impl.h', 'child/webmessageportchannel_impl.cc', 'child/webmessageportchannel_impl.h', - 'child/websocket_bridge.cc', - 'child/websocket_bridge.h', - 'child/websocket_dispatcher.cc', - 'child/websocket_dispatcher.h', - 'child/websocket_message_filter.cc', - 'child/websocket_message_filter.h', 'child/webthemeengine_impl_android.cc', 'child/webthemeengine_impl_android.h', 'child/webthemeengine_impl_default.cc',
diff --git a/content/content_common.gypi b/content/content_common.gypi index 61bc47a..966fdf4 100644 --- a/content/content_common.gypi +++ b/content/content_common.gypi
@@ -547,9 +547,6 @@ 'common/utility_messages.h', 'common/view_message_enums.h', 'common/view_messages.h', - 'common/websocket.cc', - 'common/websocket.h', - 'common/websocket_messages.h', 'common/worker_messages.h', 'common/zygote_commands_linux.h', ],
diff --git a/content/content_common_mojo_bindings.gyp b/content/content_common_mojo_bindings.gyp index ce0a991..f15d427 100644 --- a/content/content_common_mojo_bindings.gyp +++ b/content/content_common_mojo_bindings.gyp
@@ -18,6 +18,7 @@ 'common/render_frame_message_filter.mojom', 'common/service_worker/embedded_worker_setup.mojom', 'common/storage_partition_service.mojom', + 'common/websocket.mojom', '../third_party/WebKit/public/platform/modules/bluetooth/web_bluetooth.mojom', ], 'mojom_typemaps': [
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 7b0a7d7..4fb1c33 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi
@@ -273,6 +273,10 @@ 'renderer/media/aec_dump_message_filter.h', 'renderer/media/android/media_info_loader.cc', 'renderer/media/android/media_info_loader.h', + 'renderer/media/android/media_player_renderer_client.cc', + 'renderer/media/android/media_player_renderer_client.h', + 'renderer/media/android/media_player_renderer_client_factory.cc', + 'renderer/media/android/media_player_renderer_client_factory.h', 'renderer/media/android/media_source_delegate.cc', 'renderer/media/android/media_source_delegate.h', 'renderer/media/android/renderer_demuxer_android.cc', @@ -490,6 +494,8 @@ 'renderer/webscrollbarbehavior_impl_mac.mm', 'renderer/websharedworker_proxy.cc', 'renderer/websharedworker_proxy.h', + 'renderer/websockethandle_impl.cc', + 'renderer/websockethandle_impl.h', ], # Put WebRTC-related sources in the plugin+WebRTC section below. 'private_renderer_plugin_sources': [
diff --git a/content/content_resources.grd b/content/content_resources.grd index 0dab18f..7810a24d 100644 --- a/content/content_resources.grd +++ b/content/content_resources.grd
@@ -32,7 +32,7 @@ <include name="IDR_MOJO_CONTENT_GPU_MANIFEST" file="${root_out_dir}/content_gpu_manifest.json" use_base_dir="false" type="BINDATA" /> <include name="IDR_MOJO_CONTENT_RENDERER_MANIFEST" file="${root_out_dir}/content_renderer_manifest.json" use_base_dir="false" type="BINDATA" /> <include name="IDR_MOJO_CONTENT_UTILITY_MANIFEST" file="${root_out_dir}/content_utility_manifest.json" use_base_dir="false" type="BINDATA" /> - <include name="IDR_MOJO_PROFILE_MANIFEST" file="../services/user/manifest.json" type="BINDATA" /> + <include name="IDR_MOJO_FILE_MANIFEST" file="../services/file/manifest.json" type="BINDATA" /> <include name="IDR_NETWORK_ERROR_LISTING_HTML" file="browser/resources/net/network_errors_listing.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" /> <include name="IDR_NETWORK_ERROR_LISTING_JS" file="browser/resources/net/network_errors_listing.js" flattenhtml="true" type="BINDATA" /> <include name="IDR_NETWORK_ERROR_LISTING_CSS" file="browser/resources/net/network_errors_listing.css" flattenhtml="true" type="BINDATA" />
diff --git a/content/content_tests.gypi b/content/content_tests.gypi index 13c9e9f..56099bc 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi
@@ -308,6 +308,7 @@ 'browser/webrtc/webrtc_audio_debug_recordings_browsertest.cc', 'browser/webrtc/webrtc_browsertest.cc', 'browser/webrtc/webrtc_capture_from_element_browsertest.cc', + 'browser/webrtc/webrtc_constraints_browsertest.cc', 'browser/webrtc/webrtc_content_browsertest_base.cc', 'browser/webrtc/webrtc_content_browsertest_base.h', 'browser/webrtc/webrtc_data_browsertest.cc', @@ -505,13 +506,17 @@ 'browser/loader/async_revalidation_driver_unittest.cc', 'browser/loader/async_revalidation_manager_unittest.cc', 'browser/loader/mime_type_resource_handler_unittest.cc', + 'browser/loader/mojo_async_resource_handler_unittest.cc', 'browser/loader/navigation_url_loader_unittest.cc', 'browser/loader/resource_buffer_unittest.cc', 'browser/loader/resource_dispatcher_host_unittest.cc', 'browser/loader/resource_loader_unittest.cc', 'browser/loader/resource_scheduler_unittest.cc', 'browser/loader/temporary_file_stream_unittest.cc', + 'browser/loader/test_url_loader_client.cc', + 'browser/loader/test_url_loader_client.h', 'browser/loader/upload_data_stream_builder_unittest.cc', + 'browser/loader/url_loader_factory_impl_unittest.cc', 'browser/mach_broker_mac_unittest.cc', 'browser/media/audible_metrics_unittest.cc', 'browser/media/audio_stream_monitor_unittest.cc', @@ -593,8 +598,6 @@ 'browser/renderer_host/render_widget_host_view_mac_unittest.mm', 'browser/renderer_host/text_input_client_mac_unittest.mm', 'browser/renderer_host/web_input_event_aura_unittest.cc', - 'browser/renderer_host/websocket_blob_sender_unittest.cc', - 'browser/renderer_host/websocket_dispatcher_host_unittest.cc', 'browser/resolve_proxy_msg_helper_unittest.cc', 'browser/service_worker/embedded_worker_instance_unittest.cc', 'browser/service_worker/embedded_worker_test_helper.cc', @@ -639,6 +642,7 @@ 'browser/web_contents/web_contents_view_mac_unittest.mm', 'browser/web_contents/web_drag_dest_mac_unittest.mm', 'browser/web_contents/web_drag_source_mac_unittest.mm', + 'browser/websockets/websocket_manager_unittest.cc', 'browser/webui/url_data_manager_backend_unittest.cc', 'browser/webui/web_ui_data_source_unittest.cc', 'browser/webui/web_ui_message_handler_unittest.cc', @@ -665,6 +669,7 @@ 'child/v8_value_converter_impl_unittest.cc', 'child/web_data_consumer_handle_impl_unittest.cc', 'child/web_url_loader_impl_unittest.cc', + 'child/url_response_body_consumer_unittest.cc', 'child/worker_thread_registry_unittest.cc', 'common/android/address_parser_unittest.cc', 'common/android/gin_java_bridge_value_unittest.cc',
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index ac9356e..c634ed9c 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -333,7 +333,6 @@ "javatests/src/org/chromium/content/browser/ContentDetectionTestBase.java", "javatests/src/org/chromium/content/browser/ContentViewCoreFocusTest.java", "javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java", - "javatests/src/org/chromium/content/browser/ContentViewCoreViewAndroidDelegateTest.java", "javatests/src/org/chromium/content/browser/ContentViewLocationTest.java", "javatests/src/org/chromium/content/browser/ContentViewPopupZoomerTest.java", "javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java",
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java index 3c6b6785..ec613ea3 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java
@@ -544,26 +544,6 @@ if (mNativeContentViewCore != 0) nativeWasResized(mNativeContentViewCore); } - /** - * Returns a delegate that can be used to add and remove views from the current - * container view. Clients can safely hold to instances of this class as it handles the - * replacement of container views transparently. - * - * NOTE: Use with care, as not all ContentViewCore users setup their container view in the same - * way. In particular, the Android WebView has limitations on what implementation details can - * be provided via a child view, as they are visible in the API and could introduce - * compatibility breaks with existing applications. If in doubt, contact the - * android_webview/OWNERS - * - * @return A ViewAndroidDelegate that can be used to add and remove views. - */ - @VisibleForTesting - public ViewAndroidDelegate getViewAndroidDelegate() { - // TODO(jinsukkim): Remove this method since it is only used by tests that don't - // necessarily require the delegate. - return mViewAndroidDelegate; - } - @VisibleForTesting public void setImeAdapterForTest(ImeAdapter imeAdapter) { mImeAdapter = imeAdapter;
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionFactory.java b/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionFactory.java index ebd95756..0b94f22 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionFactory.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionFactory.java
@@ -87,6 +87,7 @@ // and we still want to call them for consistency. The setback here is that the only // way to distinguish calls from InputMethodManager and from ProxyView is by looking at // the call stack. + // TODO - avoid using reflection here. See crbug.com/636474 for (StackTraceElement ste : Thread.currentThread().getStackTrace()) { String className = ste.getClassName(); if (className != null @@ -239,4 +240,4 @@ if (mCheckInvalidator != null) mCheckInvalidator.invalidate(); if (mProxyView != null) mProxyView.onOriginalViewDetachedFromWindow(); } -} \ No newline at end of file +}
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java b/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java index 7ccb6961..9cf5e29 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java
@@ -13,6 +13,7 @@ import org.chromium.base.Log; import org.chromium.base.ThreadUtils; +import org.chromium.base.annotations.UsedByReflection; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicBoolean; @@ -21,6 +22,7 @@ /** * This is a fake View that is only exposed to InputMethodManager. */ +@UsedByReflection("ThreadedInputConnectionFactory.java") public class ThreadedInputConnectionProxyView extends View { private static final String TAG = "cr_Ime"; private static final boolean DEBUG_LOGS = false; @@ -132,4 +134,4 @@ if (DEBUG_LOGS) Log.w(TAG, "onWindowFocusChanged:" + hasWindowFocus); super.onWindowFocusChanged(hasWindowFocus); } -} \ No newline at end of file +}
diff --git a/content/public/android/java/src/org/chromium/content/common/CleanupReference.java b/content/public/android/java/src/org/chromium/content/common/CleanupReference.java index 95e61cea..6c6fcd71 100644 --- a/content/public/android/java/src/org/chromium/content/common/CleanupReference.java +++ b/content/public/android/java/src/org/chromium/content/common/CleanupReference.java
@@ -12,8 +12,8 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.TraceEvent; +import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; import java.util.HashSet; import java.util.Set; @@ -25,12 +25,13 @@ * cleaned up in response to java side GC of API objects. (Private/internal * interfaces should always favor explicit resource releases / destroy() * protocol for this rather than depend on GC to trigger native cleanup). - * NOTE this uses WeakReference rather than PhantomReference, to avoid delaying the - * cleanup processing until after finalizers (if any) have run. In general usage of - * this class indicates the client does NOT use finalizers anyway (Good), so this should - * not be a visible difference in practice. + * + * NOTE Using PhantonReference instead of WeakReference is required for correctness. + * WeakReferences are enqueued before finalizers are called, and finalizers can + * resurrect the referent object. PhantomReference does delay clean up more compared + * to WeakReference. */ -public class CleanupReference extends WeakReference<Object> { +public class CleanupReference extends PhantomReference<Object> { private static final String TAG = "cr.CleanupReference"; private static final boolean DEBUG = false; // Always check in as false!
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/AddressDetectionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/AddressDetectionTest.java index cdb2c539..efc8f18 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/AddressDetectionTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/AddressDetectionTest.java
@@ -26,7 +26,6 @@ public void testMultipleAddressesInText() throws Throwable { startActivityWithTestUrl( "content/test/data/android/content_detection/geo_address_multiple.html"); - assertWaitForPageScaleFactorMatch(1.0f); assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test1"), "1600 Amphitheatre Parkway Mountain View, CA 94043")); @@ -40,7 +39,6 @@ public void testSplitAddresses() throws Throwable { startActivityWithTestUrl( "content/test/data/android/content_detection/geo_address_split.html"); - assertWaitForPageScaleFactorMatch(1.0f); assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test1"), "9606 North MoPac Expressway Suite 400 Austin, TX 78759")); @@ -60,7 +58,6 @@ public void testAddressLimits() throws Throwable { startActivityWithTestUrl( "content/test/data/android/content_detection/geo_address_limits.html"); - assertWaitForPageScaleFactorMatch(1.0f); assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test1"), "2590 Pearl Street Suite 100 Boulder, CO 80302")); @@ -80,7 +77,6 @@ public void testRealAddresses() throws Throwable { startActivityWithTestUrl( "content/test/data/android/content_detection/geo_address_real.html"); - assertWaitForPageScaleFactorMatch(1.0f); assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test1"), "57th Street and Lake Shore Drive Chicago, IL 60637")); @@ -100,7 +96,6 @@ public void testSpecialChars() throws Throwable { startActivityWithTestUrl( "content/test/data/android/content_detection/geo_address_special_chars.html"); - assertWaitForPageScaleFactorMatch(1.0f); assertTrue(isExpectedGeoIntent(scrollAndTapExpectingIntent("test1"), "100 34th Avenue , San Francisco, CA 94121"));
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ClickListenerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ClickListenerTest.java index 2c57e814..6d9e8079 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ClickListenerTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ClickListenerTest.java
@@ -18,7 +18,6 @@ public void testClickContentOnLink() throws Throwable { startActivityWithTestUrl( "content/test/data/android/content_detection/click_listeners.html"); - assertWaitForPageScaleFactorMatch(1.0f); // Clicks on addresses in links should change the url. scrollAndTapNavigatingOut("linktest"); @@ -30,7 +29,6 @@ public void testClickContentOnJSListener1() throws Throwable { startActivityWithTestUrl( "content/test/data/android/content_detection/click_listeners.html"); - assertWaitForPageScaleFactorMatch(1.0f); // Clicks on addresses in elements listening to click events should be // processed normally without address detection. @@ -43,7 +41,6 @@ public void testClickContentOnJSListener2() throws Throwable { startActivityWithTestUrl( "content/test/data/android/content_detection/click_listeners.html"); - assertWaitForPageScaleFactorMatch(1.0f); // Same as previous test, but using addEventListener instead of onclick. scrollAndTapNavigatingOut("clicktest2");
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java index 5499a4f..715c30a 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreSelectionTest.java
@@ -50,7 +50,6 @@ waitForActiveShellToBeDoneLoading(); mContentViewCore = getContentViewCore(); - assertWaitForPageScaleFactorMatch(1.1f); waitForSelectActionBarVisible(false); waitForPastePopupStatus(false); }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreViewAndroidDelegateTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreViewAndroidDelegateTest.java deleted file mode 100644 index 613fb4b5..0000000 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewCoreViewAndroidDelegateTest.java +++ /dev/null
@@ -1,103 +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.content.browser; - -import android.test.suitebuilder.annotation.SmallTest; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewGroup.LayoutParams; -import android.widget.FrameLayout; - -import org.chromium.content_shell_apk.ContentShellTestBase; -import org.chromium.ui.base.ViewAndroidDelegate; - -/** - * This suite verifies that when {@link ContentViewCore} replaces container - * views then: - * 1. anchor views are transferred between container views - * 2. and the reference returned by {@link ContentViewCore#getViewAndroidDelegate()} is - * still valid and it will add/remove anchor views from the new container view. - */ -public class ContentViewCoreViewAndroidDelegateTest extends ContentShellTestBase { - - private ViewAndroidDelegate mViewAndroidDelegate; - private ContentViewCore mContentViewCore; - private ViewGroup mContainerView; - - @Override - public void setUp() throws Exception { - super.setUp(); - mContentViewCore = new ContentViewCore(getActivity()); - mContainerView = new FrameLayout(getActivity()); - - mContentViewCore.initPopupZoomer(getActivity()); - // This reference never changes during the duration of the tests, - // but can still be used to add/remove anchor views from the - // updated container view. - mViewAndroidDelegate = ViewAndroidDelegate.createBasicDelegate(mContainerView); - mContentViewCore.setContainerView(mContainerView); - } - - @SmallTest - public void testAddAndRemoveAnchorViews() { - assertEquals(0, mContainerView.getChildCount()); - - // Add 2 anchor views - View anchorView1 = addAnchorViewTest(mContainerView, 1); - View anchorView2 = addAnchorViewTest(mContainerView, 2); - - // Remove anchorView1 - removeAnchorViewTest(mContainerView, anchorView1, 1); - assertSame(anchorView2, mContainerView.getChildAt(0)); - - // Try to remove anchorView1 again; no-op. - removeAnchorViewTest(mContainerView, anchorView1, 1); - assertSame(anchorView2, mContainerView.getChildAt(0)); - - // Remove anchorView2 - removeAnchorViewTest(mContainerView, anchorView2, 0); - } - - @SmallTest - public void testAddAndMoveAnchorView() { - // Add anchorView and set layout params - View anchorView = addAnchorViewTest(mContainerView, 1); - LayoutParams originalLayoutParams = setLayoutParams(anchorView, 0, 0); - - // Move it - LayoutParams updatedLayoutParams = setLayoutParams(anchorView, 1, 2); - assertEquals(1, mContainerView.getChildCount()); - assertFalse(areEqual(originalLayoutParams, updatedLayoutParams)); - - // Move it back to the original position - updatedLayoutParams = setLayoutParams(anchorView, 0, 0); - assertEquals(1, mContainerView.getChildCount()); - assertTrue(areEqual(originalLayoutParams, updatedLayoutParams)); - } - - private View addAnchorViewTest(ViewGroup containerView, int expectedCount) { - View anchorView = mViewAndroidDelegate.acquireView(); - assertEquals(expectedCount, containerView.getChildCount()); - assertSame(anchorView, containerView.getChildAt(expectedCount - 1)); - return anchorView; - } - - private void removeAnchorViewTest( - ViewGroup containerView, View anchorView1, int expectedCount) { - mViewAndroidDelegate.removeView(anchorView1); - assertEquals(expectedCount, containerView.getChildCount()); - } - - private LayoutParams setLayoutParams(View anchorView, - int coordinatesValue, int dimensionsValue) { - mViewAndroidDelegate.setViewPosition(anchorView, coordinatesValue, coordinatesValue, - dimensionsValue, dimensionsValue, 1f, 10, 10); - return anchorView.getLayoutParams(); - } - - private boolean areEqual(LayoutParams params1, LayoutParams params2) { - return params1.height == params2.height && params1.width == params2.width; - } -}
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java index d20e507..d5fbd4d 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ContentViewScrollingTest.java
@@ -155,7 +155,6 @@ launchContentShellWithUrl(LARGE_PAGE); waitForActiveShellToBeDoneLoading(); - assertWaitForPageScaleFactorMatch(2.0f); assertEquals(0, getContentViewCore().getNativeScrollXForTest()); assertEquals(0, getContentViewCore().getNativeScrollYForTest());
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/EmailAddressDetectionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/EmailAddressDetectionTest.java index 95aa5d9..11d12d6 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/EmailAddressDetectionTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/EmailAddressDetectionTest.java
@@ -25,7 +25,6 @@ @Feature({"ContentDetection", "TabContents"}) public void testValidEmailAddresses() throws Throwable { startActivityWithTestUrl("content/test/data/android/content_detection/email.html"); - assertWaitForPageScaleFactorMatch(1.0f); // valid_1: i.want.a.pony@chromium.org. String intentUrl = scrollAndTapExpectingIntent("valid_1");
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/MediaSessionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/MediaSessionTest.java index 68fcf70..160debb1 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/MediaSessionTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/MediaSessionTest.java
@@ -313,8 +313,7 @@ @SmallTest @Feature({"MediaSession"}) - // Flaky: http:crbug.com/625584. - @DisabledTest + @DisabledTest(message = "crbug.com/625584") public void testMediaDuck() throws Exception { assertEquals(AudioManager.AUDIOFOCUS_LOSS, mAudioFocusChangeListener.getAudioFocusState()); mAudioFocusChangeListener.requestAudioFocus(AudioManager.AUDIOFOCUS_GAIN);
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/PhoneNumberDetectionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/PhoneNumberDetectionTest.java index 899dda3c..af150264 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/PhoneNumberDetectionTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/PhoneNumberDetectionTest.java
@@ -30,7 +30,6 @@ public void testInternationalNumberIntents() throws Throwable { startActivityWithTestUrl( "content/test/data/android/content_detection/phone_international.html"); - assertWaitForPageScaleFactorMatch(1.0f); // US: +1 650-253-0000. String intentUrl = scrollAndTapExpectingIntent("US"); @@ -147,7 +146,6 @@ public void testLocalUSNumbers() throws Throwable { startActivityWithTestUrl( "content/test/data/android/content_detection/phone_local.html"); - assertWaitForPageScaleFactorMatch(1.0f); // US_1: 1-888-433-5788. String intentUrl = scrollAndTapExpectingIntent("US_1"); @@ -172,7 +170,6 @@ public void testLocalUKNumbers() throws Throwable { startActivityWithTestUrl( "content/test/data/android/content_detection/phone_local.html"); - assertWaitForPageScaleFactorMatch(1.0f); // GB_1: (0) 20 7323 8299. String intentUrl = scrollAndTapExpectingIntent("GB_1"); @@ -197,7 +194,6 @@ public void testLocalFRNumbers() throws Throwable { startActivityWithTestUrl( "content/test/data/android/content_detection/phone_local.html"); - assertWaitForPageScaleFactorMatch(1.0f); // FR_1: 01 40 20 50 50. String intentUrl = scrollAndTapExpectingIntent("FR_1");
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/WebContentsObserverAndroidTest.java b/content/public/android/javatests/src/org/chromium/content/browser/WebContentsObserverAndroidTest.java index 0ab51f1..c53d217 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/WebContentsObserverAndroidTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/WebContentsObserverAndroidTest.java
@@ -51,9 +51,8 @@ /* @SmallTest @Feature({"Navigation"}) - http://crbug.com/411931 */ - @DisabledTest + @DisabledTest(message = "crbug.com/411931") public void testDidFirstVisuallyNonEmptyPaint() throws Throwable { TestWebContentsObserver observer = ThreadUtils.runOnUiThreadBlocking( new Callable<TestWebContentsObserver>() {
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/SelectPopupTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/SelectPopupTest.java index d0788356..39f630a9 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/input/SelectPopupTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/input/SelectPopupTest.java
@@ -67,8 +67,6 @@ super.setUp(); launchContentShellWithUrl(SELECT_URL); waitForActiveShellToBeDoneLoading(); - // TODO(aurimas) remove this wait once crbug.com/179511 is fixed. - assertWaitForPageScaleFactorMatch(1); } /**
diff --git a/content/public/app/BUILD.gn b/content/public/app/BUILD.gn index 470819e..4a9b82d 100644 --- a/content/public/app/BUILD.gn +++ b/content/public/app/BUILD.gn
@@ -171,12 +171,12 @@ name = "content_browser" source = "mojo/content_browser_manifest.json" packaged_services = [ + "file", "media", - "user", ] deps = [ "//media/mojo/services:media_manifest", - "//services/user:manifest", + "//services/file:manifest", ] }
diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json index e4d7a02..8e9fd5f 100644 --- a/content/public/app/mojo/content_browser_manifest.json +++ b/content/public/app/mojo/content_browser_manifest.json
@@ -24,7 +24,7 @@ "shell:user_id" ] }, - "mojo:user": { + "mojo:file": { "interfaces": [ "leveldb::mojom::LevelDBService", "user_service::UserService"
diff --git a/content/public/browser/load_from_memory_cache_details.cc b/content/public/browser/load_from_memory_cache_details.cc deleted file mode 100644 index b12c59f..0000000 --- a/content/public/browser/load_from_memory_cache_details.cc +++ /dev/null
@@ -1,27 +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 "content/public/browser/load_from_memory_cache_details.h" - -namespace content { - -LoadFromMemoryCacheDetails::LoadFromMemoryCacheDetails( - const GURL& url, - int cert_id, - net::CertStatus cert_status, - const std::string& http_method, - const std::string& mime_type, - ResourceType resource_type) - : url(url), - cert_id(cert_id), - cert_status(cert_status), - http_method(http_method), - mime_type(mime_type), - resource_type(resource_type) { -} - -LoadFromMemoryCacheDetails::~LoadFromMemoryCacheDetails() { -} - -} // namespace content
diff --git a/content/public/browser/load_from_memory_cache_details.h b/content/public/browser/load_from_memory_cache_details.h deleted file mode 100644 index 69805c2..0000000 --- a/content/public/browser/load_from_memory_cache_details.h +++ /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. - -#ifndef CONTENT_PUBLIC_BROWSER_LOAD_FROM_MEMORY_CACHE_DETAILS_H_ -#define CONTENT_PUBLIC_BROWSER_LOAD_FROM_MEMORY_CACHE_DETAILS_H_ - -#include <string> -#include "content/public/common/resource_type.h" -#include "net/cert/cert_status_flags.h" -#include "url/gurl.h" - -namespace content { - -struct LoadFromMemoryCacheDetails { - LoadFromMemoryCacheDetails(const GURL& url, - int cert_id, - net::CertStatus cert_status, - const std::string& http_method, - const std::string& mime_type, - ResourceType resource_type); - ~LoadFromMemoryCacheDetails(); - - GURL url; - int cert_id; - net::CertStatus cert_status; - std::string http_method; - std::string mime_type; - ResourceType resource_type; -}; - -} // namespace content - -#endif // CONTENT_PUBLIC_BROWSER_LOAD_FROM_MEMORY_CACHE_DETAILS_H_
diff --git a/content/public/browser/resource_dispatcher_host_delegate.cc b/content/public/browser/resource_dispatcher_host_delegate.cc index 0ce62b3..1029152 100644 --- a/content/public/browser/resource_dispatcher_host_delegate.cc +++ b/content/public/browser/resource_dispatcher_host_delegate.cc
@@ -107,6 +107,11 @@ return std::unique_ptr<net::ClientCertStore>(); } +void ResourceDispatcherHostDelegate::OnAbortedFrameLoad( + const GURL& url, + base::TimeDelta request_loading_time) { +} + ResourceDispatcherHostDelegate::~ResourceDispatcherHostDelegate() { }
diff --git a/content/public/browser/resource_dispatcher_host_delegate.h b/content/public/browser/resource_dispatcher_host_delegate.h index f32fe44..219b003 100644 --- a/content/public/browser/resource_dispatcher_host_delegate.h +++ b/content/public/browser/resource_dispatcher_host_delegate.h
@@ -9,6 +9,7 @@ #include <string> #include "base/files/file_path.h" +#include "base/time/time.h" #include "content/common/content_export.h" #include "content/public/browser/resource_request_info.h" #include "content/public/common/resource_type.h" @@ -135,6 +136,12 @@ virtual std::unique_ptr<net::ClientCertStore> CreateClientCertStore( ResourceContext* resource_context); + // Notification that a main frame load was aborted. The |request_loading_time| + // parameter contains the time between the load request start and abort. + // Called on the IO thread. + virtual void OnAbortedFrameLoad(const GURL& url, + base::TimeDelta request_loading_time); + protected: virtual ~ResourceDispatcherHostDelegate(); };
diff --git a/content/public/browser/ssl_host_state_delegate.h b/content/public/browser/ssl_host_state_delegate.h index b06b408..8c94820 100644 --- a/content/public/browser/ssl_host_state_delegate.h +++ b/content/public/browser/ssl_host_state_delegate.h
@@ -31,6 +31,20 @@ ALLOWED }; + // The types of nonsecure subresources that this class keeps track of. + // + // TODO(estark): Currently, MIXED_CONTENT is used for all insecure + // content, as SSLManager/SSLPolicy do not separate signals for mixed + // content from signals for subresources with cert errors. Fixing this + // is in progress as part of https://crbug.com/634171. + enum InsecureContentType { + // A MIXED subresource was loaded over HTTP on an HTTPS page. + MIXED_CONTENT, + // A CERT_ERRORS subresource was loaded over HTTPS with certificate + // errors on an HTTPS page. + CERT_ERRORS_CONTENT, + }; + // Records that |cert| is permitted to be used for |host| in the future, for // a specified |error| type. virtual void AllowCert(const std::string&, @@ -48,12 +62,17 @@ net::CertStatus error, bool* expired_previous_decision) = 0; - // Records that a host has run insecure content. - virtual void HostRanInsecureContent(const std::string& host, int pid) = 0; + // Records that a host has run insecure content of the given |content_type|. + virtual void HostRanInsecureContent(const std::string& host, + int pid, + InsecureContentType content_type) = 0; - // Returns whether the specified host ran insecure content. - virtual bool DidHostRunInsecureContent(const std::string& host, - int pid) const = 0; + // Returns whether the specified host ran insecure content of the given + // |content_type|. + virtual bool DidHostRunInsecureContent( + const std::string& host, + int pid, + InsecureContentType content_type) const = 0; // Revokes all SSL certificate error allow exceptions made by the user for // |host|.
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h index c34b118..efa8ae59 100644 --- a/content/public/browser/web_contents.h +++ b/content/public/browser/web_contents.h
@@ -364,9 +364,6 @@ // Returns the character encoding of the page. virtual const std::string& GetEncoding() const = 0; - // True if this is a secure page which displayed insecure content. - virtual bool DisplayedInsecureContent() const = 0; - // Internal state ------------------------------------------------------------ // Indicates whether the WebContents is being captured (e.g., for screenshots
diff --git a/content/public/browser/web_contents_observer.h b/content/public/browser/web_contents_observer.h index d01c9a30..b72cef6 100644 --- a/content/public/browser/web_contents_observer.h +++ b/content/public/browser/web_contents_observer.h
@@ -14,6 +14,7 @@ #include "content/public/browser/navigation_controller.h" #include "content/public/common/frame_navigate_params.h" #include "content/public/common/media_metadata.h" +#include "content/public/common/resource_type.h" #include "content/public/common/security_style.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_sender.h" @@ -35,7 +36,6 @@ struct FaviconURL; struct FrameNavigateParams; struct LoadCommittedDetails; -struct LoadFromMemoryCacheDetails; struct Referrer; struct ResourceRedirectDetails; struct ResourceRequestDetails; @@ -300,7 +300,9 @@ // This method is invoked when content was loaded from an in-memory cache. virtual void DidLoadResourceFromMemoryCache( - const LoadFromMemoryCacheDetails& details) {} + const GURL& url, + const std::string& mime_type, + ResourceType resource_type) {} // This method is invoked when a response has been received for a resource // request.
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn index 2df12fd..71186ee 100644 --- a/content/public/common/BUILD.gn +++ b/content/public/common/BUILD.gn
@@ -110,6 +110,9 @@ "//url/ipc:url_ipc", ] deps = [ + # This looks needless as we have //content/common in public_deps, but it's + # needed because of allow_circular_includes_from. + "//content/common:mojo_bindings_cpp_sources", "//ipc", "//media", "//mojo/common", @@ -130,7 +133,10 @@ ] # //content/common needs to include public headers. - allow_circular_includes_from = [ "//content/common" ] + allow_circular_includes_from = [ + "//content/common", + "//content/common:mojo_bindings_cpp_sources", + ] if (!enable_plugins) { sources -= [
diff --git a/content/public/common/common_param_traits_macros.h b/content/public/common/common_param_traits_macros.h index a1a574f..52cd090 100644 --- a/content/public/common/common_param_traits_macros.h +++ b/content/public/common/common_param_traits_macros.h
@@ -200,7 +200,7 @@ IPC_STRUCT_TRAITS_MEMBER(available_hover_types) IPC_STRUCT_TRAITS_MEMBER(primary_hover_type) IPC_STRUCT_TRAITS_MEMBER(sync_xhr_in_documents_enabled) - IPC_STRUCT_TRAITS_MEMBER(image_color_profiles_enabled) + IPC_STRUCT_TRAITS_MEMBER(color_correct_rendering_enabled) IPC_STRUCT_TRAITS_MEMBER(should_respect_image_orientation) IPC_STRUCT_TRAITS_MEMBER(number_of_cpu_cores) IPC_STRUCT_TRAITS_MEMBER(editing_behavior)
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index d94380d..38684b7 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -373,6 +373,9 @@ const char kEnableCanvas2dDynamicRenderingModeSwitching[] = "enable-canvas-2d-dynamic-rendering-mode-switching"; +// Enable color space aware rasterization and compositing. +const char kEnableColorCorrectRendering[] = "enable-color-correct-rendering"; + // Enable experimental canvas features, e.g. canvas 2D context attributes const char kEnableExperimentalCanvasFeatures[] = "enable-experimental-canvas-features"; @@ -415,9 +418,6 @@ // tiles may be displayed during fast scrolls especially on slower devices. const char kEnableLowResTiling[] = "enable-low-res-tiling"; -// Dynamically apply color profiles to web content images. -const char kEnableImageColorProfiles[] = "enable-image-color-profiles"; - // Force logging to be enabled. Logging is disabled by default in release // builds. const char kEnableLogging[] = "enable-logging"; @@ -630,6 +630,9 @@ // Enables experimental Harmony (ECMAScript 6) features. const char kJavaScriptHarmony[] = "javascript-harmony"; +// Enables experimental Asm.js to WebAssembly. +const char kEnableAsmWasm[] = "enable-asm-wasm"; + // Enables experimental WebAssembly. const char kEnableWasm[] = "enable-wasm";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index c94d56a..f5b7b16 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -113,10 +113,12 @@ CONTENT_EXPORT extern const char kEnableBrowserSideNavigation[]; CONTENT_EXPORT extern const char kEnableDisplayList2dCanvas[]; CONTENT_EXPORT extern const char kEnableCanvas2dDynamicRenderingModeSwitching[]; +CONTENT_EXPORT extern const char kEnableColorCorrectRendering[]; CONTENT_EXPORT extern const char kEnableDistanceFieldText[]; CONTENT_EXPORT extern const char kEnableExperimentalCanvasFeatures[]; CONTENT_EXPORT extern const char kEnableExperimentalWebPlatformFeatures[]; CONTENT_EXPORT extern const char kEnableFeatures[]; +CONTENT_EXPORT extern const char kEnableAsmWasm[]; CONTENT_EXPORT extern const char kEnableWasm[]; CONTENT_EXPORT extern const char kEnableWebBluetooth[]; CONTENT_EXPORT extern const char kEnableWebFontsInterventionV2[]; @@ -132,7 +134,6 @@ CONTENT_EXPORT extern const char kEnableGpuRasterization[]; CONTENT_EXPORT extern const char kGpuRasterizationMSAASampleCount[]; CONTENT_EXPORT extern const char kEnableLowResTiling[]; -CONTENT_EXPORT extern const char kEnableImageColorProfiles[]; CONTENT_EXPORT extern const char kEnableLCDText[]; CONTENT_EXPORT extern const char kEnableLogging[]; extern const char kEnableMemoryBenchmarking[];
diff --git a/content/public/common/renderer_preferences.cc b/content/public/common/renderer_preferences.cc index 797dd9b..e635641 100644 --- a/content/public/common/renderer_preferences.cc +++ b/content/public/common/renderer_preferences.cc
@@ -31,6 +31,8 @@ use_custom_colors(true), enable_referrers(true), enable_do_not_track(false), + webrtc_udp_min_port(0), + webrtc_udp_max_port(0), report_frame_name_changes(false), tap_multiple_targets_strategy(TAP_MULTIPLE_TARGETS_STRATEGY_POPUP), disable_client_blocked_error_page(false),
diff --git a/content/public/common/renderer_preferences.h b/content/public/common/renderer_preferences.h index 73d215a..6e6f1b4 100644 --- a/content/public/common/renderer_preferences.h +++ b/content/public/common/renderer_preferences.h
@@ -102,6 +102,11 @@ // in webrtc_ip_handling_policy.h. std::string webrtc_ip_handling_policy; + // This is the range of UDP ports allowed to be used by WebRTC. A value of + // zero in both fields means all ports are allowed. + uint16_t webrtc_udp_min_port; + uint16_t webrtc_udp_max_port; + // The user agent given to WebKit when it requests one and the user agent is // being overridden for the current navigation. std::string user_agent_override;
diff --git a/content/public/common/ssl_status.h b/content/public/common/ssl_status.h index e8e6ab7..bd50064 100644 --- a/content/public/common/ssl_status.h +++ b/content/public/common/ssl_status.h
@@ -23,16 +23,21 @@ // Flags used for the page security content status. enum ContentStatusFlags { // HTTP page, or HTTPS page with no insecure content. - NORMAL_CONTENT = 0, + NORMAL_CONTENT = 0, // HTTPS page containing "displayed" HTTP resources (e.g. images, CSS). DISPLAYED_INSECURE_CONTENT = 1 << 0, // HTTPS page containing "executed" HTTP resources (i.e. script). - // Also currently used for HTTPS page containing broken-HTTPS resources; - // this is wrong and should be fixed (see comments in - // SSLPolicy::OnRequestStarted()). - RAN_INSECURE_CONTENT = 1 << 1, + RAN_INSECURE_CONTENT = 1 << 1, + + // HTTPS page containing "displayed" HTTPS resources (e.g. images, + // CSS) loaded with certificate errors. + DISPLAYED_CONTENT_WITH_CERT_ERRORS = 1 << 2, + + // HTTPS page containing "executed" HTTPS resources (i.e. script) + // loaded with certificate errors. + RAN_CONTENT_WITH_CERT_ERRORS = 1 << 3, }; SSLStatus();
diff --git a/content/public/common/web_preferences.cc b/content/public/common/web_preferences.cc index f0703241..52f4de7c 100644 --- a/content/public/common/web_preferences.cc +++ b/content/public/common/web_preferences.cc
@@ -139,7 +139,6 @@ available_hover_types(0), primary_hover_type(ui::HOVER_TYPE_NONE), sync_xhr_in_documents_enabled(true), - image_color_profiles_enabled(false), should_respect_image_orientation(false), number_of_cpu_cores(1), #if defined(OS_MACOSX)
diff --git a/content/public/common/web_preferences.h b/content/public/common/web_preferences.h index 3fb1a79..5693431 100644 --- a/content/public/common/web_preferences.h +++ b/content/public/common/web_preferences.h
@@ -172,7 +172,7 @@ int available_hover_types; ui::HoverType primary_hover_type; bool sync_xhr_in_documents_enabled; - bool image_color_profiles_enabled; + bool color_correct_rendering_enabled = false; bool should_respect_image_orientation; int number_of_cpu_cores; EditingBehavior editing_behavior;
diff --git a/content/public/renderer/pepper_plugin_instance.h b/content/public/renderer/pepper_plugin_instance.h index 46de4fe6..f22948a6 100644 --- a/content/public/renderer/pepper_plugin_instance.h +++ b/content/public/renderer/pepper_plugin_instance.h
@@ -59,8 +59,6 @@ virtual content::RenderFrame* GetRenderFrame() = 0; - virtual content::RenderView* GetRenderView() = 0; - virtual blink::WebPluginContainer* GetContainer() = 0; virtual v8::Isolate* GetIsolate() const = 0;
diff --git a/content/public/renderer/render_frame.h b/content/public/renderer/render_frame.h index 59bec7d2..0ac29c8 100644 --- a/content/public/renderer/render_frame.h +++ b/content/public/renderer/render_frame.h
@@ -105,7 +105,7 @@ // Returns the associated WebFrame. virtual blink::WebLocalFrame* GetWebFrame() = 0; - // Gets WebKit related preferences associated with this frame. + // Gets WebKit related preferences associated with this frame. virtual WebPreferences& GetWebkitPreferences() = 0; // Shows a context menu with the given information. The given client will @@ -188,6 +188,11 @@ // Whitelists a |content_origin| so its content will never be throttled in // this RenderFrame. Whitelist is cleared by top level navigation. virtual void WhitelistContentOrigin(const url::Origin& content_origin) = 0; + + // Used by plugins that load data in this RenderFrame to update the loading + // notifications. + virtual void DidStartLoading() = 0; + virtual void DidStopLoading() = 0; #endif // Returns true if this frame is a FTP directory listing.
diff --git a/content/public/renderer/render_view.h b/content/public/renderer/render_view.h index b8bfe9f..3cddd0e 100644 --- a/content/public/renderer/render_view.h +++ b/content/public/renderer/render_view.h
@@ -28,7 +28,7 @@ class WebView; struct WebContextMenuData; struct WebRect; -} +} // namespace blink namespace gfx { class Point; @@ -103,11 +103,6 @@ // false, but set to true by some tests. virtual bool GetContentStateImmediately() const = 0; - // Used by plugins that load data in this RenderView to update the loading - // notifications. - virtual void DidStartLoading() = 0; - virtual void DidStopLoading() = 0; - // Notifies the renderer that a paint is to be generated for the size // passed in. virtual void Repaint(const gfx::Size& size) = 0;
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestInputMethodManagerWrapper.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestInputMethodManagerWrapper.java index 7cc86b7..68452ed 100644 --- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestInputMethodManagerWrapper.java +++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestInputMethodManagerWrapper.java
@@ -13,6 +13,7 @@ import android.view.inputmethod.InputConnection; import org.chromium.base.Log; +import org.chromium.base.annotations.UsedByReflection; import org.chromium.content.browser.ContentViewCore; import org.chromium.content.browser.input.InputMethodManagerWrapper; import org.chromium.content.browser.input.Range; @@ -23,6 +24,7 @@ /** * Overrides InputMethodManagerWrapper for testing purposes. */ +@UsedByReflection("ThreadedInputConnectionFactory.java") public class TestInputMethodManagerWrapper extends InputMethodManagerWrapper { private static final String TAG = "cr_Ime";
diff --git a/content/public/test/download_test_observer.cc b/content/public/test/download_test_observer.cc index 9d05e28..bf3b158 100644 --- a/content/public/test/download_test_observer.cc +++ b/content/public/test/download_test_observer.cc
@@ -138,7 +138,7 @@ void DownloadTestObserver::OnDownloadUpdated(DownloadItem* download) { // Real UI code gets the user's response after returning from the observer. if (download->IsDangerous() && - !ContainsKey(dangerous_downloads_seen_, download->GetId())) { + !base::ContainsKey(dangerous_downloads_seen_, download->GetId())) { dangerous_downloads_seen_.insert(download->GetId()); // Calling ValidateDangerousDownload() at this point will
diff --git a/content/public/test/mock_special_storage_policy.cc b/content/public/test/mock_special_storage_policy.cc index 0847536..f3b3c02 100644 --- a/content/public/test/mock_special_storage_policy.cc +++ b/content/public/test/mock_special_storage_policy.cc
@@ -13,25 +13,25 @@ } bool MockSpecialStoragePolicy::IsStorageProtected(const GURL& origin) { - return ContainsKey(protected_, origin); + return base::ContainsKey(protected_, origin); } bool MockSpecialStoragePolicy::IsStorageUnlimited(const GURL& origin) { if (all_unlimited_) return true; - return ContainsKey(unlimited_, origin); + return base::ContainsKey(unlimited_, origin); } bool MockSpecialStoragePolicy::IsStorageSessionOnly(const GURL& origin) { - return ContainsKey(session_only_, origin); + return base::ContainsKey(session_only_, origin); } bool MockSpecialStoragePolicy::CanQueryDiskSize(const GURL& origin) { - return ContainsKey(can_query_disk_size_, origin); + return base::ContainsKey(can_query_disk_size_, origin); } bool MockSpecialStoragePolicy::HasIsolatedStorage(const GURL& origin) { - return ContainsKey(isolated_, origin); + return base::ContainsKey(isolated_, origin); } bool MockSpecialStoragePolicy::HasSessionOnlyOrigins() { @@ -39,7 +39,7 @@ } bool MockSpecialStoragePolicy::IsStorageDurable(const GURL& origin) { - return ContainsKey(durable_, origin); + return base::ContainsKey(durable_, origin); } MockSpecialStoragePolicy::~MockSpecialStoragePolicy() {}
diff --git a/content/public/test/test_launcher.cc b/content/public/test/test_launcher.cc index 3630a4e..134edec 100644 --- a/content/public/test/test_launcher.cc +++ b/content/public/test/test_launcher.cc
@@ -236,13 +236,13 @@ std::string full_name(test_names[i]); std::string pre_test_name(GetPreTestName(full_name)); - while (ContainsKey(all_test_names_, pre_test_name)) { + while (base::ContainsKey(all_test_names_, pre_test_name)) { additional_tests_to_run_count++; - DCHECK(!ContainsKey(dependent_test_map_, pre_test_name)); + DCHECK(!base::ContainsKey(dependent_test_map_, pre_test_name)); dependent_test_map_[pre_test_name] = full_name; - DCHECK(!ContainsKey(reverse_dependent_test_map_, full_name)); + DCHECK(!base::ContainsKey(reverse_dependent_test_map_, full_name)); reverse_dependent_test_map_[full_name] = pre_test_name; full_name = pre_test_name; @@ -256,7 +256,7 @@ // Make sure no PRE_ tests were requested explicitly. DCHECK_EQ(full_name, RemoveAnyPrePrefixes(full_name)); - if (!ContainsKey(user_data_dir_map_, full_name)) { + if (!base::ContainsKey(user_data_dir_map_, full_name)) { base::FilePath temp_dir; CHECK(base::CreateTemporaryDirInDir(temp_dir_.path(), FILE_PATH_LITERAL("d"), &temp_dir)); @@ -264,7 +264,7 @@ } // If the test has any dependencies, get to the root and start with that. - while (ContainsKey(reverse_dependent_test_map_, full_name)) + while (base::ContainsKey(reverse_dependent_test_map_, full_name)) full_name = GetPreTestName(full_name); std::vector<std::string> test_list; @@ -288,7 +288,7 @@ // from the very first one. for (size_t i = 0; i < test_names.size(); i++) { std::string test_name(test_names[i]); - while (ContainsKey(reverse_dependent_test_map_, test_name)) { + while (base::ContainsKey(reverse_dependent_test_map_, test_name)) { test_name = reverse_dependent_test_map_[test_name]; test_names_set.insert(test_name); } @@ -314,7 +314,7 @@ // Make sure PRE_ tests and tests that depend on them share the same // data directory - based it on the test name without prefixes. std::string test_name_no_pre(RemoveAnyPrePrefixes(full_name)); - if (!ContainsKey(user_data_dir_map_, test_name_no_pre)) { + if (!base::ContainsKey(user_data_dir_map_, test_name_no_pre)) { base::FilePath temp_dir; CHECK(base::CreateTemporaryDirInDir(temp_dir_.path(), FILE_PATH_LITERAL("d"), &temp_dir)); @@ -327,7 +327,7 @@ std::string test_name = full_name.substr(dot_pos + 1); std::string pre_test_name( test_case_name + "." + kPreTestPrefix + test_name); - if (!ContainsKey(test_names_set, pre_test_name)) + if (!base::ContainsKey(test_names_set, pre_test_name)) tests_to_run_now.push_back(full_name); } @@ -403,7 +403,7 @@ test_result.status = base::TestResult::TEST_SKIPPED; test_launcher->OnTestFinished(test_result); - if (ContainsKey(dependent_test_map_, test_name)) { + if (base::ContainsKey(dependent_test_map_, test_name)) { RunDependentTest(test_launcher, dependent_test_map_[test_name], test_result); @@ -435,13 +435,13 @@ result.output_snippet = GetTestOutputSnippet(result, output); - if (ContainsKey(dependent_test_map_, test_name)) { + if (base::ContainsKey(dependent_test_map_, test_name)) { RunDependentTest(test_launcher, dependent_test_map_[test_name], result); } else { // No other tests depend on this, we can delete the temporary directory now. // Do so to avoid too many temporary files using lots of disk space. std::string test_name_no_pre(RemoveAnyPrePrefixes(test_name)); - if (ContainsKey(user_data_dir_map_, test_name_no_pre)) { + if (base::ContainsKey(user_data_dir_map_, test_name_no_pre)) { if (!base::DeleteFile(user_data_dir_map_[test_name_no_pre], true)) { LOG(WARNING) << "Failed to delete " << user_data_dir_map_[test_name_no_pre].value();
diff --git a/content/public/test/test_navigation_observer.cc b/content/public/test/test_navigation_observer.cc index 1371ba32..b8a57a2 100644 --- a/content/public/test/test_navigation_observer.cc +++ b/content/public/test/test_navigation_observer.cc
@@ -110,8 +110,8 @@ TestNavigationObserver::~TestNavigationObserver() { StopWatchingNewWebContents(); - STLDeleteContainerPointers(web_contents_observers_.begin(), - web_contents_observers_.end()); + base::STLDeleteContainerPointers(web_contents_observers_.begin(), + web_contents_observers_.end()); } void TestNavigationObserver::Wait() {
diff --git a/content/public/test/text_input_test_utils.cc b/content/public/test/text_input_test_utils.cc index 79ab737..614ead5 100644 --- a/content/public/test/text_input_test_utils.cc +++ b/content/public/test/text_input_test_utils.cc
@@ -12,6 +12,7 @@ #include "content/browser/renderer_host/render_widget_host_view_base_observer.h" #include "content/browser/renderer_host/text_input_manager.h" #include "content/browser/web_contents/web_contents_impl.h" +#include "content/common/input_messages.h" #include "content/common/text_input_state.h" #include "content/common/view_messages.h" #include "content/public/browser/render_widget_host_view.h" @@ -244,23 +245,15 @@ return true; } -void SetCompositionForRenderWidgetHost( - RenderWidgetHost* render_widget_host, - const base::string16& text, - const std::vector<ui::CompositionUnderline>& underlines, - const gfx::Range& replacement_range, - int selection_start, - int selection_end) { - std::vector<blink::WebCompositionUnderline> web_underlines; - for (auto underline : underlines) { - web_underlines.emplace_back(blink::WebCompositionUnderline( - underline.start_offset, underline.end_offset, underline.color, - underline.thick, underline.background_color)); - } +bool RequestCompositionInfoFromActiveWidget(WebContents* web_contents) { + TextInputManager* manager = + static_cast<WebContentsImpl*>(web_contents)->GetTextInputManager(); + if (!manager || !manager->GetActiveWidget()) + return false; - static_cast<RenderWidgetHostImpl*>(render_widget_host) - ->ImeSetComposition(text, web_underlines, replacement_range, - selection_start, selection_end); + manager->GetActiveWidget()->Send(new InputMsg_RequestCompositionUpdate( + manager->GetActiveWidget()->GetRoutingID(), true, false)); + return true; } size_t GetRegisteredViewsCountFromTextInputManager(WebContents* web_contents) {
diff --git a/content/public/test/text_input_test_utils.h b/content/public/test/text_input_test_utils.h index 1f36862..7785b67 100644 --- a/content/public/test/text_input_test_utils.h +++ b/content/public/test/text_input_test_utils.h
@@ -49,15 +49,11 @@ // given WebContents. RenderWidgetHostView* GetActiveViewFromWebContents(WebContents* web_contents); -// This method will send an InputMsg_ImeSetComposition IPC with the provided -// parameters to the |render_widget_host|. -void SetCompositionForRenderWidgetHost( - RenderWidgetHost* render_widget_host, - const base::string16& text, - const std::vector<ui::CompositionUnderline>& underlines, - const gfx::Range& replacement_range, - int selection_start, - int selection_end); +// This method will send a request for an immediate update on composition range +// from TextInputManager's active widget corresponding to the |web_contents|. +// This function will return false if the request is not successfully sent; +// either due to missing TextInputManager or lack of an active widget. +bool RequestCompositionInfoFromActiveWidget(WebContents* web_contents); // This class provides the necessary API for accessing the state of and also // observing the TextInputManager for WebContents.
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index b27095f..0da94dd 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -103,7 +103,7 @@ if (use_aura) { public_deps += [ "//content/renderer/mus" ] allow_circular_includes_from += [ "//content/renderer/mus" ] - deps += [ "//services/ui/common:mus_common" ] + deps += [ "//services/ui/public/cpp" ] } if (use_external_popup_menu) {
diff --git a/content/renderer/OWNERS b/content/renderer/OWNERS index d285f815..ec2f37c 100644 --- a/content/renderer/OWNERS +++ b/content/renderer/OWNERS
@@ -11,4 +11,9 @@ # Web Notifications. per-file notification_permission_dispatcher.*=mvanouwerkerk@chromium.org -per-file notification_permission_dispatcher.*=peter@chromium.org \ No newline at end of file +per-file notification_permission_dispatcher.*=peter@chromium.org + +# WebSocket +per-file *websocket*=ricea@chromium.org +per-file *websocket*=tyoshino@chromium.org +per-file *websocket*=yhirano@chromium.org
diff --git a/content/renderer/android/synchronous_compositor_filter.cc b/content/renderer/android/synchronous_compositor_filter.cc index 3dbadcc1..dc96477 100644 --- a/content/renderer/android/synchronous_compositor_filter.cc +++ b/content/renderer/android/synchronous_compositor_filter.cc
@@ -219,12 +219,12 @@ void SynchronousCompositorFilter::DidRemoveSynchronousHandlerProxy( int routing_id) { DCHECK(compositor_task_runner_->BelongsToCurrentThread()); - if (ContainsKey(sync_compositor_map_, routing_id)) { + if (base::ContainsKey(sync_compositor_map_, routing_id)) { DCHECK(compositor_task_runner_->BelongsToCurrentThread()); DCHECK(sync_compositor_map_.contains(routing_id)); sync_compositor_map_.erase(routing_id); } - if (ContainsKey(synchronous_input_handler_proxy_map_, routing_id)) + if (base::ContainsKey(synchronous_input_handler_proxy_map_, routing_id)) synchronous_input_handler_proxy_map_.erase(routing_id); }
diff --git a/content/renderer/categorized_worker_pool.cc b/content/renderer/categorized_worker_pool.cc index 8250071c..47298b3 100644 --- a/content/renderer/categorized_worker_pool.cc +++ b/content/renderer/categorized_worker_pool.cc
@@ -150,7 +150,7 @@ // Use background priority for background thread. base::SimpleThread::Options thread_options; #if !defined(OS_MACOSX) - thread_options.set_priority(base::ThreadPriority::BACKGROUND); + thread_options.priority = base::ThreadPriority::BACKGROUND; #endif std::unique_ptr<base::SimpleThread> thread(new CategorizedWorkerPoolThread(
diff --git a/content/renderer/gpu/frame_swap_message_queue.cc b/content/renderer/gpu/frame_swap_message_queue.cc index 6e59dc1..163760e 100644 --- a/content/renderer/gpu/frame_swap_message_queue.cc +++ b/content/renderer/gpu/frame_swap_message_queue.cc
@@ -54,7 +54,7 @@ ~VisualStateQueue() override { for (VisualStateQueueMap::iterator i = queue_.begin(); i != queue_.end(); i++) { - STLDeleteElements(&i->second); + base::STLDeleteElements(&i->second); } }
diff --git a/content/renderer/gpu/queue_message_swap_promise.cc b/content/renderer/gpu/queue_message_swap_promise.cc index 8b99a17..548214f 100644 --- a/content/renderer/gpu/queue_message_swap_promise.cc +++ b/content/renderer/gpu/queue_message_swap_promise.cc
@@ -66,7 +66,8 @@ PromiseCompleted(); } -void QueueMessageSwapPromise::DidNotSwap(DidNotSwapReason reason) { +cc::SwapPromise::DidNotSwapAction QueueMessageSwapPromise::DidNotSwap( + DidNotSwapReason reason) { #if DCHECK_IS_ON() DCHECK(!completed_); #endif @@ -76,6 +77,7 @@ message_sender_->Send(msg.release()); } PromiseCompleted(); + return DidNotSwapAction::BREAK_PROMISE; } void QueueMessageSwapPromise::PromiseCompleted() {
diff --git a/content/renderer/gpu/queue_message_swap_promise.h b/content/renderer/gpu/queue_message_swap_promise.h index a43626b..637b4df 100644 --- a/content/renderer/gpu/queue_message_swap_promise.h +++ b/content/renderer/gpu/queue_message_swap_promise.h
@@ -28,7 +28,7 @@ void DidActivate() override; void DidSwap(cc::CompositorFrameMetadata* metadata) override; - void DidNotSwap(DidNotSwapReason reason) override; + DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override; int64_t TraceId() const override;
diff --git a/content/renderer/input/input_event_filter.cc b/content/renderer/input/input_event_filter.cc index bb9f6a8..b3bf1fda 100644 --- a/content/renderer/input/input_event_filter.cc +++ b/content/renderer/input/input_event_filter.cc
@@ -181,7 +181,7 @@ InputMsg_HandleInputEvent::Param params; if (!InputMsg_HandleInputEvent::Read(&message, ¶ms)) return; - const WebInputEvent* event = std::get<0>(params); + ScopedWebInputEvent event = WebInputEventTraits::Clone(*std::get<0>(params)); ui::LatencyInfo latency_info = std::get<1>(params); InputEventDispatchType dispatch_type = std::get<2>(params); DCHECK(event); @@ -197,23 +197,29 @@ auto_reset_current_overscroll_params( ¤t_overscroll_params_, send_ack ? &overscroll_params : NULL); - InputEventAckState ack_state = handler_.Run(routing_id, event, &latency_info); + InputEventAckState ack_state = + handler_.Run(routing_id, event.get(), &latency_info); + + uint32_t unique_touch_event_id = + WebInputEventTraits::GetUniqueTouchEventId(*event); + WebInputEvent::Type type = event->type; if (ack_state == INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING || ack_state == INPUT_EVENT_ACK_STATE_NOT_CONSUMED) { DCHECK(!overscroll_params); RouteQueueMap::iterator iter = route_queues_.find(routing_id); - if (iter != route_queues_.end()) - send_ack &= iter->second->HandleEvent(event, latency_info, dispatch_type, - ack_state); + if (iter != route_queues_.end()) { + send_ack &= iter->second->HandleEvent(std::move(event), latency_info, + dispatch_type, ack_state); + } } + event.reset(); if (!send_ack) return; - InputEventAck ack(event->type, ack_state, latency_info, - std::move(overscroll_params), - WebInputEventTraits::GetUniqueTouchEventId(*event)); + InputEventAck ack(type, ack_state, latency_info, std::move(overscroll_params), + unique_touch_event_id); SendMessage(std::unique_ptr<IPC::Message>( new InputHostMsg_HandleInputEvent_ACK(routing_id, ack))); }
diff --git a/content/renderer/input/input_handler_manager.cc b/content/renderer/input/input_handler_manager.cc index 29ea2e4..5c5f2a8f6 100644 --- a/content/renderer/input/input_handler_manager.cc +++ b/content/renderer/input/input_handler_manager.cc
@@ -197,18 +197,18 @@ const WebInputEvent* input_event, ui::LatencyInfo* latency_info) { DCHECK(task_runner_->BelongsToCurrentThread()); - TRACE_EVENT1("input,benchmark", "InputHandlerManager::HandleInputEvent", + TRACE_EVENT1("input,benchmark,rail", "InputHandlerManager::HandleInputEvent", "type", WebInputEventTraits::GetName(input_event->type)); auto it = input_handlers_.find(routing_id); if (it == input_handlers_.end()) { - TRACE_EVENT1("input", "InputHandlerManager::HandleInputEvent", + TRACE_EVENT1("input,rail", "InputHandlerManager::HandleInputEvent", "result", "NoInputHandlerFound"); // Oops, we no longer have an interested input handler.. return INPUT_EVENT_ACK_STATE_NOT_CONSUMED; } - TRACE_EVENT1("input", "InputHandlerManager::HandleInputEvent", + TRACE_EVENT1("input,rail", "InputHandlerManager::HandleInputEvent", "result", "EventSentToInputHandlerProxy"); InputHandlerProxy* proxy = it->second->input_handler_proxy(); InputEventAckState input_event_ack_state = InputEventDispositionToAck(
diff --git a/content/renderer/input/main_thread_event_queue.cc b/content/renderer/input/main_thread_event_queue.cc index 772d3be1..ee2a3491 100644 --- a/content/renderer/input/main_thread_event_queue.cc +++ b/content/renderer/input/main_thread_event_queue.cc
@@ -9,10 +9,10 @@ namespace content { EventWithDispatchType::EventWithDispatchType( - const blink::WebInputEvent& event, + ScopedWebInputEvent event, const ui::LatencyInfo& latency, InputEventDispatchType dispatch_type) - : ScopedWebInputEventWithLatencyInfo(event, latency), + : ScopedWebInputEventWithLatencyInfo(std::move(event), latency), dispatch_type_(dispatch_type) {} EventWithDispatchType::~EventWithDispatchType() {} @@ -46,7 +46,7 @@ MainThreadEventQueue::~MainThreadEventQueue() {} bool MainThreadEventQueue::HandleEvent( - const blink::WebInputEvent* event, + ScopedWebInputEvent event, const ui::LatencyInfo& latency, InputEventDispatchType original_dispatch_type, InputEventAckState ack_result) { @@ -64,28 +64,28 @@ bool is_wheel = event->type == blink::WebInputEvent::MouseWheel; bool is_touch = blink::WebInputEvent::isTouchEventType(event->type); - std::unique_ptr<EventWithDispatchType> cloned_event( - new EventWithDispatchType(*event, latency, dispatch_type)); - if (is_touch) { - blink::WebTouchEvent& touch_event = - static_cast<blink::WebTouchEvent&>(cloned_event->event()); - touch_event.dispatchedDuringFling = is_flinging_; + blink::WebTouchEvent* touch_event = + static_cast<blink::WebTouchEvent*>(event.get()); + touch_event->dispatchedDuringFling = is_flinging_; // Adjust the |dispatchType| on the event since the compositor // determined all event listeners are passive. if (non_blocking) { - touch_event.dispatchType = + touch_event->dispatchType = blink::WebInputEvent::ListenersNonBlockingPassive; } } if (is_wheel && non_blocking) { // Adjust the |dispatchType| on the event since the compositor // determined all event listeners are passive. - static_cast<blink::WebMouseWheelEvent&>(cloned_event->event()) - .dispatchType = blink::WebInputEvent::ListenersNonBlockingPassive; + static_cast<blink::WebMouseWheelEvent*>(event.get()) + ->dispatchType = blink::WebInputEvent::ListenersNonBlockingPassive; } - QueueEvent(std::move(cloned_event)); + std::unique_ptr<EventWithDispatchType> event_with_dispatch_type( + new EventWithDispatchType(std::move(event), latency, dispatch_type)); + + QueueEvent(std::move(event_with_dispatch_type)); // send an ack when we are non-blocking. return non_blocking;
diff --git a/content/renderer/input/main_thread_event_queue.h b/content/renderer/input/main_thread_event_queue.h index 6b0bd9bd..9c2d2af 100644 --- a/content/renderer/input/main_thread_event_queue.h +++ b/content/renderer/input/main_thread_event_queue.h
@@ -19,7 +19,7 @@ class EventWithDispatchType : public ScopedWebInputEventWithLatencyInfo { public: - EventWithDispatchType(const blink::WebInputEvent& event, + EventWithDispatchType(ScopedWebInputEvent event, const ui::LatencyInfo& latency, InputEventDispatchType dispatch_type); ~EventWithDispatchType(); @@ -103,7 +103,7 @@ // Called once the compositor has handled |event| and indicated that it is // a non-blocking event to be queued to the main thread. - bool HandleEvent(const blink::WebInputEvent* event, + bool HandleEvent(ScopedWebInputEvent event, const ui::LatencyInfo& latency, InputEventDispatchType dispatch_type, InputEventAckState ack_result);
diff --git a/content/renderer/input/main_thread_event_queue_unittest.cc b/content/renderer/input/main_thread_event_queue_unittest.cc index 5fbf8b0a..e54d079 100644 --- a/content/renderer/input/main_thread_event_queue_unittest.cc +++ b/content/renderer/input/main_thread_event_queue_unittest.cc
@@ -61,6 +61,12 @@ additional_acked_events_.push_back(touch_event_id); } + void HandleEvent(WebInputEvent& event, InputEventAckState ack_result) { + queue_->HandleEvent(WebInputEventTraits::Clone(event), ui::LatencyInfo(), + DISPATCH_TYPE_BLOCKING, + ack_result); + } + WebInputEventQueue<EventWithDispatchType>& event_queue() { return queue_->events_; } @@ -82,14 +88,10 @@ EXPECT_FALSE(main_task_runner_->HasPendingTask()); EXPECT_EQ(0u, event_queue().size()); - queue_->HandleEvent(&kEvents[0], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING, - INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); - queue_->HandleEvent(&kEvents[1], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING, - INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); - queue_->HandleEvent(&kEvents[2], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING, - INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); - queue_->HandleEvent(&kEvents[3], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING, - INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); + + for (WebMouseWheelEvent& event : kEvents) + HandleEvent(event, INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); + EXPECT_EQ(2u, event_queue().size()); EXPECT_TRUE(main_task_runner_->HasPendingTask()); main_task_runner_->RunUntilIdle(); @@ -132,14 +134,9 @@ kEvents[2].MovePoint(0, 30, 30); kEvents[3].PressPoint(10, 10); kEvents[3].MovePoint(0, 35, 35); - queue_->HandleEvent(&kEvents[0], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING, - INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); - queue_->HandleEvent(&kEvents[1], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING, - INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); - queue_->HandleEvent(&kEvents[2], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING, - INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); - queue_->HandleEvent(&kEvents[3], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING, - INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); + + for (SyntheticWebTouchEvent& event : kEvents) + HandleEvent(event, INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); EXPECT_EQ(3u, event_queue().size()); EXPECT_TRUE(main_task_runner_->HasPendingTask()); @@ -185,14 +182,11 @@ kEvents[3].PressPoint(10, 10); kEvents[3].MovePoint(0, 35, 35); // Ensure that coalescing takes place. - queue_->HandleEvent(&kEvents[0], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING, - INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); - queue_->HandleEvent(&kEvents[1], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING, - INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - queue_->HandleEvent(&kEvents[2], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING, - INPUT_EVENT_ACK_STATE_NOT_CONSUMED); - queue_->HandleEvent(&kEvents[3], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING, - INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + HandleEvent(kEvents[0], INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); + HandleEvent(kEvents[1], INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + HandleEvent(kEvents[2], INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + HandleEvent(kEvents[3], INPUT_EVENT_ACK_STATE_NOT_CONSUMED); + EXPECT_EQ(2u, event_queue().size()); EXPECT_TRUE(main_task_runner_->HasPendingTask()); main_task_runner_->RunUntilIdle(); @@ -215,18 +209,12 @@ EXPECT_FALSE(main_task_runner_->HasPendingTask()); EXPECT_EQ(0u, event_queue().size()); - queue_->HandleEvent(&kWheelEvents[0], ui::LatencyInfo(), - DISPATCH_TYPE_BLOCKING, - INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); - queue_->HandleEvent(&kTouchEvents[0], ui::LatencyInfo(), - DISPATCH_TYPE_BLOCKING, - INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); - queue_->HandleEvent(&kWheelEvents[1], ui::LatencyInfo(), - DISPATCH_TYPE_BLOCKING, - INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); - queue_->HandleEvent(&kTouchEvents[1], ui::LatencyInfo(), - DISPATCH_TYPE_BLOCKING, - INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); + + HandleEvent(kWheelEvents[0], INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); + HandleEvent(kTouchEvents[0], INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); + HandleEvent(kWheelEvents[1], INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); + HandleEvent(kTouchEvents[1], INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING); + EXPECT_EQ(2u, event_queue().size()); EXPECT_TRUE(main_task_runner_->HasPendingTask()); main_task_runner_->RunUntilIdle();
diff --git a/content/renderer/input/render_widget_input_handler.cc b/content/renderer/input/render_widget_input_handler.cc index e9b4cb5..55f2aef 100644 --- a/content/renderer/input/render_widget_input_handler.cc +++ b/content/renderer/input/render_widget_input_handler.cc
@@ -243,7 +243,7 @@ if (base::TimeTicks::IsHighResolution()) start_time = base::TimeTicks::Now(); - TRACE_EVENT1("renderer,benchmark", + TRACE_EVENT1("renderer,benchmark,rail", "RenderWidgetInputHandler::OnHandleInputEvent", "event", WebInputEventTraits::GetName(input_event.type)); TRACE_EVENT_SYNTHETIC_DELAY_BEGIN("blink.HandleInputEvent");
diff --git a/content/renderer/media/android/media_player_renderer_client.cc b/content/renderer/media/android/media_player_renderer_client.cc new file mode 100644 index 0000000..20a5871 --- /dev/null +++ b/content/renderer/media/android/media_player_renderer_client.cc
@@ -0,0 +1,157 @@ +// Copyright 2016 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/media/android/media_player_renderer_client.h" + +#include "base/callback_helpers.h" + +namespace content { + +MediaPlayerRendererClient::MediaPlayerRendererClient( + scoped_refptr<base::SingleThreadTaskRunner> media_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner, + media::MojoRenderer* mojo_renderer, + media::ScopedStreamTextureWrapper stream_texture_wrapper, + media::VideoRendererSink* sink) + : mojo_renderer_(mojo_renderer), + stream_texture_wrapper_(std::move(stream_texture_wrapper)), + client_(nullptr), + sink_(sink), + media_task_runner_(std::move(media_task_runner)), + compositor_task_runner_(std::move(compositor_task_runner)), + weak_factory_(this) {} + +MediaPlayerRendererClient::~MediaPlayerRendererClient() {} + +void MediaPlayerRendererClient::Initialize( + media::DemuxerStreamProvider* demuxer_stream_provider, + media::RendererClient* client, + const media::PipelineStatusCB& init_cb) { + DCHECK(media_task_runner_->BelongsToCurrentThread()); + DCHECK(!init_cb_); + + client_ = client; + init_cb_ = init_cb; + + // Initialize the StreamTexture using a 1x1 texture because we do not have + // any size information from the MediaPlayer yet. + // The size will be automatically updated in OnVideoNaturalSizeChange() once + // we parse the media's metadata. + // Unretained is safe here because |stream_texture_wrapper_| resets the + // Closure it has before destroying itself on |compositor_task_runner_|, + // and |this| is garanteed to live until the Closure has been reset. + stream_texture_wrapper_->Initialize( + base::Bind(&MediaPlayerRendererClient::OnFrameAvailable, + base::Unretained(this)), + gfx::Size(1, 1), compositor_task_runner_, + base::Bind(&MediaPlayerRendererClient::InitializeRemoteRenderer, + weak_factory_.GetWeakPtr(), demuxer_stream_provider)); +} + +void MediaPlayerRendererClient::InitializeRemoteRenderer( + media::DemuxerStreamProvider* demuxer_stream_provider) { + DCHECK(media_task_runner_->BelongsToCurrentThread()); + mojo_renderer_->Initialize( + demuxer_stream_provider, this, + base::Bind(&MediaPlayerRendererClient::CompleteInitialization, + weak_factory_.GetWeakPtr())); +} + +void MediaPlayerRendererClient::CompleteInitialization( + media::PipelineStatus status) { + DCHECK(media_task_runner_->BelongsToCurrentThread()); + DCHECK(!init_cb_.is_null()); + + // TODO(tguilbert): Register |stream_texture_wrapper_|'s surface and send it + // to MediaPlayerRenderer via |mojo_renderer_|. See crbug.com/627658. + + base::ResetAndReturn(&init_cb_).Run(status); +} + +void MediaPlayerRendererClient::SetCdm( + media::CdmContext* cdm_context, + const media::CdmAttachedCB& cdm_attached_cb) { + NOTREACHED(); +} + +void MediaPlayerRendererClient::Flush(const base::Closure& flush_cb) { + mojo_renderer_->Flush(flush_cb); +} + +void MediaPlayerRendererClient::StartPlayingFrom(base::TimeDelta time) { + mojo_renderer_->StartPlayingFrom(time); +} + +void MediaPlayerRendererClient::SetPlaybackRate(double playback_rate) { + mojo_renderer_->SetPlaybackRate(playback_rate); +} + +void MediaPlayerRendererClient::SetVolume(float volume) { + mojo_renderer_->SetVolume(volume); +} + +base::TimeDelta MediaPlayerRendererClient::GetMediaTime() { + return mojo_renderer_->GetMediaTime(); +} + +bool MediaPlayerRendererClient::HasAudio() { + // We do not know whether or not the media has Audio before starting playback. + // Conservatively assume we do. + // TODO(tguilbert): Consider using MIME types to determine presence of audio. + // Alternatively, consider piping the HasAudio() from the MediaPlayerRenderer + // through the mojo::Renderer interface. + return true; +} + +bool MediaPlayerRendererClient::HasVideo() { + // We do not know whether or not the media has Video before starting playback. + // Conservatively assume we do. + // TODO(tguilbert): Consider using MIME types to determine presence of video. + // Alternatively, consider piping the HasVideo() from the MediaPlayerRenderer + // through the mojo::Renderer interface. + return true; +} + +void MediaPlayerRendererClient::OnFrameAvailable() { + DCHECK(compositor_task_runner_->BelongsToCurrentThread()); + sink_->PaintSingleFrame(stream_texture_wrapper_->GetCurrentFrame(), true); +} + +void MediaPlayerRendererClient::OnError(media::PipelineStatus status) { + client_->OnError(status); +} + +void MediaPlayerRendererClient::OnEnded() { + client_->OnEnded(); +} + +void MediaPlayerRendererClient::OnStatisticsUpdate( + const media::PipelineStatistics& stats) { + client_->OnStatisticsUpdate(stats); +} + +void MediaPlayerRendererClient::OnBufferingStateChange( + media::BufferingState state) { + client_->OnBufferingStateChange(state); +} + +void MediaPlayerRendererClient::OnWaitingForDecryptionKey() { + client_->OnWaitingForDecryptionKey(); +} + +void MediaPlayerRendererClient::OnVideoNaturalSizeChange( + const gfx::Size& size) { + stream_texture_wrapper_->UpdateTextureSize(size); + client_->OnVideoNaturalSizeChange(size); +} + +void MediaPlayerRendererClient::OnVideoOpacityChange(bool opaque) { + client_->OnVideoOpacityChange(opaque); +} + +void MediaPlayerRendererClient::OnDurationChange(base::TimeDelta duration) { + client_->OnDurationChange(duration); +} + +} // namespace content
diff --git a/content/renderer/media/android/media_player_renderer_client.h b/content/renderer/media/android/media_player_renderer_client.h new file mode 100644 index 0000000..cdfbce269 --- /dev/null +++ b/content/renderer/media/android/media_player_renderer_client.h
@@ -0,0 +1,107 @@ +// Copyright 2016 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_MEDIA_ANDROID_MEDIA_PLAYER_RENDERER_CLIENT_H_ +#define CONTENT_RENDERER_MEDIA_ANDROID_MEDIA_PLAYER_RENDERER_CLIENT_H_ + +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "content/common/content_export.h" +#include "media/base/android/stream_texture_wrapper.h" +#include "media/base/demuxer_stream_provider.h" +#include "media/base/renderer.h" +#include "media/base/renderer_client.h" +#include "media/base/video_renderer_sink.h" +#include "media/mojo/clients/mojo_renderer.h" + +namespace content { + +// MediaPlayerRendererClient lives in Renderer process and mirrors a +// MediaPlayerRenderer living in the Browser process. +// +// It is responsible for forwarding media::Renderer calls from WMPI to the +// MediaPlayerRenderer, using |mojo_renderer|. It also manages a StreamTexture, +// (via |stream_texture_wrapper_|) and notifies the VideoRendererSink when new +// frames are available. +// +// This class handles all calls on |media_task_runner_|, except for +// OnFrameAvailable(), which is called on |compositor_task_runner_|. +// +// N.B: This class implements media::RendererClient, in order to intercept +// OnVideoNaturalSizeChange() events, to update StreamTextureWrapper. All events +// (including OnVideoNaturalSizeChange()) are bubbled up to |client_|. +class CONTENT_EXPORT MediaPlayerRendererClient : public media::Renderer, + public media::RendererClient { + public: + MediaPlayerRendererClient( + scoped_refptr<base::SingleThreadTaskRunner> media_task_runner, + scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner, + media::MojoRenderer* mojo_renderer, + media::ScopedStreamTextureWrapper stream_texture_wrapper, + media::VideoRendererSink* sink); + + ~MediaPlayerRendererClient() override; + + // media::Renderer implementation. + void Initialize(media::DemuxerStreamProvider* demuxer_stream_provider, + media::RendererClient* client, + const media::PipelineStatusCB& init_cb) override; + void SetCdm(media::CdmContext* cdm_context, + const media::CdmAttachedCB& cdm_attached_cb) override; + void Flush(const base::Closure& flush_cb) override; + void StartPlayingFrom(base::TimeDelta time) override; + void SetPlaybackRate(double playback_rate) override; + void SetVolume(float volume) override; + base::TimeDelta GetMediaTime() override; + bool HasAudio() override; + bool HasVideo() override; + + // media::RendererClient implementation. + void OnError(media::PipelineStatus status) override; + void OnEnded() override; + void OnStatisticsUpdate(const media::PipelineStatistics& stats) override; + void OnBufferingStateChange(media::BufferingState state) override; + void OnWaitingForDecryptionKey() override; + void OnVideoNaturalSizeChange(const gfx::Size& size) override; + void OnVideoOpacityChange(bool opaque) override; + void OnDurationChange(base::TimeDelta duration) override; + + // Called on |compositor_task_runner_| whenever |stream_texture_wrapper_| has + // a new frame. + void OnFrameAvailable(); + + private: + void InitializeRemoteRenderer( + media::DemuxerStreamProvider* demuxer_stream_provider); + void CompleteInitialization(media::PipelineStatus status); + + // Used to forward calls to the MediaPlayerRenderer living in the Browser. + std::unique_ptr<media::MojoRenderer> mojo_renderer_; + + // Owns the StreamTexture whose surface is used by MediaPlayerRenderer. + // Provides the VideoFrames to |sink_|. + media::ScopedStreamTextureWrapper stream_texture_wrapper_; + + media::RendererClient* client_; + + media::VideoRendererSink* sink_; + + scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_; + + // Used by |stream_texture_wrapper_| to signal OnFrameAvailable() and to send + // VideoFrames to |sink_| on the right thread. + scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; + + media::PipelineStatusCB init_cb_; + + // NOTE: Weak pointers must be invalidated before all other member variables. + base::WeakPtrFactory<MediaPlayerRendererClient> weak_factory_; + + DISALLOW_COPY_AND_ASSIGN(MediaPlayerRendererClient); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_ANDROID_MEDIA_PLAYER_RENDERER_CLIENT_H_
diff --git a/content/renderer/media/android/media_player_renderer_client_factory.cc b/content/renderer/media/android/media_player_renderer_client_factory.cc new file mode 100644 index 0000000..66fa36d --- /dev/null +++ b/content/renderer/media/android/media_player_renderer_client_factory.cc
@@ -0,0 +1,46 @@ +// Copyright 2016 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/media/android/media_player_renderer_client_factory.h" + +#include "base/memory/ptr_util.h" +#include "content/renderer/media/android/media_player_renderer_client.h" +#include "media/mojo/clients/mojo_renderer.h" + +namespace content { + +MediaPlayerRendererClientFactory::MediaPlayerRendererClientFactory( + scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner, + std::unique_ptr<media::RendererFactory> mojo_renderer_factory, + const GetStreamTextureWrapperCB& get_stream_texture_wrapper_cb) + : get_stream_texture_wrapper_cb_(get_stream_texture_wrapper_cb), + compositor_task_runner_(std::move(compositor_task_runner)), + mojo_renderer_factory_(std::move(mojo_renderer_factory)) {} + +MediaPlayerRendererClientFactory::~MediaPlayerRendererClientFactory() {} + +std::unique_ptr<media::Renderer> +MediaPlayerRendererClientFactory::CreateRenderer( + const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, + const scoped_refptr<base::TaskRunner>& worker_task_runner, + media::AudioRendererSink* audio_renderer_sink, + media::VideoRendererSink* video_renderer_sink, + const media::RequestSurfaceCB& request_surface_cb) { + std::unique_ptr<media::Renderer> renderer = + mojo_renderer_factory_->CreateRenderer( + media_task_runner, worker_task_runner, audio_renderer_sink, + video_renderer_sink, request_surface_cb); + + media::MojoRenderer* mojo_renderer = + static_cast<media::MojoRenderer*>(renderer.release()); + + media::ScopedStreamTextureWrapper stream_texture_wrapper = + get_stream_texture_wrapper_cb_.Run(); + + return base::WrapUnique(new MediaPlayerRendererClient( + media_task_runner, compositor_task_runner_, mojo_renderer, + std::move(stream_texture_wrapper), video_renderer_sink)); +} + +} // namespace content
diff --git a/content/renderer/media/android/media_player_renderer_client_factory.h b/content/renderer/media/android/media_player_renderer_client_factory.h new file mode 100644 index 0000000..ee514cf --- /dev/null +++ b/content/renderer/media/android/media_player_renderer_client_factory.h
@@ -0,0 +1,53 @@ +// Copyright 2016 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_MEDIA_ANDROID_MEDIA_PLAYER_RENDERER_CLIENT_FACTORY_H_ +#define CONTENT_RENDERER_MEDIA_ANDROID_MEDIA_PLAYER_RENDERER_CLIENT_FACTORY_H_ + +#include "base/callback.h" +#include "base/macros.h" +#include "content/common/content_export.h" +#include "media/base/android/stream_texture_wrapper.h" +#include "media/base/renderer_factory.h" +#include "media/mojo/clients/mojo_renderer_factory.h" +#include "mojo/public/cpp/bindings/interface_request.h" + +namespace media { +class GpuVideoAcceleratorFactories; +} + +namespace content { + +// The default class for creating a MediaPlayerRendererClient +// and its associated MediaPlayerRenderer. +class CONTENT_EXPORT MediaPlayerRendererClientFactory + : public media::RendererFactory { + public: + using GetStreamTextureWrapperCB = + base::Callback<media::ScopedStreamTextureWrapper()>; + + MediaPlayerRendererClientFactory( + scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner, + std::unique_ptr<media::RendererFactory> mojo_renderer_factory, + const GetStreamTextureWrapperCB& get_stream_texture_wrapper_cb); + ~MediaPlayerRendererClientFactory() override; + + std::unique_ptr<media::Renderer> CreateRenderer( + const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, + const scoped_refptr<base::TaskRunner>& worker_task_runner, + media::AudioRendererSink* audio_renderer_sink, + media::VideoRendererSink* video_renderer_sink, + const media::RequestSurfaceCB& request_surface_cb) override; + + private: + GetStreamTextureWrapperCB get_stream_texture_wrapper_cb_; + + scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; + + std::unique_ptr<media::RendererFactory> mojo_renderer_factory_; +}; + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_ANDROID_MEDIA_PLAYER_RENDERER_CLIENT_FACTORY_H_
diff --git a/content/renderer/media/audio_track_recorder.cc b/content/renderer/media/audio_track_recorder.cc index 11a77b1..253c7d9 100644 --- a/content/renderer/media/audio_track_recorder.cc +++ b/content/renderer/media/audio_track_recorder.cc
@@ -63,7 +63,8 @@ data_out->resize(kOpusMaxDataBytes); const opus_int32 result = opus_encode_float( opus_encoder, data_in, num_samples, - reinterpret_cast<uint8_t*>(string_as_array(data_out)), kOpusMaxDataBytes); + reinterpret_cast<uint8_t*>(base::string_as_array(data_out)), + kOpusMaxDataBytes); if (result > 1) { // TODO(ajose): Investigate improving this. http://crbug.com/547918
diff --git a/content/renderer/media/audio_track_recorder_unittest.cc b/content/renderer/media/audio_track_recorder_unittest.cc index cdc376d..601867d 100644 --- a/content/renderer/media/audio_track_recorder_unittest.cc +++ b/content/renderer/media/audio_track_recorder_unittest.cc
@@ -180,7 +180,7 @@ EXPECT_EQ(kDefaultSampleRate * kOpusBufferDurationMs / 1000, opus_decode_float( opus_decoder_, reinterpret_cast<uint8_t*>( - string_as_array(encoded_data.get())), + base::string_as_array(encoded_data.get())), encoded_data->size(), buffer_.get(), kFramesPerBuffer, 0)); DoOnEncodedAudio(params, *encoded_data, timestamp);
diff --git a/content/renderer/media/cdm/renderer_cdm_manager.cc b/content/renderer/media/cdm/renderer_cdm_manager.cc index 4bf322a..4d36766 100644 --- a/content/renderer/media/cdm/renderer_cdm_manager.cc +++ b/content/renderer/media/cdm/renderer_cdm_manager.cc
@@ -233,13 +233,13 @@ int RendererCdmManager::RegisterMediaKeys(ProxyMediaKeys* media_keys) { int cdm_id = next_cdm_id_++; DCHECK_NE(cdm_id, media::CdmContext::kInvalidCdmId); - DCHECK(!ContainsKey(proxy_media_keys_map_, cdm_id)); + DCHECK(!base::ContainsKey(proxy_media_keys_map_, cdm_id)); proxy_media_keys_map_[cdm_id] = media_keys; return cdm_id; } void RendererCdmManager::UnregisterMediaKeys(int cdm_id) { - DCHECK(ContainsKey(proxy_media_keys_map_, cdm_id)); + DCHECK(base::ContainsKey(proxy_media_keys_map_, cdm_id)); proxy_media_keys_map_.erase(cdm_id); }
diff --git a/content/renderer/media/gpu/rtc_video_decoder.cc b/content/renderer/media/gpu/rtc_video_decoder.cc index 0b18b1b..a9f02cd5 100644 --- a/content/renderer/media/gpu/rtc_video_decoder.cc +++ b/content/renderer/media/gpu/rtc_video_decoder.cc
@@ -91,10 +91,10 @@ DestroyVDA(); // Delete all shared memories. - STLDeleteElements(&available_shm_segments_); - STLDeleteValues(&bitstream_buffers_in_decoder_); - STLDeleteContainerPairFirstPointers(decode_buffers_.begin(), - decode_buffers_.end()); + base::STLDeleteElements(&available_shm_segments_); + base::STLDeleteValues(&bitstream_buffers_in_decoder_); + base::STLDeleteContainerPairFirstPointers(decode_buffers_.begin(), + decode_buffers_.end()); decode_buffers_.clear(); ClearPendingBuffers(); } @@ -812,7 +812,7 @@ } if (num_shm_buffers_ != 0) { - STLDeleteElements(&available_shm_segments_); + base::STLDeleteElements(&available_shm_segments_); num_shm_buffers_ = 0; }
diff --git a/content/renderer/media/media_interface_provider.cc b/content/renderer/media/media_interface_provider.cc index 34ea4bd..e5875308 100644 --- a/content/renderer/media/media_interface_provider.cc +++ b/content/renderer/media/media_interface_provider.cc
@@ -23,7 +23,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); } -void MediaInterfaceProvider::GetInterface(const mojo::String& interface_name, +void MediaInterfaceProvider::GetInterface(const std::string& interface_name, mojo::ScopedMessagePipeHandle pipe) { DVLOG(1) << __FUNCTION__; DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/content/renderer/media/media_interface_provider.h b/content/renderer/media/media_interface_provider.h index f375f1e..271fcf1 100644 --- a/content/renderer/media/media_interface_provider.h +++ b/content/renderer/media/media_interface_provider.h
@@ -29,7 +29,7 @@ ~MediaInterfaceProvider() final; // InterfaceProvider implementation. - void GetInterface(const mojo::String& interface_name, + void GetInterface(const std::string& interface_name, mojo::ScopedMessagePipeHandle pipe) final; private:
diff --git a/content/renderer/media/media_stream_constraints_util.cc b/content/renderer/media/media_stream_constraints_util.cc index d313f3b9..3150c94 100644 --- a/content/renderer/media/media_stream_constraints_util.cc +++ b/content/renderer/media/media_stream_constraints_util.cc
@@ -41,12 +41,20 @@ *value = the_field.max(); return true; } + if (the_field.hasExact()) { + *value = the_field.exact(); + return true; + } for (const auto& advanced_constraint : constraints.advanced()) { const auto& the_field = advanced_constraint.*picker; if (the_field.hasMax()) { *value = the_field.max(); return true; } + if (the_field.hasExact()) { + *value = the_field.exact(); + return true; + } } return false; } @@ -60,12 +68,20 @@ *value = the_field.min(); return true; } + if (the_field.hasExact()) { + *value = the_field.exact(); + return true; + } for (const auto& advanced_constraint : constraints.advanced()) { const auto& the_field = advanced_constraint.*picker; if (the_field.hasMin()) { *value = the_field.min(); return true; } + if (the_field.hasExact()) { + *value = the_field.exact(); + return true; + } } return false; }
diff --git a/content/renderer/media/media_stream_constraints_util_unittest.cc b/content/renderer/media/media_stream_constraints_util_unittest.cc index 5d71cbc..786f681d 100644 --- a/content/renderer/media/media_stream_constraints_util_unittest.cc +++ b/content/renderer/media/media_stream_constraints_util_unittest.cc
@@ -89,6 +89,14 @@ EXPECT_TRUE(GetConstraintValueAsInteger( constraints, &blink::WebMediaTrackConstraintSet::width, &value)); EXPECT_EQ(test_value, value); + + // An exact value should also be reflected as min and max. + EXPECT_TRUE(GetConstraintMaxAsInteger( + constraints, &blink::WebMediaTrackConstraintSet::width, &value)); + EXPECT_EQ(test_value, value); + EXPECT_TRUE(GetConstraintMinAsInteger( + constraints, &blink::WebMediaTrackConstraintSet::width, &value)); + EXPECT_EQ(test_value, value); } } // namespace content
diff --git a/content/renderer/media/media_stream_video_source.cc b/content/renderer/media/media_stream_video_source.cc index 856781a8..b2e550c2 100644 --- a/content/renderer/media/media_stream_video_source.cc +++ b/content/renderer/media/media_stream_video_source.cc
@@ -33,19 +33,28 @@ // Retrieve the desired max width and height from |constraints|. If not set, // the |desired_width| and |desired_height| are set to // std::numeric_limits<int>::max(); -// If either max width or height is set as a mandatory constraint, the optional -// constraints are not checked. +// If either max or exact width or height is set as a mandatory constraint, +// the advanced constraints are not checked. void GetDesiredMaxWidthAndHeight(const blink::WebMediaConstraints& constraints, int* desired_width, int* desired_height) { *desired_width = std::numeric_limits<int>::max(); *desired_height = std::numeric_limits<int>::max(); const auto& basic_constraints = constraints.basic(); - if (basic_constraints.width.hasMax() || basic_constraints.height.hasMax()) { + + if (basic_constraints.width.hasMax() || basic_constraints.height.hasMax() || + basic_constraints.width.hasExact() || + basic_constraints.height.hasExact()) { if (basic_constraints.width.hasMax()) *desired_width = basic_constraints.width.max(); if (basic_constraints.height.hasMax()) *desired_height = basic_constraints.height.max(); + // Exact constraints override max constraints if both are specified. + // Specifying both in the same structure is meaningless. + if (basic_constraints.width.hasExact()) + *desired_width = basic_constraints.width.exact(); + if (basic_constraints.height.hasExact()) + *desired_height = basic_constraints.height.exact(); return; } @@ -54,6 +63,10 @@ *desired_width = constraint_set.width.max(); if (constraint_set.height.hasMax()) *desired_height = constraint_set.height.max(); + if (constraint_set.width.hasExact()) + *desired_width = constraint_set.width.exact(); + if (constraint_set.height.hasExact()) + *desired_height = constraint_set.height.exact(); } } @@ -111,11 +124,15 @@ // max width/height just has to be > 0 (we can crop anything too large). if ((constraints.width.hasMin() && constraints.width.min() > format->frame_size.width()) || - (constraints.width.hasMax() && constraints.width.max() <= 0)) { + (constraints.width.hasMax() && constraints.width.max() <= 0) || + (constraints.width.hasExact() && + constraints.width.exact() > format->frame_size.width())) { *failing_constraint_name = constraints.width.name(); } else if ((constraints.height.hasMin() && constraints.height.min() > format->frame_size.height()) || - (constraints.height.hasMax() && constraints.height.max() <= 0)) { + (constraints.height.hasMax() && constraints.height.max() <= 0) || + (constraints.height.hasExact() && + constraints.height.exact() > format->frame_size.height())) { *failing_constraint_name = constraints.height.name(); } else if (!constraints.frameRate.matches(format->frame_rate)) { if (constraints.frameRate.hasMax()) { @@ -149,6 +166,10 @@ // Delete it otherwise. if (!UpdateFormatForConstraints(constraints, &(*format_it), failing_constraint_name)) { + DVLOG(2) << "Format filter: Discarding format " + << format_it->frame_size.width() << "x" + << format_it->frame_size.height() << "@" + << format_it->frame_rate; format_it = formats->erase(format_it); } else { ++format_it;
diff --git a/content/renderer/media/media_stream_video_source_unittest.cc b/content/renderer/media/media_stream_video_source_unittest.cc index 6439597..bfb572d 100644 --- a/content/renderer/media/media_stream_video_source_unittest.cc +++ b/content/renderer/media/media_stream_video_source_unittest.cc
@@ -314,6 +314,14 @@ CreateTrackAndStartSource(factory.CreateWebMediaConstraints(), 1280, 720, 30); } +// Test that the capture output is 720P if the camera supports it and the +// mandatory constraint is exactly width 1280. +TEST_F(MediaStreamVideoSourceTest, MandatoryExact720P) { + MockConstraintFactory factory; + factory.basic().width.setExact(1280); + CreateTrackAndStartSource(factory.CreateWebMediaConstraints(), 1280, 720, 30); +} + // Test that the capture output have aspect ratio 4:3 if a mandatory constraint // require it even if an optional constraint request a higher resolution // that don't have this aspect ratio. @@ -373,8 +381,26 @@ MockConstraintFactory factory; factory.basic().frameRate.setMin(25); factory.basic().frameRate.setMax(15); - blink::WebMediaStreamTrack track = CreateTrack( - "123", factory.CreateWebMediaConstraints()); + blink::WebMediaStreamTrack track = + CreateTrack("123", factory.CreateWebMediaConstraints()); + mock_source()->CompleteGetSupportedFormats(); + EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks()); +} + +TEST_F(MediaStreamVideoSourceTest, ExactWidthNotSupported) { + MockConstraintFactory factory; + factory.basic().width.setExact(12000); + blink::WebMediaStreamTrack track = + CreateTrack("123", factory.CreateWebMediaConstraints()); + mock_source()->CompleteGetSupportedFormats(); + EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks()); +} + +TEST_F(MediaStreamVideoSourceTest, MinWidthNotSupported) { + MockConstraintFactory factory; + factory.basic().width.setMin(12000); + blink::WebMediaStreamTrack track = + CreateTrack("123", factory.CreateWebMediaConstraints()); mock_source()->CompleteGetSupportedFormats(); EXPECT_EQ(1, NumberOfFailedConstraintsCallbacks()); }
diff --git a/content/renderer/media/rtc_peer_connection_handler.cc b/content/renderer/media/rtc_peer_connection_handler.cc index 37b9d05..972c8ca 100644 --- a/content/renderer/media/rtc_peer_connection_handler.cc +++ b/content/renderer/media/rtc_peer_connection_handler.cc
@@ -1010,7 +1010,7 @@ g_peer_connection_handlers.Get().erase(this); if (peer_connection_tracker_) peer_connection_tracker_->UnregisterPeerConnection(this); - STLDeleteValues(&remote_streams_); + base::STLDeleteValues(&remote_streams_); UMA_HISTOGRAM_COUNTS_10000( "WebRTC.NumDataChannelsPerPeerConnection", num_data_channels_created_);
diff --git a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc index 6c886e9d..93b7f2f 100644 --- a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc +++ b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
@@ -91,6 +91,11 @@ return DEFAULT; } +bool IsValidPortRange(uint16_t min_port, uint16_t max_port) { + DCHECK(min_port <= max_port); + return min_port != 0 && max_port != 0; +} + } // namespace PeerConnectionDependencyFactory::PeerConnectionDependencyFactory( @@ -297,6 +302,8 @@ // Copy the flag from Preference associated with this WebFrame. P2PPortAllocator::Config port_config; + uint16_t min_port = 0; + uint16_t max_port = 0; // |media_permission| will be called to check mic/camera permission. If at // least one of them is granted, P2PPortAllocator is allowed to gather local @@ -353,10 +360,17 @@ break; } + min_port = + renderer_view_impl->renderer_preferences().webrtc_udp_min_port; + max_port = + renderer_view_impl->renderer_preferences().webrtc_udp_max_port; + VLOG(3) << "WebRTC routing preferences: " << "policy: " << policy << ", multiple_routes: " << port_config.enable_multiple_routes - << ", nonproxied_udp: " << port_config.enable_nonproxied_udp; + << ", nonproxied_udp: " << port_config.enable_nonproxied_udp + << ", min_udp_port: " << min_port + << ", max_udp_port: " << max_port; } } if (port_config.enable_multiple_routes) { @@ -393,6 +407,8 @@ std::unique_ptr<P2PPortAllocator> port_allocator(new P2PPortAllocator( p2p_socket_dispatcher_, std::move(network_manager), socket_factory_.get(), port_config, requesting_origin)); + if (IsValidPortRange(min_port, max_port)) + port_allocator->SetPortRange(min_port, max_port); return GetPcFactory() ->CreatePeerConnection(config, std::move(port_allocator),
diff --git a/content/renderer/mus/render_widget_mus_connection.cc b/content/renderer/mus/render_widget_mus_connection.cc index ad68c210..2cf5555 100644 --- a/content/renderer/mus/render_widget_mus_connection.cc +++ b/content/renderer/mus/render_widget_mus_connection.cc
@@ -40,12 +40,12 @@ } std::unique_ptr<cc::OutputSurface> -RenderWidgetMusConnection::CreateOutputSurface() { +RenderWidgetMusConnection::CreateOutputSurface(ui::GpuService* gpu_service) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(!window_surface_binding_); std::unique_ptr<cc::OutputSurface> surface(new ui::OutputSurface( - ui::WindowSurface::Create(&window_surface_binding_))); + gpu_service, ui::WindowSurface::Create(&window_surface_binding_))); if (compositor_mus_connection_) { compositor_mus_connection_->AttachSurfaceOnMainThread( std::move(window_surface_binding_));
diff --git a/content/renderer/mus/render_widget_mus_connection.h b/content/renderer/mus/render_widget_mus_connection.h index b1e77b5..27d5f822 100644 --- a/content/renderer/mus/render_widget_mus_connection.h +++ b/content/renderer/mus/render_widget_mus_connection.h
@@ -13,6 +13,10 @@ #include "content/renderer/mus/compositor_mus_connection.h" #include "services/ui/public/cpp/window_surface.h" +namespace ui { +class GpuService; +} + namespace content { class InputHandlerManager; @@ -25,7 +29,7 @@ void Bind(mojo::InterfaceRequest<ui::mojom::WindowTreeClient> request); // Create a cc output surface. - std::unique_ptr<cc::OutputSurface> CreateOutputSurface(); + std::unique_ptr<cc::OutputSurface> CreateOutputSurface(ui::GpuService* gpu); static RenderWidgetMusConnection* Get(int routing_id);
diff --git a/content/renderer/pepper/fake_pepper_plugin_instance.cc b/content/renderer/pepper/fake_pepper_plugin_instance.cc index 0b6aff3..19a9ad0 100644 --- a/content/renderer/pepper/fake_pepper_plugin_instance.cc +++ b/content/renderer/pepper/fake_pepper_plugin_instance.cc
@@ -15,10 +15,6 @@ return nullptr; } -content::RenderView* FakePepperPluginInstance::GetRenderView() { - return nullptr; -} - blink::WebPluginContainer* FakePepperPluginInstance::GetContainer() { return nullptr; }
diff --git a/content/renderer/pepper/fake_pepper_plugin_instance.h b/content/renderer/pepper/fake_pepper_plugin_instance.h index 680139f..0fb43755 100644 --- a/content/renderer/pepper/fake_pepper_plugin_instance.h +++ b/content/renderer/pepper/fake_pepper_plugin_instance.h
@@ -18,7 +18,6 @@ // PepperPluginInstance overrides. content::RenderFrame* GetRenderFrame() override; - content::RenderView* GetRenderView() override; blink::WebPluginContainer* GetContainer() override; v8::Isolate* GetIsolate() const override; ppapi::VarTracker* GetVarTracker() override;
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc index 7706d1ba4..5607f6c 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.cc +++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -3036,10 +3036,6 @@ return render_frame_; } -RenderView* PepperPluginInstanceImpl::GetRenderView() { - return render_frame_ ? render_frame_->render_view() : NULL; -} - blink::WebPluginContainer* PepperPluginInstanceImpl::GetContainer() { return container_; }
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.h b/content/renderer/pepper/pepper_plugin_instance_impl.h index 5dee1de0..6a773a1d 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.h +++ b/content/renderer/pepper/pepper_plugin_instance_impl.h
@@ -83,7 +83,7 @@ struct WebCursorInfo; struct WebURLError; struct WebPrintParams; -} +} // namespace blink namespace cc { class TextureLayer; @@ -387,7 +387,6 @@ // PluginInstance implementation RenderFrame* GetRenderFrame() override; - RenderView* GetRenderView() override; blink::WebPluginContainer* GetContainer() override; v8::Isolate* GetIsolate() const override; ppapi::VarTracker* GetVarTracker() override;
diff --git a/content/renderer/pepper/ppb_graphics_3d_impl.cc b/content/renderer/pepper/ppb_graphics_3d_impl.cc index 927f371..01ef5f5d 100644 --- a/content/renderer/pepper/ppb_graphics_3d_impl.cc +++ b/content/renderer/pepper/ppb_graphics_3d_impl.cc
@@ -221,11 +221,11 @@ if (!plugin_instance) return false; - RenderView* render_view = plugin_instance->GetRenderView(); - if (!render_view) + RenderFrame* render_frame = plugin_instance->GetRenderFrame(); + if (!render_frame) return false; - const WebPreferences& prefs = render_view->GetWebkitPreferences(); + const WebPreferences& prefs = render_frame->GetWebkitPreferences(); // 3D access might be disabled or blacklisted. if (!prefs.pepper_3d_enabled)
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 026c472..cb9e3d3 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -44,7 +44,6 @@ #include "content/child/web_url_loader_impl.h" #include "content/child/web_url_request_util.h" #include "content/child/webmessageportchannel_impl.h" -#include "content/child/websocket_bridge.h" #include "content/child/weburlresponse_extradata_impl.h" #include "content/common/accessibility_messages.h" #include "content/common/clipboard_messages.h" @@ -133,6 +132,7 @@ #include "content/renderer/web_frame_utils.h" #include "content/renderer/web_ui_extension.h" #include "content/renderer/websharedworker_proxy.h" +#include "content/renderer/websockethandle_impl.h" #include "crypto/sha2.h" #include "gin/modules/module_registry.h" #include "media/audio/audio_output_device.h" @@ -537,16 +537,19 @@ if (is_view_source_mode_enabled) request.setCachePolicy(WebCachePolicy::ReturnCacheDataElseLoad); + request.setHTTPMethod(WebString::fromUTF8(common_params.method)); if (common_params.referrer.url.is_valid()) { WebString web_referrer = WebSecurityPolicy::generateReferrerHeader( common_params.referrer.policy, common_params.url, WebString::fromUTF8(common_params.referrer.url.spec())); - if (!web_referrer.isEmpty()) + if (!web_referrer.isEmpty()) { request.setHTTPReferrer(web_referrer, common_params.referrer.policy); + request.addHTTPOriginIfNeeded( + WebString::fromUTF8(common_params.referrer.url.GetOrigin().spec())); + } } - request.setHTTPMethod(WebString::fromUTF8(common_params.method)); request.setLoFiState( static_cast<WebURLRequest::LoFiState>(common_params.lofi_state)); @@ -747,7 +750,7 @@ crypto::SHA256HashString(params_.salt + GURL(url).spec()); // Skip if the |url| already covered by serialization of an *earlier* frame. - if (ContainsKey(params_.digests_of_uris_to_skip, digest)) + if (base::ContainsKey(params_.digests_of_uris_to_skip, digest)) return true; // Let's record |url| as being serialized for the *current* frame. @@ -831,6 +834,10 @@ } #endif // defined(ENABLE_MOJO_CDM) +double ConvertToBlinkTime(const base::TimeTicks& time_ticks) { + return (time_ticks - base::TimeTicks()).InSecondsF(); +} + } // namespace struct RenderFrameImpl::PendingFileChooser { @@ -1171,11 +1178,13 @@ effective_connection_type_ = parent_frame->getEffectiveConnectionType(); } - bool is_tracing = false; - TRACE_EVENT_CATEGORY_GROUP_ENABLED("navigation", &is_tracing); - if (is_tracing) { + bool is_tracing_rail = false; + bool is_tracing_navigation = false; + TRACE_EVENT_CATEGORY_GROUP_ENABLED("navigation", &is_tracing_navigation); + TRACE_EVENT_CATEGORY_GROUP_ENABLED("rail", &is_tracing_rail); + if (is_tracing_rail || is_tracing_navigation) { int parent_id = GetRoutingIdForFrameOrProxy(frame_->parent()); - TRACE_EVENT2("navigation", "RenderFrameImpl::Initialize", + TRACE_EVENT2("navigation,rail", "RenderFrameImpl::Initialize", "id", routing_id_, "parent", parent_id); } @@ -1225,10 +1234,6 @@ void RenderFrameImpl::PepperPluginCreated(RendererPpapiHost* host) { FOR_EACH_OBSERVER(RenderFrameObserver, observers_, DidCreatePepperPlugin(host)); - if (host->GetPluginName() == kFlashPluginName) { - RenderThread::Get()->RecordAction( - base::UserMetricsAction("FrameLoadWithFlash")); - } } void RenderFrameImpl::PepperDidChangeCursor( @@ -1576,8 +1581,8 @@ if (render_thread_impl) render_thread_impl->GetRendererScheduler()->OnNavigationStarted(); DCHECK(!IsBrowserSideNavigationEnabled()); - TRACE_EVENT2("navigation", "RenderFrameImpl::OnNavigate", "id", routing_id_, - "url", common_params.url.possibly_invalid_spec()); + TRACE_EVENT2("navigation,rail", "RenderFrameImpl::OnNavigate", "id", + routing_id_, "url", common_params.url.possibly_invalid_spec()); NavigateInternal(common_params, start_params, request_params, std::unique_ptr<StreamOverrideParameters>()); } @@ -1600,7 +1605,7 @@ } void RenderFrameImpl::OnBeforeUnload(bool is_reload) { - TRACE_EVENT1("navigation", "RenderFrameImpl::OnBeforeUnload", + TRACE_EVENT1("navigation,rail", "RenderFrameImpl::OnBeforeUnload", "id", routing_id_); // TODO(creis): Right now, this is only called on the main frame. Make the // browser process send dispatchBeforeUnloadEvent to every frame that needs @@ -1618,7 +1623,8 @@ int proxy_routing_id, bool is_loading, const FrameReplicationState& replicated_frame_state) { - TRACE_EVENT1("navigation", "RenderFrameImpl::OnSwapOut", "id", routing_id_); + TRACE_EVENT1("navigation,rail", "RenderFrameImpl::OnSwapOut", + "id", routing_id_); RenderFrameProxy* proxy = NULL; // This codepath should only be hit for subframes when in --site-per-process. @@ -2425,6 +2431,14 @@ const url::Origin& content_origin) { return plugin_power_saver_helper_->WhitelistContentOrigin(content_origin); } + +void RenderFrameImpl::DidStartLoading() { + didStartLoading(true); +} + +void RenderFrameImpl::DidStopLoading() { + didStopLoading(); +} #endif // defined(ENABLE_PLUGINS) bool RenderFrameImpl::IsFTPDirectoryListing() { @@ -2782,7 +2796,7 @@ // Tracing analysis uses this to find main frames when this value is // MSG_ROUTING_NONE, and build the frame tree otherwise. - TRACE_EVENT2("navigation", "RenderFrameImpl::createChildFrame", + TRACE_EVENT2("navigation,rail", "RenderFrameImpl::createChildFrame", "id", routing_id_, "child", child_routing_id); @@ -3135,12 +3149,29 @@ document_state->navigation_state()); // Set the navigation start time in blink. - base::TimeTicks navigation_start = - navigation_state->common_params().navigation_start; datasource->setNavigationStartTime( - (navigation_start - base::TimeTicks()).InSecondsF()); - // TODO(clamy) We need to provide additional timing values for the Navigation - // Timing API to work with browser-side navigations. + ConvertToBlinkTime(navigation_state->common_params().navigation_start)); + + if (IsBrowserSideNavigationEnabled()) { + // Set timing of several events that happened during navigation. + // They will be used in blink for the Navigation Timing API. + double redirect_start = ConvertToBlinkTime( + navigation_state->request_params().navigation_timing.redirect_start); + double redirect_end = ConvertToBlinkTime( + navigation_state->request_params().navigation_timing.redirect_end); + double fetch_start = ConvertToBlinkTime( + navigation_state->request_params().navigation_timing.fetch_start); + std::vector<GURL> redirectChain = + navigation_state->request_params().redirects; + redirectChain.push_back(navigation_state->common_params().url); + + datasource->updateNavigationTimings(redirect_start, redirect_end, + fetch_start, redirectChain); + + // TODO(clamy) We need to provide additional timing values for the + // Navigation Timing API to work with browser-side navigations. + // UnloadEventStart and UnloadEventEnd are still missing. + } // Create the serviceworker's per-document network observing object if it // does not exist (When navigation happens within a page, the provider already @@ -3165,7 +3196,7 @@ if (!ds) return; - TRACE_EVENT2("navigation,benchmark", + TRACE_EVENT2("navigation,benchmark,rail", "RenderFrameImpl::didStartProvisionalLoad", "id", routing_id_, "url", ds->request().url().string().utf8()); DocumentState* document_state = DocumentState::FromDataSource(ds); @@ -3220,7 +3251,7 @@ blink::WebLocalFrame* frame, const blink::WebURLError& error, blink::WebHistoryCommitType commit_type) { - TRACE_EVENT1("navigation,benchmark", + TRACE_EVENT1("navigation,benchmark,rail", "RenderFrameImpl::didFailProvisionalLoad", "id", routing_id_); DCHECK_EQ(frame_, frame); WebDataSource* ds = frame->provisionalDataSource(); @@ -3275,7 +3306,7 @@ blink::WebLocalFrame* frame, const blink::WebHistoryItem& item, blink::WebHistoryCommitType commit_type) { - TRACE_EVENT2("navigation", "RenderFrameImpl::didCommitProvisionalLoad", + TRACE_EVENT2("navigation,rail", "RenderFrameImpl::didCommitProvisionalLoad", "id", routing_id_, "url", GetLoadingUrl().possibly_invalid_spec()); DCHECK_EQ(frame_, frame); @@ -3555,8 +3586,8 @@ } void RenderFrameImpl::didFinishDocumentLoad(blink::WebLocalFrame* frame) { - TRACE_EVENT1("navigation,benchmark", "RenderFrameImpl::didFinishDocumentLoad", - "id", routing_id_); + TRACE_EVENT1("navigation,benchmark,rail", + "RenderFrameImpl::didFinishDocumentLoad", "id", routing_id_); DCHECK_EQ(frame_, frame); WebDataSource* ds = frame->dataSource(); DocumentState* document_state = DocumentState::FromDataSource(ds); @@ -3642,7 +3673,7 @@ void RenderFrameImpl::didFailLoad(blink::WebLocalFrame* frame, const blink::WebURLError& error, blink::WebHistoryCommitType commit_type) { - TRACE_EVENT1("navigation", "RenderFrameImpl::didFailLoad", + TRACE_EVENT1("navigation,rail", "RenderFrameImpl::didFailLoad", "id", routing_id_); DCHECK_EQ(frame_, frame); // TODO(nasko): Move implementation here. No state needed. @@ -3668,14 +3699,14 @@ } void RenderFrameImpl::didFinishLoad(blink::WebLocalFrame* frame) { - TRACE_EVENT1("navigation,benchmark", "RenderFrameImpl::didFinishLoad", "id", - routing_id_); + TRACE_EVENT1("navigation,benchmark,rail", + "RenderFrameImpl::didFinishLoad", "id", routing_id_); DCHECK_EQ(frame_, frame); WebDataSource* ds = frame->dataSource(); DocumentState* document_state = DocumentState::FromDataSource(ds); if (document_state->finish_load_time().is_null()) { if (!frame->parent()) { - TRACE_EVENT_INSTANT0("WebCore,benchmark", "LoadFinished", + TRACE_EVENT_INSTANT0("WebCore,benchmark,rail", "LoadFinished", TRACE_EVENT_SCOPE_PROCESS); } document_state->set_finish_load_time(Time::Now()); @@ -3694,7 +3725,7 @@ const blink::WebHistoryItem& item, blink::WebHistoryCommitType commit_type, bool content_initiated) { - TRACE_EVENT1("navigation", "RenderFrameImpl::didNavigateWithinPage", + TRACE_EVENT1("navigation,rail", "RenderFrameImpl::didNavigateWithinPage", "id", routing_id_); DCHECK_EQ(frame_, frame); DocumentState* document_state = @@ -4155,8 +4186,8 @@ // Let the browser know we loaded a resource from the memory cache. This // message is needed to display the correct SSL indicators. Send(new FrameHostMsg_DidLoadResourceFromMemoryCache( - routing_id_, url, response.securityInfo(), request.httpMethod().utf8(), - response.mimeType().utf8(), WebURLRequestToResourceType(request))); + routing_id_, url, request.httpMethod().utf8(), response.mimeType().utf8(), + WebURLRequestToResourceType(request))); } void RenderFrameImpl::didDisplayInsecureContent() { @@ -4269,11 +4300,6 @@ QuotaDispatcher::CreateWebStorageQuotaCallbacksWrapper(callbacks)); } -void RenderFrameImpl::willOpenWebSocket(blink::WebSocketHandle* handle) { - WebSocketBridge* impl = static_cast<WebSocketBridge*>(handle); - impl->set_render_frame_id(routing_id_); -} - blink::WebPresentationClient* RenderFrameImpl::presentationClient() { if (!presentation_dispatcher_) presentation_dispatcher_ = new PresentationDispatcher(this); @@ -4286,6 +4312,15 @@ return push_messaging_dispatcher_; } +void RenderFrameImpl::willOpenWebSocket(blink::WebSocketHandle* handle) { + // Initialize the WebSocketHandle with our InterfaceProvider to provide the + // WebSocket implementation with context about this frame. This is important + // so that the browser can show UI associated with the WebSocket (e.g., for + // certificate errors). + static_cast<WebSocketHandleImpl*>(handle)->Initialize( + blink_interface_provider_.get()); +} + void RenderFrameImpl::willStartUsingPeerConnectionHandler( blink::WebRTCPeerConnectionHandler* handler) { #if defined(ENABLE_WEBRTC) @@ -4753,7 +4788,7 @@ } void RenderFrameImpl::didStartLoading(bool to_different_document) { - TRACE_EVENT1("navigation", "RenderFrameImpl::didStartLoading", + TRACE_EVENT1("navigation,rail", "RenderFrameImpl::didStartLoading", "id", routing_id_); render_view_->FrameDidStartLoading(frame_); @@ -4764,7 +4799,7 @@ } void RenderFrameImpl::didStopLoading() { - TRACE_EVENT1("navigation", "RenderFrameImpl::didStopLoading", + TRACE_EVENT1("navigation,rail", "RenderFrameImpl::didStopLoading", "id", routing_id_); render_view_->FrameDidStopLoading(frame_); Send(new FrameHostMsg_DidStopLoading(routing_id_)); @@ -5161,7 +5196,7 @@ if (!plugin->startFind(search_text, options.matchCase, request_id)) { // Send "no results". SendFindReply(request_id, 0 /* match_count */, 0 /* ordinal */, - gfx::Rect(), true /* final_status_update */ ); + gfx::Rect(), true /* final_status_update */); } } return; @@ -5493,6 +5528,16 @@ : blink::WebFrameLoadType::BackForward; should_load_request = true; + // If this is marked as a same document load but we haven't committed + // anything, treat it as a new load. The browser shouldn't let this + // happen. + // TODO(creis): Add a similar check if the DSN doesn't match, and add a + // NOTREACHED when we're confident this won't happen. + if (history_load_type == blink::WebHistorySameDocumentLoad && + current_history_item_.isNull()) { + history_load_type = blink::WebHistoryDifferentDocumentLoad; + } + // If this navigation is to a history item for a new child frame, we may // want to ignore it in some cases. If a Javascript navigation (i.e., // client redirect) interrupted it and has either been scheduled,
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index c04183e..a2b0c2e 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -91,7 +91,7 @@ struct WebCursorInfo; struct WebFindOptions; struct WebScreenInfo; -} +} // namespace blink namespace gfx { class Point; @@ -417,6 +417,8 @@ const gfx::Size& unobscured_size, RecordPeripheralDecision record_decision) const override; void WhitelistContentOrigin(const url::Origin& content_origin) override; + void DidStartLoading() override; + void DidStopLoading() override; #endif bool IsFTPDirectoryListing() override; void AttachGuest(int element_instance_id) override; @@ -601,9 +603,9 @@ void requestStorageQuota(blink::WebStorageQuotaType type, unsigned long long requested_size, blink::WebStorageQuotaCallbacks callbacks) override; - void willOpenWebSocket(blink::WebSocketHandle* handle) override; blink::WebPushClient* pushClient() override; blink::WebPresentationClient* presentationClient() override; + void willOpenWebSocket(blink::WebSocketHandle* handle) override; void willStartUsingPeerConnectionHandler( blink::WebRTCPeerConnectionHandler* handler) override; blink::WebUserMediaClient* userMediaClient() override;
diff --git a/content/renderer/render_process_impl.cc b/content/renderer/render_process_impl.cc index 6463fb9..57713f5 100644 --- a/content/renderer/render_process_impl.cc +++ b/content/renderer/render_process_impl.cc
@@ -86,6 +86,7 @@ SetV8FlagIfHasSwitch(switches::kDisableJavaScriptHarmonyShipping, "--noharmony-shipping"); SetV8FlagIfHasSwitch(switches::kJavaScriptHarmony, "--harmony"); + SetV8FlagIfHasSwitch(switches::kEnableAsmWasm, "--validate-asm"); SetV8FlagIfHasSwitch(switches::kEnableWasm, "--expose-wasm"); const base::CommandLine& command_line =
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index f28d2c4a..fecc962 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -65,7 +65,6 @@ #include "content/child/runtime_features.h" #include "content/child/thread_safe_sender.h" #include "content/child/web_database_observer_impl.h" -#include "content/child/websocket_message_filter.h" #include "content/child/worker_thread_registry.h" #include "content/common/child_process_messages.h" #include "content/common/content_constants_internal.h" @@ -203,7 +202,7 @@ #include "content/public/common/mojo_shell_connection.h" #include "content/renderer/mus/render_widget_mus_connection.h" #include "content/renderer/mus/render_widget_window_tree_client_factory.h" -#include "services/ui/common/gpu_service.h" +#include "services/ui/public/cpp/gpu_service.h" #endif #if defined(ENABLE_IPC_FUZZER) @@ -644,9 +643,10 @@ ChildProcess::current()->set_main_thread(this); #if defined(USE_AURA) - if (IsRunningInMash()) + if (IsRunningInMash()) { gpu_service_ = ui::GpuService::Initialize(GetMojoShellConnection()->GetConnector()); + } #endif InitializeWebKit(resource_task_queue); @@ -1221,9 +1221,6 @@ resource_task_queue2); resource_dispatcher()->SetMainThreadTaskRunner(resource_task_queue2); - websocket_message_filter()->SetLoadingTaskRunner( - renderer_scheduler_->LoadingTaskRunner()); - if (!command_line.HasSwitch(switches::kDisableThreadedCompositing) && !command_line.HasSwitch(switches::kUseRemoteCompositing)) InitializeCompositorThread(); @@ -1829,7 +1826,7 @@ command_line.HasSwitch(switches::kUseMusInRenderer)) { RenderWidgetMusConnection* connection = RenderWidgetMusConnection::GetOrCreate(routing_id); - return connection->CreateOutputSurface(); + return connection->CreateOutputSurface(gpu_service_.get()); } #endif
diff --git a/content/renderer/render_thread_impl_browsertest.cc b/content/renderer/render_thread_impl_browsertest.cc index b5a0fb8..b336278 100644 --- a/content/renderer/render_thread_impl_browsertest.cc +++ b/content/renderer/render_thread_impl_browsertest.cc
@@ -20,7 +20,6 @@ #include "content/app/mojo/mojo_init.h" #include "content/common/in_process_child_thread_params.h" #include "content/common/resource_messages.h" -#include "content/common/websocket_messages.h" #include "content/public/browser/content_browser_client.h" #include "content/public/common/content_client.h" #include "content/public/common/content_switches.h" @@ -232,7 +231,6 @@ WILL_LEAK(NonResourceDispatchIPCTasksDontGoThroughScheduler)) { // NOTE other than not being a resource message, the actual message is // unimportant. - test_helper_->Sender()->Send(new WebSocketMsg_NotifyFailure(1, "")); test_helper_->Sender()->Send(new TestMsg_QuitRunLoop()); base::RunLoop().Run();
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 81b2c975..2320800 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -54,6 +54,7 @@ #include "content/common/site_isolation_policy.h" #include "content/common/view_messages.h" #include "content/public/common/bindings_policy.h" +#include "content/public/common/browser_side_navigation_policy.h" #include "content/public/common/content_client.h" #include "content/public/common/content_constants.h" #include "content/public/common/content_switches.h" @@ -630,6 +631,36 @@ } } +// This class represents promise which is robust to (will not be broken by) +// |DidNotSwapReason::SWAP_FAILS| events. +class AlwaysDrawSwapPromise : public cc::SwapPromise { + public: + explicit AlwaysDrawSwapPromise(const ui::LatencyInfo& latency_info) + : latency_info_(latency_info) {} + + ~AlwaysDrawSwapPromise() override = default; + + void DidActivate() override {} + + void DidSwap(cc::CompositorFrameMetadata* metadata) override { + DCHECK(!latency_info_.terminated()); + metadata->latency_info.push_back(latency_info_); + } + + DidNotSwapAction DidNotSwap(DidNotSwapReason reason) override { + return reason == DidNotSwapReason::SWAP_FAILS + ? DidNotSwapAction::KEEP_ACTIVE + : DidNotSwapAction::BREAK_PROMISE; + } + + void OnCommit() override {} + + int64_t TraceId() const override { return latency_info_.trace_id(); } + + private: + ui::LatencyInfo latency_info_; +}; + } // namespace RenderViewImpl::RenderViewImpl(CompositorDependencies* compositor_deps, @@ -726,6 +757,9 @@ if (switches::IsTouchDragDropEnabled()) webview()->settings()->setTouchDragDropEnabled(true); + webview()->settings()->setBrowserSideNavigationEnabled( + IsBrowserSideNavigationEnabled()); + WebSettings::SelectionStrategyType selection_strategy = WebSettings::SelectionStrategyType::Character; const std::string selection_strategy_str = @@ -1033,8 +1067,8 @@ settings->setDeviceSupportsMouse(prefs.device_supports_mouse); settings->setEnableTouchAdjustment(prefs.touch_adjustment_enabled); - WebRuntimeFeatures::enableImageColorProfiles( - prefs.image_color_profiles_enabled); + WebRuntimeFeatures::enableColorCorrectRendering( + prefs.color_correct_rendering_enabled); settings->setShouldRespectImageOrientation( prefs.should_respect_image_orientation); @@ -1328,6 +1362,7 @@ IPC_MESSAGE_HANDLER(PageMsg_UpdateWindowScreenRect, OnUpdateWindowScreenRect) IPC_MESSAGE_HANDLER(PageMsg_SetZoomLevel, OnSetZoomLevel) + IPC_MESSAGE_HANDLER(PageMsg_SetDeviceScaleFactor, OnSetDeviceScaleFactor); IPC_MESSAGE_HANDLER(PageMsg_WasHidden, OnPageWasHidden) IPC_MESSAGE_HANDLER(PageMsg_WasShown, OnPageWasShown) @@ -1461,17 +1496,10 @@ ApplyWebPreferences(prefs, web_view); } -void RenderViewImpl::OnForceRedraw(int id) { - ui::LatencyInfo latency_info; - if (id) { - latency_info.AddLatencyNumber(ui::WINDOW_SNAPSHOT_FRAME_NUMBER_COMPONENT, - 0, - id); - } - std::unique_ptr<cc::SwapPromiseMonitor> latency_info_swap_promise_monitor; +void RenderViewImpl::OnForceRedraw(const ui::LatencyInfo& latency_info) { if (RenderWidgetCompositor* rwc = compositor()) { - latency_info_swap_promise_monitor = - rwc->CreateLatencyInfoSwapPromiseMonitor(&latency_info); + rwc->QueueSwapPromise( + base::MakeUnique<AlwaysDrawSwapPromise>(latency_info)); } ScheduleCompositeWithForcedRedraw(); } @@ -2212,14 +2240,6 @@ return send_content_state_immediately_; } -void RenderViewImpl::DidStartLoading() { - main_render_frame_->didStartLoading(true); -} - -void RenderViewImpl::DidStopLoading() { - main_render_frame_->didStopLoading(); -} - void RenderViewImpl::OnSetPageScale(float page_scale_factor) { if (!webview()) return; @@ -2307,7 +2327,6 @@ !(enabled_bindings_ & BINDINGS_POLICY_WEB_UI)) { // WebUIExtensionData deletes itself when we're destroyed. new WebUIExtensionData(this); - } enabled_bindings_ |= enabled_bindings_flags; @@ -2700,14 +2719,8 @@ void RenderViewImpl::RenderWidgetDidSetColorProfile( const std::vector<char>& profile) { if (webview()) { - bool was_reset = (profile.size() == 1 && profile[0] == '0'); - - if (was_reset) { - webview()->resetDeviceColorProfileForTesting(); - } else { - WebVector<char> colorProfile = profile; - webview()->setDeviceColorProfile(colorProfile); - } + WebVector<char> colorProfile = profile; + webview()->setDeviceColorProfile(colorProfile); } }
diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index 67d9a5c7..b596d59 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h
@@ -413,8 +413,6 @@ bool ShouldDisplayScrollbars(int width, int height) const override; int GetEnabledBindings() const override; bool GetContentStateImmediately() const override; - void DidStartLoading() override; - void DidStopLoading() override; void Repaint(const gfx::Size& size) override; void SetEditCommandForNextKeyEvent(const std::string& name, const std::string& value) override; @@ -634,7 +632,7 @@ void OnUpdateWebPreferences(const WebPreferences& prefs); void OnSetPageScale(float page_scale_factor); void OnZoom(PageZoom zoom); - void OnForceRedraw(int request_id); + void OnForceRedraw(const ui::LatencyInfo& latency_info); void OnSelectWordAroundCaret(); #if defined(OS_ANDROID) void OnUndoScrollFocusedEditableNodeIntoRect();
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 61cf0e2..c9e985f 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -1004,7 +1004,12 @@ screen_info_.orientationType != params.screen_info.orientationType; screen_info_ = params.screen_info; - SetDeviceScaleFactor(screen_info_.deviceScaleFactor); + + if (device_scale_factor_ != screen_info_.deviceScaleFactor) { + device_scale_factor_ = screen_info_.deviceScaleFactor; + OnDeviceScaleFactorChanged(); + ScheduleComposite(); + } if (resizing_mode_selector_->NeverUsesSynchronousResize()) { // A resize ack shouldn't be requested if we have not ACK'd the previous @@ -1591,15 +1596,16 @@ #endif } -void RenderWidget::SetDeviceScaleFactor(float device_scale_factor) { +void RenderWidget::OnSetDeviceScaleFactor(float device_scale_factor) { if (device_scale_factor_ == device_scale_factor) return; device_scale_factor_ = device_scale_factor; OnDeviceScaleFactorChanged(); - ScheduleComposite(); + + physical_backing_size_ = gfx::ScaleToCeiledSize(size_, device_scale_factor_); } bool RenderWidget::SetDeviceColorProfile( @@ -1767,12 +1773,6 @@ SetDeviceColorProfile(color_profile); } -void RenderWidget::ResetDeviceColorProfileForTesting() { - std::vector<char> color_profile; - color_profile.push_back('0'); - SetDeviceColorProfile(color_profile); -} - void RenderWidget::DidAutoResize(const gfx::Size& new_size) { WebRect new_size_in_window(0, 0, new_size.width(), new_size.height()); convertViewportToWindow(&new_size_in_window);
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 449d377c4..e41360a 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -357,7 +357,6 @@ // Change the device ICC color profile while running a layout test. void SetDeviceColorProfileForTesting(const std::vector<char>& color_profile); - void ResetDeviceColorProfileForTesting(); // Called when the Widget has changed size as a result of an auto-resize. void DidAutoResize(const gfx::Size& new_size); @@ -504,7 +503,7 @@ // go through OnResize. void AutoResizeCompositor(); - virtual void SetDeviceScaleFactor(float device_scale_factor); + virtual void OnSetDeviceScaleFactor(float device_scale_factor); bool SetDeviceColorProfile(const std::vector<char>& color_profile); virtual void OnOrientationChange();
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index 9b13722..0cdfd84b 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -70,6 +70,7 @@ #include "content/renderer/webclipboard_impl.h" #include "content/renderer/webgraphicscontext3d_provider_impl.h" #include "content/renderer/webpublicsuffixlist_impl.h" +#include "content/renderer/websockethandle_impl.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/config/gpu_info.h" #include "gpu/ipc/client/gpu_channel_host.h" @@ -306,11 +307,14 @@ //------------------------------------------------------------------------------ blink::WebURLLoader* RendererBlinkPlatformImpl::createURLLoader() { + if (!url_loader_factory_) + interfaceProvider()->getInterface(mojo::GetProxy(&url_loader_factory_)); ChildThreadImpl* child_thread = ChildThreadImpl::current(); // There may be no child thread in RenderViewTests. These tests can still use // data URLs to bypass the ResourceDispatcher. return new content::WebURLLoaderImpl( - child_thread ? child_thread->resource_dispatcher() : NULL); + child_thread ? child_thread->resource_dispatcher() : NULL, + url_loader_factory_.get()); } blink::WebThread* RendererBlinkPlatformImpl::currentThread() { @@ -394,6 +398,10 @@ default_task_runner_, channel1, channel2); } +blink::WebSocketHandle* RendererBlinkPlatformImpl::createWebSocketHandle() { + return new WebSocketHandleImpl(loading_task_runner_); +} + blink::WebPrescientNetworking* RendererBlinkPlatformImpl::prescientNetworking() { return GetContentClient()->renderer()->GetPrescientNetworking();
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h index abcb969..6775e77 100644 --- a/content/renderer/renderer_blink_platform_impl.h +++ b/content/renderer/renderer_blink_platform_impl.h
@@ -17,6 +17,7 @@ #include "cc/blink/web_compositor_support_impl.h" #include "content/child/blink_platform_impl.h" #include "content/common/content_export.h" +#include "content/common/url_loader_factory.mojom.h" #include "content/renderer/origin_trials/web_trial_token_validator_impl.h" #include "content/renderer/top_level_blame_context.h" #include "content/renderer/webpublicsuffixlist_impl.h" @@ -91,6 +92,7 @@ bool isLinkVisited(unsigned long long linkHash) override; void createMessageChannel(blink::WebMessagePortChannel** channel1, blink::WebMessagePortChannel** channel2) override; + blink::WebSocketHandle* createWebSocketHandle() override; blink::WebPrescientNetworking* prescientNetworking() override; void cacheMetadata(const blink::WebURL&, int64_t, @@ -304,6 +306,8 @@ std::unique_ptr<BlinkInterfaceProviderImpl> blink_interface_provider_; + mojom::URLLoaderFactoryPtr url_loader_factory_; + DISALLOW_COPY_AND_ASSIGN(RendererBlinkPlatformImpl); };
diff --git a/content/renderer/websockethandle_impl.cc b/content/renderer/websockethandle_impl.cc new file mode 100644 index 0000000..652f698 --- /dev/null +++ b/content/renderer/websockethandle_impl.cc
@@ -0,0 +1,302 @@ +// 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 "content/renderer/websockethandle_impl.h" + +#include <stdint.h> +#include <string.h> + +#include <string> +#include <utility> + +#include "base/logging.h" +#include "base/strings/string_util.h" +#include "third_party/WebKit/public/platform/InterfaceProvider.h" +#include "third_party/WebKit/public/platform/Platform.h" +#include "third_party/WebKit/public/platform/WebSecurityOrigin.h" +#include "third_party/WebKit/public/platform/WebString.h" +#include "third_party/WebKit/public/platform/WebURL.h" +#include "third_party/WebKit/public/platform/WebVector.h" +#include "third_party/WebKit/public/platform/modules/websockets/WebSocketHandle.h" +#include "third_party/WebKit/public/platform/modules/websockets/WebSocketHandleClient.h" +#include "third_party/WebKit/public/platform/modules/websockets/WebSocketHandshakeRequestInfo.h" +#include "third_party/WebKit/public/platform/modules/websockets/WebSocketHandshakeResponseInfo.h" +#include "url/gurl.h" +#include "url/origin.h" + +using blink::WebSecurityOrigin; +using blink::WebSocketHandle; +using blink::WebSocketHandleClient; +using blink::WebString; +using blink::WebURL; +using blink::WebVector; + +namespace content { +namespace { + +const uint16_t kAbnormalShutdownOpCode = 1006; + +} // namespace + +WebSocketHandleImpl::WebSocketHandleImpl( + scoped_refptr<base::SingleThreadTaskRunner> task_runner) + : client_(nullptr), + client_binding_(this), + task_runner_(std::move(task_runner)), + did_initialize_(false) { + DVLOG(1) << "WebSocketHandleImpl @" << reinterpret_cast<void*>(this) + << " created"; +} + +void WebSocketHandleImpl::Initialize( + blink::InterfaceProvider* interface_provider) { + DCHECK(!websocket_); + DCHECK(!did_initialize_); + + interface_provider->getInterface(mojo::GetProxy(&websocket_)); + + websocket_.set_connection_error_handler( + base::Bind(&WebSocketHandleImpl::OnConnectionError, + base::Unretained(this))); + did_initialize_ = true; +} + +void WebSocketHandleImpl::connect(const WebURL& url, + const WebVector<WebString>& protocols, + const WebSecurityOrigin& origin, + const WebURL& first_party_for_cookies, + const WebString& user_agent_override, + WebSocketHandleClient* client) { + DVLOG(1) << "WebSocketHandleImpl @" << reinterpret_cast<void*>(this) + << " Connect(" << url.string().utf8() << ", " + << origin.toString().utf8() << ")"; + + // It is insufficient to test if websocket_ is non-null as Disconnect() sets + // websocket_ to null. + if (!did_initialize_) + Initialize(blink::Platform::current()->interfaceProvider()); + + DCHECK(websocket_); + + DCHECK(!client_); + DCHECK(client); + client_ = client; + + mojo::Array<mojo::String> protocols_to_pass(protocols.size()); + for (size_t i = 0; i < protocols.size(); ++i) + protocols_to_pass[i] = protocols[i].utf8(); + + websocket_->AddChannelRequest( + url, + std::move(protocols_to_pass), + origin, + first_party_for_cookies, + user_agent_override.latin1(), + client_binding_.CreateInterfacePtrAndBind(task_runner_)); +} + +void WebSocketHandleImpl::send(bool fin, + WebSocketHandle::MessageType type, + const char* data, + size_t size) { + DCHECK(websocket_); + + mojom::WebSocketMessageType type_to_pass; + switch (type) { + case WebSocketHandle::MessageTypeContinuation: + type_to_pass = mojom::WebSocketMessageType::CONTINUATION; + break; + case WebSocketHandle::MessageTypeText: + type_to_pass = mojom::WebSocketMessageType::TEXT; + break; + case WebSocketHandle::MessageTypeBinary: + type_to_pass = mojom::WebSocketMessageType::BINARY; + break; + default: + NOTREACHED(); + return; + } + + DVLOG(1) << "WebSocketHandleImpl @" << reinterpret_cast<void*>(this) + << " Send(" << fin << ", " << type_to_pass << ", " + << "(data size = " << size << "))"; + + mojo::Array<uint8_t> data_to_pass(size); + std::copy(data, data + size, data_to_pass.begin()); + + websocket_->SendFrame(fin, type_to_pass, std::move(data_to_pass)); +} + +void WebSocketHandleImpl::flowControl(int64_t quota) { + DCHECK(websocket_); + + DVLOG(1) << "WebSocketHandleImpl @" << reinterpret_cast<void*>(this) + << " FlowControl(" << quota << ")"; + + websocket_->SendFlowControl(quota); +} + +void WebSocketHandleImpl::close(unsigned short code, const WebString& reason) { + DCHECK(websocket_); + + std::string reason_to_pass = reason.utf8(); + + DVLOG(1) << "WebSocketHandleImpl @" << reinterpret_cast<void*>(this) + << " Close(" << code << ", " << reason_to_pass << ")"; + + websocket_->StartClosingHandshake(code, reason_to_pass); +} + +WebSocketHandleImpl::~WebSocketHandleImpl() { + DVLOG(1) << "WebSocketHandleImpl @" << reinterpret_cast<void*>(this) + << " deleted"; + + if (websocket_) + websocket_->StartClosingHandshake(kAbnormalShutdownOpCode, std::string()); +} + +void WebSocketHandleImpl::Disconnect() { + websocket_.reset(); + client_ = nullptr; +} + +void WebSocketHandleImpl::OnConnectionError() { + // Our connection to the WebSocket was dropped. This could be due to + // exceeding the maximum number of concurrent websockets from this process. + + // TODO(darin): This error message is overly specific. We don't know for sure + // that this is the only reason we'd get here. This should be more generic or + // we should figure out how to make it more specific. + OnFailChannel("Error in connection establishment: " + "net::ERR_INSUFFICIENT_RESOURCES"); +} + +void WebSocketHandleImpl::OnFailChannel(const mojo::String& message) { + DVLOG(1) << "WebSocketHandleImpl @" << reinterpret_cast<void*>(this) + << " OnFailChannel(" << message << ")"; + + WebSocketHandleClient* client = client_; + Disconnect(); + if (!client) + return; + + client->didFail(this, WebString::fromUTF8(message)); + // |this| can be deleted here. +} + +void WebSocketHandleImpl::OnStartOpeningHandshake( + mojom::WebSocketHandshakeRequestPtr request) { + DVLOG(1) << "WebSocketHandleImpl @" << reinterpret_cast<void*>(this) + << " OnStartOpeningHandshake(" << request->url << ")"; + // All strings are already encoded to ASCII in the browser. + blink::WebSocketHandshakeRequestInfo request_to_pass; + request_to_pass.setURL(WebURL(request->url)); + for (size_t i = 0; i < request->headers.size(); ++i) { + const mojom::HttpHeaderPtr& header = request->headers[i]; + request_to_pass.addHeaderField(WebString::fromLatin1(header->name), + WebString::fromLatin1(header->value)); + } + request_to_pass.setHeadersText(WebString::fromLatin1(request->headers_text)); + client_->didStartOpeningHandshake(this, request_to_pass); +} + +void WebSocketHandleImpl::OnFinishOpeningHandshake( + mojom::WebSocketHandshakeResponsePtr response) { + DVLOG(1) << "WebSocketHandleImpl @" << reinterpret_cast<void*>(this) + << " OnFinishOpeningHandshake(" << response->url << ")"; + + // All strings are already encoded to ASCII in the browser. + blink::WebSocketHandshakeResponseInfo response_to_pass; + response_to_pass.setStatusCode(response->status_code); + response_to_pass.setStatusText(WebString::fromLatin1(response->status_text)); + for (size_t i = 0; i < response->headers.size(); ++i) { + const mojom::HttpHeaderPtr& header = response->headers[i]; + response_to_pass.addHeaderField(WebString::fromLatin1(header->name), + WebString::fromLatin1(header->value)); + } + response_to_pass.setHeadersText( + WebString::fromLatin1(response->headers_text)); + client_->didFinishOpeningHandshake(this, response_to_pass); +} + +void WebSocketHandleImpl::OnAddChannelResponse( + const mojo::String& protocol, + const mojo::String& extensions) { + DVLOG(1) << "WebSocketHandleImpl @" << reinterpret_cast<void*>(this) + << " OnAddChannelResponse(" + << protocol << ", " << extensions << ")"; + + if (!client_) + return; + + client_->didConnect(this, + WebString::fromUTF8(protocol), + WebString::fromUTF8(extensions)); + // |this| can be deleted here. +} + +void WebSocketHandleImpl::OnDataFrame( + bool fin, mojom::WebSocketMessageType type, + mojo::Array<uint8_t> data) { + DVLOG(1) << "WebSocketHandleImpl @" << reinterpret_cast<void*>(this) + << " OnDataFrame(" << fin << ", " << type << ", " + << "(data size = " << data.size() << "))"; + if (!client_) + return; + + WebSocketHandle::MessageType type_to_pass = + WebSocketHandle::MessageTypeContinuation; + switch (type) { + case mojom::WebSocketMessageType::CONTINUATION: + type_to_pass = WebSocketHandle::MessageTypeContinuation; + break; + case mojom::WebSocketMessageType::TEXT: + type_to_pass = WebSocketHandle::MessageTypeText; + break; + case mojom::WebSocketMessageType::BINARY: + type_to_pass = WebSocketHandle::MessageTypeBinary; + break; + } + const char* data_to_pass = + reinterpret_cast<const char*>(data.empty() ? nullptr : &data[0]); + client_->didReceiveData(this, fin, type_to_pass, data_to_pass, data.size()); + // |this| can be deleted here. +} + +void WebSocketHandleImpl::OnFlowControl(int64_t quota) { + DVLOG(1) << "WebSocketHandleImpl @" << reinterpret_cast<void*>(this) + << " OnFlowControl(" << quota << ")"; + if (!client_) + return; + + client_->didReceiveFlowControl(this, quota); + // |this| can be deleted here. +} + +void WebSocketHandleImpl::OnDropChannel(bool was_clean, uint16_t code, + const mojo::String& reason) { + DVLOG(1) << "WebSocketHandleImpl @" << reinterpret_cast<void*>(this) + << " OnDropChannel(" << was_clean << ", " << code << ", " + << reason << ")"; + + WebSocketHandleClient* client = client_; + Disconnect(); + if (!client) + return; + + client->didClose(this, was_clean, code, WebString::fromUTF8(reason)); + // |this| can be deleted here. +} + +void WebSocketHandleImpl::OnClosingHandshake() { + DVLOG(1) << "WebSocketHandleImpl @" << reinterpret_cast<void*>(this) + << " OnClosingHandshake()"; + if (!client_) + return; + + client_->didStartClosingHandshake(this); + // |this| can be deleted here. +} + +} // namespace content
diff --git a/content/renderer/websockethandle_impl.h b/content/renderer/websockethandle_impl.h new file mode 100644 index 0000000..98e3957 --- /dev/null +++ b/content/renderer/websockethandle_impl.h
@@ -0,0 +1,84 @@ +// 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 CONTENT_RENDERER_WEBSOCKETHANDLE_IMPL_H_ +#define CONTENT_RENDERER_WEBSOCKETHANDLE_IMPL_H_ + +#include <stddef.h> +#include <stdint.h> + +#include "base/macros.h" +#include "base/single_thread_task_runner.h" +#include "content/common/websocket.mojom.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "third_party/WebKit/public/platform/WebVector.h" +#include "third_party/WebKit/public/platform/modules/websockets/WebSocketHandle.h" + +namespace blink { +class InterfaceProvider; +class WebSecurityOrigin; +class WebString; +class WebURL; +} // namespace blink + +namespace content { + +class WebSocketHandleImpl : public blink::WebSocketHandle, + public mojom::WebSocketClient { + public: + explicit WebSocketHandleImpl( + scoped_refptr<base::SingleThreadTaskRunner> task_runner); + + // This method may optionally be called before connect() to specify a + // specific InterfaceProvider to get a WebSocket instance. By default, + // connect() will use blink::Platform::interfaceProvider(). + void Initialize(blink::InterfaceProvider* interface_provider); + + // blink::WebSocketHandle methods: + void connect(const blink::WebURL& url, + const blink::WebVector<blink::WebString>& protocols, + const blink::WebSecurityOrigin& origin, + const blink::WebURL& first_party_for_cookies, + const blink::WebString& user_agent_override, + blink::WebSocketHandleClient* client) override; + void send(bool fin, + WebSocketHandle::MessageType type, + const char* data, + size_t size) override; + void flowControl(int64_t quota) override; + void close(unsigned short code, const blink::WebString& reason) override; + + private: + ~WebSocketHandleImpl() override; + void Disconnect(); + void OnConnectionError(); + + // mojom::WebSocketClient methods: + void OnFailChannel(const mojo::String& reason) override; + void OnStartOpeningHandshake( + mojom::WebSocketHandshakeRequestPtr request) override; + void OnFinishOpeningHandshake( + mojom::WebSocketHandshakeResponsePtr response) override; + void OnAddChannelResponse(const mojo::String& selected_protocol, + const mojo::String& extensions) override; + void OnDataFrame(bool fin, mojom::WebSocketMessageType type, + mojo::Array<uint8_t> data) override; + void OnFlowControl(int64_t quota) override; + void OnDropChannel(bool was_clean, uint16_t code, + const mojo::String& reason) override; + void OnClosingHandshake() override; + + blink::WebSocketHandleClient* client_; + + mojom::WebSocketPtr websocket_; + mojo::Binding<mojom::WebSocketClient> client_binding_; + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + bool did_initialize_; + + DISALLOW_COPY_AND_ASSIGN(WebSocketHandleImpl); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_WEBSOCKETHANDLE_IMPL_H_
diff --git a/content/shell/android/browsertests/src/org/chromium/content_shell/browsertests/ContentShellBrowserTestActivity.java b/content/shell/android/browsertests/src/org/chromium/content_shell/browsertests/ContentShellBrowserTestActivity.java index 32a5816..1262712 100644 --- a/content/shell/android/browsertests/src/org/chromium/content_shell/browsertests/ContentShellBrowserTestActivity.java +++ b/content/shell/android/browsertests/src/org/chromium/content_shell/browsertests/ContentShellBrowserTestActivity.java
@@ -76,7 +76,7 @@ setContentView(getTestActivityViewId()); mShellManager = (ShellManager) findViewById(getShellManagerViewId()); mWindowAndroid = new ActivityWindowAndroid(this); - mShellManager.setWindow(mWindowAndroid, false); + mShellManager.setWindow(mWindowAndroid); Window wind = this.getWindow(); wind.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
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 ab3ccce..d41997f2 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
@@ -12,7 +12,6 @@ import android.widget.FrameLayout; import org.chromium.base.ThreadUtils; -import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.content.browser.ActivityContentVideoViewEmbedder; @@ -29,7 +28,6 @@ public class ShellManager extends FrameLayout { public static final String DEFAULT_SHELL_URL = "http://www.google.com"; - private static boolean sStartup = true; private WindowAndroid mWindow; private Shell mActiveShell; @@ -69,26 +67,9 @@ * @param window The window used to generate all shells. */ public void setWindow(WindowAndroid window) { - setWindow(window, true); - } - - /** - * @param window The window used to generate all shells. - * @param initialLoadingNeeded Whether initial loading is needed or not. - */ - @VisibleForTesting - public void setWindow(WindowAndroid window, final boolean initialLoadingNeeded) { assert window != null; mWindow = window; - mContentViewRenderView = new ContentViewRenderView(getContext()) { - @Override - protected void onReadyToRender() { - if (sStartup) { - if (initialLoadingNeeded) mActiveShell.loadUrl(mStartupUrl); - sStartup = false; - } - } - }; + mContentViewRenderView = new ContentViewRenderView(getContext()); mContentViewRenderView.onNativeLibraryLoaded(window); }
diff --git a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellTestBase.java b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellTestBase.java index 8206ff5d..23675f9 100644 --- a/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellTestBase.java +++ b/content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellTestBase.java
@@ -121,12 +121,12 @@ updateFailureReason("Shell is null."); return false; } - if (TextUtils.isEmpty(shell.getContentViewCore().getWebContents().getUrl())) { - updateFailureReason("Shell's URL is empty or null."); + if (shell.isLoading()) { + updateFailureReason("Shell is still loading."); return false; } - if (!shell.getContentViewCore().getWebContents().isReady()) { - updateFailureReason("Shell's view is not ready."); + if (TextUtils.isEmpty(shell.getContentViewCore().getWebContents().getUrl())) { + updateFailureReason("Shell's URL is empty or null."); return false; } return true;
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 af13bbf..881bfc0 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
@@ -42,6 +42,7 @@ private ShellManager mShellManager; private ActivityWindowAndroid mWindowAndroid; private Intent mLastSentIntent; + private String mStartupUrl; @Override @SuppressFBWarnings("DM_EXIT") @@ -81,9 +82,9 @@ mWindowAndroid.setAnimationPlaceholderView( mShellManager.getContentViewRenderView().getSurfaceView()); - String startupUrl = getUrlFromIntent(getIntent()); - if (!TextUtils.isEmpty(startupUrl)) { - mShellManager.setStartupUrl(Shell.sanitizeUrl(startupUrl)); + mStartupUrl = getUrlFromIntent(getIntent()); + if (!TextUtils.isEmpty(mStartupUrl)) { + mShellManager.setStartupUrl(Shell.sanitizeUrl(mStartupUrl)); } if (CommandLine.getInstance().hasSwitch(ContentSwitches.RUN_LAYOUT_TEST)) { @@ -118,7 +119,13 @@ } private void finishInitialization(Bundle savedInstanceState) { - String shellUrl = ShellManager.DEFAULT_SHELL_URL; + String shellUrl; + if (!TextUtils.isEmpty(mStartupUrl)) { + shellUrl = mStartupUrl; + } else { + shellUrl = ShellManager.DEFAULT_SHELL_URL; + } + if (savedInstanceState != null && savedInstanceState.containsKey(ACTIVE_SHELL_URL_KEY)) { shellUrl = savedInstanceState.getString(ACTIVE_SHELL_URL_KEY);
diff --git a/content/shell/browser/layout_test/blink_test_controller.cc b/content/shell/browser/layout_test/blink_test_controller.cc index 9aca502c..4e6a1ed 100644 --- a/content/shell/browser/layout_test/blink_test_controller.cc +++ b/content/shell/browser/layout_test/blink_test_controller.cc
@@ -597,7 +597,8 @@ } // Is this the 1st time this renderer contains parts of the main test window? - if (main_window && !ContainsKey(main_window_render_process_hosts_, process)) { + if (main_window && + !base::ContainsKey(main_window_render_process_hosts_, process)) { main_window_render_process_hosts_.insert(process); // Make sure the new renderer process has a test configuration shared with
diff --git a/content/test/content_browser_test_test.cc b/content/test/content_browser_test_test.cc index 0c88c91..23d7316 100644 --- a/content/test/content_browser_test_test.cc +++ b/content/test/content_browser_test_test.cc
@@ -68,7 +68,14 @@ } // Tests that browser tests print the callstack when a child process crashes. -IN_PROC_BROWSER_TEST_F(ContentBrowserTest, RendererCrashCallStack) { +#if defined(OS_WIN) +#define MAYBE_RendererCrashCallStack \ + DISABLED_RendererCrashCallStack +#else +#define MAYBE_RendererCrashCallStack \ + RendererCrashCallStack +#endif +IN_PROC_BROWSER_TEST_F(ContentBrowserTest, MAYBE_RendererCrashCallStack) { base::ThreadRestrictions::ScopedAllowIO allow_io_for_temp_dir; base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
diff --git a/content/test/data/accessibility/html/footer-inside-other-section-expected-android.txt b/content/test/data/accessibility/html/footer-inside-other-section-expected-android.txt new file mode 100644 index 0000000..e0eec6e --- /dev/null +++ b/content/test/data/accessibility/html/footer-inside-other-section-expected-android.txt
@@ -0,0 +1,10 @@ +android.webkit.WebView focusable focused scrollable +++android.view.View role_description='article' +++++android.view.View +++++++android.view.View clickable name='footer inside article.' +++android.view.View role_description='region' +++++android.view.View +++++++android.view.View clickable name='footer inside section.' +++android.view.View role_description='main' +++++android.view.View +++++++android.view.View clickable name='footer inside main.'
diff --git a/content/test/data/accessibility/html/footer-inside-other-section-expected-mac.txt b/content/test/data/accessibility/html/footer-inside-other-section-expected-mac.txt new file mode 100644 index 0000000..09b44a3e --- /dev/null +++ b/content/test/data/accessibility/html/footer-inside-other-section-expected-mac.txt
@@ -0,0 +1,13 @@ +AXWebArea AXRoleDescription='HTML content' +++AXGroup AXSubrole=AXDocumentArticle AXRoleDescription='article' +++++AXGroup AXRoleDescription='group' +++++++AXGroup AXRoleDescription='group' +++++++++AXStaticText AXRoleDescription='text' AXValue='footer inside article.' +++AXGroup AXSubrole=AXDocumentRegion AXRoleDescription='region' +++++AXGroup AXRoleDescription='group' +++++++AXGroup AXRoleDescription='group' +++++++++AXStaticText AXRoleDescription='text' AXValue='footer inside section.' +++AXGroup AXSubrole=AXLandmarkMain AXRoleDescription='main' +++++AXGroup AXRoleDescription='group' +++++++AXGroup AXRoleDescription='group' +++++++++AXStaticText AXRoleDescription='text' AXValue='footer inside main.'
diff --git a/content/test/data/accessibility/html/footer-inside-other-section-expected-win.txt b/content/test/data/accessibility/html/footer-inside-other-section-expected-win.txt new file mode 100644 index 0000000..41a07fcd --- /dev/null +++ b/content/test/data/accessibility/html/footer-inside-other-section-expected-win.txt
@@ -0,0 +1,13 @@ +ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE +++ROLE_SYSTEM_DOCUMENT READONLY xml-roles:article +++++IA2_ROLE_SECTION +++++++IA2_ROLE_PARAGRAPH +++++++++ROLE_SYSTEM_STATICTEXT name='footer inside article.' +++IA2_ROLE_SECTION xml-roles:region +++++IA2_ROLE_SECTION +++++++IA2_ROLE_PARAGRAPH +++++++++ROLE_SYSTEM_STATICTEXT name='footer inside section.' +++IA2_ROLE_PARAGRAPH xml-roles:main +++++IA2_ROLE_SECTION +++++++IA2_ROLE_PARAGRAPH +++++++++ROLE_SYSTEM_STATICTEXT name='footer inside main.'
diff --git a/content/test/data/accessibility/html/footer-inside-other-section.html b/content/test/data/accessibility/html/footer-inside-other-section.html new file mode 100644 index 0000000..6012e34 --- /dev/null +++ b/content/test/data/accessibility/html/footer-inside-other-section.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<!-- +@MAC-ALLOW:AXRole* +@MAC-ALLOW:AXSubrole* +@WIN-ALLOW:xml-roles:* +--> +<article> + <footer> + <p>footer inside article.</p> + </footer> +</article> +<section> + <footer> + <p>footer inside section.</p> + </footer> +</section> +<main> + <footer> + <p>footer inside main.</p> + </footer> +</main>
diff --git a/content/test/data/accessibility/html/header-inside-other-section-expected-android.txt b/content/test/data/accessibility/html/header-inside-other-section-expected-android.txt new file mode 100644 index 0000000..9680584c --- /dev/null +++ b/content/test/data/accessibility/html/header-inside-other-section-expected-android.txt
@@ -0,0 +1,10 @@ +android.webkit.WebView focusable focused scrollable +++android.view.View role_description='article' +++++android.view.View +++++++android.view.View clickable name='Header inside article.' +++android.view.View role_description='region' +++++android.view.View +++++++android.view.View clickable name='Header inside section.' +++android.view.View role_description='main' +++++android.view.View +++++++android.view.View clickable name='Header inside main.'
diff --git a/content/test/data/accessibility/html/header-inside-other-section-expected-mac.txt b/content/test/data/accessibility/html/header-inside-other-section-expected-mac.txt new file mode 100644 index 0000000..4343c26 --- /dev/null +++ b/content/test/data/accessibility/html/header-inside-other-section-expected-mac.txt
@@ -0,0 +1,13 @@ +AXWebArea AXRoleDescription='HTML content' +++AXGroup AXSubrole=AXDocumentArticle AXRoleDescription='article' +++++AXGroup AXRoleDescription='group' +++++++AXGroup AXRoleDescription='group' +++++++++AXStaticText AXRoleDescription='text' AXValue='Header inside article.' +++AXGroup AXSubrole=AXDocumentRegion AXRoleDescription='region' +++++AXGroup AXRoleDescription='group' +++++++AXGroup AXRoleDescription='group' +++++++++AXStaticText AXRoleDescription='text' AXValue='Header inside section.' +++AXGroup AXSubrole=AXLandmarkMain AXRoleDescription='main' +++++AXGroup AXRoleDescription='group' +++++++AXGroup AXRoleDescription='group' +++++++++AXStaticText AXRoleDescription='text' AXValue='Header inside main.'
diff --git a/content/test/data/accessibility/html/header-inside-other-section-expected-win.txt b/content/test/data/accessibility/html/header-inside-other-section-expected-win.txt new file mode 100644 index 0000000..e9fccc2 --- /dev/null +++ b/content/test/data/accessibility/html/header-inside-other-section-expected-win.txt
@@ -0,0 +1,13 @@ +ROLE_SYSTEM_DOCUMENT READONLY FOCUSABLE +++ROLE_SYSTEM_DOCUMENT READONLY xml-roles:article +++++IA2_ROLE_SECTION +++++++IA2_ROLE_PARAGRAPH +++++++++ROLE_SYSTEM_STATICTEXT name='Header inside article.' +++IA2_ROLE_SECTION xml-roles:region +++++IA2_ROLE_SECTION +++++++IA2_ROLE_PARAGRAPH +++++++++ROLE_SYSTEM_STATICTEXT name='Header inside section.' +++IA2_ROLE_PARAGRAPH xml-roles:main +++++IA2_ROLE_SECTION +++++++IA2_ROLE_PARAGRAPH +++++++++ROLE_SYSTEM_STATICTEXT name='Header inside main.'
diff --git a/content/test/data/accessibility/html/header-inside-other-section.html b/content/test/data/accessibility/html/header-inside-other-section.html new file mode 100644 index 0000000..9cf97a0 --- /dev/null +++ b/content/test/data/accessibility/html/header-inside-other-section.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<!-- +@MAC-ALLOW:AXRole* +@MAC-ALLOW:AXSubrole* +@WIN-ALLOW:xml-roles:* +--> +<article> + <header> + <p>Header inside article.</p> + </header> +</article> +<section> + <header> + <p>Header inside section.</p> + </header> +</section> +<main> + <header> + <p>Header inside main.</p> + </header> +</main>
diff --git a/content/test/data/find_in_dynamic_page.html b/content/test/data/find_in_dynamic_page.html new file mode 100644 index 0000000..b284ae4 --- /dev/null +++ b/content/test/data/find_in_dynamic_page.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<html> +<head> +<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> +<script> + function addNewText() { + document.querySelector('div').innerText = 'result result result result result'; + } +</script> +</head> +<body> +This is a find-in-page test page with dynamically added text.</br> +result result result +<div></div> +</body> +</html>
diff --git a/content/test/data/form_that_posts_cross_site.html b/content/test/data/form_that_posts_cross_site.html index 6317347..44c3bd18 100644 --- a/content/test/data/form_that_posts_cross_site.html +++ b/content/test/data/form_that_posts_cross_site.html
@@ -2,7 +2,7 @@ <html> <head></head> <body> - <form id="text-form" method="POST" action="/cross-site-307/x.com/echoall"> + <form id="text-form" method="POST" action="/cross-site-307/i.com/cross-site-307/x.com/echoall"> <input type="text" id="text" name="text" value="value"> <input type="submit"> </form>
diff --git a/content/test/data/hello.html b/content/test/data/hello.html new file mode 100644 index 0000000..be3b725 --- /dev/null +++ b/content/test/data/hello.html
@@ -0,0 +1,2 @@ +<!doctype html> +<p>hello</p>
diff --git a/content/test/data/hello.html.mock-http-headers b/content/test/data/hello.html.mock-http-headers new file mode 100644 index 0000000..5ad3ef0 --- /dev/null +++ b/content/test/data/hello.html.mock-http-headers
@@ -0,0 +1,2 @@ +HTTP/1.1 200 OK +content-type: text/html \ No newline at end of file
diff --git a/content/test/gpu/generate_buildbot_json.py b/content/test/gpu/generate_buildbot_json.py index 39347db7..f13b1d0 100755 --- a/content/test/gpu/generate_buildbot_json.py +++ b/content/test/gpu/generate_buildbot_json.py
@@ -933,6 +933,13 @@ # http://crbug.com/599451: this test is currently too slow # to run on x64 in Debug mode. Need to shard the tests. 'Win7 x64 Debug (NVIDIA)', + # http://crbug.com/637081: the Mac Minis are badly + # oversubscribed right now. Save some time by stopping + # running the WebGL 2.0 conformance tests on this + # configuration temporarily, until more capacity comes + # online (http://crbug.com/636472). + 'Mac 10.10 Release (Intel)', + 'Optional Mac 10.10 Release (Intel)', ], }, ], @@ -1090,12 +1097,32 @@ 'can_use_on_swarming_builders': True, 'dimension_sets': [ tester_config['swarming_dimensions'] - ], + ] }) if is_android(tester_config): # Override the isolate target to get rid of any "_apk" suffix # that would be added by the recipes. result['override_isolate_target'] = test + # Integrate with the unified logcat system. + result['swarming'].update({ + 'cipd_packages': [ + { + 'cipd_package': 'infra/tools/luci/logdog/butler/${platform}', + 'location': 'bin', + 'revision': 'git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a' + } + ], + 'output_links': [ + { + 'link': [ + 'https://luci-logdog.appspot.com/v/?s', + '=android%2Fswarming%2Flogcats%2F', + '${TASK_ID}%2F%2B%2Funified_logcats' + ], + 'name': 'shard #${SHARD_INDEX} logcats' + } + ] + }) if 'desktop_args' in result: if not is_android(tester_config): if not 'args' in result:
diff --git a/content/test/gpu/gpu_tests/gpu_process_expectations.py b/content/test/gpu/gpu_tests/gpu_process_expectations.py index 08010ac..bc7247ee 100644 --- a/content/test/gpu/gpu_tests/gpu_process_expectations.py +++ b/content/test/gpu/gpu_tests/gpu_process_expectations.py
@@ -13,6 +13,22 @@ self.Fail('GpuProcess.video', ['linux'], bug=257109) + # Android + self.Fail('GpuProcess.no_gpu_process', + ['android'], bug=611930) + self.Fail('GpuProcess.identify_active_gpu1', + ['android'], bug=611930) + self.Fail('GpuProcess.identify_active_gpu2', + ['android'], bug=611930) + self.Fail('GpuProcess.identify_active_gpu3', + ['android'], bug=611930) + self.Fail('GpuProcess.identify_active_gpu4', + ['android'], bug=611930) + self.Fail('GpuProcess.readback_webgl_gpu_process', + ['android'], bug=611930) + self.Fail('GpuProcess.driver_bug_workarounds_upon_gl_renderer', + ['android'], bug=611930) + # Nexus 5X # Skip this test because expecting it to fail will still run it. self.Skip('GpuProcess.skip_gpu_process',
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py index 8c0fbcdd..ac4183ac 100644 --- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -42,10 +42,6 @@ 'invariant-does-not-leak-across-shaders.html', bug=634813) - self.Fail('conformance2/textures/' + - 'misc/copy-texture-image-webgl-specific.html', - bug=631934) - self.Flaky('conformance2/query/occlusion-query.html', bug=603168) # All platforms with AMD GPU. @@ -243,6 +239,8 @@ ['mac', ('nvidia', 0xfe9)], bug=483282) self.Fail('conformance/programs/gl-bind-attrib-location-test.html', ['mac', ('nvidia', 0xfe9)], bug=483282) + self.Fail('conformance2/glsl3/loops-with-side-effects.html', + ['mac', ('nvidia', 0xfe9)], bug=483282) self.Fail('conformance2/textures/misc/tex-input-validation.html', ['mac', ('nvidia', 0xfe9), 'no_angle'], bug=483282) self.Fail('conformance2/textures/misc/tex-mipmap-levels.html', @@ -255,7 +253,10 @@ ['mac', ('nvidia', 0xfe9)], bug=483282) self.Fail('deqp/functional/gles3/negativevertexarrayapi.html', ['mac', ('nvidia', 0xfe9)], bug=483282) - + self.Fail('deqp/functional/gles3/shaderindexing/varying.html', + ['mac', ('nvidia', 0xfe9)], bug=483282) + self.Fail('deqp/functional/gles3/shadertexturefunction/texturesize.html', + ['mac', ('nvidia', 0xfe9)], bug=483282) self.Fail('deqp/functional/gles3/texturespecification/' + 'basic_copyteximage2d.html', ['mac', ('nvidia', 0xfe9)], bug=620067) @@ -396,6 +397,10 @@ self.Fail('deqp/functional/gles3/shaderoperator/geometric.html', ['mac', 'amd'], bug=483282) + # Mac Pro with AMD GPU + self.Flaky('deqp/functional/gles3/shaderindexing/mat_01.html', + ['mac', ('amd', 0x679e)], bug=636648) + # Mac Intel self.Fail('deqp/functional/gles3/shadercommonfunction.html', ['mac', 'intel'], bug=483282) @@ -806,6 +811,8 @@ ['linux', 'amd', 'no_angle'], bug=483282) self.Fail('conformance2/textures/misc/tex-unpack-params.html', ['linux', 'amd', 'no_angle'], bug=483282) + self.Fail('conformance2/extensions/ext-color-buffer-float.html', + ['linux', 'amd'], bug=633022) # Conflicting expectations to test that the # "Expectations Have No collisions" unittest works.
diff --git a/content/test/gpu/page_sets/gpu_process_tests.py b/content/test/gpu/page_sets/gpu_process_tests.py index ddfdd71..dbe8beb 100644 --- a/content/test/gpu/page_sets/gpu_process_tests.py +++ b/content/test/gpu/page_sets/gpu_process_tests.py
@@ -174,11 +174,7 @@ test, finder_options, story_set) options = finder_options.browser_options - if options.browser_type.startswith('android'): - # Hit id 8 from kSoftwareRenderingListJson, which applies to any platform. - options.AppendExtraBrowserArgs('--gpu-testing-vendor-id=0x10de') - options.AppendExtraBrowserArgs('--gpu-testing-device-id=0x0324') - elif sys.platform in ('cygwin', 'win32'): + if sys.platform in ('cygwin', 'win32'): # Hit id 34 from kSoftwareRenderingListJson. options.AppendExtraBrowserArgs('--gpu-testing-vendor-id=0x5333') options.AppendExtraBrowserArgs('--gpu-testing-device-id=0x8811') @@ -199,19 +195,15 @@ class NoGpuProcessPage(gpu_test_base.PageBase): - def __init__(self, story_set, expectations, is_platform_android): + def __init__(self, story_set, expectations): super(NoGpuProcessPage, self).__init__( url='about:blank', name='GpuProcess.no_gpu_process', page_set=story_set, shared_page_state_class=NoGpuProcessSharedPageState, expectations=expectations) - self.is_platform_android = is_platform_android def Validate(self, tab, results): - if self.is_platform_android: - return - has_gpu_process_js = 'chrome.gpuBenchmarking.hasGpuProcess()' has_gpu_process = tab.EvaluateJavaScript(has_gpu_process_js) if has_gpu_process: @@ -223,8 +215,6 @@ super(SoftwareGpuProcessSharedPageState, self).__init__( test, finder_options, story_set) options = finder_options.browser_options - - # Hit exception from id 50 from kSoftwareRenderingListJson. options.AppendExtraBrowserArgs('--gpu-testing-vendor-id=0x10de') options.AppendExtraBrowserArgs('--gpu-testing-device-id=0x0de1') options.AppendExtraBrowserArgs('--gpu-testing-gl-vendor=VMware') @@ -296,10 +286,7 @@ super(DriverBugWorkaroundsUponGLRendererShared, self).__init__( test, finder_options, story_set) options = finder_options.browser_options - if options.browser_type.startswith('android'): - # Hit id 108 from kGpuDriverBugListJson. - options.AppendExtraBrowserArgs('--gpu-testing-gl-vendor=Qualcomm') - elif sys.platform in ('cygwin', 'win32'): + if sys.platform in ('cygwin', 'win32'): # Hit id 51 and 87 from kGpuDriverBugListJson. options.AppendExtraBrowserArgs('--gpu-testing-vendor-id=0x1002') options.AppendExtraBrowserArgs('--gpu-testing-device-id=0x6779') @@ -310,29 +297,26 @@ options.AppendExtraBrowserArgs('--gpu-testing-gl-version=OpenGL ES 2.0 ' \ '(ANGLE 2.1.0.0c0d8006a9dd)') elif sys.platform.startswith('linux'): - # Hit id 153 from kGpuDriverBugListJson. + # Hit id 40 from kGpuDriverBugListJson. options.AppendExtraBrowserArgs('--gpu-testing-vendor-id=0x0101') options.AppendExtraBrowserArgs('--gpu-testing-device-id=0x0102') - options.AppendExtraBrowserArgs('--gpu-testing-gl-vendor=Vivante ' \ - 'Corporation') - options.AppendExtraBrowserArgs('--gpu-testing-gl-renderer=Vivante GC1000') + options.AppendExtraBrowserArgs('--gpu-testing-gl-vendor=ARM') + options.AppendExtraBrowserArgs('--gpu-testing-gl-renderer=Mali-400 MP') elif sys.platform == 'darwin': # Currently on osx no workaround relies on gl-renderer. pass class DriverBugWorkaroundsUponGLRendererPage(DriverBugWorkaroundsTestsPage): - def __init__(self, story_set, expectations, is_platform_android): + def __init__(self, story_set, expectations): self.expected_workaround = None self.unexpected_workaround = None - if is_platform_android: - self.expected_workaround = "wake_up_gpu_before_drawing" - elif sys.platform in ('cygwin', 'win32'): + if sys.platform in ('cygwin', 'win32'): self.expected_workaround = "texsubimage_faster_than_teximage" self.unexpected_workaround = "disable_d3d11" elif sys.platform.startswith('linux'): - self.expected_workaround = "disable_transparent_visuals" + self.expected_workaround = "disable_discard_framebuffer" elif sys.platform == 'darwin': pass super(DriverBugWorkaroundsUponGLRendererPage, self).__init__( @@ -476,9 +460,8 @@ super(ReadbackWebGLGpuProcessSharedPageState, self).__init__( test, finder_options, story_set) options = finder_options.browser_options - is_platform_android = options.browser_type.startswith('android') - if sys.platform.startswith('linux') and not is_platform_android: + if sys.platform.startswith('linux'): # Hit id 110 from kSoftwareRenderingListJson. options.AppendExtraBrowserArgs('--gpu-testing-vendor-id=0x10de') options.AppendExtraBrowserArgs('--gpu-testing-device-id=0x0de1') @@ -488,17 +471,16 @@ options.AppendExtraBrowserArgs('--gpu-testing-gl-version="3.0 Mesa 11.2"') class ReadbackWebGLGpuProcessPage(gpu_test_base.PageBase): - def __init__(self, story_set, expectations, is_platform_android): + def __init__(self, story_set, expectations): super(ReadbackWebGLGpuProcessPage, self).__init__( url='chrome:gpu', name='GpuProcess.readback_webgl_gpu_process', page_set=story_set, shared_page_state_class=ReadbackWebGLGpuProcessSharedPageState, expectations=expectations) - self.is_platform_android = is_platform_android def Validate(self, tab, results): - if sys.platform.startswith('linux') and not self.is_platform_android: + if sys.platform.startswith('linux'): feature_status_js = 'browserBridge.gpuInfo.featureStatus.featureStatus' feature_status_list = tab.EvaluateJavaScript(feature_status_js) result = True @@ -609,12 +591,15 @@ self.AddStory(FunctionalVideoPage(self, expectations)) self.AddStory(GpuInfoCompletePage(self, expectations)) - self.AddStory(NoGpuProcessPage(self, expectations, is_platform_android)) + self.AddStory(NoGpuProcessPage(self, expectations)) + self.AddStory(SoftwareGpuProcessPage(self, expectations)) self.AddStory(DriverBugWorkaroundsInGpuProcessPage(self, expectations)) - self.AddStory(ReadbackWebGLGpuProcessPage(self, expectations, - is_platform_android)) - self.AddStory(DriverBugWorkaroundsUponGLRendererPage(self, expectations, - is_platform_android)) + self.AddStory(IdentifyActiveGpuPage1(self, expectations)) + self.AddStory(IdentifyActiveGpuPage2(self, expectations)) + self.AddStory(IdentifyActiveGpuPage3(self, expectations)) + self.AddStory(IdentifyActiveGpuPage4(self, expectations)) + self.AddStory(ReadbackWebGLGpuProcessPage(self, expectations)) + self.AddStory(DriverBugWorkaroundsUponGLRendererPage(self, expectations)) self.AddStory(EqualBugWorkaroundsInBrowserAndGpuProcessPage(self, expectations)) if not is_platform_android: @@ -622,17 +607,6 @@ self.AddStory(HasTransparentVisualsGpuProcessPage(self, expectations)) self.AddStory(NoTransparentVisualsGpuProcessPage(self, expectations)) - # There is no Android multi-gpu configuration and the helper - # gpu_info_collector.cc::IdentifyActiveGPU is not even called. - self.AddStory(IdentifyActiveGpuPage1(self, expectations)) - self.AddStory(IdentifyActiveGpuPage2(self, expectations)) - self.AddStory(IdentifyActiveGpuPage3(self, expectations)) - self.AddStory(IdentifyActiveGpuPage4(self, expectations)) - - # There is currently no entry in kSoftwareRenderingListJson that enables - # a software GL driver on Android. - self.AddStory(SoftwareGpuProcessPage(self, expectations)) - @property def allow_mixed_story_states(self): # Return True here in order to be able to run pages with different browser
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc index 746d0ad..01d7e40 100644 --- a/content/test/layouttest_support.cc +++ b/content/test/layouttest_support.cc
@@ -203,9 +203,10 @@ void DidSwap(cc::CompositorFrameMetadata*) override { output_surface_from_commit_->RequestCopyOfOutput(std::move(copy_request_)); } - void DidNotSwap(DidNotSwapReason r) override { + DidNotSwapAction DidNotSwap(DidNotSwapReason r) override { // The compositor should always swap in layout test mode. NOTREACHED() << "did not swap for reason " << r; + return DidNotSwapAction::BREAK_PROMISE; } int64_t TraceId() const override { return 0; } @@ -352,13 +353,6 @@ } void SetDeviceColorProfile(RenderView* render_view, const std::string& name) { - if (name == "reset") { - static_cast<RenderViewImpl*>(render_view) - ->GetWidget() - ->ResetDeviceColorProfileForTesting(); - return; - } - std::vector<char> color_profile; struct TestColorProfile { // A color spin profile.
diff --git a/content/test/mock_ssl_host_state_delegate.cc b/content/test/mock_ssl_host_state_delegate.cc index daded7e..0411ba4 100644 --- a/content/test/mock_ssl_host_state_delegate.cc +++ b/content/test/mock_ssl_host_state_delegate.cc
@@ -31,12 +31,15 @@ return SSLHostStateDelegate::ALLOWED; } -void MockSSLHostStateDelegate::HostRanInsecureContent(const std::string& host, - int pid) {} +void MockSSLHostStateDelegate::HostRanInsecureContent( + const std::string& host, + int pid, + InsecureContentType content_type) {} bool MockSSLHostStateDelegate::DidHostRunInsecureContent( const std::string& host, - int pid) const { + int pid, + InsecureContentType content_type) const { return false; }
diff --git a/content/test/mock_ssl_host_state_delegate.h b/content/test/mock_ssl_host_state_delegate.h index 836139e6..2e88cc9 100644 --- a/content/test/mock_ssl_host_state_delegate.h +++ b/content/test/mock_ssl_host_state_delegate.h
@@ -25,10 +25,14 @@ net::CertStatus error, bool* expired_previous_decision) override; - void HostRanInsecureContent(const std::string& host, int pid) override; + void HostRanInsecureContent(const std::string& host, + int pid, + InsecureContentType content_type) override; - bool DidHostRunInsecureContent(const std::string& host, - int pid) const override; + bool DidHostRunInsecureContent( + const std::string& host, + int pid, + InsecureContentType content_type) const override; void RevokeUserAllowExceptions(const std::string& host) override;
diff --git a/content/test/test_blink_web_unit_test_support.cc b/content/test/test_blink_web_unit_test_support.cc index db37bfc..0661f3f 100644 --- a/content/test/test_blink_web_unit_test_support.cc +++ b/content/test/test_blink_web_unit_test_support.cc
@@ -186,7 +186,7 @@ blink::WebURLLoader* TestBlinkWebUnitTestSupport::createURLLoader() { // This loader should be used only for process-local resources such as // data URLs. - blink::WebURLLoader* default_loader = new WebURLLoaderImpl(nullptr); + blink::WebURLLoader* default_loader = new WebURLLoaderImpl(nullptr, nullptr); return url_loader_factory_->createURLLoader(default_loader); }
diff --git a/content/test/test_render_view_host.h b/content/test/test_render_view_host.h index 314267b2d6..35f9edb5 100644 --- a/content/test/test_render_view_host.h +++ b/content/test/test_render_view_host.h
@@ -117,7 +117,6 @@ bool HasAcceleratedSurface(const gfx::Size& desired_size) override; void LockCompositingSurface() override {} void UnlockCompositingSurface() override {} - void GetScreenInfo(blink::WebScreenInfo* results) override {} gfx::Rect GetBoundsInRootWindow() override; bool LockMouse() override; void UnlockMouse() override;
diff --git a/content/zygote/zygote_main_linux.cc b/content/zygote/zygote_main_linux.cc index 60e8840..88b4b4f 100644 --- a/content/zygote/zygote_main_linux.cc +++ b/content/zygote/zygote_main_linux.cc
@@ -369,13 +369,23 @@ if (android_fonts_dir.size() > 0 && android_fonts_dir.back() != '/') android_fonts_dir += '/'; - std::string font_config = android_fonts_dir + "fonts.xml"; + SkFontMgr_Android_CustomFonts custom; custom.fSystemFontUse = SkFontMgr_Android_CustomFonts::SystemFontUse::kOnlyCustom; custom.fBasePath = android_fonts_dir.c_str(); + + std::string font_config; + std::string fallback_font_config; + if (android_fonts_dir.find("kitkat") != std::string::npos) { + font_config = android_fonts_dir + "system_fonts.xml"; + fallback_font_config = android_fonts_dir + "fallback_fonts.xml"; + custom.fFallbackFontsXml = fallback_font_config.c_str(); + } else { + font_config = android_fonts_dir + "fonts.xml"; + custom.fFallbackFontsXml = nullptr; + } custom.fFontsXml = font_config.c_str(); - custom.fFallbackFontsXml = nullptr; custom.fIsolated = true; blink::WebFontRendering::setSkiaFontManager(SkFontMgr_New_Android(&custom));
diff --git a/crypto/hmac.cc b/crypto/hmac.cc index fa91628..b4dd6cf1 100644 --- a/crypto/hmac.cc +++ b/crypto/hmac.cc
@@ -25,7 +25,7 @@ HMAC::~HMAC() { // Zero out key copy. key_.assign(key_.size(), 0); - STLClearObject(&key_); + base::STLClearObject(&key_); } size_t HMAC::DigestLength() const {
diff --git a/crypto/nss_util.cc b/crypto/nss_util.cc index 66114cd..a41b4d6 100644 --- a/crypto/nss_util.cc +++ b/crypto/nss_util.cc
@@ -752,7 +752,7 @@ // down. ~NSSInitSingleton() { #if defined(OS_CHROMEOS) - STLDeleteValues(&chromeos_user_map_); + base::STLDeleteValues(&chromeos_user_map_); #endif tpm_slot_.reset(); if (root_) {
diff --git a/crypto/sha2.cc b/crypto/sha2.cc index e97b8f40..1b302b3 100644 --- a/crypto/sha2.cc +++ b/crypto/sha2.cc
@@ -21,7 +21,7 @@ std::string SHA256HashString(const base::StringPiece& str) { std::string output(kSHA256Length, 0); - SHA256HashString(str, string_as_array(&output), output.size()); + SHA256HashString(str, base::string_as_array(&output), output.size()); return output; }
diff --git a/dbus/dbus_statistics.cc b/dbus/dbus_statistics.cc index e1e0973..4bcf7fb 100644 --- a/dbus/dbus_statistics.cc +++ b/dbus/dbus_statistics.cc
@@ -69,7 +69,7 @@ ~DBusStatistics() { DCHECK_EQ(origin_thread_id_, base::PlatformThread::CurrentId()); - STLDeleteContainerPointers(stats_.begin(), stats_.end()); + base::STLDeleteContainerPointers(stats_.begin(), stats_.end()); } // Enum to specify which field in Stat to increment in AddStat
diff --git a/dbus/object_proxy.h b/dbus/object_proxy.h index 033e886..5bc4e20 100644 --- a/dbus/object_proxy.h +++ b/dbus/object_proxy.h
@@ -174,7 +174,11 @@ // represented by |service_name_|. virtual void SetNameOwnerChangedCallback(NameOwnerChangedCallback callback); - // Runs the callback as soon as the service becomes available. + // Registers |callback| to run when the service becomes available. If the + // service is already available, or if connecting to the name-owner-changed + // signal fails, |callback| will be run once asynchronously. Otherwise, + // |callback| will be run once in the future after the service becomes + // available. virtual void WaitForServiceToBeAvailable( WaitForServiceToBeAvailableCallback callback);
diff --git a/dbus/object_proxy_unittest.cc b/dbus/object_proxy_unittest.cc index cc79f84..189ef90 100644 --- a/dbus/object_proxy_unittest.cc +++ b/dbus/object_proxy_unittest.cc
@@ -29,44 +29,110 @@ }; // Used as a WaitForServiceToBeAvailableCallback. -void OnServiceIsAvailable(std::unique_ptr<base::RunLoop>* run_loop, - bool service_is_available) { - EXPECT_TRUE(service_is_available); - ASSERT_TRUE(*run_loop); - (*run_loop)->Quit(); +void OnServiceIsAvailable(bool* dest_service_is_available, + int* num_calls, + bool src_service_is_available) { + *dest_service_is_available = src_service_is_available; + (*num_calls)++; } -TEST_F(ObjectProxyTest, WaitForServiceToBeAvailable) { - std::unique_ptr<base::RunLoop> run_loop; +// Used as a callback for TestService::RequestOwnership(). +void OnOwnershipRequestDone(bool success) { + ASSERT_TRUE(success); +} +// Used as a callback for TestService::ReleaseOwnership(). +void OnOwnershipReleased() {} + +TEST_F(ObjectProxyTest, WaitForServiceToBeAvailableRunOnce) { TestService::Options options; TestService test_service(options); - - // Callback is not yet called because the service is not available. ObjectProxy* object_proxy = bus_->GetObjectProxy( test_service.service_name(), ObjectPath("/org/chromium/TestObject")); - object_proxy->WaitForServiceToBeAvailable( - base::Bind(&OnServiceIsAvailable, &run_loop)); - base::RunLoop().RunUntilIdle(); - // Start the service. + // The callback is not yet called because the service is not available. + int num_calls = 0; + bool service_is_available = false; + object_proxy->WaitForServiceToBeAvailable( + base::Bind(&OnServiceIsAvailable, &service_is_available, &num_calls)); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(0, num_calls); + + // Start the service. The callback should be called asynchronously. + ASSERT_TRUE(test_service.StartService()); + ASSERT_TRUE(test_service.WaitUntilServiceIsStarted()); + ASSERT_TRUE(test_service.has_ownership()); + num_calls = 0; + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, num_calls); + EXPECT_TRUE(service_is_available); + + // Release the service's ownership of its name. The callback should not be + // invoked again. + test_service.ReleaseOwnership(base::Bind(&OnOwnershipReleased)); + num_calls = 0; + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(0, num_calls); + + // Take ownership of the name and check that the callback is not called. + test_service.RequestOwnership(base::Bind(&OnOwnershipRequestDone)); + num_calls = 0; + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(0, num_calls); +} + +TEST_F(ObjectProxyTest, WaitForServiceToBeAvailableAlreadyRunning) { + TestService::Options options; + TestService test_service(options); + ObjectProxy* object_proxy = bus_->GetObjectProxy( + test_service.service_name(), ObjectPath("/org/chromium/TestObject")); + ASSERT_TRUE(test_service.StartService()); ASSERT_TRUE(test_service.WaitUntilServiceIsStarted()); ASSERT_TRUE(test_service.has_ownership()); - // Callback is called beacuse the service became available. - run_loop.reset(new base::RunLoop); - run_loop->Run(); - - // Callback is called because the service is already available. - run_loop.reset(new base::RunLoop); + // Since the service is already running, the callback should be invoked + // immediately (but asynchronously, rather than the callback being invoked + // directly within WaitForServiceToBeAvailable()). + int num_calls = 0; + bool service_is_available = false; object_proxy->WaitForServiceToBeAvailable( - base::Bind(&OnServiceIsAvailable, &run_loop)); - run_loop->Run(); + base::Bind(&OnServiceIsAvailable, &service_is_available, &num_calls)); + EXPECT_EQ(0, num_calls); - // Shut down the service. - test_service.ShutdownAndBlock(); - test_service.Stop(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, num_calls); + EXPECT_TRUE(service_is_available); +} + +TEST_F(ObjectProxyTest, WaitForServiceToBeAvailableMultipleCallbacks) { + TestService::Options options; + TestService test_service(options); + ObjectProxy* object_proxy = bus_->GetObjectProxy( + test_service.service_name(), ObjectPath("/org/chromium/TestObject")); + + // Register two callbacks. + int num_calls_1 = 0, num_calls_2 = 0; + bool service_is_available_1 = false, service_is_available_2 = false; + object_proxy->WaitForServiceToBeAvailable( + base::Bind(&OnServiceIsAvailable, &service_is_available_1, &num_calls_1)); + object_proxy->WaitForServiceToBeAvailable( + base::Bind(&OnServiceIsAvailable, &service_is_available_2, &num_calls_2)); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(0, num_calls_1); + EXPECT_EQ(0, num_calls_2); + + // Start the service and confirm that both callbacks are invoked. + ASSERT_TRUE(test_service.StartService()); + ASSERT_TRUE(test_service.WaitUntilServiceIsStarted()); + ASSERT_TRUE(test_service.has_ownership()); + num_calls_1 = 0; + num_calls_2 = 0; + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1, num_calls_1); + EXPECT_EQ(1, num_calls_2); + EXPECT_TRUE(service_is_available_1); + EXPECT_TRUE(service_is_available_2); } } // namespace
diff --git a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothDevice.java b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothDevice.java index 447326cc..ebe9f07 100644 --- a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothDevice.java +++ b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothDevice.java
@@ -13,6 +13,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; +import org.chromium.base.metrics.RecordHistogram; import java.util.HashMap; @@ -127,12 +128,21 @@ ? "Connected" : "Disconnected"); if (newState == android.bluetooth.BluetoothProfile.STATE_CONNECTED) { + RecordHistogram.recordSparseSlowlyHistogram( + "Bluetooth.Web.Android.onConnectionStateChange.Status.Connected", status); mBluetoothGatt.discoverServices(); } else if (newState == android.bluetooth.BluetoothProfile.STATE_DISCONNECTED) { + RecordHistogram.recordSparseSlowlyHistogram( + "Bluetooth.Web.Android.onConnectionStateChange.Status.Disconnected", + status); if (mBluetoothGatt != null) { mBluetoothGatt.close(); mBluetoothGatt = null; } + } else { + RecordHistogram.recordSparseSlowlyHistogram( + "Bluetooth.Web.Android.onConnectionStateChange.Status.InvalidState", + status); } ThreadUtils.runOnUiThread(new Runnable() { @Override @@ -153,11 +163,19 @@ @Override public void run() { if (mNativeBluetoothDeviceAndroid != 0) { - // When the device disconnects is deletes + // When the device disconnects it deletes // mBluetoothGatt, so we need to check it's not null. if (mBluetoothGatt == null) { + RecordHistogram.recordSparseSlowlyHistogram( + "Bluetooth.Web.Android.onServicesDiscovered.Status." + + "Disconnected", + status); return; } + RecordHistogram.recordSparseSlowlyHistogram( + "Bluetooth.Web.Android.onServicesDiscovered.Status.Connected", + status); + // TODO(crbug.com/576906): Update or replace existing GATT objects if they // change after initial discovery. for (Wrappers.BluetoothGattServiceWrapper service : @@ -209,6 +227,8 @@ // when the event races object destruction. Log.v(TAG, "onCharacteristicRead when chromeCharacteristic == null."); } else { + RecordHistogram.recordSparseSlowlyHistogram( + "Bluetooth.Web.Android.onCharacteristicRead.Status", status); chromeCharacteristic.onCharacteristicRead(status); } } @@ -229,6 +249,8 @@ // when the event races object destruction. Log.v(TAG, "onCharacteristicWrite when chromeCharacteristic == null."); } else { + RecordHistogram.recordSparseSlowlyHistogram( + "Bluetooth.Web.Android.onCharacteristicWrite.Status", status); chromeCharacteristic.onCharacteristicWrite(status); } } @@ -248,6 +270,8 @@ // when the event races object destruction. Log.v(TAG, "onDescriptorRead when chromeDescriptor == null."); } else { + RecordHistogram.recordSparseSlowlyHistogram( + "Bluetooth.Web.Android.onDescriptorRead.Status", status); chromeDescriptor.onDescriptorRead(status); } } @@ -267,6 +291,8 @@ // when the event races object destruction. Log.v(TAG, "onDescriptorWrite when chromeDescriptor == null."); } else { + RecordHistogram.recordSparseSlowlyHistogram( + "Bluetooth.Web.Android.onDescriptorWrite.Status", status); chromeDescriptor.onDescriptorWrite(status); } }
diff --git a/device/bluetooth/bluetooth_adapter_factory_wrapper.cc b/device/bluetooth/bluetooth_adapter_factory_wrapper.cc index 5031896..e4b858a 100644 --- a/device/bluetooth/bluetooth_adapter_factory_wrapper.cc +++ b/device/bluetooth/bluetooth_adapter_factory_wrapper.cc
@@ -103,7 +103,7 @@ BluetoothAdapter::Observer* observer) { DCHECK(thread_checker_.CalledOnValidThread()); - return ContainsKey(adapter_observers_, observer); + return base::ContainsKey(adapter_observers_, observer); } void BluetoothAdapterFactoryWrapper::AddAdapterObserver(
diff --git a/device/bluetooth/bluetooth_adapter_unittest.cc b/device/bluetooth/bluetooth_adapter_unittest.cc index 42e141df..ffd8467e 100644 --- a/device/bluetooth/bluetooth_adapter_unittest.cc +++ b/device/bluetooth/bluetooth_adapter_unittest.cc
@@ -634,10 +634,10 @@ BluetoothDevice* device = SimulateLowEnergyDevice(1); // Check the initial UUIDs: - EXPECT_TRUE( - ContainsValue(device->GetUUIDs(), BluetoothUUID(kTestUUIDGenericAccess))); - EXPECT_FALSE(ContainsValue(device->GetUUIDs(), - BluetoothUUID(kTestUUIDImmediateAlert))); + EXPECT_TRUE(base::ContainsValue(device->GetUUIDs(), + BluetoothUUID(kTestUUIDGenericAccess))); + EXPECT_FALSE(base::ContainsValue(device->GetUUIDs(), + BluetoothUUID(kTestUUIDImmediateAlert))); // Discover same device again with updated UUIDs: observer.Reset(); @@ -648,10 +648,10 @@ EXPECT_EQ(device, observer.last_device()); // Expect only new UUIDs: - EXPECT_FALSE( - ContainsValue(device->GetUUIDs(), BluetoothUUID(kTestUUIDGenericAccess))); - EXPECT_TRUE(ContainsValue(device->GetUUIDs(), - BluetoothUUID(kTestUUIDImmediateAlert))); + EXPECT_FALSE(base::ContainsValue(device->GetUUIDs(), + BluetoothUUID(kTestUUIDGenericAccess))); + EXPECT_TRUE(base::ContainsValue(device->GetUUIDs(), + BluetoothUUID(kTestUUIDImmediateAlert))); // Discover same device again with empty UUIDs: observer.Reset();
diff --git a/device/bluetooth/bluetooth_device_unittest.cc b/device/bluetooth/bluetooth_device_unittest.cc index cb2d8ac9..cb48aa7 100644 --- a/device/bluetooth/bluetooth_device_unittest.cc +++ b/device/bluetooth/bluetooth_device_unittest.cc
@@ -96,8 +96,10 @@ EXPECT_EQ(base::UTF8ToUTF16(kTestDeviceName), device->GetNameForDisplay()); EXPECT_FALSE(device->IsPaired()); BluetoothDevice::UUIDList uuids = device->GetUUIDs(); - EXPECT_TRUE(ContainsValue(uuids, BluetoothUUID(kTestUUIDGenericAccess))); - EXPECT_TRUE(ContainsValue(uuids, BluetoothUUID(kTestUUIDGenericAttribute))); + EXPECT_TRUE( + base::ContainsValue(uuids, BluetoothUUID(kTestUUIDGenericAccess))); + EXPECT_TRUE( + base::ContainsValue(uuids, BluetoothUUID(kTestUUIDGenericAttribute))); } #endif // defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN) @@ -130,10 +132,10 @@ // Check advertised UUIDs: EXPECT_EQ(2u, device->GetUUIDs().size()); - EXPECT_TRUE( - ContainsValue(device->GetUUIDs(), BluetoothUUID(kTestUUIDGenericAccess))); - EXPECT_TRUE(ContainsValue(device->GetUUIDs(), - BluetoothUUID(kTestUUIDGenericAttribute))); + EXPECT_TRUE(base::ContainsValue(device->GetUUIDs(), + BluetoothUUID(kTestUUIDGenericAccess))); + EXPECT_TRUE(base::ContainsValue(device->GetUUIDs(), + BluetoothUUID(kTestUUIDGenericAttribute))); // Connect. device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED), @@ -152,8 +154,8 @@ // GetUUIDs should return UUIDs of services in device. EXPECT_EQ(1u, device->GetUUIDs().size()); - EXPECT_TRUE( - ContainsValue(device->GetUUIDs(), BluetoothUUID(kTestUUIDGenericAccess))); + EXPECT_TRUE(base::ContainsValue(device->GetUUIDs(), + BluetoothUUID(kTestUUIDGenericAccess))); #if defined(OS_MACOSX) // Android and Windows don't yet support service changed events. @@ -169,8 +171,8 @@ // GetUUIDs should return UUIDs of services in device. EXPECT_EQ(1u, device->GetUUIDs().size()); - EXPECT_TRUE( - ContainsValue(device->GetUUIDs(), BluetoothUUID(kTestUUIDGenericAccess))); + EXPECT_TRUE(base::ContainsValue(device->GetUUIDs(), + BluetoothUUID(kTestUUIDGenericAccess))); #endif // defined(OS_MACOSX) // Disconnect. @@ -185,10 +187,10 @@ // Check advertised UUIDs. EXPECT_EQ(2u, device->GetUUIDs().size()); - EXPECT_TRUE(ContainsValue(device->GetUUIDs(), - BluetoothUUID(kTestUUIDImmediateAlert))); - EXPECT_TRUE( - ContainsValue(device->GetUUIDs(), BluetoothUUID(kTestUUIDLinkLoss))); + EXPECT_TRUE(base::ContainsValue(device->GetUUIDs(), + BluetoothUUID(kTestUUIDImmediateAlert))); + EXPECT_TRUE(base::ContainsValue(device->GetUUIDs(), + BluetoothUUID(kTestUUIDLinkLoss))); } #endif // defined(OS_ANDROID) || defined(OS_MACOSX)
diff --git a/device/bluetooth/dbus/fake_bluetooth_input_client.cc b/device/bluetooth/dbus/fake_bluetooth_input_client.cc index 849c3be..bd3b86f6 100644 --- a/device/bluetooth/dbus/fake_bluetooth_input_client.cc +++ b/device/bluetooth/dbus/fake_bluetooth_input_client.cc
@@ -48,7 +48,7 @@ FakeBluetoothInputClient::~FakeBluetoothInputClient() { // Clean up Properties structures - STLDeleteValues(&properties_map_); + base::STLDeleteValues(&properties_map_); } void FakeBluetoothInputClient::Init(dbus::Bus* bus) {}
diff --git a/device/bluetooth/dbus/fake_bluetooth_media_client.cc b/device/bluetooth/dbus/fake_bluetooth_media_client.cc index 246a140..3b7a83b9 100644 --- a/device/bluetooth/dbus/fake_bluetooth_media_client.cc +++ b/device/bluetooth/dbus/fake_bluetooth_media_client.cc
@@ -78,7 +78,7 @@ // TODO(mcchou): Come up with some corresponding actions. VLOG(1) << "UnregisterEndpoint: " << endpoint_path.value(); - if (!ContainsKey(endpoints_, endpoint_path)) { + if (!base::ContainsKey(endpoints_, endpoint_path)) { error_callback.Run(kFailedError, "Unknown media endpoint"); return; } @@ -128,7 +128,7 @@ bool FakeBluetoothMediaClient::IsRegistered( const dbus::ObjectPath& endpoint_path) { - return ContainsKey(endpoints_, endpoint_path); + return base::ContainsKey(endpoints_, endpoint_path); } } // namespace bluez
diff --git a/device/bluetooth/dbus/fake_bluetooth_media_transport_client.cc b/device/bluetooth/dbus/fake_bluetooth_media_transport_client.cc index 6172c7e..039805a 100644 --- a/device/bluetooth/dbus/fake_bluetooth_media_transport_client.cc +++ b/device/bluetooth/dbus/fake_bluetooth_media_transport_client.cc
@@ -103,7 +103,7 @@ FakeBluetoothMediaTransportClient::FakeBluetoothMediaTransportClient() {} FakeBluetoothMediaTransportClient::~FakeBluetoothMediaTransportClient() { - STLDeleteValues(&endpoint_to_transport_map_); + base::STLDeleteValues(&endpoint_to_transport_map_); } // DBusClient override.
diff --git a/device/gamepad/BUILD.gn b/device/gamepad/BUILD.gn index 275a5ca0..6e6e000 100644 --- a/device/gamepad/BUILD.gn +++ b/device/gamepad/BUILD.gn
@@ -19,6 +19,10 @@ "gamepad_consumer.h", "gamepad_data_fetcher.cc", "gamepad_data_fetcher.h", + "gamepad_data_fetcher_manager.cc", + "gamepad_data_fetcher_manager.h", + "gamepad_pad_state_provider.cc", + "gamepad_pad_state_provider.h", "gamepad_platform_data_fetcher.h", "gamepad_platform_data_fetcher_android.cc", "gamepad_platform_data_fetcher_android.h", @@ -39,8 +43,8 @@ "gamepad_user_gesture.h", "raw_input_data_fetcher_win.cc", "raw_input_data_fetcher_win.h", - "xbox_data_fetcher_mac.cc", "xbox_data_fetcher_mac.h", + "xbox_data_fetcher_mac.mm", ] deps = [ @@ -58,7 +62,6 @@ if (is_linux && use_udev) { deps += [ "//device/udev_linux" ] } else if (!is_win && !is_mac && !is_android) { - sources += [ "gamepad_platform_data_fetcher.cc" ] sources -= [ "gamepad_platform_data_fetcher_linux.cc" ] }
diff --git a/device/gamepad/gamepad.gyp b/device/gamepad/gamepad.gyp index 792843c..c5c749645 100644 --- a/device/gamepad/gamepad.gyp +++ b/device/gamepad/gamepad.gyp
@@ -24,6 +24,8 @@ 'gamepad_consumer.h', 'gamepad_data_fetcher.cc', 'gamepad_data_fetcher.h', + 'gamepad_data_fetcher_manager.cc', + 'gamepad_data_fetcher_manager.h', 'gamepad_platform_data_fetcher.h', 'gamepad_platform_data_fetcher_android.cc', 'gamepad_platform_data_fetcher_android.h', @@ -44,22 +46,14 @@ 'gamepad_user_gesture.h', 'raw_input_data_fetcher_win.cc', 'raw_input_data_fetcher_win.h', - 'xbox_data_fetcher_mac.cc', 'xbox_data_fetcher_mac.h', + 'xbox_data_fetcher_mac.mm', ], 'conditions': [ ['OS=="win"', { 'msvs_disabled_warnings': [4267, ], }], - ['OS=="linux" and use_udev==1', { - 'dependencies': [ - '../udev_linux/udev.gyp:udev_linux', - ] - }], ['OS!="win" and OS!="mac" and OS!="android" and (OS!="linux" or use_udev==0)', { - 'sources': [ - 'gamepad_platform_data_fetcher.cc', - ], 'sources!': [ 'gamepad_platform_data_fetcher_linux.cc', ],
diff --git a/device/gamepad/gamepad_data_fetcher.cc b/device/gamepad/gamepad_data_fetcher.cc index 749a6f3..bdd63e4 100644 --- a/device/gamepad/gamepad_data_fetcher.cc +++ b/device/gamepad/gamepad_data_fetcher.cc
@@ -4,84 +4,17 @@ #include "device/gamepad/gamepad_data_fetcher.h" -#include <stddef.h> -#include <string.h> - -#include <cmath> - -#include "base/logging.h" -#include "build/build_config.h" - -namespace { - -#if !defined(OS_ANDROID) -const float kMinAxisResetValue = 0.1f; -#endif - -} // namespace - namespace device { -using blink::WebGamepad; -using blink::WebGamepads; +GamepadDataFetcher::GamepadDataFetcher() : provider_(nullptr) {} -#if !defined(OS_ANDROID) -void GamepadDataFetcher::MapAndSanitizeGamepadData(PadState* pad_state, - WebGamepad* pad) { - DCHECK(pad_state); - DCHECK(pad); +void GamepadDataFetcher::InitializeProvider(GamepadPadStateProvider* provider) { + DCHECK(provider); - if (!pad_state->data.connected) { - memset(pad, 0, sizeof(WebGamepad)); - return; - } - - // Copy the current state to the output buffer, using the mapping - // function, if there is one available. - if (pad_state->mapper) - pad_state->mapper(pad_state->data, pad); - else - *pad = pad_state->data; - - // About sanitization: Gamepads may report input event if the user is not - // interacting with it, due to hardware problems or environmental ones (pad - // has something heavy leaning against an axis.) This may cause user gestures - // to be detected erroniously, exposing gamepad information when the user had - // no intention of doing so. To avoid this we require that each button or axis - // report being at rest (zero) at least once before exposing its value to the - // Gamepad API. This state is tracked by the axis_mask and button_mask - // bitfields. If the bit for an axis or button is 0 it means the axis has - // never reported being at rest, and the value will be forced to zero. - - // We can skip axis sanitation if all available axes have been masked. - uint32_t full_axis_mask = (1 << pad->axesLength) - 1; - if (pad_state->axis_mask != full_axis_mask) { - for (size_t axis = 0; axis < pad->axesLength; ++axis) { - if (!(pad_state->axis_mask & 1 << axis)) { - if (fabs(pad->axes[axis]) < kMinAxisResetValue) { - pad_state->axis_mask |= 1 << axis; - } else { - pad->axes[axis] = 0.0f; - } - } - } - } - - // We can skip button sanitation if all available buttons have been masked. - uint32_t full_button_mask = (1 << pad->buttonsLength) - 1; - if (pad_state->button_mask != full_button_mask) { - for (size_t button = 0; button < pad->buttonsLength; ++button) { - if (!(pad_state->button_mask & 1 << button)) { - if (!pad->buttons[button].pressed) { - pad_state->button_mask |= 1 << button; - } else { - pad->buttons[button].pressed = false; - pad->buttons[button].value = 0.0f; - } - } - } - } + provider_ = provider; + OnAddedToProvider(); } -#endif + +GamepadDataFetcherFactory::GamepadDataFetcherFactory() {} } // namespace device
diff --git a/device/gamepad/gamepad_data_fetcher.h b/device/gamepad/gamepad_data_fetcher.h index d071a25..846ba8e 100644 --- a/device/gamepad/gamepad_data_fetcher.h +++ b/device/gamepad/gamepad_data_fetcher.h
@@ -5,58 +5,67 @@ #ifndef DEVICE_GAMEPAD_GAMEPAD_DATA_FETCHER_H_ #define DEVICE_GAMEPAD_GAMEPAD_DATA_FETCHER_H_ -#include <stdint.h> - -#include <limits> - -#include "build/build_config.h" +#include "device/gamepad/gamepad_data_fetcher_manager.h" #include "device/gamepad/gamepad_export.h" -#include "device/gamepad/gamepad_standard_mappings.h" -#include "third_party/WebKit/public/platform/WebGamepads.h" +#include "device/gamepad/gamepad_pad_state_provider.h" namespace device { -// Abstract interface for imlementing platform- (and test-) specific behaviro +// Abstract interface for imlementing platform- (and test-) specific behavior // for getting the gamepad data. class DEVICE_GAMEPAD_EXPORT GamepadDataFetcher { public: + GamepadDataFetcher(); virtual ~GamepadDataFetcher() {} - virtual void GetGamepadData(blink::WebGamepads* pads, - bool devices_changed_hint) = 0; + virtual void GetGamepadData(bool devices_changed_hint) = 0; virtual void PauseHint(bool paused) {} -#if !defined(OS_ANDROID) - struct PadState { - // Gamepad data, unmapped. - blink::WebGamepad data; + virtual GamepadSource source() = 0; + GamepadPadStateProvider* provider() { return provider_; } - // Functions to map from device data to standard layout, if available. May - // be null if no mapping is available. - GamepadStandardMappingFunction mapper; + PadState* GetPadState(int source_id) { + if (!provider_) + return nullptr; - // Sanitization masks - // axis_mask and button_mask are bitfields that represent the reset state of - // each input. If a button or axis has ever reported 0 in the past the - // corresponding bit will be set to 1. - - // If we ever increase the max axis count this will need to be updated. - static_assert(blink::WebGamepad::axesLengthCap <= - std::numeric_limits<uint32_t>::digits, - "axis_mask is not large enough"); - uint32_t axis_mask; - - // If we ever increase the max button count this will need to be updated. - static_assert(blink::WebGamepad::buttonsLengthCap <= - std::numeric_limits<uint32_t>::digits, - "button_mask is not large enough"); - uint32_t button_mask; - }; - - void MapAndSanitizeGamepadData(PadState* pad_state, blink::WebGamepad* pad); + return provider_->GetPadState(source(), source_id); + } protected: - PadState pad_state_[blink::WebGamepads::itemsLengthCap]; -#endif + friend GamepadPadStateProvider; + + // To be called by the GamepadPadStateProvider on the polling thread; + void InitializeProvider(GamepadPadStateProvider* provider); + + // This call will happen on the gamepad polling thread. Any initialization + // that needs to happen on that thread should be done here, not in the + // constructor. + virtual void OnAddedToProvider(){}; + + private: + GamepadPadStateProvider* provider_; +}; + +// Factory class for creating a GamepadDataFetcher. Used by the +// GamepadDataFetcherManager. +class DEVICE_GAMEPAD_EXPORT GamepadDataFetcherFactory { + public: + GamepadDataFetcherFactory(); + virtual ~GamepadDataFetcherFactory() {} + virtual std::unique_ptr<GamepadDataFetcher> CreateDataFetcher() = 0; + virtual GamepadSource source() = 0; +}; + +// Basic factory implementation for GamepadDataFetchers without a complex +// constructor. +template <typename DataFetcherType, GamepadSource DataFetcherSource> +class GamepadDataFetcherFactoryImpl : public GamepadDataFetcherFactory { + public: + ~GamepadDataFetcherFactoryImpl() override {} + std::unique_ptr<GamepadDataFetcher> CreateDataFetcher() override { + return std::unique_ptr<GamepadDataFetcher>(new DataFetcherType()); + } + GamepadSource source() override { return DataFetcherSource; } + static GamepadSource static_source() { return DataFetcherSource; } }; } // namespace device
diff --git a/device/gamepad/gamepad_data_fetcher_manager.cc b/device/gamepad/gamepad_data_fetcher_manager.cc new file mode 100644 index 0000000..6b46eb8 --- /dev/null +++ b/device/gamepad/gamepad_data_fetcher_manager.cc
@@ -0,0 +1,63 @@ +// Copyright 2016 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 "device/gamepad/gamepad_data_fetcher_manager.h" + +#include "device/gamepad/gamepad_data_fetcher.h" +#include "device/gamepad/gamepad_platform_data_fetcher.h" + +namespace device { + +namespace { +GamepadDataFetcherManager* g_gamepad_data_fetcher_manager = 0; +} + +GamepadDataFetcherManager::GamepadDataFetcherManager() : provider_(nullptr) {} + +GamepadDataFetcherManager::~GamepadDataFetcherManager() {} + +GamepadDataFetcherManager* GamepadDataFetcherManager::GetInstance() { + if (!g_gamepad_data_fetcher_manager) { + g_gamepad_data_fetcher_manager = new GamepadDataFetcherManager; + + // Add platform specific data fetchers + AddGamepadPlatformDataFetchers(g_gamepad_data_fetcher_manager); + } + return g_gamepad_data_fetcher_manager; +} + +void GamepadDataFetcherManager::AddFactory(GamepadDataFetcherFactory* factory) { + factories_.push_back(factory); + if (provider_) { + provider_->AddGamepadDataFetcher(factory->CreateDataFetcher()); + } +} + +void GamepadDataFetcherManager::RemoveSourceFactory(GamepadSource source) { + if (provider_) + provider_->RemoveSourceGamepadDataFetcher(source); + + for (FactoryVector::iterator it = factories_.begin(); it != factories_.end(); + ++it) { + if ((*it)->source() == source) { + delete (*it); + factories_.erase(it); + } + } +} + +void GamepadDataFetcherManager::InitializeProvider(GamepadProvider* provider) { + DCHECK(!provider_); + + provider_ = provider; + for (const auto& it : factories_) { + provider_->AddGamepadDataFetcher(it->CreateDataFetcher()); + } +} + +void GamepadDataFetcherManager::ClearProvider() { + provider_ = nullptr; +} + +} // namespace device
diff --git a/device/gamepad/gamepad_data_fetcher_manager.h b/device/gamepad/gamepad_data_fetcher_manager.h new file mode 100644 index 0000000..dc2d68c --- /dev/null +++ b/device/gamepad/gamepad_data_fetcher_manager.h
@@ -0,0 +1,47 @@ +// Copyright 2016 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 DEVICE_GAMEPAD_GAMEPAD_DATA_FETCHER_MANAGER_H_ +#define DEVICE_GAMEPAD_GAMEPAD_DATA_FETCHER_MANAGER_H_ + +#include <memory> +#include <utility> +#include <vector> + +#include "device/gamepad/gamepad_export.h" +#include "device/gamepad/gamepad_provider.h" + +namespace device { + +class GamepadDataFetcherFactory; + +class DEVICE_GAMEPAD_EXPORT GamepadDataFetcherManager { + public: + ~GamepadDataFetcherManager(); + + // Returns the GamepadDataFetcherManager singleton. + static GamepadDataFetcherManager* GetInstance(); + + void AddFactory(GamepadDataFetcherFactory* factory); + void RemoveSourceFactory(GamepadSource source); + + // Must be called on the providers polling thread + void InitializeProvider(GamepadProvider* provider); + void ClearProvider(); + + private: + GamepadDataFetcherManager(); + + void CreateDataFetcherFromFactory(GamepadDataFetcherFactory* factory); + void RemoveSourceDataFetcher(GamepadSource* source); + + typedef std::vector<GamepadDataFetcherFactory*> FactoryVector; + FactoryVector factories_; + + GamepadProvider* provider_; +}; + +} // namespace device + +#endif // DEVICE_GAMEPAD_GAMEPAD_DATA_FETCHER_MANAGER_H_
diff --git a/device/gamepad/gamepad_pad_state_provider.cc b/device/gamepad/gamepad_pad_state_provider.cc new file mode 100644 index 0000000..892fd4d --- /dev/null +++ b/device/gamepad/gamepad_pad_state_provider.cc
@@ -0,0 +1,126 @@ +// Copyright 2016 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 "device/gamepad/gamepad_pad_state_provider.h" + +#include <cmath> + +#include "device/gamepad/gamepad_data_fetcher.h" +#include "third_party/WebKit/public/platform/WebGamepads.h" + +using blink::WebGamepad; +using blink::WebGamepads; + +namespace device { + +namespace { + +const float kMinAxisResetValue = 0.1f; + +} // namespace + +GamepadPadStateProvider::GamepadPadStateProvider() { + pad_states_.reset(new PadState[WebGamepads::itemsLengthCap]); + + for (unsigned i = 0; i < WebGamepads::itemsLengthCap; ++i) + ClearPadState(pad_states_.get()[i]); +} + +GamepadPadStateProvider::~GamepadPadStateProvider() {} + +PadState* GamepadPadStateProvider::GetPadState(GamepadSource source, + int source_id) { + // Check to see if the device already has a reserved slot + PadState* empty_slot = nullptr; + for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { + PadState& state = pad_states_.get()[i]; + if (state.source == source && state.source_id == source_id) { + // Retrieving the pad state marks this gamepad as active. + state.active_state = GAMEPAD_ACTIVE; + return &state; + } + if (!empty_slot && state.source == GAMEPAD_SOURCE_NONE) + empty_slot = &state; + } + if (empty_slot) { + empty_slot->source = source; + empty_slot->source_id = source_id; + empty_slot->active_state = GAMEPAD_NEWLY_ACTIVE; + } + return empty_slot; +} + +void GamepadPadStateProvider::ClearPadState(PadState& state) { + memset(&state, 0, sizeof(PadState)); +} + +void GamepadPadStateProvider::InitializeDataFetcher( + GamepadDataFetcher* fetcher) { + fetcher->InitializeProvider(this); +} + +void GamepadPadStateProvider::MapAndSanitizeGamepadData(PadState* pad_state, + WebGamepad* pad, + bool sanitize) { + DCHECK(pad_state); + DCHECK(pad); + + if (!pad_state->data.connected) { + memset(pad, 0, sizeof(WebGamepad)); + return; + } + + // Copy the current state to the output buffer, using the mapping + // function, if there is one available. + if (pad_state->mapper) + pad_state->mapper(pad_state->data, pad); + else + *pad = pad_state->data; + + pad->connected = true; + + if (!sanitize) + return; + + // About sanitization: Gamepads may report input event if the user is not + // interacting with it, due to hardware problems or environmental ones (pad + // has something heavy leaning against an axis.) This may cause user gestures + // to be detected erroniously, exposing gamepad information when the user had + // no intention of doing so. To avoid this we require that each button or axis + // report being at rest (zero) at least once before exposing its value to the + // Gamepad API. This state is tracked by the axis_mask and button_mask + // bitfields. If the bit for an axis or button is 0 it means the axis has + // never reported being at rest, and the value will be forced to zero. + + // We can skip axis sanitation if all available axes have been masked. + uint32_t full_axis_mask = (1 << pad->axesLength) - 1; + if (pad_state->axis_mask != full_axis_mask) { + for (size_t axis = 0; axis < pad->axesLength; ++axis) { + if (!(pad_state->axis_mask & 1 << axis)) { + if (fabs(pad->axes[axis]) < kMinAxisResetValue) { + pad_state->axis_mask |= 1 << axis; + } else { + pad->axes[axis] = 0.0f; + } + } + } + } + + // We can skip button sanitation if all available buttons have been masked. + uint32_t full_button_mask = (1 << pad->buttonsLength) - 1; + if (pad_state->button_mask != full_button_mask) { + for (size_t button = 0; button < pad->buttonsLength; ++button) { + if (!(pad_state->button_mask & 1 << button)) { + if (!pad->buttons[button].pressed) { + pad_state->button_mask |= 1 << button; + } else { + pad->buttons[button].pressed = false; + pad->buttons[button].value = 0.0f; + } + } + } + } +} + +} // namespace device \ No newline at end of file
diff --git a/device/gamepad/gamepad_pad_state_provider.h b/device/gamepad/gamepad_pad_state_provider.h new file mode 100644 index 0000000..1c250322 --- /dev/null +++ b/device/gamepad/gamepad_pad_state_provider.h
@@ -0,0 +1,97 @@ +// Copyright 2016 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 DEVICE_GAMEPAD_GAMEPAD_PAD_STATE_PROVIDER_H_ +#define DEVICE_GAMEPAD_GAMEPAD_PAD_STATE_PROVIDER_H_ + +#include <stdint.h> + +#include <limits> +#include <memory> + +#include "device/gamepad/gamepad_export.h" +#include "device/gamepad/gamepad_standard_mappings.h" +#include "third_party/WebKit/public/platform/WebGamepad.h" + +namespace device { + +class GamepadDataFetcher; + +enum GamepadSource { + GAMEPAD_SOURCE_NONE = 0, + GAMEPAD_SOURCE_ANDROID, + GAMEPAD_SOURCE_LINUX_UDEV, + GAMEPAD_SOURCE_MAC_HID, + GAMEPAD_SOURCE_MAC_XBOX, + GAMEPAD_SOURCE_TEST, + GAMEPAD_SOURCE_WIN_XINPUT, + GAMEPAD_SOURCE_WIN_RAW, +}; + +enum GamepadActiveState { + GAMEPAD_INACTIVE = 0, + GAMEPAD_ACTIVE, + GAMEPAD_NEWLY_ACTIVE, +}; + +struct PadState { + // Which data fetcher provided this gamepad's data. + GamepadSource source; + // Data fetcher-specific identifier for this gamepad. + int source_id; + + // Indicates whether or not the gamepad is actively being updated + GamepadActiveState active_state; + + // Gamepad data, unmapped. + blink::WebGamepad data; + + // Functions to map from device data to standard layout, if available. May + // be null if no mapping is available or needed. + GamepadStandardMappingFunction mapper; + + // Sanitization masks + // axis_mask and button_mask are bitfields that represent the reset state of + // each input. If a button or axis has ever reported 0 in the past the + // corresponding bit will be set to 1. + + // If we ever increase the max axis count this will need to be updated. + static_assert(blink::WebGamepad::axesLengthCap <= + std::numeric_limits<uint32_t>::digits, + "axis_mask is not large enough"); + uint32_t axis_mask; + + // If we ever increase the max button count this will need to be updated. + static_assert(blink::WebGamepad::buttonsLengthCap <= + std::numeric_limits<uint32_t>::digits, + "button_mask is not large enough"); + uint32_t button_mask; +}; + +class DEVICE_GAMEPAD_EXPORT GamepadPadStateProvider { + public: + GamepadPadStateProvider(); + virtual ~GamepadPadStateProvider(); + + // Gets a PadState object for the given source and id. If the device hasn't + // been encountered before one of the remaining slots will be reserved for it. + // If no slots are available will return NULL. + PadState* GetPadState(GamepadSource source, int source_id); + + protected: + void ClearPadState(PadState& state); + + void InitializeDataFetcher(GamepadDataFetcher* fetcher); + + void MapAndSanitizeGamepadData(PadState* pad_state, + blink::WebGamepad* pad, + bool sanitize); + + // Tracks the state of each gamepad slot. + std::unique_ptr<PadState[]> pad_states_; +}; + +} // namespace device + +#endif // DEVICE_GAMEPAD_GAMEPAD_PAD_STATE_PROVIDER_H_
diff --git a/device/gamepad/gamepad_platform_data_fetcher.cc b/device/gamepad/gamepad_platform_data_fetcher.cc deleted file mode 100644 index 2edcc6ae..0000000 --- a/device/gamepad/gamepad_platform_data_fetcher.cc +++ /dev/null
@@ -1,18 +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 "device/gamepad/gamepad_platform_data_fetcher.h" - -#include "third_party/WebKit/public/platform/WebGamepads.h" - -namespace device { - -GamepadDataFetcherEmpty::GamepadDataFetcherEmpty() {} - -void GamepadDataFetcherEmpty::GetGamepadData(blink::WebGamepads* pads, - bool devices_changed_hint) { - pads->length = 0; -} - -} // namespace device
diff --git a/device/gamepad/gamepad_platform_data_fetcher.h b/device/gamepad/gamepad_platform_data_fetcher.h index 32ef34f..9dcdd0e6 100644 --- a/device/gamepad/gamepad_platform_data_fetcher.h +++ b/device/gamepad/gamepad_platform_data_fetcher.h
@@ -8,54 +8,49 @@ #ifndef DEVICE_GAMEPAD_GAMEPAD_PLATFORM_DATA_FETCHER_H_ #define DEVICE_GAMEPAD_GAMEPAD_PLATFORM_DATA_FETCHER_H_ +#include <memory> + #include "base/compiler_specific.h" #include "base/macros.h" #include "build/build_config.h" #include "device/gamepad/gamepad_data_fetcher.h" +#include "device/gamepad/gamepad_data_fetcher_manager.h" #if defined(OS_ANDROID) #include "device/gamepad/gamepad_platform_data_fetcher_android.h" #elif defined(OS_WIN) #include "device/gamepad/gamepad_platform_data_fetcher_win.h" +#include "device/gamepad/raw_input_data_fetcher_win.h" #elif defined(OS_MACOSX) #include "device/gamepad/gamepad_platform_data_fetcher_mac.h" +#include "device/gamepad/xbox_data_fetcher_mac.h" #elif defined(OS_LINUX) #include "device/gamepad/gamepad_platform_data_fetcher_linux.h" #endif namespace device { +void AddGamepadPlatformDataFetchers(GamepadDataFetcherManager* manager) { #if defined(OS_ANDROID) -typedef GamepadPlatformDataFetcherAndroid GamepadPlatformDataFetcher; + manager->AddFactory(new GamepadPlatformDataFetcherAndroid::Factory()); #elif defined(OS_WIN) -typedef GamepadPlatformDataFetcherWin GamepadPlatformDataFetcher; + manager->AddFactory(new GamepadPlatformDataFetcherWin::Factory()); + manager->AddFactory(new RawInputDataFetcher::Factory()); #elif defined(OS_MACOSX) -typedef GamepadPlatformDataFetcherMac GamepadPlatformDataFetcher; + manager->AddFactory(new GamepadPlatformDataFetcherMac::Factory()); + manager->AddFactory(new XboxDataFetcher::Factory()); #elif defined(OS_LINUX) && defined(USE_UDEV) -typedef GamepadPlatformDataFetcherLinux GamepadPlatformDataFetcher; - -#else - -class GamepadDataFetcherEmpty : public GamepadDataFetcher { - public: - GamepadDataFetcherEmpty(); - - void GetGamepadData(blink::WebGamepads* pads, - bool devices_changed_hint) override; - - private: - DISALLOW_COPY_AND_ASSIGN(GamepadDataFetcherEmpty); -}; -typedef GamepadDataFetcherEmpty GamepadPlatformDataFetcher; + manager->AddFactory(new GamepadPlatformDataFetcherLinux::Factory()); #endif +} } // namespace device
diff --git a/device/gamepad/gamepad_platform_data_fetcher_android.cc b/device/gamepad/gamepad_platform_data_fetcher_android.cc index 2a45658..1d5220f 100644 --- a/device/gamepad/gamepad_platform_data_fetcher_android.cc +++ b/device/gamepad/gamepad_platform_data_fetcher_android.cc
@@ -35,25 +35,29 @@ } GamepadPlatformDataFetcherAndroid::GamepadPlatformDataFetcherAndroid() { - PauseHint(false); } GamepadPlatformDataFetcherAndroid::~GamepadPlatformDataFetcherAndroid() { PauseHint(true); } +GamepadSource GamepadPlatformDataFetcherAndroid::source() { + return Factory::static_source(); +} + +void GamepadPlatformDataFetcherAndroid::OnAddedToProvider() { + PauseHint(false); +} + void GamepadPlatformDataFetcherAndroid::GetGamepadData( - blink::WebGamepads* pads, bool devices_changed_hint) { TRACE_EVENT0("GAMEPAD", "GetGamepadData"); - pads->length = 0; - JNIEnv* env = AttachCurrentThread(); if (!env) return; - Java_GamepadList_updateGamepadData(env, reinterpret_cast<intptr_t>(pads)); + Java_GamepadList_updateGamepadData(env, reinterpret_cast<intptr_t>(this)); } void GamepadPlatformDataFetcherAndroid::PauseHint(bool paused) { @@ -66,7 +70,7 @@ static void SetGamepadData(JNIEnv* env, const JavaParamRef<jobject>& obj, - jlong gamepads, + jlong data_fetcher, jint index, jboolean mapping, jboolean connected, @@ -74,45 +78,44 @@ jlong timestamp, const JavaParamRef<jfloatArray>& jaxes, const JavaParamRef<jfloatArray>& jbuttons) { - DCHECK(gamepads); - blink::WebGamepads* pads = reinterpret_cast<WebGamepads*>(gamepads); - DCHECK_EQ(pads->length, unsigned(index)); + DCHECK(data_fetcher); + GamepadPlatformDataFetcherAndroid* fetcher = + reinterpret_cast<GamepadPlatformDataFetcherAndroid*>(data_fetcher); DCHECK_LT(index, static_cast<int>(blink::WebGamepads::itemsLengthCap)); - ++pads->length; - - blink::WebGamepad& pad = pads->items[index]; - - pad.connected = connected; - - pad.timestamp = timestamp; - // Do not set gamepad parameters for all the gamepad devices that are not // attached. if (!connected) return; - // Map the Gamepad DeviceName String to the WebGamepad Id. Ideally it should - // be mapped to vendor and product information but it is only available at - // kernel level and it can not be queried using class - // android.hardware.input.InputManager. - // TODO(SaurabhK): Store a cached WebGamePad object in - // GamepadPlatformDataFetcherAndroid and only update constant WebGamepad - // values when a device has changed. - base::string16 device_name; - base::android::ConvertJavaStringToUTF16(env, devicename, &device_name); - const size_t name_to_copy = - std::min(device_name.size(), WebGamepad::idLengthCap - 1); - memcpy(pad.id, device_name.data(), - name_to_copy * sizeof(base::string16::value_type)); - pad.id[name_to_copy] = 0; + PadState* state = fetcher->GetPadState(index); - base::string16 mapping_name = base::UTF8ToUTF16(mapping ? "standard" : ""); - const size_t mapping_to_copy = - std::min(mapping_name.size(), WebGamepad::mappingLengthCap - 1); - memcpy(pad.mapping, mapping_name.data(), - mapping_to_copy * sizeof(base::string16::value_type)); - pad.mapping[mapping_to_copy] = 0; + if (!state) + return; + + blink::WebGamepad& pad = state->data; + + // Is this the first time we've seen this device? + if (state->active_state == GAMEPAD_NEWLY_ACTIVE) { + // Map the Gamepad DeviceName String to the WebGamepad Id. Ideally it should + // be mapped to vendor and product information but it is only available at + // kernel level and it can not be queried using class + // android.hardware.input.InputManager. + base::string16 device_name; + base::android::ConvertJavaStringToUTF16(env, devicename, &device_name); + const size_t name_to_copy = + std::min(device_name.size(), WebGamepad::idLengthCap - 1); + memcpy(pad.id, device_name.data(), + name_to_copy * sizeof(base::string16::value_type)); + pad.id[name_to_copy] = 0; + + base::string16 mapping_name = base::UTF8ToUTF16(mapping ? "standard" : ""); + const size_t mapping_to_copy = + std::min(mapping_name.size(), WebGamepad::mappingLengthCap - 1); + memcpy(pad.mapping, mapping_name.data(), + mapping_to_copy * sizeof(base::string16::value_type)); + pad.mapping[mapping_to_copy] = 0; + } pad.timestamp = timestamp;
diff --git a/device/gamepad/gamepad_platform_data_fetcher_android.h b/device/gamepad/gamepad_platform_data_fetcher_android.h index 1038418..760ef9b 100644 --- a/device/gamepad/gamepad_platform_data_fetcher_android.h +++ b/device/gamepad/gamepad_platform_data_fetcher_android.h
@@ -21,18 +21,25 @@ class GamepadPlatformDataFetcherAndroid : public GamepadDataFetcher { public: + typedef GamepadDataFetcherFactoryImpl<GamepadPlatformDataFetcherAndroid, + GAMEPAD_SOURCE_ANDROID> + Factory; + GamepadPlatformDataFetcherAndroid(); ~GamepadPlatformDataFetcherAndroid() override; + GamepadSource source() override; + void PauseHint(bool paused) override; - void GetGamepadData(blink::WebGamepads* pads, - bool devices_changed_hint) override; + void GetGamepadData(bool devices_changed_hint) override; // Registers the JNI methods for GamepadsReader. static bool RegisterGamepadPlatformDataFetcherAndroid(JNIEnv* env); private: + void OnAddedToProvider() override; + DISALLOW_COPY_AND_ASSIGN(GamepadPlatformDataFetcherAndroid); };
diff --git a/device/gamepad/gamepad_platform_data_fetcher_linux.cc b/device/gamepad/gamepad_platform_data_fetcher_linux.cc index 4781a8f..5fe3e43 100644 --- a/device/gamepad/gamepad_platform_data_fetcher_linux.cc +++ b/device/gamepad/gamepad_platform_data_fetcher_linux.cc
@@ -11,8 +11,6 @@ #include <sys/types.h> #include <unistd.h> -#include "base/macros.h" -#include "base/message_loop/message_loop.h" #include "base/posix/eintr_wrapper.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -70,13 +68,21 @@ using blink::WebGamepads; GamepadPlatformDataFetcherLinux::GamepadPlatformDataFetcherLinux() { - for (size_t i = 0; i < arraysize(pad_state_); ++i) { + for (size_t i = 0; i < arraysize(device_fd_); ++i) { device_fd_[i] = -1; - pad_state_[i].mapper = 0; - pad_state_[i].axis_mask = 0; - pad_state_[i].button_mask = 0; } +} +GamepadPlatformDataFetcherLinux::~GamepadPlatformDataFetcherLinux() { + for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) + CloseFileDescriptorIfValid(device_fd_[i]); +} + +GamepadSource GamepadPlatformDataFetcherLinux::source() { + return Factory::static_source(); +} + +void GamepadPlatformDataFetcherLinux::OnAddedToProvider() { std::vector<UdevLinux::UdevMonitorFilter> filters; filters.push_back(UdevLinux::UdevMonitorFilter(kInputSubsystem, NULL)); udev_.reset(new UdevLinux( @@ -86,12 +92,7 @@ EnumerateDevices(); } -GamepadPlatformDataFetcherLinux::~GamepadPlatformDataFetcherLinux() { - for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) - CloseFileDescriptorIfValid(device_fd_[i]); -} - -void GamepadPlatformDataFetcherLinux::GetGamepadData(WebGamepads* pads, bool) { +void GamepadPlatformDataFetcherLinux::GetGamepadData(bool) { TRACE_EVENT0("GAMEPAD", "GetGamepadData"); // Update our internal state. @@ -100,11 +101,6 @@ ReadDeviceData(i); } } - - pads->length = WebGamepads::itemsLengthCap; - for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { - MapAndSanitizeGamepadData(&pad_state_[i], &pads->items[i]); - } } // Used during enumeration, and monitor notifications. @@ -113,8 +109,6 @@ std::string node_path; if (IsGamepad(dev, &index, &node_path)) { int& device_fd = device_fd_[index]; - WebGamepad& pad = pad_state_[index].data; - GamepadStandardMappingFunction& mapper = pad_state_[index].mapper; CloseFileDescriptorIfValid(device_fd); @@ -127,17 +121,26 @@ if (!dev) { // Unable to get device information, don't use this device. device_fd = -1; - pad.connected = false; return; } device_fd = HANDLE_EINTR(open(node_path.c_str(), O_RDONLY | O_NONBLOCK)); if (device_fd < 0) { // Unable to open device, don't use. - pad.connected = false; return; } + PadState* state = GetPadState(index); + if (!state) { + // No slot available for device, don't use. + CloseFileDescriptorIfValid(device_fd); + device_fd = -1; + return; + } + + WebGamepad& pad = state->data; + GamepadStandardMappingFunction& mapper = state->mapper; + const char* vendor_id = udev_device_get_sysattr_value(dev, "id/vendor"); const char* product_id = udev_device_get_sysattr_value(dev, "id/product"); mapper = GetGamepadStandardMappingFunction(vendor_id, product_id); @@ -194,9 +197,6 @@ pad.mapping[0] = 0; } - pad_state_[index].axis_mask = 0; - pad_state_[index].button_mask = 0; - pad.connected = true; } } @@ -234,10 +234,15 @@ return; } - const int& fd = device_fd_[index]; - WebGamepad& pad = pad_state_[index].data; + PadState* state = GetPadState(index); + if (!state) + return; + + int fd = device_fd_[index]; DCHECK_GE(fd, 0); + WebGamepad& pad = state->data; + js_event event; while (HANDLE_EINTR(read(fd, &event, sizeof(struct js_event))) > 0) { size_t item = event.number;
diff --git a/device/gamepad/gamepad_platform_data_fetcher_linux.h b/device/gamepad/gamepad_platform_data_fetcher_linux.h index a3160f0b2..76361ef 100644 --- a/device/gamepad/gamepad_platform_data_fetcher_linux.h +++ b/device/gamepad/gamepad_platform_data_fetcher_linux.h
@@ -27,14 +27,21 @@ class DEVICE_GAMEPAD_EXPORT GamepadPlatformDataFetcherLinux : public GamepadDataFetcher { public: + typedef GamepadDataFetcherFactoryImpl<GamepadPlatformDataFetcherLinux, + GAMEPAD_SOURCE_LINUX_UDEV> + Factory; + GamepadPlatformDataFetcherLinux(); ~GamepadPlatformDataFetcherLinux() override; + GamepadSource source() override; + // GamepadDataFetcher implementation. - void GetGamepadData(blink::WebGamepads* pads, - bool devices_changed_hint) override; + void GetGamepadData(bool devices_changed_hint) override; private: + void OnAddedToProvider() override; + void RefreshDevice(udev_device* dev); void EnumerateDevices(); void ReadDeviceData(size_t index);
diff --git a/device/gamepad/gamepad_platform_data_fetcher_mac.h b/device/gamepad/gamepad_platform_data_fetcher_mac.h index 36377f7..7b126ac 100644 --- a/device/gamepad/gamepad_platform_data_fetcher_mac.h +++ b/device/gamepad/gamepad_platform_data_fetcher_mac.h
@@ -16,7 +16,6 @@ #include "base/macros.h" #include "build/build_config.h" #include "device/gamepad/gamepad_data_fetcher.h" -#include "device/gamepad/xbox_data_fetcher_mac.h" #if defined(__OBJC__) @class NSArray; @@ -26,13 +25,18 @@ namespace device { -class GamepadPlatformDataFetcherMac : public GamepadDataFetcher, - public XboxDataFetcher::Delegate { +class GamepadPlatformDataFetcherMac : public GamepadDataFetcher { public: + typedef GamepadDataFetcherFactoryImpl<GamepadPlatformDataFetcherMac, + GAMEPAD_SOURCE_MAC_HID> + Factory; + GamepadPlatformDataFetcherMac(); ~GamepadPlatformDataFetcherMac() override; - void GetGamepadData(blink::WebGamepads* pads, - bool devices_changed_hint) override; + + GamepadSource source() override; + + void GetGamepadData(bool devices_changed_hint) override; void PauseHint(bool paused) override; private: @@ -54,46 +58,30 @@ void* sender, IOHIDValueRef ref); + void OnAddedToProvider() override; + size_t GetEmptySlot(); size_t GetSlotForDevice(IOHIDDeviceRef device); - size_t GetSlotForXboxDevice(XboxController* device); void DeviceAdd(IOHIDDeviceRef device); bool CheckCollection(IOHIDElementRef element); - bool AddButtonsAndAxes(NSArray* elements, size_t slot); + bool AddButtonsAndAxes(NSArray* elements, PadState* state, size_t slot); void DeviceRemove(IOHIDDeviceRef device); void ValueChanged(IOHIDValueRef value); - void XboxDeviceAdd(XboxController* device) override; - void XboxDeviceRemove(XboxController* device) override; - void XboxValueChanged(XboxController* device, - const XboxController::Data& data) override; - void RegisterForNotifications(); void UnregisterFromNotifications(); - void SanitizeGamepadData(size_t index, blink::WebGamepad* pad); - - std::unique_ptr<XboxDataFetcher> xbox_fetcher_; - // Side-band data that's not passed to the consumer, but we need to maintain // to update data_. struct AssociatedData { - bool is_xbox; - union { - struct { - IOHIDDeviceRef device_ref; - IOHIDElementRef button_elements[blink::WebGamepad::buttonsLengthCap]; - IOHIDElementRef axis_elements[blink::WebGamepad::axesLengthCap]; - CFIndex axis_minimums[blink::WebGamepad::axesLengthCap]; - CFIndex axis_maximums[blink::WebGamepad::axesLengthCap]; - CFIndex axis_report_sizes[blink::WebGamepad::axesLengthCap]; - } hid; - struct { - XboxController* device; - UInt32 location_id; - } xbox; - }; + int location_id; + IOHIDDeviceRef device_ref; + IOHIDElementRef button_elements[blink::WebGamepad::buttonsLengthCap]; + IOHIDElementRef axis_elements[blink::WebGamepad::axesLengthCap]; + CFIndex axis_minimums[blink::WebGamepad::axesLengthCap]; + CFIndex axis_maximums[blink::WebGamepad::axesLengthCap]; + CFIndex axis_report_sizes[blink::WebGamepad::axesLengthCap]; }; AssociatedData associated_[blink::WebGamepads::itemsLengthCap];
diff --git a/device/gamepad/gamepad_platform_data_fetcher_mac.mm b/device/gamepad/gamepad_platform_data_fetcher_mac.mm index 60c57dd7..3c9f4abc 100644 --- a/device/gamepad/gamepad_platform_data_fetcher_mac.mm +++ b/device/gamepad/gamepad_platform_data_fetcher_mac.mm
@@ -74,11 +74,13 @@ GamepadPlatformDataFetcherMac::GamepadPlatformDataFetcherMac() : enabled_(true), paused_(false) { memset(associated_, 0, sizeof(associated_)); +} - xbox_fetcher_.reset(new XboxDataFetcher(this)); - if (!xbox_fetcher_->RegisterForNotifications()) - xbox_fetcher_.reset(); +GamepadSource GamepadPlatformDataFetcherMac::source() { + return Factory::static_source(); +} +void GamepadPlatformDataFetcherMac::OnAddedToProvider() { hid_manager_ref_.reset( IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone)); if (CFGetTypeID(hid_manager_ref_) != IOHIDManagerGetTypeID()) { @@ -116,17 +118,12 @@ enabled_ = IOHIDManagerOpen(hid_manager_ref_, kIOHIDOptionsTypeNone) == kIOReturnSuccess; - - if (xbox_fetcher_) - xbox_fetcher_->RegisterForNotifications(); } void GamepadPlatformDataFetcherMac::UnregisterFromNotifications() { IOHIDManagerUnscheduleFromRunLoop(hid_manager_ref_, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); IOHIDManagerClose(hid_manager_ref_, kIOHIDOptionsTypeNone); - if (xbox_fetcher_) - xbox_fetcher_->UnregisterFromNotifications(); } void GamepadPlatformDataFetcherMac::PauseHint(bool pause) { @@ -180,10 +177,10 @@ } bool GamepadPlatformDataFetcherMac::AddButtonsAndAxes(NSArray* elements, + PadState* state, size_t slot) { - WebGamepad& pad = pad_state_[slot].data; + WebGamepad& pad = state->data; AssociatedData& associated = associated_[slot]; - CHECK(!associated.is_xbox); pad.axesLength = 0; pad.buttonsLength = 0; @@ -204,13 +201,13 @@ usage_page == kButtonUsagePage) { uint32_t button_index = usage - 1; if (button_index < WebGamepad::buttonsLengthCap) { - associated.hid.button_elements[button_index] = element; + associated.button_elements[button_index] = element; pad.buttonsLength = std::max(pad.buttonsLength, button_index + 1); } } else if (IOHIDElementGetType(element) == kIOHIDElementTypeInput_Misc) { uint32_t axis_index = usage - kAxisMinimumUsageNumber; if (axis_index < WebGamepad::axesLengthCap) { - associated.hid.axis_elements[axis_index] = element; + associated.axis_elements[axis_index] = element; pad.axesLength = std::max(pad.axesLength, axis_index + 1); } else { mapped_all_axes = false; @@ -232,11 +229,11 @@ usage - kAxisMinimumUsageNumber >= WebGamepad::axesLengthCap && usage_page <= kGameControlsUsagePage) { for (; next_index < WebGamepad::axesLengthCap; ++next_index) { - if (associated.hid.axis_elements[next_index] == NULL) + if (associated.axis_elements[next_index] == NULL) break; } if (next_index < WebGamepad::axesLengthCap) { - associated.hid.axis_elements[next_index] = element; + associated.axis_elements[next_index] = element; pad.axesLength = std::max(pad.axesLength, next_index + 1); } } @@ -247,7 +244,7 @@ } for (uint32_t axis_index = 0; axis_index < pad.axesLength; ++axis_index) { - IOHIDElementRef element = associated.hid.axis_elements[axis_index]; + IOHIDElementRef element = associated.axis_elements[axis_index]; if (element != NULL) { CFIndex axis_min = IOHIDElementGetLogicalMin(element); CFIndex axis_max = IOHIDElementGetLogicalMax(element); @@ -259,9 +256,9 @@ axis_min = 0; } - associated.hid.axis_minimums[axis_index] = axis_min; - associated.hid.axis_maximums[axis_index] = axis_max; - associated.hid.axis_report_sizes[axis_index] = + associated.axis_minimums[axis_index] = axis_min; + associated.axis_maximums[axis_index] = axis_max; + associated.axis_report_sizes[axis_index] = IOHIDElementGetReportSize(element); } } @@ -272,7 +269,7 @@ size_t GamepadPlatformDataFetcherMac::GetEmptySlot() { // Find a free slot for this device. for (size_t slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { - if (!pad_state_[slot].data.connected) + if (associated_[slot].device_ref == nullptr) return slot; } return WebGamepads::itemsLengthCap; @@ -282,33 +279,12 @@ for (size_t slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { // If we already have this device, and it's already connected, don't do // anything now. - if (pad_state_[slot].data.connected && !associated_[slot].is_xbox && - associated_[slot].hid.device_ref == device) + if (associated_[slot].device_ref == device) return WebGamepads::itemsLengthCap; } return GetEmptySlot(); } -size_t GamepadPlatformDataFetcherMac::GetSlotForXboxDevice( - XboxController* device) { - for (size_t slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { - if (associated_[slot].is_xbox && - associated_[slot].xbox.location_id == device->location_id()) { - if (pad_state_[slot].data.connected) { - // The device is already connected. No idea why we got a second "device - // added" call, but let's not add it twice. - DCHECK_EQ(associated_[slot].xbox.device, device); - return WebGamepads::itemsLengthCap; - } else { - // A device with the same location ID was previously connected, so put - // it in the same slot. - return slot; - } - } - } - return GetEmptySlot(); -} - void GamepadPlatformDataFetcherMac::DeviceAdd(IOHIDDeviceRef device) { using base::mac::CFToNSCast; using base::mac::CFCastStrict; @@ -316,6 +292,10 @@ if (!enabled_) return; + NSNumber* location_id = CFToNSCast(CFCastStrict<CFNumberRef>( + IOHIDDeviceGetProperty(device, CFSTR(kIOHIDLocationIDKey)))); + int location_int = [location_id intValue]; + // Find an index for this device. size_t slot = GetSlotForDevice(device); @@ -326,6 +306,10 @@ // Clear some state that may have been left behind by previous gamepads memset(&associated_[slot], 0, sizeof(AssociatedData)); + PadState* state = GetPadState(location_int); + if (!state) + return; // No available slot for this device + NSNumber* vendor_id = CFToNSCast(CFCastStrict<CFNumberRef>( IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey)))); NSNumber* product_id = CFToNSCast(CFCastStrict<CFNumberRef>( @@ -338,33 +322,32 @@ char vendor_as_str[5], product_as_str[5]; snprintf(vendor_as_str, sizeof(vendor_as_str), "%04x", vendor_int); snprintf(product_as_str, sizeof(product_as_str), "%04x", product_int); - pad_state_[slot].mapper = + state->mapper = GetGamepadStandardMappingFunction(vendor_as_str, product_as_str); - NSString* ident = [NSString - stringWithFormat:@"%@ (%sVendor: %04x Product: %04x)", product, - pad_state_[slot].mapper ? "STANDARD GAMEPAD " : "", - vendor_int, product_int]; - CopyNSStringAsUTF16LittleEndian(ident, pad_state_[slot].data.id, - sizeof(pad_state_[slot].data.id)); + NSString* ident = + [NSString stringWithFormat:@"%@ (%sVendor: %04x Product: %04x)", product, + state->mapper ? "STANDARD GAMEPAD " : "", + vendor_int, product_int]; + CopyNSStringAsUTF16LittleEndian(ident, state->data.id, + sizeof(state->data.id)); - if (pad_state_[slot].mapper) { - CopyNSStringAsUTF16LittleEndian(@"standard", pad_state_[slot].data.mapping, - sizeof(pad_state_[slot].data.mapping)); + if (state->mapper) { + CopyNSStringAsUTF16LittleEndian(@"standard", state->data.mapping, + sizeof(state->data.mapping)); } else { - pad_state_[slot].data.mapping[0] = 0; + state->data.mapping[0] = 0; } base::ScopedCFTypeRef<CFArrayRef> elements( IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone)); - if (!AddButtonsAndAxes(CFToNSCast(elements), slot)) + if (!AddButtonsAndAxes(CFToNSCast(elements), state, slot)) return; - associated_[slot].hid.device_ref = device; - pad_state_[slot].data.connected = true; - pad_state_[slot].axis_mask = 0; - pad_state_[slot].button_mask = 0; + associated_[slot].location_id = location_int; + associated_[slot].device_ref = device; + state->data.connected = true; } void GamepadPlatformDataFetcherMac::DeviceRemove(IOHIDDeviceRef device) { @@ -374,14 +357,14 @@ // Find the index for this device. size_t slot; for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { - if (pad_state_[slot].data.connected && !associated_[slot].is_xbox && - associated_[slot].hid.device_ref == device) + if (associated_[slot].device_ref == device) break; } DCHECK(slot < WebGamepads::itemsLengthCap); // Leave associated device_ref so that it will be reconnected in the same // location. Simply mark it as disconnected. - pad_state_[slot].data.connected = false; + associated_[slot].location_id = 0; + associated_[slot].device_ref = nullptr; } void GamepadPlatformDataFetcherMac::ValueChanged(IOHIDValueRef value) { @@ -394,14 +377,17 @@ // Find device slot. size_t slot; for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { - if (pad_state_[slot].data.connected && !associated_[slot].is_xbox && - associated_[slot].hid.device_ref == device) + if (associated_[slot].device_ref == device) break; } if (slot == WebGamepads::itemsLengthCap) return; - WebGamepad& pad = pad_state_[slot].data; + PadState* state = GetPadState(associated_[slot].location_id); + if (!state) + return; + + WebGamepad& pad = state->data; AssociatedData& associated = associated_[slot]; uint32_t value_length = IOHIDValueGetLength(value); @@ -413,7 +399,7 @@ // Find and fill in the associated button event, if any. for (size_t i = 0; i < pad.buttonsLength; ++i) { - if (associated.hid.button_elements[i] == element) { + if (associated.button_elements[i] == element) { pad.buttons[i].pressed = IOHIDValueGetIntegerValue(value); pad.buttons[i].value = pad.buttons[i].pressed ? 1.f : 0.f; pad.timestamp = std::max(pad.timestamp, IOHIDValueGetTimeStamp(value)); @@ -423,14 +409,14 @@ // Find and fill in the associated axis event, if any. for (size_t i = 0; i < pad.axesLength; ++i) { - if (associated.hid.axis_elements[i] == element) { - CFIndex axis_min = associated.hid.axis_minimums[i]; - CFIndex axis_max = associated.hid.axis_maximums[i]; + if (associated.axis_elements[i] == element) { + CFIndex axis_min = associated.axis_minimums[i]; + CFIndex axis_max = associated.axis_maximums[i]; CFIndex axis_value = IOHIDValueGetIntegerValue(value); if (axis_min > axis_max) { // We'll need to interpret this axis as unsigned during normalization. - switch (associated.hid.axis_report_sizes[i]) { + switch (associated.axis_report_sizes[i]) { case 8: pad.axes[i] = NormalizeUInt8Axis(axis_value, axis_min, axis_max); break; @@ -451,104 +437,16 @@ } } -void GamepadPlatformDataFetcherMac::XboxDeviceAdd(XboxController* device) { +void GamepadPlatformDataFetcherMac::GetGamepadData(bool) { if (!enabled_) return; - size_t slot = GetSlotForXboxDevice(device); - - // We can't handle this many connected devices. - if (slot == WebGamepads::itemsLengthCap) - return; - - device->SetLEDPattern( - (XboxController::LEDPattern)(XboxController::LED_FLASH_TOP_LEFT + slot)); - - NSString* ident = [NSString - stringWithFormat:@"%@ (STANDARD GAMEPAD Vendor: %04x Product: %04x)", - device->GetControllerType() == - XboxController::XBOX_360_CONTROLLER - ? @"Xbox 360 Controller" - : @"Xbox One Controller", - device->GetProductId(), device->GetVendorId()]; - CopyNSStringAsUTF16LittleEndian(ident, pad_state_[slot].data.id, - sizeof(pad_state_[slot].data.id)); - - CopyNSStringAsUTF16LittleEndian(@"standard", pad_state_[slot].data.mapping, - sizeof(pad_state_[slot].data.mapping)); - - associated_[slot].is_xbox = true; - associated_[slot].xbox.device = device; - associated_[slot].xbox.location_id = device->location_id(); - pad_state_[slot].data.connected = true; - pad_state_[slot].data.axesLength = 4; - pad_state_[slot].data.buttonsLength = 17; - pad_state_[slot].data.timestamp = 0; - pad_state_[slot].mapper = 0; - pad_state_[slot].axis_mask = 0; - pad_state_[slot].button_mask = 0; -} - -void GamepadPlatformDataFetcherMac::XboxDeviceRemove(XboxController* device) { - if (!enabled_) - return; - - // Find the index for this device. - size_t slot; - for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { - if (pad_state_[slot].data.connected && associated_[slot].is_xbox && - associated_[slot].xbox.device == device) - break; + // Loop through and GetPadState to indicate the devices are still connected. + for (size_t slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { + if (associated_[slot].device_ref != nullptr) { + GetPadState(associated_[slot].location_id); + } } - DCHECK(slot < WebGamepads::itemsLengthCap); - // Leave associated location id so that the controller will be reconnected in - // the same slot if it is plugged in again. Simply mark it as disconnected. - pad_state_[slot].data.connected = false; -} - -void GamepadPlatformDataFetcherMac::XboxValueChanged( - XboxController* device, - const XboxController::Data& data) { - // Find device slot. - size_t slot; - for (slot = 0; slot < WebGamepads::itemsLengthCap; ++slot) { - if (pad_state_[slot].data.connected && associated_[slot].is_xbox && - associated_[slot].xbox.device == device) - break; - } - if (slot == WebGamepads::itemsLengthCap) - return; - - WebGamepad& pad = pad_state_[slot].data; - - for (size_t i = 0; i < 6; i++) { - pad.buttons[i].pressed = data.buttons[i]; - pad.buttons[i].value = data.buttons[i] ? 1.0f : 0.0f; - } - pad.buttons[6].pressed = data.triggers[0] > kDefaultButtonPressedThreshold; - pad.buttons[6].value = data.triggers[0]; - pad.buttons[7].pressed = data.triggers[1] > kDefaultButtonPressedThreshold; - pad.buttons[7].value = data.triggers[1]; - for (size_t i = 8; i < 17; i++) { - pad.buttons[i].pressed = data.buttons[i - 2]; - pad.buttons[i].value = data.buttons[i - 2] ? 1.0f : 0.0f; - } - for (size_t i = 0; i < arraysize(data.axes); i++) { - pad.axes[i] = data.axes[i]; - } - - pad.timestamp = base::TimeTicks::Now().ToInternalValue(); -} - -void GamepadPlatformDataFetcherMac::GetGamepadData(WebGamepads* pads, bool) { - if (!enabled_ && !xbox_fetcher_) { - pads->length = 0; - return; - } - - pads->length = WebGamepads::itemsLengthCap; - for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) - MapAndSanitizeGamepadData(&pad_state_[i], &pads->items[i]); } } // namespace device
diff --git a/device/gamepad/gamepad_platform_data_fetcher_win.cc b/device/gamepad/gamepad_platform_data_fetcher_win.cc index e3ecc1a..8364729 100644 --- a/device/gamepad/gamepad_platform_data_fetcher_win.cc +++ b/device/gamepad/gamepad_platform_data_fetcher_win.cc
@@ -7,6 +7,9 @@ #include <stddef.h> #include <string.h> +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/single_thread_task_runner.h" #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event.h" #include "base/win/windows_version.h" @@ -80,121 +83,57 @@ } // namespace GamepadPlatformDataFetcherWin::GamepadPlatformDataFetcherWin() - : xinput_dll_(base::FilePath(XInputDllFileName())), - xinput_available_(GetXInputDllFunctions()) { - for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { - platform_pad_state_[i].status = DISCONNECTED; - pad_state_[i].mapper = NULL; - pad_state_[i].axis_mask = 0; - pad_state_[i].button_mask = 0; - } - - raw_input_fetcher_.reset(new RawInputDataFetcher()); - raw_input_fetcher_->StartMonitor(); -} + : xinput_available_(false) {} GamepadPlatformDataFetcherWin::~GamepadPlatformDataFetcherWin() { - raw_input_fetcher_->StopMonitor(); } -int GamepadPlatformDataFetcherWin::FirstAvailableGamepadId() const { - for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { - if (platform_pad_state_[i].status == DISCONNECTED) - return i; - } - return -1; +GamepadSource GamepadPlatformDataFetcherWin::source() { + return Factory::static_source(); } -bool GamepadPlatformDataFetcherWin::HasXInputGamepad(int index) const { - for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { - if (platform_pad_state_[i].status == XINPUT_CONNECTED && - platform_pad_state_[i].xinput_index == index) - return true; - } - return false; -} - -bool GamepadPlatformDataFetcherWin::HasRawInputGamepad( - const HANDLE handle) const { - for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { - if (platform_pad_state_[i].status == RAWINPUT_CONNECTED && - platform_pad_state_[i].raw_input_handle == handle) - return true; - } - return false; +void GamepadPlatformDataFetcherWin::OnAddedToProvider() { + xinput_dll_.Reset( + base::LoadNativeLibrary(base::FilePath(XInputDllFileName()), nullptr)); + xinput_available_ = GetXInputDllFunctions(); } void GamepadPlatformDataFetcherWin::EnumerateDevices() { TRACE_EVENT0("GAMEPAD", "EnumerateDevices"); - // Mark all disconnected pads DISCONNECTED. - for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { - if (!pad_state_[i].data.connected) - platform_pad_state_[i].status = DISCONNECTED; - } - - for (size_t i = 0; i < XUSER_MAX_COUNT; ++i) { - if (HasXInputGamepad(i)) - continue; - int pad_index = FirstAvailableGamepadId(); - if (pad_index == -1) - return; // We can't add any more gamepads. - WebGamepad& pad = pad_state_[pad_index].data; - if (xinput_available_ && GetXInputPadConnectivity(i, &pad)) { - platform_pad_state_[pad_index].status = XINPUT_CONNECTED; - platform_pad_state_[pad_index].xinput_index = i; - pad_state_[pad_index].mapper = NULL; - pad_state_[pad_index].axis_mask = 0; - pad_state_[pad_index].button_mask = 0; - } - } - - if (raw_input_fetcher_->Available()) { - std::vector<RawGamepadInfo*> raw_inputs = - raw_input_fetcher_->EnumerateDevices(); - for (size_t i = 0; i < raw_inputs.size(); ++i) { - RawGamepadInfo* gamepad = raw_inputs[i]; - if (gamepad->buttons_length == 0 && gamepad->axes_length == 0) + if (xinput_available_) { + for (size_t i = 0; i < XUSER_MAX_COUNT; ++i) { + // Check to see if the xinput device is connected + XINPUT_CAPABILITIES caps; + DWORD res = xinput_get_capabilities_(i, XINPUT_FLAG_GAMEPAD, &caps); + xinuput_connected_[i] = (res == ERROR_SUCCESS); + if (!xinuput_connected_[i]) continue; - if (HasRawInputGamepad(gamepad->handle)) - continue; - int pad_index = FirstAvailableGamepadId(); - if (pad_index == -1) - return; - WebGamepad& pad = pad_state_[pad_index].data; - pad.connected = true; - PadState& state = pad_state_[pad_index]; - PlatformPadState& platform_state = platform_pad_state_[pad_index]; - platform_state.status = RAWINPUT_CONNECTED; - platform_state.raw_input_handle = gamepad->handle; - std::string vendor = base::StringPrintf("%04x", gamepad->vendor_id); - std::string product = base::StringPrintf("%04x", gamepad->product_id); - state.mapper = GetGamepadStandardMappingFunction(vendor, product); - state.axis_mask = 0; - state.button_mask = 0; + PadState* state = GetPadState(i); + if (!state) + continue; // No slot available for this gamepad. - swprintf(pad.id, WebGamepad::idLengthCap, - L"%ls (%lsVendor: %04x Product: %04x)", gamepad->id, - state.mapper ? L"STANDARD GAMEPAD " : L"", gamepad->vendor_id, - gamepad->product_id); + WebGamepad& pad = state->data; - if (state.mapper) + if (state->active_state == GAMEPAD_NEWLY_ACTIVE) { + // This is the first time we've seen this device, so do some one-time + // initialization + pad.connected = true; + swprintf(pad.id, WebGamepad::idLengthCap, + L"Xbox 360 Controller (XInput STANDARD %ls)", + GamepadSubTypeName(caps.SubType)); swprintf(pad.mapping, WebGamepad::mappingLengthCap, L"standard"); - else - pad.mapping[0] = 0; + } } } } -void GamepadPlatformDataFetcherWin::GetGamepadData(WebGamepads* pads, - bool devices_changed_hint) { +void GamepadPlatformDataFetcherWin::GetGamepadData(bool devices_changed_hint) { TRACE_EVENT0("GAMEPAD", "GetGamepadData"); - if (!xinput_available_ && !raw_input_fetcher_->Available()) { - pads->length = 0; + if (!xinput_available_) return; - } // A note on XInput devices: // If we got notification that system devices have been updated, then @@ -206,69 +145,32 @@ if (devices_changed_hint) EnumerateDevices(); - pads->length = 0; - - for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { - // We rely on device_changed and GetCapabilities to tell us that - // something's been connected, but we will mark as disconnected if - // Get___PadState returns that we've lost the pad. - if (!pad_state_[i].data.connected) - continue; - - if (platform_pad_state_[i].status == XINPUT_CONNECTED) - GetXInputPadData(i, &pad_state_[i].data); - else if (platform_pad_state_[i].status == RAWINPUT_CONNECTED) - GetRawInputPadData(i, &pad_state_[i].data); - - MapAndSanitizeGamepadData(&pad_state_[i], &pads->items[i]); - - if (pads->items[i].connected) - pads->length++; + for (size_t i = 0; i < XUSER_MAX_COUNT; ++i) { + if (xinuput_connected_[i]) + GetXInputPadData(i); } } -void GamepadPlatformDataFetcherWin::PauseHint(bool pause) { - if (pause) - raw_input_fetcher_->StopMonitor(); - else - raw_input_fetcher_->StartMonitor(); -} +void GamepadPlatformDataFetcherWin::GetXInputPadData(int i) { + PadState* pad_state = provider()->GetPadState(GAMEPAD_SOURCE_WIN_XINPUT, i); + if (!pad_state) + return; -bool GamepadPlatformDataFetcherWin::GetXInputPadConnectivity( - int i, - WebGamepad* pad) const { - DCHECK(pad); - TRACE_EVENT1("GAMEPAD", "GetXInputPadConnectivity", "id", i); - XINPUT_CAPABILITIES caps; - DWORD res = xinput_get_capabilities_(i, XINPUT_FLAG_GAMEPAD, &caps); - if (res == ERROR_DEVICE_NOT_CONNECTED) { - pad->connected = false; - return false; - } else { - pad->connected = true; - swprintf(pad->id, WebGamepad::idLengthCap, - L"Xbox 360 Controller (XInput STANDARD %ls)", - GamepadSubTypeName(caps.SubType)); - swprintf(pad->mapping, WebGamepad::mappingLengthCap, L"standard"); - return true; - } -} + WebGamepad& pad = pad_state->data; -void GamepadPlatformDataFetcherWin::GetXInputPadData(int i, WebGamepad* pad) { XINPUT_STATE state; memset(&state, 0, sizeof(XINPUT_STATE)); TRACE_EVENT_BEGIN1("GAMEPAD", "XInputGetState", "id", i); - DWORD dwResult = - xinput_get_state_(platform_pad_state_[i].xinput_index, &state); + DWORD dwResult = xinput_get_state_(i, &state); TRACE_EVENT_END1("GAMEPAD", "XInputGetState", "id", i); if (dwResult == ERROR_SUCCESS) { - pad->timestamp = state.dwPacketNumber; - pad->buttonsLength = 0; + pad.timestamp = state.dwPacketNumber; + pad.buttonsLength = 0; WORD val = state.Gamepad.wButtons; -#define ADD(b) \ - pad->buttons[pad->buttonsLength].pressed = (val & (b)) != 0; \ - pad->buttons[pad->buttonsLength++].value = ((val & (b)) ? 1.f : 0.f); +#define ADD(b) \ + pad.buttons[pad.buttonsLength].pressed = (val & (b)) != 0; \ + pad.buttons[pad.buttonsLength++].value = ((val & (b)) ? 1.f : 0.f); ADD(XINPUT_GAMEPAD_A); ADD(XINPUT_GAMEPAD_B); ADD(XINPUT_GAMEPAD_X); @@ -276,14 +178,13 @@ ADD(XINPUT_GAMEPAD_LEFT_SHOULDER); ADD(XINPUT_GAMEPAD_RIGHT_SHOULDER); - pad->buttons[pad->buttonsLength].pressed = + pad.buttons[pad.buttonsLength].pressed = state.Gamepad.bLeftTrigger >= XINPUT_GAMEPAD_TRIGGER_THRESHOLD; - pad->buttons[pad->buttonsLength++].value = - state.Gamepad.bLeftTrigger / 255.f; + pad.buttons[pad.buttonsLength++].value = state.Gamepad.bLeftTrigger / 255.f; - pad->buttons[pad->buttonsLength].pressed = + pad.buttons[pad.buttonsLength].pressed = state.Gamepad.bRightTrigger >= XINPUT_GAMEPAD_TRIGGER_THRESHOLD; - pad->buttons[pad->buttonsLength++].value = + pad.buttons[pad.buttonsLength++].value = state.Gamepad.bRightTrigger / 255.f; ADD(XINPUT_GAMEPAD_BACK); @@ -295,12 +196,12 @@ ADD(XINPUT_GAMEPAD_DPAD_LEFT); ADD(XINPUT_GAMEPAD_DPAD_RIGHT); #undef ADD - pad->axesLength = 0; + pad.axesLength = 0; float value = 0.0; #define ADD(a, factor) \ value = factor * NormalizeXInputAxis(a); \ - pad->axes[pad->axesLength++] = value; + pad.axes[pad.axesLength++] = value; // XInput are +up/+right, -down/-left, we want -up/-left. ADD(state.Gamepad.sThumbLX, 1); @@ -308,33 +209,9 @@ ADD(state.Gamepad.sThumbRX, 1); ADD(state.Gamepad.sThumbRY, -1); #undef ADD - } else { - pad->connected = false; } } -void GamepadPlatformDataFetcherWin::GetRawInputPadData(int index, - WebGamepad* pad) { - RawGamepadInfo* gamepad = raw_input_fetcher_->GetGamepadInfo( - platform_pad_state_[index].raw_input_handle); - if (!gamepad) { - pad->connected = false; - return; - } - - pad->timestamp = gamepad->report_id; - pad->buttonsLength = gamepad->buttons_length; - pad->axesLength = gamepad->axes_length; - - for (unsigned int i = 0; i < pad->buttonsLength; i++) { - pad->buttons[i].pressed = gamepad->buttons[i]; - pad->buttons[i].value = gamepad->buttons[i] ? 1.0 : 0.0; - } - - for (unsigned int i = 0; i < pad->axesLength; i++) - pad->axes[i] = gamepad->axes[i].value; -} - bool GamepadPlatformDataFetcherWin::GetXInputDllFunctions() { xinput_get_capabilities_ = NULL; xinput_get_state_ = NULL;
diff --git a/device/gamepad/gamepad_platform_data_fetcher_win.h b/device/gamepad/gamepad_platform_data_fetcher_win.h index cf9f772..df5b5dcd 100644 --- a/device/gamepad/gamepad_platform_data_fetcher_win.h +++ b/device/gamepad/gamepad_platform_data_fetcher_win.h
@@ -25,23 +25,25 @@ #include "base/scoped_native_library.h" #include "device/gamepad/gamepad_data_fetcher.h" #include "device/gamepad/gamepad_standard_mappings.h" -#include "device/gamepad/raw_input_data_fetcher_win.h" #include "third_party/WebKit/public/platform/WebGamepads.h" namespace device { class GamepadPlatformDataFetcherWin : public GamepadDataFetcher { public: + typedef GamepadDataFetcherFactoryImpl<GamepadPlatformDataFetcherWin, + GAMEPAD_SOURCE_WIN_XINPUT> + Factory; + GamepadPlatformDataFetcherWin(); ~GamepadPlatformDataFetcherWin() override; - void GetGamepadData(blink::WebGamepads* pads, - bool devices_changed_hint) override; - void PauseHint(bool paused) override; + + GamepadSource source() override; + + void GetGamepadData(bool devices_changed_hint) override; private: - // XInput-specific implementation for GetGamepadData. - bool GetXInputGamepadData(blink::WebGamepads* pads, - bool devices_changed_hint); + void OnAddedToProvider() override; // The three function types we use from xinput1_3.dll. typedef void(WINAPI* XInputEnableFunc)(BOOL enable); @@ -58,14 +60,7 @@ // Scan for connected XInput and DirectInput gamepads. void EnumerateDevices(); - bool GetXInputPadConnectivity(int i, blink::WebGamepad* pad) const; - - void GetXInputPadData(int i, blink::WebGamepad* pad); - void GetRawInputPadData(int i, blink::WebGamepad* pad); - - int FirstAvailableGamepadId() const; - bool HasXInputGamepad(int index) const; - bool HasRawInputGamepad(const HANDLE handle) const; + void GetXInputPadData(int i); base::ScopedNativeLibrary xinput_dll_; bool xinput_available_; @@ -75,21 +70,7 @@ XInputGetCapabilitiesFunc xinput_get_capabilities_; XInputGetStateFunc xinput_get_state_; - enum PadConnectionStatus { - DISCONNECTED, - XINPUT_CONNECTED, - RAWINPUT_CONNECTED - }; - - struct PlatformPadState { - PadConnectionStatus status; - - int xinput_index; // XInput-only - HANDLE raw_input_handle; // RawInput-only fields. - }; - PlatformPadState platform_pad_state_[blink::WebGamepads::itemsLengthCap]; - - std::unique_ptr<RawInputDataFetcher> raw_input_fetcher_; + bool xinuput_connected_[XUSER_MAX_COUNT]; DISALLOW_COPY_AND_ASSIGN(GamepadPlatformDataFetcherWin); };
diff --git a/device/gamepad/gamepad_provider.cc b/device/gamepad/gamepad_provider.cc index c37c38a..510194da0 100644 --- a/device/gamepad/gamepad_provider.cc +++ b/device/gamepad/gamepad_provider.cc
@@ -7,7 +7,6 @@ #include <stddef.h> #include <string.h> #include <cmath> -#include <set> #include <utility> #include <vector> @@ -21,7 +20,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "device/gamepad/gamepad_data_fetcher.h" -#include "device/gamepad/gamepad_platform_data_fetcher.h" +#include "device/gamepad/gamepad_data_fetcher_manager.h" #include "device/gamepad/gamepad_user_gesture.h" using blink::WebGamepad; @@ -46,6 +45,7 @@ have_scheduled_do_poll_(false), devices_changed_(true), ever_had_user_gesture_(false), + sanitize_(true), gamepad_shared_buffer_(std::move(buffer)), connection_change_client_(connection_change_client) { Initialize(std::unique_ptr<GamepadDataFetcher>()); @@ -59,12 +59,15 @@ have_scheduled_do_poll_(false), devices_changed_(true), ever_had_user_gesture_(false), + sanitize_(true), gamepad_shared_buffer_(std::move(buffer)), connection_change_client_(connection_change_client) { Initialize(std::move(fetcher)); } GamepadProvider::~GamepadProvider() { + GamepadDataFetcherManager::GetInstance()->ClearProvider(); + base::SystemMonitor* monitor = base::SystemMonitor::Get(); if (monitor) monitor->RemoveDevicesChangedObserver(this); @@ -72,7 +75,6 @@ // Use Stop() to join the polling thread, as there may be pending callbacks // which dereference |polling_thread_|. polling_thread_->Stop(); - data_fetcher_.reset(); } base::SharedMemoryHandle GamepadProvider::GetSharedMemoryHandleForProcess( @@ -133,8 +135,6 @@ if (monitor) monitor->AddDevicesChangedObserver(this); - pad_states_.reset(new PadState[WebGamepads::itemsLengthCap]); - polling_thread_.reset(new base::Thread("Gamepad polling thread")); #if defined(OS_LINUX) // On Linux, the data fetcher needs to watch file descriptors, so the message @@ -152,58 +152,53 @@ #endif polling_thread_->StartWithOptions(base::Thread::Options(kMessageLoopType, 0)); + if (fetcher) { + AddGamepadDataFetcher(std::move(fetcher)); + } else { + GamepadDataFetcherManager::GetInstance()->InitializeProvider(this); + } +} + +void GamepadProvider::AddGamepadDataFetcher( + std::unique_ptr<GamepadDataFetcher> fetcher) { polling_thread_->task_runner()->PostTask( - FROM_HERE, base::Bind(&GamepadProvider::DoInitializePollingThread, + FROM_HERE, base::Bind(&GamepadProvider::DoAddGamepadDataFetcher, base::Unretained(this), base::Passed(&fetcher))); } -void GamepadProvider::DoInitializePollingThread( +void GamepadProvider::RemoveSourceGamepadDataFetcher(GamepadSource source) { + polling_thread_->task_runner()->PostTask( + FROM_HERE, base::Bind(&GamepadProvider::DoRemoveSourceGamepadDataFetcher, + base::Unretained(this), source)); +} + +void GamepadProvider::DoAddGamepadDataFetcher( std::unique_ptr<GamepadDataFetcher> fetcher) { DCHECK(polling_thread_->task_runner()->BelongsToCurrentThread()); - DCHECK(!data_fetcher_.get()); // Should only initialize once. if (!fetcher) - fetcher.reset(new GamepadPlatformDataFetcher); - data_fetcher_ = std::move(fetcher); + return; + + InitializeDataFetcher(fetcher.get()); + data_fetchers_.push_back(std::move(fetcher)); +} + +void GamepadProvider::DoRemoveSourceGamepadDataFetcher(GamepadSource source) { + DCHECK(polling_thread_->task_runner()->BelongsToCurrentThread()); + + for (GamepadFetcherVector::iterator it = data_fetchers_.begin(); + it != data_fetchers_.end(); ++it) { + if ((*it)->source() == source) { + data_fetchers_.erase(it); + } + } } void GamepadProvider::SendPauseHint(bool paused) { DCHECK(polling_thread_->task_runner()->BelongsToCurrentThread()); - if (data_fetcher_) - data_fetcher_->PauseHint(paused); -} - -bool GamepadProvider::PadState::Match(const WebGamepad& pad) const { - return connected_ == pad.connected && axes_length_ == pad.axesLength && - buttons_length_ == pad.buttonsLength && - memcmp(id_, pad.id, sizeof(id_)) == 0 && - memcmp(mapping_, pad.mapping, sizeof(mapping_)) == 0; -} - -void GamepadProvider::PadState::SetPad(const WebGamepad& pad) { - connected_ = pad.connected; - axes_length_ = pad.axesLength; - buttons_length_ = pad.buttonsLength; - memcpy(id_, pad.id, sizeof(id_)); - memcpy(mapping_, pad.mapping, sizeof(mapping_)); -} - -void GamepadProvider::PadState::SetDisconnected() { - connected_ = false; - axes_length_ = 0; - buttons_length_ = 0; - memset(id_, 0, sizeof(id_)); - memset(mapping_, 0, sizeof(mapping_)); -} - -void GamepadProvider::PadState::AsWebGamepad(WebGamepad* pad) { - pad->connected = connected_; - pad->axesLength = axes_length_; - pad->buttonsLength = buttons_length_; - memcpy(pad->id, id_, sizeof(id_)); - memcpy(pad->mapping, mapping_, sizeof(mapping_)); - memset(pad->axes, 0, sizeof(pad->axes)); - memset(pad->buttons, 0, sizeof(pad->buttons)); + for (const auto& it : data_fetchers_) { + it->PauseHint(paused); + } } void GamepadProvider::DoPoll() { @@ -222,29 +217,54 @@ devices_changed_ = false; } + // Loop through each registered data fetcher and poll it's gamepad data. + // It's expected that GetGamepadData will mark each gamepad as active (via + // GetPadState). If a gamepad is not marked as active during the calls to + // GetGamepadData then it's assumed to be disconnected. + for (const auto& it : data_fetchers_) { + it->GetGamepadData(changed); + } + + blink::WebGamepads* buffer = gamepad_shared_buffer_->buffer(); + + // Send out disconnect events using the last polled data before we wipe it out + // in the mapping step. + if (ever_had_user_gesture_) { + for (unsigned i = 0; i < WebGamepads::itemsLengthCap; ++i) { + PadState& state = pad_states_.get()[i]; + + if (!state.active_state && state.source != GAMEPAD_SOURCE_NONE) { + OnGamepadConnectionChange(false, i, buffer->items[i]); + ClearPadState(state); + } + } + } + { base::AutoLock lock(shared_memory_lock_); // Acquire the SeqLock. There is only ever one writer to this data. // See gamepad_hardware_buffer.h. gamepad_shared_buffer_->WriteBegin(); - data_fetcher_->GetGamepadData(gamepad_shared_buffer_->buffer(), changed); + buffer->length = 0; + for (unsigned i = 0; i < WebGamepads::itemsLengthCap; ++i) { + PadState& state = pad_states_.get()[i]; + // Must run through the map+sanitize here or CheckForUserGesture may fail. + MapAndSanitizeGamepadData(&state, &buffer->items[i], sanitize_); + if (state.active_state) + buffer->length++; + } gamepad_shared_buffer_->WriteEnd(); } if (ever_had_user_gesture_) { for (unsigned i = 0; i < WebGamepads::itemsLengthCap; ++i) { - WebGamepad& pad = gamepad_shared_buffer_->buffer()->items[i]; PadState& state = pad_states_.get()[i]; - if (pad.connected && !state.connected()) { - OnGamepadConnectionChange(true, i, pad); - } else if (!pad.connected && state.connected()) { - OnGamepadConnectionChange(false, i, pad); - } else if (pad.connected && state.connected() && !state.Match(pad)) { - WebGamepad old_pad; - state.AsWebGamepad(&old_pad); - OnGamepadConnectionChange(false, i, old_pad); - OnGamepadConnectionChange(true, i, pad); + + if (state.active_state) { + if (state.active_state == GAMEPAD_NEWLY_ACTIVE) + OnGamepadConnectionChange(true, i, buffer->items[i]); + state.active_state = GAMEPAD_INACTIVE; } } } @@ -275,12 +295,6 @@ void GamepadProvider::OnGamepadConnectionChange(bool connected, int index, const WebGamepad& pad) { - PadState& state = pad_states_.get()[index]; - if (connected) - state.SetPad(pad); - else - state.SetDisconnected(); - if (connection_change_client_) connection_change_client_->OnGamepadConnectionChange(connected, index, pad); } @@ -290,7 +304,6 @@ if (user_gesture_observers_.empty() && ever_had_user_gesture_) return; - bool had_gesture_before = ever_had_user_gesture_; const WebGamepads* pads = gamepad_shared_buffer_->buffer(); if (GamepadsHaveUserGesture(*pads)) { ever_had_user_gesture_ = true; @@ -300,12 +313,6 @@ } user_gesture_observers_.clear(); } - if (!had_gesture_before && ever_had_user_gesture_) { - // Initialize pad_states_ for the first time. - for (size_t i = 0; i < WebGamepads::itemsLengthCap; ++i) { - pad_states_.get()[i].SetPad(pads->items[i]); - } - } } } // namespace device
diff --git a/device/gamepad/gamepad_provider.h b/device/gamepad/gamepad_provider.h index 5d2e2b2e..faed53d 100644 --- a/device/gamepad/gamepad_provider.h +++ b/device/gamepad/gamepad_provider.h
@@ -13,11 +13,12 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/shared_memory.h" -#include "base/memory/weak_ptr.h" #include "base/synchronization/lock.h" #include "base/system_monitor/system_monitor.h" #include "device/gamepad/gamepad_export.h" +#include "device/gamepad/gamepad_pad_state_provider.h" #include "device/gamepad/gamepad_shared_buffer.h" + #include "third_party/WebKit/public/platform/WebGamepads.h" namespace base { @@ -37,7 +38,8 @@ }; class DEVICE_GAMEPAD_EXPORT GamepadProvider - : public base::SystemMonitor::DevicesChangedObserver { + : public GamepadPadStateProvider, + public base::SystemMonitor::DevicesChangedObserver { public: explicit GamepadProvider( std::unique_ptr<GamepadSharedBuffer> buffer, @@ -56,6 +58,9 @@ base::SharedMemoryHandle GetSharedMemoryHandleForProcess( base::ProcessHandle renderer_process); + void AddGamepadDataFetcher(GamepadDataFetcher* fetcher); + void RemoveGamepadDataFetcher(GamepadDataFetcher* fetcher); + void GetCurrentGamepadData(blink::WebGamepads* data); // Pause and resume the background polling thread. Can be called from any @@ -70,12 +75,21 @@ // base::SystemMonitor::DevicesChangedObserver implementation. void OnDevicesChanged(base::SystemMonitor::DeviceType type) override; + // Add a gamepad data fetcher. Takes ownership of |fetcher|. + void AddGamepadDataFetcher(std::unique_ptr<GamepadDataFetcher> fetcher); + + // Remove gamepad data fetchers with the given source. + void RemoveSourceGamepadDataFetcher(GamepadSource source); + + void SetSanitizationEnabled(bool sanitize) { sanitize_ = sanitize; } + private: void Initialize(std::unique_ptr<GamepadDataFetcher> fetcher); // Method for setting up the platform-specific data fetcher. Takes ownership // of |fetcher|. - void DoInitializePollingThread(std::unique_ptr<GamepadDataFetcher> fetcher); + void DoAddGamepadDataFetcher(std::unique_ptr<GamepadDataFetcher> fetcher); + void DoRemoveSourceGamepadDataFetcher(GamepadSource source); // Method for sending pause hints to the low-level data fetcher. Runs on // polling_thread_. @@ -131,31 +145,11 @@ bool devices_changed_; bool ever_had_user_gesture_; - - class PadState { - public: - PadState() { SetDisconnected(); } - - bool Match(const blink::WebGamepad& pad) const; - void SetPad(const blink::WebGamepad& pad); - void SetDisconnected(); - void AsWebGamepad(blink::WebGamepad* pad); - - bool connected() const { return connected_; } - - private: - bool connected_; - unsigned axes_length_; - unsigned buttons_length_; - blink::WebUChar id_[blink::WebGamepad::idLengthCap]; - blink::WebUChar mapping_[blink::WebGamepad::mappingLengthCap]; - }; - - // Used to detect connections and disconnections. - std::unique_ptr<PadState[]> pad_states_; + bool sanitize_; // Only used on the polling thread. - std::unique_ptr<GamepadDataFetcher> data_fetcher_; + typedef std::vector<std::unique_ptr<GamepadDataFetcher>> GamepadFetcherVector; + GamepadFetcherVector data_fetchers_; base::Lock shared_memory_lock_; std::unique_ptr<GamepadSharedBuffer> gamepad_shared_buffer_; @@ -165,8 +159,6 @@ GamepadConnectionChangeClient* connection_change_client_; - static GamepadProvider* instance_; - DISALLOW_COPY_AND_ASSIGN(GamepadProvider); };
diff --git a/device/gamepad/gamepad_provider_unittest.cc b/device/gamepad/gamepad_provider_unittest.cc index 91116cd..e9b40e77 100644 --- a/device/gamepad/gamepad_provider_unittest.cc +++ b/device/gamepad/gamepad_provider_unittest.cc
@@ -81,6 +81,7 @@ test_data.items[0].axes[1] = .5f; GamepadProvider* provider = CreateProvider(test_data); + provider->SetSanitizationEnabled(false); provider->Resume(); base::RunLoop().RunUntilIdle(); @@ -125,6 +126,7 @@ UserGestureListener listener; GamepadProvider* provider = CreateProvider(no_button_data); + provider->SetSanitizationEnabled(false); provider->Resume(); provider->RegisterForUserGesture(listener.GetClosure()); @@ -143,6 +145,88 @@ EXPECT_TRUE(listener.has_user_gesture()); } +// Crashes. http://crbug.com/106163 +// crbug.com/147549 +#if defined(OS_ANDROID) +#define MAYBE_Sanitization DISABLED_Sanitization +#else +#define MAYBE_Sanitization Sanitization +#endif +// Tests that waiting for a user gesture works properly. +TEST_F(GamepadProviderTest, MAYBE_Sanitization) { + WebGamepads active_data; + active_data.length = 1; + active_data.items[0].connected = true; + active_data.items[0].timestamp = 0; + active_data.items[0].buttonsLength = 1; + active_data.items[0].axesLength = 1; + active_data.items[0].buttons[0].value = 1.f; + active_data.items[0].buttons[0].pressed = true; + active_data.items[0].axes[0] = -1.f; + + WebGamepads zero_data; + zero_data.length = 1; + zero_data.items[0].connected = true; + zero_data.items[0].timestamp = 0; + zero_data.items[0].buttonsLength = 1; + zero_data.items[0].axesLength = 1; + zero_data.items[0].buttons[0].value = 0.f; + zero_data.items[0].buttons[0].pressed = false; + zero_data.items[0].axes[0] = 0.f; + + UserGestureListener listener; + GamepadProvider* provider = CreateProvider(active_data); + provider->SetSanitizationEnabled(true); + provider->Resume(); + + base::RunLoop().RunUntilIdle(); + + mock_data_fetcher_->WaitForDataRead(); + + // Renderer-side, pull data out of poll buffer. + base::SharedMemoryHandle handle = provider->GetSharedMemoryHandleForProcess( + base::GetCurrentProcessHandle()); + std::unique_ptr<base::SharedMemory> shared_memory( + new base::SharedMemory(handle, true)); + EXPECT_TRUE(shared_memory->Map(sizeof(WebGamepads))); + void* mem = shared_memory->memory(); + + WebGamepads* output = static_cast<WebGamepads*>(mem); + + // Initial data should all be zeroed out due to sanitization, even though the + // gamepad reported input + EXPECT_EQ(1u, output->length); + EXPECT_EQ(1u, output->items[0].buttonsLength); + EXPECT_EQ(0.f, output->items[0].buttons[0].value); + EXPECT_FALSE(output->items[0].buttons[0].pressed); + EXPECT_EQ(1u, output->items[0].axesLength); + EXPECT_EQ(0.f, output->items[0].axes[0]); + + // Zero out the inputs + mock_data_fetcher_->SetTestData(zero_data); + mock_data_fetcher_->WaitForDataReadAndCallbacksIssued(); + + // Should still read zero, which is now an accurate reflection of the data + EXPECT_EQ(1u, output->length); + EXPECT_EQ(1u, output->items[0].buttonsLength); + EXPECT_EQ(0.f, output->items[0].buttons[0].value); + EXPECT_FALSE(output->items[0].buttons[0].pressed); + EXPECT_EQ(1u, output->items[0].axesLength); + EXPECT_EQ(0.f, output->items[0].axes[0]); + + // Re-set the active inputs + mock_data_fetcher_->SetTestData(active_data); + mock_data_fetcher_->WaitForDataReadAndCallbacksIssued(); + + // Should now accurately reflect the reported data. + EXPECT_EQ(1u, output->length); + EXPECT_EQ(1u, output->items[0].buttonsLength); + EXPECT_EQ(1.f, output->items[0].buttons[0].value); + EXPECT_TRUE(output->items[0].buttons[0].pressed); + EXPECT_EQ(1u, output->items[0].axesLength); + EXPECT_EQ(-1.f, output->items[0].axes[0]); +} + } // namespace } // namespace device
diff --git a/device/gamepad/gamepad_test_helpers.cc b/device/gamepad/gamepad_test_helpers.cc index d27b808..b0aa221 100644 --- a/device/gamepad/gamepad_test_helpers.cc +++ b/device/gamepad/gamepad_test_helpers.cc
@@ -14,11 +14,21 @@ MockGamepadDataFetcher::~MockGamepadDataFetcher() {} -void MockGamepadDataFetcher::GetGamepadData(blink::WebGamepads* pads, - bool devices_changed_hint) { +GamepadSource MockGamepadDataFetcher::source() { + return GAMEPAD_SOURCE_TEST; +} + +void MockGamepadDataFetcher::GetGamepadData(bool devices_changed_hint) { { base::AutoLock lock(lock_); - *pads = test_data_; + + for (unsigned int i = 0; i < blink::WebGamepads::itemsLengthCap; ++i) { + if (test_data_.items[i].connected) { + PadState* pad = GetPadState(i); + if (pad) + memcpy(&pad->data, &test_data_.items[i], sizeof(blink::WebGamepad)); + } + } } read_data_.Signal(); }
diff --git a/device/gamepad/gamepad_test_helpers.h b/device/gamepad/gamepad_test_helpers.h index 7681bf9..4e482dc 100644 --- a/device/gamepad/gamepad_test_helpers.h +++ b/device/gamepad/gamepad_test_helpers.h
@@ -28,9 +28,10 @@ ~MockGamepadDataFetcher() override; + GamepadSource source() override; + // GamepadDataFetcher. - void GetGamepadData(blink::WebGamepads* pads, - bool devices_changed_hint) override; + void GetGamepadData(bool devices_changed_hint) override; // Blocks the current thread until the GamepadProvider reads from this // fetcher on the background thread.
diff --git a/device/gamepad/raw_input_data_fetcher_win.cc b/device/gamepad/raw_input_data_fetcher_win.cc index 1379dc7..ec7d6cb 100644 --- a/device/gamepad/raw_input_data_fetcher_win.cc +++ b/device/gamepad/raw_input_data_fetcher_win.cc
@@ -7,6 +7,7 @@ #include <stddef.h> #include "base/macros.h" +#include "base/strings/stringprintf.h" #include "base/trace_event/trace_event.h" namespace device { @@ -41,10 +42,11 @@ RawGamepadInfo::~RawGamepadInfo() {} RawInputDataFetcher::RawInputDataFetcher() - : hid_dll_(base::FilePath(FILE_PATH_LITERAL("hid.dll"))), - rawinput_available_(GetHidDllFunctions()), + : rawinput_available_(false), filter_xinput_(true), - events_monitored_(false) {} + events_monitored_(false), + last_source_id_(0), + last_enumeration_id_(0) {} RawInputDataFetcher::~RawInputDataFetcher() { ClearControllers(); @@ -52,10 +54,20 @@ DCHECK(!events_monitored_); } +GamepadSource RawInputDataFetcher::source() { + return Factory::static_source(); +} + void RawInputDataFetcher::WillDestroyCurrentMessageLoop() { StopMonitor(); } +void RawInputDataFetcher::OnAddedToProvider() { + hid_dll_.Reset(base::LoadNativeLibrary( + base::FilePath(FILE_PATH_LITERAL("hid.dll")), nullptr)); + rawinput_available_ = GetHidDllFunctions(); +} + RAWINPUTDEVICE* RawInputDataFetcher::GetRawInputDevices(DWORD flags) { size_t usage_count = arraysize(DeviceUsages); std::unique_ptr<RAWINPUTDEVICE[]> devices(new RAWINPUTDEVICE[usage_count]); @@ -68,6 +80,13 @@ return devices.release(); } +void RawInputDataFetcher::PauseHint(bool pause) { + if (pause) + StopMonitor(); + else + StartMonitor(); +} + void RawInputDataFetcher::StartMonitor() { if (!rawinput_available_ || events_monitored_) return; @@ -128,16 +147,43 @@ } } -std::vector<RawGamepadInfo*> RawInputDataFetcher::EnumerateDevices() { - std::vector<RawGamepadInfo*> valid_controllers; +void RawInputDataFetcher::GetGamepadData(bool devices_changed_hint) { + if (!rawinput_available_) + return; - ClearControllers(); + if (devices_changed_hint) + EnumerateDevices(); + + for (const auto& controller : controllers_) { + RawGamepadInfo* gamepad = controller.second; + PadState* state = GetPadState(gamepad->source_id); + if (!state) + continue; + + WebGamepad& pad = state->data; + + pad.timestamp = gamepad->report_id; + pad.buttonsLength = gamepad->buttons_length; + pad.axesLength = gamepad->axes_length; + + for (unsigned int i = 0; i < pad.buttonsLength; i++) { + pad.buttons[i].pressed = gamepad->buttons[i]; + pad.buttons[i].value = gamepad->buttons[i] ? 1.0 : 0.0; + } + + for (unsigned int i = 0; i < pad.axesLength; i++) + pad.axes[i] = gamepad->axes[i].value; + } +} + +void RawInputDataFetcher::EnumerateDevices() { + last_enumeration_id_++; UINT count = 0; UINT result = GetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)); if (result == static_cast<UINT>(-1)) { PLOG(ERROR) << "GetRawInputDeviceList() failed"; - return valid_controllers; + return; } DCHECK_EQ(0u, result); @@ -147,38 +193,66 @@ sizeof(RAWINPUTDEVICELIST)); if (result == static_cast<UINT>(-1)) { PLOG(ERROR) << "GetRawInputDeviceList() failed"; - return valid_controllers; + return; } DCHECK_EQ(count, result); for (UINT i = 0; i < count; ++i) { if (device_list[i].dwType == RIM_TYPEHID) { HANDLE device_handle = device_list[i].hDevice; - RawGamepadInfo* gamepad_info = ParseGamepadInfo(device_handle); - if (gamepad_info) { - controllers_[device_handle] = gamepad_info; - valid_controllers.push_back(gamepad_info); + ControllerMap::iterator controller = controllers_.find(device_handle); + + RawGamepadInfo* gamepad; + if (controller != controllers_.end()) { + gamepad = controller->second; + } else { + gamepad = ParseGamepadInfo(device_handle); + if (!gamepad) + continue; + + PadState* state = GetPadState(gamepad->source_id); + if (!state) + continue; // No slot available for this gamepad. + + controllers_[device_handle] = gamepad; + + WebGamepad& pad = state->data; + pad.connected = true; + + std::string vendor = base::StringPrintf("%04x", gamepad->vendor_id); + std::string product = base::StringPrintf("%04x", gamepad->product_id); + state->mapper = GetGamepadStandardMappingFunction(vendor, product); + state->axis_mask = 0; + state->button_mask = 0; + + swprintf(pad.id, WebGamepad::idLengthCap, + L"%ls (%lsVendor: %04x Product: %04x)", gamepad->id, + state->mapper ? L"STANDARD GAMEPAD " : L"", gamepad->vendor_id, + gamepad->product_id); + + if (state->mapper) + swprintf(pad.mapping, WebGamepad::mappingLengthCap, L"standard"); + else + pad.mapping[0] = 0; } + + gamepad->enumeration_id = last_enumeration_id_; } } - return valid_controllers; -} -RawGamepadInfo* RawInputDataFetcher::GetGamepadInfo(HANDLE handle) { - std::map<HANDLE, RawGamepadInfo*>::iterator it = controllers_.find(handle); - if (it != controllers_.end()) - return it->second; - - return NULL; + // Clear out old controllers that weren't part of this enumeration pass. + for (const auto& controller : controllers_) { + RawGamepadInfo* gamepad = controller.second; + if (gamepad->enumeration_id != last_enumeration_id_) { + controllers_.erase(gamepad->handle); + delete gamepad; + } + } } RawGamepadInfo* RawInputDataFetcher::ParseGamepadInfo(HANDLE hDevice) { UINT size = 0; - // Do we already have this device in the map? - if (GetGamepadInfo(hDevice)) - return NULL; - // Query basic device info. UINT result = GetRawInputDeviceInfo(hDevice, RIDI_DEVICEINFO, NULL, &size); if (result == static_cast<UINT>(-1)) { @@ -207,10 +281,17 @@ } } + // This is terrible, but the Oculus Rift seems to think it's a gamepad. + // Filter out any Oculus devices. (We'll handle Oculus Touch elsewhere.) + if (device_info->hid.dwVendorId == 0x2833) { + valid_type = false; + } + if (!valid_type) return NULL; std::unique_ptr<RawGamepadInfo> gamepad_info(new RawGamepadInfo); + gamepad_info->source_id = ++last_source_id_; gamepad_info->handle = hDevice; gamepad_info->report_id = 0; gamepad_info->vendor_id = device_info->hid.dwVendorId; @@ -350,6 +431,10 @@ } } + // Sometimes devices show up with no buttons or axes. Don't return these. + if (gamepad_info->buttons_length == 0 && gamepad_info->axes_length == 0) + return nullptr; + return gamepad_info.release(); } @@ -448,9 +533,9 @@ // Notify the observer about events generated locally. if (input->header.dwType == RIM_TYPEHID && input->header.hDevice != NULL) { - RawGamepadInfo* gamepad = GetGamepadInfo(input->header.hDevice); - if (gamepad) - UpdateGamepad(input, gamepad); + ControllerMap::iterator it = controllers_.find(input->header.hDevice); + if (it != controllers_.end()) + UpdateGamepad(input, it->second); } return DefRawInputProc(&input, 1, sizeof(RAWINPUTHEADER));
diff --git a/device/gamepad/raw_input_data_fetcher_win.h b/device/gamepad/raw_input_data_fetcher_win.h index 891a2964..79e5fb5 100644 --- a/device/gamepad/raw_input_data_fetcher_win.h +++ b/device/gamepad/raw_input_data_fetcher_win.h
@@ -39,6 +39,8 @@ RawGamepadInfo(); ~RawGamepadInfo(); + int source_id; + int enumeration_id; HANDLE handle; std::unique_ptr<uint8_t[]> ppd_buffer; PHIDP_PREPARSED_DATA preparsed_data; @@ -56,23 +58,31 @@ RawGamepadAxis axes[blink::WebGamepad::axesLengthCap]; }; -class RawInputDataFetcher : public base::SupportsWeakPtr<RawInputDataFetcher>, +class RawInputDataFetcher : public GamepadDataFetcher, + public base::SupportsWeakPtr<RawInputDataFetcher>, public base::MessageLoop::DestructionObserver { public: + typedef GamepadDataFetcherFactoryImpl<RawInputDataFetcher, + GAMEPAD_SOURCE_WIN_RAW> + Factory; + explicit RawInputDataFetcher(); ~RawInputDataFetcher() override; + GamepadSource source() override; + // DestructionObserver overrides. void WillDestroyCurrentMessageLoop() override; - bool Available() { return rawinput_available_; } - void StartMonitor(); - void StopMonitor(); - - std::vector<RawGamepadInfo*> EnumerateDevices(); - RawGamepadInfo* GetGamepadInfo(HANDLE handle); + void GetGamepadData(bool devices_changed_hint) override; + void PauseHint(bool paused) override; private: + void OnAddedToProvider() override; + + void StartMonitor(); + void StopMonitor(); + void EnumerateDevices(); RawGamepadInfo* ParseGamepadInfo(HANDLE hDevice); void UpdateGamepad(RAWINPUT* input, RawGamepadInfo* gamepad_info); // Handles WM_INPUT messages. @@ -138,8 +148,11 @@ bool rawinput_available_; bool filter_xinput_; bool events_monitored_; + int last_source_id_; + int last_enumeration_id_; - std::map<HANDLE, RawGamepadInfo*> controllers_; + typedef std::map<HANDLE, RawGamepadInfo*> ControllerMap; + ControllerMap controllers_; // Function pointers to HID functionality, retrieved in // |GetHidDllFunctions|.
diff --git a/device/gamepad/xbox_data_fetcher_mac.cc b/device/gamepad/xbox_data_fetcher_mac.cc deleted file mode 100644 index 4c526a7c..0000000 --- a/device/gamepad/xbox_data_fetcher_mac.cc +++ /dev/null
@@ -1,765 +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 "device/gamepad/xbox_data_fetcher_mac.h" - -#include <algorithm> -#include <cmath> -#include <limits> - -#include <CoreFoundation/CoreFoundation.h> -#include <IOKit/IOCFPlugIn.h> -#include <IOKit/IOKitLib.h> -#include <IOKit/usb/IOUSBLib.h> -#include <IOKit/usb/USB.h> - -#include "base/logging.h" -#include "base/mac/foundation_util.h" - -namespace { -const int kVendorMicrosoft = 0x045e; -const int kProductXbox360Controller = 0x028e; -const int kProductXboxOneController = 0x02d1; - -const int kXbox360ReadEndpoint = 1; -const int kXbox360ControlEndpoint = 2; - -const int kXboxOneReadEndpoint = 2; -const int kXboxOneControlEndpoint = 1; - -enum { - STATUS_MESSAGE_BUTTONS = 0, - STATUS_MESSAGE_LED = 1, - - // Apparently this message tells you if the rumble pack is disabled in the - // controller. If the rumble pack is disabled, vibration control messages - // have no effect. - STATUS_MESSAGE_RUMBLE = 3, -}; - -enum { - XBOX_ONE_STATUS_MESSAGE_BUTTONS = 0x20, -}; - -enum { - CONTROL_MESSAGE_SET_RUMBLE = 0, - CONTROL_MESSAGE_SET_LED = 1, -}; - -#pragma pack(push, 1) -struct Xbox360ButtonData { - bool dpad_up : 1; - bool dpad_down : 1; - bool dpad_left : 1; - bool dpad_right : 1; - - bool start : 1; - bool back : 1; - bool stick_left_click : 1; - bool stick_right_click : 1; - - bool bumper_left : 1; - bool bumper_right : 1; - bool guide : 1; - bool dummy1 : 1; // Always 0. - - bool a : 1; - bool b : 1; - bool x : 1; - bool y : 1; - - uint8_t trigger_left; - uint8_t trigger_right; - - int16_t stick_left_x; - int16_t stick_left_y; - int16_t stick_right_x; - int16_t stick_right_y; - - // Always 0. - uint32_t dummy2; - uint16_t dummy3; -}; - -struct XboxOneButtonData { - bool sync : 1; - bool dummy1 : 1; // Always 0. - bool start : 1; - bool back : 1; - - bool a : 1; - bool b : 1; - bool x : 1; - bool y : 1; - - bool dpad_up : 1; - bool dpad_down : 1; - bool dpad_left : 1; - bool dpad_right : 1; - - bool bumper_left : 1; - bool bumper_right : 1; - bool stick_left_click : 1; - bool stick_right_click : 1; - - uint16_t trigger_left; - uint16_t trigger_right; - - int16_t stick_left_x; - int16_t stick_left_y; - int16_t stick_right_x; - int16_t stick_right_y; -}; -#pragma pack(pop) - -static_assert(sizeof(Xbox360ButtonData) == 18, "xbox button data wrong size"); -static_assert(sizeof(XboxOneButtonData) == 14, "xbox button data wrong size"); - -// From MSDN: -// http://msdn.microsoft.com/en-us/library/windows/desktop/ee417001(v=vs.85).aspx#dead_zone -const int16_t kLeftThumbDeadzone = 7849; -const int16_t kRightThumbDeadzone = 8689; -const uint8_t kXbox360TriggerDeadzone = 30; -const uint16_t kXboxOneTriggerMax = 1023; -const uint16_t kXboxOneTriggerDeadzone = 120; - -void NormalizeAxis(int16_t x, - int16_t y, - int16_t deadzone, - float* x_out, - float* y_out) { - float x_val = x; - float y_val = y; - - // Determine how far the stick is pushed. - float real_magnitude = std::sqrt(x_val * x_val + y_val * y_val); - - // Check if the controller is outside a circular dead zone. - if (real_magnitude > deadzone) { - // Clip the magnitude at its expected maximum value. - float magnitude = std::min(32767.0f, real_magnitude); - - // Adjust magnitude relative to the end of the dead zone. - magnitude -= deadzone; - - // Normalize the magnitude with respect to its expected range giving a - // magnitude value of 0.0 to 1.0 - float ratio = (magnitude / (32767 - deadzone)) / real_magnitude; - - // Y is negated because xbox controllers have an opposite sign from - // the 'standard controller' recommendations. - *x_out = x_val * ratio; - *y_out = -y_val * ratio; - } else { - // If the controller is in the deadzone zero out the magnitude. - *x_out = *y_out = 0.0f; - } -} - -float NormalizeTrigger(uint8_t value) { - return value < kXbox360TriggerDeadzone - ? 0 - : static_cast<float>(value - kXbox360TriggerDeadzone) / - (std::numeric_limits<uint8_t>::max() - - kXbox360TriggerDeadzone); -} - -float NormalizeXboxOneTrigger(uint16_t value) { - return value < kXboxOneTriggerDeadzone - ? 0 - : static_cast<float>(value - kXboxOneTriggerDeadzone) / - (kXboxOneTriggerMax - kXboxOneTriggerDeadzone); -} - -void NormalizeXbox360ButtonData(const Xbox360ButtonData& data, - XboxController::Data* normalized_data) { - normalized_data->buttons[0] = data.a; - normalized_data->buttons[1] = data.b; - normalized_data->buttons[2] = data.x; - normalized_data->buttons[3] = data.y; - normalized_data->buttons[4] = data.bumper_left; - normalized_data->buttons[5] = data.bumper_right; - normalized_data->buttons[6] = data.back; - normalized_data->buttons[7] = data.start; - normalized_data->buttons[8] = data.stick_left_click; - normalized_data->buttons[9] = data.stick_right_click; - normalized_data->buttons[10] = data.dpad_up; - normalized_data->buttons[11] = data.dpad_down; - normalized_data->buttons[12] = data.dpad_left; - normalized_data->buttons[13] = data.dpad_right; - normalized_data->buttons[14] = data.guide; - normalized_data->triggers[0] = NormalizeTrigger(data.trigger_left); - normalized_data->triggers[1] = NormalizeTrigger(data.trigger_right); - NormalizeAxis(data.stick_left_x, data.stick_left_y, kLeftThumbDeadzone, - &normalized_data->axes[0], &normalized_data->axes[1]); - NormalizeAxis(data.stick_right_x, data.stick_right_y, kRightThumbDeadzone, - &normalized_data->axes[2], &normalized_data->axes[3]); -} - -void NormalizeXboxOneButtonData(const XboxOneButtonData& data, - XboxController::Data* normalized_data) { - normalized_data->buttons[0] = data.a; - normalized_data->buttons[1] = data.b; - normalized_data->buttons[2] = data.x; - normalized_data->buttons[3] = data.y; - normalized_data->buttons[4] = data.bumper_left; - normalized_data->buttons[5] = data.bumper_right; - normalized_data->buttons[6] = data.back; - normalized_data->buttons[7] = data.start; - normalized_data->buttons[8] = data.stick_left_click; - normalized_data->buttons[9] = data.stick_right_click; - normalized_data->buttons[10] = data.dpad_up; - normalized_data->buttons[11] = data.dpad_down; - normalized_data->buttons[12] = data.dpad_left; - normalized_data->buttons[13] = data.dpad_right; - normalized_data->buttons[14] = data.sync; - normalized_data->triggers[0] = NormalizeXboxOneTrigger(data.trigger_left); - normalized_data->triggers[1] = NormalizeXboxOneTrigger(data.trigger_right); - NormalizeAxis(data.stick_left_x, data.stick_left_y, kLeftThumbDeadzone, - &normalized_data->axes[0], &normalized_data->axes[1]); - NormalizeAxis(data.stick_right_x, data.stick_right_y, kRightThumbDeadzone, - &normalized_data->axes[2], &normalized_data->axes[3]); -} - -} // namespace - -XboxController::XboxController(Delegate* delegate) - : device_(NULL), - interface_(NULL), - device_is_open_(false), - interface_is_open_(false), - read_buffer_size_(0), - led_pattern_(LED_NUM_PATTERNS), - location_id_(0), - delegate_(delegate), - controller_type_(UNKNOWN_CONTROLLER), - read_endpoint_(0), - control_endpoint_(0) {} - -XboxController::~XboxController() { - if (source_) - CFRunLoopSourceInvalidate(source_); - if (interface_ && interface_is_open_) - (*interface_)->USBInterfaceClose(interface_); - if (device_ && device_is_open_) - (*device_)->USBDeviceClose(device_); -} - -bool XboxController::OpenDevice(io_service_t service) { - IOCFPlugInInterface** plugin; - SInt32 score; // Unused, but required for IOCreatePlugInInterfaceForService. - kern_return_t kr = IOCreatePlugInInterfaceForService( - service, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, - &score); - if (kr != KERN_SUCCESS) - return false; - base::mac::ScopedIOPluginInterface<IOCFPlugInInterface> plugin_ref(plugin); - - HRESULT res = (*plugin)->QueryInterface( - plugin, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID320), - (LPVOID*)&device_); - if (!SUCCEEDED(res) || !device_) - return false; - - UInt16 vendor_id; - kr = (*device_)->GetDeviceVendor(device_, &vendor_id); - if (kr != KERN_SUCCESS || vendor_id != kVendorMicrosoft) - return false; - - UInt16 product_id; - kr = (*device_)->GetDeviceProduct(device_, &product_id); - if (kr != KERN_SUCCESS) - return false; - - IOUSBFindInterfaceRequest request; - switch (product_id) { - case kProductXbox360Controller: - controller_type_ = XBOX_360_CONTROLLER; - read_endpoint_ = kXbox360ReadEndpoint; - control_endpoint_ = kXbox360ControlEndpoint; - request.bInterfaceClass = 255; - request.bInterfaceSubClass = 93; - request.bInterfaceProtocol = 1; - request.bAlternateSetting = kIOUSBFindInterfaceDontCare; - break; - case kProductXboxOneController: - controller_type_ = XBOX_ONE_CONTROLLER; - read_endpoint_ = kXboxOneReadEndpoint; - control_endpoint_ = kXboxOneControlEndpoint; - request.bInterfaceClass = 255; - request.bInterfaceSubClass = 71; - request.bInterfaceProtocol = 208; - request.bAlternateSetting = kIOUSBFindInterfaceDontCare; - break; - default: - return false; - } - - // Open the device and configure it. - kr = (*device_)->USBDeviceOpen(device_); - if (kr != KERN_SUCCESS) - return false; - device_is_open_ = true; - - // Xbox controllers have one configuration option which has configuration - // value 1. Try to set it and fail if it couldn't be configured. - IOUSBConfigurationDescriptorPtr config_desc; - kr = (*device_)->GetConfigurationDescriptorPtr(device_, 0, &config_desc); - if (kr != KERN_SUCCESS) - return false; - kr = (*device_)->SetConfiguration(device_, config_desc->bConfigurationValue); - if (kr != KERN_SUCCESS) - return false; - - // The device has 4 interfaces. They are as follows: - // Protocol 1: - // - Endpoint 1 (in) : Controller events, including button presses. - // - Endpoint 2 (out): Rumble pack and LED control - // Protocol 2 has a single endpoint to read from a connected ChatPad device. - // Protocol 3 is used by a connected headset device. - // The device also has an interface on subclass 253, protocol 10 with no - // endpoints. It is unused. - // - // We don't currently support the ChatPad or headset, so protocol 1 is the - // only protocol we care about. - // - // For more detail, see - // https://github.com/Grumbel/xboxdrv/blob/master/PROTOCOL - io_iterator_t iter; - kr = (*device_)->CreateInterfaceIterator(device_, &request, &iter); - if (kr != KERN_SUCCESS) - return false; - base::mac::ScopedIOObject<io_iterator_t> iter_ref(iter); - - // There should be exactly one USB interface which matches the requested - // settings. - io_service_t usb_interface = IOIteratorNext(iter); - if (!usb_interface) - return false; - - // We need to make an InterfaceInterface to communicate with the device - // endpoint. This is the same process as earlier: first make a - // PluginInterface from the io_service then make the InterfaceInterface from - // that. - IOCFPlugInInterface** plugin_interface; - kr = IOCreatePlugInInterfaceForService( - usb_interface, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, - &plugin_interface, &score); - if (kr != KERN_SUCCESS || !plugin_interface) - return false; - base::mac::ScopedIOPluginInterface<IOCFPlugInInterface> interface_ref( - plugin_interface); - - // Release the USB interface, and any subsequent interfaces returned by the - // iterator. (There shouldn't be any, but in case a future device does - // contain more interfaces, this will serve to avoid memory leaks.) - do { - IOObjectRelease(usb_interface); - } while ((usb_interface = IOIteratorNext(iter))); - - // Actually create the interface. - res = (*plugin_interface) - ->QueryInterface(plugin_interface, - CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID300), - (LPVOID*)&interface_); - - if (!SUCCEEDED(res) || !interface_) - return false; - - // Actually open the interface. - kr = (*interface_)->USBInterfaceOpen(interface_); - if (kr != KERN_SUCCESS) - return false; - interface_is_open_ = true; - - CFRunLoopSourceRef source_ref; - kr = (*interface_)->CreateInterfaceAsyncEventSource(interface_, &source_ref); - if (kr != KERN_SUCCESS || !source_ref) - return false; - source_.reset(source_ref); - CFRunLoopAddSource(CFRunLoopGetCurrent(), source_, kCFRunLoopDefaultMode); - - // The interface should have two pipes. Pipe 1 with direction kUSBIn and pipe - // 2 with direction kUSBOut. Both pipes should have type kUSBInterrupt. - uint8_t num_endpoints; - kr = (*interface_)->GetNumEndpoints(interface_, &num_endpoints); - if (kr != KERN_SUCCESS || num_endpoints < 2) - return false; - - for (int i = 1; i <= 2; i++) { - uint8_t direction; - uint8_t number; - uint8_t transfer_type; - uint16_t max_packet_size; - uint8_t interval; - - kr = (*interface_) - ->GetPipeProperties(interface_, i, &direction, &number, - &transfer_type, &max_packet_size, &interval); - if (kr != KERN_SUCCESS || transfer_type != kUSBInterrupt) { - return false; - } - if (i == read_endpoint_) { - if (direction != kUSBIn) - return false; - read_buffer_.reset(new uint8_t[max_packet_size]); - read_buffer_size_ = max_packet_size; - QueueRead(); - } else if (i == control_endpoint_) { - if (direction != kUSBOut) - return false; - if (controller_type_ == XBOX_ONE_CONTROLLER) - WriteXboxOneInit(); - } - } - - // The location ID is unique per controller, and can be used to track - // controllers through reconnections (though if a controller is detached from - // one USB hub and attached to another, the location ID will change). - kr = (*device_)->GetLocationID(device_, &location_id_); - if (kr != KERN_SUCCESS) - return false; - - return true; -} - -void XboxController::SetLEDPattern(LEDPattern pattern) { - led_pattern_ = pattern; - const UInt8 length = 3; - - // This buffer will be released in WriteComplete when WritePipeAsync - // finishes. - UInt8* buffer = new UInt8[length]; - buffer[0] = static_cast<UInt8>(CONTROL_MESSAGE_SET_LED); - buffer[1] = length; - buffer[2] = static_cast<UInt8>(pattern); - kern_return_t kr = - (*interface_) - ->WritePipeAsync(interface_, control_endpoint_, buffer, - (UInt32)length, WriteComplete, buffer); - if (kr != KERN_SUCCESS) { - delete[] buffer; - IOError(); - return; - } -} - -int XboxController::GetVendorId() const { - return kVendorMicrosoft; -} - -int XboxController::GetProductId() const { - if (controller_type_ == XBOX_360_CONTROLLER) - return kProductXbox360Controller; - else - return kProductXboxOneController; -} - -XboxController::ControllerType XboxController::GetControllerType() const { - return controller_type_; -} - -void XboxController::WriteComplete(void* context, IOReturn result, void* arg0) { - UInt8* buffer = static_cast<UInt8*>(context); - delete[] buffer; - - // Ignoring any errors sending data, because they will usually only occur - // when the device is disconnected, in which case it really doesn't matter if - // the data got to the controller or not. - if (result != kIOReturnSuccess) - return; -} - -void XboxController::GotData(void* context, IOReturn result, void* arg0) { - size_t bytes_read = reinterpret_cast<size_t>(arg0); - XboxController* controller = static_cast<XboxController*>(context); - - if (result != kIOReturnSuccess) { - // This will happen if the device was disconnected. The gamepad has - // probably been destroyed by a meteorite. - controller->IOError(); - return; - } - - if (controller->GetControllerType() == XBOX_360_CONTROLLER) - controller->ProcessXbox360Packet(bytes_read); - else - controller->ProcessXboxOnePacket(bytes_read); - - // Queue up another read. - controller->QueueRead(); -} - -void XboxController::ProcessXbox360Packet(size_t length) { - if (length < 2) - return; - DCHECK(length <= read_buffer_size_); - if (length > read_buffer_size_) { - IOError(); - return; - } - uint8_t* buffer = read_buffer_.get(); - - if (buffer[1] != length) - // Length in packet doesn't match length reported by USB. - return; - - uint8_t type = buffer[0]; - buffer += 2; - length -= 2; - switch (type) { - case STATUS_MESSAGE_BUTTONS: { - if (length != sizeof(Xbox360ButtonData)) - return; - Xbox360ButtonData* data = reinterpret_cast<Xbox360ButtonData*>(buffer); - Data normalized_data; - NormalizeXbox360ButtonData(*data, &normalized_data); - delegate_->XboxControllerGotData(this, normalized_data); - break; - } - case STATUS_MESSAGE_LED: - if (length != 3) - return; - // The controller sends one of these messages every time the LED pattern - // is set, as well as once when it is plugged in. - if (led_pattern_ == LED_NUM_PATTERNS && buffer[0] < LED_NUM_PATTERNS) - led_pattern_ = static_cast<LEDPattern>(buffer[0]); - break; - default: - // Unknown packet: ignore! - break; - } -} - -void XboxController::ProcessXboxOnePacket(size_t length) { - if (length < 2) - return; - DCHECK(length <= read_buffer_size_); - if (length > read_buffer_size_) { - IOError(); - return; - } - uint8_t* buffer = read_buffer_.get(); - - uint8_t type = buffer[0]; - buffer += 4; - length -= 4; - switch (type) { - case XBOX_ONE_STATUS_MESSAGE_BUTTONS: { - if (length != sizeof(XboxOneButtonData)) - return; - XboxOneButtonData* data = reinterpret_cast<XboxOneButtonData*>(buffer); - Data normalized_data; - NormalizeXboxOneButtonData(*data, &normalized_data); - delegate_->XboxControllerGotData(this, normalized_data); - break; - } - default: - // Unknown packet: ignore! - break; - } -} - -void XboxController::QueueRead() { - kern_return_t kr = - (*interface_) - ->ReadPipeAsync(interface_, read_endpoint_, read_buffer_.get(), - read_buffer_size_, GotData, this); - if (kr != KERN_SUCCESS) - IOError(); -} - -void XboxController::IOError() { - delegate_->XboxControllerError(this); -} - -void XboxController::WriteXboxOneInit() { - const UInt8 length = 2; - - // This buffer will be released in WriteComplete when WritePipeAsync - // finishes. - UInt8* buffer = new UInt8[length]; - buffer[0] = 0x05; - buffer[1] = 0x20; - kern_return_t kr = - (*interface_) - ->WritePipeAsync(interface_, control_endpoint_, buffer, - (UInt32)length, WriteComplete, buffer); - if (kr != KERN_SUCCESS) { - delete[] buffer; - IOError(); - return; - } -} - -//----------------------------------------------------------------------------- - -XboxDataFetcher::XboxDataFetcher(Delegate* delegate) - : delegate_(delegate), listening_(false), source_(NULL), port_(NULL) {} - -XboxDataFetcher::~XboxDataFetcher() { - while (!controllers_.empty()) { - RemoveController(*controllers_.begin()); - } - UnregisterFromNotifications(); -} - -void XboxDataFetcher::DeviceAdded(void* context, io_iterator_t iterator) { - DCHECK(context); - XboxDataFetcher* fetcher = static_cast<XboxDataFetcher*>(context); - io_service_t ref; - while ((ref = IOIteratorNext(iterator))) { - base::mac::ScopedIOObject<io_service_t> scoped_ref(ref); - XboxController* controller = new XboxController(fetcher); - if (controller->OpenDevice(ref)) { - fetcher->AddController(controller); - } else { - delete controller; - } - } -} - -void XboxDataFetcher::DeviceRemoved(void* context, io_iterator_t iterator) { - DCHECK(context); - XboxDataFetcher* fetcher = static_cast<XboxDataFetcher*>(context); - io_service_t ref; - while ((ref = IOIteratorNext(iterator))) { - base::mac::ScopedIOObject<io_service_t> scoped_ref(ref); - base::ScopedCFTypeRef<CFNumberRef> number( - base::mac::CFCastStrict<CFNumberRef>(IORegistryEntryCreateCFProperty( - ref, CFSTR(kUSBDevicePropertyLocationID), kCFAllocatorDefault, - kNilOptions))); - UInt32 location_id = 0; - CFNumberGetValue(number, kCFNumberSInt32Type, &location_id); - fetcher->RemoveControllerByLocationID(location_id); - } -} - -bool XboxDataFetcher::RegisterForNotifications() { - if (listening_) - return true; - port_ = IONotificationPortCreate(kIOMasterPortDefault); - if (!port_) - return false; - source_ = IONotificationPortGetRunLoopSource(port_); - if (!source_) - return false; - CFRunLoopAddSource(CFRunLoopGetCurrent(), source_, kCFRunLoopDefaultMode); - - listening_ = true; - - if (!RegisterForDeviceNotifications( - kVendorMicrosoft, kProductXboxOneController, - &xbox_one_device_added_iter_, &xbox_one_device_removed_iter_)) - return false; - - if (!RegisterForDeviceNotifications( - kVendorMicrosoft, kProductXbox360Controller, - &xbox_360_device_added_iter_, &xbox_360_device_removed_iter_)) - return false; - - return true; -} - -bool XboxDataFetcher::RegisterForDeviceNotifications( - int vendor_id, - int product_id, - base::mac::ScopedIOObject<io_iterator_t>* added_iter, - base::mac::ScopedIOObject<io_iterator_t>* removed_iter) { - base::ScopedCFTypeRef<CFNumberRef> vendor_cf( - CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vendor_id)); - base::ScopedCFTypeRef<CFNumberRef> product_cf( - CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &product_id)); - base::ScopedCFTypeRef<CFMutableDictionaryRef> matching_dict( - IOServiceMatching(kIOUSBDeviceClassName)); - if (!matching_dict) - return false; - CFDictionarySetValue(matching_dict, CFSTR(kUSBVendorID), vendor_cf); - CFDictionarySetValue(matching_dict, CFSTR(kUSBProductID), product_cf); - - // IOServiceAddMatchingNotification() releases the dictionary when it's done. - // Retain it before each call to IOServiceAddMatchingNotification to keep - // things balanced. - CFRetain(matching_dict); - io_iterator_t device_added_iter; - IOReturn ret; - ret = IOServiceAddMatchingNotification(port_, kIOFirstMatchNotification, - matching_dict, DeviceAdded, this, - &device_added_iter); - added_iter->reset(device_added_iter); - if (ret != kIOReturnSuccess) { - LOG(ERROR) << "Error listening for Xbox controller add events: " << ret; - return false; - } - DeviceAdded(this, added_iter->get()); - - CFRetain(matching_dict); - io_iterator_t device_removed_iter; - ret = IOServiceAddMatchingNotification(port_, kIOTerminatedNotification, - matching_dict, DeviceRemoved, this, - &device_removed_iter); - removed_iter->reset(device_removed_iter); - if (ret != kIOReturnSuccess) { - LOG(ERROR) << "Error listening for Xbox controller remove events: " << ret; - return false; - } - DeviceRemoved(this, removed_iter->get()); - return true; -} - -void XboxDataFetcher::UnregisterFromNotifications() { - if (!listening_) - return; - listening_ = false; - if (source_) - CFRunLoopSourceInvalidate(source_); - if (port_) - IONotificationPortDestroy(port_); - port_ = NULL; -} - -XboxController* XboxDataFetcher::ControllerForLocation(UInt32 location_id) { - for (std::set<XboxController*>::iterator i = controllers_.begin(); - i != controllers_.end(); ++i) { - if ((*i)->location_id() == location_id) - return *i; - } - return NULL; -} - -void XboxDataFetcher::AddController(XboxController* controller) { - DCHECK(!ControllerForLocation(controller->location_id())) - << "Controller with location ID " << controller->location_id() - << " already exists in the set of controllers."; - controllers_.insert(controller); - delegate_->XboxDeviceAdd(controller); -} - -void XboxDataFetcher::RemoveController(XboxController* controller) { - delegate_->XboxDeviceRemove(controller); - controllers_.erase(controller); - delete controller; -} - -void XboxDataFetcher::RemoveControllerByLocationID(uint32_t location_id) { - XboxController* controller = NULL; - for (std::set<XboxController*>::iterator i = controllers_.begin(); - i != controllers_.end(); ++i) { - if ((*i)->location_id() == location_id) { - controller = *i; - break; - } - } - if (controller) - RemoveController(controller); -} - -void XboxDataFetcher::XboxControllerGotData(XboxController* controller, - const XboxController::Data& data) { - delegate_->XboxValueChanged(controller, data); -} - -void XboxDataFetcher::XboxControllerError(XboxController* controller) { - RemoveController(controller); -}
diff --git a/device/gamepad/xbox_data_fetcher_mac.h b/device/gamepad/xbox_data_fetcher_mac.h index 13303d1..1e7f9f6 100644 --- a/device/gamepad/xbox_data_fetcher_mac.h +++ b/device/gamepad/xbox_data_fetcher_mac.h
@@ -17,6 +17,12 @@ #include "base/mac/scoped_ioobject.h" #include "base/mac/scoped_ioplugininterface.h" #include "base/macros.h" +#include "device/gamepad/gamepad_data_fetcher.h" + +struct IOUSBDeviceStruct320; +struct IOUSBInterfaceStruct300; + +namespace device { class XboxController { public: @@ -101,11 +107,11 @@ // Handle for the USB device. IOUSBDeviceStruct320 is the latest version of // the device API that is supported on Mac OS 10.6. - base::mac::ScopedIOPluginInterface<struct IOUSBDeviceStruct320> device_; + base::mac::ScopedIOPluginInterface<IOUSBDeviceStruct320> device_; // Handle for the interface on the device which sends button and analog data. // The other interfaces (for the ChatPad and headset) are ignored. - base::mac::ScopedIOPluginInterface<struct IOUSBInterfaceStruct300> interface_; + base::mac::ScopedIOPluginInterface<IOUSBInterfaceStruct300> interface_; bool device_is_open_; bool interface_is_open_; @@ -136,18 +142,19 @@ DISALLOW_COPY_AND_ASSIGN(XboxController); }; -class XboxDataFetcher : public XboxController::Delegate { +class XboxDataFetcher : public GamepadDataFetcher, + public XboxController::Delegate { public: - class Delegate { - public: - virtual void XboxDeviceAdd(XboxController* device) = 0; - virtual void XboxDeviceRemove(XboxController* device) = 0; - virtual void XboxValueChanged(XboxController* device, - const XboxController::Data& data) = 0; - }; + typedef GamepadDataFetcherFactoryImpl<XboxDataFetcher, + GAMEPAD_SOURCE_MAC_XBOX> + Factory; - explicit XboxDataFetcher(Delegate* delegate); - virtual ~XboxDataFetcher(); + XboxDataFetcher(); + ~XboxDataFetcher() override; + + GamepadSource source() override; + + void GetGamepadData(bool devices_changed_hint) override; bool RegisterForNotifications(); bool RegisterForDeviceNotifications( @@ -162,6 +169,7 @@ private: static void DeviceAdded(void* context, io_iterator_t iterator); static void DeviceRemoved(void* context, io_iterator_t iterator); + void OnAddedToProvider() override; void AddController(XboxController* controller); void RemoveController(XboxController* controller); void RemoveControllerByLocationID(uint32_t id); @@ -169,8 +177,6 @@ const XboxController::Data& data) override; void XboxControllerError(XboxController* controller) override; - Delegate* delegate_; - std::set<XboxController*> controllers_; bool listening_; @@ -187,4 +193,6 @@ DISALLOW_COPY_AND_ASSIGN(XboxDataFetcher); }; +} // namespace device + #endif // DEVICE_GAMEPAD_XBOX_DATA_FETCHER_MAC_H_
diff --git a/device/gamepad/xbox_data_fetcher_mac.mm b/device/gamepad/xbox_data_fetcher_mac.mm new file mode 100644 index 0000000..7b15fc72 --- /dev/null +++ b/device/gamepad/xbox_data_fetcher_mac.mm
@@ -0,0 +1,846 @@ +// 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 "device/gamepad/xbox_data_fetcher_mac.h" + +#include <algorithm> +#include <cmath> +#include <limits> + +#include <CoreFoundation/CoreFoundation.h> +#include <IOKit/IOCFPlugIn.h> +#include <IOKit/IOKitLib.h> +#include <IOKit/usb/IOUSBLib.h> +#include <IOKit/usb/USB.h> + +#include "base/logging.h" +#include "base/mac/foundation_util.h" + +using blink::WebGamepad; + +namespace device { + +namespace { + +const int kVendorMicrosoft = 0x045e; +const int kProductXbox360Controller = 0x028e; +const int kProductXboxOneController = 0x02d1; + +const int kXbox360ReadEndpoint = 1; +const int kXbox360ControlEndpoint = 2; + +const int kXboxOneReadEndpoint = 2; +const int kXboxOneControlEndpoint = 1; + +enum { + STATUS_MESSAGE_BUTTONS = 0, + STATUS_MESSAGE_LED = 1, + + // Apparently this message tells you if the rumble pack is disabled in the + // controller. If the rumble pack is disabled, vibration control messages + // have no effect. + STATUS_MESSAGE_RUMBLE = 3, +}; + +enum { + XBOX_ONE_STATUS_MESSAGE_BUTTONS = 0x20, +}; + +enum { + CONTROL_MESSAGE_SET_RUMBLE = 0, + CONTROL_MESSAGE_SET_LED = 1, +}; + +#pragma pack(push, 1) +struct Xbox360ButtonData { + bool dpad_up : 1; + bool dpad_down : 1; + bool dpad_left : 1; + bool dpad_right : 1; + + bool start : 1; + bool back : 1; + bool stick_left_click : 1; + bool stick_right_click : 1; + + bool bumper_left : 1; + bool bumper_right : 1; + bool guide : 1; + bool dummy1 : 1; // Always 0. + + bool a : 1; + bool b : 1; + bool x : 1; + bool y : 1; + + uint8_t trigger_left; + uint8_t trigger_right; + + int16_t stick_left_x; + int16_t stick_left_y; + int16_t stick_right_x; + int16_t stick_right_y; + + // Always 0. + uint32_t dummy2; + uint16_t dummy3; +}; + +struct XboxOneButtonData { + bool sync : 1; + bool dummy1 : 1; // Always 0. + bool start : 1; + bool back : 1; + + bool a : 1; + bool b : 1; + bool x : 1; + bool y : 1; + + bool dpad_up : 1; + bool dpad_down : 1; + bool dpad_left : 1; + bool dpad_right : 1; + + bool bumper_left : 1; + bool bumper_right : 1; + bool stick_left_click : 1; + bool stick_right_click : 1; + + uint16_t trigger_left; + uint16_t trigger_right; + + int16_t stick_left_x; + int16_t stick_left_y; + int16_t stick_right_x; + int16_t stick_right_y; +}; +#pragma pack(pop) + +static_assert(sizeof(Xbox360ButtonData) == 18, "xbox button data wrong size"); +static_assert(sizeof(XboxOneButtonData) == 14, "xbox button data wrong size"); + +// From MSDN: +// http://msdn.microsoft.com/en-us/library/windows/desktop/ee417001(v=vs.85).aspx#dead_zone +const int16_t kLeftThumbDeadzone = 7849; +const int16_t kRightThumbDeadzone = 8689; +const uint8_t kXbox360TriggerDeadzone = 30; +const uint16_t kXboxOneTriggerMax = 1023; +const uint16_t kXboxOneTriggerDeadzone = 120; + +void NormalizeAxis(int16_t x, + int16_t y, + int16_t deadzone, + float* x_out, + float* y_out) { + float x_val = x; + float y_val = y; + + // Determine how far the stick is pushed. + float real_magnitude = std::sqrt(x_val * x_val + y_val * y_val); + + // Check if the controller is outside a circular dead zone. + if (real_magnitude > deadzone) { + // Clip the magnitude at its expected maximum value. + float magnitude = std::min(32767.0f, real_magnitude); + + // Adjust magnitude relative to the end of the dead zone. + magnitude -= deadzone; + + // Normalize the magnitude with respect to its expected range giving a + // magnitude value of 0.0 to 1.0 + float ratio = (magnitude / (32767 - deadzone)) / real_magnitude; + + // Y is negated because xbox controllers have an opposite sign from + // the 'standard controller' recommendations. + *x_out = x_val * ratio; + *y_out = -y_val * ratio; + } else { + // If the controller is in the deadzone zero out the magnitude. + *x_out = *y_out = 0.0f; + } +} + +float NormalizeTrigger(uint8_t value) { + return value < kXbox360TriggerDeadzone + ? 0 + : static_cast<float>(value - kXbox360TriggerDeadzone) / + (std::numeric_limits<uint8_t>::max() - + kXbox360TriggerDeadzone); +} + +float NormalizeXboxOneTrigger(uint16_t value) { + return value < kXboxOneTriggerDeadzone + ? 0 + : static_cast<float>(value - kXboxOneTriggerDeadzone) / + (kXboxOneTriggerMax - kXboxOneTriggerDeadzone); +} + +void NormalizeXbox360ButtonData(const Xbox360ButtonData& data, + XboxController::Data* normalized_data) { + normalized_data->buttons[0] = data.a; + normalized_data->buttons[1] = data.b; + normalized_data->buttons[2] = data.x; + normalized_data->buttons[3] = data.y; + normalized_data->buttons[4] = data.bumper_left; + normalized_data->buttons[5] = data.bumper_right; + normalized_data->buttons[6] = data.back; + normalized_data->buttons[7] = data.start; + normalized_data->buttons[8] = data.stick_left_click; + normalized_data->buttons[9] = data.stick_right_click; + normalized_data->buttons[10] = data.dpad_up; + normalized_data->buttons[11] = data.dpad_down; + normalized_data->buttons[12] = data.dpad_left; + normalized_data->buttons[13] = data.dpad_right; + normalized_data->buttons[14] = data.guide; + normalized_data->triggers[0] = NormalizeTrigger(data.trigger_left); + normalized_data->triggers[1] = NormalizeTrigger(data.trigger_right); + NormalizeAxis(data.stick_left_x, data.stick_left_y, kLeftThumbDeadzone, + &normalized_data->axes[0], &normalized_data->axes[1]); + NormalizeAxis(data.stick_right_x, data.stick_right_y, kRightThumbDeadzone, + &normalized_data->axes[2], &normalized_data->axes[3]); +} + +void NormalizeXboxOneButtonData(const XboxOneButtonData& data, + XboxController::Data* normalized_data) { + normalized_data->buttons[0] = data.a; + normalized_data->buttons[1] = data.b; + normalized_data->buttons[2] = data.x; + normalized_data->buttons[3] = data.y; + normalized_data->buttons[4] = data.bumper_left; + normalized_data->buttons[5] = data.bumper_right; + normalized_data->buttons[6] = data.back; + normalized_data->buttons[7] = data.start; + normalized_data->buttons[8] = data.stick_left_click; + normalized_data->buttons[9] = data.stick_right_click; + normalized_data->buttons[10] = data.dpad_up; + normalized_data->buttons[11] = data.dpad_down; + normalized_data->buttons[12] = data.dpad_left; + normalized_data->buttons[13] = data.dpad_right; + normalized_data->buttons[14] = data.sync; + normalized_data->triggers[0] = NormalizeXboxOneTrigger(data.trigger_left); + normalized_data->triggers[1] = NormalizeXboxOneTrigger(data.trigger_right); + NormalizeAxis(data.stick_left_x, data.stick_left_y, kLeftThumbDeadzone, + &normalized_data->axes[0], &normalized_data->axes[1]); + NormalizeAxis(data.stick_right_x, data.stick_right_y, kRightThumbDeadzone, + &normalized_data->axes[2], &normalized_data->axes[3]); +} + +void CopyNSStringAsUTF16LittleEndian(NSString* src, + blink::WebUChar* dest, + size_t dest_len) { + NSData* as16 = [src dataUsingEncoding:NSUTF16LittleEndianStringEncoding]; + memset(dest, 0, dest_len); + [as16 getBytes:dest length:dest_len - sizeof(blink::WebUChar)]; +} + +} // namespace + +XboxController::XboxController(Delegate* delegate) + : device_(NULL), + interface_(NULL), + device_is_open_(false), + interface_is_open_(false), + read_buffer_size_(0), + led_pattern_(LED_NUM_PATTERNS), + location_id_(0), + delegate_(delegate), + controller_type_(UNKNOWN_CONTROLLER), + read_endpoint_(0), + control_endpoint_(0) {} + +XboxController::~XboxController() { + if (source_) + CFRunLoopSourceInvalidate(source_); + if (interface_ && interface_is_open_) + (*interface_)->USBInterfaceClose(interface_); + if (device_ && device_is_open_) + (*device_)->USBDeviceClose(device_); +} + +bool XboxController::OpenDevice(io_service_t service) { + IOCFPlugInInterface** plugin; + SInt32 score; // Unused, but required for IOCreatePlugInInterfaceForService. + kern_return_t kr = IOCreatePlugInInterfaceForService( + service, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, + &score); + if (kr != KERN_SUCCESS) + return false; + base::mac::ScopedIOPluginInterface<IOCFPlugInInterface> plugin_ref(plugin); + + HRESULT res = (*plugin)->QueryInterface( + plugin, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID320), + (LPVOID*)&device_); + if (!SUCCEEDED(res) || !device_) + return false; + + UInt16 vendor_id; + kr = (*device_)->GetDeviceVendor(device_, &vendor_id); + if (kr != KERN_SUCCESS || vendor_id != kVendorMicrosoft) + return false; + + UInt16 product_id; + kr = (*device_)->GetDeviceProduct(device_, &product_id); + if (kr != KERN_SUCCESS) + return false; + + IOUSBFindInterfaceRequest request; + switch (product_id) { + case kProductXbox360Controller: + controller_type_ = XBOX_360_CONTROLLER; + read_endpoint_ = kXbox360ReadEndpoint; + control_endpoint_ = kXbox360ControlEndpoint; + request.bInterfaceClass = 255; + request.bInterfaceSubClass = 93; + request.bInterfaceProtocol = 1; + request.bAlternateSetting = kIOUSBFindInterfaceDontCare; + break; + case kProductXboxOneController: + controller_type_ = XBOX_ONE_CONTROLLER; + read_endpoint_ = kXboxOneReadEndpoint; + control_endpoint_ = kXboxOneControlEndpoint; + request.bInterfaceClass = 255; + request.bInterfaceSubClass = 71; + request.bInterfaceProtocol = 208; + request.bAlternateSetting = kIOUSBFindInterfaceDontCare; + break; + default: + return false; + } + + // Open the device and configure it. + kr = (*device_)->USBDeviceOpen(device_); + if (kr != KERN_SUCCESS) + return false; + device_is_open_ = true; + + // Xbox controllers have one configuration option which has configuration + // value 1. Try to set it and fail if it couldn't be configured. + IOUSBConfigurationDescriptorPtr config_desc; + kr = (*device_)->GetConfigurationDescriptorPtr(device_, 0, &config_desc); + if (kr != KERN_SUCCESS) + return false; + kr = (*device_)->SetConfiguration(device_, config_desc->bConfigurationValue); + if (kr != KERN_SUCCESS) + return false; + + // The device has 4 interfaces. They are as follows: + // Protocol 1: + // - Endpoint 1 (in) : Controller events, including button presses. + // - Endpoint 2 (out): Rumble pack and LED control + // Protocol 2 has a single endpoint to read from a connected ChatPad device. + // Protocol 3 is used by a connected headset device. + // The device also has an interface on subclass 253, protocol 10 with no + // endpoints. It is unused. + // + // We don't currently support the ChatPad or headset, so protocol 1 is the + // only protocol we care about. + // + // For more detail, see + // https://github.com/Grumbel/xboxdrv/blob/master/PROTOCOL + io_iterator_t iter; + kr = (*device_)->CreateInterfaceIterator(device_, &request, &iter); + if (kr != KERN_SUCCESS) + return false; + base::mac::ScopedIOObject<io_iterator_t> iter_ref(iter); + + // There should be exactly one USB interface which matches the requested + // settings. + io_service_t usb_interface = IOIteratorNext(iter); + if (!usb_interface) + return false; + + // We need to make an InterfaceInterface to communicate with the device + // endpoint. This is the same process as earlier: first make a + // PluginInterface from the io_service then make the InterfaceInterface from + // that. + IOCFPlugInInterface** plugin_interface; + kr = IOCreatePlugInInterfaceForService( + usb_interface, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, + &plugin_interface, &score); + if (kr != KERN_SUCCESS || !plugin_interface) + return false; + base::mac::ScopedIOPluginInterface<IOCFPlugInInterface> interface_ref( + plugin_interface); + + // Release the USB interface, and any subsequent interfaces returned by the + // iterator. (There shouldn't be any, but in case a future device does + // contain more interfaces, this will serve to avoid memory leaks.) + do { + IOObjectRelease(usb_interface); + } while ((usb_interface = IOIteratorNext(iter))); + + // Actually create the interface. + res = (*plugin_interface) + ->QueryInterface(plugin_interface, + CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID300), + (LPVOID*)&interface_); + + if (!SUCCEEDED(res) || !interface_) + return false; + + // Actually open the interface. + kr = (*interface_)->USBInterfaceOpen(interface_); + if (kr != KERN_SUCCESS) + return false; + interface_is_open_ = true; + + CFRunLoopSourceRef source_ref; + kr = (*interface_)->CreateInterfaceAsyncEventSource(interface_, &source_ref); + if (kr != KERN_SUCCESS || !source_ref) + return false; + source_.reset(source_ref); + CFRunLoopAddSource(CFRunLoopGetCurrent(), source_, kCFRunLoopDefaultMode); + + // The interface should have two pipes. Pipe 1 with direction kUSBIn and pipe + // 2 with direction kUSBOut. Both pipes should have type kUSBInterrupt. + uint8_t num_endpoints; + kr = (*interface_)->GetNumEndpoints(interface_, &num_endpoints); + if (kr != KERN_SUCCESS || num_endpoints < 2) + return false; + + for (int i = 1; i <= 2; i++) { + uint8_t direction; + uint8_t number; + uint8_t transfer_type; + uint16_t max_packet_size; + uint8_t interval; + + kr = (*interface_) + ->GetPipeProperties(interface_, i, &direction, &number, + &transfer_type, &max_packet_size, &interval); + if (kr != KERN_SUCCESS || transfer_type != kUSBInterrupt) { + return false; + } + if (i == read_endpoint_) { + if (direction != kUSBIn) + return false; + read_buffer_.reset(new uint8_t[max_packet_size]); + read_buffer_size_ = max_packet_size; + QueueRead(); + } else if (i == control_endpoint_) { + if (direction != kUSBOut) + return false; + if (controller_type_ == XBOX_ONE_CONTROLLER) + WriteXboxOneInit(); + } + } + + // The location ID is unique per controller, and can be used to track + // controllers through reconnections (though if a controller is detached from + // one USB hub and attached to another, the location ID will change). + kr = (*device_)->GetLocationID(device_, &location_id_); + if (kr != KERN_SUCCESS) + return false; + + return true; +} + +void XboxController::SetLEDPattern(LEDPattern pattern) { + led_pattern_ = pattern; + const UInt8 length = 3; + + // This buffer will be released in WriteComplete when WritePipeAsync + // finishes. + UInt8* buffer = new UInt8[length]; + buffer[0] = static_cast<UInt8>(CONTROL_MESSAGE_SET_LED); + buffer[1] = length; + buffer[2] = static_cast<UInt8>(pattern); + kern_return_t kr = + (*interface_) + ->WritePipeAsync(interface_, control_endpoint_, buffer, + (UInt32)length, WriteComplete, buffer); + if (kr != KERN_SUCCESS) { + delete[] buffer; + IOError(); + return; + } +} + +int XboxController::GetVendorId() const { + return kVendorMicrosoft; +} + +int XboxController::GetProductId() const { + if (controller_type_ == XBOX_360_CONTROLLER) + return kProductXbox360Controller; + else + return kProductXboxOneController; +} + +XboxController::ControllerType XboxController::GetControllerType() const { + return controller_type_; +} + +void XboxController::WriteComplete(void* context, IOReturn result, void* arg0) { + UInt8* buffer = static_cast<UInt8*>(context); + delete[] buffer; + + // Ignoring any errors sending data, because they will usually only occur + // when the device is disconnected, in which case it really doesn't matter if + // the data got to the controller or not. + if (result != kIOReturnSuccess) + return; +} + +void XboxController::GotData(void* context, IOReturn result, void* arg0) { + size_t bytes_read = reinterpret_cast<size_t>(arg0); + XboxController* controller = static_cast<XboxController*>(context); + + if (result != kIOReturnSuccess) { + // This will happen if the device was disconnected. The gamepad has + // probably been destroyed by a meteorite. + controller->IOError(); + return; + } + + if (controller->GetControllerType() == XBOX_360_CONTROLLER) + controller->ProcessXbox360Packet(bytes_read); + else + controller->ProcessXboxOnePacket(bytes_read); + + // Queue up another read. + controller->QueueRead(); +} + +void XboxController::ProcessXbox360Packet(size_t length) { + if (length < 2) + return; + DCHECK(length <= read_buffer_size_); + if (length > read_buffer_size_) { + IOError(); + return; + } + uint8_t* buffer = read_buffer_.get(); + + if (buffer[1] != length) + // Length in packet doesn't match length reported by USB. + return; + + uint8_t type = buffer[0]; + buffer += 2; + length -= 2; + switch (type) { + case STATUS_MESSAGE_BUTTONS: { + if (length != sizeof(Xbox360ButtonData)) + return; + Xbox360ButtonData* data = reinterpret_cast<Xbox360ButtonData*>(buffer); + Data normalized_data; + NormalizeXbox360ButtonData(*data, &normalized_data); + delegate_->XboxControllerGotData(this, normalized_data); + break; + } + case STATUS_MESSAGE_LED: + if (length != 3) + return; + // The controller sends one of these messages every time the LED pattern + // is set, as well as once when it is plugged in. + if (led_pattern_ == LED_NUM_PATTERNS && buffer[0] < LED_NUM_PATTERNS) + led_pattern_ = static_cast<LEDPattern>(buffer[0]); + break; + default: + // Unknown packet: ignore! + break; + } +} + +void XboxController::ProcessXboxOnePacket(size_t length) { + if (length < 2) + return; + DCHECK(length <= read_buffer_size_); + if (length > read_buffer_size_) { + IOError(); + return; + } + uint8_t* buffer = read_buffer_.get(); + + uint8_t type = buffer[0]; + buffer += 4; + length -= 4; + switch (type) { + case XBOX_ONE_STATUS_MESSAGE_BUTTONS: { + if (length != sizeof(XboxOneButtonData)) + return; + XboxOneButtonData* data = reinterpret_cast<XboxOneButtonData*>(buffer); + Data normalized_data; + NormalizeXboxOneButtonData(*data, &normalized_data); + delegate_->XboxControllerGotData(this, normalized_data); + break; + } + default: + // Unknown packet: ignore! + break; + } +} + +void XboxController::QueueRead() { + kern_return_t kr = + (*interface_) + ->ReadPipeAsync(interface_, read_endpoint_, read_buffer_.get(), + read_buffer_size_, GotData, this); + if (kr != KERN_SUCCESS) + IOError(); +} + +void XboxController::IOError() { + delegate_->XboxControllerError(this); +} + +void XboxController::WriteXboxOneInit() { + const UInt8 length = 2; + + // This buffer will be released in WriteComplete when WritePipeAsync + // finishes. + UInt8* buffer = new UInt8[length]; + buffer[0] = 0x05; + buffer[1] = 0x20; + kern_return_t kr = + (*interface_) + ->WritePipeAsync(interface_, control_endpoint_, buffer, + (UInt32)length, WriteComplete, buffer); + if (kr != KERN_SUCCESS) { + delete[] buffer; + IOError(); + return; + } +} + +//----------------------------------------------------------------------------- + +XboxDataFetcher::XboxDataFetcher() + : listening_(false), source_(NULL), port_(NULL) {} + +XboxDataFetcher::~XboxDataFetcher() { + while (!controllers_.empty()) { + RemoveController(*controllers_.begin()); + } + UnregisterFromNotifications(); +} + +GamepadSource XboxDataFetcher::source() { + return Factory::static_source(); +} + +void XboxDataFetcher::GetGamepadData(bool devices_changed_hint) { + // This just loops through all the connected pads and "pings" them to indicate + // that they're still active. + for (const auto& controller : controllers_) { + GetPadState(controller->location_id()); + } +} + +void XboxDataFetcher::OnAddedToProvider() { + RegisterForNotifications(); +} + +void XboxDataFetcher::DeviceAdded(void* context, io_iterator_t iterator) { + DCHECK(context); + XboxDataFetcher* fetcher = static_cast<XboxDataFetcher*>(context); + io_service_t ref; + while ((ref = IOIteratorNext(iterator))) { + base::mac::ScopedIOObject<io_service_t> scoped_ref(ref); + XboxController* controller = new XboxController(fetcher); + if (controller->OpenDevice(ref)) { + fetcher->AddController(controller); + } else { + delete controller; + } + } +} + +void XboxDataFetcher::DeviceRemoved(void* context, io_iterator_t iterator) { + DCHECK(context); + XboxDataFetcher* fetcher = static_cast<XboxDataFetcher*>(context); + io_service_t ref; + while ((ref = IOIteratorNext(iterator))) { + base::mac::ScopedIOObject<io_service_t> scoped_ref(ref); + base::ScopedCFTypeRef<CFNumberRef> number( + base::mac::CFCastStrict<CFNumberRef>(IORegistryEntryCreateCFProperty( + ref, CFSTR(kUSBDevicePropertyLocationID), kCFAllocatorDefault, + kNilOptions))); + UInt32 location_id = 0; + CFNumberGetValue(number, kCFNumberSInt32Type, &location_id); + fetcher->RemoveControllerByLocationID(location_id); + } +} + +bool XboxDataFetcher::RegisterForNotifications() { + if (listening_) + return true; + port_ = IONotificationPortCreate(kIOMasterPortDefault); + if (!port_) + return false; + source_ = IONotificationPortGetRunLoopSource(port_); + if (!source_) + return false; + CFRunLoopAddSource(CFRunLoopGetCurrent(), source_, kCFRunLoopDefaultMode); + + listening_ = true; + + if (!RegisterForDeviceNotifications( + kVendorMicrosoft, kProductXboxOneController, + &xbox_one_device_added_iter_, &xbox_one_device_removed_iter_)) + return false; + + if (!RegisterForDeviceNotifications( + kVendorMicrosoft, kProductXbox360Controller, + &xbox_360_device_added_iter_, &xbox_360_device_removed_iter_)) + return false; + + return true; +} + +bool XboxDataFetcher::RegisterForDeviceNotifications( + int vendor_id, + int product_id, + base::mac::ScopedIOObject<io_iterator_t>* added_iter, + base::mac::ScopedIOObject<io_iterator_t>* removed_iter) { + base::ScopedCFTypeRef<CFNumberRef> vendor_cf( + CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vendor_id)); + base::ScopedCFTypeRef<CFNumberRef> product_cf( + CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &product_id)); + base::ScopedCFTypeRef<CFMutableDictionaryRef> matching_dict( + IOServiceMatching(kIOUSBDeviceClassName)); + if (!matching_dict) + return false; + CFDictionarySetValue(matching_dict, CFSTR(kUSBVendorID), vendor_cf); + CFDictionarySetValue(matching_dict, CFSTR(kUSBProductID), product_cf); + + // IOServiceAddMatchingNotification() releases the dictionary when it's done. + // Retain it before each call to IOServiceAddMatchingNotification to keep + // things balanced. + CFRetain(matching_dict); + io_iterator_t device_added_iter; + IOReturn ret; + ret = IOServiceAddMatchingNotification(port_, kIOFirstMatchNotification, + matching_dict, DeviceAdded, this, + &device_added_iter); + added_iter->reset(device_added_iter); + if (ret != kIOReturnSuccess) { + LOG(ERROR) << "Error listening for Xbox controller add events: " << ret; + return false; + } + DeviceAdded(this, added_iter->get()); + + CFRetain(matching_dict); + io_iterator_t device_removed_iter; + ret = IOServiceAddMatchingNotification(port_, kIOTerminatedNotification, + matching_dict, DeviceRemoved, this, + &device_removed_iter); + removed_iter->reset(device_removed_iter); + if (ret != kIOReturnSuccess) { + LOG(ERROR) << "Error listening for Xbox controller remove events: " << ret; + return false; + } + DeviceRemoved(this, removed_iter->get()); + return true; +} + +void XboxDataFetcher::UnregisterFromNotifications() { + if (!listening_) + return; + listening_ = false; + if (source_) + CFRunLoopSourceInvalidate(source_); + if (port_) + IONotificationPortDestroy(port_); + port_ = NULL; +} + +XboxController* XboxDataFetcher::ControllerForLocation(UInt32 location_id) { + for (std::set<XboxController*>::iterator i = controllers_.begin(); + i != controllers_.end(); ++i) { + if ((*i)->location_id() == location_id) + return *i; + } + return NULL; +} + +void XboxDataFetcher::AddController(XboxController* controller) { + DCHECK(!ControllerForLocation(controller->location_id())) + << "Controller with location ID " << controller->location_id() + << " already exists in the set of controllers."; + PadState* state = GetPadState(controller->location_id()); + if (!state) { + delete controller; + return; // No available slot for this device + } + + controllers_.insert(controller); + + controller->SetLEDPattern((XboxController::LEDPattern)( + XboxController::LED_FLASH_TOP_LEFT + controller->location_id())); + + NSString* ident = [NSString + stringWithFormat:@"%@ (STANDARD GAMEPAD Vendor: %04x Product: %04x)", + controller->GetControllerType() == + XboxController::XBOX_360_CONTROLLER + ? @"Xbox 360 Controller" + : @"Xbox One Controller", + controller->GetProductId(), controller->GetVendorId()]; + CopyNSStringAsUTF16LittleEndian(ident, state->data.id, + sizeof(state->data.id)); + + CopyNSStringAsUTF16LittleEndian(@"standard", state->data.mapping, + sizeof(state->data.mapping)); + + state->data.connected = true; + state->data.axesLength = 4; + state->data.buttonsLength = 17; + state->data.timestamp = 0; + state->mapper = 0; + state->axis_mask = 0; + state->button_mask = 0; +} + +void XboxDataFetcher::RemoveController(XboxController* controller) { + controllers_.erase(controller); + delete controller; +} + +void XboxDataFetcher::RemoveControllerByLocationID(uint32_t location_id) { + XboxController* controller = NULL; + for (std::set<XboxController*>::iterator i = controllers_.begin(); + i != controllers_.end(); ++i) { + if ((*i)->location_id() == location_id) { + controller = *i; + break; + } + } + if (controller) + RemoveController(controller); +} + +void XboxDataFetcher::XboxControllerGotData(XboxController* controller, + const XboxController::Data& data) { + PadState* state = GetPadState(controller->location_id()); + if (!state) + return; // No available slot for this device + + WebGamepad& pad = state->data; + + for (size_t i = 0; i < 6; i++) { + pad.buttons[i].pressed = data.buttons[i]; + pad.buttons[i].value = data.buttons[i] ? 1.0f : 0.0f; + } + pad.buttons[6].pressed = data.triggers[0] > kDefaultButtonPressedThreshold; + pad.buttons[6].value = data.triggers[0]; + pad.buttons[7].pressed = data.triggers[1] > kDefaultButtonPressedThreshold; + pad.buttons[7].value = data.triggers[1]; + for (size_t i = 8; i < 17; i++) { + pad.buttons[i].pressed = data.buttons[i - 2]; + pad.buttons[i].value = data.buttons[i - 2] ? 1.0f : 0.0f; + } + for (size_t i = 0; i < arraysize(data.axes); i++) { + pad.axes[i] = data.axes[i]; + } + + pad.timestamp = base::TimeTicks::Now().ToInternalValue(); +} + +void XboxDataFetcher::XboxControllerError(XboxController* controller) { + RemoveController(controller); +} + +} // namespace device
diff --git a/device/hid/hid_report_descriptor.cc b/device/hid/hid_report_descriptor.cc index 15789c5..f3f3a30 100644 --- a/device/hid/hid_report_descriptor.cc +++ b/device/hid/hid_report_descriptor.cc
@@ -37,7 +37,7 @@ DCHECK(max_input_report_size); DCHECK(max_output_report_size); DCHECK(max_feature_report_size); - STLClearObject(top_level_collections); + base::STLClearObject(top_level_collections); *has_report_id = false; *max_input_report_size = 0;
diff --git a/device/hid/hid_service.cc b/device/hid/hid_service.cc index d908fe7d..09b2ab60 100644 --- a/device/hid/hid_service.cc +++ b/device/hid/hid_service.cc
@@ -91,7 +91,7 @@ void HidService::AddDevice(scoped_refptr<HidDeviceInfo> device_info) { DCHECK(thread_checker_.CalledOnValidThread()); - if (!ContainsKey(devices_, device_info->device_id())) { + if (!base::ContainsKey(devices_, device_info->device_id())) { devices_[device_info->device_id()] = device_info; HID_LOG(USER) << "HID device "
diff --git a/device/hid/hid_service_mac.cc b/device/hid/hid_service_mac.cc index 2bed80b..1051135 100644 --- a/device/hid/hid_service_mac.cc +++ b/device/hid/hid_service_mac.cc
@@ -74,7 +74,7 @@ if (!ref) { return false; } - STLClearObject(result); + base::STLClearObject(result); const uint8_t* bytes = CFDataGetBytePtr(ref); result->insert(result->begin(), bytes, bytes + CFDataGetLength(ref)); return true;
diff --git a/device/media_transfer_protocol/media_transfer_protocol_manager.cc b/device/media_transfer_protocol/media_transfer_protocol_manager.cc index 52af57b..5986456 100644 --- a/device/media_transfer_protocol/media_transfer_protocol_manager.cc +++ b/device/media_transfer_protocol/media_transfer_protocol_manager.cc
@@ -131,7 +131,7 @@ const std::string& storage_name, const GetStorageInfoFromDeviceCallback& callback) override { DCHECK(thread_checker_.CalledOnValidThread()); - if (!ContainsKey(storage_info_map_, storage_name) || !mtp_client_) { + if (!base::ContainsKey(storage_info_map_, storage_name) || !mtp_client_) { MtpStorageInfo info; callback.Run(info, true /* error */); return; @@ -152,7 +152,7 @@ const std::string& mode, const OpenStorageCallback& callback) override { DCHECK(thread_checker_.CalledOnValidThread()); - if (!ContainsKey(storage_info_map_, storage_name) || !mtp_client_) { + if (!base::ContainsKey(storage_info_map_, storage_name) || !mtp_client_) { callback.Run(std::string(), true); return; } @@ -170,7 +170,7 @@ void CloseStorage(const std::string& storage_handle, const CloseStorageCallback& callback) override { DCHECK(thread_checker_.CalledOnValidThread()); - if (!ContainsKey(handles_, storage_handle) || !mtp_client_) { + if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) { callback.Run(true); return; } @@ -188,7 +188,7 @@ const std::string& directory_name, const CreateDirectoryCallback& callback) override { DCHECK(thread_checker_.CalledOnValidThread()); - if (!ContainsKey(handles_, storage_handle) || !mtp_client_) { + if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) { callback.Run(true /* error */); return; } @@ -207,7 +207,7 @@ const size_t max_size, const ReadDirectoryCallback& callback) override { DCHECK(thread_checker_.CalledOnValidThread()); - if (!ContainsKey(handles_, storage_handle) || !mtp_client_) { + if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) { callback.Run(std::vector<MtpFileEntry>(), false /* no more entries */, true /* error */); @@ -230,7 +230,7 @@ uint32_t count, const ReadFileCallback& callback) override { DCHECK(thread_checker_.CalledOnValidThread()); - if (!ContainsKey(handles_, storage_handle) || !mtp_client_) { + if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) { callback.Run(std::string(), true); return; } @@ -247,7 +247,7 @@ uint32_t file_id, const GetFileInfoCallback& callback) override { DCHECK(thread_checker_.CalledOnValidThread()); - if (!ContainsKey(handles_, storage_handle) || !mtp_client_) { + if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) { callback.Run(MtpFileEntry(), true); return; } @@ -270,7 +270,7 @@ const std::string& new_name, const RenameObjectCallback& callback) override { DCHECK(thread_checker_.CalledOnValidThread()); - if (!ContainsKey(handles_, storage_handle) || !mtp_client_) { + if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) { callback.Run(true /* error */); return; } @@ -289,7 +289,7 @@ const std::string& file_name, const CopyFileFromLocalCallback& callback) override { DCHECK(thread_checker_.CalledOnValidThread()); - if (!ContainsKey(handles_, storage_handle) || !mtp_client_) { + if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) { callback.Run(true /* error */); return; } @@ -306,7 +306,7 @@ const uint32_t object_id, const DeleteObjectCallback& callback) override { DCHECK(thread_checker_.CalledOnValidThread()); - if (!ContainsKey(handles_, storage_handle) || !mtp_client_) { + if (!base::ContainsKey(handles_, storage_handle) || !mtp_client_) { callback.Run(true /* error */); return; } @@ -373,7 +373,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(mtp_client_); for (size_t i = 0; i < storage_names.size(); ++i) { - if (ContainsKey(storage_info_map_, storage_names[i])) { + if (base::ContainsKey(storage_info_map_, storage_names[i])) { // OnStorageChanged() might have gotten called first. continue; } @@ -384,7 +384,7 @@ void OnGetStorageInfo(const MtpStorageInfo& storage_info) { DCHECK(thread_checker_.CalledOnValidThread()); const std::string& storage_name = storage_info.storage_name(); - if (ContainsKey(storage_info_map_, storage_name)) { + if (base::ContainsKey(storage_info_map_, storage_name)) { // This should not happen, since MediaTransferProtocolManagerImpl should // only call EnumerateStorages() once, which populates |storage_info_map_| // with the already-attached devices. @@ -417,7 +417,7 @@ void OnOpenStorage(const std::string& handle) { DCHECK(thread_checker_.CalledOnValidThread()); - if (!ContainsKey(handles_, handle)) { + if (!base::ContainsKey(handles_, handle)) { handles_.insert(handle); open_storage_callbacks_.front().Run(handle, false); } else { @@ -435,7 +435,7 @@ void OnCloseStorage() { DCHECK(thread_checker_.CalledOnValidThread()); const std::string& handle = close_storage_callbacks_.front().second; - if (ContainsKey(handles_, handle)) { + if (base::ContainsKey(handles_, handle)) { handles_.erase(handle); close_storage_callbacks_.front().first.Run(false); } else {
diff --git a/device/nfc/nfc_adapter.cc b/device/nfc/nfc_adapter.cc index 520d4f3..ea51454 100644 --- a/device/nfc/nfc_adapter.cc +++ b/device/nfc/nfc_adapter.cc
@@ -14,8 +14,8 @@ } NfcAdapter::~NfcAdapter() { - STLDeleteValues(&peers_); - STLDeleteValues(&tags_); + base::STLDeleteValues(&peers_); + base::STLDeleteValues(&tags_); } void NfcAdapter::GetPeers(PeerList* peer_list) const {
diff --git a/device/nfc/nfc_peer_chromeos.cc b/device/nfc/nfc_peer_chromeos.cc index 4ef1804..91169cd 100644 --- a/device/nfc/nfc_peer_chromeos.cc +++ b/device/nfc/nfc_peer_chromeos.cc
@@ -41,7 +41,7 @@ NfcPeerChromeOS::~NfcPeerChromeOS() { DBusThreadManager::Get()->GetNfcRecordClient()->RemoveObserver(this); - STLDeleteValues(&records_); + base::STLDeleteValues(&records_); } void NfcPeerChromeOS::AddObserver(device::NfcPeer::Observer* observer) {
diff --git a/device/nfc/nfc_tag_technology_chromeos.cc b/device/nfc/nfc_tag_technology_chromeos.cc index 25d1b24..7689e1f 100644 --- a/device/nfc/nfc_tag_technology_chromeos.cc +++ b/device/nfc/nfc_tag_technology_chromeos.cc
@@ -38,7 +38,7 @@ NfcNdefTagTechnologyChromeOS::~NfcNdefTagTechnologyChromeOS() { DBusThreadManager::Get()->GetNfcRecordClient()->RemoveObserver(this); - STLDeleteValues(&records_); + base::STLDeleteValues(&records_); } void NfcNdefTagTechnologyChromeOS::AddObserver(
diff --git a/device/test/usb_test_gadget_impl.cc b/device/test/usb_test_gadget_impl.cc index 5f6ecf6..8dc690b 100644 --- a/device/test/usb_test_gadget_impl.cc +++ b/device/test/usb_test_gadget_impl.cc
@@ -93,7 +93,7 @@ return false; } - STLClearObject(content); + base::STLClearObject(content); int rv; do { char buf[4096];
diff --git a/device/usb/mojo/device_impl_unittest.cc b/device/usb/mojo/device_impl_unittest.cc index 0e69ecb..73c5522 100644 --- a/device/usb/mojo/device_impl_unittest.cc +++ b/device/usb/mojo/device_impl_unittest.cc
@@ -212,7 +212,7 @@ void AddMockConfig(const ConfigBuilder& builder) { const UsbConfigDescriptor& config = builder.config(); - DCHECK(!ContainsKey(mock_configs_, config.configuration_value)); + DCHECK(!base::ContainsKey(mock_configs_, config.configuration_value)); mock_configs_.insert(std::make_pair(config.configuration_value, config)); mock_device_->AddMockConfig(config); } @@ -277,7 +277,7 @@ void ReleaseInterface(uint8_t interface_number, const UsbDeviceHandle::ResultCallback& callback) { - if (ContainsKey(claimed_interfaces_, interface_number)) { + if (base::ContainsKey(claimed_interfaces_, interface_number)) { claimed_interfaces_.erase(interface_number); callback.Run(true); } else {
diff --git a/device/usb/usb_device_handle_impl.cc b/device/usb/usb_device_handle_impl.cc index 0fd39584..1b7e560 100644 --- a/device/usb/usb_device_handle_impl.cc +++ b/device/usb/usb_device_handle_impl.cc
@@ -612,7 +612,7 @@ callback.Run(false); return; } - if (ContainsKey(claimed_interfaces_, interface_number)) { + if (base::ContainsKey(claimed_interfaces_, interface_number)) { callback.Run(true); return; } @@ -626,7 +626,7 @@ void UsbDeviceHandleImpl::ReleaseInterface(int interface_number, const ResultCallback& callback) { DCHECK(thread_checker_.CalledOnValidThread()); - if (!device_ || !ContainsKey(claimed_interfaces_, interface_number)) { + if (!device_ || !base::ContainsKey(claimed_interfaces_, interface_number)) { task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); return; } @@ -652,7 +652,7 @@ int alternate_setting, const ResultCallback& callback) { DCHECK(thread_checker_.CalledOnValidThread()); - if (!device_ || !ContainsKey(claimed_interfaces_, interface_number)) { + if (!device_ || !base::ContainsKey(claimed_interfaces_, interface_number)) { callback.Run(false); return; } @@ -1113,7 +1113,8 @@ void UsbDeviceHandleImpl::TransferComplete(Transfer* transfer, const base::Closure& callback) { DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(ContainsKey(transfers_, transfer)) << "Missing transfer completed"; + DCHECK(base::ContainsKey(transfers_, transfer)) + << "Missing transfer completed"; transfers_.erase(transfer); if (transfer->callback_task_runner()->RunsTasksOnCurrentThread()) {
diff --git a/device/usb/usb_device_handle_usbfs.cc b/device/usb/usb_device_handle_usbfs.cc index fba04342..4ac0d10 100644 --- a/device/usb/usb_device_handle_usbfs.cc +++ b/device/usb/usb_device_handle_usbfs.cc
@@ -369,7 +369,7 @@ return; } - if (ContainsKey(interfaces_, interface_number)) { + if (base::ContainsKey(interfaces_, interface_number)) { USB_LOG(DEBUG) << "Interface " << interface_number << " already claimed."; task_runner_->PostTask(FROM_HERE, base::Bind(callback, false)); return;
diff --git a/device/usb/usb_service_impl.cc b/device/usb/usb_service_impl.cc index 6a4c9675..7a23bff 100644 --- a/device/usb/usb_service_impl.cc +++ b/device/usb/usb_service_impl.cc
@@ -327,7 +327,7 @@ for (size_t i = 0; i < device_count; ++i) { PlatformUsbDevice platform_device = platform_devices[i]; // Ignore some devices. - if (ContainsValue(ignored_devices_, platform_device)) { + if (base::ContainsValue(ignored_devices_, platform_device)) { existing_ignored_devices.insert(platform_device); refresh_complete.Run(); continue; @@ -360,7 +360,7 @@ for (auto it = ignored_devices_.begin(); it != ignored_devices_.end(); /* incremented internally */) { auto current = it++; - if (!ContainsValue(existing_ignored_devices, *current)) { + if (!base::ContainsValue(existing_ignored_devices, *current)) { libusb_unref_device(*current); ignored_devices_.erase(current); } @@ -451,7 +451,7 @@ } platform_devices_[device->platform_device()] = device; - DCHECK(!ContainsKey(devices(), device->guid())); + DCHECK(!base::ContainsKey(devices(), device->guid())); devices()[device->guid()] = device; USB_LOG(USER) << "USB device added: vendor=" << device->vendor_id() << " \"" @@ -517,7 +517,7 @@ void UsbServiceImpl::OnPlatformDeviceAdded(PlatformUsbDevice platform_device) { DCHECK(CalledOnValidThread()); - DCHECK(!ContainsKey(platform_devices_, platform_device)); + DCHECK(!base::ContainsKey(platform_devices_, platform_device)); EnumerateDevice(platform_device, base::Bind(&base::DoNothing)); libusb_unref_device(platform_device); }
diff --git a/device/usb/usb_service_linux.cc b/device/usb/usb_service_linux.cc index 2afc459a..9e647af 100644 --- a/device/usb/usb_service_linux.cc +++ b/device/usb/usb_service_linux.cc
@@ -252,7 +252,7 @@ auto it = devices_by_path_.find(device->device_path()); if (it != devices_by_path_.end()) { if (success) { - DCHECK(!ContainsKey(devices(), device->guid())); + DCHECK(!base::ContainsKey(devices(), device->guid())); devices()[device->guid()] = device; USB_LOG(USER) << "USB device added: path=" << device->device_path()
diff --git a/device/usb/webusb_descriptors.cc b/device/usb/webusb_descriptors.cc index c21dc6f3..57468182 100644 --- a/device/usb/webusb_descriptors.cc +++ b/device/usb/webusb_descriptors.cc
@@ -580,15 +580,15 @@ if (!allowed_origins) return false; - if (ContainsValue(allowed_origins->origins, origin)) + if (base::ContainsValue(allowed_origins->origins, origin)) return true; for (const auto& config : allowed_origins->configurations) { - if (ContainsValue(config.origins, origin)) + if (base::ContainsValue(config.origins, origin)) return true; for (const auto& function : config.functions) { - if (ContainsValue(function.origins, origin)) + if (base::ContainsValue(function.origins, origin)) return true; } }
diff --git a/docs/atom.md b/docs/atom.md new file mode 100644 index 0000000..999b3844 --- /dev/null +++ b/docs/atom.md
@@ -0,0 +1,130 @@ +# Atom + +[TOC] + +## Workflow + +A typical Atom workflow consists of the following. + +1. Use `Ctrl-Shift-R` to find a symbol in the `.tags` file or `Ctrl-P` to find + a file by name. +2. Switch between the header and the source using `Alt-O`. +3. While editing, `you-complete-me` package helps with C++ auto-completion and + shows compile errors through `lint` package. +4. Press `Ctrl-Shift-P` and type `format<Enter>` to format the code. +5. Select the target to build by pressing `F7` and typing, for example, + `base_unittests`. +6. Rebuild again by pressing `F9`. + +## Atom packages + +To setup this workflow, install Atom packages for Chrome development. + +``` +$ apm install build-ninja clang-format \ + linter linter-eslint switch-header-source you-complete-me +``` + +## Autocomplete + +Install C++ auto-completion engine. + +``` +$ git clone https://github.com/Valloric/ycmd.git ~/.ycmd +$ cd ~/.ycmd +$ ./build.py --clang-completer +``` + +## JavaScript lint + +Install JavaScript linter for Blink layout tests. + +``` +$ npm install -g eslint eslint-config-google +``` + +Configure the JavaScript linter to use the Google style by default by replacing +the contents of `~/.eslintrc` with the following. + +``` +{ + "extends": "google", + "env": { + "browser": true + } +} +``` + +## Configuration + +Configure Atom by replacing the contents of `~/.atom/config.cson` with the +following. Replace `<path-of-your-home-dir>` and +`<path-of-your-chrome-checkout>` with the actual full paths of your home +directory and chrome checkout. For example, these can be `/Users/bob` and +`/Users/bob/chrome/src`. + +``` +"*": + # Configure ninja builder. + "build-ninja": + ninjaOptions: [ + # The number of jobs to use when running ninja. Adjust to taste. + "-j10" + ] + subdirs: [ + # The location of your build.ninja file. + "out/gn" + ] + # Do not auto-format entire files on save. + "clang-format": + formatCOnSave: false + formatCPlusPlusOnSave: false + core: + # Treat .h files as C++. + customFileTypes: + "source.cpp": [ + "h" + ] + # Don't send metrics if you're working on anything sensitive. + disabledPackages: [ + "metrics" + "exception-reporting" + ] + # Use spaces instead of tabs. + editor: + tabType: "soft" + # Show lint errors only when you save the file. + linter: + lintOnFly: false + # Configure JavaScript lint. + "linter-eslint": + eslintrcPath: "<path-of-your-home-dir>/.eslintrc" + useGlobalEslint: true + # Don't show ignored files in the project file browser. + "tree-view": + hideIgnoredNames: true + hideVcsIgnoredFiles: true + # Configure C++ autocomplete and lint. + "you-complete-me": + globalExtraConfig: "<path-of-your-chrome-checkout>/tools/vim/chromium.ycm_extra_conf.py" + ycmdPath: "<path-of-your-home-dir>/.ycmd/" +# Java uses 4 space indents and 100 character lines. +".java.source": + editor: + preferredLineLength: 100 + tabLength: 4 +``` + +## Symbol lookup + +Atom fuzzy file finder is slow to index all files in Chrome. If you're working +on a project that frequently uses `foo` or `bar` in files names, you can create +a small `.tags` file to efficiently search the symbols within these files. Be +sure to use "Exuberant Ctags." + +``` +$ git ls | egrep -i "foo|bar" | ctags -f .tags -L - +``` + +Don't create a ctags file for the full Chrome repository, as that would result +in ~9GB tag file that will not be usable in Atom.
diff --git a/extensions/browser/api/bluetooth/bluetooth_event_router.cc b/extensions/browser/api/bluetooth/bluetooth_event_router.cc index 39300a7..841935dc 100644 --- a/extensions/browser/api/bluetooth/bluetooth_event_router.cc +++ b/extensions/browser/api/bluetooth/bluetooth_event_router.cc
@@ -199,7 +199,7 @@ BluetoothApiPairingDelegate* BluetoothEventRouter::GetPairingDelegate( const std::string& extension_id) { - return ContainsKey(pairing_delegate_map_, extension_id) + return base::ContainsKey(pairing_delegate_map_, extension_id) ? pairing_delegate_map_[extension_id] : nullptr; } @@ -241,7 +241,7 @@ LOG(ERROR) << "Unable to get adapter for extension_id: " << extension_id; return; } - if (ContainsKey(pairing_delegate_map_, extension_id)) { + if (base::ContainsKey(pairing_delegate_map_, extension_id)) { // For WebUI there may be more than one page open to the same url // (e.g. chrome://settings). These will share the same pairing delegate. VLOG(1) << "Pairing delegate already exists for extension_id: " @@ -258,7 +258,7 @@ void BluetoothEventRouter::RemovePairingDelegate( const std::string& extension_id) { - if (ContainsKey(pairing_delegate_map_, extension_id)) { + if (base::ContainsKey(pairing_delegate_map_, extension_id)) { BluetoothApiPairingDelegate* delegate = pairing_delegate_map_[extension_id]; if (adapter_.get()) adapter_->RemovePairingDelegate(delegate);
diff --git a/extensions/browser/api/declarative/declarative_rule_unittest.cc b/extensions/browser/api/declarative/declarative_rule_unittest.cc index fae5a6e..c7e869c 100644 --- a/extensions/browser/api/declarative/declarative_rule_unittest.cc +++ b/extensions/browser/api/declarative/declarative_rule_unittest.cc
@@ -120,7 +120,7 @@ bool IsFulfilled(const MatchData& match_data) const { if (condition_set_id != -1 && - !ContainsKey(match_data.url_matches, condition_set_id)) + !base::ContainsKey(match_data.url_matches, condition_set_id)) return false; return match_data.value <= max_value; }
diff --git a/extensions/browser/api/declarative/deduping_factory.h b/extensions/browser/api/declarative/deduping_factory.h index 1cc3231..53c75c4 100644 --- a/extensions/browser/api/declarative/deduping_factory.h +++ b/extensions/browser/api/declarative/deduping_factory.h
@@ -106,7 +106,7 @@ const std::string& instance_type, typename DedupingFactory<BaseClassT>::Parameterized parameterized, FactoryMethod factory_method) { - DCHECK(!ContainsKey(factory_methods_, instance_type)); + DCHECK(!base::ContainsKey(factory_methods_, instance_type)); factory_methods_[instance_type] = factory_method; if (parameterized == IS_PARAMETERIZED) parameterized_types_.insert(instance_type); @@ -133,7 +133,7 @@ // We can take a shortcut for objects that are not parameterized. For those // only a single instance may ever exist so we can simplify the creation // logic. - if (!ContainsKey(parameterized_types_, instance_type)) { + if (!base::ContainsKey(parameterized_types_, instance_type)) { if (prototypes.empty()) { scoped_refptr<const BaseClassT> new_object = (*factory_method)(instance_type, value, error, bad_message);
diff --git a/extensions/browser/api/declarative/rules_registry.cc b/extensions/browser/api/declarative/rules_registry.cc index 718a8ef..b841fff 100644 --- a/extensions/browser/api/declarative/rules_registry.cc +++ b/extensions/browser/api/declarative/rules_registry.cc
@@ -332,7 +332,7 @@ void RulesRegistry::ProcessChangedRules(const std::string& extension_id) { DCHECK_CURRENTLY_ON(owner_thread()); - DCHECK(ContainsKey(process_changed_rules_requested_, extension_id)); + DCHECK(base::ContainsKey(process_changed_rules_requested_, extension_id)); process_changed_rules_requested_[extension_id] = NOT_SCHEDULED_FOR_PROCESSING; std::vector<linked_ptr<api::events::Rule>> new_rules;
diff --git a/extensions/browser/api/declarative_webrequest/webrequest_condition.cc b/extensions/browser/api/declarative_webrequest/webrequest_condition.cc index 7e41f12..0da8826 100644 --- a/extensions/browser/api/declarative_webrequest/webrequest_condition.cc +++ b/extensions/browser/api/declarative_webrequest/webrequest_condition.cc
@@ -99,11 +99,12 @@ // Check URL attributes if present. if (url_matcher_conditions_.get() && - !ContainsKey(request_data.url_match_ids, url_matcher_conditions_->id())) + !base::ContainsKey(request_data.url_match_ids, + url_matcher_conditions_->id())) return false; if (first_party_url_matcher_conditions_.get() && - !ContainsKey(request_data.first_party_url_match_ids, - first_party_url_matcher_conditions_->id())) + !base::ContainsKey(request_data.first_party_url_match_ids, + first_party_url_matcher_conditions_->id())) return false; // All condition attributes must be fulfilled for a fulfilled condition.
diff --git a/extensions/browser/api/declarative_webrequest/webrequest_rules_registry.cc b/extensions/browser/api/declarative_webrequest/webrequest_rules_registry.cc index 62bf3cc..0fb57d0 100644 --- a/extensions/browser/api/declarative_webrequest/webrequest_rules_registry.cc +++ b/extensions/browser/api/declarative_webrequest/webrequest_rules_registry.cc
@@ -130,7 +130,7 @@ if (!rule->tags().empty() && !ignore_tags[extension_id].empty()) { bool ignore_rule = false; for (const std::string& tag : rule->tags()) - ignore_rule |= ContainsKey(ignore_tags[extension_id], tag); + ignore_rule |= base::ContainsKey(ignore_tags[extension_id], tag); if (ignore_rule) continue; } @@ -381,7 +381,7 @@ for (url_matcher::URLMatcherConditionSet::ID url_match : url_matches) { RuleTriggers::const_iterator rule_trigger = rule_triggers_.find(url_match); CHECK(rule_trigger != rule_triggers_.end()); - if (!ContainsKey(*result, rule_trigger->second) && + if (!base::ContainsKey(*result, rule_trigger->second) && rule_trigger->second->conditions().IsFulfilled(url_match, request_data)) result->insert(rule_trigger->second); }
diff --git a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc index 74493cfc..3ecc6d6 100644 --- a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc +++ b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
@@ -215,7 +215,7 @@ const HostID& host_id, bool incognito_enabled, const GURL& owner_base_url, - std::set<UserScript>* result, + extensions::UserScriptList* result, std::string* error) { if (content_script_list.empty()) return false; @@ -239,7 +239,7 @@ script.set_incognito_enabled(incognito_enabled); script.set_host_id(host_id); script.set_consumer_instance_type(UserScript::WEBVIEW); - result->insert(script); + result->push_back(script); } return true; } @@ -500,12 +500,11 @@ GURL owner_base_url( render_frame_host()->GetSiteInstance()->GetSiteURL().GetWithEmptyPath()); - std::set<UserScript> result; - content::WebContents* sender_web_contents = GetSenderWebContents(); HostID host_id = GenerateHostIDFromEmbedder(extension(), sender_web_contents); bool incognito_enabled = browser_context()->IsOffTheRecord(); + UserScriptList result; if (!ParseContentScripts(params->content_script_list, extension(), host_id, incognito_enabled, owner_base_url, &result, &error_)) return RespondNow(Error(error_));
diff --git a/extensions/browser/api/hid/hid_device_manager.cc b/extensions/browser/api/hid/hid_device_manager.cc index 3985c4f..4132507 100644 --- a/extensions/browser/api/hid/hid_device_manager.cc +++ b/extensions/browser/api/hid/hid_device_manager.cc
@@ -217,7 +217,7 @@ DCHECK(thread_checker_.CalledOnValidThread()); DCHECK_LT(next_resource_id_, std::numeric_limits<int>::max()); int new_id = next_resource_id_++; - DCHECK(!ContainsKey(resource_ids_, device_info->device_id())); + DCHECK(!base::ContainsKey(resource_ids_, device_info->device_id())); resource_ids_[device_info->device_id()] = new_id; device_ids_[new_id] = device_info->device_id();
diff --git a/extensions/browser/api/networking_private/networking_private_chromeos.cc b/extensions/browser/api/networking_private/networking_private_chromeos.cc index 65309ac..b580cda 100644 --- a/extensions/browser/api/networking_private/networking_private_chromeos.cc +++ b/extensions/browser/api/networking_private/networking_private_chromeos.cc
@@ -588,7 +588,7 @@ ::onc::network_type::kWimax, ::onc::network_type::kCellular}; for (const char* technology : technology_types) { - if (ContainsValue(technologies_found, technology)) + if (base::ContainsValue(technologies_found, technology)) continue; AppendDeviceState(technology, nullptr /* device */, device_state_list.get());
diff --git a/extensions/browser/api/socket/app_firewall_hole_manager.cc b/extensions/browser/api/socket/app_firewall_hole_manager.cc index db9d3d76..1f076c3 100644 --- a/extensions/browser/api/socket/app_firewall_hole_manager.cc +++ b/extensions/browser/api/socket/app_firewall_hole_manager.cc
@@ -110,7 +110,7 @@ } AppFirewallHoleManager::~AppFirewallHoleManager() { - STLDeleteValues(&tracked_holes_); + base::STLDeleteValues(&tracked_holes_); } AppFirewallHoleManager* AppFirewallHoleManager::Get(BrowserContext* context) {
diff --git a/extensions/browser/api/vpn_provider/vpn_service.cc b/extensions/browser/api/vpn_provider/vpn_service.cc index ccc0fe2..2bd7f1e 100644 --- a/extensions/browser/api/vpn_provider/vpn_service.cc +++ b/extensions/browser/api/vpn_provider/vpn_service.cc
@@ -243,8 +243,8 @@ network_configuration_handler_->RemoveObserver(this); network_state_handler_->RemoveObserver(this, FROM_HERE); extension_registry_->RemoveObserver(this); - STLDeleteContainerPairSecondPointers(key_to_configuration_map_.begin(), - key_to_configuration_map_.end()); + base::STLDeleteContainerPairSecondPointers(key_to_configuration_map_.begin(), + key_to_configuration_map_.end()); } void VpnService::SendShowAddDialogToExtension(const std::string& extension_id) { @@ -393,7 +393,7 @@ } const std::string key = GetKey(extension_id, configuration_name); - if (ContainsKey(key_to_configuration_map_, key)) { + if (base::ContainsKey(key_to_configuration_map_, key)) { failure.Run(std::string(), std::string("Name not unique.")); return; } @@ -443,7 +443,7 @@ const FailureCallback& failure) { // The ID is the configuration name for now. This may change in the future. const std::string key = GetKey(extension_id, configuration_id); - if (!ContainsKey(key_to_configuration_map_, key)) { + if (!base::ContainsKey(key_to_configuration_map_, key)) { failure.Run(std::string(), std::string("Unauthorized access.")); return; } @@ -516,7 +516,7 @@ const std::string& extension_id, const std::string& configuration_name) { const std::string key = GetKey(extension_id, configuration_name); - return ContainsKey(key_to_configuration_map_, key); + return base::ContainsKey(key_to_configuration_map_, key); } bool VpnService::VerifyConfigIsConnectedForTesting( @@ -664,7 +664,7 @@ pepper_vpn_provider_proxy) { // The ID is the configuration name for now. This may change in the future. const std::string key = GetKey(extension_id, configuration_id); - if (!ContainsKey(key_to_configuration_map_, key)) { + if (!base::ContainsKey(key_to_configuration_map_, key)) { failure.Run(std::string(), std::string("Unauthorized access. " "The configuration does not exist."));
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc index a03d931..b405532 100644 --- a/extensions/browser/api/web_request/web_request_api.cc +++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -1121,7 +1121,7 @@ base::UserMetricsAction("WebView.WebRequest.AddListener")); } - if (ContainsKey(listeners_[browser_context][event_name], listener)) { + if (base::ContainsKey(listeners_[browser_context][event_name], listener)) { // This is likely an abuse of the API by a malicious extension. return false; } @@ -1643,7 +1643,7 @@ listeners_[browser_context][event_name]; for (const auto& listener : listeners) { - if (!ContainsKey(listener.blocked_requests, request_id)) + if (!base::ContainsKey(listener.blocked_requests, request_id)) continue; std::string delegate_info = l10n_util::GetStringFUTF8(IDS_LOAD_STATE_PARAMETER_EXTENSION,
diff --git a/extensions/browser/app_window/app_window_geometry_cache.cc b/extensions/browser/app_window/app_window_geometry_cache.cc index e1ee46ea..b2e13ab6 100644 --- a/extensions/browser/app_window/app_window_geometry_cache.cc +++ b/extensions/browser/app_window/app_window_geometry_cache.cc
@@ -56,7 +56,7 @@ if (extension_data[window_id].bounds == bounds && extension_data[window_id].window_state == window_state && extension_data[window_id].screen_bounds == screen_bounds && - !ContainsKey(unsynced_extensions_, extension_id)) + !base::ContainsKey(unsynced_extensions_, extension_id)) return; base::Time now = base::Time::Now();
diff --git a/extensions/browser/computed_hashes.cc b/extensions/browser/computed_hashes.cc index dbfe006..bf0cf98 100644 --- a/extensions/browser/computed_hashes.cc +++ b/extensions/browser/computed_hashes.cc
@@ -184,7 +184,7 @@ hashes->push_back(std::string()); std::string* buffer = &(hashes->back()); buffer->resize(crypto::kSHA256Length); - hash->Finish(string_as_array(buffer), buffer->size()); + hash->Finish(base::string_as_array(buffer), buffer->size()); // If |contents| is empty, then we want to just exit here. if (bytes_to_read == 0)
diff --git a/extensions/browser/content_hash_tree.cc b/extensions/browser/content_hash_tree.cc index 8abbf6fd..e1298cf4 100644 --- a/extensions/browser/content_hash_tree.cc +++ b/extensions/browser/content_hash_tree.cc
@@ -42,7 +42,7 @@ } parent_nodes.push_back(std::string(crypto::kSHA256Length, 0)); std::string* output = &(parent_nodes.back()); - hash->Finish(string_as_array(output), output->size()); + hash->Finish(base::string_as_array(output), output->size()); } current_nodes.swap(parent_nodes); parent_nodes.clear();
diff --git a/extensions/browser/content_hash_tree_unittest.cc b/extensions/browser/content_hash_tree_unittest.cc index 6d35dd5..f9be82e 100644 --- a/extensions/browser/content_hash_tree_unittest.cc +++ b/extensions/browser/content_hash_tree_unittest.cc
@@ -43,7 +43,7 @@ std::unique_ptr<SecureHash> hash(SecureHash::Create(SecureHash::SHA256)); hash->Update(node1.data(), node1.size()); hash->Update(node2.data(), node2.size()); - hash->Finish(string_as_array(&expected), expected.size()); + hash->Finish(base::string_as_array(&expected), expected.size()); EXPECT_EQ(expected, ComputeTreeHashRoot(nodes, 16)); }
diff --git a/extensions/browser/content_verifier.cc b/extensions/browser/content_verifier.cc index c47db07..58a89978 100644 --- a/extensions/browser/content_verifier.cc +++ b/extensions/browser/content_verifier.cc
@@ -261,7 +261,7 @@ if (relative_path == base::FilePath(kManifestFilename)) continue; - if (ContainsKey(browser_images, relative_path)) + if (base::ContainsKey(browser_images, relative_path)) continue; base::FilePath full_path = extension_root.Append(relative_path);
diff --git a/extensions/browser/content_verify_job.cc b/extensions/browser/content_verify_job.cc index e10f8637..632590ce 100644 --- a/extensions/browser/content_verify_job.cc +++ b/extensions/browser/content_verify_job.cc
@@ -146,7 +146,7 @@ if (current_hash_byte_count_ <= 0) return true; std::string final(crypto::kSHA256Length, 0); - current_hash_->Finish(string_as_array(&final), final.size()); + current_hash_->Finish(base::string_as_array(& final), final.size()); current_hash_.reset(); current_hash_byte_count_ = 0; @@ -178,7 +178,7 @@ if (!queue_.empty()) { std::string tmp; queue_.swap(tmp); - BytesRead(tmp.size(), string_as_array(&tmp)); + BytesRead(tmp.size(), base::string_as_array(&tmp)); } if (done_reading_) { ScopedElapsedTimer timer(&time_spent_);
diff --git a/extensions/browser/declarative_user_script_master.cc b/extensions/browser/declarative_user_script_master.cc index bd21cfd..9ea77e8 100644 --- a/extensions/browser/declarative_user_script_master.cc +++ b/extensions/browser/declarative_user_script_master.cc
@@ -32,26 +32,23 @@ } void DeclarativeUserScriptMaster::AddScript(const UserScript& script) { - std::set<UserScript> set; - set.insert(script); - loader_->AddScripts(set); + loader_->AddScripts(UserScriptList(1, script)); } -void DeclarativeUserScriptMaster::AddScripts( - const std::set<UserScript>& scripts, - int render_process_id, - int render_frame_id) { - loader_->AddScripts(scripts, render_process_id, render_frame_id); +void DeclarativeUserScriptMaster::AddScripts(const UserScriptList& scripts, + int render_process_id, + int render_view_id) { + loader_->AddScripts(scripts, render_process_id, render_view_id); } void DeclarativeUserScriptMaster::RemoveScript(const UserScript& script) { - std::set<UserScript> set; - set.insert(script); + std::set<UserScriptIDPair> set; + set.insert(UserScriptIDPair(script.id(), script.host_id())); loader_->RemoveScripts(set); } void DeclarativeUserScriptMaster::RemoveScripts( - const std::set<UserScript>& scripts) { + const std::set<UserScriptIDPair>& scripts) { loader_->RemoveScripts(scripts); }
diff --git a/extensions/browser/declarative_user_script_master.h b/extensions/browser/declarative_user_script_master.h index 2b05ff3..a057010 100644 --- a/extensions/browser/declarative_user_script_master.h +++ b/extensions/browser/declarative_user_script_master.h
@@ -21,6 +21,8 @@ class UserScript; class UserScriptLoader; +struct UserScriptIDPair; + // Manages declarative user scripts for a single extension. Owns a // UserScriptLoader to which file loading and shared memory management // operations are delegated, and provides an interface for adding, removing, @@ -39,7 +41,7 @@ // of the script on WebUI requires to start URL request to the associated // render specified by |render_process_id, render_frame_id|. // This may not happen right away if a script load is in progress. - void AddScripts(const std::set<UserScript>& scripts, + void AddScripts(const std::vector<UserScript>& scripts, int render_process_id, int render_frame_id); @@ -49,7 +51,7 @@ // Removes a set of scripts from shared memory region. This may not happen // right away if a script load is in progress. - void RemoveScripts(const std::set<UserScript>& scripts); + void RemoveScripts(const std::set<UserScriptIDPair>& scripts); // Removes all scripts from shared memory region. This may not happen right // away if a script load is in progress.
diff --git a/extensions/browser/error_map.cc b/extensions/browser/error_map.cc index 9a80600..91733a6 100644 --- a/extensions/browser/error_map.cc +++ b/extensions/browser/error_map.cc
@@ -133,7 +133,7 @@ } void ErrorMap::ExtensionEntry::DeleteAllErrors() { - STLDeleteContainerPointers(list_.begin(), list_.end()); + base::STLDeleteContainerPointers(list_.begin(), list_.end()); list_.clear(); }
diff --git a/extensions/browser/event_router.cc b/extensions/browser/event_router.cc index 5cbaf9c..24ac575 100644 --- a/extensions/browser/event_router.cc +++ b/extensions/browser/event_router.cc
@@ -503,7 +503,7 @@ if (listener->process()) { EventDispatchIdentifier dispatch_id(listener->GetBrowserContext(), listener->extension_id()); - if (!ContainsKey(already_dispatched, dispatch_id)) { + if (!base::ContainsKey(already_dispatched, dispatch_id)) { DispatchEventToProcess(listener->extension_id(), listener->listener_url(), listener->process(), event, listener->filter(),
diff --git a/extensions/browser/guest_view/web_view/web_view_content_script_manager.cc b/extensions/browser/guest_view/web_view/web_view_content_script_manager.cc index 75d485ea..d08769f 100644 --- a/extensions/browser/guest_view/web_view/web_view_content_script_manager.cc +++ b/extensions/browser/guest_view/web_view/web_view_content_script_manager.cc
@@ -46,7 +46,7 @@ content::RenderFrameHost* render_frame_host, int view_instance_id, const HostID& host_id, - const std::set<UserScript>& scripts) { + const UserScriptList& scripts) { DCHECK_CURRENTLY_ON(BrowserThread::UI); DeclarativeUserScriptMaster* master = @@ -71,22 +71,21 @@ // Step 2: updates the guest_content_script_map_. ContentScriptMap& map = iter->second; - std::set<UserScript> scripts_to_delete; + std::set<UserScriptIDPair> to_delete; for (const UserScript& script : scripts) { auto map_iter = map.find(script.name()); // If a content script has the same name as the new one, remove the old // script first, and insert the new one. if (map_iter != map.end()) { - scripts_to_delete.insert(map_iter->second); + to_delete.insert(map_iter->second); map.erase(map_iter); } - map.insert(std::pair<std::string, UserScript>(script.name(), script)); + map.insert(std::pair<std::string, UserScriptIDPair>( + script.name(), UserScriptIDPair(script.id(), script.host_id()))); ids_to_add.insert(script.id()); } - - if (!scripts_to_delete.empty()) { - master->RemoveScripts(scripts_to_delete); - } + if (!to_delete.empty()) + master->RemoveScripts(to_delete); // Step 3: makes WebViewContentScriptManager become an observer of the // |loader| for scripts loaded event. @@ -156,11 +155,11 @@ // We need to update WebViewRenderState in the IO thread if the guest exists. std::set<int> ids_to_delete; - std::set<UserScript> scripts_to_delete; + std::set<UserScriptIDPair> scripts_to_delete; // Step 1: removes content scripts from |master| and updates // |guest_content_script_map_|. - std::map<std::string, UserScript>& map = script_map_iter->second; + std::map<std::string, UserScriptIDPair>& map = script_map_iter->second; // If the |script_name_list| is empty, all the content scripts added by the // guest will be removed; otherwise, removes the scripts in the // |script_name_list|. @@ -168,7 +167,7 @@ auto it = map.begin(); while (it != map.end()) { scripts_to_delete.insert(it->second); - ids_to_delete.insert(it->second.id()); + ids_to_delete.insert(it->second.id); map.erase(it++); } } else { @@ -176,9 +175,9 @@ ContentScriptMap::iterator iter = map.find(name); if (iter == map.end()) continue; - const UserScript& script = iter->second; - ids_to_delete.insert(script.id()); - scripts_to_delete.insert(script); + const UserScriptIDPair& id_pair = iter->second; + ids_to_delete.insert(id_pair.id); + scripts_to_delete.insert(id_pair); map.erase(iter); } } @@ -214,8 +213,8 @@ if (iter == guest_content_script_map_.end()) return ids; const ContentScriptMap& map = iter->second; - for (const auto& pair : map) - ids.insert(pair.second.id()); + for (const auto& id_pair : map) + ids.insert(id_pair.second.id); return ids; }
diff --git a/extensions/browser/guest_view/web_view/web_view_content_script_manager.h b/extensions/browser/guest_view/web_view/web_view_content_script_manager.h index e1b7278..ace0cda6 100644 --- a/extensions/browser/guest_view/web_view/web_view_content_script_manager.h +++ b/extensions/browser/guest_view/web_view/web_view_content_script_manager.h
@@ -44,7 +44,7 @@ content::RenderFrameHost* render_frame_host, int view_instance_id, const HostID& host_id, - const std::set<UserScript>& user_scripts); + const UserScriptList& user_scripts); // Removes all content scripts for the WebView identified by // |embedder_process_id| and |view_instance_id|. @@ -73,7 +73,7 @@ private: using GuestMapKey = std::pair<int, int>; - using ContentScriptMap = std::map<std::string, extensions::UserScript>; + using ContentScriptMap = std::map<std::string, UserScriptIDPair>; using GuestContentScriptMap = std::map<GuestMapKey, ContentScriptMap>; // UserScriptLoader::Observer implementation:
diff --git a/extensions/browser/process_manager.cc b/extensions/browser/process_manager.cc index 571d06e..1689bb3 100644 --- a/extensions/browser/process_manager.cc +++ b/extensions/browser/process_manager.cc
@@ -619,7 +619,7 @@ } void ProcessManager::CloseBackgroundHosts() { - STLDeleteElements(&background_hosts_); + base::STLDeleteElements(&background_hosts_); } void ProcessManager::SetKeepaliveImpulseCallbackForTesting(
diff --git a/extensions/browser/quota_service.cc b/extensions/browser/quota_service.cc index 6d6aae8..a909b33b 100644 --- a/extensions/browser/quota_service.cc +++ b/extensions/browser/quota_service.cc
@@ -91,7 +91,7 @@ void QuotaService::PurgeFunctionHeuristicsMap(FunctionHeuristicsMap* map) { FunctionHeuristicsMap::iterator heuristics = map->begin(); while (heuristics != map->end()) { - STLDeleteElements(&heuristics->second); + base::STLDeleteElements(&heuristics->second); map->erase(heuristics++); } }
diff --git a/extensions/browser/quota_service_unittest.cc b/extensions/browser/quota_service_unittest.cc index 56cb116..f44d0b9e 100644 --- a/extensions/browser/quota_service_unittest.cc +++ b/extensions/browser/quota_service_unittest.cc
@@ -37,7 +37,7 @@ class Mapper : public QuotaLimitHeuristic::BucketMapper { public: Mapper() {} - ~Mapper() override { STLDeleteValues(&buckets_); } + ~Mapper() override { base::STLDeleteValues(&buckets_); } void GetBucketsForArgs(const base::ListValue* args, BucketList* buckets) override { for (size_t i = 0; i < args->GetSize(); i++) {
diff --git a/extensions/browser/user_script_loader.cc b/extensions/browser/user_script_loader.cc index 36e20b6..f045bcf 100644 --- a/extensions/browser/user_script_loader.cc +++ b/extensions/browser/user_script_loader.cc
@@ -28,6 +28,18 @@ namespace { +#if DCHECK_IS_ON() +bool AreScriptsUnique(const UserScriptList& scripts) { + std::set<int> script_ids; + for (const UserScript& script : scripts) { + if (script_ids.count(script.id())) + return false; + script_ids.insert(script.id()); + } + return true; +} +#endif // DCHECK_IS_ON() + // Helper function to parse greasesmonkey headers bool GetDeclarationValue(const base::StringPiece& line, const base::StringPiece& prefix, @@ -161,36 +173,44 @@ FOR_EACH_OBSERVER(Observer, observers_, OnUserScriptLoaderDestroyed(this)); } -void UserScriptLoader::AddScripts(const std::set<UserScript>& scripts) { - for (std::set<UserScript>::const_iterator it = scripts.begin(); - it != scripts.end(); - ++it) { - removed_scripts_.erase(*it); - added_scripts_.insert(*it); +void UserScriptLoader::AddScripts(const UserScriptList& scripts) { +#if DCHECK_IS_ON() + // |scripts| with non-unique IDs will work, but that would indicate we are + // doing something wrong somewhere, so DCHECK that. + DCHECK(AreScriptsUnique(scripts)) + << "AddScripts() expects scripts with unique IDs."; +#endif // DCHECK_IS_ON() + for (const UserScript& user_script : scripts) { + int id = user_script.id(); + removed_script_hosts_.erase(UserScriptIDPair(id)); + if (added_scripts_map_.count(id) == 0) + added_scripts_map_[id] = user_script; } AttemptLoad(); } -void UserScriptLoader::AddScripts(const std::set<UserScript>& scripts, +void UserScriptLoader::AddScripts(const UserScriptList& scripts, int render_process_id, int render_frame_id) { AddScripts(scripts); } -void UserScriptLoader::RemoveScripts(const std::set<UserScript>& scripts) { - for (std::set<UserScript>::const_iterator it = scripts.begin(); - it != scripts.end(); - ++it) { - added_scripts_.erase(*it); - removed_scripts_.insert(*it); +void UserScriptLoader::RemoveScripts( + const std::set<UserScriptIDPair>& scripts) { + for (const UserScriptIDPair& id_pair : scripts) { + removed_script_hosts_.insert(UserScriptIDPair(id_pair.id, id_pair.host_id)); + // TODO(lazyboy): We shouldn't be trying to remove scripts that were never + // a) added to |added_scripts_map_| or b) being loaded or has done loading + // through |user_scripts_|. This would reduce sending redundant IPC. + added_scripts_map_.erase(id_pair.id); } AttemptLoad(); } void UserScriptLoader::ClearScripts() { clear_scripts_ = true; - added_scripts_.clear(); - removed_scripts_.clear(); + added_scripts_map_.clear(); + removed_script_hosts_.clear(); AttemptLoad(); } @@ -215,10 +235,8 @@ // (1) A load is in progress (which may result in a non-zero number of // scripts that need to be cleared), or // (2) The current set of scripts is non-empty (so they need to be cleared). - return (added_scripts_.size() || - removed_scripts_.size() || - (clear_scripts_ && - (is_loading() || user_scripts_->size()))); + return (added_scripts_map_.size() || removed_script_hosts_.size() || + (clear_scripts_ && (is_loading() || user_scripts_->size()))); } void UserScriptLoader::AttemptLoad() { @@ -241,38 +259,36 @@ } else { for (UserScriptList::iterator it = user_scripts_->begin(); it != user_scripts_->end();) { - if (removed_scripts_.count(*it)) + UserScriptIDPair id_pair(it->id()); + if (removed_script_hosts_.count(id_pair) > 0u) it = user_scripts_->erase(it); else ++it; } } - user_scripts_->insert( - user_scripts_->end(), added_scripts_.begin(), added_scripts_.end()); - std::set<int> added_script_ids; - for (std::set<UserScript>::const_iterator it = added_scripts_.begin(); - it != added_scripts_.end(); - ++it) { - added_script_ids.insert(it->id()); - } - - // Expand |changed_hosts_| for OnScriptsLoaded, which will use it in - // its IPC message. This must be done before we clear |added_scripts_| and - // |removed_scripts_| below. - std::set<UserScript> changed_scripts(added_scripts_); - changed_scripts.insert(removed_scripts_.begin(), removed_scripts_.end()); - for (const UserScript& script : changed_scripts) + user_scripts_->reserve(user_scripts_->size() + added_scripts_map_.size()); + for (const auto& id_and_script : added_scripts_map_) { + const UserScript& script = id_and_script.second; + added_script_ids.insert(script.id()); + // Expand |changed_hosts_| for OnScriptsLoaded, which will use it in + // its IPC message. This must be done before we clear |added_scripts_map_| + // and |removed_script_hosts_| below. changed_hosts_.insert(script.host_id()); + // Put script from |added_scripts_map_| into |user_scripts_|. + user_scripts_->push_back(added_scripts_map_[script.id()]); + } + for (const UserScriptIDPair& id_pair : removed_script_hosts_) + changed_hosts_.insert(id_pair.host_id); LoadScripts(std::move(user_scripts_), changed_hosts_, added_script_ids, base::Bind(&UserScriptLoader::OnScriptsLoaded, weak_factory_.GetWeakPtr())); clear_scripts_ = false; - added_scripts_.clear(); - removed_scripts_.clear(); + added_scripts_map_.clear(); + removed_script_hosts_.clear(); user_scripts_.reset(); }
diff --git a/extensions/browser/user_script_loader.h b/extensions/browser/user_script_loader.h index 5d110a3..1d7aaf0 100644 --- a/extensions/browser/user_script_loader.h +++ b/extensions/browser/user_script_loader.h
@@ -58,7 +58,7 @@ ~UserScriptLoader() override; // Add |scripts| to the set of scripts managed by this loader. - void AddScripts(const std::set<UserScript>& scripts); + void AddScripts(const UserScriptList& scripts); // Add |scripts| to the set of scripts managed by this loader. // The fetch of the content of the script starts URL request @@ -66,12 +66,15 @@ // |render_process_id, render_frame_id|. // TODO(hanxi): The renderer information doesn't really belong in this base // class, but it's not an easy fix. - virtual void AddScripts(const std::set<UserScript>& scripts, + virtual void AddScripts(const UserScriptList& scripts, int render_process_id, int render_frame_id); - // Remove |scripts| from the set of scripts managed by this loader. - void RemoveScripts(const std::set<UserScript>& scripts); + // Removes scripts with ids specified in |scripts| from the set of scripts + // managed by this loader. + // TODO(lazyboy): Likely we can make |scripts| a std::vector, but + // WebViewContentScriptManager makes this non-trivial. + void RemoveScripts(const std::set<UserScriptIDPair>& scripts); // Clears the set of scripts managed by this loader. void ClearScripts(); @@ -132,7 +135,7 @@ bool is_loading() const { // Ownership of |user_scripts_| is passed to the file thread when loading. - return user_scripts_.get() == NULL; + return user_scripts_.get() == nullptr; } // Manages our notification registrations. @@ -144,10 +147,11 @@ // List of scripts from currently-installed extensions we should load. std::unique_ptr<UserScriptList> user_scripts_; - // The mutually-exclusive sets of scripts that were added or removed since the - // last script load. - std::set<UserScript> added_scripts_; - std::set<UserScript> removed_scripts_; + // The mutually-exclusive information about sets of scripts that were added or + // removed since the last script load. These maps are keyed by script ids. + // Note that we only need HostID information for removal. + std::map<int, UserScript> added_scripts_map_; + std::set<UserScriptIDPair> removed_script_hosts_; // Indicates whether the the collection of scripts should be cleared before // additions and removals on the next script load.
diff --git a/extensions/browser/web_ui_user_script_loader.cc b/extensions/browser/web_ui_user_script_loader.cc index ee8fd098..2180e8e 100644 --- a/extensions/browser/web_ui_user_script_loader.cc +++ b/extensions/browser/web_ui_user_script_loader.cc
@@ -49,7 +49,7 @@ } void WebUIUserScriptLoader::AddScripts( - const std::set<extensions::UserScript>& scripts, + const extensions::UserScriptList& scripts, int render_process_id, int render_frame_id) { UserScriptRenderInfo info(render_process_id, render_frame_id);
diff --git a/extensions/browser/web_ui_user_script_loader.h b/extensions/browser/web_ui_user_script_loader.h index ea77161..0bba40c2 100644 --- a/extensions/browser/web_ui_user_script_loader.h +++ b/extensions/browser/web_ui_user_script_loader.h
@@ -32,7 +32,7 @@ using UserScriptRenderInfoMap = std::map<int, UserScriptRenderInfo>; // UserScriptLoader: - void AddScripts(const std::set<extensions::UserScript>& scripts, + void AddScripts(const extensions::UserScriptList& scripts, int render_process_id, int render_frame_id) override; void LoadScripts(std::unique_ptr<extensions::UserScriptList> user_scripts,
diff --git a/extensions/common/extension_set.cc b/extensions/common/extension_set.cc index c4c15d4..6d5657a3 100644 --- a/extensions/common/extension_set.cc +++ b/extensions/common/extension_set.cc
@@ -44,7 +44,7 @@ } bool ExtensionSet::Insert(const scoped_refptr<const Extension>& extension) { - bool was_present = ContainsKey(extensions_, extension->id()); + bool was_present = base::ContainsKey(extensions_, extension->id()); extensions_[extension->id()] = extension; if (!was_present && !modification_callback_.is_null()) modification_callback_.Run(GetIDs());
diff --git a/extensions/common/features/base_feature_provider_unittest.cc b/extensions/common/features/base_feature_provider_unittest.cc index 52a8f79..599a6a6 100644 --- a/extensions/common/features/base_feature_provider_unittest.cc +++ b/extensions/common/features/base_feature_provider_unittest.cc
@@ -30,12 +30,13 @@ const std::vector<Manifest::Type>& extension_types = feature->extension_types(); EXPECT_EQ(6u, extension_types.size()); - EXPECT_EQ(1, STLCount(extension_types, Manifest::TYPE_EXTENSION)); - EXPECT_EQ(1, STLCount(extension_types, Manifest::TYPE_LEGACY_PACKAGED_APP)); - EXPECT_EQ(1, STLCount(extension_types, Manifest::TYPE_PLATFORM_APP)); - EXPECT_EQ(1, STLCount(extension_types, Manifest::TYPE_HOSTED_APP)); - EXPECT_EQ(1, STLCount(extension_types, Manifest::TYPE_THEME)); - EXPECT_EQ(1, STLCount(extension_types, Manifest::TYPE_SHARED_MODULE)); + EXPECT_EQ(1, base::STLCount(extension_types, Manifest::TYPE_EXTENSION)); + EXPECT_EQ( + 1, base::STLCount(extension_types, Manifest::TYPE_LEGACY_PACKAGED_APP)); + EXPECT_EQ(1, base::STLCount(extension_types, Manifest::TYPE_PLATFORM_APP)); + EXPECT_EQ(1, base::STLCount(extension_types, Manifest::TYPE_HOSTED_APP)); + EXPECT_EQ(1, base::STLCount(extension_types, Manifest::TYPE_THEME)); + EXPECT_EQ(1, base::STLCount(extension_types, Manifest::TYPE_SHARED_MODULE)); } // Tests that real manifest features have the correct availability for an @@ -87,9 +88,10 @@ const std::vector<Manifest::Type>& extension_types = feature->extension_types(); EXPECT_EQ(3u, extension_types.size()); - EXPECT_EQ(1, STLCount(extension_types, Manifest::TYPE_EXTENSION)); - EXPECT_EQ(1, STLCount(extension_types, Manifest::TYPE_LEGACY_PACKAGED_APP)); - EXPECT_EQ(1, STLCount(extension_types, Manifest::TYPE_PLATFORM_APP)); + EXPECT_EQ(1, base::STLCount(extension_types, Manifest::TYPE_EXTENSION)); + EXPECT_EQ( + 1, base::STLCount(extension_types, Manifest::TYPE_LEGACY_PACKAGED_APP)); + EXPECT_EQ(1, base::STLCount(extension_types, Manifest::TYPE_PLATFORM_APP)); } // Tests that real permission features have the correct availability for an app.
diff --git a/extensions/common/features/simple_feature.cc b/extensions/common/features/simple_feature.cc index 65f283b..37a0c80 100644 --- a/extensions/common/features/simple_feature.cc +++ b/extensions/common/features/simple_feature.cc
@@ -399,7 +399,7 @@ Manifest::Type type_to_check = (type == Manifest::TYPE_USER_SCRIPT) ? Manifest::TYPE_EXTENSION : type; if (!extension_types_.empty() && - !ContainsValue(extension_types_, type_to_check)) { + !base::ContainsValue(extension_types_, type_to_check)) { return CreateAvailability(INVALID_TYPE, type); } @@ -421,7 +421,7 @@ if (!MatchesManifestLocation(location)) return CreateAvailability(INVALID_LOCATION, type); - if (!platforms_.empty() && !ContainsValue(platforms_, platform)) + if (!platforms_.empty() && !base::ContainsValue(platforms_, platform)) return CreateAvailability(INVALID_PLATFORM, type); if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) @@ -465,7 +465,7 @@ // extension API calls, since there's no guarantee that the extension is // "active" in current renderer process when the API permission check is // done. - if (!contexts_.empty() && !ContainsValue(contexts_, context)) + if (!contexts_.empty() && !base::ContainsValue(contexts_, context)) return CreateAvailability(INVALID_CONTEXT, context); // TODO(kalman): Consider checking |matches_| regardless of context type. @@ -622,8 +622,8 @@ if (!IsValidExtensionId(extension_id)) return false; - return (ContainsValue(list, extension_id) || - ContainsValue(list, HashedIdInHex(extension_id))); + return (base::ContainsValue(list, extension_id) || + base::ContainsValue(list, HashedIdInHex(extension_id))); } bool SimpleFeature::MatchesManifestLocation(
diff --git a/extensions/common/features/simple_feature_unittest.cc b/extensions/common/features/simple_feature_unittest.cc index 5ad4f78b..662cf28 100644 --- a/extensions/common/features/simple_feature_unittest.cc +++ b/extensions/common/features/simple_feature_unittest.cc
@@ -548,8 +548,8 @@ std::unique_ptr<SimpleFeature> feature(new SimpleFeature()); feature->Parse(value.get()); EXPECT_EQ(2u, feature->whitelist().size()); - EXPECT_TRUE(STLCount(feature->whitelist(), "foo")); - EXPECT_TRUE(STLCount(feature->whitelist(), "bar")); + EXPECT_TRUE(base::STLCount(feature->whitelist(), "foo")); + EXPECT_TRUE(base::STLCount(feature->whitelist(), "bar")); } TEST_F(SimpleFeatureTest, ParsePackageTypes) { @@ -565,15 +565,17 @@ std::unique_ptr<SimpleFeature> feature(new SimpleFeature()); feature->Parse(value.get()); EXPECT_EQ(6u, feature->extension_types().size()); - EXPECT_TRUE(STLCount(feature->extension_types(), Manifest::TYPE_EXTENSION)); - EXPECT_TRUE(STLCount(feature->extension_types(), Manifest::TYPE_THEME)); EXPECT_TRUE( - STLCount(feature->extension_types(), Manifest::TYPE_LEGACY_PACKAGED_APP)); - EXPECT_TRUE(STLCount(feature->extension_types(), Manifest::TYPE_HOSTED_APP)); + base::STLCount(feature->extension_types(), Manifest::TYPE_EXTENSION)); + EXPECT_TRUE(base::STLCount(feature->extension_types(), Manifest::TYPE_THEME)); + EXPECT_TRUE(base::STLCount(feature->extension_types(), + Manifest::TYPE_LEGACY_PACKAGED_APP)); EXPECT_TRUE( - STLCount(feature->extension_types(), Manifest::TYPE_PLATFORM_APP)); + base::STLCount(feature->extension_types(), Manifest::TYPE_HOSTED_APP)); EXPECT_TRUE( - STLCount(feature->extension_types(), Manifest::TYPE_SHARED_MODULE)); + base::STLCount(feature->extension_types(), Manifest::TYPE_PLATFORM_APP)); + EXPECT_TRUE( + base::STLCount(feature->extension_types(), Manifest::TYPE_SHARED_MODULE)); value->SetString("extension_types", "all"); std::unique_ptr<SimpleFeature> feature2(new SimpleFeature()); @@ -596,12 +598,14 @@ feature->Parse(value.get()); EXPECT_EQ(7u, feature->contexts().size()); EXPECT_TRUE( - STLCount(feature->contexts(), Feature::BLESSED_EXTENSION_CONTEXT)); + base::STLCount(feature->contexts(), Feature::BLESSED_EXTENSION_CONTEXT)); + EXPECT_TRUE(base::STLCount(feature->contexts(), + Feature::UNBLESSED_EXTENSION_CONTEXT)); EXPECT_TRUE( - STLCount(feature->contexts(), Feature::UNBLESSED_EXTENSION_CONTEXT)); - EXPECT_TRUE(STLCount(feature->contexts(), Feature::CONTENT_SCRIPT_CONTEXT)); - EXPECT_TRUE(STLCount(feature->contexts(), Feature::WEB_PAGE_CONTEXT)); - EXPECT_TRUE(STLCount(feature->contexts(), Feature::BLESSED_WEB_PAGE_CONTEXT)); + base::STLCount(feature->contexts(), Feature::CONTENT_SCRIPT_CONTEXT)); + EXPECT_TRUE(base::STLCount(feature->contexts(), Feature::WEB_PAGE_CONTEXT)); + EXPECT_TRUE( + base::STLCount(feature->contexts(), Feature::BLESSED_WEB_PAGE_CONTEXT)); value->SetString("contexts", "all"); std::unique_ptr<SimpleFeature> feature2(new SimpleFeature()); @@ -675,10 +679,10 @@ EXPECT_EQ(1u, feature.whitelist().size()); EXPECT_EQ(1u, feature.extension_types().size()); EXPECT_EQ(1u, feature.contexts().size()); - EXPECT_EQ(1, STLCount(feature.whitelist(), "foo")); + EXPECT_EQ(1, base::STLCount(feature.whitelist(), "foo")); EXPECT_EQ(SimpleFeature::COMPONENT_LOCATION, feature.location()); EXPECT_EQ(1u, feature.platforms().size()); - EXPECT_EQ(1, STLCount(feature.platforms(), Feature::CHROMEOS_PLATFORM)); + EXPECT_EQ(1, base::STLCount(feature.platforms(), Feature::CHROMEOS_PLATFORM)); EXPECT_EQ(1, feature.min_manifest_version()); EXPECT_EQ(2, feature.max_manifest_version()); @@ -699,10 +703,11 @@ EXPECT_EQ(1u, feature.whitelist().size()); EXPECT_EQ(1u, feature.extension_types().size()); EXPECT_EQ(1u, feature.contexts().size()); - EXPECT_EQ(1, STLCount(feature.whitelist(), "bar")); - EXPECT_EQ(1, STLCount(feature.extension_types(), Manifest::TYPE_EXTENSION)); - EXPECT_EQ(1, - STLCount(feature.contexts(), Feature::UNBLESSED_EXTENSION_CONTEXT)); + EXPECT_EQ(1, base::STLCount(feature.whitelist(), "bar")); + EXPECT_EQ( + 1, base::STLCount(feature.extension_types(), Manifest::TYPE_EXTENSION)); + EXPECT_EQ(1, base::STLCount(feature.contexts(), + Feature::UNBLESSED_EXTENSION_CONTEXT)); EXPECT_EQ(2, feature.min_manifest_version()); EXPECT_EQ(3, feature.max_manifest_version()); }
diff --git a/extensions/common/manifest_handler.cc b/extensions/common/manifest_handler.cc index 815146e3..537bb9a 100644 --- a/extensions/common/manifest_handler.cc +++ b/extensions/common/manifest_handler.cc
@@ -227,7 +227,7 @@ << "Extension manifest handler depends on unrecognized key " << prerequisites[i]; // Prerequisite is in our map. - if (ContainsKey(priority_map_, prereq_iter->second.get())) + if (base::ContainsKey(priority_map_, prereq_iter->second.get())) unsatisfied--; } if (unsatisfied == 0) {
diff --git a/extensions/common/message_bundle.cc b/extensions/common/message_bundle.cc index 104bbae1..28d7098 100644 --- a/extensions/common/message_bundle.cc +++ b/extensions/common/message_bundle.cc
@@ -116,7 +116,7 @@ // Add all reserved messages to the dictionary, but check for collisions. SubstitutionMap::iterator it = append_messages.begin(); for (; it != append_messages.end(); ++it) { - if (ContainsKey(dictionary_, it->first)) { + if (base::ContainsKey(dictionary_, it->first)) { *error = ErrorUtils::FormatErrorMessage( errors::kReservedMessageFound, it->first); return false;
diff --git a/extensions/common/permissions/api_permission_set.cc b/extensions/common/permissions/api_permission_set.cc index d1c7f32..d5b14a0 100644 --- a/extensions/common/permissions/api_permission_set.cc +++ b/extensions/common/permissions/api_permission_set.cc
@@ -275,7 +275,7 @@ const std::set<APIPermission::ID>& permission_ids) const { PermissionIDSet subset; for (const auto& permission : permissions_) { - if (ContainsKey(permission_ids, permission.id())) { + if (base::ContainsKey(permission_ids, permission.id())) { subset.permissions_.insert(permission); } }
diff --git a/extensions/common/permissions/permissions_info.cc b/extensions/common/permissions/permissions_info.cc index e83fb2e..cabb7e6 100644 --- a/extensions/common/permissions/permissions_info.cc +++ b/extensions/common/permissions/permissions_info.cc
@@ -72,20 +72,20 @@ } PermissionsInfo::~PermissionsInfo() { - STLDeleteContainerPairSecondPointers(id_map_.begin(), id_map_.end()); + base::STLDeleteContainerPairSecondPointers(id_map_.begin(), id_map_.end()); } void PermissionsInfo::RegisterAlias( const char* name, const char* alias) { - DCHECK(ContainsKey(name_map_, name)); - DCHECK(!ContainsKey(name_map_, alias)); + DCHECK(base::ContainsKey(name_map_, name)); + DCHECK(!base::ContainsKey(name_map_, alias)); name_map_[alias] = name_map_[name]; } void PermissionsInfo::RegisterPermission(APIPermissionInfo* permission) { - DCHECK(!ContainsKey(id_map_, permission->id())); - DCHECK(!ContainsKey(name_map_, permission->name())); + DCHECK(!base::ContainsKey(id_map_, permission->id())); + DCHECK(!base::ContainsKey(name_map_, permission->name())); id_map_[permission->id()] = permission; name_map_[permission->name()] = permission;
diff --git a/extensions/common/user_script.cc b/extensions/common/user_script.cc index 20bff9f1..ddf1fb39 100644 --- a/extensions/common/user_script.cc +++ b/extensions/common/user_script.cc
@@ -288,6 +288,15 @@ } } +UserScriptIDPair::UserScriptIDPair(int id, const HostID& host_id) + : id(id), host_id(host_id) {} + +UserScriptIDPair::UserScriptIDPair(int id) : id(id), host_id(HostID()) {} + +bool operator<(const UserScriptIDPair& a, const UserScriptIDPair& b) { + return a.id < b.id; +} + bool operator<(const UserScript& script1, const UserScript& script2) { // The only kind of script that should be compared is the kind that has its // IDs initialized to a meaningful value.
diff --git a/extensions/common/user_script.h b/extensions/common/user_script.h index d6b3377..44a2d67 100644 --- a/extensions/common/user_script.h +++ b/extensions/common/user_script.h
@@ -317,9 +317,20 @@ bool incognito_enabled_; }; +// Information we need while removing scripts from a UserScriptLoader. +struct UserScriptIDPair { + UserScriptIDPair(int id, const HostID& host_id); + UserScriptIDPair(int id); + + int id; + HostID host_id; +}; + // For storing UserScripts with unique IDs in sets. bool operator<(const UserScript& script1, const UserScript& script2); +bool operator<(const UserScriptIDPair& a, const UserScriptIDPair& b); + typedef std::vector<UserScript> UserScriptList; } // namespace extensions
diff --git a/extensions/renderer/api/display_source/wifi_display/wifi_display_audio_encoder_lpcm.cc b/extensions/renderer/api/display_source/wifi_display/wifi_display_audio_encoder_lpcm.cc index b7d3d9d..6e6f169 100644 --- a/extensions/renderer/api/display_source/wifi_display/wifi_display_audio_encoder_lpcm.cc +++ b/extensions/renderer/api/display_source/wifi_display/wifi_display_audio_encoder_lpcm.cc
@@ -154,7 +154,7 @@ int sample_count = fifo_bus_->channels() * fifo_bus_->frames(); data.resize(sample_count * sizeof(uint16_t)); uint16_t* encoded_samples = - reinterpret_cast<uint16_t*>(string_as_array(&data)); + reinterpret_cast<uint16_t*>(base::string_as_array(&data)); fifo_bus_->ToInterleaved(fifo_bus_->frames(), kOutputBytesPerSample, encoded_samples); for (int i = 0; i < sample_count; ++i)
diff --git a/extensions/renderer/event_bindings.cc b/extensions/renderer/event_bindings.cc index de99257c..db5fb60f 100644 --- a/extensions/renderer/event_bindings.cc +++ b/extensions/renderer/event_bindings.cc
@@ -272,14 +272,18 @@ filter = base::DictionaryValue::From(std::move(filter_value)); } - // Hold onto a weak reference to |filter| so that it can be used after passing - // ownership to |event_filter|. - base::DictionaryValue* filter_weak = filter.get(); int id = g_event_filter.Get().AddEventMatcher( event_name, ParseEventMatcher(std::move(filter))); + if (id == -1) { + args.GetReturnValue().Set(static_cast<int32_t>(-1)); + return; + } attached_matcher_ids_.insert(id); // Only send IPCs the first time a filter gets added. + const EventMatcher* matcher = g_event_filter.Get().GetEventMatcher(id); + DCHECK(matcher); + base::DictionaryValue* filter_weak = matcher->value(); std::string extension_id = context()->GetExtensionID(); if (AddFilter(event_name, extension_id, *filter_weak)) { bool lazy = ExtensionFrameHelper::IsContextForEventPage(context());
diff --git a/extensions/renderer/i18n_custom_bindings.cc b/extensions/renderer/i18n_custom_bindings.cc index a68e7ba..87e74b37 100644 --- a/extensions/renderer/i18n_custom_bindings.cc +++ b/extensions/renderer/i18n_custom_bindings.cc
@@ -292,7 +292,7 @@ chrome_lang_id::NNetLanguageIdentifier nnet_lang_id(/*min_num_bytes=*/0, /*max_num_bytes=*/512); const std::vector<chrome_lang_id::NNetLanguageIdentifier::Result> - lang_results = nnet_lang_id.FindTopNMostLikelyLangs(text, kCldNumLangs); + lang_results = nnet_lang_id.FindTopNMostFreqLangs(text, kCldNumLangs); LanguageDetectionResult result; // Populate LanguageDetectionResult with prediction reliability, languages,
diff --git a/google_apis/drive/request_sender.cc b/google_apis/drive/request_sender.cc index 2f8b4c8..fc27535 100644 --- a/google_apis/drive/request_sender.cc +++ b/google_apis/drive/request_sender.cc
@@ -27,8 +27,8 @@ RequestSender::~RequestSender() { DCHECK(thread_checker_.CalledOnValidThread()); - STLDeleteContainerPointers(in_flight_requests_.begin(), - in_flight_requests_.end()); + base::STLDeleteContainerPointers(in_flight_requests_.begin(), + in_flight_requests_.end()); } base::Closure RequestSender::StartRequestWithAuthRetry(
diff --git a/google_apis/gaia/account_tracker.cc b/google_apis/gaia/account_tracker.cc index 83aed2f..0a2cce0 100644 --- a/google_apis/gaia/account_tracker.cc +++ b/google_apis/gaia/account_tracker.cc
@@ -28,7 +28,7 @@ void AccountTracker::Shutdown() { shutdown_called_ = true; - STLDeleteValues(&user_info_requests_); + base::STLDeleteValues(&user_info_requests_); identity_provider_->GetTokenService()->RemoveObserver(this); identity_provider_->RemoveObserver(this); } @@ -205,7 +205,7 @@ FROM_HERE_WITH_EXPLICIT_FUNCTION( "422460 AccountTracker::StartTrackingAccount")); - if (!ContainsKey(accounts_, account_key)) { + if (!base::ContainsKey(accounts_, account_key)) { DVLOG(1) << "StartTracking " << account_key; AccountState account_state; account_state.ids.account_key = account_key; @@ -217,7 +217,7 @@ void AccountTracker::StopTrackingAccount(const std::string account_key) { DVLOG(1) << "StopTracking " << account_key; - if (ContainsKey(accounts_, account_key)) { + if (base::ContainsKey(accounts_, account_key)) { AccountState& account = accounts_[account_key]; if (!account.ids.gaia.empty()) { UpdateSignInState(account_key, false); @@ -226,7 +226,7 @@ accounts_.erase(account_key); } - if (ContainsKey(user_info_requests_, account_key)) + if (base::ContainsKey(user_info_requests_, account_key)) DeleteFetcher(user_info_requests_[account_key]); } @@ -242,7 +242,7 @@ FROM_HERE_WITH_EXPLICIT_FUNCTION( "422460 AccountTracker::StartFetchingUserInfo")); - if (ContainsKey(user_info_requests_, account_key)) { + if (base::ContainsKey(user_info_requests_, account_key)) { // TODO(robliao): Remove ScopedTracker below once https://crbug.com/422460 // is fixed. tracked_objects::ScopedTracker tracking_profile1( @@ -278,7 +278,7 @@ void AccountTracker::OnUserInfoFetchSuccess(AccountIdFetcher* fetcher, const std::string& gaia_id) { const std::string& account_key = fetcher->account_key(); - DCHECK(ContainsKey(accounts_, account_key)); + DCHECK(base::ContainsKey(accounts_, account_key)); AccountState& account = accounts_[account_key]; account.ids.gaia = gaia_id; @@ -300,7 +300,7 @@ void AccountTracker::DeleteFetcher(AccountIdFetcher* fetcher) { DVLOG(1) << "DeleteFetcher " << fetcher->account_key(); const std::string& account_key = fetcher->account_key(); - DCHECK(ContainsKey(user_info_requests_, account_key)); + DCHECK(base::ContainsKey(user_info_requests_, account_key)); DCHECK_EQ(fetcher, user_info_requests_[account_key]); user_info_requests_.erase(account_key); delete fetcher;
diff --git a/google_apis/gaia/oauth2_token_service.cc b/google_apis/gaia/oauth2_token_service.cc index 8c703a1..1636701 100644 --- a/google_apis/gaia/oauth2_token_service.cc +++ b/google_apis/gaia/oauth2_token_service.cc
@@ -398,8 +398,8 @@ OAuth2TokenService::~OAuth2TokenService() { // Release all the pending fetchers. - STLDeleteContainerPairSecondPointers( - pending_fetchers_.begin(), pending_fetchers_.end()); + base::STLDeleteContainerPairSecondPointers(pending_fetchers_.begin(), + pending_fetchers_.end()); } OAuth2TokenServiceDelegate* OAuth2TokenService::GetDelegate() {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index ceabff8a..68b89484 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -11538,8 +11538,11 @@ GLint y = 0; while (y < height) { GLint h = y + tile_height > height ? height - y : tile_height; - glTexSubImage2D(target, level, xoffset, yoffset + y, width, h, format, type, - zero.get()); + glTexSubImage2D( + target, level, xoffset, yoffset + y, width, h, + TextureManager::AdjustTexFormat(feature_info_.get(), format), + type, + zero.get()); y += tile_height; } TextureRef* bound_texture = @@ -13261,10 +13264,16 @@ return; } + // For 3D textures, we always clear the entire texture. See the code in + // TextureManager::ValidateAndDoTexSubImage for TexSubImage3D. + if (!texture->IsLevelCleared(target, level)) { + texture_manager()->ClearTextureLevel(this, texture_ref, target, level); + DCHECK(texture->IsLevelCleared(target, level)); + } + // TODO(yunchao): Follow-up CLs are necessary. For instance: // 1. emulation of unsized formats in core profile - // 2. clear the 3d textures if it is uncleared. - // 3. out-of-bounds reading, etc. + // 2. out-of-bounds reading, etc. glCopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height); @@ -15017,9 +15026,18 @@ source_internal_format == GL_BGRA8_EXT || source_internal_format == GL_RGB_YCBCR_420V_CHROMIUM || source_internal_format == GL_RGB_YCBCR_422_CHROMIUM; - if (!valid_source_format || !valid_dest_format) { + if (!valid_source_format) { + std::string msg = "invalid source internal format " + + GLES2Util::GetStringEnum(source_internal_format); LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, - "invalid internal format"); + msg.c_str()); + return false; + } + if (!valid_dest_format) { + std::string msg = "invalid dest internal format " + + GLES2Util::GetStringEnum(dest_internal_format); + LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, function_name, + msg.c_str()); return false; } return true;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc index 2495c9a..7435b8d 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_textures.cc
@@ -1368,6 +1368,78 @@ EXPECT_EQ(GL_INVALID_OPERATION, GetGLError()); } +TEST_P(GLES3DecoderTest, CopyTexSubImage3DClearTheUncleared3DTexture) { + const GLenum kTarget = GL_TEXTURE_3D; + const GLint kLevel = 0; + const GLint kXoffset = 0; + const GLint kYoffset = 0; + const GLint kZoffset = 0; + const GLint kX = 0; + const GLint kY = 0; + const GLint kInternalFormat = GL_RGB8; + const GLsizei kWidth = 2; + const GLsizei kHeight = 2; + const GLsizei kDepth = 2; + const GLenum kFormat = GL_RGB; + const GLenum kType = GL_UNSIGNED_BYTE; + const uint32_t kBufferSize = kWidth * kHeight * kDepth * 4; + + DoBindTexture(kTarget, client_texture_id_, kServiceTextureId); + DoTexImage3D(kTarget, kLevel, kInternalFormat, kWidth, kHeight, kDepth, 0, + kFormat, kType, 0, 0); + TextureRef* texture_ref = + group().texture_manager()->GetTexture(client_texture_id_); + ASSERT_TRUE(texture_ref != NULL); + Texture* texture = texture_ref->texture(); + + EXPECT_FALSE(texture->SafeToRenderFrom()); + EXPECT_FALSE(texture->IsLevelCleared(kTarget, kLevel)); + + // CopyTexSubImage3D will clear the uncleared texture + EXPECT_CALL(*gl_, GenBuffersARB(1, _)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, BindBuffer(GL_PIXEL_UNPACK_BUFFER, _)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, BufferData(GL_PIXEL_UNPACK_BUFFER, + kBufferSize, _, GL_STATIC_DRAW)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, BindTexture(kTarget, kServiceTextureId)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, TexSubImage3DNoData(kTarget, kLevel, + kXoffset, kYoffset, kZoffset, + kWidth, kHeight, kDepth, + kFormat, kType)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, BindBuffer(GL_PIXEL_UNPACK_BUFFER, _)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, DeleteBuffersARB(1, _)) + .Times(1) + .RetiresOnSaturation(); + EXPECT_CALL(*gl_, BindTexture(kTarget, _)) + .Times(1) + .RetiresOnSaturation(); + + EXPECT_CALL(*gl_, + CopyTexSubImage3D(kTarget, kLevel, kXoffset, kYoffset, kZoffset, + kX, kY, kWidth, kHeight)) + .Times(1) + .RetiresOnSaturation(); + + CopyTexSubImage3D cmd; + cmd.Init(kTarget, kLevel, kXoffset, kYoffset, kZoffset, + kX, kY, kWidth, kHeight); + EXPECT_EQ(error::kNoError, ExecuteCmd(cmd)); + EXPECT_EQ(GL_NO_ERROR, GetGLError()); + EXPECT_TRUE(texture->SafeToRenderFrom()); + EXPECT_TRUE(texture->IsLevelCleared(kTarget, kLevel)); +} + TEST_P(GLES3DecoderTest, CompressedTexImage3DFailsWithBadImageSize) { const uint32_t kBucketId = 123; const GLenum kTarget = GL_TEXTURE_2D_ARRAY;
diff --git a/gpu/config/gpu_driver_bug_list_json.cc b/gpu/config/gpu_driver_bug_list_json.cc index ea220ff9..89cb16b1 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": "8.80", + "version": "8.81", "entries": [ { "id": 1, @@ -1884,6 +1884,19 @@ "disabled_extensions": [ "GL_EXT_multisampled_render_to_texture" ] + }, + { + "id": 176, + "description": "glClear does not work on Acer Predator GT-810", + "cr_bugs": [633634], + "os": { + "type": "android" + }, + "gl_vendor": "Intel", + "gl_renderer": ".*Atom.*x5/x7.*", + "features": [ + "gl_clear_broken" + ] } ] }
diff --git a/gpu/config/gpu_info_collector_android.cc b/gpu/config/gpu_info_collector_android.cc index 3ae3d66..1312e35 100644 --- a/gpu/config/gpu_info_collector_android.cc +++ b/gpu/config/gpu_info_collector_android.cc
@@ -18,7 +18,6 @@ #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" -#include "gpu/config/gpu_switches.h" #include "ui/gl/egl_util.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context.h" @@ -206,20 +205,6 @@ gpu_info->gl_extensions = reinterpret_cast<const char*>(glGetStringFn(GL_EXTENSIONS)); - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch(switches::kGpuTestingGLVendor)) { - gpu_info->gl_vendor = - command_line->GetSwitchValueASCII(switches::kGpuTestingGLVendor); - } - if (command_line->HasSwitch(switches::kGpuTestingGLRenderer)) { - gpu_info->gl_renderer = - command_line->GetSwitchValueASCII(switches::kGpuTestingGLRenderer); - } - if (command_line->HasSwitch(switches::kGpuTestingGLVersion)) { - gpu_info->gl_version = - command_line->GetSwitchValueASCII(switches::kGpuTestingGLVersion); - } - GLint max_samples = 0; glGetIntegervFn(GL_MAX_SAMPLES, &max_samples); gpu_info->max_msaa_samples = base::IntToString(max_samples);
diff --git a/gpu/config/gpu_info_collector_linux.cc b/gpu/config/gpu_info_collector_linux.cc index 050c33d..1f38047 100644 --- a/gpu/config/gpu_info_collector_linux.cc +++ b/gpu/config/gpu_info_collector_linux.cc
@@ -19,6 +19,8 @@ #include "base/strings/string_util.h" #include "base/trace_event/trace_event.h" #include "gpu/config/gpu_info_collector.h" +#include "gpu/config/gpu_switches.h" +#include "third_party/re2/src/re2/re2.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_implementation.h" @@ -246,9 +248,15 @@ CollectInfoResult CollectDriverInfoGL(GPUInfo* gpu_info) { DCHECK(gpu_info); + // Driver vendor and version are always expected to be extracted from the + // testing gl version. + if (!base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kGpuTestingGLVersion) && + !gpu_info->driver_vendor.empty() && !gpu_info->driver_version.empty()) { + return kCollectInfoSuccess; + } + std::string gl_version = gpu_info->gl_version; - if (base::StartsWith(gl_version, "OpenGL ES", base::CompareCase::SENSITIVE)) - gl_version = gl_version.substr(10); std::vector<std::string> pieces = base::SplitString( gl_version, base::kWhitespaceASCII, base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); @@ -257,14 +265,23 @@ if (pieces.size() < 3) return kCollectInfoNonFatalFailure; - std::string driver_version = pieces[2]; - size_t pos = driver_version.find_first_not_of("0123456789."); - if (pos == 0) - return kCollectInfoNonFatalFailure; - if (pos != std::string::npos) - driver_version = driver_version.substr(0, pos); + // Search from the end for the first piece that starts with major.minor or + // major.minor.micro but assume the driver version cannot be in the first two + // pieces. + re2::RE2 pattern("([\\d]+\\.[\\d]+(\\.[\\d]+)?).*"); + std::string driver_version; + auto it = pieces.rbegin(); + while (pieces.rend() - it > 2) { + bool parsed = re2::RE2::FullMatch(*it, pattern, &driver_version); + if (parsed) + break; + ++it; + } - gpu_info->driver_vendor = pieces[1]; + if (driver_version.empty()) + return kCollectInfoNonFatalFailure; + + gpu_info->driver_vendor = *(++it); gpu_info->driver_version = driver_version; return kCollectInfoSuccess; }
diff --git a/gpu/config/gpu_info_collector_unittest.cc b/gpu/config/gpu_info_collector_unittest.cc index c0847196..8c59574c 100644 --- a/gpu/config/gpu_info_collector_unittest.cc +++ b/gpu/config/gpu_info_collector_unittest.cc
@@ -246,64 +246,135 @@ }; TEST_F(CollectDriverInfoGLTest, CollectDriverInfoGL) { + // clang-format off const struct { + const char* driver_vendor; + const char* driver_version; const char* gl_renderer; const char* gl_vendor; const char* gl_version; + const char* expected_driver_vendor; const char* expected_driver_version; } kTestStrings[] = { #if defined(OS_ANDROID) - {"Adreno (TM) 320", + {"Unknown", + "-1", + "Adreno (TM) 320", "Qualcomm", "OpenGL ES 2.0 V@14.0 AU@04.02 (CL@3206)", + "Unknown", "14.0"}, - {"Adreno (TM) 420", "Qualcomm", "OpenGL ES 3.0 V@84.0 AU@ (CL@)", "84.0"}, - {"PowerVR Rogue G6430", + {"Unknown", + "-1", + "Adreno (TM) 420", + "Qualcomm", + "OpenGL ES 3.0 V@84.0 AU@ (CL@)", + "Unknown", + "84.0"}, + {"Unknown", + "-1", + "PowerVR Rogue G6430", "Imagination Technologies", "OpenGL ES 3.1 build 1.4@3283119", + "Unknown", "1.4"}, - {"Mali-T604", "ARM", "OpenGL ES 3.1", "0"}, - {"NVIDIA Tegra", + {"Unknown", + "-1", + "Mali-T604", + "ARM", + "OpenGL ES 3.1", + "Unknown", + "0"}, + {"Unknown", + "-1", + "NVIDIA Tegra", "NVIDIA Corporation", "OpenGL ES 3.1 NVIDIA 343.00", + "Unknown", "343.00"}, - {"NVIDIA Tegra 3", + {"Unknown", + "-1", + "NVIDIA Tegra 3", "NVIDIA Corporation", "OpenGL ES 2.0 14.01003", + "Unknown", "14.01003"}, - {"random GPU", + {"Unknown", + "-1", + "random GPU", "random vendor", "OpenGL ES 2.0 with_long_version_string=1.2.3.4", + NULL, "1.2"}, - {"random GPU", + {"Unknown", + "-1", + "random GPU", "random vendor", "OpenGL ES 2.0 with_short_version_string=1", + NULL, "0"}, - {"random GPU", + {"Unknown", + "-1", + "random GPU", "random vendor", "OpenGL ES 2.0 with_no_version_string", + NULL, "0"}, #elif defined(OS_MACOSX) - {"Intel Iris Pro OpenGL Engine", + {"Unknown", + "-1", + "Intel Iris Pro OpenGL Engine", "Intel Inc.", "2.1 INTEL-10.6.20", + "Unknown", "10.6.20"}, #elif defined(OS_LINUX) - {"Quadro K2000/PCIe/SSE2", + {"", + "", + "Quadro K2000/PCIe/SSE2", "NVIDIA Corporation", "4.4.0 NVIDIA 331.79", + "NVIDIA", "331.79"}, + {"", + "", + "Gallium 0.4 on NVE7", + "nouveau", + "3.3 (Core Profile) Mesa 10.5.9", + "Mesa", + "10.5.9"}, + {"", + "", + "Mesa DRI Intel(R) Haswell Mobile", + "Intel Open Source Technology Center", + "OpenGL ES 3.0 Mesa 12.1.0-devel (git-ed9dd3b)", + "Mesa", + "12.1.0"}, + {"ATI / AMD", + "15.201.1151", + "ASUS R5 230 Series", + "ATI Technologies Inc.", + "4.5.13399 Compatibility Profile Context 14.0", + "ATI / AMD", + "15.201.1151"}, #endif - {NULL, NULL, NULL, NULL} + {NULL, NULL, NULL, NULL, NULL, NULL, NULL} }; + // clang-format on - GPUInfo gpu_info; for (int i = 0; kTestStrings[i].gl_renderer != NULL; ++i) { - gpu_info.gl_renderer = kTestStrings[i].gl_renderer; - gpu_info.gl_vendor = kTestStrings[i].gl_vendor; - gpu_info.gl_version = kTestStrings[i].gl_version; - EXPECT_EQ(CollectDriverInfoGL(&gpu_info), kCollectInfoSuccess); - EXPECT_EQ(gpu_info.driver_version, kTestStrings[i].expected_driver_version); + GPUInfo gpu_info; + const auto& testStrings = kTestStrings[i]; + gpu_info.driver_vendor = testStrings.driver_vendor; + gpu_info.driver_version = testStrings.driver_version; + gpu_info.gl_renderer = testStrings.gl_renderer; + gpu_info.gl_vendor = testStrings.gl_vendor; + gpu_info.gl_version = testStrings.gl_version; + EXPECT_EQ(kCollectInfoSuccess, CollectDriverInfoGL(&gpu_info)); + EXPECT_EQ(testStrings.expected_driver_version, gpu_info.driver_version); + if (testStrings.expected_driver_vendor) { + EXPECT_EQ(testStrings.expected_driver_vendor, gpu_info.driver_vendor); + } } }
diff --git a/gpu/ipc/common/BUILD.gn b/gpu/ipc/common/BUILD.gn index 69692eb..95e2a71 100644 --- a/gpu/ipc/common/BUILD.gn +++ b/gpu/ipc/common/BUILD.gn
@@ -130,6 +130,7 @@ ] public_deps = [ + "//mojo/common:common_custom_types", "//ui/gfx/geometry/mojo", ] }
diff --git a/gpu/ipc/common/dx_diag_node.mojom b/gpu/ipc/common/dx_diag_node.mojom index f0b52e16..346a12f7 100644 --- a/gpu/ipc/common/dx_diag_node.mojom +++ b/gpu/ipc/common/dx_diag_node.mojom
@@ -4,8 +4,7 @@ module gpu.mojom; -// gpu/config/dx_diag_node.h -// gpu::DxDiagNode +// Corresponds to |gpu::DxDiagNode| in file gpu/config/dx_diag_node.h struct DxDiagNode { map<string, string> values; map<string, DxDiagNode> children;
diff --git a/gpu/ipc/common/gpu_info.mojom b/gpu/ipc/common/gpu_info.mojom index db7babde..111dae8 100644 --- a/gpu/ipc/common/gpu_info.mojom +++ b/gpu/ipc/common/gpu_info.mojom
@@ -5,6 +5,8 @@ // gpu/config/gpu_info.h module gpu.mojom; +import "gpu/ipc/common/dx_diag_node.mojom"; +import "mojo/common/common_custom_types.mojom"; import "ui/gfx/geometry/mojo/geometry.mojom"; // gpu::GPUInfo::GPUDevice @@ -68,3 +70,45 @@ uint32 max_framerate_numerator; uint32 max_framerate_denominator; }; + +// Corresponds to |gpu::GPUInfo| in gpu/config/gpu_info.h +struct GpuInfo { + mojo.common.mojom.TimeDelta initialization_time; + bool optimus; + bool amd_switchable; + bool lenovo_dcute; + mojo.common.mojom.Version display_link_version; + GpuDevice gpu; + array<GpuDevice> secondary_gpus; + uint64 adapter_luid; + string driver_vendor; + string driver_version; + string driver_date; + string pixel_shader_version; + string vertex_shader_version; + string max_msaa_samples; + string machine_model_name; + string machine_model_version; + string gl_version; + string gl_vendor; + string gl_renderer; + string gl_extensions; + string gl_ws_vendor; + string gl_ws_version; + string gl_ws_extensions; + uint32 gl_reset_notification_strategy; + bool can_lose_context; + bool software_rendering; + bool direct_rendering; + bool sandboxed; + int32 process_crash_count; + bool in_process_gpu; + CollectInfoResult basic_info_state; + CollectInfoResult context_info_state; + CollectInfoResult dx_diagnostics_info_state; + DxDiagNode? dx_diagnostics; + VideoDecodeAcceleratorCapabilities video_decode_accelerator_capabilities; + array<VideoEncodeAcceleratorSupportedProfile> + video_encode_accelerator_supported_profiles; + bool jpeg_decode_accelerator_supported; +};
diff --git a/gpu/ipc/common/gpu_info.typemap b/gpu/ipc/common/gpu_info.typemap index dc8eb05e..fe21131 100644 --- a/gpu/ipc/common/gpu_info.typemap +++ b/gpu/ipc/common/gpu_info.typemap
@@ -8,13 +8,15 @@ sources = [ "//gpu/ipc/common/gpu_info_struct_traits.cc", ] -deps = [ +public_deps = [ "//gpu/config", + "//mojo/common", "//ui/gfx/geometry/mojo", ] type_mappings = [ - "gpu.mojom.GpuDevice=gpu::GPUInfo::GPUDevice", "gpu.mojom.CollectInfoResult=gpu::CollectInfoResult", + "gpu.mojom.GpuDevice=gpu::GPUInfo::GPUDevice", + "gpu.mojom.GpuInfo=gpu::GPUInfo", "gpu.mojom.VideoCodecProfile=gpu::VideoCodecProfile", "gpu.mojom.VideoDecodeAcceleratorSupportedProfile=gpu::VideoDecodeAcceleratorSupportedProfile", "gpu.mojom.VideoDecodeAcceleratorCapabilities=gpu::VideoDecodeAcceleratorCapabilities",
diff --git a/gpu/ipc/common/gpu_info_struct_traits.cc b/gpu/ipc/common/gpu_info_struct_traits.cc index ca3153b..8dba638 100644 --- a/gpu/ipc/common/gpu_info_struct_traits.cc +++ b/gpu/ipc/common/gpu_info_struct_traits.cc
@@ -4,6 +4,9 @@ #include "gpu/ipc/common/gpu_info_struct_traits.h" +#include "ipc/ipc_message_utils.h" +#include "mojo/common/common_custom_types_struct_traits.h" + namespace mojo { // static @@ -209,4 +212,52 @@ data.ReadMaxResolution(&out->max_resolution); } +bool StructTraits<gpu::mojom::GpuInfo, gpu::GPUInfo>::Read( + gpu::mojom::GpuInfoDataView data, + gpu::GPUInfo* out) { + out->optimus = data.optimus(); + out->amd_switchable = data.amd_switchable(); + out->lenovo_dcute = data.lenovo_dcute(); + out->adapter_luid = data.adapter_luid(); + out->gl_reset_notification_strategy = data.gl_reset_notification_strategy(); + out->can_lose_context = data.can_lose_context(); + out->software_rendering = data.software_rendering(); + out->direct_rendering = data.direct_rendering(); + out->sandboxed = data.sandboxed(); + out->in_process_gpu = data.in_process_gpu(); + out->process_crash_count = data.process_crash_count(); + out->jpeg_decode_accelerator_supported = + data.jpeg_decode_accelerator_supported(); + + return data.ReadInitializationTime(&out->initialization_time) && + data.ReadDisplayLinkVersion(&out->display_link_version) && + data.ReadGpu(&out->gpu) && + data.ReadSecondaryGpus(&out->secondary_gpus) && + data.ReadDriverVendor(&out->driver_vendor) && + data.ReadDriverVersion(&out->driver_version) && + data.ReadDriverDate(&out->driver_date) && + data.ReadPixelShaderVersion(&out->pixel_shader_version) && + data.ReadVertexShaderVersion(&out->vertex_shader_version) && + data.ReadMaxMsaaSamples(&out->max_msaa_samples) && + data.ReadMachineModelName(&out->machine_model_name) && + data.ReadMachineModelVersion(&out->machine_model_version) && + data.ReadGlVersion(&out->gl_version) && + data.ReadGlVendor(&out->gl_vendor) && + data.ReadGlRenderer(&out->gl_renderer) && + data.ReadGlExtensions(&out->gl_extensions) && + data.ReadGlWsVendor(&out->gl_ws_vendor) && + data.ReadGlWsVersion(&out->gl_ws_version) && + data.ReadGlWsExtensions(&out->gl_ws_extensions) && + data.ReadBasicInfoState(&out->basic_info_state) && + data.ReadContextInfoState(&out->context_info_state) && +#if defined(OS_WIN) + data.ReadDxDiagnosticsInfoState(&out->dx_diagnostics_info_state) && + data.ReadDxDiagnostics(&out->dx_diagnostics) && +#endif + data.ReadVideoDecodeAcceleratorCapabilities( + &out->video_decode_accelerator_capabilities) && + data.ReadVideoEncodeAcceleratorSupportedProfiles( + &out->video_encode_accelerator_supported_profiles); +} + } // namespace mojo
diff --git a/gpu/ipc/common/gpu_info_struct_traits.h b/gpu/ipc/common/gpu_info_struct_traits.h index 1dedef1..a57e7762 100644 --- a/gpu/ipc/common/gpu_info_struct_traits.h +++ b/gpu/ipc/common/gpu_info_struct_traits.h
@@ -5,8 +5,11 @@ #ifndef CC_IPC_GPU_STRUCT_TRAITS_H_ #define CC_IPC_GPU_STRUCT_TRAITS_H_ +#include "base/time/time.h" #include "gpu/config/gpu_info.h" +#include "gpu/ipc/common/dx_diag_node_struct_traits.h" #include "gpu/ipc/common/gpu_info.mojom.h" +#include "mojo/common/common_custom_types_struct_traits.h" #include "ui/gfx/geometry/mojo/geometry_struct_traits.h" namespace mojo { @@ -123,5 +126,169 @@ } }; +template <> +struct StructTraits<gpu::mojom::GpuInfo, gpu::GPUInfo> { + static bool Read(gpu::mojom::GpuInfoDataView data, gpu::GPUInfo* out); + + static base::TimeDelta initialization_time(const gpu::GPUInfo& input) { + return input.initialization_time; + } + + static bool optimus(const gpu::GPUInfo& input) { return input.optimus; } + + static bool amd_switchable(const gpu::GPUInfo& input) { + return input.amd_switchable; + } + + static bool lenovo_dcute(const gpu::GPUInfo& input) { + return input.lenovo_dcute; + } + + static const base::Version& display_link_version(const gpu::GPUInfo& input) { + return input.display_link_version; + } + + static const gpu::GPUInfo::GPUDevice& gpu(const gpu::GPUInfo& input) { + return input.gpu; + } + + static const std::vector<gpu::GPUInfo::GPUDevice>& secondary_gpus( + const gpu::GPUInfo& input) { + return input.secondary_gpus; + } + + static uint64_t adapter_luid(const gpu::GPUInfo& input) { + return input.adapter_luid; + } + + static const std::string& driver_vendor(const gpu::GPUInfo& input) { + return input.driver_vendor; + } + + static const std::string& driver_version(const gpu::GPUInfo& input) { + return input.driver_version; + } + + static const std::string& driver_date(const gpu::GPUInfo& input) { + return input.driver_date; + } + + static const std::string& pixel_shader_version(const gpu::GPUInfo& input) { + return input.pixel_shader_version; + } + + static const std::string& vertex_shader_version(const gpu::GPUInfo& input) { + return input.vertex_shader_version; + } + + static const std::string& max_msaa_samples(const gpu::GPUInfo& input) { + return input.max_msaa_samples; + } + + static const std::string& machine_model_name(const gpu::GPUInfo& input) { + return input.machine_model_name; + } + + static const std::string& machine_model_version(const gpu::GPUInfo& input) { + return input.machine_model_version; + } + + static const std::string& gl_version(const gpu::GPUInfo& input) { + return input.gl_version; + } + + static const std::string& gl_vendor(const gpu::GPUInfo& input) { + return input.gl_vendor; + } + + static const std::string& gl_renderer(const gpu::GPUInfo& input) { + return input.gl_renderer; + } + + static const std::string& gl_extensions(const gpu::GPUInfo& input) { + return input.gl_extensions; + } + + static const std::string& gl_ws_vendor(const gpu::GPUInfo& input) { + return input.gl_ws_vendor; + } + + static const std::string& gl_ws_version(const gpu::GPUInfo& input) { + return input.gl_ws_version; + } + + static const std::string& gl_ws_extensions(const gpu::GPUInfo& input) { + return input.gl_ws_extensions; + } + + static uint32_t gl_reset_notification_strategy(const gpu::GPUInfo& input) { + return input.gl_reset_notification_strategy; + } + + static bool can_lose_context(const gpu::GPUInfo& input) { + return input.can_lose_context; + } + + static bool software_rendering(const gpu::GPUInfo& input) { + return input.software_rendering; + } + + static bool direct_rendering(const gpu::GPUInfo& input) { + return input.direct_rendering; + } + + static bool sandboxed(const gpu::GPUInfo& input) { return input.sandboxed; } + + static int process_crash_count(const gpu::GPUInfo& input) { + return input.process_crash_count; + } + + static bool in_process_gpu(const gpu::GPUInfo& input) { + return input.in_process_gpu; + } + + static gpu::CollectInfoResult basic_info_state(const gpu::GPUInfo& input) { + return input.basic_info_state; + } + + static gpu::CollectInfoResult context_info_state(const gpu::GPUInfo& input) { + return input.context_info_state; + } +#if defined(OS_WIN) + static const gpu::DxDiagNode& dx_diagnostics(const gpu::GPUInfo& input) { + return input.dx_diagnostics; + } +#else + static const base::Optional<gpu::DxDiagNode>& dx_diagnostics( + const gpu::GPUInfo& input) { + static const base::Optional<gpu::DxDiagNode> dx_diag_node(base::nullopt); + return dx_diag_node; + } +#endif + + static gpu::CollectInfoResult dx_diagnostics_info_state( + const gpu::GPUInfo& input) { +#if defined(OS_WIN) + return input.dx_diagnostics_info_state; +#else + return gpu::CollectInfoResult::kCollectInfoNone; +#endif + } + + static const gpu::VideoDecodeAcceleratorCapabilities& + video_decode_accelerator_capabilities(const gpu::GPUInfo& input) { + return input.video_decode_accelerator_capabilities; + } + + static std::vector<gpu::VideoEncodeAcceleratorSupportedProfile> + video_encode_accelerator_supported_profiles(const gpu::GPUInfo& input) { + return input.video_encode_accelerator_supported_profiles; + } + + static bool jpeg_decode_accelerator_supported(const gpu::GPUInfo& input) { + return input.jpeg_decode_accelerator_supported; + } +}; + } // namespace mojo #endif // CC_IPC_GPU_STRUCT_TRAITS_H_
diff --git a/gpu/ipc/common/struct_traits_unittest.cc b/gpu/ipc/common/struct_traits_unittest.cc index b25ce4eb1..45f4ba9c 100644 --- a/gpu/ipc/common/struct_traits_unittest.cc +++ b/gpu/ipc/common/struct_traits_unittest.cc
@@ -34,6 +34,11 @@ callback.Run(g); } + void EchoGpuInfo(const GPUInfo& g, + const EchoGpuInfoCallback& callback) override { + callback.Run(g); + } + void EchoMailbox(const Mailbox& m, const EchoMailboxCallback& callback) override { callback.Run(m); @@ -113,6 +118,169 @@ EXPECT_TRUE(device_string.compare(output.device_string) == 0); } +TEST_F(StructTraitsTest, GpuInfo) { + const base::TimeDelta initialization_time = base::TimeDelta::Max(); + const bool optimus = true; + const bool amd_switchable = true; + const bool lenovo_dcute = true; + const base::Version display_link_version("1.2.3.4"); + const gpu::GPUInfo::GPUDevice gpu; + const std::vector<gpu::GPUInfo::GPUDevice> secondary_gpus; + const uint64_t adapter_luid = 0x10de; + const std::string driver_vendor = "driver_vendor"; + const std::string driver_version = "driver_version"; + const std::string driver_date = "driver_date"; + const std::string pixel_shader_version = "pixel_shader_version"; + const std::string vertex_shader_version = "vertex_shader_version"; + const std::string max_msaa_samples = "max_msaa_samples"; + const std::string machine_model_name = "machine_model_name"; + const std::string machine_model_version = "machine_model_version"; + const std::string gl_version = "gl_version"; + const std::string gl_vendor = "gl_vendor"; + const std::string gl_renderer = "gl_renderer"; + const std::string gl_extensions = "gl_extension"; + const std::string gl_ws_vendor = "gl_ws_vendor"; + const std::string gl_ws_version = "gl_ws_version"; + const std::string gl_ws_extensions = "gl_ws_extensions"; + const uint32_t gl_reset_notification_strategy = 0xbeef; + const bool can_lose_context = true; + const bool software_rendering = true; + const bool direct_rendering = true; + const bool sandboxed = true; + const int process_crash_count = 0xdead; + const bool in_process_gpu = true; + const gpu::CollectInfoResult basic_info_state = + gpu::CollectInfoResult::kCollectInfoSuccess; + const gpu::CollectInfoResult context_info_state = + gpu::CollectInfoResult::kCollectInfoSuccess; +#if defined(OS_WIN) + const gpu::CollectInfoResult dx_diagnostics_info_state = + gpu::CollectInfoResult::kCollectInfoSuccess; + const DxDiagNode dx_diagnostics; +#endif + const gpu::VideoDecodeAcceleratorCapabilities + video_decode_accelerator_capabilities; + const std::vector<gpu::VideoEncodeAcceleratorSupportedProfile> + video_encode_accelerator_supported_profiles; + const bool jpeg_decode_accelerator_supported = true; + + gpu::GPUInfo input; + input.initialization_time = initialization_time; + input.optimus = optimus; + input.amd_switchable = amd_switchable; + input.lenovo_dcute = lenovo_dcute; + input.display_link_version = display_link_version; + input.gpu = gpu; + input.secondary_gpus = secondary_gpus; + input.adapter_luid = adapter_luid; + input.driver_vendor = driver_vendor; + input.driver_version = driver_version; + input.driver_date = driver_date; + input.pixel_shader_version = pixel_shader_version; + input.vertex_shader_version = vertex_shader_version; + input.max_msaa_samples = max_msaa_samples; + input.machine_model_name = machine_model_name; + input.machine_model_version = machine_model_version; + input.gl_version = gl_version; + input.gl_vendor = gl_vendor; + input.gl_renderer = gl_renderer; + input.gl_extensions = gl_extensions; + input.gl_ws_vendor = gl_ws_vendor; + input.gl_ws_version = gl_ws_version; + input.gl_ws_extensions = gl_ws_extensions; + input.gl_reset_notification_strategy = gl_reset_notification_strategy; + input.can_lose_context = can_lose_context; + input.software_rendering = software_rendering; + input.direct_rendering = direct_rendering; + input.sandboxed = sandboxed; + input.process_crash_count = process_crash_count; + input.in_process_gpu = in_process_gpu; + input.basic_info_state = basic_info_state; + input.context_info_state = context_info_state; +#if defined(OS_WIN) + input.dx_diagnostics_info_state = dx_diagnostics_info_state; + input.dx_diagnostics = dx_diagnostics; +#endif + input.video_decode_accelerator_capabilities = + video_decode_accelerator_capabilities; + input.video_encode_accelerator_supported_profiles = + video_encode_accelerator_supported_profiles; + input.jpeg_decode_accelerator_supported = jpeg_decode_accelerator_supported; + + mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy(); + gpu::GPUInfo output; + proxy->EchoGpuInfo(input, &output); + + EXPECT_EQ(optimus, output.optimus); + EXPECT_EQ(amd_switchable, output.amd_switchable); + EXPECT_EQ(lenovo_dcute, output.lenovo_dcute); + EXPECT_TRUE(display_link_version.CompareTo(output.display_link_version) == 0); + EXPECT_EQ(gpu.vendor_id, output.gpu.vendor_id); + EXPECT_EQ(gpu.device_id, output.gpu.device_id); + EXPECT_EQ(gpu.active, output.gpu.active); + EXPECT_EQ(gpu.vendor_string, output.gpu.vendor_string); + EXPECT_EQ(gpu.device_string, output.gpu.device_string); + EXPECT_EQ(secondary_gpus.size(), output.secondary_gpus.size()); + for (size_t i = 0; i < secondary_gpus.size(); ++i) { + const gpu::GPUInfo::GPUDevice& expected_gpu = secondary_gpus[i]; + const gpu::GPUInfo::GPUDevice& actual_gpu = output.secondary_gpus[i]; + EXPECT_EQ(expected_gpu.vendor_id, actual_gpu.vendor_id); + EXPECT_EQ(expected_gpu.device_id, actual_gpu.device_id); + EXPECT_EQ(expected_gpu.active, actual_gpu.active); + EXPECT_EQ(expected_gpu.vendor_string, actual_gpu.vendor_string); + EXPECT_EQ(expected_gpu.device_string, actual_gpu.device_string); + } + EXPECT_EQ(adapter_luid, output.adapter_luid); + EXPECT_EQ(driver_vendor, output.driver_vendor); + EXPECT_EQ(driver_version, output.driver_version); + EXPECT_EQ(driver_date, output.driver_date); + EXPECT_EQ(pixel_shader_version, output.pixel_shader_version); + EXPECT_EQ(vertex_shader_version, output.vertex_shader_version); + EXPECT_EQ(max_msaa_samples, output.max_msaa_samples); + EXPECT_EQ(machine_model_name, output.machine_model_name); + EXPECT_EQ(machine_model_version, output.machine_model_version); + EXPECT_EQ(gl_version, output.gl_version); + EXPECT_EQ(gl_vendor, output.gl_vendor); + EXPECT_EQ(gl_renderer, output.gl_renderer); + EXPECT_EQ(gl_extensions, output.gl_extensions); + EXPECT_EQ(gl_ws_vendor, output.gl_ws_vendor); + EXPECT_EQ(gl_ws_version, output.gl_ws_version); + EXPECT_EQ(gl_ws_extensions, output.gl_ws_extensions); + EXPECT_EQ(gl_reset_notification_strategy, + output.gl_reset_notification_strategy); + EXPECT_EQ(can_lose_context, output.can_lose_context); + EXPECT_EQ(software_rendering, output.software_rendering); + EXPECT_EQ(direct_rendering, output.direct_rendering); + EXPECT_EQ(sandboxed, output.sandboxed); + EXPECT_EQ(process_crash_count, output.process_crash_count); + EXPECT_EQ(in_process_gpu, output.in_process_gpu); + EXPECT_EQ(basic_info_state, output.basic_info_state); + EXPECT_EQ(context_info_state, output.context_info_state); +#if defined(OS_WIN) + EXPECT_EQ(output.dx_diagnostics_info_state, dx_diagnostics_info_state); + EXPECT_EQ(dx_diagnostics.values, output.dx_diagnostics.values); +#endif + EXPECT_EQ(output.video_decode_accelerator_capabilities.flags, + video_decode_accelerator_capabilities.flags); + EXPECT_EQ( + video_decode_accelerator_capabilities.supported_profiles.size(), + output.video_decode_accelerator_capabilities.supported_profiles.size()); + for (size_t i = 0; + i < video_decode_accelerator_capabilities.supported_profiles.size(); + ++i) { + const gpu::VideoDecodeAcceleratorSupportedProfile& expected = + video_decode_accelerator_capabilities.supported_profiles[i]; + const gpu::VideoDecodeAcceleratorSupportedProfile& actual = + output.video_decode_accelerator_capabilities.supported_profiles[i]; + EXPECT_EQ(expected.encrypted_only, actual.encrypted_only); + } + EXPECT_EQ( + output.video_decode_accelerator_capabilities.supported_profiles.size(), + video_decode_accelerator_capabilities.supported_profiles.size()); + EXPECT_EQ(output.video_encode_accelerator_supported_profiles.size(), + video_encode_accelerator_supported_profiles.size()); +} + TEST_F(StructTraitsTest, Mailbox) { const int8_t mailbox_name[GL_MAILBOX_SIZE_CHROMIUM] = { 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 9, 7, 5, 3, 1, 2, 4, 6, 8, 0, 0, 9,
diff --git a/gpu/ipc/common/traits_test_service.mojom b/gpu/ipc/common/traits_test_service.mojom index 94b80ae..bd7a961 100644 --- a/gpu/ipc/common/traits_test_service.mojom +++ b/gpu/ipc/common/traits_test_service.mojom
@@ -21,6 +21,9 @@ EchoGpuDevice(GpuDevice g) => (GpuDevice pass); [Sync] + EchoGpuInfo(GpuInfo g) => (GpuInfo pass); + + [Sync] EchoMailbox(Mailbox m) => (Mailbox pass); [Sync]
diff --git a/ios/build/bots/chromium.mac/ios-simulator-swarming.json b/ios/build/bots/chromium.mac/ios-simulator-swarming.json index 4297caa..56f9121 100644 --- a/ios/build/bots/chromium.mac/ios-simulator-swarming.json +++ b/ios/build/bots/chromium.mac/ios-simulator-swarming.json
@@ -8,7 +8,7 @@ "Tests run on iPhone 5s (64-bit) and iPad Retina (32-bit).", "Build is performed with gn+ninja." ], - "xcode version": "7.3", + "xcode version": "7.0", "GYP_DEFINES": [ "OS=ios", "chromium_ios_signing=0", @@ -31,19 +31,17 @@ "compiler": "ninja", "additional_compile_targets": ["gn_all"], "configuration": "Debug", - "sdk": "iphonesimulator9.3", + "sdk": "iphonesimulator9.0", "tests": [ { "include": "common_tests.json", "device type": "iPhone 5s", - "os": "9.0", - "xcode version": "7.0" + "os": "9.0" }, { "include": "common_tests.json", "device type": "iPad Retina", - "os": "9.0", - "xcode version": "7.0" + "os": "9.0" } ] }
diff --git a/ios/chrome/BUILD.gn b/ios/chrome/BUILD.gn index e8897bbd..6f8dcdaf 100644 --- a/ios/chrome/BUILD.gn +++ b/ios/chrome/BUILD.gn
@@ -60,6 +60,7 @@ "browser/reading_list/reading_list_entry_unittest.cc", "browser/reading_list/reading_list_model_storage_unittest.mm", "browser/reading_list/reading_list_model_unittest.cc", + "browser/reading_list/url_downloader_unittest.cc", "browser/signin/chrome_identity_service_observer_bridge_unittest.mm", "browser/signin/gaia_auth_fetcher_ios_unittest.mm", "browser/snapshots/lru_cache_unittest.mm", @@ -105,7 +106,7 @@ "//components/signin/core/browser:test_support", "//components/signin/ios/browser:test_support", "//components/ssl_config:ssl_config", - "//components/sync_driver:test_support", + "//components/sync:test_support_sync_driver", "//components/syncable_prefs:test_support", "//components/update_client", "//components/version_info",
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn index a7bc329c..ed49052 100644 --- a/ios/chrome/browser/BUILD.gn +++ b/ios/chrome/browser/BUILD.gn
@@ -354,8 +354,6 @@ "reading_list/url_downloader.h", "root_coordinator.h", "root_coordinator.mm", - "search/search_util.h", - "search/search_util.mm", "search_engines/search_engines_util.cc", "search_engines/search_engines_util.h", "search_engines/template_url_service_client_impl.cc", @@ -674,7 +672,6 @@ "//components/strings", "//components/suggestions", "//components/sync", - "//components/sync_driver", "//components/sync_sessions", "//components/syncable_prefs", "//components/translate/core/browser", @@ -764,7 +761,7 @@ "//components/flags_ui", "//components/flags_ui:switches", "//components/strings", - "//components/sync_driver", + "//components/sync", "//components/variations", "//google_apis", "//ios/chrome/app/strings", @@ -837,8 +834,7 @@ "//components/signin/ios/browser", "//components/signin/ios/browser:test_support", "//components/sync", - "//components/sync_driver", - "//components/sync_driver:test_support", + "//components/sync:test_support_sync_driver", "//components/syncable_prefs", "//components/syncable_prefs:test_support", "//components/user_prefs",
diff --git a/ios/chrome/browser/DEPS b/ios/chrome/browser/DEPS index 94dab69..471301ae 100644 --- a/ios/chrome/browser/DEPS +++ b/ios/chrome/browser/DEPS
@@ -62,7 +62,6 @@ "+components/ssl_config", "+components/suggestions", "+components/sync", - "+components/sync_driver", "+components/sync_sessions", "+components/syncable_prefs", "+components/translate/core",
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm index a04fae1..c5f8b35ee4 100644 --- a/ios/chrome/browser/about_flags.mm +++ b/ios/chrome/browser/about_flags.mm
@@ -25,7 +25,7 @@ #include "components/flags_ui/flags_storage.h" #include "components/flags_ui/flags_ui_switches.h" #include "components/strings/grit/components_strings.h" -#include "components/sync_driver/sync_driver_switches.h" +#include "components/sync/driver/sync_driver_switches.h" #include "google_apis/gaia/gaia_switches.h" #include "ios/chrome/browser/chrome_switches.h" #include "ios/chrome/grit/ios_strings.h" @@ -195,6 +195,15 @@ command_line->AppendSwitch(switches::kEnableQRScanner); } + // Populate command line flag for the Payment Request API. + NSString* enable_payment_request = + [defaults stringForKey:@"EnablePaymentRequest"]; + if ([enable_payment_request isEqualToString:@"Enabled"]) { + command_line->AppendSwitch(switches::kEnablePaymentRequest); + } else if ([enable_payment_request isEqualToString:@"Disabled"]) { + command_line->AppendSwitch(switches::kDisablePaymentRequest); + } + // Freeform commandline flags. These are added last, so that any flags added // earlier in this function take precedence. if ([defaults boolForKey:@"EnableFreeformCommandLineFlags"]) {
diff --git a/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.cc b/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.cc index ba5a6c16..39450e49 100644 --- a/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.cc +++ b/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.cc
@@ -10,7 +10,7 @@ #include "components/keyed_service/core/service_access_type.h" #include "components/omnibox/browser/autocomplete_classifier.h" #include "components/prefs/pref_service.h" -#include "components/sync_driver/sync_service_utils.h" +#include "components/sync/driver/sync_service_utils.h" #include "ios/chrome/browser/autocomplete/autocomplete_classifier_factory.h" #include "ios/chrome/browser/autocomplete/in_memory_url_index_factory.h" #include "ios/chrome/browser/autocomplete/shortcuts_backend_factory.h"
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state_io_data.cc b/ios/chrome/browser/browser_state/chrome_browser_state_io_data.cc index 364f76d..b79b2b05 100644 --- a/ios/chrome/browser/browser_state/chrome_browser_state_io_data.cc +++ b/ios/chrome/browser/browser_state/chrome_browser_state_io_data.cc
@@ -32,7 +32,7 @@ #include "components/net_log/chrome_net_log.h" #include "components/prefs/pref_service.h" #include "components/signin/core/common/signin_pref_names.h" -#include "components/sync_driver/pref_names.h" +#include "components/sync/driver/pref_names.h" #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/chrome_url_constants.h" @@ -268,7 +268,7 @@ const base::FilePath& partition_path) const { DCHECK(initialized_); AppRequestContext* context = nullptr; - if (ContainsKey(app_request_context_map_, partition_path)) { + if (base::ContainsKey(app_request_context_map_, partition_path)) { context = app_request_context_map_[partition_path]; } else { context = AcquireIsolatedAppRequestContext(main_context); @@ -281,7 +281,7 @@ void ChromeBrowserStateIOData::SetCookieStoreForPartitionPath( std::unique_ptr<net::CookieStore> cookie_store, const base::FilePath& partition_path) { - DCHECK(ContainsKey(app_request_context_map_, partition_path)); + DCHECK(base::ContainsKey(app_request_context_map_, partition_path)); app_request_context_map_[partition_path]->SetCookieStore( std::move(cookie_store)); }
diff --git a/ios/chrome/browser/chrome_switches.cc b/ios/chrome/browser/chrome_switches.cc index 049376e..0de8a2b0 100644 --- a/ios/chrome/browser/chrome_switches.cc +++ b/ios/chrome/browser/chrome_switches.cc
@@ -40,6 +40,9 @@ // Disable auto-reload of error pages if offline. const char kDisableOfflineAutoReload[] = "disable-offline-auto-reload"; +// Disable the Payment Request API. +const char kDisablePaymentRequest[] = "disable-payment-request"; + // Disables the tab switcher. const char kDisableTabSwitcher[] = "disable-tab-switcher"; @@ -77,6 +80,9 @@ // Enable auto-reload of error pages if offline. const char kEnableOfflineAutoReload[] = "enable-offline-auto-reload"; +// Enable the Payment Request API. +const char kEnablePaymentRequest[] = "enable-payment-request"; + // Enables the QR Code scanner. const char kEnableQRScanner[] = "enable-qr-scanner";
diff --git a/ios/chrome/browser/chrome_switches.h b/ios/chrome/browser/chrome_switches.h index 00d2fb4f..ae0eb87c 100644 --- a/ios/chrome/browser/chrome_switches.h +++ b/ios/chrome/browser/chrome_switches.h
@@ -18,6 +18,7 @@ extern const char kDisableLRUSnapshotCache[]; extern const char kDisableNTPFavicons[]; extern const char kDisableOfflineAutoReload[]; +extern const char kDisablePaymentRequest[]; extern const char kDisableTabSwitcher[]; extern const char kDisableIOSPhysicalWeb[]; @@ -31,6 +32,7 @@ extern const char kEnableLRUSnapshotCache[]; extern const char kEnableNTPFavicons[]; extern const char kEnableOfflineAutoReload[]; +extern const char kEnablePaymentRequest[]; extern const char kEnableQRScanner[]; extern const char kEnableReaderModeToolbarIcon[]; extern const char kEnableTabSwitcher[];
diff --git a/ios/chrome/browser/dom_distiller/distiller_viewer.cc b/ios/chrome/browser/dom_distiller/distiller_viewer.cc index f083738d..1433246 100644 --- a/ios/chrome/browser/dom_distiller/distiller_viewer.cc +++ b/ios/chrome/browser/dom_distiller/distiller_viewer.cc
@@ -22,7 +22,7 @@ PrefService* prefs, const GURL& url, const DistillationFinishedCallback& callback) - : DomDistillerRequestViewBase(new DistilledPagePrefs(prefs)), + : DistillerViewerInterface(distillerService, prefs), url_(url), callback_(callback) { DCHECK(distillerService); @@ -34,8 +34,7 @@ TakeViewerHandle(std::move(viewer_handle)); } -DistillerViewer::~DistillerViewer() { -} +DistillerViewer::~DistillerViewer() {} void DistillerViewer::OnArticleReady( const dom_distiller::DistilledArticleProto* article_proto) {
diff --git a/ios/chrome/browser/dom_distiller/distiller_viewer.h b/ios/chrome/browser/dom_distiller/distiller_viewer.h index 411adac..4442493 100644 --- a/ios/chrome/browser/dom_distiller/distiller_viewer.h +++ b/ios/chrome/browser/dom_distiller/distiller_viewer.h
@@ -18,10 +18,10 @@ class DistilledPagePrefs; -// A very simple and naive implementation of the dom_distiller -// ViewRequestDelegate: From an URL it builds an HTML string and notifies when -// finished. -class DistillerViewer : public DomDistillerRequestViewBase { +// An interface for a dom_distiller ViewRequestDelegate that distills a URL and +// calls the given callback with the distilled HTML string and the images it +// contains. +class DistillerViewerInterface : public DomDistillerRequestViewBase { public: typedef struct { // The url of the image. @@ -34,6 +34,22 @@ const std::vector<ImageInfo>& images)> DistillationFinishedCallback; + DistillerViewerInterface(dom_distiller::DomDistillerService* distillerService, + PrefService* prefs) + : DomDistillerRequestViewBase(new DistilledPagePrefs(prefs)) {} + ~DistillerViewerInterface() override {} + + void OnArticleReady( + const dom_distiller::DistilledArticleProto* article_proto) override = 0; + + void SendJavaScript(const std::string& buffer) override = 0; + + DISALLOW_COPY_AND_ASSIGN(DistillerViewerInterface); +}; + +// A very simple and naive implementation of the DistillerViewer. +class DistillerViewer : public DistillerViewerInterface { + public: DistillerViewer(dom_distiller::DomDistillerService* distillerService, PrefService* prefs, const GURL& url,
diff --git a/ios/chrome/browser/experimental_flags.h b/ios/chrome/browser/experimental_flags.h index e0ae81e..6ea3751 100644 --- a/ios/chrome/browser/experimental_flags.h +++ b/ios/chrome/browser/experimental_flags.h
@@ -49,6 +49,9 @@ // Whether the Clear Browsing Data counters and time selection UI is enabled. bool IsNewClearBrowsingDataUIEnabled(); +// Whether the Payment Request API is enabled or not. +bool IsPaymentRequestEnabled(); + } // namespace experimental_flags #endif // IOS_CHROME_BROWSER_EXPERIMENTAL_FLAGS_H_
diff --git a/ios/chrome/browser/experimental_flags.mm b/ios/chrome/browser/experimental_flags.mm index df980e9f..db9d7ba9 100644 --- a/ios/chrome/browser/experimental_flags.mm +++ b/ios/chrome/browser/experimental_flags.mm
@@ -27,7 +27,7 @@ NSString* const kHeuristicsForPasswordGeneration = @"HeuristicsForPasswordGeneration"; NSString* const kEnableReadingList = @"EnableReadingList"; -NSString* const kUpdatePasswordUIEnabled = @"UpdatePasswordUIEnabled"; +NSString* const kUpdatePasswordUIDisabled = @"UpdatePasswordUIDisabled"; NSString* const kEnableQRCodeReader = @"EnableQRCodeReader"; NSString* const kEnableNewClearBrowsingDataUI = @"EnableNewClearBrowsingDataUI"; } // namespace @@ -140,8 +140,8 @@ } bool IsUpdatePasswordUIEnabled() { - return [[NSUserDefaults standardUserDefaults] - boolForKey:kUpdatePasswordUIEnabled]; + return ![[NSUserDefaults standardUserDefaults] + boolForKey:kUpdatePasswordUIDisabled]; } bool IsQRCodeReaderEnabled() { @@ -162,4 +162,23 @@ return false; } +bool IsPaymentRequestEnabled() { + // This call activates the field trial, if needed, so it must come before any + // early returns. + std::string group_name = + base::FieldTrialList::FindFullName("IOSPaymentRequest"); + + // Check if the experimental flag is forced on or off. + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + if (command_line->HasSwitch(switches::kEnablePaymentRequest)) { + return true; + } else if (command_line->HasSwitch(switches::kDisablePaymentRequest)) { + return false; + } + + // Check if the Finch experiment is turned on. + return base::StartsWith(group_name, "Enabled", + base::CompareCase::INSENSITIVE_ASCII); +} + } // namespace experimental_flags
diff --git a/ios/chrome/browser/history/web_history_service_factory.cc b/ios/chrome/browser/history/web_history_service_factory.cc index 9436a2cb..6525d59 100644 --- a/ios/chrome/browser/history/web_history_service_factory.cc +++ b/ios/chrome/browser/history/web_history_service_factory.cc
@@ -12,7 +12,7 @@ #include "components/prefs/pref_service.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_manager.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_service.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/signin/oauth2_token_service_factory.h" #include "ios/chrome/browser/signin/signin_manager_factory.h"
diff --git a/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.cc b/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.cc index 6e51b06..94d9ead 100644 --- a/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.cc +++ b/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.cc
@@ -39,7 +39,7 @@ #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" #include "components/signin/core/browser/signin_status_metrics_provider.h" -#include "components/sync_driver/device_count_metrics_provider.h" +#include "components/sync/driver/device_count_metrics_provider.h" #include "components/variations/variations_associated_data.h" #include "components/version_info/version_info.h" #include "ios/chrome/browser/application_context.h"
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_manager_setting_migrator_service_factory.cc b/ios/chrome/browser/passwords/ios_chrome_password_manager_setting_migrator_service_factory.cc index 928cb3e..479f56bd 100644 --- a/ios/chrome/browser/passwords/ios_chrome_password_manager_setting_migrator_service_factory.cc +++ b/ios/chrome/browser/passwords/ios_chrome_password_manager_setting_migrator_service_factory.cc
@@ -8,7 +8,7 @@ #include "base/memory/singleton.h" #include "components/keyed_service/ios/browser_state_dependency_manager.h" #include "components/password_manager/sync/browser/password_manager_setting_migrator_service.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_service.h" #include "ios/chrome/browser/browser_state/browser_state_otr_helper.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
diff --git a/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc b/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc index e2c3ff68..9b46669 100644 --- a/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc +++ b/ios/chrome/browser/passwords/ios_chrome_password_store_factory.cc
@@ -18,7 +18,7 @@ #include "components/password_manager/core/browser/login_database.h" #include "components/password_manager/core/browser/password_store_default.h" #include "components/password_manager/core/browser/password_store_factory_util.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_service.h" #include "ios/chrome/browser/browser_state/browser_state_otr_helper.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/sync/glue/sync_start_util.h"
diff --git a/ios/chrome/browser/passwords/js_password_manager.mm b/ios/chrome/browser/passwords/js_password_manager.mm index d28205b6..afeb41f 100644 --- a/ios/chrome/browser/passwords/js_password_manager.mm +++ b/ios/chrome/browser/passwords/js_password_manager.mm
@@ -96,7 +96,6 @@ - (void)evaluateExtraScript:(NSString*)script completionHandler:(void (^)(NSString*))completionHandler { DCHECK(completionHandler); - [self injectDependenciesIfMissing]; NSString* JS = [[self injectionContent] stringByAppendingString:script]; [self evaluate:JS stringResultHandler:^(NSString* result, NSError*) {
diff --git a/ios/chrome/browser/passwords/password_controller.mm b/ios/chrome/browser/passwords/password_controller.mm index 86660e95..48853b3 100644 --- a/ios/chrome/browser/passwords/password_controller.mm +++ b/ios/chrome/browser/passwords/password_controller.mm
@@ -29,7 +29,7 @@ #include "components/password_manager/core/browser/password_manager.h" #include "components/password_manager/core/browser/password_manager_client.h" #include "components/password_manager/core/browser/password_manager_driver.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_service.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/experimental_flags.h" #include "ios/chrome/browser/infobars/infobar_manager_impl.h"
diff --git a/ios/chrome/browser/prefs/browser_prefs.mm b/ios/chrome/browser/prefs/browser_prefs.mm index f7dbbe71..d07d62b 100644 --- a/ios/chrome/browser/prefs/browser_prefs.mm +++ b/ios/chrome/browser/prefs/browser_prefs.mm
@@ -22,7 +22,7 @@ #include "components/signin/core/common/signin_pref_names.h" #include "components/ssl_config/ssl_config_service_manager.h" #include "components/strings/grit/components_locale_settings.h" -#include "components/sync_driver/sync_prefs.h" +#include "components/sync/driver/sync_prefs.h" #include "components/translate/core/browser/translate_prefs.h" #include "components/translate/core/common/translate_pref_names.h" #include "components/update_client/update_client.h"
diff --git a/ios/chrome/browser/reading_list/OWNERS b/ios/chrome/browser/reading_list/OWNERS index bf1620f..c6815f7 100644 --- a/ios/chrome/browser/reading_list/OWNERS +++ b/ios/chrome/browser/reading_list/OWNERS
@@ -1 +1,2 @@ noyau@chromium.org +olivierrobin@chromium.org
diff --git a/ios/chrome/browser/reading_list/url_downloader.cc b/ios/chrome/browser/reading_list/url_downloader.cc index 2a777a5..e0cc3448 100644 --- a/ios/chrome/browser/reading_list/url_downloader.cc +++ b/ios/chrome/browser/reading_list/url_downloader.cc
@@ -55,7 +55,9 @@ void URLDownloader::RemoveOfflineURL(const GURL& url) { // Remove all download tasks for this url as it would be pointless work. - std::remove(tasks_.begin(), tasks_.end(), std::make_pair(DOWNLOAD, url)); + tasks_.erase( + std::remove(tasks_.begin(), tasks_.end(), std::make_pair(DOWNLOAD, url)), + tasks_.end()); tasks_.push_back(std::make_pair(DELETE, url)); HandleNextTask(); } @@ -112,6 +114,7 @@ DownloadCompletionHandler(url, false); return; } + distiller_.reset(new dom_distiller::DistillerViewer( distiller_service_, pref_service_, url, base::Bind(&URLDownloader::DistillerCallback, base::Unretained(this)))); @@ -120,7 +123,8 @@ void URLDownloader::DistillerCallback( const GURL& pageURL, const std::string& html, - const std::vector<dom_distiller::DistillerViewer::ImageInfo>& images) { + const std::vector<dom_distiller::DistillerViewerInterface::ImageInfo>& + images) { std::vector<dom_distiller::DistillerViewer::ImageInfo> imagesBlock = images; std::string blockHTML = html; task_tracker_.PostTaskAndReplyWithResult( @@ -134,7 +138,7 @@ bool URLDownloader::SaveDistilledHTML( const GURL& url, - std::vector<dom_distiller::DistillerViewer::ImageInfo> images, + std::vector<dom_distiller::DistillerViewerInterface::ImageInfo> images, std::string html) { if (CreateOfflineURLDirectory(url)) { return SaveHTMLForURL(SaveAndReplaceImagesInHTML(url, html, images), url); @@ -179,7 +183,8 @@ std::string URLDownloader::SaveAndReplaceImagesInHTML( const GURL& url, const std::string& html, - const std::vector<dom_distiller::DistillerViewer::ImageInfo>& images) { + const std::vector<dom_distiller::DistillerViewerInterface::ImageInfo>& + images) { std::string mutableHTML = html; for (size_t i = 0; i < images.size(); i++) { const std::string& localImagePath =
diff --git a/ios/chrome/browser/reading_list/url_downloader.h b/ios/chrome/browser/reading_list/url_downloader.h index cdba38ee..2eab2412 100644 --- a/ios/chrome/browser/reading_list/url_downloader.h +++ b/ios/chrome/browser/reading_list/url_downloader.h
@@ -28,6 +28,8 @@ // hashing to create unique file names. When a deletion is requested, all // previous downloads for that URL are cancelled as they would be deleted. class URLDownloader { + friend class MockURLDownloader; + public: // A completion callback that takes a GURL and a bool indicating // success and returns void. @@ -82,21 +84,23 @@ std::string SaveAndReplaceImagesInHTML( const GURL& url, const std::string& html, - const std::vector<dom_distiller::DistillerViewer::ImageInfo>& images); + const std::vector<dom_distiller::DistillerViewerInterface::ImageInfo>& + images); // Saves |html| to disk in the correct location for |url|; returns success. bool SaveHTMLForURL(std::string html, const GURL& url); // Downloads |url|, depending on |offlineURLExists| state. - void DownloadURL(GURL url, bool offlineURLExists); + virtual void DownloadURL(GURL url, bool offlineURLExists); // Saves distilled html to disk, including saving images and main file. bool SaveDistilledHTML( const GURL& url, - std::vector<dom_distiller::DistillerViewer::ImageInfo> images, + std::vector<dom_distiller::DistillerViewerInterface::ImageInfo> images, std::string html); // Callback for distillation completion. void DistillerCallback( const GURL& pageURL, const std::string& html, - const std::vector<dom_distiller::DistillerViewer::ImageInfo>& images); + const std::vector<dom_distiller::DistillerViewerInterface::ImageInfo>& + images); dom_distiller::DomDistillerService* distiller_service_; PrefService* pref_service_; @@ -105,7 +109,7 @@ std::deque<Task> tasks_; bool working_; base::FilePath base_directory_; - std::unique_ptr<dom_distiller::DistillerViewer> distiller_; + std::unique_ptr<dom_distiller::DistillerViewerInterface> distiller_; base::CancelableTaskTracker task_tracker_; DISALLOW_COPY_AND_ASSIGN(URLDownloader);
diff --git a/ios/chrome/browser/reading_list/url_downloader_unittest.cc b/ios/chrome/browser/reading_list/url_downloader_unittest.cc new file mode 100644 index 0000000..14ee119a --- /dev/null +++ b/ios/chrome/browser/reading_list/url_downloader_unittest.cc
@@ -0,0 +1,188 @@ +// Copyright 2016 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 "ios/chrome/browser/reading_list/url_downloader.h" + +#include <vector> + +#include "base/files/file_util.h" +#import "base/mac/bind_objc_block.h" +#include "base/message_loop/message_loop.h" +#include "base/path_service.h" +#include "base/run_loop.h" +#import "base/test/ios/wait_util.h" +#include "ios/chrome/browser/chrome_paths.h" +#include "ios/chrome/browser/dom_distiller/distiller_viewer.h" +#include "ios/web/public/test/test_web_thread_bundle.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +class DistillerViewerTest : public dom_distiller::DistillerViewerInterface { + public: + DistillerViewerTest(const GURL& url, + const DistillationFinishedCallback& callback) + : dom_distiller::DistillerViewerInterface(nil, nil) { + std::vector<ImageInfo> images; + callback.Run(url, "html", images); + } + + void OnArticleReady( + const dom_distiller::DistilledArticleProto* article_proto) override {} + + void SendJavaScript(const std::string& buffer) override {} +}; + +} // namespace + +class MockURLDownloader : public URLDownloader { + public: + MockURLDownloader(base::FilePath path) + : URLDownloader(nil, + nil, + path, + base::Bind(&MockURLDownloader::OnEndDownload, + base::Unretained(this)), + base::Bind(&MockURLDownloader::OnEndRemove, + base::Unretained(this))) {} + + void RemoveOfflineFilesDirectory() { + base::DeleteFile(OfflineDirectoryPath(), true); + } + + void ClearCompletionTrackers() { + downloaded_files_.clear(); + removed_files_.clear(); + } + + bool CheckExistenceOfOfflineURLPagePath(const GURL& url) { + return base::PathExists(OfflineURLPagePath(url)); + } + + void FakeWorking() { working_ = true; } + + void FakeEndWorking() { + working_ = false; + HandleNextTask(); + } + + std::vector<GURL> downloaded_files_; + std::vector<GURL> removed_files_; + + private: + void DownloadURL(GURL url, bool offlineURLExists) override { + if (offlineURLExists) { + DownloadCompletionHandler(url, false); + return; + } + distiller_.reset(new DistillerViewerTest( + url, + base::Bind(&URLDownloader::DistillerCallback, base::Unretained(this)))); + } + + void OnEndDownload(const GURL& url, bool success) { + downloaded_files_.push_back(url); + } + + void OnEndRemove(const GURL& url, bool success) { + removed_files_.push_back(url); + } +}; + +namespace { +class URLDownloaderTest : public testing::Test { + public: + std::unique_ptr<MockURLDownloader> downloader_; + web::TestWebThreadBundle bundle_; + + URLDownloaderTest() { + base::FilePath data_dir; + base::PathService::Get(ios::DIR_USER_DATA, &data_dir); + downloader_.reset(new MockURLDownloader(data_dir)); + } + ~URLDownloaderTest() override {} + + void TearDown() override { + downloader_->RemoveOfflineFilesDirectory(); + downloader_->ClearCompletionTrackers(); + } + + void WaitUntilCondition(ConditionBlock condition) { + base::MessageLoop* messageLoop = base::MessageLoop::current(); + DCHECK(messageLoop); + base::test::ios::WaitUntilCondition(condition, messageLoop, + base::TimeDelta::FromSeconds(1)); + } +}; + +TEST_F(URLDownloaderTest, SingleDownload) { + GURL url = GURL("http://test.com"); + ASSERT_FALSE(downloader_->CheckExistenceOfOfflineURLPagePath(url)); + ASSERT_EQ(0ul, downloader_->downloaded_files_.size()); + ASSERT_EQ(0ul, downloader_->removed_files_.size()); + + downloader_->DownloadOfflineURL(url); + + WaitUntilCondition(^bool { + return std::find(downloader_->downloaded_files_.begin(), + downloader_->downloaded_files_.end(), + url) != downloader_->downloaded_files_.end(); + }); + + ASSERT_TRUE(downloader_->CheckExistenceOfOfflineURLPagePath(url)); +} + +TEST_F(URLDownloaderTest, DownloadAndRemove) { + GURL url = GURL("http://test.com"); + GURL url2 = GURL("http://test2.com"); + ASSERT_FALSE(downloader_->CheckExistenceOfOfflineURLPagePath(url)); + ASSERT_FALSE(downloader_->CheckExistenceOfOfflineURLPagePath(url2)); + ASSERT_EQ(0ul, downloader_->downloaded_files_.size()); + ASSERT_EQ(0ul, downloader_->removed_files_.size()); + downloader_->FakeWorking(); + downloader_->DownloadOfflineURL(url); + downloader_->DownloadOfflineURL(url2); + downloader_->RemoveOfflineURL(url); + downloader_->FakeEndWorking(); + + WaitUntilCondition(^bool { + return std::find(downloader_->removed_files_.begin(), + downloader_->removed_files_.end(), + url) != downloader_->removed_files_.end(); + }); + + ASSERT_TRUE(std::find(downloader_->downloaded_files_.begin(), + downloader_->downloaded_files_.end(), + url) == downloader_->downloaded_files_.end()); + ASSERT_EQ(1ul, downloader_->downloaded_files_.size()); + ASSERT_EQ(1ul, downloader_->removed_files_.size()); + ASSERT_FALSE(downloader_->CheckExistenceOfOfflineURLPagePath(url)); + ASSERT_TRUE(downloader_->CheckExistenceOfOfflineURLPagePath(url2)); +} + +TEST_F(URLDownloaderTest, DownloadAndRemoveAndRedownload) { + GURL url = GURL("http://test.com"); + ASSERT_FALSE(downloader_->CheckExistenceOfOfflineURLPagePath(url)); + downloader_->FakeWorking(); + downloader_->DownloadOfflineURL(url); + downloader_->RemoveOfflineURL(url); + downloader_->DownloadOfflineURL(url); + downloader_->FakeEndWorking(); + + WaitUntilCondition(^bool { + return std::find(downloader_->removed_files_.begin(), + downloader_->removed_files_.end(), + url) != downloader_->removed_files_.end(); + }); + + ASSERT_TRUE(std::find(downloader_->downloaded_files_.begin(), + downloader_->downloaded_files_.end(), + url) != downloader_->downloaded_files_.end()); + ASSERT_TRUE(std::find(downloader_->removed_files_.begin(), + downloader_->removed_files_.end(), + url) != downloader_->removed_files_.end()); + ASSERT_TRUE(downloader_->CheckExistenceOfOfflineURLPagePath(url)); +} + +} // namespace
diff --git a/ios/chrome/browser/search/search_util.h b/ios/chrome/browser/search/search_util.h deleted file mode 100644 index 6cb0b00..0000000 --- a/ios/chrome/browser/search/search_util.h +++ /dev/null
@@ -1,42 +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. - -#ifndef IOS_CHROME_BROWSER_SEARCH_SEARCH_UTIL_H_ -#define IOS_CHROME_BROWSER_SEARCH_SEARCH_UTIL_H_ - -#include "base/strings/string16.h" - -class GURL; - -namespace ios { -class ChromeBrowserState; -} - -namespace web { -class WebState; -} - -// Extracts and returns search terms from |url|. Does not consider -// IsQueryExtractionEnabled() and Instant support state of the page and does -// not check for a privileged process, so most callers should use -// GetSearchTerms() below instead. -base::string16 ExtractSearchTermsFromURL(ios::ChromeBrowserState* browser_state, - const GURL& url); - -// Returns true if it is okay to extract search terms from |url|. |url| must -// have a secure scheme and must contain the search terms replacement key for -// the default search provider. -bool IsQueryExtractionAllowedForURL(ios::ChromeBrowserState* browser_state, - const GURL& url); - -// Returns search terms if this WebState is a search results page. It looks -// in the visible NavigationItem first, to see if search terms have already -// been extracted. Failing that, it tries to extract search terms from the URL. -// -// Returns a blank string if search terms were not found, or if search terms -// extraction is disabled for this WebState or BrowserState, or if |web_state| -// does not support Instant. -base::string16 GetSearchTerms(web::WebState* web_state); - -#endif // IOS_CHROME_BROWSER_SEARCH_SEARCH_UTIL_H_
diff --git a/ios/chrome/browser/search/search_util.mm b/ios/chrome/browser/search/search_util.mm deleted file mode 100644 index 05e659c..0000000 --- a/ios/chrome/browser/search/search_util.mm +++ /dev/null
@@ -1,69 +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. - -#include "ios/chrome/browser/search/search_util.h" - -#include "components/search/search.h" -#include "components/search_engines/template_url_service.h" -#include "ios/chrome/browser/browser_state/chrome_browser_state.h" -#include "ios/chrome/browser/search_engines/template_url_service_factory.h" -#include "ios/chrome/browser/search_engines/ui_thread_search_terms_data.h" -#include "ios/web/public/navigation_item.h" -#import "ios/web/public/navigation_manager.h" -#include "ios/web/public/web_state/web_state.h" -#include "url/gurl.h" - -namespace { - -TemplateURL* GetDefaultSearchProviderTemplateURL( - ios::ChromeBrowserState* browser_state) { - if (!browser_state) - return nullptr; - - TemplateURLService* template_url_service = - ios::TemplateURLServiceFactory::GetForBrowserState(browser_state); - return template_url_service ? template_url_service->GetDefaultSearchProvider() - : nullptr; -} - -} // namespace - -base::string16 ExtractSearchTermsFromURL(ios::ChromeBrowserState* browser_state, - const GURL& url) { - base::string16 search_terms; - TemplateURL* template_url = - GetDefaultSearchProviderTemplateURL(browser_state); - if (template_url) { - template_url->ExtractSearchTermsFromURL( - url, ios::UIThreadSearchTermsData(browser_state), &search_terms); - } - return search_terms; -} - -bool IsQueryExtractionAllowedForURL(ios::ChromeBrowserState* browser_state, - const GURL& url) { - TemplateURL* template_url = - GetDefaultSearchProviderTemplateURL(browser_state); - return template_url && search::IsSuitableURLForInstant(url, template_url); -} - -base::string16 GetSearchTerms(web::WebState* web_state) { - if (!web_state) - return base::string16(); - - web::NavigationItem* item = - web_state->GetNavigationManager()->GetVisibleItem(); - if (!item) - return base::string16(); - - if (!search::IsQueryExtractionEnabled()) - return base::string16(); - - ios::ChromeBrowserState* browser_state = - ios::ChromeBrowserState::FromBrowserState(web_state->GetBrowserState()); - if (!IsQueryExtractionAllowedForURL(browser_state, item->GetVirtualURL())) - return base::string16(); - - return ExtractSearchTermsFromURL(browser_state, item->GetVirtualURL()); -}
diff --git a/ios/chrome/browser/sync/fake_sync_service_factory.cc b/ios/chrome/browser/sync/fake_sync_service_factory.cc index 7e5b0d29..02b4f30 100644 --- a/ios/chrome/browser/sync/fake_sync_service_factory.cc +++ b/ios/chrome/browser/sync/fake_sync_service_factory.cc
@@ -9,7 +9,7 @@ #include "base/memory/singleton.h" #include "components/keyed_service/core/keyed_service.h" #include "components/keyed_service/ios/browser_state_dependency_manager.h" -#include "components/sync_driver/fake_sync_service.h" +#include "components/sync/driver/fake_sync_service.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" namespace {
diff --git a/ios/chrome/browser/sync/glue/sync_start_util.cc b/ios/chrome/browser/sync/glue/sync_start_util.cc index 18bb21e..0030b55 100644 --- a/ios/chrome/browser/sync/glue/sync_start_util.cc +++ b/ios/chrome/browser/sync/glue/sync_start_util.cc
@@ -8,7 +8,7 @@ #include "base/files/file_path.h" #include "base/location.h" #include "components/browser_sync/browser/profile_sync_service.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_service.h" #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/browser_state/chrome_browser_state_manager.h"
diff --git a/ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.cc b/ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.cc index f59e95c4..132d71d 100644 --- a/ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.cc +++ b/ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.cc
@@ -14,9 +14,9 @@ #include "components/network_time/network_time_tracker.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_manager.h" -#include "components/sync_driver/signin_manager_wrapper.h" -#include "components/sync_driver/startup_controller.h" -#include "components/sync_driver/sync_util.h" +#include "components/sync/driver/signin_manager_wrapper.h" +#include "components/sync/driver/startup_controller.h" +#include "components/sync/driver/sync_util.h" #include "ios/chrome/browser/application_context.h" #include "ios/chrome/browser/autofill/personal_data_manager_factory.h" #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h"
diff --git a/ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.cc b/ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.cc index f530e233..3464c69 100644 --- a/ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.cc +++ b/ios/chrome/browser/sync/ios_chrome_profile_sync_test_util.cc
@@ -10,7 +10,7 @@ #include "components/browser_sync/browser/profile_sync_test_util.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/signin/core/browser/signin_manager.h" -#include "components/sync_driver/signin_manager_wrapper.h" +#include "components/sync/driver/signin_manager_wrapper.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/signin/oauth2_token_service_factory.h" #include "ios/chrome/browser/signin/signin_manager_factory.h"
diff --git a/ios/chrome/browser/sync/ios_chrome_sync_client.h b/ios/chrome/browser/sync/ios_chrome_sync_client.h index 2a5fafa9..c57f3ac 100644 --- a/ios/chrome/browser/sync/ios_chrome_sync_client.h +++ b/ios/chrome/browser/sync/ios_chrome_sync_client.h
@@ -10,7 +10,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" -#include "components/sync_driver/sync_client.h" +#include "components/sync/driver/sync_client.h" namespace autofill { class AutofillWebDataService;
diff --git a/ios/chrome/browser/sync/ios_chrome_sync_client.mm b/ios/chrome/browser/sync/ios_chrome_sync_client.mm index 268dbe1..56771f53 100644 --- a/ios/chrome/browser/sync/ios_chrome_sync_client.mm +++ b/ios/chrome/browser/sync/ios_chrome_sync_client.mm
@@ -28,13 +28,13 @@ #include "components/search_engines/search_engine_data_type_controller.h" #include "components/signin/core/browser/profile_oauth2_token_service.h" #include "components/sync/base/extensions_activity.h" +#include "components/sync/driver/glue/browser_thread_model_worker.h" +#include "components/sync/driver/glue/chrome_report_unrecoverable_error.h" +#include "components/sync/driver/glue/ui_model_worker.h" +#include "components/sync/driver/sync_api_component_factory.h" +#include "components/sync/driver/sync_util.h" +#include "components/sync/driver/ui_data_type_controller.h" #include "components/sync/engine/passive_model_worker.h" -#include "components/sync_driver/glue/browser_thread_model_worker.h" -#include "components/sync_driver/glue/chrome_report_unrecoverable_error.h" -#include "components/sync_driver/glue/ui_model_worker.h" -#include "components/sync_driver/sync_api_component_factory.h" -#include "components/sync_driver/sync_util.h" -#include "components/sync_driver/ui_data_type_controller.h" #include "components/sync_sessions/favicon_cache.h" #include "components/sync_sessions/local_session_event_router.h" #include "components/sync_sessions/sync_sessions_client.h"
diff --git a/ios/chrome/browser/sync/sync_observer_bridge.h b/ios/chrome/browser/sync/sync_observer_bridge.h index 00f03ff..80ab7c1b 100644 --- a/ios/chrome/browser/sync/sync_observer_bridge.h +++ b/ios/chrome/browser/sync/sync_observer_bridge.h
@@ -9,7 +9,7 @@ #include "base/ios/weak_nsobject.h" #include "base/macros.h" #include "base/scoped_observer.h" -#include "components/sync_driver/sync_service_observer.h" +#include "components/sync/driver/sync_service_observer.h" namespace sync_driver { class SyncService;
diff --git a/ios/chrome/browser/sync/sync_observer_bridge.mm b/ios/chrome/browser/sync/sync_observer_bridge.mm index 8e6f88350f..8ec52298 100644 --- a/ios/chrome/browser/sync/sync_observer_bridge.mm +++ b/ios/chrome/browser/sync/sync_observer_bridge.mm
@@ -5,7 +5,7 @@ #include "ios/chrome/browser/sync/sync_observer_bridge.h" #include "base/logging.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_service.h" SyncObserverBridge::SyncObserverBridge(id<SyncObserverModelBridge> delegate, sync_driver::SyncService* sync_service)
diff --git a/ios/chrome/browser/sync/sync_setup_service.cc b/ios/chrome/browser/sync/sync_setup_service.cc index 51a2e7e..de123a3 100644 --- a/ios/chrome/browser/sync/sync_setup_service.cc +++ b/ios/chrome/browser/sync/sync_setup_service.cc
@@ -10,9 +10,9 @@ #include "base/metrics/histogram_macros.h" #include "components/prefs/pref_service.h" #include "components/sync/base/stop_source.h" +#include "components/sync/driver/sync_prefs.h" +#include "components/sync/driver/sync_service.h" #include "components/sync/protocol/sync_protocol_error.h" -#include "components/sync_driver/sync_prefs.h" -#include "components/sync_driver/sync_service.h" #include "google_apis/gaia/google_service_auth_error.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/pref_names.h" @@ -22,11 +22,11 @@ // The set of user-selectable datatypes. This must be in the same order as // |SyncSetupService::SyncableDatatype|. syncer::ModelType kDataTypes[] = { - syncer::BOOKMARKS, - syncer::TYPED_URLS, - syncer::PASSWORDS, - syncer::PROXY_TABS, - syncer::AUTOFILL, + syncer::BOOKMARKS, syncer::TYPED_URLS, syncer::PASSWORDS, + syncer::PROXY_TABS, syncer::AUTOFILL, + // TODO(skym): Uncomment once downstream handles this case correctly, + // tracking bug crbug.com/374865. + // syncer::PREFERENCES, }; } // namespace
diff --git a/ios/chrome/browser/sync/sync_setup_service.h b/ios/chrome/browser/sync/sync_setup_service.h index da8b02d..c58a0930 100644 --- a/ios/chrome/browser/sync/sync_setup_service.h +++ b/ios/chrome/browser/sync/sync_setup_service.h
@@ -6,6 +6,7 @@ #define IOS_CHROME_BROWSER_SYNC_SYNC_SETUP_SERVICE_H_ #include <map> +#include <memory> #include "base/macros.h" #include "base/strings/string16.h" @@ -42,7 +43,10 @@ kSyncPasswords, kSyncOpenTabs, kSyncAutofill, - kNumberOfSyncableDatatypes + kNumberOfSyncableDatatypes, + // TODO(skym): This should be moved above kNumberOfSyncableDatatypes after + // downstream handling is in place, tracking bug crbug.com/374865. + kSyncPreferences } SyncableDatatype; SyncSetupService(sync_driver::SyncService* sync_service, PrefService* prefs);
diff --git a/ios/chrome/browser/ui/alert_coordinator/alert_coordinator_unittest.mm b/ios/chrome/browser/ui/alert_coordinator/alert_coordinator_unittest.mm index 43d73fdb..0b7ca78 100644 --- a/ios/chrome/browser/ui/alert_coordinator/alert_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/alert_coordinator/alert_coordinator_unittest.mm
@@ -148,32 +148,6 @@ EXPECT_OCMOCK_VERIFY(alertMock); } -// Tests the alert coordinator dismissal when the object is destroyed. -// TODO(crbug.com/631049): This test is failing on Xcode 8 bot. -TEST_F(AlertCoordinatorTest, DISABLED_ValidateDismissalOnDestroy) { - // Setup. - UIViewController* viewController = getViewController(); - AlertCoordinator* alertCoordinator = getAlertCoordinator(viewController); - - startAlertCoordinator(); - - ASSERT_TRUE(alertCoordinator.isVisible); - ASSERT_NE(nil, viewController.presentedViewController); - ASSERT_TRUE([viewController.presentedViewController - isKindOfClass:[UIAlertController class]]); - - id alertMock = [OCMockObject - partialMockForObject:viewController.presentedViewController]; - [[alertMock expect] dismissViewControllerAnimated:NO completion:nil]; - - // Action. - deleteAlertCoordinator(); - - // Test. - EXPECT_FALSE([alertCoordinator isVisible]); - ASSERT_OCMOCK_VERIFY(alertMock); -} - // Tests that only the expected actions are present on the alert. TEST_F(AlertCoordinatorTest, ValidateActions) { // Setup.
diff --git a/ios/chrome/browser/ui/webui/history/browsing_history_handler.cc b/ios/chrome/browser/ui/webui/history/browsing_history_handler.cc index 19ae493..f422b1824 100644 --- a/ios/chrome/browser/ui/webui/history/browsing_history_handler.cc +++ b/ios/chrome/browser/ui/webui/history/browsing_history_handler.cc
@@ -28,10 +28,10 @@ #include "components/history/core/browser/web_history_service.h" #include "components/keyed_service/core/service_access_type.h" #include "components/strings/grit/components_strings.h" +#include "components/sync/driver/device_info.h" +#include "components/sync/driver/device_info_tracker.h" #include "components/sync/protocol/history_delete_directive_specifics.pb.h" #include "components/sync/protocol/sync_enums.pb.h" -#include "components/sync_driver/device_info.h" -#include "components/sync_driver/device_info_tracker.h" #include "components/url_formatter/url_formatter.h" #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
diff --git a/ios/chrome/browser/ui/webui/history/favicon_source.cc b/ios/chrome/browser/ui/webui/history/favicon_source.cc index f2b915c3..b1571d0 100644 --- a/ios/chrome/browser/ui/webui/history/favicon_source.cc +++ b/ios/chrome/browser/ui/webui/history/favicon_source.cc
@@ -12,7 +12,7 @@ #include "components/favicon_base/favicon_url_parser.h" #include "components/history/core/browser/top_sites.h" #include "components/keyed_service/core/service_access_type.h" -#include "components/sync_driver/sync_service.h" +#include "components/sync/driver/sync_service.h" #include "components/sync_sessions/open_tabs_ui_delegate.h" #include "net/url_request/url_request.h" #include "ui/base/l10n/l10n_util.h"
diff --git a/ios/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc b/ios/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc index 5506d71..4bb201d 100644 --- a/ios/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc +++ b/ios/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc
@@ -10,13 +10,13 @@ #include "components/browser_sync/browser/profile_sync_service.h" #include "components/signin/core/browser/signin_manager.h" #include "components/sync/base/weak_handle.h" +#include "components/sync/driver/about_sync_util.h" +#include "components/sync/driver/sync_service.h" #include "components/sync/engine/events/protocol_event.h" #include "components/sync/js/js_event_details.h" #include "components/sync/sessions/commit_counters.h" #include "components/sync/sessions/status_counters.h" #include "components/sync/sessions/update_counters.h" -#include "components/sync_driver/about_sync_util.h" -#include "components/sync_driver/sync_service.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/signin/signin_manager_factory.h" #include "ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.h"
diff --git a/ios/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.h b/ios/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.h index 78ce92c2..b05351d 100644 --- a/ios/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.h +++ b/ios/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.h
@@ -10,11 +10,11 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "components/sync/driver/protocol_event_observer.h" +#include "components/sync/driver/sync_service_observer.h" #include "components/sync/js/js_controller.h" #include "components/sync/js/js_event_handler.h" #include "components/sync/sessions/type_debug_info_observer.h" -#include "components/sync_driver/protocol_event_observer.h" -#include "components/sync_driver/sync_service_observer.h" #include "ios/web/public/webui/web_ui_ios_message_handler.h" namespace sync_driver {
diff --git a/ios/chrome/browser/ui/webui/sync_internals/sync_internals_ui.cc b/ios/chrome/browser/ui/webui/sync_internals/sync_internals_ui.cc index cf1be20..45b1dff 100644 --- a/ios/chrome/browser/ui/webui/sync_internals/sync_internals_ui.cc +++ b/ios/chrome/browser/ui/webui/sync_internals/sync_internals_ui.cc
@@ -5,7 +5,7 @@ #include "ios/chrome/browser/ui/webui/sync_internals/sync_internals_ui.h" #include "components/grit/components_resources.h" -#include "components/sync_driver/about_sync_util.h" +#include "components/sync/driver/about_sync_util.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/chrome_url_constants.h" #include "ios/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.h"
diff --git a/ios/chrome/ios_chrome.gyp b/ios/chrome/ios_chrome.gyp index 0f738c73..cac5400 100644 --- a/ios/chrome/ios_chrome.gyp +++ b/ios/chrome/ios_chrome.gyp
@@ -105,7 +105,6 @@ '../../components/components.gyp:spellcheck_common', '../../components/components.gyp:ssl_config', '../../components/components.gyp:suggestions', - '../../components/components.gyp:sync_driver', '../../components/components.gyp:syncable_prefs', '../../components/components.gyp:translate_core_browser', '../../components/components.gyp:translate_ios_browser', @@ -483,8 +482,6 @@ 'browser/reading_list/reading_list_model_storage_defaults.mm', 'browser/root_coordinator.h', 'browser/root_coordinator.mm', - 'browser/search/search_util.h', - 'browser/search/search_util.mm', 'browser/search_engines/search_engines_util.cc', 'browser/search_engines/search_engines_util.h', 'browser/search_engines/template_url_service_client_impl.cc', @@ -752,7 +749,7 @@ '../../components/components.gyp:autofill_core_common', '../../components/components.gyp:dom_distiller_core', '../../components/components.gyp:flags_ui', - '../../components/components.gyp:sync_driver', + '../../components/sync.gyp:sync', '../../components/components_strings.gyp:components_strings', '../../google_apis/google_apis.gyp:google_apis', '../web/ios_web.gyp:ios_web',
diff --git a/ios/chrome/ios_chrome_tests.gyp b/ios/chrome/ios_chrome_tests.gyp index ac521b1..b6f6e0c 100644 --- a/ios/chrome/ios_chrome_tests.gyp +++ b/ios/chrome/ios_chrome_tests.gyp
@@ -127,8 +127,8 @@ '../../components/components.gyp:keyed_service_ios', '../../components/components.gyp:password_manager_core_browser_test_support', '../../components/components.gyp:signin_ios_browser_test_support', - '../../components/components.gyp:sync_driver_test_support', '../../components/sync.gyp:sync', + '../../components/sync.gyp:test_support_sync_driver', '../../testing/gmock.gyp:gmock', '../../testing/gtest.gyp:gtest', '../../ui/base/ui_base.gyp:ui_base',
diff --git a/ios/chrome/tools/build/ios_repack_extension_locales.py b/ios/chrome/tools/build/ios_repack_extension_locales.py index 529b8ed..540a999 100755 --- a/ios/chrome/tools/build/ios_repack_extension_locales.py +++ b/ios/chrome/tools/build/ios_repack_extension_locales.py
@@ -14,9 +14,11 @@ import os import sys +# Prepend the grit module from the source tree so it takes precedence over other +# grit versions that might present in the search path. script_dir = os.path.dirname(__file__) src_dir = os.path.join(script_dir, os.pardir, os.pardir, os.pardir, os.pardir) -sys.path.append(os.path.join(src_dir, 'tools', 'grit')) +sys.path.insert(1, os.path.join(src_dir, 'tools', 'grit')) from grit.format import data_pack
diff --git a/ios/chrome/tools/build/ios_repack_locales.py b/ios/chrome/tools/build/ios_repack_locales.py index d65ce8d7..cd7818e 100755 --- a/ios/chrome/tools/build/ios_repack_locales.py +++ b/ios/chrome/tools/build/ios_repack_locales.py
@@ -14,9 +14,11 @@ import os import sys +# Prepend the grit module from the source tree so it takes precedence over other +# grit versions that might present in the search path. script_dir = os.path.dirname(__file__) src_dir = os.path.join(script_dir, os.pardir, os.pardir, os.pardir, os.pardir) -sys.path.append(os.path.join(src_dir, 'tools', 'grit')) +sys.path.insert(1, os.path.join(src_dir, 'tools', 'grit')) from grit.format import data_pack
diff --git a/ios/net/cookies/cookie_store_ios.mm b/ios/net/cookies/cookie_store_ios.mm index 6eed4b8..fbee532 100644 --- a/ios/net/cookies/cookie_store_ios.mm +++ b/ios/net/cookies/cookie_store_ios.mm
@@ -313,7 +313,8 @@ CookieStoreIOS::~CookieStoreIOS() { NotificationTrampoline::GetInstance()->RemoveObserver(this); - STLDeleteContainerPairSecondPointers(hook_map_.begin(), hook_map_.end()); + base::STLDeleteContainerPairSecondPointers(hook_map_.begin(), + hook_map_.end()); } // static
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn index 72023be..8b09bc0 100644 --- a/ios/web/BUILD.gn +++ b/ios/web/BUILD.gn
@@ -94,6 +94,7 @@ "net/request_tracker_impl.mm", "net/web_http_protocol_handler_delegate.h", "net/web_http_protocol_handler_delegate.mm", + "payments/payment_request.cc", "public/active_state_manager.h", "public/block_types.h", "public/browser_state.h", @@ -115,6 +116,7 @@ "public/navigation_manager.h", "public/origin_util.h", "public/origin_util.mm", + "public/payments/payment_request.h", "public/referrer.h", "public/referrer_util.cc", "public/referrer_util.h", @@ -457,6 +459,7 @@ "net/request_group_util_unittest.mm", "net/request_tracker_impl_unittest.mm", "net/web_http_protocol_handler_delegate_unittest.mm", + "payments/payment_request_unittest.cc", "public/origin_util_unittest.mm", "public/referrer_util_unittest.cc", "public/web_state/page_viewport_state_unittest.mm",
diff --git a/ios/web/payments/payment_request.cc b/ios/web/payments/payment_request.cc new file mode 100644 index 0000000..f0579371 --- /dev/null +++ b/ios/web/payments/payment_request.cc
@@ -0,0 +1,240 @@ +// Copyright 2016 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 "ios/web/public/payments/payment_request.h" + +#include "base/values.h" + +namespace { + +// All of these are defined here (even though most are only used once each) so +// the format details are easy to locate and update or compare to the spec doc. +// (https://w3c.github.io/browser-payment-api/). +static const char kMethodData[] = "methodData"; +static const char kSupportedMethods[] = "supportedMethods"; +static const char kData[] = "data"; +static const char kPaymentDetails[] = "details"; +static const char kPaymentDetailsTotal[] = "total"; +static const char kPaymentDetailsTotalAmount[] = "amount"; +static const char kPaymentDetailsTotalAmountCurrency[] = "currency"; +static const char kPaymentDetailsTotalAmountValue[] = "value"; +static const char kMethodName[] = "methodName"; + +} // namespace + +namespace web { + +PaymentAddress::PaymentAddress() {} +PaymentAddress::PaymentAddress(const PaymentAddress& other) = default; +PaymentAddress::~PaymentAddress() = default; + +bool PaymentAddress::operator==(const PaymentAddress& other) const { + return this->country == other.country && + this->address_line == other.address_line && + this->region == other.region && this->city == other.city && + this->dependent_locality == other.dependent_locality && + this->postal_code == other.postal_code && + this->sorting_code == other.sorting_code && + this->language_code == other.language_code && + this->organization == other.organization && + this->recipient == other.recipient && this->care_of == other.care_of && + this->phone == other.phone; +} + +bool PaymentAddress::operator!=(const PaymentAddress& other) const { + return !(*this == other); +} + +PaymentMethodData::PaymentMethodData() {} +PaymentMethodData::PaymentMethodData(const PaymentMethodData& other) = default; +PaymentMethodData::~PaymentMethodData() = default; + +bool PaymentMethodData::operator==(const PaymentMethodData& other) const { + return this->supported_methods == other.supported_methods && + this->data == other.data; +} + +bool PaymentMethodData::operator!=(const PaymentMethodData& other) const { + return !(*this == other); +} + +PaymentCurrencyAmount::PaymentCurrencyAmount() {} +PaymentCurrencyAmount::~PaymentCurrencyAmount() = default; + +bool PaymentCurrencyAmount::operator==( + const PaymentCurrencyAmount& other) const { + return this->currency == other.currency && this->value == other.value; +} + +bool PaymentCurrencyAmount::operator!=( + const PaymentCurrencyAmount& other) const { + return !(*this == other); +} + +PaymentItem::PaymentItem() {} +PaymentItem::~PaymentItem() = default; + +bool PaymentItem::operator==(const PaymentItem& other) const { + return this->label == other.label && this->amount == other.amount; +} + +bool PaymentItem::operator!=(const PaymentItem& other) const { + return !(*this == other); +} + +PaymentShippingOption::PaymentShippingOption() : selected(false) {} +PaymentShippingOption::PaymentShippingOption( + const PaymentShippingOption& other) = default; +PaymentShippingOption::~PaymentShippingOption() = default; + +bool PaymentShippingOption::operator==( + const PaymentShippingOption& other) const { + return this->id == other.id && this->label == other.label && + this->amount == other.amount && this->selected == other.selected; +} + +bool PaymentShippingOption::operator!=( + const PaymentShippingOption& other) const { + return !(*this == other); +} + +PaymentDetailsModifier::PaymentDetailsModifier() {} +PaymentDetailsModifier::PaymentDetailsModifier( + const PaymentDetailsModifier& other) = default; +PaymentDetailsModifier::~PaymentDetailsModifier() = default; + +bool PaymentDetailsModifier::operator==( + const PaymentDetailsModifier& other) const { + return this->supported_methods == other.supported_methods && + this->total == other.total && + this->additional_display_items == other.additional_display_items; +} + +bool PaymentDetailsModifier::operator!=( + const PaymentDetailsModifier& other) const { + return !(*this == other); +} + +PaymentDetails::PaymentDetails() {} +PaymentDetails::PaymentDetails(const PaymentDetails& other) = default; +PaymentDetails::~PaymentDetails() = default; + +bool PaymentDetails::operator==(const PaymentDetails& other) const { + return this->total == other.total && + this->display_items == other.display_items && + this->shipping_options == other.shipping_options && + this->modifiers == other.modifiers; +} + +bool PaymentDetails::operator!=(const PaymentDetails& other) const { + return !(*this == other); +} + +PaymentOptions::PaymentOptions() + : request_payer_email(false), + request_payer_phone(false), + request_shipping(false) {} +PaymentOptions::~PaymentOptions() = default; + +bool PaymentOptions::operator==(const PaymentOptions& other) const { + return this->request_payer_email == other.request_payer_email && + this->request_payer_phone == other.request_payer_phone && + this->request_shipping == other.request_shipping; +} + +bool PaymentOptions::operator!=(const PaymentOptions& other) const { + return !(*this == other); +} + +PaymentRequest::PaymentRequest() {} +PaymentRequest::PaymentRequest(const PaymentRequest& other) = default; +PaymentRequest::~PaymentRequest() = default; + +bool PaymentRequest::operator==(const PaymentRequest& other) const { + return this->payment_address == other.payment_address && + this->shipping_option == other.shipping_option && + this->method_data == other.method_data && + this->details == other.details && this->options == other.options; +} + +bool PaymentRequest::operator!=(const PaymentRequest& other) const { + return !(*this == other); +} + +bool PaymentRequest::FromDictionaryValue(const base::DictionaryValue& value) { + this->method_data.clear(); + + // Parse the payment method data. + const base::ListValue* method_data_list = nullptr; + // At least one method is required. + if (!value.GetList(kMethodData, &method_data_list) || + method_data_list->GetSize() == 0) { + return false; + } + for (size_t i = 0; i < method_data_list->GetSize(); ++i) { + const base::DictionaryValue* method_data_dict; + // Method data is required. + if (!method_data_list->GetDictionary(i, &method_data_dict)) + return false; + + PaymentMethodData method_data; + const base::ListValue* supported_methods_list = nullptr; + // At least one supported method is required. + if (!method_data_dict->GetList(kSupportedMethods, + &supported_methods_list) || + supported_methods_list->GetSize() == 0) { + return false; + } + for (size_t i = 0; i < supported_methods_list->GetSize(); ++i) { + base::string16 supported_method; + supported_methods_list->GetString(i, &supported_method); + method_data.supported_methods.push_back(supported_method); + } + method_data_dict->GetString(kData, &method_data.data); + + this->method_data.push_back(method_data); + } + + // Parse the payment details. + const base::DictionaryValue* payment_details_dict = nullptr; + if (value.GetDictionary(kPaymentDetails, &payment_details_dict)) { + const base::DictionaryValue* total_dict = nullptr; + if (payment_details_dict->GetDictionary(kPaymentDetailsTotal, + &total_dict)) { + const base::DictionaryValue* amount_dict = nullptr; + if (total_dict->GetDictionary(kPaymentDetailsTotalAmount, &amount_dict)) { + amount_dict->GetString(kPaymentDetailsTotalAmountCurrency, + &this->details.total.amount.currency); + amount_dict->GetString(kPaymentDetailsTotalAmountValue, + &this->details.total.amount.value); + } + } + } + + // TODO(crbug.com/602666): Parse the remaining elements. + + return true; +} + +PaymentResponse::PaymentResponse() {} +PaymentResponse::~PaymentResponse() = default; + +bool PaymentResponse::operator==(const PaymentResponse& other) const { + return this->method_name == other.method_name && + this->details == other.details; +} + +bool PaymentResponse::operator!=(const PaymentResponse& other) const { + return !(*this == other); +} + +void PaymentResponse::ToDictionaryValue(base::DictionaryValue* value) const { + DCHECK(value); + if (!this->method_name.empty()) + value->SetString(kMethodName, this->method_name); + if (!this->details.empty()) + value->SetString(kPaymentDetails, this->details); +} + +} // namespace web
diff --git a/ios/web/payments/payment_request_unittest.cc b/ios/web/payments/payment_request_unittest.cc new file mode 100644 index 0000000..df95d40d --- /dev/null +++ b/ios/web/payments/payment_request_unittest.cc
@@ -0,0 +1,545 @@ +// Copyright 2016 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 "ios/web/public/payments/payment_request.h" + +#include <vector> + +#include "base/strings/utf_string_conversions.h" +#include "base/values.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace web { + +// PaymentRequest parsing tests. + +// Tests that parsing an empty value fails. +TEST(PaymentRequestTest, ParsingEmptyRequestDictionaryFails) { + PaymentRequest output_request; + base::DictionaryValue request_dict; + EXPECT_FALSE(output_request.FromDictionaryValue(request_dict)); +} + +// Tests that parsing a dictionary without all requirement values fails. +TEST(PaymentRequestTest, ParsingPartiallyPopulatedRequestDictionaryFails) { + PaymentRequest expected_request; + PaymentRequest output_request; + base::DictionaryValue request_dict; + + // An empty methodData list alone is insufficient. + std::unique_ptr<base::ListValue> method_data_list(new base::ListValue); + request_dict.Set("methodData", std::move(method_data_list)); + + EXPECT_FALSE(output_request.FromDictionaryValue(request_dict)); + EXPECT_EQ(expected_request, output_request); + + // A non-dictionary value in the methodData list is incorrect. + method_data_list.reset(new base::ListValue); + method_data_list->AppendString("fake method data dictionary"); + request_dict.Set("methodData", std::move(method_data_list)); + + EXPECT_FALSE(output_request.FromDictionaryValue(request_dict)); + EXPECT_EQ(expected_request, output_request); + + // An empty dictionary in the methodData list is still insufficient. + method_data_list.reset(new base::ListValue); + std::unique_ptr<base::DictionaryValue> method_data_dict( + new base::DictionaryValue); + method_data_list->Append(std::move(method_data_dict)); + request_dict.Set("methodData", std::move(method_data_list)); + + EXPECT_FALSE(output_request.FromDictionaryValue(request_dict)); + EXPECT_EQ(expected_request, output_request); +} + +// Tests that parsing a dictionary with all required elements succeeds and +// produces the expected result. +TEST(PaymentRequestTest, ParsingFullyPopulatedRequestDictionarySucceeds) { + PaymentRequest expected_request; + PaymentRequest output_request; + base::DictionaryValue request_dict; + + // Add the expected values to expected_request. + PaymentMethodData method_data; + std::vector<base::string16> supported_methods; + supported_methods.push_back(base::ASCIIToUTF16("Visa")); + method_data.supported_methods = supported_methods; + expected_request.method_data.push_back(method_data); + + // Add the same values to the dictionary to be parsed. + std::unique_ptr<base::ListValue> method_data_list(new base::ListValue); + std::unique_ptr<base::DictionaryValue> method_data_dict( + new base::DictionaryValue); + std::unique_ptr<base::ListValue> supported_methods_list(new base::ListValue); + supported_methods_list->AppendString("Visa"); + method_data_dict->Set("supportedMethods", std::move(supported_methods_list)); + method_data_list->Append(std::move(method_data_dict)); + request_dict.Set("methodData", std::move(method_data_list)); + + // With the required values present, parsing should succeed. + EXPECT_TRUE(output_request.FromDictionaryValue(request_dict)); + EXPECT_EQ(expected_request, output_request); + + // If payment details are present, parse those as well. + expected_request.details.total.amount.currency = base::ASCIIToUTF16("GBP"); + expected_request.details.total.amount.value = base::ASCIIToUTF16("6.66"); + + std::unique_ptr<base::DictionaryValue> details_dict( + new base::DictionaryValue); + std::unique_ptr<base::DictionaryValue> total_dict(new base::DictionaryValue); + std::unique_ptr<base::DictionaryValue> amount_dict(new base::DictionaryValue); + amount_dict->SetString("currency", "GBP"); + amount_dict->SetString("value", "6.66"); + total_dict->Set("amount", std::move(amount_dict)); + details_dict->Set("total", std::move(total_dict)); + request_dict.Set("details", std::move(details_dict)); + + EXPECT_TRUE(output_request.FromDictionaryValue(request_dict)); + EXPECT_EQ(expected_request, output_request); +} + +// PaymentResponse serialization tests. + +// Tests that serializing a default PaymentResponse yields an empty dictionary. +TEST(PaymentRequestTest, EmptyResponseDictionary) { + base::DictionaryValue expected_value; + base::DictionaryValue output_value; + + PaymentResponse payment_response; + payment_response.ToDictionaryValue(&output_value); + EXPECT_TRUE(expected_value.Equals(&output_value)); +} + +// Tests that serializing a populated PaymentResponse yields the expected +// result. +TEST(PaymentRequestTest, PopulatedResponseDictionary) { + base::DictionaryValue expected_value; + base::DictionaryValue output_value; + + expected_value.SetString("methodName", "American Express"); + PaymentResponse payment_response; + payment_response.method_name = base::ASCIIToUTF16("American Express"); + payment_response.ToDictionaryValue(&output_value); + EXPECT_TRUE(expected_value.Equals(&output_value)); + + expected_value.SetString("details", "{cardSecurityCode: '123'}"); + payment_response.details = base::ASCIIToUTF16("{cardSecurityCode: '123'}"); + payment_response.ToDictionaryValue(&output_value); + EXPECT_TRUE(expected_value.Equals(&output_value)); +} + +// Value equality tests. + +// Tests that two addresses are not equal if their property values differ or +// one is missing a value present in the other, and equal otherwise. +TEST(PaymentRequestTest, PaymentAddressEquality) { + PaymentAddress address1; + PaymentAddress address2; + EXPECT_EQ(address1, address2); + + address1.country = base::ASCIIToUTF16("Madagascar"); + EXPECT_NE(address1, address2); + address2.country = base::ASCIIToUTF16("Monaco"); + EXPECT_NE(address1, address2); + address2.country = base::ASCIIToUTF16("Madagascar"); + EXPECT_EQ(address1, address2); + + std::vector<base::string16> address_line1; + address_line1.push_back(base::ASCIIToUTF16("123 Main St.")); + address_line1.push_back(base::ASCIIToUTF16("Apartment B")); + address1.address_line = address_line1; + EXPECT_NE(address1, address2); + std::vector<base::string16> address_line2; + address_line2.push_back(base::ASCIIToUTF16("123 Main St.")); + address_line2.push_back(base::ASCIIToUTF16("Apartment C")); + address2.address_line = address_line2; + EXPECT_NE(address1, address2); + address2.address_line = address_line1; + EXPECT_EQ(address1, address2); + + address1.region = base::ASCIIToUTF16("Quebec"); + EXPECT_NE(address1, address2); + address2.region = base::ASCIIToUTF16("Newfoundland and Labrador"); + EXPECT_NE(address1, address2); + address2.region = base::ASCIIToUTF16("Quebec"); + EXPECT_EQ(address1, address2); + + address1.city = base::ASCIIToUTF16("Timbuktu"); + EXPECT_NE(address1, address2); + address2.city = base::ASCIIToUTF16("Timbuk 3"); + EXPECT_NE(address1, address2); + address2.city = base::ASCIIToUTF16("Timbuktu"); + EXPECT_EQ(address1, address2); + + address1.dependent_locality = base::ASCIIToUTF16("Manhattan"); + EXPECT_NE(address1, address2); + address2.dependent_locality = base::ASCIIToUTF16("Queens"); + EXPECT_NE(address1, address2); + address2.dependent_locality = base::ASCIIToUTF16("Manhattan"); + EXPECT_EQ(address1, address2); + + address1.postal_code = base::ASCIIToUTF16("90210"); + EXPECT_NE(address1, address2); + address2.postal_code = base::ASCIIToUTF16("89049"); + EXPECT_NE(address1, address2); + address2.postal_code = base::ASCIIToUTF16("90210"); + EXPECT_EQ(address1, address2); + + address1.sorting_code = base::ASCIIToUTF16("14390"); + EXPECT_NE(address1, address2); + address2.sorting_code = base::ASCIIToUTF16("09341"); + EXPECT_NE(address1, address2); + address2.sorting_code = base::ASCIIToUTF16("14390"); + EXPECT_EQ(address1, address2); + + address1.language_code = base::ASCIIToUTF16("fr"); + EXPECT_NE(address1, address2); + address2.language_code = base::ASCIIToUTF16("zh-HK"); + EXPECT_NE(address1, address2); + address2.language_code = base::ASCIIToUTF16("fr"); + EXPECT_EQ(address1, address2); + + address1.organization = base::ASCIIToUTF16("The Willy Wonka Candy Company"); + EXPECT_NE(address1, address2); + address2.organization = base::ASCIIToUTF16("Sears"); + EXPECT_NE(address1, address2); + address2.organization = base::ASCIIToUTF16("The Willy Wonka Candy Company"); + EXPECT_EQ(address1, address2); + + address1.recipient = base::ASCIIToUTF16("Veruca Salt"); + EXPECT_NE(address1, address2); + address2.recipient = base::ASCIIToUTF16("Veronica Mars"); + EXPECT_NE(address1, address2); + address2.recipient = base::ASCIIToUTF16("Veruca Salt"); + EXPECT_EQ(address1, address2); + + address1.care_of = base::ASCIIToUTF16("Jarvis"); + EXPECT_NE(address1, address2); + address2.care_of = base::ASCIIToUTF16("Tony"); + EXPECT_NE(address1, address2); + address2.care_of = base::ASCIIToUTF16("Jarvis"); + EXPECT_EQ(address1, address2); + + address1.phone = base::ASCIIToUTF16("888-867-5309"); + EXPECT_NE(address1, address2); + address2.phone = base::ASCIIToUTF16("800-984-3672"); + EXPECT_NE(address1, address2); + address2.phone = base::ASCIIToUTF16("888-867-5309"); + EXPECT_EQ(address1, address2); +} + +// Tests that two method data objects are not equal if their property values +// differ or one is missing a value present in the other, and equal otherwise. +TEST(PaymentRequestTest, PaymentMethodDataEquality) { + PaymentMethodData method_data1; + PaymentMethodData method_data2; + EXPECT_EQ(method_data1, method_data2); + + std::vector<base::string16> supported_methods1; + supported_methods1.push_back(base::ASCIIToUTF16("Visa")); + supported_methods1.push_back(base::ASCIIToUTF16("BobPay")); + method_data1.supported_methods = supported_methods1; + EXPECT_NE(method_data1, method_data2); + std::vector<base::string16> supported_methods2; + supported_methods2.push_back(base::ASCIIToUTF16("BobPay")); + method_data2.supported_methods = supported_methods2; + EXPECT_NE(method_data1, method_data2); + method_data2.supported_methods = supported_methods1; + EXPECT_EQ(method_data1, method_data2); + + method_data1.data = base::ASCIIToUTF16("{merchantId: '123456'}"); + EXPECT_NE(method_data1, method_data2); + method_data2.data = base::ASCIIToUTF16("{merchantId: '9999-88'}"); + EXPECT_NE(method_data1, method_data2); + method_data2.data = base::ASCIIToUTF16("{merchantId: '123456'}"); + EXPECT_EQ(method_data1, method_data2); +} + +// Tests that two currency amount objects are not equal if their property values +// differ or one is missing a value present in the other, and equal otherwise. +TEST(PaymentRequestTest, PaymentCurrencyAmountEquality) { + PaymentCurrencyAmount currency_amount1; + PaymentCurrencyAmount currency_amount2; + EXPECT_EQ(currency_amount1, currency_amount2); + + currency_amount1.currency = base::ASCIIToUTF16("HKD"); + EXPECT_NE(currency_amount1, currency_amount2); + currency_amount2.currency = base::ASCIIToUTF16("USD"); + EXPECT_NE(currency_amount1, currency_amount2); + currency_amount2.currency = base::ASCIIToUTF16("HKD"); + EXPECT_EQ(currency_amount1, currency_amount2); + + currency_amount1.value = base::ASCIIToUTF16("49.89"); + EXPECT_NE(currency_amount1, currency_amount2); + currency_amount2.value = base::ASCIIToUTF16("49.99"); + EXPECT_NE(currency_amount1, currency_amount2); + currency_amount2.value = base::ASCIIToUTF16("49.89"); + EXPECT_EQ(currency_amount1, currency_amount2); +} + +// Tests that two payment item objects are not equal if their property values +// differ or one is missing a value present in the other, and equal otherwise. +// Doesn't test all properties of child objects, relying instead on their +// respective tests. +TEST(PaymentRequestTest, PaymentItemEquality) { + PaymentItem item1; + PaymentItem item2; + EXPECT_EQ(item1, item2); + + item1.label = base::ASCIIToUTF16("Subtotal"); + EXPECT_NE(item1, item2); + item2.label = base::ASCIIToUTF16("Total"); + EXPECT_NE(item1, item2); + item2.label = base::ASCIIToUTF16("Subtotal"); + EXPECT_EQ(item1, item2); + + item1.amount.value = base::ASCIIToUTF16("104.34"); + EXPECT_NE(item1, item2); + item2.amount.value = base::ASCIIToUTF16("104"); + EXPECT_NE(item1, item2); + item2.amount.value = base::ASCIIToUTF16("104.34"); + EXPECT_EQ(item1, item2); +} + +// Tests that two shipping option objects are not equal if their property values +// differ or one is missing a value present in the other, and equal otherwise. +// Doesn't test all properties of child objects, relying instead on their +// respective tests. +TEST(PaymentRequestTest, PaymentShippingOptionEquality) { + PaymentShippingOption shipping_option1; + PaymentShippingOption shipping_option2; + EXPECT_EQ(shipping_option1, shipping_option2); + + shipping_option1.id = base::ASCIIToUTF16("a8df2"); + EXPECT_NE(shipping_option1, shipping_option2); + shipping_option2.id = base::ASCIIToUTF16("k42jk"); + EXPECT_NE(shipping_option1, shipping_option2); + shipping_option2.id = base::ASCIIToUTF16("a8df2"); + EXPECT_EQ(shipping_option1, shipping_option2); + + shipping_option1.label = base::ASCIIToUTF16("Overnight"); + EXPECT_NE(shipping_option1, shipping_option2); + shipping_option2.label = base::ASCIIToUTF16("Ground"); + EXPECT_NE(shipping_option1, shipping_option2); + shipping_option2.label = base::ASCIIToUTF16("Overnight"); + EXPECT_EQ(shipping_option1, shipping_option2); + + shipping_option1.amount.currency = base::ASCIIToUTF16("AUD"); + EXPECT_NE(shipping_option1, shipping_option2); + shipping_option2.amount.currency = base::ASCIIToUTF16("HKD"); + EXPECT_NE(shipping_option1, shipping_option2); + shipping_option2.amount.currency = base::ASCIIToUTF16("AUD"); + EXPECT_EQ(shipping_option1, shipping_option2); + + shipping_option1.selected = true; + EXPECT_NE(shipping_option1, shipping_option2); + shipping_option2.selected = true; + EXPECT_EQ(shipping_option1, shipping_option2); +} + +// Tests that two details modifier objects are not equal if their property +// values differ or one is missing a value present in the other, and equal +// otherwise. Doesn't test all properties of child objects, relying instead on +// their respective tests. +TEST(PaymentRequestTest, PaymentDetailsModifierEquality) { + PaymentDetailsModifier details_modifier1; + PaymentDetailsModifier details_modifier2; + EXPECT_EQ(details_modifier1, details_modifier2); + + std::vector<base::string16> supported_methods1; + supported_methods1.push_back(base::ASCIIToUTF16("China UnionPay")); + supported_methods1.push_back(base::ASCIIToUTF16("BobPay")); + details_modifier1.supported_methods = supported_methods1; + EXPECT_NE(details_modifier1, details_modifier2); + std::vector<base::string16> supported_methods2; + supported_methods2.push_back(base::ASCIIToUTF16("BobPay")); + details_modifier2.supported_methods = supported_methods2; + EXPECT_NE(details_modifier1, details_modifier2); + details_modifier2.supported_methods = supported_methods1; + EXPECT_EQ(details_modifier1, details_modifier2); + + details_modifier1.total.label = base::ASCIIToUTF16("Total"); + EXPECT_NE(details_modifier1, details_modifier2); + details_modifier2.total.label = base::ASCIIToUTF16("Gratuity"); + EXPECT_NE(details_modifier1, details_modifier2); + details_modifier2.total.label = base::ASCIIToUTF16("Total"); + EXPECT_EQ(details_modifier1, details_modifier2); + + PaymentItem payment_item; + payment_item.label = base::ASCIIToUTF16("Tax"); + std::vector<PaymentItem> display_items1; + display_items1.push_back(payment_item); + details_modifier1.additional_display_items = display_items1; + EXPECT_NE(details_modifier1, details_modifier2); + std::vector<PaymentItem> display_items2; + display_items2.push_back(payment_item); + display_items2.push_back(payment_item); + details_modifier2.additional_display_items = display_items2; + EXPECT_NE(details_modifier1, details_modifier2); + details_modifier2.additional_display_items = display_items1; + EXPECT_EQ(details_modifier1, details_modifier2); +} + +// Tests that two payment details objects are not equal if their property values +// differ or one is missing a value present in the other, and equal otherwise. +// Doesn't test all properties of child objects, relying instead on their +// respective tests. +TEST(PaymentRequestTest, PaymentDetailsEquality) { + PaymentDetails details1; + PaymentDetails details2; + EXPECT_EQ(details1, details2); + + details1.total.label = base::ASCIIToUTF16("Total"); + EXPECT_NE(details1, details2); + details2.total.label = base::ASCIIToUTF16("Shipping"); + EXPECT_NE(details1, details2); + details2.total.label = base::ASCIIToUTF16("Total"); + EXPECT_EQ(details1, details2); + + PaymentItem payment_item; + payment_item.label = base::ASCIIToUTF16("Tax"); + std::vector<PaymentItem> display_items1; + display_items1.push_back(payment_item); + details1.display_items = display_items1; + EXPECT_NE(details1, details2); + std::vector<PaymentItem> display_items2; + display_items2.push_back(payment_item); + display_items2.push_back(payment_item); + details2.display_items = display_items2; + EXPECT_NE(details1, details2); + details2.display_items = display_items1; + EXPECT_EQ(details1, details2); + + PaymentShippingOption shipping_option; + shipping_option.label = base::ASCIIToUTF16("Overnight"); + std::vector<PaymentShippingOption> shipping_options1; + shipping_options1.push_back(shipping_option); + details1.shipping_options = shipping_options1; + EXPECT_NE(details1, details2); + std::vector<PaymentShippingOption> shipping_options2; + shipping_options2.push_back(shipping_option); + shipping_options2.push_back(shipping_option); + details2.shipping_options = shipping_options2; + EXPECT_NE(details1, details2); + details2.shipping_options = shipping_options1; + EXPECT_EQ(details1, details2); + + PaymentDetailsModifier details_modifier; + details_modifier.total.label = base::ASCIIToUTF16("Total"); + std::vector<PaymentDetailsModifier> details_modifiers1; + details_modifiers1.push_back(details_modifier); + details1.modifiers = details_modifiers1; + EXPECT_NE(details1, details2); + std::vector<PaymentDetailsModifier> details_modifiers2; + details2.modifiers = details_modifiers2; + EXPECT_NE(details1, details2); + details2.modifiers = details_modifiers1; + EXPECT_EQ(details1, details2); +} + +// Tests that two payment options objects are not equal if their property values +// differ and equal otherwise. +TEST(PaymentRequestTest, PaymentOptionsEquality) { + PaymentOptions options1; + PaymentOptions options2; + EXPECT_EQ(options1, options2); + + options1.request_payer_email = true; + EXPECT_NE(options1, options2); + options2.request_payer_email = true; + EXPECT_EQ(options1, options2); + + options1.request_payer_phone = true; + EXPECT_NE(options1, options2); + options2.request_payer_phone = true; + EXPECT_EQ(options1, options2); + + options1.request_shipping = true; + EXPECT_NE(options1, options2); + options2.request_shipping = true; + EXPECT_EQ(options1, options2); +} + +// Tests that two payment request objects are not equal if their property values +// differ or one is missing a value present in the other, and equal otherwise. +// Doesn't test all properties of child objects, relying instead on their +// respective tests. +TEST(PaymentRequestTest, PaymentRequestEquality) { + PaymentRequest request1; + PaymentRequest request2; + EXPECT_EQ(request1, request2); + + PaymentAddress address1; + address1.recipient = base::ASCIIToUTF16("Jessica Jones"); + request1.payment_address = address1; + EXPECT_NE(request1, request2); + PaymentAddress address2; + address2.recipient = base::ASCIIToUTF16("Luke Cage"); + request2.payment_address = address2; + EXPECT_NE(request1, request2); + request2.payment_address = address1; + EXPECT_EQ(request1, request2); + + request1.shipping_option = base::ASCIIToUTF16("2-Day"); + EXPECT_NE(request1, request2); + request2.shipping_option = base::ASCIIToUTF16("3-Day"); + EXPECT_NE(request1, request2); + request2.shipping_option = base::ASCIIToUTF16("2-Day"); + EXPECT_EQ(request1, request2); + + PaymentMethodData method_datum; + method_datum.data = base::ASCIIToUTF16("{merchantId: '123456'}"); + std::vector<PaymentMethodData> method_data1; + method_data1.push_back(method_datum); + request1.method_data = method_data1; + EXPECT_NE(request1, request2); + std::vector<PaymentMethodData> method_data2; + request2.method_data = method_data2; + EXPECT_NE(request1, request2); + request2.method_data = method_data1; + EXPECT_EQ(request1, request2); + + PaymentDetails details1; + details1.total.label = base::ASCIIToUTF16("Total"); + request1.details = details1; + EXPECT_NE(request1, request2); + PaymentDetails details2; + details2.total.amount.value = base::ASCIIToUTF16("0.01"); + request2.details = details2; + EXPECT_NE(request1, request2); + request2.details = details1; + EXPECT_EQ(request1, request2); + + PaymentOptions options; + options.request_shipping = true; + request1.options = options; + EXPECT_NE(request1, request2); + request2.options = options; + EXPECT_EQ(request1, request2); +} + +// Tests that two payment response objects are not equal if their property +// values differ or one is missing a value present in the other, and equal +// otherwise. +TEST(PaymentRequestTest, PaymentResponseEquality) { + PaymentResponse response1; + PaymentResponse response2; + EXPECT_EQ(response1, response2); + + response1.method_name = base::ASCIIToUTF16("Visa"); + EXPECT_NE(response1, response2); + response2.method_name = base::ASCIIToUTF16("Mastercard"); + EXPECT_NE(response1, response2); + response2.method_name = base::ASCIIToUTF16("Visa"); + EXPECT_EQ(response1, response2); + + response1.details = base::ASCIIToUTF16("{cardSecurityCode: '123'}"); + EXPECT_NE(response1, response2); + response2.details = base::ASCIIToUTF16("{cardSecurityCode: '---'}"); + EXPECT_NE(response1, response2); + response2.details = base::ASCIIToUTF16("{cardSecurityCode: '123'}"); + EXPECT_EQ(response1, response2); +} + +} // namespace web
diff --git a/ios/web/public/payments/payment_request.h b/ios/web/public/payments/payment_request.h new file mode 100644 index 0000000..51eeefad --- /dev/null +++ b/ios/web/public/payments/payment_request.h
@@ -0,0 +1,290 @@ +// Copyright 2016 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 IOS_WEB_PUBLIC_PAYMENTS_PAYMENT_REQUEST_H_ +#define IOS_WEB_PUBLIC_PAYMENTS_PAYMENT_REQUEST_H_ + +#include <vector> + +#include "base/strings/string16.h" + +// C++ bindings for the PaymentRequest API. Conforms to the 18 July 2016 +// editor's draft at https://w3c.github.io/browser-payment-api/. + +namespace base { +class DictionaryValue; +} + +namespace web { + +// A shipping or billing address. +class PaymentAddress { + public: + PaymentAddress(); + PaymentAddress(const PaymentAddress& other); + ~PaymentAddress(); + + bool operator==(const PaymentAddress& other) const; + bool operator!=(const PaymentAddress& other) const; + + // The CLDR (Common Locale Data Repository) region code. For example, US, GB, + // CN, or JP. + base::string16 country; + + // The most specific part of the address. It can include, for example, a + // street name, a house number, apartment number, a rural delivery route, + // descriptive instructions, or a post office box number. + std::vector<base::string16> address_line; + + // The top level administrative subdivision of the country. For example, this + // can be a state, a province, an oblast, or a prefecture. + base::string16 region; + + // The city/town portion of the address. + base::string16 city; + + // The dependent locality or sublocality within a city. For example, used for + // neighborhoods, boroughs, districts, or UK dependent localities. + base::string16 dependent_locality; + + // The postal code or ZIP code, also known as PIN code in India. + base::string16 postal_code; + + // The sorting code as used in, for example, France. + base::string16 sorting_code; + + // The BCP-47 language code for the address. It's used to determine the field + // separators and the order of fields when formatting the address for display. + base::string16 language_code; + + // The organization, firm, company, or institution at this address. + base::string16 organization; + + // The name of the recipient or contact person. + base::string16 recipient; + + // The name of an intermediary party or entity responsible for transferring + // packages between the postal service and the recipient. + base::string16 care_of; + + // The phone number of the recipient or contact person. + base::string16 phone; +}; + +// A set of supported payment methods and any associated payment method specific +// data for those methods. +class PaymentMethodData { + public: + PaymentMethodData(); + PaymentMethodData(const PaymentMethodData& other); + ~PaymentMethodData(); + + bool operator==(const PaymentMethodData& other) const; + bool operator!=(const PaymentMethodData& other) const; + + // Payment method identifiers for payment methods that the merchant web site + // accepts. + std::vector<base::string16> supported_methods; + + // A JSON-serialized object that provides optional information that might be + // needed by the supported payment methods. + base::string16 data; +}; + +// Supplies monetary amounts. +class PaymentCurrencyAmount { + public: + PaymentCurrencyAmount(); + ~PaymentCurrencyAmount(); + + bool operator==(const PaymentCurrencyAmount& other) const; + bool operator!=(const PaymentCurrencyAmount& other) const; + + // A currency identifier. The most common identifiers are three-letter + // alphabetic codes as defined by ISO 4217 (for example, "USD" for US Dollars) + // however any string is considered valid. + base::string16 currency; + + // A string containing the decimal monetary value. + base::string16 value; +}; + +// Information indicating what the payment request is for and the value asked +// for. +class PaymentItem { + public: + PaymentItem(); + ~PaymentItem(); + + bool operator==(const PaymentItem& other) const; + bool operator!=(const PaymentItem& other) const; + + // A human-readable description of the item. + base::string16 label; + + // The monetary amount for the item. + PaymentCurrencyAmount amount; +}; + +// Information describing a shipping option. +class PaymentShippingOption { + public: + PaymentShippingOption(); + PaymentShippingOption(const PaymentShippingOption& other); + ~PaymentShippingOption(); + + bool operator==(const PaymentShippingOption& other) const; + bool operator!=(const PaymentShippingOption& other) const; + + // An identifier used to reference this PaymentShippingOption. It is unique + // for a given PaymentRequest. + base::string16 id; + + // A human-readable description of the item. The user agent should use this + // string to display the shipping option to the user. + base::string16 label; + + // A PaymentCurrencyAmount containing the monetary amount for the option. + PaymentCurrencyAmount amount; + + // This is set to true to indicate that this is the default selected + // PaymentShippingOption in a sequence. User agents should display this option + // by default in the user interface. + bool selected; +}; + +// Details that modify the PaymentDetails based on the payment method +// identifier. +class PaymentDetailsModifier { + public: + PaymentDetailsModifier(); + PaymentDetailsModifier(const PaymentDetailsModifier& other); + ~PaymentDetailsModifier(); + + bool operator==(const PaymentDetailsModifier& other) const; + bool operator!=(const PaymentDetailsModifier& other) const; + + // A sequence of payment method identifiers. The remaining fields in the + // PaymentDetailsModifier apply only if the user selects a payment method + // included in this sequence. + std::vector<base::string16> supported_methods; + + // This value overrides the total field in the PaymentDetails dictionary for + // the payment method identifiers in the supportedMethods field. + PaymentItem total; + + // Provides additional display items that are appended to the displayItems + // field in the PaymentDetails dictionary for the payment method identifiers + // in the supportedMethods field. This field is commonly used to add a + // discount or surcharge line item indicating the reason for the different + // total amount for the selected payment method that the user agent may + // display. + std::vector<PaymentItem> additional_display_items; +}; + +// Details about the requested transaction. +class PaymentDetails { + public: + PaymentDetails(); + PaymentDetails(const PaymentDetails& other); + ~PaymentDetails(); + + bool operator==(const PaymentDetails& other) const; + bool operator!=(const PaymentDetails& other) const; + + // The total amount of the payment request. + PaymentItem total; + + // Line items for the payment request that the user agent may display. For + // example, it might include details of products or breakdown of tax and + // shipping. + std::vector<PaymentItem> display_items; + + // The different shipping options for the user to choose from. If empty, this + // indicates that the merchant cannot ship to the current shipping address. + std::vector<PaymentShippingOption> shipping_options; + + // Modifiers for particular payment method identifiers. For example, it allows + // adjustment to the total amount based on payment method. + std::vector<PaymentDetailsModifier> modifiers; +}; + +// Information describing a shipping option. +class PaymentOptions { + public: + PaymentOptions(); + ~PaymentOptions(); + + bool operator==(const PaymentOptions& other) const; + bool operator!=(const PaymentOptions& other) const; + + // Indicates whether the user agent should collect and return the payer's + // email address as part of the payment request. For example, this would be + // set to true to allow a merchant to email a receipt. + bool request_payer_email; + + // Indicates whether the user agent should collect and return the payer's + // phone number as part of the payment request. For example, this would be set + // to true to allow a merchant to phone a customer with a billing enquiry. + bool request_payer_phone; + + // Indicates whether the user agent should collect and return a shipping + // address as part of the payment request. For example, this would be set to + // true when physical goods need to be shipped by the merchant to the user. + // This would be set to false for an online-only electronic purchase + // transaction. + bool request_shipping; +}; + +// All of the information provided by a page making a request for payment. +class PaymentRequest { + public: + PaymentRequest(); + PaymentRequest(const PaymentRequest& other); + ~PaymentRequest(); + + bool operator==(const PaymentRequest& other) const; + bool operator!=(const PaymentRequest& other) const; + + // Populates the properties of this PaymentRequest from |value|. + bool FromDictionaryValue(const base::DictionaryValue& value); + + // Properties set in order to communicate user choices back to the page. + PaymentAddress payment_address; + base::string16 shipping_option; + + // Properties set via the constructor for communicating from the page to the + // browser UI. + std::vector<PaymentMethodData> method_data; + PaymentDetails details; + PaymentOptions options; +}; + +// Information provided in the Promise returned by a call to +// PaymentRequest.show(). +class PaymentResponse { + public: + PaymentResponse(); + ~PaymentResponse(); + + bool operator==(const PaymentResponse& other) const; + bool operator!=(const PaymentResponse& other) const; + + // Populates |value| with the properties of this PaymentResponse. + void ToDictionaryValue(base::DictionaryValue* value) const; + + // The payment method identifier for the payment method that the user selected + // to fulfil the transaction. + base::string16 method_name; + + // A JSON-serialized object that provides a payment method specific message + // used by the merchant to process the transaction and determine successful + // fund transfer. This data is returned by the payment app that satisfies the + // payment request. + base::string16 details; +}; + +} // namespace web + +#endif // IOS_WEB_PUBLIC_PAYMENTS_PAYMENT_REQUEST_H_
diff --git a/ios/web/public/test/web_js_test.h b/ios/web/public/test/web_js_test.h index f13ea1a..1f527ba 100644 --- a/ios/web/public/test/web_js_test.h +++ b/ios/web/public/test/web_js_test.h
@@ -29,12 +29,6 @@ Inject(); } - // Returns a NSString representation of the JavaScript's evaluation results; - // the JavaScript is passed in as a |format| and its arguments. - // DEPRECATED. TODO(crbug.com/595761): Remove this API. - NSString* EvaluateJavaScriptWithFormat(NSString* format, ...) - __attribute__((format(__NSString__, 2, 3))); - // Returns an id representation of the JavaScript's evaluation results; // the JavaScript is passed in as a |format| and its arguments. id ExecuteJavaScriptWithFormat(NSString* format, ...) @@ -42,14 +36,6 @@ // Helper method that EXPECTs the |java_script| evaluation results on each // element obtained by scripts in |get_element_javas_cripts|; the expected - // result string is the corresponding entry in |expected_results|. - // DEPRECATED. TODO(crbug.com/595761): Remove this API. - void EvaluateJavaScriptOnElementsAndCheck(NSString* java_script, - NSArray* get_element_java_scripts, - NSArray* expected_results); - - // Helper method that EXPECTs the |java_script| evaluation results on each - // element obtained by scripts in |get_element_javas_cripts|; the expected // result is the corresponding entry in |expected_results|. void ExecuteJavaScriptOnElementsAndCheck(NSString* java_script, NSArray* get_element_java_scripts, @@ -60,17 +46,6 @@ // expected results are boolean and are true only for elements in // |get_element_java_scripts_expecting_true| which is subset of // |get_element_java_scripts|. - // DEPRECATED. TODO(crbug.com/595761): Remove this API. - void EvaluateBooleanJavaScriptOnElementsAndCheck( - NSString* java_script, - NSArray* get_element_java_scripts, - NSArray* get_element_java_scripts_expecting_true); - - // Helper method that EXPECTs the |java_script| evaluation results on each - // element obtained by JavaScripts in |get_element_java_scripts|. The - // expected results are boolean and are true only for elements in - // |get_element_java_scripts_expecting_true| which is subset of - // |get_element_java_scripts|. void ExecuteBooleanJavaScriptOnElementsAndCheck( NSString* java_script, NSArray* get_element_java_scripts, @@ -100,18 +75,6 @@ } template <class WebTestT> -NSString* WebJsTest<WebTestT>::EvaluateJavaScriptWithFormat(NSString* format, - ...) { - va_list args; - va_start(args, format); - base::scoped_nsobject<NSString> java_script( - [[NSString alloc] initWithFormat:format arguments:args]); - va_end(args); - - return WebTestT::EvaluateJavaScriptAsString(java_script); -} - -template <class WebTestT> id WebJsTest<WebTestT>::ExecuteJavaScriptWithFormat(NSString* format, ...) { va_list args; va_start(args, format); @@ -123,18 +86,6 @@ } template <class WebTestT> -void WebJsTest<WebTestT>::EvaluateJavaScriptOnElementsAndCheck( - NSString* java_script, - NSArray* get_element_java_scripts, - NSArray* expected_results) { - for (NSUInteger i = 0; i < get_element_java_scripts.count; ++i) { - EXPECT_NSEQ( - expected_results[i], - EvaluateJavaScriptWithFormat(java_script, get_element_java_scripts[i])); - } -} - -template <class WebTestT> void WebJsTest<WebTestT>::ExecuteJavaScriptOnElementsAndCheck( NSString* java_script, NSArray* get_element_java_scripts, @@ -147,24 +98,6 @@ } template <class WebTestT> -void WebJsTest<WebTestT>::EvaluateBooleanJavaScriptOnElementsAndCheck( - NSString* java_script, - NSArray* get_element_java_scripts, - NSArray* get_element_java_scripts_expecting_true) { - for (NSUInteger index = 0; index < get_element_java_scripts.count; ++index) { - NSString* get_element_java_script = get_element_java_scripts[index]; - NSString* expected = [get_element_java_scripts_expecting_true - containsObject:get_element_java_script] - ? @"true" - : @"false"; - EXPECT_NSEQ(expected, EvaluateJavaScriptWithFormat(java_script, - get_element_java_script)) - << [NSString stringWithFormat:@"%@ on %@ should return %@", java_script, - get_element_java_script, expected]; - } -} - -template <class WebTestT> void WebJsTest<WebTestT>::ExecuteBooleanJavaScriptOnElementsAndCheck( NSString* java_script, NSArray* get_element_java_scripts,
diff --git a/ios/web/public/test/web_test_with_web_state.h b/ios/web/public/test/web_test_with_web_state.h index 8cbdabd..8c26f2b 100644 --- a/ios/web/public/test/web_test_with_web_state.h +++ b/ios/web/public/test/web_test_with_web_state.h
@@ -45,9 +45,6 @@ // Blocks until known NSRunLoop-based have completed, known message-loop-based // background tasks have completed and |condition| evaluates to true. void WaitForCondition(ConditionBlock condition); - // Evaluates JavaScript and returns result as a string. - // DEPRECATED. TODO(crbug.com/595761): Remove this API. - NSString* EvaluateJavaScriptAsString(NSString* script); // Synchronously executes JavaScript and returns result as id. id ExecuteJavaScript(NSString* script);
diff --git a/ios/web/public/test/web_test_with_web_state.mm b/ios/web/public/test/web_test_with_web_state.mm index 4b6c2f7..4694e303 100644 --- a/ios/web/public/test/web_test_with_web_state.mm +++ b/ios/web/public/test/web_test_with_web_state.mm
@@ -146,20 +146,6 @@ base::TimeDelta::FromSeconds(10)); } -NSString* WebTestWithWebState::EvaluateJavaScriptAsString(NSString* script) { - __block base::scoped_nsobject<NSString> evaluationResult; - [GetWebController(web_state()) - evaluateJavaScript:script - stringResultHandler:^(NSString* result, NSError*) { - DCHECK([result isKindOfClass:[NSString class]]); - evaluationResult.reset([result copy]); - }]; - base::test::ios::WaitUntilCondition(^bool() { - return evaluationResult; - }); - return [[evaluationResult retain] autorelease]; -} - id WebTestWithWebState::ExecuteJavaScript(NSString* script) { __block base::scoped_nsprotocol<id> executionResult; __block bool executionCompleted = false;
diff --git a/ios/web/public/web_state/js/crw_js_injection_manager.h b/ios/web/public/web_state/js/crw_js_injection_manager.h index a7deb01..f17539d7 100644 --- a/ios/web/public/web_state/js/crw_js_injection_manager.h +++ b/ios/web/public/web_state/js/crw_js_injection_manager.h
@@ -18,17 +18,6 @@ // Designated initializer. Initializes the object with the |receiver|. - (id)initWithReceiver:(CRWJSInjectionReceiver*)receiver; -// The array of |CRWJSInjectionManager| this class depends on. Default to be -// empty array. Note circular dependency is not allowed, which will cause stack -// overflow in dependency related computation such as -allDependencies. -- (NSArray*)directDependencies; - -// Returns a list of all the CRWJSInjectionManagers required by this manager, -// that is, this manager and the managers it directly or indirectly depends on. -// The list is ordered in such a way that any CRWJSInjectionManager in the list -// only depends on those appear before it in the list. -- (NSArray*)allDependencies; - // Returns whether JavaScript has already been injected into the receiver. - (BOOL)hasBeenInjected; @@ -36,13 +25,6 @@ // missing. It also injects the dependencies' JavaScript if they are missing. - (void)inject; -// Evaluates the provided JavaScript expression, slightly deferred. Designed for -// scripts where the chance of crwebinvoke:// being triggered indirectly is -// high, and that aren't required to return a value. -// DEPRECATED. TODO(crbug.com/595761): Remove this API which was created for -// UIWebView. -- (void)deferredEvaluate:(NSString*)script; - // Evaluate the provided JavaScript asynchronously calling completionHandler // after execution. The |completionHandler| can be nil. // DEPRECATED. TODO(crbug.com/595761): Remove this API. @@ -83,9 +65,6 @@ // is necessary, override injectionContent instead. - (NSString*)staticInjectionContent; -// Injects dependencies if they are missing. -- (void)injectDependenciesIfMissing; - @end #endif // IOS_WEB_PUBLIC_WEB_STATE_JS_CRW_JS_INJECTION_MANAGER_H_
diff --git a/ios/web/web_state/js/crw_js_injection_manager.mm b/ios/web/web_state/js/crw_js_injection_manager.mm index 92fa7352..9573606 100644 --- a/ios/web/web_state/js/crw_js_injection_manager.mm +++ b/ios/web/web_state/js/crw_js_injection_manager.mm
@@ -48,7 +48,6 @@ - (void)inject { if ([self hasBeenInjected]) return; - [self injectDependenciesIfMissing]; [_receiver injectScript:[self injectionContent] forClass:[self class]]; DCHECK([self hasBeenInjected]); } @@ -57,12 +56,6 @@ _injectObject.reset(); } -- (void)deferredEvaluate:(NSString*)script { - NSString* deferredScript = [NSString - stringWithFormat:@"window.setTimeout(function() {%@}, 0)", script]; - [self evaluate:deferredScript stringResultHandler:nil]; -} - - (void)evaluate:(NSString*)script stringResultHandler:(web::JavaScriptCompletion)completionHandler { [_receiver evaluateJavaScript:script stringResultHandler:completionHandler]; @@ -73,25 +66,6 @@ [_receiver executeJavaScript:script completionHandler:completionHandler]; } -- (NSArray*)directDependencies { - return @[]; -} - -- (NSArray*)allDependencies { - NSMutableArray* allDendencies = [NSMutableArray array]; - for (Class dependencyClass in [self directDependencies]) { - CRWJSInjectionManager* dependency = - [_receiver instanceOfClass:dependencyClass]; - NSArray* list = [dependency allDependencies]; - for (CRWJSInjectionManager* manager in list) { - if (![allDendencies containsObject:manager]) - [allDendencies addObject:manager]; - } - } - [allDendencies addObject:self]; - return allDendencies; -} - #pragma mark - #pragma mark ProtectedMethods @@ -114,12 +88,4 @@ return web::GetPageScript([self scriptPath]); } -- (void)injectDependenciesIfMissing { - for (Class dependencyClass in [self directDependencies]) { - CRWJSInjectionManager* dependency = - [_receiver instanceOfClass:dependencyClass]; - [dependency inject]; - } -} - @end
diff --git a/ios/web/web_state/js/crw_js_injection_manager_unittest.mm b/ios/web/web_state/js/crw_js_injection_manager_unittest.mm index 1ab804c5..f2386d8 100644 --- a/ios/web/web_state/js/crw_js_injection_manager_unittest.mm +++ b/ios/web/web_state/js/crw_js_injection_manager_unittest.mm
@@ -46,10 +46,6 @@ return @"base['testingjs'] = {};"; } -- (NSArray*)directDependencies { - return @[ [TestingCRWJSBaseManager class] ]; -} - @end // Testing class of JsInjectioManager that has dynamic content. @@ -82,10 +78,6 @@ return @"base['anothertestingjs'] = {};"; } -- (NSArray*)directDependencies { - return @[ [TestingCRWJSBaseManager class] ]; -} - @end @@ -99,10 +91,6 @@ return @"base['testingjswithnesteddependencies'] = {};"; } -- (NSArray*)directDependencies { - return @[[TestingJsManager class]]; -} - @end // Testing class of JsInjectioManager that has nested dependencies. @@ -115,14 +103,6 @@ return @"base['testingjswithnesteddependencies']['complex'] = {};"; } -- (NSArray*)directDependencies { - return @[ - [TestingJsManagerWithNestedDependencies class], - [TestingAnotherJsManager class], - [TestingAnotherCRWJSBaseManager class], - ]; -} - @end #pragma mark - @@ -142,9 +122,6 @@ CRWJSInjectionManager* GetInstanceOfClass(Class jsInjectionManagerClass); // Returns true if the receiver_ has all the managers in |managers|. bool HasReceiverManagers(NSArray* managers); - // EXPECTs that |actual| consists of the CRWJSInjectionManagers of the - // expected classes in a correct order. - void TestAllDependencies(NSArray* expected, NSArray* actual); }; bool JsInjectionManagerTest::HasReceiverManagers(NSArray* manager_classes) { @@ -157,25 +134,6 @@ return true; } -void JsInjectionManagerTest::TestAllDependencies(NSArray* expected_classes, - NSArray* actual) { - EXPECT_EQ([expected_classes count], [actual count]); - - for (Class manager_class in expected_classes) { - CRWJSInjectionManager* expected_manager = GetInstanceOfClass(manager_class); - EXPECT_TRUE([actual containsObject:expected_manager]); - } - - for (size_t index = 0; index < [actual count]; ++ index) { - CRWJSInjectionManager* manager = [actual objectAtIndex:index]; - for (Class manager_class in [manager directDependencies]) { - CRWJSInjectionManager* dependency = GetInstanceOfClass(manager_class); - size_t dependency_index = [actual indexOfObject:dependency]; - EXPECT_TRUE(index > dependency_index); - } - } -} - CRWJSInjectionManager* JsInjectionManagerTest::GetInstanceOfClass( Class jsInjectionManagerClass) { return [web_state()->GetJSInjectionReceiver() @@ -197,25 +155,6 @@ EXPECT_TRUE([manager hasBeenInjected]); } -TEST_F(JsInjectionManagerTest, HasDependencies) { - NSUInteger originalCount = - [[web_state()->GetJSInjectionReceiver() managers] count]; - CRWJSInjectionManager* manager = GetInstanceOfClass([TestingJsManager class]); - EXPECT_TRUE(manager); - EXPECT_EQ(originalCount + 2U, - [[web_state()->GetJSInjectionReceiver() managers] count]) - << "Two more CRWJSInjectionManagers should be created."; - EXPECT_TRUE(HasReceiverManagers( - @[ [TestingCRWJSBaseManager class], [TestingCRWJSBaseManager class] ])); - - EXPECT_FALSE([manager hasBeenInjected]); - - [manager inject]; - EXPECT_TRUE([manager hasBeenInjected]); - EXPECT_TRUE( - [GetInstanceOfClass([TestingCRWJSBaseManager class]) hasBeenInjected]); -} - TEST_F(JsInjectionManagerTest, Dynamic) { CRWJSInjectionManager* manager = GetInstanceOfClass([TestingDynamicJsManager class]); @@ -228,55 +167,10 @@ EXPECT_NSNE([manager injectionContent], [manager injectionContent]); } -TEST_F(JsInjectionManagerTest, HasNestedDependencies) { - NSUInteger originalCount = - [[web_state()->GetJSInjectionReceiver() managers] count]; - CRWJSInjectionManager* manager = - GetInstanceOfClass([TestingJsManagerWithNestedDependencies class]); - EXPECT_TRUE(manager); - EXPECT_EQ(originalCount + 3U, - [[web_state()->GetJSInjectionReceiver() managers] count]) - << "Three more CRWJSInjectionManagers should be created."; - EXPECT_TRUE(HasReceiverManagers(@[ - [TestingJsManagerWithNestedDependencies class], - [TestingCRWJSBaseManager class], [TestingCRWJSBaseManager class] - ])); - - EXPECT_FALSE([manager hasBeenInjected]); - - [manager inject]; - EXPECT_TRUE([manager hasBeenInjected]); - EXPECT_TRUE([GetInstanceOfClass([TestingJsManager class]) hasBeenInjected]); - EXPECT_TRUE( - [GetInstanceOfClass([TestingCRWJSBaseManager class]) hasBeenInjected]); - - NSArray* list = [manager allDependencies]; - TestAllDependencies( - @[ - [TestingCRWJSBaseManager class], [TestingJsManager class], - [TestingJsManagerWithNestedDependencies class] - ], - list); -} - // Tests that checking for an uninjected presence beacon returns false. TEST_F(JsInjectionManagerTest, WebControllerCheckForUninjectedScript) { EXPECT_FALSE([web_state()->GetJSInjectionReceiver() scriptHasBeenInjectedForClass:Nil]); } -TEST_F(JsInjectionManagerTest, AllDependencies) { - CRWJSInjectionManager* manager = - GetInstanceOfClass([TestingJsManagerComplex class]); - NSArray* list = [manager allDependencies]; - TestAllDependencies( - @[ - [TestingCRWJSBaseManager class], [TestingAnotherCRWJSBaseManager class], - [TestingJsManager class], [TestingAnotherJsManager class], - [TestingJsManagerWithNestedDependencies class], - [TestingJsManagerComplex class] - ], - list); -} - } // namespace web
diff --git a/ios/web/web_state/js/crw_js_injection_receiver.mm b/ios/web/web_state/js/crw_js_injection_receiver.mm index ffab34ea..698d5e9 100644 --- a/ios/web/web_state/js/crw_js_injection_receiver.mm +++ b/ios/web/web_state/js/crw_js_injection_receiver.mm
@@ -65,9 +65,6 @@ manager = newManager; } DCHECK(manager); - for (Class depedencyClass in [manager directDependencies]) { - [self instanceOfClass:depedencyClass]; - } return manager; }
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index b253921a..e204650 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -2318,6 +2318,27 @@ _webStateImpl->GetRequestTracker()->SetCacheModeFromUIThread( net::RequestTracker::CACHE_NORMAL); + // Rather than creating a new WKBackForwardListItem when loading WebUI pages, + // WKWebView will cache the WebUI HTML in the previous WKBackForwardListItem + // since it's loaded via |-loadHTML:forURL:| instead of an NSURLRequest. As a + // result, the WebUI's HTML and URL will be loaded when navigating to that + // WKBackForwardListItem, causing a mismatch between the visible content and + // the visible URL (WebUI page will be visible, but URL will be the previous + // page's URL). To prevent this potential URL spoofing vulnerability, reset + // the previous NavigationItem's WKBackForwardListItem to force loading via + // NSURLRequest. + if (_webUIManager) { + web::NavigationItem* lastNavigationItem = + self.sessionController.previousEntry.navigationItem; + if (lastNavigationItem) { + web::WKBackForwardListItemHolder* holder = + web::WKBackForwardListItemHolder::FromNavigationItem( + lastNavigationItem); + DCHECK(holder); + holder->set_back_forward_list_item(nil); + } + } + [self restoreStateFromHistory]; _webStateImpl->OnPageLoaded(currentURL, loadSuccess); _webStateImpl->SetIsLoading(false);
diff --git a/mash/app_driver/app_driver.cc b/mash/app_driver/app_driver.cc index db42859..60d6725 100644 --- a/mash/app_driver/app_driver.cc +++ b/mash/app_driver/app_driver.cc
@@ -62,7 +62,7 @@ AppDriver::~AppDriver() {} void AppDriver::OnAvailableCatalogEntries( - mojo::Array<catalog::mojom::EntryPtr> entries) { + std::vector<catalog::mojom::EntryPtr> entries) { if (entries.empty()) { LOG(ERROR) << "Unable to install accelerators for launching chrome."; return;
diff --git a/mash/app_driver/app_driver.h b/mash/app_driver/app_driver.h index 1664b175..ef70ca5 100644 --- a/mash/app_driver/app_driver.h +++ b/mash/app_driver/app_driver.h
@@ -27,7 +27,7 @@ ~AppDriver() override; private: - void OnAvailableCatalogEntries(mojo::Array<catalog::mojom::EntryPtr> entries); + void OnAvailableCatalogEntries(std::vector<catalog::mojom::EntryPtr> entries); // shell::Service: void OnStart(const shell::Identity& identity) override;
diff --git a/mash/catalog_viewer/catalog_viewer.cc b/mash/catalog_viewer/catalog_viewer.cc index 7af4a71d..d9d1b8e 100644 --- a/mash/catalog_viewer/catalog_viewer.cc +++ b/mash/catalog_viewer/catalog_viewer.cc
@@ -49,8 +49,8 @@ // We don't want to show an empty UI so we just block until we have all the // data. GetEntries is a sync call. - mojo::Array<catalog::mojom::EntryPtr> entries; - bool got = catalog_->GetEntries(nullptr, &entries); + std::vector<catalog::mojom::EntryPtr> entries; + bool got = catalog_->GetEntries(base::nullopt, &entries); if (got) { for (auto& entry : entries) entries_.push_back(Entry(entry->display_name, entry->name));
diff --git a/mash/login/BUILD.gn b/mash/login/BUILD.gn index d349352..7467c54 100644 --- a/mash/login/BUILD.gn +++ b/mash/login/BUILD.gn
@@ -24,6 +24,7 @@ "//services/shell/public/cpp", "//services/tracing/public/cpp", "//services/ui/public/cpp", + "//services/ui/public/interfaces", "//ui/views", "//ui/views/mus:for_mojo_application", ]
diff --git a/mash/quick_launch/quick_launch.cc b/mash/quick_launch/quick_launch.cc index 0c19334..337b39d 100644 --- a/mash/quick_launch/quick_launch.cc +++ b/mash/quick_launch/quick_launch.cc
@@ -126,9 +126,9 @@ base::Unretained(this))); } - void OnGotCatalogEntries(mojo::Array<catalog::mojom::EntryPtr> entries) { + void OnGotCatalogEntries(std::vector<catalog::mojom::EntryPtr> entries) { for (const auto& entry : entries) - app_names_.insert(base::UTF8ToUTF16(entry->name.get())); + app_names_.insert(base::UTF8ToUTF16(entry->name)); } void Launch(const std::string& name, bool new_window) {
diff --git a/mash/task_viewer/task_viewer.cc b/mash/task_viewer/task_viewer.cc index 68a04987..867fd6ee 100644 --- a/mash/task_viewer/task_viewer.cc +++ b/mash/task_viewer/task_viewer.cc
@@ -149,12 +149,13 @@ } // Overridden from shell::mojom::ServiceManagerListener: - void OnInit(mojo::Array<ServiceInfoPtr> instances) override { + void OnInit(std::vector<ServiceInfoPtr> instances) override { // This callback should only be called with an empty model. DCHECK(instances_.empty()); - mojo::Array<mojo::String> names; + std::vector<std::string> names; + names.reserve(instances.size()); for (size_t i = 0; i < instances.size(); ++i) { - shell::Identity identity = instances[i]->identity.To<shell::Identity>(); + const shell::Identity& identity = instances[i]->identity; InsertInstance(identity, instances[i]->pid); names.push_back(identity.name()); } @@ -163,19 +164,18 @@ weak_ptr_factory_.GetWeakPtr())); } void OnServiceCreated(ServiceInfoPtr instance) override { - shell::Identity identity = instance->identity.To<shell::Identity>(); + shell::Identity identity = instance->identity; DCHECK(!ContainsIdentity(identity)); InsertInstance(identity, instance->pid); observer_->OnItemsAdded(static_cast<int>(instances_.size()), 1); - mojo::Array<mojo::String> names; + std::vector<std::string> names; names.push_back(identity.name()); catalog_->GetEntries(std::move(names), base::Bind(&TaskViewerContents::OnGotCatalogEntries, weak_ptr_factory_.GetWeakPtr())); } - void OnServiceStarted(shell::mojom::IdentityPtr identity_ptr, + void OnServiceStarted(const shell::Identity& identity, uint32_t pid) override { - shell::Identity identity = identity_ptr.To<shell::Identity>(); for (auto it = instances_.begin(); it != instances_.end(); ++it) { if ((*it)->identity == identity) { (*it)->pid = pid; @@ -185,8 +185,7 @@ } } } - void OnServiceStopped(shell::mojom::IdentityPtr identity_ptr) override { - shell::Identity identity = identity_ptr.To<shell::Identity>(); + void OnServiceStopped(const shell::Identity& identity) override { for (auto it = instances_.begin(); it != instances_.end(); ++it) { if ((*it)->identity == identity) { observer_->OnItemsRemoved( @@ -211,7 +210,7 @@ base::WrapUnique(new InstanceInfo(identity, pid))); } - void OnGotCatalogEntries(mojo::Array<catalog::mojom::EntryPtr> entries) { + void OnGotCatalogEntries(std::vector<catalog::mojom::EntryPtr> entries) { for (auto it = instances_.begin(); it != instances_.end(); ++it) { for (auto& entry : entries) { if (entry->name == (*it)->identity.name()) {
diff --git a/media/base/BUILD.gn b/media/base/BUILD.gn index c1dbdca..0b54b3c 100644 --- a/media/base/BUILD.gn +++ b/media/base/BUILD.gn
@@ -160,6 +160,8 @@ "media_track.h", "media_tracks.cc", "media_tracks.h", + "media_url_demuxer.cc", + "media_url_demuxer.h", "media_util.cc", "media_util.h", "mime_util.cc", @@ -448,6 +450,7 @@ "feedback_signal_accumulator_unittest.cc", "gmock_callback_support_unittest.cc", "key_systems_unittest.cc", + "media_url_demuxer_unittest.cc", "mime_util_unittest.cc", "moving_average_unittest.cc", "multi_channel_resampler_unittest.cc",
diff --git a/media/base/android/BUILD.gn b/media/base/android/BUILD.gn index a552319..2a82d328 100644 --- a/media/base/android/BUILD.gn +++ b/media/base/android/BUILD.gn
@@ -97,8 +97,6 @@ "media_statistics.h", "media_task_runner.cc", "media_task_runner.h", - "media_url_demuxer.cc", - "media_url_demuxer.h", "media_url_interceptor.h", "provision_fetcher.h", "sdk_media_codec_bridge.cc", @@ -134,7 +132,6 @@ "media_drm_bridge_unittest.cc", "media_player_bridge_unittest.cc", "media_source_player_unittest.cc", - "media_url_demuxer_unittest.cc", "sdk_media_codec_bridge_unittest.cc", "test_data_factory.cc", "test_data_factory.h",
diff --git a/media/base/android/access_unit_queue.cc b/media/base/android/access_unit_queue.cc index 151e4aa8..b98c89b1 100644 --- a/media/base/android/access_unit_queue.cc +++ b/media/base/android/access_unit_queue.cc
@@ -25,7 +25,7 @@ } AccessUnitQueue::~AccessUnitQueue() { - STLDeleteContainerPointers(chunks_.begin(), chunks_.end()); + base::STLDeleteContainerPointers(chunks_.begin(), chunks_.end()); } void AccessUnitQueue::PushBack(const DemuxerData& data) { @@ -108,7 +108,7 @@ if (num_consumed_chunks > history_chunks_amount_) { DataChunkQueue::iterator first_to_keep = chunks_.begin(); std::advance(first_to_keep, num_consumed_chunks - history_chunks_amount_); - STLDeleteContainerPointers(chunks_.begin(), first_to_keep); + base::STLDeleteContainerPointers(chunks_.begin(), first_to_keep); chunks_.erase(chunks_.begin(), first_to_keep); } } @@ -117,7 +117,7 @@ // Media thread base::AutoLock lock(lock_); - STLDeleteContainerPointers(chunks_.begin(), chunks_.end()); + base::STLDeleteContainerPointers(chunks_.begin(), chunks_.end()); chunks_.clear(); current_chunk_ = chunks_.end();
diff --git a/media/base/android/media_url_demuxer.cc b/media/base/android/media_url_demuxer.cc deleted file mode 100644 index d4e23e0a..0000000 --- a/media/base/android/media_url_demuxer.cc +++ /dev/null
@@ -1,78 +0,0 @@ -// Copyright 2016 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 "media/base/android/media_url_demuxer.h" - -#include "base/bind.h" - -namespace media { - -MediaUrlDemuxer::MediaUrlDemuxer( - const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, - const GURL& url) - : url_(url), task_runner_(task_runner) {} - -MediaUrlDemuxer::~MediaUrlDemuxer() {} - -// Should never be called since DemuxerStreamProvider::Type is URL. -DemuxerStream* MediaUrlDemuxer::GetStream(DemuxerStream::Type type) { - NOTREACHED(); - return nullptr; -} - -GURL MediaUrlDemuxer::GetUrl() const { - return url_; -} - -DemuxerStreamProvider::Type MediaUrlDemuxer::GetType() const { - return DemuxerStreamProvider::Type::URL; -} - -std::string MediaUrlDemuxer::GetDisplayName() const { - return "MediaUrlDemuxer"; -} - -void MediaUrlDemuxer::Initialize(DemuxerHost* host, - const PipelineStatusCB& status_cb, - bool enable_text_tracks) { - DVLOG(1) << __FUNCTION__; - task_runner_->PostTask(FROM_HERE, base::Bind(status_cb, PIPELINE_OK)); -} - -void MediaUrlDemuxer::StartWaitingForSeek(base::TimeDelta seek_time) {} - -void MediaUrlDemuxer::CancelPendingSeek(base::TimeDelta seek_time) {} - -void MediaUrlDemuxer::Seek(base::TimeDelta time, - const PipelineStatusCB& status_cb) { - task_runner_->PostTask(FROM_HERE, base::Bind(status_cb, PIPELINE_OK)); -} - -void MediaUrlDemuxer::Stop() {} - -base::TimeDelta MediaUrlDemuxer::GetStartTime() const { - // TODO(tguilbert): Investigate if we need to fetch information from the - // MediaPlayerRender in order to return a sensible value here. - return base::TimeDelta(); -} -base::Time MediaUrlDemuxer::GetTimelineOffset() const { - return base::Time(); -} - -int64_t MediaUrlDemuxer::GetMemoryUsage() const { - return 0; -} - -void MediaUrlDemuxer::OnEnabledAudioTracksChanged( - const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta currTime) { - NOTIMPLEMENTED(); -} -void MediaUrlDemuxer::OnSelectedVideoTrackChanged( - const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta currTime) { - NOTIMPLEMENTED(); -} - -} // namespace media
diff --git a/media/base/android/media_url_demuxer.h b/media/base/android/media_url_demuxer.h deleted file mode 100644 index dbd8ee6..0000000 --- a/media/base/android/media_url_demuxer.h +++ /dev/null
@@ -1,68 +0,0 @@ -// Copyright 2016 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 MEDIA_BASE_ANDROID_MEDIA_URL_DEMUXER_H_ -#define MEDIA_BASE_ANDROID_MEDIA_URL_DEMUXER_H_ - -#include <stddef.h> - -#include "base/callback.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "media/base/demuxer.h" -#include "url/gurl.h" - -namespace media { - -// Class that saves a URL for later retrieval. To be used in conjunction with -// the MediaPlayerRenderer. -// -// Its primary purpose is to act as a dummy Demuxer, when there is no need -// for DemuxerStreams (e.g. in the MediaPlayerRenderer case). For the most part, -// its implementation of the Demuxer are NOPs that return the default values and -// fire any provided callbacks immediately. -// -// If Pipeline where to be refactored to use a DemuxerStreamProvider instead of -// a Demuxer, MediaUrlDemuxer should be refactored to inherit directly from -// DemuxerStreamProvider. -class MediaUrlDemuxer : public Demuxer { - public: - MediaUrlDemuxer( - const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, - const GURL& url); - ~MediaUrlDemuxer() override; - - // DemuxerStreamProvider interface. - DemuxerStream* GetStream(DemuxerStream::Type type) override; - GURL GetUrl() const override; - DemuxerStreamProvider::Type GetType() const override; - - // Demuxer interface. - std::string GetDisplayName() const override; - void Initialize(DemuxerHost* host, - const PipelineStatusCB& status_cb, - bool enable_text_tracks) override; - void StartWaitingForSeek(base::TimeDelta seek_time) override; - void CancelPendingSeek(base::TimeDelta seek_time) override; - void Seek(base::TimeDelta time, const PipelineStatusCB& status_cb) override; - void Stop() override; - base::TimeDelta GetStartTime() const override; - base::Time GetTimelineOffset() const override; - int64_t GetMemoryUsage() const override; - void OnEnabledAudioTracksChanged(const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta currTime) override; - void OnSelectedVideoTrackChanged(const std::vector<MediaTrack::Id>& track_ids, - base::TimeDelta currTime) override; - - private: - GURL url_; - - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - - DISALLOW_COPY_AND_ASSIGN(MediaUrlDemuxer); -}; - -} // namespace media - -#endif // MEDIA_BASE_ANDROID_MEDIA_URL_DEMUXER_H_
diff --git a/media/base/android/media_url_demuxer_unittest.cc b/media/base/android/media_url_demuxer_unittest.cc deleted file mode 100644 index 495ed2f4..0000000 --- a/media/base/android/media_url_demuxer_unittest.cc +++ /dev/null
@@ -1,73 +0,0 @@ -// Copyright 2016 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/bind_helpers.h" -#include "base/macros.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/run_loop.h" -#include "media/base/android/media_url_demuxer.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace media { - -class MediaUrlDemuxerTest : public testing::Test { - public: - MediaUrlDemuxerTest() : default_url_("http://example.com/") {} - - void InitializeTest(const GURL& gurl) { - demuxer_.reset( - new MediaUrlDemuxer(base::ThreadTaskRunnerHandle::Get(), gurl)); - } - - void InitializeTest() { InitializeTest(default_url_); } - - void VerifyCallbackOk(PipelineStatus status) { - EXPECT_EQ(PIPELINE_OK, status); - } - - GURL default_url_; - std::unique_ptr<Demuxer> demuxer_; - - // Necessary, or else base::ThreadTaskRunnerHandle::Get() fails. - base::MessageLoop message_loop_; - - private: - DISALLOW_COPY_AND_ASSIGN(MediaUrlDemuxerTest); -}; - -TEST_F(MediaUrlDemuxerTest, BaseCase) { - InitializeTest(); - - EXPECT_EQ(DemuxerStreamProvider::Type::URL, demuxer_->GetType()); - EXPECT_EQ(default_url_, demuxer_->GetUrl()); -} - -TEST_F(MediaUrlDemuxerTest, AcceptsEmptyStrings) { - InitializeTest(GURL()); - - EXPECT_EQ(GURL::EmptyGURL(), demuxer_->GetUrl()); -} - -TEST_F(MediaUrlDemuxerTest, InitializeReturnsPipelineOk) { - InitializeTest(); - demuxer_->Initialize(nullptr, - base::Bind(&MediaUrlDemuxerTest::VerifyCallbackOk, - base::Unretained(this)), - false); - - base::RunLoop().RunUntilIdle(); -} - -TEST_F(MediaUrlDemuxerTest, SeekReturnsPipelineOk) { - InitializeTest(); - demuxer_->Seek(base::TimeDelta(), - base::Bind(&MediaUrlDemuxerTest::VerifyCallbackOk, - base::Unretained(this))); - - base::RunLoop().RunUntilIdle(); -} - -} // namespace media
diff --git a/media/base/media_log.cc b/media/base/media_log.cc index 546eb450..f86b4cee 100644 --- a/media/base/media_log.cc +++ b/media/base/media_log.cc
@@ -101,6 +101,8 @@ return "pipeline: initialization failed"; case PIPELINE_ERROR_COULD_NOT_RENDER: return "pipeline: could not render"; + case PIPELINE_ERROR_EXTERNAL_RENDERER_FAILED: + return "pipeline: external renderer failed"; case PIPELINE_ERROR_READ: return "pipeline: read error"; case PIPELINE_ERROR_INVALID_STATE:
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index a292246..8c796e7 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -167,5 +167,8 @@ // Use shared block-based buffering for media. const base::Feature kUseNewMediaCache{"use-new-media-cache", base::FEATURE_ENABLED_BY_DEFAULT}; +// Correct video colors based on output display? +const base::Feature kVideoColorManagement{"video-color-management", + base::FEATURE_DISABLED_BY_DEFAULT}; } // namespace media
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index 8e60f8f1..c9a1888 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -88,6 +88,7 @@ MEDIA_EXPORT extern const base::Feature kNewAudioRenderingMixingStrategy; MEDIA_EXPORT extern const base::Feature kResumeBackgroundVideo; MEDIA_EXPORT extern const base::Feature kUseNewMediaCache; +MEDIA_EXPORT extern const base::Feature kVideoColorManagement; } // namespace media
diff --git a/media/base/media_url_demuxer.cc b/media/base/media_url_demuxer.cc new file mode 100644 index 0000000..4f49f9a --- /dev/null +++ b/media/base/media_url_demuxer.cc
@@ -0,0 +1,78 @@ +// Copyright 2016 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 "media/base/media_url_demuxer.h" + +#include "base/bind.h" + +namespace media { + +MediaUrlDemuxer::MediaUrlDemuxer( + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, + const GURL& url) + : url_(url), task_runner_(task_runner) {} + +MediaUrlDemuxer::~MediaUrlDemuxer() {} + +// Should never be called since DemuxerStreamProvider::Type is URL. +DemuxerStream* MediaUrlDemuxer::GetStream(DemuxerStream::Type type) { + NOTREACHED(); + return nullptr; +} + +GURL MediaUrlDemuxer::GetUrl() const { + return url_; +} + +DemuxerStreamProvider::Type MediaUrlDemuxer::GetType() const { + return DemuxerStreamProvider::Type::URL; +} + +std::string MediaUrlDemuxer::GetDisplayName() const { + return "MediaUrlDemuxer"; +} + +void MediaUrlDemuxer::Initialize(DemuxerHost* host, + const PipelineStatusCB& status_cb, + bool enable_text_tracks) { + DVLOG(1) << __FUNCTION__; + task_runner_->PostTask(FROM_HERE, base::Bind(status_cb, PIPELINE_OK)); +} + +void MediaUrlDemuxer::StartWaitingForSeek(base::TimeDelta seek_time) {} + +void MediaUrlDemuxer::CancelPendingSeek(base::TimeDelta seek_time) {} + +void MediaUrlDemuxer::Seek(base::TimeDelta time, + const PipelineStatusCB& status_cb) { + task_runner_->PostTask(FROM_HERE, base::Bind(status_cb, PIPELINE_OK)); +} + +void MediaUrlDemuxer::Stop() {} + +base::TimeDelta MediaUrlDemuxer::GetStartTime() const { + // TODO(tguilbert): Investigate if we need to fetch information from the + // MediaPlayerRender in order to return a sensible value here. + return base::TimeDelta(); +} +base::Time MediaUrlDemuxer::GetTimelineOffset() const { + return base::Time(); +} + +int64_t MediaUrlDemuxer::GetMemoryUsage() const { + return 0; +} + +void MediaUrlDemuxer::OnEnabledAudioTracksChanged( + const std::vector<MediaTrack::Id>& track_ids, + base::TimeDelta currTime) { + NOTIMPLEMENTED(); +} +void MediaUrlDemuxer::OnSelectedVideoTrackChanged( + const std::vector<MediaTrack::Id>& track_ids, + base::TimeDelta currTime) { + NOTIMPLEMENTED(); +} + +} // namespace media
diff --git a/media/base/media_url_demuxer.h b/media/base/media_url_demuxer.h new file mode 100644 index 0000000..e110ac9 --- /dev/null +++ b/media/base/media_url_demuxer.h
@@ -0,0 +1,68 @@ +// Copyright 2016 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 MEDIA_BASE_MEDIA_URL_DEMUXER_H_ +#define MEDIA_BASE_MEDIA_URL_DEMUXER_H_ + +#include <stddef.h> + +#include "base/callback.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "media/base/demuxer.h" +#include "url/gurl.h" + +namespace media { + +// Class that saves a URL for later retrieval. To be used in conjunction with +// the MediaPlayerRenderer. +// +// Its primary purpose is to act as a dummy Demuxer, when there is no need +// for DemuxerStreams (e.g. in the MediaPlayerRenderer case). For the most part, +// its implementation of the Demuxer are NOPs that return the default values and +// fire any provided callbacks immediately. +// +// If Pipeline where to be refactored to use a DemuxerStreamProvider instead of +// a Demuxer, MediaUrlDemuxer should be refactored to inherit directly from +// DemuxerStreamProvider. +class MEDIA_EXPORT MediaUrlDemuxer : public Demuxer { + public: + MediaUrlDemuxer( + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, + const GURL& url); + ~MediaUrlDemuxer() override; + + // DemuxerStreamProvider interface. + DemuxerStream* GetStream(DemuxerStream::Type type) override; + GURL GetUrl() const override; + DemuxerStreamProvider::Type GetType() const override; + + // Demuxer interface. + std::string GetDisplayName() const override; + void Initialize(DemuxerHost* host, + const PipelineStatusCB& status_cb, + bool enable_text_tracks) override; + void StartWaitingForSeek(base::TimeDelta seek_time) override; + void CancelPendingSeek(base::TimeDelta seek_time) override; + void Seek(base::TimeDelta time, const PipelineStatusCB& status_cb) override; + void Stop() override; + base::TimeDelta GetStartTime() const override; + base::Time GetTimelineOffset() const override; + int64_t GetMemoryUsage() const override; + void OnEnabledAudioTracksChanged(const std::vector<MediaTrack::Id>& track_ids, + base::TimeDelta currTime) override; + void OnSelectedVideoTrackChanged(const std::vector<MediaTrack::Id>& track_ids, + base::TimeDelta currTime) override; + + private: + GURL url_; + + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + + DISALLOW_COPY_AND_ASSIGN(MediaUrlDemuxer); +}; + +} // namespace media + +#endif // MEDIA_BASE_MEDIA_URL_DEMUXER_H_
diff --git a/media/base/media_url_demuxer_unittest.cc b/media/base/media_url_demuxer_unittest.cc new file mode 100644 index 0000000..b5cd4866 --- /dev/null +++ b/media/base/media_url_demuxer_unittest.cc
@@ -0,0 +1,74 @@ +// Copyright 2016 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 "media/base/media_url_demuxer.h" + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/macros.h" +#include "base/run_loop.h" +#include "base/threading/thread_task_runner_handle.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace media { + +class MediaUrlDemuxerTest : public testing::Test { + public: + MediaUrlDemuxerTest() : default_url_("http://example.com/") {} + + void InitializeTest(const GURL& gurl) { + demuxer_.reset( + new MediaUrlDemuxer(base::ThreadTaskRunnerHandle::Get(), gurl)); + } + + void InitializeTest() { InitializeTest(default_url_); } + + void VerifyCallbackOk(PipelineStatus status) { + EXPECT_EQ(PIPELINE_OK, status); + } + + GURL default_url_; + std::unique_ptr<Demuxer> demuxer_; + + // Necessary, or else base::ThreadTaskRunnerHandle::Get() fails. + base::MessageLoop message_loop_; + + private: + DISALLOW_COPY_AND_ASSIGN(MediaUrlDemuxerTest); +}; + +TEST_F(MediaUrlDemuxerTest, BaseCase) { + InitializeTest(); + + EXPECT_EQ(DemuxerStreamProvider::Type::URL, demuxer_->GetType()); + EXPECT_EQ(default_url_, demuxer_->GetUrl()); +} + +TEST_F(MediaUrlDemuxerTest, AcceptsEmptyStrings) { + InitializeTest(GURL()); + + EXPECT_EQ(GURL::EmptyGURL(), demuxer_->GetUrl()); +} + +TEST_F(MediaUrlDemuxerTest, InitializeReturnsPipelineOk) { + InitializeTest(); + demuxer_->Initialize(nullptr, + base::Bind(&MediaUrlDemuxerTest::VerifyCallbackOk, + base::Unretained(this)), + false); + + base::RunLoop().RunUntilIdle(); +} + +TEST_F(MediaUrlDemuxerTest, SeekReturnsPipelineOk) { + InitializeTest(); + demuxer_->Seek(base::TimeDelta(), + base::Bind(&MediaUrlDemuxerTest::VerifyCallbackOk, + base::Unretained(this))); + + base::RunLoop().RunUntilIdle(); +} + +} // namespace media
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h index 598860f..08c1454 100644 --- a/media/base/mock_filters.h +++ b/media/base/mock_filters.h
@@ -226,6 +226,7 @@ MOCK_METHOD0(OnWaitingForDecryptionKey, void()); MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size&)); MOCK_METHOD1(OnVideoOpacityChange, void(bool)); + MOCK_METHOD1(OnDurationChange, void(base::TimeDelta)); }; class MockVideoRenderer : public VideoRenderer {
diff --git a/media/base/null_video_sink.cc b/media/base/null_video_sink.cc index f390986..6e03e53 100644 --- a/media/base/null_video_sink.cc +++ b/media/base/null_video_sink.cc
@@ -88,8 +88,9 @@ delay); } -void NullVideoSink::PaintSingleFrame(const scoped_refptr<VideoFrame>& frame) { - if (frame == last_frame_) +void NullVideoSink::PaintSingleFrame(const scoped_refptr<VideoFrame>& frame, + bool repaint_duplicate_frame) { + if (!repaint_duplicate_frame && frame == last_frame_) return; last_frame_ = frame; new_frame_cb_.Run(frame);
diff --git a/media/base/null_video_sink.h b/media/base/null_video_sink.h index 25a74070..11e4189 100644 --- a/media/base/null_video_sink.h +++ b/media/base/null_video_sink.h
@@ -35,7 +35,8 @@ // VideoRendererSink implementation. void Start(RenderCallback* callback) override; void Stop() override; - void PaintSingleFrame(const scoped_refptr<VideoFrame>& frame) override; + void PaintSingleFrame(const scoped_refptr<VideoFrame>& frame, + bool repaint_duplicate_frame) override; void set_tick_clock_for_testing(base::TickClock* tick_clock) { tick_clock_ = tick_clock;
diff --git a/media/base/null_video_sink_unittest.cc b/media/base/null_video_sink_unittest.cc index 4fc5ed7..1c6ff4b 100644 --- a/media/base/null_video_sink_unittest.cc +++ b/media/base/null_video_sink_unittest.cc
@@ -114,7 +114,7 @@ // The sink shouldn't have to be started to use the paint method. EXPECT_CALL(*this, FrameReceived(test_frame)); - sink->PaintSingleFrame(test_frame); + sink->PaintSingleFrame(test_frame, false); } TEST_F(NullVideoSinkTest, ClocklessFunctionality) {
diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc index 38a835b1..43fdf5e 100644 --- a/media/base/pipeline_impl.cc +++ b/media/base/pipeline_impl.cc
@@ -113,6 +113,7 @@ void OnWaitingForDecryptionKey() final; void OnVideoNaturalSizeChange(const gfx::Size& size) final; void OnVideoOpacityChange(bool opaque) final; + void OnDurationChange(base::TimeDelta duration) final; // TextRenderer tasks and notifications. void OnTextRendererEnded(); @@ -658,6 +659,11 @@ base::Bind(&PipelineImpl::OnVideoOpacityChange, weak_pipeline_, opaque)); } +void PipelineImpl::RendererWrapper::OnDurationChange(base::TimeDelta duration) { + DCHECK(media_task_runner_->BelongsToCurrentThread()); + SetDuration(duration); +} + void PipelineImpl::RendererWrapper::OnTextRendererEnded() { DCHECK(media_task_runner_->BelongsToCurrentThread()); media_log_->AddEvent(media_log_->CreateEvent(MediaLogEvent::TEXT_ENDED));
diff --git a/media/base/pipeline_status.h b/media/base/pipeline_status.h index 2f4b359..4df7ddb 100644 --- a/media/base/pipeline_status.h +++ b/media/base/pipeline_status.h
@@ -27,6 +27,7 @@ PIPELINE_ERROR_READ = 9, // Deprecated: PIPELINE_ERROR_OPERATION_PENDING = 10, PIPELINE_ERROR_INVALID_STATE = 11, + PIPELINE_ERROR_EXTERNAL_RENDERER_FAILED = 21, // Demuxer related errors. DEMUXER_ERROR_COULD_NOT_OPEN = 12, @@ -46,7 +47,7 @@ AUDIO_RENDERER_ERROR_SPLICE_FAILED = 20, // Must be equal to the largest value ever logged. - PIPELINE_STATUS_MAX = AUDIO_RENDERER_ERROR_SPLICE_FAILED, + PIPELINE_STATUS_MAX = PIPELINE_ERROR_EXTERNAL_RENDERER_FAILED, }; typedef base::Callback<void(PipelineStatus)> PipelineStatusCB;
diff --git a/media/base/renderer_client.h b/media/base/renderer_client.h index 49b098e..402c31b 100644 --- a/media/base/renderer_client.h +++ b/media/base/renderer_client.h
@@ -5,13 +5,14 @@ #ifndef MEDIA_BASE_RENDERER_CLIENT_H_ #define MEDIA_BASE_RENDERER_CLIENT_H_ +#include "base/time/time.h" #include "media/base/pipeline_status.h" #include "ui/gfx/geometry/size.h" namespace media { -// Interface used by Renderer, AudioRenderer, and VideoRenderer implementations -// to notify their clients. +// Interface used by Renderer, AudioRenderer, VideoRenderer and +// MediaPlayerRenderer implementations to notify their clients. class RendererClient { public: // Executed if any error was encountered after Renderer initialization. @@ -36,6 +37,10 @@ // Executed for the first video frame and whenever opacity changes. // Only used if media stream contains video track. virtual void OnVideoOpacityChange(bool opaque) = 0; + + // Executed when video metadata is first read, and whenever it changes. + // Only used when we are using a URL demuxer (e.g. for MediaPlayerRenderer). + virtual void OnDurationChange(base::TimeDelta duration) = 0; }; } // namespace media
diff --git a/media/base/text_renderer.cc b/media/base/text_renderer.cc index 902a53a..4c688c8 100644 --- a/media/base/text_renderer.cc +++ b/media/base/text_renderer.cc
@@ -30,7 +30,7 @@ TextRenderer::~TextRenderer() { DCHECK(task_runner_->BelongsToCurrentThread()); - STLDeleteValues(&text_track_state_map_); + base::STLDeleteValues(&text_track_state_map_); if (!pause_cb_.is_null()) base::ResetAndReturn(&pause_cb_).Run(); }
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc index f0b4367..661550e5 100644 --- a/media/base/video_frame.cc +++ b/media/base/video_frame.cc
@@ -653,21 +653,27 @@ } gfx::ColorSpace VideoFrame::ColorSpace() const { - int videoframe_color_space; - if (metadata()->GetInteger(media::VideoFrameMetadata::COLOR_SPACE, - &videoframe_color_space)) { - switch (videoframe_color_space) { - case media::COLOR_SPACE_JPEG: - return gfx::ColorSpace::CreateJpeg(); - case media::COLOR_SPACE_HD_REC709: - return gfx::ColorSpace::CreateREC709(); - case media::COLOR_SPACE_SD_REC601: - return gfx::ColorSpace::CreateREC601(); - default: - break; + if (color_space_ == gfx::ColorSpace()) { + int videoframe_color_space; + if (metadata()->GetInteger(media::VideoFrameMetadata::COLOR_SPACE, + &videoframe_color_space)) { + switch (videoframe_color_space) { + case media::COLOR_SPACE_JPEG: + return gfx::ColorSpace::CreateJpeg(); + case media::COLOR_SPACE_HD_REC709: + return gfx::ColorSpace::CreateREC709(); + case media::COLOR_SPACE_SD_REC601: + return gfx::ColorSpace::CreateREC601(); + default: + break; + } } } - return gfx::ColorSpace(); + return color_space_; +} + +void VideoFrame::set_color_space(const gfx::ColorSpace& color_space) { + color_space_ = color_space; } int VideoFrame::stride(size_t plane) const {
diff --git a/media/base/video_frame.h b/media/base/video_frame.h index e85d30d..4d08c39 100644 --- a/media/base/video_frame.h +++ b/media/base/video_frame.h
@@ -325,6 +325,7 @@ // Returns the color space of this frame's content. gfx::ColorSpace ColorSpace() const; + void set_color_space(const gfx::ColorSpace& color_space); VideoPixelFormat format() const { return format_; } StorageType storage_type() const { return storage_type_; } @@ -578,6 +579,8 @@ // Generated at construction time. const int unique_id_; + gfx::ColorSpace color_space_; + DISALLOW_IMPLICIT_CONSTRUCTORS(VideoFrame); };
diff --git a/media/base/video_renderer_sink.h b/media/base/video_renderer_sink.h index f8e64bf..5670f04 100644 --- a/media/base/video_renderer_sink.h +++ b/media/base/video_renderer_sink.h
@@ -58,7 +58,8 @@ // useful for painting poster images or hole frames without having to issue a // Start() -> Render() -> Stop(). Clients are free to mix usage of Render() // based painting and PaintSingleFrame(). - virtual void PaintSingleFrame(const scoped_refptr<VideoFrame>& frame) = 0; + virtual void PaintSingleFrame(const scoped_refptr<VideoFrame>& frame, + bool repaint_duplicate_frame = false) = 0; virtual ~VideoRendererSink() {} };
diff --git a/media/blink/cdm_session_adapter.cc b/media/blink/cdm_session_adapter.cc index 4558bbe..49694a9d 100644 --- a/media/blink/cdm_session_adapter.cc +++ b/media/blink/cdm_session_adapter.cc
@@ -77,7 +77,7 @@ const std::string& session_id, base::WeakPtr<WebContentDecryptionModuleSessionImpl> session) { // If this session ID is already registered, don't register it again. - if (ContainsKey(sessions_, session_id)) + if (base::ContainsKey(sessions_, session_id)) return false; sessions_[session_id] = session; @@ -85,7 +85,7 @@ } void CdmSessionAdapter::UnregisterSession(const std::string& session_id) { - DCHECK(ContainsKey(sessions_, session_id)); + DCHECK(base::ContainsKey(sessions_, session_id)); sessions_.erase(session_id); }
diff --git a/media/blink/video_frame_compositor.cc b/media/blink/video_frame_compositor.cc index 3cf2a1c..fb59ba4b 100644 --- a/media/blink/video_frame_compositor.cc +++ b/media/blink/video_frame_compositor.cc
@@ -105,7 +105,7 @@ } void VideoFrameCompositor::Start(RenderCallback* callback) { - TRACE_EVENT0("media", "VideoFrameCompositor::Start"); + TRACE_EVENT0("media,rail", "VideoFrameCompositor::Start"); // Called from the media thread, so acquire the callback under lock before // returning in case a Stop() call comes in before the PostTask is processed. @@ -118,7 +118,7 @@ } void VideoFrameCompositor::Stop() { - TRACE_EVENT0("media", "VideoFrameCompositor::Stop"); + TRACE_EVENT0("media,rail", "VideoFrameCompositor::Stop"); // Called from the media thread, so release the callback under lock before // returning to avoid a pending UpdateCurrentFrame() call occurring before @@ -132,15 +132,17 @@ } void VideoFrameCompositor::PaintSingleFrame( - const scoped_refptr<VideoFrame>& frame) { + const scoped_refptr<VideoFrame>& frame, + bool repaint_duplicate_frame) { if (!compositor_task_runner_->BelongsToCurrentThread()) { compositor_task_runner_->PostTask( - FROM_HERE, base::Bind(&VideoFrameCompositor::PaintSingleFrame, - base::Unretained(this), frame)); + FROM_HERE, + base::Bind(&VideoFrameCompositor::PaintSingleFrame, + base::Unretained(this), frame, repaint_duplicate_frame)); return; } - if (ProcessNewFrame(frame) && client_) + if (ProcessNewFrame(frame, repaint_duplicate_frame) && client_) client_->DidReceiveFrame(); } @@ -178,10 +180,11 @@ } bool VideoFrameCompositor::ProcessNewFrame( - const scoped_refptr<VideoFrame>& frame) { + const scoped_refptr<VideoFrame>& frame, + bool repaint_duplicate_frame) { DCHECK(compositor_task_runner_->BelongsToCurrentThread()); - if (frame == current_frame_) + if (!repaint_duplicate_frame && frame == current_frame_) return false; // Set the flag indicating that the current frame is unrendered, if we get a @@ -223,7 +226,8 @@ } const bool new_frame = ProcessNewFrame( - callback_->Render(deadline_min, deadline_max, background_rendering)); + callback_->Render(deadline_min, deadline_max, background_rendering), + false); // We may create a new frame here with background rendering, but the provider // has no way of knowing that a new frame had been processed, so keep track of
diff --git a/media/blink/video_frame_compositor.h b/media/blink/video_frame_compositor.h index 68a4d79..9bb79fd 100644 --- a/media/blink/video_frame_compositor.h +++ b/media/blink/video_frame_compositor.h
@@ -75,7 +75,8 @@ // same thread (typically the media thread). void Start(RenderCallback* callback) override; void Stop() override; - void PaintSingleFrame(const scoped_refptr<VideoFrame>& frame) override; + void PaintSingleFrame(const scoped_refptr<VideoFrame>& frame, + bool repaint_duplicate_frame = false) override; // Returns |current_frame_| if |client_| is set. If no |client_| is set, // |is_background_rendering_| is true, and |callback_| is set, it requests a @@ -116,7 +117,8 @@ void OnRendererStateUpdate(bool new_state); // Handles setting of |current_frame_|. - bool ProcessNewFrame(const scoped_refptr<VideoFrame>& frame); + bool ProcessNewFrame(const scoped_refptr<VideoFrame>& frame, + bool repaint_duplicate_frame); // Called by |background_rendering_timer_| when enough time elapses where we // haven't seen a Render() call.
diff --git a/media/blink/webmediaplayer_util.cc b/media/blink/webmediaplayer_util.cc index 77c1c47..2b3a044 100644 --- a/media/blink/webmediaplayer_util.cc +++ b/media/blink/webmediaplayer_util.cc
@@ -37,6 +37,7 @@ case PIPELINE_ERROR_INITIALIZATION_FAILED: case PIPELINE_ERROR_COULD_NOT_RENDER: + case PIPELINE_ERROR_EXTERNAL_RENDERER_FAILED: case DEMUXER_ERROR_COULD_NOT_OPEN: case DEMUXER_ERROR_COULD_NOT_PARSE: case DEMUXER_ERROR_NO_SUPPORTED_STREAMS:
diff --git a/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera2.java b/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera2.java index e4da6be..311fd24d 100644 --- a/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera2.java +++ b/media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera2.java
@@ -88,7 +88,8 @@ // time a downloaded image is ready. Since |handler| is null, we'll work on the // current Thread Looper. mPreviewSession.setRepeatingRequest(mPreviewRequest, null, null); - } catch (CameraAccessException | IllegalArgumentException | SecurityException ex) { + } catch (CameraAccessException | SecurityException | IllegalStateException + | IllegalArgumentException ex) { Log.e(TAG, "setRepeatingRequest: ", ex); return; } @@ -221,6 +222,15 @@ } }; + // Inner Runnable to restart capture, must be run on |mContext| looper. + private final Runnable mRestartCapture = new Runnable() { + @Override + public void run() { + mPreviewSession.close(); // Asynchronously kill the CaptureSession. + createPreviewObjects(); + } + }; + private static final double kNanoSecondsToFps = 1.0E-9; private static final String TAG = "VideoCapture"; @@ -591,13 +601,8 @@ Log.d(TAG, "zoom level " + normalizedZoom + ", rectangle: " + mCropRect.toString()); final Handler mainHandler = new Handler(mContext.getMainLooper()); - mainHandler.post(new Runnable() { - @Override - public void run() { - mPreviewSession.close(); // Asynchronously kill the CaptureSession. - createPreviewObjects(); - } - }); + mainHandler.removeCallbacks(mRestartCapture); + mainHandler.post(mRestartCapture); } @Override
diff --git a/media/cast/net/cast_transport_config.h b/media/cast/net/cast_transport_config.h index 3572988..3ba95dc 100644 --- a/media/cast/net/cast_transport_config.h +++ b/media/cast/net/cast_transport_config.h
@@ -106,10 +106,10 @@ // Convenience accessors to data as an array of uint8_t elements. const uint8_t* bytes() const { return reinterpret_cast<uint8_t*>( - string_as_array(const_cast<std::string*>(&data))); + base::string_as_array(const_cast<std::string*>(&data))); } uint8_t* mutable_bytes() { - return reinterpret_cast<uint8_t*>(string_as_array(&data)); + return reinterpret_cast<uint8_t*>(base::string_as_array(&data)); } // Copies all data members except |data| to |dest|.
diff --git a/media/cast/sender/audio_encoder.cc b/media/cast/sender/audio_encoder.cc index 37410a68..aa1aa942 100644 --- a/media/cast/sender/audio_encoder.cc +++ b/media/cast/sender/audio_encoder.cc
@@ -292,7 +292,8 @@ out->resize(kOpusMaxPayloadSize); const opus_int32 result = opus_encode_float( opus_encoder_, buffer_.get(), samples_per_frame_, - reinterpret_cast<uint8_t*>(string_as_array(out)), kOpusMaxPayloadSize); + reinterpret_cast<uint8_t*>(base::string_as_array(out)), + kOpusMaxPayloadSize); if (result > 1) { out->resize(result); return true;
diff --git a/media/cast/sender/frame_sender.cc b/media/cast/sender/frame_sender.cc index 0cc66e5..2320b7a 100644 --- a/media/cast/sender/frame_sender.cc +++ b/media/cast/sender/frame_sender.cc
@@ -86,7 +86,6 @@ << max_playout_delay_.InMilliseconds() << "animated latency " << animated_playout_delay_.InMilliseconds(); SetTargetPlayoutDelay(animated_playout_delay_); - send_target_playout_delay_ = false; CastTransportRtpConfig transport_config; transport_config.ssrc = config.sender_ssrc;
diff --git a/media/cast/test/end2end_unittest.cc b/media/cast/test/end2end_unittest.cc index 7e13e32..287ef8d 100644 --- a/media/cast/test/end2end_unittest.cc +++ b/media/cast/test/end2end_unittest.cc
@@ -303,7 +303,7 @@ protected: virtual ~TestReceiverAudioCallback() { - STLDeleteElements(&expected_frames_); + base::STLDeleteElements(&expected_frames_); } private:
diff --git a/media/cdm/aes_decryptor.cc b/media/cdm/aes_decryptor.cc index f8e12e5..918d9de7 100644 --- a/media/cdm/aes_decryptor.cc +++ b/media/cdm/aes_decryptor.cc
@@ -41,7 +41,7 @@ public: SessionIdDecryptionKeyMap() {} - ~SessionIdDecryptionKeyMap() { STLDeleteValues(&key_list_); } + ~SessionIdDecryptionKeyMap() { base::STLDeleteValues(&key_list_); } // Replaces value if |session_id| is already present, or adds it if not. // This |decryption_key| becomes the latest until another insertion or
diff --git a/media/cdm/player_tracker_impl.cc b/media/cdm/player_tracker_impl.cc index 7d5cda3..e0caf7b 100644 --- a/media/cdm/player_tracker_impl.cc +++ b/media/cdm/player_tracker_impl.cc
@@ -30,7 +30,7 @@ const base::Closure& cdm_unset_cb) { base::AutoLock lock(lock_); int registration_id = next_registration_id_++; - DCHECK(!ContainsKey(player_callbacks_map_, registration_id)); + DCHECK(!base::ContainsKey(player_callbacks_map_, registration_id)); player_callbacks_map_.insert(std::make_pair( registration_id, PlayerCallbacks(new_key_cb, cdm_unset_cb))); return registration_id; @@ -38,7 +38,7 @@ void PlayerTrackerImpl::UnregisterPlayer(int registration_id) { base::AutoLock lock(lock_); - DCHECK(ContainsKey(player_callbacks_map_, registration_id)) + DCHECK(base::ContainsKey(player_callbacks_map_, registration_id)) << registration_id; player_callbacks_map_.erase(registration_id); }
diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc index 526cafee..832caa3 100644 --- a/media/filters/chunk_demuxer.cc +++ b/media/filters/chunk_demuxer.cc
@@ -991,7 +991,7 @@ ChunkDemuxer::~ChunkDemuxer() { DCHECK_NE(state_, INITIALIZED); - STLDeleteValues(&source_state_map_); + base::STLDeleteValues(&source_state_map_); } void ChunkDemuxer::ReportError_Locked(PipelineStatus error) {
diff --git a/media/filters/frame_processor.cc b/media/filters/frame_processor.cc index 703db223..e85a7d0 100644 --- a/media/filters/frame_processor.cc +++ b/media/filters/frame_processor.cc
@@ -172,7 +172,7 @@ FrameProcessor::~FrameProcessor() { DVLOG(2) << __func__ << "()"; - STLDeleteValues(&track_buffers_); + base::STLDeleteValues(&track_buffers_); } void FrameProcessor::SetSequenceMode(bool sequence_mode) {
diff --git a/media/filters/gpu_video_decoder.cc b/media/filters/gpu_video_decoder.cc index d62b50f..d323e0f3 100644 --- a/media/filters/gpu_video_decoder.cc +++ b/media/filters/gpu_video_decoder.cc
@@ -402,7 +402,8 @@ // Mask against 30 bits, to avoid (undefined) wraparound on signed integer. next_bitstream_buffer_id_ = (next_bitstream_buffer_id_ + 1) & 0x3FFFFFFF; - DCHECK(!ContainsKey(bitstream_buffers_in_decoder_, bitstream_buffer.id())); + DCHECK( + !base::ContainsKey(bitstream_buffers_in_decoder_, bitstream_buffer.id())); bitstream_buffers_in_decoder_.insert(std::make_pair( bitstream_buffer.id(), PendingDecoderBuffer(shm_buffer.release(), buffer, decode_cb)));
diff --git a/media/filters/h264_parser.cc b/media/filters/h264_parser.cc index a70afcc8..a1118d28 100644 --- a/media/filters/h264_parser.cc +++ b/media/filters/h264_parser.cc
@@ -126,8 +126,8 @@ } H264Parser::~H264Parser() { - STLDeleteValues(&active_SPSes_); - STLDeleteValues(&active_PPSes_); + base::STLDeleteValues(&active_SPSes_); + base::STLDeleteValues(&active_PPSes_); } void H264Parser::Reset() {
diff --git a/media/filters/media_source_state.cc b/media/filters/media_source_state.cc index 6b61ee93..68ae666c 100644 --- a/media/filters/media_source_state.cc +++ b/media/filters/media_source_state.cc
@@ -110,7 +110,7 @@ MediaSourceState::~MediaSourceState() { Shutdown(); - STLDeleteValues(&text_stream_map_); + base::STLDeleteValues(&text_stream_map_); } void MediaSourceState::Init(
diff --git a/media/filters/vpx_video_decoder.cc b/media/filters/vpx_video_decoder.cc index 4f6e412..35d1f1f3 100644 --- a/media/filters/vpx_video_decoder.cc +++ b/media/filters/vpx_video_decoder.cc
@@ -234,7 +234,7 @@ } VpxVideoDecoder::MemoryPool::~MemoryPool() { - STLDeleteElements(&frame_buffers_); + base::STLDeleteElements(&frame_buffers_); base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( this); }
diff --git a/media/formats/common/stream_parser_test_base.cc b/media/formats/common/stream_parser_test_base.cc index 86c9499..2af18a4c 100644 --- a/media/formats/common/stream_parser_test_base.cc +++ b/media/formats/common/stream_parser_test_base.cc
@@ -93,6 +93,7 @@ EXPECT_EQ(tracks->tracks().size(), 1u); const auto& track = tracks->tracks()[0]; EXPECT_EQ(track->type(), MediaTrack::Audio); + audio_track_id_ = track->bytestream_track_id(); last_audio_config_ = tracks->getAudioConfig(track->bytestream_track_id()); EXPECT_TRUE(last_audio_config_.IsValidConfig()); return true; @@ -105,6 +106,11 @@ EXPECT_FALSE(audio_buffers.empty()); EXPECT_TRUE(video_buffers.empty()); + // Ensure that track ids are properly assigned on all emitted buffers. + for (const auto& buf : audio_buffers) { + EXPECT_EQ(audio_track_id_, buf->track_id()); + } + // TODO(wolenetz/acolwell): Add text track support to more MSE parsers. See // http://crbug.com/336926. EXPECT_TRUE(text_map.empty());
diff --git a/media/formats/common/stream_parser_test_base.h b/media/formats/common/stream_parser_test_base.h index f509fc6..59e85ce 100644 --- a/media/formats/common/stream_parser_test_base.h +++ b/media/formats/common/stream_parser_test_base.h
@@ -70,6 +70,7 @@ std::unique_ptr<StreamParser> parser_; std::stringstream results_stream_; AudioDecoderConfig last_audio_config_; + StreamParser::TrackId audio_track_id_; DISALLOW_COPY_AND_ASSIGN(StreamParserTestBase); };
diff --git a/media/formats/mp2t/es_parser_adts.cc b/media/formats/mp2t/es_parser_adts.cc index 6ab78457..78bb5ff 100644 --- a/media/formats/mp2t/es_parser_adts.cc +++ b/media/formats/mp2t/es_parser_adts.cc
@@ -147,11 +147,9 @@ // TODO(wolenetz/acolwell): Validate and use a common cross-parser TrackId // type and allow multiple audio tracks. See https://crbug.com/341581. scoped_refptr<StreamParserBuffer> stream_parser_buffer = - StreamParserBuffer::CopyFrom( - adts_frame.data, - adts_frame.size, - is_key_frame, - DemuxerStream::AUDIO, 0); + StreamParserBuffer::CopyFrom(adts_frame.data, adts_frame.size, + is_key_frame, DemuxerStream::AUDIO, + kMp2tAudioTrackId); stream_parser_buffer->set_timestamp(current_pts); stream_parser_buffer->SetDecodeTimestamp( DecodeTimestamp::FromPresentationTime(current_pts));
diff --git a/media/formats/mp2t/es_parser_h264.cc b/media/formats/mp2t/es_parser_h264.cc index 871a70d..7f112f05 100644 --- a/media/formats/mp2t/es_parser_h264.cc +++ b/media/formats/mp2t/es_parser_h264.cc
@@ -279,12 +279,8 @@ // TODO(wolenetz/acolwell): Validate and use a common cross-parser TrackId // type and allow multiple video tracks. See https://crbug.com/341581. scoped_refptr<StreamParserBuffer> stream_parser_buffer = - StreamParserBuffer::CopyFrom( - es, - access_unit_size, - is_key_frame, - DemuxerStream::VIDEO, - 0); + StreamParserBuffer::CopyFrom(es, access_unit_size, is_key_frame, + DemuxerStream::VIDEO, kMp2tVideoTrackId); stream_parser_buffer->SetDecodeTimestamp(current_timing_desc.dts); stream_parser_buffer->set_timestamp(current_timing_desc.pts); return es_adapter_.OnNewBuffer(stream_parser_buffer);
diff --git a/media/formats/mp2t/es_parser_mpeg1audio.cc b/media/formats/mp2t/es_parser_mpeg1audio.cc index 7cde8f8..50cb1cb 100644 --- a/media/formats/mp2t/es_parser_mpeg1audio.cc +++ b/media/formats/mp2t/es_parser_mpeg1audio.cc
@@ -79,11 +79,9 @@ // TODO(wolenetz/acolwell): Validate and use a common cross-parser TrackId // type and allow multiple audio tracks. See https://crbug.com/341581. scoped_refptr<StreamParserBuffer> stream_parser_buffer = - StreamParserBuffer::CopyFrom( - mpeg1audio_frame.data, - mpeg1audio_frame.size, - is_key_frame, - DemuxerStream::AUDIO, 0); + StreamParserBuffer::CopyFrom(mpeg1audio_frame.data, + mpeg1audio_frame.size, is_key_frame, + DemuxerStream::AUDIO, kMp2tAudioTrackId); stream_parser_buffer->set_timestamp(current_pts); stream_parser_buffer->set_duration(frame_duration); emit_buffer_cb_.Run(stream_parser_buffer);
diff --git a/media/formats/mp2t/mp2t_common.h b/media/formats/mp2t/mp2t_common.h index 5c89475..37e5891 100644 --- a/media/formats/mp2t/mp2t_common.h +++ b/media/formats/mp2t/mp2t_common.h
@@ -17,4 +17,11 @@ } \ } while (0) +namespace media { +namespace mp2t { +const int kMp2tAudioTrackId = 1; +const int kMp2tVideoTrackId = 2; +} // namespace media +} // namespace mp2t + #endif // MEDIA_FORMATS_MP2T_MP2T_COMMON_H_
diff --git a/media/formats/mp2t/mp2t_stream_parser.cc b/media/formats/mp2t/mp2t_stream_parser.cc index 238b58c..c66afeb 100644 --- a/media/formats/mp2t/mp2t_stream_parser.cc +++ b/media/formats/mp2t/mp2t_stream_parser.cc
@@ -168,7 +168,7 @@ } Mp2tStreamParser::~Mp2tStreamParser() { - STLDeleteValues(&pids_); + base::STLDeleteValues(&pids_); } void Mp2tStreamParser::Init(
diff --git a/media/formats/mp2t/mp2t_stream_parser_unittest.cc b/media/formats/mp2t/mp2t_stream_parser_unittest.cc index 6c76023..5a8e2a0 100644 --- a/media/formats/mp2t/mp2t_stream_parser_unittest.cc +++ b/media/formats/mp2t/mp2t_stream_parser_unittest.cc
@@ -80,6 +80,8 @@ DecodeTimestamp audio_max_dts_; DecodeTimestamp video_min_dts_; DecodeTimestamp video_max_dts_; + StreamParser::TrackId audio_track_id_; + StreamParser::TrackId video_track_id_; void ResetStats() { segment_count_ = 0; @@ -124,9 +126,11 @@ for (const auto& track : tracks->tracks()) { const auto& track_id = track->bytestream_track_id(); if (track->type() == MediaTrack::Audio) { + audio_track_id_ = track_id; found_audio_track = true; EXPECT_TRUE(tracks->getAudioConfig(track_id).IsValidConfig()); } else if (track->type() == MediaTrack::Video) { + video_track_id_ = track_id; found_video_track = true; EXPECT_TRUE(tracks->getVideoConfig(track_id).IsValidConfig()); } else { @@ -160,6 +164,14 @@ DumpBuffers("audio_buffers", audio_buffers); DumpBuffers("video_buffers", video_buffers); + // Ensure that track ids are properly assigned on all emitted buffers. + for (const auto& buf : audio_buffers) { + EXPECT_EQ(audio_track_id_, buf->track_id()); + } + for (const auto& buf : video_buffers) { + EXPECT_EQ(video_track_id_, buf->track_id()); + } + // TODO(wolenetz/acolwell): Add text track support to more MSE parsers. See // http://crbug.com/336926. if (!text_map.empty())
diff --git a/media/formats/mp4/mp4_stream_parser.cc b/media/formats/mp4/mp4_stream_parser.cc index ffc49a1..af8485b 100644 --- a/media/formats/mp4/mp4_stream_parser.cc +++ b/media/formats/mp4/mp4_stream_parser.cc
@@ -605,10 +605,9 @@ // TODO(wolenetz/acolwell): Validate and use a common cross-parser TrackId // type and allow multiple tracks for same media type, if applicable. See // https://crbug.com/341581. - scoped_refptr<StreamParserBuffer> stream_buf = - StreamParserBuffer::CopyFrom(&frame_buf[0], frame_buf.size(), - runs_->is_keyframe(), - buffer_type, 0); + scoped_refptr<StreamParserBuffer> stream_buf = StreamParserBuffer::CopyFrom( + &frame_buf[0], frame_buf.size(), runs_->is_keyframe(), buffer_type, + runs_->track_id()); if (decrypt_config) stream_buf->set_decrypt_config(std::move(decrypt_config));
diff --git a/media/formats/mp4/mp4_stream_parser_unittest.cc b/media/formats/mp4/mp4_stream_parser_unittest.cc index d00e7b1..dcc14b9 100644 --- a/media/formats/mp4/mp4_stream_parser_unittest.cc +++ b/media/formats/mp4/mp4_stream_parser_unittest.cc
@@ -76,6 +76,8 @@ AudioDecoderConfig audio_decoder_config_; VideoDecoderConfig video_decoder_config_; DecodeTimestamp lower_bound_; + StreamParser::TrackId audio_track_id_; + StreamParser::TrackId video_track_id_; bool AppendData(const uint8_t* data, size_t length) { return parser_->Parse(data, length); @@ -121,12 +123,14 @@ for (const auto& track : tracks->tracks()) { const auto& track_id = track->bytestream_track_id(); if (track->type() == MediaTrack::Audio) { + audio_track_id_ = track_id; audio_decoder_config_ = tracks->getAudioConfig(track_id); DVLOG(1) << "Audio track " << track_id << " config=" << (audio_decoder_config_.IsValidConfig() ? audio_decoder_config_.AsHumanReadableString() : "INVALID"); } else if (track->type() == MediaTrack::Video) { + video_track_id_ = track_id; video_decoder_config_ = tracks->getVideoConfig(track_id); DVLOG(1) << "Video track " << track_id << " config=" << (video_decoder_config_.IsValidConfig() @@ -155,6 +159,14 @@ DumpBuffers("audio_buffers", audio_buffers); DumpBuffers("video_buffers", video_buffers); + // Ensure that track ids are properly assigned on all emitted buffers. + for (const auto& buf : audio_buffers) { + EXPECT_EQ(audio_track_id_, buf->track_id()); + } + for (const auto& buf : video_buffers) { + EXPECT_EQ(video_track_id_, buf->track_id()); + } + // TODO(wolenetz/acolwell): Add text track support to more MSE parsers. See // http://crbug.com/336926. if (!text_map.empty())
diff --git a/media/formats/mpeg/mpeg_audio_stream_parser_base.cc b/media/formats/mpeg/mpeg_audio_stream_parser_base.cc index b0bb515..944225a 100644 --- a/media/formats/mpeg/mpeg_audio_stream_parser_base.cc +++ b/media/formats/mpeg/mpeg_audio_stream_parser_base.cc
@@ -19,6 +19,8 @@ namespace media { +static const int kMpegAudioTrackId = 1; + static const uint32_t kICYStartCode = 0x49435920; // 'ICY ' // Arbitrary upper bound on the size of an IceCast header before it @@ -222,7 +224,7 @@ std::unique_ptr<MediaTracks> media_tracks(new MediaTracks()); if (config_.IsValidConfig()) { - media_tracks->AddAudioTrack(config_, 1, "main", "", ""); + media_tracks->AddAudioTrack(config_, kMpegAudioTrackId, "main", "", ""); } if (!config_cb_.Run(std::move(media_tracks), TextTrackConfigMap())) return -1; @@ -241,9 +243,8 @@ // TODO(wolenetz/acolwell): Validate and use a common cross-parser TrackId // type and allow multiple audio tracks, if applicable. See // https://crbug.com/341581. - scoped_refptr<StreamParserBuffer> buffer = - StreamParserBuffer::CopyFrom(data, frame_size, true, - DemuxerStream::AUDIO, 0); + scoped_refptr<StreamParserBuffer> buffer = StreamParserBuffer::CopyFrom( + data, frame_size, true, DemuxerStream::AUDIO, kMpegAudioTrackId); buffer->set_timestamp(timestamp_helper_->GetTimestamp()); buffer->set_duration(timestamp_helper_->GetFrameDuration(sample_count)); buffers->push_back(buffer);
diff --git a/media/formats/webm/webm_content_encodings_client.cc b/media/formats/webm/webm_content_encodings_client.cc index eb1b590d..0d3aa2c 100644 --- a/media/formats/webm/webm_content_encodings_client.cc +++ b/media/formats/webm/webm_content_encodings_client.cc
@@ -18,7 +18,7 @@ } WebMContentEncodingsClient::~WebMContentEncodingsClient() { - STLDeleteElements(&content_encodings_); + base::STLDeleteElements(&content_encodings_); } const ContentEncodings& WebMContentEncodingsClient::content_encodings() const { @@ -30,7 +30,7 @@ if (id == kWebMIdContentEncodings) { DCHECK(!cur_content_encoding_.get()); DCHECK(!content_encryption_encountered_); - STLDeleteElements(&content_encodings_); + base::STLDeleteElements(&content_encodings_); content_encodings_ready_ = false; return this; }
diff --git a/media/gpu/android_video_decode_accelerator.cc b/media/gpu/android_video_decode_accelerator.cc index d88c2a0..41d3f550 100644 --- a/media/gpu/android_video_decode_accelerator.cc +++ b/media/gpu/android_video_decode_accelerator.cc
@@ -53,6 +53,8 @@ namespace media { +namespace { + enum { kNumPictureBuffers = limits::kMaxVideoFrames + 1 }; // Max number of bitstreams notified to the client with @@ -63,7 +65,7 @@ // support others. Advertise support for all H264 profiles and let the // MediaCodec fail when decoding if it's not actually supported. It's assumed // that consumers won't have software fallback for H264 on Android anyway. -static const VideoCodecProfile kSupportedH264Profiles[] = { +constexpr VideoCodecProfile kSupportedH264Profiles[] = { H264PROFILE_BASELINE, H264PROFILE_MAIN, H264PROFILE_EXTENDED, @@ -103,20 +105,22 @@ // from breaking the pipeline, if we're about to be reset anyway. constexpr base::TimeDelta ErrorPostingDelay = base::TimeDelta::FromSeconds(2); +// Maximum number of concurrent, incomplete codec creations that we'll allow +// before turning off autodection of codec type. +enum { kMaxConcurrentCodecAutodetections = 4 }; + // For RecordFormatChangedMetric. enum FormatChangedValue { CodecInitialized = false, MissingFormatChanged = true }; -// Maximum number of concurrent, incomplete codec creations that we'll allow -// before turning off autodection of codec type. -enum { kMaxConcurrentCodecAutodetections = 4 }; - -static inline void RecordFormatChangedMetric(FormatChangedValue value) { +inline void RecordFormatChangedMetric(FormatChangedValue value) { UMA_HISTOGRAM_BOOLEAN("Media.AVDA.MissingFormatChanged", !!value); } +} // namespace + // Handle OnFrameAvailable callbacks safely. Since they occur asynchronously, // we take care that the AVDA that wants them still exists. A WeakPtr to // the AVDA would be preferable, except that OnFrameAvailable callbacks can @@ -168,19 +172,20 @@ DISALLOW_COPY_AND_ASSIGN(OnFrameAvailableHandler); }; -// Helper class to share an IO timer for DoIOTask() execution; prevents each -// AVDA instance from starting its own high frequency timer. The intuition -// behind this is that, if we're waiting for long enough, then either (a) -// MediaCodec is broken or (b) MediaCodec is waiting on us to change state -// (e.g., get new demuxed data / get a free picture buffer / return an output -// buffer to MediaCodec). This is inherently a race, since we don't know if -// MediaCodec is broken or just slow. Since the MediaCodec API doesn't let -// us wait on MediaCodec state changes prior to L, we more or less have to -// time out or keep polling forever in some common cases. -class AVDATimerManager { +// AVDAManager manages shared resources for a number of AVDA instances. +// Its responsibilities include: +// - Starting and stopping a shared "construction" thread for instantiating and +// releasing MediaCodecs. +// - Tracking the number of outstanding tasks running on the construction +// thread. (For detecting when one of those tasks has hung indefinitely.) +// - Running a RepeatingTimer so that AVDAs can get a regular callback to +// DoIOTask(). +// - Tracking the allocation of surfaces to AVDAs and delivering callbacks when +// surfaces are released. +class AVDAManager { public: - // Make sure that the construction thread is started for |avda_instance|. - bool StartThread(AndroidVideoDecodeAccelerator* avda_instance) { + // Make sure that the construction thread is started for |avda|. + bool StartThread(AndroidVideoDecodeAccelerator* avda) { DCHECK(thread_checker_.CalledOnValidThread()); // If we chose not to shut it down due to pending codec constructions, then @@ -193,19 +198,19 @@ } } - thread_avda_instances_.insert(avda_instance); + thread_avda_instances_.insert(avda); UMA_HISTOGRAM_ENUMERATION("Media.AVDA.NumAVDAInstances", thread_avda_instances_.size(), 31); // PRESUBMIT_IGNORE_UMA_MAX return true; } - // |avda_instance| will no longer need the construction thread. Stop the - // thread if this is the last instance. - void StopThread(AndroidVideoDecodeAccelerator* avda_instance) { + // |avda| will no longer need the construction thread. Stop the thread if + // this is the last instance. + void StopThread(AndroidVideoDecodeAccelerator* avda) { DCHECK(thread_checker_.CalledOnValidThread()); - thread_avda_instances_.erase(avda_instance); + thread_avda_instances_.erase(avda); if (!thread_avda_instances_.empty()) return; @@ -219,44 +224,41 @@ construction_thread_.Stop(); } - // Request periodic callback of |avda_instance|->DoIOTask(). Does nothing if - // the instance is already registered and the timer started. The first request + // Request periodic callback of |avda|->DoIOTask(). Does nothing if the + // instance is already registered and the timer started. The first request // will start the repeating timer on an interval of DecodePollDelay. - void StartTimer(AndroidVideoDecodeAccelerator* avda_instance) { + void StartTimer(AndroidVideoDecodeAccelerator* avda) { DCHECK(thread_checker_.CalledOnValidThread()); - timer_avda_instances_.insert(avda_instance); + timer_avda_instances_.insert(avda); // If the timer is running, StopTimer() might have been called earlier, if // so remove the instance from the pending erasures. if (timer_running_) - pending_erase_.erase(avda_instance); + pending_erase_.erase(avda); if (io_timer_.IsRunning()) return; - io_timer_.Start(FROM_HERE, DecodePollDelay, this, - &AVDATimerManager::RunTimer); + io_timer_.Start(FROM_HERE, DecodePollDelay, this, &AVDAManager::RunTimer); } - // Stop callbacks to |avda_instance|->DoIOTask(). Does nothing if the instance - // is not registered. If there are no instances left, the repeating timer will - // be stopped. - void StopTimer(AndroidVideoDecodeAccelerator* avda_instance) { + // Stop callbacks to |avda|->DoIOTask(). Does nothing if the instance is not + // registered. If there are no instances left, the repeating timer will be + // stopped. + void StopTimer(AndroidVideoDecodeAccelerator* avda) { DCHECK(thread_checker_.CalledOnValidThread()); // If the timer is running, defer erasures to avoid iterator invalidation. if (timer_running_) { - pending_erase_.insert(avda_instance); + pending_erase_.insert(avda); return; } - timer_avda_instances_.erase(avda_instance); + timer_avda_instances_.erase(avda); if (timer_avda_instances_.empty()) io_timer_.Stop(); } - // Eventually, we should run the timer on this thread. For now, we just keep - // it as a convenience for construction. scoped_refptr<base::SingleThreadTaskRunner> ConstructionTaskRunner() { DCHECK(thread_checker_.CalledOnValidThread()); return construction_thread_.task_runner(); @@ -350,10 +352,10 @@ } private: - friend struct base::DefaultLazyInstanceTraits<AVDATimerManager>; + friend struct base::DefaultLazyInstanceTraits<AVDAManager>; - AVDATimerManager() : construction_thread_("AVDAThread") {} - ~AVDATimerManager() { NOTREACHED(); } + AVDAManager() : construction_thread_("AVDAThread") {} + ~AVDAManager() { NOTREACHED(); } void RunTimer() { { @@ -409,10 +411,10 @@ base::ThreadChecker thread_checker_; - DISALLOW_COPY_AND_ASSIGN(AVDATimerManager); + DISALLOW_COPY_AND_ASSIGN(AVDAManager); }; -static base::LazyInstance<AVDATimerManager>::Leaky g_avda_timer = +static base::LazyInstance<AVDAManager>::Leaky g_avda_manager = LAZY_INSTANCE_INITIALIZER; AndroidVideoDecodeAccelerator::CodecConfig::CodecConfig() {} @@ -452,8 +454,8 @@ AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { DCHECK(thread_checker_.CalledOnValidThread()); - g_avda_timer.Pointer()->StopTimer(this); - g_avda_timer.Pointer()->StopThread(this); + g_avda_manager.Get().StopTimer(this); + g_avda_manager.Get().StopThread(this); #if defined(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS) if (!media_drm_bridge_cdm_context_) @@ -543,7 +545,7 @@ return false; } - if (g_avda_timer.Pointer()->AllocateSurface(config_.surface_id, this)) { + if (g_avda_manager.Get().AllocateSurface(config_.surface_id, this)) { // We have succesfully owned the surface, so finish initialization now. return InitializeStrategy(); } @@ -586,7 +588,7 @@ // Start the thread for async configuration, even if we don't need it now. // ResetCodecState might rebuild the codec later, for example. - if (!g_avda_timer.Pointer()->StartThread(this)) { + if (!g_avda_manager.Get().StartThread(this)) { LOG(ERROR) << "Failed to start AVDA thread"; return false; } @@ -1098,7 +1100,7 @@ // releasing any outgoing codec, so that |codec_config_| still matches the // outgoing codec for ReleaseMediaCodec(). codec_config_->allow_autodetection_ = - g_avda_timer.Pointer()->IsCodecAutodetectionProbablySafe(); + g_avda_manager.Get().IsCodecAutodetectionProbablySafe(); // If autodetection is disallowed, fall back to Chrome's software decoders // instead of using the software decoders provided by MediaCodec. @@ -1110,13 +1112,13 @@ codec_config_->notify_completion_ = codec_config_->allow_autodetection_; if (codec_config_->allow_autodetection_) - g_avda_timer.Pointer()->StartUsingConstructionThread(); + g_avda_manager.Get().StartUsingConstructionThread(); // If we're not trying autodetection, then use the main thread. The original // might be blocked. scoped_refptr<base::SingleThreadTaskRunner> task_runner = codec_config_->allow_autodetection_ - ? g_avda_timer.Pointer()->ConstructionTaskRunner() + ? g_avda_manager.Get().ConstructionTaskRunner() : base::ThreadTaskRunnerHandle::Get(); CHECK(task_runner); @@ -1136,7 +1138,7 @@ // attempts, don't record it. It may break book-keeping, and there's not // much we can do anyway. codec_config_->allow_autodetection_ = - g_avda_timer.Pointer()->IsCodecAutodetectionProbablySafe(); + g_avda_manager.Get().IsCodecAutodetectionProbablySafe(); codec_config_->notify_completion_ = false; ReleaseMediaCodec(); @@ -1169,7 +1171,7 @@ // If we successfully completed after an autodetect, then let the other // instances know that we didn't get stuck. if (codec_config->notify_completion_) - g_avda_timer.Pointer()->DoneUsingConstructionThread(); + g_avda_manager.Get().DoneUsingConstructionThread(); return codec; } @@ -1322,7 +1324,7 @@ } else { DVLOG(3) << __FUNCTION__ << " Deleting the MediaCodec and creating a new one."; - g_avda_timer.Pointer()->StopTimer(this); + g_avda_manager.Get().StopTimer(this); ConfigureMediaCodecAsynchronously(); } } @@ -1412,18 +1414,16 @@ if (strategy_) strategy_->EndCleanup(); - AVDATimerManager* manager = g_avda_timer.Pointer(); - // We no longer care about |surface_id|, in case we did before. It's okay // if we have no surface and/or weren't the owner or a waiter. - manager->DeallocateSurface(config_.surface_id, this); + g_avda_manager.Get().DeallocateSurface(config_.surface_id, this); // Note that async codec construction might still be in progress. In that // case, the codec will be deleted when it completes once we invalidate all // our weak refs. weak_this_factory_.InvalidateWeakPtrs(); if (media_codec_) { - manager->StopTimer(this); + g_avda_manager.Get().StopTimer(this); ReleaseMediaCodec(); } delete this; @@ -1663,9 +1663,9 @@ } if (should_be_running) - g_avda_timer.Pointer()->StartTimer(this); + g_avda_manager.Get().StartTimer(this); else - g_avda_timer.Pointer()->StopTimer(this); + g_avda_manager.Get().StopTimer(this); } void AndroidVideoDecodeAccelerator::ReleaseMediaCodec() { @@ -1683,13 +1683,13 @@ if (!codec_config_->allow_autodetection_) { media_codec_.reset(); } else { - g_avda_timer.Pointer()->StartUsingConstructionThread(); + g_avda_manager.Get().StartUsingConstructionThread(); scoped_refptr<base::SingleThreadTaskRunner> task_runner = - g_avda_timer.Pointer()->ConstructionTaskRunner(); + g_avda_manager.Get().ConstructionTaskRunner(); task_runner->DeleteSoon(FROM_HERE, media_codec_.release()); task_runner->PostTask( - FROM_HERE, base::Bind(&AVDATimerManager::DoneUsingConstructionThread, - base::Unretained(g_avda_timer.Pointer()))); + FROM_HERE, base::Bind(&AVDAManager::DoneUsingConstructionThread, + base::Unretained(g_avda_manager.Pointer()))); } } @@ -1700,13 +1700,6 @@ } // static -bool AndroidVideoDecodeAccelerator::UseTextureCopyForDeferredStrategy( - const gpu::GpuPreferences& gpu_preferences) { - // http://crbug.com/582170 - return gpu_preferences.enable_threaded_texture_mailboxes; -} - -// static VideoDecodeAccelerator::Capabilities AndroidVideoDecodeAccelerator::GetCapabilities( const gpu::GpuPreferences& gpu_preferences) { @@ -1770,12 +1763,14 @@ if (UseDeferredRenderingStrategy(gpu_preferences)) { capabilities.flags |= VideoDecodeAccelerator::Capabilities:: NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE; - if (UseTextureCopyForDeferredStrategy(gpu_preferences)) { + + // If we're using threaded texture mailboxes the COPY_REQUIRED flag must be + // set on deferred strategy frames (http://crbug.com/582170), and + // SurfaceView output is disabled (http://crbug.com/582170). + if (gpu_preferences.enable_threaded_texture_mailboxes) { capabilities.flags |= media::VideoDecodeAccelerator::Capabilities::REQUIRES_TEXTURE_COPY; } else if (media::MediaCodecUtil::IsSurfaceViewOutputSupported()) { - // Fullscreen external SurfaceView is disabled for WebView. - // http://crbug.com/582170 capabilities.flags |= media::VideoDecodeAccelerator::Capabilities:: SUPPORTS_EXTERNAL_OUTPUT_SURFACE; }
diff --git a/media/gpu/android_video_decode_accelerator.h b/media/gpu/android_video_decode_accelerator.h index fd99ebc0..ac799e1 100644 --- a/media/gpu/android_video_decode_accelerator.h +++ b/media/gpu/android_video_decode_accelerator.h
@@ -158,7 +158,7 @@ void OnFrameAvailable(); private: - friend class AVDATimerManager; + friend class AVDAManager; // TODO(timav): evaluate the need for more states in the AVDA state machine. enum State { @@ -212,7 +212,7 @@ // software when autodetecting can sometimes hang mediaserver. bool allow_autodetection_ = false; - // Should we notify AVDATimerManager when codec configuration completes? + // Should we notify AVDAManager when codec configuration completes? bool notify_completion_ = false; protected: @@ -362,11 +362,6 @@ static bool UseDeferredRenderingStrategy( const gpu::GpuPreferences& gpu_preferences); - // Returns true if frame's COPY_REQUIRED flag needs to be set when using - // deferred strategy. - static bool UseTextureCopyForDeferredStrategy( - const gpu::GpuPreferences& gpu_preferences); - // Indicates if MediaCodec should not be used for software decoding since we // have safer versions elsewhere. bool IsMediaCodecSoftwareDecodingForbidden() const;
diff --git a/media/gpu/dxva_video_decode_accelerator_win.cc b/media/gpu/dxva_video_decode_accelerator_win.cc index 0751353..102337d 100644 --- a/media/gpu/dxva_video_decode_accelerator_win.cc +++ b/media/gpu/dxva_video_decode_accelerator_win.cc
@@ -507,7 +507,8 @@ main_thread_task_runner_ = base::ThreadTaskRunnerHandle::Get(); if (!config.supported_output_formats.empty() && - !ContainsValue(config.supported_output_formats, PIXEL_FORMAT_NV12)) { + !base::ContainsValue(config.supported_output_formats, + PIXEL_FORMAT_NV12)) { share_nv12_textures_ = false; copy_nv12_textures_ = false; } @@ -1425,7 +1426,8 @@ bool DXVAVideoDecodeAccelerator::SetDecoderMediaTypes() { RETURN_ON_FAILURE(SetDecoderInputMediaType(), "Failed to set decoder input media type", false); - return SetDecoderOutputMediaType(MFVideoFormat_NV12); + return SetDecoderOutputMediaType(MFVideoFormat_NV12) || + SetDecoderOutputMediaType(MFVideoFormat_P010); } bool DXVAVideoDecodeAccelerator::SetDecoderInputMediaType() { @@ -1560,7 +1562,8 @@ // A stream change needs further ProcessInput calls to get back decoder // output which is why we need to set the state to stopped. if (hr == MF_E_TRANSFORM_STREAM_CHANGE) { - if (!SetDecoderOutputMediaType(MFVideoFormat_NV12)) { + if (!SetDecoderOutputMediaType(MFVideoFormat_NV12) && + !SetDecoderOutputMediaType(MFVideoFormat_P010)) { // Decoder didn't let us set NV12 output format. Not sure as to why // this can happen. Give up in disgust. NOTREACHED() << "Failed to set decoder output media type to NV12";
diff --git a/media/gpu/ipc/service/gpu_jpeg_decode_accelerator.cc b/media/gpu/ipc/service/gpu_jpeg_decode_accelerator.cc index 3e2071f6..881a8285 100644 --- a/media/gpu/ipc/service/gpu_jpeg_decode_accelerator.cc +++ b/media/gpu/ipc/service/gpu_jpeg_decode_accelerator.cc
@@ -251,7 +251,7 @@ return; if (child_task_runner_->BelongsToCurrentThread()) { - STLDeleteValues(&client_map_); + base::STLDeleteValues(&client_map_); } else { // Make sure |Client| are deleted on child thread. std::unique_ptr<ClientMap> client_map(new ClientMap); @@ -269,7 +269,7 @@ // Must be static because this method runs after destructor. static void DeleteClientMapOnChildThread( std::unique_ptr<ClientMap> client_map) { - STLDeleteValues(client_map.get()); + base::STLDeleteValues(client_map.get()); } base::WeakPtr<GpuJpegDecodeAccelerator> owner_;
diff --git a/media/gpu/video_decode_accelerator_unittest.cc b/media/gpu/video_decode_accelerator_unittest.cc index 30ad9dec..70bc4399 100644 --- a/media/gpu/video_decode_accelerator_unittest.cc +++ b/media/gpu/video_decode_accelerator_unittest.cc
@@ -901,7 +901,7 @@ return; weak_vda_ptr_factory_->InvalidateWeakPtrs(); decoder_.reset(); - STLClearObject(&encoded_data_); + base::STLClearObject(&encoded_data_); active_textures_.clear(); // Cascade through the rest of the states to simplify test code below. @@ -1118,8 +1118,9 @@ void VideoDecodeAcceleratorTest::TearDown() { g_env->GetRenderingTaskRunner()->PostTask( - FROM_HERE, base::Bind(&STLDeleteElements<std::vector<TestVideoFile*>>, - &test_video_files_)); + FROM_HERE, + base::Bind(&base::STLDeleteElements<std::vector<TestVideoFile*>>, + &test_video_files_)); base::WaitableEvent done(base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED); @@ -1487,11 +1488,11 @@ g_env->GetRenderingTaskRunner()->PostTask( FROM_HERE, - base::Bind(&STLDeleteElements<std::vector<GLRenderingVDAClient*>>, + base::Bind(&base::STLDeleteElements<std::vector<GLRenderingVDAClient*>>, &clients)); g_env->GetRenderingTaskRunner()->PostTask( FROM_HERE, - base::Bind(&STLDeleteElements< + base::Bind(&base::STLDeleteElements< std::vector<ClientStateNotification<ClientState>*>>, ¬es)); WaitUntilIdle();
diff --git a/media/gpu/vt_video_decode_accelerator_mac.cc b/media/gpu/vt_video_decode_accelerator_mac.cc index 2b37130..e8bcaf7 100644 --- a/media/gpu/vt_video_decode_accelerator_mac.cc +++ b/media/gpu/vt_video_decode_accelerator_mac.cc
@@ -866,13 +866,16 @@ void VTVideoDecodeAccelerator::ReusePictureBuffer(int32_t picture_id) { DCHECK(gpu_thread_checker_.CalledOnValidThread()); - DCHECK(picture_info_map_.count(picture_id)); - PictureInfo* picture_info = picture_info_map_.find(picture_id)->second.get(); - picture_info->cv_image.reset(); - picture_info->gl_image->Destroy(false); - picture_info->gl_image = nullptr; - if (assigned_picture_ids_.count(picture_id) != 0) { + auto it = picture_info_map_.find(picture_id); + if (it != picture_info_map_.end()) { + PictureInfo* picture_info = it->second.get(); + picture_info->cv_image.reset(); + picture_info->gl_image->Destroy(false); + picture_info->gl_image = nullptr; + } + + if (assigned_picture_ids_.count(picture_id)) { available_picture_ids_.push_back(picture_id); ProcessWorkQueues(); } else { @@ -1024,8 +1027,9 @@ return false; int32_t picture_id = available_picture_ids_.back(); - DCHECK(picture_info_map_.count(picture_id)); - PictureInfo* picture_info = picture_info_map_.find(picture_id)->second.get(); + auto it = picture_info_map_.find(picture_id); + DCHECK(it != picture_info_map_.end()); + PictureInfo* picture_info = it->second.get(); DCHECK(!picture_info->cv_image); DCHECK(!picture_info->gl_image);
diff --git a/media/media.gyp b/media/media.gyp index 0648a3a8..1b3aeda 100644 --- a/media/media.gyp +++ b/media/media.gyp
@@ -311,6 +311,8 @@ 'base/channel_mixer.h', 'base/channel_mixing_matrix.cc', 'base/channel_mixing_matrix.h', + 'base/color_helper.cc', + 'base/color_helper.h', 'base/container_names.cc', 'base/container_names.h', 'base/data_buffer.cc', @@ -452,6 +454,8 @@ 'base/video_capturer_source.h', 'base/video_codecs.cc', 'base/video_codecs.h', + 'base/video_color_space.cc', + 'base/video_color_space.h', 'base/video_decoder.cc', 'base/video_decoder.h', 'base/video_decoder_config.cc', @@ -1164,6 +1168,7 @@ 'base/vector_math_testing.h', 'base/vector_math_unittest.cc', 'base/video_codecs_unittest.cc', + 'base/video_color_space_unittest.cc', 'base/video_decoder_config_unittest.cc', 'base/video_frame_pool_unittest.cc', 'base/video_frame_unittest.cc',
diff --git a/media/mojo/clients/mojo_renderer.cc b/media/mojo/clients/mojo_renderer.cc index 95ee0c6..675809a 100644 --- a/media/mojo/clients/mojo_renderer.cc +++ b/media/mojo/clients/mojo_renderer.cc
@@ -55,6 +55,21 @@ demuxer_stream_provider_ = demuxer_stream_provider; init_cb_ = init_cb; + switch (demuxer_stream_provider_->GetType()) { + case DemuxerStreamProvider::Type::STREAM: + InitializeRendererFromStreams(client); + break; + case DemuxerStreamProvider::Type::URL: + InitializeRendererFromUrl(client); + break; + } +} + +void MojoRenderer::InitializeRendererFromStreams( + media::RendererClient* client) { + DVLOG(1) << __FUNCTION__; + DCHECK(task_runner_->BelongsToCurrentThread()); + // Create audio and video mojom::DemuxerStream and bind its lifetime to // the pipe. DemuxerStream* const audio = @@ -93,7 +108,22 @@ // |remote_renderer_| is destroyed. remote_renderer_->Initialize( binding_.CreateInterfacePtrAndBind(), std::move(audio_stream), - std::move(video_stream), + std::move(video_stream), base::nullopt, + base::Bind(&MojoRenderer::OnInitialized, base::Unretained(this), client)); +} + +void MojoRenderer::InitializeRendererFromUrl(media::RendererClient* client) { + DVLOG(2) << __FUNCTION__; + DCHECK(task_runner_->BelongsToCurrentThread()); + + BindRemoteRendererIfNeeded(); + + // Using base::Unretained(this) is safe because |this| owns + // |remote_renderer_|, and the callback won't be dispatched if + // |remote_renderer_| is destroyed. + remote_renderer_->Initialize( + binding_.CreateInterfacePtrAndBind(), mojom::DemuxerStreamPtr(), + mojom::DemuxerStreamPtr(), demuxer_stream_provider_->GetUrl(), base::Bind(&MojoRenderer::OnInitialized, base::Unretained(this), client)); } @@ -182,6 +212,11 @@ DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(remote_renderer_.is_bound()); + if (demuxer_stream_provider_->GetType() == DemuxerStreamProvider::Type::URL) { + NOTIMPLEMENTED(); + return false; + } + return !!demuxer_stream_provider_->GetStream(DemuxerStream::AUDIO); } @@ -190,6 +225,11 @@ DCHECK(task_runner_->BelongsToCurrentThread()); DCHECK(remote_renderer_.is_bound()); + if (demuxer_stream_provider_->GetType() == DemuxerStreamProvider::Type::URL) { + NOTIMPLEMENTED(); + return false; + } + return !!demuxer_stream_provider_->GetStream(DemuxerStream::VIDEO); } @@ -234,6 +274,11 @@ client_->OnVideoNaturalSizeChange(size); } +void MojoRenderer::OnDurationChange(int64_t duration_usec) { + DVLOG(2) << __FUNCTION__ << ": duration" << duration_usec; + client_->OnDurationChange(base::TimeDelta::FromMicroseconds(duration_usec)); +} + void MojoRenderer::OnVideoOpacityChange(bool opaque) { DVLOG(2) << __FUNCTION__ << ": " << opaque; DCHECK(task_runner_->BelongsToCurrentThread());
diff --git a/media/mojo/clients/mojo_renderer.h b/media/mojo/clients/mojo_renderer.h index 9bc09f0e..ae3cea1 100644 --- a/media/mojo/clients/mojo_renderer.h +++ b/media/mojo/clients/mojo_renderer.h
@@ -67,12 +67,21 @@ void OnVideoOpacityChange(bool opaque) override; void OnWaitingForDecryptionKey() override; void OnStatisticsUpdate(const PipelineStatistics& stats) override; + void OnDurationChange(int64_t duration_usec) override; // Binds |remote_renderer_| to the mojo message pipe. Can be called multiple // times. If an error occurs during connection, OnConnectionError will be // called asynchronously. void BindRemoteRendererIfNeeded(); + // Initialize the remote renderer when |demuxer_stream_provider| is of type + // DemuxerSteamProvider::Type::STREAM. + void InitializeRendererFromStreams(media::RendererClient* client); + + // Initialize the remote renderer when |demuxer_stream_provider| is of type + // DemuxerSteamProvider::Type::URL. + void InitializeRendererFromUrl(media::RendererClient* client); + // Callback for connection error on |remote_renderer_|. void OnConnectionError();
diff --git a/media/mojo/interfaces/renderer.mojom b/media/mojo/interfaces/renderer.mojom index de144411..4b68de4d 100644 --- a/media/mojo/interfaces/renderer.mojom +++ b/media/mojo/interfaces/renderer.mojom
@@ -7,13 +7,15 @@ import "media/mojo/interfaces/demuxer_stream.mojom"; import "media/mojo/interfaces/media_types.mojom"; import "ui/gfx/geometry/mojo/geometry.mojom"; +import "url/mojo/url.mojom"; interface Renderer { // Initializes the Renderer with one or both of an audio and video stream, // executing the callback with whether the initialization succeeded. Initialize(RendererClient client, DemuxerStream? audio, - DemuxerStream? video) => (bool success); + DemuxerStream? video, + url.mojom.Url? url) => (bool success); // Discards any buffered data, executing callback when completed. // NOTE: If an error occurs, RendererClient::OnError() can be called @@ -67,4 +69,8 @@ // Called when the remote renderering service is waiting on the decryption // key. OnWaitingForDecryptionKey(); + + // Executed the first time the metadata is updated, and whenever the duration + // changes. + OnDurationChange(int64 duration_usec); };
diff --git a/media/mojo/services/media_mojo_unittest.cc b/media/mojo/services/media_mojo_unittest.cc index 12db5dd6..c19fa7e5 100644 --- a/media/mojo/services/media_mojo_unittest.cc +++ b/media/mojo/services/media_mojo_unittest.cc
@@ -52,6 +52,7 @@ MOCK_METHOD1(OnStatisticsUpdate, void(const media::PipelineStatistics& stats)); MOCK_METHOD0(OnWaitingForDecryptionKey, void()); + MOCK_METHOD1(OnDurationChange, void(int64_t time_usec)); private: DISALLOW_COPY_AND_ASSIGN(MockRendererClient); @@ -116,7 +117,7 @@ .Times(Exactly(1)) .WillOnce(InvokeWithoutArgs(run_loop_.get(), &base::RunLoop::Quit)); renderer_->Initialize(renderer_client_binding_.CreateInterfacePtrAndBind(), - nullptr, std::move(video_stream_proxy), + nullptr, std::move(video_stream_proxy), base::nullopt, base::Bind(&MediaServiceTest::OnRendererInitialized, base::Unretained(this))); }
diff --git a/media/mojo/services/mojo_renderer_service.cc b/media/mojo/services/mojo_renderer_service.cc index 7646b83..7282f8e2 100644 --- a/media/mojo/services/mojo_renderer_service.cc +++ b/media/mojo/services/mojo_renderer_service.cc
@@ -8,6 +8,7 @@ #include "base/bind.h" #include "media/base/media_keys.h" +#include "media/base/media_url_demuxer.h" #include "media/base/renderer.h" #include "media/mojo/services/demuxer_stream_provider_shim.h" #include "media/mojo/services/mojo_cdm_service_context.h" @@ -33,20 +34,33 @@ weak_this_ = weak_factory_.GetWeakPtr(); } -MojoRendererService::~MojoRendererService() { -} +MojoRendererService::~MojoRendererService() {} void MojoRendererService::Initialize(mojom::RendererClientPtr client, mojom::DemuxerStreamPtr audio, mojom::DemuxerStreamPtr video, + const base::Optional<GURL>& url, const InitializeCallback& callback) { DVLOG(1) << __FUNCTION__; DCHECK_EQ(state_, STATE_UNINITIALIZED); client_ = std::move(client); state_ = STATE_INITIALIZING; - stream_provider_.reset(new DemuxerStreamProviderShim( - std::move(audio), std::move(video), - base::Bind(&MojoRendererService::OnStreamReady, weak_this_, callback))); + + if (url == base::nullopt) { + stream_provider_.reset(new DemuxerStreamProviderShim( + std::move(audio), std::move(video), + base::Bind(&MojoRendererService::OnStreamReady, weak_this_, callback))); + return; + } + + DCHECK(!audio); + DCHECK(!video); + DCHECK(!url.value().is_empty()); + stream_provider_.reset(new MediaUrlDemuxer(nullptr, url.value())); + renderer_->Initialize( + stream_provider_.get(), this, + base::Bind(&MojoRendererService::OnRendererInitializeDone, weak_this_, + callback)); } void MojoRendererService::Flush(const FlushCallback& callback) { @@ -134,6 +148,10 @@ client_->OnVideoNaturalSizeChange(size); } +void MojoRendererService::OnDurationChange(base::TimeDelta duration) { + client_->OnDurationChange(duration.InMicroseconds()); +} + void MojoRendererService::OnVideoOpacityChange(bool opaque) { DVLOG(2) << __FUNCTION__ << "(" << opaque << ")"; client_->OnVideoOpacityChange(opaque);
diff --git a/media/mojo/services/mojo_renderer_service.h b/media/mojo/services/mojo_renderer_service.h index 57b3be0..d832bce 100644 --- a/media/mojo/services/mojo_renderer_service.h +++ b/media/mojo/services/mojo_renderer_service.h
@@ -15,6 +15,7 @@ #include "base/memory/weak_ptr.h" #include "base/timer/timer.h" #include "media/base/buffering_state.h" +#include "media/base/demuxer_stream_provider.h" #include "media/base/pipeline_status.h" #include "media/base/renderer_client.h" #include "media/mojo/interfaces/renderer.mojom.h" @@ -46,6 +47,7 @@ void Initialize(mojom::RendererClientPtr client, mojom::DemuxerStreamPtr audio, mojom::DemuxerStreamPtr video, + const base::Optional<GURL>& url, const InitializeCallback& callback) final; void Flush(const FlushCallback& callback) final; void StartPlayingFrom(int64_t time_delta_usec) final; @@ -70,6 +72,7 @@ void OnWaitingForDecryptionKey() final; void OnVideoNaturalSizeChange(const gfx::Size& size) final; void OnVideoOpacityChange(bool opaque) final; + void OnDurationChange(base::TimeDelta duration) final; // Called when the DemuxerStreamProviderShim is ready to go (has a config, // pipe handle, etc) and can be handed off to a renderer for use. @@ -100,7 +103,7 @@ State state_; - std::unique_ptr<DemuxerStreamProviderShim> stream_provider_; + std::unique_ptr<DemuxerStreamProvider> stream_provider_; base::RepeatingTimer time_update_timer_; int64_t last_media_time_usec_;
diff --git a/media/renderers/audio_renderer_impl_unittest.cc b/media/renderers/audio_renderer_impl_unittest.cc index 5f4a0d5a..8397cb4 100644 --- a/media/renderers/audio_renderer_impl_unittest.cc +++ b/media/renderers/audio_renderer_impl_unittest.cc
@@ -132,6 +132,7 @@ MOCK_METHOD0(OnWaitingForDecryptionKey, void(void)); MOCK_METHOD1(OnVideoNaturalSizeChange, void(const gfx::Size&)); MOCK_METHOD1(OnVideoOpacityChange, void(bool)); + MOCK_METHOD1(OnDurationChange, void(base::TimeDelta)); void InitializeRenderer(const PipelineStatusCB& pipeline_status_cb) { EXPECT_CALL(*this, OnWaitingForDecryptionKey()).Times(0);
diff --git a/media/renderers/renderer_impl.cc b/media/renderers/renderer_impl.cc index 7381e94e..c4fbf53 100644 --- a/media/renderers/renderer_impl.cc +++ b/media/renderers/renderer_impl.cc
@@ -58,6 +58,13 @@ DCHECK(type_ == DemuxerStream::VIDEO); renderer_->OnVideoOpacityChange(opaque); } + void OnDurationChange(base::TimeDelta duration) override { + // RendererClients should only be notified of duration changes in certain + // scenarios, none of which should arise for RendererClientInternal. + // Duration changes should be sent to the pipeline by the DemuxerStream, via + // the DemuxerHost interface. + NOTREACHED(); + } private: DemuxerStream::Type type_;
diff --git a/media/renderers/renderer_impl_unittest.cc b/media/renderers/renderer_impl_unittest.cc index 1a280e1..4895030 100644 --- a/media/renderers/renderer_impl_unittest.cc +++ b/media/renderers/renderer_impl_unittest.cc
@@ -51,6 +51,7 @@ MOCK_METHOD1(OnInitialize, void(PipelineStatus)); MOCK_METHOD0(OnFlushed, void()); MOCK_METHOD1(OnCdmAttached, void(bool)); + MOCK_METHOD1(OnDurationChange, void(base::TimeDelta duration)); private: DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
diff --git a/media/test/data/README b/media/test/data/README index 100dc76..38a413c 100644 --- a/media/test/data/README +++ b/media/test/data/README
@@ -195,6 +195,14 @@ First 40 raw i420 frames of bear-1280x720.mp4 scaled down to 320x192 for video_encode_accelerator_unittest. +// VP9 parser test files: +bear-vp9.ivf + - Created using "avconv -i bear-vp9.webm -vcodec copy -an -f ivf bear-vp9.ivf". +bear-vp9.ivf.context +test-25fps.vp9.context + - Manually dumped from libvpx with bear-vp9.ivf and test-25fps.vp9. See + vp9_parser_unittest.cc for description of their format. + // JPEG test files: pixel-1280x720.jpg - Single MJEPG encoded frame of 1280x720, captured on Chromebook Pixel. This image does not have Huffman table. peach_pi-1280x720.jpg - Single MJPEG encoded frame of 1280x720, captured on Samsung Chromebook 2(13"). This image has Huffman table.
diff --git a/media/test/data/bear-vp9.ivf b/media/test/data/bear-vp9.ivf new file mode 100644 index 0000000..c350eac --- /dev/null +++ b/media/test/data/bear-vp9.ivf Binary files differ
diff --git a/media/test/data/bear-vp9.ivf.context b/media/test/data/bear-vp9.ivf.context new file mode 100644 index 0000000..9ab97db --- /dev/null +++ b/media/test/data/bear-vp9.ivf.context Binary files differ
diff --git a/media/test/data/test-25fps.vp9.context b/media/test/data/test-25fps.vp9.context new file mode 100644 index 0000000..8add84c --- /dev/null +++ b/media/test/data/test-25fps.vp9.context Binary files differ
diff --git a/media/video/gpu_memory_buffer_video_frame_pool.cc b/media/video/gpu_memory_buffer_video_frame_pool.cc index 6c0e549d..82dd0e5 100644 --- a/media/video/gpu_memory_buffer_video_frame_pool.cc +++ b/media/video/gpu_memory_buffer_video_frame_pool.cc
@@ -605,6 +605,8 @@ return; } + frame->set_color_space(video_frame->ColorSpace()); + bool allow_overlay = false; switch (output_format_) { case PIXEL_FORMAT_I420:
diff --git a/mojo/edk/system/data_pipe_consumer_dispatcher.cc b/mojo/edk/system/data_pipe_consumer_dispatcher.cc index 23cb2e0..d5460cb 100644 --- a/mojo/edk/system/data_pipe_consumer_dispatcher.cc +++ b/mojo/edk/system/data_pipe_consumer_dispatcher.cc
@@ -421,6 +421,7 @@ dispatcher->bytes_available_ = state->bytes_available; dispatcher->peer_closed_ = state->flags & kFlagPeerClosed; dispatcher->InitializeNoLock(); + dispatcher->UpdateSignalsStateNoLock(); } return dispatcher;
diff --git a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc index 9ececaa..523c75eb 100644 --- a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc +++ b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
@@ -242,7 +242,7 @@ controller_->SyncWatch(&response_received); // Make sure that this instance hasn't been destroyed. if (weak_self) { - DCHECK(ContainsKey(sync_responses_, request_id)); + DCHECK(base::ContainsKey(sync_responses_, request_id)); auto iter = sync_responses_.find(request_id); DCHECK_EQ(&response_received, iter->second->response_received); if (response_received) {
diff --git a/mojo/public/cpp/bindings/lib/multiplex_router.cc b/mojo/public/cpp/bindings/lib/multiplex_router.cc index 06ece75..9c6431b0 100644 --- a/mojo/public/cpp/bindings/lib/multiplex_router.cc +++ b/mojo/public/cpp/bindings/lib/multiplex_router.cc
@@ -346,7 +346,7 @@ id = next_interface_id_value_++; if (set_interface_id_namespace_bit_) id |= kInterfaceIdNamespaceMask; - } while (ContainsKey(endpoints_, id)); + } while (base::ContainsKey(endpoints_, id)); InterfaceEndpoint* endpoint = new InterfaceEndpoint(this, id); endpoints_[id] = endpoint; @@ -384,7 +384,7 @@ base::AutoLock locker(lock_); if (!is_local) { - DCHECK(ContainsKey(endpoints_, id)); + DCHECK(base::ContainsKey(endpoints_, id)); DCHECK(!IsMasterInterfaceId(id)); // We will receive a NotifyPeerEndpointClosed message from the other side. @@ -393,7 +393,7 @@ return; } - DCHECK(ContainsKey(endpoints_, id)); + DCHECK(base::ContainsKey(endpoints_, id)); InterfaceEndpoint* endpoint = endpoints_[id].get(); DCHECK(!endpoint->client()); DCHECK(!endpoint->closed()); @@ -415,7 +415,7 @@ DCHECK(client); base::AutoLock locker(lock_); - DCHECK(ContainsKey(endpoints_, id)); + DCHECK(base::ContainsKey(endpoints_, id)); InterfaceEndpoint* endpoint = endpoints_[id].get(); endpoint->AttachClient(client, std::move(runner)); @@ -434,7 +434,7 @@ DCHECK(IsValidInterfaceId(id)); base::AutoLock locker(lock_); - DCHECK(ContainsKey(endpoints_, id)); + DCHECK(base::ContainsKey(endpoints_, id)); InterfaceEndpoint* endpoint = endpoints_[id].get(); endpoint->DetachClient(); @@ -494,7 +494,7 @@ if (endpoints_.size() == 0) return false; - return !ContainsKey(endpoints_, kMasterInterfaceId); + return !base::ContainsKey(endpoints_, kMasterInterfaceId); } void MultiplexRouter::EnableTestingMode() {
diff --git a/mojo/public/cpp/bindings/lib/router.cc b/mojo/public/cpp/bindings/lib/router.cc index 8c1b77d5..0bd916a3 100644 --- a/mojo/public/cpp/bindings/lib/router.cc +++ b/mojo/public/cpp/bindings/lib/router.cc
@@ -177,7 +177,7 @@ connector_.SyncWatch(&response_received); // Make sure that this instance hasn't been destroyed. if (weak_self) { - DCHECK(ContainsKey(sync_responses_, request_id)); + DCHECK(base::ContainsKey(sync_responses_, request_id)); auto iter = sync_responses_.find(request_id); DCHECK_EQ(&response_received, iter->second->response_received); if (response_received) {
diff --git a/mojo/public/cpp/bindings/lib/string_traits_wtf.cc b/mojo/public/cpp/bindings/lib/string_traits_wtf.cc index 19fa907..203f6f59 100644 --- a/mojo/public/cpp/bindings/lib/string_traits_wtf.cc +++ b/mojo/public/cpp/bindings/lib/string_traits_wtf.cc
@@ -16,7 +16,7 @@ struct UTF8AdaptorInfo { explicit UTF8AdaptorInfo(const WTF::String& input) : utf8_adaptor(input) { #if DCHECK_IS_ON() - original_size_in_bytes = static_cast<size_t>(input.sizeInBytes()); + original_size_in_bytes = input.charactersSizeInBytes(); #endif } @@ -34,8 +34,7 @@ UTF8AdaptorInfo* adaptor = static_cast<UTF8AdaptorInfo*>(context); #if DCHECK_IS_ON() - DCHECK_EQ(adaptor->original_size_in_bytes, - static_cast<size_t>(input.sizeInBytes())); + DCHECK_EQ(adaptor->original_size_in_bytes, input.charactersSizeInBytes()); #endif return adaptor; }
diff --git a/mojo/public/cpp/bindings/lib/sync_handle_registry.cc b/mojo/public/cpp/bindings/lib/sync_handle_registry.cc index f6372d9..ef236953 100644 --- a/mojo/public/cpp/bindings/lib/sync_handle_registry.cc +++ b/mojo/public/cpp/bindings/lib/sync_handle_registry.cc
@@ -34,7 +34,7 @@ const HandleCallback& callback) { DCHECK(thread_checker_.CalledOnValidThread()); - if (ContainsKey(handles_, handle)) + if (base::ContainsKey(handles_, handle)) return false; MojoResult result = MojoAddHandle(wait_set_handle_.get().value(), @@ -48,7 +48,7 @@ void SyncHandleRegistry::UnregisterHandle(const Handle& handle) { DCHECK(thread_checker_.CalledOnValidThread()); - if (!ContainsKey(handles_, handle)) + if (!base::ContainsKey(handles_, handle)) return; MojoResult result =
diff --git a/mojo/public/tools/bindings/BUILD.gn b/mojo/public/tools/bindings/BUILD.gn index 91f4cec..38304b9 100644 --- a/mojo/public/tools/bindings/BUILD.gn +++ b/mojo/public/tools/bindings/BUILD.gn
@@ -17,6 +17,9 @@ "$mojom_generator_root/generators/cpp_templates/interface_response_validator_declaration.tmpl", "$mojom_generator_root/generators/cpp_templates/interface_stub_declaration.tmpl", "$mojom_generator_root/generators/cpp_templates/module-internal.h.tmpl", + "$mojom_generator_root/generators/cpp_templates/module-shared-internal.h.tmpl", + "$mojom_generator_root/generators/cpp_templates/module-shared.cc.tmpl", + "$mojom_generator_root/generators/cpp_templates/module-shared.h.tmpl", "$mojom_generator_root/generators/cpp_templates/module.cc.tmpl", "$mojom_generator_root/generators/cpp_templates/module.h.tmpl", "$mojom_generator_root/generators/cpp_templates/struct_data_view_declaration.tmpl",
diff --git a/mojo/public/tools/bindings/chromium_bindings_configuration.gni b/mojo/public/tools/bindings/chromium_bindings_configuration.gni index 032b0c17..d1922f11 100644 --- a/mojo/public/tools/bindings/chromium_bindings_configuration.gni +++ b/mojo/public/tools/bindings/chromium_bindings_configuration.gni
@@ -8,11 +8,13 @@ "//components/arc/common/typemaps.gni", "//components/typemaps.gni", "//content/common/bluetooth/typemaps.gni", + "//content/common/typemaps.gni", "//device/bluetooth/public/interfaces/typemaps.gni", "//gpu/ipc/common/typemaps.gni", "//media/mojo/interfaces/typemaps.gni", "//mojo/common/typemaps.gni", "//mojo/public/cpp/bindings/tests/chromium_typemaps.gni", + "//services/shell/public/cpp/typemaps.gni", "//services/ui/public/interfaces/display/typemaps.gni", "//skia/public/interfaces/typemaps.gni", "//ui/events/devices/mojo/typemaps.gni",
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl new file mode 100644 index 0000000..70b6a9a --- /dev/null +++ b/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl
@@ -0,0 +1,5 @@ +// Copyright 2016 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. + +// TODO(yzshen): Move code here.
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module-shared.cc.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module-shared.cc.tmpl new file mode 100644 index 0000000..70b6a9a --- /dev/null +++ b/mojo/public/tools/bindings/generators/cpp_templates/module-shared.cc.tmpl
@@ -0,0 +1,5 @@ +// Copyright 2016 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. + +// TODO(yzshen): Move code here.
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl new file mode 100644 index 0000000..e21ec73 --- /dev/null +++ b/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl
@@ -0,0 +1,15 @@ +// Copyright 2016 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. + +{%- set header_guard = "%s_SHARED_H_"|format( + module.path|upper|replace("/","_")|replace(".","_")| + replace("-", "_")) %} + +#ifndef {{header_guard}} +#define {{header_guard}} + +// TODO(yzshen): Move code here. + +#endif // {{header_guard}} +
diff --git a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py index fec7a6be..a9fa2398 100644 --- a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py +++ b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
@@ -527,19 +527,42 @@ def GenerateModuleSource(self): return self.GetJinjaExports() + @UseJinja("module-shared.h.tmpl") + def GenerateModuleSharedHeader(self): + return self.GetJinjaExports() + + @UseJinja("module-shared-internal.h.tmpl") + def GenerateModuleSharedInternalHeader(self): + return self.GetJinjaExports() + + @UseJinja("module-shared.cc.tmpl") + def GenerateModuleSharedSource(self): + return self.GetJinjaExports() + def GenerateFiles(self, args): - global _current_typemap - _current_typemap = self.typemap - global _for_blink - _for_blink = self.for_blink - global _use_new_wrapper_types - _use_new_wrapper_types = self.use_new_wrapper_types - global _variant - _variant = self.variant - suffix = "-%s" % self.variant if self.variant else "" - self.Write(self.GenerateModuleHeader(), - self.MatchMojomFilePath("%s%s.h" % (self.module.name, suffix))) - self.Write(self.GenerateModuleInternalHeader(), - self.MatchMojomFilePath("%s%s-internal.h" % (self.module.name, suffix))) - self.Write(self.GenerateModuleSource(), - self.MatchMojomFilePath("%s%s.cc" % (self.module.name, suffix))) + if self.generate_non_variant_code: + self.Write(self.GenerateModuleSharedHeader(), + self.MatchMojomFilePath("%s-shared.h" % self.module.name)) + self.Write( + self.GenerateModuleSharedInternalHeader(), + self.MatchMojomFilePath("%s-shared-internal.h" % self.module.name)) + self.Write(self.GenerateModuleSharedSource(), + self.MatchMojomFilePath("%s-shared.cc" % self.module.name)) + else: + global _current_typemap + _current_typemap = self.typemap + global _for_blink + _for_blink = self.for_blink + global _use_new_wrapper_types + _use_new_wrapper_types = self.use_new_wrapper_types + global _variant + _variant = self.variant + suffix = "-%s" % self.variant if self.variant else "" + self.Write(self.GenerateModuleHeader(), + self.MatchMojomFilePath("%s%s.h" % (self.module.name, suffix))) + self.Write(self.GenerateModuleInternalHeader(), + self.MatchMojomFilePath("%s%s-internal.h" % + (self.module.name, suffix))) + self.Write( + self.GenerateModuleSource(), + self.MatchMojomFilePath("%s%s.cc" % (self.module.name, suffix)))
diff --git a/mojo/public/tools/bindings/mojom.gni b/mojo/public/tools/bindings/mojom.gni index 4705a5f4..1fe901b 100644 --- a/mojo/public/tools/bindings/mojom.gni +++ b/mojo/public/tools/bindings/mojom.gni
@@ -136,6 +136,77 @@ } } + # Generate code that is shared by different variants. + if (defined(invoker.sources)) { + common_generator_args = [ + "--use_bundled_pylibs", + "generate", + "{{source}}", + "-d", + rebase_path("//", root_build_dir), + "-I", + rebase_path("//", root_build_dir), + "-o", + rebase_path(root_gen_dir), + "--bytecode_path", + rebase_path("$root_gen_dir/mojo/public/tools/bindings"), + ] + + if (defined(invoker.import_dirs)) { + foreach(import_dir, invoker.import_dirs) { + common_generator_args += [ + "-I", + rebase_path(import_dir, root_build_dir), + ] + } + } + + generator_shared_cpp_outputs = [ + "{{source_gen_dir}}/{{source_name_part}}.mojom-shared-internal.h", + "{{source_gen_dir}}/{{source_name_part}}.mojom-shared.cc", + "{{source_gen_dir}}/{{source_name_part}}.mojom-shared.h", + ] + generator_shared_target_name = "${target_name}_shared__generator" + action_foreach(generator_shared_target_name) { + script = mojom_generator_script + inputs = mojom_generator_sources + sources = invoker.sources + deps = [ + "//mojo/public/tools/bindings:precompile_templates", + ] + outputs = generator_shared_cpp_outputs + args = common_generator_args + args += [ + "--generate_non_variant_code", + "-g", + "c++", + ] + } + } + + shared_cpp_sources_suffix = "shared_cpp_sources" + shared_cpp_sources_target_name = "${target_name}_${shared_cpp_sources_suffix}" + source_set(shared_cpp_sources_target_name) { + if (defined(invoker.testonly)) { + testonly = invoker.testonly + } + deps = [] + if (defined(invoker.sources)) { + sources = + process_file_template(invoker.sources, generator_shared_cpp_outputs) + deps += [ ":$generator_shared_target_name" ] + } + public_deps = [] + foreach(d, all_deps) { + # Resolve the name, so that a target //mojo/something becomes + # //mojo/something:something and we can append shared_cpp_sources_suffix + # to get the cpp dependency name. + full_name = get_label_info("$d", "label_no_toolchain") + public_deps += [ "${full_name}_${shared_cpp_sources_suffix}" ] + } + } + + # Generate code for variants. foreach(bindings_configuration, _bindings_configurations) { cpp_only = false variant_suffix = "" @@ -207,28 +278,7 @@ ] outputs = generator_cpp_outputs + generator_java_outputs + generator_js_outputs - args = [ - "--use_bundled_pylibs", - "generate", - "{{source}}", - "-d", - rebase_path("//", root_build_dir), - "-I", - rebase_path("//", root_build_dir), - "-o", - rebase_path(root_gen_dir), - "--bytecode_path", - rebase_path("$root_gen_dir/mojo/public/tools/bindings"), - ] - - if (defined(invoker.import_dirs)) { - foreach(import_dir, invoker.import_dirs) { - args += [ - "-I", - rebase_path(import_dir, root_build_dir), - ] - } - } + args = common_generator_args if (cpp_only) { args += [ @@ -386,6 +436,7 @@ sources = process_file_template(enabled_sources, generator_cpp_outputs) } deps = [ + ":$shared_cpp_sources_target_name", "//mojo/public/cpp/bindings:struct_traits", "//mojo/public/interfaces/bindings:bindings__generator", ]
diff --git a/mojo/public/tools/bindings/mojom_bindings_generator.py b/mojo/public/tools/bindings/mojom_bindings_generator.py index 48e3b88..93bcaf3 100755 --- a/mojo/public/tools/bindings/mojom_bindings_generator.py +++ b/mojo/public/tools/bindings/mojom_bindings_generator.py
@@ -165,7 +165,8 @@ for_blink=args.for_blink, use_new_wrapper_types=args.use_new_wrapper_types, export_attribute=args.export_attribute, - export_header=args.export_header) + export_header=args.export_header, + generate_non_variant_code=args.generate_non_variant_code) filtered_args = [] if hasattr(generator_module, 'GENERATOR_PREFIX'): prefix = '--' + generator_module.GENERATOR_PREFIX + '_' @@ -299,6 +300,9 @@ "--export_header", type=str, default="", help="Optional header to include in the generated headers to support the " "component build.") + generate_parser.add_argument( + "--generate_non_variant_code", action="store_true", + help="Generate code that is shared by different variants.") generate_parser.set_defaults(func=_Generate) precompile_parser = subparsers.add_parser("precompile",
diff --git a/mojo/public/tools/bindings/pylib/mojom/generate/generator.py b/mojo/public/tools/bindings/pylib/mojom/generate/generator.py index 1a10e8b..f76cc2e 100644 --- a/mojo/public/tools/bindings/pylib/mojom/generate/generator.py +++ b/mojo/public/tools/bindings/pylib/mojom/generate/generator.py
@@ -38,7 +38,8 @@ # files to stdout. def __init__(self, module, output_dir=None, typemap=None, variant=None, bytecode_path=None, for_blink=False, use_new_wrapper_types=False, - export_attribute=None, export_header=None): + export_attribute=None, export_header=None, + generate_non_variant_code=False): self.module = module self.output_dir = output_dir self.typemap = typemap or {} @@ -48,6 +49,7 @@ self.use_new_wrapper_types = use_new_wrapper_types self.export_attribute = export_attribute self.export_header = export_header + self.generate_non_variant_code = generate_non_variant_code def GetStructsFromMethods(self): result = []
diff --git a/native_client_sdk/src/doc/OWNERS b/native_client_sdk/src/doc/OWNERS index b66534ba..61fe60d 100644 --- a/native_client_sdk/src/doc/OWNERS +++ b/native_client_sdk/src/doc/OWNERS
@@ -1,5 +1,3 @@ binji@chromium.org -jfb@chromium.org -jmedley@chromium.org +bradnelson@chromium.org sbc@chromium.org -sehr@chromium.org
diff --git a/net/base/expiring_cache_unittest.cc b/net/base/expiring_cache_unittest.cc index 74b069d..f1414f9 100644 --- a/net/base/expiring_cache_unittest.cc +++ b/net/base/expiring_cache_unittest.cc
@@ -119,16 +119,16 @@ } EXPECT_EQ(10U, cache.size()); - EXPECT_TRUE(ContainsKey(cache.entries_, "valid0")); - EXPECT_TRUE(ContainsKey(cache.entries_, "valid1")); - EXPECT_TRUE(ContainsKey(cache.entries_, "valid2")); - EXPECT_TRUE(ContainsKey(cache.entries_, "valid3")); - EXPECT_TRUE(ContainsKey(cache.entries_, "valid4")); - EXPECT_TRUE(ContainsKey(cache.entries_, "expired0")); - EXPECT_TRUE(ContainsKey(cache.entries_, "expired1")); - EXPECT_TRUE(ContainsKey(cache.entries_, "expired2")); - EXPECT_TRUE(ContainsKey(cache.entries_, "negative0")); - EXPECT_TRUE(ContainsKey(cache.entries_, "negative1")); + EXPECT_TRUE(base::ContainsKey(cache.entries_, "valid0")); + EXPECT_TRUE(base::ContainsKey(cache.entries_, "valid1")); + EXPECT_TRUE(base::ContainsKey(cache.entries_, "valid2")); + EXPECT_TRUE(base::ContainsKey(cache.entries_, "valid3")); + EXPECT_TRUE(base::ContainsKey(cache.entries_, "valid4")); + EXPECT_TRUE(base::ContainsKey(cache.entries_, "expired0")); + EXPECT_TRUE(base::ContainsKey(cache.entries_, "expired1")); + EXPECT_TRUE(base::ContainsKey(cache.entries_, "expired2")); + EXPECT_TRUE(base::ContainsKey(cache.entries_, "negative0")); + EXPECT_TRUE(base::ContainsKey(cache.entries_, "negative1")); // Shrink the new max constraints bound and compact. The "negative" and // "expired" entries should be dropped. @@ -136,16 +136,16 @@ cache.Compact(now); EXPECT_EQ(5U, cache.size()); - EXPECT_TRUE(ContainsKey(cache.entries_, "valid0")); - EXPECT_TRUE(ContainsKey(cache.entries_, "valid1")); - EXPECT_TRUE(ContainsKey(cache.entries_, "valid2")); - EXPECT_TRUE(ContainsKey(cache.entries_, "valid3")); - EXPECT_TRUE(ContainsKey(cache.entries_, "valid4")); - EXPECT_FALSE(ContainsKey(cache.entries_, "expired0")); - EXPECT_FALSE(ContainsKey(cache.entries_, "expired1")); - EXPECT_FALSE(ContainsKey(cache.entries_, "expired2")); - EXPECT_FALSE(ContainsKey(cache.entries_, "negative0")); - EXPECT_FALSE(ContainsKey(cache.entries_, "negative1")); + EXPECT_TRUE(base::ContainsKey(cache.entries_, "valid0")); + EXPECT_TRUE(base::ContainsKey(cache.entries_, "valid1")); + EXPECT_TRUE(base::ContainsKey(cache.entries_, "valid2")); + EXPECT_TRUE(base::ContainsKey(cache.entries_, "valid3")); + EXPECT_TRUE(base::ContainsKey(cache.entries_, "valid4")); + EXPECT_FALSE(base::ContainsKey(cache.entries_, "expired0")); + EXPECT_FALSE(base::ContainsKey(cache.entries_, "expired1")); + EXPECT_FALSE(base::ContainsKey(cache.entries_, "expired2")); + EXPECT_FALSE(base::ContainsKey(cache.entries_, "negative0")); + EXPECT_FALSE(base::ContainsKey(cache.entries_, "negative1")); // Shrink further -- this time the compact will start dropping valid entries // to make space.
diff --git a/net/base/filename_util_internal.cc b/net/base/filename_util_internal.cc index 6eb3f55..fa0a91f 100644 --- a/net/base/filename_util_internal.cc +++ b/net/base/filename_util_internal.cc
@@ -54,7 +54,7 @@ // "foo.jpg" to "foo.jpeg". std::vector<base::FilePath::StringType> all_mime_extensions; GetExtensionsForMimeType(mime_type, &all_mime_extensions); - if (ContainsValue(all_mime_extensions, extension)) + if (base::ContainsValue(all_mime_extensions, extension)) return extension; // Get the "final" extension. In most cases, this is the same as the @@ -68,7 +68,7 @@ // If there's a double extension, and the second extension is in the // list of valid extensions for the given type, keep the double extension. // This avoids renaming things like "foo.tar.gz" to "foo.gz". - if (ContainsValue(all_mime_extensions, final_extension)) + if (base::ContainsValue(all_mime_extensions, final_extension)) return extension; return preferred_mime_extension; }
diff --git a/net/base/network_activity_monitor_unittest.cc b/net/base/network_activity_monitor_unittest.cc index 78b4521..7e2e4567 100644 --- a/net/base/network_activity_monitor_unittest.cc +++ b/net/base/network_activity_monitor_unittest.cc
@@ -119,7 +119,7 @@ base::Bind(&VerifyBytesReceivedIsMultipleOf, bytes_received)); } - STLDeleteElements(&threads); + base::STLDeleteElements(&threads); NetworkActivityMonitor* monitor = NetworkActivityMonitor::GetInstance(); EXPECT_EQ(num_increments * bytes_received, monitor->GetBytesReceived());
diff --git a/net/cert/ct_signed_certificate_timestamp_log_param.cc b/net/cert/ct_signed_certificate_timestamp_log_param.cc index f829e56a..7566081 100644 --- a/net/cert/ct_signed_certificate_timestamp_log_param.cc +++ b/net/cert/ct_signed_certificate_timestamp_log_param.cc
@@ -37,10 +37,12 @@ // is this field's value in the SCT. This dictionary is meant to be used for // outputting a de-serialized SCT to the NetLog. std::unique_ptr<base::DictionaryValue> SCTToDictionary( - const ct::SignedCertificateTimestamp& sct) { + const ct::SignedCertificateTimestamp& sct, + ct::SCTVerifyStatus status) { std::unique_ptr<base::DictionaryValue> out(new base::DictionaryValue()); out->SetString("origin", OriginToString(sct.origin)); + out->SetString("verification_status", StatusToString(status)); out->SetInteger("version", sct.version); SetBinaryData("log_id", sct.log_id, out.get()); @@ -59,13 +61,14 @@ return out; } -// Given a list of SCTs, return a ListValue instance where each item in the -// list is a dictionary created by SCTToDictionary. +// Given a list of SCTs and their statuses, return a ListValue instance where +// each item in the list is a dictionary created by SCTToDictionary. std::unique_ptr<base::ListValue> SCTListToPrintableValues( - const ct::SCTList& sct_list) { + const SignedCertificateTimestampAndStatusList& sct_and_status_list) { std::unique_ptr<base::ListValue> output_scts(new base::ListValue()); - for (const auto& sct : sct_list) - output_scts->Append(SCTToDictionary(*(sct.get()))); + for (const auto& sct_and_status : sct_and_status_list) + output_scts->Append( + SCTToDictionary(*(sct_and_status.sct.get()), sct_and_status.status)); return output_scts; } @@ -77,14 +80,7 @@ NetLogCaptureMode capture_mode) { std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - dict->Set("verified_scts", - SCTListToPrintableValues(ct_result->verified_scts)); - - dict->Set("invalid_scts", - SCTListToPrintableValues(ct_result->invalid_scts)); - - dict->Set("unknown_logs_scts", - SCTListToPrintableValues(ct_result->unknown_logs_scts)); + dict->Set("scts", SCTListToPrintableValues(ct_result->scts)); return std::move(dict); }
diff --git a/net/cert/ct_verify_result.cc b/net/cert/ct_verify_result.cc index 227bc12..5587b67 100644 --- a/net/cert/ct_verify_result.cc +++ b/net/cert/ct_verify_result.cc
@@ -20,6 +20,17 @@ CTVerifyResult::~CTVerifyResult() {} +SCTList SCTsMatchingStatus( + const SignedCertificateTimestampAndStatusList& sct_and_status_list, + SCTVerifyStatus match_status) { + SCTList result; + for (const auto& sct_and_status : sct_and_status_list) + if (sct_and_status.status == match_status) + result.push_back(sct_and_status.sct); + + return result; +} + } // namespace ct } // namespace net
diff --git a/net/cert/ct_verify_result.h b/net/cert/ct_verify_result.h index ca16358..33a25dd 100644 --- a/net/cert/ct_verify_result.h +++ b/net/cert/ct_verify_result.h
@@ -7,8 +7,9 @@ #include <vector> +#include "net/base/net_export.h" #include "net/cert/ct_policy_enforcer.h" -#include "net/cert/signed_certificate_timestamp.h" +#include "net/cert/signed_certificate_timestamp_and_status.h" namespace net { @@ -27,12 +28,8 @@ CTVerifyResult(const CTVerifyResult& other); ~CTVerifyResult(); - // SCTs from known logs where the signature verified correctly. - SCTList verified_scts; - // SCTs from known logs where the signature failed to verify. - SCTList invalid_scts; - // SCTs from unknown logs and as such are unverifiable. - SCTList unknown_logs_scts; + // All SCTs and their statuses + SignedCertificateTimestampAndStatusList scts; // True if any CT policies were applied on this connection. bool ct_policies_applied; @@ -44,6 +41,12 @@ EVPolicyCompliance ev_policy_compliance; }; +// Returns a list of SCTs from |sct_and_status_list| whose status matches +// |match_status|. +SCTList NET_EXPORT SCTsMatchingStatus( + const SignedCertificateTimestampAndStatusList& sct_and_status_list, + SCTVerifyStatus match_status); + } // namespace ct } // namespace net
diff --git a/net/cert/internal/nist_pkits_unittest.h b/net/cert/internal/nist_pkits_unittest.h index aaf3992..47fd462 100644 --- a/net/cert/internal/nist_pkits_unittest.h +++ b/net/cert/internal/nist_pkits_unittest.h
@@ -5,9 +5,7 @@ #ifndef NET_CERT_INTERNAL_NIST_PKITS_UNITTEST_H #define NET_CERT_INTERNAL_NIST_PKITS_UNITTEST_H -#include "base/base_paths.h" -#include "base/files/file_util.h" -#include "base/path_service.h" +#include "net/cert/internal/test_helpers.h" #include "testing/gtest/include/gtest/gtest.h" // Parameterized test class for PKITS tests. @@ -22,30 +20,14 @@ const char* const (&crl_names)[num_crls]) { std::vector<std::string> cert_ders; for (const std::string& s : cert_names) - cert_ders.push_back(ReadTestFileToString("certs/" + s + ".crt")); + cert_ders.push_back(net::ReadTestFileToString( + "net/third_party/nist-pkits/certs/" + s + ".crt")); std::vector<std::string> crl_ders; for (const std::string& s : crl_names) - crl_ders.push_back(ReadTestFileToString("crls/" + s + ".crl")); + crl_ders.push_back(net::ReadTestFileToString( + "net/third_party/nist-pkits/crls/" + s + ".crl")); return PkitsTestDelegate::Verify(cert_ders, crl_ders); } - - private: - std::string ReadTestFileToString(const std::string& file_name) { - // Compute the full path, relative to the src/ directory. - base::FilePath src_root; - PathService::Get(base::DIR_SOURCE_ROOT, &src_root); - base::FilePath filepath = src_root.AppendASCII( - std::string("net/third_party/nist-pkits/") + file_name); - - // Read the full contents of the file. - std::string file_data; - if (!base::ReadFileToString(filepath, &file_data)) { - ADD_FAILURE() << "Couldn't read file: " << filepath.value(); - return std::string(); - } - - return file_data; - } }; // Inline the generated test code:
diff --git a/net/cert/internal/path_builder.cc b/net/cert/internal/path_builder.cc index 863d850..2522790 100644 --- a/net/cert/internal/path_builder.cc +++ b/net/cert/internal/path_builder.cc
@@ -8,6 +8,7 @@ #include <unordered_set> #include "base/callback_helpers.h" +#include "base/logging.h" #include "base/memory/ptr_util.h" #include "net/base/net_errors.h" #include "net/cert/internal/cert_issuer_source.h" @@ -40,6 +41,26 @@ return subject_str + "(" + issuer_str + ")"; } +// This structure contains either a ParsedCertificate or a TrustAnchor. It is +// used to describe the result of getting a certificate's issuer, which may +// either be another certificate, or a trust anchor. +struct CertificateOrTrustAnchor { + CertificateOrTrustAnchor() {} + + explicit CertificateOrTrustAnchor(scoped_refptr<ParsedCertificate> cert) + : cert(std::move(cert)) {} + + explicit CertificateOrTrustAnchor(scoped_refptr<TrustAnchor> anchor) + : anchor(std::move(anchor)) {} + + bool IsTrustAnchor() const { return anchor.get() != nullptr; } + bool IsCertificate() const { return cert.get() != nullptr; } + bool IsEmpty() const { return !IsTrustAnchor() && !IsCertificate(); } + + scoped_refptr<ParsedCertificate> cert; + scoped_refptr<TrustAnchor> anchor; +}; + // CertIssuersIter iterates through the intermediates from |cert_issuer_sources| // which may be issuers of |cert|. class CertIssuersIter { @@ -51,12 +72,12 @@ const TrustStore& trust_store); // Gets the next candidate issuer. If an issuer is ready synchronously, SYNC - // is returned and the cert is stored in |*out_cert|. If an issuer is not + // is returned and the cert is stored in |*cert|. If an issuer is not // ready, ASYNC is returned and |callback| will be called once |*out_cert| has // been set. If |callback| is null, always completes synchronously. // - // In either case, if all issuers have been exhausted, |*out_cert| is cleared. - CompletionStatus GetNextIssuer(scoped_refptr<ParsedCertificate>* out_cert, + // In either case, if all issuers have been exhausted, |*out| is cleared. + CompletionStatus GetNextIssuer(CertificateOrTrustAnchor* out, const base::Closure& callback); // Returns the |cert| for which issuers are being retrieved. @@ -69,6 +90,11 @@ scoped_refptr<ParsedCertificate> cert_; CertIssuerSources* cert_issuer_sources_; + // The list of trust anchors that match the issuer name for |cert_|. + TrustAnchors anchors_; + // The index of the next trust anchor in |anchors_| to return. + size_t cur_anchor_ = 0; + // The list of issuers for |cert_|. This is added to incrementally (first // synchronous results, then possibly multiple times as asynchronous results // arrive.) The issuers may be re-sorted each time new issuers are added, but @@ -78,7 +104,8 @@ // |present_issuers_| will point to data owned by the certs. ParsedCertificateList issuers_; // The index of the next cert in |issuers_| to return. - size_t cur_ = 0; + size_t cur_issuer_ = 0; + // Set of DER-encoded values for the certs in |issuers_|. Used to prevent // duplicates. This is based on the full DER of the cert to allow different // versions of the same certificate to be tried in different candidate paths. @@ -94,10 +121,10 @@ std::vector<std::unique_ptr<CertIssuerSource::Request>> pending_async_requests_; - // When GetNextIssuer was called and returned asynchronously, |*out_cert_| is + // When GetNextIssuer was called and returned asynchronously, |*out_| is // where the result will be stored, and |callback_| will be run when the // result is ready. - scoped_refptr<ParsedCertificate>* out_cert_; + CertificateOrTrustAnchor* out_; base::Closure callback_; DISALLOW_COPY_AND_ASSIGN(CertIssuersIter); @@ -109,12 +136,7 @@ : cert_(in_cert), cert_issuer_sources_(cert_issuer_sources) { DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) << ") created"; trust_store.FindTrustAnchorsByNormalizedName(in_cert->normalized_issuer(), - &issuers_); - // Insert matching roots into |present_issuers_| in case they also are - // returned by a CertIssuerSource. It is assumed - // FindTrustAnchorsByNormalizedName does not itself return dupes. - for (const auto& root : issuers_) - present_issuers_.insert(root->der_cert().AsStringPiece()); + &anchors_); for (auto* cert_issuer_source : *cert_issuer_sources_) { ParsedCertificateList new_issuers; @@ -134,19 +156,29 @@ // is done) } -CompletionStatus CertIssuersIter::GetNextIssuer( - scoped_refptr<ParsedCertificate>* out_cert, - const base::Closure& callback) { +CompletionStatus CertIssuersIter::GetNextIssuer(CertificateOrTrustAnchor* out, + const base::Closure& callback) { // Should not be called again while already waiting for an async result. DCHECK(callback_.is_null()); - if (cur_ < issuers_.size()) { + // Return possible trust anchors first. + if (cur_anchor_ < anchors_.size()) { DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) - << "): returning item " << cur_ << " of " << issuers_.size(); + << "): returning anchor " << cur_anchor_ << " of " + << anchors_.size(); + // Still have anchors that haven't been returned yet, return one of them. + *out = CertificateOrTrustAnchor(anchors_[cur_anchor_++]); + return CompletionStatus::SYNC; + } + + if (cur_issuer_ < issuers_.size()) { + DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) + << "): returning issuer " << cur_issuer_ << " of " + << issuers_.size(); // Still have issuers that haven't been returned yet, return one of them. // A reference to the returned issuer is retained, since |present_issuers_| // points to data owned by it. - *out_cert = issuers_[cur_++]; + *out = CertificateOrTrustAnchor(issuers_[cur_issuer_++]); return CompletionStatus::SYNC; } if (did_async_query_) { @@ -154,7 +186,7 @@ DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) << ") Reached the end of all available issuers."; // Reached the end of all available issuers. - *out_cert = nullptr; + *out = CertificateOrTrustAnchor(); return CompletionStatus::SYNC; } @@ -162,7 +194,7 @@ << ") Still waiting for async results from other " "CertIssuerSources."; // Still waiting for async results from other CertIssuerSources. - out_cert_ = out_cert; + out_ = out; callback_ = callback; return CompletionStatus::ASYNC; } @@ -170,7 +202,7 @@ if (callback.is_null()) { // Synchronous-only mode, don't try to query async sources. - *out_cert = nullptr; + *out = CertificateOrTrustAnchor(); return CompletionStatus::SYNC; } @@ -195,14 +227,14 @@ DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) << ") No cert sources have async results."; // No cert sources have async results. - *out_cert = nullptr; + *out = CertificateOrTrustAnchor(); return CompletionStatus::SYNC; } DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) << ") issued AsyncGetIssuersOf call(s) (n=" << pending_async_results_ << ")"; - out_cert_ = out_cert; + out_ = out; callback_ = callback; return CompletionStatus::ASYNC; } @@ -235,16 +267,17 @@ // Notify that more results are available, if necessary. if (!callback_.is_null()) { - if (cur_ < issuers_.size()) { + DCHECK_GE(cur_anchor_, anchors_.size()); + if (cur_issuer_ < issuers_.size()) { DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) - << "): async returning item " << cur_ << " of " + << "): async returning item " << cur_issuer_ << " of " << issuers_.size(); - *out_cert_ = std::move(issuers_[cur_++]); + *out_ = CertificateOrTrustAnchor(std::move(issuers_[cur_issuer_++])); base::ResetAndReturn(&callback_).Run(); } else if (pending_async_results_ == 0) { DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) << "): async returning empty result"; - *out_cert_ = nullptr; + *out_ = CertificateOrTrustAnchor(); base::ResetAndReturn(&callback_).Run(); } else { DVLOG(1) << "CertIssuersIter(" << CertDebugString(cert()) @@ -328,6 +361,18 @@ } // namespace +CertPath::CertPath() = default; +CertPath::~CertPath() = default; + +void CertPath::Clear() { + trust_anchor = nullptr; + certs.clear(); +} + +bool CertPath::IsEmpty() const { + return certs.empty(); +} + // CertPathIter generates possible paths from |cert| to a trust anchor in // |trust_store|, using intermediates from the |cert_issuer_source| objects if // necessary. @@ -345,8 +390,7 @@ // returned and the path is stored in |*path|. If a path is not ready, // ASYNC is returned and |callback| will be called once |*path| has been set. // In either case, if all paths have been exhausted, |*path| is cleared. - CompletionStatus GetNextPath(ParsedCertificateList* path, - const base::Closure& callback); + CompletionStatus GetNextPath(CertPath* path, const base::Closure& callback); private: enum State { @@ -365,9 +409,9 @@ void HandleGotNextIssuer(void); - // Stores the next candidate issuer certificate, until it is used during the + // Stores the next candidate issuer, until it is used during the // STATE_GET_NEXT_ISSUER_COMPLETE step. - scoped_refptr<ParsedCertificate> next_cert_; + CertificateOrTrustAnchor next_issuer_; // The current path being explored, made up of CertIssuerIters. Each node // keeps track of the state of searching for issuers of that cert, so that // when backtracking it can resume the search where it left off. @@ -375,10 +419,11 @@ // The CertIssuerSources for retrieving candidate issuers. CertIssuerSources cert_issuer_sources_; // The TrustStore for checking if a path ends in a trust anchor. + // TODO: is this comment correct anymore? const TrustStore* trust_store_; // The output variable for storing the next candidate path, which the client // passes in to GetNextPath. Only used for a single path output. - ParsedCertificateList* out_path_; + CertPath* out_path_; // The callback to be called if an async lookup generated a candidate path. base::Closure callback_; // Current state of the state machine. @@ -389,7 +434,7 @@ CertPathIter::CertPathIter(scoped_refptr<ParsedCertificate> cert, const TrustStore* trust_store) - : next_cert_(std::move(cert)), + : next_issuer_(std::move(cert)), trust_store_(trust_store), next_state_(STATE_GET_NEXT_ISSUER_COMPLETE) {} @@ -397,10 +442,10 @@ cert_issuer_sources_.push_back(cert_issuer_source); } -CompletionStatus CertPathIter::GetNextPath(ParsedCertificateList* path, +CompletionStatus CertPathIter::GetNextPath(CertPath* path, const base::Closure& callback) { out_path_ = path; - out_path_->clear(); + out_path_->Clear(); CompletionStatus rv = DoLoop(!callback.is_null()); if (rv == CompletionStatus::ASYNC) { callback_ = callback; @@ -446,35 +491,35 @@ CompletionStatus CertPathIter::DoGetNextIssuer(bool allow_async) { next_state_ = STATE_GET_NEXT_ISSUER_COMPLETE; CompletionStatus rv = cur_path_.back()->GetNextIssuer( - &next_cert_, allow_async ? base::Bind(&CertPathIter::HandleGotNextIssuer, - base::Unretained(this)) - : base::Closure()); + &next_issuer_, allow_async + ? base::Bind(&CertPathIter::HandleGotNextIssuer, + base::Unretained(this)) + : base::Closure()); return rv; } CompletionStatus CertPathIter::DoGetNextIssuerComplete() { - if (next_cert_) { + // If the issuer is a trust anchor signal readiness. + if (next_issuer_.IsTrustAnchor()) { + DVLOG(1) << "CertPathIter got anchor(" + << CertDebugString(next_issuer_.anchor->cert().get()); + next_state_ = STATE_RETURN_A_PATH; + cur_path_.CopyPath(&out_path_->certs); + out_path_->trust_anchor = std::move(next_issuer_.anchor); + next_issuer_ = CertificateOrTrustAnchor(); + return CompletionStatus::SYNC; + } + + if (next_issuer_.IsCertificate()) { // Skip this cert if it is already in the chain. - if (cur_path_.IsPresent(next_cert_.get())) { + if (cur_path_.IsPresent(next_issuer_.cert.get())) { next_state_ = STATE_GET_NEXT_ISSUER; return CompletionStatus::SYNC; } - // If the cert matches a trust root, this is a (possibly) complete path. - // Signal readiness. Don't add it to cur_path_, since that would cause an - // unnecessary lookup of issuers of the trust root. - if (trust_store_->IsTrustedCertificate(next_cert_.get())) { - DVLOG(1) << "CertPathIter IsTrustedCertificate(" - << CertDebugString(next_cert_.get()) << ") = true"; - next_state_ = STATE_RETURN_A_PATH; - cur_path_.CopyPath(out_path_); - out_path_->push_back(std::move(next_cert_)); - next_cert_ = nullptr; - return CompletionStatus::SYNC; - } cur_path_.Append(base::WrapUnique(new CertIssuersIter( - std::move(next_cert_), &cert_issuer_sources_, *trust_store_))); - next_cert_ = nullptr; + std::move(next_issuer_.cert), &cert_issuer_sources_, *trust_store_))); + next_issuer_ = CertificateOrTrustAnchor(); DVLOG(1) << "CertPathIter cur_path_ = " << cur_path_.PathDebugString(); // Continue descending the tree. next_state_ = STATE_GET_NEXT_ISSUER; @@ -523,7 +568,6 @@ const der::GeneralizedTime& time, Result* result) : cert_path_iter_(new CertPathIter(std::move(cert), trust_store)), - trust_store_(trust_store), signature_policy_(signature_policy), time_(time), next_state_(STATE_NONE), @@ -586,14 +630,16 @@ } CompletionStatus CertPathBuilder::DoGetNextPathComplete() { - if (next_path_.empty()) { + if (next_path_.IsEmpty()) { // No more paths to check, signal completion. next_state_ = STATE_NONE; return CompletionStatus::SYNC; } - bool verify_result = VerifyCertificateChainAssumingTrustedRoot( - next_path_, *trust_store_, signature_policy_, time_); + bool verify_result = + next_path_.trust_anchor.get() && + VerifyCertificateChain(next_path_.certs, next_path_.trust_anchor.get(), + signature_policy_, time_); DVLOG(1) << "CertPathBuilder VerifyCertificateChain result = " << verify_result; AddResultPath(next_path_, verify_result); @@ -612,8 +658,7 @@ return CompletionStatus::SYNC; } -void CertPathBuilder::AddResultPath(const ParsedCertificateList& path, - bool is_success) { +void CertPathBuilder::AddResultPath(const CertPath& path, bool is_success) { std::unique_ptr<ResultPath> result_path(new ResultPath()); // TODO(mattm): better error reporting. result_path->error = is_success ? OK : ERR_CERT_AUTHORITY_INVALID;
diff --git a/net/cert/internal/path_builder.h b/net/cert/internal/path_builder.h index f08ad127..177f0d6e 100644 --- a/net/cert/internal/path_builder.h +++ b/net/cert/internal/path_builder.h
@@ -15,6 +15,7 @@ #include "net/base/net_export.h" #include "net/cert/internal/completion_status.h" #include "net/cert/internal/parsed_certificate.h" +#include "net/cert/internal/trust_store.h" #include "net/der/input.h" #include "net/der/parse_values.h" @@ -26,9 +27,30 @@ class CertPathIter; class CertIssuerSource; -class TrustStore; class SignaturePolicy; +// CertPath describes a chain of certificates in the "forward" direction. +// +// By convention: +// certs[0] is the target certificate +// certs[i] was issued by certs[i+1] +// certs.back() was issued by trust_anchor +struct NET_EXPORT CertPath { + CertPath(); + ~CertPath(); + + scoped_refptr<TrustAnchor> trust_anchor; + + // Path in the forward direction (path[0] is the target cert). + ParsedCertificateList certs; + + // Resets the path to empty path (same as if default constructed). + void Clear(); + + // Returns true if the path is empty. + bool IsEmpty() const; +}; + // Checks whether a certificate is trusted by building candidate paths to trust // anchors and verifying those paths according to RFC 5280. Each instance of // CertPathBuilder is used for a single verification. @@ -45,14 +67,9 @@ // Returns true if this path was successfully verified. bool is_success() const { return error == OK; } - // The candidate path, in forward direction. - // * path[0] is the target certificate. - // * path[i+1] is a candidate issuer of path[i]. The subject matches - // path[i]'s issuer, but nothing else is guaranteed unless is_success() is - // true. - // * path[N-1] will be a trust anchor if is_success() is true, otherwise - // it may or may not be a trust anchor. - ParsedCertificateList path; + // The (possibly partial) certificate path. In the case of an + // error path.trust_anchor may be nullptr. + CertPath path; // A net error code result of attempting to verify this path. // TODO(mattm): may want to have an independent result enum, which caller @@ -145,12 +162,11 @@ void HandleGotNextPath(); CompletionStatus DoGetNextPathComplete(); - void AddResultPath(const ParsedCertificateList& path, bool is_success); + void AddResultPath(const CertPath& path, bool is_success); base::Closure callback_; std::unique_ptr<CertPathIter> cert_path_iter_; - const TrustStore* trust_store_; const SignaturePolicy* signature_policy_; const der::GeneralizedTime time_; @@ -158,8 +174,9 @@ // by |cert_path_iter_| during the STATE_GET_NEXT_PATH step, and thus should // only be accessed during the STATE_GET_NEXT_PATH_COMPLETE step. // (Will be empty if all paths have been tried, otherwise will be a candidate - // path starting with the target cert and ending with a trust anchor.) - ParsedCertificateList next_path_; + // path starting with the target cert and ending with a + // certificate issued by trust anchor.) + CertPath next_path_; State next_state_; Result* out_result_;
diff --git a/net/cert/internal/path_builder_pkits_unittest.cc b/net/cert/internal/path_builder_pkits_unittest.cc index a046d1cf..86345c7c 100644 --- a/net/cert/internal/path_builder_pkits_unittest.cc +++ b/net/cert/internal/path_builder_pkits_unittest.cc
@@ -67,7 +67,10 @@ // First entry in the PKITS chain is the trust anchor. // TODO(mattm): test with all possible trust anchors in the trust store? TrustStore trust_store; - trust_store.AddTrustedCertificate(certs[0]); + + scoped_refptr<TrustAnchor> trust_anchor = + TrustAnchor::CreateFromCertificateNoConstraints(certs[0]); + trust_store.AddTrustAnchor(std::move(trust_anchor)); // TODO(mattm): test with other irrelevant certs in cert_issuer_sources? CertIssuerSourceStatic cert_issuer_source;
diff --git a/net/cert/internal/path_builder_unittest.cc b/net/cert/internal/path_builder_unittest.cc index 24d58e1..7833f82 100644 --- a/net/cert/internal/path_builder_unittest.cc +++ b/net/cert/internal/path_builder_unittest.cc
@@ -100,67 +100,6 @@ int num_async_gets_ = 0; }; -// Reads a data file from the unit-test data. -std::string ReadTestFileToString(const std::string& file_name) { - // Compute the full path, relative to the src/ directory. - base::FilePath src_root; - PathService::Get(base::DIR_SOURCE_ROOT, &src_root); - base::FilePath filepath = src_root.AppendASCII(file_name); - - // Read the full contents of the file. - std::string file_data; - if (!base::ReadFileToString(filepath, &file_data)) { - ADD_FAILURE() << "Couldn't read file: " << filepath.value(); - return std::string(); - } - - return file_data; -} - -// Reads a verify_certificate_chain_unittest-style test case from |file_name|. -// Test cases are comprised of a certificate chain, trust store, a timestamp to -// validate at, and the expected result of verification (though the expected -// result is ignored here). -void ReadVerifyCertChainTestFromFile(const std::string& file_name, - std::vector<std::string>* chain, - scoped_refptr<ParsedCertificate>* root, - der::GeneralizedTime* time) { - chain->clear(); - - std::string file_data = ReadTestFileToString(file_name); - - std::vector<std::string> pem_headers; - - const char kCertificateHeader[] = "CERTIFICATE"; - const char kTrustedCertificateHeader[] = "TRUSTED_CERTIFICATE"; - const char kTimeHeader[] = "TIME"; - - pem_headers.push_back(kCertificateHeader); - pem_headers.push_back(kTrustedCertificateHeader); - pem_headers.push_back(kTimeHeader); - - bool has_time = false; - - PEMTokenizer pem_tokenizer(file_data, pem_headers); - while (pem_tokenizer.GetNext()) { - const std::string& block_type = pem_tokenizer.block_type(); - const std::string& block_data = pem_tokenizer.data(); - - if (block_type == kCertificateHeader) { - chain->push_back(block_data); - } else if (block_type == kTrustedCertificateHeader) { - *root = ParsedCertificate::CreateFromCertificateCopy(block_data, {}); - ASSERT_TRUE(*root); - } else if (block_type == kTimeHeader) { - ASSERT_FALSE(has_time) << "Duplicate " << kTimeHeader; - has_time = true; - ASSERT_TRUE(der::ParseUTCTime(der::Input(&block_data), time)); - } - } - - ASSERT_TRUE(has_time); -} - ::testing::AssertionResult ReadTestPem(const std::string& file_name, const std::string& block_name, std::string* result) { @@ -223,12 +162,26 @@ der::GeneralizedTime time_ = {2016, 4, 11, 0, 0, 0}; }; -// If the target cert is a trust anchor, it should verify and should not include -// anything else in the path. -TEST_F(PathBuilderMultiRootTest, TargetIsTrustAnchor) { +void AddTrustedCertificate(scoped_refptr<ParsedCertificate> cert, + TrustStore* trust_store) { + ASSERT_TRUE(cert.get()); + scoped_refptr<TrustAnchor> anchor = + TrustAnchor::CreateFromCertificateNoConstraints(std::move(cert)); + ASSERT_TRUE(anchor.get()); + trust_store->AddTrustAnchor(std::move(anchor)); +} + +// If the target cert is has the same name and key as a trust anchor, however +// is signed but a different trust anchor. This should successfully build a +// path, however the trust anchor will be the signer of this cert. +// +// (This test is very similar to TestEndEntityHasSameNameAndSpkiAsTrustAnchor +// but with different data; also in this test the target cert itself is in the +// trust store). +TEST_F(PathBuilderMultiRootTest, TargetHasNameAndSpkiOfTrustAnchor) { TrustStore trust_store; - trust_store.AddTrustedCertificate(a_by_b_); - trust_store.AddTrustedCertificate(b_by_f_); + AddTrustedCertificate(a_by_b_, &trust_store); + AddTrustedCertificate(b_by_f_, &trust_store); CertPathBuilder::Result result; CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_, @@ -237,15 +190,100 @@ EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder)); EXPECT_EQ(OK, result.error()); - EXPECT_EQ(1U, result.paths[result.best_result_index]->path.size()); - EXPECT_EQ(a_by_b_, result.paths[result.best_result_index]->path[0]); + const auto& path = result.paths[result.best_result_index]->path; + EXPECT_EQ(1U, path.certs.size()); + EXPECT_EQ(a_by_b_, path.certs[0]); + EXPECT_EQ(b_by_f_, path.trust_anchor->cert()); +} + +// If the target cert is has the same name and key as a trust anchor, however +// is NOT itself signed by a trust anchor, it fails. Although the provided SPKI +// is trusted, the certificate contents cannot be verified. +TEST_F(PathBuilderMultiRootTest, TargetWithSameNameAsTrustAnchorFails) { + TrustStore trust_store; + AddTrustedCertificate(a_by_b_, &trust_store); + + CertPathBuilder::Result result; + CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_, + &result); + + EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder)); + + EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.error()); +} + +// Test a failed path building when the trust anchor is provided as a +// supplemental certificate. Conceptually the following paths can be built: +// +// B(C) <- C(D) <- [Trust anchor D] +// B(C) <- C(D) <- D(D) <- [Trust anchor D] +// +// The second one is extraneous given the shorter one, however path building +// will enumerate it if the shorter one failed validation. +TEST_F(PathBuilderMultiRootTest, SelfSignedTrustAnchorSupplementalCert) { + TrustStore trust_store; + AddTrustedCertificate(d_by_d_, &trust_store); + + // The (extraneous) trust anchor D(D) is supplied as a certificate, as is the + // intermediate needed for path building C(D). + CertIssuerSourceStatic sync_certs; + sync_certs.AddCert(d_by_d_); + sync_certs.AddCert(c_by_d_); + + // C(D) is not valid at this time, so path building will fail. + der::GeneralizedTime expired_time = {2016, 1, 1, 0, 0, 0}; + + CertPathBuilder::Result result; + CertPathBuilder path_builder(b_by_c_, &trust_store, &signature_policy_, + expired_time, &result); + path_builder.AddCertIssuerSource(&sync_certs); + + EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder)); + + EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.error()); + ASSERT_EQ(2U, result.paths.size()); + + EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[0]->error); + const auto& path0 = result.paths[0]->path; + ASSERT_EQ(2U, path0.certs.size()); + EXPECT_EQ(b_by_c_, path0.certs[0]); + EXPECT_EQ(c_by_d_, path0.certs[1]); + EXPECT_EQ(d_by_d_, path0.trust_anchor->cert()); + + const auto& path1 = result.paths[1]->path; + ASSERT_EQ(3U, path1.certs.size()); + EXPECT_EQ(b_by_c_, path1.certs[0]); + EXPECT_EQ(c_by_d_, path1.certs[1]); + EXPECT_EQ(d_by_d_, path1.certs[2]); + EXPECT_EQ(d_by_d_, path1.trust_anchor->cert()); +} + +// If the target cert is a self-signed cert whose key is a trust anchor, it +// should verify. +TEST_F(PathBuilderMultiRootTest, TargetIsSelfSignedTrustAnchor) { + TrustStore trust_store; + AddTrustedCertificate(e_by_e_, &trust_store); + // This is not necessary for the test, just an extra... + AddTrustedCertificate(f_by_e_, &trust_store); + + CertPathBuilder::Result result; + CertPathBuilder path_builder(e_by_e_, &trust_store, &signature_policy_, time_, + &result); + + EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder)); + + EXPECT_EQ(OK, result.error()); + const auto& path = result.paths[result.best_result_index]->path; + EXPECT_EQ(1U, path.certs.size()); + EXPECT_EQ(e_by_e_, path.certs[0]); + EXPECT_EQ(e_by_e_, path.trust_anchor->cert()); } // If the target cert is directly issued by a trust anchor, it should verify // without any intermediate certs being provided. TEST_F(PathBuilderMultiRootTest, TargetDirectlySignedByTrustAnchor) { TrustStore trust_store; - trust_store.AddTrustedCertificate(b_by_f_); + AddTrustedCertificate(b_by_f_, &trust_store); CertPathBuilder::Result result; CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_, @@ -253,17 +291,18 @@ EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder)); - EXPECT_EQ(OK, result.error()); - EXPECT_EQ(2U, result.paths[result.best_result_index]->path.size()); - EXPECT_EQ(a_by_b_, result.paths[result.best_result_index]->path[0]); - EXPECT_EQ(b_by_f_, result.paths[result.best_result_index]->path[1]); + ASSERT_EQ(OK, result.error()); + const auto& path = result.paths[result.best_result_index]->path; + EXPECT_EQ(1U, path.certs.size()); + EXPECT_EQ(a_by_b_, path.certs[0]); + EXPECT_EQ(b_by_f_, path.trust_anchor->cert()); } // Test that async cert queries are not made if the path can be successfully // built with synchronously available certs. TEST_F(PathBuilderMultiRootTest, TriesSyncFirst) { TrustStore trust_store; - trust_store.AddTrustedCertificate(e_by_e_); + AddTrustedCertificate(e_by_e_, &trust_store); CertIssuerSourceStatic sync_certs; sync_certs.AddCert(b_by_f_); @@ -288,7 +327,7 @@ // Test that async cert queries are not made if no callback is provided. TEST_F(PathBuilderMultiRootTest, SychronousOnlyMode) { TrustStore trust_store; - trust_store.AddTrustedCertificate(e_by_e_); + AddTrustedCertificate(e_by_e_, &trust_store); CertIssuerSourceStatic sync_certs; sync_certs.AddCert(f_by_e_); @@ -312,7 +351,7 @@ // simultaneously. TEST_F(PathBuilderMultiRootTest, TestAsyncSimultaneous) { TrustStore trust_store; - trust_store.AddTrustedCertificate(e_by_e_); + AddTrustedCertificate(e_by_e_, &trust_store); CertIssuerSourceStatic sync_certs; sync_certs.AddCert(b_by_c_); @@ -343,8 +382,8 @@ TEST_F(PathBuilderMultiRootTest, TestLongChain) { // Both D(D) and C(D) are trusted roots. TrustStore trust_store; - trust_store.AddTrustedCertificate(d_by_d_); - trust_store.AddTrustedCertificate(c_by_d_); + AddTrustedCertificate(d_by_d_, &trust_store); + AddTrustedCertificate(c_by_d_, &trust_store); // Certs B(C), and C(D) are all supplied. CertIssuerSourceStatic sync_certs; @@ -362,7 +401,8 @@ // The result path should be A(B) <- B(C) <- C(D) // not the longer but also valid A(B) <- B(C) <- C(D) <- D(D) - EXPECT_EQ(3U, result.paths[result.best_result_index]->path.size()); + const auto& path = result.paths[result.best_result_index]->path; + EXPECT_EQ(2U, path.certs.size()); } // Test that PathBuilder will backtrack and try a different path if the first @@ -370,7 +410,7 @@ TEST_F(PathBuilderMultiRootTest, TestBacktracking) { // Only D(D) is a trusted root. TrustStore trust_store; - trust_store.AddTrustedCertificate(d_by_d_); + AddTrustedCertificate(d_by_d_, &trust_store); // Certs B(F) and F(E) are supplied synchronously, thus the path // A(B) <- B(F) <- F(E) should be built first, though it won't verify. @@ -395,11 +435,12 @@ EXPECT_EQ(OK, result.error()); // The result path should be A(B) <- B(C) <- C(D) <- D(D) - ASSERT_EQ(4U, result.paths[result.best_result_index]->path.size()); - EXPECT_EQ(a_by_b_, result.paths[result.best_result_index]->path[0]); - EXPECT_EQ(b_by_c_, result.paths[result.best_result_index]->path[1]); - EXPECT_EQ(c_by_d_, result.paths[result.best_result_index]->path[2]); - EXPECT_EQ(d_by_d_, result.paths[result.best_result_index]->path[3]); + const auto& path = result.paths[result.best_result_index]->path; + ASSERT_EQ(3U, path.certs.size()); + EXPECT_EQ(a_by_b_, path.certs[0]); + EXPECT_EQ(b_by_c_, path.certs[1]); + EXPECT_EQ(c_by_d_, path.certs[2]); + EXPECT_EQ(d_by_d_, path.trust_anchor->cert()); } // Test that whichever order CertIssuerSource returns the issuers, the path @@ -407,7 +448,7 @@ TEST_F(PathBuilderMultiRootTest, TestCertIssuerOrdering) { // Only D(D) is a trusted root. TrustStore trust_store; - trust_store.AddTrustedCertificate(d_by_d_); + AddTrustedCertificate(d_by_d_, &trust_store); for (bool reverse_order : {false, true}) { SCOPED_TRACE(reverse_order); @@ -432,11 +473,12 @@ EXPECT_EQ(OK, result.error()); // The result path should be A(B) <- B(C) <- C(D) <- D(D) - ASSERT_EQ(4U, result.paths[result.best_result_index]->path.size()); - EXPECT_EQ(a_by_b_, result.paths[result.best_result_index]->path[0]); - EXPECT_EQ(b_by_c_, result.paths[result.best_result_index]->path[1]); - EXPECT_EQ(c_by_d_, result.paths[result.best_result_index]->path[2]); - EXPECT_EQ(d_by_d_, result.paths[result.best_result_index]->path[3]); + const auto& path = result.paths[result.best_result_index]->path; + ASSERT_EQ(3U, path.certs.size()); + EXPECT_EQ(a_by_b_, path.certs[0]); + EXPECT_EQ(b_by_c_, path.certs[1]); + EXPECT_EQ(c_by_d_, path.certs[2]); + EXPECT_EQ(d_by_d_, path.trust_anchor->cert()); } } @@ -445,28 +487,23 @@ PathBuilderKeyRolloverTest() : signature_policy_(1024) {} void SetUp() override { - std::vector<std::string> path; + ParsedCertificateList path; + bool unused; - ReadVerifyCertChainTestFromFile( - "net/data/verify_certificate_chain_unittest/key-rollover-oldchain.pem", - &path, &oldroot_, &time_); + ReadVerifyCertChainTestFromFile("key-rollover-oldchain.pem", &path, + &oldroot_, &time_, &unused); ASSERT_EQ(2U, path.size()); - target_ = ParsedCertificate::CreateFromCertificateCopy(path[0], {}); - oldintermediate_ = - ParsedCertificate::CreateFromCertificateCopy(path[1], {}); + target_ = path[0]; + oldintermediate_ = path[1]; ASSERT_TRUE(target_); ASSERT_TRUE(oldintermediate_); - ReadVerifyCertChainTestFromFile( - "net/data/verify_certificate_chain_unittest/" - "key-rollover-longrolloverchain.pem", - &path, &oldroot_, &time_); + ReadVerifyCertChainTestFromFile("key-rollover-longrolloverchain.pem", &path, + &oldroot_, &time_, &unused); ASSERT_EQ(4U, path.size()); - newintermediate_ = - ParsedCertificate::CreateFromCertificateCopy(path[1], {}); - newroot_ = ParsedCertificate::CreateFromCertificateCopy(path[2], {}); - newrootrollover_ = - ParsedCertificate::CreateFromCertificateCopy(path[3], {}); + newintermediate_ = path[1]; + newroot_ = path[2]; + newrootrollover_ = path[3]; ASSERT_TRUE(newintermediate_); ASSERT_TRUE(newroot_); ASSERT_TRUE(newrootrollover_); @@ -485,7 +522,7 @@ scoped_refptr<ParsedCertificate> target_; scoped_refptr<ParsedCertificate> oldintermediate_; scoped_refptr<ParsedCertificate> newintermediate_; - scoped_refptr<ParsedCertificate> oldroot_; + scoped_refptr<TrustAnchor> oldroot_; scoped_refptr<ParsedCertificate> newroot_; scoped_refptr<ParsedCertificate> newrootrollover_; @@ -498,7 +535,7 @@ TEST_F(PathBuilderKeyRolloverTest, TestRolloverOnlyOldRootTrusted) { // Only oldroot is trusted. TrustStore trust_store; - trust_store.AddTrustedCertificate(oldroot_); + trust_store.AddTrustAnchor(oldroot_); // Old intermediate cert is not provided, so the pathbuilder will need to go // through the rollover cert. @@ -518,22 +555,24 @@ // Path builder will first attempt: target <- newintermediate <- oldroot // but it will fail since newintermediate is signed by newroot. ASSERT_EQ(2U, result.paths.size()); + const auto& path0 = result.paths[0]->path; EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[0]->error); - ASSERT_EQ(3U, result.paths[0]->path.size()); - EXPECT_EQ(target_, result.paths[0]->path[0]); - EXPECT_EQ(newintermediate_, result.paths[0]->path[1]); - EXPECT_EQ(oldroot_, result.paths[0]->path[2]); + ASSERT_EQ(2U, path0.certs.size()); + EXPECT_EQ(target_, path0.certs[0]); + EXPECT_EQ(newintermediate_, path0.certs[1]); + EXPECT_EQ(oldroot_, path0.trust_anchor); // Path builder will next attempt: // target <- newintermediate <- newrootrollover <- oldroot // which will succeed. + const auto& path1 = result.paths[1]->path; EXPECT_EQ(1U, result.best_result_index); EXPECT_EQ(OK, result.paths[1]->error); - ASSERT_EQ(4U, result.paths[1]->path.size()); - EXPECT_EQ(target_, result.paths[1]->path[0]); - EXPECT_EQ(newintermediate_, result.paths[1]->path[1]); - EXPECT_EQ(newrootrollover_, result.paths[1]->path[2]); - EXPECT_EQ(oldroot_, result.paths[1]->path[3]); + ASSERT_EQ(3U, path1.certs.size()); + EXPECT_EQ(target_, path1.certs[0]); + EXPECT_EQ(newintermediate_, path1.certs[1]); + EXPECT_EQ(newrootrollover_, path1.certs[2]); + EXPECT_EQ(oldroot_, path1.trust_anchor); } // Tests that if both old and new roots are trusted it can build a path through @@ -543,8 +582,8 @@ TEST_F(PathBuilderKeyRolloverTest, TestRolloverBothRootsTrusted) { // Both oldroot and newroot are trusted. TrustStore trust_store; - trust_store.AddTrustedCertificate(oldroot_); - trust_store.AddTrustedCertificate(newroot_); + trust_store.AddTrustAnchor(oldroot_); + AddTrustedCertificate(newroot_, &trust_store); // Both old and new intermediates + rollover cert are provided. CertIssuerSourceStatic sync_certs; @@ -566,17 +605,18 @@ // target <- newintermediate <- newroot // either will succeed. ASSERT_EQ(1U, result.paths.size()); + const auto& path = result.paths[0]->path; EXPECT_EQ(OK, result.paths[0]->error); - ASSERT_EQ(3U, result.paths[0]->path.size()); - EXPECT_EQ(target_, result.paths[0]->path[0]); - if (result.paths[0]->path[1] != newintermediate_) { + ASSERT_EQ(2U, path.certs.size()); + EXPECT_EQ(target_, path.certs[0]); + if (path.certs[1] != newintermediate_) { DVLOG(1) << "USED OLD"; - EXPECT_EQ(oldintermediate_, result.paths[0]->path[1]); - EXPECT_EQ(oldroot_, result.paths[0]->path[2]); + EXPECT_EQ(oldintermediate_, path.certs[1]); + EXPECT_EQ(oldroot_, path.trust_anchor); } else { DVLOG(1) << "USED NEW"; - EXPECT_EQ(newintermediate_, result.paths[0]->path[1]); - EXPECT_EQ(newroot_, result.paths[0]->path[2]); + EXPECT_EQ(newintermediate_, path.certs[1]); + EXPECT_EQ(newroot_, path.trust_anchor->cert()); } } @@ -586,8 +626,8 @@ TEST_F(PathBuilderKeyRolloverTest, TestMultipleRootMatchesOnlyOneWorks) { // Both newroot and oldroot are trusted. TrustStore trust_store; - trust_store.AddTrustedCertificate(newroot_); - trust_store.AddTrustedCertificate(oldroot_); + AddTrustedCertificate(newroot_, &trust_store); + trust_store.AddTrustAnchor(oldroot_); // Only oldintermediate is supplied, so the path with newroot should fail, // oldroot should succeed. @@ -613,27 +653,29 @@ // Path builder may first attempt: target <- oldintermediate <- newroot // but it will fail since oldintermediate is signed by oldroot. EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[0]->error); - ASSERT_EQ(3U, result.paths[0]->path.size()); - EXPECT_EQ(target_, result.paths[0]->path[0]); - EXPECT_EQ(oldintermediate_, result.paths[0]->path[1]); - EXPECT_EQ(newroot_, result.paths[0]->path[2]); + const auto& path = result.paths[0]->path; + ASSERT_EQ(2U, path.certs.size()); + EXPECT_EQ(target_, path.certs[0]); + EXPECT_EQ(oldintermediate_, path.certs[1]); + EXPECT_EQ(newroot_, path.trust_anchor->cert()); } // Path builder will next attempt: // target <- old intermediate <- oldroot // which should succeed. EXPECT_EQ(OK, result.paths[result.best_result_index]->error); - ASSERT_EQ(3U, result.paths[result.best_result_index]->path.size()); - EXPECT_EQ(target_, result.paths[result.best_result_index]->path[0]); - EXPECT_EQ(oldintermediate_, result.paths[result.best_result_index]->path[1]); - EXPECT_EQ(oldroot_, result.paths[result.best_result_index]->path[2]); + const auto& path = result.paths[result.best_result_index]->path; + ASSERT_EQ(2U, path.certs.size()); + EXPECT_EQ(target_, path.certs[0]); + EXPECT_EQ(oldintermediate_, path.certs[1]); + EXPECT_EQ(oldroot_, path.trust_anchor); } // Tests that the path builder doesn't build longer than necessary paths. TEST_F(PathBuilderKeyRolloverTest, TestRolloverLongChain) { // Only oldroot is trusted. TrustStore trust_store; - trust_store.AddTrustedCertificate(oldroot_); + trust_store.AddTrustAnchor(oldroot_); // New intermediate and new root are provided synchronously. CertIssuerSourceStatic sync_certs; @@ -659,20 +701,22 @@ // Path builder will first attempt: target <- newintermediate <- oldroot // but it will fail since newintermediate is signed by newroot. EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[0]->error); - ASSERT_EQ(3U, result.paths[0]->path.size()); - EXPECT_EQ(target_, result.paths[0]->path[0]); - EXPECT_EQ(newintermediate_, result.paths[0]->path[1]); - EXPECT_EQ(oldroot_, result.paths[0]->path[2]); + const auto& path0 = result.paths[0]->path; + ASSERT_EQ(2U, path0.certs.size()); + EXPECT_EQ(target_, path0.certs[0]); + EXPECT_EQ(newintermediate_, path0.certs[1]); + EXPECT_EQ(oldroot_, path0.trust_anchor); // Path builder will next attempt: // target <- newintermediate <- newroot <- oldroot // but it will fail since newroot is self-signed. EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[1]->error); - ASSERT_EQ(4U, result.paths[1]->path.size()); - EXPECT_EQ(target_, result.paths[1]->path[0]); - EXPECT_EQ(newintermediate_, result.paths[1]->path[1]); - EXPECT_EQ(newroot_, result.paths[1]->path[2]); - EXPECT_EQ(oldroot_, result.paths[1]->path[3]); + const auto& path1 = result.paths[1]->path; + ASSERT_EQ(3U, path1.certs.size()); + EXPECT_EQ(target_, path1.certs[0]); + EXPECT_EQ(newintermediate_, path1.certs[1]); + EXPECT_EQ(newroot_, path1.certs[2]); + EXPECT_EQ(oldroot_, path1.trust_anchor); // Path builder will skip: // target <- newintermediate <- newroot <- newrootrollover <- ... @@ -682,18 +726,22 @@ // target <- newintermediate <- newrootrollover <- oldroot EXPECT_EQ(2U, result.best_result_index); EXPECT_EQ(OK, result.paths[2]->error); - ASSERT_EQ(4U, result.paths[2]->path.size()); - EXPECT_EQ(target_, result.paths[2]->path[0]); - EXPECT_EQ(newintermediate_, result.paths[2]->path[1]); - EXPECT_EQ(newrootrollover_, result.paths[2]->path[2]); - EXPECT_EQ(oldroot_, result.paths[2]->path[3]); + const auto& path2 = result.paths[2]->path; + ASSERT_EQ(3U, path2.certs.size()); + EXPECT_EQ(target_, path2.certs[0]); + EXPECT_EQ(newintermediate_, path2.certs[1]); + EXPECT_EQ(newrootrollover_, path2.certs[2]); + EXPECT_EQ(oldroot_, path2.trust_anchor); } -// If the target cert is a trust root, that alone is a valid path. +// If the target cert is a trust anchor, however is not itself *signed* by a +// trust anchor, then it is not considered valid (the SPKI and name of the +// trust anchor matches the SPKI and subject of the targe certificate, but the +// rest of the certificate cannot be verified). TEST_F(PathBuilderKeyRolloverTest, TestEndEntityIsTrustRoot) { // Trust newintermediate. TrustStore trust_store; - trust_store.AddTrustedCertificate(newintermediate_); + AddTrustedCertificate(newintermediate_, &trust_store); CertPathBuilder::Result result; // Newintermediate is also the target cert. @@ -702,12 +750,7 @@ EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder)); - EXPECT_EQ(OK, result.error()); - - ASSERT_EQ(1U, result.paths.size()); - EXPECT_EQ(OK, result.paths[0]->error); - ASSERT_EQ(1U, result.paths[0]->path.size()); - EXPECT_EQ(newintermediate_, result.paths[0]->path[0]); + EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.error()); } // If target has same Name+SAN+SPKI as a necessary intermediate, test if a path @@ -718,7 +761,7 @@ TestEndEntityHasSameNameAndSpkiAsIntermediate) { // Trust oldroot. TrustStore trust_store; - trust_store.AddTrustedCertificate(oldroot_); + trust_store.AddTrustAnchor(oldroot_); // New root rollover is provided synchronously. CertIssuerSourceStatic sync_certs; @@ -743,7 +786,7 @@ TestEndEntityHasSameNameAndSpkiAsTrustAnchor) { // Trust newrootrollover. TrustStore trust_store; - trust_store.AddTrustedCertificate(newrootrollover_); + AddTrustedCertificate(newrootrollover_, &trust_store); CertPathBuilder::Result result; // Newroot is the target cert. @@ -761,8 +804,9 @@ // Newroot has same name+SPKI as newrootrollover, thus the path is valid and // only contains newroot. EXPECT_EQ(OK, best_result->error); - ASSERT_EQ(1U, best_result->path.size()); - EXPECT_EQ(newroot_, best_result->path[0]); + ASSERT_EQ(1U, best_result->path.certs.size()); + EXPECT_EQ(newroot_, best_result->path.certs[0]); + EXPECT_EQ(newrootrollover_, best_result->path.trust_anchor->cert()); } // Test that PathBuilder will not try the same path twice if multiple @@ -775,7 +819,7 @@ // Only newroot is a trusted root. TrustStore trust_store; - trust_store.AddTrustedCertificate(newroot_); + AddTrustedCertificate(newroot_, &trust_store); // The oldintermediate is supplied synchronously by |sync_certs1| and // another copy of oldintermediate is supplied synchronously by |sync_certs2|. @@ -807,25 +851,28 @@ // Path builder will first attempt: target <- oldintermediate <- newroot // but it will fail since oldintermediate is signed by oldroot. EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[0]->error); - ASSERT_EQ(3U, result.paths[0]->path.size()); - EXPECT_EQ(target_, result.paths[0]->path[0]); + const auto& path0 = result.paths[0]->path; + + ASSERT_EQ(2U, path0.certs.size()); + EXPECT_EQ(target_, path0.certs[0]); // Compare the DER instead of ParsedCertificate pointer, don't care which copy // of oldintermediate was used in the path. - EXPECT_EQ(oldintermediate_->der_cert(), result.paths[0]->path[1]->der_cert()); - EXPECT_EQ(newroot_, result.paths[0]->path[2]); + EXPECT_EQ(oldintermediate_->der_cert(), path0.certs[1]->der_cert()); + EXPECT_EQ(newroot_, path0.trust_anchor->cert()); // Path builder will next attempt: target <- newintermediate <- newroot // which will succeed. EXPECT_EQ(1U, result.best_result_index); EXPECT_EQ(OK, result.paths[1]->error); - ASSERT_EQ(3U, result.paths[1]->path.size()); - EXPECT_EQ(target_, result.paths[1]->path[0]); - EXPECT_EQ(newintermediate_, result.paths[1]->path[1]); - EXPECT_EQ(newroot_, result.paths[1]->path[2]); + const auto& path1 = result.paths[1]->path; + ASSERT_EQ(2U, path1.certs.size()); + EXPECT_EQ(target_, path1.certs[0]); + EXPECT_EQ(newintermediate_, path1.certs[1]); + EXPECT_EQ(newroot_, path1.trust_anchor->cert()); } -// Test that PathBuilder will not try the same path twice if the same cert is -// presented via a CertIssuerSources and a TrustAnchor. +// Test when PathBuilder is given a cert CertIssuerSources that has the same +// SPKI as a TrustAnchor. TEST_F(PathBuilderKeyRolloverTest, TestDuplicateIntermediateAndRoot) { // Create a separate copy of newroot. scoped_refptr<ParsedCertificate> newroot_dupe( @@ -834,7 +881,7 @@ // Only newroot is a trusted root. TrustStore trust_store; - trust_store.AddTrustedCertificate(newroot_); + AddTrustedCertificate(newroot_, &trust_store); // The oldintermediate and newroot are supplied synchronously by |sync_certs|. CertIssuerSourceStatic sync_certs; @@ -849,17 +896,19 @@ EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder)); EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.error()); - ASSERT_EQ(1U, result.paths.size()); + ASSERT_EQ(2U, result.paths.size()); + // TODO(eroman): Is this right? // Path builder attempt: target <- oldintermediate <- newroot // but it will fail since oldintermediate is signed by oldroot. EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[0]->error); - ASSERT_EQ(3U, result.paths[0]->path.size()); - EXPECT_EQ(target_, result.paths[0]->path[0]); - EXPECT_EQ(oldintermediate_, result.paths[0]->path[1]); + const auto& path = result.paths[0]->path; + ASSERT_EQ(2U, path.certs.size()); + EXPECT_EQ(target_, path.certs[0]); + EXPECT_EQ(oldintermediate_, path.certs[1]); // Compare the DER instead of ParsedCertificate pointer, don't care which copy // of newroot was used in the path. - EXPECT_EQ(newroot_->der_cert(), result.paths[0]->path[2]->der_cert()); + EXPECT_EQ(newroot_->der_cert(), path.trust_anchor->cert()->der_cert()); } class MockCertIssuerSourceRequest : public CertIssuerSource::Request { @@ -902,7 +951,7 @@ // Only newroot is a trusted root. TrustStore trust_store; - trust_store.AddTrustedCertificate(newroot_); + AddTrustedCertificate(newroot_, &trust_store); CertPathBuilder::Result result; CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_, @@ -979,18 +1028,20 @@ // Path builder first attempts: target <- oldintermediate <- newroot // but it will fail since oldintermediate is signed by oldroot. EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[0]->error); - ASSERT_EQ(3U, result.paths[0]->path.size()); - EXPECT_EQ(target_, result.paths[0]->path[0]); - EXPECT_EQ(oldintermediate_, result.paths[0]->path[1]); - EXPECT_EQ(newroot_, result.paths[0]->path[2]); + const auto& path0 = result.paths[0]->path; + ASSERT_EQ(2U, path0.certs.size()); + EXPECT_EQ(target_, path0.certs[0]); + EXPECT_EQ(oldintermediate_, path0.certs[1]); + EXPECT_EQ(newroot_, path0.trust_anchor->cert()); // After the second batch of async results, path builder will attempt: // target <- newintermediate <- newroot which will succeed. EXPECT_EQ(OK, result.paths[1]->error); - ASSERT_EQ(3U, result.paths[1]->path.size()); - EXPECT_EQ(target_, result.paths[1]->path[0]); - EXPECT_EQ(newintermediate_, result.paths[1]->path[1]); - EXPECT_EQ(newroot_, result.paths[1]->path[2]); + const auto& path1 = result.paths[1]->path; + ASSERT_EQ(2U, path1.certs.size()); + EXPECT_EQ(target_, path1.certs[0]); + EXPECT_EQ(newintermediate_, path1.certs[1]); + EXPECT_EQ(newroot_, path1.trust_anchor->cert()); } // Test that PathBuilder will not try the same path twice if CertIssuerSources @@ -1000,7 +1051,7 @@ // Only newroot is a trusted root. TrustStore trust_store; - trust_store.AddTrustedCertificate(newroot_); + AddTrustedCertificate(newroot_, &trust_store); CertPathBuilder::Result result; CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_, @@ -1092,20 +1143,22 @@ // Path builder first attempts: target <- oldintermediate <- newroot // but it will fail since oldintermediate is signed by oldroot. EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[0]->error); - ASSERT_EQ(3U, result.paths[0]->path.size()); - EXPECT_EQ(target_, result.paths[0]->path[0]); - EXPECT_EQ(oldintermediate_, result.paths[0]->path[1]); - EXPECT_EQ(newroot_, result.paths[0]->path[2]); + const auto& path0 = result.paths[0]->path; + ASSERT_EQ(2U, path0.certs.size()); + EXPECT_EQ(target_, path0.certs[0]); + EXPECT_EQ(oldintermediate_, path0.certs[1]); + EXPECT_EQ(newroot_, path0.trust_anchor->cert()); // The second async result does not generate any path. // After the third batch of async results, path builder will attempt: // target <- newintermediate <- newroot which will succeed. EXPECT_EQ(OK, result.paths[1]->error); - ASSERT_EQ(3U, result.paths[1]->path.size()); - EXPECT_EQ(target_, result.paths[1]->path[0]); - EXPECT_EQ(newintermediate_, result.paths[1]->path[1]); - EXPECT_EQ(newroot_, result.paths[1]->path[2]); + const auto& path1 = result.paths[1]->path; + ASSERT_EQ(2U, path1.certs.size()); + EXPECT_EQ(target_, path1.certs[0]); + EXPECT_EQ(newintermediate_, path1.certs[1]); + EXPECT_EQ(newroot_, path1.trust_anchor->cert()); } } // namespace
diff --git a/net/cert/internal/path_builder_verify_certificate_chain_unittest.cc b/net/cert/internal/path_builder_verify_certificate_chain_unittest.cc index e08ea30..b6401216 100644 --- a/net/cert/internal/path_builder_verify_certificate_chain_unittest.cc +++ b/net/cert/internal/path_builder_verify_certificate_chain_unittest.cc
@@ -16,15 +16,14 @@ class PathBuilderDelegate { public: static void Verify(const ParsedCertificateList& chain, - const ParsedCertificateList& roots, + const scoped_refptr<TrustAnchor>& trust_anchor, const der::GeneralizedTime& time, bool expected_result) { SimpleSignaturePolicy signature_policy(1024); ASSERT_FALSE(chain.empty()); TrustStore trust_store; - for (const auto& root : roots) - trust_store.AddTrustedCertificate(root); + trust_store.AddTrustAnchor(trust_anchor); CertIssuerSourceStatic intermediate_cert_issuer_source; for (size_t i = 1; i < chain.size(); ++i) @@ -49,8 +48,4 @@ VerifyCertificateChainSingleRootTest, PathBuilderDelegate); -INSTANTIATE_TYPED_TEST_CASE_P(PathBuilder, - VerifyCertificateChainNonSingleRootTest, - PathBuilderDelegate); - } // namespace net
diff --git a/net/cert/internal/test_helpers.cc b/net/cert/internal/test_helpers.cc index 71b9a26..d143f70e 100644 --- a/net/cert/internal/test_helpers.cc +++ b/net/cert/internal/test_helpers.cc
@@ -100,4 +100,86 @@ return ::testing::AssertionSuccess(); } +void ReadVerifyCertChainTestFromFile(const std::string& file_name, + ParsedCertificateList* chain, + scoped_refptr<TrustAnchor>* trust_anchor, + der::GeneralizedTime* time, + bool* verify_result) { + chain->clear(); + *trust_anchor = nullptr; + + std::string file_data = ReadTestFileToString( + std::string("net/data/verify_certificate_chain_unittest/") + file_name); + + std::vector<std::string> pem_headers; + + // For details on the file format refer to: + // net/data/verify_certificate_chain_unittest/README. + const char kCertificateHeader[] = "CERTIFICATE"; + const char kTrustAnchorUnconstrained[] = "TRUST_ANCHOR_UNCONSTRAINED"; + const char kTimeHeader[] = "TIME"; + const char kResultHeader[] = "VERIFY_RESULT"; + + pem_headers.push_back(kCertificateHeader); + pem_headers.push_back(kTrustAnchorUnconstrained); + pem_headers.push_back(kTimeHeader); + pem_headers.push_back(kResultHeader); + + bool has_time = false; + bool has_result = false; + + PEMTokenizer pem_tokenizer(file_data, pem_headers); + while (pem_tokenizer.GetNext()) { + const std::string& block_type = pem_tokenizer.block_type(); + const std::string& block_data = pem_tokenizer.data(); + + if (block_type == kCertificateHeader) { + ASSERT_TRUE(net::ParsedCertificate::CreateAndAddToVector( + reinterpret_cast<const uint8_t*>(block_data.data()), + block_data.size(), net::ParsedCertificate::DataSource::INTERNAL_COPY, + {}, chain)); + } else if (block_type == kTrustAnchorUnconstrained) { + ASSERT_FALSE(*trust_anchor) << "Duplicate trust anchor"; + scoped_refptr<ParsedCertificate> root = + net::ParsedCertificate::CreateFromCertificateData( + reinterpret_cast<const uint8_t*>(block_data.data()), + block_data.size(), + net::ParsedCertificate::DataSource::INTERNAL_COPY, {}); + ASSERT_TRUE(root); + *trust_anchor = + TrustAnchor::CreateFromCertificateNoConstraints(std::move(root)); + } else if (block_type == kTimeHeader) { + ASSERT_FALSE(has_time) << "Duplicate " << kTimeHeader; + has_time = true; + ASSERT_TRUE(der::ParseUTCTime(der::Input(&block_data), time)); + } else if (block_type == kResultHeader) { + ASSERT_FALSE(has_result) << "Duplicate " << kResultHeader; + ASSERT_TRUE(block_data == "SUCCESS" || block_data == "FAIL") + << "Unrecognized result: " << block_data; + has_result = true; + *verify_result = block_data == "SUCCESS"; + } + } + + ASSERT_TRUE(has_time); + ASSERT_TRUE(has_result); + ASSERT_TRUE(*trust_anchor); +} + +std::string ReadTestFileToString(const std::string& file_name) { + // Compute the full path, relative to the src/ directory. + base::FilePath src_root; + PathService::Get(base::DIR_SOURCE_ROOT, &src_root); + base::FilePath filepath = src_root.AppendASCII(file_name); + + // Read the full contents of the file. + std::string file_data; + if (!base::ReadFileToString(filepath, &file_data)) { + ADD_FAILURE() << "Couldn't read file: " << filepath.value(); + return std::string(); + } + + return file_data; +} + } // namespace net
diff --git a/net/cert/internal/test_helpers.h b/net/cert/internal/test_helpers.h index 999c37b..414935b3 100644 --- a/net/cert/internal/test_helpers.h +++ b/net/cert/internal/test_helpers.h
@@ -11,6 +11,8 @@ #include <string> #include <vector> +#include "net/cert/internal/parsed_certificate.h" +#include "net/cert/internal/trust_store.h" #include "net/der/input.h" #include "testing/gtest/include/gtest/gtest.h" @@ -74,6 +76,18 @@ return ReadTestDataFromPemFile(file_path_ascii, mappings, N); } +// Reads a test case from |file_name|. Test cases are comprised of a +// certificate chain, trust anchor, a timestamp to validate at, and the +// expected result of verification. +void ReadVerifyCertChainTestFromFile(const std::string& file_name, + ParsedCertificateList* chain, + scoped_refptr<TrustAnchor>* trust_anchor, + der::GeneralizedTime* time, + bool* verify_result); + +// Reads a data file relative to the src root directory. +std::string ReadTestFileToString(const std::string& file_name); + } // namespace net #endif // NET_CERT_INTERNAL_TEST_HELPERS_H_
diff --git a/net/cert/internal/trust_store.cc b/net/cert/internal/trust_store.cc index d46933b..65cb840 100644 --- a/net/cert/internal/trust_store.cc +++ b/net/cert/internal/trust_store.cc
@@ -4,8 +4,34 @@ #include "net/cert/internal/trust_store.h" +#include "base/memory/ptr_util.h" + namespace net { +scoped_refptr<TrustAnchor> TrustAnchor::CreateFromCertificateNoConstraints( + scoped_refptr<ParsedCertificate> cert) { + return scoped_refptr<TrustAnchor>(new TrustAnchor(std::move(cert))); +} + +der::Input TrustAnchor::spki() const { + return cert_->tbs().spki_tlv; +} + +der::Input TrustAnchor::normalized_subject() const { + return cert_->normalized_subject(); +} + +const scoped_refptr<ParsedCertificate>& TrustAnchor::cert() const { + return cert_; +} + +TrustAnchor::TrustAnchor(scoped_refptr<ParsedCertificate> cert) + : cert_(std::move(cert)) { + DCHECK(cert_); +} + +TrustAnchor::~TrustAnchor() {} + TrustStore::TrustStore() {} TrustStore::~TrustStore() {} @@ -13,34 +39,18 @@ anchors_.clear(); } -void TrustStore::AddTrustedCertificate( - scoped_refptr<ParsedCertificate> anchor) { - // TODO(mattm): should this check for duplicate certs? +void TrustStore::AddTrustAnchor(scoped_refptr<TrustAnchor> anchor) { + // TODO(mattm): should this check for duplicate anchors? anchors_.insert(std::make_pair(anchor->normalized_subject().AsStringPiece(), std::move(anchor))); } void TrustStore::FindTrustAnchorsByNormalizedName( const der::Input& normalized_name, - ParsedCertificateList* matches) const { + TrustAnchors* matches) const { auto range = anchors_.equal_range(normalized_name.AsStringPiece()); for (auto it = range.first; it != range.second; ++it) matches->push_back(it->second); } -bool TrustStore::IsTrustedCertificate(const ParsedCertificate* cert) const { - auto range = anchors_.equal_range(cert->normalized_subject().AsStringPiece()); - for (auto it = range.first; it != range.second; ++it) { - // First compare the ParsedCertificate pointers as an optimization. - if (it->second == cert || - // Trust check is based on Name+SPKI match. This could match the same - // certificate stored in a different ParsedCertificate object, or a - // different cert that has the same Name+SPKI. - (it->second->normalized_subject() == cert->normalized_subject() && - it->second->tbs().spki_tlv == cert->tbs().spki_tlv)) - return true; - } - return false; -} - } // namespace net
diff --git a/net/cert/internal/trust_store.h b/net/cert/internal/trust_store.h index 0afbf9a..55d497d 100644 --- a/net/cert/internal/trust_store.h +++ b/net/cert/internal/trust_store.h
@@ -19,8 +19,64 @@ class Input; } +// A TrustAnchor represents a trust anchor used during RFC 5280 path validation. +// +// At its core, each trust anchor has two parts: +// * Name +// * Public Key +// +// Optionally a trust anchor may contain: +// * An associated certificate +// * Trust anchor constraints +// +// Relationship between ParsedCertificate and TrustAnchor: +// +// For convenience trust anchors are often described using a +// (self-signed) certificate. TrustAnchor facilitates this by allowing +// construction of a TrustAnchor given a ParsedCertificate, however +// the concepts are NOT quite the same. +// +// Notably when constructed from a certificate, properties/constraints of +// the underlying certificate like expiration, signature, or basic +// constraints are NOT processed and validated by path validation. +// Instead such properties need to be explicitly indicated via "trust +// anchor constraints". +// +// See RFC 5937 and RFC 5280 for more details. +class NET_EXPORT TrustAnchor : public base::RefCountedThreadSafe<TrustAnchor> { + public: + // Creates a TrustAnchor given a certificate. The only parts of the + // certificate that will be used are the subject and SPKI. Any extensions in + // the certificate that might limit its use (like name constraints or policy) + // are disregarded during validation. In other words, the resulting trust + // anchor has no anchor constraints. + static scoped_refptr<TrustAnchor> CreateFromCertificateNoConstraints( + scoped_refptr<ParsedCertificate> cert); + + // TODO(crbug.com/635200): Support anchor constraints. For instance + // by adding factory method CreateFromCertificateWithConstraints() + + der::Input spki() const; + der::Input normalized_subject() const; + + // Returns the optional certificate representing this trust anchor. + // In the current implementation it will never return nullptr... + // however clients should be prepared to handle this case. + const scoped_refptr<ParsedCertificate>& cert() const; + + private: + friend class base::RefCountedThreadSafe<TrustAnchor>; + explicit TrustAnchor(scoped_refptr<ParsedCertificate>); + ~TrustAnchor(); + + scoped_refptr<ParsedCertificate> cert_; +}; + +using TrustAnchors = std::vector<scoped_refptr<TrustAnchor>>; + // A very simple implementation of a TrustStore, which contains a set of -// trusted certificates. +// trust anchors. +// // TODO(mattm): convert this into an interface, provide implementations that // interface with OS trust store. class NET_EXPORT TrustStore { @@ -31,21 +87,16 @@ // Empties the trust store, resetting it to original state. void Clear(); - // Adds a trusted certificate to the store. - void AddTrustedCertificate(scoped_refptr<ParsedCertificate> anchor); + void AddTrustAnchor(scoped_refptr<TrustAnchor> anchor); // Returns the trust anchors that match |name| in |*matches|, if any. void FindTrustAnchorsByNormalizedName(const der::Input& normalized_name, - ParsedCertificateList* matches) const; - - // Returns true if |cert| matches a certificate in the TrustStore. - bool IsTrustedCertificate(const ParsedCertificate* cert) const - WARN_UNUSED_RESULT; + TrustAnchors* matches) const; private: - // Multimap from normalized subject -> ParsedCertificate. + // Multimap from normalized subject -> TrustAnchor. std::unordered_multimap<base::StringPiece, - scoped_refptr<ParsedCertificate>, + scoped_refptr<TrustAnchor>, base::StringPieceHash> anchors_;
diff --git a/net/cert/internal/verify_certificate_chain.cc b/net/cert/internal/verify_certificate_chain.cc index ee379fd..7bd928bc 100644 --- a/net/cert/internal/verify_certificate_chain.cc +++ b/net/cert/internal/verify_certificate_chain.cc
@@ -103,15 +103,9 @@ // This function corresponds to RFC 5280 section 6.1.3's "Basic Certificate // Processing" procedure. -// -// |skip_issuer_checks| controls whether the function will skip: -// - Checking that |cert|'s signature using |working_spki| -// - Checkinging that |cert|'s issuer matches |working_normalized_issuer_name| -// This should be set to true only when verifying a trusted root certificate. WARN_UNUSED_RESULT bool BasicCertificateProcessing( const ParsedCertificate& cert, bool is_target_cert, - bool skip_issuer_checks, const SignaturePolicy* signature_policy, const der::GeneralizedTime& time, const der::Input& working_spki, @@ -125,13 +119,11 @@ // Verify the digital signature using the previous certificate's key (RFC // 5280 section 6.1.3 step a.1). - if (!skip_issuer_checks) { - if (!cert.has_valid_supported_signature_algorithm() || - !VerifySignedData(cert.signature_algorithm(), - cert.tbs_certificate_tlv(), cert.signature_value(), - working_spki, signature_policy)) { - return false; - } + if (!cert.has_valid_supported_signature_algorithm() || + !VerifySignedData(cert.signature_algorithm(), cert.tbs_certificate_tlv(), + cert.signature_value(), working_spki, + signature_policy)) { + return false; } // Check the time range for the certificate's validity, ensuring it is valid @@ -144,10 +136,8 @@ // Verify the certificate's issuer name matches the issuing certificate's // subject name. (RFC 5280 section 6.1.3 step a.4) - if (!skip_issuer_checks) { - if (cert.normalized_issuer() != working_normalized_issuer_name) - return false; - } + if (cert.normalized_issuer() != working_normalized_issuer_name) + return false; // Name constraints (RFC 5280 section 6.1.3 step b & c) // If certificate i is self-issued and it is not the final certificate in the @@ -337,24 +327,15 @@ // This implementation is structured to mimic the description of certificate // path verification given by RFC 5280 section 6.1. -// -// Unlike RFC 5280, the trust anchor is specified as the root certificate in -// the chain. This root certificate is assumed to be trusted, and neither its -// signature nor issuer name are verified. (It needn't be self-signed). -bool VerifyCertificateChainAssumingTrustedRoot( - const ParsedCertificateList& certs, - // The trust store is only used for assertions. - const TrustStore& trust_store, - const SignaturePolicy* signature_policy, - const der::GeneralizedTime& time) { +bool VerifyCertificateChain(const ParsedCertificateList& certs, + const TrustAnchor* trust_anchor, + const SignaturePolicy* signature_policy, + const der::GeneralizedTime& time) { // An empty chain is necessarily invalid. if (certs.empty()) return false; - // IMPORTANT: the assumption being made is that the root certificate in - // the given path is the trust anchor (and has already been verified as - // such). - DCHECK(trust_store.IsTrustedCertificate(certs.back().get())); + // TODO(crbug.com/635200): Support anchor constraints. // Will contain a NameConstraints for each previous cert in the chain which // had nameConstraints. This corresponds to the permitted_subtrees and @@ -375,14 +356,15 @@ // // working_public_key: the public key used to verify the // signature of a certificate. - der::Input working_spki; + der::Input working_spki = trust_anchor->spki(); // |working_normalized_issuer_name| is the normalized value of the // working_issuer_name variable in RFC 5280 section 6.1.2: // // working_issuer_name: the issuer distinguished name expected // in the next certificate in the chain. - der::Input working_normalized_issuer_name; + der::Input working_normalized_issuer_name = + trust_anchor->normalized_subject(); // |max_path_length| corresponds with the same named variable in RFC 5280 // section 6.1.2: @@ -395,11 +377,12 @@ size_t max_path_length = certs.size(); // Iterate over all the certificates in the reverse direction: starting from - // the trust anchor and progressing towards the target certificate. + // the certificate signed by trust anchor and progressing towards the target + // certificate. // // Note that |i| uses 0-based indexing whereas in RFC 5280 it is 1-based. // - // * i=0 : Trust anchor. + // * i=0 : Certificated signed by trust anchor. // * i=N-1 : Target certificate. for (size_t i = 0; i < certs.size(); ++i) { const size_t index_into_certs = certs.size() - i - 1; @@ -409,10 +392,6 @@ // end-entity certificate. const bool is_target_cert = index_into_certs == 0; - // |is_trust_anchor| is true if the current certificate is the trust - // anchor. This certificate is implicitly trusted. - const bool is_trust_anchor = i == 0; - const ParsedCertificate& cert = *certs[index_into_certs]; // Per RFC 5280 section 6.1: @@ -420,10 +399,9 @@ // * If it is the last certificate in the path (target certificate) // - Then run "Wrap up" // - Otherwise run "Prepare for Next cert" - if (!BasicCertificateProcessing(cert, is_target_cert, is_trust_anchor, - signature_policy, time, working_spki, - working_normalized_issuer_name, - name_constraints_list)) { + if (!BasicCertificateProcessing( + cert, is_target_cert, signature_policy, time, working_spki, + working_normalized_issuer_name, name_constraints_list)) { return false; } if (!is_target_cert) {
diff --git a/net/cert/internal/verify_certificate_chain.h b/net/cert/internal/verify_certificate_chain.h index 5dc6275..6d5c557 100644 --- a/net/cert/internal/verify_certificate_chain.h +++ b/net/cert/internal/verify_certificate_chain.h
@@ -20,15 +20,19 @@ } class SignaturePolicy; +class TrustAnchor; class TrustStore; -// VerifyCertificateChainAssumingTrustedRoot() verifies a certificate path -// (chain) based on the rules in RFC 5280. The caller is responsible for -// building the path and ensuring the chain ends in a trusted root certificate. +// VerifyCertificateChain() verifies a certificate path (chain) based on the +// rules in RFC 5280. The caller is responsible for building the path and +// finding the trust anchor. // // WARNING: This implementation is in progress, and is currently incomplete. // Consult an OWNER before using it. // +// TODO(eroman): Take a CertPath instead of ParsedCertificateList + +// TrustAnchor. +// // --------- // Inputs // --------- @@ -39,11 +43,10 @@ // // * cert_chain[0] is the target certificate to verify. // * cert_chain[i+1] holds the certificate that issued cert_chain[i]. -// * cert_chain[N-1] must be the trust anchor. +// * cert_chain[N-1] must be issued by the trust anchor. // -// trust_store: -// Contains the set of trusted public keys (and their names). This is only -// used to DCHECK that the final cert is a trust anchor. +// trust_anchor: +// Contains the trust anchor (root) used to verify the chain. // // signature_policy: // The policy to use when verifying signatures (what hash algorithms are @@ -57,12 +60,11 @@ // --------- // // Returns true if the target certificate can be verified. -NET_EXPORT bool VerifyCertificateChainAssumingTrustedRoot( - const ParsedCertificateList& certs, - // The trust store is only used for assertions. - const TrustStore& trust_store, - const SignaturePolicy* signature_policy, - const der::GeneralizedTime& time) WARN_UNUSED_RESULT; +NET_EXPORT bool VerifyCertificateChain(const ParsedCertificateList& certs, + const TrustAnchor* trust_anchor, + const SignaturePolicy* signature_policy, + const der::GeneralizedTime& time) + WARN_UNUSED_RESULT; } // namespace net
diff --git a/net/cert/internal/verify_certificate_chain_pkits_unittest.cc b/net/cert/internal/verify_certificate_chain_pkits_unittest.cc index 33a1156..fb63db1 100644 --- a/net/cert/internal/verify_certificate_chain_pkits_unittest.cc +++ b/net/cert/internal/verify_certificate_chain_pkits_unittest.cc
@@ -66,16 +66,17 @@ } } - TrustStore trust_store; - trust_store.AddTrustedCertificate(input_chain.back()); + scoped_refptr<TrustAnchor> trust_anchor = + TrustAnchor::CreateFromCertificateNoConstraints(input_chain.back()); + input_chain.pop_back(); SimpleSignaturePolicy signature_policy(1024); // Run all tests at the time the PKITS was published. der::GeneralizedTime time = {2011, 4, 15, 0, 0, 0}; - return VerifyCertificateChainAssumingTrustedRoot(input_chain, trust_store, - &signature_policy, time); + return VerifyCertificateChain(input_chain, trust_anchor.get(), + &signature_policy, time); } };
diff --git a/net/cert/internal/verify_certificate_chain_typed_unittest.h b/net/cert/internal/verify_certificate_chain_typed_unittest.h index b4990a3..c0ce73e6 100644 --- a/net/cert/internal/verify_certificate_chain_typed_unittest.h +++ b/net/cert/internal/verify_certificate_chain_typed_unittest.h
@@ -10,6 +10,7 @@ #include "base/path_service.h" #include "net/cert/internal/parsed_certificate.h" #include "net/cert/internal/test_helpers.h" +#include "net/cert/internal/trust_store.h" #include "net/cert/pem_tokenizer.h" #include "net/der/input.h" #include "testing/gtest/include/gtest/gtest.h" @@ -21,92 +22,14 @@ public: void RunTest(const char* file_name) { ParsedCertificateList chain; - ParsedCertificateList roots; + scoped_refptr<TrustAnchor> trust_anchor; der::GeneralizedTime time; bool expected_result; - ReadTestFromFile(file_name, &chain, &roots, &time, &expected_result); + ReadVerifyCertChainTestFromFile(file_name, &chain, &trust_anchor, &time, + &expected_result); - TestDelegate::Verify(chain, roots, time, expected_result); - } - - private: - // Reads a data file from the unit-test data. - std::string ReadTestFileToString(const std::string& file_name) { - // Compute the full path, relative to the src/ directory. - base::FilePath src_root; - PathService::Get(base::DIR_SOURCE_ROOT, &src_root); - base::FilePath filepath = src_root.AppendASCII( - std::string("net/data/verify_certificate_chain_unittest/") + file_name); - - // Read the full contents of the file. - std::string file_data; - if (!base::ReadFileToString(filepath, &file_data)) { - ADD_FAILURE() << "Couldn't read file: " << filepath.value(); - return std::string(); - } - - return file_data; - } - - // Reads a test case from |file_name|. Test cases are comprised of a - // certificate chain, trust store, a timestamp to validate at, and the - // expected result of verification. - void ReadTestFromFile(const std::string& file_name, - ParsedCertificateList* chain, - ParsedCertificateList* roots, - der::GeneralizedTime* time, - bool* verify_result) { - chain->clear(); - roots->clear(); - - std::string file_data = ReadTestFileToString(file_name); - - std::vector<std::string> pem_headers; - - const char kCertificateHeader[] = "CERTIFICATE"; - const char kTrustedCertificateHeader[] = "TRUSTED_CERTIFICATE"; - const char kTimeHeader[] = "TIME"; - const char kResultHeader[] = "VERIFY_RESULT"; - - pem_headers.push_back(kCertificateHeader); - pem_headers.push_back(kTrustedCertificateHeader); - pem_headers.push_back(kTimeHeader); - pem_headers.push_back(kResultHeader); - - bool has_time = false; - bool has_result = false; - - PEMTokenizer pem_tokenizer(file_data, pem_headers); - while (pem_tokenizer.GetNext()) { - const std::string& block_type = pem_tokenizer.block_type(); - const std::string& block_data = pem_tokenizer.data(); - - if (block_type == kCertificateHeader) { - ASSERT_TRUE(net::ParsedCertificate::CreateAndAddToVector( - reinterpret_cast<const uint8_t*>(block_data.data()), - block_data.size(), - net::ParsedCertificate::DataSource::INTERNAL_COPY, {}, chain)); - } else if (block_type == kTrustedCertificateHeader) { - ASSERT_TRUE(net::ParsedCertificate::CreateAndAddToVector( - reinterpret_cast<const uint8_t*>(block_data.data()), - block_data.size(), - net::ParsedCertificate::DataSource::INTERNAL_COPY, {}, roots)); - } else if (block_type == kTimeHeader) { - ASSERT_FALSE(has_time) << "Duplicate " << kTimeHeader; - has_time = true; - ASSERT_TRUE(der::ParseUTCTime(der::Input(&block_data), time)); - } else if (block_type == kResultHeader) { - ASSERT_FALSE(has_result) << "Duplicate " << kResultHeader; - ASSERT_TRUE(block_data == "SUCCESS" || block_data == "FAIL") - << "Unrecognized result: " << block_data; - has_result = true; - *verify_result = block_data == "SUCCESS"; - } - } - - ASSERT_TRUE(has_time); - ASSERT_TRUE(has_result); + TestDelegate::Verify(chain, trust_anchor, time, expected_result); } }; @@ -251,7 +174,11 @@ this->RunTest("key-rollover-newchain.pem"); } -// TODO(eroman): Add test that invalidate validity dates where the day or month +TYPED_TEST_P(VerifyCertificateChainSingleRootTest, UnknownRoot) { + this->RunTest("unknown-root.pem"); +} + +// TODO(eroman): Add test that invalid validity dates where the day or month // ordinal not in range, like "March 39, 2016" are rejected. REGISTER_TYPED_TEST_CASE_P(VerifyCertificateChainSingleRootTest, @@ -284,20 +211,7 @@ KeyRolloverOldChain, KeyRolloverRolloverChain, KeyRolloverLongRolloverChain, - KeyRolloverNewChain); - -// Tests that have zero roots or more than one root. -template <typename TestDelegate> -class VerifyCertificateChainNonSingleRootTest - : public VerifyCertificateChainTest<TestDelegate> {}; - -TYPED_TEST_CASE_P(VerifyCertificateChainNonSingleRootTest); - -TYPED_TEST_P(VerifyCertificateChainNonSingleRootTest, UnknownRoot) { - this->RunTest("unknown-root.pem"); -} - -REGISTER_TYPED_TEST_CASE_P(VerifyCertificateChainNonSingleRootTest, + KeyRolloverNewChain, UnknownRoot); } // namespace net
diff --git a/net/cert/internal/verify_certificate_chain_unittest.cc b/net/cert/internal/verify_certificate_chain_unittest.cc index b857296..225dcab 100644 --- a/net/cert/internal/verify_certificate_chain_unittest.cc +++ b/net/cert/internal/verify_certificate_chain_unittest.cc
@@ -12,23 +12,18 @@ namespace { -class VerifyCertificateChainAssumingTrustedRootDelegate { +class VerifyCertificateChainDelegate { public: static void Verify(const ParsedCertificateList& chain, - const ParsedCertificateList& roots, + const scoped_refptr<TrustAnchor>& trust_anchor, const der::GeneralizedTime& time, bool expected_result) { - TrustStore trust_store; - ASSERT_EQ(1U, roots.size()); - trust_store.AddTrustedCertificate(roots[0]); - - ParsedCertificateList full_chain(chain); - full_chain.push_back(roots[0]); + ASSERT_TRUE(trust_anchor); SimpleSignaturePolicy signature_policy(1024); - bool result = VerifyCertificateChainAssumingTrustedRoot( - full_chain, trust_store, &signature_policy, time); + bool result = VerifyCertificateChain(chain, trust_anchor.get(), + &signature_policy, time); ASSERT_EQ(expected_result, result); } @@ -36,9 +31,8 @@ } // namespace -INSTANTIATE_TYPED_TEST_CASE_P( - VerifyCertificateChainAssumingTrustedRoot, - VerifyCertificateChainSingleRootTest, - VerifyCertificateChainAssumingTrustedRootDelegate); +INSTANTIATE_TYPED_TEST_CASE_P(VerifyCertificateChain, + VerifyCertificateChainSingleRootTest, + VerifyCertificateChainDelegate); } // namespace net
diff --git a/net/cert/multi_log_ct_verifier.cc b/net/cert/multi_log_ct_verifier.cc index d3ff737..8cba5b0 100644 --- a/net/cert/multi_log_ct_verifier.cc +++ b/net/cert/multi_log_ct_verifier.cc
@@ -46,12 +46,14 @@ // * When SCTs are available, how many are available per connection. void LogNumSCTsToUMA(const ct::CTVerifyResult& result) { UMA_HISTOGRAM_CUSTOM_COUNTS("Net.CertificateTransparency.SCTsPerConnection", - result.invalid_scts.size() + - result.verified_scts.size() + - result.unknown_logs_scts.size(), - 1, - 10, - 11); + result.scts.size(), 1, 10, 11); +} + +void AddSCTAndLogStatus(scoped_refptr<ct::SignedCertificateTimestamp> sct, + ct::SCTVerifyStatus status, + SignedCertificateTimestampAndStatusList* sct_list) { + LogSCTStatusToUMA(status); + sct_list->push_back(SignedCertificateTimestampAndStatus(sct, status)); } } // namespace @@ -82,9 +84,7 @@ DCHECK(cert); DCHECK(result); - result->verified_scts.clear(); - result->invalid_scts.clear(); - result->unknown_logs_scts.clear(); + result->scts.clear(); bool has_verified_scts = false; @@ -191,8 +191,7 @@ const auto& it = logs_.find(sct->log_id); if (it == logs_.end()) { DVLOG(1) << "SCT does not match any known log."; - result->unknown_logs_scts.push_back(sct); - LogSCTStatusToUMA(ct::SCT_STATUS_LOG_UNKNOWN); + AddSCTAndLogStatus(sct, ct::SCT_STATUS_LOG_UNKNOWN, &(result->scts)); return false; } @@ -200,21 +199,18 @@ if (!it->second->Verify(expected_entry, *sct.get())) { DVLOG(1) << "Unable to verify SCT signature."; - result->invalid_scts.push_back(sct); - LogSCTStatusToUMA(ct::SCT_STATUS_INVALID); + AddSCTAndLogStatus(sct, ct::SCT_STATUS_INVALID, &(result->scts)); return false; } // SCT verified ok, just make sure the timestamp is legitimate. if (sct->timestamp > base::Time::Now()) { DVLOG(1) << "SCT is from the future!"; - result->invalid_scts.push_back(sct); - LogSCTStatusToUMA(ct::SCT_STATUS_INVALID); + AddSCTAndLogStatus(sct, ct::SCT_STATUS_INVALID, &(result->scts)); return false; } - LogSCTStatusToUMA(ct::SCT_STATUS_OK); - result->verified_scts.push_back(sct); + AddSCTAndLogStatus(sct, ct::SCT_STATUS_OK, &(result->scts)); if (observer_) observer_->OnSCTVerified(cert, sct.get()); return true;
diff --git a/net/cert/multi_log_ct_verifier_unittest.cc b/net/cert/multi_log_ct_verifier_unittest.cc index 613218c..40617ad 100644 --- a/net/cert/multi_log_ct_verifier_unittest.cc +++ b/net/cert/multi_log_ct_verifier_unittest.cc
@@ -85,14 +85,13 @@ return false; const TestNetLogEntry& parsed = entries[1]; - base::ListValue* verified_scts; - if (!parsed.GetListValue("verified_scts", &verified_scts) || - verified_scts->GetSize() != 1) { + base::ListValue* scts; + if (!parsed.GetListValue("scts", &scts) || scts->GetSize() != 1) { return false; } base::DictionaryValue* the_sct; - if (!verified_scts->GetDictionary(0, &the_sct)) + if (!scts->GetDictionary(0, &the_sct)) return false; std::string origin; @@ -101,16 +100,11 @@ if (origin != "Embedded in certificate") return false; - base::ListValue* other_scts; - if (!parsed.GetListValue("invalid_scts", &other_scts) || - !other_scts->empty()) { + std::string verification_status; + if (!the_sct->GetString("verification_status", &verification_status)) return false; - } - - if (!parsed.GetListValue("unknown_logs_scts", &other_scts) || - !other_scts->empty()) { + if (verification_status != "Verified") return false; - } return true; } @@ -236,8 +230,9 @@ EXPECT_NE(OK, verifier_->Verify( chain_.get(), std::string(), sct_list, &result, BoundNetLog())); - EXPECT_EQ(1U, result.unknown_logs_scts.size()); - EXPECT_EQ("", result.unknown_logs_scts[0]->log_description); + EXPECT_EQ(1U, result.scts.size()); + EXPECT_EQ("", result.scts[0].sct->log_description); + EXPECT_EQ(ct::SCT_STATUS_LOG_UNKNOWN, result.scts[0].status); } TEST_F(MultiLogCTVerifierTest, CountsValidSCTsInStatusHistogram) {
diff --git a/net/cert/multi_threaded_cert_verifier.cc b/net/cert/multi_threaded_cert_verifier.cc index 7e51fd20..c17061f 100644 --- a/net/cert/multi_threaded_cert_verifier.cc +++ b/net/cert/multi_threaded_cert_verifier.cc
@@ -338,7 +338,7 @@ : requests_(0), inflight_joins_(0), verify_proc_(verify_proc) {} MultiThreadedCertVerifier::~MultiThreadedCertVerifier() { - STLDeleteElements(&inflight_); + base::STLDeleteElements(&inflight_); } int MultiThreadedCertVerifier::Verify(const RequestParams& params,
diff --git a/net/cert/test_root_certs_nss.cc b/net/cert/test_root_certs_nss.cc index bcd4add..99ca634 100644 --- a/net/cert/test_root_certs_nss.cc +++ b/net/cert/test_root_certs_nss.cc
@@ -108,7 +108,7 @@ // occur after Clear() has been called. DCHECK_EQ(SECSuccess, rv) << "Cannot restore certificate trust."; } - STLDeleteElements(&trust_cache_); + base::STLDeleteElements(&trust_cache_); } bool TestRootCerts::IsEmpty() const {
diff --git a/net/cert_net/cert_net_fetcher_impl.cc b/net/cert_net/cert_net_fetcher_impl.cc index e46a0f3..3859486 100644 --- a/net/cert_net/cert_net_fetcher_impl.cc +++ b/net/cert_net/cert_net_fetcher_impl.cc
@@ -431,7 +431,7 @@ } CertNetFetcherImpl::~CertNetFetcherImpl() { - STLDeleteElements(&jobs_); + base::STLDeleteElements(&jobs_); // The CertNetFetcherImpl was destroyed in a FetchCallback. Detach all // remaining requests from the job so no further callbacks are called.
diff --git a/net/cert_net/nss_ocsp.cc b/net/cert_net/nss_ocsp.cc index e870e3a..4600056 100644 --- a/net/cert_net/nss_ocsp.cc +++ b/net/cert_net/nss_ocsp.cc
@@ -543,12 +543,12 @@ } void OCSPIOLoop::AddRequest(OCSPRequestSession* request) { - DCHECK(!ContainsKey(requests_, request)); + DCHECK(!base::ContainsKey(requests_, request)); requests_.insert(request); } void OCSPIOLoop::RemoveRequest(OCSPRequestSession* request) { - DCHECK(ContainsKey(requests_, request)); + DCHECK(base::ContainsKey(requests_, request)); requests_.erase(request); }
diff --git a/net/data/verify_certificate_chain_unittest/README b/net/data/verify_certificate_chain_unittest/README index 5c7019d..e425e38 100644 --- a/net/data/verify_certificate_chain_unittest/README +++ b/net/data/verify_certificate_chain_unittest/README
@@ -20,10 +20,46 @@ *.pem =============================== -These files descibe a test case for certificate chain verification. +Each .pem file describes the inputs for certificate chain verification, and the +expected result. These are the PEM blocks that each file contains and their +interpretation: -The input file is a PEM file with blocks for: - * The trust store - * The certificate chain (target certificate and all intermediates) - * The timestamp to use when verifying - * The expected result of verification (success or fail) +CERTIFICATE: + +These PEM blocks describe the ordered chain of certificates starting from the +target certificate and progressing towards the trust anchor (but not including +the trust anchor). + + - There must be one or more such PEM blocks + - Its contents are a DER-encoded X.509 certificate + - The first block is the target certificate + - The (i+1)th CERTIFICATE is (allegedly) the one which issued the ith + CERTIFICATE. + +TRUST_ANCHOR_{XXX}: + +This PEM block describes the trust anchor to use when verifying the chain. +There are two possible names for this PEM block, which affect how it is +interpreted: TRUST_ANCHOR_CONSTRAINED or TRUST_ANCHOR_UNCONSTRAINED. + + - There must be exactly one TRUST_ANCHOR_{XXX} block. + - Its contents are a DER-encoded X.509 certificate + - The subject and SPKI from the certificate define the trust anchor + - If the block was named TRUST_ANCHOR_CONSTRAINED, then any constraints on the + certificate are also considered normative when verifying paths. Otherwise + any standard extensions provided by the root certificate are not used during + path validation. + +TIMESTAMP: + +This PEM block describes the time to use when verifying the chain. + + - There must be exactly one such PEM block + - Its contents are a DER-encoded UTCTime. + +VERIFY_RESULT: + +This PEM block describes the expected result from verifying the path. + + - There must be exactly one such PEM block + - Its contents are a string with value of either "SUCCESS" or "FAIL"
diff --git a/net/data/verify_certificate_chain_unittest/basic-constraints-pathlen-0-self-issued.pem b/net/data/verify_certificate_chain_unittest/basic-constraints-pathlen-0-self-issued.pem index 21e913b..e6d832f 100644 --- a/net/data/verify_certificate_chain_unittest/basic-constraints-pathlen-0-self-issued.pem +++ b/net/data/verify_certificate_chain_unittest/basic-constraints-pathlen-0-self-issued.pem
@@ -339,7 +339,7 @@ f5:e6:8f:59:49:7c:d1:a6:e2:f4:1f:a2:7f:92:2b:6a:c0:44: d7:c0:e5:7f:d9:44:13:82:ae:06:ee:1f:64:04:c4:7d:7f:cf: 04:97:2e:41 ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANpCrkC0eZVDWEup4GKW @@ -359,7 +359,7 @@ DJEoiA/ae5JmY4W28imPLKrEtFMyoQAvpR008DKyWaFh9BZCpZr7YjHjhTsjcy3B zIiX9hKVAVJdwgaqhRwleJ715o9ZSXzRpuL0H6J/kitqwETXwOV/2UQTgq4G7h9k BMR9f88Ely5B ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/common.py b/net/data/verify_certificate_chain_unittest/common.py index 92e84b7..b21e2a9c 100755 --- a/net/data/verify_certificate_chain_unittest/common.py +++ b/net/data/verify_certificate_chain_unittest/common.py
@@ -53,7 +53,7 @@ g_out_pem = None -def GetUniquePathId(name): +def get_unique_path_id(name): """Returns a base filename that contains 'name', but is unique to the output directory""" path_id = g_cur_path_id.get(name, 0) @@ -67,6 +67,61 @@ return '%s_%d' % (name, path_id) +def get_path_in_output_dir(name, suffix): + return os.path.join(g_out_dir, '%s%s' % (name, suffix)) + + +def get_unique_path_in_output_dir(name, suffix): + return get_path_in_output_dir(get_unique_path_id(name), suffix) + + +class Key(object): + """Describes a public + private key pair. It is a dumb wrapper around an + on-disk key.""" + + def __init__(self, path): + self.path = path + + + def get_path(self): + """Returns the path to a file that contains the key contents.""" + return self.path + + +def generate_rsa_key(size_bits, path=None): + """Generates an RSA private key and returns it as a Key object. If |path| is + specified the resulting key will be saved at that location.""" + if path is None: + path = get_unique_path_in_output_dir('RsaKey', 'key') + + # Ensure the path doesn't already exists (otherwise will be overwriting + # something). + assert not os.path.isfile(path) + + subprocess.check_call( + ['openssl', 'genrsa', '-out', path, str(size_bits)]) + + return Key(path) + + +def generate_ec_key(named_curve, path=None): + """Generates an EC private key for the certificate and returns it as a Key + object. |named_curve| can be something like secp384r1. If |path| is specified + the resulting key will be saved at that location.""" + if path is None: + path = get_unique_path_in_output_dir('EcKey', 'key') + + # Ensure the path doesn't already exists (otherwise will be overwriting + # something). + assert not os.path.isfile(path) + + subprocess.check_call( + ['openssl', 'ecparam', '-out', path, + '-name', named_curve, '-genkey']) + + return Key(path) + + class Certificate(object): """Helper for building an X.509 certificate.""" @@ -74,10 +129,11 @@ # The name will be used for the subject's CN, and also as a component of # the temporary filenames to help with debugging. self.name = name - self.path_id = GetUniquePathId(name) + self.path_id = get_unique_path_id(name) - # If specified, use the key from this path instead of generating a new one. - self.key_path = None + # Allow the caller to override the key later. If no key was set will + # auto-generate one. + self.key = None # The issuer is also a Certificate object. Passing |None| means it is a # self-signed certificate. @@ -98,7 +154,7 @@ self.md_flags = [] # By default OpenSSL will use the current time for the start time. Instead - # default to using a fixed timestamp for more predictabl results each time + # default to using a fixed timestamp for more predictable results each time # the certificates are re-generated. self.set_validity_range(JANUARY_1_2015_UTC, JANUARY_1_2016_UTC) @@ -133,22 +189,6 @@ write_string_to_file('', self.get_database_path()) - def generate_rsa_key(self, size_bits): - """Generates an RSA private key for the certificate.""" - assert self.key_path is None - subprocess.check_call( - ['openssl', 'genrsa', '-out', self.get_key_path(), str(size_bits)]) - - - def generate_ec_key(self, named_curve): - """Generates an EC private key for the certificate. |named_curve| can be - something like secp384r1""" - assert self.key_path is None - subprocess.check_call( - ['openssl', 'ecparam', '-out', self.get_key_path(), - '-name', named_curve, '-genkey']) - - def set_validity_range(self, start_date, end_date): """Sets the Validity notBefore and notAfter properties for the certificate""" @@ -175,20 +215,26 @@ """Forms a path to an output file for this CA, containing the indicated suffix. If multiple certificates have the same name, they will use the same path.""" - return os.path.join(g_out_dir, '%s%s' % (self.name, suffix)) + return get_path_in_output_dir(self.name, suffix) - def set_key_path(self, path): - """Uses the key from the given path instead of generating a new one.""" - self.key_path = path + def set_key(self, key): + assert self.finalized is False + self.set_key_internal(key) + + + def set_key_internal(self, key): + self.key = key + + # Associate the private key with the certificate. section = self.config.get_section('root_ca') - section.set_property('private_key', self.get_key_path()) + section.set_property('private_key', self.key.get_path()) - def get_key_path(self): - if self.key_path is not None: - return self.key_path - return self.get_path('.key') + def get_key(self): + if self.key is None: + self.set_key_internal(generate_rsa_key(2048, path=self.get_path(".key"))) + return self.key def get_cert_path(self): @@ -234,11 +280,9 @@ # accessible. Note that self.issuer could be the same as self. self.issuer.finalize() - # Ensure the certificate has a key. Callers have the option to generate a - # different type of key, but if that was not done default to a new 2048-bit - # RSA key. - if not os.path.isfile(self.get_key_path()): - self.generate_rsa_key(2048) + # Ensure the certificate has a key (gets lazily created by this call if + # missing). + self.get_key() # Serialize the config to a file. self.config.write_to_file(self.get_config_path()) @@ -246,7 +290,7 @@ # Create a CSR. subprocess.check_call( ['openssl', 'req', '-new', - '-key', self.get_key_path(), + '-key', self.key.get_path(), '-out', self.get_csr_path(), '-config', self.get_config_path()]) @@ -319,7 +363,6 @@ section = self.config.get_section('root_ca') section.set_property('certificate', self.get_cert_path()) - section.set_property('private_key', self.get_key_path()) section.set_property('new_certs_dir', g_out_dir) section.set_property('serial', self.get_serial_path()) section.set_property('database', self.get_database_path()) @@ -372,7 +415,27 @@ base64.b64encode(block_data), block_header) -def write_test_file(description, chain, trusted_certs, utc_time, verify_result, +class TrustAnchor(object): + """Structure that represents a trust anchor.""" + + def __init__(self, cert, constrained=False): + self.cert = cert + self.constrained = constrained + + + def get_pem(self): + """Returns a PEM block string describing this trust anchor.""" + + cert_data = self.cert.get_cert_pem() + block_name = 'TRUST_ANCHOR_UNCONSTRAINED' + if self.constrained: + block_name = 'TRUST_ANCHOR_CONSTRAINED' + + # Use a different block name in the .pem file, depending on the anchor type. + return cert_data.replace('CERTIFICATE', block_name) + + +def write_test_file(description, chain, trust_anchor, utc_time, verify_result, out_pem=None): """Writes a test file that contains all the inputs necessary to run a verification on a certificate chain""" @@ -384,13 +447,7 @@ for cert in chain: test_data += '\n' + cert.get_cert_pem() - # Write the trust store. - for cert in trusted_certs: - cert_data = cert.get_cert_pem() - # Use a different block type in the .pem file. - cert_data = cert_data.replace('CERTIFICATE', 'TRUSTED_CERTIFICATE') - test_data += '\n' + cert_data - + test_data += '\n' + trust_anchor.get_pem() test_data += '\n' + data_to_pem('TIME', utc_time) verify_result_string = 'SUCCESS' if verify_result else 'FAIL'
diff --git a/net/data/verify_certificate_chain_unittest/expired-intermediate.pem b/net/data/verify_certificate_chain_unittest/expired-intermediate.pem index 6ca87fd4..66cd20f 100644 --- a/net/data/verify_certificate_chain_unittest/expired-intermediate.pem +++ b/net/data/verify_certificate_chain_unittest/expired-intermediate.pem
@@ -249,7 +249,7 @@ 3d:df:f2:cc:57:ea:1a:58:1d:f8:90:d4:2d:53:67:56:c3:88: 9d:17:0f:19:19:fc:ed:4e:cc:b9:76:fa:fc:93:e5:bf:08:e7: a9:d6:46:0f ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMlTr0/RNV8+aQgTKEFb @@ -269,7 +269,7 @@ JARnUDh+6csMlA3QB1BSpQMQB2oE7zPqsHCfJzRHsPhBgX7ykwvAz8PXBlnxJCph ZH848E9305LkH+REpLaFQFk93/LMV+oaWB34kNQtU2dWw4idFw8ZGfztTsy5dvr8 k+W/COep1kYP ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/expired-root.pem b/net/data/verify_certificate_chain_unittest/expired-root.pem index 57b0b7b0..d765cfab 100644 --- a/net/data/verify_certificate_chain_unittest/expired-root.pem +++ b/net/data/verify_certificate_chain_unittest/expired-root.pem
@@ -1,7 +1,8 @@ [Created by: generate-expired-root.py] Certificate chain with 1 intermediate, where the root certificate is expired -(violates validity.notAfter). Verification is expected to fail. +(violates validity.notAfter). Verification is expected to succeed as +constraints on trust anchors are not enforced.. Certificate: Data: @@ -17,30 +18,30 @@ Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: - 00:de:6b:17:fa:9d:bf:8d:97:11:c1:2b:af:53:67: - 89:b2:bb:1b:7c:25:a6:ba:81:f9:43:3f:15:51:06: - 24:11:3c:3c:d1:28:16:86:53:15:fb:e6:99:67:08: - d7:2a:74:2d:ba:f2:72:55:ec:8e:7b:13:30:f8:31: - dc:16:a2:7f:7a:83:9c:26:ee:cb:5a:49:68:75:7e: - 97:a9:04:e5:2a:dc:e7:5d:9d:60:22:7f:b5:b3:d5: - 13:7c:64:3b:75:a5:b8:92:8f:67:7e:de:7e:42:13: - 7a:d2:e1:da:c5:f5:a7:bb:db:57:db:e5:09:d8:37: - 6f:80:c0:06:52:c5:ea:33:1b:35:ba:21:de:6c:a0: - e2:c8:19:b4:cc:3e:3c:0e:af:f1:a8:c6:01:f7:d8: - 7a:dc:83:4a:e8:9f:dc:30:f7:c8:a4:19:c4:89:45: - 69:60:3b:ca:a0:f8:86:09:56:1e:0f:55:c4:32:8f: - 95:fd:02:ee:e6:76:d5:bc:4a:6c:8f:b4:47:3f:04: - e4:0c:45:16:a3:04:3b:73:f2:5e:2e:6b:62:9e:25: - e9:46:2c:ee:b9:3a:6b:a9:84:63:d2:aa:a6:73:66: - 61:77:90:e2:7b:1e:d0:c3:3c:7d:23:40:cb:9d:a4: - 53:ab:bb:9d:57:b8:dd:30:f4:89:cd:be:40:0f:8c: - fe:45 + 00:b3:fa:1c:ab:da:95:23:00:c5:f7:9d:3e:fa:be: + 50:46:36:b3:b8:6c:9b:ed:57:22:ae:c1:19:65:f5: + 53:9b:55:48:bd:9f:59:95:8f:a6:a8:33:25:87:f8: + 69:be:58:ac:73:1f:aa:5b:0d:8d:ed:65:53:a8:fd: + a4:99:92:d7:9f:a2:ce:9d:09:a7:af:65:dd:e7:1c: + 18:9d:61:6e:3f:05:7c:09:10:03:50:90:03:3a:20: + 7c:b5:80:f3:16:8b:d8:1e:c9:e4:53:5d:1c:6e:e2: + b3:b3:9d:87:fa:2b:47:25:fe:ee:8b:4e:22:35:cc: + 22:59:94:78:13:57:67:69:ab:99:14:70:94:2c:0e: + 32:e3:bc:89:b4:e4:b1:09:4b:ae:bd:6d:7e:cd:a8: + ff:ee:37:8b:1a:25:5e:ae:21:51:e2:cb:9c:6a:a5: + 27:23:62:c7:62:89:a1:69:13:c3:03:ec:f9:a7:5a: + 90:e2:e0:c5:c7:6d:ec:76:f5:76:88:f5:15:1a:4d: + 00:da:38:51:ea:03:16:a4:90:74:87:6e:ba:23:3a: + 91:58:a0:94:6c:3c:8c:f1:c6:2f:69:9e:41:1a:50: + ea:3b:d1:a6:d2:9b:50:04:63:ca:b7:c1:eb:04:07: + 89:40:43:07:1e:84:d5:6c:08:01:50:7f:7b:aa:9e: + c4:4d Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: - E1:00:21:A7:60:75:C5:70:AE:67:AA:A2:C0:27:3E:1D:88:0B:8F:3A + BD:E0:2F:8E:DD:4A:65:2F:EE:52:E4:0F:3B:8A:28:80:D6:17:C4:76 X509v3 Authority Key Identifier: - keyid:63:74:44:85:E8:82:EC:BA:73:D2:A8:F4:8D:AF:0B:B0:37:F6:14:DD + keyid:A8:9E:04:25:6D:55:C9:D7:11:47:D3:DD:67:71:0E:7E:88:89:49:71 Authority Information Access: CA Issuers - URI:http://url-for-aia/Intermediate.cer @@ -55,42 +56,42 @@ X509v3 Extended Key Usage: TLS Web Server Authentication, TLS Web Client Authentication Signature Algorithm: sha256WithRSAEncryption - a0:85:7a:3a:fd:63:12:8f:fa:ea:aa:a0:17:37:a9:ee:2d:a1: - 98:e4:4e:c0:5a:8f:42:1e:f7:09:c9:36:0e:8e:7c:0f:00:20: - f8:73:5b:7c:e2:f0:ea:45:35:0e:70:b3:a7:65:d6:8e:ad:02: - 2b:04:79:c0:0b:e3:3e:57:da:ab:7a:e5:78:6e:91:fd:0c:bf: - 3a:22:14:16:c1:42:e1:8c:f9:92:1c:7d:74:b3:72:b6:18:42: - 1f:30:c1:f1:05:f2:7e:9e:71:f8:a7:e1:e4:6d:9b:a4:8a:29: - f0:ae:73:c3:b9:7d:93:5f:4c:b4:7e:4e:fb:6d:3f:4d:85:46: - ea:31:32:01:92:50:10:c7:81:82:d3:86:75:8b:47:c3:e7:e9: - 17:0c:42:d2:e4:70:66:eb:07:e7:6e:1a:12:b2:c9:8a:62:b0: - 0e:8e:27:f1:90:9e:82:10:96:92:c9:9f:31:e1:50:21:e8:39: - c3:d8:26:2a:f9:36:21:02:e7:ac:a7:0c:81:a1:35:1c:7c:33: - e8:84:26:9a:41:a7:07:d0:ff:d5:18:b9:b8:2c:46:47:3a:1b: - 22:c4:35:f7:ab:86:98:63:cf:8a:d1:94:be:5b:59:a3:4b:6a: - 01:1f:df:27:cb:09:d3:98:43:88:80:9c:ed:ca:73:60:41:e0: - 77:8d:e4:ab + 95:07:d3:f3:57:d3:2d:c3:f9:d5:4a:d4:54:85:1f:25:3d:3c: + e8:34:6f:6e:bc:5a:b3:50:fd:4f:b5:cf:87:54:26:7b:ab:4d: + 5d:28:af:29:d1:24:ad:75:5d:3f:5b:68:63:b3:c0:20:82:8e: + c4:7f:58:7c:74:ea:d8:0d:50:11:63:43:ee:67:af:9f:16:c3: + 89:f1:15:a6:94:a9:72:bb:0c:40:48:54:25:87:e7:94:6f:34: + f5:83:03:ed:2a:6f:b6:2d:b7:70:4d:8b:6e:31:80:0c:dd:3d: + 9a:84:5a:55:ce:b7:08:a9:15:59:66:ec:a9:a1:4f:79:73:16: + a2:6a:44:1f:7a:6d:69:f2:de:a0:50:07:da:01:4b:22:2e:40: + f4:8b:e7:7c:f3:cd:27:fd:92:eb:fd:e8:4a:da:32:91:6a:ec: + b8:0c:49:db:f8:73:5e:a4:83:a2:c2:40:dd:e0:78:f9:3c:83: + 39:e4:22:88:7c:d1:cf:58:4a:4c:f1:0b:4f:21:94:c4:fb:4e: + a8:c4:84:ce:6a:7c:ff:0c:9b:1f:c6:db:67:22:6d:29:2f:28: + 81:60:c2:a3:ab:af:fa:f9:a5:55:83:35:97:1d:17:23:2a:32: + 75:92:7b:2b:67:99:3c:25:f4:b5:c8:74:ac:05:7e:59:43:5c: + 47:38:16:9b -----BEGIN CERTIFICATE----- MIIDjTCCAnWgAwIBAgIBATANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxJbnRl cm1lZGlhdGUwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjARMQ8wDQYD -VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDeaxf6 -nb+NlxHBK69TZ4myuxt8Jaa6gflDPxVRBiQRPDzRKBaGUxX75plnCNcqdC268nJV -7I57EzD4MdwWon96g5wm7staSWh1fpepBOUq3OddnWAif7Wz1RN8ZDt1pbiSj2d+ -3n5CE3rS4drF9ae721fb5QnYN2+AwAZSxeozGzW6Id5soOLIGbTMPjwOr/GoxgH3 -2Hrcg0ron9ww98ikGcSJRWlgO8qg+IYJVh4PVcQyj5X9Au7mdtW8SmyPtEc/BOQM -RRajBDtz8l4ua2KeJelGLO65OmuphGPSqqZzZmF3kOJ7HtDDPH0jQMudpFOru51X -uN0w9InNvkAPjP5FAgMBAAGjgekwgeYwHQYDVR0OBBYEFOEAIadgdcVwrmeqosAn -Ph2IC486MB8GA1UdIwQYMBaAFGN0RIXoguy6c9Ko9I2vC7A39hTdMD8GCCsGAQUF +VQQDDAZUYXJnZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCz+hyr +2pUjAMX3nT76vlBGNrO4bJvtVyKuwRll9VObVUi9n1mVj6aoMyWH+Gm+WKxzH6pb +DY3tZVOo/aSZktefos6dCaevZd3nHBidYW4/BXwJEANQkAM6IHy1gPMWi9geyeRT +XRxu4rOznYf6K0cl/u6LTiI1zCJZlHgTV2dpq5kUcJQsDjLjvIm05LEJS669bX7N +qP/uN4saJV6uIVHiy5xqpScjYsdiiaFpE8MD7PmnWpDi4MXHbex29XaI9RUaTQDa +OFHqAxakkHSHbrojOpFYoJRsPIzxxi9pnkEaUOo70abSm1AEY8q3wesEB4lAQwce +hNVsCAFQf3uqnsRNAgMBAAGjgekwgeYwHQYDVR0OBBYEFL3gL47dSmUv7lLkDzuK +KIDWF8R2MB8GA1UdIwQYMBaAFKieBCVtVcnXEUfT3WdxDn6IiUlxMD8GCCsGAQUF BwEBBDMwMTAvBggrBgEFBQcwAoYjaHR0cDovL3VybC1mb3ItYWlhL0ludGVybWVk aWF0ZS5jZXIwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL3VybC1mb3ItY3JsL0lu dGVybWVkaWF0ZS5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUF -BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAoIV6Ov1jEo/66qqgFzep -7i2hmOROwFqPQh73Cck2Do58DwAg+HNbfOLw6kU1DnCzp2XWjq0CKwR5wAvjPlfa -q3rleG6R/Qy/OiIUFsFC4Yz5khx9dLNythhCHzDB8QXyfp5x+Kfh5G2bpIop8K5z -w7l9k19MtH5O+20/TYVG6jEyAZJQEMeBgtOGdYtHw+fpFwxC0uRwZusH524aErLJ -imKwDo4n8ZCeghCWksmfMeFQIeg5w9gmKvk2IQLnrKcMgaE1HHwz6IQmmkGnB9D/ -1Ri5uCxGRzobIsQ196uGmGPPitGUvltZo0tqAR/fJ8sJ05hDiICc7cpzYEHgd43k -qw== +BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAlQfT81fTLcP51UrUVIUf +JT086DRvbrxas1D9T7XPh1Qme6tNXSivKdEkrXVdP1toY7PAIIKOxH9YfHTq2A1Q +EWND7mevnxbDifEVppSpcrsMQEhUJYfnlG809YMD7Spvti23cE2LbjGADN09moRa +Vc63CKkVWWbsqaFPeXMWompEH3ptafLeoFAH2gFLIi5A9IvnfPPNJ/2S6/3oStoy +kWrsuAxJ2/hzXqSDosJA3eB4+TyDOeQiiHzRz1hKTPELTyGUxPtOqMSEzmp8/wyb +H8bbZyJtKS8ogWDCo6uv+vmlVYM1lx0XIyoydZJ7K2eZPCX0tch0rAV+WUNcRzgW +mw== -----END CERTIFICATE----- Certificate: @@ -107,30 +108,30 @@ Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: - 00:d6:9b:b6:c4:fd:a9:f3:0d:77:4f:26:65:7d:54: - f5:19:ab:7a:49:c0:8a:90:ee:86:43:c4:1f:52:f8: - af:1c:47:f7:88:0d:19:df:2f:5d:b1:c2:3c:5d:1d: - 9e:54:cd:e0:22:6a:6b:b4:8f:f9:38:0b:ef:b2:81: - 80:ee:22:83:5b:3e:2e:b7:b0:cd:4f:2f:78:be:d4: - 40:3f:c9:d9:4b:f6:39:6c:63:94:a4:c2:1b:97:01: - a2:a6:9b:5c:11:f8:40:c4:25:64:6a:9a:17:fb:43: - ab:d4:42:cd:d3:6e:23:68:90:3e:c0:54:0f:73:58: - 13:c2:70:9f:c6:76:a4:c3:94:e8:b2:5f:16:e3:a9: - f7:87:56:06:85:d9:ca:2c:09:01:39:97:c0:f2:36: - e1:90:97:c1:78:9f:99:86:03:e6:00:6a:ea:2c:60: - b0:ae:08:04:e8:11:bd:7e:e5:4e:e6:b1:9b:d0:1c: - 09:ff:ea:68:1b:c0:54:4a:c5:ad:d9:bd:25:e9:b3: - 7a:66:7f:98:50:9e:a7:c4:1b:ed:fa:2a:cc:94:9e: - bd:4b:11:b4:03:7c:6e:8e:5e:db:46:b1:59:2f:b2: - 18:fc:2f:83:ef:e3:d1:24:3a:c0:60:ae:dd:ab:a6: - 93:07:27:cb:d9:7f:1b:75:f2:1a:82:35:e5:1b:e6: - 27:01 + 00:c0:b1:53:c8:38:a8:e5:4e:90:c9:19:52:07:46: + ec:7c:87:46:9e:ac:a4:c9:51:89:9c:55:43:98:a0: + 58:60:59:ce:73:e2:53:df:4a:e5:fb:ee:57:a9:9c: + da:d3:c4:76:6b:82:77:94:ee:83:39:e5:d6:6e:ed: + e1:3f:6e:80:a0:51:82:85:79:14:53:b6:aa:15:d8: + d7:7a:1a:96:26:8f:09:b8:29:b4:c8:6c:a7:80:e6: + 10:18:ec:d7:f7:b0:ff:59:19:45:f8:37:de:28:bd: + 56:4f:67:53:c1:80:44:7d:80:b5:dd:d6:6f:bf:3b: + 1f:02:f3:00:67:88:7d:36:65:13:39:7d:3e:a8:35: + 13:54:e4:91:c8:ee:f1:53:fd:af:f7:3b:f8:59:e0: + bc:e0:1e:ac:41:01:d1:b8:01:ee:ae:d2:39:b8:fa: + 57:6e:b2:7a:98:5f:51:ac:d6:6a:38:80:6b:01:64: + 13:96:d7:0b:74:5f:76:82:d9:44:9d:47:26:cc:59: + 9a:22:3c:72:eb:20:9a:d9:2b:b1:dd:cd:0a:54:0b: + 77:0b:83:2c:0d:bf:b4:62:4a:fc:87:84:4f:29:8d: + fc:6c:b9:3a:4c:8b:45:85:2b:48:7d:2c:33:1f:ac: + 8b:77:39:8c:cb:0c:f4:08:93:4c:ec:34:15:be:81: + 09:a3 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: - 63:74:44:85:E8:82:EC:BA:73:D2:A8:F4:8D:AF:0B:B0:37:F6:14:DD + A8:9E:04:25:6D:55:C9:D7:11:47:D3:DD:67:71:0E:7E:88:89:49:71 X509v3 Authority Key Identifier: - keyid:01:34:E7:14:1F:DF:2E:D5:19:18:06:94:60:42:D1:A8:FC:16:E0:61 + keyid:29:13:82:EE:25:10:7F:40:23:D6:A7:1B:28:25:35:8A:E8:B6:AA:28 Authority Information Access: CA Issuers - URI:http://url-for-aia/Root.cer @@ -145,41 +146,41 @@ X509v3 Basic Constraints: critical CA:TRUE Signature Algorithm: sha256WithRSAEncryption - 33:28:d1:77:84:d7:9e:51:7e:ce:85:49:35:ee:e8:f3:fb:d6: - 4f:fa:6c:00:0b:90:a1:f1:37:4b:d0:3e:9d:82:2d:e0:96:d8: - 72:fb:61:96:d6:36:a2:1a:ca:62:44:c3:a3:14:c5:0b:e0:de: - 39:a9:c9:75:a4:9f:2c:54:0d:fa:61:5c:fa:6e:66:0f:71:0e: - 58:12:d4:1a:c6:c0:ca:33:f7:8f:0f:2a:8f:a1:2d:c1:a8:64: - 2e:52:23:ac:fe:9b:04:90:84:13:44:40:e8:4b:bf:53:30:72: - ff:5c:7e:8c:62:87:c5:03:a8:84:8c:7c:4d:fb:d6:8c:8c:35: - 56:9b:0f:01:e3:81:9b:6c:36:e2:f1:88:06:16:75:2f:6e:cc: - 70:30:67:c9:6c:3c:28:49:72:0d:11:6b:1d:73:ae:d9:bf:e6: - 6c:63:c4:70:df:18:8c:fc:d0:03:01:c5:8a:22:4e:b1:c5:03: - dc:36:9a:22:08:ab:46:88:d6:93:2c:6c:1b:05:b1:60:69:be: - ad:97:d1:a8:e4:a1:70:5a:ab:84:87:72:75:13:50:95:58:b1: - 80:27:50:60:9b:b1:da:7e:18:b8:f0:bd:f3:54:89:04:32:ff: - b1:f2:be:a8:09:14:b1:74:30:a8:95:8e:59:ed:8a:63:28:ce: - 55:68:d8:e2 + 57:37:54:5c:fd:ce:4e:4c:0f:b5:37:13:0d:0e:5f:dd:d8:4c: + 17:53:38:e6:07:65:6c:67:80:e0:75:25:26:78:7b:2e:b8:1a: + 6c:31:44:a1:5f:73:83:6d:34:1e:ff:76:42:d5:ad:ab:c0:b9: + cc:25:9e:88:7f:be:29:db:49:25:08:5d:3b:7d:43:2e:85:66: + ff:fe:b5:d4:aa:21:7a:b8:5a:b4:49:ab:c6:ef:8d:28:64:f4: + ea:be:64:33:c4:94:c6:31:f5:cc:55:cb:f1:20:be:e6:85:03: + 32:99:61:e0:09:3c:e6:df:61:9a:c5:45:ea:f8:a3:f8:c1:6d: + ff:7b:44:04:8e:7f:74:89:ab:39:5a:fc:a6:09:77:9c:5d:1c: + 99:a8:db:bc:2a:8e:19:25:8d:e3:10:37:94:42:e7:37:9c:16: + ba:be:4b:67:94:5f:18:2e:ae:e3:fd:ef:15:12:7d:4b:5a:47: + b7:45:7a:ee:27:3f:e1:6b:42:02:75:40:36:50:fd:6c:1e:de: + 8a:b9:f7:d5:f8:69:0c:fd:58:65:35:64:a2:ca:c5:1e:b3:aa: + a0:4b:42:22:00:e3:d8:e7:b4:e8:69:48:37:42:55:60:24:48: + 9a:d8:42:9e:d9:cf:2b:3c:9e:b1:fc:2f:39:5d:b5:fe:e3:72: + 44:e4:00:50 -----BEGIN CERTIFICATE----- MIIDbTCCAlWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowFzEVMBMGA1UEAwwMSW50 -ZXJtZWRpYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1pu2xP2p -8w13TyZlfVT1Gat6ScCKkO6GQ8QfUvivHEf3iA0Z3y9dscI8XR2eVM3gImprtI/5 -OAvvsoGA7iKDWz4ut7DNTy94vtRAP8nZS/Y5bGOUpMIblwGipptcEfhAxCVkapoX -+0Or1ELN024jaJA+wFQPc1gTwnCfxnakw5Tosl8W46n3h1YGhdnKLAkBOZfA8jbh -kJfBeJ+ZhgPmAGrqLGCwrggE6BG9fuVO5rGb0BwJ/+poG8BUSsWt2b0l6bN6Zn+Y -UJ6nxBvt+irMlJ69SxG0A3xujl7bRrFZL7IY/C+D7+PRJDrAYK7dq6aTByfL2X8b -dfIagjXlG+YnAQIDAQABo4HLMIHIMB0GA1UdDgQWBBRjdESF6ILsunPSqPSNrwuw -N/YU3TAfBgNVHSMEGDAWgBQBNOcUH98u1RkYBpRgQtGo/BbgYTA3BggrBgEFBQcB +ZXJtZWRpYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwLFTyDio +5U6QyRlSB0bsfIdGnqykyVGJnFVDmKBYYFnOc+JT30rl++5XqZza08R2a4J3lO6D +OeXWbu3hP26AoFGChXkUU7aqFdjXehqWJo8JuCm0yGyngOYQGOzX97D/WRlF+Dfe +KL1WT2dTwYBEfYC13dZvvzsfAvMAZ4h9NmUTOX0+qDUTVOSRyO7xU/2v9zv4WeC8 +4B6sQQHRuAHurtI5uPpXbrJ6mF9RrNZqOIBrAWQTltcLdF92gtlEnUcmzFmaIjxy +6yCa2Sux3c0KVAt3C4MsDb+0Ykr8h4RPKY38bLk6TItFhStIfSwzH6yLdzmMywz0 +CJNM7DQVvoEJowIDAQABo4HLMIHIMB0GA1UdDgQWBBSongQlbVXJ1xFH091ncQ5+ +iIlJcTAfBgNVHSMEGDAWgBQpE4LuJRB/QCPWpxsoJTWK6LaqKDA3BggrBgEFBQcB AQQrMCkwJwYIKwYBBQUHMAKGG2h0dHA6Ly91cmwtZm9yLWFpYS9Sb290LmNlcjAs BgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vdXJsLWZvci1jcmwvUm9vdC5jcmwwDgYD VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEB -ADMo0XeE155Rfs6FSTXu6PP71k/6bAALkKHxN0vQPp2CLeCW2HL7YZbWNqIaymJE -w6MUxQvg3jmpyXWknyxUDfphXPpuZg9xDlgS1BrGwMoz948PKo+hLcGoZC5SI6z+ -mwSQhBNEQOhLv1Mwcv9cfoxih8UDqISMfE371oyMNVabDwHjgZtsNuLxiAYWdS9u -zHAwZ8lsPChJcg0Rax1zrtm/5mxjxHDfGIz80AMBxYoiTrHFA9w2miIIq0aI1pMs -bBsFsWBpvq2X0ajkoXBaq4SHcnUTUJVYsYAnUGCbsdp+GLjwvfNUiQQy/7HyvqgJ -FLF0MKiVjlntimMozlVo2OI= +AFc3VFz9zk5MD7U3Ew0OX93YTBdTOOYHZWxngOB1JSZ4ey64GmwxRKFfc4NtNB7/ +dkLVravAucwlnoh/vinbSSUIXTt9Qy6FZv/+tdSqIXq4WrRJq8bvjShk9Oq+ZDPE +lMYx9cxVy/EgvuaFAzKZYeAJPObfYZrFRer4o/jBbf97RASOf3SJqzla/KYJd5xd +HJmo27wqjhkljeMQN5RC5zecFrq+S2eUXxguruP97xUSfUtaR7dFeu4nP+FrQgJ1 +QDZQ/Wwe3oq599X4aQz9WGU1ZKLKxR6zqqBLQiIA49jntOhpSDdCVWAkSJrYQp7Z +zys8nrH8Lzldtf7jckTkAFA= -----END CERTIFICATE----- Certificate: @@ -196,30 +197,30 @@ Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: - 00:cc:3f:3d:39:6a:1a:de:64:b7:11:19:82:b6:ed: - b9:47:d8:67:22:83:07:f7:a1:de:70:05:e1:83:f2: - 06:8d:ea:b0:19:95:27:f4:19:c8:b9:53:91:35:0a: - 50:2c:26:7c:77:9f:fb:d5:36:19:f3:91:67:8d:2a: - ea:0c:81:ab:f6:dd:8a:32:e9:e9:71:71:57:ea:3c: - 5f:e8:b8:9b:60:6a:7d:2a:8c:54:66:ad:5a:b5:e0: - c0:0e:a1:0b:2f:00:b3:f9:e3:82:16:4f:8c:a9:4c: - 89:72:88:ba:2c:60:04:29:09:7c:bc:9e:d4:81:62: - 22:ed:3d:2f:00:5a:71:7d:db:87:54:83:8d:43:49: - db:6d:53:59:36:81:d4:ef:8f:e6:fa:d8:9b:a2:f0: - e6:1c:32:26:8c:f6:d5:57:4e:bb:dc:6e:f4:fd:24: - b4:3a:75:91:3b:9d:72:78:1f:06:7d:05:88:72:eb: - d7:4a:d1:22:97:19:90:90:d8:e0:d5:03:4c:be:8e: - 04:9b:b0:4d:8d:1b:dd:96:91:7e:90:16:7b:5d:32: - 3d:f5:c3:a9:1c:62:07:17:55:56:4b:08:75:5b:fc: - 11:57:39:52:81:08:2e:31:b3:ee:7c:38:e0:62:dd: - cc:47:b1:fb:c7:45:47:aa:b7:c6:c1:20:ba:b0:13: - 63:b9 + 00:b4:d2:a3:a5:24:1a:21:0c:58:52:09:77:f1:ab: + 2d:49:cb:b0:e5:e2:3c:12:9a:bd:a8:df:36:37:fe: + be:97:6f:18:b0:8e:51:08:94:c1:8e:3e:8f:f0:ae: + 23:19:5e:0a:eb:5e:02:a1:bb:be:61:83:39:cb:52: + e1:8f:0e:ba:61:c4:4b:53:09:c3:f7:38:a3:95:fc: + 89:86:06:59:bc:0c:b5:e1:a2:d3:6d:d8:84:de:75: + 80:7b:1d:04:04:b0:94:03:07:42:b4:73:52:96:b0: + 68:3c:08:e3:b3:af:e9:29:60:f6:4f:6f:8a:42:fc: + 85:63:f6:18:d6:12:6c:6e:94:eb:c3:c0:60:12:19: + f8:61:d6:47:72:46:1a:cd:ed:6a:0b:65:cc:91:68: + ec:a7:c7:f1:c8:7a:44:5c:1e:e8:8e:2b:ed:50:82: + a2:1d:31:31:be:bd:06:56:52:20:bf:37:25:3d:cf: + 18:7f:87:94:ba:c7:9d:6e:68:7f:96:29:20:b7:dc: + fc:73:d9:26:82:6e:f1:97:c2:48:9d:71:35:5c:3e: + b6:86:69:e5:b5:1a:e9:08:4e:dc:dd:c5:0d:e1:4e: + 08:97:0a:41:1a:39:56:b1:31:02:0f:c2:e2:94:a0: + 3a:e0:d8:77:6e:a9:b6:fe:1d:8e:38:ad:52:e6:de: + 59:e3 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: - 01:34:E7:14:1F:DF:2E:D5:19:18:06:94:60:42:D1:A8:FC:16:E0:61 + 29:13:82:EE:25:10:7F:40:23:D6:A7:1B:28:25:35:8A:E8:B6:AA:28 X509v3 Authority Key Identifier: - keyid:01:34:E7:14:1F:DF:2E:D5:19:18:06:94:60:42:D1:A8:FC:16:E0:61 + keyid:29:13:82:EE:25:10:7F:40:23:D6:A7:1B:28:25:35:8A:E8:B6:AA:28 Authority Information Access: CA Issuers - URI:http://url-for-aia/Root.cer @@ -234,47 +235,47 @@ X509v3 Basic Constraints: critical CA:TRUE Signature Algorithm: sha256WithRSAEncryption - 79:96:30:f1:a6:30:2b:c8:b8:51:8f:17:03:6c:ca:26:30:f8: - 2e:40:ff:ea:d3:3a:b6:80:db:d6:cc:ec:83:75:84:65:47:8b: - fc:0e:b4:13:b2:68:41:2e:ab:83:0d:4a:d0:d1:16:ab:f3:5c: - 80:a0:60:f0:08:c9:b3:56:26:c3:08:d1:37:0c:66:fa:11:ce: - 93:74:d1:ed:a7:5c:34:d4:31:d4:ba:af:81:d4:ca:85:93:27: - cc:c1:8f:97:06:51:61:94:1f:e9:3a:90:e7:39:c8:0e:f0:08: - 97:bd:ff:b4:2d:b6:20:9f:78:7b:7c:c0:25:ea:3b:2e:9d:66: - 84:f9:2a:f3:7e:54:20:1c:d9:fa:5f:0c:4a:c1:ea:36:8c:ae: - 43:c5:26:b6:99:f4:bd:2d:da:ff:96:f3:a9:1d:03:4a:50:44: - 2a:0c:bb:42:fb:b2:e4:44:f5:c2:06:1a:10:e7:cb:32:d6:40: - b9:eb:85:d1:79:0e:f5:6a:1b:2b:fe:3e:01:c6:2d:a5:e4:bd: - b0:46:76:a3:50:07:42:9d:18:76:3f:c2:29:1b:03:94:c2:d1: - 14:4d:47:cd:44:63:e0:d4:30:b9:e5:05:03:88:ca:a5:a8:0e: - 01:15:02:d8:cc:8c:91:87:56:d6:20:00:58:73:db:2e:10:86: - 41:63:5e:35 ------BEGIN TRUSTED_CERTIFICATE----- + 6a:88:6c:4d:9f:ee:e6:a5:ec:19:64:e7:b9:86:03:c5:f0:32: + 92:69:3b:35:03:b8:87:12:db:48:78:5d:44:3b:75:e2:3b:87: + 7d:ef:96:83:93:06:93:fc:17:58:71:3e:c6:b0:8b:5b:13:2b: + c7:97:42:ed:3e:de:4a:96:cd:f1:df:3a:90:96:7f:f1:21:72: + 90:58:9b:77:cc:80:2d:19:5a:b1:6f:d6:dd:c8:fc:b7:32:1d: + 8f:77:d4:5e:f0:9d:e4:05:8a:ae:d9:7c:58:fa:00:6e:9f:f9: + 9a:2e:11:25:8b:28:5c:4b:76:ef:62:4d:ff:55:bc:aa:77:fa: + 87:33:3c:f5:a9:87:b5:d5:7f:e0:ef:51:a5:74:9a:04:5b:e9: + 35:f8:e6:43:d0:82:9a:db:4a:90:df:56:20:1d:31:b1:56:bc: + 73:0b:5e:91:bb:a6:62:37:fc:ba:dd:f7:24:69:54:95:c3:28: + 41:68:21:16:9f:d6:32:b6:17:88:29:52:f6:d3:2b:98:2f:28: + 78:c3:67:b3:76:83:df:a9:86:01:cd:c2:bf:e0:84:61:56:76: + f5:1f:12:d4:d1:fb:9e:c0:1b:22:c8:9e:05:4c:34:3b:93:54: + 1e:0a:db:41:91:9a:07:8d:aa:f8:fd:8d:89:ec:eb:32:b3:10: + 4f:52:53:68 +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE1MDMwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v -dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMw/PTlqGt5ktxEZgrbt -uUfYZyKDB/eh3nAF4YPyBo3qsBmVJ/QZyLlTkTUKUCwmfHef+9U2GfORZ40q6gyB -q/bdijLp6XFxV+o8X+i4m2BqfSqMVGatWrXgwA6hCy8As/njghZPjKlMiXKIuixg -BCkJfLye1IFiIu09LwBacX3bh1SDjUNJ221TWTaB1O+P5vrYm6Lw5hwyJoz21VdO -u9xu9P0ktDp1kTudcngfBn0FiHLr10rRIpcZkJDY4NUDTL6OBJuwTY0b3ZaRfpAW -e10yPfXDqRxiBxdVVksIdVv8EVc5UoEILjGz7nw44GLdzEex+8dFR6q3xsEgurAT -Y7kCAwEAAaOByzCByDAdBgNVHQ4EFgQUATTnFB/fLtUZGAaUYELRqPwW4GEwHwYD -VR0jBBgwFoAUATTnFB/fLtUZGAaUYELRqPwW4GEwNwYIKwYBBQUHAQEEKzApMCcG +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALTSo6UkGiEMWFIJd/Gr +LUnLsOXiPBKavajfNjf+vpdvGLCOUQiUwY4+j/CuIxleCuteAqG7vmGDOctS4Y8O +umHES1MJw/c4o5X8iYYGWbwMteGi023YhN51gHsdBASwlAMHQrRzUpawaDwI47Ov +6Slg9k9vikL8hWP2GNYSbG6U68PAYBIZ+GHWR3JGGs3tagtlzJFo7KfH8ch6RFwe +6I4r7VCCoh0xMb69BlZSIL83JT3PGH+HlLrHnW5of5YpILfc/HPZJoJu8ZfCSJ1x +NVw+toZp5bUa6QhO3N3FDeFOCJcKQRo5VrExAg/C4pSgOuDYd26ptv4djjitUube +WeMCAwEAAaOByzCByDAdBgNVHQ4EFgQUKROC7iUQf0Aj1qcbKCU1iui2qigwHwYD +VR0jBBgwFoAUKROC7iUQf0Aj1qcbKCU1iui2qigwNwYIKwYBBQUHAQEEKzApMCcG CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE -AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQB5ljDxpjAr -yLhRjxcDbMomMPguQP/q0zq2gNvWzOyDdYRlR4v8DrQTsmhBLquDDUrQ0Rar81yA -oGDwCMmzVibDCNE3DGb6Ec6TdNHtp1w01DHUuq+B1MqFkyfMwY+XBlFhlB/pOpDn -OcgO8AiXvf+0LbYgn3h7fMAl6jsunWaE+SrzflQgHNn6XwxKweo2jK5DxSa2mfS9 -Ldr/lvOpHQNKUEQqDLtC+7LkRPXCBhoQ58sy1kC564XReQ71ahsr/j4Bxi2l5L2w -RnajUAdCnRh2P8IpGwOUwtEUTUfNRGPg1DC55QUDiMqlqA4BFQLYzIyRh1bWIABY -c9suEIZBY141 ------END TRUSTED_CERTIFICATE----- +AwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBqiGxNn+7m +pewZZOe5hgPF8DKSaTs1A7iHEttIeF1EO3XiO4d975aDkwaT/BdYcT7GsItbEyvH +l0LtPt5Kls3x3zqQln/xIXKQWJt3zIAtGVqxb9bdyPy3Mh2Pd9Re8J3kBYqu2XxY ++gBun/maLhEliyhcS3bvYk3/Vbyqd/qHMzz1qYe11X/g71GldJoEW+k1+OZD0IKa +20qQ31YgHTGxVrxzC16Ru6ZiN/y63fckaVSVwyhBaCEWn9YytheIKVL20yuYLyh4 +w2ezdoPfqYYBzcK/4IRhVnb1HxLU0fuewBsiyJ4FTDQ7k1QeCttBkZoHjar4/Y2J +7OsysxBPUlNo +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg== -----END TIME----- -----BEGIN VERIFY_RESULT----- -RkFJTA== +U1VDQ0VTUw== -----END VERIFY_RESULT-----
diff --git a/net/data/verify_certificate_chain_unittest/expired-target-notBefore.pem b/net/data/verify_certificate_chain_unittest/expired-target-notBefore.pem index 5f480a7..c14bd359 100644 --- a/net/data/verify_certificate_chain_unittest/expired-target-notBefore.pem +++ b/net/data/verify_certificate_chain_unittest/expired-target-notBefore.pem
@@ -249,7 +249,7 @@ 15:37:70:bd:2e:7c:53:65:db:6f:1d:47:fa:53:56:dd:d0:9f: e7:d5:d5:27:7f:c7:2e:9b:55:c2:70:1f:5e:66:b8:d1:2e:ac: c6:e9:de:aa ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKAhHNEAl4AmTFn+H3Mj @@ -269,7 +269,7 @@ WH4kiDD1Qs8+hspIW4NEsAT6C+Kci1+caHcjeUAplQ1uMr+rtK6KKsryKpKnDbSA Xc6++GgkANkwnN66NdQitd0VN3C9LnxTZdtvHUf6U1bd0J/n1dUnf8cum1XCcB9e ZrjRLqzG6d6q ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAxMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/expired-target.pem b/net/data/verify_certificate_chain_unittest/expired-target.pem index 2919474..51c08336 100644 --- a/net/data/verify_certificate_chain_unittest/expired-target.pem +++ b/net/data/verify_certificate_chain_unittest/expired-target.pem
@@ -249,7 +249,7 @@ a8:76:e9:c6:4b:94:d2:24:f5:aa:80:d2:b6:81:17:c6:7d:7d: 88:36:fe:26:44:cf:36:5a:5e:de:c4:34:da:54:1e:89:1f:d6: 98:9e:3c:f7 ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN+cRQJGOOvUZM2OlWVj @@ -269,7 +269,7 @@ lvlkBXVQsz6w+BV8BlT/NpgqbU8zsHgc074SLVu0NysEG9jOKNucbUnob/ZFdQr7 adxxY83GF4RLihSg70Jqb/KodunGS5TSJPWqgNK2gRfGfX2INv4mRM82Wl7exDTa VB6JH9aYnjz3 ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/generate-basic-constraints-pathlen-0-self-issued.py b/net/data/verify_certificate_chain_unittest/generate-basic-constraints-pathlen-0-self-issued.py index 55f649f..aee8b7d 100755 --- a/net/data/verify_certificate_chain_unittest/generate-basic-constraints-pathlen-0-self-issued.py +++ b/net/data/verify_certificate_chain_unittest/generate-basic-constraints-pathlen-0-self-issued.py
@@ -9,7 +9,7 @@ import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') # Intermediate with pathlen 0 @@ -28,7 +28,7 @@ target = common.create_end_entity_certificate('Target', intermediate2) chain = [target, intermediate2, intermediate1] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) time = common.DEFAULT_TIME verify_result = True
diff --git a/net/data/verify_certificate_chain_unittest/generate-expired-intermediate.py b/net/data/verify_certificate_chain_unittest/generate-expired-intermediate.py index 708d734..6ea0b32 100755 --- a/net/data/verify_certificate_chain_unittest/generate-expired-intermediate.py +++ b/net/data/verify_certificate_chain_unittest/generate-expired-intermediate.py
@@ -8,7 +8,7 @@ import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') root.set_validity_range(common.JANUARY_1_2015_UTC, common.JANUARY_1_2016_UTC) @@ -22,7 +22,7 @@ target.set_validity_range(common.JANUARY_1_2015_UTC, common.JANUARY_1_2016_UTC) chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) # Both the root and target are valid at this time, however the # intermediate certificate is not.
diff --git a/net/data/verify_certificate_chain_unittest/generate-expired-root.py b/net/data/verify_certificate_chain_unittest/generate-expired-root.py index 328edcc..12115a1 100755 --- a/net/data/verify_certificate_chain_unittest/generate-expired-root.py +++ b/net/data/verify_certificate_chain_unittest/generate-expired-root.py
@@ -4,11 +4,12 @@ # found in the LICENSE file. """Certificate chain with 1 intermediate, where the root certificate is expired -(violates validity.notAfter). Verification is expected to fail.""" +(violates validity.notAfter). Verification is expected to succeed as +constraints on trust anchors are not enforced..""" import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') root.set_validity_range(common.JANUARY_1_2015_UTC, common.MARCH_1_2015_UTC) @@ -22,11 +23,12 @@ target.set_validity_range(common.JANUARY_1_2015_UTC, common.JANUARY_1_2016_UTC) chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) # Both the target and intermediate are valid at this time, however the -# root is not. +# root is not. This doesn't matter since the root certificate is +# just a delivery mechanism for the name + SPKI. time = common.MARCH_2_2015_UTC -verify_result = False +verify_result = True common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/net/data/verify_certificate_chain_unittest/generate-expired-target-notBefore.py b/net/data/verify_certificate_chain_unittest/generate-expired-target-notBefore.py index 209154d..510fb95 100755 --- a/net/data/verify_certificate_chain_unittest/generate-expired-target-notBefore.py +++ b/net/data/verify_certificate_chain_unittest/generate-expired-target-notBefore.py
@@ -8,7 +8,7 @@ import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') root.set_validity_range(common.JANUARY_1_2015_UTC, common.JANUARY_1_2016_UTC) @@ -22,7 +22,7 @@ target.set_validity_range(common.MARCH_2_2015_UTC, common.JANUARY_1_2016_UTC) chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) # Both the root and intermediate are valid at this time, however the # target is not.
diff --git a/net/data/verify_certificate_chain_unittest/generate-expired-target.py b/net/data/verify_certificate_chain_unittest/generate-expired-target.py index d75fa5a..d4010941 100755 --- a/net/data/verify_certificate_chain_unittest/generate-expired-target.py +++ b/net/data/verify_certificate_chain_unittest/generate-expired-target.py
@@ -8,7 +8,7 @@ import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') root.set_validity_range(common.JANUARY_1_2015_UTC, common.JANUARY_1_2016_UTC) @@ -22,7 +22,7 @@ target.set_validity_range(common.JANUARY_1_2015_UTC, common.MARCH_1_2015_UTC) chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) # Both the root and intermediate are valid at this time, however the # target is not.
diff --git a/net/data/verify_certificate_chain_unittest/generate-intermediate-basic-constraints-ca-false.py b/net/data/verify_certificate_chain_unittest/generate-intermediate-basic-constraints-ca-false.py index 5d15191..41bfe0a1 100755 --- a/net/data/verify_certificate_chain_unittest/generate-intermediate-basic-constraints-ca-false.py +++ b/net/data/verify_certificate_chain_unittest/generate-intermediate-basic-constraints-ca-false.py
@@ -9,7 +9,7 @@ import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') # Intermediate with incorrect basic constraints. @@ -21,7 +21,7 @@ target = common.create_end_entity_certificate('Target', intermediate) chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) time = common.DEFAULT_TIME verify_result = False
diff --git a/net/data/verify_certificate_chain_unittest/generate-intermediate-basic-constraints-not-critical.py b/net/data/verify_certificate_chain_unittest/generate-intermediate-basic-constraints-not-critical.py index 9a409fc..41b904e 100755 --- a/net/data/verify_certificate_chain_unittest/generate-intermediate-basic-constraints-not-critical.py +++ b/net/data/verify_certificate_chain_unittest/generate-intermediate-basic-constraints-not-critical.py
@@ -10,7 +10,7 @@ import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') # Intermediate with non-critical basic constarints. @@ -21,7 +21,7 @@ target = common.create_end_entity_certificate('Target', intermediate) chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) time = common.DEFAULT_TIME verify_result = True
diff --git a/net/data/verify_certificate_chain_unittest/generate-intermediate-lacks-basic-constraints.py b/net/data/verify_certificate_chain_unittest/generate-intermediate-lacks-basic-constraints.py index db91ff72..9d4e471 100755 --- a/net/data/verify_certificate_chain_unittest/generate-intermediate-lacks-basic-constraints.py +++ b/net/data/verify_certificate_chain_unittest/generate-intermediate-lacks-basic-constraints.py
@@ -9,7 +9,7 @@ import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') # Intermediate that lacks basic constraints. @@ -20,7 +20,7 @@ target = common.create_end_entity_certificate('Target', intermediate) chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) time = common.DEFAULT_TIME verify_result = False
diff --git a/net/data/verify_certificate_chain_unittest/generate-intermediate-lacks-signing-key-usage.py b/net/data/verify_certificate_chain_unittest/generate-intermediate-lacks-signing-key-usage.py index 5a3c5e1..d6f95c30 100755 --- a/net/data/verify_certificate_chain_unittest/generate-intermediate-lacks-signing-key-usage.py +++ b/net/data/verify_certificate_chain_unittest/generate-intermediate-lacks-signing-key-usage.py
@@ -9,7 +9,7 @@ import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') # Intermediate that is missing keyCertSign. @@ -21,7 +21,7 @@ target = common.create_end_entity_certificate('Target', intermediate) chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) time = common.DEFAULT_TIME verify_result = False
diff --git a/net/data/verify_certificate_chain_unittest/generate-intermediate-signed-with-md5.py b/net/data/verify_certificate_chain_unittest/generate-intermediate-signed-with-md5.py index 5dec9d1..31e1fc5 100755 --- a/net/data/verify_certificate_chain_unittest/generate-intermediate-signed-with-md5.py +++ b/net/data/verify_certificate_chain_unittest/generate-intermediate-signed-with-md5.py
@@ -9,7 +9,7 @@ import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') # Intermediate. @@ -20,7 +20,7 @@ target = common.create_end_entity_certificate('Target', intermediate) chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) time = common.DEFAULT_TIME verify_result = False
diff --git a/net/data/verify_certificate_chain_unittest/generate-intermediate-unknown-critical-extension.py b/net/data/verify_certificate_chain_unittest/generate-intermediate-unknown-critical-extension.py index b4bffa1a..ece4d663 100755 --- a/net/data/verify_certificate_chain_unittest/generate-intermediate-unknown-critical-extension.py +++ b/net/data/verify_certificate_chain_unittest/generate-intermediate-unknown-critical-extension.py
@@ -10,7 +10,7 @@ import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') # Intermediate that has an unknown critical extension. @@ -22,7 +22,7 @@ target = common.create_end_entity_certificate('Target', intermediate) chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) time = common.DEFAULT_TIME verify_result = False
diff --git a/net/data/verify_certificate_chain_unittest/generate-intermediate-unknown-non-critical-extension.py b/net/data/verify_certificate_chain_unittest/generate-intermediate-unknown-non-critical-extension.py index b4bbb9e..c84cd4d 100755 --- a/net/data/verify_certificate_chain_unittest/generate-intermediate-unknown-non-critical-extension.py +++ b/net/data/verify_certificate_chain_unittest/generate-intermediate-unknown-non-critical-extension.py
@@ -10,7 +10,7 @@ import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') intermediate = common.create_intermediate_certificate('Intermediate', root) @@ -21,7 +21,7 @@ target = common.create_end_entity_certificate('Target', intermediate) chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) time = common.DEFAULT_TIME verify_result = True
diff --git a/net/data/verify_certificate_chain_unittest/generate-key-rollover.py b/net/data/verify_certificate_chain_unittest/generate-key-rollover.py index 01deacb..2cf67a6 100755 --- a/net/data/verify_certificate_chain_unittest/generate-key-rollover.py +++ b/net/data/verify_certificate_chain_unittest/generate-key-rollover.py
@@ -50,7 +50,7 @@ newroot.set_validity_range(JANUARY_2_2015_UTC, common.JANUARY_1_2016_UTC) # Root with the new key signed by the old key. newrootrollover = common.create_intermediate_certificate('Root', oldroot) -newrootrollover.set_key_path(newroot.get_key_path()) +newrootrollover.set_key(newroot.get_key()) newrootrollover.set_validity_range(JANUARY_2_2015_UTC, common.JANUARY_1_2016_UTC) @@ -62,7 +62,7 @@ # Intermediate signed by newroot. Same key as oldintermediate. newintermediate = common.create_intermediate_certificate('Intermediate', newroot) -newintermediate.set_key_path(oldintermediate.get_key_path()) +newintermediate.set_key(oldintermediate.get_key()) newintermediate.set_validity_range(JANUARY_2_2015_UTC, common.JANUARY_1_2016_UTC) @@ -72,10 +72,10 @@ oldchain = [target, oldintermediate] rolloverchain = [target, newintermediate, newrootrollover] longrolloverchain = [target, newintermediate, newroot, newrootrollover] -oldtrusted = [oldroot] +oldtrusted = common.TrustAnchor(oldroot, constrained=False) newchain = [target, newintermediate] -newtrusted = [newroot] +newtrusted = common.TrustAnchor(newroot, constrained=False) time = common.DEFAULT_TIME verify_result = True
diff --git a/net/data/verify_certificate_chain_unittest/generate-non-self-signed-root.py b/net/data/verify_certificate_chain_unittest/generate-non-self-signed-root.py index 1a64171..e0ce4a8f 100755 --- a/net/data/verify_certificate_chain_unittest/generate-non-self-signed-root.py +++ b/net/data/verify_certificate_chain_unittest/generate-non-self-signed-root.py
@@ -21,7 +21,7 @@ target = common.create_end_entity_certificate('Target', intermediate) chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) time = common.DEFAULT_TIME verify_result = True
diff --git a/net/data/verify_certificate_chain_unittest/generate-target-and-intermediate.py b/net/data/verify_certificate_chain_unittest/generate-target-and-intermediate.py index f198774..c426854 100755 --- a/net/data/verify_certificate_chain_unittest/generate-target-and-intermediate.py +++ b/net/data/verify_certificate_chain_unittest/generate-target-and-intermediate.py
@@ -8,7 +8,7 @@ import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') # Intermediate certificate. @@ -18,7 +18,7 @@ target = common.create_end_entity_certificate('Target', intermediate) chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) time = common.DEFAULT_TIME verify_result = True
diff --git a/net/data/verify_certificate_chain_unittest/generate-target-has-keycertsign-but-not-ca.py b/net/data/verify_certificate_chain_unittest/generate-target-has-keycertsign-but-not-ca.py index bd19047..e6163db 100755 --- a/net/data/verify_certificate_chain_unittest/generate-target-has-keycertsign-but-not-ca.py +++ b/net/data/verify_certificate_chain_unittest/generate-target-has-keycertsign-but-not-ca.py
@@ -10,7 +10,7 @@ import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') # Intermediate certificate. @@ -23,7 +23,7 @@ chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) time = common.DEFAULT_TIME verify_result = False
diff --git a/net/data/verify_certificate_chain_unittest/generate-target-has-pathlen-but-not-ca.py b/net/data/verify_certificate_chain_unittest/generate-target-has-pathlen-but-not-ca.py index 558e98cf..abe6809 100755 --- a/net/data/verify_certificate_chain_unittest/generate-target-has-pathlen-but-not-ca.py +++ b/net/data/verify_certificate_chain_unittest/generate-target-has-pathlen-but-not-ca.py
@@ -9,7 +9,7 @@ import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') # Intermediate certificate. @@ -22,7 +22,7 @@ chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) time = common.DEFAULT_TIME verify_result = False
diff --git a/net/data/verify_certificate_chain_unittest/generate-target-not-end-entity.py b/net/data/verify_certificate_chain_unittest/generate-target-not-end-entity.py index 65423d5d..b54053fa 100755 --- a/net/data/verify_certificate_chain_unittest/generate-target-not-end-entity.py +++ b/net/data/verify_certificate_chain_unittest/generate-target-not-end-entity.py
@@ -9,7 +9,7 @@ import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') # Intermediate certificate. @@ -19,7 +19,7 @@ target = common.create_intermediate_certificate('Target', intermediate) chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) time = common.DEFAULT_TIME verify_result = True
diff --git a/net/data/verify_certificate_chain_unittest/generate-target-signed-by-512bit-rsa.py b/net/data/verify_certificate_chain_unittest/generate-target-signed-by-512bit-rsa.py index e8550d6..cd580d2 100755 --- a/net/data/verify_certificate_chain_unittest/generate-target-signed-by-512bit-rsa.py +++ b/net/data/verify_certificate_chain_unittest/generate-target-signed-by-512bit-rsa.py
@@ -9,18 +9,18 @@ import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') # Intermediate with a very weak key size (512-bit RSA). intermediate = common.create_intermediate_certificate('Intermediate', root) -intermediate.generate_rsa_key(512) +intermediate.set_key(common.generate_rsa_key(512)) # Target certificate. target = common.create_end_entity_certificate('Target', intermediate) chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) time = common.DEFAULT_TIME verify_result = False
diff --git a/net/data/verify_certificate_chain_unittest/generate-target-signed-using-ecdsa.py b/net/data/verify_certificate_chain_unittest/generate-target-signed-using-ecdsa.py index d052c540..2839b61 100755 --- a/net/data/verify_certificate_chain_unittest/generate-target-signed-using-ecdsa.py +++ b/net/data/verify_certificate_chain_unittest/generate-target-signed-using-ecdsa.py
@@ -8,18 +8,18 @@ import common -# Self-signed root certificate (part of trust store), using RSA. +# Self-signed root certificate (used as trust anchor). using RSA. root = common.create_self_signed_root_certificate('Root') # Intermediate using an EC key for the P-384 curve. intermediate = common.create_intermediate_certificate('Intermediate', root) -intermediate.generate_ec_key('secp384r1') +intermediate.set_key(common.generate_ec_key('secp384r1')) # Target certificate contains an RSA key (but is signed using ECDSA). target = common.create_end_entity_certificate('Target', intermediate) chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) time = common.DEFAULT_TIME verify_result = True
diff --git a/net/data/verify_certificate_chain_unittest/generate-target-signed-with-md5.py b/net/data/verify_certificate_chain_unittest/generate-target-signed-with-md5.py index 28a2d83..02c70c6b 100755 --- a/net/data/verify_certificate_chain_unittest/generate-target-signed-with-md5.py +++ b/net/data/verify_certificate_chain_unittest/generate-target-signed-with-md5.py
@@ -8,7 +8,7 @@ import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') # Intermediate. @@ -19,7 +19,7 @@ target.set_signature_hash('md5') chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) time = common.DEFAULT_TIME verify_result = False
diff --git a/net/data/verify_certificate_chain_unittest/generate-target-unknown-critical-extension.py b/net/data/verify_certificate_chain_unittest/generate-target-unknown-critical-extension.py index 4c0e19c..d1a9c68f 100755 --- a/net/data/verify_certificate_chain_unittest/generate-target-unknown-critical-extension.py +++ b/net/data/verify_certificate_chain_unittest/generate-target-unknown-critical-extension.py
@@ -10,7 +10,7 @@ import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') # Intermediate certificate. @@ -22,7 +22,7 @@ 'critical,DER:01:02:03:04') chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) time = common.DEFAULT_TIME verify_result = False
diff --git a/net/data/verify_certificate_chain_unittest/generate-target-wrong-signature.py b/net/data/verify_certificate_chain_unittest/generate-target-wrong-signature.py index d941b18..af15ecc 100755 --- a/net/data/verify_certificate_chain_unittest/generate-target-wrong-signature.py +++ b/net/data/verify_certificate_chain_unittest/generate-target-wrong-signature.py
@@ -9,7 +9,7 @@ import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') # Intermediate certificate to include in the certificate chain. @@ -25,7 +25,7 @@ target = common.create_end_entity_certificate('Target', wrong_intermediate) chain = [target, intermediate] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) time = common.DEFAULT_TIME verify_result = False
diff --git a/net/data/verify_certificate_chain_unittest/generate-unknown-root.py b/net/data/verify_certificate_chain_unittest/generate-unknown-root.py index 523b590..7de9d67a7 100755 --- a/net/data/verify_certificate_chain_unittest/generate-unknown-root.py +++ b/net/data/verify_certificate_chain_unittest/generate-unknown-root.py
@@ -9,7 +9,7 @@ import common -# Self-signed root certificate, which is NOT added to the trust store. +# Self-signed root certificate, which is NOT saved as the trust anchor. root = common.create_self_signed_root_certificate('Root') # Intermediate certificate. @@ -18,8 +18,12 @@ # Target certificate. target = common.create_end_entity_certificate('Target', intermediate) +# Self-signed root certificate, not part of chain, which is saved as trust +# anchor. +bogus_root = common.create_self_signed_root_certificate('BogusRoot') + chain = [target, intermediate] -trusted = [] # Note that this lacks |root| +trusted = common.TrustAnchor(bogus_root, constrained=False) time = common.DEFAULT_TIME verify_result = False
diff --git a/net/data/verify_certificate_chain_unittest/generate-violates-basic-constraints-pathlen-0.py b/net/data/verify_certificate_chain_unittest/generate-violates-basic-constraints-pathlen-0.py index 02599ffb..d9040d8 100755 --- a/net/data/verify_certificate_chain_unittest/generate-violates-basic-constraints-pathlen-0.py +++ b/net/data/verify_certificate_chain_unittest/generate-violates-basic-constraints-pathlen-0.py
@@ -9,7 +9,7 @@ import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') # Intermediate with pathlen 0 @@ -27,7 +27,7 @@ target = common.create_end_entity_certificate('Target', intermediate2) chain = [target, intermediate2, intermediate1] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) time = common.DEFAULT_TIME verify_result = False
diff --git a/net/data/verify_certificate_chain_unittest/generate-violates-pathlen-1-root.py b/net/data/verify_certificate_chain_unittest/generate-violates-pathlen-1-root.py index 149c000..ac52c189 100755 --- a/net/data/verify_certificate_chain_unittest/generate-violates-pathlen-1-root.py +++ b/net/data/verify_certificate_chain_unittest/generate-violates-pathlen-1-root.py
@@ -4,11 +4,12 @@ # found in the LICENSE file. """Certificate chain with 2 intermediates and one end entity certificate. The -root certificate has a pathlen:1 restriction so this is an invalid chain.""" +root certificate has a pathlen:1 restriction. Ordinarily this would be an +invalid chain, however constraints on trust anchors are not validated.""" import common -# Self-signed root certificate (part of trust store). +# Self-signed root certificate (used as trust anchor). root = common.create_self_signed_root_certificate('Root') root.get_extensions().set_property('basicConstraints', 'critical,CA:true,pathlen:1') @@ -24,8 +25,8 @@ target = common.create_end_entity_certificate('Target', intermediate2) chain = [target, intermediate2, intermediate1] -trusted = [root] +trusted = common.TrustAnchor(root, constrained=False) time = common.DEFAULT_TIME -verify_result = False +verify_result = True common.write_test_file(__doc__, chain, trusted, time, verify_result)
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-ca-false.pem b/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-ca-false.pem index a2a73ca9..9be0024 100644 --- a/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-ca-false.pem +++ b/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-ca-false.pem
@@ -250,7 +250,7 @@ 1a:40:e5:e7:fe:d6:d0:a7:df:33:5c:86:1e:e5:4a:64:ff:e8: 8f:1f:9e:3c:d8:a9:a2:d2:0b:c3:53:b7:cf:f6:d1:92:84:be: d9:e6:67:06 ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMQ+MTZP39A2DgZciSzI @@ -270,7 +270,7 @@ LduaW2Bh5p2mrMkkIP/Nt13ujgSSoRA0JkiytjrHmmYu8GTwYWTvKIXJlEZr+8UP ufXvUVphvic5AEwAf4pJFHsaQOXn/tbQp98zXIYe5Upk/+iPH5482Kmi0gvDU7fP 9tGShL7Z5mcG ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-not-critical.pem b/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-not-critical.pem index 60d7b29cb..729a6d17 100644 --- a/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-not-critical.pem +++ b/net/data/verify_certificate_chain_unittest/intermediate-basic-constraints-not-critical.pem
@@ -251,7 +251,7 @@ e4:7a:a4:30:08:12:86:b3:fc:d2:43:0c:b5:50:4b:45:ee:cf: 90:5b:3e:39:47:11:b6:6b:a6:24:fe:02:17:07:7c:06:15:23: 0f:d8:0e:7b ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOJMqQgwPw5q7OyAjgfL @@ -271,7 +271,7 @@ oKGNB7pSMc9eKpjxutxWS7PMEbLRLQrrdaj+9gLYmw9bfhFQsVG5MRHFS/q/NE1G 6Sc5YcoJQbJn/FSKOAtQffDkeqQwCBKGs/zSQwy1UEtF7s+QWz45RxG2a6Yk/gIX B3wGFSMP2A57 ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-lacks-basic-constraints.pem b/net/data/verify_certificate_chain_unittest/intermediate-lacks-basic-constraints.pem index 90276347..bbfa3d97 100644 --- a/net/data/verify_certificate_chain_unittest/intermediate-lacks-basic-constraints.pem +++ b/net/data/verify_certificate_chain_unittest/intermediate-lacks-basic-constraints.pem
@@ -247,7 +247,7 @@ 15:85:1e:ff:b7:2d:04:6c:3b:5b:f9:7f:70:bc:0c:ac:16:b7: d1:b4:f1:74:84:ad:73:e7:9f:c7:c9:ea:93:d9:f1:c6:a7:59: bf:92:4e:ec ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMPa2hCVeFxzyENmQSOO @@ -267,7 +267,7 @@ 80I3ArU980HVfWeXgHia4gZUGLywf113FbuJy00pDAKrs7dARDosSi5UQ3//sF/a xV84Ds5OGO3z+ZnwfAFpyg4VhR7/ty0EbDtb+X9wvAysFrfRtPF0hK1z55/HyeqT 2fHGp1m/kk7s ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-lacks-signing-key-usage.pem b/net/data/verify_certificate_chain_unittest/intermediate-lacks-signing-key-usage.pem index 536c478..495c7090 100644 --- a/net/data/verify_certificate_chain_unittest/intermediate-lacks-signing-key-usage.pem +++ b/net/data/verify_certificate_chain_unittest/intermediate-lacks-signing-key-usage.pem
@@ -250,7 +250,7 @@ bd:35:85:b1:f0:78:6a:99:ac:63:52:08:5b:69:97:55:c0:87: 81:be:bd:09:7f:eb:56:a9:84:9f:f6:9c:df:f2:19:41:60:f1: 06:d1:77:38 ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALMTGfitwP9ehhmaPH8M @@ -270,7 +270,7 @@ Wq2xVtqRgInZYoGZnKRJJHq8kU6rhuYLdg00LXX6exP1s1IiwVd8zXkMK7qLh4NS WVtpVZ3ECpiwsN2Ihowow7K9NYWx8HhqmaxjUghbaZdVwIeBvr0Jf+tWqYSf9pzf 8hlBYPEG0Xc4 ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-signed-with-md5.pem b/net/data/verify_certificate_chain_unittest/intermediate-signed-with-md5.pem index f3104f8..d5bf8f4 100644 --- a/net/data/verify_certificate_chain_unittest/intermediate-signed-with-md5.pem +++ b/net/data/verify_certificate_chain_unittest/intermediate-signed-with-md5.pem
@@ -250,7 +250,7 @@ 82:61:8e:e0:4e:2c:9a:7a:45:e3:21:1c:b8:86:cf:a0:35:1b: bf:55:36:86:05:1c:df:b0:e2:85:3b:a4:c7:7c:69:f9:56:b3: 20:28:e4:c2 ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANPu0I2Sfc5fTvIMVU29 @@ -270,7 +270,7 @@ sNrmBeYS1R4ZPGld2AhevP7fqzakcD8sbByO4/ELsyLkW/2GI3q9m7lWCOOibSvj y0KTb8hfV71mQVGKXUt+DzaCYY7gTiyaekXjIRy4hs+gNRu/VTaGBRzfsOKFO6TH fGn5VrMgKOTC ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-unknown-critical-extension.pem b/net/data/verify_certificate_chain_unittest/intermediate-unknown-critical-extension.pem index 49aa20d..70ee11b 100644 --- a/net/data/verify_certificate_chain_unittest/intermediate-unknown-critical-extension.pem +++ b/net/data/verify_certificate_chain_unittest/intermediate-unknown-critical-extension.pem
@@ -253,7 +253,7 @@ 97:90:a4:ea:d8:aa:c2:b7:08:34:a3:62:23:4b:a5:e3:9e:4d: 90:7f:d7:4c:dc:4f:c8:ac:b2:b6:de:42:fd:05:98:f6:33:90: 54:c3:6a:3f ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOfejW+BrzUtmetitEHY @@ -273,7 +273,7 @@ eeGEaKY9zhkcCmJI2flMkv+3W+gd5GYAUE04yDrj4Y6uqjIwZXgls9DrT96rnVFA fm/UFYfPQX2+PTJFovGofBGXkKTq2KrCtwg0o2IjS6Xjnk2Qf9dM3E/IrLK23kL9 BZj2M5BUw2o/ ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/intermediate-unknown-non-critical-extension.pem b/net/data/verify_certificate_chain_unittest/intermediate-unknown-non-critical-extension.pem index c7892e9..02d3aa46 100644 --- a/net/data/verify_certificate_chain_unittest/intermediate-unknown-non-critical-extension.pem +++ b/net/data/verify_certificate_chain_unittest/intermediate-unknown-non-critical-extension.pem
@@ -253,7 +253,7 @@ 23:1a:82:2d:ff:b6:83:ae:3c:c1:c3:85:5e:49:aa:d6:ef:fd: f4:4a:22:7c:90:b8:46:2e:15:63:93:0c:c5:2d:9e:f6:32:03: 53:10:30:36 ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKODhylVC44KftfTdE9s @@ -273,7 +273,7 @@ xc1gDoAyGQLgjLR25wCh5bwpMWGmVfByknhpbyYIlnG5QqnrzFSO1lUaJiygtabf Uoah3ybaJobVF1vJm5DAbKsjGoIt/7aDrjzBw4VeSarW7/30SiJ8kLhGLhVjkwzF LZ72MgNTEDA2 ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/issuer-and-subject-not-byte-for-byte-equal-anchor.pem b/net/data/verify_certificate_chain_unittest/issuer-and-subject-not-byte-for-byte-equal-anchor.pem index f4c1086..6ecd8bb 100644 --- a/net/data/verify_certificate_chain_unittest/issuer-and-subject-not-byte-for-byte-equal-anchor.pem +++ b/net/data/verify_certificate_chain_unittest/issuer-and-subject-not-byte-for-byte-equal-anchor.pem
@@ -253,7 +253,7 @@ 36:8b:f6:6c:f7:61:b9:08:ee:30:ad:1a:a8:44:f1:2e:32:ec: 83:a2:48:48:3a:67:5f:e9:6f:1b:17:33:08:2a:c1:c9:c3:67: 9a:0e:85:67 ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDijCCAnKgAwIBAgIQRfjg5AHFPnHmvXFtl5xBIzANBgkqhkiG9w0BAQUFADBPMQswCQYDVQQ GEwJLUjEcMBoGA1UEChMTR292ZXJubWVudCBvZiBLb3JlYTENMAsGA1UECxMER1BLSTETMBEGA1 UEAxMKR1BLSVJvb3RDQTAeFw0wNzAzMTUwNjAwMDRaFw0xNzAzMTUwNjAwMDRaME8xCzAJBgNVB @@ -271,7 +271,7 @@ +RkPwOazhbsnWpV5xXZPWYIKT/1DAE5M4fkMkvwd9aVrjLqqq0v+u49yJKTcE19GW9eLxveBtWO oHoDfXCpRcw041Xd8ulwUyxMN00uKuSCiICNov2bPdhuQjuMK0aqETxLjLsg6JISDpnX+lvGxcz CCrBycNnmg6FZw== ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTIwNTAyMDQ1ODU0Wg==
diff --git a/net/data/verify_certificate_chain_unittest/issuer-and-subject-not-byte-for-byte-equal.pem b/net/data/verify_certificate_chain_unittest/issuer-and-subject-not-byte-for-byte-equal.pem index 6310610..1611b2f1 100644 --- a/net/data/verify_certificate_chain_unittest/issuer-and-subject-not-byte-for-byte-equal.pem +++ b/net/data/verify_certificate_chain_unittest/issuer-and-subject-not-byte-for-byte-equal.pem
@@ -423,7 +423,7 @@ e9:b8:c9:66:f4:db:26:f3:3a:a4:74:f2:49:24:5b:c9:b0:d0: 57:c1:fa:3e:7a:e1:97:c9 ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRU wEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHh cNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU @@ -451,7 +451,7 @@ 2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPI vSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0F fB+j564ZfJ ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTMwNTIwMTUxODMzWg==
diff --git a/net/data/verify_certificate_chain_unittest/key-rollover-longrolloverchain.pem b/net/data/verify_certificate_chain_unittest/key-rollover-longrolloverchain.pem index 2e5c267..3d88a4e 100644 --- a/net/data/verify_certificate_chain_unittest/key-rollover-longrolloverchain.pem +++ b/net/data/verify_certificate_chain_unittest/key-rollover-longrolloverchain.pem
@@ -458,7 +458,7 @@ 59:44:05:fc:a5:7e:fe:73:5f:df:b5:0b:48:b5:43:b6:10:9f: 42:2e:8b:65:f6:47:25:27:66:ef:a6:a0:ca:d3:cc:9c:ac:2d: 22:5b:87:5c ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKdnzx31VOmWVLxljLee @@ -478,7 +478,7 @@ q8443cAeL93OtFxJHat64b3pptICZIqplzaJQsKCFOyq3Xe+sdbST4uk/lsGKBwv ToMVHxCpxs6Opsq7LAFqrplZRAX8pX7+c1/ftQtItUO2EJ9CLotl9kclJ2bvpqDK 08ycrC0iW4dc ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/key-rollover-newchain.pem b/net/data/verify_certificate_chain_unittest/key-rollover-newchain.pem index f998214..be31b96 100644 --- a/net/data/verify_certificate_chain_unittest/key-rollover-newchain.pem +++ b/net/data/verify_certificate_chain_unittest/key-rollover-newchain.pem
@@ -280,7 +280,7 @@ f7:48:d8:8a:12:46:c6:6c:ba:31:85:e8:45:07:85:23:37:85: ff:15:de:0b:a8:97:40:60:11:9d:20:a8:fc:53:38:66:ea:9e: d4:1b:9f:34 ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBAzANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMjEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOrMLcSIVAeQ2mLvdyOy @@ -300,7 +300,7 @@ aXHztvdEX6EvYmfwVbCi0dt/WDsQBU/hAJ1FT10euKiDvTO9FAc0I16ZuxY+7t6E llO/KeelUqm2anbbpu5FND/3SNiKEkbGbLoxhehFB4UjN4X/Fd4LqJdAYBGdIKj8 Uzhm6p7UG580 ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/key-rollover-oldchain.pem b/net/data/verify_certificate_chain_unittest/key-rollover-oldchain.pem index 1e51e28..98e7dcc 100644 --- a/net/data/verify_certificate_chain_unittest/key-rollover-oldchain.pem +++ b/net/data/verify_certificate_chain_unittest/key-rollover-oldchain.pem
@@ -280,7 +280,7 @@ 59:44:05:fc:a5:7e:fe:73:5f:df:b5:0b:48:b5:43:b6:10:9f: 42:2e:8b:65:f6:47:25:27:66:ef:a6:a0:ca:d3:cc:9c:ac:2d: 22:5b:87:5c ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKdnzx31VOmWVLxljLee @@ -300,7 +300,7 @@ q8443cAeL93OtFxJHat64b3pptICZIqplzaJQsKCFOyq3Xe+sdbST4uk/lsGKBwv ToMVHxCpxs6Opsq7LAFqrplZRAX8pX7+c1/ftQtItUO2EJ9CLotl9kclJ2bvpqDK 08ycrC0iW4dc ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/key-rollover-rolloverchain.pem b/net/data/verify_certificate_chain_unittest/key-rollover-rolloverchain.pem index d40dad5..dbb8bc5 100644 --- a/net/data/verify_certificate_chain_unittest/key-rollover-rolloverchain.pem +++ b/net/data/verify_certificate_chain_unittest/key-rollover-rolloverchain.pem
@@ -369,7 +369,7 @@ 59:44:05:fc:a5:7e:fe:73:5f:df:b5:0b:48:b5:43:b6:10:9f: 42:2e:8b:65:f6:47:25:27:66:ef:a6:a0:ca:d3:cc:9c:ac:2d: 22:5b:87:5c ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKdnzx31VOmWVLxljLee @@ -389,7 +389,7 @@ q8443cAeL93OtFxJHat64b3pptICZIqplzaJQsKCFOyq3Xe+sdbST4uk/lsGKBwv ToMVHxCpxs6Opsq7LAFqrplZRAX8pX7+c1/ftQtItUO2EJ9CLotl9kclJ2bvpqDK 08ycrC0iW4dc ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/non-self-signed-root.pem b/net/data/verify_certificate_chain_unittest/non-self-signed-root.pem index f80c4c89..b196bab 100644 --- a/net/data/verify_certificate_chain_unittest/non-self-signed-root.pem +++ b/net/data/verify_certificate_chain_unittest/non-self-signed-root.pem
@@ -250,7 +250,7 @@ a0:6f:f8:d2:ec:67:7e:95:4e:f5:eb:d4:64:c5:32:2c:0f:b4: 6c:e4:64:ef:b5:a5:07:cf:f8:b2:f1:c9:67:10:e6:1a:0d:a3: 9c:44:65:6e ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDdzCCAl+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDDApTaGFk b3dSb290MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UE AwwEUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANT6wE/6dVcu @@ -270,7 +270,7 @@ qGIH6wGXAi1plUordyejMOUifZaBybqQIvT+bLyi65aBTBqDT6+eIXdeaIfz6/gQ fTgAm4MMLZ9/uJMjxPSyd8fPHbsS5DDzu1zsghxHvzGTk7Kgb/jS7Gd+lU7169Rk xTIsD7Rs5GTvtaUHz/iy8clnEOYaDaOcRGVu ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/target-and-intermediate.pem b/net/data/verify_certificate_chain_unittest/target-and-intermediate.pem index 89ff641c..e6efbaad 100644 --- a/net/data/verify_certificate_chain_unittest/target-and-intermediate.pem +++ b/net/data/verify_certificate_chain_unittest/target-and-intermediate.pem
@@ -249,7 +249,7 @@ b6:db:58:41:bb:8d:32:e7:5b:4b:74:bf:4c:8d:ec:07:0b:7d: 3c:d6:2f:4d:27:11:31:15:6f:38:0d:ba:2a:53:76:2a:47:e6: 32:52:df:ea ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALoN0lGvDEiUN8/qg4/W @@ -269,7 +269,7 @@ YyFld25q+NF+ocbfSA50DeMDUf/5mJI8+DZ1kF4JbH8/wV5AA3Leq+1vu/73nRSS XGkTus962EvxKQRuvF/JjlK221hBu40y51tLdL9MjewHC3081i9NJxExFW84Dboq U3YqR+YyUt/q ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/target-has-keycertsign-but-not-ca.pem b/net/data/verify_certificate_chain_unittest/target-has-keycertsign-but-not-ca.pem index 2cfe408..5094c15a 100644 --- a/net/data/verify_certificate_chain_unittest/target-has-keycertsign-but-not-ca.pem +++ b/net/data/verify_certificate_chain_unittest/target-has-keycertsign-but-not-ca.pem
@@ -251,7 +251,7 @@ f3:d0:74:8e:ff:6d:24:97:30:cb:b6:e5:6f:cb:6b:c2:27:5e: a5:f1:63:c0:d9:0d:c5:08:7f:86:8c:47:c4:9b:cb:e2:d9:da: 17:51:5b:12 ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM1rjxy2TFSzDffguFqm @@ -271,7 +271,7 @@ 1SCi8O6+taKDkoZd9UD1MtCFNeuvXZsEXSGzNZDoXwpskIXrhjHkiYHGqnNNHj6v QAfxOK4wqy2qbS+yHf/YGC7z0HSO/20klzDLtuVvy2vCJ16l8WPA2Q3FCH+GjEfE m8vi2doXUVsS ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/target-has-pathlen-but-not-ca.pem b/net/data/verify_certificate_chain_unittest/target-has-pathlen-but-not-ca.pem index 0628545..01d93cc 100644 --- a/net/data/verify_certificate_chain_unittest/target-has-pathlen-but-not-ca.pem +++ b/net/data/verify_certificate_chain_unittest/target-has-pathlen-but-not-ca.pem
@@ -252,7 +252,7 @@ ce:a8:92:2b:25:c4:e3:b6:27:f7:d5:dd:e6:fa:cc:91:6c:59: 5e:f5:a4:e2:4f:0b:18:fa:4e:9c:88:66:20:25:af:87:14:01: 27:08:89:6a ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANP6sX8r5P+tEOlUVO9q @@ -272,7 +272,7 @@ RyiAA3cN+VEoKLZTJGb3O1ZsU1hVskl8xBo9oTcpGYqamYR/Y6whhfUCWlocfAqL vIP/gFcuzmLFeVgkEuivpGzOqJIrJcTjtif31d3m+syRbFle9aTiTwsY+k6ciGYg Ja+HFAEnCIlq ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/target-not-end-entity.pem b/net/data/verify_certificate_chain_unittest/target-not-end-entity.pem index ee5a515..6fa64e6 100644 --- a/net/data/verify_certificate_chain_unittest/target-not-end-entity.pem +++ b/net/data/verify_certificate_chain_unittest/target-not-end-entity.pem
@@ -249,7 +249,7 @@ 97:d2:bb:e0:cd:56:0e:b8:0e:f9:4d:d5:dd:a0:4e:ae:46:68: 00:93:d6:fd:ec:85:78:f4:c9:93:96:34:65:cc:f0:72:e7:0e: 00:3d:d0:6b ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMRoEqmIUAT0cJsKHtGD @@ -269,7 +269,7 @@ QjV6taIuhgiLKerp87XNnUaWhseC7WSrdClTHD71aVFbERwNxPABMaYy0mivHVLB xNmintqivRlx+ib1KENq/VyX0rvgzVYOuA75TdXdoE6uRmgAk9b97IV49MmTljRl zPBy5w4APdBr ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/target-signed-by-512bit-rsa.pem b/net/data/verify_certificate_chain_unittest/target-signed-by-512bit-rsa.pem index d55d955a..632d718 100644 --- a/net/data/verify_certificate_chain_unittest/target-signed-by-512bit-rsa.pem +++ b/net/data/verify_certificate_chain_unittest/target-signed-by-512bit-rsa.pem
@@ -217,7 +217,7 @@ cc:53:4d:5b:e9:0a:d6:40:a5:a0:28:99:57:44:5d:d2:7b:bf: 02:38:a3:c4:df:14:a9:c1:b2:ec:15:21:7b:84:a1:a1:56:f8: b9:45:42:cd ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMpeCBe3fMRVOaIcf5dJ @@ -237,7 +237,7 @@ BuJYj3lHeaZZdc+sXeI3bIg/v1cA9fsJU/RfBkJYXnVIln1P3TtF03xhj3UgF6Au HAhLIj83vtdDidpZrHmHHmrMU01b6QrWQKWgKJlXRF3Se78COKPE3xSpwbLsFSF7 hKGhVvi5RULN ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/target-signed-using-ecdsa.pem b/net/data/verify_certificate_chain_unittest/target-signed-using-ecdsa.pem index 620b9cc5..88c6a1cc 100644 --- a/net/data/verify_certificate_chain_unittest/target-signed-using-ecdsa.pem +++ b/net/data/verify_certificate_chain_unittest/target-signed-using-ecdsa.pem
@@ -221,7 +221,7 @@ f8:af:1e:71:d6:55:85:3a:2c:79:17:e3:df:8e:46:8d:39:13: a4:c9:e7:3d:f2:9d:ef:e7:b9:12:6e:e3:76:3f:e7:c6:5c:fe: 1e:af:1b:50 ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN2l2C5Z7aZ0Yjtx1S8M @@ -241,7 +241,7 @@ ppMBVEmvIE9NTd+KTkq6S6hehUaWomRvePnXa+Xb+zlCOhjHCM6TQeM8eAFkNove eJ4TQlJyE/aB3156RQhPDZn4rx5x1lWFOix5F+PfjkaNOROkyec98p3v57kSbuN2 P+fGXP4erxtQ ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/target-signed-with-md5.pem b/net/data/verify_certificate_chain_unittest/target-signed-with-md5.pem index 1e60c4a0..dc87ae6 100644 --- a/net/data/verify_certificate_chain_unittest/target-signed-with-md5.pem +++ b/net/data/verify_certificate_chain_unittest/target-signed-with-md5.pem
@@ -249,7 +249,7 @@ 3d:9f:bd:ed:0b:95:bf:e5:47:8f:da:dd:9d:6b:27:61:bd:49: 15:9c:9d:6b:40:2b:54:5f:3f:56:d5:08:29:6c:46:49:2d:3f: d1:91:ff:f8 ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKf1ve6t/zA35lpoIBoi @@ -269,7 +269,7 @@ BHAV+nnsCaJpqQl49z6E83/6ohGtRXJdnVVY+rHGZ05BtL2IoOJVriY6cng95Kut 94NpJM0iTy4joQUZvVfT6LM9n73tC5W/5UeP2t2daydhvUkVnJ1rQCtUXz9W1Qgp bEZJLT/Rkf/4 ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/target-unknown-critical-extension.pem b/net/data/verify_certificate_chain_unittest/target-unknown-critical-extension.pem index 20ae9b5..dac4c5c9 100644 --- a/net/data/verify_certificate_chain_unittest/target-unknown-critical-extension.pem +++ b/net/data/verify_certificate_chain_unittest/target-unknown-critical-extension.pem
@@ -253,7 +253,7 @@ c6:1f:f2:d9:e6:41:d6:29:4a:a6:3c:ff:80:4f:e6:e8:90:f5: ab:cb:bf:93:3b:90:da:e6:fb:d5:59:c3:9f:ec:91:bf:3e:0a: a3:23:ef:ee ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkJcieL9eS7M+4UHdoR @@ -273,7 +273,7 @@ +PXZO7P91KnkVRsH7tkYd9RojbDOo2D+YCzKtC8Iihka/KNrG7RyKHpjzMzNGK6Z hk1nEkimM/MZzvpapdcNTVDGH/LZ5kHWKUqmPP+AT+bokPWry7+TO5Da5vvVWcOf 7JG/PgqjI+/u ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/target-wrong-signature.pem b/net/data/verify_certificate_chain_unittest/target-wrong-signature.pem index e027308e..1c061d6 100644 --- a/net/data/verify_certificate_chain_unittest/target-wrong-signature.pem +++ b/net/data/verify_certificate_chain_unittest/target-wrong-signature.pem
@@ -250,7 +250,7 @@ ff:1d:88:8d:e1:be:6b:6b:c7:4c:0c:6d:02:d4:33:7a:f5:ea: 29:55:a9:79:94:bc:a3:01:64:4a:99:99:fc:c6:e5:38:a2:8f: 18:cc:e7:1f ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMhRsMPzsV1uSsJBnreI @@ -270,7 +270,7 @@ Yv1CYxA/xK3r7sX9vFcID6MM5YzeqwW1tOnJ0chm4upKsDPlpEciZ3xw6QLgInU1 SjkOLCflKdbS9TnJAzl6NfX/HYiN4b5ra8dMDG0C1DN69eopVal5lLyjAWRKmZn8 xuU4oo8YzOcf ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/unknown-root.pem b/net/data/verify_certificate_chain_unittest/unknown-root.pem index 1900cb05..307abb7 100644 --- a/net/data/verify_certificate_chain_unittest/unknown-root.pem +++ b/net/data/verify_certificate_chain_unittest/unknown-root.pem
@@ -183,6 +183,95 @@ A7KJguKA7jx34k6Fpc9yPyQ= -----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=BogusRoot + Validity + Not Before: Jan 1 12:00:00 2015 GMT + Not After : Jan 1 12:00:00 2016 GMT + Subject: CN=BogusRoot + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:a6:2e:77:a3:0d:0b:86:02:e4:79:46:6d:76:0e: + de:ba:55:19:76:07:90:e5:7a:4b:9a:99:70:f2:91: + f2:28:94:e7:e0:8b:aa:c4:a5:c1:82:36:d8:30:be: + 84:43:45:ae:2a:60:e7:fe:d4:a0:a1:a7:e9:30:56: + d0:c9:5d:f8:5f:86:9c:ba:c9:ad:cc:29:77:15:0c: + e8:7b:78:52:42:ec:69:db:db:38:d6:f5:25:75:50: + 6f:21:a0:9a:b2:4e:3a:33:6c:47:60:b2:a4:e7:ec: + bc:c0:9f:d7:46:1b:bb:82:43:2a:22:6d:fb:65:0d: + b5:cf:48:b9:a6:e3:2b:26:77:32:db:a6:80:b6:a7: + 63:f5:b9:d7:bf:f3:37:bd:2b:88:15:b5:50:06:0c: + c9:6f:05:2b:97:ac:ff:01:d9:9e:55:b8:2d:90:62: + a4:38:d4:d3:19:87:8f:b0:dd:88:4d:ca:19:f3:c9: + 2f:95:22:a8:19:be:98:38:6d:0f:17:65:d7:ee:5b: + 82:73:f8:c5:28:43:76:96:a6:ef:00:9c:5e:d0:9d: + cc:52:dc:c8:6c:d6:4a:8e:2c:5a:c0:9b:e0:b4:1b: + f4:5f:43:84:b7:ad:7d:d1:07:c6:79:16:d8:01:c2: + 73:e7:ad:dc:4c:d4:a5:bc:ab:99:60:6d:18:34:14: + ed:07 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + 60:21:11:AF:90:99:E9:F8:9A:0B:80:16:9C:63:C3:DC:45:08:84:91 + X509v3 Authority Key Identifier: + keyid:60:21:11:AF:90:99:E9:F8:9A:0B:80:16:9C:63:C3:DC:45:08:84:91 + + Authority Information Access: + CA Issuers - URI:http://url-for-aia/BogusRoot.cer + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://url-for-crl/BogusRoot.crl + + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + Signature Algorithm: sha256WithRSAEncryption + 97:aa:1c:16:64:05:60:ea:e0:5b:ae:7e:31:f3:6e:04:07:fe: + ba:34:6d:fd:b3:c9:74:d1:f8:b4:da:c2:97:1e:00:da:05:b6: + 08:de:e3:8e:6e:5e:a9:9b:15:62:41:0b:2f:d2:bc:24:4a:47: + e9:7a:0c:6b:ba:c9:04:7c:82:ea:c5:89:5c:03:6f:8a:e6:a1: + 13:4c:02:1a:5b:2e:ae:48:8b:16:f5:6d:01:89:89:66:29:06: + 40:49:fe:b9:51:19:9e:ea:6d:76:ce:a7:78:7e:72:bf:04:4c: + bf:f6:17:b0:bc:79:3e:67:47:89:ec:d9:07:40:55:6e:5b:7c: + 79:6e:7f:97:e9:1b:d3:df:b6:54:e5:53:44:32:e2:39:17:ea: + 17:be:6c:82:8a:b6:c2:6a:b4:c5:b7:8c:6d:38:34:b4:b8:27: + 66:1f:4f:70:1d:65:77:6c:73:d8:69:24:6f:06:09:d4:f9:a9: + 7a:eb:47:cb:9b:3e:ec:42:89:2e:f4:2b:20:36:f1:fc:70:e2: + 3b:83:0a:e0:3a:04:1e:bf:53:cb:b6:ca:fe:2f:25:d5:c6:aa: + 71:39:a9:8e:25:4a:75:bb:15:fc:29:4f:ba:d6:a9:02:c7:8d: + d8:06:48:aa:6d:0b:34:bd:36:19:ea:87:a9:50:e5:a8:d8:31: + 73:a2:30:44 +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- +MIIDeTCCAmGgAwIBAgIBATANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAlCb2d1 +c1Jvb3QwHhcNMTUwMTAxMTIwMDAwWhcNMTYwMTAxMTIwMDAwWjAUMRIwEAYDVQQD +DAlCb2d1c1Jvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCmLnej +DQuGAuR5Rm12Dt66VRl2B5DlekuamXDykfIolOfgi6rEpcGCNtgwvoRDRa4qYOf+ +1KChp+kwVtDJXfhfhpy6ya3MKXcVDOh7eFJC7Gnb2zjW9SV1UG8hoJqyTjozbEdg +sqTn7LzAn9dGG7uCQyoibftlDbXPSLmm4ysmdzLbpoC2p2P1ude/8ze9K4gVtVAG +DMlvBSuXrP8B2Z5VuC2QYqQ41NMZh4+w3YhNyhnzyS+VIqgZvpg4bQ8XZdfuW4Jz ++MUoQ3aWpu8AnF7QncxS3Mhs1kqOLFrAm+C0G/RfQ4S3rX3RB8Z5FtgBwnPnrdxM +1KW8q5lgbRg0FO0HAgMBAAGjgdUwgdIwHQYDVR0OBBYEFGAhEa+Qmen4mguAFpxj +w9xFCISRMB8GA1UdIwQYMBaAFGAhEa+Qmen4mguAFpxjw9xFCISRMDwGCCsGAQUF +BwEBBDAwLjAsBggrBgEFBQcwAoYgaHR0cDovL3VybC1mb3ItYWlhL0JvZ3VzUm9v +dC5jZXIwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDovL3VybC1mb3ItY3JsL0JvZ3Vz +Um9vdC5jcmwwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI +hvcNAQELBQADggEBAJeqHBZkBWDq4FuufjHzbgQH/ro0bf2zyXTR+LTawpceANoF +tgje445uXqmbFWJBCy/SvCRKR+l6DGu6yQR8gurFiVwDb4rmoRNMAhpbLq5Iixb1 +bQGJiWYpBkBJ/rlRGZ7qbXbOp3h+cr8ETL/2F7C8eT5nR4ns2QdAVW5bfHluf5fp +G9PftlTlU0Qy4jkX6he+bIKKtsJqtMW3jG04NLS4J2YfT3AdZXdsc9hpJG8GCdT5 +qXrrR8ubPuxCiS70KyA28fxw4juDCuA6BB6/U8u2yv4vJdXGqnE5qY4lSnW7Ffwp +T7rWqQLHjdgGSKptCzS9Nhnqh6lQ5ajYMXOiMEQ= +-----END TRUST_ANCHOR_UNCONSTRAINED----- + -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg== -----END TIME-----
diff --git a/net/data/verify_certificate_chain_unittest/violates-basic-constraints-pathlen-0.pem b/net/data/verify_certificate_chain_unittest/violates-basic-constraints-pathlen-0.pem index 04d29bf..b53bd93 100644 --- a/net/data/verify_certificate_chain_unittest/violates-basic-constraints-pathlen-0.pem +++ b/net/data/verify_certificate_chain_unittest/violates-basic-constraints-pathlen-0.pem
@@ -339,7 +339,7 @@ 91:0b:24:9d:3d:77:02:ce:83:b0:73:21:ba:3f:f6:b9:c7:5d: 08:5c:f0:33:8d:de:1e:56:e8:82:2f:5d:e6:8c:0c:ac:77:c7: bf:91:2a:25 ------BEGIN TRUSTED_CERTIFICATE----- +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDZTCCAk2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM2HnfRm+Hdc41ZtyxLc @@ -359,7 +359,7 @@ X9MdnkzFOkeTTabCAPIqeqHwdkha73ccRxBA2NWERRP2XnzSDr3j47E91ZPhxJWh uoQNoBywzba0olIuN8LzMD6RCySdPXcCzoOwcyG6P/a5x10IXPAzjd4eVuiCL13m jAysd8e/kSol ------END TRUSTED_CERTIFICATE----- +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg==
diff --git a/net/data/verify_certificate_chain_unittest/violates-pathlen-1-root.pem b/net/data/verify_certificate_chain_unittest/violates-pathlen-1-root.pem index 62ef9582..912ab567 100644 --- a/net/data/verify_certificate_chain_unittest/violates-pathlen-1-root.pem +++ b/net/data/verify_certificate_chain_unittest/violates-pathlen-1-root.pem
@@ -1,7 +1,8 @@ [Created by: generate-violates-pathlen-1-root.py] Certificate chain with 2 intermediates and one end entity certificate. The -root certificate has a pathlen:1 restriction so this is an invalid chain. +root certificate has a pathlen:1 restriction. Ordinarily this would be an +invalid chain, however constraints on trust anchors are not validated. Certificate: Data: @@ -17,30 +18,30 @@ Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: - 00:cb:62:aa:87:80:66:83:c5:88:0f:18:6f:ba:e4: - 3d:6e:3a:0e:02:40:9a:90:1c:2c:ef:63:5c:28:3a: - 27:79:e7:53:c0:d8:0e:e9:95:ec:ee:19:45:6a:39: - 1f:09:80:db:eb:0c:fc:ec:ff:e1:3d:42:8a:ab:ba: - 6e:43:bf:bc:50:6b:15:da:0d:af:84:f1:7e:8d:b1: - c6:b6:ee:50:2a:73:3f:38:de:46:49:c1:eb:52:4a: - 03:54:0b:67:d7:3b:1d:3d:ae:b5:0d:e1:2b:b5:a1: - 9d:ea:56:aa:13:8b:80:2d:fb:ea:7f:83:15:d5:df: - 09:a7:d5:ab:a8:5f:50:02:e1:82:7d:73:c3:6a:c6: - d9:bc:47:21:cd:d7:00:a2:06:7c:a7:2f:3e:e6:dd: - 35:b0:fe:35:8d:7f:1e:68:ff:15:ee:d0:3f:69:05: - b5:2f:bb:27:bc:3a:9d:29:31:3d:af:29:a6:d6:a7: - 45:0b:b9:f0:4f:a6:b3:13:f7:97:f5:6a:0f:1e:d1: - d8:9c:05:78:2e:b5:b9:de:ab:f4:26:90:93:49:f3: - b1:18:fe:3e:03:74:39:92:dd:7e:17:6d:31:c8:e7: - 3f:a0:d7:13:dc:fe:76:ec:1a:c1:7f:4e:ad:0f:cc: - b3:d4:27:9b:2f:a5:e9:d9:81:ad:f6:ab:da:7f:d4: - 71:69 + 00:c7:02:89:18:09:bc:9f:9c:9a:41:35:a9:5f:f7: + c2:22:3e:b2:39:fe:ba:57:1d:95:2e:dd:65:23:45: + ce:33:77:99:dd:f1:d7:69:0b:fb:a7:0e:89:98:02: + 7a:94:58:7b:61:e6:10:98:69:1a:09:2b:9f:73:3a: + d8:70:18:64:e2:8a:85:87:c5:69:f3:45:1e:70:d8: + c0:5e:23:6c:a6:7d:8f:77:23:8a:5d:74:a0:0b:d5: + 7f:a7:dd:f5:21:2d:02:c2:0f:e0:c8:f8:29:20:f5: + 5e:33:58:2a:38:c8:41:a6:25:66:ac:cf:c4:03:cb: + 03:25:db:e6:65:3d:bd:ab:da:fb:8f:b5:0e:d8:ba: + 3d:14:2b:9b:07:62:13:d4:1c:ea:b1:d5:7d:4d:54: + 04:c0:13:fb:d1:df:c2:36:e3:00:cf:fa:49:0b:44: + 9c:05:80:19:75:02:25:41:3d:e0:e6:cd:87:d8:63: + d7:84:3d:0c:3a:c8:ec:e8:58:22:62:2f:18:e9:ad: + 45:ce:b8:a6:63:c2:65:29:69:1e:21:08:8d:3a:da: + 96:e0:89:27:09:cc:35:e9:f1:f0:d8:f3:61:c5:05: + 3e:b1:d0:00:3c:7e:25:4a:36:e3:1d:b4:95:37:2d: + 44:ac:9e:79:38:67:e7:c7:ac:0c:71:d3:d1:60:86: + 44:09 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: - CA:5D:98:89:E9:73:51:6B:E4:E7:3E:9B:EF:A8:A0:0A:BC:48:07:92 + C6:CC:7E:B5:7C:7A:51:EC:1C:35:E1:CD:3C:A7:FC:06:31:53:CA:06 X509v3 Authority Key Identifier: - keyid:FD:E5:DE:B3:E1:33:73:97:CA:6B:94:1B:A6:4C:98:A0:8A:75:8F:F7 + keyid:48:BF:34:63:E8:E4:FB:87:49:F2:0E:A0:23:38:D2:BE:6A:3D:45:3C Authority Information Access: CA Issuers - URI:http://url-for-aia/Intermediate2.cer @@ -55,42 +56,42 @@ X509v3 Extended Key Usage: TLS Web Server Authentication, TLS Web Client Authentication Signature Algorithm: sha256WithRSAEncryption - 6c:a3:b3:78:4e:dc:a2:d9:f4:d4:37:13:e2:1d:63:41:8c:db: - 37:8a:b5:9c:6f:03:20:b8:56:3f:45:c9:53:e2:d7:07:12:e3: - 4f:70:21:11:af:68:91:67:2c:12:b0:c3:8a:c6:52:24:55:ab: - 4c:37:f3:cc:9c:4f:51:d6:0e:a4:be:c0:a6:4e:7a:8b:a3:db: - ae:3e:d8:36:71:19:f4:34:1e:d8:52:4f:75:fb:47:0e:df:fe: - 67:93:04:5b:88:84:7c:a4:21:aa:2c:3e:84:94:fa:96:5a:93: - 90:32:4f:5a:64:aa:e5:be:b1:38:24:20:a3:8e:f0:5c:96:d0: - da:b3:12:82:00:fb:88:24:51:c5:65:6c:90:64:7f:80:38:32: - 74:bf:6f:a5:5e:88:96:ff:6f:5d:22:44:bc:85:27:b5:06:8e: - db:7b:ab:b1:e0:96:f2:1c:f7:21:36:97:c7:0f:7d:99:b9:ca: - 22:74:5b:b2:70:c7:8a:4e:ae:b8:03:14:f0:ea:ad:4a:4b:97: - d4:b1:33:91:c6:1b:4d:2a:85:03:c9:f2:60:22:47:d8:74:bd: - 97:83:ec:d4:cd:20:48:f6:b2:5e:5a:a8:ed:99:cf:58:d4:02: - 2a:23:3e:9b:b3:21:c1:82:b6:4e:31:01:73:e0:a5:06:e0:b5: - 4d:18:35:9e + 51:8c:f9:c8:cb:cc:14:e3:54:cd:63:1a:f0:1e:0b:a3:6e:60: + 99:68:06:fe:e6:97:f5:68:e7:d8:7a:e1:b1:78:48:3e:03:57: + e4:84:5a:24:08:47:9f:fb:73:1a:7f:76:66:40:5d:ac:2f:f4: + f0:9e:b1:21:b0:15:5f:d1:68:4a:b6:fe:84:23:05:51:7d:d3: + 22:95:81:d0:76:87:29:9c:24:e8:3f:e0:41:a0:bb:57:96:1d: + 7e:92:2d:22:b3:98:67:4c:87:5e:42:f5:c9:08:fb:b9:05:25: + 73:b8:f0:9a:45:62:96:c6:48:b6:fe:ac:6c:42:a4:9e:41:aa: + fd:55:86:8e:4f:85:9e:b7:26:75:e3:79:28:ed:09:8d:63:35: + b5:55:78:13:46:43:17:3d:e8:12:c8:c3:c6:2f:88:f9:ce:b5: + df:af:6d:70:6f:6b:f6:1e:ff:1a:44:84:b6:51:7a:b1:7c:4f: + b4:7a:19:83:4c:85:b8:d0:e7:65:2e:0e:e2:ed:92:33:c4:f9: + cd:35:78:96:d6:8e:06:2c:17:18:0e:bf:be:f0:c5:7f:d3:85: + 71:62:94:83:d8:1b:51:c4:77:37:d3:6a:fd:43:b4:54:44:fe: + f9:da:01:3e:59:d4:7b:a4:26:32:e4:ba:9a:bf:f3:2b:6c:71: + d2:1e:2c:c4 -----BEGIN CERTIFICATE----- MIIDkDCCAnigAwIBAgIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1JbnRl cm1lZGlhdGUyMB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowETEPMA0G -A1UEAwwGVGFyZ2V0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy2Kq -h4Bmg8WIDxhvuuQ9bjoOAkCakBws72NcKDoneedTwNgO6ZXs7hlFajkfCYDb6wz8 -7P/hPUKKq7puQ7+8UGsV2g2vhPF+jbHGtu5QKnM/ON5GScHrUkoDVAtn1zsdPa61 -DeErtaGd6laqE4uALfvqf4MV1d8Jp9WrqF9QAuGCfXPDasbZvEchzdcAogZ8py8+ -5t01sP41jX8eaP8V7tA/aQW1L7snvDqdKTE9rymm1qdFC7nwT6azE/eX9WoPHtHY -nAV4LrW53qv0JpCTSfOxGP4+A3Q5kt1+F20xyOc/oNcT3P527BrBf06tD8yz1Ceb -L6Xp2YGt9qvaf9RxaQIDAQABo4HrMIHoMB0GA1UdDgQWBBTKXZiJ6XNRa+TnPpvv -qKAKvEgHkjAfBgNVHSMEGDAWgBT95d6z4TNzl8prlBumTJiginWP9zBABggrBgEF +A1UEAwwGVGFyZ2V0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxwKJ +GAm8n5yaQTWpX/fCIj6yOf66Vx2VLt1lI0XOM3eZ3fHXaQv7pw6JmAJ6lFh7YeYQ +mGkaCSufczrYcBhk4oqFh8Vp80UecNjAXiNspn2PdyOKXXSgC9V/p931IS0Cwg/g +yPgpIPVeM1gqOMhBpiVmrM/EA8sDJdvmZT29q9r7j7UO2Lo9FCubB2IT1BzqsdV9 +TVQEwBP70d/CNuMAz/pJC0ScBYAZdQIlQT3g5s2H2GPXhD0MOsjs6FgiYi8Y6a1F +zrimY8JlKWkeIQiNOtqW4IknCcw16fHw2PNhxQU+sdAAPH4lSjbjHbSVNy1ErJ55 +OGfnx6wMcdPRYIZECQIDAQABo4HrMIHoMB0GA1UdDgQWBBTGzH61fHpR7Bw14c08 +p/wGMVPKBjAfBgNVHSMEGDAWgBRIvzRj6OT7h0nyDqAjONK+aj1FPDBABggrBgEF BQcBAQQ0MDIwMAYIKwYBBQUHMAKGJGh0dHA6Ly91cmwtZm9yLWFpYS9JbnRlcm1l ZGlhdGUyLmNlcjA1BgNVHR8ELjAsMCqgKKAmhiRodHRwOi8vdXJsLWZvci1jcmwv SW50ZXJtZWRpYXRlMi5jcmwwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsG -AQUFBwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAbKOzeE7cotn01DcT -4h1jQYzbN4q1nG8DILhWP0XJU+LXBxLjT3AhEa9okWcsErDDisZSJFWrTDfzzJxP -UdYOpL7Apk56i6Pbrj7YNnEZ9DQe2FJPdftHDt/+Z5MEW4iEfKQhqiw+hJT6llqT -kDJPWmSq5b6xOCQgo47wXJbQ2rMSggD7iCRRxWVskGR/gDgydL9vpV6Ilv9vXSJE -vIUntQaO23urseCW8hz3ITaXxw99mbnKInRbsnDHik6uuAMU8OqtSkuX1LEzkcYb -TSqFA8nyYCJH2HS9l4Ps1M0gSPayXlqo7ZnPWNQCKiM+m7MhwYK2TjEBc+ClBuC1 -TRg1ng== +AQUFBwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAUYz5yMvMFONUzWMa +8B4Lo25gmWgG/uaX9Wjn2HrhsXhIPgNX5IRaJAhHn/tzGn92ZkBdrC/08J6xIbAV +X9FoSrb+hCMFUX3TIpWB0HaHKZwk6D/gQaC7V5YdfpItIrOYZ0yHXkL1yQj7uQUl +c7jwmkVilsZItv6sbEKknkGq/VWGjk+FnrcmdeN5KO0JjWM1tVV4E0ZDFz3oEsjD +xi+I+c61369tcG9r9h7/GkSEtlF6sXxPtHoZg0yFuNDnZS4O4u2SM8T5zTV4ltaO +BiwXGA6/vvDFf9OFcWKUg9gbUcR3N9Nq/UO0VET++doBPlnUe6QmMuS6mr/zK2xx +0h4sxA== -----END CERTIFICATE----- Certificate: @@ -107,30 +108,30 @@ Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: - 00:cf:d2:9b:08:f9:4a:42:eb:7d:64:c4:af:15:8e: - 1a:df:56:db:70:cd:5f:55:81:80:8b:cc:6e:2e:8a: - ed:cc:3e:cf:73:08:a8:6a:f6:d5:ab:71:ac:8e:dc: - 3f:ab:85:9a:c6:2e:d5:83:98:24:71:1d:81:c5:28: - 05:4a:ed:25:b7:d1:a0:1a:1c:d4:36:65:aa:33:5c: - a1:71:de:de:4e:ff:78:ef:54:1e:2e:6f:55:d2:58: - fc:c4:ef:b7:1d:88:5a:b7:01:25:43:84:9a:f8:20: - af:70:11:76:ec:c9:57:8b:1c:19:eb:fa:25:a4:f6: - 96:cf:b9:4e:6d:ec:a5:f6:92:01:09:ee:ec:b9:84: - 51:58:1c:a8:67:6d:46:9b:87:09:5d:3e:35:d3:d7: - cd:2f:67:96:07:c7:4c:93:df:f9:7b:48:84:3b:4f: - 6b:0d:57:15:69:8b:eb:9c:00:df:6d:59:26:7b:34: - 4c:da:6b:62:5b:16:5b:b5:df:2e:b0:97:90:54:98: - 84:83:07:f0:78:c0:6c:21:8f:5e:96:d1:8c:e7:0b: - ad:c9:be:38:c4:a9:d5:dd:96:6e:fa:3d:e9:de:04: - e0:eb:7a:8f:e7:54:9c:e8:bd:cd:df:42:91:19:2c: - 73:b0:ef:f4:f6:49:fc:ae:9a:88:50:ac:72:a1:84: - 03:75 + 00:9b:46:28:e2:70:56:b6:e1:f2:57:56:40:07:c9: + 66:0f:15:6f:6a:e9:b6:35:a4:f1:a7:17:4c:86:a4: + 8c:b7:74:55:0f:f2:cb:b0:43:11:4a:61:e0:9f:ea: + 8a:2b:c2:75:0f:b6:50:49:bc:ad:5c:3f:6c:92:4c: + 64:dc:50:2e:4d:66:65:eb:ba:9f:17:b7:d1:7e:ff: + 5d:d2:41:1f:9d:37:94:97:e1:f6:22:88:26:e2:8a: + 65:0f:0d:16:1d:b1:cc:df:e4:b1:78:87:f0:c6:f5: + f0:21:c9:f6:69:34:64:4c:cd:5b:27:ad:ee:0b:3d: + e3:ee:7a:6b:35:21:23:2b:6d:a4:82:c1:e0:37:f1: + 46:3c:16:c4:b9:20:29:16:13:14:26:05:41:c7:1e: + 21:e9:57:69:a4:3a:7b:b1:fe:92:c4:72:75:f7:bc: + c0:ef:ba:4a:0c:73:37:c1:48:e2:4d:07:c4:14:da: + ae:26:31:39:06:b8:43:6b:ec:2a:df:c8:db:02:af: + 24:9a:f2:af:28:98:1b:f3:0f:0d:57:2c:a5:c5:80: + ef:71:41:9f:99:16:20:d1:e2:f7:1d:59:1d:84:e2: + 0b:2d:23:f7:2f:05:9e:51:c3:c9:65:84:ba:db:23: + 2e:7e:43:b4:c1:eb:12:63:f4:3c:32:2e:18:dd:4c: + ad:8b Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: - FD:E5:DE:B3:E1:33:73:97:CA:6B:94:1B:A6:4C:98:A0:8A:75:8F:F7 + 48:BF:34:63:E8:E4:FB:87:49:F2:0E:A0:23:38:D2:BE:6A:3D:45:3C X509v3 Authority Key Identifier: - keyid:6A:CF:A7:31:B7:5A:1E:F0:D3:D0:55:74:2A:18:ED:26:B6:46:99:A2 + keyid:87:09:94:1A:5F:B2:4B:AE:02:70:24:A9:73:76:78:FD:C0:0E:DC:56 Authority Information Access: CA Issuers - URI:http://url-for-aia/Intermediate1.cer @@ -145,41 +146,41 @@ X509v3 Basic Constraints: critical CA:TRUE Signature Algorithm: sha256WithRSAEncryption - cb:42:61:28:aa:f4:9b:98:aa:7e:16:fc:c4:8e:58:6c:c4:3d: - 2e:47:9e:bf:ea:f6:61:db:95:30:77:23:c2:ea:21:67:d0:9c: - a5:4d:48:7b:ba:19:f9:9d:e2:f8:28:b0:f9:90:aa:f5:1e:53: - 02:e1:0c:b2:83:89:fe:63:ef:4e:3b:21:51:3d:cd:19:82:43: - c9:a1:fe:2b:ff:e7:ff:a5:19:ad:17:42:22:b8:15:01:80:17: - 1b:83:68:58:33:22:71:e5:03:20:f3:f2:11:b8:9b:93:be:11: - d0:6c:96:53:97:9e:d8:0e:f8:20:91:7d:61:a0:82:98:a2:67: - 06:3a:61:ee:d7:46:f1:02:77:75:28:50:cf:62:15:17:c9:9d: - 5b:ea:e4:1f:00:59:52:ad:66:07:46:34:df:13:3b:32:63:6a: - b5:a4:36:71:bd:e5:fa:85:40:98:3e:0b:1d:65:e6:b6:a0:c5: - b4:1b:3f:06:d4:8e:cf:4b:97:5b:7c:f2:f4:57:ba:89:a9:a9: - d4:b2:b3:7f:70:71:85:ca:8e:dd:3f:3b:5e:64:a7:a2:84:91: - 45:9e:14:4a:7e:02:1c:b0:45:4f:ee:90:8e:1a:d6:27:09:19: - 5d:f1:6c:8a:4b:2d:85:05:0a:83:af:1c:1a:0c:0e:b7:33:d2: - b7:c6:0a:f3 + be:14:33:c3:9f:0f:7b:fa:15:2f:1d:2c:29:52:bc:27:de:b3: + 7a:f5:d2:e4:3a:51:38:97:8f:90:b2:ce:5d:50:88:77:5c:e8: + ae:35:01:68:13:3a:ca:5b:6c:ab:a2:ac:f0:e0:97:37:6f:ff: + 15:d2:4a:f7:ff:80:7c:64:c8:6a:11:c1:02:f0:4b:0e:97:24: + 81:7e:90:a4:38:41:af:8d:0b:eb:0b:24:2b:dc:89:4d:32:d1: + 0b:b1:7c:67:6e:4f:43:bf:e0:63:9b:e8:f4:42:9c:3b:db:7e: + ec:f7:64:82:28:73:8c:a0:2e:73:d2:45:dd:3a:ad:6a:6a:5e: + ae:6d:f3:cd:be:4a:95:5c:d0:0d:87:54:b6:83:40:ed:14:e5: + d7:9d:23:e2:04:d1:6c:a0:2c:0a:ca:42:57:cc:f7:0b:66:4e: + 35:ef:e3:93:5f:87:e9:0e:64:c7:52:c9:22:16:61:f9:ec:f7: + f0:4a:7a:b8:ef:d6:34:d4:6c:3d:b5:a9:6c:0b:f4:19:a8:9b: + 04:d5:04:9f:fc:04:fe:60:7a:14:70:6f:38:92:80:be:8a:a6: + c4:57:a2:40:5d:bc:06:53:83:6d:f3:5f:f5:22:4a:22:10:a2: + 82:00:87:35:77:07:f1:34:81:2f:86:0b:1a:3b:8f:3d:88:0c: + 3a:a0:15:25 -----BEGIN CERTIFICATE----- MIIDiTCCAnGgAwIBAgIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1JbnRl cm1lZGlhdGUxMB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowGDEWMBQG A1UEAwwNSW50ZXJtZWRpYXRlMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAM/Smwj5SkLrfWTErxWOGt9W23DNX1WBgIvMbi6K7cw+z3MIqGr21atxrI7c -P6uFmsYu1YOYJHEdgcUoBUrtJbfRoBoc1DZlqjNcoXHe3k7/eO9UHi5vVdJY/MTv -tx2IWrcBJUOEmvggr3ARduzJV4scGev6JaT2ls+5Tm3spfaSAQnu7LmEUVgcqGdt -RpuHCV0+NdPXzS9nlgfHTJPf+XtIhDtPaw1XFWmL65wA321ZJns0TNprYlsWW7Xf -LrCXkFSYhIMH8HjAbCGPXpbRjOcLrcm+OMSp1d2Wbvo96d4E4Ot6j+dUnOi9zd9C -kRksc7Dv9PZJ/K6aiFCscqGEA3UCAwEAAaOB3TCB2jAdBgNVHQ4EFgQU/eXes+Ez -c5fKa5QbpkyYoIp1j/cwHwYDVR0jBBgwFoAUas+nMbdaHvDT0FV0KhjtJrZGmaIw +ggEBAJtGKOJwVrbh8ldWQAfJZg8Vb2rptjWk8acXTIakjLd0VQ/yy7BDEUph4J/q +iivCdQ+2UEm8rVw/bJJMZNxQLk1mZeu6nxe30X7/XdJBH503lJfh9iKIJuKKZQ8N +Fh2xzN/ksXiH8Mb18CHJ9mk0ZEzNWyet7gs94+56azUhIyttpILB4DfxRjwWxLkg +KRYTFCYFQcceIelXaaQ6e7H+ksRydfe8wO+6SgxzN8FI4k0HxBTariYxOQa4Q2vs +Kt/I2wKvJJryryiYG/MPDVcspcWA73FBn5kWINHi9x1ZHYTiCy0j9y8FnlHDyWWE +utsjLn5DtMHrEmP0PDIuGN1MrYsCAwEAAaOB3TCB2jAdBgNVHQ4EFgQUSL80Y+jk ++4dJ8g6gIzjSvmo9RTwwHwYDVR0jBBgwFoAUhwmUGl+yS64CcCSpc3Z4/cAO3FYw QAYIKwYBBQUHAQEENDAyMDAGCCsGAQUFBzAChiRodHRwOi8vdXJsLWZvci1haWEv SW50ZXJtZWRpYXRlMS5jZXIwNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL3VybC1m b3ItY3JsL0ludGVybWVkaWF0ZTEuY3JsMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB -Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQDLQmEoqvSbmKp+FvzEjlhsxD0u -R56/6vZh25UwdyPC6iFn0JylTUh7uhn5neL4KLD5kKr1HlMC4Qyyg4n+Y+9OOyFR -Pc0ZgkPJof4r/+f/pRmtF0IiuBUBgBcbg2hYMyJx5QMg8/IRuJuTvhHQbJZTl57Y -DvggkX1hoIKYomcGOmHu10bxAnd1KFDPYhUXyZ1b6uQfAFlSrWYHRjTfEzsyY2q1 -pDZxveX6hUCYPgsdZea2oMW0Gz8G1I7PS5dbfPL0V7qJqanUsrN/cHGFyo7dPzte -ZKeihJFFnhRKfgIcsEVP7pCOGtYnCRld8WyKSy2FBQqDrxwaDA63M9K3xgrz +Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQC+FDPDnw97+hUvHSwpUrwn3rN6 +9dLkOlE4l4+Qss5dUIh3XOiuNQFoEzrKW2yroqzw4Jc3b/8V0kr3/4B8ZMhqEcEC +8EsOlySBfpCkOEGvjQvrCyQr3IlNMtELsXxnbk9Dv+Bjm+j0Qpw7237s92SCKHOM +oC5z0kXdOq1qal6ubfPNvkqVXNANh1S2g0DtFOXXnSPiBNFsoCwKykJXzPcLZk41 +7+OTX4fpDmTHUskiFmH57PfwSnq479Y01Gw9talsC/QZqJsE1QSf/AT+YHoUcG84 +koC+iqbEV6JAXbwGU4Nt81/1IkoiEKKCAIc1dwfxNIEvhgsaO489iAw6oBUl -----END CERTIFICATE----- Certificate: @@ -196,30 +197,30 @@ Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: - 00:db:38:a4:dd:a1:12:62:44:8f:17:f5:d0:26:2d: - 52:d6:74:74:29:d1:7c:9d:97:a2:a2:18:10:ff:08: - 38:d8:b1:9b:ff:ff:91:f1:e0:36:31:37:e1:e7:32: - ca:40:12:7a:6a:4f:fa:44:91:40:1f:51:14:85:32: - 9f:16:e1:2d:35:65:5f:3b:a8:6d:a4:e9:eb:51:d0: - 1f:f7:9c:1e:22:82:48:2d:72:82:a3:59:82:f1:02: - 0f:73:ce:1e:92:0d:1c:23:31:a7:4a:80:f1:65:13: - a5:57:2b:ab:16:f4:87:ca:45:79:8e:46:68:4b:97: - 00:b2:98:61:c7:0d:21:47:58:dc:ff:85:4e:46:9e: - 7c:2a:90:a0:8c:22:a2:91:06:51:61:e1:75:7d:66: - a4:4f:7e:12:4b:8b:f1:aa:a5:aa:fb:73:d8:ca:a2: - 2b:c3:ba:3c:b4:03:4c:c8:9a:b6:8e:6d:9d:3f:45: - 2b:35:3c:f7:86:f6:83:1a:b8:0e:41:a8:7f:62:2d: - d7:95:f8:39:f8:7c:bf:e9:2d:3a:1d:7b:16:b4:55: - 46:d4:5c:bb:d1:19:24:97:c3:14:97:94:d4:43:b4: - 94:07:be:12:72:ba:de:60:7a:75:3b:da:df:81:cc: - 55:18:07:85:44:9c:95:da:30:e7:a1:01:e9:2a:85: - 64:07 + 00:cc:c9:7a:84:dc:8e:0c:4b:60:fc:fb:35:ff:5c: + 72:00:1d:25:df:87:50:fa:65:2e:fa:40:a2:c7:9a: + cb:b5:2e:b6:0d:d8:80:6c:54:ef:44:c9:2f:a4:20: + 60:07:c7:0a:f9:0f:62:0c:30:9e:ff:9b:3f:a7:35: + 6a:ab:a3:56:ca:1b:ea:62:90:0f:ef:e3:29:52:dc: + 88:06:a5:65:1f:29:ba:73:11:b5:98:70:dd:88:7f: + 83:a6:0b:4c:da:42:92:e6:08:45:da:f4:54:e0:8d: + 67:6c:97:0b:fd:8c:13:65:81:6a:1b:49:1b:4e:c7: + de:dc:b5:68:1d:14:57:23:98:33:7b:43:a2:bf:da: + bf:ef:e7:58:43:27:d3:d6:a9:45:d0:8d:e7:d7:48: + b1:dc:f1:00:9b:85:8a:66:3e:20:f3:fc:e1:0f:89: + 9f:28:a6:2d:2c:f7:a2:44:e8:47:5a:0a:fa:cd:8e: + 40:2a:75:06:6d:ca:38:89:b6:9d:1f:15:d9:42:36: + 14:7e:2b:c4:e3:d7:03:a6:cf:4c:cb:34:c0:ce:e9: + ad:05:da:8c:73:91:25:d3:23:3e:70:ab:16:e7:fe: + 8b:95:69:f6:4f:98:68:86:04:d6:70:bd:0f:9a:37: + 0b:35:b9:ad:18:27:aa:15:b7:08:d0:54:1e:94:af: + ed:f9 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: - 6A:CF:A7:31:B7:5A:1E:F0:D3:D0:55:74:2A:18:ED:26:B6:46:99:A2 + 87:09:94:1A:5F:B2:4B:AE:02:70:24:A9:73:76:78:FD:C0:0E:DC:56 X509v3 Authority Key Identifier: - keyid:46:4A:98:70:E1:6E:F7:E1:51:0F:EE:4D:43:FA:ED:D8:F3:23:58:BF + keyid:0F:0F:6A:FA:74:D2:B6:49:DD:B5:2E:25:97:97:E3:E0:51:F7:1E:2A Authority Information Access: CA Issuers - URI:http://url-for-aia/Root.cer @@ -234,41 +235,41 @@ X509v3 Basic Constraints: critical CA:TRUE Signature Algorithm: sha256WithRSAEncryption - 97:fe:af:92:37:5a:ea:1f:72:3a:0a:87:37:b2:e1:67:bf:37: - 66:1c:34:85:aa:86:38:36:c2:5e:cf:bb:de:4c:05:06:d8:61: - 96:4e:e7:3a:28:65:fb:1d:ee:c2:ff:e4:93:17:3d:6c:fa:1b: - 04:d0:06:6d:fb:41:3c:81:ff:e5:39:14:d1:37:b1:ad:fa:2f: - c8:fa:ce:7f:7a:85:b1:11:22:7d:24:d4:b8:93:cb:41:75:b2: - 7c:09:cc:af:79:af:e5:a6:49:f6:42:d3:f0:38:47:b7:28:10: - 56:5e:ea:65:09:11:e7:4b:42:66:3f:e5:83:08:19:cf:da:69: - 6a:45:51:c9:d0:93:43:71:2d:94:d4:33:b3:77:2c:a9:9e:76: - b8:49:70:17:ae:80:2e:3b:d0:91:63:28:9e:86:11:88:8e:0b: - c3:10:04:13:87:b0:5e:29:67:e8:03:ba:3d:40:04:3d:df:a5: - 68:34:1d:3f:7e:c8:ff:38:00:4d:da:a1:2f:e6:76:54:26:d7: - 42:11:fa:b0:be:8d:a1:67:95:ec:04:ff:21:db:99:ad:90:50: - cf:38:54:8a:4f:68:ca:e5:aa:00:9d:79:4a:57:ed:58:b0:b1: - bc:0b:31:c2:c6:6b:c5:5b:e0:5f:3e:b3:8c:56:8a:04:9a:45: - 23:3a:e2:dd + db:01:1b:5b:f9:4f:9a:03:74:cb:a6:84:16:ab:ba:bb:63:7d: + 22:94:f5:70:03:dd:6d:fa:53:f2:23:c6:7b:a2:d2:62:96:ba: + 5a:95:f8:c8:a0:1f:f5:37:01:ce:a5:56:ef:19:5e:da:30:3a: + 81:ac:13:37:74:dd:5d:1b:b0:4a:cc:c0:b5:8f:d0:ce:6e:06: + 2b:74:c0:c4:70:fa:3b:90:d1:7b:c3:10:b3:8f:e1:69:42:ec: + 82:5c:09:ad:5b:0e:8d:4a:18:83:ec:f8:82:dc:e9:d8:5c:fa: + cc:f9:c9:6d:cc:b4:db:b0:d8:99:b9:fb:30:d2:28:a0:46:b8: + 77:fc:c2:12:eb:75:52:20:81:85:da:a6:ed:71:49:db:5c:4f: + a5:31:0f:59:c2:73:8d:da:10:be:ec:0c:4a:f8:d4:35:c7:13: + 5c:eb:f3:c8:42:19:d7:22:07:13:ac:71:46:9f:12:73:9e:0d: + 2e:c6:75:2d:fc:00:b4:99:13:e4:35:be:7f:7a:2f:2c:7b:44: + 57:3f:0f:2b:bb:06:25:45:94:2c:2d:af:c0:9f:e2:29:14:61: + 53:9d:ac:89:d2:04:c6:b9:52:a0:21:70:6f:b1:c0:9c:c9:6d: + 07:ab:14:d3:d3:49:05:bb:1e:4d:47:b6:62:6d:a2:35:3c:47: + 3e:32:1c:11 -----BEGIN CERTIFICATE----- MIIDbjCCAlagAwIBAgIBAjANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowGDEWMBQGA1UEAwwNSW50 -ZXJtZWRpYXRlMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANs4pN2h -EmJEjxf10CYtUtZ0dCnRfJ2XoqIYEP8IONixm///kfHgNjE34ecyykASempP+kSR -QB9RFIUynxbhLTVlXzuobaTp61HQH/ecHiKCSC1ygqNZgvECD3POHpINHCMxp0qA -8WUTpVcrqxb0h8pFeY5GaEuXALKYYccNIUdY3P+FTkaefCqQoIwiopEGUWHhdX1m -pE9+EkuL8aqlqvtz2MqiK8O6PLQDTMiato5tnT9FKzU894b2gxq4DkGof2It15X4 -Ofh8v+ktOh17FrRVRtRcu9EZJJfDFJeU1EO0lAe+EnK63mB6dTva34HMVRgHhUSc -ldow56EB6SqFZAcCAwEAAaOByzCByDAdBgNVHQ4EFgQUas+nMbdaHvDT0FV0Khjt -JrZGmaIwHwYDVR0jBBgwFoAURkqYcOFu9+FRD+5NQ/rt2PMjWL8wNwYIKwYBBQUH +ZXJtZWRpYXRlMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMzJeoTc +jgxLYPz7Nf9ccgAdJd+HUPplLvpAoseay7Uutg3YgGxU70TJL6QgYAfHCvkPYgww +nv+bP6c1aqujVsob6mKQD+/jKVLciAalZR8punMRtZhw3Yh/g6YLTNpCkuYIRdr0 +VOCNZ2yXC/2ME2WBahtJG07H3ty1aB0UVyOYM3tDor/av+/nWEMn09apRdCN59dI +sdzxAJuFimY+IPP84Q+JnyimLSz3okToR1oK+s2OQCp1Bm3KOIm2nR8V2UI2FH4r +xOPXA6bPTMs0wM7prQXajHORJdMjPnCrFuf+i5Vp9k+YaIYE1nC9D5o3CzW5rRgn +qhW3CNBUHpSv7fkCAwEAAaOByzCByDAdBgNVHQ4EFgQUhwmUGl+yS64CcCSpc3Z4 +/cAO3FYwHwYDVR0jBBgwFoAUDw9q+nTStkndtS4ll5fj4FH3HiowNwYIKwYBBQUH AQEEKzApMCcGCCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIw LAYDVR0fBCUwIzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4G A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IB -AQCX/q+SN1rqH3I6Coc3suFnvzdmHDSFqoY4NsJez7veTAUG2GGWTuc6KGX7He7C -/+STFz1s+hsE0AZt+0E8gf/lORTRN7Gt+i/I+s5/eoWxESJ9JNS4k8tBdbJ8Ccyv -ea/lpkn2QtPwOEe3KBBWXuplCRHnS0JmP+WDCBnP2mlqRVHJ0JNDcS2U1DOzdyyp -nna4SXAXroAuO9CRYyiehhGIjgvDEAQTh7BeKWfoA7o9QAQ936VoNB0/fsj/OABN -2qEv5nZUJtdCEfqwvo2hZ5XsBP8h25mtkFDPOFSKT2jK5aoAnXlKV+1YsLG8CzHC -xmvFW+BfPrOMVooEmkUjOuLd +AQDbARtb+U+aA3TLpoQWq7q7Y30ilPVwA91t+lPyI8Z7otJilrpalfjIoB/1NwHO +pVbvGV7aMDqBrBM3dN1dG7BKzMC1j9DObgYrdMDEcPo7kNF7wxCzj+FpQuyCXAmt +Ww6NShiD7PiC3OnYXPrM+cltzLTbsNiZufsw0iigRrh3/MIS63VSIIGF2qbtcUnb +XE+lMQ9ZwnON2hC+7AxK+NQ1xxNc6/PIQhnXIgcTrHFGnxJzng0uxnUt/AC0mRPk +Nb5/ei8se0RXPw8ruwYlRZQsLa/An+IpFGFTnayJ0gTGuVKgIXBvscCcyW0HqxTT +00kFux5NR7ZibaI1PEc+MhwR -----END CERTIFICATE----- Certificate: @@ -285,30 +286,30 @@ Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: - 00:ae:d8:f0:4c:e2:aa:62:09:4f:6c:9e:00:49:b4: - b3:65:74:d7:78:f8:8d:42:96:f8:95:0e:58:91:bc: - b5:0c:9e:0c:df:0d:ab:e4:0b:8c:4d:77:24:45:0f: - 02:97:7c:d7:c4:10:41:7f:1f:10:80:46:85:6b:c1: - bb:88:81:fc:af:9e:35:f1:88:62:ff:58:e8:67:13: - a1:0d:10:9c:ea:0e:5d:fa:2c:b3:a2:e4:aa:53:55: - f4:01:1d:f9:bf:05:7e:36:f6:93:df:ce:44:e6:a9: - 8e:2d:93:75:1c:a1:55:18:41:f3:7f:1e:62:76:18: - 3f:0f:ca:5b:d5:0b:49:d1:ff:6a:1c:d5:2f:9d:c9: - 63:b7:1c:b7:03:39:5a:41:c5:b2:19:86:dd:f8:a1: - df:e8:75:4b:91:69:0b:96:83:c7:df:c5:c8:f0:a9: - ea:7c:d3:fe:11:29:39:ca:ce:1e:5e:9a:00:0c:16: - 1d:aa:c4:f0:4f:4f:d8:12:57:06:04:3c:04:e3:89: - d8:fb:71:9f:d5:14:c0:e9:ad:c9:c9:61:7f:00:6a: - e7:3f:c3:fc:99:b7:94:2a:dd:16:d7:f5:7d:77:1d: - de:87:e7:0b:18:fa:35:e6:23:7b:c9:d1:6a:88:20: - bf:ed:ec:2a:2a:e1:65:96:1e:68:15:bd:1b:ae:31: - cf:73 + 00:f1:6d:df:8a:62:88:18:33:0e:b6:95:4d:a7:53: + 82:ad:ec:81:5e:c7:e1:d8:b9:38:a5:eb:3f:8e:d8: + 97:bb:ed:29:77:b2:d6:ac:34:96:a0:cd:a2:33:d8: + 88:49:88:6b:ce:aa:91:02:b9:33:51:52:d5:e7:b6: + ef:55:d3:d6:6a:f3:3f:87:d9:1b:60:b2:e3:b3:78: + be:e2:8c:b4:30:f3:60:75:eb:30:c5:71:51:49:90: + b9:99:5c:2c:78:9e:72:0d:02:3f:16:bb:6d:f7:f7: + 9e:07:d2:b4:47:85:ea:b0:92:3e:b6:8a:41:71:6a: + 4c:f6:ba:6d:60:4f:7c:29:b3:82:1d:04:07:76:32: + bc:25:38:2c:e4:be:29:2d:80:c3:20:62:a3:65:31: + f2:14:93:2d:92:9d:54:8b:96:4e:4d:df:4e:f7:80: + b2:e7:88:fd:06:32:30:3e:64:9d:e4:96:e0:0e:3a: + ea:c3:4f:ca:df:4a:46:22:1f:df:92:bd:24:82:59: + 20:36:95:62:82:92:2e:d9:d7:a7:93:1e:a7:75:fb: + a9:22:a6:98:4d:e6:f2:b4:12:d0:76:0c:b8:a2:fc: + c3:5e:e7:df:fb:c0:b5:90:5b:a8:1a:1d:33:ae:ab: + e3:25:3d:87:b5:58:c6:bc:e4:fa:db:e9:50:67:3f: + ad:ad Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: - 46:4A:98:70:E1:6E:F7:E1:51:0F:EE:4D:43:FA:ED:D8:F3:23:58:BF + 0F:0F:6A:FA:74:D2:B6:49:DD:B5:2E:25:97:97:E3:E0:51:F7:1E:2A X509v3 Authority Key Identifier: - keyid:46:4A:98:70:E1:6E:F7:E1:51:0F:EE:4D:43:FA:ED:D8:F3:23:58:BF + keyid:0F:0F:6A:FA:74:D2:B6:49:DD:B5:2E:25:97:97:E3:E0:51:F7:1E:2A Authority Information Access: CA Issuers - URI:http://url-for-aia/Root.cer @@ -323,47 +324,47 @@ X509v3 Basic Constraints: critical CA:TRUE, pathlen:1 Signature Algorithm: sha256WithRSAEncryption - 75:7f:28:f3:9e:92:a5:65:6a:9a:ed:7f:29:3e:17:88:10:6a: - cc:a7:0d:b7:80:f0:d4:38:d0:f2:ed:a6:51:3e:7f:20:98:f3: - bc:18:ad:c3:3d:83:bb:b4:37:f0:27:68:eb:71:e4:a0:33:f0: - 6b:57:be:f2:9d:f6:45:ac:7b:83:bd:f9:bc:90:6e:38:20:4a: - 69:00:f3:2c:b0:b2:68:a4:14:b8:2d:09:f5:87:63:57:97:0a: - c5:64:41:c4:ab:b3:09:91:4e:ab:c6:b6:0f:1b:d4:86:16:12: - 02:86:3f:c7:4b:46:05:55:28:8b:f8:a5:f1:a3:1a:8c:d0:1c: - b6:83:56:01:9f:fd:68:f6:e1:6d:ff:ce:3a:59:7d:0e:5e:be: - 72:e7:b3:7c:c3:b6:a4:a1:a9:bc:a4:af:60:55:5b:07:51:19: - db:5b:1a:89:b9:ab:bb:cb:7a:ed:33:b1:c7:10:f6:6b:c7:a8: - 93:fb:fb:b7:f0:40:db:22:73:86:7d:da:db:33:a8:f4:e3:fc: - 45:6e:69:49:ba:18:7c:c0:59:75:b9:82:64:ae:8d:db:ae:27: - 03:14:2d:e2:e0:38:d3:af:0c:65:3b:4b:d7:c2:94:d4:9a:4d: - e6:58:31:d8:b6:c0:b1:c7:71:21:3f:a1:bf:84:d1:a1:c0:d9: - 06:47:08:0b ------BEGIN TRUSTED_CERTIFICATE----- + 38:cf:2c:95:d8:1b:14:a6:43:13:ed:9b:a2:9f:54:eb:33:64: + 2b:a6:c0:04:81:23:52:27:f1:17:12:a1:9a:f0:d2:77:dd:06: + 95:90:a5:bb:be:e1:98:f7:f0:11:a3:fc:71:80:c7:d0:72:f3: + d4:dc:3f:36:51:52:66:5f:92:a8:fa:ca:4f:8f:8f:2a:3d:93: + 12:8a:4f:94:69:99:6f:60:0b:86:81:91:00:98:cd:00:37:a7: + c7:60:e9:f4:07:85:5b:db:35:9b:61:bb:b6:aa:ca:a2:af:1c: + a4:e2:f8:0d:2b:84:2a:9f:7f:53:b6:25:31:ff:31:b8:e6:03: + 3c:f3:a1:5c:1a:51:4b:3e:d6:82:c9:24:d2:e8:3c:06:6b:b7: + f9:f5:77:55:67:fd:75:93:1a:d4:07:5d:6c:7c:6a:ed:12:9c: + b5:d6:f2:df:0c:39:a9:05:b9:11:b9:ca:21:31:26:5c:63:ac: + c3:bb:a7:e7:87:82:80:10:3a:32:fb:3a:9a:a8:0d:cf:af:94: + a4:a2:8a:0e:1c:1d:89:05:82:53:b6:86:1d:80:b4:00:de:31: + f1:20:4e:77:65:16:28:70:95:78:6b:d3:2e:e5:30:40:32:d2: + f6:b6:5c:30:de:07:70:5f:87:6b:51:31:85:4b:cf:8c:d9:0e: + 01:9a:12:6c +-----BEGIN TRUST_ANCHOR_UNCONSTRAINED----- MIIDaDCCAlCgAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290 MB4XDTE1MDEwMTEyMDAwMFoXDTE2MDEwMTEyMDAwMFowDzENMAsGA1UEAwwEUm9v -dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK7Y8EziqmIJT2yeAEm0 -s2V013j4jUKW+JUOWJG8tQyeDN8Nq+QLjE13JEUPApd818QQQX8fEIBGhWvBu4iB -/K+eNfGIYv9Y6GcToQ0QnOoOXfoss6LkqlNV9AEd+b8Ffjb2k9/OROapji2TdRyh -VRhB838eYnYYPw/KW9ULSdH/ahzVL53JY7cctwM5WkHFshmG3fih3+h1S5FpC5aD -x9/FyPCp6nzT/hEpOcrOHl6aAAwWHarE8E9P2BJXBgQ8BOOJ2Ptxn9UUwOmtyclh -fwBq5z/D/Jm3lCrdFtf1fXcd3ofnCxj6NeYje8nRaoggv+3sKirhZZYeaBW9G64x -z3MCAwEAAaOBzjCByzAdBgNVHQ4EFgQURkqYcOFu9+FRD+5NQ/rt2PMjWL8wHwYD -VR0jBBgwFoAURkqYcOFu9+FRD+5NQ/rt2PMjWL8wNwYIKwYBBQUHAQEEKzApMCcG +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPFt34piiBgzDraVTadT +gq3sgV7H4di5OKXrP47Yl7vtKXey1qw0lqDNojPYiEmIa86qkQK5M1FS1ee271XT +1mrzP4fZG2Cy47N4vuKMtDDzYHXrMMVxUUmQuZlcLHiecg0CPxa7bff3ngfStEeF +6rCSPraKQXFqTPa6bWBPfCmzgh0EB3YyvCU4LOS+KS2AwyBio2Ux8hSTLZKdVIuW +Tk3fTveAsueI/QYyMD5kneSW4A466sNPyt9KRiIf35K9JIJZIDaVYoKSLtnXp5Me +p3X7qSKmmE3m8rQS0HYMuKL8w17n3/vAtZBbqBodM66r4yU9h7VYxrzk+tvpUGc/ +ra0CAwEAAaOBzjCByzAdBgNVHQ4EFgQUDw9q+nTStkndtS4ll5fj4FH3HiowHwYD +VR0jBBgwFoAUDw9q+nTStkndtS4ll5fj4FH3HiowNwYIKwYBBQUHAQEEKzApMCcG CCsGAQUFBzAChhtodHRwOi8vdXJsLWZvci1haWEvUm9vdC5jZXIwLAYDVR0fBCUw IzAhoB+gHYYbaHR0cDovL3VybC1mb3ItY3JsL1Jvb3QuY3JsMA4GA1UdDwEB/wQE -AwIBBjASBgNVHRMBAf8ECDAGAQH/AgEBMA0GCSqGSIb3DQEBCwUAA4IBAQB1fyjz -npKlZWqa7X8pPheIEGrMpw23gPDUONDy7aZRPn8gmPO8GK3DPYO7tDfwJ2jrceSg -M/BrV77ynfZFrHuDvfm8kG44IEppAPMssLJopBS4LQn1h2NXlwrFZEHEq7MJkU6r -xrYPG9SGFhIChj/HS0YFVSiL+KXxoxqM0By2g1YBn/1o9uFt/846WX0OXr5y57N8 -w7akoam8pK9gVVsHURnbWxqJuau7y3rtM7HHEPZrx6iT+/u38EDbInOGfdrbM6j0 -4/xFbmlJuhh8wFl1uYJkro3bricDFC3i4DjTrwxlO0vXwpTUmk3mWDHYtsCxx3Eh -P6G/hNGhwNkGRwgL ------END TRUSTED_CERTIFICATE----- +AwIBBjASBgNVHRMBAf8ECDAGAQH/AgEBMA0GCSqGSIb3DQEBCwUAA4IBAQA4zyyV +2BsUpkMT7Zuin1TrM2QrpsAEgSNSJ/EXEqGa8NJ33QaVkKW7vuGY9/ARo/xxgMfQ +cvPU3D82UVJmX5Ko+spPj48qPZMSik+UaZlvYAuGgZEAmM0AN6fHYOn0B4Vb2zWb +Ybu2qsqirxyk4vgNK4Qqn39TtiUx/zG45gM886FcGlFLPtaCySTS6DwGa7f59XdV +Z/11kxrUB11sfGrtEpy11vLfDDmpBbkRucohMSZcY6zDu6fnh4KAEDoy+zqaqA3P +r5SkoooOHB2JBYJTtoYdgLQA3jHxIE53ZRYocJV4a9Mu5TBAMtL2tlww3gdwX4dr +UTGFS8+M2Q4BmhJs +-----END TRUST_ANCHOR_UNCONSTRAINED----- -----BEGIN TIME----- MTUwMzAyMTIwMDAwWg== -----END TIME----- -----BEGIN VERIFY_RESULT----- -RkFJTA== +U1VDQ0VTUw== -----END VERIFY_RESULT-----
diff --git a/net/disk_cache/backend_unittest.cc b/net/disk_cache/backend_unittest.cc index 9db8e92..77b6f7c 100644 --- a/net/disk_cache/backend_unittest.cc +++ b/net/disk_cache/backend_unittest.cc
@@ -119,6 +119,7 @@ void BackendTrimInvalidEntry2(); void BackendEnumerations(); void BackendEnumerations2(); + void BackendDoomMidEnumeration(); void BackendInvalidEntryEnumeration(); void BackendFixEnumerators(); void BackendDoomRecent(); @@ -1419,11 +1420,6 @@ BackendEnumerations2(); } -TEST_F(DiskCacheBackendTest, MemoryOnlyEnumerations2) { - SetMemoryOnlyMode(); - BackendEnumerations2(); -} - TEST_F(DiskCacheBackendTest, AppCacheEnumerations2) { SetCacheType(net::APP_CACHE); BackendEnumerations2(); @@ -1434,6 +1430,70 @@ BackendEnumerations2(); } +void DiskCacheBackendTest::BackendDoomMidEnumeration() { + InitCache(); + + const int kNumEntries = 100; + std::set<std::string> keys; + for (int i = 0; i < kNumEntries; i++) { + std::string key = GenerateKey(true); + keys.insert(key); + disk_cache::Entry* entry; + ASSERT_THAT(CreateEntry(key, &entry), IsOk()); + entry->Close(); + } + + disk_cache::Entry* entry; + std::unique_ptr<TestIterator> iter = CreateIterator(); + int count = 0; + while (iter->OpenNextEntry(&entry) == net::OK) { + if (count == 0) { + // Delete a random entry from the cache while in the midst of iteration. + auto key_to_doom = keys.begin(); + while (*key_to_doom == entry->GetKey()) + key_to_doom++; + ASSERT_THAT(DoomEntry(*key_to_doom), IsOk()); + ASSERT_EQ(1u, keys.erase(*key_to_doom)); + } + ASSERT_NE(nullptr, entry); + EXPECT_EQ(1u, keys.erase(entry->GetKey())); + entry->Close(); + count++; + }; + + EXPECT_EQ(kNumEntries - 1, cache_->GetEntryCount()); + EXPECT_EQ(0u, keys.size()); +} + +TEST_F(DiskCacheBackendTest, DoomEnumerations) { + BackendDoomMidEnumeration(); +} + +TEST_F(DiskCacheBackendTest, NewEvictionDoomEnumerations) { + SetNewEviction(); + BackendDoomMidEnumeration(); +} + +TEST_F(DiskCacheBackendTest, MemoryOnlyDoomEnumerations) { + SetMemoryOnlyMode(); + BackendDoomMidEnumeration(); +} + +TEST_F(DiskCacheBackendTest, ShaderCacheDoomEnumerations) { + SetCacheType(net::SHADER_CACHE); + BackendDoomMidEnumeration(); +} + +TEST_F(DiskCacheBackendTest, AppCacheDoomEnumerations) { + SetCacheType(net::APP_CACHE); + BackendDoomMidEnumeration(); +} + +TEST_F(DiskCacheBackendTest, SimpleDoomEnumerations) { + SetSimpleCacheMode(); + BackendDoomMidEnumeration(); +} + // Verify that ReadData calls do not update the LRU cache // when using the SHADER_CACHE type. TEST_F(DiskCacheBackendTest, ShaderCacheEnumerationReadData) {
diff --git a/net/disk_cache/memory/mem_backend_impl.cc b/net/disk_cache/memory/mem_backend_impl.cc index 0ba2d3f..ad9dfed 100644 --- a/net/disk_cache/memory/mem_backend_impl.cc +++ b/net/disk_cache/memory/mem_backend_impl.cc
@@ -9,6 +9,7 @@ #include <utility> #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "base/sys_info.h" #include "net/base/net_errors.h" #include "net/disk_cache/cache_util.h" @@ -208,38 +209,48 @@ class MemBackendImpl::MemIterator final : public Backend::Iterator { public: explicit MemIterator(base::WeakPtr<MemBackendImpl> backend) - : backend_(backend), current_(nullptr) {} + : backend_(backend) {} int OpenNextEntry(Entry** next_entry, const CompletionCallback& callback) override { if (!backend_) return net::ERR_FAILED; - // Iterate using |lru_list_|, from most recently used to least recently - // used, for compatibility with the unit tests that assume this behaviour. - // Consider the last element if we are beginning an iteration, otherwise - // progressively move earlier in the LRU list. - current_ = current_ ? current_->previous() : backend_->lru_list_.tail(); - - // We should never return a child entry so iterate until we hit a parent - // entry. - while (current_ != backend_->lru_list_.end() && - current_->value()->type() != MemEntryImpl::PARENT_ENTRY) { - current_ = current_->previous(); - } - if (current_ == backend_->lru_list_.end()) { - *next_entry = nullptr; - return net::ERR_FAILED; + if (!backend_keys_) { + backend_keys_ = base::MakeUnique<Strings>(backend_->entries_.size()); + for (const auto& iter : backend_->entries_) + backend_keys_->push_back(iter.first); + current_ = backend_keys_->begin(); + } else { + current_++; } - current_->value()->Open(); - *next_entry = current_->value(); - return net::OK; + while (true) { + if (current_ == backend_keys_->end()) { + *next_entry = nullptr; + backend_keys_.reset(); + return net::ERR_FAILED; + } + + const auto& entry_iter = backend_->entries_.find(*current_); + if (entry_iter == backend_->entries_.end()) { + // The key is no longer in the cache, move on to the next key. + current_++; + continue; + } + + entry_iter->second->Open(); + *next_entry = entry_iter->second; + return net::OK; + } } private: + using Strings = std::vector<std::string>; + base::WeakPtr<MemBackendImpl> backend_; - base::LinkNode<MemEntryImpl>* current_; + std::unique_ptr<Strings> backend_keys_; + Strings::iterator current_; }; std::unique_ptr<Backend::Iterator> MemBackendImpl::CreateIterator() {
diff --git a/net/dns/dns_session_unittest.cc b/net/dns/dns_session_unittest.cc index d22a937..1eba413 100644 --- a/net/dns/dns_session_unittest.cc +++ b/net/dns/dns_session_unittest.cc
@@ -194,7 +194,7 @@ } TestClientSocketFactory::~TestClientSocketFactory() { - STLDeleteElements(&data_providers_); + base::STLDeleteElements(&data_providers_); } TEST_F(DnsSessionTest, AllocateFree) {
diff --git a/net/dns/dns_socket_pool.cc b/net/dns/dns_socket_pool.cc index 4017e2a..8a230e6 100644 --- a/net/dns/dns_socket_pool.cc +++ b/net/dns/dns_socket_pool.cc
@@ -176,7 +176,7 @@ unsigned num_servers = pools_.size(); for (unsigned server_index = 0; server_index < num_servers; ++server_index) { SocketVector& pool = pools_[server_index]; - STLDeleteElements(&pool); + base::STLDeleteElements(&pool); } }
diff --git a/net/dns/host_resolver_impl.cc b/net/dns/host_resolver_impl.cc index a599adc..8d3651c 100644 --- a/net/dns/host_resolver_impl.cc +++ b/net/dns/host_resolver_impl.cc
@@ -1895,7 +1895,7 @@ dispatcher_->SetLimitsToZero(); // It's now safe for Jobs to call KillDsnTask on destruction, because // OnJobComplete will not start any new jobs. - STLDeleteValues(&jobs_); + base::STLDeleteValues(&jobs_); NetworkChangeNotifier::RemoveIPAddressObserver(this); NetworkChangeNotifier::RemoveConnectionTypeObserver(this);
diff --git a/net/dns/mdns_client_impl.cc b/net/dns/mdns_client_impl.cc index 346b7bc7..7c24d10 100644 --- a/net/dns/mdns_client_impl.cc +++ b/net/dns/mdns_client_impl.cc
@@ -209,7 +209,7 @@ } MDnsClientImpl::Core::~Core() { - STLDeleteValues(&listeners_); + base::STLDeleteValues(&listeners_); } bool MDnsClientImpl::Core::Init(MDnsSocketFactory* socket_factory) {
diff --git a/net/dns/mojo_host_resolver_impl.cc b/net/dns/mojo_host_resolver_impl.cc index ee01def..e503570 100644 --- a/net/dns/mojo_host_resolver_impl.cc +++ b/net/dns/mojo_host_resolver_impl.cc
@@ -53,7 +53,7 @@ MojoHostResolverImpl::~MojoHostResolverImpl() { DCHECK(thread_checker_.CalledOnValidThread()); - STLDeleteElements(&pending_jobs_); + base::STLDeleteElements(&pending_jobs_); } void MojoHostResolverImpl::Resolve(
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc b/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc index 6389e4b..3b53079 100644 --- a/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc +++ b/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
@@ -229,7 +229,7 @@ ASSERT_STREQ("A", cookies[0]->Name().c_str()); ASSERT_STREQ("B", cookies[0]->Value().c_str()); DestroyStore(); - STLDeleteElements(&cookies); + base::STLDeleteElements(&cookies); // Now corrupt the meta table. { @@ -254,7 +254,7 @@ ASSERT_STREQ("foo.bar", cookies[0]->Domain().c_str()); ASSERT_STREQ("X", cookies[0]->Name().c_str()); ASSERT_STREQ("Y", cookies[0]->Value().c_str()); - STLDeleteElements(&cookies); + base::STLDeleteElements(&cookies); } // Test if data is stored as expected in the SQLite database. @@ -277,7 +277,7 @@ // Now delete the cookie and check persistence again. store_->DeleteCookie(*cookies[0]); DestroyStore(); - STLDeleteElements(&cookies); + base::STLDeleteElements(&cookies); // Reload and check if the cookie has been removed. CreateAndLoad(false, false, &cookies); @@ -346,7 +346,7 @@ db_thread_event_.Signal(); event.Wait(); loaded_event_.Wait(); - STLDeleteElements(&cookies_); + base::STLDeleteElements(&cookies_); DestroyStore(); // Load the store a third time, this time restoring session cookies. The @@ -359,7 +359,7 @@ base::Unretained(this))); loaded_event_.Wait(); ASSERT_EQ(4u, cookies_.size()); - STLDeleteElements(&cookies_); + base::STLDeleteElements(&cookies_); } // Test that priority load of cookies for a specfic domain key could be @@ -409,7 +409,7 @@ it != cookies_.end(); ++it) { cookies_loaded.insert((*it)->Domain().c_str()); } - STLDeleteElements(&cookies_); + base::STLDeleteElements(&cookies_); ASSERT_GT(4U, cookies_loaded.size()); ASSERT_EQ(true, cookies_loaded.find("www.aaa.com") != cookies_loaded.end()); ASSERT_EQ(true, @@ -424,7 +424,7 @@ ASSERT_EQ(4U, cookies_loaded.size()); ASSERT_EQ(cookies_loaded.find("foo.bar") != cookies_loaded.end(), true); ASSERT_EQ(cookies_loaded.find("www.bbb.com") != cookies_loaded.end(), true); - STLDeleteElements(&cookies_); + base::STLDeleteElements(&cookies_); } // Test that we can force the database to be written by calling Flush(). @@ -477,7 +477,7 @@ ASSERT_STREQ("D", cookies[0]->Value().c_str()); ASSERT_EQ(COOKIE_PRIORITY_DEFAULT, cookies[0]->Priority()); - STLDeleteElements(&cookies); + base::STLDeleteElements(&cookies); } // Test loading old session cookies from the disk. @@ -550,7 +550,7 @@ ASSERT_TRUE(it != cookie_map.end()); EXPECT_TRUE(cookie_map[kPersistentName]->IsPersistent()); - STLDeleteElements(&cookies); + base::STLDeleteElements(&cookies); } TEST_F(SQLitePersistentCookieStoreTest, PriorityIsPersistent) { @@ -614,7 +614,7 @@ ASSERT_TRUE(it != cookie_map.end()); EXPECT_EQ(COOKIE_PRIORITY_HIGH, cookie_map[kHighName]->Priority()); - STLDeleteElements(&cookies); + base::STLDeleteElements(&cookies); } TEST_F(SQLitePersistentCookieStoreTest, SameSiteIsPersistent) { @@ -672,7 +672,7 @@ ASSERT_EQ(1u, cookie_map.count(kStrictName)); EXPECT_EQ(CookieSameSite::STRICT_MODE, cookie_map[kStrictName]->SameSite()); - STLDeleteElements(&cookies); + base::STLDeleteElements(&cookies); } TEST_F(SQLitePersistentCookieStoreTest, UpdateToEncryption) { @@ -691,7 +691,7 @@ EXPECT_NE(contents.find("value123XYZ"), std::string::npos); // Create encrypted cookie store and ensure old cookie still reads. - STLDeleteElements(&cookies_); + base::STLDeleteElements(&cookies_); EXPECT_EQ(0U, cookies_.size()); CreateAndLoad(true, false, &cookies); EXPECT_EQ(1U, cookies_.size()); @@ -705,7 +705,7 @@ AddCookie(GURL("http://foo.bar"), "other", "something456ABC", std::string(), "/", base::Time::Now() + base::TimeDelta::FromInternalValue(10)); DestroyStore(); - STLDeleteElements(&cookies_); + base::STLDeleteElements(&cookies_); CreateAndLoad(true, false, &cookies); EXPECT_EQ(2U, cookies_.size()); CanonicalCookie* cookie_name = nullptr; @@ -720,7 +720,7 @@ EXPECT_EQ("encrypted_value123XYZ", cookie_name->Value()); EXPECT_EQ("something456ABC", cookie_other->Value()); DestroyStore(); - STLDeleteElements(&cookies_); + base::STLDeleteElements(&cookies_); // Examine the real record to make sure plaintext version doesn't exist. sql::Connection db; @@ -762,7 +762,7 @@ EXPECT_EQ(contents.find("value123XYZ"), std::string::npos); // Create encrypted cookie store and ensure old cookie still reads. - STLDeleteElements(&cookies_); + base::STLDeleteElements(&cookies_); EXPECT_EQ(0U, cookies_.size()); CreateAndLoad(true, false, &cookies); EXPECT_EQ(1U, cookies_.size()); @@ -777,7 +777,7 @@ AddCookie(GURL("http://foo.bar"), "other", "something456ABC", std::string(), "/", base::Time::Now() + base::TimeDelta::FromInternalValue(10)); DestroyStore(); - STLDeleteElements(&cookies_); + base::STLDeleteElements(&cookies_); CreateAndLoad(true, false, &cookies); EXPECT_EQ(2U, cookies_.size()); CanonicalCookie* cookie_name = nullptr; @@ -792,7 +792,7 @@ EXPECT_EQ("plaintext_value123XYZ", cookie_name->Value()); EXPECT_EQ("something456ABC", cookie_other->Value()); DestroyStore(); - STLDeleteElements(&cookies_); + base::STLDeleteElements(&cookies_); // Verify that "value" is now visible in the file. contents = ReadRawDBContents();
diff --git a/net/http/bidirectional_stream.cc b/net/http/bidirectional_stream.cc index bbac8c0..e9e98a7 100644 --- a/net/http/bidirectional_stream.cc +++ b/net/http/bidirectional_stream.cc
@@ -11,8 +11,8 @@ #include "base/location.h" #include "base/logging.h" #include "base/memory/ptr_util.h" +#include "base/metrics/histogram_macros.h" #include "base/threading/thread_task_runner_handle.h" -#include "base/time/time.h" #include "base/timer/timer.h" #include "base/values.h" #include "net/base/load_flags.h" @@ -126,6 +126,7 @@ } BidirectionalStream::~BidirectionalStream() { + UpdateHistograms(); if (net_log_.IsCapturing()) { net_log_.EndEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_ALIVE); } @@ -144,6 +145,7 @@ int rv = stream_impl_->ReadData(buf, buf_len); if (rv > 0) { + read_end_time_ = base::TimeTicks::Now(); net_log_.AddByteTransferEvent( NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_RECEIVED, rv, buf->data()); } else if (rv == ERR_IO_PENDING) { @@ -220,6 +222,8 @@ NetLog::TYPE_BIDIRECTIONAL_STREAM_READY, NetLog::BoolCallback("request_headers_sent", request_headers_sent)); } + send_start_time_ = base::TimeTicks::Now(); + send_end_time_ = send_start_time_; delegate_->OnStreamReady(request_headers_sent); } @@ -235,6 +239,8 @@ net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_RECV_HEADERS, base::Bind(&NetLogHeadersCallback, &response_headers)); } + read_start_time_ = base::TimeTicks::Now(); + read_end_time_ = read_start_time_; session_->http_stream_factory()->ProcessAlternativeServices( session_, response_info.headers.get(), url::SchemeHostPort(request_info_->url)); @@ -249,6 +255,7 @@ NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_RECEIVED, bytes_read, read_buffer_->data()); } + read_end_time_ = base::TimeTicks::Now(); read_buffer_ = nullptr; delegate_->OnDataRead(bytes_read); } @@ -273,6 +280,7 @@ net_log_.EndEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_SENT_COALESCED); } } + send_end_time_ = base::TimeTicks::Now(); write_buffer_list_.clear(); write_buffer_len_list_.clear(); delegate_->OnDataSent(); @@ -283,6 +291,7 @@ net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_RECV_TRAILERS, base::Bind(&NetLogHeadersCallback, &trailers)); } + read_end_time_ = base::TimeTicks::Now(); delegate_->OnTrailersReceived(trailers); } @@ -306,6 +315,7 @@ BidirectionalStreamImpl* stream) { DCHECK(!stream_impl_); + start_time_ = base::TimeTicks::Now(); stream_request_.reset(); stream_impl_.reset(stream); stream_impl_->Start(request_info_.get(), net_log_, @@ -372,4 +382,41 @@ delegate_->OnFailed(error); } +void BidirectionalStream::UpdateHistograms() { + // If the request failed before response is started, treat the metrics as + // bogus and skip logging. + if (start_time_.is_null() || read_start_time_.is_null() || + read_end_time_.is_null() || send_start_time_.is_null() || + send_end_time_.is_null()) { + return; + } + if (GetProtocol() == kProtoHTTP2) { + UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.HTTP2.TimeToReadStart", + read_start_time_ - start_time_); + UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.HTTP2.TimeToReadEnd", + read_end_time_ - start_time_); + UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.HTTP2.TimeToSendStart", + send_start_time_ - start_time_); + UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.HTTP2.TimeToSendEnd", + send_end_time_ - start_time_); + UMA_HISTOGRAM_COUNTS("Net.BidirectionalStream.HTTP2.ReceivedBytes", + stream_impl_->GetTotalReceivedBytes()); + UMA_HISTOGRAM_COUNTS("Net.BidirectionalStream.HTTP2.SentBytes", + stream_impl_->GetTotalSentBytes()); + } else if (GetProtocol() == kProtoQUIC1SPDY3) { + UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.QUIC.TimeToReadStart", + read_start_time_ - start_time_); + UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.QUIC.TimeToReadEnd", + read_end_time_ - start_time_); + UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.QUIC.TimeToSendStart", + send_start_time_ - start_time_); + UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.QUIC.TimeToSendEnd", + send_end_time_ - start_time_); + UMA_HISTOGRAM_COUNTS("Net.BidirectionalStream.QUIC.ReceivedBytes", + stream_impl_->GetTotalReceivedBytes()); + UMA_HISTOGRAM_COUNTS("Net.BidirectionalStream.QUIC.SentBytes", + stream_impl_->GetTotalSentBytes()); + } +} + } // namespace net
diff --git a/net/http/bidirectional_stream.h b/net/http/bidirectional_stream.h index 0b86870..c7fa97c 100644 --- a/net/http/bidirectional_stream.h +++ b/net/http/bidirectional_stream.h
@@ -13,6 +13,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/time/time.h" #include "net/http/bidirectional_stream_impl.h" #include "net/http/http_stream_factory.h" #include "net/log/net_log.h" @@ -213,6 +214,8 @@ // Helper method to notify delegate if there is an error. void NotifyFailed(int error); + void UpdateHistograms(); + // BidirectionalStreamRequestInfo used when requesting the stream. std::unique_ptr<BidirectionalStreamRequestInfo> request_info_; const BoundNetLog net_log_; @@ -243,6 +246,12 @@ // List of buffer length. std::vector<int> write_buffer_len_list_; + base::TimeTicks start_time_; + base::TimeTicks read_start_time_; + base::TimeTicks read_end_time_; + base::TimeTicks send_start_time_; + base::TimeTicks send_end_time_; + base::WeakPtrFactory<BidirectionalStream> weak_factory_; DISALLOW_COPY_AND_ASSIGN(BidirectionalStream);
diff --git a/net/http/bidirectional_stream_unittest.cc b/net/http/bidirectional_stream_unittest.cc index b7e8666e..52ea0c0 100644 --- a/net/http/bidirectional_stream_unittest.cc +++ b/net/http/bidirectional_stream_unittest.cc
@@ -345,7 +345,7 @@ host_port_pair_(HostPortPair::FromURL(default_url_)), key_(host_port_pair_, ProxyServer::Direct(), PRIVACY_MODE_DISABLED), ssl_data_(SSLSocketDataProvider(ASYNC, OK)) { - ssl_data_.SetNextProto(kProtoHTTP2); + ssl_data_.next_proto = kProtoHTTP2; ssl_data_.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"); net_log_.SetCaptureMode(NetLogCaptureMode::IncludeSocketBytes()); }
diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc index 1422400..daca3b7 100644 --- a/net/http/http_cache.cc +++ b/net/http/http_cache.cc
@@ -342,7 +342,7 @@ DeactivateEntry(entry); } - STLDeleteElements(&doomed_entries_); + base::STLDeleteElements(&doomed_entries_); // Before deleting pending_ops_, we have to make sure that the disk cache is // done with said operations, or it will attempt to use deleted data. @@ -366,7 +366,7 @@ pending_op->callback.Reset(); } - STLDeleteElements(&pending_op->pending_queue); + base::STLDeleteElements(&pending_op->pending_queue); if (delete_pending_op) delete pending_op; }
diff --git a/net/http/http_content_disposition.cc b/net/http/http_content_disposition.cc index 3f7d6b5..05f3e193 100644 --- a/net/http/http_content_disposition.cc +++ b/net/http/http_content_disposition.cc
@@ -6,6 +6,7 @@ #include "base/base64.h" #include "base/logging.h" +#include "base/strings/string_piece.h" #include "base/strings/string_tokenizer.h" #include "base/strings/string_util.h" #include "base/strings/sys_string_conversions.h" @@ -344,33 +345,30 @@ std::string::const_iterator HttpContentDisposition::ConsumeDispositionType( std::string::const_iterator begin, std::string::const_iterator end) { DCHECK(type_ == INLINE); - std::string::const_iterator delimiter = std::find(begin, end, ';'); - - std::string::const_iterator type_begin = begin; - std::string::const_iterator type_end = delimiter; - HttpUtil::TrimLWS(&type_begin, &type_end); + base::StringPiece header(begin, end); + size_t delimiter = header.find(';'); + base::StringPiece type = header.substr(0, delimiter); + type = HttpUtil::TrimLWS(type); // If the disposition-type isn't a valid token the then the // Content-Disposition header is malformed, and we treat the first bytes as // a parameter rather than a disposition-type. - if (!HttpUtil::IsToken(type_begin, type_end)) + if (type.empty() || !HttpUtil::IsToken(type)) return begin; parse_result_flags_ |= HAS_DISPOSITION_TYPE; - DCHECK(std::find(type_begin, type_end, '=') == type_end); + DCHECK(type.find('=') == base::StringPiece::npos); - if (base::LowerCaseEqualsASCII(base::StringPiece(type_begin, type_end), - "inline")) { + if (base::LowerCaseEqualsASCII(type, "inline")) { type_ = INLINE; - } else if (base::LowerCaseEqualsASCII(base::StringPiece(type_begin, type_end), - "attachment")) { + } else if (base::LowerCaseEqualsASCII(type, "attachment")) { type_ = ATTACHMENT; } else { parse_result_flags_ |= HAS_UNKNOWN_DISPOSITION_TYPE; type_ = ATTACHMENT; } - return delimiter; + return begin + (type.data() + type.size() - header.data()); } // http://tools.ietf.org/html/rfc6266
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index 8fe401c..fe66a8d 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc
@@ -246,18 +246,18 @@ } HttpNetworkSession::~HttpNetworkSession() { - STLDeleteElements(&response_drainers_); + base::STLDeleteElements(&response_drainers_); spdy_session_pool_.CloseAllSessions(); } void HttpNetworkSession::AddResponseDrainer(HttpResponseBodyDrainer* drainer) { - DCHECK(!ContainsKey(response_drainers_, drainer)); + DCHECK(!base::ContainsKey(response_drainers_, drainer)); response_drainers_.insert(drainer); } void HttpNetworkSession::RemoveResponseDrainer( HttpResponseBodyDrainer* drainer) { - DCHECK(ContainsKey(response_drainers_, drainer)); + DCHECK(base::ContainsKey(response_drainers_, drainer)); response_drainers_.erase(drainer); }
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index d53779d..ada7a37 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc
@@ -458,7 +458,7 @@ proxy_info_ = used_proxy_info; response_.was_npn_negotiated = stream_request_->was_npn_negotiated(); response_.npn_negotiated_protocol = SSLClientSocket::NextProtoToString( - stream_request_->protocol_negotiated()); + stream_request_->negotiated_protocol()); response_.was_fetched_via_spdy = stream_request_->using_spdy(); response_.was_fetched_via_proxy = !proxy_info_.is_direct(); if (response_.was_fetched_via_proxy && !proxy_info_.is_empty())
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 07f0c23..df7938a 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc
@@ -330,8 +330,7 @@ BoundTestNetLog log; session_deps_.net_log = log.bound().net_log(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); for (size_t i = 0; i < data_count; ++i) { session_deps_.socket_factory->AddSocketDataProvider(data[i]); @@ -340,22 +339,22 @@ TestCompletionCallback callback; EXPECT_TRUE(log.bound().IsCapturing()); - int rv = trans->Start(&request, callback.callback(), log.bound()); + int rv = trans.Start(&request, callback.callback(), log.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); out.rv = callback.WaitForResult(); - out.total_received_bytes = trans->GetTotalReceivedBytes(); - out.total_sent_bytes = trans->GetTotalSentBytes(); + out.total_received_bytes = trans.GetTotalReceivedBytes(); + out.total_sent_bytes = trans.GetTotalSentBytes(); // Even in the failure cases that use this function, connections are always // successfully established before the error. - EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&out.load_timing_info)); TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); if (out.rv != OK) return out; - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); // Can't use ASSERT_* inside helper functions like this, so // return an error. if (!response || !response->headers) { @@ -368,11 +367,11 @@ EXPECT_EQ(80, response->socket_address.port()); bool got_endpoint = - trans->GetRemoteEndpoint(&out.remote_endpoint_after_start); + trans.GetRemoteEndpoint(&out.remote_endpoint_after_start); EXPECT_EQ(got_endpoint, out.remote_endpoint_after_start.address().size() > 0); - rv = ReadTransaction(trans.get(), &out.response_data); + rv = ReadTransaction(&trans, &out.response_data); EXPECT_THAT(rv, IsOk()); TestNetLogEntry::List entries; @@ -390,7 +389,7 @@ EXPECT_EQ("GET / HTTP/1.1\r\n", line); HttpRequestHeaders request_headers; - EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); + EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers)); std::string value; EXPECT_TRUE(request_headers.GetHeader("Host", &value)); EXPECT_EQ("www.example.org", value); @@ -402,11 +401,11 @@ EXPECT_EQ("['Host: www.example.org','Connection: keep-alive']", response_headers); - out.total_received_bytes = trans->GetTotalReceivedBytes(); + out.total_received_bytes = trans.GetTotalReceivedBytes(); // The total number of sent bytes should not have changed. - EXPECT_EQ(out.total_sent_bytes, trans->GetTotalSentBytes()); + EXPECT_EQ(out.total_sent_bytes, trans.GetTotalSentBytes()); - trans->GetConnectionAttempts(&out.connection_attempts); + trans.GetConnectionAttempts(&out.connection_attempts); return out; } @@ -673,8 +672,7 @@ TEST_F(HttpNetworkTransactionTest, Basic) { std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); } TEST_F(HttpNetworkTransactionTest, SimpleGET) { @@ -982,20 +980,19 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); session_deps_.socket_factory->AddSocketDataProvider(&data); TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine()); @@ -1028,10 +1025,9 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); BeforeHeadersSentHandler headers_handler; - trans->SetBeforeHeadersSentCallback( + trans.SetBeforeHeadersSentCallback( base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent, base::Unretained(&headers_handler))); @@ -1054,13 +1050,13 @@ TestCompletionCallback callback1; - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); // Check that the headers got parsed. @@ -1081,7 +1077,7 @@ // Reading should give EOF right away, since there is no message body // (despite non-zero content-length). std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("", response_data); } @@ -1109,18 +1105,17 @@ request.url = GURL("http://www.example.org/"); request.load_flags = 0; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers); @@ -1128,7 +1123,7 @@ EXPECT_TRUE(response->proxy_server.IsEmpty()); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); EXPECT_EQ(kExpectedResponseData[i], response_data); } @@ -1147,8 +1142,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockRead data_reads[] = { MockRead("HTTP/1.0 100 Continue\r\n\r\n"), @@ -1161,20 +1155,20 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers); EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("hello world", response_data); } @@ -1189,8 +1183,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockRead data_reads[] = { MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n" @@ -1203,20 +1196,20 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers); EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("hello world", response_data); } @@ -1228,8 +1221,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockRead data_reads[] = { MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"), @@ -1240,14 +1232,14 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("", response_data); } @@ -1259,8 +1251,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockRead data_reads[] = { MockRead(ASYNC, 0), @@ -1270,7 +1261,7 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -1334,17 +1325,16 @@ for (int i = 0; i < 2; ++i) { TestCompletionCallback callback; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); LoadTimingInfo load_timing_info; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES); if (i == 0) { first_socket_log_id = load_timing_info.socket_log_id; @@ -1353,14 +1343,14 @@ EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id); } - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers); EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); EXPECT_EQ(kExpectedResponseData[i], response_data); } @@ -1382,8 +1372,8 @@ SSLSocketDataProvider ssl1(ASYNC, OK); SSLSocketDataProvider ssl2(ASYNC, OK); if (use_spdy) { - ssl1.SetNextProto(kProtoHTTP2); - ssl2.SetNextProto(kProtoHTTP2); + ssl1.next_proto = kProtoHTTP2; + ssl2.next_proto = kProtoHTTP2; } session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1); session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); @@ -1455,22 +1445,21 @@ // Make the request. TestCompletionCallback callback; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); LoadTimingInfo load_timing_info; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReused( load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers); @@ -1481,7 +1470,7 @@ } std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); EXPECT_EQ(kHttpData, response_data); } @@ -1571,8 +1560,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockRead data_reads[] = { MockRead(ASYNC, ERR_CONNECTION_RESET), @@ -1585,14 +1573,14 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET)); IPEndPoint endpoint; - EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint)); + EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint)); EXPECT_LT(0u, endpoint.address().size()); } @@ -1628,7 +1616,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); MockRead data_reads[] = { @@ -1669,7 +1657,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); MockRead data_reads[] = { @@ -1777,7 +1765,7 @@ for (size_t i = 0; i < kNumUnreadBodies; ++i) { TestCompletionCallback callback; - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); int rv = trans->Start(&request, callback.callback(), BoundNetLog()); @@ -1824,16 +1812,15 @@ EXPECT_EQ(kStatusLines[i], response_lines[i]); TestCompletionCallback callback; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(callback.GetResult(rv), IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("hello", response_data); } @@ -1878,7 +1865,7 @@ request1.method = "HEAD"; request1.url = GURL("http://www.borked.com/"); - std::unique_ptr<HttpTransaction> trans1( + std::unique_ptr<HttpNetworkTransaction> trans1( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); int rv = trans1->Start(&request1, callback.callback(), BoundNetLog()); EXPECT_THAT(callback.GetResult(rv), IsOk()); @@ -1900,7 +1887,7 @@ request2.method = "GET"; request2.url = GURL("http://www.borked.com/foo"); - std::unique_ptr<HttpTransaction> trans2( + std::unique_ptr<HttpNetworkTransaction> trans2( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); EXPECT_THAT(callback.GetResult(rv), IsOk()); @@ -1954,7 +1941,7 @@ request1.method = "GET"; request1.url = GURL("http://www.borked.com/"); - std::unique_ptr<HttpTransaction> trans1( + std::unique_ptr<HttpNetworkTransaction> trans1( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); int rv = trans1->Start(&request1, callback.callback(), BoundNetLog()); EXPECT_THAT(callback.GetResult(rv), IsOk()); @@ -1976,7 +1963,7 @@ request2.method = "GET"; request2.url = GURL("http://www.borked.com/foo"); - std::unique_ptr<HttpTransaction> trans2( + std::unique_ptr<HttpNetworkTransaction> trans2( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); EXPECT_THAT(callback.GetResult(rv), IsOk()); @@ -2030,7 +2017,7 @@ request1.method = "GET"; request1.url = GURL("http://www.borked.com/"); - std::unique_ptr<HttpTransaction> trans1( + std::unique_ptr<HttpNetworkTransaction> trans1( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); int rv = trans1->Start(&request1, callback.callback(), BoundNetLog()); EXPECT_THAT(callback.GetResult(rv), IsOk()); @@ -2052,7 +2039,7 @@ request2.method = "GET"; request2.url = GURL("http://www.borked.com/foo"); - std::unique_ptr<HttpTransaction> trans2( + std::unique_ptr<HttpNetworkTransaction> trans2( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); EXPECT_THAT(callback.GetResult(rv), IsOk()); @@ -2095,7 +2082,7 @@ request1.method = "GET"; request1.url = GURL("http://www.borked.com/"); - std::unique_ptr<HttpTransaction> trans1( + std::unique_ptr<HttpNetworkTransaction> trans1( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); int rv = trans1->Start(&request1, callback.callback(), BoundNetLog()); EXPECT_THAT(callback.GetResult(rv), IsOk()); @@ -2129,8 +2116,7 @@ TestNetLog log; session_deps_.net_log = &log; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes1[] = { MockWrite( @@ -2179,36 +2165,35 @@ TestCompletionCallback callback1; - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); LoadTimingInfo load_timing_info1; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1)); TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES); int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1)); - EXPECT_EQ(writes_size1, trans->GetTotalSentBytes()); + EXPECT_EQ(writes_size1, trans.GetTotalSentBytes()); int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1)); - EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes()); + EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); TestCompletionCallback callback2; - rv = trans->RestartWithAuth( - AuthCredentials(kFoo, kBar), callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback2.WaitForResult(); EXPECT_THAT(rv, IsOk()); LoadTimingInfo load_timing_info2; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2)); TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES); // The load timing after restart should have a new socket ID, and times after // those of the first load timing. @@ -2217,11 +2202,11 @@ EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2)); - EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes()); + EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes()); int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2)); - EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes()); + EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); EXPECT_EQ(100, response->headers->GetContentLength()); @@ -2240,8 +2225,7 @@ session_deps_.net_log = &log; session_deps_.host_resolver.reset(resolver); std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); resolver->rules()->ClearRules(); resolver->rules()->AddRule("www.example.org", "127.0.0.1"); @@ -2290,24 +2274,24 @@ TestCompletionCallback callback1; - EXPECT_EQ(OK, callback1.GetResult(trans->Start(&request, callback1.callback(), - BoundNetLog()))); + EXPECT_EQ(OK, callback1.GetResult(trans.Start(&request, callback1.callback(), + BoundNetLog()))); LoadTimingInfo load_timing_info1; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1)); TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES); int64_t writes_size1 = CountWriteBytes(data_writes1, arraysize(data_writes1)); - EXPECT_EQ(writes_size1, trans->GetTotalSentBytes()); + EXPECT_EQ(writes_size1, trans.GetTotalSentBytes()); int64_t reads_size1 = CountReadBytes(data_reads1, arraysize(data_reads1)); - EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes()); + EXPECT_EQ(reads_size1, trans.GetTotalReceivedBytes()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); IPEndPoint endpoint; - EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint)); + EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint)); ASSERT_FALSE(endpoint.address().empty()); EXPECT_EQ("127.0.0.1:80", endpoint.ToString()); @@ -2316,11 +2300,11 @@ TestCompletionCallback callback2; - EXPECT_EQ(OK, callback2.GetResult(trans->RestartWithAuth( + EXPECT_EQ(OK, callback2.GetResult(trans.RestartWithAuth( AuthCredentials(kFoo, kBar), callback2.callback()))); LoadTimingInfo load_timing_info2; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2)); TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES); // The load timing after restart should have a new socket ID, and times after // those of the first load timing. @@ -2329,16 +2313,16 @@ EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); int64_t writes_size2 = CountWriteBytes(data_writes2, arraysize(data_writes2)); - EXPECT_EQ(writes_size1 + writes_size2, trans->GetTotalSentBytes()); + EXPECT_EQ(writes_size1 + writes_size2, trans.GetTotalSentBytes()); int64_t reads_size2 = CountReadBytes(data_reads2, arraysize(data_reads2)); - EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes()); + EXPECT_EQ(reads_size1 + reads_size2, trans.GetTotalReceivedBytes()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); EXPECT_EQ(100, response->headers->GetContentLength()); - EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint)); + EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint)); ASSERT_FALSE(endpoint.address().empty()); EXPECT_EQ("127.0.0.2:80", endpoint.ToString()); } @@ -2350,8 +2334,7 @@ request.load_flags = LOAD_DO_NOT_SEND_AUTH_DATA; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes[] = { MockWrite( @@ -2374,18 +2357,18 @@ session_deps_.socket_factory->AddSocketDataProvider(&data); TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_EQ(0, rv); int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes)); - EXPECT_EQ(writes_size, trans->GetTotalSentBytes()); + EXPECT_EQ(writes_size, trans.GetTotalSentBytes()); int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads)); - EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes()); + EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); } @@ -2412,7 +2395,7 @@ "Host: www.example.org\r\n" "Connection: keep-alive\r\n\r\n"), - // After calling trans->RestartWithAuth(), this is the request we should + // After calling trans.RestartWithAuth(), this is the request we should // be issuing -- the final header line contains the credentials. MockWrite(ASYNC, 6, "GET / HTTP/1.1\r\n" @@ -2442,27 +2425,26 @@ TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); ASSERT_THAT(callback1.GetResult(rv), IsOk()); LoadTimingInfo load_timing_info1; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info1)); TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); TestCompletionCallback callback2; - rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), - callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), + callback2.callback()); ASSERT_THAT(callback2.GetResult(rv), IsOk()); LoadTimingInfo load_timing_info2; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info2)); TestLoadTimingReused(load_timing_info2); // The load timing after restart should have the same socket ID, and times // those of the first load timing. @@ -2470,18 +2452,18 @@ load_timing_info2.send_start); EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); EXPECT_EQ(5, response->headers->GetContentLength()); std::string response_data; - EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk()); + EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk()); int64_t writes_size = CountWriteBytes(data_writes, arraysize(data_writes)); - EXPECT_EQ(writes_size, trans->GetTotalSentBytes()); + EXPECT_EQ(writes_size, trans.GetTotalSentBytes()); int64_t reads_size = CountReadBytes(data_reads, arraysize(data_reads)); - EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes()); + EXPECT_EQ(reads_size, trans.GetTotalReceivedBytes()); } } @@ -2496,18 +2478,16 @@ std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); MockWrite data_writes1[] = { - MockWrite( - "GET / HTTP/1.1\r\n" - "Host: www.example.org\r\n" - "Connection: keep-alive\r\n\r\n"), + MockWrite("GET / HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Connection: keep-alive\r\n\r\n"), - // After calling trans->RestartWithAuth(), this is the request we should + // After calling trans.RestartWithAuth(), this is the request we should // be issuing -- the final header line contains the credentials. - MockWrite( - "GET / HTTP/1.1\r\n" - "Host: www.example.org\r\n" - "Connection: keep-alive\r\n" - "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), + MockWrite("GET / HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Connection: keep-alive\r\n" + "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), }; MockRead data_reads1[] = { @@ -2536,28 +2516,26 @@ TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); TestCompletionCallback callback2; - rv = trans->RestartWithAuth( - AuthCredentials(kFoo, kBar), callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback2.WaitForResult(); EXPECT_THAT(rv, IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); EXPECT_EQ(5, response->headers->GetContentLength()); @@ -2574,18 +2552,16 @@ std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); MockWrite data_writes1[] = { - MockWrite( - "GET / HTTP/1.1\r\n" - "Host: www.example.org\r\n" - "Connection: keep-alive\r\n\r\n"), + MockWrite("GET / HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Connection: keep-alive\r\n\r\n"), - // After calling trans->RestartWithAuth(), this is the request we should + // After calling trans.RestartWithAuth(), this is the request we should // be issuing -- the final header line contains the credentials. - MockWrite( - "GET / HTTP/1.1\r\n" - "Host: www.example.org\r\n" - "Connection: keep-alive\r\n" - "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), + MockWrite("GET / HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Connection: keep-alive\r\n" + "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), }; // Respond with 5 kb of response body. @@ -2622,28 +2598,26 @@ TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); TestCompletionCallback callback2; - rv = trans->RestartWithAuth( - AuthCredentials(kFoo, kBar), callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback2.WaitForResult(); EXPECT_THAT(rv, IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); EXPECT_EQ(5, response->headers->GetContentLength()); @@ -2684,7 +2658,7 @@ MockRead(SYNCHRONOUS, OK), // The server closes the connection. }; - // After calling trans->RestartWithAuth(), this is the request we should + // After calling trans.RestartWithAuth(), this is the request we should // be issuing -- the final header line contains the credentials. MockWrite data_writes2[] = { MockWrite( @@ -2711,28 +2685,26 @@ TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); TestCompletionCallback callback2; - rv = trans->RestartWithAuth( - AuthCredentials(kFoo, kBar), callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback2.WaitForResult(); EXPECT_THAT(rv, IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); EXPECT_EQ(5, response->headers->GetContentLength()); @@ -2804,7 +2776,7 @@ TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); int rv = trans->Start(&request, callback1.callback(), log.bound()); @@ -2927,7 +2899,7 @@ TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); int rv = trans->Start(&request, callback1.callback(), log.bound()); @@ -3006,8 +2978,7 @@ session_deps_.net_log = log.bound().net_log(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Since we have proxy, should try to establish tunnel. MockWrite data_writes1[] = { @@ -3016,7 +2987,7 @@ "Host: www.example.org:443\r\n" "Proxy-Connection: keep-alive\r\n\r\n"), - // After calling trans->RestartWithAuth(), this is the request we should + // After calling trans.RestartWithAuth(), this is the request we should // be issuing -- the final header line contains the credentials. MockWrite(ASYNC, 3, "CONNECT www.example.org:443 HTTP/1.1\r\n" @@ -3053,7 +3024,7 @@ TestCompletionCallback callback1; - int rv = trans->Start(&request, callback1.callback(), log.bound()); + int rv = trans.Start(&request, callback1.callback(), log.bound()); EXPECT_THAT(callback1.GetResult(rv), IsOk()); TestNetLogEntry::List entries; @@ -3066,7 +3037,7 @@ NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, NetLog::PHASE_NONE); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_TRUE(response->headers->IsKeepAlive()); @@ -3078,11 +3049,11 @@ TestCompletionCallback callback2; // Wrong password (should be "bar"). - rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBaz), - callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz), + callback2.callback()); EXPECT_THAT(callback2.GetResult(rv), IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_TRUE(response->headers->IsKeepAlive()); @@ -3117,8 +3088,7 @@ session_deps_.net_log = log.bound().net_log(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Since we have proxy, should try to establish tunnel. MockWrite data_writes1[] = { @@ -3127,7 +3097,7 @@ "Host: www.example.org:443\r\n" "Proxy-Connection: keep-alive\r\n\r\n"), - // After calling trans->RestartWithAuth(), this is the request we should + // After calling trans.RestartWithAuth(), this is the request we should // be issuing -- the final header line contains the credentials. MockWrite(ASYNC, 3, "CONNECT www.example.org:443 HTTP/1.1\r\n" @@ -3162,7 +3132,7 @@ TestCompletionCallback callback1; - int rv = trans->Start(&request, callback1.callback(), log.bound()); + int rv = trans.Start(&request, callback1.callback(), log.bound()); EXPECT_THAT(callback1.GetResult(rv), IsOk()); TestNetLogEntry::List entries; @@ -3175,7 +3145,7 @@ NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, NetLog::PHASE_NONE); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_TRUE(response->headers->IsKeepAlive()); @@ -3187,11 +3157,11 @@ TestCompletionCallback callback2; // Wrong password (should be "bar"). - rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBaz), - callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBaz), + callback2.callback()); EXPECT_THAT(callback2.GetResult(rv), IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_TRUE(response->headers->IsKeepAlive()); @@ -3282,7 +3252,7 @@ TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); int rv = trans->Start(&request, callback1.callback(), log.bound()); @@ -3347,8 +3317,7 @@ session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70"); std::unique_ptr<HttpNetworkSession> session = CreateSession(&session_deps_); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Since we have proxy, should try to establish tunnel. MockWrite data_writes1[] = { @@ -3369,7 +3338,7 @@ }; MockWrite data_writes2[] = { - // After calling trans->RestartWithAuth(), this is the request we should + // After calling trans.RestartWithAuth(), this is the request we should // be issuing -- the final header line contains the credentials. MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n" "Host: www.example.org:443\r\n" @@ -3401,26 +3370,26 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(callback.GetResult(rv), IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_TRUE(response->headers->IsKeepAlive()); EXPECT_EQ(407, response->headers->response_code()); EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); - rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback()); EXPECT_THAT(callback.GetResult(rv), IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_TRUE(response->headers->IsKeepAlive()); EXPECT_EQ(200, response->headers->response_code()); std::string body; - EXPECT_THAT(ReadTransaction(trans.get(), &body), IsOk()); + EXPECT_THAT(ReadTransaction(&trans, &body), IsOk()); EXPECT_EQ("hello", body); } @@ -3437,8 +3406,7 @@ std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Since we have proxy, should try to establish tunnel. MockWrite data_writes[] = { @@ -3462,13 +3430,13 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_TRUE(response->headers->IsKeepAlive()); @@ -3476,7 +3444,7 @@ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED)); // Flush the idle socket before the HttpNetworkTransaction goes out of scope. @@ -3496,8 +3464,7 @@ std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Since we have proxy, should try to establish tunnel. MockWrite data_writes[] = { @@ -3522,13 +3489,13 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_TRUE(response->headers->IsKeepAlive()); @@ -3538,7 +3505,7 @@ EXPECT_FALSE(response->headers->HasHeader("Set-Cookie")); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED)); // Flush the idle socket before the HttpNetworkTransaction goes out of scope. @@ -3555,8 +3522,7 @@ // We are using a DIRECT connection (i.e. no proxy) for this session. std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes1[] = { MockWrite( @@ -3579,7 +3545,7 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -3631,10 +3597,9 @@ TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback1.callback(), log.bound()); + int rv = trans.Start(&request, callback1.callback(), log.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); @@ -3725,7 +3690,7 @@ SSLSocketDataProvider ssl(ASYNC, OK); session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); TestCompletionCallback callback; @@ -3845,7 +3810,7 @@ SSLSocketDataProvider ssl(ASYNC, OK); session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); TestCompletionCallback callback; @@ -3960,7 +3925,7 @@ data_writes2, arraysize(data_writes2)); session_deps_.socket_factory->AddSocketDataProvider(&data2); - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); TestCompletionCallback callback; @@ -4059,7 +4024,7 @@ SSLSocketDataProvider ssl(ASYNC, OK); session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); TestCompletionCallback callback; @@ -4142,7 +4107,7 @@ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans1( + std::unique_ptr<HttpNetworkTransaction> trans1( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); int rv = trans1->Start(&request1, callback1.callback(), log.bound()); @@ -4163,7 +4128,7 @@ trans1.reset(); TestCompletionCallback callback2; - std::unique_ptr<HttpTransaction> trans2( + std::unique_ptr<HttpNetworkTransaction> trans2( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); rv = trans2->Start(&request2, callback2.callback(), log.bound()); @@ -4240,7 +4205,7 @@ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans1( + std::unique_ptr<HttpNetworkTransaction> trans1( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); int rv = trans1->Start(&request1, callback1.callback(), log.bound()); @@ -4262,7 +4227,7 @@ trans1.reset(); TestCompletionCallback callback2; - std::unique_ptr<HttpTransaction> trans2( + std::unique_ptr<HttpNetworkTransaction> trans2( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); rv = trans2->Start(&request2, callback2.callback(), log.bound()); @@ -4321,21 +4286,20 @@ TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback1.callback(), log.bound()); + int rv = trans.Start(&request, callback1.callback(), log.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); LoadTimingInfo load_timing_info; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers->IsKeepAlive()); @@ -4376,32 +4340,31 @@ session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback1.callback(), log.bound()); + int rv = trans.Start(&request, callback1.callback(), log.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); LoadTimingInfo load_timing_info; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine()); std::string response_data; - ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk()); + ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk()); EXPECT_EQ(kUploadData, response_data); } @@ -4436,19 +4399,18 @@ session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Stall the hostname resolution begun by the transaction. session_deps_.host_resolver->set_synchronous_mode(false); session_deps_.host_resolver->set_ondemand_mode(true); - int rv = trans->Start(&request, callback1.callback(), log.bound()); + int rv = trans.Start(&request, callback1.callback(), log.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // Race a session to the proxy, which completes first. @@ -4466,13 +4428,13 @@ rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine()); std::string response_data; - ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk()); + ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk()); EXPECT_EQ(kUploadData, response_data); } @@ -4531,21 +4493,20 @@ session_deps_.socket_factory->AddSocketDataProvider(&data); SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback1.callback(), log.bound()); + int rv = trans.Start(&request, callback1.callback(), log.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* const response = trans->GetResponseInfo(); + const HttpResponseInfo* const response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); @@ -4555,14 +4516,13 @@ TestCompletionCallback callback2; - rv = trans->RestartWithAuth( - AuthCredentials(kFoo, kBar), callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback2.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* const response_restart = trans->GetResponseInfo(); + const HttpResponseInfo* const response_restart = trans.GetResponseInfo(); ASSERT_TRUE(response_restart); ASSERT_TRUE(response_restart->headers); @@ -4584,8 +4544,7 @@ session_deps_.net_log = log.bound().net_log(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // CONNECT to www.example.org:443 via SPDY SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect( @@ -4626,30 +4585,30 @@ session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); SSLSocketDataProvider ssl2(ASYNC, OK); session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); TestCompletionCallback callback1; - int rv = trans->Start(&request, callback1.callback(), log.bound()); + int rv = trans.Start(&request, callback1.callback(), log.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); ASSERT_THAT(rv, IsOk()); LoadTimingInfo load_timing_info; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); std::string response_data; - ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk()); + ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk()); EXPECT_EQ("1234567890", response_data); } @@ -4668,8 +4627,7 @@ session_deps_.net_log = log.bound().net_log(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // CONNECT to www.example.org:443 via SPDY SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect( @@ -4711,15 +4669,15 @@ session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); SSLSocketDataProvider ssl2(ASYNC, OK); - ssl2.SetNextProto(kProtoHTTP2); + ssl2.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); TestCompletionCallback callback1; - int rv = trans->Start(&request, callback1.callback(), log.bound()); + int rv = trans.Start(&request, callback1.callback(), log.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // Allow the SpdyProxyClientSocket's write callback to complete. @@ -4730,16 +4688,16 @@ EXPECT_THAT(rv, IsOk()); LoadTimingInfo load_timing_info; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine()); std::string response_data; - ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk()); + ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk()); EXPECT_EQ(kUploadData, response_data); } @@ -4756,8 +4714,7 @@ session_deps_.net_log = log.bound().net_log(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // CONNECT to www.example.org:443 via SPDY SpdySerializedFrame connect(spdy_util_.ConstructSpdyConnect( @@ -4780,15 +4737,15 @@ session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); SSLSocketDataProvider ssl2(ASYNC, OK); - ssl2.SetNextProto(kProtoHTTP2); + ssl2.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); TestCompletionCallback callback1; - int rv = trans->Start(&request, callback1.callback(), log.bound()); + int rv = trans.Start(&request, callback1.callback(), log.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); @@ -4882,7 +4839,7 @@ session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); SSLSocketDataProvider ssl2(ASYNC, OK); session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); @@ -4891,32 +4848,30 @@ TestCompletionCallback callback; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); - int rv = trans->Start(&request1, callback.callback(), BoundNetLog()); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); + int rv = trans.Start(&request1, callback.callback(), BoundNetLog()); EXPECT_THAT(callback.GetResult(rv), IsOk()); LoadTimingInfo load_timing_info; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); std::string response_data; scoped_refptr<IOBuffer> buf(new IOBuffer(256)); - rv = trans->Read(buf.get(), 256, callback.callback()); + rv = trans.Read(buf.get(), 256, callback.callback()); EXPECT_EQ(1, callback.GetResult(rv)); - std::unique_ptr<HttpTransaction> trans2( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); - rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); + HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get()); + rv = trans2.Start(&request2, callback.callback(), BoundNetLog()); EXPECT_THAT(callback.GetResult(rv), IsOk()); LoadTimingInfo load_timing_info2; - EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2)); + EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2)); // Even though the SPDY connection is reused, a new tunnelled connection has // to be created, so the socket's load timing looks like a fresh connection. TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES); @@ -4925,7 +4880,7 @@ // separate stream. EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id); - rv = trans2->Read(buf.get(), 256, callback.callback()); + rv = trans2.Read(buf.get(), 256, callback.callback()); EXPECT_EQ(2, callback.GetResult(rv)); } @@ -5004,14 +4959,14 @@ session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); SSLSocketDataProvider ssl2(ASYNC, OK); session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); TestCompletionCallback callback; - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); int rv = trans->Start(&request1, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -5033,7 +4988,7 @@ EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback())); trans.reset(); - std::unique_ptr<HttpTransaction> trans2( + std::unique_ptr<HttpNetworkTransaction> trans2( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -5106,12 +5061,12 @@ session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); TestCompletionCallback callback; - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); int rv = trans->Start(&request1, callback.callback(), BoundNetLog()); EXPECT_THAT(callback.GetResult(rv), IsOk()); @@ -5133,19 +5088,18 @@ // Delete the first request, so the second one can reuse the socket. trans.reset(); - std::unique_ptr<HttpTransaction> trans2( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); - rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); + HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get()); + rv = trans2.Start(&request2, callback.callback(), BoundNetLog()); EXPECT_THAT(callback.GetResult(rv), IsOk()); LoadTimingInfo load_timing_info2; - EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2)); + EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2)); TestLoadTimingReused(load_timing_info2); // The requests should have the same ID. EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id); - rv = trans2->Read(buf.get(), 256, callback.callback()); + rv = trans2.Read(buf.get(), 256, callback.callback()); EXPECT_EQ(2, callback.GetResult(rv)); } @@ -5165,18 +5119,16 @@ // Since we have proxy, should use full url MockWrite data_writes1[] = { - MockWrite( - "GET http://www.example.org/ HTTP/1.1\r\n" - "Host: www.example.org\r\n" - "Proxy-Connection: keep-alive\r\n\r\n"), + MockWrite("GET http://www.example.org/ HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Proxy-Connection: keep-alive\r\n\r\n"), - // After calling trans->RestartWithAuth(), this is the request we should + // After calling trans.RestartWithAuth(), this is the request we should // be issuing -- the final header line contains the credentials. - MockWrite( - "GET http://www.example.org/ HTTP/1.1\r\n" - "Host: www.example.org\r\n" - "Proxy-Connection: keep-alive\r\n" - "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), + MockWrite("GET http://www.example.org/ HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Proxy-Connection: keep-alive\r\n" + "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"), }; // The proxy responds to the GET with a 407, using a persistent @@ -5202,21 +5154,20 @@ TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback1.callback(), log.bound()); + int rv = trans.Start(&request, callback1.callback(), log.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); LoadTimingInfo load_timing_info; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_EQ(407, response->headers->response_code()); @@ -5225,19 +5176,18 @@ TestCompletionCallback callback2; - rv = trans->RestartWithAuth( - AuthCredentials(kFoo, kBar), callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback2.WaitForResult(); EXPECT_THAT(rv, IsOk()); load_timing_info = LoadTimingInfo(); - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); // Retrying with HTTP AUTH is considered to be reusing a socket. TestLoadTimingReused(load_timing_info); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers->IsKeepAlive()); @@ -5279,10 +5229,9 @@ TestCompletionCallback callback; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -5476,8 +5425,7 @@ session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70"); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes1[] = { MockWrite( @@ -5499,7 +5447,7 @@ MockRead(SYNCHRONOUS, ERR_FAILED), }; - // After calling trans->RestartWithAuth() the first time, this is the + // After calling trans.RestartWithAuth() the first time, this is the // request we should be issuing -- the final header line contains the // proxy's credentials. MockWrite data_writes2[] = { @@ -5522,7 +5470,7 @@ MockRead(SYNCHRONOUS, ERR_FAILED), // Won't be reached. }; - // After calling trans->RestartWithAuth() the second time, we should send + // After calling trans.RestartWithAuth() the second time, we should send // the credentials for both the proxy and origin server. MockWrite data_writes3[] = { MockWrite( @@ -5553,39 +5501,38 @@ TestCompletionCallback callback1; - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get())); TestCompletionCallback callback2; - rv = trans->RestartWithAuth( - AuthCredentials(kFoo, kBar), callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback2.WaitForResult(); EXPECT_THAT(rv, IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); TestCompletionCallback callback3; - rv = trans->RestartWithAuth( - AuthCredentials(kFoo2, kBar2), callback3.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2), + callback3.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback3.WaitForResult(); EXPECT_THAT(rv, IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); EXPECT_FALSE(response->auth_challenge); EXPECT_EQ(100, response->headers->GetContentLength()); } @@ -5632,26 +5579,26 @@ }; MockWrite data_writes2[] = { - // After restarting with a null identity, this is the - // request we should be issuing -- the final header line contains a Type - // 1 message. - MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" - "Host: 172.22.68.17\r\n" - "Connection: keep-alive\r\n" - "Authorization: NTLM " - "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"), + // After restarting with a null identity, this is the + // request we should be issuing -- the final header line contains a Type + // 1 message. + MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" + "Host: 172.22.68.17\r\n" + "Connection: keep-alive\r\n" + "Authorization: NTLM " + "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"), - // After calling trans->RestartWithAuth(), we should send a Type 3 message - // (the credentials for the origin server). The second request continues - // on the same connection. - MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" - "Host: 172.22.68.17\r\n" - "Connection: keep-alive\r\n" - "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA" - "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA" - "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW" - "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX" - "ahlhx5I=\r\n\r\n"), + // After calling trans.RestartWithAuth(), we should send a Type 3 message + // (the credentials for the origin server). The second request continues + // on the same connection. + MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" + "Host: 172.22.68.17\r\n" + "Connection: keep-alive\r\n" + "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA" + "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA" + "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW" + "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX" + "ahlhx5I=\r\n\r\n"), }; MockRead data_reads2[] = { @@ -5686,45 +5633,44 @@ TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - EXPECT_FALSE(trans->IsReadyToRestartForAuth()); + EXPECT_FALSE(trans.IsReadyToRestartForAuth()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get())); TestCompletionCallback callback2; - rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM), - callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM), + callback2.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback2.WaitForResult(); EXPECT_THAT(rv, IsOk()); - EXPECT_TRUE(trans->IsReadyToRestartForAuth()); + EXPECT_TRUE(trans.IsReadyToRestartForAuth()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); TestCompletionCallback callback3; - rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback()); + rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback3.WaitForResult(); EXPECT_THAT(rv, IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); EXPECT_EQ(13, response->headers->GetContentLength()); @@ -5761,26 +5707,26 @@ }; MockWrite data_writes2[] = { - // After restarting with a null identity, this is the - // request we should be issuing -- the final header line contains a Type - // 1 message. - MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" - "Host: 172.22.68.17\r\n" - "Connection: keep-alive\r\n" - "Authorization: NTLM " - "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"), + // After restarting with a null identity, this is the + // request we should be issuing -- the final header line contains a Type + // 1 message. + MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" + "Host: 172.22.68.17\r\n" + "Connection: keep-alive\r\n" + "Authorization: NTLM " + "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"), - // After calling trans->RestartWithAuth(), we should send a Type 3 message - // (the credentials for the origin server). The second request continues - // on the same connection. - MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" - "Host: 172.22.68.17\r\n" - "Connection: keep-alive\r\n" - "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA" - "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA" - "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY" - "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj" - "4Ww7b7E=\r\n\r\n"), + // After calling trans.RestartWithAuth(), we should send a Type 3 message + // (the credentials for the origin server). The second request continues + // on the same connection. + MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" + "Host: 172.22.68.17\r\n" + "Connection: keep-alive\r\n" + "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA" + "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA" + "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY" + "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj" + "4Ww7b7E=\r\n\r\n"), }; MockRead data_reads2[] = { @@ -5809,26 +5755,26 @@ }; MockWrite data_writes3[] = { - // After restarting with a null identity, this is the - // request we should be issuing -- the final header line contains a Type - // 1 message. - MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" - "Host: 172.22.68.17\r\n" - "Connection: keep-alive\r\n" - "Authorization: NTLM " - "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"), + // After restarting with a null identity, this is the + // request we should be issuing -- the final header line contains a Type + // 1 message. + MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" + "Host: 172.22.68.17\r\n" + "Connection: keep-alive\r\n" + "Authorization: NTLM " + "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"), - // After calling trans->RestartWithAuth(), we should send a Type 3 message - // (the credentials for the origin server). The second request continues - // on the same connection. - MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" - "Host: 172.22.68.17\r\n" - "Connection: keep-alive\r\n" - "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA" - "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA" - "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54" - "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI" - "+4MUm7c=\r\n\r\n"), + // After calling trans.RestartWithAuth(), we should send a Type 3 message + // (the credentials for the origin server). The second request continues + // on the same connection. + MockWrite("GET /kids/login.aspx HTTP/1.1\r\n" + "Host: 172.22.68.17\r\n" + "Connection: keep-alive\r\n" + "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA" + "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA" + "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54" + "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI" + "+4MUm7c=\r\n\r\n"), }; MockRead data_reads3[] = { @@ -5866,65 +5812,64 @@ TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - EXPECT_FALSE(trans->IsReadyToRestartForAuth()); + EXPECT_FALSE(trans.IsReadyToRestartForAuth()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get())); TestCompletionCallback callback2; // Enter the wrong password. - rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword), - callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword), + callback2.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback2.WaitForResult(); EXPECT_THAT(rv, IsOk()); - EXPECT_TRUE(trans->IsReadyToRestartForAuth()); + EXPECT_TRUE(trans.IsReadyToRestartForAuth()); TestCompletionCallback callback3; - rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback()); + rv = trans.RestartWithAuth(AuthCredentials(), callback3.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback3.WaitForResult(); EXPECT_THAT(rv, IsOk()); - EXPECT_FALSE(trans->IsReadyToRestartForAuth()); + EXPECT_FALSE(trans.IsReadyToRestartForAuth()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get())); TestCompletionCallback callback4; // Now enter the right password. - rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM), - callback4.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM), + callback4.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback4.WaitForResult(); EXPECT_THAT(rv, IsOk()); - EXPECT_TRUE(trans->IsReadyToRestartForAuth()); + EXPECT_TRUE(trans.IsReadyToRestartForAuth()); TestCompletionCallback callback5; // One more roundtrip - rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback()); + rv = trans.RestartWithAuth(AuthCredentials(), callback5.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback5.WaitForResult(); EXPECT_THAT(rv, IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); EXPECT_FALSE(response->auth_challenge); EXPECT_EQ(13, response->headers->GetContentLength()); } @@ -5940,8 +5885,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Respond with 300 kb of headers (we should fail after 256 kb). std::string large_headers_string; @@ -5958,7 +5902,7 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -5979,7 +5923,7 @@ std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); // Since we have proxy, should try to establish tunnel. @@ -6032,8 +5976,7 @@ std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockRead data_reads[] = { // A part of the response body is received with the response headers. @@ -6050,13 +5993,13 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers); @@ -6066,7 +6009,7 @@ EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("hello world", response_data); @@ -6110,15 +6053,14 @@ TestCompletionCallback callback; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); @@ -6126,7 +6068,7 @@ EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("hello world", response_data); @@ -6176,7 +6118,7 @@ TestCompletionCallback callback; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); int rv = trans->Start(&request, callback.callback(), BoundNetLog()); @@ -6241,8 +6183,7 @@ std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockRead data_reads[] = { // A part of the response body is received with the response headers. @@ -6258,12 +6199,12 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.GetResult(rv), IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers); std::string status_line = response->headers->GetStatusLine(); @@ -6279,7 +6220,7 @@ EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("hello world", response_data); @@ -6326,15 +6267,14 @@ TestCompletionCallback callback; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get())); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(callback.GetResult(rv), IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); @@ -6348,7 +6288,7 @@ EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get())); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("hello world", response_data); @@ -6394,18 +6334,17 @@ // Transaction must be created after the MockReads, so it's destroyed before // them. - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers); @@ -6415,7 +6354,7 @@ EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get())); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("", response_data); @@ -6493,25 +6432,24 @@ }; for (int i = 0; i < 2; ++i) { - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); TestCompletionCallback callback; - int rv = trans->Start(&request[i], callback.callback(), BoundNetLog()); + int rv = trans.Start(&request[i], callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers); EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); EXPECT_EQ(kExpectedResponseData[i], response_data); } @@ -6527,8 +6465,7 @@ request.load_flags = LOAD_NORMAL; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // The password contains an escaped character -- for this test to pass it // will need to be unescaped by HttpNetworkTransaction. @@ -6572,20 +6509,20 @@ session_deps_.socket_factory->AddSocketDataProvider(&data2); TestCompletionCallback callback1; - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - EXPECT_TRUE(trans->IsReadyToRestartForAuth()); + EXPECT_TRUE(trans.IsReadyToRestartForAuth()); TestCompletionCallback callback2; - rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback2.WaitForResult(); EXPECT_THAT(rv, IsOk()); - EXPECT_FALSE(trans->IsReadyToRestartForAuth()); + EXPECT_FALSE(trans.IsReadyToRestartForAuth()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); // There is no challenge info, since the identity in URL worked. @@ -6610,8 +6547,7 @@ request.load_flags = LOAD_NORMAL; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes1[] = { MockWrite( @@ -6672,33 +6608,32 @@ TestCompletionCallback callback1; - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - EXPECT_TRUE(trans->IsReadyToRestartForAuth()); + EXPECT_TRUE(trans.IsReadyToRestartForAuth()); TestCompletionCallback callback2; - rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback2.WaitForResult(); EXPECT_THAT(rv, IsOk()); - EXPECT_FALSE(trans->IsReadyToRestartForAuth()); + EXPECT_FALSE(trans.IsReadyToRestartForAuth()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); TestCompletionCallback callback3; - rv = trans->RestartWithAuth( - AuthCredentials(kFoo, kBar), callback3.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback3.WaitForResult(); EXPECT_THAT(rv, IsOk()); - EXPECT_FALSE(trans->IsReadyToRestartForAuth()); + EXPECT_FALSE(trans.IsReadyToRestartForAuth()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); // There is no challenge info, since the identity worked. @@ -6721,8 +6656,7 @@ request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes1[] = { MockWrite( @@ -6763,25 +6697,24 @@ session_deps_.socket_factory->AddSocketDataProvider(&data3); TestCompletionCallback callback1; - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - EXPECT_FALSE(trans->IsReadyToRestartForAuth()); + EXPECT_FALSE(trans.IsReadyToRestartForAuth()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); TestCompletionCallback callback3; - rv = trans->RestartWithAuth( - AuthCredentials(kFoo, kBar), callback3.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback3.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback3.WaitForResult(); EXPECT_THAT(rv, IsOk()); - EXPECT_FALSE(trans->IsReadyToRestartForAuth()); + EXPECT_FALSE(trans.IsReadyToRestartForAuth()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); // There is no challenge info, since the identity worked. @@ -6803,8 +6736,7 @@ request.url = GURL("http://www.example.org/x/y/z"); request.load_flags = 0; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes1[] = { MockWrite( @@ -6845,26 +6777,26 @@ TestCompletionCallback callback1; - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); TestCompletionCallback callback2; - rv = trans->RestartWithAuth( - AuthCredentials(kFoo, kBar), callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), + callback2.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback2.WaitForResult(); EXPECT_THAT(rv, IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); EXPECT_EQ(100, response->headers->GetContentLength()); @@ -6881,8 +6813,7 @@ request.url = GURL("http://www.example.org/x/y/a/b"); request.load_flags = 0; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes1[] = { MockWrite( @@ -6927,13 +6858,13 @@ TestCompletionCallback callback1; - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->auth_challenge); EXPECT_FALSE(response->auth_challenge->is_proxy); @@ -6944,14 +6875,14 @@ TestCompletionCallback callback2; - rv = trans->RestartWithAuth( - AuthCredentials(kFoo2, kBar2), callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFoo2, kBar2), + callback2.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback2.WaitForResult(); EXPECT_THAT(rv, IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); EXPECT_EQ(100, response->headers->GetContentLength()); @@ -6967,8 +6898,7 @@ request.url = GURL("http://www.example.org/x/y/z2"); request.load_flags = 0; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes1[] = { MockWrite( @@ -6993,13 +6923,13 @@ TestCompletionCallback callback1; - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); @@ -7016,8 +6946,7 @@ request.url = GURL("http://www.example.org/x/1"); request.load_flags = 0; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes1[] = { MockWrite( @@ -7058,21 +6987,21 @@ TestCompletionCallback callback1; - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - EXPECT_TRUE(trans->IsReadyToRestartForAuth()); + EXPECT_TRUE(trans.IsReadyToRestartForAuth()); TestCompletionCallback callback2; - rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback2.WaitForResult(); EXPECT_THAT(rv, IsOk()); - EXPECT_FALSE(trans->IsReadyToRestartForAuth()); + EXPECT_FALSE(trans.IsReadyToRestartForAuth()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); EXPECT_EQ(100, response->headers->GetContentLength()); @@ -7088,8 +7017,7 @@ request.url = GURL("http://www.example.org/p/q/t"); request.load_flags = 0; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes1[] = { MockWrite( @@ -7151,34 +7079,34 @@ TestCompletionCallback callback1; - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - EXPECT_TRUE(trans->IsReadyToRestartForAuth()); + EXPECT_TRUE(trans.IsReadyToRestartForAuth()); TestCompletionCallback callback2; - rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(), callback2.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback2.WaitForResult(); EXPECT_THAT(rv, IsOk()); - EXPECT_FALSE(trans->IsReadyToRestartForAuth()); + EXPECT_FALSE(trans.IsReadyToRestartForAuth()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); TestCompletionCallback callback3; - rv = trans->RestartWithAuth( - AuthCredentials(kFoo3, kBar3), callback3.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFoo3, kBar3), + callback3.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback3.WaitForResult(); EXPECT_THAT(rv, IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); EXPECT_EQ(100, response->headers->GetContentLength()); @@ -7203,8 +7131,7 @@ request.url = GURL("http://www.example.org/x/y/z"); request.load_flags = 0; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes1[] = { MockWrite( @@ -7247,26 +7174,26 @@ TestCompletionCallback callback1; - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get())); TestCompletionCallback callback2; - rv = trans->RestartWithAuth( - AuthCredentials(kFoo, kBar), callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), + callback2.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback2.WaitForResult(); EXPECT_THAT(rv, IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); } @@ -7284,8 +7211,7 @@ request.url = GURL("http://www.example.org/x/y/a/b"); request.load_flags = 0; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes1[] = { MockWrite( @@ -7311,13 +7237,13 @@ TestCompletionCallback callback1; - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); } @@ -7327,16 +7253,15 @@ TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) { // Create a transaction (the dependencies aren't important). std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpNetworkTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Setup some state (which we expect ResetStateForRestart() will clear). - trans->read_buf_ = new IOBuffer(15); - trans->read_buf_len_ = 15; - trans->request_headers_.SetHeader("Authorization", "NTLM"); + trans.read_buf_ = new IOBuffer(15); + trans.read_buf_len_ = 15; + trans.request_headers_.SetHeader("Authorization", "NTLM"); // Setup state in response_ - HttpResponseInfo* response = &trans->response_; + HttpResponseInfo* response = &trans.response_; response->auth_challenge = new AuthChallengeInfo(); response->ssl_info.cert_status = static_cast<CertStatus>(-1); // Nonsensical. response->response_time = base::Time::Now(); @@ -7353,12 +7278,12 @@ } // Cause the above state to be reset. - trans->ResetStateForRestart(); + trans.ResetStateForRestart(); // Verify that the state that needed to be reset, has been reset. - EXPECT_FALSE(trans->read_buf_); - EXPECT_EQ(0, trans->read_buf_len_); - EXPECT_TRUE(trans->request_headers_.IsEmpty()); + EXPECT_FALSE(trans.read_buf_); + EXPECT_EQ(0, trans.read_buf_len_); + EXPECT_TRUE(trans.request_headers_.IsEmpty()); EXPECT_FALSE(response->auth_challenge); EXPECT_FALSE(response->headers); EXPECT_FALSE(response->was_cached); @@ -7374,8 +7299,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes[] = { MockWrite( @@ -7404,19 +7328,19 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID)); - rv = trans->RestartIgnoringLastError(callback.callback()); + rv = trans.RestartIgnoringLastError(callback.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_EQ(100, response->headers->GetContentLength()); @@ -7479,22 +7403,21 @@ session_deps_.socket_factory->ResetNextMockIndexes(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID)); - rv = trans->RestartIgnoringLastError(callback.callback()); + rv = trans.RestartIgnoringLastError(callback.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_EQ(100, response->headers->GetContentLength()); @@ -7543,15 +7466,14 @@ TestCompletionCallback callback; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); @@ -7561,7 +7483,7 @@ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); LoadTimingInfo load_timing_info; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReusedWithPac(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES); } @@ -7601,15 +7523,14 @@ TestCompletionCallback callback; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); @@ -7623,7 +7544,7 @@ // and no send / receive times. // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse. LoadTimingInfo load_timing_info; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); EXPECT_FALSE(load_timing_info.socket_reused); EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id); @@ -7673,7 +7594,7 @@ SequencedSocketData data(data_reads, arraysize(data_reads), data_writes, arraysize(data_writes)); SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy - proxy_ssl.SetNextProto(kProtoHTTP2); + proxy_ssl.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSocketDataProvider(&data); session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl); @@ -7681,15 +7602,14 @@ TestCompletionCallback callback; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); @@ -7731,10 +7651,9 @@ TestCompletionCallback callback; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -7776,7 +7695,7 @@ SequencedSocketData data(data_reads, arraysize(data_reads), data_writes, arraysize(data_writes)); SSLSocketDataProvider proxy_ssl(ASYNC, OK); // SSL to the proxy - proxy_ssl.SetNextProto(kProtoHTTP2); + proxy_ssl.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSocketDataProvider(&data); session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl); @@ -7784,10 +7703,9 @@ TestCompletionCallback callback; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -7819,7 +7737,7 @@ spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); spdy_util_.UpdateWithStreamDestruction(1); - // After calling trans->RestartWithAuth(), this is the request we should + // After calling trans.RestartWithAuth(), this is the request we should // be issuing -- the final header line contains the credentials. const char* const kAuthCredentials[] = { "proxy-authorization", "Basic Zm9vOmJhcg==", @@ -7870,7 +7788,7 @@ session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); // Negotiate SPDY to the proxy SSLSocketDataProvider proxy(ASYNC, OK); - proxy.SetNextProto(kProtoHTTP2); + proxy.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy); // Vanilla SSL to the server SSLSocketDataProvider server(ASYNC, OK); @@ -7878,7 +7796,7 @@ TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); int rv = trans->Start(&request, callback1.callback(), log.bound()); @@ -7989,10 +7907,10 @@ session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); // Negotiate SPDY to the proxy SSLSocketDataProvider proxy(ASYNC, OK); - proxy.SetNextProto(kProtoHTTP2); + proxy.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy); - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); TestCompletionCallback callback; int rv = trans->Start(&request, callback.callback(), log.bound()); @@ -8002,7 +7920,7 @@ EXPECT_THAT(rv, IsOk()); const HttpResponseInfo* response = trans->GetResponseInfo(); - std::unique_ptr<HttpTransaction> push_trans( + std::unique_ptr<HttpNetworkTransaction> push_trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); rv = push_trans->Start(&push_request, callback.callback(), log.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -8099,10 +8017,10 @@ session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); // Negotiate SPDY to the proxy SSLSocketDataProvider proxy(ASYNC, OK); - proxy.SetNextProto(kProtoHTTP2); + proxy.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy); - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); TestCompletionCallback callback; int rv = trans->Start(&request, callback.callback(), log.bound()); @@ -8183,10 +8101,10 @@ session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); // Negotiate SPDY to the proxy SSLSocketDataProvider proxy(ASYNC, OK); - proxy.SetNextProto(kProtoHTTP2); + proxy.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy); - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); TestCompletionCallback callback; int rv = trans->Start(&request, callback.callback(), log.bound()); @@ -8272,22 +8190,21 @@ TestCompletionCallback callback; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsError(ERR_CERT_AUTHORITY_INVALID)); - rv = trans->RestartIgnoringLastError(callback.callback()); + rv = trans.RestartIgnoringLastError(callback.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_EQ(100, response->headers->GetContentLength()); @@ -8301,8 +8218,7 @@ "Chromium Ultra Awesome X Edition"); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes[] = { MockWrite( @@ -8326,7 +8242,7 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -8342,8 +8258,7 @@ session_deps_.proxy_service = ProxyService::CreateFixed("myproxy:70"); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes[] = { MockWrite("CONNECT www.example.org:443 HTTP/1.1\r\n" @@ -8365,7 +8280,7 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -8381,8 +8296,7 @@ "http://the.previous.site.com/"); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes[] = { MockWrite( @@ -8406,7 +8320,7 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -8419,8 +8333,7 @@ request.url = GURL("http://www.example.org/"); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes[] = { MockWrite( @@ -8444,7 +8357,7 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -8457,8 +8370,7 @@ request.url = GURL("http://www.example.org/"); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes[] = { MockWrite( @@ -8482,7 +8394,7 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -8495,8 +8407,7 @@ request.url = GURL("http://www.example.org/"); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes[] = { MockWrite("HEAD / HTTP/1.1\r\n" @@ -8518,7 +8429,7 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -8532,8 +8443,7 @@ request.load_flags = LOAD_BYPASS_CACHE; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes[] = { MockWrite( @@ -8558,7 +8468,7 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -8572,8 +8482,7 @@ request.load_flags = LOAD_VALIDATE_CACHE; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes[] = { MockWrite( @@ -8597,7 +8506,7 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -8611,8 +8520,7 @@ request.extra_headers.SetHeader("FooHeader", "Bar"); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes[] = { MockWrite( @@ -8636,7 +8544,7 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -8652,8 +8560,7 @@ request.extra_headers.SetHeader("FoO", "bar"); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes[] = { MockWrite( @@ -8679,7 +8586,7 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -8698,8 +8605,7 @@ session_deps_.net_log = &net_log; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 }; char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; @@ -8725,22 +8631,22 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); LoadTimingInfo load_timing_info; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReusedWithPac(load_timing_info, CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); std::string response_text; - rv = ReadTransaction(trans.get(), &response_text); + rv = ReadTransaction(&trans, &response_text); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("Payload", response_text); } @@ -8757,8 +8663,7 @@ session_deps_.net_log = &net_log; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 }; unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; @@ -8789,22 +8694,22 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); LoadTimingInfo load_timing_info; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReusedWithPac(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); std::string response_text; - rv = ReadTransaction(trans.get(), &response_text); + rv = ReadTransaction(&trans, &response_text); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("Payload", response_text); } @@ -8821,8 +8726,7 @@ session_deps_.net_log = &net_log; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 }; char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 }; @@ -8848,22 +8752,22 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); LoadTimingInfo load_timing_info; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); std::string response_text; - rv = ReadTransaction(trans.get(), &response_text); + rv = ReadTransaction(&trans, &response_text); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("Payload", response_text); } @@ -8880,8 +8784,7 @@ session_deps_.net_log = &net_log; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 }; const char kSOCKS5GreetResponse[] = { 0x05, 0x00 }; @@ -8920,22 +8823,22 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); LoadTimingInfo load_timing_info; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReusedWithPac(load_timing_info, CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); std::string response_text; - rv = ReadTransaction(trans.get(), &response_text); + rv = ReadTransaction(&trans, &response_text); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("Payload", response_text); } @@ -8952,8 +8855,7 @@ session_deps_.net_log = &net_log; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 }; const char kSOCKS5GreetResponse[] = { 0x05, 0x00 }; @@ -8997,22 +8899,22 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); LoadTimingInfo load_timing_info; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReusedWithPac(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES); std::string response_text; - rv = ReadTransaction(trans.get(), &response_text); + rv = ReadTransaction(&trans, &response_text); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("Payload", response_text); } @@ -9051,13 +8953,12 @@ request.url = GURL(url); request.load_flags = 0; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session); TestCompletionCallback callback; // We do not complete this request, the dtor will clean the transaction up. - return trans->Start(&request, callback.callback(), BoundNetLog()); + return trans.Start(&request, callback.callback(), BoundNetLog()); } } // namespace @@ -9246,8 +9147,7 @@ mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool); peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); EXPECT_EQ(ERR_IO_PENDING, GroupNameTransactionHelper(tests[i].url, session.get())); @@ -9273,12 +9173,11 @@ session_deps_.host_resolver->rules()->AddSimulatedFailure("*"); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -9299,8 +9198,7 @@ session_deps_.host_resolver.reset(new MockCachingHostResolver); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Warm up the host cache so it has an entry for "www.example.org". AddressList addrlist; @@ -9335,7 +9233,7 @@ session_deps_.socket_factory->AddSocketDataProvider(&data); // Run the request. - rv = trans->Start(&request_info, callback.callback(), BoundNetLog()); + rv = trans.Start(&request_info, callback.callback(), BoundNetLog()); ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -9375,17 +9273,16 @@ TestCompletionCallback callback; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET)); IPEndPoint endpoint; - EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint)); + EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint)); EXPECT_LT(0u, endpoint.address().size()); } @@ -9407,28 +9304,27 @@ TestCompletionCallback callback; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers); EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("", response_data); IPEndPoint endpoint; - EXPECT_TRUE(trans->GetRemoteEndpoint(&endpoint)); + EXPECT_TRUE(trans.GetRemoteEndpoint(&endpoint)); EXPECT_LT(0u, endpoint.address().size()); } @@ -9460,7 +9356,7 @@ data_writes1, arraysize(data_writes1)); session_deps_.socket_factory->AddSocketDataProvider(&data1); - // After calling trans->RestartWithAuth(), this is the request we should + // After calling trans.RestartWithAuth(), this is the request we should // be issuing -- the final header line contains the credentials. MockWrite data_writes2[] = { MockWrite( @@ -9485,29 +9381,27 @@ TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get())); TestCompletionCallback callback2; - rv = trans->RestartWithAuth( - AuthCredentials(kFoo, kBar), callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback2.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback2.WaitForResult(); EXPECT_THAT(rv, IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); EXPECT_EQ(100, response->headers->GetContentLength()); @@ -9538,10 +9432,9 @@ session_deps_.socket_factory->ResetNextMockIndexes(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -9555,8 +9448,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockRead data_reads[] = { MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"), @@ -9568,19 +9460,19 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers); EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine()); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsError(ERR_CONTENT_LENGTH_MISMATCH)); } @@ -9604,8 +9496,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockRead data_reads[] = { MockRead("HTTP/1.0 200 OK\r\n\r\n"), @@ -9617,13 +9508,13 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsError(ERR_UPLOAD_FILE_CHANGED)); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->headers); @@ -9653,15 +9544,14 @@ // If we try to upload an unreadable file, the transaction should fail. std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); StaticSocketDataProvider data(NULL, 0, NULL, 0); session_deps_.socket_factory->AddSocketDataProvider(&data); TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -9707,7 +9597,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); StaticSocketDataProvider data; @@ -9748,7 +9638,7 @@ "\r\n"), }; - // After calling trans->RestartWithAuth(), provide an Authentication header + // After calling trans.RestartWithAuth(), provide an Authentication header // for first_realm. The server will reject and provide a challenge with // second_realm. MockWrite data_writes2[] = { @@ -9814,17 +9704,16 @@ TestCompletionCallback callback1; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Issue the first request with Authorize headers. There should be a // password prompt for first_realm waiting to be filled in after the // transaction completes. - int rv = trans->Start(&request, callback1.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback1.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); const AuthChallengeInfo* challenge = response->auth_challenge.get(); ASSERT_TRUE(challenge); @@ -9837,12 +9726,12 @@ // password prompt for second_realm waiting to be filled in after the // transaction completes. TestCompletionCallback callback2; - rv = trans->RestartWithAuth( - AuthCredentials(kFirst, kBaz), callback2.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBaz), + callback2.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback2.WaitForResult(); EXPECT_THAT(rv, IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); challenge = response->auth_challenge.get(); ASSERT_TRUE(challenge); @@ -9856,12 +9745,12 @@ // prompt is not present, it indicates that the HttpAuthCacheEntry for // first_realm was not correctly removed. TestCompletionCallback callback3; - rv = trans->RestartWithAuth( - AuthCredentials(kSecond, kFou), callback3.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kSecond, kFou), + callback3.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback3.WaitForResult(); EXPECT_THAT(rv, IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); challenge = response->auth_challenge.get(); ASSERT_TRUE(challenge); @@ -9872,12 +9761,12 @@ // Issue the fourth request with the correct password and username. TestCompletionCallback callback4; - rv = trans->RestartWithAuth( - AuthCredentials(kFirst, kBar), callback4.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFirst, kBar), + callback4.callback()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback4.WaitForResult(); EXPECT_THAT(rv, IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); } @@ -9905,10 +9794,9 @@ TestCompletionCallback callback; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); url::SchemeHostPort test_server(request.url); @@ -9920,7 +9808,7 @@ EXPECT_THAT(callback.WaitForResult(), IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); @@ -9928,7 +9816,7 @@ EXPECT_FALSE(response->was_npn_negotiated); std::string response_data; - ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk()); + ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk()); EXPECT_EQ("hello world", response_data); alternative_service_vector = @@ -9962,8 +9850,7 @@ TestCompletionCallback callback; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); url::SchemeHostPort test_server(request.url); HttpServerProperties* http_server_properties = @@ -9972,11 +9859,11 @@ http_server_properties->GetAlternativeServices(test_server); EXPECT_TRUE(alternative_service_vector.empty()); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); @@ -9984,7 +9871,7 @@ EXPECT_FALSE(response->was_npn_negotiated); std::string response_data; - ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk()); + ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk()); EXPECT_EQ("hello world", response_data); alternative_service_vector = @@ -10009,7 +9896,7 @@ first_data.set_connect_data(mock_connect); session_deps_.socket_factory->AddSocketDataProvider(&first_data); SSLSocketDataProvider ssl_http11(ASYNC, OK); - ssl_http11.SetNextProto(kProtoHTTP11); + ssl_http11.next_proto = kProtoHTTP11; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11); MockRead data_reads[] = { @@ -10031,11 +9918,10 @@ http_server_properties->SetAlternativeService( url::SchemeHostPort(request.url), alternative_service, expiration); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); // Alternative service is not used, request fails. EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED)); } @@ -10072,11 +9958,10 @@ http_server_properties->SetAlternativeService( url::SchemeHostPort(request.url), alternative_service, expiration); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); // Alternative service is not used, request fails. EXPECT_THAT(callback.GetResult(rv), IsError(ERR_CONNECTION_REFUSED)); } @@ -10116,13 +10001,12 @@ TestCompletionCallback callback; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(callback.GetResult(rv), IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); @@ -10130,7 +10014,7 @@ EXPECT_FALSE(response->was_npn_negotiated); std::string response_data; - ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk()); + ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk()); EXPECT_EQ("hello world", response_data); alternative_service_vector = @@ -10161,10 +10045,9 @@ TestCompletionCallback callback; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); url::SchemeHostPort test_server("https", "www.example.org", 443); @@ -10176,7 +10059,7 @@ EXPECT_THAT(callback.WaitForResult(), IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); @@ -10184,7 +10067,7 @@ EXPECT_FALSE(response->was_npn_negotiated); std::string response_data; - ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk()); + ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk()); EXPECT_EQ("hello world", response_data); alternative_service_vector = @@ -10208,7 +10091,7 @@ // Negotiate HTTP/1.1 with alternative.example.org. SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP11); + ssl.next_proto = kProtoHTTP11; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); // HTTP/1.1 data for request. @@ -10243,8 +10126,7 @@ // Mark the QUIC alternative service as broken. http_server_properties->MarkAlternativeServiceBroken(alternative_service); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); HttpRequestInfo request; request.method = "GET"; request.url = GURL(origin_url); @@ -10253,8 +10135,8 @@ NetErrorDetails details; EXPECT_FALSE(details.quic_broken); - trans->Start(&request, callback.callback(), BoundNetLog()); - trans->PopulateNetErrorDetails(&details); + trans.Start(&request, callback.callback(), BoundNetLog()); + trans.PopulateNetErrorDetails(&details); EXPECT_TRUE(details.quic_broken); } @@ -10268,7 +10150,7 @@ // Negotiate HTTP/1.1 with alternative1.example.org. SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP11); + ssl.next_proto = kProtoHTTP11; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); // HTTP/1.1 data for request. @@ -10318,8 +10200,7 @@ const AlternativeServiceVector alternative_service_vector = http_server_properties->GetAlternativeServices(server); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); HttpRequestInfo request; request.method = "GET"; request.url = GURL(origin_url); @@ -10328,8 +10209,8 @@ NetErrorDetails details; EXPECT_FALSE(details.quic_broken); - trans->Start(&request, callback.callback(), BoundNetLog()); - trans->PopulateNetErrorDetails(&details); + trans.Start(&request, callback.callback(), BoundNetLog()); + trans.PopulateNetErrorDetails(&details); EXPECT_FALSE(details.quic_broken); } @@ -10344,7 +10225,7 @@ first_data.set_connect_data(mock_connect); session_deps_.socket_factory->AddSocketDataProvider(&first_data); SSLSocketDataProvider ssl_http11(ASYNC, OK); - ssl_http11.SetNextProto(kProtoHTTP11); + ssl_http11.next_proto = kProtoHTTP11; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11); MockRead data_reads[] = { @@ -10370,21 +10251,20 @@ http_server_properties->SetAlternativeService(server, alternative_service, expiration); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); std::string response_data; - ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk()); + ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk()); EXPECT_EQ("hello world", response_data); const AlternativeServiceVector alternative_service_vector = @@ -10419,7 +10299,7 @@ data_reads, arraysize(data_reads), NULL, 0); session_deps_.socket_factory->AddSocketDataProvider(&second_data); SSLSocketDataProvider ssl_http11(ASYNC, OK); - ssl_http11.SetNextProto(kProtoHTTP11); + ssl_http11.next_proto = kProtoHTTP11; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -10435,13 +10315,11 @@ url::SchemeHostPort(restricted_port_request.url), alternative_service, expiration); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); TestCompletionCallback callback; - int rv = trans->Start( - &restricted_port_request, - callback.callback(), BoundNetLog()); + int rv = + trans.Start(&restricted_port_request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // Invalid change to unrestricted port should fail. EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_REFUSED)); @@ -10472,7 +10350,7 @@ data_reads, arraysize(data_reads), NULL, 0); session_deps_.socket_factory->AddSocketDataProvider(&second_data); SSLSocketDataProvider ssl_http11(ASYNC, OK); - ssl_http11.SetNextProto(kProtoHTTP11); + ssl_http11.next_proto = kProtoHTTP11; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -10488,13 +10366,11 @@ url::SchemeHostPort(restricted_port_request.url), alternative_service, expiration); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); TestCompletionCallback callback; - EXPECT_EQ(ERR_IO_PENDING, trans->Start( - &restricted_port_request, - callback.callback(), BoundNetLog())); + EXPECT_EQ(ERR_IO_PENDING, trans.Start(&restricted_port_request, + callback.callback(), BoundNetLog())); // Change to unrestricted port should succeed. EXPECT_THAT(callback.WaitForResult(), IsOk()); } @@ -10539,13 +10415,11 @@ url::SchemeHostPort(restricted_port_request.url), alternative_service, expiration); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); TestCompletionCallback callback; - int rv = trans->Start( - &restricted_port_request, - callback.callback(), BoundNetLog()); + int rv = + trans.Start(&restricted_port_request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // Valid change to restricted port should pass. EXPECT_THAT(callback.WaitForResult(), IsOk()); @@ -10575,7 +10449,7 @@ data_reads, arraysize(data_reads), NULL, 0); session_deps_.socket_factory->AddSocketDataProvider(&second_data); SSLSocketDataProvider ssl_http11(ASYNC, OK); - ssl_http11.SetNextProto(kProtoHTTP11); + ssl_http11.next_proto = kProtoHTTP11; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -10591,12 +10465,11 @@ url::SchemeHostPort(unrestricted_port_request.url), alternative_service, expiration); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); TestCompletionCallback callback; - int rv = trans->Start( - &unrestricted_port_request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&unrestricted_port_request, callback.callback(), + BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // Valid change to restricted port should pass. EXPECT_THAT(callback.WaitForResult(), IsOk()); @@ -10642,12 +10515,11 @@ url::SchemeHostPort(unrestricted_port_request.url), alternative_service, expiration); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); TestCompletionCallback callback; - int rv = trans->Start( - &unrestricted_port_request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&unrestricted_port_request, callback.callback(), + BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // Valid change to an unrestricted port should pass. EXPECT_THAT(callback.WaitForResult(), IsOk()); @@ -10685,22 +10557,21 @@ http_server_properties->SetAlternativeService( url::SchemeHostPort(request.url), alternative_service, expiration); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // The HTTP request should succeed. EXPECT_THAT(callback.WaitForResult(), IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); std::string response_data; - ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk()); + ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk()); EXPECT_EQ("hello world", response_data); } @@ -10722,11 +10593,11 @@ data_reads, arraysize(data_reads), NULL, 0); session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); SSLSocketDataProvider ssl_http11(ASYNC, OK); - ssl_http11.SetNextProto(kProtoHTTP11); + ssl_http11.next_proto = kProtoHTTP11; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11); SSLSocketDataProvider ssl_http2(ASYNC, OK); - ssl_http2.SetNextProto(kProtoHTTP2); + ssl_http2.next_proto = kProtoHTTP2; ssl_http2.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"); ASSERT_TRUE(ssl_http2.cert.get()); @@ -10757,7 +10628,7 @@ TestCompletionCallback callback; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); int rv = trans->Start(&request, callback.callback(), BoundNetLog()); @@ -10849,7 +10720,7 @@ session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); SSLSocketDataProvider ssl_http2(ASYNC, OK); - ssl_http2.SetNextProto(kProtoHTTP2); + ssl_http2.next_proto = kProtoHTTP2; ssl_http2.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"); ASSERT_TRUE(ssl_http2.cert); @@ -10947,7 +10818,7 @@ TestCompletionCallback callback; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); int rv = trans->Start(&request, callback.callback(), BoundNetLog()); @@ -11030,6 +10901,98 @@ ProxyResolver* resolver_; }; +// Test that proxy is resolved using the origin url, +// regardless of the alternative server. +TEST_F(HttpNetworkTransactionTest, UseOriginNotAlternativeForProxy) { + // Configure proxy to bypass www.example.org, which is the origin URL. + ProxyConfig proxy_config; + proxy_config.proxy_rules().ParseFromString("myproxy:70"); + proxy_config.proxy_rules().bypass_rules.AddRuleFromString("www.example.org"); + auto proxy_config_service = + base::MakeUnique<ProxyConfigServiceFixed>(proxy_config); + + CapturingProxyResolver capturing_proxy_resolver; + auto proxy_resolver_factory = base::MakeUnique<CapturingProxyResolverFactory>( + &capturing_proxy_resolver); + + TestNetLog net_log; + + session_deps_.proxy_service = base::MakeUnique<ProxyService>( + std::move(proxy_config_service), std::move(proxy_resolver_factory), + &net_log); + + session_deps_.net_log = &net_log; + + // Configure alternative service with a hostname that is not bypassed by the + // proxy. + std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); + HttpServerProperties* http_server_properties = + session->http_server_properties(); + url::SchemeHostPort server("https", "www.example.org", 443); + HostPortPair alternative("www.example.com", 443); + AlternativeService alternative_service( + AlternateProtocolFromNextProto(kProtoHTTP2), alternative); + base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1); + http_server_properties->SetAlternativeService(server, alternative_service, + expiration); + + // Non-alternative job should hang. + MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING); + StaticSocketDataProvider hanging_alternate_protocol_socket(nullptr, 0, + nullptr, 0); + hanging_alternate_protocol_socket.set_connect_data(never_finishing_connect); + session_deps_.socket_factory->AddSocketDataProvider( + &hanging_alternate_protocol_socket); + + SSLSocketDataProvider ssl_http2(ASYNC, OK); + ssl_http2.next_proto = kProtoHTTP2; + ssl_http2.cert = + ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"); + ASSERT_TRUE(ssl_http2.cert); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http2); + + HttpRequestInfo request; + request.method = "GET"; + request.url = GURL("https://www.example.org/"); + request.load_flags = 0; + + SpdySerializedFrame req( + spdy_util_.ConstructSpdyGet("https://www.example.org/", 1, LOWEST)); + + MockWrite spdy_writes[] = {CreateMockWrite(req, 0)}; + + SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); + SpdySerializedFrame data(spdy_util_.ConstructSpdyDataFrame(1, true)); + MockRead spdy_reads[] = { + CreateMockRead(resp, 1), CreateMockRead(data, 2), MockRead(ASYNC, 0, 3), + }; + + SequencedSocketData spdy_data(spdy_reads, arraysize(spdy_reads), spdy_writes, + arraysize(spdy_writes)); + session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); + + TestCompletionCallback callback; + + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); + + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); + EXPECT_THAT(callback.GetResult(rv), IsOk()); + + const HttpResponseInfo* response = trans.GetResponseInfo(); + ASSERT_TRUE(response); + ASSERT_TRUE(response->headers); + EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine()); + EXPECT_TRUE(response->was_fetched_via_spdy); + EXPECT_TRUE(response->was_npn_negotiated); + + std::string response_data; + ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk()); + EXPECT_EQ("hello!", response_data); + + // Origin host bypasses proxy, no resolution should have happened. + ASSERT_TRUE(capturing_proxy_resolver.resolved().empty()); +} + TEST_F(HttpNetworkTransactionTest, UseAlternativeServiceForTunneledNpnSpdy) { ProxyConfig proxy_config; proxy_config.set_auto_detect(true); @@ -11062,11 +11025,11 @@ data_reads, arraysize(data_reads), NULL, 0); session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); SSLSocketDataProvider ssl_http11(ASYNC, OK); - ssl_http11.SetNextProto(kProtoHTTP11); + ssl_http11.next_proto = kProtoHTTP11; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11); SSLSocketDataProvider ssl_http2(ASYNC, OK); - ssl_http2.SetNextProto(kProtoHTTP2); + ssl_http2.next_proto = kProtoHTTP2; ssl_http2.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"); ASSERT_TRUE(ssl_http2.cert); @@ -11106,7 +11069,7 @@ TestCompletionCallback callback; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); // HTTP/0.9 should fail. @@ -11160,11 +11123,11 @@ data_reads, arraysize(data_reads), NULL, 0); session_deps_.socket_factory->AddSocketDataProvider(&first_transaction); SSLSocketDataProvider ssl_http11(ASYNC, OK); - ssl_http11.SetNextProto(kProtoHTTP11); + ssl_http11.next_proto = kProtoHTTP11; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_http11); SSLSocketDataProvider ssl_http2(ASYNC, OK); - ssl_http2.SetNextProto(kProtoHTTP2); + ssl_http2.next_proto = kProtoHTTP2; ssl_http2.cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"); ASSERT_TRUE(ssl_http2.cert); @@ -11188,7 +11151,7 @@ std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); int rv = trans->Start(&request, callback.callback(), BoundNetLog()); @@ -11698,8 +11661,7 @@ mock_pool_manager->SetTransportSocketPool(transport_pool); session_peer.SetClientSocketPoolManager(std::move(mock_pool_manager)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); TestCompletionCallback callback; const MockWrite kGet( @@ -11756,11 +11718,11 @@ // First round of authentication. auth_handler->SetGenerateExpectation(false, OK); - rv = trans->Start(&request, callback.callback(), BoundNetLog()); + rv = trans.Start(&request, callback.callback(), BoundNetLog()); if (rv == ERR_IO_PENDING) rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->auth_challenge); EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); @@ -11768,11 +11730,10 @@ // In between rounds, another request comes in for the same domain. // It should not be able to grab the TCP socket that trans has already // claimed. - std::unique_ptr<HttpTransaction> trans_compete( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans_compete(DEFAULT_PRIORITY, session.get()); TestCompletionCallback callback_compete; - rv = trans_compete->Start( - &request, callback_compete.callback(), BoundNetLog()); + rv = + trans_compete.Start(&request, callback_compete.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // callback_compete.WaitForResult at this point would stall forever, // since the HttpNetworkTransaction does not release the request back to @@ -11780,33 +11741,33 @@ // Second round of authentication. auth_handler->SetGenerateExpectation(false, OK); - rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback()); + rv = trans.RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback()); if (rv == ERR_IO_PENDING) rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); // Third round of authentication. auth_handler->SetGenerateExpectation(false, OK); - rv = trans->RestartWithAuth(AuthCredentials(), callback.callback()); + rv = trans.RestartWithAuth(AuthCredentials(), callback.callback()); if (rv == ERR_IO_PENDING) rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); // Fourth round of authentication, which completes successfully. auth_handler->SetGenerateExpectation(false, OK); - rv = trans->RestartWithAuth(AuthCredentials(), callback.callback()); + rv = trans.RestartWithAuth(AuthCredentials(), callback.callback()); if (rv == ERR_IO_PENDING) rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - response = trans->GetResponseInfo(); + response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_FALSE(response->auth_challenge); EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup)); @@ -11814,11 +11775,11 @@ // Read the body since the fourth round was successful. This will also // release the socket back to the pool. scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50)); - rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); + rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback()); if (rv == ERR_IO_PENDING) rv = callback.WaitForResult(); EXPECT_EQ(3, rv); - rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback()); + rv = trans.Read(io_buf.get(), io_buf->size(), callback.callback()); EXPECT_EQ(0, rv); // There are still 0 idle sockets, since the trans_compete transaction // will be handed it immediately after trans releases it to the group. @@ -11828,11 +11789,11 @@ // read the body. rv = callback_compete.WaitForResult(); EXPECT_THAT(rv, IsOk()); - rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback()); + rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback()); if (rv == ERR_IO_PENDING) rv = callback.WaitForResult(); EXPECT_EQ(3, rv); - rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback()); + rv = trans_compete.Read(io_buf.get(), io_buf->size(), callback.callback()); EXPECT_EQ(0, rv); // Finally, the socket is released to the group. @@ -11863,7 +11824,7 @@ }; SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP11); + ssl.next_proto = kProtoHTTP11; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); @@ -11874,21 +11835,20 @@ TestCompletionCallback callback; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); ASSERT_TRUE(response->headers); EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); std::string response_data; - ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk()); + ASSERT_THAT(ReadTransaction(&trans, &response_data), IsOk()); EXPECT_EQ("hello world", response_data); EXPECT_FALSE(response->was_fetched_via_spdy); @@ -11905,7 +11865,7 @@ request.load_flags = 0; SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); SpdySerializedFrame req( @@ -11923,10 +11883,9 @@ TestCompletionCallback callback; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED)); } @@ -11976,7 +11935,7 @@ session_deps_.host_resolver->set_synchronous_mode(true); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0); @@ -12075,20 +12034,19 @@ TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); BeforeHeadersSentHandler headers_handler; - trans->SetBeforeHeadersSentCallback( + trans.SetBeforeHeadersSentCallback( base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent, base::Unretained(&headers_handler))); - int rv = trans->Start(&request, callback1.callback(), log.bound()); + int rv = trans.Start(&request, callback1.callback(), log.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers->IsKeepAlive()); @@ -12103,7 +12061,7 @@ EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion()); LoadTimingInfo load_timing_info; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReusedWithPac(load_timing_info, CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY); } @@ -12148,14 +12106,13 @@ TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); BeforeHeadersSentHandler headers_handler; - trans->SetBeforeHeadersSentCallback( + trans.SetBeforeHeadersSentCallback( base::Bind(&BeforeHeadersSentHandler::OnBeforeHeadersSent, base::Unretained(&headers_handler))); - int rv = trans->Start(&request, callback1.callback(), log.bound()); + int rv = trans.Start(&request, callback1.callback(), log.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); @@ -12170,7 +12127,7 @@ NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, NetLog::PHASE_NONE); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers->IsKeepAlive()); @@ -12185,7 +12142,7 @@ EXPECT_EQ("myproxy:70", headers_handler.observed_proxy_server_uri()); LoadTimingInfo load_timing_info; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReusedWithPac(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES); } @@ -12231,10 +12188,9 @@ TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback1.callback(), log.bound()); + int rv = trans.Start(&request, callback1.callback(), log.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); @@ -12248,7 +12204,7 @@ entries, pos, NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS, NetLog::PHASE_NONE); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers->IsKeepAlive()); @@ -12260,7 +12216,7 @@ response->proxy_server.Equals(HostPortPair::FromString("myproxy:70"))); LoadTimingInfo load_timing_info; - EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + EXPECT_TRUE(trans.GetLoadTimingInfo(&load_timing_info)); TestLoadTimingNotReusedWithPac(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES); } @@ -12302,10 +12258,9 @@ TestCompletionCallback callback1; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); - int rv = trans->Start(&request, callback1.callback(), log.bound()); + int rv = trans.Start(&request, callback1.callback(), log.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback1.WaitForResult(); @@ -12338,7 +12293,7 @@ session_deps_.socket_factory->AddSocketDataProvider(&spdy_data); SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); @@ -12358,17 +12313,16 @@ // This is the important line that marks this as a preconnect. request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED; - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsOk()); } // Given a net error, cause that error to be returned from the first Write() -// call and verify that the HttpTransaction fails with that error. +// call and verify that the HttpNetworkTransaction fails with that error. void HttpNetworkTransactionTest::CheckErrorIsPassedBack( int error, IoMode mode) { HttpRequestInfo request_info; @@ -12385,11 +12339,10 @@ session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); TestCompletionCallback callback; - int rv = trans->Start(&request_info, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request_info, callback.callback(), BoundNetLog()); if (rv == ERR_IO_PENDING) rv = callback.WaitForResult(); ASSERT_EQ(error, rv); @@ -12471,12 +12424,11 @@ session_deps_.socket_factory->AddSocketDataProvider(&data4); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Begin the SSL handshake with the peer. This consumes ssl_data1. TestCompletionCallback callback; - int rv = trans->Start(&request_info, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request_info, callback.callback(), BoundNetLog()); ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); // Complete the SSL handshake, which should abort due to requiring a @@ -12488,7 +12440,7 @@ // of SSLClientCertCache, NULL is just as meaningful as a real // certificate, so this is the same as supply a // legitimate-but-unacceptable certificate. - rv = trans->RestartWithCertificate(NULL, NULL, callback.callback()); + rv = trans.RestartWithCertificate(NULL, NULL, callback.callback()); ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); // Ensure the certificate was added to the client auth cache before @@ -12588,12 +12540,11 @@ session_deps_.socket_factory->AddSocketDataProvider(&data5); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Begin the initial SSL handshake. TestCompletionCallback callback; - int rv = trans->Start(&request_info, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request_info, callback.callback(), BoundNetLog()); ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); // Complete the SSL handshake, which should abort due to requiring a @@ -12605,7 +12556,7 @@ // of SSLClientCertCache, NULL is just as meaningful as a real // certificate, so this is the same as supply a // legitimate-but-unacceptable certificate. - rv = trans->RestartWithCertificate(NULL, NULL, callback.callback()); + rv = trans.RestartWithCertificate(NULL, NULL, callback.callback()); ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); // Ensure the certificate was added to the client auth cache before @@ -12681,12 +12632,11 @@ for (size_t i = 0; i < arraysize(requests); ++i) { session_deps_.socket_factory->ResetNextMockIndexes(); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpNetworkTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Begin the SSL handshake with the proxy. TestCompletionCallback callback; - int rv = trans->Start(&requests[i], callback.callback(), BoundNetLog()); + int rv = trans.Start(&requests[i], callback.callback(), BoundNetLog()); ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); // Complete the SSL handshake, which should abort due to requiring a @@ -12698,7 +12648,7 @@ // of SSLClientCertCache, NULL is just as meaningful as a real // certificate, so this is the same as supply a // legitimate-but-unacceptable certificate. - rv = trans->RestartWithCertificate(NULL, NULL, callback.callback()); + rv = trans.RestartWithCertificate(NULL, NULL, callback.callback()); ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); // Ensure the certificate was added to the client auth cache before @@ -12738,7 +12688,7 @@ pool_peer.DisableDomainAuthenticationVerification(); SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); SpdySerializedFrame host1_req( @@ -12827,7 +12777,7 @@ pool_peer.DisableDomainAuthenticationVerification(); SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); SpdySerializedFrame host1_req( @@ -12945,7 +12895,7 @@ pool_peer.DisableDomainAuthenticationVerification(); SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); SpdySerializedFrame host1_req( @@ -13064,7 +13014,7 @@ arraysize(writes2)); SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); session_deps_.socket_factory->AddSocketDataProvider(&data1); session_deps_.socket_factory->AddSocketDataProvider(&data2); @@ -13108,7 +13058,7 @@ // Negotiate HTTP/1.1 with alternative. SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP11); + ssl.next_proto = kProtoHTTP11; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); // No data should be read from the alternative, because HTTP/1.1 is @@ -13133,8 +13083,7 @@ http_server_properties->SetAlternativeService(server, alternative_service, expiration); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); HttpRequestInfo request; request.method = "GET"; request.url = GURL("https://www.example.org:443"); @@ -13143,7 +13092,7 @@ // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED. - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(callback.GetResult(rv), IsError(ERR_NPN_NEGOTIATION_FAILED)); } @@ -13157,7 +13106,7 @@ // Negotiate HTTP/1.1 with alternative. SSLSocketDataProvider alternative_ssl(ASYNC, OK); - alternative_ssl.SetNextProto(kProtoHTTP11); + alternative_ssl.next_proto = kProtoHTTP11; session_deps_.socket_factory->AddSSLSocketDataProvider(&alternative_ssl); // No data should be read from the alternative, because HTTP/1.1 is @@ -13167,7 +13116,7 @@ // Negotiate HTTP/1.1 with server. SSLSocketDataProvider origin_ssl(ASYNC, OK); - origin_ssl.SetNextProto(kProtoHTTP11); + origin_ssl.next_proto = kProtoHTTP11; session_deps_.socket_factory->AddSSLSocketDataProvider(&origin_ssl); MockWrite http_writes[] = { @@ -13263,7 +13212,7 @@ // Negotiate HTTP/1.1 with alternative.example.org. SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP11); + ssl.next_proto = kProtoHTTP11; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); // HTTP/1.1 data for |request1| and |request2|. @@ -13312,24 +13261,23 @@ expiration); // First transaction to alternative to open an HTTP/1.1 socket. - std::unique_ptr<HttpTransaction> trans1( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get()); HttpRequestInfo request1; request1.method = "GET"; request1.url = GURL(alternative_url); request1.load_flags = 0; TestCompletionCallback callback1; - int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog()); + int rv = trans1.Start(&request1, callback1.callback(), BoundNetLog()); EXPECT_THAT(callback1.GetResult(rv), IsOk()); - const HttpResponseInfo* response1 = trans1->GetResponseInfo(); + const HttpResponseInfo* response1 = trans1.GetResponseInfo(); ASSERT_TRUE(response1); ASSERT_TRUE(response1->headers); EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine()); EXPECT_TRUE(response1->was_npn_negotiated); EXPECT_FALSE(response1->was_fetched_via_spdy); std::string response_data1; - ASSERT_THAT(ReadTransaction(trans1.get(), &response_data1), IsOk()); + ASSERT_THAT(ReadTransaction(&trans1, &response_data1), IsOk()); EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1); // Request for origin.example.org, which has an alternative service. This @@ -13337,37 +13285,35 @@ // finds one which is HTTP/1.1, and should ignore it, and should not try to // open other connections to alternative server. The Job to server fails, so // this request fails. - std::unique_ptr<HttpTransaction> trans2( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get()); HttpRequestInfo request2; request2.method = "GET"; request2.url = GURL(origin_url); request2.load_flags = 0; TestCompletionCallback callback2; - rv = trans2->Start(&request2, callback2.callback(), BoundNetLog()); + rv = trans2.Start(&request2, callback2.callback(), BoundNetLog()); EXPECT_THAT(callback2.GetResult(rv), IsError(ERR_CONNECTION_REFUSED)); // Another transaction to alternative. This is to test that the HTTP/1.1 // socket is still open and in the pool. - std::unique_ptr<HttpTransaction> trans3( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get()); HttpRequestInfo request3; request3.method = "GET"; request3.url = GURL(alternative_url); request3.load_flags = 0; TestCompletionCallback callback3; - rv = trans3->Start(&request3, callback3.callback(), BoundNetLog()); + rv = trans3.Start(&request3, callback3.callback(), BoundNetLog()); EXPECT_THAT(callback3.GetResult(rv), IsOk()); - const HttpResponseInfo* response3 = trans3->GetResponseInfo(); + const HttpResponseInfo* response3 = trans3.GetResponseInfo(); ASSERT_TRUE(response3); ASSERT_TRUE(response3->headers); EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine()); EXPECT_TRUE(response3->was_npn_negotiated); EXPECT_FALSE(response3->was_fetched_via_spdy); std::string response_data3; - ASSERT_THAT(ReadTransaction(trans3.get(), &response_data3), IsOk()); + ASSERT_THAT(ReadTransaction(&trans3, &response_data3), IsOk()); EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3); } @@ -13433,10 +13379,10 @@ TestNetLog log; session_deps_.net_log = &log; SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy - ssl1.SetNextProto(kProtoHTTP2); + ssl1.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1); SSLSocketDataProvider ssl2(ASYNC, OK); // to the server - ssl2.SetNextProto(kProtoHTTP2); + ssl2.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); session_deps_.socket_factory->AddSocketDataProvider(&data1); @@ -13553,7 +13499,7 @@ NULL)); SSLSocketDataProvider ssl1(ASYNC, OK); // to the proxy - ssl1.SetNextProto(kProtoHTTP2); + ssl1.next_proto = kProtoHTTP2; // Load a valid cert. Note, that this does not need to // be valid for proxy because the MockSSLClientSocket does // not actually verify it. But SpdySession will use this @@ -13564,7 +13510,7 @@ session_deps_.socket_factory->AddSocketDataProvider(&data1); SSLSocketDataProvider ssl2(ASYNC, OK); // to the server - ssl2.SetNextProto(kProtoHTTP2); + ssl2.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); session_deps_.socket_factory->AddSocketDataProvider(&data2); @@ -13637,12 +13583,12 @@ arraysize(writes2)); SSLSocketDataProvider ssl1(ASYNC, OK); - ssl1.SetNextProto(kProtoHTTP2); + ssl1.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1); session_deps_.socket_factory->AddSocketDataProvider(&data1); SSLSocketDataProvider ssl2(ASYNC, OK); - ssl2.SetNextProto(kProtoHTTP2); + ssl2.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); session_deps_.socket_factory->AddSocketDataProvider(&data2); @@ -13687,9 +13633,9 @@ std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); SSLSocketDataProvider ssl1(ASYNC, OK); - ssl1.SetNextProto(kProtoHTTP2); + ssl1.next_proto = kProtoHTTP2; SSLSocketDataProvider ssl2(ASYNC, OK); - ssl2.SetNextProto(kProtoHTTP2); + ssl2.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1); session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2); @@ -13844,8 +13790,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockConnect mock_connect(SYNCHRONOUS, ERR_NAME_NOT_RESOLVED); StaticSocketDataProvider data; @@ -13854,7 +13799,7 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -13862,15 +13807,15 @@ // We don't care whether this succeeds or fails, but it shouldn't crash. HttpRequestHeaders request_headers; - trans->GetFullRequestHeaders(&request_headers); + trans.GetFullRequestHeaders(&request_headers); ConnectionAttempts attempts; - trans->GetConnectionAttempts(&attempts); + trans.GetConnectionAttempts(&attempts); ASSERT_EQ(1u, attempts.size()); EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED)); IPEndPoint endpoint; - EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint)); + EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint)); EXPECT_TRUE(endpoint.address().empty()); } @@ -13881,8 +13826,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockConnect mock_connect(ASYNC, ERR_NAME_NOT_RESOLVED); StaticSocketDataProvider data; @@ -13891,7 +13835,7 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -13899,15 +13843,15 @@ // We don't care whether this succeeds or fails, but it shouldn't crash. HttpRequestHeaders request_headers; - trans->GetFullRequestHeaders(&request_headers); + trans.GetFullRequestHeaders(&request_headers); ConnectionAttempts attempts; - trans->GetConnectionAttempts(&attempts); + trans.GetConnectionAttempts(&attempts); ASSERT_EQ(1u, attempts.size()); EXPECT_THAT(attempts[0].result, IsError(ERR_NAME_NOT_RESOLVED)); IPEndPoint endpoint; - EXPECT_FALSE(trans->GetRemoteEndpoint(&endpoint)); + EXPECT_FALSE(trans.GetRemoteEndpoint(&endpoint)); EXPECT_TRUE(endpoint.address().empty()); } @@ -13918,8 +13862,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes[] = { MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET), @@ -13934,14 +13877,14 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET)); HttpRequestHeaders request_headers; - EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); + EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers)); EXPECT_TRUE(request_headers.HasHeader("Host")); } @@ -13952,8 +13895,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes[] = { MockWrite(ASYNC, ERR_CONNECTION_RESET), @@ -13968,14 +13910,14 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET)); HttpRequestHeaders request_headers; - EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); + EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers)); EXPECT_TRUE(request_headers.HasHeader("Host")); } @@ -13986,8 +13928,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes[] = { MockWrite( @@ -14005,14 +13946,14 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET)); HttpRequestHeaders request_headers; - EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); + EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers)); EXPECT_TRUE(request_headers.HasHeader("Host")); } @@ -14023,8 +13964,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes[] = { MockWrite( @@ -14042,14 +13982,14 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET)); HttpRequestHeaders request_headers; - EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); + EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers)); EXPECT_TRUE(request_headers.HasHeader("Host")); } @@ -14061,8 +14001,7 @@ request.extra_headers.SetHeader("X-Foo", "bar"); std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes[] = { MockWrite( @@ -14084,14 +14023,14 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); HttpRequestHeaders request_headers; - EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers)); + EXPECT_TRUE(trans.GetFullRequestHeaders(&request_headers)); std::string foo; EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo)); EXPECT_EQ("bar", foo); @@ -14247,7 +14186,7 @@ bool was_npn_negotiated() const override { return false; } - NextProto protocol_negotiated() const override { return kProtoUnknown; } + NextProto negotiated_protocol() const override { return kProtoUnknown; } bool using_spdy() const override { return false; } @@ -14640,25 +14579,23 @@ // Start the SSL request. TestCompletionCallback ssl_callback; - std::unique_ptr<HttpTransaction> ssl_trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); - ASSERT_EQ(ERR_IO_PENDING, - ssl_trans->Start(&ssl_request, ssl_callback.callback(), - BoundNetLog())); + HttpNetworkTransaction ssl_trans(DEFAULT_PRIORITY, session.get()); + ASSERT_EQ( + ERR_IO_PENDING, + ssl_trans.Start(&ssl_request, ssl_callback.callback(), BoundNetLog())); // Start the HTTP request. Pool should stall. TestCompletionCallback http_callback; - std::unique_ptr<HttpTransaction> http_trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); - ASSERT_EQ(ERR_IO_PENDING, - http_trans->Start(&http_request, http_callback.callback(), - BoundNetLog())); + HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get()); + ASSERT_EQ( + ERR_IO_PENDING, + http_trans.Start(&http_request, http_callback.callback(), BoundNetLog())); EXPECT_TRUE(IsTransportSocketPoolStalled(session.get())); // Wait for response from SSL request. ASSERT_THAT(ssl_callback.WaitForResult(), IsOk()); std::string response_data; - ASSERT_THAT(ReadTransaction(ssl_trans.get(), &response_data), IsOk()); + ASSERT_THAT(ReadTransaction(&ssl_trans, &response_data), IsOk()); EXPECT_EQ("hello world", response_data); // The SSL socket should automatically be closed, so the HTTP request can @@ -14668,7 +14605,7 @@ // The HTTP request can now complete. ASSERT_THAT(http_callback.WaitForResult(), IsOk()); - ASSERT_THAT(ReadTransaction(http_trans.get(), &response_data), IsOk()); + ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk()); EXPECT_EQ("falafel", response_data); EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get())); @@ -14728,18 +14665,17 @@ // Start the HTTP request. Pool should stall. TestCompletionCallback http_callback; - std::unique_ptr<HttpTransaction> http_trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); - ASSERT_EQ(ERR_IO_PENDING, - http_trans->Start(&http_request, http_callback.callback(), - BoundNetLog())); + HttpNetworkTransaction http_trans(DEFAULT_PRIORITY, session.get()); + ASSERT_EQ( + ERR_IO_PENDING, + http_trans.Start(&http_request, http_callback.callback(), BoundNetLog())); EXPECT_TRUE(IsTransportSocketPoolStalled(session.get())); // The SSL connection will automatically be closed once the connection is // established, to let the HTTP request start. ASSERT_THAT(http_callback.WaitForResult(), IsOk()); std::string response_data; - ASSERT_THAT(ReadTransaction(http_trans.get(), &response_data), IsOk()); + ASSERT_THAT(ReadTransaction(&http_trans, &response_data), IsOk()); EXPECT_EQ("falafel", response_data); EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get())); @@ -14758,8 +14694,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Send headers successfully, but get an error while sending the body. MockWrite data_writes[] = { MockWrite("POST / HTTP/1.1\r\n" @@ -14780,20 +14715,20 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers); EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine()); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("hello world", response_data); } @@ -14833,7 +14768,7 @@ request1.url = GURL("http://www.foo.com/"); request1.load_flags = 0; - std::unique_ptr<HttpTransaction> trans1( + std::unique_ptr<HttpNetworkTransaction> trans1( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); int rv = trans1->Start(&request1, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -14865,22 +14800,21 @@ request2.upload_data_stream = &upload_data_stream; request2.load_flags = 0; - std::unique_ptr<HttpTransaction> trans2( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); - rv = trans2->Start(&request2, callback.callback(), BoundNetLog()); + HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get()); + rv = trans2.Start(&request2, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response2 = trans2->GetResponseInfo(); + const HttpResponseInfo* response2 = trans2.GetResponseInfo(); ASSERT_TRUE(response2); EXPECT_TRUE(response2->headers); EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine()); std::string response_data2; - rv = ReadTransaction(trans2.get(), &response_data2); + rv = ReadTransaction(&trans2, &response_data2); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("second response", response_data2); } @@ -14899,8 +14833,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Send headers successfully, but get an error while sending the body. MockWrite data_writes[] = { MockWrite("POST / HTTP/1.1\r\n" @@ -14922,20 +14855,20 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers); EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine()); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("hello world", response_data); } @@ -14952,8 +14885,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Send headers successfully, but get an error while sending the body. MockWrite data_writes[] = { MockWrite("POST / HTTP/1.1\r\n" @@ -14974,7 +14906,7 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // Make sure the headers are sent before adding a chunk. This ensures that // they can't be merged with the body in a single send. Not currently @@ -14987,14 +14919,14 @@ rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers); EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine()); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("hello world", response_data); } @@ -15012,8 +14944,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes[] = { MockWrite("POST / HTTP/1.1\r\n" @@ -15035,20 +14966,20 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers); EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine()); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("hello world", response_data); } @@ -15066,8 +14997,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Send headers successfully, but get an error while sending the body. MockWrite data_writes[] = { MockWrite("POST / HTTP/1.1\r\n" @@ -15088,7 +15018,7 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -15109,8 +15039,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Send headers successfully, but get an error while sending the body. MockWrite data_writes[] = { MockWrite("POST / HTTP/1.1\r\n" @@ -15133,7 +15062,7 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -15153,8 +15082,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Send headers successfully, but get an error while sending the body. MockWrite data_writes[] = { MockWrite("POST / HTTP/1.1\r\n" @@ -15174,7 +15102,7 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -15194,8 +15122,7 @@ request.load_flags = 0; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Send headers successfully, but get an error while sending the body. MockWrite data_writes[] = { MockWrite("POST / HTTP/1.1\r\n" @@ -15215,7 +15142,7 @@ TestCompletionCallback callback; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); rv = callback.WaitForResult(); @@ -15281,7 +15208,7 @@ SSLSocketDataProvider ssl(ASYNC, OK); session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); FakeWebSocketStreamCreateHelper websocket_stream_create_helper; trans->SetWebSocketHandshakeStreamCreateHelper( @@ -15380,7 +15307,7 @@ GURL("http://myproxy:70/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC, "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/"); - std::unique_ptr<HttpTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); FakeWebSocketStreamCreateHelper websocket_stream_create_helper; trans->SetWebSocketHandshakeStreamCreateHelper( @@ -15416,8 +15343,7 @@ request.upload_data_stream = &upload_data_stream; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes[] = { MockWrite("POST / HTTP/1.1\r\n" "Host: www.foo.com\r\n" @@ -15437,16 +15363,16 @@ TestCompletionCallback callback; EXPECT_EQ(ERR_IO_PENDING, - trans->Start(&request, callback.callback(), BoundNetLog())); + trans.Start(&request, callback.callback(), BoundNetLog())); EXPECT_THAT(callback.WaitForResult(), IsOk()); std::string response_data; - EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk()); + EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk()); EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)), - trans->GetTotalSentBytes()); + trans.GetTotalSentBytes()); EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)), - trans->GetTotalReceivedBytes()); + trans.GetTotalReceivedBytes()); } TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesPost100Continue) { @@ -15461,8 +15387,7 @@ request.upload_data_stream = &upload_data_stream; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); MockWrite data_writes[] = { MockWrite("POST / HTTP/1.1\r\n" "Host: www.foo.com\r\n" @@ -15483,16 +15408,16 @@ TestCompletionCallback callback; EXPECT_EQ(ERR_IO_PENDING, - trans->Start(&request, callback.callback(), BoundNetLog())); + trans.Start(&request, callback.callback(), BoundNetLog())); EXPECT_THAT(callback.WaitForResult(), IsOk()); std::string response_data; - EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk()); + EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk()); EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)), - trans->GetTotalSentBytes()); + trans.GetTotalSentBytes()); EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)), - trans->GetTotalReceivedBytes()); + trans.GetTotalReceivedBytes()); } TEST_F(HttpNetworkTransactionTest, TotalNetworkBytesChunkedPost) { @@ -15504,8 +15429,7 @@ request.upload_data_stream = &upload_data_stream; std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); - std::unique_ptr<HttpTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); // Send headers successfully, but get an error while sending the body. MockWrite data_writes[] = { MockWrite("POST / HTTP/1.1\r\n" @@ -15526,7 +15450,7 @@ TestCompletionCallback callback; EXPECT_EQ(ERR_IO_PENDING, - trans->Start(&request, callback.callback(), BoundNetLog())); + trans.Start(&request, callback.callback(), BoundNetLog())); base::RunLoop().RunUntilIdle(); upload_data_stream.AppendData("f", 1, false); @@ -15537,12 +15461,12 @@ EXPECT_THAT(callback.WaitForResult(), IsOk()); std::string response_data; - EXPECT_THAT(ReadTransaction(trans.get(), &response_data), IsOk()); + EXPECT_THAT(ReadTransaction(&trans, &response_data), IsOk()); EXPECT_EQ(CountWriteBytes(data_writes, arraysize(data_writes)), - trans->GetTotalSentBytes()); + trans.GetTotalSentBytes()); EXPECT_EQ(CountReadBytes(data_reads, arraysize(data_reads)), - trans->GetTotalReceivedBytes()); + trans.GetTotalReceivedBytes()); } #if !defined(OS_IOS) @@ -15555,7 +15479,7 @@ SSLSocketDataProvider ssl(ASYNC, OK); ssl.token_binding_negotiated = true; ssl.token_binding_key_param = TB_PARAM_ECDSAP256; - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl); SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
diff --git a/net/http/http_proxy_client_socket.cc b/net/http/http_proxy_client_socket.cc index e99049e..b84eeaad 100644 --- a/net/http/http_proxy_client_socket.cc +++ b/net/http/http_proxy_client_socket.cc
@@ -34,7 +34,7 @@ HttpAuthController* http_auth_controller, bool tunnel, bool using_spdy, - NextProto protocol_negotiated, + NextProto negotiated_protocol, ProxyDelegate* proxy_delegate, bool is_https_proxy) : io_callback_(base::Bind(&HttpProxyClientSocket::OnIOComplete, @@ -45,7 +45,7 @@ auth_(http_auth_controller), tunnel_(tunnel), using_spdy_(using_spdy), - protocol_negotiated_(protocol_negotiated), + negotiated_protocol_(negotiated_protocol), is_https_proxy_(is_https_proxy), redirect_has_load_timing_info_(false), proxy_server_(proxy_server), @@ -89,8 +89,8 @@ return using_spdy_; } -NextProto HttpProxyClientSocket::GetProtocolNegotiated() const { - return protocol_negotiated_; +NextProto HttpProxyClientSocket::GetProxyNegotiatedProtocol() const { + return negotiated_protocol_; } const HttpResponseInfo* HttpProxyClientSocket::GetConnectResponseInfo() const {
diff --git a/net/http/http_proxy_client_socket.h b/net/http/http_proxy_client_socket.h index 1c433ea..3cb0a2b 100644 --- a/net/http/http_proxy_client_socket.h +++ b/net/http/http_proxy_client_socket.h
@@ -45,7 +45,7 @@ HttpAuthController* http_auth_controller, bool tunnel, bool using_spdy, - NextProto protocol_negotiated, + NextProto negotiated_protocol, ProxyDelegate* proxy_delegate, bool is_https_proxy); @@ -58,7 +58,7 @@ int RestartWithAuth(const CompletionCallback& callback) override; const scoped_refptr<HttpAuthController>& GetAuthController() const override; bool IsUsingSpdy() const override; - NextProto GetProtocolNegotiated() const override; + NextProto GetProxyNegotiatedProtocol() const override; // StreamSocket implementation. int Connect(const CompletionCallback& callback) override; @@ -150,7 +150,7 @@ // If true, then the connection to the proxy is a SPDY connection. const bool using_spdy_; // Protocol negotiated with the server. - NextProto protocol_negotiated_; + NextProto negotiated_protocol_; // If true, then SSL is used to communicate with this proxy const bool is_https_proxy_;
diff --git a/net/http/http_proxy_client_socket_pool_unittest.cc b/net/http/http_proxy_client_socket_pool_unittest.cc index 7f056ea..88849a0 100644 --- a/net/http/http_proxy_client_socket_pool_unittest.cc +++ b/net/http/http_proxy_client_socket_pool_unittest.cc
@@ -180,7 +180,7 @@ } } - void InitializeSpdySsl() { ssl_data_->SetNextProto(kProtoHTTP2); } + void InitializeSpdySsl() { ssl_data_->next_proto = kProtoHTTP2; } std::unique_ptr<HttpNetworkSession> CreateNetworkSession() { return SpdySessionDependencies::SpdyCreateSession(&session_deps_);
diff --git a/net/http/http_proxy_client_socket_wrapper.cc b/net/http/http_proxy_client_socket_wrapper.cc index 207f1a5..6be76b5 100644 --- a/net/http/http_proxy_client_socket_wrapper.cc +++ b/net/http/http_proxy_client_socket_wrapper.cc
@@ -147,9 +147,9 @@ return false; } -NextProto HttpProxyClientSocketWrapper::GetProtocolNegotiated() const { +NextProto HttpProxyClientSocketWrapper::GetProxyNegotiatedProtocol() const { if (transport_socket_) - return transport_socket_->GetProtocolNegotiated(); + return transport_socket_->GetProxyNegotiatedProtocol(); return kProtoUnknown; } @@ -470,8 +470,8 @@ SSLClientSocket* ssl = static_cast<SSLClientSocket*>(transport_socket_handle_->socket()); - protocol_negotiated_ = ssl->GetNegotiatedProtocol(); - using_spdy_ = protocol_negotiated_ == kProtoHTTP2; + negotiated_protocol_ = ssl->GetNegotiatedProtocol(); + using_spdy_ = negotiated_protocol_ == kProtoHTTP2; // Reset the timer to just the length of time allowed for HttpProxy handshake // so that a fast SSL connection plus a slow HttpProxy failure doesn't take @@ -499,7 +499,7 @@ transport_socket_.reset(new HttpProxyClientSocket( transport_socket_handle_.release(), user_agent_, endpoint_, GetDestination().host_port_pair(), http_auth_controller_.get(), tunnel_, - using_spdy_, protocol_negotiated_, proxy_delegate_, + using_spdy_, negotiated_protocol_, proxy_delegate_, ssl_params_.get() != nullptr)); return transport_socket_->Connect(base::Bind( &HttpProxyClientSocketWrapper::OnIOComplete, base::Unretained(this)));
diff --git a/net/http/http_proxy_client_socket_wrapper.h b/net/http/http_proxy_client_socket_wrapper.h index 6e4bc80..7ecc561b 100644 --- a/net/http/http_proxy_client_socket_wrapper.h +++ b/net/http/http_proxy_client_socket_wrapper.h
@@ -86,7 +86,7 @@ int RestartWithAuth(const CompletionCallback& callback) override; const scoped_refptr<HttpAuthController>& GetAuthController() const override; bool IsUsingSpdy() const override; - NextProto GetProtocolNegotiated() const override; + NextProto GetProxyNegotiatedProtocol() const override; // StreamSocket implementation. int Connect(const CompletionCallback& callback) override; @@ -185,7 +185,7 @@ ProxyDelegate* const proxy_delegate_; bool using_spdy_; - NextProto protocol_negotiated_; + NextProto negotiated_protocol_; std::unique_ptr<HttpResponseInfo> error_response_info_;
diff --git a/net/http/http_request_headers.cc b/net/http/http_request_headers.cc index ec01446..9a6f1b9 100644 --- a/net/http/http_request_headers.cc +++ b/net/http/http_request_headers.cc
@@ -132,26 +132,22 @@ } const base::StringPiece header_key(header_line.data(), key_end_index); + if (!HttpUtil::IsValidHeaderName(header_key)) { + LOG(DFATAL) << "\"" << header_line << "\" has invalid header key."; + return; + } const std::string::size_type value_index = key_end_index + 1; if (value_index < header_line.size()) { - std::string header_value(header_line.data() + value_index, - header_line.size() - value_index); - std::string::const_iterator header_value_begin = - header_value.begin(); - std::string::const_iterator header_value_end = - header_value.end(); - HttpUtil::TrimLWS(&header_value_begin, &header_value_end); - - if (header_value_begin == header_value_end) { - // Value was all LWS. - SetHeader(header_key, ""); - } else { - SetHeader(header_key, - base::StringPiece(&*header_value_begin, - header_value_end - header_value_begin)); + base::StringPiece header_value(header_line.data() + value_index, + header_line.size() - value_index); + header_value = HttpUtil::TrimLWS(header_value); + if (!HttpUtil::IsValidHeaderValue(header_value)) { + LOG(DFATAL) << "\"" << header_line << "\" has invalid header value."; + return; } + SetHeader(header_key, header_value); } else if (value_index == header_line.size()) { SetHeader(header_key, ""); } else {
diff --git a/net/http/http_request_headers.h b/net/http/http_request_headers.h index 62ec37ca..5efa5b5b 100644 --- a/net/http/http_request_headers.h +++ b/net/http/http_request_headers.h
@@ -100,6 +100,8 @@ // Sets the header value pair for |key| and |value|. If |key| already exists, // then the header value is modified, but the key is untouched, and the order // in the vector remains the same. When comparing |key|, case is ignored. + // The caller must ensure that |key| passes HttpUtil::IsValidHeaderName() and + // |value| passes HttpUtil::IsValidHeaderValue(). void SetHeader(const base::StringPiece& key, const base::StringPiece& value); // Sets the header value pair for |key| and |value|, if |key| does not exist.
diff --git a/net/http/http_server_properties_impl.cc b/net/http/http_server_properties_impl.cc index 90eee30..11f5e3fb 100644 --- a/net/http/http_server_properties_impl.cc +++ b/net/http/http_server_properties_impl.cc
@@ -112,7 +112,7 @@ url::SchemeHostPort canonical_server(kCanonicalScheme, canonical_suffix, kCanonicalPort); // If we already have a valid canonical server, we're done. - if (ContainsKey(canonical_host_to_origin_map_, canonical_server) && + if (base::ContainsKey(canonical_host_to_origin_map_, canonical_server) && (alternative_service_map_.Peek( canonical_host_to_origin_map_[canonical_server]) != alternative_service_map_.end())) { @@ -492,7 +492,8 @@ void HttpServerPropertiesImpl::MarkAlternativeServiceRecentlyBroken( const AlternativeService& alternative_service) { - if (!ContainsKey(recently_broken_alternative_services_, alternative_service)) + if (!base::ContainsKey(recently_broken_alternative_services_, + alternative_service)) recently_broken_alternative_services_[alternative_service] = 1; } @@ -500,15 +501,15 @@ const AlternativeService& alternative_service) const { // Empty host means use host of origin, callers are supposed to substitute. DCHECK(!alternative_service.host.empty()); - return ContainsKey(broken_alternative_services_, alternative_service); + return base::ContainsKey(broken_alternative_services_, alternative_service); } bool HttpServerPropertiesImpl::WasAlternativeServiceRecentlyBroken( const AlternativeService& alternative_service) { if (alternative_service.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) return false; - return ContainsKey(recently_broken_alternative_services_, - alternative_service); + return base::ContainsKey(recently_broken_alternative_services_, + alternative_service); } void HttpServerPropertiesImpl::ConfirmAlternativeService(
diff --git a/net/http/http_stream_factory.h b/net/http/http_stream_factory.h index fe81822..d6e7127 100644 --- a/net/http/http_stream_factory.h +++ b/net/http/http_stream_factory.h
@@ -184,7 +184,7 @@ virtual bool was_npn_negotiated() const = 0; // Protocol negotiated with the server. - virtual NextProto protocol_negotiated() const = 0; + virtual NextProto negotiated_protocol() const = 0; // Returns true if this stream is being fetched over SPDY. virtual bool using_spdy() const = 0;
diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc index 3772a9f6..ddea41b 100644 --- a/net/http/http_stream_factory_impl.cc +++ b/net/http/http_stream_factory_impl.cc
@@ -172,7 +172,7 @@ const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, bool was_npn_negotiated, - NextProto protocol_negotiated, + NextProto negotiated_protocol, bool using_spdy, const BoundNetLog& net_log) { while (true) { @@ -186,10 +186,10 @@ // TODO(willchan): If it's important, switch RequestSet out for a FIFO // queue (Order by priority first, then FIFO within same priority). Unclear // that it matters here. - if (!ContainsKey(spdy_session_request_map_, spdy_session_key)) + if (!base::ContainsKey(spdy_session_request_map_, spdy_session_key)) break; Request* request = *spdy_session_request_map_[spdy_session_key].begin(); - request->Complete(was_npn_negotiated, protocol_negotiated, using_spdy); + request->Complete(was_npn_negotiated, negotiated_protocol, using_spdy); if (for_websockets_) { // TODO(ricea): Restore this code path when WebSocket over SPDY // implementation is ready.
diff --git a/net/http/http_stream_factory_impl.h b/net/http/http_stream_factory_impl.h index ed5a9c4..ba0dd41 100644 --- a/net/http/http_stream_factory_impl.h +++ b/net/http/http_stream_factory_impl.h
@@ -111,7 +111,7 @@ const SSLConfig& used_ssl_config, const ProxyInfo& used_proxy_info, bool was_npn_negotiated, - NextProto protocol_negotiated, + NextProto negotiated_protocol, bool using_spdy, const BoundNetLog& net_log);
diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc index f74561b..f444f29d 100644 --- a/net/http/http_stream_factory_impl_job.cc +++ b/net/http/http_stream_factory_impl_job.cc
@@ -132,14 +132,12 @@ // Returns parameters associated with the Proto (with NPN negotiation) of a HTTP // stream. std::unique_ptr<base::Value> NetLogHttpStreamProtoCallback( - const SSLClientSocket::NextProtoStatus status, - const std::string* proto, + NextProto negotiated_protocol, NetLogCaptureMode /* capture_mode */) { std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - dict->SetString("next_proto_status", - SSLClientSocket::NextProtoStatusToString(status)); - dict->SetString("proto", *proto); + dict->SetString("proto", + SSLClientSocket::NextProtoToString(negotiated_protocol)); return std::move(dict); } @@ -199,7 +197,7 @@ spdy_certificate_error_(OK), establishing_tunnel_(false), was_npn_negotiated_(false), - protocol_negotiated_(kProtoUnknown), + negotiated_protocol_(kProtoUnknown), num_streams_(0), spdy_session_direct_(false), job_status_(STATUS_RUNNING), @@ -306,8 +304,8 @@ return was_npn_negotiated_; } -NextProto HttpStreamFactoryImpl::Job::protocol_negotiated() const { - return protocol_negotiated_; +NextProto HttpStreamFactoryImpl::Job::negotiated_protocol() const { + return negotiated_protocol_; } bool HttpStreamFactoryImpl::Job::using_spdy() const { @@ -364,9 +362,6 @@ DCHECK_NE(job_type_, PRECONNECT); DCHECK(!delegate_->for_websockets()); - UMA_HISTOGRAM_TIMES("Net.HttpStreamFactoryJob.StreamReadyCallbackTime", - base::TimeTicks::Now() - job_stream_ready_start_time_); - MaybeCopyConnectionAttemptsFromSocketOrHandle(); delegate_->OnStreamReady(this, server_ssl_config_, proxy_info_); @@ -587,7 +582,6 @@ } } else { DCHECK(stream_.get()); - job_stream_ready_start_time_ = base::TimeTicks::Now(); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(&Job::OnStreamReadyCallback, ptr_factory_.GetWeakPtr())); @@ -707,28 +701,8 @@ return OK; } - // TODO(rch): remove this code since Alt-Svc seems to prohibit it. - GURL url_for_proxy = origin_url_; - // For SPDY via Alt-Svc, set |alternative_service_url_| to - // https://<alternative host>:<alternative port>/... - // so the proxy resolution works with the actual destination, and so - // that the correct socket pool is used. - if (IsSpdyAlternative()) { - // TODO(rch): Figure out how to make QUIC iteract with PAC - // scripts. By not re-writing the URL, we will query the PAC script - // for the proxy to use to reach the original URL via TCP. But - // the alternate request will be going via UDP to a different port. - GURL::Replacements replacements; - // new_port needs to be in scope here because GURL::Replacements references - // the memory contained by it directly. - const std::string new_port = base::UintToString(alternative_service_.port); - replacements.SetSchemeStr("https"); - replacements.SetPortStr(new_port); - url_for_proxy = url_for_proxy.ReplaceComponents(replacements); - } - return session_->proxy_service()->ResolveProxy( - url_for_proxy, request_info_.method, &proxy_info_, io_callback_, + origin_url_, request_info_.method, &proxy_info_, io_callback_, &pac_request_, session_->params().proxy_delegate, net_log_); } @@ -769,10 +743,10 @@ bool HttpStreamFactoryImpl::Job::ShouldForceQuic() const { return session_->params().enable_quic && - (ContainsKey(session_->params().origins_to_force_quic_on, - HostPortPair()) || - ContainsKey(session_->params().origins_to_force_quic_on, - destination_)) && + (base::ContainsKey(session_->params().origins_to_force_quic_on, + HostPortPair()) || + base::ContainsKey(session_->params().origins_to_force_quic_on, + destination_)) && proxy_info_.is_direct() && origin_url_.SchemeIs("https"); } @@ -1009,22 +983,17 @@ if (ssl_started && (result == OK || IsCertificateError(result))) { if (using_quic_ && result == OK) { was_npn_negotiated_ = true; - protocol_negotiated_ = - SSLClientSocket::NextProtoFromString("quic/1+spdy/3"); + negotiated_protocol_ = kProtoQUIC1SPDY3; } else { SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(connection_->socket()); if (ssl_socket->WasNpnNegotiated()) { was_npn_negotiated_ = true; - std::string proto; - SSLClientSocket::NextProtoStatus status = - ssl_socket->GetNextProto(&proto); - protocol_negotiated_ = SSLClientSocket::NextProtoFromString(proto); + negotiated_protocol_ = ssl_socket->GetNegotiatedProtocol(); net_log_.AddEvent( NetLog::TYPE_HTTP_STREAM_REQUEST_PROTO, - base::Bind(&NetLogHttpStreamProtoCallback, - status, &proto)); - if (protocol_negotiated_ == kProtoHTTP2) + base::Bind(&NetLogHttpStreamProtoCallback, negotiated_protocol_)); + if (negotiated_protocol_ == kProtoHTTP2) SwitchToSpdyMode(); } } @@ -1034,7 +1003,7 @@ static_cast<ProxyClientSocket*>(connection_->socket()); if (proxy_socket->IsUsingSpdy()) { was_npn_negotiated_ = true; - protocol_negotiated_ = proxy_socket->GetProtocolNegotiated(); + negotiated_protocol_ = proxy_socket->GetProxyNegotiatedProtocol(); SwitchToSpdyMode(); } } @@ -1228,10 +1197,7 @@ } SSLInfo ssl_info; - bool was_npn_negotiated; - NextProto protocol_negotiated; - if (spdy_session->GetSSLInfo(&ssl_info, &was_npn_negotiated, - &protocol_negotiated)) { + if (spdy_session->GetSSLInfo(&ssl_info)) { UMA_HISTOGRAM_SPARSE_SLOWLY( "Net.Http2SSLCipherSuite", SSLConnectionStatusToCipherSuite(ssl_info.connection_status));
diff --git a/net/http/http_stream_factory_impl_job.h b/net/http/http_stream_factory_impl_job.h index e6cbd47a..02d7054 100644 --- a/net/http/http_stream_factory_impl_job.h +++ b/net/http/http_stream_factory_impl_job.h
@@ -195,7 +195,7 @@ RequestPriority priority() const { return priority_; } bool was_npn_negotiated() const; - NextProto protocol_negotiated() const; + NextProto negotiated_protocol() const; bool using_spdy() const; const BoundNetLog& net_log() const { return net_log_; } HttpStreamRequest::StreamType stream_type() const { return stream_type_; } @@ -448,7 +448,7 @@ bool was_npn_negotiated_; // Protocol negotiated with the server. - NextProto protocol_negotiated_; + NextProto negotiated_protocol_; // 0 if we're not preconnecting. Otherwise, the number of streams to // preconnect. @@ -465,7 +465,6 @@ JobStatus job_status_; JobStatus other_job_status_; - base::TimeTicks job_stream_ready_start_time_; // Type of stream that is requested. HttpStreamRequest::StreamType stream_type_;
diff --git a/net/http/http_stream_factory_impl_job_controller.cc b/net/http/http_stream_factory_impl_job_controller.cc index 2daf8419..f526618a 100644 --- a/net/http/http_stream_factory_impl_job_controller.cc +++ b/net/http/http_stream_factory_impl_job_controller.cc
@@ -170,7 +170,7 @@ std::unique_ptr<HttpStream> stream = job->ReleaseStream(); DCHECK(stream); - MarkRequestComplete(job->was_npn_negotiated(), job->protocol_negotiated(), + MarkRequestComplete(job->was_npn_negotiated(), job->negotiated_protocol(), job->using_spdy()); if (!request_) @@ -193,7 +193,7 @@ return; } - MarkRequestComplete(job->was_npn_negotiated(), job->protocol_negotiated(), + MarkRequestComplete(job->was_npn_negotiated(), job->negotiated_protocol(), job->using_spdy()); if (!request_) @@ -216,7 +216,7 @@ WebSocketHandshakeStreamBase* stream) { DCHECK(job); - MarkRequestComplete(job->was_npn_negotiated(), job->protocol_negotiated(), + MarkRequestComplete(job->was_npn_negotiated(), job->negotiated_protocol(), job->using_spdy()); if (!request_) @@ -368,7 +368,7 @@ const SSLConfig used_ssl_config = job->server_ssl_config(); const ProxyInfo used_proxy_info = job->proxy_info(); const bool was_npn_negotiated = job->was_npn_negotiated(); - const NextProto protocol_negotiated = job->protocol_negotiated(); + const NextProto negotiated_protocol = job->negotiated_protocol(); const bool using_spdy = job->using_spdy(); const BoundNetLog net_log = job->net_log(); @@ -384,7 +384,7 @@ BindJob(job); } - MarkRequestComplete(was_npn_negotiated, protocol_negotiated, using_spdy); + MarkRequestComplete(was_npn_negotiated, negotiated_protocol, using_spdy); std::unique_ptr<HttpStream> stream; std::unique_ptr<BidirectionalStreamImpl> bidirectional_stream_impl; @@ -411,7 +411,7 @@ if (spdy_session && spdy_session->IsAvailable()) { factory->OnNewSpdySessionReady(spdy_session, direct, used_ssl_config, used_proxy_info, was_npn_negotiated, - protocol_negotiated, using_spdy, net_log); + negotiated_protocol, using_spdy, net_log); } if (is_job_orphaned) { OnOrphanedJobComplete(job); @@ -515,7 +515,7 @@ if (!request_->HasSpdySessionKey()) { RequestSet& request_set = factory_->spdy_session_request_map_[spdy_session_key]; - DCHECK(!ContainsKey(request_set, request_)); + DCHECK(!base::ContainsKey(request_set, request_)); request_set.insert(request_); request_->SetSpdySessionKey(spdy_session_key); } @@ -536,9 +536,9 @@ if (spdy_session_key) { SpdySessionRequestMap& spdy_session_request_map = factory_->spdy_session_request_map_; - DCHECK(ContainsKey(spdy_session_request_map, *spdy_session_key)); + DCHECK(base::ContainsKey(spdy_session_request_map, *spdy_session_key)); RequestSet& request_set = spdy_session_request_map[*spdy_session_key]; - DCHECK(ContainsKey(request_set, request_)); + DCHECK(base::ContainsKey(request_set, request_)); request_set.erase(request_); if (request_set.empty()) spdy_session_request_map.erase(*spdy_session_key); @@ -705,10 +705,10 @@ void HttpStreamFactoryImpl::JobController::MarkRequestComplete( bool was_npn_negotiated, - NextProto protocol_negotiated, + NextProto negotiated_protocol, bool using_spdy) { if (request_) - request_->Complete(was_npn_negotiated, protocol_negotiated, using_spdy); + request_->Complete(was_npn_negotiated, negotiated_protocol, using_spdy); } void HttpStreamFactoryImpl::JobController::MaybeNotifyFactoryOfCompletion() { @@ -750,8 +750,8 @@ if (session_->params().transport_security_state->IsGooglePinnedHost(host)) return true; - return ContainsKey(session_->params().quic_host_whitelist, - base::ToLowerASCII(host)); + return base::ContainsKey(session_->params().quic_host_whitelist, + base::ToLowerASCII(host)); } AlternativeService
diff --git a/net/http/http_stream_factory_impl_job_controller.h b/net/http/http_stream_factory_impl_job_controller.h index 331ed06..c19b6791 100644 --- a/net/http/http_stream_factory_impl_job_controller.h +++ b/net/http/http_stream_factory_impl_job_controller.h
@@ -189,7 +189,7 @@ // Marks completion of the |request_|. void MarkRequestComplete(bool was_npn_negotiated, - NextProto protocol_negotiated, + NextProto negotiated_protocol, bool using_spdy); void MaybeNotifyFactoryOfCompletion();
diff --git a/net/http/http_stream_factory_impl_request.cc b/net/http/http_stream_factory_impl_request.cc index 09962039..9933bd27 100644 --- a/net/http/http_stream_factory_impl_request.cc +++ b/net/http/http_stream_factory_impl_request.cc
@@ -30,7 +30,7 @@ net_log_(net_log), completed_(false), was_npn_negotiated_(false), - protocol_negotiated_(kProtoUnknown), + negotiated_protocol_(kProtoUnknown), using_spdy_(false), stream_type_(stream_type) { DCHECK(delegate_); @@ -49,12 +49,12 @@ } void HttpStreamFactoryImpl::Request::Complete(bool was_npn_negotiated, - NextProto protocol_negotiated, + NextProto negotiated_protocol, bool using_spdy) { DCHECK(!completed_); completed_ = true; was_npn_negotiated_ = was_npn_negotiated; - protocol_negotiated_ = protocol_negotiated; + negotiated_protocol_ = negotiated_protocol; using_spdy_ = using_spdy; } @@ -139,10 +139,9 @@ return was_npn_negotiated_; } -NextProto HttpStreamFactoryImpl::Request::protocol_negotiated() - const { +NextProto HttpStreamFactoryImpl::Request::negotiated_protocol() const { DCHECK(completed_); - return protocol_negotiated_; + return negotiated_protocol_; } bool HttpStreamFactoryImpl::Request::using_spdy() const {
diff --git a/net/http/http_stream_factory_impl_request.h b/net/http/http_stream_factory_impl_request.h index 5eab8d82..90a7e16 100644 --- a/net/http/http_stream_factory_impl_request.h +++ b/net/http/http_stream_factory_impl_request.h
@@ -71,7 +71,7 @@ // Marks completion of the request. Must be called before OnStreamReady(). void Complete(bool was_npn_negotiated, - NextProto protocol_negotiated, + NextProto negotiated_protocol, bool using_spdy); void ResetSpdySessionKey(); @@ -120,7 +120,7 @@ void SetPriority(RequestPriority priority) override; LoadState GetLoadState() const override; bool was_npn_negotiated() const override; - NextProto protocol_negotiated() const override; + NextProto negotiated_protocol() const override; bool using_spdy() const override; const ConnectionAttempts& connection_attempts() const override; HttpStreamRequest::StreamType stream_type() const { return stream_type_; } @@ -144,7 +144,7 @@ bool completed_; bool was_npn_negotiated_; // Protocol negotiated with the server. - NextProto protocol_negotiated_; + NextProto negotiated_protocol_; bool using_spdy_; ConnectionAttempts connection_attempts_;
diff --git a/net/http/http_stream_factory_impl_unittest.cc b/net/http/http_stream_factory_impl_unittest.cc index 5886821..2448768 100644 --- a/net/http/http_stream_factory_impl_unittest.cc +++ b/net/http/http_stream_factory_impl_unittest.cc
@@ -796,7 +796,7 @@ public: MockQuicData() : packet_number_(0) {} - ~MockQuicData() { STLDeleteElements(&packets_); } + ~MockQuicData() { base::STLDeleteElements(&packets_); } void AddRead(std::unique_ptr<QuicEncryptedPacket> packet) { reads_.push_back( @@ -1442,7 +1442,7 @@ session_deps.socket_factory->AddSocketDataProvider(&socket_data); SSLSocketDataProvider ssl_socket_data(ASYNC, OK); - ssl_socket_data.SetNextProto(kProtoHTTP2); + ssl_socket_data.next_proto = kProtoHTTP2; session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); HostPortPair host_port_pair("www.google.com", 443); @@ -1488,7 +1488,7 @@ session_deps.socket_factory->AddSocketDataProvider(&socket_data); SSLSocketDataProvider ssl_socket_data(ASYNC, OK); - ssl_socket_data.SetNextProto(kProtoHTTP2); + ssl_socket_data.next_proto = kProtoHTTP2; session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); HostPortPair host_port_pair("www.google.com", 443); @@ -1629,7 +1629,7 @@ INSTANTIATE_TEST_CASE_P(Version, HttpStreamFactoryBidirectionalQuicTest, - ::testing::ValuesIn(QuicSupportedVersions())); + ::testing::ValuesIn(AllSupportedVersions())); TEST_P(HttpStreamFactoryBidirectionalQuicTest, RequestBidirectionalStreamImplQuicAlternative) { @@ -1846,7 +1846,7 @@ SSLSocketDataProvider ssl_socket_data(ASYNC, OK); // If HTTP/1 is used, BidirectionalStreamImpl should not be obtained. - ssl_socket_data.SetNextProto(kProtoHTTP11); + ssl_socket_data.next_proto = kProtoHTTP11; session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); HostPortPair host_port_pair("www.google.com", 443); @@ -1939,7 +1939,7 @@ session_deps.socket_factory->AddSocketDataProvider(&socket_data); SSLSocketDataProvider ssl_socket_data(ASYNC, OK); - ssl_socket_data.SetNextProto(kProtoHTTP2); + ssl_socket_data.next_proto = kProtoHTTP2; session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); HostPortPair host_port_pair("www.google.com", 80); @@ -2011,7 +2011,7 @@ session_deps.socket_factory->AddSocketDataProvider(&socket_data2); SSLSocketDataProvider ssl_socket_data(ASYNC, OK); - ssl_socket_data.SetNextProto(kProtoHTTP2); + ssl_socket_data.next_proto = kProtoHTTP2; session_deps.socket_factory->AddSSLSocketDataProvider(&ssl_socket_data); std::unique_ptr<HttpNetworkSession> session(
diff --git a/net/http/http_util.cc b/net/http/http_util.cc index 313da11..cb7913b 100644 --- a/net/http/http_util.cc +++ b/net/http/http_util.cc
@@ -20,6 +20,19 @@ namespace net { +namespace { +template <typename ConstIterator> +void TrimLWSImplementation(ConstIterator* begin, ConstIterator* end) { + // leading whitespace + while (*begin < *end && HttpUtil::IsLWS((*begin)[0])) + ++(*begin); + + // trailing whitespace + while (*begin < *end && HttpUtil::IsLWS((*end)[-1])) + --(*end); +} +} // namespace + // Helpers -------------------------------------------------------------------- // Returns the index of the closing quote of the string, if any. |start| points @@ -340,15 +353,19 @@ } // static -bool HttpUtil::IsValidHeaderName(const std::string& name) { +bool HttpUtil::IsValidHeaderName(const base::StringPiece& name) { // Check whether the header name is RFC 2616-compliant. return HttpUtil::IsToken(name); } // static -bool HttpUtil::IsValidHeaderValue(const std::string& value) { +bool HttpUtil::IsValidHeaderValue(const base::StringPiece& value) { // Just a sanity check: disallow NUL, CR and LF. - return value.find_first_of("\0\r\n", 0, 3) == std::string::npos; + for (char c : value) { + if (c == '\0' || c == '\r' || c == '\n') + return false; + } + return true; } // static @@ -409,15 +426,18 @@ return strchr(HTTP_LWS, c) != NULL; } +// static void HttpUtil::TrimLWS(std::string::const_iterator* begin, std::string::const_iterator* end) { - // leading whitespace - while (*begin < *end && IsLWS((*begin)[0])) - ++(*begin); + TrimLWSImplementation(begin, end); +} - // trailing whitespace - while (*begin < *end && IsLWS((*end)[-1])) - --(*end); +// static +base::StringPiece HttpUtil::TrimLWS(const base::StringPiece& string) { + const char* begin = string.data(); + const char* end = string.data() + string.size(); + TrimLWSImplementation(&begin, &end); + return base::StringPiece(begin, end - begin); } bool HttpUtil::IsQuote(char c) { @@ -437,12 +457,11 @@ } // anonymous namespace // See RFC 2616 Sec 2.2 for the definition of |token|. -bool HttpUtil::IsToken(std::string::const_iterator begin, - std::string::const_iterator end) { - if (begin == end) +bool HttpUtil::IsToken(const base::StringPiece& string) { + if (string.empty()) return false; - for (std::string::const_iterator iter = begin; iter != end; ++iter) { - if (!IsTokenChar(*iter)) + for (char c : string) { + if (!IsTokenChar(c)) return false; } return true; @@ -891,7 +910,8 @@ continue; TrimLWS(&name_begin_, &name_end_); - if (!IsToken(name_begin_, name_end_)) + DCHECK(name_begin_ < name_end_); + if (!IsToken(base::StringPiece(name_begin_, name_end_))) continue; // skip malformed header values_begin_ = colon + 1;
diff --git a/net/http/http_util.h b/net/http/http_util.h index 77706f1a..527f659 100644 --- a/net/http/http_util.h +++ b/net/http/http_util.h
@@ -12,6 +12,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/strings/string_piece.h" #include "base/strings/string_tokenizer.h" #include "base/time/time.h" #include "net/base/net_export.h" @@ -77,11 +78,11 @@ static bool IsSafeHeader(const std::string& name); // Returns true if |name| is a valid HTTP header name. - static bool IsValidHeaderName(const std::string& name); + static bool IsValidHeaderName(const base::StringPiece& name); // Returns false if |value| contains NUL or CRLF. This method does not perform // a fully RFC-2616-compliant header value validation. - static bool IsValidHeaderValue(const std::string& value); + static bool IsValidHeaderValue(const base::StringPiece& value); // Strips all header lines from |headers| whose name matches // |headers_to_remove|. |headers_to_remove| is a list of null-terminated @@ -108,16 +109,13 @@ // Trim HTTP_LWS chars from the beginning and end of the string. static void TrimLWS(std::string::const_iterator* begin, std::string::const_iterator* end); + static base::StringPiece TrimLWS(const base::StringPiece& string); // Whether the character is the start of a quotation mark. static bool IsQuote(char c); // Whether the string is a valid |token| as defined in RFC 2616 Sec 2.2. - static bool IsToken(std::string::const_iterator begin, - std::string::const_iterator end); - static bool IsToken(const std::string& str) { - return IsToken(str.begin(), str.end()); - } + static bool IsToken(const base::StringPiece& str); // Whether the string is a valid |parmname| as defined in RFC 5987 Sec 3.2.1. static bool IsParmName(std::string::const_iterator begin,
diff --git a/net/http/http_util_unittest.cc b/net/http/http_util_unittest.cc index 94fde66..4a1257d 100644 --- a/net/http/http_util_unittest.cc +++ b/net/http/http_util_unittest.cc
@@ -1392,4 +1392,11 @@ EXPECT_TRUE(HttpUtil::IsValidHeaderValue(allowed)); } +TEST(HttpUtilTest, IsToken) { + EXPECT_TRUE(HttpUtil::IsToken("valid")); + EXPECT_FALSE(HttpUtil::IsToken("")); + EXPECT_FALSE(HttpUtil::IsToken(base::StringPiece())); + EXPECT_FALSE(HttpUtil::IsToken("hello, world")); +} + } // namespace net
diff --git a/net/http/proxy_client_socket.h b/net/http/proxy_client_socket.h index b240689b..ce26719e 100644 --- a/net/http/proxy_client_socket.h +++ b/net/http/proxy_client_socket.h
@@ -52,7 +52,7 @@ virtual bool IsUsingSpdy() const = 0; // Returns the protocol negotiated with the proxy. - virtual NextProto GetProtocolNegotiated() const = 0; + virtual NextProto GetProxyNegotiatedProtocol() const = 0; protected: // The HTTP CONNECT method for establishing a tunnel connection is documented
diff --git a/net/log/bounded_file_net_log_observer.cc b/net/log/bounded_file_net_log_observer.cc index 6f31c54..9098caf1 100644 --- a/net/log/bounded_file_net_log_observer.cc +++ b/net/log/bounded_file_net_log_observer.cc
@@ -176,6 +176,7 @@ base::Unretained(file_writer_))); net_log()->DeprecatedRemoveObserver(this); } + task_runner_->DeleteSoon(FROM_HERE, file_writer_); } @@ -203,7 +204,9 @@ // |file_writer_| may write more events to file than can be contained by the // |write_queue_| if they have the same size limit. The maximum size of the // |write_queue_| is doubled to allow the |queue_| to hold enough events for - // the |file_writer_| to fill all files. + // the |file_writer_| to fill all files. As long as all events have sizes <= + // the size of an individual event file, the discrepancy between the hard + // limit and the soft limit will not cause an issue. // TODO(dconnol): Handle the case when the |write_queue_| still doesn't // contain enough events to fill all files, because of very large events // relative to file size. @@ -226,18 +229,20 @@ } void BoundedFileNetLogObserver::StopObserving( - URLRequestContext* url_request_context) { + URLRequestContext* url_request_context, + const base::Closure& callback) { task_runner_->PostTask( FROM_HERE, base::Bind(&BoundedFileNetLogObserver::FileWriter::Flush, base::Unretained(file_writer_), write_queue_)); - task_runner_->PostTask( + task_runner_->PostTaskAndReply( FROM_HERE, base::Bind(&BoundedFileNetLogObserver::FileWriter::Stop, base::Unretained(file_writer_), base::Passed(url_request_context ? GetNetInfo(url_request_context, NET_INFO_ALL_SOURCES) - : nullptr))); + : nullptr)), + callback); net_log()->DeprecatedRemoveObserver(this); }
diff --git a/net/log/bounded_file_net_log_observer.h b/net/log/bounded_file_net_log_observer.h index c3eb9e1f..1939b14 100644 --- a/net/log/bounded_file_net_log_observer.h +++ b/net/log/bounded_file_net_log_observer.h
@@ -88,12 +88,15 @@ // NetLog, or the NetLog files will be deleted when the observer is // destroyed. // + // |callback| will be run on whichever thread StopObserving() was called on + // once all file writing is complete and the netlog files can be accessed + // safely. + // // |url_request_context| is an optional argument used to add additional // network stack state to the log. If the context is non-NULL, // StopObserving() must be called on the context's thread. - // - // TODO (dconnol): Add callback to verify that logging is complete. - void StopObserving(URLRequestContext* url_request_context); + void StopObserving(URLRequestContext* url_request_context, + const base::Closure& callback); // NetLog::ThreadSafeObserver void OnAddEntry(const NetLog::Entry& entry) override;
diff --git a/net/log/bounded_file_net_log_observer_unittest.cc b/net/log/bounded_file_net_log_observer_unittest.cc index ffce266..fe20aae0 100644 --- a/net/log/bounded_file_net_log_observer_unittest.cc +++ b/net/log/bounded_file_net_log_observer_unittest.cc
@@ -18,6 +18,7 @@ #include "base/json/json_writer.h" #include "base/strings/string_util.h" #include "base/values.h" +#include "net/base/test_completion_callback.h" #include "net/log/net_log.h" #include "net/log/net_log_util.h" #include "net/url_request/url_request.h" @@ -163,11 +164,13 @@ } TEST_F(BoundedFileNetLogObserverTest, GeneratesValidJSONForNoEvents) { + TestClosure closure; + logger_->StartObserving(&net_log_, log_path_, nullptr, nullptr, kLargeFileSize, kTotalNumFiles); - logger_->StopObserving(nullptr); - logger_.reset(); - file_thread_.reset(); + logger_->StopObserving(nullptr, closure.closure()); + + closure.WaitForResult(); std::string input; AddAllFiles(&input); @@ -193,13 +196,16 @@ // Checks that capture_mode_ defaults correctly when set_capture_mode is not // called, and that |capture_mode_| is changed when set_capture_mode is called. TEST_F(BoundedFileNetLogObserverTest, SetsCaptureMode) { + TestClosure default_closure; + logger_->StartObserving(&net_log_, log_path_, nullptr, nullptr, kLargeFileSize, kTotalNumFiles); EXPECT_EQ(NetLogCaptureMode::Default(), logger_->capture_mode()); - logger_->StopObserving(nullptr); + logger_->StopObserving(nullptr, default_closure.closure()); - logger_.reset(); + default_closure.WaitForResult(); + TestClosure new_capture_mode_closure; logger_ = std::unique_ptr<BoundedFileNetLogObserver>( new BoundedFileNetLogObserver(file_thread_->task_runner())); @@ -208,10 +214,9 @@ kLargeFileSize, kTotalNumFiles); EXPECT_EQ(NetLogCaptureMode::IncludeCookiesAndCredentials(), logger_->capture_mode()); - logger_->StopObserving(nullptr); + logger_->StopObserving(nullptr, new_capture_mode_closure.closure()); - logger_.reset(); - file_thread_.reset(); + new_capture_mode_closure.WaitForResult(); std::string input; AddAllFiles(&input); @@ -219,15 +224,17 @@ } TEST_F(BoundedFileNetLogObserverTest, GeneratesValidJSONWithOneEvent) { + TestClosure closure; + logger_->StartObserving(&net_log_, log_path_, nullptr, nullptr, kLargeFileSize, kTotalNumFiles); // Send dummy event. AddEntries(1, kDummyEventSize); - logger_->StopObserving(nullptr); - logger_.reset(); - file_thread_.reset(); + logger_->StopObserving(nullptr, closure.closure()); + + closure.WaitForResult(); std::string input; AddAllFiles(&input); @@ -249,15 +256,16 @@ TEST_F(BoundedFileNetLogObserverTest, GeneratesValidJSONWithMultipleEvents) { const int kTotalFileSize = 250000; + TestClosure closure; logger_->StartObserving(&net_log_, log_path_, nullptr, nullptr, kTotalFileSize, kTotalNumFiles); AddEntries(2, kDummyEventSize); - logger_->StopObserving(nullptr); - logger_.reset(); - file_thread_.reset(); + logger_->StopObserving(nullptr, closure.closure()); + + closure.WaitForResult(); std::string input; AddAllFiles(&input); @@ -283,14 +291,15 @@ const int kTotalFileSize = 5000; const int kNumEvents = 2; const int kEventSize = 250; + TestClosure closure; logger_->StartObserving(&net_log_, log_path_, nullptr, nullptr, kTotalFileSize, kTotalNumFiles); AddEntries(kNumEvents, kEventSize); - logger_->StopObserving(nullptr); - logger_.reset(); - file_thread_.reset(); + logger_->StopObserving(nullptr, closure.closure()); + + closure.WaitForResult(); std::string input; AddAllFiles(&input); @@ -343,15 +352,16 @@ const int kTotalFileSize = 6000; const int kNumEvents = 4; const int kEventSize = 200; + TestClosure closure; logger_->StartObserving(&net_log_, log_path_, nullptr, nullptr, kTotalFileSize, kTotalNumFiles); AddEntries(kNumEvents, kEventSize); - logger_->StopObserving(nullptr); - logger_.reset(); - file_thread_.reset(); + logger_->StopObserving(nullptr, closure.closure()); + + closure.WaitForResult(); std::string input; AddAllFiles(&input); @@ -392,15 +402,16 @@ const int kTotalFileSize = 6000; const int kNumEvents = 6; const int kEventSize = 200; + TestClosure closure; logger_->StartObserving(&net_log_, log_path_, nullptr, nullptr, kTotalFileSize, kTotalNumFiles); AddEntries(kNumEvents, kEventSize); - logger_->StopObserving(nullptr); - logger_.reset(); - file_thread_.reset(); + logger_->StopObserving(nullptr, closure.closure()); + + closure.WaitForResult(); std::string input; AddAllFiles(&input); @@ -456,15 +467,16 @@ const int kEventSize = 200; const int kFileSize = kTotalFileSize / kTotalNumFiles; const int kNumEvents = kTotalNumFiles * ((kFileSize - 1) / kEventSize + 1); + TestClosure closure; logger_->StartObserving(&net_log_, log_path_, nullptr, nullptr, kTotalFileSize, kTotalNumFiles); AddEntries(kNumEvents, kEventSize); - logger_->StopObserving(nullptr); - logger_.reset(); - file_thread_.reset(); + logger_->StopObserving(nullptr, closure.closure()); + + closure.WaitForResult(); std::string input; AddAllFiles(&input); @@ -513,15 +525,16 @@ const int kNumEvents = 11; const int kEventSize = 200; const int kFileSize = kTotalFileSize / kTotalNumFiles; + TestClosure closure; logger_->StartObserving(&net_log_, log_path_, nullptr, nullptr, kTotalFileSize, kTotalNumFiles); AddEntries(kNumEvents, kEventSize); - logger_->StopObserving(nullptr); - logger_.reset(); - file_thread_.reset(); + logger_->StopObserving(nullptr, closure.closure()); + + closure.WaitForResult(); std::string input; AddAllFiles(&input); @@ -571,15 +584,16 @@ const int kNumEvents = 60; const int kEventSize = 200; const int kFileSize = kTotalFileSize / kTotalNumFiles; + TestClosure closure; logger_->StartObserving(&net_log_, log_path_, nullptr, nullptr, kTotalFileSize, kTotalNumFiles); AddEntries(kNumEvents, kEventSize); - logger_->StopObserving(nullptr); - logger_.reset(); - file_thread_.reset(); + logger_->StopObserving(nullptr, closure.closure()); + + closure.WaitForResult(); std::string input; AddAllFiles(&input); @@ -656,15 +670,16 @@ const int kNumEvents = 50; const int kEventSize = 200; const int kFileSize = kTotalFileSize / kTotalNumFiles; + TestClosure closure; logger_->StartObserving(&net_log_, log_path_, nullptr, nullptr, kTotalFileSize, kTotalNumFiles); AddEntries(kNumEvents, kEventSize); - logger_->StopObserving(nullptr); - logger_.reset(); - file_thread_.reset(); + logger_->StopObserving(nullptr, closure.closure()); + + closure.WaitForResult(); std::string input; AddAllFiles(&input); @@ -716,6 +731,8 @@ } TEST_F(BoundedFileNetLogObserverTest, CustomConstants) { + TestClosure closure; + const char kConstantString[] = "awesome constant"; std::unique_ptr<base::Value> constants( new base::StringValue(kConstantString)); @@ -723,9 +740,9 @@ logger_->StartObserving(&net_log_, log_path_, constants.get(), nullptr, kLargeFileSize, kTotalNumFiles); - logger_->StopObserving(nullptr); - logger_.reset(); - file_thread_.reset(); + logger_->StopObserving(nullptr, closure.closure()); + + closure.WaitForResult(); std::string input; AddAllFiles(&input); @@ -744,6 +761,8 @@ } TEST_F(BoundedFileNetLogObserverTest, GeneratesValidJSONWithContext) { + TestClosure closure; + logger_->StartObserving(&net_log_, log_path_, nullptr, nullptr, kLargeFileSize, kTotalNumFiles); @@ -758,9 +777,9 @@ context.set_http_network_session_params(std::move(params)); context.Init(); - logger_->StopObserving(&context); - logger_.reset(); - file_thread_.reset(); + logger_->StopObserving(&context, closure.closure()); + + closure.WaitForResult(); std::string input; AddAllFiles(&input); @@ -796,11 +815,14 @@ TEST_F(BoundedFileNetLogObserverTest, GeneratesValidJSONWithContextWithActiveRequest) { + TestClosure closure; + // Create context, start a request. TestURLRequestContext context(true); context.set_net_log(&net_log_); context.Init(); TestDelegate delegate; + delegate.set_quit_on_complete(false); // URL doesn't matter. Requests can't fail synchronously. std::unique_ptr<URLRequest> request( @@ -810,9 +832,9 @@ logger_->StartObserving(&net_log_, log_path_, nullptr, &context, kLargeFileSize, kTotalNumFiles); - logger_->StopObserving(&context); - logger_.reset(); - file_thread_.reset(); + logger_->StopObserving(&context, closure.closure()); + + closure.WaitForResult(); std::string input; AddAllFiles(&input);
diff --git a/net/log/stitch_net_log_files.py b/net/log/stitch_net_log_files.py new file mode 100755 index 0000000..922d8520 --- /dev/null +++ b/net/log/stitch_net_log_files.py
@@ -0,0 +1,92 @@ +#!/usr/bin/env python +# Copyright 2016 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 script stitches the NetLog files in a specified directory. + +The complete NetLog will be written to net-internals-log.json in the directory +passed as argument to --path. +''' + +import argparse, os + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--path', action='store', + help="Specifies the complete filepath of the directory where the log " + "files are located.") + # TODO(dconnol): Automatically pull all event files matching the format + # event_file_<num>.json and remove the num_files argument. + parser.add_argument('--num_files', action='store', + help="Specifies the number of event files (not including the constants " + "file or the end_netlog file) that need need to be stitched together. " + "The number of event files passed to the script must not be greater " + "than the number of event files in the directory.") + args = parser.parse_args() + + num_files = int(args.num_files) + filepath = args.path + if filepath[-1:] != "/": + filepath += "/" + + os.chdir(filepath) + + with open("net-internals-log.json", "w") as stitched_file: + try: + file = open("constants.json") + with file: + for line in file: + stitched_file.write(line) + except IOError: + os.remove("net-internals-log.json") + print "File \"constants.json\" not found." + return + + events_written = False; + for i in range(num_files): + try: + file = open("event_file_%d.json" % i) + with file: + if not events_written: + line = file.readline(); + events_written = True + for next_line in file: + if next_line.strip() == "": + line += next_line + else: + stitched_file.write(line) + line = next_line + except IOError: + os.remove("net-internals-log.json") + print "File \"event_file_%d.json\" not found." % i + return + # Remove hanging comma from last event + # TODO(dconnol): Check if the last line is a valid JSON object. If not, + # do not write the line to file. This handles incomplete logs. + line = line.strip() + if line[-1:] == ",": + stitched_file.write(line[:-1]) + elif line: + raise ValueError('Last event is not properly formed') + + try: + file = open("end_netlog.json") + with file: + for line in file: + stitched_file.write(line) + except IOError: + os.remove("net-internals-log.json") + print "File \"end_netlog\" not found." + return + + # Delete old NetLog files + for i in range (num_files): + os.remove("event_file_%d.json" % i) + os.remove("constants.json") + os.remove("end_netlog.json") + + +if __name__ == "__main__": + main()
diff --git a/net/net.gypi b/net/net.gypi index 2fdf6c0..a93cede0 100644 --- a/net/net.gypi +++ b/net/net.gypi
@@ -747,6 +747,7 @@ 'http/url_security_manager_win.cc', 'nqe/cached_network_quality.cc', 'nqe/cached_network_quality.h', + 'nqe/effective_connection_type.cc', 'nqe/effective_connection_type.h', 'nqe/external_estimate_provider.h', 'nqe/network_id.h', @@ -1564,6 +1565,7 @@ 'log/trace_net_log_observer_unittest.cc', 'log/write_to_file_net_log_observer_unittest.cc', 'log/bounded_file_net_log_observer_unittest.cc', + 'nqe/effective_connection_type_unittest.cc', 'nqe/network_quality_estimator_unittest.cc', 'nqe/network_quality_observation_unittest.cc', 'nqe/network_quality_store_unittest.cc', @@ -1708,6 +1710,8 @@ 'quic/test_tools/mock_quic_spdy_client_stream.h', 'quic/test_tools/mock_random.cc', 'quic/test_tools/mock_random.h', + 'quic/test_tools/quic_buffered_packet_store_peer.cc', + 'quic/test_tools/quic_buffered_packet_store_peer.h', 'quic/test_tools/quic_config_peer.cc', 'quic/test_tools/quic_config_peer.h', 'quic/test_tools/quic_connection_peer.cc', @@ -1903,6 +1907,8 @@ 'tools/quic/test_tools/mock_quic_time_wait_list_manager.h', 'tools/quic/test_tools/packet_dropping_test_writer.cc', 'tools/quic/test_tools/packet_dropping_test_writer.h', + 'tools/quic/test_tools/packet_reordering_writer.cc', + 'tools/quic/test_tools/packet_reordering_writer.h', 'tools/quic/test_tools/quic_client_peer.cc', 'tools/quic/test_tools/quic_client_peer.h', 'tools/quic/test_tools/quic_dispatcher_peer.cc',
diff --git a/net/nqe/effective_connection_type.cc b/net/nqe/effective_connection_type.cc new file mode 100644 index 0000000..2996cb101 --- /dev/null +++ b/net/nqe/effective_connection_type.cc
@@ -0,0 +1,81 @@ +// Copyright 2016 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/nqe/effective_connection_type.h" + +#include "base/logging.h" + +namespace { + +const char kEffectiveConnectionTypeUnknown[] = "Unknown"; +const char kEffectiveConnectionTypeOffline[] = "Offline"; +const char kEffectiveConnectionTypeSlow2G[] = "Slow2G"; +const char kEffectiveConnectionType2G[] = "2G"; +const char kEffectiveConnectionType3G[] = "3G"; +const char kEffectiveConnectionType4G[] = "4G"; +const char kEffectiveConnectionTypeBroadband[] = "Broadband"; + +} // namespace + +namespace net { + +const char* GetNameForEffectiveConnectionType(EffectiveConnectionType type) { + switch (type) { + case EFFECTIVE_CONNECTION_TYPE_UNKNOWN: + return kEffectiveConnectionTypeUnknown; + case EFFECTIVE_CONNECTION_TYPE_OFFLINE: + return kEffectiveConnectionTypeOffline; + case EFFECTIVE_CONNECTION_TYPE_SLOW_2G: + return kEffectiveConnectionTypeSlow2G; + case EFFECTIVE_CONNECTION_TYPE_2G: + return kEffectiveConnectionType2G; + case EFFECTIVE_CONNECTION_TYPE_3G: + return kEffectiveConnectionType3G; + case EFFECTIVE_CONNECTION_TYPE_4G: + return kEffectiveConnectionType4G; + case EFFECTIVE_CONNECTION_TYPE_BROADBAND: + return kEffectiveConnectionTypeBroadband; + default: + NOTREACHED(); + break; + } + return ""; +} + +bool GetEffectiveConnectionTypeForName( + const std::string& connection_type_name, + EffectiveConnectionType* effective_connection_type) { + if (connection_type_name == kEffectiveConnectionTypeUnknown) { + *effective_connection_type = EFFECTIVE_CONNECTION_TYPE_UNKNOWN; + return true; + } + if (connection_type_name == kEffectiveConnectionTypeOffline) { + *effective_connection_type = EFFECTIVE_CONNECTION_TYPE_OFFLINE; + return true; + } + if (connection_type_name == kEffectiveConnectionTypeSlow2G) { + *effective_connection_type = EFFECTIVE_CONNECTION_TYPE_SLOW_2G; + return true; + } + if (connection_type_name == kEffectiveConnectionType2G) { + *effective_connection_type = EFFECTIVE_CONNECTION_TYPE_2G; + return true; + } + if (connection_type_name == kEffectiveConnectionType3G) { + *effective_connection_type = EFFECTIVE_CONNECTION_TYPE_3G; + return true; + } + if (connection_type_name == kEffectiveConnectionType4G) { + *effective_connection_type = EFFECTIVE_CONNECTION_TYPE_4G; + return true; + } + if (connection_type_name == kEffectiveConnectionTypeBroadband) { + *effective_connection_type = EFFECTIVE_CONNECTION_TYPE_BROADBAND; + return true; + } + *effective_connection_type = EFFECTIVE_CONNECTION_TYPE_UNKNOWN; + return false; +} + +} // namespace net \ No newline at end of file
diff --git a/net/nqe/effective_connection_type.h b/net/nqe/effective_connection_type.h index 6160a4d..56fdbaf 100644 --- a/net/nqe/effective_connection_type.h +++ b/net/nqe/effective_connection_type.h
@@ -5,6 +5,10 @@ #ifndef NET_NQE_EFFECTIVE_CONNECTION_TYPE_H_ #define NET_NQE_EFFECTIVE_CONNECTION_TYPE_H_ +#include <string> + +#include "net/base/net_export.h" + namespace net { // EffectiveConnectionType is the connection type whose typical performance is @@ -14,19 +18,60 @@ // differently, usually worse, from its expected capabilities. // EffectiveConnectionType of a network is independent of if the current // connection is metered or not. For example, an unmetered slow connection may -// have EFFECTIVE_CONNECTION_TYPE_SLOW_2G as its effective connection type. +// have EFFECTIVE_CONNECTION_TYPE_SLOW_2G as its effective connection type. The +// effective connection type enums are be in increasing order of quality. +// An invalid Java prefix to strip is specified to prevent the Java class +// generator from automatically stripping off the common prefix +// ("EFFECTIVE_CONNECTION_TYPE_"). +// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.net +// GENERATED_JAVA_PREFIX_TO_STRIP: PREFIX_NOT_PRESENT_ enum EffectiveConnectionType { - // The connection types should be in increasing order of quality. + // Effective connection type reported when the network quality is unknown. EFFECTIVE_CONNECTION_TYPE_UNKNOWN = 0, + + // Effective connection type reported when the Internet is unreachable, either + // because the device does not have a connection or because the + // connection is too slow to be usable. EFFECTIVE_CONNECTION_TYPE_OFFLINE, + + // Effective connection type reported when the network has the quality of a + // poor 2G connection. EFFECTIVE_CONNECTION_TYPE_SLOW_2G, + + // Effective connection type reported when the network has the quality of a + // faster 2G connection. EFFECTIVE_CONNECTION_TYPE_2G, + + // Effective connection type reported when the network has the quality of a 3G + // connection. EFFECTIVE_CONNECTION_TYPE_3G, + + // Effective connection type reported when the network has the quality of a 4G + // connection. EFFECTIVE_CONNECTION_TYPE_4G, + + // Effective connection type reported when the network has the quality of a + // broadband connection. EFFECTIVE_CONNECTION_TYPE_BROADBAND, + + // Last value of the effective connection type. This value is unused. EFFECTIVE_CONNECTION_TYPE_LAST, }; +// Returns the string equivalent of |type|. +NET_EXPORT const char* GetNameForEffectiveConnectionType( + EffectiveConnectionType type); + +// Returns true if the EffectiveConnectionType that corresponds to +// |connection_type_name| is available, and sets |effective_connection_type| to +// that value. If the effective connection type is unavailable, false is +// returned, and |effective_connection_type| is set to +// EFFECTIVE_CONNECTION_TYPE_UNKNOWN. |effective_connection_type| must be +// non-null. +NET_EXPORT bool GetEffectiveConnectionTypeForName( + const std::string& connection_type_name, + EffectiveConnectionType* effective_connection_type); + } // namespace net #endif // NET_NQE_EFFECTIVE_CONNECTION_TYPE_H_
diff --git a/net/nqe/effective_connection_type_unittest.cc b/net/nqe/effective_connection_type_unittest.cc new file mode 100644 index 0000000..f5dffba9 --- /dev/null +++ b/net/nqe/effective_connection_type_unittest.cc
@@ -0,0 +1,53 @@ +// Copyright 2016 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/nqe/effective_connection_type.h" + +#include <string> + +#include "testing/gtest/include/gtest/gtest.h" + +namespace net { + +namespace { + +// Tests that the effective connection type is converted correctly to a +// descriptive string name, and vice-versa. +TEST(EffectiveConnectionTypeTest, NameConnectionTypeConversion) { + // Initialize |converted_effective_connection_type| to a value other than + // EFFECTIVE_CONNECTION_TYPE_UNKNOWN, and verify that it is set to + // EFFECTIVE_CONNECTION_TYPE_UNKNOWN when an invalid effective connection + // type name is provided. + EffectiveConnectionType converted_effective_connection_type = + EFFECTIVE_CONNECTION_TYPE_SLOW_2G; + EXPECT_FALSE( + GetEffectiveConnectionTypeForName("InvalidEffectiveConnectionTypeName", + &converted_effective_connection_type)); + EXPECT_EQ(EFFECTIVE_CONNECTION_TYPE_UNKNOWN, + converted_effective_connection_type); + + // Reset |converted_effective_connection_type| to a value other than + // EFFECTIVE_CONNECTION_TYPE_UNKNOWN. + converted_effective_connection_type = EFFECTIVE_CONNECTION_TYPE_SLOW_2G; + EXPECT_FALSE(GetEffectiveConnectionTypeForName( + std::string(), &converted_effective_connection_type)); + EXPECT_EQ(EFFECTIVE_CONNECTION_TYPE_UNKNOWN, + converted_effective_connection_type); + + for (size_t i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) { + const EffectiveConnectionType effective_connection_type = + static_cast<EffectiveConnectionType>(i); + std::string connection_type_name = std::string( + GetNameForEffectiveConnectionType(effective_connection_type)); + EXPECT_FALSE(connection_type_name.empty()); + + EXPECT_TRUE(GetEffectiveConnectionTypeForName( + connection_type_name, &converted_effective_connection_type)); + EXPECT_EQ(effective_connection_type, converted_effective_connection_type); + } +} + +} // namespace + +} // namespace net \ No newline at end of file
diff --git a/net/nqe/network_quality_estimator.cc b/net/nqe/network_quality_estimator.cc index c31f9a4..9511ee7 100644 --- a/net/nqe/network_quality_estimator.cc +++ b/net/nqe/network_quality_estimator.cc
@@ -314,12 +314,12 @@ int32_t metric, base::TimeDelta measuring_duration, net::EffectiveConnectionType observed_effective_connection_type) { - const std::string histogram_name = base::StringPrintf( - "%s.EstimatedObservedDiff.%s.%d.%s", prefix, - metric >= 0 ? "Positive" : "Negative", - static_cast<int32_t>(measuring_duration.InSeconds()), - net::NetworkQualityEstimator::GetNameForEffectiveConnectionType( - observed_effective_connection_type)); + const std::string histogram_name = + base::StringPrintf("%s.EstimatedObservedDiff.%s.%d.%s", prefix, + metric >= 0 ? "Positive" : "Negative", + static_cast<int32_t>(measuring_duration.InSeconds()), + net::GetNameForEffectiveConnectionType( + observed_effective_connection_type)); base::HistogramBase* histogram = base::Histogram::FactoryGet( histogram_name, 0, net::EFFECTIVE_CONNECTION_TYPE_LAST, @@ -363,8 +363,6 @@ .find(GetEffectiveConnectionTypeAlgorithm(variation_params)) ->second), tick_clock_(new base::DefaultTickClock()), - effective_connection_type_recomputation_interval_( - base::TimeDelta::FromSeconds(15)), last_connection_change_(tick_clock_->NowTicks()), current_network_id_(nqe::internal::NetworkID( NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, @@ -374,6 +372,10 @@ effective_connection_type_at_last_main_frame_( EFFECTIVE_CONNECTION_TYPE_UNKNOWN), external_estimate_provider_(std::move(external_estimates_provider)), + effective_connection_type_recomputation_interval_( + base::TimeDelta::FromSeconds(15)), + rtt_observations_size_at_last_ect_computation_(0), + throughput_observations_size_at_last_ect_computation_(0), effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), min_signal_strength_since_connection_change_(INT32_MAX), max_signal_strength_since_connection_change_(INT32_MIN), @@ -1534,53 +1536,6 @@ } } -// static -const char* NetworkQualityEstimator::GetNameForEffectiveConnectionType( - EffectiveConnectionType type) { - switch (type) { - case EFFECTIVE_CONNECTION_TYPE_UNKNOWN: - return "Unknown"; - case EFFECTIVE_CONNECTION_TYPE_OFFLINE: - return "Offline"; - case EFFECTIVE_CONNECTION_TYPE_SLOW_2G: - return "Slow2G"; - case EFFECTIVE_CONNECTION_TYPE_2G: - return "2G"; - case EFFECTIVE_CONNECTION_TYPE_3G: - return "3G"; - case EFFECTIVE_CONNECTION_TYPE_4G: - return "4G"; - case EFFECTIVE_CONNECTION_TYPE_BROADBAND: - return "Broadband"; - default: - NOTREACHED(); - break; - } - return ""; -} - -// static -EffectiveConnectionType -NetworkQualityEstimator::GetEffectiveConnectionTypeForName( - const std::string& connection_type_name) { - if (connection_type_name == "Unknown") - return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; - if (connection_type_name == "Offline") - return EFFECTIVE_CONNECTION_TYPE_OFFLINE; - if (connection_type_name == "Slow2G") - return EFFECTIVE_CONNECTION_TYPE_SLOW_2G; - if (connection_type_name == "2G") - return EFFECTIVE_CONNECTION_TYPE_2G; - if (connection_type_name == "3G") - return EFFECTIVE_CONNECTION_TYPE_3G; - if (connection_type_name == "4G") - return EFFECTIVE_CONNECTION_TYPE_4G; - if (connection_type_name == "Broadband") - return EFFECTIVE_CONNECTION_TYPE_BROADBAND; - NOTREACHED(); - return EFFECTIVE_CONNECTION_TYPE_UNKNOWN; -} - void NetworkQualityEstimator::SetTickClockForTesting( std::unique_ptr<base::TickClock> tick_clock) { DCHECK(thread_checker_.CalledOnValidThread()); @@ -1662,14 +1617,21 @@ // last computed or a connection change event was observed since the last // computation. Strict inequalities are used to ensure that effective // connection type is recomputed on connection change events even if the clock - // has not updated. Recompute the effective connection type if the effective - // connection type was previously unavailable. This is because the RTT - // observations are voluminous, so it may now be possible to compute the - // effective connection type. + // has not updated. if (now - last_effective_connection_type_computation_ < effective_connection_type_recomputation_interval_ && last_connection_change_ < last_effective_connection_type_computation_ && - effective_connection_type_ != EFFECTIVE_CONNECTION_TYPE_UNKNOWN) { + // Recompute the effective connection type if the previously computed + // effective connection type was unknown. + effective_connection_type_ != EFFECTIVE_CONNECTION_TYPE_UNKNOWN && + // Recompute the effective connection type if the number of samples + // available now are more than twice in count than the number of + // samples that were available when the effective connection type was + // last computed. + rtt_observations_size_at_last_ect_computation_ * 2 >= + rtt_observations_.Size() && + throughput_observations_size_at_last_ect_computation_ * 2 >= + downstream_throughput_kbps_observations_.Size()) { return; } @@ -1679,11 +1641,16 @@ if (past_type != effective_connection_type_) NotifyObserversOfEffectiveConnectionTypeChanged(); + + rtt_observations_size_at_last_ect_computation_ = rtt_observations_.Size(); + throughput_observations_size_at_last_ect_computation_ = + downstream_throughput_kbps_observations_.Size(); } void NetworkQualityEstimator:: NotifyObserversOfEffectiveConnectionTypeChanged() { DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK_NE(EFFECTIVE_CONNECTION_TYPE_LAST, effective_connection_type_); // TODO(tbansal): Add hysteresis in the notification. FOR_EACH_OBSERVER(
diff --git a/net/nqe/network_quality_estimator.h b/net/nqe/network_quality_estimator.h index 973b925..80c7feb 100644 --- a/net/nqe/network_quality_estimator.h +++ b/net/nqe/network_quality_estimator.h
@@ -201,14 +201,6 @@ SocketPerformanceWatcherFactory* GetSocketPerformanceWatcherFactory(); - // Returns a string equivalent to |type|. - static const char* GetNameForEffectiveConnectionType( - EffectiveConnectionType type); - - // Returns an EffectiveConnectionType equivalent to |connection_type_name|. - static EffectiveConnectionType GetEffectiveConnectionTypeForName( - const std::string& connection_type_name); - // |use_localhost_requests| should only be true when testing against local // HTTP server and allows the requests to local host to be used for network // quality estimation. @@ -295,6 +287,8 @@ virtual double RandDouble() const; private: + FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, + AdaptiveRecomputationEffectiveConnectionType); FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, StoreObservations); FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestAddObservation); FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, ObtainOperatingParams); @@ -305,6 +299,8 @@ FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestGetMetricsSince); FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, TestExternalEstimateProviderMergeEstimates); + FRIEND_TEST_ALL_PREFIXES(NetworkQualityEstimatorTest, + UnknownEffectiveConnectionType); // Value of round trip time observations is in base::TimeDelta. typedef nqe::internal::Observation<base::TimeDelta> RttObservation; @@ -508,13 +504,6 @@ // Tick clock used by the network quality estimator. std::unique_ptr<base::TickClock> tick_clock_; - // Minimum duration between two consecutive computations of effective - // connection type. Set to non-zero value as a performance optimization. - const base::TimeDelta effective_connection_type_recomputation_interval_; - - // Time when the effective connection type was last computed. - base::TimeTicks last_effective_connection_type_computation_; - // Intervals after the main frame request arrives at which accuracy of network // quality prediction is recorded. std::vector<base::TimeDelta> accuracy_recording_intervals_; @@ -591,6 +580,18 @@ // estimating the throughput. std::unique_ptr<nqe::internal::ThroughputAnalyzer> throughput_analyzer_; + // Minimum duration between two consecutive computations of effective + // connection type. Set to non-zero value as a performance optimization. + const base::TimeDelta effective_connection_type_recomputation_interval_; + + // Time when the effective connection type was last computed. + base::TimeTicks last_effective_connection_type_computation_; + + // Number of RTT and bandwidth samples available when effective connection + // type was last recomputed. + size_t rtt_observations_size_at_last_ect_computation_; + size_t throughput_observations_size_at_last_ect_computation_; + // Current effective connection type. It is updated on connection change // events. It is also updated every time there is network traffic (provided // the last computation was more than
diff --git a/net/nqe/network_quality_estimator_unittest.cc b/net/nqe/network_quality_estimator_unittest.cc index d6917fc..211bf066 100644 --- a/net/nqe/network_quality_estimator_unittest.cc +++ b/net/nqe/network_quality_estimator_unittest.cc
@@ -1601,6 +1601,128 @@ EXPECT_EQ(2U, observer.effective_connection_types().size()); } +// Tests that the effective connection type is computed on every RTT +// observation if the last computed effective connection type was unknown. +TEST(NetworkQualityEstimatorTest, UnknownEffectiveConnectionType) { + std::unique_ptr<base::SimpleTestTickClock> tick_clock( + new base::SimpleTestTickClock()); + base::SimpleTestTickClock* tick_clock_ptr = tick_clock.get(); + + TestEffectiveConnectionTypeObserver observer; + std::map<std::string, std::string> variation_params; + TestNetworkQualityEstimator estimator(variation_params); + estimator.SetTickClockForTesting(std::move(tick_clock)); + estimator.AddEffectiveConnectionTypeObserver(&observer); + tick_clock_ptr->Advance(base::TimeDelta::FromMinutes(60)); + + size_t expected_effective_connection_type_notifications = 0; + estimator.set_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_UNKNOWN); + estimator.SimulateNetworkChangeTo(NetworkChangeNotifier::CONNECTION_WIFI, + "test"); + + NetworkQualityEstimator::RttObservation rtt_observation( + base::TimeDelta::FromSeconds(5), tick_clock_ptr->NowTicks(), + NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST); + + for (size_t i = 0; i < 10; ++i) { + estimator.NotifyObserversOfRTT(rtt_observation); + EXPECT_EQ(expected_effective_connection_type_notifications, + observer.effective_connection_types().size()); + } + estimator.set_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_SLOW_2G); + // Even though there are 10 RTT samples already available, the addition of one + // more RTT sample should trigger recomputation of the effective connection + // type since the last computed effective connection type was unknown. + estimator.NotifyObserversOfRTT(NetworkQualityEstimator::RttObservation( + base::TimeDelta::FromSeconds(5), tick_clock_ptr->NowTicks(), + NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST)); + ++expected_effective_connection_type_notifications; + EXPECT_EQ(expected_effective_connection_type_notifications, + observer.effective_connection_types().size()); +} + +// Tests that the effective connection type is computed regularly depending +// on the number of RTT and bandwidth samples. +TEST(NetworkQualityEstimatorTest, + AdaptiveRecomputationEffectiveConnectionType) { + base::HistogramTester histogram_tester; + std::unique_ptr<base::SimpleTestTickClock> tick_clock( + new base::SimpleTestTickClock()); + base::SimpleTestTickClock* tick_clock_ptr = tick_clock.get(); + + TestEffectiveConnectionTypeObserver observer; + std::map<std::string, std::string> variation_params; + TestNetworkQualityEstimator estimator(variation_params); + estimator.SetTickClockForTesting(std::move(tick_clock)); + estimator.SimulateNetworkChangeTo(NetworkChangeNotifier::CONNECTION_WIFI, + "test"); + estimator.AddEffectiveConnectionTypeObserver(&observer); + + TestDelegate test_delegate; + TestURLRequestContext context(true); + context.set_network_quality_estimator(&estimator); + context.Init(); + + EXPECT_EQ(0U, observer.effective_connection_types().size()); + + estimator.set_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_2G); + tick_clock_ptr->Advance(base::TimeDelta::FromMinutes(60)); + + std::unique_ptr<URLRequest> request(context.CreateRequest( + estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); + request->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME); + request->Start(); + base::RunLoop().Run(); + EXPECT_EQ(1U, observer.effective_connection_types().size()); + histogram_tester.ExpectUniqueSample( + "NQE.MainFrame.EffectiveConnectionType.WiFi", + EFFECTIVE_CONNECTION_TYPE_2G, 1); + + size_t expected_effective_connection_type_notifications = 1; + EXPECT_EQ(expected_effective_connection_type_notifications, + observer.effective_connection_types().size()); + + EXPECT_EQ(expected_effective_connection_type_notifications, + estimator.rtt_observations_.Size()); + + // Increase the number of RTT observations. Every time the number of RTT + // observations is more than doubled, effective connection type must be + // recomputed and notified to observers. + for (size_t repetition = 0; repetition < 2; ++repetition) { + // Change the effective connection type so that the observers are + // notified when the effective connection type is recomputed. + if (repetition % 2 == 0) { + estimator.set_effective_connection_type( + EFFECTIVE_CONNECTION_TYPE_SLOW_2G); + } else { + estimator.set_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_3G); + } + size_t rtt_observations_count = estimator.rtt_observations_.Size(); + // Increase the number of RTT observations to more than twice the number + // of current observations. This should trigger recomputation of + // effective connection type. + for (size_t i = 0; i < rtt_observations_count + 1; ++i) { + estimator.rtt_observations_.AddObservation( + NetworkQualityEstimator::RttObservation( + base::TimeDelta::FromSeconds(5), tick_clock_ptr->NowTicks(), + NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST)); + + estimator.NotifyObserversOfRTT(NetworkQualityEstimator::RttObservation( + base::TimeDelta::FromSeconds(5), tick_clock_ptr->NowTicks(), + NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST)); + + if (i == rtt_observations_count) { + // Effective connection type must be recomputed since the number of RTT + // samples are now more than twice the number of RTT samples that were + // available when effective connection type was last computed. + ++expected_effective_connection_type_notifications; + } + EXPECT_EQ(expected_effective_connection_type_notifications, + observer.effective_connection_types().size()); + } + } +} + TEST(NetworkQualityEstimatorTest, TestRttThroughputObservers) { TestRTTObserver rtt_observer; TestThroughputObserver throughput_observer; @@ -1930,22 +2052,6 @@ } } -// Tests that the effective connection type is converted correctly to a -// descriptive string name, and vice-versa. -TEST(NetworkQualityEstimatorTest, NameConnectionTypeConversion) { - for (size_t i = 0; i < EFFECTIVE_CONNECTION_TYPE_LAST; ++i) { - const EffectiveConnectionType effective_connection_type = - static_cast<EffectiveConnectionType>(i); - std::string connection_type_name = - std::string(NetworkQualityEstimator::GetNameForEffectiveConnectionType( - effective_connection_type)); - EXPECT_FALSE(connection_type_name.empty()); - EXPECT_EQ(effective_connection_type, - NetworkQualityEstimator::GetEffectiveConnectionTypeForName( - connection_type_name)); - } -} - TEST(NetworkQualityEstimatorTest, TestRecordNetworkIDAvailability) { base::HistogramTester histogram_tester; std::map<std::string, std::string> variation_params;
diff --git a/net/proxy/mojo_proxy_resolver_factory_impl.cc b/net/proxy/mojo_proxy_resolver_factory_impl.cc index 65b6a48..bf01a22 100644 --- a/net/proxy/mojo_proxy_resolver_factory_impl.cc +++ b/net/proxy/mojo_proxy_resolver_factory_impl.cc
@@ -131,7 +131,7 @@ std::move(request)) {} MojoProxyResolverFactoryImpl::~MojoProxyResolverFactoryImpl() { - STLDeleteElements(&jobs_); + base::STLDeleteElements(&jobs_); } void MojoProxyResolverFactoryImpl::CreateResolver(
diff --git a/net/proxy/mojo_proxy_resolver_impl.cc b/net/proxy/mojo_proxy_resolver_impl.cc index e72008b5..184761a2 100644 --- a/net/proxy/mojo_proxy_resolver_impl.cc +++ b/net/proxy/mojo_proxy_resolver_impl.cc
@@ -51,7 +51,7 @@ : resolver_(std::move(resolver)) {} MojoProxyResolverImpl::~MojoProxyResolverImpl() { - STLDeleteElements(&resolve_jobs_); + base::STLDeleteElements(&resolve_jobs_); } void MojoProxyResolverImpl::GetProxyForUrl(
diff --git a/net/proxy/proxy_bypass_rules.cc b/net/proxy/proxy_bypass_rules.cc index 963f6b0..86bf4fb 100644 --- a/net/proxy/proxy_bypass_rules.cc +++ b/net/proxy/proxy_bypass_rules.cc
@@ -229,7 +229,7 @@ } void ProxyBypassRules::Clear() { - STLDeleteElements(&rules_); + base::STLDeleteElements(&rules_); } void ProxyBypassRules::AssignFrom(const ProxyBypassRules& other) {
diff --git a/net/proxy/proxy_config_service_win.cc b/net/proxy/proxy_config_service_win.cc index e819bf4..0edc523 100644 --- a/net/proxy/proxy_config_service_win.cc +++ b/net/proxy/proxy_config_service_win.cc
@@ -49,7 +49,7 @@ // The registry functions below will end up going to disk. Do this on another // thread to avoid slowing the IO thread. http://crbug.com/61453 base::ThreadRestrictions::ScopedAllowIO allow_io; - STLDeleteElements(&keys_to_watch_); + base::STLDeleteElements(&keys_to_watch_); } void ProxyConfigServiceWin::AddObserver(Observer* observer) {
diff --git a/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc b/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc index 754bf4a..68b206f 100644 --- a/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc +++ b/net/quic/chromium/bidirectional_stream_quic_impl_unittest.cc
@@ -625,7 +625,7 @@ INSTANTIATE_TEST_CASE_P(Version, BidirectionalStreamQuicImplTest, - ::testing::ValuesIn(QuicSupportedVersions())); + ::testing::ValuesIn(AllSupportedVersions())); TEST_P(BidirectionalStreamQuicImplTest, GetRequest) { SetRequest("GET", "/", DEFAULT_PRIORITY);
diff --git a/net/quic/chromium/crypto/channel_id_chromium.cc b/net/quic/chromium/crypto/channel_id_chromium.cc index 661749da..cfaf61b 100644 --- a/net/quic/chromium/crypto/channel_id_chromium.cc +++ b/net/quic/chromium/crypto/channel_id_chromium.cc
@@ -200,7 +200,7 @@ : channel_id_service_(channel_id_service) {} ChannelIDSourceChromium::~ChannelIDSourceChromium() { - STLDeleteElements(&active_jobs_); + base::STLDeleteElements(&active_jobs_); } QuicAsyncStatus ChannelIDSourceChromium::GetChannelIDKey(
diff --git a/net/quic/chromium/crypto/proof_verifier_chromium.cc b/net/quic/chromium/crypto/proof_verifier_chromium.cc index 9a7396e..d42dba8 100644 --- a/net/quic/chromium/crypto/proof_verifier_chromium.cc +++ b/net/quic/chromium/crypto/proof_verifier_chromium.cc
@@ -397,12 +397,14 @@ if (enforce_policy_checking_ && (result == OK || (IsCertificateError(result) && IsCertStatusMinorError(cert_status)))) { + SCTList verified_scts = ct::SCTsMatchingStatus( + verify_details_->ct_verify_result.scts, ct::SCT_STATUS_OK); if ((cert_verify_result.cert_status & CERT_STATUS_IS_EV)) { ct::EVPolicyCompliance ev_policy_compliance = policy_enforcer_->DoesConformToCTEVPolicy( cert_verify_result.verified_cert.get(), - SSLConfigService::GetEVCertsWhitelist().get(), - verify_details_->ct_verify_result.verified_scts, net_log_); + SSLConfigService::GetEVCertsWhitelist().get(), verified_scts, + net_log_); verify_details_->ct_verify_result.ev_policy_compliance = ev_policy_compliance; if (ev_policy_compliance != @@ -419,8 +421,7 @@ verify_details_->ct_verify_result.cert_policy_compliance = policy_enforcer_->DoesConformToCertPolicy( - cert_verify_result.verified_cert.get(), - verify_details_->ct_verify_result.verified_scts, net_log_); + cert_verify_result.verified_cert.get(), verified_scts, net_log_); int ct_result = OK; if (verify_details_->ct_verify_result.cert_policy_compliance != @@ -556,7 +557,7 @@ } ProofVerifierChromium::~ProofVerifierChromium() { - STLDeleteElements(&active_jobs_); + base::STLDeleteElements(&active_jobs_); } QuicAsyncStatus ProofVerifierChromium::VerifyProof(
diff --git a/net/quic/chromium/crypto/proof_verifier_chromium_test.cc b/net/quic/chromium/crypto/proof_verifier_chromium_test.cc index 91f9aed..e1471dc 100644 --- a/net/quic/chromium/crypto/proof_verifier_chromium_test.cc +++ b/net/quic/chromium/crypto/proof_verifier_chromium_test.cc
@@ -205,7 +205,8 @@ ct_verify_result, ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION)); } else { - EXPECT_EQ(1U, ct_verify_result.unknown_logs_scts.size()); + EXPECT_EQ(1U, ct_verify_result.scts.size()); + EXPECT_EQ(ct::SCT_STATUS_LOG_UNKNOWN, ct_verify_result.scts[0].status); } }
diff --git a/net/quic/chromium/quic_chromium_client_session.cc b/net/quic/chromium/quic_chromium_client_session.cc index 3c0aad5..00d3410 100644 --- a/net/quic/chromium/quic_chromium_client_session.cc +++ b/net/quic/chromium/quic_chromium_client_session.cc
@@ -418,12 +418,12 @@ return; } - DCHECK(!ContainsKey(observers_, observer)); + DCHECK(!base::ContainsKey(observers_, observer)); observers_.insert(observer); } void QuicChromiumClientSession::RemoveObserver(Observer* observer) { - DCHECK(ContainsKey(observers_, observer)); + DCHECK(base::ContainsKey(observers_, observer)); observers_.erase(observer); }
diff --git a/net/quic/chromium/quic_chromium_client_session_test.cc b/net/quic/chromium/quic_chromium_client_session_test.cc index 6c82634c..cd672083 100644 --- a/net/quic/chromium/quic_chromium_client_session_test.cc +++ b/net/quic/chromium/quic_chromium_client_session_test.cc
@@ -152,7 +152,7 @@ INSTANTIATE_TEST_CASE_P(Tests, QuicChromiumClientSessionTest, - ::testing::ValuesIn(QuicSupportedVersions())); + ::testing::ValuesIn(AllSupportedVersions())); TEST_P(QuicChromiumClientSessionTest, CryptoConnect) { Initialize();
diff --git a/net/quic/chromium/quic_chromium_client_stream_test.cc b/net/quic/chromium/quic_chromium_client_stream_test.cc index 5e52585..a240f24 100644 --- a/net/quic/chromium/quic_chromium_client_stream_test.cc +++ b/net/quic/chromium/quic_chromium_client_stream_test.cc
@@ -228,7 +228,7 @@ INSTANTIATE_TEST_CASE_P(Version, QuicChromiumClientStreamTest, - ::testing::ValuesIn(QuicSupportedVersions())); + ::testing::ValuesIn(AllSupportedVersions())); TEST_P(QuicChromiumClientStreamTest, OnFinRead) { InitializeHeaders();
diff --git a/net/quic/chromium/quic_connection_logger.cc b/net/quic/chromium/quic_connection_logger.cc index aa3318c3c..df5c499b 100644 --- a/net/quic/chromium/quic_connection_logger.cc +++ b/net/quic/chromium/quic_connection_logger.cc
@@ -327,6 +327,12 @@ UMA_HISTOGRAM_COUNTS("Net.QuicSession.HeadersStream.EarlyFramesReceived", session_->headers_stream()->num_early_frames_received()); + const QuicConnectionStats& stats = session_->connection()->GetStats(); + UMA_HISTOGRAM_TIMES("Net.QuicSession.MinRTT", + base::TimeDelta::FromMicroseconds(stats.min_rtt_us)); + UMA_HISTOGRAM_TIMES("Net.QuicSession.SmoothedRTT", + base::TimeDelta::FromMicroseconds(stats.srtt_us)); + if (num_frames_received_ > 0) { int duplicate_stream_frame_per_thousand = num_duplicate_frames_received_ * 1000 / num_frames_received_;
diff --git a/net/quic/chromium/quic_http_stream_test.cc b/net/quic/chromium/quic_http_stream_test.cc index 7f2daa22..38223ef 100644 --- a/net/quic/chromium/quic_http_stream_test.cc +++ b/net/quic/chromium/quic_http_stream_test.cc
@@ -574,7 +574,7 @@ INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest, - ::testing::ValuesIn(QuicSupportedVersions())); + ::testing::ValuesIn(AllSupportedVersions())); TEST_P(QuicHttpStreamTest, RenewStreamForAuth) { Initialize();
diff --git a/net/quic/chromium/quic_network_transaction_unittest.cc b/net/quic/chromium/quic_network_transaction_unittest.cc index 1862f63..3f3654e 100644 --- a/net/quic/chromium/quic_network_transaction_unittest.cc +++ b/net/quic/chromium/quic_network_transaction_unittest.cc
@@ -115,7 +115,7 @@ std::vector<PoolingTestParams> GetPoolingTestParams() { std::vector<PoolingTestParams> params; - QuicVersionVector all_supported_versions = QuicSupportedVersions(); + QuicVersionVector all_supported_versions = AllSupportedVersions(); for (const QuicVersion version : all_supported_versions) { params.push_back(PoolingTestParams{version, SAME_AS_FIRST}); params.push_back(PoolingTestParams{version, SAME_AS_SECOND}); @@ -132,7 +132,7 @@ public: MockQuicData() : packet_number_(0) {} - ~MockQuicData() { STLDeleteElements(&packets_); } + ~MockQuicData() { base::STLDeleteElements(&packets_); } void AddSynchronousRead(std::unique_ptr<QuicEncryptedPacket> packet) { reads_.push_back(MockRead(SYNCHRONOUS, packet->data(), packet->length(), @@ -523,8 +523,7 @@ session_->quic_stream_factory()->socket_receive_buffer_size()); } - void CheckWasQuicResponse( - const std::unique_ptr<HttpNetworkTransaction>& trans) { + void CheckWasQuicResponse(HttpNetworkTransaction* trans) { const HttpResponseInfo* response = trans->GetResponseInfo(); ASSERT_TRUE(response != nullptr); ASSERT_TRUE(response->headers.get() != nullptr); @@ -535,15 +534,13 @@ response->connection_info); } - void CheckResponsePort(const std::unique_ptr<HttpNetworkTransaction>& trans, - uint16_t port) { + void CheckResponsePort(HttpNetworkTransaction* trans, uint16_t port) { const HttpResponseInfo* response = trans->GetResponseInfo(); ASSERT_TRUE(response != nullptr); EXPECT_EQ(port, response->socket_address.port()); } - void CheckWasHttpResponse( - const std::unique_ptr<HttpNetworkTransaction>& trans) { + void CheckWasHttpResponse(HttpNetworkTransaction* trans) { const HttpResponseInfo* response = trans->GetResponseInfo(); ASSERT_TRUE(response != nullptr); ASSERT_TRUE(response->headers.get() != nullptr); @@ -554,14 +551,14 @@ response->connection_info); } - void CheckResponseData(const std::unique_ptr<HttpNetworkTransaction>& trans, + void CheckResponseData(HttpNetworkTransaction* trans, const std::string& expected) { std::string response_data; - ASSERT_THAT(ReadTransaction(trans.get(), &response_data), IsOk()); + ASSERT_THAT(ReadTransaction(trans, &response_data), IsOk()); EXPECT_EQ(expected, response_data); } - void RunTransaction(const std::unique_ptr<HttpNetworkTransaction>& trans) { + void RunTransaction(HttpNetworkTransaction* trans) { TestCompletionCallback callback; int rv = trans->Start(&request_, callback.callback(), net_log_.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -569,11 +566,10 @@ } void SendRequestAndExpectHttpResponse(const std::string& expected) { - std::unique_ptr<HttpNetworkTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); - RunTransaction(trans); - CheckWasHttpResponse(trans); - CheckResponseData(trans, expected); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get()); + RunTransaction(&trans); + CheckWasHttpResponse(&trans); + CheckResponseData(&trans, expected); } void SendRequestAndExpectQuicResponse(const std::string& expected) { @@ -664,23 +660,22 @@ const std::string& expected, bool used_proxy, uint16_t port) { - std::unique_ptr<HttpNetworkTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get()); HeadersHandler headers_handler; - trans->SetBeforeHeadersSentCallback( + trans.SetBeforeHeadersSentCallback( base::Bind(&HeadersHandler::OnBeforeHeadersSent, base::Unretained(&headers_handler))); - RunTransaction(trans); - CheckWasQuicResponse(trans); - CheckResponsePort(trans, port); - CheckResponseData(trans, expected); + RunTransaction(&trans); + CheckWasQuicResponse(&trans); + CheckResponsePort(&trans, port); + CheckResponseData(&trans, expected); EXPECT_EQ(used_proxy, headers_handler.was_proxied()); } }; INSTANTIATE_TEST_CASE_P(Version, QuicNetworkTransactionTest, - ::testing::ValuesIn(QuicSupportedVersions())); + ::testing::ValuesIn(AllSupportedVersions())); TEST_P(QuicNetworkTransactionTest, ForceQuic) { params_.origins_to_force_quic_on.insert( @@ -909,10 +904,9 @@ EXPECT_EQ(0U, test_socket_performance_watcher_factory_.watcher_count()); for (size_t i = 0; i < 2; ++i) { - std::unique_ptr<HttpNetworkTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get()); TestCompletionCallback callback; - int rv = trans->Start(&request_, callback.callback(), net_log_.bound()); + int rv = trans.Start(&request_, callback.callback(), net_log_.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_CLOSED)); EXPECT_EQ(1 + i, test_socket_performance_watcher_factory_.watcher_count()); @@ -1074,7 +1068,7 @@ SendRequestAndExpectHttpResponse("hello world"); } -TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceQuicSupportedVersion) { +TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) { std::string altsvc_header = base::StringPrintf( "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", GetParam()); MockRead http_reads[] = { @@ -1153,10 +1147,9 @@ session_->quic_stream_factory()->set_require_confirmation(true); AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); - std::unique_ptr<HttpNetworkTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get()); TestCompletionCallback callback; - int rv = trans->Start(&request_, callback.callback(), net_log_.bound()); + int rv = trans.Start(&request_, callback.callback(), net_log_.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( @@ -1167,7 +1160,7 @@ // because of migrating port. NetErrorDetails details; EXPECT_FALSE(details.quic_port_migration_detected); - trans->PopulateNetErrorDetails(&details); + trans.PopulateNetErrorDetails(&details); EXPECT_TRUE(details.quic_port_migration_detected); } @@ -1773,18 +1766,17 @@ session_->quic_stream_factory()->set_require_confirmation(true); AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); - std::unique_ptr<HttpNetworkTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get()); TestCompletionCallback callback; - int rv = trans->Start(&request_, callback.callback(), net_log_.bound()); + int rv = trans.Start(&request_, callback.callback(), net_log_.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( QuicSession::HANDSHAKE_CONFIRMED); EXPECT_THAT(callback.WaitForResult(), IsOk()); - CheckWasQuicResponse(trans); - CheckResponseData(trans, "hello!"); + CheckWasQuicResponse(&trans); + CheckResponseData(&trans, "hello!"); } TEST_P(QuicNetworkTransactionTest, @@ -1820,10 +1812,9 @@ session_->quic_stream_factory()->set_require_confirmation(true); AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); - std::unique_ptr<HttpNetworkTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get()); TestCompletionCallback callback; - int rv = trans->Start(&request_, callback.callback(), net_log_.bound()); + int rv = trans.Start(&request_, callback.callback(), net_log_.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( @@ -1833,7 +1824,7 @@ NetErrorDetails details; EXPECT_EQ(QUIC_NO_ERROR, details.quic_connection_error); - trans->PopulateNetErrorDetails(&details); + trans.PopulateNetErrorDetails(&details); // Verify the error code logged is what sent by the peer. EXPECT_EQ(QUIC_CRYPTO_VERSION_NOT_SUPPORTED, details.quic_connection_error); } @@ -1876,10 +1867,9 @@ session_->quic_stream_factory()->set_require_confirmation(true); AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); - std::unique_ptr<HttpNetworkTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get()); TestCompletionCallback callback; - int rv = trans->Start(&request_, callback.callback(), net_log_.bound()); + int rv = trans.Start(&request_, callback.callback(), net_log_.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( @@ -1888,7 +1878,7 @@ NetErrorDetails details; EXPECT_EQ(QUIC_NO_ERROR, details.quic_connection_error); - trans->PopulateNetErrorDetails(&details); + trans.PopulateNetErrorDetails(&details); EXPECT_EQ(QUIC_INVALID_STREAM_ID, details.quic_connection_error); } @@ -1928,10 +1918,9 @@ session_->quic_stream_factory()->set_require_confirmation(true); AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); - std::unique_ptr<HttpNetworkTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get()); TestCompletionCallback callback; - int rv = trans->Start(&request_, callback.callback(), net_log_.bound()); + int rv = trans.Start(&request_, callback.callback(), net_log_.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( @@ -1939,7 +1928,7 @@ // Read the headers. EXPECT_THAT(callback.WaitForResult(), IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response != nullptr); ASSERT_TRUE(response->headers.get() != nullptr); EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); @@ -1949,8 +1938,7 @@ response->connection_info); std::string response_data; - ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, - ReadTransaction(trans.get(), &response_data)); + ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR, ReadTransaction(&trans, &response_data)); } TEST_P(QuicNetworkTransactionTest, RstSteamBeforeHeaders) { @@ -1985,10 +1973,9 @@ session_->quic_stream_factory()->set_require_confirmation(true); AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); - std::unique_ptr<HttpNetworkTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get()); TestCompletionCallback callback; - int rv = trans->Start(&request_, callback.callback(), net_log_.bound()); + int rv = trans.Start(&request_, callback.callback(), net_log_.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( @@ -2078,10 +2065,9 @@ CreateSession(); AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START); - std::unique_ptr<HttpNetworkTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get()); TestCompletionCallback callback; - int rv = trans->Start(&request_, callback.callback(), net_log_.bound()); + int rv = trans.Start(&request_, callback.callback(), net_log_.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsError(ERR_SOCKET_NOT_CONNECTED)); ExpectQuicAlternateProtocolMapping(); @@ -2261,10 +2247,9 @@ request_.upload_data_stream = &upload_data; - std::unique_ptr<HttpNetworkTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get()); TestCompletionCallback callback; - int rv = trans->Start(&request_, callback.callback(), net_log_.bound()); + int rv = trans.Start(&request_, callback.callback(), net_log_.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_NE(OK, callback.WaitForResult()); }
diff --git a/net/quic/chromium/quic_stream_factory.cc b/net/quic/chromium/quic_stream_factory.cc index 5cd80d1..e99a35b 100644 --- a/net/quic/chromium/quic_stream_factory.cc +++ b/net/quic/chromium/quic_stream_factory.cc
@@ -229,6 +229,7 @@ verify_callback_(nullptr), verify_context_(base::WrapUnique( new ProofVerifyContextChromium(cert_verify_flags, net_log))), + start_time_(base::TimeTicks::Now()), net_log_(net_log), weak_factory_(this) {} @@ -256,6 +257,8 @@ } void OnComplete() { + UMA_HISTOGRAM_TIMES("Net.QuicSession.CertVerifierJob.CompleteTime", + base::TimeTicks::Now() - start_time_); if (!callback_.is_null()) callback_.Run(OK); } @@ -268,6 +271,7 @@ std::unique_ptr<ProofVerifyContext> verify_context_; std::unique_ptr<ProofVerifyDetails> verify_details_; std::string verify_error_details_; + base::TimeTicks start_time_; const BoundNetLog net_log_; CompletionCallback callback_; base::WeakPtrFactory<CertVerifierJob> weak_factory_; @@ -860,7 +864,7 @@ } while (!active_jobs_.empty()) { const QuicServerId server_id = active_jobs_.begin()->first; - STLDeleteElements(&(active_jobs_[server_id])); + base::STLDeleteElements(&(active_jobs_[server_id])); active_jobs_.erase(server_id); } while (!active_cert_verifier_jobs_.empty()) @@ -912,7 +916,7 @@ if (active_sessions_.empty()) return false; - if (ContainsKey(active_sessions_, server_id)) + if (base::ContainsKey(active_sessions_, server_id)) return true; for (const auto& key_value : active_sessions_) { @@ -991,7 +995,7 @@ if (quic_server_info_factory_.get()) { bool load_from_disk_cache = !disable_disk_cache_; MaybeInitialize(); - if (!ContainsKey(quic_supported_servers_at_startup_, destination)) { + if (!base::ContainsKey(quic_supported_servers_at_startup_, destination)) { // If there is no entry for QUIC, consider that as a new server and // don't wait for Cache thread to load the data for that server. load_from_disk_cache = false; @@ -1065,7 +1069,7 @@ if (disable_connection_pooling_) return false; for (const IPEndPoint& address : address_list) { - if (!ContainsKey(ip_aliases_, address)) + if (!base::ContainsKey(ip_aliases_, address)) continue; const SessionSet& sessions = ip_aliases_[address]; @@ -1128,7 +1132,7 @@ other_job->Cancel(); } - STLDeleteElements(&(active_jobs_[server_id])); + base::STLDeleteElements(&(active_jobs_[server_id])); active_jobs_.erase(server_id); job_requests_map_.erase(server_id); } @@ -1681,16 +1685,16 @@ // TODO(rtenneti): crbug.com/498823 - delete active_sessions_.empty() check. if (active_sessions_.empty()) return false; - return ContainsKey(active_sessions_, server_id); + return base::ContainsKey(active_sessions_, server_id); } bool QuicStreamFactory::HasActiveJob(const QuicServerId& server_id) const { - return ContainsKey(active_jobs_, server_id); + return base::ContainsKey(active_jobs_, server_id); } bool QuicStreamFactory::HasActiveCertVerifierJob( const QuicServerId& server_id) const { - return ContainsKey(active_cert_verifier_jobs_, server_id); + return base::ContainsKey(active_cert_verifier_jobs_, server_id); } int QuicStreamFactory::ConfigureSocket(DatagramClientSocket* socket, @@ -1758,7 +1762,7 @@ TRACE_EVENT0("net", "QuicStreamFactory::CreateSession"); IPEndPoint addr = *address_list.begin(); bool enable_port_selection = enable_port_selection_; - if (enable_port_selection && ContainsKey(gone_away_aliases_, key)) { + if (enable_port_selection && base::ContainsKey(gone_away_aliases_, key)) { // Disable port selection when the server is going away. // There is no point in trying to return to the same server, if // that server is no longer handling requests. @@ -1851,7 +1855,7 @@ writer->Initialize(*session, connection); (*session)->Initialize(); - bool closed_during_initialize = !ContainsKey(all_sessions_, *session) || + bool closed_during_initialize = !base::ContainsKey(all_sessions_, *session) || !(*session)->connection()->connected(); UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.ClosedDuringInitializeSession", closed_during_initialize); @@ -1871,7 +1875,7 @@ active_sessions_[server_id] = session; session_aliases_[session].insert(key); const IPEndPoint peer_address = session->connection()->peer_address(); - DCHECK(!ContainsKey(ip_aliases_[peer_address], session)); + DCHECK(!base::ContainsKey(ip_aliases_[peer_address], session)); ip_aliases_[peer_address].insert(session); } @@ -1944,8 +1948,8 @@ // TODO(rtenneti): Delete the following histogram after collecting stats. // If the AlternativeServiceMap contained an entry for this host, check if // the disk cache contained an entry for it. - if (ContainsKey(quic_supported_servers_at_startup_, - server_id.host_port_pair())) { + if (base::ContainsKey(quic_supported_servers_at_startup_, + server_id.host_port_pair())) { UMA_HISTOGRAM_BOOLEAN("Net.QuicServerInfo.ExpectConfigMissingFromDiskCache", server_info->state().server_config.empty()); }
diff --git a/net/quic/chromium/quic_stream_factory_test.cc b/net/quic/chromium/quic_stream_factory_test.cc index d8abc7f2..081f9e5 100644 --- a/net/quic/chromium/quic_stream_factory_test.cc +++ b/net/quic/chromium/quic_stream_factory_test.cc
@@ -113,7 +113,7 @@ vector<TestParams> GetTestParams() { vector<TestParams> params; - QuicVersionVector all_supported_versions = QuicSupportedVersions(); + QuicVersionVector all_supported_versions = AllSupportedVersions(); for (const QuicVersion version : all_supported_versions) { params.push_back(TestParams{version, false}); params.push_back(TestParams{version, true}); @@ -152,7 +152,7 @@ vector<PoolingTestParams> GetPoolingTestParams() { vector<PoolingTestParams> params; - QuicVersionVector all_supported_versions = QuicSupportedVersions(); + QuicVersionVector all_supported_versions = AllSupportedVersions(); for (const QuicVersion version : all_supported_versions) { params.push_back(PoolingTestParams{version, false, SAME_AS_FIRST}); params.push_back(PoolingTestParams{version, false, SAME_AS_SECOND}); @@ -1210,7 +1210,7 @@ session->connection()->CloseConnection(QUIC_PUBLIC_RESET, "test", ConnectionCloseBehavior::SILENT_CLOSE); - STLDeleteElements(&streams); + base::STLDeleteElements(&streams); } TEST_P(QuicStreamFactoryTest, ResolutionErrorInCreate) {
diff --git a/net/quic/core/congestion_control/general_loss_algorithm.cc b/net/quic/core/congestion_control/general_loss_algorithm.cc index 428c4e8..319087b 100644 --- a/net/quic/core/congestion_control/general_loss_algorithm.cc +++ b/net/quic/core/congestion_control/general_loss_algorithm.cc
@@ -27,15 +27,15 @@ } // namespace GeneralLossAlgorithm::GeneralLossAlgorithm() - : loss_type_(kNack), - loss_detection_timeout_(QuicTime::Zero()), + : loss_detection_timeout_(QuicTime::Zero()), largest_sent_on_spurious_retransmit_(0), + loss_type_(kNack), reordering_shift_(kDefaultLossDelayShift) {} GeneralLossAlgorithm::GeneralLossAlgorithm(LossDetectionType loss_type) - : loss_type_(loss_type), - loss_detection_timeout_(QuicTime::Zero()), + : loss_detection_timeout_(QuicTime::Zero()), largest_sent_on_spurious_retransmit_(0), + loss_type_(loss_type), reordering_shift_(loss_type == kAdaptiveTime ? kDefaultAdaptiveLossDelayShift : kDefaultLossDelayShift) {} @@ -45,10 +45,12 @@ } void GeneralLossAlgorithm::SetLossDetectionType(LossDetectionType loss_type) { + loss_detection_timeout_ = QuicTime::Zero(); + largest_sent_on_spurious_retransmit_ = 0; loss_type_ = loss_type; - if (loss_type_ == kAdaptiveTime) { - reordering_shift_ = kDefaultAdaptiveLossDelayShift; - } + reordering_shift_ = loss_type == kAdaptiveTime + ? kDefaultAdaptiveLossDelayShift + : kDefaultLossDelayShift; } // Uses nack counts to decide when packets are lost.
diff --git a/net/quic/core/congestion_control/general_loss_algorithm.h b/net/quic/core/congestion_control/general_loss_algorithm.h index 82f7d9c..5ceaa37a 100644 --- a/net/quic/core/congestion_control/general_loss_algorithm.h +++ b/net/quic/core/congestion_control/general_loss_algorithm.h
@@ -29,6 +29,9 @@ ~GeneralLossAlgorithm() override {} LossDetectionType GetLossDetectionType() const override; + + // Switches the loss detection type to |loss_type| and resets the loss + // algorithm. void SetLossDetectionType(LossDetectionType loss_type); // Uses |largest_acked| and time to decide when packets are lost. @@ -52,11 +55,11 @@ int reordering_shift() const { return reordering_shift_; } private: - LossDetectionType loss_type_; QuicTime loss_detection_timeout_; // Largest sent packet when a spurious retransmit is detected. // Prevents increasing the reordering threshold multiple times per epoch. QuicPacketNumber largest_sent_on_spurious_retransmit_; + LossDetectionType loss_type_; // Fraction of a max(SRTT, latest_rtt) to permit reordering before declaring // loss. Fraction calculated by shifting max(SRTT, latest_rtt) to the right // by reordering_shift.
diff --git a/net/quic/core/congestion_control/pacing_sender.cc b/net/quic/core/congestion_control/pacing_sender.cc index 1d63947..cc2c40b 100644 --- a/net/quic/core/congestion_control/pacing_sender.cc +++ b/net/quic/core/congestion_control/pacing_sender.cc
@@ -4,6 +4,8 @@ #include "net/quic/core/congestion_control/pacing_sender.h" +#include <string> + #include "net/quic/core/quic_flags.h" using std::min; @@ -27,47 +29,21 @@ burst_tokens_(kInitialUnpacedBurst), last_delayed_packet_sent_time_(QuicTime::Zero()), ideal_next_packet_send_time_(QuicTime::Zero()), - was_last_send_delayed_(false), - owns_sender_(false) {} + was_last_send_delayed_(false) {} -PacingSender::~PacingSender() { - if (owns_sender_) { - delete sender_; - } -} +PacingSender::~PacingSender() {} -void PacingSender::SetFromConfig(const QuicConfig& config, - Perspective perspective) { - sender_->SetFromConfig(config, perspective); -} - -void PacingSender::ResumeConnectionState( - const CachedNetworkParameters& cached_network_params, - bool max_bandwidth_resumption) { - sender_->ResumeConnectionState(cached_network_params, - max_bandwidth_resumption); -} - -void PacingSender::SetNumEmulatedConnections(int num_connections) { - sender_->SetNumEmulatedConnections(num_connections); -} - -void PacingSender::SetMaxPacingRate(QuicBandwidth max_pacing_rate) { - max_pacing_rate_ = max_pacing_rate; -} - -void PacingSender::SetSender(SendAlgorithmInterface* sender, bool owns_sender) { - if (owns_sender_) { - delete sender_; - } +void PacingSender::set_sender(SendAlgorithmInterface* sender) { + DCHECK(sender != nullptr); sender_ = sender; - owns_sender_ = owns_sender; } -void PacingSender::OnCongestionEvent(bool rtt_updated, - QuicByteCount bytes_in_flight, - const CongestionVector& acked_packets, - const CongestionVector& lost_packets) { +void PacingSender::OnCongestionEvent( + bool rtt_updated, + QuicByteCount bytes_in_flight, + const SendAlgorithmInterface::CongestionVector& acked_packets, + const SendAlgorithmInterface::CongestionVector& lost_packets) { + DCHECK(sender_ != nullptr); if (!lost_packets.empty()) { // Clear any burst tokens when entering recovery. burst_tokens_ = 0; @@ -82,6 +58,7 @@ QuicPacketNumber packet_number, QuicByteCount bytes, HasRetransmittableData has_retransmittable_data) { + DCHECK(sender_ != nullptr); const bool in_flight = sender_->OnPacketSent(sent_time, bytes_in_flight, packet_number, bytes, has_retransmittable_data); @@ -135,17 +112,10 @@ return in_flight; } -void PacingSender::OnRetransmissionTimeout(bool packets_retransmitted) { - sender_->OnRetransmissionTimeout(packets_retransmitted); -} - -void PacingSender::OnConnectionMigration() { - sender_->OnConnectionMigration(); -} - QuicTime::Delta PacingSender::TimeUntilSend( QuicTime now, QuicByteCount bytes_in_flight) const { + DCHECK(sender_ != nullptr); QuicTime::Delta time_until_send = sender_->TimeUntilSend(now, bytes_in_flight); if (burst_tokens_ > 0 || bytes_in_flight == 0) { @@ -172,6 +142,7 @@ } QuicBandwidth PacingSender::PacingRate(QuicByteCount bytes_in_flight) const { + DCHECK(sender_ != nullptr); if (!max_pacing_rate_.IsZero()) { return QuicBandwidth::FromBitsPerSecond( min(max_pacing_rate_.ToBitsPerSecond(), @@ -180,32 +151,4 @@ return sender_->PacingRate(bytes_in_flight); } -QuicBandwidth PacingSender::BandwidthEstimate() const { - return sender_->BandwidthEstimate(); -} - -QuicTime::Delta PacingSender::RetransmissionDelay() const { - return sender_->RetransmissionDelay(); -} - -QuicByteCount PacingSender::GetCongestionWindow() const { - return sender_->GetCongestionWindow(); -} - -bool PacingSender::InSlowStart() const { - return sender_->InSlowStart(); -} - -bool PacingSender::InRecovery() const { - return sender_->InRecovery(); -} - -QuicByteCount PacingSender::GetSlowStartThreshold() const { - return sender_->GetSlowStartThreshold(); -} - -CongestionControlType PacingSender::GetCongestionControlType() const { - return sender_->GetCongestionControlType(); -} - } // namespace net
diff --git a/net/quic/core/congestion_control/pacing_sender.h b/net/quic/core/congestion_control/pacing_sender.h index 6b44967..9349871 100644 --- a/net/quic/core/congestion_control/pacing_sender.h +++ b/net/quic/core/congestion_control/pacing_sender.h
@@ -25,48 +25,36 @@ namespace net { -class NET_EXPORT_PRIVATE PacingSender : public SendAlgorithmInterface { +class NET_EXPORT_PRIVATE PacingSender { public: PacingSender(); - ~PacingSender() override; + ~PacingSender(); - void SetMaxPacingRate(QuicBandwidth max_pacing_rate); - // Sets the underlying sender. Takes ownership of |sender| if |owns_sender| is - // true. - void SetSender(SendAlgorithmInterface* sender, bool owns_sender); + // Sets the underlying sender. Does not take ownership of |sender|. |sender| + // must not be null. This must be called before any of the + // SendAlgorithmInterface wrapper methods are called. + void set_sender(SendAlgorithmInterface* sender); - // SendAlgorithmInterface methods. - void SetFromConfig(const QuicConfig& config, - Perspective perspective) override; - void ResumeConnectionState( - const CachedNetworkParameters& cached_network_params, - bool max_bandwidth_resumption) override; - void SetNumEmulatedConnections(int num_connections) override; - void OnCongestionEvent(bool rtt_updated, - QuicByteCount bytes_in_flight, - const CongestionVector& acked_packets, - const CongestionVector& lost_packets) override; + void set_max_pacing_rate(QuicBandwidth max_pacing_rate) { + max_pacing_rate_ = max_pacing_rate; + } + + void OnCongestionEvent( + bool rtt_updated, + QuicByteCount bytes_in_flight, + const SendAlgorithmInterface::CongestionVector& acked_packets, + const SendAlgorithmInterface::CongestionVector& lost_packets); bool OnPacketSent(QuicTime sent_time, QuicByteCount bytes_in_flight, QuicPacketNumber packet_number, QuicByteCount bytes, - HasRetransmittableData is_retransmittable) override; - void OnRetransmissionTimeout(bool packets_retransmitted) override; - void OnConnectionMigration() override; + HasRetransmittableData is_retransmittable); QuicTime::Delta TimeUntilSend(QuicTime now, - QuicByteCount bytes_in_flight) const override; - QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const override; - QuicBandwidth BandwidthEstimate() const override; - QuicTime::Delta RetransmissionDelay() const override; - QuicByteCount GetCongestionWindow() const override; - bool InSlowStart() const override; - bool InRecovery() const override; - QuicByteCount GetSlowStartThreshold() const override; - CongestionControlType GetCongestionControlType() const override; - // End implementation of SendAlgorithmInterface. + QuicByteCount bytes_in_flight) const; + QuicBandwidth PacingRate(QuicByteCount bytes_in_flight) const; private: - // Underlying sender. Owned if |owns_sender_| is true. + // Underlying sender. Not owned. SendAlgorithmInterface* sender_; // If not QuicBandidth::Zero, the maximum rate the PacingSender will use. QuicBandwidth max_pacing_rate_; @@ -77,7 +65,6 @@ QuicTime last_delayed_packet_sent_time_; QuicTime ideal_next_packet_send_time_; // When can the next packet be sent. mutable bool was_last_send_delayed_; // True when the last send was delayed. - bool owns_sender_; // True if PacingSender owns |sender_|. DISALLOW_COPY_AND_ASSIGN(PacingSender); };
diff --git a/net/quic/core/congestion_control/pacing_sender_test.cc b/net/quic/core/congestion_control/pacing_sender_test.cc index cefcdae..2a6073f 100644 --- a/net/quic/core/congestion_control/pacing_sender_test.cc +++ b/net/quic/core/congestion_control/pacing_sender_test.cc
@@ -30,7 +30,7 @@ packet_number_(1), mock_sender_(new StrictMock<MockSendAlgorithm>()), pacing_sender_(new PacingSender) { - pacing_sender_->SetSender(mock_sender_, true); + pacing_sender_->set_sender(mock_sender_.get()); // Pick arbitrary time. clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(9)); } @@ -38,9 +38,9 @@ ~PacingSenderTest() override {} void InitPacingRate(QuicPacketCount burst_size, QuicBandwidth bandwidth) { - mock_sender_ = new StrictMock<MockSendAlgorithm>(); + mock_sender_.reset(new StrictMock<MockSendAlgorithm>()); pacing_sender_.reset(new PacingSender); - pacing_sender_->SetSender(mock_sender_, true); + pacing_sender_->set_sender(mock_sender_.get()); EXPECT_CALL(*mock_sender_, PacingRate(_)).WillRepeatedly(Return(bandwidth)); if (burst_size == 0) { EXPECT_CALL(*mock_sender_, OnCongestionEvent(_, _, _, _)); @@ -49,7 +49,9 @@ SendAlgorithmInterface::CongestionVector empty; pacing_sender_->OnCongestionEvent(true, 1234, empty, lost_packets); } else if (burst_size != kInitialBurstPackets) { - LOG(FATAL) << "Unsupported burst_size specificied."; + LOG(FATAL) << "Unsupported burst_size " << burst_size + << " specificied, only 0 and " << kInitialBurstPackets + << " are supported."; } } @@ -107,7 +109,7 @@ const QuicTime::Delta infinite_time_; MockClock clock_; QuicPacketNumber packet_number_; - StrictMock<MockSendAlgorithm>* mock_sender_; + std::unique_ptr<StrictMock<MockSendAlgorithm>> mock_sender_; std::unique_ptr<PacingSender> pacing_sender_; }; @@ -343,72 +345,5 @@ CheckPacketIsDelayed(QuicTime::Delta::FromMilliseconds(2)); } -TEST_F(PacingSenderTest, VerifyInnerSenderCalled) { - // Configure pacing rate of 1 packet per 1 ms with no burst tokens. - InitPacingRate(0, QuicBandwidth::FromBytesAndTimeDelta( - kMaxPacketSize, QuicTime::Delta::FromMilliseconds(1))); - QuicBandwidth kBandwidth = QuicBandwidth::FromBitsPerSecond(1000); - QuicTime kTime = QuicTime::Infinite(); - QuicTime::Delta kTimeDelta = QuicTime::Delta::Infinite(); - QuicByteCount kBytes = 12345u; - - EXPECT_CALL(*mock_sender_, SetFromConfig(_, Perspective::IS_SERVER)); - QuicConfig config; - pacing_sender_->SetFromConfig(config, Perspective::IS_SERVER); - - EXPECT_CALL(*mock_sender_, ResumeConnectionState(_, true)); - CachedNetworkParameters cached_network_params; - pacing_sender_->ResumeConnectionState(cached_network_params, true); - - EXPECT_CALL(*mock_sender_, SetNumEmulatedConnections(2)); - pacing_sender_->SetNumEmulatedConnections(2); - - SendAlgorithmInterface::CongestionVector packets; - EXPECT_CALL(*mock_sender_, OnCongestionEvent(true, kBytes, packets, packets)); - pacing_sender_->OnCongestionEvent(true, kBytes, packets, packets); - - EXPECT_CALL(*mock_sender_, OnPacketSent(kTime, kBytes, 123u, kBytes, - HAS_RETRANSMITTABLE_DATA)); - EXPECT_CALL(*mock_sender_, PacingRate(_)).WillOnce(Return(kBandwidth)); - pacing_sender_->OnPacketSent(kTime, kBytes, 123u, kBytes, - HAS_RETRANSMITTABLE_DATA); - - EXPECT_CALL(*mock_sender_, OnRetransmissionTimeout(true)); - pacing_sender_->OnRetransmissionTimeout(true); - - EXPECT_CALL(*mock_sender_, OnConnectionMigration()); - pacing_sender_->OnConnectionMigration(); - - EXPECT_CALL(*mock_sender_, TimeUntilSend(kTime, kBytes)) - .WillOnce(Return(kTimeDelta)); - pacing_sender_->TimeUntilSend(kTime, kBytes); - - EXPECT_CALL(*mock_sender_, PacingRate(_)).WillOnce(Return(kBandwidth)); - EXPECT_EQ(kBandwidth, pacing_sender_->PacingRate(0)); - - EXPECT_CALL(*mock_sender_, BandwidthEstimate()).WillOnce(Return(kBandwidth)); - EXPECT_EQ(kBandwidth, pacing_sender_->BandwidthEstimate()); - - EXPECT_CALL(*mock_sender_, RetransmissionDelay()) - .WillOnce(Return(kTimeDelta)); - EXPECT_EQ(kTimeDelta, pacing_sender_->RetransmissionDelay()); - - EXPECT_CALL(*mock_sender_, GetCongestionWindow()).WillOnce(Return(kBytes)); - EXPECT_EQ(kBytes, pacing_sender_->GetCongestionWindow()); - - EXPECT_CALL(*mock_sender_, InSlowStart()).WillOnce(Return(true)); - EXPECT_TRUE(pacing_sender_->InSlowStart()); - - EXPECT_CALL(*mock_sender_, InRecovery()).WillOnce(Return(true)); - EXPECT_TRUE(pacing_sender_->InRecovery()); - - EXPECT_CALL(*mock_sender_, GetSlowStartThreshold()).WillOnce(Return(kBytes)); - EXPECT_EQ(kBytes, pacing_sender_->GetSlowStartThreshold()); - - EXPECT_CALL(*mock_sender_, GetCongestionControlType()) - .WillOnce(Return(kReno)); - EXPECT_EQ(kReno, pacing_sender_->GetCongestionControlType()); -} - } // namespace test } // namespace net
diff --git a/net/quic/core/congestion_control/send_algorithm_interface.h b/net/quic/core/congestion_control/send_algorithm_interface.h index 24efde36..b9c1d4c 100644 --- a/net/quic/core/congestion_control/send_algorithm_interface.h +++ b/net/quic/core/congestion_control/send_algorithm_interface.h
@@ -117,6 +117,24 @@ virtual void ResumeConnectionState( const CachedNetworkParameters& cached_network_params, bool max_bandwidth_resumption) = 0; + + // Retrieves debugging information about the current state of the + // send algorithm. + virtual std::string GetDebugState() const = 0; + + // Called when the connection has no outstanding data to send. Specifically, + // this means that none of the data streams are write-blocked, there are no + // packets in the connection queue, and there are no pending retransmissins, + // i.e. the sender cannot send anything for reasons other than being blocked + // by congestion controller. This includes cases when the connection is + // blocked by the flow controller. + // + // The fact that this method is called does not necessarily imply that the + // connection would not be blocked by the congestion control if it actually + // tried to send data. If the congestion control algorithm needs to exclude + // such cases, it should use the internal state it uses for congestion control + // for that. + virtual void OnApplicationLimited(QuicByteCount bytes_in_flight) = 0; }; } // namespace net
diff --git a/net/quic/core/congestion_control/send_algorithm_simulator.cc b/net/quic/core/congestion_control/send_algorithm_simulator.cc index b6cce65..bdb8b91 100644 --- a/net/quic/core/congestion_control/send_algorithm_simulator.cc +++ b/net/quic/core/congestion_control/send_algorithm_simulator.cc
@@ -92,18 +92,23 @@ } void SendAlgorithmSimulator::TransferBytes() { - TransferBytes(std::numeric_limits<uint64_t>::max(), - QuicTime::Delta::Infinite()); + TransferBytesUntil([](QuicTime, QuicByteCount) { return false; }); } void SendAlgorithmSimulator::TransferBytes(QuicByteCount max_bytes, QuicTime::Delta max_time) { - const QuicTime end_time = max_time.IsInfinite() - ? QuicTime::Zero() + QuicTime::Delta::Infinite() - : clock_->Now() + max_time; + const QuicTime start_time = clock_->Now(); + TransferBytesUntil([=](QuicTime now, QuicByteCount bytes_sent) { + return bytes_sent >= max_bytes || now - start_time > max_time; + }); +} + +template <class TerminationPredicate> +bool SendAlgorithmSimulator::TransferBytesUntil( + TerminationPredicate termination_predicate) { QuicByteCount bytes_sent = 0; - while (!pending_transfers_.empty() && clock_->Now() < end_time && - bytes_sent < max_bytes) { + while (!pending_transfers_.empty() && + !termination_predicate(clock_->Now(), bytes_sent)) { // Determine the times of next send and of the next ack arrival. PacketEvent send_event = NextSendEvent(); PacketEvent ack_event = NextAckEvent(); @@ -133,6 +138,8 @@ bytes_sent += kPacketSize; } } + + return !pending_transfers_.empty(); } SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextSendEvent() {
diff --git a/net/quic/core/congestion_control/send_algorithm_simulator.h b/net/quic/core/congestion_control/send_algorithm_simulator.h index fd93e27e..9b3974b 100644 --- a/net/quic/core/congestion_control/send_algorithm_simulator.h +++ b/net/quic/core/congestion_control/send_algorithm_simulator.h
@@ -168,10 +168,17 @@ void TransferBytes(); // Transfers bytes through the connection until |max_bytes| are reached, - // |max_time| is reached, or all senders have finished sending. If max_bytes - // is 0, it does not apply, and if |max_time| is Zero, no time limit applies. + // |max_time| is reached, or all senders have finished sending. If |max_time| + // is Zero, no time limit applies. void TransferBytes(QuicByteCount max_bytes, QuicTime::Delta max_time); + // Transfers bytes through the connection until the supplied termination + // predicate returns true, or until all senders have finished sending. + // Returns true if the transfer was terminated due to the predicate, and false + // otherwise. + template <class TerminationPredicate> + bool TransferBytesUntil(TerminationPredicate termination_predicate); + private: // A pending packet event, either a send or an ack. struct PacketEvent {
diff --git a/net/quic/core/congestion_control/tcp_cubic_sender_base.cc b/net/quic/core/congestion_control/tcp_cubic_sender_base.cc index caa02eb..6d24820 100644 --- a/net/quic/core/congestion_control/tcp_cubic_sender_base.cc +++ b/net/quic/core/congestion_control/tcp_cubic_sender_base.cc
@@ -5,6 +5,7 @@ #include "net/quic/core/congestion_control/tcp_cubic_sender_base.h" #include <algorithm> +#include <string> #include "base/metrics/histogram_macros.h" #include "net/quic/core/congestion_control/prr_sender.h" @@ -283,4 +284,10 @@ last_cutback_exited_slowstart_ = false; } +std::string TcpCubicSenderBase::GetDebugState() const { + return ""; +} + +void TcpCubicSenderBase::OnApplicationLimited(QuicByteCount bytes_in_flight) {} + } // namespace net
diff --git a/net/quic/core/congestion_control/tcp_cubic_sender_base.h b/net/quic/core/congestion_control/tcp_cubic_sender_base.h index b85d263d..a6ddff39 100644 --- a/net/quic/core/congestion_control/tcp_cubic_sender_base.h +++ b/net/quic/core/congestion_control/tcp_cubic_sender_base.h
@@ -66,6 +66,8 @@ QuicTime::Delta RetransmissionDelay() const override; bool InSlowStart() const override; bool InRecovery() const override; + std::string GetDebugState() const override; + void OnApplicationLimited(QuicByteCount bytes_in_flight) override; protected: // Called when resuming a previous bandwidth.
diff --git a/net/quic/core/crypto/common_cert_set.cc b/net/quic/core/crypto/common_cert_set.cc index 57132a2..5b68b63 100644 --- a/net/quic/core/crypto/common_cert_set.cc +++ b/net/quic/core/crypto/common_cert_set.cc
@@ -15,14 +15,14 @@ namespace net { -namespace common_cert_set_1 { -#include "net/quic/core/crypto/common_cert_set_1.c" -} - namespace common_cert_set_2 { #include "net/quic/core/crypto/common_cert_set_2.c" } +namespace common_cert_set_3 { +#include "net/quic/core/crypto/common_cert_set_3.c" +} + namespace { struct CertSet { @@ -39,17 +39,17 @@ const CertSet kSets[] = { { - common_cert_set_1::kNumCerts, common_cert_set_1::kCerts, - common_cert_set_1::kLens, common_cert_set_1::kHash, - }, - { common_cert_set_2::kNumCerts, common_cert_set_2::kCerts, common_cert_set_2::kLens, common_cert_set_2::kHash, }, + { + common_cert_set_3::kNumCerts, common_cert_set_3::kCerts, + common_cert_set_3::kLens, common_cert_set_3::kHash, + }, }; const uint64_t kSetHashes[] = { - common_cert_set_1::kHash, common_cert_set_2::kHash, + common_cert_set_2::kHash, common_cert_set_3::kHash, }; // Compare returns a value less than, equal to or greater than zero if |a| is
diff --git a/net/quic/core/crypto/common_cert_set_1.c b/net/quic/core/crypto/common_cert_set_1.c deleted file mode 100644 index 3c61925d..0000000 --- a/net/quic/core/crypto/common_cert_set_1.c +++ /dev/null
@@ -1,145 +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. - */ - -/* This file contains common certificates. It's designed to be #included in - * another file, in a namespace. */ - -#include <stdint.h> - -#include "net/quic/core/crypto/common_cert_set_1a.inc" -#include "net/quic/core/crypto/common_cert_set_1b.inc" - -static const size_t kNumCerts = 62; -static const unsigned char* const kCerts[] = { - kDERCert0, - kDERCert1, - kDERCert2, - kDERCert3, - kDERCert4, - kDERCert5, - kDERCert6, - kDERCert7, - kDERCert8, - kDERCert9, - kDERCert10, - kDERCert11, - kDERCert12, - kDERCert13, - kDERCert14, - kDERCert15, - kDERCert16, - kDERCert17, - kDERCert18, - kDERCert19, - kDERCert20, - kDERCert21, - kDERCert22, - kDERCert23, - kDERCert24, - kDERCert25, - kDERCert26, - kDERCert27, - kDERCert28, - kDERCert29, - kDERCert30, - kDERCert31, - kDERCert32, - kDERCert33, - kDERCert34, - kDERCert35, - kDERCert36, - kDERCert37, - kDERCert38, - kDERCert39, - kDERCert40, - kDERCert41, - kDERCert42, - kDERCert43, - kDERCert44, - kDERCert45, - kDERCert46, - kDERCert47, - kDERCert48, - kDERCert49, - kDERCert50, - kDERCert51, - kDERCert52, - kDERCert53, - kDERCert54, - kDERCert55, - kDERCert56, - kDERCert57, - kDERCert58, - kDERCert59, - kDERCert60, - kDERCert61, -}; - -static const size_t kLens[] = { - 897, - 911, - 985, - 989, - 1012, - 1022, - 1049, - 1055, - 1071, - 1080, - 1084, - 1088, - 1097, - 1098, - 1105, - 1107, - 1117, - 1124, - 1127, - 1133, - 1136, - 1153, - 1171, - 1171, - 1172, - 1176, - 1182, - 1188, - 1191, - 1194, - 1194, - 1199, - 1205, - 1210, - 1226, - 1236, - 1236, - 1238, - 1250, - 1254, - 1256, - 1257, - 1269, - 1270, - 1280, - 1284, - 1285, - 1287, - 1290, - 1291, - 1291, - 1294, - 1297, - 1385, - 1512, - 1520, - 1548, - 1570, - 1581, - 1628, - 1712, - 1770, -}; - -static const uint64_t kHash = UINT64_C(0xff715ce4e7e9267b);
diff --git a/net/quic/core/crypto/common_cert_set_1a.inc b/net/quic/core/crypto/common_cert_set_1a.inc deleted file mode 100644 index 23aef213..0000000 --- a/net/quic/core/crypto/common_cert_set_1a.inc +++ /dev/null
@@ -1,10166 +0,0 @@ -/* Copyright (c) 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 contains common certificates. It's designed to be #included in - * another file, in a namespace. */ - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 1227750 (0x12bbe6) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=Equifax, OU=Equifax Secure Certificate Authority - Validity - Not Before: May 21 04:00:00 2002 GMT - Not After : Aug 21 04:00:00 2018 GMT - Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:da:cc:18:63:30:fd:f4:17:23:1a:56:7e:5b:df: - 3c:6c:38:e4:71:b7:78:91:d4:bc:a1:d8:4c:f8:a8: - 43:b6:03:e9:4d:21:07:08:88:da:58:2f:66:39:29: - bd:05:78:8b:9d:38:e8:05:b7:6a:7e:71:a4:e6:c4: - 60:a6:b0:ef:80:e4:89:28:0f:9e:25:d6:ed:83:f3: - ad:a6:91:c7:98:c9:42:18:35:14:9d:ad:98:46:92: - 2e:4f:ca:f1:87:43:c1:16:95:57:2d:50:ef:89:2d: - 80:7a:57:ad:f2:ee:5f:6b:d2:00:8d:b9:14:f8:14: - 15:35:d9:c0:46:a3:7b:72:c8:91:bf:c9:55:2b:cd: - d0:97:3e:9c:26:64:cc:df:ce:83:19:71:ca:4e:e6: - d4:d5:7b:a9:19:cd:55:de:c8:ec:d2:5e:38:53:e5: - 5c:4f:8c:2d:fe:50:23:36:fc:66:e6:cb:8e:a4:39: - 19:00:b7:95:02:39:91:0b:0e:fe:38:2e:d1:1d:05: - 9a:f6:4d:3e:6f:0f:07:1d:af:2c:1e:8f:60:39:e2: - fa:36:53:13:39:d4:5e:26:2b:db:3d:a8:14:bd:32: - eb:18:03:28:52:04:71:e5:ab:33:3d:e1:38:bb:07: - 36:84:62:9c:79:ea:16:30:f4:5f:c0:2b:e8:71:6b: - e4:f9 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Authority Key Identifier: - keyid:48:E6:68:F9:2B:D2:B2:95:D7:47:D8:23:20:10:4F:33:98:90:9F:D4 - - X509v3 Subject Key Identifier: - C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.geotrust.com/crls/secureca.crl - - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://www.geotrust.com/resources/repository - - Signature Algorithm: sha1WithRSAEncryption - 76:e1:12:6e:4e:4b:16:12:86:30:06:b2:81:08:cf:f0:08:c7: - c7:71:7e:66:ee:c2:ed:d4:3b:1f:ff:f0:f0:c8:4e:d6:43:38: - b0:b9:30:7d:18:d0:55:83:a2:6a:cb:36:11:9c:e8:48:66:a3: - 6d:7f:b8:13:d4:47:fe:8b:5a:5c:73:fc:ae:d9:1b:32:19:38: - ab:97:34:14:aa:96:d2:eb:a3:1c:14:08:49:b6:bb:e5:91:ef: - 83:36:eb:1d:56:6f:ca:da:bc:73:63:90:e4:7f:7b:3e:22:cb: - 3d:07:ed:5f:38:74:9c:e3:03:50:4e:a1:af:98:ee:61:f2:84: - 3f:12 ------BEGIN CERTIFICATE----- -MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT -MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0 -aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDIwNTIxMDQwMDAwWhcNMTgwODIxMDQwMDAw -WjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UE -AxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9m -OSm9BXiLnTjoBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIu -T8rxh0PBFpVXLVDviS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6c -JmTM386DGXHKTubU1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmR -Cw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5asz -PeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo4HwMIHtMB8GA1UdIwQYMBaAFEjm -aPkr0rKV10fYIyAQTzOYkJ/UMB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrM -TjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjA6BgNVHR8EMzAxMC+g -LaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL3NlY3VyZWNhLmNybDBO -BgNVHSAERzBFMEMGBFUdIAAwOzA5BggrBgEFBQcCARYtaHR0cHM6Ly93d3cuZ2Vv -dHJ1c3QuY29tL3Jlc291cmNlcy9yZXBvc2l0b3J5MA0GCSqGSIb3DQEBBQUAA4GB -AHbhEm5OSxYShjAGsoEIz/AIx8dxfmbuwu3UOx//8PDITtZDOLC5MH0Y0FWDomrL -NhGc6Ehmo21/uBPUR/6LWlxz/K7ZGzIZOKuXNBSqltLroxwUCEm2u+WR74M26x1W -b8ravHNjkOR/ez4iyz0H7V84dJzjA1BOoa+Y7mHyhD8S ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert0[] = { - 0x30, 0x82, 0x03, 0x7d, 0x30, 0x82, 0x02, 0xe6, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x03, 0x12, 0xbb, 0xe6, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4e, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, - 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x07, 0x45, - 0x71, 0x75, 0x69, 0x66, 0x61, 0x78, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, - 0x55, 0x04, 0x0b, 0x13, 0x24, 0x45, 0x71, 0x75, 0x69, 0x66, 0x61, 0x78, - 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x32, 0x30, - 0x35, 0x32, 0x31, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, - 0x31, 0x38, 0x30, 0x38, 0x32, 0x31, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, - 0x5a, 0x30, 0x42, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, - 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x13, 0x12, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, - 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x43, 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, 0xda, 0xcc, 0x18, 0x63, 0x30, 0xfd, - 0xf4, 0x17, 0x23, 0x1a, 0x56, 0x7e, 0x5b, 0xdf, 0x3c, 0x6c, 0x38, 0xe4, - 0x71, 0xb7, 0x78, 0x91, 0xd4, 0xbc, 0xa1, 0xd8, 0x4c, 0xf8, 0xa8, 0x43, - 0xb6, 0x03, 0xe9, 0x4d, 0x21, 0x07, 0x08, 0x88, 0xda, 0x58, 0x2f, 0x66, - 0x39, 0x29, 0xbd, 0x05, 0x78, 0x8b, 0x9d, 0x38, 0xe8, 0x05, 0xb7, 0x6a, - 0x7e, 0x71, 0xa4, 0xe6, 0xc4, 0x60, 0xa6, 0xb0, 0xef, 0x80, 0xe4, 0x89, - 0x28, 0x0f, 0x9e, 0x25, 0xd6, 0xed, 0x83, 0xf3, 0xad, 0xa6, 0x91, 0xc7, - 0x98, 0xc9, 0x42, 0x18, 0x35, 0x14, 0x9d, 0xad, 0x98, 0x46, 0x92, 0x2e, - 0x4f, 0xca, 0xf1, 0x87, 0x43, 0xc1, 0x16, 0x95, 0x57, 0x2d, 0x50, 0xef, - 0x89, 0x2d, 0x80, 0x7a, 0x57, 0xad, 0xf2, 0xee, 0x5f, 0x6b, 0xd2, 0x00, - 0x8d, 0xb9, 0x14, 0xf8, 0x14, 0x15, 0x35, 0xd9, 0xc0, 0x46, 0xa3, 0x7b, - 0x72, 0xc8, 0x91, 0xbf, 0xc9, 0x55, 0x2b, 0xcd, 0xd0, 0x97, 0x3e, 0x9c, - 0x26, 0x64, 0xcc, 0xdf, 0xce, 0x83, 0x19, 0x71, 0xca, 0x4e, 0xe6, 0xd4, - 0xd5, 0x7b, 0xa9, 0x19, 0xcd, 0x55, 0xde, 0xc8, 0xec, 0xd2, 0x5e, 0x38, - 0x53, 0xe5, 0x5c, 0x4f, 0x8c, 0x2d, 0xfe, 0x50, 0x23, 0x36, 0xfc, 0x66, - 0xe6, 0xcb, 0x8e, 0xa4, 0x39, 0x19, 0x00, 0xb7, 0x95, 0x02, 0x39, 0x91, - 0x0b, 0x0e, 0xfe, 0x38, 0x2e, 0xd1, 0x1d, 0x05, 0x9a, 0xf6, 0x4d, 0x3e, - 0x6f, 0x0f, 0x07, 0x1d, 0xaf, 0x2c, 0x1e, 0x8f, 0x60, 0x39, 0xe2, 0xfa, - 0x36, 0x53, 0x13, 0x39, 0xd4, 0x5e, 0x26, 0x2b, 0xdb, 0x3d, 0xa8, 0x14, - 0xbd, 0x32, 0xeb, 0x18, 0x03, 0x28, 0x52, 0x04, 0x71, 0xe5, 0xab, 0x33, - 0x3d, 0xe1, 0x38, 0xbb, 0x07, 0x36, 0x84, 0x62, 0x9c, 0x79, 0xea, 0x16, - 0x30, 0xf4, 0x5f, 0xc0, 0x2b, 0xe8, 0x71, 0x6b, 0xe4, 0xf9, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xa3, 0x81, 0xf0, 0x30, 0x81, 0xed, 0x30, 0x1f, 0x06, - 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x48, 0xe6, - 0x68, 0xf9, 0x2b, 0xd2, 0xb2, 0x95, 0xd7, 0x47, 0xd8, 0x23, 0x20, 0x10, - 0x4f, 0x33, 0x98, 0x90, 0x9f, 0xd4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, - 0x0e, 0x04, 0x16, 0x04, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, - 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, - 0x4e, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, - 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, - 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3a, - 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, 0xa0, - 0x2d, 0xa0, 0x2b, 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x73, 0x65, - 0x63, 0x75, 0x72, 0x65, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x4e, - 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x47, 0x30, 0x45, 0x30, 0x43, 0x06, - 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x2d, 0x68, 0x74, 0x74, - 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, - 0x00, 0x76, 0xe1, 0x12, 0x6e, 0x4e, 0x4b, 0x16, 0x12, 0x86, 0x30, 0x06, - 0xb2, 0x81, 0x08, 0xcf, 0xf0, 0x08, 0xc7, 0xc7, 0x71, 0x7e, 0x66, 0xee, - 0xc2, 0xed, 0xd4, 0x3b, 0x1f, 0xff, 0xf0, 0xf0, 0xc8, 0x4e, 0xd6, 0x43, - 0x38, 0xb0, 0xb9, 0x30, 0x7d, 0x18, 0xd0, 0x55, 0x83, 0xa2, 0x6a, 0xcb, - 0x36, 0x11, 0x9c, 0xe8, 0x48, 0x66, 0xa3, 0x6d, 0x7f, 0xb8, 0x13, 0xd4, - 0x47, 0xfe, 0x8b, 0x5a, 0x5c, 0x73, 0xfc, 0xae, 0xd9, 0x1b, 0x32, 0x19, - 0x38, 0xab, 0x97, 0x34, 0x14, 0xaa, 0x96, 0xd2, 0xeb, 0xa3, 0x1c, 0x14, - 0x08, 0x49, 0xb6, 0xbb, 0xe5, 0x91, 0xef, 0x83, 0x36, 0xeb, 0x1d, 0x56, - 0x6f, 0xca, 0xda, 0xbc, 0x73, 0x63, 0x90, 0xe4, 0x7f, 0x7b, 0x3e, 0x22, - 0xcb, 0x3d, 0x07, 0xed, 0x5f, 0x38, 0x74, 0x9c, 0xe3, 0x03, 0x50, 0x4e, - 0xa1, 0xaf, 0x98, 0xee, 0x61, 0xf2, 0x84, 0x3f, 0x12, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 880226 (0xd6e62) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=Equifax, OU=Equifax Secure Certificate Authority - Validity - Not Before: Nov 27 00:00:00 2006 GMT - Not After : Aug 21 16:15:00 2018 GMT - Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:be:b8:15:7b:ff:d4:7c:7d:67:ad:83:64:7b:c8: - 42:53:2d:df:f6:84:08:20:61:d6:01:59:6a:9c:44: - 11:af:ef:76:fd:95:7e:ce:61:30:bb:7a:83:5f:02: - bd:01:66:ca:ee:15:8d:6f:a1:30:9c:bd:a1:85:9e: - 94:3a:f3:56:88:00:31:cf:d8:ee:6a:96:02:d9:ed: - 03:8c:fb:75:6d:e7:ea:b8:55:16:05:16:9a:f4:e0: - 5e:b1:88:c0:64:85:5c:15:4d:88:c7:b7:ba:e0:75: - e9:ad:05:3d:9d:c7:89:48:e0:bb:28:c8:03:e1:30: - 93:64:5e:52:c0:59:70:22:35:57:88:8a:f1:95:0a: - 83:d7:bc:31:73:01:34:ed:ef:46:71:e0:6b:02:a8: - 35:72:6b:97:9b:66:e0:cb:1c:79:5f:d8:1a:04:68: - 1e:47:02:e6:9d:60:e2:36:97:01:df:ce:35:92:df: - be:67:c7:6d:77:59:3b:8f:9d:d6:90:15:94:bc:42: - 34:10:c1:39:f9:b1:27:3e:7e:d6:8a:75:c5:b2:af: - 96:d3:a2:de:9b:e4:98:be:7d:e1:e9:81:ad:b6:6f: - fc:d7:0e:da:e0:34:b0:0d:1a:77:e7:e3:08:98:ef: - 58:fa:9c:84:b7:36:af:c2:df:ac:d2:f4:10:06:70: - 71:35 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Subject Key Identifier: - 2C:D5:50:41:97:15:8B:F0:8F:36:61:5B:4A:FB:6B:D9:99:C9:33:92 - X509v3 Authority Key Identifier: - keyid:48:E6:68:F9:2B:D2:B2:95:D7:47:D8:23:20:10:4F:33:98:90:9F:D4 - - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.geotrust.com/crls/secureca.crl - - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: http://www.geotrust.com/resources/cps - - Signature Algorithm: sha1WithRSAEncryption - af:f3:0e:d6:72:ab:c7:a9:97:ca:2a:6b:84:39:de:79:a9:f0: - 81:e5:08:67:ab:d7:2f:20:02:01:71:0c:04:22:c9:1e:88:95: - 03:c9:49:3a:af:67:08:49:b0:d5:08:f5:20:3d:80:91:a0:c5: - 87:a3:fb:c9:a3:17:91:f9:a8:2f:ae:e9:0f:df:96:72:0f:75: - 17:80:5d:78:01:4d:9f:1f:6d:7b:d8:f5:42:38:23:1a:99:93: - f4:83:be:3b:35:74:e7:37:13:35:7a:ac:b4:b6:90:82:6c:27: - a4:e0:ec:9e:35:bd:bf:e5:29:a1:47:9f:5b:32:fc:e9:99:7d: - 2b:39 ------BEGIN CERTIFICATE----- -MIIDizCCAvSgAwIBAgIDDW5iMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT -MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0 -aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMTI3MDAwMDAwWhcNMTgwODIxMTYxNTAw -WjBYMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UE -AxMoR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL64FXv/1Hx9Z62DZHvIQlMt3/aE -CCBh1gFZapxEEa/vdv2Vfs5hMLt6g18CvQFmyu4VjW+hMJy9oYWelDrzVogAMc/Y -7mqWAtntA4z7dW3n6rhVFgUWmvTgXrGIwGSFXBVNiMe3uuB16a0FPZ3HiUjguyjI -A+Ewk2ReUsBZcCI1V4iK8ZUKg9e8MXMBNO3vRnHgawKoNXJrl5tm4MsceV/YGgRo -HkcC5p1g4jaXAd/ONZLfvmfHbXdZO4+d1pAVlLxCNBDBOfmxJz5+1op1xbKvltOi -3pvkmL594emBrbZv/NcO2uA0sA0ad+fjCJjvWPqchLc2r8LfrNL0EAZwcTUCAwEA -AaOB6DCB5TAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFCzVUEGXFYvwjzZhW0r7 -a9mZyTOSMB8GA1UdIwQYMBaAFEjmaPkr0rKV10fYIyAQTzOYkJ/UMA8GA1UdEwEB -/wQFMAMBAf8wOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5j -b20vY3Jscy9zZWN1cmVjYS5jcmwwRgYDVR0gBD8wPTA7BgRVHSAAMDMwMQYIKwYB -BQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwDQYJ -KoZIhvcNAQEFBQADgYEAr/MO1nKrx6mXyiprhDneeanwgeUIZ6vXLyACAXEMBCLJ -HoiVA8lJOq9nCEmw1Qj1ID2AkaDFh6P7yaMXkfmoL67pD9+Wcg91F4BdeAFNnx9t -e9j1QjgjGpmT9IO+OzV05zcTNXqstLaQgmwnpODsnjW9v+UpoUefWzL86Zl9Kzk= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert1[] = { - 0x30, 0x82, 0x03, 0x8b, 0x30, 0x82, 0x02, 0xf4, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x03, 0x0d, 0x6e, 0x62, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4e, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, - 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x07, 0x45, - 0x71, 0x75, 0x69, 0x66, 0x61, 0x78, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, - 0x55, 0x04, 0x0b, 0x13, 0x24, 0x45, 0x71, 0x75, 0x69, 0x66, 0x61, 0x78, - 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, - 0x31, 0x32, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, - 0x31, 0x38, 0x30, 0x38, 0x32, 0x31, 0x31, 0x36, 0x31, 0x35, 0x30, 0x30, - 0x5a, 0x30, 0x58, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, - 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x13, 0x28, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, - 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 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, 0xbe, 0xb8, 0x15, 0x7b, 0xff, 0xd4, 0x7c, 0x7d, - 0x67, 0xad, 0x83, 0x64, 0x7b, 0xc8, 0x42, 0x53, 0x2d, 0xdf, 0xf6, 0x84, - 0x08, 0x20, 0x61, 0xd6, 0x01, 0x59, 0x6a, 0x9c, 0x44, 0x11, 0xaf, 0xef, - 0x76, 0xfd, 0x95, 0x7e, 0xce, 0x61, 0x30, 0xbb, 0x7a, 0x83, 0x5f, 0x02, - 0xbd, 0x01, 0x66, 0xca, 0xee, 0x15, 0x8d, 0x6f, 0xa1, 0x30, 0x9c, 0xbd, - 0xa1, 0x85, 0x9e, 0x94, 0x3a, 0xf3, 0x56, 0x88, 0x00, 0x31, 0xcf, 0xd8, - 0xee, 0x6a, 0x96, 0x02, 0xd9, 0xed, 0x03, 0x8c, 0xfb, 0x75, 0x6d, 0xe7, - 0xea, 0xb8, 0x55, 0x16, 0x05, 0x16, 0x9a, 0xf4, 0xe0, 0x5e, 0xb1, 0x88, - 0xc0, 0x64, 0x85, 0x5c, 0x15, 0x4d, 0x88, 0xc7, 0xb7, 0xba, 0xe0, 0x75, - 0xe9, 0xad, 0x05, 0x3d, 0x9d, 0xc7, 0x89, 0x48, 0xe0, 0xbb, 0x28, 0xc8, - 0x03, 0xe1, 0x30, 0x93, 0x64, 0x5e, 0x52, 0xc0, 0x59, 0x70, 0x22, 0x35, - 0x57, 0x88, 0x8a, 0xf1, 0x95, 0x0a, 0x83, 0xd7, 0xbc, 0x31, 0x73, 0x01, - 0x34, 0xed, 0xef, 0x46, 0x71, 0xe0, 0x6b, 0x02, 0xa8, 0x35, 0x72, 0x6b, - 0x97, 0x9b, 0x66, 0xe0, 0xcb, 0x1c, 0x79, 0x5f, 0xd8, 0x1a, 0x04, 0x68, - 0x1e, 0x47, 0x02, 0xe6, 0x9d, 0x60, 0xe2, 0x36, 0x97, 0x01, 0xdf, 0xce, - 0x35, 0x92, 0xdf, 0xbe, 0x67, 0xc7, 0x6d, 0x77, 0x59, 0x3b, 0x8f, 0x9d, - 0xd6, 0x90, 0x15, 0x94, 0xbc, 0x42, 0x34, 0x10, 0xc1, 0x39, 0xf9, 0xb1, - 0x27, 0x3e, 0x7e, 0xd6, 0x8a, 0x75, 0xc5, 0xb2, 0xaf, 0x96, 0xd3, 0xa2, - 0xde, 0x9b, 0xe4, 0x98, 0xbe, 0x7d, 0xe1, 0xe9, 0x81, 0xad, 0xb6, 0x6f, - 0xfc, 0xd7, 0x0e, 0xda, 0xe0, 0x34, 0xb0, 0x0d, 0x1a, 0x77, 0xe7, 0xe3, - 0x08, 0x98, 0xef, 0x58, 0xfa, 0x9c, 0x84, 0xb7, 0x36, 0xaf, 0xc2, 0xdf, - 0xac, 0xd2, 0xf4, 0x10, 0x06, 0x70, 0x71, 0x35, 0x02, 0x03, 0x01, 0x00, - 0x01, 0xa3, 0x81, 0xe8, 0x30, 0x81, 0xe5, 0x30, 0x0e, 0x06, 0x03, 0x55, - 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, - 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2c, 0xd5, - 0x50, 0x41, 0x97, 0x15, 0x8b, 0xf0, 0x8f, 0x36, 0x61, 0x5b, 0x4a, 0xfb, - 0x6b, 0xd9, 0x99, 0xc9, 0x33, 0x92, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, - 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x48, 0xe6, 0x68, 0xf9, 0x2b, - 0xd2, 0xb2, 0x95, 0xd7, 0x47, 0xd8, 0x23, 0x20, 0x10, 0x4f, 0x33, 0x98, - 0x90, 0x9f, 0xd4, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, - 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x3a, 0x06, 0x03, - 0x55, 0x1d, 0x1f, 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, 0xa0, 0x2d, 0xa0, - 0x2b, 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, - 0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x73, 0x65, 0x63, 0x75, - 0x72, 0x65, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x46, 0x06, 0x03, - 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30, 0x3b, 0x06, 0x04, 0x55, - 0x1d, 0x20, 0x00, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, - 0x81, 0x81, 0x00, 0xaf, 0xf3, 0x0e, 0xd6, 0x72, 0xab, 0xc7, 0xa9, 0x97, - 0xca, 0x2a, 0x6b, 0x84, 0x39, 0xde, 0x79, 0xa9, 0xf0, 0x81, 0xe5, 0x08, - 0x67, 0xab, 0xd7, 0x2f, 0x20, 0x02, 0x01, 0x71, 0x0c, 0x04, 0x22, 0xc9, - 0x1e, 0x88, 0x95, 0x03, 0xc9, 0x49, 0x3a, 0xaf, 0x67, 0x08, 0x49, 0xb0, - 0xd5, 0x08, 0xf5, 0x20, 0x3d, 0x80, 0x91, 0xa0, 0xc5, 0x87, 0xa3, 0xfb, - 0xc9, 0xa3, 0x17, 0x91, 0xf9, 0xa8, 0x2f, 0xae, 0xe9, 0x0f, 0xdf, 0x96, - 0x72, 0x0f, 0x75, 0x17, 0x80, 0x5d, 0x78, 0x01, 0x4d, 0x9f, 0x1f, 0x6d, - 0x7b, 0xd8, 0xf5, 0x42, 0x38, 0x23, 0x1a, 0x99, 0x93, 0xf4, 0x83, 0xbe, - 0x3b, 0x35, 0x74, 0xe7, 0x37, 0x13, 0x35, 0x7a, 0xac, 0xb4, 0xb6, 0x90, - 0x82, 0x6c, 0x27, 0xa4, 0xe0, 0xec, 0x9e, 0x35, 0xbd, 0xbf, 0xe5, 0x29, - 0xa1, 0x47, 0x9f, 0x5b, 0x32, 0xfc, 0xe9, 0x99, 0x7d, 0x2b, 0x39, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 145105 (0x236d1) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA - Validity - Not Before: Feb 19 22:45:05 2010 GMT - Not After : Feb 18 22:45:05 2020 GMT - Subject: C=US, O=GeoTrust, Inc., CN=RapidSSL CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:c7:71:f8:56:c7:1e:d9:cc:b5:ad:f6:b4:97:a3: - fb:a1:e6:0b:50:5f:50:aa:3a:da:0f:fc:3d:29:24: - 43:c6:10:29:c1:fc:55:40:72:ee:bd:ea:df:9f:b6: - 41:f4:48:4b:c8:6e:fe:4f:57:12:8b:5b:fa:92:dd: - 5e:e8:ad:f3:f0:1b:b1:7b:4d:fb:cf:fd:d1:e5:f8: - e3:dc:e7:f5:73:7f:df:01:49:cf:8c:56:c1:bd:37: - e3:5b:be:b5:4f:8b:8b:f0:da:4f:c7:e3:dd:55:47: - 69:df:f2:5b:7b:07:4f:3d:e5:ac:21:c1:c8:1d:7a: - e8:e7:f6:0f:a1:aa:f5:6f:de:a8:65:4f:10:89:9c: - 03:f3:89:7a:a5:5e:01:72:33:ed:a9:e9:5a:1e:79: - f3:87:c8:df:c8:c5:fc:37:c8:9a:9a:d7:b8:76:cc: - b0:3e:e7:fd:e6:54:ea:df:5f:52:41:78:59:57:ad: - f1:12:d6:7f:bc:d5:9f:70:d3:05:6c:fa:a3:7d:67: - 58:dd:26:62:1d:31:92:0c:79:79:1c:8e:cf:ca:7b: - c1:66:af:a8:74:48:fb:8e:82:c2:9e:2c:99:5c:7b: - 2d:5d:9b:bc:5b:57:9e:7c:3a:7a:13:ad:f2:a3:18: - 5b:2b:59:0f:cd:5c:3a:eb:68:33:c6:28:1d:82:d1: - 50:8b - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Subject Key Identifier: - 6B:69:3D:6A:18:42:4A:DD:8F:02:65:39:FD:35:24:86:78:91:16:30 - X509v3 Authority Key Identifier: - keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E - - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.geotrust.com/crls/gtglobal.crl - - Authority Information Access: - OCSP - URI:http://ocsp.geotrust.com - - Signature Algorithm: sha1WithRSAEncryption - ab:bc:bc:0a:5d:18:94:e3:c1:b1:c3:a8:4c:55:d6:be:b4:98: - f1:ee:3c:1c:cd:cf:f3:24:24:5c:96:03:27:58:fc:36:ae:a2: - 2f:8f:f1:fe:da:2b:02:c3:33:bd:c8:dd:48:22:2b:60:0f:a5: - 03:10:fd:77:f8:d0:ed:96:67:4f:fd:ea:47:20:70:54:dc:a9: - 0c:55:7e:e1:96:25:8a:d9:b5:da:57:4a:be:8d:8e:49:43:63: - a5:6c:4e:27:87:25:eb:5b:6d:fe:a2:7f:38:28:e0:36:ab:ad: - 39:a5:a5:62:c4:b7:5c:58:2c:aa:5d:01:60:a6:62:67:a3:c0: - c7:62:23:f4:e7:6c:46:ee:b5:d3:80:6a:22:13:d2:2d:3f:74: - 4f:ea:af:8c:5f:b4:38:9c:db:ae:ce:af:84:1e:a6:f6:34:51: - 59:79:d3:e3:75:dc:bc:d7:f3:73:df:92:ec:d2:20:59:6f:9c: - fb:95:f8:92:76:18:0a:7c:0f:2c:a6:ca:de:8a:62:7b:d8:f3: - ce:5f:68:bd:8f:3e:c1:74:bb:15:72:3a:16:83:a9:0b:e6:4d: - 99:9c:d8:57:ec:a8:01:51:c7:6f:57:34:5e:ab:4a:2c:42:f6: - 4f:1c:89:78:de:26:4e:f5:6f:93:4c:15:6b:27:56:4d:00:54: - 6c:7a:b7:b7 ------BEGIN CERTIFICATE----- -MIID1TCCAr2gAwIBAgIDAjbRMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT -MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i -YWwgQ0EwHhcNMTAwMjE5MjI0NTA1WhcNMjAwMjE4MjI0NTA1WjA8MQswCQYDVQQG -EwJVUzEXMBUGA1UEChMOR2VvVHJ1c3QsIEluYy4xFDASBgNVBAMTC1JhcGlkU1NM -IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx3H4Vsce2cy1rfa0 -l6P7oeYLUF9QqjraD/w9KSRDxhApwfxVQHLuverfn7ZB9EhLyG7+T1cSi1v6kt1e -6K3z8Buxe037z/3R5fjj3Of1c3/fAUnPjFbBvTfjW761T4uL8NpPx+PdVUdp3/Jb -ewdPPeWsIcHIHXro5/YPoar1b96oZU8QiZwD84l6pV4BcjPtqelaHnnzh8jfyMX8 -N8iamte4dsywPuf95lTq319SQXhZV63xEtZ/vNWfcNMFbPqjfWdY3SZiHTGSDHl5 -HI7PynvBZq+odEj7joLCniyZXHstXZu8W1eefDp6E63yoxhbK1kPzVw662gzxigd -gtFQiwIDAQABo4HZMIHWMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUa2k9ahhC -St2PAmU5/TUkhniRFjAwHwYDVR0jBBgwFoAUwHqYaI2J+6sFZAwRfap9ZbjKzE4w -EgYDVR0TAQH/BAgwBgEB/wIBADA6BgNVHR8EMzAxMC+gLaArhilodHRwOi8vY3Js -Lmdlb3RydXN0LmNvbS9jcmxzL2d0Z2xvYmFsLmNybDA0BggrBgEFBQcBAQQoMCYw -JAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmdlb3RydXN0LmNvbTANBgkqhkiG9w0B -AQUFAAOCAQEAq7y8Cl0YlOPBscOoTFXWvrSY8e48HM3P8yQkXJYDJ1j8Nq6iL4/x -/torAsMzvcjdSCIrYA+lAxD9d/jQ7ZZnT/3qRyBwVNypDFV+4ZYlitm12ldKvo2O -SUNjpWxOJ4cl61tt/qJ/OCjgNqutOaWlYsS3XFgsql0BYKZiZ6PAx2Ij9OdsRu61 -04BqIhPSLT90T+qvjF+0OJzbrs6vhB6m9jRRWXnT43XcvNfzc9+S7NIgWW+c+5X4 -knYYCnwPLKbK3opie9jzzl9ovY8+wXS7FXI6FoOpC+ZNmZzYV+yoAVHHb1c0XqtK -LEL2TxyJeN4mTvVvk0wVaydWTQBUbHq3tw== ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert2[] = { - 0x30, 0x82, 0x03, 0xd5, 0x30, 0x82, 0x02, 0xbd, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x03, 0x02, 0x36, 0xd1, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x42, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, - 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, - 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, - 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, - 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, - 0x32, 0x31, 0x39, 0x32, 0x32, 0x34, 0x35, 0x30, 0x35, 0x5a, 0x17, 0x0d, - 0x32, 0x30, 0x30, 0x32, 0x31, 0x38, 0x32, 0x32, 0x34, 0x35, 0x30, 0x35, - 0x5a, 0x30, 0x3c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x0e, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x2c, - 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x0b, 0x52, 0x61, 0x70, 0x69, 0x64, 0x53, 0x53, 0x4c, - 0x20, 0x43, 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, - 0xc7, 0x71, 0xf8, 0x56, 0xc7, 0x1e, 0xd9, 0xcc, 0xb5, 0xad, 0xf6, 0xb4, - 0x97, 0xa3, 0xfb, 0xa1, 0xe6, 0x0b, 0x50, 0x5f, 0x50, 0xaa, 0x3a, 0xda, - 0x0f, 0xfc, 0x3d, 0x29, 0x24, 0x43, 0xc6, 0x10, 0x29, 0xc1, 0xfc, 0x55, - 0x40, 0x72, 0xee, 0xbd, 0xea, 0xdf, 0x9f, 0xb6, 0x41, 0xf4, 0x48, 0x4b, - 0xc8, 0x6e, 0xfe, 0x4f, 0x57, 0x12, 0x8b, 0x5b, 0xfa, 0x92, 0xdd, 0x5e, - 0xe8, 0xad, 0xf3, 0xf0, 0x1b, 0xb1, 0x7b, 0x4d, 0xfb, 0xcf, 0xfd, 0xd1, - 0xe5, 0xf8, 0xe3, 0xdc, 0xe7, 0xf5, 0x73, 0x7f, 0xdf, 0x01, 0x49, 0xcf, - 0x8c, 0x56, 0xc1, 0xbd, 0x37, 0xe3, 0x5b, 0xbe, 0xb5, 0x4f, 0x8b, 0x8b, - 0xf0, 0xda, 0x4f, 0xc7, 0xe3, 0xdd, 0x55, 0x47, 0x69, 0xdf, 0xf2, 0x5b, - 0x7b, 0x07, 0x4f, 0x3d, 0xe5, 0xac, 0x21, 0xc1, 0xc8, 0x1d, 0x7a, 0xe8, - 0xe7, 0xf6, 0x0f, 0xa1, 0xaa, 0xf5, 0x6f, 0xde, 0xa8, 0x65, 0x4f, 0x10, - 0x89, 0x9c, 0x03, 0xf3, 0x89, 0x7a, 0xa5, 0x5e, 0x01, 0x72, 0x33, 0xed, - 0xa9, 0xe9, 0x5a, 0x1e, 0x79, 0xf3, 0x87, 0xc8, 0xdf, 0xc8, 0xc5, 0xfc, - 0x37, 0xc8, 0x9a, 0x9a, 0xd7, 0xb8, 0x76, 0xcc, 0xb0, 0x3e, 0xe7, 0xfd, - 0xe6, 0x54, 0xea, 0xdf, 0x5f, 0x52, 0x41, 0x78, 0x59, 0x57, 0xad, 0xf1, - 0x12, 0xd6, 0x7f, 0xbc, 0xd5, 0x9f, 0x70, 0xd3, 0x05, 0x6c, 0xfa, 0xa3, - 0x7d, 0x67, 0x58, 0xdd, 0x26, 0x62, 0x1d, 0x31, 0x92, 0x0c, 0x79, 0x79, - 0x1c, 0x8e, 0xcf, 0xca, 0x7b, 0xc1, 0x66, 0xaf, 0xa8, 0x74, 0x48, 0xfb, - 0x8e, 0x82, 0xc2, 0x9e, 0x2c, 0x99, 0x5c, 0x7b, 0x2d, 0x5d, 0x9b, 0xbc, - 0x5b, 0x57, 0x9e, 0x7c, 0x3a, 0x7a, 0x13, 0xad, 0xf2, 0xa3, 0x18, 0x5b, - 0x2b, 0x59, 0x0f, 0xcd, 0x5c, 0x3a, 0xeb, 0x68, 0x33, 0xc6, 0x28, 0x1d, - 0x82, 0xd1, 0x50, 0x8b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xd9, - 0x30, 0x81, 0xd6, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, - 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, - 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x6b, 0x69, 0x3d, 0x6a, 0x18, 0x42, - 0x4a, 0xdd, 0x8f, 0x02, 0x65, 0x39, 0xfd, 0x35, 0x24, 0x86, 0x78, 0x91, - 0x16, 0x30, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, - 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, - 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, - 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, - 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x3a, 0x06, 0x03, 0x55, - 0x1d, 0x1f, 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, 0xa0, 0x2d, 0xa0, 0x2b, - 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, - 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, - 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x34, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, - 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, - 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, - 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, - 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xab, 0xbc, 0xbc, - 0x0a, 0x5d, 0x18, 0x94, 0xe3, 0xc1, 0xb1, 0xc3, 0xa8, 0x4c, 0x55, 0xd6, - 0xbe, 0xb4, 0x98, 0xf1, 0xee, 0x3c, 0x1c, 0xcd, 0xcf, 0xf3, 0x24, 0x24, - 0x5c, 0x96, 0x03, 0x27, 0x58, 0xfc, 0x36, 0xae, 0xa2, 0x2f, 0x8f, 0xf1, - 0xfe, 0xda, 0x2b, 0x02, 0xc3, 0x33, 0xbd, 0xc8, 0xdd, 0x48, 0x22, 0x2b, - 0x60, 0x0f, 0xa5, 0x03, 0x10, 0xfd, 0x77, 0xf8, 0xd0, 0xed, 0x96, 0x67, - 0x4f, 0xfd, 0xea, 0x47, 0x20, 0x70, 0x54, 0xdc, 0xa9, 0x0c, 0x55, 0x7e, - 0xe1, 0x96, 0x25, 0x8a, 0xd9, 0xb5, 0xda, 0x57, 0x4a, 0xbe, 0x8d, 0x8e, - 0x49, 0x43, 0x63, 0xa5, 0x6c, 0x4e, 0x27, 0x87, 0x25, 0xeb, 0x5b, 0x6d, - 0xfe, 0xa2, 0x7f, 0x38, 0x28, 0xe0, 0x36, 0xab, 0xad, 0x39, 0xa5, 0xa5, - 0x62, 0xc4, 0xb7, 0x5c, 0x58, 0x2c, 0xaa, 0x5d, 0x01, 0x60, 0xa6, 0x62, - 0x67, 0xa3, 0xc0, 0xc7, 0x62, 0x23, 0xf4, 0xe7, 0x6c, 0x46, 0xee, 0xb5, - 0xd3, 0x80, 0x6a, 0x22, 0x13, 0xd2, 0x2d, 0x3f, 0x74, 0x4f, 0xea, 0xaf, - 0x8c, 0x5f, 0xb4, 0x38, 0x9c, 0xdb, 0xae, 0xce, 0xaf, 0x84, 0x1e, 0xa6, - 0xf6, 0x34, 0x51, 0x59, 0x79, 0xd3, 0xe3, 0x75, 0xdc, 0xbc, 0xd7, 0xf3, - 0x73, 0xdf, 0x92, 0xec, 0xd2, 0x20, 0x59, 0x6f, 0x9c, 0xfb, 0x95, 0xf8, - 0x92, 0x76, 0x18, 0x0a, 0x7c, 0x0f, 0x2c, 0xa6, 0xca, 0xde, 0x8a, 0x62, - 0x7b, 0xd8, 0xf3, 0xce, 0x5f, 0x68, 0xbd, 0x8f, 0x3e, 0xc1, 0x74, 0xbb, - 0x15, 0x72, 0x3a, 0x16, 0x83, 0xa9, 0x0b, 0xe6, 0x4d, 0x99, 0x9c, 0xd8, - 0x57, 0xec, 0xa8, 0x01, 0x51, 0xc7, 0x6f, 0x57, 0x34, 0x5e, 0xab, 0x4a, - 0x2c, 0x42, 0xf6, 0x4f, 0x1c, 0x89, 0x78, 0xde, 0x26, 0x4e, 0xf5, 0x6f, - 0x93, 0x4c, 0x15, 0x6b, 0x27, 0x56, 0x4d, 0x00, 0x54, 0x6c, 0x7a, 0xb7, - 0xb7, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 145104 (0x236d0) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA - Validity - Not Before: Feb 19 22:39:26 2010 GMT - Not After : Feb 18 22:39:26 2020 GMT - Subject: C=US, O=GeoTrust, Inc., CN=GeoTrust SSL CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:90:b3:80:c1:e4:e5:46:ad:70:60:3d:ba:e5:14: - dd:9e:8a:5e:8b:75:5a:e6:ca:6d:41:a5:23:e8:39: - 85:26:7a:a7:55:77:9a:48:a1:92:7e:3a:1e:1a:f1: - 27:ab:a3:4c:39:cc:cb:3d:47:af:81:ae:16:6a:5c: - 37:ef:45:41:fd:fb:9a:97:3c:a0:43:9d:c6:df:17: - 21:d1:8a:a2:56:c2:03:49:84:12:81:3e:c9:0a:54: - 60:66:b9:8c:54:e4:f9:e6:f9:94:f1:e0:5f:75:11: - f2:29:b9:e4:86:a2:b1:89:ad:a6:1e:83:29:63:b2: - f0:54:1c:85:0b:7a:e7:e1:2e:0d:af:a4:bd:cd:e7: - b1:5a:d7:8c:05:5a:0e:4b:73:28:8b:75:5d:34:d8: - 77:0b:e1:74:62:e2:71:30:62:d8:bc:8a:05:e5:31: - 63:4a:54:89:6a:33:78:a7:4e:55:24:1d:97:ef:1a: - e4:12:c6:0f:30:18:b4:34:4d:e1:d8:23:3b:21:5b: - 2d:30:19:25:0e:74:f7:a4:21:4b:a0:a4:20:c9:6c: - cd:98:56:c0:f2:a8:5f:3e:26:75:a0:0d:f8:36:88: - 8a:2c:5a:7d:67:30:a9:0f:d1:99:70:2e:78:e1:51: - 26:af:55:7a:24:be:8c:39:0d:77:9d:de:02:c3:0c: - bd:1f - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Subject Key Identifier: - 42:79:54:1B:61:CD:55:2B:3E:63:D5:3C:48:57:F5:9F:FB:45:CE:4A - X509v3 Authority Key Identifier: - keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E - - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.geotrust.com/crls/gtglobal.crl - - Authority Information Access: - OCSP - URI:http://ocsp.geotrust.com - - Signature Algorithm: sha1WithRSAEncryption - d4:ef:53:84:e8:1a:bd:a1:8b:04:c0:a9:f5:5f:a1:10:78:45: - 5d:b2:57:6a:4e:24:cb:65:4e:31:97:91:9a:d4:24:f8:e2:27: - 66:70:31:9c:c1:62:54:06:e7:97:1d:3a:9a:c0:a4:29:48:0a: - af:24:c7:a8:c4:9a:54:c1:7c:4c:78:4c:2b:68:2c:5d:17:a6: - 54:78:4c:46:e2:80:c3:1f:38:71:12:d2:d7:53:e3:54:85:50: - b8:02:cb:ee:63:3a:f8:56:89:4d:55:bb:2e:c0:c8:18:77:86: - 31:0b:0b:70:f0:7e:35:83:a4:2a:13:64:56:67:34:5d:16:5f: - 73:ac:7b:06:24:da:4f:50:6d:2a:ab:d0:4d:53:41:c2:8e:bb: - 71:03:49:29:86:18:cf:21:42:4c:74:62:51:15:c5:6f:a8:ef: - c4:27:e5:1b:33:dd:5a:88:d7:7f:12:d1:a7:61:25:1f:d5:e0: - dc:1d:cf:1a:10:d8:a0:cb:5f:8c:fa:0c:e5:bf:71:ff:e5:5d: - 44:1d:a6:3e:87:47:fa:1a:4e:83:83:12:3f:88:66:95:98:79: - 9a:85:eb:02:47:cd:25:e3:f2:06:04:4e:99:ca:5c:a0:6e:7a: - bb:dd:a3:90:1a:45:33:ef:bf:3e:d2:04:c4:b6:e0:2a:85:65: - 41:3e:10:d4 ------BEGIN CERTIFICATE----- -MIID2TCCAsGgAwIBAgIDAjbQMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT -MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i -YWwgQ0EwHhcNMTAwMjE5MjIzOTI2WhcNMjAwMjE4MjIzOTI2WjBAMQswCQYDVQQG -EwJVUzEXMBUGA1UEChMOR2VvVHJ1c3QsIEluYy4xGDAWBgNVBAMTD0dlb1RydXN0 -IFNTTCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJCzgMHk5Uat -cGA9uuUU3Z6KXot1WubKbUGlI+g5hSZ6p1V3mkihkn46HhrxJ6ujTDnMyz1Hr4Gu -FmpcN+9FQf37mpc8oEOdxt8XIdGKolbCA0mEEoE+yQpUYGa5jFTk+eb5lPHgX3UR -8im55IaisYmtph6DKWOy8FQchQt65+EuDa+kvc3nsVrXjAVaDktzKIt1XTTYdwvh -dGLicTBi2LyKBeUxY0pUiWozeKdOVSQdl+8a5BLGDzAYtDRN4dgjOyFbLTAZJQ50 -96QhS6CkIMlszZhWwPKoXz4mdaAN+DaIiixafWcwqQ/RmXAueOFRJq9VeiS+jDkN -d53eAsMMvR8CAwEAAaOB2TCB1jAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFEJ5 -VBthzVUrPmPVPEhX9Z/7Rc5KMB8GA1UdIwQYMBaAFMB6mGiNifurBWQMEX2qfWW4 -ysxOMBIGA1UdEwEB/wQIMAYBAf8CAQAwOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDov -L2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwNAYIKwYBBQUHAQEE -KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5nZW90cnVzdC5jb20wDQYJKoZI -hvcNAQEFBQADggEBANTvU4ToGr2hiwTAqfVfoRB4RV2yV2pOJMtlTjGXkZrUJPji -J2ZwMZzBYlQG55cdOprApClICq8kx6jEmlTBfEx4TCtoLF0XplR4TEbigMMfOHES -0tdT41SFULgCy+5jOvhWiU1Vuy7AyBh3hjELC3DwfjWDpCoTZFZnNF0WX3OsewYk -2k9QbSqr0E1TQcKOu3EDSSmGGM8hQkx0YlEVxW+o78Qn5Rsz3VqI138S0adhJR/V -4NwdzxoQ2KDLX4z6DOW/cf/lXUQdpj6HR/oaToODEj+IZpWYeZqF6wJHzSXj8gYE -TpnKXKBuervdo5AaRTPvvz7SBMS24CqFZUE+ENQ= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert3[] = { - 0x30, 0x82, 0x03, 0xd9, 0x30, 0x82, 0x02, 0xc1, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x03, 0x02, 0x36, 0xd0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x42, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, - 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, - 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, - 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, - 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, - 0x32, 0x31, 0x39, 0x32, 0x32, 0x33, 0x39, 0x32, 0x36, 0x5a, 0x17, 0x0d, - 0x32, 0x30, 0x30, 0x32, 0x31, 0x38, 0x32, 0x32, 0x33, 0x39, 0x32, 0x36, - 0x5a, 0x30, 0x40, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x0e, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x2c, - 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x0f, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, - 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 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, 0x90, 0xb3, 0x80, 0xc1, 0xe4, 0xe5, 0x46, 0xad, - 0x70, 0x60, 0x3d, 0xba, 0xe5, 0x14, 0xdd, 0x9e, 0x8a, 0x5e, 0x8b, 0x75, - 0x5a, 0xe6, 0xca, 0x6d, 0x41, 0xa5, 0x23, 0xe8, 0x39, 0x85, 0x26, 0x7a, - 0xa7, 0x55, 0x77, 0x9a, 0x48, 0xa1, 0x92, 0x7e, 0x3a, 0x1e, 0x1a, 0xf1, - 0x27, 0xab, 0xa3, 0x4c, 0x39, 0xcc, 0xcb, 0x3d, 0x47, 0xaf, 0x81, 0xae, - 0x16, 0x6a, 0x5c, 0x37, 0xef, 0x45, 0x41, 0xfd, 0xfb, 0x9a, 0x97, 0x3c, - 0xa0, 0x43, 0x9d, 0xc6, 0xdf, 0x17, 0x21, 0xd1, 0x8a, 0xa2, 0x56, 0xc2, - 0x03, 0x49, 0x84, 0x12, 0x81, 0x3e, 0xc9, 0x0a, 0x54, 0x60, 0x66, 0xb9, - 0x8c, 0x54, 0xe4, 0xf9, 0xe6, 0xf9, 0x94, 0xf1, 0xe0, 0x5f, 0x75, 0x11, - 0xf2, 0x29, 0xb9, 0xe4, 0x86, 0xa2, 0xb1, 0x89, 0xad, 0xa6, 0x1e, 0x83, - 0x29, 0x63, 0xb2, 0xf0, 0x54, 0x1c, 0x85, 0x0b, 0x7a, 0xe7, 0xe1, 0x2e, - 0x0d, 0xaf, 0xa4, 0xbd, 0xcd, 0xe7, 0xb1, 0x5a, 0xd7, 0x8c, 0x05, 0x5a, - 0x0e, 0x4b, 0x73, 0x28, 0x8b, 0x75, 0x5d, 0x34, 0xd8, 0x77, 0x0b, 0xe1, - 0x74, 0x62, 0xe2, 0x71, 0x30, 0x62, 0xd8, 0xbc, 0x8a, 0x05, 0xe5, 0x31, - 0x63, 0x4a, 0x54, 0x89, 0x6a, 0x33, 0x78, 0xa7, 0x4e, 0x55, 0x24, 0x1d, - 0x97, 0xef, 0x1a, 0xe4, 0x12, 0xc6, 0x0f, 0x30, 0x18, 0xb4, 0x34, 0x4d, - 0xe1, 0xd8, 0x23, 0x3b, 0x21, 0x5b, 0x2d, 0x30, 0x19, 0x25, 0x0e, 0x74, - 0xf7, 0xa4, 0x21, 0x4b, 0xa0, 0xa4, 0x20, 0xc9, 0x6c, 0xcd, 0x98, 0x56, - 0xc0, 0xf2, 0xa8, 0x5f, 0x3e, 0x26, 0x75, 0xa0, 0x0d, 0xf8, 0x36, 0x88, - 0x8a, 0x2c, 0x5a, 0x7d, 0x67, 0x30, 0xa9, 0x0f, 0xd1, 0x99, 0x70, 0x2e, - 0x78, 0xe1, 0x51, 0x26, 0xaf, 0x55, 0x7a, 0x24, 0xbe, 0x8c, 0x39, 0x0d, - 0x77, 0x9d, 0xde, 0x02, 0xc3, 0x0c, 0xbd, 0x1f, 0x02, 0x03, 0x01, 0x00, - 0x01, 0xa3, 0x81, 0xd9, 0x30, 0x81, 0xd6, 0x30, 0x0e, 0x06, 0x03, 0x55, - 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, - 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x42, 0x79, - 0x54, 0x1b, 0x61, 0xcd, 0x55, 0x2b, 0x3e, 0x63, 0xd5, 0x3c, 0x48, 0x57, - 0xf5, 0x9f, 0xfb, 0x45, 0xce, 0x4a, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, - 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, - 0x89, 0xfb, 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, - 0xca, 0xcc, 0x4e, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, - 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, - 0x3a, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, - 0xa0, 0x2d, 0xa0, 0x2b, 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x67, - 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72, 0x6c, 0x30, - 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, - 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, - 0x00, 0xd4, 0xef, 0x53, 0x84, 0xe8, 0x1a, 0xbd, 0xa1, 0x8b, 0x04, 0xc0, - 0xa9, 0xf5, 0x5f, 0xa1, 0x10, 0x78, 0x45, 0x5d, 0xb2, 0x57, 0x6a, 0x4e, - 0x24, 0xcb, 0x65, 0x4e, 0x31, 0x97, 0x91, 0x9a, 0xd4, 0x24, 0xf8, 0xe2, - 0x27, 0x66, 0x70, 0x31, 0x9c, 0xc1, 0x62, 0x54, 0x06, 0xe7, 0x97, 0x1d, - 0x3a, 0x9a, 0xc0, 0xa4, 0x29, 0x48, 0x0a, 0xaf, 0x24, 0xc7, 0xa8, 0xc4, - 0x9a, 0x54, 0xc1, 0x7c, 0x4c, 0x78, 0x4c, 0x2b, 0x68, 0x2c, 0x5d, 0x17, - 0xa6, 0x54, 0x78, 0x4c, 0x46, 0xe2, 0x80, 0xc3, 0x1f, 0x38, 0x71, 0x12, - 0xd2, 0xd7, 0x53, 0xe3, 0x54, 0x85, 0x50, 0xb8, 0x02, 0xcb, 0xee, 0x63, - 0x3a, 0xf8, 0x56, 0x89, 0x4d, 0x55, 0xbb, 0x2e, 0xc0, 0xc8, 0x18, 0x77, - 0x86, 0x31, 0x0b, 0x0b, 0x70, 0xf0, 0x7e, 0x35, 0x83, 0xa4, 0x2a, 0x13, - 0x64, 0x56, 0x67, 0x34, 0x5d, 0x16, 0x5f, 0x73, 0xac, 0x7b, 0x06, 0x24, - 0xda, 0x4f, 0x50, 0x6d, 0x2a, 0xab, 0xd0, 0x4d, 0x53, 0x41, 0xc2, 0x8e, - 0xbb, 0x71, 0x03, 0x49, 0x29, 0x86, 0x18, 0xcf, 0x21, 0x42, 0x4c, 0x74, - 0x62, 0x51, 0x15, 0xc5, 0x6f, 0xa8, 0xef, 0xc4, 0x27, 0xe5, 0x1b, 0x33, - 0xdd, 0x5a, 0x88, 0xd7, 0x7f, 0x12, 0xd1, 0xa7, 0x61, 0x25, 0x1f, 0xd5, - 0xe0, 0xdc, 0x1d, 0xcf, 0x1a, 0x10, 0xd8, 0xa0, 0xcb, 0x5f, 0x8c, 0xfa, - 0x0c, 0xe5, 0xbf, 0x71, 0xff, 0xe5, 0x5d, 0x44, 0x1d, 0xa6, 0x3e, 0x87, - 0x47, 0xfa, 0x1a, 0x4e, 0x83, 0x83, 0x12, 0x3f, 0x88, 0x66, 0x95, 0x98, - 0x79, 0x9a, 0x85, 0xeb, 0x02, 0x47, 0xcd, 0x25, 0xe3, 0xf2, 0x06, 0x04, - 0x4e, 0x99, 0xca, 0x5c, 0xa0, 0x6e, 0x7a, 0xbb, 0xdd, 0xa3, 0x90, 0x1a, - 0x45, 0x33, 0xef, 0xbf, 0x3e, 0xd2, 0x04, 0xc4, 0xb6, 0xe0, 0x2a, 0x85, - 0x65, 0x41, 0x3e, 0x10, 0xd4, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 146038 (0x23a76) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA - Validity - Not Before: Apr 5 15:15:55 2013 GMT - Not After : Dec 31 23:59:59 2016 GMT - Subject: C=US, O=Google Inc, CN=Google Internet Authority G2 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:9c:2a:04:77:5c:d8:50:91:3a:06:a3:82:e0:d8: - 50:48:bc:89:3f:f1:19:70:1a:88:46:7e:e0:8f:c5: - f1:89:ce:21:ee:5a:fe:61:0d:b7:32:44:89:a0:74: - 0b:53:4f:55:a4:ce:82:62:95:ee:eb:59:5f:c6:e1: - 05:80:12:c4:5e:94:3f:bc:5b:48:38:f4:53:f7:24: - e6:fb:91:e9:15:c4:cf:f4:53:0d:f4:4a:fc:9f:54: - de:7d:be:a0:6b:6f:87:c0:d0:50:1f:28:30:03:40: - da:08:73:51:6c:7f:ff:3a:3c:a7:37:06:8e:bd:4b: - 11:04:eb:7d:24:de:e6:f9:fc:31:71:fb:94:d5:60: - f3:2e:4a:af:42:d2:cb:ea:c4:6a:1a:b2:cc:53:dd: - 15:4b:8b:1f:c8:19:61:1f:cd:9d:a8:3e:63:2b:84: - 35:69:65:84:c8:19:c5:46:22:f8:53:95:be:e3:80: - 4a:10:c6:2a:ec:ba:97:20:11:c7:39:99:10:04:a0: - f0:61:7a:95:25:8c:4e:52:75:e2:b6:ed:08:ca:14: - fc:ce:22:6a:b3:4e:cf:46:03:97:97:03:7e:c0:b1: - de:7b:af:45:33:cf:ba:3e:71:b7:de:f4:25:25:c2: - 0d:35:89:9d:9d:fb:0e:11:79:89:1e:37:c5:af:8e: - 72:69 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Authority Key Identifier: - keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E - - X509v3 Subject Key Identifier: - 4A:DD:06:16:1B:BC:F6:68:B5:76:F5:81:B6:BB:62:1A:BA:5A:81:2F - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 CRL Distribution Points: - - Full Name: - URI:http://g.symcb.com/crls/gtglobal.crl - - Authority Information Access: - OCSP - URI:http://g.symcd.com - - X509v3 Certificate Policies: - Policy: 1.3.6.1.4.1.11129.2.5.1 - - Signature Algorithm: sha1WithRSAEncryption - 27:8c:cf:e9:c7:3b:be:c0:6f:e8:96:84:fb:9c:5c:5d:90:e4: - 77:db:8b:32:60:9b:65:d8:85:26:b5:ba:9f:1e:de:64:4e:1f: - c6:c8:20:5b:09:9f:ab:a9:e0:09:34:45:a2:65:25:37:3d:7f: - 5a:6f:20:cc:f9:fa:f1:1d:8f:10:0c:02:3a:c4:c9:01:76:96: - be:9b:f9:15:d8:39:d1:c5:03:47:76:b8:8a:8c:31:d6:60:d5: - e4:8f:db:fa:3c:c6:d5:98:28:f8:1c:8f:17:91:34:cb:cb:52: - 7a:d1:fb:3a:20:e4:e1:86:b1:d8:18:0f:be:d6:87:64:8d:c5: - 0a:25:42:51:ef:b2:38:b8:e0:1d:d0:e1:fc:e6:f4:af:46:ba: - ef:c0:bf:c5:b4:05:f5:94:75:0c:fe:a2:be:02:ba:ea:86:5b: - f9:35:b3:66:f5:c5:8d:85:a1:1a:23:77:1a:19:17:54:13:60: - 9f:0b:e1:b4:9c:28:2a:f9:ae:02:34:6d:25:93:9c:82:a8:17: - 7b:f1:85:b0:d3:0f:58:e1:fb:b1:fe:9c:a1:a3:e8:fd:c9:3f: - f4:d7:71:dc:bd:8c:a4:19:e0:21:23:23:55:13:8f:a4:16:02: - 09:7e:b9:af:ee:db:53:64:bd:71:2f:b9:39:ce:30:b7:b4:bc: - 54:e0:47:07 ------BEGIN CERTIFICATE----- -MIID8DCCAtigAwIBAgIDAjp2MA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT -MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i -YWwgQ0EwHhcNMTMwNDA1MTUxNTU1WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG -EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy -bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP -VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv -h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE -ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ -EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC -DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7 -qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wEgYD -VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwNQYDVR0fBC4wLDAqoCig -JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMC4GCCsGAQUF -BwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDovL2cuc3ltY2QuY29tMBcGA1UdIAQQ -MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQUFAAOCAQEAJ4zP6cc7vsBv6JaE -+5xcXZDkd9uLMmCbZdiFJrW6nx7eZE4fxsggWwmfq6ngCTRFomUlNz1/Wm8gzPn6 -8R2PEAwCOsTJAXaWvpv5Fdg50cUDR3a4iowx1mDV5I/b+jzG1Zgo+ByPF5E0y8tS -etH7OiDk4Yax2BgPvtaHZI3FCiVCUe+yOLjgHdDh/Ob0r0a678C/xbQF9ZR1DP6i -vgK66oZb+TWzZvXFjYWhGiN3GhkXVBNgnwvhtJwoKvmuAjRtJZOcgqgXe/GFsNMP -WOH7sf6coaPo/ck/9Ndx3L2MpBngISMjVROPpBYCCX65r+7bU2S9cS+5Oc4wt7S8 -VOBHBw== ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert4[] = { - 0x30, 0x82, 0x03, 0xf0, 0x30, 0x82, 0x02, 0xd8, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x03, 0x02, 0x3a, 0x76, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x42, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, - 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, - 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, - 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, - 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, - 0x34, 0x30, 0x35, 0x31, 0x35, 0x31, 0x35, 0x35, 0x35, 0x5a, 0x17, 0x0d, - 0x31, 0x36, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, - 0x5a, 0x30, 0x49, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x0a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, - 0x63, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1c, - 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x65, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, - 0x79, 0x20, 0x47, 0x32, 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, 0x9c, 0x2a, 0x04, 0x77, 0x5c, 0xd8, 0x50, 0x91, 0x3a, 0x06, 0xa3, - 0x82, 0xe0, 0xd8, 0x50, 0x48, 0xbc, 0x89, 0x3f, 0xf1, 0x19, 0x70, 0x1a, - 0x88, 0x46, 0x7e, 0xe0, 0x8f, 0xc5, 0xf1, 0x89, 0xce, 0x21, 0xee, 0x5a, - 0xfe, 0x61, 0x0d, 0xb7, 0x32, 0x44, 0x89, 0xa0, 0x74, 0x0b, 0x53, 0x4f, - 0x55, 0xa4, 0xce, 0x82, 0x62, 0x95, 0xee, 0xeb, 0x59, 0x5f, 0xc6, 0xe1, - 0x05, 0x80, 0x12, 0xc4, 0x5e, 0x94, 0x3f, 0xbc, 0x5b, 0x48, 0x38, 0xf4, - 0x53, 0xf7, 0x24, 0xe6, 0xfb, 0x91, 0xe9, 0x15, 0xc4, 0xcf, 0xf4, 0x53, - 0x0d, 0xf4, 0x4a, 0xfc, 0x9f, 0x54, 0xde, 0x7d, 0xbe, 0xa0, 0x6b, 0x6f, - 0x87, 0xc0, 0xd0, 0x50, 0x1f, 0x28, 0x30, 0x03, 0x40, 0xda, 0x08, 0x73, - 0x51, 0x6c, 0x7f, 0xff, 0x3a, 0x3c, 0xa7, 0x37, 0x06, 0x8e, 0xbd, 0x4b, - 0x11, 0x04, 0xeb, 0x7d, 0x24, 0xde, 0xe6, 0xf9, 0xfc, 0x31, 0x71, 0xfb, - 0x94, 0xd5, 0x60, 0xf3, 0x2e, 0x4a, 0xaf, 0x42, 0xd2, 0xcb, 0xea, 0xc4, - 0x6a, 0x1a, 0xb2, 0xcc, 0x53, 0xdd, 0x15, 0x4b, 0x8b, 0x1f, 0xc8, 0x19, - 0x61, 0x1f, 0xcd, 0x9d, 0xa8, 0x3e, 0x63, 0x2b, 0x84, 0x35, 0x69, 0x65, - 0x84, 0xc8, 0x19, 0xc5, 0x46, 0x22, 0xf8, 0x53, 0x95, 0xbe, 0xe3, 0x80, - 0x4a, 0x10, 0xc6, 0x2a, 0xec, 0xba, 0x97, 0x20, 0x11, 0xc7, 0x39, 0x99, - 0x10, 0x04, 0xa0, 0xf0, 0x61, 0x7a, 0x95, 0x25, 0x8c, 0x4e, 0x52, 0x75, - 0xe2, 0xb6, 0xed, 0x08, 0xca, 0x14, 0xfc, 0xce, 0x22, 0x6a, 0xb3, 0x4e, - 0xcf, 0x46, 0x03, 0x97, 0x97, 0x03, 0x7e, 0xc0, 0xb1, 0xde, 0x7b, 0xaf, - 0x45, 0x33, 0xcf, 0xba, 0x3e, 0x71, 0xb7, 0xde, 0xf4, 0x25, 0x25, 0xc2, - 0x0d, 0x35, 0x89, 0x9d, 0x9d, 0xfb, 0x0e, 0x11, 0x79, 0x89, 0x1e, 0x37, - 0xc5, 0xaf, 0x8e, 0x72, 0x69, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, - 0xe7, 0x30, 0x81, 0xe4, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, - 0x18, 0x30, 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, - 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, - 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, - 0x4a, 0xdd, 0x06, 0x16, 0x1b, 0xbc, 0xf6, 0x68, 0xb5, 0x76, 0xf5, 0x81, - 0xb6, 0xbb, 0x62, 0x1a, 0xba, 0x5a, 0x81, 0x2f, 0x30, 0x12, 0x06, 0x03, - 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, - 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, - 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x35, 0x06, 0x03, - 0x55, 0x1d, 0x1f, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0, - 0x26, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, - 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, - 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, - 0x63, 0x72, 0x6c, 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x01, 0x01, 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, - 0x63, 0x6f, 0x6d, 0x30, 0x17, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x10, - 0x30, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, - 0x79, 0x02, 0x05, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, - 0x27, 0x8c, 0xcf, 0xe9, 0xc7, 0x3b, 0xbe, 0xc0, 0x6f, 0xe8, 0x96, 0x84, - 0xfb, 0x9c, 0x5c, 0x5d, 0x90, 0xe4, 0x77, 0xdb, 0x8b, 0x32, 0x60, 0x9b, - 0x65, 0xd8, 0x85, 0x26, 0xb5, 0xba, 0x9f, 0x1e, 0xde, 0x64, 0x4e, 0x1f, - 0xc6, 0xc8, 0x20, 0x5b, 0x09, 0x9f, 0xab, 0xa9, 0xe0, 0x09, 0x34, 0x45, - 0xa2, 0x65, 0x25, 0x37, 0x3d, 0x7f, 0x5a, 0x6f, 0x20, 0xcc, 0xf9, 0xfa, - 0xf1, 0x1d, 0x8f, 0x10, 0x0c, 0x02, 0x3a, 0xc4, 0xc9, 0x01, 0x76, 0x96, - 0xbe, 0x9b, 0xf9, 0x15, 0xd8, 0x39, 0xd1, 0xc5, 0x03, 0x47, 0x76, 0xb8, - 0x8a, 0x8c, 0x31, 0xd6, 0x60, 0xd5, 0xe4, 0x8f, 0xdb, 0xfa, 0x3c, 0xc6, - 0xd5, 0x98, 0x28, 0xf8, 0x1c, 0x8f, 0x17, 0x91, 0x34, 0xcb, 0xcb, 0x52, - 0x7a, 0xd1, 0xfb, 0x3a, 0x20, 0xe4, 0xe1, 0x86, 0xb1, 0xd8, 0x18, 0x0f, - 0xbe, 0xd6, 0x87, 0x64, 0x8d, 0xc5, 0x0a, 0x25, 0x42, 0x51, 0xef, 0xb2, - 0x38, 0xb8, 0xe0, 0x1d, 0xd0, 0xe1, 0xfc, 0xe6, 0xf4, 0xaf, 0x46, 0xba, - 0xef, 0xc0, 0xbf, 0xc5, 0xb4, 0x05, 0xf5, 0x94, 0x75, 0x0c, 0xfe, 0xa2, - 0xbe, 0x02, 0xba, 0xea, 0x86, 0x5b, 0xf9, 0x35, 0xb3, 0x66, 0xf5, 0xc5, - 0x8d, 0x85, 0xa1, 0x1a, 0x23, 0x77, 0x1a, 0x19, 0x17, 0x54, 0x13, 0x60, - 0x9f, 0x0b, 0xe1, 0xb4, 0x9c, 0x28, 0x2a, 0xf9, 0xae, 0x02, 0x34, 0x6d, - 0x25, 0x93, 0x9c, 0x82, 0xa8, 0x17, 0x7b, 0xf1, 0x85, 0xb0, 0xd3, 0x0f, - 0x58, 0xe1, 0xfb, 0xb1, 0xfe, 0x9c, 0xa1, 0xa3, 0xe8, 0xfd, 0xc9, 0x3f, - 0xf4, 0xd7, 0x71, 0xdc, 0xbd, 0x8c, 0xa4, 0x19, 0xe0, 0x21, 0x23, 0x23, - 0x55, 0x13, 0x8f, 0xa4, 0x16, 0x02, 0x09, 0x7e, 0xb9, 0xaf, 0xee, 0xdb, - 0x53, 0x64, 0xbd, 0x71, 0x2f, 0xb9, 0x39, 0xce, 0x30, 0xb7, 0xb4, 0xbc, - 0x54, 0xe0, 0x47, 0x07, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 145106 (0x236d2) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA - Validity - Not Before: Feb 26 21:32:31 2010 GMT - Not After : Feb 25 21:32:31 2020 GMT - Subject: C=US, O=GeoTrust Inc., OU=Domain Validated SSL, CN=GeoTrust DV SSL CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:a6:bb:8e:7a:cd:a4:9c:62:57:d4:51:30:42:7b: - 8b:1a:b2:d2:88:06:ad:3b:3c:29:13:0c:31:bc:69: - f9:9f:5a:94:da:06:ba:ac:24:04:9e:ce:d4:aa:c4: - 48:60:00:f8:34:ae:a1:93:af:de:04:7e:cd:f8:5c: - 22:52:0d:56:53:eb:a9:94:cf:fb:74:44:eb:43:94: - a4:97:7a:40:57:35:b6:a4:62:da:d5:48:f8:7a:f1: - ec:90:b5:5f:39:fe:63:72:70:c8:12:85:d0:a5:2e: - 86:13:40:6c:eb:6c:4d:d2:54:fd:5f:3e:26:1f:66: - 71:a8:c0:b8:85:9e:f5:f5:75:8f:da:91:4e:89:e3: - ca:78:74:30:5f:15:0a:99:a7:ca:83:3a:76:35:48: - d0:dc:8b:1a:22:4e:85:a4:4e:fa:49:6d:2b:70:be: - 8e:0c:21:c3:62:cc:a4:d1:ad:16:6b:9a:7b:cb:64: - ff:8d:ba:42:c3:26:aa:15:78:68:9c:ec:f6:6b:c8: - 0c:57:0d:e5:38:07:d3:6a:57:03:9d:20:0e:4b:c4: - 7b:81:b0:2a:1c:f5:4a:ea:4a:98:49:fe:02:5b:3d: - 03:14:90:28:7e:9a:f4:78:d0:31:84:57:e5:4c:38: - 7a:42:11:e2:f5:28:51:03:4b:20:15:bb:22:1a:b6: - f0:15 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Subject Key Identifier: - 8C:F4:D9:93:0A:47:BC:00:A0:4A:CE:4B:75:6E:A0:B6:B0:B2:7E:FC - X509v3 Authority Key Identifier: - keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E - - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.geotrust.com/crls/gtglobal.crl - - Authority Information Access: - OCSP - URI:http://ocsp.geotrust.com - - Signature Algorithm: sha1WithRSAEncryption - 33:91:37:11:db:40:f9:de:8c:b2:02:88:77:af:63:21:c1:ad: - b0:0d:fa:a0:78:56:a3:82:fd:bb:49:5f:14:6d:c8:dc:5f:94: - da:11:66:7c:1e:91:c5:b6:d8:6d:4f:aa:f2:bf:21:28:7e:52: - a2:92:78:08:61:69:21:fe:2d:ec:82:18:84:f4:d3:8d:c5:8a: - bb:8a:cc:5d:e6:a3:b6:cc:6e:ad:6f:b3:0e:61:ee:89:ce:13: - 34:4f:49:55:f5:39:bb:99:96:f0:f5:ea:5a:3c:9c:16:bd:02: - 53:f0:2a:0e:41:6e:eb:ef:9e:f7:70:36:cd:80:2a:76:c8:87: - e3:eb:23:b3:96:2c:e6:1d:94:5f:1c:a4:e2:cd:24:31:2b:06: - 38:32:61:61:39:5c:89:4c:48:1d:42:c9:67:9e:d2:bf:58:f7: - f9:37:31:b0:67:dd:8d:26:36:1a:78:1a:09:19:3c:93:07:70: - 2a:e1:7c:29:f5:de:66:57:0b:12:5e:16:ed:5e:bd:37:b3:30: - 69:c6:92:a5:f6:19:d8:1d:f8:36:12:b9:4b:95:95:9c:d0:ce: - 6c:30:a7:16:fb:f6:4d:64:b6:5f:2a:14:9c:a6:c8:55:8e:20: - f9:65:07:24:cc:38:05:4c:20:88:b4:b5:67:94:cf:5d:8e:62: - 37:fe:c4:b4 ------BEGIN CERTIFICATE----- -MIID+jCCAuKgAwIBAgIDAjbSMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT -MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i -YWwgQ0EwHhcNMTAwMjI2MjEzMjMxWhcNMjAwMjI1MjEzMjMxWjBhMQswCQYDVQQG -EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UECxMURG9tYWluIFZh -bGlkYXRlZCBTU0wxGzAZBgNVBAMTEkdlb1RydXN0IERWIFNTTCBDQTCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBAKa7jnrNpJxiV9RRMEJ7ixqy0ogGrTs8 -KRMMMbxp+Z9alNoGuqwkBJ7O1KrESGAA+DSuoZOv3gR+zfhcIlINVlPrqZTP+3RE -60OUpJd6QFc1tqRi2tVI+Hrx7JC1Xzn+Y3JwyBKF0KUuhhNAbOtsTdJU/V8+Jh9m -cajAuIWe9fV1j9qRTonjynh0MF8VCpmnyoM6djVI0NyLGiJOhaRO+kltK3C+jgwh -w2LMpNGtFmuae8tk/426QsMmqhV4aJzs9mvIDFcN5TgH02pXA50gDkvEe4GwKhz1 -SupKmEn+Als9AxSQKH6a9HjQMYRX5Uw4ekIR4vUoUQNLIBW7Ihq28BUCAwEAAaOB -2TCB1jAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFIz02ZMKR7wAoErOS3VuoLaw -sn78MB8GA1UdIwQYMBaAFMB6mGiNifurBWQMEX2qfWW4ysxOMBIGA1UdEwEB/wQI -MAYBAf8CAQAwOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5j -b20vY3Jscy9ndGdsb2JhbC5jcmwwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzAB -hhhodHRwOi8vb2NzcC5nZW90cnVzdC5jb20wDQYJKoZIhvcNAQEFBQADggEBADOR -NxHbQPnejLICiHevYyHBrbAN+qB4VqOC/btJXxRtyNxflNoRZnwekcW22G1PqvK/ -ISh+UqKSeAhhaSH+LeyCGIT0043FiruKzF3mo7bMbq1vsw5h7onOEzRPSVX1ObuZ -lvD16lo8nBa9AlPwKg5BbuvvnvdwNs2AKnbIh+PrI7OWLOYdlF8cpOLNJDErBjgy -YWE5XIlMSB1CyWee0r9Y9/k3MbBn3Y0mNhp4GgkZPJMHcCrhfCn13mZXCxJeFu1e -vTezMGnGkqX2Gdgd+DYSuUuVlZzQzmwwpxb79k1ktl8qFJymyFWOIPllByTMOAVM -IIi0tWeUz12OYjf+xLQ= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert5[] = { - 0x30, 0x82, 0x03, 0xfa, 0x30, 0x82, 0x02, 0xe2, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x03, 0x02, 0x36, 0xd2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x42, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, - 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, - 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, - 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, - 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, - 0x32, 0x32, 0x36, 0x32, 0x31, 0x33, 0x32, 0x33, 0x31, 0x5a, 0x17, 0x0d, - 0x32, 0x30, 0x30, 0x32, 0x32, 0x35, 0x32, 0x31, 0x33, 0x32, 0x33, 0x31, - 0x5a, 0x30, 0x61, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, - 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, - 0x0b, 0x13, 0x14, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x61, - 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x20, 0x53, 0x53, 0x4c, 0x31, - 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, 0x65, - 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x44, 0x56, 0x20, 0x53, 0x53, - 0x4c, 0x20, 0x43, 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, 0xa6, 0xbb, 0x8e, 0x7a, 0xcd, 0xa4, 0x9c, 0x62, 0x57, 0xd4, 0x51, - 0x30, 0x42, 0x7b, 0x8b, 0x1a, 0xb2, 0xd2, 0x88, 0x06, 0xad, 0x3b, 0x3c, - 0x29, 0x13, 0x0c, 0x31, 0xbc, 0x69, 0xf9, 0x9f, 0x5a, 0x94, 0xda, 0x06, - 0xba, 0xac, 0x24, 0x04, 0x9e, 0xce, 0xd4, 0xaa, 0xc4, 0x48, 0x60, 0x00, - 0xf8, 0x34, 0xae, 0xa1, 0x93, 0xaf, 0xde, 0x04, 0x7e, 0xcd, 0xf8, 0x5c, - 0x22, 0x52, 0x0d, 0x56, 0x53, 0xeb, 0xa9, 0x94, 0xcf, 0xfb, 0x74, 0x44, - 0xeb, 0x43, 0x94, 0xa4, 0x97, 0x7a, 0x40, 0x57, 0x35, 0xb6, 0xa4, 0x62, - 0xda, 0xd5, 0x48, 0xf8, 0x7a, 0xf1, 0xec, 0x90, 0xb5, 0x5f, 0x39, 0xfe, - 0x63, 0x72, 0x70, 0xc8, 0x12, 0x85, 0xd0, 0xa5, 0x2e, 0x86, 0x13, 0x40, - 0x6c, 0xeb, 0x6c, 0x4d, 0xd2, 0x54, 0xfd, 0x5f, 0x3e, 0x26, 0x1f, 0x66, - 0x71, 0xa8, 0xc0, 0xb8, 0x85, 0x9e, 0xf5, 0xf5, 0x75, 0x8f, 0xda, 0x91, - 0x4e, 0x89, 0xe3, 0xca, 0x78, 0x74, 0x30, 0x5f, 0x15, 0x0a, 0x99, 0xa7, - 0xca, 0x83, 0x3a, 0x76, 0x35, 0x48, 0xd0, 0xdc, 0x8b, 0x1a, 0x22, 0x4e, - 0x85, 0xa4, 0x4e, 0xfa, 0x49, 0x6d, 0x2b, 0x70, 0xbe, 0x8e, 0x0c, 0x21, - 0xc3, 0x62, 0xcc, 0xa4, 0xd1, 0xad, 0x16, 0x6b, 0x9a, 0x7b, 0xcb, 0x64, - 0xff, 0x8d, 0xba, 0x42, 0xc3, 0x26, 0xaa, 0x15, 0x78, 0x68, 0x9c, 0xec, - 0xf6, 0x6b, 0xc8, 0x0c, 0x57, 0x0d, 0xe5, 0x38, 0x07, 0xd3, 0x6a, 0x57, - 0x03, 0x9d, 0x20, 0x0e, 0x4b, 0xc4, 0x7b, 0x81, 0xb0, 0x2a, 0x1c, 0xf5, - 0x4a, 0xea, 0x4a, 0x98, 0x49, 0xfe, 0x02, 0x5b, 0x3d, 0x03, 0x14, 0x90, - 0x28, 0x7e, 0x9a, 0xf4, 0x78, 0xd0, 0x31, 0x84, 0x57, 0xe5, 0x4c, 0x38, - 0x7a, 0x42, 0x11, 0xe2, 0xf5, 0x28, 0x51, 0x03, 0x4b, 0x20, 0x15, 0xbb, - 0x22, 0x1a, 0xb6, 0xf0, 0x15, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, - 0xd9, 0x30, 0x81, 0xd6, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, - 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, - 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x8c, 0xf4, 0xd9, 0x93, 0x0a, - 0x47, 0xbc, 0x00, 0xa0, 0x4a, 0xce, 0x4b, 0x75, 0x6e, 0xa0, 0xb6, 0xb0, - 0xb2, 0x7e, 0xfc, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, - 0x30, 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, - 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, - 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, - 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x3a, 0x06, 0x03, - 0x55, 0x1d, 0x1f, 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, 0xa0, 0x2d, 0xa0, - 0x2b, 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, - 0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, - 0x6f, 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x34, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, - 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, - 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, - 0x70, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, - 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x33, 0x91, - 0x37, 0x11, 0xdb, 0x40, 0xf9, 0xde, 0x8c, 0xb2, 0x02, 0x88, 0x77, 0xaf, - 0x63, 0x21, 0xc1, 0xad, 0xb0, 0x0d, 0xfa, 0xa0, 0x78, 0x56, 0xa3, 0x82, - 0xfd, 0xbb, 0x49, 0x5f, 0x14, 0x6d, 0xc8, 0xdc, 0x5f, 0x94, 0xda, 0x11, - 0x66, 0x7c, 0x1e, 0x91, 0xc5, 0xb6, 0xd8, 0x6d, 0x4f, 0xaa, 0xf2, 0xbf, - 0x21, 0x28, 0x7e, 0x52, 0xa2, 0x92, 0x78, 0x08, 0x61, 0x69, 0x21, 0xfe, - 0x2d, 0xec, 0x82, 0x18, 0x84, 0xf4, 0xd3, 0x8d, 0xc5, 0x8a, 0xbb, 0x8a, - 0xcc, 0x5d, 0xe6, 0xa3, 0xb6, 0xcc, 0x6e, 0xad, 0x6f, 0xb3, 0x0e, 0x61, - 0xee, 0x89, 0xce, 0x13, 0x34, 0x4f, 0x49, 0x55, 0xf5, 0x39, 0xbb, 0x99, - 0x96, 0xf0, 0xf5, 0xea, 0x5a, 0x3c, 0x9c, 0x16, 0xbd, 0x02, 0x53, 0xf0, - 0x2a, 0x0e, 0x41, 0x6e, 0xeb, 0xef, 0x9e, 0xf7, 0x70, 0x36, 0xcd, 0x80, - 0x2a, 0x76, 0xc8, 0x87, 0xe3, 0xeb, 0x23, 0xb3, 0x96, 0x2c, 0xe6, 0x1d, - 0x94, 0x5f, 0x1c, 0xa4, 0xe2, 0xcd, 0x24, 0x31, 0x2b, 0x06, 0x38, 0x32, - 0x61, 0x61, 0x39, 0x5c, 0x89, 0x4c, 0x48, 0x1d, 0x42, 0xc9, 0x67, 0x9e, - 0xd2, 0xbf, 0x58, 0xf7, 0xf9, 0x37, 0x31, 0xb0, 0x67, 0xdd, 0x8d, 0x26, - 0x36, 0x1a, 0x78, 0x1a, 0x09, 0x19, 0x3c, 0x93, 0x07, 0x70, 0x2a, 0xe1, - 0x7c, 0x29, 0xf5, 0xde, 0x66, 0x57, 0x0b, 0x12, 0x5e, 0x16, 0xed, 0x5e, - 0xbd, 0x37, 0xb3, 0x30, 0x69, 0xc6, 0x92, 0xa5, 0xf6, 0x19, 0xd8, 0x1d, - 0xf8, 0x36, 0x12, 0xb9, 0x4b, 0x95, 0x95, 0x9c, 0xd0, 0xce, 0x6c, 0x30, - 0xa7, 0x16, 0xfb, 0xf6, 0x4d, 0x64, 0xb6, 0x5f, 0x2a, 0x14, 0x9c, 0xa6, - 0xc8, 0x55, 0x8e, 0x20, 0xf9, 0x65, 0x07, 0x24, 0xcc, 0x38, 0x05, 0x4c, - 0x20, 0x88, 0xb4, 0xb5, 0x67, 0x94, 0xcf, 0x5d, 0x8e, 0x62, 0x37, 0xfe, - 0xc4, 0xb4, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 120033005 (0x7278eed) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=GTE Corporation, OU=GTE CyberTrust Solutions, Inc., CN=GTE CyberTrust Global Root - Validity - Not Before: Apr 18 16:36:18 2012 GMT - Not After : Aug 13 16:35:17 2018 GMT - Subject: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:a3:04:bb:22:ab:98:3d:57:e8:26:72:9a:b5:79: - d4:29:e2:e1:e8:95:80:b1:b0:e3:5b:8e:2b:29:9a: - 64:df:a1:5d:ed:b0:09:05:6d:db:28:2e:ce:62:a2: - 62:fe:b4:88:da:12:eb:38:eb:21:9d:c0:41:2b:01: - 52:7b:88:77:d3:1c:8f:c7:ba:b9:88:b5:6a:09:e7: - 73:e8:11:40:a7:d1:cc:ca:62:8d:2d:e5:8f:0b:a6: - 50:d2:a8:50:c3:28:ea:f5:ab:25:87:8a:9a:96:1c: - a9:67:b8:3f:0c:d5:f7:f9:52:13:2f:c2:1b:d5:70: - 70:f0:8f:c0:12:ca:06:cb:9a:e1:d9:ca:33:7a:77: - d6:f8:ec:b9:f1:68:44:42:48:13:d2:c0:c2:a4:ae: - 5e:60:fe:b6:a6:05:fc:b4:dd:07:59:02:d4:59:18: - 98:63:f5:a5:63:e0:90:0c:7d:5d:b2:06:7a:f3:85: - ea:eb:d4:03:ae:5e:84:3e:5f:ff:15:ed:69:bc:f9: - 39:36:72:75:cf:77:52:4d:f3:c9:90:2c:b9:3d:e5: - c9:23:53:3f:1f:24:98:21:5c:07:99:29:bd:c6:3a: - ec:e7:6e:86:3a:6b:97:74:63:33:bd:68:18:31:f0: - 78:8d:76:bf:fc:9e:8e:5d:2a:86:a7:4d:90:dc:27: - 1a:39 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:3 - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: http://cybertrust.omniroot.com/repository - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Authority Key Identifier: - DirName:/C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Global Root - serial:01:A5 - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://www.public-trust.com/cgi-bin/CRL/2018/cdp.crl - - Signature Algorithm: sha1WithRSAEncryption - 93:1d:fe:8b:ae:46:ec:cb:a9:0f:ab:e5:ef:ca:b2:68:16:68: - d8:8f:fa:13:a9:af:b3:cb:2d:e7:4b:6e:8e:69:2a:c2:2b:10: - 0a:8d:f6:ae:73:b6:b9:fb:14:fd:5f:6d:b8:50:b6:c4:8a:d6: - 40:7e:d7:c3:cb:73:dc:c9:5d:5b:af:b0:41:b5:37:eb:ea:dc: - 20:91:c4:34:6a:f4:a1:f3:96:9d:37:86:97:e1:71:a4:dd:7d: - fa:44:84:94:ae:d7:09:04:22:76:0f:64:51:35:a9:24:0f:f9: - 0b:db:32:da:c2:fe:c1:b9:2a:5c:7a:27:13:ca:b1:48:3a:71: - d0:43 ------BEGIN CERTIFICATE----- -MIIEFTCCA36gAwIBAgIEByeO7TANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV -UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU -cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds -b2JhbCBSb290MB4XDTEyMDQxODE2MzYxOFoXDTE4MDgxMzE2MzUxN1owWjELMAkG -A1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVz -dDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKrmD1X6CZymrV51Cni4eiVgLGw41uO -KymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsBUnuId9Mcj8e6uYi1agnn -c+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/CG9VwcPCP -wBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPg -kAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFc -B5kpvcY67Oduhjprl3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaOCAUcw -ggFDMBIGA1UdEwEB/wQIMAYBAf8CAQMwSgYDVR0gBEMwQTA/BgRVHSAAMDcwNQYI -KwYBBQUHAgEWKWh0dHA6Ly9jeWJlcnRydXN0Lm9tbmlyb290LmNvbS9yZXBvc2l0 -b3J5MA4GA1UdDwEB/wQEAwIBBjCBiQYDVR0jBIGBMH+heaR3MHUxCzAJBgNVBAYT -AlVTMRgwFgYDVQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJl -clRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3Qg -R2xvYmFsIFJvb3SCAgGlMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly93d3cucHVi -bGljLXRydXN0LmNvbS9jZ2ktYmluL0NSTC8yMDE4L2NkcC5jcmwwDQYJKoZIhvcN -AQEFBQADgYEAkx3+i65G7MupD6vl78qyaBZo2I/6E6mvs8st50tujmkqwisQCo32 -rnO2ufsU/V9tuFC2xIrWQH7Xw8tz3MldW6+wQbU36+rcIJHENGr0ofOWnTeGl+Fx -pN19+kSElK7XCQQidg9kUTWpJA/5C9sy2sL+wbkqXHonE8qxSDpx0EM= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert6[] = { - 0x30, 0x82, 0x04, 0x15, 0x30, 0x82, 0x03, 0x7e, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x04, 0x07, 0x27, 0x8e, 0xed, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x75, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0f, - 0x47, 0x54, 0x45, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x13, 0x1e, 0x47, 0x54, 0x45, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, - 0x72, 0x75, 0x73, 0x74, 0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x23, 0x30, 0x21, - 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x47, 0x54, 0x45, 0x20, 0x43, - 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, - 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, - 0x0d, 0x31, 0x32, 0x30, 0x34, 0x31, 0x38, 0x31, 0x36, 0x33, 0x36, 0x31, - 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x38, 0x31, 0x33, 0x31, 0x36, - 0x33, 0x35, 0x31, 0x37, 0x5a, 0x30, 0x5a, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10, - 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, 0x42, 0x61, 0x6c, 0x74, 0x69, - 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, - 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, - 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, - 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x43, 0x79, - 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, - 0x74, 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, 0xa3, 0x04, - 0xbb, 0x22, 0xab, 0x98, 0x3d, 0x57, 0xe8, 0x26, 0x72, 0x9a, 0xb5, 0x79, - 0xd4, 0x29, 0xe2, 0xe1, 0xe8, 0x95, 0x80, 0xb1, 0xb0, 0xe3, 0x5b, 0x8e, - 0x2b, 0x29, 0x9a, 0x64, 0xdf, 0xa1, 0x5d, 0xed, 0xb0, 0x09, 0x05, 0x6d, - 0xdb, 0x28, 0x2e, 0xce, 0x62, 0xa2, 0x62, 0xfe, 0xb4, 0x88, 0xda, 0x12, - 0xeb, 0x38, 0xeb, 0x21, 0x9d, 0xc0, 0x41, 0x2b, 0x01, 0x52, 0x7b, 0x88, - 0x77, 0xd3, 0x1c, 0x8f, 0xc7, 0xba, 0xb9, 0x88, 0xb5, 0x6a, 0x09, 0xe7, - 0x73, 0xe8, 0x11, 0x40, 0xa7, 0xd1, 0xcc, 0xca, 0x62, 0x8d, 0x2d, 0xe5, - 0x8f, 0x0b, 0xa6, 0x50, 0xd2, 0xa8, 0x50, 0xc3, 0x28, 0xea, 0xf5, 0xab, - 0x25, 0x87, 0x8a, 0x9a, 0x96, 0x1c, 0xa9, 0x67, 0xb8, 0x3f, 0x0c, 0xd5, - 0xf7, 0xf9, 0x52, 0x13, 0x2f, 0xc2, 0x1b, 0xd5, 0x70, 0x70, 0xf0, 0x8f, - 0xc0, 0x12, 0xca, 0x06, 0xcb, 0x9a, 0xe1, 0xd9, 0xca, 0x33, 0x7a, 0x77, - 0xd6, 0xf8, 0xec, 0xb9, 0xf1, 0x68, 0x44, 0x42, 0x48, 0x13, 0xd2, 0xc0, - 0xc2, 0xa4, 0xae, 0x5e, 0x60, 0xfe, 0xb6, 0xa6, 0x05, 0xfc, 0xb4, 0xdd, - 0x07, 0x59, 0x02, 0xd4, 0x59, 0x18, 0x98, 0x63, 0xf5, 0xa5, 0x63, 0xe0, - 0x90, 0x0c, 0x7d, 0x5d, 0xb2, 0x06, 0x7a, 0xf3, 0x85, 0xea, 0xeb, 0xd4, - 0x03, 0xae, 0x5e, 0x84, 0x3e, 0x5f, 0xff, 0x15, 0xed, 0x69, 0xbc, 0xf9, - 0x39, 0x36, 0x72, 0x75, 0xcf, 0x77, 0x52, 0x4d, 0xf3, 0xc9, 0x90, 0x2c, - 0xb9, 0x3d, 0xe5, 0xc9, 0x23, 0x53, 0x3f, 0x1f, 0x24, 0x98, 0x21, 0x5c, - 0x07, 0x99, 0x29, 0xbd, 0xc6, 0x3a, 0xec, 0xe7, 0x6e, 0x86, 0x3a, 0x6b, - 0x97, 0x74, 0x63, 0x33, 0xbd, 0x68, 0x18, 0x31, 0xf0, 0x78, 0x8d, 0x76, - 0xbf, 0xfc, 0x9e, 0x8e, 0x5d, 0x2a, 0x86, 0xa7, 0x4d, 0x90, 0xdc, 0x27, - 0x1a, 0x39, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x47, 0x30, - 0x82, 0x01, 0x43, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, - 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x03, 0x30, - 0x4a, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x43, 0x30, 0x41, 0x30, 0x3f, - 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x37, 0x30, 0x35, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x29, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, - 0x75, 0x73, 0x74, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, - 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x81, 0x89, 0x06, 0x03, - 0x55, 0x1d, 0x23, 0x04, 0x81, 0x81, 0x30, 0x7f, 0xa1, 0x79, 0xa4, 0x77, - 0x30, 0x75, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x0f, 0x47, 0x54, 0x45, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, - 0x04, 0x0b, 0x13, 0x1e, 0x47, 0x54, 0x45, 0x20, 0x43, 0x79, 0x62, 0x65, - 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x23, - 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x47, 0x54, 0x45, - 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, - 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x82, - 0x02, 0x01, 0xa5, 0x30, 0x45, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3e, - 0x30, 0x3c, 0x30, 0x3a, 0xa0, 0x38, 0xa0, 0x36, 0x86, 0x34, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x70, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x63, 0x67, 0x69, 0x2d, 0x62, 0x69, 0x6e, 0x2f, 0x43, 0x52, - 0x4c, 0x2f, 0x32, 0x30, 0x31, 0x38, 0x2f, 0x63, 0x64, 0x70, 0x2e, 0x63, - 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x93, 0x1d, 0xfe, - 0x8b, 0xae, 0x46, 0xec, 0xcb, 0xa9, 0x0f, 0xab, 0xe5, 0xef, 0xca, 0xb2, - 0x68, 0x16, 0x68, 0xd8, 0x8f, 0xfa, 0x13, 0xa9, 0xaf, 0xb3, 0xcb, 0x2d, - 0xe7, 0x4b, 0x6e, 0x8e, 0x69, 0x2a, 0xc2, 0x2b, 0x10, 0x0a, 0x8d, 0xf6, - 0xae, 0x73, 0xb6, 0xb9, 0xfb, 0x14, 0xfd, 0x5f, 0x6d, 0xb8, 0x50, 0xb6, - 0xc4, 0x8a, 0xd6, 0x40, 0x7e, 0xd7, 0xc3, 0xcb, 0x73, 0xdc, 0xc9, 0x5d, - 0x5b, 0xaf, 0xb0, 0x41, 0xb5, 0x37, 0xeb, 0xea, 0xdc, 0x20, 0x91, 0xc4, - 0x34, 0x6a, 0xf4, 0xa1, 0xf3, 0x96, 0x9d, 0x37, 0x86, 0x97, 0xe1, 0x71, - 0xa4, 0xdd, 0x7d, 0xfa, 0x44, 0x84, 0x94, 0xae, 0xd7, 0x09, 0x04, 0x22, - 0x76, 0x0f, 0x64, 0x51, 0x35, 0xa9, 0x24, 0x0f, 0xf9, 0x0b, 0xdb, 0x32, - 0xda, 0xc2, 0xfe, 0xc1, 0xb9, 0x2a, 0x5c, 0x7a, 0x27, 0x13, 0xca, 0xb1, - 0x48, 0x3a, 0x71, 0xd0, 0x43, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 120010508 (0x727370c) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root - Validity - Not Before: Sep 8 17:35:16 2010 GMT - Not After : Sep 8 17:34:08 2020 GMT - Subject: O=Cybertrust Inc, CN=Cybertrust Public SureServer SV CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:a3:ba:99:8d:b7:e1:cd:73:88:f9:b9:dd:de:f4: - 05:f3:25:f5:3f:c5:52:1e:51:5a:3f:9a:ff:4d:84: - b7:50:7f:f1:10:8a:5d:7f:64:55:1c:3b:a3:f3:ff: - 97:7f:1c:4b:ed:6f:7f:e9:54:ec:97:2a:42:03:67: - 7f:b9:c8:6c:a2:97:f8:40:93:24:c3:25:5e:a5:66: - 8b:86:bd:d7:b9:26:22:6e:d2:66:83:b3:78:c1:7c: - 58:76:11:eb:16:55:47:32:f0:b9:34:10:bd:8f:26: - a2:25:68:c1:14:2b:a2:73:d6:66:3d:44:87:5c:13: - 7f:58:91:62:3d:57:7f:6c:ae:42:e8:12:7e:bd:78: - f1:f1:ac:5c:35:60:68:45:bc:53:73:87:11:1d:c5: - 2e:fa:60:35:da:91:f9:da:f2:55:6c:bf:ca:a2:57: - 5c:c8:64:bc:a9:5b:15:a0:fc:1c:f3:44:2e:bd:06: - f2:68:d8:40:2d:bb:b3:61:25:92:93:25:1c:77:46: - 90:bf:d0:af:b7:83:a0:3c:87:5e:a5:91:a8:ff:c1: - 31:1b:b6:4b:ac:12:34:08:d5:db:ec:89:87:63:06: - a7:53:f8:d5:f5:e6:66:ac:5e:84:65:46:c9:f4:3a: - 25:0f:6c:cc:0f:66:b8:9a:55:a1:46:6c:fc:91:23: - 5f:bd - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Certificate Policies: - Policy: 1.3.6.1.4.1.6334.1.50 - CPS: http://cybertrust.omniroot.com/repository - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Authority Key Identifier: - keyid:E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0 - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://cdp1.public-trust.com/CRL/Omniroot2025.crl - - X509v3 Subject Key Identifier: - 04:98:60:DF:80:1B:96:49:5D:65:56:2D:A5:2C:09:24:0A:EC:DC:B9 - Signature Algorithm: sha1WithRSAEncryption - 5f:df:8b:cf:29:79:78:2b:f3:7c:f4:82:5f:79:e0:e1:b3:28: - bd:08:75:41:ce:8c:88:d7:0e:55:b9:02:b5:05:79:3e:bb:52: - 31:b3:4b:1e:b1:fe:d3:a2:21:43:d2:91:d3:16:fa:6b:79:e4: - 8e:4d:19:ec:4c:86:68:34:52:b7:6f:c2:bd:9c:78:be:f0:6f: - 3f:3d:9e:9f:49:74:c4:7c:97:19:45:57:ac:6f:fa:5a:3e:3f: - d3:d6:e3:2b:dc:8a:f8:c8:0a:0d:6b:8c:3f:94:78:37:98:88: - 61:91:df:59:14:0f:09:c5:63:54:fb:f4:f6:af:97:ec:fc:63: - 64:43:a6:bc:cc:e4:e3:1f:df:73:b0:6e:f7:b5:c8:29:9b:ae: - 25:52:b8:b4:72:e1:de:93:48:f1:28:9f:7e:66:3f:3f:8b:55: - 0f:f8:16:07:71:05:d7:65:9c:d7:1b:3c:34:e6:44:16:3a:bd: - d8:60:93:83:83:0c:88:96:65:33:40:df:6a:ac:ff:fe:94:51: - 61:bb:89:3f:f7:ac:c4:e4:b3:47:e2:fd:a2:6a:32:83:e2:7e: - 6f:f0:12:8e:a3:66:76:40:97:fb:11:e1:f7:73:1f:da:8b:1c: - 31:42:8b:9f:11:c5:49:a5:60:ed:48:2b:05:84:15:ab:2f:8a: - 2c:51:72:c0 ------BEGIN CERTIFICATE----- -MIIEGzCCAwOgAwIBAgIEByc3DDANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ -RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD -VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTEwMDkwODE3MzUxNloX -DTIwMDkwODE3MzQwOFowRjEXMBUGA1UEChMOQ3liZXJ0cnVzdCBJbmMxKzApBgNV -BAMTIkN5YmVydHJ1c3QgUHVibGljIFN1cmVTZXJ2ZXIgU1YgQ0EwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCjupmNt+HNc4j5ud3e9AXzJfU/xVIeUVo/ -mv9NhLdQf/EQil1/ZFUcO6Pz/5d/HEvtb3/pVOyXKkIDZ3+5yGyil/hAkyTDJV6l -ZouGvde5JiJu0maDs3jBfFh2EesWVUcy8Lk0EL2PJqIlaMEUK6Jz1mY9RIdcE39Y -kWI9V39srkLoEn69ePHxrFw1YGhFvFNzhxEdxS76YDXakfna8lVsv8qiV1zIZLyp -WxWg/BzzRC69BvJo2EAtu7NhJZKTJRx3RpC/0K+3g6A8h16lkaj/wTEbtkusEjQI -1dvsiYdjBqdT+NX15masXoRlRsn0OiUPbMwPZriaVaFGbPyRI1+9AgMBAAGjgfww -gfkwEgYDVR0TAQH/BAgwBgEB/wIBADBPBgNVHSAESDBGMEQGCSsGAQQBsT4BMjA3 -MDUGCCsGAQUFBwIBFilodHRwOi8vY3liZXJ0cnVzdC5vbW5pcm9vdC5jb20vcmVw -b3NpdG9yeTAOBgNVHQ8BAf8EBAMCAQYwHwYDVR0jBBgwFoAU5Z1ZMIJHWMys+ghU -NoZ7OrUETfAwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NkcDEucHVibGljLXRy -dXN0LmNvbS9DUkwvT21uaXJvb3QyMDI1LmNybDAdBgNVHQ4EFgQUBJhg34Ablkld -ZVYtpSwJJArs3LkwDQYJKoZIhvcNAQEFBQADggEBAF/fi88peXgr83z0gl954OGz -KL0IdUHOjIjXDlW5ArUFeT67UjGzSx6x/tOiIUPSkdMW+mt55I5NGexMhmg0Urdv -wr2ceL7wbz89np9JdMR8lxlFV6xv+lo+P9PW4yvcivjICg1rjD+UeDeYiGGR31kU -DwnFY1T79Pavl+z8Y2RDprzM5OMf33Owbve1yCmbriVSuLRy4d6TSPEon35mPz+L -VQ/4FgdxBddlnNcbPDTmRBY6vdhgk4ODDIiWZTNA32qs//6UUWG7iT/3rMTks0fi -/aJqMoPifm/wEo6jZnZAl/sR4fdzH9qLHDFCi58RxUmlYO1IKwWEFasviixRcsA= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert7[] = { - 0x30, 0x82, 0x04, 0x1b, 0x30, 0x82, 0x03, 0x03, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x04, 0x07, 0x27, 0x37, 0x0c, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5a, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49, - 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, - 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30, - 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65, - 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, - 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, - 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, - 0x30, 0x39, 0x30, 0x38, 0x31, 0x37, 0x33, 0x35, 0x31, 0x36, 0x5a, 0x17, - 0x0d, 0x32, 0x30, 0x30, 0x39, 0x30, 0x38, 0x31, 0x37, 0x33, 0x34, 0x30, - 0x38, 0x5a, 0x30, 0x46, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x0e, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x22, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x53, 0x75, - 0x72, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x53, 0x56, 0x20, - 0x43, 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, 0xa3, - 0xba, 0x99, 0x8d, 0xb7, 0xe1, 0xcd, 0x73, 0x88, 0xf9, 0xb9, 0xdd, 0xde, - 0xf4, 0x05, 0xf3, 0x25, 0xf5, 0x3f, 0xc5, 0x52, 0x1e, 0x51, 0x5a, 0x3f, - 0x9a, 0xff, 0x4d, 0x84, 0xb7, 0x50, 0x7f, 0xf1, 0x10, 0x8a, 0x5d, 0x7f, - 0x64, 0x55, 0x1c, 0x3b, 0xa3, 0xf3, 0xff, 0x97, 0x7f, 0x1c, 0x4b, 0xed, - 0x6f, 0x7f, 0xe9, 0x54, 0xec, 0x97, 0x2a, 0x42, 0x03, 0x67, 0x7f, 0xb9, - 0xc8, 0x6c, 0xa2, 0x97, 0xf8, 0x40, 0x93, 0x24, 0xc3, 0x25, 0x5e, 0xa5, - 0x66, 0x8b, 0x86, 0xbd, 0xd7, 0xb9, 0x26, 0x22, 0x6e, 0xd2, 0x66, 0x83, - 0xb3, 0x78, 0xc1, 0x7c, 0x58, 0x76, 0x11, 0xeb, 0x16, 0x55, 0x47, 0x32, - 0xf0, 0xb9, 0x34, 0x10, 0xbd, 0x8f, 0x26, 0xa2, 0x25, 0x68, 0xc1, 0x14, - 0x2b, 0xa2, 0x73, 0xd6, 0x66, 0x3d, 0x44, 0x87, 0x5c, 0x13, 0x7f, 0x58, - 0x91, 0x62, 0x3d, 0x57, 0x7f, 0x6c, 0xae, 0x42, 0xe8, 0x12, 0x7e, 0xbd, - 0x78, 0xf1, 0xf1, 0xac, 0x5c, 0x35, 0x60, 0x68, 0x45, 0xbc, 0x53, 0x73, - 0x87, 0x11, 0x1d, 0xc5, 0x2e, 0xfa, 0x60, 0x35, 0xda, 0x91, 0xf9, 0xda, - 0xf2, 0x55, 0x6c, 0xbf, 0xca, 0xa2, 0x57, 0x5c, 0xc8, 0x64, 0xbc, 0xa9, - 0x5b, 0x15, 0xa0, 0xfc, 0x1c, 0xf3, 0x44, 0x2e, 0xbd, 0x06, 0xf2, 0x68, - 0xd8, 0x40, 0x2d, 0xbb, 0xb3, 0x61, 0x25, 0x92, 0x93, 0x25, 0x1c, 0x77, - 0x46, 0x90, 0xbf, 0xd0, 0xaf, 0xb7, 0x83, 0xa0, 0x3c, 0x87, 0x5e, 0xa5, - 0x91, 0xa8, 0xff, 0xc1, 0x31, 0x1b, 0xb6, 0x4b, 0xac, 0x12, 0x34, 0x08, - 0xd5, 0xdb, 0xec, 0x89, 0x87, 0x63, 0x06, 0xa7, 0x53, 0xf8, 0xd5, 0xf5, - 0xe6, 0x66, 0xac, 0x5e, 0x84, 0x65, 0x46, 0xc9, 0xf4, 0x3a, 0x25, 0x0f, - 0x6c, 0xcc, 0x0f, 0x66, 0xb8, 0x9a, 0x55, 0xa1, 0x46, 0x6c, 0xfc, 0x91, - 0x23, 0x5f, 0xbd, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xfc, 0x30, - 0x81, 0xf9, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, - 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x4f, - 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x48, 0x30, 0x46, 0x30, 0x44, 0x06, - 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb1, 0x3e, 0x01, 0x32, 0x30, 0x37, - 0x30, 0x35, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, - 0x16, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x79, 0x62, - 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, - 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x30, 0x0e, 0x06, 0x03, 0x55, - 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, - 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, - 0xe5, 0x9d, 0x59, 0x30, 0x82, 0x47, 0x58, 0xcc, 0xac, 0xfa, 0x08, 0x54, - 0x36, 0x86, 0x7b, 0x3a, 0xb5, 0x04, 0x4d, 0xf0, 0x30, 0x42, 0x06, 0x03, - 0x55, 0x1d, 0x1f, 0x04, 0x3b, 0x30, 0x39, 0x30, 0x37, 0xa0, 0x35, 0xa0, - 0x33, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x64, - 0x70, 0x31, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, - 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x52, 0x4c, 0x2f, - 0x4f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x32, 0x30, 0x32, 0x35, - 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, - 0x16, 0x04, 0x14, 0x04, 0x98, 0x60, 0xdf, 0x80, 0x1b, 0x96, 0x49, 0x5d, - 0x65, 0x56, 0x2d, 0xa5, 0x2c, 0x09, 0x24, 0x0a, 0xec, 0xdc, 0xb9, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, - 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x5f, 0xdf, 0x8b, 0xcf, 0x29, - 0x79, 0x78, 0x2b, 0xf3, 0x7c, 0xf4, 0x82, 0x5f, 0x79, 0xe0, 0xe1, 0xb3, - 0x28, 0xbd, 0x08, 0x75, 0x41, 0xce, 0x8c, 0x88, 0xd7, 0x0e, 0x55, 0xb9, - 0x02, 0xb5, 0x05, 0x79, 0x3e, 0xbb, 0x52, 0x31, 0xb3, 0x4b, 0x1e, 0xb1, - 0xfe, 0xd3, 0xa2, 0x21, 0x43, 0xd2, 0x91, 0xd3, 0x16, 0xfa, 0x6b, 0x79, - 0xe4, 0x8e, 0x4d, 0x19, 0xec, 0x4c, 0x86, 0x68, 0x34, 0x52, 0xb7, 0x6f, - 0xc2, 0xbd, 0x9c, 0x78, 0xbe, 0xf0, 0x6f, 0x3f, 0x3d, 0x9e, 0x9f, 0x49, - 0x74, 0xc4, 0x7c, 0x97, 0x19, 0x45, 0x57, 0xac, 0x6f, 0xfa, 0x5a, 0x3e, - 0x3f, 0xd3, 0xd6, 0xe3, 0x2b, 0xdc, 0x8a, 0xf8, 0xc8, 0x0a, 0x0d, 0x6b, - 0x8c, 0x3f, 0x94, 0x78, 0x37, 0x98, 0x88, 0x61, 0x91, 0xdf, 0x59, 0x14, - 0x0f, 0x09, 0xc5, 0x63, 0x54, 0xfb, 0xf4, 0xf6, 0xaf, 0x97, 0xec, 0xfc, - 0x63, 0x64, 0x43, 0xa6, 0xbc, 0xcc, 0xe4, 0xe3, 0x1f, 0xdf, 0x73, 0xb0, - 0x6e, 0xf7, 0xb5, 0xc8, 0x29, 0x9b, 0xae, 0x25, 0x52, 0xb8, 0xb4, 0x72, - 0xe1, 0xde, 0x93, 0x48, 0xf1, 0x28, 0x9f, 0x7e, 0x66, 0x3f, 0x3f, 0x8b, - 0x55, 0x0f, 0xf8, 0x16, 0x07, 0x71, 0x05, 0xd7, 0x65, 0x9c, 0xd7, 0x1b, - 0x3c, 0x34, 0xe6, 0x44, 0x16, 0x3a, 0xbd, 0xd8, 0x60, 0x93, 0x83, 0x83, - 0x0c, 0x88, 0x96, 0x65, 0x33, 0x40, 0xdf, 0x6a, 0xac, 0xff, 0xfe, 0x94, - 0x51, 0x61, 0xbb, 0x89, 0x3f, 0xf7, 0xac, 0xc4, 0xe4, 0xb3, 0x47, 0xe2, - 0xfd, 0xa2, 0x6a, 0x32, 0x83, 0xe2, 0x7e, 0x6f, 0xf0, 0x12, 0x8e, 0xa3, - 0x66, 0x76, 0x40, 0x97, 0xfb, 0x11, 0xe1, 0xf7, 0x73, 0x1f, 0xda, 0x8b, - 0x1c, 0x31, 0x42, 0x8b, 0x9f, 0x11, 0xc5, 0x49, 0xa5, 0x60, 0xed, 0x48, - 0x2b, 0x05, 0x84, 0x15, 0xab, 0x2f, 0x8a, 0x2c, 0x51, 0x72, 0xc0, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 11:20:96:f6:c8:03:7c:9e:07:b1:38:bf:2e:72:10:8a:d7:ed - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=FR, O=Certplus, CN=Class 2 Primary CA - Validity - Not Before: Jun 5 00:00:00 2007 GMT - Not After : Jun 20 00:00:00 2019 GMT - Subject: C=FR, O=KEYNECTIS, CN=CLASS 2 KEYNECTIS CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:c6:be:fe:44:23:04:d4:ef:2f:3b:86:aa:35:58: - 81:d1:e1:9a:d6:b1:d4:27:45:28:fc:d1:1e:46:85: - ba:54:23:11:7d:e0:66:3f:d4:a3:57:66:78:f9:6b: - eb:74:7c:2a:b8:37:a5:e8:70:ae:82:b5:4e:d4:81: - fe:5b:e2:ea:e7:22:16:f8:f9:d7:ba:3a:f6:88:56: - dc:c4:f2:a0:a4:e5:75:06:60:72:2b:fb:f5:94:ee: - 2c:83:28:de:91:9a:b3:83:3a:b0:9f:08:fa:dd:d8: - 9e:8c:24:e6:df:66:5b:c8:7e:a3:62:4d:3f:3a:85: - 23:ec:e8:71:8f:0a:00:ac:89:6d:7e:d8:72:e5:dd: - c1:94:8e:5f:e4:73:e6:c1:c6:0c:87:58:4f:37:da: - d1:a9:88:26:76:b4:ee:11:8d:f6:ad:b2:a7:bc:73: - c4:cd:1c:6e:1a:e6:8d:72:56:44:a0:98:f7:92:f9: - d7:79:9b:03:e6:68:5f:a4:5c:7c:3d:50:b4:83:cc: - e5:ac:0d:e1:3e:4f:14:f2:b4:e4:7d:bf:71:a4:c3: - 97:73:38:d6:52:7c:c8:a4:b5:ea:e9:b2:54:56:d4: - eb:b8:57:3a:40:52:5a:5e:46:27:a3:7b:30:2d:08: - 3d:85:1e:9a:f0:32:a8:f2:10:a2:83:9b:e2:28:f6: - 9d:cb - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Certificate Policies: - Policy: 1.3.6.4.1.22234.2.5.3.3 - CPS: http://www.keynectis.com/PC - Policy: 1.3.6.4.1.22234.2.5.1.3 - CPS: http://www.keynectis.com/PC - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://www.certplus.com/CRL/class2.crl - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Subject Key Identifier: - 00:11:41:DF:3B:9D:3B:CB:B8:A2:C1:33:92:A8:81:CC:E5:7D:E7:99 - X509v3 Authority Key Identifier: - keyid:E3:73:2D:DF:CB:0E:28:0C:DE:DD:B3:A4:CA:79:B8:8E:BB:E8:30:89 - - Signature Algorithm: sha1WithRSAEncryption - 08:88:fe:1f:a2:ca:cd:e2:a0:f1:2e:7c:67:49:fb:dc:94:ac: - 7f:41:0d:78:01:ba:31:f7:9b:fb:31:18:77:2f:66:25:94:b8: - 6d:16:74:81:f1:c0:ae:67:c6:14:45:7a:01:d1:13:88:fc:e2: - 8d:22:1d:bd:1e:0c:c7:a9:7e:d0:c3:97:f6:37:5b:41:5e:67: - 94:8e:ab:69:02:17:18:f5:4d:38:c2:49:28:09:6e:5a:9b:a6: - 27:db:c0:5f:8f:44:9c:90:65:99:d8:b3:2e:c1:92:ee:1a:9d: - 0f:72:45:20:fa:2c:0c:9c:5d:cd:5b:54:41:54:4f:d3:e2:c7: - 59:84:3f:17:7b:7d:0e:c2:ef:62:c7:ba:b1:26:6c:83:4e:d3: - 19:c5:ff:56:a7:b4:45:3f:7a:9e:fa:d0:39:3e:80:46:75:5d: - 5a:79:7a:33:c5:01:bc:02:44:ce:1b:c0:31:4e:47:96:15:6e: - e7:e4:76:f0:c2:90:0d:a1:78:f4:38:00:91:2b:65:7c:79:13: - a8:3e:91:14:dc:88:05:08:d7:6f:53:f6:15:43:ee:c5:53:56: - 1a:02:b5:a6:a2:46:8d:1e:13:e4:67:c2:45:5f:40:5e:10:42: - 58:b5:cd:44:a3:94:4c:1c:54:90:4d:91:9a:26:8b:ad:a2:80: - 50:8d:14:14 ------BEGIN CERTIFICATE----- -MIIEKzCCAxOgAwIBAgISESCW9sgDfJ4HsTi/LnIQitftMA0GCSqGSIb3DQEBBQUA -MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xh -c3MgMiBQcmltYXJ5IENBMB4XDTA3MDYwNTAwMDAwMFoXDTE5MDYyMDAwMDAwMFow -QDELMAkGA1UEBhMCRlIxEjAQBgNVBAoTCUtFWU5FQ1RJUzEdMBsGA1UEAxMUQ0xB -U1MgMiBLRVlORUNUSVMgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQDGvv5EIwTU7y87hqo1WIHR4ZrWsdQnRSj80R5GhbpUIxF94GY/1KNXZnj5a+t0 -fCq4N6XocK6CtU7Ugf5b4urnIhb4+de6OvaIVtzE8qCk5XUGYHIr+/WU7iyDKN6R -mrODOrCfCPrd2J6MJObfZlvIfqNiTT86hSPs6HGPCgCsiW1+2HLl3cGUjl/kc+bB -xgyHWE832tGpiCZ2tO4Rjfatsqe8c8TNHG4a5o1yVkSgmPeS+dd5mwPmaF+kXHw9 -ULSDzOWsDeE+TxTytOR9v3Gkw5dzONZSfMikterpslRW1Ou4VzpAUlpeRiejezAt -CD2FHprwMqjyEKKDm+Io9p3LAgMBAAGjggEgMIIBHDASBgNVHRMBAf8ECDAGAQH/ -AgEAMH0GA1UdIAR2MHQwOAYLKwYEAYGtWgIFAwMwKTAnBggrBgEFBQcCARYbaHR0 -cDovL3d3dy5rZXluZWN0aXMuY29tL1BDMDgGCysGBAGBrVoCBQEDMCkwJwYIKwYB -BQUHAgEWG2h0dHA6Ly93d3cua2V5bmVjdGlzLmNvbS9QQzA3BgNVHR8EMDAuMCyg -KqAohiZodHRwOi8vd3d3LmNlcnRwbHVzLmNvbS9DUkwvY2xhc3MyLmNybDAOBgNV -HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFAARQd87nTvLuKLBM5KogczlfeeZMB8GA1Ud -IwQYMBaAFONzLd/LDigM3t2zpMp5uI676DCJMA0GCSqGSIb3DQEBBQUAA4IBAQAI -iP4fosrN4qDxLnxnSfvclKx/QQ14Abox95v7MRh3L2YllLhtFnSB8cCuZ8YURXoB -0ROI/OKNIh29HgzHqX7Qw5f2N1tBXmeUjqtpAhcY9U04wkkoCW5am6Yn28Bfj0Sc -kGWZ2LMuwZLuGp0PckUg+iwMnF3NW1RBVE/T4sdZhD8Xe30Owu9ix7qxJmyDTtMZ -xf9Wp7RFP3qe+tA5PoBGdV1aeXozxQG8AkTOG8AxTkeWFW7n5HbwwpANoXj0OACR -K2V8eROoPpEU3IgFCNdvU/YVQ+7FU1YaArWmokaNHhPkZ8JFX0BeEEJYtc1Eo5RM -HFSQTZGaJoutooBQjRQU ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert8[] = { - 0x30, 0x82, 0x04, 0x2b, 0x30, 0x82, 0x03, 0x13, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x12, 0x11, 0x20, 0x96, 0xf6, 0xc8, 0x03, 0x7c, 0x9e, 0x07, - 0xb1, 0x38, 0xbf, 0x2e, 0x72, 0x10, 0x8a, 0xd7, 0xed, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, - 0x30, 0x3d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x46, 0x52, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x08, 0x43, 0x65, 0x72, 0x74, 0x70, 0x6c, 0x75, 0x73, 0x31, 0x1b, - 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x43, 0x6c, 0x61, - 0x73, 0x73, 0x20, 0x32, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, - 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x37, 0x30, 0x36, 0x30, - 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x39, - 0x30, 0x36, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, - 0x40, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x09, 0x4b, 0x45, 0x59, 0x4e, 0x45, 0x43, 0x54, 0x49, 0x53, 0x31, 0x1d, - 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x43, 0x4c, 0x41, - 0x53, 0x53, 0x20, 0x32, 0x20, 0x4b, 0x45, 0x59, 0x4e, 0x45, 0x43, 0x54, - 0x49, 0x53, 0x20, 0x43, 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, 0xc6, 0xbe, 0xfe, 0x44, 0x23, 0x04, 0xd4, 0xef, 0x2f, 0x3b, - 0x86, 0xaa, 0x35, 0x58, 0x81, 0xd1, 0xe1, 0x9a, 0xd6, 0xb1, 0xd4, 0x27, - 0x45, 0x28, 0xfc, 0xd1, 0x1e, 0x46, 0x85, 0xba, 0x54, 0x23, 0x11, 0x7d, - 0xe0, 0x66, 0x3f, 0xd4, 0xa3, 0x57, 0x66, 0x78, 0xf9, 0x6b, 0xeb, 0x74, - 0x7c, 0x2a, 0xb8, 0x37, 0xa5, 0xe8, 0x70, 0xae, 0x82, 0xb5, 0x4e, 0xd4, - 0x81, 0xfe, 0x5b, 0xe2, 0xea, 0xe7, 0x22, 0x16, 0xf8, 0xf9, 0xd7, 0xba, - 0x3a, 0xf6, 0x88, 0x56, 0xdc, 0xc4, 0xf2, 0xa0, 0xa4, 0xe5, 0x75, 0x06, - 0x60, 0x72, 0x2b, 0xfb, 0xf5, 0x94, 0xee, 0x2c, 0x83, 0x28, 0xde, 0x91, - 0x9a, 0xb3, 0x83, 0x3a, 0xb0, 0x9f, 0x08, 0xfa, 0xdd, 0xd8, 0x9e, 0x8c, - 0x24, 0xe6, 0xdf, 0x66, 0x5b, 0xc8, 0x7e, 0xa3, 0x62, 0x4d, 0x3f, 0x3a, - 0x85, 0x23, 0xec, 0xe8, 0x71, 0x8f, 0x0a, 0x00, 0xac, 0x89, 0x6d, 0x7e, - 0xd8, 0x72, 0xe5, 0xdd, 0xc1, 0x94, 0x8e, 0x5f, 0xe4, 0x73, 0xe6, 0xc1, - 0xc6, 0x0c, 0x87, 0x58, 0x4f, 0x37, 0xda, 0xd1, 0xa9, 0x88, 0x26, 0x76, - 0xb4, 0xee, 0x11, 0x8d, 0xf6, 0xad, 0xb2, 0xa7, 0xbc, 0x73, 0xc4, 0xcd, - 0x1c, 0x6e, 0x1a, 0xe6, 0x8d, 0x72, 0x56, 0x44, 0xa0, 0x98, 0xf7, 0x92, - 0xf9, 0xd7, 0x79, 0x9b, 0x03, 0xe6, 0x68, 0x5f, 0xa4, 0x5c, 0x7c, 0x3d, - 0x50, 0xb4, 0x83, 0xcc, 0xe5, 0xac, 0x0d, 0xe1, 0x3e, 0x4f, 0x14, 0xf2, - 0xb4, 0xe4, 0x7d, 0xbf, 0x71, 0xa4, 0xc3, 0x97, 0x73, 0x38, 0xd6, 0x52, - 0x7c, 0xc8, 0xa4, 0xb5, 0xea, 0xe9, 0xb2, 0x54, 0x56, 0xd4, 0xeb, 0xb8, - 0x57, 0x3a, 0x40, 0x52, 0x5a, 0x5e, 0x46, 0x27, 0xa3, 0x7b, 0x30, 0x2d, - 0x08, 0x3d, 0x85, 0x1e, 0x9a, 0xf0, 0x32, 0xa8, 0xf2, 0x10, 0xa2, 0x83, - 0x9b, 0xe2, 0x28, 0xf6, 0x9d, 0xcb, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, - 0x82, 0x01, 0x20, 0x30, 0x82, 0x01, 0x1c, 0x30, 0x12, 0x06, 0x03, 0x55, - 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, - 0x02, 0x01, 0x00, 0x30, 0x7d, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x76, - 0x30, 0x74, 0x30, 0x38, 0x06, 0x0b, 0x2b, 0x06, 0x04, 0x01, 0x81, 0xad, - 0x5a, 0x02, 0x05, 0x03, 0x03, 0x30, 0x29, 0x30, 0x27, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1b, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6b, 0x65, 0x79, 0x6e, - 0x65, 0x63, 0x74, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x43, - 0x30, 0x38, 0x06, 0x0b, 0x2b, 0x06, 0x04, 0x01, 0x81, 0xad, 0x5a, 0x02, - 0x05, 0x01, 0x03, 0x30, 0x29, 0x30, 0x27, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1b, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6b, 0x65, 0x79, 0x6e, 0x65, 0x63, - 0x74, 0x69, 0x73, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x43, 0x30, 0x37, - 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x30, 0x30, 0x2e, 0x30, 0x2c, 0xa0, - 0x2a, 0xa0, 0x28, 0x86, 0x26, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x77, 0x77, 0x77, 0x2e, 0x63, 0x65, 0x72, 0x74, 0x70, 0x6c, 0x75, 0x73, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x52, 0x4c, 0x2f, 0x63, 0x6c, 0x61, - 0x73, 0x73, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, - 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, - 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x00, 0x11, - 0x41, 0xdf, 0x3b, 0x9d, 0x3b, 0xcb, 0xb8, 0xa2, 0xc1, 0x33, 0x92, 0xa8, - 0x81, 0xcc, 0xe5, 0x7d, 0xe7, 0x99, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, - 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe3, 0x73, 0x2d, 0xdf, 0xcb, - 0x0e, 0x28, 0x0c, 0xde, 0xdd, 0xb3, 0xa4, 0xca, 0x79, 0xb8, 0x8e, 0xbb, - 0xe8, 0x30, 0x89, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x08, - 0x88, 0xfe, 0x1f, 0xa2, 0xca, 0xcd, 0xe2, 0xa0, 0xf1, 0x2e, 0x7c, 0x67, - 0x49, 0xfb, 0xdc, 0x94, 0xac, 0x7f, 0x41, 0x0d, 0x78, 0x01, 0xba, 0x31, - 0xf7, 0x9b, 0xfb, 0x31, 0x18, 0x77, 0x2f, 0x66, 0x25, 0x94, 0xb8, 0x6d, - 0x16, 0x74, 0x81, 0xf1, 0xc0, 0xae, 0x67, 0xc6, 0x14, 0x45, 0x7a, 0x01, - 0xd1, 0x13, 0x88, 0xfc, 0xe2, 0x8d, 0x22, 0x1d, 0xbd, 0x1e, 0x0c, 0xc7, - 0xa9, 0x7e, 0xd0, 0xc3, 0x97, 0xf6, 0x37, 0x5b, 0x41, 0x5e, 0x67, 0x94, - 0x8e, 0xab, 0x69, 0x02, 0x17, 0x18, 0xf5, 0x4d, 0x38, 0xc2, 0x49, 0x28, - 0x09, 0x6e, 0x5a, 0x9b, 0xa6, 0x27, 0xdb, 0xc0, 0x5f, 0x8f, 0x44, 0x9c, - 0x90, 0x65, 0x99, 0xd8, 0xb3, 0x2e, 0xc1, 0x92, 0xee, 0x1a, 0x9d, 0x0f, - 0x72, 0x45, 0x20, 0xfa, 0x2c, 0x0c, 0x9c, 0x5d, 0xcd, 0x5b, 0x54, 0x41, - 0x54, 0x4f, 0xd3, 0xe2, 0xc7, 0x59, 0x84, 0x3f, 0x17, 0x7b, 0x7d, 0x0e, - 0xc2, 0xef, 0x62, 0xc7, 0xba, 0xb1, 0x26, 0x6c, 0x83, 0x4e, 0xd3, 0x19, - 0xc5, 0xff, 0x56, 0xa7, 0xb4, 0x45, 0x3f, 0x7a, 0x9e, 0xfa, 0xd0, 0x39, - 0x3e, 0x80, 0x46, 0x75, 0x5d, 0x5a, 0x79, 0x7a, 0x33, 0xc5, 0x01, 0xbc, - 0x02, 0x44, 0xce, 0x1b, 0xc0, 0x31, 0x4e, 0x47, 0x96, 0x15, 0x6e, 0xe7, - 0xe4, 0x76, 0xf0, 0xc2, 0x90, 0x0d, 0xa1, 0x78, 0xf4, 0x38, 0x00, 0x91, - 0x2b, 0x65, 0x7c, 0x79, 0x13, 0xa8, 0x3e, 0x91, 0x14, 0xdc, 0x88, 0x05, - 0x08, 0xd7, 0x6f, 0x53, 0xf6, 0x15, 0x43, 0xee, 0xc5, 0x53, 0x56, 0x1a, - 0x02, 0xb5, 0xa6, 0xa2, 0x46, 0x8d, 0x1e, 0x13, 0xe4, 0x67, 0xc2, 0x45, - 0x5f, 0x40, 0x5e, 0x10, 0x42, 0x58, 0xb5, 0xcd, 0x44, 0xa3, 0x94, 0x4c, - 0x1c, 0x54, 0x90, 0x4d, 0x91, 0x9a, 0x26, 0x8b, 0xad, 0xa2, 0x80, 0x50, - 0x8d, 0x14, 0x14, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 120031016 (0x7278728) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root - Validity - Not Before: May 8 16:04:33 2013 GMT - Not After : Jun 8 16:03:31 2020 GMT - Subject: C=JP, O=Cybertrust Japan Co., Ltd., CN=Cybertrust Japan Public CA G3 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:94:56:a3:45:44:54:aa:60:64:bf:b8:57:9f:4e: - db:d4:79:68:5f:13:05:f4:3f:cd:25:dd:3c:5e:58: - 77:1c:9d:e6:9f:e3:32:49:ef:02:3a:34:53:8d:52: - e5:e3:39:66:1f:e7:33:61:b6:27:c6:24:55:50:27: - 02:65:f0:b0:8c:41:8d:30:5e:47:5b:82:6f:c7:9c: - a3:28:43:6d:58:7b:c8:15:98:4e:25:6f:cb:76:27: - 5b:0b:2c:2c:b5:98:23:e7:8b:7c:fd:77:1a:c4:52: - ba:5d:19:ee:78:21:4d:21:9a:d9:12:7c:33:15:6b: - 1a:c9:81:ea:da:da:57:b7:d5:2f:ce:1f:4b:fc:b4: - 33:e0:a0:c9:94:27:bb:27:40:b6:90:db:ac:9e:75: - a6:11:2b:49:19:2d:c3:c2:43:07:09:bb:3d:6e:88: - a3:e3:8a:c5:d2:86:f6:65:5b:34:c3:9f:4c:02:e5: - 09:ba:2c:c6:76:66:eb:d1:76:25:f4:30:13:fb:58: - 60:a8:58:e3:51:6f:4b:08:04:61:8d:ac:a9:30:2f: - 52:41:a3:22:c1:33:59:ab:7b:59:f9:93:67:4b:c9: - 89:75:52:ef:29:49:34:93:1c:9c:93:73:9c:19:ce: - 5c:18:cd:4c:09:27:c1:3f:f5:49:ec:f4:e2:df:4b: - af:8f - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Certificate Policies: - Policy: 1.3.6.1.4.1.6334.1.0 - CPS: http://cybertrust.omniroot.com/repository.cfm - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Authority Key Identifier: - keyid:E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0 - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://cdp1.public-trust.com/CRL/Omniroot2025.crl - - X509v3 Subject Key Identifier: - 73:A8:08:53:29:B8:15:FB:99:80:E5:C5:37:D8:F8:39:7B:A4:13:06 - Signature Algorithm: sha1WithRSAEncryption - 04:39:ce:55:2c:db:4e:2b:a7:fe:fe:cc:54:cf:4d:29:f4:fd: - eb:27:c0:55:3a:62:3f:c9:e0:90:66:13:dd:69:c1:9e:c9:75: - 56:69:97:f7:a6:e8:22:ab:07:4e:d6:52:db:d6:5b:10:a8:29: - df:80:d1:64:2b:1d:8e:e8:af:6a:ef:4c:05:da:d1:80:4f:86: - 97:32:ab:b1:79:14:b8:0d:d7:6f:39:96:e3:b1:db:74:46:df: - 81:7e:40:b8:f9:5b:27:7b:5b:f8:2e:15:75:e9:a7:7a:fb:02: - 5f:9a:1b:08:84:7b:33:fb:f0:66:ba:73:ba:8f:04:d5:66:cc: - 88:c3:3e:ba:4b:d9:02:b2:37:60:87:4e:ad:ef:5a:c2:60:57: - 38:e3:a0:bd:1e:6a:ec:ff:c4:5a:c3:95:a5:5d:7a:7c:97:3f: - 6c:f0:68:73:80:ff:aa:29:a3:0c:07:8a:b8:0c:a5:05:ab:5e: - 0f:59:fc:61:15:2f:89:07:b0:15:c4:6f:7a:21:02:60:ce:18: - 23:ce:7d:b4:01:7c:69:46:19:e1:47:57:93:6f:5c:23:01:a5: - 7a:0c:13:b9:69:94:d4:f9:39:3c:41:ae:74:70:c5:90:40:b0: - d9:94:fe:0b:35:44:8d:54:23:53:16:78:b7:da:a8:cb:25:4b: - ca:8d:34:2c ------BEGIN CERTIFICATE----- -MIIENDCCAxygAwIBAgIEByeHKDANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ -RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD -VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTEzMDUwODE2MDQzM1oX -DTIwMDYwODE2MDMzMVowWjELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1 -c3QgSmFwYW4gQ28uLCBMdGQuMSYwJAYDVQQDEx1DeWJlcnRydXN0IEphcGFuIFB1 -YmxpYyBDQSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJRWo0VE -VKpgZL+4V59O29R5aF8TBfQ/zSXdPF5Ydxyd5p/jMknvAjo0U41S5eM5Zh/nM2G2 -J8YkVVAnAmXwsIxBjTBeR1uCb8ecoyhDbVh7yBWYTiVvy3YnWwssLLWYI+eLfP13 -GsRSul0Z7nghTSGa2RJ8MxVrGsmB6traV7fVL84fS/y0M+CgyZQnuydAtpDbrJ51 -phErSRktw8JDBwm7PW6Io+OKxdKG9mVbNMOfTALlCbosxnZm69F2JfQwE/tYYKhY -41FvSwgEYY2sqTAvUkGjIsEzWat7WfmTZ0vJiXVS7ylJNJMcnJNznBnOXBjNTAkn -wT/1Sez04t9Lr48CAwEAAaOCAQAwgf0wEgYDVR0TAQH/BAgwBgEB/wIBADBTBgNV -HSAETDBKMEgGCSsGAQQBsT4BADA7MDkGCCsGAQUFBwIBFi1odHRwOi8vY3liZXJ0 -cnVzdC5vbW5pcm9vdC5jb20vcmVwb3NpdG9yeS5jZm0wDgYDVR0PAQH/BAQDAgEG -MB8GA1UdIwQYMBaAFOWdWTCCR1jMrPoIVDaGezq1BE3wMEIGA1UdHwQ7MDkwN6A1 -oDOGMWh0dHA6Ly9jZHAxLnB1YmxpYy10cnVzdC5jb20vQ1JML09tbmlyb290MjAy -NS5jcmwwHQYDVR0OBBYEFHOoCFMpuBX7mYDlxTfY+Dl7pBMGMA0GCSqGSIb3DQEB -BQUAA4IBAQAEOc5VLNtOK6f+/sxUz00p9P3rJ8BVOmI/yeCQZhPdacGeyXVWaZf3 -pugiqwdO1lLb1lsQqCnfgNFkKx2O6K9q70wF2tGAT4aXMquxeRS4DddvOZbjsdt0 -Rt+BfkC4+Vsne1v4LhV16ad6+wJfmhsIhHsz+/BmunO6jwTVZsyIwz66S9kCsjdg -h06t71rCYFc446C9Hmrs/8Raw5WlXXp8lz9s8GhzgP+qKaMMB4q4DKUFq14PWfxh -FS+JB7AVxG96IQJgzhgjzn20AXxpRhnhR1eTb1wjAaV6DBO5aZTU+Tk8Qa50cMWQ -QLDZlP4LNUSNVCNTFni32qjLJUvKjTQs ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert9[] = { - 0x30, 0x82, 0x04, 0x34, 0x30, 0x82, 0x03, 0x1c, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x04, 0x07, 0x27, 0x87, 0x28, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5a, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49, - 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, - 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30, - 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65, - 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, - 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, - 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, - 0x30, 0x35, 0x30, 0x38, 0x31, 0x36, 0x30, 0x34, 0x33, 0x33, 0x5a, 0x17, - 0x0d, 0x32, 0x30, 0x30, 0x36, 0x30, 0x38, 0x31, 0x36, 0x30, 0x33, 0x33, - 0x31, 0x5a, 0x30, 0x5a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, - 0x06, 0x13, 0x02, 0x4a, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x1a, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x20, 0x4a, 0x61, 0x70, 0x61, 0x6e, 0x20, 0x43, 0x6f, 0x2e, - 0x2c, 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x1d, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, - 0x75, 0x73, 0x74, 0x20, 0x4a, 0x61, 0x70, 0x61, 0x6e, 0x20, 0x50, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x20, 0x43, 0x41, 0x20, 0x47, 0x33, 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, 0x94, 0x56, 0xa3, 0x45, 0x44, - 0x54, 0xaa, 0x60, 0x64, 0xbf, 0xb8, 0x57, 0x9f, 0x4e, 0xdb, 0xd4, 0x79, - 0x68, 0x5f, 0x13, 0x05, 0xf4, 0x3f, 0xcd, 0x25, 0xdd, 0x3c, 0x5e, 0x58, - 0x77, 0x1c, 0x9d, 0xe6, 0x9f, 0xe3, 0x32, 0x49, 0xef, 0x02, 0x3a, 0x34, - 0x53, 0x8d, 0x52, 0xe5, 0xe3, 0x39, 0x66, 0x1f, 0xe7, 0x33, 0x61, 0xb6, - 0x27, 0xc6, 0x24, 0x55, 0x50, 0x27, 0x02, 0x65, 0xf0, 0xb0, 0x8c, 0x41, - 0x8d, 0x30, 0x5e, 0x47, 0x5b, 0x82, 0x6f, 0xc7, 0x9c, 0xa3, 0x28, 0x43, - 0x6d, 0x58, 0x7b, 0xc8, 0x15, 0x98, 0x4e, 0x25, 0x6f, 0xcb, 0x76, 0x27, - 0x5b, 0x0b, 0x2c, 0x2c, 0xb5, 0x98, 0x23, 0xe7, 0x8b, 0x7c, 0xfd, 0x77, - 0x1a, 0xc4, 0x52, 0xba, 0x5d, 0x19, 0xee, 0x78, 0x21, 0x4d, 0x21, 0x9a, - 0xd9, 0x12, 0x7c, 0x33, 0x15, 0x6b, 0x1a, 0xc9, 0x81, 0xea, 0xda, 0xda, - 0x57, 0xb7, 0xd5, 0x2f, 0xce, 0x1f, 0x4b, 0xfc, 0xb4, 0x33, 0xe0, 0xa0, - 0xc9, 0x94, 0x27, 0xbb, 0x27, 0x40, 0xb6, 0x90, 0xdb, 0xac, 0x9e, 0x75, - 0xa6, 0x11, 0x2b, 0x49, 0x19, 0x2d, 0xc3, 0xc2, 0x43, 0x07, 0x09, 0xbb, - 0x3d, 0x6e, 0x88, 0xa3, 0xe3, 0x8a, 0xc5, 0xd2, 0x86, 0xf6, 0x65, 0x5b, - 0x34, 0xc3, 0x9f, 0x4c, 0x02, 0xe5, 0x09, 0xba, 0x2c, 0xc6, 0x76, 0x66, - 0xeb, 0xd1, 0x76, 0x25, 0xf4, 0x30, 0x13, 0xfb, 0x58, 0x60, 0xa8, 0x58, - 0xe3, 0x51, 0x6f, 0x4b, 0x08, 0x04, 0x61, 0x8d, 0xac, 0xa9, 0x30, 0x2f, - 0x52, 0x41, 0xa3, 0x22, 0xc1, 0x33, 0x59, 0xab, 0x7b, 0x59, 0xf9, 0x93, - 0x67, 0x4b, 0xc9, 0x89, 0x75, 0x52, 0xef, 0x29, 0x49, 0x34, 0x93, 0x1c, - 0x9c, 0x93, 0x73, 0x9c, 0x19, 0xce, 0x5c, 0x18, 0xcd, 0x4c, 0x09, 0x27, - 0xc1, 0x3f, 0xf5, 0x49, 0xec, 0xf4, 0xe2, 0xdf, 0x4b, 0xaf, 0x8f, 0x02, - 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x00, 0x30, 0x81, 0xfd, 0x30, - 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, - 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x53, 0x06, 0x03, 0x55, - 0x1d, 0x20, 0x04, 0x4c, 0x30, 0x4a, 0x30, 0x48, 0x06, 0x09, 0x2b, 0x06, - 0x01, 0x04, 0x01, 0xb1, 0x3e, 0x01, 0x00, 0x30, 0x3b, 0x30, 0x39, 0x06, - 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x2d, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x79, 0x62, 0x65, 0x72, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, - 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x63, 0x66, 0x6d, 0x30, 0x0e, 0x06, 0x03, - 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, - 0x14, 0xe5, 0x9d, 0x59, 0x30, 0x82, 0x47, 0x58, 0xcc, 0xac, 0xfa, 0x08, - 0x54, 0x36, 0x86, 0x7b, 0x3a, 0xb5, 0x04, 0x4d, 0xf0, 0x30, 0x42, 0x06, - 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3b, 0x30, 0x39, 0x30, 0x37, 0xa0, 0x35, - 0xa0, 0x33, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, - 0x64, 0x70, 0x31, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2d, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x52, 0x4c, - 0x2f, 0x4f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x32, 0x30, 0x32, - 0x35, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, - 0x04, 0x16, 0x04, 0x14, 0x73, 0xa8, 0x08, 0x53, 0x29, 0xb8, 0x15, 0xfb, - 0x99, 0x80, 0xe5, 0xc5, 0x37, 0xd8, 0xf8, 0x39, 0x7b, 0xa4, 0x13, 0x06, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x04, 0x39, 0xce, 0x55, - 0x2c, 0xdb, 0x4e, 0x2b, 0xa7, 0xfe, 0xfe, 0xcc, 0x54, 0xcf, 0x4d, 0x29, - 0xf4, 0xfd, 0xeb, 0x27, 0xc0, 0x55, 0x3a, 0x62, 0x3f, 0xc9, 0xe0, 0x90, - 0x66, 0x13, 0xdd, 0x69, 0xc1, 0x9e, 0xc9, 0x75, 0x56, 0x69, 0x97, 0xf7, - 0xa6, 0xe8, 0x22, 0xab, 0x07, 0x4e, 0xd6, 0x52, 0xdb, 0xd6, 0x5b, 0x10, - 0xa8, 0x29, 0xdf, 0x80, 0xd1, 0x64, 0x2b, 0x1d, 0x8e, 0xe8, 0xaf, 0x6a, - 0xef, 0x4c, 0x05, 0xda, 0xd1, 0x80, 0x4f, 0x86, 0x97, 0x32, 0xab, 0xb1, - 0x79, 0x14, 0xb8, 0x0d, 0xd7, 0x6f, 0x39, 0x96, 0xe3, 0xb1, 0xdb, 0x74, - 0x46, 0xdf, 0x81, 0x7e, 0x40, 0xb8, 0xf9, 0x5b, 0x27, 0x7b, 0x5b, 0xf8, - 0x2e, 0x15, 0x75, 0xe9, 0xa7, 0x7a, 0xfb, 0x02, 0x5f, 0x9a, 0x1b, 0x08, - 0x84, 0x7b, 0x33, 0xfb, 0xf0, 0x66, 0xba, 0x73, 0xba, 0x8f, 0x04, 0xd5, - 0x66, 0xcc, 0x88, 0xc3, 0x3e, 0xba, 0x4b, 0xd9, 0x02, 0xb2, 0x37, 0x60, - 0x87, 0x4e, 0xad, 0xef, 0x5a, 0xc2, 0x60, 0x57, 0x38, 0xe3, 0xa0, 0xbd, - 0x1e, 0x6a, 0xec, 0xff, 0xc4, 0x5a, 0xc3, 0x95, 0xa5, 0x5d, 0x7a, 0x7c, - 0x97, 0x3f, 0x6c, 0xf0, 0x68, 0x73, 0x80, 0xff, 0xaa, 0x29, 0xa3, 0x0c, - 0x07, 0x8a, 0xb8, 0x0c, 0xa5, 0x05, 0xab, 0x5e, 0x0f, 0x59, 0xfc, 0x61, - 0x15, 0x2f, 0x89, 0x07, 0xb0, 0x15, 0xc4, 0x6f, 0x7a, 0x21, 0x02, 0x60, - 0xce, 0x18, 0x23, 0xce, 0x7d, 0xb4, 0x01, 0x7c, 0x69, 0x46, 0x19, 0xe1, - 0x47, 0x57, 0x93, 0x6f, 0x5c, 0x23, 0x01, 0xa5, 0x7a, 0x0c, 0x13, 0xb9, - 0x69, 0x94, 0xd4, 0xf9, 0x39, 0x3c, 0x41, 0xae, 0x74, 0x70, 0xc5, 0x90, - 0x40, 0xb0, 0xd9, 0x94, 0xfe, 0x0b, 0x35, 0x44, 0x8d, 0x54, 0x23, 0x53, - 0x16, 0x78, 0xb7, 0xda, 0xa8, 0xcb, 0x25, 0x4b, 0xca, 0x8d, 0x34, 0x2c, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 120024505 (0x7276db9) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=GTE Corporation, OU=GTE CyberTrust Solutions, Inc., CN=GTE CyberTrust Global Root - Validity - Not Before: Nov 30 16:35:21 2010 GMT - Not After : Aug 10 15:34:26 2018 GMT - Subject: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:a3:04:bb:22:ab:98:3d:57:e8:26:72:9a:b5:79: - d4:29:e2:e1:e8:95:80:b1:b0:e3:5b:8e:2b:29:9a: - 64:df:a1:5d:ed:b0:09:05:6d:db:28:2e:ce:62:a2: - 62:fe:b4:88:da:12:eb:38:eb:21:9d:c0:41:2b:01: - 52:7b:88:77:d3:1c:8f:c7:ba:b9:88:b5:6a:09:e7: - 73:e8:11:40:a7:d1:cc:ca:62:8d:2d:e5:8f:0b:a6: - 50:d2:a8:50:c3:28:ea:f5:ab:25:87:8a:9a:96:1c: - a9:67:b8:3f:0c:d5:f7:f9:52:13:2f:c2:1b:d5:70: - 70:f0:8f:c0:12:ca:06:cb:9a:e1:d9:ca:33:7a:77: - d6:f8:ec:b9:f1:68:44:42:48:13:d2:c0:c2:a4:ae: - 5e:60:fe:b6:a6:05:fc:b4:dd:07:59:02:d4:59:18: - 98:63:f5:a5:63:e0:90:0c:7d:5d:b2:06:7a:f3:85: - ea:eb:d4:03:ae:5e:84:3e:5f:ff:15:ed:69:bc:f9: - 39:36:72:75:cf:77:52:4d:f3:c9:90:2c:b9:3d:e5: - c9:23:53:3f:1f:24:98:21:5c:07:99:29:bd:c6:3a: - ec:e7:6e:86:3a:6b:97:74:63:33:bd:68:18:31:f0: - 78:8d:76:bf:fc:9e:8e:5d:2a:86:a7:4d:90:dc:27: - 1a:39 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:3 - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: http://cybertrust.omniroot.com/repository.cfm - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Authority Key Identifier: - DirName:/C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Global Root - serial:01:A5 - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://www.public-trust.com/cgi-bin/CRL/2018/cdp.crl - - X509v3 Subject Key Identifier: - E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0 - Signature Algorithm: sha1WithRSAEncryption - 16:b4:2c:c9:f1:5e:e1:a2:7b:9b:78:20:7a:4a:70:70:86:19: - 00:b7:05:2a:e8:c9:25:39:0f:c3:64:3c:75:09:d9:89:15:80: - 07:c2:8d:bc:29:a5:64:50:cf:71:75:47:23:bd:4d:d8:7f:77: - 9a:51:10:6e:4e:1f:20:3c:47:9c:43:74:7f:96:84:10:4c:13: - 43:be:f8:e0:72:2e:ff:bf:ae:3c:0a:03:60:82:4b:6f:f9:9a: - c5:1e:f6:af:90:3b:9f:61:3b:3e:de:9b:05:1a:c6:2c:3c:57: - 21:08:0f:54:fa:28:63:6c:e8:1b:9c:0f:cf:dd:30:44:13:b9: - 57:fe ------BEGIN CERTIFICATE----- -MIIEODCCA6GgAwIBAgIEBydtuTANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV -UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU -cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds -b2JhbCBSb290MB4XDTEwMTEzMDE2MzUyMVoXDTE4MDgxMDE1MzQyNlowWjELMAkG -A1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVz -dDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKrmD1X6CZymrV51Cni4eiVgLGw41uO -KymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsBUnuId9Mcj8e6uYi1agnn -c+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/CG9VwcPCP -wBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPg -kAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFc -B5kpvcY67Oduhjprl3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaOCAWow -ggFmMBIGA1UdEwEB/wQIMAYBAf8CAQMwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYI -KwYBBQUHAgEWLWh0dHA6Ly9jeWJlcnRydXN0Lm9tbmlyb290LmNvbS9yZXBvc2l0 -b3J5LmNmbTAOBgNVHQ8BAf8EBAMCAQYwgYkGA1UdIwSBgTB/oXmkdzB1MQswCQYD -VQQGEwJVUzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUg -Q3liZXJUcnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRy -dXN0IEdsb2JhbCBSb290ggIBpTBFBgNVHR8EPjA8MDqgOKA2hjRodHRwOi8vd3d3 -LnB1YmxpYy10cnVzdC5jb20vY2dpLWJpbi9DUkwvMjAxOC9jZHAuY3JsMB0GA1Ud -DgQWBBTlnVkwgkdYzKz6CFQ2hns6tQRN8DANBgkqhkiG9w0BAQUFAAOBgQAWtCzJ -8V7honubeCB6SnBwhhkAtwUq6MklOQ/DZDx1CdmJFYAHwo28KaVkUM9xdUcjvU3Y -f3eaURBuTh8gPEecQ3R/loQQTBNDvvjgci7/v648CgNggktv+ZrFHvavkDufYTs+ -3psFGsYsPFchCA9U+ihjbOgbnA/P3TBEE7lX/g== ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert10[] = { - 0x30, 0x82, 0x04, 0x38, 0x30, 0x82, 0x03, 0xa1, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x04, 0x07, 0x27, 0x6d, 0xb9, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x75, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0f, - 0x47, 0x54, 0x45, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x13, 0x1e, 0x47, 0x54, 0x45, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, - 0x72, 0x75, 0x73, 0x74, 0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x23, 0x30, 0x21, - 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x47, 0x54, 0x45, 0x20, 0x43, - 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, - 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, - 0x0d, 0x31, 0x30, 0x31, 0x31, 0x33, 0x30, 0x31, 0x36, 0x33, 0x35, 0x32, - 0x31, 0x5a, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x38, 0x31, 0x30, 0x31, 0x35, - 0x33, 0x34, 0x32, 0x36, 0x5a, 0x30, 0x5a, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10, - 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, 0x42, 0x61, 0x6c, 0x74, 0x69, - 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, - 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, - 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, - 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x43, 0x79, - 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, - 0x74, 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, 0xa3, 0x04, - 0xbb, 0x22, 0xab, 0x98, 0x3d, 0x57, 0xe8, 0x26, 0x72, 0x9a, 0xb5, 0x79, - 0xd4, 0x29, 0xe2, 0xe1, 0xe8, 0x95, 0x80, 0xb1, 0xb0, 0xe3, 0x5b, 0x8e, - 0x2b, 0x29, 0x9a, 0x64, 0xdf, 0xa1, 0x5d, 0xed, 0xb0, 0x09, 0x05, 0x6d, - 0xdb, 0x28, 0x2e, 0xce, 0x62, 0xa2, 0x62, 0xfe, 0xb4, 0x88, 0xda, 0x12, - 0xeb, 0x38, 0xeb, 0x21, 0x9d, 0xc0, 0x41, 0x2b, 0x01, 0x52, 0x7b, 0x88, - 0x77, 0xd3, 0x1c, 0x8f, 0xc7, 0xba, 0xb9, 0x88, 0xb5, 0x6a, 0x09, 0xe7, - 0x73, 0xe8, 0x11, 0x40, 0xa7, 0xd1, 0xcc, 0xca, 0x62, 0x8d, 0x2d, 0xe5, - 0x8f, 0x0b, 0xa6, 0x50, 0xd2, 0xa8, 0x50, 0xc3, 0x28, 0xea, 0xf5, 0xab, - 0x25, 0x87, 0x8a, 0x9a, 0x96, 0x1c, 0xa9, 0x67, 0xb8, 0x3f, 0x0c, 0xd5, - 0xf7, 0xf9, 0x52, 0x13, 0x2f, 0xc2, 0x1b, 0xd5, 0x70, 0x70, 0xf0, 0x8f, - 0xc0, 0x12, 0xca, 0x06, 0xcb, 0x9a, 0xe1, 0xd9, 0xca, 0x33, 0x7a, 0x77, - 0xd6, 0xf8, 0xec, 0xb9, 0xf1, 0x68, 0x44, 0x42, 0x48, 0x13, 0xd2, 0xc0, - 0xc2, 0xa4, 0xae, 0x5e, 0x60, 0xfe, 0xb6, 0xa6, 0x05, 0xfc, 0xb4, 0xdd, - 0x07, 0x59, 0x02, 0xd4, 0x59, 0x18, 0x98, 0x63, 0xf5, 0xa5, 0x63, 0xe0, - 0x90, 0x0c, 0x7d, 0x5d, 0xb2, 0x06, 0x7a, 0xf3, 0x85, 0xea, 0xeb, 0xd4, - 0x03, 0xae, 0x5e, 0x84, 0x3e, 0x5f, 0xff, 0x15, 0xed, 0x69, 0xbc, 0xf9, - 0x39, 0x36, 0x72, 0x75, 0xcf, 0x77, 0x52, 0x4d, 0xf3, 0xc9, 0x90, 0x2c, - 0xb9, 0x3d, 0xe5, 0xc9, 0x23, 0x53, 0x3f, 0x1f, 0x24, 0x98, 0x21, 0x5c, - 0x07, 0x99, 0x29, 0xbd, 0xc6, 0x3a, 0xec, 0xe7, 0x6e, 0x86, 0x3a, 0x6b, - 0x97, 0x74, 0x63, 0x33, 0xbd, 0x68, 0x18, 0x31, 0xf0, 0x78, 0x8d, 0x76, - 0xbf, 0xfc, 0x9e, 0x8e, 0x5d, 0x2a, 0x86, 0xa7, 0x4d, 0x90, 0xdc, 0x27, - 0x1a, 0x39, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x6a, 0x30, - 0x82, 0x01, 0x66, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, - 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x03, 0x30, - 0x4e, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x47, 0x30, 0x45, 0x30, 0x43, - 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x2d, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, - 0x75, 0x73, 0x74, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x2e, 0x63, 0x66, 0x6d, 0x30, 0x0e, 0x06, 0x03, 0x55, - 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, - 0x81, 0x89, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0x81, 0x30, 0x7f, - 0xa1, 0x79, 0xa4, 0x77, 0x30, 0x75, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, - 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0f, 0x47, 0x54, 0x45, 0x20, 0x43, 0x6f, - 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x27, 0x30, - 0x25, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1e, 0x47, 0x54, 0x45, 0x20, - 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x53, - 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e, - 0x63, 0x2e, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, - 0x1a, 0x47, 0x54, 0x45, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, - 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, - 0x6f, 0x6f, 0x74, 0x82, 0x02, 0x01, 0xa5, 0x30, 0x45, 0x06, 0x03, 0x55, - 0x1d, 0x1f, 0x04, 0x3e, 0x30, 0x3c, 0x30, 0x3a, 0xa0, 0x38, 0xa0, 0x36, - 0x86, 0x34, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x67, 0x69, 0x2d, 0x62, 0x69, - 0x6e, 0x2f, 0x43, 0x52, 0x4c, 0x2f, 0x32, 0x30, 0x31, 0x38, 0x2f, 0x63, - 0x64, 0x70, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, - 0x0e, 0x04, 0x16, 0x04, 0x14, 0xe5, 0x9d, 0x59, 0x30, 0x82, 0x47, 0x58, - 0xcc, 0xac, 0xfa, 0x08, 0x54, 0x36, 0x86, 0x7b, 0x3a, 0xb5, 0x04, 0x4d, - 0xf0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x16, 0xb4, 0x2c, 0xc9, - 0xf1, 0x5e, 0xe1, 0xa2, 0x7b, 0x9b, 0x78, 0x20, 0x7a, 0x4a, 0x70, 0x70, - 0x86, 0x19, 0x00, 0xb7, 0x05, 0x2a, 0xe8, 0xc9, 0x25, 0x39, 0x0f, 0xc3, - 0x64, 0x3c, 0x75, 0x09, 0xd9, 0x89, 0x15, 0x80, 0x07, 0xc2, 0x8d, 0xbc, - 0x29, 0xa5, 0x64, 0x50, 0xcf, 0x71, 0x75, 0x47, 0x23, 0xbd, 0x4d, 0xd8, - 0x7f, 0x77, 0x9a, 0x51, 0x10, 0x6e, 0x4e, 0x1f, 0x20, 0x3c, 0x47, 0x9c, - 0x43, 0x74, 0x7f, 0x96, 0x84, 0x10, 0x4c, 0x13, 0x43, 0xbe, 0xf8, 0xe0, - 0x72, 0x2e, 0xff, 0xbf, 0xae, 0x3c, 0x0a, 0x03, 0x60, 0x82, 0x4b, 0x6f, - 0xf9, 0x9a, 0xc5, 0x1e, 0xf6, 0xaf, 0x90, 0x3b, 0x9f, 0x61, 0x3b, 0x3e, - 0xde, 0x9b, 0x05, 0x1a, 0xc6, 0x2c, 0x3c, 0x57, 0x21, 0x08, 0x0f, 0x54, - 0xfa, 0x28, 0x63, 0x6c, 0xe8, 0x1b, 0x9c, 0x0f, 0xcf, 0xdd, 0x30, 0x44, - 0x13, 0xb9, 0x57, 0xfe, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 48:4b:ac:f1:aa:c7:d7:13:43:d1:a2:74:35:49:97:25 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root - Validity - Not Before: Jun 7 08:09:10 2005 GMT - Not After : May 30 10:48:38 2020 GMT - Subject: C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network, OU=http://www.usertrust.com, CN=UTN-USERFirst-Hardware - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:b1:f7:c3:38:3f:b4:a8:7f:cf:39:82:51:67:d0: - 6d:9f:d2:ff:58:f3:e7:9f:2b:ec:0d:89:54:99:b9: - 38:99:16:f7:e0:21:79:48:c2:bb:61:74:12:96:1d: - 3c:6a:72:d5:3c:10:67:3a:39:ed:2b:13:cd:66:eb: - 95:09:33:a4:6c:97:b1:e8:c6:ec:c1:75:79:9c:46: - 5e:8d:ab:d0:6a:fd:b9:2a:55:17:10:54:b3:19:f0: - 9a:f6:f1:b1:5d:b6:a7:6d:fb:e0:71:17:6b:a2:88: - fb:00:df:fe:1a:31:77:0c:9a:01:7a:b1:32:e3:2b: - 01:07:38:6e:c3:a5:5e:23:bc:45:9b:7b:50:c1:c9: - 30:8f:db:e5:2b:7a:d3:5b:fb:33:40:1e:a0:d5:98: - 17:bc:8b:87:c3:89:d3:5d:a0:8e:b2:aa:aa:f6:8e: - 69:88:06:c5:fa:89:21:f3:08:9d:69:2e:09:33:9b: - 29:0d:46:0f:8c:cc:49:34:b0:69:51:bd:f9:06:cd: - 68:ad:66:4c:bc:3e:ac:61:bd:0a:88:0e:c8:df:3d: - ee:7c:04:4c:9d:0a:5e:6b:91:d6:ee:c7:ed:28:8d: - ab:4d:87:89:73:d0:6e:a4:d0:1e:16:8b:14:e1:76: - 44:03:7f:63:ac:e4:cd:49:9c:c5:92:f4:ab:32:a1: - 48:5b - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Authority Key Identifier: - keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A - - X509v3 Subject Key Identifier: - A1:72:5F:26:1B:28:98:43:95:5D:07:37:D5:85:96:9D:4B:D2:C3:45 - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.usertrust.com/AddTrustExternalCARoot.crl - - Signature Algorithm: sha1WithRSAEncryption - 3c:ec:7b:e0:ae:a3:0e:96:6d:30:d7:85:c6:d2:68:5b:45:5a: - 82:a6:34:0f:b0:c9:92:23:5e:11:6d:08:11:b2:74:09:23:3a: - 35:25:73:58:5e:ca:b9:7c:28:fa:47:ec:f9:a0:03:58:50:b6: - 53:ef:8c:db:39:e4:67:e9:d8:ca:28:46:d4:a7:e0:f5:38:75: - f8:e7:cb:5c:bf:1d:11:3c:6a:40:9b:2d:44:56:d3:f7:ff:05: - 28:32:0c:15:c8:64:45:93:e8:21:24:8f:2d:da:7a:84:7b:4f: - cf:cd:b2:25:7c:77:10:d3:94:d1:04:91:a8:25:1c:09:22:0f: - 7d:44:35:11:14:ef:af:00:fe:5e:ea:5f:8e:b0:d9:92:59:ba: - fc:13:96:a0:18:01:56:ce:da:f6:28:0b:b1:af:dd:5c:4f:5c: - b2:f3:8f:5a:71:cf:ed:18:ad:63:88:1d:8e:95:f7:ea:95:e7: - 1f:ad:90:b8:84:08:47:85:7f:22:2f:1a:1d:48:30:d6:4c:08: - d8:37:19:67:32:2b:eb:5c:d0:b2:fc:6e:57:9f:04:35:5e:90: - 00:7e:11:c7:de:13:2a:cd:a4:6d:45:26:c7:88:56:a0:f0:6a: - f7:d8:e7:fc:27:7e:67:08:d0:bd:fa:b6:c3:61:02:01:65:b9: - b8:2f:cf:5a ------BEGIN CERTIFICATE----- -MIIEPDCCAySgAwIBAgIQSEus8arH1xND0aJ0NUmXJTANBgkqhkiG9w0BAQUFADBv -MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk -ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF -eHRlcm5hbCBDQSBSb290MB4XDTA1MDYwNzA4MDkxMFoXDTIwMDUzMDEwNDgzOFow -gZcxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtl -IENpdHkxHjAcBgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMY -aHR0cDovL3d3dy51c2VydHJ1c3QuY29tMR8wHQYDVQQDExZVVE4tVVNFUkZpcnN0 -LUhhcmR3YXJlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsffDOD+0 -qH/POYJRZ9Btn9L/WPPnnyvsDYlUmbk4mRb34CF5SMK7YXQSlh08anLVPBBnOjnt -KxPNZuuVCTOkbJex6MbswXV5nEZejavQav25KlUXEFSzGfCa9vGxXbanbfvgcRdr -ooj7AN/+GjF3DJoBerEy4ysBBzhuw6VeI7xFm3tQwckwj9vlK3rTW/szQB6g1ZgX -vIuHw4nTXaCOsqqq9o5piAbF+okh8widaS4JM5spDUYPjMxJNLBpUb35Bs1orWZM -vD6sYb0KiA7I3z3ufARMnQpea5HW7sftKI2rTYeJc9BupNAeFosU4XZEA39jrOTN -SZzFkvSrMqFIWwIDAQABo4GqMIGnMB8GA1UdIwQYMBaAFK29mHo0tCb3+sQmVO8D -veAky1QaMB0GA1UdDgQWBBShcl8mGyiYQ5VdBzfVhZadS9LDRTAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8v -Y3JsLnVzZXJ0cnVzdC5jb20vQWRkVHJ1c3RFeHRlcm5hbENBUm9vdC5jcmwwDQYJ -KoZIhvcNAQEFBQADggEBADzse+Cuow6WbTDXhcbSaFtFWoKmNA+wyZIjXhFtCBGy -dAkjOjUlc1heyrl8KPpH7PmgA1hQtlPvjNs55Gfp2MooRtSn4PU4dfjny1y/HRE8 -akCbLURW0/f/BSgyDBXIZEWT6CEkjy3aeoR7T8/NsiV8dxDTlNEEkaglHAkiD31E -NREU768A/l7qX46w2ZJZuvwTlqAYAVbO2vYoC7Gv3VxPXLLzj1pxz+0YrWOIHY6V -9+qV5x+tkLiECEeFfyIvGh1IMNZMCNg3GWcyK+tc0LL8blefBDVekAB+EcfeEyrN -pG1FJseIVqDwavfY5/wnfmcI0L36tsNhAgFlubgvz1o= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert11[] = { - 0x30, 0x82, 0x04, 0x3c, 0x30, 0x82, 0x03, 0x24, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x48, 0x4b, 0xac, 0xf1, 0xaa, 0xc7, 0xd7, 0x13, 0x43, - 0xd1, 0xa2, 0x74, 0x35, 0x49, 0x97, 0x25, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x6f, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x53, - 0x45, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, - 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41, 0x42, 0x31, - 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x64, - 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x20, 0x54, 0x54, 0x50, 0x20, 0x4e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x19, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, - 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x52, - 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x35, 0x30, 0x36, 0x30, - 0x37, 0x30, 0x38, 0x30, 0x39, 0x31, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, - 0x30, 0x35, 0x33, 0x30, 0x31, 0x30, 0x34, 0x38, 0x33, 0x38, 0x5a, 0x30, - 0x81, 0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, - 0x13, 0x02, 0x55, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, - 0x07, 0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, 0x6b, 0x65, - 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, - 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, - 0x6b, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75, - 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, - 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x55, - 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74, - 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 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, 0xb1, 0xf7, 0xc3, 0x38, 0x3f, 0xb4, - 0xa8, 0x7f, 0xcf, 0x39, 0x82, 0x51, 0x67, 0xd0, 0x6d, 0x9f, 0xd2, 0xff, - 0x58, 0xf3, 0xe7, 0x9f, 0x2b, 0xec, 0x0d, 0x89, 0x54, 0x99, 0xb9, 0x38, - 0x99, 0x16, 0xf7, 0xe0, 0x21, 0x79, 0x48, 0xc2, 0xbb, 0x61, 0x74, 0x12, - 0x96, 0x1d, 0x3c, 0x6a, 0x72, 0xd5, 0x3c, 0x10, 0x67, 0x3a, 0x39, 0xed, - 0x2b, 0x13, 0xcd, 0x66, 0xeb, 0x95, 0x09, 0x33, 0xa4, 0x6c, 0x97, 0xb1, - 0xe8, 0xc6, 0xec, 0xc1, 0x75, 0x79, 0x9c, 0x46, 0x5e, 0x8d, 0xab, 0xd0, - 0x6a, 0xfd, 0xb9, 0x2a, 0x55, 0x17, 0x10, 0x54, 0xb3, 0x19, 0xf0, 0x9a, - 0xf6, 0xf1, 0xb1, 0x5d, 0xb6, 0xa7, 0x6d, 0xfb, 0xe0, 0x71, 0x17, 0x6b, - 0xa2, 0x88, 0xfb, 0x00, 0xdf, 0xfe, 0x1a, 0x31, 0x77, 0x0c, 0x9a, 0x01, - 0x7a, 0xb1, 0x32, 0xe3, 0x2b, 0x01, 0x07, 0x38, 0x6e, 0xc3, 0xa5, 0x5e, - 0x23, 0xbc, 0x45, 0x9b, 0x7b, 0x50, 0xc1, 0xc9, 0x30, 0x8f, 0xdb, 0xe5, - 0x2b, 0x7a, 0xd3, 0x5b, 0xfb, 0x33, 0x40, 0x1e, 0xa0, 0xd5, 0x98, 0x17, - 0xbc, 0x8b, 0x87, 0xc3, 0x89, 0xd3, 0x5d, 0xa0, 0x8e, 0xb2, 0xaa, 0xaa, - 0xf6, 0x8e, 0x69, 0x88, 0x06, 0xc5, 0xfa, 0x89, 0x21, 0xf3, 0x08, 0x9d, - 0x69, 0x2e, 0x09, 0x33, 0x9b, 0x29, 0x0d, 0x46, 0x0f, 0x8c, 0xcc, 0x49, - 0x34, 0xb0, 0x69, 0x51, 0xbd, 0xf9, 0x06, 0xcd, 0x68, 0xad, 0x66, 0x4c, - 0xbc, 0x3e, 0xac, 0x61, 0xbd, 0x0a, 0x88, 0x0e, 0xc8, 0xdf, 0x3d, 0xee, - 0x7c, 0x04, 0x4c, 0x9d, 0x0a, 0x5e, 0x6b, 0x91, 0xd6, 0xee, 0xc7, 0xed, - 0x28, 0x8d, 0xab, 0x4d, 0x87, 0x89, 0x73, 0xd0, 0x6e, 0xa4, 0xd0, 0x1e, - 0x16, 0x8b, 0x14, 0xe1, 0x76, 0x44, 0x03, 0x7f, 0x63, 0xac, 0xe4, 0xcd, - 0x49, 0x9c, 0xc5, 0x92, 0xf4, 0xab, 0x32, 0xa1, 0x48, 0x5b, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xa3, 0x81, 0xaa, 0x30, 0x81, 0xa7, 0x30, 0x1f, 0x06, - 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xad, 0xbd, - 0x98, 0x7a, 0x34, 0xb4, 0x26, 0xf7, 0xfa, 0xc4, 0x26, 0x54, 0xef, 0x03, - 0xbd, 0xe0, 0x24, 0xcb, 0x54, 0x1a, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, - 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa1, 0x72, 0x5f, 0x26, 0x1b, 0x28, 0x98, - 0x43, 0x95, 0x5d, 0x07, 0x37, 0xd5, 0x85, 0x96, 0x9d, 0x4b, 0xd2, 0xc3, - 0x45, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, - 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, - 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x44, - 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3d, 0x30, 0x3b, 0x30, 0x39, 0xa0, - 0x37, 0xa0, 0x35, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x63, 0x72, 0x6c, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, - 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x41, - 0x52, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, - 0x82, 0x01, 0x01, 0x00, 0x3c, 0xec, 0x7b, 0xe0, 0xae, 0xa3, 0x0e, 0x96, - 0x6d, 0x30, 0xd7, 0x85, 0xc6, 0xd2, 0x68, 0x5b, 0x45, 0x5a, 0x82, 0xa6, - 0x34, 0x0f, 0xb0, 0xc9, 0x92, 0x23, 0x5e, 0x11, 0x6d, 0x08, 0x11, 0xb2, - 0x74, 0x09, 0x23, 0x3a, 0x35, 0x25, 0x73, 0x58, 0x5e, 0xca, 0xb9, 0x7c, - 0x28, 0xfa, 0x47, 0xec, 0xf9, 0xa0, 0x03, 0x58, 0x50, 0xb6, 0x53, 0xef, - 0x8c, 0xdb, 0x39, 0xe4, 0x67, 0xe9, 0xd8, 0xca, 0x28, 0x46, 0xd4, 0xa7, - 0xe0, 0xf5, 0x38, 0x75, 0xf8, 0xe7, 0xcb, 0x5c, 0xbf, 0x1d, 0x11, 0x3c, - 0x6a, 0x40, 0x9b, 0x2d, 0x44, 0x56, 0xd3, 0xf7, 0xff, 0x05, 0x28, 0x32, - 0x0c, 0x15, 0xc8, 0x64, 0x45, 0x93, 0xe8, 0x21, 0x24, 0x8f, 0x2d, 0xda, - 0x7a, 0x84, 0x7b, 0x4f, 0xcf, 0xcd, 0xb2, 0x25, 0x7c, 0x77, 0x10, 0xd3, - 0x94, 0xd1, 0x04, 0x91, 0xa8, 0x25, 0x1c, 0x09, 0x22, 0x0f, 0x7d, 0x44, - 0x35, 0x11, 0x14, 0xef, 0xaf, 0x00, 0xfe, 0x5e, 0xea, 0x5f, 0x8e, 0xb0, - 0xd9, 0x92, 0x59, 0xba, 0xfc, 0x13, 0x96, 0xa0, 0x18, 0x01, 0x56, 0xce, - 0xda, 0xf6, 0x28, 0x0b, 0xb1, 0xaf, 0xdd, 0x5c, 0x4f, 0x5c, 0xb2, 0xf3, - 0x8f, 0x5a, 0x71, 0xcf, 0xed, 0x18, 0xad, 0x63, 0x88, 0x1d, 0x8e, 0x95, - 0xf7, 0xea, 0x95, 0xe7, 0x1f, 0xad, 0x90, 0xb8, 0x84, 0x08, 0x47, 0x85, - 0x7f, 0x22, 0x2f, 0x1a, 0x1d, 0x48, 0x30, 0xd6, 0x4c, 0x08, 0xd8, 0x37, - 0x19, 0x67, 0x32, 0x2b, 0xeb, 0x5c, 0xd0, 0xb2, 0xfc, 0x6e, 0x57, 0x9f, - 0x04, 0x35, 0x5e, 0x90, 0x00, 0x7e, 0x11, 0xc7, 0xde, 0x13, 0x2a, 0xcd, - 0xa4, 0x6d, 0x45, 0x26, 0xc7, 0x88, 0x56, 0xa0, 0xf0, 0x6a, 0xf7, 0xd8, - 0xe7, 0xfc, 0x27, 0x7e, 0x67, 0x08, 0xd0, 0xbd, 0xfa, 0xb6, 0xc3, 0x61, - 0x02, 0x01, 0x65, 0xb9, 0xb8, 0x2f, 0xcf, 0x5a, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 33:65:50:08:79:ad:73:e2:30:b9:e0:1d:0d:7f:ac:91 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com - Validity - Not Before: Nov 17 00:00:00 2006 GMT - Not After : Dec 30 23:59:59 2020 GMT - Subject: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:ac:a0:f0:fb:80:59:d4:9c:c7:a4:cf:9d:a1:59: - 73:09:10:45:0c:0d:2c:6e:68:f1:6c:5b:48:68:49: - 59:37:fc:0b:33:19:c2:77:7f:cc:10:2d:95:34:1c: - e6:eb:4d:09:a7:1c:d2:b8:c9:97:36:02:b7:89:d4: - 24:5f:06:c0:cc:44:94:94:8d:02:62:6f:eb:5a:dd: - 11:8d:28:9a:5c:84:90:10:7a:0d:bd:74:66:2f:6a: - 38:a0:e2:d5:54:44:eb:1d:07:9f:07:ba:6f:ee:e9: - fd:4e:0b:29:f5:3e:84:a0:01:f1:9c:ab:f8:1c:7e: - 89:a4:e8:a1:d8:71:65:0d:a3:51:7b:ee:bc:d2:22: - 60:0d:b9:5b:9d:df:ba:fc:51:5b:0b:af:98:b2:e9: - 2e:e9:04:e8:62:87:de:2b:c8:d7:4e:c1:4c:64:1e: - dd:cf:87:58:ba:4a:4f:ca:68:07:1d:1c:9d:4a:c6: - d5:2f:91:cc:7c:71:72:1c:c5:c0:67:eb:32:fd:c9: - 92:5c:94:da:85:c0:9b:bf:53:7d:2b:09:f4:8c:9d: - 91:1f:97:6a:52:cb:de:09:36:a4:77:d8:7b:87:50: - 44:d5:3e:6e:29:69:fb:39:49:26:1e:09:a5:80:7b: - 40:2d:eb:e8:27:85:c9:fe:61:fd:7e:e6:7c:97:1d: - d5:9d - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://www.thawte.com/cps - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Subject Key Identifier: - 7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50 - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.thawte.com/ThawtePremiumServerCA.crl - - Signature Algorithm: sha1WithRSAEncryption - 84:a8:4c:c9:3e:2a:bc:9a:e2:cc:8f:0b:b2:25:77:c4:61:89: - 89:63:5a:d4:a3:15:40:d4:fb:5e:3f:b4:43:ea:63:17:2b:6b: - 99:74:9e:09:a8:dd:d4:56:15:2e:7a:79:31:5f:63:96:53:1b: - 34:d9:15:ea:4f:6d:70:ca:be:f6:82:a9:ed:da:85:77:cc:76: - 1c:6a:81:0a:21:d8:41:99:7f:5e:2e:82:c1:e8:aa:f7:93:81: - 05:aa:92:b4:1f:b7:9a:c0:07:17:f5:cb:c6:b4:4c:0e:d7:56: - dc:71:20:74:38:d6:74:c6:d6:8f:6b:af:8b:8d:a0:6c:29:0b: - 61:e0 ------BEGIN CERTIFICATE----- -MIIERTCCA66gAwIBAgIQM2VQCHmtc+IwueAdDX+skTANBgkqhkiG9w0BAQUFADCB -zjELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJ -Q2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UE -CxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhh -d3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNl -cnZlckB0aGF3dGUuY29tMB4XDTA2MTExNzAwMDAwMFoXDTIwMTIzMDIzNTk1OVow -gakxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xKDAmBgNVBAsT -H0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24xODA2BgNVBAsTLyhjKSAy -MDA2IHRoYXd0ZSwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYD -VQQDExZ0aGF3dGUgUHJpbWFyeSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEArKDw+4BZ1JzHpM+doVlzCRBFDA0sbmjxbFtIaElZN/wLMxnC -d3/MEC2VNBzm600JpxzSuMmXNgK3idQkXwbAzESUlI0CYm/rWt0RjSiaXISQEHoN -vXRmL2o4oOLVVETrHQefB7pv7un9Tgsp9T6EoAHxnKv4HH6JpOih2HFlDaNRe+68 -0iJgDblbnd+6/FFbC6+Ysuku6QToYofeK8jXTsFMZB7dz4dYukpPymgHHRydSsbV -L5HMfHFyHMXAZ+sy/cmSXJTahcCbv1N9Kwn0jJ2RH5dqUsveCTakd9h7h1BE1T5u -KWn7OUkmHgmlgHtALevoJ4XJ/mH9fuZ8lx3VnQIDAQABo4HCMIG/MA8GA1UdEwEB -/wQFMAMBAf8wOwYDVR0gBDQwMjAwBgRVHSAAMCgwJgYIKwYBBQUHAgEWGmh0dHBz -Oi8vd3d3LnRoYXd0ZS5jb20vY3BzMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU -e1tFz6/Oy3r9MZIaarbzRutXSFAwQAYDVR0fBDkwNzA1oDOgMYYvaHR0cDovL2Ny -bC50aGF3dGUuY29tL1RoYXd0ZVByZW1pdW1TZXJ2ZXJDQS5jcmwwDQYJKoZIhvcN -AQEFBQADgYEAhKhMyT4qvJrizI8LsiV3xGGJiWNa1KMVQNT7Xj+0Q+pjFytrmXSe -Cajd1FYVLnp5MV9jllMbNNkV6k9tcMq+9oKp7dqFd8x2HGqBCiHYQZl/Xi6Cweiq -95OBBaqStB+3msAHF/XLxrRMDtdW3HEgdDjWdMbWj2uvi42gbCkLYeA= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert12[] = { - 0x30, 0x82, 0x04, 0x45, 0x30, 0x82, 0x03, 0xae, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x33, 0x65, 0x50, 0x08, 0x79, 0xad, 0x73, 0xe2, 0x30, - 0xb9, 0xe0, 0x1d, 0x0d, 0x7f, 0xac, 0x91, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, - 0xce, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x5a, 0x41, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x0c, 0x57, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x43, 0x61, 0x70, - 0x65, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, - 0x43, 0x61, 0x70, 0x65, 0x20, 0x54, 0x6f, 0x77, 0x6e, 0x31, 0x1d, 0x30, - 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x14, 0x54, 0x68, 0x61, 0x77, - 0x74, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x74, 0x69, 0x6e, - 0x67, 0x20, 0x63, 0x63, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, - 0x0b, 0x13, 0x1f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x20, 0x44, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x21, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x18, 0x54, 0x68, 0x61, - 0x77, 0x74, 0x65, 0x20, 0x50, 0x72, 0x65, 0x6d, 0x69, 0x75, 0x6d, 0x20, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x31, 0x28, 0x30, - 0x26, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, - 0x16, 0x19, 0x70, 0x72, 0x65, 0x6d, 0x69, 0x75, 0x6d, 0x2d, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x40, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, - 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x31, - 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, - 0x31, 0x32, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, - 0x81, 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, - 0x63, 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, - 0x1f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, - 0x44, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, - 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, - 0x30, 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, - 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, - 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, - 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, - 0x20, 0x43, 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, - 0xac, 0xa0, 0xf0, 0xfb, 0x80, 0x59, 0xd4, 0x9c, 0xc7, 0xa4, 0xcf, 0x9d, - 0xa1, 0x59, 0x73, 0x09, 0x10, 0x45, 0x0c, 0x0d, 0x2c, 0x6e, 0x68, 0xf1, - 0x6c, 0x5b, 0x48, 0x68, 0x49, 0x59, 0x37, 0xfc, 0x0b, 0x33, 0x19, 0xc2, - 0x77, 0x7f, 0xcc, 0x10, 0x2d, 0x95, 0x34, 0x1c, 0xe6, 0xeb, 0x4d, 0x09, - 0xa7, 0x1c, 0xd2, 0xb8, 0xc9, 0x97, 0x36, 0x02, 0xb7, 0x89, 0xd4, 0x24, - 0x5f, 0x06, 0xc0, 0xcc, 0x44, 0x94, 0x94, 0x8d, 0x02, 0x62, 0x6f, 0xeb, - 0x5a, 0xdd, 0x11, 0x8d, 0x28, 0x9a, 0x5c, 0x84, 0x90, 0x10, 0x7a, 0x0d, - 0xbd, 0x74, 0x66, 0x2f, 0x6a, 0x38, 0xa0, 0xe2, 0xd5, 0x54, 0x44, 0xeb, - 0x1d, 0x07, 0x9f, 0x07, 0xba, 0x6f, 0xee, 0xe9, 0xfd, 0x4e, 0x0b, 0x29, - 0xf5, 0x3e, 0x84, 0xa0, 0x01, 0xf1, 0x9c, 0xab, 0xf8, 0x1c, 0x7e, 0x89, - 0xa4, 0xe8, 0xa1, 0xd8, 0x71, 0x65, 0x0d, 0xa3, 0x51, 0x7b, 0xee, 0xbc, - 0xd2, 0x22, 0x60, 0x0d, 0xb9, 0x5b, 0x9d, 0xdf, 0xba, 0xfc, 0x51, 0x5b, - 0x0b, 0xaf, 0x98, 0xb2, 0xe9, 0x2e, 0xe9, 0x04, 0xe8, 0x62, 0x87, 0xde, - 0x2b, 0xc8, 0xd7, 0x4e, 0xc1, 0x4c, 0x64, 0x1e, 0xdd, 0xcf, 0x87, 0x58, - 0xba, 0x4a, 0x4f, 0xca, 0x68, 0x07, 0x1d, 0x1c, 0x9d, 0x4a, 0xc6, 0xd5, - 0x2f, 0x91, 0xcc, 0x7c, 0x71, 0x72, 0x1c, 0xc5, 0xc0, 0x67, 0xeb, 0x32, - 0xfd, 0xc9, 0x92, 0x5c, 0x94, 0xda, 0x85, 0xc0, 0x9b, 0xbf, 0x53, 0x7d, - 0x2b, 0x09, 0xf4, 0x8c, 0x9d, 0x91, 0x1f, 0x97, 0x6a, 0x52, 0xcb, 0xde, - 0x09, 0x36, 0xa4, 0x77, 0xd8, 0x7b, 0x87, 0x50, 0x44, 0xd5, 0x3e, 0x6e, - 0x29, 0x69, 0xfb, 0x39, 0x49, 0x26, 0x1e, 0x09, 0xa5, 0x80, 0x7b, 0x40, - 0x2d, 0xeb, 0xe8, 0x27, 0x85, 0xc9, 0xfe, 0x61, 0xfd, 0x7e, 0xe6, 0x7c, - 0x97, 0x1d, 0xd5, 0x9d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xc2, - 0x30, 0x81, 0xbf, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, - 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x3b, 0x06, 0x03, - 0x55, 0x1d, 0x20, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06, 0x04, 0x55, - 0x1d, 0x20, 0x00, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73, - 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, - 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0e, 0x06, - 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, - 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, - 0x7b, 0x5b, 0x45, 0xcf, 0xaf, 0xce, 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a, - 0x6a, 0xb6, 0xf3, 0x46, 0xeb, 0x57, 0x48, 0x50, 0x30, 0x40, 0x06, 0x03, - 0x55, 0x1d, 0x1f, 0x04, 0x39, 0x30, 0x37, 0x30, 0x35, 0xa0, 0x33, 0xa0, - 0x31, 0x86, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, - 0x6c, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, 0x72, 0x65, 0x6d, 0x69, - 0x75, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x41, 0x2e, 0x63, - 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x84, 0xa8, 0x4c, - 0xc9, 0x3e, 0x2a, 0xbc, 0x9a, 0xe2, 0xcc, 0x8f, 0x0b, 0xb2, 0x25, 0x77, - 0xc4, 0x61, 0x89, 0x89, 0x63, 0x5a, 0xd4, 0xa3, 0x15, 0x40, 0xd4, 0xfb, - 0x5e, 0x3f, 0xb4, 0x43, 0xea, 0x63, 0x17, 0x2b, 0x6b, 0x99, 0x74, 0x9e, - 0x09, 0xa8, 0xdd, 0xd4, 0x56, 0x15, 0x2e, 0x7a, 0x79, 0x31, 0x5f, 0x63, - 0x96, 0x53, 0x1b, 0x34, 0xd9, 0x15, 0xea, 0x4f, 0x6d, 0x70, 0xca, 0xbe, - 0xf6, 0x82, 0xa9, 0xed, 0xda, 0x85, 0x77, 0xcc, 0x76, 0x1c, 0x6a, 0x81, - 0x0a, 0x21, 0xd8, 0x41, 0x99, 0x7f, 0x5e, 0x2e, 0x82, 0xc1, 0xe8, 0xaa, - 0xf7, 0x93, 0x81, 0x05, 0xaa, 0x92, 0xb4, 0x1f, 0xb7, 0x9a, 0xc0, 0x07, - 0x17, 0xf5, 0xcb, 0xc6, 0xb4, 0x4c, 0x0e, 0xd7, 0x56, 0xdc, 0x71, 0x20, - 0x74, 0x38, 0xd6, 0x74, 0xc6, 0xd6, 0x8f, 0x6b, 0xaf, 0x8b, 0x8d, 0xa0, - 0x6c, 0x29, 0x0b, 0x61, 0xe0, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 120026506 (0x727758a) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root - Validity - Not Before: Jul 25 17:58:28 2012 GMT - Not After : Jul 25 17:57:44 2019 GMT - Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:c6:cc:e5:73:e6:fb:d4:bb:e5:2d:2d:32:a6:df: - e5:81:3f:c9:cd:25:49:b6:71:2a:c3:d5:94:34:67: - a2:0a:1c:b0:5f:69:a6:40:b1:c4:b7:b2:8f:d0:98: - a4:a9:41:59:3a:d3:dc:94:d6:3c:db:74:38:a4:4a: - cc:4d:25:82:f7:4a:a5:53:12:38:ee:f3:49:6d:71: - 91:7e:63:b6:ab:a6:5f:c3:a4:84:f8:4f:62:51:be: - f8:c5:ec:db:38:92:e3:06:e5:08:91:0c:c4:28:41: - 55:fb:cb:5a:89:15:7e:71:e8:35:bf:4d:72:09:3d: - be:3a:38:50:5b:77:31:1b:8d:b3:c7:24:45:9a:a7: - ac:6d:00:14:5a:04:b7:ba:13:eb:51:0a:98:41:41: - 22:4e:65:61:87:81:41:50:a6:79:5c:89:de:19:4a: - 57:d5:2e:e6:5d:1c:53:2c:7e:98:cd:1a:06:16:a4: - 68:73:d0:34:04:13:5c:a1:71:d3:5a:7c:55:db:5e: - 64:e1:37:87:30:56:04:e5:11:b4:29:80:12:f1:79: - 39:88:a2:02:11:7c:27:66:b7:88:b7:78:f2:ca:0a: - a8:38:ab:0a:64:c2:bf:66:5d:95:84:c1:a1:25:1e: - 87:5d:1a:50:0b:20:12:cc:41:bb:6e:0b:51:38:b8: - 4b:cb - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:1 - X509v3 Certificate Policies: - Policy: 1.3.6.1.4.1.6334.1.0 - CPS: http://cybertrust.omniroot.com/repository.cfm - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Authority Key Identifier: - keyid:E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0 - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://cdp1.public-trust.com/CRL/Omniroot2025.crl - - X509v3 Subject Key Identifier: - B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3 - Signature Algorithm: sha1WithRSAEncryption - 76:56:58:36:0d:19:98:b4:d9:a5:cb:30:75:ae:b1:d6:80:97: - cc:ee:38:72:68:39:b0:02:3e:46:b6:c4:f2:ac:d1:d2:e1:66: - 16:e6:85:a4:55:77:cb:2e:1c:59:dd:a5:4b:df:2f:33:bb:ce: - 60:57:27:3a:a1:4d:49:6f:55:76:6d:d5:d7:c2:a0:5b:2a:9b: - f9:4b:f7:7f:21:dd:ee:5c:57:0d:00:35:3a:f1:8c:46:cb:04: - f6:46:8f:ce:05:6a:d5:c4:6c:fe:6e:98:bf:a4:9c:bd:8e:89: - 2c:be:71:01:43:cc:36:2a:64:06:56:97:93:a5:47:bd:4a:3f: - 8c:1b:75:c8:9e:b0:f0:25:98:77:21:c0:76:a7:51:7a:24:25: - 7d:18:35:06:fe:c1:09:c5:0e:3b:99:a8:cd:9d:29:b0:3a:89: - f5:ea:e7:2a:e5:e2:24:4e:68:a9:1d:a7:dd:d2:08:4b:a1:d1: - 6f:0c:bd:2c:e0:bb:7c:fa:a1:3c:65:cf:3a:52:4b:d3:20:7a: - 0a:10:55:f8:ad:43:16:54:27:4e:53:73:c8:a3:96:89:d0:e1: - 79:c6:09:78:d5:f5:bd:b1:b3:c5:7f:a6:4b:af:49:11:c8:97: - 9c:4f:7c:70:69:16:5c:2d:b8:d0:df:1c:32:52:b9:de:f3:c3: - 06:e8:83:22 ------BEGIN CERTIFICATE----- -MIIERjCCAy6gAwIBAgIEByd1ijANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ -RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD -VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTEyMDcyNTE3NTgyOFoX -DTE5MDcyNTE3NTc0NFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0 -IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNl -cnQgSGlnaCBBc3N1cmFuY2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAMbM5XPm+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9p -pkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8Ok -hPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ck -RZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhak -aHPQNAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDir -CmTCv2ZdlYTBoSUeh10aUAsgEsxBu24LUTi4S8sCAwEAAaOCAQAwgf0wEgYDVR0T -AQH/BAgwBgEB/wIBATBTBgNVHSAETDBKMEgGCSsGAQQBsT4BADA7MDkGCCsGAQUF -BwIBFi1odHRwOi8vY3liZXJ0cnVzdC5vbW5pcm9vdC5jb20vcmVwb3NpdG9yeS5j -Zm0wDgYDVR0PAQH/BAQDAgEGMB8GA1UdIwQYMBaAFOWdWTCCR1jMrPoIVDaGezq1 -BE3wMEIGA1UdHwQ7MDkwN6A1oDOGMWh0dHA6Ly9jZHAxLnB1YmxpYy10cnVzdC5j -b20vQ1JML09tbmlyb290MjAyNS5jcmwwHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoI -Au9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQB2Vlg2DRmYtNmlyzB1rrHWgJfM7jhy -aDmwAj5GtsTyrNHS4WYW5oWkVXfLLhxZ3aVL3y8zu85gVyc6oU1Jb1V2bdXXwqBb -Kpv5S/d/Id3uXFcNADU68YxGywT2Ro/OBWrVxGz+bpi/pJy9joksvnEBQ8w2KmQG -VpeTpUe9Sj+MG3XInrDwJZh3IcB2p1F6JCV9GDUG/sEJxQ47majNnSmwOon16ucq -5eIkTmipHafd0ghLodFvDL0s4Lt8+qE8Zc86UkvTIHoKEFX4rUMWVCdOU3PIo5aJ -0OF5xgl41fW9sbPFf6ZLr0kRyJecT3xwaRZcLbjQ3xwyUrne88MG6IMi ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert13[] = { - 0x30, 0x82, 0x04, 0x46, 0x30, 0x82, 0x03, 0x2e, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x04, 0x07, 0x27, 0x75, 0x8a, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5a, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49, - 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, - 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30, - 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65, - 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, - 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, - 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, - 0x30, 0x37, 0x32, 0x35, 0x31, 0x37, 0x35, 0x38, 0x32, 0x38, 0x5a, 0x17, - 0x0d, 0x31, 0x39, 0x30, 0x37, 0x32, 0x35, 0x31, 0x37, 0x35, 0x37, 0x34, - 0x34, 0x5a, 0x30, 0x6c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, - 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x0c, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, - 0x20, 0x49, 0x6e, 0x63, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, - 0x0b, 0x13, 0x10, 0x77, 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, - 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x31, 0x2b, 0x30, 0x29, 0x06, - 0x03, 0x55, 0x04, 0x03, 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, - 0x72, 0x74, 0x20, 0x48, 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, - 0x72, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6f, 0x6f, - 0x74, 0x20, 0x43, 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, 0xc6, 0xcc, 0xe5, 0x73, 0xe6, 0xfb, 0xd4, 0xbb, 0xe5, 0x2d, 0x2d, - 0x32, 0xa6, 0xdf, 0xe5, 0x81, 0x3f, 0xc9, 0xcd, 0x25, 0x49, 0xb6, 0x71, - 0x2a, 0xc3, 0xd5, 0x94, 0x34, 0x67, 0xa2, 0x0a, 0x1c, 0xb0, 0x5f, 0x69, - 0xa6, 0x40, 0xb1, 0xc4, 0xb7, 0xb2, 0x8f, 0xd0, 0x98, 0xa4, 0xa9, 0x41, - 0x59, 0x3a, 0xd3, 0xdc, 0x94, 0xd6, 0x3c, 0xdb, 0x74, 0x38, 0xa4, 0x4a, - 0xcc, 0x4d, 0x25, 0x82, 0xf7, 0x4a, 0xa5, 0x53, 0x12, 0x38, 0xee, 0xf3, - 0x49, 0x6d, 0x71, 0x91, 0x7e, 0x63, 0xb6, 0xab, 0xa6, 0x5f, 0xc3, 0xa4, - 0x84, 0xf8, 0x4f, 0x62, 0x51, 0xbe, 0xf8, 0xc5, 0xec, 0xdb, 0x38, 0x92, - 0xe3, 0x06, 0xe5, 0x08, 0x91, 0x0c, 0xc4, 0x28, 0x41, 0x55, 0xfb, 0xcb, - 0x5a, 0x89, 0x15, 0x7e, 0x71, 0xe8, 0x35, 0xbf, 0x4d, 0x72, 0x09, 0x3d, - 0xbe, 0x3a, 0x38, 0x50, 0x5b, 0x77, 0x31, 0x1b, 0x8d, 0xb3, 0xc7, 0x24, - 0x45, 0x9a, 0xa7, 0xac, 0x6d, 0x00, 0x14, 0x5a, 0x04, 0xb7, 0xba, 0x13, - 0xeb, 0x51, 0x0a, 0x98, 0x41, 0x41, 0x22, 0x4e, 0x65, 0x61, 0x87, 0x81, - 0x41, 0x50, 0xa6, 0x79, 0x5c, 0x89, 0xde, 0x19, 0x4a, 0x57, 0xd5, 0x2e, - 0xe6, 0x5d, 0x1c, 0x53, 0x2c, 0x7e, 0x98, 0xcd, 0x1a, 0x06, 0x16, 0xa4, - 0x68, 0x73, 0xd0, 0x34, 0x04, 0x13, 0x5c, 0xa1, 0x71, 0xd3, 0x5a, 0x7c, - 0x55, 0xdb, 0x5e, 0x64, 0xe1, 0x37, 0x87, 0x30, 0x56, 0x04, 0xe5, 0x11, - 0xb4, 0x29, 0x80, 0x12, 0xf1, 0x79, 0x39, 0x88, 0xa2, 0x02, 0x11, 0x7c, - 0x27, 0x66, 0xb7, 0x88, 0xb7, 0x78, 0xf2, 0xca, 0x0a, 0xa8, 0x38, 0xab, - 0x0a, 0x64, 0xc2, 0xbf, 0x66, 0x5d, 0x95, 0x84, 0xc1, 0xa1, 0x25, 0x1e, - 0x87, 0x5d, 0x1a, 0x50, 0x0b, 0x20, 0x12, 0xcc, 0x41, 0xbb, 0x6e, 0x0b, - 0x51, 0x38, 0xb8, 0x4b, 0xcb, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, - 0x01, 0x00, 0x30, 0x81, 0xfd, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, - 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, - 0x01, 0x30, 0x53, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x4c, 0x30, 0x4a, - 0x30, 0x48, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb1, 0x3e, 0x01, - 0x00, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x02, 0x01, 0x16, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x63, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6f, - 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x63, - 0x66, 0x6d, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, - 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, - 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe5, 0x9d, 0x59, 0x30, 0x82, - 0x47, 0x58, 0xcc, 0xac, 0xfa, 0x08, 0x54, 0x36, 0x86, 0x7b, 0x3a, 0xb5, - 0x04, 0x4d, 0xf0, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3b, - 0x30, 0x39, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33, 0x86, 0x31, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x64, 0x70, 0x31, 0x2e, 0x70, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x43, 0x52, 0x4c, 0x2f, 0x4f, 0x6d, 0x6e, 0x69, 0x72, - 0x6f, 0x6f, 0x74, 0x32, 0x30, 0x32, 0x35, 0x2e, 0x63, 0x72, 0x6c, 0x30, - 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb1, 0x3e, - 0xc3, 0x69, 0x03, 0xf8, 0xbf, 0x47, 0x01, 0xd4, 0x98, 0x26, 0x1a, 0x08, - 0x02, 0xef, 0x63, 0x64, 0x2b, 0xc3, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, - 0x01, 0x00, 0x76, 0x56, 0x58, 0x36, 0x0d, 0x19, 0x98, 0xb4, 0xd9, 0xa5, - 0xcb, 0x30, 0x75, 0xae, 0xb1, 0xd6, 0x80, 0x97, 0xcc, 0xee, 0x38, 0x72, - 0x68, 0x39, 0xb0, 0x02, 0x3e, 0x46, 0xb6, 0xc4, 0xf2, 0xac, 0xd1, 0xd2, - 0xe1, 0x66, 0x16, 0xe6, 0x85, 0xa4, 0x55, 0x77, 0xcb, 0x2e, 0x1c, 0x59, - 0xdd, 0xa5, 0x4b, 0xdf, 0x2f, 0x33, 0xbb, 0xce, 0x60, 0x57, 0x27, 0x3a, - 0xa1, 0x4d, 0x49, 0x6f, 0x55, 0x76, 0x6d, 0xd5, 0xd7, 0xc2, 0xa0, 0x5b, - 0x2a, 0x9b, 0xf9, 0x4b, 0xf7, 0x7f, 0x21, 0xdd, 0xee, 0x5c, 0x57, 0x0d, - 0x00, 0x35, 0x3a, 0xf1, 0x8c, 0x46, 0xcb, 0x04, 0xf6, 0x46, 0x8f, 0xce, - 0x05, 0x6a, 0xd5, 0xc4, 0x6c, 0xfe, 0x6e, 0x98, 0xbf, 0xa4, 0x9c, 0xbd, - 0x8e, 0x89, 0x2c, 0xbe, 0x71, 0x01, 0x43, 0xcc, 0x36, 0x2a, 0x64, 0x06, - 0x56, 0x97, 0x93, 0xa5, 0x47, 0xbd, 0x4a, 0x3f, 0x8c, 0x1b, 0x75, 0xc8, - 0x9e, 0xb0, 0xf0, 0x25, 0x98, 0x77, 0x21, 0xc0, 0x76, 0xa7, 0x51, 0x7a, - 0x24, 0x25, 0x7d, 0x18, 0x35, 0x06, 0xfe, 0xc1, 0x09, 0xc5, 0x0e, 0x3b, - 0x99, 0xa8, 0xcd, 0x9d, 0x29, 0xb0, 0x3a, 0x89, 0xf5, 0xea, 0xe7, 0x2a, - 0xe5, 0xe2, 0x24, 0x4e, 0x68, 0xa9, 0x1d, 0xa7, 0xdd, 0xd2, 0x08, 0x4b, - 0xa1, 0xd1, 0x6f, 0x0c, 0xbd, 0x2c, 0xe0, 0xbb, 0x7c, 0xfa, 0xa1, 0x3c, - 0x65, 0xcf, 0x3a, 0x52, 0x4b, 0xd3, 0x20, 0x7a, 0x0a, 0x10, 0x55, 0xf8, - 0xad, 0x43, 0x16, 0x54, 0x27, 0x4e, 0x53, 0x73, 0xc8, 0xa3, 0x96, 0x89, - 0xd0, 0xe1, 0x79, 0xc6, 0x09, 0x78, 0xd5, 0xf5, 0xbd, 0xb1, 0xb3, 0xc5, - 0x7f, 0xa6, 0x4b, 0xaf, 0x49, 0x11, 0xc8, 0x97, 0x9c, 0x4f, 0x7c, 0x70, - 0x69, 0x16, 0x5c, 0x2d, 0xb8, 0xd0, 0xdf, 0x1c, 0x32, 0x52, 0xb9, 0xde, - 0xf3, 0xc3, 0x06, 0xe8, 0x83, 0x22, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 04:00:00:00:00:01:44:4e:f0:36:31 - Signature Algorithm: sha256WithRSAEncryption - Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA - Validity - Not Before: Feb 20 10:00:00 2014 GMT - Not After : Feb 20 10:00:00 2024 GMT - Subject: C=BE, O=GlobalSign nv-sa, CN=AlphaSSL CA - SHA256 - G2 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:da:01:ec:e4:ec:73:60:fb:7e:8f:6a:b7:c6:17: - e3:92:64:32:d4:ac:00:d9:a2:0f:b9:ed:ee:6b:8a: - 86:ca:92:67:d9:74:d7:5d:47:02:3c:8f:40:d6:9e: - 6d:14:cd:c3:da:29:39:a7:0f:05:0a:68:a2:66:1a: - 1e:c4:b2:8b:76:58:e5:ab:5d:1d:8f:40:b3:39:8b: - ef:1e:83:7d:22:d0:e3:a9:00:2e:ec:53:cf:62:19: - 85:44:28:4c:c0:27:cb:7b:0e:ec:10:64:00:10:a4: - 05:cc:a0:72:be:41:6c:31:5b:48:e4:b1:ec:b9:23: - eb:55:4d:d0:7d:62:4a:a5:b4:a5:a4:59:85:c5:25: - 91:a6:fe:a6:09:9f:06:10:6d:8f:81:0c:64:40:5e: - 73:00:9a:e0:2e:65:98:54:10:00:70:98:c8:e1:ed: - 34:5f:d8:9c:c7:0d:c0:d6:23:59:45:fc:fe:55:7a: - 86:ee:94:60:22:f1:ae:d1:e6:55:46:f6:99:c5:1b: - 08:74:5f:ac:b0:64:84:8f:89:38:1c:a1:a7:90:21: - 4f:02:6e:bd:e0:61:67:d4:f8:42:87:0f:0a:f7:c9: - 04:6d:2a:a9:2f:ef:42:a5:df:dd:a3:53:db:98:1e: - 81:f9:9a:72:7b:5a:de:4f:3e:7f:a2:58:a0:e2:17: - ad:67 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Subject Key Identifier: - F5:CD:D5:3C:08:50:F9:6A:4F:3A:B7:97:DA:56:83:E6:69:D2:68:F7 - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://www.alphassl.com/repository/ - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.globalsign.net/root.crl - - Authority Information Access: - OCSP - URI:http://ocsp.globalsign.com/rootr1 - - X509v3 Authority Key Identifier: - keyid:60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B - - Signature Algorithm: sha256WithRSAEncryption - 60:40:68:16:47:e7:16:8d:db:5c:a1:56:2a:cb:f4:5c:9b:b0: - 1e:a2:4b:f5:cb:02:3f:f8:0b:a1:f2:a7:42:d4:b7:4c:eb:e3: - 66:80:f3:25:43:78:2e:1b:17:56:07:52:18:cb:d1:a8:ec:e6: - fb:73:3e:a4:62:8c:80:b4:d2:c5:12:73:a3:d3:fa:02:38:be: - 63:3d:84:b8:99:c1:f1:ba:f7:9f:c3:40:d1:58:18:53:c1:62: - dd:af:18:42:7f:34:4e:c5:43:d5:71:b0:30:00:c7:e3:90:ae: - 3f:57:86:97:ce:ea:0c:12:8e:22:70:e3:66:a7:54:7f:2e:28: - cb:d4:54:d0:b3:1e:62:67:08:f9:27:e1:cb:e3:66:b8:24:1b: - 89:6a:89:44:65:f2:d9:4c:d2:58:1c:8c:4e:c0:95:a1:d4:ef: - 67:2f:38:20:e8:2e:ff:96:51:f0:ba:d8:3d:92:70:47:65:1c: - 9e:73:72:b4:60:0c:5c:e2:d1:73:76:e0:af:4e:e2:e5:37:a5: - 45:2f:8a:23:3e:87:c7:30:e6:31:38:7c:f4:dd:52:ca:f3:53: - 04:25:57:56:66:94:e8:0b:ee:e6:03:14:4e:ee:fd:6d:94:64: - 9e:5e:ce:79:d4:b2:a6:cf:40:b1:44:a8:3e:87:19:5e:e9:f8: - 21:16:59:53 ------BEGIN CERTIFICATE----- -MIIETTCCAzWgAwIBAgILBAAAAAABRE7wNjEwDQYJKoZIhvcNAQELBQAwVzELMAkG -A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv -b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xNDAyMjAxMDAw -MDBaFw0yNDAyMjAxMDAwMDBaMEwxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i -YWxTaWduIG52LXNhMSIwIAYDVQQDExlBbHBoYVNTTCBDQSAtIFNIQTI1NiAtIEcy -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2gHs5OxzYPt+j2q3xhfj -kmQy1KwA2aIPue3ua4qGypJn2XTXXUcCPI9A1p5tFM3D2ik5pw8FCmiiZhoexLKL -dljlq10dj0CzOYvvHoN9ItDjqQAu7FPPYhmFRChMwCfLew7sEGQAEKQFzKByvkFs -MVtI5LHsuSPrVU3QfWJKpbSlpFmFxSWRpv6mCZ8GEG2PgQxkQF5zAJrgLmWYVBAA -cJjI4e00X9icxw3A1iNZRfz+VXqG7pRgIvGu0eZVRvaZxRsIdF+ssGSEj4k4HKGn -kCFPAm694GFn1PhChw8K98kEbSqpL+9Cpd/do1PbmB6B+Zpye1reTz5/olig4het -ZwIDAQABo4IBIzCCAR8wDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8C -AQAwHQYDVR0OBBYEFPXN1TwIUPlqTzq3l9pWg+Zp0mj3MEUGA1UdIAQ+MDwwOgYE -VR0gADAyMDAGCCsGAQUFBwIBFiRodHRwczovL3d3dy5hbHBoYXNzbC5jb20vcmVw -b3NpdG9yeS8wMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nbG9iYWxzaWdu -Lm5ldC9yb290LmNybDA9BggrBgEFBQcBAQQxMC8wLQYIKwYBBQUHMAGGIWh0dHA6 -Ly9vY3NwLmdsb2JhbHNpZ24uY29tL3Jvb3RyMTAfBgNVHSMEGDAWgBRge2YaRQ2X -yolQL30EzTSo//z9SzANBgkqhkiG9w0BAQsFAAOCAQEAYEBoFkfnFo3bXKFWKsv0 -XJuwHqJL9csCP/gLofKnQtS3TOvjZoDzJUN4LhsXVgdSGMvRqOzm+3M+pGKMgLTS -xRJzo9P6Aji+Yz2EuJnB8br3n8NA0VgYU8Fi3a8YQn80TsVD1XGwMADH45CuP1eG -l87qDBKOInDjZqdUfy4oy9RU0LMeYmcI+Sfhy+NmuCQbiWqJRGXy2UzSWByMTsCV -odTvZy84IOgu/5ZR8LrYPZJwR2UcnnNytGAMXOLRc3bgr07i5TelRS+KIz6HxzDm -MTh89N1SyvNTBCVXVmaU6Avu5gMUTu79bZRknl7OedSyps9AsUSoPocZXun4IRZZ -Uw== ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert14[] = { - 0x30, 0x82, 0x04, 0x4d, 0x30, 0x82, 0x03, 0x35, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0x4e, 0xf0, - 0x36, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x57, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, - 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, - 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, - 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x07, 0x52, 0x6f, - 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, - 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, - 0x17, 0x0d, 0x31, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x4c, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, - 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, - 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, - 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x41, - 0x6c, 0x70, 0x68, 0x61, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, - 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, 0x47, 0x32, - 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, 0xda, 0x01, 0xec, - 0xe4, 0xec, 0x73, 0x60, 0xfb, 0x7e, 0x8f, 0x6a, 0xb7, 0xc6, 0x17, 0xe3, - 0x92, 0x64, 0x32, 0xd4, 0xac, 0x00, 0xd9, 0xa2, 0x0f, 0xb9, 0xed, 0xee, - 0x6b, 0x8a, 0x86, 0xca, 0x92, 0x67, 0xd9, 0x74, 0xd7, 0x5d, 0x47, 0x02, - 0x3c, 0x8f, 0x40, 0xd6, 0x9e, 0x6d, 0x14, 0xcd, 0xc3, 0xda, 0x29, 0x39, - 0xa7, 0x0f, 0x05, 0x0a, 0x68, 0xa2, 0x66, 0x1a, 0x1e, 0xc4, 0xb2, 0x8b, - 0x76, 0x58, 0xe5, 0xab, 0x5d, 0x1d, 0x8f, 0x40, 0xb3, 0x39, 0x8b, 0xef, - 0x1e, 0x83, 0x7d, 0x22, 0xd0, 0xe3, 0xa9, 0x00, 0x2e, 0xec, 0x53, 0xcf, - 0x62, 0x19, 0x85, 0x44, 0x28, 0x4c, 0xc0, 0x27, 0xcb, 0x7b, 0x0e, 0xec, - 0x10, 0x64, 0x00, 0x10, 0xa4, 0x05, 0xcc, 0xa0, 0x72, 0xbe, 0x41, 0x6c, - 0x31, 0x5b, 0x48, 0xe4, 0xb1, 0xec, 0xb9, 0x23, 0xeb, 0x55, 0x4d, 0xd0, - 0x7d, 0x62, 0x4a, 0xa5, 0xb4, 0xa5, 0xa4, 0x59, 0x85, 0xc5, 0x25, 0x91, - 0xa6, 0xfe, 0xa6, 0x09, 0x9f, 0x06, 0x10, 0x6d, 0x8f, 0x81, 0x0c, 0x64, - 0x40, 0x5e, 0x73, 0x00, 0x9a, 0xe0, 0x2e, 0x65, 0x98, 0x54, 0x10, 0x00, - 0x70, 0x98, 0xc8, 0xe1, 0xed, 0x34, 0x5f, 0xd8, 0x9c, 0xc7, 0x0d, 0xc0, - 0xd6, 0x23, 0x59, 0x45, 0xfc, 0xfe, 0x55, 0x7a, 0x86, 0xee, 0x94, 0x60, - 0x22, 0xf1, 0xae, 0xd1, 0xe6, 0x55, 0x46, 0xf6, 0x99, 0xc5, 0x1b, 0x08, - 0x74, 0x5f, 0xac, 0xb0, 0x64, 0x84, 0x8f, 0x89, 0x38, 0x1c, 0xa1, 0xa7, - 0x90, 0x21, 0x4f, 0x02, 0x6e, 0xbd, 0xe0, 0x61, 0x67, 0xd4, 0xf8, 0x42, - 0x87, 0x0f, 0x0a, 0xf7, 0xc9, 0x04, 0x6d, 0x2a, 0xa9, 0x2f, 0xef, 0x42, - 0xa5, 0xdf, 0xdd, 0xa3, 0x53, 0xdb, 0x98, 0x1e, 0x81, 0xf9, 0x9a, 0x72, - 0x7b, 0x5a, 0xde, 0x4f, 0x3e, 0x7f, 0xa2, 0x58, 0xa0, 0xe2, 0x17, 0xad, - 0x67, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x23, 0x30, 0x82, - 0x01, 0x1f, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, - 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, - 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, - 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, - 0x14, 0xf5, 0xcd, 0xd5, 0x3c, 0x08, 0x50, 0xf9, 0x6a, 0x4f, 0x3a, 0xb7, - 0x97, 0xda, 0x56, 0x83, 0xe6, 0x69, 0xd2, 0x68, 0xf7, 0x30, 0x45, 0x06, - 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3e, 0x30, 0x3c, 0x30, 0x3a, 0x06, 0x04, - 0x55, 0x1d, 0x20, 0x00, 0x30, 0x32, 0x30, 0x30, 0x06, 0x08, 0x2b, 0x06, - 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x24, 0x68, 0x74, 0x74, 0x70, - 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x6c, 0x70, 0x68, - 0x61, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x30, 0x33, 0x06, 0x03, - 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, - 0x24, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, - 0x6c, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, - 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, - 0x6c, 0x30, 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, - 0x01, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, - 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, - 0x6f, 0x74, 0x72, 0x31, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, - 0x18, 0x30, 0x16, 0x80, 0x14, 0x60, 0x7b, 0x66, 0x1a, 0x45, 0x0d, 0x97, - 0xca, 0x89, 0x50, 0x2f, 0x7d, 0x04, 0xcd, 0x34, 0xa8, 0xff, 0xfc, 0xfd, - 0x4b, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x60, 0x40, 0x68, - 0x16, 0x47, 0xe7, 0x16, 0x8d, 0xdb, 0x5c, 0xa1, 0x56, 0x2a, 0xcb, 0xf4, - 0x5c, 0x9b, 0xb0, 0x1e, 0xa2, 0x4b, 0xf5, 0xcb, 0x02, 0x3f, 0xf8, 0x0b, - 0xa1, 0xf2, 0xa7, 0x42, 0xd4, 0xb7, 0x4c, 0xeb, 0xe3, 0x66, 0x80, 0xf3, - 0x25, 0x43, 0x78, 0x2e, 0x1b, 0x17, 0x56, 0x07, 0x52, 0x18, 0xcb, 0xd1, - 0xa8, 0xec, 0xe6, 0xfb, 0x73, 0x3e, 0xa4, 0x62, 0x8c, 0x80, 0xb4, 0xd2, - 0xc5, 0x12, 0x73, 0xa3, 0xd3, 0xfa, 0x02, 0x38, 0xbe, 0x63, 0x3d, 0x84, - 0xb8, 0x99, 0xc1, 0xf1, 0xba, 0xf7, 0x9f, 0xc3, 0x40, 0xd1, 0x58, 0x18, - 0x53, 0xc1, 0x62, 0xdd, 0xaf, 0x18, 0x42, 0x7f, 0x34, 0x4e, 0xc5, 0x43, - 0xd5, 0x71, 0xb0, 0x30, 0x00, 0xc7, 0xe3, 0x90, 0xae, 0x3f, 0x57, 0x86, - 0x97, 0xce, 0xea, 0x0c, 0x12, 0x8e, 0x22, 0x70, 0xe3, 0x66, 0xa7, 0x54, - 0x7f, 0x2e, 0x28, 0xcb, 0xd4, 0x54, 0xd0, 0xb3, 0x1e, 0x62, 0x67, 0x08, - 0xf9, 0x27, 0xe1, 0xcb, 0xe3, 0x66, 0xb8, 0x24, 0x1b, 0x89, 0x6a, 0x89, - 0x44, 0x65, 0xf2, 0xd9, 0x4c, 0xd2, 0x58, 0x1c, 0x8c, 0x4e, 0xc0, 0x95, - 0xa1, 0xd4, 0xef, 0x67, 0x2f, 0x38, 0x20, 0xe8, 0x2e, 0xff, 0x96, 0x51, - 0xf0, 0xba, 0xd8, 0x3d, 0x92, 0x70, 0x47, 0x65, 0x1c, 0x9e, 0x73, 0x72, - 0xb4, 0x60, 0x0c, 0x5c, 0xe2, 0xd1, 0x73, 0x76, 0xe0, 0xaf, 0x4e, 0xe2, - 0xe5, 0x37, 0xa5, 0x45, 0x2f, 0x8a, 0x23, 0x3e, 0x87, 0xc7, 0x30, 0xe6, - 0x31, 0x38, 0x7c, 0xf4, 0xdd, 0x52, 0xca, 0xf3, 0x53, 0x04, 0x25, 0x57, - 0x56, 0x66, 0x94, 0xe8, 0x0b, 0xee, 0xe6, 0x03, 0x14, 0x4e, 0xee, 0xfd, - 0x6d, 0x94, 0x64, 0x9e, 0x5e, 0xce, 0x79, 0xd4, 0xb2, 0xa6, 0xcf, 0x40, - 0xb1, 0x44, 0xa8, 0x3e, 0x87, 0x19, 0x5e, 0xe9, 0xf8, 0x21, 0x16, 0x59, - 0x53, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 146031 (0x23a6f) - Signature Algorithm: sha256WithRSAEncryption - Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA - Validity - Not Before: Nov 5 21:36:50 2013 GMT - Not After : May 20 21:36:50 2022 GMT - Subject: C=US, O=GeoTrust Inc., CN=GeoTrust SSL CA - G3 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:e3:be:7e:0a:86:a3:cf:6b:6d:3d:2b:a1:97:ad: - 49:24:4d:d7:77:b9:34:79:08:a5:9e:a2:9e:de:47: - 12:92:3d:7e:ea:19:86:b1:e8:4f:3d:5f:f7:d0:a7: - 77:9a:5b:1f:0a:03:b5:19:53:db:a5:21:94:69:63: - 9d:6a:4c:91:0c:10:47:be:11:fa:6c:86:25:b7:ab: - 04:68:42:38:09:65:f0:14:da:19:9e:fa:6b:0b:ab: - 62:ef:8d:a7:ef:63:70:23:a8:af:81:f3:d1:6e:88: - 67:53:ec:12:a4:29:75:8a:a7:f2:57:3d:a2:83:98: - 97:f2:0a:7d:d4:e7:43:6e:30:78:62:22:59:59:b8: - 71:27:45:aa:0f:66:c6:55:3f:fa:32:17:2b:31:8f: - 46:a0:fa:69:14:7c:9d:9f:5a:e2:eb:33:4e:10:a6: - b3:ed:77:63:d8:c3:9e:f4:dd:df:79:9a:7a:d4:ee: - de:dd:9a:cc:c3:b7:a9:5d:cc:11:3a:07:bb:6f:97: - a4:01:23:47:95:1f:a3:77:fa:58:92:c6:c7:d0:bd: - cf:93:18:42:b7:7e:f7:9e:65:ea:d5:3b:ca:ed:ac: - c5:70:a1:fe:d4:10:9a:f0:12:04:44:ac:1a:5b:78: - 50:45:57:4c:6f:bd:80:cb:81:5c:2d:b3:bc:76:a1: - 1e:65 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Authority Key Identifier: - keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E - - X509v3 Subject Key Identifier: - D2:6F:F7:96:F4:85:3F:72:3C:30:7D:23:DA:85:78:9B:A3:7C:5A:7C - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 CRL Distribution Points: - - Full Name: - URI:http://g1.symcb.com/crls/gtglobal.crl - - Authority Information Access: - OCSP - URI:http://g2.symcb.com - - X509v3 Certificate Policies: - Policy: 2.16.840.1.113733.1.7.54 - CPS: http://www.geotrust.com/resources/cps - - X509v3 Subject Alternative Name: - DirName:/CN=SymantecPKI-1-539 - Signature Algorithm: sha256WithRSAEncryption - a0:d4:f7:2c:fb:74:0b:7f:64:f1:cd:43:6a:9f:62:53:1c:02: - 7c:98:90:a2:ee:4f:68:d4:20:1a:73:12:3e:77:b3:50:eb:72: - bc:ee:88:be:7f:17:ea:77:8f:83:61:95:4f:84:a1:cb:32:4f: - 6c:21:be:d2:69:96:7d:63:bd:dc:2b:a8:1f:d0:13:84:70:fe: - f6:35:95:89:f9:a6:77:b0:46:c8:bb:b7:13:f5:c9:60:69:d6: - 4c:fe:d2:8e:ef:d3:60:c1:80:80:e1:e7:fb:8b:6f:21:79:4a: - e0:dc:a9:1b:c1:b7:fb:c3:49:59:5c:b5:77:07:44:d4:97:fc: - 49:00:89:6f:06:4e:01:70:19:ac:2f:11:c0:e2:e6:0f:2f:86: - 4b:8d:7b:c3:b9:a7:2e:f4:f1:ac:16:3e:39:49:51:9e:17:4b: - 4f:10:3a:5b:a5:a8:92:6f:fd:fa:d6:0b:03:4d:47:56:57:19: - f3:cb:6b:f5:f3:d6:cf:b0:f5:f5:a3:11:d2:20:53:13:34:37: - 05:2c:43:5a:63:df:8d:40:d6:85:1e:51:e9:51:17:1e:03:56: - c9:f1:30:ad:e7:9b:11:a2:b9:d0:31:81:9b:68:b1:d9:e8:f3: - e6:94:7e:c7:ae:13:2f:87:ed:d0:25:b0:68:f9:de:08:5a:f3: - 29:cc:d4:92 ------BEGIN CERTIFICATE----- -MIIETzCCAzegAwIBAgIDAjpvMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT -MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i -YWwgQ0EwHhcNMTMxMTA1MjEzNjUwWhcNMjIwNTIwMjEzNjUwWjBEMQswCQYDVQQG -EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg -U1NMIENBIC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDjvn4K -hqPPa209K6GXrUkkTdd3uTR5CKWeop7eRxKSPX7qGYax6E89X/fQp3eaWx8KA7UZ -U9ulIZRpY51qTJEMEEe+EfpshiW3qwRoQjgJZfAU2hme+msLq2LvjafvY3AjqK+B -89FuiGdT7BKkKXWKp/JXPaKDmJfyCn3U50NuMHhiIllZuHEnRaoPZsZVP/oyFysx -j0ag+mkUfJ2fWuLrM04QprPtd2PYw5703d95mnrU7t7dmszDt6ldzBE6B7tvl6QB -I0eVH6N3+liSxsfQvc+TGEK3fveeZerVO8rtrMVwof7UEJrwEgRErBpbeFBFV0xv -vYDLgVwts7x2oR5lAgMBAAGjggFKMIIBRjAfBgNVHSMEGDAWgBTAephojYn7qwVk -DBF9qn1luMrMTjAdBgNVHQ4EFgQU0m/3lvSFP3I8MH0j2oV4m6N8WnwwEgYDVR0T -AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwNgYDVR0fBC8wLTAroCmgJ4Yl -aHR0cDovL2cxLnN5bWNiLmNvbS9jcmxzL2d0Z2xvYmFsLmNybDAvBggrBgEFBQcB -AQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9nMi5zeW1jYi5jb20wTAYDVR0gBEUw -QzBBBgpghkgBhvhFAQc2MDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1 -c3QuY29tL3Jlc291cmNlcy9jcHMwKQYDVR0RBCIwIKQeMBwxGjAYBgNVBAMTEVN5 -bWFudGVjUEtJLTEtNTM5MA0GCSqGSIb3DQEBCwUAA4IBAQCg1Pcs+3QLf2TxzUNq -n2JTHAJ8mJCi7k9o1CAacxI+d7NQ63K87oi+fxfqd4+DYZVPhKHLMk9sIb7SaZZ9 -Y73cK6gf0BOEcP72NZWJ+aZ3sEbIu7cT9clgadZM/tKO79NgwYCA4ef7i28heUrg -3Kkbwbf7w0lZXLV3B0TUl/xJAIlvBk4BcBmsLxHA4uYPL4ZLjXvDuacu9PGsFj45 -SVGeF0tPEDpbpaiSb/361gsDTUdWVxnzy2v189bPsPX1oxHSIFMTNDcFLENaY9+N -QNaFHlHpURceA1bJ8TCt55sRornQMYGbaLHZ6PPmlH7HrhMvh+3QJbBo+d4IWvMp -zNSS ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert15[] = { - 0x30, 0x82, 0x04, 0x4f, 0x30, 0x82, 0x03, 0x37, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x03, 0x02, 0x3a, 0x6f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, - 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, - 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, - 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, - 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, - 0x31, 0x30, 0x35, 0x32, 0x31, 0x33, 0x36, 0x35, 0x30, 0x5a, 0x17, 0x0d, - 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x31, 0x33, 0x36, 0x35, 0x30, - 0x5a, 0x30, 0x44, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, - 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x13, 0x14, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, - 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 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, 0xe3, 0xbe, 0x7e, 0x0a, - 0x86, 0xa3, 0xcf, 0x6b, 0x6d, 0x3d, 0x2b, 0xa1, 0x97, 0xad, 0x49, 0x24, - 0x4d, 0xd7, 0x77, 0xb9, 0x34, 0x79, 0x08, 0xa5, 0x9e, 0xa2, 0x9e, 0xde, - 0x47, 0x12, 0x92, 0x3d, 0x7e, 0xea, 0x19, 0x86, 0xb1, 0xe8, 0x4f, 0x3d, - 0x5f, 0xf7, 0xd0, 0xa7, 0x77, 0x9a, 0x5b, 0x1f, 0x0a, 0x03, 0xb5, 0x19, - 0x53, 0xdb, 0xa5, 0x21, 0x94, 0x69, 0x63, 0x9d, 0x6a, 0x4c, 0x91, 0x0c, - 0x10, 0x47, 0xbe, 0x11, 0xfa, 0x6c, 0x86, 0x25, 0xb7, 0xab, 0x04, 0x68, - 0x42, 0x38, 0x09, 0x65, 0xf0, 0x14, 0xda, 0x19, 0x9e, 0xfa, 0x6b, 0x0b, - 0xab, 0x62, 0xef, 0x8d, 0xa7, 0xef, 0x63, 0x70, 0x23, 0xa8, 0xaf, 0x81, - 0xf3, 0xd1, 0x6e, 0x88, 0x67, 0x53, 0xec, 0x12, 0xa4, 0x29, 0x75, 0x8a, - 0xa7, 0xf2, 0x57, 0x3d, 0xa2, 0x83, 0x98, 0x97, 0xf2, 0x0a, 0x7d, 0xd4, - 0xe7, 0x43, 0x6e, 0x30, 0x78, 0x62, 0x22, 0x59, 0x59, 0xb8, 0x71, 0x27, - 0x45, 0xaa, 0x0f, 0x66, 0xc6, 0x55, 0x3f, 0xfa, 0x32, 0x17, 0x2b, 0x31, - 0x8f, 0x46, 0xa0, 0xfa, 0x69, 0x14, 0x7c, 0x9d, 0x9f, 0x5a, 0xe2, 0xeb, - 0x33, 0x4e, 0x10, 0xa6, 0xb3, 0xed, 0x77, 0x63, 0xd8, 0xc3, 0x9e, 0xf4, - 0xdd, 0xdf, 0x79, 0x9a, 0x7a, 0xd4, 0xee, 0xde, 0xdd, 0x9a, 0xcc, 0xc3, - 0xb7, 0xa9, 0x5d, 0xcc, 0x11, 0x3a, 0x07, 0xbb, 0x6f, 0x97, 0xa4, 0x01, - 0x23, 0x47, 0x95, 0x1f, 0xa3, 0x77, 0xfa, 0x58, 0x92, 0xc6, 0xc7, 0xd0, - 0xbd, 0xcf, 0x93, 0x18, 0x42, 0xb7, 0x7e, 0xf7, 0x9e, 0x65, 0xea, 0xd5, - 0x3b, 0xca, 0xed, 0xac, 0xc5, 0x70, 0xa1, 0xfe, 0xd4, 0x10, 0x9a, 0xf0, - 0x12, 0x04, 0x44, 0xac, 0x1a, 0x5b, 0x78, 0x50, 0x45, 0x57, 0x4c, 0x6f, - 0xbd, 0x80, 0xcb, 0x81, 0x5c, 0x2d, 0xb3, 0xbc, 0x76, 0xa1, 0x1e, 0x65, - 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x4a, 0x30, 0x82, 0x01, - 0x46, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, - 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64, - 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x1d, - 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xd2, 0x6f, 0xf7, - 0x96, 0xf4, 0x85, 0x3f, 0x72, 0x3c, 0x30, 0x7d, 0x23, 0xda, 0x85, 0x78, - 0x9b, 0xa3, 0x7c, 0x5a, 0x7c, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, - 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, - 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, - 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x36, 0x06, 0x03, 0x55, 0x1d, 0x1f, - 0x04, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27, 0x86, 0x25, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x31, 0x2e, 0x73, 0x79, - 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, - 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72, - 0x6c, 0x30, 0x2f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, - 0x01, 0x04, 0x23, 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x67, 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, - 0x43, 0x30, 0x41, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, - 0x01, 0x07, 0x36, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x29, 0x06, 0x03, - 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, - 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, - 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, - 0x35, 0x33, 0x39, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xa0, - 0xd4, 0xf7, 0x2c, 0xfb, 0x74, 0x0b, 0x7f, 0x64, 0xf1, 0xcd, 0x43, 0x6a, - 0x9f, 0x62, 0x53, 0x1c, 0x02, 0x7c, 0x98, 0x90, 0xa2, 0xee, 0x4f, 0x68, - 0xd4, 0x20, 0x1a, 0x73, 0x12, 0x3e, 0x77, 0xb3, 0x50, 0xeb, 0x72, 0xbc, - 0xee, 0x88, 0xbe, 0x7f, 0x17, 0xea, 0x77, 0x8f, 0x83, 0x61, 0x95, 0x4f, - 0x84, 0xa1, 0xcb, 0x32, 0x4f, 0x6c, 0x21, 0xbe, 0xd2, 0x69, 0x96, 0x7d, - 0x63, 0xbd, 0xdc, 0x2b, 0xa8, 0x1f, 0xd0, 0x13, 0x84, 0x70, 0xfe, 0xf6, - 0x35, 0x95, 0x89, 0xf9, 0xa6, 0x77, 0xb0, 0x46, 0xc8, 0xbb, 0xb7, 0x13, - 0xf5, 0xc9, 0x60, 0x69, 0xd6, 0x4c, 0xfe, 0xd2, 0x8e, 0xef, 0xd3, 0x60, - 0xc1, 0x80, 0x80, 0xe1, 0xe7, 0xfb, 0x8b, 0x6f, 0x21, 0x79, 0x4a, 0xe0, - 0xdc, 0xa9, 0x1b, 0xc1, 0xb7, 0xfb, 0xc3, 0x49, 0x59, 0x5c, 0xb5, 0x77, - 0x07, 0x44, 0xd4, 0x97, 0xfc, 0x49, 0x00, 0x89, 0x6f, 0x06, 0x4e, 0x01, - 0x70, 0x19, 0xac, 0x2f, 0x11, 0xc0, 0xe2, 0xe6, 0x0f, 0x2f, 0x86, 0x4b, - 0x8d, 0x7b, 0xc3, 0xb9, 0xa7, 0x2e, 0xf4, 0xf1, 0xac, 0x16, 0x3e, 0x39, - 0x49, 0x51, 0x9e, 0x17, 0x4b, 0x4f, 0x10, 0x3a, 0x5b, 0xa5, 0xa8, 0x92, - 0x6f, 0xfd, 0xfa, 0xd6, 0x0b, 0x03, 0x4d, 0x47, 0x56, 0x57, 0x19, 0xf3, - 0xcb, 0x6b, 0xf5, 0xf3, 0xd6, 0xcf, 0xb0, 0xf5, 0xf5, 0xa3, 0x11, 0xd2, - 0x20, 0x53, 0x13, 0x34, 0x37, 0x05, 0x2c, 0x43, 0x5a, 0x63, 0xdf, 0x8d, - 0x40, 0xd6, 0x85, 0x1e, 0x51, 0xe9, 0x51, 0x17, 0x1e, 0x03, 0x56, 0xc9, - 0xf1, 0x30, 0xad, 0xe7, 0x9b, 0x11, 0xa2, 0xb9, 0xd0, 0x31, 0x81, 0x9b, - 0x68, 0xb1, 0xd9, 0xe8, 0xf3, 0xe6, 0x94, 0x7e, 0xc7, 0xae, 0x13, 0x2f, - 0x87, 0xed, 0xd0, 0x25, 0xb0, 0x68, 0xf9, 0xde, 0x08, 0x5a, 0xf3, 0x29, - 0xcc, 0xd4, 0x92, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 146019 (0x23a63) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA - Validity - Not Before: Aug 27 20:40:40 2012 GMT - Not After : May 20 20:40:40 2022 GMT - Subject: C=US, O=GeoTrust Inc., CN=GeoTrust SSL CA - G2 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:b9:27:f9:4f:d8:f6:b7:15:3f:8f:cd:ce:d6:8d: - 1c:6b:fd:7f:da:54:21:4e:03:d8:ca:d0:72:52:15: - b8:c9:82:5b:58:79:84:ff:24:72:6f:f2:69:7f:bc: - 96:d9:9a:7a:c3:3e:a9:cf:50:22:13:0e:86:19:db: - e8:49:ef:8b:e6:d6:47:f2:fd:73:45:08:ae:8f:ac: - 5e:b6:f8:9e:7c:f7:10:ff:92:43:66:ef:1c:d4:ee: - a1:46:88:11:89:49:79:7a:25:ce:4b:6a:f0:d7:1c: - 76:1a:29:3c:c9:e4:fd:1e:85:dc:e0:31:65:05:47: - 16:ac:0a:07:4b:2e:70:5e:6b:06:a7:6b:3a:6c:af: - 05:12:c4:b2:11:25:d6:3e:97:29:f0:83:6c:57:1c: - d8:a5:ef:cc:ec:fd:d6:12:f1:3f:db:40:b4:ae:0f: - 18:d3:c5:af:40:92:5d:07:5e:4e:fe:62:17:37:89: - e9:8b:74:26:a2:ed:b8:0a:e7:6c:15:5b:35:90:72: - dd:d8:4d:21:d4:40:23:5c:8f:ee:80:31:16:ab:68: - 55:f4:0e:3b:54:e9:04:4d:f0:cc:4e:81:5e:e9:6f: - 52:69:4e:be:a6:16:6d:42:f5:51:ff:e0:0b:56:3c: - 98:4f:73:8f:0e:6f:1a:23:f1:c9:c8:d9:df:bc:ec: - 52:d7 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Authority Key Identifier: - keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E - - X509v3 Subject Key Identifier: - 11:4A:D0:73:39:D5:5B:69:08:5C:BA:3D:BF:64:9A:A8:8B:1C:55:BC - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.geotrust.com/crls/gtglobal.crl - - Authority Information Access: - OCSP - URI:http://ocsp.geotrust.com - - X509v3 Certificate Policies: - Policy: 2.16.840.1.113733.1.7.54 - CPS: http://www.geotrust.com/resources/cps - - X509v3 Subject Alternative Name: - DirName:/CN=VeriSignMPKI-2-254 - Signature Algorithm: sha1WithRSAEncryption - 3c:e5:3d:5a:1b:a2:37:2a:e3:46:cf:36:96:18:3c:7b:f1:84: - c5:57:86:77:40:9d:35:f0:12:f0:78:18:fb:22:a4:de:98:4b: - 78:81:e6:4d:86:e3:91:0f:42:e3:b9:dc:a0:d6:ff:a9:f8:b1: - 79:97:99:d1:c3:6c:42:a5:92:94:e0:5d:0c:33:18:25:c9:2b: - 95:53:e0:e5:a9:0c:7d:47:fe:7f:51:31:44:5e:f7:2a:1e:35: - a2:94:32:f7:c9:ee:c0:b6:c6:9a:ac:de:99:21:6a:23:a0:38: - 64:ee:a3:c4:88:73:32:3b:50:ce:bf:ad:d3:75:1e:a6:f4:e9: - f9:42:6b:60:b2:dd:45:fd:5d:57:08:ce:2d:50:e6:12:32:16: - 13:8a:f2:94:a2:9b:47:a8:86:7f:d9:98:e5:f7:e5:76:74:64: - d8:91:bc:84:16:28:d8:25:44:30:7e:82:d8:ac:b1:e4:c0:e4: - 15:6c:db:b6:24:27:02:2a:01:12:85:ba:31:88:58:47:74:e3: - b8:d2:64:a6:c3:32:59:2e:29:4b:45:f1:5b:89:49:2e:82:9a: - c6:18:15:44:d0:2e:64:01:15:68:38:f9:f6:f9:66:03:0c:55: - 1b:9d:bf:00:40:ae:f0:48:27:4c:e0:80:5e:2d:b9:2a:15:7a: - bc:66:f8:35 ------BEGIN CERTIFICATE----- -MIIEWTCCA0GgAwIBAgIDAjpjMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT -MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i -YWwgQ0EwHhcNMTIwODI3MjA0MDQwWhcNMjIwNTIwMjA0MDQwWjBEMQswCQYDVQQG -EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg -U1NMIENBIC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5J/lP -2Pa3FT+Pzc7WjRxr/X/aVCFOA9jK0HJSFbjJgltYeYT/JHJv8ml/vJbZmnrDPqnP -UCITDoYZ2+hJ74vm1kfy/XNFCK6PrF62+J589xD/kkNm7xzU7qFGiBGJSXl6Jc5L -avDXHHYaKTzJ5P0ehdzgMWUFRxasCgdLLnBeawanazpsrwUSxLIRJdY+lynwg2xX -HNil78zs/dYS8T/bQLSuDxjTxa9Akl0HXk7+Yhc3iemLdCai7bgK52wVWzWQct3Y -TSHUQCNcj+6AMRaraFX0DjtU6QRN8MxOgV7pb1JpTr6mFm1C9VH/4AtWPJhPc48O -bxoj8cnI2d+87FLXAgMBAAGjggFUMIIBUDAfBgNVHSMEGDAWgBTAephojYn7qwVk -DBF9qn1luMrMTjAdBgNVHQ4EFgQUEUrQcznVW2kIXLo9v2SaqIscVbwwEgYDVR0T -AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMwMTAvoC2gK4Yp -aHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwNAYIKwYB -BQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5nZW90cnVzdC5jb20w -TAYDVR0gBEUwQzBBBgpghkgBhvhFAQc2MDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93 -d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwKgYDVR0RBCMwIaQfMB0xGzAZ -BgNVBAMTElZlcmlTaWduTVBLSS0yLTI1NDANBgkqhkiG9w0BAQUFAAOCAQEAPOU9 -WhuiNyrjRs82lhg8e/GExVeGd0CdNfAS8HgY+yKk3phLeIHmTYbjkQ9C47ncoNb/ -qfixeZeZ0cNsQqWSlOBdDDMYJckrlVPg5akMfUf+f1ExRF73Kh41opQy98nuwLbG -mqzemSFqI6A4ZO6jxIhzMjtQzr+t03UepvTp+UJrYLLdRf1dVwjOLVDmEjIWE4ry -lKKbR6iGf9mY5ffldnRk2JG8hBYo2CVEMH6C2Kyx5MDkFWzbtiQnAioBEoW6MYhY -R3TjuNJkpsMyWS4pS0XxW4lJLoKaxhgVRNAuZAEVaDj59vlmAwxVG52/AECu8Egn -TOCAXi25KhV6vGb4NQ== ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert16[] = { - 0x30, 0x82, 0x04, 0x59, 0x30, 0x82, 0x03, 0x41, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x03, 0x02, 0x3a, 0x63, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x42, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, - 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, - 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, - 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, - 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x30, - 0x38, 0x32, 0x37, 0x32, 0x30, 0x34, 0x30, 0x34, 0x30, 0x5a, 0x17, 0x0d, - 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x30, 0x34, 0x30, 0x34, 0x30, - 0x5a, 0x30, 0x44, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, - 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x13, 0x14, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, - 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x32, 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, 0xb9, 0x27, 0xf9, 0x4f, - 0xd8, 0xf6, 0xb7, 0x15, 0x3f, 0x8f, 0xcd, 0xce, 0xd6, 0x8d, 0x1c, 0x6b, - 0xfd, 0x7f, 0xda, 0x54, 0x21, 0x4e, 0x03, 0xd8, 0xca, 0xd0, 0x72, 0x52, - 0x15, 0xb8, 0xc9, 0x82, 0x5b, 0x58, 0x79, 0x84, 0xff, 0x24, 0x72, 0x6f, - 0xf2, 0x69, 0x7f, 0xbc, 0x96, 0xd9, 0x9a, 0x7a, 0xc3, 0x3e, 0xa9, 0xcf, - 0x50, 0x22, 0x13, 0x0e, 0x86, 0x19, 0xdb, 0xe8, 0x49, 0xef, 0x8b, 0xe6, - 0xd6, 0x47, 0xf2, 0xfd, 0x73, 0x45, 0x08, 0xae, 0x8f, 0xac, 0x5e, 0xb6, - 0xf8, 0x9e, 0x7c, 0xf7, 0x10, 0xff, 0x92, 0x43, 0x66, 0xef, 0x1c, 0xd4, - 0xee, 0xa1, 0x46, 0x88, 0x11, 0x89, 0x49, 0x79, 0x7a, 0x25, 0xce, 0x4b, - 0x6a, 0xf0, 0xd7, 0x1c, 0x76, 0x1a, 0x29, 0x3c, 0xc9, 0xe4, 0xfd, 0x1e, - 0x85, 0xdc, 0xe0, 0x31, 0x65, 0x05, 0x47, 0x16, 0xac, 0x0a, 0x07, 0x4b, - 0x2e, 0x70, 0x5e, 0x6b, 0x06, 0xa7, 0x6b, 0x3a, 0x6c, 0xaf, 0x05, 0x12, - 0xc4, 0xb2, 0x11, 0x25, 0xd6, 0x3e, 0x97, 0x29, 0xf0, 0x83, 0x6c, 0x57, - 0x1c, 0xd8, 0xa5, 0xef, 0xcc, 0xec, 0xfd, 0xd6, 0x12, 0xf1, 0x3f, 0xdb, - 0x40, 0xb4, 0xae, 0x0f, 0x18, 0xd3, 0xc5, 0xaf, 0x40, 0x92, 0x5d, 0x07, - 0x5e, 0x4e, 0xfe, 0x62, 0x17, 0x37, 0x89, 0xe9, 0x8b, 0x74, 0x26, 0xa2, - 0xed, 0xb8, 0x0a, 0xe7, 0x6c, 0x15, 0x5b, 0x35, 0x90, 0x72, 0xdd, 0xd8, - 0x4d, 0x21, 0xd4, 0x40, 0x23, 0x5c, 0x8f, 0xee, 0x80, 0x31, 0x16, 0xab, - 0x68, 0x55, 0xf4, 0x0e, 0x3b, 0x54, 0xe9, 0x04, 0x4d, 0xf0, 0xcc, 0x4e, - 0x81, 0x5e, 0xe9, 0x6f, 0x52, 0x69, 0x4e, 0xbe, 0xa6, 0x16, 0x6d, 0x42, - 0xf5, 0x51, 0xff, 0xe0, 0x0b, 0x56, 0x3c, 0x98, 0x4f, 0x73, 0x8f, 0x0e, - 0x6f, 0x1a, 0x23, 0xf1, 0xc9, 0xc8, 0xd9, 0xdf, 0xbc, 0xec, 0x52, 0xd7, - 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x54, 0x30, 0x82, 0x01, - 0x50, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, - 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64, - 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x1d, - 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x11, 0x4a, 0xd0, - 0x73, 0x39, 0xd5, 0x5b, 0x69, 0x08, 0x5c, 0xba, 0x3d, 0xbf, 0x64, 0x9a, - 0xa8, 0x8b, 0x1c, 0x55, 0xbc, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, - 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, - 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, - 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x1d, 0x1f, - 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, 0xa0, 0x2d, 0xa0, 0x2b, 0x86, 0x29, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67, - 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, - 0x6c, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, - 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, - 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, - 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, - 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x36, - 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, - 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x1d, 0x11, - 0x04, 0x23, 0x30, 0x21, 0xa4, 0x1f, 0x30, 0x1d, 0x31, 0x1b, 0x30, 0x19, - 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x56, 0x65, 0x72, 0x69, 0x53, - 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49, 0x2d, 0x32, 0x2d, 0x32, 0x35, - 0x34, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x3c, 0xe5, 0x3d, - 0x5a, 0x1b, 0xa2, 0x37, 0x2a, 0xe3, 0x46, 0xcf, 0x36, 0x96, 0x18, 0x3c, - 0x7b, 0xf1, 0x84, 0xc5, 0x57, 0x86, 0x77, 0x40, 0x9d, 0x35, 0xf0, 0x12, - 0xf0, 0x78, 0x18, 0xfb, 0x22, 0xa4, 0xde, 0x98, 0x4b, 0x78, 0x81, 0xe6, - 0x4d, 0x86, 0xe3, 0x91, 0x0f, 0x42, 0xe3, 0xb9, 0xdc, 0xa0, 0xd6, 0xff, - 0xa9, 0xf8, 0xb1, 0x79, 0x97, 0x99, 0xd1, 0xc3, 0x6c, 0x42, 0xa5, 0x92, - 0x94, 0xe0, 0x5d, 0x0c, 0x33, 0x18, 0x25, 0xc9, 0x2b, 0x95, 0x53, 0xe0, - 0xe5, 0xa9, 0x0c, 0x7d, 0x47, 0xfe, 0x7f, 0x51, 0x31, 0x44, 0x5e, 0xf7, - 0x2a, 0x1e, 0x35, 0xa2, 0x94, 0x32, 0xf7, 0xc9, 0xee, 0xc0, 0xb6, 0xc6, - 0x9a, 0xac, 0xde, 0x99, 0x21, 0x6a, 0x23, 0xa0, 0x38, 0x64, 0xee, 0xa3, - 0xc4, 0x88, 0x73, 0x32, 0x3b, 0x50, 0xce, 0xbf, 0xad, 0xd3, 0x75, 0x1e, - 0xa6, 0xf4, 0xe9, 0xf9, 0x42, 0x6b, 0x60, 0xb2, 0xdd, 0x45, 0xfd, 0x5d, - 0x57, 0x08, 0xce, 0x2d, 0x50, 0xe6, 0x12, 0x32, 0x16, 0x13, 0x8a, 0xf2, - 0x94, 0xa2, 0x9b, 0x47, 0xa8, 0x86, 0x7f, 0xd9, 0x98, 0xe5, 0xf7, 0xe5, - 0x76, 0x74, 0x64, 0xd8, 0x91, 0xbc, 0x84, 0x16, 0x28, 0xd8, 0x25, 0x44, - 0x30, 0x7e, 0x82, 0xd8, 0xac, 0xb1, 0xe4, 0xc0, 0xe4, 0x15, 0x6c, 0xdb, - 0xb6, 0x24, 0x27, 0x02, 0x2a, 0x01, 0x12, 0x85, 0xba, 0x31, 0x88, 0x58, - 0x47, 0x74, 0xe3, 0xb8, 0xd2, 0x64, 0xa6, 0xc3, 0x32, 0x59, 0x2e, 0x29, - 0x4b, 0x45, 0xf1, 0x5b, 0x89, 0x49, 0x2e, 0x82, 0x9a, 0xc6, 0x18, 0x15, - 0x44, 0xd0, 0x2e, 0x64, 0x01, 0x15, 0x68, 0x38, 0xf9, 0xf6, 0xf9, 0x66, - 0x03, 0x0c, 0x55, 0x1b, 0x9d, 0xbf, 0x00, 0x40, 0xae, 0xf0, 0x48, 0x27, - 0x4c, 0xe0, 0x80, 0x5e, 0x2d, 0xb9, 0x2a, 0x15, 0x7a, 0xbc, 0x66, 0xf8, - 0x35, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 04:00:00:00:00:01:2f:4e:e1:45:0c - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA - Validity - Not Before: Apr 13 10:00:00 2011 GMT - Not After : Apr 13 10:00:00 2022 GMT - Subject: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Organization Validation CA - G2 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:dd:35:1d:f2:20:54:26:1a:d0:ef:a5:6f:81:76: - 59:70:dc:e7:f4:d4:03:24:1f:24:0e:9d:22:9f:d4: - 27:32:7a:2b:7c:ee:8b:e3:61:62:38:17:af:b4:4b: - 7a:9f:67:21:1c:2d:95:54:ba:79:ba:b6:c4:f2:0d: - 21:74:17:67:74:e2:b1:64:08:99:60:78:fb:67:c2: - 4b:f7:27:8d:6f:36:76:cf:31:8c:e5:f1:06:d7:dc: - 57:0e:5b:ac:ee:ce:2d:ab:aa:a9:70:2f:02:86:c8: - b1:d0:08:07:95:ea:2a:ec:d1:9e:e4:36:5c:3b:a6: - 36:b5:43:8b:ab:f7:8e:3e:00:1b:ff:85:59:6b:62: - 01:8d:82:e8:4a:ba:38:b3:e0:c3:f4:6d:19:a7:ea: - 05:dd:84:67:c2:66:c7:24:02:73:5a:b5:ee:a4:19: - d9:fc:00:ce:b6:a4:8d:df:7e:bd:5f:b2:3a:9d:84: - 31:4f:c8:63:0c:e4:d8:0d:52:a3:7e:01:1b:d4:67: - a5:18:28:eb:01:a7:82:3c:d9:8e:1d:e5:47:0d:ba: - 8b:59:14:a3:1f:1f:4b:ea:e2:27:46:86:ce:9d:39: - c4:66:41:a7:e2:15:23:6b:56:47:c1:ed:c5:53:e4: - d4:80:1f:6b:fa:80:46:98:b2:09:a6:0f:95:be:66: - 88:93 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Subject Key Identifier: - 5D:46:B2:8D:C4:4B:74:1C:BB:ED:F5:73:B6:3A:B7:38:8F:75:9E:7E - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://www.globalsign.com/repository/ - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.globalsign.net/root.crl - - Authority Information Access: - OCSP - URI:http://ocsp.globalsign.com/rootr1 - - X509v3 Authority Key Identifier: - keyid:60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B - - Signature Algorithm: sha1WithRSAEncryption - 1b:e0:88:00:c7:05:11:1c:ff:ab:2d:48:42:52:cd:20:68:e7: - 7c:41:8d:c1:27:c5:2c:59:67:a0:9a:35:db:b3:50:a7:1b:62: - e9:a5:3b:fa:b6:21:07:a7:7c:f3:0e:2b:6e:7e:2e:4d:93:9c: - ba:f2:86:3e:63:88:10:d8:5b:61:50:12:db:87:ae:19:bb:d2: - df:32:96:00:a8:5e:dc:2d:23:bc:b0:d3:b5:4a:a0:8e:65:91: - 2f:d9:f6:82:f6:74:b2:df:7c:26:ef:19:2b:97:2f:e0:a1:ee: - b9:17:22:48:3f:a5:f7:0d:60:d5:0d:51:47:e5:58:fe:b7:9f: - 8d:5e:75:3c:c6:41:f0:cf:81:54:49:11:c6:17:a4:e0:56:61: - dc:3d:3f:dd:67:6c:76:45:da:4a:ea:ae:1a:a4:60:4f:c7:a3: - d6:aa:a7:d9:cd:81:2b:c1:66:75:b2:80:8f:f5:87:4d:5f:c2: - 5a:f5:90:c6:da:c1:bd:f4:85:a8:3c:23:2a:e1:14:7b:c1:37: - dd:62:d1:92:6c:ba:60:7d:88:e4:1c:b7:e4:76:51:38:c4:a9: - 47:4e:a8:2b:2e:90:d2:b5:38:51:eb:c1:9c:8a:6a:b5:cc:b2: - 1d:e8:c0:56:54:4c:a8:8b:f0:89:32:86:dc:93:32:be:4d:1a: - fa:35:75:b5 ------BEGIN CERTIFICATE----- -MIIEYDCCA0igAwIBAgILBAAAAAABL07hRQwwDQYJKoZIhvcNAQEFBQAwVzELMAkG -A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv -b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xMTA0MTMxMDAw -MDBaFw0yMjA0MTMxMDAwMDBaMF0xCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i -YWxTaWduIG52LXNhMTMwMQYDVQQDEypHbG9iYWxTaWduIE9yZ2FuaXphdGlvbiBW -YWxpZGF0aW9uIENBIC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQDdNR3yIFQmGtDvpW+Bdllw3Of01AMkHyQOnSKf1Ccyeit87ovjYWI4F6+0S3qf -ZyEcLZVUunm6tsTyDSF0F2d04rFkCJlgePtnwkv3J41vNnbPMYzl8QbX3FcOW6zu -zi2rqqlwLwKGyLHQCAeV6irs0Z7kNlw7pja1Q4ur944+ABv/hVlrYgGNguhKujiz -4MP0bRmn6gXdhGfCZsckAnNate6kGdn8AM62pI3ffr1fsjqdhDFPyGMM5NgNUqN+ -ARvUZ6UYKOsBp4I82Y4d5UcNuotZFKMfH0vq4idGhs6dOcRmQafiFSNrVkfB7cVT -5NSAH2v6gEaYsgmmD5W+ZoiTAgMBAAGjggElMIIBITAOBgNVHQ8BAf8EBAMCAQYw -EgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUXUayjcRLdBy77fVztjq3OI91 -nn4wRwYDVR0gBEAwPjA8BgRVHSAAMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8vd3d3 -Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMDMGA1UdHwQsMCowKKAmoCSGImh0 -dHA6Ly9jcmwuZ2xvYmFsc2lnbi5uZXQvcm9vdC5jcmwwPQYIKwYBBQUHAQEEMTAv -MC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNvbS9yb290cjEw -HwYDVR0jBBgwFoAUYHtmGkUNl8qJUC99BM00qP/8/UswDQYJKoZIhvcNAQEFBQAD -ggEBABvgiADHBREc/6stSEJSzSBo53xBjcEnxSxZZ6CaNduzUKcbYumlO/q2IQen -fPMOK25+Lk2TnLryhj5jiBDYW2FQEtuHrhm70t8ylgCoXtwtI7yw07VKoI5lkS/Z -9oL2dLLffCbvGSuXL+Ch7rkXIkg/pfcNYNUNUUflWP63n41edTzGQfDPgVRJEcYX -pOBWYdw9P91nbHZF2krqrhqkYE/Ho9aqp9nNgSvBZnWygI/1h01fwlr1kMbawb30 -hag8IyrhFHvBN91i0ZJsumB9iOQct+R2UTjEqUdOqCsukNK1OFHrwZyKarXMsh3o -wFZUTKiL8IkyhtyTMr5NGvo1dbU= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert17[] = { - 0x30, 0x82, 0x04, 0x60, 0x30, 0x82, 0x03, 0x48, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2f, 0x4e, 0xe1, - 0x45, 0x0c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x57, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, - 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, - 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, - 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x07, 0x52, 0x6f, - 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, - 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, - 0x17, 0x0d, 0x31, 0x31, 0x30, 0x34, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x32, 0x30, 0x34, 0x31, 0x33, 0x31, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x5d, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, - 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, - 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, - 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2a, 0x47, - 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x4f, 0x72, - 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x41, - 0x20, 0x2d, 0x20, 0x47, 0x32, 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, 0xdd, 0x35, 0x1d, 0xf2, 0x20, 0x54, 0x26, 0x1a, 0xd0, 0xef, - 0xa5, 0x6f, 0x81, 0x76, 0x59, 0x70, 0xdc, 0xe7, 0xf4, 0xd4, 0x03, 0x24, - 0x1f, 0x24, 0x0e, 0x9d, 0x22, 0x9f, 0xd4, 0x27, 0x32, 0x7a, 0x2b, 0x7c, - 0xee, 0x8b, 0xe3, 0x61, 0x62, 0x38, 0x17, 0xaf, 0xb4, 0x4b, 0x7a, 0x9f, - 0x67, 0x21, 0x1c, 0x2d, 0x95, 0x54, 0xba, 0x79, 0xba, 0xb6, 0xc4, 0xf2, - 0x0d, 0x21, 0x74, 0x17, 0x67, 0x74, 0xe2, 0xb1, 0x64, 0x08, 0x99, 0x60, - 0x78, 0xfb, 0x67, 0xc2, 0x4b, 0xf7, 0x27, 0x8d, 0x6f, 0x36, 0x76, 0xcf, - 0x31, 0x8c, 0xe5, 0xf1, 0x06, 0xd7, 0xdc, 0x57, 0x0e, 0x5b, 0xac, 0xee, - 0xce, 0x2d, 0xab, 0xaa, 0xa9, 0x70, 0x2f, 0x02, 0x86, 0xc8, 0xb1, 0xd0, - 0x08, 0x07, 0x95, 0xea, 0x2a, 0xec, 0xd1, 0x9e, 0xe4, 0x36, 0x5c, 0x3b, - 0xa6, 0x36, 0xb5, 0x43, 0x8b, 0xab, 0xf7, 0x8e, 0x3e, 0x00, 0x1b, 0xff, - 0x85, 0x59, 0x6b, 0x62, 0x01, 0x8d, 0x82, 0xe8, 0x4a, 0xba, 0x38, 0xb3, - 0xe0, 0xc3, 0xf4, 0x6d, 0x19, 0xa7, 0xea, 0x05, 0xdd, 0x84, 0x67, 0xc2, - 0x66, 0xc7, 0x24, 0x02, 0x73, 0x5a, 0xb5, 0xee, 0xa4, 0x19, 0xd9, 0xfc, - 0x00, 0xce, 0xb6, 0xa4, 0x8d, 0xdf, 0x7e, 0xbd, 0x5f, 0xb2, 0x3a, 0x9d, - 0x84, 0x31, 0x4f, 0xc8, 0x63, 0x0c, 0xe4, 0xd8, 0x0d, 0x52, 0xa3, 0x7e, - 0x01, 0x1b, 0xd4, 0x67, 0xa5, 0x18, 0x28, 0xeb, 0x01, 0xa7, 0x82, 0x3c, - 0xd9, 0x8e, 0x1d, 0xe5, 0x47, 0x0d, 0xba, 0x8b, 0x59, 0x14, 0xa3, 0x1f, - 0x1f, 0x4b, 0xea, 0xe2, 0x27, 0x46, 0x86, 0xce, 0x9d, 0x39, 0xc4, 0x66, - 0x41, 0xa7, 0xe2, 0x15, 0x23, 0x6b, 0x56, 0x47, 0xc1, 0xed, 0xc5, 0x53, - 0xe4, 0xd4, 0x80, 0x1f, 0x6b, 0xfa, 0x80, 0x46, 0x98, 0xb2, 0x09, 0xa6, - 0x0f, 0x95, 0xbe, 0x66, 0x88, 0x93, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, - 0x82, 0x01, 0x25, 0x30, 0x82, 0x01, 0x21, 0x30, 0x0e, 0x06, 0x03, 0x55, - 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, - 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, - 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, - 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x5d, 0x46, 0xb2, 0x8d, 0xc4, 0x4b, - 0x74, 0x1c, 0xbb, 0xed, 0xf5, 0x73, 0xb6, 0x3a, 0xb7, 0x38, 0x8f, 0x75, - 0x9e, 0x7e, 0x30, 0x47, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x40, 0x30, - 0x3e, 0x30, 0x3c, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x34, 0x30, - 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, - 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x2f, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2c, - 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86, 0x22, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x6c, 0x6f, - 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2f, - 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3d, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x31, 0x30, 0x2f, - 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, - 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, - 0x70, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x72, 0x31, 0x30, - 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, - 0x60, 0x7b, 0x66, 0x1a, 0x45, 0x0d, 0x97, 0xca, 0x89, 0x50, 0x2f, 0x7d, - 0x04, 0xcd, 0x34, 0xa8, 0xff, 0xfc, 0xfd, 0x4b, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, - 0x82, 0x01, 0x01, 0x00, 0x1b, 0xe0, 0x88, 0x00, 0xc7, 0x05, 0x11, 0x1c, - 0xff, 0xab, 0x2d, 0x48, 0x42, 0x52, 0xcd, 0x20, 0x68, 0xe7, 0x7c, 0x41, - 0x8d, 0xc1, 0x27, 0xc5, 0x2c, 0x59, 0x67, 0xa0, 0x9a, 0x35, 0xdb, 0xb3, - 0x50, 0xa7, 0x1b, 0x62, 0xe9, 0xa5, 0x3b, 0xfa, 0xb6, 0x21, 0x07, 0xa7, - 0x7c, 0xf3, 0x0e, 0x2b, 0x6e, 0x7e, 0x2e, 0x4d, 0x93, 0x9c, 0xba, 0xf2, - 0x86, 0x3e, 0x63, 0x88, 0x10, 0xd8, 0x5b, 0x61, 0x50, 0x12, 0xdb, 0x87, - 0xae, 0x19, 0xbb, 0xd2, 0xdf, 0x32, 0x96, 0x00, 0xa8, 0x5e, 0xdc, 0x2d, - 0x23, 0xbc, 0xb0, 0xd3, 0xb5, 0x4a, 0xa0, 0x8e, 0x65, 0x91, 0x2f, 0xd9, - 0xf6, 0x82, 0xf6, 0x74, 0xb2, 0xdf, 0x7c, 0x26, 0xef, 0x19, 0x2b, 0x97, - 0x2f, 0xe0, 0xa1, 0xee, 0xb9, 0x17, 0x22, 0x48, 0x3f, 0xa5, 0xf7, 0x0d, - 0x60, 0xd5, 0x0d, 0x51, 0x47, 0xe5, 0x58, 0xfe, 0xb7, 0x9f, 0x8d, 0x5e, - 0x75, 0x3c, 0xc6, 0x41, 0xf0, 0xcf, 0x81, 0x54, 0x49, 0x11, 0xc6, 0x17, - 0xa4, 0xe0, 0x56, 0x61, 0xdc, 0x3d, 0x3f, 0xdd, 0x67, 0x6c, 0x76, 0x45, - 0xda, 0x4a, 0xea, 0xae, 0x1a, 0xa4, 0x60, 0x4f, 0xc7, 0xa3, 0xd6, 0xaa, - 0xa7, 0xd9, 0xcd, 0x81, 0x2b, 0xc1, 0x66, 0x75, 0xb2, 0x80, 0x8f, 0xf5, - 0x87, 0x4d, 0x5f, 0xc2, 0x5a, 0xf5, 0x90, 0xc6, 0xda, 0xc1, 0xbd, 0xf4, - 0x85, 0xa8, 0x3c, 0x23, 0x2a, 0xe1, 0x14, 0x7b, 0xc1, 0x37, 0xdd, 0x62, - 0xd1, 0x92, 0x6c, 0xba, 0x60, 0x7d, 0x88, 0xe4, 0x1c, 0xb7, 0xe4, 0x76, - 0x51, 0x38, 0xc4, 0xa9, 0x47, 0x4e, 0xa8, 0x2b, 0x2e, 0x90, 0xd2, 0xb5, - 0x38, 0x51, 0xeb, 0xc1, 0x9c, 0x8a, 0x6a, 0xb5, 0xcc, 0xb2, 0x1d, 0xe8, - 0xc0, 0x56, 0x54, 0x4c, 0xa8, 0x8b, 0xf0, 0x89, 0x32, 0x86, 0xdc, 0x93, - 0x32, 0xbe, 0x4d, 0x1a, 0xfa, 0x35, 0x75, 0xb5, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 04:00:00:00:00:01:44:4e:f0:3e:20 - Signature Algorithm: sha256WithRSAEncryption - Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA - Validity - Not Before: Feb 20 10:00:00 2014 GMT - Not After : Feb 20 10:00:00 2024 GMT - Subject: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Domain Validation CA - SHA256 - G2 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:a9:dd:cc:0e:b3:e2:32:39:dd:49:22:a8:13:69: - 93:87:88:e1:0c:ee:71:7d:bd:90:87:96:5d:59:f2: - cc:b3:d2:58:57:57:f9:46:ef:6c:26:d8:36:42:8e: - 7e:30:b3:2f:9a:3e:53:7b:1f:6e:b6:a2:4c:45:1f: - 3c:d3:15:93:1c:89:ed:3c:f4:57:de:ca:bd:ec:06: - 9a:6a:2a:a0:19:52:7f:51:d1:74:39:08:9f:ab:eb: - d7:86:13:15:97:ae:36:c3:54:66:0e:5a:f2:a0:73: - 85:31:e3:b2:64:14:6a:ff:a5:a2:8e:24:bb:bd:85: - 52:15:a2:79:ee:f0:b5:ee:3d:b8:f4:7d:80:bc:d9: - 90:35:65:b8:17:a9:ad:b3:98:9f:a0:7e:7d:6e:fb: - 3f:ad:7c:c2:1b:59:36:96:da:37:32:4b:4b:5d:35: - 02:63:8e:db:a7:cf:62:ee:cc:2e:d4:8d:c9:bd:3c: - 6a:91:72:a2:22:a7:72:2d:20:d1:fa:ca:37:da:18: - 98:e6:16:24:71:25:4b:c4:e5:7b:89:52:09:02:fd: - 59:2b:04:6e:ca:07:81:d4:b3:da:da:db:e3:cc:80: - a8:56:07:06:7c:96:08:37:9d:db:38:b6:62:34:91: - 62:07:74:01:38:d8:72:30:e2:eb:90:71:26:62:c0: - 57:f3 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Subject Key Identifier: - EA:4E:7C:D4:80:2D:E5:15:81:86:26:8C:82:6D:C0:98:A4:CF:97:0F - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://www.globalsign.com/repository/ - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.globalsign.net/root.crl - - Authority Information Access: - OCSP - URI:http://ocsp.globalsign.com/rootr1 - - X509v3 Authority Key Identifier: - keyid:60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B - - Signature Algorithm: sha256WithRSAEncryption - d7:45:9e:a0:dc:e0:e3:61:5a:0b:7d:77:84:17:2d:65:5a:82: - 9a:8d:a3:27:2a:85:f7:c9:ef:e9:86:fd:d4:47:cd:01:52:96: - c5:43:bd:37:b1:e1:b8:f2:a9:d2:8a:11:84:71:91:15:89:dc: - 02:9d:0b:cb:6c:33:85:34:28:9e:20:b2:b1:97:dc:6d:0b:10: - c1:3c:cd:5f:ea:5d:d7:98:31:c5:34:99:5c:00:61:55:c4:1b: - 02:5b:c5:e3:89:c8:b4:b8:6f:1e:38:f2:56:26:e9:41:ef:3d: - cd:ac:99:4f:59:4a:57:2d:4b:7d:ae:c7:88:fb:d6:98:3b:f5: - e5:f0:e8:89:89:b9:8b:03:cb:5a:23:1f:a4:fd:b8:ea:fb:2e: - 9d:ae:6a:73:09:bc:fc:d5:a0:b5:44:82:ab:44:91:2e:50:2e: - 57:c1:43:d8:91:04:8b:e9:11:2e:5f:b4:3f:79:df:1e:fb:3f: - 30:00:8b:53:e3:b7:2c:1d:3b:4d:8b:dc:e4:64:1d:04:58:33: - af:1b:55:e7:ab:0c:bf:30:04:74:e4:f3:0e:2f:30:39:8d:4b: - 04:8c:1e:75:66:66:49:e0:be:40:34:c7:5c:5a:51:92:ba:12: - 3c:52:d5:04:82:55:2d:67:a5:df:b7:95:7c:ee:3f:c3:08:ba: - 04:be:c0:46 ------BEGIN CERTIFICATE----- -MIIEYzCCA0ugAwIBAgILBAAAAAABRE7wPiAwDQYJKoZIhvcNAQELBQAwVzELMAkG -A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv -b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xNDAyMjAxMDAw -MDBaFw0yNDAyMjAxMDAwMDBaMGAxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i -YWxTaWduIG52LXNhMTYwNAYDVQQDEy1HbG9iYWxTaWduIERvbWFpbiBWYWxpZGF0 -aW9uIENBIC0gU0hBMjU2IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQCp3cwOs+IyOd1JIqgTaZOHiOEM7nF9vZCHll1Z8syz0lhXV/lG72wm2DZC -jn4wsy+aPlN7H262okxFHzzTFZMcie089Ffeyr3sBppqKqAZUn9R0XQ5CJ+r69eG -ExWXrjbDVGYOWvKgc4Ux47JkFGr/paKOJLu9hVIVonnu8LXuPbj0fYC82ZA1ZbgX -qa2zmJ+gfn1u+z+tfMIbWTaW2jcyS0tdNQJjjtunz2LuzC7Ujcm9PGqRcqIip3It -INH6yjfaGJjmFiRxJUvE5XuJUgkC/VkrBG7KB4HUs9ra2+PMgKhWBwZ8lgg3nds4 -tmI0kWIHdAE42HIw4uuQcSZiwFfzAgMBAAGjggElMIIBITAOBgNVHQ8BAf8EBAMC -AQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU6k581IAt5RWBhiaMgm3A -mKTPlw8wRwYDVR0gBEAwPjA8BgRVHSAAMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8v -d3d3Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMDMGA1UdHwQsMCowKKAmoCSG -Imh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5uZXQvcm9vdC5jcmwwPQYIKwYBBQUHAQEE -MTAvMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNvbS9yb290 -cjEwHwYDVR0jBBgwFoAUYHtmGkUNl8qJUC99BM00qP/8/UswDQYJKoZIhvcNAQEL -BQADggEBANdFnqDc4ONhWgt9d4QXLWVagpqNoycqhffJ7+mG/dRHzQFSlsVDvTex -4bjyqdKKEYRxkRWJ3AKdC8tsM4U0KJ4gsrGX3G0LEME8zV/qXdeYMcU0mVwAYVXE -GwJbxeOJyLS4bx448lYm6UHvPc2smU9ZSlctS32ux4j71pg79eXw6ImJuYsDy1oj -H6T9uOr7Lp2uanMJvPzVoLVEgqtEkS5QLlfBQ9iRBIvpES5ftD953x77PzAAi1Pj -tywdO02L3ORkHQRYM68bVeerDL8wBHTk8w4vMDmNSwSMHnVmZkngvkA0x1xaUZK6 -EjxS1QSCVS1npd+3lXzuP8MIugS+wEY= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert18[] = { - 0x30, 0x82, 0x04, 0x63, 0x30, 0x82, 0x03, 0x4b, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0x4e, 0xf0, - 0x3e, 0x20, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x57, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, - 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, - 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, - 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x07, 0x52, 0x6f, - 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, - 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, - 0x17, 0x0d, 0x31, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x60, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, - 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, - 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, - 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d, 0x47, - 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x44, 0x6f, - 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x53, 0x48, 0x41, - 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, 0x47, 0x32, 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, 0xa9, 0xdd, 0xcc, 0x0e, 0xb3, 0xe2, 0x32, - 0x39, 0xdd, 0x49, 0x22, 0xa8, 0x13, 0x69, 0x93, 0x87, 0x88, 0xe1, 0x0c, - 0xee, 0x71, 0x7d, 0xbd, 0x90, 0x87, 0x96, 0x5d, 0x59, 0xf2, 0xcc, 0xb3, - 0xd2, 0x58, 0x57, 0x57, 0xf9, 0x46, 0xef, 0x6c, 0x26, 0xd8, 0x36, 0x42, - 0x8e, 0x7e, 0x30, 0xb3, 0x2f, 0x9a, 0x3e, 0x53, 0x7b, 0x1f, 0x6e, 0xb6, - 0xa2, 0x4c, 0x45, 0x1f, 0x3c, 0xd3, 0x15, 0x93, 0x1c, 0x89, 0xed, 0x3c, - 0xf4, 0x57, 0xde, 0xca, 0xbd, 0xec, 0x06, 0x9a, 0x6a, 0x2a, 0xa0, 0x19, - 0x52, 0x7f, 0x51, 0xd1, 0x74, 0x39, 0x08, 0x9f, 0xab, 0xeb, 0xd7, 0x86, - 0x13, 0x15, 0x97, 0xae, 0x36, 0xc3, 0x54, 0x66, 0x0e, 0x5a, 0xf2, 0xa0, - 0x73, 0x85, 0x31, 0xe3, 0xb2, 0x64, 0x14, 0x6a, 0xff, 0xa5, 0xa2, 0x8e, - 0x24, 0xbb, 0xbd, 0x85, 0x52, 0x15, 0xa2, 0x79, 0xee, 0xf0, 0xb5, 0xee, - 0x3d, 0xb8, 0xf4, 0x7d, 0x80, 0xbc, 0xd9, 0x90, 0x35, 0x65, 0xb8, 0x17, - 0xa9, 0xad, 0xb3, 0x98, 0x9f, 0xa0, 0x7e, 0x7d, 0x6e, 0xfb, 0x3f, 0xad, - 0x7c, 0xc2, 0x1b, 0x59, 0x36, 0x96, 0xda, 0x37, 0x32, 0x4b, 0x4b, 0x5d, - 0x35, 0x02, 0x63, 0x8e, 0xdb, 0xa7, 0xcf, 0x62, 0xee, 0xcc, 0x2e, 0xd4, - 0x8d, 0xc9, 0xbd, 0x3c, 0x6a, 0x91, 0x72, 0xa2, 0x22, 0xa7, 0x72, 0x2d, - 0x20, 0xd1, 0xfa, 0xca, 0x37, 0xda, 0x18, 0x98, 0xe6, 0x16, 0x24, 0x71, - 0x25, 0x4b, 0xc4, 0xe5, 0x7b, 0x89, 0x52, 0x09, 0x02, 0xfd, 0x59, 0x2b, - 0x04, 0x6e, 0xca, 0x07, 0x81, 0xd4, 0xb3, 0xda, 0xda, 0xdb, 0xe3, 0xcc, - 0x80, 0xa8, 0x56, 0x07, 0x06, 0x7c, 0x96, 0x08, 0x37, 0x9d, 0xdb, 0x38, - 0xb6, 0x62, 0x34, 0x91, 0x62, 0x07, 0x74, 0x01, 0x38, 0xd8, 0x72, 0x30, - 0xe2, 0xeb, 0x90, 0x71, 0x26, 0x62, 0xc0, 0x57, 0xf3, 0x02, 0x03, 0x01, - 0x00, 0x01, 0xa3, 0x82, 0x01, 0x25, 0x30, 0x82, 0x01, 0x21, 0x30, 0x0e, - 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, - 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, - 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x1d, - 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xea, 0x4e, 0x7c, - 0xd4, 0x80, 0x2d, 0xe5, 0x15, 0x81, 0x86, 0x26, 0x8c, 0x82, 0x6d, 0xc0, - 0x98, 0xa4, 0xcf, 0x97, 0x0f, 0x30, 0x47, 0x06, 0x03, 0x55, 0x1d, 0x20, - 0x04, 0x40, 0x30, 0x3e, 0x30, 0x3c, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, - 0x30, 0x34, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x02, 0x01, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, - 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, - 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, - 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86, - 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, - 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x6e, - 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, - 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, - 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x30, 0x01, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, - 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, - 0x72, 0x31, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, - 0x16, 0x80, 0x14, 0x60, 0x7b, 0x66, 0x1a, 0x45, 0x0d, 0x97, 0xca, 0x89, - 0x50, 0x2f, 0x7d, 0x04, 0xcd, 0x34, 0xa8, 0xff, 0xfc, 0xfd, 0x4b, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, - 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xd7, 0x45, 0x9e, 0xa0, 0xdc, - 0xe0, 0xe3, 0x61, 0x5a, 0x0b, 0x7d, 0x77, 0x84, 0x17, 0x2d, 0x65, 0x5a, - 0x82, 0x9a, 0x8d, 0xa3, 0x27, 0x2a, 0x85, 0xf7, 0xc9, 0xef, 0xe9, 0x86, - 0xfd, 0xd4, 0x47, 0xcd, 0x01, 0x52, 0x96, 0xc5, 0x43, 0xbd, 0x37, 0xb1, - 0xe1, 0xb8, 0xf2, 0xa9, 0xd2, 0x8a, 0x11, 0x84, 0x71, 0x91, 0x15, 0x89, - 0xdc, 0x02, 0x9d, 0x0b, 0xcb, 0x6c, 0x33, 0x85, 0x34, 0x28, 0x9e, 0x20, - 0xb2, 0xb1, 0x97, 0xdc, 0x6d, 0x0b, 0x10, 0xc1, 0x3c, 0xcd, 0x5f, 0xea, - 0x5d, 0xd7, 0x98, 0x31, 0xc5, 0x34, 0x99, 0x5c, 0x00, 0x61, 0x55, 0xc4, - 0x1b, 0x02, 0x5b, 0xc5, 0xe3, 0x89, 0xc8, 0xb4, 0xb8, 0x6f, 0x1e, 0x38, - 0xf2, 0x56, 0x26, 0xe9, 0x41, 0xef, 0x3d, 0xcd, 0xac, 0x99, 0x4f, 0x59, - 0x4a, 0x57, 0x2d, 0x4b, 0x7d, 0xae, 0xc7, 0x88, 0xfb, 0xd6, 0x98, 0x3b, - 0xf5, 0xe5, 0xf0, 0xe8, 0x89, 0x89, 0xb9, 0x8b, 0x03, 0xcb, 0x5a, 0x23, - 0x1f, 0xa4, 0xfd, 0xb8, 0xea, 0xfb, 0x2e, 0x9d, 0xae, 0x6a, 0x73, 0x09, - 0xbc, 0xfc, 0xd5, 0xa0, 0xb5, 0x44, 0x82, 0xab, 0x44, 0x91, 0x2e, 0x50, - 0x2e, 0x57, 0xc1, 0x43, 0xd8, 0x91, 0x04, 0x8b, 0xe9, 0x11, 0x2e, 0x5f, - 0xb4, 0x3f, 0x79, 0xdf, 0x1e, 0xfb, 0x3f, 0x30, 0x00, 0x8b, 0x53, 0xe3, - 0xb7, 0x2c, 0x1d, 0x3b, 0x4d, 0x8b, 0xdc, 0xe4, 0x64, 0x1d, 0x04, 0x58, - 0x33, 0xaf, 0x1b, 0x55, 0xe7, 0xab, 0x0c, 0xbf, 0x30, 0x04, 0x74, 0xe4, - 0xf3, 0x0e, 0x2f, 0x30, 0x39, 0x8d, 0x4b, 0x04, 0x8c, 0x1e, 0x75, 0x66, - 0x66, 0x49, 0xe0, 0xbe, 0x40, 0x34, 0xc7, 0x5c, 0x5a, 0x51, 0x92, 0xba, - 0x12, 0x3c, 0x52, 0xd5, 0x04, 0x82, 0x55, 0x2d, 0x67, 0xa5, 0xdf, 0xb7, - 0x95, 0x7c, 0xee, 0x3f, 0xc3, 0x08, 0xba, 0x04, 0xbe, 0xc0, 0x46, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 04:00:00:00:00:01:44:4e:f0:42:47 - Signature Algorithm: sha256WithRSAEncryption - Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA - Validity - Not Before: Feb 20 10:00:00 2014 GMT - Not After : Feb 20 10:00:00 2024 GMT - Subject: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Organization Validation CA - SHA256 - G2 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:c7:0e:6c:3f:23:93:7f:cc:70:a5:9d:20:c3:0e: - 53:3f:7e:c0:4e:c2:98:49:ca:47:d5:23:ef:03:34: - 85:74:c8:a3:02:2e:46:5c:0b:7d:c9:88:9d:4f:8b: - f0:f8:9c:6c:8c:55:35:db:bf:f2:b3:ea:fb:e3:56: - e7:4a:46:d9:13:22:ca:36:d5:9b:c1:a8:e3:96:43: - 93:f2:0c:bc:e6:f9:e6:e8:99:c8:63:48:78:7f:57: - 36:69:1a:19:1d:5a:d1:d4:7d:c2:9c:d4:7f:e1:80: - 12:ae:7a:ea:88:ea:57:d8:ca:0a:0a:3a:12:49:a2: - 62:19:7a:0d:24:f7:37:eb:b4:73:92:7b:05:23:9b: - 12:b5:ce:eb:29:df:a4:14:02:b9:01:a5:d4:a6:9c: - 43:64:88:de:f8:7e:fe:e3:f5:1e:e5:fe:dc:a3:a8: - e4:66:31:d9:4c:25:e9:18:b9:89:59:09:ae:e9:9d: - 1c:6d:37:0f:4a:1e:35:20:28:e2:af:d4:21:8b:01: - c4:45:ad:6e:2b:63:ab:92:6b:61:0a:4d:20:ed:73: - ba:7c:ce:fe:16:b5:db:9f:80:f0:d6:8b:6c:d9:08: - 79:4a:4f:78:65:da:92:bc:be:35:f9:b3:c4:f9:27: - 80:4e:ff:96:52:e6:02:20:e1:07:73:e9:5d:2b:bd: - b2:f1 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Subject Key Identifier: - 96:DE:61:F1:BD:1C:16:29:53:1C:C0:CC:7D:3B:83:00:40:E6:1A:7C - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://www.globalsign.com/repository/ - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.globalsign.net/root.crl - - Authority Information Access: - OCSP - URI:http://ocsp.globalsign.com/rootr1 - - X509v3 Authority Key Identifier: - keyid:60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B - - Signature Algorithm: sha256WithRSAEncryption - 46:2a:ee:5e:bd:ae:01:60:37:31:11:86:71:74:b6:46:49:c8: - 10:16:fe:2f:62:23:17:ab:1f:87:f8:82:ed:ca:df:0e:2c:df: - 64:75:8e:e5:18:72:a7:8c:3a:8b:c9:ac:a5:77:50:f7:ef:9e: - a4:e0:a0:8f:14:57:a3:2a:5f:ec:7e:6d:10:e6:ba:8d:b0:08: - 87:76:0e:4c:b2:d9:51:bb:11:02:f2:5c:dd:1c:bd:f3:55:96: - 0f:d4:06:c0:fc:e2:23:8a:24:70:d3:bb:f0:79:1a:a7:61:70: - 83:8a:af:06:c5:20:d8:a1:63:d0:6c:ae:4f:32:d7:ae:7c:18: - 45:75:05:29:77:df:42:40:64:64:86:be:2a:76:09:31:6f:1d: - 24:f4:99:d0:85:fe:f2:21:08:f9:c6:f6:f1:d0:59:ed:d6:56: - 3c:08:28:03:67:ba:f0:f9:f1:90:16:47:ae:67:e6:bc:80:48: - e9:42:76:34:97:55:69:24:0e:83:d6:a0:2d:b4:f5:f3:79:8a: - 49:28:74:1a:41:a1:c2:d3:24:88:35:30:60:94:17:b4:e1:04: - 22:31:3d:3b:2f:17:06:b2:b8:9d:86:2b:5a:69:ef:83:f5:4b: - c4:aa:b4:2a:f8:7c:a1:b1:85:94:8c:f4:0c:87:0c:f4:ac:40: - f8:59:49:98 ------BEGIN CERTIFICATE----- -MIIEaTCCA1GgAwIBAgILBAAAAAABRE7wQkcwDQYJKoZIhvcNAQELBQAwVzELMAkG -A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv -b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xNDAyMjAxMDAw -MDBaFw0yNDAyMjAxMDAwMDBaMGYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i -YWxTaWduIG52LXNhMTwwOgYDVQQDEzNHbG9iYWxTaWduIE9yZ2FuaXphdGlvbiBW -YWxpZGF0aW9uIENBIC0gU0hBMjU2IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IB -DwAwggEKAoIBAQDHDmw/I5N/zHClnSDDDlM/fsBOwphJykfVI+8DNIV0yKMCLkZc -C33JiJ1Pi/D4nGyMVTXbv/Kz6vvjVudKRtkTIso21ZvBqOOWQ5PyDLzm+ebomchj -SHh/VzZpGhkdWtHUfcKc1H/hgBKueuqI6lfYygoKOhJJomIZeg0k9zfrtHOSewUj -mxK1zusp36QUArkBpdSmnENkiN74fv7j9R7l/tyjqORmMdlMJekYuYlZCa7pnRxt -Nw9KHjUgKOKv1CGLAcRFrW4rY6uSa2EKTSDtc7p8zv4WtdufgPDWi2zZCHlKT3hl -2pK8vjX5s8T5J4BO/5ZS5gIg4Qdz6V0rvbLxAgMBAAGjggElMIIBITAOBgNVHQ8B -Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUlt5h8b0cFilT -HMDMfTuDAEDmGnwwRwYDVR0gBEAwPjA8BgRVHSAAMDQwMgYIKwYBBQUHAgEWJmh0 -dHBzOi8vd3d3Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMDMGA1UdHwQsMCow -KKAmoCSGImh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5uZXQvcm9vdC5jcmwwPQYIKwYB -BQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNv -bS9yb290cjEwHwYDVR0jBBgwFoAUYHtmGkUNl8qJUC99BM00qP/8/UswDQYJKoZI -hvcNAQELBQADggEBAEYq7l69rgFgNzERhnF0tkZJyBAW/i9iIxerH4f4gu3K3w4s -32R1juUYcqeMOovJrKV3UPfvnqTgoI8UV6MqX+x+bRDmuo2wCId2Dkyy2VG7EQLy -XN0cvfNVlg/UBsD84iOKJHDTu/B5GqdhcIOKrwbFINihY9Bsrk8y1658GEV1BSl3 -30JAZGSGvip2CTFvHST0mdCF/vIhCPnG9vHQWe3WVjwIKANnuvD58ZAWR65n5ryA -SOlCdjSXVWkkDoPWoC209fN5ikkodBpBocLTJIg1MGCUF7ThBCIxPTsvFwayuJ2G -K1pp74P1S8SqtCr4fKGxhZSM9AyHDPSsQPhZSZg= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert19[] = { - 0x30, 0x82, 0x04, 0x69, 0x30, 0x82, 0x03, 0x51, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0x4e, 0xf0, - 0x42, 0x47, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x57, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, - 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, - 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, - 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x07, 0x52, 0x6f, - 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, - 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, - 0x17, 0x0d, 0x31, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x66, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, - 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, - 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, - 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x33, 0x47, - 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x4f, 0x72, - 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x41, - 0x20, 0x2d, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, - 0x47, 0x32, 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, 0xc7, - 0x0e, 0x6c, 0x3f, 0x23, 0x93, 0x7f, 0xcc, 0x70, 0xa5, 0x9d, 0x20, 0xc3, - 0x0e, 0x53, 0x3f, 0x7e, 0xc0, 0x4e, 0xc2, 0x98, 0x49, 0xca, 0x47, 0xd5, - 0x23, 0xef, 0x03, 0x34, 0x85, 0x74, 0xc8, 0xa3, 0x02, 0x2e, 0x46, 0x5c, - 0x0b, 0x7d, 0xc9, 0x88, 0x9d, 0x4f, 0x8b, 0xf0, 0xf8, 0x9c, 0x6c, 0x8c, - 0x55, 0x35, 0xdb, 0xbf, 0xf2, 0xb3, 0xea, 0xfb, 0xe3, 0x56, 0xe7, 0x4a, - 0x46, 0xd9, 0x13, 0x22, 0xca, 0x36, 0xd5, 0x9b, 0xc1, 0xa8, 0xe3, 0x96, - 0x43, 0x93, 0xf2, 0x0c, 0xbc, 0xe6, 0xf9, 0xe6, 0xe8, 0x99, 0xc8, 0x63, - 0x48, 0x78, 0x7f, 0x57, 0x36, 0x69, 0x1a, 0x19, 0x1d, 0x5a, 0xd1, 0xd4, - 0x7d, 0xc2, 0x9c, 0xd4, 0x7f, 0xe1, 0x80, 0x12, 0xae, 0x7a, 0xea, 0x88, - 0xea, 0x57, 0xd8, 0xca, 0x0a, 0x0a, 0x3a, 0x12, 0x49, 0xa2, 0x62, 0x19, - 0x7a, 0x0d, 0x24, 0xf7, 0x37, 0xeb, 0xb4, 0x73, 0x92, 0x7b, 0x05, 0x23, - 0x9b, 0x12, 0xb5, 0xce, 0xeb, 0x29, 0xdf, 0xa4, 0x14, 0x02, 0xb9, 0x01, - 0xa5, 0xd4, 0xa6, 0x9c, 0x43, 0x64, 0x88, 0xde, 0xf8, 0x7e, 0xfe, 0xe3, - 0xf5, 0x1e, 0xe5, 0xfe, 0xdc, 0xa3, 0xa8, 0xe4, 0x66, 0x31, 0xd9, 0x4c, - 0x25, 0xe9, 0x18, 0xb9, 0x89, 0x59, 0x09, 0xae, 0xe9, 0x9d, 0x1c, 0x6d, - 0x37, 0x0f, 0x4a, 0x1e, 0x35, 0x20, 0x28, 0xe2, 0xaf, 0xd4, 0x21, 0x8b, - 0x01, 0xc4, 0x45, 0xad, 0x6e, 0x2b, 0x63, 0xab, 0x92, 0x6b, 0x61, 0x0a, - 0x4d, 0x20, 0xed, 0x73, 0xba, 0x7c, 0xce, 0xfe, 0x16, 0xb5, 0xdb, 0x9f, - 0x80, 0xf0, 0xd6, 0x8b, 0x6c, 0xd9, 0x08, 0x79, 0x4a, 0x4f, 0x78, 0x65, - 0xda, 0x92, 0xbc, 0xbe, 0x35, 0xf9, 0xb3, 0xc4, 0xf9, 0x27, 0x80, 0x4e, - 0xff, 0x96, 0x52, 0xe6, 0x02, 0x20, 0xe1, 0x07, 0x73, 0xe9, 0x5d, 0x2b, - 0xbd, 0xb2, 0xf1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x25, - 0x30, 0x82, 0x01, 0x21, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, - 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, - 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, - 0xff, 0x02, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, - 0x16, 0x04, 0x14, 0x96, 0xde, 0x61, 0xf1, 0xbd, 0x1c, 0x16, 0x29, 0x53, - 0x1c, 0xc0, 0xcc, 0x7d, 0x3b, 0x83, 0x00, 0x40, 0xe6, 0x1a, 0x7c, 0x30, - 0x47, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x40, 0x30, 0x3e, 0x30, 0x3c, - 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x34, 0x30, 0x32, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x26, 0x68, 0x74, - 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6c, - 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, - 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, - 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, - 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f, - 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06, - 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x21, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, - 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x72, 0x31, 0x30, 0x1f, 0x06, 0x03, - 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x60, 0x7b, 0x66, - 0x1a, 0x45, 0x0d, 0x97, 0xca, 0x89, 0x50, 0x2f, 0x7d, 0x04, 0xcd, 0x34, - 0xa8, 0xff, 0xfc, 0xfd, 0x4b, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, - 0x00, 0x46, 0x2a, 0xee, 0x5e, 0xbd, 0xae, 0x01, 0x60, 0x37, 0x31, 0x11, - 0x86, 0x71, 0x74, 0xb6, 0x46, 0x49, 0xc8, 0x10, 0x16, 0xfe, 0x2f, 0x62, - 0x23, 0x17, 0xab, 0x1f, 0x87, 0xf8, 0x82, 0xed, 0xca, 0xdf, 0x0e, 0x2c, - 0xdf, 0x64, 0x75, 0x8e, 0xe5, 0x18, 0x72, 0xa7, 0x8c, 0x3a, 0x8b, 0xc9, - 0xac, 0xa5, 0x77, 0x50, 0xf7, 0xef, 0x9e, 0xa4, 0xe0, 0xa0, 0x8f, 0x14, - 0x57, 0xa3, 0x2a, 0x5f, 0xec, 0x7e, 0x6d, 0x10, 0xe6, 0xba, 0x8d, 0xb0, - 0x08, 0x87, 0x76, 0x0e, 0x4c, 0xb2, 0xd9, 0x51, 0xbb, 0x11, 0x02, 0xf2, - 0x5c, 0xdd, 0x1c, 0xbd, 0xf3, 0x55, 0x96, 0x0f, 0xd4, 0x06, 0xc0, 0xfc, - 0xe2, 0x23, 0x8a, 0x24, 0x70, 0xd3, 0xbb, 0xf0, 0x79, 0x1a, 0xa7, 0x61, - 0x70, 0x83, 0x8a, 0xaf, 0x06, 0xc5, 0x20, 0xd8, 0xa1, 0x63, 0xd0, 0x6c, - 0xae, 0x4f, 0x32, 0xd7, 0xae, 0x7c, 0x18, 0x45, 0x75, 0x05, 0x29, 0x77, - 0xdf, 0x42, 0x40, 0x64, 0x64, 0x86, 0xbe, 0x2a, 0x76, 0x09, 0x31, 0x6f, - 0x1d, 0x24, 0xf4, 0x99, 0xd0, 0x85, 0xfe, 0xf2, 0x21, 0x08, 0xf9, 0xc6, - 0xf6, 0xf1, 0xd0, 0x59, 0xed, 0xd6, 0x56, 0x3c, 0x08, 0x28, 0x03, 0x67, - 0xba, 0xf0, 0xf9, 0xf1, 0x90, 0x16, 0x47, 0xae, 0x67, 0xe6, 0xbc, 0x80, - 0x48, 0xe9, 0x42, 0x76, 0x34, 0x97, 0x55, 0x69, 0x24, 0x0e, 0x83, 0xd6, - 0xa0, 0x2d, 0xb4, 0xf5, 0xf3, 0x79, 0x8a, 0x49, 0x28, 0x74, 0x1a, 0x41, - 0xa1, 0xc2, 0xd3, 0x24, 0x88, 0x35, 0x30, 0x60, 0x94, 0x17, 0xb4, 0xe1, - 0x04, 0x22, 0x31, 0x3d, 0x3b, 0x2f, 0x17, 0x06, 0xb2, 0xb8, 0x9d, 0x86, - 0x2b, 0x5a, 0x69, 0xef, 0x83, 0xf5, 0x4b, 0xc4, 0xaa, 0xb4, 0x2a, 0xf8, - 0x7c, 0xa1, 0xb1, 0x85, 0x94, 0x8c, 0xf4, 0x0c, 0x87, 0x0c, 0xf4, 0xac, - 0x40, 0xf8, 0x59, 0x49, 0x98, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 4d:5f:2c:34:08:b2:4c:20:cd:6d:50:7e:24:4d:c9:ec - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - Validity - Not Before: Feb 8 00:00:00 2010 GMT - Not After : Feb 7 23:59:59 2020 GMT - Subject: C=US, O=Thawte, Inc., CN=Thawte SSL CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:99:e4:85:5b:76:49:7d:2f:05:d8:c5:ac:c8:c8: - a9:d3:dc:98:e6:d7:34:a6:2f:0c:f2:22:26:d8:a3: - c9:14:4c:8f:05:a4:45:e8:14:0c:58:90:05:1a:b7: - c5:c1:06:a5:80:af:bb:1d:49:6b:52:34:88:c3:59: - e7:ef:6b:c4:27:41:8c:2b:66:1d:d0:e0:a3:97:98: - 19:34:4b:41:d5:98:d5:c7:05:ad:a2:e4:d7:ed:0c: - ad:4f:c1:b5:b0:21:fd:3e:50:53:b2:c4:90:d0:d4: - 30:67:6c:9a:f1:0e:74:c4:c2:dc:8a:e8:97:ff:c9: - 92:ae:01:8a:56:0a:98:32:b0:00:23:ec:90:1a:60: - c3:ed:bb:3a:cb:0f:63:9f:0d:44:c9:52:e1:25:96: - bf:ed:50:95:89:7f:56:14:b1:b7:61:1d:1c:07:8c: - 3a:2c:f7:ff:80:de:39:45:d5:af:1a:d1:78:d8:c7: - 71:6a:a3:19:a7:32:50:21:e9:f2:0e:a1:c6:13:03: - 44:48:d1:66:a8:52:57:d7:11:b4:93:8b:e5:99:9f: - 5d:e7:78:51:e5:4d:f6:b7:59:b4:76:b5:09:37:4d: - 06:38:13:7a:1c:08:98:5c:c4:48:4a:cb:52:a0:a9: - f8:b1:9d:8e:7b:79:b0:20:2f:3c:96:a8:11:62:47: - bb:11 - Exponent: 65537 (0x10001) - X509v3 extensions: - Authority Information Access: - OCSP - URI:http://ocsp.thawte.com - - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.thawte.com/ThawtePCA.crl - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Subject Alternative Name: - DirName:/CN=VeriSignMPKI-2-9 - X509v3 Subject Key Identifier: - A7:A2:83:BB:34:45:40:3D:FC:D5:30:4F:12:B9:3E:A1:01:9F:F6:DB - X509v3 Authority Key Identifier: - keyid:7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50 - - Signature Algorithm: sha1WithRSAEncryption - 80:22:80:e0:6c:c8:95:16:d7:57:26:87:f3:72:34:db:c6:72: - 56:27:3e:d3:96:f6:2e:25:91:a5:3e:33:97:a7:4b:e5:2f:fb: - 25:7d:2f:07:61:fa:6f:83:74:4c:4c:53:72:20:a4:7a:cf:51: - 51:56:81:88:b0:6d:1f:36:2c:c8:2b:b1:88:99:c1:fe:44:ab: - 48:51:7c:d8:f2:44:64:2a:d8:71:a7:fb:1a:2f:f9:19:8d:34: - b2:23:bf:c4:4c:55:1d:8e:44:e8:aa:5d:9a:dd:9f:fd:03:c7: - ba:24:43:8d:2d:47:44:db:f6:d8:98:c8:b2:f9:da:ef:ed:29: - 5c:69:12:fa:d1:23:96:0f:bf:9c:0d:f2:79:45:53:37:9a:56: - 2f:e8:57:10:70:f6:ee:89:0c:49:89:9a:c1:23:f5:c2:2a:cc: - 41:cf:22:ab:65:6e:b7:94:82:6d:2f:40:5f:58:de:eb:95:2b: - a6:72:68:52:19:91:2a:ae:75:9d:4e:92:e6:ca:de:54:ea:18: - ab:25:3c:e6:64:a6:79:1f:26:7d:61:ed:7d:d2:e5:71:55:d8: - 93:17:7c:14:38:30:3c:df:86:e3:4c:ad:49:e3:97:59:ce:1b: - 9b:2b:ce:dc:65:d4:0b:28:6b:4e:84:46:51:44:f7:33:08:2d: - 58:97:21:ae ------BEGIN CERTIFICATE----- -MIIEbDCCA1SgAwIBAgIQTV8sNAiyTCDNbVB+JE3J7DANBgkqhkiG9w0BAQUFADCB -qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf -Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw -MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV -BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTAwMjA4MDAwMDAwWhcNMjAw -MjA3MjM1OTU5WjA8MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMVGhhd3RlLCBJbmMu -MRYwFAYDVQQDEw1UaGF3dGUgU1NMIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAmeSFW3ZJfS8F2MWsyMip09yY5tc0pi8M8iIm2KPJFEyPBaRF6BQM -WJAFGrfFwQalgK+7HUlrUjSIw1nn72vEJ0GMK2Yd0OCjl5gZNEtB1ZjVxwWtouTX -7QytT8G1sCH9PlBTssSQ0NQwZ2ya8Q50xMLciuiX/8mSrgGKVgqYMrAAI+yQGmDD -7bs6yw9jnw1EyVLhJZa/7VCViX9WFLG3YR0cB4w6LPf/gN45RdWvGtF42MdxaqMZ -pzJQIenyDqHGEwNESNFmqFJX1xG0k4vlmZ9d53hR5U32t1m0drUJN00GOBN6HAiY -XMRISstSoKn4sZ2Oe3mwIC88lqgRYke7EQIDAQABo4H7MIH4MDIGCCsGAQUFBwEB -BCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL29jc3AudGhhd3RlLmNvbTASBgNVHRMB -Af8ECDAGAQH/AgEAMDQGA1UdHwQtMCswKaAnoCWGI2h0dHA6Ly9jcmwudGhhd3Rl -LmNvbS9UaGF3dGVQQ0EuY3JsMA4GA1UdDwEB/wQEAwIBBjAoBgNVHREEITAfpB0w -GzEZMBcGA1UEAxMQVmVyaVNpZ25NUEtJLTItOTAdBgNVHQ4EFgQUp6KDuzRFQD38 -1TBPErk+oQGf9tswHwYDVR0jBBgwFoAUe1tFz6/Oy3r9MZIaarbzRutXSFAwDQYJ -KoZIhvcNAQEFBQADggEBAIAigOBsyJUW11cmh/NyNNvGclYnPtOW9i4lkaU+M5en -S+Uv+yV9Lwdh+m+DdExMU3IgpHrPUVFWgYiwbR82LMgrsYiZwf5Eq0hRfNjyRGQq -2HGn+xov+RmNNLIjv8RMVR2OROiqXZrdn/0Dx7okQ40tR0Tb9tiYyLL52u/tKVxp -EvrRI5YPv5wN8nlFUzeaVi/oVxBw9u6JDEmJmsEj9cIqzEHPIqtlbreUgm0vQF9Y -3uuVK6ZyaFIZkSqudZ1OkubK3lTqGKslPOZkpnkfJn1h7X3S5XFV2JMXfBQ4MDzf -huNMrUnjl1nOG5srztxl1Asoa06ERlFE9zMILViXIa4= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert20[] = { - 0x30, 0x82, 0x04, 0x6c, 0x30, 0x82, 0x03, 0x54, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x4d, 0x5f, 0x2c, 0x34, 0x08, 0xb2, 0x4c, 0x20, 0xcd, - 0x6d, 0x50, 0x7e, 0x24, 0x4d, 0xc9, 0xec, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, - 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, - 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44, - 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06, - 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, - 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, - 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, - 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, - 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x32, 0x30, 0x38, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30, - 0x32, 0x30, 0x37, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x3c, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, - 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x54, - 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 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, 0x99, 0xe4, 0x85, - 0x5b, 0x76, 0x49, 0x7d, 0x2f, 0x05, 0xd8, 0xc5, 0xac, 0xc8, 0xc8, 0xa9, - 0xd3, 0xdc, 0x98, 0xe6, 0xd7, 0x34, 0xa6, 0x2f, 0x0c, 0xf2, 0x22, 0x26, - 0xd8, 0xa3, 0xc9, 0x14, 0x4c, 0x8f, 0x05, 0xa4, 0x45, 0xe8, 0x14, 0x0c, - 0x58, 0x90, 0x05, 0x1a, 0xb7, 0xc5, 0xc1, 0x06, 0xa5, 0x80, 0xaf, 0xbb, - 0x1d, 0x49, 0x6b, 0x52, 0x34, 0x88, 0xc3, 0x59, 0xe7, 0xef, 0x6b, 0xc4, - 0x27, 0x41, 0x8c, 0x2b, 0x66, 0x1d, 0xd0, 0xe0, 0xa3, 0x97, 0x98, 0x19, - 0x34, 0x4b, 0x41, 0xd5, 0x98, 0xd5, 0xc7, 0x05, 0xad, 0xa2, 0xe4, 0xd7, - 0xed, 0x0c, 0xad, 0x4f, 0xc1, 0xb5, 0xb0, 0x21, 0xfd, 0x3e, 0x50, 0x53, - 0xb2, 0xc4, 0x90, 0xd0, 0xd4, 0x30, 0x67, 0x6c, 0x9a, 0xf1, 0x0e, 0x74, - 0xc4, 0xc2, 0xdc, 0x8a, 0xe8, 0x97, 0xff, 0xc9, 0x92, 0xae, 0x01, 0x8a, - 0x56, 0x0a, 0x98, 0x32, 0xb0, 0x00, 0x23, 0xec, 0x90, 0x1a, 0x60, 0xc3, - 0xed, 0xbb, 0x3a, 0xcb, 0x0f, 0x63, 0x9f, 0x0d, 0x44, 0xc9, 0x52, 0xe1, - 0x25, 0x96, 0xbf, 0xed, 0x50, 0x95, 0x89, 0x7f, 0x56, 0x14, 0xb1, 0xb7, - 0x61, 0x1d, 0x1c, 0x07, 0x8c, 0x3a, 0x2c, 0xf7, 0xff, 0x80, 0xde, 0x39, - 0x45, 0xd5, 0xaf, 0x1a, 0xd1, 0x78, 0xd8, 0xc7, 0x71, 0x6a, 0xa3, 0x19, - 0xa7, 0x32, 0x50, 0x21, 0xe9, 0xf2, 0x0e, 0xa1, 0xc6, 0x13, 0x03, 0x44, - 0x48, 0xd1, 0x66, 0xa8, 0x52, 0x57, 0xd7, 0x11, 0xb4, 0x93, 0x8b, 0xe5, - 0x99, 0x9f, 0x5d, 0xe7, 0x78, 0x51, 0xe5, 0x4d, 0xf6, 0xb7, 0x59, 0xb4, - 0x76, 0xb5, 0x09, 0x37, 0x4d, 0x06, 0x38, 0x13, 0x7a, 0x1c, 0x08, 0x98, - 0x5c, 0xc4, 0x48, 0x4a, 0xcb, 0x52, 0xa0, 0xa9, 0xf8, 0xb1, 0x9d, 0x8e, - 0x7b, 0x79, 0xb0, 0x20, 0x2f, 0x3c, 0x96, 0xa8, 0x11, 0x62, 0x47, 0xbb, - 0x11, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xfb, 0x30, 0x81, 0xf8, - 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, - 0x04, 0x26, 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, - 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, - 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, - 0x30, 0x34, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2d, 0x30, 0x2b, 0x30, - 0x29, 0xa0, 0x27, 0xa0, 0x25, 0x86, 0x23, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, - 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, - 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x28, - 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x21, 0x30, 0x1f, 0xa4, 0x1d, 0x30, - 0x1b, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, - 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49, - 0x2d, 0x32, 0x2d, 0x39, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, - 0x16, 0x04, 0x14, 0xa7, 0xa2, 0x83, 0xbb, 0x34, 0x45, 0x40, 0x3d, 0xfc, - 0xd5, 0x30, 0x4f, 0x12, 0xb9, 0x3e, 0xa1, 0x01, 0x9f, 0xf6, 0xdb, 0x30, - 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, - 0x7b, 0x5b, 0x45, 0xcf, 0xaf, 0xce, 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a, - 0x6a, 0xb6, 0xf3, 0x46, 0xeb, 0x57, 0x48, 0x50, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, - 0x82, 0x01, 0x01, 0x00, 0x80, 0x22, 0x80, 0xe0, 0x6c, 0xc8, 0x95, 0x16, - 0xd7, 0x57, 0x26, 0x87, 0xf3, 0x72, 0x34, 0xdb, 0xc6, 0x72, 0x56, 0x27, - 0x3e, 0xd3, 0x96, 0xf6, 0x2e, 0x25, 0x91, 0xa5, 0x3e, 0x33, 0x97, 0xa7, - 0x4b, 0xe5, 0x2f, 0xfb, 0x25, 0x7d, 0x2f, 0x07, 0x61, 0xfa, 0x6f, 0x83, - 0x74, 0x4c, 0x4c, 0x53, 0x72, 0x20, 0xa4, 0x7a, 0xcf, 0x51, 0x51, 0x56, - 0x81, 0x88, 0xb0, 0x6d, 0x1f, 0x36, 0x2c, 0xc8, 0x2b, 0xb1, 0x88, 0x99, - 0xc1, 0xfe, 0x44, 0xab, 0x48, 0x51, 0x7c, 0xd8, 0xf2, 0x44, 0x64, 0x2a, - 0xd8, 0x71, 0xa7, 0xfb, 0x1a, 0x2f, 0xf9, 0x19, 0x8d, 0x34, 0xb2, 0x23, - 0xbf, 0xc4, 0x4c, 0x55, 0x1d, 0x8e, 0x44, 0xe8, 0xaa, 0x5d, 0x9a, 0xdd, - 0x9f, 0xfd, 0x03, 0xc7, 0xba, 0x24, 0x43, 0x8d, 0x2d, 0x47, 0x44, 0xdb, - 0xf6, 0xd8, 0x98, 0xc8, 0xb2, 0xf9, 0xda, 0xef, 0xed, 0x29, 0x5c, 0x69, - 0x12, 0xfa, 0xd1, 0x23, 0x96, 0x0f, 0xbf, 0x9c, 0x0d, 0xf2, 0x79, 0x45, - 0x53, 0x37, 0x9a, 0x56, 0x2f, 0xe8, 0x57, 0x10, 0x70, 0xf6, 0xee, 0x89, - 0x0c, 0x49, 0x89, 0x9a, 0xc1, 0x23, 0xf5, 0xc2, 0x2a, 0xcc, 0x41, 0xcf, - 0x22, 0xab, 0x65, 0x6e, 0xb7, 0x94, 0x82, 0x6d, 0x2f, 0x40, 0x5f, 0x58, - 0xde, 0xeb, 0x95, 0x2b, 0xa6, 0x72, 0x68, 0x52, 0x19, 0x91, 0x2a, 0xae, - 0x75, 0x9d, 0x4e, 0x92, 0xe6, 0xca, 0xde, 0x54, 0xea, 0x18, 0xab, 0x25, - 0x3c, 0xe6, 0x64, 0xa6, 0x79, 0x1f, 0x26, 0x7d, 0x61, 0xed, 0x7d, 0xd2, - 0xe5, 0x71, 0x55, 0xd8, 0x93, 0x17, 0x7c, 0x14, 0x38, 0x30, 0x3c, 0xdf, - 0x86, 0xe3, 0x4c, 0xad, 0x49, 0xe3, 0x97, 0x59, 0xce, 0x1b, 0x9b, 0x2b, - 0xce, 0xdc, 0x65, 0xd4, 0x0b, 0x28, 0x6b, 0x4e, 0x84, 0x46, 0x51, 0x44, - 0xf7, 0x33, 0x08, 0x2d, 0x58, 0x97, 0x21, 0xae, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 1828629 (0x1be715) - Signature Algorithm: sha256WithRSAEncryption - Issuer: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority - Validity - Not Before: Jan 1 07:00:00 2014 GMT - Not After : May 30 07:00:00 2031 GMT - Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:bf:71:62:08:f1:fa:59:34:f7:1b:c9:18:a3:f7: - 80:49:58:e9:22:83:13:a6:c5:20:43:01:3b:84:f1: - e6:85:49:9f:27:ea:f6:84:1b:4e:a0:b4:db:70:98: - c7:32:01:b1:05:3e:07:4e:ee:f4:fa:4f:2f:59:30: - 22:e7:ab:19:56:6b:e2:80:07:fc:f3:16:75:80:39: - 51:7b:e5:f9:35:b6:74:4e:a9:8d:82:13:e4:b6:3f: - a9:03:83:fa:a2:be:8a:15:6a:7f:de:0b:c3:b6:19: - 14:05:ca:ea:c3:a8:04:94:3b:46:7c:32:0d:f3:00: - 66:22:c8:8d:69:6d:36:8c:11:18:b7:d3:b2:1c:60: - b4:38:fa:02:8c:ce:d3:dd:46:07:de:0a:3e:eb:5d: - 7c:c8:7c:fb:b0:2b:53:a4:92:62:69:51:25:05:61: - 1a:44:81:8c:2c:a9:43:96:23:df:ac:3a:81:9a:0e: - 29:c5:1c:a9:e9:5d:1e:b6:9e:9e:30:0a:39:ce:f1: - 88:80:fb:4b:5d:cc:32:ec:85:62:43:25:34:02:56: - 27:01:91:b4:3b:70:2a:3f:6e:b1:e8:9c:88:01:7d: - 9f:d4:f9:db:53:6d:60:9d:bf:2c:e7:58:ab:b8:5f: - 46:fc:ce:c4:1b:03:3c:09:eb:49:31:5c:69:46:b3: - e0:47 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Subject Key Identifier: - 3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE - X509v3 Authority Key Identifier: - keyid:D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3 - - Authority Information Access: - OCSP - URI:http://ocsp.godaddy.com/ - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.godaddy.com/gdroot.crl - - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://certs.godaddy.com/repository/ - - Signature Algorithm: sha256WithRSAEncryption - 59:0b:53:bd:92:86:11:a7:24:7b:ed:5b:31:cf:1d:1f:6c:70: - c5:b8:6e:be:4e:bb:f6:be:97:50:e1:30:7f:ba:28:5c:62:94: - c2:e3:7e:33:f7:fb:42:76:85:db:95:1c:8c:22:58:75:09:0c: - 88:65:67:39:0a:16:09:c5:a0:38:97:a4:c5:23:93:3f:b4:18: - a6:01:06:44:91:e3:a7:69:27:b4:5a:25:7f:3a:b7:32:cd:dd: - 84:ff:2a:38:29:33:a4:dd:67:b2:85:fe:a1:88:20:1c:50:89: - c8:dc:2a:f6:42:03:37:4c:e6:88:df:d5:af:24:f2:b1:c3:df: - cc:b5:ec:e0:99:5e:b7:49:54:20:3c:94:18:0c:c7:1c:52:18: - 49:a4:6d:e1:b3:58:0b:c9:d8:ec:d9:ae:1c:32:8e:28:70:0d: - e2:fe:a6:17:9e:84:0f:bd:57:70:b3:5a:e9:1f:a0:86:53:bb: - ef:7c:ff:69:0b:e0:48:c3:b7:93:0b:c8:0a:54:c4:ac:5d:14: - 67:37:6c:ca:a5:2f:31:08:37:aa:6e:6f:8c:bc:9b:e2:57:5d: - 24:81:af:97:97:9c:84:ad:6c:ac:37:4c:66:f3:61:91:11:20: - e4:be:30:9f:7a:a4:29:09:b0:e1:34:5f:64:77:18:40:51:df: - 8c:30:a6:af ------BEGIN CERTIFICATE----- -MIIEfTCCA2WgAwIBAgIDG+cVMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNVBAYTAlVT -MSEwHwYDVQQKExhUaGUgR28gRGFkZHkgR3JvdXAsIEluYy4xMTAvBgNVBAsTKEdv -IERhZGR5IENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQwMTAx -MDcwMDAwWhcNMzEwNTMwMDcwMDAwWjCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT -B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHku -Y29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1 -dGhvcml0eSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv3Fi -CPH6WTT3G8kYo/eASVjpIoMTpsUgQwE7hPHmhUmfJ+r2hBtOoLTbcJjHMgGxBT4H -Tu70+k8vWTAi56sZVmvigAf88xZ1gDlRe+X5NbZ0TqmNghPktj+pA4P6or6KFWp/ -3gvDthkUBcrqw6gElDtGfDIN8wBmIsiNaW02jBEYt9OyHGC0OPoCjM7T3UYH3go+ -6118yHz7sCtTpJJiaVElBWEaRIGMLKlDliPfrDqBmg4pxRyp6V0etp6eMAo5zvGI -gPtLXcwy7IViQyU0AlYnAZG0O3AqP26x6JyIAX2f1PnbU21gnb8s51iruF9G/M7E -GwM8CetJMVxpRrPgRwIDAQABo4IBFzCCARMwDwYDVR0TAQH/BAUwAwEB/zAOBgNV -HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9BUFuIMGU2g/eMB8GA1Ud -IwQYMBaAFNLEsNKR1EwRcbNhyz2h/t2oatTjMDQGCCsGAQUFBwEBBCgwJjAkBggr -BgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRkeS5jb20vMDIGA1UdHwQrMCkwJ6Al -oCOGIWh0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Ryb290LmNybDBGBgNVHSAEPzA9 -MDsGBFUdIAAwMzAxBggrBgEFBQcCARYlaHR0cHM6Ly9jZXJ0cy5nb2RhZGR5LmNv -bS9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEAWQtTvZKGEacke+1bMc8d -H2xwxbhuvk679r6XUOEwf7ooXGKUwuN+M/f7QnaF25UcjCJYdQkMiGVnOQoWCcWg -OJekxSOTP7QYpgEGRJHjp2kntFolfzq3Ms3dhP8qOCkzpN1nsoX+oYggHFCJyNwq -9kIDN0zmiN/VryTyscPfzLXs4Jlet0lUIDyUGAzHHFIYSaRt4bNYC8nY7NmuHDKO -KHAN4v6mF56ED71XcLNa6R+ghlO773z/aQvgSMO3kwvIClTErF0UZzdsyqUvMQg3 -qm5vjLyb4lddJIGvl5echK1srDdMZvNhkREg5L4wn3qkKQmw4TRfZHcYQFHfjDCm -rw== ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert21[] = { - 0x30, 0x82, 0x04, 0x7d, 0x30, 0x82, 0x03, 0x65, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x03, 0x1b, 0xe7, 0x15, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x63, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, - 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x54, - 0x68, 0x65, 0x20, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, - 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x28, 0x47, 0x6f, - 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, - 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x31, 0x30, 0x31, - 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x31, 0x30, - 0x35, 0x33, 0x30, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x81, - 0x83, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, - 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, - 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 0x2e, - 0x63, 0x6f, 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30, - 0x2f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, 0x47, 0x6f, 0x20, 0x44, - 0x61, 0x64, 0x64, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, - 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, 0xbf, 0x71, 0x62, - 0x08, 0xf1, 0xfa, 0x59, 0x34, 0xf7, 0x1b, 0xc9, 0x18, 0xa3, 0xf7, 0x80, - 0x49, 0x58, 0xe9, 0x22, 0x83, 0x13, 0xa6, 0xc5, 0x20, 0x43, 0x01, 0x3b, - 0x84, 0xf1, 0xe6, 0x85, 0x49, 0x9f, 0x27, 0xea, 0xf6, 0x84, 0x1b, 0x4e, - 0xa0, 0xb4, 0xdb, 0x70, 0x98, 0xc7, 0x32, 0x01, 0xb1, 0x05, 0x3e, 0x07, - 0x4e, 0xee, 0xf4, 0xfa, 0x4f, 0x2f, 0x59, 0x30, 0x22, 0xe7, 0xab, 0x19, - 0x56, 0x6b, 0xe2, 0x80, 0x07, 0xfc, 0xf3, 0x16, 0x75, 0x80, 0x39, 0x51, - 0x7b, 0xe5, 0xf9, 0x35, 0xb6, 0x74, 0x4e, 0xa9, 0x8d, 0x82, 0x13, 0xe4, - 0xb6, 0x3f, 0xa9, 0x03, 0x83, 0xfa, 0xa2, 0xbe, 0x8a, 0x15, 0x6a, 0x7f, - 0xde, 0x0b, 0xc3, 0xb6, 0x19, 0x14, 0x05, 0xca, 0xea, 0xc3, 0xa8, 0x04, - 0x94, 0x3b, 0x46, 0x7c, 0x32, 0x0d, 0xf3, 0x00, 0x66, 0x22, 0xc8, 0x8d, - 0x69, 0x6d, 0x36, 0x8c, 0x11, 0x18, 0xb7, 0xd3, 0xb2, 0x1c, 0x60, 0xb4, - 0x38, 0xfa, 0x02, 0x8c, 0xce, 0xd3, 0xdd, 0x46, 0x07, 0xde, 0x0a, 0x3e, - 0xeb, 0x5d, 0x7c, 0xc8, 0x7c, 0xfb, 0xb0, 0x2b, 0x53, 0xa4, 0x92, 0x62, - 0x69, 0x51, 0x25, 0x05, 0x61, 0x1a, 0x44, 0x81, 0x8c, 0x2c, 0xa9, 0x43, - 0x96, 0x23, 0xdf, 0xac, 0x3a, 0x81, 0x9a, 0x0e, 0x29, 0xc5, 0x1c, 0xa9, - 0xe9, 0x5d, 0x1e, 0xb6, 0x9e, 0x9e, 0x30, 0x0a, 0x39, 0xce, 0xf1, 0x88, - 0x80, 0xfb, 0x4b, 0x5d, 0xcc, 0x32, 0xec, 0x85, 0x62, 0x43, 0x25, 0x34, - 0x02, 0x56, 0x27, 0x01, 0x91, 0xb4, 0x3b, 0x70, 0x2a, 0x3f, 0x6e, 0xb1, - 0xe8, 0x9c, 0x88, 0x01, 0x7d, 0x9f, 0xd4, 0xf9, 0xdb, 0x53, 0x6d, 0x60, - 0x9d, 0xbf, 0x2c, 0xe7, 0x58, 0xab, 0xb8, 0x5f, 0x46, 0xfc, 0xce, 0xc4, - 0x1b, 0x03, 0x3c, 0x09, 0xeb, 0x49, 0x31, 0x5c, 0x69, 0x46, 0xb3, 0xe0, - 0x47, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x17, 0x30, 0x82, - 0x01, 0x13, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, - 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, - 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, - 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3a, 0x9a, - 0x85, 0x07, 0x10, 0x67, 0x28, 0xb6, 0xef, 0xf6, 0xbd, 0x05, 0x41, 0x6e, - 0x20, 0xc1, 0x94, 0xda, 0x0f, 0xde, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, - 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xd2, 0xc4, 0xb0, 0xd2, 0x91, - 0xd4, 0x4c, 0x11, 0x71, 0xb3, 0x61, 0xcb, 0x3d, 0xa1, 0xfe, 0xdd, 0xa8, - 0x6a, 0xd4, 0xe3, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64, - 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x32, 0x06, - 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2b, 0x30, 0x29, 0x30, 0x27, 0xa0, 0x25, - 0xa0, 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, - 0x72, 0x6c, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x67, 0x64, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, - 0x6c, 0x30, 0x46, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, - 0x30, 0x3b, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x33, 0x30, 0x31, - 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, - 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, - 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x2f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x59, 0x0b, 0x53, - 0xbd, 0x92, 0x86, 0x11, 0xa7, 0x24, 0x7b, 0xed, 0x5b, 0x31, 0xcf, 0x1d, - 0x1f, 0x6c, 0x70, 0xc5, 0xb8, 0x6e, 0xbe, 0x4e, 0xbb, 0xf6, 0xbe, 0x97, - 0x50, 0xe1, 0x30, 0x7f, 0xba, 0x28, 0x5c, 0x62, 0x94, 0xc2, 0xe3, 0x7e, - 0x33, 0xf7, 0xfb, 0x42, 0x76, 0x85, 0xdb, 0x95, 0x1c, 0x8c, 0x22, 0x58, - 0x75, 0x09, 0x0c, 0x88, 0x65, 0x67, 0x39, 0x0a, 0x16, 0x09, 0xc5, 0xa0, - 0x38, 0x97, 0xa4, 0xc5, 0x23, 0x93, 0x3f, 0xb4, 0x18, 0xa6, 0x01, 0x06, - 0x44, 0x91, 0xe3, 0xa7, 0x69, 0x27, 0xb4, 0x5a, 0x25, 0x7f, 0x3a, 0xb7, - 0x32, 0xcd, 0xdd, 0x84, 0xff, 0x2a, 0x38, 0x29, 0x33, 0xa4, 0xdd, 0x67, - 0xb2, 0x85, 0xfe, 0xa1, 0x88, 0x20, 0x1c, 0x50, 0x89, 0xc8, 0xdc, 0x2a, - 0xf6, 0x42, 0x03, 0x37, 0x4c, 0xe6, 0x88, 0xdf, 0xd5, 0xaf, 0x24, 0xf2, - 0xb1, 0xc3, 0xdf, 0xcc, 0xb5, 0xec, 0xe0, 0x99, 0x5e, 0xb7, 0x49, 0x54, - 0x20, 0x3c, 0x94, 0x18, 0x0c, 0xc7, 0x1c, 0x52, 0x18, 0x49, 0xa4, 0x6d, - 0xe1, 0xb3, 0x58, 0x0b, 0xc9, 0xd8, 0xec, 0xd9, 0xae, 0x1c, 0x32, 0x8e, - 0x28, 0x70, 0x0d, 0xe2, 0xfe, 0xa6, 0x17, 0x9e, 0x84, 0x0f, 0xbd, 0x57, - 0x70, 0xb3, 0x5a, 0xe9, 0x1f, 0xa0, 0x86, 0x53, 0xbb, 0xef, 0x7c, 0xff, - 0x69, 0x0b, 0xe0, 0x48, 0xc3, 0xb7, 0x93, 0x0b, 0xc8, 0x0a, 0x54, 0xc4, - 0xac, 0x5d, 0x14, 0x67, 0x37, 0x6c, 0xca, 0xa5, 0x2f, 0x31, 0x08, 0x37, - 0xaa, 0x6e, 0x6f, 0x8c, 0xbc, 0x9b, 0xe2, 0x57, 0x5d, 0x24, 0x81, 0xaf, - 0x97, 0x97, 0x9c, 0x84, 0xad, 0x6c, 0xac, 0x37, 0x4c, 0x66, 0xf3, 0x61, - 0x91, 0x11, 0x20, 0xe4, 0xbe, 0x30, 0x9f, 0x7a, 0xa4, 0x29, 0x09, 0xb0, - 0xe1, 0x34, 0x5f, 0x64, 0x77, 0x18, 0x40, 0x51, 0xdf, 0x8c, 0x30, 0xa6, - 0xaf, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 06:9e:1d:b7:7f:cf:1d:fb:a9:7a:f5:e5:c9:a2:40:37 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA - Validity - Not Before: Mar 8 12:00:00 2013 GMT - Not After : Mar 8 12:00:00 2023 GMT - Subject: C=US, O=DigiCert Inc, CN=DigiCert Secure Server CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:bb:57:e4:21:a9:d5:9b:60:37:7e:8e:a1:61:7f: - 81:e2:1a:c2:75:64:d9:91:50:0b:e4:36:44:24:6e: - 30:d2:9b:7a:27:fa:c2:6a:ae:6a:70:09:38:b9:20: - 0a:c8:65:10:4a:88:ac:31:f2:dc:92:f2:63:a1:5d: - 80:63:59:80:92:23:1c:e6:ef:76:4a:50:35:c9:d8: - 71:38:b9:ed:f0:e6:42:ae:d3:38:26:79:30:f9:22: - 94:c6:db:a6:3f:41:78:90:d8:de:5c:7e:69:7d:f8: - 90:15:3a:d0:a1:a0:be:fa:b2:b2:19:a1:d8:2b:d1: - ce:bf:6b:dd:49:ab:a3:92:fe:b5:ab:c8:c1:3e:ee: - 01:00:d8:a9:44:b8:42:73:88:c3:61:f5:ab:4a:83: - 28:0a:d2:d4:49:fa:6a:b1:cd:df:57:2c:94:e5:e2: - ca:83:5f:b7:ba:62:5c:2f:68:a5:f0:c0:b9:fd:2b: - d1:e9:1f:d8:1a:62:15:bd:ff:3d:a6:f7:cb:ef:e6: - db:65:2f:25:38:ec:fb:e6:20:66:58:96:34:19:d2: - 15:ce:21:d3:24:cc:d9:14:6f:d8:fe:55:c7:e7:6f: - b6:0f:1a:8c:49:be:29:f2:ba:5a:9a:81:26:37:24: - 6f:d7:48:12:6c:2e:59:f5:9c:18:bb:d9:f6:68:e2: - df:45 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Key Usage: critical - Digital Signature, Certificate Sign, CRL Sign - Authority Information Access: - OCSP - URI:http://ocsp.digicert.com - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl3.digicert.com/DigiCertGlobalRootCA.crl - - Full Name: - URI:http://crl4.digicert.com/DigiCertGlobalRootCA.crl - - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://www.digicert.com/CPS - - X509v3 Subject Key Identifier: - 90:71:DB:37:EB:73:C8:EF:DC:D5:1E:12:B6:34:BA:2B:5A:A0:A6:92 - X509v3 Authority Key Identifier: - keyid:03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55 - - Signature Algorithm: sha1WithRSAEncryption - 30:ce:d1:95:51:00:ae:06:0b:a1:0e:02:c0:17:ac:b6:7f:8f: - 20:f6:40:75:74:1c:cc:78:b1:a4:4f:ea:f4:d0:c4:9d:a2:de: - 81:07:26:1f:40:88:51:f0:1f:cf:b7:4c:40:99:d0:f4:3c:71: - 98:73:88:97:2c:19:d7:6e:84:8f:a4:1f:9c:5a:20:e3:51:5c: - b0:c5:9e:99:6a:4f:c8:69:f7:10:ff:4e:ad:19:d9:c9:58:b3: - 33:ae:0c:d9:96:29:9e:71:b2:70:63:a3:b6:99:16:42:1d:65: - f3:f7:a0:1e:7d:c5:d4:65:14:b2:62:84:d4:6c:5c:08:0c:d8: - 6c:93:2b:b4:76:59:8a:d1:7f:ff:03:d8:c2:5d:b8:2f:22:d6: - 38:f0:f6:9c:6b:7d:46:eb:99:74:f7:eb:4a:0e:a9:a6:04:eb: - 7b:ce:f0:5c:6b:98:31:5a:98:40:eb:69:c4:05:f4:20:a8:ca: - 08:3a:65:6c:38:15:f5:5c:2c:b2:55:e4:2c:6b:41:f0:be:5c: - 46:ca:4a:29:a0:48:5e:20:d2:45:ff:05:de:34:af:70:4b:81: - 39:e2:ca:07:57:7c:b6:31:dc:21:29:e2:be:97:0e:77:90:14: - 51:40:e1:bf:e3:cc:1b:19:9c:25:ca:a7:06:b2:53:df:23:b2: - cf:12:19:a3 ------BEGIN CERTIFICATE----- -MIIEjzCCA3egAwIBAgIQBp4dt3/PHfupevXlyaJANzANBgkqhkiG9w0BAQUFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD -QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaMEgxCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxIjAgBgNVBAMTGURpZ2lDZXJ0IFNlY3Vy -ZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7V+Qh -qdWbYDd+jqFhf4HiGsJ1ZNmRUAvkNkQkbjDSm3on+sJqrmpwCTi5IArIZRBKiKwx -8tyS8mOhXYBjWYCSIxzm73ZKUDXJ2HE4ue3w5kKu0zgmeTD5IpTG26Y/QXiQ2N5c -fml9+JAVOtChoL76srIZodgr0c6/a91Jq6OS/rWryME+7gEA2KlEuEJziMNh9atK -gygK0tRJ+mqxzd9XLJTl4sqDX7e6YlwvaKXwwLn9K9HpH9gaYhW9/z2m98vv5ttl -LyU47PvmIGZYljQZ0hXOIdMkzNkUb9j+Vcfnb7YPGoxJvinyulqagSY3JG/XSBJs -Lln1nBi72fZo4t9FAgMBAAGjggFaMIIBVjASBgNVHRMBAf8ECDAGAQH/AgEAMA4G -A1UdDwEB/wQEAwIBhjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6 -Ly9vY3NwLmRpZ2ljZXJ0LmNvbTB7BgNVHR8EdDByMDegNaAzhjFodHRwOi8vY3Js -My5kaWdpY2VydC5jb20vRGlnaUNlcnRHbG9iYWxSb290Q0EuY3JsMDegNaAzhjFo -dHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRHbG9iYWxSb290Q0EuY3Js -MD0GA1UdIAQ2MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5k -aWdpY2VydC5jb20vQ1BTMB0GA1UdDgQWBBSQcds363PI79zVHhK2NLorWqCmkjAf -BgNVHSMEGDAWgBQD3lA1VtFMu2bwo+IbG8OXsj3RVTANBgkqhkiG9w0BAQUFAAOC -AQEAMM7RlVEArgYLoQ4CwBestn+PIPZAdXQczHixpE/q9NDEnaLegQcmH0CIUfAf -z7dMQJnQ9DxxmHOIlywZ126Ej6QfnFog41FcsMWemWpPyGn3EP9OrRnZyVizM64M -2ZYpnnGycGOjtpkWQh1l8/egHn3F1GUUsmKE1GxcCAzYbJMrtHZZitF//wPYwl24 -LyLWOPD2nGt9RuuZdPfrSg6ppgTre87wXGuYMVqYQOtpxAX0IKjKCDplbDgV9Vws -slXkLGtB8L5cRspKKaBIXiDSRf8F3jSvcEuBOeLKB1d8tjHcISnivpcOd5AUUUDh -v+PMGxmcJcqnBrJT3yOyzxIZow== ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert22[] = { - 0x30, 0x82, 0x04, 0x8f, 0x30, 0x82, 0x03, 0x77, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x06, 0x9e, 0x1d, 0xb7, 0x7f, 0xcf, 0x1d, 0xfb, 0xa9, - 0x7a, 0xf5, 0xe5, 0xc9, 0xa2, 0x40, 0x37, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x61, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, - 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, - 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, - 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, - 0x63, 0x6f, 0x6d, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x47, - 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, - 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x33, 0x30, 0x38, 0x31, - 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x33, - 0x30, 0x38, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x48, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, - 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44, - 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, - 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x44, 0x69, - 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, - 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 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, 0xbb, 0x57, 0xe4, 0x21, - 0xa9, 0xd5, 0x9b, 0x60, 0x37, 0x7e, 0x8e, 0xa1, 0x61, 0x7f, 0x81, 0xe2, - 0x1a, 0xc2, 0x75, 0x64, 0xd9, 0x91, 0x50, 0x0b, 0xe4, 0x36, 0x44, 0x24, - 0x6e, 0x30, 0xd2, 0x9b, 0x7a, 0x27, 0xfa, 0xc2, 0x6a, 0xae, 0x6a, 0x70, - 0x09, 0x38, 0xb9, 0x20, 0x0a, 0xc8, 0x65, 0x10, 0x4a, 0x88, 0xac, 0x31, - 0xf2, 0xdc, 0x92, 0xf2, 0x63, 0xa1, 0x5d, 0x80, 0x63, 0x59, 0x80, 0x92, - 0x23, 0x1c, 0xe6, 0xef, 0x76, 0x4a, 0x50, 0x35, 0xc9, 0xd8, 0x71, 0x38, - 0xb9, 0xed, 0xf0, 0xe6, 0x42, 0xae, 0xd3, 0x38, 0x26, 0x79, 0x30, 0xf9, - 0x22, 0x94, 0xc6, 0xdb, 0xa6, 0x3f, 0x41, 0x78, 0x90, 0xd8, 0xde, 0x5c, - 0x7e, 0x69, 0x7d, 0xf8, 0x90, 0x15, 0x3a, 0xd0, 0xa1, 0xa0, 0xbe, 0xfa, - 0xb2, 0xb2, 0x19, 0xa1, 0xd8, 0x2b, 0xd1, 0xce, 0xbf, 0x6b, 0xdd, 0x49, - 0xab, 0xa3, 0x92, 0xfe, 0xb5, 0xab, 0xc8, 0xc1, 0x3e, 0xee, 0x01, 0x00, - 0xd8, 0xa9, 0x44, 0xb8, 0x42, 0x73, 0x88, 0xc3, 0x61, 0xf5, 0xab, 0x4a, - 0x83, 0x28, 0x0a, 0xd2, 0xd4, 0x49, 0xfa, 0x6a, 0xb1, 0xcd, 0xdf, 0x57, - 0x2c, 0x94, 0xe5, 0xe2, 0xca, 0x83, 0x5f, 0xb7, 0xba, 0x62, 0x5c, 0x2f, - 0x68, 0xa5, 0xf0, 0xc0, 0xb9, 0xfd, 0x2b, 0xd1, 0xe9, 0x1f, 0xd8, 0x1a, - 0x62, 0x15, 0xbd, 0xff, 0x3d, 0xa6, 0xf7, 0xcb, 0xef, 0xe6, 0xdb, 0x65, - 0x2f, 0x25, 0x38, 0xec, 0xfb, 0xe6, 0x20, 0x66, 0x58, 0x96, 0x34, 0x19, - 0xd2, 0x15, 0xce, 0x21, 0xd3, 0x24, 0xcc, 0xd9, 0x14, 0x6f, 0xd8, 0xfe, - 0x55, 0xc7, 0xe7, 0x6f, 0xb6, 0x0f, 0x1a, 0x8c, 0x49, 0xbe, 0x29, 0xf2, - 0xba, 0x5a, 0x9a, 0x81, 0x26, 0x37, 0x24, 0x6f, 0xd7, 0x48, 0x12, 0x6c, - 0x2e, 0x59, 0xf5, 0x9c, 0x18, 0xbb, 0xd9, 0xf6, 0x68, 0xe2, 0xdf, 0x45, - 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x5a, 0x30, 0x82, 0x01, - 0x56, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, - 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, - 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, - 0x86, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, - 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, - 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x7b, 0x06, 0x03, 0x55, - 0x1d, 0x1f, 0x04, 0x74, 0x30, 0x72, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33, - 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, - 0x33, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x47, - 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e, - 0x63, 0x72, 0x6c, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33, 0x86, 0x31, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x34, 0x2e, 0x64, - 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x47, 0x6c, 0x6f, 0x62, - 0x61, 0x6c, 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, - 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30, - 0x32, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06, - 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, - 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x64, - 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x43, 0x50, 0x53, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, - 0x04, 0x14, 0x90, 0x71, 0xdb, 0x37, 0xeb, 0x73, 0xc8, 0xef, 0xdc, 0xd5, - 0x1e, 0x12, 0xb6, 0x34, 0xba, 0x2b, 0x5a, 0xa0, 0xa6, 0x92, 0x30, 0x1f, - 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x03, - 0xde, 0x50, 0x35, 0x56, 0xd1, 0x4c, 0xbb, 0x66, 0xf0, 0xa3, 0xe2, 0x1b, - 0x1b, 0xc3, 0x97, 0xb2, 0x3d, 0xd1, 0x55, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, - 0x01, 0x01, 0x00, 0x30, 0xce, 0xd1, 0x95, 0x51, 0x00, 0xae, 0x06, 0x0b, - 0xa1, 0x0e, 0x02, 0xc0, 0x17, 0xac, 0xb6, 0x7f, 0x8f, 0x20, 0xf6, 0x40, - 0x75, 0x74, 0x1c, 0xcc, 0x78, 0xb1, 0xa4, 0x4f, 0xea, 0xf4, 0xd0, 0xc4, - 0x9d, 0xa2, 0xde, 0x81, 0x07, 0x26, 0x1f, 0x40, 0x88, 0x51, 0xf0, 0x1f, - 0xcf, 0xb7, 0x4c, 0x40, 0x99, 0xd0, 0xf4, 0x3c, 0x71, 0x98, 0x73, 0x88, - 0x97, 0x2c, 0x19, 0xd7, 0x6e, 0x84, 0x8f, 0xa4, 0x1f, 0x9c, 0x5a, 0x20, - 0xe3, 0x51, 0x5c, 0xb0, 0xc5, 0x9e, 0x99, 0x6a, 0x4f, 0xc8, 0x69, 0xf7, - 0x10, 0xff, 0x4e, 0xad, 0x19, 0xd9, 0xc9, 0x58, 0xb3, 0x33, 0xae, 0x0c, - 0xd9, 0x96, 0x29, 0x9e, 0x71, 0xb2, 0x70, 0x63, 0xa3, 0xb6, 0x99, 0x16, - 0x42, 0x1d, 0x65, 0xf3, 0xf7, 0xa0, 0x1e, 0x7d, 0xc5, 0xd4, 0x65, 0x14, - 0xb2, 0x62, 0x84, 0xd4, 0x6c, 0x5c, 0x08, 0x0c, 0xd8, 0x6c, 0x93, 0x2b, - 0xb4, 0x76, 0x59, 0x8a, 0xd1, 0x7f, 0xff, 0x03, 0xd8, 0xc2, 0x5d, 0xb8, - 0x2f, 0x22, 0xd6, 0x38, 0xf0, 0xf6, 0x9c, 0x6b, 0x7d, 0x46, 0xeb, 0x99, - 0x74, 0xf7, 0xeb, 0x4a, 0x0e, 0xa9, 0xa6, 0x04, 0xeb, 0x7b, 0xce, 0xf0, - 0x5c, 0x6b, 0x98, 0x31, 0x5a, 0x98, 0x40, 0xeb, 0x69, 0xc4, 0x05, 0xf4, - 0x20, 0xa8, 0xca, 0x08, 0x3a, 0x65, 0x6c, 0x38, 0x15, 0xf5, 0x5c, 0x2c, - 0xb2, 0x55, 0xe4, 0x2c, 0x6b, 0x41, 0xf0, 0xbe, 0x5c, 0x46, 0xca, 0x4a, - 0x29, 0xa0, 0x48, 0x5e, 0x20, 0xd2, 0x45, 0xff, 0x05, 0xde, 0x34, 0xaf, - 0x70, 0x4b, 0x81, 0x39, 0xe2, 0xca, 0x07, 0x57, 0x7c, 0xb6, 0x31, 0xdc, - 0x21, 0x29, 0xe2, 0xbe, 0x97, 0x0e, 0x77, 0x90, 0x14, 0x51, 0x40, 0xe1, - 0xbf, 0xe3, 0xcc, 0x1b, 0x19, 0x9c, 0x25, 0xca, 0xa7, 0x06, 0xb2, 0x53, - 0xdf, 0x23, 0xb2, 0xcf, 0x12, 0x19, 0xa3, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 76:10:12:8a:17:b6:82:bb:3a:1f:9d:1a:9a:35:c0:92 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - Validity - Not Before: Feb 18 00:00:00 2010 GMT - Not After : Feb 17 23:59:59 2020 GMT - Subject: C=US, O=Thawte, Inc., OU=Domain Validated SSL, CN=Thawte DV SSL CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:cb:98:c9:36:3f:d2:9c:d8:16:07:d4:49:63:f9: - 83:b0:e8:02:2d:cc:5c:5a:74:97:a6:13:ef:13:13: - de:05:7c:a7:e6:ca:00:23:da:39:f9:ef:13:cf:52: - c5:af:9a:e3:ca:be:f3:82:d9:8b:3d:aa:e1:cc:ae: - 88:50:66:a3:2d:ec:61:14:75:49:ab:0e:24:f1:ac: - 44:5b:0b:28:a2:33:20:76:1e:06:60:6a:67:05:71: - 8b:ba:66:62:16:7a:b3:6d:0d:c7:d0:94:40:c6:8c: - 3d:1e:92:0c:62:34:0d:44:89:d5:f7:89:fe:29:ed: - 18:8f:f6:9b:2b:08:f7:6a:ab:d8:48:97:5a:f4:9f: - ed:0c:75:52:22:f7:d5:5e:84:00:9f:c0:4a:0d:31: - 77:4c:64:d0:12:e6:0f:3a:f0:a1:c0:d5:5c:1d:e7: - 5f:2d:c2:f7:d6:36:18:d9:95:6e:44:4e:c9:58:14: - 4d:b6:8e:bb:cd:de:62:1e:fa:5b:b5:bd:18:2b:98: - ac:ac:93:3f:50:5a:f5:14:0b:a2:cf:b6:f3:9e:4f: - 5a:cd:5a:c3:36:23:da:1a:af:b0:4d:d6:4a:22:03: - 8f:43:02:19:bd:ea:ac:dd:c4:7a:35:32:14:f1:72: - 2e:08:55:40:0c:f4:07:41:41:af:38:37:84:29:42: - b2:55 - Exponent: 65537 (0x10001) - X509v3 extensions: - Authority Information Access: - OCSP - URI:http://ocsp.thawte.com - - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.thawte.com/ThawtePCA.crl - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Subject Alternative Name: - DirName:/CN=VeriSignMPKI-2-11 - X509v3 Subject Key Identifier: - AB:44:E4:5D:EC:83:C7:D9:C0:85:9F:F7:E1:C6:97:90:B0:8C:3F:98 - X509v3 Authority Key Identifier: - keyid:7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50 - - Signature Algorithm: sha1WithRSAEncryption - 04:ba:fb:ac:bb:fc:4b:54:11:a3:2d:88:b3:3c:bd:00:6d:8a: - 1a:b6:8d:c4:c1:83:f8:c7:53:2a:c1:32:6e:3a:81:a1:54:7d: - da:1a:3f:3a:45:4f:36:e7:42:b0:0a:42:85:97:a0:ac:fb:e5: - 87:a7:83:4f:e8:b1:b7:9b:58:65:6e:26:80:0b:92:4d:47:55: - b9:61:16:51:65:e9:2b:f1:68:d9:58:b8:03:81:d1:b7:66:1c: - d3:bc:c5:a6:7b:5f:3e:c5:38:46:76:e7:75:b4:a0:0c:4b:ce: - a2:c2:a9:c1:cc:36:73:7b:fb:b9:24:24:a0:5e:a7:f6:fa:bb: - 0c:28:43:9e:1d:f0:4e:f0:3f:d8:24:b0:21:dc:6d:2d:ee:bf: - 5a:3b:fa:88:9c:74:6c:af:21:dd:92:ec:c3:15:ef:94:75:26: - 46:d6:a6:3f:bf:66:48:aa:1d:ef:dd:27:e6:b7:51:89:38:7d: - 13:84:0c:40:fc:d0:b5:f1:e0:db:f9:4f:2f:40:1c:b4:8e:47: - 22:61:b8:4c:96:de:f0:5f:11:7e:4f:11:d9:ec:50:47:22:0e: - c5:1d:e2:64:49:e7:68:63:45:3a:8a:d9:71:f4:5e:f1:6e:b7: - 14:4d:3e:6f:14:1e:dc:52:fe:bc:df:0c:bd:29:3f:76:fb:11: - 5f:68:68:15 ------BEGIN CERTIFICATE----- -MIIEjzCCA3egAwIBAgIQdhASihe2grs6H50amjXAkjANBgkqhkiG9w0BAQUFADCB -qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf -Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw -MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV -BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTAwMjE4MDAwMDAwWhcNMjAw -MjE3MjM1OTU5WjBeMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMVGhhd3RlLCBJbmMu -MR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEZMBcGA1UEAxMQVGhhd3Rl -IERWIFNTTCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMuYyTY/ -0pzYFgfUSWP5g7DoAi3MXFp0l6YT7xMT3gV8p+bKACPaOfnvE89Sxa+a48q+84LZ -iz2q4cyuiFBmoy3sYRR1SasOJPGsRFsLKKIzIHYeBmBqZwVxi7pmYhZ6s20Nx9CU -QMaMPR6SDGI0DUSJ1feJ/intGI/2mysI92qr2EiXWvSf7Qx1UiL31V6EAJ/ASg0x -d0xk0BLmDzrwocDVXB3nXy3C99Y2GNmVbkROyVgUTbaOu83eYh76W7W9GCuYrKyT -P1Ba9RQLos+2855PWs1awzYj2hqvsE3WSiIDj0MCGb3qrN3EejUyFPFyLghVQAz0 -B0FBrzg3hClCslUCAwEAAaOB/DCB+TAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUH -MAGGFmh0dHA6Ly9vY3NwLnRoYXd0ZS5jb20wEgYDVR0TAQH/BAgwBgEB/wIBADA0 -BgNVHR8ELTArMCmgJ6AlhiNodHRwOi8vY3JsLnRoYXd0ZS5jb20vVGhhd3RlUENB -LmNybDAOBgNVHQ8BAf8EBAMCAQYwKQYDVR0RBCIwIKQeMBwxGjAYBgNVBAMTEVZl -cmlTaWduTVBLSS0yLTExMB0GA1UdDgQWBBSrRORd7IPH2cCFn/fhxpeQsIw/mDAf -BgNVHSMEGDAWgBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOC -AQEABLr7rLv8S1QRoy2Iszy9AG2KGraNxMGD+MdTKsEybjqBoVR92ho/OkVPNudC -sApChZegrPvlh6eDT+ixt5tYZW4mgAuSTUdVuWEWUWXpK/Fo2Vi4A4HRt2Yc07zF -pntfPsU4RnbndbSgDEvOosKpwcw2c3v7uSQkoF6n9vq7DChDnh3wTvA/2CSwIdxt -Le6/Wjv6iJx0bK8h3ZLswxXvlHUmRtamP79mSKod790n5rdRiTh9E4QMQPzQtfHg -2/lPL0ActI5HImG4TJbe8F8Rfk8R2exQRyIOxR3iZEnnaGNFOorZcfRe8W63FE0+ -bxQe3FL+vN8MvSk/dvsRX2hoFQ== ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert23[] = { - 0x30, 0x82, 0x04, 0x8f, 0x30, 0x82, 0x03, 0x77, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x76, 0x10, 0x12, 0x8a, 0x17, 0xb6, 0x82, 0xbb, 0x3a, - 0x1f, 0x9d, 0x1a, 0x9a, 0x35, 0xc0, 0x92, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, - 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, - 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44, - 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06, - 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, - 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, - 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, - 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, - 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x32, 0x31, 0x38, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30, - 0x32, 0x31, 0x37, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x5e, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, - 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x14, 0x44, - 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x65, 0x64, 0x20, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, - 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, - 0x20, 0x44, 0x56, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 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, 0xcb, 0x98, 0xc9, 0x36, 0x3f, - 0xd2, 0x9c, 0xd8, 0x16, 0x07, 0xd4, 0x49, 0x63, 0xf9, 0x83, 0xb0, 0xe8, - 0x02, 0x2d, 0xcc, 0x5c, 0x5a, 0x74, 0x97, 0xa6, 0x13, 0xef, 0x13, 0x13, - 0xde, 0x05, 0x7c, 0xa7, 0xe6, 0xca, 0x00, 0x23, 0xda, 0x39, 0xf9, 0xef, - 0x13, 0xcf, 0x52, 0xc5, 0xaf, 0x9a, 0xe3, 0xca, 0xbe, 0xf3, 0x82, 0xd9, - 0x8b, 0x3d, 0xaa, 0xe1, 0xcc, 0xae, 0x88, 0x50, 0x66, 0xa3, 0x2d, 0xec, - 0x61, 0x14, 0x75, 0x49, 0xab, 0x0e, 0x24, 0xf1, 0xac, 0x44, 0x5b, 0x0b, - 0x28, 0xa2, 0x33, 0x20, 0x76, 0x1e, 0x06, 0x60, 0x6a, 0x67, 0x05, 0x71, - 0x8b, 0xba, 0x66, 0x62, 0x16, 0x7a, 0xb3, 0x6d, 0x0d, 0xc7, 0xd0, 0x94, - 0x40, 0xc6, 0x8c, 0x3d, 0x1e, 0x92, 0x0c, 0x62, 0x34, 0x0d, 0x44, 0x89, - 0xd5, 0xf7, 0x89, 0xfe, 0x29, 0xed, 0x18, 0x8f, 0xf6, 0x9b, 0x2b, 0x08, - 0xf7, 0x6a, 0xab, 0xd8, 0x48, 0x97, 0x5a, 0xf4, 0x9f, 0xed, 0x0c, 0x75, - 0x52, 0x22, 0xf7, 0xd5, 0x5e, 0x84, 0x00, 0x9f, 0xc0, 0x4a, 0x0d, 0x31, - 0x77, 0x4c, 0x64, 0xd0, 0x12, 0xe6, 0x0f, 0x3a, 0xf0, 0xa1, 0xc0, 0xd5, - 0x5c, 0x1d, 0xe7, 0x5f, 0x2d, 0xc2, 0xf7, 0xd6, 0x36, 0x18, 0xd9, 0x95, - 0x6e, 0x44, 0x4e, 0xc9, 0x58, 0x14, 0x4d, 0xb6, 0x8e, 0xbb, 0xcd, 0xde, - 0x62, 0x1e, 0xfa, 0x5b, 0xb5, 0xbd, 0x18, 0x2b, 0x98, 0xac, 0xac, 0x93, - 0x3f, 0x50, 0x5a, 0xf5, 0x14, 0x0b, 0xa2, 0xcf, 0xb6, 0xf3, 0x9e, 0x4f, - 0x5a, 0xcd, 0x5a, 0xc3, 0x36, 0x23, 0xda, 0x1a, 0xaf, 0xb0, 0x4d, 0xd6, - 0x4a, 0x22, 0x03, 0x8f, 0x43, 0x02, 0x19, 0xbd, 0xea, 0xac, 0xdd, 0xc4, - 0x7a, 0x35, 0x32, 0x14, 0xf1, 0x72, 0x2e, 0x08, 0x55, 0x40, 0x0c, 0xf4, - 0x07, 0x41, 0x41, 0xaf, 0x38, 0x37, 0x84, 0x29, 0x42, 0xb2, 0x55, 0x02, - 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xfc, 0x30, 0x81, 0xf9, 0x30, 0x32, - 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x26, - 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, - 0x63, 0x73, 0x70, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, - 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, - 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x34, - 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2d, 0x30, 0x2b, 0x30, 0x29, 0xa0, - 0x27, 0xa0, 0x25, 0x86, 0x23, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x63, 0x72, 0x6c, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, 0x43, 0x41, - 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, - 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x29, 0x06, 0x03, - 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, - 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x56, 0x65, - 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49, 0x2d, 0x32, - 0x2d, 0x31, 0x31, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, - 0x04, 0x14, 0xab, 0x44, 0xe4, 0x5d, 0xec, 0x83, 0xc7, 0xd9, 0xc0, 0x85, - 0x9f, 0xf7, 0xe1, 0xc6, 0x97, 0x90, 0xb0, 0x8c, 0x3f, 0x98, 0x30, 0x1f, - 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7b, - 0x5b, 0x45, 0xcf, 0xaf, 0xce, 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a, 0x6a, - 0xb6, 0xf3, 0x46, 0xeb, 0x57, 0x48, 0x50, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, - 0x01, 0x01, 0x00, 0x04, 0xba, 0xfb, 0xac, 0xbb, 0xfc, 0x4b, 0x54, 0x11, - 0xa3, 0x2d, 0x88, 0xb3, 0x3c, 0xbd, 0x00, 0x6d, 0x8a, 0x1a, 0xb6, 0x8d, - 0xc4, 0xc1, 0x83, 0xf8, 0xc7, 0x53, 0x2a, 0xc1, 0x32, 0x6e, 0x3a, 0x81, - 0xa1, 0x54, 0x7d, 0xda, 0x1a, 0x3f, 0x3a, 0x45, 0x4f, 0x36, 0xe7, 0x42, - 0xb0, 0x0a, 0x42, 0x85, 0x97, 0xa0, 0xac, 0xfb, 0xe5, 0x87, 0xa7, 0x83, - 0x4f, 0xe8, 0xb1, 0xb7, 0x9b, 0x58, 0x65, 0x6e, 0x26, 0x80, 0x0b, 0x92, - 0x4d, 0x47, 0x55, 0xb9, 0x61, 0x16, 0x51, 0x65, 0xe9, 0x2b, 0xf1, 0x68, - 0xd9, 0x58, 0xb8, 0x03, 0x81, 0xd1, 0xb7, 0x66, 0x1c, 0xd3, 0xbc, 0xc5, - 0xa6, 0x7b, 0x5f, 0x3e, 0xc5, 0x38, 0x46, 0x76, 0xe7, 0x75, 0xb4, 0xa0, - 0x0c, 0x4b, 0xce, 0xa2, 0xc2, 0xa9, 0xc1, 0xcc, 0x36, 0x73, 0x7b, 0xfb, - 0xb9, 0x24, 0x24, 0xa0, 0x5e, 0xa7, 0xf6, 0xfa, 0xbb, 0x0c, 0x28, 0x43, - 0x9e, 0x1d, 0xf0, 0x4e, 0xf0, 0x3f, 0xd8, 0x24, 0xb0, 0x21, 0xdc, 0x6d, - 0x2d, 0xee, 0xbf, 0x5a, 0x3b, 0xfa, 0x88, 0x9c, 0x74, 0x6c, 0xaf, 0x21, - 0xdd, 0x92, 0xec, 0xc3, 0x15, 0xef, 0x94, 0x75, 0x26, 0x46, 0xd6, 0xa6, - 0x3f, 0xbf, 0x66, 0x48, 0xaa, 0x1d, 0xef, 0xdd, 0x27, 0xe6, 0xb7, 0x51, - 0x89, 0x38, 0x7d, 0x13, 0x84, 0x0c, 0x40, 0xfc, 0xd0, 0xb5, 0xf1, 0xe0, - 0xdb, 0xf9, 0x4f, 0x2f, 0x40, 0x1c, 0xb4, 0x8e, 0x47, 0x22, 0x61, 0xb8, - 0x4c, 0x96, 0xde, 0xf0, 0x5f, 0x11, 0x7e, 0x4f, 0x11, 0xd9, 0xec, 0x50, - 0x47, 0x22, 0x0e, 0xc5, 0x1d, 0xe2, 0x64, 0x49, 0xe7, 0x68, 0x63, 0x45, - 0x3a, 0x8a, 0xd9, 0x71, 0xf4, 0x5e, 0xf1, 0x6e, 0xb7, 0x14, 0x4d, 0x3e, - 0x6f, 0x14, 0x1e, 0xdc, 0x52, 0xfe, 0xbc, 0xdf, 0x0c, 0xbd, 0x29, 0x3f, - 0x76, 0xfb, 0x11, 0x5f, 0x68, 0x68, 0x15, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 1b:09:3b:78:60:96:da:37:bb:a4:51:94:46:c8:96:78 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority - Validity - Not Before: Nov 8 00:00:00 2006 GMT - Not After : Nov 7 23:59:59 2021 GMT - Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:af:24:08:08:29:7a:35:9e:60:0c:aa:e7:4b:3b: - 4e:dc:7c:bc:3c:45:1c:bb:2b:e0:fe:29:02:f9:57: - 08:a3:64:85:15:27:f5:f1:ad:c8:31:89:5d:22:e8: - 2a:aa:a6:42:b3:8f:f8:b9:55:b7:b1:b7:4b:b3:fe: - 8f:7e:07:57:ec:ef:43:db:66:62:15:61:cf:60:0d: - a4:d8:de:f8:e0:c3:62:08:3d:54:13:eb:49:ca:59: - 54:85:26:e5:2b:8f:1b:9f:eb:f5:a1:91:c2:33:49: - d8:43:63:6a:52:4b:d2:8f:e8:70:51:4d:d1:89:69: - 7b:c7:70:f6:b3:dc:12:74:db:7b:5d:4b:56:d3:96: - bf:15:77:a1:b0:f4:a2:25:f2:af:1c:92:67:18:e5: - f4:06:04:ef:90:b9:e4:00:e4:dd:3a:b5:19:ff:02: - ba:f4:3c:ee:e0:8b:eb:37:8b:ec:f4:d7:ac:f2:f6: - f0:3d:af:dd:75:91:33:19:1d:1c:40:cb:74:24:19: - 21:93:d9:14:fe:ac:2a:52:c7:8f:d5:04:49:e4:8d: - 63:47:88:3c:69:83:cb:fe:47:bd:2b:7e:4f:c5:95: - ae:0e:9d:d4:d1:43:c0:67:73:e3:14:08:7e:e5:3f: - 9f:73:b8:33:0a:cf:5d:3f:34:87:96:8a:ee:53:e8: - 25:15 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.verisign.com/pca3.crl - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://www.verisign.com/cps - - X509v3 Subject Key Identifier: - 7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33 - 1.3.6.1.5.5.7.1.12: - 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif - Authority Information Access: - OCSP - URI:http://ocsp.verisign.com - - Signature Algorithm: sha1WithRSAEncryption - a3:cd:7d:1e:f7:c7:75:8d:48:e7:56:34:4c:00:90:75:a9:51: - a5:56:c1:6d:bc:fe:f5:53:22:e9:98:a2:ac:9a:7e:70:1e:b3: - 8e:3b:45:e3:86:95:31:da:6d:4c:fb:34:50:80:96:cd:24:f2: - 40:df:04:3f:e2:65:ce:34:22:61:15:ea:66:70:64:d2:f1:6e: - f3:ca:18:59:6a:41:46:7e:82:de:19:b0:70:31:56:69:0d:0c: - e6:1d:9d:71:58:dc:cc:de:62:f5:e1:7a:10:02:d8:7a:dc:3b: - fa:57:bd:c9:e9:8f:46:21:39:9f:51:65:4c:8e:3a:be:28:41: - 70:1d ------BEGIN CERTIFICATE----- -MIIEkDCCA/mgAwIBAgIQGwk7eGCW2je7pFGURsiWeDANBgkqhkiG9w0BAQUFADBf -MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsT -LkNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw -HhcNMDYxMTA4MDAwMDAwWhcNMjExMTA3MjM1OTU5WjCByjELMAkGA1UEBhMCVVMx -FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz -dCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZv -ciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAz -IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8 -RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbext0uz/o9+B1fs70Pb -ZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhDY2pSS9KP6HBR -TdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/ -Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNH -iDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMB -AAGjggFbMIIBVzAPBgNVHRMBAf8EBTADAQH/MDEGA1UdHwQqMCgwJqAkoCKGIGh0 -dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMuY3JsMA4GA1UdDwEB/wQEAwIBBjA9 -BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVy -aXNpZ24uY29tL2NwczAdBgNVHQ4EFgQUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwbQYI -KwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQU -j+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24uY29t -L3ZzbG9nby5naWYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v -b2NzcC52ZXJpc2lnbi5jb20wDQYJKoZIhvcNAQEFBQADgYEAo819HvfHdY1I51Y0 -TACQdalRpVbBbbz+9VMi6ZiirJp+cB6zjjtF44aVMdptTPs0UICWzSTyQN8EP+Jl -zjQiYRXqZnBk0vFu88oYWWpBRn6C3hmwcDFWaQ0M5h2dcVjczN5i9eF6EALYetw7 -+le9yemPRiE5n1FlTI46vihBcB0= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert24[] = { - 0x30, 0x82, 0x04, 0x90, 0x30, 0x82, 0x03, 0xf9, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x1b, 0x09, 0x3b, 0x78, 0x60, 0x96, 0xda, 0x37, 0xbb, - 0xa4, 0x51, 0x94, 0x46, 0xc8, 0x96, 0x78, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5f, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, - 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, - 0x63, 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, - 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, - 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x30, 0x38, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31, 0x30, 0x37, - 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xca, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, - 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56, - 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, - 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3a, 0x30, - 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, 0x63, 0x29, 0x20, - 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, - 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, - 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, - 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x45, 0x30, - 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56, 0x65, 0x72, 0x69, - 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, - 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 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, 0xaf, 0x24, 0x08, 0x08, 0x29, 0x7a, 0x35, - 0x9e, 0x60, 0x0c, 0xaa, 0xe7, 0x4b, 0x3b, 0x4e, 0xdc, 0x7c, 0xbc, 0x3c, - 0x45, 0x1c, 0xbb, 0x2b, 0xe0, 0xfe, 0x29, 0x02, 0xf9, 0x57, 0x08, 0xa3, - 0x64, 0x85, 0x15, 0x27, 0xf5, 0xf1, 0xad, 0xc8, 0x31, 0x89, 0x5d, 0x22, - 0xe8, 0x2a, 0xaa, 0xa6, 0x42, 0xb3, 0x8f, 0xf8, 0xb9, 0x55, 0xb7, 0xb1, - 0xb7, 0x4b, 0xb3, 0xfe, 0x8f, 0x7e, 0x07, 0x57, 0xec, 0xef, 0x43, 0xdb, - 0x66, 0x62, 0x15, 0x61, 0xcf, 0x60, 0x0d, 0xa4, 0xd8, 0xde, 0xf8, 0xe0, - 0xc3, 0x62, 0x08, 0x3d, 0x54, 0x13, 0xeb, 0x49, 0xca, 0x59, 0x54, 0x85, - 0x26, 0xe5, 0x2b, 0x8f, 0x1b, 0x9f, 0xeb, 0xf5, 0xa1, 0x91, 0xc2, 0x33, - 0x49, 0xd8, 0x43, 0x63, 0x6a, 0x52, 0x4b, 0xd2, 0x8f, 0xe8, 0x70, 0x51, - 0x4d, 0xd1, 0x89, 0x69, 0x7b, 0xc7, 0x70, 0xf6, 0xb3, 0xdc, 0x12, 0x74, - 0xdb, 0x7b, 0x5d, 0x4b, 0x56, 0xd3, 0x96, 0xbf, 0x15, 0x77, 0xa1, 0xb0, - 0xf4, 0xa2, 0x25, 0xf2, 0xaf, 0x1c, 0x92, 0x67, 0x18, 0xe5, 0xf4, 0x06, - 0x04, 0xef, 0x90, 0xb9, 0xe4, 0x00, 0xe4, 0xdd, 0x3a, 0xb5, 0x19, 0xff, - 0x02, 0xba, 0xf4, 0x3c, 0xee, 0xe0, 0x8b, 0xeb, 0x37, 0x8b, 0xec, 0xf4, - 0xd7, 0xac, 0xf2, 0xf6, 0xf0, 0x3d, 0xaf, 0xdd, 0x75, 0x91, 0x33, 0x19, - 0x1d, 0x1c, 0x40, 0xcb, 0x74, 0x24, 0x19, 0x21, 0x93, 0xd9, 0x14, 0xfe, - 0xac, 0x2a, 0x52, 0xc7, 0x8f, 0xd5, 0x04, 0x49, 0xe4, 0x8d, 0x63, 0x47, - 0x88, 0x3c, 0x69, 0x83, 0xcb, 0xfe, 0x47, 0xbd, 0x2b, 0x7e, 0x4f, 0xc5, - 0x95, 0xae, 0x0e, 0x9d, 0xd4, 0xd1, 0x43, 0xc0, 0x67, 0x73, 0xe3, 0x14, - 0x08, 0x7e, 0xe5, 0x3f, 0x9f, 0x73, 0xb8, 0x33, 0x0a, 0xcf, 0x5d, 0x3f, - 0x34, 0x87, 0x96, 0x8a, 0xee, 0x53, 0xe8, 0x25, 0x15, 0x02, 0x03, 0x01, - 0x00, 0x01, 0xa3, 0x82, 0x01, 0x5b, 0x30, 0x82, 0x01, 0x57, 0x30, 0x0f, - 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, - 0x01, 0x01, 0xff, 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2a, - 0x30, 0x28, 0x30, 0x26, 0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, - 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, - 0x61, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, - 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3d, - 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06, - 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, - 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, - 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, - 0x73, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, - 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3, - 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x6d, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f, - 0xa1, 0x5d, 0xa0, 0x5b, 0x30, 0x59, 0x30, 0x57, 0x30, 0x55, 0x16, 0x09, - 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x30, 0x21, 0x30, - 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, - 0x8f, 0xe5, 0xd3, 0x1a, 0x86, 0xac, 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80, - 0x6a, 0xd4, 0x48, 0x18, 0x2c, 0x7b, 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, - 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x76, 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30, - 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, - 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, - 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, - 0xa3, 0xcd, 0x7d, 0x1e, 0xf7, 0xc7, 0x75, 0x8d, 0x48, 0xe7, 0x56, 0x34, - 0x4c, 0x00, 0x90, 0x75, 0xa9, 0x51, 0xa5, 0x56, 0xc1, 0x6d, 0xbc, 0xfe, - 0xf5, 0x53, 0x22, 0xe9, 0x98, 0xa2, 0xac, 0x9a, 0x7e, 0x70, 0x1e, 0xb3, - 0x8e, 0x3b, 0x45, 0xe3, 0x86, 0x95, 0x31, 0xda, 0x6d, 0x4c, 0xfb, 0x34, - 0x50, 0x80, 0x96, 0xcd, 0x24, 0xf2, 0x40, 0xdf, 0x04, 0x3f, 0xe2, 0x65, - 0xce, 0x34, 0x22, 0x61, 0x15, 0xea, 0x66, 0x70, 0x64, 0xd2, 0xf1, 0x6e, - 0xf3, 0xca, 0x18, 0x59, 0x6a, 0x41, 0x46, 0x7e, 0x82, 0xde, 0x19, 0xb0, - 0x70, 0x31, 0x56, 0x69, 0x0d, 0x0c, 0xe6, 0x1d, 0x9d, 0x71, 0x58, 0xdc, - 0xcc, 0xde, 0x62, 0xf5, 0xe1, 0x7a, 0x10, 0x02, 0xd8, 0x7a, 0xdc, 0x3b, - 0xfa, 0x57, 0xbd, 0xc9, 0xe9, 0x8f, 0x46, 0x21, 0x39, 0x9f, 0x51, 0x65, - 0x4c, 0x8e, 0x3a, 0xbe, 0x28, 0x41, 0x70, 0x1d, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 01:fd:a3:eb:6e:ca:75:c8:88:43:8b:72:4b:cf:bc:91 - Signature Algorithm: sha256WithRSAEncryption - Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA - Validity - Not Before: Mar 8 12:00:00 2013 GMT - Not After : Mar 8 12:00:00 2023 GMT - Subject: C=US, O=DigiCert Inc, CN=DigiCert SHA2 Secure Server CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:dc:ae:58:90:4d:c1:c4:30:15:90:35:5b:6e:3c: - 82:15:f5:2c:5c:bd:e3:db:ff:71:43:fa:64:25:80: - d4:ee:18:a2:4d:f0:66:d0:0a:73:6e:11:98:36:17: - 64:af:37:9d:fd:fa:41:84:af:c7:af:8c:fe:1a:73: - 4d:cf:33:97:90:a2:96:87:53:83:2b:b9:a6:75:48: - 2d:1d:56:37:7b:da:31:32:1a:d7:ac:ab:06:f4:aa: - 5d:4b:b7:47:46:dd:2a:93:c3:90:2e:79:80:80:ef: - 13:04:6a:14:3b:b5:9b:92:be:c2:07:65:4e:fc:da: - fc:ff:7a:ae:dc:5c:7e:55:31:0c:e8:39:07:a4:d7: - be:2f:d3:0b:6a:d2:b1:df:5f:fe:57:74:53:3b:35: - 80:dd:ae:8e:44:98:b3:9f:0e:d3:da:e0:d7:f4:6b: - 29:ab:44:a7:4b:58:84:6d:92:4b:81:c3:da:73:8b: - 12:97:48:90:04:45:75:1a:dd:37:31:97:92:e8:cd: - 54:0d:3b:e4:c1:3f:39:5e:2e:b8:f3:5c:7e:10:8e: - 86:41:00:8d:45:66:47:b0:a1:65:ce:a0:aa:29:09: - 4e:f3:97:eb:e8:2e:ab:0f:72:a7:30:0e:fa:c7:f4: - fd:14:77:c3:a4:5b:28:57:c2:b3:f9:82:fd:b7:45: - 58:9b - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Key Usage: critical - Digital Signature, Certificate Sign, CRL Sign - Authority Information Access: - OCSP - URI:http://ocsp.digicert.com - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl3.digicert.com/DigiCertGlobalRootCA.crl - - Full Name: - URI:http://crl4.digicert.com/DigiCertGlobalRootCA.crl - - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://www.digicert.com/CPS - - X509v3 Subject Key Identifier: - 0F:80:61:1C:82:31:61:D5:2F:28:E7:8D:46:38:B4:2C:E1:C6:D9:E2 - X509v3 Authority Key Identifier: - keyid:03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55 - - Signature Algorithm: sha256WithRSAEncryption - 23:3e:df:4b:d2:31:42:a5:b6:7e:42:5c:1a:44:cc:69:d1:68: - b4:5d:4b:e0:04:21:6c:4b:e2:6d:cc:b1:e0:97:8f:a6:53:09: - cd:aa:2a:65:e5:39:4f:1e:83:a5:6e:5c:98:a2:24:26:e6:fb: - a1:ed:93:c7:2e:02:c6:4d:4a:bf:b0:42:df:78:da:b3:a8:f9: - 6d:ff:21:85:53:36:60:4c:76:ce:ec:38:dc:d6:51:80:f0:c5: - d6:e5:d4:4d:27:64:ab:9b:c7:3e:71:fb:48:97:b8:33:6d:c9: - 13:07:ee:96:a2:1b:18:15:f6:5c:4c:40:ed:b3:c2:ec:ff:71: - c1:e3:47:ff:d4:b9:00:b4:37:42:da:20:c9:ea:6e:8a:ee:14: - 06:ae:7d:a2:59:98:88:a8:1b:6f:2d:f4:f2:c9:14:5f:26:cf: - 2c:8d:7e:ed:37:c0:a9:d5:39:b9:82:bf:19:0c:ea:34:af:00: - 21:68:f8:ad:73:e2:c9:32:da:38:25:0b:55:d3:9a:1d:f0:68: - 86:ed:2e:41:34:ef:7c:a5:50:1d:bf:3a:f9:d3:c1:08:0c:e6: - ed:1e:8a:58:25:e4:b8:77:ad:2d:6e:f5:52:dd:b4:74:8f:ab: - 49:2e:9d:3b:93:34:28:1f:78:ce:94:ea:c7:bd:d3:c9:6d:1c: - de:5c:32:f3 ------BEGIN CERTIFICATE----- -MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG9w0BAQsFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD -QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaME0xCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIg -U2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -ANyuWJBNwcQwFZA1W248ghX1LFy949v/cUP6ZCWA1O4Yok3wZtAKc24RmDYXZK83 -nf36QYSvx6+M/hpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yrBvSqXUu3R0bd -KpPDkC55gIDvEwRqFDu1m5K+wgdlTvza/P96rtxcflUxDOg5B6TXvi/TC2rSsd9f -/ld0Uzs1gN2ujkSYs58O09rg1/RrKatEp0tYhG2SS4HD2nOLEpdIkARFdRrdNzGX -kujNVA075ME/OV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJTvOX6+guqw9ypzAO+sf0 -/RR3w6RbKFfCs/mC/bdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8C -AQAwDgYDVR0PAQH/BAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYY -aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6 -Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwN6A1 -oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RD -QS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v -d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA+AYRyCMWHVLyjnjUY4tCzh -xtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0GCSqGSIb3DQEB -CwUAA4IBAQAjPt9L0jFCpbZ+QlwaRMxp0Wi0XUvgBCFsS+JtzLHgl4+mUwnNqipl -5TlPHoOlblyYoiQm5vuh7ZPHLgLGTUq/sELfeNqzqPlt/yGFUzZgTHbO7Djc1lGA -8MXW5dRNJ2Srm8c+cftIl7gzbckTB+6WohsYFfZcTEDts8Ls/3HB40f/1LkAtDdC -2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8sjX7tN8Cp1Tm5gr8ZDOo0rwAhaPit -c+LJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopYJeS4d60tbvVS3bR0 -j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLz ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert25[] = { - 0x30, 0x82, 0x04, 0x94, 0x30, 0x82, 0x03, 0x7c, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x01, 0xfd, 0xa3, 0xeb, 0x6e, 0xca, 0x75, 0xc8, 0x88, - 0x43, 0x8b, 0x72, 0x4b, 0xcf, 0xbc, 0x91, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x61, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, - 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, - 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, - 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, - 0x63, 0x6f, 0x6d, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x47, - 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, - 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x33, 0x30, 0x38, 0x31, - 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x33, - 0x30, 0x38, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x4d, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, - 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44, - 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, - 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1e, 0x44, 0x69, - 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x53, 0x48, 0x41, 0x32, 0x20, - 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x20, 0x43, 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, 0xdc, 0xae, 0x58, 0x90, 0x4d, 0xc1, 0xc4, 0x30, 0x15, 0x90, 0x35, - 0x5b, 0x6e, 0x3c, 0x82, 0x15, 0xf5, 0x2c, 0x5c, 0xbd, 0xe3, 0xdb, 0xff, - 0x71, 0x43, 0xfa, 0x64, 0x25, 0x80, 0xd4, 0xee, 0x18, 0xa2, 0x4d, 0xf0, - 0x66, 0xd0, 0x0a, 0x73, 0x6e, 0x11, 0x98, 0x36, 0x17, 0x64, 0xaf, 0x37, - 0x9d, 0xfd, 0xfa, 0x41, 0x84, 0xaf, 0xc7, 0xaf, 0x8c, 0xfe, 0x1a, 0x73, - 0x4d, 0xcf, 0x33, 0x97, 0x90, 0xa2, 0x96, 0x87, 0x53, 0x83, 0x2b, 0xb9, - 0xa6, 0x75, 0x48, 0x2d, 0x1d, 0x56, 0x37, 0x7b, 0xda, 0x31, 0x32, 0x1a, - 0xd7, 0xac, 0xab, 0x06, 0xf4, 0xaa, 0x5d, 0x4b, 0xb7, 0x47, 0x46, 0xdd, - 0x2a, 0x93, 0xc3, 0x90, 0x2e, 0x79, 0x80, 0x80, 0xef, 0x13, 0x04, 0x6a, - 0x14, 0x3b, 0xb5, 0x9b, 0x92, 0xbe, 0xc2, 0x07, 0x65, 0x4e, 0xfc, 0xda, - 0xfc, 0xff, 0x7a, 0xae, 0xdc, 0x5c, 0x7e, 0x55, 0x31, 0x0c, 0xe8, 0x39, - 0x07, 0xa4, 0xd7, 0xbe, 0x2f, 0xd3, 0x0b, 0x6a, 0xd2, 0xb1, 0xdf, 0x5f, - 0xfe, 0x57, 0x74, 0x53, 0x3b, 0x35, 0x80, 0xdd, 0xae, 0x8e, 0x44, 0x98, - 0xb3, 0x9f, 0x0e, 0xd3, 0xda, 0xe0, 0xd7, 0xf4, 0x6b, 0x29, 0xab, 0x44, - 0xa7, 0x4b, 0x58, 0x84, 0x6d, 0x92, 0x4b, 0x81, 0xc3, 0xda, 0x73, 0x8b, - 0x12, 0x97, 0x48, 0x90, 0x04, 0x45, 0x75, 0x1a, 0xdd, 0x37, 0x31, 0x97, - 0x92, 0xe8, 0xcd, 0x54, 0x0d, 0x3b, 0xe4, 0xc1, 0x3f, 0x39, 0x5e, 0x2e, - 0xb8, 0xf3, 0x5c, 0x7e, 0x10, 0x8e, 0x86, 0x41, 0x00, 0x8d, 0x45, 0x66, - 0x47, 0xb0, 0xa1, 0x65, 0xce, 0xa0, 0xaa, 0x29, 0x09, 0x4e, 0xf3, 0x97, - 0xeb, 0xe8, 0x2e, 0xab, 0x0f, 0x72, 0xa7, 0x30, 0x0e, 0xfa, 0xc7, 0xf4, - 0xfd, 0x14, 0x77, 0xc3, 0xa4, 0x5b, 0x28, 0x57, 0xc2, 0xb3, 0xf9, 0x82, - 0xfd, 0xb7, 0x45, 0x58, 0x9b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, - 0x01, 0x5a, 0x30, 0x82, 0x01, 0x56, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, - 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, - 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, - 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, - 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, - 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, - 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, - 0x30, 0x7b, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x74, 0x30, 0x72, 0x30, - 0x37, 0xa0, 0x35, 0xa0, 0x33, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x33, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, - 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, - 0x43, 0x65, 0x72, 0x74, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x52, 0x6f, - 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x37, 0xa0, 0x35, - 0xa0, 0x33, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, - 0x72, 0x6c, 0x34, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, - 0x74, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x52, 0x6f, 0x6f, 0x74, 0x43, - 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x20, - 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, - 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, - 0x77, 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x1d, 0x06, 0x03, - 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x0f, 0x80, 0x61, 0x1c, 0x82, - 0x31, 0x61, 0xd5, 0x2f, 0x28, 0xe7, 0x8d, 0x46, 0x38, 0xb4, 0x2c, 0xe1, - 0xc6, 0xd9, 0xe2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, - 0x30, 0x16, 0x80, 0x14, 0x03, 0xde, 0x50, 0x35, 0x56, 0xd1, 0x4c, 0xbb, - 0x66, 0xf0, 0xa3, 0xe2, 0x1b, 0x1b, 0xc3, 0x97, 0xb2, 0x3d, 0xd1, 0x55, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x23, 0x3e, 0xdf, 0x4b, - 0xd2, 0x31, 0x42, 0xa5, 0xb6, 0x7e, 0x42, 0x5c, 0x1a, 0x44, 0xcc, 0x69, - 0xd1, 0x68, 0xb4, 0x5d, 0x4b, 0xe0, 0x04, 0x21, 0x6c, 0x4b, 0xe2, 0x6d, - 0xcc, 0xb1, 0xe0, 0x97, 0x8f, 0xa6, 0x53, 0x09, 0xcd, 0xaa, 0x2a, 0x65, - 0xe5, 0x39, 0x4f, 0x1e, 0x83, 0xa5, 0x6e, 0x5c, 0x98, 0xa2, 0x24, 0x26, - 0xe6, 0xfb, 0xa1, 0xed, 0x93, 0xc7, 0x2e, 0x02, 0xc6, 0x4d, 0x4a, 0xbf, - 0xb0, 0x42, 0xdf, 0x78, 0xda, 0xb3, 0xa8, 0xf9, 0x6d, 0xff, 0x21, 0x85, - 0x53, 0x36, 0x60, 0x4c, 0x76, 0xce, 0xec, 0x38, 0xdc, 0xd6, 0x51, 0x80, - 0xf0, 0xc5, 0xd6, 0xe5, 0xd4, 0x4d, 0x27, 0x64, 0xab, 0x9b, 0xc7, 0x3e, - 0x71, 0xfb, 0x48, 0x97, 0xb8, 0x33, 0x6d, 0xc9, 0x13, 0x07, 0xee, 0x96, - 0xa2, 0x1b, 0x18, 0x15, 0xf6, 0x5c, 0x4c, 0x40, 0xed, 0xb3, 0xc2, 0xec, - 0xff, 0x71, 0xc1, 0xe3, 0x47, 0xff, 0xd4, 0xb9, 0x00, 0xb4, 0x37, 0x42, - 0xda, 0x20, 0xc9, 0xea, 0x6e, 0x8a, 0xee, 0x14, 0x06, 0xae, 0x7d, 0xa2, - 0x59, 0x98, 0x88, 0xa8, 0x1b, 0x6f, 0x2d, 0xf4, 0xf2, 0xc9, 0x14, 0x5f, - 0x26, 0xcf, 0x2c, 0x8d, 0x7e, 0xed, 0x37, 0xc0, 0xa9, 0xd5, 0x39, 0xb9, - 0x82, 0xbf, 0x19, 0x0c, 0xea, 0x34, 0xaf, 0x00, 0x21, 0x68, 0xf8, 0xad, - 0x73, 0xe2, 0xc9, 0x32, 0xda, 0x38, 0x25, 0x0b, 0x55, 0xd3, 0x9a, 0x1d, - 0xf0, 0x68, 0x86, 0xed, 0x2e, 0x41, 0x34, 0xef, 0x7c, 0xa5, 0x50, 0x1d, - 0xbf, 0x3a, 0xf9, 0xd3, 0xc1, 0x08, 0x0c, 0xe6, 0xed, 0x1e, 0x8a, 0x58, - 0x25, 0xe4, 0xb8, 0x77, 0xad, 0x2d, 0x6e, 0xf5, 0x52, 0xdd, 0xb4, 0x74, - 0x8f, 0xab, 0x49, 0x2e, 0x9d, 0x3b, 0x93, 0x34, 0x28, 0x1f, 0x78, 0xce, - 0x94, 0xea, 0xc7, 0xbd, 0xd3, 0xc9, 0x6d, 0x1c, 0xde, 0x5c, 0x32, 0xf3, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 0b:1d:b1:a9:19:f2:4c:3c:4e:fc:b5:7a:6a:4e:6c:bf - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority - Validity - Not Before: Aug 23 00:00:00 2012 GMT - Not After : Aug 22 23:59:59 2022 GMT - Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Extended Validation SSL CA - G2 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:9e:c6:21:cd:2e:3d:d0:bb:2a:4d:a4:7b:1f:a8: - 1a:c2:03:a6:ff:43:62:5b:bf:91:d1:66:52:a9:81: - 90:68:31:86:16:bb:1d:85:58:a9:7e:91:6a:1e:4c: - 31:ca:21:c4:be:70:1b:9f:8c:e4:05:2d:9c:ed:11: - 79:ad:8f:9c:25:86:4c:ba:f2:e5:62:79:8e:22:5f: - 85:7c:22:35:38:23:8d:80:3c:ac:cc:2d:fc:58:f2: - 35:bf:66:5b:eb:c1:24:f8:70:80:74:32:f9:46:de: - 32:19:80:8c:b7:e7:1a:a1:aa:64:98:8d:ca:ce:0e: - dc:6b:f7:e2:90:0a:6c:1c:a5:f4:90:32:52:e5:f1: - 00:42:31:91:48:42:89:a8:5d:7f:63:8d:31:b2:d6: - 48:5c:45:45:22:c9:c5:59:12:ab:41:94:ea:fe:9c: - 46:4d:9a:bc:9c:e0:e2:c6:46:b3:e6:7f:dc:f5:0f: - a3:13:45:86:6d:79:78:fc:e1:50:cf:09:86:e5:9f: - bf:cb:3a:d4:e0:b1:d4:ff:a8:3f:7d:62:1f:c0:6d: - 78:48:c3:d7:a3:a5:23:61:c5:3e:35:4d:b2:e5:f8: - fd:94:4b:bc:73:53:af:e3:9a:69:55:be:cb:67:ab: - e1:be:ef:1b:c2:4d:ac:cb:29:5c:bc:ed:b8:62:9d: - 10:e9 - Exponent: 65537 (0x10001) - X509v3 extensions: - Authority Information Access: - OCSP - URI:http://EVSecure-ocsp.geotrust.com - - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: http://www.geotrust.com/resources/cps - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://EVSecure-crl.geotrust.com/GeoTrustPCA.crl - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Subject Alternative Name: - DirName:/CN=VeriSignMPKI-2-253 - X509v3 Subject Key Identifier: - 6F:26:56:D9:5C:E7:F7:C9:04:20:F8:1E:BA:7C:91:27:2F:8C:FA:07 - X509v3 Authority Key Identifier: - keyid:2C:D5:50:41:97:15:8B:F0:8F:36:61:5B:4A:FB:6B:D9:99:C9:33:92 - - Signature Algorithm: sha1WithRSAEncryption - 92:77:e9:57:c9:eb:c4:45:6f:c9:4c:6e:7d:00:12:71:a5:e3: - 39:fe:13:84:49:6c:e7:49:71:f5:2c:c7:c0:36:c2:08:58:f3: - 83:75:c5:72:d8:8d:78:f4:65:ea:8c:d5:e3:a5:0e:a9:ad:eb: - e3:a1:23:ae:93:b7:d8:75:75:4a:59:cb:f2:9e:db:40:bf:4e: - 89:fe:95:42:29:34:7b:f4:dd:6a:0d:74:5f:c7:11:13:2e:dd: - 11:6e:c6:e3:5b:b3:cf:a6:8d:e5:f7:67:7b:ba:b3:b3:69:70: - 14:b0:c2:99:b4:d2:76:5b:38:17:39:45:1b:82:f1:53:b8:3d: - 55:39:0b:7f:ff:98:ad:6e:96:9a:b6:6a:4c:7a:5e:bd:b1:86: - 12:9d:7c:2c:62:bb:09:93:5f:3f:d8:b5:8a:c3:49:28:0f:0b: - f9:39:22:1a:fe:5d:d3:e8:18:5f:9d:5f:b4:c0:20:c6:a9:49: - 0d:55:73:6a:09:7a:ff:a2:99:bf:d8:bb:91:dc:30:39:ae:28: - 4b:f6:c5:77:24:e8:d6:c6:a7:a0:4e:f2:a6:99:75:cd:dd:57: - dd:0a:47:92:cb:bb:b7:48:fa:21:f0:69:21:ff:e5:0c:aa:0c: - b1:ea:dd:05:1c:19:8e:d1:2a:79:68:02:5e:cc:38:e6:29:c4: - 77:f5:19:1c ------BEGIN CERTIFICATE----- -MIIEmjCCA4KgAwIBAgIQCx2xqRnyTDxO/LV6ak5svzANBgkqhkiG9w0BAQUFADBY -MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo -R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xMjA4 -MjMwMDAwMDBaFw0yMjA4MjIyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK -Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBFeHRlbmRlZCBWYWxp -ZGF0aW9uIFNTTCBDQSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC -AQEAnsYhzS490LsqTaR7H6gawgOm/0NiW7+R0WZSqYGQaDGGFrsdhVipfpFqHkwx -yiHEvnAbn4zkBS2c7RF5rY+cJYZMuvLlYnmOIl+FfCI1OCONgDyszC38WPI1v2Zb -68Ek+HCAdDL5Rt4yGYCMt+caoapkmI3Kzg7ca/fikApsHKX0kDJS5fEAQjGRSEKJ -qF1/Y40xstZIXEVFIsnFWRKrQZTq/pxGTZq8nODixkaz5n/c9Q+jE0WGbXl4/OFQ -zwmG5Z+/yzrU4LHU/6g/fWIfwG14SMPXo6UjYcU+NU2y5fj9lEu8c1Ov45ppVb7L -Z6vhvu8bwk2syylcvO24Yp0Q6QIDAQABo4IBXjCCAVowPQYIKwYBBQUHAQEEMTAv -MC0GCCsGAQUFBzABhiFodHRwOi8vRVZTZWN1cmUtb2NzcC5nZW90cnVzdC5jb20w -EgYDVR0TAQH/BAgwBgEB/wIBADBGBgNVHSAEPzA9MDsGBFUdIAAwMzAxBggrBgEF -BQcCARYlaHR0cDovL3d3dy5nZW90cnVzdC5jb20vcmVzb3VyY2VzL2NwczBBBgNV -HR8EOjA4MDagNKAyhjBodHRwOi8vRVZTZWN1cmUtY3JsLmdlb3RydXN0LmNvbS9H -ZW9UcnVzdFBDQS5jcmwwDgYDVR0PAQH/BAQDAgEGMCoGA1UdEQQjMCGkHzAdMRsw -GQYDVQQDExJWZXJpU2lnbk1QS0ktMi0yNTMwHQYDVR0OBBYEFG8mVtlc5/fJBCD4 -Hrp8kScvjPoHMB8GA1UdIwQYMBaAFCzVUEGXFYvwjzZhW0r7a9mZyTOSMA0GCSqG -SIb3DQEBBQUAA4IBAQCSd+lXyevERW/JTG59ABJxpeM5/hOESWznSXH1LMfANsII -WPODdcVy2I149GXqjNXjpQ6prevjoSOuk7fYdXVKWcvynttAv06J/pVCKTR79N1q -DXRfxxETLt0RbsbjW7PPpo3l92d7urOzaXAUsMKZtNJ2WzgXOUUbgvFTuD1VOQt/ -/5itbpaatmpMel69sYYSnXwsYrsJk18/2LWKw0koDwv5OSIa/l3T6BhfnV+0wCDG -qUkNVXNqCXr/opm/2LuR3DA5rihL9sV3JOjWxqegTvKmmXXN3VfdCkeSy7u3SPoh -8Gkh/+UMqgyx6t0FHBmO0Sp5aAJezDjmKcR39Rkc ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert26[] = { - 0x30, 0x82, 0x04, 0x9a, 0x30, 0x82, 0x03, 0x82, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x0b, 0x1d, 0xb1, 0xa9, 0x19, 0xf2, 0x4c, 0x3c, 0x4e, - 0xfc, 0xb5, 0x7a, 0x6a, 0x4e, 0x6c, 0xbf, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x58, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, - 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, - 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, - 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x69, - 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x30, 0x38, - 0x32, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, - 0x32, 0x30, 0x38, 0x32, 0x32, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, - 0x30, 0x58, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, - 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x28, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, - 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x56, 0x61, 0x6c, 0x69, - 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, - 0x41, 0x20, 0x2d, 0x20, 0x47, 0x32, 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, 0x9e, 0xc6, 0x21, 0xcd, 0x2e, 0x3d, 0xd0, 0xbb, 0x2a, - 0x4d, 0xa4, 0x7b, 0x1f, 0xa8, 0x1a, 0xc2, 0x03, 0xa6, 0xff, 0x43, 0x62, - 0x5b, 0xbf, 0x91, 0xd1, 0x66, 0x52, 0xa9, 0x81, 0x90, 0x68, 0x31, 0x86, - 0x16, 0xbb, 0x1d, 0x85, 0x58, 0xa9, 0x7e, 0x91, 0x6a, 0x1e, 0x4c, 0x31, - 0xca, 0x21, 0xc4, 0xbe, 0x70, 0x1b, 0x9f, 0x8c, 0xe4, 0x05, 0x2d, 0x9c, - 0xed, 0x11, 0x79, 0xad, 0x8f, 0x9c, 0x25, 0x86, 0x4c, 0xba, 0xf2, 0xe5, - 0x62, 0x79, 0x8e, 0x22, 0x5f, 0x85, 0x7c, 0x22, 0x35, 0x38, 0x23, 0x8d, - 0x80, 0x3c, 0xac, 0xcc, 0x2d, 0xfc, 0x58, 0xf2, 0x35, 0xbf, 0x66, 0x5b, - 0xeb, 0xc1, 0x24, 0xf8, 0x70, 0x80, 0x74, 0x32, 0xf9, 0x46, 0xde, 0x32, - 0x19, 0x80, 0x8c, 0xb7, 0xe7, 0x1a, 0xa1, 0xaa, 0x64, 0x98, 0x8d, 0xca, - 0xce, 0x0e, 0xdc, 0x6b, 0xf7, 0xe2, 0x90, 0x0a, 0x6c, 0x1c, 0xa5, 0xf4, - 0x90, 0x32, 0x52, 0xe5, 0xf1, 0x00, 0x42, 0x31, 0x91, 0x48, 0x42, 0x89, - 0xa8, 0x5d, 0x7f, 0x63, 0x8d, 0x31, 0xb2, 0xd6, 0x48, 0x5c, 0x45, 0x45, - 0x22, 0xc9, 0xc5, 0x59, 0x12, 0xab, 0x41, 0x94, 0xea, 0xfe, 0x9c, 0x46, - 0x4d, 0x9a, 0xbc, 0x9c, 0xe0, 0xe2, 0xc6, 0x46, 0xb3, 0xe6, 0x7f, 0xdc, - 0xf5, 0x0f, 0xa3, 0x13, 0x45, 0x86, 0x6d, 0x79, 0x78, 0xfc, 0xe1, 0x50, - 0xcf, 0x09, 0x86, 0xe5, 0x9f, 0xbf, 0xcb, 0x3a, 0xd4, 0xe0, 0xb1, 0xd4, - 0xff, 0xa8, 0x3f, 0x7d, 0x62, 0x1f, 0xc0, 0x6d, 0x78, 0x48, 0xc3, 0xd7, - 0xa3, 0xa5, 0x23, 0x61, 0xc5, 0x3e, 0x35, 0x4d, 0xb2, 0xe5, 0xf8, 0xfd, - 0x94, 0x4b, 0xbc, 0x73, 0x53, 0xaf, 0xe3, 0x9a, 0x69, 0x55, 0xbe, 0xcb, - 0x67, 0xab, 0xe1, 0xbe, 0xef, 0x1b, 0xc2, 0x4d, 0xac, 0xcb, 0x29, 0x5c, - 0xbc, 0xed, 0xb8, 0x62, 0x9d, 0x10, 0xe9, 0x02, 0x03, 0x01, 0x00, 0x01, - 0xa3, 0x82, 0x01, 0x5e, 0x30, 0x82, 0x01, 0x5a, 0x30, 0x3d, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x31, 0x30, 0x2f, - 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, - 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x45, 0x56, 0x53, - 0x65, 0x63, 0x75, 0x72, 0x65, 0x2d, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, - 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, - 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, - 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x46, 0x06, 0x03, 0x55, - 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30, 0x3b, 0x06, 0x04, 0x55, 0x1d, - 0x20, 0x00, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x41, 0x06, 0x03, 0x55, - 0x1d, 0x1f, 0x04, 0x3a, 0x30, 0x38, 0x30, 0x36, 0xa0, 0x34, 0xa0, 0x32, - 0x86, 0x30, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x45, 0x56, 0x53, - 0x65, 0x63, 0x75, 0x72, 0x65, 0x2d, 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x65, - 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x47, - 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x50, 0x43, 0x41, 0x2e, 0x63, - 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, - 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x1d, - 0x11, 0x04, 0x23, 0x30, 0x21, 0xa4, 0x1f, 0x30, 0x1d, 0x31, 0x1b, 0x30, - 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x56, 0x65, 0x72, 0x69, - 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49, 0x2d, 0x32, 0x2d, 0x32, - 0x35, 0x33, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, - 0x14, 0x6f, 0x26, 0x56, 0xd9, 0x5c, 0xe7, 0xf7, 0xc9, 0x04, 0x20, 0xf8, - 0x1e, 0xba, 0x7c, 0x91, 0x27, 0x2f, 0x8c, 0xfa, 0x07, 0x30, 0x1f, 0x06, - 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2c, 0xd5, - 0x50, 0x41, 0x97, 0x15, 0x8b, 0xf0, 0x8f, 0x36, 0x61, 0x5b, 0x4a, 0xfb, - 0x6b, 0xd9, 0x99, 0xc9, 0x33, 0x92, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, - 0x01, 0x00, 0x92, 0x77, 0xe9, 0x57, 0xc9, 0xeb, 0xc4, 0x45, 0x6f, 0xc9, - 0x4c, 0x6e, 0x7d, 0x00, 0x12, 0x71, 0xa5, 0xe3, 0x39, 0xfe, 0x13, 0x84, - 0x49, 0x6c, 0xe7, 0x49, 0x71, 0xf5, 0x2c, 0xc7, 0xc0, 0x36, 0xc2, 0x08, - 0x58, 0xf3, 0x83, 0x75, 0xc5, 0x72, 0xd8, 0x8d, 0x78, 0xf4, 0x65, 0xea, - 0x8c, 0xd5, 0xe3, 0xa5, 0x0e, 0xa9, 0xad, 0xeb, 0xe3, 0xa1, 0x23, 0xae, - 0x93, 0xb7, 0xd8, 0x75, 0x75, 0x4a, 0x59, 0xcb, 0xf2, 0x9e, 0xdb, 0x40, - 0xbf, 0x4e, 0x89, 0xfe, 0x95, 0x42, 0x29, 0x34, 0x7b, 0xf4, 0xdd, 0x6a, - 0x0d, 0x74, 0x5f, 0xc7, 0x11, 0x13, 0x2e, 0xdd, 0x11, 0x6e, 0xc6, 0xe3, - 0x5b, 0xb3, 0xcf, 0xa6, 0x8d, 0xe5, 0xf7, 0x67, 0x7b, 0xba, 0xb3, 0xb3, - 0x69, 0x70, 0x14, 0xb0, 0xc2, 0x99, 0xb4, 0xd2, 0x76, 0x5b, 0x38, 0x17, - 0x39, 0x45, 0x1b, 0x82, 0xf1, 0x53, 0xb8, 0x3d, 0x55, 0x39, 0x0b, 0x7f, - 0xff, 0x98, 0xad, 0x6e, 0x96, 0x9a, 0xb6, 0x6a, 0x4c, 0x7a, 0x5e, 0xbd, - 0xb1, 0x86, 0x12, 0x9d, 0x7c, 0x2c, 0x62, 0xbb, 0x09, 0x93, 0x5f, 0x3f, - 0xd8, 0xb5, 0x8a, 0xc3, 0x49, 0x28, 0x0f, 0x0b, 0xf9, 0x39, 0x22, 0x1a, - 0xfe, 0x5d, 0xd3, 0xe8, 0x18, 0x5f, 0x9d, 0x5f, 0xb4, 0xc0, 0x20, 0xc6, - 0xa9, 0x49, 0x0d, 0x55, 0x73, 0x6a, 0x09, 0x7a, 0xff, 0xa2, 0x99, 0xbf, - 0xd8, 0xbb, 0x91, 0xdc, 0x30, 0x39, 0xae, 0x28, 0x4b, 0xf6, 0xc5, 0x77, - 0x24, 0xe8, 0xd6, 0xc6, 0xa7, 0xa0, 0x4e, 0xf2, 0xa6, 0x99, 0x75, 0xcd, - 0xdd, 0x57, 0xdd, 0x0a, 0x47, 0x92, 0xcb, 0xbb, 0xb7, 0x48, 0xfa, 0x21, - 0xf0, 0x69, 0x21, 0xff, 0xe5, 0x0c, 0xaa, 0x0c, 0xb1, 0xea, 0xdd, 0x05, - 0x1c, 0x19, 0x8e, 0xd1, 0x2a, 0x79, 0x68, 0x02, 0x5e, 0xcc, 0x38, 0xe6, - 0x29, 0xc4, 0x77, 0xf5, 0x19, 0x1c, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 3740804 (0x391484) - Signature Algorithm: sha256WithRSAEncryption - Issuer: C=US, O=Starfield Technologies, Inc., OU=Starfield Class 2 Certification Authority - Validity - Not Before: Jan 1 07:00:00 2014 GMT - Not After : May 30 07:00:00 2031 GMT - Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Root Certificate Authority - G2 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:bd:ed:c1:03:fc:f6:8f:fc:02:b1:6f:5b:9f:48: - d9:9d:79:e2:a2:b7:03:61:56:18:c3:47:b6:d7:ca: - 3d:35:2e:89:43:f7:a1:69:9b:de:8a:1a:fd:13:20: - 9c:b4:49:77:32:29:56:fd:b9:ec:8c:dd:22:fa:72: - dc:27:61:97:ee:f6:5a:84:ec:6e:19:b9:89:2c:dc: - 84:5b:d5:74:fb:6b:5f:c5:89:a5:10:52:89:46:55: - f4:b8:75:1c:e6:7f:e4:54:ae:4b:f8:55:72:57:02: - 19:f8:17:71:59:eb:1e:28:07:74:c5:9d:48:be:6c: - b4:f4:a4:b0:f3:64:37:79:92:c0:ec:46:5e:7f:e1: - 6d:53:4c:62:af:cd:1f:0b:63:bb:3a:9d:fb:fc:79: - 00:98:61:74:cf:26:82:40:63:f3:b2:72:6a:19:0d: - 99:ca:d4:0e:75:cc:37:fb:8b:89:c1:59:f1:62:7f: - 5f:b3:5f:65:30:f8:a7:b7:4d:76:5a:1e:76:5e:34: - c0:e8:96:56:99:8a:b3:f0:7f:a4:cd:bd:dc:32:31: - 7c:91:cf:e0:5f:11:f8:6b:aa:49:5c:d1:99:94:d1: - a2:e3:63:5b:09:76:b5:56:62:e1:4b:74:1d:96:d4: - 26:d4:08:04:59:d0:98:0e:0e:e6:de:fc:c3:ec:1f: - 90:f1 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Subject Key Identifier: - 7C:0C:32:1F:A7:D9:30:7F:C4:7D:68:A3:62:A8:A1:CE:AB:07:5B:27 - X509v3 Authority Key Identifier: - keyid:BF:5F:B7:D1:CE:DD:1F:86:F4:5B:55:AC:DC:D7:10:C2:0E:A9:88:E7 - - Authority Information Access: - OCSP - URI:http://ocsp.starfieldtech.com/ - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.starfieldtech.com/sfroot.crl - - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://certs.starfieldtech.com/repository/ - - Signature Algorithm: sha256WithRSAEncryption - 85:63:c1:d9:dd:b9:ff:a9:bd:a6:19:dc:bf:13:3a:11:38:22: - 54:b1:ac:05:10:fb:7c:b3:96:3f:31:8b:66:ff:88:f3:e1:bf: - fb:c7:1f:00:ff:46:6a:8b:61:32:c9:01:51:76:fb:9a:c6:fa: - 20:51:c8:46:c4:98:d7:79:a3:e3:04:72:3f:8b:4d:34:53:67: - ec:33:2c:7b:e8:94:01:28:7c:3a:34:5b:02:77:16:8d:40:25: - 33:b0:bc:6c:97:d7:05:7a:ff:8c:85:ce:6f:a0:53:00:17:6e: - 1e:6c:bd:22:d7:0a:88:37:f6:7d:eb:99:41:ef:27:cb:8c:60: - 6b:4c:01:7e:65:50:0b:4f:b8:95:9a:9a:6e:34:fd:73:3a:33: - f1:91:d5:f3:4e:2d:74:e8:ef:d3:90:35:f1:06:68:64:d4:d0: - 13:fd:52:d3:c6:6d:c1:3a:8a:31:dd:05:26:35:4a:8c:65:b8: - 52:6b:81:ec:d2:9c:b5:34:10:97:9c:3e:c6:2f:ed:8e:42:42: - 24:2e:e9:73:9a:25:f9:11:f1:f2:23:69:cb:e5:94:69:a0:d2: - dc:b0:fc:44:89:ac:17:a8:cc:d5:37:77:16:c5:80:b9:0c:8f: - 57:02:55:99:85:7b:49:f0:2e:5b:a0:c2:57:53:5d:a2:e8:a6: - 37:c3:01:fa ------BEGIN CERTIFICATE----- -MIIEoDCCA4igAwIBAgIDORSEMA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNVBAYTAlVT -MSUwIwYDVQQKExxTdGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQL -EylTdGFyZmllbGQgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x -NDAxMDEwNzAwMDBaFw0zMTA1MzAwNzAwMDBaMIGPMQswCQYDVQQGEwJVUzEQMA4G -A1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTElMCMGA1UEChMcU3Rh -cmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UEAxMpU3RhcmZpZWxkIFJv -b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUA -A4IBDwAwggEKAoIBAQC97cED/PaP/AKxb1ufSNmdeeKitwNhVhjDR7bXyj01LolD -96Fpm96KGv0TIJy0SXcyKVb9ueyM3SL6ctwnYZfu9lqE7G4ZuYks3IRb1XT7a1/F -iaUQUolGVfS4dRzmf+RUrkv4VXJXAhn4F3FZ6x4oB3TFnUi+bLT0pLDzZDd5ksDs -Rl5/4W1TTGKvzR8LY7s6nfv8eQCYYXTPJoJAY/OycmoZDZnK1A51zDf7i4nBWfFi -f1+zX2Uw+Ke3TXZaHnZeNMDollaZirPwf6TNvdwyMXyRz+BfEfhrqklc0ZmU0aLj -Y1sJdrVWYuFLdB2W1CbUCARZ0JgODube/MPsH5DxAgMBAAGjggEpMIIBJTAPBgNV -HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUfAwyH6fZMH/E -fWijYqihzqsHWycwHwYDVR0jBBgwFoAUv1+30c7dH4b0W1Ws3NcQwg6piOcwOgYI -KwYBBQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vb2NzcC5zdGFyZmllbGR0 -ZWNoLmNvbS8wOAYDVR0fBDEwLzAtoCugKYYnaHR0cDovL2NybC5zdGFyZmllbGR0 -ZWNoLmNvbS9zZnJvb3QuY3JsMEwGA1UdIARFMEMwQQYEVR0gADA5MDcGCCsGAQUF -BwIBFitodHRwczovL2NlcnRzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkv -MA0GCSqGSIb3DQEBCwUAA4IBAQCFY8HZ3bn/qb2mGdy/EzoROCJUsawFEPt8s5Y/ -MYtm/4jz4b/7xx8A/0Zqi2EyyQFRdvuaxvogUchGxJjXeaPjBHI/i000U2fsMyx7 -6JQBKHw6NFsCdxaNQCUzsLxsl9cFev+Mhc5voFMAF24ebL0i1wqIN/Z965lB7yfL -jGBrTAF+ZVALT7iVmppuNP1zOjPxkdXzTi106O/TkDXxBmhk1NAT/VLTxm3BOoox -3QUmNUqMZbhSa4Hs0py1NBCXnD7GL+2OQkIkLulzmiX5EfHyI2nL5ZRpoNLcsPxE -iawXqMzVN3cWxYC5DI9XAlWZhXtJ8C5boMJXU12i6KY3wwH6 ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert27[] = { - 0x30, 0x82, 0x04, 0xa0, 0x30, 0x82, 0x03, 0x88, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x03, 0x39, 0x14, 0x84, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x68, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, - 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53, - 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63, - 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49, - 0x6e, 0x63, 0x2e, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, - 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, - 0x34, 0x30, 0x31, 0x30, 0x31, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5a, - 0x17, 0x0d, 0x33, 0x31, 0x30, 0x35, 0x33, 0x30, 0x30, 0x37, 0x30, 0x30, - 0x30, 0x30, 0x5a, 0x30, 0x81, 0x8f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, - 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, - 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, - 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x25, - 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53, 0x74, 0x61, - 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6e, - 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, - 0x2e, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, - 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x52, 0x6f, - 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, - 0x20, 0x2d, 0x20, 0x47, 0x32, 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, 0xbd, 0xed, 0xc1, 0x03, 0xfc, 0xf6, 0x8f, 0xfc, 0x02, 0xb1, - 0x6f, 0x5b, 0x9f, 0x48, 0xd9, 0x9d, 0x79, 0xe2, 0xa2, 0xb7, 0x03, 0x61, - 0x56, 0x18, 0xc3, 0x47, 0xb6, 0xd7, 0xca, 0x3d, 0x35, 0x2e, 0x89, 0x43, - 0xf7, 0xa1, 0x69, 0x9b, 0xde, 0x8a, 0x1a, 0xfd, 0x13, 0x20, 0x9c, 0xb4, - 0x49, 0x77, 0x32, 0x29, 0x56, 0xfd, 0xb9, 0xec, 0x8c, 0xdd, 0x22, 0xfa, - 0x72, 0xdc, 0x27, 0x61, 0x97, 0xee, 0xf6, 0x5a, 0x84, 0xec, 0x6e, 0x19, - 0xb9, 0x89, 0x2c, 0xdc, 0x84, 0x5b, 0xd5, 0x74, 0xfb, 0x6b, 0x5f, 0xc5, - 0x89, 0xa5, 0x10, 0x52, 0x89, 0x46, 0x55, 0xf4, 0xb8, 0x75, 0x1c, 0xe6, - 0x7f, 0xe4, 0x54, 0xae, 0x4b, 0xf8, 0x55, 0x72, 0x57, 0x02, 0x19, 0xf8, - 0x17, 0x71, 0x59, 0xeb, 0x1e, 0x28, 0x07, 0x74, 0xc5, 0x9d, 0x48, 0xbe, - 0x6c, 0xb4, 0xf4, 0xa4, 0xb0, 0xf3, 0x64, 0x37, 0x79, 0x92, 0xc0, 0xec, - 0x46, 0x5e, 0x7f, 0xe1, 0x6d, 0x53, 0x4c, 0x62, 0xaf, 0xcd, 0x1f, 0x0b, - 0x63, 0xbb, 0x3a, 0x9d, 0xfb, 0xfc, 0x79, 0x00, 0x98, 0x61, 0x74, 0xcf, - 0x26, 0x82, 0x40, 0x63, 0xf3, 0xb2, 0x72, 0x6a, 0x19, 0x0d, 0x99, 0xca, - 0xd4, 0x0e, 0x75, 0xcc, 0x37, 0xfb, 0x8b, 0x89, 0xc1, 0x59, 0xf1, 0x62, - 0x7f, 0x5f, 0xb3, 0x5f, 0x65, 0x30, 0xf8, 0xa7, 0xb7, 0x4d, 0x76, 0x5a, - 0x1e, 0x76, 0x5e, 0x34, 0xc0, 0xe8, 0x96, 0x56, 0x99, 0x8a, 0xb3, 0xf0, - 0x7f, 0xa4, 0xcd, 0xbd, 0xdc, 0x32, 0x31, 0x7c, 0x91, 0xcf, 0xe0, 0x5f, - 0x11, 0xf8, 0x6b, 0xaa, 0x49, 0x5c, 0xd1, 0x99, 0x94, 0xd1, 0xa2, 0xe3, - 0x63, 0x5b, 0x09, 0x76, 0xb5, 0x56, 0x62, 0xe1, 0x4b, 0x74, 0x1d, 0x96, - 0xd4, 0x26, 0xd4, 0x08, 0x04, 0x59, 0xd0, 0x98, 0x0e, 0x0e, 0xe6, 0xde, - 0xfc, 0xc3, 0xec, 0x1f, 0x90, 0xf1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, - 0x82, 0x01, 0x29, 0x30, 0x82, 0x01, 0x25, 0x30, 0x0f, 0x06, 0x03, 0x55, - 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, - 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, - 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, - 0x16, 0x04, 0x14, 0x7c, 0x0c, 0x32, 0x1f, 0xa7, 0xd9, 0x30, 0x7f, 0xc4, - 0x7d, 0x68, 0xa3, 0x62, 0xa8, 0xa1, 0xce, 0xab, 0x07, 0x5b, 0x27, 0x30, - 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, - 0xbf, 0x5f, 0xb7, 0xd1, 0xce, 0xdd, 0x1f, 0x86, 0xf4, 0x5b, 0x55, 0xac, - 0xdc, 0xd7, 0x10, 0xc2, 0x0e, 0xa9, 0x88, 0xe7, 0x30, 0x3a, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x2e, 0x30, 0x2c, - 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, - 0x86, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, - 0x70, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74, - 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x38, 0x06, 0x03, - 0x55, 0x1d, 0x1f, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0xa0, 0x2b, 0xa0, - 0x29, 0x86, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, - 0x6c, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74, - 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x66, 0x72, 0x6f, - 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, - 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0x06, 0x04, 0x55, 0x1d, 0x20, - 0x00, 0x30, 0x39, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x02, 0x01, 0x16, 0x2b, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, - 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x85, 0x63, 0xc1, 0xd9, - 0xdd, 0xb9, 0xff, 0xa9, 0xbd, 0xa6, 0x19, 0xdc, 0xbf, 0x13, 0x3a, 0x11, - 0x38, 0x22, 0x54, 0xb1, 0xac, 0x05, 0x10, 0xfb, 0x7c, 0xb3, 0x96, 0x3f, - 0x31, 0x8b, 0x66, 0xff, 0x88, 0xf3, 0xe1, 0xbf, 0xfb, 0xc7, 0x1f, 0x00, - 0xff, 0x46, 0x6a, 0x8b, 0x61, 0x32, 0xc9, 0x01, 0x51, 0x76, 0xfb, 0x9a, - 0xc6, 0xfa, 0x20, 0x51, 0xc8, 0x46, 0xc4, 0x98, 0xd7, 0x79, 0xa3, 0xe3, - 0x04, 0x72, 0x3f, 0x8b, 0x4d, 0x34, 0x53, 0x67, 0xec, 0x33, 0x2c, 0x7b, - 0xe8, 0x94, 0x01, 0x28, 0x7c, 0x3a, 0x34, 0x5b, 0x02, 0x77, 0x16, 0x8d, - 0x40, 0x25, 0x33, 0xb0, 0xbc, 0x6c, 0x97, 0xd7, 0x05, 0x7a, 0xff, 0x8c, - 0x85, 0xce, 0x6f, 0xa0, 0x53, 0x00, 0x17, 0x6e, 0x1e, 0x6c, 0xbd, 0x22, - 0xd7, 0x0a, 0x88, 0x37, 0xf6, 0x7d, 0xeb, 0x99, 0x41, 0xef, 0x27, 0xcb, - 0x8c, 0x60, 0x6b, 0x4c, 0x01, 0x7e, 0x65, 0x50, 0x0b, 0x4f, 0xb8, 0x95, - 0x9a, 0x9a, 0x6e, 0x34, 0xfd, 0x73, 0x3a, 0x33, 0xf1, 0x91, 0xd5, 0xf3, - 0x4e, 0x2d, 0x74, 0xe8, 0xef, 0xd3, 0x90, 0x35, 0xf1, 0x06, 0x68, 0x64, - 0xd4, 0xd0, 0x13, 0xfd, 0x52, 0xd3, 0xc6, 0x6d, 0xc1, 0x3a, 0x8a, 0x31, - 0xdd, 0x05, 0x26, 0x35, 0x4a, 0x8c, 0x65, 0xb8, 0x52, 0x6b, 0x81, 0xec, - 0xd2, 0x9c, 0xb5, 0x34, 0x10, 0x97, 0x9c, 0x3e, 0xc6, 0x2f, 0xed, 0x8e, - 0x42, 0x42, 0x24, 0x2e, 0xe9, 0x73, 0x9a, 0x25, 0xf9, 0x11, 0xf1, 0xf2, - 0x23, 0x69, 0xcb, 0xe5, 0x94, 0x69, 0xa0, 0xd2, 0xdc, 0xb0, 0xfc, 0x44, - 0x89, 0xac, 0x17, 0xa8, 0xcc, 0xd5, 0x37, 0x77, 0x16, 0xc5, 0x80, 0xb9, - 0x0c, 0x8f, 0x57, 0x02, 0x55, 0x99, 0x85, 0x7b, 0x49, 0xf0, 0x2e, 0x5b, - 0xa0, 0xc2, 0x57, 0x53, 0x5d, 0xa2, 0xe8, 0xa6, 0x37, 0xc3, 0x01, 0xfa, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 5a:b6:1d:ac:1e:4d:a2:06:14:c7:55:3d:3d:a9:b2:dc - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network, OU=http://www.usertrust.com, CN=UTN-USERFirst-Hardware - Validity - Not Before: Oct 23 00:00:00 2008 GMT - Not After : May 30 10:48:38 2020 GMT - Subject: C=FR, O=GANDI SAS, CN=Gandi Standard SSL CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:b6:54:3d:a5:db:0d:22:78:50:6a:5a:23:89:3f: - 97:a1:d4:07:1a:a9:58:08:9b:a0:15:c3:32:b6:b7: - f1:e8:b9:a5:6f:ad:37:f6:6e:71:1b:b4:75:2d:48: - 5e:9f:c6:15:aa:81:ef:e5:c4:88:95:8a:3a:6c:77: - cc:b5:cd:65:e4:67:e5:73:c9:50:52:94:c1:27:49: - 3e:a0:6b:41:16:41:b6:94:99:41:ae:3e:cb:e2:06: - 46:09:e9:4d:be:c9:4c:55:a9:18:7e:a6:df:6e:fd: - 4a:b2:cc:6c:4e:d9:c8:50:15:93:b3:f2:e9:e3:c2: - 6a:ad:3a:d5:fb:c3:79:50:9f:25:79:29:b2:47:64: - 7c:20:3e:e2:08:4d:93:29:14:b6:34:6e:cf:71:46: - 7e:76:10:f4:fd:6c:aa:01:d2:c2:06:de:92:83:cc: - 58:90:2e:92:de:1e:65:b7:63:2f:3d:b2:eb:70:8c: - 4c:e0:be:15:9d:de:c1:4d:56:f8:0b:c6:8e:07:b9: - 5d:df:95:f0:7b:40:1f:1a:2c:d7:9c:2b:4b:76:f4: - 59:f5:43:c1:2c:66:10:9e:9e:66:96:60:9d:1c:74: - 1b:4e:18:5c:08:b0:6e:6c:ca:69:1a:02:e9:bb:ca: - 78:ef:66:2e:e3:32:fd:41:5c:95:74:81:4d:f4:da: - fe:4b - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Authority Key Identifier: - keyid:A1:72:5F:26:1B:28:98:43:95:5D:07:37:D5:85:96:9D:4B:D2:C3:45 - - X509v3 Subject Key Identifier: - B6:A8:FF:A2:A8:2F:D0:A6:CD:4B:B1:68:F3:E7:50:10:31:A7:79:21 - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Certificate Policies: - Policy: 1.3.6.1.4.1.6449.1.2.2.26 - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.usertrust.com/UTN-USERFirst-Hardware.crl - - Authority Information Access: - CA Issuers - URI:http://crt.usertrust.com/UTNAddTrustServer_CA.crt - OCSP - URI:http://ocsp.usertrust.com - - Signature Algorithm: sha1WithRSAEncryption - 19:53:bf:03:3d:9b:e2:6b:5a:fd:ba:49:1f:4f:ec:e1:c6:82: - 39:3c:d2:03:04:0f:ab:7b:3e:82:a9:85:10:1f:f4:de:32:af: - 58:3f:ff:70:f3:30:1d:97:2d:4c:9a:e2:ec:0c:3e:14:2d:2f: - 98:48:9d:ae:16:6a:ac:2d:42:aa:b5:64:a4:70:bb:eb:73:94: - 7b:46:4c:e7:7a:14:76:5b:4c:1d:84:a1:20:74:1f:2e:4b:5c: - 70:88:dc:bd:f7:19:3d:ed:59:0d:e2:3f:26:e2:9c:ac:a4:3c: - 95:1c:f8:be:8c:03:ae:f0:e5:9c:4d:bc:c7:9b:58:00:bf:af: - ad:fa:37:6e:71:6d:18:34:0e:c1:ea:6a:f8:0d:df:69:54:56: - 15:f2:28:b3:fe:a4:63:ec:c5:04:64:60:bb:fe:2a:f0:f4:87: - a1:b0:ae:bd:aa:e4:2f:e3:03:0b:2f:66:5f:85:a4:32:7b:46: - ed:25:0c:e7:f1:b7:e7:19:fd:60:ba:5f:87:77:de:98:07:96: - e4:5e:ea:63:7d:a8:de:55:da:61:5c:3c:90:83:43:04:07:3c: - dd:f3:f8:9f:06:52:0a:de:c7:b6:7b:8f:e1:11:f7:04:7a:35: - ff:6a:bc:5b:c7:50:49:08:70:6f:94:43:cd:9e:c7:70:f1:db: - d0:6d:da:8f ------BEGIN CERTIFICATE----- -MIIEozCCA4ugAwIBAgIQWrYdrB5NogYUx1U9Pamy3DANBgkqhkiG9w0BAQUFADCB -lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug -Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt -SGFyZHdhcmUwHhcNMDgxMDIzMDAwMDAwWhcNMjAwNTMwMTA0ODM4WjBBMQswCQYD -VQQGEwJGUjESMBAGA1UEChMJR0FOREkgU0FTMR4wHAYDVQQDExVHYW5kaSBTdGFu -ZGFyZCBTU0wgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2VD2l -2w0ieFBqWiOJP5eh1AcaqVgIm6AVwzK2t/HouaVvrTf2bnEbtHUtSF6fxhWqge/l -xIiVijpsd8y1zWXkZ+VzyVBSlMEnST6ga0EWQbaUmUGuPsviBkYJ6U2+yUxVqRh+ -pt9u/UqyzGxO2chQFZOz8unjwmqtOtX7w3lQnyV5KbJHZHwgPuIITZMpFLY0bs9x -Rn52EPT9bKoB0sIG3pKDzFiQLpLeHmW3Yy89sutwjEzgvhWd3sFNVvgLxo4HuV3f -lfB7QB8aLNecK0t29Fn1Q8EsZhCenmaWYJ0cdBtOGFwIsG5symkaAum7ynjvZi7j -Mv1BXJV0gU302v5LAgMBAAGjggE+MIIBOjAfBgNVHSMEGDAWgBShcl8mGyiYQ5Vd -BzfVhZadS9LDRTAdBgNVHQ4EFgQUtqj/oqgv0KbNS7Fo8+dQEDGneSEwDgYDVR0P -AQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwGAYDVR0gBBEwDzANBgsrBgEE -AbIxAQICGjBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8vY3JsLnVzZXJ0cnVzdC5j -b20vVVROLVVTRVJGaXJzdC1IYXJkd2FyZS5jcmwwdAYIKwYBBQUHAQEEaDBmMD0G -CCsGAQUFBzAChjFodHRwOi8vY3J0LnVzZXJ0cnVzdC5jb20vVVROQWRkVHJ1c3RT -ZXJ2ZXJfQ0EuY3J0MCUGCCsGAQUFBzABhhlodHRwOi8vb2NzcC51c2VydHJ1c3Qu -Y29tMA0GCSqGSIb3DQEBBQUAA4IBAQAZU78DPZvia1r9ukkfT+zhxoI5PNIDBA+r -ez6CqYUQH/TeMq9YP/9w8zAdly1MmuLsDD4ULS+YSJ2uFmqsLUKqtWSkcLvrc5R7 -RkznehR2W0wdhKEgdB8uS1xwiNy99xk97VkN4j8m4pyspDyVHPi+jAOu8OWcTbzH -m1gAv6+t+jducW0YNA7B6mr4Dd9pVFYV8iiz/qRj7MUEZGC7/irw9IehsK69quQv -4wMLL2ZfhaQye0btJQzn8bfnGf1gul+Hd96YB5bkXupjfajeVdphXDyQg0MEBzzd -8/ifBlIK3se2e4/hEfcEejX/arxbx1BJCHBvlEPNnsdw8dvQbdqP ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert28[] = { - 0x30, 0x82, 0x04, 0xa3, 0x30, 0x82, 0x03, 0x8b, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x5a, 0xb6, 0x1d, 0xac, 0x1e, 0x4d, 0xa2, 0x06, 0x14, - 0xc7, 0x55, 0x3d, 0x3d, 0xa9, 0xb2, 0xdc, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, - 0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x02, 0x55, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x07, - 0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, 0x6b, 0x65, 0x20, - 0x43, 0x69, 0x74, 0x79, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, - 0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75, 0x73, - 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x31, - 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x55, 0x54, - 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74, 0x2d, - 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x30, 0x1e, 0x17, 0x0d, - 0x30, 0x38, 0x31, 0x30, 0x32, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x35, 0x33, 0x30, 0x31, 0x30, 0x34, - 0x38, 0x33, 0x38, 0x5a, 0x30, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x04, 0x06, 0x13, 0x02, 0x46, 0x52, 0x31, 0x12, 0x30, 0x10, 0x06, - 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, 0x47, 0x41, 0x4e, 0x44, 0x49, 0x20, - 0x53, 0x41, 0x53, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x15, 0x47, 0x61, 0x6e, 0x64, 0x69, 0x20, 0x53, 0x74, 0x61, 0x6e, - 0x64, 0x61, 0x72, 0x64, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 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, 0xb6, 0x54, 0x3d, 0xa5, - 0xdb, 0x0d, 0x22, 0x78, 0x50, 0x6a, 0x5a, 0x23, 0x89, 0x3f, 0x97, 0xa1, - 0xd4, 0x07, 0x1a, 0xa9, 0x58, 0x08, 0x9b, 0xa0, 0x15, 0xc3, 0x32, 0xb6, - 0xb7, 0xf1, 0xe8, 0xb9, 0xa5, 0x6f, 0xad, 0x37, 0xf6, 0x6e, 0x71, 0x1b, - 0xb4, 0x75, 0x2d, 0x48, 0x5e, 0x9f, 0xc6, 0x15, 0xaa, 0x81, 0xef, 0xe5, - 0xc4, 0x88, 0x95, 0x8a, 0x3a, 0x6c, 0x77, 0xcc, 0xb5, 0xcd, 0x65, 0xe4, - 0x67, 0xe5, 0x73, 0xc9, 0x50, 0x52, 0x94, 0xc1, 0x27, 0x49, 0x3e, 0xa0, - 0x6b, 0x41, 0x16, 0x41, 0xb6, 0x94, 0x99, 0x41, 0xae, 0x3e, 0xcb, 0xe2, - 0x06, 0x46, 0x09, 0xe9, 0x4d, 0xbe, 0xc9, 0x4c, 0x55, 0xa9, 0x18, 0x7e, - 0xa6, 0xdf, 0x6e, 0xfd, 0x4a, 0xb2, 0xcc, 0x6c, 0x4e, 0xd9, 0xc8, 0x50, - 0x15, 0x93, 0xb3, 0xf2, 0xe9, 0xe3, 0xc2, 0x6a, 0xad, 0x3a, 0xd5, 0xfb, - 0xc3, 0x79, 0x50, 0x9f, 0x25, 0x79, 0x29, 0xb2, 0x47, 0x64, 0x7c, 0x20, - 0x3e, 0xe2, 0x08, 0x4d, 0x93, 0x29, 0x14, 0xb6, 0x34, 0x6e, 0xcf, 0x71, - 0x46, 0x7e, 0x76, 0x10, 0xf4, 0xfd, 0x6c, 0xaa, 0x01, 0xd2, 0xc2, 0x06, - 0xde, 0x92, 0x83, 0xcc, 0x58, 0x90, 0x2e, 0x92, 0xde, 0x1e, 0x65, 0xb7, - 0x63, 0x2f, 0x3d, 0xb2, 0xeb, 0x70, 0x8c, 0x4c, 0xe0, 0xbe, 0x15, 0x9d, - 0xde, 0xc1, 0x4d, 0x56, 0xf8, 0x0b, 0xc6, 0x8e, 0x07, 0xb9, 0x5d, 0xdf, - 0x95, 0xf0, 0x7b, 0x40, 0x1f, 0x1a, 0x2c, 0xd7, 0x9c, 0x2b, 0x4b, 0x76, - 0xf4, 0x59, 0xf5, 0x43, 0xc1, 0x2c, 0x66, 0x10, 0x9e, 0x9e, 0x66, 0x96, - 0x60, 0x9d, 0x1c, 0x74, 0x1b, 0x4e, 0x18, 0x5c, 0x08, 0xb0, 0x6e, 0x6c, - 0xca, 0x69, 0x1a, 0x02, 0xe9, 0xbb, 0xca, 0x78, 0xef, 0x66, 0x2e, 0xe3, - 0x32, 0xfd, 0x41, 0x5c, 0x95, 0x74, 0x81, 0x4d, 0xf4, 0xda, 0xfe, 0x4b, - 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x3e, 0x30, 0x82, 0x01, - 0x3a, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, - 0x80, 0x14, 0xa1, 0x72, 0x5f, 0x26, 0x1b, 0x28, 0x98, 0x43, 0x95, 0x5d, - 0x07, 0x37, 0xd5, 0x85, 0x96, 0x9d, 0x4b, 0xd2, 0xc3, 0x45, 0x30, 0x1d, - 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb6, 0xa8, 0xff, - 0xa2, 0xa8, 0x2f, 0xd0, 0xa6, 0xcd, 0x4b, 0xb1, 0x68, 0xf3, 0xe7, 0x50, - 0x10, 0x31, 0xa7, 0x79, 0x21, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, - 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, - 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, - 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x18, 0x06, 0x03, 0x55, 0x1d, 0x20, - 0x04, 0x11, 0x30, 0x0f, 0x30, 0x0d, 0x06, 0x0b, 0x2b, 0x06, 0x01, 0x04, - 0x01, 0xb2, 0x31, 0x01, 0x02, 0x02, 0x1a, 0x30, 0x44, 0x06, 0x03, 0x55, - 0x1d, 0x1f, 0x04, 0x3d, 0x30, 0x3b, 0x30, 0x39, 0xa0, 0x37, 0xa0, 0x35, - 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, - 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, - 0x69, 0x72, 0x73, 0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, - 0x65, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x74, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x68, 0x30, 0x66, 0x30, 0x3d, 0x06, - 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x31, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x75, 0x73, - 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x55, 0x54, 0x4e, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, - 0x30, 0x25, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, - 0x86, 0x19, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, - 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, - 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x19, - 0x53, 0xbf, 0x03, 0x3d, 0x9b, 0xe2, 0x6b, 0x5a, 0xfd, 0xba, 0x49, 0x1f, - 0x4f, 0xec, 0xe1, 0xc6, 0x82, 0x39, 0x3c, 0xd2, 0x03, 0x04, 0x0f, 0xab, - 0x7b, 0x3e, 0x82, 0xa9, 0x85, 0x10, 0x1f, 0xf4, 0xde, 0x32, 0xaf, 0x58, - 0x3f, 0xff, 0x70, 0xf3, 0x30, 0x1d, 0x97, 0x2d, 0x4c, 0x9a, 0xe2, 0xec, - 0x0c, 0x3e, 0x14, 0x2d, 0x2f, 0x98, 0x48, 0x9d, 0xae, 0x16, 0x6a, 0xac, - 0x2d, 0x42, 0xaa, 0xb5, 0x64, 0xa4, 0x70, 0xbb, 0xeb, 0x73, 0x94, 0x7b, - 0x46, 0x4c, 0xe7, 0x7a, 0x14, 0x76, 0x5b, 0x4c, 0x1d, 0x84, 0xa1, 0x20, - 0x74, 0x1f, 0x2e, 0x4b, 0x5c, 0x70, 0x88, 0xdc, 0xbd, 0xf7, 0x19, 0x3d, - 0xed, 0x59, 0x0d, 0xe2, 0x3f, 0x26, 0xe2, 0x9c, 0xac, 0xa4, 0x3c, 0x95, - 0x1c, 0xf8, 0xbe, 0x8c, 0x03, 0xae, 0xf0, 0xe5, 0x9c, 0x4d, 0xbc, 0xc7, - 0x9b, 0x58, 0x00, 0xbf, 0xaf, 0xad, 0xfa, 0x37, 0x6e, 0x71, 0x6d, 0x18, - 0x34, 0x0e, 0xc1, 0xea, 0x6a, 0xf8, 0x0d, 0xdf, 0x69, 0x54, 0x56, 0x15, - 0xf2, 0x28, 0xb3, 0xfe, 0xa4, 0x63, 0xec, 0xc5, 0x04, 0x64, 0x60, 0xbb, - 0xfe, 0x2a, 0xf0, 0xf4, 0x87, 0xa1, 0xb0, 0xae, 0xbd, 0xaa, 0xe4, 0x2f, - 0xe3, 0x03, 0x0b, 0x2f, 0x66, 0x5f, 0x85, 0xa4, 0x32, 0x7b, 0x46, 0xed, - 0x25, 0x0c, 0xe7, 0xf1, 0xb7, 0xe7, 0x19, 0xfd, 0x60, 0xba, 0x5f, 0x87, - 0x77, 0xde, 0x98, 0x07, 0x96, 0xe4, 0x5e, 0xea, 0x63, 0x7d, 0xa8, 0xde, - 0x55, 0xda, 0x61, 0x5c, 0x3c, 0x90, 0x83, 0x43, 0x04, 0x07, 0x3c, 0xdd, - 0xf3, 0xf8, 0x9f, 0x06, 0x52, 0x0a, 0xde, 0xc7, 0xb6, 0x7b, 0x8f, 0xe1, - 0x11, 0xf7, 0x04, 0x7a, 0x35, 0xff, 0x6a, 0xbc, 0x5b, 0xc7, 0x50, 0x49, - 0x08, 0x70, 0x6f, 0x94, 0x43, 0xcd, 0x9e, 0xc7, 0x70, 0xf1, 0xdb, 0xd0, - 0x6d, 0xda, 0x8f, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 10:e7:76:e8:a6:5a:6e:37:7e:05:03:06:d4:3c:25:ea - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network, OU=http://www.usertrust.com, CN=UTN-USERFirst-Hardware - Validity - Not Before: Apr 10 00:00:00 2006 GMT - Not After : May 30 10:48:38 2020 GMT - Subject: C=US, O=Network Solutions L.L.C., CN=Network Solutions Certificate Authority - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:c3:dd:36:cc:83:c3:18:55:b0:96:d9:13:25:d3: - 26:86:48:38:bb:16:7f:f1:9f:29:f6:fd:03:f1:ed: - 4d:26:9a:56:f0:b5:1a:1a:cd:e6:cc:85:55:40:a4: - b5:d0:0d:ca:22:ef:3d:23:c6:7e:6c:cc:bc:a1:e9: - 7c:50:46:e0:bd:14:ad:65:12:c2:0b:11:69:52:0a: - 07:92:1f:73:6f:c1:ba:d7:62:f0:ce:00:2e:34:a5: - c8:e6:2f:0f:ec:0d:ea:44:61:75:68:e5:e4:dc:80: - 36:4f:da:78:5d:53:25:94:94:f5:4f:2e:3a:60:6f: - 0c:a6:d9:b3:f6:2a:2e:03:12:d5:26:42:07:51:b2: - 64:57:71:dc:21:1c:89:c7:69:a3:e6:fb:c2:7b:6e: - ef:0c:87:fb:50:64:e8:4e:4b:ef:e7:71:9b:83:63: - 61:c9:32:8d:8c:ec:14:a7:e4:89:ad:3f:2b:26:64: - e4:85:42:f2:89:50:e1:3a:be:15:e3:45:25:e2:5a: - cb:8c:3f:e0:33:1e:35:09:5a:84:ea:7e:5d:a1:f5: - 91:80:0a:28:06:b7:cb:31:41:25:61:8b:01:e9:56: - a2:f6:3e:5f:2f:f3:c4:43:f6:19:94:75:83:4c:a1: - 82:42:3a:c6:ba:c4:09:30:a6:e1:75:02:51:b9:5e: - 64:8b - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Authority Key Identifier: - keyid:A1:72:5F:26:1B:28:98:43:95:5D:07:37:D5:85:96:9D:4B:D2:C3:45 - - X509v3 Subject Key Identifier: - 3C:41:E2:8F:08:08:A9:4C:25:89:8D:6D:C5:38:D0:FC:85:8C:62:17 - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Certificate Policies: - Policy: 1.3.6.1.4.1.782.1.2.1.3.1 - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.usertrust.com/UTN-USERFirst-Hardware.crl - - Authority Information Access: - CA Issuers - URI:http://www.usertrust.com/cacerts/UTNAddTrustServer_CA.crt - - Signature Algorithm: sha1WithRSAEncryption - 68:ab:fc:ef:80:6b:18:b2:b0:b3:a3:45:89:cb:53:c5:a2:e6: - af:08:a9:fd:ff:0f:49:ac:ff:e4:9f:d7:41:7c:a3:c5:a2:e8: - aa:e0:57:21:2d:c3:aa:7c:0c:4c:28:0b:79:f4:ee:4c:32:ad: - 79:0e:7e:a2:5e:34:18:4f:df:54:f1:bd:68:7c:e3:d3:d7:46: - 5e:6d:64:c2:f7:6d:88:82:73:0c:ef:99:85:ea:a9:ef:32:4a: - f0:83:9f:73:91:0c:a4:3e:2b:31:51:a6:62:8f:15:84:f9:a6: - 3a:12:30:3f:da:6e:f8:cc:c7:19:92:0f:5c:f4:fe:17:f1:95: - 08:47:52:2c:50:8f:e8:9b:a5:ee:ae:70:33:89:91:82:fe:30: - aa:76:76:59:d7:6c:18:d3:2b:12:5b:1d:28:1d:78:71:f6:cd: - 36:a2:e9:07:48:44:3b:e7:57:6e:82:0a:ad:c5:8a:dd:e8:53: - b4:71:af:13:d2:06:9d:37:6d:53:3f:8a:35:08:fa:fe:a2:16: - e6:b9:6f:5c:56:39:d6:c6:aa:ef:19:67:ce:13:c5:b8:95:05: - fb:0a:44:c9:9f:a9:40:25:4b:32:11:af:07:fe:08:d5:42:71: - e9:e1:53:8b:15:1f:dd:2a:07:95:70:24:6f:64:5e:d3:b7:90: - 2e:8b:21:d8 ------BEGIN CERTIFICATE----- -MIIEpjCCA46gAwIBAgIQEOd26KZabjd+BQMG1Dwl6jANBgkqhkiG9w0BAQUFADCB -lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug -Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt -SGFyZHdhcmUwHhcNMDYwNDEwMDAwMDAwWhcNMjAwNTMwMTA0ODM4WjBiMQswCQYD -VQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYD -VQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDD3TbMg8MYVbCW2RMl0yaGSDi7 -Fn/xnyn2/QPx7U0mmlbwtRoazebMhVVApLXQDcoi7z0jxn5szLyh6XxQRuC9FK1l -EsILEWlSCgeSH3NvwbrXYvDOAC40pcjmLw/sDepEYXVo5eTcgDZP2nhdUyWUlPVP -Ljpgbwym2bP2Ki4DEtUmQgdRsmRXcdwhHInHaaPm+8J7bu8Mh/tQZOhOS+/ncZuD -Y2HJMo2M7BSn5ImtPysmZOSFQvKJUOE6vhXjRSXiWsuMP+AzHjUJWoTqfl2h9ZGA -CigGt8sxQSVhiwHpVqL2Pl8v88RD9hmUdYNMoYJCOsa6xAkwpuF1AlG5XmSLAgMB -AAGjggEgMIIBHDAfBgNVHSMEGDAWgBShcl8mGyiYQ5VdBzfVhZadS9LDRTAdBgNV -HQ4EFgQUPEHijwgIqUwliY1txTjQ/IWMYhcwDgYDVR0PAQH/BAQDAgEGMBIGA1Ud -EwEB/wQIMAYBAf8CAQAwGQYDVR0gBBIwEDAOBgwrBgEEAYYOAQIBAwEwRAYDVR0f -BD0wOzA5oDegNYYzaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmly -c3QtSGFyZHdhcmUuY3JsMFUGCCsGAQUFBwEBBEkwRzBFBggrBgEFBQcwAoY5aHR0 -cDovL3d3dy51c2VydHJ1c3QuY29tL2NhY2VydHMvVVROQWRkVHJ1c3RTZXJ2ZXJf -Q0EuY3J0MA0GCSqGSIb3DQEBBQUAA4IBAQBoq/zvgGsYsrCzo0WJy1PFouavCKn9 -/w9JrP/kn9dBfKPFouiq4FchLcOqfAxMKAt59O5MMq15Dn6iXjQYT99U8b1ofOPT -10ZebWTC922IgnMM75mF6qnvMkrwg59zkQykPisxUaZijxWE+aY6EjA/2m74zMcZ -kg9c9P4X8ZUIR1IsUI/om6XurnAziZGC/jCqdnZZ12wY0ysSWx0oHXhx9s02oukH -SEQ751duggqtxYrd6FO0ca8T0gadN21TP4o1CPr+ohbmuW9cVjnWxqrvGWfOE8W4 -lQX7CkTJn6lAJUsyEa8H/gjVQnHp4VOLFR/dKgeVcCRvZF7Tt5AuiyHY ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert29[] = { - 0x30, 0x82, 0x04, 0xa6, 0x30, 0x82, 0x03, 0x8e, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x10, 0xe7, 0x76, 0xe8, 0xa6, 0x5a, 0x6e, 0x37, 0x7e, - 0x05, 0x03, 0x06, 0xd4, 0x3c, 0x25, 0xea, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, - 0x97, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x02, 0x55, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x07, - 0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, 0x6b, 0x65, 0x20, - 0x43, 0x69, 0x74, 0x79, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, - 0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75, 0x73, - 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x31, - 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x55, 0x54, - 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, 0x73, 0x74, 0x2d, - 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x30, 0x1e, 0x17, 0x0d, - 0x30, 0x36, 0x30, 0x34, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x35, 0x33, 0x30, 0x31, 0x30, 0x34, - 0x38, 0x33, 0x38, 0x5a, 0x30, 0x62, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x21, 0x30, 0x1f, 0x06, - 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, - 0x6b, 0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, - 0x4c, 0x2e, 0x4c, 0x2e, 0x43, 0x2e, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x27, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x43, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, - 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 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, 0xc3, 0xdd, 0x36, 0xcc, 0x83, 0xc3, 0x18, - 0x55, 0xb0, 0x96, 0xd9, 0x13, 0x25, 0xd3, 0x26, 0x86, 0x48, 0x38, 0xbb, - 0x16, 0x7f, 0xf1, 0x9f, 0x29, 0xf6, 0xfd, 0x03, 0xf1, 0xed, 0x4d, 0x26, - 0x9a, 0x56, 0xf0, 0xb5, 0x1a, 0x1a, 0xcd, 0xe6, 0xcc, 0x85, 0x55, 0x40, - 0xa4, 0xb5, 0xd0, 0x0d, 0xca, 0x22, 0xef, 0x3d, 0x23, 0xc6, 0x7e, 0x6c, - 0xcc, 0xbc, 0xa1, 0xe9, 0x7c, 0x50, 0x46, 0xe0, 0xbd, 0x14, 0xad, 0x65, - 0x12, 0xc2, 0x0b, 0x11, 0x69, 0x52, 0x0a, 0x07, 0x92, 0x1f, 0x73, 0x6f, - 0xc1, 0xba, 0xd7, 0x62, 0xf0, 0xce, 0x00, 0x2e, 0x34, 0xa5, 0xc8, 0xe6, - 0x2f, 0x0f, 0xec, 0x0d, 0xea, 0x44, 0x61, 0x75, 0x68, 0xe5, 0xe4, 0xdc, - 0x80, 0x36, 0x4f, 0xda, 0x78, 0x5d, 0x53, 0x25, 0x94, 0x94, 0xf5, 0x4f, - 0x2e, 0x3a, 0x60, 0x6f, 0x0c, 0xa6, 0xd9, 0xb3, 0xf6, 0x2a, 0x2e, 0x03, - 0x12, 0xd5, 0x26, 0x42, 0x07, 0x51, 0xb2, 0x64, 0x57, 0x71, 0xdc, 0x21, - 0x1c, 0x89, 0xc7, 0x69, 0xa3, 0xe6, 0xfb, 0xc2, 0x7b, 0x6e, 0xef, 0x0c, - 0x87, 0xfb, 0x50, 0x64, 0xe8, 0x4e, 0x4b, 0xef, 0xe7, 0x71, 0x9b, 0x83, - 0x63, 0x61, 0xc9, 0x32, 0x8d, 0x8c, 0xec, 0x14, 0xa7, 0xe4, 0x89, 0xad, - 0x3f, 0x2b, 0x26, 0x64, 0xe4, 0x85, 0x42, 0xf2, 0x89, 0x50, 0xe1, 0x3a, - 0xbe, 0x15, 0xe3, 0x45, 0x25, 0xe2, 0x5a, 0xcb, 0x8c, 0x3f, 0xe0, 0x33, - 0x1e, 0x35, 0x09, 0x5a, 0x84, 0xea, 0x7e, 0x5d, 0xa1, 0xf5, 0x91, 0x80, - 0x0a, 0x28, 0x06, 0xb7, 0xcb, 0x31, 0x41, 0x25, 0x61, 0x8b, 0x01, 0xe9, - 0x56, 0xa2, 0xf6, 0x3e, 0x5f, 0x2f, 0xf3, 0xc4, 0x43, 0xf6, 0x19, 0x94, - 0x75, 0x83, 0x4c, 0xa1, 0x82, 0x42, 0x3a, 0xc6, 0xba, 0xc4, 0x09, 0x30, - 0xa6, 0xe1, 0x75, 0x02, 0x51, 0xb9, 0x5e, 0x64, 0x8b, 0x02, 0x03, 0x01, - 0x00, 0x01, 0xa3, 0x82, 0x01, 0x20, 0x30, 0x82, 0x01, 0x1c, 0x30, 0x1f, - 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xa1, - 0x72, 0x5f, 0x26, 0x1b, 0x28, 0x98, 0x43, 0x95, 0x5d, 0x07, 0x37, 0xd5, - 0x85, 0x96, 0x9d, 0x4b, 0xd2, 0xc3, 0x45, 0x30, 0x1d, 0x06, 0x03, 0x55, - 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3c, 0x41, 0xe2, 0x8f, 0x08, 0x08, - 0xa9, 0x4c, 0x25, 0x89, 0x8d, 0x6d, 0xc5, 0x38, 0xd0, 0xfc, 0x85, 0x8c, - 0x62, 0x17, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, - 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, - 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, - 0x01, 0x00, 0x30, 0x19, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x12, 0x30, - 0x10, 0x30, 0x0e, 0x06, 0x0c, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x86, 0x0e, - 0x01, 0x02, 0x01, 0x03, 0x01, 0x30, 0x44, 0x06, 0x03, 0x55, 0x1d, 0x1f, - 0x04, 0x3d, 0x30, 0x3b, 0x30, 0x39, 0xa0, 0x37, 0xa0, 0x35, 0x86, 0x33, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x75, - 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x55, 0x54, 0x4e, 0x2d, 0x55, 0x53, 0x45, 0x52, 0x46, 0x69, 0x72, - 0x73, 0x74, 0x2d, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x2e, - 0x63, 0x72, 0x6c, 0x30, 0x55, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x01, 0x01, 0x04, 0x49, 0x30, 0x47, 0x30, 0x45, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x39, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75, 0x73, 0x65, 0x72, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x61, - 0x63, 0x65, 0x72, 0x74, 0x73, 0x2f, 0x55, 0x54, 0x4e, 0x41, 0x64, 0x64, - 0x54, 0x72, 0x75, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, - 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, - 0x01, 0x00, 0x68, 0xab, 0xfc, 0xef, 0x80, 0x6b, 0x18, 0xb2, 0xb0, 0xb3, - 0xa3, 0x45, 0x89, 0xcb, 0x53, 0xc5, 0xa2, 0xe6, 0xaf, 0x08, 0xa9, 0xfd, - 0xff, 0x0f, 0x49, 0xac, 0xff, 0xe4, 0x9f, 0xd7, 0x41, 0x7c, 0xa3, 0xc5, - 0xa2, 0xe8, 0xaa, 0xe0, 0x57, 0x21, 0x2d, 0xc3, 0xaa, 0x7c, 0x0c, 0x4c, - 0x28, 0x0b, 0x79, 0xf4, 0xee, 0x4c, 0x32, 0xad, 0x79, 0x0e, 0x7e, 0xa2, - 0x5e, 0x34, 0x18, 0x4f, 0xdf, 0x54, 0xf1, 0xbd, 0x68, 0x7c, 0xe3, 0xd3, - 0xd7, 0x46, 0x5e, 0x6d, 0x64, 0xc2, 0xf7, 0x6d, 0x88, 0x82, 0x73, 0x0c, - 0xef, 0x99, 0x85, 0xea, 0xa9, 0xef, 0x32, 0x4a, 0xf0, 0x83, 0x9f, 0x73, - 0x91, 0x0c, 0xa4, 0x3e, 0x2b, 0x31, 0x51, 0xa6, 0x62, 0x8f, 0x15, 0x84, - 0xf9, 0xa6, 0x3a, 0x12, 0x30, 0x3f, 0xda, 0x6e, 0xf8, 0xcc, 0xc7, 0x19, - 0x92, 0x0f, 0x5c, 0xf4, 0xfe, 0x17, 0xf1, 0x95, 0x08, 0x47, 0x52, 0x2c, - 0x50, 0x8f, 0xe8, 0x9b, 0xa5, 0xee, 0xae, 0x70, 0x33, 0x89, 0x91, 0x82, - 0xfe, 0x30, 0xaa, 0x76, 0x76, 0x59, 0xd7, 0x6c, 0x18, 0xd3, 0x2b, 0x12, - 0x5b, 0x1d, 0x28, 0x1d, 0x78, 0x71, 0xf6, 0xcd, 0x36, 0xa2, 0xe9, 0x07, - 0x48, 0x44, 0x3b, 0xe7, 0x57, 0x6e, 0x82, 0x0a, 0xad, 0xc5, 0x8a, 0xdd, - 0xe8, 0x53, 0xb4, 0x71, 0xaf, 0x13, 0xd2, 0x06, 0x9d, 0x37, 0x6d, 0x53, - 0x3f, 0x8a, 0x35, 0x08, 0xfa, 0xfe, 0xa2, 0x16, 0xe6, 0xb9, 0x6f, 0x5c, - 0x56, 0x39, 0xd6, 0xc6, 0xaa, 0xef, 0x19, 0x67, 0xce, 0x13, 0xc5, 0xb8, - 0x95, 0x05, 0xfb, 0x0a, 0x44, 0xc9, 0x9f, 0xa9, 0x40, 0x25, 0x4b, 0x32, - 0x11, 0xaf, 0x07, 0xfe, 0x08, 0xd5, 0x42, 0x71, 0xe9, 0xe1, 0x53, 0x8b, - 0x15, 0x1f, 0xdd, 0x2a, 0x07, 0x95, 0x70, 0x24, 0x6f, 0x64, 0x5e, 0xd3, - 0xb7, 0x90, 0x2e, 0x8b, 0x21, 0xd8, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 46:ea:f0:96:05:4c:c5:e3:fa:65:ea:6e:9f:42:c6:64 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root - Validity - Not Before: Jun 7 08:09:10 2005 GMT - Not After : May 30 10:48:38 2020 GMT - Subject: C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network, OU=http://www.usertrust.com, CN=UTN - DATACorp SGC - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:df:ee:58:10:a2:2b:6e:55:c4:8e:bf:2e:46:09: - e7:e0:08:0f:2e:2b:7a:13:94:1b:bd:f6:b6:80:8e: - 65:05:93:00:1e:bc:af:e2:0f:8e:19:0d:12:47:ec: - ac:ad:a3:fa:2e:70:f8:de:6e:fb:56:42:15:9e:2e: - 5c:ef:23:de:21:b9:05:76:27:19:0f:4f:d6:c3:9c: - b4:be:94:19:63:f2:a6:11:0a:eb:53:48:9c:be:f2: - 29:3b:16:e8:1a:a0:4c:a6:c9:f4:18:59:68:c0:70: - f2:53:00:c0:5e:50:82:a5:56:6f:36:f9:4a:e0:44: - 86:a0:4d:4e:d6:47:6e:49:4a:cb:67:d7:a6:c4:05: - b9:8e:1e:f4:fc:ff:cd:e7:36:e0:9c:05:6c:b2:33: - 22:15:d0:b4:e0:cc:17:c0:b2:c0:f4:fe:32:3f:29: - 2a:95:7b:d8:f2:a7:4e:0f:54:7c:a1:0d:80:b3:09: - 03:c1:ff:5c:dd:5e:9a:3e:bc:ae:bc:47:8a:6a:ae: - 71:ca:1f:b1:2a:b8:5f:42:05:0b:ec:46:30:d1:72: - 0b:ca:e9:56:6d:f5:ef:df:78:be:61:ba:b2:a5:ae: - 04:4c:bc:a8:ac:69:15:97:bd:ef:eb:b4:8c:bf:35: - f8:d4:c3:d1:28:0e:5c:3a:9f:70:18:33:20:77:c4: - a2:af - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Authority Key Identifier: - keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A - - X509v3 Subject Key Identifier: - 53:32:D1:B3:CF:7F:FA:E0:F1:A0:5D:85:4E:92:D2:9E:45:1D:B4:4F - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Extended Key Usage: - Microsoft Server Gated Crypto, Netscape Server Gated Crypto - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.comodoca.com/AddTrustExternalCARoot.crl - - Full Name: - URI:http://crl.comodo.net/AddTrustExternalCARoot.crl - - Signature Algorithm: sha1WithRSAEncryption - 63:86:92:10:b1:13:fa:37:be:8e:2a:b6:1b:8a:43:f5:5c:ae: - 0e:14:df:f7:69:40:7f:bf:1a:71:00:09:d8:bf:d4:24:4a:bf: - e0:93:ff:01:d8:0b:c6:0f:ec:7e:47:9c:b0:5d:f7:7c:14:9d: - fc:c0:33:92:84:5b:d2:83:f4:52:e2:22:58:74:fc:43:1b:3f: - a7:a3:58:da:03:fd:bc:f0:3a:e4:ed:cc:12:bb:c9:b9:ae:7b: - 04:a0:04:72:bf:e9:de:2d:d2:a7:51:66:00:73:d2:bd:7e:aa: - 9e:53:96:7d:69:b2:18:3e:8e:ad:56:50:7e:f7:d5:b0:ff:39: - 62:65:82:8c:96:57:c3:8f:f7:60:f6:c2:8d:34:87:fc:4f:43: - e5:db:bf:1c:aa:f6:86:cd:e6:df:11:3f:8d:07:f7:6d:83:13: - c0:38:88:39:60:a1:7e:30:e1:e3:88:3e:a4:bb:63:6f:2c:e9: - 8a:68:2c:ee:96:69:ac:04:61:e1:4f:4e:0e:9d:72:4c:f6:79: - 38:c8:c7:48:69:6f:94:0f:74:b4:bc:c8:cf:57:4d:b9:75:71: - 96:0d:8a:06:0b:eb:dd:d0:f0:3c:7d:c6:2e:98:46:6a:38:c7: - 02:b5:c8:b8:b2:65:75:de:da:90:08:b6:77:b8:53:00:25:cb: - 47:ca:73:5f ------BEGIN CERTIFICATE----- -MIIEpjCCA46gAwIBAgIQRurwlgVMxeP6Zepun0LGZDANBgkqhkiG9w0BAQUFADBv -MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk -ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF -eHRlcm5hbCBDQSBSb290MB4XDTA1MDYwNzA4MDkxMFoXDTIwMDUzMDEwNDgzOFow -gZMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtl -IENpdHkxHjAcBgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMY -aHR0cDovL3d3dy51c2VydHJ1c3QuY29tMRswGQYDVQQDExJVVE4gLSBEQVRBQ29y -cCBTR0MwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDf7lgQoituVcSO -vy5GCefgCA8uK3oTlBu99raAjmUFkwAevK/iD44ZDRJH7Kyto/oucPjebvtWQhWe -LlzvI94huQV2JxkPT9bDnLS+lBlj8qYRCutTSJy+8ik7FugaoEymyfQYWWjAcPJT -AMBeUIKlVm82+UrgRIagTU7WR25JSstn16bEBbmOHvT8/83nNuCcBWyyMyIV0LTg -zBfAssD0/jI/KSqVe9jyp04PVHyhDYCzCQPB/1zdXpo+vK68R4pqrnHKH7EquF9C -BQvsRjDRcgvK6VZt9e/feL5hurKlrgRMvKisaRWXve/rtIy/NfjUw9EoDlw6n3AY -MyB3xKKvAgMBAAGjggEXMIIBEzAfBgNVHSMEGDAWgBStvZh6NLQm9/rEJlTvA73g -JMtUGjAdBgNVHQ4EFgQUUzLRs89/+uDxoF2FTpLSnkUdtE8wDgYDVR0PAQH/BAQD -AgEGMA8GA1UdEwEB/wQFMAMBAf8wIAYDVR0lBBkwFwYKKwYBBAGCNwoDAwYJYIZI -AYb4QgQBMBEGA1UdIAQKMAgwBgYEVR0gADB7BgNVHR8EdDByMDigNqA0hjJodHRw -Oi8vY3JsLmNvbW9kb2NhLmNvbS9BZGRUcnVzdEV4dGVybmFsQ0FSb290LmNybDA2 -oDSgMoYwaHR0cDovL2NybC5jb21vZG8ubmV0L0FkZFRydXN0RXh0ZXJuYWxDQVJv -b3QuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQBjhpIQsRP6N76OKrYbikP1XK4OFN/3 -aUB/vxpxAAnYv9QkSr/gk/8B2AvGD+x+R5ywXfd8FJ38wDOShFvSg/RS4iJYdPxD -Gz+no1jaA/288Drk7cwSu8m5rnsEoARyv+neLdKnUWYAc9K9fqqeU5Z9abIYPo6t -VlB+99Ww/zliZYKMllfDj/dg9sKNNIf8T0Pl278cqvaGzebfET+NB/dtgxPAOIg5 -YKF+MOHjiD6ku2NvLOmKaCzulmmsBGHhT04OnXJM9nk4yMdIaW+UD3S0vMjPV025 -dXGWDYoGC+vd0PA8fcYumEZqOMcCtci4smV13tqQCLZ3uFMAJctHynNf ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert30[] = { - 0x30, 0x82, 0x04, 0xa6, 0x30, 0x82, 0x03, 0x8e, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x46, 0xea, 0xf0, 0x96, 0x05, 0x4c, 0xc5, 0xe3, 0xfa, - 0x65, 0xea, 0x6e, 0x9f, 0x42, 0xc6, 0x64, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x6f, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x53, - 0x45, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, - 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41, 0x42, 0x31, - 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x64, - 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x20, 0x54, 0x54, 0x50, 0x20, 0x4e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x19, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, - 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x52, - 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x35, 0x30, 0x36, 0x30, - 0x37, 0x30, 0x38, 0x30, 0x39, 0x31, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, - 0x30, 0x35, 0x33, 0x30, 0x31, 0x30, 0x34, 0x38, 0x33, 0x38, 0x5a, 0x30, - 0x81, 0x93, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, - 0x13, 0x02, 0x55, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, - 0x07, 0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, 0x6b, 0x65, - 0x20, 0x43, 0x69, 0x74, 0x79, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, - 0x04, 0x0a, 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, - 0x54, 0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, - 0x6b, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75, - 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, - 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x55, - 0x54, 0x4e, 0x20, 0x2d, 0x20, 0x44, 0x41, 0x54, 0x41, 0x43, 0x6f, 0x72, - 0x70, 0x20, 0x53, 0x47, 0x43, 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, 0xdf, 0xee, 0x58, 0x10, 0xa2, 0x2b, 0x6e, 0x55, 0xc4, 0x8e, - 0xbf, 0x2e, 0x46, 0x09, 0xe7, 0xe0, 0x08, 0x0f, 0x2e, 0x2b, 0x7a, 0x13, - 0x94, 0x1b, 0xbd, 0xf6, 0xb6, 0x80, 0x8e, 0x65, 0x05, 0x93, 0x00, 0x1e, - 0xbc, 0xaf, 0xe2, 0x0f, 0x8e, 0x19, 0x0d, 0x12, 0x47, 0xec, 0xac, 0xad, - 0xa3, 0xfa, 0x2e, 0x70, 0xf8, 0xde, 0x6e, 0xfb, 0x56, 0x42, 0x15, 0x9e, - 0x2e, 0x5c, 0xef, 0x23, 0xde, 0x21, 0xb9, 0x05, 0x76, 0x27, 0x19, 0x0f, - 0x4f, 0xd6, 0xc3, 0x9c, 0xb4, 0xbe, 0x94, 0x19, 0x63, 0xf2, 0xa6, 0x11, - 0x0a, 0xeb, 0x53, 0x48, 0x9c, 0xbe, 0xf2, 0x29, 0x3b, 0x16, 0xe8, 0x1a, - 0xa0, 0x4c, 0xa6, 0xc9, 0xf4, 0x18, 0x59, 0x68, 0xc0, 0x70, 0xf2, 0x53, - 0x00, 0xc0, 0x5e, 0x50, 0x82, 0xa5, 0x56, 0x6f, 0x36, 0xf9, 0x4a, 0xe0, - 0x44, 0x86, 0xa0, 0x4d, 0x4e, 0xd6, 0x47, 0x6e, 0x49, 0x4a, 0xcb, 0x67, - 0xd7, 0xa6, 0xc4, 0x05, 0xb9, 0x8e, 0x1e, 0xf4, 0xfc, 0xff, 0xcd, 0xe7, - 0x36, 0xe0, 0x9c, 0x05, 0x6c, 0xb2, 0x33, 0x22, 0x15, 0xd0, 0xb4, 0xe0, - 0xcc, 0x17, 0xc0, 0xb2, 0xc0, 0xf4, 0xfe, 0x32, 0x3f, 0x29, 0x2a, 0x95, - 0x7b, 0xd8, 0xf2, 0xa7, 0x4e, 0x0f, 0x54, 0x7c, 0xa1, 0x0d, 0x80, 0xb3, - 0x09, 0x03, 0xc1, 0xff, 0x5c, 0xdd, 0x5e, 0x9a, 0x3e, 0xbc, 0xae, 0xbc, - 0x47, 0x8a, 0x6a, 0xae, 0x71, 0xca, 0x1f, 0xb1, 0x2a, 0xb8, 0x5f, 0x42, - 0x05, 0x0b, 0xec, 0x46, 0x30, 0xd1, 0x72, 0x0b, 0xca, 0xe9, 0x56, 0x6d, - 0xf5, 0xef, 0xdf, 0x78, 0xbe, 0x61, 0xba, 0xb2, 0xa5, 0xae, 0x04, 0x4c, - 0xbc, 0xa8, 0xac, 0x69, 0x15, 0x97, 0xbd, 0xef, 0xeb, 0xb4, 0x8c, 0xbf, - 0x35, 0xf8, 0xd4, 0xc3, 0xd1, 0x28, 0x0e, 0x5c, 0x3a, 0x9f, 0x70, 0x18, - 0x33, 0x20, 0x77, 0xc4, 0xa2, 0xaf, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, - 0x82, 0x01, 0x17, 0x30, 0x82, 0x01, 0x13, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xad, 0xbd, 0x98, 0x7a, - 0x34, 0xb4, 0x26, 0xf7, 0xfa, 0xc4, 0x26, 0x54, 0xef, 0x03, 0xbd, 0xe0, - 0x24, 0xcb, 0x54, 0x1a, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, - 0x16, 0x04, 0x14, 0x53, 0x32, 0xd1, 0xb3, 0xcf, 0x7f, 0xfa, 0xe0, 0xf1, - 0xa0, 0x5d, 0x85, 0x4e, 0x92, 0xd2, 0x9e, 0x45, 0x1d, 0xb4, 0x4f, 0x30, - 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, - 0x02, 0x01, 0x06, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, - 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x20, 0x06, 0x03, - 0x55, 0x1d, 0x25, 0x04, 0x19, 0x30, 0x17, 0x06, 0x0a, 0x2b, 0x06, 0x01, - 0x04, 0x01, 0x82, 0x37, 0x0a, 0x03, 0x03, 0x06, 0x09, 0x60, 0x86, 0x48, - 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01, 0x30, 0x11, 0x06, 0x03, 0x55, 0x1d, - 0x20, 0x04, 0x0a, 0x30, 0x08, 0x30, 0x06, 0x06, 0x04, 0x55, 0x1d, 0x20, - 0x00, 0x30, 0x7b, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x74, 0x30, 0x72, - 0x30, 0x38, 0xa0, 0x36, 0xa0, 0x34, 0x86, 0x32, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, - 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, - 0x72, 0x75, 0x73, 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, - 0x43, 0x41, 0x52, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x36, - 0xa0, 0x34, 0xa0, 0x32, 0x86, 0x30, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x2e, - 0x6e, 0x65, 0x74, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, - 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x41, 0x52, 0x6f, - 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, - 0x01, 0x00, 0x63, 0x86, 0x92, 0x10, 0xb1, 0x13, 0xfa, 0x37, 0xbe, 0x8e, - 0x2a, 0xb6, 0x1b, 0x8a, 0x43, 0xf5, 0x5c, 0xae, 0x0e, 0x14, 0xdf, 0xf7, - 0x69, 0x40, 0x7f, 0xbf, 0x1a, 0x71, 0x00, 0x09, 0xd8, 0xbf, 0xd4, 0x24, - 0x4a, 0xbf, 0xe0, 0x93, 0xff, 0x01, 0xd8, 0x0b, 0xc6, 0x0f, 0xec, 0x7e, - 0x47, 0x9c, 0xb0, 0x5d, 0xf7, 0x7c, 0x14, 0x9d, 0xfc, 0xc0, 0x33, 0x92, - 0x84, 0x5b, 0xd2, 0x83, 0xf4, 0x52, 0xe2, 0x22, 0x58, 0x74, 0xfc, 0x43, - 0x1b, 0x3f, 0xa7, 0xa3, 0x58, 0xda, 0x03, 0xfd, 0xbc, 0xf0, 0x3a, 0xe4, - 0xed, 0xcc, 0x12, 0xbb, 0xc9, 0xb9, 0xae, 0x7b, 0x04, 0xa0, 0x04, 0x72, - 0xbf, 0xe9, 0xde, 0x2d, 0xd2, 0xa7, 0x51, 0x66, 0x00, 0x73, 0xd2, 0xbd, - 0x7e, 0xaa, 0x9e, 0x53, 0x96, 0x7d, 0x69, 0xb2, 0x18, 0x3e, 0x8e, 0xad, - 0x56, 0x50, 0x7e, 0xf7, 0xd5, 0xb0, 0xff, 0x39, 0x62, 0x65, 0x82, 0x8c, - 0x96, 0x57, 0xc3, 0x8f, 0xf7, 0x60, 0xf6, 0xc2, 0x8d, 0x34, 0x87, 0xfc, - 0x4f, 0x43, 0xe5, 0xdb, 0xbf, 0x1c, 0xaa, 0xf6, 0x86, 0xcd, 0xe6, 0xdf, - 0x11, 0x3f, 0x8d, 0x07, 0xf7, 0x6d, 0x83, 0x13, 0xc0, 0x38, 0x88, 0x39, - 0x60, 0xa1, 0x7e, 0x30, 0xe1, 0xe3, 0x88, 0x3e, 0xa4, 0xbb, 0x63, 0x6f, - 0x2c, 0xe9, 0x8a, 0x68, 0x2c, 0xee, 0x96, 0x69, 0xac, 0x04, 0x61, 0xe1, - 0x4f, 0x4e, 0x0e, 0x9d, 0x72, 0x4c, 0xf6, 0x79, 0x38, 0xc8, 0xc7, 0x48, - 0x69, 0x6f, 0x94, 0x0f, 0x74, 0xb4, 0xbc, 0xc8, 0xcf, 0x57, 0x4d, 0xb9, - 0x75, 0x71, 0x96, 0x0d, 0x8a, 0x06, 0x0b, 0xeb, 0xdd, 0xd0, 0xf0, 0x3c, - 0x7d, 0xc6, 0x2e, 0x98, 0x46, 0x6a, 0x38, 0xc7, 0x02, 0xb5, 0xc8, 0xb8, - 0xb2, 0x65, 0x75, 0xde, 0xda, 0x90, 0x08, 0xb6, 0x77, 0xb8, 0x53, 0x00, - 0x25, 0xcb, 0x47, 0xca, 0x73, 0x5f, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 2e:79:83:2e:90:88:87:ea:8b:8e:f3:1a:6e:e6:7a:44 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, ST=UT, L=Salt Lake City, O=The USERTRUST Network, OU=http://www.usertrust.com, CN=UTN - DATACorp SGC - Validity - Not Before: Dec 1 00:00:00 2006 GMT - Not After : May 30 10:48:38 2020 GMT - Subject: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO Certification Authority - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:d0:40:8b:8b:72:e3:91:1b:f7:51:c1:1b:54:04: - 98:d3:a9:bf:c1:e6:8a:5d:3b:87:fb:bb:88:ce:0d: - e3:2f:3f:06:96:f0:a2:29:50:99:ae:db:3b:a1:57: - b0:74:51:71:cd:ed:42:91:4d:41:fe:a9:c8:d8:6a: - 86:77:44:bb:59:66:97:50:5e:b4:d4:2c:70:44:cf: - da:37:95:42:69:3c:30:c4:71:b3:52:f0:21:4d:a1: - d8:ba:39:7c:1c:9e:a3:24:9d:f2:83:16:98:aa:16: - 7c:43:9b:15:5b:b7:ae:34:91:fe:d4:62:26:18:46: - 9a:3f:eb:c1:f9:f1:90:57:eb:ac:7a:0d:8b:db:72: - 30:6a:66:d5:e0:46:a3:70:dc:68:d9:ff:04:48:89: - 77:de:b5:e9:fb:67:6d:41:e9:bc:39:bd:32:d9:62: - 02:f1:b1:a8:3d:6e:37:9c:e2:2f:e2:d3:a2:26:8b: - c6:b8:55:43:88:e1:23:3e:a5:d2:24:39:6a:47:ab: - 00:d4:a1:b3:a9:25:fe:0d:3f:a7:1d:ba:d3:51:c1: - 0b:a4:da:ac:38:ef:55:50:24:05:65:46:93:34:4f: - 2d:8d:ad:c6:d4:21:19:d2:8e:ca:05:61:71:07:73: - 47:e5:8a:19:12:bd:04:4d:ce:4e:9c:a5:48:ac:bb: - 26:f7 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Authority Key Identifier: - keyid:53:32:D1:B3:CF:7F:FA:E0:F1:A0:5D:85:4E:92:D2:9E:45:1D:B4:4F - - X509v3 Subject Key Identifier: - 0B:58:E5:8B:C6:4C:15:37:A4:40:A9:30:A9:21:BE:47:36:5A:56:FF - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Extended Key Usage: - Microsoft Server Gated Crypto, Netscape Server Gated Crypto - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.comodoca.com/UTN-DATACorpSGC.crl - - Full Name: - URI:http://crl.comodo.net/UTN-DATACorpSGC.crl - - Signature Algorithm: sha1WithRSAEncryption - d8:5e:92:c4:ae:14:dc:43:ad:c2:a4:c3:67:45:07:1d:f9:37: - a2:19:c7:1c:37:35:91:13:1c:07:c4:7d:42:a6:0e:f0:86:5c: - 43:6b:0e:44:cf:be:24:61:3a:42:a9:ce:9d:4c:af:79:39:70: - dd:0e:04:20:4e:95:9c:3c:de:b7:60:ba:63:43:40:ed:6a:0f: - 81:49:46:bb:1e:93:c0:4b:f3:f8:e1:36:49:1b:6f:b6:0c:0d: - f2:90:57:8a:fc:6d:93:f2:28:c7:fa:86:0a:28:b3:17:0e:59: - 8a:2e:b6:bf:cd:e1:ac:4c:66:6c:f2:55:91:56:b7:32:bf:b1: - e4:7d:b5:e8:3a:b6:2f:db:b2:9c:da:50:93:8e:4e:c5:ac:9a: - 7e:5c:9e:12:3c:3b:4d:c6:50:70:b3:65:2b:8e:f7:6b:a1:bb: - 25:c0:00:bb:f5:ec:16:65:81:0e:fb:d4:a3:21:96:77:9a:a8: - 74:bc:53:aa:c2:39:50:ff:0b:02:09:61:cc:95:b7:d7:88:6a: - f6:5c:c5:68:d3:14:95:1a:47:5f:d9:fb:2d:e4:2f:8f:13:86: - ab:31:13:40:13:ac:6e:ed:b5:10:30:8b:1b:50:a9:ce:ee:8c: - ca:eb:7c:b5:b9:16:3d:d4:fa:6f:92:6d:1e:a2:bd:fb:02:4a: - c5:70:be:f1 ------BEGIN CERTIFICATE----- -MIIEqzCCA5OgAwIBAgIQLnmDLpCIh+qLjvMabuZ6RDANBgkqhkiG9w0BAQUFADCB -kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug -Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw -IFNHQzAeFw0wNjEyMDEwMDAwMDBaFw0yMDA1MzAxMDQ4MzhaMIGBMQswCQYDVQQG -EwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxm -b3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RP -IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZ -rts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAh -TaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23Iw -ambV4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVD -iOEjPqXSJDlqR6sA1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ -0o7KBWFxB3NH5YoZEr0ETc5OnKVIrLsm9wIDAQABo4IBCTCCAQUwHwYDVR0jBBgw -FoAUUzLRs89/+uDxoF2FTpLSnkUdtE8wHQYDVR0OBBYEFAtY5YvGTBU3pECpMKkh -vkc2Wlb/MA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MCAGA1UdJQQZ -MBcGCisGAQQBgjcKAwMGCWCGSAGG+EIEATARBgNVHSAECjAIMAYGBFUdIAAwbQYD -VR0fBGYwZDAxoC+gLYYraHR0cDovL2NybC5jb21vZG9jYS5jb20vVVROLURBVEFD -b3JwU0dDLmNybDAvoC2gK4YpaHR0cDovL2NybC5jb21vZG8ubmV0L1VUTi1EQVRB -Q29ycFNHQy5jcmwwDQYJKoZIhvcNAQEFBQADggEBANheksSuFNxDrcKkw2dFBx35 -N6IZxxw3NZETHAfEfUKmDvCGXENrDkTPviRhOkKpzp1Mr3k5cN0OBCBOlZw83rdg -umNDQO1qD4FJRrsek8BL8/jhNkkbb7YMDfKQV4r8bZPyKMf6hgoosxcOWYoutr/N -4axMZmzyVZFWtzK/seR9teg6ti/bspzaUJOOTsWsmn5cnhI8O03GUHCzZSuO92uh -uyXAALv17BZlgQ771KMhlneaqHS8U6rCOVD/CwIJYcyVt9eIavZcxWjTFJUaR1/Z -+y3kL48ThqsxE0ATrG7ttRAwixtQqc7ujMrrfLW5Fj3U+m+SbR6ivfsCSsVwvvE= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert31[] = { - 0x30, 0x82, 0x04, 0xab, 0x30, 0x82, 0x03, 0x93, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x2e, 0x79, 0x83, 0x2e, 0x90, 0x88, 0x87, 0xea, 0x8b, - 0x8e, 0xf3, 0x1a, 0x6e, 0xe6, 0x7a, 0x44, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, - 0x93, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x02, 0x55, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x07, - 0x13, 0x0e, 0x53, 0x61, 0x6c, 0x74, 0x20, 0x4c, 0x61, 0x6b, 0x65, 0x20, - 0x43, 0x69, 0x74, 0x79, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x15, 0x54, 0x68, 0x65, 0x20, 0x55, 0x53, 0x45, 0x52, 0x54, - 0x52, 0x55, 0x53, 0x54, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x18, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x75, 0x73, - 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x31, - 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x55, 0x54, - 0x4e, 0x20, 0x2d, 0x20, 0x44, 0x41, 0x54, 0x41, 0x43, 0x6f, 0x72, 0x70, - 0x20, 0x53, 0x47, 0x43, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x32, - 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, - 0x30, 0x30, 0x35, 0x33, 0x30, 0x31, 0x30, 0x34, 0x38, 0x33, 0x38, 0x5a, - 0x30, 0x81, 0x81, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x47, 0x42, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, - 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4d, - 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, - 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6c, 0x66, - 0x6f, 0x72, 0x64, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x13, 0x11, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x43, 0x41, 0x20, - 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x27, 0x30, 0x25, 0x06, - 0x03, 0x55, 0x04, 0x03, 0x13, 0x1e, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, - 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, - 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, 0xd0, 0x40, 0x8b, - 0x8b, 0x72, 0xe3, 0x91, 0x1b, 0xf7, 0x51, 0xc1, 0x1b, 0x54, 0x04, 0x98, - 0xd3, 0xa9, 0xbf, 0xc1, 0xe6, 0x8a, 0x5d, 0x3b, 0x87, 0xfb, 0xbb, 0x88, - 0xce, 0x0d, 0xe3, 0x2f, 0x3f, 0x06, 0x96, 0xf0, 0xa2, 0x29, 0x50, 0x99, - 0xae, 0xdb, 0x3b, 0xa1, 0x57, 0xb0, 0x74, 0x51, 0x71, 0xcd, 0xed, 0x42, - 0x91, 0x4d, 0x41, 0xfe, 0xa9, 0xc8, 0xd8, 0x6a, 0x86, 0x77, 0x44, 0xbb, - 0x59, 0x66, 0x97, 0x50, 0x5e, 0xb4, 0xd4, 0x2c, 0x70, 0x44, 0xcf, 0xda, - 0x37, 0x95, 0x42, 0x69, 0x3c, 0x30, 0xc4, 0x71, 0xb3, 0x52, 0xf0, 0x21, - 0x4d, 0xa1, 0xd8, 0xba, 0x39, 0x7c, 0x1c, 0x9e, 0xa3, 0x24, 0x9d, 0xf2, - 0x83, 0x16, 0x98, 0xaa, 0x16, 0x7c, 0x43, 0x9b, 0x15, 0x5b, 0xb7, 0xae, - 0x34, 0x91, 0xfe, 0xd4, 0x62, 0x26, 0x18, 0x46, 0x9a, 0x3f, 0xeb, 0xc1, - 0xf9, 0xf1, 0x90, 0x57, 0xeb, 0xac, 0x7a, 0x0d, 0x8b, 0xdb, 0x72, 0x30, - 0x6a, 0x66, 0xd5, 0xe0, 0x46, 0xa3, 0x70, 0xdc, 0x68, 0xd9, 0xff, 0x04, - 0x48, 0x89, 0x77, 0xde, 0xb5, 0xe9, 0xfb, 0x67, 0x6d, 0x41, 0xe9, 0xbc, - 0x39, 0xbd, 0x32, 0xd9, 0x62, 0x02, 0xf1, 0xb1, 0xa8, 0x3d, 0x6e, 0x37, - 0x9c, 0xe2, 0x2f, 0xe2, 0xd3, 0xa2, 0x26, 0x8b, 0xc6, 0xb8, 0x55, 0x43, - 0x88, 0xe1, 0x23, 0x3e, 0xa5, 0xd2, 0x24, 0x39, 0x6a, 0x47, 0xab, 0x00, - 0xd4, 0xa1, 0xb3, 0xa9, 0x25, 0xfe, 0x0d, 0x3f, 0xa7, 0x1d, 0xba, 0xd3, - 0x51, 0xc1, 0x0b, 0xa4, 0xda, 0xac, 0x38, 0xef, 0x55, 0x50, 0x24, 0x05, - 0x65, 0x46, 0x93, 0x34, 0x4f, 0x2d, 0x8d, 0xad, 0xc6, 0xd4, 0x21, 0x19, - 0xd2, 0x8e, 0xca, 0x05, 0x61, 0x71, 0x07, 0x73, 0x47, 0xe5, 0x8a, 0x19, - 0x12, 0xbd, 0x04, 0x4d, 0xce, 0x4e, 0x9c, 0xa5, 0x48, 0xac, 0xbb, 0x26, - 0xf7, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x09, 0x30, 0x82, - 0x01, 0x05, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, - 0x16, 0x80, 0x14, 0x53, 0x32, 0xd1, 0xb3, 0xcf, 0x7f, 0xfa, 0xe0, 0xf1, - 0xa0, 0x5d, 0x85, 0x4e, 0x92, 0xd2, 0x9e, 0x45, 0x1d, 0xb4, 0x4f, 0x30, - 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x0b, 0x58, - 0xe5, 0x8b, 0xc6, 0x4c, 0x15, 0x37, 0xa4, 0x40, 0xa9, 0x30, 0xa9, 0x21, - 0xbe, 0x47, 0x36, 0x5a, 0x56, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, - 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0f, - 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, - 0x01, 0x01, 0xff, 0x30, 0x20, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x19, - 0x30, 0x17, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x0a, - 0x03, 0x03, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, - 0x01, 0x30, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x0a, 0x30, 0x08, - 0x30, 0x06, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x6d, 0x06, 0x03, - 0x55, 0x1d, 0x1f, 0x04, 0x66, 0x30, 0x64, 0x30, 0x31, 0xa0, 0x2f, 0xa0, - 0x2d, 0x86, 0x2b, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, - 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x55, 0x54, 0x4e, 0x2d, 0x44, 0x41, 0x54, 0x41, 0x43, - 0x6f, 0x72, 0x70, 0x53, 0x47, 0x43, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x2f, - 0xa0, 0x2d, 0xa0, 0x2b, 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x2e, - 0x6e, 0x65, 0x74, 0x2f, 0x55, 0x54, 0x4e, 0x2d, 0x44, 0x41, 0x54, 0x41, - 0x43, 0x6f, 0x72, 0x70, 0x53, 0x47, 0x43, 0x2e, 0x63, 0x72, 0x6c, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, - 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xd8, 0x5e, 0x92, 0xc4, 0xae, - 0x14, 0xdc, 0x43, 0xad, 0xc2, 0xa4, 0xc3, 0x67, 0x45, 0x07, 0x1d, 0xf9, - 0x37, 0xa2, 0x19, 0xc7, 0x1c, 0x37, 0x35, 0x91, 0x13, 0x1c, 0x07, 0xc4, - 0x7d, 0x42, 0xa6, 0x0e, 0xf0, 0x86, 0x5c, 0x43, 0x6b, 0x0e, 0x44, 0xcf, - 0xbe, 0x24, 0x61, 0x3a, 0x42, 0xa9, 0xce, 0x9d, 0x4c, 0xaf, 0x79, 0x39, - 0x70, 0xdd, 0x0e, 0x04, 0x20, 0x4e, 0x95, 0x9c, 0x3c, 0xde, 0xb7, 0x60, - 0xba, 0x63, 0x43, 0x40, 0xed, 0x6a, 0x0f, 0x81, 0x49, 0x46, 0xbb, 0x1e, - 0x93, 0xc0, 0x4b, 0xf3, 0xf8, 0xe1, 0x36, 0x49, 0x1b, 0x6f, 0xb6, 0x0c, - 0x0d, 0xf2, 0x90, 0x57, 0x8a, 0xfc, 0x6d, 0x93, 0xf2, 0x28, 0xc7, 0xfa, - 0x86, 0x0a, 0x28, 0xb3, 0x17, 0x0e, 0x59, 0x8a, 0x2e, 0xb6, 0xbf, 0xcd, - 0xe1, 0xac, 0x4c, 0x66, 0x6c, 0xf2, 0x55, 0x91, 0x56, 0xb7, 0x32, 0xbf, - 0xb1, 0xe4, 0x7d, 0xb5, 0xe8, 0x3a, 0xb6, 0x2f, 0xdb, 0xb2, 0x9c, 0xda, - 0x50, 0x93, 0x8e, 0x4e, 0xc5, 0xac, 0x9a, 0x7e, 0x5c, 0x9e, 0x12, 0x3c, - 0x3b, 0x4d, 0xc6, 0x50, 0x70, 0xb3, 0x65, 0x2b, 0x8e, 0xf7, 0x6b, 0xa1, - 0xbb, 0x25, 0xc0, 0x00, 0xbb, 0xf5, 0xec, 0x16, 0x65, 0x81, 0x0e, 0xfb, - 0xd4, 0xa3, 0x21, 0x96, 0x77, 0x9a, 0xa8, 0x74, 0xbc, 0x53, 0xaa, 0xc2, - 0x39, 0x50, 0xff, 0x0b, 0x02, 0x09, 0x61, 0xcc, 0x95, 0xb7, 0xd7, 0x88, - 0x6a, 0xf6, 0x5c, 0xc5, 0x68, 0xd3, 0x14, 0x95, 0x1a, 0x47, 0x5f, 0xd9, - 0xfb, 0x2d, 0xe4, 0x2f, 0x8f, 0x13, 0x86, 0xab, 0x31, 0x13, 0x40, 0x13, - 0xac, 0x6e, 0xed, 0xb5, 0x10, 0x30, 0x8b, 0x1b, 0x50, 0xa9, 0xce, 0xee, - 0x8c, 0xca, 0xeb, 0x7c, 0xb5, 0xb9, 0x16, 0x3d, 0xd4, 0xfa, 0x6f, 0x92, - 0x6d, 0x1e, 0xa2, 0xbd, 0xfb, 0x02, 0x4a, 0xc5, 0x70, 0xbe, 0xf1, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 04:e1:e7:a4:dc:5c:f2:f3:6d:c0:2b:42:b8:5d:15:9f - Signature Algorithm: sha256WithRSAEncryption - Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA - Validity - Not Before: Oct 22 12:00:00 2013 GMT - Not After : Oct 22 12:00:00 2028 GMT - Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert SHA2 High Assurance Server CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:b6:e0:2f:c2:24:06:c8:6d:04:5f:d7:ef:0a:64: - 06:b2:7d:22:26:65:16:ae:42:40:9b:ce:dc:9f:9f: - 76:07:3e:c3:30:55:87:19:b9:4f:94:0e:5a:94:1f: - 55:56:b4:c2:02:2a:af:d0:98:ee:0b:40:d7:c4:d0: - 3b:72:c8:14:9e:ef:90:b1:11:a9:ae:d2:c8:b8:43: - 3a:d9:0b:0b:d5:d5:95:f5:40:af:c8:1d:ed:4d:9c: - 5f:57:b7:86:50:68:99:f5:8a:da:d2:c7:05:1f:a8: - 97:c9:dc:a4:b1:82:84:2d:c6:ad:a5:9c:c7:19:82: - a6:85:0f:5e:44:58:2a:37:8f:fd:35:f1:0b:08:27: - 32:5a:f5:bb:8b:9e:a4:bd:51:d0:27:e2:dd:3b:42: - 33:a3:05:28:c4:bb:28:cc:9a:ac:2b:23:0d:78:c6: - 7b:e6:5e:71:b7:4a:3e:08:fb:81:b7:16:16:a1:9d: - 23:12:4d:e5:d7:92:08:ac:75:a4:9c:ba:cd:17:b2: - 1e:44:35:65:7f:53:25:39:d1:1c:0a:9a:63:1b:19: - 92:74:68:0a:37:c2:c2:52:48:cb:39:5a:a2:b6:e1: - 5d:c1:dd:a0:20:b8:21:a2:93:26:6f:14:4a:21:41: - c7:ed:6d:9b:f2:48:2f:f3:03:f5:a2:68:92:53:2f: - 5e:e3 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Key Usage: critical - Digital Signature, Certificate Sign, CRL Sign - X509v3 Extended Key Usage: - TLS Web Server Authentication, TLS Web Client Authentication - Authority Information Access: - OCSP - URI:http://ocsp.digicert.com - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl4.digicert.com/DigiCertHighAssuranceEVRootCA.crl - - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://www.digicert.com/CPS - - X509v3 Subject Key Identifier: - 51:68:FF:90:AF:02:07:75:3C:CC:D9:65:64:62:A2:12:B8:59:72:3B - X509v3 Authority Key Identifier: - keyid:B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3 - - Signature Algorithm: sha256WithRSAEncryption - 18:8a:95:89:03:e6:6d:df:5c:fc:1d:68:ea:4a:8f:83:d6:51: - 2f:8d:6b:44:16:9e:ac:63:f5:d2:6e:6c:84:99:8b:aa:81:71: - 84:5b:ed:34:4e:b0:b7:79:92:29:cc:2d:80:6a:f0:8e:20:e1: - 79:a4:fe:03:47:13:ea:f5:86:ca:59:71:7d:f4:04:96:6b:d3: - 59:58:3d:fe:d3:31:25:5c:18:38:84:a3:e6:9f:82:fd:8c:5b: - 98:31:4e:cd:78:9e:1a:fd:85:cb:49:aa:f2:27:8b:99:72:fc: - 3e:aa:d5:41:0b:da:d5:36:a1:bf:1c:6e:47:49:7f:5e:d9:48: - 7c:03:d9:fd:8b:49:a0:98:26:42:40:eb:d6:92:11:a4:64:0a: - 57:54:c4:f5:1d:d6:02:5e:6b:ac:ee:c4:80:9a:12:72:fa:56: - 93:d7:ff:bf:30:85:06:30:bf:0b:7f:4e:ff:57:05:9d:24:ed: - 85:c3:2b:fb:a6:75:a8:ac:2d:16:ef:7d:79:27:b2:eb:c2:9d: - 0b:07:ea:aa:85:d3:01:a3:20:28:41:59:43:28:d2:81:e3:aa: - f6:ec:7b:3b:77:b6:40:62:80:05:41:45:01:ef:17:06:3e:de: - c0:33:9b:67:d3:61:2e:72:87:e4:69:fc:12:00:57:40:1e:70: - f5:1e:c9:b4 ------BEGIN CERTIFICATE----- -MIIEsTCCA5mgAwIBAgIQBOHnpNxc8vNtwCtCuF0VnzANBgkqhkiG9w0BAQsFADBs -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j -ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcDEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 -LmRpZ2ljZXJ0LmNvbTEvMC0GA1UEAxMmRGlnaUNlcnQgU0hBMiBIaWdoIEFzc3Vy -YW5jZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2 -4C/CJAbIbQRf1+8KZAayfSImZRauQkCbztyfn3YHPsMwVYcZuU+UDlqUH1VWtMIC -Kq/QmO4LQNfE0DtyyBSe75CxEamu0si4QzrZCwvV1ZX1QK/IHe1NnF9Xt4ZQaJn1 -itrSxwUfqJfJ3KSxgoQtxq2lnMcZgqaFD15EWCo3j/018QsIJzJa9buLnqS9UdAn -4t07QjOjBSjEuyjMmqwrIw14xnvmXnG3Sj4I+4G3FhahnSMSTeXXkgisdaScus0X -sh5ENWV/UyU50RwKmmMbGZJ0aAo3wsJSSMs5WqK24V3B3aAguCGikyZvFEohQcft -bZvySC/zA/WiaJJTL17jAgMBAAGjggFJMIIBRTASBgNVHRMBAf8ECDAGAQH/AgEA -MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw -NAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy -dC5jb20wSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNlcnQuY29t -L0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDA9BgNVHSAENjA0MDIG -BFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQ -UzAdBgNVHQ4EFgQUUWj/kK8CB3U8zNllZGKiErhZcjswHwYDVR0jBBgwFoAUsT7D -aQP4v0cB1JgmGggC72NkK8MwDQYJKoZIhvcNAQELBQADggEBABiKlYkD5m3fXPwd -aOpKj4PWUS+Na0QWnqxj9dJubISZi6qBcYRb7TROsLd5kinMLYBq8I4g4Xmk/gNH -E+r1hspZcX30BJZr01lYPf7TMSVcGDiEo+afgv2MW5gxTs14nhr9hctJqvIni5ly -/D6q1UEL2tU2ob8cbkdJf17ZSHwD2f2LSaCYJkJA69aSEaRkCldUxPUd1gJea6zu -xICaEnL6VpPX/78whQYwvwt/Tv9XBZ0k7YXDK/umdaisLRbvfXknsuvCnQsH6qqF -0wGjIChBWUMo0oHjqvbsezt3tkBigAVBRQHvFwY+3sAzm2fTYS5yh+Rp/BIAV0Ae -cPUeybQ= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert32[] = { - 0x30, 0x82, 0x04, 0xb1, 0x30, 0x82, 0x03, 0x99, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x04, 0xe1, 0xe7, 0xa4, 0xdc, 0x5c, 0xf2, 0xf3, 0x6d, - 0xc0, 0x2b, 0x42, 0xb8, 0x5d, 0x15, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x6c, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, - 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, - 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, - 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, - 0x63, 0x6f, 0x6d, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48, - 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, - 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, - 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x32, 0x32, 0x31, 0x32, - 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x31, 0x30, 0x32, - 0x32, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x70, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44, 0x69, - 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x19, - 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, 0x77, 0x77, - 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, - 0x6d, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26, - 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x53, 0x48, 0x41, - 0x32, 0x20, 0x48, 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, - 0x61, 0x6e, 0x63, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, - 0x43, 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, 0xb6, - 0xe0, 0x2f, 0xc2, 0x24, 0x06, 0xc8, 0x6d, 0x04, 0x5f, 0xd7, 0xef, 0x0a, - 0x64, 0x06, 0xb2, 0x7d, 0x22, 0x26, 0x65, 0x16, 0xae, 0x42, 0x40, 0x9b, - 0xce, 0xdc, 0x9f, 0x9f, 0x76, 0x07, 0x3e, 0xc3, 0x30, 0x55, 0x87, 0x19, - 0xb9, 0x4f, 0x94, 0x0e, 0x5a, 0x94, 0x1f, 0x55, 0x56, 0xb4, 0xc2, 0x02, - 0x2a, 0xaf, 0xd0, 0x98, 0xee, 0x0b, 0x40, 0xd7, 0xc4, 0xd0, 0x3b, 0x72, - 0xc8, 0x14, 0x9e, 0xef, 0x90, 0xb1, 0x11, 0xa9, 0xae, 0xd2, 0xc8, 0xb8, - 0x43, 0x3a, 0xd9, 0x0b, 0x0b, 0xd5, 0xd5, 0x95, 0xf5, 0x40, 0xaf, 0xc8, - 0x1d, 0xed, 0x4d, 0x9c, 0x5f, 0x57, 0xb7, 0x86, 0x50, 0x68, 0x99, 0xf5, - 0x8a, 0xda, 0xd2, 0xc7, 0x05, 0x1f, 0xa8, 0x97, 0xc9, 0xdc, 0xa4, 0xb1, - 0x82, 0x84, 0x2d, 0xc6, 0xad, 0xa5, 0x9c, 0xc7, 0x19, 0x82, 0xa6, 0x85, - 0x0f, 0x5e, 0x44, 0x58, 0x2a, 0x37, 0x8f, 0xfd, 0x35, 0xf1, 0x0b, 0x08, - 0x27, 0x32, 0x5a, 0xf5, 0xbb, 0x8b, 0x9e, 0xa4, 0xbd, 0x51, 0xd0, 0x27, - 0xe2, 0xdd, 0x3b, 0x42, 0x33, 0xa3, 0x05, 0x28, 0xc4, 0xbb, 0x28, 0xcc, - 0x9a, 0xac, 0x2b, 0x23, 0x0d, 0x78, 0xc6, 0x7b, 0xe6, 0x5e, 0x71, 0xb7, - 0x4a, 0x3e, 0x08, 0xfb, 0x81, 0xb7, 0x16, 0x16, 0xa1, 0x9d, 0x23, 0x12, - 0x4d, 0xe5, 0xd7, 0x92, 0x08, 0xac, 0x75, 0xa4, 0x9c, 0xba, 0xcd, 0x17, - 0xb2, 0x1e, 0x44, 0x35, 0x65, 0x7f, 0x53, 0x25, 0x39, 0xd1, 0x1c, 0x0a, - 0x9a, 0x63, 0x1b, 0x19, 0x92, 0x74, 0x68, 0x0a, 0x37, 0xc2, 0xc2, 0x52, - 0x48, 0xcb, 0x39, 0x5a, 0xa2, 0xb6, 0xe1, 0x5d, 0xc1, 0xdd, 0xa0, 0x20, - 0xb8, 0x21, 0xa2, 0x93, 0x26, 0x6f, 0x14, 0x4a, 0x21, 0x41, 0xc7, 0xed, - 0x6d, 0x9b, 0xf2, 0x48, 0x2f, 0xf3, 0x03, 0xf5, 0xa2, 0x68, 0x92, 0x53, - 0x2f, 0x5e, 0xe3, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x49, - 0x30, 0x82, 0x01, 0x45, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, - 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, - 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, - 0x03, 0x02, 0x01, 0x86, 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, - 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, - 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, - 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4b, 0x06, 0x03, 0x55, 0x1d, 0x1f, - 0x04, 0x44, 0x30, 0x42, 0x30, 0x40, 0xa0, 0x3e, 0xa0, 0x3c, 0x86, 0x3a, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x34, 0x2e, - 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x48, 0x69, 0x67, - 0x68, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x56, - 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3d, - 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06, - 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, - 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, - 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, - 0x53, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, - 0x51, 0x68, 0xff, 0x90, 0xaf, 0x02, 0x07, 0x75, 0x3c, 0xcc, 0xd9, 0x65, - 0x64, 0x62, 0xa2, 0x12, 0xb8, 0x59, 0x72, 0x3b, 0x30, 0x1f, 0x06, 0x03, - 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb1, 0x3e, 0xc3, - 0x69, 0x03, 0xf8, 0xbf, 0x47, 0x01, 0xd4, 0x98, 0x26, 0x1a, 0x08, 0x02, - 0xef, 0x63, 0x64, 0x2b, 0xc3, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, - 0x00, 0x18, 0x8a, 0x95, 0x89, 0x03, 0xe6, 0x6d, 0xdf, 0x5c, 0xfc, 0x1d, - 0x68, 0xea, 0x4a, 0x8f, 0x83, 0xd6, 0x51, 0x2f, 0x8d, 0x6b, 0x44, 0x16, - 0x9e, 0xac, 0x63, 0xf5, 0xd2, 0x6e, 0x6c, 0x84, 0x99, 0x8b, 0xaa, 0x81, - 0x71, 0x84, 0x5b, 0xed, 0x34, 0x4e, 0xb0, 0xb7, 0x79, 0x92, 0x29, 0xcc, - 0x2d, 0x80, 0x6a, 0xf0, 0x8e, 0x20, 0xe1, 0x79, 0xa4, 0xfe, 0x03, 0x47, - 0x13, 0xea, 0xf5, 0x86, 0xca, 0x59, 0x71, 0x7d, 0xf4, 0x04, 0x96, 0x6b, - 0xd3, 0x59, 0x58, 0x3d, 0xfe, 0xd3, 0x31, 0x25, 0x5c, 0x18, 0x38, 0x84, - 0xa3, 0xe6, 0x9f, 0x82, 0xfd, 0x8c, 0x5b, 0x98, 0x31, 0x4e, 0xcd, 0x78, - 0x9e, 0x1a, 0xfd, 0x85, 0xcb, 0x49, 0xaa, 0xf2, 0x27, 0x8b, 0x99, 0x72, - 0xfc, 0x3e, 0xaa, 0xd5, 0x41, 0x0b, 0xda, 0xd5, 0x36, 0xa1, 0xbf, 0x1c, - 0x6e, 0x47, 0x49, 0x7f, 0x5e, 0xd9, 0x48, 0x7c, 0x03, 0xd9, 0xfd, 0x8b, - 0x49, 0xa0, 0x98, 0x26, 0x42, 0x40, 0xeb, 0xd6, 0x92, 0x11, 0xa4, 0x64, - 0x0a, 0x57, 0x54, 0xc4, 0xf5, 0x1d, 0xd6, 0x02, 0x5e, 0x6b, 0xac, 0xee, - 0xc4, 0x80, 0x9a, 0x12, 0x72, 0xfa, 0x56, 0x93, 0xd7, 0xff, 0xbf, 0x30, - 0x85, 0x06, 0x30, 0xbf, 0x0b, 0x7f, 0x4e, 0xff, 0x57, 0x05, 0x9d, 0x24, - 0xed, 0x85, 0xc3, 0x2b, 0xfb, 0xa6, 0x75, 0xa8, 0xac, 0x2d, 0x16, 0xef, - 0x7d, 0x79, 0x27, 0xb2, 0xeb, 0xc2, 0x9d, 0x0b, 0x07, 0xea, 0xaa, 0x85, - 0xd3, 0x01, 0xa3, 0x20, 0x28, 0x41, 0x59, 0x43, 0x28, 0xd2, 0x81, 0xe3, - 0xaa, 0xf6, 0xec, 0x7b, 0x3b, 0x77, 0xb6, 0x40, 0x62, 0x80, 0x05, 0x41, - 0x45, 0x01, 0xef, 0x17, 0x06, 0x3e, 0xde, 0xc0, 0x33, 0x9b, 0x67, 0xd3, - 0x61, 0x2e, 0x72, 0x87, 0xe4, 0x69, 0xfc, 0x12, 0x00, 0x57, 0x40, 0x1e, - 0x70, 0xf5, 0x1e, 0xc9, 0xb4, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 0c:79:a9:44:b0:8c:11:95:20:92:61:5f:e2:6b:1d:83 - Signature Algorithm: sha256WithRSAEncryption - Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA - Validity - Not Before: Oct 22 12:00:00 2013 GMT - Not After : Oct 22 12:00:00 2028 GMT - Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert SHA2 Extended Validation Server CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:d7:53:a4:04:51:f8:99:a6:16:48:4b:67:27:aa: - 93:49:d0:39:ed:0c:b0:b0:00:87:f1:67:28:86:85: - 8c:8e:63:da:bc:b1:40:38:e2:d3:f5:ec:a5:05:18: - b8:3d:3e:c5:99:17:32:ec:18:8c:fa:f1:0c:a6:64: - 21:85:cb:07:10:34:b0:52:88:2b:1f:68:9b:d2:b1: - 8f:12:b0:b3:d2:e7:88:1f:1f:ef:38:77:54:53:5f: - 80:79:3f:2e:1a:aa:a8:1e:4b:2b:0d:ab:b7:63:b9: - 35:b7:7d:14:bc:59:4b:df:51:4a:d2:a1:e2:0c:e2: - 90:82:87:6a:ae:ea:d7:64:d6:98:55:e8:fd:af:1a: - 50:6c:54:bc:11:f2:fd:4a:f2:9d:bb:7f:0e:f4:d5: - be:8e:16:89:12:55:d8:c0:71:34:ee:f6:dc:2d:ec: - c4:87:25:86:8d:d8:21:e4:b0:4d:0c:89:dc:39:26: - 17:dd:f6:d7:94:85:d8:04:21:70:9d:6f:6f:ff:5c: - ba:19:e1:45:cb:56:57:28:7e:1c:0d:41:57:aa:b7: - b8:27:bb:b1:e4:fa:2a:ef:21:23:75:1a:ad:2d:9b: - 86:35:8c:9c:77:b5:73:ad:d8:94:2d:e4:f3:0c:9d: - ee:c1:4e:62:7e:17:c0:71:9e:2c:de:f1:f9:10:28: - 19:33 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Key Usage: critical - Digital Signature, Certificate Sign, CRL Sign - X509v3 Extended Key Usage: - TLS Web Server Authentication, TLS Web Client Authentication - Authority Information Access: - OCSP - URI:http://ocsp.digicert.com - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl4.digicert.com/DigiCertHighAssuranceEVRootCA.crl - - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://www.digicert.com/CPS - - X509v3 Subject Key Identifier: - 3D:D3:50:A5:D6:A0:AD:EE:F3:4A:60:0A:65:D3:21:D4:F8:F8:D6:0F - X509v3 Authority Key Identifier: - keyid:B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3 - - Signature Algorithm: sha256WithRSAEncryption - 9d:b6:d0:90:86:e1:86:02:ed:c5:a0:f0:34:1c:74:c1:8d:76: - cc:86:0a:a8:f0:4a:8a:42:d6:3f:c8:a9:4d:ad:7c:08:ad:e6: - b6:50:b8:a2:1a:4d:88:07:b1:29:21:dc:e7:da:c6:3c:21:e0: - e3:11:49:70:ac:7a:1d:01:a4:ca:11:3a:57:ab:7d:57:2a:40: - 74:fd:d3:1d:85:18:50:df:57:47:75:a1:7d:55:20:2e:47:37: - 50:72:8c:7f:82:1b:d2:62:8f:2d:03:5a:da:c3:c8:a1:ce:2c: - 52:a2:00:63:eb:73:ba:71:c8:49:27:23:97:64:85:9e:38:0e: - ad:63:68:3c:ba:52:81:58:79:a3:2c:0c:df:de:6d:eb:31:f2: - ba:a0:7c:6c:f1:2c:d4:e1:bd:77:84:37:03:ce:32:b5:c8:9a: - 81:1a:4a:92:4e:3b:46:9a:85:fe:83:a2:f9:9e:8c:a3:cc:0d: - 5e:b3:3d:cf:04:78:8f:14:14:7b:32:9c:c7:00:a6:5c:c4:b5: - a1:55:8d:5a:56:68:a4:22:70:aa:3c:81:71:d9:9d:a8:45:3b: - f4:e5:f6:a2:51:dd:c7:7b:62:e8:6f:0c:74:eb:b8:da:f8:bf: - 87:0d:79:50:91:90:9b:18:3b:91:59:27:f1:35:28:13:ab:26: - 7e:d5:f7:7a ------BEGIN CERTIFICATE----- -MIIEtjCCA56gAwIBAgIQDHmpRLCMEZUgkmFf4msdgzANBgkqhkiG9w0BAQsFADBs -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j -ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowdTEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 -LmRpZ2ljZXJ0LmNvbTE0MDIGA1UEAxMrRGlnaUNlcnQgU0hBMiBFeHRlbmRlZCBW -YWxpZGF0aW9uIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBANdTpARR+JmmFkhLZyeqk0nQOe0MsLAAh/FnKIaFjI5j2ryxQDji0/XspQUY -uD0+xZkXMuwYjPrxDKZkIYXLBxA0sFKIKx9om9KxjxKws9LniB8f7zh3VFNfgHk/ -LhqqqB5LKw2rt2O5Nbd9FLxZS99RStKh4gzikIKHaq7q12TWmFXo/a8aUGxUvBHy -/Urynbt/DvTVvo4WiRJV2MBxNO723C3sxIclho3YIeSwTQyJ3DkmF93215SF2AQh -cJ1vb/9cuhnhRctWVyh+HA1BV6q3uCe7seT6Ku8hI3UarS2bhjWMnHe1c63YlC3k -8wyd7sFOYn4XwHGeLN7x+RAoGTMCAwEAAaOCAUkwggFFMBIGA1UdEwEB/wQIMAYB -Af8CAQAwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF -BQcDAjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp -Z2ljZXJ0LmNvbTBLBgNVHR8ERDBCMECgPqA8hjpodHRwOi8vY3JsNC5kaWdpY2Vy -dC5jb20vRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3JsMD0GA1UdIAQ2 -MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5j -b20vQ1BTMB0GA1UdDgQWBBQ901Cl1qCt7vNKYApl0yHU+PjWDzAfBgNVHSMEGDAW -gBSxPsNpA/i/RwHUmCYaCALvY2QrwzANBgkqhkiG9w0BAQsFAAOCAQEAnbbQkIbh -hgLtxaDwNBx0wY12zIYKqPBKikLWP8ipTa18CK3mtlC4ohpNiAexKSHc59rGPCHg -4xFJcKx6HQGkyhE6V6t9VypAdP3THYUYUN9XR3WhfVUgLkc3UHKMf4Ib0mKPLQNa -2sPIoc4sUqIAY+tzunHISScjl2SFnjgOrWNoPLpSgVh5oywM395t6zHyuqB8bPEs -1OG9d4Q3A84ytciagRpKkk47RpqF/oOi+Z6Mo8wNXrM9zwR4jxQUezKcxwCmXMS1 -oVWNWlZopCJwqjyBcdmdqEU79OX2olHdx3ti6G8MdOu42vi/hw15UJGQmxg7kVkn -8TUoE6smftX3eg== ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert33[] = { - 0x30, 0x82, 0x04, 0xb6, 0x30, 0x82, 0x03, 0x9e, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x0c, 0x79, 0xa9, 0x44, 0xb0, 0x8c, 0x11, 0x95, 0x20, - 0x92, 0x61, 0x5f, 0xe2, 0x6b, 0x1d, 0x83, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x6c, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, - 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, - 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, - 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, - 0x63, 0x6f, 0x6d, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48, - 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, - 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, - 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x32, 0x32, 0x31, 0x32, - 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x31, 0x30, 0x32, - 0x32, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x75, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44, 0x69, - 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x19, - 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, 0x77, 0x77, - 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, - 0x6d, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2b, - 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x53, 0x48, 0x41, - 0x32, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 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, 0xd7, 0x53, 0xa4, 0x04, 0x51, 0xf8, 0x99, 0xa6, - 0x16, 0x48, 0x4b, 0x67, 0x27, 0xaa, 0x93, 0x49, 0xd0, 0x39, 0xed, 0x0c, - 0xb0, 0xb0, 0x00, 0x87, 0xf1, 0x67, 0x28, 0x86, 0x85, 0x8c, 0x8e, 0x63, - 0xda, 0xbc, 0xb1, 0x40, 0x38, 0xe2, 0xd3, 0xf5, 0xec, 0xa5, 0x05, 0x18, - 0xb8, 0x3d, 0x3e, 0xc5, 0x99, 0x17, 0x32, 0xec, 0x18, 0x8c, 0xfa, 0xf1, - 0x0c, 0xa6, 0x64, 0x21, 0x85, 0xcb, 0x07, 0x10, 0x34, 0xb0, 0x52, 0x88, - 0x2b, 0x1f, 0x68, 0x9b, 0xd2, 0xb1, 0x8f, 0x12, 0xb0, 0xb3, 0xd2, 0xe7, - 0x88, 0x1f, 0x1f, 0xef, 0x38, 0x77, 0x54, 0x53, 0x5f, 0x80, 0x79, 0x3f, - 0x2e, 0x1a, 0xaa, 0xa8, 0x1e, 0x4b, 0x2b, 0x0d, 0xab, 0xb7, 0x63, 0xb9, - 0x35, 0xb7, 0x7d, 0x14, 0xbc, 0x59, 0x4b, 0xdf, 0x51, 0x4a, 0xd2, 0xa1, - 0xe2, 0x0c, 0xe2, 0x90, 0x82, 0x87, 0x6a, 0xae, 0xea, 0xd7, 0x64, 0xd6, - 0x98, 0x55, 0xe8, 0xfd, 0xaf, 0x1a, 0x50, 0x6c, 0x54, 0xbc, 0x11, 0xf2, - 0xfd, 0x4a, 0xf2, 0x9d, 0xbb, 0x7f, 0x0e, 0xf4, 0xd5, 0xbe, 0x8e, 0x16, - 0x89, 0x12, 0x55, 0xd8, 0xc0, 0x71, 0x34, 0xee, 0xf6, 0xdc, 0x2d, 0xec, - 0xc4, 0x87, 0x25, 0x86, 0x8d, 0xd8, 0x21, 0xe4, 0xb0, 0x4d, 0x0c, 0x89, - 0xdc, 0x39, 0x26, 0x17, 0xdd, 0xf6, 0xd7, 0x94, 0x85, 0xd8, 0x04, 0x21, - 0x70, 0x9d, 0x6f, 0x6f, 0xff, 0x5c, 0xba, 0x19, 0xe1, 0x45, 0xcb, 0x56, - 0x57, 0x28, 0x7e, 0x1c, 0x0d, 0x41, 0x57, 0xaa, 0xb7, 0xb8, 0x27, 0xbb, - 0xb1, 0xe4, 0xfa, 0x2a, 0xef, 0x21, 0x23, 0x75, 0x1a, 0xad, 0x2d, 0x9b, - 0x86, 0x35, 0x8c, 0x9c, 0x77, 0xb5, 0x73, 0xad, 0xd8, 0x94, 0x2d, 0xe4, - 0xf3, 0x0c, 0x9d, 0xee, 0xc1, 0x4e, 0x62, 0x7e, 0x17, 0xc0, 0x71, 0x9e, - 0x2c, 0xde, 0xf1, 0xf9, 0x10, 0x28, 0x19, 0x33, 0x02, 0x03, 0x01, 0x00, - 0x01, 0xa3, 0x82, 0x01, 0x49, 0x30, 0x82, 0x01, 0x45, 0x30, 0x12, 0x06, - 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, - 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, - 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 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, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x64, 0x69, - 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4b, - 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x44, 0x30, 0x42, 0x30, 0x40, 0xa0, - 0x3e, 0xa0, 0x3c, 0x86, 0x3a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x63, 0x72, 0x6c, 0x34, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, - 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, - 0x72, 0x74, 0x48, 0x69, 0x67, 0x68, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, - 0x6e, 0x63, 0x65, 0x45, 0x56, 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e, - 0x63, 0x72, 0x6c, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, - 0x30, 0x34, 0x30, 0x32, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, - 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, - 0x16, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, - 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, - 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3d, 0xd3, 0x50, 0xa5, 0xd6, 0xa0, 0xad, - 0xee, 0xf3, 0x4a, 0x60, 0x0a, 0x65, 0xd3, 0x21, 0xd4, 0xf8, 0xf8, 0xd6, - 0x0f, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, - 0x80, 0x14, 0xb1, 0x3e, 0xc3, 0x69, 0x03, 0xf8, 0xbf, 0x47, 0x01, 0xd4, - 0x98, 0x26, 0x1a, 0x08, 0x02, 0xef, 0x63, 0x64, 0x2b, 0xc3, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, - 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x9d, 0xb6, 0xd0, 0x90, 0x86, 0xe1, - 0x86, 0x02, 0xed, 0xc5, 0xa0, 0xf0, 0x34, 0x1c, 0x74, 0xc1, 0x8d, 0x76, - 0xcc, 0x86, 0x0a, 0xa8, 0xf0, 0x4a, 0x8a, 0x42, 0xd6, 0x3f, 0xc8, 0xa9, - 0x4d, 0xad, 0x7c, 0x08, 0xad, 0xe6, 0xb6, 0x50, 0xb8, 0xa2, 0x1a, 0x4d, - 0x88, 0x07, 0xb1, 0x29, 0x21, 0xdc, 0xe7, 0xda, 0xc6, 0x3c, 0x21, 0xe0, - 0xe3, 0x11, 0x49, 0x70, 0xac, 0x7a, 0x1d, 0x01, 0xa4, 0xca, 0x11, 0x3a, - 0x57, 0xab, 0x7d, 0x57, 0x2a, 0x40, 0x74, 0xfd, 0xd3, 0x1d, 0x85, 0x18, - 0x50, 0xdf, 0x57, 0x47, 0x75, 0xa1, 0x7d, 0x55, 0x20, 0x2e, 0x47, 0x37, - 0x50, 0x72, 0x8c, 0x7f, 0x82, 0x1b, 0xd2, 0x62, 0x8f, 0x2d, 0x03, 0x5a, - 0xda, 0xc3, 0xc8, 0xa1, 0xce, 0x2c, 0x52, 0xa2, 0x00, 0x63, 0xeb, 0x73, - 0xba, 0x71, 0xc8, 0x49, 0x27, 0x23, 0x97, 0x64, 0x85, 0x9e, 0x38, 0x0e, - 0xad, 0x63, 0x68, 0x3c, 0xba, 0x52, 0x81, 0x58, 0x79, 0xa3, 0x2c, 0x0c, - 0xdf, 0xde, 0x6d, 0xeb, 0x31, 0xf2, 0xba, 0xa0, 0x7c, 0x6c, 0xf1, 0x2c, - 0xd4, 0xe1, 0xbd, 0x77, 0x84, 0x37, 0x03, 0xce, 0x32, 0xb5, 0xc8, 0x9a, - 0x81, 0x1a, 0x4a, 0x92, 0x4e, 0x3b, 0x46, 0x9a, 0x85, 0xfe, 0x83, 0xa2, - 0xf9, 0x9e, 0x8c, 0xa3, 0xcc, 0x0d, 0x5e, 0xb3, 0x3d, 0xcf, 0x04, 0x78, - 0x8f, 0x14, 0x14, 0x7b, 0x32, 0x9c, 0xc7, 0x00, 0xa6, 0x5c, 0xc4, 0xb5, - 0xa1, 0x55, 0x8d, 0x5a, 0x56, 0x68, 0xa4, 0x22, 0x70, 0xaa, 0x3c, 0x81, - 0x71, 0xd9, 0x9d, 0xa8, 0x45, 0x3b, 0xf4, 0xe5, 0xf6, 0xa2, 0x51, 0xdd, - 0xc7, 0x7b, 0x62, 0xe8, 0x6f, 0x0c, 0x74, 0xeb, 0xb8, 0xda, 0xf8, 0xbf, - 0x87, 0x0d, 0x79, 0x50, 0x91, 0x90, 0x9b, 0x18, 0x3b, 0x91, 0x59, 0x27, - 0xf1, 0x35, 0x28, 0x13, 0xab, 0x26, 0x7e, 0xd5, 0xf7, 0x7a, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 35:97:31:87:f3:87:3a:07:32:7e:ce:58:0c:9b:7e:da - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority - Validity - Not Before: Nov 8 00:00:00 2006 GMT - Not After : Nov 7 23:59:59 2021 GMT - Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:af:24:08:08:29:7a:35:9e:60:0c:aa:e7:4b:3b: - 4e:dc:7c:bc:3c:45:1c:bb:2b:e0:fe:29:02:f9:57: - 08:a3:64:85:15:27:f5:f1:ad:c8:31:89:5d:22:e8: - 2a:aa:a6:42:b3:8f:f8:b9:55:b7:b1:b7:4b:b3:fe: - 8f:7e:07:57:ec:ef:43:db:66:62:15:61:cf:60:0d: - a4:d8:de:f8:e0:c3:62:08:3d:54:13:eb:49:ca:59: - 54:85:26:e5:2b:8f:1b:9f:eb:f5:a1:91:c2:33:49: - d8:43:63:6a:52:4b:d2:8f:e8:70:51:4d:d1:89:69: - 7b:c7:70:f6:b3:dc:12:74:db:7b:5d:4b:56:d3:96: - bf:15:77:a1:b0:f4:a2:25:f2:af:1c:92:67:18:e5: - f4:06:04:ef:90:b9:e4:00:e4:dd:3a:b5:19:ff:02: - ba:f4:3c:ee:e0:8b:eb:37:8b:ec:f4:d7:ac:f2:f6: - f0:3d:af:dd:75:91:33:19:1d:1c:40:cb:74:24:19: - 21:93:d9:14:fe:ac:2a:52:c7:8f:d5:04:49:e4:8d: - 63:47:88:3c:69:83:cb:fe:47:bd:2b:7e:4f:c5:95: - ae:0e:9d:d4:d1:43:c0:67:73:e3:14:08:7e:e5:3f: - 9f:73:b8:33:0a:cf:5d:3f:34:87:96:8a:ee:53:e8: - 25:15 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.verisign.com/pca3.crl - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://www.verisign.com/cps - - X509v3 Subject Key Identifier: - 7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33 - X509v3 Extended Key Usage: - Netscape Server Gated Crypto, 2.16.840.1.113733.1.8.1, TLS Web Server Authentication, TLS Web Client Authentication - 1.3.6.1.5.5.7.1.12: - 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif - Authority Information Access: - OCSP - URI:http://ocsp.verisign.com - - Signature Algorithm: sha1WithRSAEncryption - 0f:25:ae:48:ed:1b:33:85:4c:0c:b5:c2:d7:fe:4d:d6:83:28: - 4c:41:65:60:00:0b:77:48:71:82:fe:7f:db:5a:0e:20:cc:d2: - ea:47:bc:64:42:61:44:34:74:30:81:81:26:8a:4a:f7:44:5d: - 7e:34:80:a8:b8:83:e2:09:d7:6d:23:dd:89:ed:28:08:bd:63: - 5a:11:57:08:c4:9e:da:e2:68:28:af:dd:50:3c:ec:82:21:d8: - 00:c2:55:44:50:70:41:ad:83:17:79:ba:08:f3:2b:de:ed:34: - 1d:44:9e:d2:04:93:f4:cb:05:17:2d:09:2d:2d:63:ef:f6:26: - 0b:7b ------BEGIN CERTIFICATE----- -MIIExjCCBC+gAwIBAgIQNZcxh/OHOgcyfs5YDJt+2jANBgkqhkiG9w0BAQUFADBf -MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsT -LkNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw -HhcNMDYxMTA4MDAwMDAwWhcNMjExMTA3MjM1OTU5WjCByjELMAkGA1UEBhMCVVMx -FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz -dCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZv -ciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAz -IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8 -RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbext0uz/o9+B1fs70Pb -ZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhDY2pSS9KP6HBR -TdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/ -Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNH -iDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMB -AAGjggGRMIIBjTAPBgNVHRMBAf8EBTADAQH/MDEGA1UdHwQqMCgwJqAkoCKGIGh0 -dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMuY3JsMA4GA1UdDwEB/wQEAwIBBjA9 -BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVy -aXNpZ24uY29tL2NwczAdBgNVHQ4EFgQUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwNAYD -VR0lBC0wKwYJYIZIAYb4QgQBBgpghkgBhvhFAQgBBggrBgEFBQcDAQYIKwYBBQUH -AwIwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAHBgUr -DgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNp -Z24uY29tL3ZzbG9nby5naWYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhho -dHRwOi8vb2NzcC52ZXJpc2lnbi5jb20wDQYJKoZIhvcNAQEFBQADgYEADyWuSO0b -M4VMDLXC1/5N1oMoTEFlYAALd0hxgv5/21oOIMzS6ke8ZEJhRDR0MIGBJopK90Rd -fjSAqLiD4gnXbSPdie0oCL1jWhFXCMSe2uJoKK/dUDzsgiHYAMJVRFBwQa2DF3m6 -CPMr3u00HUSe0gST9MsFFy0JLS1j7/YmC3s= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert34[] = { - 0x30, 0x82, 0x04, 0xc6, 0x30, 0x82, 0x04, 0x2f, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x35, 0x97, 0x31, 0x87, 0xf3, 0x87, 0x3a, 0x07, 0x32, - 0x7e, 0xce, 0x58, 0x0c, 0x9b, 0x7e, 0xda, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5f, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, - 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, - 0x63, 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, - 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, - 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x30, 0x38, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31, 0x30, 0x37, - 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xca, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, - 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56, - 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, - 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3a, 0x30, - 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, 0x63, 0x29, 0x20, - 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, - 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, - 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, - 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x45, 0x30, - 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56, 0x65, 0x72, 0x69, - 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, - 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 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, 0xaf, 0x24, 0x08, 0x08, 0x29, 0x7a, 0x35, - 0x9e, 0x60, 0x0c, 0xaa, 0xe7, 0x4b, 0x3b, 0x4e, 0xdc, 0x7c, 0xbc, 0x3c, - 0x45, 0x1c, 0xbb, 0x2b, 0xe0, 0xfe, 0x29, 0x02, 0xf9, 0x57, 0x08, 0xa3, - 0x64, 0x85, 0x15, 0x27, 0xf5, 0xf1, 0xad, 0xc8, 0x31, 0x89, 0x5d, 0x22, - 0xe8, 0x2a, 0xaa, 0xa6, 0x42, 0xb3, 0x8f, 0xf8, 0xb9, 0x55, 0xb7, 0xb1, - 0xb7, 0x4b, 0xb3, 0xfe, 0x8f, 0x7e, 0x07, 0x57, 0xec, 0xef, 0x43, 0xdb, - 0x66, 0x62, 0x15, 0x61, 0xcf, 0x60, 0x0d, 0xa4, 0xd8, 0xde, 0xf8, 0xe0, - 0xc3, 0x62, 0x08, 0x3d, 0x54, 0x13, 0xeb, 0x49, 0xca, 0x59, 0x54, 0x85, - 0x26, 0xe5, 0x2b, 0x8f, 0x1b, 0x9f, 0xeb, 0xf5, 0xa1, 0x91, 0xc2, 0x33, - 0x49, 0xd8, 0x43, 0x63, 0x6a, 0x52, 0x4b, 0xd2, 0x8f, 0xe8, 0x70, 0x51, - 0x4d, 0xd1, 0x89, 0x69, 0x7b, 0xc7, 0x70, 0xf6, 0xb3, 0xdc, 0x12, 0x74, - 0xdb, 0x7b, 0x5d, 0x4b, 0x56, 0xd3, 0x96, 0xbf, 0x15, 0x77, 0xa1, 0xb0, - 0xf4, 0xa2, 0x25, 0xf2, 0xaf, 0x1c, 0x92, 0x67, 0x18, 0xe5, 0xf4, 0x06, - 0x04, 0xef, 0x90, 0xb9, 0xe4, 0x00, 0xe4, 0xdd, 0x3a, 0xb5, 0x19, 0xff, - 0x02, 0xba, 0xf4, 0x3c, 0xee, 0xe0, 0x8b, 0xeb, 0x37, 0x8b, 0xec, 0xf4, - 0xd7, 0xac, 0xf2, 0xf6, 0xf0, 0x3d, 0xaf, 0xdd, 0x75, 0x91, 0x33, 0x19, - 0x1d, 0x1c, 0x40, 0xcb, 0x74, 0x24, 0x19, 0x21, 0x93, 0xd9, 0x14, 0xfe, - 0xac, 0x2a, 0x52, 0xc7, 0x8f, 0xd5, 0x04, 0x49, 0xe4, 0x8d, 0x63, 0x47, - 0x88, 0x3c, 0x69, 0x83, 0xcb, 0xfe, 0x47, 0xbd, 0x2b, 0x7e, 0x4f, 0xc5, - 0x95, 0xae, 0x0e, 0x9d, 0xd4, 0xd1, 0x43, 0xc0, 0x67, 0x73, 0xe3, 0x14, - 0x08, 0x7e, 0xe5, 0x3f, 0x9f, 0x73, 0xb8, 0x33, 0x0a, 0xcf, 0x5d, 0x3f, - 0x34, 0x87, 0x96, 0x8a, 0xee, 0x53, 0xe8, 0x25, 0x15, 0x02, 0x03, 0x01, - 0x00, 0x01, 0xa3, 0x82, 0x01, 0x91, 0x30, 0x82, 0x01, 0x8d, 0x30, 0x0f, - 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, - 0x01, 0x01, 0xff, 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2a, - 0x30, 0x28, 0x30, 0x26, 0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, - 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, - 0x61, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, - 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3d, - 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06, - 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, - 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, - 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, - 0x73, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, - 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3, - 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x34, 0x06, 0x03, - 0x55, 0x1d, 0x25, 0x04, 0x2d, 0x30, 0x2b, 0x06, 0x09, 0x60, 0x86, 0x48, - 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, - 0x86, 0xf8, 0x45, 0x01, 0x08, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x03, 0x02, 0x30, 0x6d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f, 0xa1, 0x5d, 0xa0, 0x5b, 0x30, 0x59, - 0x30, 0x57, 0x30, 0x55, 0x16, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, - 0x67, 0x69, 0x66, 0x30, 0x21, 0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, - 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, 0x8f, 0xe5, 0xd3, 0x1a, 0x86, 0xac, - 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80, 0x6a, 0xd4, 0x48, 0x18, 0x2c, 0x7b, - 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, - 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x73, 0x6c, 0x6f, 0x67, - 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, - 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x76, - 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, - 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x0f, 0x25, 0xae, 0x48, 0xed, 0x1b, - 0x33, 0x85, 0x4c, 0x0c, 0xb5, 0xc2, 0xd7, 0xfe, 0x4d, 0xd6, 0x83, 0x28, - 0x4c, 0x41, 0x65, 0x60, 0x00, 0x0b, 0x77, 0x48, 0x71, 0x82, 0xfe, 0x7f, - 0xdb, 0x5a, 0x0e, 0x20, 0xcc, 0xd2, 0xea, 0x47, 0xbc, 0x64, 0x42, 0x61, - 0x44, 0x34, 0x74, 0x30, 0x81, 0x81, 0x26, 0x8a, 0x4a, 0xf7, 0x44, 0x5d, - 0x7e, 0x34, 0x80, 0xa8, 0xb8, 0x83, 0xe2, 0x09, 0xd7, 0x6d, 0x23, 0xdd, - 0x89, 0xed, 0x28, 0x08, 0xbd, 0x63, 0x5a, 0x11, 0x57, 0x08, 0xc4, 0x9e, - 0xda, 0xe2, 0x68, 0x28, 0xaf, 0xdd, 0x50, 0x3c, 0xec, 0x82, 0x21, 0xd8, - 0x00, 0xc2, 0x55, 0x44, 0x50, 0x70, 0x41, 0xad, 0x83, 0x17, 0x79, 0xba, - 0x08, 0xf3, 0x2b, 0xde, 0xed, 0x34, 0x1d, 0x44, 0x9e, 0xd2, 0x04, 0x93, - 0xf4, 0xcb, 0x05, 0x17, 0x2d, 0x09, 0x2d, 0x2d, 0x63, 0xef, 0xf6, 0x26, - 0x0b, 0x7b, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 7 (0x7) - Signature Algorithm: sha256WithRSAEncryption - Issuer: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2 - Validity - Not Before: May 3 07:00:00 2011 GMT - Not After : May 3 07:00:00 2031 GMT - Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., OU=http://certs.godaddy.com/repository/, CN=Go Daddy Secure Certificate Authority - G2 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:b9:e0:cb:10:d4:af:76:bd:d4:93:62:eb:30:64: - b8:81:08:6c:c3:04:d9:62:17:8e:2f:ff:3e:65:cf: - 8f:ce:62:e6:3c:52:1c:da:16:45:4b:55:ab:78:6b: - 63:83:62:90:ce:0f:69:6c:99:c8:1a:14:8b:4c:cc: - 45:33:ea:88:dc:9e:a3:af:2b:fe:80:61:9d:79:57: - c4:cf:2e:f4:3f:30:3c:5d:47:fc:9a:16:bc:c3:37: - 96:41:51:8e:11:4b:54:f8:28:be:d0:8c:be:f0:30: - 38:1e:f3:b0:26:f8:66:47:63:6d:de:71:26:47:8f: - 38:47:53:d1:46:1d:b4:e3:dc:00:ea:45:ac:bd:bc: - 71:d9:aa:6f:00:db:db:cd:30:3a:79:4f:5f:4c:47: - f8:1d:ef:5b:c2:c4:9d:60:3b:b1:b2:43:91:d8:a4: - 33:4e:ea:b3:d6:27:4f:ad:25:8a:a5:c6:f4:d5:d0: - a6:ae:74:05:64:57:88:b5:44:55:d4:2d:2a:3a:3e: - f8:b8:bd:e9:32:0a:02:94:64:c4:16:3a:50:f1:4a: - ae:e7:79:33:af:0c:20:07:7f:e8:df:04:39:c2:69: - 02:6c:63:52:fa:77:c1:1b:c8:74:87:c8:b9:93:18: - 50:54:35:4b:69:4e:bc:3b:d3:49:2e:1f:dc:c1:d2: - 52:fb - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Subject Key Identifier: - 40:C2:BD:27:8E:CC:34:83:30:A2:33:D7:FB:6C:B3:F0:B4:2C:80:CE - X509v3 Authority Key Identifier: - keyid:3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE - - Authority Information Access: - OCSP - URI:http://ocsp.godaddy.com/ - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.godaddy.com/gdroot-g2.crl - - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://certs.godaddy.com/repository/ - - Signature Algorithm: sha256WithRSAEncryption - 08:7e:6c:93:10:c8:38:b8:96:a9:90:4b:ff:a1:5f:4f:04:ef: - 6c:3e:9c:88:06:c9:50:8f:a6:73:f7:57:31:1b:be:bc:e4:2f: - db:f8:ba:d3:5b:e0:b4:e7:e6:79:62:0e:0c:a2:d7:6a:63:73: - 31:b5:f5:a8:48:a4:3b:08:2d:a2:5d:90:d7:b4:7c:25:4f:11: - 56:30:c4:b6:44:9d:7b:2c:9d:e5:5e:e6:ef:0c:61:aa:bf:e4: - 2a:1b:ee:84:9e:b8:83:7d:c1:43:ce:44:a7:13:70:0d:91:1f: - f4:c8:13:ad:83:60:d9:d8:72:a8:73:24:1e:b5:ac:22:0e:ca: - 17:89:62:58:44:1b:ab:89:25:01:00:0f:cd:c4:1b:62:db:51: - b4:d3:0f:51:2a:9b:f4:bc:73:fc:76:ce:36:a4:cd:d9:d8:2c: - ea:ae:9b:f5:2a:b2:90:d1:4d:75:18:8a:3f:8a:41:90:23:7d: - 5b:4b:fe:a4:03:58:9b:46:b2:c3:60:60:83:f8:7d:50:41:ce: - c2:a1:90:c3:bb:ef:02:2f:d2:15:54:ee:44:15:d9:0a:ae:a7: - 8a:33:ed:b1:2d:76:36:26:dc:04:eb:9f:f7:61:1f:15:dc:87: - 6f:ee:46:96:28:ad:a1:26:7d:0a:09:a7:2e:04:a3:8d:bc:f8: - bc:04:30:01 ------BEGIN CERTIFICATE----- -MIIE0DCCA7igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT -EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp -ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAwMFoXDTMxMDUwMzA3 -MDAwMFowgbQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH -EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UE -CxMkaHR0cDovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQD -EypHbyBEYWRkeSBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC54MsQ1K92vdSTYuswZLiBCGzD -BNliF44v/z5lz4/OYuY8UhzaFkVLVat4a2ODYpDOD2lsmcgaFItMzEUz6ojcnqOv -K/6AYZ15V8TPLvQ/MDxdR/yaFrzDN5ZBUY4RS1T4KL7QjL7wMDge87Am+GZHY23e -cSZHjzhHU9FGHbTj3ADqRay9vHHZqm8A29vNMDp5T19MR/gd71vCxJ1gO7GyQ5HY -pDNO6rPWJ0+tJYqlxvTV0KaudAVkV4i1RFXULSo6Pvi4vekyCgKUZMQWOlDxSq7n -eTOvDCAHf+jfBDnCaQJsY1L6d8EbyHSHyLmTGFBUNUtpTrw700kuH9zB0lL7AgMB -AAGjggEaMIIBFjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV -HQ4EFgQUQMK9J47MNIMwojPX+2yz8LQsgM4wHwYDVR0jBBgwFoAUOpqFBxBnKLbv -9r0FQW4gwZTaD94wNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v -b2NzcC5nb2RhZGR5LmNvbS8wNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2NybC5n -b2RhZGR5LmNvbS9nZHJvb3QtZzIuY3JsMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEG -CCsGAQUFBwIBFiVodHRwczovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkv -MA0GCSqGSIb3DQEBCwUAA4IBAQAIfmyTEMg4uJapkEv/oV9PBO9sPpyIBslQj6Zz -91cxG7685C/b+LrTW+C05+Z5Yg4MotdqY3MxtfWoSKQ7CC2iXZDXtHwlTxFWMMS2 -RJ17LJ3lXubvDGGqv+QqG+6EnriDfcFDzkSnE3ANkR/0yBOtg2DZ2HKocyQetawi -DsoXiWJYRBuriSUBAA/NxBti21G00w9RKpv0vHP8ds42pM3Z2Czqrpv1KrKQ0U11 -GIo/ikGQI31bS/6kA1ibRrLDYGCD+H1QQc7CoZDDu+8CL9IVVO5EFdkKrqeKM+2x -LXY2JtwE65/3YR8V3Idv7kaWKK2hJn0KCacuBKONvPi8BDAB ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert35[] = { - 0x30, 0x82, 0x04, 0xd0, 0x30, 0x82, 0x03, 0xb8, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x01, 0x07, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x83, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, - 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, - 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, - 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, - 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x28, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, - 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x1e, 0x17, - 0x0d, 0x31, 0x31, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37, 0x30, 0x30, 0x30, - 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x31, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37, - 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x81, 0xb4, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, - 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, - 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, - 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, - 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x47, - 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x20, - 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, - 0x0b, 0x13, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, - 0x72, 0x74, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x2f, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x2a, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x53, - 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 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, 0xb9, 0xe0, 0xcb, 0x10, 0xd4, 0xaf, 0x76, - 0xbd, 0xd4, 0x93, 0x62, 0xeb, 0x30, 0x64, 0xb8, 0x81, 0x08, 0x6c, 0xc3, - 0x04, 0xd9, 0x62, 0x17, 0x8e, 0x2f, 0xff, 0x3e, 0x65, 0xcf, 0x8f, 0xce, - 0x62, 0xe6, 0x3c, 0x52, 0x1c, 0xda, 0x16, 0x45, 0x4b, 0x55, 0xab, 0x78, - 0x6b, 0x63, 0x83, 0x62, 0x90, 0xce, 0x0f, 0x69, 0x6c, 0x99, 0xc8, 0x1a, - 0x14, 0x8b, 0x4c, 0xcc, 0x45, 0x33, 0xea, 0x88, 0xdc, 0x9e, 0xa3, 0xaf, - 0x2b, 0xfe, 0x80, 0x61, 0x9d, 0x79, 0x57, 0xc4, 0xcf, 0x2e, 0xf4, 0x3f, - 0x30, 0x3c, 0x5d, 0x47, 0xfc, 0x9a, 0x16, 0xbc, 0xc3, 0x37, 0x96, 0x41, - 0x51, 0x8e, 0x11, 0x4b, 0x54, 0xf8, 0x28, 0xbe, 0xd0, 0x8c, 0xbe, 0xf0, - 0x30, 0x38, 0x1e, 0xf3, 0xb0, 0x26, 0xf8, 0x66, 0x47, 0x63, 0x6d, 0xde, - 0x71, 0x26, 0x47, 0x8f, 0x38, 0x47, 0x53, 0xd1, 0x46, 0x1d, 0xb4, 0xe3, - 0xdc, 0x00, 0xea, 0x45, 0xac, 0xbd, 0xbc, 0x71, 0xd9, 0xaa, 0x6f, 0x00, - 0xdb, 0xdb, 0xcd, 0x30, 0x3a, 0x79, 0x4f, 0x5f, 0x4c, 0x47, 0xf8, 0x1d, - 0xef, 0x5b, 0xc2, 0xc4, 0x9d, 0x60, 0x3b, 0xb1, 0xb2, 0x43, 0x91, 0xd8, - 0xa4, 0x33, 0x4e, 0xea, 0xb3, 0xd6, 0x27, 0x4f, 0xad, 0x25, 0x8a, 0xa5, - 0xc6, 0xf4, 0xd5, 0xd0, 0xa6, 0xae, 0x74, 0x05, 0x64, 0x57, 0x88, 0xb5, - 0x44, 0x55, 0xd4, 0x2d, 0x2a, 0x3a, 0x3e, 0xf8, 0xb8, 0xbd, 0xe9, 0x32, - 0x0a, 0x02, 0x94, 0x64, 0xc4, 0x16, 0x3a, 0x50, 0xf1, 0x4a, 0xae, 0xe7, - 0x79, 0x33, 0xaf, 0x0c, 0x20, 0x07, 0x7f, 0xe8, 0xdf, 0x04, 0x39, 0xc2, - 0x69, 0x02, 0x6c, 0x63, 0x52, 0xfa, 0x77, 0xc1, 0x1b, 0xc8, 0x74, 0x87, - 0xc8, 0xb9, 0x93, 0x18, 0x50, 0x54, 0x35, 0x4b, 0x69, 0x4e, 0xbc, 0x3b, - 0xd3, 0x49, 0x2e, 0x1f, 0xdc, 0xc1, 0xd2, 0x52, 0xfb, 0x02, 0x03, 0x01, - 0x00, 0x01, 0xa3, 0x82, 0x01, 0x1a, 0x30, 0x82, 0x01, 0x16, 0x30, 0x0f, - 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, - 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, - 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, - 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x40, 0xc2, 0xbd, 0x27, 0x8e, 0xcc, - 0x34, 0x83, 0x30, 0xa2, 0x33, 0xd7, 0xfb, 0x6c, 0xb3, 0xf0, 0xb4, 0x2c, - 0x80, 0xce, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, - 0x16, 0x80, 0x14, 0x3a, 0x9a, 0x85, 0x07, 0x10, 0x67, 0x28, 0xb6, 0xef, - 0xf6, 0xbd, 0x05, 0x41, 0x6e, 0x20, 0xc1, 0x94, 0xda, 0x0f, 0xde, 0x30, - 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, - 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x35, 0x06, 0x03, 0x55, 0x1d, 0x1f, - 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0, 0x26, 0x86, 0x24, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67, - 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, - 0x64, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x67, 0x32, 0x2e, 0x63, 0x72, 0x6c, - 0x30, 0x46, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30, - 0x3b, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x33, 0x30, 0x31, 0x06, - 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, - 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73, - 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x08, 0x7e, 0x6c, 0x93, - 0x10, 0xc8, 0x38, 0xb8, 0x96, 0xa9, 0x90, 0x4b, 0xff, 0xa1, 0x5f, 0x4f, - 0x04, 0xef, 0x6c, 0x3e, 0x9c, 0x88, 0x06, 0xc9, 0x50, 0x8f, 0xa6, 0x73, - 0xf7, 0x57, 0x31, 0x1b, 0xbe, 0xbc, 0xe4, 0x2f, 0xdb, 0xf8, 0xba, 0xd3, - 0x5b, 0xe0, 0xb4, 0xe7, 0xe6, 0x79, 0x62, 0x0e, 0x0c, 0xa2, 0xd7, 0x6a, - 0x63, 0x73, 0x31, 0xb5, 0xf5, 0xa8, 0x48, 0xa4, 0x3b, 0x08, 0x2d, 0xa2, - 0x5d, 0x90, 0xd7, 0xb4, 0x7c, 0x25, 0x4f, 0x11, 0x56, 0x30, 0xc4, 0xb6, - 0x44, 0x9d, 0x7b, 0x2c, 0x9d, 0xe5, 0x5e, 0xe6, 0xef, 0x0c, 0x61, 0xaa, - 0xbf, 0xe4, 0x2a, 0x1b, 0xee, 0x84, 0x9e, 0xb8, 0x83, 0x7d, 0xc1, 0x43, - 0xce, 0x44, 0xa7, 0x13, 0x70, 0x0d, 0x91, 0x1f, 0xf4, 0xc8, 0x13, 0xad, - 0x83, 0x60, 0xd9, 0xd8, 0x72, 0xa8, 0x73, 0x24, 0x1e, 0xb5, 0xac, 0x22, - 0x0e, 0xca, 0x17, 0x89, 0x62, 0x58, 0x44, 0x1b, 0xab, 0x89, 0x25, 0x01, - 0x00, 0x0f, 0xcd, 0xc4, 0x1b, 0x62, 0xdb, 0x51, 0xb4, 0xd3, 0x0f, 0x51, - 0x2a, 0x9b, 0xf4, 0xbc, 0x73, 0xfc, 0x76, 0xce, 0x36, 0xa4, 0xcd, 0xd9, - 0xd8, 0x2c, 0xea, 0xae, 0x9b, 0xf5, 0x2a, 0xb2, 0x90, 0xd1, 0x4d, 0x75, - 0x18, 0x8a, 0x3f, 0x8a, 0x41, 0x90, 0x23, 0x7d, 0x5b, 0x4b, 0xfe, 0xa4, - 0x03, 0x58, 0x9b, 0x46, 0xb2, 0xc3, 0x60, 0x60, 0x83, 0xf8, 0x7d, 0x50, - 0x41, 0xce, 0xc2, 0xa1, 0x90, 0xc3, 0xbb, 0xef, 0x02, 0x2f, 0xd2, 0x15, - 0x54, 0xee, 0x44, 0x15, 0xd9, 0x0a, 0xae, 0xa7, 0x8a, 0x33, 0xed, 0xb1, - 0x2d, 0x76, 0x36, 0x26, 0xdc, 0x04, 0xeb, 0x9f, 0xf7, 0x61, 0x1f, 0x15, - 0xdc, 0x87, 0x6f, 0xee, 0x46, 0x96, 0x28, 0xad, 0xa1, 0x26, 0x7d, 0x0a, - 0x09, 0xa7, 0x2e, 0x04, 0xa3, 0x8d, 0xbc, 0xf8, 0xbc, 0x04, 0x30, 0x01, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 25:0c:e8:e0:30:61:2e:9f:2b:89:f7:05:4d:7c:f8:fd - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority - Validity - Not Before: Nov 8 00:00:00 2006 GMT - Not After : Nov 7 23:59:59 2021 GMT - Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:af:24:08:08:29:7a:35:9e:60:0c:aa:e7:4b:3b: - 4e:dc:7c:bc:3c:45:1c:bb:2b:e0:fe:29:02:f9:57: - 08:a3:64:85:15:27:f5:f1:ad:c8:31:89:5d:22:e8: - 2a:aa:a6:42:b3:8f:f8:b9:55:b7:b1:b7:4b:b3:fe: - 8f:7e:07:57:ec:ef:43:db:66:62:15:61:cf:60:0d: - a4:d8:de:f8:e0:c3:62:08:3d:54:13:eb:49:ca:59: - 54:85:26:e5:2b:8f:1b:9f:eb:f5:a1:91:c2:33:49: - d8:43:63:6a:52:4b:d2:8f:e8:70:51:4d:d1:89:69: - 7b:c7:70:f6:b3:dc:12:74:db:7b:5d:4b:56:d3:96: - bf:15:77:a1:b0:f4:a2:25:f2:af:1c:92:67:18:e5: - f4:06:04:ef:90:b9:e4:00:e4:dd:3a:b5:19:ff:02: - ba:f4:3c:ee:e0:8b:eb:37:8b:ec:f4:d7:ac:f2:f6: - f0:3d:af:dd:75:91:33:19:1d:1c:40:cb:74:24:19: - 21:93:d9:14:fe:ac:2a:52:c7:8f:d5:04:49:e4:8d: - 63:47:88:3c:69:83:cb:fe:47:bd:2b:7e:4f:c5:95: - ae:0e:9d:d4:d1:43:c0:67:73:e3:14:08:7e:e5:3f: - 9f:73:b8:33:0a:cf:5d:3f:34:87:96:8a:ee:53:e8: - 25:15 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.verisign.com/pca3.crl - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://www.verisign.com/cps - - X509v3 Subject Key Identifier: - 7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33 - 1.3.6.1.5.5.7.1.12: - 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif - Authority Information Access: - OCSP - URI:http://ocsp.verisign.com - - X509v3 Extended Key Usage: - TLS Web Server Authentication, TLS Web Client Authentication, Code Signing, Netscape Server Gated Crypto, 2.16.840.1.113733.1.8.1 - Signature Algorithm: sha1WithRSAEncryption - 13:02:dd:f8:e8:86:00:f2:5a:f8:f8:20:0c:59:88:62:07:ce: - ce:f7:4e:f9:bb:59:a1:98:e5:e1:38:dd:4e:bc:66:18:d3:ad: - eb:18:f2:0d:c9:6d:3e:4a:94:20:c3:3c:ba:bd:65:54:c6:af: - 44:b3:10:ad:2c:6b:3e:ab:d7:07:b6:b8:81:63:c5:f9:5e:2e: - e5:2a:67:ce:cd:33:0c:2a:d7:89:56:03:23:1f:b3:be:e8:3a: - 08:59:b4:ec:45:35:f7:8a:5b:ff:66:cf:50:af:c6:6d:57:8d: - 19:78:b7:b9:a2:d1:57:ea:1f:9a:4b:af:ba:c9:8e:12:7e:c6: - bd:ff ------BEGIN CERTIFICATE----- -MIIE0DCCBDmgAwIBAgIQJQzo4DBhLp8rifcFTXz4/TANBgkqhkiG9w0BAQUFADBf -MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsT -LkNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw -HhcNMDYxMTA4MDAwMDAwWhcNMjExMTA3MjM1OTU5WjCByjELMAkGA1UEBhMCVVMx -FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz -dCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZv -ciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAz -IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8 -RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbext0uz/o9+B1fs70Pb -ZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhDY2pSS9KP6HBR -TdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/ -Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNH -iDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMB -AAGjggGbMIIBlzAPBgNVHRMBAf8EBTADAQH/MDEGA1UdHwQqMCgwJqAkoCKGIGh0 -dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMuY3JsMA4GA1UdDwEB/wQEAwIBBjA9 -BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVy -aXNpZ24uY29tL2NwczAdBgNVHQ4EFgQUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwbQYI -KwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQU -j+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24uY29t -L3ZzbG9nby5naWYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v -b2NzcC52ZXJpc2lnbi5jb20wPgYDVR0lBDcwNQYIKwYBBQUHAwEGCCsGAQUFBwMC -BggrBgEFBQcDAwYJYIZIAYb4QgQBBgpghkgBhvhFAQgBMA0GCSqGSIb3DQEBBQUA -A4GBABMC3fjohgDyWvj4IAxZiGIHzs73Tvm7WaGY5eE43U68ZhjTresY8g3JbT5K -lCDDPLq9ZVTGr0SzEK0saz6r1we2uIFjxfleLuUqZ87NMwwq14lWAyMfs77oOghZ -tOxFNfeKW/9mz1Cvxm1XjRl4t7mi0VfqH5pLr7rJjhJ+xr3/ ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert36[] = { - 0x30, 0x82, 0x04, 0xd0, 0x30, 0x82, 0x04, 0x39, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x25, 0x0c, 0xe8, 0xe0, 0x30, 0x61, 0x2e, 0x9f, 0x2b, - 0x89, 0xf7, 0x05, 0x4d, 0x7c, 0xf8, 0xfd, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5f, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, - 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, - 0x63, 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, - 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, - 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x30, 0x38, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31, 0x30, 0x37, - 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xca, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, - 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56, - 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, - 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3a, 0x30, - 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, 0x63, 0x29, 0x20, - 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, - 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, - 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, - 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x45, 0x30, - 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56, 0x65, 0x72, 0x69, - 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, - 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, - 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 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, 0xaf, 0x24, 0x08, 0x08, 0x29, 0x7a, 0x35, - 0x9e, 0x60, 0x0c, 0xaa, 0xe7, 0x4b, 0x3b, 0x4e, 0xdc, 0x7c, 0xbc, 0x3c, - 0x45, 0x1c, 0xbb, 0x2b, 0xe0, 0xfe, 0x29, 0x02, 0xf9, 0x57, 0x08, 0xa3, - 0x64, 0x85, 0x15, 0x27, 0xf5, 0xf1, 0xad, 0xc8, 0x31, 0x89, 0x5d, 0x22, - 0xe8, 0x2a, 0xaa, 0xa6, 0x42, 0xb3, 0x8f, 0xf8, 0xb9, 0x55, 0xb7, 0xb1, - 0xb7, 0x4b, 0xb3, 0xfe, 0x8f, 0x7e, 0x07, 0x57, 0xec, 0xef, 0x43, 0xdb, - 0x66, 0x62, 0x15, 0x61, 0xcf, 0x60, 0x0d, 0xa4, 0xd8, 0xde, 0xf8, 0xe0, - 0xc3, 0x62, 0x08, 0x3d, 0x54, 0x13, 0xeb, 0x49, 0xca, 0x59, 0x54, 0x85, - 0x26, 0xe5, 0x2b, 0x8f, 0x1b, 0x9f, 0xeb, 0xf5, 0xa1, 0x91, 0xc2, 0x33, - 0x49, 0xd8, 0x43, 0x63, 0x6a, 0x52, 0x4b, 0xd2, 0x8f, 0xe8, 0x70, 0x51, - 0x4d, 0xd1, 0x89, 0x69, 0x7b, 0xc7, 0x70, 0xf6, 0xb3, 0xdc, 0x12, 0x74, - 0xdb, 0x7b, 0x5d, 0x4b, 0x56, 0xd3, 0x96, 0xbf, 0x15, 0x77, 0xa1, 0xb0, - 0xf4, 0xa2, 0x25, 0xf2, 0xaf, 0x1c, 0x92, 0x67, 0x18, 0xe5, 0xf4, 0x06, - 0x04, 0xef, 0x90, 0xb9, 0xe4, 0x00, 0xe4, 0xdd, 0x3a, 0xb5, 0x19, 0xff, - 0x02, 0xba, 0xf4, 0x3c, 0xee, 0xe0, 0x8b, 0xeb, 0x37, 0x8b, 0xec, 0xf4, - 0xd7, 0xac, 0xf2, 0xf6, 0xf0, 0x3d, 0xaf, 0xdd, 0x75, 0x91, 0x33, 0x19, - 0x1d, 0x1c, 0x40, 0xcb, 0x74, 0x24, 0x19, 0x21, 0x93, 0xd9, 0x14, 0xfe, - 0xac, 0x2a, 0x52, 0xc7, 0x8f, 0xd5, 0x04, 0x49, 0xe4, 0x8d, 0x63, 0x47, - 0x88, 0x3c, 0x69, 0x83, 0xcb, 0xfe, 0x47, 0xbd, 0x2b, 0x7e, 0x4f, 0xc5, - 0x95, 0xae, 0x0e, 0x9d, 0xd4, 0xd1, 0x43, 0xc0, 0x67, 0x73, 0xe3, 0x14, - 0x08, 0x7e, 0xe5, 0x3f, 0x9f, 0x73, 0xb8, 0x33, 0x0a, 0xcf, 0x5d, 0x3f, - 0x34, 0x87, 0x96, 0x8a, 0xee, 0x53, 0xe8, 0x25, 0x15, 0x02, 0x03, 0x01, - 0x00, 0x01, 0xa3, 0x82, 0x01, 0x9b, 0x30, 0x82, 0x01, 0x97, 0x30, 0x0f, - 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, - 0x01, 0x01, 0xff, 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2a, - 0x30, 0x28, 0x30, 0x26, 0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, - 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, - 0x61, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, - 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3d, - 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06, - 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, - 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, - 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, - 0x73, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, - 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3, - 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x6d, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f, - 0xa1, 0x5d, 0xa0, 0x5b, 0x30, 0x59, 0x30, 0x57, 0x30, 0x55, 0x16, 0x09, - 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x30, 0x21, 0x30, - 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, - 0x8f, 0xe5, 0xd3, 0x1a, 0x86, 0xac, 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80, - 0x6a, 0xd4, 0x48, 0x18, 0x2c, 0x7b, 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, - 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x76, 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30, - 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, - 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, - 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x3e, 0x06, 0x03, 0x55, 0x1d, 0x25, - 0x04, 0x37, 0x30, 0x35, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, - 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, 0x06, 0x09, - 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01, 0x06, 0x0a, 0x60, - 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x08, 0x01, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, - 0x03, 0x81, 0x81, 0x00, 0x13, 0x02, 0xdd, 0xf8, 0xe8, 0x86, 0x00, 0xf2, - 0x5a, 0xf8, 0xf8, 0x20, 0x0c, 0x59, 0x88, 0x62, 0x07, 0xce, 0xce, 0xf7, - 0x4e, 0xf9, 0xbb, 0x59, 0xa1, 0x98, 0xe5, 0xe1, 0x38, 0xdd, 0x4e, 0xbc, - 0x66, 0x18, 0xd3, 0xad, 0xeb, 0x18, 0xf2, 0x0d, 0xc9, 0x6d, 0x3e, 0x4a, - 0x94, 0x20, 0xc3, 0x3c, 0xba, 0xbd, 0x65, 0x54, 0xc6, 0xaf, 0x44, 0xb3, - 0x10, 0xad, 0x2c, 0x6b, 0x3e, 0xab, 0xd7, 0x07, 0xb6, 0xb8, 0x81, 0x63, - 0xc5, 0xf9, 0x5e, 0x2e, 0xe5, 0x2a, 0x67, 0xce, 0xcd, 0x33, 0x0c, 0x2a, - 0xd7, 0x89, 0x56, 0x03, 0x23, 0x1f, 0xb3, 0xbe, 0xe8, 0x3a, 0x08, 0x59, - 0xb4, 0xec, 0x45, 0x35, 0xf7, 0x8a, 0x5b, 0xff, 0x66, 0xcf, 0x50, 0xaf, - 0xc6, 0x6d, 0x57, 0x8d, 0x19, 0x78, 0xb7, 0xb9, 0xa2, 0xd1, 0x57, 0xea, - 0x1f, 0x9a, 0x4b, 0xaf, 0xba, 0xc9, 0x8e, 0x12, 0x7e, 0xc6, 0xbd, 0xff, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 2c:69:e1:2f:6a:67:0b:d9:9d:d2:0f:91:9e:f0:9e:51 - Signature Algorithm: sha256WithRSAEncryption - Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - Validity - Not Before: Jun 10 00:00:00 2014 GMT - Not After : Jun 9 23:59:59 2024 GMT - Subject: C=US, O=thawte, Inc., OU=Domain Validated SSL, CN=thawte DV SSL CA - G2 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:ea:94:07:85:c8:41:2c:f6:83:12:6c:92:5f:ab: - 1f:00:d4:96:6f:74:cd:2e:11:e9:6c:0f:39:01:b9: - 48:90:40:39:4d:c4:a2:c8:79:6a:a5:9a:bd:91:44: - 65:77:54:ad:ff:25:5f:ee:42:fb:b3:02:0f:ea:5d: - 7a:dd:1a:54:9e:d7:73:42:9b:cc:79:5f:c5:4d:f4: - b7:0b:18:39:20:7a:dd:50:01:5d:34:45:5f:4c:11: - 0e:f5:87:26:26:b4:b0:f3:7e:71:a0:31:71:50:89: - 68:5a:63:8a:14:62:e5:8c:3a:16:55:0d:3e:eb:aa: - 80:1d:71:7a:e3:87:07:ab:bd:a2:74:cd:da:08:01: - 9d:1b:cc:27:88:8c:47:d4:69:25:42:d6:bb:50:6d: - 85:50:d0:48:82:0d:08:9f:e9:23:e3:42:c6:3c:98: - b8:bb:6e:c5:70:13:df:19:1d:01:fd:d2:b5:4e:e6: - 62:f4:07:fa:6b:7d:11:77:c4:62:4f:40:4e:a5:78: - 97:ab:2c:4d:0c:a7:7c:c3:c4:50:32:9f:d0:70:9b: - 0f:ff:ff:75:59:34:85:ad:49:d5:35:ee:4f:5b:d4: - d4:36:95:a0:7e:e8:c5:a1:1c:bd:13:4e:7d:ee:63: - 6a:96:19:99:c8:a7:2a:00:e6:51:8d:46:eb:30:58: - e8:2d - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Certificate Policies: - Policy: 2.16.840.1.113733.1.7.54 - CPS: https://www.thawte.com/cps - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - Authority Information Access: - OCSP - URI:http://t.symcd.com - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://t.symcb.com/ThawtePCA.crl - - X509v3 Subject Alternative Name: - DirName:/CN=SymantecPKI-1-698 - X509v3 Subject Key Identifier: - 9F:B8:C1:A9:6C:F2:F5:C0:22:2A:94:ED:5C:99:AC:D4:EC:D7:C6:07 - X509v3 Authority Key Identifier: - keyid:7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50 - - Signature Algorithm: sha256WithRSAEncryption - 53:54:f2:47:a8:02:d7:ef:aa:35:78:be:4a:08:0d:90:18:4b: - 6d:9e:2a:53:2b:e9:54:17:77:74:29:7e:d0:37:07:05:b8:e4: - fa:b8:b4:63:98:44:dc:c6:4f:81:06:8c:3a:be:c7:30:57:c6: - 70:fc:d6:93:19:9f:c3:55:d7:3e:1f:72:8a:9d:30:5a:35:97: - 32:cb:63:e4:c6:72:df:fb:68:ca:69:2f:db:cd:50:38:3e:2b: - bb:ab:3b:82:c7:fd:4b:9b:bd:7c:41:98:ef:01:53:d8:35:8f: - 25:c9:03:06:e6:9c:57:c1:51:0f:9e:f6:7d:93:4d:f8:76:c8: - 3a:6b:f4:c4:8f:33:32:7f:9d:21:84:34:d9:a7:f9:92:fa:41: - 91:61:84:05:9d:a3:79:46:ce:67:e7:81:f2:5e:ac:4c:bc:a8: - ab:6a:6d:15:e2:9c:4e:5a:d9:63:80:bc:f7:42:eb:9a:44:c6: - 8c:6b:06:36:b4:8b:32:89:de:c2:f1:a8:26:aa:a9:ac:ff:ea: - 71:a6:e7:8c:41:fa:17:35:bb:b3:87:31:a9:93:c2:c8:58:e1: - 0a:4e:95:83:9c:b9:ed:3b:a5:ef:08:e0:74:f9:c3:1b:e6:07: - a3:ee:07:d7:42:22:79:21:a0:a1:d4:1d:26:d3:d0:d6:a6:5d: - 2b:41:c0:79 ------BEGIN CERTIFICATE----- -MIIE0jCCA7qgAwIBAgIQLGnhL2pnC9md0g+RnvCeUTANBgkqhkiG9w0BAQsFADCB -qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf -Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw -MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV -BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTQwNjEwMDAwMDAwWhcNMjQw -NjA5MjM1OTU5WjBjMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMu -MR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEeMBwGA1UEAxMVdGhhd3Rl -IERWIFNTTCBDQSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA -6pQHhchBLPaDEmySX6sfANSWb3TNLhHpbA85AblIkEA5TcSiyHlqpZq9kURld1St -/yVf7kL7swIP6l163RpUntdzQpvMeV/FTfS3Cxg5IHrdUAFdNEVfTBEO9YcmJrSw -835xoDFxUIloWmOKFGLljDoWVQ0+66qAHXF644cHq72idM3aCAGdG8wniIxH1Gkl -Qta7UG2FUNBIgg0In+kj40LGPJi4u27FcBPfGR0B/dK1TuZi9Af6a30Rd8RiT0BO -pXiXqyxNDKd8w8RQMp/QcJsP//91WTSFrUnVNe5PW9TUNpWgfujFoRy9E0597mNq -lhmZyKcqAOZRjUbrMFjoLQIDAQABo4IBOTCCATUwEgYDVR0TAQH/BAgwBgEB/wIB -ADBBBgNVHSAEOjA4MDYGCmCGSAGG+EUBBzYwKDAmBggrBgEFBQcCARYaaHR0cHM6 -Ly93d3cudGhhd3RlLmNvbS9jcHMwDgYDVR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEB -BCIwIDAeBggrBgEFBQcwAYYSaHR0cDovL3Quc3ltY2QuY29tMDEGA1UdHwQqMCgw -JqAkoCKGIGh0dHA6Ly90LnN5bWNiLmNvbS9UaGF3dGVQQ0EuY3JsMCkGA1UdEQQi -MCCkHjAcMRowGAYDVQQDExFTeW1hbnRlY1BLSS0xLTY5ODAdBgNVHQ4EFgQUn7jB -qWzy9cAiKpTtXJms1OzXxgcwHwYDVR0jBBgwFoAUe1tFz6/Oy3r9MZIaarbzRutX -SFAwDQYJKoZIhvcNAQELBQADggEBAFNU8keoAtfvqjV4vkoIDZAYS22eKlMr6VQX -d3QpftA3BwW45Pq4tGOYRNzGT4EGjDq+xzBXxnD81pMZn8NV1z4fcoqdMFo1lzLL -Y+TGct/7aMppL9vNUDg+K7urO4LH/UubvXxBmO8BU9g1jyXJAwbmnFfBUQ+e9n2T -Tfh2yDpr9MSPMzJ/nSGENNmn+ZL6QZFhhAWdo3lGzmfngfJerEy8qKtqbRXinE5a -2WOAvPdC65pExoxrBja0izKJ3sLxqCaqqaz/6nGm54xB+hc1u7OHMamTwshY4QpO -lYOcue07pe8I4HT5wxvmB6PuB9dCInkhoKHUHSbT0NamXStBwHk= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert37[] = { - 0x30, 0x82, 0x04, 0xd2, 0x30, 0x82, 0x03, 0xba, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x2c, 0x69, 0xe1, 0x2f, 0x6a, 0x67, 0x0b, 0xd9, 0x9d, - 0xd2, 0x0f, 0x91, 0x9e, 0xf0, 0x9e, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, - 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, - 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44, - 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06, - 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, - 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, - 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, - 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, - 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x36, 0x31, 0x30, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, - 0x36, 0x30, 0x39, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x63, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, - 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x14, 0x44, - 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, - 0x74, 0x65, 0x64, 0x20, 0x53, 0x53, 0x4c, 0x31, 0x1e, 0x30, 0x1c, 0x06, - 0x03, 0x55, 0x04, 0x03, 0x13, 0x15, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, - 0x20, 0x44, 0x56, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, - 0x20, 0x47, 0x32, 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, - 0xea, 0x94, 0x07, 0x85, 0xc8, 0x41, 0x2c, 0xf6, 0x83, 0x12, 0x6c, 0x92, - 0x5f, 0xab, 0x1f, 0x00, 0xd4, 0x96, 0x6f, 0x74, 0xcd, 0x2e, 0x11, 0xe9, - 0x6c, 0x0f, 0x39, 0x01, 0xb9, 0x48, 0x90, 0x40, 0x39, 0x4d, 0xc4, 0xa2, - 0xc8, 0x79, 0x6a, 0xa5, 0x9a, 0xbd, 0x91, 0x44, 0x65, 0x77, 0x54, 0xad, - 0xff, 0x25, 0x5f, 0xee, 0x42, 0xfb, 0xb3, 0x02, 0x0f, 0xea, 0x5d, 0x7a, - 0xdd, 0x1a, 0x54, 0x9e, 0xd7, 0x73, 0x42, 0x9b, 0xcc, 0x79, 0x5f, 0xc5, - 0x4d, 0xf4, 0xb7, 0x0b, 0x18, 0x39, 0x20, 0x7a, 0xdd, 0x50, 0x01, 0x5d, - 0x34, 0x45, 0x5f, 0x4c, 0x11, 0x0e, 0xf5, 0x87, 0x26, 0x26, 0xb4, 0xb0, - 0xf3, 0x7e, 0x71, 0xa0, 0x31, 0x71, 0x50, 0x89, 0x68, 0x5a, 0x63, 0x8a, - 0x14, 0x62, 0xe5, 0x8c, 0x3a, 0x16, 0x55, 0x0d, 0x3e, 0xeb, 0xaa, 0x80, - 0x1d, 0x71, 0x7a, 0xe3, 0x87, 0x07, 0xab, 0xbd, 0xa2, 0x74, 0xcd, 0xda, - 0x08, 0x01, 0x9d, 0x1b, 0xcc, 0x27, 0x88, 0x8c, 0x47, 0xd4, 0x69, 0x25, - 0x42, 0xd6, 0xbb, 0x50, 0x6d, 0x85, 0x50, 0xd0, 0x48, 0x82, 0x0d, 0x08, - 0x9f, 0xe9, 0x23, 0xe3, 0x42, 0xc6, 0x3c, 0x98, 0xb8, 0xbb, 0x6e, 0xc5, - 0x70, 0x13, 0xdf, 0x19, 0x1d, 0x01, 0xfd, 0xd2, 0xb5, 0x4e, 0xe6, 0x62, - 0xf4, 0x07, 0xfa, 0x6b, 0x7d, 0x11, 0x77, 0xc4, 0x62, 0x4f, 0x40, 0x4e, - 0xa5, 0x78, 0x97, 0xab, 0x2c, 0x4d, 0x0c, 0xa7, 0x7c, 0xc3, 0xc4, 0x50, - 0x32, 0x9f, 0xd0, 0x70, 0x9b, 0x0f, 0xff, 0xff, 0x75, 0x59, 0x34, 0x85, - 0xad, 0x49, 0xd5, 0x35, 0xee, 0x4f, 0x5b, 0xd4, 0xd4, 0x36, 0x95, 0xa0, - 0x7e, 0xe8, 0xc5, 0xa1, 0x1c, 0xbd, 0x13, 0x4e, 0x7d, 0xee, 0x63, 0x6a, - 0x96, 0x19, 0x99, 0xc8, 0xa7, 0x2a, 0x00, 0xe6, 0x51, 0x8d, 0x46, 0xeb, - 0x30, 0x58, 0xe8, 0x2d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, - 0x39, 0x30, 0x82, 0x01, 0x35, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, - 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, - 0x00, 0x30, 0x41, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3a, 0x30, 0x38, - 0x30, 0x36, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, - 0x07, 0x36, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, - 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0e, 0x06, 0x03, - 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, - 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, - 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x74, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d, - 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2a, 0x30, 0x28, 0x30, - 0x26, 0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x74, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, 0x43, 0x41, 0x2e, - 0x63, 0x72, 0x6c, 0x30, 0x29, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x22, - 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, - 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, 0x36, 0x39, 0x38, 0x30, 0x1d, - 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x9f, 0xb8, 0xc1, - 0xa9, 0x6c, 0xf2, 0xf5, 0xc0, 0x22, 0x2a, 0x94, 0xed, 0x5c, 0x99, 0xac, - 0xd4, 0xec, 0xd7, 0xc6, 0x07, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, - 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7b, 0x5b, 0x45, 0xcf, 0xaf, 0xce, - 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a, 0x6a, 0xb6, 0xf3, 0x46, 0xeb, 0x57, - 0x48, 0x50, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x53, 0x54, - 0xf2, 0x47, 0xa8, 0x02, 0xd7, 0xef, 0xaa, 0x35, 0x78, 0xbe, 0x4a, 0x08, - 0x0d, 0x90, 0x18, 0x4b, 0x6d, 0x9e, 0x2a, 0x53, 0x2b, 0xe9, 0x54, 0x17, - 0x77, 0x74, 0x29, 0x7e, 0xd0, 0x37, 0x07, 0x05, 0xb8, 0xe4, 0xfa, 0xb8, - 0xb4, 0x63, 0x98, 0x44, 0xdc, 0xc6, 0x4f, 0x81, 0x06, 0x8c, 0x3a, 0xbe, - 0xc7, 0x30, 0x57, 0xc6, 0x70, 0xfc, 0xd6, 0x93, 0x19, 0x9f, 0xc3, 0x55, - 0xd7, 0x3e, 0x1f, 0x72, 0x8a, 0x9d, 0x30, 0x5a, 0x35, 0x97, 0x32, 0xcb, - 0x63, 0xe4, 0xc6, 0x72, 0xdf, 0xfb, 0x68, 0xca, 0x69, 0x2f, 0xdb, 0xcd, - 0x50, 0x38, 0x3e, 0x2b, 0xbb, 0xab, 0x3b, 0x82, 0xc7, 0xfd, 0x4b, 0x9b, - 0xbd, 0x7c, 0x41, 0x98, 0xef, 0x01, 0x53, 0xd8, 0x35, 0x8f, 0x25, 0xc9, - 0x03, 0x06, 0xe6, 0x9c, 0x57, 0xc1, 0x51, 0x0f, 0x9e, 0xf6, 0x7d, 0x93, - 0x4d, 0xf8, 0x76, 0xc8, 0x3a, 0x6b, 0xf4, 0xc4, 0x8f, 0x33, 0x32, 0x7f, - 0x9d, 0x21, 0x84, 0x34, 0xd9, 0xa7, 0xf9, 0x92, 0xfa, 0x41, 0x91, 0x61, - 0x84, 0x05, 0x9d, 0xa3, 0x79, 0x46, 0xce, 0x67, 0xe7, 0x81, 0xf2, 0x5e, - 0xac, 0x4c, 0xbc, 0xa8, 0xab, 0x6a, 0x6d, 0x15, 0xe2, 0x9c, 0x4e, 0x5a, - 0xd9, 0x63, 0x80, 0xbc, 0xf7, 0x42, 0xeb, 0x9a, 0x44, 0xc6, 0x8c, 0x6b, - 0x06, 0x36, 0xb4, 0x8b, 0x32, 0x89, 0xde, 0xc2, 0xf1, 0xa8, 0x26, 0xaa, - 0xa9, 0xac, 0xff, 0xea, 0x71, 0xa6, 0xe7, 0x8c, 0x41, 0xfa, 0x17, 0x35, - 0xbb, 0xb3, 0x87, 0x31, 0xa9, 0x93, 0xc2, 0xc8, 0x58, 0xe1, 0x0a, 0x4e, - 0x95, 0x83, 0x9c, 0xb9, 0xed, 0x3b, 0xa5, 0xef, 0x08, 0xe0, 0x74, 0xf9, - 0xc3, 0x1b, 0xe6, 0x07, 0xa3, 0xee, 0x07, 0xd7, 0x42, 0x22, 0x79, 0x21, - 0xa0, 0xa1, 0xd4, 0x1d, 0x26, 0xd3, 0xd0, 0xd6, 0xa6, 0x5d, 0x2b, 0x41, - 0xc0, 0x79, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 769 (0x301) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority - Validity - Not Before: Nov 16 01:54:37 2006 GMT - Not After : Nov 16 01:54:37 2026 GMT - Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., OU=http://certificates.godaddy.com/repository, CN=Go Daddy Secure Certification Authority/serialNumber=07969287 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:c4:2d:d5:15:8c:9c:26:4c:ec:32:35:eb:5f:b8: - 59:01:5a:a6:61:81:59:3b:70:63:ab:e3:dc:3d:c7: - 2a:b8:c9:33:d3:79:e4:3a:ed:3c:30:23:84:8e:b3: - 30:14:b6:b2:87:c3:3d:95:54:04:9e:df:99:dd:0b: - 25:1e:21:de:65:29:7e:35:a8:a9:54:eb:f6:f7:32: - 39:d4:26:55:95:ad:ef:fb:fe:58:86:d7:9e:f4:00: - 8d:8c:2a:0c:bd:42:04:ce:a7:3f:04:f6:ee:80:f2: - aa:ef:52:a1:69:66:da:be:1a:ad:5d:da:2c:66:ea: - 1a:6b:bb:e5:1a:51:4a:00:2f:48:c7:98:75:d8:b9: - 29:c8:ee:f8:66:6d:0a:9c:b3:f3:fc:78:7c:a2:f8: - a3:f2:b5:c3:f3:b9:7a:91:c1:a7:e6:25:2e:9c:a8: - ed:12:65:6e:6a:f6:12:44:53:70:30:95:c3:9c:2b: - 58:2b:3d:08:74:4a:f2:be:51:b0:bf:87:d0:4c:27: - 58:6b:b5:35:c5:9d:af:17:31:f8:0b:8f:ee:ad:81: - 36:05:89:08:98:cf:3a:af:25:87:c0:49:ea:a7:fd: - 67:f7:45:8e:97:cc:14:39:e2:36:85:b5:7e:1a:37: - fd:16:f6:71:11:9a:74:30:16:fe:13:94:a3:3f:84: - 0d:4f - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Subject Key Identifier: - FD:AC:61:32:93:6C:45:D6:E2:EE:85:5F:9A:BA:E7:76:99:68:CC:E7 - X509v3 Authority Key Identifier: - keyid:D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3 - - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - Authority Information Access: - OCSP - URI:http://ocsp.godaddy.com - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://certificates.godaddy.com/repository/gdroot.crl - - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: http://certificates.godaddy.com/repository - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - Signature Algorithm: sha1WithRSAEncryption - d2:86:c0:ec:bd:f9:a1:b6:67:ee:66:0b:a2:06:3a:04:50:8e: - 15:72:ac:4a:74:95:53:cb:37:cb:44:49:ef:07:90:6b:33:d9: - 96:f0:94:56:a5:13:30:05:3c:85:32:21:7b:c9:c7:0a:a8:24: - a4:90:de:46:d3:25:23:14:03:67:c2:10:d6:6f:0f:5d:7b:7a: - cc:9f:c5:58:2a:c1:c4:9e:21:a8:5a:f3:ac:a4:46:f3:9e:e4: - 63:cb:2f:90:a4:29:29:01:d9:72:2c:29:df:37:01:27:bc:4f: - ee:68:d3:21:8f:c0:b3:e4:f5:09:ed:d2:10:aa:53:b4:be:f0: - cc:59:0b:d6:3b:96:1c:95:24:49:df:ce:ec:fd:a7:48:91:14: - 45:0e:3a:36:6f:da:45:b3:45:a2:41:c9:d4:d7:44:4e:3e:b9: - 74:76:d5:a2:13:55:2c:c6:87:a3:b5:99:ac:06:84:87:7f:75: - 06:fc:bf:14:4c:0e:cc:6e:c4:df:3d:b7:12:71:f4:e8:f1:51: - 40:22:28:49:e0:1d:4b:87:a8:34:cc:06:a2:dd:12:5a:d1:86: - 36:64:03:35:6f:6f:77:6e:eb:f2:85:50:98:5e:ab:03:53:ad: - 91:23:63:1f:16:9c:cd:b9:b2:05:63:3a:e1:f4:68:1b:17:05: - 35:95:53:ee ------BEGIN CERTIFICATE----- -MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx -ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g -RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYw -MTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMH -QXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5j -b20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j -b20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmlj -YXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcN -AQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3H -KrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQm -VZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpR -SgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRT -cDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ -6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEu -MB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDS -kdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEB -BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0f -BD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv -c2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUH -AgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAO -BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IG -OgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMU -A2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o -0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTX -RE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuH -qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV -U+4= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert38[] = { - 0x30, 0x82, 0x04, 0xde, 0x30, 0x82, 0x03, 0xc6, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x02, 0x03, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x63, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x54, 0x68, - 0x65, 0x20, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x31, - 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x28, 0x47, 0x6f, 0x20, - 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, - 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, - 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x31, 0x36, 0x30, - 0x31, 0x35, 0x34, 0x33, 0x37, 0x5a, 0x17, 0x0d, 0x32, 0x36, 0x31, 0x31, - 0x31, 0x36, 0x30, 0x31, 0x35, 0x34, 0x33, 0x37, 0x5a, 0x30, 0x81, 0xca, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, - 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, - 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, - 0x64, 0x61, 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, - 0x6f, 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x33, 0x30, 0x31, - 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x31, 0x30, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x27, - 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x53, 0x65, 0x63, - 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x74, 0x79, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x05, - 0x13, 0x08, 0x30, 0x37, 0x39, 0x36, 0x39, 0x32, 0x38, 0x37, 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, 0xc4, 0x2d, 0xd5, 0x15, 0x8c, - 0x9c, 0x26, 0x4c, 0xec, 0x32, 0x35, 0xeb, 0x5f, 0xb8, 0x59, 0x01, 0x5a, - 0xa6, 0x61, 0x81, 0x59, 0x3b, 0x70, 0x63, 0xab, 0xe3, 0xdc, 0x3d, 0xc7, - 0x2a, 0xb8, 0xc9, 0x33, 0xd3, 0x79, 0xe4, 0x3a, 0xed, 0x3c, 0x30, 0x23, - 0x84, 0x8e, 0xb3, 0x30, 0x14, 0xb6, 0xb2, 0x87, 0xc3, 0x3d, 0x95, 0x54, - 0x04, 0x9e, 0xdf, 0x99, 0xdd, 0x0b, 0x25, 0x1e, 0x21, 0xde, 0x65, 0x29, - 0x7e, 0x35, 0xa8, 0xa9, 0x54, 0xeb, 0xf6, 0xf7, 0x32, 0x39, 0xd4, 0x26, - 0x55, 0x95, 0xad, 0xef, 0xfb, 0xfe, 0x58, 0x86, 0xd7, 0x9e, 0xf4, 0x00, - 0x8d, 0x8c, 0x2a, 0x0c, 0xbd, 0x42, 0x04, 0xce, 0xa7, 0x3f, 0x04, 0xf6, - 0xee, 0x80, 0xf2, 0xaa, 0xef, 0x52, 0xa1, 0x69, 0x66, 0xda, 0xbe, 0x1a, - 0xad, 0x5d, 0xda, 0x2c, 0x66, 0xea, 0x1a, 0x6b, 0xbb, 0xe5, 0x1a, 0x51, - 0x4a, 0x00, 0x2f, 0x48, 0xc7, 0x98, 0x75, 0xd8, 0xb9, 0x29, 0xc8, 0xee, - 0xf8, 0x66, 0x6d, 0x0a, 0x9c, 0xb3, 0xf3, 0xfc, 0x78, 0x7c, 0xa2, 0xf8, - 0xa3, 0xf2, 0xb5, 0xc3, 0xf3, 0xb9, 0x7a, 0x91, 0xc1, 0xa7, 0xe6, 0x25, - 0x2e, 0x9c, 0xa8, 0xed, 0x12, 0x65, 0x6e, 0x6a, 0xf6, 0x12, 0x44, 0x53, - 0x70, 0x30, 0x95, 0xc3, 0x9c, 0x2b, 0x58, 0x2b, 0x3d, 0x08, 0x74, 0x4a, - 0xf2, 0xbe, 0x51, 0xb0, 0xbf, 0x87, 0xd0, 0x4c, 0x27, 0x58, 0x6b, 0xb5, - 0x35, 0xc5, 0x9d, 0xaf, 0x17, 0x31, 0xf8, 0x0b, 0x8f, 0xee, 0xad, 0x81, - 0x36, 0x05, 0x89, 0x08, 0x98, 0xcf, 0x3a, 0xaf, 0x25, 0x87, 0xc0, 0x49, - 0xea, 0xa7, 0xfd, 0x67, 0xf7, 0x45, 0x8e, 0x97, 0xcc, 0x14, 0x39, 0xe2, - 0x36, 0x85, 0xb5, 0x7e, 0x1a, 0x37, 0xfd, 0x16, 0xf6, 0x71, 0x11, 0x9a, - 0x74, 0x30, 0x16, 0xfe, 0x13, 0x94, 0xa3, 0x3f, 0x84, 0x0d, 0x4f, 0x02, - 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x32, 0x30, 0x82, 0x01, 0x2e, - 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xfd, - 0xac, 0x61, 0x32, 0x93, 0x6c, 0x45, 0xd6, 0xe2, 0xee, 0x85, 0x5f, 0x9a, - 0xba, 0xe7, 0x76, 0x99, 0x68, 0xcc, 0xe7, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xd2, 0xc4, 0xb0, 0xd2, - 0x91, 0xd4, 0x4c, 0x11, 0x71, 0xb3, 0x61, 0xcb, 0x3d, 0xa1, 0xfe, 0xdd, - 0xa8, 0x6a, 0xd4, 0xe3, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, - 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, - 0x30, 0x33, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, - 0x04, 0x27, 0x30, 0x25, 0x30, 0x23, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x30, 0x01, 0x86, 0x17, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, - 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x46, 0x06, 0x03, 0x55, 0x1d, 0x1f, - 0x04, 0x3f, 0x30, 0x3d, 0x30, 0x3b, 0xa0, 0x39, 0xa0, 0x37, 0x86, 0x35, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, - 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x67, 0x64, 0x72, 0x6f, 0x6f, - 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x4b, 0x06, 0x03, 0x55, 0x1d, 0x20, - 0x04, 0x44, 0x30, 0x42, 0x30, 0x40, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, - 0x30, 0x38, 0x30, 0x36, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x02, 0x01, 0x16, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, - 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x30, 0x0e, - 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, - 0x01, 0x06, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xd2, 0x86, - 0xc0, 0xec, 0xbd, 0xf9, 0xa1, 0xb6, 0x67, 0xee, 0x66, 0x0b, 0xa2, 0x06, - 0x3a, 0x04, 0x50, 0x8e, 0x15, 0x72, 0xac, 0x4a, 0x74, 0x95, 0x53, 0xcb, - 0x37, 0xcb, 0x44, 0x49, 0xef, 0x07, 0x90, 0x6b, 0x33, 0xd9, 0x96, 0xf0, - 0x94, 0x56, 0xa5, 0x13, 0x30, 0x05, 0x3c, 0x85, 0x32, 0x21, 0x7b, 0xc9, - 0xc7, 0x0a, 0xa8, 0x24, 0xa4, 0x90, 0xde, 0x46, 0xd3, 0x25, 0x23, 0x14, - 0x03, 0x67, 0xc2, 0x10, 0xd6, 0x6f, 0x0f, 0x5d, 0x7b, 0x7a, 0xcc, 0x9f, - 0xc5, 0x58, 0x2a, 0xc1, 0xc4, 0x9e, 0x21, 0xa8, 0x5a, 0xf3, 0xac, 0xa4, - 0x46, 0xf3, 0x9e, 0xe4, 0x63, 0xcb, 0x2f, 0x90, 0xa4, 0x29, 0x29, 0x01, - 0xd9, 0x72, 0x2c, 0x29, 0xdf, 0x37, 0x01, 0x27, 0xbc, 0x4f, 0xee, 0x68, - 0xd3, 0x21, 0x8f, 0xc0, 0xb3, 0xe4, 0xf5, 0x09, 0xed, 0xd2, 0x10, 0xaa, - 0x53, 0xb4, 0xbe, 0xf0, 0xcc, 0x59, 0x0b, 0xd6, 0x3b, 0x96, 0x1c, 0x95, - 0x24, 0x49, 0xdf, 0xce, 0xec, 0xfd, 0xa7, 0x48, 0x91, 0x14, 0x45, 0x0e, - 0x3a, 0x36, 0x6f, 0xda, 0x45, 0xb3, 0x45, 0xa2, 0x41, 0xc9, 0xd4, 0xd7, - 0x44, 0x4e, 0x3e, 0xb9, 0x74, 0x76, 0xd5, 0xa2, 0x13, 0x55, 0x2c, 0xc6, - 0x87, 0xa3, 0xb5, 0x99, 0xac, 0x06, 0x84, 0x87, 0x7f, 0x75, 0x06, 0xfc, - 0xbf, 0x14, 0x4c, 0x0e, 0xcc, 0x6e, 0xc4, 0xdf, 0x3d, 0xb7, 0x12, 0x71, - 0xf4, 0xe8, 0xf1, 0x51, 0x40, 0x22, 0x28, 0x49, 0xe0, 0x1d, 0x4b, 0x87, - 0xa8, 0x34, 0xcc, 0x06, 0xa2, 0xdd, 0x12, 0x5a, 0xd1, 0x86, 0x36, 0x64, - 0x03, 0x35, 0x6f, 0x6f, 0x77, 0x6e, 0xeb, 0xf2, 0x85, 0x50, 0x98, 0x5e, - 0xab, 0x03, 0x53, 0xad, 0x91, 0x23, 0x63, 0x1f, 0x16, 0x9c, 0xcd, 0xb9, - 0xb2, 0x05, 0x63, 0x3a, 0xe1, 0xf4, 0x68, 0x1b, 0x17, 0x05, 0x35, 0x95, - 0x53, 0xee, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 6e:ba:f0:8f:79:83:fa:9d:e1:b2:6f:96:fc:6e:98:bf - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root - Validity - Not Before: Aug 23 00:00:00 2011 GMT - Not After : May 30 10:48:38 2020 GMT - Subject: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO SSL CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:d4:2b:2e:1c:d2:a3:f8:7f:55:14:40:de:f7:44: - dd:84:55:f7:85:7b:55:66:69:a7:e5:59:eb:65:83: - f4:f3:76:b1:66:c3:4f:4e:98:93:09:b7:40:b3:d1: - 17:a0:12:09:a8:80:e1:29:63:97:02:8c:31:9d:0a: - 02:e0:59:5b:bb:ed:30:b5:ef:7e:5d:af:08:4e:8d: - 8b:c2:39:56:16:98:73:94:78:0a:c9:a6:4f:28:b7: - a8:34:37:db:25:21:b1:3c:99:f6:e0:12:3e:73:ea: - 64:32:9f:42:06:3c:19:d8:0a:04:7a:4c:57:49:2b: - d2:77:7a:d0:00:bc:5e:fa:8e:ee:cc:c2:e4:13:6e: - 25:5f:dc:3c:a4:88:a3:dc:49:c7:bc:c7:0f:dd:19: - c0:b1:72:ed:78:ef:38:83:0a:45:17:1b:c9:7d:9d: - ed:df:ab:2c:2c:a3:75:ae:5b:82:1d:88:83:8d:ce: - 08:65:0c:66:26:57:05:a1:0c:df:e6:07:84:0b:84: - a3:c8:ab:d5:95:47:bf:dc:dc:fe:1d:fc:02:93:44: - 01:ca:e6:b5:b7:6b:16:30:01:5d:e9:89:09:95:9e: - f8:5e:29:5c:dd:c7:55:8c:f2:8e:20:4e:40:7a:e4: - f5:45:03:b4:98:2b:c4:80:7e:53:87:6f:c2:d2:57: - b0:e9 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Authority Key Identifier: - keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A - - X509v3 Subject Key Identifier: - 1B:6B:BD:1F:8A:49:18:94:54:37:55:B4:20:17:ED:37:B9:77:18:7D - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.usertrust.com/AddTrustExternalCARoot.crl - - Authority Information Access: - CA Issuers - URI:http://crt.usertrust.com/AddTrustExternalCARoot.p7c - CA Issuers - URI:http://crt.usertrust.com/AddTrustUTNSGCCA.crt - OCSP - URI:http://ocsp.usertrust.com - - Signature Algorithm: sha1WithRSAEncryption - 43:25:39:23:07:04:ac:99:5d:59:67:3d:e6:2f:61:7d:5a:56: - 7b:fc:06:8d:b3:4b:9d:fa:d5:05:4c:0d:66:b5:bd:3c:c7:a2: - 2a:6b:b5:cf:e6:ba:83:3e:60:90:36:0c:d5:c2:ed:8a:95:d9: - 92:42:23:1c:03:76:3e:c2:48:f1:75:72:9d:b3:8c:cf:b3:58: - 34:56:49:1d:a1:2e:2b:3d:b2:e8:5a:10:46:de:64:b5:4d:ae: - 4b:6e:fc:01:b7:21:10:d5:95:b7:eb:2c:be:14:06:cc:41:2e: - e4:6c:e2:46:90:ff:c6:28:7e:73:fe:e5:17:ba:82:c3:10:05: - 81:66:c2:8b:28:38:a0:44:3e:e9:e4:ce:33:b0:7c:f8:e1:53: - 9d:b8:b4:cb:da:c9:2e:d9:93:70:8e:7c:0b:e3:73:3e:99:99: - 8f:eb:e1:11:44:35:d8:60:81:62:45:d4:de:45:5b:90:2e:49: - 1b:1b:db:a4:0f:80:62:21:73:69:f1:e3:de:6d:d8:48:7c:56: - 12:26:22:11:47:01:c6:5e:19:c2:b4:95:97:ee:61:00:55:f1: - 04:38:fc:84:e6:78:b4:0d:43:be:43:33:dd:68:d3:22:5b:00: - fb:14:82:e8:4b:62:79:30:cf:d3:95:9f:b3:b9:84:01:d4:dd: - cf:23:12:f8 ------BEGIN CERTIFICATE----- -MIIE4jCCA8qgAwIBAgIQbrrwj3mD+p3hsm+W/G6YvzANBgkqhkiG9w0BAQUFADBv -MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk -ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF -eHRlcm5hbCBDQSBSb290MB4XDTExMDgyMzAwMDAwMFoXDTIwMDUzMDEwNDgzOFow -cDELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxFjAUBgNV -BAMTDUNPTU9ETyBTU0wgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQDUKy4c0qP4f1UUQN73RN2EVfeFe1VmaaflWetlg/TzdrFmw09OmJMJt0Cz0Reg -EgmogOEpY5cCjDGdCgLgWVu77TC1735drwhOjYvCOVYWmHOUeArJpk8ot6g0N9sl -IbE8mfbgEj5z6mQyn0IGPBnYCgR6TFdJK9J3etAAvF76ju7MwuQTbiVf3DykiKPc -Sce8xw/dGcCxcu147ziDCkUXG8l9ne3fqywso3WuW4IdiIONzghlDGYmVwWhDN/m -B4QLhKPIq9WVR7/c3P4d/AKTRAHK5rW3axYwAV3piQmVnvheKVzdx1WM8o4gTkB6 -5PVFA7SYK8SAflOHb8LSV7DpAgMBAAGjggF3MIIBczAfBgNVHSMEGDAWgBStvZh6 -NLQm9/rEJlTvA73gJMtUGjAdBgNVHQ4EFgQUG2u9H4pJGJRUN1W0IBftN7l3GH0w -DgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwEQYDVR0gBAowCDAG -BgRVHSAAMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNv -bS9BZGRUcnVzdEV4dGVybmFsQ0FSb290LmNybDCBswYIKwYBBQUHAQEEgaYwgaMw -PwYIKwYBBQUHMAKGM2h0dHA6Ly9jcnQudXNlcnRydXN0LmNvbS9BZGRUcnVzdEV4 -dGVybmFsQ0FSb290LnA3YzA5BggrBgEFBQcwAoYtaHR0cDovL2NydC51c2VydHJ1 -c3QuY29tL0FkZFRydXN0VVROU0dDQ0EuY3J0MCUGCCsGAQUFBzABhhlodHRwOi8v -b2NzcC51c2VydHJ1c3QuY29tMA0GCSqGSIb3DQEBBQUAA4IBAQBDJTkjBwSsmV1Z -Zz3mL2F9WlZ7/AaNs0ud+tUFTA1mtb08x6Iqa7XP5rqDPmCQNgzVwu2KldmSQiMc -A3Y+wkjxdXKds4zPs1g0VkkdoS4rPbLoWhBG3mS1Ta5LbvwBtyEQ1ZW36yy+FAbM -QS7kbOJGkP/GKH5z/uUXuoLDEAWBZsKLKDigRD7p5M4zsHz44VOduLTL2sku2ZNw -jnwL43M+mZmP6+ERRDXYYIFiRdTeRVuQLkkbG9ukD4BiIXNp8ePebdhIfFYSJiIR -RwHGXhnCtJWX7mEAVfEEOPyE5ni0DUO+QzPdaNMiWwD7FILoS2J5MM/TlZ+zuYQB -1N3PIxL4 ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert39[] = { - 0x30, 0x82, 0x04, 0xe2, 0x30, 0x82, 0x03, 0xca, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x6e, 0xba, 0xf0, 0x8f, 0x79, 0x83, 0xfa, 0x9d, 0xe1, - 0xb2, 0x6f, 0x96, 0xfc, 0x6e, 0x98, 0xbf, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x6f, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x53, - 0x45, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, - 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41, 0x42, 0x31, - 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x64, - 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x20, 0x54, 0x54, 0x50, 0x20, 0x4e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x19, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, - 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x52, - 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x30, 0x38, 0x32, - 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, - 0x30, 0x35, 0x33, 0x30, 0x31, 0x30, 0x34, 0x38, 0x33, 0x38, 0x5a, 0x30, - 0x70, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x47, 0x42, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e, - 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0e, 0x06, - 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6c, 0x66, 0x6f, 0x72, - 0x64, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, - 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, - 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x0d, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x53, - 0x53, 0x4c, 0x20, 0x43, 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, 0xd4, 0x2b, 0x2e, 0x1c, 0xd2, 0xa3, 0xf8, 0x7f, 0x55, 0x14, - 0x40, 0xde, 0xf7, 0x44, 0xdd, 0x84, 0x55, 0xf7, 0x85, 0x7b, 0x55, 0x66, - 0x69, 0xa7, 0xe5, 0x59, 0xeb, 0x65, 0x83, 0xf4, 0xf3, 0x76, 0xb1, 0x66, - 0xc3, 0x4f, 0x4e, 0x98, 0x93, 0x09, 0xb7, 0x40, 0xb3, 0xd1, 0x17, 0xa0, - 0x12, 0x09, 0xa8, 0x80, 0xe1, 0x29, 0x63, 0x97, 0x02, 0x8c, 0x31, 0x9d, - 0x0a, 0x02, 0xe0, 0x59, 0x5b, 0xbb, 0xed, 0x30, 0xb5, 0xef, 0x7e, 0x5d, - 0xaf, 0x08, 0x4e, 0x8d, 0x8b, 0xc2, 0x39, 0x56, 0x16, 0x98, 0x73, 0x94, - 0x78, 0x0a, 0xc9, 0xa6, 0x4f, 0x28, 0xb7, 0xa8, 0x34, 0x37, 0xdb, 0x25, - 0x21, 0xb1, 0x3c, 0x99, 0xf6, 0xe0, 0x12, 0x3e, 0x73, 0xea, 0x64, 0x32, - 0x9f, 0x42, 0x06, 0x3c, 0x19, 0xd8, 0x0a, 0x04, 0x7a, 0x4c, 0x57, 0x49, - 0x2b, 0xd2, 0x77, 0x7a, 0xd0, 0x00, 0xbc, 0x5e, 0xfa, 0x8e, 0xee, 0xcc, - 0xc2, 0xe4, 0x13, 0x6e, 0x25, 0x5f, 0xdc, 0x3c, 0xa4, 0x88, 0xa3, 0xdc, - 0x49, 0xc7, 0xbc, 0xc7, 0x0f, 0xdd, 0x19, 0xc0, 0xb1, 0x72, 0xed, 0x78, - 0xef, 0x38, 0x83, 0x0a, 0x45, 0x17, 0x1b, 0xc9, 0x7d, 0x9d, 0xed, 0xdf, - 0xab, 0x2c, 0x2c, 0xa3, 0x75, 0xae, 0x5b, 0x82, 0x1d, 0x88, 0x83, 0x8d, - 0xce, 0x08, 0x65, 0x0c, 0x66, 0x26, 0x57, 0x05, 0xa1, 0x0c, 0xdf, 0xe6, - 0x07, 0x84, 0x0b, 0x84, 0xa3, 0xc8, 0xab, 0xd5, 0x95, 0x47, 0xbf, 0xdc, - 0xdc, 0xfe, 0x1d, 0xfc, 0x02, 0x93, 0x44, 0x01, 0xca, 0xe6, 0xb5, 0xb7, - 0x6b, 0x16, 0x30, 0x01, 0x5d, 0xe9, 0x89, 0x09, 0x95, 0x9e, 0xf8, 0x5e, - 0x29, 0x5c, 0xdd, 0xc7, 0x55, 0x8c, 0xf2, 0x8e, 0x20, 0x4e, 0x40, 0x7a, - 0xe4, 0xf5, 0x45, 0x03, 0xb4, 0x98, 0x2b, 0xc4, 0x80, 0x7e, 0x53, 0x87, - 0x6f, 0xc2, 0xd2, 0x57, 0xb0, 0xe9, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, - 0x82, 0x01, 0x77, 0x30, 0x82, 0x01, 0x73, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xad, 0xbd, 0x98, 0x7a, - 0x34, 0xb4, 0x26, 0xf7, 0xfa, 0xc4, 0x26, 0x54, 0xef, 0x03, 0xbd, 0xe0, - 0x24, 0xcb, 0x54, 0x1a, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, - 0x16, 0x04, 0x14, 0x1b, 0x6b, 0xbd, 0x1f, 0x8a, 0x49, 0x18, 0x94, 0x54, - 0x37, 0x55, 0xb4, 0x20, 0x17, 0xed, 0x37, 0xb9, 0x77, 0x18, 0x7d, 0x30, - 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, - 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, - 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, - 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x0a, 0x30, 0x08, 0x30, 0x06, - 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x44, 0x06, 0x03, 0x55, 0x1d, - 0x1f, 0x04, 0x3d, 0x30, 0x3b, 0x30, 0x39, 0xa0, 0x37, 0xa0, 0x35, 0x86, - 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, - 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x45, 0x78, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x41, 0x52, 0x6f, 0x6f, 0x74, - 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x81, 0xb3, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x81, 0xa6, 0x30, 0x81, 0xa3, 0x30, - 0x3f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, - 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, - 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x45, 0x78, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x41, 0x52, 0x6f, 0x6f, 0x74, - 0x2e, 0x70, 0x37, 0x63, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, - 0x75, 0x73, 0x74, 0x55, 0x54, 0x4e, 0x53, 0x47, 0x43, 0x43, 0x41, 0x2e, - 0x63, 0x72, 0x74, 0x30, 0x25, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x30, 0x01, 0x86, 0x19, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, - 0x01, 0x00, 0x43, 0x25, 0x39, 0x23, 0x07, 0x04, 0xac, 0x99, 0x5d, 0x59, - 0x67, 0x3d, 0xe6, 0x2f, 0x61, 0x7d, 0x5a, 0x56, 0x7b, 0xfc, 0x06, 0x8d, - 0xb3, 0x4b, 0x9d, 0xfa, 0xd5, 0x05, 0x4c, 0x0d, 0x66, 0xb5, 0xbd, 0x3c, - 0xc7, 0xa2, 0x2a, 0x6b, 0xb5, 0xcf, 0xe6, 0xba, 0x83, 0x3e, 0x60, 0x90, - 0x36, 0x0c, 0xd5, 0xc2, 0xed, 0x8a, 0x95, 0xd9, 0x92, 0x42, 0x23, 0x1c, - 0x03, 0x76, 0x3e, 0xc2, 0x48, 0xf1, 0x75, 0x72, 0x9d, 0xb3, 0x8c, 0xcf, - 0xb3, 0x58, 0x34, 0x56, 0x49, 0x1d, 0xa1, 0x2e, 0x2b, 0x3d, 0xb2, 0xe8, - 0x5a, 0x10, 0x46, 0xde, 0x64, 0xb5, 0x4d, 0xae, 0x4b, 0x6e, 0xfc, 0x01, - 0xb7, 0x21, 0x10, 0xd5, 0x95, 0xb7, 0xeb, 0x2c, 0xbe, 0x14, 0x06, 0xcc, - 0x41, 0x2e, 0xe4, 0x6c, 0xe2, 0x46, 0x90, 0xff, 0xc6, 0x28, 0x7e, 0x73, - 0xfe, 0xe5, 0x17, 0xba, 0x82, 0xc3, 0x10, 0x05, 0x81, 0x66, 0xc2, 0x8b, - 0x28, 0x38, 0xa0, 0x44, 0x3e, 0xe9, 0xe4, 0xce, 0x33, 0xb0, 0x7c, 0xf8, - 0xe1, 0x53, 0x9d, 0xb8, 0xb4, 0xcb, 0xda, 0xc9, 0x2e, 0xd9, 0x93, 0x70, - 0x8e, 0x7c, 0x0b, 0xe3, 0x73, 0x3e, 0x99, 0x99, 0x8f, 0xeb, 0xe1, 0x11, - 0x44, 0x35, 0xd8, 0x60, 0x81, 0x62, 0x45, 0xd4, 0xde, 0x45, 0x5b, 0x90, - 0x2e, 0x49, 0x1b, 0x1b, 0xdb, 0xa4, 0x0f, 0x80, 0x62, 0x21, 0x73, 0x69, - 0xf1, 0xe3, 0xde, 0x6d, 0xd8, 0x48, 0x7c, 0x56, 0x12, 0x26, 0x22, 0x11, - 0x47, 0x01, 0xc6, 0x5e, 0x19, 0xc2, 0xb4, 0x95, 0x97, 0xee, 0x61, 0x00, - 0x55, 0xf1, 0x04, 0x38, 0xfc, 0x84, 0xe6, 0x78, 0xb4, 0x0d, 0x43, 0xbe, - 0x43, 0x33, 0xdd, 0x68, 0xd3, 0x22, 0x5b, 0x00, 0xfb, 0x14, 0x82, 0xe8, - 0x4b, 0x62, 0x79, 0x30, 0xcf, 0xd3, 0x95, 0x9f, 0xb3, 0xb9, 0x84, 0x01, - 0xd4, 0xdd, 0xcf, 0x23, 0x12, 0xf8, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 4f:e3:e2:65:21:07:ab:20:37:41:6e:48:70:ce:d2:c2 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root - Validity - Not Before: May 25 00:00:00 2010 GMT - Not After : May 30 10:48:38 2020 GMT - Subject: C=US, O=Trusted Secure Certificate Authority, CN=Trusted Secure Certificate Authority - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:80:0b:42:c6:06:6c:cf:22:b3:1a:9e:11:2e:42: - 6e:39:bf:e8:12:af:3c:42:21:12:95:40:5d:32:b1: - 6d:1c:21:d1:34:e5:4f:a8:d1:43:a2:26:4e:30:7d: - 73:44:2c:73:aa:c5:4d:66:01:19:d2:ea:50:59:65: - d0:68:9d:05:a0:7c:a1:79:53:d0:21:90:59:0e:37: - db:1e:dc:92:a7:8b:0d:c4:f5:f8:e6:ff:b5:35:1a: - da:a8:b6:9b:20:85:65:c4:a2:4d:df:f3:94:4d:63: - 7e:ee:89:07:af:fe:e1:ba:00:15:2d:c6:77:8e:a3: - fe:ad:cf:26:54:5a:df:fc:d2:de:c2:ad:f6:b2:23: - fd:a8:83:e5:65:bd:27:f7:27:1a:18:59:6a:9e:14: - f6:b4:86:ff:1c:58:14:43:73:96:24:bf:10:43:d5: - 5c:89:f0:ce:f7:e1:96:16:5e:18:4a:27:28:90:80: - 18:fc:32:fe:f4:c7:b8:d6:82:3d:35:af:bb:4a:1c: - 5b:05:78:f6:fd:55:3e:82:74:b2:73:b8:89:4e:f7: - 1b:85:9a:d8:ca:b1:5a:b1:00:20:41:14:30:2b:14: - 24:ed:37:0e:32:3e:23:88:39:7e:b9:d9:38:03:e2: - 4c:d9:0d:43:41:33:10:eb:30:72:53:88:f7:52:9b: - 4f:81 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Authority Key Identifier: - keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A - - X509v3 Subject Key Identifier: - CC:03:5B:96:5A:9E:16:CC:26:1E:BD:A3:70:FB:E3:CB:79:19:FC:4D - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Certificate Policies: - Policy: 1.3.6.1.4.1.6449.1.2.2.8 - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.usertrust.com/AddTrustExternalCARoot.crl - - Authority Information Access: - CA Issuers - URI:http://crt.usertrust.com/AddTrustExternalCARoot.p7c - CA Issuers - URI:http://crt.usertrust.com/AddTrustUTNSGCCA.crt - OCSP - URI:http://ocsp.usertrust.com - - Signature Algorithm: sha1WithRSAEncryption - 7b:f0:fc:a1:28:47:bc:2b:b4:04:73:3f:4b:dd:1e:d1:b9:cd: - 1c:ed:7d:e5:e8:cb:51:f4:92:bf:dd:9c:0d:5c:6e:1d:95:ed: - 5b:70:50:89:d4:67:9a:15:54:d1:90:0a:fa:09:68:06:18:bb: - d7:27:e4:93:ff:43:48:81:3b:c8:59:49:35:ea:ac:b6:ae:46: - b5:d4:f3:b8:c3:c6:e4:91:bf:c9:34:fd:7e:d0:59:6e:61:a1: - 1f:48:63:54:b2:7d:46:bf:c8:fa:c3:bf:48:58:98:f6:69:84: - a7:16:69:08:27:a4:22:cb:a2:2c:c8:df:6e:a9:ee:f8:41:df: - 1b:a8:b7:f3:e3:ae:ce:a3:fe:d9:27:60:50:3f:04:7d:7a:44: - ea:76:42:5c:d3:55:46:ef:27:c5:6a:4a:80:e7:35:a0:91:c6: - 1b:a6:86:9c:5a:3b:04:83:54:34:d7:d1:88:a6:36:e9:7f:40: - 27:da:56:0a:50:21:9d:29:8b:a0:84:ec:fe:71:23:53:04:18: - 19:70:67:86:44:95:72:40:55:f6:dd:a3:b4:3d:2d:09:60:a5: - e7:5f:fc:ac:3b:ec:0c:91:9f:f8:ee:6a:ba:b2:3c:fd:95:7d: - 9a:07:f4:b0:65:43:a2:f6:df:7d:b8:21:49:84:04:ee:bd:ce: - 53:8f:0f:29 ------BEGIN CERTIFICATE----- -MIIE5DCCA8ygAwIBAgIQT+PiZSEHqyA3QW5IcM7SwjANBgkqhkiG9w0BAQUFADBv -MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk -ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF -eHRlcm5hbCBDQSBSb290MB4XDTEwMDUyNTAwMDAwMFoXDTIwMDUzMDEwNDgzOFow -azELMAkGA1UEBhMCVVMxLTArBgNVBAoTJFRydXN0ZWQgU2VjdXJlIENlcnRpZmlj -YXRlIEF1dGhvcml0eTEtMCsGA1UEAxMkVHJ1c3RlZCBTZWN1cmUgQ2VydGlmaWNh -dGUgQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgAtC -xgZszyKzGp4RLkJuOb/oEq88QiESlUBdMrFtHCHRNOVPqNFDoiZOMH1zRCxzqsVN -ZgEZ0upQWWXQaJ0FoHyheVPQIZBZDjfbHtySp4sNxPX45v+1NRraqLabIIVlxKJN -3/OUTWN+7okHr/7hugAVLcZ3jqP+rc8mVFrf/NLewq32siP9qIPlZb0n9ycaGFlq -nhT2tIb/HFgUQ3OWJL8QQ9VcifDO9+GWFl4YSicokIAY/DL+9Me41oI9Na+7Shxb -BXj2/VU+gnSyc7iJTvcbhZrYyrFasQAgQRQwKxQk7TcOMj4jiDl+udk4A+JM2Q1D -QTMQ6zByU4j3UptPgQIDAQABo4IBfjCCAXowHwYDVR0jBBgwFoAUrb2YejS0Jvf6 -xCZU7wO94CTLVBowHQYDVR0OBBYEFMwDW5ZanhbMJh69o3D748t5GfxNMA4GA1Ud -DwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMBgGA1UdIAQRMA8wDQYLKwYB -BAGyMQECAggwRAYDVR0fBD0wOzA5oDegNYYzaHR0cDovL2NybC51c2VydHJ1c3Qu -Y29tL0FkZFRydXN0RXh0ZXJuYWxDQVJvb3QuY3JsMIGzBggrBgEFBQcBAQSBpjCB -ozA/BggrBgEFBQcwAoYzaHR0cDovL2NydC51c2VydHJ1c3QuY29tL0FkZFRydXN0 -RXh0ZXJuYWxDQVJvb3QucDdjMDkGCCsGAQUFBzAChi1odHRwOi8vY3J0LnVzZXJ0 -cnVzdC5jb20vQWRkVHJ1c3RVVE5TR0NDQS5jcnQwJQYIKwYBBQUHMAGGGWh0dHA6 -Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEFBQADggEBAHvw/KEoR7wr -tARzP0vdHtG5zRztfeXoy1H0kr/dnA1cbh2V7VtwUInUZ5oVVNGQCvoJaAYYu9cn -5JP/Q0iBO8hZSTXqrLauRrXU87jDxuSRv8k0/X7QWW5hoR9IY1SyfUa/yPrDv0hY -mPZphKcWaQgnpCLLoizI326p7vhB3xuot/Pjrs6j/tknYFA/BH16ROp2QlzTVUbv -J8VqSoDnNaCRxhumhpxaOwSDVDTX0YimNul/QCfaVgpQIZ0pi6CE7P5xI1MEGBlw -Z4ZElXJAVfbdo7Q9LQlgpedf/Kw77AyRn/juarqyPP2VfZoH9LBlQ6L23324IUmE -BO69zlOPDyk= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert40[] = { - 0x30, 0x82, 0x04, 0xe4, 0x30, 0x82, 0x03, 0xcc, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x4f, 0xe3, 0xe2, 0x65, 0x21, 0x07, 0xab, 0x20, 0x37, - 0x41, 0x6e, 0x48, 0x70, 0xce, 0xd2, 0xc2, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x6f, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x53, - 0x45, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, - 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41, 0x42, 0x31, - 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x64, - 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x20, 0x54, 0x54, 0x50, 0x20, 0x4e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x19, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, - 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x52, - 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x35, 0x32, - 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, - 0x30, 0x35, 0x33, 0x30, 0x31, 0x30, 0x34, 0x38, 0x33, 0x38, 0x5a, 0x30, - 0x6b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x24, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x53, 0x65, 0x63, - 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, - 0x79, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, - 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x53, 0x65, 0x63, 0x75, - 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, - 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, 0x80, 0x0b, 0x42, - 0xc6, 0x06, 0x6c, 0xcf, 0x22, 0xb3, 0x1a, 0x9e, 0x11, 0x2e, 0x42, 0x6e, - 0x39, 0xbf, 0xe8, 0x12, 0xaf, 0x3c, 0x42, 0x21, 0x12, 0x95, 0x40, 0x5d, - 0x32, 0xb1, 0x6d, 0x1c, 0x21, 0xd1, 0x34, 0xe5, 0x4f, 0xa8, 0xd1, 0x43, - 0xa2, 0x26, 0x4e, 0x30, 0x7d, 0x73, 0x44, 0x2c, 0x73, 0xaa, 0xc5, 0x4d, - 0x66, 0x01, 0x19, 0xd2, 0xea, 0x50, 0x59, 0x65, 0xd0, 0x68, 0x9d, 0x05, - 0xa0, 0x7c, 0xa1, 0x79, 0x53, 0xd0, 0x21, 0x90, 0x59, 0x0e, 0x37, 0xdb, - 0x1e, 0xdc, 0x92, 0xa7, 0x8b, 0x0d, 0xc4, 0xf5, 0xf8, 0xe6, 0xff, 0xb5, - 0x35, 0x1a, 0xda, 0xa8, 0xb6, 0x9b, 0x20, 0x85, 0x65, 0xc4, 0xa2, 0x4d, - 0xdf, 0xf3, 0x94, 0x4d, 0x63, 0x7e, 0xee, 0x89, 0x07, 0xaf, 0xfe, 0xe1, - 0xba, 0x00, 0x15, 0x2d, 0xc6, 0x77, 0x8e, 0xa3, 0xfe, 0xad, 0xcf, 0x26, - 0x54, 0x5a, 0xdf, 0xfc, 0xd2, 0xde, 0xc2, 0xad, 0xf6, 0xb2, 0x23, 0xfd, - 0xa8, 0x83, 0xe5, 0x65, 0xbd, 0x27, 0xf7, 0x27, 0x1a, 0x18, 0x59, 0x6a, - 0x9e, 0x14, 0xf6, 0xb4, 0x86, 0xff, 0x1c, 0x58, 0x14, 0x43, 0x73, 0x96, - 0x24, 0xbf, 0x10, 0x43, 0xd5, 0x5c, 0x89, 0xf0, 0xce, 0xf7, 0xe1, 0x96, - 0x16, 0x5e, 0x18, 0x4a, 0x27, 0x28, 0x90, 0x80, 0x18, 0xfc, 0x32, 0xfe, - 0xf4, 0xc7, 0xb8, 0xd6, 0x82, 0x3d, 0x35, 0xaf, 0xbb, 0x4a, 0x1c, 0x5b, - 0x05, 0x78, 0xf6, 0xfd, 0x55, 0x3e, 0x82, 0x74, 0xb2, 0x73, 0xb8, 0x89, - 0x4e, 0xf7, 0x1b, 0x85, 0x9a, 0xd8, 0xca, 0xb1, 0x5a, 0xb1, 0x00, 0x20, - 0x41, 0x14, 0x30, 0x2b, 0x14, 0x24, 0xed, 0x37, 0x0e, 0x32, 0x3e, 0x23, - 0x88, 0x39, 0x7e, 0xb9, 0xd9, 0x38, 0x03, 0xe2, 0x4c, 0xd9, 0x0d, 0x43, - 0x41, 0x33, 0x10, 0xeb, 0x30, 0x72, 0x53, 0x88, 0xf7, 0x52, 0x9b, 0x4f, - 0x81, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x7e, 0x30, 0x82, - 0x01, 0x7a, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, - 0x16, 0x80, 0x14, 0xad, 0xbd, 0x98, 0x7a, 0x34, 0xb4, 0x26, 0xf7, 0xfa, - 0xc4, 0x26, 0x54, 0xef, 0x03, 0xbd, 0xe0, 0x24, 0xcb, 0x54, 0x1a, 0x30, - 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xcc, 0x03, - 0x5b, 0x96, 0x5a, 0x9e, 0x16, 0xcc, 0x26, 0x1e, 0xbd, 0xa3, 0x70, 0xfb, - 0xe3, 0xcb, 0x79, 0x19, 0xfc, 0x4d, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, - 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, - 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, - 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x18, 0x06, 0x03, 0x55, 0x1d, - 0x20, 0x04, 0x11, 0x30, 0x0f, 0x30, 0x0d, 0x06, 0x0b, 0x2b, 0x06, 0x01, - 0x04, 0x01, 0xb2, 0x31, 0x01, 0x02, 0x02, 0x08, 0x30, 0x44, 0x06, 0x03, - 0x55, 0x1d, 0x1f, 0x04, 0x3d, 0x30, 0x3b, 0x30, 0x39, 0xa0, 0x37, 0xa0, - 0x35, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, - 0x6c, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, - 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x41, 0x52, 0x6f, - 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x81, 0xb3, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x81, 0xa6, 0x30, 0x81, - 0xa3, 0x30, 0x3f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, - 0x02, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, - 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, - 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x41, 0x52, 0x6f, - 0x6f, 0x74, 0x2e, 0x70, 0x37, 0x63, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, - 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, - 0x54, 0x72, 0x75, 0x73, 0x74, 0x55, 0x54, 0x4e, 0x53, 0x47, 0x43, 0x43, - 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x25, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x19, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, - 0x82, 0x01, 0x01, 0x00, 0x7b, 0xf0, 0xfc, 0xa1, 0x28, 0x47, 0xbc, 0x2b, - 0xb4, 0x04, 0x73, 0x3f, 0x4b, 0xdd, 0x1e, 0xd1, 0xb9, 0xcd, 0x1c, 0xed, - 0x7d, 0xe5, 0xe8, 0xcb, 0x51, 0xf4, 0x92, 0xbf, 0xdd, 0x9c, 0x0d, 0x5c, - 0x6e, 0x1d, 0x95, 0xed, 0x5b, 0x70, 0x50, 0x89, 0xd4, 0x67, 0x9a, 0x15, - 0x54, 0xd1, 0x90, 0x0a, 0xfa, 0x09, 0x68, 0x06, 0x18, 0xbb, 0xd7, 0x27, - 0xe4, 0x93, 0xff, 0x43, 0x48, 0x81, 0x3b, 0xc8, 0x59, 0x49, 0x35, 0xea, - 0xac, 0xb6, 0xae, 0x46, 0xb5, 0xd4, 0xf3, 0xb8, 0xc3, 0xc6, 0xe4, 0x91, - 0xbf, 0xc9, 0x34, 0xfd, 0x7e, 0xd0, 0x59, 0x6e, 0x61, 0xa1, 0x1f, 0x48, - 0x63, 0x54, 0xb2, 0x7d, 0x46, 0xbf, 0xc8, 0xfa, 0xc3, 0xbf, 0x48, 0x58, - 0x98, 0xf6, 0x69, 0x84, 0xa7, 0x16, 0x69, 0x08, 0x27, 0xa4, 0x22, 0xcb, - 0xa2, 0x2c, 0xc8, 0xdf, 0x6e, 0xa9, 0xee, 0xf8, 0x41, 0xdf, 0x1b, 0xa8, - 0xb7, 0xf3, 0xe3, 0xae, 0xce, 0xa3, 0xfe, 0xd9, 0x27, 0x60, 0x50, 0x3f, - 0x04, 0x7d, 0x7a, 0x44, 0xea, 0x76, 0x42, 0x5c, 0xd3, 0x55, 0x46, 0xef, - 0x27, 0xc5, 0x6a, 0x4a, 0x80, 0xe7, 0x35, 0xa0, 0x91, 0xc6, 0x1b, 0xa6, - 0x86, 0x9c, 0x5a, 0x3b, 0x04, 0x83, 0x54, 0x34, 0xd7, 0xd1, 0x88, 0xa6, - 0x36, 0xe9, 0x7f, 0x40, 0x27, 0xda, 0x56, 0x0a, 0x50, 0x21, 0x9d, 0x29, - 0x8b, 0xa0, 0x84, 0xec, 0xfe, 0x71, 0x23, 0x53, 0x04, 0x18, 0x19, 0x70, - 0x67, 0x86, 0x44, 0x95, 0x72, 0x40, 0x55, 0xf6, 0xdd, 0xa3, 0xb4, 0x3d, - 0x2d, 0x09, 0x60, 0xa5, 0xe7, 0x5f, 0xfc, 0xac, 0x3b, 0xec, 0x0c, 0x91, - 0x9f, 0xf8, 0xee, 0x6a, 0xba, 0xb2, 0x3c, 0xfd, 0x95, 0x7d, 0x9a, 0x07, - 0xf4, 0xb0, 0x65, 0x43, 0xa2, 0xf6, 0xdf, 0x7d, 0xb8, 0x21, 0x49, 0x84, - 0x04, 0xee, 0xbd, 0xce, 0x53, 0x8f, 0x0f, 0x29, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 07:6f:12:46:81:45:9c:28:d5:48:d6:97:c4:0e:00:1b - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root - Validity - Not Before: Feb 16 00:00:00 2012 GMT - Not After : May 30 10:48:38 2020 GMT - Subject: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=PositiveSSL CA 2 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:e8:ea:39:e3:22:a6:aa:b9:c4:00:d0:e7:aa:67: - 3b:43:07:bd:4f:92:eb:bc:be:01:a3:40:ad:e0:ef: - 44:28:b5:d0:3a:be:80:54:17:85:7a:6b:84:6c:36: - 36:e5:a3:24:e2:fe:28:01:90:bc:d7:dd:0f:b9:2b: - 4e:48:77:05:69:af:de:57:30:b1:e8:fb:1a:03:f6: - 3c:5b:53:1e:a1:01:49:68:72:73:d6:33:2b:43:a9: - 37:32:52:0f:ae:27:56:31:30:60:ad:c9:bd:73:2c: - 39:ee:90:d8:75:b0:25:21:60:7b:2a:7f:02:fd:82: - 85:1f:74:4f:92:34:73:5c:1d:00:a0:b0:c0:ea:98: - e2:be:01:14:58:17:28:22:8a:77:5d:50:25:cd:9a: - 6c:a6:e5:0c:e5:ab:28:c3:b2:20:89:f0:07:24:1e: - 95:c2:2e:c0:e5:e9:ec:f6:3d:12:07:48:3d:d2:c3: - 23:56:41:ec:d3:df:35:4b:c8:e7:f6:86:05:52:10: - 43:9a:8c:17:7c:8b:aa:bc:78:e0:f0:45:3b:ac:80: - 55:fe:28:93:e1:0a:11:68:f4:52:57:6f:fe:48:0b: - 5b:5d:1a:6a:67:73:99:82:b4:9e:43:60:3e:c7:5b: - 2a:12:6e:1a:ee:cb:39:ae:c3:35:9d:a8:bc:5d:b0: - 2f:c3 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Authority Key Identifier: - keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A - - X509v3 Subject Key Identifier: - 99:E4:40:5F:6B:14:5E:3E:05:D9:DD:D3:63:54:FC:62:B8:F7:00:AC - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.usertrust.com/AddTrustExternalCARoot.crl - - Authority Information Access: - CA Issuers - URI:http://crt.usertrust.com/AddTrustExternalCARoot.p7c - CA Issuers - URI:http://crt.usertrust.com/AddTrustUTNSGCCA.crt - OCSP - URI:http://ocsp.usertrust.com - - Signature Algorithm: sha1WithRSAEncryption - 9c:36:e3:4e:ae:f1:8a:bb:6c:97:8c:8f:4b:67:d0:9f:d8:84: - aa:9f:21:5f:35:a1:5b:c4:2b:63:0d:e8:bc:77:5d:a7:c4:37: - fd:4b:2d:9e:e8:1d:69:a1:c0:84:cc:d1:6d:8b:f3:81:cb:9f: - 4b:74:b0:49:2a:31:e8:37:40:eb:1f:d9:97:a3:1a:11:d5:26: - a7:6e:0f:ba:d5:be:2c:fd:b4:91:64:dc:be:3b:19:50:0d:7a: - 95:f3:04:13:a9:bb:47:0f:8b:5c:d1:ac:c2:7b:77:21:50:dd: - 5b:ab:ee:f4:a6:d8:d4:4a:53:6b:4d:ad:b8:c8:e7:e6:52:58: - 4d:43:4c:c2:a2:23:4f:0e:c0:20:39:af:df:4f:42:5b:1e:d3: - 09:f4:18:09:59:2a:d9:e8:4a:18:bf:32:fb:fa:2d:64:8b:87: - ca:5b:2b:e8:b8:0b:7e:be:17:12:c7:03:82:29:af:58:af:85: - 84:5d:3d:0a:df:23:51:c3:cd:af:10:bf:80:69:77:91:0a:4f: - e5:ba:e1:ad:9b:ce:df:33:4e:30:3b:e9:8f:66:7f:82:fa:6b: - fa:db:a3:c0:73:00:e3:d6:12:af:4d:f2:0f:5a:14:51:1f:6d: - b8:86:81:62:07:ce:5c:72:c2:4f:f3:57:2a:71:d9:d4:97:85: - e6:18:53:b7 ------BEGIN CERTIFICATE----- -MIIE5TCCA82gAwIBAgIQB28SRoFFnCjVSNaXxA4AGzANBgkqhkiG9w0BAQUFADBv -MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk -ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF -eHRlcm5hbCBDQSBSb290MB4XDTEyMDIxNjAwMDAwMFoXDTIwMDUzMDEwNDgzOFow -czELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxGTAXBgNV -BAMTEFBvc2l0aXZlU1NMIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQDo6jnjIqaqucQA0OeqZztDB71Pkuu8vgGjQK3g70QotdA6voBUF4V6a4Rs -NjbloyTi/igBkLzX3Q+5K05IdwVpr95XMLHo+xoD9jxbUx6hAUlocnPWMytDqTcy -Ug+uJ1YxMGCtyb1zLDnukNh1sCUhYHsqfwL9goUfdE+SNHNcHQCgsMDqmOK+ARRY -FygiinddUCXNmmym5QzlqyjDsiCJ8AckHpXCLsDl6ez2PRIHSD3SwyNWQezT3zVL -yOf2hgVSEEOajBd8i6q8eODwRTusgFX+KJPhChFo9FJXb/5IC1tdGmpnc5mCtJ5D -YD7HWyoSbhruyzmuwzWdqLxdsC/DAgMBAAGjggF3MIIBczAfBgNVHSMEGDAWgBSt -vZh6NLQm9/rEJlTvA73gJMtUGjAdBgNVHQ4EFgQUmeRAX2sUXj4F2d3TY1T8Yrj3 -AKwwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwEQYDVR0gBAow -CDAGBgRVHSAAMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0 -LmNvbS9BZGRUcnVzdEV4dGVybmFsQ0FSb290LmNybDCBswYIKwYBBQUHAQEEgaYw -gaMwPwYIKwYBBQUHMAKGM2h0dHA6Ly9jcnQudXNlcnRydXN0LmNvbS9BZGRUcnVz -dEV4dGVybmFsQ0FSb290LnA3YzA5BggrBgEFBQcwAoYtaHR0cDovL2NydC51c2Vy -dHJ1c3QuY29tL0FkZFRydXN0VVROU0dDQ0EuY3J0MCUGCCsGAQUFBzABhhlodHRw -Oi8vb2NzcC51c2VydHJ1c3QuY29tMA0GCSqGSIb3DQEBBQUAA4IBAQCcNuNOrvGK -u2yXjI9LZ9Cf2ISqnyFfNaFbxCtjDei8d12nxDf9Sy2e6B1pocCEzNFti/OBy59L -dLBJKjHoN0DrH9mXoxoR1Sanbg+61b4s/bSRZNy+OxlQDXqV8wQTqbtHD4tc0azC -e3chUN1bq+70ptjUSlNrTa24yOfmUlhNQ0zCoiNPDsAgOa/fT0JbHtMJ9BgJWSrZ -6EoYvzL7+i1ki4fKWyvouAt+vhcSxwOCKa9Yr4WEXT0K3yNRw82vEL+AaXeRCk/l -uuGtm87fM04wO+mPZn+C+mv626PAcwDj1hKvTfIPWhRRH224hoFiB85ccsJP81cq -cdnUl4XmGFO3 ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert41[] = { - 0x30, 0x82, 0x04, 0xe5, 0x30, 0x82, 0x03, 0xcd, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x07, 0x6f, 0x12, 0x46, 0x81, 0x45, 0x9c, 0x28, 0xd5, - 0x48, 0xd6, 0x97, 0xc4, 0x0e, 0x00, 0x1b, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x6f, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x53, - 0x45, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, - 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41, 0x42, 0x31, - 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x64, - 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x20, 0x54, 0x54, 0x50, 0x20, 0x4e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x19, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, - 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x52, - 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x30, 0x32, 0x31, - 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, - 0x30, 0x35, 0x33, 0x30, 0x31, 0x30, 0x34, 0x38, 0x33, 0x38, 0x5a, 0x30, - 0x73, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x47, 0x42, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e, - 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0e, 0x06, - 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6c, 0x66, 0x6f, 0x72, - 0x64, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, - 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, - 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x10, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, - 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x32, 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, 0xe8, 0xea, 0x39, 0xe3, 0x22, 0xa6, 0xaa, - 0xb9, 0xc4, 0x00, 0xd0, 0xe7, 0xaa, 0x67, 0x3b, 0x43, 0x07, 0xbd, 0x4f, - 0x92, 0xeb, 0xbc, 0xbe, 0x01, 0xa3, 0x40, 0xad, 0xe0, 0xef, 0x44, 0x28, - 0xb5, 0xd0, 0x3a, 0xbe, 0x80, 0x54, 0x17, 0x85, 0x7a, 0x6b, 0x84, 0x6c, - 0x36, 0x36, 0xe5, 0xa3, 0x24, 0xe2, 0xfe, 0x28, 0x01, 0x90, 0xbc, 0xd7, - 0xdd, 0x0f, 0xb9, 0x2b, 0x4e, 0x48, 0x77, 0x05, 0x69, 0xaf, 0xde, 0x57, - 0x30, 0xb1, 0xe8, 0xfb, 0x1a, 0x03, 0xf6, 0x3c, 0x5b, 0x53, 0x1e, 0xa1, - 0x01, 0x49, 0x68, 0x72, 0x73, 0xd6, 0x33, 0x2b, 0x43, 0xa9, 0x37, 0x32, - 0x52, 0x0f, 0xae, 0x27, 0x56, 0x31, 0x30, 0x60, 0xad, 0xc9, 0xbd, 0x73, - 0x2c, 0x39, 0xee, 0x90, 0xd8, 0x75, 0xb0, 0x25, 0x21, 0x60, 0x7b, 0x2a, - 0x7f, 0x02, 0xfd, 0x82, 0x85, 0x1f, 0x74, 0x4f, 0x92, 0x34, 0x73, 0x5c, - 0x1d, 0x00, 0xa0, 0xb0, 0xc0, 0xea, 0x98, 0xe2, 0xbe, 0x01, 0x14, 0x58, - 0x17, 0x28, 0x22, 0x8a, 0x77, 0x5d, 0x50, 0x25, 0xcd, 0x9a, 0x6c, 0xa6, - 0xe5, 0x0c, 0xe5, 0xab, 0x28, 0xc3, 0xb2, 0x20, 0x89, 0xf0, 0x07, 0x24, - 0x1e, 0x95, 0xc2, 0x2e, 0xc0, 0xe5, 0xe9, 0xec, 0xf6, 0x3d, 0x12, 0x07, - 0x48, 0x3d, 0xd2, 0xc3, 0x23, 0x56, 0x41, 0xec, 0xd3, 0xdf, 0x35, 0x4b, - 0xc8, 0xe7, 0xf6, 0x86, 0x05, 0x52, 0x10, 0x43, 0x9a, 0x8c, 0x17, 0x7c, - 0x8b, 0xaa, 0xbc, 0x78, 0xe0, 0xf0, 0x45, 0x3b, 0xac, 0x80, 0x55, 0xfe, - 0x28, 0x93, 0xe1, 0x0a, 0x11, 0x68, 0xf4, 0x52, 0x57, 0x6f, 0xfe, 0x48, - 0x0b, 0x5b, 0x5d, 0x1a, 0x6a, 0x67, 0x73, 0x99, 0x82, 0xb4, 0x9e, 0x43, - 0x60, 0x3e, 0xc7, 0x5b, 0x2a, 0x12, 0x6e, 0x1a, 0xee, 0xcb, 0x39, 0xae, - 0xc3, 0x35, 0x9d, 0xa8, 0xbc, 0x5d, 0xb0, 0x2f, 0xc3, 0x02, 0x03, 0x01, - 0x00, 0x01, 0xa3, 0x82, 0x01, 0x77, 0x30, 0x82, 0x01, 0x73, 0x30, 0x1f, - 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xad, - 0xbd, 0x98, 0x7a, 0x34, 0xb4, 0x26, 0xf7, 0xfa, 0xc4, 0x26, 0x54, 0xef, - 0x03, 0xbd, 0xe0, 0x24, 0xcb, 0x54, 0x1a, 0x30, 0x1d, 0x06, 0x03, 0x55, - 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x99, 0xe4, 0x40, 0x5f, 0x6b, 0x14, - 0x5e, 0x3e, 0x05, 0xd9, 0xdd, 0xd3, 0x63, 0x54, 0xfc, 0x62, 0xb8, 0xf7, - 0x00, 0xac, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, - 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, - 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, - 0x01, 0x00, 0x30, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x0a, 0x30, - 0x08, 0x30, 0x06, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x44, 0x06, - 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3d, 0x30, 0x3b, 0x30, 0x39, 0xa0, 0x37, - 0xa0, 0x35, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, - 0x72, 0x6c, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, - 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x41, 0x52, - 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x81, 0xb3, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x81, 0xa6, 0x30, - 0x81, 0xa3, 0x30, 0x3f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x30, 0x02, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, - 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, - 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x41, 0x52, - 0x6f, 0x6f, 0x74, 0x2e, 0x70, 0x37, 0x63, 0x30, 0x39, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, - 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x55, 0x54, 0x4e, 0x53, 0x47, 0x43, - 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x25, 0x06, 0x08, 0x2b, 0x06, - 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x19, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, - 0x03, 0x82, 0x01, 0x01, 0x00, 0x9c, 0x36, 0xe3, 0x4e, 0xae, 0xf1, 0x8a, - 0xbb, 0x6c, 0x97, 0x8c, 0x8f, 0x4b, 0x67, 0xd0, 0x9f, 0xd8, 0x84, 0xaa, - 0x9f, 0x21, 0x5f, 0x35, 0xa1, 0x5b, 0xc4, 0x2b, 0x63, 0x0d, 0xe8, 0xbc, - 0x77, 0x5d, 0xa7, 0xc4, 0x37, 0xfd, 0x4b, 0x2d, 0x9e, 0xe8, 0x1d, 0x69, - 0xa1, 0xc0, 0x84, 0xcc, 0xd1, 0x6d, 0x8b, 0xf3, 0x81, 0xcb, 0x9f, 0x4b, - 0x74, 0xb0, 0x49, 0x2a, 0x31, 0xe8, 0x37, 0x40, 0xeb, 0x1f, 0xd9, 0x97, - 0xa3, 0x1a, 0x11, 0xd5, 0x26, 0xa7, 0x6e, 0x0f, 0xba, 0xd5, 0xbe, 0x2c, - 0xfd, 0xb4, 0x91, 0x64, 0xdc, 0xbe, 0x3b, 0x19, 0x50, 0x0d, 0x7a, 0x95, - 0xf3, 0x04, 0x13, 0xa9, 0xbb, 0x47, 0x0f, 0x8b, 0x5c, 0xd1, 0xac, 0xc2, - 0x7b, 0x77, 0x21, 0x50, 0xdd, 0x5b, 0xab, 0xee, 0xf4, 0xa6, 0xd8, 0xd4, - 0x4a, 0x53, 0x6b, 0x4d, 0xad, 0xb8, 0xc8, 0xe7, 0xe6, 0x52, 0x58, 0x4d, - 0x43, 0x4c, 0xc2, 0xa2, 0x23, 0x4f, 0x0e, 0xc0, 0x20, 0x39, 0xaf, 0xdf, - 0x4f, 0x42, 0x5b, 0x1e, 0xd3, 0x09, 0xf4, 0x18, 0x09, 0x59, 0x2a, 0xd9, - 0xe8, 0x4a, 0x18, 0xbf, 0x32, 0xfb, 0xfa, 0x2d, 0x64, 0x8b, 0x87, 0xca, - 0x5b, 0x2b, 0xe8, 0xb8, 0x0b, 0x7e, 0xbe, 0x17, 0x12, 0xc7, 0x03, 0x82, - 0x29, 0xaf, 0x58, 0xaf, 0x85, 0x84, 0x5d, 0x3d, 0x0a, 0xdf, 0x23, 0x51, - 0xc3, 0xcd, 0xaf, 0x10, 0xbf, 0x80, 0x69, 0x77, 0x91, 0x0a, 0x4f, 0xe5, - 0xba, 0xe1, 0xad, 0x9b, 0xce, 0xdf, 0x33, 0x4e, 0x30, 0x3b, 0xe9, 0x8f, - 0x66, 0x7f, 0x82, 0xfa, 0x6b, 0xfa, 0xdb, 0xa3, 0xc0, 0x73, 0x00, 0xe3, - 0xd6, 0x12, 0xaf, 0x4d, 0xf2, 0x0f, 0x5a, 0x14, 0x51, 0x1f, 0x6d, 0xb8, - 0x86, 0x81, 0x62, 0x07, 0xce, 0x5c, 0x72, 0xc2, 0x4f, 0xf3, 0x57, 0x2a, - 0x71, 0xd9, 0xd4, 0x97, 0x85, 0xe6, 0x18, 0x53, 0xb7, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 6f:25:dc:15:af:df:5e:a3:08:56:0c:3b:7a:4f:c7:f8 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root - Validity - Not Before: May 30 10:48:38 2000 GMT - Not After : May 30 10:48:38 2020 GMT - Subject: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO Certification Authority - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:d0:40:8b:8b:72:e3:91:1b:f7:51:c1:1b:54:04: - 98:d3:a9:bf:c1:e6:8a:5d:3b:87:fb:bb:88:ce:0d: - e3:2f:3f:06:96:f0:a2:29:50:99:ae:db:3b:a1:57: - b0:74:51:71:cd:ed:42:91:4d:41:fe:a9:c8:d8:6a: - 86:77:44:bb:59:66:97:50:5e:b4:d4:2c:70:44:cf: - da:37:95:42:69:3c:30:c4:71:b3:52:f0:21:4d:a1: - d8:ba:39:7c:1c:9e:a3:24:9d:f2:83:16:98:aa:16: - 7c:43:9b:15:5b:b7:ae:34:91:fe:d4:62:26:18:46: - 9a:3f:eb:c1:f9:f1:90:57:eb:ac:7a:0d:8b:db:72: - 30:6a:66:d5:e0:46:a3:70:dc:68:d9:ff:04:48:89: - 77:de:b5:e9:fb:67:6d:41:e9:bc:39:bd:32:d9:62: - 02:f1:b1:a8:3d:6e:37:9c:e2:2f:e2:d3:a2:26:8b: - c6:b8:55:43:88:e1:23:3e:a5:d2:24:39:6a:47:ab: - 00:d4:a1:b3:a9:25:fe:0d:3f:a7:1d:ba:d3:51:c1: - 0b:a4:da:ac:38:ef:55:50:24:05:65:46:93:34:4f: - 2d:8d:ad:c6:d4:21:19:d2:8e:ca:05:61:71:07:73: - 47:e5:8a:19:12:bd:04:4d:ce:4e:9c:a5:48:ac:bb: - 26:f7 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Authority Key Identifier: - keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A - - X509v3 Subject Key Identifier: - 0B:58:E5:8B:C6:4C:15:37:A4:40:A9:30:A9:21:BE:47:36:5A:56:FF - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.usertrust.com/AddTrustExternalCARoot.crl - - Authority Information Access: - CA Issuers - URI:http://crt.usertrust.com/AddTrustExternalCARoot.p7c - CA Issuers - URI:http://crt.usertrust.com/AddTrustUTNSGCCA.crt - OCSP - URI:http://ocsp.usertrust.com - - Signature Algorithm: sha1WithRSAEncryption - 07:60:93:99:aa:ce:d0:d3:47:d0:37:33:de:3f:64:b7:e5:2e: - a3:25:0c:d5:33:1d:0d:8d:ab:f6:7e:46:7b:59:06:92:e3:82: - c4:e7:f5:f6:f3:d9:05:cf:49:34:2d:37:5f:f4:25:c7:f0:fb: - 6b:23:77:f1:f1:40:d7:4c:bb:49:45:31:dd:00:28:67:b7:29: - 4c:75:a8:1f:79:31:c9:36:37:0f:ca:35:4f:8c:f1:7e:de:fc: - 46:ab:bf:68:9b:70:23:30:2e:b7:c5:5c:7b:8a:fb:18:13:79: - 4b:92:42:8c:dc:2c:ab:6c:22:b7:28:53:b3:1a:4a:ce:1b:fb: - 28:0e:b7:3a:a4:da:0d:f7:40:32:4f:df:6f:bb:01:50:fc:87: - d3:76:d9:fc:fb:b6:84:03:ca:c9:36:18:f7:dd:6c:db:bb:ba: - 81:1c:a6:ad:fe:28:f9:cf:b9:a2:71:5d:19:05:ea:4a:46:dc: - 73:41:ef:89:94:42:b1:43:88:6f:35:17:af:1e:60:83:ac:7a: - 8c:10:7b:9f:c9:f6:83:6d:9e:fa:88:ee:3e:dd:ee:9e:b0:bf: - e0:6a:b9:d0:9f:07:b2:09:13:9a:f5:a4:e5:c8:5b:79:a7:47: - 35:33:68:e5:55:9e:aa:5b:cb:30:0b:9d:c7:0f:bf:68:44:81: - 97:8b:51:4a ------BEGIN CERTIFICATE----- -MIIE8TCCA9mgAwIBAgIQbyXcFa/fXqMIVgw7ek/H+DANBgkqhkiG9w0BAQUFADBv -MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk -ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF -eHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFow -gYExCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO -BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMScwJQYD -VQQDEx5DT01PRE8gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQDQQIuLcuORG/dRwRtUBJjTqb/B5opdO4f7u4jO -DeMvPwaW8KIpUJmu2zuhV7B0UXHN7UKRTUH+qcjYaoZ3RLtZZpdQXrTULHBEz9o3 -lUJpPDDEcbNS8CFNodi6OXwcnqMknfKDFpiqFnxDmxVbt640kf7UYiYYRpo/68H5 -8ZBX66x6DYvbcjBqZtXgRqNw3GjZ/wRIiXfeten7Z21B6bw5vTLZYgLxsag9bjec -4i/i06Imi8a4VUOI4SM+pdIkOWpHqwDUobOpJf4NP6cdutNRwQuk2qw471VQJAVl -RpM0Ty2NrcbUIRnSjsoFYXEHc0flihkSvQRNzk6cpUisuyb3AgMBAAGjggF0MIIB -cDAfBgNVHSMEGDAWgBStvZh6NLQm9/rEJlTvA73gJMtUGjAdBgNVHQ4EFgQUC1jl -i8ZMFTekQKkwqSG+RzZaVv8wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB -Af8wEQYDVR0gBAowCDAGBgRVHSAAMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9j -cmwudXNlcnRydXN0LmNvbS9BZGRUcnVzdEV4dGVybmFsQ0FSb290LmNybDCBswYI -KwYBBQUHAQEEgaYwgaMwPwYIKwYBBQUHMAKGM2h0dHA6Ly9jcnQudXNlcnRydXN0 -LmNvbS9BZGRUcnVzdEV4dGVybmFsQ0FSb290LnA3YzA5BggrBgEFBQcwAoYtaHR0 -cDovL2NydC51c2VydHJ1c3QuY29tL0FkZFRydXN0VVROU0dDQ0EuY3J0MCUGCCsG -AQUFBzABhhlodHRwOi8vb2NzcC51c2VydHJ1c3QuY29tMA0GCSqGSIb3DQEBBQUA -A4IBAQAHYJOZqs7Q00fQNzPeP2S35S6jJQzVMx0Njav2fkZ7WQaS44LE5/X289kF -z0k0LTdf9CXH8PtrI3fx8UDXTLtJRTHdAChntylMdagfeTHJNjcPyjVPjPF+3vxG -q79om3AjMC63xVx7ivsYE3lLkkKM3CyrbCK3KFOzGkrOG/soDrc6pNoN90AyT99v -uwFQ/IfTdtn8+7aEA8rJNhj33Wzbu7qBHKat/ij5z7micV0ZBepKRtxzQe+JlEKx -Q4hvNRevHmCDrHqMEHufyfaDbZ76iO4+3e6esL/garnQnweyCROa9aTlyFt5p0c1 -M2jlVZ6qW8swC53HD79oRIGXi1FK ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert42[] = { - 0x30, 0x82, 0x04, 0xf1, 0x30, 0x82, 0x03, 0xd9, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x6f, 0x25, 0xdc, 0x15, 0xaf, 0xdf, 0x5e, 0xa3, 0x08, - 0x56, 0x0c, 0x3b, 0x7a, 0x4f, 0xc7, 0xf8, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x6f, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x53, - 0x45, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, - 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41, 0x42, 0x31, - 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x64, - 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x20, 0x54, 0x54, 0x50, 0x20, 0x4e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x19, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, - 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x52, - 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x35, 0x33, - 0x30, 0x31, 0x30, 0x34, 0x38, 0x33, 0x38, 0x5a, 0x17, 0x0d, 0x32, 0x30, - 0x30, 0x35, 0x33, 0x30, 0x31, 0x30, 0x34, 0x38, 0x33, 0x38, 0x5a, 0x30, - 0x81, 0x81, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x47, 0x42, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, - 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4d, 0x61, - 0x6e, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0e, - 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6c, 0x66, 0x6f, - 0x72, 0x64, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x11, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x43, 0x41, 0x20, 0x4c, - 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x1e, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 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, 0xd0, 0x40, 0x8b, 0x8b, - 0x72, 0xe3, 0x91, 0x1b, 0xf7, 0x51, 0xc1, 0x1b, 0x54, 0x04, 0x98, 0xd3, - 0xa9, 0xbf, 0xc1, 0xe6, 0x8a, 0x5d, 0x3b, 0x87, 0xfb, 0xbb, 0x88, 0xce, - 0x0d, 0xe3, 0x2f, 0x3f, 0x06, 0x96, 0xf0, 0xa2, 0x29, 0x50, 0x99, 0xae, - 0xdb, 0x3b, 0xa1, 0x57, 0xb0, 0x74, 0x51, 0x71, 0xcd, 0xed, 0x42, 0x91, - 0x4d, 0x41, 0xfe, 0xa9, 0xc8, 0xd8, 0x6a, 0x86, 0x77, 0x44, 0xbb, 0x59, - 0x66, 0x97, 0x50, 0x5e, 0xb4, 0xd4, 0x2c, 0x70, 0x44, 0xcf, 0xda, 0x37, - 0x95, 0x42, 0x69, 0x3c, 0x30, 0xc4, 0x71, 0xb3, 0x52, 0xf0, 0x21, 0x4d, - 0xa1, 0xd8, 0xba, 0x39, 0x7c, 0x1c, 0x9e, 0xa3, 0x24, 0x9d, 0xf2, 0x83, - 0x16, 0x98, 0xaa, 0x16, 0x7c, 0x43, 0x9b, 0x15, 0x5b, 0xb7, 0xae, 0x34, - 0x91, 0xfe, 0xd4, 0x62, 0x26, 0x18, 0x46, 0x9a, 0x3f, 0xeb, 0xc1, 0xf9, - 0xf1, 0x90, 0x57, 0xeb, 0xac, 0x7a, 0x0d, 0x8b, 0xdb, 0x72, 0x30, 0x6a, - 0x66, 0xd5, 0xe0, 0x46, 0xa3, 0x70, 0xdc, 0x68, 0xd9, 0xff, 0x04, 0x48, - 0x89, 0x77, 0xde, 0xb5, 0xe9, 0xfb, 0x67, 0x6d, 0x41, 0xe9, 0xbc, 0x39, - 0xbd, 0x32, 0xd9, 0x62, 0x02, 0xf1, 0xb1, 0xa8, 0x3d, 0x6e, 0x37, 0x9c, - 0xe2, 0x2f, 0xe2, 0xd3, 0xa2, 0x26, 0x8b, 0xc6, 0xb8, 0x55, 0x43, 0x88, - 0xe1, 0x23, 0x3e, 0xa5, 0xd2, 0x24, 0x39, 0x6a, 0x47, 0xab, 0x00, 0xd4, - 0xa1, 0xb3, 0xa9, 0x25, 0xfe, 0x0d, 0x3f, 0xa7, 0x1d, 0xba, 0xd3, 0x51, - 0xc1, 0x0b, 0xa4, 0xda, 0xac, 0x38, 0xef, 0x55, 0x50, 0x24, 0x05, 0x65, - 0x46, 0x93, 0x34, 0x4f, 0x2d, 0x8d, 0xad, 0xc6, 0xd4, 0x21, 0x19, 0xd2, - 0x8e, 0xca, 0x05, 0x61, 0x71, 0x07, 0x73, 0x47, 0xe5, 0x8a, 0x19, 0x12, - 0xbd, 0x04, 0x4d, 0xce, 0x4e, 0x9c, 0xa5, 0x48, 0xac, 0xbb, 0x26, 0xf7, - 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x74, 0x30, 0x82, 0x01, - 0x70, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, - 0x80, 0x14, 0xad, 0xbd, 0x98, 0x7a, 0x34, 0xb4, 0x26, 0xf7, 0xfa, 0xc4, - 0x26, 0x54, 0xef, 0x03, 0xbd, 0xe0, 0x24, 0xcb, 0x54, 0x1a, 0x30, 0x1d, - 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x0b, 0x58, 0xe5, - 0x8b, 0xc6, 0x4c, 0x15, 0x37, 0xa4, 0x40, 0xa9, 0x30, 0xa9, 0x21, 0xbe, - 0x47, 0x36, 0x5a, 0x56, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, - 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0f, 0x06, - 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, - 0x01, 0xff, 0x30, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x0a, 0x30, - 0x08, 0x30, 0x06, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x44, 0x06, - 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3d, 0x30, 0x3b, 0x30, 0x39, 0xa0, 0x37, - 0xa0, 0x35, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, - 0x72, 0x6c, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, - 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x41, 0x52, - 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x81, 0xb3, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x81, 0xa6, 0x30, - 0x81, 0xa3, 0x30, 0x3f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x30, 0x02, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, - 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, - 0x74, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x41, 0x52, - 0x6f, 0x6f, 0x74, 0x2e, 0x70, 0x37, 0x63, 0x30, 0x39, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, - 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x55, 0x54, 0x4e, 0x53, 0x47, 0x43, - 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x25, 0x06, 0x08, 0x2b, 0x06, - 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x19, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, - 0x03, 0x82, 0x01, 0x01, 0x00, 0x07, 0x60, 0x93, 0x99, 0xaa, 0xce, 0xd0, - 0xd3, 0x47, 0xd0, 0x37, 0x33, 0xde, 0x3f, 0x64, 0xb7, 0xe5, 0x2e, 0xa3, - 0x25, 0x0c, 0xd5, 0x33, 0x1d, 0x0d, 0x8d, 0xab, 0xf6, 0x7e, 0x46, 0x7b, - 0x59, 0x06, 0x92, 0xe3, 0x82, 0xc4, 0xe7, 0xf5, 0xf6, 0xf3, 0xd9, 0x05, - 0xcf, 0x49, 0x34, 0x2d, 0x37, 0x5f, 0xf4, 0x25, 0xc7, 0xf0, 0xfb, 0x6b, - 0x23, 0x77, 0xf1, 0xf1, 0x40, 0xd7, 0x4c, 0xbb, 0x49, 0x45, 0x31, 0xdd, - 0x00, 0x28, 0x67, 0xb7, 0x29, 0x4c, 0x75, 0xa8, 0x1f, 0x79, 0x31, 0xc9, - 0x36, 0x37, 0x0f, 0xca, 0x35, 0x4f, 0x8c, 0xf1, 0x7e, 0xde, 0xfc, 0x46, - 0xab, 0xbf, 0x68, 0x9b, 0x70, 0x23, 0x30, 0x2e, 0xb7, 0xc5, 0x5c, 0x7b, - 0x8a, 0xfb, 0x18, 0x13, 0x79, 0x4b, 0x92, 0x42, 0x8c, 0xdc, 0x2c, 0xab, - 0x6c, 0x22, 0xb7, 0x28, 0x53, 0xb3, 0x1a, 0x4a, 0xce, 0x1b, 0xfb, 0x28, - 0x0e, 0xb7, 0x3a, 0xa4, 0xda, 0x0d, 0xf7, 0x40, 0x32, 0x4f, 0xdf, 0x6f, - 0xbb, 0x01, 0x50, 0xfc, 0x87, 0xd3, 0x76, 0xd9, 0xfc, 0xfb, 0xb6, 0x84, - 0x03, 0xca, 0xc9, 0x36, 0x18, 0xf7, 0xdd, 0x6c, 0xdb, 0xbb, 0xba, 0x81, - 0x1c, 0xa6, 0xad, 0xfe, 0x28, 0xf9, 0xcf, 0xb9, 0xa2, 0x71, 0x5d, 0x19, - 0x05, 0xea, 0x4a, 0x46, 0xdc, 0x73, 0x41, 0xef, 0x89, 0x94, 0x42, 0xb1, - 0x43, 0x88, 0x6f, 0x35, 0x17, 0xaf, 0x1e, 0x60, 0x83, 0xac, 0x7a, 0x8c, - 0x10, 0x7b, 0x9f, 0xc9, 0xf6, 0x83, 0x6d, 0x9e, 0xfa, 0x88, 0xee, 0x3e, - 0xdd, 0xee, 0x9e, 0xb0, 0xbf, 0xe0, 0x6a, 0xb9, 0xd0, 0x9f, 0x07, 0xb2, - 0x09, 0x13, 0x9a, 0xf5, 0xa4, 0xe5, 0xc8, 0x5b, 0x79, 0xa7, 0x47, 0x35, - 0x33, 0x68, 0xe5, 0x55, 0x9e, 0xaa, 0x5b, 0xcb, 0x30, 0x0b, 0x9d, 0xc7, - 0x0f, 0xbf, 0x68, 0x44, 0x81, 0x97, 0x8b, 0x51, 0x4a, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 946072060 (0x3863e9fc) - Signature Algorithm: sha1WithRSAEncryption - Issuer: O=Entrust.net, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Certification Authority (2048) - Validity - Not Before: Dec 10 20:43:54 2009 GMT - Not After : Dec 10 21:13:54 2019 GMT - Subject: C=US, O=Entrust, Inc., OU=www.entrust.net/rpa is incorporated by reference, OU=(c) 2009 Entrust, Inc., CN=Entrust Certification Authority - L1C - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:97:a3:2d:3c:9e:de:05:da:13:c2:11:8d:9d:8e: - e3:7f:c7:4b:7e:5a:9f:b3:ff:62:ab:73:c8:28:6b: - ba:10:64:82:87:13:cd:57:18:ff:28:ce:c0:e6:0e: - 06:91:50:29:83:d1:f2:c3:2a:db:d8:db:4e:04:cc: - 00:eb:8b:b6:96:dc:bc:aa:fa:52:77:04:c1:db:19: - e4:ae:9c:fd:3c:8b:03:ef:4d:bc:1a:03:65:f9:c1: - b1:3f:72:86:f2:38:aa:19:ae:10:88:78:28:da:75: - c3:3d:02:82:02:9c:b9:c1:65:77:76:24:4c:98:f7: - 6d:31:38:fb:db:fe:db:37:02:76:a1:18:97:a6:cc: - de:20:09:49:36:24:69:42:f6:e4:37:62:f1:59:6d: - a9:3c:ed:34:9c:a3:8e:db:dc:3a:d7:f7:0a:6f:ef: - 2e:d8:d5:93:5a:7a:ed:08:49:68:e2:41:e3:5a:90: - c1:86:55:fc:51:43:9d:e0:b2:c4:67:b4:cb:32:31: - 25:f0:54:9f:4b:d1:6f:db:d4:dd:fc:af:5e:6c:78: - 90:95:de:ca:3a:48:b9:79:3c:9b:19:d6:75:05:a0: - f9:88:d7:c1:e8:a5:09:e4:1a:15:dc:87:23:aa:b2: - 75:8c:63:25:87:d8:f8:3d:a6:c2:cc:66:ff:a5:66: - 68:55 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE - Authority Information Access: - OCSP - URI:http://ocsp.entrust.net - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.entrust.net/2048ca.crl - - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: http://www.entrust.net/rpa - - X509v3 Subject Key Identifier: - 1E:F1:AB:89:06:F8:49:0F:01:33:77:EE:14:7A:EE:19:7C:93:28:4D - X509v3 Authority Key Identifier: - keyid:55:E4:81:D1:11:80:BE:D8:89:B9:08:A3:31:F9:A1:24:09:16:B9:70 - - Signature Algorithm: sha1WithRSAEncryption - 07:f6:5f:82:84:7f:80:40:c7:90:34:46:42:24:03:ce:2f:ab: - ba:83:9e:25:73:0d:ed:ac:05:69:c6:87:ed:a3:5c:f2:57:c1: - b1:49:76:9a:4d:f2:3f:dd:e4:0e:fe:0b:3e:b9:98:d9:32:95: - 1d:32:f4:01:ee:9c:c8:c8:e5:3f:e0:53:76:62:fc:dd:ab:6d: - 3d:94:90:f2:c0:b3:3c:98:27:36:5e:28:97:22:fc:1b:40:d3: - 2b:0d:ad:b5:57:6d:df:0f:e3:4b:ef:73:02:10:65:fa:1b:d0: - ac:31:d5:e3:0f:e8:ba:32:30:83:ee:4a:d0:bf:df:22:90:7a: - be:ec:3a:1b:c4:49:04:1d:f1:ae:80:77:3c:42:08:db:a7:3b: - 28:a6:80:01:03:e6:39:a3:eb:df:80:59:1b:f3:2c:be:dc:72: - 44:79:a0:6c:07:a5:6d:4d:44:8e:42:68:ca:94:7c:2e:36:ba: - 85:9e:cd:aa:c4:5e:3c:54:be:fe:2f:ea:69:9d:1c:1e:29:9b: - 96:d8:c8:fe:51:90:f1:24:a6:90:06:b3:f0:29:a2:ff:78:2e: - 77:5c:45:21:d9:44:00:31:f3:be:32:4f:f5:0a:32:0d:fc:fc: - ba:16:76:56:b2:d6:48:92:f2:8b:a6:3e:b7:ac:5c:69:ea:0b: - 3f:66:45:b9 ------BEGIN CERTIFICATE----- -MIIE8jCCA9qgAwIBAgIEOGPp/DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML -RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp -bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 -IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw0wOTEyMTAyMDQzNTRaFw0xOTEy -MTAyMTEzNTRaMIGxMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNRW50cnVzdCwgSW5j -LjE5MDcGA1UECxMwd3d3LmVudHJ1c3QubmV0L3JwYSBpcyBpbmNvcnBvcmF0ZWQg -YnkgcmVmZXJlbmNlMR8wHQYDVQQLExYoYykgMjAwOSBFbnRydXN0LCBJbmMuMS4w -LAYDVQQDEyVFbnRydXN0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gTDFDMIIB -IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl6MtPJ7eBdoTwhGNnY7jf8dL -flqfs/9iq3PIKGu6EGSChxPNVxj/KM7A5g4GkVApg9Hywyrb2NtOBMwA64u2lty8 -qvpSdwTB2xnkrpz9PIsD7028GgNl+cGxP3KG8jiqGa4QiHgo2nXDPQKCApy5wWV3 -diRMmPdtMTj72/7bNwJ2oRiXpszeIAlJNiRpQvbkN2LxWW2pPO00nKOO29w61/cK -b+8u2NWTWnrtCElo4kHjWpDBhlX8UUOd4LLEZ7TLMjEl8FSfS9Fv29Td/K9ebHiQ -ld7KOki5eTybGdZ1BaD5iNfB6KUJ5BoV3IcjqrJ1jGMlh9j4PabCzGb/pWZoVQID -AQABo4IBCzCCAQcwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wMwYI -KwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5l -dDAyBgNVHR8EKzApMCegJaAjhiFodHRwOi8vY3JsLmVudHJ1c3QubmV0LzIwNDhj -YS5jcmwwOwYDVR0gBDQwMjAwBgRVHSAAMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly93 -d3cuZW50cnVzdC5uZXQvcnBhMB0GA1UdDgQWBBQe8auJBvhJDwEzd+4Ueu4ZfJMo -TTAfBgNVHSMEGDAWgBRV5IHREYC+2Im5CKMx+aEkCRa5cDANBgkqhkiG9w0BAQUF -AAOCAQEAB/ZfgoR/gEDHkDRGQiQDzi+ruoOeJXMN7awFacaH7aNc8lfBsUl2mk3y -P93kDv4LPrmY2TKVHTL0Ae6cyMjlP+BTdmL83attPZSQ8sCzPJgnNl4olyL8G0DT -Kw2ttVdt3w/jS+9zAhBl+hvQrDHV4w/oujIwg+5K0L/fIpB6vuw6G8RJBB3xroB3 -PEII26c7KKaAAQPmOaPr34BZG/MsvtxyRHmgbAelbU1EjkJoypR8Lja6hZ7NqsRe -PFS+/i/qaZ0cHimbltjI/lGQ8SSmkAaz8Cmi/3gud1xFIdlEADHzvjJP9QoyDfz8 -uhZ2VrLWSJLyi6Y+t6xcaeoLP2ZFuQ== ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert43[] = { - 0x30, 0x82, 0x04, 0xf2, 0x30, 0x82, 0x03, 0xda, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x04, 0x38, 0x63, 0xe9, 0xfc, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, - 0xb4, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, - 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x31, - 0x40, 0x30, 0x3e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x14, 0x37, 0x77, 0x77, - 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, - 0x74, 0x2f, 0x43, 0x50, 0x53, 0x5f, 0x32, 0x30, 0x34, 0x38, 0x20, 0x69, - 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x20, 0x62, 0x79, 0x20, 0x72, 0x65, - 0x66, 0x2e, 0x20, 0x28, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x20, 0x6c, - 0x69, 0x61, 0x62, 0x2e, 0x29, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, - 0x04, 0x0b, 0x13, 0x1c, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, 0x39, 0x39, - 0x20, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, - 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x33, 0x30, 0x31, - 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2a, 0x45, 0x6e, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x28, 0x32, 0x30, 0x34, 0x38, - 0x29, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x31, 0x32, 0x31, 0x30, 0x32, - 0x30, 0x34, 0x33, 0x35, 0x34, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x31, 0x32, - 0x31, 0x30, 0x32, 0x31, 0x31, 0x33, 0x35, 0x34, 0x5a, 0x30, 0x81, 0xb1, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, - 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, - 0x2e, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x30, - 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, - 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x70, 0x61, 0x20, 0x69, 0x73, 0x20, 0x69, - 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, - 0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, - 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x28, - 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x39, 0x20, 0x45, 0x6e, 0x74, 0x72, - 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, - 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x45, 0x6e, 0x74, 0x72, - 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x4c, 0x31, 0x43, 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, 0x97, 0xa3, 0x2d, 0x3c, 0x9e, 0xde, - 0x05, 0xda, 0x13, 0xc2, 0x11, 0x8d, 0x9d, 0x8e, 0xe3, 0x7f, 0xc7, 0x4b, - 0x7e, 0x5a, 0x9f, 0xb3, 0xff, 0x62, 0xab, 0x73, 0xc8, 0x28, 0x6b, 0xba, - 0x10, 0x64, 0x82, 0x87, 0x13, 0xcd, 0x57, 0x18, 0xff, 0x28, 0xce, 0xc0, - 0xe6, 0x0e, 0x06, 0x91, 0x50, 0x29, 0x83, 0xd1, 0xf2, 0xc3, 0x2a, 0xdb, - 0xd8, 0xdb, 0x4e, 0x04, 0xcc, 0x00, 0xeb, 0x8b, 0xb6, 0x96, 0xdc, 0xbc, - 0xaa, 0xfa, 0x52, 0x77, 0x04, 0xc1, 0xdb, 0x19, 0xe4, 0xae, 0x9c, 0xfd, - 0x3c, 0x8b, 0x03, 0xef, 0x4d, 0xbc, 0x1a, 0x03, 0x65, 0xf9, 0xc1, 0xb1, - 0x3f, 0x72, 0x86, 0xf2, 0x38, 0xaa, 0x19, 0xae, 0x10, 0x88, 0x78, 0x28, - 0xda, 0x75, 0xc3, 0x3d, 0x02, 0x82, 0x02, 0x9c, 0xb9, 0xc1, 0x65, 0x77, - 0x76, 0x24, 0x4c, 0x98, 0xf7, 0x6d, 0x31, 0x38, 0xfb, 0xdb, 0xfe, 0xdb, - 0x37, 0x02, 0x76, 0xa1, 0x18, 0x97, 0xa6, 0xcc, 0xde, 0x20, 0x09, 0x49, - 0x36, 0x24, 0x69, 0x42, 0xf6, 0xe4, 0x37, 0x62, 0xf1, 0x59, 0x6d, 0xa9, - 0x3c, 0xed, 0x34, 0x9c, 0xa3, 0x8e, 0xdb, 0xdc, 0x3a, 0xd7, 0xf7, 0x0a, - 0x6f, 0xef, 0x2e, 0xd8, 0xd5, 0x93, 0x5a, 0x7a, 0xed, 0x08, 0x49, 0x68, - 0xe2, 0x41, 0xe3, 0x5a, 0x90, 0xc1, 0x86, 0x55, 0xfc, 0x51, 0x43, 0x9d, - 0xe0, 0xb2, 0xc4, 0x67, 0xb4, 0xcb, 0x32, 0x31, 0x25, 0xf0, 0x54, 0x9f, - 0x4b, 0xd1, 0x6f, 0xdb, 0xd4, 0xdd, 0xfc, 0xaf, 0x5e, 0x6c, 0x78, 0x90, - 0x95, 0xde, 0xca, 0x3a, 0x48, 0xb9, 0x79, 0x3c, 0x9b, 0x19, 0xd6, 0x75, - 0x05, 0xa0, 0xf9, 0x88, 0xd7, 0xc1, 0xe8, 0xa5, 0x09, 0xe4, 0x1a, 0x15, - 0xdc, 0x87, 0x23, 0xaa, 0xb2, 0x75, 0x8c, 0x63, 0x25, 0x87, 0xd8, 0xf8, - 0x3d, 0xa6, 0xc2, 0xcc, 0x66, 0xff, 0xa5, 0x66, 0x68, 0x55, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x0b, 0x30, 0x82, 0x01, 0x07, 0x30, - 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, - 0x02, 0x01, 0x06, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, - 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x33, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x27, 0x30, 0x25, - 0x30, 0x23, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, - 0x86, 0x17, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, - 0x70, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, - 0x74, 0x30, 0x32, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2b, 0x30, 0x29, - 0x30, 0x27, 0xa0, 0x25, 0xa0, 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x32, 0x30, 0x34, 0x38, 0x63, - 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3b, 0x06, 0x03, 0x55, 0x1d, 0x20, - 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, - 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, - 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, - 0x65, 0x74, 0x2f, 0x72, 0x70, 0x61, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, - 0x0e, 0x04, 0x16, 0x04, 0x14, 0x1e, 0xf1, 0xab, 0x89, 0x06, 0xf8, 0x49, - 0x0f, 0x01, 0x33, 0x77, 0xee, 0x14, 0x7a, 0xee, 0x19, 0x7c, 0x93, 0x28, - 0x4d, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, - 0x80, 0x14, 0x55, 0xe4, 0x81, 0xd1, 0x11, 0x80, 0xbe, 0xd8, 0x89, 0xb9, - 0x08, 0xa3, 0x31, 0xf9, 0xa1, 0x24, 0x09, 0x16, 0xb9, 0x70, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, - 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x07, 0xf6, 0x5f, 0x82, 0x84, 0x7f, - 0x80, 0x40, 0xc7, 0x90, 0x34, 0x46, 0x42, 0x24, 0x03, 0xce, 0x2f, 0xab, - 0xba, 0x83, 0x9e, 0x25, 0x73, 0x0d, 0xed, 0xac, 0x05, 0x69, 0xc6, 0x87, - 0xed, 0xa3, 0x5c, 0xf2, 0x57, 0xc1, 0xb1, 0x49, 0x76, 0x9a, 0x4d, 0xf2, - 0x3f, 0xdd, 0xe4, 0x0e, 0xfe, 0x0b, 0x3e, 0xb9, 0x98, 0xd9, 0x32, 0x95, - 0x1d, 0x32, 0xf4, 0x01, 0xee, 0x9c, 0xc8, 0xc8, 0xe5, 0x3f, 0xe0, 0x53, - 0x76, 0x62, 0xfc, 0xdd, 0xab, 0x6d, 0x3d, 0x94, 0x90, 0xf2, 0xc0, 0xb3, - 0x3c, 0x98, 0x27, 0x36, 0x5e, 0x28, 0x97, 0x22, 0xfc, 0x1b, 0x40, 0xd3, - 0x2b, 0x0d, 0xad, 0xb5, 0x57, 0x6d, 0xdf, 0x0f, 0xe3, 0x4b, 0xef, 0x73, - 0x02, 0x10, 0x65, 0xfa, 0x1b, 0xd0, 0xac, 0x31, 0xd5, 0xe3, 0x0f, 0xe8, - 0xba, 0x32, 0x30, 0x83, 0xee, 0x4a, 0xd0, 0xbf, 0xdf, 0x22, 0x90, 0x7a, - 0xbe, 0xec, 0x3a, 0x1b, 0xc4, 0x49, 0x04, 0x1d, 0xf1, 0xae, 0x80, 0x77, - 0x3c, 0x42, 0x08, 0xdb, 0xa7, 0x3b, 0x28, 0xa6, 0x80, 0x01, 0x03, 0xe6, - 0x39, 0xa3, 0xeb, 0xdf, 0x80, 0x59, 0x1b, 0xf3, 0x2c, 0xbe, 0xdc, 0x72, - 0x44, 0x79, 0xa0, 0x6c, 0x07, 0xa5, 0x6d, 0x4d, 0x44, 0x8e, 0x42, 0x68, - 0xca, 0x94, 0x7c, 0x2e, 0x36, 0xba, 0x85, 0x9e, 0xcd, 0xaa, 0xc4, 0x5e, - 0x3c, 0x54, 0xbe, 0xfe, 0x2f, 0xea, 0x69, 0x9d, 0x1c, 0x1e, 0x29, 0x9b, - 0x96, 0xd8, 0xc8, 0xfe, 0x51, 0x90, 0xf1, 0x24, 0xa6, 0x90, 0x06, 0xb3, - 0xf0, 0x29, 0xa2, 0xff, 0x78, 0x2e, 0x77, 0x5c, 0x45, 0x21, 0xd9, 0x44, - 0x00, 0x31, 0xf3, 0xbe, 0x32, 0x4f, 0xf5, 0x0a, 0x32, 0x0d, 0xfc, 0xfc, - 0xba, 0x16, 0x76, 0x56, 0xb2, 0xd6, 0x48, 0x92, 0xf2, 0x8b, 0xa6, 0x3e, - 0xb7, 0xac, 0x5c, 0x69, 0xea, 0x0b, 0x3f, 0x66, 0x45, 0xb9, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 16:90:c3:29:b6:78:06:07:51:1f:05:b0:34:48:46:cb - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root - Validity - Not Before: Apr 16 00:00:00 2010 GMT - Not After : May 30 10:48:38 2020 GMT - Subject: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO High-Assurance Secure Server CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:e7:87:da:c0:77:e4:bb:3a:fa:6a:24:c8:80:41: - ac:d2:16:13:15:3d:fa:f7:f8:2a:76:dc:a8:2d:39: - 08:ce:48:4a:be:0f:7d:f0:de:ba:bb:47:d5:bd:2d: - d7:1b:ab:0f:20:81:23:08:72:b1:c0:11:95:0d:e6: - ea:a9:87:ff:c7:6e:1e:4f:66:32:ba:53:bc:05:aa: - 1c:2c:0c:ef:4d:37:47:6b:10:0c:db:c5:a0:98:7e: - 58:db:37:d6:ae:e9:06:bd:d7:a8:65:f3:37:b9:c7: - 6d:ce:77:c7:26:e0:d7:74:1f:a6:98:16:bb:0c:6b: - c8:be:77:d0:ef:58:a7:29:a0:b9:b8:69:05:36:cb: - b2:da:58:a3:0b:75:ad:3d:8b:22:82:20:3e:70:86: - 99:1c:b9:4f:cf:77:a4:07:1a:23:63:d1:38:56:84: - ec:bf:8f:c5:4e:f4:18:96:9b:1a:e8:93:ec:8d:af: - 15:9c:24:f0:5a:3b:e8:0f:b9:a8:5a:01:d3:b2:1c: - 60:c9:9c:52:04:dd:92:a7:fe:0c:ac:e2:45:8d:03: - 61:bc:79:e0:77:2e:87:41:3c:58:5f:cb:f5:c5:77: - f2:58:c8:4d:28:d0:9a:fa:f3:73:09:24:68:74:bc: - 20:4c:d8:2c:b0:aa:e8:d9:4e:6d:f2:8c:24:d3:93: - 5d:91 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Authority Key Identifier: - keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A - - X509v3 Subject Key Identifier: - 3F:D5:B5:D0:D6:44:79:50:4A:17:A3:9B:8C:4A:DC:B8:B0:22:64:6B - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.usertrust.com/AddTrustExternalCARoot.crl - - Authority Information Access: - CA Issuers - URI:http://crt.usertrust.com/AddTrustExternalCARoot.p7c - CA Issuers - URI:http://crt.usertrust.com/AddTrustUTNSGCCA.crt - OCSP - URI:http://ocsp.usertrust.com - - Signature Algorithm: sha1WithRSAEncryption - 13:85:1f:52:80:18:c9:53:f7:fe:2e:1a:af:cc:d9:0b:3c:c2: - d3:85:81:10:f0:28:8d:b9:40:7e:2c:9e:8f:d6:36:86:0a:4c: - 14:2d:d6:97:43:92:41:19:37:4b:96:9e:eb:a9:30:79:12:95: - b3:02:36:57:ed:2b:b9:1d:98:1a:a3:18:0a:3f:9b:39:8b:cd: - a1:49:29:4c:2f:f9:d0:95:8c:c8:4d:95:ba:a8:43:cf:33:aa: - 25:2a:5a:0e:aa:27:c9:4e:6b:b1:e6:73:1f:b3:74:04:c3:f3: - 4c:e2:a8:eb:67:b7:5d:b8:08:05:1a:56:9a:54:29:85:f5:29: - 4e:80:3b:95:d0:7b:53:96:11:56:c1:02:d3:ea:b2:7f:ca:8f: - 9c:70:4a:14:8d:5a:b9:16:60:75:d6:cd:27:1e:16:cd:5b:33: - 8e:79:40:cf:28:48:e7:dc:71:16:4e:74:91:75:b9:2a:8c:f1: - 70:ac:26:dd:04:b9:40:c2:85:de:1c:93:40:d0:cc:6e:c3:9b: - aa:ef:60:65:df:60:22:f0:5a:a5:7a:a2:2f:e4:70:73:ee:3c: - d4:26:2b:68:07:c1:20:7a:e8:98:5a:3e:7b:9f:02:8b:62:c0: - 85:81:80:60:35:7e:a5:1d:0c:d2:9c:df:62:45:0d:db:fc:37: - fb:f5:25:22 ------BEGIN CERTIFICATE----- -MIIE/DCCA+SgAwIBAgIQFpDDKbZ4BgdRHwWwNEhGyzANBgkqhkiG9w0BAQUFADBv -MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk -ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF -eHRlcm5hbCBDQSBSb290MB4XDTEwMDQxNjAwMDAwMFoXDTIwMDUzMDEwNDgzOFow -gYkxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO -BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMS8wLQYD -VQQDEyZDT01PRE8gSGlnaC1Bc3N1cmFuY2UgU2VjdXJlIFNlcnZlciBDQTCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOeH2sB35Ls6+mokyIBBrNIWExU9 -+vf4KnbcqC05CM5ISr4PffDeurtH1b0t1xurDyCBIwhyscARlQ3m6qmH/8duHk9m -MrpTvAWqHCwM7003R2sQDNvFoJh+WNs31q7pBr3XqGXzN7nHbc53xybg13QfppgW -uwxryL530O9YpymgubhpBTbLstpYowt1rT2LIoIgPnCGmRy5T893pAcaI2PROFaE -7L+PxU70GJabGuiT7I2vFZwk8Fo76A+5qFoB07IcYMmcUgTdkqf+DKziRY0DYbx5 -4Hcuh0E8WF/L9cV38ljITSjQmvrzcwkkaHS8IEzYLLCq6NlObfKMJNOTXZECAwEA -AaOCAXcwggFzMB8GA1UdIwQYMBaAFK29mHo0tCb3+sQmVO8DveAky1QaMB0GA1Ud -DgQWBBQ/1bXQ1kR5UEoXo5uMSty4sCJkazAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0T -AQH/BAgwBgEB/wIBADARBgNVHSAECjAIMAYGBFUdIAAwRAYDVR0fBD0wOzA5oDeg -NYYzaHR0cDovL2NybC51c2VydHJ1c3QuY29tL0FkZFRydXN0RXh0ZXJuYWxDQVJv -b3QuY3JsMIGzBggrBgEFBQcBAQSBpjCBozA/BggrBgEFBQcwAoYzaHR0cDovL2Ny -dC51c2VydHJ1c3QuY29tL0FkZFRydXN0RXh0ZXJuYWxDQVJvb3QucDdjMDkGCCsG -AQUFBzAChi1odHRwOi8vY3J0LnVzZXJ0cnVzdC5jb20vQWRkVHJ1c3RVVE5TR0ND -QS5jcnQwJQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJ -KoZIhvcNAQEFBQADggEBABOFH1KAGMlT9/4uGq/M2Qs8wtOFgRDwKI25QH4sno/W -NoYKTBQt1pdDkkEZN0uWnuupMHkSlbMCNlftK7kdmBqjGAo/mzmLzaFJKUwv+dCV -jMhNlbqoQ88zqiUqWg6qJ8lOa7Hmcx+zdATD80ziqOtnt124CAUaVppUKYX1KU6A -O5XQe1OWEVbBAtPqsn/Kj5xwShSNWrkWYHXWzSceFs1bM455QM8oSOfccRZOdJF1 -uSqM8XCsJt0EuUDChd4ck0DQzG7Dm6rvYGXfYCLwWqV6oi/kcHPuPNQmK2gHwSB6 -6JhaPnufAotiwIWBgGA1fqUdDNKc32JFDdv8N/v1JSI= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert44[] = { - 0x30, 0x82, 0x04, 0xfc, 0x30, 0x82, 0x03, 0xe4, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x16, 0x90, 0xc3, 0x29, 0xb6, 0x78, 0x06, 0x07, 0x51, - 0x1f, 0x05, 0xb0, 0x34, 0x48, 0x46, 0xcb, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x6f, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x53, - 0x45, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, - 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41, 0x42, 0x31, - 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x64, - 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, 0x78, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x20, 0x54, 0x54, 0x50, 0x20, 0x4e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x19, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, - 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x20, 0x43, 0x41, 0x20, 0x52, - 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x34, 0x31, - 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, - 0x30, 0x35, 0x33, 0x30, 0x31, 0x30, 0x34, 0x38, 0x33, 0x38, 0x5a, 0x30, - 0x81, 0x89, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x47, 0x42, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, - 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4d, 0x61, - 0x6e, 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0e, - 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6c, 0x66, 0x6f, - 0x72, 0x64, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x11, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x43, 0x41, 0x20, 0x4c, - 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x26, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, - 0x48, 0x69, 0x67, 0x68, 0x2d, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, - 0x63, 0x65, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 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, 0xe7, 0x87, 0xda, 0xc0, 0x77, 0xe4, 0xbb, 0x3a, - 0xfa, 0x6a, 0x24, 0xc8, 0x80, 0x41, 0xac, 0xd2, 0x16, 0x13, 0x15, 0x3d, - 0xfa, 0xf7, 0xf8, 0x2a, 0x76, 0xdc, 0xa8, 0x2d, 0x39, 0x08, 0xce, 0x48, - 0x4a, 0xbe, 0x0f, 0x7d, 0xf0, 0xde, 0xba, 0xbb, 0x47, 0xd5, 0xbd, 0x2d, - 0xd7, 0x1b, 0xab, 0x0f, 0x20, 0x81, 0x23, 0x08, 0x72, 0xb1, 0xc0, 0x11, - 0x95, 0x0d, 0xe6, 0xea, 0xa9, 0x87, 0xff, 0xc7, 0x6e, 0x1e, 0x4f, 0x66, - 0x32, 0xba, 0x53, 0xbc, 0x05, 0xaa, 0x1c, 0x2c, 0x0c, 0xef, 0x4d, 0x37, - 0x47, 0x6b, 0x10, 0x0c, 0xdb, 0xc5, 0xa0, 0x98, 0x7e, 0x58, 0xdb, 0x37, - 0xd6, 0xae, 0xe9, 0x06, 0xbd, 0xd7, 0xa8, 0x65, 0xf3, 0x37, 0xb9, 0xc7, - 0x6d, 0xce, 0x77, 0xc7, 0x26, 0xe0, 0xd7, 0x74, 0x1f, 0xa6, 0x98, 0x16, - 0xbb, 0x0c, 0x6b, 0xc8, 0xbe, 0x77, 0xd0, 0xef, 0x58, 0xa7, 0x29, 0xa0, - 0xb9, 0xb8, 0x69, 0x05, 0x36, 0xcb, 0xb2, 0xda, 0x58, 0xa3, 0x0b, 0x75, - 0xad, 0x3d, 0x8b, 0x22, 0x82, 0x20, 0x3e, 0x70, 0x86, 0x99, 0x1c, 0xb9, - 0x4f, 0xcf, 0x77, 0xa4, 0x07, 0x1a, 0x23, 0x63, 0xd1, 0x38, 0x56, 0x84, - 0xec, 0xbf, 0x8f, 0xc5, 0x4e, 0xf4, 0x18, 0x96, 0x9b, 0x1a, 0xe8, 0x93, - 0xec, 0x8d, 0xaf, 0x15, 0x9c, 0x24, 0xf0, 0x5a, 0x3b, 0xe8, 0x0f, 0xb9, - 0xa8, 0x5a, 0x01, 0xd3, 0xb2, 0x1c, 0x60, 0xc9, 0x9c, 0x52, 0x04, 0xdd, - 0x92, 0xa7, 0xfe, 0x0c, 0xac, 0xe2, 0x45, 0x8d, 0x03, 0x61, 0xbc, 0x79, - 0xe0, 0x77, 0x2e, 0x87, 0x41, 0x3c, 0x58, 0x5f, 0xcb, 0xf5, 0xc5, 0x77, - 0xf2, 0x58, 0xc8, 0x4d, 0x28, 0xd0, 0x9a, 0xfa, 0xf3, 0x73, 0x09, 0x24, - 0x68, 0x74, 0xbc, 0x20, 0x4c, 0xd8, 0x2c, 0xb0, 0xaa, 0xe8, 0xd9, 0x4e, - 0x6d, 0xf2, 0x8c, 0x24, 0xd3, 0x93, 0x5d, 0x91, 0x02, 0x03, 0x01, 0x00, - 0x01, 0xa3, 0x82, 0x01, 0x77, 0x30, 0x82, 0x01, 0x73, 0x30, 0x1f, 0x06, - 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xad, 0xbd, - 0x98, 0x7a, 0x34, 0xb4, 0x26, 0xf7, 0xfa, 0xc4, 0x26, 0x54, 0xef, 0x03, - 0xbd, 0xe0, 0x24, 0xcb, 0x54, 0x1a, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, - 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3f, 0xd5, 0xb5, 0xd0, 0xd6, 0x44, 0x79, - 0x50, 0x4a, 0x17, 0xa3, 0x9b, 0x8c, 0x4a, 0xdc, 0xb8, 0xb0, 0x22, 0x64, - 0x6b, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, - 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, - 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, - 0x00, 0x30, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x0a, 0x30, 0x08, - 0x30, 0x06, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x44, 0x06, 0x03, - 0x55, 0x1d, 0x1f, 0x04, 0x3d, 0x30, 0x3b, 0x30, 0x39, 0xa0, 0x37, 0xa0, - 0x35, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, - 0x6c, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, - 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x41, 0x52, 0x6f, - 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x81, 0xb3, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x81, 0xa6, 0x30, 0x81, - 0xa3, 0x30, 0x3f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, - 0x02, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, - 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, 0x54, 0x72, 0x75, 0x73, 0x74, - 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x43, 0x41, 0x52, 0x6f, - 0x6f, 0x74, 0x2e, 0x70, 0x37, 0x63, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, - 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x41, 0x64, 0x64, - 0x54, 0x72, 0x75, 0x73, 0x74, 0x55, 0x54, 0x4e, 0x53, 0x47, 0x43, 0x43, - 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x25, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x19, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, - 0x82, 0x01, 0x01, 0x00, 0x13, 0x85, 0x1f, 0x52, 0x80, 0x18, 0xc9, 0x53, - 0xf7, 0xfe, 0x2e, 0x1a, 0xaf, 0xcc, 0xd9, 0x0b, 0x3c, 0xc2, 0xd3, 0x85, - 0x81, 0x10, 0xf0, 0x28, 0x8d, 0xb9, 0x40, 0x7e, 0x2c, 0x9e, 0x8f, 0xd6, - 0x36, 0x86, 0x0a, 0x4c, 0x14, 0x2d, 0xd6, 0x97, 0x43, 0x92, 0x41, 0x19, - 0x37, 0x4b, 0x96, 0x9e, 0xeb, 0xa9, 0x30, 0x79, 0x12, 0x95, 0xb3, 0x02, - 0x36, 0x57, 0xed, 0x2b, 0xb9, 0x1d, 0x98, 0x1a, 0xa3, 0x18, 0x0a, 0x3f, - 0x9b, 0x39, 0x8b, 0xcd, 0xa1, 0x49, 0x29, 0x4c, 0x2f, 0xf9, 0xd0, 0x95, - 0x8c, 0xc8, 0x4d, 0x95, 0xba, 0xa8, 0x43, 0xcf, 0x33, 0xaa, 0x25, 0x2a, - 0x5a, 0x0e, 0xaa, 0x27, 0xc9, 0x4e, 0x6b, 0xb1, 0xe6, 0x73, 0x1f, 0xb3, - 0x74, 0x04, 0xc3, 0xf3, 0x4c, 0xe2, 0xa8, 0xeb, 0x67, 0xb7, 0x5d, 0xb8, - 0x08, 0x05, 0x1a, 0x56, 0x9a, 0x54, 0x29, 0x85, 0xf5, 0x29, 0x4e, 0x80, - 0x3b, 0x95, 0xd0, 0x7b, 0x53, 0x96, 0x11, 0x56, 0xc1, 0x02, 0xd3, 0xea, - 0xb2, 0x7f, 0xca, 0x8f, 0x9c, 0x70, 0x4a, 0x14, 0x8d, 0x5a, 0xb9, 0x16, - 0x60, 0x75, 0xd6, 0xcd, 0x27, 0x1e, 0x16, 0xcd, 0x5b, 0x33, 0x8e, 0x79, - 0x40, 0xcf, 0x28, 0x48, 0xe7, 0xdc, 0x71, 0x16, 0x4e, 0x74, 0x91, 0x75, - 0xb9, 0x2a, 0x8c, 0xf1, 0x70, 0xac, 0x26, 0xdd, 0x04, 0xb9, 0x40, 0xc2, - 0x85, 0xde, 0x1c, 0x93, 0x40, 0xd0, 0xcc, 0x6e, 0xc3, 0x9b, 0xaa, 0xef, - 0x60, 0x65, 0xdf, 0x60, 0x22, 0xf0, 0x5a, 0xa5, 0x7a, 0xa2, 0x2f, 0xe4, - 0x70, 0x73, 0xee, 0x3c, 0xd4, 0x26, 0x2b, 0x68, 0x07, 0xc1, 0x20, 0x7a, - 0xe8, 0x98, 0x5a, 0x3e, 0x7b, 0x9f, 0x02, 0x8b, 0x62, 0xc0, 0x85, 0x81, - 0x80, 0x60, 0x35, 0x7e, 0xa5, 0x1d, 0x0c, 0xd2, 0x9c, 0xdf, 0x62, 0x45, - 0x0d, 0xdb, 0xfc, 0x37, 0xfb, 0xf5, 0x25, 0x22, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 7 (0x7) - Signature Algorithm: sha256WithRSAEncryption - Issuer: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Root Certificate Authority - G2 - Validity - Not Before: May 3 07:00:00 2011 GMT - Not After : May 3 07:00:00 2031 GMT - Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., OU=http://certs.starfieldtech.com/repository/, CN=Starfield Secure Certificate Authority - G2 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:e5:90:66:4b:ec:f9:46:71:a9:20:83:be:e9:6c: - bf:4a:c9:48:69:81:75:4e:6d:24:f6:cb:17:13:f8: - b0:71:59:84:7a:6b:2b:85:a4:34:b5:16:e5:cb:cc: - e9:41:70:2c:a4:2e:d6:fa:32:7d:e1:a8:de:94:10: - ac:31:c1:c0:d8:6a:ff:59:27:ab:76:d6:fc:0b:74: - 6b:b8:a7:ae:3f:c4:54:f4:b4:31:44:dd:93:56:8c: - a4:4c:5e:9b:89:cb:24:83:9b:e2:57:7d:b7:d8:12: - 1f:c9:85:6d:f4:d1:80:f1:50:9b:87:ae:d4:0b:10: - 05:fb:27:ba:28:6d:17:e9:0e:d6:4d:b9:39:55:06: - ff:0a:24:05:7e:2f:c6:1d:72:6c:d4:8b:29:8c:57: - 7d:da:d9:eb:66:1a:d3:4f:a7:df:7f:52:c4:30:c5: - a5:c9:0e:02:c5:53:bf:77:38:68:06:24:c3:66:c8: - 37:7e:30:1e:45:71:23:35:ff:90:d8:2a:9d:8d:e7: - b0:92:4d:3c:7f:2a:0a:93:dc:cd:16:46:65:f7:60: - 84:8b:76:4b:91:27:73:14:92:e0:ea:ee:8f:16:ea: - 8d:0e:3e:76:17:bf:7d:89:80:80:44:43:e7:2d:e0: - 43:09:75:da:36:e8:ad:db:89:3a:f5:5d:12:8e:23: - 04:83 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Subject Key Identifier: - 25:45:81:68:50:26:38:3D:3B:2D:2C:BE:CD:6A:D9:B6:3D:B3:66:63 - X509v3 Authority Key Identifier: - keyid:7C:0C:32:1F:A7:D9:30:7F:C4:7D:68:A3:62:A8:A1:CE:AB:07:5B:27 - - Authority Information Access: - OCSP - URI:http://ocsp.starfieldtech.com/ - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.starfieldtech.com/sfroot-g2.crl - - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://certs.starfieldtech.com/repository/ - - Signature Algorithm: sha256WithRSAEncryption - 56:65:ca:fe:f3:3f:0a:a8:93:8b:18:c7:de:43:69:13:34:20: - be:4e:5f:78:a8:6b:9c:db:6a:4d:41:db:c1:13:ec:dc:31:00: - 22:5e:f7:00:9e:0c:e0:34:65:34:f9:b1:3a:4e:48:c8:12:81: - 88:5c:5b:3e:08:53:7a:f7:1a:64:df:b8:50:61:cc:53:51:40: - 29:4b:c2:f4:ae:3a:5f:e4:ca:ad:26:cc:4e:61:43:e5:fd:57: - a6:37:70:ce:43:2b:b0:94:c3:92:e9:e1:5f:aa:10:49:b7:69: - e4:e0:d0:1f:64:a4:2b:cd:1f:6f:a0:f8:84:24:18:ce:79:3d: - a9:91:bf:54:18:13:89:99:54:11:0d:55:c5:26:0b:79:4f:5a: - 1c:6e:f9:63:db:14:80:a4:07:ab:fa:b2:a5:b9:88:dd:91:fe: - 65:3b:a4:a3:79:be:89:4d:e1:d0:b0:f4:c8:17:0c:0a:96:14: - 7c:09:b7:6c:e1:c2:d8:55:d4:18:a0:aa:41:69:70:24:a3:b9: - ef:e9:5a:dc:3e:eb:94:4a:f0:b7:de:5f:0e:76:fa:fb:fb:69: - 03:45:40:50:ee:72:0c:a4:12:86:81:cd:13:d1:4e:c4:3c:ca: - 4e:0d:d2:26:f1:00:b7:b4:a6:a2:e1:6e:7a:81:fd:30:ac:7a: - 1f:c7:59:7b ------BEGIN CERTIFICATE----- -MIIFADCCA+igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx -EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT -HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs -ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAw -MFoXDTMxMDUwMzA3MDAwMFowgcYxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 -b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj -aG5vbG9naWVzLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydHMuc3RhcmZpZWxk -dGVjaC5jb20vcmVwb3NpdG9yeS8xNDAyBgNVBAMTK1N0YXJmaWVsZCBTZWN1cmUg -Q2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IB -DwAwggEKAoIBAQDlkGZL7PlGcakgg77pbL9KyUhpgXVObST2yxcT+LBxWYR6ayuF -pDS1FuXLzOlBcCykLtb6Mn3hqN6UEKwxwcDYav9ZJ6t21vwLdGu4p64/xFT0tDFE -3ZNWjKRMXpuJyySDm+JXfbfYEh/JhW300YDxUJuHrtQLEAX7J7oobRfpDtZNuTlV -Bv8KJAV+L8YdcmzUiymMV33a2etmGtNPp99/UsQwxaXJDgLFU793OGgGJMNmyDd+ -MB5FcSM1/5DYKp2N57CSTTx/KgqT3M0WRmX3YISLdkuRJ3MUkuDq7o8W6o0OPnYX -v32JgIBEQ+ct4EMJddo26K3biTr1XRKOIwSDAgMBAAGjggEsMIIBKDAPBgNVHRMB -Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUJUWBaFAmOD07LSy+ -zWrZtj2zZmMwHwYDVR0jBBgwFoAUfAwyH6fZMH/EfWijYqihzqsHWycwOgYIKwYB -BQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vb2NzcC5zdGFyZmllbGR0ZWNo -LmNvbS8wOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5zdGFyZmllbGR0ZWNo -LmNvbS9zZnJvb3QtZzIuY3JsMEwGA1UdIARFMEMwQQYEVR0gADA5MDcGCCsGAQUF -BwIBFitodHRwczovL2NlcnRzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkv -MA0GCSqGSIb3DQEBCwUAA4IBAQBWZcr+8z8KqJOLGMfeQ2kTNCC+Tl94qGuc22pN -QdvBE+zcMQAiXvcAngzgNGU0+bE6TkjIEoGIXFs+CFN69xpk37hQYcxTUUApS8L0 -rjpf5MqtJsxOYUPl/VemN3DOQyuwlMOS6eFfqhBJt2nk4NAfZKQrzR9voPiEJBjO -eT2pkb9UGBOJmVQRDVXFJgt5T1ocbvlj2xSApAer+rKluYjdkf5lO6Sjeb6JTeHQ -sPTIFwwKlhR8Cbds4cLYVdQYoKpBaXAko7nv6VrcPuuUSvC33l8Odvr7+2kDRUBQ -7nIMpBKGgc0T0U7EPMpODdIm8QC3tKai4W56gf0wrHofx1l7 ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert45[] = { - 0x30, 0x82, 0x05, 0x00, 0x30, 0x82, 0x03, 0xe8, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x01, 0x07, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x8f, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, - 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, - 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, - 0x6c, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x1c, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, - 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, - 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, - 0x64, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x1e, 0x17, - 0x0d, 0x31, 0x31, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37, 0x30, 0x30, 0x30, - 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x31, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37, - 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x81, 0xc6, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, - 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, - 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, - 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, - 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53, - 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63, - 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49, - 0x6e, 0x63, 0x2e, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x13, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, - 0x74, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, - 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x31, 0x34, 0x30, 0x32, - 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2b, 0x53, 0x74, 0x61, 0x72, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, - 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, - 0x47, 0x32, 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, 0xe5, - 0x90, 0x66, 0x4b, 0xec, 0xf9, 0x46, 0x71, 0xa9, 0x20, 0x83, 0xbe, 0xe9, - 0x6c, 0xbf, 0x4a, 0xc9, 0x48, 0x69, 0x81, 0x75, 0x4e, 0x6d, 0x24, 0xf6, - 0xcb, 0x17, 0x13, 0xf8, 0xb0, 0x71, 0x59, 0x84, 0x7a, 0x6b, 0x2b, 0x85, - 0xa4, 0x34, 0xb5, 0x16, 0xe5, 0xcb, 0xcc, 0xe9, 0x41, 0x70, 0x2c, 0xa4, - 0x2e, 0xd6, 0xfa, 0x32, 0x7d, 0xe1, 0xa8, 0xde, 0x94, 0x10, 0xac, 0x31, - 0xc1, 0xc0, 0xd8, 0x6a, 0xff, 0x59, 0x27, 0xab, 0x76, 0xd6, 0xfc, 0x0b, - 0x74, 0x6b, 0xb8, 0xa7, 0xae, 0x3f, 0xc4, 0x54, 0xf4, 0xb4, 0x31, 0x44, - 0xdd, 0x93, 0x56, 0x8c, 0xa4, 0x4c, 0x5e, 0x9b, 0x89, 0xcb, 0x24, 0x83, - 0x9b, 0xe2, 0x57, 0x7d, 0xb7, 0xd8, 0x12, 0x1f, 0xc9, 0x85, 0x6d, 0xf4, - 0xd1, 0x80, 0xf1, 0x50, 0x9b, 0x87, 0xae, 0xd4, 0x0b, 0x10, 0x05, 0xfb, - 0x27, 0xba, 0x28, 0x6d, 0x17, 0xe9, 0x0e, 0xd6, 0x4d, 0xb9, 0x39, 0x55, - 0x06, 0xff, 0x0a, 0x24, 0x05, 0x7e, 0x2f, 0xc6, 0x1d, 0x72, 0x6c, 0xd4, - 0x8b, 0x29, 0x8c, 0x57, 0x7d, 0xda, 0xd9, 0xeb, 0x66, 0x1a, 0xd3, 0x4f, - 0xa7, 0xdf, 0x7f, 0x52, 0xc4, 0x30, 0xc5, 0xa5, 0xc9, 0x0e, 0x02, 0xc5, - 0x53, 0xbf, 0x77, 0x38, 0x68, 0x06, 0x24, 0xc3, 0x66, 0xc8, 0x37, 0x7e, - 0x30, 0x1e, 0x45, 0x71, 0x23, 0x35, 0xff, 0x90, 0xd8, 0x2a, 0x9d, 0x8d, - 0xe7, 0xb0, 0x92, 0x4d, 0x3c, 0x7f, 0x2a, 0x0a, 0x93, 0xdc, 0xcd, 0x16, - 0x46, 0x65, 0xf7, 0x60, 0x84, 0x8b, 0x76, 0x4b, 0x91, 0x27, 0x73, 0x14, - 0x92, 0xe0, 0xea, 0xee, 0x8f, 0x16, 0xea, 0x8d, 0x0e, 0x3e, 0x76, 0x17, - 0xbf, 0x7d, 0x89, 0x80, 0x80, 0x44, 0x43, 0xe7, 0x2d, 0xe0, 0x43, 0x09, - 0x75, 0xda, 0x36, 0xe8, 0xad, 0xdb, 0x89, 0x3a, 0xf5, 0x5d, 0x12, 0x8e, - 0x23, 0x04, 0x83, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x2c, - 0x30, 0x82, 0x01, 0x28, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, - 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, - 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, - 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, - 0x25, 0x45, 0x81, 0x68, 0x50, 0x26, 0x38, 0x3d, 0x3b, 0x2d, 0x2c, 0xbe, - 0xcd, 0x6a, 0xd9, 0xb6, 0x3d, 0xb3, 0x66, 0x63, 0x30, 0x1f, 0x06, 0x03, - 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7c, 0x0c, 0x32, - 0x1f, 0xa7, 0xd9, 0x30, 0x7f, 0xc4, 0x7d, 0x68, 0xa3, 0x62, 0xa8, 0xa1, - 0xce, 0xab, 0x07, 0x5b, 0x27, 0x30, 0x3a, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0x06, - 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x1e, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x73, - 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x3b, 0x06, 0x03, 0x55, 0x1d, 0x1f, - 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0xa0, 0x2e, 0xa0, 0x2c, 0x86, 0x2a, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x73, - 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x66, 0x72, 0x6f, 0x6f, 0x74, 0x2d, - 0x67, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, - 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0x06, 0x04, 0x55, 0x1d, 0x20, - 0x00, 0x30, 0x39, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x02, 0x01, 0x16, 0x2b, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, - 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x56, 0x65, 0xca, 0xfe, - 0xf3, 0x3f, 0x0a, 0xa8, 0x93, 0x8b, 0x18, 0xc7, 0xde, 0x43, 0x69, 0x13, - 0x34, 0x20, 0xbe, 0x4e, 0x5f, 0x78, 0xa8, 0x6b, 0x9c, 0xdb, 0x6a, 0x4d, - 0x41, 0xdb, 0xc1, 0x13, 0xec, 0xdc, 0x31, 0x00, 0x22, 0x5e, 0xf7, 0x00, - 0x9e, 0x0c, 0xe0, 0x34, 0x65, 0x34, 0xf9, 0xb1, 0x3a, 0x4e, 0x48, 0xc8, - 0x12, 0x81, 0x88, 0x5c, 0x5b, 0x3e, 0x08, 0x53, 0x7a, 0xf7, 0x1a, 0x64, - 0xdf, 0xb8, 0x50, 0x61, 0xcc, 0x53, 0x51, 0x40, 0x29, 0x4b, 0xc2, 0xf4, - 0xae, 0x3a, 0x5f, 0xe4, 0xca, 0xad, 0x26, 0xcc, 0x4e, 0x61, 0x43, 0xe5, - 0xfd, 0x57, 0xa6, 0x37, 0x70, 0xce, 0x43, 0x2b, 0xb0, 0x94, 0xc3, 0x92, - 0xe9, 0xe1, 0x5f, 0xaa, 0x10, 0x49, 0xb7, 0x69, 0xe4, 0xe0, 0xd0, 0x1f, - 0x64, 0xa4, 0x2b, 0xcd, 0x1f, 0x6f, 0xa0, 0xf8, 0x84, 0x24, 0x18, 0xce, - 0x79, 0x3d, 0xa9, 0x91, 0xbf, 0x54, 0x18, 0x13, 0x89, 0x99, 0x54, 0x11, - 0x0d, 0x55, 0xc5, 0x26, 0x0b, 0x79, 0x4f, 0x5a, 0x1c, 0x6e, 0xf9, 0x63, - 0xdb, 0x14, 0x80, 0xa4, 0x07, 0xab, 0xfa, 0xb2, 0xa5, 0xb9, 0x88, 0xdd, - 0x91, 0xfe, 0x65, 0x3b, 0xa4, 0xa3, 0x79, 0xbe, 0x89, 0x4d, 0xe1, 0xd0, - 0xb0, 0xf4, 0xc8, 0x17, 0x0c, 0x0a, 0x96, 0x14, 0x7c, 0x09, 0xb7, 0x6c, - 0xe1, 0xc2, 0xd8, 0x55, 0xd4, 0x18, 0xa0, 0xaa, 0x41, 0x69, 0x70, 0x24, - 0xa3, 0xb9, 0xef, 0xe9, 0x5a, 0xdc, 0x3e, 0xeb, 0x94, 0x4a, 0xf0, 0xb7, - 0xde, 0x5f, 0x0e, 0x76, 0xfa, 0xfb, 0xfb, 0x69, 0x03, 0x45, 0x40, 0x50, - 0xee, 0x72, 0x0c, 0xa4, 0x12, 0x86, 0x81, 0xcd, 0x13, 0xd1, 0x4e, 0xc4, - 0x3c, 0xca, 0x4e, 0x0d, 0xd2, 0x26, 0xf1, 0x00, 0xb7, 0xb4, 0xa6, 0xa2, - 0xe1, 0x6e, 0x7a, 0x81, 0xfd, 0x30, 0xac, 0x7a, 0x1f, 0xc7, 0x59, 0x7b, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 120025006 (0x7276fae) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root - Validity - Not Before: Apr 25 17:41:36 2012 GMT - Not After : Apr 25 17:40:55 2020 GMT - Subject: CN=Microsoft Internet Authority - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (4096 bit) - Modulus: - 00:be:40:54:11:aa:28:79:66:5e:a9:bb:b0:93:62: - 4b:73:19:aa:e9:2f:91:4c:6d:97:37:25:68:b8:b0: - 36:50:94:5c:ef:ff:c4:c4:17:76:43:57:fc:a0:e1: - c6:33:ec:30:62:be:35:0f:23:7a:96:4d:6c:74:62: - 09:7e:31:48:4e:9f:4d:aa:5b:b3:16:b7:fe:a0:29: - 2f:65:a5:4b:ac:6a:56:8a:bf:28:70:6a:df:37:18: - df:ec:c6:87:22:3e:16:dd:38:1c:0f:e2:05:be:77: - ab:ee:85:8a:1e:0d:23:3f:e9:24:e1:90:47:b2:67: - 3b:15:3e:55:20:3c:f9:f5:42:d7:af:c5:66:0d:9a: - 94:17:b9:6a:67:7c:a8:fa:b1:26:00:04:23:d5:4d: - a3:ae:8d:79:60:b1:8e:83:4f:cd:bb:77:78:27:b2: - e8:74:ad:1f:4c:34:80:31:7f:8b:e4:50:7e:6f:7f: - cf:55:da:c6:fb:b6:5a:f5:5d:1d:38:94:a5:fe:b0: - 8d:22:63:23:e7:70:40:40:bf:89:aa:54:46:25:03: - ec:a4:f2:ad:c0:40:b3:72:fe:94:b5:d9:96:b2:1b: - 73:5e:d5:f4:6b:47:41:79:a4:da:f3:8e:2e:8d:38: - 4d:c9:5e:17:1c:ae:b5:4c:36:6b:e8:7f:d9:24:c7: - 28:f0:a7:86:be:e8:1d:08:b4:db:72:23:64:d1:42: - f3:f5:4c:da:ac:f3:b6:a5:75:68:fc:f0:bb:02:61: - 5d:1e:7a:07:52:29:be:74:12:42:53:9c:8d:cc:e9: - 88:7b:a4:55:36:08:58:8c:21:89:c5:ba:13:e8:6d: - 9b:81:8a:77:c6:38:6c:f5:3a:1d:91:37:57:2b:a9: - eb:2b:46:4a:a8:97:28:8b:a3:7e:4a:dd:8d:a7:d3: - 02:10:7c:96:b0:c8:bc:86:28:06:d6:57:a2:a7:66: - f1:17:d6:cc:5f:55:12:3d:59:03:a2:c7:d2:d6:69: - b4:0d:25:f9:f1:d3:94:56:16:2e:26:bc:96:f9:ba: - 1c:51:9b:81:f1:37:bc:77:ee:7e:d9:9a:78:f6:41: - b4:71:df:10:25:5b:b2:e1:3a:c7:7b:f2:6c:b3:19: - b7:20:e7:89:e9:c4:a5:6a:a4:7c:39:24:ee:e7:5d: - 2b:2b:c9:91:fe:a1:3c:33:25:bd:c5:41:14:92:ee: - cf:56:3a:26:13:75:ca:11:5c:c6:27:ab:49:88:ab: - 55:72:fc:65:48:dc:ae:cd:f1:8f:8b:10:66:2a:90: - 2e:0b:8b:b7:fe:38:75:cd:b1:75:80:b6:8f:cf:43: - 1c:21:29:93:0f:e3:13:b9:e2:b0:c8:b2:46:2a:5a: - 14:0c:1d - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:1 - X509v3 Certificate Policies: - Policy: 1.3.6.1.4.1.6334.1.0 - CPS: http://cybertrust.omniroot.com/repository.cfm - - X509v3 Key Usage: critical - Digital Signature, Certificate Sign, CRL Sign - X509v3 Authority Key Identifier: - keyid:E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0 - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://cdp1.public-trust.com/CRL/Omniroot2025.crl - - X509v3 Subject Key Identifier: - 2A:4D:97:95:5D:34:7E:9D:B6:E6:33:BE:9C:27:C1:70:7E:67:DB:C1 - Signature Algorithm: sha1WithRSAEncryption - 23:3e:87:6e:d3:ca:d6:0e:b0:36:25:8d:cc:0a:ce:dc:5d:74: - f3:42:1b:ef:aa:c0:49:73:85:cc:7d:2f:77:09:23:c5:2c:50: - 1d:46:c3:68:68:ef:10:32:d9:4d:7e:e3:5a:e3:1d:18:3c:d2: - 40:54:cd:ef:59:ee:df:fe:fb:70:4a:bc:d8:74:37:2b:dc:a4: - 68:71:50:ba:63:cb:44:dd:11:48:ff:f8:f1:ff:60:ba:7c:aa: - 30:7d:dd:17:b1:77:ea:50:90:20:00:0b:a3:3d:5d:98:71:51: - 9f:dd:2d:c0:78:5e:0d:55:b1:83:45:de:e5:59:98:6d:a4:e1: - 69:7c:32:d0:04:7b:f7:a9:1d:97:3b:d5:59:bf:cb:6f:9d:a4: - b6:a5:bb:41:11:ed:c8:91:83:15:55:ae:59:36:b7:9f:6a:f0: - b8:38:f9:7c:32:25:95:cc:33:f1:31:e7:df:cb:78:4b:36:1f: - f4:55:e0:bd:28:f9:ca:b9:64:99:ce:eb:61:e9:81:72:94:d3: - 9b:cd:0a:2b:2a:a4:94:83:ae:6a:0c:23:44:0e:35:ad:a1:e9: - ec:d8:d7:75:90:8d:e1:d6:b3:c5:50:fc:5d:d5:fb:6f:92:e1: - f4:7e:f0:ae:af:f9:39:b3:ce:4b:01:9c:bd:4e:f7:f1:f2:6f: - ce:c0:36:d8 ------BEGIN CERTIFICATE----- -MIIFATCCA+mgAwIBAgIEBydvrjANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ -RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD -VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTEyMDQyNTE3NDEzNloX -DTIwMDQyNTE3NDA1NVowJzElMCMGA1UEAxMcTWljcm9zb2Z0IEludGVybmV0IEF1 -dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL5AVBGqKHlm -Xqm7sJNiS3MZqukvkUxtlzclaLiwNlCUXO//xMQXdkNX/KDhxjPsMGK+NQ8jepZN -bHRiCX4xSE6fTapbsxa3/qApL2WlS6xqVoq/KHBq3zcY3+zGhyI+Ft04HA/iBb53 -q+6Fih4NIz/pJOGQR7JnOxU+VSA8+fVC16/FZg2alBe5amd8qPqxJgAEI9VNo66N -eWCxjoNPzbt3eCey6HStH0w0gDF/i+RQfm9/z1Xaxvu2WvVdHTiUpf6wjSJjI+dw -QEC/iapURiUD7KTyrcBAs3L+lLXZlrIbc17V9GtHQXmk2vOOLo04TcleFxyutUw2 -a+h/2STHKPCnhr7oHQi023IjZNFC8/VM2qzztqV1aPzwuwJhXR56B1IpvnQSQlOc -jczpiHukVTYIWIwhicW6E+htm4GKd8Y4bPU6HZE3Vyup6ytGSqiXKIujfkrdjafT -AhB8lrDIvIYoBtZXoqdm8RfWzF9VEj1ZA6LH0tZptA0l+fHTlFYWLia8lvm6HFGb -gfE3vHfuftmaePZBtHHfECVbsuE6x3vybLMZtyDnienEpWqkfDkk7uddKyvJkf6h -PDMlvcVBFJLuz1Y6JhN1yhFcxierSYirVXL8ZUjcrs3xj4sQZiqQLguLt/44dc2x -dYC2j89DHCEpkw/jE7nisMiyRipaFAwdAgMBAAGjggEAMIH9MBIGA1UdEwEB/wQI -MAYBAf8CAQEwUwYDVR0gBEwwSjBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcCARYt -aHR0cDovL2N5YmVydHJ1c3Qub21uaXJvb3QuY29tL3JlcG9zaXRvcnkuY2ZtMA4G -A1UdDwEB/wQEAwIBhjAfBgNVHSMEGDAWgBTlnVkwgkdYzKz6CFQ2hns6tQRN8DBC -BgNVHR8EOzA5MDegNaAzhjFodHRwOi8vY2RwMS5wdWJsaWMtdHJ1c3QuY29tL0NS -TC9PbW5pcm9vdDIwMjUuY3JsMB0GA1UdDgQWBBQqTZeVXTR+nbbmM76cJ8Fwfmfb -wTANBgkqhkiG9w0BAQUFAAOCAQEAIz6HbtPK1g6wNiWNzArO3F1080Ib76rASXOF -zH0vdwkjxSxQHUbDaGjvEDLZTX7jWuMdGDzSQFTN71nu3/77cEq82HQ3K9ykaHFQ -umPLRN0RSP/48f9gunyqMH3dF7F36lCQIAALoz1dmHFRn90twHheDVWxg0Xe5VmY -baThaXwy0AR796kdlzvVWb/Lb52ktqW7QRHtyJGDFVWuWTa3n2rwuDj5fDIllcwz -8THn38t4SzYf9FXgvSj5yrlkmc7rYemBcpTTm80KKyqklIOuagwjRA41raHp7NjX -dZCN4dazxVD8XdX7b5Lh9H7wrq/5ObPOSwGcvU738fJvzsA22A== ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert46[] = { - 0x30, 0x82, 0x05, 0x01, 0x30, 0x82, 0x03, 0xe9, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x04, 0x07, 0x27, 0x6f, 0xae, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5a, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49, - 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, - 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30, - 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65, - 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, - 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, - 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, - 0x30, 0x34, 0x32, 0x35, 0x31, 0x37, 0x34, 0x31, 0x33, 0x36, 0x5a, 0x17, - 0x0d, 0x32, 0x30, 0x30, 0x34, 0x32, 0x35, 0x31, 0x37, 0x34, 0x30, 0x35, - 0x35, 0x5a, 0x30, 0x27, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x13, 0x1c, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, - 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x41, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x82, 0x02, 0x22, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, - 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, - 0x82, 0x02, 0x01, 0x00, 0xbe, 0x40, 0x54, 0x11, 0xaa, 0x28, 0x79, 0x66, - 0x5e, 0xa9, 0xbb, 0xb0, 0x93, 0x62, 0x4b, 0x73, 0x19, 0xaa, 0xe9, 0x2f, - 0x91, 0x4c, 0x6d, 0x97, 0x37, 0x25, 0x68, 0xb8, 0xb0, 0x36, 0x50, 0x94, - 0x5c, 0xef, 0xff, 0xc4, 0xc4, 0x17, 0x76, 0x43, 0x57, 0xfc, 0xa0, 0xe1, - 0xc6, 0x33, 0xec, 0x30, 0x62, 0xbe, 0x35, 0x0f, 0x23, 0x7a, 0x96, 0x4d, - 0x6c, 0x74, 0x62, 0x09, 0x7e, 0x31, 0x48, 0x4e, 0x9f, 0x4d, 0xaa, 0x5b, - 0xb3, 0x16, 0xb7, 0xfe, 0xa0, 0x29, 0x2f, 0x65, 0xa5, 0x4b, 0xac, 0x6a, - 0x56, 0x8a, 0xbf, 0x28, 0x70, 0x6a, 0xdf, 0x37, 0x18, 0xdf, 0xec, 0xc6, - 0x87, 0x22, 0x3e, 0x16, 0xdd, 0x38, 0x1c, 0x0f, 0xe2, 0x05, 0xbe, 0x77, - 0xab, 0xee, 0x85, 0x8a, 0x1e, 0x0d, 0x23, 0x3f, 0xe9, 0x24, 0xe1, 0x90, - 0x47, 0xb2, 0x67, 0x3b, 0x15, 0x3e, 0x55, 0x20, 0x3c, 0xf9, 0xf5, 0x42, - 0xd7, 0xaf, 0xc5, 0x66, 0x0d, 0x9a, 0x94, 0x17, 0xb9, 0x6a, 0x67, 0x7c, - 0xa8, 0xfa, 0xb1, 0x26, 0x00, 0x04, 0x23, 0xd5, 0x4d, 0xa3, 0xae, 0x8d, - 0x79, 0x60, 0xb1, 0x8e, 0x83, 0x4f, 0xcd, 0xbb, 0x77, 0x78, 0x27, 0xb2, - 0xe8, 0x74, 0xad, 0x1f, 0x4c, 0x34, 0x80, 0x31, 0x7f, 0x8b, 0xe4, 0x50, - 0x7e, 0x6f, 0x7f, 0xcf, 0x55, 0xda, 0xc6, 0xfb, 0xb6, 0x5a, 0xf5, 0x5d, - 0x1d, 0x38, 0x94, 0xa5, 0xfe, 0xb0, 0x8d, 0x22, 0x63, 0x23, 0xe7, 0x70, - 0x40, 0x40, 0xbf, 0x89, 0xaa, 0x54, 0x46, 0x25, 0x03, 0xec, 0xa4, 0xf2, - 0xad, 0xc0, 0x40, 0xb3, 0x72, 0xfe, 0x94, 0xb5, 0xd9, 0x96, 0xb2, 0x1b, - 0x73, 0x5e, 0xd5, 0xf4, 0x6b, 0x47, 0x41, 0x79, 0xa4, 0xda, 0xf3, 0x8e, - 0x2e, 0x8d, 0x38, 0x4d, 0xc9, 0x5e, 0x17, 0x1c, 0xae, 0xb5, 0x4c, 0x36, - 0x6b, 0xe8, 0x7f, 0xd9, 0x24, 0xc7, 0x28, 0xf0, 0xa7, 0x86, 0xbe, 0xe8, - 0x1d, 0x08, 0xb4, 0xdb, 0x72, 0x23, 0x64, 0xd1, 0x42, 0xf3, 0xf5, 0x4c, - 0xda, 0xac, 0xf3, 0xb6, 0xa5, 0x75, 0x68, 0xfc, 0xf0, 0xbb, 0x02, 0x61, - 0x5d, 0x1e, 0x7a, 0x07, 0x52, 0x29, 0xbe, 0x74, 0x12, 0x42, 0x53, 0x9c, - 0x8d, 0xcc, 0xe9, 0x88, 0x7b, 0xa4, 0x55, 0x36, 0x08, 0x58, 0x8c, 0x21, - 0x89, 0xc5, 0xba, 0x13, 0xe8, 0x6d, 0x9b, 0x81, 0x8a, 0x77, 0xc6, 0x38, - 0x6c, 0xf5, 0x3a, 0x1d, 0x91, 0x37, 0x57, 0x2b, 0xa9, 0xeb, 0x2b, 0x46, - 0x4a, 0xa8, 0x97, 0x28, 0x8b, 0xa3, 0x7e, 0x4a, 0xdd, 0x8d, 0xa7, 0xd3, - 0x02, 0x10, 0x7c, 0x96, 0xb0, 0xc8, 0xbc, 0x86, 0x28, 0x06, 0xd6, 0x57, - 0xa2, 0xa7, 0x66, 0xf1, 0x17, 0xd6, 0xcc, 0x5f, 0x55, 0x12, 0x3d, 0x59, - 0x03, 0xa2, 0xc7, 0xd2, 0xd6, 0x69, 0xb4, 0x0d, 0x25, 0xf9, 0xf1, 0xd3, - 0x94, 0x56, 0x16, 0x2e, 0x26, 0xbc, 0x96, 0xf9, 0xba, 0x1c, 0x51, 0x9b, - 0x81, 0xf1, 0x37, 0xbc, 0x77, 0xee, 0x7e, 0xd9, 0x9a, 0x78, 0xf6, 0x41, - 0xb4, 0x71, 0xdf, 0x10, 0x25, 0x5b, 0xb2, 0xe1, 0x3a, 0xc7, 0x7b, 0xf2, - 0x6c, 0xb3, 0x19, 0xb7, 0x20, 0xe7, 0x89, 0xe9, 0xc4, 0xa5, 0x6a, 0xa4, - 0x7c, 0x39, 0x24, 0xee, 0xe7, 0x5d, 0x2b, 0x2b, 0xc9, 0x91, 0xfe, 0xa1, - 0x3c, 0x33, 0x25, 0xbd, 0xc5, 0x41, 0x14, 0x92, 0xee, 0xcf, 0x56, 0x3a, - 0x26, 0x13, 0x75, 0xca, 0x11, 0x5c, 0xc6, 0x27, 0xab, 0x49, 0x88, 0xab, - 0x55, 0x72, 0xfc, 0x65, 0x48, 0xdc, 0xae, 0xcd, 0xf1, 0x8f, 0x8b, 0x10, - 0x66, 0x2a, 0x90, 0x2e, 0x0b, 0x8b, 0xb7, 0xfe, 0x38, 0x75, 0xcd, 0xb1, - 0x75, 0x80, 0xb6, 0x8f, 0xcf, 0x43, 0x1c, 0x21, 0x29, 0x93, 0x0f, 0xe3, - 0x13, 0xb9, 0xe2, 0xb0, 0xc8, 0xb2, 0x46, 0x2a, 0x5a, 0x14, 0x0c, 0x1d, - 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x00, 0x30, 0x81, 0xfd, - 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, - 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x53, 0x06, 0x03, - 0x55, 0x1d, 0x20, 0x04, 0x4c, 0x30, 0x4a, 0x30, 0x48, 0x06, 0x09, 0x2b, - 0x06, 0x01, 0x04, 0x01, 0xb1, 0x3e, 0x01, 0x00, 0x30, 0x3b, 0x30, 0x39, - 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x2d, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x79, 0x62, 0x65, 0x72, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, - 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x63, 0x66, 0x6d, 0x30, 0x0e, 0x06, - 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, - 0x86, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, - 0x80, 0x14, 0xe5, 0x9d, 0x59, 0x30, 0x82, 0x47, 0x58, 0xcc, 0xac, 0xfa, - 0x08, 0x54, 0x36, 0x86, 0x7b, 0x3a, 0xb5, 0x04, 0x4d, 0xf0, 0x30, 0x42, - 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3b, 0x30, 0x39, 0x30, 0x37, 0xa0, - 0x35, 0xa0, 0x33, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x63, 0x64, 0x70, 0x31, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2d, - 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x52, - 0x4c, 0x2f, 0x4f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x32, 0x30, - 0x32, 0x35, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, - 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2a, 0x4d, 0x97, 0x95, 0x5d, 0x34, 0x7e, - 0x9d, 0xb6, 0xe6, 0x33, 0xbe, 0x9c, 0x27, 0xc1, 0x70, 0x7e, 0x67, 0xdb, - 0xc1, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x23, 0x3e, 0x87, - 0x6e, 0xd3, 0xca, 0xd6, 0x0e, 0xb0, 0x36, 0x25, 0x8d, 0xcc, 0x0a, 0xce, - 0xdc, 0x5d, 0x74, 0xf3, 0x42, 0x1b, 0xef, 0xaa, 0xc0, 0x49, 0x73, 0x85, - 0xcc, 0x7d, 0x2f, 0x77, 0x09, 0x23, 0xc5, 0x2c, 0x50, 0x1d, 0x46, 0xc3, - 0x68, 0x68, 0xef, 0x10, 0x32, 0xd9, 0x4d, 0x7e, 0xe3, 0x5a, 0xe3, 0x1d, - 0x18, 0x3c, 0xd2, 0x40, 0x54, 0xcd, 0xef, 0x59, 0xee, 0xdf, 0xfe, 0xfb, - 0x70, 0x4a, 0xbc, 0xd8, 0x74, 0x37, 0x2b, 0xdc, 0xa4, 0x68, 0x71, 0x50, - 0xba, 0x63, 0xcb, 0x44, 0xdd, 0x11, 0x48, 0xff, 0xf8, 0xf1, 0xff, 0x60, - 0xba, 0x7c, 0xaa, 0x30, 0x7d, 0xdd, 0x17, 0xb1, 0x77, 0xea, 0x50, 0x90, - 0x20, 0x00, 0x0b, 0xa3, 0x3d, 0x5d, 0x98, 0x71, 0x51, 0x9f, 0xdd, 0x2d, - 0xc0, 0x78, 0x5e, 0x0d, 0x55, 0xb1, 0x83, 0x45, 0xde, 0xe5, 0x59, 0x98, - 0x6d, 0xa4, 0xe1, 0x69, 0x7c, 0x32, 0xd0, 0x04, 0x7b, 0xf7, 0xa9, 0x1d, - 0x97, 0x3b, 0xd5, 0x59, 0xbf, 0xcb, 0x6f, 0x9d, 0xa4, 0xb6, 0xa5, 0xbb, - 0x41, 0x11, 0xed, 0xc8, 0x91, 0x83, 0x15, 0x55, 0xae, 0x59, 0x36, 0xb7, - 0x9f, 0x6a, 0xf0, 0xb8, 0x38, 0xf9, 0x7c, 0x32, 0x25, 0x95, 0xcc, 0x33, - 0xf1, 0x31, 0xe7, 0xdf, 0xcb, 0x78, 0x4b, 0x36, 0x1f, 0xf4, 0x55, 0xe0, - 0xbd, 0x28, 0xf9, 0xca, 0xb9, 0x64, 0x99, 0xce, 0xeb, 0x61, 0xe9, 0x81, - 0x72, 0x94, 0xd3, 0x9b, 0xcd, 0x0a, 0x2b, 0x2a, 0xa4, 0x94, 0x83, 0xae, - 0x6a, 0x0c, 0x23, 0x44, 0x0e, 0x35, 0xad, 0xa1, 0xe9, 0xec, 0xd8, 0xd7, - 0x75, 0x90, 0x8d, 0xe1, 0xd6, 0xb3, 0xc5, 0x50, 0xfc, 0x5d, 0xd5, 0xfb, - 0x6f, 0x92, 0xe1, 0xf4, 0x7e, 0xf0, 0xae, 0xaf, 0xf9, 0x39, 0xb3, 0xce, - 0x4b, 0x01, 0x9c, 0xbd, 0x4e, 0xf7, 0xf1, 0xf2, 0x6f, 0xce, 0xc0, 0x36, - 0xd8, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 18:b2:cb:ba:a3:04:f1:a0:0f:c1:f2:f3:26:46:2a:4a - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO Certification Authority - Validity - Not Before: Dec 1 00:00:00 2006 GMT - Not After : Dec 31 23:59:59 2019 GMT - Subject: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=EssentialSSL CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:ad:f0:08:b0:72:c6:ab:83:12:31:17:70:89:85: - a9:20:12:d4:98:6a:ed:80:d4:d1:df:e4:8e:59:2d: - d3:96:21:8d:76:d2:3f:18:0b:46:19:63:0b:c7:20: - f3:e5:0b:dd:80:1a:f1:5a:a0:bd:1d:76:cd:b7:23: - 3a:74:5e:61:1b:75:aa:9b:d4:85:f4:e1:78:91:d3: - 2d:e1:af:fc:98:2e:06:d2:79:3d:5a:c0:1f:21:2d: - 1c:ae:21:53:c6:3a:a7:21:7e:be:ed:67:6f:75:1d: - 1a:9f:6a:5b:06:b3:6a:e3:b1:0b:aa:6a:0e:e7:6d: - 6c:c3:ca:95:8c:37:ce:21:1f:35:90:7d:db:da:1a: - 5c:a8:88:14:b2:0f:c8:12:20:5f:c5:d3:7f:e8:e1: - 38:e0:db:bc:f9:1f:a1:aa:d6:1b:90:07:21:fa:45: - 24:50:5d:27:2a:a0:28:41:45:5b:7d:bc:a0:a2:2f: - aa:9b:7e:5b:53:c5:f1:05:16:57:7e:11:d7:3b:b4: - d9:01:76:dc:df:7d:10:cf:51:a9:e5:38:f2:7b:14: - 00:75:59:f9:f0:59:db:17:3e:f7:af:e6:02:2d:a4: - 79:c1:5d:a2:1c:c3:9a:c8:a7:a8:0b:48:0a:6a:2e: - 7f:2d:97:65:f6:c5:04:9c:44:c8:99:96:7e:7e:a4: - dd:2f - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Authority Key Identifier: - keyid:0B:58:E5:8B:C6:4C:15:37:A4:40:A9:30:A9:21:BE:47:36:5A:56:FF - - X509v3 Subject Key Identifier: - DA:CB:EA:AD:5B:08:5D:CC:FF:FC:26:54:CE:49:E5:55:C6:38:F4:F8 - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Extended Key Usage: - Microsoft Server Gated Crypto, Netscape Server Gated Crypto - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://secure.comodo.com/CPS - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.comodoca.com/COMODOCertificationAuthority.crl - - Authority Information Access: - CA Issuers - URI:http://crt.comodoca.com/ComodoUTNSGCCA.crt - OCSP - URI:http://ocsp.comodoca.com - - Signature Algorithm: sha1WithRSAEncryption - 2d:97:34:7a:40:32:ea:70:97:2f:81:3b:4b:79:12:77:ae:fb: - aa:d7:1a:a8:da:5f:f3:a1:db:9e:4d:96:cb:37:7a:a8:ea:ee: - 9b:95:db:9d:bb:e1:27:9e:fd:45:ed:0e:52:96:ac:f4:27:bf: - 74:aa:92:f4:a5:c4:43:00:1f:0e:b5:78:f9:8a:c5:8c:70:bd: - 9a:7a:31:a3:29:d0:59:6b:4c:33:b5:2c:f8:8b:0f:92:63:57: - 56:ac:24:67:8a:5b:2f:29:c2:b1:b9:da:24:c5:e4:62:0e:7e: - 79:c3:fe:b9:83:ea:27:3b:bc:1d:43:b5:6e:17:aa:fb:c8:98: - 88:6a:d9:f2:7c:a1:f6:71:ba:19:4f:b8:38:e3:42:d7:f0:da: - b1:c0:23:df:dd:d7:f1:a7:ed:09:8f:56:a0:ab:c3:0b:cb:a4: - 92:80:81:92:1f:a9:6f:f9:6c:33:dc:3e:57:c6:a7:f2:1f:cc: - 2a:7c:e4:2c:4c:46:5f:eb:f3:61:f7:2b:c4:35:9f:8d:58:f5: - 3a:83:44:0e:d8:93:ac:4c:6b:cc:77:f4:03:cd:cc:dc:e0:1c: - 4b:5d:25:da:3d:5e:ce:77:8a:e1:3e:c6:d7:94:cd:70:49:3c: - ff:0e:bd:08:48:ab:e5:52:14:15:9d:0e:9c:1a:87:56:68:ad: - 9c:09:00:64 ------BEGIN CERTIFICATE----- -MIIFAzCCA+ugAwIBAgIQGLLLuqME8aAPwfLzJkYqSjANBgkqhkiG9w0BAQUFADCB -gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV -BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw -MDBaFw0xOTEyMzEyMzU5NTlaMHIxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVh -dGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9E -TyBDQSBMaW1pdGVkMRgwFgYDVQQDEw9Fc3NlbnRpYWxTU0wgQ0EwggEiMA0GCSqG -SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCt8AiwcsargxIxF3CJhakgEtSYau2A1NHf -5I5ZLdOWIY120j8YC0YZYwvHIPPlC92AGvFaoL0dds23Izp0XmEbdaqb1IX04XiR -0y3hr/yYLgbSeT1awB8hLRyuIVPGOqchfr7tZ291HRqfalsGs2rjsQuqag7nbWzD -ypWMN84hHzWQfdvaGlyoiBSyD8gSIF/F03/o4Tjg27z5H6Gq1huQByH6RSRQXScq -oChBRVt9vKCiL6qbfltTxfEFFld+Edc7tNkBdtzffRDPUanlOPJ7FAB1WfnwWdsX -Pvev5gItpHnBXaIcw5rIp6gLSApqLn8tl2X2xQScRMiZln5+pN0vAgMBAAGjggGD -MIIBfzAfBgNVHSMEGDAWgBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAdBgNVHQ4EFgQU -2svqrVsIXcz//CZUzknlVcY49PgwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQI -MAYBAf8CAQAwIAYDVR0lBBkwFwYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMD4GA1Ud -IAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwczovL3NlY3VyZS5jb21v -ZG8uY29tL0NQUzBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9kb2Nh -LmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDBsBggrBgEFBQcB -AQRgMF4wNgYIKwYBBQUHMAKGKmh0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NvbW9k -b1VUTlNHQ0NBLmNydDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2Eu -Y29tMA0GCSqGSIb3DQEBBQUAA4IBAQAtlzR6QDLqcJcvgTtLeRJ3rvuq1xqo2l/z -odueTZbLN3qo6u6bldudu+Ennv1F7Q5Slqz0J790qpL0pcRDAB8OtXj5isWMcL2a -ejGjKdBZa0wztSz4iw+SY1dWrCRnilsvKcKxudokxeRiDn55w/65g+onO7wdQ7Vu -F6r7yJiIatnyfKH2cboZT7g440LX8NqxwCPf3dfxp+0Jj1agq8MLy6SSgIGSH6lv -+Wwz3D5XxqfyH8wqfOQsTEZf6/Nh9yvENZ+NWPU6g0QO2JOsTGvMd/QDzczc4BxL -XSXaPV7Od4rhPsbXlM1wSTz/Dr0ISKvlUhQVnQ6cGodWaK2cCQBk ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert47[] = { - 0x30, 0x82, 0x05, 0x03, 0x30, 0x82, 0x03, 0xeb, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x18, 0xb2, 0xcb, 0xba, 0xa3, 0x04, 0xf1, 0xa0, 0x0f, - 0xc1, 0xf2, 0xf3, 0x26, 0x46, 0x2a, 0x4a, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, - 0x81, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x47, 0x42, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e, - 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0e, 0x06, - 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6c, 0x66, 0x6f, 0x72, - 0x64, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, - 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, - 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x1e, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x43, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, - 0x17, 0x0d, 0x30, 0x36, 0x31, 0x32, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, - 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x72, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x1b, 0x30, - 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, 0x74, - 0x65, 0x72, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, - 0x07, 0x53, 0x61, 0x6c, 0x66, 0x6f, 0x72, 0x64, 0x31, 0x1a, 0x30, 0x18, - 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x43, 0x4f, 0x4d, 0x4f, 0x44, - 0x4f, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, - 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, 0x45, - 0x73, 0x73, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x53, 0x53, 0x4c, 0x20, - 0x43, 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, 0xad, - 0xf0, 0x08, 0xb0, 0x72, 0xc6, 0xab, 0x83, 0x12, 0x31, 0x17, 0x70, 0x89, - 0x85, 0xa9, 0x20, 0x12, 0xd4, 0x98, 0x6a, 0xed, 0x80, 0xd4, 0xd1, 0xdf, - 0xe4, 0x8e, 0x59, 0x2d, 0xd3, 0x96, 0x21, 0x8d, 0x76, 0xd2, 0x3f, 0x18, - 0x0b, 0x46, 0x19, 0x63, 0x0b, 0xc7, 0x20, 0xf3, 0xe5, 0x0b, 0xdd, 0x80, - 0x1a, 0xf1, 0x5a, 0xa0, 0xbd, 0x1d, 0x76, 0xcd, 0xb7, 0x23, 0x3a, 0x74, - 0x5e, 0x61, 0x1b, 0x75, 0xaa, 0x9b, 0xd4, 0x85, 0xf4, 0xe1, 0x78, 0x91, - 0xd3, 0x2d, 0xe1, 0xaf, 0xfc, 0x98, 0x2e, 0x06, 0xd2, 0x79, 0x3d, 0x5a, - 0xc0, 0x1f, 0x21, 0x2d, 0x1c, 0xae, 0x21, 0x53, 0xc6, 0x3a, 0xa7, 0x21, - 0x7e, 0xbe, 0xed, 0x67, 0x6f, 0x75, 0x1d, 0x1a, 0x9f, 0x6a, 0x5b, 0x06, - 0xb3, 0x6a, 0xe3, 0xb1, 0x0b, 0xaa, 0x6a, 0x0e, 0xe7, 0x6d, 0x6c, 0xc3, - 0xca, 0x95, 0x8c, 0x37, 0xce, 0x21, 0x1f, 0x35, 0x90, 0x7d, 0xdb, 0xda, - 0x1a, 0x5c, 0xa8, 0x88, 0x14, 0xb2, 0x0f, 0xc8, 0x12, 0x20, 0x5f, 0xc5, - 0xd3, 0x7f, 0xe8, 0xe1, 0x38, 0xe0, 0xdb, 0xbc, 0xf9, 0x1f, 0xa1, 0xaa, - 0xd6, 0x1b, 0x90, 0x07, 0x21, 0xfa, 0x45, 0x24, 0x50, 0x5d, 0x27, 0x2a, - 0xa0, 0x28, 0x41, 0x45, 0x5b, 0x7d, 0xbc, 0xa0, 0xa2, 0x2f, 0xaa, 0x9b, - 0x7e, 0x5b, 0x53, 0xc5, 0xf1, 0x05, 0x16, 0x57, 0x7e, 0x11, 0xd7, 0x3b, - 0xb4, 0xd9, 0x01, 0x76, 0xdc, 0xdf, 0x7d, 0x10, 0xcf, 0x51, 0xa9, 0xe5, - 0x38, 0xf2, 0x7b, 0x14, 0x00, 0x75, 0x59, 0xf9, 0xf0, 0x59, 0xdb, 0x17, - 0x3e, 0xf7, 0xaf, 0xe6, 0x02, 0x2d, 0xa4, 0x79, 0xc1, 0x5d, 0xa2, 0x1c, - 0xc3, 0x9a, 0xc8, 0xa7, 0xa8, 0x0b, 0x48, 0x0a, 0x6a, 0x2e, 0x7f, 0x2d, - 0x97, 0x65, 0xf6, 0xc5, 0x04, 0x9c, 0x44, 0xc8, 0x99, 0x96, 0x7e, 0x7e, - 0xa4, 0xdd, 0x2f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x83, - 0x30, 0x82, 0x01, 0x7f, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, - 0x18, 0x30, 0x16, 0x80, 0x14, 0x0b, 0x58, 0xe5, 0x8b, 0xc6, 0x4c, 0x15, - 0x37, 0xa4, 0x40, 0xa9, 0x30, 0xa9, 0x21, 0xbe, 0x47, 0x36, 0x5a, 0x56, - 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, - 0xda, 0xcb, 0xea, 0xad, 0x5b, 0x08, 0x5d, 0xcc, 0xff, 0xfc, 0x26, 0x54, - 0xce, 0x49, 0xe5, 0x55, 0xc6, 0x38, 0xf4, 0xf8, 0x30, 0x0e, 0x06, 0x03, - 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, - 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, - 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x20, 0x06, 0x03, - 0x55, 0x1d, 0x25, 0x04, 0x19, 0x30, 0x17, 0x06, 0x0a, 0x2b, 0x06, 0x01, - 0x04, 0x01, 0x82, 0x37, 0x0a, 0x03, 0x03, 0x06, 0x09, 0x60, 0x86, 0x48, - 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01, 0x30, 0x3e, 0x06, 0x03, 0x55, 0x1d, - 0x20, 0x04, 0x37, 0x30, 0x35, 0x30, 0x33, 0x06, 0x04, 0x55, 0x1d, 0x20, - 0x00, 0x30, 0x2b, 0x30, 0x29, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x02, 0x01, 0x16, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, - 0x2f, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, - 0x64, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x49, - 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x42, 0x30, 0x40, 0x30, 0x3e, 0xa0, - 0x3c, 0xa0, 0x3a, 0x86, 0x38, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x63, 0x72, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x43, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x2e, 0x63, 0x72, - 0x6c, 0x30, 0x6c, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, - 0x01, 0x04, 0x60, 0x30, 0x5e, 0x30, 0x36, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, - 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x6f, 0x6d, 0x6f, 0x64, - 0x6f, 0x55, 0x54, 0x4e, 0x53, 0x47, 0x43, 0x43, 0x41, 0x2e, 0x63, 0x72, - 0x74, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, - 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, - 0x73, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, - 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x2d, - 0x97, 0x34, 0x7a, 0x40, 0x32, 0xea, 0x70, 0x97, 0x2f, 0x81, 0x3b, 0x4b, - 0x79, 0x12, 0x77, 0xae, 0xfb, 0xaa, 0xd7, 0x1a, 0xa8, 0xda, 0x5f, 0xf3, - 0xa1, 0xdb, 0x9e, 0x4d, 0x96, 0xcb, 0x37, 0x7a, 0xa8, 0xea, 0xee, 0x9b, - 0x95, 0xdb, 0x9d, 0xbb, 0xe1, 0x27, 0x9e, 0xfd, 0x45, 0xed, 0x0e, 0x52, - 0x96, 0xac, 0xf4, 0x27, 0xbf, 0x74, 0xaa, 0x92, 0xf4, 0xa5, 0xc4, 0x43, - 0x00, 0x1f, 0x0e, 0xb5, 0x78, 0xf9, 0x8a, 0xc5, 0x8c, 0x70, 0xbd, 0x9a, - 0x7a, 0x31, 0xa3, 0x29, 0xd0, 0x59, 0x6b, 0x4c, 0x33, 0xb5, 0x2c, 0xf8, - 0x8b, 0x0f, 0x92, 0x63, 0x57, 0x56, 0xac, 0x24, 0x67, 0x8a, 0x5b, 0x2f, - 0x29, 0xc2, 0xb1, 0xb9, 0xda, 0x24, 0xc5, 0xe4, 0x62, 0x0e, 0x7e, 0x79, - 0xc3, 0xfe, 0xb9, 0x83, 0xea, 0x27, 0x3b, 0xbc, 0x1d, 0x43, 0xb5, 0x6e, - 0x17, 0xaa, 0xfb, 0xc8, 0x98, 0x88, 0x6a, 0xd9, 0xf2, 0x7c, 0xa1, 0xf6, - 0x71, 0xba, 0x19, 0x4f, 0xb8, 0x38, 0xe3, 0x42, 0xd7, 0xf0, 0xda, 0xb1, - 0xc0, 0x23, 0xdf, 0xdd, 0xd7, 0xf1, 0xa7, 0xed, 0x09, 0x8f, 0x56, 0xa0, - 0xab, 0xc3, 0x0b, 0xcb, 0xa4, 0x92, 0x80, 0x81, 0x92, 0x1f, 0xa9, 0x6f, - 0xf9, 0x6c, 0x33, 0xdc, 0x3e, 0x57, 0xc6, 0xa7, 0xf2, 0x1f, 0xcc, 0x2a, - 0x7c, 0xe4, 0x2c, 0x4c, 0x46, 0x5f, 0xeb, 0xf3, 0x61, 0xf7, 0x2b, 0xc4, - 0x35, 0x9f, 0x8d, 0x58, 0xf5, 0x3a, 0x83, 0x44, 0x0e, 0xd8, 0x93, 0xac, - 0x4c, 0x6b, 0xcc, 0x77, 0xf4, 0x03, 0xcd, 0xcc, 0xdc, 0xe0, 0x1c, 0x4b, - 0x5d, 0x25, 0xda, 0x3d, 0x5e, 0xce, 0x77, 0x8a, 0xe1, 0x3e, 0xc6, 0xd7, - 0x94, 0xcd, 0x70, 0x49, 0x3c, 0xff, 0x0e, 0xbd, 0x08, 0x48, 0xab, 0xe5, - 0x52, 0x14, 0x15, 0x9d, 0x0e, 0x9c, 0x1a, 0x87, 0x56, 0x68, 0xad, 0x9c, - 0x09, 0x00, 0x64, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 11:a3:b4:d0:ec:8d:b7:7f:9d:a0:cd:5d:2d:51:2f:42 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO Certification Authority - Validity - Not Before: May 24 00:00:00 2010 GMT - Not After : May 30 10:48:38 2020 GMT - Subject: C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO Extended Validation Secure Server CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:cc:4a:96:33:cd:25:8d:67:ee:28:96:37:87:46: - f0:f6:04:a2:84:7f:53:aa:96:e6:1f:b1:02:1c:6e: - ed:7d:21:d4:d7:3c:1e:a2:d8:69:2f:a8:b7:f5:a2: - ed:64:58:64:e1:44:65:36:49:41:20:01:8d:3b:13: - e2:08:f3:0c:f2:57:39:93:37:b7:1c:93:44:83:8e: - bf:2d:f1:a1:05:75:da:6e:ee:7b:6f:1b:ea:76:83: - 28:74:4a:1c:2b:d3:f5:c4:03:72:93:af:86:ce:09: - 8c:3c:75:d4:c9:0a:2f:72:f3:ad:bd:0e:30:3c:84: - a1:73:1f:03:25:14:a5:8f:c3:d6:f4:b5:e4:dd:86: - 7a:f5:19:ba:68:f2:85:54:a2:30:11:ca:d1:92:cb: - 3b:74:06:12:a0:37:ab:6a:d8:54:11:df:6c:9a:16: - 94:b9:b4:a7:65:c6:74:2d:31:f3:4d:52:e9:55:51: - 9f:cb:3e:a2:8d:76:98:70:d2:6f:a6:65:45:2f:1b: - 85:bb:5b:6d:f9:f2:c0:04:66:13:84:7a:9d:ce:27: - d8:f4:44:9e:bf:ac:be:99:db:6b:4f:db:58:21:b0: - 89:27:b4:8f:32:d6:4b:5e:72:91:5e:df:05:9d:d9: - 49:2f:f4:b6:6f:50:1f:75:cb:80:9d:e6:d3:e4:d1: - f2:d3 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Authority Key Identifier: - keyid:0B:58:E5:8B:C6:4C:15:37:A4:40:A9:30:A9:21:BE:47:36:5A:56:FF - - X509v3 Subject Key Identifier: - 88:44:51:FF:50:2A:69:5E:2D:88:F4:21:BA:D9:0C:F2:CE:CB:EA:7C - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://secure.comodo.com/CPS - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.comodoca.com/COMODOCertificationAuthority.crl - - Authority Information Access: - CA Issuers - URI:http://crt.comodoca.com/COMODOAddTrustServerCA.crt - OCSP - URI:http://ocsp.comodoca.com - - Signature Algorithm: sha1WithRSAEncryption - 9a:43:bf:af:a4:72:5e:cd:7d:6f:7f:f4:fc:3d:8c:bb:70:e6: - 1e:dd:04:fd:3f:dc:9d:9f:bf:89:76:9b:f2:86:31:fc:7f:b3: - ed:2a:91:53:2c:e2:aa:b0:e3:c8:2c:71:f7:15:8a:23:1c:f1: - 69:2e:81:fb:b1:bc:62:0b:ab:1a:54:1c:d9:22:5e:34:4c:a5: - f6:23:0f:5d:7a:3d:db:43:cd:69:7e:17:37:52:cd:53:a1:c2: - 11:d4:53:78:27:64:d5:89:41:4d:16:55:bb:90:cb:f0:d8:e4: - dd:dd:d3:09:64:48:28:ff:32:23:84:2f:8c:7b:55:2f:cf:29: - 88:37:34:78:0f:33:aa:ff:b7:f2:96:a4:9b:44:80:b5:be:6c: - 56:54:ab:a4:81:9e:25:18:28:54:3a:7f:2c:63:cf:59:20:8c: - 18:6b:38:2c:b4:dd:ed:e3:40:de:0c:36:25:57:9a:c0:d1:60: - 9e:5e:03:68:97:ae:1a:3b:ea:45:d7:51:99:49:ee:44:59:56: - 0b:5e:b1:8f:68:ea:8a:9e:ca:d2:c9:a0:03:7e:70:25:f4:32: - c9:4e:50:83:87:a2:34:48:3d:4f:35:77:fc:d8:88:ea:f6:7d: - 1e:ce:43:b6:d5:c2:6a:7e:38:66:63:4d:e7:ee:32:ef:0f:24: - e8:2a:67:fa ------BEGIN CERTIFICATE----- -MIIFBjCCA+6gAwIBAgIQEaO00OyNt3+doM1dLVEvQjANBgkqhkiG9w0BAQUFADCB -gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G -A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV -BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xMDA1MjQwMDAw -MDBaFw0yMDA1MzAxMDQ4MzhaMIGOMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl -YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P -RE8gQ0EgTGltaXRlZDE0MDIGA1UEAxMrQ09NT0RPIEV4dGVuZGVkIFZhbGlkYXRp -b24gU2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAMxKljPNJY1n7iiWN4dG8PYEooR/U6qW5h+xAhxu7X0h1Nc8HqLYaS+ot/Wi -7WRYZOFEZTZJQSABjTsT4gjzDPJXOZM3txyTRIOOvy3xoQV12m7ue28b6naDKHRK -HCvT9cQDcpOvhs4JjDx11MkKL3Lzrb0OMDyEoXMfAyUUpY/D1vS15N2GevUZumjy -hVSiMBHK0ZLLO3QGEqA3q2rYVBHfbJoWlLm0p2XGdC0x801S6VVRn8s+oo12mHDS -b6ZlRS8bhbtbbfnywARmE4R6nc4n2PREnr+svpnba0/bWCGwiSe0jzLWS15ykV7f -BZ3ZSS/0tm9QH3XLgJ3m0+TR8tMCAwEAAaOCAWkwggFlMB8GA1UdIwQYMBaAFAtY -5YvGTBU3pECpMKkhvkc2Wlb/MB0GA1UdDgQWBBSIRFH/UCppXi2I9CG62Qzyzsvq -fDAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADA+BgNVHSAENzA1 -MDMGBFUdIAAwKzApBggrBgEFBQcCARYdaHR0cHM6Ly9zZWN1cmUuY29tb2RvLmNv -bS9DUFMwSQYDVR0fBEIwQDA+oDygOoY4aHR0cDovL2NybC5jb21vZG9jYS5jb20v -Q09NT0RPQ2VydGlmaWNhdGlvbkF1dGhvcml0eS5jcmwwdAYIKwYBBQUHAQEEaDBm -MD4GCCsGAQUFBzAChjJodHRwOi8vY3J0LmNvbW9kb2NhLmNvbS9DT01PRE9BZGRU -cnVzdFNlcnZlckNBLmNydDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2Rv -Y2EuY29tMA0GCSqGSIb3DQEBBQUAA4IBAQCaQ7+vpHJezX1vf/T8PYy7cOYe3QT9 -P9ydn7+JdpvyhjH8f7PtKpFTLOKqsOPILHH3FYojHPFpLoH7sbxiC6saVBzZIl40 -TKX2Iw9dej3bQ81pfhc3Us1TocIR1FN4J2TViUFNFlW7kMvw2OTd3dMJZEgo/zIj -hC+Me1UvzymINzR4DzOq/7fylqSbRIC1vmxWVKukgZ4lGChUOn8sY89ZIIwYazgs -tN3t40DeDDYlV5rA0WCeXgNol64aO+pF11GZSe5EWVYLXrGPaOqKnsrSyaADfnAl -9DLJTlCDh6I0SD1PNXf82Ijq9n0ezkO21cJqfjhmY03n7jLvDyToKmf6 ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert48[] = { - 0x30, 0x82, 0x05, 0x06, 0x30, 0x82, 0x03, 0xee, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x11, 0xa3, 0xb4, 0xd0, 0xec, 0x8d, 0xb7, 0x7f, 0x9d, - 0xa0, 0xcd, 0x5d, 0x2d, 0x51, 0x2f, 0x42, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, - 0x81, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x47, 0x42, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, - 0x12, 0x47, 0x72, 0x65, 0x61, 0x74, 0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e, - 0x63, 0x68, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0e, 0x06, - 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x53, 0x61, 0x6c, 0x66, 0x6f, 0x72, - 0x64, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, - 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, - 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x1e, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x43, - 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, - 0x17, 0x0d, 0x31, 0x30, 0x30, 0x35, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x35, 0x33, 0x30, 0x31, - 0x30, 0x34, 0x38, 0x33, 0x38, 0x5a, 0x30, 0x81, 0x8e, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x47, 0x42, 0x31, 0x1b, - 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x12, 0x47, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x73, - 0x74, 0x65, 0x72, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, - 0x13, 0x07, 0x53, 0x61, 0x6c, 0x66, 0x6f, 0x72, 0x64, 0x31, 0x1a, 0x30, - 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x43, 0x4f, 0x4d, 0x4f, - 0x44, 0x4f, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, - 0x64, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2b, - 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, - 0x64, 0x65, 0x64, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 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, 0xcc, 0x4a, 0x96, 0x33, 0xcd, 0x25, 0x8d, 0x67, - 0xee, 0x28, 0x96, 0x37, 0x87, 0x46, 0xf0, 0xf6, 0x04, 0xa2, 0x84, 0x7f, - 0x53, 0xaa, 0x96, 0xe6, 0x1f, 0xb1, 0x02, 0x1c, 0x6e, 0xed, 0x7d, 0x21, - 0xd4, 0xd7, 0x3c, 0x1e, 0xa2, 0xd8, 0x69, 0x2f, 0xa8, 0xb7, 0xf5, 0xa2, - 0xed, 0x64, 0x58, 0x64, 0xe1, 0x44, 0x65, 0x36, 0x49, 0x41, 0x20, 0x01, - 0x8d, 0x3b, 0x13, 0xe2, 0x08, 0xf3, 0x0c, 0xf2, 0x57, 0x39, 0x93, 0x37, - 0xb7, 0x1c, 0x93, 0x44, 0x83, 0x8e, 0xbf, 0x2d, 0xf1, 0xa1, 0x05, 0x75, - 0xda, 0x6e, 0xee, 0x7b, 0x6f, 0x1b, 0xea, 0x76, 0x83, 0x28, 0x74, 0x4a, - 0x1c, 0x2b, 0xd3, 0xf5, 0xc4, 0x03, 0x72, 0x93, 0xaf, 0x86, 0xce, 0x09, - 0x8c, 0x3c, 0x75, 0xd4, 0xc9, 0x0a, 0x2f, 0x72, 0xf3, 0xad, 0xbd, 0x0e, - 0x30, 0x3c, 0x84, 0xa1, 0x73, 0x1f, 0x03, 0x25, 0x14, 0xa5, 0x8f, 0xc3, - 0xd6, 0xf4, 0xb5, 0xe4, 0xdd, 0x86, 0x7a, 0xf5, 0x19, 0xba, 0x68, 0xf2, - 0x85, 0x54, 0xa2, 0x30, 0x11, 0xca, 0xd1, 0x92, 0xcb, 0x3b, 0x74, 0x06, - 0x12, 0xa0, 0x37, 0xab, 0x6a, 0xd8, 0x54, 0x11, 0xdf, 0x6c, 0x9a, 0x16, - 0x94, 0xb9, 0xb4, 0xa7, 0x65, 0xc6, 0x74, 0x2d, 0x31, 0xf3, 0x4d, 0x52, - 0xe9, 0x55, 0x51, 0x9f, 0xcb, 0x3e, 0xa2, 0x8d, 0x76, 0x98, 0x70, 0xd2, - 0x6f, 0xa6, 0x65, 0x45, 0x2f, 0x1b, 0x85, 0xbb, 0x5b, 0x6d, 0xf9, 0xf2, - 0xc0, 0x04, 0x66, 0x13, 0x84, 0x7a, 0x9d, 0xce, 0x27, 0xd8, 0xf4, 0x44, - 0x9e, 0xbf, 0xac, 0xbe, 0x99, 0xdb, 0x6b, 0x4f, 0xdb, 0x58, 0x21, 0xb0, - 0x89, 0x27, 0xb4, 0x8f, 0x32, 0xd6, 0x4b, 0x5e, 0x72, 0x91, 0x5e, 0xdf, - 0x05, 0x9d, 0xd9, 0x49, 0x2f, 0xf4, 0xb6, 0x6f, 0x50, 0x1f, 0x75, 0xcb, - 0x80, 0x9d, 0xe6, 0xd3, 0xe4, 0xd1, 0xf2, 0xd3, 0x02, 0x03, 0x01, 0x00, - 0x01, 0xa3, 0x82, 0x01, 0x69, 0x30, 0x82, 0x01, 0x65, 0x30, 0x1f, 0x06, - 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x0b, 0x58, - 0xe5, 0x8b, 0xc6, 0x4c, 0x15, 0x37, 0xa4, 0x40, 0xa9, 0x30, 0xa9, 0x21, - 0xbe, 0x47, 0x36, 0x5a, 0x56, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, - 0x0e, 0x04, 0x16, 0x04, 0x14, 0x88, 0x44, 0x51, 0xff, 0x50, 0x2a, 0x69, - 0x5e, 0x2d, 0x88, 0xf4, 0x21, 0xba, 0xd9, 0x0c, 0xf2, 0xce, 0xcb, 0xea, - 0x7c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, - 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, - 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, - 0x00, 0x30, 0x3e, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x37, 0x30, 0x35, - 0x30, 0x33, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2b, 0x30, 0x29, - 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1d, - 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x73, 0x65, 0x63, 0x75, - 0x72, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x49, 0x06, 0x03, 0x55, 0x1d, 0x1f, - 0x04, 0x42, 0x30, 0x40, 0x30, 0x3e, 0xa0, 0x3c, 0xa0, 0x3a, 0x86, 0x38, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x63, - 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x69, 0x74, 0x79, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x74, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x68, 0x30, 0x66, - 0x30, 0x3e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, - 0x86, 0x32, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, - 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, 0x63, 0x61, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x43, 0x4f, 0x4d, 0x4f, 0x44, 0x4f, 0x41, 0x64, 0x64, 0x54, - 0x72, 0x75, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x41, - 0x2e, 0x63, 0x72, 0x74, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x6f, 0x64, 0x6f, - 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, - 0x01, 0x00, 0x9a, 0x43, 0xbf, 0xaf, 0xa4, 0x72, 0x5e, 0xcd, 0x7d, 0x6f, - 0x7f, 0xf4, 0xfc, 0x3d, 0x8c, 0xbb, 0x70, 0xe6, 0x1e, 0xdd, 0x04, 0xfd, - 0x3f, 0xdc, 0x9d, 0x9f, 0xbf, 0x89, 0x76, 0x9b, 0xf2, 0x86, 0x31, 0xfc, - 0x7f, 0xb3, 0xed, 0x2a, 0x91, 0x53, 0x2c, 0xe2, 0xaa, 0xb0, 0xe3, 0xc8, - 0x2c, 0x71, 0xf7, 0x15, 0x8a, 0x23, 0x1c, 0xf1, 0x69, 0x2e, 0x81, 0xfb, - 0xb1, 0xbc, 0x62, 0x0b, 0xab, 0x1a, 0x54, 0x1c, 0xd9, 0x22, 0x5e, 0x34, - 0x4c, 0xa5, 0xf6, 0x23, 0x0f, 0x5d, 0x7a, 0x3d, 0xdb, 0x43, 0xcd, 0x69, - 0x7e, 0x17, 0x37, 0x52, 0xcd, 0x53, 0xa1, 0xc2, 0x11, 0xd4, 0x53, 0x78, - 0x27, 0x64, 0xd5, 0x89, 0x41, 0x4d, 0x16, 0x55, 0xbb, 0x90, 0xcb, 0xf0, - 0xd8, 0xe4, 0xdd, 0xdd, 0xd3, 0x09, 0x64, 0x48, 0x28, 0xff, 0x32, 0x23, - 0x84, 0x2f, 0x8c, 0x7b, 0x55, 0x2f, 0xcf, 0x29, 0x88, 0x37, 0x34, 0x78, - 0x0f, 0x33, 0xaa, 0xff, 0xb7, 0xf2, 0x96, 0xa4, 0x9b, 0x44, 0x80, 0xb5, - 0xbe, 0x6c, 0x56, 0x54, 0xab, 0xa4, 0x81, 0x9e, 0x25, 0x18, 0x28, 0x54, - 0x3a, 0x7f, 0x2c, 0x63, 0xcf, 0x59, 0x20, 0x8c, 0x18, 0x6b, 0x38, 0x2c, - 0xb4, 0xdd, 0xed, 0xe3, 0x40, 0xde, 0x0c, 0x36, 0x25, 0x57, 0x9a, 0xc0, - 0xd1, 0x60, 0x9e, 0x5e, 0x03, 0x68, 0x97, 0xae, 0x1a, 0x3b, 0xea, 0x45, - 0xd7, 0x51, 0x99, 0x49, 0xee, 0x44, 0x59, 0x56, 0x0b, 0x5e, 0xb1, 0x8f, - 0x68, 0xea, 0x8a, 0x9e, 0xca, 0xd2, 0xc9, 0xa0, 0x03, 0x7e, 0x70, 0x25, - 0xf4, 0x32, 0xc9, 0x4e, 0x50, 0x83, 0x87, 0xa2, 0x34, 0x48, 0x3d, 0x4f, - 0x35, 0x77, 0xfc, 0xd8, 0x88, 0xea, 0xf6, 0x7d, 0x1e, 0xce, 0x43, 0xb6, - 0xd5, 0xc2, 0x6a, 0x7e, 0x38, 0x66, 0x63, 0x4d, 0xe7, 0xee, 0x32, 0xef, - 0x0f, 0x24, 0xe8, 0x2a, 0x67, 0xfa, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 513 (0x201) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=Starfield Technologies, Inc., OU=Starfield Class 2 Certification Authority - Validity - Not Before: Nov 16 01:15:40 2006 GMT - Not After : Nov 16 01:15:40 2026 GMT - Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., OU=http://certificates.starfieldtech.com/repository, CN=Starfield Secure Certification Authority/serialNumber=10688435 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:e2:a7:5d:a3:ed:66:ef:6a:2f:2b:36:1f:dd:8d: - d3:05:02:a0:ca:0f:5e:19:ae:38:72:cf:16:da:54: - 4a:cb:48:0a:f4:a1:73:11:65:85:43:c9:5b:17:0c: - 9a:2b:be:0f:98:51:7a:60:29:0d:6c:de:e2:e8:e5: - 15:4d:56:ff:90:d1:a7:a6:04:3f:60:07:4a:ca:6f: - a5:10:e7:b3:f8:5c:b1:bc:2b:2a:dc:01:79:f5:1d: - 35:f5:7a:28:83:f2:93:73:82:89:ac:60:6d:cb:c2: - 48:c2:1d:d4:06:44:17:3c:ac:01:47:ab:3e:70:84: - 09:0b:b8:20:08:40:20:87:a1:63:1a:ca:3e:83:d2: - 37:b3:98:8d:32:3f:37:bf:a1:b7:5b:5f:de:5c:33: - 92:cf:3e:07:ce:b9:48:4b:e2:f0:55:50:2f:f8:70: - 42:89:d1:93:96:8a:63:d9:66:0d:e6:58:6e:b9:6d: - 90:bd:ca:dc:84:66:f2:39:8e:5b:a6:58:55:73:cb: - 62:6c:1b:d7:20:16:3b:2c:59:f5:cb:c8:56:32:4a: - 50:27:ba:55:d3:a8:01:cb:72:a9:74:8b:0c:ad:3a: - e5:15:b6:2a:df:65:f8:de:8a:f5:ef:84:3b:f9:e7: - 54:65:0b:80:bd:47:45:a5:f0:44:d8:53:3b:be:80: - f1:2f - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Subject Key Identifier: - 49:4B:52:27:D1:1B:BC:F2:A1:21:6A:62:7B:51:42:7A:8A:D7:D5:56 - X509v3 Authority Key Identifier: - keyid:BF:5F:B7:D1:CE:DD:1F:86:F4:5B:55:AC:DC:D7:10:C2:0E:A9:88:E7 - - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - Authority Information Access: - OCSP - URI:http://ocsp.starfieldtech.com - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://certificates.starfieldtech.com/repository/sfroot.crl - - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: http://certificates.starfieldtech.com/repository - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - Signature Algorithm: sha1WithRSAEncryption - 86:52:ba:b3:1f:a6:5e:6b:90:a6:64:2a:fc:45:b2:ae:9f:3e: - b3:62:af:db:1f:67:c4:bd:ca:a1:2f:c7:9c:0d:21:57:d0:f8: - 36:21:ce:3a:25:3e:78:76:b3:d9:dd:bc:de:fb:6c:84:5f:0c: - a3:0d:12:eb:11:3b:71:5f:80:1e:f1:1f:6d:0e:5f:c1:ec:d4: - a5:f7:65:bb:1f:4c:95:01:13:b2:6a:9c:0b:eb:1f:9d:b1:e7: - ed:19:0d:bc:85:7c:f3:17:bd:59:63:ae:a7:1a:05:cd:47:e3: - 2d:96:62:51:32:0a:08:68:4b:22:77:5f:f7:45:dc:61:de:f4: - cb:2b:22:29:44:25:d2:9f:0b:77:7a:a1:26:7c:4a:d7:0f:c2: - d1:3c:ba:0e:a7:95:9a:5b:05:0a:10:f9:55:5f:c1:97:8b:74: - cc:5e:28:69:13:7e:d0:0a:8d:9d:0f:60:54:7a:c4:8c:1b:35: - 0f:74:7a:70:b2:82:cf:1d:b5:e2:8a:db:2a:c6:b2:51:69:bf: - 12:17:92:60:17:aa:3d:5b:09:f8:87:65:1d:a7:a4:28:e5:22: - 02:03:82:44:9a:34:63:9e:fb:28:cf:e8:cd:2e:0e:52:20:ed: - 4a:cb:38:7c:9d:ae:6e:79:d7:95:2c:a8:91:f3:86:01:21:91: - 4b:b5:40:a4 ------BEGIN CERTIFICATE----- -MIIFBzCCA++gAwIBAgICAgEwDQYJKoZIhvcNAQEFBQAwaDELMAkGA1UEBhMCVVMx -JTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsT -KVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2 -MTExNjAxMTU0MFoXDTI2MTExNjAxMTU0MFowgdwxCzAJBgNVBAYTAlVTMRAwDgYD -VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy -ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTkwNwYDVQQLEzBodHRwOi8vY2VydGlm -aWNhdGVzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkxMTAvBgNVBAMTKFN0 -YXJmaWVsZCBTZWN1cmUgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxETAPBgNVBAUT -CDEwNjg4NDM1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4qddo+1m -72ovKzYf3Y3TBQKgyg9eGa44cs8W2lRKy0gK9KFzEWWFQ8lbFwyaK74PmFF6YCkN -bN7i6OUVTVb/kNGnpgQ/YAdKym+lEOez+FyxvCsq3AF59R019Xoog/KTc4KJrGBt -y8JIwh3UBkQXPKwBR6s+cIQJC7ggCEAgh6FjGso+g9I3s5iNMj83v6G3W1/eXDOS -zz4HzrlIS+LwVVAv+HBCidGTlopj2WYN5lhuuW2QvcrchGbyOY5bplhVc8tibBvX -IBY7LFn1y8hWMkpQJ7pV06gBy3KpdIsMrTrlFbYq32X43or174Q7+edUZQuAvUdF -pfBE2FM7voDxLwIDAQABo4IBRDCCAUAwHQYDVR0OBBYEFElLUifRG7zyoSFqYntR -QnqK19VWMB8GA1UdIwQYMBaAFL9ft9HO3R+G9FtVrNzXEMIOqYjnMBIGA1UdEwEB -/wQIMAYBAf8CAQAwOQYIKwYBBQUHAQEELTArMCkGCCsGAQUFBzABhh1odHRwOi8v -b2NzcC5zdGFyZmllbGR0ZWNoLmNvbTBMBgNVHR8ERTBDMEGgP6A9hjtodHRwOi8v -Y2VydGlmaWNhdGVzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkvc2Zyb290 -LmNybDBRBgNVHSAESjBIMEYGBFUdIAAwPjA8BggrBgEFBQcCARYwaHR0cDovL2Nl -cnRpZmljYXRlcy5zdGFyZmllbGR0ZWNoLmNvbS9yZXBvc2l0b3J5MA4GA1UdDwEB -/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAhlK6sx+mXmuQpmQq/EWyrp8+s2Kv -2x9nxL3KoS/HnA0hV9D4NiHOOiU+eHaz2d283vtshF8Mow0S6xE7cV+AHvEfbQ5f -wezUpfdlux9MlQETsmqcC+sfnbHn7RkNvIV88xe9WWOupxoFzUfjLZZiUTIKCGhL -Indf90XcYd70yysiKUQl0p8Ld3qhJnxK1w/C0Ty6DqeVmlsFChD5VV/Bl4t0zF4o -aRN+0AqNnQ9gVHrEjBs1D3R6cLKCzx214orbKsayUWm/EheSYBeqPVsJ+IdlHaek -KOUiAgOCRJo0Y577KM/ozS4OUiDtSss4fJ2ubnnXlSyokfOGASGRS7VApA== ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert49[] = { - 0x30, 0x82, 0x05, 0x07, 0x30, 0x82, 0x03, 0xef, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x02, 0x02, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x68, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53, 0x74, - 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, - 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49, 0x6e, - 0x63, 0x2e, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, - 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x43, - 0x6c, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, - 0x31, 0x31, 0x31, 0x36, 0x30, 0x31, 0x31, 0x35, 0x34, 0x30, 0x5a, 0x17, - 0x0d, 0x32, 0x36, 0x31, 0x31, 0x31, 0x36, 0x30, 0x31, 0x31, 0x35, 0x34, - 0x30, 0x5a, 0x30, 0x81, 0xdc, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, - 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, - 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x25, 0x30, - 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53, 0x74, 0x61, 0x72, - 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6e, 0x6f, - 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x30, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, - 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x31, - 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, 0x53, 0x74, - 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x53, 0x65, 0x63, 0x75, - 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x74, 0x79, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x05, 0x13, - 0x08, 0x31, 0x30, 0x36, 0x38, 0x38, 0x34, 0x33, 0x35, 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, 0xe2, 0xa7, 0x5d, 0xa3, 0xed, 0x66, - 0xef, 0x6a, 0x2f, 0x2b, 0x36, 0x1f, 0xdd, 0x8d, 0xd3, 0x05, 0x02, 0xa0, - 0xca, 0x0f, 0x5e, 0x19, 0xae, 0x38, 0x72, 0xcf, 0x16, 0xda, 0x54, 0x4a, - 0xcb, 0x48, 0x0a, 0xf4, 0xa1, 0x73, 0x11, 0x65, 0x85, 0x43, 0xc9, 0x5b, - 0x17, 0x0c, 0x9a, 0x2b, 0xbe, 0x0f, 0x98, 0x51, 0x7a, 0x60, 0x29, 0x0d, - 0x6c, 0xde, 0xe2, 0xe8, 0xe5, 0x15, 0x4d, 0x56, 0xff, 0x90, 0xd1, 0xa7, - 0xa6, 0x04, 0x3f, 0x60, 0x07, 0x4a, 0xca, 0x6f, 0xa5, 0x10, 0xe7, 0xb3, - 0xf8, 0x5c, 0xb1, 0xbc, 0x2b, 0x2a, 0xdc, 0x01, 0x79, 0xf5, 0x1d, 0x35, - 0xf5, 0x7a, 0x28, 0x83, 0xf2, 0x93, 0x73, 0x82, 0x89, 0xac, 0x60, 0x6d, - 0xcb, 0xc2, 0x48, 0xc2, 0x1d, 0xd4, 0x06, 0x44, 0x17, 0x3c, 0xac, 0x01, - 0x47, 0xab, 0x3e, 0x70, 0x84, 0x09, 0x0b, 0xb8, 0x20, 0x08, 0x40, 0x20, - 0x87, 0xa1, 0x63, 0x1a, 0xca, 0x3e, 0x83, 0xd2, 0x37, 0xb3, 0x98, 0x8d, - 0x32, 0x3f, 0x37, 0xbf, 0xa1, 0xb7, 0x5b, 0x5f, 0xde, 0x5c, 0x33, 0x92, - 0xcf, 0x3e, 0x07, 0xce, 0xb9, 0x48, 0x4b, 0xe2, 0xf0, 0x55, 0x50, 0x2f, - 0xf8, 0x70, 0x42, 0x89, 0xd1, 0x93, 0x96, 0x8a, 0x63, 0xd9, 0x66, 0x0d, - 0xe6, 0x58, 0x6e, 0xb9, 0x6d, 0x90, 0xbd, 0xca, 0xdc, 0x84, 0x66, 0xf2, - 0x39, 0x8e, 0x5b, 0xa6, 0x58, 0x55, 0x73, 0xcb, 0x62, 0x6c, 0x1b, 0xd7, - 0x20, 0x16, 0x3b, 0x2c, 0x59, 0xf5, 0xcb, 0xc8, 0x56, 0x32, 0x4a, 0x50, - 0x27, 0xba, 0x55, 0xd3, 0xa8, 0x01, 0xcb, 0x72, 0xa9, 0x74, 0x8b, 0x0c, - 0xad, 0x3a, 0xe5, 0x15, 0xb6, 0x2a, 0xdf, 0x65, 0xf8, 0xde, 0x8a, 0xf5, - 0xef, 0x84, 0x3b, 0xf9, 0xe7, 0x54, 0x65, 0x0b, 0x80, 0xbd, 0x47, 0x45, - 0xa5, 0xf0, 0x44, 0xd8, 0x53, 0x3b, 0xbe, 0x80, 0xf1, 0x2f, 0x02, 0x03, - 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x44, 0x30, 0x82, 0x01, 0x40, 0x30, - 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x49, 0x4b, - 0x52, 0x27, 0xd1, 0x1b, 0xbc, 0xf2, 0xa1, 0x21, 0x6a, 0x62, 0x7b, 0x51, - 0x42, 0x7a, 0x8a, 0xd7, 0xd5, 0x56, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, - 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xbf, 0x5f, 0xb7, 0xd1, 0xce, - 0xdd, 0x1f, 0x86, 0xf4, 0x5b, 0x55, 0xac, 0xdc, 0xd7, 0x10, 0xc2, 0x0e, - 0xa9, 0x88, 0xe7, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, - 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, - 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, - 0x2d, 0x30, 0x2b, 0x30, 0x29, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x30, 0x01, 0x86, 0x1d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4c, - 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0xa0, - 0x3f, 0xa0, 0x3d, 0x86, 0x3b, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, - 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, - 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x73, 0x66, 0x72, 0x6f, 0x6f, 0x74, - 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x51, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, - 0x4a, 0x30, 0x48, 0x30, 0x46, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, - 0x3e, 0x30, 0x3c, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, - 0x01, 0x16, 0x30, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x73, - 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, - 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, - 0x01, 0x01, 0x00, 0x86, 0x52, 0xba, 0xb3, 0x1f, 0xa6, 0x5e, 0x6b, 0x90, - 0xa6, 0x64, 0x2a, 0xfc, 0x45, 0xb2, 0xae, 0x9f, 0x3e, 0xb3, 0x62, 0xaf, - 0xdb, 0x1f, 0x67, 0xc4, 0xbd, 0xca, 0xa1, 0x2f, 0xc7, 0x9c, 0x0d, 0x21, - 0x57, 0xd0, 0xf8, 0x36, 0x21, 0xce, 0x3a, 0x25, 0x3e, 0x78, 0x76, 0xb3, - 0xd9, 0xdd, 0xbc, 0xde, 0xfb, 0x6c, 0x84, 0x5f, 0x0c, 0xa3, 0x0d, 0x12, - 0xeb, 0x11, 0x3b, 0x71, 0x5f, 0x80, 0x1e, 0xf1, 0x1f, 0x6d, 0x0e, 0x5f, - 0xc1, 0xec, 0xd4, 0xa5, 0xf7, 0x65, 0xbb, 0x1f, 0x4c, 0x95, 0x01, 0x13, - 0xb2, 0x6a, 0x9c, 0x0b, 0xeb, 0x1f, 0x9d, 0xb1, 0xe7, 0xed, 0x19, 0x0d, - 0xbc, 0x85, 0x7c, 0xf3, 0x17, 0xbd, 0x59, 0x63, 0xae, 0xa7, 0x1a, 0x05, - 0xcd, 0x47, 0xe3, 0x2d, 0x96, 0x62, 0x51, 0x32, 0x0a, 0x08, 0x68, 0x4b, - 0x22, 0x77, 0x5f, 0xf7, 0x45, 0xdc, 0x61, 0xde, 0xf4, 0xcb, 0x2b, 0x22, - 0x29, 0x44, 0x25, 0xd2, 0x9f, 0x0b, 0x77, 0x7a, 0xa1, 0x26, 0x7c, 0x4a, - 0xd7, 0x0f, 0xc2, 0xd1, 0x3c, 0xba, 0x0e, 0xa7, 0x95, 0x9a, 0x5b, 0x05, - 0x0a, 0x10, 0xf9, 0x55, 0x5f, 0xc1, 0x97, 0x8b, 0x74, 0xcc, 0x5e, 0x28, - 0x69, 0x13, 0x7e, 0xd0, 0x0a, 0x8d, 0x9d, 0x0f, 0x60, 0x54, 0x7a, 0xc4, - 0x8c, 0x1b, 0x35, 0x0f, 0x74, 0x7a, 0x70, 0xb2, 0x82, 0xcf, 0x1d, 0xb5, - 0xe2, 0x8a, 0xdb, 0x2a, 0xc6, 0xb2, 0x51, 0x69, 0xbf, 0x12, 0x17, 0x92, - 0x60, 0x17, 0xaa, 0x3d, 0x5b, 0x09, 0xf8, 0x87, 0x65, 0x1d, 0xa7, 0xa4, - 0x28, 0xe5, 0x22, 0x02, 0x03, 0x82, 0x44, 0x9a, 0x34, 0x63, 0x9e, 0xfb, - 0x28, 0xcf, 0xe8, 0xcd, 0x2e, 0x0e, 0x52, 0x20, 0xed, 0x4a, 0xcb, 0x38, - 0x7c, 0x9d, 0xae, 0x6e, 0x79, 0xd7, 0x95, 0x2c, 0xa8, 0x91, 0xf3, 0x86, - 0x01, 0x21, 0x91, 0x4b, 0xb5, 0x40, 0xa4, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 1276028635 (0x4c0ea6db) - Signature Algorithm: sha1WithRSAEncryption - Issuer: O=Entrust.net, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Certification Authority (2048) - Validity - Not Before: Oct 1 19:42:24 2006 GMT - Not After : Nov 4 03:38:44 2016 GMT - Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:c6:cc:e5:73:e6:fb:d4:bb:e5:2d:2d:32:a6:df: - e5:81:3f:c9:cd:25:49:b6:71:2a:c3:d5:94:34:67: - a2:0a:1c:b0:5f:69:a6:40:b1:c4:b7:b2:8f:d0:98: - a4:a9:41:59:3a:d3:dc:94:d6:3c:db:74:38:a4:4a: - cc:4d:25:82:f7:4a:a5:53:12:38:ee:f3:49:6d:71: - 91:7e:63:b6:ab:a6:5f:c3:a4:84:f8:4f:62:51:be: - f8:c5:ec:db:38:92:e3:06:e5:08:91:0c:c4:28:41: - 55:fb:cb:5a:89:15:7e:71:e8:35:bf:4d:72:09:3d: - be:3a:38:50:5b:77:31:1b:8d:b3:c7:24:45:9a:a7: - ac:6d:00:14:5a:04:b7:ba:13:eb:51:0a:98:41:41: - 22:4e:65:61:87:81:41:50:a6:79:5c:89:de:19:4a: - 57:d5:2e:e6:5d:1c:53:2c:7e:98:cd:1a:06:16:a4: - 68:73:d0:34:04:13:5c:a1:71:d3:5a:7c:55:db:5e: - 64:e1:37:87:30:56:04:e5:11:b4:29:80:12:f1:79: - 39:88:a2:02:11:7c:27:66:b7:88:b7:78:f2:ca:0a: - a8:38:ab:0a:64:c2:bf:66:5d:95:84:c1:a1:25:1e: - 87:5d:1a:50:0b:20:12:cc:41:bb:6e:0b:51:38:b8: - 4b:cb - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:1 - X509v3 Extended Key Usage: - TLS Web Server Authentication, TLS Web Client Authentication, E-mail Protection - Authority Information Access: - OCSP - URI:http://ocsp.entrust.net - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.entrust.net/2048ca.crl - - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: http://www.digicert.com/ssl-cps-repository.htm - - X509v3 Subject Key Identifier: - B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3 - X509v3 Authority Key Identifier: - keyid:55:E4:81:D1:11:80:BE:D8:89:B9:08:A3:31:F9:A1:24:09:16:B9:70 - - 1.2.840.113533.7.65.0: - 0 -..V8.1.... - Signature Algorithm: sha1WithRSAEncryption - 59:e1:94:14:89:c6:72:3c:e7:6b:75:4b:25:7a:2d:3e:a3:db: - ac:3c:72:4f:9b:30:b0:a2:5e:d6:62:5d:8f:36:6b:e7:dd:23: - 59:c1:80:2c:a0:ed:7e:11:a0:c9:a3:bb:f6:96:b8:34:c9:fe: - c6:d7:58:b4:bb:27:7f:e5:6b:23:04:68:61:4b:16:57:df:e1: - 7e:c0:c5:36:8f:0c:04:de:ef:77:68:68:83:6d:7c:05:fb:45: - dd:ce:16:56:91:39:d2:58:91:51:95:87:9e:4d:b4:0a:d7:05: - 63:83:43:26:de:08:a6:19:77:9d:fe:59:a2:5f:db:32:33:4a: - 65:10:c4:47:ef:ba:57:07:1f:4c:9f:af:68:65:ef:67:6d:9a: - de:1e:5e:4e:87:85:ee:9d:0d:7b:3d:d2:03:a9:dd:b7:05:04: - 9e:95:0d:c1:b2:11:fd:5a:77:c4:1f:98:9f:2e:a0:d0:c9:7c: - d3:34:62:f5:2f:96:37:48:48:b4:21:fb:2f:ad:53:65:34:c2: - 7b:4a:7c:fc:90:49:9f:f3:f7:37:08:9e:41:00:b2:63:1b:4b: - b9:f6:c1:7d:59:66:ab:d1:f3:8a:30:05:18:7a:41:47:ab:c7: - 67:14:3a:7c:60:b1:08:4e:d0:ce:c7:e1:ad:a6:4d:ee:ae:32: - ac:ac:c6:5a ------BEGIN CERTIFICATE----- -MIIFBzCCA++gAwIBAgIETA6m2zANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML -RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp -bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 -IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp -ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw0wNjEwMDExOTQyMjRaFw0xNjEx -MDQwMzM4NDRaMGwxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx -GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xKzApBgNVBAMTIkRpZ2lDZXJ0IEhp -Z2ggQXNzdXJhbmNlIEVWIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQDGzOVz5vvUu+UtLTKm3+WBP8nNJUm2cSrD1ZQ0Z6IKHLBfaaZAscS3 -so/QmKSpQVk609yU1jzbdDikSsxNJYL3SqVTEjju80ltcZF+Y7arpl/DpIT4T2JR -vvjF7Ns4kuMG5QiRDMQoQVX7y1qJFX5x6DW/TXIJPb46OFBbdzEbjbPHJEWap6xt -ABRaBLe6E+tRCphBQSJOZWGHgUFQpnlcid4ZSlfVLuZdHFMsfpjNGgYWpGhz0DQE -E1yhcdNafFXbXmThN4cwVgTlEbQpgBLxeTmIogIRfCdmt4i3ePLKCqg4qwpkwr9m -XZWEwaElHoddGlALIBLMQbtuC1E4uEvLAgMBAAGjggFmMIIBYjAOBgNVHQ8BAf8E -BAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBATAnBgNVHSUEIDAeBggrBgEFBQcDAQYI -KwYBBQUHAwIGCCsGAQUFBwMEMDMGCCsGAQUFBwEBBCcwJTAjBggrBgEFBQcwAYYX -aHR0cDovL29jc3AuZW50cnVzdC5uZXQwMgYDVR0fBCswKTAnoCWgI4YhaHR0cDov -L2NybC5lbnRydXN0Lm5ldC8yMDQ4Y2EuY3JsME8GA1UdIARIMEYwRAYEVR0gADA8 -MDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9zc2wtY3BzLXJl -cG9zaXRvcnkuaHRtMB0GA1UdDgQWBBSxPsNpA/i/RwHUmCYaCALvY2QrwzAfBgNV -HSMEGDAWgBRV5IHREYC+2Im5CKMx+aEkCRa5cDAZBgkqhkiG9n0HQQAEDDAKGwRW -OC4xAwIAgTANBgkqhkiG9w0BAQUFAAOCAQEAWeGUFInGcjzna3VLJXotPqPbrDxy -T5swsKJe1mJdjzZr590jWcGALKDtfhGgyaO79pa4NMn+xtdYtLsnf+VrIwRoYUsW -V9/hfsDFNo8MBN7vd2hog218BftF3c4WVpE50liRUZWHnk20CtcFY4NDJt4Iphl3 -nf5Zol/bMjNKZRDER++6VwcfTJ+vaGXvZ22a3h5eToeF7p0Nez3SA6ndtwUEnpUN -wbIR/Vp3xB+Yny6g0Ml80zRi9S+WN0hItCH7L61TZTTCe0p8/JBJn/P3NwieQQCy -YxtLufbBfVlmq9HzijAFGHpBR6vHZxQ6fGCxCE7QzsfhraZN7q4yrKzGWg== ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert50[] = { - 0x30, 0x82, 0x05, 0x07, 0x30, 0x82, 0x03, 0xef, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x04, 0x4c, 0x0e, 0xa6, 0xdb, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, - 0xb4, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0b, - 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x31, - 0x40, 0x30, 0x3e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x14, 0x37, 0x77, 0x77, - 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, - 0x74, 0x2f, 0x43, 0x50, 0x53, 0x5f, 0x32, 0x30, 0x34, 0x38, 0x20, 0x69, - 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x20, 0x62, 0x79, 0x20, 0x72, 0x65, - 0x66, 0x2e, 0x20, 0x28, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x20, 0x6c, - 0x69, 0x61, 0x62, 0x2e, 0x29, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, - 0x04, 0x0b, 0x13, 0x1c, 0x28, 0x63, 0x29, 0x20, 0x31, 0x39, 0x39, 0x39, - 0x20, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, - 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x33, 0x30, 0x31, - 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2a, 0x45, 0x6e, 0x74, 0x72, 0x75, - 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x28, 0x32, 0x30, 0x34, 0x38, - 0x29, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x30, 0x30, 0x31, 0x31, - 0x39, 0x34, 0x32, 0x32, 0x34, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x31, 0x31, - 0x30, 0x34, 0x30, 0x33, 0x33, 0x38, 0x34, 0x34, 0x5a, 0x30, 0x6c, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, - 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44, - 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, - 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, 0x77, - 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, - 0x6f, 0x6d, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, - 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48, 0x69, - 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, - 0x20, 0x45, 0x56, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 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, 0xc6, 0xcc, 0xe5, 0x73, - 0xe6, 0xfb, 0xd4, 0xbb, 0xe5, 0x2d, 0x2d, 0x32, 0xa6, 0xdf, 0xe5, 0x81, - 0x3f, 0xc9, 0xcd, 0x25, 0x49, 0xb6, 0x71, 0x2a, 0xc3, 0xd5, 0x94, 0x34, - 0x67, 0xa2, 0x0a, 0x1c, 0xb0, 0x5f, 0x69, 0xa6, 0x40, 0xb1, 0xc4, 0xb7, - 0xb2, 0x8f, 0xd0, 0x98, 0xa4, 0xa9, 0x41, 0x59, 0x3a, 0xd3, 0xdc, 0x94, - 0xd6, 0x3c, 0xdb, 0x74, 0x38, 0xa4, 0x4a, 0xcc, 0x4d, 0x25, 0x82, 0xf7, - 0x4a, 0xa5, 0x53, 0x12, 0x38, 0xee, 0xf3, 0x49, 0x6d, 0x71, 0x91, 0x7e, - 0x63, 0xb6, 0xab, 0xa6, 0x5f, 0xc3, 0xa4, 0x84, 0xf8, 0x4f, 0x62, 0x51, - 0xbe, 0xf8, 0xc5, 0xec, 0xdb, 0x38, 0x92, 0xe3, 0x06, 0xe5, 0x08, 0x91, - 0x0c, 0xc4, 0x28, 0x41, 0x55, 0xfb, 0xcb, 0x5a, 0x89, 0x15, 0x7e, 0x71, - 0xe8, 0x35, 0xbf, 0x4d, 0x72, 0x09, 0x3d, 0xbe, 0x3a, 0x38, 0x50, 0x5b, - 0x77, 0x31, 0x1b, 0x8d, 0xb3, 0xc7, 0x24, 0x45, 0x9a, 0xa7, 0xac, 0x6d, - 0x00, 0x14, 0x5a, 0x04, 0xb7, 0xba, 0x13, 0xeb, 0x51, 0x0a, 0x98, 0x41, - 0x41, 0x22, 0x4e, 0x65, 0x61, 0x87, 0x81, 0x41, 0x50, 0xa6, 0x79, 0x5c, - 0x89, 0xde, 0x19, 0x4a, 0x57, 0xd5, 0x2e, 0xe6, 0x5d, 0x1c, 0x53, 0x2c, - 0x7e, 0x98, 0xcd, 0x1a, 0x06, 0x16, 0xa4, 0x68, 0x73, 0xd0, 0x34, 0x04, - 0x13, 0x5c, 0xa1, 0x71, 0xd3, 0x5a, 0x7c, 0x55, 0xdb, 0x5e, 0x64, 0xe1, - 0x37, 0x87, 0x30, 0x56, 0x04, 0xe5, 0x11, 0xb4, 0x29, 0x80, 0x12, 0xf1, - 0x79, 0x39, 0x88, 0xa2, 0x02, 0x11, 0x7c, 0x27, 0x66, 0xb7, 0x88, 0xb7, - 0x78, 0xf2, 0xca, 0x0a, 0xa8, 0x38, 0xab, 0x0a, 0x64, 0xc2, 0xbf, 0x66, - 0x5d, 0x95, 0x84, 0xc1, 0xa1, 0x25, 0x1e, 0x87, 0x5d, 0x1a, 0x50, 0x0b, - 0x20, 0x12, 0xcc, 0x41, 0xbb, 0x6e, 0x0b, 0x51, 0x38, 0xb8, 0x4b, 0xcb, - 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x66, 0x30, 0x82, 0x01, - 0x62, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, - 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, - 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, - 0x01, 0x30, 0x27, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x20, 0x30, 0x1e, - 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08, 0x2b, 0x06, - 0x01, 0x05, 0x05, 0x07, 0x03, 0x04, 0x30, 0x33, 0x06, 0x08, 0x2b, 0x06, - 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x27, 0x30, 0x25, 0x30, 0x23, - 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x17, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, - 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x30, - 0x32, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2b, 0x30, 0x29, 0x30, 0x27, - 0xa0, 0x25, 0xa0, 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, - 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x32, 0x30, 0x34, 0x38, 0x63, 0x61, 0x2e, - 0x63, 0x72, 0x6c, 0x30, 0x4f, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x48, - 0x30, 0x46, 0x30, 0x44, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x3c, - 0x30, 0x3a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, - 0x16, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x73, 0x73, 0x6c, 0x2d, 0x63, 0x70, 0x73, 0x2d, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x68, 0x74, 0x6d, - 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb1, - 0x3e, 0xc3, 0x69, 0x03, 0xf8, 0xbf, 0x47, 0x01, 0xd4, 0x98, 0x26, 0x1a, - 0x08, 0x02, 0xef, 0x63, 0x64, 0x2b, 0xc3, 0x30, 0x1f, 0x06, 0x03, 0x55, - 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x55, 0xe4, 0x81, 0xd1, - 0x11, 0x80, 0xbe, 0xd8, 0x89, 0xb9, 0x08, 0xa3, 0x31, 0xf9, 0xa1, 0x24, - 0x09, 0x16, 0xb9, 0x70, 0x30, 0x19, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf6, 0x7d, 0x07, 0x41, 0x00, 0x04, 0x0c, 0x30, 0x0a, 0x1b, 0x04, 0x56, - 0x38, 0x2e, 0x31, 0x03, 0x02, 0x00, 0x81, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, - 0x01, 0x01, 0x00, 0x59, 0xe1, 0x94, 0x14, 0x89, 0xc6, 0x72, 0x3c, 0xe7, - 0x6b, 0x75, 0x4b, 0x25, 0x7a, 0x2d, 0x3e, 0xa3, 0xdb, 0xac, 0x3c, 0x72, - 0x4f, 0x9b, 0x30, 0xb0, 0xa2, 0x5e, 0xd6, 0x62, 0x5d, 0x8f, 0x36, 0x6b, - 0xe7, 0xdd, 0x23, 0x59, 0xc1, 0x80, 0x2c, 0xa0, 0xed, 0x7e, 0x11, 0xa0, - 0xc9, 0xa3, 0xbb, 0xf6, 0x96, 0xb8, 0x34, 0xc9, 0xfe, 0xc6, 0xd7, 0x58, - 0xb4, 0xbb, 0x27, 0x7f, 0xe5, 0x6b, 0x23, 0x04, 0x68, 0x61, 0x4b, 0x16, - 0x57, 0xdf, 0xe1, 0x7e, 0xc0, 0xc5, 0x36, 0x8f, 0x0c, 0x04, 0xde, 0xef, - 0x77, 0x68, 0x68, 0x83, 0x6d, 0x7c, 0x05, 0xfb, 0x45, 0xdd, 0xce, 0x16, - 0x56, 0x91, 0x39, 0xd2, 0x58, 0x91, 0x51, 0x95, 0x87, 0x9e, 0x4d, 0xb4, - 0x0a, 0xd7, 0x05, 0x63, 0x83, 0x43, 0x26, 0xde, 0x08, 0xa6, 0x19, 0x77, - 0x9d, 0xfe, 0x59, 0xa2, 0x5f, 0xdb, 0x32, 0x33, 0x4a, 0x65, 0x10, 0xc4, - 0x47, 0xef, 0xba, 0x57, 0x07, 0x1f, 0x4c, 0x9f, 0xaf, 0x68, 0x65, 0xef, - 0x67, 0x6d, 0x9a, 0xde, 0x1e, 0x5e, 0x4e, 0x87, 0x85, 0xee, 0x9d, 0x0d, - 0x7b, 0x3d, 0xd2, 0x03, 0xa9, 0xdd, 0xb7, 0x05, 0x04, 0x9e, 0x95, 0x0d, - 0xc1, 0xb2, 0x11, 0xfd, 0x5a, 0x77, 0xc4, 0x1f, 0x98, 0x9f, 0x2e, 0xa0, - 0xd0, 0xc9, 0x7c, 0xd3, 0x34, 0x62, 0xf5, 0x2f, 0x96, 0x37, 0x48, 0x48, - 0xb4, 0x21, 0xfb, 0x2f, 0xad, 0x53, 0x65, 0x34, 0xc2, 0x7b, 0x4a, 0x7c, - 0xfc, 0x90, 0x49, 0x9f, 0xf3, 0xf7, 0x37, 0x08, 0x9e, 0x41, 0x00, 0xb2, - 0x63, 0x1b, 0x4b, 0xb9, 0xf6, 0xc1, 0x7d, 0x59, 0x66, 0xab, 0xd1, 0xf3, - 0x8a, 0x30, 0x05, 0x18, 0x7a, 0x41, 0x47, 0xab, 0xc7, 0x67, 0x14, 0x3a, - 0x7c, 0x60, 0xb1, 0x08, 0x4e, 0xd0, 0xce, 0xc7, 0xe1, 0xad, 0xa6, 0x4d, - 0xee, 0xae, 0x32, 0xac, 0xac, 0xc6, 0x5a, -};
diff --git a/net/quic/core/crypto/common_cert_set_1b.inc b/net/quic/core/crypto/common_cert_set_1b.inc deleted file mode 100644 index 326b1fd..0000000 --- a/net/quic/core/crypto/common_cert_set_1b.inc +++ /dev/null
@@ -1,2711 +0,0 @@ -/* Copyright (c) 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 contains common certificates. It's designed to be #included in - * another file, in a namespace. */ - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 7b:11:55:eb:78:9a:90:85:b5:8c:92:ff:42:b7:fe:56 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - Validity - Not Before: Nov 17 00:00:00 2006 GMT - Not After : Nov 16 23:59:59 2016 GMT - Subject: C=US, O=thawte, Inc., OU=Terms of use at https://www.thawte.com/cps (c)06, CN=thawte Extended Validation SSL CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:b5:8d:47:f7:b0:48:76:9b:bd:fb:a9:cb:bf:04: - 31:a2:3d:9a:7e:30:29:d3:28:b8:fe:68:ce:cf:e9: - 30:6a:53:95:0e:50:65:80:26:c9:98:bf:f2:14:ff: - 06:7c:6a:7b:dc:50:07:e2:98:fa:df:cf:30:5d:ca: - a8:b9:8a:9b:2d:2d:7e:59:8b:1a:f7:b3:c9:c3:69: - 80:0f:89:19:08:77:b2:52:55:ad:78:83:9d:6b:b9: - 87:e4:53:24:37:2c:fc:19:0e:8b:79:14:4d:be:80: - 9e:b4:9b:73:74:31:f2:38:ec:8a:af:2a:36:8e:64: - ce:31:26:14:03:54:53:8e:fb:84:08:c1:7e:47:32: - 3d:71:e0:ba:ba:8c:82:58:96:4d:68:43:56:1a:f3: - 46:5a:32:99:95:b0:60:6f:e9:41:8a:48:cc:16:0d: - 44:68:b1:8a:dd:dd:17:3d:a4:9b:78:7f:2e:29:06: - f0:dc:d5:d2:13:3f:c0:36:05:fd:c7:b5:b9:80:1b: - 8a:46:74:2f:f1:ab:79:9e:97:6e:f8:a5:13:5a:f3: - fc:b5:d7:c8:96:19:37:ee:06:bc:c6:27:14:81:05: - 14:33:38:16:9f:4b:e2:0f:db:38:bb:f3:01:ef:35: - 2e:de:af:f1:e4:6f:6f:f7:96:00:56:5e:8f:60:94: - 1d:2f - Exponent: 65537 (0x10001) - X509v3 extensions: - Authority Information Access: - OCSP - URI:http://EVSecure-ocsp.thawte.com - - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://www.thawte.com/cps - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.thawte.com/ThawtePCA.crl - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Subject Alternative Name: - DirName:/CN=PrivateLabel3-2048-234 - X509v3 Subject Key Identifier: - CD:32:E2:F2:5D:25:47:02:AA:8F:79:4B:32:EE:03:99:FD:30:49:D1 - X509v3 Authority Key Identifier: - keyid:7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50 - - Signature Algorithm: sha1WithRSAEncryption - 0b:b4:96:ce:03:0c:d1:9d:af:cb:e3:39:56:0d:c6:22:a0:c9: - 71:7d:ea:65:95:31:f1:dc:b6:1e:f2:8d:31:5d:61:b3:54:84: - 13:cc:2b:3f:02:5c:c7:1f:15:01:82:90:1e:31:25:06:e3:32: - 0c:87:f0:c3:be:9a:c4:00:41:f6:c6:91:e5:6c:3e:92:5d:a3: - e4:3d:1f:32:2d:31:1e:50:c1:02:21:b4:23:e3:07:75:9a:52: - 45:51:fa:d3:1d:fd:01:6f:60:6d:25:d9:bf:43:b1:a7:43:6c: - ad:8c:bb:bc:f7:99:41:eb:d6:95:cf:20:5c:7e:6f:c4:2a:da: - 4b:4d:1b:5b:c2:9f:b0:94:d4:bf:47:97:fd:9d:49:79:60:8e: - ae:96:19:a1:b0:eb:e8:df:42:c7:22:74:61:0c:25:a3:7f:8f: - 45:d2:7e:e7:4a:6e:1d:4f:48:bb:c2:da:1a:7e:4a:59:81:fa: - 1c:e3:fb:14:73:41:03:a1:77:fa:9b:06:fc:7c:33:bd:46:3d: - 0c:06:17:85:7b:2a:7b:e3:36:e8:83:df:fa:aa:cb:32:0c:79: - aa:86:74:6c:44:54:f6:d8:07:9e:cd:98:f4:23:05:09:2f:a2: - 53:b5:db:0a:81:cc:5f:23:cb:79:11:c5:11:5b:85:6b:27:01: - 89:f3:0e:bb ------BEGIN CERTIFICATE----- -MIIFCjCCA/KgAwIBAgIQexFV63iakIW1jJL/Qrf+VjANBgkqhkiG9w0BAQUFADCB -qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf -Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw -MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV -BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMTYx -MTE2MjM1OTU5WjCBizELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j -LjE5MDcGA1UECxMwVGVybXMgb2YgdXNlIGF0IGh0dHBzOi8vd3d3LnRoYXd0ZS5j -b20vY3BzIChjKTA2MSowKAYDVQQDEyF0aGF3dGUgRXh0ZW5kZWQgVmFsaWRhdGlv -biBTU0wgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1jUf3sEh2 -m737qcu/BDGiPZp+MCnTKLj+aM7P6TBqU5UOUGWAJsmYv/IU/wZ8anvcUAfimPrf -zzBdyqi5ipstLX5Zixr3s8nDaYAPiRkId7JSVa14g51ruYfkUyQ3LPwZDot5FE2+ -gJ60m3N0MfI47IqvKjaOZM4xJhQDVFOO+4QIwX5HMj1x4Lq6jIJYlk1oQ1Ya80Za -MpmVsGBv6UGKSMwWDURosYrd3Rc9pJt4fy4pBvDc1dITP8A2Bf3HtbmAG4pGdC/x -q3mel274pRNa8/y118iWGTfuBrzGJxSBBRQzOBafS+IP2zi78wHvNS7er/Hkb2/3 -lgBWXo9glB0vAgMBAAGjggFIMIIBRDA7BggrBgEFBQcBAQQvMC0wKwYIKwYBBQUH -MAGGH2h0dHA6Ly9FVlNlY3VyZS1vY3NwLnRoYXd0ZS5jb20wEgYDVR0TAQH/BAgw -BgEB/wIBADA7BgNVHSAENDAyMDAGBFUdIAAwKDAmBggrBgEFBQcCARYaaHR0cHM6 -Ly93d3cudGhhd3RlLmNvbS9jcHMwNAYDVR0fBC0wKzApoCegJYYjaHR0cDovL2Ny -bC50aGF3dGUuY29tL1RoYXd0ZVBDQS5jcmwwDgYDVR0PAQH/BAQDAgEGMC4GA1Ud -EQQnMCWkIzAhMR8wHQYDVQQDExZQcml2YXRlTGFiZWwzLTIwNDgtMjM0MB0GA1Ud -DgQWBBTNMuLyXSVHAqqPeUsy7gOZ/TBJ0TAfBgNVHSMEGDAWgBR7W0XPr87Lev0x -khpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAC7SWzgMM0Z2vy+M5Vg3GIqDJ -cX3qZZUx8dy2HvKNMV1hs1SEE8wrPwJcxx8VAYKQHjElBuMyDIfww76axABB9saR -5Ww+kl2j5D0fMi0xHlDBAiG0I+MHdZpSRVH60x39AW9gbSXZv0Oxp0NsrYy7vPeZ -QevWlc8gXH5vxCraS00bW8KfsJTUv0eX/Z1JeWCOrpYZobDr6N9CxyJ0YQwlo3+P -RdJ+50puHU9Iu8LaGn5KWYH6HOP7FHNBA6F3+psG/HwzvUY9DAYXhXsqe+M26IPf -+qrLMgx5qoZ0bERU9tgHns2Y9CMFCS+iU7XbCoHMXyPLeRHFEVuFaycBifMOuw== ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert51[] = { - 0x30, 0x82, 0x05, 0x0a, 0x30, 0x82, 0x03, 0xf2, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x7b, 0x11, 0x55, 0xeb, 0x78, 0x9a, 0x90, 0x85, 0xb5, - 0x8c, 0x92, 0xff, 0x42, 0xb7, 0xfe, 0x56, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, - 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, - 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44, - 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06, - 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, - 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, - 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, - 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, - 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, - 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x31, 0x37, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x31, - 0x31, 0x31, 0x36, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, - 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, - 0x2e, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x30, - 0x54, 0x65, 0x72, 0x6d, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, - 0x20, 0x61, 0x74, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, - 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x20, 0x28, 0x63, 0x29, 0x30, 0x36, - 0x31, 0x2a, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x21, 0x74, - 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, - 0x65, 0x64, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 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, 0xb5, 0x8d, 0x47, 0xf7, 0xb0, 0x48, 0x76, - 0x9b, 0xbd, 0xfb, 0xa9, 0xcb, 0xbf, 0x04, 0x31, 0xa2, 0x3d, 0x9a, 0x7e, - 0x30, 0x29, 0xd3, 0x28, 0xb8, 0xfe, 0x68, 0xce, 0xcf, 0xe9, 0x30, 0x6a, - 0x53, 0x95, 0x0e, 0x50, 0x65, 0x80, 0x26, 0xc9, 0x98, 0xbf, 0xf2, 0x14, - 0xff, 0x06, 0x7c, 0x6a, 0x7b, 0xdc, 0x50, 0x07, 0xe2, 0x98, 0xfa, 0xdf, - 0xcf, 0x30, 0x5d, 0xca, 0xa8, 0xb9, 0x8a, 0x9b, 0x2d, 0x2d, 0x7e, 0x59, - 0x8b, 0x1a, 0xf7, 0xb3, 0xc9, 0xc3, 0x69, 0x80, 0x0f, 0x89, 0x19, 0x08, - 0x77, 0xb2, 0x52, 0x55, 0xad, 0x78, 0x83, 0x9d, 0x6b, 0xb9, 0x87, 0xe4, - 0x53, 0x24, 0x37, 0x2c, 0xfc, 0x19, 0x0e, 0x8b, 0x79, 0x14, 0x4d, 0xbe, - 0x80, 0x9e, 0xb4, 0x9b, 0x73, 0x74, 0x31, 0xf2, 0x38, 0xec, 0x8a, 0xaf, - 0x2a, 0x36, 0x8e, 0x64, 0xce, 0x31, 0x26, 0x14, 0x03, 0x54, 0x53, 0x8e, - 0xfb, 0x84, 0x08, 0xc1, 0x7e, 0x47, 0x32, 0x3d, 0x71, 0xe0, 0xba, 0xba, - 0x8c, 0x82, 0x58, 0x96, 0x4d, 0x68, 0x43, 0x56, 0x1a, 0xf3, 0x46, 0x5a, - 0x32, 0x99, 0x95, 0xb0, 0x60, 0x6f, 0xe9, 0x41, 0x8a, 0x48, 0xcc, 0x16, - 0x0d, 0x44, 0x68, 0xb1, 0x8a, 0xdd, 0xdd, 0x17, 0x3d, 0xa4, 0x9b, 0x78, - 0x7f, 0x2e, 0x29, 0x06, 0xf0, 0xdc, 0xd5, 0xd2, 0x13, 0x3f, 0xc0, 0x36, - 0x05, 0xfd, 0xc7, 0xb5, 0xb9, 0x80, 0x1b, 0x8a, 0x46, 0x74, 0x2f, 0xf1, - 0xab, 0x79, 0x9e, 0x97, 0x6e, 0xf8, 0xa5, 0x13, 0x5a, 0xf3, 0xfc, 0xb5, - 0xd7, 0xc8, 0x96, 0x19, 0x37, 0xee, 0x06, 0xbc, 0xc6, 0x27, 0x14, 0x81, - 0x05, 0x14, 0x33, 0x38, 0x16, 0x9f, 0x4b, 0xe2, 0x0f, 0xdb, 0x38, 0xbb, - 0xf3, 0x01, 0xef, 0x35, 0x2e, 0xde, 0xaf, 0xf1, 0xe4, 0x6f, 0x6f, 0xf7, - 0x96, 0x00, 0x56, 0x5e, 0x8f, 0x60, 0x94, 0x1d, 0x2f, 0x02, 0x03, 0x01, - 0x00, 0x01, 0xa3, 0x82, 0x01, 0x48, 0x30, 0x82, 0x01, 0x44, 0x30, 0x3b, - 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x2f, - 0x30, 0x2d, 0x30, 0x2b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x30, 0x01, 0x86, 0x1f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x45, - 0x56, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2d, 0x6f, 0x63, 0x73, 0x70, - 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, - 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, - 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x3b, 0x06, 0x03, 0x55, - 0x1d, 0x20, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06, 0x04, 0x55, 0x1d, - 0x20, 0x00, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, - 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x34, 0x06, 0x03, - 0x55, 0x1d, 0x1f, 0x04, 0x2d, 0x30, 0x2b, 0x30, 0x29, 0xa0, 0x27, 0xa0, - 0x25, 0x86, 0x23, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, - 0x6c, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, 0x43, 0x41, 0x2e, 0x63, - 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, - 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x2e, 0x06, 0x03, 0x55, 0x1d, - 0x11, 0x04, 0x27, 0x30, 0x25, 0xa4, 0x23, 0x30, 0x21, 0x31, 0x1f, 0x30, - 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x50, 0x72, 0x69, 0x76, - 0x61, 0x74, 0x65, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x33, 0x2d, 0x32, 0x30, - 0x34, 0x38, 0x2d, 0x32, 0x33, 0x34, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, - 0x0e, 0x04, 0x16, 0x04, 0x14, 0xcd, 0x32, 0xe2, 0xf2, 0x5d, 0x25, 0x47, - 0x02, 0xaa, 0x8f, 0x79, 0x4b, 0x32, 0xee, 0x03, 0x99, 0xfd, 0x30, 0x49, - 0xd1, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, - 0x80, 0x14, 0x7b, 0x5b, 0x45, 0xcf, 0xaf, 0xce, 0xcb, 0x7a, 0xfd, 0x31, - 0x92, 0x1a, 0x6a, 0xb6, 0xf3, 0x46, 0xeb, 0x57, 0x48, 0x50, 0x30, 0x0d, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, - 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x0b, 0xb4, 0x96, 0xce, 0x03, 0x0c, - 0xd1, 0x9d, 0xaf, 0xcb, 0xe3, 0x39, 0x56, 0x0d, 0xc6, 0x22, 0xa0, 0xc9, - 0x71, 0x7d, 0xea, 0x65, 0x95, 0x31, 0xf1, 0xdc, 0xb6, 0x1e, 0xf2, 0x8d, - 0x31, 0x5d, 0x61, 0xb3, 0x54, 0x84, 0x13, 0xcc, 0x2b, 0x3f, 0x02, 0x5c, - 0xc7, 0x1f, 0x15, 0x01, 0x82, 0x90, 0x1e, 0x31, 0x25, 0x06, 0xe3, 0x32, - 0x0c, 0x87, 0xf0, 0xc3, 0xbe, 0x9a, 0xc4, 0x00, 0x41, 0xf6, 0xc6, 0x91, - 0xe5, 0x6c, 0x3e, 0x92, 0x5d, 0xa3, 0xe4, 0x3d, 0x1f, 0x32, 0x2d, 0x31, - 0x1e, 0x50, 0xc1, 0x02, 0x21, 0xb4, 0x23, 0xe3, 0x07, 0x75, 0x9a, 0x52, - 0x45, 0x51, 0xfa, 0xd3, 0x1d, 0xfd, 0x01, 0x6f, 0x60, 0x6d, 0x25, 0xd9, - 0xbf, 0x43, 0xb1, 0xa7, 0x43, 0x6c, 0xad, 0x8c, 0xbb, 0xbc, 0xf7, 0x99, - 0x41, 0xeb, 0xd6, 0x95, 0xcf, 0x20, 0x5c, 0x7e, 0x6f, 0xc4, 0x2a, 0xda, - 0x4b, 0x4d, 0x1b, 0x5b, 0xc2, 0x9f, 0xb0, 0x94, 0xd4, 0xbf, 0x47, 0x97, - 0xfd, 0x9d, 0x49, 0x79, 0x60, 0x8e, 0xae, 0x96, 0x19, 0xa1, 0xb0, 0xeb, - 0xe8, 0xdf, 0x42, 0xc7, 0x22, 0x74, 0x61, 0x0c, 0x25, 0xa3, 0x7f, 0x8f, - 0x45, 0xd2, 0x7e, 0xe7, 0x4a, 0x6e, 0x1d, 0x4f, 0x48, 0xbb, 0xc2, 0xda, - 0x1a, 0x7e, 0x4a, 0x59, 0x81, 0xfa, 0x1c, 0xe3, 0xfb, 0x14, 0x73, 0x41, - 0x03, 0xa1, 0x77, 0xfa, 0x9b, 0x06, 0xfc, 0x7c, 0x33, 0xbd, 0x46, 0x3d, - 0x0c, 0x06, 0x17, 0x85, 0x7b, 0x2a, 0x7b, 0xe3, 0x36, 0xe8, 0x83, 0xdf, - 0xfa, 0xaa, 0xcb, 0x32, 0x0c, 0x79, 0xaa, 0x86, 0x74, 0x6c, 0x44, 0x54, - 0xf6, 0xd8, 0x07, 0x9e, 0xcd, 0x98, 0xf4, 0x23, 0x05, 0x09, 0x2f, 0xa2, - 0x53, 0xb5, 0xdb, 0x0a, 0x81, 0xcc, 0x5f, 0x23, 0xcb, 0x79, 0x11, 0xc5, - 0x11, 0x5b, 0x85, 0x6b, 0x27, 0x01, 0x89, 0xf3, 0x0e, 0xbb, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 1276037400 (0x4c0ec918) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=Entrust, Inc., OU=www.entrust.net/CPS is incorporated by reference, OU=(c) 2006 Entrust, Inc., CN=Entrust Root Certification Authority - Validity - Not Before: Nov 11 14:57:22 2011 GMT - Not After : Nov 12 08:12:31 2021 GMT - Subject: C=US, O=Entrust, Inc., OU=www.entrust.net/rpa is incorporated by reference, OU=(c) 2009 Entrust, Inc., CN=Entrust Certification Authority - L1E - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:b6:5b:04:54:77:dd:0e:24:66:dc:2a:a1:db:80: - cc:5d:c7:5f:fd:52:16:58:da:5f:94:06:a9:b8:b6: - b9:63:0c:47:20:82:ec:c7:95:4e:8b:b8:77:52:6a: - 3d:b5:87:a9:d6:e1:cc:74:e5:a6:c8:c0:d4:56:4f: - 8d:2e:d6:08:3e:0c:4c:43:3e:f0:41:93:5e:46:ef: - 39:e7:d9:65:2a:0c:76:50:27:bd:5b:0d:33:33:07: - e0:f7:a2:a9:9c:e1:11:33:ad:66:fc:d2:2c:7a:aa: - a3:73:16:be:93:85:75:0f:d7:37:8c:fa:23:b7:64: - f8:e3:4c:6e:ed:b3:05:bd:e2:36:db:7c:de:76:44: - da:82:72:76:b6:6e:ff:94:a1:d0:86:f7:10:cd:4a: - 5a:8b:b0:75:8c:66:52:80:4e:48:4c:49:83:a6:40: - d7:77:81:13:4d:5e:72:7e:48:46:22:aa:0f:e2:3e: - 65:94:38:e1:72:71:fe:4a:71:09:ba:35:7f:55:89: - 3d:81:d5:b8:28:01:10:77:36:5a:10:85:d2:bd:60: - 84:2b:49:61:94:0c:de:4c:40:6a:2a:c4:79:60:84: - 24:82:32:69:4a:98:4b:e2:56:10:ba:03:45:51:20: - d3:cf:da:8e:54:1b:45:b6:7a:ba:97:9a:5a:d8:c6: - d1:5f - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - Authority Information Access: - OCSP - URI:http://ocsp.entrust.net - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.entrust.net/rootca1.crl - - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: http://www.entrust.net/CPS - - X509v3 Subject Key Identifier: - 5B:41:8A:B2:C4:43:C1:BD:BF:C8:54:41:55:9D:E0:96:AD:FF:B9:A1 - X509v3 Authority Key Identifier: - keyid:68:90:E4:67:A4:A6:53:80:C7:86:66:A4:F1:F7:4B:43:FB:84:BD:6D - - 1.2.840.113533.7.65.0: - 0 -..V8.1.... - Signature Algorithm: sha1WithRSAEncryption - a1:f1:a8:10:e8:e6:29:b9:22:6c:61:5b:2a:3f:3c:01:c7:82: - 21:0b:e8:4e:0f:c4:c9:c6:bc:99:9d:f6:ef:5b:c7:69:b2:d9: - 9e:ac:52:42:e9:8a:b8:31:c4:13:96:03:8f:65:93:06:69:fe: - 28:b6:a6:fd:ad:87:8c:d5:cc:a6:e7:f9:1a:37:ef:32:2d:05: - 2d:1e:4e:b9:d5:d5:d1:0f:9b:7f:24:4e:b8:90:ec:e6:69:bf: - 9f:2a:3c:63:02:e1:69:a3:6e:a0:34:72:c8:50:50:b6:da:8e: - 92:2e:b8:4b:28:fe:f4:92:f0:04:b6:d6:9d:3d:07:66:11:75: - 6d:85:71:5e:32:f2:d7:0c:db:30:21:15:e1:74:b7:b5:eb:6b: - f9:73:ea:0a:49:ad:48:f6:23:23:8c:60:47:2c:51:96:b1:cc: - 23:77:cd:96:c5:c6:cd:b5:4c:2c:95:f7:22:45:f8:b6:ad:84: - 0c:08:ca:13:b0:a8:9d:35:6f:8b:48:d8:5f:b6:2b:a7:a8:27: - 44:c3:0c:8e:a6:0d:e3:64:26:61:92:97:13:5e:80:31:0c:b7: - 9e:90:20:87:0b:d0:aa:0a:06:04:27:3c:86:6a:20:0d:9d:bb: - ce:7d:57:c9:59:93:a2:03:3b:8c:b3:6f:42:fd:a4:d5:9b:ca: - 01:aa:04:0c ------BEGIN CERTIFICATE----- -MIIFDTCCA/WgAwIBAgIETA7JGDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC -VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 -Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW -KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl -cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTExMTExMTE0NTcyMloXDTIxMTExMjA4 -MTIzMVowgbExCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw -NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvcnBhIGlzIGluY29ycG9yYXRlZCBieSBy -ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA5IEVudHJ1c3QsIEluYy4xLjAsBgNV -BAMTJUVudHJ1c3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBMMUUwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2WwRUd90OJGbcKqHbgMxdx1/9UhZY -2l+UBqm4trljDEcgguzHlU6LuHdSaj21h6nW4cx05abIwNRWT40u1gg+DExDPvBB -k15G7znn2WUqDHZQJ71bDTMzB+D3oqmc4REzrWb80ix6qqNzFr6ThXUP1zeM+iO3 -ZPjjTG7tswW94jbbfN52RNqCcna2bv+UodCG9xDNSlqLsHWMZlKATkhMSYOmQNd3 -gRNNXnJ+SEYiqg/iPmWUOOFycf5KcQm6NX9ViT2B1bgoARB3NloQhdK9YIQrSWGU -DN5MQGoqxHlghCSCMmlKmEviVhC6A0VRINPP2o5UG0W2erqXmlrYxtFfAgMBAAGj -ggEqMIIBJjAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAzBggr -BgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmVudHJ1c3QubmV0 -MDMGA1UdHwQsMCowKKAmoCSGImh0dHA6Ly9jcmwuZW50cnVzdC5uZXQvcm9vdGNh -MS5jcmwwOwYDVR0gBDQwMjAwBgRVHSAAMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly93 -d3cuZW50cnVzdC5uZXQvQ1BTMB0GA1UdDgQWBBRbQYqyxEPBvb/IVEFVneCWrf+5 -oTAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAZBgkqhkiG9n0HQQAE -DDAKGwRWOC4xAwIAgTANBgkqhkiG9w0BAQUFAAOCAQEAofGoEOjmKbkibGFbKj88 -AceCIQvoTg/Eyca8mZ3271vHabLZnqxSQumKuDHEE5YDj2WTBmn+KLam/a2HjNXM -puf5GjfvMi0FLR5OudXV0Q+bfyROuJDs5mm/nyo8YwLhaaNuoDRyyFBQttqOki64 -Syj+9JLwBLbWnT0HZhF1bYVxXjLy1wzbMCEV4XS3tetr+XPqCkmtSPYjI4xgRyxR -lrHMI3fNlsXGzbVMLJX3IkX4tq2EDAjKE7ConTVvi0jYX7Yrp6gnRMMMjqYN42Qm -YZKXE16AMQy3npAghwvQqgoGBCc8hmogDZ27zn1XyVmTogM7jLNvQv2k1ZvKAaoE -DA== ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert52[] = { - 0x30, 0x82, 0x05, 0x0d, 0x30, 0x82, 0x03, 0xf5, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x04, 0x4c, 0x0e, 0xc9, 0x18, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, - 0xb0, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x0d, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, - 0x63, 0x2e, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, - 0x30, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, - 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x43, 0x50, 0x53, 0x20, 0x69, 0x73, 0x20, - 0x69, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x65, 0x64, - 0x20, 0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, - 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x45, 0x6e, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2d, - 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x45, 0x6e, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, - 0x0d, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x34, 0x35, 0x37, 0x32, - 0x32, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31, 0x31, 0x32, 0x30, 0x38, - 0x31, 0x32, 0x33, 0x31, 0x5a, 0x30, 0x81, 0xb1, 0x31, 0x0b, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, - 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x45, 0x6e, 0x74, 0x72, - 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x39, 0x30, - 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x30, 0x77, 0x77, 0x77, 0x2e, - 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, - 0x72, 0x70, 0x61, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x63, 0x6f, 0x72, - 0x70, 0x6f, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x72, - 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x31, 0x1f, 0x30, 0x1d, - 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x28, 0x63, 0x29, 0x20, 0x32, - 0x30, 0x30, 0x39, 0x20, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, - 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x25, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, - 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, - 0x2d, 0x20, 0x4c, 0x31, 0x45, 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, 0xb6, 0x5b, 0x04, 0x54, 0x77, 0xdd, 0x0e, 0x24, 0x66, 0xdc, - 0x2a, 0xa1, 0xdb, 0x80, 0xcc, 0x5d, 0xc7, 0x5f, 0xfd, 0x52, 0x16, 0x58, - 0xda, 0x5f, 0x94, 0x06, 0xa9, 0xb8, 0xb6, 0xb9, 0x63, 0x0c, 0x47, 0x20, - 0x82, 0xec, 0xc7, 0x95, 0x4e, 0x8b, 0xb8, 0x77, 0x52, 0x6a, 0x3d, 0xb5, - 0x87, 0xa9, 0xd6, 0xe1, 0xcc, 0x74, 0xe5, 0xa6, 0xc8, 0xc0, 0xd4, 0x56, - 0x4f, 0x8d, 0x2e, 0xd6, 0x08, 0x3e, 0x0c, 0x4c, 0x43, 0x3e, 0xf0, 0x41, - 0x93, 0x5e, 0x46, 0xef, 0x39, 0xe7, 0xd9, 0x65, 0x2a, 0x0c, 0x76, 0x50, - 0x27, 0xbd, 0x5b, 0x0d, 0x33, 0x33, 0x07, 0xe0, 0xf7, 0xa2, 0xa9, 0x9c, - 0xe1, 0x11, 0x33, 0xad, 0x66, 0xfc, 0xd2, 0x2c, 0x7a, 0xaa, 0xa3, 0x73, - 0x16, 0xbe, 0x93, 0x85, 0x75, 0x0f, 0xd7, 0x37, 0x8c, 0xfa, 0x23, 0xb7, - 0x64, 0xf8, 0xe3, 0x4c, 0x6e, 0xed, 0xb3, 0x05, 0xbd, 0xe2, 0x36, 0xdb, - 0x7c, 0xde, 0x76, 0x44, 0xda, 0x82, 0x72, 0x76, 0xb6, 0x6e, 0xff, 0x94, - 0xa1, 0xd0, 0x86, 0xf7, 0x10, 0xcd, 0x4a, 0x5a, 0x8b, 0xb0, 0x75, 0x8c, - 0x66, 0x52, 0x80, 0x4e, 0x48, 0x4c, 0x49, 0x83, 0xa6, 0x40, 0xd7, 0x77, - 0x81, 0x13, 0x4d, 0x5e, 0x72, 0x7e, 0x48, 0x46, 0x22, 0xaa, 0x0f, 0xe2, - 0x3e, 0x65, 0x94, 0x38, 0xe1, 0x72, 0x71, 0xfe, 0x4a, 0x71, 0x09, 0xba, - 0x35, 0x7f, 0x55, 0x89, 0x3d, 0x81, 0xd5, 0xb8, 0x28, 0x01, 0x10, 0x77, - 0x36, 0x5a, 0x10, 0x85, 0xd2, 0xbd, 0x60, 0x84, 0x2b, 0x49, 0x61, 0x94, - 0x0c, 0xde, 0x4c, 0x40, 0x6a, 0x2a, 0xc4, 0x79, 0x60, 0x84, 0x24, 0x82, - 0x32, 0x69, 0x4a, 0x98, 0x4b, 0xe2, 0x56, 0x10, 0xba, 0x03, 0x45, 0x51, - 0x20, 0xd3, 0xcf, 0xda, 0x8e, 0x54, 0x1b, 0x45, 0xb6, 0x7a, 0xba, 0x97, - 0x9a, 0x5a, 0xd8, 0xc6, 0xd1, 0x5f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, - 0x82, 0x01, 0x2a, 0x30, 0x82, 0x01, 0x26, 0x30, 0x0e, 0x06, 0x03, 0x55, - 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, - 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, - 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x33, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x27, 0x30, 0x25, 0x30, - 0x23, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, - 0x17, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, - 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, - 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, - 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, - 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x63, 0x61, - 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3b, 0x06, 0x03, 0x55, 0x1d, 0x20, - 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, - 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, - 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, - 0x65, 0x74, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, - 0x0e, 0x04, 0x16, 0x04, 0x14, 0x5b, 0x41, 0x8a, 0xb2, 0xc4, 0x43, 0xc1, - 0xbd, 0xbf, 0xc8, 0x54, 0x41, 0x55, 0x9d, 0xe0, 0x96, 0xad, 0xff, 0xb9, - 0xa1, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, - 0x80, 0x14, 0x68, 0x90, 0xe4, 0x67, 0xa4, 0xa6, 0x53, 0x80, 0xc7, 0x86, - 0x66, 0xa4, 0xf1, 0xf7, 0x4b, 0x43, 0xfb, 0x84, 0xbd, 0x6d, 0x30, 0x19, - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf6, 0x7d, 0x07, 0x41, 0x00, 0x04, - 0x0c, 0x30, 0x0a, 0x1b, 0x04, 0x56, 0x38, 0x2e, 0x31, 0x03, 0x02, 0x00, - 0x81, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xa1, 0xf1, 0xa8, - 0x10, 0xe8, 0xe6, 0x29, 0xb9, 0x22, 0x6c, 0x61, 0x5b, 0x2a, 0x3f, 0x3c, - 0x01, 0xc7, 0x82, 0x21, 0x0b, 0xe8, 0x4e, 0x0f, 0xc4, 0xc9, 0xc6, 0xbc, - 0x99, 0x9d, 0xf6, 0xef, 0x5b, 0xc7, 0x69, 0xb2, 0xd9, 0x9e, 0xac, 0x52, - 0x42, 0xe9, 0x8a, 0xb8, 0x31, 0xc4, 0x13, 0x96, 0x03, 0x8f, 0x65, 0x93, - 0x06, 0x69, 0xfe, 0x28, 0xb6, 0xa6, 0xfd, 0xad, 0x87, 0x8c, 0xd5, 0xcc, - 0xa6, 0xe7, 0xf9, 0x1a, 0x37, 0xef, 0x32, 0x2d, 0x05, 0x2d, 0x1e, 0x4e, - 0xb9, 0xd5, 0xd5, 0xd1, 0x0f, 0x9b, 0x7f, 0x24, 0x4e, 0xb8, 0x90, 0xec, - 0xe6, 0x69, 0xbf, 0x9f, 0x2a, 0x3c, 0x63, 0x02, 0xe1, 0x69, 0xa3, 0x6e, - 0xa0, 0x34, 0x72, 0xc8, 0x50, 0x50, 0xb6, 0xda, 0x8e, 0x92, 0x2e, 0xb8, - 0x4b, 0x28, 0xfe, 0xf4, 0x92, 0xf0, 0x04, 0xb6, 0xd6, 0x9d, 0x3d, 0x07, - 0x66, 0x11, 0x75, 0x6d, 0x85, 0x71, 0x5e, 0x32, 0xf2, 0xd7, 0x0c, 0xdb, - 0x30, 0x21, 0x15, 0xe1, 0x74, 0xb7, 0xb5, 0xeb, 0x6b, 0xf9, 0x73, 0xea, - 0x0a, 0x49, 0xad, 0x48, 0xf6, 0x23, 0x23, 0x8c, 0x60, 0x47, 0x2c, 0x51, - 0x96, 0xb1, 0xcc, 0x23, 0x77, 0xcd, 0x96, 0xc5, 0xc6, 0xcd, 0xb5, 0x4c, - 0x2c, 0x95, 0xf7, 0x22, 0x45, 0xf8, 0xb6, 0xad, 0x84, 0x0c, 0x08, 0xca, - 0x13, 0xb0, 0xa8, 0x9d, 0x35, 0x6f, 0x8b, 0x48, 0xd8, 0x5f, 0xb6, 0x2b, - 0xa7, 0xa8, 0x27, 0x44, 0xc3, 0x0c, 0x8e, 0xa6, 0x0d, 0xe3, 0x64, 0x26, - 0x61, 0x92, 0x97, 0x13, 0x5e, 0x80, 0x31, 0x0c, 0xb7, 0x9e, 0x90, 0x20, - 0x87, 0x0b, 0xd0, 0xaa, 0x0a, 0x06, 0x04, 0x27, 0x3c, 0x86, 0x6a, 0x20, - 0x0d, 0x9d, 0xbb, 0xce, 0x7d, 0x57, 0xc9, 0x59, 0x93, 0xa2, 0x03, 0x3b, - 0x8c, 0xb3, 0x6f, 0x42, 0xfd, 0xa4, 0xd5, 0x9b, 0xca, 0x01, 0xaa, 0x04, - 0x0c, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 7a:0f:41:df:1c:cd:14:dc:b2:69:29:8e:e2:2c:6a:35 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5 - Validity - Not Before: Oct 31 00:00:00 2013 GMT - Not After : Oct 30 23:59:59 2023 GMT - Subject: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 EV SSL SGC CA - G2 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:c4:38:4c:43:0a:b3:a0:64:d3:50:d3:e6:aa:09: - 3d:80:ba:ac:1c:e8:0a:69:63:8e:80:e1:56:04:31: - b9:6f:a8:09:8a:a8:d4:b4:0c:4c:bf:06:2a:ce:7d: - cb:a1:f4:ac:7a:6b:fc:9a:cc:bf:c2:1b:3e:76:cc: - 7b:5d:50:b3:1d:26:6c:15:95:e0:4b:d4:5d:a1:0c: - d3:7d:13:59:0b:4e:c5:96:90:50:2e:88:93:96:af: - 97:32:74:0d:f7:1b:a4:c7:09:2a:16:4f:ff:fa:52: - 56:ef:71:ff:30:b5:b4:65:42:59:d2:9c:92:75:a7: - 5c:74:a5:51:8c:88:3c:53:8d:66:9a:de:a2:c8:f8: - c8:dd:3d:39:5d:c2:79:c4:48:37:c6:28:fa:24:73: - fe:0c:2a:68:f0:66:a8:d0:b2:f0:76:94:22:18:6c: - f3:8f:e4:d1:ad:59:81:0f:8e:fd:8a:85:5e:45:e8: - 7d:88:56:ef:14:63:ca:0e:9a:66:34:87:ec:bf:fd: - e1:51:0e:1a:cd:4b:4f:ab:fc:52:98:48:4d:f7:fb: - d6:b0:71:a2:27:b8:6d:46:b6:8f:80:58:80:49:57: - 0e:76:33:ef:9c:6f:29:f0:a8:7f:b0:d5:0f:df:d6: - c1:01:cb:0c:78:ed:9c:6d:bb:2d:95:d8:bf:c7:96: - 7a:4f - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 CRL Distribution Points: - - Full Name: - URI:http://s1.symcb.com/pca3-g5.crl - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - Authority Information Access: - OCSP - URI:http://s2.symcb.com - - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: http://www.symauth.com/cps - User Notice: - Explicit Text: http://www.symauth.com/rpa - - X509v3 Extended Key Usage: - Netscape Server Gated Crypto, 2.16.840.1.113733.1.8.1, TLS Web Server Authentication, TLS Web Client Authentication - X509v3 Subject Alternative Name: - DirName:/CN=SymantecPKI-1-542 - X509v3 Subject Key Identifier: - 46:4F:C1:E0:88:DA:7D:D3:78:9B:C8:6E:59:2F:B0:E4:F7:1D:90:E2 - X509v3 Authority Key Identifier: - keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33 - - Signature Algorithm: sha1WithRSAEncryption - 53:2f:a7:8a:f8:45:72:32:9f:38:42:f5:85:de:c7:6c:fa:7c: - e5:b6:c4:57:fd:40:e6:ad:45:f4:9b:eb:fe:9b:04:96:c1:66: - 5f:ab:a3:e0:df:1a:60:eb:d0:93:d1:c1:1a:8a:85:c1:bc:f6: - d8:0b:30:73:5c:16:3e:b8:49:bd:03:1d:97:19:e2:5a:98:a8: - fe:86:16:1e:09:00:c2:e7:b9:4f:65:23:e4:dc:93:7d:fe:53: - 20:d9:80:f5:e3:72:60:ae:29:ec:ff:67:36:0b:4d:1a:a1:c6: - f0:9f:d5:27:53:3e:da:4f:d9:80:0a:34:0b:76:10:c2:75:f4: - a9:77:ef:1e:1a:34:aa:2e:81:ef:4f:78:03:8f:7c:8b:a7:04: - b9:e5:e7:cb:93:80:7b:6a:06:ce:2e:c7:c9:1a:88:ca:3b:14: - b0:75:39:d5:c1:23:03:5c:90:33:ec:81:0c:fa:b3:1c:38:5a: - 03:5d:a8:08:a3:fe:d5:c9:08:57:c9:8f:69:5f:d9:7f:eb:72: - 40:17:cd:81:19:b9:e4:dd:49:f5:aa:5c:ff:98:da:32:ec:7c: - 93:2a:26:fe:da:4c:1e:23:f7:18:e4:3b:62:09:67:43:20:ed: - 36:b8:3a:35:a0:6c:dc:69:59:ca:2a:27:94:3a:6d:ee:78:a0: - 47:b1:f5:94 ------BEGIN CERTIFICATE----- -MIIFZTCCBE2gAwIBAgIQeg9B3xzNFNyyaSmO4ixqNTANBgkqhkiG9w0BAQUFADCB -yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL -ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp -U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW -ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5IC0gRzUwHhcNMTMxMDMxMDAwMDAwWhcNMjMxMDMwMjM1OTU5WjB7MQsw -CQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAdBgNV -BAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxLDAqBgNVBAMTI1N5bWFudGVjIENs -YXNzIDMgRVYgU1NMIFNHQyBDQSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAxDhMQwqzoGTTUNPmqgk9gLqsHOgKaWOOgOFWBDG5b6gJiqjUtAxM -vwYqzn3LofSsemv8msy/whs+dsx7XVCzHSZsFZXgS9RdoQzTfRNZC07FlpBQLoiT -lq+XMnQN9xukxwkqFk//+lJW73H/MLW0ZUJZ0pySdadcdKVRjIg8U41mmt6iyPjI -3T05XcJ5xEg3xij6JHP+DCpo8Gao0LLwdpQiGGzzj+TRrVmBD479ioVeReh9iFbv -FGPKDppmNIfsv/3hUQ4azUtPq/xSmEhN9/vWsHGiJ7htRraPgFiASVcOdjPvnG8p -8Kh/sNUP39bBAcsMeO2cbbstldi/x5Z6TwIDAQABo4IBkzCCAY8wEgYDVR0TAQH/ -BAgwBgEB/wIBADAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vczEuc3ltY2IuY29t -L3BjYTMtZzUuY3JsMA4GA1UdDwEB/wQEAwIBBjAvBggrBgEFBQcBAQQjMCEwHwYI -KwYBBQUHMAGGE2h0dHA6Ly9zMi5zeW1jYi5jb20wZQYDVR0gBF4wXDBaBgRVHSAA -MFIwJgYIKwYBBQUHAgEWGmh0dHA6Ly93d3cuc3ltYXV0aC5jb20vY3BzMCgGCCsG -AQUFBwICMBwaGmh0dHA6Ly93d3cuc3ltYXV0aC5jb20vcnBhMDQGA1UdJQQtMCsG -CWCGSAGG+EIEAQYKYIZIAYb4RQEIAQYIKwYBBQUHAwEGCCsGAQUFBwMCMCkGA1Ud -EQQiMCCkHjAcMRowGAYDVQQDExFTeW1hbnRlY1BLSS0xLTU0MjAdBgNVHQ4EFgQU -Rk/B4IjafdN4m8huWS+w5PcdkOIwHwYDVR0jBBgwFoAUf9Nlp8Ld7LvwMAnzQzn6 -Aq8zMTMwDQYJKoZIhvcNAQEFBQADggEBAFMvp4r4RXIynzhC9YXex2z6fOW2xFf9 -QOatRfSb6/6bBJbBZl+ro+DfGmDr0JPRwRqKhcG89tgLMHNcFj64Sb0DHZcZ4lqY -qP6GFh4JAMLnuU9lI+Tck33+UyDZgPXjcmCuKez/ZzYLTRqhxvCf1SdTPtpP2YAK -NAt2EMJ19Kl37x4aNKouge9PeAOPfIunBLnl58uTgHtqBs4ux8kaiMo7FLB1OdXB -IwNckDPsgQz6sxw4WgNdqAij/tXJCFfJj2lf2X/rckAXzYEZueTdSfWqXP+Y2jLs -fJMqJv7aTB4j9xjkO2IJZ0Mg7Ta4OjWgbNxpWcoqJ5Q6be54oEex9ZQ= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert53[] = { - 0x30, 0x82, 0x05, 0x65, 0x30, 0x82, 0x04, 0x4d, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x7a, 0x0f, 0x41, 0xdf, 0x1c, 0xcd, 0x14, 0xdc, 0xb2, - 0x69, 0x29, 0x8e, 0xe2, 0x2c, 0x6a, 0x35, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, - 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, - 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, - 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, - 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, - 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, - 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, - 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56, - 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, - 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30, - 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x33, 0x31, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x31, 0x30, 0x33, 0x30, - 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x7b, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1d, - 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x14, 0x53, 0x79, 0x6d, - 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, - 0x04, 0x0b, 0x13, 0x16, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, - 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, - 0x72, 0x6b, 0x31, 0x2c, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, - 0x23, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6c, - 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x45, 0x56, 0x20, 0x53, 0x53, 0x4c, - 0x20, 0x53, 0x47, 0x43, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x32, - 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, 0xc4, 0x38, 0x4c, - 0x43, 0x0a, 0xb3, 0xa0, 0x64, 0xd3, 0x50, 0xd3, 0xe6, 0xaa, 0x09, 0x3d, - 0x80, 0xba, 0xac, 0x1c, 0xe8, 0x0a, 0x69, 0x63, 0x8e, 0x80, 0xe1, 0x56, - 0x04, 0x31, 0xb9, 0x6f, 0xa8, 0x09, 0x8a, 0xa8, 0xd4, 0xb4, 0x0c, 0x4c, - 0xbf, 0x06, 0x2a, 0xce, 0x7d, 0xcb, 0xa1, 0xf4, 0xac, 0x7a, 0x6b, 0xfc, - 0x9a, 0xcc, 0xbf, 0xc2, 0x1b, 0x3e, 0x76, 0xcc, 0x7b, 0x5d, 0x50, 0xb3, - 0x1d, 0x26, 0x6c, 0x15, 0x95, 0xe0, 0x4b, 0xd4, 0x5d, 0xa1, 0x0c, 0xd3, - 0x7d, 0x13, 0x59, 0x0b, 0x4e, 0xc5, 0x96, 0x90, 0x50, 0x2e, 0x88, 0x93, - 0x96, 0xaf, 0x97, 0x32, 0x74, 0x0d, 0xf7, 0x1b, 0xa4, 0xc7, 0x09, 0x2a, - 0x16, 0x4f, 0xff, 0xfa, 0x52, 0x56, 0xef, 0x71, 0xff, 0x30, 0xb5, 0xb4, - 0x65, 0x42, 0x59, 0xd2, 0x9c, 0x92, 0x75, 0xa7, 0x5c, 0x74, 0xa5, 0x51, - 0x8c, 0x88, 0x3c, 0x53, 0x8d, 0x66, 0x9a, 0xde, 0xa2, 0xc8, 0xf8, 0xc8, - 0xdd, 0x3d, 0x39, 0x5d, 0xc2, 0x79, 0xc4, 0x48, 0x37, 0xc6, 0x28, 0xfa, - 0x24, 0x73, 0xfe, 0x0c, 0x2a, 0x68, 0xf0, 0x66, 0xa8, 0xd0, 0xb2, 0xf0, - 0x76, 0x94, 0x22, 0x18, 0x6c, 0xf3, 0x8f, 0xe4, 0xd1, 0xad, 0x59, 0x81, - 0x0f, 0x8e, 0xfd, 0x8a, 0x85, 0x5e, 0x45, 0xe8, 0x7d, 0x88, 0x56, 0xef, - 0x14, 0x63, 0xca, 0x0e, 0x9a, 0x66, 0x34, 0x87, 0xec, 0xbf, 0xfd, 0xe1, - 0x51, 0x0e, 0x1a, 0xcd, 0x4b, 0x4f, 0xab, 0xfc, 0x52, 0x98, 0x48, 0x4d, - 0xf7, 0xfb, 0xd6, 0xb0, 0x71, 0xa2, 0x27, 0xb8, 0x6d, 0x46, 0xb6, 0x8f, - 0x80, 0x58, 0x80, 0x49, 0x57, 0x0e, 0x76, 0x33, 0xef, 0x9c, 0x6f, 0x29, - 0xf0, 0xa8, 0x7f, 0xb0, 0xd5, 0x0f, 0xdf, 0xd6, 0xc1, 0x01, 0xcb, 0x0c, - 0x78, 0xed, 0x9c, 0x6d, 0xbb, 0x2d, 0x95, 0xd8, 0xbf, 0xc7, 0x96, 0x7a, - 0x4f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x93, 0x30, 0x82, - 0x01, 0x8f, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, - 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x30, - 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x29, 0x30, 0x27, 0x30, 0x25, 0xa0, - 0x23, 0xa0, 0x21, 0x86, 0x1f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x73, 0x31, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x70, 0x63, 0x61, 0x33, 0x2d, 0x67, 0x35, 0x2e, 0x63, 0x72, 0x6c, - 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, - 0x03, 0x02, 0x01, 0x06, 0x30, 0x2f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x01, 0x01, 0x04, 0x23, 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x65, 0x06, 0x03, 0x55, 0x1d, 0x20, - 0x04, 0x5e, 0x30, 0x5c, 0x30, 0x5a, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, - 0x30, 0x52, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, - 0x77, 0x77, 0x2e, 0x73, 0x79, 0x6d, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, - 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x1c, 0x1a, 0x1a, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x79, 0x6d, - 0x61, 0x75, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x70, 0x61, - 0x30, 0x34, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x2d, 0x30, 0x2b, 0x06, - 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01, 0x06, 0x0a, - 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x08, 0x01, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, - 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x29, 0x06, 0x03, 0x55, 0x1d, - 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x1a, 0x30, - 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, 0x6d, 0x61, - 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, 0x35, 0x34, - 0x32, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, - 0x46, 0x4f, 0xc1, 0xe0, 0x88, 0xda, 0x7d, 0xd3, 0x78, 0x9b, 0xc8, 0x6e, - 0x59, 0x2f, 0xb0, 0xe4, 0xf7, 0x1d, 0x90, 0xe2, 0x30, 0x1f, 0x06, 0x03, - 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7f, 0xd3, 0x65, - 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3, 0x43, 0x39, 0xfa, - 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, - 0x00, 0x53, 0x2f, 0xa7, 0x8a, 0xf8, 0x45, 0x72, 0x32, 0x9f, 0x38, 0x42, - 0xf5, 0x85, 0xde, 0xc7, 0x6c, 0xfa, 0x7c, 0xe5, 0xb6, 0xc4, 0x57, 0xfd, - 0x40, 0xe6, 0xad, 0x45, 0xf4, 0x9b, 0xeb, 0xfe, 0x9b, 0x04, 0x96, 0xc1, - 0x66, 0x5f, 0xab, 0xa3, 0xe0, 0xdf, 0x1a, 0x60, 0xeb, 0xd0, 0x93, 0xd1, - 0xc1, 0x1a, 0x8a, 0x85, 0xc1, 0xbc, 0xf6, 0xd8, 0x0b, 0x30, 0x73, 0x5c, - 0x16, 0x3e, 0xb8, 0x49, 0xbd, 0x03, 0x1d, 0x97, 0x19, 0xe2, 0x5a, 0x98, - 0xa8, 0xfe, 0x86, 0x16, 0x1e, 0x09, 0x00, 0xc2, 0xe7, 0xb9, 0x4f, 0x65, - 0x23, 0xe4, 0xdc, 0x93, 0x7d, 0xfe, 0x53, 0x20, 0xd9, 0x80, 0xf5, 0xe3, - 0x72, 0x60, 0xae, 0x29, 0xec, 0xff, 0x67, 0x36, 0x0b, 0x4d, 0x1a, 0xa1, - 0xc6, 0xf0, 0x9f, 0xd5, 0x27, 0x53, 0x3e, 0xda, 0x4f, 0xd9, 0x80, 0x0a, - 0x34, 0x0b, 0x76, 0x10, 0xc2, 0x75, 0xf4, 0xa9, 0x77, 0xef, 0x1e, 0x1a, - 0x34, 0xaa, 0x2e, 0x81, 0xef, 0x4f, 0x78, 0x03, 0x8f, 0x7c, 0x8b, 0xa7, - 0x04, 0xb9, 0xe5, 0xe7, 0xcb, 0x93, 0x80, 0x7b, 0x6a, 0x06, 0xce, 0x2e, - 0xc7, 0xc9, 0x1a, 0x88, 0xca, 0x3b, 0x14, 0xb0, 0x75, 0x39, 0xd5, 0xc1, - 0x23, 0x03, 0x5c, 0x90, 0x33, 0xec, 0x81, 0x0c, 0xfa, 0xb3, 0x1c, 0x38, - 0x5a, 0x03, 0x5d, 0xa8, 0x08, 0xa3, 0xfe, 0xd5, 0xc9, 0x08, 0x57, 0xc9, - 0x8f, 0x69, 0x5f, 0xd9, 0x7f, 0xeb, 0x72, 0x40, 0x17, 0xcd, 0x81, 0x19, - 0xb9, 0xe4, 0xdd, 0x49, 0xf5, 0xaa, 0x5c, 0xff, 0x98, 0xda, 0x32, 0xec, - 0x7c, 0x93, 0x2a, 0x26, 0xfe, 0xda, 0x4c, 0x1e, 0x23, 0xf7, 0x18, 0xe4, - 0x3b, 0x62, 0x09, 0x67, 0x43, 0x20, 0xed, 0x36, 0xb8, 0x3a, 0x35, 0xa0, - 0x6c, 0xdc, 0x69, 0x59, 0xca, 0x2a, 0x27, 0x94, 0x3a, 0x6d, 0xee, 0x78, - 0xa0, 0x47, 0xb1, 0xf5, 0x94, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 5b:77:59:c6:17:84:e1:5e:c7:27:c0:32:95:29:28:6b - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5 - Validity - Not Before: Nov 8 00:00:00 2006 GMT - Not After : Nov 7 23:59:59 2016 GMT - Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=Terms of use at https://www.verisign.com/rpa (c)06, CN=VeriSign Class 3 Extended Validation SSL CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:98:db:a0:55:eb:9c:fd:17:79:e3:9a:6e:14:1d: - b1:5b:98:23:87:16:6e:87:76:9c:b5:38:3b:b5:a0: - 7a:b4:07:63:09:19:e6:2a:88:48:a9:e7:9d:b6:30: - 5a:08:97:0c:ec:aa:e4:16:69:72:62:23:9a:fb:7a: - 54:28:98:c5:0c:2d:b7:d7:22:b6:c8:f9:38:17:c7: - dd:da:31:46:9a:94:14:8e:9e:ee:78:a0:b7:22:d4: - 49:54:97:4d:e5:74:5b:92:bc:ec:6c:2c:df:e7:c1: - b6:1b:1a:55:6b:66:08:03:7f:45:af:9a:33:f1:10: - c0:6c:99:4a:92:24:31:08:6d:dd:02:3e:61:76:78: - 78:b6:ed:7e:37:ae:6c:f3:89:e1:b7:e1:dc:15:cc: - b7:56:9f:80:a0:b1:05:7f:4e:37:15:ff:b7:2f:1e: - 8f:06:38:3f:50:b7:69:28:a3:b5:66:5f:36:1a:52: - 48:43:66:52:df:a2:92:4f:d3:18:60:be:e3:ea:5e: - 19:71:05:bf:9e:1c:6c:68:72:25:6f:b3:7b:73:c9: - 6d:bd:12:ff:9b:41:32:5e:f4:e8:7e:c5:0b:a3:4c: - 64:d1:4e:bc:26:08:65:fb:19:97:58:78:e1:33:bf: - ed:68:3e:b1:27:45:6f:c0:e2:ec:97:69:f7:5c:d3: - f7:51 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Subject Key Identifier: - FC:8A:50:BA:9E:B9:25:5A:7B:55:85:4F:95:00:63:8F:E9:58:6B:43 - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://www.verisign.com/cps - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://EVSecure-crl.verisign.com/pca3-g5.crl - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - Netscape Cert Type: - SSL CA, S/MIME CA - 1.3.6.1.5.5.7.1.12: - 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif - X509v3 Subject Alternative Name: - DirName:/CN=Class3CA2048-1-47 - Authority Information Access: - OCSP - URI:http://EVSecure-ocsp.verisign.com - - X509v3 Authority Key Identifier: - keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33 - - Signature Algorithm: sha1WithRSAEncryption - 96:a2:fa:7f:e6:3d:ed:d4:2b:ce:b7:15:3f:c0:72:03:5f:8b: - ba:16:90:25:f7:c2:83:d8:c7:75:34:63:68:12:53:0c:53:89: - 7b:c9:56:09:a7:c3:36:44:4e:0e:d0:62:62:b3:86:fa:e8:a1: - 9b:34:67:8d:53:22:17:3e:fd:ac:ee:67:2e:43:e2:5d:7f:33: - 84:f2:a2:70:c0:6e:82:97:c0:34:fd:25:c6:23:7f:ed:e6:b0: - c5:57:43:84:b2:de:2d:f1:d0:f6:48:1f:14:71:57:b2:ac:31: - e1:97:24:23:c9:13:5d:74:e5:46:ef:09:7c:9e:e1:99:31:0a: - 08:79:1b:8f:71:9f:17:66:c8:38:cf:ee:8c:97:b6:06:b9:73: - 46:e4:d3:94:c1:e5:60:b5:25:75:2d:d9:69:31:ec:cd:96:c3: - a3:76:fd:e8:74:44:ac:12:b9:4d:bf:51:e8:b9:d4:44:4e:27: - cb:ae:20:d1:7e:2a:7c:b6:63:47:9e:76:ba:97:d0:16:e7:0b: - 6c:6d:f7:43:6f:33:0b:29:30:77:fa:9d:f9:f5:4e:b8:76:b3: - cd:18:b4:f9:20:ef:3d:db:e6:ca:ad:9b:d0:4e:d2:87:a9:0d: - a6:44:73:50:dd:70:5b:ed:ad:7e:4a:bc:22:d5:a8:26:e4:c2: - 85:20:0d:d9 ------BEGIN CERTIFICATE----- -MIIF5DCCBMygAwIBAgIQW3dZxheE4V7HJ8AylSkoazANBgkqhkiG9w0BAQUFADCB -yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL -ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp -U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW -ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMTYxMTA3MjM1OTU5WjCBujEL -MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW -ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQg -aHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE0MDIGA1UEAxMrVmVy -aVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBDQTCCASIwDQYJ -KoZIhvcNAQEBBQADggEPADCCAQoCggEBAJjboFXrnP0XeeOabhQdsVuYI4cWbod2 -nLU4O7WgerQHYwkZ5iqISKnnnbYwWgiXDOyq5BZpcmIjmvt6VCiYxQwtt9citsj5 -OBfH3doxRpqUFI6e7nigtyLUSVSXTeV0W5K87Gws3+fBthsaVWtmCAN/Ra+aM/EQ -wGyZSpIkMQht3QI+YXZ4eLbtfjeubPOJ4bfh3BXMt1afgKCxBX9ONxX/ty8ejwY4 -P1C3aSijtWZfNhpSSENmUt+ikk/TGGC+4+peGXEFv54cbGhyJW+ze3PJbb0S/5tB -Ml706H7FC6NMZNFOvCYIZfsZl1h44TO/7Wg+sSdFb8Di7Jdp91zT91ECAwEAAaOC -AdIwggHOMB0GA1UdDgQWBBT8ilC6nrklWntVhU+VAGOP6VhrQzASBgNVHRMBAf8E -CDAGAQH/AgEAMD0GA1UdIAQ2MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxodHRw -czovL3d3dy52ZXJpc2lnbi5jb20vY3BzMD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6 -Ly9FVlNlY3VyZS1jcmwudmVyaXNpZ24uY29tL3BjYTMtZzUuY3JsMA4GA1UdDwEB -/wQEAwIBBjARBglghkgBhvhCAQEEBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZ -MFcwVRYJaW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7 -GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwKQYDVR0R -BCIwIKQeMBwxGjAYBgNVBAMTEUNsYXNzM0NBMjA0OC0xLTQ3MD0GCCsGAQUFBwEB -BDEwLzAtBggrBgEFBQcwAYYhaHR0cDovL0VWU2VjdXJlLW9jc3AudmVyaXNpZ24u -Y29tMB8GA1UdIwQYMBaAFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqGSIb3DQEB -BQUAA4IBAQCWovp/5j3t1CvOtxU/wHIDX4u6FpAl98KD2Md1NGNoElMMU4l7yVYJ -p8M2RE4O0GJis4b66KGbNGeNUyIXPv2s7mcuQ+JdfzOE8qJwwG6Cl8A0/SXGI3/t -5rDFV0OEst4t8dD2SB8UcVeyrDHhlyQjyRNddOVG7wl8nuGZMQoIeRuPcZ8XZsg4 -z+6Ml7YGuXNG5NOUweVgtSV1LdlpMezNlsOjdv3odESsErlNv1HoudRETifLriDR -fip8tmNHnna6l9AW5wtsbfdDbzMLKTB3+p359U64drPNGLT5IO892+bKrZvQTtKH -qQ2mRHNQ3XBb7a1+Srwi1agm5MKFIA3Z ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert54[] = { - 0x30, 0x82, 0x05, 0xe4, 0x30, 0x82, 0x04, 0xcc, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x5b, 0x77, 0x59, 0xc6, 0x17, 0x84, 0xe1, 0x5e, 0xc7, - 0x27, 0xc0, 0x32, 0x95, 0x29, 0x28, 0x6b, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, - 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, - 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, - 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, - 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, - 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, - 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, - 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56, - 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, - 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30, - 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x30, 0x38, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x31, 0x31, 0x30, 0x37, - 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xba, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, - 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56, - 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, - 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3b, 0x30, - 0x39, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65, 0x72, 0x6d, - 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20, - 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, - 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x30, 0x36, 0x31, 0x34, - 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2b, 0x56, 0x65, 0x72, - 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, - 0x33, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x53, - 0x4c, 0x20, 0x43, 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, 0x98, 0xdb, 0xa0, 0x55, 0xeb, 0x9c, 0xfd, 0x17, 0x79, 0xe3, 0x9a, - 0x6e, 0x14, 0x1d, 0xb1, 0x5b, 0x98, 0x23, 0x87, 0x16, 0x6e, 0x87, 0x76, - 0x9c, 0xb5, 0x38, 0x3b, 0xb5, 0xa0, 0x7a, 0xb4, 0x07, 0x63, 0x09, 0x19, - 0xe6, 0x2a, 0x88, 0x48, 0xa9, 0xe7, 0x9d, 0xb6, 0x30, 0x5a, 0x08, 0x97, - 0x0c, 0xec, 0xaa, 0xe4, 0x16, 0x69, 0x72, 0x62, 0x23, 0x9a, 0xfb, 0x7a, - 0x54, 0x28, 0x98, 0xc5, 0x0c, 0x2d, 0xb7, 0xd7, 0x22, 0xb6, 0xc8, 0xf9, - 0x38, 0x17, 0xc7, 0xdd, 0xda, 0x31, 0x46, 0x9a, 0x94, 0x14, 0x8e, 0x9e, - 0xee, 0x78, 0xa0, 0xb7, 0x22, 0xd4, 0x49, 0x54, 0x97, 0x4d, 0xe5, 0x74, - 0x5b, 0x92, 0xbc, 0xec, 0x6c, 0x2c, 0xdf, 0xe7, 0xc1, 0xb6, 0x1b, 0x1a, - 0x55, 0x6b, 0x66, 0x08, 0x03, 0x7f, 0x45, 0xaf, 0x9a, 0x33, 0xf1, 0x10, - 0xc0, 0x6c, 0x99, 0x4a, 0x92, 0x24, 0x31, 0x08, 0x6d, 0xdd, 0x02, 0x3e, - 0x61, 0x76, 0x78, 0x78, 0xb6, 0xed, 0x7e, 0x37, 0xae, 0x6c, 0xf3, 0x89, - 0xe1, 0xb7, 0xe1, 0xdc, 0x15, 0xcc, 0xb7, 0x56, 0x9f, 0x80, 0xa0, 0xb1, - 0x05, 0x7f, 0x4e, 0x37, 0x15, 0xff, 0xb7, 0x2f, 0x1e, 0x8f, 0x06, 0x38, - 0x3f, 0x50, 0xb7, 0x69, 0x28, 0xa3, 0xb5, 0x66, 0x5f, 0x36, 0x1a, 0x52, - 0x48, 0x43, 0x66, 0x52, 0xdf, 0xa2, 0x92, 0x4f, 0xd3, 0x18, 0x60, 0xbe, - 0xe3, 0xea, 0x5e, 0x19, 0x71, 0x05, 0xbf, 0x9e, 0x1c, 0x6c, 0x68, 0x72, - 0x25, 0x6f, 0xb3, 0x7b, 0x73, 0xc9, 0x6d, 0xbd, 0x12, 0xff, 0x9b, 0x41, - 0x32, 0x5e, 0xf4, 0xe8, 0x7e, 0xc5, 0x0b, 0xa3, 0x4c, 0x64, 0xd1, 0x4e, - 0xbc, 0x26, 0x08, 0x65, 0xfb, 0x19, 0x97, 0x58, 0x78, 0xe1, 0x33, 0xbf, - 0xed, 0x68, 0x3e, 0xb1, 0x27, 0x45, 0x6f, 0xc0, 0xe2, 0xec, 0x97, 0x69, - 0xf7, 0x5c, 0xd3, 0xf7, 0x51, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, - 0x01, 0xd2, 0x30, 0x82, 0x01, 0xce, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, - 0x0e, 0x04, 0x16, 0x04, 0x14, 0xfc, 0x8a, 0x50, 0xba, 0x9e, 0xb9, 0x25, - 0x5a, 0x7b, 0x55, 0x85, 0x4f, 0x95, 0x00, 0x63, 0x8f, 0xe9, 0x58, 0x6b, - 0x43, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, - 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x3d, 0x06, - 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06, 0x04, - 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, - 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, 0x70, - 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, - 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, - 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x36, 0x30, 0x34, 0x30, - 0x32, 0xa0, 0x30, 0xa0, 0x2e, 0x86, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x45, 0x56, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2d, 0x63, - 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33, 0x2d, 0x67, 0x35, 0x2e, - 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, - 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x11, 0x06, 0x09, 0x60, - 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, - 0x01, 0x06, 0x30, 0x6d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f, 0xa1, 0x5d, 0xa0, 0x5b, 0x30, 0x59, - 0x30, 0x57, 0x30, 0x55, 0x16, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, - 0x67, 0x69, 0x66, 0x30, 0x21, 0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, - 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, 0x8f, 0xe5, 0xd3, 0x1a, 0x86, 0xac, - 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80, 0x6a, 0xd4, 0x48, 0x18, 0x2c, 0x7b, - 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, - 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x73, 0x6c, 0x6f, 0x67, - 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30, 0x29, 0x06, 0x03, 0x55, 0x1d, 0x11, - 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, - 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, 0x6c, 0x61, 0x73, 0x73, - 0x33, 0x43, 0x41, 0x32, 0x30, 0x34, 0x38, 0x2d, 0x31, 0x2d, 0x34, 0x37, - 0x30, 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, - 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x30, 0x01, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x45, 0x56, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2d, 0x6f, 0x63, - 0x73, 0x70, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, - 0x63, 0x6f, 0x6d, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, - 0x30, 0x16, 0x80, 0x14, 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, - 0xf0, 0x30, 0x09, 0xf3, 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x96, 0xa2, 0xfa, 0x7f, - 0xe6, 0x3d, 0xed, 0xd4, 0x2b, 0xce, 0xb7, 0x15, 0x3f, 0xc0, 0x72, 0x03, - 0x5f, 0x8b, 0xba, 0x16, 0x90, 0x25, 0xf7, 0xc2, 0x83, 0xd8, 0xc7, 0x75, - 0x34, 0x63, 0x68, 0x12, 0x53, 0x0c, 0x53, 0x89, 0x7b, 0xc9, 0x56, 0x09, - 0xa7, 0xc3, 0x36, 0x44, 0x4e, 0x0e, 0xd0, 0x62, 0x62, 0xb3, 0x86, 0xfa, - 0xe8, 0xa1, 0x9b, 0x34, 0x67, 0x8d, 0x53, 0x22, 0x17, 0x3e, 0xfd, 0xac, - 0xee, 0x67, 0x2e, 0x43, 0xe2, 0x5d, 0x7f, 0x33, 0x84, 0xf2, 0xa2, 0x70, - 0xc0, 0x6e, 0x82, 0x97, 0xc0, 0x34, 0xfd, 0x25, 0xc6, 0x23, 0x7f, 0xed, - 0xe6, 0xb0, 0xc5, 0x57, 0x43, 0x84, 0xb2, 0xde, 0x2d, 0xf1, 0xd0, 0xf6, - 0x48, 0x1f, 0x14, 0x71, 0x57, 0xb2, 0xac, 0x31, 0xe1, 0x97, 0x24, 0x23, - 0xc9, 0x13, 0x5d, 0x74, 0xe5, 0x46, 0xef, 0x09, 0x7c, 0x9e, 0xe1, 0x99, - 0x31, 0x0a, 0x08, 0x79, 0x1b, 0x8f, 0x71, 0x9f, 0x17, 0x66, 0xc8, 0x38, - 0xcf, 0xee, 0x8c, 0x97, 0xb6, 0x06, 0xb9, 0x73, 0x46, 0xe4, 0xd3, 0x94, - 0xc1, 0xe5, 0x60, 0xb5, 0x25, 0x75, 0x2d, 0xd9, 0x69, 0x31, 0xec, 0xcd, - 0x96, 0xc3, 0xa3, 0x76, 0xfd, 0xe8, 0x74, 0x44, 0xac, 0x12, 0xb9, 0x4d, - 0xbf, 0x51, 0xe8, 0xb9, 0xd4, 0x44, 0x4e, 0x27, 0xcb, 0xae, 0x20, 0xd1, - 0x7e, 0x2a, 0x7c, 0xb6, 0x63, 0x47, 0x9e, 0x76, 0xba, 0x97, 0xd0, 0x16, - 0xe7, 0x0b, 0x6c, 0x6d, 0xf7, 0x43, 0x6f, 0x33, 0x0b, 0x29, 0x30, 0x77, - 0xfa, 0x9d, 0xf9, 0xf5, 0x4e, 0xb8, 0x76, 0xb3, 0xcd, 0x18, 0xb4, 0xf9, - 0x20, 0xef, 0x3d, 0xdb, 0xe6, 0xca, 0xad, 0x9b, 0xd0, 0x4e, 0xd2, 0x87, - 0xa9, 0x0d, 0xa6, 0x44, 0x73, 0x50, 0xdd, 0x70, 0x5b, 0xed, 0xad, 0x7e, - 0x4a, 0xbc, 0x22, 0xd5, 0xa8, 0x26, 0xe4, 0xc2, 0x85, 0x20, 0x0d, 0xd9, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 6e:cc:7a:a5:a7:03:20:09:b8:ce:bc:f4:e9:52:d4:91 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5 - Validity - Not Before: Feb 8 00:00:00 2010 GMT - Not After : Feb 7 23:59:59 2020 GMT - Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=Terms of use at https://www.verisign.com/rpa (c)10, CN=VeriSign Class 3 Secure Server CA - G3 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:b1:87:84:1f:c2:0c:45:f5:bc:ab:25:97:a7:ad: - a2:3e:9c:ba:f6:c1:39:b8:8b:ca:c2:ac:56:c6:e5: - bb:65:8e:44:4f:4d:ce:6f:ed:09:4a:d4:af:4e:10: - 9c:68:8b:2e:95:7b:89:9b:13:ca:e2:34:34:c1:f3: - 5b:f3:49:7b:62:83:48:81:74:d1:88:78:6c:02:53: - f9:bc:7f:43:26:57:58:33:83:3b:33:0a:17:b0:d0: - 4e:91:24:ad:86:7d:64:12:dc:74:4a:34:a1:1d:0a: - ea:96:1d:0b:15:fc:a3:4b:3b:ce:63:88:d0:f8:2d: - 0c:94:86:10:ca:b6:9a:3d:ca:eb:37:9c:00:48:35: - 86:29:50:78:e8:45:63:cd:19:41:4f:f5:95:ec:7b: - 98:d4:c4:71:b3:50:be:28:b3:8f:a0:b9:53:9c:f5: - ca:2c:23:a9:fd:14:06:e8:18:b4:9a:e8:3c:6e:81: - fd:e4:cd:35:36:b3:51:d3:69:ec:12:ba:56:6e:6f: - 9b:57:c5:8b:14:e7:0e:c7:9c:ed:4a:54:6a:c9:4d: - c5:bf:11:b1:ae:1c:67:81:cb:44:55:33:99:7f:24: - 9b:3f:53:45:7f:86:1a:f3:3c:fa:6d:7f:81:f5:b8: - 4a:d3:f5:85:37:1c:b5:a6:d0:09:e4:18:7b:38:4e: - fa:0f - Exponent: 65537 (0x10001) - X509v3 extensions: - Authority Information Access: - OCSP - URI:http://ocsp.verisign.com - - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Certificate Policies: - Policy: 2.16.840.1.113733.1.7.23.3 - CPS: https://www.verisign.com/cps - User Notice: - Explicit Text: https://www.verisign.com/rpa - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.verisign.com/pca3-g5.crl - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - 1.3.6.1.5.5.7.1.12: - 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif - X509v3 Subject Alternative Name: - DirName:/CN=VeriSignMPKI-2-6 - X509v3 Subject Key Identifier: - 0D:44:5C:16:53:44:C1:82:7E:1D:20:AB:25:F4:01:63:D8:BE:79:A5 - X509v3 Authority Key Identifier: - keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33 - - Signature Algorithm: sha1WithRSAEncryption - 0c:83:24:ef:dd:c3:0c:d9:58:9c:fe:36:b6:eb:8a:80:4b:d1: - a3:f7:9d:f3:cc:53:ef:82:9e:a3:a1:e6:97:c1:58:9d:75:6c: - e0:1d:1b:4c:fa:d1:c1:2d:05:c0:ea:6e:b2:22:70:55:d9:20: - 33:40:33:07:c2:65:83:fa:8f:43:37:9b:ea:0e:9a:6c:70:ee: - f6:9c:80:3b:d9:37:f4:7a:6d:ec:d0:18:7d:49:4a:ca:99:c7: - 19:28:a2:be:d8:77:24:f7:85:26:86:6d:87:05:40:41:67:d1: - 27:3a:ed:dc:48:1d:22:cd:0b:0b:8b:bc:f4:b1:7b:fd:b4:99: - a8:e9:76:2a:e1:1a:2d:87:6e:74:d3:88:dd:1e:22:c6:df:16: - b6:2b:82:14:0a:94:5c:f2:50:ec:af:ce:ff:62:37:0d:ad:65: - d3:06:41:53:ed:02:14:c8:b5:58:28:a1:ac:e0:5b:ec:b3:7f: - 95:4a:fb:03:c8:ad:26:db:e6:66:78:12:4a:d9:9f:42:fb:e1: - 98:e6:42:83:9b:8f:8f:67:24:e8:61:19:b5:dd:cd:b5:0b:26: - 05:8e:c3:6e:c4:c8:75:b8:46:cf:e2:18:06:5e:a9:ae:a8:81: - 9a:47:16:de:0c:28:6c:25:27:b9:de:b7:84:58:c6:1f:38:1e: - a4:c4:cb:66 ------BEGIN CERTIFICATE----- -MIIF7DCCBNSgAwIBAgIQbsx6pacDIAm4zrz06VLUkTANBgkqhkiG9w0BAQUFADCB -yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL -ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp -U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW -ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5IC0gRzUwHhcNMTAwMjA4MDAwMDAwWhcNMjAwMjA3MjM1OTU5WjCBtTEL -MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW -ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQg -aHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDEvMC0GA1UEAxMmVmVy -aVNpZ24gQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzMwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCxh4QfwgxF9byrJZenraI+nLr2wTm4i8rCrFbG -5btljkRPTc5v7QlK1K9OEJxoiy6Ve4mbE8riNDTB81vzSXtig0iBdNGIeGwCU/m8 -f0MmV1gzgzszChew0E6RJK2GfWQS3HRKNKEdCuqWHQsV/KNLO85jiND4LQyUhhDK -tpo9yus3nABINYYpUHjoRWPNGUFP9ZXse5jUxHGzUL4os4+guVOc9cosI6n9FAbo -GLSa6Dxugf3kzTU2s1HTaewSulZub5tXxYsU5w7HnO1KVGrJTcW/EbGuHGeBy0RV -M5l/JJs/U0V/hhrzPPptf4H1uErT9YU3HLWm0AnkGHs4TvoPAgMBAAGjggHfMIIB -2zA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLnZlcmlz -aWduLmNvbTASBgNVHRMBAf8ECDAGAQH/AgEAMHAGA1UdIARpMGcwZQYLYIZIAYb4 -RQEHFwMwVjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL2Nw -czAqBggrBgEFBQcCAjAeGhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMDQG -A1UdHwQtMCswKaAnoCWGI2h0dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMtZzUu -Y3JsMA4GA1UdDwEB/wQEAwIBBjBtBggrBgEFBQcBDARhMF+hXaBbMFkwVzBVFglp -bWFnZS9naWYwITAfMAcGBSsOAwIaBBSP5dMahqyNjmvDz4Bq1EgYLHsZLjAlFiNo -dHRwOi8vbG9nby52ZXJpc2lnbi5jb20vdnNsb2dvLmdpZjAoBgNVHREEITAfpB0w -GzEZMBcGA1UEAxMQVmVyaVNpZ25NUEtJLTItNjAdBgNVHQ4EFgQUDURcFlNEwYJ+ -HSCrJfQBY9i+eaUwHwYDVR0jBBgwFoAUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwDQYJ -KoZIhvcNAQEFBQADggEBAAyDJO/dwwzZWJz+NrbrioBL0aP3nfPMU++CnqOh5pfB -WJ11bOAdG0z60cEtBcDqbrIicFXZIDNAMwfCZYP6j0M3m+oOmmxw7vacgDvZN/R6 -bezQGH1JSsqZxxkoor7YdyT3hSaGbYcFQEFn0Sc67dxIHSLNCwuLvPSxe/20majp -dirhGi2HbnTTiN0eIsbfFrYrghQKlFzyUOyvzv9iNw2tZdMGQVPtAhTItVgooazg -W+yzf5VK+wPIrSbb5mZ4EkrZn0L74ZjmQoObj49nJOhhGbXdzbULJgWOw27EyHW4 -Rs/iGAZeqa6ogZpHFt4MKGwlJ7net4RYxh84HqTEy2Y= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert55[] = { - 0x30, 0x82, 0x05, 0xec, 0x30, 0x82, 0x04, 0xd4, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x6e, 0xcc, 0x7a, 0xa5, 0xa7, 0x03, 0x20, 0x09, 0xb8, - 0xce, 0xbc, 0xf4, 0xe9, 0x52, 0xd4, 0x91, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, - 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, - 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, - 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, - 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, - 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, - 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, - 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56, - 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, - 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30, - 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x32, 0x30, 0x38, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x32, 0x30, 0x37, - 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xb5, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, - 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56, - 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, - 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3b, 0x30, - 0x39, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65, 0x72, 0x6d, - 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20, - 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, - 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x31, 0x30, 0x31, 0x2f, - 0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26, 0x56, 0x65, 0x72, - 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, - 0x33, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 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, 0xb1, 0x87, 0x84, 0x1f, - 0xc2, 0x0c, 0x45, 0xf5, 0xbc, 0xab, 0x25, 0x97, 0xa7, 0xad, 0xa2, 0x3e, - 0x9c, 0xba, 0xf6, 0xc1, 0x39, 0xb8, 0x8b, 0xca, 0xc2, 0xac, 0x56, 0xc6, - 0xe5, 0xbb, 0x65, 0x8e, 0x44, 0x4f, 0x4d, 0xce, 0x6f, 0xed, 0x09, 0x4a, - 0xd4, 0xaf, 0x4e, 0x10, 0x9c, 0x68, 0x8b, 0x2e, 0x95, 0x7b, 0x89, 0x9b, - 0x13, 0xca, 0xe2, 0x34, 0x34, 0xc1, 0xf3, 0x5b, 0xf3, 0x49, 0x7b, 0x62, - 0x83, 0x48, 0x81, 0x74, 0xd1, 0x88, 0x78, 0x6c, 0x02, 0x53, 0xf9, 0xbc, - 0x7f, 0x43, 0x26, 0x57, 0x58, 0x33, 0x83, 0x3b, 0x33, 0x0a, 0x17, 0xb0, - 0xd0, 0x4e, 0x91, 0x24, 0xad, 0x86, 0x7d, 0x64, 0x12, 0xdc, 0x74, 0x4a, - 0x34, 0xa1, 0x1d, 0x0a, 0xea, 0x96, 0x1d, 0x0b, 0x15, 0xfc, 0xa3, 0x4b, - 0x3b, 0xce, 0x63, 0x88, 0xd0, 0xf8, 0x2d, 0x0c, 0x94, 0x86, 0x10, 0xca, - 0xb6, 0x9a, 0x3d, 0xca, 0xeb, 0x37, 0x9c, 0x00, 0x48, 0x35, 0x86, 0x29, - 0x50, 0x78, 0xe8, 0x45, 0x63, 0xcd, 0x19, 0x41, 0x4f, 0xf5, 0x95, 0xec, - 0x7b, 0x98, 0xd4, 0xc4, 0x71, 0xb3, 0x50, 0xbe, 0x28, 0xb3, 0x8f, 0xa0, - 0xb9, 0x53, 0x9c, 0xf5, 0xca, 0x2c, 0x23, 0xa9, 0xfd, 0x14, 0x06, 0xe8, - 0x18, 0xb4, 0x9a, 0xe8, 0x3c, 0x6e, 0x81, 0xfd, 0xe4, 0xcd, 0x35, 0x36, - 0xb3, 0x51, 0xd3, 0x69, 0xec, 0x12, 0xba, 0x56, 0x6e, 0x6f, 0x9b, 0x57, - 0xc5, 0x8b, 0x14, 0xe7, 0x0e, 0xc7, 0x9c, 0xed, 0x4a, 0x54, 0x6a, 0xc9, - 0x4d, 0xc5, 0xbf, 0x11, 0xb1, 0xae, 0x1c, 0x67, 0x81, 0xcb, 0x44, 0x55, - 0x33, 0x99, 0x7f, 0x24, 0x9b, 0x3f, 0x53, 0x45, 0x7f, 0x86, 0x1a, 0xf3, - 0x3c, 0xfa, 0x6d, 0x7f, 0x81, 0xf5, 0xb8, 0x4a, 0xd3, 0xf5, 0x85, 0x37, - 0x1c, 0xb5, 0xa6, 0xd0, 0x09, 0xe4, 0x18, 0x7b, 0x38, 0x4e, 0xfa, 0x0f, - 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xdf, 0x30, 0x82, 0x01, - 0xdb, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, - 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, - 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03, 0x55, - 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, - 0x02, 0x01, 0x00, 0x30, 0x70, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x69, - 0x30, 0x67, 0x30, 0x65, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, - 0x45, 0x01, 0x07, 0x17, 0x03, 0x30, 0x56, 0x30, 0x28, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, - 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, - 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, - 0x73, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, - 0x02, 0x30, 0x1e, 0x1a, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, - 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, - 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x70, 0x61, 0x30, 0x34, 0x06, - 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2d, 0x30, 0x2b, 0x30, 0x29, 0xa0, 0x27, - 0xa0, 0x25, 0x86, 0x23, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, - 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33, 0x2d, 0x67, 0x35, 0x2e, - 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, - 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x6d, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f, 0xa1, - 0x5d, 0xa0, 0x5b, 0x30, 0x59, 0x30, 0x57, 0x30, 0x55, 0x16, 0x09, 0x69, - 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x30, 0x21, 0x30, 0x1f, - 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, 0x8f, - 0xe5, 0xd3, 0x1a, 0x86, 0xac, 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80, 0x6a, - 0xd4, 0x48, 0x18, 0x2c, 0x7b, 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x76, - 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x76, 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30, 0x28, - 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x21, 0x30, 0x1f, 0xa4, 0x1d, 0x30, - 0x1b, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, - 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49, - 0x2d, 0x32, 0x2d, 0x36, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, - 0x16, 0x04, 0x14, 0x0d, 0x44, 0x5c, 0x16, 0x53, 0x44, 0xc1, 0x82, 0x7e, - 0x1d, 0x20, 0xab, 0x25, 0xf4, 0x01, 0x63, 0xd8, 0xbe, 0x79, 0xa5, 0x30, - 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, - 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3, - 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, - 0x82, 0x01, 0x01, 0x00, 0x0c, 0x83, 0x24, 0xef, 0xdd, 0xc3, 0x0c, 0xd9, - 0x58, 0x9c, 0xfe, 0x36, 0xb6, 0xeb, 0x8a, 0x80, 0x4b, 0xd1, 0xa3, 0xf7, - 0x9d, 0xf3, 0xcc, 0x53, 0xef, 0x82, 0x9e, 0xa3, 0xa1, 0xe6, 0x97, 0xc1, - 0x58, 0x9d, 0x75, 0x6c, 0xe0, 0x1d, 0x1b, 0x4c, 0xfa, 0xd1, 0xc1, 0x2d, - 0x05, 0xc0, 0xea, 0x6e, 0xb2, 0x22, 0x70, 0x55, 0xd9, 0x20, 0x33, 0x40, - 0x33, 0x07, 0xc2, 0x65, 0x83, 0xfa, 0x8f, 0x43, 0x37, 0x9b, 0xea, 0x0e, - 0x9a, 0x6c, 0x70, 0xee, 0xf6, 0x9c, 0x80, 0x3b, 0xd9, 0x37, 0xf4, 0x7a, - 0x6d, 0xec, 0xd0, 0x18, 0x7d, 0x49, 0x4a, 0xca, 0x99, 0xc7, 0x19, 0x28, - 0xa2, 0xbe, 0xd8, 0x77, 0x24, 0xf7, 0x85, 0x26, 0x86, 0x6d, 0x87, 0x05, - 0x40, 0x41, 0x67, 0xd1, 0x27, 0x3a, 0xed, 0xdc, 0x48, 0x1d, 0x22, 0xcd, - 0x0b, 0x0b, 0x8b, 0xbc, 0xf4, 0xb1, 0x7b, 0xfd, 0xb4, 0x99, 0xa8, 0xe9, - 0x76, 0x2a, 0xe1, 0x1a, 0x2d, 0x87, 0x6e, 0x74, 0xd3, 0x88, 0xdd, 0x1e, - 0x22, 0xc6, 0xdf, 0x16, 0xb6, 0x2b, 0x82, 0x14, 0x0a, 0x94, 0x5c, 0xf2, - 0x50, 0xec, 0xaf, 0xce, 0xff, 0x62, 0x37, 0x0d, 0xad, 0x65, 0xd3, 0x06, - 0x41, 0x53, 0xed, 0x02, 0x14, 0xc8, 0xb5, 0x58, 0x28, 0xa1, 0xac, 0xe0, - 0x5b, 0xec, 0xb3, 0x7f, 0x95, 0x4a, 0xfb, 0x03, 0xc8, 0xad, 0x26, 0xdb, - 0xe6, 0x66, 0x78, 0x12, 0x4a, 0xd9, 0x9f, 0x42, 0xfb, 0xe1, 0x98, 0xe6, - 0x42, 0x83, 0x9b, 0x8f, 0x8f, 0x67, 0x24, 0xe8, 0x61, 0x19, 0xb5, 0xdd, - 0xcd, 0xb5, 0x0b, 0x26, 0x05, 0x8e, 0xc3, 0x6e, 0xc4, 0xc8, 0x75, 0xb8, - 0x46, 0xcf, 0xe2, 0x18, 0x06, 0x5e, 0xa9, 0xae, 0xa8, 0x81, 0x9a, 0x47, - 0x16, 0xde, 0x0c, 0x28, 0x6c, 0x25, 0x27, 0xb9, 0xde, 0xb7, 0x84, 0x58, - 0xc6, 0x1f, 0x38, 0x1e, 0xa4, 0xc4, 0xcb, 0x66, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 61:5d:aa:d2:00:06:00:00:00:40 - Signature Algorithm: sha1WithRSAEncryption - Issuer: CN=Microsoft Internet Authority - Validity - Not Before: May 15 20:40:55 2012 GMT - Not After : May 15 20:50:55 2016 GMT - Subject: DC=com, DC=microsoft, DC=corp, DC=redmond, CN=MSIT Machine Auth CA 2 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:bd:c8:e8:00:eb:58:69:29:11:84:87:1c:9f:87: - 4d:44:3d:38:1b:c7:13:93:e7:14:4c:17:2b:db:75: - 08:c0:c9:21:ca:ae:e0:1f:e8:8c:fe:a1:df:24:8c: - bf:02:9c:ed:99:be:3a:53:2a:45:4e:b0:48:78:37: - dc:a1:63:ef:03:b7:94:29:66:6c:66:d7:6c:6a:48: - 65:b2:dd:47:21:23:1b:b8:41:74:2f:96:dd:98:22: - b9:fa:f3:0e:4a:b0:2f:0b:a2:de:b7:02:13:42:70: - 3f:78:04:14:72:e3:3a:2b:7e:28:48:1d:96:b4:db: - 16:39:8d:b3:c4:59:a1:d7:a2:d2:64:61:33:2b:41: - 18:c5:ab:95:6f:5d:22:07:77:cd:53:9d:03:49:65: - d5:88:f5:5f:9d:f0:c4:69:4f:91:08:a5:39:07:96: - 36:af:2d:64:dc:26:5a:c1:13:ee:31:39:d6:5f:dc: - 97:fc:27:aa:05:78:47:c5:22:26:63:53:7e:37:c2: - 7b:64:3d:69:cb:f0:fb:8a:15:3e:52:b3:86:6a:b4: - c1:1c:3b:b2:f5:c7:3e:c5:76:dd:74:68:76:7a:55: - e6:80:7b:2e:8c:a6:da:bb:91:5a:07:cd:19:4a:ea: - 08:5c:ff:c1:49:d6:7b:06:bf:eb:b7:4a:9f:b4:27: - 9c:17 - Exponent: 65537 (0x10001) - X509v3 extensions: - 1.3.6.1.4.1.311.21.1: - ..... - 1.3.6.1.4.1.311.21.2: - ..#...h..f...@z.g.3... - X509v3 Subject Key Identifier: - EB:DB:11:5E:F8:09:9E:D8:D6:62:9C:FD:62:9D:E3:84:4A:28:E1:27 - 1.3.6.1.4.1.311.20.2: - . -.S.u.b.C.A - X509v3 Key Usage: - Digital Signature, Certificate Sign, CRL Sign - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Authority Key Identifier: - keyid:2A:4D:97:95:5D:34:7E:9D:B6:E6:33:BE:9C:27:C1:70:7E:67:DB:C1 - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://mscrl.microsoft.com/pki/mscorp/crl/mswww(6).crl - URI:http://crl.microsoft.com/pki/mscorp/crl/mswww(6).crl - URI:http://corppki/crl/mswww(6).crl - - Authority Information Access: - CA Issuers - URI:http://www.microsoft.com/pki/mscorp/mswww(6).crt - CA Issuers - URI:http://corppki/aia/mswww(6).crt - - Signature Algorithm: sha1WithRSAEncryption - a3:36:72:f7:45:0b:a7:86:37:de:20:8d:f5:d7:8e:da:89:00: - 7a:52:4b:85:32:b2:32:d7:ed:80:57:fd:0d:51:1c:d1:1e:3d: - 0c:3e:91:2a:30:e2:53:bc:61:07:89:02:11:b9:1b:83:48:d3: - 1a:c7:47:96:62:b7:cf:de:d7:0d:b8:9d:84:8e:de:d5:e6:e4: - b9:c0:06:e3:1c:f4:31:43:1f:53:fc:4a:42:b5:9b:23:cd:b2: - ec:0d:0f:81:89:ff:59:a9:00:d3:04:4a:0b:af:5b:84:f5:3b: - 4f:b9:37:91:88:21:e4:9c:ca:52:76:63:7e:88:7a:65:b4:8e: - 16:6a:f4:60:bd:2c:0e:ef:17:86:2b:75:09:58:73:c5:4f:b9: - a8:1b:ef:2a:f4:b6:a3:b9:07:f0:a4:90:39:53:df:e1:ba:02: - 98:a5:a5:82:11:a1:06:53:b2:c2:eb:fd:ea:67:72:37:63:d0: - 85:cf:86:05:c8:c3:73:c1:db:f3:c4:d2:55:ff:a0:1d:e7:72: - 14:1a:ff:b2:ff:08:42:48:40:0a:19:82:cf:22:f3:05:c5:d5: - df:0b:29:c4:3a:0e:c5:32:38:ef:2f:94:9a:0c:f2:d4:ee:bf: - 62:c7:e2:a4:5f:3d:6e:78:bc:10:c1:2e:4a:30:f2:87:db:89: - 38:be:fe:cc:80:8f:f5:f9:5c:cb:5c:f1:ea:02:08:6b:a5:0b: - ef:20:5c:a3:34:cc:f0:80:b6:1f:63:b9:44:32:1c:26:41:9b: - dd:93:a3:64:01:57:11:21:43:94:2a:57:2d:8a:4a:cb:8a:28: - 40:0a:fb:50:f9:af:26:74:13:97:82:4e:6c:64:eb:d1:c6:bf: - 5e:fd:25:da:05:46:4a:ae:c7:2f:c7:04:ef:2e:71:2e:e2:a8: - 5b:a4:ea:b2:6f:a8:91:35:c4:b7:63:17:62:0e:27:8e:3c:24: - cd:3d:45:69:05:dc:52:c5:35:f8:11:c0:1d:df:62:60:f4:e1: - a6:5e:70:b8:45:74:03:ab:d1:16:74:e3:9e:d3:c1:a3:e8:90: - 96:8a:8a:c2:46:46:9d:b9:5c:6c:02:1d:32:84:eb:14:85:76: - 95:aa:4d:2d:69:b6:02:f6:fe:ed:34:d5:8c:e6:fa:ac:5d:dc: - 03:40:e6:cf:77:89:ff:b1:28:ca:86:8c:c8:e7:31:47:fc:16: - fe:54:0c:f5:26:b1:7e:dc:98:26:70:58:26:13:5c:c7:75:db: - 12:de:4c:ac:ff:9a:0c:ea:a2:c2:1c:41:04:8c:e6:47:97:47: - 6f:89:c5:48:de:37:0d:6a:d9:f0:68:24:5c:ff:19:59:e6:e1: - 70:37:38:0d:db:ee:b0:e2 ------BEGIN CERTIFICATE----- -MIIGCDCCA/CgAwIBAgIKYV2q0gAGAAAAQDANBgkqhkiG9w0BAQUFADAnMSUwIwYD -VQQDExxNaWNyb3NvZnQgSW50ZXJuZXQgQXV0aG9yaXR5MB4XDTEyMDUxNTIwNDA1 -NVoXDTE2MDUxNTIwNTA1NVowgYAxEzARBgoJkiaJk/IsZAEZFgNjb20xGTAXBgoJ -kiaJk/IsZAEZFgltaWNyb3NvZnQxFDASBgoJkiaJk/IsZAEZFgRjb3JwMRcwFQYK -CZImiZPyLGQBGRYHcmVkbW9uZDEfMB0GA1UEAxMWTVNJVCBNYWNoaW5lIEF1dGgg -Q0EgMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3I6ADrWGkpEYSH -HJ+HTUQ9OBvHE5PnFEwXK9t1CMDJIcqu4B/ojP6h3ySMvwKc7Zm+OlMqRU6wSHg3 -3KFj7wO3lClmbGbXbGpIZbLdRyEjG7hBdC+W3ZgiufrzDkqwLwui3rcCE0JwP3gE -FHLjOit+KEgdlrTbFjmNs8RZodei0mRhMytBGMWrlW9dIgd3zVOdA0ll1Yj1X53w -xGlPkQilOQeWNq8tZNwmWsET7jE51l/cl/wnqgV4R8UiJmNTfjfCe2Q9acvw+4oV -PlKzhmq0wRw7svXHPsV23XRodnpV5oB7Loym2ruRWgfNGUrqCFz/wUnWewa/67dK -n7QnnBcCAwEAAaOCAdowggHWMBIGCSsGAQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGC -NxUCBBYEFCO30O1oke9mm+EFQHq+Z8oz1ga9MB0GA1UdDgQWBBTr2xFe+Ame2NZi -nP1ineOESijhJzAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMC -AYYwEgYDVR0TAQH/BAgwBgEB/wIBADAfBgNVHSMEGDAWgBQqTZeVXTR+nbbmM76c -J8FwfmfbwTCBowYDVR0fBIGbMIGYMIGVoIGSoIGPhjZodHRwOi8vbXNjcmwubWlj -cm9zb2Z0LmNvbS9wa2kvbXNjb3JwL2NybC9tc3d3dyg2KS5jcmyGNGh0dHA6Ly9j -cmwubWljcm9zb2Z0LmNvbS9wa2kvbXNjb3JwL2NybC9tc3d3dyg2KS5jcmyGH2h0 -dHA6Ly9jb3JwcGtpL2NybC9tc3d3dyg2KS5jcmwweQYIKwYBBQUHAQEEbTBrMDwG -CCsGAQUFBzAChjBodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL21zY29ycC9t -c3d3dyg2KS5jcnQwKwYIKwYBBQUHMAKGH2h0dHA6Ly9jb3JwcGtpL2FpYS9tc3d3 -dyg2KS5jcnQwDQYJKoZIhvcNAQEFBQADggIBAKM2cvdFC6eGN94gjfXXjtqJAHpS -S4UysjLX7YBX/Q1RHNEePQw+kSow4lO8YQeJAhG5G4NI0xrHR5Zit8/e1w24nYSO -3tXm5LnABuMc9DFDH1P8SkK1myPNsuwND4GJ/1mpANMESguvW4T1O0+5N5GIIeSc -ylJ2Y36IemW0jhZq9GC9LA7vF4YrdQlYc8VPuagb7yr0tqO5B/CkkDlT3+G6Apil -pYIRoQZTssLr/epncjdj0IXPhgXIw3PB2/PE0lX/oB3nchQa/7L/CEJIQAoZgs8i -8wXF1d8LKcQ6DsUyOO8vlJoM8tTuv2LH4qRfPW54vBDBLkow8ofbiTi+/syAj/X5 -XMtc8eoCCGulC+8gXKM0zPCAth9juUQyHCZBm92To2QBVxEhQ5QqVy2KSsuKKEAK -+1D5ryZ0E5eCTmxk69HGv179JdoFRkquxy/HBO8ucS7iqFuk6rJvqJE1xLdjF2IO -J448JM09RWkF3FLFNfgRwB3fYmD04aZecLhFdAOr0RZ0457TwaPokJaKisJGRp25 -XGwCHTKE6xSFdpWqTS1ptgL2/u001Yzm+qxd3ANA5s93if+xKMqGjMjnMUf8Fv5U -DPUmsX7cmCZwWCYTXMd12xLeTKz/mgzqosIcQQSM5keXR2+JxUjeNw1q2fBoJFz/ -GVnm4XA3OA3b7rDi ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert56[] = { - 0x30, 0x82, 0x06, 0x08, 0x30, 0x82, 0x03, 0xf0, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x0a, 0x61, 0x5d, 0xaa, 0xd2, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x40, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, - 0x01, 0x05, 0x05, 0x00, 0x30, 0x27, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, - 0x55, 0x04, 0x03, 0x13, 0x1c, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, - 0x66, 0x74, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, - 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, - 0x0d, 0x31, 0x32, 0x30, 0x35, 0x31, 0x35, 0x32, 0x30, 0x34, 0x30, 0x35, - 0x35, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x35, 0x31, 0x35, 0x32, 0x30, - 0x35, 0x30, 0x35, 0x35, 0x5a, 0x30, 0x81, 0x80, 0x31, 0x13, 0x30, 0x11, - 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, - 0x16, 0x03, 0x63, 0x6f, 0x6d, 0x31, 0x19, 0x30, 0x17, 0x06, 0x0a, 0x09, - 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x09, 0x6d, - 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x31, 0x14, 0x30, 0x12, - 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, - 0x16, 0x04, 0x63, 0x6f, 0x72, 0x70, 0x31, 0x17, 0x30, 0x15, 0x06, 0x0a, - 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x07, - 0x72, 0x65, 0x64, 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1f, 0x30, 0x1d, 0x06, - 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x4d, 0x53, 0x49, 0x54, 0x20, 0x4d, - 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x20, - 0x43, 0x41, 0x20, 0x32, 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, 0xbd, 0xc8, 0xe8, 0x00, 0xeb, 0x58, 0x69, 0x29, 0x11, 0x84, 0x87, - 0x1c, 0x9f, 0x87, 0x4d, 0x44, 0x3d, 0x38, 0x1b, 0xc7, 0x13, 0x93, 0xe7, - 0x14, 0x4c, 0x17, 0x2b, 0xdb, 0x75, 0x08, 0xc0, 0xc9, 0x21, 0xca, 0xae, - 0xe0, 0x1f, 0xe8, 0x8c, 0xfe, 0xa1, 0xdf, 0x24, 0x8c, 0xbf, 0x02, 0x9c, - 0xed, 0x99, 0xbe, 0x3a, 0x53, 0x2a, 0x45, 0x4e, 0xb0, 0x48, 0x78, 0x37, - 0xdc, 0xa1, 0x63, 0xef, 0x03, 0xb7, 0x94, 0x29, 0x66, 0x6c, 0x66, 0xd7, - 0x6c, 0x6a, 0x48, 0x65, 0xb2, 0xdd, 0x47, 0x21, 0x23, 0x1b, 0xb8, 0x41, - 0x74, 0x2f, 0x96, 0xdd, 0x98, 0x22, 0xb9, 0xfa, 0xf3, 0x0e, 0x4a, 0xb0, - 0x2f, 0x0b, 0xa2, 0xde, 0xb7, 0x02, 0x13, 0x42, 0x70, 0x3f, 0x78, 0x04, - 0x14, 0x72, 0xe3, 0x3a, 0x2b, 0x7e, 0x28, 0x48, 0x1d, 0x96, 0xb4, 0xdb, - 0x16, 0x39, 0x8d, 0xb3, 0xc4, 0x59, 0xa1, 0xd7, 0xa2, 0xd2, 0x64, 0x61, - 0x33, 0x2b, 0x41, 0x18, 0xc5, 0xab, 0x95, 0x6f, 0x5d, 0x22, 0x07, 0x77, - 0xcd, 0x53, 0x9d, 0x03, 0x49, 0x65, 0xd5, 0x88, 0xf5, 0x5f, 0x9d, 0xf0, - 0xc4, 0x69, 0x4f, 0x91, 0x08, 0xa5, 0x39, 0x07, 0x96, 0x36, 0xaf, 0x2d, - 0x64, 0xdc, 0x26, 0x5a, 0xc1, 0x13, 0xee, 0x31, 0x39, 0xd6, 0x5f, 0xdc, - 0x97, 0xfc, 0x27, 0xaa, 0x05, 0x78, 0x47, 0xc5, 0x22, 0x26, 0x63, 0x53, - 0x7e, 0x37, 0xc2, 0x7b, 0x64, 0x3d, 0x69, 0xcb, 0xf0, 0xfb, 0x8a, 0x15, - 0x3e, 0x52, 0xb3, 0x86, 0x6a, 0xb4, 0xc1, 0x1c, 0x3b, 0xb2, 0xf5, 0xc7, - 0x3e, 0xc5, 0x76, 0xdd, 0x74, 0x68, 0x76, 0x7a, 0x55, 0xe6, 0x80, 0x7b, - 0x2e, 0x8c, 0xa6, 0xda, 0xbb, 0x91, 0x5a, 0x07, 0xcd, 0x19, 0x4a, 0xea, - 0x08, 0x5c, 0xff, 0xc1, 0x49, 0xd6, 0x7b, 0x06, 0xbf, 0xeb, 0xb7, 0x4a, - 0x9f, 0xb4, 0x27, 0x9c, 0x17, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, - 0x01, 0xda, 0x30, 0x82, 0x01, 0xd6, 0x30, 0x12, 0x06, 0x09, 0x2b, 0x06, - 0x01, 0x04, 0x01, 0x82, 0x37, 0x15, 0x01, 0x04, 0x05, 0x02, 0x03, 0x01, - 0x00, 0x01, 0x30, 0x23, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, - 0x37, 0x15, 0x02, 0x04, 0x16, 0x04, 0x14, 0x23, 0xb7, 0xd0, 0xed, 0x68, - 0x91, 0xef, 0x66, 0x9b, 0xe1, 0x05, 0x40, 0x7a, 0xbe, 0x67, 0xca, 0x33, - 0xd6, 0x06, 0xbd, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, - 0x04, 0x14, 0xeb, 0xdb, 0x11, 0x5e, 0xf8, 0x09, 0x9e, 0xd8, 0xd6, 0x62, - 0x9c, 0xfd, 0x62, 0x9d, 0xe3, 0x84, 0x4a, 0x28, 0xe1, 0x27, 0x30, 0x19, - 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, - 0x0c, 0x1e, 0x0a, 0x00, 0x53, 0x00, 0x75, 0x00, 0x62, 0x00, 0x43, 0x00, - 0x41, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, - 0x01, 0x86, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, - 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x1f, - 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x2a, - 0x4d, 0x97, 0x95, 0x5d, 0x34, 0x7e, 0x9d, 0xb6, 0xe6, 0x33, 0xbe, 0x9c, - 0x27, 0xc1, 0x70, 0x7e, 0x67, 0xdb, 0xc1, 0x30, 0x81, 0xa3, 0x06, 0x03, - 0x55, 0x1d, 0x1f, 0x04, 0x81, 0x9b, 0x30, 0x81, 0x98, 0x30, 0x81, 0x95, - 0xa0, 0x81, 0x92, 0xa0, 0x81, 0x8f, 0x86, 0x36, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x6d, 0x73, 0x63, 0x72, 0x6c, 0x2e, 0x6d, 0x69, 0x63, - 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, - 0x6b, 0x69, 0x2f, 0x6d, 0x73, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x72, - 0x6c, 0x2f, 0x6d, 0x73, 0x77, 0x77, 0x77, 0x28, 0x36, 0x29, 0x2e, 0x63, - 0x72, 0x6c, 0x86, 0x34, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, - 0x72, 0x6c, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6b, 0x69, 0x2f, 0x6d, 0x73, 0x63, - 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x6d, 0x73, 0x77, 0x77, - 0x77, 0x28, 0x36, 0x29, 0x2e, 0x63, 0x72, 0x6c, 0x86, 0x1f, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x6f, 0x72, 0x70, 0x70, 0x6b, 0x69, - 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x6d, 0x73, 0x77, 0x77, 0x77, 0x28, 0x36, - 0x29, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x79, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x6d, 0x30, 0x6b, 0x30, 0x3c, 0x06, - 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x30, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x6d, 0x69, - 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x70, 0x6b, 0x69, 0x2f, 0x6d, 0x73, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x6d, - 0x73, 0x77, 0x77, 0x77, 0x28, 0x36, 0x29, 0x2e, 0x63, 0x72, 0x74, 0x30, - 0x2b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, - 0x1f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x6f, 0x72, 0x70, - 0x70, 0x6b, 0x69, 0x2f, 0x61, 0x69, 0x61, 0x2f, 0x6d, 0x73, 0x77, 0x77, - 0x77, 0x28, 0x36, 0x29, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, - 0x82, 0x02, 0x01, 0x00, 0xa3, 0x36, 0x72, 0xf7, 0x45, 0x0b, 0xa7, 0x86, - 0x37, 0xde, 0x20, 0x8d, 0xf5, 0xd7, 0x8e, 0xda, 0x89, 0x00, 0x7a, 0x52, - 0x4b, 0x85, 0x32, 0xb2, 0x32, 0xd7, 0xed, 0x80, 0x57, 0xfd, 0x0d, 0x51, - 0x1c, 0xd1, 0x1e, 0x3d, 0x0c, 0x3e, 0x91, 0x2a, 0x30, 0xe2, 0x53, 0xbc, - 0x61, 0x07, 0x89, 0x02, 0x11, 0xb9, 0x1b, 0x83, 0x48, 0xd3, 0x1a, 0xc7, - 0x47, 0x96, 0x62, 0xb7, 0xcf, 0xde, 0xd7, 0x0d, 0xb8, 0x9d, 0x84, 0x8e, - 0xde, 0xd5, 0xe6, 0xe4, 0xb9, 0xc0, 0x06, 0xe3, 0x1c, 0xf4, 0x31, 0x43, - 0x1f, 0x53, 0xfc, 0x4a, 0x42, 0xb5, 0x9b, 0x23, 0xcd, 0xb2, 0xec, 0x0d, - 0x0f, 0x81, 0x89, 0xff, 0x59, 0xa9, 0x00, 0xd3, 0x04, 0x4a, 0x0b, 0xaf, - 0x5b, 0x84, 0xf5, 0x3b, 0x4f, 0xb9, 0x37, 0x91, 0x88, 0x21, 0xe4, 0x9c, - 0xca, 0x52, 0x76, 0x63, 0x7e, 0x88, 0x7a, 0x65, 0xb4, 0x8e, 0x16, 0x6a, - 0xf4, 0x60, 0xbd, 0x2c, 0x0e, 0xef, 0x17, 0x86, 0x2b, 0x75, 0x09, 0x58, - 0x73, 0xc5, 0x4f, 0xb9, 0xa8, 0x1b, 0xef, 0x2a, 0xf4, 0xb6, 0xa3, 0xb9, - 0x07, 0xf0, 0xa4, 0x90, 0x39, 0x53, 0xdf, 0xe1, 0xba, 0x02, 0x98, 0xa5, - 0xa5, 0x82, 0x11, 0xa1, 0x06, 0x53, 0xb2, 0xc2, 0xeb, 0xfd, 0xea, 0x67, - 0x72, 0x37, 0x63, 0xd0, 0x85, 0xcf, 0x86, 0x05, 0xc8, 0xc3, 0x73, 0xc1, - 0xdb, 0xf3, 0xc4, 0xd2, 0x55, 0xff, 0xa0, 0x1d, 0xe7, 0x72, 0x14, 0x1a, - 0xff, 0xb2, 0xff, 0x08, 0x42, 0x48, 0x40, 0x0a, 0x19, 0x82, 0xcf, 0x22, - 0xf3, 0x05, 0xc5, 0xd5, 0xdf, 0x0b, 0x29, 0xc4, 0x3a, 0x0e, 0xc5, 0x32, - 0x38, 0xef, 0x2f, 0x94, 0x9a, 0x0c, 0xf2, 0xd4, 0xee, 0xbf, 0x62, 0xc7, - 0xe2, 0xa4, 0x5f, 0x3d, 0x6e, 0x78, 0xbc, 0x10, 0xc1, 0x2e, 0x4a, 0x30, - 0xf2, 0x87, 0xdb, 0x89, 0x38, 0xbe, 0xfe, 0xcc, 0x80, 0x8f, 0xf5, 0xf9, - 0x5c, 0xcb, 0x5c, 0xf1, 0xea, 0x02, 0x08, 0x6b, 0xa5, 0x0b, 0xef, 0x20, - 0x5c, 0xa3, 0x34, 0xcc, 0xf0, 0x80, 0xb6, 0x1f, 0x63, 0xb9, 0x44, 0x32, - 0x1c, 0x26, 0x41, 0x9b, 0xdd, 0x93, 0xa3, 0x64, 0x01, 0x57, 0x11, 0x21, - 0x43, 0x94, 0x2a, 0x57, 0x2d, 0x8a, 0x4a, 0xcb, 0x8a, 0x28, 0x40, 0x0a, - 0xfb, 0x50, 0xf9, 0xaf, 0x26, 0x74, 0x13, 0x97, 0x82, 0x4e, 0x6c, 0x64, - 0xeb, 0xd1, 0xc6, 0xbf, 0x5e, 0xfd, 0x25, 0xda, 0x05, 0x46, 0x4a, 0xae, - 0xc7, 0x2f, 0xc7, 0x04, 0xef, 0x2e, 0x71, 0x2e, 0xe2, 0xa8, 0x5b, 0xa4, - 0xea, 0xb2, 0x6f, 0xa8, 0x91, 0x35, 0xc4, 0xb7, 0x63, 0x17, 0x62, 0x0e, - 0x27, 0x8e, 0x3c, 0x24, 0xcd, 0x3d, 0x45, 0x69, 0x05, 0xdc, 0x52, 0xc5, - 0x35, 0xf8, 0x11, 0xc0, 0x1d, 0xdf, 0x62, 0x60, 0xf4, 0xe1, 0xa6, 0x5e, - 0x70, 0xb8, 0x45, 0x74, 0x03, 0xab, 0xd1, 0x16, 0x74, 0xe3, 0x9e, 0xd3, - 0xc1, 0xa3, 0xe8, 0x90, 0x96, 0x8a, 0x8a, 0xc2, 0x46, 0x46, 0x9d, 0xb9, - 0x5c, 0x6c, 0x02, 0x1d, 0x32, 0x84, 0xeb, 0x14, 0x85, 0x76, 0x95, 0xaa, - 0x4d, 0x2d, 0x69, 0xb6, 0x02, 0xf6, 0xfe, 0xed, 0x34, 0xd5, 0x8c, 0xe6, - 0xfa, 0xac, 0x5d, 0xdc, 0x03, 0x40, 0xe6, 0xcf, 0x77, 0x89, 0xff, 0xb1, - 0x28, 0xca, 0x86, 0x8c, 0xc8, 0xe7, 0x31, 0x47, 0xfc, 0x16, 0xfe, 0x54, - 0x0c, 0xf5, 0x26, 0xb1, 0x7e, 0xdc, 0x98, 0x26, 0x70, 0x58, 0x26, 0x13, - 0x5c, 0xc7, 0x75, 0xdb, 0x12, 0xde, 0x4c, 0xac, 0xff, 0x9a, 0x0c, 0xea, - 0xa2, 0xc2, 0x1c, 0x41, 0x04, 0x8c, 0xe6, 0x47, 0x97, 0x47, 0x6f, 0x89, - 0xc5, 0x48, 0xde, 0x37, 0x0d, 0x6a, 0xd9, 0xf0, 0x68, 0x24, 0x5c, 0xff, - 0x19, 0x59, 0xe6, 0xe1, 0x70, 0x37, 0x38, 0x0d, 0xdb, 0xee, 0xb0, 0xe2, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 2c:48:dd:93:0d:f5:59:8e:f9:3c:99:54:7a:60:ed:43 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5 - Validity - Not Before: Nov 8 00:00:00 2006 GMT - Not After : Nov 7 23:59:59 2016 GMT - Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=Terms of use at https://www.verisign.com/rpa (c)06, CN=VeriSign Class 3 Extended Validation SSL SGC CA - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:bd:56:88:ba:88:34:64:64:cf:cd:ca:b0:ee:e7: - 19:73:c5:72:d9:bb:45:bc:b5:a8:ff:83:be:1c:03: - db:ed:89:b7:2e:10:1a:25:bc:55:ca:41:a1:9f:0b: - cf:19:5e:70:b9:5e:39:4b:9e:31:1c:5f:87:ae:2a: - aa:a8:2b:a2:1b:3b:10:23:5f:13:b1:dd:08:8c:4e: - 14:da:83:81:e3:b5:8c:e3:68:ed:24:67:ce:56:b6: - ac:9b:73:96:44:db:8a:8c:b3:d6:f0:71:93:8e:db: - 71:54:4a:eb:73:59:6a:8f:70:51:2c:03:9f:97:d1: - cc:11:7a:bc:62:0d:95:2a:c9:1c:75:57:e9:f5:c7: - ea:ba:84:35:cb:c7:85:5a:7e:e4:4d:e1:11:97:7d: - 0e:20:34:45:db:f1:a2:09:eb:eb:3d:9e:b8:96:43: - 5e:34:4b:08:25:1e:43:1a:a2:d9:b7:8a:01:34:3d: - c3:f8:e5:af:4f:8c:ff:cd:65:f0:23:4e:c5:97:b3: - 5c:da:90:1c:82:85:0d:06:0d:c1:22:b6:7b:28:a4: - 03:c3:4c:53:d1:58:bc:72:bc:08:39:fc:a0:76:a8: - a8:e9:4b:6e:88:3d:e3:b3:31:25:8c:73:29:48:0e: - 32:79:06:ed:3d:43:f4:f6:e4:e9:fc:7d:be:8e:08: - d5:1f - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Subject Key Identifier: - 4E:43:C8:1D:76:EF:37:53:7A:4F:F2:58:6F:94:F3:38:E2:D5:BD:DF - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Certificate Policies: - Policy: X509v3 Any Policy - CPS: https://www.verisign.com/cps - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://EVSecure-crl.verisign.com/pca3-g5.crl - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - Netscape Cert Type: - SSL CA, S/MIME CA - 1.3.6.1.5.5.7.1.12: - 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif - X509v3 Subject Alternative Name: - DirName:/CN=Class3CA2048-1-48 - X509v3 Authority Key Identifier: - keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33 - - Authority Information Access: - OCSP - URI:http://EVSecure-ocsp.verisign.com - - X509v3 Extended Key Usage: - Netscape Server Gated Crypto, 2.16.840.1.113733.1.8.1, TLS Web Server Authentication, TLS Web Client Authentication - Signature Algorithm: sha1WithRSAEncryption - 27:74:a6:34:ea:1d:9d:e1:53:d6:1c:9d:0c:a7:5b:4c:a9:67: - f2:f0:32:b7:01:0f:fb:42:18:38:de:e4:ee:49:c8:13:c9:0b: - ec:04:c3:40:71:18:72:76:43:02:23:5d:ab:7b:c8:48:14:1a: - c8:7b:1d:fc:f6:0a:9f:36:a1:d2:09:73:71:66:96:75:51:34: - bf:99:30:51:67:9d:54:b7:26:45:ac:73:08:23:86:26:99:71: - f4:8e:d7:ea:39:9b:06:09:23:bf:62:dd:a8:c4:b6:7d:a4:89: - 07:3e:f3:6d:ae:40:59:50:79:97:37:3d:32:78:7d:b2:63:4b: - f9:ea:08:69:0e:13:ed:e8:cf:bb:ac:05:86:ca:22:cf:88:62: - 5d:3c:22:49:d8:63:d5:24:a6:bd:ef:5c:e3:cc:20:3b:22:ea: - fc:44:c6:a8:e5:1f:e1:86:cd:0c:4d:8f:93:53:d9:7f:ee:a1: - 08:a7:b3:30:96:49:70:6e:a3:6c:3d:d0:63:ef:25:66:63:cc: - aa:b7:18:17:4e:ea:70:76:f6:ba:42:a6:80:37:09:4e:9f:66: - 88:2e:6b:33:66:c8:c0:71:a4:41:eb:5a:e3:fc:14:2e:4b:88: - fd:ae:6e:5b:65:e9:27:e4:bf:e4:b0:23:c1:b2:7d:5b:62:25: - d7:3e:10:d4 ------BEGIN CERTIFICATE----- -MIIGHjCCBQagAwIBAgIQLEjdkw31WY75PJlUemDtQzANBgkqhkiG9w0BAQUFADCB -yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL -ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp -U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW -ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMTYxMTA3MjM1OTU5WjCBvjEL -MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW -ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQg -aHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwNjE4MDYGA1UEAxMvVmVy -aVNpZ24gQ2xhc3MgMyBFeHRlbmRlZCBWYWxpZGF0aW9uIFNTTCBTR0MgQ0EwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9Voi6iDRkZM/NyrDu5xlzxXLZ -u0W8taj/g74cA9vtibcuEBolvFXKQaGfC88ZXnC5XjlLnjEcX4euKqqoK6IbOxAj -XxOx3QiMThTag4HjtYzjaO0kZ85Wtqybc5ZE24qMs9bwcZOO23FUSutzWWqPcFEs -A5+X0cwRerxiDZUqyRx1V+n1x+q6hDXLx4VafuRN4RGXfQ4gNEXb8aIJ6+s9nriW -Q140SwglHkMaotm3igE0PcP45a9PjP/NZfAjTsWXs1zakByChQ0GDcEitnsopAPD -TFPRWLxyvAg5/KB2qKjpS26IPeOzMSWMcylIDjJ5Bu09Q/T25On8fb6OCNUfAgMB -AAGjggIIMIICBDAdBgNVHQ4EFgQUTkPIHXbvN1N6T/JYb5TzOOLVvd8wEgYDVR0T -AQH/BAgwBgEB/wIBADA9BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYc -aHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL2NwczA9BgNVHR8ENjA0MDKgMKAuhixo -dHRwOi8vRVZTZWN1cmUtY3JsLnZlcmlzaWduLmNvbS9wY2EzLWc1LmNybDAOBgNV -HQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgEGMG0GCCsGAQUFBwEMBGEwX6Fd -oFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrU -SBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMCkG -A1UdEQQiMCCkHjAcMRowGAYDVQQDExFDbGFzczNDQTIwNDgtMS00ODAfBgNVHSME -GDAWgBR/02Wnwt3su/AwCfNDOfoCrzMxMzA9BggrBgEFBQcBAQQxMC8wLQYIKwYB -BQUHMAGGIWh0dHA6Ly9FVlNlY3VyZS1vY3NwLnZlcmlzaWduLmNvbTA0BgNVHSUE -LTArBglghkgBhvhCBAEGCmCGSAGG+EUBCAEGCCsGAQUFBwMBBggrBgEFBQcDAjAN -BgkqhkiG9w0BAQUFAAOCAQEAJ3SmNOodneFT1hydDKdbTKln8vAytwEP+0IYON7k -7knIE8kL7ATDQHEYcnZDAiNdq3vISBQayHsd/PYKnzah0glzcWaWdVE0v5kwUWed -VLcmRaxzCCOGJplx9I7X6jmbBgkjv2LdqMS2faSJBz7zba5AWVB5lzc9Mnh9smNL -+eoIaQ4T7ejPu6wFhsoiz4hiXTwiSdhj1SSmve9c48wgOyLq/ETGqOUf4YbNDE2P -k1PZf+6hCKezMJZJcG6jbD3QY+8lZmPMqrcYF07qcHb2ukKmgDcJTp9miC5rM2bI -wHGkQeta4/wULkuI/a5uW2XpJ+S/5LAjwbJ9W2Il1z4Q1A== ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert57[] = { - 0x30, 0x82, 0x06, 0x1e, 0x30, 0x82, 0x05, 0x06, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x2c, 0x48, 0xdd, 0x93, 0x0d, 0xf5, 0x59, 0x8e, 0xf9, - 0x3c, 0x99, 0x54, 0x7a, 0x60, 0xed, 0x43, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, - 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, - 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, - 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, - 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, - 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, - 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, - 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56, - 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, - 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30, - 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x30, 0x38, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, 0x36, 0x31, 0x31, 0x30, 0x37, - 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xbe, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, - 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56, - 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, - 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3b, 0x30, - 0x39, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65, 0x72, 0x6d, - 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20, - 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, - 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x30, 0x36, 0x31, 0x38, - 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2f, 0x56, 0x65, 0x72, - 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, - 0x33, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x53, - 0x4c, 0x20, 0x53, 0x47, 0x43, 0x20, 0x43, 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, 0xbd, 0x56, 0x88, 0xba, 0x88, 0x34, 0x64, - 0x64, 0xcf, 0xcd, 0xca, 0xb0, 0xee, 0xe7, 0x19, 0x73, 0xc5, 0x72, 0xd9, - 0xbb, 0x45, 0xbc, 0xb5, 0xa8, 0xff, 0x83, 0xbe, 0x1c, 0x03, 0xdb, 0xed, - 0x89, 0xb7, 0x2e, 0x10, 0x1a, 0x25, 0xbc, 0x55, 0xca, 0x41, 0xa1, 0x9f, - 0x0b, 0xcf, 0x19, 0x5e, 0x70, 0xb9, 0x5e, 0x39, 0x4b, 0x9e, 0x31, 0x1c, - 0x5f, 0x87, 0xae, 0x2a, 0xaa, 0xa8, 0x2b, 0xa2, 0x1b, 0x3b, 0x10, 0x23, - 0x5f, 0x13, 0xb1, 0xdd, 0x08, 0x8c, 0x4e, 0x14, 0xda, 0x83, 0x81, 0xe3, - 0xb5, 0x8c, 0xe3, 0x68, 0xed, 0x24, 0x67, 0xce, 0x56, 0xb6, 0xac, 0x9b, - 0x73, 0x96, 0x44, 0xdb, 0x8a, 0x8c, 0xb3, 0xd6, 0xf0, 0x71, 0x93, 0x8e, - 0xdb, 0x71, 0x54, 0x4a, 0xeb, 0x73, 0x59, 0x6a, 0x8f, 0x70, 0x51, 0x2c, - 0x03, 0x9f, 0x97, 0xd1, 0xcc, 0x11, 0x7a, 0xbc, 0x62, 0x0d, 0x95, 0x2a, - 0xc9, 0x1c, 0x75, 0x57, 0xe9, 0xf5, 0xc7, 0xea, 0xba, 0x84, 0x35, 0xcb, - 0xc7, 0x85, 0x5a, 0x7e, 0xe4, 0x4d, 0xe1, 0x11, 0x97, 0x7d, 0x0e, 0x20, - 0x34, 0x45, 0xdb, 0xf1, 0xa2, 0x09, 0xeb, 0xeb, 0x3d, 0x9e, 0xb8, 0x96, - 0x43, 0x5e, 0x34, 0x4b, 0x08, 0x25, 0x1e, 0x43, 0x1a, 0xa2, 0xd9, 0xb7, - 0x8a, 0x01, 0x34, 0x3d, 0xc3, 0xf8, 0xe5, 0xaf, 0x4f, 0x8c, 0xff, 0xcd, - 0x65, 0xf0, 0x23, 0x4e, 0xc5, 0x97, 0xb3, 0x5c, 0xda, 0x90, 0x1c, 0x82, - 0x85, 0x0d, 0x06, 0x0d, 0xc1, 0x22, 0xb6, 0x7b, 0x28, 0xa4, 0x03, 0xc3, - 0x4c, 0x53, 0xd1, 0x58, 0xbc, 0x72, 0xbc, 0x08, 0x39, 0xfc, 0xa0, 0x76, - 0xa8, 0xa8, 0xe9, 0x4b, 0x6e, 0x88, 0x3d, 0xe3, 0xb3, 0x31, 0x25, 0x8c, - 0x73, 0x29, 0x48, 0x0e, 0x32, 0x79, 0x06, 0xed, 0x3d, 0x43, 0xf4, 0xf6, - 0xe4, 0xe9, 0xfc, 0x7d, 0xbe, 0x8e, 0x08, 0xd5, 0x1f, 0x02, 0x03, 0x01, - 0x00, 0x01, 0xa3, 0x82, 0x02, 0x08, 0x30, 0x82, 0x02, 0x04, 0x30, 0x1d, - 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x4e, 0x43, 0xc8, - 0x1d, 0x76, 0xef, 0x37, 0x53, 0x7a, 0x4f, 0xf2, 0x58, 0x6f, 0x94, 0xf3, - 0x38, 0xe2, 0xd5, 0xbd, 0xdf, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, - 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, - 0x00, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, - 0x30, 0x32, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, - 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, - 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, - 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x63, 0x70, 0x73, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, - 0x36, 0x30, 0x34, 0x30, 0x32, 0xa0, 0x30, 0xa0, 0x2e, 0x86, 0x2c, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x45, 0x56, 0x53, 0x65, 0x63, 0x75, - 0x72, 0x65, 0x2d, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, - 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33, - 0x2d, 0x67, 0x35, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, - 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, - 0x11, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01, - 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x6d, 0x06, 0x08, 0x2b, 0x06, - 0x01, 0x05, 0x05, 0x07, 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f, 0xa1, 0x5d, - 0xa0, 0x5b, 0x30, 0x59, 0x30, 0x57, 0x30, 0x55, 0x16, 0x09, 0x69, 0x6d, - 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x30, 0x21, 0x30, 0x1f, 0x30, - 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, 0x8f, 0xe5, - 0xd3, 0x1a, 0x86, 0xac, 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80, 0x6a, 0xd4, - 0x48, 0x18, 0x2c, 0x7b, 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x76, 0x65, - 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, - 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30, 0x29, 0x06, - 0x03, 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, - 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x43, - 0x6c, 0x61, 0x73, 0x73, 0x33, 0x43, 0x41, 0x32, 0x30, 0x34, 0x38, 0x2d, - 0x31, 0x2d, 0x34, 0x38, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, - 0x18, 0x30, 0x16, 0x80, 0x14, 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, - 0xbb, 0xf0, 0x30, 0x09, 0xf3, 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, - 0x33, 0x30, 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, - 0x01, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x45, 0x56, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2d, 0x6f, - 0x63, 0x73, 0x70, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, - 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x34, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, - 0x2d, 0x30, 0x2b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, - 0x04, 0x01, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, - 0x08, 0x01, 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, 0x05, 0x05, - 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x27, 0x74, 0xa6, 0x34, 0xea, 0x1d, - 0x9d, 0xe1, 0x53, 0xd6, 0x1c, 0x9d, 0x0c, 0xa7, 0x5b, 0x4c, 0xa9, 0x67, - 0xf2, 0xf0, 0x32, 0xb7, 0x01, 0x0f, 0xfb, 0x42, 0x18, 0x38, 0xde, 0xe4, - 0xee, 0x49, 0xc8, 0x13, 0xc9, 0x0b, 0xec, 0x04, 0xc3, 0x40, 0x71, 0x18, - 0x72, 0x76, 0x43, 0x02, 0x23, 0x5d, 0xab, 0x7b, 0xc8, 0x48, 0x14, 0x1a, - 0xc8, 0x7b, 0x1d, 0xfc, 0xf6, 0x0a, 0x9f, 0x36, 0xa1, 0xd2, 0x09, 0x73, - 0x71, 0x66, 0x96, 0x75, 0x51, 0x34, 0xbf, 0x99, 0x30, 0x51, 0x67, 0x9d, - 0x54, 0xb7, 0x26, 0x45, 0xac, 0x73, 0x08, 0x23, 0x86, 0x26, 0x99, 0x71, - 0xf4, 0x8e, 0xd7, 0xea, 0x39, 0x9b, 0x06, 0x09, 0x23, 0xbf, 0x62, 0xdd, - 0xa8, 0xc4, 0xb6, 0x7d, 0xa4, 0x89, 0x07, 0x3e, 0xf3, 0x6d, 0xae, 0x40, - 0x59, 0x50, 0x79, 0x97, 0x37, 0x3d, 0x32, 0x78, 0x7d, 0xb2, 0x63, 0x4b, - 0xf9, 0xea, 0x08, 0x69, 0x0e, 0x13, 0xed, 0xe8, 0xcf, 0xbb, 0xac, 0x05, - 0x86, 0xca, 0x22, 0xcf, 0x88, 0x62, 0x5d, 0x3c, 0x22, 0x49, 0xd8, 0x63, - 0xd5, 0x24, 0xa6, 0xbd, 0xef, 0x5c, 0xe3, 0xcc, 0x20, 0x3b, 0x22, 0xea, - 0xfc, 0x44, 0xc6, 0xa8, 0xe5, 0x1f, 0xe1, 0x86, 0xcd, 0x0c, 0x4d, 0x8f, - 0x93, 0x53, 0xd9, 0x7f, 0xee, 0xa1, 0x08, 0xa7, 0xb3, 0x30, 0x96, 0x49, - 0x70, 0x6e, 0xa3, 0x6c, 0x3d, 0xd0, 0x63, 0xef, 0x25, 0x66, 0x63, 0xcc, - 0xaa, 0xb7, 0x18, 0x17, 0x4e, 0xea, 0x70, 0x76, 0xf6, 0xba, 0x42, 0xa6, - 0x80, 0x37, 0x09, 0x4e, 0x9f, 0x66, 0x88, 0x2e, 0x6b, 0x33, 0x66, 0xc8, - 0xc0, 0x71, 0xa4, 0x41, 0xeb, 0x5a, 0xe3, 0xfc, 0x14, 0x2e, 0x4b, 0x88, - 0xfd, 0xae, 0x6e, 0x5b, 0x65, 0xe9, 0x27, 0xe4, 0xbf, 0xe4, 0xb0, 0x23, - 0xc1, 0xb2, 0x7d, 0x5b, 0x62, 0x25, 0xd7, 0x3e, 0x10, 0xd4, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 64:1b:e8:20:ce:02:08:13:f3:2d:4d:2d:95:d6:7e:67 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5 - Validity - Not Before: Feb 8 00:00:00 2010 GMT - Not After : Feb 7 23:59:59 2020 GMT - Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=Terms of use at https://www.verisign.com/rpa (c)10, CN=VeriSign Class 3 International Server CA - G3 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:99:d6:9c:62:f0:15:f4:81:9a:41:08:59:8f:13: - 9d:17:c9:9f:51:dc:da:b1:52:ef:ff:e3:41:dd:e0: - df:c4:28:c6:e3:ad:79:1f:27:10:98:b8:bb:20:97: - c1:28:44:41:0f:ea:a9:a8:52:cf:4d:4e:1b:8b:bb: - b5:c4:76:d9:cc:56:06:ee:b3:55:20:2a:de:15:8d: - 71:cb:54:c8:6f:17:cd:89:00:e4:dc:ff:e1:c0:1f: - 68:71:e9:c7:29:2e:7e:bc:3b:fc:e5:bb:ab:26:54: - 8b:66:90:cd:f6:92:b9:31:24:80:bc:9e:6c:d5:fc: - 7e:d2:e1:4b:8c:dc:42:fa:44:4b:5f:f8:18:b5:2e: - 30:f4:3d:12:98:d3:62:05:73:54:a6:9c:a2:1d:be: - 52:83:3a:07:46:c4:3b:02:56:21:bf:f2:51:4f:d0: - a6:99:39:e9:ae:a5:3f:89:9b:9c:7d:fe:4d:60:07: - 25:20:f7:bb:d7:69:83:2b:82:93:43:37:d9:83:41: - 1b:6b:0b:ab:4a:66:84:4f:4a:8e:de:7e:34:99:8e: - 68:d6:ca:39:06:9b:4c:b3:9a:48:4d:13:46:b4:58: - 21:04:c4:fb:a0:4d:ac:2e:4b:62:12:e3:fb:4d:f6: - c9:51:00:01:1f:fc:1e:6a:81:2a:38:e0:b9:4f:d6: - 2d:45 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Certificate Policies: - Policy: 2.16.840.1.113733.1.7.23.3 - CPS: https://www.verisign.com/cps - User Notice: - Explicit Text: https://www.verisign.com/rpa - - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - 1.3.6.1.5.5.7.1.12: - 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif - X509v3 Extended Key Usage: - TLS Web Server Authentication, TLS Web Client Authentication, Netscape Server Gated Crypto, 2.16.840.1.113733.1.8.1 - Authority Information Access: - OCSP - URI:http://ocsp.verisign.com - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.verisign.com/pca3-g5.crl - - X509v3 Subject Alternative Name: - DirName:/CN=VeriSignMPKI-2-7 - X509v3 Subject Key Identifier: - D7:9B:7C:D8:22:A0:15:F7:DD:AD:5F:CE:29:9B:58:C3:BC:46:00:B5 - X509v3 Authority Key Identifier: - keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33 - - Signature Algorithm: sha1WithRSAEncryption - 71:b5:7d:73:52:4a:dd:d7:4d:34:2b:2e:af:94:46:a5:49:50: - 02:4f:f8:2f:17:70:f2:13:dc:1f:21:86:aa:c2:4f:7c:37:3c: - d4:46:78:ae:5d:78:6f:d1:ba:5a:bc:10:ab:58:36:c5:8c:62: - 15:45:60:17:21:e2:d5:42:a8:77:a1:55:d8:43:04:51:f6:6e: - ba:48:e6:5d:4c:b7:44:d3:3e:a4:d5:d6:33:9a:9f:0d:e6:d7: - 4e:96:44:95:5a:6c:d6:a3:16:53:0e:98:43:ce:a4:b8:c3:66: - 7a:05:5c:62:10:e8:1b:12:db:7d:2e:76:50:ff:df:d7:6b:1b: - cc:8a:cc:71:fa:b3:40:56:7c:33:7a:77:94:5b:f5:0b:53:fb: - 0e:5f:bc:68:fb:af:2a:ee:30:37:79:16:93:25:7f:4d:10:ff: - 57:fb:bf:6e:3b:33:21:de:79:dc:86:17:59:2d:43:64:b7:a6: - 66:87:ea:bc:96:46:19:1a:86:8b:6f:d7:b7:49:00:5b:db:a3: - bf:29:9a:ee:f7:d3:33:ae:a3:f4:9e:4c:ca:5e:69:d4:1b:ad: - b7:90:77:6a:d8:59:6f:79:ab:01:fa:55:f0:8a:21:66:e5:65: - 6e:fd:7c:d3:df:1e:eb:7e:3f:06:90:fb:19:0b:d3:06:02:1b: - 78:43:99:a8 ------BEGIN CERTIFICATE----- -MIIGKTCCBRGgAwIBAgIQZBvoIM4CCBPzLU0tldZ+ZzANBgkqhkiG9w0BAQUFADCB -yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL -ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp -U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW -ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 -aG9yaXR5IC0gRzUwHhcNMTAwMjA4MDAwMDAwWhcNMjAwMjA3MjM1OTU5WjCBvDEL -MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW -ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQg -aHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDE2MDQGA1UEAxMtVmVy -aVNpZ24gQ2xhc3MgMyBJbnRlcm5hdGlvbmFsIFNlcnZlciBDQSAtIEczMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmdacYvAV9IGaQQhZjxOdF8mfUdza -sVLv/+NB3eDfxCjG4615HycQmLi7IJfBKERBD+qpqFLPTU4bi7u1xHbZzFYG7rNV -ICreFY1xy1TIbxfNiQDk3P/hwB9ocenHKS5+vDv85burJlSLZpDN9pK5MSSAvJ5s -1fx+0uFLjNxC+kRLX/gYtS4w9D0SmNNiBXNUppyiHb5SgzoHRsQ7AlYhv/JRT9Cm -mTnprqU/iZucff5NYAclIPe712mDK4KTQzfZg0EbawurSmaET0qO3n40mY5o1so5 -BptMs5pITRNGtFghBMT7oE2sLktiEuP7TfbJUQABH/weaoEqOOC5T9YtRQIDAQAB -o4ICFTCCAhEwEgYDVR0TAQH/BAgwBgEB/wIBADBwBgNVHSAEaTBnMGUGC2CGSAGG -+EUBBxcDMFYwKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9j -cHMwKgYIKwYBBQUHAgIwHhocaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYTAO -BgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv -Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDov -L2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwNAYDVR0lBC0wKwYIKwYBBQUH -AwEGCCsGAQUFBwMCBglghkgBhvhCBAEGCmCGSAGG+EUBCAEwNAYIKwYBBQUHAQEE -KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC52ZXJpc2lnbi5jb20wNAYDVR0f -BC0wKzApoCegJYYjaHR0cDovL2NybC52ZXJpc2lnbi5jb20vcGNhMy1nNS5jcmww -KAYDVR0RBCEwH6QdMBsxGTAXBgNVBAMTEFZlcmlTaWduTVBLSS0yLTcwHQYDVR0O -BBYEFNebfNgioBX33a1fzimbWMO8RgC1MB8GA1UdIwQYMBaAFH/TZafC3ey78DAJ -80M5+gKvMzEzMA0GCSqGSIb3DQEBBQUAA4IBAQBxtX1zUkrd1000Ky6vlEalSVAC -T/gvF3DyE9wfIYaqwk98NzzURniuXXhv0bpavBCrWDbFjGIVRWAXIeLVQqh3oVXY -QwRR9m66SOZdTLdE0z6k1dYzmp8N5tdOlkSVWmzWoxZTDphDzqS4w2Z6BVxiEOgb -Ett9LnZQ/9/XaxvMisxx+rNAVnwzeneUW/ULU/sOX7xo+68q7jA3eRaTJX9NEP9X -+79uOzMh3nnchhdZLUNkt6Zmh+q8lkYZGoaLb9e3SQBb26O/KZru99MzrqP0nkzK -XmnUG623kHdq2FlveasB+lXwiiFm5WVu/XzT3x7rfj8GkPsZC9MGAht4Q5mo ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert58[] = { - 0x30, 0x82, 0x06, 0x29, 0x30, 0x82, 0x05, 0x11, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x64, 0x1b, 0xe8, 0x20, 0xce, 0x02, 0x08, 0x13, 0xf3, - 0x2d, 0x4d, 0x2d, 0x95, 0xd6, 0x7e, 0x67, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, - 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, - 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, - 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, - 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, - 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, - 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, - 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, - 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, - 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, - 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56, - 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, - 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, - 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30, - 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x32, 0x30, 0x38, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30, 0x32, 0x30, 0x37, - 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xbc, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, - 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56, - 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, - 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3b, 0x30, - 0x39, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x32, 0x54, 0x65, 0x72, 0x6d, - 0x73, 0x20, 0x6f, 0x66, 0x20, 0x75, 0x73, 0x65, 0x20, 0x61, 0x74, 0x20, - 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, - 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x72, 0x70, 0x61, 0x20, 0x28, 0x63, 0x29, 0x31, 0x30, 0x31, 0x36, - 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d, 0x56, 0x65, 0x72, - 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, - 0x33, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, - 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 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, 0x99, 0xd6, 0x9c, 0x62, 0xf0, 0x15, 0xf4, 0x81, 0x9a, - 0x41, 0x08, 0x59, 0x8f, 0x13, 0x9d, 0x17, 0xc9, 0x9f, 0x51, 0xdc, 0xda, - 0xb1, 0x52, 0xef, 0xff, 0xe3, 0x41, 0xdd, 0xe0, 0xdf, 0xc4, 0x28, 0xc6, - 0xe3, 0xad, 0x79, 0x1f, 0x27, 0x10, 0x98, 0xb8, 0xbb, 0x20, 0x97, 0xc1, - 0x28, 0x44, 0x41, 0x0f, 0xea, 0xa9, 0xa8, 0x52, 0xcf, 0x4d, 0x4e, 0x1b, - 0x8b, 0xbb, 0xb5, 0xc4, 0x76, 0xd9, 0xcc, 0x56, 0x06, 0xee, 0xb3, 0x55, - 0x20, 0x2a, 0xde, 0x15, 0x8d, 0x71, 0xcb, 0x54, 0xc8, 0x6f, 0x17, 0xcd, - 0x89, 0x00, 0xe4, 0xdc, 0xff, 0xe1, 0xc0, 0x1f, 0x68, 0x71, 0xe9, 0xc7, - 0x29, 0x2e, 0x7e, 0xbc, 0x3b, 0xfc, 0xe5, 0xbb, 0xab, 0x26, 0x54, 0x8b, - 0x66, 0x90, 0xcd, 0xf6, 0x92, 0xb9, 0x31, 0x24, 0x80, 0xbc, 0x9e, 0x6c, - 0xd5, 0xfc, 0x7e, 0xd2, 0xe1, 0x4b, 0x8c, 0xdc, 0x42, 0xfa, 0x44, 0x4b, - 0x5f, 0xf8, 0x18, 0xb5, 0x2e, 0x30, 0xf4, 0x3d, 0x12, 0x98, 0xd3, 0x62, - 0x05, 0x73, 0x54, 0xa6, 0x9c, 0xa2, 0x1d, 0xbe, 0x52, 0x83, 0x3a, 0x07, - 0x46, 0xc4, 0x3b, 0x02, 0x56, 0x21, 0xbf, 0xf2, 0x51, 0x4f, 0xd0, 0xa6, - 0x99, 0x39, 0xe9, 0xae, 0xa5, 0x3f, 0x89, 0x9b, 0x9c, 0x7d, 0xfe, 0x4d, - 0x60, 0x07, 0x25, 0x20, 0xf7, 0xbb, 0xd7, 0x69, 0x83, 0x2b, 0x82, 0x93, - 0x43, 0x37, 0xd9, 0x83, 0x41, 0x1b, 0x6b, 0x0b, 0xab, 0x4a, 0x66, 0x84, - 0x4f, 0x4a, 0x8e, 0xde, 0x7e, 0x34, 0x99, 0x8e, 0x68, 0xd6, 0xca, 0x39, - 0x06, 0x9b, 0x4c, 0xb3, 0x9a, 0x48, 0x4d, 0x13, 0x46, 0xb4, 0x58, 0x21, - 0x04, 0xc4, 0xfb, 0xa0, 0x4d, 0xac, 0x2e, 0x4b, 0x62, 0x12, 0xe3, 0xfb, - 0x4d, 0xf6, 0xc9, 0x51, 0x00, 0x01, 0x1f, 0xfc, 0x1e, 0x6a, 0x81, 0x2a, - 0x38, 0xe0, 0xb9, 0x4f, 0xd6, 0x2d, 0x45, 0x02, 0x03, 0x01, 0x00, 0x01, - 0xa3, 0x82, 0x02, 0x15, 0x30, 0x82, 0x02, 0x11, 0x30, 0x12, 0x06, 0x03, - 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, - 0xff, 0x02, 0x01, 0x00, 0x30, 0x70, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, - 0x69, 0x30, 0x67, 0x30, 0x65, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, 0x86, - 0xf8, 0x45, 0x01, 0x07, 0x17, 0x03, 0x30, 0x56, 0x30, 0x28, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, - 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, - 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, - 0x70, 0x73, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x02, 0x02, 0x30, 0x1e, 0x1a, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, - 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, - 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x70, 0x61, 0x30, 0x0e, - 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, - 0x01, 0x06, 0x30, 0x6d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f, 0xa1, 0x5d, 0xa0, 0x5b, 0x30, 0x59, - 0x30, 0x57, 0x30, 0x55, 0x16, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, - 0x67, 0x69, 0x66, 0x30, 0x21, 0x30, 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, - 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, 0x8f, 0xe5, 0xd3, 0x1a, 0x86, 0xac, - 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80, 0x6a, 0xd4, 0x48, 0x18, 0x2c, 0x7b, - 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, - 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x76, 0x73, 0x6c, 0x6f, 0x67, - 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30, 0x34, 0x06, 0x03, 0x55, 0x1d, 0x25, - 0x04, 0x2d, 0x30, 0x2b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, - 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01, 0x06, - 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x08, 0x01, 0x30, - 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, - 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, - 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x34, 0x06, 0x03, 0x55, 0x1d, 0x1f, - 0x04, 0x2d, 0x30, 0x2b, 0x30, 0x29, 0xa0, 0x27, 0xa0, 0x25, 0x86, 0x23, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76, - 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x70, 0x63, 0x61, 0x33, 0x2d, 0x67, 0x35, 0x2e, 0x63, 0x72, 0x6c, 0x30, - 0x28, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x21, 0x30, 0x1f, 0xa4, 0x1d, - 0x30, 0x1b, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, - 0x10, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, - 0x49, 0x2d, 0x32, 0x2d, 0x37, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, - 0x04, 0x16, 0x04, 0x14, 0xd7, 0x9b, 0x7c, 0xd8, 0x22, 0xa0, 0x15, 0xf7, - 0xdd, 0xad, 0x5f, 0xce, 0x29, 0x9b, 0x58, 0xc3, 0xbc, 0x46, 0x00, 0xb5, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, - 0x14, 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, - 0xf3, 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, - 0x03, 0x82, 0x01, 0x01, 0x00, 0x71, 0xb5, 0x7d, 0x73, 0x52, 0x4a, 0xdd, - 0xd7, 0x4d, 0x34, 0x2b, 0x2e, 0xaf, 0x94, 0x46, 0xa5, 0x49, 0x50, 0x02, - 0x4f, 0xf8, 0x2f, 0x17, 0x70, 0xf2, 0x13, 0xdc, 0x1f, 0x21, 0x86, 0xaa, - 0xc2, 0x4f, 0x7c, 0x37, 0x3c, 0xd4, 0x46, 0x78, 0xae, 0x5d, 0x78, 0x6f, - 0xd1, 0xba, 0x5a, 0xbc, 0x10, 0xab, 0x58, 0x36, 0xc5, 0x8c, 0x62, 0x15, - 0x45, 0x60, 0x17, 0x21, 0xe2, 0xd5, 0x42, 0xa8, 0x77, 0xa1, 0x55, 0xd8, - 0x43, 0x04, 0x51, 0xf6, 0x6e, 0xba, 0x48, 0xe6, 0x5d, 0x4c, 0xb7, 0x44, - 0xd3, 0x3e, 0xa4, 0xd5, 0xd6, 0x33, 0x9a, 0x9f, 0x0d, 0xe6, 0xd7, 0x4e, - 0x96, 0x44, 0x95, 0x5a, 0x6c, 0xd6, 0xa3, 0x16, 0x53, 0x0e, 0x98, 0x43, - 0xce, 0xa4, 0xb8, 0xc3, 0x66, 0x7a, 0x05, 0x5c, 0x62, 0x10, 0xe8, 0x1b, - 0x12, 0xdb, 0x7d, 0x2e, 0x76, 0x50, 0xff, 0xdf, 0xd7, 0x6b, 0x1b, 0xcc, - 0x8a, 0xcc, 0x71, 0xfa, 0xb3, 0x40, 0x56, 0x7c, 0x33, 0x7a, 0x77, 0x94, - 0x5b, 0xf5, 0x0b, 0x53, 0xfb, 0x0e, 0x5f, 0xbc, 0x68, 0xfb, 0xaf, 0x2a, - 0xee, 0x30, 0x37, 0x79, 0x16, 0x93, 0x25, 0x7f, 0x4d, 0x10, 0xff, 0x57, - 0xfb, 0xbf, 0x6e, 0x3b, 0x33, 0x21, 0xde, 0x79, 0xdc, 0x86, 0x17, 0x59, - 0x2d, 0x43, 0x64, 0xb7, 0xa6, 0x66, 0x87, 0xea, 0xbc, 0x96, 0x46, 0x19, - 0x1a, 0x86, 0x8b, 0x6f, 0xd7, 0xb7, 0x49, 0x00, 0x5b, 0xdb, 0xa3, 0xbf, - 0x29, 0x9a, 0xee, 0xf7, 0xd3, 0x33, 0xae, 0xa3, 0xf4, 0x9e, 0x4c, 0xca, - 0x5e, 0x69, 0xd4, 0x1b, 0xad, 0xb7, 0x90, 0x77, 0x6a, 0xd8, 0x59, 0x6f, - 0x79, 0xab, 0x01, 0xfa, 0x55, 0xf0, 0x8a, 0x21, 0x66, 0xe5, 0x65, 0x6e, - 0xfd, 0x7c, 0xd3, 0xdf, 0x1e, 0xeb, 0x7e, 0x3f, 0x06, 0x90, 0xfb, 0x19, - 0x0b, 0xd3, 0x06, 0x02, 0x1b, 0x78, 0x43, 0x99, 0xa8, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 0a:5f:11:4d:03:5b:17:91:17:d2:ef:d4:03:8c:3f:3b - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA - Validity - Not Before: Apr 2 12:00:00 2008 GMT - Not After : Apr 3 00:00:00 2022 GMT - Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance CA-3 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:bf:61:0a:29:10:1f:5e:fe:34:37:51:08:f8:1e: - fb:22:ed:61:be:0b:0d:70:4c:50:63:26:75:15:b9: - 41:88:97:b6:f0:a0:15:bb:08:60:e0:42:e8:05:29: - 10:87:36:8a:28:65:a8:ef:31:07:74:6d:36:97:2f: - 28:46:66:04:c7:2a:79:26:7a:99:d5:8e:c3:6d:4f: - a0:5e:ad:bc:3d:91:c2:59:7b:5e:36:6c:c0:53:cf: - 00:08:32:3e:10:64:58:10:13:69:c7:0c:ee:9c:42: - 51:00:f9:05:44:ee:24:ce:7a:1f:ed:8c:11:bd:12: - a8:f3:15:f4:1c:7a:31:69:01:1b:a7:e6:5d:c0:9a: - 6c:7e:09:9e:e7:52:44:4a:10:3a:23:e4:9b:b6:03: - af:a8:9c:b4:5b:9f:d4:4b:ad:92:8c:ce:b5:11:2a: - aa:37:18:8d:b4:c2:b8:d8:5c:06:8c:f8:ff:23:bd: - 35:5e:d4:7c:3e:7e:83:0e:91:96:05:98:c3:b2:1f: - e3:c8:65:eb:a9:7b:5d:a0:2c:cc:fc:3c:d9:6d:ed: - cc:fa:4b:43:8c:c9:d4:b8:a5:61:1c:b2:40:b6:28: - 12:df:b9:f8:5f:fe:d3:b2:c9:ef:3d:b4:1e:4b:7c: - 1c:4c:99:36:9e:3d:eb:ec:a7:68:5e:1d:df:67:6e: - 5e:fb - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Key Usage: critical - Digital Signature, Certificate Sign, CRL Sign - X509v3 Certificate Policies: - Policy: 2.16.840.1.114412.1.3.0.2 - CPS: http://www.digicert.com/ssl-cps-repository.htm - User Notice: - Explicit Text: - - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - Authority Information Access: - OCSP - URI:http://ocsp.digicert.com - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl3.digicert.com/DigiCertHighAssuranceEVRootCA.crl - - Full Name: - URI:http://crl4.digicert.com/DigiCertHighAssuranceEVRootCA.crl - - X509v3 Authority Key Identifier: - keyid:B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3 - - X509v3 Subject Key Identifier: - 50:EA:73:89:DB:29:FB:10:8F:9E:E5:01:20:D4:DE:79:99:48:83:F7 - Signature Algorithm: sha1WithRSAEncryption - 1e:e2:a5:48:9e:6c:db:53:38:0f:ef:a6:1a:2a:ac:e2:03:43: - ed:9a:bc:3e:8e:75:1b:f0:fd:2e:22:59:ac:13:c0:61:e2:e7: - fa:e9:99:cd:87:09:75:54:28:bf:46:60:dc:be:51:2c:92:f3: - 1b:91:7c:31:08:70:e2:37:b9:c1:5b:a8:bd:a3:0b:00:fb:1a: - 15:fd:03:ad:58:6a:c5:c7:24:99:48:47:46:31:1e:92:ef:b4: - 5f:4e:34:c7:90:bf:31:c1:f8:b1:84:86:d0:9c:01:aa:df:8a: - 56:06:ce:3a:e9:0e:ae:97:74:5d:d7:71:9a:42:74:5f:de:8d: - 43:7c:de:e9:55:ed:69:00:cb:05:e0:7a:61:61:33:d1:19:4d: - f9:08:ee:a0:39:c5:25:35:b7:2b:c4:0f:b2:dd:f1:a5:b7:0e: - 24:c4:26:28:8d:79:77:f5:2f:f0:57:ba:7c:07:d4:e1:fc:cd: - 5a:30:57:7e:86:10:47:dd:31:1f:d7:fc:a2:c2:bf:30:7c:5d: - 24:aa:e8:f9:ae:5f:6a:74:c2:ce:6b:b3:46:d8:21:be:29:d4: - 8e:5e:15:d6:42:4a:e7:32:6f:a4:b1:6b:51:83:58:be:3f:6d: - c7:fb:da:03:21:cb:6a:16:19:4e:0a:f0:ad:84:ca:5d:94:b3: - 5a:76:f7:61 ------BEGIN CERTIFICATE----- -MIIGWDCCBUCgAwIBAgIQCl8RTQNbF5EX0u/UA4w/OzANBgkqhkiG9w0BAQUFADBs -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j -ZSBFViBSb290IENBMB4XDTA4MDQwMjEyMDAwMFoXDTIyMDQwMzAwMDAwMFowZjEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 -LmRpZ2ljZXJ0LmNvbTElMCMGA1UEAxMcRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug -Q0EtMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9hCikQH17+NDdR -CPge+yLtYb4LDXBMUGMmdRW5QYiXtvCgFbsIYOBC6AUpEIc2iihlqO8xB3RtNpcv -KEZmBMcqeSZ6mdWOw21PoF6tvD2Rwll7XjZswFPPAAgyPhBkWBATaccM7pxCUQD5 -BUTuJM56H+2MEb0SqPMV9Bx6MWkBG6fmXcCabH4JnudSREoQOiPkm7YDr6ictFuf -1EutkozOtREqqjcYjbTCuNhcBoz4/yO9NV7UfD5+gw6RlgWYw7If48hl66l7XaAs -zPw82W3tzPpLQ4zJ1LilYRyyQLYoEt+5+F/+07LJ7z20Hkt8HEyZNp496+ynaF4d -32duXvsCAwEAAaOCAvowggL2MA4GA1UdDwEB/wQEAwIBhjCCAcYGA1UdIASCAb0w -ggG5MIIBtQYLYIZIAYb9bAEDAAIwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3 -LmRpZ2ljZXJ0LmNvbS9zc2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUH -AgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQBy -AHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBj -AGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAg -AEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQ -AGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBt -AGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBj -AG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBl -AHIAZQBuAGMAZQAuMBIGA1UdEwEB/wQIMAYBAf8CAQAwNAYIKwYBBQUHAQEEKDAm -MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wgY8GA1UdHwSB -hzCBhDBAoD6gPIY6aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0SGln -aEFzc3VyYW5jZUVWUm9vdENBLmNybDBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNl -cnQuY29tL0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDAfBgNVHSME -GDAWgBSxPsNpA/i/RwHUmCYaCALvY2QrwzAdBgNVHQ4EFgQUUOpzidsp+xCPnuUB -INTeeZlIg/cwDQYJKoZIhvcNAQEFBQADggEBAB7ipUiebNtTOA/vphoqrOIDQ+2a -vD6OdRvw/S4iWawTwGHi5/rpmc2HCXVUKL9GYNy+USyS8xuRfDEIcOI3ucFbqL2j -CwD7GhX9A61YasXHJJlIR0YxHpLvtF9ONMeQvzHB+LGEhtCcAarfilYGzjrpDq6X -dF3XcZpCdF/ejUN83ulV7WkAywXgemFhM9EZTfkI7qA5xSU1tyvED7Ld8aW3DiTE -JiiNeXf1L/BXunwH1OH8zVowV36GEEfdMR/X/KLCvzB8XSSq6PmuX2p0ws5rs0bY -Ib4p1I5eFdZCSucyb6Sxa1GDWL4/bcf72gMhy2oWGU4K8K2Eyl2Us1p292E= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert59[] = { - 0x30, 0x82, 0x06, 0x58, 0x30, 0x82, 0x05, 0x40, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x0a, 0x5f, 0x11, 0x4d, 0x03, 0x5b, 0x17, 0x91, 0x17, - 0xd2, 0xef, 0xd4, 0x03, 0x8c, 0x3f, 0x3b, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x6c, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, - 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, - 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, - 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, - 0x63, 0x6f, 0x6d, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48, - 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, - 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, - 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x38, 0x30, 0x34, 0x30, 0x32, 0x31, 0x32, - 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x32, 0x30, 0x34, 0x30, - 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x66, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44, 0x69, - 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x19, - 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, 0x77, 0x77, - 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, - 0x6d, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1c, - 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48, 0x69, 0x67, - 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x20, - 0x43, 0x41, 0x2d, 0x33, 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, 0xbf, 0x61, 0x0a, 0x29, 0x10, 0x1f, 0x5e, 0xfe, 0x34, 0x37, 0x51, - 0x08, 0xf8, 0x1e, 0xfb, 0x22, 0xed, 0x61, 0xbe, 0x0b, 0x0d, 0x70, 0x4c, - 0x50, 0x63, 0x26, 0x75, 0x15, 0xb9, 0x41, 0x88, 0x97, 0xb6, 0xf0, 0xa0, - 0x15, 0xbb, 0x08, 0x60, 0xe0, 0x42, 0xe8, 0x05, 0x29, 0x10, 0x87, 0x36, - 0x8a, 0x28, 0x65, 0xa8, 0xef, 0x31, 0x07, 0x74, 0x6d, 0x36, 0x97, 0x2f, - 0x28, 0x46, 0x66, 0x04, 0xc7, 0x2a, 0x79, 0x26, 0x7a, 0x99, 0xd5, 0x8e, - 0xc3, 0x6d, 0x4f, 0xa0, 0x5e, 0xad, 0xbc, 0x3d, 0x91, 0xc2, 0x59, 0x7b, - 0x5e, 0x36, 0x6c, 0xc0, 0x53, 0xcf, 0x00, 0x08, 0x32, 0x3e, 0x10, 0x64, - 0x58, 0x10, 0x13, 0x69, 0xc7, 0x0c, 0xee, 0x9c, 0x42, 0x51, 0x00, 0xf9, - 0x05, 0x44, 0xee, 0x24, 0xce, 0x7a, 0x1f, 0xed, 0x8c, 0x11, 0xbd, 0x12, - 0xa8, 0xf3, 0x15, 0xf4, 0x1c, 0x7a, 0x31, 0x69, 0x01, 0x1b, 0xa7, 0xe6, - 0x5d, 0xc0, 0x9a, 0x6c, 0x7e, 0x09, 0x9e, 0xe7, 0x52, 0x44, 0x4a, 0x10, - 0x3a, 0x23, 0xe4, 0x9b, 0xb6, 0x03, 0xaf, 0xa8, 0x9c, 0xb4, 0x5b, 0x9f, - 0xd4, 0x4b, 0xad, 0x92, 0x8c, 0xce, 0xb5, 0x11, 0x2a, 0xaa, 0x37, 0x18, - 0x8d, 0xb4, 0xc2, 0xb8, 0xd8, 0x5c, 0x06, 0x8c, 0xf8, 0xff, 0x23, 0xbd, - 0x35, 0x5e, 0xd4, 0x7c, 0x3e, 0x7e, 0x83, 0x0e, 0x91, 0x96, 0x05, 0x98, - 0xc3, 0xb2, 0x1f, 0xe3, 0xc8, 0x65, 0xeb, 0xa9, 0x7b, 0x5d, 0xa0, 0x2c, - 0xcc, 0xfc, 0x3c, 0xd9, 0x6d, 0xed, 0xcc, 0xfa, 0x4b, 0x43, 0x8c, 0xc9, - 0xd4, 0xb8, 0xa5, 0x61, 0x1c, 0xb2, 0x40, 0xb6, 0x28, 0x12, 0xdf, 0xb9, - 0xf8, 0x5f, 0xfe, 0xd3, 0xb2, 0xc9, 0xef, 0x3d, 0xb4, 0x1e, 0x4b, 0x7c, - 0x1c, 0x4c, 0x99, 0x36, 0x9e, 0x3d, 0xeb, 0xec, 0xa7, 0x68, 0x5e, 0x1d, - 0xdf, 0x67, 0x6e, 0x5e, 0xfb, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, - 0x02, 0xfa, 0x30, 0x82, 0x02, 0xf6, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, - 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x82, - 0x01, 0xc6, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x82, 0x01, 0xbd, 0x30, - 0x82, 0x01, 0xb9, 0x30, 0x82, 0x01, 0xb5, 0x06, 0x0b, 0x60, 0x86, 0x48, - 0x01, 0x86, 0xfd, 0x6c, 0x01, 0x03, 0x00, 0x02, 0x30, 0x82, 0x01, 0xa4, - 0x30, 0x3a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, - 0x16, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x73, 0x73, 0x6c, 0x2d, 0x63, 0x70, 0x73, 0x2d, 0x72, 0x65, - 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x68, 0x74, 0x6d, - 0x30, 0x82, 0x01, 0x64, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x02, 0x02, 0x30, 0x82, 0x01, 0x56, 0x1e, 0x82, 0x01, 0x52, 0x00, 0x41, - 0x00, 0x6e, 0x00, 0x79, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00, 0x65, - 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, - 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, 0x00, 0x43, 0x00, 0x65, 0x00, 0x72, - 0x00, 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61, - 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e, - 0x00, 0x73, 0x00, 0x74, 0x00, 0x69, 0x00, 0x74, 0x00, 0x75, 0x00, 0x74, - 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, 0x00, 0x63, 0x00, 0x63, - 0x00, 0x65, 0x00, 0x70, 0x00, 0x74, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x63, - 0x00, 0x65, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x74, - 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x44, 0x00, 0x69, 0x00, 0x67, - 0x00, 0x69, 0x00, 0x43, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74, 0x00, 0x20, - 0x00, 0x43, 0x00, 0x50, 0x00, 0x2f, 0x00, 0x43, 0x00, 0x50, 0x00, 0x53, - 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x74, - 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x52, 0x00, 0x65, 0x00, 0x6c, - 0x00, 0x79, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x20, 0x00, 0x50, - 0x00, 0x61, 0x00, 0x72, 0x00, 0x74, 0x00, 0x79, 0x00, 0x20, 0x00, 0x41, - 0x00, 0x67, 0x00, 0x72, 0x00, 0x65, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, - 0x00, 0x6e, 0x00, 0x74, 0x00, 0x20, 0x00, 0x77, 0x00, 0x68, 0x00, 0x69, - 0x00, 0x63, 0x00, 0x68, 0x00, 0x20, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x6d, - 0x00, 0x69, 0x00, 0x74, 0x00, 0x20, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x61, - 0x00, 0x62, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x74, 0x00, 0x79, - 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x61, - 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x63, - 0x00, 0x6f, 0x00, 0x72, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x61, - 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x68, 0x00, 0x65, - 0x00, 0x72, 0x00, 0x65, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x62, - 0x00, 0x79, 0x00, 0x20, 0x00, 0x72, 0x00, 0x65, 0x00, 0x66, 0x00, 0x65, - 0x00, 0x72, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x65, 0x00, 0x2e, - 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, - 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x34, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, - 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, - 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, - 0x70, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, - 0x6f, 0x6d, 0x30, 0x81, 0x8f, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x81, - 0x87, 0x30, 0x81, 0x84, 0x30, 0x40, 0xa0, 0x3e, 0xa0, 0x3c, 0x86, 0x3a, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x33, 0x2e, - 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x48, 0x69, 0x67, - 0x68, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x56, - 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x40, - 0xa0, 0x3e, 0xa0, 0x3c, 0x86, 0x3a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, - 0x2f, 0x63, 0x72, 0x6c, 0x34, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, - 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, - 0x65, 0x72, 0x74, 0x48, 0x69, 0x67, 0x68, 0x41, 0x73, 0x73, 0x75, 0x72, - 0x61, 0x6e, 0x63, 0x65, 0x45, 0x56, 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, - 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, - 0x18, 0x30, 0x16, 0x80, 0x14, 0xb1, 0x3e, 0xc3, 0x69, 0x03, 0xf8, 0xbf, - 0x47, 0x01, 0xd4, 0x98, 0x26, 0x1a, 0x08, 0x02, 0xef, 0x63, 0x64, 0x2b, - 0xc3, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, - 0x50, 0xea, 0x73, 0x89, 0xdb, 0x29, 0xfb, 0x10, 0x8f, 0x9e, 0xe5, 0x01, - 0x20, 0xd4, 0xde, 0x79, 0x99, 0x48, 0x83, 0xf7, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, - 0x82, 0x01, 0x01, 0x00, 0x1e, 0xe2, 0xa5, 0x48, 0x9e, 0x6c, 0xdb, 0x53, - 0x38, 0x0f, 0xef, 0xa6, 0x1a, 0x2a, 0xac, 0xe2, 0x03, 0x43, 0xed, 0x9a, - 0xbc, 0x3e, 0x8e, 0x75, 0x1b, 0xf0, 0xfd, 0x2e, 0x22, 0x59, 0xac, 0x13, - 0xc0, 0x61, 0xe2, 0xe7, 0xfa, 0xe9, 0x99, 0xcd, 0x87, 0x09, 0x75, 0x54, - 0x28, 0xbf, 0x46, 0x60, 0xdc, 0xbe, 0x51, 0x2c, 0x92, 0xf3, 0x1b, 0x91, - 0x7c, 0x31, 0x08, 0x70, 0xe2, 0x37, 0xb9, 0xc1, 0x5b, 0xa8, 0xbd, 0xa3, - 0x0b, 0x00, 0xfb, 0x1a, 0x15, 0xfd, 0x03, 0xad, 0x58, 0x6a, 0xc5, 0xc7, - 0x24, 0x99, 0x48, 0x47, 0x46, 0x31, 0x1e, 0x92, 0xef, 0xb4, 0x5f, 0x4e, - 0x34, 0xc7, 0x90, 0xbf, 0x31, 0xc1, 0xf8, 0xb1, 0x84, 0x86, 0xd0, 0x9c, - 0x01, 0xaa, 0xdf, 0x8a, 0x56, 0x06, 0xce, 0x3a, 0xe9, 0x0e, 0xae, 0x97, - 0x74, 0x5d, 0xd7, 0x71, 0x9a, 0x42, 0x74, 0x5f, 0xde, 0x8d, 0x43, 0x7c, - 0xde, 0xe9, 0x55, 0xed, 0x69, 0x00, 0xcb, 0x05, 0xe0, 0x7a, 0x61, 0x61, - 0x33, 0xd1, 0x19, 0x4d, 0xf9, 0x08, 0xee, 0xa0, 0x39, 0xc5, 0x25, 0x35, - 0xb7, 0x2b, 0xc4, 0x0f, 0xb2, 0xdd, 0xf1, 0xa5, 0xb7, 0x0e, 0x24, 0xc4, - 0x26, 0x28, 0x8d, 0x79, 0x77, 0xf5, 0x2f, 0xf0, 0x57, 0xba, 0x7c, 0x07, - 0xd4, 0xe1, 0xfc, 0xcd, 0x5a, 0x30, 0x57, 0x7e, 0x86, 0x10, 0x47, 0xdd, - 0x31, 0x1f, 0xd7, 0xfc, 0xa2, 0xc2, 0xbf, 0x30, 0x7c, 0x5d, 0x24, 0xaa, - 0xe8, 0xf9, 0xae, 0x5f, 0x6a, 0x74, 0xc2, 0xce, 0x6b, 0xb3, 0x46, 0xd8, - 0x21, 0xbe, 0x29, 0xd4, 0x8e, 0x5e, 0x15, 0xd6, 0x42, 0x4a, 0xe7, 0x32, - 0x6f, 0xa4, 0xb1, 0x6b, 0x51, 0x83, 0x58, 0xbe, 0x3f, 0x6d, 0xc7, 0xfb, - 0xda, 0x03, 0x21, 0xcb, 0x6a, 0x16, 0x19, 0x4e, 0x0a, 0xf0, 0xad, 0x84, - 0xca, 0x5d, 0x94, 0xb3, 0x5a, 0x76, 0xf7, 0x61, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 14365921339544682215 (0xc75e01582ac3bee7) - Signature Algorithm: sha256WithRSAEncryption - Issuer: C=DE, O=Deutsche Telekom AG, OU=T-TeleSec Trust Center, CN=Deutsche Telekom Root CA 2 - Validity - Not Before: Feb 11 14:30:17 2014 GMT - Not After : Jul 9 23:59:00 2019 GMT - Subject: C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen/postalCode=57250, L=Netphen/street=Untere Industriestr. 20, CN=TeleSec ServerPass DE-2 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:c1:d6:c7:60:bd:8e:ff:b3:4d:ad:28:cd:4e:d4: - 63:18:a0:55:81:68:8e:89:8d:15:78:2a:af:21:90: - 48:00:01:96:ef:74:c0:92:ae:d9:6f:64:53:98:9f: - e7:5d:8d:ab:28:99:71:7a:e0:2b:e5:75:83:30:4d: - 83:95:58:7d:63:38:e8:61:24:0b:8f:ad:0e:95:ae: - 22:5b:80:13:1b:d6:e6:a4:d0:cb:20:07:55:57:1c: - e7:8d:fb:42:90:28:ea:7d:0f:da:5e:7f:b4:9d:db: - de:61:ab:f9:03:52:73:30:7b:33:e7:ea:06:57:a1: - 56:ef:06:25:85:38:d5:ca:7f:61:e4:f8:8b:5d:56: - 3e:76:53:74:0a:23:77:d4:b5:f3:72:4c:4e:d4:0c: - 96:0a:02:53:65:92:07:78:19:a1:a0:9c:13:91:f1: - ae:85:f4:a8:e1:80:bb:0a:42:ec:bc:6f:4d:3e:ed: - 09:86:46:f0:0e:df:ee:ae:b9:aa:d4:41:c8:81:1b: - b2:bf:bb:13:7c:61:bf:0d:95:d0:9f:c2:f6:dd:6a: - 40:9b:4a:6a:fd:f9:92:7e:e6:f7:a9:d5:0b:61:e2: - bd:e2:6b:d1:1d:c5:28:f5:96:db:d4:74:af:29:50: - c3:e5:f1:1f:9c:86:5b:c9:8b:de:6c:76:8f:89:74: - a3:ef - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Key Usage: critical - Certificate Sign, CRL Sign - X509v3 Subject Key Identifier: - 54:04:29:6F:A2:93:C6:90:31:45:C0:3D:DE:2B:E2:0A:69:80:92:5F - X509v3 Authority Key Identifier: - keyid:31:C3:79:1B:BA:F5:53:D7:17:E0:89:7A:2D:17:6C:0A:B3:2B:9D:33 - - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - X509v3 Certificate Policies: - Policy: 1.3.6.1.4.1.7879.13.2 - CPS: http://www.telesec.de/serverpass/cps.html - Policy: 2.23.140.1.2.2 - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl.serverpass.telesec.de/rl/DT_ROOT_CA_2.crl - - Full Name: - URI:ldap://ldap.serverpass.telesec.de/CN=Deutsche%20Telekom%20Root%20CA%202,OU=T-TeleSec%20Trust%20Center,O=Deutsche%20Telekom%20AG,C=DE?AuthorityRevocationList - - Authority Information Access: - OCSP - URI:http://ocsp02.telesec.de/ocspr - CA Issuers - URI:http://crl.serverpass.telesec.de/crt/DT_ROOT_CA_2.cer - CA Issuers - URI:ldap://ldap.serverpass.telesec.de/CN=Deutsche%20Telekom%20Root%20CA%202,OU=T-TeleSec%20Trust%20Center,O=Deutsche%20Telekom%20AG,C=DE?cACertificate - - Signature Algorithm: sha256WithRSAEncryption - 2c:6c:cc:30:8e:5a:d4:38:ce:3f:d4:a3:37:db:fe:c8:ba:4a: - ce:6d:aa:07:e8:4a:54:39:b5:36:a7:dc:57:e8:b0:ab:ee:0c: - c0:08:bf:ab:94:0e:88:97:78:9a:d2:fe:b3:cb:88:a9:03:68: - 17:3f:46:7d:65:cc:a2:36:9a:65:b3:ad:4d:79:62:c1:86:4d: - a1:bb:ac:84:65:63:bb:ea:a1:71:28:c7:ab:04:59:9c:53:72: - 5c:8f:f2:6f:df:77:c7:d9:a4:93:07:d9:4e:86:b9:36:af:5c: - 9f:c0:2b:ff:fd:7c:cc:ee:bc:68:10:b1:0b:32:c7:0b:3d:b6: - 6e:10:09:dd:e8:49:57:7f:75:a5:1b:1d:0f:ba:04:80:51:3f: - 2c:8c:e7:94:b5:0d:00:c7:e9:5e:3e:b4:b1:59:7e:26:70:72: - 36:69:27:2d:85:b2:d7:7a:53:ad:0f:d2:0a:89:59:04:29:65: - 41:11:e2:75:d3:6c:09:bc:00:7d:46:df:17:b7:e2:51:68:36: - 04:be:96:1b:82:b8:a2:ac:3c:9e:3d:3e:18:47:59:50:33:95: - 01:6a:7e:89:75:b3:d0:62:b3:b1:17:2d:ea:03:ca:12:6b:bd: - 38:d2:a8:f6:97:f3:b3:da:2a:dd:16:d3:e3:7b:87:f7:e9:36: - 07:0c:7e:11 ------BEGIN CERTIFICATE----- -MIIGrDCCBZSgAwIBAgIJAMdeAVgqw77nMA0GCSqGSIb3DQEBCwUAMHExCzAJBgNV -BAYTAkRFMRwwGgYDVQQKExNEZXV0c2NoZSBUZWxla29tIEFHMR8wHQYDVQQLExZU -LVRlbGVTZWMgVHJ1c3QgQ2VudGVyMSMwIQYDVQQDExpEZXV0c2NoZSBUZWxla29t -IFJvb3QgQ0EgMjAeFw0xNDAyMTExNDMwMTdaFw0xOTA3MDkyMzU5MDBaMIHZMQsw -CQYDVQQGEwJERTElMCMGA1UEChMcVC1TeXN0ZW1zIEludGVybmF0aW9uYWwgR21i -SDEfMB0GA1UECxMWVC1TeXN0ZW1zIFRydXN0IENlbnRlcjEcMBoGA1UECBMTTm9y -ZHJoZWluIFdlc3RmYWxlbjEOMAwGA1UEERMFNTcyNTAxEDAOBgNVBAcTB05ldHBo -ZW4xIDAeBgNVBAkTF1VudGVyZSBJbmR1c3RyaWVzdHIuIDIwMSAwHgYDVQQDExdU -ZWxlU2VjIFNlcnZlclBhc3MgREUtMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBAMHWx2C9jv+zTa0ozU7UYxigVYFojomNFXgqryGQSAABlu90wJKu2W9k -U5if512NqyiZcXrgK+V1gzBNg5VYfWM46GEkC4+tDpWuIluAExvW5qTQyyAHVVcc -5437QpAo6n0P2l5/tJ3b3mGr+QNSczB7M+fqBlehVu8GJYU41cp/YeT4i11WPnZT -dAojd9S183JMTtQMlgoCU2WSB3gZoaCcE5HxroX0qOGAuwpC7LxvTT7tCYZG8A7f -7q65qtRByIEbsr+7E3xhvw2V0J/C9t1qQJtKav35kn7m96nVC2HiveJr0R3FKPWW -29R0rylQw+XxH5yGW8mL3mx2j4l0o+8CAwEAAaOCAtwwggLYMA4GA1UdDwEB/wQE -AwIBBjAdBgNVHQ4EFgQUVAQpb6KTxpAxRcA93iviCmmAkl8wHwYDVR0jBBgwFoAU -McN5G7r1U9cX4Il6LRdsCrMrnTMwEgYDVR0TAQH/BAgwBgEB/wIBADBZBgNVHSAE -UjBQMEQGCSsGAQQBvUcNAjA3MDUGCCsGAQUFBwIBFilodHRwOi8vd3d3LnRlbGVz -ZWMuZGUvc2VydmVycGFzcy9jcHMuaHRtbDAIBgZngQwBAgIwge8GA1UdHwSB5zCB -5DA6oDigNoY0aHR0cDovL2NybC5zZXJ2ZXJwYXNzLnRlbGVzZWMuZGUvcmwvRFRf -Uk9PVF9DQV8yLmNybDCBpaCBoqCBn4aBnGxkYXA6Ly9sZGFwLnNlcnZlcnBhc3Mu -dGVsZXNlYy5kZS9DTj1EZXV0c2NoZSUyMFRlbGVrb20lMjBSb290JTIwQ0ElMjAy -LE9VPVQtVGVsZVNlYyUyMFRydXN0JTIwQ2VudGVyLE89RGV1dHNjaGUlMjBUZWxl -a29tJTIwQUcsQz1ERT9BdXRob3JpdHlSZXZvY2F0aW9uTGlzdDCCASMGCCsGAQUF -BwEBBIIBFTCCAREwKgYIKwYBBQUHMAGGHmh0dHA6Ly9vY3NwMDIudGVsZXNlYy5k -ZS9vY3NwcjBBBggrBgEFBQcwAoY1aHR0cDovL2NybC5zZXJ2ZXJwYXNzLnRlbGVz -ZWMuZGUvY3J0L0RUX1JPT1RfQ0FfMi5jZXIwgZ8GCCsGAQUFBzAChoGSbGRhcDov -L2xkYXAuc2VydmVycGFzcy50ZWxlc2VjLmRlL0NOPURldXRzY2hlJTIwVGVsZWtv -bSUyMFJvb3QlMjBDQSUyMDIsT1U9VC1UZWxlU2VjJTIwVHJ1c3QlMjBDZW50ZXIs -Tz1EZXV0c2NoZSUyMFRlbGVrb20lMjBBRyxDPURFP2NBQ2VydGlmaWNhdGUwDQYJ -KoZIhvcNAQELBQADggEBACxszDCOWtQ4zj/Uozfb/si6Ss5tqgfoSlQ5tTan3Ffo -sKvuDMAIv6uUDoiXeJrS/rPLiKkDaBc/Rn1lzKI2mmWzrU15YsGGTaG7rIRlY7vq -oXEox6sEWZxTclyP8m/fd8fZpJMH2U6GuTavXJ/AK//9fMzuvGgQsQsyxws9tm4Q -Cd3oSVd/daUbHQ+6BIBRPyyM55S1DQDH6V4+tLFZfiZwcjZpJy2Fstd6U60P0gqJ -WQQpZUER4nXTbAm8AH1G3xe34lFoNgS+lhuCuKKsPJ49PhhHWVAzlQFqfol1s9Bi -s7EXLeoDyhJrvTjSqPaX87PaKt0W0+N7h/fpNgcMfhE= ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert60[] = { - 0x30, 0x82, 0x06, 0xac, 0x30, 0x82, 0x05, 0x94, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x09, 0x00, 0xc7, 0x5e, 0x01, 0x58, 0x2a, 0xc3, 0xbe, 0xe7, - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x0b, 0x05, 0x00, 0x30, 0x71, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x06, 0x13, 0x02, 0x44, 0x45, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x13, 0x13, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, - 0x65, 0x20, 0x54, 0x65, 0x6c, 0x65, 0x6b, 0x6f, 0x6d, 0x20, 0x41, 0x47, - 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x54, - 0x2d, 0x54, 0x65, 0x6c, 0x65, 0x53, 0x65, 0x63, 0x20, 0x54, 0x72, 0x75, - 0x73, 0x74, 0x20, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x31, 0x23, 0x30, - 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x44, 0x65, 0x75, 0x74, - 0x73, 0x63, 0x68, 0x65, 0x20, 0x54, 0x65, 0x6c, 0x65, 0x6b, 0x6f, 0x6d, - 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20, 0x32, 0x30, 0x1e, - 0x17, 0x0d, 0x31, 0x34, 0x30, 0x32, 0x31, 0x31, 0x31, 0x34, 0x33, 0x30, - 0x31, 0x37, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x37, 0x30, 0x39, 0x32, - 0x33, 0x35, 0x39, 0x30, 0x30, 0x5a, 0x30, 0x81, 0xd9, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x44, 0x45, 0x31, 0x25, - 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x54, 0x2d, 0x53, - 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x47, 0x6d, 0x62, - 0x48, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, - 0x54, 0x2d, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x20, 0x54, 0x72, - 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x31, 0x1c, - 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x13, 0x4e, 0x6f, 0x72, - 0x64, 0x72, 0x68, 0x65, 0x69, 0x6e, 0x20, 0x57, 0x65, 0x73, 0x74, 0x66, - 0x61, 0x6c, 0x65, 0x6e, 0x31, 0x0e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x04, - 0x11, 0x13, 0x05, 0x35, 0x37, 0x32, 0x35, 0x30, 0x31, 0x10, 0x30, 0x0e, - 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x07, 0x4e, 0x65, 0x74, 0x70, 0x68, - 0x65, 0x6e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x09, 0x13, - 0x17, 0x55, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x20, 0x49, 0x6e, 0x64, 0x75, - 0x73, 0x74, 0x72, 0x69, 0x65, 0x73, 0x74, 0x72, 0x2e, 0x20, 0x32, 0x30, - 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x54, - 0x65, 0x6c, 0x65, 0x53, 0x65, 0x63, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x50, 0x61, 0x73, 0x73, 0x20, 0x44, 0x45, 0x2d, 0x32, 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, 0xc1, 0xd6, 0xc7, 0x60, 0xbd, - 0x8e, 0xff, 0xb3, 0x4d, 0xad, 0x28, 0xcd, 0x4e, 0xd4, 0x63, 0x18, 0xa0, - 0x55, 0x81, 0x68, 0x8e, 0x89, 0x8d, 0x15, 0x78, 0x2a, 0xaf, 0x21, 0x90, - 0x48, 0x00, 0x01, 0x96, 0xef, 0x74, 0xc0, 0x92, 0xae, 0xd9, 0x6f, 0x64, - 0x53, 0x98, 0x9f, 0xe7, 0x5d, 0x8d, 0xab, 0x28, 0x99, 0x71, 0x7a, 0xe0, - 0x2b, 0xe5, 0x75, 0x83, 0x30, 0x4d, 0x83, 0x95, 0x58, 0x7d, 0x63, 0x38, - 0xe8, 0x61, 0x24, 0x0b, 0x8f, 0xad, 0x0e, 0x95, 0xae, 0x22, 0x5b, 0x80, - 0x13, 0x1b, 0xd6, 0xe6, 0xa4, 0xd0, 0xcb, 0x20, 0x07, 0x55, 0x57, 0x1c, - 0xe7, 0x8d, 0xfb, 0x42, 0x90, 0x28, 0xea, 0x7d, 0x0f, 0xda, 0x5e, 0x7f, - 0xb4, 0x9d, 0xdb, 0xde, 0x61, 0xab, 0xf9, 0x03, 0x52, 0x73, 0x30, 0x7b, - 0x33, 0xe7, 0xea, 0x06, 0x57, 0xa1, 0x56, 0xef, 0x06, 0x25, 0x85, 0x38, - 0xd5, 0xca, 0x7f, 0x61, 0xe4, 0xf8, 0x8b, 0x5d, 0x56, 0x3e, 0x76, 0x53, - 0x74, 0x0a, 0x23, 0x77, 0xd4, 0xb5, 0xf3, 0x72, 0x4c, 0x4e, 0xd4, 0x0c, - 0x96, 0x0a, 0x02, 0x53, 0x65, 0x92, 0x07, 0x78, 0x19, 0xa1, 0xa0, 0x9c, - 0x13, 0x91, 0xf1, 0xae, 0x85, 0xf4, 0xa8, 0xe1, 0x80, 0xbb, 0x0a, 0x42, - 0xec, 0xbc, 0x6f, 0x4d, 0x3e, 0xed, 0x09, 0x86, 0x46, 0xf0, 0x0e, 0xdf, - 0xee, 0xae, 0xb9, 0xaa, 0xd4, 0x41, 0xc8, 0x81, 0x1b, 0xb2, 0xbf, 0xbb, - 0x13, 0x7c, 0x61, 0xbf, 0x0d, 0x95, 0xd0, 0x9f, 0xc2, 0xf6, 0xdd, 0x6a, - 0x40, 0x9b, 0x4a, 0x6a, 0xfd, 0xf9, 0x92, 0x7e, 0xe6, 0xf7, 0xa9, 0xd5, - 0x0b, 0x61, 0xe2, 0xbd, 0xe2, 0x6b, 0xd1, 0x1d, 0xc5, 0x28, 0xf5, 0x96, - 0xdb, 0xd4, 0x74, 0xaf, 0x29, 0x50, 0xc3, 0xe5, 0xf1, 0x1f, 0x9c, 0x86, - 0x5b, 0xc9, 0x8b, 0xde, 0x6c, 0x76, 0x8f, 0x89, 0x74, 0xa3, 0xef, 0x02, - 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x02, 0xdc, 0x30, 0x82, 0x02, 0xd8, - 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, - 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, - 0x16, 0x04, 0x14, 0x54, 0x04, 0x29, 0x6f, 0xa2, 0x93, 0xc6, 0x90, 0x31, - 0x45, 0xc0, 0x3d, 0xde, 0x2b, 0xe2, 0x0a, 0x69, 0x80, 0x92, 0x5f, 0x30, - 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, - 0x31, 0xc3, 0x79, 0x1b, 0xba, 0xf5, 0x53, 0xd7, 0x17, 0xe0, 0x89, 0x7a, - 0x2d, 0x17, 0x6c, 0x0a, 0xb3, 0x2b, 0x9d, 0x33, 0x30, 0x12, 0x06, 0x03, - 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, - 0xff, 0x02, 0x01, 0x00, 0x30, 0x59, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, - 0x52, 0x30, 0x50, 0x30, 0x44, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, - 0xbd, 0x47, 0x0d, 0x02, 0x30, 0x37, 0x30, 0x35, 0x06, 0x08, 0x2b, 0x06, - 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x29, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x73, - 0x65, 0x63, 0x2e, 0x64, 0x65, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x70, 0x61, 0x73, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x2e, 0x68, 0x74, 0x6d, - 0x6c, 0x30, 0x08, 0x06, 0x06, 0x67, 0x81, 0x0c, 0x01, 0x02, 0x02, 0x30, - 0x81, 0xef, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x81, 0xe7, 0x30, 0x81, - 0xe4, 0x30, 0x3a, 0xa0, 0x38, 0xa0, 0x36, 0x86, 0x34, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x70, 0x61, 0x73, 0x73, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x73, - 0x65, 0x63, 0x2e, 0x64, 0x65, 0x2f, 0x72, 0x6c, 0x2f, 0x44, 0x54, 0x5f, - 0x52, 0x4f, 0x4f, 0x54, 0x5f, 0x43, 0x41, 0x5f, 0x32, 0x2e, 0x63, 0x72, - 0x6c, 0x30, 0x81, 0xa5, 0xa0, 0x81, 0xa2, 0xa0, 0x81, 0x9f, 0x86, 0x81, - 0x9c, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x64, 0x61, 0x70, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x70, 0x61, 0x73, 0x73, 0x2e, - 0x74, 0x65, 0x6c, 0x65, 0x73, 0x65, 0x63, 0x2e, 0x64, 0x65, 0x2f, 0x43, - 0x4e, 0x3d, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x25, 0x32, - 0x30, 0x54, 0x65, 0x6c, 0x65, 0x6b, 0x6f, 0x6d, 0x25, 0x32, 0x30, 0x52, - 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, 0x41, 0x25, 0x32, 0x30, 0x32, - 0x2c, 0x4f, 0x55, 0x3d, 0x54, 0x2d, 0x54, 0x65, 0x6c, 0x65, 0x53, 0x65, - 0x63, 0x25, 0x32, 0x30, 0x54, 0x72, 0x75, 0x73, 0x74, 0x25, 0x32, 0x30, - 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2c, 0x4f, 0x3d, 0x44, 0x65, 0x75, - 0x74, 0x73, 0x63, 0x68, 0x65, 0x25, 0x32, 0x30, 0x54, 0x65, 0x6c, 0x65, - 0x6b, 0x6f, 0x6d, 0x25, 0x32, 0x30, 0x41, 0x47, 0x2c, 0x43, 0x3d, 0x44, - 0x45, 0x3f, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x52, - 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, - 0x74, 0x30, 0x82, 0x01, 0x23, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x01, 0x01, 0x04, 0x82, 0x01, 0x15, 0x30, 0x82, 0x01, 0x11, 0x30, - 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, - 0x1e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, - 0x30, 0x32, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x73, 0x65, 0x63, 0x2e, 0x64, - 0x65, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x72, 0x30, 0x41, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x35, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x70, 0x61, 0x73, 0x73, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x73, - 0x65, 0x63, 0x2e, 0x64, 0x65, 0x2f, 0x63, 0x72, 0x74, 0x2f, 0x44, 0x54, - 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x5f, 0x43, 0x41, 0x5f, 0x32, 0x2e, 0x63, - 0x65, 0x72, 0x30, 0x81, 0x9f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x30, 0x02, 0x86, 0x81, 0x92, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, - 0x2f, 0x6c, 0x64, 0x61, 0x70, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x70, 0x61, 0x73, 0x73, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x73, 0x65, 0x63, - 0x2e, 0x64, 0x65, 0x2f, 0x43, 0x4e, 0x3d, 0x44, 0x65, 0x75, 0x74, 0x73, - 0x63, 0x68, 0x65, 0x25, 0x32, 0x30, 0x54, 0x65, 0x6c, 0x65, 0x6b, 0x6f, - 0x6d, 0x25, 0x32, 0x30, 0x52, 0x6f, 0x6f, 0x74, 0x25, 0x32, 0x30, 0x43, - 0x41, 0x25, 0x32, 0x30, 0x32, 0x2c, 0x4f, 0x55, 0x3d, 0x54, 0x2d, 0x54, - 0x65, 0x6c, 0x65, 0x53, 0x65, 0x63, 0x25, 0x32, 0x30, 0x54, 0x72, 0x75, - 0x73, 0x74, 0x25, 0x32, 0x30, 0x43, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2c, - 0x4f, 0x3d, 0x44, 0x65, 0x75, 0x74, 0x73, 0x63, 0x68, 0x65, 0x25, 0x32, - 0x30, 0x54, 0x65, 0x6c, 0x65, 0x6b, 0x6f, 0x6d, 0x25, 0x32, 0x30, 0x41, - 0x47, 0x2c, 0x43, 0x3d, 0x44, 0x45, 0x3f, 0x63, 0x41, 0x43, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, - 0x82, 0x01, 0x01, 0x00, 0x2c, 0x6c, 0xcc, 0x30, 0x8e, 0x5a, 0xd4, 0x38, - 0xce, 0x3f, 0xd4, 0xa3, 0x37, 0xdb, 0xfe, 0xc8, 0xba, 0x4a, 0xce, 0x6d, - 0xaa, 0x07, 0xe8, 0x4a, 0x54, 0x39, 0xb5, 0x36, 0xa7, 0xdc, 0x57, 0xe8, - 0xb0, 0xab, 0xee, 0x0c, 0xc0, 0x08, 0xbf, 0xab, 0x94, 0x0e, 0x88, 0x97, - 0x78, 0x9a, 0xd2, 0xfe, 0xb3, 0xcb, 0x88, 0xa9, 0x03, 0x68, 0x17, 0x3f, - 0x46, 0x7d, 0x65, 0xcc, 0xa2, 0x36, 0x9a, 0x65, 0xb3, 0xad, 0x4d, 0x79, - 0x62, 0xc1, 0x86, 0x4d, 0xa1, 0xbb, 0xac, 0x84, 0x65, 0x63, 0xbb, 0xea, - 0xa1, 0x71, 0x28, 0xc7, 0xab, 0x04, 0x59, 0x9c, 0x53, 0x72, 0x5c, 0x8f, - 0xf2, 0x6f, 0xdf, 0x77, 0xc7, 0xd9, 0xa4, 0x93, 0x07, 0xd9, 0x4e, 0x86, - 0xb9, 0x36, 0xaf, 0x5c, 0x9f, 0xc0, 0x2b, 0xff, 0xfd, 0x7c, 0xcc, 0xee, - 0xbc, 0x68, 0x10, 0xb1, 0x0b, 0x32, 0xc7, 0x0b, 0x3d, 0xb6, 0x6e, 0x10, - 0x09, 0xdd, 0xe8, 0x49, 0x57, 0x7f, 0x75, 0xa5, 0x1b, 0x1d, 0x0f, 0xba, - 0x04, 0x80, 0x51, 0x3f, 0x2c, 0x8c, 0xe7, 0x94, 0xb5, 0x0d, 0x00, 0xc7, - 0xe9, 0x5e, 0x3e, 0xb4, 0xb1, 0x59, 0x7e, 0x26, 0x70, 0x72, 0x36, 0x69, - 0x27, 0x2d, 0x85, 0xb2, 0xd7, 0x7a, 0x53, 0xad, 0x0f, 0xd2, 0x0a, 0x89, - 0x59, 0x04, 0x29, 0x65, 0x41, 0x11, 0xe2, 0x75, 0xd3, 0x6c, 0x09, 0xbc, - 0x00, 0x7d, 0x46, 0xdf, 0x17, 0xb7, 0xe2, 0x51, 0x68, 0x36, 0x04, 0xbe, - 0x96, 0x1b, 0x82, 0xb8, 0xa2, 0xac, 0x3c, 0x9e, 0x3d, 0x3e, 0x18, 0x47, - 0x59, 0x50, 0x33, 0x95, 0x01, 0x6a, 0x7e, 0x89, 0x75, 0xb3, 0xd0, 0x62, - 0xb3, 0xb1, 0x17, 0x2d, 0xea, 0x03, 0xca, 0x12, 0x6b, 0xbd, 0x38, 0xd2, - 0xa8, 0xf6, 0x97, 0xf3, 0xb3, 0xda, 0x2a, 0xdd, 0x16, 0xd3, 0xe3, 0x7b, - 0x87, 0xf7, 0xe9, 0x36, 0x07, 0x0c, 0x7e, 0x11, -}; - -#if 0 -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 03:37:b9:28:34:7c:60:a6:ae:c5:ad:b1:21:7f:38:60 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA - Validity - Not Before: Nov 9 12:00:00 2007 GMT - Not After : Nov 10 00:00:00 2021 GMT - Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV CA-1 - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:f3:96:62:d8:75:6e:19:ff:3f:34:7c:49:4f:31: - 7e:0d:04:4e:99:81:e2:b3:85:55:91:30:b1:c0:af: - 70:bb:2c:a8:e7:18:aa:3f:78:f7:90:68:52:86:01: - 88:97:e2:3b:06:65:90:aa:bd:65:76:c2:ec:be:10: - 5b:37:78:83:60:75:45:c6:bd:74:aa:b6:9f:a4:3a: - 01:50:17:c4:39:69:b9:f1:4f:ef:82:c1:ca:f3:4a: - db:cc:9e:50:4f:4d:40:a3:3a:90:e7:86:66:bc:f0: - 3e:76:28:4c:d1:75:80:9e:6a:35:14:35:03:9e:db: - 0c:8c:c2:28:ad:50:b2:ce:f6:91:a3:c3:a5:0a:58: - 49:f6:75:44:6c:ba:f9:ce:e9:ab:3a:02:e0:4d:f3: - ac:e2:7a:e0:60:22:05:3c:82:d3:52:e2:f3:9c:47: - f8:3b:d8:b2:4b:93:56:4a:bf:70:ab:3e:e9:68:c8: - 1d:8f:58:1d:2a:4d:5e:27:3d:ad:0a:59:2f:5a:11: - 20:40:d9:68:04:68:2d:f4:c0:84:0b:0a:1b:78:df: - ed:1a:58:dc:fb:41:5a:6d:6b:f2:ed:1c:ee:5c:32: - b6:5c:ec:d7:a6:03:32:a6:e8:de:b7:28:27:59:88: - 80:ff:7b:ad:89:58:d5:1e:14:a4:f2:b0:70:d4:a0: - 3e:a7 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Key Usage: critical - Digital Signature, Certificate Sign, CRL Sign - X509v3 Extended Key Usage: - TLS Web Server Authentication, TLS Web Client Authentication, Code Signing, E-mail Protection, Time Stamping - X509v3 Certificate Policies: - Policy: 2.16.840.1.114412.2.1 - CPS: http://www.digicert.com/ssl-cps-repository.htm - User Notice: - Explicit Text: - - X509v3 Basic Constraints: critical - CA:TRUE, pathlen:0 - Authority Information Access: - OCSP - URI:http://ocsp.digicert.com - CA Issuers - URI:http://www.digicert.com/CACerts/DigiCertHighAssuranceEVRootCA.crt - - X509v3 CRL Distribution Points: - - Full Name: - URI:http://crl3.digicert.com/DigiCertHighAssuranceEVRootCA.crl - - Full Name: - URI:http://crl4.digicert.com/DigiCertHighAssuranceEVRootCA.crl - - X509v3 Subject Key Identifier: - 4C:58:CB:25:F0:41:4F:52:F4:28:C8:81:43:9B:A6:A8:A0:E6:92:E5 - X509v3 Authority Key Identifier: - keyid:B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3 - - Signature Algorithm: sha1WithRSAEncryption - 4c:7a:17:87:28:5d:17:bc:b2:32:73:bf:cd:2e:f5:58:31:1d: - f0:b1:71:54:9c:d6:9b:67:93:db:2f:03:3e:16:6f:1e:03:c9: - 53:84:a3:56:60:1e:78:94:1b:a2:a8:6f:a3:a4:8b:52:91:d7: - dd:5c:95:bb:ef:b5:16:49:e9:a5:42:4f:34:f2:47:ff:ae:81: - 7f:13:54:b7:20:c4:70:15:cb:81:0a:81:cb:74:57:dc:9c:df: - 24:a4:29:0c:18:f0:1c:e4:ae:07:33:ec:f1:49:3e:55:cf:6e: - 4f:0d:54:7b:d3:c9:e8:15:48:d4:c5:bb:dc:35:1c:77:45:07: - 48:45:85:bd:d7:7e:53:b8:c0:16:d9:95:cd:8b:8d:7d:c9:60: - 4f:d1:a2:9b:e3:d0:30:d6:b4:73:36:e6:d2:f9:03:b2:e3:a4: - f5:e5:b8:3e:04:49:00:ba:2e:a6:4a:72:83:72:9d:f7:0b:8c: - a9:89:e7:b3:d7:64:1f:d6:e3:60:cb:03:c4:dc:88:e9:9d:25: - 01:00:71:cb:03:b4:29:60:25:8f:f9:46:d1:7b:71:ae:cd:53: - 12:5b:84:8e:c2:0f:c7:ed:93:19:d9:c9:fa:8f:58:34:76:32: - 2f:ae:e1:50:14:61:d4:a8:58:a3:c8:30:13:23:ef:c6:25:8c: - 36:8f:1c:80 ------BEGIN CERTIFICATE----- -MIIG5jCCBc6gAwIBAgIQAze5KDR8YKauxa2xIX84YDANBgkqhkiG9w0BAQUFADBs -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j -ZSBFViBSb290IENBMB4XDTA3MTEwOTEyMDAwMFoXDTIxMTExMDAwMDAwMFowaTEL -MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 -LmRpZ2ljZXJ0LmNvbTEoMCYGA1UEAxMfRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug -RVYgQ0EtMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPOWYth1bhn/ -PzR8SU8xfg0ETpmB4rOFVZEwscCvcLssqOcYqj9495BoUoYBiJfiOwZlkKq9ZXbC -7L4QWzd4g2B1Rca9dKq2n6Q6AVAXxDlpufFP74LByvNK28yeUE9NQKM6kOeGZrzw -PnYoTNF1gJ5qNRQ1A57bDIzCKK1Qss72kaPDpQpYSfZ1RGy6+c7pqzoC4E3zrOJ6 -4GAiBTyC01Li85xH+DvYskuTVkq/cKs+6WjIHY9YHSpNXic9rQpZL1oRIEDZaARo -LfTAhAsKG3jf7RpY3PtBWm1r8u0c7lwytlzs16YDMqbo3rcoJ1mIgP97rYlY1R4U -pPKwcNSgPqcCAwEAAaOCA4UwggOBMA4GA1UdDwEB/wQEAwIBhjA7BgNVHSUENDAy -BggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUH -AwgwggHEBgNVHSAEggG7MIIBtzCCAbMGCWCGSAGG/WwCATCCAaQwOgYIKwYBBQUH -AgEWLmh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5o -dG0wggFkBggrBgEFBQcCAjCCAVYeggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0 -AGgAaQBzACAAQwBlAHIAdABpAGYAaQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1 -AHQAZQBzACAAYQBjAGMAZQBwAHQAYQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABp -AGcAaQBDAGUAcgB0ACAARQBWACAAQwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBl -AGwAeQBpAG4AZwAgAFAAYQByAHQAeQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBo -AGkAYwBoACAAbABpAG0AaQB0ACAAbABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAg -AGEAcgBlACAAaQBuAGMAbwByAHAAbwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAg -AGIAeQAgAHIAZQBmAGUAcgBlAG4AYwBlAC4wEgYDVR0TAQH/BAgwBgEB/wIBADCB -gwYIKwYBBQUHAQEEdzB1MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy -dC5jb20wTQYIKwYBBQUHMAKGQWh0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NBQ2Vy -dHMvRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3J0MIGPBgNVHR8EgYcw -gYQwQKA+oDyGOmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEhpZ2hB -c3N1cmFuY2VFVlJvb3RDQS5jcmwwQKA+oDyGOmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0 -LmNvbS9EaWdpQ2VydEhpZ2hBc3N1cmFuY2VFVlJvb3RDQS5jcmwwHQYDVR0OBBYE -FExYyyXwQU9S9CjIgUObpqig5pLlMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSYJhoI -Au9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQBMeheHKF0XvLIyc7/NLvVYMR3wsXFU -nNabZ5PbLwM+Fm8eA8lThKNWYB54lBuiqG+jpItSkdfdXJW777UWSemlQk808kf/ -roF/E1S3IMRwFcuBCoHLdFfcnN8kpCkMGPAc5K4HM+zxST5Vz25PDVR708noFUjU -xbvcNRx3RQdIRYW9135TuMAW2ZXNi419yWBP0aKb49Aw1rRzNubS+QOy46T15bg+ -BEkAui6mSnKDcp33C4ypieez12Qf1uNgywPE3IjpnSUBAHHLA7QpYCWP+UbRe3Gu -zVMSW4SOwg/H7ZMZ2cn6j1g0djIvruFQFGHUqFijyDATI+/GJYw2jxyA ------END CERTIFICATE----- -#endif -static const unsigned char kDERCert61[] = { - 0x30, 0x82, 0x06, 0xe6, 0x30, 0x82, 0x05, 0xce, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x03, 0x37, 0xb9, 0x28, 0x34, 0x7c, 0x60, 0xa6, 0xae, - 0xc5, 0xad, 0xb1, 0x21, 0x7f, 0x38, 0x60, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x6c, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, - 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, - 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, - 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, - 0x63, 0x6f, 0x6d, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, - 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48, - 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, - 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, - 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x37, 0x31, 0x31, 0x30, 0x39, 0x31, 0x32, - 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31, 0x31, - 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x69, 0x31, 0x0b, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, - 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44, 0x69, - 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x19, - 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, 0x77, 0x77, - 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, - 0x6d, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1f, - 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48, 0x69, 0x67, - 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x20, - 0x45, 0x56, 0x20, 0x43, 0x41, 0x2d, 0x31, 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, 0xf3, 0x96, 0x62, 0xd8, 0x75, 0x6e, 0x19, 0xff, - 0x3f, 0x34, 0x7c, 0x49, 0x4f, 0x31, 0x7e, 0x0d, 0x04, 0x4e, 0x99, 0x81, - 0xe2, 0xb3, 0x85, 0x55, 0x91, 0x30, 0xb1, 0xc0, 0xaf, 0x70, 0xbb, 0x2c, - 0xa8, 0xe7, 0x18, 0xaa, 0x3f, 0x78, 0xf7, 0x90, 0x68, 0x52, 0x86, 0x01, - 0x88, 0x97, 0xe2, 0x3b, 0x06, 0x65, 0x90, 0xaa, 0xbd, 0x65, 0x76, 0xc2, - 0xec, 0xbe, 0x10, 0x5b, 0x37, 0x78, 0x83, 0x60, 0x75, 0x45, 0xc6, 0xbd, - 0x74, 0xaa, 0xb6, 0x9f, 0xa4, 0x3a, 0x01, 0x50, 0x17, 0xc4, 0x39, 0x69, - 0xb9, 0xf1, 0x4f, 0xef, 0x82, 0xc1, 0xca, 0xf3, 0x4a, 0xdb, 0xcc, 0x9e, - 0x50, 0x4f, 0x4d, 0x40, 0xa3, 0x3a, 0x90, 0xe7, 0x86, 0x66, 0xbc, 0xf0, - 0x3e, 0x76, 0x28, 0x4c, 0xd1, 0x75, 0x80, 0x9e, 0x6a, 0x35, 0x14, 0x35, - 0x03, 0x9e, 0xdb, 0x0c, 0x8c, 0xc2, 0x28, 0xad, 0x50, 0xb2, 0xce, 0xf6, - 0x91, 0xa3, 0xc3, 0xa5, 0x0a, 0x58, 0x49, 0xf6, 0x75, 0x44, 0x6c, 0xba, - 0xf9, 0xce, 0xe9, 0xab, 0x3a, 0x02, 0xe0, 0x4d, 0xf3, 0xac, 0xe2, 0x7a, - 0xe0, 0x60, 0x22, 0x05, 0x3c, 0x82, 0xd3, 0x52, 0xe2, 0xf3, 0x9c, 0x47, - 0xf8, 0x3b, 0xd8, 0xb2, 0x4b, 0x93, 0x56, 0x4a, 0xbf, 0x70, 0xab, 0x3e, - 0xe9, 0x68, 0xc8, 0x1d, 0x8f, 0x58, 0x1d, 0x2a, 0x4d, 0x5e, 0x27, 0x3d, - 0xad, 0x0a, 0x59, 0x2f, 0x5a, 0x11, 0x20, 0x40, 0xd9, 0x68, 0x04, 0x68, - 0x2d, 0xf4, 0xc0, 0x84, 0x0b, 0x0a, 0x1b, 0x78, 0xdf, 0xed, 0x1a, 0x58, - 0xdc, 0xfb, 0x41, 0x5a, 0x6d, 0x6b, 0xf2, 0xed, 0x1c, 0xee, 0x5c, 0x32, - 0xb6, 0x5c, 0xec, 0xd7, 0xa6, 0x03, 0x32, 0xa6, 0xe8, 0xde, 0xb7, 0x28, - 0x27, 0x59, 0x88, 0x80, 0xff, 0x7b, 0xad, 0x89, 0x58, 0xd5, 0x1e, 0x14, - 0xa4, 0xf2, 0xb0, 0x70, 0xd4, 0xa0, 0x3e, 0xa7, 0x02, 0x03, 0x01, 0x00, - 0x01, 0xa3, 0x82, 0x03, 0x85, 0x30, 0x82, 0x03, 0x81, 0x30, 0x0e, 0x06, - 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, - 0x86, 0x30, 0x3b, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x34, 0x30, 0x32, - 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, - 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08, 0x2b, 0x06, - 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x03, 0x04, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x03, 0x08, 0x30, 0x82, 0x01, 0xc4, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, - 0x82, 0x01, 0xbb, 0x30, 0x82, 0x01, 0xb7, 0x30, 0x82, 0x01, 0xb3, 0x06, - 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xfd, 0x6c, 0x02, 0x01, 0x30, 0x82, - 0x01, 0xa4, 0x30, 0x3a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, - 0x02, 0x01, 0x16, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, - 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x73, 0x6c, 0x2d, 0x63, 0x70, 0x73, 0x2d, - 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x68, - 0x74, 0x6d, 0x30, 0x82, 0x01, 0x64, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x02, 0x02, 0x30, 0x82, 0x01, 0x56, 0x1e, 0x82, 0x01, 0x52, - 0x00, 0x41, 0x00, 0x6e, 0x00, 0x79, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, - 0x00, 0x65, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x74, - 0x00, 0x68, 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, 0x00, 0x43, 0x00, 0x65, - 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x63, - 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, - 0x00, 0x6e, 0x00, 0x73, 0x00, 0x74, 0x00, 0x69, 0x00, 0x74, 0x00, 0x75, - 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, 0x00, 0x63, - 0x00, 0x63, 0x00, 0x65, 0x00, 0x70, 0x00, 0x74, 0x00, 0x61, 0x00, 0x6e, - 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, - 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x44, 0x00, 0x69, - 0x00, 0x67, 0x00, 0x69, 0x00, 0x43, 0x00, 0x65, 0x00, 0x72, 0x00, 0x74, - 0x00, 0x20, 0x00, 0x45, 0x00, 0x56, 0x00, 0x20, 0x00, 0x43, 0x00, 0x50, - 0x00, 0x53, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, - 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x52, 0x00, 0x65, - 0x00, 0x6c, 0x00, 0x79, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x20, - 0x00, 0x50, 0x00, 0x61, 0x00, 0x72, 0x00, 0x74, 0x00, 0x79, 0x00, 0x20, - 0x00, 0x41, 0x00, 0x67, 0x00, 0x72, 0x00, 0x65, 0x00, 0x65, 0x00, 0x6d, - 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x20, 0x00, 0x77, 0x00, 0x68, - 0x00, 0x69, 0x00, 0x63, 0x00, 0x68, 0x00, 0x20, 0x00, 0x6c, 0x00, 0x69, - 0x00, 0x6d, 0x00, 0x69, 0x00, 0x74, 0x00, 0x20, 0x00, 0x6c, 0x00, 0x69, - 0x00, 0x61, 0x00, 0x62, 0x00, 0x69, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x74, - 0x00, 0x79, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, - 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x69, 0x00, 0x6e, - 0x00, 0x63, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72, - 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x68, - 0x00, 0x65, 0x00, 0x72, 0x00, 0x65, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x20, - 0x00, 0x62, 0x00, 0x79, 0x00, 0x20, 0x00, 0x72, 0x00, 0x65, 0x00, 0x66, - 0x00, 0x65, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x65, - 0x00, 0x2e, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, - 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x81, - 0x83, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, - 0x77, 0x30, 0x75, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, - 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, - 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4d, 0x06, 0x08, 0x2b, 0x06, 0x01, - 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x41, 0x68, 0x74, 0x74, 0x70, 0x3a, - 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, - 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x41, 0x43, 0x65, 0x72, - 0x74, 0x73, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x48, - 0x69, 0x67, 0x68, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, - 0x45, 0x56, 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, - 0x30, 0x81, 0x8f, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x81, 0x87, 0x30, - 0x81, 0x84, 0x30, 0x40, 0xa0, 0x3e, 0xa0, 0x3c, 0x86, 0x3a, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x33, 0x2e, 0x64, 0x69, - 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, - 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x48, 0x69, 0x67, 0x68, 0x41, - 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x56, 0x52, 0x6f, - 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x40, 0xa0, 0x3e, - 0xa0, 0x3c, 0x86, 0x3a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, - 0x72, 0x6c, 0x34, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, - 0x74, 0x48, 0x69, 0x67, 0x68, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, - 0x63, 0x65, 0x45, 0x56, 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, - 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, - 0x14, 0x4c, 0x58, 0xcb, 0x25, 0xf0, 0x41, 0x4f, 0x52, 0xf4, 0x28, 0xc8, - 0x81, 0x43, 0x9b, 0xa6, 0xa8, 0xa0, 0xe6, 0x92, 0xe5, 0x30, 0x1f, 0x06, - 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb1, 0x3e, - 0xc3, 0x69, 0x03, 0xf8, 0xbf, 0x47, 0x01, 0xd4, 0x98, 0x26, 0x1a, 0x08, - 0x02, 0xef, 0x63, 0x64, 0x2b, 0xc3, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, - 0x01, 0x00, 0x4c, 0x7a, 0x17, 0x87, 0x28, 0x5d, 0x17, 0xbc, 0xb2, 0x32, - 0x73, 0xbf, 0xcd, 0x2e, 0xf5, 0x58, 0x31, 0x1d, 0xf0, 0xb1, 0x71, 0x54, - 0x9c, 0xd6, 0x9b, 0x67, 0x93, 0xdb, 0x2f, 0x03, 0x3e, 0x16, 0x6f, 0x1e, - 0x03, 0xc9, 0x53, 0x84, 0xa3, 0x56, 0x60, 0x1e, 0x78, 0x94, 0x1b, 0xa2, - 0xa8, 0x6f, 0xa3, 0xa4, 0x8b, 0x52, 0x91, 0xd7, 0xdd, 0x5c, 0x95, 0xbb, - 0xef, 0xb5, 0x16, 0x49, 0xe9, 0xa5, 0x42, 0x4f, 0x34, 0xf2, 0x47, 0xff, - 0xae, 0x81, 0x7f, 0x13, 0x54, 0xb7, 0x20, 0xc4, 0x70, 0x15, 0xcb, 0x81, - 0x0a, 0x81, 0xcb, 0x74, 0x57, 0xdc, 0x9c, 0xdf, 0x24, 0xa4, 0x29, 0x0c, - 0x18, 0xf0, 0x1c, 0xe4, 0xae, 0x07, 0x33, 0xec, 0xf1, 0x49, 0x3e, 0x55, - 0xcf, 0x6e, 0x4f, 0x0d, 0x54, 0x7b, 0xd3, 0xc9, 0xe8, 0x15, 0x48, 0xd4, - 0xc5, 0xbb, 0xdc, 0x35, 0x1c, 0x77, 0x45, 0x07, 0x48, 0x45, 0x85, 0xbd, - 0xd7, 0x7e, 0x53, 0xb8, 0xc0, 0x16, 0xd9, 0x95, 0xcd, 0x8b, 0x8d, 0x7d, - 0xc9, 0x60, 0x4f, 0xd1, 0xa2, 0x9b, 0xe3, 0xd0, 0x30, 0xd6, 0xb4, 0x73, - 0x36, 0xe6, 0xd2, 0xf9, 0x03, 0xb2, 0xe3, 0xa4, 0xf5, 0xe5, 0xb8, 0x3e, - 0x04, 0x49, 0x00, 0xba, 0x2e, 0xa6, 0x4a, 0x72, 0x83, 0x72, 0x9d, 0xf7, - 0x0b, 0x8c, 0xa9, 0x89, 0xe7, 0xb3, 0xd7, 0x64, 0x1f, 0xd6, 0xe3, 0x60, - 0xcb, 0x03, 0xc4, 0xdc, 0x88, 0xe9, 0x9d, 0x25, 0x01, 0x00, 0x71, 0xcb, - 0x03, 0xb4, 0x29, 0x60, 0x25, 0x8f, 0xf9, 0x46, 0xd1, 0x7b, 0x71, 0xae, - 0xcd, 0x53, 0x12, 0x5b, 0x84, 0x8e, 0xc2, 0x0f, 0xc7, 0xed, 0x93, 0x19, - 0xd9, 0xc9, 0xfa, 0x8f, 0x58, 0x34, 0x76, 0x32, 0x2f, 0xae, 0xe1, 0x50, - 0x14, 0x61, 0xd4, 0xa8, 0x58, 0xa3, 0xc8, 0x30, 0x13, 0x23, 0xef, 0xc6, - 0x25, 0x8c, 0x36, 0x8f, 0x1c, 0x80, -};
diff --git a/net/quic/core/crypto/common_cert_set_3.c b/net/quic/core/crypto/common_cert_set_3.c new file mode 100644 index 0000000..3d16aae3 --- /dev/null +++ b/net/quic/core/crypto/common_cert_set_3.c
@@ -0,0 +1,123 @@ +/* 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 contains common certificates. It's designed to be #included in + * another file, in a namespace. */ + +#include "net/quic/core/crypto/common_cert_set_3a.inc" +#include "net/quic/core/crypto/common_cert_set_3b.inc" + +static const size_t kNumCerts = 52; +static const unsigned char* const kCerts[] = { + kDERCert0, + kDERCert1, + kDERCert2, + kDERCert3, + kDERCert4, + kDERCert5, + kDERCert6, + kDERCert7, + kDERCert8, + kDERCert9, + kDERCert10, + kDERCert11, + kDERCert12, + kDERCert13, + kDERCert14, + kDERCert15, + kDERCert16, + kDERCert17, + kDERCert18, + kDERCert19, + kDERCert20, + kDERCert21, + kDERCert22, + kDERCert23, + kDERCert24, + kDERCert25, + kDERCert26, + kDERCert27, + kDERCert28, + kDERCert29, + kDERCert30, + kDERCert31, + kDERCert32, + kDERCert33, + kDERCert34, + kDERCert35, + kDERCert36, + kDERCert37, + kDERCert38, + kDERCert39, + kDERCert40, + kDERCert41, + kDERCert42, + kDERCert43, + kDERCert44, + kDERCert45, + kDERCert46, + kDERCert47, + kDERCert48, + kDERCert49, + kDERCert50, + kDERCert51, +}; + +static const size_t kLens[] = { + 897, + 911, + 1012, + 1049, + 1065, + 1096, + 1097, + 1101, + 1105, + 1105, + 1107, + 1117, + 1127, + 1133, + 1136, + 1138, + 1139, + 1145, + 1149, + 1153, + 1167, + 1172, + 1174, + 1174, + 1176, + 1188, + 1194, + 1196, + 1203, + 1205, + 1206, + 1208, + 1209, + 1210, + 1222, + 1227, + 1236, + 1236, + 1238, + 1283, + 1284, + 1287, + 1298, + 1315, + 1327, + 1340, + 1357, + 1418, + 1447, + 1509, + 1513, + 1632, +}; + +static const uint64_t kHash = UINT64_C(0x918215a28680ed7e);
diff --git a/net/quic/core/crypto/common_cert_set_3a.inc b/net/quic/core/crypto/common_cert_set_3a.inc new file mode 100644 index 0000000..a500cb0 --- /dev/null +++ b/net/quic/core/crypto/common_cert_set_3a.inc
@@ -0,0 +1,5038 @@ +/* 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 contains common certificates. It's designed to be #included in + * another file, in a namespace. */ + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1227750 (0x12bbe6) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=US, O=Equifax, OU=Equifax Secure Certificate Authority + Validity + Not Before: May 21 04:00:00 2002 GMT + Not After : Aug 21 04:00:00 2018 GMT + Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:da:cc:18:63:30:fd:f4:17:23:1a:56:7e:5b:df: + 3c:6c:38:e4:71:b7:78:91:d4:bc:a1:d8:4c:f8:a8: + 43:b6:03:e9:4d:21:07:08:88:da:58:2f:66:39:29: + bd:05:78:8b:9d:38:e8:05:b7:6a:7e:71:a4:e6:c4: + 60:a6:b0:ef:80:e4:89:28:0f:9e:25:d6:ed:83:f3: + ad:a6:91:c7:98:c9:42:18:35:14:9d:ad:98:46:92: + 2e:4f:ca:f1:87:43:c1:16:95:57:2d:50:ef:89:2d: + 80:7a:57:ad:f2:ee:5f:6b:d2:00:8d:b9:14:f8:14: + 15:35:d9:c0:46:a3:7b:72:c8:91:bf:c9:55:2b:cd: + d0:97:3e:9c:26:64:cc:df:ce:83:19:71:ca:4e:e6: + d4:d5:7b:a9:19:cd:55:de:c8:ec:d2:5e:38:53:e5: + 5c:4f:8c:2d:fe:50:23:36:fc:66:e6:cb:8e:a4:39: + 19:00:b7:95:02:39:91:0b:0e:fe:38:2e:d1:1d:05: + 9a:f6:4d:3e:6f:0f:07:1d:af:2c:1e:8f:60:39:e2: + fa:36:53:13:39:d4:5e:26:2b:db:3d:a8:14:bd:32: + eb:18:03:28:52:04:71:e5:ab:33:3d:e1:38:bb:07: + 36:84:62:9c:79:ea:16:30:f4:5f:c0:2b:e8:71:6b: + e4:f9 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Authority Key Identifier: + keyid:48:E6:68:F9:2B:D2:B2:95:D7:47:D8:23:20:10:4F:33:98:90:9F:D4 + + X509v3 Subject Key Identifier: + C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.geotrust.com/crls/secureca.crl + + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: https://www.geotrust.com/resources/repository + + Signature Algorithm: sha1WithRSAEncryption + 76:e1:12:6e:4e:4b:16:12:86:30:06:b2:81:08:cf:f0:08:c7: + c7:71:7e:66:ee:c2:ed:d4:3b:1f:ff:f0:f0:c8:4e:d6:43:38: + b0:b9:30:7d:18:d0:55:83:a2:6a:cb:36:11:9c:e8:48:66:a3: + 6d:7f:b8:13:d4:47:fe:8b:5a:5c:73:fc:ae:d9:1b:32:19:38: + ab:97:34:14:aa:96:d2:eb:a3:1c:14:08:49:b6:bb:e5:91:ef: + 83:36:eb:1d:56:6f:ca:da:bc:73:63:90:e4:7f:7b:3e:22:cb: + 3d:07:ed:5f:38:74:9c:e3:03:50:4e:a1:af:98:ee:61:f2:84: + 3f:12 +-----BEGIN CERTIFICATE----- +MIIDfTCCAuagAwIBAgIDErvmMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT +MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0 +aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDIwNTIxMDQwMDAwWhcNMTgwODIxMDQwMDAw +WjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UE +AxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9m +OSm9BXiLnTjoBbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIu +T8rxh0PBFpVXLVDviS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6c +JmTM386DGXHKTubU1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmR +Cw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5asz +PeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo4HwMIHtMB8GA1UdIwQYMBaAFEjm +aPkr0rKV10fYIyAQTzOYkJ/UMB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrM +TjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjA6BgNVHR8EMzAxMC+g +LaArhilodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9jcmxzL3NlY3VyZWNhLmNybDBO +BgNVHSAERzBFMEMGBFUdIAAwOzA5BggrBgEFBQcCARYtaHR0cHM6Ly93d3cuZ2Vv +dHJ1c3QuY29tL3Jlc291cmNlcy9yZXBvc2l0b3J5MA0GCSqGSIb3DQEBBQUAA4GB +AHbhEm5OSxYShjAGsoEIz/AIx8dxfmbuwu3UOx//8PDITtZDOLC5MH0Y0FWDomrL +NhGc6Ehmo21/uBPUR/6LWlxz/K7ZGzIZOKuXNBSqltLroxwUCEm2u+WR74M26x1W +b8ravHNjkOR/ez4iyz0H7V84dJzjA1BOoa+Y7mHyhD8S +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert0[] = { + 0x30, 0x82, 0x03, 0x7d, 0x30, 0x82, 0x02, 0xe6, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x03, 0x12, 0xbb, 0xe6, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4e, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x07, 0x45, + 0x71, 0x75, 0x69, 0x66, 0x61, 0x78, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, + 0x55, 0x04, 0x0b, 0x13, 0x24, 0x45, 0x71, 0x75, 0x69, 0x66, 0x61, 0x78, + 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x32, 0x30, + 0x35, 0x32, 0x31, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, + 0x31, 0x38, 0x30, 0x38, 0x32, 0x31, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, + 0x5a, 0x30, 0x42, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x12, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x43, 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, 0xda, 0xcc, 0x18, 0x63, 0x30, 0xfd, + 0xf4, 0x17, 0x23, 0x1a, 0x56, 0x7e, 0x5b, 0xdf, 0x3c, 0x6c, 0x38, 0xe4, + 0x71, 0xb7, 0x78, 0x91, 0xd4, 0xbc, 0xa1, 0xd8, 0x4c, 0xf8, 0xa8, 0x43, + 0xb6, 0x03, 0xe9, 0x4d, 0x21, 0x07, 0x08, 0x88, 0xda, 0x58, 0x2f, 0x66, + 0x39, 0x29, 0xbd, 0x05, 0x78, 0x8b, 0x9d, 0x38, 0xe8, 0x05, 0xb7, 0x6a, + 0x7e, 0x71, 0xa4, 0xe6, 0xc4, 0x60, 0xa6, 0xb0, 0xef, 0x80, 0xe4, 0x89, + 0x28, 0x0f, 0x9e, 0x25, 0xd6, 0xed, 0x83, 0xf3, 0xad, 0xa6, 0x91, 0xc7, + 0x98, 0xc9, 0x42, 0x18, 0x35, 0x14, 0x9d, 0xad, 0x98, 0x46, 0x92, 0x2e, + 0x4f, 0xca, 0xf1, 0x87, 0x43, 0xc1, 0x16, 0x95, 0x57, 0x2d, 0x50, 0xef, + 0x89, 0x2d, 0x80, 0x7a, 0x57, 0xad, 0xf2, 0xee, 0x5f, 0x6b, 0xd2, 0x00, + 0x8d, 0xb9, 0x14, 0xf8, 0x14, 0x15, 0x35, 0xd9, 0xc0, 0x46, 0xa3, 0x7b, + 0x72, 0xc8, 0x91, 0xbf, 0xc9, 0x55, 0x2b, 0xcd, 0xd0, 0x97, 0x3e, 0x9c, + 0x26, 0x64, 0xcc, 0xdf, 0xce, 0x83, 0x19, 0x71, 0xca, 0x4e, 0xe6, 0xd4, + 0xd5, 0x7b, 0xa9, 0x19, 0xcd, 0x55, 0xde, 0xc8, 0xec, 0xd2, 0x5e, 0x38, + 0x53, 0xe5, 0x5c, 0x4f, 0x8c, 0x2d, 0xfe, 0x50, 0x23, 0x36, 0xfc, 0x66, + 0xe6, 0xcb, 0x8e, 0xa4, 0x39, 0x19, 0x00, 0xb7, 0x95, 0x02, 0x39, 0x91, + 0x0b, 0x0e, 0xfe, 0x38, 0x2e, 0xd1, 0x1d, 0x05, 0x9a, 0xf6, 0x4d, 0x3e, + 0x6f, 0x0f, 0x07, 0x1d, 0xaf, 0x2c, 0x1e, 0x8f, 0x60, 0x39, 0xe2, 0xfa, + 0x36, 0x53, 0x13, 0x39, 0xd4, 0x5e, 0x26, 0x2b, 0xdb, 0x3d, 0xa8, 0x14, + 0xbd, 0x32, 0xeb, 0x18, 0x03, 0x28, 0x52, 0x04, 0x71, 0xe5, 0xab, 0x33, + 0x3d, 0xe1, 0x38, 0xbb, 0x07, 0x36, 0x84, 0x62, 0x9c, 0x79, 0xea, 0x16, + 0x30, 0xf4, 0x5f, 0xc0, 0x2b, 0xe8, 0x71, 0x6b, 0xe4, 0xf9, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x81, 0xf0, 0x30, 0x81, 0xed, 0x30, 0x1f, 0x06, + 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x48, 0xe6, + 0x68, 0xf9, 0x2b, 0xd2, 0xb2, 0x95, 0xd7, 0x47, 0xd8, 0x23, 0x20, 0x10, + 0x4f, 0x33, 0x98, 0x90, 0x9f, 0xd4, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, + 0x0e, 0x04, 0x16, 0x04, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, + 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, + 0x4e, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, + 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3a, + 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, 0xa0, + 0x2d, 0xa0, 0x2b, 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x73, 0x65, + 0x63, 0x75, 0x72, 0x65, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x4e, + 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x47, 0x30, 0x45, 0x30, 0x43, 0x06, + 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x2d, 0x68, 0x74, 0x74, + 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x72, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, + 0x00, 0x76, 0xe1, 0x12, 0x6e, 0x4e, 0x4b, 0x16, 0x12, 0x86, 0x30, 0x06, + 0xb2, 0x81, 0x08, 0xcf, 0xf0, 0x08, 0xc7, 0xc7, 0x71, 0x7e, 0x66, 0xee, + 0xc2, 0xed, 0xd4, 0x3b, 0x1f, 0xff, 0xf0, 0xf0, 0xc8, 0x4e, 0xd6, 0x43, + 0x38, 0xb0, 0xb9, 0x30, 0x7d, 0x18, 0xd0, 0x55, 0x83, 0xa2, 0x6a, 0xcb, + 0x36, 0x11, 0x9c, 0xe8, 0x48, 0x66, 0xa3, 0x6d, 0x7f, 0xb8, 0x13, 0xd4, + 0x47, 0xfe, 0x8b, 0x5a, 0x5c, 0x73, 0xfc, 0xae, 0xd9, 0x1b, 0x32, 0x19, + 0x38, 0xab, 0x97, 0x34, 0x14, 0xaa, 0x96, 0xd2, 0xeb, 0xa3, 0x1c, 0x14, + 0x08, 0x49, 0xb6, 0xbb, 0xe5, 0x91, 0xef, 0x83, 0x36, 0xeb, 0x1d, 0x56, + 0x6f, 0xca, 0xda, 0xbc, 0x73, 0x63, 0x90, 0xe4, 0x7f, 0x7b, 0x3e, 0x22, + 0xcb, 0x3d, 0x07, 0xed, 0x5f, 0x38, 0x74, 0x9c, 0xe3, 0x03, 0x50, 0x4e, + 0xa1, 0xaf, 0x98, 0xee, 0x61, 0xf2, 0x84, 0x3f, 0x12, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 880226 (0xd6e62) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=US, O=Equifax, OU=Equifax Secure Certificate Authority + Validity + Not Before: Nov 27 00:00:00 2006 GMT + Not After : Aug 21 16:15:00 2018 GMT + Subject: C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:be:b8:15:7b:ff:d4:7c:7d:67:ad:83:64:7b:c8: + 42:53:2d:df:f6:84:08:20:61:d6:01:59:6a:9c:44: + 11:af:ef:76:fd:95:7e:ce:61:30:bb:7a:83:5f:02: + bd:01:66:ca:ee:15:8d:6f:a1:30:9c:bd:a1:85:9e: + 94:3a:f3:56:88:00:31:cf:d8:ee:6a:96:02:d9:ed: + 03:8c:fb:75:6d:e7:ea:b8:55:16:05:16:9a:f4:e0: + 5e:b1:88:c0:64:85:5c:15:4d:88:c7:b7:ba:e0:75: + e9:ad:05:3d:9d:c7:89:48:e0:bb:28:c8:03:e1:30: + 93:64:5e:52:c0:59:70:22:35:57:88:8a:f1:95:0a: + 83:d7:bc:31:73:01:34:ed:ef:46:71:e0:6b:02:a8: + 35:72:6b:97:9b:66:e0:cb:1c:79:5f:d8:1a:04:68: + 1e:47:02:e6:9d:60:e2:36:97:01:df:ce:35:92:df: + be:67:c7:6d:77:59:3b:8f:9d:d6:90:15:94:bc:42: + 34:10:c1:39:f9:b1:27:3e:7e:d6:8a:75:c5:b2:af: + 96:d3:a2:de:9b:e4:98:be:7d:e1:e9:81:ad:b6:6f: + fc:d7:0e:da:e0:34:b0:0d:1a:77:e7:e3:08:98:ef: + 58:fa:9c:84:b7:36:af:c2:df:ac:d2:f4:10:06:70: + 71:35 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 2C:D5:50:41:97:15:8B:F0:8F:36:61:5B:4A:FB:6B:D9:99:C9:33:92 + X509v3 Authority Key Identifier: + keyid:48:E6:68:F9:2B:D2:B2:95:D7:47:D8:23:20:10:4F:33:98:90:9F:D4 + + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.geotrust.com/crls/secureca.crl + + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: http://www.geotrust.com/resources/cps + + Signature Algorithm: sha1WithRSAEncryption + af:f3:0e:d6:72:ab:c7:a9:97:ca:2a:6b:84:39:de:79:a9:f0: + 81:e5:08:67:ab:d7:2f:20:02:01:71:0c:04:22:c9:1e:88:95: + 03:c9:49:3a:af:67:08:49:b0:d5:08:f5:20:3d:80:91:a0:c5: + 87:a3:fb:c9:a3:17:91:f9:a8:2f:ae:e9:0f:df:96:72:0f:75: + 17:80:5d:78:01:4d:9f:1f:6d:7b:d8:f5:42:38:23:1a:99:93: + f4:83:be:3b:35:74:e7:37:13:35:7a:ac:b4:b6:90:82:6c:27: + a4:e0:ec:9e:35:bd:bf:e5:29:a1:47:9f:5b:32:fc:e9:99:7d: + 2b:39 +-----BEGIN CERTIFICATE----- +MIIDizCCAvSgAwIBAgIDDW5iMA0GCSqGSIb3DQEBBQUAME4xCzAJBgNVBAYTAlVT +MRAwDgYDVQQKEwdFcXVpZmF4MS0wKwYDVQQLEyRFcXVpZmF4IFNlY3VyZSBDZXJ0 +aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMTI3MDAwMDAwWhcNMTgwODIxMTYxNTAw +WjBYMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UE +AxMoR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL64FXv/1Hx9Z62DZHvIQlMt3/aE +CCBh1gFZapxEEa/vdv2Vfs5hMLt6g18CvQFmyu4VjW+hMJy9oYWelDrzVogAMc/Y +7mqWAtntA4z7dW3n6rhVFgUWmvTgXrGIwGSFXBVNiMe3uuB16a0FPZ3HiUjguyjI +A+Ewk2ReUsBZcCI1V4iK8ZUKg9e8MXMBNO3vRnHgawKoNXJrl5tm4MsceV/YGgRo +HkcC5p1g4jaXAd/ONZLfvmfHbXdZO4+d1pAVlLxCNBDBOfmxJz5+1op1xbKvltOi +3pvkmL594emBrbZv/NcO2uA0sA0ad+fjCJjvWPqchLc2r8LfrNL0EAZwcTUCAwEA +AaOB6DCB5TAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFCzVUEGXFYvwjzZhW0r7 +a9mZyTOSMB8GA1UdIwQYMBaAFEjmaPkr0rKV10fYIyAQTzOYkJ/UMA8GA1UdEwEB +/wQFMAMBAf8wOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5j +b20vY3Jscy9zZWN1cmVjYS5jcmwwRgYDVR0gBD8wPTA7BgRVHSAAMDMwMQYIKwYB +BQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwDQYJ +KoZIhvcNAQEFBQADgYEAr/MO1nKrx6mXyiprhDneeanwgeUIZ6vXLyACAXEMBCLJ +HoiVA8lJOq9nCEmw1Qj1ID2AkaDFh6P7yaMXkfmoL67pD9+Wcg91F4BdeAFNnx9t +e9j1QjgjGpmT9IO+OzV05zcTNXqstLaQgmwnpODsnjW9v+UpoUefWzL86Zl9Kzk= +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert1[] = { + 0x30, 0x82, 0x03, 0x8b, 0x30, 0x82, 0x02, 0xf4, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x03, 0x0d, 0x6e, 0x62, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4e, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x07, 0x45, + 0x71, 0x75, 0x69, 0x66, 0x61, 0x78, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, + 0x55, 0x04, 0x0b, 0x13, 0x24, 0x45, 0x71, 0x75, 0x69, 0x66, 0x61, 0x78, + 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, + 0x31, 0x32, 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, + 0x31, 0x38, 0x30, 0x38, 0x32, 0x31, 0x31, 0x36, 0x31, 0x35, 0x30, 0x30, + 0x5a, 0x30, 0x58, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x28, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 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, 0xbe, 0xb8, 0x15, 0x7b, 0xff, 0xd4, 0x7c, 0x7d, + 0x67, 0xad, 0x83, 0x64, 0x7b, 0xc8, 0x42, 0x53, 0x2d, 0xdf, 0xf6, 0x84, + 0x08, 0x20, 0x61, 0xd6, 0x01, 0x59, 0x6a, 0x9c, 0x44, 0x11, 0xaf, 0xef, + 0x76, 0xfd, 0x95, 0x7e, 0xce, 0x61, 0x30, 0xbb, 0x7a, 0x83, 0x5f, 0x02, + 0xbd, 0x01, 0x66, 0xca, 0xee, 0x15, 0x8d, 0x6f, 0xa1, 0x30, 0x9c, 0xbd, + 0xa1, 0x85, 0x9e, 0x94, 0x3a, 0xf3, 0x56, 0x88, 0x00, 0x31, 0xcf, 0xd8, + 0xee, 0x6a, 0x96, 0x02, 0xd9, 0xed, 0x03, 0x8c, 0xfb, 0x75, 0x6d, 0xe7, + 0xea, 0xb8, 0x55, 0x16, 0x05, 0x16, 0x9a, 0xf4, 0xe0, 0x5e, 0xb1, 0x88, + 0xc0, 0x64, 0x85, 0x5c, 0x15, 0x4d, 0x88, 0xc7, 0xb7, 0xba, 0xe0, 0x75, + 0xe9, 0xad, 0x05, 0x3d, 0x9d, 0xc7, 0x89, 0x48, 0xe0, 0xbb, 0x28, 0xc8, + 0x03, 0xe1, 0x30, 0x93, 0x64, 0x5e, 0x52, 0xc0, 0x59, 0x70, 0x22, 0x35, + 0x57, 0x88, 0x8a, 0xf1, 0x95, 0x0a, 0x83, 0xd7, 0xbc, 0x31, 0x73, 0x01, + 0x34, 0xed, 0xef, 0x46, 0x71, 0xe0, 0x6b, 0x02, 0xa8, 0x35, 0x72, 0x6b, + 0x97, 0x9b, 0x66, 0xe0, 0xcb, 0x1c, 0x79, 0x5f, 0xd8, 0x1a, 0x04, 0x68, + 0x1e, 0x47, 0x02, 0xe6, 0x9d, 0x60, 0xe2, 0x36, 0x97, 0x01, 0xdf, 0xce, + 0x35, 0x92, 0xdf, 0xbe, 0x67, 0xc7, 0x6d, 0x77, 0x59, 0x3b, 0x8f, 0x9d, + 0xd6, 0x90, 0x15, 0x94, 0xbc, 0x42, 0x34, 0x10, 0xc1, 0x39, 0xf9, 0xb1, + 0x27, 0x3e, 0x7e, 0xd6, 0x8a, 0x75, 0xc5, 0xb2, 0xaf, 0x96, 0xd3, 0xa2, + 0xde, 0x9b, 0xe4, 0x98, 0xbe, 0x7d, 0xe1, 0xe9, 0x81, 0xad, 0xb6, 0x6f, + 0xfc, 0xd7, 0x0e, 0xda, 0xe0, 0x34, 0xb0, 0x0d, 0x1a, 0x77, 0xe7, 0xe3, + 0x08, 0x98, 0xef, 0x58, 0xfa, 0x9c, 0x84, 0xb7, 0x36, 0xaf, 0xc2, 0xdf, + 0xac, 0xd2, 0xf4, 0x10, 0x06, 0x70, 0x71, 0x35, 0x02, 0x03, 0x01, 0x00, + 0x01, 0xa3, 0x81, 0xe8, 0x30, 0x81, 0xe5, 0x30, 0x0e, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, + 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2c, 0xd5, + 0x50, 0x41, 0x97, 0x15, 0x8b, 0xf0, 0x8f, 0x36, 0x61, 0x5b, 0x4a, 0xfb, + 0x6b, 0xd9, 0x99, 0xc9, 0x33, 0x92, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, + 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x48, 0xe6, 0x68, 0xf9, 0x2b, + 0xd2, 0xb2, 0x95, 0xd7, 0x47, 0xd8, 0x23, 0x20, 0x10, 0x4f, 0x33, 0x98, + 0x90, 0x9f, 0xd4, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, + 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x3a, 0x06, 0x03, + 0x55, 0x1d, 0x1f, 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, 0xa0, 0x2d, 0xa0, + 0x2b, 0x86, 0x29, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, + 0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x73, 0x65, 0x63, 0x75, + 0x72, 0x65, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x46, 0x06, 0x03, + 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30, 0x3b, 0x06, 0x04, 0x55, + 0x1d, 0x20, 0x00, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, + 0x81, 0x81, 0x00, 0xaf, 0xf3, 0x0e, 0xd6, 0x72, 0xab, 0xc7, 0xa9, 0x97, + 0xca, 0x2a, 0x6b, 0x84, 0x39, 0xde, 0x79, 0xa9, 0xf0, 0x81, 0xe5, 0x08, + 0x67, 0xab, 0xd7, 0x2f, 0x20, 0x02, 0x01, 0x71, 0x0c, 0x04, 0x22, 0xc9, + 0x1e, 0x88, 0x95, 0x03, 0xc9, 0x49, 0x3a, 0xaf, 0x67, 0x08, 0x49, 0xb0, + 0xd5, 0x08, 0xf5, 0x20, 0x3d, 0x80, 0x91, 0xa0, 0xc5, 0x87, 0xa3, 0xfb, + 0xc9, 0xa3, 0x17, 0x91, 0xf9, 0xa8, 0x2f, 0xae, 0xe9, 0x0f, 0xdf, 0x96, + 0x72, 0x0f, 0x75, 0x17, 0x80, 0x5d, 0x78, 0x01, 0x4d, 0x9f, 0x1f, 0x6d, + 0x7b, 0xd8, 0xf5, 0x42, 0x38, 0x23, 0x1a, 0x99, 0x93, 0xf4, 0x83, 0xbe, + 0x3b, 0x35, 0x74, 0xe7, 0x37, 0x13, 0x35, 0x7a, 0xac, 0xb4, 0xb6, 0x90, + 0x82, 0x6c, 0x27, 0xa4, 0xe0, 0xec, 0x9e, 0x35, 0xbd, 0xbf, 0xe5, 0x29, + 0xa1, 0x47, 0x9f, 0x5b, 0x32, 0xfc, 0xe9, 0x99, 0x7d, 0x2b, 0x39, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 146066 (0x23a92) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA + Validity + Not Before: Apr 1 00:00:00 2015 GMT + Not After : Dec 31 23:59:59 2017 GMT + Subject: C=US, O=Google Inc, CN=Google Internet Authority G2 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:9c:2a:04:77:5c:d8:50:91:3a:06:a3:82:e0:d8: + 50:48:bc:89:3f:f1:19:70:1a:88:46:7e:e0:8f:c5: + f1:89:ce:21:ee:5a:fe:61:0d:b7:32:44:89:a0:74: + 0b:53:4f:55:a4:ce:82:62:95:ee:eb:59:5f:c6:e1: + 05:80:12:c4:5e:94:3f:bc:5b:48:38:f4:53:f7:24: + e6:fb:91:e9:15:c4:cf:f4:53:0d:f4:4a:fc:9f:54: + de:7d:be:a0:6b:6f:87:c0:d0:50:1f:28:30:03:40: + da:08:73:51:6c:7f:ff:3a:3c:a7:37:06:8e:bd:4b: + 11:04:eb:7d:24:de:e6:f9:fc:31:71:fb:94:d5:60: + f3:2e:4a:af:42:d2:cb:ea:c4:6a:1a:b2:cc:53:dd: + 15:4b:8b:1f:c8:19:61:1f:cd:9d:a8:3e:63:2b:84: + 35:69:65:84:c8:19:c5:46:22:f8:53:95:be:e3:80: + 4a:10:c6:2a:ec:ba:97:20:11:c7:39:99:10:04:a0: + f0:61:7a:95:25:8c:4e:52:75:e2:b6:ed:08:ca:14: + fc:ce:22:6a:b3:4e:cf:46:03:97:97:03:7e:c0:b1: + de:7b:af:45:33:cf:ba:3e:71:b7:de:f4:25:25:c2: + 0d:35:89:9d:9d:fb:0e:11:79:89:1e:37:c5:af:8e: + 72:69 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Authority Key Identifier: + keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E + + X509v3 Subject Key Identifier: + 4A:DD:06:16:1B:BC:F6:68:B5:76:F5:81:B6:BB:62:1A:BA:5A:81:2F + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + Authority Information Access: + OCSP - URI:http://g.symcd.com + + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 CRL Distribution Points: + + Full Name: + URI:http://g.symcb.com/crls/gtglobal.crl + + X509v3 Certificate Policies: + Policy: 1.3.6.1.4.1.11129.2.5.1 + + Signature Algorithm: sha256WithRSAEncryption + 08:4e:04:a7:80:7f:10:16:43:5e:02:ad:d7:42:80:f4:b0:8e: + d2:ae:b3:eb:11:7d:90:84:18:7d:e7:90:15:fb:49:7f:a8:99: + 05:91:bb:7a:c9:d6:3c:37:18:09:9a:b6:c7:92:20:07:35:33: + 09:e4:28:63:72:0d:b4:e0:32:9c:87:98:c4:1b:76:89:67:c1: + 50:58:b0:13:aa:13:1a:1b:32:a5:be:ea:11:95:4c:48:63:49: + e9:99:5d:20:37:cc:fe:2a:69:51:16:95:4b:a9:de:49:82:c0: + 10:70:f4:2c:f3:ec:bc:24:24:d0:4e:ac:a5:d9:5e:1e:6d:92: + c1:a7:ac:48:35:81:f9:e5:e4:9c:65:69:cd:87:a4:41:50:3f: + 2e:57:a5:91:51:12:58:0e:8c:09:a1:ac:7a:a4:12:a5:27:f3: + 9a:10:97:7d:55:03:06:f7:66:58:5f:5f:64:e1:ab:5d:6d:a5: + 39:48:75:98:4c:29:5a:3a:8d:d3:2b:ca:9c:55:04:bf:f4:e6: + 14:d5:80:ac:26:ed:17:89:a6:93:6c:5c:a4:cc:b8:f0:66:8e: + 64:e3:7d:9a:e2:00:b3:49:c7:e4:0a:aa:dd:5b:83:c7:70:90: + 46:4e:be:d0:db:59:96:6c:2e:f5:16:36:de:71:cc:01:c2:12: + c1:21:c6:16 +-----BEGIN CERTIFICATE----- +MIID8DCCAtigAwIBAgIDAjqSMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMTUwNDAxMDAwMDAwWhcNMTcxMjMxMjM1OTU5WjBJMQswCQYDVQQG +EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy +bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP +VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv +h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE +ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ +EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC +DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7 +qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD +VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov +L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig +JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ +MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEACE4Ep4B/EBZDXgKt +10KA9LCO0q6z6xF9kIQYfeeQFftJf6iZBZG7esnWPDcYCZq2x5IgBzUzCeQoY3IN +tOAynIeYxBt2iWfBUFiwE6oTGhsypb7qEZVMSGNJ6ZldIDfM/ippURaVS6neSYLA +EHD0LPPsvCQk0E6spdleHm2SwaesSDWB+eXknGVpzYekQVA/LlelkVESWA6MCaGs +eqQSpSfzmhCXfVUDBvdmWF9fZOGrXW2lOUh1mEwpWjqN0yvKnFUEv/TmFNWArCbt +F4mmk2xcpMy48GaOZON9muIAs0nH5Aqq3VuDx3CQRk6+0NtZlmwu9RY23nHMAcIS +wSHGFg== +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert2[] = { + 0x30, 0x82, 0x03, 0xf0, 0x30, 0x82, 0x02, 0xd8, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x03, 0x02, 0x3a, 0x92, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, + 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, + 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x30, + 0x34, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, + 0x31, 0x37, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, + 0x5a, 0x30, 0x49, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x0a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, + 0x63, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1c, + 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x65, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x47, 0x32, 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, 0x9c, 0x2a, 0x04, 0x77, 0x5c, 0xd8, 0x50, 0x91, 0x3a, 0x06, 0xa3, + 0x82, 0xe0, 0xd8, 0x50, 0x48, 0xbc, 0x89, 0x3f, 0xf1, 0x19, 0x70, 0x1a, + 0x88, 0x46, 0x7e, 0xe0, 0x8f, 0xc5, 0xf1, 0x89, 0xce, 0x21, 0xee, 0x5a, + 0xfe, 0x61, 0x0d, 0xb7, 0x32, 0x44, 0x89, 0xa0, 0x74, 0x0b, 0x53, 0x4f, + 0x55, 0xa4, 0xce, 0x82, 0x62, 0x95, 0xee, 0xeb, 0x59, 0x5f, 0xc6, 0xe1, + 0x05, 0x80, 0x12, 0xc4, 0x5e, 0x94, 0x3f, 0xbc, 0x5b, 0x48, 0x38, 0xf4, + 0x53, 0xf7, 0x24, 0xe6, 0xfb, 0x91, 0xe9, 0x15, 0xc4, 0xcf, 0xf4, 0x53, + 0x0d, 0xf4, 0x4a, 0xfc, 0x9f, 0x54, 0xde, 0x7d, 0xbe, 0xa0, 0x6b, 0x6f, + 0x87, 0xc0, 0xd0, 0x50, 0x1f, 0x28, 0x30, 0x03, 0x40, 0xda, 0x08, 0x73, + 0x51, 0x6c, 0x7f, 0xff, 0x3a, 0x3c, 0xa7, 0x37, 0x06, 0x8e, 0xbd, 0x4b, + 0x11, 0x04, 0xeb, 0x7d, 0x24, 0xde, 0xe6, 0xf9, 0xfc, 0x31, 0x71, 0xfb, + 0x94, 0xd5, 0x60, 0xf3, 0x2e, 0x4a, 0xaf, 0x42, 0xd2, 0xcb, 0xea, 0xc4, + 0x6a, 0x1a, 0xb2, 0xcc, 0x53, 0xdd, 0x15, 0x4b, 0x8b, 0x1f, 0xc8, 0x19, + 0x61, 0x1f, 0xcd, 0x9d, 0xa8, 0x3e, 0x63, 0x2b, 0x84, 0x35, 0x69, 0x65, + 0x84, 0xc8, 0x19, 0xc5, 0x46, 0x22, 0xf8, 0x53, 0x95, 0xbe, 0xe3, 0x80, + 0x4a, 0x10, 0xc6, 0x2a, 0xec, 0xba, 0x97, 0x20, 0x11, 0xc7, 0x39, 0x99, + 0x10, 0x04, 0xa0, 0xf0, 0x61, 0x7a, 0x95, 0x25, 0x8c, 0x4e, 0x52, 0x75, + 0xe2, 0xb6, 0xed, 0x08, 0xca, 0x14, 0xfc, 0xce, 0x22, 0x6a, 0xb3, 0x4e, + 0xcf, 0x46, 0x03, 0x97, 0x97, 0x03, 0x7e, 0xc0, 0xb1, 0xde, 0x7b, 0xaf, + 0x45, 0x33, 0xcf, 0xba, 0x3e, 0x71, 0xb7, 0xde, 0xf4, 0x25, 0x25, 0xc2, + 0x0d, 0x35, 0x89, 0x9d, 0x9d, 0xfb, 0x0e, 0x11, 0x79, 0x89, 0x1e, 0x37, + 0xc5, 0xaf, 0x8e, 0x72, 0x69, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, + 0xe7, 0x30, 0x81, 0xe4, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, + 0x18, 0x30, 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, + 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, + 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, + 0x4a, 0xdd, 0x06, 0x16, 0x1b, 0xbc, 0xf6, 0x68, 0xb5, 0x76, 0xf5, 0x81, + 0xb6, 0xbb, 0x62, 0x1a, 0xba, 0x5a, 0x81, 0x2f, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, + 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, + 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d, + 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, + 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x35, 0x06, 0x03, + 0x55, 0x1d, 0x1f, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0, + 0x26, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, + 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, + 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, + 0x63, 0x72, 0x6c, 0x30, 0x17, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x10, + 0x30, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, + 0x79, 0x02, 0x05, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, + 0x08, 0x4e, 0x04, 0xa7, 0x80, 0x7f, 0x10, 0x16, 0x43, 0x5e, 0x02, 0xad, + 0xd7, 0x42, 0x80, 0xf4, 0xb0, 0x8e, 0xd2, 0xae, 0xb3, 0xeb, 0x11, 0x7d, + 0x90, 0x84, 0x18, 0x7d, 0xe7, 0x90, 0x15, 0xfb, 0x49, 0x7f, 0xa8, 0x99, + 0x05, 0x91, 0xbb, 0x7a, 0xc9, 0xd6, 0x3c, 0x37, 0x18, 0x09, 0x9a, 0xb6, + 0xc7, 0x92, 0x20, 0x07, 0x35, 0x33, 0x09, 0xe4, 0x28, 0x63, 0x72, 0x0d, + 0xb4, 0xe0, 0x32, 0x9c, 0x87, 0x98, 0xc4, 0x1b, 0x76, 0x89, 0x67, 0xc1, + 0x50, 0x58, 0xb0, 0x13, 0xaa, 0x13, 0x1a, 0x1b, 0x32, 0xa5, 0xbe, 0xea, + 0x11, 0x95, 0x4c, 0x48, 0x63, 0x49, 0xe9, 0x99, 0x5d, 0x20, 0x37, 0xcc, + 0xfe, 0x2a, 0x69, 0x51, 0x16, 0x95, 0x4b, 0xa9, 0xde, 0x49, 0x82, 0xc0, + 0x10, 0x70, 0xf4, 0x2c, 0xf3, 0xec, 0xbc, 0x24, 0x24, 0xd0, 0x4e, 0xac, + 0xa5, 0xd9, 0x5e, 0x1e, 0x6d, 0x92, 0xc1, 0xa7, 0xac, 0x48, 0x35, 0x81, + 0xf9, 0xe5, 0xe4, 0x9c, 0x65, 0x69, 0xcd, 0x87, 0xa4, 0x41, 0x50, 0x3f, + 0x2e, 0x57, 0xa5, 0x91, 0x51, 0x12, 0x58, 0x0e, 0x8c, 0x09, 0xa1, 0xac, + 0x7a, 0xa4, 0x12, 0xa5, 0x27, 0xf3, 0x9a, 0x10, 0x97, 0x7d, 0x55, 0x03, + 0x06, 0xf7, 0x66, 0x58, 0x5f, 0x5f, 0x64, 0xe1, 0xab, 0x5d, 0x6d, 0xa5, + 0x39, 0x48, 0x75, 0x98, 0x4c, 0x29, 0x5a, 0x3a, 0x8d, 0xd3, 0x2b, 0xca, + 0x9c, 0x55, 0x04, 0xbf, 0xf4, 0xe6, 0x14, 0xd5, 0x80, 0xac, 0x26, 0xed, + 0x17, 0x89, 0xa6, 0x93, 0x6c, 0x5c, 0xa4, 0xcc, 0xb8, 0xf0, 0x66, 0x8e, + 0x64, 0xe3, 0x7d, 0x9a, 0xe2, 0x00, 0xb3, 0x49, 0xc7, 0xe4, 0x0a, 0xaa, + 0xdd, 0x5b, 0x83, 0xc7, 0x70, 0x90, 0x46, 0x4e, 0xbe, 0xd0, 0xdb, 0x59, + 0x96, 0x6c, 0x2e, 0xf5, 0x16, 0x36, 0xde, 0x71, 0xcc, 0x01, 0xc2, 0x12, + 0xc1, 0x21, 0xc6, 0x16, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 120033005 (0x7278eed) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=US, O=GTE Corporation, OU=GTE CyberTrust Solutions, Inc., CN=GTE CyberTrust Global Root + Validity + Not Before: Apr 18 16:36:18 2012 GMT + Not After : Aug 13 16:35:17 2018 GMT + Subject: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:a3:04:bb:22:ab:98:3d:57:e8:26:72:9a:b5:79: + d4:29:e2:e1:e8:95:80:b1:b0:e3:5b:8e:2b:29:9a: + 64:df:a1:5d:ed:b0:09:05:6d:db:28:2e:ce:62:a2: + 62:fe:b4:88:da:12:eb:38:eb:21:9d:c0:41:2b:01: + 52:7b:88:77:d3:1c:8f:c7:ba:b9:88:b5:6a:09:e7: + 73:e8:11:40:a7:d1:cc:ca:62:8d:2d:e5:8f:0b:a6: + 50:d2:a8:50:c3:28:ea:f5:ab:25:87:8a:9a:96:1c: + a9:67:b8:3f:0c:d5:f7:f9:52:13:2f:c2:1b:d5:70: + 70:f0:8f:c0:12:ca:06:cb:9a:e1:d9:ca:33:7a:77: + d6:f8:ec:b9:f1:68:44:42:48:13:d2:c0:c2:a4:ae: + 5e:60:fe:b6:a6:05:fc:b4:dd:07:59:02:d4:59:18: + 98:63:f5:a5:63:e0:90:0c:7d:5d:b2:06:7a:f3:85: + ea:eb:d4:03:ae:5e:84:3e:5f:ff:15:ed:69:bc:f9: + 39:36:72:75:cf:77:52:4d:f3:c9:90:2c:b9:3d:e5: + c9:23:53:3f:1f:24:98:21:5c:07:99:29:bd:c6:3a: + ec:e7:6e:86:3a:6b:97:74:63:33:bd:68:18:31:f0: + 78:8d:76:bf:fc:9e:8e:5d:2a:86:a7:4d:90:dc:27: + 1a:39 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:3 + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: http://cybertrust.omniroot.com/repository + + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Authority Key Identifier: + DirName:/C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Global Root + serial:01:A5 + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://www.public-trust.com/cgi-bin/CRL/2018/cdp.crl + + Signature Algorithm: sha1WithRSAEncryption + 93:1d:fe:8b:ae:46:ec:cb:a9:0f:ab:e5:ef:ca:b2:68:16:68: + d8:8f:fa:13:a9:af:b3:cb:2d:e7:4b:6e:8e:69:2a:c2:2b:10: + 0a:8d:f6:ae:73:b6:b9:fb:14:fd:5f:6d:b8:50:b6:c4:8a:d6: + 40:7e:d7:c3:cb:73:dc:c9:5d:5b:af:b0:41:b5:37:eb:ea:dc: + 20:91:c4:34:6a:f4:a1:f3:96:9d:37:86:97:e1:71:a4:dd:7d: + fa:44:84:94:ae:d7:09:04:22:76:0f:64:51:35:a9:24:0f:f9: + 0b:db:32:da:c2:fe:c1:b9:2a:5c:7a:27:13:ca:b1:48:3a:71: + d0:43 +-----BEGIN CERTIFICATE----- +MIIEFTCCA36gAwIBAgIEByeO7TANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQGEwJV +UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU +cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds +b2JhbCBSb290MB4XDTEyMDQxODE2MzYxOFoXDTE4MDgxMzE2MzUxN1owWjELMAkG +A1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVz +dDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKrmD1X6CZymrV51Cni4eiVgLGw41uO +KymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsBUnuId9Mcj8e6uYi1agnn +c+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/CG9VwcPCP +wBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPg +kAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFc +B5kpvcY67Oduhjprl3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaOCAUcw +ggFDMBIGA1UdEwEB/wQIMAYBAf8CAQMwSgYDVR0gBEMwQTA/BgRVHSAAMDcwNQYI +KwYBBQUHAgEWKWh0dHA6Ly9jeWJlcnRydXN0Lm9tbmlyb290LmNvbS9yZXBvc2l0 +b3J5MA4GA1UdDwEB/wQEAwIBBjCBiQYDVR0jBIGBMH+heaR3MHUxCzAJBgNVBAYT +AlVTMRgwFgYDVQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJl +clRydXN0IFNvbHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3Qg +R2xvYmFsIFJvb3SCAgGlMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly93d3cucHVi +bGljLXRydXN0LmNvbS9jZ2ktYmluL0NSTC8yMDE4L2NkcC5jcmwwDQYJKoZIhvcN +AQEFBQADgYEAkx3+i65G7MupD6vl78qyaBZo2I/6E6mvs8st50tujmkqwisQCo32 +rnO2ufsU/V9tuFC2xIrWQH7Xw8tz3MldW6+wQbU36+rcIJHENGr0ofOWnTeGl+Fx +pN19+kSElK7XCQQidg9kUTWpJA/5C9sy2sL+wbkqXHonE8qxSDpx0EM= +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert3[] = { + 0x30, 0x82, 0x04, 0x15, 0x30, 0x82, 0x03, 0x7e, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x04, 0x07, 0x27, 0x8e, 0xed, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x75, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0f, + 0x47, 0x54, 0x45, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x13, 0x1e, 0x47, 0x54, 0x45, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, + 0x72, 0x75, 0x73, 0x74, 0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x23, 0x30, 0x21, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x47, 0x54, 0x45, 0x20, 0x43, + 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, + 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, + 0x0d, 0x31, 0x32, 0x30, 0x34, 0x31, 0x38, 0x31, 0x36, 0x33, 0x36, 0x31, + 0x38, 0x5a, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x38, 0x31, 0x33, 0x31, 0x36, + 0x33, 0x35, 0x31, 0x37, 0x5a, 0x30, 0x5a, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49, 0x45, 0x31, 0x12, 0x30, 0x10, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, 0x42, 0x61, 0x6c, 0x74, 0x69, + 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, + 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x20, 0x43, 0x79, + 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, + 0x74, 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, 0xa3, 0x04, + 0xbb, 0x22, 0xab, 0x98, 0x3d, 0x57, 0xe8, 0x26, 0x72, 0x9a, 0xb5, 0x79, + 0xd4, 0x29, 0xe2, 0xe1, 0xe8, 0x95, 0x80, 0xb1, 0xb0, 0xe3, 0x5b, 0x8e, + 0x2b, 0x29, 0x9a, 0x64, 0xdf, 0xa1, 0x5d, 0xed, 0xb0, 0x09, 0x05, 0x6d, + 0xdb, 0x28, 0x2e, 0xce, 0x62, 0xa2, 0x62, 0xfe, 0xb4, 0x88, 0xda, 0x12, + 0xeb, 0x38, 0xeb, 0x21, 0x9d, 0xc0, 0x41, 0x2b, 0x01, 0x52, 0x7b, 0x88, + 0x77, 0xd3, 0x1c, 0x8f, 0xc7, 0xba, 0xb9, 0x88, 0xb5, 0x6a, 0x09, 0xe7, + 0x73, 0xe8, 0x11, 0x40, 0xa7, 0xd1, 0xcc, 0xca, 0x62, 0x8d, 0x2d, 0xe5, + 0x8f, 0x0b, 0xa6, 0x50, 0xd2, 0xa8, 0x50, 0xc3, 0x28, 0xea, 0xf5, 0xab, + 0x25, 0x87, 0x8a, 0x9a, 0x96, 0x1c, 0xa9, 0x67, 0xb8, 0x3f, 0x0c, 0xd5, + 0xf7, 0xf9, 0x52, 0x13, 0x2f, 0xc2, 0x1b, 0xd5, 0x70, 0x70, 0xf0, 0x8f, + 0xc0, 0x12, 0xca, 0x06, 0xcb, 0x9a, 0xe1, 0xd9, 0xca, 0x33, 0x7a, 0x77, + 0xd6, 0xf8, 0xec, 0xb9, 0xf1, 0x68, 0x44, 0x42, 0x48, 0x13, 0xd2, 0xc0, + 0xc2, 0xa4, 0xae, 0x5e, 0x60, 0xfe, 0xb6, 0xa6, 0x05, 0xfc, 0xb4, 0xdd, + 0x07, 0x59, 0x02, 0xd4, 0x59, 0x18, 0x98, 0x63, 0xf5, 0xa5, 0x63, 0xe0, + 0x90, 0x0c, 0x7d, 0x5d, 0xb2, 0x06, 0x7a, 0xf3, 0x85, 0xea, 0xeb, 0xd4, + 0x03, 0xae, 0x5e, 0x84, 0x3e, 0x5f, 0xff, 0x15, 0xed, 0x69, 0xbc, 0xf9, + 0x39, 0x36, 0x72, 0x75, 0xcf, 0x77, 0x52, 0x4d, 0xf3, 0xc9, 0x90, 0x2c, + 0xb9, 0x3d, 0xe5, 0xc9, 0x23, 0x53, 0x3f, 0x1f, 0x24, 0x98, 0x21, 0x5c, + 0x07, 0x99, 0x29, 0xbd, 0xc6, 0x3a, 0xec, 0xe7, 0x6e, 0x86, 0x3a, 0x6b, + 0x97, 0x74, 0x63, 0x33, 0xbd, 0x68, 0x18, 0x31, 0xf0, 0x78, 0x8d, 0x76, + 0xbf, 0xfc, 0x9e, 0x8e, 0x5d, 0x2a, 0x86, 0xa7, 0x4d, 0x90, 0xdc, 0x27, + 0x1a, 0x39, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x47, 0x30, + 0x82, 0x01, 0x43, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, + 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x03, 0x30, + 0x4a, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x43, 0x30, 0x41, 0x30, 0x3f, + 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x37, 0x30, 0x35, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x29, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, + 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x81, 0x89, 0x06, 0x03, + 0x55, 0x1d, 0x23, 0x04, 0x81, 0x81, 0x30, 0x7f, 0xa1, 0x79, 0xa4, 0x77, + 0x30, 0x75, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x13, 0x0f, 0x47, 0x54, 0x45, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x13, 0x1e, 0x47, 0x54, 0x45, 0x20, 0x43, 0x79, 0x62, 0x65, + 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x53, 0x6f, 0x6c, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x23, + 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1a, 0x47, 0x54, 0x45, + 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x82, + 0x02, 0x01, 0xa5, 0x30, 0x45, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3e, + 0x30, 0x3c, 0x30, 0x3a, 0xa0, 0x38, 0xa0, 0x36, 0x86, 0x34, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x63, 0x67, 0x69, 0x2d, 0x62, 0x69, 0x6e, 0x2f, 0x43, 0x52, + 0x4c, 0x2f, 0x32, 0x30, 0x31, 0x38, 0x2f, 0x63, 0x64, 0x70, 0x2e, 0x63, + 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x93, 0x1d, 0xfe, + 0x8b, 0xae, 0x46, 0xec, 0xcb, 0xa9, 0x0f, 0xab, 0xe5, 0xef, 0xca, 0xb2, + 0x68, 0x16, 0x68, 0xd8, 0x8f, 0xfa, 0x13, 0xa9, 0xaf, 0xb3, 0xcb, 0x2d, + 0xe7, 0x4b, 0x6e, 0x8e, 0x69, 0x2a, 0xc2, 0x2b, 0x10, 0x0a, 0x8d, 0xf6, + 0xae, 0x73, 0xb6, 0xb9, 0xfb, 0x14, 0xfd, 0x5f, 0x6d, 0xb8, 0x50, 0xb6, + 0xc4, 0x8a, 0xd6, 0x40, 0x7e, 0xd7, 0xc3, 0xcb, 0x73, 0xdc, 0xc9, 0x5d, + 0x5b, 0xaf, 0xb0, 0x41, 0xb5, 0x37, 0xeb, 0xea, 0xdc, 0x20, 0x91, 0xc4, + 0x34, 0x6a, 0xf4, 0xa1, 0xf3, 0x96, 0x9d, 0x37, 0x86, 0x97, 0xe1, 0x71, + 0xa4, 0xdd, 0x7d, 0xfa, 0x44, 0x84, 0x94, 0xae, 0xd7, 0x09, 0x04, 0x22, + 0x76, 0x0f, 0x64, 0x51, 0x35, 0xa9, 0x24, 0x0f, 0xf9, 0x0b, 0xdb, 0x32, + 0xda, 0xc2, 0xfe, 0xc1, 0xb9, 0x2a, 0x5c, 0x7a, 0x27, 0x13, 0xca, 0xb1, + 0x48, 0x3a, 0x71, 0xd0, 0x43, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 146039 (0x23a77) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA + Validity + Not Before: Aug 29 21:39:32 2014 GMT + Not After : May 20 21:39:32 2022 GMT + Subject: C=US, O=GeoTrust Inc., CN=RapidSSL SHA256 CA - G3 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:af:54:9b:d9:58:5d:1e:2c:56:c6:d5:e8:7f:f4: + 7d:16:03:ff:d0:8b:5a:e4:8e:a7:dd:54:2e:d4:04: + c0:5d:98:9c:8d:90:0f:bc:10:65:5f:da:9a:d6:44: + 7c:c0:9f:b5:e9:4a:8c:0b:06:43:04:bb:f4:96:e2: + 26:f6:61:01:91:66:31:22:c3:34:34:5f:3f:3f:91: + 2f:44:5f:dc:c7:14:b6:03:9f:86:4b:0e:a3:ff:a0: + 80:02:83:c3:d3:1f:69:52:d6:9d:64:0f:c9:83:e7: + 1b:c4:70:ac:94:e7:c3:a4:6a:2c:bd:b8:9e:69:d8: + be:0a:8f:16:63:5a:68:71:80:7b:30:de:15:04:bf: + cc:d3:bf:3e:48:05:55:7a:b3:d7:10:0c:03:fc:9b: + fd:08:a7:8c:8c:db:a7:8e:f1:1e:63:dc:b3:01:2f: + 7f:af:57:c3:3c:48:a7:83:68:21:a7:2f:e7:a7:3f: + f0:b5:0c:fc:f5:84:d1:53:bc:0e:72:4f:60:0c:42: + b8:98:ad:19:88:57:d7:04:ec:87:bf:7e:87:4e:a3: + 21:f9:53:fd:36:98:48:8d:d6:f8:bb:48:f2:29:c8: + 64:d1:cc:54:48:53:8b:af:b7:65:1e:bf:29:33:29: + d9:29:60:48:f8:ff:91:bc:57:58:e5:35:2e:bb:69: + b6:59 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Authority Key Identifier: + keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E + + X509v3 Subject Key Identifier: + C3:9C:F3:FC:D3:46:08:34:BB:CE:46:7F:A0:7C:5B:F3:E2:08:CB:59 + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 CRL Distribution Points: + + Full Name: + URI:http://g.symcb.com/crls/gtglobal.crl + + Authority Information Access: + OCSP - URI:http://g.symcd.com + + X509v3 Certificate Policies: + Policy: 2.16.840.1.113733.1.7.54 + CPS: http://www.geotrust.com/resources/cps + + Signature Algorithm: sha256WithRSAEncryption + a3:58:1e:c6:43:32:ac:ac:2f:93:78:b7:ea:ae:54:40:47:2d: + 7e:78:8d:50:f6:f8:66:ac:d6:4f:73:d6:44:ef:af:0b:cc:5b: + c1:f4:4f:9a:8f:49:7e:60:af:c2:27:c7:16:f1:fb:93:81:90: + a9:7c:ef:6f:7e:6e:45:94:16:84:bd:ec:49:f1:c4:0e:f4:af: + 04:59:83:87:0f:2c:3b:97:c3:5a:12:9b:7b:04:35:7b:a3:95: + 33:08:7b:93:71:22:42:b3:a9:d9:6f:4f:81:92:fc:07:b6:79: + bc:84:4a:9d:77:09:f1:c5:89:f2:f0:b4:9c:54:aa:12:7b:0d: + ba:4f:ef:93:19:ec:ef:7d:4e:61:a3:8e:76:9c:59:cf:8c:94: + b1:84:97:f7:1a:b9:07:b8:b2:c6:4f:13:79:db:bf:4f:51:1b: + 7f:69:0d:51:2a:c1:d6:15:ff:37:51:34:65:51:f4:1e:be:38: + 6a:ec:0e:ab:bf:3d:7b:39:05:7b:f4:f3:fb:1a:a1:d0:c8:7e: + 4e:64:8d:cd:8c:61:55:90:fe:3a:ca:5d:25:0f:f8:1d:a3:4a: + 74:56:4f:1a:55:40:70:75:25:a6:33:2e:ba:4b:a5:5d:53:9a: + 0d:30:e1:8d:5f:61:2c:af:cc:ef:b0:99:a1:80:ff:0b:f2:62: + 4c:70:26:98 +-----BEGIN CERTIFICATE----- +MIIEJTCCAw2gAwIBAgIDAjp3MA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMTQwODI5MjEzOTMyWhcNMjIwNTIwMjEzOTMyWjBHMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXUmFwaWRTU0wg +U0hBMjU2IENBIC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCv +VJvZWF0eLFbG1eh/9H0WA//Qi1rkjqfdVC7UBMBdmJyNkA+8EGVf2prWRHzAn7Xp +SowLBkMEu/SW4ib2YQGRZjEiwzQ0Xz8/kS9EX9zHFLYDn4ZLDqP/oIACg8PTH2lS +1p1kD8mD5xvEcKyU58Okaiy9uJ5p2L4KjxZjWmhxgHsw3hUEv8zTvz5IBVV6s9cQ +DAP8m/0Ip4yM26eO8R5j3LMBL3+vV8M8SKeDaCGnL+enP/C1DPz1hNFTvA5yT2AM +QriYrRmIV9cE7Ie/fodOoyH5U/02mEiN1vi7SPIpyGTRzFRIU4uvt2UevykzKdkp +YEj4/5G8V1jlNS67abZZAgMBAAGjggEdMIIBGTAfBgNVHSMEGDAWgBTAephojYn7 +qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUw5zz/NNGCDS7zkZ/oHxb8+IIy1kwEgYD +VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwNQYDVR0fBC4wLDAqoCig +JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMC4GCCsGAQUF +BwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDovL2cuc3ltY2QuY29tMEwGA1UdIARF +MEMwQQYKYIZIAYb4RQEHNjAzMDEGCCsGAQUFBwIBFiVodHRwOi8vd3d3Lmdlb3Ry +dXN0LmNvbS9yZXNvdXJjZXMvY3BzMA0GCSqGSIb3DQEBCwUAA4IBAQCjWB7GQzKs +rC+TeLfqrlRARy1+eI1Q9vhmrNZPc9ZE768LzFvB9E+aj0l+YK/CJ8cW8fuTgZCp +fO9vfm5FlBaEvexJ8cQO9K8EWYOHDyw7l8NaEpt7BDV7o5UzCHuTcSJCs6nZb0+B +kvwHtnm8hEqddwnxxYny8LScVKoSew26T++TGezvfU5ho452nFnPjJSxhJf3GrkH +uLLGTxN5279PURt/aQ1RKsHWFf83UTRlUfQevjhq7A6rvz17OQV79PP7GqHQyH5O +ZI3NjGFVkP46yl0lD/gdo0p0Vk8aVUBwdSWmMy66S6VdU5oNMOGNX2Esr8zvsJmh +gP8L8mJMcCaY +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert4[] = { + 0x30, 0x82, 0x04, 0x25, 0x30, 0x82, 0x03, 0x0d, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x03, 0x02, 0x3a, 0x77, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, + 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, + 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30, + 0x38, 0x32, 0x39, 0x32, 0x31, 0x33, 0x39, 0x33, 0x32, 0x5a, 0x17, 0x0d, + 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x31, 0x33, 0x39, 0x33, 0x32, + 0x5a, 0x30, 0x47, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x17, 0x52, 0x61, 0x70, 0x69, 0x64, 0x53, 0x53, 0x4c, 0x20, + 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, + 0x47, 0x33, 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, 0xaf, + 0x54, 0x9b, 0xd9, 0x58, 0x5d, 0x1e, 0x2c, 0x56, 0xc6, 0xd5, 0xe8, 0x7f, + 0xf4, 0x7d, 0x16, 0x03, 0xff, 0xd0, 0x8b, 0x5a, 0xe4, 0x8e, 0xa7, 0xdd, + 0x54, 0x2e, 0xd4, 0x04, 0xc0, 0x5d, 0x98, 0x9c, 0x8d, 0x90, 0x0f, 0xbc, + 0x10, 0x65, 0x5f, 0xda, 0x9a, 0xd6, 0x44, 0x7c, 0xc0, 0x9f, 0xb5, 0xe9, + 0x4a, 0x8c, 0x0b, 0x06, 0x43, 0x04, 0xbb, 0xf4, 0x96, 0xe2, 0x26, 0xf6, + 0x61, 0x01, 0x91, 0x66, 0x31, 0x22, 0xc3, 0x34, 0x34, 0x5f, 0x3f, 0x3f, + 0x91, 0x2f, 0x44, 0x5f, 0xdc, 0xc7, 0x14, 0xb6, 0x03, 0x9f, 0x86, 0x4b, + 0x0e, 0xa3, 0xff, 0xa0, 0x80, 0x02, 0x83, 0xc3, 0xd3, 0x1f, 0x69, 0x52, + 0xd6, 0x9d, 0x64, 0x0f, 0xc9, 0x83, 0xe7, 0x1b, 0xc4, 0x70, 0xac, 0x94, + 0xe7, 0xc3, 0xa4, 0x6a, 0x2c, 0xbd, 0xb8, 0x9e, 0x69, 0xd8, 0xbe, 0x0a, + 0x8f, 0x16, 0x63, 0x5a, 0x68, 0x71, 0x80, 0x7b, 0x30, 0xde, 0x15, 0x04, + 0xbf, 0xcc, 0xd3, 0xbf, 0x3e, 0x48, 0x05, 0x55, 0x7a, 0xb3, 0xd7, 0x10, + 0x0c, 0x03, 0xfc, 0x9b, 0xfd, 0x08, 0xa7, 0x8c, 0x8c, 0xdb, 0xa7, 0x8e, + 0xf1, 0x1e, 0x63, 0xdc, 0xb3, 0x01, 0x2f, 0x7f, 0xaf, 0x57, 0xc3, 0x3c, + 0x48, 0xa7, 0x83, 0x68, 0x21, 0xa7, 0x2f, 0xe7, 0xa7, 0x3f, 0xf0, 0xb5, + 0x0c, 0xfc, 0xf5, 0x84, 0xd1, 0x53, 0xbc, 0x0e, 0x72, 0x4f, 0x60, 0x0c, + 0x42, 0xb8, 0x98, 0xad, 0x19, 0x88, 0x57, 0xd7, 0x04, 0xec, 0x87, 0xbf, + 0x7e, 0x87, 0x4e, 0xa3, 0x21, 0xf9, 0x53, 0xfd, 0x36, 0x98, 0x48, 0x8d, + 0xd6, 0xf8, 0xbb, 0x48, 0xf2, 0x29, 0xc8, 0x64, 0xd1, 0xcc, 0x54, 0x48, + 0x53, 0x8b, 0xaf, 0xb7, 0x65, 0x1e, 0xbf, 0x29, 0x33, 0x29, 0xd9, 0x29, + 0x60, 0x48, 0xf8, 0xff, 0x91, 0xbc, 0x57, 0x58, 0xe5, 0x35, 0x2e, 0xbb, + 0x69, 0xb6, 0x59, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x1d, + 0x30, 0x82, 0x01, 0x19, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, + 0x18, 0x30, 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, + 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, + 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, + 0xc3, 0x9c, 0xf3, 0xfc, 0xd3, 0x46, 0x08, 0x34, 0xbb, 0xce, 0x46, 0x7f, + 0xa0, 0x7c, 0x5b, 0xf3, 0xe2, 0x08, 0xcb, 0x59, 0x30, 0x12, 0x06, 0x03, + 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, + 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, + 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x35, 0x06, 0x03, + 0x55, 0x1d, 0x1f, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0, + 0x26, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, + 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, + 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, + 0x63, 0x72, 0x6c, 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x01, 0x01, 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, + 0x63, 0x6f, 0x6d, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, + 0x30, 0x43, 0x30, 0x41, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, + 0x45, 0x01, 0x07, 0x36, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, + 0x03, 0x82, 0x01, 0x01, 0x00, 0xa3, 0x58, 0x1e, 0xc6, 0x43, 0x32, 0xac, + 0xac, 0x2f, 0x93, 0x78, 0xb7, 0xea, 0xae, 0x54, 0x40, 0x47, 0x2d, 0x7e, + 0x78, 0x8d, 0x50, 0xf6, 0xf8, 0x66, 0xac, 0xd6, 0x4f, 0x73, 0xd6, 0x44, + 0xef, 0xaf, 0x0b, 0xcc, 0x5b, 0xc1, 0xf4, 0x4f, 0x9a, 0x8f, 0x49, 0x7e, + 0x60, 0xaf, 0xc2, 0x27, 0xc7, 0x16, 0xf1, 0xfb, 0x93, 0x81, 0x90, 0xa9, + 0x7c, 0xef, 0x6f, 0x7e, 0x6e, 0x45, 0x94, 0x16, 0x84, 0xbd, 0xec, 0x49, + 0xf1, 0xc4, 0x0e, 0xf4, 0xaf, 0x04, 0x59, 0x83, 0x87, 0x0f, 0x2c, 0x3b, + 0x97, 0xc3, 0x5a, 0x12, 0x9b, 0x7b, 0x04, 0x35, 0x7b, 0xa3, 0x95, 0x33, + 0x08, 0x7b, 0x93, 0x71, 0x22, 0x42, 0xb3, 0xa9, 0xd9, 0x6f, 0x4f, 0x81, + 0x92, 0xfc, 0x07, 0xb6, 0x79, 0xbc, 0x84, 0x4a, 0x9d, 0x77, 0x09, 0xf1, + 0xc5, 0x89, 0xf2, 0xf0, 0xb4, 0x9c, 0x54, 0xaa, 0x12, 0x7b, 0x0d, 0xba, + 0x4f, 0xef, 0x93, 0x19, 0xec, 0xef, 0x7d, 0x4e, 0x61, 0xa3, 0x8e, 0x76, + 0x9c, 0x59, 0xcf, 0x8c, 0x94, 0xb1, 0x84, 0x97, 0xf7, 0x1a, 0xb9, 0x07, + 0xb8, 0xb2, 0xc6, 0x4f, 0x13, 0x79, 0xdb, 0xbf, 0x4f, 0x51, 0x1b, 0x7f, + 0x69, 0x0d, 0x51, 0x2a, 0xc1, 0xd6, 0x15, 0xff, 0x37, 0x51, 0x34, 0x65, + 0x51, 0xf4, 0x1e, 0xbe, 0x38, 0x6a, 0xec, 0x0e, 0xab, 0xbf, 0x3d, 0x7b, + 0x39, 0x05, 0x7b, 0xf4, 0xf3, 0xfb, 0x1a, 0xa1, 0xd0, 0xc8, 0x7e, 0x4e, + 0x64, 0x8d, 0xcd, 0x8c, 0x61, 0x55, 0x90, 0xfe, 0x3a, 0xca, 0x5d, 0x25, + 0x0f, 0xf8, 0x1d, 0xa3, 0x4a, 0x74, 0x56, 0x4f, 0x1a, 0x55, 0x40, 0x70, + 0x75, 0x25, 0xa6, 0x33, 0x2e, 0xba, 0x4b, 0xa5, 0x5d, 0x53, 0x9a, 0x0d, + 0x30, 0xe1, 0x8d, 0x5f, 0x61, 0x2c, 0xaf, 0xcc, 0xef, 0xb0, 0x99, 0xa1, + 0x80, 0xff, 0x0b, 0xf2, 0x62, 0x4c, 0x70, 0x26, 0x98, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 146040 (0x23a78) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA + Validity + Not Before: Aug 29 22:24:58 2014 GMT + Not After : May 20 22:24:58 2022 GMT + Subject: C=US, O=GeoTrust Inc., OU=Domain Validated SSL, CN=GeoTrust DV SSL CA - G4 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:df:41:94:7a:da:f7:e4:31:43:b6:ea:01:1b:5c: + ce:63:ea:fa:6d:a3:d9:6a:ee:2d:9a:75:f9:d5:9c: + 5b:bd:34:df:d8:1c:c9:6d:d8:04:88:da:6e:b5:b7: + b5:f0:30:ae:40:d6:5d:fa:c4:53:c1:d4:22:9d:04: + 4e:11:a6:95:d5:45:7c:41:05:58:e0:4c:dd:f9:ee: + 55:bd:5f:46:dc:ad:13:08:9d:2c:e4:f7:82:e6:07: + 2b:9e:0e:8c:34:a1:ce:c4:a1:e0:81:70:86:00:06: + 3f:2d:ea:7c:9b:28:ae:1b:28:8b:39:09:d3:e7:f0: + 45:a4:b1:ba:11:67:90:55:7b:8f:de:ed:38:5c:a1: + e1:e3:83:c4:c3:72:91:4f:98:ee:1c:c2:80:aa:64: + a5:3e:83:62:1c:cc:e0:9e:f8:5a:c0:13:12:7d:a2: + a7:8b:a3:e7:9f:2a:d7:9b:ca:cb:ed:97:01:9c:28: + 84:51:04:50:41:bc:b4:fc:78:e9:1b:cf:14:ea:1f: + 0f:fc:2e:01:32:8d:b6:35:cb:0a:18:3b:ec:5a:3e: + 3c:1b:d3:99:43:1e:2f:f7:bd:f3:5b:12:b9:07:5e: + ed:3e:d1:a9:87:cc:77:72:27:d4:d9:75:a2:63:4b: + 93:36:bd:e5:5c:d7:bf:5f:79:0d:b3:32:a7:0b:b2: + 63:23 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Authority Key Identifier: + keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E + + X509v3 Subject Key Identifier: + 0B:50:EC:77:EF:2A:9B:FF:EC:03:A1:0A:FF:AD:C6:E4:2A:18:C7:3E + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 CRL Distribution Points: + + Full Name: + URI:http://g.symcb.com/crls/gtglobal.crl + + Authority Information Access: + OCSP - URI:http://g.symcd.com + + X509v3 Certificate Policies: + Policy: 2.16.840.1.113733.1.7.54 + CPS: http://www.geotrust.com/resources/cps + + Signature Algorithm: sha256WithRSAEncryption + 33:24:d5:90:aa:29:0c:35:b9:2f:c3:c7:42:93:c0:c6:10:4b: + 03:08:76:84:10:a2:e0:e7:53:12:27:f2:0a:da:7f:3a:dc:fd: + 5c:79:5a:8f:17:74:43:53:b1:d5:d1:5d:59:b9:a6:84:64:ca: + f1:3a:0a:59:96:10:bf:a9:81:57:8b:5c:87:dc:7f:e3:e4:bb: + 05:7a:a0:32:09:13:4e:10:81:28:1f:9c:03:62:bc:f4:01:b5: + 29:83:46:07:b9:e7:b8:5d:c8:e9:d1:dd:ad:3b:f8:34:db:c1: + d1:95:a9:91:18:ed:3c:2c:37:11:4d:cc:fe:53:3e:50:43:f9: + c3:56:41:ac:53:9b:6c:05:b2:9a:e2:e0:59:57:30:32:b6:26: + 4e:13:25:cd:fa:48:70:0f:75:55:60:11:f5:3b:d5:5e:5a:3c: + 8b:5b:0f:0f:62:42:48:61:85:8b:10:f4:c1:88:bf:7f:5f:8a: + c2:d7:cd:2b:94:5c:1f:34:4a:08:af:eb:ae:89:a8:48:75:55: + 95:1d:bb:c0:9a:01:b9:f4:03:22:3e:d4:e6:52:30:0d:67:b9: + c0:91:fd:2d:4c:30:8e:bd:8c:a5:04:91:bb:a4:ab:7f:0f:d8: + 6f:f0:66:00:c9:a3:5c:f5:b0:8f:83:e6:9c:5a:e6:b6:b9:c5: + bc:be:e4:02 +-----BEGIN CERTIFICATE----- +MIIERDCCAyygAwIBAgIDAjp4MA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMTQwODI5MjIyNDU4WhcNMjIwNTIwMjIyNDU4WjBmMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UECxMURG9tYWluIFZh +bGlkYXRlZCBTU0wxIDAeBgNVBAMTF0dlb1RydXN0IERWIFNTTCBDQSAtIEc0MIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA30GUetr35DFDtuoBG1zOY+r6 +baPZau4tmnX51ZxbvTTf2BzJbdgEiNputbe18DCuQNZd+sRTwdQinQROEaaV1UV8 +QQVY4Ezd+e5VvV9G3K0TCJ0s5PeC5gcrng6MNKHOxKHggXCGAAY/Lep8myiuGyiL +OQnT5/BFpLG6EWeQVXuP3u04XKHh44PEw3KRT5juHMKAqmSlPoNiHMzgnvhawBMS +faKni6PnnyrXm8rL7ZcBnCiEUQRQQby0/HjpG88U6h8P/C4BMo22NcsKGDvsWj48 +G9OZQx4v973zWxK5B17tPtGph8x3cifU2XWiY0uTNr3lXNe/X3kNszKnC7JjIwID +AQABo4IBHTCCARkwHwYDVR0jBBgwFoAUwHqYaI2J+6sFZAwRfap9ZbjKzE4wHQYD +VR0OBBYEFAtQ7HfvKpv/7AOhCv+txuQqGMc+MBIGA1UdEwEB/wQIMAYBAf8CAQAw +DgYDVR0PAQH/BAQDAgEGMDUGA1UdHwQuMCwwKqAooCaGJGh0dHA6Ly9nLnN5bWNi +LmNvbS9jcmxzL2d0Z2xvYmFsLmNybDAuBggrBgEFBQcBAQQiMCAwHgYIKwYBBQUH +MAGGEmh0dHA6Ly9nLnN5bWNkLmNvbTBMBgNVHSAERTBDMEEGCmCGSAGG+EUBBzYw +MzAxBggrBgEFBQcCARYlaHR0cDovL3d3dy5nZW90cnVzdC5jb20vcmVzb3VyY2Vz +L2NwczANBgkqhkiG9w0BAQsFAAOCAQEAMyTVkKopDDW5L8PHQpPAxhBLAwh2hBCi +4OdTEifyCtp/Otz9XHlajxd0Q1Ox1dFdWbmmhGTK8ToKWZYQv6mBV4tch9x/4+S7 +BXqgMgkTThCBKB+cA2K89AG1KYNGB7nnuF3I6dHdrTv4NNvB0ZWpkRjtPCw3EU3M +/lM+UEP5w1ZBrFObbAWymuLgWVcwMrYmThMlzfpIcA91VWAR9TvVXlo8i1sPD2JC +SGGFixD0wYi/f1+KwtfNK5RcHzRKCK/rromoSHVVlR27wJoBufQDIj7U5lIwDWe5 +wJH9LUwwjr2MpQSRu6Srfw/Yb/BmAMmjXPWwj4PmnFrmtrnFvL7kAg== +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert5[] = { + 0x30, 0x82, 0x04, 0x44, 0x30, 0x82, 0x03, 0x2c, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x03, 0x02, 0x3a, 0x78, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, + 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, + 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30, + 0x38, 0x32, 0x39, 0x32, 0x32, 0x32, 0x34, 0x35, 0x38, 0x5a, 0x17, 0x0d, + 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x32, 0x32, 0x34, 0x35, 0x38, + 0x5a, 0x30, 0x66, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x13, 0x14, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x20, 0x53, 0x53, 0x4c, 0x31, + 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x47, 0x65, + 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x44, 0x56, 0x20, 0x53, 0x53, + 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x34, 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, 0xdf, 0x41, 0x94, 0x7a, 0xda, 0xf7, + 0xe4, 0x31, 0x43, 0xb6, 0xea, 0x01, 0x1b, 0x5c, 0xce, 0x63, 0xea, 0xfa, + 0x6d, 0xa3, 0xd9, 0x6a, 0xee, 0x2d, 0x9a, 0x75, 0xf9, 0xd5, 0x9c, 0x5b, + 0xbd, 0x34, 0xdf, 0xd8, 0x1c, 0xc9, 0x6d, 0xd8, 0x04, 0x88, 0xda, 0x6e, + 0xb5, 0xb7, 0xb5, 0xf0, 0x30, 0xae, 0x40, 0xd6, 0x5d, 0xfa, 0xc4, 0x53, + 0xc1, 0xd4, 0x22, 0x9d, 0x04, 0x4e, 0x11, 0xa6, 0x95, 0xd5, 0x45, 0x7c, + 0x41, 0x05, 0x58, 0xe0, 0x4c, 0xdd, 0xf9, 0xee, 0x55, 0xbd, 0x5f, 0x46, + 0xdc, 0xad, 0x13, 0x08, 0x9d, 0x2c, 0xe4, 0xf7, 0x82, 0xe6, 0x07, 0x2b, + 0x9e, 0x0e, 0x8c, 0x34, 0xa1, 0xce, 0xc4, 0xa1, 0xe0, 0x81, 0x70, 0x86, + 0x00, 0x06, 0x3f, 0x2d, 0xea, 0x7c, 0x9b, 0x28, 0xae, 0x1b, 0x28, 0x8b, + 0x39, 0x09, 0xd3, 0xe7, 0xf0, 0x45, 0xa4, 0xb1, 0xba, 0x11, 0x67, 0x90, + 0x55, 0x7b, 0x8f, 0xde, 0xed, 0x38, 0x5c, 0xa1, 0xe1, 0xe3, 0x83, 0xc4, + 0xc3, 0x72, 0x91, 0x4f, 0x98, 0xee, 0x1c, 0xc2, 0x80, 0xaa, 0x64, 0xa5, + 0x3e, 0x83, 0x62, 0x1c, 0xcc, 0xe0, 0x9e, 0xf8, 0x5a, 0xc0, 0x13, 0x12, + 0x7d, 0xa2, 0xa7, 0x8b, 0xa3, 0xe7, 0x9f, 0x2a, 0xd7, 0x9b, 0xca, 0xcb, + 0xed, 0x97, 0x01, 0x9c, 0x28, 0x84, 0x51, 0x04, 0x50, 0x41, 0xbc, 0xb4, + 0xfc, 0x78, 0xe9, 0x1b, 0xcf, 0x14, 0xea, 0x1f, 0x0f, 0xfc, 0x2e, 0x01, + 0x32, 0x8d, 0xb6, 0x35, 0xcb, 0x0a, 0x18, 0x3b, 0xec, 0x5a, 0x3e, 0x3c, + 0x1b, 0xd3, 0x99, 0x43, 0x1e, 0x2f, 0xf7, 0xbd, 0xf3, 0x5b, 0x12, 0xb9, + 0x07, 0x5e, 0xed, 0x3e, 0xd1, 0xa9, 0x87, 0xcc, 0x77, 0x72, 0x27, 0xd4, + 0xd9, 0x75, 0xa2, 0x63, 0x4b, 0x93, 0x36, 0xbd, 0xe5, 0x5c, 0xd7, 0xbf, + 0x5f, 0x79, 0x0d, 0xb3, 0x32, 0xa7, 0x0b, 0xb2, 0x63, 0x23, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x1d, 0x30, 0x82, 0x01, 0x19, 0x30, + 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, + 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64, 0x0c, 0x11, + 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x1d, 0x06, 0x03, + 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x0b, 0x50, 0xec, 0x77, 0xef, + 0x2a, 0x9b, 0xff, 0xec, 0x03, 0xa1, 0x0a, 0xff, 0xad, 0xc6, 0xe4, 0x2a, + 0x18, 0xc7, 0x3e, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, + 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, + 0x02, 0x01, 0x06, 0x30, 0x35, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2e, + 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0, 0x26, 0x86, 0x24, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x67, 0x74, + 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x2e, + 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x22, + 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, + 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4c, + 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0x06, + 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x36, 0x30, + 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, + 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, + 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, + 0x33, 0x24, 0xd5, 0x90, 0xaa, 0x29, 0x0c, 0x35, 0xb9, 0x2f, 0xc3, 0xc7, + 0x42, 0x93, 0xc0, 0xc6, 0x10, 0x4b, 0x03, 0x08, 0x76, 0x84, 0x10, 0xa2, + 0xe0, 0xe7, 0x53, 0x12, 0x27, 0xf2, 0x0a, 0xda, 0x7f, 0x3a, 0xdc, 0xfd, + 0x5c, 0x79, 0x5a, 0x8f, 0x17, 0x74, 0x43, 0x53, 0xb1, 0xd5, 0xd1, 0x5d, + 0x59, 0xb9, 0xa6, 0x84, 0x64, 0xca, 0xf1, 0x3a, 0x0a, 0x59, 0x96, 0x10, + 0xbf, 0xa9, 0x81, 0x57, 0x8b, 0x5c, 0x87, 0xdc, 0x7f, 0xe3, 0xe4, 0xbb, + 0x05, 0x7a, 0xa0, 0x32, 0x09, 0x13, 0x4e, 0x10, 0x81, 0x28, 0x1f, 0x9c, + 0x03, 0x62, 0xbc, 0xf4, 0x01, 0xb5, 0x29, 0x83, 0x46, 0x07, 0xb9, 0xe7, + 0xb8, 0x5d, 0xc8, 0xe9, 0xd1, 0xdd, 0xad, 0x3b, 0xf8, 0x34, 0xdb, 0xc1, + 0xd1, 0x95, 0xa9, 0x91, 0x18, 0xed, 0x3c, 0x2c, 0x37, 0x11, 0x4d, 0xcc, + 0xfe, 0x53, 0x3e, 0x50, 0x43, 0xf9, 0xc3, 0x56, 0x41, 0xac, 0x53, 0x9b, + 0x6c, 0x05, 0xb2, 0x9a, 0xe2, 0xe0, 0x59, 0x57, 0x30, 0x32, 0xb6, 0x26, + 0x4e, 0x13, 0x25, 0xcd, 0xfa, 0x48, 0x70, 0x0f, 0x75, 0x55, 0x60, 0x11, + 0xf5, 0x3b, 0xd5, 0x5e, 0x5a, 0x3c, 0x8b, 0x5b, 0x0f, 0x0f, 0x62, 0x42, + 0x48, 0x61, 0x85, 0x8b, 0x10, 0xf4, 0xc1, 0x88, 0xbf, 0x7f, 0x5f, 0x8a, + 0xc2, 0xd7, 0xcd, 0x2b, 0x94, 0x5c, 0x1f, 0x34, 0x4a, 0x08, 0xaf, 0xeb, + 0xae, 0x89, 0xa8, 0x48, 0x75, 0x55, 0x95, 0x1d, 0xbb, 0xc0, 0x9a, 0x01, + 0xb9, 0xf4, 0x03, 0x22, 0x3e, 0xd4, 0xe6, 0x52, 0x30, 0x0d, 0x67, 0xb9, + 0xc0, 0x91, 0xfd, 0x2d, 0x4c, 0x30, 0x8e, 0xbd, 0x8c, 0xa5, 0x04, 0x91, + 0xbb, 0xa4, 0xab, 0x7f, 0x0f, 0xd8, 0x6f, 0xf0, 0x66, 0x00, 0xc9, 0xa3, + 0x5c, 0xf5, 0xb0, 0x8f, 0x83, 0xe6, 0x9c, 0x5a, 0xe6, 0xb6, 0xb9, 0xc5, + 0xbc, 0xbe, 0xe4, 0x02, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 33:65:50:08:79:ad:73:e2:30:b9:e0:1d:0d:7f:ac:91 + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Premium Server CA/emailAddress=premium-server@thawte.com + Validity + Not Before: Nov 17 00:00:00 2006 GMT + Not After : Dec 30 23:59:59 2020 GMT + Subject: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:ac:a0:f0:fb:80:59:d4:9c:c7:a4:cf:9d:a1:59: + 73:09:10:45:0c:0d:2c:6e:68:f1:6c:5b:48:68:49: + 59:37:fc:0b:33:19:c2:77:7f:cc:10:2d:95:34:1c: + e6:eb:4d:09:a7:1c:d2:b8:c9:97:36:02:b7:89:d4: + 24:5f:06:c0:cc:44:94:94:8d:02:62:6f:eb:5a:dd: + 11:8d:28:9a:5c:84:90:10:7a:0d:bd:74:66:2f:6a: + 38:a0:e2:d5:54:44:eb:1d:07:9f:07:ba:6f:ee:e9: + fd:4e:0b:29:f5:3e:84:a0:01:f1:9c:ab:f8:1c:7e: + 89:a4:e8:a1:d8:71:65:0d:a3:51:7b:ee:bc:d2:22: + 60:0d:b9:5b:9d:df:ba:fc:51:5b:0b:af:98:b2:e9: + 2e:e9:04:e8:62:87:de:2b:c8:d7:4e:c1:4c:64:1e: + dd:cf:87:58:ba:4a:4f:ca:68:07:1d:1c:9d:4a:c6: + d5:2f:91:cc:7c:71:72:1c:c5:c0:67:eb:32:fd:c9: + 92:5c:94:da:85:c0:9b:bf:53:7d:2b:09:f4:8c:9d: + 91:1f:97:6a:52:cb:de:09:36:a4:77:d8:7b:87:50: + 44:d5:3e:6e:29:69:fb:39:49:26:1e:09:a5:80:7b: + 40:2d:eb:e8:27:85:c9:fe:61:fd:7e:e6:7c:97:1d: + d5:9d + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: https://www.thawte.com/cps + + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50 + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.thawte.com/ThawtePremiumServerCA.crl + + Signature Algorithm: sha1WithRSAEncryption + 84:a8:4c:c9:3e:2a:bc:9a:e2:cc:8f:0b:b2:25:77:c4:61:89: + 89:63:5a:d4:a3:15:40:d4:fb:5e:3f:b4:43:ea:63:17:2b:6b: + 99:74:9e:09:a8:dd:d4:56:15:2e:7a:79:31:5f:63:96:53:1b: + 34:d9:15:ea:4f:6d:70:ca:be:f6:82:a9:ed:da:85:77:cc:76: + 1c:6a:81:0a:21:d8:41:99:7f:5e:2e:82:c1:e8:aa:f7:93:81: + 05:aa:92:b4:1f:b7:9a:c0:07:17:f5:cb:c6:b4:4c:0e:d7:56: + dc:71:20:74:38:d6:74:c6:d6:8f:6b:af:8b:8d:a0:6c:29:0b: + 61:e0 +-----BEGIN CERTIFICATE----- +MIIERTCCA66gAwIBAgIQM2VQCHmtc+IwueAdDX+skTANBgkqhkiG9w0BAQUFADCB +zjELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJ +Q2FwZSBUb3duMR0wGwYDVQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UE +CxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhh +d3RlIFByZW1pdW0gU2VydmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNl +cnZlckB0aGF3dGUuY29tMB4XDTA2MTExNzAwMDAwMFoXDTIwMTIzMDIzNTk1OVow +gakxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUsIEluYy4xKDAmBgNVBAsT +H0NlcnRpZmljYXRpb24gU2VydmljZXMgRGl2aXNpb24xODA2BgNVBAsTLyhjKSAy +MDA2IHRoYXd0ZSwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYD +VQQDExZ0aGF3dGUgUHJpbWFyeSBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEArKDw+4BZ1JzHpM+doVlzCRBFDA0sbmjxbFtIaElZN/wLMxnC +d3/MEC2VNBzm600JpxzSuMmXNgK3idQkXwbAzESUlI0CYm/rWt0RjSiaXISQEHoN +vXRmL2o4oOLVVETrHQefB7pv7un9Tgsp9T6EoAHxnKv4HH6JpOih2HFlDaNRe+68 +0iJgDblbnd+6/FFbC6+Ysuku6QToYofeK8jXTsFMZB7dz4dYukpPymgHHRydSsbV +L5HMfHFyHMXAZ+sy/cmSXJTahcCbv1N9Kwn0jJ2RH5dqUsveCTakd9h7h1BE1T5u +KWn7OUkmHgmlgHtALevoJ4XJ/mH9fuZ8lx3VnQIDAQABo4HCMIG/MA8GA1UdEwEB +/wQFMAMBAf8wOwYDVR0gBDQwMjAwBgRVHSAAMCgwJgYIKwYBBQUHAgEWGmh0dHBz +Oi8vd3d3LnRoYXd0ZS5jb20vY3BzMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU +e1tFz6/Oy3r9MZIaarbzRutXSFAwQAYDVR0fBDkwNzA1oDOgMYYvaHR0cDovL2Ny +bC50aGF3dGUuY29tL1RoYXd0ZVByZW1pdW1TZXJ2ZXJDQS5jcmwwDQYJKoZIhvcN +AQEFBQADgYEAhKhMyT4qvJrizI8LsiV3xGGJiWNa1KMVQNT7Xj+0Q+pjFytrmXSe +Cajd1FYVLnp5MV9jllMbNNkV6k9tcMq+9oKp7dqFd8x2HGqBCiHYQZl/Xi6Cweiq +95OBBaqStB+3msAHF/XLxrRMDtdW3HEgdDjWdMbWj2uvi42gbCkLYeA= +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert6[] = { + 0x30, 0x82, 0x04, 0x45, 0x30, 0x82, 0x03, 0xae, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x33, 0x65, 0x50, 0x08, 0x79, 0xad, 0x73, 0xe2, 0x30, + 0xb9, 0xe0, 0x1d, 0x0d, 0x7f, 0xac, 0x91, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, + 0xce, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x5a, 0x41, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, + 0x0c, 0x57, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x43, 0x61, 0x70, + 0x65, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, + 0x43, 0x61, 0x70, 0x65, 0x20, 0x54, 0x6f, 0x77, 0x6e, 0x31, 0x1d, 0x30, + 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x14, 0x54, 0x68, 0x61, 0x77, + 0x74, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x74, 0x69, 0x6e, + 0x67, 0x20, 0x63, 0x63, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x13, 0x1f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x73, 0x20, 0x44, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x21, + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x18, 0x54, 0x68, 0x61, + 0x77, 0x74, 0x65, 0x20, 0x50, 0x72, 0x65, 0x6d, 0x69, 0x75, 0x6d, 0x20, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, + 0x16, 0x19, 0x70, 0x72, 0x65, 0x6d, 0x69, 0x75, 0x6d, 0x2d, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x40, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, + 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x31, + 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, + 0x31, 0x32, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, + 0x81, 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x13, 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, + 0x63, 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, + 0x1f, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, + 0x44, 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, + 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, + 0x30, 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, + 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, + 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, + 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, + 0x20, 0x43, 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, + 0xac, 0xa0, 0xf0, 0xfb, 0x80, 0x59, 0xd4, 0x9c, 0xc7, 0xa4, 0xcf, 0x9d, + 0xa1, 0x59, 0x73, 0x09, 0x10, 0x45, 0x0c, 0x0d, 0x2c, 0x6e, 0x68, 0xf1, + 0x6c, 0x5b, 0x48, 0x68, 0x49, 0x59, 0x37, 0xfc, 0x0b, 0x33, 0x19, 0xc2, + 0x77, 0x7f, 0xcc, 0x10, 0x2d, 0x95, 0x34, 0x1c, 0xe6, 0xeb, 0x4d, 0x09, + 0xa7, 0x1c, 0xd2, 0xb8, 0xc9, 0x97, 0x36, 0x02, 0xb7, 0x89, 0xd4, 0x24, + 0x5f, 0x06, 0xc0, 0xcc, 0x44, 0x94, 0x94, 0x8d, 0x02, 0x62, 0x6f, 0xeb, + 0x5a, 0xdd, 0x11, 0x8d, 0x28, 0x9a, 0x5c, 0x84, 0x90, 0x10, 0x7a, 0x0d, + 0xbd, 0x74, 0x66, 0x2f, 0x6a, 0x38, 0xa0, 0xe2, 0xd5, 0x54, 0x44, 0xeb, + 0x1d, 0x07, 0x9f, 0x07, 0xba, 0x6f, 0xee, 0xe9, 0xfd, 0x4e, 0x0b, 0x29, + 0xf5, 0x3e, 0x84, 0xa0, 0x01, 0xf1, 0x9c, 0xab, 0xf8, 0x1c, 0x7e, 0x89, + 0xa4, 0xe8, 0xa1, 0xd8, 0x71, 0x65, 0x0d, 0xa3, 0x51, 0x7b, 0xee, 0xbc, + 0xd2, 0x22, 0x60, 0x0d, 0xb9, 0x5b, 0x9d, 0xdf, 0xba, 0xfc, 0x51, 0x5b, + 0x0b, 0xaf, 0x98, 0xb2, 0xe9, 0x2e, 0xe9, 0x04, 0xe8, 0x62, 0x87, 0xde, + 0x2b, 0xc8, 0xd7, 0x4e, 0xc1, 0x4c, 0x64, 0x1e, 0xdd, 0xcf, 0x87, 0x58, + 0xba, 0x4a, 0x4f, 0xca, 0x68, 0x07, 0x1d, 0x1c, 0x9d, 0x4a, 0xc6, 0xd5, + 0x2f, 0x91, 0xcc, 0x7c, 0x71, 0x72, 0x1c, 0xc5, 0xc0, 0x67, 0xeb, 0x32, + 0xfd, 0xc9, 0x92, 0x5c, 0x94, 0xda, 0x85, 0xc0, 0x9b, 0xbf, 0x53, 0x7d, + 0x2b, 0x09, 0xf4, 0x8c, 0x9d, 0x91, 0x1f, 0x97, 0x6a, 0x52, 0xcb, 0xde, + 0x09, 0x36, 0xa4, 0x77, 0xd8, 0x7b, 0x87, 0x50, 0x44, 0xd5, 0x3e, 0x6e, + 0x29, 0x69, 0xfb, 0x39, 0x49, 0x26, 0x1e, 0x09, 0xa5, 0x80, 0x7b, 0x40, + 0x2d, 0xeb, 0xe8, 0x27, 0x85, 0xc9, 0xfe, 0x61, 0xfd, 0x7e, 0xe6, 0x7c, + 0x97, 0x1d, 0xd5, 0x9d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xc2, + 0x30, 0x81, 0xbf, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, + 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x3b, 0x06, 0x03, + 0x55, 0x1d, 0x20, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06, 0x04, 0x55, + 0x1d, 0x20, 0x00, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73, + 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, + 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, + 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, + 0x7b, 0x5b, 0x45, 0xcf, 0xaf, 0xce, 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a, + 0x6a, 0xb6, 0xf3, 0x46, 0xeb, 0x57, 0x48, 0x50, 0x30, 0x40, 0x06, 0x03, + 0x55, 0x1d, 0x1f, 0x04, 0x39, 0x30, 0x37, 0x30, 0x35, 0xa0, 0x33, 0xa0, + 0x31, 0x86, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, + 0x6c, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, 0x72, 0x65, 0x6d, 0x69, + 0x75, 0x6d, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x41, 0x2e, 0x63, + 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x84, 0xa8, 0x4c, + 0xc9, 0x3e, 0x2a, 0xbc, 0x9a, 0xe2, 0xcc, 0x8f, 0x0b, 0xb2, 0x25, 0x77, + 0xc4, 0x61, 0x89, 0x89, 0x63, 0x5a, 0xd4, 0xa3, 0x15, 0x40, 0xd4, 0xfb, + 0x5e, 0x3f, 0xb4, 0x43, 0xea, 0x63, 0x17, 0x2b, 0x6b, 0x99, 0x74, 0x9e, + 0x09, 0xa8, 0xdd, 0xd4, 0x56, 0x15, 0x2e, 0x7a, 0x79, 0x31, 0x5f, 0x63, + 0x96, 0x53, 0x1b, 0x34, 0xd9, 0x15, 0xea, 0x4f, 0x6d, 0x70, 0xca, 0xbe, + 0xf6, 0x82, 0xa9, 0xed, 0xda, 0x85, 0x77, 0xcc, 0x76, 0x1c, 0x6a, 0x81, + 0x0a, 0x21, 0xd8, 0x41, 0x99, 0x7f, 0x5e, 0x2e, 0x82, 0xc1, 0xe8, 0xaa, + 0xf7, 0x93, 0x81, 0x05, 0xaa, 0x92, 0xb4, 0x1f, 0xb7, 0x9a, 0xc0, 0x07, + 0x17, 0xf5, 0xcb, 0xc6, 0xb4, 0x4c, 0x0e, 0xd7, 0x56, 0xdc, 0x71, 0x20, + 0x74, 0x38, 0xd6, 0x74, 0xc6, 0xd6, 0x8f, 0x6b, 0xaf, 0x8b, 0x8d, 0xa0, + 0x6c, 0x29, 0x0b, 0x61, 0xe0, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 06:7f:94:57:85:87:e8:ac:77:de:b2:53:32:5b:bc:99:8b:56:0d + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=Amazon, CN=Amazon Root CA 1 + Validity + Not Before: Oct 22 00:00:00 2015 GMT + Not After : Oct 19 00:00:00 2025 GMT + Subject: C=US, O=Amazon, OU=Server CA 1B, CN=Amazon + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c2:4e:16:67:dd:ce:bc:6a:c8:37:5a:ec:3a:30: + b0:1d:e6:d1:12:e8:12:28:48:cc:e8:29:c1:b9:6e: + 53:d5:a3:eb:03:39:1a:cc:77:87:f6:01:b9:d9:70: + cc:cf:6b:8d:e3:e3:03:71:86:99:6d:cb:a6:94:2a: + 4e:13:d6:a7:bd:04:ec:0a:16:3c:0a:eb:39:b1:c4: + b5:58:a3:b6:c7:56:25:ec:3e:52:7a:a8:e3:29:16: + 07:b9:6e:50:cf:fb:5f:31:f8:1d:ba:03:4a:62:89: + 03:ae:3e:47:f2:0f:27:91:e3:14:20:85:f8:fa:e9: + 8a:35:f5:5f:9e:99:4d:e7:6b:37:ef:a4:50:3e:44: + ec:fa:5a:85:66:07:9c:7e:17:6a:55:f3:17:8a:35: + 1e:ee:e9:ac:c3:75:4e:58:55:7d:53:6b:0a:6b:9b: + 14:42:d7:e5:ac:01:89:b3:ea:a3:fe:cf:c0:2b:0c: + 84:c2:d8:53:15:cb:67:f0:d0:88:ca:3a:d1:17:73: + f5:5f:9a:d4:c5:72:1e:7e:01:f1:98:30:63:2a:aa: + f2:7a:2d:c5:e2:02:1a:86:e5:32:3e:0e:bd:11:b4: + cf:3c:93:ef:17:50:10:9e:43:c2:06:2a:e0:0d:68: + be:d3:88:8b:4a:65:8c:4a:d4:c3:2e:4c:9b:55:f4: + 86:e5 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 59:A4:66:06:52:A0:7B:95:92:3C:A3:94:07:27:96:74:5B:F9:3D:D0 + X509v3 Authority Key Identifier: + keyid:84:18:CC:85:34:EC:BC:0C:94:94:2E:08:59:9C:C7:B2:10:4E:0A:08 + + Authority Information Access: + OCSP - URI:http://ocsp.rootca1.amazontrust.com + CA Issuers - URI:http://crt.rootca1.amazontrust.com/rootca1.cer + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.rootca1.amazontrust.com/rootca1.crl + + X509v3 Certificate Policies: + Policy: 2.23.140.1.2.1 + + Signature Algorithm: sha256WithRSAEncryption + 85:92:be:35:bb:79:cf:a3:81:42:1c:e4:e3:63:73:53:39:52: + 35:e7:d1:ad:fd:ae:99:8a:ac:89:12:2f:bb:e7:6f:9a:d5:4e: + 72:ea:20:30:61:f9:97:b2:cd:a5:27:02:45:a8:ca:76:3e:98: + 4a:83:9e:b6:e6:45:e0:f2:43:f6:08:de:6d:e8:6e:db:31:07: + 13:f0:2f:31:0d:93:6d:61:37:7b:58:f0:fc:51:98:91:28:02: + 4f:05:76:b7:d3:f0:1b:c2:e6:5e:d0:66:85:11:0f:2e:81:c6: + 10:81:29:fe:20:60:48:f3:f2:f0:84:13:53:65:35:15:11:6b: + 82:51:40:55:57:5f:18:b5:b0:22:3e:ad:f2:5e:a3:01:e3:c3: + b3:f9:cb:41:5a:e6:52:91:bb:e4:36:87:4f:2d:a9:a4:07:68: + 35:ba:94:72:cd:0e:ea:0e:7d:57:f2:79:fc:37:c5:7b:60:9e: + b2:eb:c0:2d:90:77:0d:49:10:27:a5:38:ad:c4:12:a3:b4:a3: + c8:48:b3:15:0b:1e:e2:e2:19:dc:c4:76:52:c8:bc:8a:41:78: + 70:d9:6d:97:b3:4a:8b:78:2d:5e:b4:0f:a3:4c:60:ca:e1:47: + cb:78:2d:12:17:b1:52:8b:ca:39:2c:bd:b5:2f:c2:33:02:96: + ab:da:94:7f +-----BEGIN CERTIFICATE----- +MIIESTCCAzGgAwIBAgITBn+UV4WH6Kx33rJTMlu8mYtWDTANBgkqhkiG9w0BAQsF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAxMB4XDTE1MTAyMjAwMDAwMFoXDTI1MTAxOTAwMDAwMFowRjEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEVMBMGA1UECxMMU2VydmVyIENB +IDFCMQ8wDQYDVQQDEwZBbWF6b24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQDCThZn3c68asg3Wuw6MLAd5tES6BIoSMzoKcG5blPVo+sDORrMd4f2AbnZ +cMzPa43j4wNxhplty6aUKk4T1qe9BOwKFjwK6zmxxLVYo7bHViXsPlJ6qOMpFge5 +blDP+18x+B26A0piiQOuPkfyDyeR4xQghfj66Yo19V+emU3nazfvpFA+ROz6WoVm +B5x+F2pV8xeKNR7u6azDdU5YVX1TawprmxRC1+WsAYmz6qP+z8ArDITC2FMVy2fw +0IjKOtEXc/VfmtTFch5+AfGYMGMqqvJ6LcXiAhqG5TI+Dr0RtM88k+8XUBCeQ8IG +KuANaL7TiItKZYxK1MMuTJtV9IblAgMBAAGjggE7MIIBNzASBgNVHRMBAf8ECDAG +AQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUWaRmBlKge5WSPKOUByeW +dFv5PdAwHwYDVR0jBBgwFoAUhBjMhTTsvAyUlC4IWZzHshBOCggwewYIKwYBBQUH +AQEEbzBtMC8GCCsGAQUFBzABhiNodHRwOi8vb2NzcC5yb290Y2ExLmFtYXpvbnRy +dXN0LmNvbTA6BggrBgEFBQcwAoYuaHR0cDovL2NydC5yb290Y2ExLmFtYXpvbnRy +dXN0LmNvbS9yb290Y2ExLmNlcjA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3Js +LnJvb3RjYTEuYW1hem9udHJ1c3QuY29tL3Jvb3RjYTEuY3JsMBMGA1UdIAQMMAow +CAYGZ4EMAQIBMA0GCSqGSIb3DQEBCwUAA4IBAQCFkr41u3nPo4FCHOTjY3NTOVI1 +59Gt/a6ZiqyJEi+752+a1U5y6iAwYfmXss2lJwJFqMp2PphKg5625kXg8kP2CN5t +6G7bMQcT8C8xDZNtYTd7WPD8UZiRKAJPBXa30/AbwuZe0GaFEQ8ugcYQgSn+IGBI +8/LwhBNTZTUVEWuCUUBVV18YtbAiPq3yXqMB48Oz+ctBWuZSkbvkNodPLamkB2g1 +upRyzQ7qDn1X8nn8N8V7YJ6y68AtkHcNSRAnpTitxBKjtKPISLMVCx7i4hncxHZS +yLyKQXhw2W2Xs0qLeC1etA+jTGDK4UfLeC0SF7FSi8o5LL21L8IzApar2pR/ +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert7[] = { + 0x30, 0x82, 0x04, 0x49, 0x30, 0x82, 0x03, 0x31, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x13, 0x06, 0x7f, 0x94, 0x57, 0x85, 0x87, 0xe8, 0xac, 0x77, + 0xde, 0xb2, 0x53, 0x32, 0x5b, 0xbc, 0x99, 0x8b, 0x56, 0x0d, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x30, 0x39, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x06, 0x41, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x31, 0x19, 0x30, + 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x41, 0x6d, 0x61, 0x7a, + 0x6f, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, + 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x30, 0x32, 0x32, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x35, 0x31, 0x30, 0x31, + 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x46, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x06, 0x41, 0x6d, + 0x61, 0x7a, 0x6f, 0x6e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x13, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, + 0x20, 0x31, 0x42, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x06, 0x41, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 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, 0xc2, 0x4e, 0x16, 0x67, 0xdd, 0xce, 0xbc, + 0x6a, 0xc8, 0x37, 0x5a, 0xec, 0x3a, 0x30, 0xb0, 0x1d, 0xe6, 0xd1, 0x12, + 0xe8, 0x12, 0x28, 0x48, 0xcc, 0xe8, 0x29, 0xc1, 0xb9, 0x6e, 0x53, 0xd5, + 0xa3, 0xeb, 0x03, 0x39, 0x1a, 0xcc, 0x77, 0x87, 0xf6, 0x01, 0xb9, 0xd9, + 0x70, 0xcc, 0xcf, 0x6b, 0x8d, 0xe3, 0xe3, 0x03, 0x71, 0x86, 0x99, 0x6d, + 0xcb, 0xa6, 0x94, 0x2a, 0x4e, 0x13, 0xd6, 0xa7, 0xbd, 0x04, 0xec, 0x0a, + 0x16, 0x3c, 0x0a, 0xeb, 0x39, 0xb1, 0xc4, 0xb5, 0x58, 0xa3, 0xb6, 0xc7, + 0x56, 0x25, 0xec, 0x3e, 0x52, 0x7a, 0xa8, 0xe3, 0x29, 0x16, 0x07, 0xb9, + 0x6e, 0x50, 0xcf, 0xfb, 0x5f, 0x31, 0xf8, 0x1d, 0xba, 0x03, 0x4a, 0x62, + 0x89, 0x03, 0xae, 0x3e, 0x47, 0xf2, 0x0f, 0x27, 0x91, 0xe3, 0x14, 0x20, + 0x85, 0xf8, 0xfa, 0xe9, 0x8a, 0x35, 0xf5, 0x5f, 0x9e, 0x99, 0x4d, 0xe7, + 0x6b, 0x37, 0xef, 0xa4, 0x50, 0x3e, 0x44, 0xec, 0xfa, 0x5a, 0x85, 0x66, + 0x07, 0x9c, 0x7e, 0x17, 0x6a, 0x55, 0xf3, 0x17, 0x8a, 0x35, 0x1e, 0xee, + 0xe9, 0xac, 0xc3, 0x75, 0x4e, 0x58, 0x55, 0x7d, 0x53, 0x6b, 0x0a, 0x6b, + 0x9b, 0x14, 0x42, 0xd7, 0xe5, 0xac, 0x01, 0x89, 0xb3, 0xea, 0xa3, 0xfe, + 0xcf, 0xc0, 0x2b, 0x0c, 0x84, 0xc2, 0xd8, 0x53, 0x15, 0xcb, 0x67, 0xf0, + 0xd0, 0x88, 0xca, 0x3a, 0xd1, 0x17, 0x73, 0xf5, 0x5f, 0x9a, 0xd4, 0xc5, + 0x72, 0x1e, 0x7e, 0x01, 0xf1, 0x98, 0x30, 0x63, 0x2a, 0xaa, 0xf2, 0x7a, + 0x2d, 0xc5, 0xe2, 0x02, 0x1a, 0x86, 0xe5, 0x32, 0x3e, 0x0e, 0xbd, 0x11, + 0xb4, 0xcf, 0x3c, 0x93, 0xef, 0x17, 0x50, 0x10, 0x9e, 0x43, 0xc2, 0x06, + 0x2a, 0xe0, 0x0d, 0x68, 0xbe, 0xd3, 0x88, 0x8b, 0x4a, 0x65, 0x8c, 0x4a, + 0xd4, 0xc3, 0x2e, 0x4c, 0x9b, 0x55, 0xf4, 0x86, 0xe5, 0x02, 0x03, 0x01, + 0x00, 0x01, 0xa3, 0x82, 0x01, 0x3b, 0x30, 0x82, 0x01, 0x37, 0x30, 0x12, + 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, + 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, + 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x59, 0xa4, 0x66, + 0x06, 0x52, 0xa0, 0x7b, 0x95, 0x92, 0x3c, 0xa3, 0x94, 0x07, 0x27, 0x96, + 0x74, 0x5b, 0xf9, 0x3d, 0xd0, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, + 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x84, 0x18, 0xcc, 0x85, 0x34, 0xec, + 0xbc, 0x0c, 0x94, 0x94, 0x2e, 0x08, 0x59, 0x9c, 0xc7, 0xb2, 0x10, 0x4e, + 0x0a, 0x08, 0x30, 0x7b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x01, 0x01, 0x04, 0x6f, 0x30, 0x6d, 0x30, 0x2f, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x23, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x72, 0x6f, 0x6f, 0x74, + 0x63, 0x61, 0x31, 0x2e, 0x61, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x3a, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2e, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x74, 0x2e, 0x72, 0x6f, 0x6f, 0x74, + 0x63, 0x61, 0x31, 0x2e, 0x61, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, + 0x63, 0x61, 0x31, 0x2e, 0x63, 0x65, 0x72, 0x30, 0x3f, 0x06, 0x03, 0x55, + 0x1d, 0x1f, 0x04, 0x38, 0x30, 0x36, 0x30, 0x34, 0xa0, 0x32, 0xa0, 0x30, + 0x86, 0x2e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, + 0x2e, 0x72, 0x6f, 0x6f, 0x74, 0x63, 0x61, 0x31, 0x2e, 0x61, 0x6d, 0x61, + 0x7a, 0x6f, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x63, 0x61, 0x31, 0x2e, 0x63, 0x72, 0x6c, + 0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x0c, 0x30, 0x0a, 0x30, + 0x08, 0x06, 0x06, 0x67, 0x81, 0x0c, 0x01, 0x02, 0x01, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, + 0x03, 0x82, 0x01, 0x01, 0x00, 0x85, 0x92, 0xbe, 0x35, 0xbb, 0x79, 0xcf, + 0xa3, 0x81, 0x42, 0x1c, 0xe4, 0xe3, 0x63, 0x73, 0x53, 0x39, 0x52, 0x35, + 0xe7, 0xd1, 0xad, 0xfd, 0xae, 0x99, 0x8a, 0xac, 0x89, 0x12, 0x2f, 0xbb, + 0xe7, 0x6f, 0x9a, 0xd5, 0x4e, 0x72, 0xea, 0x20, 0x30, 0x61, 0xf9, 0x97, + 0xb2, 0xcd, 0xa5, 0x27, 0x02, 0x45, 0xa8, 0xca, 0x76, 0x3e, 0x98, 0x4a, + 0x83, 0x9e, 0xb6, 0xe6, 0x45, 0xe0, 0xf2, 0x43, 0xf6, 0x08, 0xde, 0x6d, + 0xe8, 0x6e, 0xdb, 0x31, 0x07, 0x13, 0xf0, 0x2f, 0x31, 0x0d, 0x93, 0x6d, + 0x61, 0x37, 0x7b, 0x58, 0xf0, 0xfc, 0x51, 0x98, 0x91, 0x28, 0x02, 0x4f, + 0x05, 0x76, 0xb7, 0xd3, 0xf0, 0x1b, 0xc2, 0xe6, 0x5e, 0xd0, 0x66, 0x85, + 0x11, 0x0f, 0x2e, 0x81, 0xc6, 0x10, 0x81, 0x29, 0xfe, 0x20, 0x60, 0x48, + 0xf3, 0xf2, 0xf0, 0x84, 0x13, 0x53, 0x65, 0x35, 0x15, 0x11, 0x6b, 0x82, + 0x51, 0x40, 0x55, 0x57, 0x5f, 0x18, 0xb5, 0xb0, 0x22, 0x3e, 0xad, 0xf2, + 0x5e, 0xa3, 0x01, 0xe3, 0xc3, 0xb3, 0xf9, 0xcb, 0x41, 0x5a, 0xe6, 0x52, + 0x91, 0xbb, 0xe4, 0x36, 0x87, 0x4f, 0x2d, 0xa9, 0xa4, 0x07, 0x68, 0x35, + 0xba, 0x94, 0x72, 0xcd, 0x0e, 0xea, 0x0e, 0x7d, 0x57, 0xf2, 0x79, 0xfc, + 0x37, 0xc5, 0x7b, 0x60, 0x9e, 0xb2, 0xeb, 0xc0, 0x2d, 0x90, 0x77, 0x0d, + 0x49, 0x10, 0x27, 0xa5, 0x38, 0xad, 0xc4, 0x12, 0xa3, 0xb4, 0xa3, 0xc8, + 0x48, 0xb3, 0x15, 0x0b, 0x1e, 0xe2, 0xe2, 0x19, 0xdc, 0xc4, 0x76, 0x52, + 0xc8, 0xbc, 0x8a, 0x41, 0x78, 0x70, 0xd9, 0x6d, 0x97, 0xb3, 0x4a, 0x8b, + 0x78, 0x2d, 0x5e, 0xb4, 0x0f, 0xa3, 0x4c, 0x60, 0xca, 0xe1, 0x47, 0xcb, + 0x78, 0x2d, 0x12, 0x17, 0xb1, 0x52, 0x8b, 0xca, 0x39, 0x2c, 0xbd, 0xb5, + 0x2f, 0xc2, 0x33, 0x02, 0x96, 0xab, 0xda, 0x94, 0x7f, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 146033 (0x23a71) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA + Validity + Not Before: Dec 11 23:45:51 2013 GMT + Not After : May 20 23:45:51 2022 GMT + Subject: C=US, O=GeoTrust Inc., CN=RapidSSL SHA256 CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:bb:58:c1:12:01:2e:97:d8:7d:18:aa:c8:c2:e5: + 85:e2:17:6c:60:2e:c9:8d:31:05:39:1a:06:98:56: + dd:54:d7:11:8c:59:5b:3d:b1:54:ae:4b:21:85:32: + 16:5f:54:86:e6:d9:b1:d8:60:89:6b:58:be:72:da: + a0:00:42:76:b1:27:59:4c:cd:e3:ba:d4:5c:d9:a6: + 7f:bb:2b:75:d5:46:44:bd:ec:40:5c:59:b7:dd:59: + 9f:f1:6a:f7:06:fc:d6:2f:19:8a:95:12:ba:9a:ca: + d5:30:d2:38:fc:19:3b:5b:15:3b:36:d0:43:4d:d1: + 65:a1:d4:8b:c1:60:41:b3:d6:70:17:cc:39:c0:9c: + 0c:a0:3d:b7:11:22:4e:ce:d9:a9:7a:d2:2a:62:9c: + a0:0b:4e:2a:d7:c3:61:5a:85:dd:5c:10:b9:54:3d: + 2d:03:f8:49:f0:bc:92:b7:b7:9c:31:c7:e9:b8:aa: + 82:0b:05:b9:31:cd:08:5b:bb:22:0b:f6:9c:8e:8a: + 55:1c:76:43:76:f0:e2:6e:f0:df:a8:29:75:e7:c8: + a4:87:8b:6a:f1:bb:08:c9:36:18:65:ee:50:43:b8: + 5d:72:d5:28:39:e1:53:3e:25:2c:da:2b:4f:dd:8a: + 9e:50:50:e0:6f:9a:c4:d5:19:26:89:01:75:73:09: + 9b:3b + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Authority Key Identifier: + keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E + + X509v3 Subject Key Identifier: + 97:C2:27:50:9E:C2:C9:EC:0C:88:32:C8:7C:AD:E2:A6:01:4F:DA:6F + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 CRL Distribution Points: + + Full Name: + URI:http://g1.symcb.com/crls/gtglobal.crl + + Authority Information Access: + OCSP - URI:http://g2.symcb.com + + X509v3 Certificate Policies: + Policy: 2.16.840.1.113733.1.7.54 + CPS: http://www.geotrust.com/resources/cps + + X509v3 Subject Alternative Name: + DirName:/CN=SymantecPKI-1-569 + Signature Algorithm: sha256WithRSAEncryption + 35:eb:e1:8b:20:56:94:ba:7a:bd:79:a9:f6:e3:fe:6e:38:b4: + 32:c1:a3:db:58:56:20:3e:7d:c7:3a:b1:67:69:d5:79:14:1b: + f6:fa:ec:60:f2:79:cd:0a:0c:60:8a:74:4c:a3:93:2a:a0:f0: + 51:7f:cd:e9:f9:92:fd:96:ab:45:f5:62:3d:3f:60:46:50:13: + 3d:20:13:18:2e:94:46:ae:d5:21:fe:43:a1:c9:23:fe:53:c4: + bf:1a:d8:ac:3a:ca:de:66:97:23:ae:d3:df:4a:4d:73:1f:6f: + 31:a2:51:04:16:6a:00:eb:f9:8d:43:81:f0:50:a1:1f:a6:ca: + 3a:f3:28:3c:5f:51:ac:d7:0a:45:77:4b:0e:52:62:1b:d8:38: + 51:a0:92:2d:3f:90:6e:c8:7e:40:9f:20:46:15:5d:e0:50:7c: + e1:76:af:5e:ed:11:d3:2f:13:b9:b8:25:a4:af:58:09:af:35: + b4:62:54:85:e3:48:de:bc:d2:90:7a:7a:a4:84:0d:a3:42:f2: + 51:c0:d4:ad:53:65:5d:6c:f8:3f:1f:06:f2:4f:cb:97:a0:4a: + 59:c6:78:d1:e8:03:b9:85:6d:2c:ba:e1:5f:b6:ad:2b:3e:25: + 79:c5:8b:56:d5:e3:09:80:ea:c1:27:c2:d9:0e:ec:47:0a:e9: + d0:ca:fc:d8 +-----BEGIN CERTIFICATE----- +MIIETTCCAzWgAwIBAgIDAjpxMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMTMxMjExMjM0NTUxWhcNMjIwNTIwMjM0NTUxWjBCMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSUmFwaWRTU0wg +U0hBMjU2IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1jBEgEu +l9h9GKrIwuWF4hdsYC7JjTEFORoGmFbdVNcRjFlbPbFUrkshhTIWX1SG5tmx2GCJ +a1i+ctqgAEJ2sSdZTM3jutRc2aZ/uyt11UZEvexAXFm33Vmf8Wr3BvzWLxmKlRK6 +msrVMNI4/Bk7WxU7NtBDTdFlodSLwWBBs9ZwF8w5wJwMoD23ESJOztmpetIqYpyg +C04q18NhWoXdXBC5VD0tA/hJ8LySt7ecMcfpuKqCCwW5Mc0IW7siC/acjopVHHZD +dvDibvDfqCl158ikh4tq8bsIyTYYZe5QQ7hdctUoOeFTPiUs2itP3YqeUFDgb5rE +1RkmiQF1cwmbOwIDAQABo4IBSjCCAUYwHwYDVR0jBBgwFoAUwHqYaI2J+6sFZAwR +fap9ZbjKzE4wHQYDVR0OBBYEFJfCJ1CewsnsDIgyyHyt4qYBT9pvMBIGA1UdEwEB +/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMDYGA1UdHwQvMC0wK6ApoCeGJWh0 +dHA6Ly9nMS5zeW1jYi5jb20vY3Jscy9ndGdsb2JhbC5jcmwwLwYIKwYBBQUHAQEE +IzAhMB8GCCsGAQUFBzABhhNodHRwOi8vZzIuc3ltY2IuY29tMEwGA1UdIARFMEMw +QQYKYIZIAYb4RQEHNjAzMDEGCCsGAQUFBwIBFiVodHRwOi8vd3d3Lmdlb3RydXN0 +LmNvbS9yZXNvdXJjZXMvY3BzMCkGA1UdEQQiMCCkHjAcMRowGAYDVQQDExFTeW1h +bnRlY1BLSS0xLTU2OTANBgkqhkiG9w0BAQsFAAOCAQEANevhiyBWlLp6vXmp9uP+ +bji0MsGj21hWID59xzqxZ2nVeRQb9vrsYPJ5zQoMYIp0TKOTKqDwUX/N6fmS/Zar +RfViPT9gRlATPSATGC6URq7VIf5Dockj/lPEvxrYrDrK3maXI67T30pNcx9vMaJR +BBZqAOv5jUOB8FChH6bKOvMoPF9RrNcKRXdLDlJiG9g4UaCSLT+Qbsh+QJ8gRhVd +4FB84XavXu0R0y8TubglpK9YCa81tGJUheNI3rzSkHp6pIQNo0LyUcDUrVNlXWz4 +Px8G8k/Ll6BKWcZ40egDuYVtLLrhX7atKz4lecWLVtXjCYDqwSfC2Q7sRwrp0Mr8 +2A== +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert8[] = { + 0x30, 0x82, 0x04, 0x4d, 0x30, 0x82, 0x03, 0x35, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x03, 0x02, 0x3a, 0x71, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, + 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, + 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, + 0x32, 0x31, 0x31, 0x32, 0x33, 0x34, 0x35, 0x35, 0x31, 0x5a, 0x17, 0x0d, + 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x33, 0x34, 0x35, 0x35, 0x31, + 0x5a, 0x30, 0x42, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x12, 0x52, 0x61, 0x70, 0x69, 0x64, 0x53, 0x53, 0x4c, 0x20, + 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43, 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, 0xbb, 0x58, 0xc1, 0x12, 0x01, 0x2e, + 0x97, 0xd8, 0x7d, 0x18, 0xaa, 0xc8, 0xc2, 0xe5, 0x85, 0xe2, 0x17, 0x6c, + 0x60, 0x2e, 0xc9, 0x8d, 0x31, 0x05, 0x39, 0x1a, 0x06, 0x98, 0x56, 0xdd, + 0x54, 0xd7, 0x11, 0x8c, 0x59, 0x5b, 0x3d, 0xb1, 0x54, 0xae, 0x4b, 0x21, + 0x85, 0x32, 0x16, 0x5f, 0x54, 0x86, 0xe6, 0xd9, 0xb1, 0xd8, 0x60, 0x89, + 0x6b, 0x58, 0xbe, 0x72, 0xda, 0xa0, 0x00, 0x42, 0x76, 0xb1, 0x27, 0x59, + 0x4c, 0xcd, 0xe3, 0xba, 0xd4, 0x5c, 0xd9, 0xa6, 0x7f, 0xbb, 0x2b, 0x75, + 0xd5, 0x46, 0x44, 0xbd, 0xec, 0x40, 0x5c, 0x59, 0xb7, 0xdd, 0x59, 0x9f, + 0xf1, 0x6a, 0xf7, 0x06, 0xfc, 0xd6, 0x2f, 0x19, 0x8a, 0x95, 0x12, 0xba, + 0x9a, 0xca, 0xd5, 0x30, 0xd2, 0x38, 0xfc, 0x19, 0x3b, 0x5b, 0x15, 0x3b, + 0x36, 0xd0, 0x43, 0x4d, 0xd1, 0x65, 0xa1, 0xd4, 0x8b, 0xc1, 0x60, 0x41, + 0xb3, 0xd6, 0x70, 0x17, 0xcc, 0x39, 0xc0, 0x9c, 0x0c, 0xa0, 0x3d, 0xb7, + 0x11, 0x22, 0x4e, 0xce, 0xd9, 0xa9, 0x7a, 0xd2, 0x2a, 0x62, 0x9c, 0xa0, + 0x0b, 0x4e, 0x2a, 0xd7, 0xc3, 0x61, 0x5a, 0x85, 0xdd, 0x5c, 0x10, 0xb9, + 0x54, 0x3d, 0x2d, 0x03, 0xf8, 0x49, 0xf0, 0xbc, 0x92, 0xb7, 0xb7, 0x9c, + 0x31, 0xc7, 0xe9, 0xb8, 0xaa, 0x82, 0x0b, 0x05, 0xb9, 0x31, 0xcd, 0x08, + 0x5b, 0xbb, 0x22, 0x0b, 0xf6, 0x9c, 0x8e, 0x8a, 0x55, 0x1c, 0x76, 0x43, + 0x76, 0xf0, 0xe2, 0x6e, 0xf0, 0xdf, 0xa8, 0x29, 0x75, 0xe7, 0xc8, 0xa4, + 0x87, 0x8b, 0x6a, 0xf1, 0xbb, 0x08, 0xc9, 0x36, 0x18, 0x65, 0xee, 0x50, + 0x43, 0xb8, 0x5d, 0x72, 0xd5, 0x28, 0x39, 0xe1, 0x53, 0x3e, 0x25, 0x2c, + 0xda, 0x2b, 0x4f, 0xdd, 0x8a, 0x9e, 0x50, 0x50, 0xe0, 0x6f, 0x9a, 0xc4, + 0xd5, 0x19, 0x26, 0x89, 0x01, 0x75, 0x73, 0x09, 0x9b, 0x3b, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x4a, 0x30, 0x82, 0x01, 0x46, 0x30, + 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, + 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64, 0x0c, 0x11, + 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x1d, 0x06, 0x03, + 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x97, 0xc2, 0x27, 0x50, 0x9e, + 0xc2, 0xc9, 0xec, 0x0c, 0x88, 0x32, 0xc8, 0x7c, 0xad, 0xe2, 0xa6, 0x01, + 0x4f, 0xda, 0x6f, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, + 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, + 0x02, 0x01, 0x06, 0x30, 0x36, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2f, + 0x30, 0x2d, 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27, 0x86, 0x25, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x31, 0x2e, 0x73, 0x79, 0x6d, 0x63, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x67, + 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72, 0x6c, 0x30, + 0x2f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, + 0x23, 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x67, 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, + 0x41, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, + 0x36, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x29, 0x06, 0x03, 0x55, 0x1d, + 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x1a, 0x30, + 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, 0x6d, 0x61, + 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, 0x35, 0x36, + 0x39, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x35, 0xeb, 0xe1, + 0x8b, 0x20, 0x56, 0x94, 0xba, 0x7a, 0xbd, 0x79, 0xa9, 0xf6, 0xe3, 0xfe, + 0x6e, 0x38, 0xb4, 0x32, 0xc1, 0xa3, 0xdb, 0x58, 0x56, 0x20, 0x3e, 0x7d, + 0xc7, 0x3a, 0xb1, 0x67, 0x69, 0xd5, 0x79, 0x14, 0x1b, 0xf6, 0xfa, 0xec, + 0x60, 0xf2, 0x79, 0xcd, 0x0a, 0x0c, 0x60, 0x8a, 0x74, 0x4c, 0xa3, 0x93, + 0x2a, 0xa0, 0xf0, 0x51, 0x7f, 0xcd, 0xe9, 0xf9, 0x92, 0xfd, 0x96, 0xab, + 0x45, 0xf5, 0x62, 0x3d, 0x3f, 0x60, 0x46, 0x50, 0x13, 0x3d, 0x20, 0x13, + 0x18, 0x2e, 0x94, 0x46, 0xae, 0xd5, 0x21, 0xfe, 0x43, 0xa1, 0xc9, 0x23, + 0xfe, 0x53, 0xc4, 0xbf, 0x1a, 0xd8, 0xac, 0x3a, 0xca, 0xde, 0x66, 0x97, + 0x23, 0xae, 0xd3, 0xdf, 0x4a, 0x4d, 0x73, 0x1f, 0x6f, 0x31, 0xa2, 0x51, + 0x04, 0x16, 0x6a, 0x00, 0xeb, 0xf9, 0x8d, 0x43, 0x81, 0xf0, 0x50, 0xa1, + 0x1f, 0xa6, 0xca, 0x3a, 0xf3, 0x28, 0x3c, 0x5f, 0x51, 0xac, 0xd7, 0x0a, + 0x45, 0x77, 0x4b, 0x0e, 0x52, 0x62, 0x1b, 0xd8, 0x38, 0x51, 0xa0, 0x92, + 0x2d, 0x3f, 0x90, 0x6e, 0xc8, 0x7e, 0x40, 0x9f, 0x20, 0x46, 0x15, 0x5d, + 0xe0, 0x50, 0x7c, 0xe1, 0x76, 0xaf, 0x5e, 0xed, 0x11, 0xd3, 0x2f, 0x13, + 0xb9, 0xb8, 0x25, 0xa4, 0xaf, 0x58, 0x09, 0xaf, 0x35, 0xb4, 0x62, 0x54, + 0x85, 0xe3, 0x48, 0xde, 0xbc, 0xd2, 0x90, 0x7a, 0x7a, 0xa4, 0x84, 0x0d, + 0xa3, 0x42, 0xf2, 0x51, 0xc0, 0xd4, 0xad, 0x53, 0x65, 0x5d, 0x6c, 0xf8, + 0x3f, 0x1f, 0x06, 0xf2, 0x4f, 0xcb, 0x97, 0xa0, 0x4a, 0x59, 0xc6, 0x78, + 0xd1, 0xe8, 0x03, 0xb9, 0x85, 0x6d, 0x2c, 0xba, 0xe1, 0x5f, 0xb6, 0xad, + 0x2b, 0x3e, 0x25, 0x79, 0xc5, 0x8b, 0x56, 0xd5, 0xe3, 0x09, 0x80, 0xea, + 0xc1, 0x27, 0xc2, 0xd9, 0x0e, 0xec, 0x47, 0x0a, 0xe9, 0xd0, 0xca, 0xfc, + 0xd8, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 04:00:00:00:00:01:44:4e:f0:36:31 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA + Validity + Not Before: Feb 20 10:00:00 2014 GMT + Not After : Feb 20 10:00:00 2024 GMT + Subject: C=BE, O=GlobalSign nv-sa, CN=AlphaSSL CA - SHA256 - G2 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:da:01:ec:e4:ec:73:60:fb:7e:8f:6a:b7:c6:17: + e3:92:64:32:d4:ac:00:d9:a2:0f:b9:ed:ee:6b:8a: + 86:ca:92:67:d9:74:d7:5d:47:02:3c:8f:40:d6:9e: + 6d:14:cd:c3:da:29:39:a7:0f:05:0a:68:a2:66:1a: + 1e:c4:b2:8b:76:58:e5:ab:5d:1d:8f:40:b3:39:8b: + ef:1e:83:7d:22:d0:e3:a9:00:2e:ec:53:cf:62:19: + 85:44:28:4c:c0:27:cb:7b:0e:ec:10:64:00:10:a4: + 05:cc:a0:72:be:41:6c:31:5b:48:e4:b1:ec:b9:23: + eb:55:4d:d0:7d:62:4a:a5:b4:a5:a4:59:85:c5:25: + 91:a6:fe:a6:09:9f:06:10:6d:8f:81:0c:64:40:5e: + 73:00:9a:e0:2e:65:98:54:10:00:70:98:c8:e1:ed: + 34:5f:d8:9c:c7:0d:c0:d6:23:59:45:fc:fe:55:7a: + 86:ee:94:60:22:f1:ae:d1:e6:55:46:f6:99:c5:1b: + 08:74:5f:ac:b0:64:84:8f:89:38:1c:a1:a7:90:21: + 4f:02:6e:bd:e0:61:67:d4:f8:42:87:0f:0a:f7:c9: + 04:6d:2a:a9:2f:ef:42:a5:df:dd:a3:53:db:98:1e: + 81:f9:9a:72:7b:5a:de:4f:3e:7f:a2:58:a0:e2:17: + ad:67 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Subject Key Identifier: + F5:CD:D5:3C:08:50:F9:6A:4F:3A:B7:97:DA:56:83:E6:69:D2:68:F7 + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: https://www.alphassl.com/repository/ + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.globalsign.net/root.crl + + Authority Information Access: + OCSP - URI:http://ocsp.globalsign.com/rootr1 + + X509v3 Authority Key Identifier: + keyid:60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B + + Signature Algorithm: sha256WithRSAEncryption + 60:40:68:16:47:e7:16:8d:db:5c:a1:56:2a:cb:f4:5c:9b:b0: + 1e:a2:4b:f5:cb:02:3f:f8:0b:a1:f2:a7:42:d4:b7:4c:eb:e3: + 66:80:f3:25:43:78:2e:1b:17:56:07:52:18:cb:d1:a8:ec:e6: + fb:73:3e:a4:62:8c:80:b4:d2:c5:12:73:a3:d3:fa:02:38:be: + 63:3d:84:b8:99:c1:f1:ba:f7:9f:c3:40:d1:58:18:53:c1:62: + dd:af:18:42:7f:34:4e:c5:43:d5:71:b0:30:00:c7:e3:90:ae: + 3f:57:86:97:ce:ea:0c:12:8e:22:70:e3:66:a7:54:7f:2e:28: + cb:d4:54:d0:b3:1e:62:67:08:f9:27:e1:cb:e3:66:b8:24:1b: + 89:6a:89:44:65:f2:d9:4c:d2:58:1c:8c:4e:c0:95:a1:d4:ef: + 67:2f:38:20:e8:2e:ff:96:51:f0:ba:d8:3d:92:70:47:65:1c: + 9e:73:72:b4:60:0c:5c:e2:d1:73:76:e0:af:4e:e2:e5:37:a5: + 45:2f:8a:23:3e:87:c7:30:e6:31:38:7c:f4:dd:52:ca:f3:53: + 04:25:57:56:66:94:e8:0b:ee:e6:03:14:4e:ee:fd:6d:94:64: + 9e:5e:ce:79:d4:b2:a6:cf:40:b1:44:a8:3e:87:19:5e:e9:f8: + 21:16:59:53 +-----BEGIN CERTIFICATE----- +MIIETTCCAzWgAwIBAgILBAAAAAABRE7wNjEwDQYJKoZIhvcNAQELBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xNDAyMjAxMDAw +MDBaFw0yNDAyMjAxMDAwMDBaMEwxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMSIwIAYDVQQDExlBbHBoYVNTTCBDQSAtIFNIQTI1NiAtIEcy +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2gHs5OxzYPt+j2q3xhfj +kmQy1KwA2aIPue3ua4qGypJn2XTXXUcCPI9A1p5tFM3D2ik5pw8FCmiiZhoexLKL +dljlq10dj0CzOYvvHoN9ItDjqQAu7FPPYhmFRChMwCfLew7sEGQAEKQFzKByvkFs +MVtI5LHsuSPrVU3QfWJKpbSlpFmFxSWRpv6mCZ8GEG2PgQxkQF5zAJrgLmWYVBAA +cJjI4e00X9icxw3A1iNZRfz+VXqG7pRgIvGu0eZVRvaZxRsIdF+ssGSEj4k4HKGn +kCFPAm694GFn1PhChw8K98kEbSqpL+9Cpd/do1PbmB6B+Zpye1reTz5/olig4het +ZwIDAQABo4IBIzCCAR8wDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8C +AQAwHQYDVR0OBBYEFPXN1TwIUPlqTzq3l9pWg+Zp0mj3MEUGA1UdIAQ+MDwwOgYE +VR0gADAyMDAGCCsGAQUFBwIBFiRodHRwczovL3d3dy5hbHBoYXNzbC5jb20vcmVw +b3NpdG9yeS8wMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nbG9iYWxzaWdu +Lm5ldC9yb290LmNybDA9BggrBgEFBQcBAQQxMC8wLQYIKwYBBQUHMAGGIWh0dHA6 +Ly9vY3NwLmdsb2JhbHNpZ24uY29tL3Jvb3RyMTAfBgNVHSMEGDAWgBRge2YaRQ2X +yolQL30EzTSo//z9SzANBgkqhkiG9w0BAQsFAAOCAQEAYEBoFkfnFo3bXKFWKsv0 +XJuwHqJL9csCP/gLofKnQtS3TOvjZoDzJUN4LhsXVgdSGMvRqOzm+3M+pGKMgLTS +xRJzo9P6Aji+Yz2EuJnB8br3n8NA0VgYU8Fi3a8YQn80TsVD1XGwMADH45CuP1eG +l87qDBKOInDjZqdUfy4oy9RU0LMeYmcI+Sfhy+NmuCQbiWqJRGXy2UzSWByMTsCV +odTvZy84IOgu/5ZR8LrYPZJwR2UcnnNytGAMXOLRc3bgr07i5TelRS+KIz6HxzDm +MTh89N1SyvNTBCVXVmaU6Avu5gMUTu79bZRknl7OedSyps9AsUSoPocZXun4IRZZ +Uw== +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert9[] = { + 0x30, 0x82, 0x04, 0x4d, 0x30, 0x82, 0x03, 0x35, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0x4e, 0xf0, + 0x36, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x57, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, + 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x07, 0x52, 0x6f, + 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, + 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, + 0x17, 0x0d, 0x31, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x4c, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, + 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, + 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x41, + 0x6c, 0x70, 0x68, 0x61, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, + 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, 0x47, 0x32, + 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, 0xda, 0x01, 0xec, + 0xe4, 0xec, 0x73, 0x60, 0xfb, 0x7e, 0x8f, 0x6a, 0xb7, 0xc6, 0x17, 0xe3, + 0x92, 0x64, 0x32, 0xd4, 0xac, 0x00, 0xd9, 0xa2, 0x0f, 0xb9, 0xed, 0xee, + 0x6b, 0x8a, 0x86, 0xca, 0x92, 0x67, 0xd9, 0x74, 0xd7, 0x5d, 0x47, 0x02, + 0x3c, 0x8f, 0x40, 0xd6, 0x9e, 0x6d, 0x14, 0xcd, 0xc3, 0xda, 0x29, 0x39, + 0xa7, 0x0f, 0x05, 0x0a, 0x68, 0xa2, 0x66, 0x1a, 0x1e, 0xc4, 0xb2, 0x8b, + 0x76, 0x58, 0xe5, 0xab, 0x5d, 0x1d, 0x8f, 0x40, 0xb3, 0x39, 0x8b, 0xef, + 0x1e, 0x83, 0x7d, 0x22, 0xd0, 0xe3, 0xa9, 0x00, 0x2e, 0xec, 0x53, 0xcf, + 0x62, 0x19, 0x85, 0x44, 0x28, 0x4c, 0xc0, 0x27, 0xcb, 0x7b, 0x0e, 0xec, + 0x10, 0x64, 0x00, 0x10, 0xa4, 0x05, 0xcc, 0xa0, 0x72, 0xbe, 0x41, 0x6c, + 0x31, 0x5b, 0x48, 0xe4, 0xb1, 0xec, 0xb9, 0x23, 0xeb, 0x55, 0x4d, 0xd0, + 0x7d, 0x62, 0x4a, 0xa5, 0xb4, 0xa5, 0xa4, 0x59, 0x85, 0xc5, 0x25, 0x91, + 0xa6, 0xfe, 0xa6, 0x09, 0x9f, 0x06, 0x10, 0x6d, 0x8f, 0x81, 0x0c, 0x64, + 0x40, 0x5e, 0x73, 0x00, 0x9a, 0xe0, 0x2e, 0x65, 0x98, 0x54, 0x10, 0x00, + 0x70, 0x98, 0xc8, 0xe1, 0xed, 0x34, 0x5f, 0xd8, 0x9c, 0xc7, 0x0d, 0xc0, + 0xd6, 0x23, 0x59, 0x45, 0xfc, 0xfe, 0x55, 0x7a, 0x86, 0xee, 0x94, 0x60, + 0x22, 0xf1, 0xae, 0xd1, 0xe6, 0x55, 0x46, 0xf6, 0x99, 0xc5, 0x1b, 0x08, + 0x74, 0x5f, 0xac, 0xb0, 0x64, 0x84, 0x8f, 0x89, 0x38, 0x1c, 0xa1, 0xa7, + 0x90, 0x21, 0x4f, 0x02, 0x6e, 0xbd, 0xe0, 0x61, 0x67, 0xd4, 0xf8, 0x42, + 0x87, 0x0f, 0x0a, 0xf7, 0xc9, 0x04, 0x6d, 0x2a, 0xa9, 0x2f, 0xef, 0x42, + 0xa5, 0xdf, 0xdd, 0xa3, 0x53, 0xdb, 0x98, 0x1e, 0x81, 0xf9, 0x9a, 0x72, + 0x7b, 0x5a, 0xde, 0x4f, 0x3e, 0x7f, 0xa2, 0x58, 0xa0, 0xe2, 0x17, 0xad, + 0x67, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x23, 0x30, 0x82, + 0x01, 0x1f, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, + 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, + 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, + 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, + 0x14, 0xf5, 0xcd, 0xd5, 0x3c, 0x08, 0x50, 0xf9, 0x6a, 0x4f, 0x3a, 0xb7, + 0x97, 0xda, 0x56, 0x83, 0xe6, 0x69, 0xd2, 0x68, 0xf7, 0x30, 0x45, 0x06, + 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3e, 0x30, 0x3c, 0x30, 0x3a, 0x06, 0x04, + 0x55, 0x1d, 0x20, 0x00, 0x30, 0x32, 0x30, 0x30, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x24, 0x68, 0x74, 0x74, 0x70, + 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x30, 0x33, 0x06, 0x03, + 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, + 0x24, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, + 0x6c, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, + 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, + 0x6c, 0x30, 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, + 0x01, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, + 0x6f, 0x74, 0x72, 0x31, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, + 0x18, 0x30, 0x16, 0x80, 0x14, 0x60, 0x7b, 0x66, 0x1a, 0x45, 0x0d, 0x97, + 0xca, 0x89, 0x50, 0x2f, 0x7d, 0x04, 0xcd, 0x34, 0xa8, 0xff, 0xfc, 0xfd, + 0x4b, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x60, 0x40, 0x68, + 0x16, 0x47, 0xe7, 0x16, 0x8d, 0xdb, 0x5c, 0xa1, 0x56, 0x2a, 0xcb, 0xf4, + 0x5c, 0x9b, 0xb0, 0x1e, 0xa2, 0x4b, 0xf5, 0xcb, 0x02, 0x3f, 0xf8, 0x0b, + 0xa1, 0xf2, 0xa7, 0x42, 0xd4, 0xb7, 0x4c, 0xeb, 0xe3, 0x66, 0x80, 0xf3, + 0x25, 0x43, 0x78, 0x2e, 0x1b, 0x17, 0x56, 0x07, 0x52, 0x18, 0xcb, 0xd1, + 0xa8, 0xec, 0xe6, 0xfb, 0x73, 0x3e, 0xa4, 0x62, 0x8c, 0x80, 0xb4, 0xd2, + 0xc5, 0x12, 0x73, 0xa3, 0xd3, 0xfa, 0x02, 0x38, 0xbe, 0x63, 0x3d, 0x84, + 0xb8, 0x99, 0xc1, 0xf1, 0xba, 0xf7, 0x9f, 0xc3, 0x40, 0xd1, 0x58, 0x18, + 0x53, 0xc1, 0x62, 0xdd, 0xaf, 0x18, 0x42, 0x7f, 0x34, 0x4e, 0xc5, 0x43, + 0xd5, 0x71, 0xb0, 0x30, 0x00, 0xc7, 0xe3, 0x90, 0xae, 0x3f, 0x57, 0x86, + 0x97, 0xce, 0xea, 0x0c, 0x12, 0x8e, 0x22, 0x70, 0xe3, 0x66, 0xa7, 0x54, + 0x7f, 0x2e, 0x28, 0xcb, 0xd4, 0x54, 0xd0, 0xb3, 0x1e, 0x62, 0x67, 0x08, + 0xf9, 0x27, 0xe1, 0xcb, 0xe3, 0x66, 0xb8, 0x24, 0x1b, 0x89, 0x6a, 0x89, + 0x44, 0x65, 0xf2, 0xd9, 0x4c, 0xd2, 0x58, 0x1c, 0x8c, 0x4e, 0xc0, 0x95, + 0xa1, 0xd4, 0xef, 0x67, 0x2f, 0x38, 0x20, 0xe8, 0x2e, 0xff, 0x96, 0x51, + 0xf0, 0xba, 0xd8, 0x3d, 0x92, 0x70, 0x47, 0x65, 0x1c, 0x9e, 0x73, 0x72, + 0xb4, 0x60, 0x0c, 0x5c, 0xe2, 0xd1, 0x73, 0x76, 0xe0, 0xaf, 0x4e, 0xe2, + 0xe5, 0x37, 0xa5, 0x45, 0x2f, 0x8a, 0x23, 0x3e, 0x87, 0xc7, 0x30, 0xe6, + 0x31, 0x38, 0x7c, 0xf4, 0xdd, 0x52, 0xca, 0xf3, 0x53, 0x04, 0x25, 0x57, + 0x56, 0x66, 0x94, 0xe8, 0x0b, 0xee, 0xe6, 0x03, 0x14, 0x4e, 0xee, 0xfd, + 0x6d, 0x94, 0x64, 0x9e, 0x5e, 0xce, 0x79, 0xd4, 0xb2, 0xa6, 0xcf, 0x40, + 0xb1, 0x44, 0xa8, 0x3e, 0x87, 0x19, 0x5e, 0xe9, 0xf8, 0x21, 0x16, 0x59, + 0x53, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 146031 (0x23a6f) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA + Validity + Not Before: Nov 5 21:36:50 2013 GMT + Not After : May 20 21:36:50 2022 GMT + Subject: C=US, O=GeoTrust Inc., CN=GeoTrust SSL CA - G3 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:e3:be:7e:0a:86:a3:cf:6b:6d:3d:2b:a1:97:ad: + 49:24:4d:d7:77:b9:34:79:08:a5:9e:a2:9e:de:47: + 12:92:3d:7e:ea:19:86:b1:e8:4f:3d:5f:f7:d0:a7: + 77:9a:5b:1f:0a:03:b5:19:53:db:a5:21:94:69:63: + 9d:6a:4c:91:0c:10:47:be:11:fa:6c:86:25:b7:ab: + 04:68:42:38:09:65:f0:14:da:19:9e:fa:6b:0b:ab: + 62:ef:8d:a7:ef:63:70:23:a8:af:81:f3:d1:6e:88: + 67:53:ec:12:a4:29:75:8a:a7:f2:57:3d:a2:83:98: + 97:f2:0a:7d:d4:e7:43:6e:30:78:62:22:59:59:b8: + 71:27:45:aa:0f:66:c6:55:3f:fa:32:17:2b:31:8f: + 46:a0:fa:69:14:7c:9d:9f:5a:e2:eb:33:4e:10:a6: + b3:ed:77:63:d8:c3:9e:f4:dd:df:79:9a:7a:d4:ee: + de:dd:9a:cc:c3:b7:a9:5d:cc:11:3a:07:bb:6f:97: + a4:01:23:47:95:1f:a3:77:fa:58:92:c6:c7:d0:bd: + cf:93:18:42:b7:7e:f7:9e:65:ea:d5:3b:ca:ed:ac: + c5:70:a1:fe:d4:10:9a:f0:12:04:44:ac:1a:5b:78: + 50:45:57:4c:6f:bd:80:cb:81:5c:2d:b3:bc:76:a1: + 1e:65 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Authority Key Identifier: + keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E + + X509v3 Subject Key Identifier: + D2:6F:F7:96:F4:85:3F:72:3C:30:7D:23:DA:85:78:9B:A3:7C:5A:7C + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 CRL Distribution Points: + + Full Name: + URI:http://g1.symcb.com/crls/gtglobal.crl + + Authority Information Access: + OCSP - URI:http://g2.symcb.com + + X509v3 Certificate Policies: + Policy: 2.16.840.1.113733.1.7.54 + CPS: http://www.geotrust.com/resources/cps + + X509v3 Subject Alternative Name: + DirName:/CN=SymantecPKI-1-539 + Signature Algorithm: sha256WithRSAEncryption + a0:d4:f7:2c:fb:74:0b:7f:64:f1:cd:43:6a:9f:62:53:1c:02: + 7c:98:90:a2:ee:4f:68:d4:20:1a:73:12:3e:77:b3:50:eb:72: + bc:ee:88:be:7f:17:ea:77:8f:83:61:95:4f:84:a1:cb:32:4f: + 6c:21:be:d2:69:96:7d:63:bd:dc:2b:a8:1f:d0:13:84:70:fe: + f6:35:95:89:f9:a6:77:b0:46:c8:bb:b7:13:f5:c9:60:69:d6: + 4c:fe:d2:8e:ef:d3:60:c1:80:80:e1:e7:fb:8b:6f:21:79:4a: + e0:dc:a9:1b:c1:b7:fb:c3:49:59:5c:b5:77:07:44:d4:97:fc: + 49:00:89:6f:06:4e:01:70:19:ac:2f:11:c0:e2:e6:0f:2f:86: + 4b:8d:7b:c3:b9:a7:2e:f4:f1:ac:16:3e:39:49:51:9e:17:4b: + 4f:10:3a:5b:a5:a8:92:6f:fd:fa:d6:0b:03:4d:47:56:57:19: + f3:cb:6b:f5:f3:d6:cf:b0:f5:f5:a3:11:d2:20:53:13:34:37: + 05:2c:43:5a:63:df:8d:40:d6:85:1e:51:e9:51:17:1e:03:56: + c9:f1:30:ad:e7:9b:11:a2:b9:d0:31:81:9b:68:b1:d9:e8:f3: + e6:94:7e:c7:ae:13:2f:87:ed:d0:25:b0:68:f9:de:08:5a:f3: + 29:cc:d4:92 +-----BEGIN CERTIFICATE----- +MIIETzCCAzegAwIBAgIDAjpvMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMTMxMTA1MjEzNjUwWhcNMjIwNTIwMjEzNjUwWjBEMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg +U1NMIENBIC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDjvn4K +hqPPa209K6GXrUkkTdd3uTR5CKWeop7eRxKSPX7qGYax6E89X/fQp3eaWx8KA7UZ +U9ulIZRpY51qTJEMEEe+EfpshiW3qwRoQjgJZfAU2hme+msLq2LvjafvY3AjqK+B +89FuiGdT7BKkKXWKp/JXPaKDmJfyCn3U50NuMHhiIllZuHEnRaoPZsZVP/oyFysx +j0ag+mkUfJ2fWuLrM04QprPtd2PYw5703d95mnrU7t7dmszDt6ldzBE6B7tvl6QB +I0eVH6N3+liSxsfQvc+TGEK3fveeZerVO8rtrMVwof7UEJrwEgRErBpbeFBFV0xv +vYDLgVwts7x2oR5lAgMBAAGjggFKMIIBRjAfBgNVHSMEGDAWgBTAephojYn7qwVk +DBF9qn1luMrMTjAdBgNVHQ4EFgQU0m/3lvSFP3I8MH0j2oV4m6N8WnwwEgYDVR0T +AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwNgYDVR0fBC8wLTAroCmgJ4Yl +aHR0cDovL2cxLnN5bWNiLmNvbS9jcmxzL2d0Z2xvYmFsLmNybDAvBggrBgEFBQcB +AQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9nMi5zeW1jYi5jb20wTAYDVR0gBEUw +QzBBBgpghkgBhvhFAQc2MDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93d3cuZ2VvdHJ1 +c3QuY29tL3Jlc291cmNlcy9jcHMwKQYDVR0RBCIwIKQeMBwxGjAYBgNVBAMTEVN5 +bWFudGVjUEtJLTEtNTM5MA0GCSqGSIb3DQEBCwUAA4IBAQCg1Pcs+3QLf2TxzUNq +n2JTHAJ8mJCi7k9o1CAacxI+d7NQ63K87oi+fxfqd4+DYZVPhKHLMk9sIb7SaZZ9 +Y73cK6gf0BOEcP72NZWJ+aZ3sEbIu7cT9clgadZM/tKO79NgwYCA4ef7i28heUrg +3Kkbwbf7w0lZXLV3B0TUl/xJAIlvBk4BcBmsLxHA4uYPL4ZLjXvDuacu9PGsFj45 +SVGeF0tPEDpbpaiSb/361gsDTUdWVxnzy2v189bPsPX1oxHSIFMTNDcFLENaY9+N +QNaFHlHpURceA1bJ8TCt55sRornQMYGbaLHZ6PPmlH7HrhMvh+3QJbBo+d4IWvMp +zNSS +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert10[] = { + 0x30, 0x82, 0x04, 0x4f, 0x30, 0x82, 0x03, 0x37, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x03, 0x02, 0x3a, 0x6f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, + 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, + 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, + 0x31, 0x30, 0x35, 0x32, 0x31, 0x33, 0x36, 0x35, 0x30, 0x5a, 0x17, 0x0d, + 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x31, 0x33, 0x36, 0x35, 0x30, + 0x5a, 0x30, 0x44, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 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, 0xe3, 0xbe, 0x7e, 0x0a, + 0x86, 0xa3, 0xcf, 0x6b, 0x6d, 0x3d, 0x2b, 0xa1, 0x97, 0xad, 0x49, 0x24, + 0x4d, 0xd7, 0x77, 0xb9, 0x34, 0x79, 0x08, 0xa5, 0x9e, 0xa2, 0x9e, 0xde, + 0x47, 0x12, 0x92, 0x3d, 0x7e, 0xea, 0x19, 0x86, 0xb1, 0xe8, 0x4f, 0x3d, + 0x5f, 0xf7, 0xd0, 0xa7, 0x77, 0x9a, 0x5b, 0x1f, 0x0a, 0x03, 0xb5, 0x19, + 0x53, 0xdb, 0xa5, 0x21, 0x94, 0x69, 0x63, 0x9d, 0x6a, 0x4c, 0x91, 0x0c, + 0x10, 0x47, 0xbe, 0x11, 0xfa, 0x6c, 0x86, 0x25, 0xb7, 0xab, 0x04, 0x68, + 0x42, 0x38, 0x09, 0x65, 0xf0, 0x14, 0xda, 0x19, 0x9e, 0xfa, 0x6b, 0x0b, + 0xab, 0x62, 0xef, 0x8d, 0xa7, 0xef, 0x63, 0x70, 0x23, 0xa8, 0xaf, 0x81, + 0xf3, 0xd1, 0x6e, 0x88, 0x67, 0x53, 0xec, 0x12, 0xa4, 0x29, 0x75, 0x8a, + 0xa7, 0xf2, 0x57, 0x3d, 0xa2, 0x83, 0x98, 0x97, 0xf2, 0x0a, 0x7d, 0xd4, + 0xe7, 0x43, 0x6e, 0x30, 0x78, 0x62, 0x22, 0x59, 0x59, 0xb8, 0x71, 0x27, + 0x45, 0xaa, 0x0f, 0x66, 0xc6, 0x55, 0x3f, 0xfa, 0x32, 0x17, 0x2b, 0x31, + 0x8f, 0x46, 0xa0, 0xfa, 0x69, 0x14, 0x7c, 0x9d, 0x9f, 0x5a, 0xe2, 0xeb, + 0x33, 0x4e, 0x10, 0xa6, 0xb3, 0xed, 0x77, 0x63, 0xd8, 0xc3, 0x9e, 0xf4, + 0xdd, 0xdf, 0x79, 0x9a, 0x7a, 0xd4, 0xee, 0xde, 0xdd, 0x9a, 0xcc, 0xc3, + 0xb7, 0xa9, 0x5d, 0xcc, 0x11, 0x3a, 0x07, 0xbb, 0x6f, 0x97, 0xa4, 0x01, + 0x23, 0x47, 0x95, 0x1f, 0xa3, 0x77, 0xfa, 0x58, 0x92, 0xc6, 0xc7, 0xd0, + 0xbd, 0xcf, 0x93, 0x18, 0x42, 0xb7, 0x7e, 0xf7, 0x9e, 0x65, 0xea, 0xd5, + 0x3b, 0xca, 0xed, 0xac, 0xc5, 0x70, 0xa1, 0xfe, 0xd4, 0x10, 0x9a, 0xf0, + 0x12, 0x04, 0x44, 0xac, 0x1a, 0x5b, 0x78, 0x50, 0x45, 0x57, 0x4c, 0x6f, + 0xbd, 0x80, 0xcb, 0x81, 0x5c, 0x2d, 0xb3, 0xbc, 0x76, 0xa1, 0x1e, 0x65, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x4a, 0x30, 0x82, 0x01, + 0x46, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64, + 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x1d, + 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xd2, 0x6f, 0xf7, + 0x96, 0xf4, 0x85, 0x3f, 0x72, 0x3c, 0x30, 0x7d, 0x23, 0xda, 0x85, 0x78, + 0x9b, 0xa3, 0x7c, 0x5a, 0x7c, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, + 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, + 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x36, 0x06, 0x03, 0x55, 0x1d, 0x1f, + 0x04, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27, 0x86, 0x25, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x31, 0x2e, 0x73, 0x79, + 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, + 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72, + 0x6c, 0x30, 0x2f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, + 0x01, 0x04, 0x23, 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x67, 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, + 0x43, 0x30, 0x41, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, + 0x01, 0x07, 0x36, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x29, 0x06, 0x03, + 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, + 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, + 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, + 0x35, 0x33, 0x39, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xa0, + 0xd4, 0xf7, 0x2c, 0xfb, 0x74, 0x0b, 0x7f, 0x64, 0xf1, 0xcd, 0x43, 0x6a, + 0x9f, 0x62, 0x53, 0x1c, 0x02, 0x7c, 0x98, 0x90, 0xa2, 0xee, 0x4f, 0x68, + 0xd4, 0x20, 0x1a, 0x73, 0x12, 0x3e, 0x77, 0xb3, 0x50, 0xeb, 0x72, 0xbc, + 0xee, 0x88, 0xbe, 0x7f, 0x17, 0xea, 0x77, 0x8f, 0x83, 0x61, 0x95, 0x4f, + 0x84, 0xa1, 0xcb, 0x32, 0x4f, 0x6c, 0x21, 0xbe, 0xd2, 0x69, 0x96, 0x7d, + 0x63, 0xbd, 0xdc, 0x2b, 0xa8, 0x1f, 0xd0, 0x13, 0x84, 0x70, 0xfe, 0xf6, + 0x35, 0x95, 0x89, 0xf9, 0xa6, 0x77, 0xb0, 0x46, 0xc8, 0xbb, 0xb7, 0x13, + 0xf5, 0xc9, 0x60, 0x69, 0xd6, 0x4c, 0xfe, 0xd2, 0x8e, 0xef, 0xd3, 0x60, + 0xc1, 0x80, 0x80, 0xe1, 0xe7, 0xfb, 0x8b, 0x6f, 0x21, 0x79, 0x4a, 0xe0, + 0xdc, 0xa9, 0x1b, 0xc1, 0xb7, 0xfb, 0xc3, 0x49, 0x59, 0x5c, 0xb5, 0x77, + 0x07, 0x44, 0xd4, 0x97, 0xfc, 0x49, 0x00, 0x89, 0x6f, 0x06, 0x4e, 0x01, + 0x70, 0x19, 0xac, 0x2f, 0x11, 0xc0, 0xe2, 0xe6, 0x0f, 0x2f, 0x86, 0x4b, + 0x8d, 0x7b, 0xc3, 0xb9, 0xa7, 0x2e, 0xf4, 0xf1, 0xac, 0x16, 0x3e, 0x39, + 0x49, 0x51, 0x9e, 0x17, 0x4b, 0x4f, 0x10, 0x3a, 0x5b, 0xa5, 0xa8, 0x92, + 0x6f, 0xfd, 0xfa, 0xd6, 0x0b, 0x03, 0x4d, 0x47, 0x56, 0x57, 0x19, 0xf3, + 0xcb, 0x6b, 0xf5, 0xf3, 0xd6, 0xcf, 0xb0, 0xf5, 0xf5, 0xa3, 0x11, 0xd2, + 0x20, 0x53, 0x13, 0x34, 0x37, 0x05, 0x2c, 0x43, 0x5a, 0x63, 0xdf, 0x8d, + 0x40, 0xd6, 0x85, 0x1e, 0x51, 0xe9, 0x51, 0x17, 0x1e, 0x03, 0x56, 0xc9, + 0xf1, 0x30, 0xad, 0xe7, 0x9b, 0x11, 0xa2, 0xb9, 0xd0, 0x31, 0x81, 0x9b, + 0x68, 0xb1, 0xd9, 0xe8, 0xf3, 0xe6, 0x94, 0x7e, 0xc7, 0xae, 0x13, 0x2f, + 0x87, 0xed, 0xd0, 0x25, 0xb0, 0x68, 0xf9, 0xde, 0x08, 0x5a, 0xf3, 0x29, + 0xcc, 0xd4, 0x92, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 146019 (0x23a63) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA + Validity + Not Before: Aug 27 20:40:40 2012 GMT + Not After : May 20 20:40:40 2022 GMT + Subject: C=US, O=GeoTrust Inc., CN=GeoTrust SSL CA - G2 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:b9:27:f9:4f:d8:f6:b7:15:3f:8f:cd:ce:d6:8d: + 1c:6b:fd:7f:da:54:21:4e:03:d8:ca:d0:72:52:15: + b8:c9:82:5b:58:79:84:ff:24:72:6f:f2:69:7f:bc: + 96:d9:9a:7a:c3:3e:a9:cf:50:22:13:0e:86:19:db: + e8:49:ef:8b:e6:d6:47:f2:fd:73:45:08:ae:8f:ac: + 5e:b6:f8:9e:7c:f7:10:ff:92:43:66:ef:1c:d4:ee: + a1:46:88:11:89:49:79:7a:25:ce:4b:6a:f0:d7:1c: + 76:1a:29:3c:c9:e4:fd:1e:85:dc:e0:31:65:05:47: + 16:ac:0a:07:4b:2e:70:5e:6b:06:a7:6b:3a:6c:af: + 05:12:c4:b2:11:25:d6:3e:97:29:f0:83:6c:57:1c: + d8:a5:ef:cc:ec:fd:d6:12:f1:3f:db:40:b4:ae:0f: + 18:d3:c5:af:40:92:5d:07:5e:4e:fe:62:17:37:89: + e9:8b:74:26:a2:ed:b8:0a:e7:6c:15:5b:35:90:72: + dd:d8:4d:21:d4:40:23:5c:8f:ee:80:31:16:ab:68: + 55:f4:0e:3b:54:e9:04:4d:f0:cc:4e:81:5e:e9:6f: + 52:69:4e:be:a6:16:6d:42:f5:51:ff:e0:0b:56:3c: + 98:4f:73:8f:0e:6f:1a:23:f1:c9:c8:d9:df:bc:ec: + 52:d7 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Authority Key Identifier: + keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E + + X509v3 Subject Key Identifier: + 11:4A:D0:73:39:D5:5B:69:08:5C:BA:3D:BF:64:9A:A8:8B:1C:55:BC + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.geotrust.com/crls/gtglobal.crl + + Authority Information Access: + OCSP - URI:http://ocsp.geotrust.com + + X509v3 Certificate Policies: + Policy: 2.16.840.1.113733.1.7.54 + CPS: http://www.geotrust.com/resources/cps + + X509v3 Subject Alternative Name: + DirName:/CN=VeriSignMPKI-2-254 + Signature Algorithm: sha1WithRSAEncryption + 3c:e5:3d:5a:1b:a2:37:2a:e3:46:cf:36:96:18:3c:7b:f1:84: + c5:57:86:77:40:9d:35:f0:12:f0:78:18:fb:22:a4:de:98:4b: + 78:81:e6:4d:86:e3:91:0f:42:e3:b9:dc:a0:d6:ff:a9:f8:b1: + 79:97:99:d1:c3:6c:42:a5:92:94:e0:5d:0c:33:18:25:c9:2b: + 95:53:e0:e5:a9:0c:7d:47:fe:7f:51:31:44:5e:f7:2a:1e:35: + a2:94:32:f7:c9:ee:c0:b6:c6:9a:ac:de:99:21:6a:23:a0:38: + 64:ee:a3:c4:88:73:32:3b:50:ce:bf:ad:d3:75:1e:a6:f4:e9: + f9:42:6b:60:b2:dd:45:fd:5d:57:08:ce:2d:50:e6:12:32:16: + 13:8a:f2:94:a2:9b:47:a8:86:7f:d9:98:e5:f7:e5:76:74:64: + d8:91:bc:84:16:28:d8:25:44:30:7e:82:d8:ac:b1:e4:c0:e4: + 15:6c:db:b6:24:27:02:2a:01:12:85:ba:31:88:58:47:74:e3: + b8:d2:64:a6:c3:32:59:2e:29:4b:45:f1:5b:89:49:2e:82:9a: + c6:18:15:44:d0:2e:64:01:15:68:38:f9:f6:f9:66:03:0c:55: + 1b:9d:bf:00:40:ae:f0:48:27:4c:e0:80:5e:2d:b9:2a:15:7a: + bc:66:f8:35 +-----BEGIN CERTIFICATE----- +MIIEWTCCA0GgAwIBAgIDAjpjMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMTIwODI3MjA0MDQwWhcNMjIwNTIwMjA0MDQwWjBEMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg +U1NMIENBIC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5J/lP +2Pa3FT+Pzc7WjRxr/X/aVCFOA9jK0HJSFbjJgltYeYT/JHJv8ml/vJbZmnrDPqnP +UCITDoYZ2+hJ74vm1kfy/XNFCK6PrF62+J589xD/kkNm7xzU7qFGiBGJSXl6Jc5L +avDXHHYaKTzJ5P0ehdzgMWUFRxasCgdLLnBeawanazpsrwUSxLIRJdY+lynwg2xX +HNil78zs/dYS8T/bQLSuDxjTxa9Akl0HXk7+Yhc3iemLdCai7bgK52wVWzWQct3Y +TSHUQCNcj+6AMRaraFX0DjtU6QRN8MxOgV7pb1JpTr6mFm1C9VH/4AtWPJhPc48O +bxoj8cnI2d+87FLXAgMBAAGjggFUMIIBUDAfBgNVHSMEGDAWgBTAephojYn7qwVk +DBF9qn1luMrMTjAdBgNVHQ4EFgQUEUrQcznVW2kIXLo9v2SaqIscVbwwEgYDVR0T +AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMwMTAvoC2gK4Yp +aHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwNAYIKwYB +BQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5nZW90cnVzdC5jb20w +TAYDVR0gBEUwQzBBBgpghkgBhvhFAQc2MDMwMQYIKwYBBQUHAgEWJWh0dHA6Ly93 +d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwKgYDVR0RBCMwIaQfMB0xGzAZ +BgNVBAMTElZlcmlTaWduTVBLSS0yLTI1NDANBgkqhkiG9w0BAQUFAAOCAQEAPOU9 +WhuiNyrjRs82lhg8e/GExVeGd0CdNfAS8HgY+yKk3phLeIHmTYbjkQ9C47ncoNb/ +qfixeZeZ0cNsQqWSlOBdDDMYJckrlVPg5akMfUf+f1ExRF73Kh41opQy98nuwLbG +mqzemSFqI6A4ZO6jxIhzMjtQzr+t03UepvTp+UJrYLLdRf1dVwjOLVDmEjIWE4ry +lKKbR6iGf9mY5ffldnRk2JG8hBYo2CVEMH6C2Kyx5MDkFWzbtiQnAioBEoW6MYhY +R3TjuNJkpsMyWS4pS0XxW4lJLoKaxhgVRNAuZAEVaDj59vlmAwxVG52/AECu8Egn +TOCAXi25KhV6vGb4NQ== +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert11[] = { + 0x30, 0x82, 0x04, 0x59, 0x30, 0x82, 0x03, 0x41, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x03, 0x02, 0x3a, 0x63, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x42, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, + 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, + 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x32, 0x30, + 0x38, 0x32, 0x37, 0x32, 0x30, 0x34, 0x30, 0x34, 0x30, 0x5a, 0x17, 0x0d, + 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x30, 0x34, 0x30, 0x34, 0x30, + 0x5a, 0x30, 0x44, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x14, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x32, 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, 0xb9, 0x27, 0xf9, 0x4f, + 0xd8, 0xf6, 0xb7, 0x15, 0x3f, 0x8f, 0xcd, 0xce, 0xd6, 0x8d, 0x1c, 0x6b, + 0xfd, 0x7f, 0xda, 0x54, 0x21, 0x4e, 0x03, 0xd8, 0xca, 0xd0, 0x72, 0x52, + 0x15, 0xb8, 0xc9, 0x82, 0x5b, 0x58, 0x79, 0x84, 0xff, 0x24, 0x72, 0x6f, + 0xf2, 0x69, 0x7f, 0xbc, 0x96, 0xd9, 0x9a, 0x7a, 0xc3, 0x3e, 0xa9, 0xcf, + 0x50, 0x22, 0x13, 0x0e, 0x86, 0x19, 0xdb, 0xe8, 0x49, 0xef, 0x8b, 0xe6, + 0xd6, 0x47, 0xf2, 0xfd, 0x73, 0x45, 0x08, 0xae, 0x8f, 0xac, 0x5e, 0xb6, + 0xf8, 0x9e, 0x7c, 0xf7, 0x10, 0xff, 0x92, 0x43, 0x66, 0xef, 0x1c, 0xd4, + 0xee, 0xa1, 0x46, 0x88, 0x11, 0x89, 0x49, 0x79, 0x7a, 0x25, 0xce, 0x4b, + 0x6a, 0xf0, 0xd7, 0x1c, 0x76, 0x1a, 0x29, 0x3c, 0xc9, 0xe4, 0xfd, 0x1e, + 0x85, 0xdc, 0xe0, 0x31, 0x65, 0x05, 0x47, 0x16, 0xac, 0x0a, 0x07, 0x4b, + 0x2e, 0x70, 0x5e, 0x6b, 0x06, 0xa7, 0x6b, 0x3a, 0x6c, 0xaf, 0x05, 0x12, + 0xc4, 0xb2, 0x11, 0x25, 0xd6, 0x3e, 0x97, 0x29, 0xf0, 0x83, 0x6c, 0x57, + 0x1c, 0xd8, 0xa5, 0xef, 0xcc, 0xec, 0xfd, 0xd6, 0x12, 0xf1, 0x3f, 0xdb, + 0x40, 0xb4, 0xae, 0x0f, 0x18, 0xd3, 0xc5, 0xaf, 0x40, 0x92, 0x5d, 0x07, + 0x5e, 0x4e, 0xfe, 0x62, 0x17, 0x37, 0x89, 0xe9, 0x8b, 0x74, 0x26, 0xa2, + 0xed, 0xb8, 0x0a, 0xe7, 0x6c, 0x15, 0x5b, 0x35, 0x90, 0x72, 0xdd, 0xd8, + 0x4d, 0x21, 0xd4, 0x40, 0x23, 0x5c, 0x8f, 0xee, 0x80, 0x31, 0x16, 0xab, + 0x68, 0x55, 0xf4, 0x0e, 0x3b, 0x54, 0xe9, 0x04, 0x4d, 0xf0, 0xcc, 0x4e, + 0x81, 0x5e, 0xe9, 0x6f, 0x52, 0x69, 0x4e, 0xbe, 0xa6, 0x16, 0x6d, 0x42, + 0xf5, 0x51, 0xff, 0xe0, 0x0b, 0x56, 0x3c, 0x98, 0x4f, 0x73, 0x8f, 0x0e, + 0x6f, 0x1a, 0x23, 0xf1, 0xc9, 0xc8, 0xd9, 0xdf, 0xbc, 0xec, 0x52, 0xd7, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x54, 0x30, 0x82, 0x01, + 0x50, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64, + 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x1d, + 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x11, 0x4a, 0xd0, + 0x73, 0x39, 0xd5, 0x5b, 0x69, 0x08, 0x5c, 0xba, 0x3d, 0xbf, 0x64, 0x9a, + 0xa8, 0x8b, 0x1c, 0x55, 0xbc, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, + 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, + 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x1d, 0x1f, + 0x04, 0x33, 0x30, 0x31, 0x30, 0x2f, 0xa0, 0x2d, 0xa0, 0x2b, 0x86, 0x29, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67, + 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, + 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, + 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, + 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, + 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x36, + 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, + 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x1d, 0x11, + 0x04, 0x23, 0x30, 0x21, 0xa4, 0x1f, 0x30, 0x1d, 0x31, 0x1b, 0x30, 0x19, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x56, 0x65, 0x72, 0x69, 0x53, + 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49, 0x2d, 0x32, 0x2d, 0x32, 0x35, + 0x34, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x3c, 0xe5, 0x3d, + 0x5a, 0x1b, 0xa2, 0x37, 0x2a, 0xe3, 0x46, 0xcf, 0x36, 0x96, 0x18, 0x3c, + 0x7b, 0xf1, 0x84, 0xc5, 0x57, 0x86, 0x77, 0x40, 0x9d, 0x35, 0xf0, 0x12, + 0xf0, 0x78, 0x18, 0xfb, 0x22, 0xa4, 0xde, 0x98, 0x4b, 0x78, 0x81, 0xe6, + 0x4d, 0x86, 0xe3, 0x91, 0x0f, 0x42, 0xe3, 0xb9, 0xdc, 0xa0, 0xd6, 0xff, + 0xa9, 0xf8, 0xb1, 0x79, 0x97, 0x99, 0xd1, 0xc3, 0x6c, 0x42, 0xa5, 0x92, + 0x94, 0xe0, 0x5d, 0x0c, 0x33, 0x18, 0x25, 0xc9, 0x2b, 0x95, 0x53, 0xe0, + 0xe5, 0xa9, 0x0c, 0x7d, 0x47, 0xfe, 0x7f, 0x51, 0x31, 0x44, 0x5e, 0xf7, + 0x2a, 0x1e, 0x35, 0xa2, 0x94, 0x32, 0xf7, 0xc9, 0xee, 0xc0, 0xb6, 0xc6, + 0x9a, 0xac, 0xde, 0x99, 0x21, 0x6a, 0x23, 0xa0, 0x38, 0x64, 0xee, 0xa3, + 0xc4, 0x88, 0x73, 0x32, 0x3b, 0x50, 0xce, 0xbf, 0xad, 0xd3, 0x75, 0x1e, + 0xa6, 0xf4, 0xe9, 0xf9, 0x42, 0x6b, 0x60, 0xb2, 0xdd, 0x45, 0xfd, 0x5d, + 0x57, 0x08, 0xce, 0x2d, 0x50, 0xe6, 0x12, 0x32, 0x16, 0x13, 0x8a, 0xf2, + 0x94, 0xa2, 0x9b, 0x47, 0xa8, 0x86, 0x7f, 0xd9, 0x98, 0xe5, 0xf7, 0xe5, + 0x76, 0x74, 0x64, 0xd8, 0x91, 0xbc, 0x84, 0x16, 0x28, 0xd8, 0x25, 0x44, + 0x30, 0x7e, 0x82, 0xd8, 0xac, 0xb1, 0xe4, 0xc0, 0xe4, 0x15, 0x6c, 0xdb, + 0xb6, 0x24, 0x27, 0x02, 0x2a, 0x01, 0x12, 0x85, 0xba, 0x31, 0x88, 0x58, + 0x47, 0x74, 0xe3, 0xb8, 0xd2, 0x64, 0xa6, 0xc3, 0x32, 0x59, 0x2e, 0x29, + 0x4b, 0x45, 0xf1, 0x5b, 0x89, 0x49, 0x2e, 0x82, 0x9a, 0xc6, 0x18, 0x15, + 0x44, 0xd0, 0x2e, 0x64, 0x01, 0x15, 0x68, 0x38, 0xf9, 0xf6, 0xf9, 0x66, + 0x03, 0x0c, 0x55, 0x1b, 0x9d, 0xbf, 0x00, 0x40, 0xae, 0xf0, 0x48, 0x27, + 0x4c, 0xe0, 0x80, 0x5e, 0x2d, 0xb9, 0x2a, 0x15, 0x7a, 0xbc, 0x66, 0xf8, + 0x35, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 04:00:00:00:00:01:44:4e:f0:3e:20 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA + Validity + Not Before: Feb 20 10:00:00 2014 GMT + Not After : Feb 20 10:00:00 2024 GMT + Subject: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Domain Validation CA - SHA256 - G2 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:a9:dd:cc:0e:b3:e2:32:39:dd:49:22:a8:13:69: + 93:87:88:e1:0c:ee:71:7d:bd:90:87:96:5d:59:f2: + cc:b3:d2:58:57:57:f9:46:ef:6c:26:d8:36:42:8e: + 7e:30:b3:2f:9a:3e:53:7b:1f:6e:b6:a2:4c:45:1f: + 3c:d3:15:93:1c:89:ed:3c:f4:57:de:ca:bd:ec:06: + 9a:6a:2a:a0:19:52:7f:51:d1:74:39:08:9f:ab:eb: + d7:86:13:15:97:ae:36:c3:54:66:0e:5a:f2:a0:73: + 85:31:e3:b2:64:14:6a:ff:a5:a2:8e:24:bb:bd:85: + 52:15:a2:79:ee:f0:b5:ee:3d:b8:f4:7d:80:bc:d9: + 90:35:65:b8:17:a9:ad:b3:98:9f:a0:7e:7d:6e:fb: + 3f:ad:7c:c2:1b:59:36:96:da:37:32:4b:4b:5d:35: + 02:63:8e:db:a7:cf:62:ee:cc:2e:d4:8d:c9:bd:3c: + 6a:91:72:a2:22:a7:72:2d:20:d1:fa:ca:37:da:18: + 98:e6:16:24:71:25:4b:c4:e5:7b:89:52:09:02:fd: + 59:2b:04:6e:ca:07:81:d4:b3:da:da:db:e3:cc:80: + a8:56:07:06:7c:96:08:37:9d:db:38:b6:62:34:91: + 62:07:74:01:38:d8:72:30:e2:eb:90:71:26:62:c0: + 57:f3 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Subject Key Identifier: + EA:4E:7C:D4:80:2D:E5:15:81:86:26:8C:82:6D:C0:98:A4:CF:97:0F + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: https://www.globalsign.com/repository/ + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.globalsign.net/root.crl + + Authority Information Access: + OCSP - URI:http://ocsp.globalsign.com/rootr1 + + X509v3 Authority Key Identifier: + keyid:60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B + + Signature Algorithm: sha256WithRSAEncryption + d7:45:9e:a0:dc:e0:e3:61:5a:0b:7d:77:84:17:2d:65:5a:82: + 9a:8d:a3:27:2a:85:f7:c9:ef:e9:86:fd:d4:47:cd:01:52:96: + c5:43:bd:37:b1:e1:b8:f2:a9:d2:8a:11:84:71:91:15:89:dc: + 02:9d:0b:cb:6c:33:85:34:28:9e:20:b2:b1:97:dc:6d:0b:10: + c1:3c:cd:5f:ea:5d:d7:98:31:c5:34:99:5c:00:61:55:c4:1b: + 02:5b:c5:e3:89:c8:b4:b8:6f:1e:38:f2:56:26:e9:41:ef:3d: + cd:ac:99:4f:59:4a:57:2d:4b:7d:ae:c7:88:fb:d6:98:3b:f5: + e5:f0:e8:89:89:b9:8b:03:cb:5a:23:1f:a4:fd:b8:ea:fb:2e: + 9d:ae:6a:73:09:bc:fc:d5:a0:b5:44:82:ab:44:91:2e:50:2e: + 57:c1:43:d8:91:04:8b:e9:11:2e:5f:b4:3f:79:df:1e:fb:3f: + 30:00:8b:53:e3:b7:2c:1d:3b:4d:8b:dc:e4:64:1d:04:58:33: + af:1b:55:e7:ab:0c:bf:30:04:74:e4:f3:0e:2f:30:39:8d:4b: + 04:8c:1e:75:66:66:49:e0:be:40:34:c7:5c:5a:51:92:ba:12: + 3c:52:d5:04:82:55:2d:67:a5:df:b7:95:7c:ee:3f:c3:08:ba: + 04:be:c0:46 +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgILBAAAAAABRE7wPiAwDQYJKoZIhvcNAQELBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xNDAyMjAxMDAw +MDBaFw0yNDAyMjAxMDAwMDBaMGAxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMTYwNAYDVQQDEy1HbG9iYWxTaWduIERvbWFpbiBWYWxpZGF0 +aW9uIENBIC0gU0hBMjU2IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCp3cwOs+IyOd1JIqgTaZOHiOEM7nF9vZCHll1Z8syz0lhXV/lG72wm2DZC +jn4wsy+aPlN7H262okxFHzzTFZMcie089Ffeyr3sBppqKqAZUn9R0XQ5CJ+r69eG +ExWXrjbDVGYOWvKgc4Ux47JkFGr/paKOJLu9hVIVonnu8LXuPbj0fYC82ZA1ZbgX +qa2zmJ+gfn1u+z+tfMIbWTaW2jcyS0tdNQJjjtunz2LuzC7Ujcm9PGqRcqIip3It +INH6yjfaGJjmFiRxJUvE5XuJUgkC/VkrBG7KB4HUs9ra2+PMgKhWBwZ8lgg3nds4 +tmI0kWIHdAE42HIw4uuQcSZiwFfzAgMBAAGjggElMIIBITAOBgNVHQ8BAf8EBAMC +AQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU6k581IAt5RWBhiaMgm3A +mKTPlw8wRwYDVR0gBEAwPjA8BgRVHSAAMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8v +d3d3Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMDMGA1UdHwQsMCowKKAmoCSG +Imh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5uZXQvcm9vdC5jcmwwPQYIKwYBBQUHAQEE +MTAvMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNvbS9yb290 +cjEwHwYDVR0jBBgwFoAUYHtmGkUNl8qJUC99BM00qP/8/UswDQYJKoZIhvcNAQEL +BQADggEBANdFnqDc4ONhWgt9d4QXLWVagpqNoycqhffJ7+mG/dRHzQFSlsVDvTex +4bjyqdKKEYRxkRWJ3AKdC8tsM4U0KJ4gsrGX3G0LEME8zV/qXdeYMcU0mVwAYVXE +GwJbxeOJyLS4bx448lYm6UHvPc2smU9ZSlctS32ux4j71pg79eXw6ImJuYsDy1oj +H6T9uOr7Lp2uanMJvPzVoLVEgqtEkS5QLlfBQ9iRBIvpES5ftD953x77PzAAi1Pj +tywdO02L3ORkHQRYM68bVeerDL8wBHTk8w4vMDmNSwSMHnVmZkngvkA0x1xaUZK6 +EjxS1QSCVS1npd+3lXzuP8MIugS+wEY= +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert12[] = { + 0x30, 0x82, 0x04, 0x63, 0x30, 0x82, 0x03, 0x4b, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0x4e, 0xf0, + 0x3e, 0x20, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x57, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, + 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x07, 0x52, 0x6f, + 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, + 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, + 0x17, 0x0d, 0x31, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x60, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, + 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, + 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d, 0x47, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x44, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x53, 0x48, 0x41, + 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, 0x47, 0x32, 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, 0xa9, 0xdd, 0xcc, 0x0e, 0xb3, 0xe2, 0x32, + 0x39, 0xdd, 0x49, 0x22, 0xa8, 0x13, 0x69, 0x93, 0x87, 0x88, 0xe1, 0x0c, + 0xee, 0x71, 0x7d, 0xbd, 0x90, 0x87, 0x96, 0x5d, 0x59, 0xf2, 0xcc, 0xb3, + 0xd2, 0x58, 0x57, 0x57, 0xf9, 0x46, 0xef, 0x6c, 0x26, 0xd8, 0x36, 0x42, + 0x8e, 0x7e, 0x30, 0xb3, 0x2f, 0x9a, 0x3e, 0x53, 0x7b, 0x1f, 0x6e, 0xb6, + 0xa2, 0x4c, 0x45, 0x1f, 0x3c, 0xd3, 0x15, 0x93, 0x1c, 0x89, 0xed, 0x3c, + 0xf4, 0x57, 0xde, 0xca, 0xbd, 0xec, 0x06, 0x9a, 0x6a, 0x2a, 0xa0, 0x19, + 0x52, 0x7f, 0x51, 0xd1, 0x74, 0x39, 0x08, 0x9f, 0xab, 0xeb, 0xd7, 0x86, + 0x13, 0x15, 0x97, 0xae, 0x36, 0xc3, 0x54, 0x66, 0x0e, 0x5a, 0xf2, 0xa0, + 0x73, 0x85, 0x31, 0xe3, 0xb2, 0x64, 0x14, 0x6a, 0xff, 0xa5, 0xa2, 0x8e, + 0x24, 0xbb, 0xbd, 0x85, 0x52, 0x15, 0xa2, 0x79, 0xee, 0xf0, 0xb5, 0xee, + 0x3d, 0xb8, 0xf4, 0x7d, 0x80, 0xbc, 0xd9, 0x90, 0x35, 0x65, 0xb8, 0x17, + 0xa9, 0xad, 0xb3, 0x98, 0x9f, 0xa0, 0x7e, 0x7d, 0x6e, 0xfb, 0x3f, 0xad, + 0x7c, 0xc2, 0x1b, 0x59, 0x36, 0x96, 0xda, 0x37, 0x32, 0x4b, 0x4b, 0x5d, + 0x35, 0x02, 0x63, 0x8e, 0xdb, 0xa7, 0xcf, 0x62, 0xee, 0xcc, 0x2e, 0xd4, + 0x8d, 0xc9, 0xbd, 0x3c, 0x6a, 0x91, 0x72, 0xa2, 0x22, 0xa7, 0x72, 0x2d, + 0x20, 0xd1, 0xfa, 0xca, 0x37, 0xda, 0x18, 0x98, 0xe6, 0x16, 0x24, 0x71, + 0x25, 0x4b, 0xc4, 0xe5, 0x7b, 0x89, 0x52, 0x09, 0x02, 0xfd, 0x59, 0x2b, + 0x04, 0x6e, 0xca, 0x07, 0x81, 0xd4, 0xb3, 0xda, 0xda, 0xdb, 0xe3, 0xcc, + 0x80, 0xa8, 0x56, 0x07, 0x06, 0x7c, 0x96, 0x08, 0x37, 0x9d, 0xdb, 0x38, + 0xb6, 0x62, 0x34, 0x91, 0x62, 0x07, 0x74, 0x01, 0x38, 0xd8, 0x72, 0x30, + 0xe2, 0xeb, 0x90, 0x71, 0x26, 0x62, 0xc0, 0x57, 0xf3, 0x02, 0x03, 0x01, + 0x00, 0x01, 0xa3, 0x82, 0x01, 0x25, 0x30, 0x82, 0x01, 0x21, 0x30, 0x0e, + 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, + 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, + 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x1d, + 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xea, 0x4e, 0x7c, + 0xd4, 0x80, 0x2d, 0xe5, 0x15, 0x81, 0x86, 0x26, 0x8c, 0x82, 0x6d, 0xc0, + 0x98, 0xa4, 0xcf, 0x97, 0x0f, 0x30, 0x47, 0x06, 0x03, 0x55, 0x1d, 0x20, + 0x04, 0x40, 0x30, 0x3e, 0x30, 0x3c, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, + 0x30, 0x34, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x02, 0x01, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, + 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, + 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, + 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86, + 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, + 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x6e, + 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, + 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, + 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x30, 0x01, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, + 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, + 0x72, 0x31, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, + 0x16, 0x80, 0x14, 0x60, 0x7b, 0x66, 0x1a, 0x45, 0x0d, 0x97, 0xca, 0x89, + 0x50, 0x2f, 0x7d, 0x04, 0xcd, 0x34, 0xa8, 0xff, 0xfc, 0xfd, 0x4b, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xd7, 0x45, 0x9e, 0xa0, 0xdc, + 0xe0, 0xe3, 0x61, 0x5a, 0x0b, 0x7d, 0x77, 0x84, 0x17, 0x2d, 0x65, 0x5a, + 0x82, 0x9a, 0x8d, 0xa3, 0x27, 0x2a, 0x85, 0xf7, 0xc9, 0xef, 0xe9, 0x86, + 0xfd, 0xd4, 0x47, 0xcd, 0x01, 0x52, 0x96, 0xc5, 0x43, 0xbd, 0x37, 0xb1, + 0xe1, 0xb8, 0xf2, 0xa9, 0xd2, 0x8a, 0x11, 0x84, 0x71, 0x91, 0x15, 0x89, + 0xdc, 0x02, 0x9d, 0x0b, 0xcb, 0x6c, 0x33, 0x85, 0x34, 0x28, 0x9e, 0x20, + 0xb2, 0xb1, 0x97, 0xdc, 0x6d, 0x0b, 0x10, 0xc1, 0x3c, 0xcd, 0x5f, 0xea, + 0x5d, 0xd7, 0x98, 0x31, 0xc5, 0x34, 0x99, 0x5c, 0x00, 0x61, 0x55, 0xc4, + 0x1b, 0x02, 0x5b, 0xc5, 0xe3, 0x89, 0xc8, 0xb4, 0xb8, 0x6f, 0x1e, 0x38, + 0xf2, 0x56, 0x26, 0xe9, 0x41, 0xef, 0x3d, 0xcd, 0xac, 0x99, 0x4f, 0x59, + 0x4a, 0x57, 0x2d, 0x4b, 0x7d, 0xae, 0xc7, 0x88, 0xfb, 0xd6, 0x98, 0x3b, + 0xf5, 0xe5, 0xf0, 0xe8, 0x89, 0x89, 0xb9, 0x8b, 0x03, 0xcb, 0x5a, 0x23, + 0x1f, 0xa4, 0xfd, 0xb8, 0xea, 0xfb, 0x2e, 0x9d, 0xae, 0x6a, 0x73, 0x09, + 0xbc, 0xfc, 0xd5, 0xa0, 0xb5, 0x44, 0x82, 0xab, 0x44, 0x91, 0x2e, 0x50, + 0x2e, 0x57, 0xc1, 0x43, 0xd8, 0x91, 0x04, 0x8b, 0xe9, 0x11, 0x2e, 0x5f, + 0xb4, 0x3f, 0x79, 0xdf, 0x1e, 0xfb, 0x3f, 0x30, 0x00, 0x8b, 0x53, 0xe3, + 0xb7, 0x2c, 0x1d, 0x3b, 0x4d, 0x8b, 0xdc, 0xe4, 0x64, 0x1d, 0x04, 0x58, + 0x33, 0xaf, 0x1b, 0x55, 0xe7, 0xab, 0x0c, 0xbf, 0x30, 0x04, 0x74, 0xe4, + 0xf3, 0x0e, 0x2f, 0x30, 0x39, 0x8d, 0x4b, 0x04, 0x8c, 0x1e, 0x75, 0x66, + 0x66, 0x49, 0xe0, 0xbe, 0x40, 0x34, 0xc7, 0x5c, 0x5a, 0x51, 0x92, 0xba, + 0x12, 0x3c, 0x52, 0xd5, 0x04, 0x82, 0x55, 0x2d, 0x67, 0xa5, 0xdf, 0xb7, + 0x95, 0x7c, 0xee, 0x3f, 0xc3, 0x08, 0xba, 0x04, 0xbe, 0xc0, 0x46, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 04:00:00:00:00:01:44:4e:f0:42:47 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA + Validity + Not Before: Feb 20 10:00:00 2014 GMT + Not After : Feb 20 10:00:00 2024 GMT + Subject: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Organization Validation CA - SHA256 - G2 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c7:0e:6c:3f:23:93:7f:cc:70:a5:9d:20:c3:0e: + 53:3f:7e:c0:4e:c2:98:49:ca:47:d5:23:ef:03:34: + 85:74:c8:a3:02:2e:46:5c:0b:7d:c9:88:9d:4f:8b: + f0:f8:9c:6c:8c:55:35:db:bf:f2:b3:ea:fb:e3:56: + e7:4a:46:d9:13:22:ca:36:d5:9b:c1:a8:e3:96:43: + 93:f2:0c:bc:e6:f9:e6:e8:99:c8:63:48:78:7f:57: + 36:69:1a:19:1d:5a:d1:d4:7d:c2:9c:d4:7f:e1:80: + 12:ae:7a:ea:88:ea:57:d8:ca:0a:0a:3a:12:49:a2: + 62:19:7a:0d:24:f7:37:eb:b4:73:92:7b:05:23:9b: + 12:b5:ce:eb:29:df:a4:14:02:b9:01:a5:d4:a6:9c: + 43:64:88:de:f8:7e:fe:e3:f5:1e:e5:fe:dc:a3:a8: + e4:66:31:d9:4c:25:e9:18:b9:89:59:09:ae:e9:9d: + 1c:6d:37:0f:4a:1e:35:20:28:e2:af:d4:21:8b:01: + c4:45:ad:6e:2b:63:ab:92:6b:61:0a:4d:20:ed:73: + ba:7c:ce:fe:16:b5:db:9f:80:f0:d6:8b:6c:d9:08: + 79:4a:4f:78:65:da:92:bc:be:35:f9:b3:c4:f9:27: + 80:4e:ff:96:52:e6:02:20:e1:07:73:e9:5d:2b:bd: + b2:f1 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Subject Key Identifier: + 96:DE:61:F1:BD:1C:16:29:53:1C:C0:CC:7D:3B:83:00:40:E6:1A:7C + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: https://www.globalsign.com/repository/ + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.globalsign.net/root.crl + + Authority Information Access: + OCSP - URI:http://ocsp.globalsign.com/rootr1 + + X509v3 Authority Key Identifier: + keyid:60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B + + Signature Algorithm: sha256WithRSAEncryption + 46:2a:ee:5e:bd:ae:01:60:37:31:11:86:71:74:b6:46:49:c8: + 10:16:fe:2f:62:23:17:ab:1f:87:f8:82:ed:ca:df:0e:2c:df: + 64:75:8e:e5:18:72:a7:8c:3a:8b:c9:ac:a5:77:50:f7:ef:9e: + a4:e0:a0:8f:14:57:a3:2a:5f:ec:7e:6d:10:e6:ba:8d:b0:08: + 87:76:0e:4c:b2:d9:51:bb:11:02:f2:5c:dd:1c:bd:f3:55:96: + 0f:d4:06:c0:fc:e2:23:8a:24:70:d3:bb:f0:79:1a:a7:61:70: + 83:8a:af:06:c5:20:d8:a1:63:d0:6c:ae:4f:32:d7:ae:7c:18: + 45:75:05:29:77:df:42:40:64:64:86:be:2a:76:09:31:6f:1d: + 24:f4:99:d0:85:fe:f2:21:08:f9:c6:f6:f1:d0:59:ed:d6:56: + 3c:08:28:03:67:ba:f0:f9:f1:90:16:47:ae:67:e6:bc:80:48: + e9:42:76:34:97:55:69:24:0e:83:d6:a0:2d:b4:f5:f3:79:8a: + 49:28:74:1a:41:a1:c2:d3:24:88:35:30:60:94:17:b4:e1:04: + 22:31:3d:3b:2f:17:06:b2:b8:9d:86:2b:5a:69:ef:83:f5:4b: + c4:aa:b4:2a:f8:7c:a1:b1:85:94:8c:f4:0c:87:0c:f4:ac:40: + f8:59:49:98 +-----BEGIN CERTIFICATE----- +MIIEaTCCA1GgAwIBAgILBAAAAAABRE7wQkcwDQYJKoZIhvcNAQELBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xNDAyMjAxMDAw +MDBaFw0yNDAyMjAxMDAwMDBaMGYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMTwwOgYDVQQDEzNHbG9iYWxTaWduIE9yZ2FuaXphdGlvbiBW +YWxpZGF0aW9uIENBIC0gU0hBMjU2IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDHDmw/I5N/zHClnSDDDlM/fsBOwphJykfVI+8DNIV0yKMCLkZc +C33JiJ1Pi/D4nGyMVTXbv/Kz6vvjVudKRtkTIso21ZvBqOOWQ5PyDLzm+ebomchj +SHh/VzZpGhkdWtHUfcKc1H/hgBKueuqI6lfYygoKOhJJomIZeg0k9zfrtHOSewUj +mxK1zusp36QUArkBpdSmnENkiN74fv7j9R7l/tyjqORmMdlMJekYuYlZCa7pnRxt +Nw9KHjUgKOKv1CGLAcRFrW4rY6uSa2EKTSDtc7p8zv4WtdufgPDWi2zZCHlKT3hl +2pK8vjX5s8T5J4BO/5ZS5gIg4Qdz6V0rvbLxAgMBAAGjggElMIIBITAOBgNVHQ8B +Af8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUlt5h8b0cFilT +HMDMfTuDAEDmGnwwRwYDVR0gBEAwPjA8BgRVHSAAMDQwMgYIKwYBBQUHAgEWJmh0 +dHBzOi8vd3d3Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMDMGA1UdHwQsMCow +KKAmoCSGImh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5uZXQvcm9vdC5jcmwwPQYIKwYB +BQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNv +bS9yb290cjEwHwYDVR0jBBgwFoAUYHtmGkUNl8qJUC99BM00qP/8/UswDQYJKoZI +hvcNAQELBQADggEBAEYq7l69rgFgNzERhnF0tkZJyBAW/i9iIxerH4f4gu3K3w4s +32R1juUYcqeMOovJrKV3UPfvnqTgoI8UV6MqX+x+bRDmuo2wCId2Dkyy2VG7EQLy +XN0cvfNVlg/UBsD84iOKJHDTu/B5GqdhcIOKrwbFINihY9Bsrk8y1658GEV1BSl3 +30JAZGSGvip2CTFvHST0mdCF/vIhCPnG9vHQWe3WVjwIKANnuvD58ZAWR65n5ryA +SOlCdjSXVWkkDoPWoC209fN5ikkodBpBocLTJIg1MGCUF7ThBCIxPTsvFwayuJ2G +K1pp74P1S8SqtCr4fKGxhZSM9AyHDPSsQPhZSZg= +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert13[] = { + 0x30, 0x82, 0x04, 0x69, 0x30, 0x82, 0x03, 0x51, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0x4e, 0xf0, + 0x42, 0x47, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x57, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, 0x17, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, 0x31, + 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x07, 0x52, 0x6f, + 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, + 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, + 0x17, 0x0d, 0x31, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x32, 0x32, 0x30, 0x31, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x66, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, 0x19, 0x30, + 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, 0x73, 0x61, + 0x31, 0x3c, 0x30, 0x3a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x33, 0x47, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x4f, 0x72, + 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x41, + 0x20, 0x2d, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, + 0x47, 0x32, 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, 0xc7, + 0x0e, 0x6c, 0x3f, 0x23, 0x93, 0x7f, 0xcc, 0x70, 0xa5, 0x9d, 0x20, 0xc3, + 0x0e, 0x53, 0x3f, 0x7e, 0xc0, 0x4e, 0xc2, 0x98, 0x49, 0xca, 0x47, 0xd5, + 0x23, 0xef, 0x03, 0x34, 0x85, 0x74, 0xc8, 0xa3, 0x02, 0x2e, 0x46, 0x5c, + 0x0b, 0x7d, 0xc9, 0x88, 0x9d, 0x4f, 0x8b, 0xf0, 0xf8, 0x9c, 0x6c, 0x8c, + 0x55, 0x35, 0xdb, 0xbf, 0xf2, 0xb3, 0xea, 0xfb, 0xe3, 0x56, 0xe7, 0x4a, + 0x46, 0xd9, 0x13, 0x22, 0xca, 0x36, 0xd5, 0x9b, 0xc1, 0xa8, 0xe3, 0x96, + 0x43, 0x93, 0xf2, 0x0c, 0xbc, 0xe6, 0xf9, 0xe6, 0xe8, 0x99, 0xc8, 0x63, + 0x48, 0x78, 0x7f, 0x57, 0x36, 0x69, 0x1a, 0x19, 0x1d, 0x5a, 0xd1, 0xd4, + 0x7d, 0xc2, 0x9c, 0xd4, 0x7f, 0xe1, 0x80, 0x12, 0xae, 0x7a, 0xea, 0x88, + 0xea, 0x57, 0xd8, 0xca, 0x0a, 0x0a, 0x3a, 0x12, 0x49, 0xa2, 0x62, 0x19, + 0x7a, 0x0d, 0x24, 0xf7, 0x37, 0xeb, 0xb4, 0x73, 0x92, 0x7b, 0x05, 0x23, + 0x9b, 0x12, 0xb5, 0xce, 0xeb, 0x29, 0xdf, 0xa4, 0x14, 0x02, 0xb9, 0x01, + 0xa5, 0xd4, 0xa6, 0x9c, 0x43, 0x64, 0x88, 0xde, 0xf8, 0x7e, 0xfe, 0xe3, + 0xf5, 0x1e, 0xe5, 0xfe, 0xdc, 0xa3, 0xa8, 0xe4, 0x66, 0x31, 0xd9, 0x4c, + 0x25, 0xe9, 0x18, 0xb9, 0x89, 0x59, 0x09, 0xae, 0xe9, 0x9d, 0x1c, 0x6d, + 0x37, 0x0f, 0x4a, 0x1e, 0x35, 0x20, 0x28, 0xe2, 0xaf, 0xd4, 0x21, 0x8b, + 0x01, 0xc4, 0x45, 0xad, 0x6e, 0x2b, 0x63, 0xab, 0x92, 0x6b, 0x61, 0x0a, + 0x4d, 0x20, 0xed, 0x73, 0xba, 0x7c, 0xce, 0xfe, 0x16, 0xb5, 0xdb, 0x9f, + 0x80, 0xf0, 0xd6, 0x8b, 0x6c, 0xd9, 0x08, 0x79, 0x4a, 0x4f, 0x78, 0x65, + 0xda, 0x92, 0xbc, 0xbe, 0x35, 0xf9, 0xb3, 0xc4, 0xf9, 0x27, 0x80, 0x4e, + 0xff, 0x96, 0x52, 0xe6, 0x02, 0x20, 0xe1, 0x07, 0x73, 0xe9, 0x5d, 0x2b, + 0xbd, 0xb2, 0xf1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x25, + 0x30, 0x82, 0x01, 0x21, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, + 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, + 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, + 0xff, 0x02, 0x01, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, + 0x16, 0x04, 0x14, 0x96, 0xde, 0x61, 0xf1, 0xbd, 0x1c, 0x16, 0x29, 0x53, + 0x1c, 0xc0, 0xcc, 0x7d, 0x3b, 0x83, 0x00, 0x40, 0xe6, 0x1a, 0x7c, 0x30, + 0x47, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x40, 0x30, 0x3e, 0x30, 0x3c, + 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x34, 0x30, 0x32, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x26, 0x68, 0x74, + 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x6c, + 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, + 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, + 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, + 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f, + 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06, + 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x21, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x72, 0x31, 0x30, 0x1f, 0x06, 0x03, + 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x60, 0x7b, 0x66, + 0x1a, 0x45, 0x0d, 0x97, 0xca, 0x89, 0x50, 0x2f, 0x7d, 0x04, 0xcd, 0x34, + 0xa8, 0xff, 0xfc, 0xfd, 0x4b, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, + 0x00, 0x46, 0x2a, 0xee, 0x5e, 0xbd, 0xae, 0x01, 0x60, 0x37, 0x31, 0x11, + 0x86, 0x71, 0x74, 0xb6, 0x46, 0x49, 0xc8, 0x10, 0x16, 0xfe, 0x2f, 0x62, + 0x23, 0x17, 0xab, 0x1f, 0x87, 0xf8, 0x82, 0xed, 0xca, 0xdf, 0x0e, 0x2c, + 0xdf, 0x64, 0x75, 0x8e, 0xe5, 0x18, 0x72, 0xa7, 0x8c, 0x3a, 0x8b, 0xc9, + 0xac, 0xa5, 0x77, 0x50, 0xf7, 0xef, 0x9e, 0xa4, 0xe0, 0xa0, 0x8f, 0x14, + 0x57, 0xa3, 0x2a, 0x5f, 0xec, 0x7e, 0x6d, 0x10, 0xe6, 0xba, 0x8d, 0xb0, + 0x08, 0x87, 0x76, 0x0e, 0x4c, 0xb2, 0xd9, 0x51, 0xbb, 0x11, 0x02, 0xf2, + 0x5c, 0xdd, 0x1c, 0xbd, 0xf3, 0x55, 0x96, 0x0f, 0xd4, 0x06, 0xc0, 0xfc, + 0xe2, 0x23, 0x8a, 0x24, 0x70, 0xd3, 0xbb, 0xf0, 0x79, 0x1a, 0xa7, 0x61, + 0x70, 0x83, 0x8a, 0xaf, 0x06, 0xc5, 0x20, 0xd8, 0xa1, 0x63, 0xd0, 0x6c, + 0xae, 0x4f, 0x32, 0xd7, 0xae, 0x7c, 0x18, 0x45, 0x75, 0x05, 0x29, 0x77, + 0xdf, 0x42, 0x40, 0x64, 0x64, 0x86, 0xbe, 0x2a, 0x76, 0x09, 0x31, 0x6f, + 0x1d, 0x24, 0xf4, 0x99, 0xd0, 0x85, 0xfe, 0xf2, 0x21, 0x08, 0xf9, 0xc6, + 0xf6, 0xf1, 0xd0, 0x59, 0xed, 0xd6, 0x56, 0x3c, 0x08, 0x28, 0x03, 0x67, + 0xba, 0xf0, 0xf9, 0xf1, 0x90, 0x16, 0x47, 0xae, 0x67, 0xe6, 0xbc, 0x80, + 0x48, 0xe9, 0x42, 0x76, 0x34, 0x97, 0x55, 0x69, 0x24, 0x0e, 0x83, 0xd6, + 0xa0, 0x2d, 0xb4, 0xf5, 0xf3, 0x79, 0x8a, 0x49, 0x28, 0x74, 0x1a, 0x41, + 0xa1, 0xc2, 0xd3, 0x24, 0x88, 0x35, 0x30, 0x60, 0x94, 0x17, 0xb4, 0xe1, + 0x04, 0x22, 0x31, 0x3d, 0x3b, 0x2f, 0x17, 0x06, 0xb2, 0xb8, 0x9d, 0x86, + 0x2b, 0x5a, 0x69, 0xef, 0x83, 0xf5, 0x4b, 0xc4, 0xaa, 0xb4, 0x2a, 0xf8, + 0x7c, 0xa1, 0xb1, 0x85, 0x94, 0x8c, 0xf4, 0x0c, 0x87, 0x0c, 0xf4, 0xac, + 0x40, 0xf8, 0x59, 0x49, 0x98, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 4d:5f:2c:34:08:b2:4c:20:cd:6d:50:7e:24:4d:c9:ec + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA + Validity + Not Before: Feb 8 00:00:00 2010 GMT + Not After : Feb 7 23:59:59 2020 GMT + Subject: C=US, O=Thawte, Inc., CN=Thawte SSL CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:99:e4:85:5b:76:49:7d:2f:05:d8:c5:ac:c8:c8: + a9:d3:dc:98:e6:d7:34:a6:2f:0c:f2:22:26:d8:a3: + c9:14:4c:8f:05:a4:45:e8:14:0c:58:90:05:1a:b7: + c5:c1:06:a5:80:af:bb:1d:49:6b:52:34:88:c3:59: + e7:ef:6b:c4:27:41:8c:2b:66:1d:d0:e0:a3:97:98: + 19:34:4b:41:d5:98:d5:c7:05:ad:a2:e4:d7:ed:0c: + ad:4f:c1:b5:b0:21:fd:3e:50:53:b2:c4:90:d0:d4: + 30:67:6c:9a:f1:0e:74:c4:c2:dc:8a:e8:97:ff:c9: + 92:ae:01:8a:56:0a:98:32:b0:00:23:ec:90:1a:60: + c3:ed:bb:3a:cb:0f:63:9f:0d:44:c9:52:e1:25:96: + bf:ed:50:95:89:7f:56:14:b1:b7:61:1d:1c:07:8c: + 3a:2c:f7:ff:80:de:39:45:d5:af:1a:d1:78:d8:c7: + 71:6a:a3:19:a7:32:50:21:e9:f2:0e:a1:c6:13:03: + 44:48:d1:66:a8:52:57:d7:11:b4:93:8b:e5:99:9f: + 5d:e7:78:51:e5:4d:f6:b7:59:b4:76:b5:09:37:4d: + 06:38:13:7a:1c:08:98:5c:c4:48:4a:cb:52:a0:a9: + f8:b1:9d:8e:7b:79:b0:20:2f:3c:96:a8:11:62:47: + bb:11 + Exponent: 65537 (0x10001) + X509v3 extensions: + Authority Information Access: + OCSP - URI:http://ocsp.thawte.com + + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.thawte.com/ThawtePCA.crl + + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Alternative Name: + DirName:/CN=VeriSignMPKI-2-9 + X509v3 Subject Key Identifier: + A7:A2:83:BB:34:45:40:3D:FC:D5:30:4F:12:B9:3E:A1:01:9F:F6:DB + X509v3 Authority Key Identifier: + keyid:7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50 + + Signature Algorithm: sha1WithRSAEncryption + 80:22:80:e0:6c:c8:95:16:d7:57:26:87:f3:72:34:db:c6:72: + 56:27:3e:d3:96:f6:2e:25:91:a5:3e:33:97:a7:4b:e5:2f:fb: + 25:7d:2f:07:61:fa:6f:83:74:4c:4c:53:72:20:a4:7a:cf:51: + 51:56:81:88:b0:6d:1f:36:2c:c8:2b:b1:88:99:c1:fe:44:ab: + 48:51:7c:d8:f2:44:64:2a:d8:71:a7:fb:1a:2f:f9:19:8d:34: + b2:23:bf:c4:4c:55:1d:8e:44:e8:aa:5d:9a:dd:9f:fd:03:c7: + ba:24:43:8d:2d:47:44:db:f6:d8:98:c8:b2:f9:da:ef:ed:29: + 5c:69:12:fa:d1:23:96:0f:bf:9c:0d:f2:79:45:53:37:9a:56: + 2f:e8:57:10:70:f6:ee:89:0c:49:89:9a:c1:23:f5:c2:2a:cc: + 41:cf:22:ab:65:6e:b7:94:82:6d:2f:40:5f:58:de:eb:95:2b: + a6:72:68:52:19:91:2a:ae:75:9d:4e:92:e6:ca:de:54:ea:18: + ab:25:3c:e6:64:a6:79:1f:26:7d:61:ed:7d:d2:e5:71:55:d8: + 93:17:7c:14:38:30:3c:df:86:e3:4c:ad:49:e3:97:59:ce:1b: + 9b:2b:ce:dc:65:d4:0b:28:6b:4e:84:46:51:44:f7:33:08:2d: + 58:97:21:ae +-----BEGIN CERTIFICATE----- +MIIEbDCCA1SgAwIBAgIQTV8sNAiyTCDNbVB+JE3J7DANBgkqhkiG9w0BAQUFADCB +qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV +BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTAwMjA4MDAwMDAwWhcNMjAw +MjA3MjM1OTU5WjA8MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMVGhhd3RlLCBJbmMu +MRYwFAYDVQQDEw1UaGF3dGUgU1NMIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAmeSFW3ZJfS8F2MWsyMip09yY5tc0pi8M8iIm2KPJFEyPBaRF6BQM +WJAFGrfFwQalgK+7HUlrUjSIw1nn72vEJ0GMK2Yd0OCjl5gZNEtB1ZjVxwWtouTX +7QytT8G1sCH9PlBTssSQ0NQwZ2ya8Q50xMLciuiX/8mSrgGKVgqYMrAAI+yQGmDD +7bs6yw9jnw1EyVLhJZa/7VCViX9WFLG3YR0cB4w6LPf/gN45RdWvGtF42MdxaqMZ +pzJQIenyDqHGEwNESNFmqFJX1xG0k4vlmZ9d53hR5U32t1m0drUJN00GOBN6HAiY +XMRISstSoKn4sZ2Oe3mwIC88lqgRYke7EQIDAQABo4H7MIH4MDIGCCsGAQUFBwEB +BCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL29jc3AudGhhd3RlLmNvbTASBgNVHRMB +Af8ECDAGAQH/AgEAMDQGA1UdHwQtMCswKaAnoCWGI2h0dHA6Ly9jcmwudGhhd3Rl +LmNvbS9UaGF3dGVQQ0EuY3JsMA4GA1UdDwEB/wQEAwIBBjAoBgNVHREEITAfpB0w +GzEZMBcGA1UEAxMQVmVyaVNpZ25NUEtJLTItOTAdBgNVHQ4EFgQUp6KDuzRFQD38 +1TBPErk+oQGf9tswHwYDVR0jBBgwFoAUe1tFz6/Oy3r9MZIaarbzRutXSFAwDQYJ +KoZIhvcNAQEFBQADggEBAIAigOBsyJUW11cmh/NyNNvGclYnPtOW9i4lkaU+M5en +S+Uv+yV9Lwdh+m+DdExMU3IgpHrPUVFWgYiwbR82LMgrsYiZwf5Eq0hRfNjyRGQq +2HGn+xov+RmNNLIjv8RMVR2OROiqXZrdn/0Dx7okQ40tR0Tb9tiYyLL52u/tKVxp +EvrRI5YPv5wN8nlFUzeaVi/oVxBw9u6JDEmJmsEj9cIqzEHPIqtlbreUgm0vQF9Y +3uuVK6ZyaFIZkSqudZ1OkubK3lTqGKslPOZkpnkfJn1h7X3S5XFV2JMXfBQ4MDzf +huNMrUnjl1nOG5srztxl1Asoa06ERlFE9zMILViXIa4= +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert14[] = { + 0x30, 0x82, 0x04, 0x6c, 0x30, 0x82, 0x03, 0x54, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x4d, 0x5f, 0x2c, 0x34, 0x08, 0xb2, 0x4c, 0x20, 0xcd, + 0x6d, 0x50, 0x7e, 0x24, 0x4d, 0xc9, 0xec, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x81, + 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, + 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44, + 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06, + 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, + 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, + 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, + 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, + 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x30, 0x30, 0x32, 0x30, 0x38, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x30, 0x30, + 0x32, 0x30, 0x37, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x3c, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, + 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0d, 0x54, + 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 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, 0x99, 0xe4, 0x85, + 0x5b, 0x76, 0x49, 0x7d, 0x2f, 0x05, 0xd8, 0xc5, 0xac, 0xc8, 0xc8, 0xa9, + 0xd3, 0xdc, 0x98, 0xe6, 0xd7, 0x34, 0xa6, 0x2f, 0x0c, 0xf2, 0x22, 0x26, + 0xd8, 0xa3, 0xc9, 0x14, 0x4c, 0x8f, 0x05, 0xa4, 0x45, 0xe8, 0x14, 0x0c, + 0x58, 0x90, 0x05, 0x1a, 0xb7, 0xc5, 0xc1, 0x06, 0xa5, 0x80, 0xaf, 0xbb, + 0x1d, 0x49, 0x6b, 0x52, 0x34, 0x88, 0xc3, 0x59, 0xe7, 0xef, 0x6b, 0xc4, + 0x27, 0x41, 0x8c, 0x2b, 0x66, 0x1d, 0xd0, 0xe0, 0xa3, 0x97, 0x98, 0x19, + 0x34, 0x4b, 0x41, 0xd5, 0x98, 0xd5, 0xc7, 0x05, 0xad, 0xa2, 0xe4, 0xd7, + 0xed, 0x0c, 0xad, 0x4f, 0xc1, 0xb5, 0xb0, 0x21, 0xfd, 0x3e, 0x50, 0x53, + 0xb2, 0xc4, 0x90, 0xd0, 0xd4, 0x30, 0x67, 0x6c, 0x9a, 0xf1, 0x0e, 0x74, + 0xc4, 0xc2, 0xdc, 0x8a, 0xe8, 0x97, 0xff, 0xc9, 0x92, 0xae, 0x01, 0x8a, + 0x56, 0x0a, 0x98, 0x32, 0xb0, 0x00, 0x23, 0xec, 0x90, 0x1a, 0x60, 0xc3, + 0xed, 0xbb, 0x3a, 0xcb, 0x0f, 0x63, 0x9f, 0x0d, 0x44, 0xc9, 0x52, 0xe1, + 0x25, 0x96, 0xbf, 0xed, 0x50, 0x95, 0x89, 0x7f, 0x56, 0x14, 0xb1, 0xb7, + 0x61, 0x1d, 0x1c, 0x07, 0x8c, 0x3a, 0x2c, 0xf7, 0xff, 0x80, 0xde, 0x39, + 0x45, 0xd5, 0xaf, 0x1a, 0xd1, 0x78, 0xd8, 0xc7, 0x71, 0x6a, 0xa3, 0x19, + 0xa7, 0x32, 0x50, 0x21, 0xe9, 0xf2, 0x0e, 0xa1, 0xc6, 0x13, 0x03, 0x44, + 0x48, 0xd1, 0x66, 0xa8, 0x52, 0x57, 0xd7, 0x11, 0xb4, 0x93, 0x8b, 0xe5, + 0x99, 0x9f, 0x5d, 0xe7, 0x78, 0x51, 0xe5, 0x4d, 0xf6, 0xb7, 0x59, 0xb4, + 0x76, 0xb5, 0x09, 0x37, 0x4d, 0x06, 0x38, 0x13, 0x7a, 0x1c, 0x08, 0x98, + 0x5c, 0xc4, 0x48, 0x4a, 0xcb, 0x52, 0xa0, 0xa9, 0xf8, 0xb1, 0x9d, 0x8e, + 0x7b, 0x79, 0xb0, 0x20, 0x2f, 0x3c, 0x96, 0xa8, 0x11, 0x62, 0x47, 0xbb, + 0x11, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xfb, 0x30, 0x81, 0xf8, + 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, + 0x04, 0x26, 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, + 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, + 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, + 0x30, 0x34, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2d, 0x30, 0x2b, 0x30, + 0x29, 0xa0, 0x27, 0xa0, 0x25, 0x86, 0x23, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, + 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x28, + 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x21, 0x30, 0x1f, 0xa4, 0x1d, 0x30, + 0x1b, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, + 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49, + 0x2d, 0x32, 0x2d, 0x39, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, + 0x16, 0x04, 0x14, 0xa7, 0xa2, 0x83, 0xbb, 0x34, 0x45, 0x40, 0x3d, 0xfc, + 0xd5, 0x30, 0x4f, 0x12, 0xb9, 0x3e, 0xa1, 0x01, 0x9f, 0xf6, 0xdb, 0x30, + 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, + 0x7b, 0x5b, 0x45, 0xcf, 0xaf, 0xce, 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a, + 0x6a, 0xb6, 0xf3, 0x46, 0xeb, 0x57, 0x48, 0x50, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x01, 0x00, 0x80, 0x22, 0x80, 0xe0, 0x6c, 0xc8, 0x95, 0x16, + 0xd7, 0x57, 0x26, 0x87, 0xf3, 0x72, 0x34, 0xdb, 0xc6, 0x72, 0x56, 0x27, + 0x3e, 0xd3, 0x96, 0xf6, 0x2e, 0x25, 0x91, 0xa5, 0x3e, 0x33, 0x97, 0xa7, + 0x4b, 0xe5, 0x2f, 0xfb, 0x25, 0x7d, 0x2f, 0x07, 0x61, 0xfa, 0x6f, 0x83, + 0x74, 0x4c, 0x4c, 0x53, 0x72, 0x20, 0xa4, 0x7a, 0xcf, 0x51, 0x51, 0x56, + 0x81, 0x88, 0xb0, 0x6d, 0x1f, 0x36, 0x2c, 0xc8, 0x2b, 0xb1, 0x88, 0x99, + 0xc1, 0xfe, 0x44, 0xab, 0x48, 0x51, 0x7c, 0xd8, 0xf2, 0x44, 0x64, 0x2a, + 0xd8, 0x71, 0xa7, 0xfb, 0x1a, 0x2f, 0xf9, 0x19, 0x8d, 0x34, 0xb2, 0x23, + 0xbf, 0xc4, 0x4c, 0x55, 0x1d, 0x8e, 0x44, 0xe8, 0xaa, 0x5d, 0x9a, 0xdd, + 0x9f, 0xfd, 0x03, 0xc7, 0xba, 0x24, 0x43, 0x8d, 0x2d, 0x47, 0x44, 0xdb, + 0xf6, 0xd8, 0x98, 0xc8, 0xb2, 0xf9, 0xda, 0xef, 0xed, 0x29, 0x5c, 0x69, + 0x12, 0xfa, 0xd1, 0x23, 0x96, 0x0f, 0xbf, 0x9c, 0x0d, 0xf2, 0x79, 0x45, + 0x53, 0x37, 0x9a, 0x56, 0x2f, 0xe8, 0x57, 0x10, 0x70, 0xf6, 0xee, 0x89, + 0x0c, 0x49, 0x89, 0x9a, 0xc1, 0x23, 0xf5, 0xc2, 0x2a, 0xcc, 0x41, 0xcf, + 0x22, 0xab, 0x65, 0x6e, 0xb7, 0x94, 0x82, 0x6d, 0x2f, 0x40, 0x5f, 0x58, + 0xde, 0xeb, 0x95, 0x2b, 0xa6, 0x72, 0x68, 0x52, 0x19, 0x91, 0x2a, 0xae, + 0x75, 0x9d, 0x4e, 0x92, 0xe6, 0xca, 0xde, 0x54, 0xea, 0x18, 0xab, 0x25, + 0x3c, 0xe6, 0x64, 0xa6, 0x79, 0x1f, 0x26, 0x7d, 0x61, 0xed, 0x7d, 0xd2, + 0xe5, 0x71, 0x55, 0xd8, 0x93, 0x17, 0x7c, 0x14, 0x38, 0x30, 0x3c, 0xdf, + 0x86, 0xe3, 0x4c, 0xad, 0x49, 0xe3, 0x97, 0x59, 0xce, 0x1b, 0x9b, 0x2b, + 0xce, 0xdc, 0x65, 0xd4, 0x0b, 0x28, 0x6b, 0x4e, 0x84, 0x46, 0x51, 0x44, + 0xf7, 0x33, 0x08, 0x2d, 0x58, 0x97, 0x21, 0xae, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 6e:8a:90:eb:cf:f0:44:8a:72:0d:08:05:d0:82:a5:44 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Primary Certification Authority + Validity + Not Before: Oct 31 00:00:00 2013 GMT + Not After : Oct 30 23:59:59 2023 GMT + Subject: C=US, O=GeoTrust Inc., CN=GeoTrust EV SSL CA - G4 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:d9:b4:05:f2:38:67:0f:09:e7:7c:f5:63:2a:e5: + b9:5e:a8:11:ae:75:71:d9:4c:84:67:ad:89:5d:fc: + 28:3d:2a:b0:a5:d5:d4:e6:30:0a:84:d4:e4:18:cb: + 85:37:c5:46:71:eb:1c:7b:69:db:65:69:8c:30:05: + 3e:07:e1:6f:3c:c1:0b:61:e6:38:44:fc:bc:8c:2f: + 4e:75:57:f5:96:99:7c:3e:87:1f:0f:90:4b:70:c3: + 3f:39:45:3b:3a:6b:cb:bb:7b:40:54:d1:8b:4b:a1: + 72:d2:04:e9:e0:72:1a:93:11:7a:2f:f1:ab:9d:9c: + 98:58:ae:2c:ea:77:5f:2f:2e:87:af:b8:6b:e3:e2: + e2:3f:d6:3d:e0:96:44:df:11:55:63:52:2f:f4:26: + 78:c4:0f:20:4d:0a:c0:68:70:15:86:38:ee:b7:76: + 88:ab:18:8f:4f:35:1e:d4:8c:c9:db:7e:3d:44:d4: + 36:8c:c1:37:b5:59:5b:87:f9:e9:f1:d4:c5:28:bd: + 1d:dc:cc:96:72:d1:7a:a1:a7:20:b5:b8:af:f8:6e: + a5:60:7b:2b:8d:1f:ee:f4:2b:d6:69:cd:af:ca:80: + 58:29:e8:4c:00:20:8a:49:0a:6e:8e:8c:a8:d1:00: + 12:84:b6:c5:e2:95:a2:c0:3b:a4:6b:f0:82:d0:96: + 5d:25 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + Authority Information Access: + OCSP - URI:http://g2.symcb.com + + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: https://www.geotrust.com/resources/cps + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://g1.symcb.com/GeoTrustPCA.crl + + X509v3 Subject Alternative Name: + DirName:/CN=SymantecPKI-1-538 + X509v3 Subject Key Identifier: + DE:CF:5C:50:B7:AE:02:1F:15:17:AA:16:E8:0D:B5:28:9D:6A:5A:F3 + X509v3 Authority Key Identifier: + keyid:2C:D5:50:41:97:15:8B:F0:8F:36:61:5B:4A:FB:6B:D9:99:C9:33:92 + + Signature Algorithm: sha256WithRSAEncryption + b4:8e:bd:07:b9:9a:85:ec:3b:67:bd:07:60:61:e6:84:d1:d4: + ef:eb:1b:ba:0b:82:4b:95:64:b6:66:53:23:bd:b7:84:dd:e4: + 7b:8d:09:da:cf:b2:f5:f1:c3:bf:87:84:be:4e:a6:a8:c2:e7: + 12:39:28:34:e0:a4:56:44:40:0c:9f:88:a3:15:d3:e8:d3:5e: + e3:1c:04:60:fb:69:36:4f:6a:7e:0c:2a:28:c1:f3:aa:58:0e: + 6c:ce:1d:07:c3:4a:c0:9c:8d:c3:74:b1:ae:82:f0:1a:e1:f9: + 4e:29:bd:46:de:b7:1d:f9:7d:db:d9:0f:84:cb:92:45:cc:1c: + b3:18:f6:a0:cf:71:6f:0c:2e:9b:d2:2d:b3:99:93:83:44:ac: + 15:aa:9b:2e:67:ec:4f:88:69:05:56:7b:8b:b2:43:a9:3a:6c: + 1c:13:33:25:1b:fd:a8:c8:57:02:fb:1c:e0:d1:bd:3b:56:44: + 65:c3:63:f5:1b:ef:ec:30:d9:e3:6e:2e:13:e9:39:08:2a:0c: + 72:f3:9a:cc:f6:27:29:84:d3:ef:4c:c7:84:11:65:1f:c6:e3: + 81:03:db:87:cc:78:f7:b5:9d:96:3e:6a:7f:bc:11:85:7a:75: + e6:41:7d:0d:cf:f9:e5:85:69:25:8f:c7:8d:07:2d:f8:69:0f: + cb:41:53:00 +-----BEGIN CERTIFICATE----- +MIIEbjCCA1agAwIBAgIQboqQ68/wRIpyDQgF0IKlRDANBgkqhkiG9w0BAQsFADBY +MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo +R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xMzEw +MzEwMDAwMDBaFw0yMzEwMzAyMzU5NTlaMEcxCzAJBgNVBAYTAlVTMRYwFAYDVQQK +Ew1HZW9UcnVzdCBJbmMuMSAwHgYDVQQDExdHZW9UcnVzdCBFViBTU0wgQ0EgLSBH +NDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANm0BfI4Zw8J53z1Yyrl +uV6oEa51cdlMhGetiV38KD0qsKXV1OYwCoTU5BjLhTfFRnHrHHtp22VpjDAFPgfh +bzzBC2HmOET8vIwvTnVX9ZaZfD6HHw+QS3DDPzlFOzpry7t7QFTRi0uhctIE6eBy +GpMRei/xq52cmFiuLOp3Xy8uh6+4a+Pi4j/WPeCWRN8RVWNSL/QmeMQPIE0KwGhw +FYY47rd2iKsYj081HtSMydt+PUTUNozBN7VZW4f56fHUxSi9HdzMlnLReqGnILW4 +r/hupWB7K40f7vQr1mnNr8qAWCnoTAAgikkKbo6MqNEAEoS2xeKVosA7pGvwgtCW +XSUCAwEAAaOCAUMwggE/MBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQD +AgEGMC8GCCsGAQUFBwEBBCMwITAfBggrBgEFBQcwAYYTaHR0cDovL2cyLnN5bWNi +LmNvbTBHBgNVHSAEQDA+MDwGBFUdIAAwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93 +d3cuZ2VvdHJ1c3QuY29tL3Jlc291cmNlcy9jcHMwNAYDVR0fBC0wKzApoCegJYYj +aHR0cDovL2cxLnN5bWNiLmNvbS9HZW9UcnVzdFBDQS5jcmwwKQYDVR0RBCIwIKQe +MBwxGjAYBgNVBAMTEVN5bWFudGVjUEtJLTEtNTM4MB0GA1UdDgQWBBTez1xQt64C +HxUXqhboDbUonWpa8zAfBgNVHSMEGDAWgBQs1VBBlxWL8I82YVtK+2vZmckzkjAN +BgkqhkiG9w0BAQsFAAOCAQEAtI69B7mahew7Z70HYGHmhNHU7+sbuguCS5VktmZT +I723hN3ke40J2s+y9fHDv4eEvk6mqMLnEjkoNOCkVkRADJ+IoxXT6NNe4xwEYPtp +Nk9qfgwqKMHzqlgObM4dB8NKwJyNw3SxroLwGuH5Tim9Rt63Hfl929kPhMuSRcwc +sxj2oM9xbwwum9Its5mTg0SsFaqbLmfsT4hpBVZ7i7JDqTpsHBMzJRv9qMhXAvsc +4NG9O1ZEZcNj9Rvv7DDZ424uE+k5CCoMcvOazPYnKYTT70zHhBFlH8bjgQPbh8x4 +97Wdlj5qf7wRhXp15kF9Dc/55YVpJY/HjQct+GkPy0FTAA== +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert15[] = { + 0x30, 0x82, 0x04, 0x6e, 0x30, 0x82, 0x03, 0x56, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x6e, 0x8a, 0x90, 0xeb, 0xcf, 0xf0, 0x44, 0x8a, 0x72, + 0x0d, 0x08, 0x05, 0xd0, 0x82, 0xa5, 0x44, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x58, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, + 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, + 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, + 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, + 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, + 0x33, 0x31, 0x30, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, + 0x30, 0x47, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, + 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x17, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x45, + 0x56, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, + 0x34, 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, 0xd9, 0xb4, + 0x05, 0xf2, 0x38, 0x67, 0x0f, 0x09, 0xe7, 0x7c, 0xf5, 0x63, 0x2a, 0xe5, + 0xb9, 0x5e, 0xa8, 0x11, 0xae, 0x75, 0x71, 0xd9, 0x4c, 0x84, 0x67, 0xad, + 0x89, 0x5d, 0xfc, 0x28, 0x3d, 0x2a, 0xb0, 0xa5, 0xd5, 0xd4, 0xe6, 0x30, + 0x0a, 0x84, 0xd4, 0xe4, 0x18, 0xcb, 0x85, 0x37, 0xc5, 0x46, 0x71, 0xeb, + 0x1c, 0x7b, 0x69, 0xdb, 0x65, 0x69, 0x8c, 0x30, 0x05, 0x3e, 0x07, 0xe1, + 0x6f, 0x3c, 0xc1, 0x0b, 0x61, 0xe6, 0x38, 0x44, 0xfc, 0xbc, 0x8c, 0x2f, + 0x4e, 0x75, 0x57, 0xf5, 0x96, 0x99, 0x7c, 0x3e, 0x87, 0x1f, 0x0f, 0x90, + 0x4b, 0x70, 0xc3, 0x3f, 0x39, 0x45, 0x3b, 0x3a, 0x6b, 0xcb, 0xbb, 0x7b, + 0x40, 0x54, 0xd1, 0x8b, 0x4b, 0xa1, 0x72, 0xd2, 0x04, 0xe9, 0xe0, 0x72, + 0x1a, 0x93, 0x11, 0x7a, 0x2f, 0xf1, 0xab, 0x9d, 0x9c, 0x98, 0x58, 0xae, + 0x2c, 0xea, 0x77, 0x5f, 0x2f, 0x2e, 0x87, 0xaf, 0xb8, 0x6b, 0xe3, 0xe2, + 0xe2, 0x3f, 0xd6, 0x3d, 0xe0, 0x96, 0x44, 0xdf, 0x11, 0x55, 0x63, 0x52, + 0x2f, 0xf4, 0x26, 0x78, 0xc4, 0x0f, 0x20, 0x4d, 0x0a, 0xc0, 0x68, 0x70, + 0x15, 0x86, 0x38, 0xee, 0xb7, 0x76, 0x88, 0xab, 0x18, 0x8f, 0x4f, 0x35, + 0x1e, 0xd4, 0x8c, 0xc9, 0xdb, 0x7e, 0x3d, 0x44, 0xd4, 0x36, 0x8c, 0xc1, + 0x37, 0xb5, 0x59, 0x5b, 0x87, 0xf9, 0xe9, 0xf1, 0xd4, 0xc5, 0x28, 0xbd, + 0x1d, 0xdc, 0xcc, 0x96, 0x72, 0xd1, 0x7a, 0xa1, 0xa7, 0x20, 0xb5, 0xb8, + 0xaf, 0xf8, 0x6e, 0xa5, 0x60, 0x7b, 0x2b, 0x8d, 0x1f, 0xee, 0xf4, 0x2b, + 0xd6, 0x69, 0xcd, 0xaf, 0xca, 0x80, 0x58, 0x29, 0xe8, 0x4c, 0x00, 0x20, + 0x8a, 0x49, 0x0a, 0x6e, 0x8e, 0x8c, 0xa8, 0xd1, 0x00, 0x12, 0x84, 0xb6, + 0xc5, 0xe2, 0x95, 0xa2, 0xc0, 0x3b, 0xa4, 0x6b, 0xf0, 0x82, 0xd0, 0x96, + 0x5d, 0x25, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x43, 0x30, + 0x82, 0x01, 0x3f, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, + 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, + 0x02, 0x01, 0x06, 0x30, 0x2f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x01, 0x01, 0x04, 0x23, 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x47, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, + 0x40, 0x30, 0x3e, 0x30, 0x3c, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, + 0x34, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, + 0x01, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, + 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x34, 0x06, 0x03, 0x55, 0x1d, 0x1f, + 0x04, 0x2d, 0x30, 0x2b, 0x30, 0x29, 0xa0, 0x27, 0xa0, 0x25, 0x86, 0x23, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x31, 0x2e, 0x73, 0x79, + 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x47, 0x65, 0x6f, 0x54, + 0x72, 0x75, 0x73, 0x74, 0x50, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, + 0x29, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, + 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x11, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, + 0x2d, 0x31, 0x2d, 0x35, 0x33, 0x38, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, + 0x0e, 0x04, 0x16, 0x04, 0x14, 0xde, 0xcf, 0x5c, 0x50, 0xb7, 0xae, 0x02, + 0x1f, 0x15, 0x17, 0xaa, 0x16, 0xe8, 0x0d, 0xb5, 0x28, 0x9d, 0x6a, 0x5a, + 0xf3, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0x2c, 0xd5, 0x50, 0x41, 0x97, 0x15, 0x8b, 0xf0, 0x8f, 0x36, + 0x61, 0x5b, 0x4a, 0xfb, 0x6b, 0xd9, 0x99, 0xc9, 0x33, 0x92, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xb4, 0x8e, 0xbd, 0x07, 0xb9, 0x9a, + 0x85, 0xec, 0x3b, 0x67, 0xbd, 0x07, 0x60, 0x61, 0xe6, 0x84, 0xd1, 0xd4, + 0xef, 0xeb, 0x1b, 0xba, 0x0b, 0x82, 0x4b, 0x95, 0x64, 0xb6, 0x66, 0x53, + 0x23, 0xbd, 0xb7, 0x84, 0xdd, 0xe4, 0x7b, 0x8d, 0x09, 0xda, 0xcf, 0xb2, + 0xf5, 0xf1, 0xc3, 0xbf, 0x87, 0x84, 0xbe, 0x4e, 0xa6, 0xa8, 0xc2, 0xe7, + 0x12, 0x39, 0x28, 0x34, 0xe0, 0xa4, 0x56, 0x44, 0x40, 0x0c, 0x9f, 0x88, + 0xa3, 0x15, 0xd3, 0xe8, 0xd3, 0x5e, 0xe3, 0x1c, 0x04, 0x60, 0xfb, 0x69, + 0x36, 0x4f, 0x6a, 0x7e, 0x0c, 0x2a, 0x28, 0xc1, 0xf3, 0xaa, 0x58, 0x0e, + 0x6c, 0xce, 0x1d, 0x07, 0xc3, 0x4a, 0xc0, 0x9c, 0x8d, 0xc3, 0x74, 0xb1, + 0xae, 0x82, 0xf0, 0x1a, 0xe1, 0xf9, 0x4e, 0x29, 0xbd, 0x46, 0xde, 0xb7, + 0x1d, 0xf9, 0x7d, 0xdb, 0xd9, 0x0f, 0x84, 0xcb, 0x92, 0x45, 0xcc, 0x1c, + 0xb3, 0x18, 0xf6, 0xa0, 0xcf, 0x71, 0x6f, 0x0c, 0x2e, 0x9b, 0xd2, 0x2d, + 0xb3, 0x99, 0x93, 0x83, 0x44, 0xac, 0x15, 0xaa, 0x9b, 0x2e, 0x67, 0xec, + 0x4f, 0x88, 0x69, 0x05, 0x56, 0x7b, 0x8b, 0xb2, 0x43, 0xa9, 0x3a, 0x6c, + 0x1c, 0x13, 0x33, 0x25, 0x1b, 0xfd, 0xa8, 0xc8, 0x57, 0x02, 0xfb, 0x1c, + 0xe0, 0xd1, 0xbd, 0x3b, 0x56, 0x44, 0x65, 0xc3, 0x63, 0xf5, 0x1b, 0xef, + 0xec, 0x30, 0xd9, 0xe3, 0x6e, 0x2e, 0x13, 0xe9, 0x39, 0x08, 0x2a, 0x0c, + 0x72, 0xf3, 0x9a, 0xcc, 0xf6, 0x27, 0x29, 0x84, 0xd3, 0xef, 0x4c, 0xc7, + 0x84, 0x11, 0x65, 0x1f, 0xc6, 0xe3, 0x81, 0x03, 0xdb, 0x87, 0xcc, 0x78, + 0xf7, 0xb5, 0x9d, 0x96, 0x3e, 0x6a, 0x7f, 0xbc, 0x11, 0x85, 0x7a, 0x75, + 0xe6, 0x41, 0x7d, 0x0d, 0xcf, 0xf9, 0xe5, 0x85, 0x69, 0x25, 0x8f, 0xc7, + 0x8d, 0x07, 0x2d, 0xf8, 0x69, 0x0f, 0xcb, 0x41, 0x53, 0x00, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 146035 (0x23a73) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=GeoTrust Inc., CN=GeoTrust Global CA + Validity + Not Before: Jun 11 22:02:59 2014 GMT + Not After : May 20 22:02:59 2022 GMT + Subject: C=US, O=GeoTrust Inc., OU=Domain Validated SSL, CN=GeoTrust DV SSL CA - G3 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:b3:44:3a:6c:b0:ae:cb:14:f9:8c:19:74:34:5c: + a9:69:e3:88:53:77:a5:a7:ff:bd:d1:3c:0d:27:e4: + de:ad:7f:bc:d1:90:58:93:d6:a6:da:39:9c:ad:e1: + 0e:56:46:ee:95:9e:10:68:4c:9c:2b:f6:6a:3a:8b: + 80:81:87:06:57:25:1a:56:52:94:dd:90:eb:67:3b: + de:fa:ae:36:68:d3:62:69:f6:6c:82:24:44:4f:87: + 5c:98:11:95:64:6b:e8:0c:d1:dd:e6:27:97:ae:cc: + e2:91:6a:41:12:b6:ab:e5:cc:6e:cc:23:b8:63:8a: + 1f:31:93:2d:06:c4:f7:e8:3d:58:cd:97:08:46:6c: + 7b:74:c0:f8:fc:31:3b:a7:7f:d7:8f:b0:c9:15:63: + 50:7a:12:4d:f5:12:1e:a3:7e:55:e3:75:b7:ea:1e: + ea:31:2c:08:4e:d8:cb:43:74:89:24:bc:d2:0e:1e: + f0:db:05:24:f6:8a:bf:10:27:84:41:1a:f6:18:53: + ee:91:d0:54:17:d3:7d:3e:7e:b2:7d:a8:bf:db:b9: + 21:2a:f0:89:b9:08:6e:5a:b3:5e:ea:82:b8:7e:27: + 0b:cc:56:73:81:05:4f:e3:96:2d:71:d5:78:a7:60: + c3:d7:ec:aa:39:1a:05:39:82:81:e0:15:2c:35:d1: + ee:25 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Authority Key Identifier: + keyid:C0:7A:98:68:8D:89:FB:AB:05:64:0C:11:7D:AA:7D:65:B8:CA:CC:4E + + X509v3 Subject Key Identifier: + AD:65:22:85:90:D0:3B:E3:A1:49:8B:37:F9:F1:0B:1D:5F:17:A0:77 + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 CRL Distribution Points: + + Full Name: + URI:http://g.symcb.com/crls/gtglobal.crl + + Authority Information Access: + OCSP - URI:http://g.symcd.com + + X509v3 Certificate Policies: + Policy: 2.16.840.1.113733.1.7.54 + CPS: http://www.geotrust.com/resources/cps + + X509v3 Subject Alternative Name: + DirName:/CN=SymantecPKI-1-699 + Signature Algorithm: sha256WithRSAEncryption + 4e:27:b8:1a:c7:3b:dc:5d:bb:9e:1a:35:23:1e:88:55:90:d1: + ec:86:9c:88:b7:e0:1f:67:87:e2:7c:b5:43:03:0e:b6:02:e8: + e0:ff:86:84:19:71:e9:f2:4b:f5:9e:2e:2e:5e:db:ab:d6:1c: + 4e:c4:3e:b8:2c:78:86:71:10:ae:8d:c5:70:bf:a4:f9:89:e6: + b4:ed:e8:4b:ed:7c:09:2a:09:08:06:3e:d4:e1:de:82:92:0c: + 34:30:35:0a:c1:60:75:ca:b6:55:6b:aa:00:42:cb:3f:fb:10: + e1:fb:85:c1:21:90:72:2b:6e:c0:e8:9d:d9:b5:5a:50:8e:34: + 1e:bb:38:a7:3c:31:bd:7a:f2:43:8b:eb:16:ca:ad:9b:de:6b: + 1e:f8:4f:b6:5e:4a:29:1f:7a:14:ee:91:f4:94:4f:a4:bd:9b: + 76:7a:bc:f1:51:7a:96:a8:81:0e:83:87:3f:8b:ae:5e:32:9b: + 34:9e:b2:e7:db:2f:ec:02:a0:e1:fd:51:52:fe:2c:db:36:ba: + c1:d6:5e:4b:58:6d:de:c6:e1:e1:fa:9a:03:2c:5b:a2:e1:b3: + 9b:f9:36:ec:c1:73:fa:33:12:66:95:e3:69:10:b6:d7:aa:33: + fa:f6:9d:41:6d:96:2a:ba:be:83:31:41:7f:0c:0a:d2:69:d6: + fc:35:4c:c3 +-----BEGIN CERTIFICATE----- +MIIEbzCCA1egAwIBAgIDAjpzMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMTQwNjExMjIwMjU5WhcNMjIwNTIwMjIwMjU5WjBmMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UECxMURG9tYWluIFZh +bGlkYXRlZCBTU0wxIDAeBgNVBAMTF0dlb1RydXN0IERWIFNTTCBDQSAtIEczMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs0Q6bLCuyxT5jBl0NFypaeOI +U3elp/+90TwNJ+TerX+80ZBYk9am2jmcreEOVkbulZ4QaEycK/ZqOouAgYcGVyUa +VlKU3ZDrZzve+q42aNNiafZsgiRET4dcmBGVZGvoDNHd5ieXrszikWpBErar5cxu +zCO4Y4ofMZMtBsT36D1YzZcIRmx7dMD4/DE7p3/Xj7DJFWNQehJN9RIeo35V43W3 +6h7qMSwITtjLQ3SJJLzSDh7w2wUk9oq/ECeEQRr2GFPukdBUF9N9Pn6yfai/27kh +KvCJuQhuWrNe6oK4ficLzFZzgQVP45YtcdV4p2DD1+yqORoFOYKB4BUsNdHuJQID +AQABo4IBSDCCAUQwHwYDVR0jBBgwFoAUwHqYaI2J+6sFZAwRfap9ZbjKzE4wHQYD +VR0OBBYEFK1lIoWQ0DvjoUmLN/nxCx1fF6B3MBIGA1UdEwEB/wQIMAYBAf8CAQAw +DgYDVR0PAQH/BAQDAgEGMDUGA1UdHwQuMCwwKqAooCaGJGh0dHA6Ly9nLnN5bWNi +LmNvbS9jcmxzL2d0Z2xvYmFsLmNybDAuBggrBgEFBQcBAQQiMCAwHgYIKwYBBQUH +MAGGEmh0dHA6Ly9nLnN5bWNkLmNvbTBMBgNVHSAERTBDMEEGCmCGSAGG+EUBBzYw +MzAxBggrBgEFBQcCARYlaHR0cDovL3d3dy5nZW90cnVzdC5jb20vcmVzb3VyY2Vz +L2NwczApBgNVHREEIjAgpB4wHDEaMBgGA1UEAxMRU3ltYW50ZWNQS0ktMS02OTkw +DQYJKoZIhvcNAQELBQADggEBAE4nuBrHO9xdu54aNSMeiFWQ0eyGnIi34B9nh+J8 +tUMDDrYC6OD/hoQZcenyS/WeLi5e26vWHE7EPrgseIZxEK6NxXC/pPmJ5rTt6Evt +fAkqCQgGPtTh3oKSDDQwNQrBYHXKtlVrqgBCyz/7EOH7hcEhkHIrbsDondm1WlCO +NB67OKc8Mb168kOL6xbKrZveax74T7ZeSikfehTukfSUT6S9m3Z6vPFRepaogQ6D +hz+Lrl4ymzSesufbL+wCoOH9UVL+LNs2usHWXktYbd7G4eH6mgMsW6Lhs5v5NuzB +c/ozEmaV42kQtteqM/r2nUFtliq6voMxQX8MCtJp1vw1TMM= +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert16[] = { + 0x30, 0x82, 0x04, 0x6f, 0x30, 0x82, 0x03, 0x57, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x03, 0x02, 0x3a, 0x73, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, + 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, + 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30, + 0x36, 0x31, 0x31, 0x32, 0x32, 0x30, 0x32, 0x35, 0x39, 0x5a, 0x17, 0x0d, + 0x32, 0x32, 0x30, 0x35, 0x32, 0x30, 0x32, 0x32, 0x30, 0x32, 0x35, 0x39, + 0x5a, 0x30, 0x66, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, + 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x13, 0x14, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x61, + 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x64, 0x20, 0x53, 0x53, 0x4c, 0x31, + 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x47, 0x65, + 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x44, 0x56, 0x20, 0x53, 0x53, + 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 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, 0xb3, 0x44, 0x3a, 0x6c, 0xb0, 0xae, + 0xcb, 0x14, 0xf9, 0x8c, 0x19, 0x74, 0x34, 0x5c, 0xa9, 0x69, 0xe3, 0x88, + 0x53, 0x77, 0xa5, 0xa7, 0xff, 0xbd, 0xd1, 0x3c, 0x0d, 0x27, 0xe4, 0xde, + 0xad, 0x7f, 0xbc, 0xd1, 0x90, 0x58, 0x93, 0xd6, 0xa6, 0xda, 0x39, 0x9c, + 0xad, 0xe1, 0x0e, 0x56, 0x46, 0xee, 0x95, 0x9e, 0x10, 0x68, 0x4c, 0x9c, + 0x2b, 0xf6, 0x6a, 0x3a, 0x8b, 0x80, 0x81, 0x87, 0x06, 0x57, 0x25, 0x1a, + 0x56, 0x52, 0x94, 0xdd, 0x90, 0xeb, 0x67, 0x3b, 0xde, 0xfa, 0xae, 0x36, + 0x68, 0xd3, 0x62, 0x69, 0xf6, 0x6c, 0x82, 0x24, 0x44, 0x4f, 0x87, 0x5c, + 0x98, 0x11, 0x95, 0x64, 0x6b, 0xe8, 0x0c, 0xd1, 0xdd, 0xe6, 0x27, 0x97, + 0xae, 0xcc, 0xe2, 0x91, 0x6a, 0x41, 0x12, 0xb6, 0xab, 0xe5, 0xcc, 0x6e, + 0xcc, 0x23, 0xb8, 0x63, 0x8a, 0x1f, 0x31, 0x93, 0x2d, 0x06, 0xc4, 0xf7, + 0xe8, 0x3d, 0x58, 0xcd, 0x97, 0x08, 0x46, 0x6c, 0x7b, 0x74, 0xc0, 0xf8, + 0xfc, 0x31, 0x3b, 0xa7, 0x7f, 0xd7, 0x8f, 0xb0, 0xc9, 0x15, 0x63, 0x50, + 0x7a, 0x12, 0x4d, 0xf5, 0x12, 0x1e, 0xa3, 0x7e, 0x55, 0xe3, 0x75, 0xb7, + 0xea, 0x1e, 0xea, 0x31, 0x2c, 0x08, 0x4e, 0xd8, 0xcb, 0x43, 0x74, 0x89, + 0x24, 0xbc, 0xd2, 0x0e, 0x1e, 0xf0, 0xdb, 0x05, 0x24, 0xf6, 0x8a, 0xbf, + 0x10, 0x27, 0x84, 0x41, 0x1a, 0xf6, 0x18, 0x53, 0xee, 0x91, 0xd0, 0x54, + 0x17, 0xd3, 0x7d, 0x3e, 0x7e, 0xb2, 0x7d, 0xa8, 0xbf, 0xdb, 0xb9, 0x21, + 0x2a, 0xf0, 0x89, 0xb9, 0x08, 0x6e, 0x5a, 0xb3, 0x5e, 0xea, 0x82, 0xb8, + 0x7e, 0x27, 0x0b, 0xcc, 0x56, 0x73, 0x81, 0x05, 0x4f, 0xe3, 0x96, 0x2d, + 0x71, 0xd5, 0x78, 0xa7, 0x60, 0xc3, 0xd7, 0xec, 0xaa, 0x39, 0x1a, 0x05, + 0x39, 0x82, 0x81, 0xe0, 0x15, 0x2c, 0x35, 0xd1, 0xee, 0x25, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x48, 0x30, 0x82, 0x01, 0x44, 0x30, + 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, + 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, 0xab, 0x05, 0x64, 0x0c, 0x11, + 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, 0x4e, 0x30, 0x1d, 0x06, 0x03, + 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xad, 0x65, 0x22, 0x85, 0x90, + 0xd0, 0x3b, 0xe3, 0xa1, 0x49, 0x8b, 0x37, 0xf9, 0xf1, 0x0b, 0x1d, 0x5f, + 0x17, 0xa0, 0x77, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, + 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, + 0x02, 0x01, 0x06, 0x30, 0x35, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2e, + 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0, 0x26, 0x86, 0x24, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, 0x6c, 0x73, 0x2f, 0x67, 0x74, + 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x2e, + 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x22, + 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, + 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4c, + 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0x06, + 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x36, 0x30, + 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, + 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, + 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, + 0x2f, 0x63, 0x70, 0x73, 0x30, 0x29, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, + 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, + 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, 0x36, 0x39, 0x39, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4e, 0x27, 0xb8, 0x1a, 0xc7, + 0x3b, 0xdc, 0x5d, 0xbb, 0x9e, 0x1a, 0x35, 0x23, 0x1e, 0x88, 0x55, 0x90, + 0xd1, 0xec, 0x86, 0x9c, 0x88, 0xb7, 0xe0, 0x1f, 0x67, 0x87, 0xe2, 0x7c, + 0xb5, 0x43, 0x03, 0x0e, 0xb6, 0x02, 0xe8, 0xe0, 0xff, 0x86, 0x84, 0x19, + 0x71, 0xe9, 0xf2, 0x4b, 0xf5, 0x9e, 0x2e, 0x2e, 0x5e, 0xdb, 0xab, 0xd6, + 0x1c, 0x4e, 0xc4, 0x3e, 0xb8, 0x2c, 0x78, 0x86, 0x71, 0x10, 0xae, 0x8d, + 0xc5, 0x70, 0xbf, 0xa4, 0xf9, 0x89, 0xe6, 0xb4, 0xed, 0xe8, 0x4b, 0xed, + 0x7c, 0x09, 0x2a, 0x09, 0x08, 0x06, 0x3e, 0xd4, 0xe1, 0xde, 0x82, 0x92, + 0x0c, 0x34, 0x30, 0x35, 0x0a, 0xc1, 0x60, 0x75, 0xca, 0xb6, 0x55, 0x6b, + 0xaa, 0x00, 0x42, 0xcb, 0x3f, 0xfb, 0x10, 0xe1, 0xfb, 0x85, 0xc1, 0x21, + 0x90, 0x72, 0x2b, 0x6e, 0xc0, 0xe8, 0x9d, 0xd9, 0xb5, 0x5a, 0x50, 0x8e, + 0x34, 0x1e, 0xbb, 0x38, 0xa7, 0x3c, 0x31, 0xbd, 0x7a, 0xf2, 0x43, 0x8b, + 0xeb, 0x16, 0xca, 0xad, 0x9b, 0xde, 0x6b, 0x1e, 0xf8, 0x4f, 0xb6, 0x5e, + 0x4a, 0x29, 0x1f, 0x7a, 0x14, 0xee, 0x91, 0xf4, 0x94, 0x4f, 0xa4, 0xbd, + 0x9b, 0x76, 0x7a, 0xbc, 0xf1, 0x51, 0x7a, 0x96, 0xa8, 0x81, 0x0e, 0x83, + 0x87, 0x3f, 0x8b, 0xae, 0x5e, 0x32, 0x9b, 0x34, 0x9e, 0xb2, 0xe7, 0xdb, + 0x2f, 0xec, 0x02, 0xa0, 0xe1, 0xfd, 0x51, 0x52, 0xfe, 0x2c, 0xdb, 0x36, + 0xba, 0xc1, 0xd6, 0x5e, 0x4b, 0x58, 0x6d, 0xde, 0xc6, 0xe1, 0xe1, 0xfa, + 0x9a, 0x03, 0x2c, 0x5b, 0xa2, 0xe1, 0xb3, 0x9b, 0xf9, 0x36, 0xec, 0xc1, + 0x73, 0xfa, 0x33, 0x12, 0x66, 0x95, 0xe3, 0x69, 0x10, 0xb6, 0xd7, 0xaa, + 0x33, 0xfa, 0xf6, 0x9d, 0x41, 0x6d, 0x96, 0x2a, 0xba, 0xbe, 0x83, 0x31, + 0x41, 0x7f, 0x0c, 0x0a, 0xd2, 0x69, 0xd6, 0xfc, 0x35, 0x4c, 0xc3, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 12037640545166866303 (0xa70e4a4c3482b77f) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=Starfield Technologies, Inc., OU=Starfield Class 2 Certification Authority + Validity + Not Before: Sep 2 00:00:00 2009 GMT + Not After : Jun 28 17:39:16 2034 GMT + Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Services Root Certificate Authority - G2 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:d5:0c:3a:c4:2a:f9:4e:e2:f5:be:19:97:5f:8e: + 88:53:b1:1f:3f:cb:cf:9f:20:13:6d:29:3a:c8:0f: + 7d:3c:f7:6b:76:38:63:d9:36:60:a8:9b:5e:5c:00: + 80:b2:2f:59:7f:f6:87:f9:25:43:86:e7:69:1b:52: + 9a:90:e1:71:e3:d8:2d:0d:4e:6f:f6:c8:49:d9:b6: + f3:1a:56:ae:2b:b6:74:14:eb:cf:fb:26:e3:1a:ba: + 1d:96:2e:6a:3b:58:94:89:47:56:ff:25:a0:93:70: + 53:83:da:84:74:14:c3:67:9e:04:68:3a:df:8e:40: + 5a:1d:4a:4e:cf:43:91:3b:e7:56:d6:00:70:cb:52: + ee:7b:7d:ae:3a:e7:bc:31:f9:45:f6:c2:60:cf:13: + 59:02:2b:80:cc:34:47:df:b9:de:90:65:6d:02:cf: + 2c:91:a6:a6:e7:de:85:18:49:7c:66:4e:a3:3a:6d: + a9:b5:ee:34:2e:ba:0d:03:b8:33:df:47:eb:b1:6b: + 8d:25:d9:9b:ce:81:d1:45:46:32:96:70:87:de:02: + 0e:49:43:85:b6:6c:73:bb:64:ea:61:41:ac:c9:d4: + 54:df:87:2f:c7:22:b2:26:cc:9f:59:54:68:9f:fc: + be:2a:2f:c4:55:1c:75:40:60:17:85:02:55:39:8b: + 7f:05 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 9C:5F:00:DF:AA:01:D7:30:2B:38:88:A2:B8:6D:4A:9C:F2:11:91:83 + X509v3 Authority Key Identifier: + keyid:BF:5F:B7:D1:CE:DD:1F:86:F4:5B:55:AC:DC:D7:10:C2:0E:A9:88:E7 + + Authority Information Access: + OCSP - URI:http://o.ss2.us/ + CA Issuers - URI:http://x.ss2.us/x.cer + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://s.ss2.us/r.crl + + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + + Signature Algorithm: sha256WithRSAEncryption + 23:1d:e3:8a:57:ca:7d:e9:17:79:4c:f1:1e:55:fd:cc:53:6e: + 3e:47:0f:df:c6:55:f2:b2:04:36:ed:80:1f:53:c4:5d:34:28: + 6b:be:c7:55:fc:67:ea:cb:3f:7f:90:b2:33:cd:1b:58:10:82: + 02:f8:f8:2f:f5:13:60:d4:05:ce:f1:81:08:c1:dd:a7:75:97: + 4f:18:b9:6d:de:f7:93:91:08:ba:7e:40:2c:ed:c1:ea:bb:76: + 9e:33:06:77:1d:0d:08:7f:53:dd:1b:64:ab:82:27:f1:69:d5: + 4d:5e:ae:f4:a1:c3:75:a7:58:44:2d:f2:3c:70:98:ac:ba:69: + b6:95:77:7f:0f:31:5e:2c:fc:a0:87:3a:47:69:f0:79:5f:f4: + 14:54:a4:95:5e:11:78:12:60:27:ce:9f:c2:77:ff:23:53:77: + 5d:ba:ff:ea:59:e7:db:cf:af:92:96:ef:24:9a:35:10:7a:9c: + 91:c6:0e:7d:99:f6:3f:19:df:f5:72:54:e1:15:a9:07:59:7b: + 83:bf:52:2e:46:8c:b2:00:64:76:1c:48:d3:d8:79:e8:6e:56: + cc:ae:2c:03:90:d7:19:38:99:e4:ca:09:19:5b:ff:07:96:b0: + a8:7f:34:49:df:56:a9:f7:b0:5f:ed:33:ed:8c:47:b7:30:03: + 5d:f4:03:8c +-----BEGIN CERTIFICATE----- +MIIEdTCCA12gAwIBAgIJAKcOSkw0grd/MA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNV +BAYTAlVTMSUwIwYDVQQKExxTdGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTIw +MAYDVQQLEylTdGFyZmllbGQgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eTAeFw0wOTA5MDIwMDAwMDBaFw0zNDA2MjgxNzM5MTZaMIGYMQswCQYDVQQGEwJV +UzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTElMCMGA1UE +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjE7MDkGA1UEAxMyU3RhcmZp +ZWxkIFNlcnZpY2VzIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVDDrEKvlO4vW+GZdfjohTsR8/ +y8+fIBNtKTrID30892t2OGPZNmCom15cAICyL1l/9of5JUOG52kbUpqQ4XHj2C0N +Tm/2yEnZtvMaVq4rtnQU68/7JuMauh2WLmo7WJSJR1b/JaCTcFOD2oR0FMNnngRo +Ot+OQFodSk7PQ5E751bWAHDLUu57fa4657wx+UX2wmDPE1kCK4DMNEffud6QZW0C +zyyRpqbn3oUYSXxmTqM6bam17jQuug0DuDPfR+uxa40l2ZvOgdFFRjKWcIfeAg5J +Q4W2bHO7ZOphQazJ1FTfhy/HIrImzJ9ZVGif/L4qL8RVHHVAYBeFAlU5i38FAgMB +AAGjgfAwge0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0O +BBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMB8GA1UdIwQYMBaAFL9ft9HO3R+G9FtV +rNzXEMIOqYjnME8GCCsGAQUFBwEBBEMwQTAcBggrBgEFBQcwAYYQaHR0cDovL28u +c3MyLnVzLzAhBggrBgEFBQcwAoYVaHR0cDovL3guc3MyLnVzL3guY2VyMCYGA1Ud +HwQfMB0wG6AZoBeGFWh0dHA6Ly9zLnNzMi51cy9yLmNybDARBgNVHSAECjAIMAYG +BFUdIAAwDQYJKoZIhvcNAQELBQADggEBACMd44pXyn3pF3lM8R5V/cxTbj5HD9/G +VfKyBDbtgB9TxF00KGu+x1X8Z+rLP3+QsjPNG1gQggL4+C/1E2DUBc7xgQjB3ad1 +l08YuW3e95ORCLp+QCztweq7dp4zBncdDQh/U90bZKuCJ/Fp1U1ervShw3WnWEQt +8jxwmKy6abaVd38PMV4s/KCHOkdp8Hlf9BRUpJVeEXgSYCfOn8J3/yNTd126/+pZ +59vPr5KW7ySaNRB6nJHGDn2Z9j8Z3/VyVOEVqQdZe4O/Ui5GjLIAZHYcSNPYeehu +VsyuLAOQ1xk4meTKCRlb/weWsKh/NEnfVqn3sF/tM+2MR7cwA130A4w= +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert17[] = { + 0x30, 0x82, 0x04, 0x75, 0x30, 0x82, 0x03, 0x5d, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x09, 0x00, 0xa7, 0x0e, 0x4a, 0x4c, 0x34, 0x82, 0xb7, 0x7f, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x0b, 0x05, 0x00, 0x30, 0x68, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, + 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x32, 0x30, + 0x30, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, + 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, + 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 0x30, 0x39, 0x30, 0x32, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36, + 0x32, 0x38, 0x31, 0x37, 0x33, 0x39, 0x31, 0x36, 0x5a, 0x30, 0x81, 0x98, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, + 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, + 0x64, 0x61, 0x6c, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x1c, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x20, 0x54, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, + 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x3b, 0x30, 0x39, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x32, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, + 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 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, 0x0c, 0x3a, 0xc4, 0x2a, 0xf9, 0x4e, + 0xe2, 0xf5, 0xbe, 0x19, 0x97, 0x5f, 0x8e, 0x88, 0x53, 0xb1, 0x1f, 0x3f, + 0xcb, 0xcf, 0x9f, 0x20, 0x13, 0x6d, 0x29, 0x3a, 0xc8, 0x0f, 0x7d, 0x3c, + 0xf7, 0x6b, 0x76, 0x38, 0x63, 0xd9, 0x36, 0x60, 0xa8, 0x9b, 0x5e, 0x5c, + 0x00, 0x80, 0xb2, 0x2f, 0x59, 0x7f, 0xf6, 0x87, 0xf9, 0x25, 0x43, 0x86, + 0xe7, 0x69, 0x1b, 0x52, 0x9a, 0x90, 0xe1, 0x71, 0xe3, 0xd8, 0x2d, 0x0d, + 0x4e, 0x6f, 0xf6, 0xc8, 0x49, 0xd9, 0xb6, 0xf3, 0x1a, 0x56, 0xae, 0x2b, + 0xb6, 0x74, 0x14, 0xeb, 0xcf, 0xfb, 0x26, 0xe3, 0x1a, 0xba, 0x1d, 0x96, + 0x2e, 0x6a, 0x3b, 0x58, 0x94, 0x89, 0x47, 0x56, 0xff, 0x25, 0xa0, 0x93, + 0x70, 0x53, 0x83, 0xda, 0x84, 0x74, 0x14, 0xc3, 0x67, 0x9e, 0x04, 0x68, + 0x3a, 0xdf, 0x8e, 0x40, 0x5a, 0x1d, 0x4a, 0x4e, 0xcf, 0x43, 0x91, 0x3b, + 0xe7, 0x56, 0xd6, 0x00, 0x70, 0xcb, 0x52, 0xee, 0x7b, 0x7d, 0xae, 0x3a, + 0xe7, 0xbc, 0x31, 0xf9, 0x45, 0xf6, 0xc2, 0x60, 0xcf, 0x13, 0x59, 0x02, + 0x2b, 0x80, 0xcc, 0x34, 0x47, 0xdf, 0xb9, 0xde, 0x90, 0x65, 0x6d, 0x02, + 0xcf, 0x2c, 0x91, 0xa6, 0xa6, 0xe7, 0xde, 0x85, 0x18, 0x49, 0x7c, 0x66, + 0x4e, 0xa3, 0x3a, 0x6d, 0xa9, 0xb5, 0xee, 0x34, 0x2e, 0xba, 0x0d, 0x03, + 0xb8, 0x33, 0xdf, 0x47, 0xeb, 0xb1, 0x6b, 0x8d, 0x25, 0xd9, 0x9b, 0xce, + 0x81, 0xd1, 0x45, 0x46, 0x32, 0x96, 0x70, 0x87, 0xde, 0x02, 0x0e, 0x49, + 0x43, 0x85, 0xb6, 0x6c, 0x73, 0xbb, 0x64, 0xea, 0x61, 0x41, 0xac, 0xc9, + 0xd4, 0x54, 0xdf, 0x87, 0x2f, 0xc7, 0x22, 0xb2, 0x26, 0xcc, 0x9f, 0x59, + 0x54, 0x68, 0x9f, 0xfc, 0xbe, 0x2a, 0x2f, 0xc4, 0x55, 0x1c, 0x75, 0x40, + 0x60, 0x17, 0x85, 0x02, 0x55, 0x39, 0x8b, 0x7f, 0x05, 0x02, 0x03, 0x01, + 0x00, 0x01, 0xa3, 0x81, 0xf0, 0x30, 0x81, 0xed, 0x30, 0x0f, 0x06, 0x03, + 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, + 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, + 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0x9c, 0x5f, 0x00, 0xdf, 0xaa, 0x01, 0xd7, 0x30, + 0x2b, 0x38, 0x88, 0xa2, 0xb8, 0x6d, 0x4a, 0x9c, 0xf2, 0x11, 0x91, 0x83, + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, + 0x14, 0xbf, 0x5f, 0xb7, 0xd1, 0xce, 0xdd, 0x1f, 0x86, 0xf4, 0x5b, 0x55, + 0xac, 0xdc, 0xd7, 0x10, 0xc2, 0x0e, 0xa9, 0x88, 0xe7, 0x30, 0x4f, 0x06, + 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x43, 0x30, + 0x41, 0x30, 0x1c, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, + 0x01, 0x86, 0x10, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x2e, + 0x73, 0x73, 0x32, 0x2e, 0x75, 0x73, 0x2f, 0x30, 0x21, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x15, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x78, 0x2e, 0x73, 0x73, 0x32, 0x2e, 0x75, 0x73, + 0x2f, 0x78, 0x2e, 0x63, 0x65, 0x72, 0x30, 0x26, 0x06, 0x03, 0x55, 0x1d, + 0x1f, 0x04, 0x1f, 0x30, 0x1d, 0x30, 0x1b, 0xa0, 0x19, 0xa0, 0x17, 0x86, + 0x15, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x2e, 0x73, 0x73, + 0x32, 0x2e, 0x75, 0x73, 0x2f, 0x72, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x11, + 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x0a, 0x30, 0x08, 0x30, 0x06, 0x06, + 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, + 0x00, 0x23, 0x1d, 0xe3, 0x8a, 0x57, 0xca, 0x7d, 0xe9, 0x17, 0x79, 0x4c, + 0xf1, 0x1e, 0x55, 0xfd, 0xcc, 0x53, 0x6e, 0x3e, 0x47, 0x0f, 0xdf, 0xc6, + 0x55, 0xf2, 0xb2, 0x04, 0x36, 0xed, 0x80, 0x1f, 0x53, 0xc4, 0x5d, 0x34, + 0x28, 0x6b, 0xbe, 0xc7, 0x55, 0xfc, 0x67, 0xea, 0xcb, 0x3f, 0x7f, 0x90, + 0xb2, 0x33, 0xcd, 0x1b, 0x58, 0x10, 0x82, 0x02, 0xf8, 0xf8, 0x2f, 0xf5, + 0x13, 0x60, 0xd4, 0x05, 0xce, 0xf1, 0x81, 0x08, 0xc1, 0xdd, 0xa7, 0x75, + 0x97, 0x4f, 0x18, 0xb9, 0x6d, 0xde, 0xf7, 0x93, 0x91, 0x08, 0xba, 0x7e, + 0x40, 0x2c, 0xed, 0xc1, 0xea, 0xbb, 0x76, 0x9e, 0x33, 0x06, 0x77, 0x1d, + 0x0d, 0x08, 0x7f, 0x53, 0xdd, 0x1b, 0x64, 0xab, 0x82, 0x27, 0xf1, 0x69, + 0xd5, 0x4d, 0x5e, 0xae, 0xf4, 0xa1, 0xc3, 0x75, 0xa7, 0x58, 0x44, 0x2d, + 0xf2, 0x3c, 0x70, 0x98, 0xac, 0xba, 0x69, 0xb6, 0x95, 0x77, 0x7f, 0x0f, + 0x31, 0x5e, 0x2c, 0xfc, 0xa0, 0x87, 0x3a, 0x47, 0x69, 0xf0, 0x79, 0x5f, + 0xf4, 0x14, 0x54, 0xa4, 0x95, 0x5e, 0x11, 0x78, 0x12, 0x60, 0x27, 0xce, + 0x9f, 0xc2, 0x77, 0xff, 0x23, 0x53, 0x77, 0x5d, 0xba, 0xff, 0xea, 0x59, + 0xe7, 0xdb, 0xcf, 0xaf, 0x92, 0x96, 0xef, 0x24, 0x9a, 0x35, 0x10, 0x7a, + 0x9c, 0x91, 0xc6, 0x0e, 0x7d, 0x99, 0xf6, 0x3f, 0x19, 0xdf, 0xf5, 0x72, + 0x54, 0xe1, 0x15, 0xa9, 0x07, 0x59, 0x7b, 0x83, 0xbf, 0x52, 0x2e, 0x46, + 0x8c, 0xb2, 0x00, 0x64, 0x76, 0x1c, 0x48, 0xd3, 0xd8, 0x79, 0xe8, 0x6e, + 0x56, 0xcc, 0xae, 0x2c, 0x03, 0x90, 0xd7, 0x19, 0x38, 0x99, 0xe4, 0xca, + 0x09, 0x19, 0x5b, 0xff, 0x07, 0x96, 0xb0, 0xa8, 0x7f, 0x34, 0x49, 0xdf, + 0x56, 0xa9, 0xf7, 0xb0, 0x5f, 0xed, 0x33, 0xed, 0x8c, 0x47, 0xb7, 0x30, + 0x03, 0x5d, 0xf4, 0x03, 0x8c, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 120038006 (0x727a276) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root + Validity + Not Before: Feb 27 18:09:27 2014 GMT + Not After : Jun 9 17:07:29 2020 GMT + Subject: C=JP, O=Cybertrust Japan Co., Ltd., CN=Cybertrust Japan Public CA G3 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:94:56:a3:45:44:54:aa:60:64:bf:b8:57:9f:4e: + db:d4:79:68:5f:13:05:f4:3f:cd:25:dd:3c:5e:58: + 77:1c:9d:e6:9f:e3:32:49:ef:02:3a:34:53:8d:52: + e5:e3:39:66:1f:e7:33:61:b6:27:c6:24:55:50:27: + 02:65:f0:b0:8c:41:8d:30:5e:47:5b:82:6f:c7:9c: + a3:28:43:6d:58:7b:c8:15:98:4e:25:6f:cb:76:27: + 5b:0b:2c:2c:b5:98:23:e7:8b:7c:fd:77:1a:c4:52: + ba:5d:19:ee:78:21:4d:21:9a:d9:12:7c:33:15:6b: + 1a:c9:81:ea:da:da:57:b7:d5:2f:ce:1f:4b:fc:b4: + 33:e0:a0:c9:94:27:bb:27:40:b6:90:db:ac:9e:75: + a6:11:2b:49:19:2d:c3:c2:43:07:09:bb:3d:6e:88: + a3:e3:8a:c5:d2:86:f6:65:5b:34:c3:9f:4c:02:e5: + 09:ba:2c:c6:76:66:eb:d1:76:25:f4:30:13:fb:58: + 60:a8:58:e3:51:6f:4b:08:04:61:8d:ac:a9:30:2f: + 52:41:a3:22:c1:33:59:ab:7b:59:f9:93:67:4b:c9: + 89:75:52:ef:29:49:34:93:1c:9c:93:73:9c:19:ce: + 5c:18:cd:4c:09:27:c1:3f:f5:49:ec:f4:e2:df:4b: + af:8f + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Certificate Policies: + Policy: 1.3.6.1.4.1.6334.1.0 + CPS: http://cybertrust.omniroot.com/repository.cfm + + Authority Information Access: + OCSP - URI:http://ocsp.omniroot.com/baltimoreroot + + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Authority Key Identifier: + keyid:E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0 + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://cdp1.public-trust.com/CRL/Omniroot2025.crl + + X509v3 Subject Key Identifier: + 73:A8:08:53:29:B8:15:FB:99:80:E5:C5:37:D8:F8:39:7B:A4:13:06 + Signature Algorithm: sha256WithRSAEncryption + 68:df:fe:72:54:4e:1b:fb:5c:6e:5a:45:46:cf:42:be:b2:02: + 9c:9d:90:6a:09:2e:b7:36:64:24:b6:b1:e2:48:67:ce:17:46: + 9b:23:75:78:11:f6:c6:09:38:42:62:96:97:30:7b:51:77:df: + 33:b5:00:51:29:d5:24:fe:b7:98:a2:ac:6c:a1:13:7f:ca:f3: + b7:a6:52:c2:16:0d:ec:3a:bf:a3:37:77:4f:ae:7b:55:1d:46: + e9:10:da:c3:b4:05:5c:5b:f6:48:21:00:89:f4:bb:38:8e:1e: + 33:f3:49:97:81:31:6c:16:74:08:91:17:c0:d3:25:b3:bc:c1: + 15:b5:a4:cd:84:4d:b9:c8:eb:c5:59:42:10:14:25:79:f8:db: + b6:d0:e6:d3:a0:14:7c:17:1c:20:1e:ed:99:90:65:c0:41:71: + c3:ab:3f:29:41:67:f9:e2:d1:98:e3:f8:df:3a:b8:ca:a3:6f: + 68:8b:6c:9f:6e:88:7c:9d:41:5c:ba:cb:19:05:83:9c:99:f4: + 1a:d2:24:69:57:0a:0f:7a:c3:1b:2c:4b:06:d3:2a:97:7e:07: + b0:f9:20:5a:b5:92:4b:5b:a8:eb:eb:36:33:47:36:da:72:9c: + bf:68:45:81:31:be:d2:fd:3b:e9:72:d5:70:dd:a6:de:5f:0d: + b6:5e:00:49 +-----BEGIN CERTIFICATE----- +MIIEeTCCA2GgAwIBAgIEByeidjANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTE0MDIyNzE4MDkyN1oX +DTIwMDYwOTE3MDcyOVowWjELMAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1 +c3QgSmFwYW4gQ28uLCBMdGQuMSYwJAYDVQQDEx1DeWJlcnRydXN0IEphcGFuIFB1 +YmxpYyBDQSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJRWo0VE +VKpgZL+4V59O29R5aF8TBfQ/zSXdPF5Ydxyd5p/jMknvAjo0U41S5eM5Zh/nM2G2 +J8YkVVAnAmXwsIxBjTBeR1uCb8ecoyhDbVh7yBWYTiVvy3YnWwssLLWYI+eLfP13 +GsRSul0Z7nghTSGa2RJ8MxVrGsmB6traV7fVL84fS/y0M+CgyZQnuydAtpDbrJ51 +phErSRktw8JDBwm7PW6Io+OKxdKG9mVbNMOfTALlCbosxnZm69F2JfQwE/tYYKhY +41FvSwgEYY2sqTAvUkGjIsEzWat7WfmTZ0vJiXVS7ylJNJMcnJNznBnOXBjNTAkn +wT/1Sez04t9Lr48CAwEAAaOCAUUwggFBMBIGA1UdEwEB/wQIMAYBAf8CAQAwUwYD +VR0gBEwwSjBIBgkrBgEEAbE+AQAwOzA5BggrBgEFBQcCARYtaHR0cDovL2N5YmVy +dHJ1c3Qub21uaXJvb3QuY29tL3JlcG9zaXRvcnkuY2ZtMEIGCCsGAQUFBwEBBDYw +NDAyBggrBgEFBQcwAYYmaHR0cDovL29jc3Aub21uaXJvb3QuY29tL2JhbHRpbW9y +ZXJvb3QwDgYDVR0PAQH/BAQDAgEGMB8GA1UdIwQYMBaAFOWdWTCCR1jMrPoIVDaG +ezq1BE3wMEIGA1UdHwQ7MDkwN6A1oDOGMWh0dHA6Ly9jZHAxLnB1YmxpYy10cnVz +dC5jb20vQ1JML09tbmlyb290MjAyNS5jcmwwHQYDVR0OBBYEFHOoCFMpuBX7mYDl +xTfY+Dl7pBMGMA0GCSqGSIb3DQEBCwUAA4IBAQBo3/5yVE4b+1xuWkVGz0K+sgKc +nZBqCS63NmQktrHiSGfOF0abI3V4EfbGCThCYpaXMHtRd98ztQBRKdUk/reYoqxs +oRN/yvO3plLCFg3sOr+jN3dPrntVHUbpENrDtAVcW/ZIIQCJ9Ls4jh4z80mXgTFs +FnQIkRfA0yWzvMEVtaTNhE25yOvFWUIQFCV5+Nu20ObToBR8FxwgHu2ZkGXAQXHD +qz8pQWf54tGY4/jfOrjKo29oi2yfboh8nUFcussZBYOcmfQa0iRpVwoPesMbLEsG +0yqXfgew+SBatZJLW6jr6zYzRzbacpy/aEWBMb7S/TvpctVw3abeXw22XgBJ +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert18[] = { + 0x30, 0x82, 0x04, 0x79, 0x30, 0x82, 0x03, 0x61, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x04, 0x07, 0x27, 0xa2, 0x76, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x5a, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49, + 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, + 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65, + 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, + 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, + 0x30, 0x32, 0x32, 0x37, 0x31, 0x38, 0x30, 0x39, 0x32, 0x37, 0x5a, 0x17, + 0x0d, 0x32, 0x30, 0x30, 0x36, 0x30, 0x39, 0x31, 0x37, 0x30, 0x37, 0x32, + 0x39, 0x5a, 0x30, 0x5a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x4a, 0x50, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x13, 0x1a, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x20, 0x4a, 0x61, 0x70, 0x61, 0x6e, 0x20, 0x43, 0x6f, 0x2e, + 0x2c, 0x20, 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x1d, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x4a, 0x61, 0x70, 0x61, 0x6e, 0x20, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x20, 0x43, 0x41, 0x20, 0x47, 0x33, 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, 0x94, 0x56, 0xa3, 0x45, 0x44, + 0x54, 0xaa, 0x60, 0x64, 0xbf, 0xb8, 0x57, 0x9f, 0x4e, 0xdb, 0xd4, 0x79, + 0x68, 0x5f, 0x13, 0x05, 0xf4, 0x3f, 0xcd, 0x25, 0xdd, 0x3c, 0x5e, 0x58, + 0x77, 0x1c, 0x9d, 0xe6, 0x9f, 0xe3, 0x32, 0x49, 0xef, 0x02, 0x3a, 0x34, + 0x53, 0x8d, 0x52, 0xe5, 0xe3, 0x39, 0x66, 0x1f, 0xe7, 0x33, 0x61, 0xb6, + 0x27, 0xc6, 0x24, 0x55, 0x50, 0x27, 0x02, 0x65, 0xf0, 0xb0, 0x8c, 0x41, + 0x8d, 0x30, 0x5e, 0x47, 0x5b, 0x82, 0x6f, 0xc7, 0x9c, 0xa3, 0x28, 0x43, + 0x6d, 0x58, 0x7b, 0xc8, 0x15, 0x98, 0x4e, 0x25, 0x6f, 0xcb, 0x76, 0x27, + 0x5b, 0x0b, 0x2c, 0x2c, 0xb5, 0x98, 0x23, 0xe7, 0x8b, 0x7c, 0xfd, 0x77, + 0x1a, 0xc4, 0x52, 0xba, 0x5d, 0x19, 0xee, 0x78, 0x21, 0x4d, 0x21, 0x9a, + 0xd9, 0x12, 0x7c, 0x33, 0x15, 0x6b, 0x1a, 0xc9, 0x81, 0xea, 0xda, 0xda, + 0x57, 0xb7, 0xd5, 0x2f, 0xce, 0x1f, 0x4b, 0xfc, 0xb4, 0x33, 0xe0, 0xa0, + 0xc9, 0x94, 0x27, 0xbb, 0x27, 0x40, 0xb6, 0x90, 0xdb, 0xac, 0x9e, 0x75, + 0xa6, 0x11, 0x2b, 0x49, 0x19, 0x2d, 0xc3, 0xc2, 0x43, 0x07, 0x09, 0xbb, + 0x3d, 0x6e, 0x88, 0xa3, 0xe3, 0x8a, 0xc5, 0xd2, 0x86, 0xf6, 0x65, 0x5b, + 0x34, 0xc3, 0x9f, 0x4c, 0x02, 0xe5, 0x09, 0xba, 0x2c, 0xc6, 0x76, 0x66, + 0xeb, 0xd1, 0x76, 0x25, 0xf4, 0x30, 0x13, 0xfb, 0x58, 0x60, 0xa8, 0x58, + 0xe3, 0x51, 0x6f, 0x4b, 0x08, 0x04, 0x61, 0x8d, 0xac, 0xa9, 0x30, 0x2f, + 0x52, 0x41, 0xa3, 0x22, 0xc1, 0x33, 0x59, 0xab, 0x7b, 0x59, 0xf9, 0x93, + 0x67, 0x4b, 0xc9, 0x89, 0x75, 0x52, 0xef, 0x29, 0x49, 0x34, 0x93, 0x1c, + 0x9c, 0x93, 0x73, 0x9c, 0x19, 0xce, 0x5c, 0x18, 0xcd, 0x4c, 0x09, 0x27, + 0xc1, 0x3f, 0xf5, 0x49, 0xec, 0xf4, 0xe2, 0xdf, 0x4b, 0xaf, 0x8f, 0x02, + 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x45, 0x30, 0x82, 0x01, 0x41, + 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, + 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x53, 0x06, 0x03, + 0x55, 0x1d, 0x20, 0x04, 0x4c, 0x30, 0x4a, 0x30, 0x48, 0x06, 0x09, 0x2b, + 0x06, 0x01, 0x04, 0x01, 0xb1, 0x3e, 0x01, 0x00, 0x30, 0x3b, 0x30, 0x39, + 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x2d, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x79, 0x62, 0x65, 0x72, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, + 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x63, 0x66, 0x6d, 0x30, 0x42, 0x06, + 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x36, 0x30, + 0x34, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, + 0x01, 0x86, 0x26, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, + 0x73, 0x70, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, + 0x65, 0x72, 0x6f, 0x6f, 0x74, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, + 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1f, 0x06, + 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe5, 0x9d, + 0x59, 0x30, 0x82, 0x47, 0x58, 0xcc, 0xac, 0xfa, 0x08, 0x54, 0x36, 0x86, + 0x7b, 0x3a, 0xb5, 0x04, 0x4d, 0xf0, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1d, + 0x1f, 0x04, 0x3b, 0x30, 0x39, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33, 0x86, + 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x64, 0x70, 0x31, + 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x52, 0x4c, 0x2f, 0x4f, 0x6d, + 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x32, 0x30, 0x32, 0x35, 0x2e, 0x63, + 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, + 0x14, 0x73, 0xa8, 0x08, 0x53, 0x29, 0xb8, 0x15, 0xfb, 0x99, 0x80, 0xe5, + 0xc5, 0x37, 0xd8, 0xf8, 0x39, 0x7b, 0xa4, 0x13, 0x06, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, + 0x03, 0x82, 0x01, 0x01, 0x00, 0x68, 0xdf, 0xfe, 0x72, 0x54, 0x4e, 0x1b, + 0xfb, 0x5c, 0x6e, 0x5a, 0x45, 0x46, 0xcf, 0x42, 0xbe, 0xb2, 0x02, 0x9c, + 0x9d, 0x90, 0x6a, 0x09, 0x2e, 0xb7, 0x36, 0x64, 0x24, 0xb6, 0xb1, 0xe2, + 0x48, 0x67, 0xce, 0x17, 0x46, 0x9b, 0x23, 0x75, 0x78, 0x11, 0xf6, 0xc6, + 0x09, 0x38, 0x42, 0x62, 0x96, 0x97, 0x30, 0x7b, 0x51, 0x77, 0xdf, 0x33, + 0xb5, 0x00, 0x51, 0x29, 0xd5, 0x24, 0xfe, 0xb7, 0x98, 0xa2, 0xac, 0x6c, + 0xa1, 0x13, 0x7f, 0xca, 0xf3, 0xb7, 0xa6, 0x52, 0xc2, 0x16, 0x0d, 0xec, + 0x3a, 0xbf, 0xa3, 0x37, 0x77, 0x4f, 0xae, 0x7b, 0x55, 0x1d, 0x46, 0xe9, + 0x10, 0xda, 0xc3, 0xb4, 0x05, 0x5c, 0x5b, 0xf6, 0x48, 0x21, 0x00, 0x89, + 0xf4, 0xbb, 0x38, 0x8e, 0x1e, 0x33, 0xf3, 0x49, 0x97, 0x81, 0x31, 0x6c, + 0x16, 0x74, 0x08, 0x91, 0x17, 0xc0, 0xd3, 0x25, 0xb3, 0xbc, 0xc1, 0x15, + 0xb5, 0xa4, 0xcd, 0x84, 0x4d, 0xb9, 0xc8, 0xeb, 0xc5, 0x59, 0x42, 0x10, + 0x14, 0x25, 0x79, 0xf8, 0xdb, 0xb6, 0xd0, 0xe6, 0xd3, 0xa0, 0x14, 0x7c, + 0x17, 0x1c, 0x20, 0x1e, 0xed, 0x99, 0x90, 0x65, 0xc0, 0x41, 0x71, 0xc3, + 0xab, 0x3f, 0x29, 0x41, 0x67, 0xf9, 0xe2, 0xd1, 0x98, 0xe3, 0xf8, 0xdf, + 0x3a, 0xb8, 0xca, 0xa3, 0x6f, 0x68, 0x8b, 0x6c, 0x9f, 0x6e, 0x88, 0x7c, + 0x9d, 0x41, 0x5c, 0xba, 0xcb, 0x19, 0x05, 0x83, 0x9c, 0x99, 0xf4, 0x1a, + 0xd2, 0x24, 0x69, 0x57, 0x0a, 0x0f, 0x7a, 0xc3, 0x1b, 0x2c, 0x4b, 0x06, + 0xd3, 0x2a, 0x97, 0x7e, 0x07, 0xb0, 0xf9, 0x20, 0x5a, 0xb5, 0x92, 0x4b, + 0x5b, 0xa8, 0xeb, 0xeb, 0x36, 0x33, 0x47, 0x36, 0xda, 0x72, 0x9c, 0xbf, + 0x68, 0x45, 0x81, 0x31, 0xbe, 0xd2, 0xfd, 0x3b, 0xe9, 0x72, 0xd5, 0x70, + 0xdd, 0xa6, 0xde, 0x5f, 0x0d, 0xb6, 0x5e, 0x00, 0x49, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1828629 (0x1be715) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=The Go Daddy Group, Inc., OU=Go Daddy Class 2 Certification Authority + Validity + Not Before: Jan 1 07:00:00 2014 GMT + Not After : May 30 07:00:00 2031 GMT + Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:bf:71:62:08:f1:fa:59:34:f7:1b:c9:18:a3:f7: + 80:49:58:e9:22:83:13:a6:c5:20:43:01:3b:84:f1: + e6:85:49:9f:27:ea:f6:84:1b:4e:a0:b4:db:70:98: + c7:32:01:b1:05:3e:07:4e:ee:f4:fa:4f:2f:59:30: + 22:e7:ab:19:56:6b:e2:80:07:fc:f3:16:75:80:39: + 51:7b:e5:f9:35:b6:74:4e:a9:8d:82:13:e4:b6:3f: + a9:03:83:fa:a2:be:8a:15:6a:7f:de:0b:c3:b6:19: + 14:05:ca:ea:c3:a8:04:94:3b:46:7c:32:0d:f3:00: + 66:22:c8:8d:69:6d:36:8c:11:18:b7:d3:b2:1c:60: + b4:38:fa:02:8c:ce:d3:dd:46:07:de:0a:3e:eb:5d: + 7c:c8:7c:fb:b0:2b:53:a4:92:62:69:51:25:05:61: + 1a:44:81:8c:2c:a9:43:96:23:df:ac:3a:81:9a:0e: + 29:c5:1c:a9:e9:5d:1e:b6:9e:9e:30:0a:39:ce:f1: + 88:80:fb:4b:5d:cc:32:ec:85:62:43:25:34:02:56: + 27:01:91:b4:3b:70:2a:3f:6e:b1:e8:9c:88:01:7d: + 9f:d4:f9:db:53:6d:60:9d:bf:2c:e7:58:ab:b8:5f: + 46:fc:ce:c4:1b:03:3c:09:eb:49:31:5c:69:46:b3: + e0:47 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE + X509v3 Authority Key Identifier: + keyid:D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3 + + Authority Information Access: + OCSP - URI:http://ocsp.godaddy.com/ + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.godaddy.com/gdroot.crl + + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: https://certs.godaddy.com/repository/ + + Signature Algorithm: sha256WithRSAEncryption + 59:0b:53:bd:92:86:11:a7:24:7b:ed:5b:31:cf:1d:1f:6c:70: + c5:b8:6e:be:4e:bb:f6:be:97:50:e1:30:7f:ba:28:5c:62:94: + c2:e3:7e:33:f7:fb:42:76:85:db:95:1c:8c:22:58:75:09:0c: + 88:65:67:39:0a:16:09:c5:a0:38:97:a4:c5:23:93:3f:b4:18: + a6:01:06:44:91:e3:a7:69:27:b4:5a:25:7f:3a:b7:32:cd:dd: + 84:ff:2a:38:29:33:a4:dd:67:b2:85:fe:a1:88:20:1c:50:89: + c8:dc:2a:f6:42:03:37:4c:e6:88:df:d5:af:24:f2:b1:c3:df: + cc:b5:ec:e0:99:5e:b7:49:54:20:3c:94:18:0c:c7:1c:52:18: + 49:a4:6d:e1:b3:58:0b:c9:d8:ec:d9:ae:1c:32:8e:28:70:0d: + e2:fe:a6:17:9e:84:0f:bd:57:70:b3:5a:e9:1f:a0:86:53:bb: + ef:7c:ff:69:0b:e0:48:c3:b7:93:0b:c8:0a:54:c4:ac:5d:14: + 67:37:6c:ca:a5:2f:31:08:37:aa:6e:6f:8c:bc:9b:e2:57:5d: + 24:81:af:97:97:9c:84:ad:6c:ac:37:4c:66:f3:61:91:11:20: + e4:be:30:9f:7a:a4:29:09:b0:e1:34:5f:64:77:18:40:51:df: + 8c:30:a6:af +-----BEGIN CERTIFICATE----- +MIIEfTCCA2WgAwIBAgIDG+cVMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNVBAYTAlVT +MSEwHwYDVQQKExhUaGUgR28gRGFkZHkgR3JvdXAsIEluYy4xMTAvBgNVBAsTKEdv +IERhZGR5IENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQwMTAx +MDcwMDAwWhcNMzEwNTMwMDcwMDAwWjCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT +B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHku +Y29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1 +dGhvcml0eSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv3Fi +CPH6WTT3G8kYo/eASVjpIoMTpsUgQwE7hPHmhUmfJ+r2hBtOoLTbcJjHMgGxBT4H +Tu70+k8vWTAi56sZVmvigAf88xZ1gDlRe+X5NbZ0TqmNghPktj+pA4P6or6KFWp/ +3gvDthkUBcrqw6gElDtGfDIN8wBmIsiNaW02jBEYt9OyHGC0OPoCjM7T3UYH3go+ +6118yHz7sCtTpJJiaVElBWEaRIGMLKlDliPfrDqBmg4pxRyp6V0etp6eMAo5zvGI +gPtLXcwy7IViQyU0AlYnAZG0O3AqP26x6JyIAX2f1PnbU21gnb8s51iruF9G/M7E +GwM8CetJMVxpRrPgRwIDAQABo4IBFzCCARMwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9BUFuIMGU2g/eMB8GA1Ud +IwQYMBaAFNLEsNKR1EwRcbNhyz2h/t2oatTjMDQGCCsGAQUFBwEBBCgwJjAkBggr +BgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRkeS5jb20vMDIGA1UdHwQrMCkwJ6Al +oCOGIWh0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Ryb290LmNybDBGBgNVHSAEPzA9 +MDsGBFUdIAAwMzAxBggrBgEFBQcCARYlaHR0cHM6Ly9jZXJ0cy5nb2RhZGR5LmNv +bS9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEAWQtTvZKGEacke+1bMc8d +H2xwxbhuvk679r6XUOEwf7ooXGKUwuN+M/f7QnaF25UcjCJYdQkMiGVnOQoWCcWg +OJekxSOTP7QYpgEGRJHjp2kntFolfzq3Ms3dhP8qOCkzpN1nsoX+oYggHFCJyNwq +9kIDN0zmiN/VryTyscPfzLXs4Jlet0lUIDyUGAzHHFIYSaRt4bNYC8nY7NmuHDKO +KHAN4v6mF56ED71XcLNa6R+ghlO773z/aQvgSMO3kwvIClTErF0UZzdsyqUvMQg3 +qm5vjLyb4lddJIGvl5echK1srDdMZvNhkREg5L4wn3qkKQmw4TRfZHcYQFHfjDCm +rw== +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert19[] = { + 0x30, 0x82, 0x04, 0x7d, 0x30, 0x82, 0x03, 0x65, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x03, 0x1b, 0xe7, 0x15, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x63, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 0x54, + 0x68, 0x65, 0x20, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, + 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x28, 0x47, 0x6f, + 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, + 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x31, 0x30, 0x31, + 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x31, 0x30, + 0x35, 0x33, 0x30, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x81, + 0x83, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, + 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, + 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, + 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x13, 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 0x2e, + 0x63, 0x6f, 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30, + 0x2f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x28, 0x47, 0x6f, 0x20, 0x44, + 0x61, 0x64, 0x64, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, + 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, 0xbf, 0x71, 0x62, + 0x08, 0xf1, 0xfa, 0x59, 0x34, 0xf7, 0x1b, 0xc9, 0x18, 0xa3, 0xf7, 0x80, + 0x49, 0x58, 0xe9, 0x22, 0x83, 0x13, 0xa6, 0xc5, 0x20, 0x43, 0x01, 0x3b, + 0x84, 0xf1, 0xe6, 0x85, 0x49, 0x9f, 0x27, 0xea, 0xf6, 0x84, 0x1b, 0x4e, + 0xa0, 0xb4, 0xdb, 0x70, 0x98, 0xc7, 0x32, 0x01, 0xb1, 0x05, 0x3e, 0x07, + 0x4e, 0xee, 0xf4, 0xfa, 0x4f, 0x2f, 0x59, 0x30, 0x22, 0xe7, 0xab, 0x19, + 0x56, 0x6b, 0xe2, 0x80, 0x07, 0xfc, 0xf3, 0x16, 0x75, 0x80, 0x39, 0x51, + 0x7b, 0xe5, 0xf9, 0x35, 0xb6, 0x74, 0x4e, 0xa9, 0x8d, 0x82, 0x13, 0xe4, + 0xb6, 0x3f, 0xa9, 0x03, 0x83, 0xfa, 0xa2, 0xbe, 0x8a, 0x15, 0x6a, 0x7f, + 0xde, 0x0b, 0xc3, 0xb6, 0x19, 0x14, 0x05, 0xca, 0xea, 0xc3, 0xa8, 0x04, + 0x94, 0x3b, 0x46, 0x7c, 0x32, 0x0d, 0xf3, 0x00, 0x66, 0x22, 0xc8, 0x8d, + 0x69, 0x6d, 0x36, 0x8c, 0x11, 0x18, 0xb7, 0xd3, 0xb2, 0x1c, 0x60, 0xb4, + 0x38, 0xfa, 0x02, 0x8c, 0xce, 0xd3, 0xdd, 0x46, 0x07, 0xde, 0x0a, 0x3e, + 0xeb, 0x5d, 0x7c, 0xc8, 0x7c, 0xfb, 0xb0, 0x2b, 0x53, 0xa4, 0x92, 0x62, + 0x69, 0x51, 0x25, 0x05, 0x61, 0x1a, 0x44, 0x81, 0x8c, 0x2c, 0xa9, 0x43, + 0x96, 0x23, 0xdf, 0xac, 0x3a, 0x81, 0x9a, 0x0e, 0x29, 0xc5, 0x1c, 0xa9, + 0xe9, 0x5d, 0x1e, 0xb6, 0x9e, 0x9e, 0x30, 0x0a, 0x39, 0xce, 0xf1, 0x88, + 0x80, 0xfb, 0x4b, 0x5d, 0xcc, 0x32, 0xec, 0x85, 0x62, 0x43, 0x25, 0x34, + 0x02, 0x56, 0x27, 0x01, 0x91, 0xb4, 0x3b, 0x70, 0x2a, 0x3f, 0x6e, 0xb1, + 0xe8, 0x9c, 0x88, 0x01, 0x7d, 0x9f, 0xd4, 0xf9, 0xdb, 0x53, 0x6d, 0x60, + 0x9d, 0xbf, 0x2c, 0xe7, 0x58, 0xab, 0xb8, 0x5f, 0x46, 0xfc, 0xce, 0xc4, + 0x1b, 0x03, 0x3c, 0x09, 0xeb, 0x49, 0x31, 0x5c, 0x69, 0x46, 0xb3, 0xe0, + 0x47, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x17, 0x30, 0x82, + 0x01, 0x13, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, + 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, + 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3a, 0x9a, + 0x85, 0x07, 0x10, 0x67, 0x28, 0xb6, 0xef, 0xf6, 0xbd, 0x05, 0x41, 0x6e, + 0x20, 0xc1, 0x94, 0xda, 0x0f, 0xde, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, + 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xd2, 0xc4, 0xb0, 0xd2, 0x91, + 0xd4, 0x4c, 0x11, 0x71, 0xb3, 0x61, 0xcb, 0x3d, 0xa1, 0xfe, 0xdd, 0xa8, + 0x6a, 0xd4, 0xe3, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64, + 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x32, 0x06, + 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2b, 0x30, 0x29, 0x30, 0x27, 0xa0, 0x25, + 0xa0, 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, + 0x72, 0x6c, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x67, 0x64, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, + 0x6c, 0x30, 0x46, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, + 0x30, 0x3b, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x33, 0x30, 0x31, + 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, + 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, + 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, + 0x2f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x59, 0x0b, 0x53, + 0xbd, 0x92, 0x86, 0x11, 0xa7, 0x24, 0x7b, 0xed, 0x5b, 0x31, 0xcf, 0x1d, + 0x1f, 0x6c, 0x70, 0xc5, 0xb8, 0x6e, 0xbe, 0x4e, 0xbb, 0xf6, 0xbe, 0x97, + 0x50, 0xe1, 0x30, 0x7f, 0xba, 0x28, 0x5c, 0x62, 0x94, 0xc2, 0xe3, 0x7e, + 0x33, 0xf7, 0xfb, 0x42, 0x76, 0x85, 0xdb, 0x95, 0x1c, 0x8c, 0x22, 0x58, + 0x75, 0x09, 0x0c, 0x88, 0x65, 0x67, 0x39, 0x0a, 0x16, 0x09, 0xc5, 0xa0, + 0x38, 0x97, 0xa4, 0xc5, 0x23, 0x93, 0x3f, 0xb4, 0x18, 0xa6, 0x01, 0x06, + 0x44, 0x91, 0xe3, 0xa7, 0x69, 0x27, 0xb4, 0x5a, 0x25, 0x7f, 0x3a, 0xb7, + 0x32, 0xcd, 0xdd, 0x84, 0xff, 0x2a, 0x38, 0x29, 0x33, 0xa4, 0xdd, 0x67, + 0xb2, 0x85, 0xfe, 0xa1, 0x88, 0x20, 0x1c, 0x50, 0x89, 0xc8, 0xdc, 0x2a, + 0xf6, 0x42, 0x03, 0x37, 0x4c, 0xe6, 0x88, 0xdf, 0xd5, 0xaf, 0x24, 0xf2, + 0xb1, 0xc3, 0xdf, 0xcc, 0xb5, 0xec, 0xe0, 0x99, 0x5e, 0xb7, 0x49, 0x54, + 0x20, 0x3c, 0x94, 0x18, 0x0c, 0xc7, 0x1c, 0x52, 0x18, 0x49, 0xa4, 0x6d, + 0xe1, 0xb3, 0x58, 0x0b, 0xc9, 0xd8, 0xec, 0xd9, 0xae, 0x1c, 0x32, 0x8e, + 0x28, 0x70, 0x0d, 0xe2, 0xfe, 0xa6, 0x17, 0x9e, 0x84, 0x0f, 0xbd, 0x57, + 0x70, 0xb3, 0x5a, 0xe9, 0x1f, 0xa0, 0x86, 0x53, 0xbb, 0xef, 0x7c, 0xff, + 0x69, 0x0b, 0xe0, 0x48, 0xc3, 0xb7, 0x93, 0x0b, 0xc8, 0x0a, 0x54, 0xc4, + 0xac, 0x5d, 0x14, 0x67, 0x37, 0x6c, 0xca, 0xa5, 0x2f, 0x31, 0x08, 0x37, + 0xaa, 0x6e, 0x6f, 0x8c, 0xbc, 0x9b, 0xe2, 0x57, 0x5d, 0x24, 0x81, 0xaf, + 0x97, 0x97, 0x9c, 0x84, 0xad, 0x6c, 0xac, 0x37, 0x4c, 0x66, 0xf3, 0x61, + 0x91, 0x11, 0x20, 0xe4, 0xbe, 0x30, 0x9f, 0x7a, 0xa4, 0x29, 0x09, 0xb0, + 0xe1, 0x34, 0x5f, 0x64, 0x77, 0x18, 0x40, 0x51, 0xdf, 0x8c, 0x30, 0xa6, + 0xaf, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 46:f0:8c:db:cf:2c:54:66:ef:33:01:dd:5f:34 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA + Validity + Not Before: Aug 19 00:00:00 2015 GMT + Not After : Aug 19 00:00:00 2025 GMT + Subject: C=BE, O=GlobalSign nv-sa, CN=GlobalSign CloudSSL CA - SHA256 - G3 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:a3:c0:75:e1:32:98:e5:d9:ae:84:7c:8d:e8:23: + 5f:46:95:5b:4c:a2:25:70:d7:90:04:85:80:c9:b5: + f4:8a:65:4d:92:cb:a5:c4:42:a0:b6:79:25:31:ed: + f1:85:20:cd:13:51:3d:67:ac:97:4d:68:9b:33:86: + 5c:b3:7b:2d:aa:df:77:a0:61:d1:f5:3c:fb:9a:fc: + d3:d5:94:ca:c9:1e:80:1b:90:90:c8:ac:8d:f6:60: + 17:9c:31:b8:c5:61:a2:e2:6e:57:25:08:6f:24:99: + 99:cf:94:bf:c7:8b:6b:b0:1f:ca:14:fa:18:9b:6c: + 10:7c:99:2b:da:4a:63:e5:b2:4e:c2:fd:3e:10:0b: + 48:f4:77:0b:2f:f0:96:4b:3a:ee:bd:35:de:85:8d: + da:13:0e:ce:01:c4:71:d3:d3:77:c5:08:a6:60:39: + 25:a7:27:69:5c:83:d1:6f:76:78:ee:c5:44:5b:45: + bd:29:3b:e2:c6:09:0f:a2:be:2b:dc:e3:5c:da:5a: + 6f:8e:e7:c9:07:6b:7e:a1:c0:53:95:82:89:e0:78: + 5c:72:a8:6c:be:67:6b:ab:e7:33:d9:87:f2:f8:5c: + 27:f4:f6:2a:3b:87:ef:da:c2:47:da:bf:ac:eb:27: + 64:7b:4c:53:eb:34:e1:2f:9b:20:4d:54:12:6b:7d: + 28:bd + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Extended Key Usage: + TLS Web Server Authentication, TLS Web Client Authentication + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Subject Key Identifier: + A9:2B:87:E1:CE:24:47:3B:1B:BF:CF:85:37:02:55:9D:0D:94:58:E6 + X509v3 Authority Key Identifier: + keyid:60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B + + Authority Information Access: + OCSP - URI:http://ocsp.globalsign.com/rootr1 + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.globalsign.com/root.crl + + X509v3 Certificate Policies: + Policy: 1.3.6.1.4.1.4146.1.20 + Policy: 2.23.140.1.2.2 + CPS: https://www.globalsign.com/repository/ + + Signature Algorithm: sha256WithRSAEncryption + a2:1d:69:8a:0a:8e:c4:14:83:2a:2a:12:4d:39:27:90:4e:f0: + 8d:ac:d2:96:62:47:36:5e:92:d1:fa:c5:93:b5:37:07:65:29: + d2:f4:53:50:6b:c9:f4:fe:34:f5:dd:b8:1d:fa:fc:dc:14:ac: + 56:94:27:9c:42:aa:04:4d:b7:ed:58:d9:99:d2:49:e6:20:2f: + d3:a7:77:b8:2a:89:1a:ef:a7:cf:86:2d:d6:53:e9:0b:93:9c: + 4e:ab:d9:45:ee:a4:84:85:ff:34:e4:0e:c0:bb:a5:ce:5f:95: + 89:85:70:aa:c1:5d:ec:cf:2b:d3:d9:83:df:03:ca:81:a7:02: + 32:b7:77:61:10:25:4e:d9:74:f3:d9:79:82:b5:26:70:b4:52: + bc:8f:33:d7:8a:ae:19:d0:fc:92:ad:2f:ba:3c:a0:48:58:47: + 5e:fd:20:56:95:20:c1:72:1d:ab:66:99:a4:d5:78:37:48:1b: + 9f:b2:4c:37:67:7a:fd:42:d2:d3:56:9e:d3:1d:8e:c4:0c:68: + 96:b6:47:51:10:f7:7b:eb:15:09:64:f5:f9:f0:63:16:2d:3d: + df:23:42:3a:93:63:cc:ab:af:4f:57:06:c7:fe:14:55:62:ce: + 27:11:19:e1:f4:42:ed:22:30:6b:35:1a:4a:05:80:a4:65:df: + cc:cb:6f:d0 +-----BEGIN CERTIFICATE----- +MIIEizCCA3OgAwIBAgIORvCM288sVGbvMwHdXzQwDQYJKoZIhvcNAQELBQAwVzEL +MAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsT +B1Jvb3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0xNTA4MTkw +MDAwMDBaFw0yNTA4MTkwMDAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBH +bG9iYWxTaWduIG52LXNhMS0wKwYDVQQDEyRHbG9iYWxTaWduIENsb3VkU1NMIENB +IC0gU0hBMjU2IC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCj +wHXhMpjl2a6EfI3oI19GlVtMoiVw15AEhYDJtfSKZU2Sy6XEQqC2eSUx7fGFIM0T +UT1nrJdNaJszhlyzey2q33egYdH1PPua/NPVlMrJHoAbkJDIrI32YBecMbjFYaLi +blclCG8kmZnPlL/Hi2uwH8oU+hibbBB8mSvaSmPlsk7C/T4QC0j0dwsv8JZLOu69 +Nd6FjdoTDs4BxHHT03fFCKZgOSWnJ2lcg9FvdnjuxURbRb0pO+LGCQ+ivivc41za +Wm+O58kHa36hwFOVgongeFxyqGy+Z2ur5zPZh/L4XCf09io7h+/awkfav6zrJ2R7 +TFPrNOEvmyBNVBJrfSi9AgMBAAGjggFTMIIBTzAOBgNVHQ8BAf8EBAMCAQYwHQYD +VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8CAQAw +HQYDVR0OBBYEFKkrh+HOJEc7G7/PhTcCVZ0NlFjmMB8GA1UdIwQYMBaAFGB7ZhpF +DZfKiVAvfQTNNKj//P1LMD0GCCsGAQUFBwEBBDEwLzAtBggrBgEFBQcwAYYhaHR0 +cDovL29jc3AuZ2xvYmFsc2lnbi5jb20vcm9vdHIxMDMGA1UdHwQsMCowKKAmoCSG +Imh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5jb20vcm9vdC5jcmwwVgYDVR0gBE8wTTAL +BgkrBgEEAaAyARQwPgYGZ4EMAQICMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8vd3d3 +Lmdsb2JhbHNpZ24uY29tL3JlcG9zaXRvcnkvMA0GCSqGSIb3DQEBCwUAA4IBAQCi +HWmKCo7EFIMqKhJNOSeQTvCNrNKWYkc2XpLR+sWTtTcHZSnS9FNQa8n0/jT13bgd ++vzcFKxWlCecQqoETbftWNmZ0knmIC/Tp3e4Koka76fPhi3WU+kLk5xOq9lF7qSE +hf805A7Au6XOX5WJhXCqwV3szyvT2YPfA8qBpwIyt3dhECVO2XTz2XmCtSZwtFK8 +jzPXiq4Z0PySrS+6PKBIWEde/SBWlSDBch2rZpmk1Xg3SBufskw3Z3r9QtLTVp7T +HY7EDGiWtkdREPd76xUJZPX58GMWLT3fI0I6k2PMq69PVwbH/hRVYs4nERnh9ELt +IjBrNRpKBYCkZd/My2/Q +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert20[] = { + 0x30, 0x82, 0x04, 0x8b, 0x30, 0x82, 0x03, 0x73, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x0e, 0x46, 0xf0, 0x8c, 0xdb, 0xcf, 0x2c, 0x54, 0x66, 0xef, + 0x33, 0x01, 0xdd, 0x5f, 0x34, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x57, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, 0x31, + 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, 0x6c, + 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, 0x2d, + 0x73, 0x61, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, + 0x07, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1b, 0x30, 0x19, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, + 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x38, 0x31, 0x39, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x38, + 0x31, 0x39, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x57, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x42, 0x45, + 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x10, 0x47, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x6e, 0x76, + 0x2d, 0x73, 0x61, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x53, 0x69, 0x67, 0x6e, + 0x20, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, + 0x20, 0x2d, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, + 0x47, 0x33, 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, 0xa3, + 0xc0, 0x75, 0xe1, 0x32, 0x98, 0xe5, 0xd9, 0xae, 0x84, 0x7c, 0x8d, 0xe8, + 0x23, 0x5f, 0x46, 0x95, 0x5b, 0x4c, 0xa2, 0x25, 0x70, 0xd7, 0x90, 0x04, + 0x85, 0x80, 0xc9, 0xb5, 0xf4, 0x8a, 0x65, 0x4d, 0x92, 0xcb, 0xa5, 0xc4, + 0x42, 0xa0, 0xb6, 0x79, 0x25, 0x31, 0xed, 0xf1, 0x85, 0x20, 0xcd, 0x13, + 0x51, 0x3d, 0x67, 0xac, 0x97, 0x4d, 0x68, 0x9b, 0x33, 0x86, 0x5c, 0xb3, + 0x7b, 0x2d, 0xaa, 0xdf, 0x77, 0xa0, 0x61, 0xd1, 0xf5, 0x3c, 0xfb, 0x9a, + 0xfc, 0xd3, 0xd5, 0x94, 0xca, 0xc9, 0x1e, 0x80, 0x1b, 0x90, 0x90, 0xc8, + 0xac, 0x8d, 0xf6, 0x60, 0x17, 0x9c, 0x31, 0xb8, 0xc5, 0x61, 0xa2, 0xe2, + 0x6e, 0x57, 0x25, 0x08, 0x6f, 0x24, 0x99, 0x99, 0xcf, 0x94, 0xbf, 0xc7, + 0x8b, 0x6b, 0xb0, 0x1f, 0xca, 0x14, 0xfa, 0x18, 0x9b, 0x6c, 0x10, 0x7c, + 0x99, 0x2b, 0xda, 0x4a, 0x63, 0xe5, 0xb2, 0x4e, 0xc2, 0xfd, 0x3e, 0x10, + 0x0b, 0x48, 0xf4, 0x77, 0x0b, 0x2f, 0xf0, 0x96, 0x4b, 0x3a, 0xee, 0xbd, + 0x35, 0xde, 0x85, 0x8d, 0xda, 0x13, 0x0e, 0xce, 0x01, 0xc4, 0x71, 0xd3, + 0xd3, 0x77, 0xc5, 0x08, 0xa6, 0x60, 0x39, 0x25, 0xa7, 0x27, 0x69, 0x5c, + 0x83, 0xd1, 0x6f, 0x76, 0x78, 0xee, 0xc5, 0x44, 0x5b, 0x45, 0xbd, 0x29, + 0x3b, 0xe2, 0xc6, 0x09, 0x0f, 0xa2, 0xbe, 0x2b, 0xdc, 0xe3, 0x5c, 0xda, + 0x5a, 0x6f, 0x8e, 0xe7, 0xc9, 0x07, 0x6b, 0x7e, 0xa1, 0xc0, 0x53, 0x95, + 0x82, 0x89, 0xe0, 0x78, 0x5c, 0x72, 0xa8, 0x6c, 0xbe, 0x67, 0x6b, 0xab, + 0xe7, 0x33, 0xd9, 0x87, 0xf2, 0xf8, 0x5c, 0x27, 0xf4, 0xf6, 0x2a, 0x3b, + 0x87, 0xef, 0xda, 0xc2, 0x47, 0xda, 0xbf, 0xac, 0xeb, 0x27, 0x64, 0x7b, + 0x4c, 0x53, 0xeb, 0x34, 0xe1, 0x2f, 0x9b, 0x20, 0x4d, 0x54, 0x12, 0x6b, + 0x7d, 0x28, 0xbd, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x53, + 0x30, 0x82, 0x01, 0x4f, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, + 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 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, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, + 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, + 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa9, 0x2b, + 0x87, 0xe1, 0xce, 0x24, 0x47, 0x3b, 0x1b, 0xbf, 0xcf, 0x85, 0x37, 0x02, + 0x55, 0x9d, 0x0d, 0x94, 0x58, 0xe6, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, + 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x60, 0x7b, 0x66, 0x1a, 0x45, + 0x0d, 0x97, 0xca, 0x89, 0x50, 0x2f, 0x7d, 0x04, 0xcd, 0x34, 0xa8, 0xff, + 0xfc, 0xfd, 0x4b, 0x30, 0x3d, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x01, 0x01, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x21, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6c, 0x6f, + 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x72, 0x6f, 0x6f, 0x74, 0x72, 0x31, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, + 0x1f, 0x04, 0x2c, 0x30, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86, + 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, + 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, + 0x56, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x4f, 0x30, 0x4d, 0x30, 0x0b, + 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xa0, 0x32, 0x01, 0x14, 0x30, + 0x3e, 0x06, 0x06, 0x67, 0x81, 0x0c, 0x01, 0x02, 0x02, 0x30, 0x34, 0x30, + 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, + 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, + 0x2e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x69, 0x67, 0x6e, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x2f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xa2, + 0x1d, 0x69, 0x8a, 0x0a, 0x8e, 0xc4, 0x14, 0x83, 0x2a, 0x2a, 0x12, 0x4d, + 0x39, 0x27, 0x90, 0x4e, 0xf0, 0x8d, 0xac, 0xd2, 0x96, 0x62, 0x47, 0x36, + 0x5e, 0x92, 0xd1, 0xfa, 0xc5, 0x93, 0xb5, 0x37, 0x07, 0x65, 0x29, 0xd2, + 0xf4, 0x53, 0x50, 0x6b, 0xc9, 0xf4, 0xfe, 0x34, 0xf5, 0xdd, 0xb8, 0x1d, + 0xfa, 0xfc, 0xdc, 0x14, 0xac, 0x56, 0x94, 0x27, 0x9c, 0x42, 0xaa, 0x04, + 0x4d, 0xb7, 0xed, 0x58, 0xd9, 0x99, 0xd2, 0x49, 0xe6, 0x20, 0x2f, 0xd3, + 0xa7, 0x77, 0xb8, 0x2a, 0x89, 0x1a, 0xef, 0xa7, 0xcf, 0x86, 0x2d, 0xd6, + 0x53, 0xe9, 0x0b, 0x93, 0x9c, 0x4e, 0xab, 0xd9, 0x45, 0xee, 0xa4, 0x84, + 0x85, 0xff, 0x34, 0xe4, 0x0e, 0xc0, 0xbb, 0xa5, 0xce, 0x5f, 0x95, 0x89, + 0x85, 0x70, 0xaa, 0xc1, 0x5d, 0xec, 0xcf, 0x2b, 0xd3, 0xd9, 0x83, 0xdf, + 0x03, 0xca, 0x81, 0xa7, 0x02, 0x32, 0xb7, 0x77, 0x61, 0x10, 0x25, 0x4e, + 0xd9, 0x74, 0xf3, 0xd9, 0x79, 0x82, 0xb5, 0x26, 0x70, 0xb4, 0x52, 0xbc, + 0x8f, 0x33, 0xd7, 0x8a, 0xae, 0x19, 0xd0, 0xfc, 0x92, 0xad, 0x2f, 0xba, + 0x3c, 0xa0, 0x48, 0x58, 0x47, 0x5e, 0xfd, 0x20, 0x56, 0x95, 0x20, 0xc1, + 0x72, 0x1d, 0xab, 0x66, 0x99, 0xa4, 0xd5, 0x78, 0x37, 0x48, 0x1b, 0x9f, + 0xb2, 0x4c, 0x37, 0x67, 0x7a, 0xfd, 0x42, 0xd2, 0xd3, 0x56, 0x9e, 0xd3, + 0x1d, 0x8e, 0xc4, 0x0c, 0x68, 0x96, 0xb6, 0x47, 0x51, 0x10, 0xf7, 0x7b, + 0xeb, 0x15, 0x09, 0x64, 0xf5, 0xf9, 0xf0, 0x63, 0x16, 0x2d, 0x3d, 0xdf, + 0x23, 0x42, 0x3a, 0x93, 0x63, 0xcc, 0xab, 0xaf, 0x4f, 0x57, 0x06, 0xc7, + 0xfe, 0x14, 0x55, 0x62, 0xce, 0x27, 0x11, 0x19, 0xe1, 0xf4, 0x42, 0xed, + 0x22, 0x30, 0x6b, 0x35, 0x1a, 0x4a, 0x05, 0x80, 0xa4, 0x65, 0xdf, 0xcc, + 0xcb, 0x6f, 0xd0, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 1b:09:3b:78:60:96:da:37:bb:a4:51:94:46:c8:96:78 + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority + Validity + Not Before: Nov 8 00:00:00 2006 GMT + Not After : Nov 7 23:59:59 2021 GMT + Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:af:24:08:08:29:7a:35:9e:60:0c:aa:e7:4b:3b: + 4e:dc:7c:bc:3c:45:1c:bb:2b:e0:fe:29:02:f9:57: + 08:a3:64:85:15:27:f5:f1:ad:c8:31:89:5d:22:e8: + 2a:aa:a6:42:b3:8f:f8:b9:55:b7:b1:b7:4b:b3:fe: + 8f:7e:07:57:ec:ef:43:db:66:62:15:61:cf:60:0d: + a4:d8:de:f8:e0:c3:62:08:3d:54:13:eb:49:ca:59: + 54:85:26:e5:2b:8f:1b:9f:eb:f5:a1:91:c2:33:49: + d8:43:63:6a:52:4b:d2:8f:e8:70:51:4d:d1:89:69: + 7b:c7:70:f6:b3:dc:12:74:db:7b:5d:4b:56:d3:96: + bf:15:77:a1:b0:f4:a2:25:f2:af:1c:92:67:18:e5: + f4:06:04:ef:90:b9:e4:00:e4:dd:3a:b5:19:ff:02: + ba:f4:3c:ee:e0:8b:eb:37:8b:ec:f4:d7:ac:f2:f6: + f0:3d:af:dd:75:91:33:19:1d:1c:40:cb:74:24:19: + 21:93:d9:14:fe:ac:2a:52:c7:8f:d5:04:49:e4:8d: + 63:47:88:3c:69:83:cb:fe:47:bd:2b:7e:4f:c5:95: + ae:0e:9d:d4:d1:43:c0:67:73:e3:14:08:7e:e5:3f: + 9f:73:b8:33:0a:cf:5d:3f:34:87:96:8a:ee:53:e8: + 25:15 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.verisign.com/pca3.crl + + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: https://www.verisign.com/cps + + X509v3 Subject Key Identifier: + 7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33 + 1.3.6.1.5.5.7.1.12: + 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif + Authority Information Access: + OCSP - URI:http://ocsp.verisign.com + + Signature Algorithm: sha1WithRSAEncryption + a3:cd:7d:1e:f7:c7:75:8d:48:e7:56:34:4c:00:90:75:a9:51: + a5:56:c1:6d:bc:fe:f5:53:22:e9:98:a2:ac:9a:7e:70:1e:b3: + 8e:3b:45:e3:86:95:31:da:6d:4c:fb:34:50:80:96:cd:24:f2: + 40:df:04:3f:e2:65:ce:34:22:61:15:ea:66:70:64:d2:f1:6e: + f3:ca:18:59:6a:41:46:7e:82:de:19:b0:70:31:56:69:0d:0c: + e6:1d:9d:71:58:dc:cc:de:62:f5:e1:7a:10:02:d8:7a:dc:3b: + fa:57:bd:c9:e9:8f:46:21:39:9f:51:65:4c:8e:3a:be:28:41: + 70:1d +-----BEGIN CERTIFICATE----- +MIIEkDCCA/mgAwIBAgIQGwk7eGCW2je7pFGURsiWeDANBgkqhkiG9w0BAQUFADBf +MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsT +LkNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw +HhcNMDYxMTA4MDAwMDAwWhcNMjExMTA3MjM1OTU5WjCByjELMAkGA1UEBhMCVVMx +FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz +dCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZv +ciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAz +IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8 +RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbext0uz/o9+B1fs70Pb +ZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhDY2pSS9KP6HBR +TdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/ +Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNH +iDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMB +AAGjggFbMIIBVzAPBgNVHRMBAf8EBTADAQH/MDEGA1UdHwQqMCgwJqAkoCKGIGh0 +dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMuY3JsMA4GA1UdDwEB/wQEAwIBBjA9 +BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVy +aXNpZ24uY29tL2NwczAdBgNVHQ4EFgQUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwbQYI +KwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQU +j+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24uY29t +L3ZzbG9nby5naWYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v +b2NzcC52ZXJpc2lnbi5jb20wDQYJKoZIhvcNAQEFBQADgYEAo819HvfHdY1I51Y0 +TACQdalRpVbBbbz+9VMi6ZiirJp+cB6zjjtF44aVMdptTPs0UICWzSTyQN8EP+Jl +zjQiYRXqZnBk0vFu88oYWWpBRn6C3hmwcDFWaQ0M5h2dcVjczN5i9eF6EALYetw7 ++le9yemPRiE5n1FlTI46vihBcB0= +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert21[] = { + 0x30, 0x82, 0x04, 0x90, 0x30, 0x82, 0x03, 0xf9, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x1b, 0x09, 0x3b, 0x78, 0x60, 0x96, 0xda, 0x37, 0xbb, + 0xa4, 0x51, 0x94, 0x46, 0xc8, 0x96, 0x78, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5f, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, + 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, + 0x63, 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, + 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, + 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x30, 0x38, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31, 0x30, 0x37, + 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xca, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, + 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56, + 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3a, 0x30, + 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, 0x63, 0x29, 0x20, + 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, + 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x45, 0x30, + 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56, 0x65, 0x72, 0x69, + 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, + 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 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, 0xaf, 0x24, 0x08, 0x08, 0x29, 0x7a, 0x35, + 0x9e, 0x60, 0x0c, 0xaa, 0xe7, 0x4b, 0x3b, 0x4e, 0xdc, 0x7c, 0xbc, 0x3c, + 0x45, 0x1c, 0xbb, 0x2b, 0xe0, 0xfe, 0x29, 0x02, 0xf9, 0x57, 0x08, 0xa3, + 0x64, 0x85, 0x15, 0x27, 0xf5, 0xf1, 0xad, 0xc8, 0x31, 0x89, 0x5d, 0x22, + 0xe8, 0x2a, 0xaa, 0xa6, 0x42, 0xb3, 0x8f, 0xf8, 0xb9, 0x55, 0xb7, 0xb1, + 0xb7, 0x4b, 0xb3, 0xfe, 0x8f, 0x7e, 0x07, 0x57, 0xec, 0xef, 0x43, 0xdb, + 0x66, 0x62, 0x15, 0x61, 0xcf, 0x60, 0x0d, 0xa4, 0xd8, 0xde, 0xf8, 0xe0, + 0xc3, 0x62, 0x08, 0x3d, 0x54, 0x13, 0xeb, 0x49, 0xca, 0x59, 0x54, 0x85, + 0x26, 0xe5, 0x2b, 0x8f, 0x1b, 0x9f, 0xeb, 0xf5, 0xa1, 0x91, 0xc2, 0x33, + 0x49, 0xd8, 0x43, 0x63, 0x6a, 0x52, 0x4b, 0xd2, 0x8f, 0xe8, 0x70, 0x51, + 0x4d, 0xd1, 0x89, 0x69, 0x7b, 0xc7, 0x70, 0xf6, 0xb3, 0xdc, 0x12, 0x74, + 0xdb, 0x7b, 0x5d, 0x4b, 0x56, 0xd3, 0x96, 0xbf, 0x15, 0x77, 0xa1, 0xb0, + 0xf4, 0xa2, 0x25, 0xf2, 0xaf, 0x1c, 0x92, 0x67, 0x18, 0xe5, 0xf4, 0x06, + 0x04, 0xef, 0x90, 0xb9, 0xe4, 0x00, 0xe4, 0xdd, 0x3a, 0xb5, 0x19, 0xff, + 0x02, 0xba, 0xf4, 0x3c, 0xee, 0xe0, 0x8b, 0xeb, 0x37, 0x8b, 0xec, 0xf4, + 0xd7, 0xac, 0xf2, 0xf6, 0xf0, 0x3d, 0xaf, 0xdd, 0x75, 0x91, 0x33, 0x19, + 0x1d, 0x1c, 0x40, 0xcb, 0x74, 0x24, 0x19, 0x21, 0x93, 0xd9, 0x14, 0xfe, + 0xac, 0x2a, 0x52, 0xc7, 0x8f, 0xd5, 0x04, 0x49, 0xe4, 0x8d, 0x63, 0x47, + 0x88, 0x3c, 0x69, 0x83, 0xcb, 0xfe, 0x47, 0xbd, 0x2b, 0x7e, 0x4f, 0xc5, + 0x95, 0xae, 0x0e, 0x9d, 0xd4, 0xd1, 0x43, 0xc0, 0x67, 0x73, 0xe3, 0x14, + 0x08, 0x7e, 0xe5, 0x3f, 0x9f, 0x73, 0xb8, 0x33, 0x0a, 0xcf, 0x5d, 0x3f, + 0x34, 0x87, 0x96, 0x8a, 0xee, 0x53, 0xe8, 0x25, 0x15, 0x02, 0x03, 0x01, + 0x00, 0x01, 0xa3, 0x82, 0x01, 0x5b, 0x30, 0x82, 0x01, 0x57, 0x30, 0x0f, + 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, + 0x01, 0x01, 0xff, 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2a, + 0x30, 0x28, 0x30, 0x26, 0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, + 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, + 0x61, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3d, + 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06, + 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, + 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, + 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, + 0x73, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, + 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3, + 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x6d, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f, + 0xa1, 0x5d, 0xa0, 0x5b, 0x30, 0x59, 0x30, 0x57, 0x30, 0x55, 0x16, 0x09, + 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x30, 0x21, 0x30, + 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, + 0x8f, 0xe5, 0xd3, 0x1a, 0x86, 0xac, 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80, + 0x6a, 0xd4, 0x48, 0x18, 0x2c, 0x7b, 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, + 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x76, 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30, + 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, + 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, + 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, + 0xa3, 0xcd, 0x7d, 0x1e, 0xf7, 0xc7, 0x75, 0x8d, 0x48, 0xe7, 0x56, 0x34, + 0x4c, 0x00, 0x90, 0x75, 0xa9, 0x51, 0xa5, 0x56, 0xc1, 0x6d, 0xbc, 0xfe, + 0xf5, 0x53, 0x22, 0xe9, 0x98, 0xa2, 0xac, 0x9a, 0x7e, 0x70, 0x1e, 0xb3, + 0x8e, 0x3b, 0x45, 0xe3, 0x86, 0x95, 0x31, 0xda, 0x6d, 0x4c, 0xfb, 0x34, + 0x50, 0x80, 0x96, 0xcd, 0x24, 0xf2, 0x40, 0xdf, 0x04, 0x3f, 0xe2, 0x65, + 0xce, 0x34, 0x22, 0x61, 0x15, 0xea, 0x66, 0x70, 0x64, 0xd2, 0xf1, 0x6e, + 0xf3, 0xca, 0x18, 0x59, 0x6a, 0x41, 0x46, 0x7e, 0x82, 0xde, 0x19, 0xb0, + 0x70, 0x31, 0x56, 0x69, 0x0d, 0x0c, 0xe6, 0x1d, 0x9d, 0x71, 0x58, 0xdc, + 0xcc, 0xde, 0x62, 0xf5, 0xe1, 0x7a, 0x10, 0x02, 0xd8, 0x7a, 0xdc, 0x3b, + 0xfa, 0x57, 0xbd, 0xc9, 0xe9, 0x8f, 0x46, 0x21, 0x39, 0x9f, 0x51, 0x65, + 0x4c, 0x8e, 0x3a, 0xbe, 0x28, 0x41, 0x70, 0x1d, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 0a:01:41:42:00:00:01:53:85:73:6a:0b:85:ec:a7:08 + Signature Algorithm: sha256WithRSAEncryption + Issuer: O=Digital Signature Trust Co., CN=DST Root CA X3 + Validity + Not Before: Mar 17 16:40:46 2016 GMT + Not After : Mar 17 16:40:46 2021 GMT + Subject: C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:9c:d3:0c:f0:5a:e5:2e:47:b7:72:5d:37:83:b3: + 68:63:30:ea:d7:35:26:19:25:e1:bd:be:35:f1:70: + 92:2f:b7:b8:4b:41:05:ab:a9:9e:35:08:58:ec:b1: + 2a:c4:68:87:0b:a3:e3:75:e4:e6:f3:a7:62:71:ba: + 79:81:60:1f:d7:91:9a:9f:f3:d0:78:67:71:c8:69: + 0e:95:91:cf:fe:e6:99:e9:60:3c:48:cc:7e:ca:4d: + 77:12:24:9d:47:1b:5a:eb:b9:ec:1e:37:00:1c:9c: + ac:7b:a7:05:ea:ce:4a:eb:bd:41:e5:36:98:b9:cb: + fd:6d:3c:96:68:df:23:2a:42:90:0c:86:74:67:c8: + 7f:a5:9a:b8:52:61:14:13:3f:65:e9:82:87:cb:db: + fa:0e:56:f6:86:89:f3:85:3f:97:86:af:b0:dc:1a: + ef:6b:0d:95:16:7d:c4:2b:a0:65:b2:99:04:36:75: + 80:6b:ac:4a:f3:1b:90:49:78:2f:a2:96:4f:2a:20: + 25:29:04:c6:74:c0:d0:31:cd:8f:31:38:95:16:ba: + a8:33:b8:43:f1:b1:1f:c3:30:7f:a2:79:31:13:3d: + 2d:36:f8:e3:fc:f2:33:6a:b9:39:31:c5:af:c4:8d: + 0d:1d:64:16:33:aa:fa:84:29:b6:d4:0b:c0:d8:7d: + c3:93 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + Authority Information Access: + OCSP - URI:http://isrg.trustid.ocsp.identrust.com + CA Issuers - URI:http://apps.identrust.com/roots/dstrootcax3.p7c + + X509v3 Authority Key Identifier: + keyid:C4:A7:B1:A4:7B:2C:71:FA:DB:E1:4B:90:75:FF:C4:15:60:85:89:10 + + X509v3 Certificate Policies: + Policy: 2.23.140.1.2.1 + Policy: 1.3.6.1.4.1.44947.1.1.1 + CPS: http://cps.root-x1.letsencrypt.org + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.identrust.com/DSTROOTCAX3CRL.crl + + X509v3 Subject Key Identifier: + A8:4A:6A:63:04:7D:DD:BA:E6:D1:39:B7:A6:45:65:EF:F3:A8:EC:A1 + Signature Algorithm: sha256WithRSAEncryption + dd:33:d7:11:f3:63:58:38:dd:18:15:fb:09:55:be:76:56:b9: + 70:48:a5:69:47:27:7b:c2:24:08:92:f1:5a:1f:4a:12:29:37: + 24:74:51:1c:62:68:b8:cd:95:70:67:e5:f7:a4:bc:4e:28:51: + cd:9b:e8:ae:87:9d:ea:d8:ba:5a:a1:01:9a:dc:f0:dd:6a:1d: + 6a:d8:3e:57:23:9e:a6:1e:04:62:9a:ff:d7:05:ca:b7:1f:3f: + c0:0a:48:bc:94:b0:b6:65:62:e0:c1:54:e5:a3:2a:ad:20:c4: + e9:e6:bb:dc:c8:f6:b5:c3:32:a3:98:cc:77:a8:e6:79:65:07: + 2b:cb:28:fe:3a:16:52:81:ce:52:0c:2e:5f:83:e8:d5:06:33: + fb:77:6c:ce:40:ea:32:9e:1f:92:5c:41:c1:74:6c:5b:5d:0a: + 5f:33:cc:4d:9f:ac:38:f0:2f:7b:2c:62:9d:d9:a3:91:6f:25: + 1b:2f:90:b1:19:46:3d:f6:7e:1b:a6:7a:87:b9:a3:7a:6d:18: + fa:25:a5:91:87:15:e0:f2:16:2f:58:b0:06:2f:2c:68:26:c6: + 4b:98:cd:da:9f:0c:f9:7f:90:ed:43:4a:12:44:4e:6f:73:7a: + 28:ea:a4:aa:6e:7b:4c:7d:87:dd:e0:c9:02:44:a7:87:af:c3: + 34:5b:b4:42 +-----BEGIN CERTIFICATE----- +MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/ +MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT +DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow +SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT +GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF +q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8 +SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0 +Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA +a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj +/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T +AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG +CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv +bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k +c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw +VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC +ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz +MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu +Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF +AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo +uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/ +wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu +X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG +PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6 +KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg== +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert22[] = { + 0x30, 0x82, 0x04, 0x92, 0x30, 0x82, 0x03, 0x7a, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x0a, 0x01, 0x41, 0x42, 0x00, 0x00, 0x01, 0x53, 0x85, + 0x73, 0x6a, 0x0b, 0x85, 0xec, 0xa7, 0x08, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3f, + 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1b, 0x44, + 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43, + 0x6f, 0x2e, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x0e, 0x44, 0x53, 0x54, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, + 0x20, 0x58, 0x33, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x33, 0x31, + 0x37, 0x31, 0x36, 0x34, 0x30, 0x34, 0x36, 0x5a, 0x17, 0x0d, 0x32, 0x31, + 0x30, 0x33, 0x31, 0x37, 0x31, 0x36, 0x34, 0x30, 0x34, 0x36, 0x5a, 0x30, + 0x4a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x0d, 0x4c, 0x65, 0x74, 0x27, 0x73, 0x20, 0x45, 0x6e, 0x63, 0x72, 0x79, + 0x70, 0x74, 0x31, 0x23, 0x30, 0x21, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x1a, 0x4c, 0x65, 0x74, 0x27, 0x73, 0x20, 0x45, 0x6e, 0x63, 0x72, 0x79, + 0x70, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, + 0x20, 0x58, 0x33, 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, + 0x9c, 0xd3, 0x0c, 0xf0, 0x5a, 0xe5, 0x2e, 0x47, 0xb7, 0x72, 0x5d, 0x37, + 0x83, 0xb3, 0x68, 0x63, 0x30, 0xea, 0xd7, 0x35, 0x26, 0x19, 0x25, 0xe1, + 0xbd, 0xbe, 0x35, 0xf1, 0x70, 0x92, 0x2f, 0xb7, 0xb8, 0x4b, 0x41, 0x05, + 0xab, 0xa9, 0x9e, 0x35, 0x08, 0x58, 0xec, 0xb1, 0x2a, 0xc4, 0x68, 0x87, + 0x0b, 0xa3, 0xe3, 0x75, 0xe4, 0xe6, 0xf3, 0xa7, 0x62, 0x71, 0xba, 0x79, + 0x81, 0x60, 0x1f, 0xd7, 0x91, 0x9a, 0x9f, 0xf3, 0xd0, 0x78, 0x67, 0x71, + 0xc8, 0x69, 0x0e, 0x95, 0x91, 0xcf, 0xfe, 0xe6, 0x99, 0xe9, 0x60, 0x3c, + 0x48, 0xcc, 0x7e, 0xca, 0x4d, 0x77, 0x12, 0x24, 0x9d, 0x47, 0x1b, 0x5a, + 0xeb, 0xb9, 0xec, 0x1e, 0x37, 0x00, 0x1c, 0x9c, 0xac, 0x7b, 0xa7, 0x05, + 0xea, 0xce, 0x4a, 0xeb, 0xbd, 0x41, 0xe5, 0x36, 0x98, 0xb9, 0xcb, 0xfd, + 0x6d, 0x3c, 0x96, 0x68, 0xdf, 0x23, 0x2a, 0x42, 0x90, 0x0c, 0x86, 0x74, + 0x67, 0xc8, 0x7f, 0xa5, 0x9a, 0xb8, 0x52, 0x61, 0x14, 0x13, 0x3f, 0x65, + 0xe9, 0x82, 0x87, 0xcb, 0xdb, 0xfa, 0x0e, 0x56, 0xf6, 0x86, 0x89, 0xf3, + 0x85, 0x3f, 0x97, 0x86, 0xaf, 0xb0, 0xdc, 0x1a, 0xef, 0x6b, 0x0d, 0x95, + 0x16, 0x7d, 0xc4, 0x2b, 0xa0, 0x65, 0xb2, 0x99, 0x04, 0x36, 0x75, 0x80, + 0x6b, 0xac, 0x4a, 0xf3, 0x1b, 0x90, 0x49, 0x78, 0x2f, 0xa2, 0x96, 0x4f, + 0x2a, 0x20, 0x25, 0x29, 0x04, 0xc6, 0x74, 0xc0, 0xd0, 0x31, 0xcd, 0x8f, + 0x31, 0x38, 0x95, 0x16, 0xba, 0xa8, 0x33, 0xb8, 0x43, 0xf1, 0xb1, 0x1f, + 0xc3, 0x30, 0x7f, 0xa2, 0x79, 0x31, 0x13, 0x3d, 0x2d, 0x36, 0xf8, 0xe3, + 0xfc, 0xf2, 0x33, 0x6a, 0xb9, 0x39, 0x31, 0xc5, 0xaf, 0xc4, 0x8d, 0x0d, + 0x1d, 0x64, 0x16, 0x33, 0xaa, 0xfa, 0x84, 0x29, 0xb6, 0xd4, 0x0b, 0xc0, + 0xd8, 0x7d, 0xc3, 0x93, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, + 0x7d, 0x30, 0x82, 0x01, 0x79, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, + 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, + 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x7f, 0x06, 0x08, 0x2b, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x73, 0x30, 0x71, 0x30, 0x32, 0x06, + 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x26, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x69, 0x73, 0x72, 0x67, 0x2e, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x69, 0x64, 0x2e, 0x6f, 0x63, 0x73, 0x70, 0x2e, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, + 0x6d, 0x30, 0x3b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, + 0x02, 0x86, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x61, 0x70, + 0x70, 0x73, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x73, 0x2f, 0x64, + 0x73, 0x74, 0x72, 0x6f, 0x6f, 0x74, 0x63, 0x61, 0x78, 0x33, 0x2e, 0x70, + 0x37, 0x63, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, + 0x16, 0x80, 0x14, 0xc4, 0xa7, 0xb1, 0xa4, 0x7b, 0x2c, 0x71, 0xfa, 0xdb, + 0xe1, 0x4b, 0x90, 0x75, 0xff, 0xc4, 0x15, 0x60, 0x85, 0x89, 0x10, 0x30, + 0x54, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x4d, 0x30, 0x4b, 0x30, 0x08, + 0x06, 0x06, 0x67, 0x81, 0x0c, 0x01, 0x02, 0x01, 0x30, 0x3f, 0x06, 0x0b, + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xdf, 0x13, 0x01, 0x01, 0x01, 0x30, + 0x30, 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, + 0x01, 0x16, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x70, + 0x73, 0x2e, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x78, 0x31, 0x2e, 0x6c, 0x65, + 0x74, 0x73, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2e, 0x6f, 0x72, + 0x67, 0x30, 0x3c, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x35, 0x30, 0x33, + 0x30, 0x31, 0xa0, 0x2f, 0xa0, 0x2d, 0x86, 0x2b, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x53, 0x54, + 0x52, 0x4f, 0x4f, 0x54, 0x43, 0x41, 0x58, 0x33, 0x43, 0x52, 0x4c, 0x2e, + 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, + 0x04, 0x14, 0xa8, 0x4a, 0x6a, 0x63, 0x04, 0x7d, 0xdd, 0xba, 0xe6, 0xd1, + 0x39, 0xb7, 0xa6, 0x45, 0x65, 0xef, 0xf3, 0xa8, 0xec, 0xa1, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xdd, 0x33, 0xd7, 0x11, 0xf3, 0x63, + 0x58, 0x38, 0xdd, 0x18, 0x15, 0xfb, 0x09, 0x55, 0xbe, 0x76, 0x56, 0xb9, + 0x70, 0x48, 0xa5, 0x69, 0x47, 0x27, 0x7b, 0xc2, 0x24, 0x08, 0x92, 0xf1, + 0x5a, 0x1f, 0x4a, 0x12, 0x29, 0x37, 0x24, 0x74, 0x51, 0x1c, 0x62, 0x68, + 0xb8, 0xcd, 0x95, 0x70, 0x67, 0xe5, 0xf7, 0xa4, 0xbc, 0x4e, 0x28, 0x51, + 0xcd, 0x9b, 0xe8, 0xae, 0x87, 0x9d, 0xea, 0xd8, 0xba, 0x5a, 0xa1, 0x01, + 0x9a, 0xdc, 0xf0, 0xdd, 0x6a, 0x1d, 0x6a, 0xd8, 0x3e, 0x57, 0x23, 0x9e, + 0xa6, 0x1e, 0x04, 0x62, 0x9a, 0xff, 0xd7, 0x05, 0xca, 0xb7, 0x1f, 0x3f, + 0xc0, 0x0a, 0x48, 0xbc, 0x94, 0xb0, 0xb6, 0x65, 0x62, 0xe0, 0xc1, 0x54, + 0xe5, 0xa3, 0x2a, 0xad, 0x20, 0xc4, 0xe9, 0xe6, 0xbb, 0xdc, 0xc8, 0xf6, + 0xb5, 0xc3, 0x32, 0xa3, 0x98, 0xcc, 0x77, 0xa8, 0xe6, 0x79, 0x65, 0x07, + 0x2b, 0xcb, 0x28, 0xfe, 0x3a, 0x16, 0x52, 0x81, 0xce, 0x52, 0x0c, 0x2e, + 0x5f, 0x83, 0xe8, 0xd5, 0x06, 0x33, 0xfb, 0x77, 0x6c, 0xce, 0x40, 0xea, + 0x32, 0x9e, 0x1f, 0x92, 0x5c, 0x41, 0xc1, 0x74, 0x6c, 0x5b, 0x5d, 0x0a, + 0x5f, 0x33, 0xcc, 0x4d, 0x9f, 0xac, 0x38, 0xf0, 0x2f, 0x7b, 0x2c, 0x62, + 0x9d, 0xd9, 0xa3, 0x91, 0x6f, 0x25, 0x1b, 0x2f, 0x90, 0xb1, 0x19, 0x46, + 0x3d, 0xf6, 0x7e, 0x1b, 0xa6, 0x7a, 0x87, 0xb9, 0xa3, 0x7a, 0x6d, 0x18, + 0xfa, 0x25, 0xa5, 0x91, 0x87, 0x15, 0xe0, 0xf2, 0x16, 0x2f, 0x58, 0xb0, + 0x06, 0x2f, 0x2c, 0x68, 0x26, 0xc6, 0x4b, 0x98, 0xcd, 0xda, 0x9f, 0x0c, + 0xf9, 0x7f, 0x90, 0xed, 0x43, 0x4a, 0x12, 0x44, 0x4e, 0x6f, 0x73, 0x7a, + 0x28, 0xea, 0xa4, 0xaa, 0x6e, 0x7b, 0x4c, 0x7d, 0x87, 0xdd, 0xe0, 0xc9, + 0x02, 0x44, 0xa7, 0x87, 0xaf, 0xc3, 0x34, 0x5b, 0xb4, 0x42, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 06:7f:94:4a:2a:27:cd:f3:fa:c2:ae:2b:01:f9:08:ee:b9:c4:c6 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Services Root Certificate Authority - G2 + Validity + Not Before: May 25 12:00:00 2015 GMT + Not After : Dec 31 01:00:00 2037 GMT + Subject: C=US, O=Amazon, CN=Amazon Root CA 1 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:b2:78:80:71:ca:78:d5:e3:71:af:47:80:50:74: + 7d:6e:d8:d7:88:76:f4:99:68:f7:58:21:60:f9:74: + 84:01:2f:ac:02:2d:86:d3:a0:43:7a:4e:b2:a4:d0: + 36:ba:01:be:8d:db:48:c8:07:17:36:4c:f4:ee:88: + 23:c7:3e:eb:37:f5:b5:19:f8:49:68:b0:de:d7:b9: + 76:38:1d:61:9e:a4:fe:82:36:a5:e5:4a:56:e4:45: + e1:f9:fd:b4:16:fa:74:da:9c:9b:35:39:2f:fa:b0: + 20:50:06:6c:7a:d0:80:b2:a6:f9:af:ec:47:19:8f: + 50:38:07:dc:a2:87:39:58:f8:ba:d5:a9:f9:48:67: + 30:96:ee:94:78:5e:6f:89:a3:51:c0:30:86:66:a1: + 45:66:ba:54:eb:a3:c3:91:f9:48:dc:ff:d1:e8:30: + 2d:7d:2d:74:70:35:d7:88:24:f7:9e:c4:59:6e:bb: + 73:87:17:f2:32:46:28:b8:43:fa:b7:1d:aa:ca:b4: + f2:9f:24:0e:2d:4b:f7:71:5c:5e:69:ff:ea:95:02: + cb:38:8a:ae:50:38:6f:db:fb:2d:62:1b:c5:c7:1e: + 54:e1:77:e0:67:c8:0f:9c:87:23:d6:3f:40:20:7f: + 20:80:c4:80:4c:3e:3b:24:26:8e:04:ae:6c:9a:c8: + aa:0d + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 84:18:CC:85:34:EC:BC:0C:94:94:2E:08:59:9C:C7:B2:10:4E:0A:08 + X509v3 Authority Key Identifier: + keyid:9C:5F:00:DF:AA:01:D7:30:2B:38:88:A2:B8:6D:4A:9C:F2:11:91:83 + + Authority Information Access: + OCSP - URI:http://ocsp.rootg2.amazontrust.com + CA Issuers - URI:http://crt.rootg2.amazontrust.com/rootg2.cer + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.rootg2.amazontrust.com/rootg2.crl + + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + + Signature Algorithm: sha256WithRSAEncryption + 62:37:42:5c:bc:10:b5:3e:8b:2c:e9:0c:9b:6c:45:e2:07:00: + 7a:f9:c5:58:0b:b9:08:8c:3e:ed:b3:25:3c:b5:6f:50:e4:cd: + 35:6a:a7:93:34:96:32:21:a9:48:44:ab:9c:ed:3d:b4:aa:73: + 6d:e4:7f:16:80:89:6c:cf:28:03:18:83:47:79:a3:10:7e:30: + 5b:ac:3b:b0:60:e0:77:d4:08:a6:e1:1d:7c:5e:c0:bb:f9:9a: + 7b:22:9d:a7:00:09:7e:ac:46:17:83:dc:9c:26:57:99:30:39: + 62:96:8f:ed:da:de:aa:c5:cc:1b:3e:ca:43:68:6c:57:16:bc: + d5:0e:20:2e:fe:ff:c2:6a:5d:2e:a0:4a:6d:14:58:87:94:e6: + 39:31:5f:7c:73:cb:90:88:6a:84:11:96:27:a6:ed:d9:81:46: + a6:7e:a3:72:00:0a:52:3e:83:88:07:63:77:89:69:17:0f:39: + 85:d2:ab:08:45:4d:d0:51:3a:fd:5d:5d:37:64:4c:7e:30:b2: + 55:24:42:9d:36:b0:5d:9c:17:81:61:f1:ca:f9:10:02:24:ab: + eb:0d:74:91:8d:7b:45:29:50:39:88:b2:a6:89:35:25:1e:14: + 6a:47:23:31:2f:5c:9a:fa:ad:9a:0e:62:51:a4:2a:a9:c4:f9: + 34:9d:21:18 +-----BEGIN CERTIFICATE----- +MIIEkjCCA3qgAwIBAgITBn+USionzfP6wq4rAfkI7rnExjANBgkqhkiG9w0BAQsF +ADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNj +b3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4x +OzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1 +dGhvcml0eSAtIEcyMB4XDTE1MDUyNTEyMDAwMFoXDTM3MTIzMTAxMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm +jgSubJrIqg0CAwEAAaOCATEwggEtMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBSEGMyFNOy8DJSULghZnMeyEE4KCDAfBgNVHSMEGDAW +gBScXwDfqgHXMCs4iKK4bUqc8hGRgzB4BggrBgEFBQcBAQRsMGowLgYIKwYBBQUH +MAGGImh0dHA6Ly9vY3NwLnJvb3RnMi5hbWF6b250cnVzdC5jb20wOAYIKwYBBQUH +MAKGLGh0dHA6Ly9jcnQucm9vdGcyLmFtYXpvbnRydXN0LmNvbS9yb290ZzIuY2Vy +MD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6Ly9jcmwucm9vdGcyLmFtYXpvbnRydXN0 +LmNvbS9yb290ZzIuY3JsMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQsF +AAOCAQEAYjdCXLwQtT6LLOkMm2xF4gcAevnFWAu5CIw+7bMlPLVvUOTNNWqnkzSW +MiGpSESrnO09tKpzbeR/FoCJbM8oAxiDR3mjEH4wW6w7sGDgd9QIpuEdfF7Au/ma +eyKdpwAJfqxGF4PcnCZXmTA5YpaP7dreqsXMGz7KQ2hsVxa81Q4gLv7/wmpdLqBK +bRRYh5TmOTFffHPLkIhqhBGWJ6bt2YFGpn6jcgAKUj6DiAdjd4lpFw85hdKrCEVN +0FE6/V1dN2RMfjCyVSRCnTawXZwXgWHxyvkQAiSr6w10kY17RSlQOYiypok1JR4U +akcjMS9cmvqtmg5iUaQqqcT5NJ0hGA== +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert23[] = { + 0x30, 0x82, 0x04, 0x92, 0x30, 0x82, 0x03, 0x7a, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x13, 0x06, 0x7f, 0x94, 0x4a, 0x2a, 0x27, 0xcd, 0xf3, 0xfa, + 0xc2, 0xae, 0x2b, 0x01, 0xf9, 0x08, 0xee, 0xb9, 0xc4, 0xc6, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x30, 0x81, 0x98, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, + 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, + 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, + 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, + 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x25, 0x30, 0x23, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53, 0x74, 0x61, 0x72, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, + 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, + 0x3b, 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x32, 0x53, 0x74, + 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, + 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x35, 0x32, 0x35, 0x31, 0x32, + 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x37, 0x31, 0x32, 0x33, + 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x39, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x06, 0x41, 0x6d, + 0x61, 0x7a, 0x6f, 0x6e, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x10, 0x41, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x20, 0x52, 0x6f, + 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20, 0x31, 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, 0xb2, 0x78, 0x80, 0x71, 0xca, 0x78, 0xd5, 0xe3, + 0x71, 0xaf, 0x47, 0x80, 0x50, 0x74, 0x7d, 0x6e, 0xd8, 0xd7, 0x88, 0x76, + 0xf4, 0x99, 0x68, 0xf7, 0x58, 0x21, 0x60, 0xf9, 0x74, 0x84, 0x01, 0x2f, + 0xac, 0x02, 0x2d, 0x86, 0xd3, 0xa0, 0x43, 0x7a, 0x4e, 0xb2, 0xa4, 0xd0, + 0x36, 0xba, 0x01, 0xbe, 0x8d, 0xdb, 0x48, 0xc8, 0x07, 0x17, 0x36, 0x4c, + 0xf4, 0xee, 0x88, 0x23, 0xc7, 0x3e, 0xeb, 0x37, 0xf5, 0xb5, 0x19, 0xf8, + 0x49, 0x68, 0xb0, 0xde, 0xd7, 0xb9, 0x76, 0x38, 0x1d, 0x61, 0x9e, 0xa4, + 0xfe, 0x82, 0x36, 0xa5, 0xe5, 0x4a, 0x56, 0xe4, 0x45, 0xe1, 0xf9, 0xfd, + 0xb4, 0x16, 0xfa, 0x74, 0xda, 0x9c, 0x9b, 0x35, 0x39, 0x2f, 0xfa, 0xb0, + 0x20, 0x50, 0x06, 0x6c, 0x7a, 0xd0, 0x80, 0xb2, 0xa6, 0xf9, 0xaf, 0xec, + 0x47, 0x19, 0x8f, 0x50, 0x38, 0x07, 0xdc, 0xa2, 0x87, 0x39, 0x58, 0xf8, + 0xba, 0xd5, 0xa9, 0xf9, 0x48, 0x67, 0x30, 0x96, 0xee, 0x94, 0x78, 0x5e, + 0x6f, 0x89, 0xa3, 0x51, 0xc0, 0x30, 0x86, 0x66, 0xa1, 0x45, 0x66, 0xba, + 0x54, 0xeb, 0xa3, 0xc3, 0x91, 0xf9, 0x48, 0xdc, 0xff, 0xd1, 0xe8, 0x30, + 0x2d, 0x7d, 0x2d, 0x74, 0x70, 0x35, 0xd7, 0x88, 0x24, 0xf7, 0x9e, 0xc4, + 0x59, 0x6e, 0xbb, 0x73, 0x87, 0x17, 0xf2, 0x32, 0x46, 0x28, 0xb8, 0x43, + 0xfa, 0xb7, 0x1d, 0xaa, 0xca, 0xb4, 0xf2, 0x9f, 0x24, 0x0e, 0x2d, 0x4b, + 0xf7, 0x71, 0x5c, 0x5e, 0x69, 0xff, 0xea, 0x95, 0x02, 0xcb, 0x38, 0x8a, + 0xae, 0x50, 0x38, 0x6f, 0xdb, 0xfb, 0x2d, 0x62, 0x1b, 0xc5, 0xc7, 0x1e, + 0x54, 0xe1, 0x77, 0xe0, 0x67, 0xc8, 0x0f, 0x9c, 0x87, 0x23, 0xd6, 0x3f, + 0x40, 0x20, 0x7f, 0x20, 0x80, 0xc4, 0x80, 0x4c, 0x3e, 0x3b, 0x24, 0x26, + 0x8e, 0x04, 0xae, 0x6c, 0x9a, 0xc8, 0xaa, 0x0d, 0x02, 0x03, 0x01, 0x00, + 0x01, 0xa3, 0x82, 0x01, 0x31, 0x30, 0x82, 0x01, 0x2d, 0x30, 0x0f, 0x06, + 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, + 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, + 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, + 0x0e, 0x04, 0x16, 0x04, 0x14, 0x84, 0x18, 0xcc, 0x85, 0x34, 0xec, 0xbc, + 0x0c, 0x94, 0x94, 0x2e, 0x08, 0x59, 0x9c, 0xc7, 0xb2, 0x10, 0x4e, 0x0a, + 0x08, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0x9c, 0x5f, 0x00, 0xdf, 0xaa, 0x01, 0xd7, 0x30, 0x2b, 0x38, + 0x88, 0xa2, 0xb8, 0x6d, 0x4a, 0x9c, 0xf2, 0x11, 0x91, 0x83, 0x30, 0x78, + 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x6c, + 0x30, 0x6a, 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x30, 0x01, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, + 0x63, 0x73, 0x70, 0x2e, 0x72, 0x6f, 0x6f, 0x74, 0x67, 0x32, 0x2e, 0x61, + 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, + 0x6f, 0x6d, 0x30, 0x38, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x30, 0x02, 0x86, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, + 0x72, 0x74, 0x2e, 0x72, 0x6f, 0x6f, 0x74, 0x67, 0x32, 0x2e, 0x61, 0x6d, + 0x61, 0x7a, 0x6f, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x67, 0x32, 0x2e, 0x63, 0x65, 0x72, + 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x36, 0x30, 0x34, 0x30, + 0x32, 0xa0, 0x30, 0xa0, 0x2e, 0x86, 0x2c, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x72, 0x6f, 0x6f, 0x74, 0x67, 0x32, + 0x2e, 0x61, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x67, 0x32, 0x2e, + 0x63, 0x72, 0x6c, 0x30, 0x11, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x0a, + 0x30, 0x08, 0x30, 0x06, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x62, 0x37, 0x42, 0x5c, 0xbc, 0x10, + 0xb5, 0x3e, 0x8b, 0x2c, 0xe9, 0x0c, 0x9b, 0x6c, 0x45, 0xe2, 0x07, 0x00, + 0x7a, 0xf9, 0xc5, 0x58, 0x0b, 0xb9, 0x08, 0x8c, 0x3e, 0xed, 0xb3, 0x25, + 0x3c, 0xb5, 0x6f, 0x50, 0xe4, 0xcd, 0x35, 0x6a, 0xa7, 0x93, 0x34, 0x96, + 0x32, 0x21, 0xa9, 0x48, 0x44, 0xab, 0x9c, 0xed, 0x3d, 0xb4, 0xaa, 0x73, + 0x6d, 0xe4, 0x7f, 0x16, 0x80, 0x89, 0x6c, 0xcf, 0x28, 0x03, 0x18, 0x83, + 0x47, 0x79, 0xa3, 0x10, 0x7e, 0x30, 0x5b, 0xac, 0x3b, 0xb0, 0x60, 0xe0, + 0x77, 0xd4, 0x08, 0xa6, 0xe1, 0x1d, 0x7c, 0x5e, 0xc0, 0xbb, 0xf9, 0x9a, + 0x7b, 0x22, 0x9d, 0xa7, 0x00, 0x09, 0x7e, 0xac, 0x46, 0x17, 0x83, 0xdc, + 0x9c, 0x26, 0x57, 0x99, 0x30, 0x39, 0x62, 0x96, 0x8f, 0xed, 0xda, 0xde, + 0xaa, 0xc5, 0xcc, 0x1b, 0x3e, 0xca, 0x43, 0x68, 0x6c, 0x57, 0x16, 0xbc, + 0xd5, 0x0e, 0x20, 0x2e, 0xfe, 0xff, 0xc2, 0x6a, 0x5d, 0x2e, 0xa0, 0x4a, + 0x6d, 0x14, 0x58, 0x87, 0x94, 0xe6, 0x39, 0x31, 0x5f, 0x7c, 0x73, 0xcb, + 0x90, 0x88, 0x6a, 0x84, 0x11, 0x96, 0x27, 0xa6, 0xed, 0xd9, 0x81, 0x46, + 0xa6, 0x7e, 0xa3, 0x72, 0x00, 0x0a, 0x52, 0x3e, 0x83, 0x88, 0x07, 0x63, + 0x77, 0x89, 0x69, 0x17, 0x0f, 0x39, 0x85, 0xd2, 0xab, 0x08, 0x45, 0x4d, + 0xd0, 0x51, 0x3a, 0xfd, 0x5d, 0x5d, 0x37, 0x64, 0x4c, 0x7e, 0x30, 0xb2, + 0x55, 0x24, 0x42, 0x9d, 0x36, 0xb0, 0x5d, 0x9c, 0x17, 0x81, 0x61, 0xf1, + 0xca, 0xf9, 0x10, 0x02, 0x24, 0xab, 0xeb, 0x0d, 0x74, 0x91, 0x8d, 0x7b, + 0x45, 0x29, 0x50, 0x39, 0x88, 0xb2, 0xa6, 0x89, 0x35, 0x25, 0x1e, 0x14, + 0x6a, 0x47, 0x23, 0x31, 0x2f, 0x5c, 0x9a, 0xfa, 0xad, 0x9a, 0x0e, 0x62, + 0x51, 0xa4, 0x2a, 0xa9, 0xc4, 0xf9, 0x34, 0x9d, 0x21, 0x18, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 01:fd:a3:eb:6e:ca:75:c8:88:43:8b:72:4b:cf:bc:91 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA + Validity + Not Before: Mar 8 12:00:00 2013 GMT + Not After : Mar 8 12:00:00 2023 GMT + Subject: C=US, O=DigiCert Inc, CN=DigiCert SHA2 Secure Server CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:dc:ae:58:90:4d:c1:c4:30:15:90:35:5b:6e:3c: + 82:15:f5:2c:5c:bd:e3:db:ff:71:43:fa:64:25:80: + d4:ee:18:a2:4d:f0:66:d0:0a:73:6e:11:98:36:17: + 64:af:37:9d:fd:fa:41:84:af:c7:af:8c:fe:1a:73: + 4d:cf:33:97:90:a2:96:87:53:83:2b:b9:a6:75:48: + 2d:1d:56:37:7b:da:31:32:1a:d7:ac:ab:06:f4:aa: + 5d:4b:b7:47:46:dd:2a:93:c3:90:2e:79:80:80:ef: + 13:04:6a:14:3b:b5:9b:92:be:c2:07:65:4e:fc:da: + fc:ff:7a:ae:dc:5c:7e:55:31:0c:e8:39:07:a4:d7: + be:2f:d3:0b:6a:d2:b1:df:5f:fe:57:74:53:3b:35: + 80:dd:ae:8e:44:98:b3:9f:0e:d3:da:e0:d7:f4:6b: + 29:ab:44:a7:4b:58:84:6d:92:4b:81:c3:da:73:8b: + 12:97:48:90:04:45:75:1a:dd:37:31:97:92:e8:cd: + 54:0d:3b:e4:c1:3f:39:5e:2e:b8:f3:5c:7e:10:8e: + 86:41:00:8d:45:66:47:b0:a1:65:ce:a0:aa:29:09: + 4e:f3:97:eb:e8:2e:ab:0f:72:a7:30:0e:fa:c7:f4: + fd:14:77:c3:a4:5b:28:57:c2:b3:f9:82:fd:b7:45: + 58:9b + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + Authority Information Access: + OCSP - URI:http://ocsp.digicert.com + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl3.digicert.com/DigiCertGlobalRootCA.crl + + Full Name: + URI:http://crl4.digicert.com/DigiCertGlobalRootCA.crl + + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: https://www.digicert.com/CPS + + X509v3 Subject Key Identifier: + 0F:80:61:1C:82:31:61:D5:2F:28:E7:8D:46:38:B4:2C:E1:C6:D9:E2 + X509v3 Authority Key Identifier: + keyid:03:DE:50:35:56:D1:4C:BB:66:F0:A3:E2:1B:1B:C3:97:B2:3D:D1:55 + + Signature Algorithm: sha256WithRSAEncryption + 23:3e:df:4b:d2:31:42:a5:b6:7e:42:5c:1a:44:cc:69:d1:68: + b4:5d:4b:e0:04:21:6c:4b:e2:6d:cc:b1:e0:97:8f:a6:53:09: + cd:aa:2a:65:e5:39:4f:1e:83:a5:6e:5c:98:a2:24:26:e6:fb: + a1:ed:93:c7:2e:02:c6:4d:4a:bf:b0:42:df:78:da:b3:a8:f9: + 6d:ff:21:85:53:36:60:4c:76:ce:ec:38:dc:d6:51:80:f0:c5: + d6:e5:d4:4d:27:64:ab:9b:c7:3e:71:fb:48:97:b8:33:6d:c9: + 13:07:ee:96:a2:1b:18:15:f6:5c:4c:40:ed:b3:c2:ec:ff:71: + c1:e3:47:ff:d4:b9:00:b4:37:42:da:20:c9:ea:6e:8a:ee:14: + 06:ae:7d:a2:59:98:88:a8:1b:6f:2d:f4:f2:c9:14:5f:26:cf: + 2c:8d:7e:ed:37:c0:a9:d5:39:b9:82:bf:19:0c:ea:34:af:00: + 21:68:f8:ad:73:e2:c9:32:da:38:25:0b:55:d3:9a:1d:f0:68: + 86:ed:2e:41:34:ef:7c:a5:50:1d:bf:3a:f9:d3:c1:08:0c:e6: + ed:1e:8a:58:25:e4:b8:77:ad:2d:6e:f5:52:dd:b4:74:8f:ab: + 49:2e:9d:3b:93:34:28:1f:78:ce:94:ea:c7:bd:d3:c9:6d:1c: + de:5c:32:f3 +-----BEGIN CERTIFICATE----- +MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaME0xCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIg +U2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANyuWJBNwcQwFZA1W248ghX1LFy949v/cUP6ZCWA1O4Yok3wZtAKc24RmDYXZK83 +nf36QYSvx6+M/hpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yrBvSqXUu3R0bd +KpPDkC55gIDvEwRqFDu1m5K+wgdlTvza/P96rtxcflUxDOg5B6TXvi/TC2rSsd9f +/ld0Uzs1gN2ujkSYs58O09rg1/RrKatEp0tYhG2SS4HD2nOLEpdIkARFdRrdNzGX +kujNVA075ME/OV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJTvOX6+guqw9ypzAO+sf0 +/RR3w6RbKFfCs/mC/bdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8C +AQAwDgYDVR0PAQH/BAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYY +aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6 +Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwN6A1 +oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RD +QS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v +d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA+AYRyCMWHVLyjnjUY4tCzh +xtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0GCSqGSIb3DQEB +CwUAA4IBAQAjPt9L0jFCpbZ+QlwaRMxp0Wi0XUvgBCFsS+JtzLHgl4+mUwnNqipl +5TlPHoOlblyYoiQm5vuh7ZPHLgLGTUq/sELfeNqzqPlt/yGFUzZgTHbO7Djc1lGA +8MXW5dRNJ2Srm8c+cftIl7gzbckTB+6WohsYFfZcTEDts8Ls/3HB40f/1LkAtDdC +2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8sjX7tN8Cp1Tm5gr8ZDOo0rwAhaPit +c+LJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopYJeS4d60tbvVS3bR0 +j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLz +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert24[] = { + 0x30, 0x82, 0x04, 0x94, 0x30, 0x82, 0x03, 0x7c, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x01, 0xfd, 0xa3, 0xeb, 0x6e, 0xca, 0x75, 0xc8, 0x88, + 0x43, 0x8b, 0x72, 0x4b, 0xcf, 0xbc, 0x91, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x61, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, + 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, + 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, + 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, + 0x63, 0x6f, 0x6d, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x17, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x47, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, + 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x33, 0x30, 0x38, 0x31, + 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x33, + 0x30, 0x38, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x4d, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44, + 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, + 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1e, 0x44, 0x69, + 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x53, 0x48, 0x41, 0x32, 0x20, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x20, 0x43, 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, 0xdc, 0xae, 0x58, 0x90, 0x4d, 0xc1, 0xc4, 0x30, 0x15, 0x90, 0x35, + 0x5b, 0x6e, 0x3c, 0x82, 0x15, 0xf5, 0x2c, 0x5c, 0xbd, 0xe3, 0xdb, 0xff, + 0x71, 0x43, 0xfa, 0x64, 0x25, 0x80, 0xd4, 0xee, 0x18, 0xa2, 0x4d, 0xf0, + 0x66, 0xd0, 0x0a, 0x73, 0x6e, 0x11, 0x98, 0x36, 0x17, 0x64, 0xaf, 0x37, + 0x9d, 0xfd, 0xfa, 0x41, 0x84, 0xaf, 0xc7, 0xaf, 0x8c, 0xfe, 0x1a, 0x73, + 0x4d, 0xcf, 0x33, 0x97, 0x90, 0xa2, 0x96, 0x87, 0x53, 0x83, 0x2b, 0xb9, + 0xa6, 0x75, 0x48, 0x2d, 0x1d, 0x56, 0x37, 0x7b, 0xda, 0x31, 0x32, 0x1a, + 0xd7, 0xac, 0xab, 0x06, 0xf4, 0xaa, 0x5d, 0x4b, 0xb7, 0x47, 0x46, 0xdd, + 0x2a, 0x93, 0xc3, 0x90, 0x2e, 0x79, 0x80, 0x80, 0xef, 0x13, 0x04, 0x6a, + 0x14, 0x3b, 0xb5, 0x9b, 0x92, 0xbe, 0xc2, 0x07, 0x65, 0x4e, 0xfc, 0xda, + 0xfc, 0xff, 0x7a, 0xae, 0xdc, 0x5c, 0x7e, 0x55, 0x31, 0x0c, 0xe8, 0x39, + 0x07, 0xa4, 0xd7, 0xbe, 0x2f, 0xd3, 0x0b, 0x6a, 0xd2, 0xb1, 0xdf, 0x5f, + 0xfe, 0x57, 0x74, 0x53, 0x3b, 0x35, 0x80, 0xdd, 0xae, 0x8e, 0x44, 0x98, + 0xb3, 0x9f, 0x0e, 0xd3, 0xda, 0xe0, 0xd7, 0xf4, 0x6b, 0x29, 0xab, 0x44, + 0xa7, 0x4b, 0x58, 0x84, 0x6d, 0x92, 0x4b, 0x81, 0xc3, 0xda, 0x73, 0x8b, + 0x12, 0x97, 0x48, 0x90, 0x04, 0x45, 0x75, 0x1a, 0xdd, 0x37, 0x31, 0x97, + 0x92, 0xe8, 0xcd, 0x54, 0x0d, 0x3b, 0xe4, 0xc1, 0x3f, 0x39, 0x5e, 0x2e, + 0xb8, 0xf3, 0x5c, 0x7e, 0x10, 0x8e, 0x86, 0x41, 0x00, 0x8d, 0x45, 0x66, + 0x47, 0xb0, 0xa1, 0x65, 0xce, 0xa0, 0xaa, 0x29, 0x09, 0x4e, 0xf3, 0x97, + 0xeb, 0xe8, 0x2e, 0xab, 0x0f, 0x72, 0xa7, 0x30, 0x0e, 0xfa, 0xc7, 0xf4, + 0xfd, 0x14, 0x77, 0xc3, 0xa4, 0x5b, 0x28, 0x57, 0xc2, 0xb3, 0xf9, 0x82, + 0xfd, 0xb7, 0x45, 0x58, 0x9b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, + 0x01, 0x5a, 0x30, 0x82, 0x01, 0x56, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, + 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, + 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, + 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, + 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, + 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, + 0x30, 0x7b, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x74, 0x30, 0x72, 0x30, + 0x37, 0xa0, 0x35, 0xa0, 0x33, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x33, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, + 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, + 0x43, 0x65, 0x72, 0x74, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x52, 0x6f, + 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x37, 0xa0, 0x35, + 0xa0, 0x33, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, + 0x72, 0x6c, 0x34, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, + 0x74, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x52, 0x6f, 0x6f, 0x74, 0x43, + 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x20, + 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, + 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, + 0x77, 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x1d, 0x06, 0x03, + 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x0f, 0x80, 0x61, 0x1c, 0x82, + 0x31, 0x61, 0xd5, 0x2f, 0x28, 0xe7, 0x8d, 0x46, 0x38, 0xb4, 0x2c, 0xe1, + 0xc6, 0xd9, 0xe2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, + 0x30, 0x16, 0x80, 0x14, 0x03, 0xde, 0x50, 0x35, 0x56, 0xd1, 0x4c, 0xbb, + 0x66, 0xf0, 0xa3, 0xe2, 0x1b, 0x1b, 0xc3, 0x97, 0xb2, 0x3d, 0xd1, 0x55, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x23, 0x3e, 0xdf, 0x4b, + 0xd2, 0x31, 0x42, 0xa5, 0xb6, 0x7e, 0x42, 0x5c, 0x1a, 0x44, 0xcc, 0x69, + 0xd1, 0x68, 0xb4, 0x5d, 0x4b, 0xe0, 0x04, 0x21, 0x6c, 0x4b, 0xe2, 0x6d, + 0xcc, 0xb1, 0xe0, 0x97, 0x8f, 0xa6, 0x53, 0x09, 0xcd, 0xaa, 0x2a, 0x65, + 0xe5, 0x39, 0x4f, 0x1e, 0x83, 0xa5, 0x6e, 0x5c, 0x98, 0xa2, 0x24, 0x26, + 0xe6, 0xfb, 0xa1, 0xed, 0x93, 0xc7, 0x2e, 0x02, 0xc6, 0x4d, 0x4a, 0xbf, + 0xb0, 0x42, 0xdf, 0x78, 0xda, 0xb3, 0xa8, 0xf9, 0x6d, 0xff, 0x21, 0x85, + 0x53, 0x36, 0x60, 0x4c, 0x76, 0xce, 0xec, 0x38, 0xdc, 0xd6, 0x51, 0x80, + 0xf0, 0xc5, 0xd6, 0xe5, 0xd4, 0x4d, 0x27, 0x64, 0xab, 0x9b, 0xc7, 0x3e, + 0x71, 0xfb, 0x48, 0x97, 0xb8, 0x33, 0x6d, 0xc9, 0x13, 0x07, 0xee, 0x96, + 0xa2, 0x1b, 0x18, 0x15, 0xf6, 0x5c, 0x4c, 0x40, 0xed, 0xb3, 0xc2, 0xec, + 0xff, 0x71, 0xc1, 0xe3, 0x47, 0xff, 0xd4, 0xb9, 0x00, 0xb4, 0x37, 0x42, + 0xda, 0x20, 0xc9, 0xea, 0x6e, 0x8a, 0xee, 0x14, 0x06, 0xae, 0x7d, 0xa2, + 0x59, 0x98, 0x88, 0xa8, 0x1b, 0x6f, 0x2d, 0xf4, 0xf2, 0xc9, 0x14, 0x5f, + 0x26, 0xcf, 0x2c, 0x8d, 0x7e, 0xed, 0x37, 0xc0, 0xa9, 0xd5, 0x39, 0xb9, + 0x82, 0xbf, 0x19, 0x0c, 0xea, 0x34, 0xaf, 0x00, 0x21, 0x68, 0xf8, 0xad, + 0x73, 0xe2, 0xc9, 0x32, 0xda, 0x38, 0x25, 0x0b, 0x55, 0xd3, 0x9a, 0x1d, + 0xf0, 0x68, 0x86, 0xed, 0x2e, 0x41, 0x34, 0xef, 0x7c, 0xa5, 0x50, 0x1d, + 0xbf, 0x3a, 0xf9, 0xd3, 0xc1, 0x08, 0x0c, 0xe6, 0xed, 0x1e, 0x8a, 0x58, + 0x25, 0xe4, 0xb8, 0x77, 0xad, 0x2d, 0x6e, 0xf5, 0x52, 0xdd, 0xb4, 0x74, + 0x8f, 0xab, 0x49, 0x2e, 0x9d, 0x3b, 0x93, 0x34, 0x28, 0x1f, 0x78, 0xce, + 0x94, 0xea, 0xc7, 0xbd, 0xd3, 0xc9, 0x6d, 0x1c, 0xde, 0x5c, 0x32, 0xf3, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 3740804 (0x391484) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=Starfield Technologies, Inc., OU=Starfield Class 2 Certification Authority + Validity + Not Before: Jan 1 07:00:00 2014 GMT + Not After : May 30 07:00:00 2031 GMT + Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Root Certificate Authority - G2 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:bd:ed:c1:03:fc:f6:8f:fc:02:b1:6f:5b:9f:48: + d9:9d:79:e2:a2:b7:03:61:56:18:c3:47:b6:d7:ca: + 3d:35:2e:89:43:f7:a1:69:9b:de:8a:1a:fd:13:20: + 9c:b4:49:77:32:29:56:fd:b9:ec:8c:dd:22:fa:72: + dc:27:61:97:ee:f6:5a:84:ec:6e:19:b9:89:2c:dc: + 84:5b:d5:74:fb:6b:5f:c5:89:a5:10:52:89:46:55: + f4:b8:75:1c:e6:7f:e4:54:ae:4b:f8:55:72:57:02: + 19:f8:17:71:59:eb:1e:28:07:74:c5:9d:48:be:6c: + b4:f4:a4:b0:f3:64:37:79:92:c0:ec:46:5e:7f:e1: + 6d:53:4c:62:af:cd:1f:0b:63:bb:3a:9d:fb:fc:79: + 00:98:61:74:cf:26:82:40:63:f3:b2:72:6a:19:0d: + 99:ca:d4:0e:75:cc:37:fb:8b:89:c1:59:f1:62:7f: + 5f:b3:5f:65:30:f8:a7:b7:4d:76:5a:1e:76:5e:34: + c0:e8:96:56:99:8a:b3:f0:7f:a4:cd:bd:dc:32:31: + 7c:91:cf:e0:5f:11:f8:6b:aa:49:5c:d1:99:94:d1: + a2:e3:63:5b:09:76:b5:56:62:e1:4b:74:1d:96:d4: + 26:d4:08:04:59:d0:98:0e:0e:e6:de:fc:c3:ec:1f: + 90:f1 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 7C:0C:32:1F:A7:D9:30:7F:C4:7D:68:A3:62:A8:A1:CE:AB:07:5B:27 + X509v3 Authority Key Identifier: + keyid:BF:5F:B7:D1:CE:DD:1F:86:F4:5B:55:AC:DC:D7:10:C2:0E:A9:88:E7 + + Authority Information Access: + OCSP - URI:http://ocsp.starfieldtech.com/ + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.starfieldtech.com/sfroot.crl + + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: https://certs.starfieldtech.com/repository/ + + Signature Algorithm: sha256WithRSAEncryption + 85:63:c1:d9:dd:b9:ff:a9:bd:a6:19:dc:bf:13:3a:11:38:22: + 54:b1:ac:05:10:fb:7c:b3:96:3f:31:8b:66:ff:88:f3:e1:bf: + fb:c7:1f:00:ff:46:6a:8b:61:32:c9:01:51:76:fb:9a:c6:fa: + 20:51:c8:46:c4:98:d7:79:a3:e3:04:72:3f:8b:4d:34:53:67: + ec:33:2c:7b:e8:94:01:28:7c:3a:34:5b:02:77:16:8d:40:25: + 33:b0:bc:6c:97:d7:05:7a:ff:8c:85:ce:6f:a0:53:00:17:6e: + 1e:6c:bd:22:d7:0a:88:37:f6:7d:eb:99:41:ef:27:cb:8c:60: + 6b:4c:01:7e:65:50:0b:4f:b8:95:9a:9a:6e:34:fd:73:3a:33: + f1:91:d5:f3:4e:2d:74:e8:ef:d3:90:35:f1:06:68:64:d4:d0: + 13:fd:52:d3:c6:6d:c1:3a:8a:31:dd:05:26:35:4a:8c:65:b8: + 52:6b:81:ec:d2:9c:b5:34:10:97:9c:3e:c6:2f:ed:8e:42:42: + 24:2e:e9:73:9a:25:f9:11:f1:f2:23:69:cb:e5:94:69:a0:d2: + dc:b0:fc:44:89:ac:17:a8:cc:d5:37:77:16:c5:80:b9:0c:8f: + 57:02:55:99:85:7b:49:f0:2e:5b:a0:c2:57:53:5d:a2:e8:a6: + 37:c3:01:fa +-----BEGIN CERTIFICATE----- +MIIEoDCCA4igAwIBAgIDORSEMA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNVBAYTAlVT +MSUwIwYDVQQKExxTdGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQL +EylTdGFyZmllbGQgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x +NDAxMDEwNzAwMDBaFw0zMTA1MzAwNzAwMDBaMIGPMQswCQYDVQQGEwJVUzEQMA4G +A1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTElMCMGA1UEChMcU3Rh +cmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UEAxMpU3RhcmZpZWxkIFJv +b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC97cED/PaP/AKxb1ufSNmdeeKitwNhVhjDR7bXyj01LolD +96Fpm96KGv0TIJy0SXcyKVb9ueyM3SL6ctwnYZfu9lqE7G4ZuYks3IRb1XT7a1/F +iaUQUolGVfS4dRzmf+RUrkv4VXJXAhn4F3FZ6x4oB3TFnUi+bLT0pLDzZDd5ksDs +Rl5/4W1TTGKvzR8LY7s6nfv8eQCYYXTPJoJAY/OycmoZDZnK1A51zDf7i4nBWfFi +f1+zX2Uw+Ke3TXZaHnZeNMDollaZirPwf6TNvdwyMXyRz+BfEfhrqklc0ZmU0aLj +Y1sJdrVWYuFLdB2W1CbUCARZ0JgODube/MPsH5DxAgMBAAGjggEpMIIBJTAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUfAwyH6fZMH/E +fWijYqihzqsHWycwHwYDVR0jBBgwFoAUv1+30c7dH4b0W1Ws3NcQwg6piOcwOgYI +KwYBBQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vb2NzcC5zdGFyZmllbGR0 +ZWNoLmNvbS8wOAYDVR0fBDEwLzAtoCugKYYnaHR0cDovL2NybC5zdGFyZmllbGR0 +ZWNoLmNvbS9zZnJvb3QuY3JsMEwGA1UdIARFMEMwQQYEVR0gADA5MDcGCCsGAQUF +BwIBFitodHRwczovL2NlcnRzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkv +MA0GCSqGSIb3DQEBCwUAA4IBAQCFY8HZ3bn/qb2mGdy/EzoROCJUsawFEPt8s5Y/ +MYtm/4jz4b/7xx8A/0Zqi2EyyQFRdvuaxvogUchGxJjXeaPjBHI/i000U2fsMyx7 +6JQBKHw6NFsCdxaNQCUzsLxsl9cFev+Mhc5voFMAF24ebL0i1wqIN/Z965lB7yfL +jGBrTAF+ZVALT7iVmppuNP1zOjPxkdXzTi106O/TkDXxBmhk1NAT/VLTxm3BOoox +3QUmNUqMZbhSa4Hs0py1NBCXnD7GL+2OQkIkLulzmiX5EfHyI2nL5ZRpoNLcsPxE +iawXqMzVN3cWxYC5DI9XAlWZhXtJ8C5boMJXU12i6KY3wwH6 +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert25[] = { + 0x30, 0x82, 0x04, 0xa0, 0x30, 0x82, 0x03, 0x88, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x03, 0x39, 0x14, 0x84, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x68, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53, + 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63, + 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49, + 0x6e, 0x63, 0x2e, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, + 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x32, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, + 0x34, 0x30, 0x31, 0x30, 0x31, 0x30, 0x37, 0x30, 0x30, 0x30, 0x30, 0x5a, + 0x17, 0x0d, 0x33, 0x31, 0x30, 0x35, 0x33, 0x30, 0x30, 0x37, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x30, 0x81, 0x8f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, 0x6f, 0x6e, + 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0a, + 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, 0x31, 0x25, + 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53, 0x74, 0x61, + 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63, 0x68, 0x6e, + 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49, 0x6e, 0x63, + 0x2e, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, + 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x52, 0x6f, + 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, + 0x20, 0x2d, 0x20, 0x47, 0x32, 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, 0xbd, 0xed, 0xc1, 0x03, 0xfc, 0xf6, 0x8f, 0xfc, 0x02, 0xb1, + 0x6f, 0x5b, 0x9f, 0x48, 0xd9, 0x9d, 0x79, 0xe2, 0xa2, 0xb7, 0x03, 0x61, + 0x56, 0x18, 0xc3, 0x47, 0xb6, 0xd7, 0xca, 0x3d, 0x35, 0x2e, 0x89, 0x43, + 0xf7, 0xa1, 0x69, 0x9b, 0xde, 0x8a, 0x1a, 0xfd, 0x13, 0x20, 0x9c, 0xb4, + 0x49, 0x77, 0x32, 0x29, 0x56, 0xfd, 0xb9, 0xec, 0x8c, 0xdd, 0x22, 0xfa, + 0x72, 0xdc, 0x27, 0x61, 0x97, 0xee, 0xf6, 0x5a, 0x84, 0xec, 0x6e, 0x19, + 0xb9, 0x89, 0x2c, 0xdc, 0x84, 0x5b, 0xd5, 0x74, 0xfb, 0x6b, 0x5f, 0xc5, + 0x89, 0xa5, 0x10, 0x52, 0x89, 0x46, 0x55, 0xf4, 0xb8, 0x75, 0x1c, 0xe6, + 0x7f, 0xe4, 0x54, 0xae, 0x4b, 0xf8, 0x55, 0x72, 0x57, 0x02, 0x19, 0xf8, + 0x17, 0x71, 0x59, 0xeb, 0x1e, 0x28, 0x07, 0x74, 0xc5, 0x9d, 0x48, 0xbe, + 0x6c, 0xb4, 0xf4, 0xa4, 0xb0, 0xf3, 0x64, 0x37, 0x79, 0x92, 0xc0, 0xec, + 0x46, 0x5e, 0x7f, 0xe1, 0x6d, 0x53, 0x4c, 0x62, 0xaf, 0xcd, 0x1f, 0x0b, + 0x63, 0xbb, 0x3a, 0x9d, 0xfb, 0xfc, 0x79, 0x00, 0x98, 0x61, 0x74, 0xcf, + 0x26, 0x82, 0x40, 0x63, 0xf3, 0xb2, 0x72, 0x6a, 0x19, 0x0d, 0x99, 0xca, + 0xd4, 0x0e, 0x75, 0xcc, 0x37, 0xfb, 0x8b, 0x89, 0xc1, 0x59, 0xf1, 0x62, + 0x7f, 0x5f, 0xb3, 0x5f, 0x65, 0x30, 0xf8, 0xa7, 0xb7, 0x4d, 0x76, 0x5a, + 0x1e, 0x76, 0x5e, 0x34, 0xc0, 0xe8, 0x96, 0x56, 0x99, 0x8a, 0xb3, 0xf0, + 0x7f, 0xa4, 0xcd, 0xbd, 0xdc, 0x32, 0x31, 0x7c, 0x91, 0xcf, 0xe0, 0x5f, + 0x11, 0xf8, 0x6b, 0xaa, 0x49, 0x5c, 0xd1, 0x99, 0x94, 0xd1, 0xa2, 0xe3, + 0x63, 0x5b, 0x09, 0x76, 0xb5, 0x56, 0x62, 0xe1, 0x4b, 0x74, 0x1d, 0x96, + 0xd4, 0x26, 0xd4, 0x08, 0x04, 0x59, 0xd0, 0x98, 0x0e, 0x0e, 0xe6, 0xde, + 0xfc, 0xc3, 0xec, 0x1f, 0x90, 0xf1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, + 0x82, 0x01, 0x29, 0x30, 0x82, 0x01, 0x25, 0x30, 0x0f, 0x06, 0x03, 0x55, + 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, + 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, + 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, + 0x16, 0x04, 0x14, 0x7c, 0x0c, 0x32, 0x1f, 0xa7, 0xd9, 0x30, 0x7f, 0xc4, + 0x7d, 0x68, 0xa3, 0x62, 0xa8, 0xa1, 0xce, 0xab, 0x07, 0x5b, 0x27, 0x30, + 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, + 0xbf, 0x5f, 0xb7, 0xd1, 0xce, 0xdd, 0x1f, 0x86, 0xf4, 0x5b, 0x55, 0xac, + 0xdc, 0xd7, 0x10, 0xc2, 0x0e, 0xa9, 0x88, 0xe7, 0x30, 0x3a, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x2e, 0x30, 0x2c, + 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, + 0x86, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, + 0x70, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74, + 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x38, 0x06, 0x03, + 0x55, 0x1d, 0x1f, 0x04, 0x31, 0x30, 0x2f, 0x30, 0x2d, 0xa0, 0x2b, 0xa0, + 0x29, 0x86, 0x27, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, + 0x6c, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74, + 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x66, 0x72, 0x6f, + 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, + 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0x06, 0x04, 0x55, 0x1d, 0x20, + 0x00, 0x30, 0x39, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x02, 0x01, 0x16, 0x2b, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, + 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x85, 0x63, 0xc1, 0xd9, + 0xdd, 0xb9, 0xff, 0xa9, 0xbd, 0xa6, 0x19, 0xdc, 0xbf, 0x13, 0x3a, 0x11, + 0x38, 0x22, 0x54, 0xb1, 0xac, 0x05, 0x10, 0xfb, 0x7c, 0xb3, 0x96, 0x3f, + 0x31, 0x8b, 0x66, 0xff, 0x88, 0xf3, 0xe1, 0xbf, 0xfb, 0xc7, 0x1f, 0x00, + 0xff, 0x46, 0x6a, 0x8b, 0x61, 0x32, 0xc9, 0x01, 0x51, 0x76, 0xfb, 0x9a, + 0xc6, 0xfa, 0x20, 0x51, 0xc8, 0x46, 0xc4, 0x98, 0xd7, 0x79, 0xa3, 0xe3, + 0x04, 0x72, 0x3f, 0x8b, 0x4d, 0x34, 0x53, 0x67, 0xec, 0x33, 0x2c, 0x7b, + 0xe8, 0x94, 0x01, 0x28, 0x7c, 0x3a, 0x34, 0x5b, 0x02, 0x77, 0x16, 0x8d, + 0x40, 0x25, 0x33, 0xb0, 0xbc, 0x6c, 0x97, 0xd7, 0x05, 0x7a, 0xff, 0x8c, + 0x85, 0xce, 0x6f, 0xa0, 0x53, 0x00, 0x17, 0x6e, 0x1e, 0x6c, 0xbd, 0x22, + 0xd7, 0x0a, 0x88, 0x37, 0xf6, 0x7d, 0xeb, 0x99, 0x41, 0xef, 0x27, 0xcb, + 0x8c, 0x60, 0x6b, 0x4c, 0x01, 0x7e, 0x65, 0x50, 0x0b, 0x4f, 0xb8, 0x95, + 0x9a, 0x9a, 0x6e, 0x34, 0xfd, 0x73, 0x3a, 0x33, 0xf1, 0x91, 0xd5, 0xf3, + 0x4e, 0x2d, 0x74, 0xe8, 0xef, 0xd3, 0x90, 0x35, 0xf1, 0x06, 0x68, 0x64, + 0xd4, 0xd0, 0x13, 0xfd, 0x52, 0xd3, 0xc6, 0x6d, 0xc1, 0x3a, 0x8a, 0x31, + 0xdd, 0x05, 0x26, 0x35, 0x4a, 0x8c, 0x65, 0xb8, 0x52, 0x6b, 0x81, 0xec, + 0xd2, 0x9c, 0xb5, 0x34, 0x10, 0x97, 0x9c, 0x3e, 0xc6, 0x2f, 0xed, 0x8e, + 0x42, 0x42, 0x24, 0x2e, 0xe9, 0x73, 0x9a, 0x25, 0xf9, 0x11, 0xf1, 0xf2, + 0x23, 0x69, 0xcb, 0xe5, 0x94, 0x69, 0xa0, 0xd2, 0xdc, 0xb0, 0xfc, 0x44, + 0x89, 0xac, 0x17, 0xa8, 0xcc, 0xd5, 0x37, 0x77, 0x16, 0xc5, 0x80, 0xb9, + 0x0c, 0x8f, 0x57, 0x02, 0x55, 0x99, 0x85, 0x7b, 0x49, 0xf0, 0x2e, 0x5b, + 0xa0, 0xc2, 0x57, 0x53, 0x5d, 0xa2, 0xe8, 0xa6, 0x37, 0xc3, 0x01, 0xfa, +}; +
diff --git a/net/quic/core/crypto/common_cert_set_3b.inc b/net/quic/core/crypto/common_cert_set_3b.inc new file mode 100644 index 0000000..7ba882c --- /dev/null +++ b/net/quic/core/crypto/common_cert_set_3b.inc
@@ -0,0 +1,5722 @@ +/* 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. + */ + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 28:1c:89:29:66:14:43:80:42:63:55:3a:32:40:ae:b3 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=GeoTrust Inc., OU=(c) 2008 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G3 + Validity + Not Before: Jun 30 00:00:00 2015 GMT + Not After : Jun 29 23:59:59 2025 GMT + Subject: C=US, O=GeoTrust Inc., CN=RapidSSL SHA256 CA - G4 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c0:9e:3a:0f:9a:b2:ba:d3:d2:dc:15:ec:d0:30: + 54:59:30:4d:40:51:ae:42:71:71:d2:8d:53:73:81: + fe:b8:e0:c4:96:c5:8e:7e:c2:f1:b7:63:4a:cf:a7: + 1e:3f:a8:e7:ce:53:a0:fa:2d:f7:d6:e6:ce:70:11: + a6:ee:e1:03:52:d2:68:de:3d:08:0d:87:fd:1c:d7: + 0b:97:62:6d:82:30:76:1b:47:3a:c4:f7:ce:ed:1d: + 7c:8c:b7:17:8e:53:80:1e:1d:0f:5d:8c:f9:90:e4: + 04:1e:02:7e:cb:b0:49:ef:da:52:25:fb:fb:67:ed: + dd:84:74:59:84:0e:f3:de:70:66:8d:e4:52:38:f7: + 53:5a:37:13:67:0b:3e:bb:a8:58:b7:2e:ed:ff:b7: + 5e:11:73:b9:77:45:52:67:46:ae:c4:dc:24:81:89: + 76:0a:ca:a1:6c:66:73:04:82:aa:f5:70:6c:5f:1b: + 9a:00:79:46:d6:7f:7a:26:17:30:cf:39:4b:2c:74: + d9:89:44:76:10:d0:ed:f7:8b:bb:89:05:75:4d:0b: + 0d:b3:da:e9:bf:f1:6a:7d:2a:11:db:1e:9f:8c:e3: + c4:06:69:e1:1d:88:45:39:d1:6e:55:d8:aa:b7:9b: + 6f:ea:f4:de:ac:17:11:92:5d:40:9b:83:7b:9a:e2: + f7:a9 + Exponent: 65537 (0x10001) + X509v3 extensions: + Authority Information Access: + OCSP - URI:http://g.symcd.com + + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Certificate Policies: + Policy: 2.23.140.1.2.1 + CPS: https://www.geotrust.com/resources/cps + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://g.symcb.com/GeoTrustPCA-G3.crl + + X509v3 Extended Key Usage: + TLS Web Server Authentication, TLS Web Client Authentication + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + F3:B5:56:0C:C4:09:B0:B4:CF:1F:AA:F9:DD:23:56:F0:77:E8:A1:F9 + X509v3 Authority Key Identifier: + keyid:C4:79:CA:8E:A1:4E:03:1D:1C:DC:6B:DB:31:5B:94:3E:3F:30:7F:2D + + Signature Algorithm: sha256WithRSAEncryption + c3:7e:d8:83:4b:04:4c:55:29:2a:4f:14:9d:9a:6e:de:90:70: + c1:a4:26:4c:88:8e:78:48:ef:bd:9c:b0:a0:f5:f0:66:fc:fe: + 59:26:e1:79:ef:c8:b7:60:64:a8:8b:47:ea:2f:e0:83:99:da: + 41:19:d7:c5:be:05:fa:f2:90:11:f0:0a:ff:6c:dc:05:b4:d8: + 06:6f:a4:6f:8d:be:20:2b:54:db:f9:a2:45:83:9a:1e:a5:21: + 89:35:1d:7c:20:5c:17:fd:04:2e:45:d8:b2:c6:f8:42:99:fc: + 54:08:4e:4b:80:5f:39:37:ba:95:4e:a6:37:0a:9e:93:5e:87: + 5b:e9:90:d6:a8:b6:65:08:8d:61:49:eb:83:20:a9:5d:1b:16: + 60:62:6b:2f:54:fb:5a:02:0d:7a:27:e2:4b:e1:05:14:c2:e4: + e9:f9:70:c0:d9:f7:34:65:0e:a2:91:4b:ac:28:f2:b7:08:0f: + 98:ca:d7:3e:70:b6:c8:0b:f1:8b:9c:51:f8:c6:10:6c:d2:53: + 4f:62:8c:11:00:3e:88:df:bf:e6:d2:cc:70:bd:ed:25:9c:fb: + dd:24:0a:bd:59:91:4a:42:03:38:12:71:32:88:76:a0:8e:7c: + bb:32:ef:88:2a:1b:d4:6a:6f:50:b9:52:67:8b:ab:30:fa:1f: + fd:e3:24:9a +-----BEGIN CERTIFICATE----- +MIIEpjCCA46gAwIBAgIQKByJKWYUQ4BCY1U6MkCuszANBgkqhkiG9w0BAQsFADCB +mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT +MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eSAtIEczMB4XDTE1MDYzMDAwMDAwMFoXDTI1MDYyOTIzNTk1OVowRzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xIDAeBgNVBAMTF1JhcGlk +U1NMIFNIQTI1NiBDQSAtIEc0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAwJ46D5qyutPS3BXs0DBUWTBNQFGuQnFx0o1Tc4H+uODElsWOfsLxt2NKz6ce +P6jnzlOg+i331ubOcBGm7uEDUtJo3j0IDYf9HNcLl2JtgjB2G0c6xPfO7R18jLcX +jlOAHh0PXYz5kOQEHgJ+y7BJ79pSJfv7Z+3dhHRZhA7z3nBmjeRSOPdTWjcTZws+ +u6hYty7t/7deEXO5d0VSZ0auxNwkgYl2CsqhbGZzBIKq9XBsXxuaAHlG1n96Jhcw +zzlLLHTZiUR2ENDt94u7iQV1TQsNs9rpv/FqfSoR2x6fjOPEBmnhHYhFOdFuVdiq +t5tv6vTerBcRkl1Am4N7muL3qQIDAQABo4IBOjCCATYwLgYIKwYBBQUHAQEEIjAg +MB4GCCsGAQUFBzABhhJodHRwOi8vZy5zeW1jZC5jb20wEgYDVR0TAQH/BAgwBgEB +/wIBADBJBgNVHSAEQjBAMD4GBmeBDAECATA0MDIGCCsGAQUFBwIBFiZodHRwczov +L3d3dy5nZW90cnVzdC5jb20vcmVzb3VyY2VzL2NwczA2BgNVHR8ELzAtMCugKaAn +hiVodHRwOi8vZy5zeW1jYi5jb20vR2VvVHJ1c3RQQ0EtRzMuY3JsMB0GA1UdJQQW +MBQGCCsGAQUFBwMBBggrBgEFBQcDAjAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FPO1VgzECbC0zx+q+d0jVvB36KH5MB8GA1UdIwQYMBaAFMR5yo6hTgMdHNxr2zFb +lD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQDDftiDSwRMVSkqTxSdmm7ekHDBpCZM +iI54SO+9nLCg9fBm/P5ZJuF578i3YGSoi0fqL+CDmdpBGdfFvgX68pAR8Ar/bNwF +tNgGb6Rvjb4gK1Tb+aJFg5oepSGJNR18IFwX/QQuRdiyxvhCmfxUCE5LgF85N7qV +TqY3Cp6TXodb6ZDWqLZlCI1hSeuDIKldGxZgYmsvVPtaAg16J+JL4QUUwuTp+XDA +2fc0ZQ6ikUusKPK3CA+Yytc+cLbIC/GLnFH4xhBs0lNPYowRAD6I37/m0sxwve0l +nPvdJAq9WZFKQgM4EnEyiHagjny7Mu+IKhvUam9QuVJni6sw+h/94ySa +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert26[] = { + 0x30, 0x82, 0x04, 0xa6, 0x30, 0x82, 0x03, 0x8e, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x28, 0x1c, 0x89, 0x29, 0x66, 0x14, 0x43, 0x80, 0x42, + 0x63, 0x55, 0x3a, 0x32, 0x40, 0xae, 0xb3, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, + 0x98, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, + 0x63, 0x2e, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, + 0x30, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x47, 0x65, + 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, + 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, + 0x79, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d, + 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x1e, 0x17, + 0x0d, 0x31, 0x35, 0x30, 0x36, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x36, 0x32, 0x39, 0x32, 0x33, + 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x47, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x52, 0x61, 0x70, 0x69, 0x64, + 0x53, 0x53, 0x4c, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43, + 0x41, 0x20, 0x2d, 0x20, 0x47, 0x34, 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, 0xc0, 0x9e, 0x3a, 0x0f, 0x9a, 0xb2, 0xba, 0xd3, 0xd2, + 0xdc, 0x15, 0xec, 0xd0, 0x30, 0x54, 0x59, 0x30, 0x4d, 0x40, 0x51, 0xae, + 0x42, 0x71, 0x71, 0xd2, 0x8d, 0x53, 0x73, 0x81, 0xfe, 0xb8, 0xe0, 0xc4, + 0x96, 0xc5, 0x8e, 0x7e, 0xc2, 0xf1, 0xb7, 0x63, 0x4a, 0xcf, 0xa7, 0x1e, + 0x3f, 0xa8, 0xe7, 0xce, 0x53, 0xa0, 0xfa, 0x2d, 0xf7, 0xd6, 0xe6, 0xce, + 0x70, 0x11, 0xa6, 0xee, 0xe1, 0x03, 0x52, 0xd2, 0x68, 0xde, 0x3d, 0x08, + 0x0d, 0x87, 0xfd, 0x1c, 0xd7, 0x0b, 0x97, 0x62, 0x6d, 0x82, 0x30, 0x76, + 0x1b, 0x47, 0x3a, 0xc4, 0xf7, 0xce, 0xed, 0x1d, 0x7c, 0x8c, 0xb7, 0x17, + 0x8e, 0x53, 0x80, 0x1e, 0x1d, 0x0f, 0x5d, 0x8c, 0xf9, 0x90, 0xe4, 0x04, + 0x1e, 0x02, 0x7e, 0xcb, 0xb0, 0x49, 0xef, 0xda, 0x52, 0x25, 0xfb, 0xfb, + 0x67, 0xed, 0xdd, 0x84, 0x74, 0x59, 0x84, 0x0e, 0xf3, 0xde, 0x70, 0x66, + 0x8d, 0xe4, 0x52, 0x38, 0xf7, 0x53, 0x5a, 0x37, 0x13, 0x67, 0x0b, 0x3e, + 0xbb, 0xa8, 0x58, 0xb7, 0x2e, 0xed, 0xff, 0xb7, 0x5e, 0x11, 0x73, 0xb9, + 0x77, 0x45, 0x52, 0x67, 0x46, 0xae, 0xc4, 0xdc, 0x24, 0x81, 0x89, 0x76, + 0x0a, 0xca, 0xa1, 0x6c, 0x66, 0x73, 0x04, 0x82, 0xaa, 0xf5, 0x70, 0x6c, + 0x5f, 0x1b, 0x9a, 0x00, 0x79, 0x46, 0xd6, 0x7f, 0x7a, 0x26, 0x17, 0x30, + 0xcf, 0x39, 0x4b, 0x2c, 0x74, 0xd9, 0x89, 0x44, 0x76, 0x10, 0xd0, 0xed, + 0xf7, 0x8b, 0xbb, 0x89, 0x05, 0x75, 0x4d, 0x0b, 0x0d, 0xb3, 0xda, 0xe9, + 0xbf, 0xf1, 0x6a, 0x7d, 0x2a, 0x11, 0xdb, 0x1e, 0x9f, 0x8c, 0xe3, 0xc4, + 0x06, 0x69, 0xe1, 0x1d, 0x88, 0x45, 0x39, 0xd1, 0x6e, 0x55, 0xd8, 0xaa, + 0xb7, 0x9b, 0x6f, 0xea, 0xf4, 0xde, 0xac, 0x17, 0x11, 0x92, 0x5d, 0x40, + 0x9b, 0x83, 0x7b, 0x9a, 0xe2, 0xf7, 0xa9, 0x02, 0x03, 0x01, 0x00, 0x01, + 0xa3, 0x82, 0x01, 0x3a, 0x30, 0x82, 0x01, 0x36, 0x30, 0x2e, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x22, 0x30, 0x20, + 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, + 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73, + 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03, + 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, + 0xff, 0x02, 0x01, 0x00, 0x30, 0x49, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, + 0x42, 0x30, 0x40, 0x30, 0x3e, 0x06, 0x06, 0x67, 0x81, 0x0c, 0x01, 0x02, + 0x01, 0x30, 0x34, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x02, 0x01, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x36, 0x06, 0x03, 0x55, + 0x1d, 0x1f, 0x04, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27, + 0x86, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73, + 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x47, 0x65, 0x6f, + 0x54, 0x72, 0x75, 0x73, 0x74, 0x50, 0x43, 0x41, 0x2d, 0x47, 0x33, 0x2e, + 0x63, 0x72, 0x6c, 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, 0x0e, + 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, + 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, + 0x14, 0xf3, 0xb5, 0x56, 0x0c, 0xc4, 0x09, 0xb0, 0xb4, 0xcf, 0x1f, 0xaa, + 0xf9, 0xdd, 0x23, 0x56, 0xf0, 0x77, 0xe8, 0xa1, 0xf9, 0x30, 0x1f, 0x06, + 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xc4, 0x79, + 0xca, 0x8e, 0xa1, 0x4e, 0x03, 0x1d, 0x1c, 0xdc, 0x6b, 0xdb, 0x31, 0x5b, + 0x94, 0x3e, 0x3f, 0x30, 0x7f, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, + 0x01, 0x00, 0xc3, 0x7e, 0xd8, 0x83, 0x4b, 0x04, 0x4c, 0x55, 0x29, 0x2a, + 0x4f, 0x14, 0x9d, 0x9a, 0x6e, 0xde, 0x90, 0x70, 0xc1, 0xa4, 0x26, 0x4c, + 0x88, 0x8e, 0x78, 0x48, 0xef, 0xbd, 0x9c, 0xb0, 0xa0, 0xf5, 0xf0, 0x66, + 0xfc, 0xfe, 0x59, 0x26, 0xe1, 0x79, 0xef, 0xc8, 0xb7, 0x60, 0x64, 0xa8, + 0x8b, 0x47, 0xea, 0x2f, 0xe0, 0x83, 0x99, 0xda, 0x41, 0x19, 0xd7, 0xc5, + 0xbe, 0x05, 0xfa, 0xf2, 0x90, 0x11, 0xf0, 0x0a, 0xff, 0x6c, 0xdc, 0x05, + 0xb4, 0xd8, 0x06, 0x6f, 0xa4, 0x6f, 0x8d, 0xbe, 0x20, 0x2b, 0x54, 0xdb, + 0xf9, 0xa2, 0x45, 0x83, 0x9a, 0x1e, 0xa5, 0x21, 0x89, 0x35, 0x1d, 0x7c, + 0x20, 0x5c, 0x17, 0xfd, 0x04, 0x2e, 0x45, 0xd8, 0xb2, 0xc6, 0xf8, 0x42, + 0x99, 0xfc, 0x54, 0x08, 0x4e, 0x4b, 0x80, 0x5f, 0x39, 0x37, 0xba, 0x95, + 0x4e, 0xa6, 0x37, 0x0a, 0x9e, 0x93, 0x5e, 0x87, 0x5b, 0xe9, 0x90, 0xd6, + 0xa8, 0xb6, 0x65, 0x08, 0x8d, 0x61, 0x49, 0xeb, 0x83, 0x20, 0xa9, 0x5d, + 0x1b, 0x16, 0x60, 0x62, 0x6b, 0x2f, 0x54, 0xfb, 0x5a, 0x02, 0x0d, 0x7a, + 0x27, 0xe2, 0x4b, 0xe1, 0x05, 0x14, 0xc2, 0xe4, 0xe9, 0xf9, 0x70, 0xc0, + 0xd9, 0xf7, 0x34, 0x65, 0x0e, 0xa2, 0x91, 0x4b, 0xac, 0x28, 0xf2, 0xb7, + 0x08, 0x0f, 0x98, 0xca, 0xd7, 0x3e, 0x70, 0xb6, 0xc8, 0x0b, 0xf1, 0x8b, + 0x9c, 0x51, 0xf8, 0xc6, 0x10, 0x6c, 0xd2, 0x53, 0x4f, 0x62, 0x8c, 0x11, + 0x00, 0x3e, 0x88, 0xdf, 0xbf, 0xe6, 0xd2, 0xcc, 0x70, 0xbd, 0xed, 0x25, + 0x9c, 0xfb, 0xdd, 0x24, 0x0a, 0xbd, 0x59, 0x91, 0x4a, 0x42, 0x03, 0x38, + 0x12, 0x71, 0x32, 0x88, 0x76, 0xa0, 0x8e, 0x7c, 0xbb, 0x32, 0xef, 0x88, + 0x2a, 0x1b, 0xd4, 0x6a, 0x6f, 0x50, 0xb9, 0x52, 0x67, 0x8b, 0xab, 0x30, + 0xfa, 0x1f, 0xfd, 0xe3, 0x24, 0x9a, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + e4:05:47:83:0e:0c:64:52:97:6f:7a:35:49:c0:dd:48 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=PL, O=Unizeto Technologies S.A., OU=Certum Certification Authority, CN=Certum Trusted Network CA + Validity + Not Before: Jan 21 12:00:00 2015 GMT + Not After : Jan 18 12:00:00 2025 GMT + Subject: C=RU, O=Yandex LLC, OU=Yandex Certification Authority, CN=Yandex CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:a6:05:24:76:61:b9:9e:42:60:22:63:85:59:e5: + 9d:88:0d:df:ef:21:64:5a:26:94:71:3a:a4:7f:2b: + 53:c3:ac:7b:ba:95:42:6d:6a:5b:d6:7e:78:0c:67: + 40:98:2f:6a:2d:d0:b7:18:3a:7e:99:60:01:e5:27: + bf:ff:49:f5:cd:c4:58:c3:4c:e1:70:d5:fd:08:a8: + 79:95:76:1c:0e:05:41:fa:bd:80:38:2a:87:4f:c1: + 67:42:aa:17:a6:ee:a7:8c:8e:ef:2d:7f:7a:1d:05: + 17:8f:7e:3b:92:35:f5:68:ed:93:03:55:23:4f:4b: + a2:00:86:65:91:0f:eb:f6:3c:d5:db:6d:0e:ed:e8: + 7c:3a:c8:ba:b7:53:c1:a4:d8:40:02:e5:b5:a2:ca: + bf:da:9c:94:0d:fc:c5:1c:2a:59:88:62:57:93:2e: + 11:f0:38:2c:7a:81:2a:f2:25:15:17:35:70:2c:4b: + f7:23:4c:82:ef:33:9f:c2:9a:0b:a3:e2:5d:6b:38: + 77:f9:60:33:cf:2e:7b:56:b7:13:93:1f:34:97:71: + 99:76:02:46:35:14:7c:dc:ca:48:8a:0a:72:4b:78: + 6d:82:34:96:13:45:cf:02:2f:50:13:39:43:89:c0: + e1:74:d7:28:71:21:e5:aa:97:0e:ee:46:ec:93:f7: + 23:7d + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + 37:5C:E3:19:E0:B2:8E:A1:A8:4E:D2:CF:AB:D0:DC:E3:0B:5C:35:4D + X509v3 Authority Key Identifier: + keyid:08:76:CD:CB:07:FF:24:F6:C5:CD:ED:BB:90:BC:E2:84:37:46:75:F7 + + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.certum.pl/ctnca.crl + + Authority Information Access: + OCSP - URI:http://subca.ocsp-certum.com + CA Issuers - URI:http://repository.certum.pl/ctnca.cer + + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: http://www.certum.pl/CPS + + Signature Algorithm: sha256WithRSAEncryption + 02:5e:8e:7b:e0:66:a1:c6:ab:8b:18:1f:0e:b9:c4:cd:71:db: + 44:5c:03:7d:65:ea:b8:47:b5:1e:ce:24:70:a0:7f:d3:df:66: + 4b:8c:90:e2:a5:ed:9b:94:36:b4:a8:be:f0:74:8c:26:92:75: + 9d:56:50:9e:ad:d0:1a:a0:df:a4:14:56:10:75:93:7a:c1:f4: + 53:a0:76:74:2c:72:ba:b5:d1:c9:e2:dc:46:86:3f:1d:f6:33: + 87:59:ec:9c:dc:2d:1e:4d:43:1a:ce:ba:d9:87:7e:e2:47:45: + 72:3d:28:03:c9:0a:4d:e0:57:a3:5e:6e:7e:cc:5a:c8:c4:78: + 01:57:68:7a:38:3b:53:36:e7:92:6d:8a:2c:2f:d7:8b:b6:34: + a8:d1:b6:f8:5e:3b:ab:ed:a5:8f:39:6f:45:ad:cb:63:ed:6a: + 64:c9:10:a7:03:08:12:53:b1:1c:af:ca:f7:53:fc:d8:29:4b: + 1b:fb:38:cd:c0:63:ff:5f:e4:b9:8d:5e:aa:2b:d2:c3:22:35: + 31:f6:30:0e:53:32:f4:93:c5:43:cb:c8:f0:15:56:8f:00:19: + 87:ca:78:22:8d:a0:2e:db:2f:a0:c3:7e:29:5d:91:25:84:1d: + 1d:39:ab:1b:c5:d6:91:fe:69:0e:46:80:bc:45:7b:35:53:2a: + df:00:b6:77 +-----BEGIN CERTIFICATE----- +MIIEqDCCA5CgAwIBAgIRAOQFR4MODGRSl296NUnA3UgwDQYJKoZIhvcNAQELBQAw +fjELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEiMCAG +A1UEAxMZQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQTAeFw0xNTAxMjExMjAwMDBa +Fw0yNTAxMTgxMjAwMDBaMF8xCzAJBgNVBAYTAlJVMRMwEQYDVQQKEwpZYW5kZXgg +TExDMScwJQYDVQQLEx5ZYW5kZXggQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxEjAQ +BgNVBAMTCVlhbmRleCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AKYFJHZhuZ5CYCJjhVnlnYgN3+8hZFomlHE6pH8rU8Ose7qVQm1qW9Z+eAxnQJgv +ai3Qtxg6fplgAeUnv/9J9c3EWMNM4XDV/QioeZV2HA4FQfq9gDgqh0/BZ0KqF6bu +p4yO7y1/eh0FF49+O5I19WjtkwNVI09LogCGZZEP6/Y81dttDu3ofDrIurdTwaTY +QALltaLKv9qclA38xRwqWYhiV5MuEfA4LHqBKvIlFRc1cCxL9yNMgu8zn8KaC6Pi +XWs4d/lgM88ue1a3E5MfNJdxmXYCRjUUfNzKSIoKckt4bYI0lhNFzwIvUBM5Q4nA +4XTXKHEh5aqXDu5G7JP3I30CAwEAAaOCAT4wggE6MA8GA1UdEwEB/wQFMAMBAf8w +HQYDVR0OBBYEFDdc4xngso6hqE7Sz6vQ3OMLXDVNMB8GA1UdIwQYMBaAFAh2zcsH +/yT2xc3tu5C84oQ3RnX3MA4GA1UdDwEB/wQEAwIBBjAvBgNVHR8EKDAmMCSgIqAg +hh5odHRwOi8vY3JsLmNlcnR1bS5wbC9jdG5jYS5jcmwwawYIKwYBBQUHAQEEXzBd +MCgGCCsGAQUFBzABhhxodHRwOi8vc3ViY2Eub2NzcC1jZXJ0dW0uY29tMDEGCCsG +AQUFBzAChiVodHRwOi8vcmVwb3NpdG9yeS5jZXJ0dW0ucGwvY3RuY2EuY2VyMDkG +A1UdIAQyMDAwLgYEVR0gADAmMCQGCCsGAQUFBwIBFhhodHRwOi8vd3d3LmNlcnR1 +bS5wbC9DUFMwDQYJKoZIhvcNAQELBQADggEBAAJejnvgZqHGq4sYHw65xM1x20Rc +A31l6rhHtR7OJHCgf9PfZkuMkOKl7ZuUNrSovvB0jCaSdZ1WUJ6t0Bqg36QUVhB1 +k3rB9FOgdnQscrq10cni3EaGPx32M4dZ7JzcLR5NQxrOutmHfuJHRXI9KAPJCk3g +V6Nebn7MWsjEeAFXaHo4O1M255Jtiiwv14u2NKjRtvheO6vtpY85b0Wty2PtamTJ +EKcDCBJTsRyvyvdT/NgpSxv7OM3AY/9f5LmNXqor0sMiNTH2MA5TMvSTxUPLyPAV +Vo8AGYfKeCKNoC7bL6DDfildkSWEHR05qxvF1pH+aQ5GgLxFezVTKt8Atnc= +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert27[] = { + 0x30, 0x82, 0x04, 0xa8, 0x30, 0x82, 0x03, 0x90, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x11, 0x00, 0xe4, 0x05, 0x47, 0x83, 0x0e, 0x0c, 0x64, 0x52, + 0x97, 0x6f, 0x7a, 0x35, 0x49, 0xc0, 0xdd, 0x48, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, + 0x7e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x50, 0x4c, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x19, 0x55, 0x6e, 0x69, 0x7a, 0x65, 0x74, 0x6f, 0x20, 0x54, 0x65, 0x63, + 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x20, 0x53, 0x2e, + 0x41, 0x2e, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, + 0x1e, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6d, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x22, 0x30, 0x20, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6d, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, + 0x35, 0x30, 0x31, 0x32, 0x31, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, + 0x17, 0x0d, 0x32, 0x35, 0x30, 0x31, 0x31, 0x38, 0x31, 0x32, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x30, 0x5f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x52, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x59, 0x61, 0x6e, 0x64, 0x65, 0x78, 0x20, + 0x4c, 0x4c, 0x43, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x13, 0x1e, 0x59, 0x61, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x59, 0x61, 0x6e, 0x64, 0x65, + 0x78, 0x20, 0x43, 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, 0xa6, 0x05, 0x24, 0x76, 0x61, 0xb9, 0x9e, 0x42, 0x60, 0x22, 0x63, + 0x85, 0x59, 0xe5, 0x9d, 0x88, 0x0d, 0xdf, 0xef, 0x21, 0x64, 0x5a, 0x26, + 0x94, 0x71, 0x3a, 0xa4, 0x7f, 0x2b, 0x53, 0xc3, 0xac, 0x7b, 0xba, 0x95, + 0x42, 0x6d, 0x6a, 0x5b, 0xd6, 0x7e, 0x78, 0x0c, 0x67, 0x40, 0x98, 0x2f, + 0x6a, 0x2d, 0xd0, 0xb7, 0x18, 0x3a, 0x7e, 0x99, 0x60, 0x01, 0xe5, 0x27, + 0xbf, 0xff, 0x49, 0xf5, 0xcd, 0xc4, 0x58, 0xc3, 0x4c, 0xe1, 0x70, 0xd5, + 0xfd, 0x08, 0xa8, 0x79, 0x95, 0x76, 0x1c, 0x0e, 0x05, 0x41, 0xfa, 0xbd, + 0x80, 0x38, 0x2a, 0x87, 0x4f, 0xc1, 0x67, 0x42, 0xaa, 0x17, 0xa6, 0xee, + 0xa7, 0x8c, 0x8e, 0xef, 0x2d, 0x7f, 0x7a, 0x1d, 0x05, 0x17, 0x8f, 0x7e, + 0x3b, 0x92, 0x35, 0xf5, 0x68, 0xed, 0x93, 0x03, 0x55, 0x23, 0x4f, 0x4b, + 0xa2, 0x00, 0x86, 0x65, 0x91, 0x0f, 0xeb, 0xf6, 0x3c, 0xd5, 0xdb, 0x6d, + 0x0e, 0xed, 0xe8, 0x7c, 0x3a, 0xc8, 0xba, 0xb7, 0x53, 0xc1, 0xa4, 0xd8, + 0x40, 0x02, 0xe5, 0xb5, 0xa2, 0xca, 0xbf, 0xda, 0x9c, 0x94, 0x0d, 0xfc, + 0xc5, 0x1c, 0x2a, 0x59, 0x88, 0x62, 0x57, 0x93, 0x2e, 0x11, 0xf0, 0x38, + 0x2c, 0x7a, 0x81, 0x2a, 0xf2, 0x25, 0x15, 0x17, 0x35, 0x70, 0x2c, 0x4b, + 0xf7, 0x23, 0x4c, 0x82, 0xef, 0x33, 0x9f, 0xc2, 0x9a, 0x0b, 0xa3, 0xe2, + 0x5d, 0x6b, 0x38, 0x77, 0xf9, 0x60, 0x33, 0xcf, 0x2e, 0x7b, 0x56, 0xb7, + 0x13, 0x93, 0x1f, 0x34, 0x97, 0x71, 0x99, 0x76, 0x02, 0x46, 0x35, 0x14, + 0x7c, 0xdc, 0xca, 0x48, 0x8a, 0x0a, 0x72, 0x4b, 0x78, 0x6d, 0x82, 0x34, + 0x96, 0x13, 0x45, 0xcf, 0x02, 0x2f, 0x50, 0x13, 0x39, 0x43, 0x89, 0xc0, + 0xe1, 0x74, 0xd7, 0x28, 0x71, 0x21, 0xe5, 0xaa, 0x97, 0x0e, 0xee, 0x46, + 0xec, 0x93, 0xf7, 0x23, 0x7d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, + 0x01, 0x3e, 0x30, 0x82, 0x01, 0x3a, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, + 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, + 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x37, 0x5c, + 0xe3, 0x19, 0xe0, 0xb2, 0x8e, 0xa1, 0xa8, 0x4e, 0xd2, 0xcf, 0xab, 0xd0, + 0xdc, 0xe3, 0x0b, 0x5c, 0x35, 0x4d, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, + 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x08, 0x76, 0xcd, 0xcb, 0x07, + 0xff, 0x24, 0xf6, 0xc5, 0xcd, 0xed, 0xbb, 0x90, 0xbc, 0xe2, 0x84, 0x37, + 0x46, 0x75, 0xf7, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, + 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x2f, 0x06, 0x03, 0x55, + 0x1d, 0x1f, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0xa0, 0x22, 0xa0, 0x20, + 0x86, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, + 0x2e, 0x63, 0x65, 0x72, 0x74, 0x75, 0x6d, 0x2e, 0x70, 0x6c, 0x2f, 0x63, + 0x74, 0x6e, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x6b, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x5f, 0x30, 0x5d, + 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, + 0x86, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x75, 0x62, + 0x63, 0x61, 0x2e, 0x6f, 0x63, 0x73, 0x70, 0x2d, 0x63, 0x65, 0x72, 0x74, + 0x75, 0x6d, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x31, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x25, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x2e, 0x63, 0x65, 0x72, 0x74, 0x75, 0x6d, 0x2e, 0x70, 0x6c, 0x2f, + 0x63, 0x74, 0x6e, 0x63, 0x61, 0x2e, 0x63, 0x65, 0x72, 0x30, 0x39, 0x06, + 0x03, 0x55, 0x1d, 0x20, 0x04, 0x32, 0x30, 0x30, 0x30, 0x2e, 0x06, 0x04, + 0x55, 0x1d, 0x20, 0x00, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x18, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x63, 0x65, 0x72, 0x74, 0x75, + 0x6d, 0x2e, 0x70, 0x6c, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x01, 0x00, 0x02, 0x5e, 0x8e, 0x7b, 0xe0, 0x66, 0xa1, 0xc6, + 0xab, 0x8b, 0x18, 0x1f, 0x0e, 0xb9, 0xc4, 0xcd, 0x71, 0xdb, 0x44, 0x5c, + 0x03, 0x7d, 0x65, 0xea, 0xb8, 0x47, 0xb5, 0x1e, 0xce, 0x24, 0x70, 0xa0, + 0x7f, 0xd3, 0xdf, 0x66, 0x4b, 0x8c, 0x90, 0xe2, 0xa5, 0xed, 0x9b, 0x94, + 0x36, 0xb4, 0xa8, 0xbe, 0xf0, 0x74, 0x8c, 0x26, 0x92, 0x75, 0x9d, 0x56, + 0x50, 0x9e, 0xad, 0xd0, 0x1a, 0xa0, 0xdf, 0xa4, 0x14, 0x56, 0x10, 0x75, + 0x93, 0x7a, 0xc1, 0xf4, 0x53, 0xa0, 0x76, 0x74, 0x2c, 0x72, 0xba, 0xb5, + 0xd1, 0xc9, 0xe2, 0xdc, 0x46, 0x86, 0x3f, 0x1d, 0xf6, 0x33, 0x87, 0x59, + 0xec, 0x9c, 0xdc, 0x2d, 0x1e, 0x4d, 0x43, 0x1a, 0xce, 0xba, 0xd9, 0x87, + 0x7e, 0xe2, 0x47, 0x45, 0x72, 0x3d, 0x28, 0x03, 0xc9, 0x0a, 0x4d, 0xe0, + 0x57, 0xa3, 0x5e, 0x6e, 0x7e, 0xcc, 0x5a, 0xc8, 0xc4, 0x78, 0x01, 0x57, + 0x68, 0x7a, 0x38, 0x3b, 0x53, 0x36, 0xe7, 0x92, 0x6d, 0x8a, 0x2c, 0x2f, + 0xd7, 0x8b, 0xb6, 0x34, 0xa8, 0xd1, 0xb6, 0xf8, 0x5e, 0x3b, 0xab, 0xed, + 0xa5, 0x8f, 0x39, 0x6f, 0x45, 0xad, 0xcb, 0x63, 0xed, 0x6a, 0x64, 0xc9, + 0x10, 0xa7, 0x03, 0x08, 0x12, 0x53, 0xb1, 0x1c, 0xaf, 0xca, 0xf7, 0x53, + 0xfc, 0xd8, 0x29, 0x4b, 0x1b, 0xfb, 0x38, 0xcd, 0xc0, 0x63, 0xff, 0x5f, + 0xe4, 0xb9, 0x8d, 0x5e, 0xaa, 0x2b, 0xd2, 0xc3, 0x22, 0x35, 0x31, 0xf6, + 0x30, 0x0e, 0x53, 0x32, 0xf4, 0x93, 0xc5, 0x43, 0xcb, 0xc8, 0xf0, 0x15, + 0x56, 0x8f, 0x00, 0x19, 0x87, 0xca, 0x78, 0x22, 0x8d, 0xa0, 0x2e, 0xdb, + 0x2f, 0xa0, 0xc3, 0x7e, 0x29, 0x5d, 0x91, 0x25, 0x84, 0x1d, 0x1d, 0x39, + 0xab, 0x1b, 0xc5, 0xd6, 0x91, 0xfe, 0x69, 0x0e, 0x46, 0x80, 0xbc, 0x45, + 0x7b, 0x35, 0x53, 0x2a, 0xdf, 0x00, 0xb6, 0x77, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 5d:72:fb:33:76:20:f6:4c:72:80:db:e9:12:81:ff:6a + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA + Validity + Not Before: Oct 31 00:00:00 2013 GMT + Not After : Oct 30 23:59:59 2023 GMT + Subject: C=US, O=thawte, Inc., CN=thawte EV SSL CA - G3 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c4:dd:da:94:1e:32:b2:2e:a0:83:c0:a6:7d:5f: + 65:2d:fd:27:b8:73:0e:f8:0b:a9:d4:56:26:69:98: + 67:35:39:64:58:ce:82:6f:98:94:d1:8f:e0:90:d6: + ed:55:4b:98:4b:d7:10:59:34:02:1b:e7:51:31:51: + c4:38:c2:bc:db:03:5c:ca:e1:7c:dc:4f:59:97:ea: + 07:7f:0f:85:3e:92:ea:aa:a7:d9:be:01:41:e4:62: + 56:47:36:bd:57:91:e6:21:d3:f8:41:0b:d8:ba:e8: + ed:81:ad:70:c0:8b:6e:f3:89:6e:27:9e:a6:a6:73: + 59:bb:71:00:d4:4f:4b:48:e9:d5:c9:27:36:9c:7c: + 1c:02:aa:ac:bd:3b:d1:53:83:6a:1f:e6:08:47:33: + a7:b1:9f:02:be:9b:47:ed:33:04:dc:1c:80:27:d1: + 4a:33:a0:8c:eb:01:47:a1:32:90:64:7b:c4:e0:84: + c9:32:e9:dd:34:1f:8a:68:67:f3:ad:10:63:eb:ee: + 8a:9a:b1:2a:1b:26:74:a1:2a:b0:8f:fe:52:98:46: + 97:cf:a3:56:1c:6f:6e:99:97:8d:26:0e:a9:ec:c2: + 53:70:fc:7a:a5:19:49:bd:b5:17:82:55:de:97:e0: + 5d:62:84:81:f0:70:a8:34:53:4f:14:fd:3d:5d:3d: + 6f:b9 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + Authority Information Access: + OCSP - URI:http://t2.symcb.com + + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: https://www.thawte.com/cps + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://t1.symcb.com/ThawtePCA.crl + + X509v3 Subject Alternative Name: + DirName:/CN=SymantecPKI-1-536 + X509v3 Subject Key Identifier: + F0:70:51:DA:D3:2A:91:4F:52:77:D7:86:77:74:0F:CE:71:1A:6C:22 + X509v3 Authority Key Identifier: + keyid:7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50 + + Signature Algorithm: sha256WithRSAEncryption + a1:2e:94:3e:9b:16:f4:58:1a:6f:c1:fa:c1:7e:43:93:b2:c3: + f7:89:eb:13:62:5d:dd:cc:61:13:2b:1d:4e:88:79:11:62:14: + 37:30:46:ff:89:62:10:85:2a:87:1e:f8:e2:af:fe:93:02:93: + ca:f2:e9:46:03:6b:a1:1a:ac:d5:f0:80:1b:98:6f:b8:3a:50: + f8:54:71:06:03:e7:84:cc:8e:61:d2:5f:4d:0c:97:02:65:b5: + 8c:26:bc:05:98:f4:dc:c6:af:e4:57:7f:e3:dc:a1:d7:27:47: + 2a:e0:2c:3f:09:74:dc:5a:e5:b5:7c:fa:82:9a:15:fa:74:2b: + 84:2e:6b:ac:ef:35:a6:30:fa:47:4a:aa:36:44:f6:5a:91:07: + d3:e4:4e:97:3f:a6:53:d8:29:33:32:6f:8b:3d:b5:a5:0d:e5: + e4:8a:e8:f5:c0:fa:af:d8:37:28:27:c3:ed:34:31:d9:7c:a6: + af:4d:12:4f:d0:2b:92:9c:69:95:f2:28:a6:fe:a8:c6:e0:2c: + 4d:36:eb:11:34:d6:e1:81:99:9d:41:f2:e7:c5:57:05:0e:19: + ca:af:42:39:1f:a7:27:5e:e0:0a:17:b8:ae:47:ab:92:f1:8a: + 04:df:30:e0:bb:4f:8a:f9:1b:88:4f:03:b4:25:7a:78:de:2e: + 7d:29:d1:31 +-----BEGIN CERTIFICATE----- +MIIErzCCA5egAwIBAgIQXXL7M3Yg9kxygNvpEoH/ajANBgkqhkiG9w0BAQsFADCB +qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV +BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTMxMDMxMDAwMDAwWhcNMjMx +MDMwMjM1OTU5WjBEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMu +MR4wHAYDVQQDExV0aGF3dGUgRVYgU1NMIENBIC0gRzMwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDE3dqUHjKyLqCDwKZ9X2Ut/Se4cw74C6nUViZpmGc1 +OWRYzoJvmJTRj+CQ1u1VS5hL1xBZNAIb51ExUcQ4wrzbA1zK4XzcT1mX6gd/D4U+ +kuqqp9m+AUHkYlZHNr1XkeYh0/hBC9i66O2BrXDAi27ziW4nnqamc1m7cQDUT0tI +6dXJJzacfBwCqqy9O9FTg2of5ghHM6exnwK+m0ftMwTcHIAn0UozoIzrAUehMpBk +e8TghMky6d00H4poZ/OtEGPr7oqasSobJnShKrCP/lKYRpfPo1Ycb26Zl40mDqns +wlNw/HqlGUm9tReCVd6X4F1ihIHwcKg0U08U/T1dPW+5AgMBAAGjggE1MIIBMTAS +BgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAvBggrBgEFBQcBAQQj +MCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly90Mi5zeW1jYi5jb20wOwYDVR0gBDQwMjAw +BgRVHSAAMCgwJgYIKwYBBQUHAgEWGmh0dHBzOi8vd3d3LnRoYXd0ZS5jb20vY3Bz +MDIGA1UdHwQrMCkwJ6AloCOGIWh0dHA6Ly90MS5zeW1jYi5jb20vVGhhd3RlUENB +LmNybDApBgNVHREEIjAgpB4wHDEaMBgGA1UEAxMRU3ltYW50ZWNQS0ktMS01MzYw +HQYDVR0OBBYEFPBwUdrTKpFPUnfXhnd0D85xGmwiMB8GA1UdIwQYMBaAFHtbRc+v +zst6/TGSGmq280brV0hQMA0GCSqGSIb3DQEBCwUAA4IBAQChLpQ+mxb0WBpvwfrB +fkOTssP3iesTYl3dzGETKx1OiHkRYhQ3MEb/iWIQhSqHHvjir/6TApPK8ulGA2uh +GqzV8IAbmG+4OlD4VHEGA+eEzI5h0l9NDJcCZbWMJrwFmPTcxq/kV3/j3KHXJ0cq +4Cw/CXTcWuW1fPqCmhX6dCuELmus7zWmMPpHSqo2RPZakQfT5E6XP6ZT2CkzMm+L +PbWlDeXkiuj1wPqv2DcoJ8PtNDHZfKavTRJP0CuSnGmV8iim/qjG4CxNNusRNNbh +gZmdQfLnxVcFDhnKr0I5H6cnXuAKF7iuR6uS8YoE3zDgu0+K+RuITwO0JXp43i59 +KdEx +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert28[] = { + 0x30, 0x82, 0x04, 0xaf, 0x30, 0x82, 0x03, 0x97, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x5d, 0x72, 0xfb, 0x33, 0x76, 0x20, 0xf6, 0x4c, 0x72, + 0x80, 0xdb, 0xe9, 0x12, 0x81, 0xff, 0x6a, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, + 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, + 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44, + 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06, + 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, + 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, + 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, + 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, + 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x33, 0x31, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x31, + 0x30, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x44, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, + 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x15, 0x74, + 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x45, 0x56, 0x20, 0x53, 0x53, 0x4c, + 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 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, 0xc4, 0xdd, 0xda, 0x94, 0x1e, 0x32, 0xb2, + 0x2e, 0xa0, 0x83, 0xc0, 0xa6, 0x7d, 0x5f, 0x65, 0x2d, 0xfd, 0x27, 0xb8, + 0x73, 0x0e, 0xf8, 0x0b, 0xa9, 0xd4, 0x56, 0x26, 0x69, 0x98, 0x67, 0x35, + 0x39, 0x64, 0x58, 0xce, 0x82, 0x6f, 0x98, 0x94, 0xd1, 0x8f, 0xe0, 0x90, + 0xd6, 0xed, 0x55, 0x4b, 0x98, 0x4b, 0xd7, 0x10, 0x59, 0x34, 0x02, 0x1b, + 0xe7, 0x51, 0x31, 0x51, 0xc4, 0x38, 0xc2, 0xbc, 0xdb, 0x03, 0x5c, 0xca, + 0xe1, 0x7c, 0xdc, 0x4f, 0x59, 0x97, 0xea, 0x07, 0x7f, 0x0f, 0x85, 0x3e, + 0x92, 0xea, 0xaa, 0xa7, 0xd9, 0xbe, 0x01, 0x41, 0xe4, 0x62, 0x56, 0x47, + 0x36, 0xbd, 0x57, 0x91, 0xe6, 0x21, 0xd3, 0xf8, 0x41, 0x0b, 0xd8, 0xba, + 0xe8, 0xed, 0x81, 0xad, 0x70, 0xc0, 0x8b, 0x6e, 0xf3, 0x89, 0x6e, 0x27, + 0x9e, 0xa6, 0xa6, 0x73, 0x59, 0xbb, 0x71, 0x00, 0xd4, 0x4f, 0x4b, 0x48, + 0xe9, 0xd5, 0xc9, 0x27, 0x36, 0x9c, 0x7c, 0x1c, 0x02, 0xaa, 0xac, 0xbd, + 0x3b, 0xd1, 0x53, 0x83, 0x6a, 0x1f, 0xe6, 0x08, 0x47, 0x33, 0xa7, 0xb1, + 0x9f, 0x02, 0xbe, 0x9b, 0x47, 0xed, 0x33, 0x04, 0xdc, 0x1c, 0x80, 0x27, + 0xd1, 0x4a, 0x33, 0xa0, 0x8c, 0xeb, 0x01, 0x47, 0xa1, 0x32, 0x90, 0x64, + 0x7b, 0xc4, 0xe0, 0x84, 0xc9, 0x32, 0xe9, 0xdd, 0x34, 0x1f, 0x8a, 0x68, + 0x67, 0xf3, 0xad, 0x10, 0x63, 0xeb, 0xee, 0x8a, 0x9a, 0xb1, 0x2a, 0x1b, + 0x26, 0x74, 0xa1, 0x2a, 0xb0, 0x8f, 0xfe, 0x52, 0x98, 0x46, 0x97, 0xcf, + 0xa3, 0x56, 0x1c, 0x6f, 0x6e, 0x99, 0x97, 0x8d, 0x26, 0x0e, 0xa9, 0xec, + 0xc2, 0x53, 0x70, 0xfc, 0x7a, 0xa5, 0x19, 0x49, 0xbd, 0xb5, 0x17, 0x82, + 0x55, 0xde, 0x97, 0xe0, 0x5d, 0x62, 0x84, 0x81, 0xf0, 0x70, 0xa8, 0x34, + 0x53, 0x4f, 0x14, 0xfd, 0x3d, 0x5d, 0x3d, 0x6f, 0xb9, 0x02, 0x03, 0x01, + 0x00, 0x01, 0xa3, 0x82, 0x01, 0x35, 0x30, 0x82, 0x01, 0x31, 0x30, 0x12, + 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, + 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x2f, + 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x23, + 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x74, + 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x30, + 0x3b, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, + 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, + 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, + 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, + 0x30, 0x32, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2b, 0x30, 0x29, 0x30, + 0x27, 0xa0, 0x25, 0xa0, 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x74, 0x31, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, 0x43, 0x41, + 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x29, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, + 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, + 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, 0x35, 0x33, 0x36, 0x30, + 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xf0, 0x70, + 0x51, 0xda, 0xd3, 0x2a, 0x91, 0x4f, 0x52, 0x77, 0xd7, 0x86, 0x77, 0x74, + 0x0f, 0xce, 0x71, 0x1a, 0x6c, 0x22, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, + 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7b, 0x5b, 0x45, 0xcf, 0xaf, + 0xce, 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a, 0x6a, 0xb6, 0xf3, 0x46, 0xeb, + 0x57, 0x48, 0x50, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xa1, + 0x2e, 0x94, 0x3e, 0x9b, 0x16, 0xf4, 0x58, 0x1a, 0x6f, 0xc1, 0xfa, 0xc1, + 0x7e, 0x43, 0x93, 0xb2, 0xc3, 0xf7, 0x89, 0xeb, 0x13, 0x62, 0x5d, 0xdd, + 0xcc, 0x61, 0x13, 0x2b, 0x1d, 0x4e, 0x88, 0x79, 0x11, 0x62, 0x14, 0x37, + 0x30, 0x46, 0xff, 0x89, 0x62, 0x10, 0x85, 0x2a, 0x87, 0x1e, 0xf8, 0xe2, + 0xaf, 0xfe, 0x93, 0x02, 0x93, 0xca, 0xf2, 0xe9, 0x46, 0x03, 0x6b, 0xa1, + 0x1a, 0xac, 0xd5, 0xf0, 0x80, 0x1b, 0x98, 0x6f, 0xb8, 0x3a, 0x50, 0xf8, + 0x54, 0x71, 0x06, 0x03, 0xe7, 0x84, 0xcc, 0x8e, 0x61, 0xd2, 0x5f, 0x4d, + 0x0c, 0x97, 0x02, 0x65, 0xb5, 0x8c, 0x26, 0xbc, 0x05, 0x98, 0xf4, 0xdc, + 0xc6, 0xaf, 0xe4, 0x57, 0x7f, 0xe3, 0xdc, 0xa1, 0xd7, 0x27, 0x47, 0x2a, + 0xe0, 0x2c, 0x3f, 0x09, 0x74, 0xdc, 0x5a, 0xe5, 0xb5, 0x7c, 0xfa, 0x82, + 0x9a, 0x15, 0xfa, 0x74, 0x2b, 0x84, 0x2e, 0x6b, 0xac, 0xef, 0x35, 0xa6, + 0x30, 0xfa, 0x47, 0x4a, 0xaa, 0x36, 0x44, 0xf6, 0x5a, 0x91, 0x07, 0xd3, + 0xe4, 0x4e, 0x97, 0x3f, 0xa6, 0x53, 0xd8, 0x29, 0x33, 0x32, 0x6f, 0x8b, + 0x3d, 0xb5, 0xa5, 0x0d, 0xe5, 0xe4, 0x8a, 0xe8, 0xf5, 0xc0, 0xfa, 0xaf, + 0xd8, 0x37, 0x28, 0x27, 0xc3, 0xed, 0x34, 0x31, 0xd9, 0x7c, 0xa6, 0xaf, + 0x4d, 0x12, 0x4f, 0xd0, 0x2b, 0x92, 0x9c, 0x69, 0x95, 0xf2, 0x28, 0xa6, + 0xfe, 0xa8, 0xc6, 0xe0, 0x2c, 0x4d, 0x36, 0xeb, 0x11, 0x34, 0xd6, 0xe1, + 0x81, 0x99, 0x9d, 0x41, 0xf2, 0xe7, 0xc5, 0x57, 0x05, 0x0e, 0x19, 0xca, + 0xaf, 0x42, 0x39, 0x1f, 0xa7, 0x27, 0x5e, 0xe0, 0x0a, 0x17, 0xb8, 0xae, + 0x47, 0xab, 0x92, 0xf1, 0x8a, 0x04, 0xdf, 0x30, 0xe0, 0xbb, 0x4f, 0x8a, + 0xf9, 0x1b, 0x88, 0x4f, 0x03, 0xb4, 0x25, 0x7a, 0x78, 0xde, 0x2e, 0x7d, + 0x29, 0xd1, 0x31, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 04:e1:e7:a4:dc:5c:f2:f3:6d:c0:2b:42:b8:5d:15:9f + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA + Validity + Not Before: Oct 22 12:00:00 2013 GMT + Not After : Oct 22 12:00:00 2028 GMT + Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert SHA2 High Assurance Server CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:b6:e0:2f:c2:24:06:c8:6d:04:5f:d7:ef:0a:64: + 06:b2:7d:22:26:65:16:ae:42:40:9b:ce:dc:9f:9f: + 76:07:3e:c3:30:55:87:19:b9:4f:94:0e:5a:94:1f: + 55:56:b4:c2:02:2a:af:d0:98:ee:0b:40:d7:c4:d0: + 3b:72:c8:14:9e:ef:90:b1:11:a9:ae:d2:c8:b8:43: + 3a:d9:0b:0b:d5:d5:95:f5:40:af:c8:1d:ed:4d:9c: + 5f:57:b7:86:50:68:99:f5:8a:da:d2:c7:05:1f:a8: + 97:c9:dc:a4:b1:82:84:2d:c6:ad:a5:9c:c7:19:82: + a6:85:0f:5e:44:58:2a:37:8f:fd:35:f1:0b:08:27: + 32:5a:f5:bb:8b:9e:a4:bd:51:d0:27:e2:dd:3b:42: + 33:a3:05:28:c4:bb:28:cc:9a:ac:2b:23:0d:78:c6: + 7b:e6:5e:71:b7:4a:3e:08:fb:81:b7:16:16:a1:9d: + 23:12:4d:e5:d7:92:08:ac:75:a4:9c:ba:cd:17:b2: + 1e:44:35:65:7f:53:25:39:d1:1c:0a:9a:63:1b:19: + 92:74:68:0a:37:c2:c2:52:48:cb:39:5a:a2:b6:e1: + 5d:c1:dd:a0:20:b8:21:a2:93:26:6f:14:4a:21:41: + c7:ed:6d:9b:f2:48:2f:f3:03:f5:a2:68:92:53:2f: + 5e:e3 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + X509v3 Extended Key Usage: + TLS Web Server Authentication, TLS Web Client Authentication + Authority Information Access: + OCSP - URI:http://ocsp.digicert.com + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl4.digicert.com/DigiCertHighAssuranceEVRootCA.crl + + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: https://www.digicert.com/CPS + + X509v3 Subject Key Identifier: + 51:68:FF:90:AF:02:07:75:3C:CC:D9:65:64:62:A2:12:B8:59:72:3B + X509v3 Authority Key Identifier: + keyid:B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3 + + Signature Algorithm: sha256WithRSAEncryption + 18:8a:95:89:03:e6:6d:df:5c:fc:1d:68:ea:4a:8f:83:d6:51: + 2f:8d:6b:44:16:9e:ac:63:f5:d2:6e:6c:84:99:8b:aa:81:71: + 84:5b:ed:34:4e:b0:b7:79:92:29:cc:2d:80:6a:f0:8e:20:e1: + 79:a4:fe:03:47:13:ea:f5:86:ca:59:71:7d:f4:04:96:6b:d3: + 59:58:3d:fe:d3:31:25:5c:18:38:84:a3:e6:9f:82:fd:8c:5b: + 98:31:4e:cd:78:9e:1a:fd:85:cb:49:aa:f2:27:8b:99:72:fc: + 3e:aa:d5:41:0b:da:d5:36:a1:bf:1c:6e:47:49:7f:5e:d9:48: + 7c:03:d9:fd:8b:49:a0:98:26:42:40:eb:d6:92:11:a4:64:0a: + 57:54:c4:f5:1d:d6:02:5e:6b:ac:ee:c4:80:9a:12:72:fa:56: + 93:d7:ff:bf:30:85:06:30:bf:0b:7f:4e:ff:57:05:9d:24:ed: + 85:c3:2b:fb:a6:75:a8:ac:2d:16:ef:7d:79:27:b2:eb:c2:9d: + 0b:07:ea:aa:85:d3:01:a3:20:28:41:59:43:28:d2:81:e3:aa: + f6:ec:7b:3b:77:b6:40:62:80:05:41:45:01:ef:17:06:3e:de: + c0:33:9b:67:d3:61:2e:72:87:e4:69:fc:12:00:57:40:1e:70: + f5:1e:c9:b4 +-----BEGIN CERTIFICATE----- +MIIEsTCCA5mgAwIBAgIQBOHnpNxc8vNtwCtCuF0VnzANBgkqhkiG9w0BAQsFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTEvMC0GA1UEAxMmRGlnaUNlcnQgU0hBMiBIaWdoIEFzc3Vy +YW5jZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2 +4C/CJAbIbQRf1+8KZAayfSImZRauQkCbztyfn3YHPsMwVYcZuU+UDlqUH1VWtMIC +Kq/QmO4LQNfE0DtyyBSe75CxEamu0si4QzrZCwvV1ZX1QK/IHe1NnF9Xt4ZQaJn1 +itrSxwUfqJfJ3KSxgoQtxq2lnMcZgqaFD15EWCo3j/018QsIJzJa9buLnqS9UdAn +4t07QjOjBSjEuyjMmqwrIw14xnvmXnG3Sj4I+4G3FhahnSMSTeXXkgisdaScus0X +sh5ENWV/UyU50RwKmmMbGZJ0aAo3wsJSSMs5WqK24V3B3aAguCGikyZvFEohQcft +bZvySC/zA/WiaJJTL17jAgMBAAGjggFJMIIBRTASBgNVHRMBAf8ECDAGAQH/AgEA +MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw +NAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy +dC5jb20wSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNlcnQuY29t +L0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDA9BgNVHSAENjA0MDIG +BFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQ +UzAdBgNVHQ4EFgQUUWj/kK8CB3U8zNllZGKiErhZcjswHwYDVR0jBBgwFoAUsT7D +aQP4v0cB1JgmGggC72NkK8MwDQYJKoZIhvcNAQELBQADggEBABiKlYkD5m3fXPwd +aOpKj4PWUS+Na0QWnqxj9dJubISZi6qBcYRb7TROsLd5kinMLYBq8I4g4Xmk/gNH +E+r1hspZcX30BJZr01lYPf7TMSVcGDiEo+afgv2MW5gxTs14nhr9hctJqvIni5ly +/D6q1UEL2tU2ob8cbkdJf17ZSHwD2f2LSaCYJkJA69aSEaRkCldUxPUd1gJea6zu +xICaEnL6VpPX/78whQYwvwt/Tv9XBZ0k7YXDK/umdaisLRbvfXknsuvCnQsH6qqF +0wGjIChBWUMo0oHjqvbsezt3tkBigAVBRQHvFwY+3sAzm2fTYS5yh+Rp/BIAV0Ae +cPUeybQ= +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert29[] = { + 0x30, 0x82, 0x04, 0xb1, 0x30, 0x82, 0x03, 0x99, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x04, 0xe1, 0xe7, 0xa4, 0xdc, 0x5c, 0xf2, 0xf3, 0x6d, + 0xc0, 0x2b, 0x42, 0xb8, 0x5d, 0x15, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x6c, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, + 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, + 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, + 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, + 0x63, 0x6f, 0x6d, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48, + 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, + 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, + 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x32, 0x32, 0x31, 0x32, + 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x31, 0x30, 0x32, + 0x32, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x70, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44, 0x69, + 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, 0x77, 0x77, + 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, + 0x6d, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26, + 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x53, 0x48, 0x41, + 0x32, 0x20, 0x48, 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, + 0x61, 0x6e, 0x63, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, + 0x43, 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, 0xb6, + 0xe0, 0x2f, 0xc2, 0x24, 0x06, 0xc8, 0x6d, 0x04, 0x5f, 0xd7, 0xef, 0x0a, + 0x64, 0x06, 0xb2, 0x7d, 0x22, 0x26, 0x65, 0x16, 0xae, 0x42, 0x40, 0x9b, + 0xce, 0xdc, 0x9f, 0x9f, 0x76, 0x07, 0x3e, 0xc3, 0x30, 0x55, 0x87, 0x19, + 0xb9, 0x4f, 0x94, 0x0e, 0x5a, 0x94, 0x1f, 0x55, 0x56, 0xb4, 0xc2, 0x02, + 0x2a, 0xaf, 0xd0, 0x98, 0xee, 0x0b, 0x40, 0xd7, 0xc4, 0xd0, 0x3b, 0x72, + 0xc8, 0x14, 0x9e, 0xef, 0x90, 0xb1, 0x11, 0xa9, 0xae, 0xd2, 0xc8, 0xb8, + 0x43, 0x3a, 0xd9, 0x0b, 0x0b, 0xd5, 0xd5, 0x95, 0xf5, 0x40, 0xaf, 0xc8, + 0x1d, 0xed, 0x4d, 0x9c, 0x5f, 0x57, 0xb7, 0x86, 0x50, 0x68, 0x99, 0xf5, + 0x8a, 0xda, 0xd2, 0xc7, 0x05, 0x1f, 0xa8, 0x97, 0xc9, 0xdc, 0xa4, 0xb1, + 0x82, 0x84, 0x2d, 0xc6, 0xad, 0xa5, 0x9c, 0xc7, 0x19, 0x82, 0xa6, 0x85, + 0x0f, 0x5e, 0x44, 0x58, 0x2a, 0x37, 0x8f, 0xfd, 0x35, 0xf1, 0x0b, 0x08, + 0x27, 0x32, 0x5a, 0xf5, 0xbb, 0x8b, 0x9e, 0xa4, 0xbd, 0x51, 0xd0, 0x27, + 0xe2, 0xdd, 0x3b, 0x42, 0x33, 0xa3, 0x05, 0x28, 0xc4, 0xbb, 0x28, 0xcc, + 0x9a, 0xac, 0x2b, 0x23, 0x0d, 0x78, 0xc6, 0x7b, 0xe6, 0x5e, 0x71, 0xb7, + 0x4a, 0x3e, 0x08, 0xfb, 0x81, 0xb7, 0x16, 0x16, 0xa1, 0x9d, 0x23, 0x12, + 0x4d, 0xe5, 0xd7, 0x92, 0x08, 0xac, 0x75, 0xa4, 0x9c, 0xba, 0xcd, 0x17, + 0xb2, 0x1e, 0x44, 0x35, 0x65, 0x7f, 0x53, 0x25, 0x39, 0xd1, 0x1c, 0x0a, + 0x9a, 0x63, 0x1b, 0x19, 0x92, 0x74, 0x68, 0x0a, 0x37, 0xc2, 0xc2, 0x52, + 0x48, 0xcb, 0x39, 0x5a, 0xa2, 0xb6, 0xe1, 0x5d, 0xc1, 0xdd, 0xa0, 0x20, + 0xb8, 0x21, 0xa2, 0x93, 0x26, 0x6f, 0x14, 0x4a, 0x21, 0x41, 0xc7, 0xed, + 0x6d, 0x9b, 0xf2, 0x48, 0x2f, 0xf3, 0x03, 0xf5, 0xa2, 0x68, 0x92, 0x53, + 0x2f, 0x5e, 0xe3, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x49, + 0x30, 0x82, 0x01, 0x45, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, + 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, + 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, + 0x03, 0x02, 0x01, 0x86, 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, + 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, + 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4b, 0x06, 0x03, 0x55, 0x1d, 0x1f, + 0x04, 0x44, 0x30, 0x42, 0x30, 0x40, 0xa0, 0x3e, 0xa0, 0x3c, 0x86, 0x3a, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x34, 0x2e, + 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x48, 0x69, 0x67, + 0x68, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x45, 0x56, + 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3d, + 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06, + 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, + 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, + 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, + 0x53, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, + 0x51, 0x68, 0xff, 0x90, 0xaf, 0x02, 0x07, 0x75, 0x3c, 0xcc, 0xd9, 0x65, + 0x64, 0x62, 0xa2, 0x12, 0xb8, 0x59, 0x72, 0x3b, 0x30, 0x1f, 0x06, 0x03, + 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb1, 0x3e, 0xc3, + 0x69, 0x03, 0xf8, 0xbf, 0x47, 0x01, 0xd4, 0x98, 0x26, 0x1a, 0x08, 0x02, + 0xef, 0x63, 0x64, 0x2b, 0xc3, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, + 0x00, 0x18, 0x8a, 0x95, 0x89, 0x03, 0xe6, 0x6d, 0xdf, 0x5c, 0xfc, 0x1d, + 0x68, 0xea, 0x4a, 0x8f, 0x83, 0xd6, 0x51, 0x2f, 0x8d, 0x6b, 0x44, 0x16, + 0x9e, 0xac, 0x63, 0xf5, 0xd2, 0x6e, 0x6c, 0x84, 0x99, 0x8b, 0xaa, 0x81, + 0x71, 0x84, 0x5b, 0xed, 0x34, 0x4e, 0xb0, 0xb7, 0x79, 0x92, 0x29, 0xcc, + 0x2d, 0x80, 0x6a, 0xf0, 0x8e, 0x20, 0xe1, 0x79, 0xa4, 0xfe, 0x03, 0x47, + 0x13, 0xea, 0xf5, 0x86, 0xca, 0x59, 0x71, 0x7d, 0xf4, 0x04, 0x96, 0x6b, + 0xd3, 0x59, 0x58, 0x3d, 0xfe, 0xd3, 0x31, 0x25, 0x5c, 0x18, 0x38, 0x84, + 0xa3, 0xe6, 0x9f, 0x82, 0xfd, 0x8c, 0x5b, 0x98, 0x31, 0x4e, 0xcd, 0x78, + 0x9e, 0x1a, 0xfd, 0x85, 0xcb, 0x49, 0xaa, 0xf2, 0x27, 0x8b, 0x99, 0x72, + 0xfc, 0x3e, 0xaa, 0xd5, 0x41, 0x0b, 0xda, 0xd5, 0x36, 0xa1, 0xbf, 0x1c, + 0x6e, 0x47, 0x49, 0x7f, 0x5e, 0xd9, 0x48, 0x7c, 0x03, 0xd9, 0xfd, 0x8b, + 0x49, 0xa0, 0x98, 0x26, 0x42, 0x40, 0xeb, 0xd6, 0x92, 0x11, 0xa4, 0x64, + 0x0a, 0x57, 0x54, 0xc4, 0xf5, 0x1d, 0xd6, 0x02, 0x5e, 0x6b, 0xac, 0xee, + 0xc4, 0x80, 0x9a, 0x12, 0x72, 0xfa, 0x56, 0x93, 0xd7, 0xff, 0xbf, 0x30, + 0x85, 0x06, 0x30, 0xbf, 0x0b, 0x7f, 0x4e, 0xff, 0x57, 0x05, 0x9d, 0x24, + 0xed, 0x85, 0xc3, 0x2b, 0xfb, 0xa6, 0x75, 0xa8, 0xac, 0x2d, 0x16, 0xef, + 0x7d, 0x79, 0x27, 0xb2, 0xeb, 0xc2, 0x9d, 0x0b, 0x07, 0xea, 0xaa, 0x85, + 0xd3, 0x01, 0xa3, 0x20, 0x28, 0x41, 0x59, 0x43, 0x28, 0xd2, 0x81, 0xe3, + 0xaa, 0xf6, 0xec, 0x7b, 0x3b, 0x77, 0xb6, 0x40, 0x62, 0x80, 0x05, 0x41, + 0x45, 0x01, 0xef, 0x17, 0x06, 0x3e, 0xde, 0xc0, 0x33, 0x9b, 0x67, 0xd3, + 0x61, 0x2e, 0x72, 0x87, 0xe4, 0x69, 0xfc, 0x12, 0x00, 0x57, 0x40, 0x1e, + 0x70, 0xf5, 0x1e, 0xc9, 0xb4, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 16:87:d6:88:6d:e2:30:06:85:23:3d:bf:11:bf:65:97 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA + Validity + Not Before: Oct 31 00:00:00 2013 GMT + Not After : Oct 30 23:59:59 2023 GMT + Subject: C=US, O=thawte, Inc., CN=thawte SSL CA - G2 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:b2:fc:06:fb:04:93:d2:ea:59:20:3b:44:85:97: + 52:39:e7:10:f0:7a:e0:b0:94:40:da:46:f8:0c:28: + bb:b9:ce:60:38:3f:d2:d8:11:42:1b:91:ad:49:ee: + 8f:c7:de:6c:de:37:6f:fd:8b:20:3c:6d:e7:74:d3: + dc:d5:24:88:41:80:89:ee:36:be:c4:d5:be:8d:53: + 13:aa:e4:a5:b8:93:0a:be:ec:da:cd:3c:d4:32:56: + ef:d0:4e:a0:b8:97:bb:39:50:1e:6e:65:c3:fd:b2: + ce:e0:59:a9:48:09:c6:fe:be:ae:fc:3e:3b:81:20: + 97:8b:8f:46:df:60:64:07:75:bb:1b:86:38:9f:47: + 7b:34:ce:a1:d1:97:ad:76:d8:9f:b7:26:db:79:80: + 36:48:f2:c5:37:f8:d9:32:ae:7c:a4:53:81:c7:99: + a1:54:38:2f:4f:75:a0:bb:5a:a5:bb:cd:ac:02:5b: + 19:02:d5:13:18:a7:ce:ac:74:55:12:05:8b:9b:a2: + 95:46:64:72:38:cd:5a:1b:3a:16:a7:be:71:99:8c: + 54:03:b8:96:6c:01:d3:3e:06:98:3f:21:81:3b:02: + 7e:00:47:53:01:1e:0e:46:43:fb:4b:2d:dc:0b:1a: + e8:2f:98:f8:7e:d1:99:ab:13:6c:a4:17:de:6f:f6: + 15:f5 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 CRL Distribution Points: + + Full Name: + URI:http://t1.symcb.com/ThawtePCA.crl + + Authority Information Access: + OCSP - URI:http://t2.symcb.com + + X509v3 Certificate Policies: + Policy: 2.16.840.1.113733.1.7.54 + CPS: https://www.thawte.com/cps + + X509v3 Subject Alternative Name: + DirName:/CN=SymantecPKI-1-537 + X509v3 Subject Key Identifier: + C2:4F:48:57:FC:D1:4F:9A:C0:5D:38:7D:0E:05:DB:D9:2E:B5:52:60 + X509v3 Authority Key Identifier: + keyid:7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50 + + Signature Algorithm: sha256WithRSAEncryption + 8d:06:de:43:c9:76:02:ca:d9:23:97:5e:f3:63:d7:7d:44:c2: + 0f:6b:0a:f5:07:e5:8b:b8:fa:e0:a3:fa:6b:80:92:b5:03:2c: + c5:37:e0:c2:e5:95:b5:92:70:18:28:42:94:ee:4b:77:6a:01: + 0f:8b:23:ec:56:4d:f4:00:69:e5:84:c8:e2:ea:de:5b:3e:f6: + 3c:07:3a:94:ca:6c:27:b1:cc:83:1a:60:71:27:d2:bf:02:f5: + 1e:44:d3:48:d5:a6:d3:76:21:00:9c:fa:98:64:eb:17:36:3f: + eb:1b:3c:3e:a6:b1:d9:58:06:0e:72:d9:68:be:f1:a7:20:d7: + 52:e4:a4:77:1f:71:70:9d:55:35:85:37:e1:1d:4d:94:c2:70: + 7f:95:40:6e:4b:7d:b2:b4:29:2a:03:79:c8:b9:4c:67:61:04: + a0:8b:27:ff:59:00:eb:55:7f:c6:b7:33:35:2d:5e:4e:ac:b8: + ea:12:c5:e8:f7:b9:ab:be:74:92:2c:b7:d9:4d:ca:84:2f:1c: + c2:f0:72:7c:b2:31:6e:cf:80:e5:88:07:36:51:7b:ba:61:af: + 6d:8d:23:5b:34:a3:95:bc:a2:31:7f:f2:f5:e7:b7:e8:ef:c4: + b5:27:32:e9:f7:9e:69:c7:2b:e8:be:bb:0c:aa:e7:ea:60:12: + ea:26:8a:78 +-----BEGIN CERTIFICATE----- +MIIEsjCCA5qgAwIBAgIQFofWiG3iMAaFIz2/Eb9llzANBgkqhkiG9w0BAQsFADCB +qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV +BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTMxMDMxMDAwMDAwWhcNMjMx +MDMwMjM1OTU5WjBBMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMu +MRswGQYDVQQDExJ0aGF3dGUgU1NMIENBIC0gRzIwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCy/Ab7BJPS6lkgO0SFl1I55xDweuCwlEDaRvgMKLu5zmA4 +P9LYEUIbka1J7o/H3mzeN2/9iyA8bed009zVJIhBgInuNr7E1b6NUxOq5KW4kwq+ +7NrNPNQyVu/QTqC4l7s5UB5uZcP9ss7gWalICcb+vq78PjuBIJeLj0bfYGQHdbsb +hjifR3s0zqHRl6122J+3Jtt5gDZI8sU3+NkyrnykU4HHmaFUOC9PdaC7WqW7zawC +WxkC1RMYp86sdFUSBYubopVGZHI4zVobOhanvnGZjFQDuJZsAdM+Bpg/IYE7An4A +R1MBHg5GQ/tLLdwLGugvmPh+0ZmrE2ykF95v9hX1AgMBAAGjggE7MIIBNzASBgNV +HRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAyBgNVHR8EKzApMCegJaAj +hiFodHRwOi8vdDEuc3ltY2IuY29tL1RoYXd0ZVBDQS5jcmwwLwYIKwYBBQUHAQEE +IzAhMB8GCCsGAQUFBzABhhNodHRwOi8vdDIuc3ltY2IuY29tMEEGA1UdIAQ6MDgw +NgYKYIZIAYb4RQEHNjAoMCYGCCsGAQUFBwIBFhpodHRwczovL3d3dy50aGF3dGUu +Y29tL2NwczApBgNVHREEIjAgpB4wHDEaMBgGA1UEAxMRU3ltYW50ZWNQS0ktMS01 +MzcwHQYDVR0OBBYEFMJPSFf80U+awF04fQ4F29kutVJgMB8GA1UdIwQYMBaAFHtb +Rc+vzst6/TGSGmq280brV0hQMA0GCSqGSIb3DQEBCwUAA4IBAQCNBt5DyXYCytkj +l17zY9d9RMIPawr1B+WLuPrgo/prgJK1AyzFN+DC5ZW1knAYKEKU7kt3agEPiyPs +Vk30AGnlhMji6t5bPvY8BzqUymwnscyDGmBxJ9K/AvUeRNNI1abTdiEAnPqYZOsX +Nj/rGzw+prHZWAYOctlovvGnINdS5KR3H3FwnVU1hTfhHU2UwnB/lUBuS32ytCkq +A3nIuUxnYQSgiyf/WQDrVX/GtzM1LV5OrLjqEsXo97mrvnSSLLfZTcqELxzC8HJ8 +sjFuz4DliAc2UXu6Ya9tjSNbNKOVvKIxf/L157fo78S1JzLp955pxyvovrsMqufq +YBLqJop4 +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert30[] = { + 0x30, 0x82, 0x04, 0xb2, 0x30, 0x82, 0x03, 0x9a, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x16, 0x87, 0xd6, 0x88, 0x6d, 0xe2, 0x30, 0x06, 0x85, + 0x23, 0x3d, 0xbf, 0x11, 0xbf, 0x65, 0x97, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, + 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, + 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44, + 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06, + 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, + 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, + 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, + 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, + 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x33, 0x31, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x31, + 0x30, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x41, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, + 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x74, + 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, + 0x20, 0x2d, 0x20, 0x47, 0x32, 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, 0xb2, 0xfc, 0x06, 0xfb, 0x04, 0x93, 0xd2, 0xea, 0x59, 0x20, + 0x3b, 0x44, 0x85, 0x97, 0x52, 0x39, 0xe7, 0x10, 0xf0, 0x7a, 0xe0, 0xb0, + 0x94, 0x40, 0xda, 0x46, 0xf8, 0x0c, 0x28, 0xbb, 0xb9, 0xce, 0x60, 0x38, + 0x3f, 0xd2, 0xd8, 0x11, 0x42, 0x1b, 0x91, 0xad, 0x49, 0xee, 0x8f, 0xc7, + 0xde, 0x6c, 0xde, 0x37, 0x6f, 0xfd, 0x8b, 0x20, 0x3c, 0x6d, 0xe7, 0x74, + 0xd3, 0xdc, 0xd5, 0x24, 0x88, 0x41, 0x80, 0x89, 0xee, 0x36, 0xbe, 0xc4, + 0xd5, 0xbe, 0x8d, 0x53, 0x13, 0xaa, 0xe4, 0xa5, 0xb8, 0x93, 0x0a, 0xbe, + 0xec, 0xda, 0xcd, 0x3c, 0xd4, 0x32, 0x56, 0xef, 0xd0, 0x4e, 0xa0, 0xb8, + 0x97, 0xbb, 0x39, 0x50, 0x1e, 0x6e, 0x65, 0xc3, 0xfd, 0xb2, 0xce, 0xe0, + 0x59, 0xa9, 0x48, 0x09, 0xc6, 0xfe, 0xbe, 0xae, 0xfc, 0x3e, 0x3b, 0x81, + 0x20, 0x97, 0x8b, 0x8f, 0x46, 0xdf, 0x60, 0x64, 0x07, 0x75, 0xbb, 0x1b, + 0x86, 0x38, 0x9f, 0x47, 0x7b, 0x34, 0xce, 0xa1, 0xd1, 0x97, 0xad, 0x76, + 0xd8, 0x9f, 0xb7, 0x26, 0xdb, 0x79, 0x80, 0x36, 0x48, 0xf2, 0xc5, 0x37, + 0xf8, 0xd9, 0x32, 0xae, 0x7c, 0xa4, 0x53, 0x81, 0xc7, 0x99, 0xa1, 0x54, + 0x38, 0x2f, 0x4f, 0x75, 0xa0, 0xbb, 0x5a, 0xa5, 0xbb, 0xcd, 0xac, 0x02, + 0x5b, 0x19, 0x02, 0xd5, 0x13, 0x18, 0xa7, 0xce, 0xac, 0x74, 0x55, 0x12, + 0x05, 0x8b, 0x9b, 0xa2, 0x95, 0x46, 0x64, 0x72, 0x38, 0xcd, 0x5a, 0x1b, + 0x3a, 0x16, 0xa7, 0xbe, 0x71, 0x99, 0x8c, 0x54, 0x03, 0xb8, 0x96, 0x6c, + 0x01, 0xd3, 0x3e, 0x06, 0x98, 0x3f, 0x21, 0x81, 0x3b, 0x02, 0x7e, 0x00, + 0x47, 0x53, 0x01, 0x1e, 0x0e, 0x46, 0x43, 0xfb, 0x4b, 0x2d, 0xdc, 0x0b, + 0x1a, 0xe8, 0x2f, 0x98, 0xf8, 0x7e, 0xd1, 0x99, 0xab, 0x13, 0x6c, 0xa4, + 0x17, 0xde, 0x6f, 0xf6, 0x15, 0xf5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, + 0x82, 0x01, 0x3b, 0x30, 0x82, 0x01, 0x37, 0x30, 0x12, 0x06, 0x03, 0x55, + 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, + 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, + 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x32, 0x06, 0x03, 0x55, + 0x1d, 0x1f, 0x04, 0x2b, 0x30, 0x29, 0x30, 0x27, 0xa0, 0x25, 0xa0, 0x23, + 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x74, 0x31, 0x2e, + 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68, + 0x61, 0x77, 0x74, 0x65, 0x50, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, + 0x2f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, + 0x23, 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x74, 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x30, 0x41, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3a, 0x30, 0x38, 0x30, + 0x36, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, + 0x36, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x29, 0x06, 0x03, 0x55, + 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x1a, + 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, 0x6d, + 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, 0x35, + 0x33, 0x37, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, + 0x14, 0xc2, 0x4f, 0x48, 0x57, 0xfc, 0xd1, 0x4f, 0x9a, 0xc0, 0x5d, 0x38, + 0x7d, 0x0e, 0x05, 0xdb, 0xd9, 0x2e, 0xb5, 0x52, 0x60, 0x30, 0x1f, 0x06, + 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7b, 0x5b, + 0x45, 0xcf, 0xaf, 0xce, 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a, 0x6a, 0xb6, + 0xf3, 0x46, 0xeb, 0x57, 0x48, 0x50, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, + 0x01, 0x00, 0x8d, 0x06, 0xde, 0x43, 0xc9, 0x76, 0x02, 0xca, 0xd9, 0x23, + 0x97, 0x5e, 0xf3, 0x63, 0xd7, 0x7d, 0x44, 0xc2, 0x0f, 0x6b, 0x0a, 0xf5, + 0x07, 0xe5, 0x8b, 0xb8, 0xfa, 0xe0, 0xa3, 0xfa, 0x6b, 0x80, 0x92, 0xb5, + 0x03, 0x2c, 0xc5, 0x37, 0xe0, 0xc2, 0xe5, 0x95, 0xb5, 0x92, 0x70, 0x18, + 0x28, 0x42, 0x94, 0xee, 0x4b, 0x77, 0x6a, 0x01, 0x0f, 0x8b, 0x23, 0xec, + 0x56, 0x4d, 0xf4, 0x00, 0x69, 0xe5, 0x84, 0xc8, 0xe2, 0xea, 0xde, 0x5b, + 0x3e, 0xf6, 0x3c, 0x07, 0x3a, 0x94, 0xca, 0x6c, 0x27, 0xb1, 0xcc, 0x83, + 0x1a, 0x60, 0x71, 0x27, 0xd2, 0xbf, 0x02, 0xf5, 0x1e, 0x44, 0xd3, 0x48, + 0xd5, 0xa6, 0xd3, 0x76, 0x21, 0x00, 0x9c, 0xfa, 0x98, 0x64, 0xeb, 0x17, + 0x36, 0x3f, 0xeb, 0x1b, 0x3c, 0x3e, 0xa6, 0xb1, 0xd9, 0x58, 0x06, 0x0e, + 0x72, 0xd9, 0x68, 0xbe, 0xf1, 0xa7, 0x20, 0xd7, 0x52, 0xe4, 0xa4, 0x77, + 0x1f, 0x71, 0x70, 0x9d, 0x55, 0x35, 0x85, 0x37, 0xe1, 0x1d, 0x4d, 0x94, + 0xc2, 0x70, 0x7f, 0x95, 0x40, 0x6e, 0x4b, 0x7d, 0xb2, 0xb4, 0x29, 0x2a, + 0x03, 0x79, 0xc8, 0xb9, 0x4c, 0x67, 0x61, 0x04, 0xa0, 0x8b, 0x27, 0xff, + 0x59, 0x00, 0xeb, 0x55, 0x7f, 0xc6, 0xb7, 0x33, 0x35, 0x2d, 0x5e, 0x4e, + 0xac, 0xb8, 0xea, 0x12, 0xc5, 0xe8, 0xf7, 0xb9, 0xab, 0xbe, 0x74, 0x92, + 0x2c, 0xb7, 0xd9, 0x4d, 0xca, 0x84, 0x2f, 0x1c, 0xc2, 0xf0, 0x72, 0x7c, + 0xb2, 0x31, 0x6e, 0xcf, 0x80, 0xe5, 0x88, 0x07, 0x36, 0x51, 0x7b, 0xba, + 0x61, 0xaf, 0x6d, 0x8d, 0x23, 0x5b, 0x34, 0xa3, 0x95, 0xbc, 0xa2, 0x31, + 0x7f, 0xf2, 0xf5, 0xe7, 0xb7, 0xe8, 0xef, 0xc4, 0xb5, 0x27, 0x32, 0xe9, + 0xf7, 0x9e, 0x69, 0xc7, 0x2b, 0xe8, 0xbe, 0xbb, 0x0c, 0xaa, 0xe7, 0xea, + 0x60, 0x12, 0xea, 0x26, 0x8a, 0x78, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 93:92:85:40:01:65:71:5f:94:7f:28:8f:ef:c9:9b:28 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=PL, O=Unizeto Sp. z o.o., CN=Certum CA + Validity + Not Before: Oct 22 12:07:37 2008 GMT + Not After : Jun 10 10:46:39 2027 GMT + Subject: C=PL, O=Unizeto Technologies S.A., OU=Certum Certification Authority, CN=Certum Trusted Network CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:e3:fb:7d:a3:72:ba:c2:f0:c9:14:87:f5:6b:01: + 4e:e1:6e:40:07:ba:6d:27:5d:7f:f7:5b:2d:b3:5a: + c7:51:5f:ab:a4:32:a6:61:87:b6:6e:0f:86:d2:30: + 02:97:f8:d7:69:57:a1:18:39:5d:6a:64:79:c6:01: + 59:ac:3c:31:4a:38:7c:d2:04:d2:4b:28:e8:20:5f: + 3b:07:a2:cc:4d:73:db:f3:ae:4f:c7:56:d5:5a:a7: + 96:89:fa:f3:ab:68:d4:23:86:59:27:cf:09:27:bc: + ac:6e:72:83:1c:30:72:df:e0:a2:e9:d2:e1:74:75: + 19:bd:2a:9e:7b:15:54:04:1b:d7:43:39:ad:55:28: + c5:e2:1a:bb:f4:c0:e4:ae:38:49:33:cc:76:85:9f: + 39:45:d2:a4:9e:f2:12:8c:51:f8:7c:e4:2d:7f:f5: + ac:5f:eb:16:9f:b1:2d:d1:ba:cc:91:42:77:4c:25: + c9:90:38:6f:db:f0:cc:fb:8e:1e:97:59:3e:d5:60: + 4e:e6:05:28:ed:49:79:13:4b:ba:48:db:2f:f9:72: + d3:39:ca:fe:1f:d8:34:72:f5:b4:40:cf:31:01:c3: + ec:de:11:2d:17:5d:1f:b8:50:d1:5e:19:a7:69:de: + 07:33:28:ca:50:95:f9:a7:54:cb:54:86:50:45:a9: + f9:49 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + 08:76:CD:CB:07:FF:24:F6:C5:CD:ED:BB:90:BC:E2:84:37:46:75:F7 + X509v3 Authority Key Identifier: + DirName:/C=PL/O=Unizeto Sp. z o.o./CN=Certum CA + serial:01:00:20 + + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.certum.pl/ca.crl + + Authority Information Access: + OCSP - URI:http://subca.ocsp-certum.com + CA Issuers - URI:http://repository.certum.pl/ca.cer + + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: http://www.certum.pl/CPS + + Signature Algorithm: sha256WithRSAEncryption + 8d:e6:fd:40:66:a3:4c:9c:a7:ab:a1:da:84:dd:1c:30:07:e6: + db:c7:2d:ec:83:a1:56:e4:1d:3c:26:a1:a5:09:2b:e8:7d:62: + be:b2:75:94:dd:08:f2:7f:28:41:e4:80:67:02:4e:8a:8f:c3: + 35:d0:d5:a9:27:28:ea:d2:f4:ab:06:86:43:ae:8c:e3:f9:88: + 7d:e0:db:bd:42:81:80:02:12:75:b2:e8:17:71:ab:21:95:31: + 46:42:0d:88:10:39:d3:6f:ec:2f:42:ea:40:53:62:bf:eb:ca: + 78:9e:ab:a2:d5:2e:05:ea:33:ab:e9:d6:97:94:42:5e:04:ed: + 2c:ed:6a:9c:7a:95:7d:05:2a:05:7f:08:5d:66:ad:61:d4:76: + ac:75:96:97:73:63:bd:1a:41:59:29:a5:5e:22:83:c3:8b:59: + fa:9a:a2:f6:bd:30:bf:72:1d:1c:99:86:9c:f2:85:3c:1d:f7: + 26:96:2f:2e:f9:02:b1:b5:a9:50:e8:38:fa:9b:0a:5e:b4:04: + c0:ce:4e:39:2c:ca:0b:5b:62:f0:4d:58:50:34:99:e6:9a:2c: + d2:90:d7:09:81:d6:c0:aa:5e:ce:fe:d2:f7:a1:ba:4b:d9:d6: + 86:8e:19:1f:a6:06:47:42:72:e0:56:0a:00:1c:78:b9:8d:cc: + 99:04:37:49 +-----BEGIN CERTIFICATE----- +MIIEtDCCA5ygAwIBAgIRAJOShUABZXFflH8oj+/JmygwDQYJKoZIhvcNAQELBQAw +PjELMAkGA1UEBhMCUEwxGzAZBgNVBAoTElVuaXpldG8gU3AuIHogby5vLjESMBAG +A1UEAxMJQ2VydHVtIENBMB4XDTA4MTAyMjEyMDczN1oXDTI3MDYxMDEwNDYzOVow +fjELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEiMCAG +A1UEAxMZQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAOP7faNyusLwyRSH9WsBTuFuQAe6bSddf/dbLbNax1Ff +q6QypmGHtm4PhtIwApf412lXoRg5XWpkecYBWaw8MUo4fNIE0kso6CBfOweizE1z +2/OuT8dW1Vqnlon686to1COGWSfPCSe8rG5ygxwwct/gounS4XR1Gb0qnnsVVAQb +10M5rVUoxeIau/TA5K44STPMdoWfOUXSpJ7yEoxR+HzkLX/1rF/rFp+xLdG6zJFC +d0wlyZA4b9vwzPuOHpdZPtVgTuYFKO1JeRNLukjbL/ly0znK/h/YNHL1tEDPMQHD +7N4RLRddH7hQ0V4Zp2neBzMoylCV+adUy1SGUEWp+UkCAwEAAaOCAWswggFnMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFAh2zcsH/yT2xc3tu5C84oQ3RnX3MFIG +A1UdIwRLMEmhQqRAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNw +LiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQYIDAQAgMA4GA1UdDwEB/wQEAwIB +BjAsBgNVHR8EJTAjMCGgH6AdhhtodHRwOi8vY3JsLmNlcnR1bS5wbC9jYS5jcmww +aAYIKwYBBQUHAQEEXDBaMCgGCCsGAQUFBzABhhxodHRwOi8vc3ViY2Eub2NzcC1j +ZXJ0dW0uY29tMC4GCCsGAQUFBzAChiJodHRwOi8vcmVwb3NpdG9yeS5jZXJ0dW0u +cGwvY2EuY2VyMDkGA1UdIAQyMDAwLgYEVR0gADAmMCQGCCsGAQUFBwIBFhhodHRw +Oi8vd3d3LmNlcnR1bS5wbC9DUFMwDQYJKoZIhvcNAQELBQADggEBAI3m/UBmo0yc +p6uh2oTdHDAH5tvHLeyDoVbkHTwmoaUJK+h9Yr6ydZTdCPJ/KEHkgGcCToqPwzXQ +1aknKOrS9KsGhkOujOP5iH3g271CgYACEnWy6BdxqyGVMUZCDYgQOdNv7C9C6kBT +Yr/rynieq6LVLgXqM6vp1peUQl4E7Sztapx6lX0FKgV/CF1mrWHUdqx1lpdzY70a +QVkppV4ig8OLWfqaova9ML9yHRyZhpzyhTwd9yaWLy75ArG1qVDoOPqbCl60BMDO +TjksygtbYvBNWFA0meaaLNKQ1wmB1sCqXs7+0vehukvZ1oaOGR+mBkdCcuBWCgAc +eLmNzJkEN0k= +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert31[] = { + 0x30, 0x82, 0x04, 0xb4, 0x30, 0x82, 0x03, 0x9c, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x11, 0x00, 0x93, 0x92, 0x85, 0x40, 0x01, 0x65, 0x71, 0x5f, + 0x94, 0x7f, 0x28, 0x8f, 0xef, 0xc9, 0x9b, 0x28, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, + 0x3e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x50, 0x4c, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x12, 0x55, 0x6e, 0x69, 0x7a, 0x65, 0x74, 0x6f, 0x20, 0x53, 0x70, 0x2e, + 0x20, 0x7a, 0x20, 0x6f, 0x2e, 0x6f, 0x2e, 0x31, 0x12, 0x30, 0x10, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6d, + 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x38, 0x31, 0x30, 0x32, + 0x32, 0x31, 0x32, 0x30, 0x37, 0x33, 0x37, 0x5a, 0x17, 0x0d, 0x32, 0x37, + 0x30, 0x36, 0x31, 0x30, 0x31, 0x30, 0x34, 0x36, 0x33, 0x39, 0x5a, 0x30, + 0x7e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x50, 0x4c, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x19, 0x55, 0x6e, 0x69, 0x7a, 0x65, 0x74, 0x6f, 0x20, 0x54, 0x65, 0x63, + 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x20, 0x53, 0x2e, + 0x41, 0x2e, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, + 0x1e, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6d, 0x20, 0x43, 0x65, 0x72, 0x74, + 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x22, 0x30, 0x20, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x19, 0x43, 0x65, 0x72, 0x74, 0x75, 0x6d, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x4e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x43, 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, 0xe3, 0xfb, 0x7d, 0xa3, 0x72, 0xba, 0xc2, 0xf0, + 0xc9, 0x14, 0x87, 0xf5, 0x6b, 0x01, 0x4e, 0xe1, 0x6e, 0x40, 0x07, 0xba, + 0x6d, 0x27, 0x5d, 0x7f, 0xf7, 0x5b, 0x2d, 0xb3, 0x5a, 0xc7, 0x51, 0x5f, + 0xab, 0xa4, 0x32, 0xa6, 0x61, 0x87, 0xb6, 0x6e, 0x0f, 0x86, 0xd2, 0x30, + 0x02, 0x97, 0xf8, 0xd7, 0x69, 0x57, 0xa1, 0x18, 0x39, 0x5d, 0x6a, 0x64, + 0x79, 0xc6, 0x01, 0x59, 0xac, 0x3c, 0x31, 0x4a, 0x38, 0x7c, 0xd2, 0x04, + 0xd2, 0x4b, 0x28, 0xe8, 0x20, 0x5f, 0x3b, 0x07, 0xa2, 0xcc, 0x4d, 0x73, + 0xdb, 0xf3, 0xae, 0x4f, 0xc7, 0x56, 0xd5, 0x5a, 0xa7, 0x96, 0x89, 0xfa, + 0xf3, 0xab, 0x68, 0xd4, 0x23, 0x86, 0x59, 0x27, 0xcf, 0x09, 0x27, 0xbc, + 0xac, 0x6e, 0x72, 0x83, 0x1c, 0x30, 0x72, 0xdf, 0xe0, 0xa2, 0xe9, 0xd2, + 0xe1, 0x74, 0x75, 0x19, 0xbd, 0x2a, 0x9e, 0x7b, 0x15, 0x54, 0x04, 0x1b, + 0xd7, 0x43, 0x39, 0xad, 0x55, 0x28, 0xc5, 0xe2, 0x1a, 0xbb, 0xf4, 0xc0, + 0xe4, 0xae, 0x38, 0x49, 0x33, 0xcc, 0x76, 0x85, 0x9f, 0x39, 0x45, 0xd2, + 0xa4, 0x9e, 0xf2, 0x12, 0x8c, 0x51, 0xf8, 0x7c, 0xe4, 0x2d, 0x7f, 0xf5, + 0xac, 0x5f, 0xeb, 0x16, 0x9f, 0xb1, 0x2d, 0xd1, 0xba, 0xcc, 0x91, 0x42, + 0x77, 0x4c, 0x25, 0xc9, 0x90, 0x38, 0x6f, 0xdb, 0xf0, 0xcc, 0xfb, 0x8e, + 0x1e, 0x97, 0x59, 0x3e, 0xd5, 0x60, 0x4e, 0xe6, 0x05, 0x28, 0xed, 0x49, + 0x79, 0x13, 0x4b, 0xba, 0x48, 0xdb, 0x2f, 0xf9, 0x72, 0xd3, 0x39, 0xca, + 0xfe, 0x1f, 0xd8, 0x34, 0x72, 0xf5, 0xb4, 0x40, 0xcf, 0x31, 0x01, 0xc3, + 0xec, 0xde, 0x11, 0x2d, 0x17, 0x5d, 0x1f, 0xb8, 0x50, 0xd1, 0x5e, 0x19, + 0xa7, 0x69, 0xde, 0x07, 0x33, 0x28, 0xca, 0x50, 0x95, 0xf9, 0xa7, 0x54, + 0xcb, 0x54, 0x86, 0x50, 0x45, 0xa9, 0xf9, 0x49, 0x02, 0x03, 0x01, 0x00, + 0x01, 0xa3, 0x82, 0x01, 0x6b, 0x30, 0x82, 0x01, 0x67, 0x30, 0x0f, 0x06, + 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, + 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, + 0x14, 0x08, 0x76, 0xcd, 0xcb, 0x07, 0xff, 0x24, 0xf6, 0xc5, 0xcd, 0xed, + 0xbb, 0x90, 0xbc, 0xe2, 0x84, 0x37, 0x46, 0x75, 0xf7, 0x30, 0x52, 0x06, + 0x03, 0x55, 0x1d, 0x23, 0x04, 0x4b, 0x30, 0x49, 0xa1, 0x42, 0xa4, 0x40, + 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, + 0x02, 0x50, 0x4c, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x0a, + 0x13, 0x12, 0x55, 0x6e, 0x69, 0x7a, 0x65, 0x74, 0x6f, 0x20, 0x53, 0x70, + 0x2e, 0x20, 0x7a, 0x20, 0x6f, 0x2e, 0x6f, 0x2e, 0x31, 0x12, 0x30, 0x10, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x43, 0x65, 0x72, 0x74, 0x75, + 0x6d, 0x20, 0x43, 0x41, 0x82, 0x03, 0x01, 0x00, 0x20, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, + 0x06, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x25, 0x30, 0x23, + 0x30, 0x21, 0xa0, 0x1f, 0xa0, 0x1d, 0x86, 0x1b, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x63, 0x65, 0x72, 0x74, 0x75, + 0x6d, 0x2e, 0x70, 0x6c, 0x2f, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, + 0x68, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, + 0x5c, 0x30, 0x5a, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x30, 0x01, 0x86, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x73, 0x75, 0x62, 0x63, 0x61, 0x2e, 0x6f, 0x63, 0x73, 0x70, 0x2d, 0x63, + 0x65, 0x72, 0x74, 0x75, 0x6d, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x2e, 0x06, + 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x22, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x6f, 0x72, 0x79, 0x2e, 0x63, 0x65, 0x72, 0x74, 0x75, 0x6d, 0x2e, + 0x70, 0x6c, 0x2f, 0x63, 0x61, 0x2e, 0x63, 0x65, 0x72, 0x30, 0x39, 0x06, + 0x03, 0x55, 0x1d, 0x20, 0x04, 0x32, 0x30, 0x30, 0x30, 0x2e, 0x06, 0x04, + 0x55, 0x1d, 0x20, 0x00, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x18, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x63, 0x65, 0x72, 0x74, 0x75, + 0x6d, 0x2e, 0x70, 0x6c, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x01, 0x00, 0x8d, 0xe6, 0xfd, 0x40, 0x66, 0xa3, 0x4c, 0x9c, + 0xa7, 0xab, 0xa1, 0xda, 0x84, 0xdd, 0x1c, 0x30, 0x07, 0xe6, 0xdb, 0xc7, + 0x2d, 0xec, 0x83, 0xa1, 0x56, 0xe4, 0x1d, 0x3c, 0x26, 0xa1, 0xa5, 0x09, + 0x2b, 0xe8, 0x7d, 0x62, 0xbe, 0xb2, 0x75, 0x94, 0xdd, 0x08, 0xf2, 0x7f, + 0x28, 0x41, 0xe4, 0x80, 0x67, 0x02, 0x4e, 0x8a, 0x8f, 0xc3, 0x35, 0xd0, + 0xd5, 0xa9, 0x27, 0x28, 0xea, 0xd2, 0xf4, 0xab, 0x06, 0x86, 0x43, 0xae, + 0x8c, 0xe3, 0xf9, 0x88, 0x7d, 0xe0, 0xdb, 0xbd, 0x42, 0x81, 0x80, 0x02, + 0x12, 0x75, 0xb2, 0xe8, 0x17, 0x71, 0xab, 0x21, 0x95, 0x31, 0x46, 0x42, + 0x0d, 0x88, 0x10, 0x39, 0xd3, 0x6f, 0xec, 0x2f, 0x42, 0xea, 0x40, 0x53, + 0x62, 0xbf, 0xeb, 0xca, 0x78, 0x9e, 0xab, 0xa2, 0xd5, 0x2e, 0x05, 0xea, + 0x33, 0xab, 0xe9, 0xd6, 0x97, 0x94, 0x42, 0x5e, 0x04, 0xed, 0x2c, 0xed, + 0x6a, 0x9c, 0x7a, 0x95, 0x7d, 0x05, 0x2a, 0x05, 0x7f, 0x08, 0x5d, 0x66, + 0xad, 0x61, 0xd4, 0x76, 0xac, 0x75, 0x96, 0x97, 0x73, 0x63, 0xbd, 0x1a, + 0x41, 0x59, 0x29, 0xa5, 0x5e, 0x22, 0x83, 0xc3, 0x8b, 0x59, 0xfa, 0x9a, + 0xa2, 0xf6, 0xbd, 0x30, 0xbf, 0x72, 0x1d, 0x1c, 0x99, 0x86, 0x9c, 0xf2, + 0x85, 0x3c, 0x1d, 0xf7, 0x26, 0x96, 0x2f, 0x2e, 0xf9, 0x02, 0xb1, 0xb5, + 0xa9, 0x50, 0xe8, 0x38, 0xfa, 0x9b, 0x0a, 0x5e, 0xb4, 0x04, 0xc0, 0xce, + 0x4e, 0x39, 0x2c, 0xca, 0x0b, 0x5b, 0x62, 0xf0, 0x4d, 0x58, 0x50, 0x34, + 0x99, 0xe6, 0x9a, 0x2c, 0xd2, 0x90, 0xd7, 0x09, 0x81, 0xd6, 0xc0, 0xaa, + 0x5e, 0xce, 0xfe, 0xd2, 0xf7, 0xa1, 0xba, 0x4b, 0xd9, 0xd6, 0x86, 0x8e, + 0x19, 0x1f, 0xa6, 0x06, 0x47, 0x42, 0x72, 0xe0, 0x56, 0x0a, 0x00, 0x1c, + 0x78, 0xb9, 0x8d, 0xcc, 0x99, 0x04, 0x37, 0x49, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 48:e9:94:40:d4:36:49:1c:b8:b8:82:3d:09:43:94:c7 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=GeoTrust Inc., OU=(c) 2008 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G3 + Validity + Not Before: Jun 10 00:00:00 2014 GMT + Not After : Jun 9 23:59:59 2024 GMT + Subject: C=US, O=GeoTrust Inc., CN=RapidSSL SHA256 CA - G2 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c4:95:63:28:d0:4e:30:45:af:8b:97:34:14:45: + f8:5c:58:4a:fa:33:8e:6e:9c:60:ab:f3:86:ff:34: + 74:b2:2b:be:a1:8c:d5:a2:a3:60:7a:40:b9:e1:fc: + 22:ca:67:ba:60:aa:c7:9a:f9:06:7f:ee:f7:ba:85: + 05:b0:03:ff:72:ae:15:41:4a:98:64:d7:17:4b:54: + ef:05:c6:98:07:93:27:3e:4f:dc:0f:c6:7b:8b:e7: + f3:06:5e:8d:e8:b4:ae:29:b4:1e:1e:2d:16:90:d3: + ea:aa:e7:8c:3b:6d:af:36:59:ff:c5:0a:fa:c7:4c: + bd:36:8b:64:c4:4a:f5:ce:33:f9:07:be:7f:45:90: + a8:08:14:b0:d0:a5:4f:df:82:80:da:1b:ee:c3:13: + b0:98:f5:0f:f9:7e:76:b5:e6:b9:5d:68:b9:5c:50: + 90:89:a4:36:b1:70:16:ea:b1:10:b5:6a:76:df:e1: + bb:fc:78:f2:72:99:cf:c9:a2:d4:73:54:77:bf:c0: + 39:77:e5:ae:12:c5:78:5a:19:45:d4:41:19:d3:7c: + f5:6f:99:6b:d7:8b:bc:2d:09:9d:4b:10:61:c0:da: + 52:c3:af:22:43:c6:eb:37:7e:63:74:30:0d:6a:71: + 8e:de:5d:5b:8a:c8:c5:d7:9b:29:e8:ae:b6:25:61: + 81:eb + Exponent: 65537 (0x10001) + X509v3 extensions: + Authority Information Access: + OCSP - URI:http://g.symcd.com + + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Certificate Policies: + Policy: 2.16.840.1.113733.1.7.54 + CPS: http://www.geotrust.com/resources/cps + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://g.symcb.com/GeoTrustPCA-G3.crl + + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Alternative Name: + DirName:/CN=SymantecPKI-1-697 + X509v3 Subject Key Identifier: + 4C:F4:BF:E8:3B:BE:C2:24:F3:1B:47:3B:B5:6E:48:8E:16:AB:AF:12 + X509v3 Authority Key Identifier: + keyid:C4:79:CA:8E:A1:4E:03:1D:1C:DC:6B:DB:31:5B:94:3E:3F:30:7F:2D + + Signature Algorithm: sha256WithRSAEncryption + 7a:53:b5:de:b6:ef:52:a3:5f:8a:f5:89:f1:42:cc:5e:46:88: + ae:a5:08:87:51:de:0f:0f:02:eb:0c:82:78:e3:73:7d:71:bd: + 43:e9:ca:8a:3f:e0:25:92:9b:33:33:74:49:5e:00:d9:73:14: + 1c:0b:46:76:1c:8a:0d:4d:8c:6c:7e:4b:f7:60:d8:81:78:a0: + 78:d0:25:62:ab:10:ca:22:e8:1c:19:dd:52:83:64:05:e5:87: + 66:ae:e7:7a:a4:3b:3e:d8:70:7a:76:a2:67:39:d4:c9:fa:e5: + b7:1e:41:e2:09:39:88:1c:18:55:0a:c4:41:af:b2:f3:f3:0f: + 42:14:61:74:81:e3:da:87:5a:9a:4d:8b:d3:c9:8f:89:66:13: + 29:11:e4:ff:e2:df:8e:96:0c:5a:a1:aa:6b:9b:fd:fc:03:3b: + 55:0d:a6:a2:25:48:17:1f:42:a8:da:6c:7e:69:6e:a0:df:67: + d2:6d:f4:0e:6a:12:79:f5:7c:c8:a5:32:1c:c4:31:b2:e6:bb: + a8:6b:6a:a2:8a:60:69:c0:57:7d:b2:f2:31:0c:98:65:32:ec: + 08:5a:ce:c6:98:e9:21:97:3f:2c:79:29:03:f5:f6:94:2b:53: + 31:f3:93:68:57:e1:d7:4f:3a:d1:61:a1:60:ce:b9:ab:98:ae: + 35:54:63:8b +-----BEGIN CERTIFICATE----- +MIIEtTCCA52gAwIBAgIQSOmUQNQ2SRy4uII9CUOUxzANBgkqhkiG9w0BAQsFADCB +mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT +MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eSAtIEczMB4XDTE0MDYxMDAwMDAwMFoXDTI0MDYwOTIzNTk1OVowRzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xIDAeBgNVBAMTF1JhcGlk +U1NMIFNIQTI1NiBDQSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAxJVjKNBOMEWvi5c0FEX4XFhK+jOObpxgq/OG/zR0siu+oYzVoqNgekC54fwi +yme6YKrHmvkGf+73uoUFsAP/cq4VQUqYZNcXS1TvBcaYB5MnPk/cD8Z7i+fzBl6N +6LSuKbQeHi0WkNPqqueMO22vNln/xQr6x0y9NotkxEr1zjP5B75/RZCoCBSw0KVP +34KA2hvuwxOwmPUP+X52tea5XWi5XFCQiaQ2sXAW6rEQtWp23+G7/HjycpnPyaLU +c1R3v8A5d+WuEsV4WhlF1EEZ03z1b5lr14u8LQmdSxBhwNpSw68iQ8brN35jdDAN +anGO3l1bisjF15sp6K62JWGB6wIDAQABo4IBSTCCAUUwLgYIKwYBBQUHAQEEIjAg +MB4GCCsGAQUFBzABhhJodHRwOi8vZy5zeW1jZC5jb20wEgYDVR0TAQH/BAgwBgEB +/wIBADBMBgNVHSAERTBDMEEGCmCGSAGG+EUBBzYwMzAxBggrBgEFBQcCARYlaHR0 +cDovL3d3dy5nZW90cnVzdC5jb20vcmVzb3VyY2VzL2NwczA2BgNVHR8ELzAtMCug +KaAnhiVodHRwOi8vZy5zeW1jYi5jb20vR2VvVHJ1c3RQQ0EtRzMuY3JsMA4GA1Ud +DwEB/wQEAwIBBjApBgNVHREEIjAgpB4wHDEaMBgGA1UEAxMRU3ltYW50ZWNQS0kt +MS02OTcwHQYDVR0OBBYEFEz0v+g7vsIk8xtHO7VuSI4Wq68SMB8GA1UdIwQYMBaA +FMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQB6U7Xetu9S +o1+K9YnxQsxeRoiupQiHUd4PDwLrDIJ443N9cb1D6cqKP+AlkpszM3RJXgDZcxQc +C0Z2HIoNTYxsfkv3YNiBeKB40CViqxDKIugcGd1Sg2QF5Ydmrud6pDs+2HB6dqJn +OdTJ+uW3HkHiCTmIHBhVCsRBr7Lz8w9CFGF0gePah1qaTYvTyY+JZhMpEeT/4t+O +lgxaoaprm/38AztVDaaiJUgXH0Ko2mx+aW6g32fSbfQOahJ59XzIpTIcxDGy5ruo +a2qiimBpwFd9svIxDJhlMuwIWs7GmOkhlz8seSkD9faUK1Mx85NoV+HXTzrRYaFg +zrmrmK41VGOL +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert32[] = { + 0x30, 0x82, 0x04, 0xb5, 0x30, 0x82, 0x03, 0x9d, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x48, 0xe9, 0x94, 0x40, 0xd4, 0x36, 0x49, 0x1c, 0xb8, + 0xb8, 0x82, 0x3d, 0x09, 0x43, 0x94, 0xc7, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, + 0x98, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, + 0x63, 0x2e, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, + 0x30, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x47, 0x65, + 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, + 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, + 0x79, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d, + 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x1e, 0x17, + 0x0d, 0x31, 0x34, 0x30, 0x36, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x36, 0x30, 0x39, 0x32, 0x33, + 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x47, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x20, 0x30, 0x1e, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x17, 0x52, 0x61, 0x70, 0x69, 0x64, + 0x53, 0x53, 0x4c, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x43, + 0x41, 0x20, 0x2d, 0x20, 0x47, 0x32, 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, 0xc4, 0x95, 0x63, 0x28, 0xd0, 0x4e, 0x30, 0x45, 0xaf, + 0x8b, 0x97, 0x34, 0x14, 0x45, 0xf8, 0x5c, 0x58, 0x4a, 0xfa, 0x33, 0x8e, + 0x6e, 0x9c, 0x60, 0xab, 0xf3, 0x86, 0xff, 0x34, 0x74, 0xb2, 0x2b, 0xbe, + 0xa1, 0x8c, 0xd5, 0xa2, 0xa3, 0x60, 0x7a, 0x40, 0xb9, 0xe1, 0xfc, 0x22, + 0xca, 0x67, 0xba, 0x60, 0xaa, 0xc7, 0x9a, 0xf9, 0x06, 0x7f, 0xee, 0xf7, + 0xba, 0x85, 0x05, 0xb0, 0x03, 0xff, 0x72, 0xae, 0x15, 0x41, 0x4a, 0x98, + 0x64, 0xd7, 0x17, 0x4b, 0x54, 0xef, 0x05, 0xc6, 0x98, 0x07, 0x93, 0x27, + 0x3e, 0x4f, 0xdc, 0x0f, 0xc6, 0x7b, 0x8b, 0xe7, 0xf3, 0x06, 0x5e, 0x8d, + 0xe8, 0xb4, 0xae, 0x29, 0xb4, 0x1e, 0x1e, 0x2d, 0x16, 0x90, 0xd3, 0xea, + 0xaa, 0xe7, 0x8c, 0x3b, 0x6d, 0xaf, 0x36, 0x59, 0xff, 0xc5, 0x0a, 0xfa, + 0xc7, 0x4c, 0xbd, 0x36, 0x8b, 0x64, 0xc4, 0x4a, 0xf5, 0xce, 0x33, 0xf9, + 0x07, 0xbe, 0x7f, 0x45, 0x90, 0xa8, 0x08, 0x14, 0xb0, 0xd0, 0xa5, 0x4f, + 0xdf, 0x82, 0x80, 0xda, 0x1b, 0xee, 0xc3, 0x13, 0xb0, 0x98, 0xf5, 0x0f, + 0xf9, 0x7e, 0x76, 0xb5, 0xe6, 0xb9, 0x5d, 0x68, 0xb9, 0x5c, 0x50, 0x90, + 0x89, 0xa4, 0x36, 0xb1, 0x70, 0x16, 0xea, 0xb1, 0x10, 0xb5, 0x6a, 0x76, + 0xdf, 0xe1, 0xbb, 0xfc, 0x78, 0xf2, 0x72, 0x99, 0xcf, 0xc9, 0xa2, 0xd4, + 0x73, 0x54, 0x77, 0xbf, 0xc0, 0x39, 0x77, 0xe5, 0xae, 0x12, 0xc5, 0x78, + 0x5a, 0x19, 0x45, 0xd4, 0x41, 0x19, 0xd3, 0x7c, 0xf5, 0x6f, 0x99, 0x6b, + 0xd7, 0x8b, 0xbc, 0x2d, 0x09, 0x9d, 0x4b, 0x10, 0x61, 0xc0, 0xda, 0x52, + 0xc3, 0xaf, 0x22, 0x43, 0xc6, 0xeb, 0x37, 0x7e, 0x63, 0x74, 0x30, 0x0d, + 0x6a, 0x71, 0x8e, 0xde, 0x5d, 0x5b, 0x8a, 0xc8, 0xc5, 0xd7, 0x9b, 0x29, + 0xe8, 0xae, 0xb6, 0x25, 0x61, 0x81, 0xeb, 0x02, 0x03, 0x01, 0x00, 0x01, + 0xa3, 0x82, 0x01, 0x49, 0x30, 0x82, 0x01, 0x45, 0x30, 0x2e, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x22, 0x30, 0x20, + 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, + 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73, + 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03, + 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, + 0xff, 0x02, 0x01, 0x00, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, + 0x45, 0x30, 0x43, 0x30, 0x41, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, + 0xf8, 0x45, 0x01, 0x07, 0x36, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x36, + 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0xa0, + 0x29, 0xa0, 0x27, 0x86, 0x25, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x50, 0x43, 0x41, 0x2d, + 0x47, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x29, + 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, + 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, + 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, + 0x31, 0x2d, 0x36, 0x39, 0x37, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, + 0x04, 0x16, 0x04, 0x14, 0x4c, 0xf4, 0xbf, 0xe8, 0x3b, 0xbe, 0xc2, 0x24, + 0xf3, 0x1b, 0x47, 0x3b, 0xb5, 0x6e, 0x48, 0x8e, 0x16, 0xab, 0xaf, 0x12, + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, + 0x14, 0xc4, 0x79, 0xca, 0x8e, 0xa1, 0x4e, 0x03, 0x1d, 0x1c, 0xdc, 0x6b, + 0xdb, 0x31, 0x5b, 0x94, 0x3e, 0x3f, 0x30, 0x7f, 0x2d, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, + 0x03, 0x82, 0x01, 0x01, 0x00, 0x7a, 0x53, 0xb5, 0xde, 0xb6, 0xef, 0x52, + 0xa3, 0x5f, 0x8a, 0xf5, 0x89, 0xf1, 0x42, 0xcc, 0x5e, 0x46, 0x88, 0xae, + 0xa5, 0x08, 0x87, 0x51, 0xde, 0x0f, 0x0f, 0x02, 0xeb, 0x0c, 0x82, 0x78, + 0xe3, 0x73, 0x7d, 0x71, 0xbd, 0x43, 0xe9, 0xca, 0x8a, 0x3f, 0xe0, 0x25, + 0x92, 0x9b, 0x33, 0x33, 0x74, 0x49, 0x5e, 0x00, 0xd9, 0x73, 0x14, 0x1c, + 0x0b, 0x46, 0x76, 0x1c, 0x8a, 0x0d, 0x4d, 0x8c, 0x6c, 0x7e, 0x4b, 0xf7, + 0x60, 0xd8, 0x81, 0x78, 0xa0, 0x78, 0xd0, 0x25, 0x62, 0xab, 0x10, 0xca, + 0x22, 0xe8, 0x1c, 0x19, 0xdd, 0x52, 0x83, 0x64, 0x05, 0xe5, 0x87, 0x66, + 0xae, 0xe7, 0x7a, 0xa4, 0x3b, 0x3e, 0xd8, 0x70, 0x7a, 0x76, 0xa2, 0x67, + 0x39, 0xd4, 0xc9, 0xfa, 0xe5, 0xb7, 0x1e, 0x41, 0xe2, 0x09, 0x39, 0x88, + 0x1c, 0x18, 0x55, 0x0a, 0xc4, 0x41, 0xaf, 0xb2, 0xf3, 0xf3, 0x0f, 0x42, + 0x14, 0x61, 0x74, 0x81, 0xe3, 0xda, 0x87, 0x5a, 0x9a, 0x4d, 0x8b, 0xd3, + 0xc9, 0x8f, 0x89, 0x66, 0x13, 0x29, 0x11, 0xe4, 0xff, 0xe2, 0xdf, 0x8e, + 0x96, 0x0c, 0x5a, 0xa1, 0xaa, 0x6b, 0x9b, 0xfd, 0xfc, 0x03, 0x3b, 0x55, + 0x0d, 0xa6, 0xa2, 0x25, 0x48, 0x17, 0x1f, 0x42, 0xa8, 0xda, 0x6c, 0x7e, + 0x69, 0x6e, 0xa0, 0xdf, 0x67, 0xd2, 0x6d, 0xf4, 0x0e, 0x6a, 0x12, 0x79, + 0xf5, 0x7c, 0xc8, 0xa5, 0x32, 0x1c, 0xc4, 0x31, 0xb2, 0xe6, 0xbb, 0xa8, + 0x6b, 0x6a, 0xa2, 0x8a, 0x60, 0x69, 0xc0, 0x57, 0x7d, 0xb2, 0xf2, 0x31, + 0x0c, 0x98, 0x65, 0x32, 0xec, 0x08, 0x5a, 0xce, 0xc6, 0x98, 0xe9, 0x21, + 0x97, 0x3f, 0x2c, 0x79, 0x29, 0x03, 0xf5, 0xf6, 0x94, 0x2b, 0x53, 0x31, + 0xf3, 0x93, 0x68, 0x57, 0xe1, 0xd7, 0x4f, 0x3a, 0xd1, 0x61, 0xa1, 0x60, + 0xce, 0xb9, 0xab, 0x98, 0xae, 0x35, 0x54, 0x63, 0x8b, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 0c:79:a9:44:b0:8c:11:95:20:92:61:5f:e2:6b:1d:83 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA + Validity + Not Before: Oct 22 12:00:00 2013 GMT + Not After : Oct 22 12:00:00 2028 GMT + Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert SHA2 Extended Validation Server CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:d7:53:a4:04:51:f8:99:a6:16:48:4b:67:27:aa: + 93:49:d0:39:ed:0c:b0:b0:00:87:f1:67:28:86:85: + 8c:8e:63:da:bc:b1:40:38:e2:d3:f5:ec:a5:05:18: + b8:3d:3e:c5:99:17:32:ec:18:8c:fa:f1:0c:a6:64: + 21:85:cb:07:10:34:b0:52:88:2b:1f:68:9b:d2:b1: + 8f:12:b0:b3:d2:e7:88:1f:1f:ef:38:77:54:53:5f: + 80:79:3f:2e:1a:aa:a8:1e:4b:2b:0d:ab:b7:63:b9: + 35:b7:7d:14:bc:59:4b:df:51:4a:d2:a1:e2:0c:e2: + 90:82:87:6a:ae:ea:d7:64:d6:98:55:e8:fd:af:1a: + 50:6c:54:bc:11:f2:fd:4a:f2:9d:bb:7f:0e:f4:d5: + be:8e:16:89:12:55:d8:c0:71:34:ee:f6:dc:2d:ec: + c4:87:25:86:8d:d8:21:e4:b0:4d:0c:89:dc:39:26: + 17:dd:f6:d7:94:85:d8:04:21:70:9d:6f:6f:ff:5c: + ba:19:e1:45:cb:56:57:28:7e:1c:0d:41:57:aa:b7: + b8:27:bb:b1:e4:fa:2a:ef:21:23:75:1a:ad:2d:9b: + 86:35:8c:9c:77:b5:73:ad:d8:94:2d:e4:f3:0c:9d: + ee:c1:4e:62:7e:17:c0:71:9e:2c:de:f1:f9:10:28: + 19:33 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + X509v3 Extended Key Usage: + TLS Web Server Authentication, TLS Web Client Authentication + Authority Information Access: + OCSP - URI:http://ocsp.digicert.com + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl4.digicert.com/DigiCertHighAssuranceEVRootCA.crl + + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: https://www.digicert.com/CPS + + X509v3 Subject Key Identifier: + 3D:D3:50:A5:D6:A0:AD:EE:F3:4A:60:0A:65:D3:21:D4:F8:F8:D6:0F + X509v3 Authority Key Identifier: + keyid:B1:3E:C3:69:03:F8:BF:47:01:D4:98:26:1A:08:02:EF:63:64:2B:C3 + + Signature Algorithm: sha256WithRSAEncryption + 9d:b6:d0:90:86:e1:86:02:ed:c5:a0:f0:34:1c:74:c1:8d:76: + cc:86:0a:a8:f0:4a:8a:42:d6:3f:c8:a9:4d:ad:7c:08:ad:e6: + b6:50:b8:a2:1a:4d:88:07:b1:29:21:dc:e7:da:c6:3c:21:e0: + e3:11:49:70:ac:7a:1d:01:a4:ca:11:3a:57:ab:7d:57:2a:40: + 74:fd:d3:1d:85:18:50:df:57:47:75:a1:7d:55:20:2e:47:37: + 50:72:8c:7f:82:1b:d2:62:8f:2d:03:5a:da:c3:c8:a1:ce:2c: + 52:a2:00:63:eb:73:ba:71:c8:49:27:23:97:64:85:9e:38:0e: + ad:63:68:3c:ba:52:81:58:79:a3:2c:0c:df:de:6d:eb:31:f2: + ba:a0:7c:6c:f1:2c:d4:e1:bd:77:84:37:03:ce:32:b5:c8:9a: + 81:1a:4a:92:4e:3b:46:9a:85:fe:83:a2:f9:9e:8c:a3:cc:0d: + 5e:b3:3d:cf:04:78:8f:14:14:7b:32:9c:c7:00:a6:5c:c4:b5: + a1:55:8d:5a:56:68:a4:22:70:aa:3c:81:71:d9:9d:a8:45:3b: + f4:e5:f6:a2:51:dd:c7:7b:62:e8:6f:0c:74:eb:b8:da:f8:bf: + 87:0d:79:50:91:90:9b:18:3b:91:59:27:f1:35:28:13:ab:26: + 7e:d5:f7:7a +-----BEGIN CERTIFICATE----- +MIIEtjCCA56gAwIBAgIQDHmpRLCMEZUgkmFf4msdgzANBgkqhkiG9w0BAQsFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowdTEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTE0MDIGA1UEAxMrRGlnaUNlcnQgU0hBMiBFeHRlbmRlZCBW +YWxpZGF0aW9uIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBANdTpARR+JmmFkhLZyeqk0nQOe0MsLAAh/FnKIaFjI5j2ryxQDji0/XspQUY +uD0+xZkXMuwYjPrxDKZkIYXLBxA0sFKIKx9om9KxjxKws9LniB8f7zh3VFNfgHk/ +LhqqqB5LKw2rt2O5Nbd9FLxZS99RStKh4gzikIKHaq7q12TWmFXo/a8aUGxUvBHy +/Urynbt/DvTVvo4WiRJV2MBxNO723C3sxIclho3YIeSwTQyJ3DkmF93215SF2AQh +cJ1vb/9cuhnhRctWVyh+HA1BV6q3uCe7seT6Ku8hI3UarS2bhjWMnHe1c63YlC3k +8wyd7sFOYn4XwHGeLN7x+RAoGTMCAwEAAaOCAUkwggFFMBIGA1UdEwEB/wQIMAYB +Af8CAQAwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF +BQcDAjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp +Z2ljZXJ0LmNvbTBLBgNVHR8ERDBCMECgPqA8hjpodHRwOi8vY3JsNC5kaWdpY2Vy +dC5jb20vRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3JsMD0GA1UdIAQ2 +MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5j +b20vQ1BTMB0GA1UdDgQWBBQ901Cl1qCt7vNKYApl0yHU+PjWDzAfBgNVHSMEGDAW +gBSxPsNpA/i/RwHUmCYaCALvY2QrwzANBgkqhkiG9w0BAQsFAAOCAQEAnbbQkIbh +hgLtxaDwNBx0wY12zIYKqPBKikLWP8ipTa18CK3mtlC4ohpNiAexKSHc59rGPCHg +4xFJcKx6HQGkyhE6V6t9VypAdP3THYUYUN9XR3WhfVUgLkc3UHKMf4Ib0mKPLQNa +2sPIoc4sUqIAY+tzunHISScjl2SFnjgOrWNoPLpSgVh5oywM395t6zHyuqB8bPEs +1OG9d4Q3A84ytciagRpKkk47RpqF/oOi+Z6Mo8wNXrM9zwR4jxQUezKcxwCmXMS1 +oVWNWlZopCJwqjyBcdmdqEU79OX2olHdx3ti6G8MdOu42vi/hw15UJGQmxg7kVkn +8TUoE6smftX3eg== +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert33[] = { + 0x30, 0x82, 0x04, 0xb6, 0x30, 0x82, 0x03, 0x9e, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x0c, 0x79, 0xa9, 0x44, 0xb0, 0x8c, 0x11, 0x95, 0x20, + 0x92, 0x61, 0x5f, 0xe2, 0x6b, 0x1d, 0x83, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x6c, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, + 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, + 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, + 0x77, 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, + 0x63, 0x6f, 0x6d, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x22, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x48, + 0x69, 0x67, 0x68, 0x20, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, + 0x65, 0x20, 0x45, 0x56, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, + 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x32, 0x32, 0x31, 0x32, + 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x31, 0x30, 0x32, + 0x32, 0x31, 0x32, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x75, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x44, 0x69, + 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x10, 0x77, 0x77, 0x77, + 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, + 0x6d, 0x31, 0x34, 0x30, 0x32, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2b, + 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, 0x72, 0x74, 0x20, 0x53, 0x48, 0x41, + 0x32, 0x20, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 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, 0xd7, 0x53, 0xa4, 0x04, 0x51, 0xf8, 0x99, 0xa6, + 0x16, 0x48, 0x4b, 0x67, 0x27, 0xaa, 0x93, 0x49, 0xd0, 0x39, 0xed, 0x0c, + 0xb0, 0xb0, 0x00, 0x87, 0xf1, 0x67, 0x28, 0x86, 0x85, 0x8c, 0x8e, 0x63, + 0xda, 0xbc, 0xb1, 0x40, 0x38, 0xe2, 0xd3, 0xf5, 0xec, 0xa5, 0x05, 0x18, + 0xb8, 0x3d, 0x3e, 0xc5, 0x99, 0x17, 0x32, 0xec, 0x18, 0x8c, 0xfa, 0xf1, + 0x0c, 0xa6, 0x64, 0x21, 0x85, 0xcb, 0x07, 0x10, 0x34, 0xb0, 0x52, 0x88, + 0x2b, 0x1f, 0x68, 0x9b, 0xd2, 0xb1, 0x8f, 0x12, 0xb0, 0xb3, 0xd2, 0xe7, + 0x88, 0x1f, 0x1f, 0xef, 0x38, 0x77, 0x54, 0x53, 0x5f, 0x80, 0x79, 0x3f, + 0x2e, 0x1a, 0xaa, 0xa8, 0x1e, 0x4b, 0x2b, 0x0d, 0xab, 0xb7, 0x63, 0xb9, + 0x35, 0xb7, 0x7d, 0x14, 0xbc, 0x59, 0x4b, 0xdf, 0x51, 0x4a, 0xd2, 0xa1, + 0xe2, 0x0c, 0xe2, 0x90, 0x82, 0x87, 0x6a, 0xae, 0xea, 0xd7, 0x64, 0xd6, + 0x98, 0x55, 0xe8, 0xfd, 0xaf, 0x1a, 0x50, 0x6c, 0x54, 0xbc, 0x11, 0xf2, + 0xfd, 0x4a, 0xf2, 0x9d, 0xbb, 0x7f, 0x0e, 0xf4, 0xd5, 0xbe, 0x8e, 0x16, + 0x89, 0x12, 0x55, 0xd8, 0xc0, 0x71, 0x34, 0xee, 0xf6, 0xdc, 0x2d, 0xec, + 0xc4, 0x87, 0x25, 0x86, 0x8d, 0xd8, 0x21, 0xe4, 0xb0, 0x4d, 0x0c, 0x89, + 0xdc, 0x39, 0x26, 0x17, 0xdd, 0xf6, 0xd7, 0x94, 0x85, 0xd8, 0x04, 0x21, + 0x70, 0x9d, 0x6f, 0x6f, 0xff, 0x5c, 0xba, 0x19, 0xe1, 0x45, 0xcb, 0x56, + 0x57, 0x28, 0x7e, 0x1c, 0x0d, 0x41, 0x57, 0xaa, 0xb7, 0xb8, 0x27, 0xbb, + 0xb1, 0xe4, 0xfa, 0x2a, 0xef, 0x21, 0x23, 0x75, 0x1a, 0xad, 0x2d, 0x9b, + 0x86, 0x35, 0x8c, 0x9c, 0x77, 0xb5, 0x73, 0xad, 0xd8, 0x94, 0x2d, 0xe4, + 0xf3, 0x0c, 0x9d, 0xee, 0xc1, 0x4e, 0x62, 0x7e, 0x17, 0xc0, 0x71, 0x9e, + 0x2c, 0xde, 0xf1, 0xf9, 0x10, 0x28, 0x19, 0x33, 0x02, 0x03, 0x01, 0x00, + 0x01, 0xa3, 0x82, 0x01, 0x49, 0x30, 0x82, 0x01, 0x45, 0x30, 0x12, 0x06, + 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, + 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, + 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 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, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x01, 0x01, 0x04, 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x64, 0x69, + 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x4b, + 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x44, 0x30, 0x42, 0x30, 0x40, 0xa0, + 0x3e, 0xa0, 0x3c, 0x86, 0x3a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x63, 0x72, 0x6c, 0x34, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, + 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x44, 0x69, 0x67, 0x69, 0x43, 0x65, + 0x72, 0x74, 0x48, 0x69, 0x67, 0x68, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, + 0x6e, 0x63, 0x65, 0x45, 0x56, 0x52, 0x6f, 0x6f, 0x74, 0x43, 0x41, 0x2e, + 0x63, 0x72, 0x6c, 0x30, 0x3d, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, + 0x30, 0x34, 0x30, 0x32, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, + 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, + 0x16, 0x1c, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, + 0x77, 0x2e, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, + 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3d, 0xd3, 0x50, 0xa5, 0xd6, 0xa0, 0xad, + 0xee, 0xf3, 0x4a, 0x60, 0x0a, 0x65, 0xd3, 0x21, 0xd4, 0xf8, 0xf8, 0xd6, + 0x0f, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0xb1, 0x3e, 0xc3, 0x69, 0x03, 0xf8, 0xbf, 0x47, 0x01, 0xd4, + 0x98, 0x26, 0x1a, 0x08, 0x02, 0xef, 0x63, 0x64, 0x2b, 0xc3, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x9d, 0xb6, 0xd0, 0x90, 0x86, 0xe1, + 0x86, 0x02, 0xed, 0xc5, 0xa0, 0xf0, 0x34, 0x1c, 0x74, 0xc1, 0x8d, 0x76, + 0xcc, 0x86, 0x0a, 0xa8, 0xf0, 0x4a, 0x8a, 0x42, 0xd6, 0x3f, 0xc8, 0xa9, + 0x4d, 0xad, 0x7c, 0x08, 0xad, 0xe6, 0xb6, 0x50, 0xb8, 0xa2, 0x1a, 0x4d, + 0x88, 0x07, 0xb1, 0x29, 0x21, 0xdc, 0xe7, 0xda, 0xc6, 0x3c, 0x21, 0xe0, + 0xe3, 0x11, 0x49, 0x70, 0xac, 0x7a, 0x1d, 0x01, 0xa4, 0xca, 0x11, 0x3a, + 0x57, 0xab, 0x7d, 0x57, 0x2a, 0x40, 0x74, 0xfd, 0xd3, 0x1d, 0x85, 0x18, + 0x50, 0xdf, 0x57, 0x47, 0x75, 0xa1, 0x7d, 0x55, 0x20, 0x2e, 0x47, 0x37, + 0x50, 0x72, 0x8c, 0x7f, 0x82, 0x1b, 0xd2, 0x62, 0x8f, 0x2d, 0x03, 0x5a, + 0xda, 0xc3, 0xc8, 0xa1, 0xce, 0x2c, 0x52, 0xa2, 0x00, 0x63, 0xeb, 0x73, + 0xba, 0x71, 0xc8, 0x49, 0x27, 0x23, 0x97, 0x64, 0x85, 0x9e, 0x38, 0x0e, + 0xad, 0x63, 0x68, 0x3c, 0xba, 0x52, 0x81, 0x58, 0x79, 0xa3, 0x2c, 0x0c, + 0xdf, 0xde, 0x6d, 0xeb, 0x31, 0xf2, 0xba, 0xa0, 0x7c, 0x6c, 0xf1, 0x2c, + 0xd4, 0xe1, 0xbd, 0x77, 0x84, 0x37, 0x03, 0xce, 0x32, 0xb5, 0xc8, 0x9a, + 0x81, 0x1a, 0x4a, 0x92, 0x4e, 0x3b, 0x46, 0x9a, 0x85, 0xfe, 0x83, 0xa2, + 0xf9, 0x9e, 0x8c, 0xa3, 0xcc, 0x0d, 0x5e, 0xb3, 0x3d, 0xcf, 0x04, 0x78, + 0x8f, 0x14, 0x14, 0x7b, 0x32, 0x9c, 0xc7, 0x00, 0xa6, 0x5c, 0xc4, 0xb5, + 0xa1, 0x55, 0x8d, 0x5a, 0x56, 0x68, 0xa4, 0x22, 0x70, 0xaa, 0x3c, 0x81, + 0x71, 0xd9, 0x9d, 0xa8, 0x45, 0x3b, 0xf4, 0xe5, 0xf6, 0xa2, 0x51, 0xdd, + 0xc7, 0x7b, 0x62, 0xe8, 0x6f, 0x0c, 0x74, 0xeb, 0xb8, 0xda, 0xf8, 0xbf, + 0x87, 0x0d, 0x79, 0x50, 0x91, 0x90, 0x9b, 0x18, 0x3b, 0x91, 0x59, 0x27, + 0xf1, 0x35, 0x28, 0x13, 0xab, 0x26, 0x7e, 0xd5, 0xf7, 0x7a, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 36:34:9e:18:c9:9c:26:69:b6:56:2e:6c:e5:ad:71:32 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2008 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA - G3 + Validity + Not Before: May 23 00:00:00 2013 GMT + Not After : May 22 23:59:59 2023 GMT + Subject: C=US, O=thawte, Inc., CN=thawte SHA256 SSL CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:a3:63:2b:d4:ba:5d:38:ae:b0:cf:b9:4c:38:df: + 20:7d:f1:2b:47:71:1d:8b:68:f3:56:f9:9c:da:aa: + e5:84:26:de:a5:71:30:bc:f3:31:23:9d:e8:3b:80: + c8:66:57:75:b6:57:0e:db:93:f5:26:8e:70:ba:64: + 52:66:8a:2a:88:5c:44:18:4d:a8:a2:7c:bd:56:61: + 32:90:12:f9:35:87:48:60:b0:6e:90:67:44:01:8d: + e7:c9:0d:63:68:72:72:ab:63:3c:86:b8:1f:7d:ad: + 88:25:a7:6a:88:29:fb:59:c6:78:71:5f:2c:ba:89: + e6:d3:80:fd:57:ec:b9:51:5f:43:33:2e:7e:25:3b: + a4:04:d1:60:8c:b3:44:33:93:0c:ad:2a:b6:44:a2: + 19:3b:af:c4:90:6f:7b:05:87:86:9b:2c:6a:9d:2b: + 6c:77:c9:00:9f:c9:cf:ac:ed:3e:1b:f7:c3:f3:d9: + f8:6c:d4:a0:57:c4:fb:28:32:aa:33:f0:e6:ba:98: + df:e5:c2:4e:9c:74:bf:8a:48:c2:f2:1b:f0:77:40: + 41:07:04:b2:3a:d5:4c:c4:29:a9:11:40:3f:02:46: + f0:91:d5:d2:81:83:86:13:b3:31:ed:46:ab:a8:87: + 76:a9:99:7d:bc:cd:31:50:f4:a5:b5:dc:a5:32:b3: + 8b:8b + Exponent: 65537 (0x10001) + X509v3 extensions: + Authority Information Access: + OCSP - URI:http://ocsp.thawte.com + + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Certificate Policies: + Policy: 2.16.840.1.113733.1.7.54 + CPS: https://www.thawte.com/cps + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.thawte.com/ThawtePCA-G3.crl + + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Alternative Name: + DirName:/CN=VeriSignMPKI-2-415 + X509v3 Subject Key Identifier: + 2B:9A:35:AE:01:18:38:30:E1:70:7A:05:E0:11:76:A3:CE:BD:90:14 + X509v3 Authority Key Identifier: + keyid:AD:6C:AA:94:60:9C:ED:E4:FF:FA:3E:0A:74:2B:63:03:F7:B6:59:BF + + Signature Algorithm: sha256WithRSAEncryption + 74:a6:56:e8:af:93:96:19:fb:26:f9:0d:b0:44:a5:cd:e9:7a: + 48:03:74:01:6c:13:71:b7:e0:82:90:99:62:23:e3:d6:99:af: + f0:c7:1e:9e:a8:18:21:db:b4:94:3f:34:56:1b:99:55:2f:8e: + f0:45:33:32:b7:72:c1:13:5b:34:d3:f5:60:e5:2e:18:d1:5c: + c5:6a:c1:aa:87:50:0c:1c:9d:64:2b:ff:1b:dc:d5:2e:61:0b: + e7:b9:b6:91:53:86:d9:03:2a:d1:3d:7b:4a:da:2b:07:be:29: + f2:60:42:a9:91:1a:0e:2e:3c:d1:7d:a5:13:14:02:fa:ee:8b: + 8d:b6:c8:b8:3e:56:81:57:21:24:3f:65:c3:b4:c9:ce:5c:8d: + 46:ac:53:f3:f9:55:74:c8:2b:fd:d2:78:70:f5:f8:11:e5:f4: + a7:ad:20:f5:9d:f1:ec:70:f6:13:ac:e6:8c:8d:db:3f:c6:f2: + 79:0e:ab:52:f2:cc:1b:79:27:cf:16:b3:d6:f3:c6:36:80:43: + ec:c5:94:f0:dd:90:8d:f8:c6:52:46:56:eb:74:47:be:a6:f3: + 19:ae:71:4c:c0:e1:e7:d4:cf:ed:d4:06:28:2a:11:3c:ba:d9: + 41:6e:00:e7:81:37:93:e4:da:62:c6:1d:67:6f:63:b4:14:86: + d9:a6:62:f0 +-----BEGIN CERTIFICATE----- +MIIEwjCCA6qgAwIBAgIQNjSeGMmcJmm2Vi5s5a1xMjANBgkqhkiG9w0BAQsFADCB +rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV +BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0xMzA1MjMwMDAwMDBa +Fw0yMzA1MjIyMzU5NTlaMEMxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwx0aGF3dGUs +IEluYy4xHTAbBgNVBAMTFHRoYXd0ZSBTSEEyNTYgU1NMIENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo2Mr1LpdOK6wz7lMON8gffErR3Edi2jzVvmc +2qrlhCbepXEwvPMxI53oO4DIZld1tlcO25P1Jo5wumRSZooqiFxEGE2oony9VmEy +kBL5NYdIYLBukGdEAY3nyQ1jaHJyq2M8hrgffa2IJadqiCn7WcZ4cV8suonm04D9 +V+y5UV9DMy5+JTukBNFgjLNEM5MMrSq2RKIZO6/EkG97BYeGmyxqnStsd8kAn8nP +rO0+G/fD89n4bNSgV8T7KDKqM/Dmupjf5cJOnHS/ikjC8hvwd0BBBwSyOtVMxCmp +EUA/AkbwkdXSgYOGE7Mx7UarqId2qZl9vM0xUPSltdylMrOLiwIDAQABo4IBRDCC +AUAwMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vb2NzcC50aGF3 +dGUuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwQQYDVR0gBDowODA2BgpghkgBhvhF +AQc2MCgwJgYIKwYBBQUHAgEWGmh0dHBzOi8vd3d3LnRoYXd0ZS5jb20vY3BzMDcG +A1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly9jcmwudGhhd3RlLmNvbS9UaGF3dGVQQ0Et +RzMuY3JsMA4GA1UdDwEB/wQEAwIBBjAqBgNVHREEIzAhpB8wHTEbMBkGA1UEAxMS +VmVyaVNpZ25NUEtJLTItNDE1MB0GA1UdDgQWBBQrmjWuARg4MOFwegXgEXajzr2Q +FDAfBgNVHSMEGDAWgBStbKqUYJzt5P/6Pgp0K2MD97ZZvzANBgkqhkiG9w0BAQsF +AAOCAQEAdKZW6K+Tlhn7JvkNsESlzel6SAN0AWwTcbfggpCZYiPj1pmv8McenqgY +Idu0lD80VhuZVS+O8EUzMrdywRNbNNP1YOUuGNFcxWrBqodQDBydZCv/G9zVLmEL +57m2kVOG2QMq0T17StorB74p8mBCqZEaDi480X2lExQC+u6LjbbIuD5WgVchJD9l +w7TJzlyNRqxT8/lVdMgr/dJ4cPX4EeX0p60g9Z3x7HD2E6zmjI3bP8byeQ6rUvLM +G3knzxaz1vPGNoBD7MWU8N2QjfjGUkZW63RHvqbzGa5xTMDh59TP7dQGKCoRPLrZ +QW4A54E3k+TaYsYdZ29jtBSG2aZi8A== +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert34[] = { + 0x30, 0x82, 0x04, 0xc2, 0x30, 0x82, 0x03, 0xaa, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x36, 0x34, 0x9e, 0x18, 0xc9, 0x9c, 0x26, 0x69, 0xb6, + 0x56, 0x2e, 0x6c, 0xe5, 0xad, 0x71, 0x32, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, + 0xae, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, + 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44, + 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06, + 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, + 0x30, 0x38, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, + 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, + 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x1b, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, + 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x1e, 0x17, 0x0d, 0x31, + 0x33, 0x30, 0x35, 0x32, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, + 0x17, 0x0d, 0x32, 0x33, 0x30, 0x35, 0x32, 0x32, 0x32, 0x33, 0x35, 0x39, + 0x35, 0x39, 0x5a, 0x30, 0x43, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x13, 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, + 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x14, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x53, + 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 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, 0xa3, 0x63, 0x2b, + 0xd4, 0xba, 0x5d, 0x38, 0xae, 0xb0, 0xcf, 0xb9, 0x4c, 0x38, 0xdf, 0x20, + 0x7d, 0xf1, 0x2b, 0x47, 0x71, 0x1d, 0x8b, 0x68, 0xf3, 0x56, 0xf9, 0x9c, + 0xda, 0xaa, 0xe5, 0x84, 0x26, 0xde, 0xa5, 0x71, 0x30, 0xbc, 0xf3, 0x31, + 0x23, 0x9d, 0xe8, 0x3b, 0x80, 0xc8, 0x66, 0x57, 0x75, 0xb6, 0x57, 0x0e, + 0xdb, 0x93, 0xf5, 0x26, 0x8e, 0x70, 0xba, 0x64, 0x52, 0x66, 0x8a, 0x2a, + 0x88, 0x5c, 0x44, 0x18, 0x4d, 0xa8, 0xa2, 0x7c, 0xbd, 0x56, 0x61, 0x32, + 0x90, 0x12, 0xf9, 0x35, 0x87, 0x48, 0x60, 0xb0, 0x6e, 0x90, 0x67, 0x44, + 0x01, 0x8d, 0xe7, 0xc9, 0x0d, 0x63, 0x68, 0x72, 0x72, 0xab, 0x63, 0x3c, + 0x86, 0xb8, 0x1f, 0x7d, 0xad, 0x88, 0x25, 0xa7, 0x6a, 0x88, 0x29, 0xfb, + 0x59, 0xc6, 0x78, 0x71, 0x5f, 0x2c, 0xba, 0x89, 0xe6, 0xd3, 0x80, 0xfd, + 0x57, 0xec, 0xb9, 0x51, 0x5f, 0x43, 0x33, 0x2e, 0x7e, 0x25, 0x3b, 0xa4, + 0x04, 0xd1, 0x60, 0x8c, 0xb3, 0x44, 0x33, 0x93, 0x0c, 0xad, 0x2a, 0xb6, + 0x44, 0xa2, 0x19, 0x3b, 0xaf, 0xc4, 0x90, 0x6f, 0x7b, 0x05, 0x87, 0x86, + 0x9b, 0x2c, 0x6a, 0x9d, 0x2b, 0x6c, 0x77, 0xc9, 0x00, 0x9f, 0xc9, 0xcf, + 0xac, 0xed, 0x3e, 0x1b, 0xf7, 0xc3, 0xf3, 0xd9, 0xf8, 0x6c, 0xd4, 0xa0, + 0x57, 0xc4, 0xfb, 0x28, 0x32, 0xaa, 0x33, 0xf0, 0xe6, 0xba, 0x98, 0xdf, + 0xe5, 0xc2, 0x4e, 0x9c, 0x74, 0xbf, 0x8a, 0x48, 0xc2, 0xf2, 0x1b, 0xf0, + 0x77, 0x40, 0x41, 0x07, 0x04, 0xb2, 0x3a, 0xd5, 0x4c, 0xc4, 0x29, 0xa9, + 0x11, 0x40, 0x3f, 0x02, 0x46, 0xf0, 0x91, 0xd5, 0xd2, 0x81, 0x83, 0x86, + 0x13, 0xb3, 0x31, 0xed, 0x46, 0xab, 0xa8, 0x87, 0x76, 0xa9, 0x99, 0x7d, + 0xbc, 0xcd, 0x31, 0x50, 0xf4, 0xa5, 0xb5, 0xdc, 0xa5, 0x32, 0xb3, 0x8b, + 0x8b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x44, 0x30, 0x82, + 0x01, 0x40, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x01, 0x01, 0x04, 0x26, 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x74, 0x68, 0x61, 0x77, + 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, + 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, + 0x01, 0x00, 0x30, 0x41, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3a, 0x30, + 0x38, 0x30, 0x36, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, + 0x01, 0x07, 0x36, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73, + 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, + 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x37, 0x06, + 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x30, 0x30, 0x2e, 0x30, 0x2c, 0xa0, 0x2a, + 0xa0, 0x28, 0x86, 0x26, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, + 0x72, 0x6c, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, 0x43, 0x41, 0x2d, + 0x47, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x2a, + 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x23, 0x30, 0x21, 0xa4, 0x1f, 0x30, + 0x1d, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, + 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x50, 0x4b, 0x49, + 0x2d, 0x32, 0x2d, 0x34, 0x31, 0x35, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, + 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2b, 0x9a, 0x35, 0xae, 0x01, 0x18, 0x38, + 0x30, 0xe1, 0x70, 0x7a, 0x05, 0xe0, 0x11, 0x76, 0xa3, 0xce, 0xbd, 0x90, + 0x14, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, + 0x80, 0x14, 0xad, 0x6c, 0xaa, 0x94, 0x60, 0x9c, 0xed, 0xe4, 0xff, 0xfa, + 0x3e, 0x0a, 0x74, 0x2b, 0x63, 0x03, 0xf7, 0xb6, 0x59, 0xbf, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x74, 0xa6, 0x56, 0xe8, 0xaf, 0x93, + 0x96, 0x19, 0xfb, 0x26, 0xf9, 0x0d, 0xb0, 0x44, 0xa5, 0xcd, 0xe9, 0x7a, + 0x48, 0x03, 0x74, 0x01, 0x6c, 0x13, 0x71, 0xb7, 0xe0, 0x82, 0x90, 0x99, + 0x62, 0x23, 0xe3, 0xd6, 0x99, 0xaf, 0xf0, 0xc7, 0x1e, 0x9e, 0xa8, 0x18, + 0x21, 0xdb, 0xb4, 0x94, 0x3f, 0x34, 0x56, 0x1b, 0x99, 0x55, 0x2f, 0x8e, + 0xf0, 0x45, 0x33, 0x32, 0xb7, 0x72, 0xc1, 0x13, 0x5b, 0x34, 0xd3, 0xf5, + 0x60, 0xe5, 0x2e, 0x18, 0xd1, 0x5c, 0xc5, 0x6a, 0xc1, 0xaa, 0x87, 0x50, + 0x0c, 0x1c, 0x9d, 0x64, 0x2b, 0xff, 0x1b, 0xdc, 0xd5, 0x2e, 0x61, 0x0b, + 0xe7, 0xb9, 0xb6, 0x91, 0x53, 0x86, 0xd9, 0x03, 0x2a, 0xd1, 0x3d, 0x7b, + 0x4a, 0xda, 0x2b, 0x07, 0xbe, 0x29, 0xf2, 0x60, 0x42, 0xa9, 0x91, 0x1a, + 0x0e, 0x2e, 0x3c, 0xd1, 0x7d, 0xa5, 0x13, 0x14, 0x02, 0xfa, 0xee, 0x8b, + 0x8d, 0xb6, 0xc8, 0xb8, 0x3e, 0x56, 0x81, 0x57, 0x21, 0x24, 0x3f, 0x65, + 0xc3, 0xb4, 0xc9, 0xce, 0x5c, 0x8d, 0x46, 0xac, 0x53, 0xf3, 0xf9, 0x55, + 0x74, 0xc8, 0x2b, 0xfd, 0xd2, 0x78, 0x70, 0xf5, 0xf8, 0x11, 0xe5, 0xf4, + 0xa7, 0xad, 0x20, 0xf5, 0x9d, 0xf1, 0xec, 0x70, 0xf6, 0x13, 0xac, 0xe6, + 0x8c, 0x8d, 0xdb, 0x3f, 0xc6, 0xf2, 0x79, 0x0e, 0xab, 0x52, 0xf2, 0xcc, + 0x1b, 0x79, 0x27, 0xcf, 0x16, 0xb3, 0xd6, 0xf3, 0xc6, 0x36, 0x80, 0x43, + 0xec, 0xc5, 0x94, 0xf0, 0xdd, 0x90, 0x8d, 0xf8, 0xc6, 0x52, 0x46, 0x56, + 0xeb, 0x74, 0x47, 0xbe, 0xa6, 0xf3, 0x19, 0xae, 0x71, 0x4c, 0xc0, 0xe1, + 0xe7, 0xd4, 0xcf, 0xed, 0xd4, 0x06, 0x28, 0x2a, 0x11, 0x3c, 0xba, 0xd9, + 0x41, 0x6e, 0x00, 0xe7, 0x81, 0x37, 0x93, 0xe4, 0xda, 0x62, 0xc6, 0x1d, + 0x67, 0x6f, 0x63, 0xb4, 0x14, 0x86, 0xd9, 0xa6, 0x62, 0xf0, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 41:82:12:7d:12:d9:c6:b3:21:39:43:12:56:64:00:b8 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=GeoTrust Inc., OU=(c) 2008 GeoTrust Inc. - For authorized use only, CN=GeoTrust Primary Certification Authority - G3 + Validity + Not Before: May 23 00:00:00 2013 GMT + Not After : May 22 23:59:59 2023 GMT + Subject: C=US, O=GeoTrust Inc., CN=GeoTrust SHA256 SSL CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:c6:a9:0b:5d:17:a5:7d:c6:cf:2a:ef:c6:66:d1: + 42:1e:5f:83:78:68:91:af:e6:a7:8b:f0:1d:44:01: + 0a:19:ca:9c:d4:8b:1d:e1:a1:90:a3:c1:5b:b4:d7: + 5b:6a:8b:fc:0e:49:1e:c2:62:29:fe:80:15:39:8b: + 81:2a:27:b5:fb:12:a8:05:22:0b:c5:2c:f5:d9:98: + dd:16:2f:3b:66:e7:62:a2:43:32:ac:8f:b5:85:c8: + 52:06:2c:5c:c0:77:fa:67:f7:83:e8:5e:05:8d:c8: + ab:a1:16:32:8a:d2:40:ec:86:3a:1c:23:a9:8d:b5: + 00:de:72:bd:85:55:fe:06:01:60:5d:ad:b3:e0:65: + 73:a5:92:14:9e:94:56:6f:93:ee:af:a9:3a:30:25: + 4a:8e:09:84:ef:b7:d2:d5:d7:9b:49:cd:e9:c0:5e: + 67:71:22:ac:50:90:43:20:5d:a1:a3:15:83:fd:fc: + a7:39:bc:6b:65:48:12:60:ff:dd:23:b3:3a:aa:f4: + 9f:9c:37:53:41:a2:47:93:81:33:09:e5:22:c6:c8: + 1c:49:a1:6e:8d:cc:83:b3:9a:cd:ea:43:f2:19:d3: + 24:cb:a8:29:ae:52:cc:f4:08:27:b0:84:ea:ce:27: + b5:e1:34:13:73:92:5c:87:86:2a:c6:b0:68:36:ad: + cb:09 + Exponent: 65537 (0x10001) + X509v3 extensions: + Authority Information Access: + OCSP - URI:http://pca-g3-ocsp.geotrust.com + + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Certificate Policies: + Policy: 2.16.840.1.113733.1.7.54 + CPS: http://www.geotrust.com/resources/cps + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.geotrust.com/GeoTrustPCA-G3.crl + + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Alternative Name: + DirName:/CN=VeriSignMPKI-2-416 + X509v3 Subject Key Identifier: + 14:67:8E:ED:83:4F:D6:1E:9D:40:04:0C:04:46:A1:70:34:B2:0F:72 + X509v3 Authority Key Identifier: + keyid:C4:79:CA:8E:A1:4E:03:1D:1C:DC:6B:DB:31:5B:94:3E:3F:30:7F:2D + + Signature Algorithm: sha256WithRSAEncryption + 10:10:ea:f2:10:d6:08:46:e2:c1:8f:3e:36:59:c8:2b:0f:fe: + 4d:ec:e3:f8:b6:56:31:78:25:d4:76:f2:08:dd:ef:3f:cd:8b: + 1c:7e:aa:7f:fc:0b:a8:23:64:51:b3:87:d6:09:fa:22:fa:c7: + 0a:51:e8:ce:b8:f6:03:70:e0:1b:5a:b9:b1:b2:93:11:10:f9: + 97:05:07:29:6c:6d:57:25:54:e8:f9:66:9b:0e:fb:db:9f:ee: + 96:6f:65:cb:1f:d8:55:ce:31:fa:cf:02:f4:d0:7f:50:66:ff: + 2f:79:9b:a5:c2:df:d6:cf:c8:15:83:96:84:98:b2:46:d4:5f: + 13:a8:3e:a7:34:9c:05:38:da:cf:d6:69:95:a9:26:87:76:01: + d7:b2:51:0f:81:69:46:26:1c:99:b6:83:58:e3:3b:58:8f:dc: + b4:71:c0:b9:bf:42:9c:1c:03:9e:e4:46:a8:ea:b9:c1:cd:f6: + 5b:a9:3c:96:fb:79:a4:33:73:a7:9e:78:b9:70:dc:72:74:c4: + 32:c8:00:1b:c9:ef:48:d3:fb:3a:9b:fa:fe:7a:9a:40:69:1c: + c8:da:28:37:0b:d3:a3:b9:7e:96:cc:2b:28:c3:56:6c:6f:e9: + db:52:b1:fa:9a:fb:e7:af:b5:97:a6:22:c3:c5:a8:93:b1:00: + c9:07:b2:7d +-----BEGIN CERTIFICATE----- +MIIExzCCA6+gAwIBAgIQQYISfRLZxrMhOUMSVmQAuDANBgkqhkiG9w0BAQsFADCB +mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT +MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eSAtIEczMB4XDTEzMDUyMzAwMDAwMFoXDTIzMDUyMjIzNTk1OVowRjELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHzAdBgNVBAMTFkdlb1Ry +dXN0IFNIQTI1NiBTU0wgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQDGqQtdF6V9xs8q78Zm0UIeX4N4aJGv5qeL8B1EAQoZypzUix3hoZCjwVu011tq +i/wOSR7CYin+gBU5i4EqJ7X7EqgFIgvFLPXZmN0WLztm52KiQzKsj7WFyFIGLFzA +d/pn94PoXgWNyKuhFjKK0kDshjocI6mNtQDecr2FVf4GAWBdrbPgZXOlkhSelFZv +k+6vqTowJUqOCYTvt9LV15tJzenAXmdxIqxQkEMgXaGjFYP9/Kc5vGtlSBJg/90j +szqq9J+cN1NBokeTgTMJ5SLGyBxJoW6NzIOzms3qQ/IZ0yTLqCmuUsz0CCewhOrO +J7XhNBNzklyHhirGsGg2rcsJAgMBAAGjggFcMIIBWDA7BggrBgEFBQcBAQQvMC0w +KwYIKwYBBQUHMAGGH2h0dHA6Ly9wY2EtZzMtb2NzcC5nZW90cnVzdC5jb20wEgYD +VR0TAQH/BAgwBgEB/wIBADBMBgNVHSAERTBDMEEGCmCGSAGG+EUBBzYwMzAxBggr +BgEFBQcCARYlaHR0cDovL3d3dy5nZW90cnVzdC5jb20vcmVzb3VyY2VzL2NwczA7 +BgNVHR8ENDAyMDCgLqAshipodHRwOi8vY3JsLmdlb3RydXN0LmNvbS9HZW9UcnVz +dFBDQS1HMy5jcmwwDgYDVR0PAQH/BAQDAgEGMCoGA1UdEQQjMCGkHzAdMRswGQYD +VQQDExJWZXJpU2lnbk1QS0ktMi00MTYwHQYDVR0OBBYEFBRnju2DT9YenUAEDARG +oXA0sg9yMB8GA1UdIwQYMBaAFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3 +DQEBCwUAA4IBAQAQEOryENYIRuLBjz42WcgrD/5N7OP4tlYxeCXUdvII3e8/zYsc +fqp//AuoI2RRs4fWCfoi+scKUejOuPYDcOAbWrmxspMREPmXBQcpbG1XJVTo+Wab +Dvvbn+6Wb2XLH9hVzjH6zwL00H9QZv8veZulwt/Wz8gVg5aEmLJG1F8TqD6nNJwF +ONrP1mmVqSaHdgHXslEPgWlGJhyZtoNY4ztYj9y0ccC5v0KcHAOe5Eao6rnBzfZb +qTyW+3mkM3Onnni5cNxydMQyyAAbye9I0/s6m/r+eppAaRzI2ig3C9OjuX6WzCso +w1Zsb+nbUrH6mvvnr7WXpiLDxaiTsQDJB7J9 +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert35[] = { + 0x30, 0x82, 0x04, 0xc7, 0x30, 0x82, 0x03, 0xaf, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x41, 0x82, 0x12, 0x7d, 0x12, 0xd9, 0xc6, 0xb3, 0x21, + 0x39, 0x43, 0x12, 0x56, 0x64, 0x00, 0xb8, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, + 0x98, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, + 0x63, 0x2e, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, + 0x30, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x47, 0x65, + 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, + 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, + 0x79, 0x31, 0x36, 0x30, 0x34, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2d, + 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x33, 0x30, 0x1e, 0x17, + 0x0d, 0x31, 0x33, 0x30, 0x35, 0x32, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x35, 0x32, 0x32, 0x32, 0x33, + 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x46, 0x31, 0x0b, 0x30, 0x09, 0x06, + 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, + 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, 0x65, 0x6f, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x16, 0x47, 0x65, 0x6f, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x20, 0x53, + 0x53, 0x4c, 0x20, 0x43, 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, 0xc6, 0xa9, 0x0b, 0x5d, 0x17, 0xa5, 0x7d, 0xc6, 0xcf, 0x2a, + 0xef, 0xc6, 0x66, 0xd1, 0x42, 0x1e, 0x5f, 0x83, 0x78, 0x68, 0x91, 0xaf, + 0xe6, 0xa7, 0x8b, 0xf0, 0x1d, 0x44, 0x01, 0x0a, 0x19, 0xca, 0x9c, 0xd4, + 0x8b, 0x1d, 0xe1, 0xa1, 0x90, 0xa3, 0xc1, 0x5b, 0xb4, 0xd7, 0x5b, 0x6a, + 0x8b, 0xfc, 0x0e, 0x49, 0x1e, 0xc2, 0x62, 0x29, 0xfe, 0x80, 0x15, 0x39, + 0x8b, 0x81, 0x2a, 0x27, 0xb5, 0xfb, 0x12, 0xa8, 0x05, 0x22, 0x0b, 0xc5, + 0x2c, 0xf5, 0xd9, 0x98, 0xdd, 0x16, 0x2f, 0x3b, 0x66, 0xe7, 0x62, 0xa2, + 0x43, 0x32, 0xac, 0x8f, 0xb5, 0x85, 0xc8, 0x52, 0x06, 0x2c, 0x5c, 0xc0, + 0x77, 0xfa, 0x67, 0xf7, 0x83, 0xe8, 0x5e, 0x05, 0x8d, 0xc8, 0xab, 0xa1, + 0x16, 0x32, 0x8a, 0xd2, 0x40, 0xec, 0x86, 0x3a, 0x1c, 0x23, 0xa9, 0x8d, + 0xb5, 0x00, 0xde, 0x72, 0xbd, 0x85, 0x55, 0xfe, 0x06, 0x01, 0x60, 0x5d, + 0xad, 0xb3, 0xe0, 0x65, 0x73, 0xa5, 0x92, 0x14, 0x9e, 0x94, 0x56, 0x6f, + 0x93, 0xee, 0xaf, 0xa9, 0x3a, 0x30, 0x25, 0x4a, 0x8e, 0x09, 0x84, 0xef, + 0xb7, 0xd2, 0xd5, 0xd7, 0x9b, 0x49, 0xcd, 0xe9, 0xc0, 0x5e, 0x67, 0x71, + 0x22, 0xac, 0x50, 0x90, 0x43, 0x20, 0x5d, 0xa1, 0xa3, 0x15, 0x83, 0xfd, + 0xfc, 0xa7, 0x39, 0xbc, 0x6b, 0x65, 0x48, 0x12, 0x60, 0xff, 0xdd, 0x23, + 0xb3, 0x3a, 0xaa, 0xf4, 0x9f, 0x9c, 0x37, 0x53, 0x41, 0xa2, 0x47, 0x93, + 0x81, 0x33, 0x09, 0xe5, 0x22, 0xc6, 0xc8, 0x1c, 0x49, 0xa1, 0x6e, 0x8d, + 0xcc, 0x83, 0xb3, 0x9a, 0xcd, 0xea, 0x43, 0xf2, 0x19, 0xd3, 0x24, 0xcb, + 0xa8, 0x29, 0xae, 0x52, 0xcc, 0xf4, 0x08, 0x27, 0xb0, 0x84, 0xea, 0xce, + 0x27, 0xb5, 0xe1, 0x34, 0x13, 0x73, 0x92, 0x5c, 0x87, 0x86, 0x2a, 0xc6, + 0xb0, 0x68, 0x36, 0xad, 0xcb, 0x09, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, + 0x82, 0x01, 0x5c, 0x30, 0x82, 0x01, 0x58, 0x30, 0x3b, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x2f, 0x30, 0x2d, 0x30, + 0x2b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, + 0x1f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x70, 0x63, 0x61, 0x2d, + 0x67, 0x33, 0x2d, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x65, 0x6f, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x12, 0x06, 0x03, + 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, + 0xff, 0x02, 0x01, 0x00, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, + 0x45, 0x30, 0x43, 0x30, 0x41, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, + 0xf8, 0x45, 0x01, 0x07, 0x36, 0x30, 0x33, 0x30, 0x31, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x67, 0x65, 0x6f, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x3b, + 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0xa0, + 0x2e, 0xa0, 0x2c, 0x86, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x63, 0x72, 0x6c, 0x2e, 0x67, 0x65, 0x6f, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x47, 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x50, 0x43, 0x41, 0x2d, 0x47, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, + 0x02, 0x01, 0x06, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x23, + 0x30, 0x21, 0xa4, 0x1f, 0x30, 0x1d, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x12, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, + 0x6e, 0x4d, 0x50, 0x4b, 0x49, 0x2d, 0x32, 0x2d, 0x34, 0x31, 0x36, 0x30, + 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x14, 0x67, + 0x8e, 0xed, 0x83, 0x4f, 0xd6, 0x1e, 0x9d, 0x40, 0x04, 0x0c, 0x04, 0x46, + 0xa1, 0x70, 0x34, 0xb2, 0x0f, 0x72, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, + 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xc4, 0x79, 0xca, 0x8e, 0xa1, + 0x4e, 0x03, 0x1d, 0x1c, 0xdc, 0x6b, 0xdb, 0x31, 0x5b, 0x94, 0x3e, 0x3f, + 0x30, 0x7f, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x10, + 0x10, 0xea, 0xf2, 0x10, 0xd6, 0x08, 0x46, 0xe2, 0xc1, 0x8f, 0x3e, 0x36, + 0x59, 0xc8, 0x2b, 0x0f, 0xfe, 0x4d, 0xec, 0xe3, 0xf8, 0xb6, 0x56, 0x31, + 0x78, 0x25, 0xd4, 0x76, 0xf2, 0x08, 0xdd, 0xef, 0x3f, 0xcd, 0x8b, 0x1c, + 0x7e, 0xaa, 0x7f, 0xfc, 0x0b, 0xa8, 0x23, 0x64, 0x51, 0xb3, 0x87, 0xd6, + 0x09, 0xfa, 0x22, 0xfa, 0xc7, 0x0a, 0x51, 0xe8, 0xce, 0xb8, 0xf6, 0x03, + 0x70, 0xe0, 0x1b, 0x5a, 0xb9, 0xb1, 0xb2, 0x93, 0x11, 0x10, 0xf9, 0x97, + 0x05, 0x07, 0x29, 0x6c, 0x6d, 0x57, 0x25, 0x54, 0xe8, 0xf9, 0x66, 0x9b, + 0x0e, 0xfb, 0xdb, 0x9f, 0xee, 0x96, 0x6f, 0x65, 0xcb, 0x1f, 0xd8, 0x55, + 0xce, 0x31, 0xfa, 0xcf, 0x02, 0xf4, 0xd0, 0x7f, 0x50, 0x66, 0xff, 0x2f, + 0x79, 0x9b, 0xa5, 0xc2, 0xdf, 0xd6, 0xcf, 0xc8, 0x15, 0x83, 0x96, 0x84, + 0x98, 0xb2, 0x46, 0xd4, 0x5f, 0x13, 0xa8, 0x3e, 0xa7, 0x34, 0x9c, 0x05, + 0x38, 0xda, 0xcf, 0xd6, 0x69, 0x95, 0xa9, 0x26, 0x87, 0x76, 0x01, 0xd7, + 0xb2, 0x51, 0x0f, 0x81, 0x69, 0x46, 0x26, 0x1c, 0x99, 0xb6, 0x83, 0x58, + 0xe3, 0x3b, 0x58, 0x8f, 0xdc, 0xb4, 0x71, 0xc0, 0xb9, 0xbf, 0x42, 0x9c, + 0x1c, 0x03, 0x9e, 0xe4, 0x46, 0xa8, 0xea, 0xb9, 0xc1, 0xcd, 0xf6, 0x5b, + 0xa9, 0x3c, 0x96, 0xfb, 0x79, 0xa4, 0x33, 0x73, 0xa7, 0x9e, 0x78, 0xb9, + 0x70, 0xdc, 0x72, 0x74, 0xc4, 0x32, 0xc8, 0x00, 0x1b, 0xc9, 0xef, 0x48, + 0xd3, 0xfb, 0x3a, 0x9b, 0xfa, 0xfe, 0x7a, 0x9a, 0x40, 0x69, 0x1c, 0xc8, + 0xda, 0x28, 0x37, 0x0b, 0xd3, 0xa3, 0xb9, 0x7e, 0x96, 0xcc, 0x2b, 0x28, + 0xc3, 0x56, 0x6c, 0x6f, 0xe9, 0xdb, 0x52, 0xb1, 0xfa, 0x9a, 0xfb, 0xe7, + 0xaf, 0xb5, 0x97, 0xa6, 0x22, 0xc3, 0xc5, 0xa8, 0x93, 0xb1, 0x00, 0xc9, + 0x07, 0xb2, 0x7d, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 7 (0x7) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., CN=Go Daddy Root Certificate Authority - G2 + Validity + Not Before: May 3 07:00:00 2011 GMT + Not After : May 3 07:00:00 2031 GMT + Subject: C=US, ST=Arizona, L=Scottsdale, O=GoDaddy.com, Inc., OU=http://certs.godaddy.com/repository/, CN=Go Daddy Secure Certificate Authority - G2 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:b9:e0:cb:10:d4:af:76:bd:d4:93:62:eb:30:64: + b8:81:08:6c:c3:04:d9:62:17:8e:2f:ff:3e:65:cf: + 8f:ce:62:e6:3c:52:1c:da:16:45:4b:55:ab:78:6b: + 63:83:62:90:ce:0f:69:6c:99:c8:1a:14:8b:4c:cc: + 45:33:ea:88:dc:9e:a3:af:2b:fe:80:61:9d:79:57: + c4:cf:2e:f4:3f:30:3c:5d:47:fc:9a:16:bc:c3:37: + 96:41:51:8e:11:4b:54:f8:28:be:d0:8c:be:f0:30: + 38:1e:f3:b0:26:f8:66:47:63:6d:de:71:26:47:8f: + 38:47:53:d1:46:1d:b4:e3:dc:00:ea:45:ac:bd:bc: + 71:d9:aa:6f:00:db:db:cd:30:3a:79:4f:5f:4c:47: + f8:1d:ef:5b:c2:c4:9d:60:3b:b1:b2:43:91:d8:a4: + 33:4e:ea:b3:d6:27:4f:ad:25:8a:a5:c6:f4:d5:d0: + a6:ae:74:05:64:57:88:b5:44:55:d4:2d:2a:3a:3e: + f8:b8:bd:e9:32:0a:02:94:64:c4:16:3a:50:f1:4a: + ae:e7:79:33:af:0c:20:07:7f:e8:df:04:39:c2:69: + 02:6c:63:52:fa:77:c1:1b:c8:74:87:c8:b9:93:18: + 50:54:35:4b:69:4e:bc:3b:d3:49:2e:1f:dc:c1:d2: + 52:fb + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 40:C2:BD:27:8E:CC:34:83:30:A2:33:D7:FB:6C:B3:F0:B4:2C:80:CE + X509v3 Authority Key Identifier: + keyid:3A:9A:85:07:10:67:28:B6:EF:F6:BD:05:41:6E:20:C1:94:DA:0F:DE + + Authority Information Access: + OCSP - URI:http://ocsp.godaddy.com/ + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.godaddy.com/gdroot-g2.crl + + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: https://certs.godaddy.com/repository/ + + Signature Algorithm: sha256WithRSAEncryption + 08:7e:6c:93:10:c8:38:b8:96:a9:90:4b:ff:a1:5f:4f:04:ef: + 6c:3e:9c:88:06:c9:50:8f:a6:73:f7:57:31:1b:be:bc:e4:2f: + db:f8:ba:d3:5b:e0:b4:e7:e6:79:62:0e:0c:a2:d7:6a:63:73: + 31:b5:f5:a8:48:a4:3b:08:2d:a2:5d:90:d7:b4:7c:25:4f:11: + 56:30:c4:b6:44:9d:7b:2c:9d:e5:5e:e6:ef:0c:61:aa:bf:e4: + 2a:1b:ee:84:9e:b8:83:7d:c1:43:ce:44:a7:13:70:0d:91:1f: + f4:c8:13:ad:83:60:d9:d8:72:a8:73:24:1e:b5:ac:22:0e:ca: + 17:89:62:58:44:1b:ab:89:25:01:00:0f:cd:c4:1b:62:db:51: + b4:d3:0f:51:2a:9b:f4:bc:73:fc:76:ce:36:a4:cd:d9:d8:2c: + ea:ae:9b:f5:2a:b2:90:d1:4d:75:18:8a:3f:8a:41:90:23:7d: + 5b:4b:fe:a4:03:58:9b:46:b2:c3:60:60:83:f8:7d:50:41:ce: + c2:a1:90:c3:bb:ef:02:2f:d2:15:54:ee:44:15:d9:0a:ae:a7: + 8a:33:ed:b1:2d:76:36:26:dc:04:eb:9f:f7:61:1f:15:dc:87: + 6f:ee:46:96:28:ad:a1:26:7d:0a:09:a7:2e:04:a3:8d:bc:f8: + bc:04:30:01 +-----BEGIN CERTIFICATE----- +MIIE0DCCA7igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAwMFoXDTMxMDUwMzA3 +MDAwMFowgbQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UE +CxMkaHR0cDovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQD +EypHbyBEYWRkeSBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC54MsQ1K92vdSTYuswZLiBCGzD +BNliF44v/z5lz4/OYuY8UhzaFkVLVat4a2ODYpDOD2lsmcgaFItMzEUz6ojcnqOv +K/6AYZ15V8TPLvQ/MDxdR/yaFrzDN5ZBUY4RS1T4KL7QjL7wMDge87Am+GZHY23e +cSZHjzhHU9FGHbTj3ADqRay9vHHZqm8A29vNMDp5T19MR/gd71vCxJ1gO7GyQ5HY +pDNO6rPWJ0+tJYqlxvTV0KaudAVkV4i1RFXULSo6Pvi4vekyCgKUZMQWOlDxSq7n +eTOvDCAHf+jfBDnCaQJsY1L6d8EbyHSHyLmTGFBUNUtpTrw700kuH9zB0lL7AgMB +AAGjggEaMIIBFjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV +HQ4EFgQUQMK9J47MNIMwojPX+2yz8LQsgM4wHwYDVR0jBBgwFoAUOpqFBxBnKLbv +9r0FQW4gwZTaD94wNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v +b2NzcC5nb2RhZGR5LmNvbS8wNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2NybC5n +b2RhZGR5LmNvbS9nZHJvb3QtZzIuY3JsMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEG +CCsGAQUFBwIBFiVodHRwczovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkv +MA0GCSqGSIb3DQEBCwUAA4IBAQAIfmyTEMg4uJapkEv/oV9PBO9sPpyIBslQj6Zz +91cxG7685C/b+LrTW+C05+Z5Yg4MotdqY3MxtfWoSKQ7CC2iXZDXtHwlTxFWMMS2 +RJ17LJ3lXubvDGGqv+QqG+6EnriDfcFDzkSnE3ANkR/0yBOtg2DZ2HKocyQetawi +DsoXiWJYRBuriSUBAA/NxBti21G00w9RKpv0vHP8ds42pM3Z2Czqrpv1KrKQ0U11 +GIo/ikGQI31bS/6kA1ibRrLDYGCD+H1QQc7CoZDDu+8CL9IVVO5EFdkKrqeKM+2x +LXY2JtwE65/3YR8V3Idv7kaWKK2hJn0KCacuBKONvPi8BDAB +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert36[] = { + 0x30, 0x82, 0x04, 0xd0, 0x30, 0x82, 0x03, 0xb8, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x01, 0x07, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x83, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, + 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, + 0x6c, 0x65, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x11, 0x47, 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, + 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x28, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, + 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x1e, 0x17, + 0x0d, 0x31, 0x31, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37, 0x30, 0x30, 0x30, + 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x31, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37, + 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x81, 0xb4, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, + 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, + 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x47, + 0x6f, 0x44, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2c, 0x20, + 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2d, 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x13, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, + 0x72, 0x74, 0x73, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, + 0x72, 0x79, 0x2f, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x2a, 0x47, 0x6f, 0x20, 0x44, 0x61, 0x64, 0x64, 0x79, 0x20, 0x53, + 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 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, 0xb9, 0xe0, 0xcb, 0x10, 0xd4, 0xaf, 0x76, + 0xbd, 0xd4, 0x93, 0x62, 0xeb, 0x30, 0x64, 0xb8, 0x81, 0x08, 0x6c, 0xc3, + 0x04, 0xd9, 0x62, 0x17, 0x8e, 0x2f, 0xff, 0x3e, 0x65, 0xcf, 0x8f, 0xce, + 0x62, 0xe6, 0x3c, 0x52, 0x1c, 0xda, 0x16, 0x45, 0x4b, 0x55, 0xab, 0x78, + 0x6b, 0x63, 0x83, 0x62, 0x90, 0xce, 0x0f, 0x69, 0x6c, 0x99, 0xc8, 0x1a, + 0x14, 0x8b, 0x4c, 0xcc, 0x45, 0x33, 0xea, 0x88, 0xdc, 0x9e, 0xa3, 0xaf, + 0x2b, 0xfe, 0x80, 0x61, 0x9d, 0x79, 0x57, 0xc4, 0xcf, 0x2e, 0xf4, 0x3f, + 0x30, 0x3c, 0x5d, 0x47, 0xfc, 0x9a, 0x16, 0xbc, 0xc3, 0x37, 0x96, 0x41, + 0x51, 0x8e, 0x11, 0x4b, 0x54, 0xf8, 0x28, 0xbe, 0xd0, 0x8c, 0xbe, 0xf0, + 0x30, 0x38, 0x1e, 0xf3, 0xb0, 0x26, 0xf8, 0x66, 0x47, 0x63, 0x6d, 0xde, + 0x71, 0x26, 0x47, 0x8f, 0x38, 0x47, 0x53, 0xd1, 0x46, 0x1d, 0xb4, 0xe3, + 0xdc, 0x00, 0xea, 0x45, 0xac, 0xbd, 0xbc, 0x71, 0xd9, 0xaa, 0x6f, 0x00, + 0xdb, 0xdb, 0xcd, 0x30, 0x3a, 0x79, 0x4f, 0x5f, 0x4c, 0x47, 0xf8, 0x1d, + 0xef, 0x5b, 0xc2, 0xc4, 0x9d, 0x60, 0x3b, 0xb1, 0xb2, 0x43, 0x91, 0xd8, + 0xa4, 0x33, 0x4e, 0xea, 0xb3, 0xd6, 0x27, 0x4f, 0xad, 0x25, 0x8a, 0xa5, + 0xc6, 0xf4, 0xd5, 0xd0, 0xa6, 0xae, 0x74, 0x05, 0x64, 0x57, 0x88, 0xb5, + 0x44, 0x55, 0xd4, 0x2d, 0x2a, 0x3a, 0x3e, 0xf8, 0xb8, 0xbd, 0xe9, 0x32, + 0x0a, 0x02, 0x94, 0x64, 0xc4, 0x16, 0x3a, 0x50, 0xf1, 0x4a, 0xae, 0xe7, + 0x79, 0x33, 0xaf, 0x0c, 0x20, 0x07, 0x7f, 0xe8, 0xdf, 0x04, 0x39, 0xc2, + 0x69, 0x02, 0x6c, 0x63, 0x52, 0xfa, 0x77, 0xc1, 0x1b, 0xc8, 0x74, 0x87, + 0xc8, 0xb9, 0x93, 0x18, 0x50, 0x54, 0x35, 0x4b, 0x69, 0x4e, 0xbc, 0x3b, + 0xd3, 0x49, 0x2e, 0x1f, 0xdc, 0xc1, 0xd2, 0x52, 0xfb, 0x02, 0x03, 0x01, + 0x00, 0x01, 0xa3, 0x82, 0x01, 0x1a, 0x30, 0x82, 0x01, 0x16, 0x30, 0x0f, + 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, + 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, + 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, + 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x40, 0xc2, 0xbd, 0x27, 0x8e, 0xcc, + 0x34, 0x83, 0x30, 0xa2, 0x33, 0xd7, 0xfb, 0x6c, 0xb3, 0xf0, 0xb4, 0x2c, + 0x80, 0xce, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, + 0x16, 0x80, 0x14, 0x3a, 0x9a, 0x85, 0x07, 0x10, 0x67, 0x28, 0xb6, 0xef, + 0xf6, 0xbd, 0x05, 0x41, 0x6e, 0x20, 0xc1, 0x94, 0xda, 0x0f, 0xde, 0x30, + 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, + 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x35, 0x06, 0x03, 0x55, 0x1d, 0x1f, + 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0, 0x26, 0x86, 0x24, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x67, + 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, + 0x64, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x67, 0x32, 0x2e, 0x63, 0x72, 0x6c, + 0x30, 0x46, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3f, 0x30, 0x3d, 0x30, + 0x3b, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x33, 0x30, 0x31, 0x06, + 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x25, 0x68, + 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73, + 0x2e, 0x67, 0x6f, 0x64, 0x61, 0x64, 0x64, 0x79, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x08, 0x7e, 0x6c, 0x93, + 0x10, 0xc8, 0x38, 0xb8, 0x96, 0xa9, 0x90, 0x4b, 0xff, 0xa1, 0x5f, 0x4f, + 0x04, 0xef, 0x6c, 0x3e, 0x9c, 0x88, 0x06, 0xc9, 0x50, 0x8f, 0xa6, 0x73, + 0xf7, 0x57, 0x31, 0x1b, 0xbe, 0xbc, 0xe4, 0x2f, 0xdb, 0xf8, 0xba, 0xd3, + 0x5b, 0xe0, 0xb4, 0xe7, 0xe6, 0x79, 0x62, 0x0e, 0x0c, 0xa2, 0xd7, 0x6a, + 0x63, 0x73, 0x31, 0xb5, 0xf5, 0xa8, 0x48, 0xa4, 0x3b, 0x08, 0x2d, 0xa2, + 0x5d, 0x90, 0xd7, 0xb4, 0x7c, 0x25, 0x4f, 0x11, 0x56, 0x30, 0xc4, 0xb6, + 0x44, 0x9d, 0x7b, 0x2c, 0x9d, 0xe5, 0x5e, 0xe6, 0xef, 0x0c, 0x61, 0xaa, + 0xbf, 0xe4, 0x2a, 0x1b, 0xee, 0x84, 0x9e, 0xb8, 0x83, 0x7d, 0xc1, 0x43, + 0xce, 0x44, 0xa7, 0x13, 0x70, 0x0d, 0x91, 0x1f, 0xf4, 0xc8, 0x13, 0xad, + 0x83, 0x60, 0xd9, 0xd8, 0x72, 0xa8, 0x73, 0x24, 0x1e, 0xb5, 0xac, 0x22, + 0x0e, 0xca, 0x17, 0x89, 0x62, 0x58, 0x44, 0x1b, 0xab, 0x89, 0x25, 0x01, + 0x00, 0x0f, 0xcd, 0xc4, 0x1b, 0x62, 0xdb, 0x51, 0xb4, 0xd3, 0x0f, 0x51, + 0x2a, 0x9b, 0xf4, 0xbc, 0x73, 0xfc, 0x76, 0xce, 0x36, 0xa4, 0xcd, 0xd9, + 0xd8, 0x2c, 0xea, 0xae, 0x9b, 0xf5, 0x2a, 0xb2, 0x90, 0xd1, 0x4d, 0x75, + 0x18, 0x8a, 0x3f, 0x8a, 0x41, 0x90, 0x23, 0x7d, 0x5b, 0x4b, 0xfe, 0xa4, + 0x03, 0x58, 0x9b, 0x46, 0xb2, 0xc3, 0x60, 0x60, 0x83, 0xf8, 0x7d, 0x50, + 0x41, 0xce, 0xc2, 0xa1, 0x90, 0xc3, 0xbb, 0xef, 0x02, 0x2f, 0xd2, 0x15, + 0x54, 0xee, 0x44, 0x15, 0xd9, 0x0a, 0xae, 0xa7, 0x8a, 0x33, 0xed, 0xb1, + 0x2d, 0x76, 0x36, 0x26, 0xdc, 0x04, 0xeb, 0x9f, 0xf7, 0x61, 0x1f, 0x15, + 0xdc, 0x87, 0x6f, 0xee, 0x46, 0x96, 0x28, 0xad, 0xa1, 0x26, 0x7d, 0x0a, + 0x09, 0xa7, 0x2e, 0x04, 0xa3, 0x8d, 0xbc, 0xf8, 0xbc, 0x04, 0x30, 0x01, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 25:0c:e8:e0:30:61:2e:9f:2b:89:f7:05:4d:7c:f8:fd + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification Authority + Validity + Not Before: Nov 8 00:00:00 2006 GMT + Not After : Nov 7 23:59:59 2021 GMT + Subject: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:af:24:08:08:29:7a:35:9e:60:0c:aa:e7:4b:3b: + 4e:dc:7c:bc:3c:45:1c:bb:2b:e0:fe:29:02:f9:57: + 08:a3:64:85:15:27:f5:f1:ad:c8:31:89:5d:22:e8: + 2a:aa:a6:42:b3:8f:f8:b9:55:b7:b1:b7:4b:b3:fe: + 8f:7e:07:57:ec:ef:43:db:66:62:15:61:cf:60:0d: + a4:d8:de:f8:e0:c3:62:08:3d:54:13:eb:49:ca:59: + 54:85:26:e5:2b:8f:1b:9f:eb:f5:a1:91:c2:33:49: + d8:43:63:6a:52:4b:d2:8f:e8:70:51:4d:d1:89:69: + 7b:c7:70:f6:b3:dc:12:74:db:7b:5d:4b:56:d3:96: + bf:15:77:a1:b0:f4:a2:25:f2:af:1c:92:67:18:e5: + f4:06:04:ef:90:b9:e4:00:e4:dd:3a:b5:19:ff:02: + ba:f4:3c:ee:e0:8b:eb:37:8b:ec:f4:d7:ac:f2:f6: + f0:3d:af:dd:75:91:33:19:1d:1c:40:cb:74:24:19: + 21:93:d9:14:fe:ac:2a:52:c7:8f:d5:04:49:e4:8d: + 63:47:88:3c:69:83:cb:fe:47:bd:2b:7e:4f:c5:95: + ae:0e:9d:d4:d1:43:c0:67:73:e3:14:08:7e:e5:3f: + 9f:73:b8:33:0a:cf:5d:3f:34:87:96:8a:ee:53:e8: + 25:15 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.verisign.com/pca3.crl + + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: https://www.verisign.com/cps + + X509v3 Subject Key Identifier: + 7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33 + 1.3.6.1.5.5.7.1.12: + 0_.].[0Y0W0U..image/gif0!0.0...+..............k...j.H.,{..0%.#http://logo.verisign.com/vslogo.gif + Authority Information Access: + OCSP - URI:http://ocsp.verisign.com + + X509v3 Extended Key Usage: + TLS Web Server Authentication, TLS Web Client Authentication, Code Signing, Netscape Server Gated Crypto, 2.16.840.1.113733.1.8.1 + Signature Algorithm: sha1WithRSAEncryption + 13:02:dd:f8:e8:86:00:f2:5a:f8:f8:20:0c:59:88:62:07:ce: + ce:f7:4e:f9:bb:59:a1:98:e5:e1:38:dd:4e:bc:66:18:d3:ad: + eb:18:f2:0d:c9:6d:3e:4a:94:20:c3:3c:ba:bd:65:54:c6:af: + 44:b3:10:ad:2c:6b:3e:ab:d7:07:b6:b8:81:63:c5:f9:5e:2e: + e5:2a:67:ce:cd:33:0c:2a:d7:89:56:03:23:1f:b3:be:e8:3a: + 08:59:b4:ec:45:35:f7:8a:5b:ff:66:cf:50:af:c6:6d:57:8d: + 19:78:b7:b9:a2:d1:57:ea:1f:9a:4b:af:ba:c9:8e:12:7e:c6: + bd:ff +-----BEGIN CERTIFICATE----- +MIIE0DCCBDmgAwIBAgIQJQzo4DBhLp8rifcFTXz4/TANBgkqhkiG9w0BAQUFADBf +MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsT +LkNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw +HhcNMDYxMTA4MDAwMDAwWhcNMjExMTA3MjM1OTU5WjCByjELMAkGA1UEBhMCVVMx +FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz +dCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZv +ciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAz +IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8 +RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbext0uz/o9+B1fs70Pb +ZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhDY2pSS9KP6HBR +TdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/ +Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNH +iDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMB +AAGjggGbMIIBlzAPBgNVHRMBAf8EBTADAQH/MDEGA1UdHwQqMCgwJqAkoCKGIGh0 +dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMuY3JsMA4GA1UdDwEB/wQEAwIBBjA9 +BgNVHSAENjA0MDIGBFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVy +aXNpZ24uY29tL2NwczAdBgNVHQ4EFgQUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwbQYI +KwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQU +j+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24uY29t +L3ZzbG9nby5naWYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v +b2NzcC52ZXJpc2lnbi5jb20wPgYDVR0lBDcwNQYIKwYBBQUHAwEGCCsGAQUFBwMC +BggrBgEFBQcDAwYJYIZIAYb4QgQBBgpghkgBhvhFAQgBMA0GCSqGSIb3DQEBBQUA +A4GBABMC3fjohgDyWvj4IAxZiGIHzs73Tvm7WaGY5eE43U68ZhjTresY8g3JbT5K +lCDDPLq9ZVTGr0SzEK0saz6r1we2uIFjxfleLuUqZ87NMwwq14lWAyMfs77oOghZ +tOxFNfeKW/9mz1Cvxm1XjRl4t7mi0VfqH5pLr7rJjhJ+xr3/ +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert37[] = { + 0x30, 0x82, 0x04, 0xd0, 0x30, 0x82, 0x04, 0x39, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x25, 0x0c, 0xe8, 0xe0, 0x30, 0x61, 0x2e, 0x9f, 0x2b, + 0x89, 0xf7, 0x05, 0x4d, 0x7c, 0xf8, 0xfd, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5f, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, + 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, + 0x63, 0x2e, 0x31, 0x37, 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, + 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, + 0x1e, 0x17, 0x0d, 0x30, 0x36, 0x31, 0x31, 0x30, 0x38, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x31, 0x30, 0x37, + 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0xca, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56, 0x65, + 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, 0x56, + 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x31, 0x3a, 0x30, + 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, 0x63, 0x29, 0x20, + 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, + 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, + 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, + 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x45, 0x30, + 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56, 0x65, 0x72, 0x69, + 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x33, + 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 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, 0xaf, 0x24, 0x08, 0x08, 0x29, 0x7a, 0x35, + 0x9e, 0x60, 0x0c, 0xaa, 0xe7, 0x4b, 0x3b, 0x4e, 0xdc, 0x7c, 0xbc, 0x3c, + 0x45, 0x1c, 0xbb, 0x2b, 0xe0, 0xfe, 0x29, 0x02, 0xf9, 0x57, 0x08, 0xa3, + 0x64, 0x85, 0x15, 0x27, 0xf5, 0xf1, 0xad, 0xc8, 0x31, 0x89, 0x5d, 0x22, + 0xe8, 0x2a, 0xaa, 0xa6, 0x42, 0xb3, 0x8f, 0xf8, 0xb9, 0x55, 0xb7, 0xb1, + 0xb7, 0x4b, 0xb3, 0xfe, 0x8f, 0x7e, 0x07, 0x57, 0xec, 0xef, 0x43, 0xdb, + 0x66, 0x62, 0x15, 0x61, 0xcf, 0x60, 0x0d, 0xa4, 0xd8, 0xde, 0xf8, 0xe0, + 0xc3, 0x62, 0x08, 0x3d, 0x54, 0x13, 0xeb, 0x49, 0xca, 0x59, 0x54, 0x85, + 0x26, 0xe5, 0x2b, 0x8f, 0x1b, 0x9f, 0xeb, 0xf5, 0xa1, 0x91, 0xc2, 0x33, + 0x49, 0xd8, 0x43, 0x63, 0x6a, 0x52, 0x4b, 0xd2, 0x8f, 0xe8, 0x70, 0x51, + 0x4d, 0xd1, 0x89, 0x69, 0x7b, 0xc7, 0x70, 0xf6, 0xb3, 0xdc, 0x12, 0x74, + 0xdb, 0x7b, 0x5d, 0x4b, 0x56, 0xd3, 0x96, 0xbf, 0x15, 0x77, 0xa1, 0xb0, + 0xf4, 0xa2, 0x25, 0xf2, 0xaf, 0x1c, 0x92, 0x67, 0x18, 0xe5, 0xf4, 0x06, + 0x04, 0xef, 0x90, 0xb9, 0xe4, 0x00, 0xe4, 0xdd, 0x3a, 0xb5, 0x19, 0xff, + 0x02, 0xba, 0xf4, 0x3c, 0xee, 0xe0, 0x8b, 0xeb, 0x37, 0x8b, 0xec, 0xf4, + 0xd7, 0xac, 0xf2, 0xf6, 0xf0, 0x3d, 0xaf, 0xdd, 0x75, 0x91, 0x33, 0x19, + 0x1d, 0x1c, 0x40, 0xcb, 0x74, 0x24, 0x19, 0x21, 0x93, 0xd9, 0x14, 0xfe, + 0xac, 0x2a, 0x52, 0xc7, 0x8f, 0xd5, 0x04, 0x49, 0xe4, 0x8d, 0x63, 0x47, + 0x88, 0x3c, 0x69, 0x83, 0xcb, 0xfe, 0x47, 0xbd, 0x2b, 0x7e, 0x4f, 0xc5, + 0x95, 0xae, 0x0e, 0x9d, 0xd4, 0xd1, 0x43, 0xc0, 0x67, 0x73, 0xe3, 0x14, + 0x08, 0x7e, 0xe5, 0x3f, 0x9f, 0x73, 0xb8, 0x33, 0x0a, 0xcf, 0x5d, 0x3f, + 0x34, 0x87, 0x96, 0x8a, 0xee, 0x53, 0xe8, 0x25, 0x15, 0x02, 0x03, 0x01, + 0x00, 0x01, 0xa3, 0x82, 0x01, 0x9b, 0x30, 0x82, 0x01, 0x97, 0x30, 0x0f, + 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, + 0x01, 0x01, 0xff, 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2a, + 0x30, 0x28, 0x30, 0x26, 0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x76, 0x65, 0x72, + 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, + 0x61, 0x33, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x3d, + 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06, + 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x2a, 0x30, 0x28, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1c, 0x68, 0x74, 0x74, + 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x76, 0x65, 0x72, + 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, + 0x73, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, + 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3, + 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x6d, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0c, 0x04, 0x61, 0x30, 0x5f, + 0xa1, 0x5d, 0xa0, 0x5b, 0x30, 0x59, 0x30, 0x57, 0x30, 0x55, 0x16, 0x09, + 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x30, 0x21, 0x30, + 0x1f, 0x30, 0x07, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x04, 0x14, + 0x8f, 0xe5, 0xd3, 0x1a, 0x86, 0xac, 0x8d, 0x8e, 0x6b, 0xc3, 0xcf, 0x80, + 0x6a, 0xd4, 0x48, 0x18, 0x2c, 0x7b, 0x19, 0x2e, 0x30, 0x25, 0x16, 0x23, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, + 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x76, 0x73, 0x6c, 0x6f, 0x67, 0x6f, 0x2e, 0x67, 0x69, 0x66, 0x30, + 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, + 0x28, 0x30, 0x26, 0x30, 0x24, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, + 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x3e, 0x06, 0x03, 0x55, 0x1d, 0x25, + 0x04, 0x37, 0x30, 0x35, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, + 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, 0x06, 0x09, + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01, 0x06, 0x0a, 0x60, + 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x08, 0x01, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, + 0x03, 0x81, 0x81, 0x00, 0x13, 0x02, 0xdd, 0xf8, 0xe8, 0x86, 0x00, 0xf2, + 0x5a, 0xf8, 0xf8, 0x20, 0x0c, 0x59, 0x88, 0x62, 0x07, 0xce, 0xce, 0xf7, + 0x4e, 0xf9, 0xbb, 0x59, 0xa1, 0x98, 0xe5, 0xe1, 0x38, 0xdd, 0x4e, 0xbc, + 0x66, 0x18, 0xd3, 0xad, 0xeb, 0x18, 0xf2, 0x0d, 0xc9, 0x6d, 0x3e, 0x4a, + 0x94, 0x20, 0xc3, 0x3c, 0xba, 0xbd, 0x65, 0x54, 0xc6, 0xaf, 0x44, 0xb3, + 0x10, 0xad, 0x2c, 0x6b, 0x3e, 0xab, 0xd7, 0x07, 0xb6, 0xb8, 0x81, 0x63, + 0xc5, 0xf9, 0x5e, 0x2e, 0xe5, 0x2a, 0x67, 0xce, 0xcd, 0x33, 0x0c, 0x2a, + 0xd7, 0x89, 0x56, 0x03, 0x23, 0x1f, 0xb3, 0xbe, 0xe8, 0x3a, 0x08, 0x59, + 0xb4, 0xec, 0x45, 0x35, 0xf7, 0x8a, 0x5b, 0xff, 0x66, 0xcf, 0x50, 0xaf, + 0xc6, 0x6d, 0x57, 0x8d, 0x19, 0x78, 0xb7, 0xb9, 0xa2, 0xd1, 0x57, 0xea, + 0x1f, 0x9a, 0x4b, 0xaf, 0xba, 0xc9, 0x8e, 0x12, 0x7e, 0xc6, 0xbd, 0xff, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 2c:69:e1:2f:6a:67:0b:d9:9d:d2:0f:91:9e:f0:9e:51 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=thawte, Inc., OU=Certification Services Division, OU=(c) 2006 thawte, Inc. - For authorized use only, CN=thawte Primary Root CA + Validity + Not Before: Jun 10 00:00:00 2014 GMT + Not After : Jun 9 23:59:59 2024 GMT + Subject: C=US, O=thawte, Inc., OU=Domain Validated SSL, CN=thawte DV SSL CA - G2 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:ea:94:07:85:c8:41:2c:f6:83:12:6c:92:5f:ab: + 1f:00:d4:96:6f:74:cd:2e:11:e9:6c:0f:39:01:b9: + 48:90:40:39:4d:c4:a2:c8:79:6a:a5:9a:bd:91:44: + 65:77:54:ad:ff:25:5f:ee:42:fb:b3:02:0f:ea:5d: + 7a:dd:1a:54:9e:d7:73:42:9b:cc:79:5f:c5:4d:f4: + b7:0b:18:39:20:7a:dd:50:01:5d:34:45:5f:4c:11: + 0e:f5:87:26:26:b4:b0:f3:7e:71:a0:31:71:50:89: + 68:5a:63:8a:14:62:e5:8c:3a:16:55:0d:3e:eb:aa: + 80:1d:71:7a:e3:87:07:ab:bd:a2:74:cd:da:08:01: + 9d:1b:cc:27:88:8c:47:d4:69:25:42:d6:bb:50:6d: + 85:50:d0:48:82:0d:08:9f:e9:23:e3:42:c6:3c:98: + b8:bb:6e:c5:70:13:df:19:1d:01:fd:d2:b5:4e:e6: + 62:f4:07:fa:6b:7d:11:77:c4:62:4f:40:4e:a5:78: + 97:ab:2c:4d:0c:a7:7c:c3:c4:50:32:9f:d0:70:9b: + 0f:ff:ff:75:59:34:85:ad:49:d5:35:ee:4f:5b:d4: + d4:36:95:a0:7e:e8:c5:a1:1c:bd:13:4e:7d:ee:63: + 6a:96:19:99:c8:a7:2a:00:e6:51:8d:46:eb:30:58: + e8:2d + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Certificate Policies: + Policy: 2.16.840.1.113733.1.7.54 + CPS: https://www.thawte.com/cps + + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + Authority Information Access: + OCSP - URI:http://t.symcd.com + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://t.symcb.com/ThawtePCA.crl + + X509v3 Subject Alternative Name: + DirName:/CN=SymantecPKI-1-698 + X509v3 Subject Key Identifier: + 9F:B8:C1:A9:6C:F2:F5:C0:22:2A:94:ED:5C:99:AC:D4:EC:D7:C6:07 + X509v3 Authority Key Identifier: + keyid:7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50 + + Signature Algorithm: sha256WithRSAEncryption + 53:54:f2:47:a8:02:d7:ef:aa:35:78:be:4a:08:0d:90:18:4b: + 6d:9e:2a:53:2b:e9:54:17:77:74:29:7e:d0:37:07:05:b8:e4: + fa:b8:b4:63:98:44:dc:c6:4f:81:06:8c:3a:be:c7:30:57:c6: + 70:fc:d6:93:19:9f:c3:55:d7:3e:1f:72:8a:9d:30:5a:35:97: + 32:cb:63:e4:c6:72:df:fb:68:ca:69:2f:db:cd:50:38:3e:2b: + bb:ab:3b:82:c7:fd:4b:9b:bd:7c:41:98:ef:01:53:d8:35:8f: + 25:c9:03:06:e6:9c:57:c1:51:0f:9e:f6:7d:93:4d:f8:76:c8: + 3a:6b:f4:c4:8f:33:32:7f:9d:21:84:34:d9:a7:f9:92:fa:41: + 91:61:84:05:9d:a3:79:46:ce:67:e7:81:f2:5e:ac:4c:bc:a8: + ab:6a:6d:15:e2:9c:4e:5a:d9:63:80:bc:f7:42:eb:9a:44:c6: + 8c:6b:06:36:b4:8b:32:89:de:c2:f1:a8:26:aa:a9:ac:ff:ea: + 71:a6:e7:8c:41:fa:17:35:bb:b3:87:31:a9:93:c2:c8:58:e1: + 0a:4e:95:83:9c:b9:ed:3b:a5:ef:08:e0:74:f9:c3:1b:e6:07: + a3:ee:07:d7:42:22:79:21:a0:a1:d4:1d:26:d3:d0:d6:a6:5d: + 2b:41:c0:79 +-----BEGIN CERTIFICATE----- +MIIE0jCCA7qgAwIBAgIQLGnhL2pnC9md0g+RnvCeUTANBgkqhkiG9w0BAQsFADCB +qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV +BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMTQwNjEwMDAwMDAwWhcNMjQw +NjA5MjM1OTU5WjBjMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMu +MR0wGwYDVQQLExREb21haW4gVmFsaWRhdGVkIFNTTDEeMBwGA1UEAxMVdGhhd3Rl +IERWIFNTTCBDQSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +6pQHhchBLPaDEmySX6sfANSWb3TNLhHpbA85AblIkEA5TcSiyHlqpZq9kURld1St +/yVf7kL7swIP6l163RpUntdzQpvMeV/FTfS3Cxg5IHrdUAFdNEVfTBEO9YcmJrSw +835xoDFxUIloWmOKFGLljDoWVQ0+66qAHXF644cHq72idM3aCAGdG8wniIxH1Gkl +Qta7UG2FUNBIgg0In+kj40LGPJi4u27FcBPfGR0B/dK1TuZi9Af6a30Rd8RiT0BO +pXiXqyxNDKd8w8RQMp/QcJsP//91WTSFrUnVNe5PW9TUNpWgfujFoRy9E0597mNq +lhmZyKcqAOZRjUbrMFjoLQIDAQABo4IBOTCCATUwEgYDVR0TAQH/BAgwBgEB/wIB +ADBBBgNVHSAEOjA4MDYGCmCGSAGG+EUBBzYwKDAmBggrBgEFBQcCARYaaHR0cHM6 +Ly93d3cudGhhd3RlLmNvbS9jcHMwDgYDVR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEB +BCIwIDAeBggrBgEFBQcwAYYSaHR0cDovL3Quc3ltY2QuY29tMDEGA1UdHwQqMCgw +JqAkoCKGIGh0dHA6Ly90LnN5bWNiLmNvbS9UaGF3dGVQQ0EuY3JsMCkGA1UdEQQi +MCCkHjAcMRowGAYDVQQDExFTeW1hbnRlY1BLSS0xLTY5ODAdBgNVHQ4EFgQUn7jB +qWzy9cAiKpTtXJms1OzXxgcwHwYDVR0jBBgwFoAUe1tFz6/Oy3r9MZIaarbzRutX +SFAwDQYJKoZIhvcNAQELBQADggEBAFNU8keoAtfvqjV4vkoIDZAYS22eKlMr6VQX +d3QpftA3BwW45Pq4tGOYRNzGT4EGjDq+xzBXxnD81pMZn8NV1z4fcoqdMFo1lzLL +Y+TGct/7aMppL9vNUDg+K7urO4LH/UubvXxBmO8BU9g1jyXJAwbmnFfBUQ+e9n2T +Tfh2yDpr9MSPMzJ/nSGENNmn+ZL6QZFhhAWdo3lGzmfngfJerEy8qKtqbRXinE5a +2WOAvPdC65pExoxrBja0izKJ3sLxqCaqqaz/6nGm54xB+hc1u7OHMamTwshY4QpO +lYOcue07pe8I4HT5wxvmB6PuB9dCInkhoKHUHSbT0NamXStBwHk= +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert38[] = { + 0x30, 0x82, 0x04, 0xd2, 0x30, 0x82, 0x03, 0xba, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x2c, 0x69, 0xe1, 0x2f, 0x6a, 0x67, 0x0b, 0xd9, 0x9d, + 0xd2, 0x0f, 0x91, 0x9e, 0xf0, 0x9e, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, + 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x0c, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, + 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x44, + 0x69, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x31, 0x38, 0x30, 0x36, 0x06, + 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2f, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, + 0x30, 0x36, 0x20, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, + 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, + 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x16, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, + 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x30, 0x36, 0x31, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, + 0x36, 0x30, 0x39, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x63, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0c, + 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x14, 0x44, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x64, 0x20, 0x53, 0x53, 0x4c, 0x31, 0x1e, 0x30, 0x1c, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x15, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, + 0x20, 0x44, 0x56, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x41, 0x20, 0x2d, + 0x20, 0x47, 0x32, 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, + 0xea, 0x94, 0x07, 0x85, 0xc8, 0x41, 0x2c, 0xf6, 0x83, 0x12, 0x6c, 0x92, + 0x5f, 0xab, 0x1f, 0x00, 0xd4, 0x96, 0x6f, 0x74, 0xcd, 0x2e, 0x11, 0xe9, + 0x6c, 0x0f, 0x39, 0x01, 0xb9, 0x48, 0x90, 0x40, 0x39, 0x4d, 0xc4, 0xa2, + 0xc8, 0x79, 0x6a, 0xa5, 0x9a, 0xbd, 0x91, 0x44, 0x65, 0x77, 0x54, 0xad, + 0xff, 0x25, 0x5f, 0xee, 0x42, 0xfb, 0xb3, 0x02, 0x0f, 0xea, 0x5d, 0x7a, + 0xdd, 0x1a, 0x54, 0x9e, 0xd7, 0x73, 0x42, 0x9b, 0xcc, 0x79, 0x5f, 0xc5, + 0x4d, 0xf4, 0xb7, 0x0b, 0x18, 0x39, 0x20, 0x7a, 0xdd, 0x50, 0x01, 0x5d, + 0x34, 0x45, 0x5f, 0x4c, 0x11, 0x0e, 0xf5, 0x87, 0x26, 0x26, 0xb4, 0xb0, + 0xf3, 0x7e, 0x71, 0xa0, 0x31, 0x71, 0x50, 0x89, 0x68, 0x5a, 0x63, 0x8a, + 0x14, 0x62, 0xe5, 0x8c, 0x3a, 0x16, 0x55, 0x0d, 0x3e, 0xeb, 0xaa, 0x80, + 0x1d, 0x71, 0x7a, 0xe3, 0x87, 0x07, 0xab, 0xbd, 0xa2, 0x74, 0xcd, 0xda, + 0x08, 0x01, 0x9d, 0x1b, 0xcc, 0x27, 0x88, 0x8c, 0x47, 0xd4, 0x69, 0x25, + 0x42, 0xd6, 0xbb, 0x50, 0x6d, 0x85, 0x50, 0xd0, 0x48, 0x82, 0x0d, 0x08, + 0x9f, 0xe9, 0x23, 0xe3, 0x42, 0xc6, 0x3c, 0x98, 0xb8, 0xbb, 0x6e, 0xc5, + 0x70, 0x13, 0xdf, 0x19, 0x1d, 0x01, 0xfd, 0xd2, 0xb5, 0x4e, 0xe6, 0x62, + 0xf4, 0x07, 0xfa, 0x6b, 0x7d, 0x11, 0x77, 0xc4, 0x62, 0x4f, 0x40, 0x4e, + 0xa5, 0x78, 0x97, 0xab, 0x2c, 0x4d, 0x0c, 0xa7, 0x7c, 0xc3, 0xc4, 0x50, + 0x32, 0x9f, 0xd0, 0x70, 0x9b, 0x0f, 0xff, 0xff, 0x75, 0x59, 0x34, 0x85, + 0xad, 0x49, 0xd5, 0x35, 0xee, 0x4f, 0x5b, 0xd4, 0xd4, 0x36, 0x95, 0xa0, + 0x7e, 0xe8, 0xc5, 0xa1, 0x1c, 0xbd, 0x13, 0x4e, 0x7d, 0xee, 0x63, 0x6a, + 0x96, 0x19, 0x99, 0xc8, 0xa7, 0x2a, 0x00, 0xe6, 0x51, 0x8d, 0x46, 0xeb, + 0x30, 0x58, 0xe8, 0x2d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, + 0x39, 0x30, 0x82, 0x01, 0x35, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, + 0x00, 0x30, 0x41, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3a, 0x30, 0x38, + 0x30, 0x36, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, + 0x07, 0x36, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, + 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, 0x65, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, + 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, + 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x74, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d, + 0x30, 0x31, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2a, 0x30, 0x28, 0x30, + 0x26, 0xa0, 0x24, 0xa0, 0x22, 0x86, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x74, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x50, 0x43, 0x41, 0x2e, + 0x63, 0x72, 0x6c, 0x30, 0x29, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x22, + 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, + 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, 0x36, 0x39, 0x38, 0x30, 0x1d, + 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x9f, 0xb8, 0xc1, + 0xa9, 0x6c, 0xf2, 0xf5, 0xc0, 0x22, 0x2a, 0x94, 0xed, 0x5c, 0x99, 0xac, + 0xd4, 0xec, 0xd7, 0xc6, 0x07, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, + 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7b, 0x5b, 0x45, 0xcf, 0xaf, 0xce, + 0xcb, 0x7a, 0xfd, 0x31, 0x92, 0x1a, 0x6a, 0xb6, 0xf3, 0x46, 0xeb, 0x57, + 0x48, 0x50, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x53, 0x54, + 0xf2, 0x47, 0xa8, 0x02, 0xd7, 0xef, 0xaa, 0x35, 0x78, 0xbe, 0x4a, 0x08, + 0x0d, 0x90, 0x18, 0x4b, 0x6d, 0x9e, 0x2a, 0x53, 0x2b, 0xe9, 0x54, 0x17, + 0x77, 0x74, 0x29, 0x7e, 0xd0, 0x37, 0x07, 0x05, 0xb8, 0xe4, 0xfa, 0xb8, + 0xb4, 0x63, 0x98, 0x44, 0xdc, 0xc6, 0x4f, 0x81, 0x06, 0x8c, 0x3a, 0xbe, + 0xc7, 0x30, 0x57, 0xc6, 0x70, 0xfc, 0xd6, 0x93, 0x19, 0x9f, 0xc3, 0x55, + 0xd7, 0x3e, 0x1f, 0x72, 0x8a, 0x9d, 0x30, 0x5a, 0x35, 0x97, 0x32, 0xcb, + 0x63, 0xe4, 0xc6, 0x72, 0xdf, 0xfb, 0x68, 0xca, 0x69, 0x2f, 0xdb, 0xcd, + 0x50, 0x38, 0x3e, 0x2b, 0xbb, 0xab, 0x3b, 0x82, 0xc7, 0xfd, 0x4b, 0x9b, + 0xbd, 0x7c, 0x41, 0x98, 0xef, 0x01, 0x53, 0xd8, 0x35, 0x8f, 0x25, 0xc9, + 0x03, 0x06, 0xe6, 0x9c, 0x57, 0xc1, 0x51, 0x0f, 0x9e, 0xf6, 0x7d, 0x93, + 0x4d, 0xf8, 0x76, 0xc8, 0x3a, 0x6b, 0xf4, 0xc4, 0x8f, 0x33, 0x32, 0x7f, + 0x9d, 0x21, 0x84, 0x34, 0xd9, 0xa7, 0xf9, 0x92, 0xfa, 0x41, 0x91, 0x61, + 0x84, 0x05, 0x9d, 0xa3, 0x79, 0x46, 0xce, 0x67, 0xe7, 0x81, 0xf2, 0x5e, + 0xac, 0x4c, 0xbc, 0xa8, 0xab, 0x6a, 0x6d, 0x15, 0xe2, 0x9c, 0x4e, 0x5a, + 0xd9, 0x63, 0x80, 0xbc, 0xf7, 0x42, 0xeb, 0x9a, 0x44, 0xc6, 0x8c, 0x6b, + 0x06, 0x36, 0xb4, 0x8b, 0x32, 0x89, 0xde, 0xc2, 0xf1, 0xa8, 0x26, 0xaa, + 0xa9, 0xac, 0xff, 0xea, 0x71, 0xa6, 0xe7, 0x8c, 0x41, 0xfa, 0x17, 0x35, + 0xbb, 0xb3, 0x87, 0x31, 0xa9, 0x93, 0xc2, 0xc8, 0x58, 0xe1, 0x0a, 0x4e, + 0x95, 0x83, 0x9c, 0xb9, 0xed, 0x3b, 0xa5, 0xef, 0x08, 0xe0, 0x74, 0xf9, + 0xc3, 0x1b, 0xe6, 0x07, 0xa3, 0xee, 0x07, 0xd7, 0x42, 0x22, 0x79, 0x21, + 0xa0, 0xa1, 0xd4, 0x1d, 0x26, 0xd3, 0xd0, 0xd6, 0xa6, 0x5d, 0x2b, 0x41, + 0xc0, 0x79, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1372799044 (0x51d34044) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=Entrust, Inc., OU=www.entrust.net/CPS is incorporated by reference, OU=(c) 2006 Entrust, Inc., CN=Entrust Root Certification Authority + Validity + Not Before: Sep 22 17:14:57 2014 GMT + Not After : Sep 23 01:31:53 2024 GMT + Subject: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2009 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - G2 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:ba:84:b6:72:db:9e:0c:6b:e2:99:e9:30:01:a7: + 76:ea:32:b8:95:41:1a:c9:da:61:4e:58:72:cf:fe: + f6:82:79:bf:73:61:06:0a:a5:27:d8:b3:5f:d3:45: + 4e:1c:72:d6:4e:32:f2:72:8a:0f:f7:83:19:d0:6a: + 80:80:00:45:1e:b0:c7:e7:9a:bf:12:57:27:1c:a3: + 68:2f:0a:87:bd:6a:6b:0e:5e:65:f3:1c:77:d5:d4: + 85:8d:70:21:b4:b3:32:e7:8b:a2:d5:86:39:02:b1: + b8:d2:47:ce:e4:c9:49:c4:3b:a7:de:fb:54:7d:57: + be:f0:e8:6e:c2:79:b2:3a:0b:55:e2:50:98:16:32: + 13:5c:2f:78:56:c1:c2:94:b3:f2:5a:e4:27:9a:9f: + 24:d7:c6:ec:d0:9b:25:82:e3:cc:c2:c4:45:c5:8c: + 97:7a:06:6b:2a:11:9f:a9:0a:6e:48:3b:6f:db:d4: + 11:19:42:f7:8f:07:bf:f5:53:5f:9c:3e:f4:17:2c: + e6:69:ac:4e:32:4c:62:77:ea:b7:e8:e5:bb:34:bc: + 19:8b:ae:9c:51:e7:b7:7e:b5:53:b1:33:22:e5:6d: + cf:70:3c:1a:fa:e2:9b:67:b6:83:f4:8d:a5:af:62: + 4c:4d:e0:58:ac:64:34:12:03:f8:b6:8d:94:63:24: + a4:71 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:1 + Authority Information Access: + OCSP - URI:http://ocsp.entrust.net + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.entrust.net/rootca1.crl + + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: http://www.entrust.net/CPS + + X509v3 Subject Key Identifier: + 6A:72:26:7A:D0:1E:EF:7D:E7:3B:69:51:D4:6C:8D:9F:90:12:66:AB + X509v3 Authority Key Identifier: + keyid:68:90:E4:67:A4:A6:53:80:C7:86:66:A4:F1:F7:4B:43:FB:84:BD:6D + + Signature Algorithm: sha256WithRSAEncryption + 69:33:83:fc:28:7a:6f:7d:ef:9d:55:eb:c5:3e:7a:9d:75:b3: + cc:c3:38:36:d9:34:a2:28:68:18:ea:1e:69:d3:bd:e7:d0:77: + da:b8:00:83:4e:4a:cf:6f:d1:f1:c1:22:3f:74:e4:f7:98:49: + 9e:9b:b6:9e:e1:db:98:77:2d:56:34:b1:a8:3c:d9:fd:c0:cd: + c7:bf:05:03:d4:02:c5:f1:e5:c6:da:08:a5:13:c7:62:23:11: + d1:61:30:1d:60:84:45:ef:79:a8:c6:26:93:a4:b7:cd:34:b8: + 69:c5:13:f6:91:b3:c9:45:73:76:b6:92:f6:76:0a:5b:e1:03: + 47:b7:e9:29:4c:91:32:23:37:4a:9c:35:d8:78:fd:1d:1f:e4: + 83:89:24:80:ad:b7:f9:cf:e4:5d:a5:d4:71:c4:85:5b:70:1f: + db:3f:1c:01:eb:1a:45:26:31:14:cc:65:bf:67:de:ca:cc:33: + 65:e5:41:91:d7:37:be:41:1a:96:9d:e6:8a:97:9d:a7:ce:ac: + 4e:9a:3d:bd:01:a0:6a:d9:4f:22:00:8b:44:d5:69:62:7b:2e: + eb:cc:ba:e7:92:7d:69:67:3d:fc:b8:7c:de:41:87:d0:69:ea: + ba:0a:18:7a:1a:95:43:b3:79:71:28:76:6d:a1:fb:57:4a:ec: + 4d:c8:0e:10 +-----BEGIN CERTIFICATE----- +MIIE/zCCA+egAwIBAgIEUdNARDANBgkqhkiG9w0BAQsFADCBsDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 +Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW +KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE0MDkyMjE3MTQ1N1oXDTI0MDkyMzAx +MzE1M1owgb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgw +JgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQL +EzAoYykgMjAwOSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9u +bHkxMjAwBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuoS2ctueDGvi +mekwAad26jK4lUEaydphTlhyz/72gnm/c2EGCqUn2LNf00VOHHLWTjLycooP94MZ +0GqAgABFHrDH55q/ElcnHKNoLwqHvWprDl5l8xx31dSFjXAhtLMy54ui1YY5ArG4 +0kfO5MlJxDun3vtUfVe+8OhuwnmyOgtV4lCYFjITXC94VsHClLPyWuQnmp8k18bs +0JslguPMwsRFxYyXegZrKhGfqQpuSDtv29QRGUL3jwe/9VNfnD70FyzmaaxOMkxi +d+q36OW7NLwZi66cUee3frVTsTMi5W3PcDwa+uKbZ7aD9I2lr2JMTeBYrGQ0EgP4 +to2UYySkcQIDAQABo4IBDzCCAQswDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQI +MAYBAf8CAQEwMwYIKwYBBQUHAQEEJzAlMCMGCCsGAQUFBzABhhdodHRwOi8vb2Nz +cC5lbnRydXN0Lm5ldDAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3JsLmVudHJ1 +c3QubmV0L3Jvb3RjYTEuY3JsMDsGA1UdIAQ0MDIwMAYEVR0gADAoMCYGCCsGAQUF +BwIBFhpodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NQUzAdBgNVHQ4EFgQUanImetAe +733nO2lR1GyNn5ASZqswHwYDVR0jBBgwFoAUaJDkZ6SmU4DHhmak8fdLQ/uEvW0w +DQYJKoZIhvcNAQELBQADggEBAGkzg/woem99751V68U+ep11s8zDODbZNKIoaBjq +HmnTvefQd9q4AINOSs9v0fHBIj905PeYSZ6btp7h25h3LVY0sag82f3Azce/BQPU +AsXx5cbaCKUTx2IjEdFhMB1ghEXveajGJpOkt800uGnFE/aRs8lFc3a2kvZ2Clvh +A0e36SlMkTIjN0qcNdh4/R0f5IOJJICtt/nP5F2l1HHEhVtwH9s/HAHrGkUmMRTM +Zb9n3srMM2XlQZHXN75BGpad5oqXnafOrE6aPb0BoGrZTyIAi0TVaWJ7LuvMuueS +fWlnPfy4fN5Bh9Bp6roKGHoalUOzeXEodm2h+1dK7E3IDhA= +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert39[] = { + 0x30, 0x82, 0x04, 0xff, 0x30, 0x82, 0x03, 0xe7, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x04, 0x51, 0xd3, 0x40, 0x44, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, + 0xb0, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x0d, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, + 0x63, 0x2e, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, + 0x30, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x43, 0x50, 0x53, 0x20, 0x69, 0x73, 0x20, + 0x69, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x65, 0x64, + 0x20, 0x62, 0x79, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, + 0x65, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x16, + 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x45, 0x6e, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x2d, + 0x30, 0x2b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x24, 0x45, 0x6e, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, + 0x0d, 0x31, 0x34, 0x30, 0x39, 0x32, 0x32, 0x31, 0x37, 0x31, 0x34, 0x35, + 0x37, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x39, 0x32, 0x33, 0x30, 0x31, + 0x33, 0x31, 0x35, 0x33, 0x5a, 0x30, 0x81, 0xbe, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, + 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x45, 0x6e, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x28, 0x30, + 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x65, 0x20, + 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, + 0x6e, 0x65, 0x74, 0x2f, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x2d, 0x74, 0x65, + 0x72, 0x6d, 0x73, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x13, 0x30, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x39, 0x20, 0x45, + 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x20, 0x2d, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, + 0x6c, 0x79, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x29, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, + 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 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, 0xba, 0x84, 0xb6, 0x72, 0xdb, 0x9e, 0x0c, 0x6b, 0xe2, + 0x99, 0xe9, 0x30, 0x01, 0xa7, 0x76, 0xea, 0x32, 0xb8, 0x95, 0x41, 0x1a, + 0xc9, 0xda, 0x61, 0x4e, 0x58, 0x72, 0xcf, 0xfe, 0xf6, 0x82, 0x79, 0xbf, + 0x73, 0x61, 0x06, 0x0a, 0xa5, 0x27, 0xd8, 0xb3, 0x5f, 0xd3, 0x45, 0x4e, + 0x1c, 0x72, 0xd6, 0x4e, 0x32, 0xf2, 0x72, 0x8a, 0x0f, 0xf7, 0x83, 0x19, + 0xd0, 0x6a, 0x80, 0x80, 0x00, 0x45, 0x1e, 0xb0, 0xc7, 0xe7, 0x9a, 0xbf, + 0x12, 0x57, 0x27, 0x1c, 0xa3, 0x68, 0x2f, 0x0a, 0x87, 0xbd, 0x6a, 0x6b, + 0x0e, 0x5e, 0x65, 0xf3, 0x1c, 0x77, 0xd5, 0xd4, 0x85, 0x8d, 0x70, 0x21, + 0xb4, 0xb3, 0x32, 0xe7, 0x8b, 0xa2, 0xd5, 0x86, 0x39, 0x02, 0xb1, 0xb8, + 0xd2, 0x47, 0xce, 0xe4, 0xc9, 0x49, 0xc4, 0x3b, 0xa7, 0xde, 0xfb, 0x54, + 0x7d, 0x57, 0xbe, 0xf0, 0xe8, 0x6e, 0xc2, 0x79, 0xb2, 0x3a, 0x0b, 0x55, + 0xe2, 0x50, 0x98, 0x16, 0x32, 0x13, 0x5c, 0x2f, 0x78, 0x56, 0xc1, 0xc2, + 0x94, 0xb3, 0xf2, 0x5a, 0xe4, 0x27, 0x9a, 0x9f, 0x24, 0xd7, 0xc6, 0xec, + 0xd0, 0x9b, 0x25, 0x82, 0xe3, 0xcc, 0xc2, 0xc4, 0x45, 0xc5, 0x8c, 0x97, + 0x7a, 0x06, 0x6b, 0x2a, 0x11, 0x9f, 0xa9, 0x0a, 0x6e, 0x48, 0x3b, 0x6f, + 0xdb, 0xd4, 0x11, 0x19, 0x42, 0xf7, 0x8f, 0x07, 0xbf, 0xf5, 0x53, 0x5f, + 0x9c, 0x3e, 0xf4, 0x17, 0x2c, 0xe6, 0x69, 0xac, 0x4e, 0x32, 0x4c, 0x62, + 0x77, 0xea, 0xb7, 0xe8, 0xe5, 0xbb, 0x34, 0xbc, 0x19, 0x8b, 0xae, 0x9c, + 0x51, 0xe7, 0xb7, 0x7e, 0xb5, 0x53, 0xb1, 0x33, 0x22, 0xe5, 0x6d, 0xcf, + 0x70, 0x3c, 0x1a, 0xfa, 0xe2, 0x9b, 0x67, 0xb6, 0x83, 0xf4, 0x8d, 0xa5, + 0xaf, 0x62, 0x4c, 0x4d, 0xe0, 0x58, 0xac, 0x64, 0x34, 0x12, 0x03, 0xf8, + 0xb6, 0x8d, 0x94, 0x63, 0x24, 0xa4, 0x71, 0x02, 0x03, 0x01, 0x00, 0x01, + 0xa3, 0x82, 0x01, 0x0f, 0x30, 0x82, 0x01, 0x0b, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, + 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, + 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x33, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x27, 0x30, 0x25, + 0x30, 0x23, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, + 0x86, 0x17, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, + 0x70, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, + 0x74, 0x30, 0x33, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2c, 0x30, 0x2a, + 0x30, 0x28, 0xa0, 0x26, 0xa0, 0x24, 0x86, 0x22, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x6f, 0x6f, 0x74, 0x63, + 0x61, 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3b, 0x06, 0x03, 0x55, 0x1d, + 0x20, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06, 0x04, 0x55, 0x1d, 0x20, + 0x00, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, + 0x6e, 0x65, 0x74, 0x2f, 0x43, 0x50, 0x53, 0x30, 0x1d, 0x06, 0x03, 0x55, + 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x6a, 0x72, 0x26, 0x7a, 0xd0, 0x1e, + 0xef, 0x7d, 0xe7, 0x3b, 0x69, 0x51, 0xd4, 0x6c, 0x8d, 0x9f, 0x90, 0x12, + 0x66, 0xab, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, + 0x16, 0x80, 0x14, 0x68, 0x90, 0xe4, 0x67, 0xa4, 0xa6, 0x53, 0x80, 0xc7, + 0x86, 0x66, 0xa4, 0xf1, 0xf7, 0x4b, 0x43, 0xfb, 0x84, 0xbd, 0x6d, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x69, 0x33, 0x83, 0xfc, 0x28, + 0x7a, 0x6f, 0x7d, 0xef, 0x9d, 0x55, 0xeb, 0xc5, 0x3e, 0x7a, 0x9d, 0x75, + 0xb3, 0xcc, 0xc3, 0x38, 0x36, 0xd9, 0x34, 0xa2, 0x28, 0x68, 0x18, 0xea, + 0x1e, 0x69, 0xd3, 0xbd, 0xe7, 0xd0, 0x77, 0xda, 0xb8, 0x00, 0x83, 0x4e, + 0x4a, 0xcf, 0x6f, 0xd1, 0xf1, 0xc1, 0x22, 0x3f, 0x74, 0xe4, 0xf7, 0x98, + 0x49, 0x9e, 0x9b, 0xb6, 0x9e, 0xe1, 0xdb, 0x98, 0x77, 0x2d, 0x56, 0x34, + 0xb1, 0xa8, 0x3c, 0xd9, 0xfd, 0xc0, 0xcd, 0xc7, 0xbf, 0x05, 0x03, 0xd4, + 0x02, 0xc5, 0xf1, 0xe5, 0xc6, 0xda, 0x08, 0xa5, 0x13, 0xc7, 0x62, 0x23, + 0x11, 0xd1, 0x61, 0x30, 0x1d, 0x60, 0x84, 0x45, 0xef, 0x79, 0xa8, 0xc6, + 0x26, 0x93, 0xa4, 0xb7, 0xcd, 0x34, 0xb8, 0x69, 0xc5, 0x13, 0xf6, 0x91, + 0xb3, 0xc9, 0x45, 0x73, 0x76, 0xb6, 0x92, 0xf6, 0x76, 0x0a, 0x5b, 0xe1, + 0x03, 0x47, 0xb7, 0xe9, 0x29, 0x4c, 0x91, 0x32, 0x23, 0x37, 0x4a, 0x9c, + 0x35, 0xd8, 0x78, 0xfd, 0x1d, 0x1f, 0xe4, 0x83, 0x89, 0x24, 0x80, 0xad, + 0xb7, 0xf9, 0xcf, 0xe4, 0x5d, 0xa5, 0xd4, 0x71, 0xc4, 0x85, 0x5b, 0x70, + 0x1f, 0xdb, 0x3f, 0x1c, 0x01, 0xeb, 0x1a, 0x45, 0x26, 0x31, 0x14, 0xcc, + 0x65, 0xbf, 0x67, 0xde, 0xca, 0xcc, 0x33, 0x65, 0xe5, 0x41, 0x91, 0xd7, + 0x37, 0xbe, 0x41, 0x1a, 0x96, 0x9d, 0xe6, 0x8a, 0x97, 0x9d, 0xa7, 0xce, + 0xac, 0x4e, 0x9a, 0x3d, 0xbd, 0x01, 0xa0, 0x6a, 0xd9, 0x4f, 0x22, 0x00, + 0x8b, 0x44, 0xd5, 0x69, 0x62, 0x7b, 0x2e, 0xeb, 0xcc, 0xba, 0xe7, 0x92, + 0x7d, 0x69, 0x67, 0x3d, 0xfc, 0xb8, 0x7c, 0xde, 0x41, 0x87, 0xd0, 0x69, + 0xea, 0xba, 0x0a, 0x18, 0x7a, 0x1a, 0x95, 0x43, 0xb3, 0x79, 0x71, 0x28, + 0x76, 0x6d, 0xa1, 0xfb, 0x57, 0x4a, 0xec, 0x4d, 0xc8, 0x0e, 0x10, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 7 (0x7) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., CN=Starfield Root Certificate Authority - G2 + Validity + Not Before: May 3 07:00:00 2011 GMT + Not After : May 3 07:00:00 2031 GMT + Subject: C=US, ST=Arizona, L=Scottsdale, O=Starfield Technologies, Inc., OU=http://certs.starfieldtech.com/repository/, CN=Starfield Secure Certificate Authority - G2 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:e5:90:66:4b:ec:f9:46:71:a9:20:83:be:e9:6c: + bf:4a:c9:48:69:81:75:4e:6d:24:f6:cb:17:13:f8: + b0:71:59:84:7a:6b:2b:85:a4:34:b5:16:e5:cb:cc: + e9:41:70:2c:a4:2e:d6:fa:32:7d:e1:a8:de:94:10: + ac:31:c1:c0:d8:6a:ff:59:27:ab:76:d6:fc:0b:74: + 6b:b8:a7:ae:3f:c4:54:f4:b4:31:44:dd:93:56:8c: + a4:4c:5e:9b:89:cb:24:83:9b:e2:57:7d:b7:d8:12: + 1f:c9:85:6d:f4:d1:80:f1:50:9b:87:ae:d4:0b:10: + 05:fb:27:ba:28:6d:17:e9:0e:d6:4d:b9:39:55:06: + ff:0a:24:05:7e:2f:c6:1d:72:6c:d4:8b:29:8c:57: + 7d:da:d9:eb:66:1a:d3:4f:a7:df:7f:52:c4:30:c5: + a5:c9:0e:02:c5:53:bf:77:38:68:06:24:c3:66:c8: + 37:7e:30:1e:45:71:23:35:ff:90:d8:2a:9d:8d:e7: + b0:92:4d:3c:7f:2a:0a:93:dc:cd:16:46:65:f7:60: + 84:8b:76:4b:91:27:73:14:92:e0:ea:ee:8f:16:ea: + 8d:0e:3e:76:17:bf:7d:89:80:80:44:43:e7:2d:e0: + 43:09:75:da:36:e8:ad:db:89:3a:f5:5d:12:8e:23: + 04:83 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + 25:45:81:68:50:26:38:3D:3B:2D:2C:BE:CD:6A:D9:B6:3D:B3:66:63 + X509v3 Authority Key Identifier: + keyid:7C:0C:32:1F:A7:D9:30:7F:C4:7D:68:A3:62:A8:A1:CE:AB:07:5B:27 + + Authority Information Access: + OCSP - URI:http://ocsp.starfieldtech.com/ + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.starfieldtech.com/sfroot-g2.crl + + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: https://certs.starfieldtech.com/repository/ + + Signature Algorithm: sha256WithRSAEncryption + 56:65:ca:fe:f3:3f:0a:a8:93:8b:18:c7:de:43:69:13:34:20: + be:4e:5f:78:a8:6b:9c:db:6a:4d:41:db:c1:13:ec:dc:31:00: + 22:5e:f7:00:9e:0c:e0:34:65:34:f9:b1:3a:4e:48:c8:12:81: + 88:5c:5b:3e:08:53:7a:f7:1a:64:df:b8:50:61:cc:53:51:40: + 29:4b:c2:f4:ae:3a:5f:e4:ca:ad:26:cc:4e:61:43:e5:fd:57: + a6:37:70:ce:43:2b:b0:94:c3:92:e9:e1:5f:aa:10:49:b7:69: + e4:e0:d0:1f:64:a4:2b:cd:1f:6f:a0:f8:84:24:18:ce:79:3d: + a9:91:bf:54:18:13:89:99:54:11:0d:55:c5:26:0b:79:4f:5a: + 1c:6e:f9:63:db:14:80:a4:07:ab:fa:b2:a5:b9:88:dd:91:fe: + 65:3b:a4:a3:79:be:89:4d:e1:d0:b0:f4:c8:17:0c:0a:96:14: + 7c:09:b7:6c:e1:c2:d8:55:d4:18:a0:aa:41:69:70:24:a3:b9: + ef:e9:5a:dc:3e:eb:94:4a:f0:b7:de:5f:0e:76:fa:fb:fb:69: + 03:45:40:50:ee:72:0c:a4:12:86:81:cd:13:d1:4e:c4:3c:ca: + 4e:0d:d2:26:f1:00:b7:b4:a6:a2:e1:6e:7a:81:fd:30:ac:7a: + 1f:c7:59:7b +-----BEGIN CERTIFICATE----- +MIIFADCCA+igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAw +MFoXDTMxMDUwMzA3MDAwMFowgcYxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj +aG5vbG9naWVzLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydHMuc3RhcmZpZWxk +dGVjaC5jb20vcmVwb3NpdG9yeS8xNDAyBgNVBAMTK1N0YXJmaWVsZCBTZWN1cmUg +Q2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDlkGZL7PlGcakgg77pbL9KyUhpgXVObST2yxcT+LBxWYR6ayuF +pDS1FuXLzOlBcCykLtb6Mn3hqN6UEKwxwcDYav9ZJ6t21vwLdGu4p64/xFT0tDFE +3ZNWjKRMXpuJyySDm+JXfbfYEh/JhW300YDxUJuHrtQLEAX7J7oobRfpDtZNuTlV +Bv8KJAV+L8YdcmzUiymMV33a2etmGtNPp99/UsQwxaXJDgLFU793OGgGJMNmyDd+ +MB5FcSM1/5DYKp2N57CSTTx/KgqT3M0WRmX3YISLdkuRJ3MUkuDq7o8W6o0OPnYX +v32JgIBEQ+ct4EMJddo26K3biTr1XRKOIwSDAgMBAAGjggEsMIIBKDAPBgNVHRMB +Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUJUWBaFAmOD07LSy+ +zWrZtj2zZmMwHwYDVR0jBBgwFoAUfAwyH6fZMH/EfWijYqihzqsHWycwOgYIKwYB +BQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vb2NzcC5zdGFyZmllbGR0ZWNo +LmNvbS8wOwYDVR0fBDQwMjAwoC6gLIYqaHR0cDovL2NybC5zdGFyZmllbGR0ZWNo +LmNvbS9zZnJvb3QtZzIuY3JsMEwGA1UdIARFMEMwQQYEVR0gADA5MDcGCCsGAQUF +BwIBFitodHRwczovL2NlcnRzLnN0YXJmaWVsZHRlY2guY29tL3JlcG9zaXRvcnkv +MA0GCSqGSIb3DQEBCwUAA4IBAQBWZcr+8z8KqJOLGMfeQ2kTNCC+Tl94qGuc22pN +QdvBE+zcMQAiXvcAngzgNGU0+bE6TkjIEoGIXFs+CFN69xpk37hQYcxTUUApS8L0 +rjpf5MqtJsxOYUPl/VemN3DOQyuwlMOS6eFfqhBJt2nk4NAfZKQrzR9voPiEJBjO +eT2pkb9UGBOJmVQRDVXFJgt5T1ocbvlj2xSApAer+rKluYjdkf5lO6Sjeb6JTeHQ +sPTIFwwKlhR8Cbds4cLYVdQYoKpBaXAko7nv6VrcPuuUSvC33l8Odvr7+2kDRUBQ +7nIMpBKGgc0T0U7EPMpODdIm8QC3tKai4W56gf0wrHofx1l7 +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert40[] = { + 0x30, 0x82, 0x05, 0x00, 0x30, 0x82, 0x03, 0xe8, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x01, 0x07, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x8f, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, + 0x69, 0x7a, 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x07, 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, + 0x6c, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x1c, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, + 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, + 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x29, 0x53, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, + 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x1e, 0x17, + 0x0d, 0x31, 0x31, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37, 0x30, 0x30, 0x30, + 0x30, 0x5a, 0x17, 0x0d, 0x33, 0x31, 0x30, 0x35, 0x30, 0x33, 0x30, 0x37, + 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x81, 0xc6, 0x31, 0x0b, 0x30, 0x09, + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x10, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x07, 0x41, 0x72, 0x69, 0x7a, + 0x6f, 0x6e, 0x61, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x13, 0x0a, 0x53, 0x63, 0x6f, 0x74, 0x74, 0x73, 0x64, 0x61, 0x6c, 0x65, + 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, 0x53, + 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x54, 0x65, 0x63, + 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x49, + 0x6e, 0x63, 0x2e, 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x13, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x65, 0x72, + 0x74, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x31, 0x34, 0x30, 0x32, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2b, 0x53, 0x74, 0x61, 0x72, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, + 0x47, 0x32, 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, 0xe5, + 0x90, 0x66, 0x4b, 0xec, 0xf9, 0x46, 0x71, 0xa9, 0x20, 0x83, 0xbe, 0xe9, + 0x6c, 0xbf, 0x4a, 0xc9, 0x48, 0x69, 0x81, 0x75, 0x4e, 0x6d, 0x24, 0xf6, + 0xcb, 0x17, 0x13, 0xf8, 0xb0, 0x71, 0x59, 0x84, 0x7a, 0x6b, 0x2b, 0x85, + 0xa4, 0x34, 0xb5, 0x16, 0xe5, 0xcb, 0xcc, 0xe9, 0x41, 0x70, 0x2c, 0xa4, + 0x2e, 0xd6, 0xfa, 0x32, 0x7d, 0xe1, 0xa8, 0xde, 0x94, 0x10, 0xac, 0x31, + 0xc1, 0xc0, 0xd8, 0x6a, 0xff, 0x59, 0x27, 0xab, 0x76, 0xd6, 0xfc, 0x0b, + 0x74, 0x6b, 0xb8, 0xa7, 0xae, 0x3f, 0xc4, 0x54, 0xf4, 0xb4, 0x31, 0x44, + 0xdd, 0x93, 0x56, 0x8c, 0xa4, 0x4c, 0x5e, 0x9b, 0x89, 0xcb, 0x24, 0x83, + 0x9b, 0xe2, 0x57, 0x7d, 0xb7, 0xd8, 0x12, 0x1f, 0xc9, 0x85, 0x6d, 0xf4, + 0xd1, 0x80, 0xf1, 0x50, 0x9b, 0x87, 0xae, 0xd4, 0x0b, 0x10, 0x05, 0xfb, + 0x27, 0xba, 0x28, 0x6d, 0x17, 0xe9, 0x0e, 0xd6, 0x4d, 0xb9, 0x39, 0x55, + 0x06, 0xff, 0x0a, 0x24, 0x05, 0x7e, 0x2f, 0xc6, 0x1d, 0x72, 0x6c, 0xd4, + 0x8b, 0x29, 0x8c, 0x57, 0x7d, 0xda, 0xd9, 0xeb, 0x66, 0x1a, 0xd3, 0x4f, + 0xa7, 0xdf, 0x7f, 0x52, 0xc4, 0x30, 0xc5, 0xa5, 0xc9, 0x0e, 0x02, 0xc5, + 0x53, 0xbf, 0x77, 0x38, 0x68, 0x06, 0x24, 0xc3, 0x66, 0xc8, 0x37, 0x7e, + 0x30, 0x1e, 0x45, 0x71, 0x23, 0x35, 0xff, 0x90, 0xd8, 0x2a, 0x9d, 0x8d, + 0xe7, 0xb0, 0x92, 0x4d, 0x3c, 0x7f, 0x2a, 0x0a, 0x93, 0xdc, 0xcd, 0x16, + 0x46, 0x65, 0xf7, 0x60, 0x84, 0x8b, 0x76, 0x4b, 0x91, 0x27, 0x73, 0x14, + 0x92, 0xe0, 0xea, 0xee, 0x8f, 0x16, 0xea, 0x8d, 0x0e, 0x3e, 0x76, 0x17, + 0xbf, 0x7d, 0x89, 0x80, 0x80, 0x44, 0x43, 0xe7, 0x2d, 0xe0, 0x43, 0x09, + 0x75, 0xda, 0x36, 0xe8, 0xad, 0xdb, 0x89, 0x3a, 0xf5, 0x5d, 0x12, 0x8e, + 0x23, 0x04, 0x83, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x2c, + 0x30, 0x82, 0x01, 0x28, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, + 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, + 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, + 0x25, 0x45, 0x81, 0x68, 0x50, 0x26, 0x38, 0x3d, 0x3b, 0x2d, 0x2c, 0xbe, + 0xcd, 0x6a, 0xd9, 0xb6, 0x3d, 0xb3, 0x66, 0x63, 0x30, 0x1f, 0x06, 0x03, + 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7c, 0x0c, 0x32, + 0x1f, 0xa7, 0xd9, 0x30, 0x7f, 0xc4, 0x7d, 0x68, 0xa3, 0x62, 0xa8, 0xa1, + 0xce, 0xab, 0x07, 0x5b, 0x27, 0x30, 0x3a, 0x06, 0x08, 0x2b, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0x06, + 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x1e, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x73, + 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x3b, 0x06, 0x03, 0x55, 0x1d, 0x1f, + 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0xa0, 0x2e, 0xa0, 0x2c, 0x86, 0x2a, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x73, + 0x74, 0x61, 0x72, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x66, 0x72, 0x6f, 0x6f, 0x74, 0x2d, + 0x67, 0x32, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, + 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, 0x41, 0x06, 0x04, 0x55, 0x1d, 0x20, + 0x00, 0x30, 0x39, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x02, 0x01, 0x16, 0x2b, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, + 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x74, 0x65, 0x63, 0x68, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x56, 0x65, 0xca, 0xfe, + 0xf3, 0x3f, 0x0a, 0xa8, 0x93, 0x8b, 0x18, 0xc7, 0xde, 0x43, 0x69, 0x13, + 0x34, 0x20, 0xbe, 0x4e, 0x5f, 0x78, 0xa8, 0x6b, 0x9c, 0xdb, 0x6a, 0x4d, + 0x41, 0xdb, 0xc1, 0x13, 0xec, 0xdc, 0x31, 0x00, 0x22, 0x5e, 0xf7, 0x00, + 0x9e, 0x0c, 0xe0, 0x34, 0x65, 0x34, 0xf9, 0xb1, 0x3a, 0x4e, 0x48, 0xc8, + 0x12, 0x81, 0x88, 0x5c, 0x5b, 0x3e, 0x08, 0x53, 0x7a, 0xf7, 0x1a, 0x64, + 0xdf, 0xb8, 0x50, 0x61, 0xcc, 0x53, 0x51, 0x40, 0x29, 0x4b, 0xc2, 0xf4, + 0xae, 0x3a, 0x5f, 0xe4, 0xca, 0xad, 0x26, 0xcc, 0x4e, 0x61, 0x43, 0xe5, + 0xfd, 0x57, 0xa6, 0x37, 0x70, 0xce, 0x43, 0x2b, 0xb0, 0x94, 0xc3, 0x92, + 0xe9, 0xe1, 0x5f, 0xaa, 0x10, 0x49, 0xb7, 0x69, 0xe4, 0xe0, 0xd0, 0x1f, + 0x64, 0xa4, 0x2b, 0xcd, 0x1f, 0x6f, 0xa0, 0xf8, 0x84, 0x24, 0x18, 0xce, + 0x79, 0x3d, 0xa9, 0x91, 0xbf, 0x54, 0x18, 0x13, 0x89, 0x99, 0x54, 0x11, + 0x0d, 0x55, 0xc5, 0x26, 0x0b, 0x79, 0x4f, 0x5a, 0x1c, 0x6e, 0xf9, 0x63, + 0xdb, 0x14, 0x80, 0xa4, 0x07, 0xab, 0xfa, 0xb2, 0xa5, 0xb9, 0x88, 0xdd, + 0x91, 0xfe, 0x65, 0x3b, 0xa4, 0xa3, 0x79, 0xbe, 0x89, 0x4d, 0xe1, 0xd0, + 0xb0, 0xf4, 0xc8, 0x17, 0x0c, 0x0a, 0x96, 0x14, 0x7c, 0x09, 0xb7, 0x6c, + 0xe1, 0xc2, 0xd8, 0x55, 0xd4, 0x18, 0xa0, 0xaa, 0x41, 0x69, 0x70, 0x24, + 0xa3, 0xb9, 0xef, 0xe9, 0x5a, 0xdc, 0x3e, 0xeb, 0x94, 0x4a, 0xf0, 0xb7, + 0xde, 0x5f, 0x0e, 0x76, 0xfa, 0xfb, 0xfb, 0x69, 0x03, 0x45, 0x40, 0x50, + 0xee, 0x72, 0x0c, 0xa4, 0x12, 0x86, 0x81, 0xcd, 0x13, 0xd1, 0x4e, 0xc4, + 0x3c, 0xca, 0x4e, 0x0d, 0xd2, 0x26, 0xf1, 0x00, 0xb7, 0xb4, 0xa6, 0xa2, + 0xe1, 0x6e, 0x7a, 0x81, 0xfd, 0x30, 0xac, 0x7a, 0x1f, 0xc7, 0x59, 0x7b, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1372807406 (0x51d360ee) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2009 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - G2 + Validity + Not Before: Oct 22 17:05:14 2014 GMT + Not After : Oct 23 07:33:22 2024 GMT + Subject: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust, Inc. - for authorized use only, CN=Entrust Certification Authority - L1K + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:da:3f:96:d0:4d:b9:2f:44:e7:db:39:5e:9b:50: + ee:5c:a5:61:da:41:67:53:09:aa:00:9a:8e:57:7f: + 29:6b:db:c7:e1:21:24:aa:3a:d0:8d:47:23:d2:ed: + 72:16:f0:91:21:d2:5d:b7:b8:4b:a8:83:8f:b7:91: + 32:68:cf:ce:25:93:2c:b2:7d:97:c8:fe:c1:b4:17: + ba:09:9e:03:90:93:7b:7c:49:83:22:68:8a:9b:de: + 47:c3:31:98:7a:2e:7d:40:0b:d2:ef:3e:d3:b2:8c: + aa:8f:48:a9:ff:00:e8:29:58:06:f7:b6:93:5a:94: + 73:26:26:ad:58:0e:e5:42:b8:d5:ea:73:79:64:68: + 53:25:b8:84:cf:94:7a:ae:06:45:0c:a3:6b:4d:d0: + c6:be:ea:18:a4:36:f0:92:b2:ba:1c:88:8f:3a:52: + 7f:f7:5e:6d:83:1c:9d:f0:1f:e5:c3:d6:dd:a5:78: + 92:3d:b0:6d:2c:ea:c9:cf:94:41:19:71:44:68:ba: + 47:3c:04:e9:5d:ba:3e:f0:35:f7:15:b6:9e:f2:2e: + 15:1e:3f:47:c8:c8:38:a7:73:45:5d:4d:b0:3b:b1: + 8e:17:29:37:ea:dd:05:01:22:bb:94:36:2a:8d:5b: + 35:fe:53:19:2f:08:46:c1:2a:b3:1a:62:1d:4e:2b: + d9:1b + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: + CA:TRUE, pathlen:0 + Authority Information Access: + OCSP - URI:http://ocsp.entrust.net + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.entrust.net/g2ca.crl + + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: http://www.entrust.net/rpa + + X509v3 Subject Key Identifier: + 82:A2:70:74:DD:BC:53:3F:CF:7B:D4:F7:CD:7F:A7:60:C6:0A:4C:BF + X509v3 Authority Key Identifier: + keyid:6A:72:26:7A:D0:1E:EF:7D:E7:3B:69:51:D4:6C:8D:9F:90:12:66:AB + + Signature Algorithm: sha256WithRSAEncryption + 3f:1c:1a:5b:ff:40:22:1d:8f:35:0c:2d:aa:99:27:ab:c0:11: + 32:70:d7:36:28:69:a5:8d:b1:27:99:42:be:c4:93:eb:48:57: + 43:71:23:c4:e5:4e:ad:ae:43:6f:92:76:c5:19:ef:ca:bc:6f: + 42:4c:16:9a:86:a9:04:38:c7:65:f0:f5:0c:e0:4a:df:a2:fa: + ce:1a:11:a8:9c:69:2f:1b:df:ea:e2:32:f3:ce:4c:bc:46:0c: + c0:89:80:d1:87:6b:a2:cf:6b:d4:7f:fd:f5:60:52:67:57:a0: + 6d:d1:64:41:14:6d:34:62:ed:06:6c:24:f2:06:bc:28:02:af: + 03:2d:c2:33:05:fb:cb:aa:16:e8:65:10:43:f5:69:5c:e3:81: + 58:99:cd:6b:d3:b8:c7:7b:19:55:c9:40:ce:79:55:b8:73:89: + e9:5c:40:66:43:12:7f:07:b8:65:56:d5:8d:c3:a7:f5:b1:b6: + 65:9e:c0:83:36:7f:16:45:3c:74:4b:93:8a:3c:f1:2b:f5:35: + 70:73:7b:e7:82:04:b1:18:98:0e:d4:9c:6f:1a:fc:fc:a7:33: + a5:bb:bb:18:f3:6b:7a:5d:32:87:f7:6d:25:e4:e2:76:86:21: + 1e:11:46:cd:76:0e:6f:4f:a4:21:71:0a:84:a7:2d:36:a9:48: + 22:51:7e:82 +-----BEGIN CERTIFICATE----- +MIIFAzCCA+ugAwIBAgIEUdNg7jANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMTQxMDIyMTcw +NTE0WhcNMjQxMDIzMDczMzIyWjCBujELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEuMCwGA1UEAxMlRW50cnVzdCBDZXJ0aWZpY2F0aW9u +IEF1dGhvcml0eSAtIEwxSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANo/ltBNuS9E59s5XptQ7lylYdpBZ1MJqgCajld/KWvbx+EhJKo60I1HI9Ltchbw +kSHSXbe4S6iDj7eRMmjPziWTLLJ9l8j+wbQXugmeA5CTe3xJgyJoipveR8MxmHou +fUAL0u8+07KMqo9Iqf8A6ClYBve2k1qUcyYmrVgO5UK41epzeWRoUyW4hM+Ueq4G +RQyja03Qxr7qGKQ28JKyuhyIjzpSf/debYMcnfAf5cPW3aV4kj2wbSzqyc+UQRlx +RGi6RzwE6V26PvA19xW2nvIuFR4/R8jIOKdzRV1NsDuxjhcpN+rdBQEiu5Q2Ko1b +Nf5TGS8IRsEqsxpiHU4r2RsCAwEAAaOCAQkwggEFMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMECDAGAQH/AgEAMDMGCCsGAQUFBwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0 +cDovL29jc3AuZW50cnVzdC5uZXQwMAYDVR0fBCkwJzAloCOgIYYfaHR0cDovL2Ny +bC5lbnRydXN0Lm5ldC9nMmNhLmNybDA7BgNVHSAENDAyMDAGBFUdIAAwKDAmBggr +BgEFBQcCARYaaHR0cDovL3d3dy5lbnRydXN0Lm5ldC9ycGEwHQYDVR0OBBYEFIKi +cHTdvFM/z3vU981/p2DGCky/MB8GA1UdIwQYMBaAFGpyJnrQHu995ztpUdRsjZ+Q +EmarMA0GCSqGSIb3DQEBCwUAA4IBAQA/HBpb/0AiHY81DC2qmSerwBEycNc2KGml +jbEnmUK+xJPrSFdDcSPE5U6trkNvknbFGe/KvG9CTBaahqkEOMdl8PUM4ErfovrO +GhGonGkvG9/q4jLzzky8RgzAiYDRh2uiz2vUf/31YFJnV6Bt0WRBFG00Yu0GbCTy +BrwoAq8DLcIzBfvLqhboZRBD9Wlc44FYmc1r07jHexlVyUDOeVW4c4npXEBmQxJ/ +B7hlVtWNw6f1sbZlnsCDNn8WRTx0S5OKPPEr9TVwc3vnggSxGJgO1JxvGvz8pzOl +u7sY82t6XTKH920l5OJ2hiEeEUbNdg5vT6QhcQqEpy02qUgiUX6C +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert41[] = { + 0x30, 0x82, 0x05, 0x03, 0x30, 0x82, 0x03, 0xeb, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x04, 0x51, 0xd3, 0x60, 0xee, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, + 0xbe, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x0d, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, + 0x63, 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, + 0x1f, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x6c, 0x65, 0x67, + 0x61, 0x6c, 0x2d, 0x74, 0x65, 0x72, 0x6d, 0x73, 0x31, 0x39, 0x30, 0x37, + 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x30, 0x28, 0x63, 0x29, 0x20, 0x32, + 0x30, 0x30, 0x39, 0x20, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, + 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x66, 0x6f, 0x72, 0x20, + 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, + 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x32, 0x30, 0x30, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x13, 0x29, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, + 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x31, 0x30, 0x32, 0x32, 0x31, 0x37, 0x30, + 0x35, 0x31, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x31, 0x30, 0x32, 0x33, + 0x30, 0x37, 0x33, 0x33, 0x32, 0x32, 0x5a, 0x30, 0x81, 0xba, 0x31, 0x0b, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, + 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x45, 0x6e, + 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, + 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, + 0x65, 0x20, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x2d, + 0x74, 0x65, 0x72, 0x6d, 0x73, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x13, 0x30, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x31, 0x32, + 0x20, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, + 0x63, 0x2e, 0x20, 0x2d, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, + 0x6f, 0x6e, 0x6c, 0x79, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x25, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, + 0x20, 0x4c, 0x31, 0x4b, 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, 0xda, 0x3f, 0x96, 0xd0, 0x4d, 0xb9, 0x2f, 0x44, 0xe7, 0xdb, 0x39, + 0x5e, 0x9b, 0x50, 0xee, 0x5c, 0xa5, 0x61, 0xda, 0x41, 0x67, 0x53, 0x09, + 0xaa, 0x00, 0x9a, 0x8e, 0x57, 0x7f, 0x29, 0x6b, 0xdb, 0xc7, 0xe1, 0x21, + 0x24, 0xaa, 0x3a, 0xd0, 0x8d, 0x47, 0x23, 0xd2, 0xed, 0x72, 0x16, 0xf0, + 0x91, 0x21, 0xd2, 0x5d, 0xb7, 0xb8, 0x4b, 0xa8, 0x83, 0x8f, 0xb7, 0x91, + 0x32, 0x68, 0xcf, 0xce, 0x25, 0x93, 0x2c, 0xb2, 0x7d, 0x97, 0xc8, 0xfe, + 0xc1, 0xb4, 0x17, 0xba, 0x09, 0x9e, 0x03, 0x90, 0x93, 0x7b, 0x7c, 0x49, + 0x83, 0x22, 0x68, 0x8a, 0x9b, 0xde, 0x47, 0xc3, 0x31, 0x98, 0x7a, 0x2e, + 0x7d, 0x40, 0x0b, 0xd2, 0xef, 0x3e, 0xd3, 0xb2, 0x8c, 0xaa, 0x8f, 0x48, + 0xa9, 0xff, 0x00, 0xe8, 0x29, 0x58, 0x06, 0xf7, 0xb6, 0x93, 0x5a, 0x94, + 0x73, 0x26, 0x26, 0xad, 0x58, 0x0e, 0xe5, 0x42, 0xb8, 0xd5, 0xea, 0x73, + 0x79, 0x64, 0x68, 0x53, 0x25, 0xb8, 0x84, 0xcf, 0x94, 0x7a, 0xae, 0x06, + 0x45, 0x0c, 0xa3, 0x6b, 0x4d, 0xd0, 0xc6, 0xbe, 0xea, 0x18, 0xa4, 0x36, + 0xf0, 0x92, 0xb2, 0xba, 0x1c, 0x88, 0x8f, 0x3a, 0x52, 0x7f, 0xf7, 0x5e, + 0x6d, 0x83, 0x1c, 0x9d, 0xf0, 0x1f, 0xe5, 0xc3, 0xd6, 0xdd, 0xa5, 0x78, + 0x92, 0x3d, 0xb0, 0x6d, 0x2c, 0xea, 0xc9, 0xcf, 0x94, 0x41, 0x19, 0x71, + 0x44, 0x68, 0xba, 0x47, 0x3c, 0x04, 0xe9, 0x5d, 0xba, 0x3e, 0xf0, 0x35, + 0xf7, 0x15, 0xb6, 0x9e, 0xf2, 0x2e, 0x15, 0x1e, 0x3f, 0x47, 0xc8, 0xc8, + 0x38, 0xa7, 0x73, 0x45, 0x5d, 0x4d, 0xb0, 0x3b, 0xb1, 0x8e, 0x17, 0x29, + 0x37, 0xea, 0xdd, 0x05, 0x01, 0x22, 0xbb, 0x94, 0x36, 0x2a, 0x8d, 0x5b, + 0x35, 0xfe, 0x53, 0x19, 0x2f, 0x08, 0x46, 0xc1, 0x2a, 0xb3, 0x1a, 0x62, + 0x1d, 0x4e, 0x2b, 0xd9, 0x1b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, + 0x01, 0x09, 0x30, 0x82, 0x01, 0x05, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0f, + 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, + 0x02, 0x01, 0x00, 0x30, 0x33, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x01, 0x01, 0x04, 0x27, 0x30, 0x25, 0x30, 0x23, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x17, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x65, 0x6e, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x30, 0x30, 0x06, 0x03, + 0x55, 0x1d, 0x1f, 0x04, 0x29, 0x30, 0x27, 0x30, 0x25, 0xa0, 0x23, 0xa0, + 0x21, 0x86, 0x1f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, + 0x6c, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, + 0x74, 0x2f, 0x67, 0x32, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3b, + 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06, + 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x70, 0x61, 0x30, + 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x82, 0xa2, + 0x70, 0x74, 0xdd, 0xbc, 0x53, 0x3f, 0xcf, 0x7b, 0xd4, 0xf7, 0xcd, 0x7f, + 0xa7, 0x60, 0xc6, 0x0a, 0x4c, 0xbf, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, + 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x6a, 0x72, 0x26, 0x7a, 0xd0, + 0x1e, 0xef, 0x7d, 0xe7, 0x3b, 0x69, 0x51, 0xd4, 0x6c, 0x8d, 0x9f, 0x90, + 0x12, 0x66, 0xab, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x3f, + 0x1c, 0x1a, 0x5b, 0xff, 0x40, 0x22, 0x1d, 0x8f, 0x35, 0x0c, 0x2d, 0xaa, + 0x99, 0x27, 0xab, 0xc0, 0x11, 0x32, 0x70, 0xd7, 0x36, 0x28, 0x69, 0xa5, + 0x8d, 0xb1, 0x27, 0x99, 0x42, 0xbe, 0xc4, 0x93, 0xeb, 0x48, 0x57, 0x43, + 0x71, 0x23, 0xc4, 0xe5, 0x4e, 0xad, 0xae, 0x43, 0x6f, 0x92, 0x76, 0xc5, + 0x19, 0xef, 0xca, 0xbc, 0x6f, 0x42, 0x4c, 0x16, 0x9a, 0x86, 0xa9, 0x04, + 0x38, 0xc7, 0x65, 0xf0, 0xf5, 0x0c, 0xe0, 0x4a, 0xdf, 0xa2, 0xfa, 0xce, + 0x1a, 0x11, 0xa8, 0x9c, 0x69, 0x2f, 0x1b, 0xdf, 0xea, 0xe2, 0x32, 0xf3, + 0xce, 0x4c, 0xbc, 0x46, 0x0c, 0xc0, 0x89, 0x80, 0xd1, 0x87, 0x6b, 0xa2, + 0xcf, 0x6b, 0xd4, 0x7f, 0xfd, 0xf5, 0x60, 0x52, 0x67, 0x57, 0xa0, 0x6d, + 0xd1, 0x64, 0x41, 0x14, 0x6d, 0x34, 0x62, 0xed, 0x06, 0x6c, 0x24, 0xf2, + 0x06, 0xbc, 0x28, 0x02, 0xaf, 0x03, 0x2d, 0xc2, 0x33, 0x05, 0xfb, 0xcb, + 0xaa, 0x16, 0xe8, 0x65, 0x10, 0x43, 0xf5, 0x69, 0x5c, 0xe3, 0x81, 0x58, + 0x99, 0xcd, 0x6b, 0xd3, 0xb8, 0xc7, 0x7b, 0x19, 0x55, 0xc9, 0x40, 0xce, + 0x79, 0x55, 0xb8, 0x73, 0x89, 0xe9, 0x5c, 0x40, 0x66, 0x43, 0x12, 0x7f, + 0x07, 0xb8, 0x65, 0x56, 0xd5, 0x8d, 0xc3, 0xa7, 0xf5, 0xb1, 0xb6, 0x65, + 0x9e, 0xc0, 0x83, 0x36, 0x7f, 0x16, 0x45, 0x3c, 0x74, 0x4b, 0x93, 0x8a, + 0x3c, 0xf1, 0x2b, 0xf5, 0x35, 0x70, 0x73, 0x7b, 0xe7, 0x82, 0x04, 0xb1, + 0x18, 0x98, 0x0e, 0xd4, 0x9c, 0x6f, 0x1a, 0xfc, 0xfc, 0xa7, 0x33, 0xa5, + 0xbb, 0xbb, 0x18, 0xf3, 0x6b, 0x7a, 0x5d, 0x32, 0x87, 0xf7, 0x6d, 0x25, + 0xe4, 0xe2, 0x76, 0x86, 0x21, 0x1e, 0x11, 0x46, 0xcd, 0x76, 0x0e, 0x6f, + 0x4f, 0xa4, 0x21, 0x71, 0x0a, 0x84, 0xa7, 0x2d, 0x36, 0xa9, 0x48, 0x22, + 0x51, 0x7e, 0x82, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 0e:e9:4c:c3:00:00:00:00:51:d3:77:85 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2009 Entrust, Inc. - for authorized use only, CN=Entrust Root Certification Authority - G2 + Validity + Not Before: Oct 5 19:13:56 2015 GMT + Not After : Dec 5 19:43:56 2030 GMT + Subject: C=US, O=Entrust, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust, Inc. - for authorized use only, CN=Entrust Certification Authority - L1K + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:da:3f:96:d0:4d:b9:2f:44:e7:db:39:5e:9b:50: + ee:5c:a5:61:da:41:67:53:09:aa:00:9a:8e:57:7f: + 29:6b:db:c7:e1:21:24:aa:3a:d0:8d:47:23:d2:ed: + 72:16:f0:91:21:d2:5d:b7:b8:4b:a8:83:8f:b7:91: + 32:68:cf:ce:25:93:2c:b2:7d:97:c8:fe:c1:b4:17: + ba:09:9e:03:90:93:7b:7c:49:83:22:68:8a:9b:de: + 47:c3:31:98:7a:2e:7d:40:0b:d2:ef:3e:d3:b2:8c: + aa:8f:48:a9:ff:00:e8:29:58:06:f7:b6:93:5a:94: + 73:26:26:ad:58:0e:e5:42:b8:d5:ea:73:79:64:68: + 53:25:b8:84:cf:94:7a:ae:06:45:0c:a3:6b:4d:d0: + c6:be:ea:18:a4:36:f0:92:b2:ba:1c:88:8f:3a:52: + 7f:f7:5e:6d:83:1c:9d:f0:1f:e5:c3:d6:dd:a5:78: + 92:3d:b0:6d:2c:ea:c9:cf:94:41:19:71:44:68:ba: + 47:3c:04:e9:5d:ba:3e:f0:35:f7:15:b6:9e:f2:2e: + 15:1e:3f:47:c8:c8:38:a7:73:45:5d:4d:b0:3b:b1: + 8e:17:29:37:ea:dd:05:01:22:bb:94:36:2a:8d:5b: + 35:fe:53:19:2f:08:46:c1:2a:b3:1a:62:1d:4e:2b: + d9:1b + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + Authority Information Access: + OCSP - URI:http://ocsp.entrust.net + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.entrust.net/g2ca.crl + + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: http://www.entrust.net/rpa + + X509v3 Subject Key Identifier: + 82:A2:70:74:DD:BC:53:3F:CF:7B:D4:F7:CD:7F:A7:60:C6:0A:4C:BF + X509v3 Authority Key Identifier: + keyid:6A:72:26:7A:D0:1E:EF:7D:E7:3B:69:51:D4:6C:8D:9F:90:12:66:AB + + Signature Algorithm: sha256WithRSAEncryption + 39:d5:8e:98:83:61:c8:2c:63:d3:70:1d:19:30:cb:f6:09:ac: + cc:69:d5:c9:dc:37:41:f2:32:0f:ef:74:c3:58:f6:78:27:09: + 34:08:95:92:2f:d7:df:b8:a3:fd:0e:81:e9:a4:9c:d3:3f:4d: + 68:2b:15:31:0a:15:cc:52:04:93:e8:93:50:c3:d9:b1:e2:e1: + 68:b7:3a:09:74:f1:34:58:0a:3f:77:98:40:b8:e6:68:ff:5d: + e4:c8:46:c5:ec:81:d7:c9:82:18:5c:83:ce:71:d8:bc:bf:ac: + 99:02:93:db:94:98:84:d2:9c:a6:b5:fe:5c:bb:f0:4a:af:21: + ac:c2:3f:49:24:67:d6:2e:8e:cf:ac:cc:64:15:18:72:e5:6c: + 77:d3:52:a8:b9:dd:8d:ac:00:4a:35:19:d4:6f:73:a3:75:ef: + 6b:64:c3:e0:8d:83:12:a1:8a:e7:0e:86:4d:d8:b4:20:1b:be: + 6a:a5:8c:4b:68:66:e3:2b:c7:58:0b:fb:56:10:d4:91:fb:1d: + d3:31:58:10:8c:44:e3:75:7b:10:9d:b5:38:b1:f6:aa:ca:81: + 64:6c:e8:f2:e2:81:55:97:51:7f:e1:c2:27:50:a2:c9:3c:5b: + 00:43:f6:5b:b9:d5:a5:fc:ff:07:50:40:67:07:b0:55:f0:b7: + 7e:6e:2d:cc +-----BEGIN CERTIFICATE----- +MIIFDjCCA/agAwIBAgIMDulMwwAAAABR03eFMA0GCSqGSIb3DQEBCwUAMIG+MQsw +CQYDVQQGEwJVUzEWMBQGA1UEChMNRW50cnVzdCwgSW5jLjEoMCYGA1UECxMfU2Vl +IHd3dy5lbnRydXN0Lm5ldC9sZWdhbC10ZXJtczE5MDcGA1UECxMwKGMpIDIwMDkg +RW50cnVzdCwgSW5jLiAtIGZvciBhdXRob3JpemVkIHVzZSBvbmx5MTIwMAYDVQQD +EylFbnRydXN0IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjAeFw0x +NTEwMDUxOTEzNTZaFw0zMDEyMDUxOTQzNTZaMIG6MQswCQYDVQQGEwJVUzEWMBQG +A1UEChMNRW50cnVzdCwgSW5jLjEoMCYGA1UECxMfU2VlIHd3dy5lbnRydXN0Lm5l +dC9sZWdhbC10ZXJtczE5MDcGA1UECxMwKGMpIDIwMTIgRW50cnVzdCwgSW5jLiAt +IGZvciBhdXRob3JpemVkIHVzZSBvbmx5MS4wLAYDVQQDEyVFbnRydXN0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5IC0gTDFLMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEA2j+W0E25L0Tn2zlem1DuXKVh2kFnUwmqAJqOV38pa9vH4SEkqjrQ +jUcj0u1yFvCRIdJdt7hLqIOPt5EyaM/OJZMssn2XyP7BtBe6CZ4DkJN7fEmDImiK +m95HwzGYei59QAvS7z7Tsoyqj0ip/wDoKVgG97aTWpRzJiatWA7lQrjV6nN5ZGhT +JbiEz5R6rgZFDKNrTdDGvuoYpDbwkrK6HIiPOlJ/915tgxyd8B/lw9bdpXiSPbBt +LOrJz5RBGXFEaLpHPATpXbo+8DX3Fbae8i4VHj9HyMg4p3NFXU2wO7GOFyk36t0F +ASK7lDYqjVs1/lMZLwhGwSqzGmIdTivZGwIDAQABo4IBDDCCAQgwDgYDVR0PAQH/ +BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwMwYIKwYBBQUHAQEEJzAlMCMGCCsG +AQUFBzABhhdodHRwOi8vb2NzcC5lbnRydXN0Lm5ldDAwBgNVHR8EKTAnMCWgI6Ah +hh9odHRwOi8vY3JsLmVudHJ1c3QubmV0L2cyY2EuY3JsMDsGA1UdIAQ0MDIwMAYE +VR0gADAoMCYGCCsGAQUFBwIBFhpodHRwOi8vd3d3LmVudHJ1c3QubmV0L3JwYTAd +BgNVHQ4EFgQUgqJwdN28Uz/Pe9T3zX+nYMYKTL8wHwYDVR0jBBgwFoAUanImetAe +733nO2lR1GyNn5ASZqswDQYJKoZIhvcNAQELBQADggEBADnVjpiDYcgsY9NwHRkw +y/YJrMxp1cncN0HyMg/vdMNY9ngnCTQIlZIv19+4o/0OgemknNM/TWgrFTEKFcxS +BJPok1DD2bHi4Wi3Ogl08TRYCj93mEC45mj/XeTIRsXsgdfJghhcg85x2Ly/rJkC +k9uUmITSnKa1/ly78EqvIazCP0kkZ9Yujs+szGQVGHLlbHfTUqi53Y2sAEo1GdRv +c6N172tkw+CNgxKhiucOhk3YtCAbvmqljEtoZuMrx1gL+1YQ1JH7HdMxWBCMRON1 +exCdtTix9qrKgWRs6PLigVWXUX/hwidQosk8WwBD9lu51aX8/wdQQGcHsFXwt35u +Lcw= +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert42[] = { + 0x30, 0x82, 0x05, 0x0e, 0x30, 0x82, 0x03, 0xf6, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x0c, 0x0e, 0xe9, 0x4c, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x51, + 0xd3, 0x77, 0x85, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0xbe, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, + 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x45, 0x6e, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x28, + 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x65, + 0x20, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, + 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x2d, 0x74, + 0x65, 0x72, 0x6d, 0x73, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x13, 0x30, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x39, 0x20, + 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, + 0x2e, 0x20, 0x2d, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, + 0x6e, 0x6c, 0x79, 0x31, 0x32, 0x30, 0x30, 0x06, 0x03, 0x55, 0x04, 0x03, + 0x13, 0x29, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x52, 0x6f, + 0x6f, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x31, + 0x35, 0x31, 0x30, 0x30, 0x35, 0x31, 0x39, 0x31, 0x33, 0x35, 0x36, 0x5a, + 0x17, 0x0d, 0x33, 0x30, 0x31, 0x32, 0x30, 0x35, 0x31, 0x39, 0x34, 0x33, + 0x35, 0x36, 0x5a, 0x30, 0x81, 0xba, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x16, 0x30, 0x14, 0x06, + 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x45, 0x6e, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x28, 0x30, 0x26, 0x06, + 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1f, 0x53, 0x65, 0x65, 0x20, 0x77, 0x77, + 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, + 0x74, 0x2f, 0x6c, 0x65, 0x67, 0x61, 0x6c, 0x2d, 0x74, 0x65, 0x72, 0x6d, + 0x73, 0x31, 0x39, 0x30, 0x37, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x30, + 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, 0x45, 0x6e, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, + 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, + 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x25, 0x45, + 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x4c, 0x31, 0x4b, + 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, 0xda, 0x3f, 0x96, + 0xd0, 0x4d, 0xb9, 0x2f, 0x44, 0xe7, 0xdb, 0x39, 0x5e, 0x9b, 0x50, 0xee, + 0x5c, 0xa5, 0x61, 0xda, 0x41, 0x67, 0x53, 0x09, 0xaa, 0x00, 0x9a, 0x8e, + 0x57, 0x7f, 0x29, 0x6b, 0xdb, 0xc7, 0xe1, 0x21, 0x24, 0xaa, 0x3a, 0xd0, + 0x8d, 0x47, 0x23, 0xd2, 0xed, 0x72, 0x16, 0xf0, 0x91, 0x21, 0xd2, 0x5d, + 0xb7, 0xb8, 0x4b, 0xa8, 0x83, 0x8f, 0xb7, 0x91, 0x32, 0x68, 0xcf, 0xce, + 0x25, 0x93, 0x2c, 0xb2, 0x7d, 0x97, 0xc8, 0xfe, 0xc1, 0xb4, 0x17, 0xba, + 0x09, 0x9e, 0x03, 0x90, 0x93, 0x7b, 0x7c, 0x49, 0x83, 0x22, 0x68, 0x8a, + 0x9b, 0xde, 0x47, 0xc3, 0x31, 0x98, 0x7a, 0x2e, 0x7d, 0x40, 0x0b, 0xd2, + 0xef, 0x3e, 0xd3, 0xb2, 0x8c, 0xaa, 0x8f, 0x48, 0xa9, 0xff, 0x00, 0xe8, + 0x29, 0x58, 0x06, 0xf7, 0xb6, 0x93, 0x5a, 0x94, 0x73, 0x26, 0x26, 0xad, + 0x58, 0x0e, 0xe5, 0x42, 0xb8, 0xd5, 0xea, 0x73, 0x79, 0x64, 0x68, 0x53, + 0x25, 0xb8, 0x84, 0xcf, 0x94, 0x7a, 0xae, 0x06, 0x45, 0x0c, 0xa3, 0x6b, + 0x4d, 0xd0, 0xc6, 0xbe, 0xea, 0x18, 0xa4, 0x36, 0xf0, 0x92, 0xb2, 0xba, + 0x1c, 0x88, 0x8f, 0x3a, 0x52, 0x7f, 0xf7, 0x5e, 0x6d, 0x83, 0x1c, 0x9d, + 0xf0, 0x1f, 0xe5, 0xc3, 0xd6, 0xdd, 0xa5, 0x78, 0x92, 0x3d, 0xb0, 0x6d, + 0x2c, 0xea, 0xc9, 0xcf, 0x94, 0x41, 0x19, 0x71, 0x44, 0x68, 0xba, 0x47, + 0x3c, 0x04, 0xe9, 0x5d, 0xba, 0x3e, 0xf0, 0x35, 0xf7, 0x15, 0xb6, 0x9e, + 0xf2, 0x2e, 0x15, 0x1e, 0x3f, 0x47, 0xc8, 0xc8, 0x38, 0xa7, 0x73, 0x45, + 0x5d, 0x4d, 0xb0, 0x3b, 0xb1, 0x8e, 0x17, 0x29, 0x37, 0xea, 0xdd, 0x05, + 0x01, 0x22, 0xbb, 0x94, 0x36, 0x2a, 0x8d, 0x5b, 0x35, 0xfe, 0x53, 0x19, + 0x2f, 0x08, 0x46, 0xc1, 0x2a, 0xb3, 0x1a, 0x62, 0x1d, 0x4e, 0x2b, 0xd9, + 0x1b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x0c, 0x30, 0x82, + 0x01, 0x08, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, + 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, + 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, + 0x01, 0x00, 0x30, 0x33, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x01, 0x01, 0x04, 0x27, 0x30, 0x25, 0x30, 0x23, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x17, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x65, 0x6e, 0x74, 0x72, + 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x30, 0x30, 0x06, 0x03, 0x55, + 0x1d, 0x1f, 0x04, 0x29, 0x30, 0x27, 0x30, 0x25, 0xa0, 0x23, 0xa0, 0x21, + 0x86, 0x1f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, + 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, + 0x2f, 0x67, 0x32, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x3b, 0x06, + 0x03, 0x55, 0x1d, 0x20, 0x04, 0x34, 0x30, 0x32, 0x30, 0x30, 0x06, 0x04, + 0x55, 0x1d, 0x20, 0x00, 0x30, 0x28, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x72, 0x70, 0x61, 0x30, 0x1d, + 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x82, 0xa2, 0x70, + 0x74, 0xdd, 0xbc, 0x53, 0x3f, 0xcf, 0x7b, 0xd4, 0xf7, 0xcd, 0x7f, 0xa7, + 0x60, 0xc6, 0x0a, 0x4c, 0xbf, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, + 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x6a, 0x72, 0x26, 0x7a, 0xd0, 0x1e, + 0xef, 0x7d, 0xe7, 0x3b, 0x69, 0x51, 0xd4, 0x6c, 0x8d, 0x9f, 0x90, 0x12, + 0x66, 0xab, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x39, 0xd5, + 0x8e, 0x98, 0x83, 0x61, 0xc8, 0x2c, 0x63, 0xd3, 0x70, 0x1d, 0x19, 0x30, + 0xcb, 0xf6, 0x09, 0xac, 0xcc, 0x69, 0xd5, 0xc9, 0xdc, 0x37, 0x41, 0xf2, + 0x32, 0x0f, 0xef, 0x74, 0xc3, 0x58, 0xf6, 0x78, 0x27, 0x09, 0x34, 0x08, + 0x95, 0x92, 0x2f, 0xd7, 0xdf, 0xb8, 0xa3, 0xfd, 0x0e, 0x81, 0xe9, 0xa4, + 0x9c, 0xd3, 0x3f, 0x4d, 0x68, 0x2b, 0x15, 0x31, 0x0a, 0x15, 0xcc, 0x52, + 0x04, 0x93, 0xe8, 0x93, 0x50, 0xc3, 0xd9, 0xb1, 0xe2, 0xe1, 0x68, 0xb7, + 0x3a, 0x09, 0x74, 0xf1, 0x34, 0x58, 0x0a, 0x3f, 0x77, 0x98, 0x40, 0xb8, + 0xe6, 0x68, 0xff, 0x5d, 0xe4, 0xc8, 0x46, 0xc5, 0xec, 0x81, 0xd7, 0xc9, + 0x82, 0x18, 0x5c, 0x83, 0xce, 0x71, 0xd8, 0xbc, 0xbf, 0xac, 0x99, 0x02, + 0x93, 0xdb, 0x94, 0x98, 0x84, 0xd2, 0x9c, 0xa6, 0xb5, 0xfe, 0x5c, 0xbb, + 0xf0, 0x4a, 0xaf, 0x21, 0xac, 0xc2, 0x3f, 0x49, 0x24, 0x67, 0xd6, 0x2e, + 0x8e, 0xcf, 0xac, 0xcc, 0x64, 0x15, 0x18, 0x72, 0xe5, 0x6c, 0x77, 0xd3, + 0x52, 0xa8, 0xb9, 0xdd, 0x8d, 0xac, 0x00, 0x4a, 0x35, 0x19, 0xd4, 0x6f, + 0x73, 0xa3, 0x75, 0xef, 0x6b, 0x64, 0xc3, 0xe0, 0x8d, 0x83, 0x12, 0xa1, + 0x8a, 0xe7, 0x0e, 0x86, 0x4d, 0xd8, 0xb4, 0x20, 0x1b, 0xbe, 0x6a, 0xa5, + 0x8c, 0x4b, 0x68, 0x66, 0xe3, 0x2b, 0xc7, 0x58, 0x0b, 0xfb, 0x56, 0x10, + 0xd4, 0x91, 0xfb, 0x1d, 0xd3, 0x31, 0x58, 0x10, 0x8c, 0x44, 0xe3, 0x75, + 0x7b, 0x10, 0x9d, 0xb5, 0x38, 0xb1, 0xf6, 0xaa, 0xca, 0x81, 0x64, 0x6c, + 0xe8, 0xf2, 0xe2, 0x81, 0x55, 0x97, 0x51, 0x7f, 0xe1, 0xc2, 0x27, 0x50, + 0xa2, 0xc9, 0x3c, 0x5b, 0x00, 0x43, 0xf6, 0x5b, 0xb9, 0xd5, 0xa5, 0xfc, + 0xff, 0x07, 0x50, 0x40, 0x67, 0x07, 0xb0, 0x55, 0xf0, 0xb7, 0x7e, 0x6e, + 0x2d, 0xcc, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 120038507 (0x727a46b) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root + Validity + Not Before: Apr 2 14:36:10 2014 GMT + Not After : Apr 2 14:35:52 2021 GMT + Subject: C=NL, L=Amsterdam, O=Verizon Enterprise Solutions, OU=Cybertrust, CN=Verizon Akamai SureServer CA G14-SHA2 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:dd:6e:9e:02:69:02:b5:a3:99:2e:08:64:32:6a: + 59:f3:c6:9e:a6:20:07:d2:48:d1:a8:93:c7:ea:47: + 8f:83:39:40:d7:20:5d:8d:9a:ba:ab:d8:70:ec:9d: + 88:d1:bd:62:f6:db:ec:9d:5e:35:01:76:03:23:e5: + 6f:d2:af:46:35:59:5a:5c:d1:a8:23:c1:eb:e9:20: + d4:49:d6:3f:00:d8:a8:22:de:43:79:81:ac:e9:a4: + 92:f5:77:70:05:1e:5c:b6:a0:f7:90:a4:cd:ab:28: + 2c:90:c2:e7:0f:c3:af:1c:47:59:d5:84:2e:df:26: + 07:45:23:5a:c6:e8:90:c8:85:4b:8c:16:1e:60:f9: + 01:13:f1:14:1f:e6:e8:14:ed:c5:d2:6f:63:28:6e: + 72:8c:49:ae:08:72:c7:93:95:b4:0b:0c:ae:8f:9a: + 67:84:f5:57:1b:db:81:d7:17:9d:41:11:43:19:bd: + 6d:4a:85:ed:8f:70:25:ab:66:ab:f6:fa:6d:1c:3c: + ab:ed:17:bd:56:84:e1:db:75:33:b2:28:4b:99:8e: + f9:4b:82:33:50:9f:92:53:ed:fa:ad:0f:95:9c:a3: + f2:cb:60:f0:77:1d:c9:01:8b:5f:2d:86:be:bf:36: + b8:24:96:13:7c:c1:86:5a:6c:c1:48:2a:7f:3e:93: + 60:c5 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:2 + X509v3 Certificate Policies: + Policy: 1.3.6.1.4.1.6334.1.50 + CPS: https://secure.omniroot.com/repository + + Authority Information Access: + OCSP - URI:http://ocsp.omniroot.com/baltimoreroot + CA Issuers - URI:https://cacert.omniroot.com/baltimoreroot.crt + CA Issuers - URI:https://cacert.omniroot.com/baltimoreroot.der + + X509v3 Key Usage: critical + Digital Signature, Non Repudiation, Certificate Sign, CRL Sign + X509v3 Authority Key Identifier: + keyid:E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0 + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://cdp1.public-trust.com/CRL/Omniroot2025.crl + + X509v3 Subject Key Identifier: + F8:BD:FA:AF:73:77:C6:C7:1B:F9:4B:4D:11:A7:D1:33:AF:AF:72:11 + Signature Algorithm: sha256WithRSAEncryption + 80:d9:7a:ed:72:05:37:8f:61:aa:73:7c:9a:6a:fc:fe:01:e2: + 19:81:70:07:25:32:b0:f0:6f:3b:c7:6a:28:3d:e4:51:87:e6: + 7e:82:ec:ae:48:a7:b1:77:38:c2:d6:56:af:8f:f2:01:fc:65: + 65:10:09:f7:74:29:b5:0e:92:ee:90:98:d1:88:a2:65:b7:cd: + 9c:0e:a7:86:98:28:bc:ae:15:83:b6:1a:d7:1d:ec:19:da:7a: + 8e:40:f9:99:15:d5:7d:a5:ba:ab:fd:26:98:6e:9c:41:3b:b6: + 81:18:ec:70:48:d7:6e:7f:a6:e1:77:25:d6:dd:62:e8:52:f3: + 8c:16:39:67:e2:22:0d:77:2e:fb:11:6c:e4:dd:38:b4:27:5f: + 03:a8:3d:44:e2:f2:84:4b:84:fd:56:a6:9e:4d:7b:a2:16:4f: + 07:f5:34:24:72:a5:a2:fa:16:66:2a:a4:4a:0e:c8:0d:27:44: + 9c:77:d4:12:10:87:d2:00:2c:7a:bb:8e:88:22:91:15:be:a2: + 59:ca:34:e0:1c:61:94:86:20:33:cd:e7:4c:5d:3b:92:3e:cb: + d6:2d:ea:54:fa:fb:af:54:f5:a8:c5:0b:ca:8b:87:00:e6:9f: + e6:95:bf:b7:c4:a3:59:f5:16:6c:5f:3e:69:55:80:39:f6:75: + 50:14:3e:32 +-----BEGIN CERTIFICATE----- +MIIFHzCCBAegAwIBAgIEByekazANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTE0MDQwMjE0MzYxMFoX +DTIxMDQwMjE0MzU1MlowgY0xCzAJBgNVBAYTAk5MMRIwEAYDVQQHEwlBbXN0ZXJk +YW0xJTAjBgNVBAoTHFZlcml6b24gRW50ZXJwcmlzZSBTb2x1dGlvbnMxEzARBgNV +BAsTCkN5YmVydHJ1c3QxLjAsBgNVBAMTJVZlcml6b24gQWthbWFpIFN1cmVTZXJ2 +ZXIgQ0EgRzE0LVNIQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDd +bp4CaQK1o5kuCGQyalnzxp6mIAfSSNGok8fqR4+DOUDXIF2Nmrqr2HDsnYjRvWL2 +2+ydXjUBdgMj5W/Sr0Y1WVpc0agjwevpINRJ1j8A2Kgi3kN5gazppJL1d3AFHly2 +oPeQpM2rKCyQwucPw68cR1nVhC7fJgdFI1rG6JDIhUuMFh5g+QET8RQf5ugU7cXS +b2MobnKMSa4IcseTlbQLDK6PmmeE9Vcb24HXF51BEUMZvW1Khe2PcCWrZqv2+m0c +PKvtF71WhOHbdTOyKEuZjvlLgjNQn5JT7fqtD5Wco/LLYPB3HckBi18thr6/Nrgk +lhN8wYZabMFIKn8+k2DFAgMBAAGjggG3MIIBszASBgNVHRMBAf8ECDAGAQH/AgEC +MEwGA1UdIARFMEMwQQYJKwYBBAGxPgEyMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8v +c2VjdXJlLm9tbmlyb290LmNvbS9yZXBvc2l0b3J5MIG6BggrBgEFBQcBAQSBrTCB +qjAyBggrBgEFBQcwAYYmaHR0cDovL29jc3Aub21uaXJvb3QuY29tL2JhbHRpbW9y +ZXJvb3QwOQYIKwYBBQUHMAKGLWh0dHBzOi8vY2FjZXJ0Lm9tbmlyb290LmNvbS9i +YWx0aW1vcmVyb290LmNydDA5BggrBgEFBQcwAoYtaHR0cHM6Ly9jYWNlcnQub21u +aXJvb3QuY29tL2JhbHRpbW9yZXJvb3QuZGVyMA4GA1UdDwEB/wQEAwIBxjAfBgNV +HSMEGDAWgBTlnVkwgkdYzKz6CFQ2hns6tQRN8DBCBgNVHR8EOzA5MDegNaAzhjFo +dHRwOi8vY2RwMS5wdWJsaWMtdHJ1c3QuY29tL0NSTC9PbW5pcm9vdDIwMjUuY3Js +MB0GA1UdDgQWBBT4vfqvc3fGxxv5S00Rp9Ezr69yETANBgkqhkiG9w0BAQsFAAOC +AQEAgNl67XIFN49hqnN8mmr8/gHiGYFwByUysPBvO8dqKD3kUYfmfoLsrkinsXc4 +wtZWr4/yAfxlZRAJ93QptQ6S7pCY0YiiZbfNnA6nhpgovK4Vg7Ya1x3sGdp6jkD5 +mRXVfaW6q/0mmG6cQTu2gRjscEjXbn+m4Xcl1t1i6FLzjBY5Z+IiDXcu+xFs5N04 +tCdfA6g9ROLyhEuE/Vamnk17ohZPB/U0JHKlovoWZiqkSg7IDSdEnHfUEhCH0gAs +eruOiCKRFb6iWco04BxhlIYgM83nTF07kj7L1i3qVPr7r1T1qMULyouHAOaf5pW/ +t8SjWfUWbF8+aVWAOfZ1UBQ+Mg== +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert43[] = { + 0x30, 0x82, 0x05, 0x1f, 0x30, 0x82, 0x04, 0x07, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x04, 0x07, 0x27, 0xa4, 0x6b, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x5a, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49, + 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, + 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65, + 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, + 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, + 0x30, 0x34, 0x30, 0x32, 0x31, 0x34, 0x33, 0x36, 0x31, 0x30, 0x5a, 0x17, + 0x0d, 0x32, 0x31, 0x30, 0x34, 0x30, 0x32, 0x31, 0x34, 0x33, 0x35, 0x35, + 0x32, 0x5a, 0x30, 0x81, 0x8d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, + 0x55, 0x04, 0x07, 0x13, 0x09, 0x41, 0x6d, 0x73, 0x74, 0x65, 0x72, 0x64, + 0x61, 0x6d, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x1c, 0x56, 0x65, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x20, 0x45, 0x6e, 0x74, + 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x20, 0x53, 0x6f, 0x6c, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, + 0x73, 0x74, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x25, 0x56, 0x65, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x20, 0x41, 0x6b, 0x61, + 0x6d, 0x61, 0x69, 0x20, 0x53, 0x75, 0x72, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x20, 0x43, 0x41, 0x20, 0x47, 0x31, 0x34, 0x2d, 0x53, 0x48, + 0x41, 0x32, 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, 0xdd, + 0x6e, 0x9e, 0x02, 0x69, 0x02, 0xb5, 0xa3, 0x99, 0x2e, 0x08, 0x64, 0x32, + 0x6a, 0x59, 0xf3, 0xc6, 0x9e, 0xa6, 0x20, 0x07, 0xd2, 0x48, 0xd1, 0xa8, + 0x93, 0xc7, 0xea, 0x47, 0x8f, 0x83, 0x39, 0x40, 0xd7, 0x20, 0x5d, 0x8d, + 0x9a, 0xba, 0xab, 0xd8, 0x70, 0xec, 0x9d, 0x88, 0xd1, 0xbd, 0x62, 0xf6, + 0xdb, 0xec, 0x9d, 0x5e, 0x35, 0x01, 0x76, 0x03, 0x23, 0xe5, 0x6f, 0xd2, + 0xaf, 0x46, 0x35, 0x59, 0x5a, 0x5c, 0xd1, 0xa8, 0x23, 0xc1, 0xeb, 0xe9, + 0x20, 0xd4, 0x49, 0xd6, 0x3f, 0x00, 0xd8, 0xa8, 0x22, 0xde, 0x43, 0x79, + 0x81, 0xac, 0xe9, 0xa4, 0x92, 0xf5, 0x77, 0x70, 0x05, 0x1e, 0x5c, 0xb6, + 0xa0, 0xf7, 0x90, 0xa4, 0xcd, 0xab, 0x28, 0x2c, 0x90, 0xc2, 0xe7, 0x0f, + 0xc3, 0xaf, 0x1c, 0x47, 0x59, 0xd5, 0x84, 0x2e, 0xdf, 0x26, 0x07, 0x45, + 0x23, 0x5a, 0xc6, 0xe8, 0x90, 0xc8, 0x85, 0x4b, 0x8c, 0x16, 0x1e, 0x60, + 0xf9, 0x01, 0x13, 0xf1, 0x14, 0x1f, 0xe6, 0xe8, 0x14, 0xed, 0xc5, 0xd2, + 0x6f, 0x63, 0x28, 0x6e, 0x72, 0x8c, 0x49, 0xae, 0x08, 0x72, 0xc7, 0x93, + 0x95, 0xb4, 0x0b, 0x0c, 0xae, 0x8f, 0x9a, 0x67, 0x84, 0xf5, 0x57, 0x1b, + 0xdb, 0x81, 0xd7, 0x17, 0x9d, 0x41, 0x11, 0x43, 0x19, 0xbd, 0x6d, 0x4a, + 0x85, 0xed, 0x8f, 0x70, 0x25, 0xab, 0x66, 0xab, 0xf6, 0xfa, 0x6d, 0x1c, + 0x3c, 0xab, 0xed, 0x17, 0xbd, 0x56, 0x84, 0xe1, 0xdb, 0x75, 0x33, 0xb2, + 0x28, 0x4b, 0x99, 0x8e, 0xf9, 0x4b, 0x82, 0x33, 0x50, 0x9f, 0x92, 0x53, + 0xed, 0xfa, 0xad, 0x0f, 0x95, 0x9c, 0xa3, 0xf2, 0xcb, 0x60, 0xf0, 0x77, + 0x1d, 0xc9, 0x01, 0x8b, 0x5f, 0x2d, 0x86, 0xbe, 0xbf, 0x36, 0xb8, 0x24, + 0x96, 0x13, 0x7c, 0xc1, 0x86, 0x5a, 0x6c, 0xc1, 0x48, 0x2a, 0x7f, 0x3e, + 0x93, 0x60, 0xc5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0xb7, + 0x30, 0x82, 0x01, 0xb3, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, + 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x02, + 0x30, 0x4c, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x45, 0x30, 0x43, 0x30, + 0x41, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb1, 0x3e, 0x01, 0x32, + 0x30, 0x34, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x02, 0x01, 0x16, 0x26, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, + 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72, + 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x30, 0x81, 0xba, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x81, 0xad, 0x30, 0x81, + 0xaa, 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, + 0x01, 0x86, 0x26, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, + 0x73, 0x70, 0x2e, 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, + 0x65, 0x72, 0x6f, 0x6f, 0x74, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x73, + 0x3a, 0x2f, 0x2f, 0x63, 0x61, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x6f, 0x6d, + 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, + 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x72, 0x6f, 0x6f, 0x74, + 0x2e, 0x63, 0x72, 0x74, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x30, 0x02, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, + 0x2f, 0x2f, 0x63, 0x61, 0x63, 0x65, 0x72, 0x74, 0x2e, 0x6f, 0x6d, 0x6e, + 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, 0x61, + 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x72, 0x6f, 0x6f, 0x74, 0x2e, + 0x64, 0x65, 0x72, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, + 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0xc6, 0x30, 0x1f, 0x06, 0x03, 0x55, + 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe5, 0x9d, 0x59, 0x30, + 0x82, 0x47, 0x58, 0xcc, 0xac, 0xfa, 0x08, 0x54, 0x36, 0x86, 0x7b, 0x3a, + 0xb5, 0x04, 0x4d, 0xf0, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, + 0x3b, 0x30, 0x39, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33, 0x86, 0x31, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x64, 0x70, 0x31, 0x2e, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x52, 0x4c, 0x2f, 0x4f, 0x6d, 0x6e, 0x69, + 0x72, 0x6f, 0x6f, 0x74, 0x32, 0x30, 0x32, 0x35, 0x2e, 0x63, 0x72, 0x6c, + 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xf8, + 0xbd, 0xfa, 0xaf, 0x73, 0x77, 0xc6, 0xc7, 0x1b, 0xf9, 0x4b, 0x4d, 0x11, + 0xa7, 0xd1, 0x33, 0xaf, 0xaf, 0x72, 0x11, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, + 0x01, 0x01, 0x00, 0x80, 0xd9, 0x7a, 0xed, 0x72, 0x05, 0x37, 0x8f, 0x61, + 0xaa, 0x73, 0x7c, 0x9a, 0x6a, 0xfc, 0xfe, 0x01, 0xe2, 0x19, 0x81, 0x70, + 0x07, 0x25, 0x32, 0xb0, 0xf0, 0x6f, 0x3b, 0xc7, 0x6a, 0x28, 0x3d, 0xe4, + 0x51, 0x87, 0xe6, 0x7e, 0x82, 0xec, 0xae, 0x48, 0xa7, 0xb1, 0x77, 0x38, + 0xc2, 0xd6, 0x56, 0xaf, 0x8f, 0xf2, 0x01, 0xfc, 0x65, 0x65, 0x10, 0x09, + 0xf7, 0x74, 0x29, 0xb5, 0x0e, 0x92, 0xee, 0x90, 0x98, 0xd1, 0x88, 0xa2, + 0x65, 0xb7, 0xcd, 0x9c, 0x0e, 0xa7, 0x86, 0x98, 0x28, 0xbc, 0xae, 0x15, + 0x83, 0xb6, 0x1a, 0xd7, 0x1d, 0xec, 0x19, 0xda, 0x7a, 0x8e, 0x40, 0xf9, + 0x99, 0x15, 0xd5, 0x7d, 0xa5, 0xba, 0xab, 0xfd, 0x26, 0x98, 0x6e, 0x9c, + 0x41, 0x3b, 0xb6, 0x81, 0x18, 0xec, 0x70, 0x48, 0xd7, 0x6e, 0x7f, 0xa6, + 0xe1, 0x77, 0x25, 0xd6, 0xdd, 0x62, 0xe8, 0x52, 0xf3, 0x8c, 0x16, 0x39, + 0x67, 0xe2, 0x22, 0x0d, 0x77, 0x2e, 0xfb, 0x11, 0x6c, 0xe4, 0xdd, 0x38, + 0xb4, 0x27, 0x5f, 0x03, 0xa8, 0x3d, 0x44, 0xe2, 0xf2, 0x84, 0x4b, 0x84, + 0xfd, 0x56, 0xa6, 0x9e, 0x4d, 0x7b, 0xa2, 0x16, 0x4f, 0x07, 0xf5, 0x34, + 0x24, 0x72, 0xa5, 0xa2, 0xfa, 0x16, 0x66, 0x2a, 0xa4, 0x4a, 0x0e, 0xc8, + 0x0d, 0x27, 0x44, 0x9c, 0x77, 0xd4, 0x12, 0x10, 0x87, 0xd2, 0x00, 0x2c, + 0x7a, 0xbb, 0x8e, 0x88, 0x22, 0x91, 0x15, 0xbe, 0xa2, 0x59, 0xca, 0x34, + 0xe0, 0x1c, 0x61, 0x94, 0x86, 0x20, 0x33, 0xcd, 0xe7, 0x4c, 0x5d, 0x3b, + 0x92, 0x3e, 0xcb, 0xd6, 0x2d, 0xea, 0x54, 0xfa, 0xfb, 0xaf, 0x54, 0xf5, + 0xa8, 0xc5, 0x0b, 0xca, 0x8b, 0x87, 0x00, 0xe6, 0x9f, 0xe6, 0x95, 0xbf, + 0xb7, 0xc4, 0xa3, 0x59, 0xf5, 0x16, 0x6c, 0x5f, 0x3e, 0x69, 0x55, 0x80, + 0x39, 0xf6, 0x75, 0x50, 0x14, 0x3e, 0x32, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 7e:e1:4a:6f:6f:ef:f2:d3:7f:3f:ad:65:4d:3a:da:b4 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5 + Validity + Not Before: Oct 31 00:00:00 2013 GMT + Not After : Oct 30 23:59:59 2023 GMT + Subject: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 EV SSL CA - G3 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:d8:a1:65:74:23:e8:2b:64:e2:32:d7:33:37:3d: + 8e:f5:34:16:48:dd:4f:7f:87:1c:f8:44:23:13:8e: + fb:11:d8:44:5a:18:71:8e:60:16:26:92:9b:fd:17: + 0b:e1:71:70:42:fe:bf:fa:1c:c0:aa:a3:a7:b5:71: + e8:ff:18:83:f6:df:10:0a:13:62:c8:3d:9c:a7:de: + 2e:3f:0c:d9:1d:e7:2e:fb:2a:ce:c8:9a:7f:87:bf: + d8:4c:04:15:32:c9:d1:cc:95:71:a0:4e:28:4f:84: + d9:35:fb:e3:86:6f:94:53:e6:72:8a:63:67:2e:be: + 69:f6:f7:6e:8e:9c:60:04:eb:29:fa:c4:47:42:d2: + 78:98:e3:ec:0b:a5:92:dc:b7:9a:bd:80:64:2b:38: + 7c:38:09:5b:66:f6:2d:95:7a:86:b2:34:2e:85:9e: + 90:0e:5f:b7:5d:a4:51:72:46:70:13:bf:67:f2:b6: + a7:4d:14:1e:6c:b9:53:ee:23:1a:4e:8d:48:55:43: + 41:b1:89:75:6a:40:28:c5:7d:dd:d2:6e:d2:02:19: + 2f:7b:24:94:4b:eb:f1:1a:a9:9b:e3:23:9a:ea:fa: + 33:ab:0a:2c:b7:f4:60:08:dd:9f:1c:cd:dd:2d:01: + 66:80:af:b3:2f:29:1d:23:b8:8a:e1:a1:70:07:0c: + 34:0f + Exponent: 65537 (0x10001) + X509v3 extensions: + Authority Information Access: + OCSP - URI:http://s2.symcb.com + + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: http://www.symauth.com/cps + User Notice: + Explicit Text: http://www.symauth.com/rpa + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://s1.symcb.com/pca3-g5.crl + + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Alternative Name: + DirName:/CN=SymantecPKI-1-533 + X509v3 Subject Key Identifier: + 01:59:AB:E7:DD:3A:0B:59:A6:64:63:D6:CF:20:07:57:D5:91:E7:6A + X509v3 Authority Key Identifier: + keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33 + + Signature Algorithm: sha256WithRSAEncryption + 42:01:55:7b:d0:16:1a:5d:58:e8:bb:9b:a8:4d:d7:f3:d7:eb: + 13:94:86:d6:7f:21:0b:47:bc:57:9b:92:5d:4f:05:9f:38:a4: + 10:7c:cf:83:be:06:43:46:8d:08:bc:6a:d7:10:a6:fa:ab:af: + 2f:61:a8:63:f2:65:df:7f:4c:88:12:88:4f:b3:69:d9:ff:27: + c0:0a:97:91:8f:56:fb:89:c4:a8:bb:92:2d:1b:73:b0:c6:ab: + 36:f4:96:6c:20:08:ef:0a:1e:66:24:45:4f:67:00:40:c8:07: + 54:74:33:3b:a6:ad:bb:23:9f:66:ed:a2:44:70:34:fb:0e:ea: + 01:fd:cf:78:74:df:a7:ad:55:b7:5f:4d:f6:d6:3f:e0:86:ce: + 24:c7:42:a9:13:14:44:35:4b:b6:df:c9:60:ac:0c:7f:d9:93: + 21:4b:ee:9c:e4:49:02:98:d3:60:7b:5c:bc:d5:30:2f:07:ce: + 44:42:c4:0b:99:fe:e6:9f:fc:b0:78:86:51:6d:d1:2c:9d:c6: + 96:fb:85:82:bb:04:2f:f7:62:80:ef:62:da:7f:f6:0e:ac:90: + b8:56:bd:79:3f:f2:80:6e:a3:d9:b9:0f:5d:3a:07:1d:91:93: + 86:4b:29:4c:e1:dc:b5:e1:e0:33:9d:b3:cb:36:91:4b:fe:a1: + b4:ee:f0:f9 +-----BEGIN CERTIFICATE----- +MIIFKzCCBBOgAwIBAgIQfuFKb2/v8tN/P61lTTratDANBgkqhkiG9w0BAQsFADCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW +ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5IC0gRzUwHhcNMTMxMDMxMDAwMDAwWhcNMjMxMDMwMjM1OTU5WjB3MQsw +CQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAdBgNV +BAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMTH1N5bWFudGVjIENs +YXNzIDMgRVYgU1NMIENBIC0gRzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQDYoWV0I+grZOIy1zM3PY71NBZI3U9/hxz4RCMTjvsR2ERaGHGOYBYmkpv9 +FwvhcXBC/r/6HMCqo6e1cej/GIP23xAKE2LIPZyn3i4/DNkd5y77Ks7Imn+Hv9hM +BBUyydHMlXGgTihPhNk1++OGb5RT5nKKY2cuvmn2926OnGAE6yn6xEdC0niY4+wL +pZLct5q9gGQrOHw4CVtm9i2VeoayNC6FnpAOX7ddpFFyRnATv2fytqdNFB5suVPu +IxpOjUhVQ0GxiXVqQCjFfd3SbtICGS97JJRL6/EaqZvjI5rq+jOrCiy39GAI3Z8c +zd0tAWaAr7MvKR0juIrhoXAHDDQPAgMBAAGjggFdMIIBWTAvBggrBgEFBQcBAQQj +MCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9zMi5zeW1jYi5jb20wEgYDVR0TAQH/BAgw +BgEB/wIBADBlBgNVHSAEXjBcMFoGBFUdIAAwUjAmBggrBgEFBQcCARYaaHR0cDov +L3d3dy5zeW1hdXRoLmNvbS9jcHMwKAYIKwYBBQUHAgIwHBoaaHR0cDovL3d3dy5z +eW1hdXRoLmNvbS9ycGEwMAYDVR0fBCkwJzAloCOgIYYfaHR0cDovL3MxLnN5bWNi +LmNvbS9wY2EzLWc1LmNybDAOBgNVHQ8BAf8EBAMCAQYwKQYDVR0RBCIwIKQeMBwx +GjAYBgNVBAMTEVN5bWFudGVjUEtJLTEtNTMzMB0GA1UdDgQWBBQBWavn3ToLWaZk +Y9bPIAdX1ZHnajAfBgNVHSMEGDAWgBR/02Wnwt3su/AwCfNDOfoCrzMxMzANBgkq +hkiG9w0BAQsFAAOCAQEAQgFVe9AWGl1Y6LubqE3X89frE5SG1n8hC0e8V5uSXU8F +nzikEHzPg74GQ0aNCLxq1xCm+quvL2GoY/Jl339MiBKIT7Np2f8nwAqXkY9W+4nE +qLuSLRtzsMarNvSWbCAI7woeZiRFT2cAQMgHVHQzO6atuyOfZu2iRHA0+w7qAf3P +eHTfp61Vt19N9tY/4IbOJMdCqRMURDVLtt/JYKwMf9mTIUvunORJApjTYHtcvNUw +LwfORELEC5n+5p/8sHiGUW3RLJ3GlvuFgrsEL/digO9i2n/2DqyQuFa9eT/ygG6j +2bkPXToHHZGThkspTOHcteHgM52zyzaRS/6htO7w+Q== +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert44[] = { + 0x30, 0x82, 0x05, 0x2b, 0x30, 0x82, 0x04, 0x13, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x7e, 0xe1, 0x4a, 0x6f, 0x6f, 0xef, 0xf2, 0xd3, 0x7f, + 0x3f, 0xad, 0x65, 0x4d, 0x3a, 0xda, 0xb4, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, + 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, + 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, + 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, + 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, + 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, + 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, + 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56, + 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, + 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30, + 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x33, 0x31, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x31, 0x30, 0x33, 0x30, + 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x77, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1d, + 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x14, 0x53, 0x79, 0x6d, + 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x13, 0x16, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x1f, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6c, + 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x45, 0x56, 0x20, 0x53, 0x53, 0x4c, + 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x47, 0x33, 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, 0xd8, 0xa1, 0x65, 0x74, 0x23, 0xe8, 0x2b, + 0x64, 0xe2, 0x32, 0xd7, 0x33, 0x37, 0x3d, 0x8e, 0xf5, 0x34, 0x16, 0x48, + 0xdd, 0x4f, 0x7f, 0x87, 0x1c, 0xf8, 0x44, 0x23, 0x13, 0x8e, 0xfb, 0x11, + 0xd8, 0x44, 0x5a, 0x18, 0x71, 0x8e, 0x60, 0x16, 0x26, 0x92, 0x9b, 0xfd, + 0x17, 0x0b, 0xe1, 0x71, 0x70, 0x42, 0xfe, 0xbf, 0xfa, 0x1c, 0xc0, 0xaa, + 0xa3, 0xa7, 0xb5, 0x71, 0xe8, 0xff, 0x18, 0x83, 0xf6, 0xdf, 0x10, 0x0a, + 0x13, 0x62, 0xc8, 0x3d, 0x9c, 0xa7, 0xde, 0x2e, 0x3f, 0x0c, 0xd9, 0x1d, + 0xe7, 0x2e, 0xfb, 0x2a, 0xce, 0xc8, 0x9a, 0x7f, 0x87, 0xbf, 0xd8, 0x4c, + 0x04, 0x15, 0x32, 0xc9, 0xd1, 0xcc, 0x95, 0x71, 0xa0, 0x4e, 0x28, 0x4f, + 0x84, 0xd9, 0x35, 0xfb, 0xe3, 0x86, 0x6f, 0x94, 0x53, 0xe6, 0x72, 0x8a, + 0x63, 0x67, 0x2e, 0xbe, 0x69, 0xf6, 0xf7, 0x6e, 0x8e, 0x9c, 0x60, 0x04, + 0xeb, 0x29, 0xfa, 0xc4, 0x47, 0x42, 0xd2, 0x78, 0x98, 0xe3, 0xec, 0x0b, + 0xa5, 0x92, 0xdc, 0xb7, 0x9a, 0xbd, 0x80, 0x64, 0x2b, 0x38, 0x7c, 0x38, + 0x09, 0x5b, 0x66, 0xf6, 0x2d, 0x95, 0x7a, 0x86, 0xb2, 0x34, 0x2e, 0x85, + 0x9e, 0x90, 0x0e, 0x5f, 0xb7, 0x5d, 0xa4, 0x51, 0x72, 0x46, 0x70, 0x13, + 0xbf, 0x67, 0xf2, 0xb6, 0xa7, 0x4d, 0x14, 0x1e, 0x6c, 0xb9, 0x53, 0xee, + 0x23, 0x1a, 0x4e, 0x8d, 0x48, 0x55, 0x43, 0x41, 0xb1, 0x89, 0x75, 0x6a, + 0x40, 0x28, 0xc5, 0x7d, 0xdd, 0xd2, 0x6e, 0xd2, 0x02, 0x19, 0x2f, 0x7b, + 0x24, 0x94, 0x4b, 0xeb, 0xf1, 0x1a, 0xa9, 0x9b, 0xe3, 0x23, 0x9a, 0xea, + 0xfa, 0x33, 0xab, 0x0a, 0x2c, 0xb7, 0xf4, 0x60, 0x08, 0xdd, 0x9f, 0x1c, + 0xcd, 0xdd, 0x2d, 0x01, 0x66, 0x80, 0xaf, 0xb3, 0x2f, 0x29, 0x1d, 0x23, + 0xb8, 0x8a, 0xe1, 0xa1, 0x70, 0x07, 0x0c, 0x34, 0x0f, 0x02, 0x03, 0x01, + 0x00, 0x01, 0xa3, 0x82, 0x01, 0x5d, 0x30, 0x82, 0x01, 0x59, 0x30, 0x2f, + 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x23, + 0x30, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x30, 0x01, 0x86, 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, + 0x32, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x30, + 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, + 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x65, 0x06, 0x03, 0x55, + 0x1d, 0x20, 0x04, 0x5e, 0x30, 0x5c, 0x30, 0x5a, 0x06, 0x04, 0x55, 0x1d, + 0x20, 0x00, 0x30, 0x52, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x79, 0x6d, 0x61, 0x75, 0x74, 0x68, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x28, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x1c, 0x1a, 0x1a, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, + 0x79, 0x6d, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, + 0x70, 0x61, 0x30, 0x30, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x29, 0x30, + 0x27, 0x30, 0x25, 0xa0, 0x23, 0xa0, 0x21, 0x86, 0x1f, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x31, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33, 0x2d, 0x67, 0x35, + 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, + 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x29, 0x06, 0x03, + 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, 0x31, + 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, 0x79, + 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, 0x2d, + 0x35, 0x33, 0x33, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, + 0x04, 0x14, 0x01, 0x59, 0xab, 0xe7, 0xdd, 0x3a, 0x0b, 0x59, 0xa6, 0x64, + 0x63, 0xd6, 0xcf, 0x20, 0x07, 0x57, 0xd5, 0x91, 0xe7, 0x6a, 0x30, 0x1f, + 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x7f, + 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3, 0x43, + 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, + 0x01, 0x01, 0x00, 0x42, 0x01, 0x55, 0x7b, 0xd0, 0x16, 0x1a, 0x5d, 0x58, + 0xe8, 0xbb, 0x9b, 0xa8, 0x4d, 0xd7, 0xf3, 0xd7, 0xeb, 0x13, 0x94, 0x86, + 0xd6, 0x7f, 0x21, 0x0b, 0x47, 0xbc, 0x57, 0x9b, 0x92, 0x5d, 0x4f, 0x05, + 0x9f, 0x38, 0xa4, 0x10, 0x7c, 0xcf, 0x83, 0xbe, 0x06, 0x43, 0x46, 0x8d, + 0x08, 0xbc, 0x6a, 0xd7, 0x10, 0xa6, 0xfa, 0xab, 0xaf, 0x2f, 0x61, 0xa8, + 0x63, 0xf2, 0x65, 0xdf, 0x7f, 0x4c, 0x88, 0x12, 0x88, 0x4f, 0xb3, 0x69, + 0xd9, 0xff, 0x27, 0xc0, 0x0a, 0x97, 0x91, 0x8f, 0x56, 0xfb, 0x89, 0xc4, + 0xa8, 0xbb, 0x92, 0x2d, 0x1b, 0x73, 0xb0, 0xc6, 0xab, 0x36, 0xf4, 0x96, + 0x6c, 0x20, 0x08, 0xef, 0x0a, 0x1e, 0x66, 0x24, 0x45, 0x4f, 0x67, 0x00, + 0x40, 0xc8, 0x07, 0x54, 0x74, 0x33, 0x3b, 0xa6, 0xad, 0xbb, 0x23, 0x9f, + 0x66, 0xed, 0xa2, 0x44, 0x70, 0x34, 0xfb, 0x0e, 0xea, 0x01, 0xfd, 0xcf, + 0x78, 0x74, 0xdf, 0xa7, 0xad, 0x55, 0xb7, 0x5f, 0x4d, 0xf6, 0xd6, 0x3f, + 0xe0, 0x86, 0xce, 0x24, 0xc7, 0x42, 0xa9, 0x13, 0x14, 0x44, 0x35, 0x4b, + 0xb6, 0xdf, 0xc9, 0x60, 0xac, 0x0c, 0x7f, 0xd9, 0x93, 0x21, 0x4b, 0xee, + 0x9c, 0xe4, 0x49, 0x02, 0x98, 0xd3, 0x60, 0x7b, 0x5c, 0xbc, 0xd5, 0x30, + 0x2f, 0x07, 0xce, 0x44, 0x42, 0xc4, 0x0b, 0x99, 0xfe, 0xe6, 0x9f, 0xfc, + 0xb0, 0x78, 0x86, 0x51, 0x6d, 0xd1, 0x2c, 0x9d, 0xc6, 0x96, 0xfb, 0x85, + 0x82, 0xbb, 0x04, 0x2f, 0xf7, 0x62, 0x80, 0xef, 0x62, 0xda, 0x7f, 0xf6, + 0x0e, 0xac, 0x90, 0xb8, 0x56, 0xbd, 0x79, 0x3f, 0xf2, 0x80, 0x6e, 0xa3, + 0xd9, 0xb9, 0x0f, 0x5d, 0x3a, 0x07, 0x1d, 0x91, 0x93, 0x86, 0x4b, 0x29, + 0x4c, 0xe1, 0xdc, 0xb5, 0xe1, 0xe0, 0x33, 0x9d, 0xb3, 0xcb, 0x36, 0x91, + 0x4b, 0xfe, 0xa1, 0xb4, 0xee, 0xf0, 0xf9, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 51:3f:b9:74:38:70:b7:34:40:41:8d:30:93:06:99:ff + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2006 VeriSign, Inc. - For authorized use only, CN=VeriSign Class 3 Public Primary Certification Authority - G5 + Validity + Not Before: Oct 31 00:00:00 2013 GMT + Not After : Oct 30 23:59:59 2023 GMT + Subject: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 Secure Server CA - G4 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:b2:d8:05:ca:1c:74:2d:b5:17:56:39:c5:4a:52: + 09:96:e8:4b:d8:0c:f1:68:9f:9a:42:28:62:c3:a5: + 30:53:7e:55:11:82:5b:03:7a:0d:2f:e1:79:04:c9: + b4:96:77:19:81:01:94:59:f9:bc:f7:7a:99:27:82: + 2d:b7:83:dd:5a:27:7f:b2:03:7a:9c:53:25:e9:48: + 1f:46:4f:c8:9d:29:f8:be:79:56:f6:f7:fd:d9:3a: + 68:da:8b:4b:82:33:41:12:c3:c8:3c:cc:d6:96:7a: + 84:21:1a:22:04:03:27:17:8b:1c:68:61:93:0f:0e: + 51:80:33:1d:b4:b5:ce:eb:7e:d0:62:ac:ee:b3:7b: + 01:74:ef:69:35:eb:ca:d5:3d:a9:ee:97:98:ca:8d: + aa:44:0e:25:99:4a:15:96:a4:ce:6d:02:54:1f:2a: + 6a:26:e2:06:3a:63:48:ac:b4:4c:d1:75:93:50:ff: + 13:2f:d6:da:e1:c6:18:f5:9f:c9:25:5d:f3:00:3a: + de:26:4d:b4:29:09:cd:0f:3d:23:6f:16:4a:81:16: + fb:f2:83:10:c3:b8:d6:d8:55:32:3d:f1:bd:0f:bd: + 8c:52:95:4a:16:97:7a:52:21:63:75:2f:16:f9:c4: + 66:be:f5:b5:09:d8:ff:27:00:cd:44:7c:6f:4b:3f: + b0:f7 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 CRL Distribution Points: + + Full Name: + URI:http://s1.symcb.com/pca3-g5.crl + + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + Authority Information Access: + OCSP - URI:http://s2.symcb.com + + X509v3 Certificate Policies: + Policy: 2.16.840.1.113733.1.7.54 + CPS: http://www.symauth.com/cps + User Notice: + Explicit Text: http://www.symauth.com/rpa + + X509v3 Subject Alternative Name: + DirName:/CN=SymantecPKI-1-534 + X509v3 Subject Key Identifier: + 5F:60:CF:61:90:55:DF:84:43:14:8A:60:2A:B2:F5:7A:F4:43:18:EF + X509v3 Authority Key Identifier: + keyid:7F:D3:65:A7:C2:DD:EC:BB:F0:30:09:F3:43:39:FA:02:AF:33:31:33 + + Signature Algorithm: sha256WithRSAEncryption + 5e:94:56:49:dd:8e:2d:65:f5:c1:36:51:b6:03:e3:da:9e:73: + 19:f2:1f:59:ab:58:7e:6c:26:05:2c:fa:81:d7:5c:23:17:22: + 2c:37:93:f7:86:ec:85:e6:b0:a3:fd:1f:e2:32:a8:45:6f:e1: + d9:fb:b9:af:d2:70:a0:32:42:65:bf:84:fe:16:2a:8f:3f:c5: + a6:d6:a3:93:7d:43:e9:74:21:91:35:28:f4:63:e9:2e:ed:f7: + f5:5c:7f:4b:9a:b5:20:e9:0a:bd:e0:45:10:0c:14:94:9a:5d: + a5:e3:4b:91:e8:24:9b:46:40:65:f4:22:72:cd:99:f8:88:11: + f5:f3:7f:e6:33:82:e6:a8:c5:7e:fe:d0:08:e2:25:58:08:71: + 68:e6:cd:a2:e6:14:de:4e:52:24:2d:fd:e5:79:13:53:e7:5e: + 2f:2d:4d:1b:6d:40:15:52:2b:f7:87:89:78:12:81:6e:d9:4d: + aa:2d:78:d4:c2:2c:3d:08:5f:87:91:9e:1f:0e:b0:de:30:52: + 64:86:89:aa:9d:66:9c:0e:76:0c:80:f2:74:d8:2a:f8:b8:3a: + ce:d7:d6:0f:11:be:6b:ab:14:f5:bd:41:a0:22:63:89:f1:ba: + 0f:6f:29:63:66:2d:3f:ac:8c:72:c5:fb:c7:e4:d4:0f:f2:3b: + 4f:8c:29:c7 +-----BEGIN CERTIFICATE----- +MIIFODCCBCCgAwIBAgIQUT+5dDhwtzRAQY0wkwaZ/zANBgkqhkiG9w0BAQsFADCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW +ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5IC0gRzUwHhcNMTMxMDMxMDAwMDAwWhcNMjMxMDMwMjM1OTU5WjB+MQsw +CQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAdBgNV +BAsTFlN5bWFudGVjIFRydXN0IE5ldHdvcmsxLzAtBgNVBAMTJlN5bWFudGVjIENs +YXNzIDMgU2VjdXJlIFNlcnZlciBDQSAtIEc0MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAstgFyhx0LbUXVjnFSlIJluhL2AzxaJ+aQihiw6UwU35VEYJb +A3oNL+F5BMm0lncZgQGUWfm893qZJ4Itt4PdWid/sgN6nFMl6UgfRk/InSn4vnlW +9vf92Tpo2otLgjNBEsPIPMzWlnqEIRoiBAMnF4scaGGTDw5RgDMdtLXO637QYqzu +s3sBdO9pNevK1T2p7peYyo2qRA4lmUoVlqTObQJUHypqJuIGOmNIrLRM0XWTUP8T +L9ba4cYY9Z/JJV3zADreJk20KQnNDz0jbxZKgRb78oMQw7jW2FUyPfG9D72MUpVK +Fpd6UiFjdS8W+cRmvvW1Cdj/JwDNRHxvSz+w9wIDAQABo4IBYzCCAV8wEgYDVR0T +AQH/BAgwBgEB/wIBADAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vczEuc3ltY2Iu +Y29tL3BjYTMtZzUuY3JsMA4GA1UdDwEB/wQEAwIBBjAvBggrBgEFBQcBAQQjMCEw +HwYIKwYBBQUHMAGGE2h0dHA6Ly9zMi5zeW1jYi5jb20wawYDVR0gBGQwYjBgBgpg +hkgBhvhFAQc2MFIwJgYIKwYBBQUHAgEWGmh0dHA6Ly93d3cuc3ltYXV0aC5jb20v +Y3BzMCgGCCsGAQUFBwICMBwaGmh0dHA6Ly93d3cuc3ltYXV0aC5jb20vcnBhMCkG +A1UdEQQiMCCkHjAcMRowGAYDVQQDExFTeW1hbnRlY1BLSS0xLTUzNDAdBgNVHQ4E +FgQUX2DPYZBV34RDFIpgKrL1evRDGO8wHwYDVR0jBBgwFoAUf9Nlp8Ld7LvwMAnz +Qzn6Aq8zMTMwDQYJKoZIhvcNAQELBQADggEBAF6UVkndji1l9cE2UbYD49qecxny +H1mrWH5sJgUs+oHXXCMXIiw3k/eG7IXmsKP9H+IyqEVv4dn7ua/ScKAyQmW/hP4W +Ko8/xabWo5N9Q+l0IZE1KPRj6S7t9/Vcf0uatSDpCr3gRRAMFJSaXaXjS5HoJJtG +QGX0InLNmfiIEfXzf+YzguaoxX7+0AjiJVgIcWjmzaLmFN5OUiQt/eV5E1PnXi8t +TRttQBVSK/eHiXgSgW7ZTaoteNTCLD0IX4eRnh8OsN4wUmSGiaqdZpwOdgyA8nTY +Kvi4Os7X1g8RvmurFPW9QaAiY4nxug9vKWNmLT+sjHLF+8fk1A/yO0+MKcc= +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert45[] = { + 0x30, 0x82, 0x05, 0x38, 0x30, 0x82, 0x04, 0x20, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x51, 0x3f, 0xb9, 0x74, 0x38, 0x70, 0xb7, 0x34, 0x40, + 0x41, 0x8d, 0x30, 0x93, 0x06, 0x99, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, + 0xca, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, + 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, + 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, + 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x56, 0x65, 0x72, 0x69, + 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, + 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, + 0x31, 0x45, 0x30, 0x43, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x3c, 0x56, + 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, 0x61, 0x73, + 0x73, 0x20, 0x33, 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x50, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, + 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x2d, 0x20, 0x47, 0x35, 0x30, + 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x30, 0x33, 0x31, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x31, 0x30, 0x33, 0x30, + 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x7e, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1d, + 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x14, 0x53, 0x79, 0x6d, + 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x13, 0x16, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x26, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6c, + 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20, 0x2d, + 0x20, 0x47, 0x34, 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, + 0xb2, 0xd8, 0x05, 0xca, 0x1c, 0x74, 0x2d, 0xb5, 0x17, 0x56, 0x39, 0xc5, + 0x4a, 0x52, 0x09, 0x96, 0xe8, 0x4b, 0xd8, 0x0c, 0xf1, 0x68, 0x9f, 0x9a, + 0x42, 0x28, 0x62, 0xc3, 0xa5, 0x30, 0x53, 0x7e, 0x55, 0x11, 0x82, 0x5b, + 0x03, 0x7a, 0x0d, 0x2f, 0xe1, 0x79, 0x04, 0xc9, 0xb4, 0x96, 0x77, 0x19, + 0x81, 0x01, 0x94, 0x59, 0xf9, 0xbc, 0xf7, 0x7a, 0x99, 0x27, 0x82, 0x2d, + 0xb7, 0x83, 0xdd, 0x5a, 0x27, 0x7f, 0xb2, 0x03, 0x7a, 0x9c, 0x53, 0x25, + 0xe9, 0x48, 0x1f, 0x46, 0x4f, 0xc8, 0x9d, 0x29, 0xf8, 0xbe, 0x79, 0x56, + 0xf6, 0xf7, 0xfd, 0xd9, 0x3a, 0x68, 0xda, 0x8b, 0x4b, 0x82, 0x33, 0x41, + 0x12, 0xc3, 0xc8, 0x3c, 0xcc, 0xd6, 0x96, 0x7a, 0x84, 0x21, 0x1a, 0x22, + 0x04, 0x03, 0x27, 0x17, 0x8b, 0x1c, 0x68, 0x61, 0x93, 0x0f, 0x0e, 0x51, + 0x80, 0x33, 0x1d, 0xb4, 0xb5, 0xce, 0xeb, 0x7e, 0xd0, 0x62, 0xac, 0xee, + 0xb3, 0x7b, 0x01, 0x74, 0xef, 0x69, 0x35, 0xeb, 0xca, 0xd5, 0x3d, 0xa9, + 0xee, 0x97, 0x98, 0xca, 0x8d, 0xaa, 0x44, 0x0e, 0x25, 0x99, 0x4a, 0x15, + 0x96, 0xa4, 0xce, 0x6d, 0x02, 0x54, 0x1f, 0x2a, 0x6a, 0x26, 0xe2, 0x06, + 0x3a, 0x63, 0x48, 0xac, 0xb4, 0x4c, 0xd1, 0x75, 0x93, 0x50, 0xff, 0x13, + 0x2f, 0xd6, 0xda, 0xe1, 0xc6, 0x18, 0xf5, 0x9f, 0xc9, 0x25, 0x5d, 0xf3, + 0x00, 0x3a, 0xde, 0x26, 0x4d, 0xb4, 0x29, 0x09, 0xcd, 0x0f, 0x3d, 0x23, + 0x6f, 0x16, 0x4a, 0x81, 0x16, 0xfb, 0xf2, 0x83, 0x10, 0xc3, 0xb8, 0xd6, + 0xd8, 0x55, 0x32, 0x3d, 0xf1, 0xbd, 0x0f, 0xbd, 0x8c, 0x52, 0x95, 0x4a, + 0x16, 0x97, 0x7a, 0x52, 0x21, 0x63, 0x75, 0x2f, 0x16, 0xf9, 0xc4, 0x66, + 0xbe, 0xf5, 0xb5, 0x09, 0xd8, 0xff, 0x27, 0x00, 0xcd, 0x44, 0x7c, 0x6f, + 0x4b, 0x3f, 0xb0, 0xf7, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, + 0x63, 0x30, 0x82, 0x01, 0x5f, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, + 0x00, 0x30, 0x30, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x29, 0x30, 0x27, + 0x30, 0x25, 0xa0, 0x23, 0xa0, 0x21, 0x86, 0x1f, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x73, 0x31, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33, 0x2d, 0x67, 0x35, 0x2e, + 0x63, 0x72, 0x6c, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, + 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x2f, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x23, 0x30, 0x21, 0x30, + 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, + 0x13, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x73, 0x32, 0x2e, 0x73, + 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x6b, 0x06, 0x03, + 0x55, 0x1d, 0x20, 0x04, 0x64, 0x30, 0x62, 0x30, 0x60, 0x06, 0x0a, 0x60, + 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, 0x36, 0x30, 0x52, 0x30, + 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, + 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, + 0x73, 0x79, 0x6d, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x63, 0x70, 0x73, 0x30, 0x28, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x02, 0x02, 0x30, 0x1c, 0x1a, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x79, 0x6d, 0x61, 0x75, 0x74, + 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x70, 0x61, 0x30, 0x29, 0x06, + 0x03, 0x55, 0x1d, 0x11, 0x04, 0x22, 0x30, 0x20, 0xa4, 0x1e, 0x30, 0x1c, + 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x53, + 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x50, 0x4b, 0x49, 0x2d, 0x31, + 0x2d, 0x35, 0x33, 0x34, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, + 0x16, 0x04, 0x14, 0x5f, 0x60, 0xcf, 0x61, 0x90, 0x55, 0xdf, 0x84, 0x43, + 0x14, 0x8a, 0x60, 0x2a, 0xb2, 0xf5, 0x7a, 0xf4, 0x43, 0x18, 0xef, 0x30, + 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, + 0x7f, 0xd3, 0x65, 0xa7, 0xc2, 0xdd, 0xec, 0xbb, 0xf0, 0x30, 0x09, 0xf3, + 0x43, 0x39, 0xfa, 0x02, 0xaf, 0x33, 0x31, 0x33, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, + 0x82, 0x01, 0x01, 0x00, 0x5e, 0x94, 0x56, 0x49, 0xdd, 0x8e, 0x2d, 0x65, + 0xf5, 0xc1, 0x36, 0x51, 0xb6, 0x03, 0xe3, 0xda, 0x9e, 0x73, 0x19, 0xf2, + 0x1f, 0x59, 0xab, 0x58, 0x7e, 0x6c, 0x26, 0x05, 0x2c, 0xfa, 0x81, 0xd7, + 0x5c, 0x23, 0x17, 0x22, 0x2c, 0x37, 0x93, 0xf7, 0x86, 0xec, 0x85, 0xe6, + 0xb0, 0xa3, 0xfd, 0x1f, 0xe2, 0x32, 0xa8, 0x45, 0x6f, 0xe1, 0xd9, 0xfb, + 0xb9, 0xaf, 0xd2, 0x70, 0xa0, 0x32, 0x42, 0x65, 0xbf, 0x84, 0xfe, 0x16, + 0x2a, 0x8f, 0x3f, 0xc5, 0xa6, 0xd6, 0xa3, 0x93, 0x7d, 0x43, 0xe9, 0x74, + 0x21, 0x91, 0x35, 0x28, 0xf4, 0x63, 0xe9, 0x2e, 0xed, 0xf7, 0xf5, 0x5c, + 0x7f, 0x4b, 0x9a, 0xb5, 0x20, 0xe9, 0x0a, 0xbd, 0xe0, 0x45, 0x10, 0x0c, + 0x14, 0x94, 0x9a, 0x5d, 0xa5, 0xe3, 0x4b, 0x91, 0xe8, 0x24, 0x9b, 0x46, + 0x40, 0x65, 0xf4, 0x22, 0x72, 0xcd, 0x99, 0xf8, 0x88, 0x11, 0xf5, 0xf3, + 0x7f, 0xe6, 0x33, 0x82, 0xe6, 0xa8, 0xc5, 0x7e, 0xfe, 0xd0, 0x08, 0xe2, + 0x25, 0x58, 0x08, 0x71, 0x68, 0xe6, 0xcd, 0xa2, 0xe6, 0x14, 0xde, 0x4e, + 0x52, 0x24, 0x2d, 0xfd, 0xe5, 0x79, 0x13, 0x53, 0xe7, 0x5e, 0x2f, 0x2d, + 0x4d, 0x1b, 0x6d, 0x40, 0x15, 0x52, 0x2b, 0xf7, 0x87, 0x89, 0x78, 0x12, + 0x81, 0x6e, 0xd9, 0x4d, 0xaa, 0x2d, 0x78, 0xd4, 0xc2, 0x2c, 0x3d, 0x08, + 0x5f, 0x87, 0x91, 0x9e, 0x1f, 0x0e, 0xb0, 0xde, 0x30, 0x52, 0x64, 0x86, + 0x89, 0xaa, 0x9d, 0x66, 0x9c, 0x0e, 0x76, 0x0c, 0x80, 0xf2, 0x74, 0xd8, + 0x2a, 0xf8, 0xb8, 0x3a, 0xce, 0xd7, 0xd6, 0x0f, 0x11, 0xbe, 0x6b, 0xab, + 0x14, 0xf5, 0xbd, 0x41, 0xa0, 0x22, 0x63, 0x89, 0xf1, 0xba, 0x0f, 0x6f, + 0x29, 0x63, 0x66, 0x2d, 0x3f, 0xac, 0x8c, 0x72, 0xc5, 0xfb, 0xc7, 0xe4, + 0xd4, 0x0f, 0xf2, 0x3b, 0x4f, 0x8c, 0x29, 0xc7, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 69:87:94:19:d9:e3:62:70:74:9d:bb:e5:9d:c6:68:5e + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=VeriSign, Inc., OU=VeriSign Trust Network, OU=(c) 2008 VeriSign, Inc. - For authorized use only, CN=VeriSign Universal Root Certification Authority + Validity + Not Before: Apr 9 00:00:00 2013 GMT + Not After : Apr 8 23:59:59 2023 GMT + Subject: C=US, O=Symantec Corporation, OU=Symantec Trust Network, CN=Symantec Class 3 Secure Server SHA256 SSL CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:be:38:16:51:8b:80:db:ea:0e:4d:ec:e8:3f:5c: + c4:7c:a2:5d:ed:3b:af:a5:d6:9e:10:35:2c:e3:c5: + e5:a8:de:8c:86:17:26:e6:de:0b:51:4a:2c:d0:fb: + d1:14:5a:72:f7:c9:dd:b8:83:1c:c6:46:8c:31:25: + 91:0e:59:17:a3:d0:13:8c:92:c1:af:81:54:4e:bc: + 62:02:9e:aa:a7:1a:57:d8:ca:a6:99:7a:70:56:4f: + 98:07:2e:4b:96:d0:4c:39:53:b9:61:2f:3b:76:7c: + 8e:05:9e:99:44:d1:03:54:77:29:2b:56:2a:aa:61: + e4:84:2f:12:15:3c:bd:d7:8a:e8:09:1e:56:f1:b5: + 14:ac:8a:84:ce:ae:78:a2:60:0a:53:7e:13:4c:1a: + 40:70:0e:52:59:ff:5a:68:2e:4c:46:13:3b:39:09: + 82:78:02:35:49:20:08:82:b3:b1:6c:89:0f:6e:1e: + 35:25:b0:2c:24:83:e3:c5:50:2c:ba:46:90:45:87: + 0d:72:ff:5d:11:38:c5:91:76:c5:2c:fb:05:2a:82: + 95:a1:59:63:e3:d0:26:58:cd:67:56:3a:ba:df:7c: + d2:d2:3b:d8:de:1a:7a:77:e4:0c:8c:0b:eb:2b:c2: + 22:b0:bd:55:ba:d9:b9:55:d1:22:7a:c6:02:4e:3f: + c3:35 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.ws.symantec.com/universal-root.crl + + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + Authority Information Access: + OCSP - URI:http://ocsp.ws.symantec.com + + X509v3 Certificate Policies: + Policy: 2.16.840.1.113733.1.7.54 + CPS: http://www.symauth.com/cps + User Notice: + Explicit Text: http://www.symauth.com/rpa + + X509v3 Subject Alternative Name: + DirName:/CN=VeriSignMPKI-2-373 + X509v3 Subject Key Identifier: + DB:62:20:FB:7D:02:89:7C:D2:3B:6F:C7:E4:32:6C:05:52:1D:AD:B1 + X509v3 Authority Key Identifier: + keyid:B6:77:FA:69:48:47:9F:53:12:D5:C2:EA:07:32:76:07:D1:97:07:19 + + Signature Algorithm: sha256WithRSAEncryption + 19:cc:95:e2:2f:7b:49:d0:48:90:53:f4:07:b1:20:44:35:70: + 14:d5:44:37:31:ef:ef:70:d1:2d:4c:e9:2d:b0:53:91:01:4c: + 54:e7:7d:9b:da:3a:ff:b7:cb:14:ad:30:0f:69:1a:2a:f0:bc: + cd:35:eb:48:dc:b9:87:fd:cf:b1:5a:f6:05:da:3c:64:e6:2b: + e6:dc:73:5e:9a:d8:0c:9b:d2:97:b3:e8:fa:87:95:53:e1:99: + ad:88:e8:fa:bc:09:4d:a2:c4:6a:1b:28:3b:2d:c3:21:15:ee: + 14:fa:9d:98:10:eb:9f:3e:e6:24:24:5f:7a:1c:05:bb:9a:31: + 23:58:79:4c:ec:6d:18:19:4d:51:1f:08:61:bd:91:05:0c:5a: + 9c:26:fc:0b:a5:20:25:bf:6a:1b:2b:f7:02:09:72:69:83:32: + 14:c3:60:5b:7e:fd:9a:32:fa:b4:95:0e:1a:f9:3b:09:a4:54: + 47:9a:0c:ce:32:af:d1:21:cc:7f:d2:06:ef:60:0e:62:6f:6f: + 81:1a:17:9d:c8:cb:28:cc:e2:5f:6e:2c:7a:b4:cb:47:7c:74: + 68:7b:48:71:02:9c:23:09:f3:5a:ae:5f:42:2e:5f:2b:59:2d: + 52:88:e5:8d:0b:b3:a8:61:f9:4b:9b:55:d6:da:b1:92:3b:bf: + c3:9b:f9:2c +-----BEGIN CERTIFICATE----- +MIIFSTCCBDGgAwIBAgIQaYeUGdnjYnB0nbvlncZoXjANBgkqhkiG9w0BAQsFADCB +vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W +ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0xMzA0MDkwMDAwMDBaFw0yMzA0MDgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEd +MBsGA1UEChMUU3ltYW50ZWMgQ29ycG9yYXRpb24xHzAdBgNVBAsTFlN5bWFudGVj +IFRydXN0IE5ldHdvcmsxNTAzBgNVBAMTLFN5bWFudGVjIENsYXNzIDMgU2VjdXJl +IFNlcnZlciBTSEEyNTYgU1NMIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAvjgWUYuA2+oOTezoP1zEfKJd7TuvpdaeEDUs48XlqN6Mhhcm5t4LUUos +0PvRFFpy98nduIMcxkaMMSWRDlkXo9ATjJLBr4FUTrxiAp6qpxpX2MqmmXpwVk+Y +By5LltBMOVO5YS87dnyOBZ6ZRNEDVHcpK1YqqmHkhC8SFTy914roCR5W8bUUrIqE +zq54omAKU34TTBpAcA5SWf9aaC5MRhM7OQmCeAI1SSAIgrOxbIkPbh41JbAsJIPj +xVAsukaQRYcNcv9dETjFkXbFLPsFKoKVoVlj49AmWM1nVjq633zS0jvY3hp6d+QM +jAvrK8IisL1Vutm5VdEiesYCTj/DNQIDAQABo4IBejCCAXYwEgYDVR0TAQH/BAgw +BgEB/wIBADA+BgNVHR8ENzA1MDOgMaAvhi1odHRwOi8vY3JsLndzLnN5bWFudGVj +LmNvbS91bml2ZXJzYWwtcm9vdC5jcmwwDgYDVR0PAQH/BAQDAgEGMDcGCCsGAQUF +BwEBBCswKTAnBggrBgEFBQcwAYYbaHR0cDovL29jc3Aud3Muc3ltYW50ZWMuY29t +MGsGA1UdIARkMGIwYAYKYIZIAYb4RQEHNjBSMCYGCCsGAQUFBwIBFhpodHRwOi8v +d3d3LnN5bWF1dGguY29tL2NwczAoBggrBgEFBQcCAjAcGhpodHRwOi8vd3d3LnN5 +bWF1dGguY29tL3JwYTAqBgNVHREEIzAhpB8wHTEbMBkGA1UEAxMSVmVyaVNpZ25N +UEtJLTItMzczMB0GA1UdDgQWBBTbYiD7fQKJfNI7b8fkMmwFUh2tsTAfBgNVHSME +GDAWgBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEAGcyV +4i97SdBIkFP0B7EgRDVwFNVENzHv73DRLUzpLbBTkQFMVOd9m9o6/7fLFK0wD2ka +KvC8zTXrSNy5h/3PsVr2Bdo8ZOYr5txzXprYDJvSl7Po+oeVU+GZrYjo+rwJTaLE +ahsoOy3DIRXuFPqdmBDrnz7mJCRfehwFu5oxI1h5TOxtGBlNUR8IYb2RBQxanCb8 +C6UgJb9qGyv3AglyaYMyFMNgW379mjL6tJUOGvk7CaRUR5oMzjKv0SHMf9IG72AO +Ym9vgRoXncjLKMziX24serTLR3x0aHtIcQKcIwnzWq5fQi5fK1ktUojljQuzqGH5 +S5tV1tqxkju/w5v5LA== +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert46[] = { + 0x30, 0x82, 0x05, 0x49, 0x30, 0x82, 0x04, 0x31, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x69, 0x87, 0x94, 0x19, 0xd9, 0xe3, 0x62, 0x70, 0x74, + 0x9d, 0xbb, 0xe5, 0x9d, 0xc6, 0x68, 0x5e, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, + 0xbd, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, + 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, + 0x6e, 0x63, 0x2e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0b, + 0x13, 0x16, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54, + 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x31, 0x3a, 0x30, 0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x28, + 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x38, 0x20, 0x56, 0x65, 0x72, 0x69, + 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x2d, + 0x20, 0x46, 0x6f, 0x72, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x65, 0x64, 0x20, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x6e, 0x6c, 0x79, + 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x2f, 0x56, + 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x55, 0x6e, 0x69, 0x76, + 0x65, 0x72, 0x73, 0x61, 0x6c, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, + 0x17, 0x0d, 0x31, 0x33, 0x30, 0x34, 0x30, 0x39, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x34, 0x30, 0x38, 0x32, + 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x81, 0x84, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1d, + 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x14, 0x53, 0x79, 0x6d, + 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x13, 0x16, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x31, 0x35, 0x30, 0x33, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x2c, 0x53, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x20, 0x43, 0x6c, + 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, + 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x53, 0x48, 0x41, 0x32, + 0x35, 0x36, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x43, 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, 0xbe, 0x38, 0x16, 0x51, 0x8b, 0x80, + 0xdb, 0xea, 0x0e, 0x4d, 0xec, 0xe8, 0x3f, 0x5c, 0xc4, 0x7c, 0xa2, 0x5d, + 0xed, 0x3b, 0xaf, 0xa5, 0xd6, 0x9e, 0x10, 0x35, 0x2c, 0xe3, 0xc5, 0xe5, + 0xa8, 0xde, 0x8c, 0x86, 0x17, 0x26, 0xe6, 0xde, 0x0b, 0x51, 0x4a, 0x2c, + 0xd0, 0xfb, 0xd1, 0x14, 0x5a, 0x72, 0xf7, 0xc9, 0xdd, 0xb8, 0x83, 0x1c, + 0xc6, 0x46, 0x8c, 0x31, 0x25, 0x91, 0x0e, 0x59, 0x17, 0xa3, 0xd0, 0x13, + 0x8c, 0x92, 0xc1, 0xaf, 0x81, 0x54, 0x4e, 0xbc, 0x62, 0x02, 0x9e, 0xaa, + 0xa7, 0x1a, 0x57, 0xd8, 0xca, 0xa6, 0x99, 0x7a, 0x70, 0x56, 0x4f, 0x98, + 0x07, 0x2e, 0x4b, 0x96, 0xd0, 0x4c, 0x39, 0x53, 0xb9, 0x61, 0x2f, 0x3b, + 0x76, 0x7c, 0x8e, 0x05, 0x9e, 0x99, 0x44, 0xd1, 0x03, 0x54, 0x77, 0x29, + 0x2b, 0x56, 0x2a, 0xaa, 0x61, 0xe4, 0x84, 0x2f, 0x12, 0x15, 0x3c, 0xbd, + 0xd7, 0x8a, 0xe8, 0x09, 0x1e, 0x56, 0xf1, 0xb5, 0x14, 0xac, 0x8a, 0x84, + 0xce, 0xae, 0x78, 0xa2, 0x60, 0x0a, 0x53, 0x7e, 0x13, 0x4c, 0x1a, 0x40, + 0x70, 0x0e, 0x52, 0x59, 0xff, 0x5a, 0x68, 0x2e, 0x4c, 0x46, 0x13, 0x3b, + 0x39, 0x09, 0x82, 0x78, 0x02, 0x35, 0x49, 0x20, 0x08, 0x82, 0xb3, 0xb1, + 0x6c, 0x89, 0x0f, 0x6e, 0x1e, 0x35, 0x25, 0xb0, 0x2c, 0x24, 0x83, 0xe3, + 0xc5, 0x50, 0x2c, 0xba, 0x46, 0x90, 0x45, 0x87, 0x0d, 0x72, 0xff, 0x5d, + 0x11, 0x38, 0xc5, 0x91, 0x76, 0xc5, 0x2c, 0xfb, 0x05, 0x2a, 0x82, 0x95, + 0xa1, 0x59, 0x63, 0xe3, 0xd0, 0x26, 0x58, 0xcd, 0x67, 0x56, 0x3a, 0xba, + 0xdf, 0x7c, 0xd2, 0xd2, 0x3b, 0xd8, 0xde, 0x1a, 0x7a, 0x77, 0xe4, 0x0c, + 0x8c, 0x0b, 0xeb, 0x2b, 0xc2, 0x22, 0xb0, 0xbd, 0x55, 0xba, 0xd9, 0xb9, + 0x55, 0xd1, 0x22, 0x7a, 0xc6, 0x02, 0x4e, 0x3f, 0xc3, 0x35, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x7a, 0x30, 0x82, 0x01, 0x76, 0x30, + 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, + 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x3e, 0x06, 0x03, 0x55, + 0x1d, 0x1f, 0x04, 0x37, 0x30, 0x35, 0x30, 0x33, 0xa0, 0x31, 0xa0, 0x2f, + 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, + 0x2e, 0x77, 0x73, 0x2e, 0x73, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x75, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, + 0x61, 0x6c, 0x2d, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x72, 0x6c, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, + 0x02, 0x01, 0x06, 0x30, 0x37, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x01, 0x01, 0x04, 0x2b, 0x30, 0x29, 0x30, 0x27, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x1b, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x77, 0x73, 0x2e, + 0x73, 0x79, 0x6d, 0x61, 0x6e, 0x74, 0x65, 0x63, 0x2e, 0x63, 0x6f, 0x6d, + 0x30, 0x6b, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x64, 0x30, 0x62, 0x30, + 0x60, 0x06, 0x0a, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x07, + 0x36, 0x30, 0x52, 0x30, 0x26, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x02, 0x01, 0x16, 0x1a, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x77, 0x77, 0x77, 0x2e, 0x73, 0x79, 0x6d, 0x61, 0x75, 0x74, 0x68, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x70, 0x73, 0x30, 0x28, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, 0x30, 0x1c, 0x1a, 0x1a, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x79, + 0x6d, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x70, + 0x61, 0x30, 0x2a, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x23, 0x30, 0x21, + 0xa4, 0x1f, 0x30, 0x1d, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x12, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x4d, + 0x50, 0x4b, 0x49, 0x2d, 0x32, 0x2d, 0x33, 0x37, 0x33, 0x30, 0x1d, 0x06, + 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xdb, 0x62, 0x20, 0xfb, + 0x7d, 0x02, 0x89, 0x7c, 0xd2, 0x3b, 0x6f, 0xc7, 0xe4, 0x32, 0x6c, 0x05, + 0x52, 0x1d, 0xad, 0xb1, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, + 0x18, 0x30, 0x16, 0x80, 0x14, 0xb6, 0x77, 0xfa, 0x69, 0x48, 0x47, 0x9f, + 0x53, 0x12, 0xd5, 0xc2, 0xea, 0x07, 0x32, 0x76, 0x07, 0xd1, 0x97, 0x07, + 0x19, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x19, 0xcc, 0x95, + 0xe2, 0x2f, 0x7b, 0x49, 0xd0, 0x48, 0x90, 0x53, 0xf4, 0x07, 0xb1, 0x20, + 0x44, 0x35, 0x70, 0x14, 0xd5, 0x44, 0x37, 0x31, 0xef, 0xef, 0x70, 0xd1, + 0x2d, 0x4c, 0xe9, 0x2d, 0xb0, 0x53, 0x91, 0x01, 0x4c, 0x54, 0xe7, 0x7d, + 0x9b, 0xda, 0x3a, 0xff, 0xb7, 0xcb, 0x14, 0xad, 0x30, 0x0f, 0x69, 0x1a, + 0x2a, 0xf0, 0xbc, 0xcd, 0x35, 0xeb, 0x48, 0xdc, 0xb9, 0x87, 0xfd, 0xcf, + 0xb1, 0x5a, 0xf6, 0x05, 0xda, 0x3c, 0x64, 0xe6, 0x2b, 0xe6, 0xdc, 0x73, + 0x5e, 0x9a, 0xd8, 0x0c, 0x9b, 0xd2, 0x97, 0xb3, 0xe8, 0xfa, 0x87, 0x95, + 0x53, 0xe1, 0x99, 0xad, 0x88, 0xe8, 0xfa, 0xbc, 0x09, 0x4d, 0xa2, 0xc4, + 0x6a, 0x1b, 0x28, 0x3b, 0x2d, 0xc3, 0x21, 0x15, 0xee, 0x14, 0xfa, 0x9d, + 0x98, 0x10, 0xeb, 0x9f, 0x3e, 0xe6, 0x24, 0x24, 0x5f, 0x7a, 0x1c, 0x05, + 0xbb, 0x9a, 0x31, 0x23, 0x58, 0x79, 0x4c, 0xec, 0x6d, 0x18, 0x19, 0x4d, + 0x51, 0x1f, 0x08, 0x61, 0xbd, 0x91, 0x05, 0x0c, 0x5a, 0x9c, 0x26, 0xfc, + 0x0b, 0xa5, 0x20, 0x25, 0xbf, 0x6a, 0x1b, 0x2b, 0xf7, 0x02, 0x09, 0x72, + 0x69, 0x83, 0x32, 0x14, 0xc3, 0x60, 0x5b, 0x7e, 0xfd, 0x9a, 0x32, 0xfa, + 0xb4, 0x95, 0x0e, 0x1a, 0xf9, 0x3b, 0x09, 0xa4, 0x54, 0x47, 0x9a, 0x0c, + 0xce, 0x32, 0xaf, 0xd1, 0x21, 0xcc, 0x7f, 0xd2, 0x06, 0xef, 0x60, 0x0e, + 0x62, 0x6f, 0x6f, 0x81, 0x1a, 0x17, 0x9d, 0xc8, 0xcb, 0x28, 0xcc, 0xe2, + 0x5f, 0x6e, 0x2c, 0x7a, 0xb4, 0xcb, 0x47, 0x7c, 0x74, 0x68, 0x7b, 0x48, + 0x71, 0x02, 0x9c, 0x23, 0x09, 0xf3, 0x5a, 0xae, 0x5f, 0x42, 0x2e, 0x5f, + 0x2b, 0x59, 0x2d, 0x52, 0x88, 0xe5, 0x8d, 0x0b, 0xb3, 0xa8, 0x61, 0xf9, + 0x4b, 0x9b, 0x55, 0xd6, 0xda, 0xb1, 0x92, 0x3b, 0xbf, 0xc3, 0x9b, 0xf9, + 0x2c, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 120036009 (0x7279aa9) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root + Validity + Not Before: Dec 19 20:07:32 2013 GMT + Not After : Dec 19 20:06:55 2017 GMT + Subject: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, OU=Microsoft IT, CN=Microsoft IT SSL SHA2 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + 00:d1:e8:37:a7:76:8a:70:4b:19:f0:20:37:09:24: + 37:7f:ea:fb:78:e6:05:ba:6a:ad:4e:27:0d:fc:72: + 6a:d9:6c:21:c4:64:11:95:73:10:0a:5c:25:7b:88: + 6c:94:04:fd:c7:db:ae:7b:dc:4a:08:b3:3e:16:f1: + d0:ad:db:30:6d:d7:1a:1e:52:b5:3d:f0:47:19:03: + e2:7d:a6:bd:57:13:3f:54:ea:3a:a3:b1:77:fc:42: + f0:63:49:6a:91:80:2e:30:49:c0:8a:eb:2b:af:fe: + 3a:eb:07:5d:06:f7:e9:fd:84:0e:91:bd:09:20:29: + e8:6e:5d:09:ce:15:d3:e7:ef:db:50:eb:44:ef:18: + 57:ab:04:1d:bc:31:f9:f7:7b:2a:13:cf:d1:3d:51: + af:1b:c5:b5:7b:e7:b0:fc:53:bb:9a:e7:63:de:41: + 33:b6:47:24:69:5d:b8:46:a7:ff:ad:ab:df:4f:7a: + 78:25:27:21:26:34:ca:02:6e:37:51:f0:ed:58:1a: + 60:94:f6:c4:93:d8:dd:30:24:25:d7:1c:eb:19:94: + 35:5d:93:b2:ae:aa:29:83:73:c4:74:59:05:52:67: + 9d:da:67:51:39:05:3a:36:ea:f2:1e:76:2b:14:ae: + ec:3d:f9:14:99:8b:07:6e:bc:e7:0c:56:de:ac:be: + ae:db:75:32:90:9e:63:bd:74:bf:e0:0a:ca:f8:34: + 96:67:84:cd:d1:42:38:78:c7:99:b6:0c:ce:b6:0f: + e9:1b:cb:f4:59:be:11:0e:cb:2c:32:c8:fa:83:29: + 64:79:3c:8b:4b:f0:32:74:6c:f3:93:b8:96:6b:5d: + 57:5a:68:c1:cc:0c:79:8a:19:de:f5:49:02:5e:08: + 80:01:89:0c:32:cd:d2:d6:96:d5:4b:a0:f3:ec:bf: + ab:f4:7d:b3:a1:b9:7c:da:4e:d7:e5:b7:ac:b9:f2: + 25:5f:01:cb:8c:96:a8:28:ae:c1:33:5a:f6:3f:08: + 90:dc:eb:ff:39:d8:26:c8:12:9d:1c:9a:aa:a9:c0: + 16:8e:86:ed:67:52:96:00:7f:0d:92:3d:3d:d9:70: + 36:e5:ea:42:6f:1f:ae:95:e5:5b:5d:f8:d0:3a:c7: + d4:de:77:86:d0:fc:9e:4e:e2:e2:b8:a9:68:37:09: + c4:39:e3:85:b8:89:f3:1f:6e:b7:6d:1f:4a:2f:18: + 09:6f:de:4a:01:8f:14:c9:b7:a6:ee:a7:63:9f:33: + a4:54:7c:42:83:68:b8:a5:df:bf:ec:b9:1a:5d:13: + 3b:d9:ad:68:fd:20:0a:55:91:21:64:f9:d7:13:01: + a0:08:5d:59:89:1b:44:af:a4:ac:c7:05:10:fa:41: + 4a:a8:fb + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Certificate Policies: + Policy: 1.3.6.1.4.1.6334.1.0 + CPS: http://cybertrust.omniroot.com/repository.cfm + + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + X509v3 Extended Key Usage: + TLS Web Server Authentication, TLS Web Client Authentication + X509v3 Authority Key Identifier: + keyid:E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0 + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://cdp1.public-trust.com/CRL/Omniroot2025.crl + + X509v3 Subject Key Identifier: + 51:AF:24:26:9C:F4:68:22:57:80:26:2B:3B:46:62:15:7B:1E:CC:A5 + Signature Algorithm: sha256WithRSAEncryption + 76:85:c5:23:31:1f:b4:73:ea:a0:bc:a5:ed:df:45:43:6a:7f: + 69:20:1b:80:b2:fb:1c:dd:aa:7f:88:d3:31:41:36:f7:fb:fb: + 6b:ad:98:8c:78:1f:9d:11:67:3a:cd:4b:ec:a8:bc:9d:15:19: + c4:3b:0b:a7:93:ce:e8:fc:9d:5b:e8:1f:cb:56:ae:76:43:2b: + c7:13:51:77:41:a8:66:4c:5f:a7:d1:d7:aa:75:c5:1b:29:4c: + c9:f4:6d:a1:5e:a1:85:93:16:c2:cb:3b:ab:14:7d:44:fd:da: + 25:29:86:2a:fe:63:20:ca:d2:0b:c2:34:15:bb:af:5b:7f:8a: + e0:aa:ed:45:a6:ea:79:db:d8:35:66:54:43:de:37:33:d1:e4: + e0:cd:57:ca:71:b0:7d:e9:16:77:64:e8:59:97:b9:d5:2e:d1: + b4:91:da:77:71:f3:4a:0f:48:d2:34:99:60:95:37:ac:1f:01: + cd:10:9d:e8:2a:a5:20:c7:50:9b:b3:6c:49:78:2b:58:92:64: + 89:b8:95:36:a8:34:aa:f0:41:d2:95:5a:24:54:97:4d:6e:05: + c4:95:ad:c4:7a:a3:39:fb:79:06:8a:9b:a6:4f:d9:22:fa:44: + 4e:36:f3:c9:0f:a6:39:e7:80:b2:5e:bf:bd:39:d1:46:e5:55: + 47:db:bc:6e +-----BEGIN CERTIFICATE----- +MIIFhjCCBG6gAwIBAgIEByeaqTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTEzMTIxOTIwMDczMloX +DTE3MTIxOTIwMDY1NVowgYsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n +dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y +YXRpb24xFTATBgNVBAsTDE1pY3Jvc29mdCBJVDEeMBwGA1UEAxMVTWljcm9zb2Z0 +IElUIFNTTCBTSEEyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0eg3 +p3aKcEsZ8CA3CSQ3f+r7eOYFumqtTicN/HJq2WwhxGQRlXMQClwle4hslAT9x9uu +e9xKCLM+FvHQrdswbdcaHlK1PfBHGQPifaa9VxM/VOo6o7F3/ELwY0lqkYAuMEnA +iusrr/466wddBvfp/YQOkb0JICnobl0JzhXT5+/bUOtE7xhXqwQdvDH593sqE8/R +PVGvG8W1e+ew/FO7mudj3kEztkckaV24Rqf/ravfT3p4JSchJjTKAm43UfDtWBpg +lPbEk9jdMCQl1xzrGZQ1XZOyrqopg3PEdFkFUmed2mdROQU6NuryHnYrFK7sPfkU +mYsHbrznDFberL6u23UykJ5jvXS/4ArK+DSWZ4TN0UI4eMeZtgzOtg/pG8v0Wb4R +DsssMsj6gylkeTyLS/AydGzzk7iWa11XWmjBzAx5ihne9UkCXgiAAYkMMs3S1pbV +S6Dz7L+r9H2zobl82k7X5besufIlXwHLjJaoKK7BM1r2PwiQ3Ov/OdgmyBKdHJqq +qcAWjobtZ1KWAH8Nkj092XA25epCbx+uleVbXfjQOsfU3neG0PyeTuLiuKloNwnE +OeOFuInzH263bR9KLxgJb95KAY8Uybem7qdjnzOkVHxCg2i4pd+/7LkaXRM72a1o +/SAKVZEhZPnXEwGgCF1ZiRtEr6SsxwUQ+kFKqPsCAwEAAaOCASAwggEcMBIGA1Ud +EwEB/wQIMAYBAf8CAQAwUwYDVR0gBEwwSjBIBgkrBgEEAbE+AQAwOzA5BggrBgEF +BQcCARYtaHR0cDovL2N5YmVydHJ1c3Qub21uaXJvb3QuY29tL3JlcG9zaXRvcnku +Y2ZtMA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUH +AwIwHwYDVR0jBBgwFoAU5Z1ZMIJHWMys+ghUNoZ7OrUETfAwQgYDVR0fBDswOTA3 +oDWgM4YxaHR0cDovL2NkcDEucHVibGljLXRydXN0LmNvbS9DUkwvT21uaXJvb3Qy +MDI1LmNybDAdBgNVHQ4EFgQUUa8kJpz0aCJXgCYrO0ZiFXsezKUwDQYJKoZIhvcN +AQELBQADggEBAHaFxSMxH7Rz6qC8pe3fRUNqf2kgG4Cy+xzdqn+I0zFBNvf7+2ut +mIx4H50RZzrNS+yovJ0VGcQ7C6eTzuj8nVvoH8tWrnZDK8cTUXdBqGZMX6fR16p1 +xRspTMn0baFeoYWTFsLLO6sUfUT92iUphir+YyDK0gvCNBW7r1t/iuCq7UWm6nnb +2DVmVEPeNzPR5ODNV8pxsH3pFndk6FmXudUu0bSR2ndx80oPSNI0mWCVN6wfAc0Q +negqpSDHUJuzbEl4K1iSZIm4lTaoNKrwQdKVWiRUl01uBcSVrcR6ozn7eQaKm6ZP +2SL6RE4288kPpjnngLJev7050UblVUfbvG4= +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert47[] = { + 0x30, 0x82, 0x05, 0x86, 0x30, 0x82, 0x04, 0x6e, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x04, 0x07, 0x27, 0x9a, 0xa9, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x5a, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49, + 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, + 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65, + 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, + 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, + 0x31, 0x32, 0x31, 0x39, 0x32, 0x30, 0x30, 0x37, 0x33, 0x32, 0x5a, 0x17, + 0x0d, 0x31, 0x37, 0x31, 0x32, 0x31, 0x39, 0x32, 0x30, 0x30, 0x36, 0x35, + 0x35, 0x5a, 0x30, 0x81, 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, + 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x13, 0x07, 0x52, 0x65, 0x64, 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30, + 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, + 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x13, 0x0c, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, + 0x74, 0x20, 0x49, 0x54, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, + 0x20, 0x49, 0x54, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x53, 0x48, 0x41, 0x32, + 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, + 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xd1, 0xe8, 0x37, + 0xa7, 0x76, 0x8a, 0x70, 0x4b, 0x19, 0xf0, 0x20, 0x37, 0x09, 0x24, 0x37, + 0x7f, 0xea, 0xfb, 0x78, 0xe6, 0x05, 0xba, 0x6a, 0xad, 0x4e, 0x27, 0x0d, + 0xfc, 0x72, 0x6a, 0xd9, 0x6c, 0x21, 0xc4, 0x64, 0x11, 0x95, 0x73, 0x10, + 0x0a, 0x5c, 0x25, 0x7b, 0x88, 0x6c, 0x94, 0x04, 0xfd, 0xc7, 0xdb, 0xae, + 0x7b, 0xdc, 0x4a, 0x08, 0xb3, 0x3e, 0x16, 0xf1, 0xd0, 0xad, 0xdb, 0x30, + 0x6d, 0xd7, 0x1a, 0x1e, 0x52, 0xb5, 0x3d, 0xf0, 0x47, 0x19, 0x03, 0xe2, + 0x7d, 0xa6, 0xbd, 0x57, 0x13, 0x3f, 0x54, 0xea, 0x3a, 0xa3, 0xb1, 0x77, + 0xfc, 0x42, 0xf0, 0x63, 0x49, 0x6a, 0x91, 0x80, 0x2e, 0x30, 0x49, 0xc0, + 0x8a, 0xeb, 0x2b, 0xaf, 0xfe, 0x3a, 0xeb, 0x07, 0x5d, 0x06, 0xf7, 0xe9, + 0xfd, 0x84, 0x0e, 0x91, 0xbd, 0x09, 0x20, 0x29, 0xe8, 0x6e, 0x5d, 0x09, + 0xce, 0x15, 0xd3, 0xe7, 0xef, 0xdb, 0x50, 0xeb, 0x44, 0xef, 0x18, 0x57, + 0xab, 0x04, 0x1d, 0xbc, 0x31, 0xf9, 0xf7, 0x7b, 0x2a, 0x13, 0xcf, 0xd1, + 0x3d, 0x51, 0xaf, 0x1b, 0xc5, 0xb5, 0x7b, 0xe7, 0xb0, 0xfc, 0x53, 0xbb, + 0x9a, 0xe7, 0x63, 0xde, 0x41, 0x33, 0xb6, 0x47, 0x24, 0x69, 0x5d, 0xb8, + 0x46, 0xa7, 0xff, 0xad, 0xab, 0xdf, 0x4f, 0x7a, 0x78, 0x25, 0x27, 0x21, + 0x26, 0x34, 0xca, 0x02, 0x6e, 0x37, 0x51, 0xf0, 0xed, 0x58, 0x1a, 0x60, + 0x94, 0xf6, 0xc4, 0x93, 0xd8, 0xdd, 0x30, 0x24, 0x25, 0xd7, 0x1c, 0xeb, + 0x19, 0x94, 0x35, 0x5d, 0x93, 0xb2, 0xae, 0xaa, 0x29, 0x83, 0x73, 0xc4, + 0x74, 0x59, 0x05, 0x52, 0x67, 0x9d, 0xda, 0x67, 0x51, 0x39, 0x05, 0x3a, + 0x36, 0xea, 0xf2, 0x1e, 0x76, 0x2b, 0x14, 0xae, 0xec, 0x3d, 0xf9, 0x14, + 0x99, 0x8b, 0x07, 0x6e, 0xbc, 0xe7, 0x0c, 0x56, 0xde, 0xac, 0xbe, 0xae, + 0xdb, 0x75, 0x32, 0x90, 0x9e, 0x63, 0xbd, 0x74, 0xbf, 0xe0, 0x0a, 0xca, + 0xf8, 0x34, 0x96, 0x67, 0x84, 0xcd, 0xd1, 0x42, 0x38, 0x78, 0xc7, 0x99, + 0xb6, 0x0c, 0xce, 0xb6, 0x0f, 0xe9, 0x1b, 0xcb, 0xf4, 0x59, 0xbe, 0x11, + 0x0e, 0xcb, 0x2c, 0x32, 0xc8, 0xfa, 0x83, 0x29, 0x64, 0x79, 0x3c, 0x8b, + 0x4b, 0xf0, 0x32, 0x74, 0x6c, 0xf3, 0x93, 0xb8, 0x96, 0x6b, 0x5d, 0x57, + 0x5a, 0x68, 0xc1, 0xcc, 0x0c, 0x79, 0x8a, 0x19, 0xde, 0xf5, 0x49, 0x02, + 0x5e, 0x08, 0x80, 0x01, 0x89, 0x0c, 0x32, 0xcd, 0xd2, 0xd6, 0x96, 0xd5, + 0x4b, 0xa0, 0xf3, 0xec, 0xbf, 0xab, 0xf4, 0x7d, 0xb3, 0xa1, 0xb9, 0x7c, + 0xda, 0x4e, 0xd7, 0xe5, 0xb7, 0xac, 0xb9, 0xf2, 0x25, 0x5f, 0x01, 0xcb, + 0x8c, 0x96, 0xa8, 0x28, 0xae, 0xc1, 0x33, 0x5a, 0xf6, 0x3f, 0x08, 0x90, + 0xdc, 0xeb, 0xff, 0x39, 0xd8, 0x26, 0xc8, 0x12, 0x9d, 0x1c, 0x9a, 0xaa, + 0xa9, 0xc0, 0x16, 0x8e, 0x86, 0xed, 0x67, 0x52, 0x96, 0x00, 0x7f, 0x0d, + 0x92, 0x3d, 0x3d, 0xd9, 0x70, 0x36, 0xe5, 0xea, 0x42, 0x6f, 0x1f, 0xae, + 0x95, 0xe5, 0x5b, 0x5d, 0xf8, 0xd0, 0x3a, 0xc7, 0xd4, 0xde, 0x77, 0x86, + 0xd0, 0xfc, 0x9e, 0x4e, 0xe2, 0xe2, 0xb8, 0xa9, 0x68, 0x37, 0x09, 0xc4, + 0x39, 0xe3, 0x85, 0xb8, 0x89, 0xf3, 0x1f, 0x6e, 0xb7, 0x6d, 0x1f, 0x4a, + 0x2f, 0x18, 0x09, 0x6f, 0xde, 0x4a, 0x01, 0x8f, 0x14, 0xc9, 0xb7, 0xa6, + 0xee, 0xa7, 0x63, 0x9f, 0x33, 0xa4, 0x54, 0x7c, 0x42, 0x83, 0x68, 0xb8, + 0xa5, 0xdf, 0xbf, 0xec, 0xb9, 0x1a, 0x5d, 0x13, 0x3b, 0xd9, 0xad, 0x68, + 0xfd, 0x20, 0x0a, 0x55, 0x91, 0x21, 0x64, 0xf9, 0xd7, 0x13, 0x01, 0xa0, + 0x08, 0x5d, 0x59, 0x89, 0x1b, 0x44, 0xaf, 0xa4, 0xac, 0xc7, 0x05, 0x10, + 0xfa, 0x41, 0x4a, 0xa8, 0xfb, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, + 0x01, 0x20, 0x30, 0x82, 0x01, 0x1c, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, + 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, + 0x01, 0x00, 0x30, 0x53, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x4c, 0x30, + 0x4a, 0x30, 0x48, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb1, 0x3e, + 0x01, 0x00, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x02, 0x01, 0x16, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x63, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, + 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e, + 0x63, 0x66, 0x6d, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, + 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 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, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, + 0x16, 0x80, 0x14, 0xe5, 0x9d, 0x59, 0x30, 0x82, 0x47, 0x58, 0xcc, 0xac, + 0xfa, 0x08, 0x54, 0x36, 0x86, 0x7b, 0x3a, 0xb5, 0x04, 0x4d, 0xf0, 0x30, + 0x42, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x3b, 0x30, 0x39, 0x30, 0x37, + 0xa0, 0x35, 0xa0, 0x33, 0x86, 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x63, 0x64, 0x70, 0x31, 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x2d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, + 0x52, 0x4c, 0x2f, 0x4f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x32, + 0x30, 0x32, 0x35, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, + 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x51, 0xaf, 0x24, 0x26, 0x9c, 0xf4, + 0x68, 0x22, 0x57, 0x80, 0x26, 0x2b, 0x3b, 0x46, 0x62, 0x15, 0x7b, 0x1e, + 0xcc, 0xa5, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x76, 0x85, + 0xc5, 0x23, 0x31, 0x1f, 0xb4, 0x73, 0xea, 0xa0, 0xbc, 0xa5, 0xed, 0xdf, + 0x45, 0x43, 0x6a, 0x7f, 0x69, 0x20, 0x1b, 0x80, 0xb2, 0xfb, 0x1c, 0xdd, + 0xaa, 0x7f, 0x88, 0xd3, 0x31, 0x41, 0x36, 0xf7, 0xfb, 0xfb, 0x6b, 0xad, + 0x98, 0x8c, 0x78, 0x1f, 0x9d, 0x11, 0x67, 0x3a, 0xcd, 0x4b, 0xec, 0xa8, + 0xbc, 0x9d, 0x15, 0x19, 0xc4, 0x3b, 0x0b, 0xa7, 0x93, 0xce, 0xe8, 0xfc, + 0x9d, 0x5b, 0xe8, 0x1f, 0xcb, 0x56, 0xae, 0x76, 0x43, 0x2b, 0xc7, 0x13, + 0x51, 0x77, 0x41, 0xa8, 0x66, 0x4c, 0x5f, 0xa7, 0xd1, 0xd7, 0xaa, 0x75, + 0xc5, 0x1b, 0x29, 0x4c, 0xc9, 0xf4, 0x6d, 0xa1, 0x5e, 0xa1, 0x85, 0x93, + 0x16, 0xc2, 0xcb, 0x3b, 0xab, 0x14, 0x7d, 0x44, 0xfd, 0xda, 0x25, 0x29, + 0x86, 0x2a, 0xfe, 0x63, 0x20, 0xca, 0xd2, 0x0b, 0xc2, 0x34, 0x15, 0xbb, + 0xaf, 0x5b, 0x7f, 0x8a, 0xe0, 0xaa, 0xed, 0x45, 0xa6, 0xea, 0x79, 0xdb, + 0xd8, 0x35, 0x66, 0x54, 0x43, 0xde, 0x37, 0x33, 0xd1, 0xe4, 0xe0, 0xcd, + 0x57, 0xca, 0x71, 0xb0, 0x7d, 0xe9, 0x16, 0x77, 0x64, 0xe8, 0x59, 0x97, + 0xb9, 0xd5, 0x2e, 0xd1, 0xb4, 0x91, 0xda, 0x77, 0x71, 0xf3, 0x4a, 0x0f, + 0x48, 0xd2, 0x34, 0x99, 0x60, 0x95, 0x37, 0xac, 0x1f, 0x01, 0xcd, 0x10, + 0x9d, 0xe8, 0x2a, 0xa5, 0x20, 0xc7, 0x50, 0x9b, 0xb3, 0x6c, 0x49, 0x78, + 0x2b, 0x58, 0x92, 0x64, 0x89, 0xb8, 0x95, 0x36, 0xa8, 0x34, 0xaa, 0xf0, + 0x41, 0xd2, 0x95, 0x5a, 0x24, 0x54, 0x97, 0x4d, 0x6e, 0x05, 0xc4, 0x95, + 0xad, 0xc4, 0x7a, 0xa3, 0x39, 0xfb, 0x79, 0x06, 0x8a, 0x9b, 0xa6, 0x4f, + 0xd9, 0x22, 0xfa, 0x44, 0x4e, 0x36, 0xf3, 0xc9, 0x0f, 0xa6, 0x39, 0xe7, + 0x80, 0xb2, 0x5e, 0xbf, 0xbd, 0x39, 0xd1, 0x46, 0xe5, 0x55, 0x47, 0xdb, + 0xbc, 0x6e, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 75:96:c2:3e:fa:89:59:45:6e:79:f7:17:ba:cf:64:f3 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=CN, O=WoSign CA Limited, CN=Certification Authority of WoSign + Validity + Not Before: Nov 8 00:58:58 2014 GMT + Not After : Nov 8 00:58:58 2029 GMT + Subject: C=CN, O=WoSign CA Limited, CN=WoSign Class 3 OV Server CA G2 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:d6:74:87:af:99:c0:57:96:99:c2:89:74:3c:92: + 55:99:bf:1f:07:00:35:05:26:96:16:5b:03:c1:42: + 37:33:be:3f:0d:4f:ff:bb:94:26:91:d7:14:16:78: + 1b:f7:13:a2:4b:4c:e5:5c:a7:10:40:35:59:30:d1: + 77:99:e3:9d:29:c2:be:31:95:bd:92:61:5b:b0:23: + fb:67:58:d5:52:e4:7b:2f:f0:73:1c:73:94:55:ba: + c8:68:59:02:10:10:e4:f7:11:f0:c3:b6:d7:ae:56: + 80:00:9e:65:64:a6:83:91:41:e6:ed:a7:7a:65:a5: + 1f:30:2e:13:3c:bf:df:63:97:f3:96:f0:52:32:b4: + f4:7b:98:57:ed:36:4f:f7:21:4a:28:9d:dd:1c:92: + b3:4d:8d:9c:58:8b:17:21:d8:dc:a1:b7:ae:73:78: + 8a:c4:b6:e9:7f:28:8e:9a:d5:2e:9e:39:e9:da:59: + 74:e3:c8:97:10:32:94:19:59:d4:0f:89:57:44:e6: + e5:2b:17:30:62:52:98:7f:ab:0d:a5:01:ea:04:41: + ca:fa:13:0e:3b:87:06:ba:bd:47:31:d7:63:03:01: + f4:be:a1:37:11:9f:1e:01:95:4e:0f:3f:54:1e:92: + a6:9f:30:8c:fe:98:e8:56:96:66:04:e1:35:fe:59: + ac:57 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Extended Key Usage: + TLS Web Client Authentication, TLS Web Server Authentication + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crls1.wosign.com/ca1.crl + + Authority Information Access: + OCSP - URI:http://ocsp1.wosign.com/ca1 + CA Issuers - URI:http://aia1.wosign.com/ca1g2-server3.cer + + X509v3 Subject Key Identifier: + F9:8B:EC:04:38:6A:3F:AA:06:C6:94:AD:73:95:2A:B0:C8:E6:B8:FB + X509v3 Authority Key Identifier: + keyid:E1:66:CF:0E:D1:F1:B3:4B:B7:06:20:14:FE:87:12:D5:F6:FE:FB:3E + + X509v3 Certificate Policies: + Policy: 1.3.6.1.4.1.36305.6.3.2.1 + CPS: http://www.wosign.com/policy/ + + Signature Algorithm: sha256WithRSAEncryption + 5e:67:ba:78:32:05:b6:b7:af:e7:de:6a:7a:82:64:0e:a0:0b: + f2:9e:9a:ba:c6:2b:6f:56:3a:b4:62:57:ab:7c:ad:60:50:96: + 34:9c:a3:88:cf:d9:8f:50:af:f6:f0:00:36:1b:1f:1f:87:55: + 3c:60:9a:f0:b0:0d:9a:80:2d:8a:3b:be:05:b3:d7:a0:80:b6: + b8:19:eb:51:db:ec:64:54:f1:1a:89:4a:48:a1:4d:3f:31:7d: + c4:79:94:4b:f1:de:ab:83:af:5f:86:be:96:1c:b3:3e:1c:e7: + bc:96:b2:e8:5a:ac:b5:58:cb:3c:56:6f:0a:a7:a5:d0:36:89: + 82:26:8c:b9:1f:b6:eb:8f:7e:78:fc:5b:8b:79:1c:d6:df:47: + a7:56:f4:98:4e:c7:a9:d5:0e:75:56:06:7f:b4:37:46:08:c6: + e9:4f:8b:5b:43:1c:e0:45:3e:95:20:71:c0:1c:98:16:ef:f2: + 78:df:ac:4d:bb:bf:56:0e:cf:85:af:cf:bf:04:ed:72:6b:fd: + 1f:57:0e:58:91:44:11:58:3b:62:3b:09:78:b3:a4:75:6a:ec: + b3:c2:2b:32:cc:b3:8d:c3:a3:6e:dc:8a:d5:e8:4a:c4:0b:7b: + db:30:5d:95:33:c3:d1:a3:69:64:5b:a8:aa:96:48:73:73:e3: + c9:b9:24:df:17:75:aa:af:07:3a:cf:be:9b:8a:80:a7:bf:7c: + e2:e9:2a:e6:fd:b0:2c:e7:e6:e6:7e:b3:35:15:65:00:f4:e1: + 39:73:0e:28:4b:f0:0c:98:9e:3a:eb:ce:7b:7a:9e:40:c1:50: + 65:96:9a:e7:4b:77:cd:dd:cb:7d:97:b4:ea:09:b2:e9:49:28: + c3:30:e0:87:15:f0:26:ea:d8:03:fd:ec:da:08:83:65:dc:77: + c5:6e:3d:34:f7:87:c3:1c:1d:26:33:ec:33:ac:c6:99:53:ab: + 60:f4:b0:d9:ee:64:5a:33:07:70:13:74:88:07:f5:86:f9:18: + d3:b2:47:c8:ae:03:4a:53:de:1c:65:d6:0a:2e:3a:51:93:ee: + b7:e3:6f:0a:fb:e9:fe:4e:e8:bb:1d:c2:97:ab:0a:b9:ed:36: + 32:1b:4d:a1:cc:03:a6:9d:b3:d9:1c:d5:67:e2:8f:74:3c:92: + 2a:74:b1:56:50:df:53:15:d7:21:d6:eb:f3:fb:63:e3:20:2c: + 0a:74:37:0b:c1:a1:35:6a:84:70:f4:45:f8:b2:b6:81:49:aa: + fd:54:45:90:4d:e7:04:07:5f:78:14:dd:3a:bb:2b:f9:72:50: + ec:68:ea:3c:a8:d1:80:bb:be:35:43:97:c3:32:b2:f5:aa:ad: + c9:7f:83:9f:7d:69:1e:15 +-----BEGIN CERTIFICATE----- +MIIFozCCA4ugAwIBAgIQdZbCPvqJWUVuefcXus9k8zANBgkqhkiG9w0BAQsFADBV +MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNV +BAMTIUNlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0xNDExMDgw +MDU4NThaFw0yOTExMDgwMDU4NThaMFIxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFX +b1NpZ24gQ0EgTGltaXRlZDEnMCUGA1UEAxMeV29TaWduIENsYXNzIDMgT1YgU2Vy +dmVyIENBIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1nSHr5nA +V5aZwol0PJJVmb8fBwA1BSaWFlsDwUI3M74/DU//u5QmkdcUFngb9xOiS0zlXKcQ +QDVZMNF3meOdKcK+MZW9kmFbsCP7Z1jVUuR7L/BzHHOUVbrIaFkCEBDk9xHww7bX +rlaAAJ5lZKaDkUHm7ad6ZaUfMC4TPL/fY5fzlvBSMrT0e5hX7TZP9yFKKJ3dHJKz +TY2cWIsXIdjcobeuc3iKxLbpfyiOmtUunjnp2ll048iXEDKUGVnUD4lXROblKxcw +YlKYf6sNpQHqBEHK+hMOO4cGur1HMddjAwH0vqE3EZ8eAZVODz9UHpKmnzCM/pjo +VpZmBOE1/lmsVwIDAQABo4IBcDCCAWwwDgYDVR0PAQH/BAQDAgEGMB0GA1UdJQQW +MBQGCCsGAQUFBwMCBggrBgEFBQcDATASBgNVHRMBAf8ECDAGAQH/AgEAMDAGA1Ud +HwQpMCcwJaAjoCGGH2h0dHA6Ly9jcmxzMS53b3NpZ24uY29tL2NhMS5jcmwwbQYI +KwYBBQUHAQEEYTBfMCcGCCsGAQUFBzABhhtodHRwOi8vb2NzcDEud29zaWduLmNv +bS9jYTEwNAYIKwYBBQUHMAKGKGh0dHA6Ly9haWExLndvc2lnbi5jb20vY2ExZzIt +c2VydmVyMy5jZXIwHQYDVR0OBBYEFPmL7AQ4aj+qBsaUrXOVKrDI5rj7MB8GA1Ud +IwQYMBaAFOFmzw7R8bNLtwYgFP6HEtX2/vs+MEYGA1UdIAQ/MD0wOwYMKwYBBAGC +m1EGAwIBMCswKQYIKwYBBQUHAgEWHWh0dHA6Ly93d3cud29zaWduLmNvbS9wb2xp +Y3kvMA0GCSqGSIb3DQEBCwUAA4ICAQBeZ7p4MgW2t6/n3mp6gmQOoAvynpq6xitv +Vjq0YlerfK1gUJY0nKOIz9mPUK/28AA2Gx8fh1U8YJrwsA2agC2KO74Fs9eggLa4 +GetR2+xkVPEaiUpIoU0/MX3EeZRL8d6rg69fhr6WHLM+HOe8lrLoWqy1WMs8Vm8K +p6XQNomCJoy5H7brj354/FuLeRzW30enVvSYTsep1Q51VgZ/tDdGCMbpT4tbQxzg +RT6VIHHAHJgW7/J436xNu79WDs+Fr8+/BO1ya/0fVw5YkUQRWDtiOwl4s6R1auyz +wisyzLONw6Nu3IrV6ErEC3vbMF2VM8PRo2lkW6iqlkhzc+PJuSTfF3Wqrwc6z76b +ioCnv3zi6Srm/bAs5+bmfrM1FWUA9OE5cw4oS/AMmJ466857ep5AwVBllprnS3fN +3ct9l7TqCbLpSSjDMOCHFfAm6tgD/ezaCINl3HfFbj0094fDHB0mM+wzrMaZU6tg +9LDZ7mRaMwdwE3SIB/WG+RjTskfIrgNKU94cZdYKLjpRk+63428K++n+Tui7HcKX +qwq57TYyG02hzAOmnbPZHNVn4o90PJIqdLFWUN9TFdch1uvz+2PjICwKdDcLwaE1 +aoRw9EX4sraBSar9VEWQTecEB194FN06uyv5clDsaOo8qNGAu741Q5fDMrL1qq3J +f4OffWkeFQ== +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert48[] = { + 0x30, 0x82, 0x05, 0xa3, 0x30, 0x82, 0x03, 0x8b, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x75, 0x96, 0xc2, 0x3e, 0xfa, 0x89, 0x59, 0x45, 0x6e, + 0x79, 0xf7, 0x17, 0xba, 0xcf, 0x64, 0xf3, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x55, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, + 0x4e, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, + 0x57, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, + 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, 0x2a, 0x30, 0x28, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x21, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x57, 0x6f, 0x53, 0x69, 0x67, + 0x6e, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, 0x31, 0x31, 0x30, 0x38, 0x30, + 0x30, 0x35, 0x38, 0x35, 0x38, 0x5a, 0x17, 0x0d, 0x32, 0x39, 0x31, 0x31, + 0x30, 0x38, 0x30, 0x30, 0x35, 0x38, 0x35, 0x38, 0x5a, 0x30, 0x52, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x4e, + 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x57, + 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d, + 0x69, 0x74, 0x65, 0x64, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x1e, 0x57, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6c, + 0x61, 0x73, 0x73, 0x20, 0x33, 0x20, 0x4f, 0x56, 0x20, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20, 0x47, 0x32, 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, 0xd6, 0x74, 0x87, 0xaf, 0x99, 0xc0, + 0x57, 0x96, 0x99, 0xc2, 0x89, 0x74, 0x3c, 0x92, 0x55, 0x99, 0xbf, 0x1f, + 0x07, 0x00, 0x35, 0x05, 0x26, 0x96, 0x16, 0x5b, 0x03, 0xc1, 0x42, 0x37, + 0x33, 0xbe, 0x3f, 0x0d, 0x4f, 0xff, 0xbb, 0x94, 0x26, 0x91, 0xd7, 0x14, + 0x16, 0x78, 0x1b, 0xf7, 0x13, 0xa2, 0x4b, 0x4c, 0xe5, 0x5c, 0xa7, 0x10, + 0x40, 0x35, 0x59, 0x30, 0xd1, 0x77, 0x99, 0xe3, 0x9d, 0x29, 0xc2, 0xbe, + 0x31, 0x95, 0xbd, 0x92, 0x61, 0x5b, 0xb0, 0x23, 0xfb, 0x67, 0x58, 0xd5, + 0x52, 0xe4, 0x7b, 0x2f, 0xf0, 0x73, 0x1c, 0x73, 0x94, 0x55, 0xba, 0xc8, + 0x68, 0x59, 0x02, 0x10, 0x10, 0xe4, 0xf7, 0x11, 0xf0, 0xc3, 0xb6, 0xd7, + 0xae, 0x56, 0x80, 0x00, 0x9e, 0x65, 0x64, 0xa6, 0x83, 0x91, 0x41, 0xe6, + 0xed, 0xa7, 0x7a, 0x65, 0xa5, 0x1f, 0x30, 0x2e, 0x13, 0x3c, 0xbf, 0xdf, + 0x63, 0x97, 0xf3, 0x96, 0xf0, 0x52, 0x32, 0xb4, 0xf4, 0x7b, 0x98, 0x57, + 0xed, 0x36, 0x4f, 0xf7, 0x21, 0x4a, 0x28, 0x9d, 0xdd, 0x1c, 0x92, 0xb3, + 0x4d, 0x8d, 0x9c, 0x58, 0x8b, 0x17, 0x21, 0xd8, 0xdc, 0xa1, 0xb7, 0xae, + 0x73, 0x78, 0x8a, 0xc4, 0xb6, 0xe9, 0x7f, 0x28, 0x8e, 0x9a, 0xd5, 0x2e, + 0x9e, 0x39, 0xe9, 0xda, 0x59, 0x74, 0xe3, 0xc8, 0x97, 0x10, 0x32, 0x94, + 0x19, 0x59, 0xd4, 0x0f, 0x89, 0x57, 0x44, 0xe6, 0xe5, 0x2b, 0x17, 0x30, + 0x62, 0x52, 0x98, 0x7f, 0xab, 0x0d, 0xa5, 0x01, 0xea, 0x04, 0x41, 0xca, + 0xfa, 0x13, 0x0e, 0x3b, 0x87, 0x06, 0xba, 0xbd, 0x47, 0x31, 0xd7, 0x63, + 0x03, 0x01, 0xf4, 0xbe, 0xa1, 0x37, 0x11, 0x9f, 0x1e, 0x01, 0x95, 0x4e, + 0x0f, 0x3f, 0x54, 0x1e, 0x92, 0xa6, 0x9f, 0x30, 0x8c, 0xfe, 0x98, 0xe8, + 0x56, 0x96, 0x66, 0x04, 0xe1, 0x35, 0xfe, 0x59, 0xac, 0x57, 0x02, 0x03, + 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x70, 0x30, 0x82, 0x01, 0x6c, 0x30, + 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, + 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, + 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, + 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x12, + 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, + 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x30, 0x06, 0x03, 0x55, 0x1d, + 0x1f, 0x04, 0x29, 0x30, 0x27, 0x30, 0x25, 0xa0, 0x23, 0xa0, 0x21, 0x86, + 0x1f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x73, + 0x31, 0x2e, 0x77, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x63, 0x61, 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x6d, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x61, 0x30, 0x5f, + 0x30, 0x27, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, + 0x86, 0x1b, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, + 0x70, 0x31, 0x2e, 0x77, 0x6f, 0x73, 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x63, 0x61, 0x31, 0x30, 0x34, 0x06, 0x08, 0x2b, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x28, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x61, 0x69, 0x61, 0x31, 0x2e, 0x77, 0x6f, 0x73, 0x69, 0x67, + 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x61, 0x31, 0x67, 0x32, 0x2d, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x33, 0x2e, 0x63, 0x65, 0x72, 0x30, + 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xf9, 0x8b, + 0xec, 0x04, 0x38, 0x6a, 0x3f, 0xaa, 0x06, 0xc6, 0x94, 0xad, 0x73, 0x95, + 0x2a, 0xb0, 0xc8, 0xe6, 0xb8, 0xfb, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, + 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe1, 0x66, 0xcf, 0x0e, 0xd1, + 0xf1, 0xb3, 0x4b, 0xb7, 0x06, 0x20, 0x14, 0xfe, 0x87, 0x12, 0xd5, 0xf6, + 0xfe, 0xfb, 0x3e, 0x30, 0x46, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3f, + 0x30, 0x3d, 0x30, 0x3b, 0x06, 0x0c, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, + 0x9b, 0x51, 0x06, 0x03, 0x02, 0x01, 0x30, 0x2b, 0x30, 0x29, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, 0x16, 0x1d, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x6f, 0x73, + 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x5e, + 0x67, 0xba, 0x78, 0x32, 0x05, 0xb6, 0xb7, 0xaf, 0xe7, 0xde, 0x6a, 0x7a, + 0x82, 0x64, 0x0e, 0xa0, 0x0b, 0xf2, 0x9e, 0x9a, 0xba, 0xc6, 0x2b, 0x6f, + 0x56, 0x3a, 0xb4, 0x62, 0x57, 0xab, 0x7c, 0xad, 0x60, 0x50, 0x96, 0x34, + 0x9c, 0xa3, 0x88, 0xcf, 0xd9, 0x8f, 0x50, 0xaf, 0xf6, 0xf0, 0x00, 0x36, + 0x1b, 0x1f, 0x1f, 0x87, 0x55, 0x3c, 0x60, 0x9a, 0xf0, 0xb0, 0x0d, 0x9a, + 0x80, 0x2d, 0x8a, 0x3b, 0xbe, 0x05, 0xb3, 0xd7, 0xa0, 0x80, 0xb6, 0xb8, + 0x19, 0xeb, 0x51, 0xdb, 0xec, 0x64, 0x54, 0xf1, 0x1a, 0x89, 0x4a, 0x48, + 0xa1, 0x4d, 0x3f, 0x31, 0x7d, 0xc4, 0x79, 0x94, 0x4b, 0xf1, 0xde, 0xab, + 0x83, 0xaf, 0x5f, 0x86, 0xbe, 0x96, 0x1c, 0xb3, 0x3e, 0x1c, 0xe7, 0xbc, + 0x96, 0xb2, 0xe8, 0x5a, 0xac, 0xb5, 0x58, 0xcb, 0x3c, 0x56, 0x6f, 0x0a, + 0xa7, 0xa5, 0xd0, 0x36, 0x89, 0x82, 0x26, 0x8c, 0xb9, 0x1f, 0xb6, 0xeb, + 0x8f, 0x7e, 0x78, 0xfc, 0x5b, 0x8b, 0x79, 0x1c, 0xd6, 0xdf, 0x47, 0xa7, + 0x56, 0xf4, 0x98, 0x4e, 0xc7, 0xa9, 0xd5, 0x0e, 0x75, 0x56, 0x06, 0x7f, + 0xb4, 0x37, 0x46, 0x08, 0xc6, 0xe9, 0x4f, 0x8b, 0x5b, 0x43, 0x1c, 0xe0, + 0x45, 0x3e, 0x95, 0x20, 0x71, 0xc0, 0x1c, 0x98, 0x16, 0xef, 0xf2, 0x78, + 0xdf, 0xac, 0x4d, 0xbb, 0xbf, 0x56, 0x0e, 0xcf, 0x85, 0xaf, 0xcf, 0xbf, + 0x04, 0xed, 0x72, 0x6b, 0xfd, 0x1f, 0x57, 0x0e, 0x58, 0x91, 0x44, 0x11, + 0x58, 0x3b, 0x62, 0x3b, 0x09, 0x78, 0xb3, 0xa4, 0x75, 0x6a, 0xec, 0xb3, + 0xc2, 0x2b, 0x32, 0xcc, 0xb3, 0x8d, 0xc3, 0xa3, 0x6e, 0xdc, 0x8a, 0xd5, + 0xe8, 0x4a, 0xc4, 0x0b, 0x7b, 0xdb, 0x30, 0x5d, 0x95, 0x33, 0xc3, 0xd1, + 0xa3, 0x69, 0x64, 0x5b, 0xa8, 0xaa, 0x96, 0x48, 0x73, 0x73, 0xe3, 0xc9, + 0xb9, 0x24, 0xdf, 0x17, 0x75, 0xaa, 0xaf, 0x07, 0x3a, 0xcf, 0xbe, 0x9b, + 0x8a, 0x80, 0xa7, 0xbf, 0x7c, 0xe2, 0xe9, 0x2a, 0xe6, 0xfd, 0xb0, 0x2c, + 0xe7, 0xe6, 0xe6, 0x7e, 0xb3, 0x35, 0x15, 0x65, 0x00, 0xf4, 0xe1, 0x39, + 0x73, 0x0e, 0x28, 0x4b, 0xf0, 0x0c, 0x98, 0x9e, 0x3a, 0xeb, 0xce, 0x7b, + 0x7a, 0x9e, 0x40, 0xc1, 0x50, 0x65, 0x96, 0x9a, 0xe7, 0x4b, 0x77, 0xcd, + 0xdd, 0xcb, 0x7d, 0x97, 0xb4, 0xea, 0x09, 0xb2, 0xe9, 0x49, 0x28, 0xc3, + 0x30, 0xe0, 0x87, 0x15, 0xf0, 0x26, 0xea, 0xd8, 0x03, 0xfd, 0xec, 0xda, + 0x08, 0x83, 0x65, 0xdc, 0x77, 0xc5, 0x6e, 0x3d, 0x34, 0xf7, 0x87, 0xc3, + 0x1c, 0x1d, 0x26, 0x33, 0xec, 0x33, 0xac, 0xc6, 0x99, 0x53, 0xab, 0x60, + 0xf4, 0xb0, 0xd9, 0xee, 0x64, 0x5a, 0x33, 0x07, 0x70, 0x13, 0x74, 0x88, + 0x07, 0xf5, 0x86, 0xf9, 0x18, 0xd3, 0xb2, 0x47, 0xc8, 0xae, 0x03, 0x4a, + 0x53, 0xde, 0x1c, 0x65, 0xd6, 0x0a, 0x2e, 0x3a, 0x51, 0x93, 0xee, 0xb7, + 0xe3, 0x6f, 0x0a, 0xfb, 0xe9, 0xfe, 0x4e, 0xe8, 0xbb, 0x1d, 0xc2, 0x97, + 0xab, 0x0a, 0xb9, 0xed, 0x36, 0x32, 0x1b, 0x4d, 0xa1, 0xcc, 0x03, 0xa6, + 0x9d, 0xb3, 0xd9, 0x1c, 0xd5, 0x67, 0xe2, 0x8f, 0x74, 0x3c, 0x92, 0x2a, + 0x74, 0xb1, 0x56, 0x50, 0xdf, 0x53, 0x15, 0xd7, 0x21, 0xd6, 0xeb, 0xf3, + 0xfb, 0x63, 0xe3, 0x20, 0x2c, 0x0a, 0x74, 0x37, 0x0b, 0xc1, 0xa1, 0x35, + 0x6a, 0x84, 0x70, 0xf4, 0x45, 0xf8, 0xb2, 0xb6, 0x81, 0x49, 0xaa, 0xfd, + 0x54, 0x45, 0x90, 0x4d, 0xe7, 0x04, 0x07, 0x5f, 0x78, 0x14, 0xdd, 0x3a, + 0xbb, 0x2b, 0xf9, 0x72, 0x50, 0xec, 0x68, 0xea, 0x3c, 0xa8, 0xd1, 0x80, + 0xbb, 0xbe, 0x35, 0x43, 0x97, 0xc3, 0x32, 0xb2, 0xf5, 0xaa, 0xad, 0xc9, + 0x7f, 0x83, 0x9f, 0x7d, 0x69, 0x1e, 0x15, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 120040007 (0x727aa47) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root + Validity + Not Before: May 7 17:04:09 2014 GMT + Not After : May 7 17:03:30 2018 GMT + Subject: C=US, ST=Washington, L=Redmond, O=Microsoft Corporation, OU=Microsoft IT, CN=Microsoft IT SSL SHA2 + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + 00:d1:e8:37:a7:76:8a:70:4b:19:f0:20:37:09:24: + 37:7f:ea:fb:78:e6:05:ba:6a:ad:4e:27:0d:fc:72: + 6a:d9:6c:21:c4:64:11:95:73:10:0a:5c:25:7b:88: + 6c:94:04:fd:c7:db:ae:7b:dc:4a:08:b3:3e:16:f1: + d0:ad:db:30:6d:d7:1a:1e:52:b5:3d:f0:47:19:03: + e2:7d:a6:bd:57:13:3f:54:ea:3a:a3:b1:77:fc:42: + f0:63:49:6a:91:80:2e:30:49:c0:8a:eb:2b:af:fe: + 3a:eb:07:5d:06:f7:e9:fd:84:0e:91:bd:09:20:29: + e8:6e:5d:09:ce:15:d3:e7:ef:db:50:eb:44:ef:18: + 57:ab:04:1d:bc:31:f9:f7:7b:2a:13:cf:d1:3d:51: + af:1b:c5:b5:7b:e7:b0:fc:53:bb:9a:e7:63:de:41: + 33:b6:47:24:69:5d:b8:46:a7:ff:ad:ab:df:4f:7a: + 78:25:27:21:26:34:ca:02:6e:37:51:f0:ed:58:1a: + 60:94:f6:c4:93:d8:dd:30:24:25:d7:1c:eb:19:94: + 35:5d:93:b2:ae:aa:29:83:73:c4:74:59:05:52:67: + 9d:da:67:51:39:05:3a:36:ea:f2:1e:76:2b:14:ae: + ec:3d:f9:14:99:8b:07:6e:bc:e7:0c:56:de:ac:be: + ae:db:75:32:90:9e:63:bd:74:bf:e0:0a:ca:f8:34: + 96:67:84:cd:d1:42:38:78:c7:99:b6:0c:ce:b6:0f: + e9:1b:cb:f4:59:be:11:0e:cb:2c:32:c8:fa:83:29: + 64:79:3c:8b:4b:f0:32:74:6c:f3:93:b8:96:6b:5d: + 57:5a:68:c1:cc:0c:79:8a:19:de:f5:49:02:5e:08: + 80:01:89:0c:32:cd:d2:d6:96:d5:4b:a0:f3:ec:bf: + ab:f4:7d:b3:a1:b9:7c:da:4e:d7:e5:b7:ac:b9:f2: + 25:5f:01:cb:8c:96:a8:28:ae:c1:33:5a:f6:3f:08: + 90:dc:eb:ff:39:d8:26:c8:12:9d:1c:9a:aa:a9:c0: + 16:8e:86:ed:67:52:96:00:7f:0d:92:3d:3d:d9:70: + 36:e5:ea:42:6f:1f:ae:95:e5:5b:5d:f8:d0:3a:c7: + d4:de:77:86:d0:fc:9e:4e:e2:e2:b8:a9:68:37:09: + c4:39:e3:85:b8:89:f3:1f:6e:b7:6d:1f:4a:2f:18: + 09:6f:de:4a:01:8f:14:c9:b7:a6:ee:a7:63:9f:33: + a4:54:7c:42:83:68:b8:a5:df:bf:ec:b9:1a:5d:13: + 3b:d9:ad:68:fd:20:0a:55:91:21:64:f9:d7:13:01: + a0:08:5d:59:89:1b:44:af:a4:ac:c7:05:10:fa:41: + 4a:a8:fb + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 Certificate Policies: + Policy: 1.3.6.1.4.1.6334.1.0 + CPS: http://cybertrust.omniroot.com/repository.cfm + Policy: 1.3.6.1.4.1.311.42.1 + + Authority Information Access: + OCSP - URI:http://ocsp.omniroot.com/baltimoreroot + + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + X509v3 Extended Key Usage: + TLS Web Server Authentication, TLS Web Client Authentication, OCSP Signing + X509v3 Authority Key Identifier: + keyid:E5:9D:59:30:82:47:58:CC:AC:FA:08:54:36:86:7B:3A:B5:04:4D:F0 + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://cdp1.public-trust.com/CRL/Omniroot2025.crl + + X509v3 Subject Key Identifier: + 51:AF:24:26:9C:F4:68:22:57:80:26:2B:3B:46:62:15:7B:1E:CC:A5 + Signature Algorithm: sha256WithRSAEncryption + 69:62:f6:84:91:00:c4:6f:82:7b:24:e1:42:a2:a5:8b:82:5c: + a7:c5:44:cb:e7:52:76:63:d3:76:9e:78:e2:69:35:b1:38:ba: + b0:96:c6:1f:ac:7b:c6:b2:65:77:8b:7d:8d:ae:64:b9:a5:8c: + 17:ca:58:65:c3:ad:82:f5:c5:a2:f5:01:13:93:c6:7e:44:e5: + c4:61:fa:03:b6:56:c1:72:e1:c8:28:c5:69:21:8f:ac:6e:fd: + 7f:43:83:36:b8:c0:d6:a0:28:fe:1a:45:be:fd:93:8c:8d:a4: + 64:79:1f:14:db:a1:9f:21:dc:c0:4e:7b:17:22:17:b1:b6:3c: + d3:9b:e2:0a:a3:7e:99:b0:c1:ac:d8:f4:86:df:3c:da:7d:14: + 9c:40:c1:7c:d2:18:6f:f1:4f:26:45:09:95:94:5c:da:d0:98: + f8:f4:4c:82:96:10:de:ac:30:cb:2b:ae:f9:92:ea:bf:79:03: + fc:1e:3f:ac:09:a4:3f:65:fd:91:4f:96:24:a7:ce:b4:4e:6a: + 96:29:17:ae:c0:a8:df:17:22:f4:17:e3:dc:1c:39:06:56:10: + ea:ea:b5:74:17:3c:4e:dd:7e:91:0a:a8:0b:78:07:a7:31:44: + 08:31:ab:18:84:0f:12:9c:e7:de:84:2c:e9:6d:93:45:bf:a8: + c1:3f:34:dc +-----BEGIN CERTIFICATE----- +MIIF4TCCBMmgAwIBAgIEByeqRzANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTE0MDUwNzE3MDQwOVoX +DTE4MDUwNzE3MDMzMFowgYsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n +dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y +YXRpb24xFTATBgNVBAsTDE1pY3Jvc29mdCBJVDEeMBwGA1UEAxMVTWljcm9zb2Z0 +IElUIFNTTCBTSEEyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0eg3 +p3aKcEsZ8CA3CSQ3f+r7eOYFumqtTicN/HJq2WwhxGQRlXMQClwle4hslAT9x9uu +e9xKCLM+FvHQrdswbdcaHlK1PfBHGQPifaa9VxM/VOo6o7F3/ELwY0lqkYAuMEnA +iusrr/466wddBvfp/YQOkb0JICnobl0JzhXT5+/bUOtE7xhXqwQdvDH593sqE8/R +PVGvG8W1e+ew/FO7mudj3kEztkckaV24Rqf/ravfT3p4JSchJjTKAm43UfDtWBpg +lPbEk9jdMCQl1xzrGZQ1XZOyrqopg3PEdFkFUmed2mdROQU6NuryHnYrFK7sPfkU +mYsHbrznDFberL6u23UykJ5jvXS/4ArK+DSWZ4TN0UI4eMeZtgzOtg/pG8v0Wb4R +DsssMsj6gylkeTyLS/AydGzzk7iWa11XWmjBzAx5ihne9UkCXgiAAYkMMs3S1pbV +S6Dz7L+r9H2zobl82k7X5besufIlXwHLjJaoKK7BM1r2PwiQ3Ov/OdgmyBKdHJqq +qcAWjobtZ1KWAH8Nkj092XA25epCbx+uleVbXfjQOsfU3neG0PyeTuLiuKloNwnE +OeOFuInzH263bR9KLxgJb95KAY8Uybem7qdjnzOkVHxCg2i4pd+/7LkaXRM72a1o +/SAKVZEhZPnXEwGgCF1ZiRtEr6SsxwUQ+kFKqPsCAwEAAaOCAXswggF3MBIGA1Ud +EwEB/wQIMAYBAf8CAQAwYAYDVR0gBFkwVzBIBgkrBgEEAbE+AQAwOzA5BggrBgEF +BQcCARYtaHR0cDovL2N5YmVydHJ1c3Qub21uaXJvb3QuY29tL3JlcG9zaXRvcnku +Y2ZtMAsGCSsGAQQBgjcqATBCBggrBgEFBQcBAQQ2MDQwMgYIKwYBBQUHMAGGJmh0 +dHA6Ly9vY3NwLm9tbmlyb290LmNvbS9iYWx0aW1vcmVyb290MA4GA1UdDwEB/wQE +AwIBhjAnBgNVHSUEIDAeBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMJMB8G +A1UdIwQYMBaAFOWdWTCCR1jMrPoIVDaGezq1BE3wMEIGA1UdHwQ7MDkwN6A1oDOG +MWh0dHA6Ly9jZHAxLnB1YmxpYy10cnVzdC5jb20vQ1JML09tbmlyb290MjAyNS5j +cmwwHQYDVR0OBBYEFFGvJCac9GgiV4AmKztGYhV7HsylMA0GCSqGSIb3DQEBCwUA +A4IBAQBpYvaEkQDEb4J7JOFCoqWLglynxUTL51J2Y9N2nnjiaTWxOLqwlsYfrHvG +smV3i32NrmS5pYwXylhlw62C9cWi9QETk8Z+ROXEYfoDtlbBcuHIKMVpIY+sbv1/ +Q4M2uMDWoCj+GkW+/ZOMjaRkeR8U26GfIdzATnsXIhextjzTm+IKo36ZsMGs2PSG +3zzafRScQMF80hhv8U8mRQmVlFza0Jj49EyClhDerDDLK675kuq/eQP8Hj+sCaQ/ +Zf2RT5Ykp860TmqWKReuwKjfFyL0F+PcHDkGVhDq6rV0FzxO3X6RCqgLeAenMUQI +MasYhA8SnOfehCzpbZNFv6jBPzTc +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert49[] = { + 0x30, 0x82, 0x05, 0xe1, 0x30, 0x82, 0x04, 0xc9, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x04, 0x07, 0x27, 0xaa, 0x47, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x5a, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49, + 0x45, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x09, + 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x31, 0x13, 0x30, + 0x11, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0a, 0x43, 0x79, 0x62, 0x65, + 0x72, 0x54, 0x72, 0x75, 0x73, 0x74, 0x31, 0x22, 0x30, 0x20, 0x06, 0x03, + 0x55, 0x04, 0x03, 0x13, 0x19, 0x42, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, + 0x72, 0x65, 0x20, 0x43, 0x79, 0x62, 0x65, 0x72, 0x54, 0x72, 0x75, 0x73, + 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x34, + 0x30, 0x35, 0x30, 0x37, 0x31, 0x37, 0x30, 0x34, 0x30, 0x39, 0x5a, 0x17, + 0x0d, 0x31, 0x38, 0x30, 0x35, 0x30, 0x37, 0x31, 0x37, 0x30, 0x33, 0x33, + 0x30, 0x5a, 0x30, 0x81, 0x8b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x13, 0x0a, 0x57, 0x61, 0x73, 0x68, 0x69, 0x6e, 0x67, + 0x74, 0x6f, 0x6e, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x07, + 0x13, 0x07, 0x52, 0x65, 0x64, 0x6d, 0x6f, 0x6e, 0x64, 0x31, 0x1e, 0x30, + 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, + 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x13, 0x0c, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, + 0x74, 0x20, 0x49, 0x54, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, + 0x20, 0x49, 0x54, 0x20, 0x53, 0x53, 0x4c, 0x20, 0x53, 0x48, 0x41, 0x32, + 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, + 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xd1, 0xe8, 0x37, + 0xa7, 0x76, 0x8a, 0x70, 0x4b, 0x19, 0xf0, 0x20, 0x37, 0x09, 0x24, 0x37, + 0x7f, 0xea, 0xfb, 0x78, 0xe6, 0x05, 0xba, 0x6a, 0xad, 0x4e, 0x27, 0x0d, + 0xfc, 0x72, 0x6a, 0xd9, 0x6c, 0x21, 0xc4, 0x64, 0x11, 0x95, 0x73, 0x10, + 0x0a, 0x5c, 0x25, 0x7b, 0x88, 0x6c, 0x94, 0x04, 0xfd, 0xc7, 0xdb, 0xae, + 0x7b, 0xdc, 0x4a, 0x08, 0xb3, 0x3e, 0x16, 0xf1, 0xd0, 0xad, 0xdb, 0x30, + 0x6d, 0xd7, 0x1a, 0x1e, 0x52, 0xb5, 0x3d, 0xf0, 0x47, 0x19, 0x03, 0xe2, + 0x7d, 0xa6, 0xbd, 0x57, 0x13, 0x3f, 0x54, 0xea, 0x3a, 0xa3, 0xb1, 0x77, + 0xfc, 0x42, 0xf0, 0x63, 0x49, 0x6a, 0x91, 0x80, 0x2e, 0x30, 0x49, 0xc0, + 0x8a, 0xeb, 0x2b, 0xaf, 0xfe, 0x3a, 0xeb, 0x07, 0x5d, 0x06, 0xf7, 0xe9, + 0xfd, 0x84, 0x0e, 0x91, 0xbd, 0x09, 0x20, 0x29, 0xe8, 0x6e, 0x5d, 0x09, + 0xce, 0x15, 0xd3, 0xe7, 0xef, 0xdb, 0x50, 0xeb, 0x44, 0xef, 0x18, 0x57, + 0xab, 0x04, 0x1d, 0xbc, 0x31, 0xf9, 0xf7, 0x7b, 0x2a, 0x13, 0xcf, 0xd1, + 0x3d, 0x51, 0xaf, 0x1b, 0xc5, 0xb5, 0x7b, 0xe7, 0xb0, 0xfc, 0x53, 0xbb, + 0x9a, 0xe7, 0x63, 0xde, 0x41, 0x33, 0xb6, 0x47, 0x24, 0x69, 0x5d, 0xb8, + 0x46, 0xa7, 0xff, 0xad, 0xab, 0xdf, 0x4f, 0x7a, 0x78, 0x25, 0x27, 0x21, + 0x26, 0x34, 0xca, 0x02, 0x6e, 0x37, 0x51, 0xf0, 0xed, 0x58, 0x1a, 0x60, + 0x94, 0xf6, 0xc4, 0x93, 0xd8, 0xdd, 0x30, 0x24, 0x25, 0xd7, 0x1c, 0xeb, + 0x19, 0x94, 0x35, 0x5d, 0x93, 0xb2, 0xae, 0xaa, 0x29, 0x83, 0x73, 0xc4, + 0x74, 0x59, 0x05, 0x52, 0x67, 0x9d, 0xda, 0x67, 0x51, 0x39, 0x05, 0x3a, + 0x36, 0xea, 0xf2, 0x1e, 0x76, 0x2b, 0x14, 0xae, 0xec, 0x3d, 0xf9, 0x14, + 0x99, 0x8b, 0x07, 0x6e, 0xbc, 0xe7, 0x0c, 0x56, 0xde, 0xac, 0xbe, 0xae, + 0xdb, 0x75, 0x32, 0x90, 0x9e, 0x63, 0xbd, 0x74, 0xbf, 0xe0, 0x0a, 0xca, + 0xf8, 0x34, 0x96, 0x67, 0x84, 0xcd, 0xd1, 0x42, 0x38, 0x78, 0xc7, 0x99, + 0xb6, 0x0c, 0xce, 0xb6, 0x0f, 0xe9, 0x1b, 0xcb, 0xf4, 0x59, 0xbe, 0x11, + 0x0e, 0xcb, 0x2c, 0x32, 0xc8, 0xfa, 0x83, 0x29, 0x64, 0x79, 0x3c, 0x8b, + 0x4b, 0xf0, 0x32, 0x74, 0x6c, 0xf3, 0x93, 0xb8, 0x96, 0x6b, 0x5d, 0x57, + 0x5a, 0x68, 0xc1, 0xcc, 0x0c, 0x79, 0x8a, 0x19, 0xde, 0xf5, 0x49, 0x02, + 0x5e, 0x08, 0x80, 0x01, 0x89, 0x0c, 0x32, 0xcd, 0xd2, 0xd6, 0x96, 0xd5, + 0x4b, 0xa0, 0xf3, 0xec, 0xbf, 0xab, 0xf4, 0x7d, 0xb3, 0xa1, 0xb9, 0x7c, + 0xda, 0x4e, 0xd7, 0xe5, 0xb7, 0xac, 0xb9, 0xf2, 0x25, 0x5f, 0x01, 0xcb, + 0x8c, 0x96, 0xa8, 0x28, 0xae, 0xc1, 0x33, 0x5a, 0xf6, 0x3f, 0x08, 0x90, + 0xdc, 0xeb, 0xff, 0x39, 0xd8, 0x26, 0xc8, 0x12, 0x9d, 0x1c, 0x9a, 0xaa, + 0xa9, 0xc0, 0x16, 0x8e, 0x86, 0xed, 0x67, 0x52, 0x96, 0x00, 0x7f, 0x0d, + 0x92, 0x3d, 0x3d, 0xd9, 0x70, 0x36, 0xe5, 0xea, 0x42, 0x6f, 0x1f, 0xae, + 0x95, 0xe5, 0x5b, 0x5d, 0xf8, 0xd0, 0x3a, 0xc7, 0xd4, 0xde, 0x77, 0x86, + 0xd0, 0xfc, 0x9e, 0x4e, 0xe2, 0xe2, 0xb8, 0xa9, 0x68, 0x37, 0x09, 0xc4, + 0x39, 0xe3, 0x85, 0xb8, 0x89, 0xf3, 0x1f, 0x6e, 0xb7, 0x6d, 0x1f, 0x4a, + 0x2f, 0x18, 0x09, 0x6f, 0xde, 0x4a, 0x01, 0x8f, 0x14, 0xc9, 0xb7, 0xa6, + 0xee, 0xa7, 0x63, 0x9f, 0x33, 0xa4, 0x54, 0x7c, 0x42, 0x83, 0x68, 0xb8, + 0xa5, 0xdf, 0xbf, 0xec, 0xb9, 0x1a, 0x5d, 0x13, 0x3b, 0xd9, 0xad, 0x68, + 0xfd, 0x20, 0x0a, 0x55, 0x91, 0x21, 0x64, 0xf9, 0xd7, 0x13, 0x01, 0xa0, + 0x08, 0x5d, 0x59, 0x89, 0x1b, 0x44, 0xaf, 0xa4, 0xac, 0xc7, 0x05, 0x10, + 0xfa, 0x41, 0x4a, 0xa8, 0xfb, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, + 0x01, 0x7b, 0x30, 0x82, 0x01, 0x77, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, + 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, + 0x01, 0x00, 0x30, 0x60, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x59, 0x30, + 0x57, 0x30, 0x48, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb1, 0x3e, + 0x01, 0x00, 0x30, 0x3b, 0x30, 0x39, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x02, 0x01, 0x16, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x63, 0x79, 0x62, 0x65, 0x72, 0x74, 0x72, 0x75, 0x73, 0x74, 0x2e, + 0x6f, 0x6d, 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2e, + 0x63, 0x66, 0x6d, 0x30, 0x0b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, + 0x82, 0x37, 0x2a, 0x01, 0x30, 0x42, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x01, 0x01, 0x04, 0x36, 0x30, 0x34, 0x30, 0x32, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x26, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x6f, 0x6d, + 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x62, + 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x6f, 0x72, 0x65, 0x72, 0x6f, 0x6f, 0x74, + 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, + 0x03, 0x02, 0x01, 0x86, 0x30, 0x27, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, + 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, + 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, + 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x09, 0x30, 0x1f, 0x06, + 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe5, 0x9d, + 0x59, 0x30, 0x82, 0x47, 0x58, 0xcc, 0xac, 0xfa, 0x08, 0x54, 0x36, 0x86, + 0x7b, 0x3a, 0xb5, 0x04, 0x4d, 0xf0, 0x30, 0x42, 0x06, 0x03, 0x55, 0x1d, + 0x1f, 0x04, 0x3b, 0x30, 0x39, 0x30, 0x37, 0xa0, 0x35, 0xa0, 0x33, 0x86, + 0x31, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x64, 0x70, 0x31, + 0x2e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2d, 0x74, 0x72, 0x75, 0x73, + 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x52, 0x4c, 0x2f, 0x4f, 0x6d, + 0x6e, 0x69, 0x72, 0x6f, 0x6f, 0x74, 0x32, 0x30, 0x32, 0x35, 0x2e, 0x63, + 0x72, 0x6c, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, + 0x14, 0x51, 0xaf, 0x24, 0x26, 0x9c, 0xf4, 0x68, 0x22, 0x57, 0x80, 0x26, + 0x2b, 0x3b, 0x46, 0x62, 0x15, 0x7b, 0x1e, 0xcc, 0xa5, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, + 0x03, 0x82, 0x01, 0x01, 0x00, 0x69, 0x62, 0xf6, 0x84, 0x91, 0x00, 0xc4, + 0x6f, 0x82, 0x7b, 0x24, 0xe1, 0x42, 0xa2, 0xa5, 0x8b, 0x82, 0x5c, 0xa7, + 0xc5, 0x44, 0xcb, 0xe7, 0x52, 0x76, 0x63, 0xd3, 0x76, 0x9e, 0x78, 0xe2, + 0x69, 0x35, 0xb1, 0x38, 0xba, 0xb0, 0x96, 0xc6, 0x1f, 0xac, 0x7b, 0xc6, + 0xb2, 0x65, 0x77, 0x8b, 0x7d, 0x8d, 0xae, 0x64, 0xb9, 0xa5, 0x8c, 0x17, + 0xca, 0x58, 0x65, 0xc3, 0xad, 0x82, 0xf5, 0xc5, 0xa2, 0xf5, 0x01, 0x13, + 0x93, 0xc6, 0x7e, 0x44, 0xe5, 0xc4, 0x61, 0xfa, 0x03, 0xb6, 0x56, 0xc1, + 0x72, 0xe1, 0xc8, 0x28, 0xc5, 0x69, 0x21, 0x8f, 0xac, 0x6e, 0xfd, 0x7f, + 0x43, 0x83, 0x36, 0xb8, 0xc0, 0xd6, 0xa0, 0x28, 0xfe, 0x1a, 0x45, 0xbe, + 0xfd, 0x93, 0x8c, 0x8d, 0xa4, 0x64, 0x79, 0x1f, 0x14, 0xdb, 0xa1, 0x9f, + 0x21, 0xdc, 0xc0, 0x4e, 0x7b, 0x17, 0x22, 0x17, 0xb1, 0xb6, 0x3c, 0xd3, + 0x9b, 0xe2, 0x0a, 0xa3, 0x7e, 0x99, 0xb0, 0xc1, 0xac, 0xd8, 0xf4, 0x86, + 0xdf, 0x3c, 0xda, 0x7d, 0x14, 0x9c, 0x40, 0xc1, 0x7c, 0xd2, 0x18, 0x6f, + 0xf1, 0x4f, 0x26, 0x45, 0x09, 0x95, 0x94, 0x5c, 0xda, 0xd0, 0x98, 0xf8, + 0xf4, 0x4c, 0x82, 0x96, 0x10, 0xde, 0xac, 0x30, 0xcb, 0x2b, 0xae, 0xf9, + 0x92, 0xea, 0xbf, 0x79, 0x03, 0xfc, 0x1e, 0x3f, 0xac, 0x09, 0xa4, 0x3f, + 0x65, 0xfd, 0x91, 0x4f, 0x96, 0x24, 0xa7, 0xce, 0xb4, 0x4e, 0x6a, 0x96, + 0x29, 0x17, 0xae, 0xc0, 0xa8, 0xdf, 0x17, 0x22, 0xf4, 0x17, 0xe3, 0xdc, + 0x1c, 0x39, 0x06, 0x56, 0x10, 0xea, 0xea, 0xb5, 0x74, 0x17, 0x3c, 0x4e, + 0xdd, 0x7e, 0x91, 0x0a, 0xa8, 0x0b, 0x78, 0x07, 0xa7, 0x31, 0x44, 0x08, + 0x31, 0xab, 0x18, 0x84, 0x0f, 0x12, 0x9c, 0xe7, 0xde, 0x84, 0x2c, 0xe9, + 0x6d, 0x93, 0x45, 0xbf, 0xa8, 0xc1, 0x3f, 0x34, 0xdc, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 13:8b:fe:f3:32:94:f9:d8:16:f9:45:c2:71:95:29:98 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Certification Authority + Validity + Not Before: Dec 16 01:00:05 2015 GMT + Not After : Dec 16 01:00:05 2030 GMT + Subject: C=IL, O=StartCom Ltd., OU=StartCom Certification Authority, CN=StartCom Class 3 OV Server CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:af:67:1c:6f:e5:45:e0:d7:46:4b:75:2c:b6:80: + f2:9a:17:4d:2d:ff:de:ae:d2:d4:00:8a:3a:b8:31: + fe:8e:37:9e:fa:aa:d5:a3:5b:16:12:c1:19:3e:34: + 85:96:c3:be:d3:b3:43:f4:8d:6f:16:bd:30:ba:07: + fc:d8:9a:c1:79:89:80:6d:a0:8c:be:dd:37:f7:eb: + 05:d3:53:7f:57:58:76:55:b6:a8:a8:86:44:b8:bb: + d0:13:da:fd:8f:e1:f2:cd:a0:15:38:55:56:ce:26: + cf:7c:93:75:29:7a:0a:ab:fb:ba:09:38:20:11:57: + 07:5d:7f:49:9f:2a:4a:67:1e:9e:58:e9:c7:7f:f9: + c3:ed:fe:5f:4d:af:b8:4f:9d:df:69:2d:69:1b:3a: + 58:81:69:63:30:ea:87:8d:0f:52:9d:5a:da:39:44: + ba:9f:89:9f:36:b6:c2:19:5c:d9:26:78:d9:ae:5e: + fc:95:90:bf:e8:11:c0:47:0f:77:89:dd:6a:28:4f: + 0a:bc:32:64:57:43:3d:08:65:93:e5:45:ae:dd:28: + 0c:27:2c:8e:a6:2b:09:03:5d:a1:78:d2:8c:ab:b6: + 6b:b9:46:c9:19:00:39:b9:bf:c6:13:2b:73:72:1f: + f2:3e:37:b8:e8:b9:14:65:88:4d:e2:f1:1b:d8:a5: + 1d:3b + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Extended Key Usage: + TLS Web Client Authentication, TLS Web Server Authentication + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:0 + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.startssl.com/sfsca.crl + + Authority Information Access: + OCSP - URI:http://ocsp.startssl.com + CA Issuers - URI:http://aia.startssl.com/certs/ca.crt + + X509v3 Subject Key Identifier: + B1:3F:1C:92:7B:92:B0:5A:25:B3:38:FB:9C:07:A4:26:50:32:E3:51 + X509v3 Authority Key Identifier: + keyid:4E:0B:EF:1A:A4:40:5B:A5:17:69:87:30:CA:34:68:43:D0:41:AE:F2 + + X509v3 Certificate Policies: + Policy: X509v3 Any Policy + CPS: http://www.startssl.com/policy + + Signature Algorithm: sha256WithRSAEncryption + 85:f2:e8:14:d3:1b:c1:a1:16:1d:a4:f4:4d:ba:51:8b:5c:52: + b1:54:54:12:16:17:9c:96:78:6f:d3:bf:df:43:36:f5:12:89: + 61:72:44:df:1c:9b:09:4f:60:26:68:c1:e6:66:50:70:b3:6a: + f1:a8:6a:0c:1e:2e:93:f1:ee:07:3e:09:dd:30:45:b2:56:8e: + dc:2c:5c:ab:49:fa:b9:04:03:40:15:7a:b5:30:e0:1d:91:8f: + a6:d6:6f:1f:99:a0:84:95:39:bd:ac:77:7f:72:4b:dd:2d:ae: + ff:a8:58:1d:46:27:d4:83:c7:69:64:9f:19:bb:10:f8:04:42: + 87:59:5d:02:b1:d6:e5:c8:da:43:30:a3:e8:37:a5:d2:48:0b: + a2:83:4e:9d:4f:83:58:9d:d7:47:22:b1:89:f0:89:3b:3d:28: + 43:2c:9b:17:7c:03:ee:9d:26:25:e0:04:b8:1d:04:57:42:47: + da:58:69:f0:d3:29:ab:12:02:99:2b:2a:d8:9d:a0:1f:54:5e: + 23:9a:0c:d2:99:58:c4:a1:e5:49:c2:25:a7:64:20:52:2e:e7: + 89:f5:19:c0:8b:d0:63:b1:78:1e:be:01:47:be:76:81:46:f1: + 99:1f:94:9a:be:fa:82:15:b5:84:84:79:75:93:ba:9f:b5:e4: + 9b:c2:cb:69:5c:bd:1f:55:0a:a7:26:30:05:51:be:65:ee:57: + a9:6a:df:bd:f9:36:2f:ad:1e:46:41:2b:b1:88:d0:88:25:85: + 40:17:79:bf:3d:8d:e2:f4:2d:ea:30:31:df:a1:40:cb:35:ff: + 82:9f:f5:99:3c:4a:fd:9d:a1:d1:55:cc:20:a8:1c:d8:20:05: + ab:b3:14:65:95:53:d8:e8:8e:57:c5:77:6b:2d:4d:88:e9:5d: + 62:d5:a2:f8:70:e1:70:eb:45:23:0e:f0:00:46:c2:48:31:e8: + e7:36:80:36:2d:22:f2:01:27:53:eb:ce:a7:69:49:82:bf:e7: + 0f:9c:f3:20:2e:f5:fa:5d:ce:ea:58:3a:8f:d8:aa:7d:30:b7: + 74:96:7c:3d:6e:b4:ec:4a:3b:59:b6:a9:50:0d:0f:05:06:70: + 26:b9:95:91:d1:5e:24:8c:8f:ca:74:57:97:90:8b:5a:b7:fe: + 8d:ad:d8:e8:c2:06:bc:08:56:21:02:12:53:c6:9f:86:04:58: + ca:2d:f8:03:0d:57:0b:1c:37:bd:f0:5a:35:f2:fe:3b:d6:a4: + 37:15:e9:f8:08:92:96:3d:74:c8:b5:5c:6e:65:08:e7:df:69: + 73:9c:ec:e3:30:5a:a6:df:5c:be:da:7f:00:ee:a5:da:2b:5c: + 1e:2a:6a:c0:a3:ae:1e:f1 +-----BEGIN CERTIFICATE----- +MIIF5TCCA82gAwIBAgIQE4v+8zKU+dgW+UXCcZUpmDANBgkqhkiG9w0BAQsFADB9 +MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi +U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh +cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTUxMjE2MDEwMDA1WhcN +MzAxMjE2MDEwMDA1WjB4MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20g +THRkLjEpMCcGA1UECxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx +JjAkBgNVBAMTHVN0YXJ0Q29tIENsYXNzIDMgT1YgU2VydmVyIENBMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr2ccb+VF4NdGS3UstoDymhdNLf/ertLU +AIo6uDH+jjee+qrVo1sWEsEZPjSFlsO+07ND9I1vFr0wugf82JrBeYmAbaCMvt03 +9+sF01N/V1h2VbaoqIZEuLvQE9r9j+HyzaAVOFVWzibPfJN1KXoKq/u6CTggEVcH +XX9JnypKZx6eWOnHf/nD7f5fTa+4T53faS1pGzpYgWljMOqHjQ9SnVraOUS6n4mf +NrbCGVzZJnjZrl78lZC/6BHARw93id1qKE8KvDJkV0M9CGWT5UWu3SgMJyyOpisJ +A12heNKMq7ZruUbJGQA5ub/GEytzch/yPje46LkUZYhN4vEb2KUdOwIDAQABo4IB +ZDCCAWAwDgYDVR0PAQH/BAQDAgEGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEF +BQcDATASBgNVHRMBAf8ECDAGAQH/AgEAMDIGA1UdHwQrMCkwJ6AloCOGIWh0dHA6 +Ly9jcmwuc3RhcnRzc2wuY29tL3Nmc2NhLmNybDBmBggrBgEFBQcBAQRaMFgwJAYI +KwYBBQUHMAGGGGh0dHA6Ly9vY3NwLnN0YXJ0c3NsLmNvbTAwBggrBgEFBQcwAoYk +aHR0cDovL2FpYS5zdGFydHNzbC5jb20vY2VydHMvY2EuY3J0MB0GA1UdDgQWBBSx +PxySe5KwWiWzOPucB6QmUDLjUTAfBgNVHSMEGDAWgBROC+8apEBbpRdphzDKNGhD +0EGu8jA/BgNVHSAEODA2MDQGBFUdIAAwLDAqBggrBgEFBQcCARYeaHR0cDovL3d3 +dy5zdGFydHNzbC5jb20vcG9saWN5MA0GCSqGSIb3DQEBCwUAA4ICAQCF8ugU0xvB +oRYdpPRNulGLXFKxVFQSFheclnhv07/fQzb1EolhckTfHJsJT2AmaMHmZlBws2rx +qGoMHi6T8e4HPgndMEWyVo7cLFyrSfq5BANAFXq1MOAdkY+m1m8fmaCElTm9rHd/ +ckvdLa7/qFgdRifUg8dpZJ8ZuxD4BEKHWV0CsdblyNpDMKPoN6XSSAuig06dT4NY +nddHIrGJ8Ik7PShDLJsXfAPunSYl4AS4HQRXQkfaWGnw0ymrEgKZKyrYnaAfVF4j +mgzSmVjEoeVJwiWnZCBSLueJ9RnAi9BjsXgevgFHvnaBRvGZH5SavvqCFbWEhHl1 +k7qfteSbwstpXL0fVQqnJjAFUb5l7lepat+9+TYvrR5GQSuxiNCIJYVAF3m/PY3i +9C3qMDHfoUDLNf+Cn/WZPEr9naHRVcwgqBzYIAWrsxRllVPY6I5XxXdrLU2I6V1i +1aL4cOFw60UjDvAARsJIMejnNoA2LSLyASdT686naUmCv+cPnPMgLvX6Xc7qWDqP +2Kp9MLd0lnw9brTsSjtZtqlQDQ8FBnAmuZWR0V4kjI/KdFeXkItat/6Nrdjowga8 +CFYhAhJTxp+GBFjKLfgDDVcLHDe98Fo18v471qQ3Fen4CJKWPXTItVxuZQjn32lz +nOzjMFqm31y+2n8A7qXaK1weKmrAo64e8Q== +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert50[] = { + 0x30, 0x82, 0x05, 0xe5, 0x30, 0x82, 0x03, 0xcd, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x13, 0x8b, 0xfe, 0xf3, 0x32, 0x94, 0xf9, 0xd8, 0x16, + 0xf9, 0x45, 0xc2, 0x71, 0x95, 0x29, 0x98, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x7d, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x49, + 0x4c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x4c, 0x74, 0x64, + 0x2e, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x22, + 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x69, 0x67, 0x69, 0x74, + 0x61, 0x6c, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x31, 0x29, + 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x20, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x31, + 0x32, 0x31, 0x36, 0x30, 0x31, 0x30, 0x30, 0x30, 0x35, 0x5a, 0x17, 0x0d, + 0x33, 0x30, 0x31, 0x32, 0x31, 0x36, 0x30, 0x31, 0x30, 0x30, 0x30, 0x35, + 0x5a, 0x30, 0x78, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x49, 0x4c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, + 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x13, 0x20, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, + 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1d, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, + 0x20, 0x33, 0x20, 0x4f, 0x56, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x20, 0x43, 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, + 0xaf, 0x67, 0x1c, 0x6f, 0xe5, 0x45, 0xe0, 0xd7, 0x46, 0x4b, 0x75, 0x2c, + 0xb6, 0x80, 0xf2, 0x9a, 0x17, 0x4d, 0x2d, 0xff, 0xde, 0xae, 0xd2, 0xd4, + 0x00, 0x8a, 0x3a, 0xb8, 0x31, 0xfe, 0x8e, 0x37, 0x9e, 0xfa, 0xaa, 0xd5, + 0xa3, 0x5b, 0x16, 0x12, 0xc1, 0x19, 0x3e, 0x34, 0x85, 0x96, 0xc3, 0xbe, + 0xd3, 0xb3, 0x43, 0xf4, 0x8d, 0x6f, 0x16, 0xbd, 0x30, 0xba, 0x07, 0xfc, + 0xd8, 0x9a, 0xc1, 0x79, 0x89, 0x80, 0x6d, 0xa0, 0x8c, 0xbe, 0xdd, 0x37, + 0xf7, 0xeb, 0x05, 0xd3, 0x53, 0x7f, 0x57, 0x58, 0x76, 0x55, 0xb6, 0xa8, + 0xa8, 0x86, 0x44, 0xb8, 0xbb, 0xd0, 0x13, 0xda, 0xfd, 0x8f, 0xe1, 0xf2, + 0xcd, 0xa0, 0x15, 0x38, 0x55, 0x56, 0xce, 0x26, 0xcf, 0x7c, 0x93, 0x75, + 0x29, 0x7a, 0x0a, 0xab, 0xfb, 0xba, 0x09, 0x38, 0x20, 0x11, 0x57, 0x07, + 0x5d, 0x7f, 0x49, 0x9f, 0x2a, 0x4a, 0x67, 0x1e, 0x9e, 0x58, 0xe9, 0xc7, + 0x7f, 0xf9, 0xc3, 0xed, 0xfe, 0x5f, 0x4d, 0xaf, 0xb8, 0x4f, 0x9d, 0xdf, + 0x69, 0x2d, 0x69, 0x1b, 0x3a, 0x58, 0x81, 0x69, 0x63, 0x30, 0xea, 0x87, + 0x8d, 0x0f, 0x52, 0x9d, 0x5a, 0xda, 0x39, 0x44, 0xba, 0x9f, 0x89, 0x9f, + 0x36, 0xb6, 0xc2, 0x19, 0x5c, 0xd9, 0x26, 0x78, 0xd9, 0xae, 0x5e, 0xfc, + 0x95, 0x90, 0xbf, 0xe8, 0x11, 0xc0, 0x47, 0x0f, 0x77, 0x89, 0xdd, 0x6a, + 0x28, 0x4f, 0x0a, 0xbc, 0x32, 0x64, 0x57, 0x43, 0x3d, 0x08, 0x65, 0x93, + 0xe5, 0x45, 0xae, 0xdd, 0x28, 0x0c, 0x27, 0x2c, 0x8e, 0xa6, 0x2b, 0x09, + 0x03, 0x5d, 0xa1, 0x78, 0xd2, 0x8c, 0xab, 0xb6, 0x6b, 0xb9, 0x46, 0xc9, + 0x19, 0x00, 0x39, 0xb9, 0xbf, 0xc6, 0x13, 0x2b, 0x73, 0x72, 0x1f, 0xf2, + 0x3e, 0x37, 0xb8, 0xe8, 0xb9, 0x14, 0x65, 0x88, 0x4d, 0xe2, 0xf1, 0x1b, + 0xd8, 0xa5, 0x1d, 0x3b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, + 0x64, 0x30, 0x82, 0x01, 0x60, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, + 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x1d, 0x06, + 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x03, 0x01, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, + 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, + 0x30, 0x32, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2b, 0x30, 0x29, 0x30, + 0x27, 0xa0, 0x25, 0xa0, 0x23, 0x86, 0x21, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, + 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x66, 0x73, 0x63, 0x61, + 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x66, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x01, 0x01, 0x04, 0x5a, 0x30, 0x58, 0x30, 0x24, 0x06, 0x08, + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x18, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x30, + 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x24, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x61, 0x69, 0x61, 0x2e, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x63, 0x65, 0x72, 0x74, 0x73, 0x2f, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x74, + 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xb1, + 0x3f, 0x1c, 0x92, 0x7b, 0x92, 0xb0, 0x5a, 0x25, 0xb3, 0x38, 0xfb, 0x9c, + 0x07, 0xa4, 0x26, 0x50, 0x32, 0xe3, 0x51, 0x30, 0x1f, 0x06, 0x03, 0x55, + 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x4e, 0x0b, 0xef, 0x1a, + 0xa4, 0x40, 0x5b, 0xa5, 0x17, 0x69, 0x87, 0x30, 0xca, 0x34, 0x68, 0x43, + 0xd0, 0x41, 0xae, 0xf2, 0x30, 0x3f, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, + 0x38, 0x30, 0x36, 0x30, 0x34, 0x06, 0x04, 0x55, 0x1d, 0x20, 0x00, 0x30, + 0x2c, 0x30, 0x2a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, + 0x01, 0x16, 0x1e, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, + 0x77, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, + 0x03, 0x82, 0x02, 0x01, 0x00, 0x85, 0xf2, 0xe8, 0x14, 0xd3, 0x1b, 0xc1, + 0xa1, 0x16, 0x1d, 0xa4, 0xf4, 0x4d, 0xba, 0x51, 0x8b, 0x5c, 0x52, 0xb1, + 0x54, 0x54, 0x12, 0x16, 0x17, 0x9c, 0x96, 0x78, 0x6f, 0xd3, 0xbf, 0xdf, + 0x43, 0x36, 0xf5, 0x12, 0x89, 0x61, 0x72, 0x44, 0xdf, 0x1c, 0x9b, 0x09, + 0x4f, 0x60, 0x26, 0x68, 0xc1, 0xe6, 0x66, 0x50, 0x70, 0xb3, 0x6a, 0xf1, + 0xa8, 0x6a, 0x0c, 0x1e, 0x2e, 0x93, 0xf1, 0xee, 0x07, 0x3e, 0x09, 0xdd, + 0x30, 0x45, 0xb2, 0x56, 0x8e, 0xdc, 0x2c, 0x5c, 0xab, 0x49, 0xfa, 0xb9, + 0x04, 0x03, 0x40, 0x15, 0x7a, 0xb5, 0x30, 0xe0, 0x1d, 0x91, 0x8f, 0xa6, + 0xd6, 0x6f, 0x1f, 0x99, 0xa0, 0x84, 0x95, 0x39, 0xbd, 0xac, 0x77, 0x7f, + 0x72, 0x4b, 0xdd, 0x2d, 0xae, 0xff, 0xa8, 0x58, 0x1d, 0x46, 0x27, 0xd4, + 0x83, 0xc7, 0x69, 0x64, 0x9f, 0x19, 0xbb, 0x10, 0xf8, 0x04, 0x42, 0x87, + 0x59, 0x5d, 0x02, 0xb1, 0xd6, 0xe5, 0xc8, 0xda, 0x43, 0x30, 0xa3, 0xe8, + 0x37, 0xa5, 0xd2, 0x48, 0x0b, 0xa2, 0x83, 0x4e, 0x9d, 0x4f, 0x83, 0x58, + 0x9d, 0xd7, 0x47, 0x22, 0xb1, 0x89, 0xf0, 0x89, 0x3b, 0x3d, 0x28, 0x43, + 0x2c, 0x9b, 0x17, 0x7c, 0x03, 0xee, 0x9d, 0x26, 0x25, 0xe0, 0x04, 0xb8, + 0x1d, 0x04, 0x57, 0x42, 0x47, 0xda, 0x58, 0x69, 0xf0, 0xd3, 0x29, 0xab, + 0x12, 0x02, 0x99, 0x2b, 0x2a, 0xd8, 0x9d, 0xa0, 0x1f, 0x54, 0x5e, 0x23, + 0x9a, 0x0c, 0xd2, 0x99, 0x58, 0xc4, 0xa1, 0xe5, 0x49, 0xc2, 0x25, 0xa7, + 0x64, 0x20, 0x52, 0x2e, 0xe7, 0x89, 0xf5, 0x19, 0xc0, 0x8b, 0xd0, 0x63, + 0xb1, 0x78, 0x1e, 0xbe, 0x01, 0x47, 0xbe, 0x76, 0x81, 0x46, 0xf1, 0x99, + 0x1f, 0x94, 0x9a, 0xbe, 0xfa, 0x82, 0x15, 0xb5, 0x84, 0x84, 0x79, 0x75, + 0x93, 0xba, 0x9f, 0xb5, 0xe4, 0x9b, 0xc2, 0xcb, 0x69, 0x5c, 0xbd, 0x1f, + 0x55, 0x0a, 0xa7, 0x26, 0x30, 0x05, 0x51, 0xbe, 0x65, 0xee, 0x57, 0xa9, + 0x6a, 0xdf, 0xbd, 0xf9, 0x36, 0x2f, 0xad, 0x1e, 0x46, 0x41, 0x2b, 0xb1, + 0x88, 0xd0, 0x88, 0x25, 0x85, 0x40, 0x17, 0x79, 0xbf, 0x3d, 0x8d, 0xe2, + 0xf4, 0x2d, 0xea, 0x30, 0x31, 0xdf, 0xa1, 0x40, 0xcb, 0x35, 0xff, 0x82, + 0x9f, 0xf5, 0x99, 0x3c, 0x4a, 0xfd, 0x9d, 0xa1, 0xd1, 0x55, 0xcc, 0x20, + 0xa8, 0x1c, 0xd8, 0x20, 0x05, 0xab, 0xb3, 0x14, 0x65, 0x95, 0x53, 0xd8, + 0xe8, 0x8e, 0x57, 0xc5, 0x77, 0x6b, 0x2d, 0x4d, 0x88, 0xe9, 0x5d, 0x62, + 0xd5, 0xa2, 0xf8, 0x70, 0xe1, 0x70, 0xeb, 0x45, 0x23, 0x0e, 0xf0, 0x00, + 0x46, 0xc2, 0x48, 0x31, 0xe8, 0xe7, 0x36, 0x80, 0x36, 0x2d, 0x22, 0xf2, + 0x01, 0x27, 0x53, 0xeb, 0xce, 0xa7, 0x69, 0x49, 0x82, 0xbf, 0xe7, 0x0f, + 0x9c, 0xf3, 0x20, 0x2e, 0xf5, 0xfa, 0x5d, 0xce, 0xea, 0x58, 0x3a, 0x8f, + 0xd8, 0xaa, 0x7d, 0x30, 0xb7, 0x74, 0x96, 0x7c, 0x3d, 0x6e, 0xb4, 0xec, + 0x4a, 0x3b, 0x59, 0xb6, 0xa9, 0x50, 0x0d, 0x0f, 0x05, 0x06, 0x70, 0x26, + 0xb9, 0x95, 0x91, 0xd1, 0x5e, 0x24, 0x8c, 0x8f, 0xca, 0x74, 0x57, 0x97, + 0x90, 0x8b, 0x5a, 0xb7, 0xfe, 0x8d, 0xad, 0xd8, 0xe8, 0xc2, 0x06, 0xbc, + 0x08, 0x56, 0x21, 0x02, 0x12, 0x53, 0xc6, 0x9f, 0x86, 0x04, 0x58, 0xca, + 0x2d, 0xf8, 0x03, 0x0d, 0x57, 0x0b, 0x1c, 0x37, 0xbd, 0xf0, 0x5a, 0x35, + 0xf2, 0xfe, 0x3b, 0xd6, 0xa4, 0x37, 0x15, 0xe9, 0xf8, 0x08, 0x92, 0x96, + 0x3d, 0x74, 0xc8, 0xb5, 0x5c, 0x6e, 0x65, 0x08, 0xe7, 0xdf, 0x69, 0x73, + 0x9c, 0xec, 0xe3, 0x30, 0x5a, 0xa6, 0xdf, 0x5c, 0xbe, 0xda, 0x7f, 0x00, + 0xee, 0xa5, 0xda, 0x2b, 0x5c, 0x1e, 0x2a, 0x6a, 0xc0, 0xa3, 0xae, 0x1e, + 0xf1, +}; + +#if 0 +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 7250751724796726 (0x19c28530e93b36) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=IL, O=StartCom Ltd., OU=Secure Digital Certificate Signing, CN=StartCom Certification Authority + Validity + Not Before: Sep 17 22:46:36 2006 GMT + Not After : Dec 31 23:59:59 2019 GMT + Subject: C=CN, O=WoSign CA Limited, CN=Certification Authority of WoSign + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (4096 bit) + Modulus: + 00:bd:ca:8d:ac:b8:91:15:56:97:7b:6b:5c:7a:c2: + de:6b:d9:a1:b0:c3:10:23:fa:a7:a1:b2:cc:31:fa: + 3e:d9:a6:29:6f:16:3d:e0:6b:f8:b8:40:5f:db:39: + a8:00:7a:8b:a0:4d:54:7d:c2:22:78:fc:8e:09:b8: + a8:85:d7:cc:95:97:4b:74:d8:9e:7e:f0:00:e4:0e: + 89:ae:49:28:44:1a:10:99:32:0f:25:88:53:a4:0d: + b3:0f:12:08:16:0b:03:71:27:1c:7f:e1:db:d2:fd: + 67:68:c4:05:5d:0a:0e:5d:70:d7:d8:97:a0:bc:53: + 41:9a:91:8d:f4:9e:36:66:7a:7e:56:c1:90:5f:e6: + b1:68:20:36:a4:8c:24:2c:2c:47:0b:59:76:66:30: + b5:be:de:ed:8f:f8:9d:d3:bb:01:30:e6:f2:f3:0e: + e0:2c:92:80:f3:85:f9:28:8a:b4:54:2e:9a:ed:f7: + 76:fc:15:68:16:eb:4a:6c:eb:2e:12:8f:d4:cf:fe: + 0c:c7:5c:1d:0b:7e:05:32:be:5e:b0:09:2a:42:d5: + c9:4e:90:b3:59:0d:bb:7a:7e:cd:d5:08:5a:b4:7f: + d8:1c:69:11:f9:27:0f:7b:06:af:54:83:18:7b:e1: + dd:54:7a:51:68:6e:77:fc:c6:bf:52:4a:66:46:a1: + b2:67:1a:bb:a3:4f:77:a0:be:5d:ff:fc:56:0b:43: + 72:77:90:ca:9e:f9:f2:39:f5:0d:a9:f4:ea:d7:e7: + b3:10:2f:30:42:37:21:cc:30:70:c9:86:98:0f:cc: + 58:4d:83:bb:7d:e5:1a:a5:37:8d:b6:ac:32:97:00: + 3a:63:71:24:1e:9e:37:c4:ff:74:d4:37:c0:e2:fe: + 88:46:60:11:dd:08:3f:50:36:ab:b8:7a:a4:95:62: + 6a:6e:b0:ca:6a:21:5a:69:f3:f3:fb:1d:70:39:95: + f3:a7:6e:a6:81:89:a1:88:c5:3b:71:ca:a3:52:ee: + 83:bb:fd:a0:77:f4:e4:6f:e7:42:db:6d:4a:99:8a: + 34:48:bc:17:dc:e4:80:08:22:b6:f2:31:c0:3f:04: + 3e:eb:9f:20:79:d6:b8:06:64:64:02:31:d7:a9:cd: + 52:fb:84:45:69:09:00:2a:dc:55:8b:c4:06:46:4b: + c0:4a:1d:09:5b:39:28:fd:a9:ab:ce:00:f9:2e:48: + 4b:26:e6:30:4c:a5:58:ca:b4:44:82:4f:e7:91:1e: + 33:c3:b0:93:ff:11:fc:81:d2:ca:1f:71:29:dd:76: + 4f:92:25:af:1d:81:b7:0f:2f:8c:c3:06:cc:2f:27: + a3:4a:e4:0e:99:ba:7c:1e:45:1f:7f:aa:19:45:96: + fd:fc:3d + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: critical + CA:TRUE, pathlen:2 + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Subject Key Identifier: + E1:66:CF:0E:D1:F1:B3:4B:B7:06:20:14:FE:87:12:D5:F6:FE:FB:3E + X509v3 Authority Key Identifier: + keyid:4E:0B:EF:1A:A4:40:5B:A5:17:69:87:30:CA:34:68:43:D0:41:AE:F2 + + Authority Information Access: + OCSP - URI:http://ocsp.startssl.com/ca + CA Issuers - URI:http://aia.startssl.com/certs/ca.crt + + X509v3 CRL Distribution Points: + + Full Name: + URI:http://crl.startssl.com/sfsca.crl + + Signature Algorithm: sha256WithRSAEncryption + b6:6d:f8:70:fb:e2:0d:4c:98:b3:07:49:15:f5:04:c4:6c:ca: + ca:f5:68:a0:08:fe:12:6d:9c:04:06:c9:ad:9a:91:52:3e:78: + c4:5c:ee:9f:54:1d:ee:e3:f1:5e:30:c9:49:e1:39:e0:a6:9d: + 36:6c:57:fa:e6:34:4f:55:e8:87:a8:2c:dd:05:f1:58:12:91: + e8:ca:ce:28:78:8f:df:07:85:01:a5:dc:45:96:05:d4:80:b2: + 2b:05:9a:cb:9a:a5:8b:e0:3a:67:e6:73:47:be:4a:fd:27:b1: + 88:ef:e6:ca:cf:8d:0e:26:9f:fa:5f:57:78:ad:6d:fe:ae:9b: + 35:08:b1:c3:ba:c1:00:4a:4b:7d:14:bd:f7:f1:d3:55:18:ac: + d0:33:70:88:6d:c4:09:71:14:a6:2b:4f:88:81:e7:0b:00:37: + a9:15:7d:7e:d7:01:96:3f:2f:af:7b:62:ae:0a:4a:bf:4b:39: + 2e:35:10:8b:fe:04:39:e4:3c:3a:0c:09:56:40:3a:b5:f4:c2: + 68:0c:b5:f9:52:cd:ee:9d:f8:98:fc:78:e7:58:47:8f:1c:73: + 58:69:33:ab:ff:dd:df:8e:24:01:77:98:19:3a:b0:66:79:bc: + e1:08:a3:0e:4f:c1:04:b3:f3:01:c8:eb:d3:59:1c:35:d2:93: + 1e:70:65:82:7f:db:cf:fb:c8:99:12:60:c3:44:6f:3a:80:4b: + d7:be:21:aa:14:7a:64:cb:dd:37:43:45:5b:32:2e:45:f0:d9: + 59:1f:6b:18:f0:7c:e9:55:36:19:61:5f:b5:7d:f1:8d:bd:88: + e4:75:4b:98:dd:27:b0:e4:84:44:2a:61:84:57:05:82:11:1f: + aa:35:58:f3:20:0e:af:59:ef:fa:55:72:72:0d:26:d0:9b:53: + 49:ac:ce:37:2e:65:61:ff:f6:ec:1b:ea:f6:f1:a6:d3:d1:b5: + 7b:be:35:f4:22:c1:bc:8d:01:bd:68:5e:83:0d:2f:ec:d6:da: + 63:0c:27:d1:54:3e:e4:a8:d3:ce:4b:32:b8:91:94:ff:fb:5b: + 49:2d:75:18:a8:ba:71:9a:3b:ae:d9:c0:a9:4f:87:91:ed:8b: + 7b:6b:20:98:89:39:83:4f:80:c4:69:cc:17:c9:c8:4e:be:e4: + a9:a5:81:76:70:06:04:32:cd:83:65:f4:bc:7d:3e:13:bc:d2: + e8:6f:63:aa:b5:3b:da:8d:86:32:82:78:9d:d9:cc:ff:bf:57: + 64:74:ed:28:3d:44:62:15:61:4b:f7:94:b0:0d:2a:67:1c:f0: + cb:9b:a5:92:bf:f8:41:5a:c1:3d:60:ed:9f:bb:b8:6d:9b:ce: + a9:6a:16:3f:7e:ea:06:f1 +-----BEGIN CERTIFICATE----- +MIIGXDCCBESgAwIBAgIHGcKFMOk7NjANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQG +EwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERp +Z2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MjI0NjM2WhcNMTkxMjMxMjM1 +OTU5WjBVMQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQx +KjAoBgNVBAMTIUNlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbjCCAiIw +DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL3Kjay4kRVWl3trXHrC3mvZobDD +ECP6p6GyzDH6PtmmKW8WPeBr+LhAX9s5qAB6i6BNVH3CInj8jgm4qIXXzJWXS3TY +nn7wAOQOia5JKEQaEJkyDyWIU6QNsw8SCBYLA3EnHH/h29L9Z2jEBV0KDl1w19iX +oLxTQZqRjfSeNmZ6flbBkF/msWggNqSMJCwsRwtZdmYwtb7e7Y/4ndO7ATDm8vMO +4CySgPOF+SiKtFQumu33dvwVaBbrSmzrLhKP1M/+DMdcHQt+BTK+XrAJKkLVyU6Q +s1kNu3p+zdUIWrR/2BxpEfknD3sGr1SDGHvh3VR6UWhud/zGv1JKZkahsmcau6NP +d6C+Xf/8VgtDcneQyp758jn1Dan06tfnsxAvMEI3IcwwcMmGmA/MWE2Du33lGqU3 +jbasMpcAOmNxJB6eN8T/dNQ3wOL+iEZgEd0IP1A2q7h6pJViam6wymohWmnz8/sd +cDmV86dupoGJoYjFO3HKo1Lug7v9oHf05G/nQtttSpmKNEi8F9zkgAgitvIxwD8E +PuufIHnWuAZkZAIx16nNUvuERWkJACrcVYvEBkZLwEodCVs5KP2pq84A+S5ISybm +MEylWMq0RIJP55EeM8Owk/8R/IHSyh9xKd12T5Ilrx2Btw8vjMMGzC8no0rkDpm6 +fB5FH3+qGUWW/fw9AgMBAAGjggEHMIIBAzASBgNVHRMBAf8ECDAGAQH/AgECMA4G +A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU4WbPDtHxs0u3BiAU/ocS1fb++z4wHwYD +VR0jBBgwFoAUTgvvGqRAW6UXaYcwyjRoQ9BBrvIwaQYIKwYBBQUHAQEEXTBbMCcG +CCsGAQUFBzABhhtodHRwOi8vb2NzcC5zdGFydHNzbC5jb20vY2EwMAYIKwYBBQUH +MAKGJGh0dHA6Ly9haWEuc3RhcnRzc2wuY29tL2NlcnRzL2NhLmNydDAyBgNVHR8E +KzApMCegJaAjhiFodHRwOi8vY3JsLnN0YXJ0c3NsLmNvbS9zZnNjYS5jcmwwDQYJ +KoZIhvcNAQELBQADggIBALZt+HD74g1MmLMHSRX1BMRsysr1aKAI/hJtnAQGya2a +kVI+eMRc7p9UHe7j8V4wyUnhOeCmnTZsV/rmNE9V6IeoLN0F8VgSkejKzih4j98H +hQGl3EWWBdSAsisFmsuapYvgOmfmc0e+Sv0nsYjv5srPjQ4mn/pfV3itbf6umzUI +scO6wQBKS30Uvffx01UYrNAzcIhtxAlxFKYrT4iB5wsAN6kVfX7XAZY/L697Yq4K +Sr9LOS41EIv+BDnkPDoMCVZAOrX0wmgMtflSze6d+Jj8eOdYR48cc1hpM6v/3d+O +JAF3mBk6sGZ5vOEIow5PwQSz8wHI69NZHDXSkx5wZYJ/28/7yJkSYMNEbzqAS9e+ +IaoUemTL3TdDRVsyLkXw2VkfaxjwfOlVNhlhX7V98Y29iOR1S5jdJ7DkhEQqYYRX +BYIRH6o1WPMgDq9Z7/pVcnINJtCbU0mszjcuZWH/9uwb6vbxptPRtXu+NfQiwbyN +Ab1oXoMNL+zW2mMMJ9FUPuSo085LMriRlP/7W0ktdRiounGaO67ZwKlPh5Hti3tr +IJiJOYNPgMRpzBfJyE6+5KmlgXZwBgQyzYNl9Lx9PhO80uhvY6q1O9qNhjKCeJ3Z +zP+/V2R07Sg9RGIVYUv3lLANKmcc8MubpZK/+EFawT1g7Z+7uG2bzqlqFj9+6gbx +-----END CERTIFICATE----- +#endif +static const unsigned char kDERCert51[] = { + 0x30, 0x82, 0x06, 0x5c, 0x30, 0x82, 0x04, 0x44, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x07, 0x19, 0xc2, 0x85, 0x30, 0xe9, 0x3b, 0x36, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, + 0x00, 0x30, 0x7d, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x49, 0x4c, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, + 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x2b, 0x30, 0x29, 0x06, 0x03, 0x55, 0x04, + 0x0b, 0x13, 0x22, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x44, 0x69, + 0x67, 0x69, 0x74, 0x61, 0x6c, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, + 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, + 0x67, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x20, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6f, 0x6d, 0x20, 0x43, 0x65, 0x72, + 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, + 0x30, 0x36, 0x30, 0x39, 0x31, 0x37, 0x32, 0x32, 0x34, 0x36, 0x33, 0x36, + 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, + 0x39, 0x35, 0x39, 0x5a, 0x30, 0x55, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x4e, 0x31, 0x1a, 0x30, 0x18, 0x06, + 0x03, 0x55, 0x04, 0x0a, 0x13, 0x11, 0x57, 0x6f, 0x53, 0x69, 0x67, 0x6e, + 0x20, 0x43, 0x41, 0x20, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x64, 0x31, + 0x2a, 0x30, 0x28, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x21, 0x43, 0x65, + 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x6f, 0x66, + 0x20, 0x57, 0x6f, 0x53, 0x69, 0x67, 0x6e, 0x30, 0x82, 0x02, 0x22, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, + 0x82, 0x02, 0x01, 0x00, 0xbd, 0xca, 0x8d, 0xac, 0xb8, 0x91, 0x15, 0x56, + 0x97, 0x7b, 0x6b, 0x5c, 0x7a, 0xc2, 0xde, 0x6b, 0xd9, 0xa1, 0xb0, 0xc3, + 0x10, 0x23, 0xfa, 0xa7, 0xa1, 0xb2, 0xcc, 0x31, 0xfa, 0x3e, 0xd9, 0xa6, + 0x29, 0x6f, 0x16, 0x3d, 0xe0, 0x6b, 0xf8, 0xb8, 0x40, 0x5f, 0xdb, 0x39, + 0xa8, 0x00, 0x7a, 0x8b, 0xa0, 0x4d, 0x54, 0x7d, 0xc2, 0x22, 0x78, 0xfc, + 0x8e, 0x09, 0xb8, 0xa8, 0x85, 0xd7, 0xcc, 0x95, 0x97, 0x4b, 0x74, 0xd8, + 0x9e, 0x7e, 0xf0, 0x00, 0xe4, 0x0e, 0x89, 0xae, 0x49, 0x28, 0x44, 0x1a, + 0x10, 0x99, 0x32, 0x0f, 0x25, 0x88, 0x53, 0xa4, 0x0d, 0xb3, 0x0f, 0x12, + 0x08, 0x16, 0x0b, 0x03, 0x71, 0x27, 0x1c, 0x7f, 0xe1, 0xdb, 0xd2, 0xfd, + 0x67, 0x68, 0xc4, 0x05, 0x5d, 0x0a, 0x0e, 0x5d, 0x70, 0xd7, 0xd8, 0x97, + 0xa0, 0xbc, 0x53, 0x41, 0x9a, 0x91, 0x8d, 0xf4, 0x9e, 0x36, 0x66, 0x7a, + 0x7e, 0x56, 0xc1, 0x90, 0x5f, 0xe6, 0xb1, 0x68, 0x20, 0x36, 0xa4, 0x8c, + 0x24, 0x2c, 0x2c, 0x47, 0x0b, 0x59, 0x76, 0x66, 0x30, 0xb5, 0xbe, 0xde, + 0xed, 0x8f, 0xf8, 0x9d, 0xd3, 0xbb, 0x01, 0x30, 0xe6, 0xf2, 0xf3, 0x0e, + 0xe0, 0x2c, 0x92, 0x80, 0xf3, 0x85, 0xf9, 0x28, 0x8a, 0xb4, 0x54, 0x2e, + 0x9a, 0xed, 0xf7, 0x76, 0xfc, 0x15, 0x68, 0x16, 0xeb, 0x4a, 0x6c, 0xeb, + 0x2e, 0x12, 0x8f, 0xd4, 0xcf, 0xfe, 0x0c, 0xc7, 0x5c, 0x1d, 0x0b, 0x7e, + 0x05, 0x32, 0xbe, 0x5e, 0xb0, 0x09, 0x2a, 0x42, 0xd5, 0xc9, 0x4e, 0x90, + 0xb3, 0x59, 0x0d, 0xbb, 0x7a, 0x7e, 0xcd, 0xd5, 0x08, 0x5a, 0xb4, 0x7f, + 0xd8, 0x1c, 0x69, 0x11, 0xf9, 0x27, 0x0f, 0x7b, 0x06, 0xaf, 0x54, 0x83, + 0x18, 0x7b, 0xe1, 0xdd, 0x54, 0x7a, 0x51, 0x68, 0x6e, 0x77, 0xfc, 0xc6, + 0xbf, 0x52, 0x4a, 0x66, 0x46, 0xa1, 0xb2, 0x67, 0x1a, 0xbb, 0xa3, 0x4f, + 0x77, 0xa0, 0xbe, 0x5d, 0xff, 0xfc, 0x56, 0x0b, 0x43, 0x72, 0x77, 0x90, + 0xca, 0x9e, 0xf9, 0xf2, 0x39, 0xf5, 0x0d, 0xa9, 0xf4, 0xea, 0xd7, 0xe7, + 0xb3, 0x10, 0x2f, 0x30, 0x42, 0x37, 0x21, 0xcc, 0x30, 0x70, 0xc9, 0x86, + 0x98, 0x0f, 0xcc, 0x58, 0x4d, 0x83, 0xbb, 0x7d, 0xe5, 0x1a, 0xa5, 0x37, + 0x8d, 0xb6, 0xac, 0x32, 0x97, 0x00, 0x3a, 0x63, 0x71, 0x24, 0x1e, 0x9e, + 0x37, 0xc4, 0xff, 0x74, 0xd4, 0x37, 0xc0, 0xe2, 0xfe, 0x88, 0x46, 0x60, + 0x11, 0xdd, 0x08, 0x3f, 0x50, 0x36, 0xab, 0xb8, 0x7a, 0xa4, 0x95, 0x62, + 0x6a, 0x6e, 0xb0, 0xca, 0x6a, 0x21, 0x5a, 0x69, 0xf3, 0xf3, 0xfb, 0x1d, + 0x70, 0x39, 0x95, 0xf3, 0xa7, 0x6e, 0xa6, 0x81, 0x89, 0xa1, 0x88, 0xc5, + 0x3b, 0x71, 0xca, 0xa3, 0x52, 0xee, 0x83, 0xbb, 0xfd, 0xa0, 0x77, 0xf4, + 0xe4, 0x6f, 0xe7, 0x42, 0xdb, 0x6d, 0x4a, 0x99, 0x8a, 0x34, 0x48, 0xbc, + 0x17, 0xdc, 0xe4, 0x80, 0x08, 0x22, 0xb6, 0xf2, 0x31, 0xc0, 0x3f, 0x04, + 0x3e, 0xeb, 0x9f, 0x20, 0x79, 0xd6, 0xb8, 0x06, 0x64, 0x64, 0x02, 0x31, + 0xd7, 0xa9, 0xcd, 0x52, 0xfb, 0x84, 0x45, 0x69, 0x09, 0x00, 0x2a, 0xdc, + 0x55, 0x8b, 0xc4, 0x06, 0x46, 0x4b, 0xc0, 0x4a, 0x1d, 0x09, 0x5b, 0x39, + 0x28, 0xfd, 0xa9, 0xab, 0xce, 0x00, 0xf9, 0x2e, 0x48, 0x4b, 0x26, 0xe6, + 0x30, 0x4c, 0xa5, 0x58, 0xca, 0xb4, 0x44, 0x82, 0x4f, 0xe7, 0x91, 0x1e, + 0x33, 0xc3, 0xb0, 0x93, 0xff, 0x11, 0xfc, 0x81, 0xd2, 0xca, 0x1f, 0x71, + 0x29, 0xdd, 0x76, 0x4f, 0x92, 0x25, 0xaf, 0x1d, 0x81, 0xb7, 0x0f, 0x2f, + 0x8c, 0xc3, 0x06, 0xcc, 0x2f, 0x27, 0xa3, 0x4a, 0xe4, 0x0e, 0x99, 0xba, + 0x7c, 0x1e, 0x45, 0x1f, 0x7f, 0xaa, 0x19, 0x45, 0x96, 0xfd, 0xfc, 0x3d, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x07, 0x30, 0x82, 0x01, + 0x03, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, + 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x02, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, + 0x06, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, + 0xe1, 0x66, 0xcf, 0x0e, 0xd1, 0xf1, 0xb3, 0x4b, 0xb7, 0x06, 0x20, 0x14, + 0xfe, 0x87, 0x12, 0xd5, 0xf6, 0xfe, 0xfb, 0x3e, 0x30, 0x1f, 0x06, 0x03, + 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x4e, 0x0b, 0xef, + 0x1a, 0xa4, 0x40, 0x5b, 0xa5, 0x17, 0x69, 0x87, 0x30, 0xca, 0x34, 0x68, + 0x43, 0xd0, 0x41, 0xae, 0xf2, 0x30, 0x69, 0x06, 0x08, 0x2b, 0x06, 0x01, + 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x5d, 0x30, 0x5b, 0x30, 0x27, 0x06, + 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x1b, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x63, 0x61, 0x30, 0x30, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + 0x30, 0x02, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x61, + 0x69, 0x61, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, 0x72, 0x74, 0x73, 0x2f, 0x63, 0x61, + 0x2e, 0x63, 0x72, 0x74, 0x30, 0x32, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, + 0x2b, 0x30, 0x29, 0x30, 0x27, 0xa0, 0x25, 0xa0, 0x23, 0x86, 0x21, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x73, 0x73, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, + 0x66, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, + 0x82, 0x02, 0x01, 0x00, 0xb6, 0x6d, 0xf8, 0x70, 0xfb, 0xe2, 0x0d, 0x4c, + 0x98, 0xb3, 0x07, 0x49, 0x15, 0xf5, 0x04, 0xc4, 0x6c, 0xca, 0xca, 0xf5, + 0x68, 0xa0, 0x08, 0xfe, 0x12, 0x6d, 0x9c, 0x04, 0x06, 0xc9, 0xad, 0x9a, + 0x91, 0x52, 0x3e, 0x78, 0xc4, 0x5c, 0xee, 0x9f, 0x54, 0x1d, 0xee, 0xe3, + 0xf1, 0x5e, 0x30, 0xc9, 0x49, 0xe1, 0x39, 0xe0, 0xa6, 0x9d, 0x36, 0x6c, + 0x57, 0xfa, 0xe6, 0x34, 0x4f, 0x55, 0xe8, 0x87, 0xa8, 0x2c, 0xdd, 0x05, + 0xf1, 0x58, 0x12, 0x91, 0xe8, 0xca, 0xce, 0x28, 0x78, 0x8f, 0xdf, 0x07, + 0x85, 0x01, 0xa5, 0xdc, 0x45, 0x96, 0x05, 0xd4, 0x80, 0xb2, 0x2b, 0x05, + 0x9a, 0xcb, 0x9a, 0xa5, 0x8b, 0xe0, 0x3a, 0x67, 0xe6, 0x73, 0x47, 0xbe, + 0x4a, 0xfd, 0x27, 0xb1, 0x88, 0xef, 0xe6, 0xca, 0xcf, 0x8d, 0x0e, 0x26, + 0x9f, 0xfa, 0x5f, 0x57, 0x78, 0xad, 0x6d, 0xfe, 0xae, 0x9b, 0x35, 0x08, + 0xb1, 0xc3, 0xba, 0xc1, 0x00, 0x4a, 0x4b, 0x7d, 0x14, 0xbd, 0xf7, 0xf1, + 0xd3, 0x55, 0x18, 0xac, 0xd0, 0x33, 0x70, 0x88, 0x6d, 0xc4, 0x09, 0x71, + 0x14, 0xa6, 0x2b, 0x4f, 0x88, 0x81, 0xe7, 0x0b, 0x00, 0x37, 0xa9, 0x15, + 0x7d, 0x7e, 0xd7, 0x01, 0x96, 0x3f, 0x2f, 0xaf, 0x7b, 0x62, 0xae, 0x0a, + 0x4a, 0xbf, 0x4b, 0x39, 0x2e, 0x35, 0x10, 0x8b, 0xfe, 0x04, 0x39, 0xe4, + 0x3c, 0x3a, 0x0c, 0x09, 0x56, 0x40, 0x3a, 0xb5, 0xf4, 0xc2, 0x68, 0x0c, + 0xb5, 0xf9, 0x52, 0xcd, 0xee, 0x9d, 0xf8, 0x98, 0xfc, 0x78, 0xe7, 0x58, + 0x47, 0x8f, 0x1c, 0x73, 0x58, 0x69, 0x33, 0xab, 0xff, 0xdd, 0xdf, 0x8e, + 0x24, 0x01, 0x77, 0x98, 0x19, 0x3a, 0xb0, 0x66, 0x79, 0xbc, 0xe1, 0x08, + 0xa3, 0x0e, 0x4f, 0xc1, 0x04, 0xb3, 0xf3, 0x01, 0xc8, 0xeb, 0xd3, 0x59, + 0x1c, 0x35, 0xd2, 0x93, 0x1e, 0x70, 0x65, 0x82, 0x7f, 0xdb, 0xcf, 0xfb, + 0xc8, 0x99, 0x12, 0x60, 0xc3, 0x44, 0x6f, 0x3a, 0x80, 0x4b, 0xd7, 0xbe, + 0x21, 0xaa, 0x14, 0x7a, 0x64, 0xcb, 0xdd, 0x37, 0x43, 0x45, 0x5b, 0x32, + 0x2e, 0x45, 0xf0, 0xd9, 0x59, 0x1f, 0x6b, 0x18, 0xf0, 0x7c, 0xe9, 0x55, + 0x36, 0x19, 0x61, 0x5f, 0xb5, 0x7d, 0xf1, 0x8d, 0xbd, 0x88, 0xe4, 0x75, + 0x4b, 0x98, 0xdd, 0x27, 0xb0, 0xe4, 0x84, 0x44, 0x2a, 0x61, 0x84, 0x57, + 0x05, 0x82, 0x11, 0x1f, 0xaa, 0x35, 0x58, 0xf3, 0x20, 0x0e, 0xaf, 0x59, + 0xef, 0xfa, 0x55, 0x72, 0x72, 0x0d, 0x26, 0xd0, 0x9b, 0x53, 0x49, 0xac, + 0xce, 0x37, 0x2e, 0x65, 0x61, 0xff, 0xf6, 0xec, 0x1b, 0xea, 0xf6, 0xf1, + 0xa6, 0xd3, 0xd1, 0xb5, 0x7b, 0xbe, 0x35, 0xf4, 0x22, 0xc1, 0xbc, 0x8d, + 0x01, 0xbd, 0x68, 0x5e, 0x83, 0x0d, 0x2f, 0xec, 0xd6, 0xda, 0x63, 0x0c, + 0x27, 0xd1, 0x54, 0x3e, 0xe4, 0xa8, 0xd3, 0xce, 0x4b, 0x32, 0xb8, 0x91, + 0x94, 0xff, 0xfb, 0x5b, 0x49, 0x2d, 0x75, 0x18, 0xa8, 0xba, 0x71, 0x9a, + 0x3b, 0xae, 0xd9, 0xc0, 0xa9, 0x4f, 0x87, 0x91, 0xed, 0x8b, 0x7b, 0x6b, + 0x20, 0x98, 0x89, 0x39, 0x83, 0x4f, 0x80, 0xc4, 0x69, 0xcc, 0x17, 0xc9, + 0xc8, 0x4e, 0xbe, 0xe4, 0xa9, 0xa5, 0x81, 0x76, 0x70, 0x06, 0x04, 0x32, + 0xcd, 0x83, 0x65, 0xf4, 0xbc, 0x7d, 0x3e, 0x13, 0xbc, 0xd2, 0xe8, 0x6f, + 0x63, 0xaa, 0xb5, 0x3b, 0xda, 0x8d, 0x86, 0x32, 0x82, 0x78, 0x9d, 0xd9, + 0xcc, 0xff, 0xbf, 0x57, 0x64, 0x74, 0xed, 0x28, 0x3d, 0x44, 0x62, 0x15, + 0x61, 0x4b, 0xf7, 0x94, 0xb0, 0x0d, 0x2a, 0x67, 0x1c, 0xf0, 0xcb, 0x9b, + 0xa5, 0x92, 0xbf, 0xf8, 0x41, 0x5a, 0xc1, 0x3d, 0x60, 0xed, 0x9f, 0xbb, + 0xb8, 0x6d, 0x9b, 0xce, 0xa9, 0x6a, 0x16, 0x3f, 0x7e, 0xea, 0x06, 0xf1, +};
diff --git a/net/quic/core/crypto/common_cert_set_test.cc b/net/quic/core/crypto/common_cert_set_test.cc index df60892..3eea6ee 100644 --- a/net/quic/core/crypto/common_cert_set_test.cc +++ b/net/quic/core/crypto/common_cert_set_test.cc
@@ -13,93 +13,7 @@ namespace net { namespace test { -static const unsigned char kGIACertificate1[] = { - 0x30, 0x82, 0x03, 0xf0, 0x30, 0x82, 0x02, 0xd8, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x03, 0x02, 0x3a, 0x76, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x42, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, - 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, - 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, - 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, - 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, - 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, - 0x34, 0x30, 0x35, 0x31, 0x35, 0x31, 0x35, 0x35, 0x35, 0x5a, 0x17, 0x0d, - 0x31, 0x36, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, - 0x5a, 0x30, 0x49, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, - 0x0a, 0x13, 0x0a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, - 0x63, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1c, - 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x65, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, - 0x79, 0x20, 0x47, 0x32, 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, 0x9c, 0x2a, 0x04, 0x77, 0x5c, 0xd8, 0x50, 0x91, 0x3a, 0x06, 0xa3, - 0x82, 0xe0, 0xd8, 0x50, 0x48, 0xbc, 0x89, 0x3f, 0xf1, 0x19, 0x70, 0x1a, - 0x88, 0x46, 0x7e, 0xe0, 0x8f, 0xc5, 0xf1, 0x89, 0xce, 0x21, 0xee, 0x5a, - 0xfe, 0x61, 0x0d, 0xb7, 0x32, 0x44, 0x89, 0xa0, 0x74, 0x0b, 0x53, 0x4f, - 0x55, 0xa4, 0xce, 0x82, 0x62, 0x95, 0xee, 0xeb, 0x59, 0x5f, 0xc6, 0xe1, - 0x05, 0x80, 0x12, 0xc4, 0x5e, 0x94, 0x3f, 0xbc, 0x5b, 0x48, 0x38, 0xf4, - 0x53, 0xf7, 0x24, 0xe6, 0xfb, 0x91, 0xe9, 0x15, 0xc4, 0xcf, 0xf4, 0x53, - 0x0d, 0xf4, 0x4a, 0xfc, 0x9f, 0x54, 0xde, 0x7d, 0xbe, 0xa0, 0x6b, 0x6f, - 0x87, 0xc0, 0xd0, 0x50, 0x1f, 0x28, 0x30, 0x03, 0x40, 0xda, 0x08, 0x73, - 0x51, 0x6c, 0x7f, 0xff, 0x3a, 0x3c, 0xa7, 0x37, 0x06, 0x8e, 0xbd, 0x4b, - 0x11, 0x04, 0xeb, 0x7d, 0x24, 0xde, 0xe6, 0xf9, 0xfc, 0x31, 0x71, 0xfb, - 0x94, 0xd5, 0x60, 0xf3, 0x2e, 0x4a, 0xaf, 0x42, 0xd2, 0xcb, 0xea, 0xc4, - 0x6a, 0x1a, 0xb2, 0xcc, 0x53, 0xdd, 0x15, 0x4b, 0x8b, 0x1f, 0xc8, 0x19, - 0x61, 0x1f, 0xcd, 0x9d, 0xa8, 0x3e, 0x63, 0x2b, 0x84, 0x35, 0x69, 0x65, - 0x84, 0xc8, 0x19, 0xc5, 0x46, 0x22, 0xf8, 0x53, 0x95, 0xbe, 0xe3, 0x80, - 0x4a, 0x10, 0xc6, 0x2a, 0xec, 0xba, 0x97, 0x20, 0x11, 0xc7, 0x39, 0x99, - 0x10, 0x04, 0xa0, 0xf0, 0x61, 0x7a, 0x95, 0x25, 0x8c, 0x4e, 0x52, 0x75, - 0xe2, 0xb6, 0xed, 0x08, 0xca, 0x14, 0xfc, 0xce, 0x22, 0x6a, 0xb3, 0x4e, - 0xcf, 0x46, 0x03, 0x97, 0x97, 0x03, 0x7e, 0xc0, 0xb1, 0xde, 0x7b, 0xaf, - 0x45, 0x33, 0xcf, 0xba, 0x3e, 0x71, 0xb7, 0xde, 0xf4, 0x25, 0x25, 0xc2, - 0x0d, 0x35, 0x89, 0x9d, 0x9d, 0xfb, 0x0e, 0x11, 0x79, 0x89, 0x1e, 0x37, - 0xc5, 0xaf, 0x8e, 0x72, 0x69, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, - 0xe7, 0x30, 0x81, 0xe4, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, - 0x18, 0x30, 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, - 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, - 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, - 0x4a, 0xdd, 0x06, 0x16, 0x1b, 0xbc, 0xf6, 0x68, 0xb5, 0x76, 0xf5, 0x81, - 0xb6, 0xbb, 0x62, 0x1a, 0xba, 0x5a, 0x81, 0x2f, 0x30, 0x12, 0x06, 0x03, - 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, - 0xff, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, - 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x35, 0x06, 0x03, - 0x55, 0x1d, 0x1f, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0, - 0x26, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, - 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, - 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, - 0x63, 0x72, 0x6c, 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x01, 0x01, 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, - 0x63, 0x6f, 0x6d, 0x30, 0x17, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x10, - 0x30, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, - 0x79, 0x02, 0x05, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, - 0x27, 0x8c, 0xcf, 0xe9, 0xc7, 0x3b, 0xbe, 0xc0, 0x6f, 0xe8, 0x96, 0x84, - 0xfb, 0x9c, 0x5c, 0x5d, 0x90, 0xe4, 0x77, 0xdb, 0x8b, 0x32, 0x60, 0x9b, - 0x65, 0xd8, 0x85, 0x26, 0xb5, 0xba, 0x9f, 0x1e, 0xde, 0x64, 0x4e, 0x1f, - 0xc6, 0xc8, 0x20, 0x5b, 0x09, 0x9f, 0xab, 0xa9, 0xe0, 0x09, 0x34, 0x45, - 0xa2, 0x65, 0x25, 0x37, 0x3d, 0x7f, 0x5a, 0x6f, 0x20, 0xcc, 0xf9, 0xfa, - 0xf1, 0x1d, 0x8f, 0x10, 0x0c, 0x02, 0x3a, 0xc4, 0xc9, 0x01, 0x76, 0x96, - 0xbe, 0x9b, 0xf9, 0x15, 0xd8, 0x39, 0xd1, 0xc5, 0x03, 0x47, 0x76, 0xb8, - 0x8a, 0x8c, 0x31, 0xd6, 0x60, 0xd5, 0xe4, 0x8f, 0xdb, 0xfa, 0x3c, 0xc6, - 0xd5, 0x98, 0x28, 0xf8, 0x1c, 0x8f, 0x17, 0x91, 0x34, 0xcb, 0xcb, 0x52, - 0x7a, 0xd1, 0xfb, 0x3a, 0x20, 0xe4, 0xe1, 0x86, 0xb1, 0xd8, 0x18, 0x0f, - 0xbe, 0xd6, 0x87, 0x64, 0x8d, 0xc5, 0x0a, 0x25, 0x42, 0x51, 0xef, 0xb2, - 0x38, 0xb8, 0xe0, 0x1d, 0xd0, 0xe1, 0xfc, 0xe6, 0xf4, 0xaf, 0x46, 0xba, - 0xef, 0xc0, 0xbf, 0xc5, 0xb4, 0x05, 0xf5, 0x94, 0x75, 0x0c, 0xfe, 0xa2, - 0xbe, 0x02, 0xba, 0xea, 0x86, 0x5b, 0xf9, 0x35, 0xb3, 0x66, 0xf5, 0xc5, - 0x8d, 0x85, 0xa1, 0x1a, 0x23, 0x77, 0x1a, 0x19, 0x17, 0x54, 0x13, 0x60, - 0x9f, 0x0b, 0xe1, 0xb4, 0x9c, 0x28, 0x2a, 0xf9, 0xae, 0x02, 0x34, 0x6d, - 0x25, 0x93, 0x9c, 0x82, 0xa8, 0x17, 0x7b, 0xf1, 0x85, 0xb0, 0xd3, 0x0f, - 0x58, 0xe1, 0xfb, 0xb1, 0xfe, 0x9c, 0xa1, 0xa3, 0xe8, 0xfd, 0xc9, 0x3f, - 0xf4, 0xd7, 0x71, 0xdc, 0xbd, 0x8c, 0xa4, 0x19, 0xe0, 0x21, 0x23, 0x23, - 0x55, 0x13, 0x8f, 0xa4, 0x16, 0x02, 0x09, 0x7e, 0xb9, 0xaf, 0xee, 0xdb, - 0x53, 0x64, 0xbd, 0x71, 0x2f, 0xb9, 0x39, 0xce, 0x30, 0xb7, 0xb4, 0xbc, - 0x54, 0xe0, 0x47, 0x07, -}; +// Google Internet Authority cert from v2 of the cert set. static const unsigned char kGIACertificate2[] = { 0x30, 0x82, 0x03, 0xf0, 0x30, 0x82, 0x02, 0xd8, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x02, 0x3a, 0x83, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, @@ -188,13 +102,102 @@ 0x7e, 0xc8, 0x35, 0xd8, }; -TEST(CommonCertSets, FindGIA_1) { - StringPiece gia(reinterpret_cast<const char*>(kGIACertificate1), - sizeof(kGIACertificate1)); +// Google Internet Authority cert from v3 of the cert set. +static const unsigned char kGIACertificate3[] = { + 0x30, 0x82, 0x03, 0xf0, 0x30, 0x82, 0x02, 0xd8, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x03, 0x02, 0x3a, 0x92, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x42, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0d, 0x47, + 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x63, 0x2e, + 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x12, 0x47, + 0x65, 0x6f, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x30, + 0x34, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, + 0x31, 0x37, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, + 0x5a, 0x30, 0x49, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, + 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, + 0x0a, 0x13, 0x0a, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, + 0x63, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1c, + 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x65, 0x74, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, + 0x79, 0x20, 0x47, 0x32, 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, 0x9c, 0x2a, 0x04, 0x77, 0x5c, 0xd8, 0x50, 0x91, 0x3a, 0x06, 0xa3, + 0x82, 0xe0, 0xd8, 0x50, 0x48, 0xbc, 0x89, 0x3f, 0xf1, 0x19, 0x70, 0x1a, + 0x88, 0x46, 0x7e, 0xe0, 0x8f, 0xc5, 0xf1, 0x89, 0xce, 0x21, 0xee, 0x5a, + 0xfe, 0x61, 0x0d, 0xb7, 0x32, 0x44, 0x89, 0xa0, 0x74, 0x0b, 0x53, 0x4f, + 0x55, 0xa4, 0xce, 0x82, 0x62, 0x95, 0xee, 0xeb, 0x59, 0x5f, 0xc6, 0xe1, + 0x05, 0x80, 0x12, 0xc4, 0x5e, 0x94, 0x3f, 0xbc, 0x5b, 0x48, 0x38, 0xf4, + 0x53, 0xf7, 0x24, 0xe6, 0xfb, 0x91, 0xe9, 0x15, 0xc4, 0xcf, 0xf4, 0x53, + 0x0d, 0xf4, 0x4a, 0xfc, 0x9f, 0x54, 0xde, 0x7d, 0xbe, 0xa0, 0x6b, 0x6f, + 0x87, 0xc0, 0xd0, 0x50, 0x1f, 0x28, 0x30, 0x03, 0x40, 0xda, 0x08, 0x73, + 0x51, 0x6c, 0x7f, 0xff, 0x3a, 0x3c, 0xa7, 0x37, 0x06, 0x8e, 0xbd, 0x4b, + 0x11, 0x04, 0xeb, 0x7d, 0x24, 0xde, 0xe6, 0xf9, 0xfc, 0x31, 0x71, 0xfb, + 0x94, 0xd5, 0x60, 0xf3, 0x2e, 0x4a, 0xaf, 0x42, 0xd2, 0xcb, 0xea, 0xc4, + 0x6a, 0x1a, 0xb2, 0xcc, 0x53, 0xdd, 0x15, 0x4b, 0x8b, 0x1f, 0xc8, 0x19, + 0x61, 0x1f, 0xcd, 0x9d, 0xa8, 0x3e, 0x63, 0x2b, 0x84, 0x35, 0x69, 0x65, + 0x84, 0xc8, 0x19, 0xc5, 0x46, 0x22, 0xf8, 0x53, 0x95, 0xbe, 0xe3, 0x80, + 0x4a, 0x10, 0xc6, 0x2a, 0xec, 0xba, 0x97, 0x20, 0x11, 0xc7, 0x39, 0x99, + 0x10, 0x04, 0xa0, 0xf0, 0x61, 0x7a, 0x95, 0x25, 0x8c, 0x4e, 0x52, 0x75, + 0xe2, 0xb6, 0xed, 0x08, 0xca, 0x14, 0xfc, 0xce, 0x22, 0x6a, 0xb3, 0x4e, + 0xcf, 0x46, 0x03, 0x97, 0x97, 0x03, 0x7e, 0xc0, 0xb1, 0xde, 0x7b, 0xaf, + 0x45, 0x33, 0xcf, 0xba, 0x3e, 0x71, 0xb7, 0xde, 0xf4, 0x25, 0x25, 0xc2, + 0x0d, 0x35, 0x89, 0x9d, 0x9d, 0xfb, 0x0e, 0x11, 0x79, 0x89, 0x1e, 0x37, + 0xc5, 0xaf, 0x8e, 0x72, 0x69, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, + 0xe7, 0x30, 0x81, 0xe4, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, + 0x18, 0x30, 0x16, 0x80, 0x14, 0xc0, 0x7a, 0x98, 0x68, 0x8d, 0x89, 0xfb, + 0xab, 0x05, 0x64, 0x0c, 0x11, 0x7d, 0xaa, 0x7d, 0x65, 0xb8, 0xca, 0xcc, + 0x4e, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, + 0x4a, 0xdd, 0x06, 0x16, 0x1b, 0xbc, 0xf6, 0x68, 0xb5, 0x76, 0xf5, 0x81, + 0xb6, 0xbb, 0x62, 0x1a, 0xba, 0x5a, 0x81, 0x2f, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, + 0x30, 0x2e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, + 0x04, 0x22, 0x30, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x30, 0x01, 0x86, 0x12, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, + 0x2f, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x63, 0x64, 0x2e, 0x63, 0x6f, 0x6d, + 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, + 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x35, 0x06, 0x03, + 0x55, 0x1d, 0x1f, 0x04, 0x2e, 0x30, 0x2c, 0x30, 0x2a, 0xa0, 0x28, 0xa0, + 0x26, 0x86, 0x24, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, 0x2e, + 0x73, 0x79, 0x6d, 0x63, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x72, + 0x6c, 0x73, 0x2f, 0x67, 0x74, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x2e, + 0x63, 0x72, 0x6c, 0x30, 0x17, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x10, + 0x30, 0x0e, 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, + 0x79, 0x02, 0x05, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, + 0x08, 0x4e, 0x04, 0xa7, 0x80, 0x7f, 0x10, 0x16, 0x43, 0x5e, 0x02, 0xad, + 0xd7, 0x42, 0x80, 0xf4, 0xb0, 0x8e, 0xd2, 0xae, 0xb3, 0xeb, 0x11, 0x7d, + 0x90, 0x84, 0x18, 0x7d, 0xe7, 0x90, 0x15, 0xfb, 0x49, 0x7f, 0xa8, 0x99, + 0x05, 0x91, 0xbb, 0x7a, 0xc9, 0xd6, 0x3c, 0x37, 0x18, 0x09, 0x9a, 0xb6, + 0xc7, 0x92, 0x20, 0x07, 0x35, 0x33, 0x09, 0xe4, 0x28, 0x63, 0x72, 0x0d, + 0xb4, 0xe0, 0x32, 0x9c, 0x87, 0x98, 0xc4, 0x1b, 0x76, 0x89, 0x67, 0xc1, + 0x50, 0x58, 0xb0, 0x13, 0xaa, 0x13, 0x1a, 0x1b, 0x32, 0xa5, 0xbe, 0xea, + 0x11, 0x95, 0x4c, 0x48, 0x63, 0x49, 0xe9, 0x99, 0x5d, 0x20, 0x37, 0xcc, + 0xfe, 0x2a, 0x69, 0x51, 0x16, 0x95, 0x4b, 0xa9, 0xde, 0x49, 0x82, 0xc0, + 0x10, 0x70, 0xf4, 0x2c, 0xf3, 0xec, 0xbc, 0x24, 0x24, 0xd0, 0x4e, 0xac, + 0xa5, 0xd9, 0x5e, 0x1e, 0x6d, 0x92, 0xc1, 0xa7, 0xac, 0x48, 0x35, 0x81, + 0xf9, 0xe5, 0xe4, 0x9c, 0x65, 0x69, 0xcd, 0x87, 0xa4, 0x41, 0x50, 0x3f, + 0x2e, 0x57, 0xa5, 0x91, 0x51, 0x12, 0x58, 0x0e, 0x8c, 0x09, 0xa1, 0xac, + 0x7a, 0xa4, 0x12, 0xa5, 0x27, 0xf3, 0x9a, 0x10, 0x97, 0x7d, 0x55, 0x03, + 0x06, 0xf7, 0x66, 0x58, 0x5f, 0x5f, 0x64, 0xe1, 0xab, 0x5d, 0x6d, 0xa5, + 0x39, 0x48, 0x75, 0x98, 0x4c, 0x29, 0x5a, 0x3a, 0x8d, 0xd3, 0x2b, 0xca, + 0x9c, 0x55, 0x04, 0xbf, 0xf4, 0xe6, 0x14, 0xd5, 0x80, 0xac, 0x26, 0xed, + 0x17, 0x89, 0xa6, 0x93, 0x6c, 0x5c, 0xa4, 0xcc, 0xb8, 0xf0, 0x66, 0x8e, + 0x64, 0xe3, 0x7d, 0x9a, 0xe2, 0x00, 0xb3, 0x49, 0xc7, 0xe4, 0x0a, 0xaa, + 0xdd, 0x5b, 0x83, 0xc7, 0x70, 0x90, 0x46, 0x4e, 0xbe, 0xd0, 0xdb, 0x59, + 0x96, 0x6c, 0x2e, 0xf5, 0x16, 0x36, 0xde, 0x71, 0xcc, 0x01, 0xc2, 0x12, + 0xc1, 0x21, 0xc6, 0x16, +}; + +TEST(CommonCertSets, FindGIA_2) { + StringPiece gia(reinterpret_cast<const char*>(kGIACertificate2), + sizeof(kGIACertificate2)); const CommonCertSets* sets(CommonCertSets::GetInstanceQUIC()); - // Common Cert Set 1's hash. - const uint64_t in_hash = UINT64_C(0xff715ce4e7e9267b); + // Common Cert Set 2's hash. + const uint64_t in_hash = UINT64_C(0xe81a92926081e801); uint64_t hash; uint32_t index; ASSERT_TRUE(sets->MatchCert( @@ -209,13 +212,13 @@ EXPECT_EQ(0, memcmp(gia.data(), gia_copy.data(), gia.size())); } -TEST(CommonCertSets, FindGIA_2) { - StringPiece gia(reinterpret_cast<const char*>(kGIACertificate2), - sizeof(kGIACertificate2)); +TEST(CommonCertSets, FindGIA_3) { + StringPiece gia(reinterpret_cast<const char*>(kGIACertificate3), + sizeof(kGIACertificate3)); const CommonCertSets* sets(CommonCertSets::GetInstanceQUIC()); - // Common Cert Set 2's hash. - const uint64_t in_hash = UINT64_C(0xe81a92926081e801); + // Common Cert Set 3's hash. + const uint64_t in_hash = UINT64_C(0x918215a28680ed7e); uint64_t hash; uint32_t index; ASSERT_TRUE(sets->MatchCert(
diff --git a/net/quic/core/crypto/crypto_server_config_protobuf.cc b/net/quic/core/crypto/crypto_server_config_protobuf.cc index a2b8a34..c8e70ed 100644 --- a/net/quic/core/crypto/crypto_server_config_protobuf.cc +++ b/net/quic/core/crypto/crypto_server_config_protobuf.cc
@@ -12,7 +12,7 @@ : primary_time_(QuicWallTime::Zero().ToUNIXSeconds()), priority_(0) {} QuicServerConfigProtobuf::~QuicServerConfigProtobuf() { - STLDeleteElements(&keys_); + base::STLDeleteElements(&keys_); } } // namespace net
diff --git a/net/quic/core/crypto/crypto_server_config_protobuf.h b/net/quic/core/crypto/crypto_server_config_protobuf.h index 4ea23d5..28c2eb9 100644 --- a/net/quic/core/crypto/crypto_server_config_protobuf.h +++ b/net/quic/core/crypto/crypto_server_config_protobuf.h
@@ -59,7 +59,7 @@ return keys_.back(); } - void clear_key() { STLDeleteElements(&keys_); } + void clear_key() { base::STLDeleteElements(&keys_); } bool has_primary_time() const { return primary_time_ > 0; }
diff --git a/net/quic/core/crypto/crypto_server_test.cc b/net/quic/core/crypto/crypto_server_test.cc index b125e7d8..fe56b9e 100644 --- a/net/quic/core/crypto/crypto_server_test.cc +++ b/net/quic/core/crypto/crypto_server_test.cc
@@ -91,7 +91,7 @@ for (bool enable_stateless_rejects : kTrueFalse) { for (bool use_stateless_rejects : kTrueFalse) { // Start with all versions, remove highest on each iteration. - QuicVersionVector supported_versions = QuicSupportedVersions(); + QuicVersionVector supported_versions = AllSupportedVersions(); while (!supported_versions.empty()) { params.push_back(TestParams(enable_stateless_rejects, use_stateless_rejects, supported_versions)); @@ -111,7 +111,8 @@ rand_, CryptoTestUtils::ProofSourceForTesting()), compressed_certs_cache_( - QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) { + QuicCompressedCertsCache::kQuicCompressedCertsCacheSize), + chlo_packet_size_(kDefaultMaxPacketSize) { supported_versions_ = GetParam().supported_versions; config_.set_enable_serving_sct(true); @@ -282,7 +283,8 @@ result, /*reject_only=*/false, /*connection_id=*/1, server_ip, client_address_, supported_versions_.front(), supported_versions_, use_stateless_rejects_, server_designated_connection_id, &clock_, rand_, - &compressed_certs_cache_, ¶ms_, &crypto_proof_, &out_, + &compressed_certs_cache_, ¶ms_, &crypto_proof_, + /*total_framing_overhead=*/50, chlo_packet_size_, &out_, &diversification_nonce, &error_details); if (should_succeed) { @@ -375,6 +377,7 @@ CryptoHandshakeMessage out_; uint8_t orbit_[kOrbitSize]; bool use_stateless_rejects_; + size_t chlo_packet_size_; // These strings contain hex escaped values from the server suitable for using // when constructing client hello messages. @@ -475,6 +478,38 @@ CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); } +TEST_P(CryptoServerTest, RejectNotTooLarge) { + FLAGS_quic_use_chlo_packet_size = true; + // When the CHLO packet is large enough, ensure that a full REJ is sent. + chlo_packet_size_ *= 2; + + // clang-format off + CryptoHandshakeMessage msg = CryptoTestUtils::Message( + "CHLO", + "PDMD", "X509", + "AEAD", "AESG", + "KEXS", "C255", + "PUBS", pub_hex_.c_str(), + "NONC", nonce_hex_.c_str(), + "PDMD", "X509", + "VER\0", client_version_string_.c_str(), + "$padding", static_cast<int>(kClientHelloMinimumSize), + nullptr); + // clang-format on + + // The REJ will be larger than the CHLO so no PROF or CRT will be sent. + config_.set_chlo_multiplier(1); + + ShouldSucceed(msg); + StringPiece cert, proof, cert_sct; + EXPECT_TRUE(out_.GetStringPiece(kCertificateTag, &cert)); + EXPECT_TRUE(out_.GetStringPiece(kPROF, &proof)); + EXPECT_TRUE(out_.GetStringPiece(kCertificateSCTTag, &cert_sct)); + const HandshakeFailureReason kRejectReasons[] = { + SERVER_CONFIG_INCHOATE_HELLO_FAILURE}; + CheckRejectReasons(kRejectReasons, arraysize(kRejectReasons)); +} + TEST_P(CryptoServerTest, RejectTooLargeButValidSTK) { // Check that the server replies with no certificate when a CHLO is // constructed with a PDMD but no SKT when the REJ would be too large.
diff --git a/net/quic/core/crypto/proof_test.cc b/net/quic/core/crypto/proof_test.cc index 2a1123b..af0a439 100644 --- a/net/quic/core/crypto/proof_test.cc +++ b/net/quic/core/crypto/proof_test.cc
@@ -142,7 +142,7 @@ INSTANTIATE_TEST_CASE_P(QuicVersion, ProofTest, - ::testing::ValuesIn(QuicSupportedVersions())); + ::testing::ValuesIn(AllSupportedVersions())); // TODO(rtenneti): Enable testing of ProofVerifier. See http://crbug.com/514468. TEST_P(ProofTest, DISABLED_Verify) {
diff --git a/net/quic/core/crypto/quic_crypto_client_config.cc b/net/quic/core/crypto/quic_crypto_client_config.cc index 47c03a7..a9fb9d08e 100644 --- a/net/quic/core/crypto/quic_crypto_client_config.cc +++ b/net/quic/core/crypto/quic_crypto_client_config.cc
@@ -62,7 +62,7 @@ } QuicCryptoClientConfig::~QuicCryptoClientConfig() { - STLDeleteValues(&cached_states_); + base::STLDeleteValues(&cached_states_); } QuicCryptoClientConfig::CachedState::CachedState() @@ -417,6 +417,8 @@ QuicCryptoNegotiatedParameters* out_params, CryptoHandshakeMessage* out) const { out->set_tag(kCHLO); + // TODO(rch): Remove this when we remove: + // FLAGS_quic_use_chlo_packet_size out->set_minimum_size(kClientHelloMinimumSize); // Server name indication. We only send SNI if it's a valid domain name, as @@ -958,7 +960,7 @@ QuicServerId suffix_server_id(canonical_suffixes_[i], server_id.port(), server_id.privacy_mode()); - if (!ContainsKey(canonical_server_map_, suffix_server_id)) { + if (!base::ContainsKey(canonical_server_map_, suffix_server_id)) { // This is the first host we've seen which matches the suffix, so make it // canonical. canonical_server_map_[suffix_server_id] = server_id;
diff --git a/net/quic/core/crypto/quic_crypto_client_config_test.cc b/net/quic/core/crypto/quic_crypto_client_config_test.cc index 9555dd1..36022ef20 100644 --- a/net/quic/core/crypto/quic_crypto_client_config_test.cc +++ b/net/quic/core/crypto/quic_crypto_client_config_test.cc
@@ -255,7 +255,7 @@ } TEST(QuicCryptoClientConfigTest, ProcessServerDowngradeAttack) { - QuicVersionVector supported_versions = QuicSupportedVersions(); + QuicVersionVector supported_versions = AllSupportedVersions(); if (supported_versions.size() == 1) { // No downgrade attack is possible if the client only supports one version. return; @@ -437,8 +437,8 @@ QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting()); EXPECT_EQ(QUIC_NO_ERROR, config.ProcessRejection(rej, QuicWallTime::FromUNIXSeconds(0), - QuicSupportedVersions().front(), "", - &cached, &out_params, &error)); + AllSupportedVersions().front(), "", &cached, + &out_params, &error)); EXPECT_FALSE(cached.has_server_designated_connection_id()); EXPECT_FALSE(cached.has_server_nonce()); } @@ -459,8 +459,8 @@ QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting()); EXPECT_EQ(QUIC_NO_ERROR, config.ProcessRejection(rej, QuicWallTime::FromUNIXSeconds(0), - QuicSupportedVersions().front(), "", - &cached, &out_params, &error)); + AllSupportedVersions().front(), "", &cached, + &out_params, &error)); EXPECT_TRUE(cached.has_server_designated_connection_id()); EXPECT_EQ(kConnectionId, cached.GetNextServerDesignatedConnectionId()); EXPECT_EQ(server_nonce, cached.GetNextServerNonce()); @@ -479,8 +479,8 @@ QuicCryptoClientConfig config(CryptoTestUtils::ProofVerifierForTesting()); EXPECT_EQ(QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND, config.ProcessRejection(rej, QuicWallTime::FromUNIXSeconds(0), - QuicSupportedVersions().front(), "", - &cached, &out_params, &error)); + AllSupportedVersions().front(), "", &cached, + &out_params, &error)); EXPECT_FALSE(cached.has_server_designated_connection_id()); EXPECT_EQ("Missing kRCID", error); } @@ -491,7 +491,7 @@ msg.set_tag(kSHLO); // Choose the latest version. QuicVersionVector supported_versions; - QuicVersion version = QuicSupportedVersions().front(); + QuicVersion version = AllSupportedVersions().front(); supported_versions.push_back(version); QuicTagVector versions; versions.push_back(QuicVersionToQuicTag(version));
diff --git a/net/quic/core/crypto/quic_crypto_server_config.cc b/net/quic/core/crypto/quic_crypto_server_config.cc index bb1b809..2c843a61 100644 --- a/net/quic/core/crypto/quic_crypto_server_config.cc +++ b/net/quic/core/crypto/quic_crypto_server_config.cc
@@ -567,6 +567,8 @@ QuicCompressedCertsCache* compressed_certs_cache, QuicCryptoNegotiatedParameters* params, QuicCryptoProof* crypto_proof, + QuicByteCount total_framing_overhead, + QuicByteCount chlo_packet_size, CryptoHandshakeMessage* out, DiversificationNonce* out_diversification_nonce, string* error_details) const { @@ -641,7 +643,8 @@ BuildRejection(version, *primary_config, client_hello, info, validate_chlo_result.cached_network_params, use_stateless_rejects, server_designated_connection_id, rand, - compressed_certs_cache, params, *crypto_proof, out); + compressed_certs_cache, params, *crypto_proof, + total_framing_overhead, chlo_packet_size, out); return QUIC_NO_ERROR; } @@ -1442,6 +1445,8 @@ QuicCompressedCertsCache* compressed_certs_cache, QuicCryptoNegotiatedParameters* params, const QuicCryptoProof& crypto_proof, + QuicByteCount total_framing_overhead, + QuicByteCount chlo_packet_size, CryptoHandshakeMessage* out) const { if (FLAGS_enable_quic_stateless_reject_support && use_stateless_rejects) { DVLOG(1) << "QUIC Crypto server config returning stateless reject " @@ -1486,6 +1491,7 @@ params->client_common_set_hashes, params->client_cached_cert_hashes, config.common_cert_sets); + DCHECK_GT(chlo_packet_size, client_hello.size()); // kREJOverheadBytes is a very rough estimate of how much of a REJ // message is taken up by things other than the certificates. // STK: 56 bytes @@ -1497,8 +1503,14 @@ // max_unverified_size is the number of bytes that the certificate chain, // signature, and (optionally) signed certificate timestamp can consume before // we will demand a valid source-address token. - const size_t max_unverified_size = + const size_t old_max_unverified_size = client_hello.size() * chlo_multiplier_ - kREJOverheadBytes; + const size_t new_max_unverified_size = + chlo_multiplier_ * (chlo_packet_size - total_framing_overhead) - + kREJOverheadBytes; + const size_t max_unverified_size = FLAGS_quic_use_chlo_packet_size + ? new_max_unverified_size + : old_max_unverified_size; static_assert(kClientHelloMinimumSize * kMultiplier >= kREJOverheadBytes, "overhead calculation may underflow"); bool should_return_sct = @@ -2038,7 +2050,7 @@ source_address_token_boxer(nullptr) {} QuicCryptoServerConfig::Config::~Config() { - STLDeleteElements(&key_exchanges); + base::STLDeleteElements(&key_exchanges); } QuicCryptoProof::QuicCryptoProof() {}
diff --git a/net/quic/core/crypto/quic_crypto_server_config.h b/net/quic/core/crypto/quic_crypto_server_config.h index 7203fa5..2092132 100644 --- a/net/quic/core/crypto/quic_crypto_server_config.h +++ b/net/quic/core/crypto/quic_crypto_server_config.h
@@ -279,6 +279,8 @@ // contain the state of the connection. // crypto_proof: output structure containing the crypto proof used in reply to // a proof demand. + // total_framing_overhead: the total per-packet overhead for a stream frame + // chlo_packet_size: the size, in bytes, of the CHLO packet // out: the resulting handshake message (either REJ or SHLO) // out_diversification_nonce: If the resulting handshake message is SHLO and // the version is greater than QUIC_VERSION_32 then this contains a @@ -300,6 +302,8 @@ QuicCompressedCertsCache* compressed_certs_cache, QuicCryptoNegotiatedParameters* params, QuicCryptoProof* crypto_proof, + QuicByteCount total_framing_overhead, + QuicByteCount chlo_packet_size, CryptoHandshakeMessage* out, DiversificationNonce* out_diversification_nonce, std::string* error_details) const; @@ -550,6 +554,8 @@ QuicCompressedCertsCache* compressed_certs_cache, QuicCryptoNegotiatedParameters* params, const QuicCryptoProof& crypto_proof, + QuicByteCount total_framing_overhead, + QuicByteCount chlo_packet_size, CryptoHandshakeMessage* out) const; // CompressChain compresses the certificates in |chain->certs| and returns a
diff --git a/net/quic/core/crypto/quic_crypto_server_config_test.cc b/net/quic/core/crypto/quic_crypto_server_config_test.cc index 24bbb1d..5dfc4f4 100644 --- a/net/quic/core/crypto/quic_crypto_server_config_test.cc +++ b/net/quic/core/crypto/quic_crypto_server_config_test.cc
@@ -468,7 +468,7 @@ ASSERT_EQ(!has_invalid && !is_empty, config_.SetConfigs(protobufs, clock_.WallNow())); - STLDeleteElements(&protobufs); + base::STLDeleteElements(&protobufs); } protected:
diff --git a/net/quic/core/interval_test.cc b/net/quic/core/interval_test.cc index 055caf9..cc2e6c79 100644 --- a/net/quic/core/interval_test.cc +++ b/net/quic/core/interval_test.cc
@@ -211,7 +211,7 @@ EXPECT_EQ(1u, diff.size()); EXPECT_EQ(100u, diff[0]->min()); EXPECT_EQ(200u, diff[0]->max()); - STLDeleteElements(&diff); + base::STLDeleteElements(&diff); EXPECT_TRUE(!empty.Difference(d, &diff) && diff.empty()); EXPECT_TRUE(d.Difference(d, &diff) && diff.empty()); @@ -219,7 +219,7 @@ EXPECT_EQ(1u, diff.size()); EXPECT_EQ(100u, diff[0]->min()); EXPECT_EQ(200u, diff[0]->max()); - STLDeleteElements(&diff); + base::STLDeleteElements(&diff); Interval<int64_t> lo; Interval<int64_t> hi; @@ -232,7 +232,7 @@ EXPECT_EQ(1u, diff.size()); EXPECT_EQ(110u, diff[0]->min()); EXPECT_EQ(200u, diff[0]->max()); - STLDeleteElements(&diff); + base::STLDeleteElements(&diff); EXPECT_TRUE(d.Difference(d3, &lo, &hi)); EXPECT_EQ(100u, lo.min()); @@ -245,7 +245,7 @@ EXPECT_EQ(110u, diff[0]->max()); EXPECT_EQ(180u, diff[1]->min()); EXPECT_EQ(200u, diff[1]->max()); - STLDeleteElements(&diff); + base::STLDeleteElements(&diff); EXPECT_TRUE(d.Difference(d4, &lo, &hi)); EXPECT_EQ(100u, lo.min()); @@ -255,7 +255,7 @@ EXPECT_EQ(1u, diff.size()); EXPECT_EQ(100u, diff[0]->min()); EXPECT_EQ(180u, diff[0]->max()); - STLDeleteElements(&diff); + base::STLDeleteElements(&diff); EXPECT_FALSE(d.Difference(d5, &lo, &hi)); EXPECT_EQ(100u, lo.min()); @@ -265,7 +265,7 @@ EXPECT_EQ(1u, diff.size()); EXPECT_EQ(100u, diff[0]->min()); EXPECT_EQ(200u, diff[0]->max()); - STLDeleteElements(&diff); + base::STLDeleteElements(&diff); EXPECT_TRUE(d.Difference(d6, &lo, &hi)); EXPECT_TRUE(lo.Empty()); @@ -275,7 +275,7 @@ EXPECT_EQ(1u, diff.size()); EXPECT_EQ(150u, diff[0]->min()); EXPECT_EQ(200u, diff[0]->max()); - STLDeleteElements(&diff); + base::STLDeleteElements(&diff); EXPECT_TRUE(d.Difference(d7, &lo, &hi)); EXPECT_EQ(100u, lo.min()); @@ -285,7 +285,7 @@ EXPECT_EQ(1u, diff.size()); EXPECT_EQ(100u, diff[0]->min()); EXPECT_EQ(150u, diff[0]->max()); - STLDeleteElements(&diff); + base::STLDeleteElements(&diff); EXPECT_TRUE(d.Difference(d8, &lo, &hi)); EXPECT_TRUE(lo.Empty());
diff --git a/net/quic/core/quic_buffered_packet_store.cc b/net/quic/core/quic_buffered_packet_store.cc index db9e29d9..823a9ae 100644 --- a/net/quic/core/quic_buffered_packet_store.cc +++ b/net/quic/core/quic_buffered_packet_store.cc
@@ -79,15 +79,15 @@ const QuicReceivedPacket& packet, IPEndPoint server_address, IPEndPoint client_address) { - if (!ContainsKey(undecryptable_packets_, connection_id) && + if (!base::ContainsKey(undecryptable_packets_, connection_id) && undecryptable_packets_.size() >= kDefaultMaxConnectionsInStore) { // Drop the packet if store can't keep track of more connections. return TOO_MANY_CONNECTIONS; - } else if (!ContainsKey(undecryptable_packets_, connection_id)) { + } else if (!base::ContainsKey(undecryptable_packets_, connection_id)) { undecryptable_packets_.emplace( std::make_pair(connection_id, BufferedPacketList())); } - CHECK(ContainsKey(undecryptable_packets_, connection_id)); + CHECK(base::ContainsKey(undecryptable_packets_, connection_id)); BufferedPacketList& queue = undecryptable_packets_.find(connection_id)->second; @@ -116,7 +116,7 @@ bool QuicBufferedPacketStore::HasBufferedPackets( QuicConnectionId connection_id) const { - return ContainsKey(undecryptable_packets_, connection_id); + return base::ContainsKey(undecryptable_packets_, connection_id); } list<BufferedPacket> QuicBufferedPacketStore::DeliverPackets(
diff --git a/net/quic/core/quic_buffered_packet_store_test.cc b/net/quic/core/quic_buffered_packet_store_test.cc index 3d08db4..2ea70ac 100644 --- a/net/quic/core/quic_buffered_packet_store_test.cc +++ b/net/quic/core/quic_buffered_packet_store_test.cc
@@ -9,6 +9,7 @@ #include "base/stl_util.h" #include "net/quic/test_tools/mock_clock.h" +#include "net/quic/test_tools/quic_buffered_packet_store_peer.h" #include "net/quic/test_tools/quic_test_utils.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -24,13 +25,6 @@ static const size_t kDefaultMaxConnectionsInStore = 100; namespace test { -class QuicBufferedPacketStorePeer { - public: - static QuicAlarm* expiration_alarm(QuicBufferedPacketStore* store) { - return store->expiration_alarm_.get(); - } -}; - namespace { typedef QuicBufferedPacketStore::BufferedPacket BufferedPacket;
diff --git a/net/quic/core/quic_client_session_base.cc b/net/quic/core/quic_client_session_base.cc index 58bd2da..2d3bb29 100644 --- a/net/quic/core/quic_client_session_base.cc +++ b/net/quic/core/quic_client_session_base.cc
@@ -27,6 +27,7 @@ DVLOG(1) << "erase stream " << it.first << " url " << it.second->url(); push_promise_index_->promised_by_url()->erase(it.second->url()); } + delete connection(); } void QuicClientSessionBase::OnConfigNegotiated() {
diff --git a/net/quic/core/quic_client_session_base.h b/net/quic/core/quic_client_session_base.h index 948f65a..0fcf887 100644 --- a/net/quic/core/quic_client_session_base.h +++ b/net/quic/core/quic_client_session_base.h
@@ -35,7 +35,8 @@ : public QuicSpdySession, public QuicCryptoClientStream::ProofHandler { public: - // Caller retains ownership of |promised_by_url|. + // Takes ownership of |connection|. Caller retains ownership of + // |promised_by_url|. QuicClientSessionBase(QuicConnection* connection, QuicClientPushPromiseIndex* push_promise_index, const QuicConfig& config);
diff --git a/net/quic/core/quic_config.cc b/net/quic/core/quic_config.cc index 1764b2d..3697a97d 100644 --- a/net/quic/core/quic_config.cc +++ b/net/quic/core/quic_config.cc
@@ -694,6 +694,7 @@ connection_migration_disabled_.ToHandshakeMessage(out); connection_options_.ToHandshakeMessage(out); alternate_server_address_.ToHandshakeMessage(out); + force_hol_blocking_.ToHandshakeMessage(out); } QuicErrorCode QuicConfig::ProcessPeerHello( @@ -751,6 +752,10 @@ error = alternate_server_address_.ProcessPeerHello(peer_hello, hello_type, error_details); } + if (error == QUIC_NO_ERROR) { + error = force_hol_blocking_.ProcessPeerHello(peer_hello, hello_type, + error_details); + } return error; }
diff --git a/net/quic/core/quic_config_test.cc b/net/quic/core/quic_config_test.cc index 3c554b5..adac1600 100644 --- a/net/quic/core/quic_config_test.cc +++ b/net/quic/core/quic_config_test.cc
@@ -75,6 +75,7 @@ client_config.SetInitialSessionFlowControlWindowToSend( 2 * kInitialSessionFlowControlWindowForTest); client_config.SetSocketReceiveBufferToSend(kDefaultSocketReceiveBuffer); + client_config.SetForceHolBlocking(); QuicTagVector copt; copt.push_back(kTBBR); client_config.SetConnectionOptionsToSend(copt); @@ -100,6 +101,7 @@ config_.IdleConnectionStateLifetime()); EXPECT_EQ(kDefaultMaxStreamsPerConnection, config_.MaxStreamsPerConnection()); EXPECT_EQ(10 * kNumMicrosPerMilli, config_.ReceivedInitialRoundTripTimeUs()); + EXPECT_TRUE(config_.ForceHolBlocking(Perspective::IS_SERVER)); EXPECT_TRUE(config_.HasReceivedConnectionOptions()); EXPECT_EQ(2u, config_.ReceivedConnectionOptions().size()); EXPECT_EQ(config_.ReceivedConnectionOptions()[0], kIW50);
diff --git a/net/quic/core/quic_connection.cc b/net/quic/core/quic_connection.cc index 7d23d90..bb7170d 100644 --- a/net/quic/core/quic_connection.cc +++ b/net/quic/core/quic_connection.cc
@@ -338,7 +338,7 @@ if (owns_writer_) { delete writer_; } - STLDeleteElements(&undecryptable_packets_); + base::STLDeleteElements(&undecryptable_packets_); ClearQueuedPackets(); } @@ -443,7 +443,7 @@ const QuicVersionVector& supported_versions = framer_.supported_versions(); for (size_t i = 0; i < supported_versions.size(); ++i) { const QuicVersion& version = supported_versions[i]; - if (ContainsValue(available_versions, version)) { + if (base::ContainsValue(available_versions, version)) { framer_.set_version(version); return true; } @@ -562,7 +562,7 @@ return; } - if (ContainsValue(packet.versions, version())) { + if (base::ContainsValue(packet.versions, version())) { const string error_details = "Server already supports client's version and should have accepted the " "connection."; @@ -690,8 +690,7 @@ // packet. if (active_peer_migration_type_ == NO_CHANGE && peer_migration_type != NO_CHANGE && - (!FLAGS_quic_do_not_migrate_on_old_packet || - header.packet_number > received_packet_manager_.GetLargestObserved())) { + header.packet_number > received_packet_manager_.GetLargestObserved()) { StartPeerMigration(header.path_id, peer_migration_type); } @@ -1168,7 +1167,6 @@ } void QuicConnection::SendVersionNegotiationPacket() { - // TODO(alyssar): implement zero server state negotiation. pending_version_negotiation_packet_ = true; if (writer_->IsWriteBlocked()) { visitor_->OnWriteBlocked(); @@ -1711,9 +1709,17 @@ if (FLAGS_quic_simple_packet_number_length) { // The packet number length must be updated after OnPacketSent, because it // may change the packet number length in packet. - packet_generator_.UpdateSequenceNumberLength( - sent_packet_manager_->GetLeastPacketAwaitedByPeer(packet->path_id), - sent_packet_manager_->EstimateMaxPacketsInFlight(max_packet_length())); + if (FLAGS_quic_least_unacked_packet_number_length) { + packet_generator_.UpdateSequenceNumberLength( + sent_packet_manager_->GetLeastUnacked(packet->path_id), + sent_packet_manager_->EstimateMaxPacketsInFlight( + max_packet_length())); + } else { + packet_generator_.UpdateSequenceNumberLength( + sent_packet_manager_->GetLeastPacketAwaitedByPeer(packet->path_id), + sent_packet_manager_->EstimateMaxPacketsInFlight( + max_packet_length())); + } } stats_.bytes_sent += result.bytes_written; @@ -2016,7 +2022,7 @@ debug_visitor_->OnUndecryptablePacket(); } } - STLDeleteElements(&undecryptable_packets_); + base::STLDeleteElements(&undecryptable_packets_); } } @@ -2307,6 +2313,28 @@ if (!already_in_batch_mode_) { DVLOG(2) << "Leaving Batch Mode."; connection_->packet_generator_.FinishBatchOperations(); + + // Once all transmissions are done, check if there is any outstanding data + // to send and notify the congestion controller if not. + // + // Note that this means that the application limited check will happen as + // soon as the last bundler gets destroyed, which is typically after a + // single stream write is finished. This means that if all the data from a + // single write goes through the connection, the application-limited signal + // will fire even if the caller does a write operation immediately after. + // There are two important approaches to remedy this situation: + // (1) Instantiate ScopedPacketBundler before performing multiple subsequent + // writes, thus deferring this check until all writes are done. + // (2) Write data in chunks sufficiently large so that they cause the + // connection to be limited by the congestion control. Typically, this + // would mean writing chunks larger than the product of the current + // pacing rate and the pacer granularity. So, for instance, if the + // pacing rate of the connection is 1 Gbps, and the pacer granularity is + // 1 ms, the caller should send at least 125k bytes in order to not + // be marked as application-limited. + if (FLAGS_quic_enable_app_limited_check) { + connection_->CheckIfApplicationLimited(); + } } DCHECK_EQ(already_in_batch_mode_, connection_->packet_generator_.InBatchMode()); @@ -2523,4 +2551,12 @@ min(kMaxDelayedAckTimeMs, kMinRetransmissionTimeMs / 2)); } +void QuicConnection::CheckIfApplicationLimited() { + if (queued_packets_.empty() && + !sent_packet_manager_->HasPendingRetransmissions() && + !visitor_->WillingAndAbleToWrite()) { + sent_packet_manager_->OnApplicationLimited(); + } +} + } // namespace net
diff --git a/net/quic/core/quic_connection.h b/net/quic/core/quic_connection.h index a18b87a..dc0701f 100644 --- a/net/quic/core/quic_connection.h +++ b/net/quic/core/quic_connection.h
@@ -851,6 +851,10 @@ const QuicTime::Delta DelayedAckTime(); + // Check if the connection has no outstanding data to send and notify + // congestion controller if it is the case. + void CheckIfApplicationLimited(); + QuicFramer framer_; QuicConnectionHelperInterface* helper_; // Not owned. QuicAlarmFactory* alarm_factory_; // Not owned.
diff --git a/net/quic/core/quic_connection_test.cc b/net/quic/core/quic_connection_test.cc index fbeae11..e63abd80 100644 --- a/net/quic/core/quic_connection_test.cc +++ b/net/quic/core/quic_connection_test.cc
@@ -662,7 +662,7 @@ // Constructs various test permutations. vector<TestParams> GetTestParams() { vector<TestParams> params; - QuicVersionVector all_supported_versions = QuicSupportedVersions(); + QuicVersionVector all_supported_versions = AllSupportedVersions(); for (size_t i = 0; i < all_supported_versions.size(); ++i) { for (AckResponse ack_response : {AckResponse::kDefer, AckResponse::kImmediate}) { @@ -712,7 +712,7 @@ FLAGS_quic_always_log_bugs_for_tests = true; connection_.set_visitor(&visitor_); connection_.SetSendAlgorithm(kDefaultPathId, send_algorithm_); - connection_.SetLossAlgorithm(kDefaultPathId, loss_algorithm_); + connection_.SetLossAlgorithm(kDefaultPathId, loss_algorithm_.get()); framer_.set_received_entropy_calculator(&entropy_calculator_); peer_framer_.set_received_entropy_calculator(&peer_entropy_calculator_); EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _)) @@ -734,6 +734,7 @@ .WillRepeatedly(Return(QuicBandwidth::Zero())); EXPECT_CALL(*send_algorithm_, InSlowStart()).Times(AnyNumber()); EXPECT_CALL(*send_algorithm_, InRecovery()).Times(AnyNumber()); + EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(AnyNumber()); EXPECT_CALL(visitor_, WillingAndAbleToWrite()).Times(AnyNumber()); EXPECT_CALL(visitor_, HasPendingHandshake()).Times(AnyNumber()); EXPECT_CALL(visitor_, OnCanWrite()).Times(AnyNumber()); @@ -1068,7 +1069,7 @@ MockEntropyCalculator peer_entropy_calculator_; MockSendAlgorithm* send_algorithm_; - MockLossAlgorithm* loss_algorithm_; + std::unique_ptr<MockLossAlgorithm> loss_algorithm_; MockClock clock_; MockRandom random_generator_; SimpleBufferAllocator buffer_allocator_; @@ -1155,13 +1156,8 @@ // Decrease packet number to simulate out-of-order packets. QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 4); - if (FLAGS_quic_do_not_migrate_on_old_packet) { - // This is an old packet, do not migrate. - EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0); - } else { - // A connection migration is observed. - EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)); - } + // This is an old packet, do not migrate. + EXPECT_CALL(visitor_, OnConnectionMigration(PORT_CHANGE)).Times(0); ProcessFramePacketWithAddresses(QuicFrame(&stream_frame), kSelfAddress, kPeerAddress); } @@ -1949,7 +1945,13 @@ &connection_, &TestConnection::SendStreamData3)), IgnoreResult(InvokeWithoutArgs( &connection_, &TestConnection::SendStreamData5)))); - EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillOnce(Return(true)); + { + InSequence seq; + EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillOnce(Return(true)); + EXPECT_CALL(visitor_, WillingAndAbleToWrite()) + .WillRepeatedly(Return(false)); + } + EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _)) .WillRepeatedly(testing::Return(QuicTime::Delta::Zero())); @@ -4272,7 +4274,7 @@ } TEST_P(QuicConnectionTest, ServerSendsVersionNegotiationPacket) { - connection_.SetSupportedVersions(QuicSupportedVersions()); + connection_.SetSupportedVersions(AllSupportedVersions()); set_perspective(Perspective::IS_SERVER); peer_framer_.set_version_for_tests(QUIC_VERSION_UNSUPPORTED); @@ -4308,7 +4310,7 @@ } TEST_P(QuicConnectionTest, ServerSendsVersionNegotiationPacketSocketBlocked) { - connection_.SetSupportedVersions(QuicSupportedVersions()); + connection_.SetSupportedVersions(AllSupportedVersions()); set_perspective(Perspective::IS_SERVER); peer_framer_.set_version_for_tests(QUIC_VERSION_UNSUPPORTED); @@ -4350,7 +4352,7 @@ TEST_P(QuicConnectionTest, ServerSendsVersionNegotiationPacketSocketBlockedDataBuffered) { - connection_.SetSupportedVersions(QuicSupportedVersions()); + connection_.SetSupportedVersions(AllSupportedVersions()); set_perspective(Perspective::IS_SERVER); peer_framer_.set_version_for_tests(QUIC_VERSION_UNSUPPORTED); @@ -4385,7 +4387,7 @@ // Send a version negotiation packet. std::unique_ptr<QuicEncryptedPacket> encrypted( framer_.BuildVersionNegotiationPacket(connection_id_, - QuicSupportedVersions())); + AllSupportedVersions())); std::unique_ptr<QuicReceivedPacket> received( ConstructReceivedPacket(*encrypted, QuicTime::Zero())); connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received); @@ -4421,7 +4423,7 @@ ConnectionCloseSource::FROM_SELF)); std::unique_ptr<QuicEncryptedPacket> encrypted( framer_.BuildVersionNegotiationPacket(connection_id_, - QuicSupportedVersions())); + AllSupportedVersions())); std::unique_ptr<QuicReceivedPacket> received( ConstructReceivedPacket(*encrypted, QuicTime::Zero())); connection_.ProcessUdpPacket(kSelfAddress, kPeerAddress, *received); @@ -4504,7 +4506,7 @@ } TEST_P(QuicConnectionTest, SelectMutualVersion) { - connection_.SetSupportedVersions(QuicSupportedVersions()); + connection_.SetSupportedVersions(AllSupportedVersions()); // Set the connection to speak the lowest quic version. connection_.set_version(QuicVersionMin()); EXPECT_EQ(QuicVersionMin(), connection_.version()); @@ -4990,6 +4992,52 @@ connection_.SendStreamDataWithString(3, "foo", 0, !kFin, nullptr); } +// Verify that if connection has no outstanding data, it notifies the send +// algorithm after the write. +TEST_P(QuicConnectionTest, SendDataAndBecomeApplicationLimited) { + FLAGS_quic_enable_app_limited_check = true; + + EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(1); + { + InSequence seq; + EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true)); + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) + .WillOnce(Return(true)); + EXPECT_CALL(visitor_, WillingAndAbleToWrite()) + .WillRepeatedly(Return(false)); + } + + connection_.SendStreamData3(); +} + +// Verify that the connection does not become app-limited if there is +// outstanding data to send after the write. +TEST_P(QuicConnectionTest, NotBecomeApplicationLimitedIfMoreDataAvailable) { + FLAGS_quic_enable_app_limited_check = true; + + EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(0); + { + InSequence seq; + EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)) + .WillOnce(Return(true)); + EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true)); + } + + connection_.SendStreamData3(); +} + +// Verify that the connection does not become app-limited after blocked write +// even if there is outstanding data to send after the write. +TEST_P(QuicConnectionTest, NotBecomeApplicationLimitedDueToWriteBlock) { + FLAGS_quic_enable_app_limited_check = true; + + EXPECT_CALL(*send_algorithm_, OnApplicationLimited(_)).Times(0); + EXPECT_CALL(visitor_, WillingAndAbleToWrite()).WillRepeatedly(Return(true)); + BlockOnNextWrite(); + + connection_.SendStreamData3(); +} + } // namespace } // namespace test } // namespace net
diff --git a/net/quic/core/quic_crypto_client_stream.cc b/net/quic/core/quic_crypto_client_stream.cc index a0e2afa..3157411 100644 --- a/net/quic/core/quic_crypto_client_stream.cc +++ b/net/quic/core/quic_crypto_client_stream.cc
@@ -342,6 +342,8 @@ CloseConnectionWithDetails(QUIC_INTERNAL_ERROR, "CHLO too large"); return; } + // TODO(rch): Remove this when we remove: + // FLAGS_quic_use_chlo_packet_size out.set_minimum_size( static_cast<size_t>(max_packet_size - kFramingOverhead)); next_state_ = STATE_RECV_REJ;
diff --git a/net/quic/core/quic_crypto_client_stream_test.cc b/net/quic/core/quic_crypto_client_stream_test.cc index 7952702..f8d2216 100644 --- a/net/quic/core/quic_crypto_client_stream_test.cc +++ b/net/quic/core/quic_crypto_client_stream_test.cc
@@ -274,7 +274,7 @@ CreateClientSessionForTest(server_id_, /* supports_stateless_rejects= */ true, QuicTime::Delta::FromSeconds(100000), - QuicSupportedVersions(), &helper_, + AllSupportedVersions(), &helper_, &alarm_factory_, &client_crypto_config_, &client_connection_, &client_session); CHECK(client_session); @@ -296,7 +296,7 @@ void InitializeFakeStatelessRejectServer() { TestQuicSpdyServerSession* server_session = nullptr; CreateServerSessionForTest(server_id_, QuicTime::Delta::FromSeconds(100000), - QuicSupportedVersions(), &helper_, + AllSupportedVersions(), &helper_, &alarm_factory_, &server_crypto_config_, &server_compressed_certs_cache_, &server_connection_, &server_session);
diff --git a/net/quic/core/quic_crypto_server_stream.cc b/net/quic/core/quic_crypto_server_stream.cc index 37d68ad..10c19e2 100644 --- a/net/quic/core/quic_crypto_server_stream.cc +++ b/net/quic/core/quic_crypto_server_stream.cc
@@ -80,7 +80,8 @@ num_server_config_update_messages_sent_(0), use_stateless_rejects_if_peer_supported_( use_stateless_rejects_if_peer_supported), - peer_supports_stateless_rejects_(false) { + peer_supports_stateless_rejects_(false), + chlo_packet_size_(0) { DCHECK_EQ(Perspective::IS_SERVER, session->connection()->perspective()); } @@ -104,6 +105,7 @@ const CryptoHandshakeMessage& message) { QuicCryptoServerStreamBase::OnHandshakeMessage(message); ++num_handshake_messages_; + chlo_packet_size_ = session()->connection()->GetCurrentPacket().length(); bool require_kfixd = !FLAGS_quic_deprecate_kfixd; @@ -439,7 +441,8 @@ use_stateless_rejects_in_crypto_config, server_designated_connection_id, connection->clock(), connection->random_generator(), compressed_certs_cache_, &crypto_negotiated_params_, &crypto_proof_, - reply, out_diversification_nonce, error_details); + QuicCryptoStream::CryptoMessageFramingOverhead(version()), + chlo_packet_size_, reply, out_diversification_nonce, error_details); } void QuicCryptoServerStream::OverrideQuicConfigDefaults(QuicConfig* config) {}
diff --git a/net/quic/core/quic_crypto_server_stream.h b/net/quic/core/quic_crypto_server_stream.h index 92cf176..a48f6b6 100644 --- a/net/quic/core/quic_crypto_server_stream.h +++ b/net/quic/core/quic_crypto_server_stream.h
@@ -230,6 +230,9 @@ // becomes the default. bool peer_supports_stateless_rejects_; + // Size of the packet containing the most recently received CHLO. + QuicByteCount chlo_packet_size_; + DISALLOW_COPY_AND_ASSIGN(QuicCryptoServerStream); };
diff --git a/net/quic/core/quic_crypto_server_stream_test.cc b/net/quic/core/quic_crypto_server_stream_test.cc index 2a702397..c7576e1 100644 --- a/net/quic/core/quic_crypto_server_stream_test.cc +++ b/net/quic/core/quic_crypto_server_stream_test.cc
@@ -91,8 +91,8 @@ // |helpers_| is destroyed. server_session_.reset(); client_session_.reset(); - STLDeleteElements(&helpers_); - STLDeleteElements(&alarm_factories_); + base::STLDeleteElements(&helpers_); + base::STLDeleteElements(&alarm_factories_); } // Initializes the crypto server stream state for testing. May be @@ -197,7 +197,7 @@ DelayedVerifyStrikeRegisterClient* strike_register_client_; // Which QUIC versions the client and server support. - QuicVersionVector supported_versions_ = QuicSupportedVersions(); + QuicVersionVector supported_versions_ = AllSupportedVersions(); }; INSTANTIATE_TEST_CASE_P(Tests, QuicCryptoServerStreamTest, testing::Bool());
diff --git a/net/quic/core/quic_crypto_stream.cc b/net/quic/core/quic_crypto_stream.cc index cffd838..879834d3 100644 --- a/net/quic/core/quic_crypto_stream.cc +++ b/net/quic/core/quic_crypto_stream.cc
@@ -33,6 +33,17 @@ DisableConnectionFlowControlForThisStream(); } +// static +QuicByteCount QuicCryptoStream::CryptoMessageFramingOverhead( + QuicVersion version) { + return QuicPacketCreator::StreamFramePacketOverhead( + version, PACKET_8BYTE_CONNECTION_ID, + /*include_version=*/true, + /*include_path_id=*/true, + /*include_diversification_nonce=*/true, PACKET_1BYTE_PACKET_NUMBER, + /*offset=*/0); +} + void QuicCryptoStream::OnError(CryptoFramer* framer) { DLOG(WARNING) << "Error processing crypto data: " << QuicUtils::ErrorToString(framer->error());
diff --git a/net/quic/core/quic_crypto_stream.h b/net/quic/core/quic_crypto_stream.h index e048cb0..225324f5 100644 --- a/net/quic/core/quic_crypto_stream.h +++ b/net/quic/core/quic_crypto_stream.h
@@ -35,6 +35,10 @@ public: explicit QuicCryptoStream(QuicSession* session); + // Returns the per-packet framing overhead associated with sending a + // handshake message for |version|. + static QuicByteCount CryptoMessageFramingOverhead(QuicVersion version); + // CryptoFramerVisitorInterface implementation void OnError(CryptoFramer* framer) override; void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
diff --git a/net/quic/core/quic_end_to_end_unittest.cc b/net/quic/core/quic_end_to_end_unittest.cc index a2df10d..79e1c26 100644 --- a/net/quic/core/quic_end_to_end_unittest.cc +++ b/net/quic/core/quic_end_to_end_unittest.cc
@@ -187,7 +187,7 @@ server_config_options_.token_binding_enabled = true; QuicServer* server = new QuicServer(CryptoTestUtils::ProofSourceForTesting(), server_config_, - server_config_options_, QuicSupportedVersions()); + server_config_options_, AllSupportedVersions()); server_thread_.reset(new ServerThread(server, server_address_, strike_register_no_startup_period_)); server_thread_->Initialize(); @@ -384,7 +384,7 @@ for (size_t i = 0; i < num_requests; ++i) { CheckResponse(*consumers[i], "HTTP/1.1 200", kResponseBody); } - STLDeleteElements(&consumers); + base::STLDeleteElements(&consumers); } } // namespace test
diff --git a/net/quic/core/quic_flags.cc b/net/quic/core/quic_flags.cc index 5b7e208..ab5ceb8 100644 --- a/net/quic/core/quic_flags.cc +++ b/net/quic/core/quic_flags.cc
@@ -79,10 +79,6 @@ // connection. bool FLAGS_quic_use_cheap_stateless_rejects = false; -// If true, treat timestamps from SO_TIMESTAMPING as QuicWallTimes rather -// than QuicTimes. -bool FLAGS_quic_socket_walltimestamps = true; - // If true, QUIC respect HTTP2 SETTINGS frame rather than always close the // connection. bool FLAGS_quic_respect_http2_settings_frame = true; @@ -97,25 +93,24 @@ // If true, enables QUIC_VERSION_35. bool FLAGS_quic_enable_version_35 = true; -// If true, enables QUIC_VERSION_36. +// If true, re-enables QUIC_VERSION_36. bool FLAGS_quic_enable_version_36 = true; +// If true, enables QUIC_VERSION_36. +bool FLAGS_quic_enable_version_36_v2 = false; + // If true, requires support for X509 certificates in QUIC CHLO PDMDs. bool FLAGS_quic_require_x509 = true; // If true, deprecate safeguards for b/26023400. -bool FLAGS_quic_deprecate_kfixd = false; - -// If true, a connection does not migrate on an old packet even the peer address -// changes. -bool FLAGS_quic_do_not_migrate_on_old_packet = true; +bool FLAGS_quic_deprecate_kfixd = true; // If true, use async codepaths to invoke ProofSource::GetProof. bool FLAGS_enable_async_get_proof = false; // If true, neuter null encrypted packets before sending the next handshake // message. -bool FLAGS_quic_neuter_unencrypted_when_sending = false; +bool FLAGS_quic_neuter_unencrypted_when_sending = true; // If true, QuicAlarm::Update will call a faster UpdateImpl implementation // instead of canceling and reregistering the alarm. @@ -127,8 +122,10 @@ // If true, use the interval form of iteration over a PacketNumberQueue instead // of iterating over the individual numbers. -bool FLAGS_quic_use_packet_number_queue_intervals = false; +bool FLAGS_quic_use_packet_number_queue_intervals = true; +// If true, fix a bug with which QuicStreamSequencerBuffer can\'t release block +// memory in time. bool FLAGS_quic_sequencer_buffer_retire_block_in_time = true; // Remove obsolete code to force QUIC to go forward secure, now that the server @@ -151,6 +148,17 @@ // gaps in QuicStreamSequenceBuffer exceeds allowed limit. bool FLAGS_quic_limit_frame_gaps_in_buffer = false; -// If true, QuicSentPacketManager will use inline pacing functionality instead -// of wrapping the SendAlgorithm with a PacingSender. -bool FLAGS_quic_use_inline_pacing = false; +// If true, v33 QUIC client uses 1 bit to specify 8-byte connection id in public +// flag. +bool FLAGS_quic_remove_v33_hacks = true; + +// If true, use the CHLO packet size, not message size when determining how +// large a REJ can be. +bool FLAGS_quic_use_chlo_packet_size = false; + +// If true, defer creation of new connection till its CHLO arrives. +bool FLAGS_quic_buffer_packet_till_chlo = false; + +// If true, the connection will check whether it is application-limited, and +// notify the congestion controller about it. +bool FLAGS_quic_enable_app_limited_check = true;
diff --git a/net/quic/core/quic_flags.h b/net/quic/core/quic_flags.h index 6cd8c3e..b3f4869 100644 --- a/net/quic/core/quic_flags.h +++ b/net/quic/core/quic_flags.h
@@ -27,15 +27,14 @@ NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_old_public_reset_packets; NET_EXPORT_PRIVATE extern bool FLAGS_quic_rate_based_sending; NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_cheap_stateless_rejects; -NET_EXPORT_PRIVATE extern bool FLAGS_quic_socket_walltimestamps; NET_EXPORT_PRIVATE extern bool FLAGS_quic_respect_http2_settings_frame; NET_EXPORT_PRIVATE extern bool FLAGS_quic_no_mtu_discovery_ack_listener; NET_EXPORT_PRIVATE extern bool FLAGS_quic_simple_packet_number_length; NET_EXPORT_PRIVATE extern bool FLAGS_quic_enable_version_35; NET_EXPORT_PRIVATE extern bool FLAGS_quic_enable_version_36; +NET_EXPORT_PRIVATE extern bool FLAGS_quic_enable_version_36_v2; NET_EXPORT_PRIVATE extern bool FLAGS_quic_require_x509; NET_EXPORT_PRIVATE extern bool FLAGS_quic_deprecate_kfixd; -NET_EXPORT_PRIVATE extern bool FLAGS_quic_do_not_migrate_on_old_packet; NET_EXPORT_PRIVATE extern bool FLAGS_enable_async_get_proof; NET_EXPORT_PRIVATE extern bool FLAGS_quic_neuter_unencrypted_when_sending; NET_EXPORT_PRIVATE extern bool FLAGS_quic_change_alarms_efficiently; @@ -48,6 +47,9 @@ NET_EXPORT_PRIVATE extern bool FLAGS_quic_close_stream_after_writing_queued_data; NET_EXPORT_PRIVATE extern bool FLAGS_quic_limit_frame_gaps_in_buffer; -NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_inline_pacing; +NET_EXPORT_PRIVATE extern bool FLAGS_quic_remove_v33_hacks; +NET_EXPORT_PRIVATE extern bool FLAGS_quic_use_chlo_packet_size; +NET_EXPORT_PRIVATE extern bool FLAGS_quic_buffer_packet_till_chlo; +NET_EXPORT_PRIVATE extern bool FLAGS_quic_enable_app_limited_check; #endif // NET_QUIC_QUIC_FLAGS_H_
diff --git a/net/quic/core/quic_framer.cc b/net/quic/core/quic_framer.cc index 1dad357..ad8144df 100644 --- a/net/quic/core/quic_framer.cc +++ b/net/quic/core/quic_framer.cc
@@ -721,8 +721,8 @@ case PACKET_8BYTE_CONNECTION_ID: if (quic_version_ > QUIC_VERSION_32) { public_flags |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID; - if (perspective_ == Perspective::IS_CLIENT) { - // TODO(rch): Fix this when v33 flags are supported by middle boxes. + if (!FLAGS_quic_remove_v33_hacks && + perspective_ == Perspective::IS_CLIENT) { public_flags |= PACKET_PUBLIC_FLAGS_8BYTE_CONNECTION_ID_OLD; } @@ -800,7 +800,7 @@ bool QuicFramer::IsValidPath(QuicPathId path_id, QuicPacketNumber* last_packet_number) { - if (ContainsKey(closed_paths_, path_id)) { + if (base::ContainsKey(closed_paths_, path_id)) { // Path is closed. return false; } @@ -810,7 +810,7 @@ return true; } - if (ContainsKey(last_packet_numbers_, path_id)) { + if (base::ContainsKey(last_packet_numbers_, path_id)) { *last_packet_number = last_packet_numbers_[path_id]; } else { *last_packet_number = 0;
diff --git a/net/quic/core/quic_framer_test.cc b/net/quic/core/quic_framer_test.cc index 205ea06b1..922ed4ca 100644 --- a/net/quic/core/quic_framer_test.cc +++ b/net/quic/core/quic_framer_test.cc
@@ -199,12 +199,12 @@ accept_public_header_(true) {} ~TestQuicVisitor() override { - STLDeleteElements(&stream_frames_); - STLDeleteElements(&ack_frames_); - STLDeleteElements(&stop_waiting_frames_); - STLDeleteElements(&padding_frames_); - STLDeleteElements(&ping_frames_); - STLDeleteElements(&stream_data_); + base::STLDeleteElements(&stream_frames_); + base::STLDeleteElements(&ack_frames_); + base::STLDeleteElements(&stop_waiting_frames_); + base::STLDeleteElements(&padding_frames_); + base::STLDeleteElements(&ping_frames_); + base::STLDeleteElements(&stream_data_); } void OnError(QuicFramer* f) override { @@ -352,7 +352,7 @@ : encrypter_(new test::TestEncrypter()), decrypter_(new test::TestDecrypter()), start_(QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(0x10)), - framer_(QuicSupportedVersions(), start_, Perspective::IS_SERVER) { + framer_(AllSupportedVersions(), start_, Perspective::IS_SERVER) { version_ = GetParam(); framer_.set_version(version_); framer_.SetDecrypter(ENCRYPTION_NONE, decrypter_); @@ -4824,7 +4824,8 @@ unsigned char packet[] = { // public flags (version, 8 byte connection_id) static_cast<unsigned char>( - framer_.version() > QUIC_VERSION_32 ? 0x3D : 0x3D), + (FLAGS_quic_remove_v33_hacks && + framer_.version() > QUIC_VERSION_32) ? 0x39 : 0x3D), // connection_id 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, // version tag @@ -4845,7 +4846,8 @@ }; unsigned char packet_34[] = { // public flags (version, 8 byte connection_id) - 0x3D, + static_cast<unsigned char>( + FLAGS_quic_remove_v33_hacks ? 0x39 : 0x3D), // connection_id 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, // version tag @@ -4977,7 +4979,8 @@ unsigned char packet[] = { // public flags (8 byte connection_id) static_cast<unsigned char>( - framer_.version() > QUIC_VERSION_32 ? 0x7D : 0x7D), + (FLAGS_quic_remove_v33_hacks && + framer_.version() > QUIC_VERSION_32) ? 0x79 : 0x7D), // connection_id 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, @@ -5005,7 +5008,8 @@ }; unsigned char packet_34[] = { // public flags (8 byte connection_id) - 0x7D, + static_cast<unsigned char>( + FLAGS_quic_remove_v33_hacks ? 0x79 : 0x7D), // connection_id 0x10, 0x32, 0x54, 0x76, 0x98, 0xBA, 0xDC, 0xFE, @@ -7135,7 +7139,7 @@ // target function to be fuzzed by Dr. Fuzz void QuicFramerFuzzFunc(unsigned char* data, size_t size) { - QuicFramer framer(QuicSupportedVersions(), QuicTime::Zero(), + QuicFramer framer(AllSupportedVersions(), QuicTime::Zero(), Perspective::IS_SERVER); const char* const packet_bytes = reinterpret_cast<const char*>(data);
diff --git a/net/quic/core/quic_headers_stream_test.cc b/net/quic/core/quic_headers_stream_test.cc index 00fd09d9..59f300e 100644 --- a/net/quic/core/quic_headers_stream_test.cc +++ b/net/quic/core/quic_headers_stream_test.cc
@@ -40,7 +40,7 @@ // TODO(bnc): Merge these correctly. bool FLAGS_use_http2_frame_decoder_adapter; bool FLAGS_spdy_use_hpack_decoder2; -bool FLAGS_spdy_framer_use_new_methods2; +bool FLAGS_spdy_framer_use_new_methods3; namespace net { namespace test { @@ -171,16 +171,16 @@ return os; } -typedef std:: +typedef testing:: tuple<QuicVersion, Perspective, Http2DecoderChoice, HpackDecoderChoice> TestParamsTuple; struct TestParams { explicit TestParams(TestParamsTuple params) - : version(std::get<0>(params)), - perspective(std::get<1>(params)), - http2_decoder(std::get<2>(params)), - hpack_decoder(std::get<3>(params)) { + : version(testing::get<0>(params)), + perspective(testing::get<1>(params)), + http2_decoder(testing::get<2>(params)), + hpack_decoder(testing::get<3>(params)) { switch (http2_decoder) { case HTTP2_DECODER_SPDY: FLAGS_use_nested_spdy_framer_decoder = false; @@ -195,7 +195,7 @@ FLAGS_use_http2_frame_decoder_adapter = true; // Http2FrameDecoderAdapter needs the new header methods, else // --use_http2_frame_decoder_adapter=true will be ignored. - FLAGS_spdy_framer_use_new_methods2 = true; + FLAGS_spdy_framer_use_new_methods3 = true; break; } switch (hpack_decoder) { @@ -205,7 +205,7 @@ case HPACK_DECODER_NEW: FLAGS_spdy_use_hpack_decoder2 = true; // Needs new header methods to be used. - FLAGS_spdy_framer_use_new_methods2 = true; + FLAGS_spdy_framer_use_new_methods3 = true; break; } FLAGS_quic_always_log_bugs_for_tests = true; @@ -408,7 +408,7 @@ Tests, QuicHeadersStreamTest, ::testing::Combine( - ::testing::ValuesIn(QuicSupportedVersions()), + ::testing::ValuesIn(AllSupportedVersions()), ::testing::Values(Perspective::IS_CLIENT, Perspective::IS_SERVER), ::testing::Values(HTTP2_DECODER_SPDY, HTTP2_DECODER_NESTED_SPDY,
diff --git a/net/quic/core/quic_multipath_received_packet_manager.cc b/net/quic/core/quic_multipath_received_packet_manager.cc index 932ca32..8c40483 100644 --- a/net/quic/core/quic_multipath_received_packet_manager.cc +++ b/net/quic/core/quic_multipath_received_packet_manager.cc
@@ -16,7 +16,7 @@ } QuicMultipathReceivedPacketManager::~QuicMultipathReceivedPacketManager() { - STLDeleteValues(&path_managers_); + base::STLDeleteValues(&path_managers_); } void QuicMultipathReceivedPacketManager::OnPathCreated(
diff --git a/net/quic/core/quic_multipath_sent_packet_manager.cc b/net/quic/core/quic_multipath_sent_packet_manager.cc index a3f9320..0800a6a 100644 --- a/net/quic/core/quic_multipath_sent_packet_manager.cc +++ b/net/quic/core/quic_multipath_sent_packet_manager.cc
@@ -316,6 +316,23 @@ return path_manager->GetSlowStartThresholdInTcpMss(); } +string QuicMultipathSentPacketManager::GetDebugState() const { + string debug_state_by_path; + for (size_t i = 0; i < path_managers_info_.size(); ++i) { + if (path_managers_info_[i].manager == nullptr || + path_managers_info_[i].state != ACTIVE) { + continue; + } + const string& debug_state = path_managers_info_[i].manager->GetDebugState(); + if (debug_state.empty()) { + continue; + } + debug_state_by_path = + debug_state_by_path + "[" + base::IntToString(i) + "]:" + debug_state; + } + return debug_state_by_path; +} + void QuicMultipathSentPacketManager::CancelRetransmissionsForStream( QuicStreamId stream_id) { for (PathSentPacketManagerInfo path_manager_info : path_managers_info_) { @@ -500,4 +517,14 @@ ConnectionCloseSource::FROM_SELF); } +void QuicMultipathSentPacketManager::OnApplicationLimited() { + for (PathSentPacketManagerInfo& path_manager_info : path_managers_info_) { + if (path_manager_info.manager == nullptr || + path_manager_info.state != ACTIVE) { + continue; + } + path_manager_info.manager->OnApplicationLimited(); + } +} + } // namespace net
diff --git a/net/quic/core/quic_multipath_sent_packet_manager.h b/net/quic/core/quic_multipath_sent_packet_manager.h index 46fe740..c805280 100644 --- a/net/quic/core/quic_multipath_sent_packet_manager.h +++ b/net/quic/core/quic_multipath_sent_packet_manager.h
@@ -132,6 +132,10 @@ // TCP segments on the default path. QuicPacketCount GetSlowStartThresholdInTcpMss() const override; + // Returns debugging information about the state of the congestion + // controller for all paths. + std::string GetDebugState() const override; + // No longer retransmit data for |stream_id| on all paths and any pending // retransmissions in pending_retransmissions_. void CancelRetransmissionsForStream(QuicStreamId stream_id) override; @@ -162,6 +166,8 @@ size_t GetConsecutiveRtoCount() const override; size_t GetConsecutiveTlpCount() const override; + void OnApplicationLimited() override; + private: friend class test::QuicConnectionPeer; friend class test::QuicMultipathSentPacketManagerPeer;
diff --git a/net/quic/core/quic_multipath_sent_packet_manager_test.cc b/net/quic/core/quic_multipath_sent_packet_manager_test.cc index f7bd7187..4098c30ad 100644 --- a/net/quic/core/quic_multipath_sent_packet_manager_test.cc +++ b/net/quic/core/quic_multipath_sent_packet_manager_test.cc
@@ -350,6 +350,13 @@ EXPECT_EQ(3u, multipath_manager_.GetConsecutiveTlpCount()); } +TEST_F(QuicMultipathSentPacketManagerTest, OnApplicationLimited) { + EXPECT_CALL(*manager_0_, OnApplicationLimited()).Times(1); + EXPECT_CALL(*manager_1_, OnApplicationLimited()).Times(1); + EXPECT_CALL(*manager_2_, OnApplicationLimited()).Times(0); + multipath_manager_.OnApplicationLimited(); +} + } // namespace } // namespace test } // namespace net
diff --git a/net/quic/core/quic_packet_creator_test.cc b/net/quic/core/quic_packet_creator_test.cc index a8c1ea7..ec7156a 100644 --- a/net/quic/core/quic_packet_creator_test.cc +++ b/net/quic/core/quic_packet_creator_test.cc
@@ -63,7 +63,7 @@ vector<TestParams> GetTestParams() { vector<TestParams> params; constexpr QuicConnectionIdLength kMax = PACKET_8BYTE_CONNECTION_ID; - QuicVersionVector all_supported_versions = QuicSupportedVersions(); + QuicVersionVector all_supported_versions = AllSupportedVersions(); for (size_t i = 0; i < all_supported_versions.size(); ++i) { params.push_back(TestParams(all_supported_versions[i], true, kMax)); params.push_back(TestParams(all_supported_versions[i], false, kMax));
diff --git a/net/quic/core/quic_packet_generator_test.cc b/net/quic/core/quic_packet_generator_test.cc index b760d871..f3a2327 100644 --- a/net/quic/core/quic_packet_generator_test.cc +++ b/net/quic/core/quic_packet_generator_test.cc
@@ -104,7 +104,7 @@ class QuicPacketGeneratorTest : public ::testing::Test { public: QuicPacketGeneratorTest() - : framer_(QuicSupportedVersions(), + : framer_(AllSupportedVersions(), QuicTime::Zero(), Perspective::IS_CLIENT), generator_(42, &framer_, &random_, &buffer_allocator_, &delegate_),
diff --git a/net/quic/core/quic_protocol.cc b/net/quic/core/quic_protocol.cc index 6b879458..586e316 100644 --- a/net/quic/core/quic_protocol.cc +++ b/net/quic/core/quic_protocol.cc
@@ -171,7 +171,7 @@ tag_vector.end(); } -QuicVersionVector QuicSupportedVersions() { +QuicVersionVector AllSupportedVersions() { QuicVersionVector supported_versions; for (size_t i = 0; i < arraysize(kSupportedQuicVersions); ++i) { supported_versions.push_back(kSupportedQuicVersions[i]); @@ -179,6 +179,10 @@ return supported_versions; } +QuicVersionVector CurrentSupportedVersions() { + return FilterSupportedVersions(AllSupportedVersions()); +} + QuicVersionVector FilterSupportedVersions(QuicVersionVector versions) { QuicVersionVector filtered_versions(versions.size()); filtered_versions.clear(); // Guaranteed by spec not to change capacity. @@ -188,7 +192,7 @@ filtered_versions.push_back(version); } } else if (version == QUIC_VERSION_36) { - if (FLAGS_quic_enable_version_35 && FLAGS_quic_enable_version_36) { + if (FLAGS_quic_enable_version_35 && FLAGS_quic_enable_version_36_v2) { filtered_versions.push_back(version); } } else { @@ -198,6 +202,17 @@ return filtered_versions; } +QuicVersionVector VersionOfIndex(const QuicVersionVector& versions, int index) { + QuicVersionVector version; + int version_count = versions.size(); + if (index >= 0 && index < version_count) { + version.push_back(versions[index]); + } else { + version.push_back(QUIC_VERSION_UNSUPPORTED); + } + return version; +} + QuicTag QuicVersionToQuicTag(const QuicVersion version) { switch (version) { case QUIC_VERSION_30: @@ -727,7 +742,7 @@ QuicData::QuicData(const char* buffer, size_t length) : buffer_(buffer), length_(length), owns_buffer_(false) {} -QuicData::QuicData(char* buffer, size_t length, bool owns_buffer) +QuicData::QuicData(const char* buffer, size_t length, bool owns_buffer) : buffer_(buffer), length_(length), owns_buffer_(owns_buffer) {} QuicData::~QuicData() { @@ -764,7 +779,7 @@ QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer, size_t length) : QuicData(buffer, length) {} -QuicEncryptedPacket::QuicEncryptedPacket(char* buffer, +QuicEncryptedPacket::QuicEncryptedPacket(const char* buffer, size_t length, bool owns_buffer) : QuicData(buffer, length, owns_buffer) {} @@ -783,19 +798,33 @@ QuicReceivedPacket::QuicReceivedPacket(const char* buffer, size_t length, QuicTime receipt_time) - : QuicEncryptedPacket(buffer, length), receipt_time_(receipt_time) {} + : QuicEncryptedPacket(buffer, length), + receipt_time_(receipt_time), + ttl_(0) {} -QuicReceivedPacket::QuicReceivedPacket(char* buffer, +QuicReceivedPacket::QuicReceivedPacket(const char* buffer, size_t length, QuicTime receipt_time, bool owns_buffer) : QuicEncryptedPacket(buffer, length, owns_buffer), - receipt_time_(receipt_time) {} + receipt_time_(receipt_time), + ttl_(0) {} + +QuicReceivedPacket::QuicReceivedPacket(const char* buffer, + size_t length, + QuicTime receipt_time, + bool owns_buffer, + int ttl, + bool ttl_valid) + : QuicEncryptedPacket(buffer, length, owns_buffer), + receipt_time_(receipt_time), + ttl_(ttl_valid ? ttl : -1) {} QuicReceivedPacket* QuicReceivedPacket::Clone() const { char* buffer = new char[this->length()]; memcpy(buffer, this->data(), this->length()); - return new QuicReceivedPacket(buffer, this->length(), receipt_time(), true); + return new QuicReceivedPacket(buffer, this->length(), receipt_time(), true, + ttl(), ttl() >= 0); } ostream& operator<<(ostream& os, const QuicReceivedPacket& s) { @@ -819,18 +848,18 @@ length() - start_of_encrypted_data); } -QuicVersionManager::QuicVersionManager(QuicVersionVector supported_versions) { - enable_quic_version_35_ = FLAGS_quic_enable_version_35; - enable_quic_version_36_ = FLAGS_quic_enable_version_36; - allowed_supported_versions_ = supported_versions; - filtered_supported_versions_ = FilterSupportedVersions(supported_versions); -} +QuicVersionManager::QuicVersionManager(QuicVersionVector supported_versions) + : enable_quic_version_35_(FLAGS_quic_enable_version_35), + enable_quic_version_36_(FLAGS_quic_enable_version_36_v2), + allowed_supported_versions_(supported_versions), + filtered_supported_versions_( + FilterSupportedVersions(supported_versions)) {} const QuicVersionVector& QuicVersionManager::GetSupportedVersions() { if (enable_quic_version_35_ != FLAGS_quic_enable_version_35 || - enable_quic_version_36_ != FLAGS_quic_enable_version_36) { + enable_quic_version_36_ != FLAGS_quic_enable_version_36_v2) { enable_quic_version_35_ = FLAGS_quic_enable_version_35; - enable_quic_version_36_ = FLAGS_quic_enable_version_36; + enable_quic_version_36_ = FLAGS_quic_enable_version_36_v2; filtered_supported_versions_ = FilterSupportedVersions(allowed_supported_versions_); }
diff --git a/net/quic/core/quic_protocol.h b/net/quic/core/quic_protocol.h index 0ac0b33..bfe61f7 100644 --- a/net/quic/core/quic_protocol.h +++ b/net/quic/core/quic_protocol.h
@@ -387,13 +387,22 @@ typedef std::vector<QuicVersion> QuicVersionVector; // Returns a vector of QUIC versions in kSupportedQuicVersions. -NET_EXPORT_PRIVATE QuicVersionVector QuicSupportedVersions(); +NET_EXPORT_PRIVATE QuicVersionVector AllSupportedVersions(); + +// Returns a vector of QUIC versions from kSupportedQuicVersions which exclude +// any versions which are disabled by flags. +NET_EXPORT_PRIVATE QuicVersionVector CurrentSupportedVersions(); // Returns a vector of QUIC versions from |versions| which exclude any versions // which are disabled by flags. NET_EXPORT_PRIVATE QuicVersionVector FilterSupportedVersions(QuicVersionVector versions); +// Returns QUIC version of |index| in result of |versions|. Returns +// QUIC_VERSION_UNSUPPORTED if |index| is out of bounds. +NET_EXPORT_PRIVATE QuicVersionVector +VersionOfIndex(const QuicVersionVector& versions, int index); + // QuicTag is written to and read from the wire, but we prefer to use // the more readable QuicVersion at other levels. // Helper function which translates from a QuicVersion to a QuicTag. Returns 0 @@ -1259,7 +1268,7 @@ class NET_EXPORT_PRIVATE QuicData { public: QuicData(const char* buffer, size_t length); - QuicData(char* buffer, size_t length, bool owns_buffer); + QuicData(const char* buffer, size_t length, bool owns_buffer); virtual ~QuicData(); base::StringPiece AsStringPiece() const { @@ -1311,7 +1320,7 @@ class NET_EXPORT_PRIVATE QuicEncryptedPacket : public QuicData { public: QuicEncryptedPacket(const char* buffer, size_t length); - QuicEncryptedPacket(char* buffer, size_t length, bool owns_buffer); + QuicEncryptedPacket(const char* buffer, size_t length, bool owns_buffer); // Clones the packet into a new packet which owns the buffer. QuicEncryptedPacket* Clone() const; @@ -1332,10 +1341,16 @@ class NET_EXPORT_PRIVATE QuicReceivedPacket : public QuicEncryptedPacket { public: QuicReceivedPacket(const char* buffer, size_t length, QuicTime receipt_time); - QuicReceivedPacket(char* buffer, + QuicReceivedPacket(const char* buffer, size_t length, QuicTime receipt_time, bool owns_buffer); + QuicReceivedPacket(const char* buffer, + size_t length, + QuicTime receipt_time, + bool owns_buffer, + int ttl, + bool ttl_valid); // Clones the packet into a new packet which owns the buffer. QuicReceivedPacket* Clone() const; @@ -1343,6 +1358,9 @@ // Returns the time at which the packet was received. QuicTime receipt_time() const { return receipt_time_; } + // This is the TTL of the packet, assuming ttl_vaild_ is true. + int ttl() const { return ttl_; } + // By default, gtest prints the raw bytes of an object. The bool data // member (in the base class QuicData) causes this object to have padding // bytes, which causes the default gtest object printer to read @@ -1353,6 +1371,7 @@ private: const QuicTime receipt_time_; + int ttl_; DISALLOW_COPY_AND_ASSIGN(QuicReceivedPacket); }; @@ -1402,7 +1421,7 @@ private: // FLAGS_quic_enable_version_35 bool enable_quic_version_35_; - // FLAGS_quic_enable_version_36 + // FLAGS_quic_enable_version_36_v2 bool enable_quic_version_36_; // The list of versions that may be supported. QuicVersionVector allowed_supported_versions_;
diff --git a/net/quic/core/quic_protocol_test.cc b/net/quic/core/quic_protocol_test.cc index 0626bfd0..deee283 100644 --- a/net/quic/core/quic_protocol_test.cc +++ b/net/quic/core/quic_protocol_test.cc
@@ -289,7 +289,7 @@ QUIC_VERSION_34, QUIC_VERSION_35, QUIC_VERSION_36}; FLAGS_quic_enable_version_35 = false; - FLAGS_quic_enable_version_36 = false; + FLAGS_quic_enable_version_36_v2 = false; QuicVersionVector filtered_versions = FilterSupportedVersions(all_versions); ASSERT_EQ(5u, filtered_versions.size()); @@ -302,18 +302,32 @@ TEST(QuicProtocolTest, QuicVersionManager) { FLAGS_quic_enable_version_35 = false; - FLAGS_quic_enable_version_36 = false; - QuicVersionManager manager(QuicSupportedVersions()); - EXPECT_EQ(FilterSupportedVersions(QuicSupportedVersions()), + FLAGS_quic_enable_version_36_v2 = false; + QuicVersionManager manager(AllSupportedVersions()); + EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()), manager.GetSupportedVersions()); FLAGS_quic_enable_version_35 = true; - FLAGS_quic_enable_version_36 = true; - EXPECT_EQ(FilterSupportedVersions(QuicSupportedVersions()), + FLAGS_quic_enable_version_36_v2 = true; + EXPECT_EQ(FilterSupportedVersions(AllSupportedVersions()), manager.GetSupportedVersions()); EXPECT_EQ(QUIC_VERSION_36, manager.GetSupportedVersions()[0]); EXPECT_EQ(QUIC_VERSION_35, manager.GetSupportedVersions()[1]); } +TEST(QuicProtocolTest, LookUpVersionByIndex) { + QuicVersionVector all_versions = { + QUIC_VERSION_30, QUIC_VERSION_31, QUIC_VERSION_32, QUIC_VERSION_33, + QUIC_VERSION_34, QUIC_VERSION_35, QUIC_VERSION_36}; + int version_count = all_versions.size(); + for (int i = -5; i <= version_count + 1; ++i) { + if (i >= 0 && i < version_count) { + EXPECT_EQ(all_versions[i], VersionOfIndex(all_versions, i)[0]); + } else { + EXPECT_EQ(QUIC_VERSION_UNSUPPORTED, VersionOfIndex(all_versions, i)[0]); + } + } +} + // Tests that a queue contains the expected data after calls to Add(). TEST(PacketNumberQueueTest, AddRange) { PacketNumberQueue queue;
diff --git a/net/quic/core/quic_received_packet_manager_test.cc b/net/quic/core/quic_received_packet_manager_test.cc index f3c6145..9784e1c 100644 --- a/net/quic/core/quic_received_packet_manager_test.cc +++ b/net/quic/core/quic_received_packet_manager_test.cc
@@ -199,7 +199,7 @@ vector<TestParams> GetTestParams() { vector<TestParams> params; - QuicVersionVector all_supported_versions = QuicSupportedVersions(); + QuicVersionVector all_supported_versions = AllSupportedVersions(); for (size_t i = 0; i < all_supported_versions.size(); ++i) { params.push_back(TestParams(all_supported_versions[i])); }
diff --git a/net/quic/core/quic_sent_packet_manager.cc b/net/quic/core/quic_sent_packet_manager.cc index 6c618841..58fc40d 100644 --- a/net/quic/core/quic_sent_packet_manager.cc +++ b/net/quic/core/quic_sent_packet_manager.cc
@@ -5,6 +5,7 @@ #include "net/quic/core/quic_sent_packet_manager.h" #include <algorithm> +#include <string> #include "base/logging.h" #include "base/stl_util.h" @@ -69,13 +70,8 @@ debug_delegate_(nullptr), network_change_visitor_(nullptr), initial_congestion_window_(kInitialCongestionWindow), - send_algorithm_( - SendAlgorithmInterface::Create(clock, - &rtt_stats_, - congestion_control_type, - stats, - initial_congestion_window_)), - loss_algorithm_(new GeneralLossAlgorithm(loss_type)), + loss_algorithm_(&general_loss_algorithm_), + general_loss_algorithm_(loss_type), n_connection_simulation_(false), receive_buffer_bytes_(kDefaultSocketReceiveBuffer), least_packet_awaited_by_peer_(1), @@ -87,12 +83,13 @@ max_tail_loss_probes_(kDefaultMaxTailLossProbes), enable_half_rtt_tail_loss_probe_(false), using_pacing_(false), - using_inline_pacing_(false), use_new_rto_(false), undo_pending_retransmits_(false), largest_newly_acked_(0), largest_mtu_acked_(0), - handshake_confirmed_(false) {} + handshake_confirmed_(false) { + SetSendAlgorithm(congestion_control_type); +} QuicSentPacketManager::~QuicSentPacketManager() {} @@ -113,26 +110,20 @@ // TODO(ianswett): BBR is currently a server only feature. if (FLAGS_quic_allow_bbr && config.HasReceivedConnectionOptions() && ContainsQuicTag(config.ReceivedConnectionOptions(), kTBBR)) { - send_algorithm_.reset(SendAlgorithmInterface::Create( - clock_, &rtt_stats_, kBBR, stats_, initial_congestion_window_)); + SetSendAlgorithm(kBBR); } if (config.HasReceivedConnectionOptions() && ContainsQuicTag(config.ReceivedConnectionOptions(), kRENO)) { if (ContainsQuicTag(config.ReceivedConnectionOptions(), kBYTE)) { - send_algorithm_.reset(SendAlgorithmInterface::Create( - clock_, &rtt_stats_, kRenoBytes, stats_, initial_congestion_window_)); + SetSendAlgorithm(kRenoBytes); } else { - send_algorithm_.reset(SendAlgorithmInterface::Create( - clock_, &rtt_stats_, kReno, stats_, initial_congestion_window_)); + SetSendAlgorithm(kReno); } } else if (config.HasReceivedConnectionOptions() && ContainsQuicTag(config.ReceivedConnectionOptions(), kBYTE)) { - send_algorithm_.reset(SendAlgorithmInterface::Create( - clock_, &rtt_stats_, kCubicBytes, stats_, initial_congestion_window_)); + SetSendAlgorithm(kCubicBytes); } - if (!FLAGS_quic_disable_pacing_for_perf_tests) { - EnablePacing(); - } + using_pacing_ = !FLAGS_quic_disable_pacing_for_perf_tests; if (config.HasClientSentConnectionOption(k1CON, perspective_)) { send_algorithm_->SetNumEmulatedConnections(1); @@ -151,11 +142,11 @@ } if (config.HasReceivedConnectionOptions() && ContainsQuicTag(config.ReceivedConnectionOptions(), kTIME)) { - loss_algorithm_.reset(new GeneralLossAlgorithm(kTime)); + general_loss_algorithm_.SetLossDetectionType(kTime); } if (config.HasReceivedConnectionOptions() && ContainsQuicTag(config.ReceivedConnectionOptions(), kATIM)) { - loss_algorithm_.reset(new GeneralLossAlgorithm(kAdaptiveTime)); + general_loss_algorithm_.SetLossDetectionType(kAdaptiveTime); } if (FLAGS_quic_loss_recovery_use_largest_acked && config.HasClientSentConnectionOption(kUNDO, perspective_)) { @@ -191,12 +182,7 @@ } void QuicSentPacketManager::SetMaxPacingRate(QuicBandwidth max_pacing_rate) { - if (using_inline_pacing_) { - pacing_sender_.SetMaxPacingRate(max_pacing_rate); - } else if (using_pacing_) { - static_cast<PacingSender*>(send_algorithm_.get()) - ->SetMaxPacingRate(max_pacing_rate); - } + pacing_sender_.set_max_pacing_rate(max_pacing_rate); } void QuicSentPacketManager::SetHandshakeConfirmed() { @@ -281,7 +267,7 @@ if (!rtt_updated && packets_acked_.empty() && packets_lost_.empty()) { return; } - if (using_inline_pacing_) { + if (using_pacing_) { pacing_sender_.OnCongestionEvent(rtt_updated, bytes_in_flight, packets_acked_, packets_lost_); } else { @@ -381,7 +367,7 @@ } else { // TODO(ianswett): Currently the RTO can fire while there are pending NACK // retransmissions for the same data, which is not ideal. - if (ContainsKey(pending_retransmissions_, packet_number)) { + if (base::ContainsKey(pending_retransmissions_, packet_number)) { return; } @@ -564,7 +550,7 @@ } bool in_flight; - if (using_inline_pacing_) { + if (using_pacing_) { in_flight = pacing_sender_.OnPacketSent( sent_time, unacked_packets_.bytes_in_flight(), packet_number, serialized_packet->encrypted_length, has_retransmittable_data); @@ -761,8 +747,7 @@ QuicTime::Delta send_delta = ack_receive_time - transmission_info.sent_time; const int kMaxSendDeltaSeconds = 30; - if (FLAGS_quic_socket_walltimestamps && - send_delta.ToSeconds() > kMaxSendDeltaSeconds) { + if (send_delta.ToSeconds() > kMaxSendDeltaSeconds) { // send_delta can be very high if local clock is changed mid-connection. LOG(WARNING) << "Excessive send delta: " << send_delta.ToSeconds() << ", setting to: " << kMaxSendDeltaSeconds @@ -784,14 +769,12 @@ // send algorithm does not need to be consulted. if (pending_timer_transmission_count_ > 0) { delay = QuicTime::Delta::Zero(); + } else if (using_pacing_) { + delay = + pacing_sender_.TimeUntilSend(now, unacked_packets_.bytes_in_flight()); } else { - if (using_inline_pacing_) { - delay = - pacing_sender_.TimeUntilSend(now, unacked_packets_.bytes_in_flight()); - } else { - delay = send_algorithm_->TimeUntilSend( - now, unacked_packets_.bytes_in_flight()); - } + delay = + send_algorithm_->TimeUntilSend(now, unacked_packets_.bytes_in_flight()); } if (!delay.IsInfinite()) { *path_id = path_id_; @@ -921,6 +904,10 @@ return send_algorithm_->GetSlowStartThreshold() / kDefaultTCPMSS; } +std::string QuicSentPacketManager::GetDebugState() const { + return send_algorithm_->GetDebugState(); +} + void QuicSentPacketManager::CancelRetransmissionsForStream( QuicStreamId stream_id) { unacked_packets_.CancelRetransmissionsForStream(stream_id); @@ -937,24 +924,17 @@ } } -void QuicSentPacketManager::EnablePacing() { - if (FLAGS_quic_use_inline_pacing) { - using_inline_pacing_ = true; - pacing_sender_.SetSender(send_algorithm_.get(), false); - } else { - // TODO(ianswett): Replace with a method which wraps the send algorithm in a - // pacer every time a new algorithm is set. - if (using_pacing_) { - return; - } +void QuicSentPacketManager::SetSendAlgorithm( + CongestionControlType congestion_control_type) { + SetSendAlgorithm(SendAlgorithmInterface::Create( + clock_, &rtt_stats_, congestion_control_type, stats_, + initial_congestion_window_)); +} - // Set up a pacing sender with a 1 millisecond alarm granularity, the same - // as the default granularity of the Linux kernel's FQ qdisc. - using_pacing_ = true; - PacingSender* pacing_sender = new PacingSender; - pacing_sender->SetSender(send_algorithm_.release(), true); - send_algorithm_.reset(pacing_sender); - } +void QuicSentPacketManager::SetSendAlgorithm( + SendAlgorithmInterface* send_algorithm) { + send_algorithm_.reset(send_algorithm); + pacing_sender_.set_sender(send_algorithm); } void QuicSentPacketManager::OnConnectionMigration(QuicPathId, @@ -1020,4 +1000,8 @@ unacked_packets_.RemoveObsoletePackets(); } +void QuicSentPacketManager::OnApplicationLimited() { + send_algorithm_->OnApplicationLimited(unacked_packets_.bytes_in_flight()); +} + } // namespace net
diff --git a/net/quic/core/quic_sent_packet_manager.h b/net/quic/core/quic_sent_packet_manager.h index a875bc9..17e2203 100644 --- a/net/quic/core/quic_sent_packet_manager.h +++ b/net/quic/core/quic_sent_packet_manager.h
@@ -15,6 +15,7 @@ #include "base/macros.h" #include "net/base/linked_hash_map.h" +#include "net/quic/core/congestion_control/general_loss_algorithm.h" #include "net/quic/core/congestion_control/loss_detection_interface.h" #include "net/quic/core/congestion_control/pacing_sender.h" #include "net/quic/core/congestion_control/rtt_stats.h" @@ -179,6 +180,9 @@ // start threshold and will return 0. QuicPacketCount GetSlowStartThresholdInTcpMss() const override; + // Returns debugging information about the state of the congestion controller. + std::string GetDebugState() const override; + // No longer retransmit data for |stream_id|. void CancelRetransmissionsForStream(QuicStreamId stream_id) override; @@ -203,6 +207,8 @@ size_t GetConsecutiveTlpCount() const override; + void OnApplicationLimited() override; + private: friend class test::QuicConnectionPeer; friend class test::QuicSentPacketManagerPeer; @@ -311,8 +317,14 @@ // RTT measurement purposes. void RemoveObsoletePackets(); - // Enables pacing if it has not already been enabled. - void EnablePacing(); + // Sets the send algorithm to the given congestion control type and points the + // pacing sender at |send_algorithm_|. Can be called any number of times. + void SetSendAlgorithm(CongestionControlType congestion_control_type); + + // Sets the send algorithm to |send_algorithm| and points the pacing sender at + // |send_algorithm_|. Takes ownership of |send_algorithm|. Can be called any + // number of times. + void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm); // Newly serialized retransmittable packets are added to this map, which // contains owning pointers to any contained frames. If a packet is @@ -343,7 +355,9 @@ const QuicPacketCount initial_congestion_window_; RttStats rtt_stats_; std::unique_ptr<SendAlgorithmInterface> send_algorithm_; - std::unique_ptr<LossDetectionInterface> loss_algorithm_; + // Not owned. Always points to |general_loss_algorithm_| outside of tests. + LossDetectionInterface* loss_algorithm_; + GeneralLossAlgorithm general_loss_algorithm_; bool n_connection_simulation_; // Receiver side buffer in bytes. @@ -368,10 +382,6 @@ // If true, send the TLP at 0.5 RTT. bool enable_half_rtt_tail_loss_probe_; bool using_pacing_; - // TODO(jdorfman): Remove |using_pacing_| and rename |using_inline_pacing_| to - // |using_pacing| when deprecating - // gfe2_reloadable_flag_quic_use_inline_pacing. - bool using_inline_pacing_; // If true, use the new RTO with loss based CWND reduction instead of the send // algorithms's OnRetransmissionTimeout to reduce the congestion window. bool use_new_rto_; @@ -387,6 +397,8 @@ // Largest packet in bytes ever acknowledged. QuicPacketLength largest_mtu_acked_; + // Replaces certain calls to |send_algorithm_| when |using_pacing_| is true. + // Calls into |send_algorithm_| for the underlying congestion control. PacingSender pacing_sender_; // Set to true after the crypto handshake has successfully completed. After
diff --git a/net/quic/core/quic_sent_packet_manager_interface.h b/net/quic/core/quic_sent_packet_manager_interface.h index e1f9d48..c366ed6 100644 --- a/net/quic/core/quic_sent_packet_manager_interface.h +++ b/net/quic/core/quic_sent_packet_manager_interface.h
@@ -152,6 +152,10 @@ // TCP segments on the default path. virtual QuicPacketCount GetSlowStartThresholdInTcpMss() const = 0; + // Returns debugging information about the current state of the + // congestion controller. + virtual std::string GetDebugState() const = 0; + // No longer retransmit data for |stream_id| on all paths. virtual void CancelRetransmissionsForStream(QuicStreamId stream_id) = 0; @@ -181,6 +185,10 @@ // path. virtual size_t GetConsecutiveRtoCount() const = 0; virtual size_t GetConsecutiveTlpCount() const = 0; + + // Signals to the congestion controller that the connection has no outstanding + // data to send. + virtual void OnApplicationLimited() = 0; }; } // namespace net
diff --git a/net/quic/core/quic_sent_packet_manager_test.cc b/net/quic/core/quic_sent_packet_manager_test.cc index 3e7c4502..c18f491620 100644 --- a/net/quic/core/quic_sent_packet_manager_test.cc +++ b/net/quic/core/quic_sent_packet_manager_test.cc
@@ -5,7 +5,7 @@ #include "net/quic/core/quic_sent_packet_manager.h" #include <memory> - +#include "base/memory/ptr_util.h" #include "base/stl_util.h" #include "net/quic/core/quic_flags.h" #include "net/quic/test_tools/quic_config_peer.h" @@ -106,9 +106,7 @@ .Times(AnyNumber()); } - ~QuicSentPacketManagerTest() override { - STLDeleteElements(&packets_); - } + ~QuicSentPacketManagerTest() override { base::STLDeleteElements(&packets_); } QuicByteCount BytesInFlight() { return QuicSentPacketManagerPeer::GetBytesInFlight(&manager_); @@ -534,8 +532,8 @@ } TEST_P(QuicSentPacketManagerTest, AckOriginalTransmission) { - MockLossAlgorithm* loss_algorithm = new MockLossAlgorithm(); - QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm); + auto loss_algorithm = base::MakeUnique<MockLossAlgorithm>(); + QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm.get()); SendDataPacket(1); RetransmitAndSendPacket(1, 2); @@ -1346,8 +1344,8 @@ } TEST_P(QuicSentPacketManagerTest, GetLossDelay) { - MockLossAlgorithm* loss_algorithm = new MockLossAlgorithm(); - QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm); + auto loss_algorithm = base::MakeUnique<MockLossAlgorithm>(); + QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm.get()); EXPECT_CALL(*loss_algorithm, GetLossTimeout()) .WillRepeatedly(Return(QuicTime::Zero())); @@ -1570,8 +1568,8 @@ for (size_t i = 1; i <= kNumSentPackets; ++i) { SendDataPacket(i); } - MockLossAlgorithm* loss_algorithm = new MockLossAlgorithm(); - QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm); + auto loss_algorithm = base::MakeUnique<MockLossAlgorithm>(); + QuicSentPacketManagerPeer::SetLossAlgorithm(&manager_, loss_algorithm.get()); EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _)); EXPECT_CALL(*network_change_visitor_, OnCongestionChange()); SendAlgorithmInterface::CongestionVector lost_packets;
diff --git a/net/quic/core/quic_server_session_base.h b/net/quic/core/quic_server_session_base.h index fe14d61..0a14a56 100644 --- a/net/quic/core/quic_server_session_base.h +++ b/net/quic/core/quic_server_session_base.h
@@ -74,7 +74,8 @@ std::string* error_details) const = 0; }; - // |crypto_config| must outlive the session. + // Does not take ownership of |connection|. |crypto_config| must outlive the + // session. QuicServerSessionBase(const QuicConfig& config, QuicConnection* connection, Visitor* visitor,
diff --git a/net/quic/core/quic_server_session_base_test.cc b/net/quic/core/quic_server_session_base_test.cc index 00b83cd..daa947009 100644 --- a/net/quic/core/quic_server_session_base_test.cc +++ b/net/quic/core/quic_server_session_base_test.cc
@@ -86,7 +86,7 @@ crypto_config, compressed_certs_cache) {} - ~TestServerSession() override{}; + ~TestServerSession() override { delete connection(); }; protected: QuicSpdyStream* CreateIncomingDynamicStream(QuicStreamId id) override { @@ -184,7 +184,7 @@ INSTANTIATE_TEST_CASE_P(Tests, QuicServerSessionBaseTest, - ::testing::ValuesIn(QuicSupportedVersions())); + ::testing::ValuesIn(AllSupportedVersions())); TEST_P(QuicServerSessionBaseTest, ServerPushDisabledByDefault) { // Without the client explicitly sending kSPSH, server push will be disabled
diff --git a/net/quic/core/quic_session.cc b/net/quic/core/quic_session.cc index c3bf20ba..e3472b7 100644 --- a/net/quic/core/quic_session.cc +++ b/net/quic/core/quic_session.cc
@@ -40,7 +40,7 @@ num_draining_incoming_streams_(0), num_locally_closed_incoming_streams_highest_offset_(0), error_(QUIC_NO_ERROR), - flow_controller_(connection_.get(), + flow_controller_(connection_, 0, perspective(), kMinimumFlowControlSendWindow, @@ -57,8 +57,8 @@ } QuicSession::~QuicSession() { - STLDeleteElements(&closed_streams_); - STLDeleteValues(&dynamic_stream_map_); + base::STLDeleteElements(&closed_streams_); + base::STLDeleteValues(&dynamic_stream_map_); DLOG_IF(WARNING, num_locally_closed_incoming_streams_highest_offset() > max_open_incoming_streams_) @@ -90,7 +90,7 @@ } void QuicSession::OnRstStream(const QuicRstStreamFrame& frame) { - if (ContainsKey(static_stream_map_, frame.stream_id)) { + if (base::ContainsKey(static_stream_map_, frame.stream_id)) { connection()->CloseConnection( QUIC_INVALID_STREAM_ID, "Attempt to reset a static stream", ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); @@ -185,7 +185,7 @@ } QuicConnection::ScopedPacketBundler ack_bundler( - connection_.get(), QuicConnection::SEND_ACK_IF_QUEUED); + connection_, QuicConnection::SEND_ACK_IF_QUEUED); for (size_t i = 0; i < num_writes; ++i) { if (!(write_blocked_streams_.HasWriteBlockedCryptoOrHeadersStream() || write_blocked_streams_.HasWriteBlockedDataStreams())) { @@ -270,7 +270,7 @@ void QuicSession::SendRstStream(QuicStreamId id, QuicRstStreamErrorCode error, QuicStreamOffset bytes_written) { - if (ContainsKey(static_stream_map_, id)) { + if (base::ContainsKey(static_stream_map_, id)) { QUIC_BUG << "Cannot send RST for a static stream with ID " << id; return; } @@ -535,8 +535,8 @@ void QuicSession::ActivateStream(ReliableQuicStream* stream) { DVLOG(1) << ENDPOINT << "num_streams: " << dynamic_stream_map_.size() << ". activating " << stream->id(); - DCHECK(!ContainsKey(dynamic_stream_map_, stream->id())); - DCHECK(!ContainsKey(static_stream_map_, stream->id())); + DCHECK(!base::ContainsKey(dynamic_stream_map_, stream->id())); + DCHECK(!base::ContainsKey(static_stream_map_, stream->id())); dynamic_stream_map_[stream->id()] = stream; if (IsIncomingStream(stream->id())) { ++num_dynamic_incoming_streams_; @@ -561,8 +561,8 @@ } void QuicSession::StreamDraining(QuicStreamId stream_id) { - DCHECK(ContainsKey(dynamic_stream_map_, stream_id)); - if (!ContainsKey(draining_streams_, stream_id)) { + DCHECK(base::ContainsKey(dynamic_stream_map_, stream_id)); + if (!base::ContainsKey(draining_streams_, stream_id)) { draining_streams_.insert(stream_id); if (IsIncomingStream(stream_id)) { ++num_draining_incoming_streams_; @@ -614,7 +614,7 @@ ReliableQuicStream* QuicSession::GetOrCreateDynamicStream( const QuicStreamId stream_id) { - DCHECK(!ContainsKey(static_stream_map_, stream_id)) + DCHECK(!base::ContainsKey(static_stream_map_, stream_id)) << "Attempt to call GetOrCreateDynamicStream for a static stream"; DynamicStreamMap::iterator it = dynamic_stream_map_.find(stream_id); @@ -683,13 +683,13 @@ } // For peer created streams, we also need to consider available streams. return id <= largest_peer_created_stream_id_ && - !ContainsKey(available_streams_, id); + !base::ContainsKey(available_streams_, id); } bool QuicSession::IsOpenStream(QuicStreamId id) { DCHECK_NE(0u, id); - if (ContainsKey(static_stream_map_, id) || - ContainsKey(dynamic_stream_map_, id)) { + if (base::ContainsKey(static_stream_map_, id) || + base::ContainsKey(dynamic_stream_map_, id)) { // Stream is active return true; } @@ -728,7 +728,7 @@ } void QuicSession::PostProcessAfterData() { - STLDeleteElements(&closed_streams_); + base::STLDeleteElements(&closed_streams_); closed_streams_.clear(); }
diff --git a/net/quic/core/quic_session.h b/net/quic/core/quic_session.h index a4da9f98..2c93486a 100644 --- a/net/quic/core/quic_session.h +++ b/net/quic/core/quic_session.h
@@ -57,7 +57,7 @@ HANDSHAKE_CONFIRMED, }; - // Takes ownership of |connection|. + // Does not take ownership of |connection|. QuicSession(QuicConnection* connection, const QuicConfig& config); ~QuicSession() override; @@ -155,8 +155,8 @@ // not yet been created. bool IsClosedStream(QuicStreamId id); - QuicConnection* connection() { return connection_.get(); } - const QuicConnection* connection() const { return connection_.get(); } + QuicConnection* connection() { return connection_; } + const QuicConnection* connection() const { return connection_; } size_t num_active_requests() const { return dynamic_stream_map_.size(); } const IPEndPoint& peer_address() const { return connection_->peer_address(); } QuicConnectionId connection_id() const { @@ -352,7 +352,7 @@ std::map<QuicStreamId, QuicStreamOffset> locally_closed_streams_highest_offset_; - std::unique_ptr<QuicConnection> connection_; + QuicConnection* connection_; std::vector<ReliableQuicStream*> closed_streams_;
diff --git a/net/quic/core/quic_session_test.cc b/net/quic/core/quic_session_test.cc index 64de93e..2d58f66 100644 --- a/net/quic/core/quic_session_test.cc +++ b/net/quic/core/quic_session_test.cc
@@ -119,6 +119,8 @@ Initialize(); } + ~TestSession() override { delete connection(); } + TestCryptoStream* GetCryptoStream() override { return &crypto_stream_; } TestStream* CreateOutgoingDynamicStream(SpdyPriority priority) override { @@ -249,7 +251,7 @@ void CheckClosedStreams() { for (QuicStreamId i = kCryptoStreamId; i < 100; i++) { - if (!ContainsKey(closed_streams_, i)) { + if (!base::ContainsKey(closed_streams_, i)) { EXPECT_FALSE(session_.IsClosedStream(i)) << " stream id: " << i; } else { EXPECT_TRUE(session_.IsClosedStream(i)) << " stream id: " << i; @@ -280,7 +282,7 @@ INSTANTIATE_TEST_CASE_P(Tests, QuicSessionTestServer, - ::testing::ValuesIn(QuicSupportedVersions())); + ::testing::ValuesIn(AllSupportedVersions())); TEST_P(QuicSessionTestServer, PeerAddress) { EXPECT_EQ(IPEndPoint(Loopback4(), kTestPort), session_.peer_address()); @@ -490,6 +492,8 @@ } TEST_P(QuicSessionTestServer, OnCanWriteBundlesStreams) { + FLAGS_quic_enable_app_limited_check = true; + // Encryption needs to be established before data can be sent. CryptoHandshakeMessage msg; session_.GetCryptoStream()->OnHandshakeMessage(msg); @@ -511,6 +515,7 @@ .WillRepeatedly(Return(QuicTime::Delta::Zero())); EXPECT_CALL(*send_algorithm, GetCongestionWindow()) .WillRepeatedly(Return(kMaxPacketSize * 10)); + EXPECT_CALL(*send_algorithm, InRecovery()).WillRepeatedly(Return(false)); EXPECT_CALL(*stream2, OnCanWrite()) .WillOnce(testing::IgnoreResult( Invoke(CreateFunctor(&TestSession::SendStreamData, @@ -531,11 +536,14 @@ EXPECT_CALL(*writer, WritePacket(_, _, _, _, _)) .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 0))); EXPECT_CALL(*send_algorithm, OnPacketSent(_, _, _, _, _)); + EXPECT_CALL(*send_algorithm, OnApplicationLimited(_)); session_.OnCanWrite(); EXPECT_FALSE(session_.WillingAndAbleToWrite()); } TEST_P(QuicSessionTestServer, OnCanWriteCongestionControlBlocks) { + FLAGS_quic_enable_app_limited_check = true; + InSequence s; // Drive congestion control manually. @@ -576,10 +584,41 @@ EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _)) .WillOnce(Return(QuicTime::Delta::Zero())); EXPECT_CALL(*stream4, OnCanWrite()); + EXPECT_CALL(*send_algorithm, OnApplicationLimited(_)); session_.OnCanWrite(); EXPECT_FALSE(session_.WillingAndAbleToWrite()); } +TEST_P(QuicSessionTestServer, OnCanWriteWriterBlocks) { + FLAGS_quic_enable_app_limited_check = true; + + // Drive congestion control manually in order to ensure that + // application-limited signaling is handled correctly. + MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; + QuicConnectionPeer::SetSendAlgorithm(session_.connection(), kDefaultPathId, + send_algorithm); + EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _)) + .WillRepeatedly(Return(QuicTime::Delta::Zero())); + + // Drive packet writer manually. + MockPacketWriter* writer = static_cast<MockPacketWriter*>( + QuicConnectionPeer::GetWriter(session_.connection())); + EXPECT_CALL(*writer, IsWriteBlocked()).WillRepeatedly(Return(true)); + EXPECT_CALL(*writer, IsWriteBlockedDataBuffered()) + .WillRepeatedly(Return(true)); + EXPECT_CALL(*writer, WritePacket(_, _, _, _, _)).Times(0); + + TestStream* stream2 = session_.CreateOutgoingDynamicStream(kDefaultPriority); + + session_.MarkConnectionLevelWriteBlocked(stream2->id()); + + EXPECT_CALL(*stream2, OnCanWrite()).Times(0); + EXPECT_CALL(*send_algorithm, OnApplicationLimited(_)).Times(0); + + session_.OnCanWrite(); + EXPECT_TRUE(session_.WillingAndAbleToWrite()); +} + TEST_P(QuicSessionTestServer, BufferedHandshake) { EXPECT_FALSE(session_.HasPendingHandshake()); // Default value. @@ -642,6 +681,16 @@ } TEST_P(QuicSessionTestServer, OnCanWriteLimitsNumWritesIfFlowControlBlocked) { + FLAGS_quic_enable_app_limited_check = true; + + // Drive congestion control manually in order to ensure that + // application-limited signaling is handled correctly. + MockSendAlgorithm* send_algorithm = new StrictMock<MockSendAlgorithm>; + QuicConnectionPeer::SetSendAlgorithm(session_.connection(), kDefaultPathId, + send_algorithm); + EXPECT_CALL(*send_algorithm, TimeUntilSend(_, _)) + .WillRepeatedly(Return(QuicTime::Delta::Zero())); + // Ensure connection level flow control blockage. QuicFlowControllerPeer::SetSendWindowOffset(session_.flow_controller(), 0); EXPECT_TRUE(session_.flow_controller()->IsBlocked()); @@ -667,6 +716,10 @@ QuicSpdySessionPeer::SetHeadersStream(&session_, headers_stream); EXPECT_CALL(*headers_stream, OnCanWrite()); + // After the crypto and header streams perform a write, the connection will be + // blocked by the flow control, hence it should become application-limited. + EXPECT_CALL(*send_algorithm, OnApplicationLimited(_)); + session_.OnCanWrite(); EXPECT_FALSE(session_.WillingAndAbleToWrite()); } @@ -1127,7 +1180,7 @@ INSTANTIATE_TEST_CASE_P(Tests, QuicSessionTestClient, - ::testing::ValuesIn(QuicSupportedVersions())); + ::testing::ValuesIn(AllSupportedVersions())); TEST_P(QuicSessionTestClient, AvailableStreamsClient) { ASSERT_TRUE(session_.GetOrCreateDynamicStream(6) != nullptr);
diff --git a/net/quic/core/quic_spdy_session.h b/net/quic/core/quic_spdy_session.h index 0b28bdb6..0f92a20 100644 --- a/net/quic/core/quic_spdy_session.h +++ b/net/quic/core/quic_spdy_session.h
@@ -24,6 +24,7 @@ // A QUIC session with a headers stream. class NET_EXPORT_PRIVATE QuicSpdySession : public QuicSession { public: + // Does not take ownership of |connection|. QuicSpdySession(QuicConnection* connection, const QuicConfig& config); ~QuicSpdySession() override;
diff --git a/net/quic/core/quic_spdy_stream_test.cc b/net/quic/core/quic_spdy_stream_test.cc index ced5e17..cad7e8b 100644 --- a/net/quic/core/quic_spdy_stream_test.cc +++ b/net/quic/core/quic_spdy_stream_test.cc
@@ -125,7 +125,7 @@ INSTANTIATE_TEST_CASE_P(Tests, QuicSpdyStreamTest, - ::testing::ValuesIn(QuicSupportedVersions())); + ::testing::ValuesIn(AllSupportedVersions())); TEST_P(QuicSpdyStreamTest, ProcessHeaders) { Initialize(kShouldProcessData);
diff --git a/net/quic/core/quic_unacked_packet_map_test.cc b/net/quic/core/quic_unacked_packet_map_test.cc index dfd2759..c841806 100644 --- a/net/quic/core/quic_unacked_packet_map_test.cc +++ b/net/quic/core/quic_unacked_packet_map_test.cc
@@ -26,7 +26,7 @@ : unacked_packets_(), now_(QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(1000)) {} - ~QuicUnackedPacketMapTest() override { STLDeleteElements(&packets_); } + ~QuicUnackedPacketMapTest() override { base::STLDeleteElements(&packets_); } SerializedPacket CreateRetransmittablePacket(QuicPacketNumber packet_number) { return CreateRetransmittablePacketForStream(packet_number,
diff --git a/net/quic/core/quic_utils.cc b/net/quic/core/quic_utils.cc index 25cb2d4..f02adfc2 100644 --- a/net/quic/core/quic_utils.cc +++ b/net/quic/core/quic_utils.cc
@@ -381,6 +381,14 @@ return options; } +string QuicUtils::ListTags(QuicTagValueMap tag_map) { + string result; + for (auto entry : tag_map) { + result.append(TagToString(entry.first) + " "); + } + return result; +} + string QuicUtils::PeerAddressChangeTypeToString(PeerAddressChangeType type) { switch (type) { RETURN_STRING_LITERAL(NO_CHANGE);
diff --git a/net/quic/core/quic_utils.h b/net/quic/core/quic_utils.h index 8fe06d1..b80e845 100644 --- a/net/quic/core/quic_utils.h +++ b/net/quic/core/quic_utils.h
@@ -94,6 +94,9 @@ static QuicTagVector ParseQuicConnectionOptions( const std::string& connection_options); + // ListTags prints all of the tags in |tag_map| using TagToString. + static std::string ListTags(QuicTagValueMap tag_map); + // Returns PeerAddressChangeType as a std::string. static std::string PeerAddressChangeTypeToString(PeerAddressChangeType type);
diff --git a/net/quic/core/quic_utils_test.cc b/net/quic/core/quic_utils_test.cc index 57f57ff..1830bc7 100644 --- a/net/quic/core/quic_utils_test.cc +++ b/net/quic/core/quic_utils_test.cc
@@ -35,6 +35,13 @@ QuicUtils::TagToString(MakeQuicTag('C', 'H', 'L', '\x1f'))); } +TEST(QuicUtilsTest, ListTags) { + QuicTagValueMap map; + map.insert(std::make_pair(kSCFG, "asd")); + map.insert(std::make_pair(kCHLO, "dsa")); + EXPECT_EQ("SCFG CHLO ", QuicUtils::ListTags(map)); +} + TEST(QuicUtilsTest, ParseQuicConnectionOptions) { QuicTagVector empty_options = QuicUtils::ParseQuicConnectionOptions(""); EXPECT_EQ(0ul, empty_options.size());
diff --git a/net/quic/core/reliable_quic_stream_test.cc b/net/quic/core/reliable_quic_stream_test.cc index 18b9e16..15e09cbd 100644 --- a/net/quic/core/reliable_quic_stream_test.cc +++ b/net/quic/core/reliable_quic_stream_test.cc
@@ -74,7 +74,7 @@ ReliableQuicStreamTest() : initial_flow_control_window_bytes_(kMaxPacketSize), zero_(QuicTime::Delta::Zero()), - supported_versions_(QuicSupportedVersions()) { + supported_versions_(AllSupportedVersions()) { headers_[":host"] = "www.google.com"; headers_[":path"] = "/index.hml"; headers_[":scheme"] = "https";
diff --git a/net/quic/core/spdy_utils.cc b/net/quic/core/spdy_utils.cc index c6d6666..9ed8642 100644 --- a/net/quic/core/spdy_utils.cc +++ b/net/quic/core/spdy_utils.cc
@@ -47,7 +47,7 @@ return false; // Headers were invalid. } - if (ContainsKey(*headers, "content-length")) { + if (base::ContainsKey(*headers, "content-length")) { // Check whether multiple values are consistent. base::StringPiece content_length_header = (*headers)["content-length"]; vector<string> values = @@ -149,7 +149,7 @@ } } - if (ContainsKey(*headers, "content-length")) { + if (base::ContainsKey(*headers, "content-length")) { // Check whether multiple values are consistent. StringPiece content_length_header = (*headers)["content-length"]; vector<string> values =
diff --git a/net/quic/test_tools/crypto_test_utils.cc b/net/quic/test_tools/crypto_test_utils.cc index f285e254..8b0cf60 100644 --- a/net/quic/test_tools/crypto_test_utils.cc +++ b/net/quic/test_tools/crypto_test_utils.cc
@@ -20,6 +20,7 @@ #include "net/quic/core/crypto/channel_id.h" #include "net/quic/core/crypto/common_cert_set.h" #include "net/quic/core/crypto/crypto_handshake.h" +#include "net/quic/core/crypto/crypto_server_config_protobuf.h" #include "net/quic/core/crypto/quic_crypto_server_config.h" #include "net/quic/core/crypto/quic_decrypter.h" #include "net/quic/core/crypto/quic_encrypter.h" @@ -299,10 +300,11 @@ CryptoHandshakeMessage rej; crypto_config_->ProcessClientHello( result, /*reject_only=*/false, /*connection_id=*/1, server_ip_, - client_addr_, QuicSupportedVersions().front(), QuicSupportedVersions(), + client_addr_, AllSupportedVersions().front(), AllSupportedVersions(), /*use_stateless_rejects=*/true, /*server_designated_connection_id=*/0, clock_, QuicRandom::GetInstance(), compressed_certs_cache_, ¶ms, - proof_, &rej, &diversification_nonce, &error_details); + proof_, /*total_framing_overhead=*/50, kDefaultMaxPacketSize, &rej, + &diversification_nonce, &error_details); // Verify output is a REJ or SREJ. EXPECT_THAT(rej.tag(), testing::AnyOf(testing::Eq(kSREJ), testing::Eq(kREJ))); @@ -523,9 +525,8 @@ string cert_sct; std::unique_ptr<ProofSource> proof_source( CryptoTestUtils::ProofSourceForTesting()); - if (!proof_source->GetProof(server_ip, "", "", - QuicSupportedVersions().front(), "", &chain, &sig, - &cert_sct) || + if (!proof_source->GetProof(server_ip, "", "", AllSupportedVersions().front(), + "", &chain, &sig, &cert_sct) || chain->certs.empty()) { DCHECK(false) << "Proof generation failed"; return 0; @@ -883,6 +884,8 @@ StringPiece(stream_frame->data_buffer, stream_frame->data_length))); ASSERT_FALSE(crypto_visitor.error()); } + QuicConnectionPeer::SetCurrentPacket( + dest_conn, source_conn->encrypted_packets_[index]->AsStringPiece()); } *inout_packet_index = index; @@ -893,6 +896,58 @@ for (const CryptoHandshakeMessage& message : crypto_visitor.messages()) { dest_stream->OnHandshakeMessage(message); } + QuicConnectionPeer::SetCurrentPacket(dest_conn, StringPiece(nullptr, 0)); +} + +CryptoHandshakeMessage CryptoTestUtils::GenerateDefaultInchoateCHLO( + const QuicClock* clock, + QuicVersion version, + QuicCryptoServerConfig* crypto_config) { + // clang-format off + return CryptoTestUtils::Message( + "CHLO", + "PDMD", "X509", + "AEAD", "AESG", + "KEXS", "C255", + "PUBS", CryptoTestUtils::GenerateClientPublicValuesHex().c_str(), + "NONC", CryptoTestUtils::GenerateClientNonceHex(clock, + crypto_config).c_str(), + "VER\0", QuicUtils::TagToString( + QuicVersionToQuicTag(version)).c_str(), + "$padding", static_cast<int>(kClientHelloMinimumSize), + nullptr); + // clang-format on +} + +string CryptoTestUtils::GenerateClientNonceHex( + const QuicClock* clock, + QuicCryptoServerConfig* crypto_config) { + net::QuicCryptoServerConfig::ConfigOptions old_config_options; + net::QuicCryptoServerConfig::ConfigOptions new_config_options; + old_config_options.id = "old-config-id"; + delete crypto_config->AddDefaultConfig(net::QuicRandom::GetInstance(), clock, + old_config_options); + std::unique_ptr<QuicServerConfigProtobuf> primary_config( + crypto_config->GenerateConfig(net::QuicRandom::GetInstance(), clock, + new_config_options)); + primary_config->set_primary_time(clock->WallNow().ToUNIXSeconds()); + std::unique_ptr<net::CryptoHandshakeMessage> msg( + crypto_config->AddConfig(primary_config.get(), clock->WallNow())); + StringPiece orbit; + CHECK(msg->GetStringPiece(net::kORBT, &orbit)); + string nonce; + net::CryptoUtils::GenerateNonce( + clock->WallNow(), net::QuicRandom::GetInstance(), + StringPiece(reinterpret_cast<const char*>(orbit.data()), + sizeof(orbit.size())), + &nonce); + return ("#" + net::QuicUtils::HexEncode(nonce)); +} + +string CryptoTestUtils::GenerateClientPublicValuesHex() { + char public_value[32]; + memset(public_value, 42, sizeof(public_value)); + return ("#" + net::QuicUtils::HexEncode(public_value, sizeof(public_value))); } // static
diff --git a/net/quic/test_tools/crypto_test_utils.h b/net/quic/test_tools/crypto_test_utils.h index 22c6d5f..5c64abd1b 100644 --- a/net/quic/test_tools/crypto_test_utils.h +++ b/net/quic/test_tools/crypto_test_utils.h
@@ -205,6 +205,12 @@ PacketSavingConnection* dest_conn, Perspective dest_perspective); + // Return an inchoate CHLO with some basic tag value std:pairs. + static CryptoHandshakeMessage GenerateDefaultInchoateCHLO( + const QuicClock* clock, + QuicVersion version, + QuicCryptoServerConfig* crypto_config); + // Takes a inchoate CHLO, returns a full CHLO in |out| which can pass // |crypto_config|'s validation. static void GenerateFullCHLO(const CryptoHandshakeMessage& inchoate_chlo, @@ -221,6 +227,14 @@ static void CompareClientAndServerKeys(QuicCryptoClientStream* client, QuicCryptoServerStream* server); + // Return a CHLO nonce in hexadecimal. + static std::string GenerateClientNonceHex( + const QuicClock* clock, + QuicCryptoServerConfig* crypto_config); + + // Return a CHLO PUBS in hexadecimal. + static std::string GenerateClientPublicValuesHex(); + DISALLOW_COPY_AND_ASSIGN(CryptoTestUtils); };
diff --git a/net/quic/test_tools/crypto_test_utils_test.cc b/net/quic/test_tools/crypto_test_utils_test.cc index a2524a7..52c0759 100644 --- a/net/quic/test_tools/crypto_test_utils_test.cc +++ b/net/quic/test_tools/crypto_test_utils_test.cc
@@ -41,10 +41,11 @@ CryptoHandshakeMessage out; crypto_config_->ProcessClientHello( result, /*reject_only=*/false, /*connection_id=*/1, server_ip_, - client_addr_, QuicSupportedVersions().front(), QuicSupportedVersions(), + client_addr_, AllSupportedVersions().front(), AllSupportedVersions(), /*use_stateless_rejects=*/true, /*server_designated_connection_id=*/0, clock_, QuicRandom::GetInstance(), compressed_certs_cache_, ¶ms, - proof_, &out, &diversification_nonce, &error_details); + proof_, /*total_framing_overhead=*/50, kDefaultMaxPacketSize, &out, + &diversification_nonce, &error_details); // Verify output is a SHLO. EXPECT_EQ(out.tag(), kSHLO) << "Fail to pass validation. Get " << out.DebugString(); @@ -97,7 +98,7 @@ string pub_hex = "#" + QuicUtils::HexEncode(public_value, sizeof(public_value)); - QuicVersion version(QuicSupportedVersions().front()); + QuicVersion version(AllSupportedVersions().front()); // clang-format off CryptoHandshakeMessage inchoate_chlo = CryptoTestUtils::Message( "CHLO",
diff --git a/net/quic/test_tools/quic_buffered_packet_store_peer.cc b/net/quic/test_tools/quic_buffered_packet_store_peer.cc new file mode 100644 index 0000000..d4db6866 --- /dev/null +++ b/net/quic/test_tools/quic_buffered_packet_store_peer.cc
@@ -0,0 +1,25 @@ +// Copyright 2016 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/test_tools/quic_buffered_packet_store_peer.h" + +#include "net/quic/core/quic_buffered_packet_store.h" + +namespace net { +namespace test { + +// static +QuicAlarm* QuicBufferedPacketStorePeer::expiration_alarm( + QuicBufferedPacketStore* store) { + return store->expiration_alarm_.get(); +} + +// static +void QuicBufferedPacketStorePeer::set_clock(QuicBufferedPacketStore* store, + const QuicClock* clock) { + store->clock_ = clock; +} + +} // namespace test +} // namespace net
diff --git a/net/quic/test_tools/quic_buffered_packet_store_peer.h b/net/quic/test_tools/quic_buffered_packet_store_peer.h new file mode 100644 index 0000000..efa4b034 --- /dev/null +++ b/net/quic/test_tools/quic_buffered_packet_store_peer.h
@@ -0,0 +1,33 @@ +// Copyright 2016 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 NET_QUIC_TEST_TOOLS_QUIC_BUFFERED_PACKET_STORE_PEER_H_ +#define NET_QUIC_TEST_TOOLS_QUIC_BUFFERED_PACKET_STORE_PEER_H_ + +#include <memory> + +#include "net/quic/core/quic_alarm.h" +#include "net/quic/core/quic_clock.h" + +namespace net { + +class QuicBufferedPacketStore; + +namespace test { + +class QuicBufferedPacketStorePeer { + public: + static QuicAlarm* expiration_alarm(QuicBufferedPacketStore* store); + + static void set_clock(QuicBufferedPacketStore* store, const QuicClock* clock); + + private: + DISALLOW_COPY_AND_ASSIGN(QuicBufferedPacketStorePeer); +}; + +} // namespace test + +} // namespace net + +#endif // NET_QUIC_TEST_TOOLS_QUIC_BUFFERED_PACKET_STORE_PEER_H_
diff --git a/net/quic/test_tools/quic_connection_peer.cc b/net/quic/test_tools/quic_connection_peer.cc index fd2a3afe..24118dd 100644 --- a/net/quic/test_tools/quic_connection_peer.cc +++ b/net/quic/test_tools/quic_connection_peer.cc
@@ -26,9 +26,7 @@ QuicConnection* connection, QuicPathId path_id, SendAlgorithmInterface* send_algorithm) { - GetSentPacketManager(connection, path_id) - ->send_algorithm_.reset(send_algorithm); - GetSentPacketManager(connection, path_id)->using_inline_pacing_ = false; + GetSentPacketManager(connection, path_id)->SetSendAlgorithm(send_algorithm); } // static @@ -36,8 +34,7 @@ QuicConnection* connection, QuicPathId path_id, LossDetectionInterface* loss_algorithm) { - GetSentPacketManager(connection, path_id) - ->loss_algorithm_.reset(loss_algorithm); + GetSentPacketManager(connection, path_id)->loss_algorithm_ = loss_algorithm; } // static @@ -161,6 +158,13 @@ } // static +void QuicConnectionPeer::SetCurrentPacket(QuicConnection* connection, + base::StringPiece current_packet) { + connection->current_packet_data_ = current_packet.data(); + connection->last_size_ = current_packet.size(); +} + +// static QuicConnectionHelperInterface* QuicConnectionPeer::GetHelper( QuicConnection* connection) { return connection->helper_;
diff --git a/net/quic/test_tools/quic_connection_peer.h b/net/quic/test_tools/quic_connection_peer.h index 7b8c7dd..dc35c9e9 100644 --- a/net/quic/test_tools/quic_connection_peer.h +++ b/net/quic/test_tools/quic_connection_peer.h
@@ -91,6 +91,9 @@ static void SwapCrypters(QuicConnection* connection, QuicFramer* framer); + static void SetCurrentPacket(QuicConnection* connection, + base::StringPiece current_packet); + static QuicConnectionHelperInterface* GetHelper(QuicConnection* connection); static QuicAlarmFactory* GetAlarmFactory(QuicConnection* connection);
diff --git a/net/quic/test_tools/quic_framer_peer.cc b/net/quic/test_tools/quic_framer_peer.cc index 25e281f..42bd17c 100644 --- a/net/quic/test_tools/quic_framer_peer.cc +++ b/net/quic/test_tools/quic_framer_peer.cc
@@ -78,7 +78,7 @@ // static bool QuicFramerPeer::IsPathClosed(QuicFramer* framer, QuicPathId path_id) { - return ContainsKey(framer->closed_paths_, path_id); + return base::ContainsKey(framer->closed_paths_, path_id); } } // namespace test
diff --git a/net/quic/test_tools/quic_sent_packet_manager_peer.cc b/net/quic/test_tools/quic_sent_packet_manager_peer.cc index b3ad0b5..572f7da0 100644 --- a/net/quic/test_tools/quic_sent_packet_manager_peer.cc +++ b/net/quic/test_tools/quic_sent_packet_manager_peer.cc
@@ -68,21 +68,20 @@ void QuicSentPacketManagerPeer::SetSendAlgorithm( QuicSentPacketManager* sent_packet_manager, SendAlgorithmInterface* send_algorithm) { - sent_packet_manager->send_algorithm_.reset(send_algorithm); - sent_packet_manager->using_inline_pacing_ = false; + sent_packet_manager->SetSendAlgorithm(send_algorithm); } // static const LossDetectionInterface* QuicSentPacketManagerPeer::GetLossAlgorithm( QuicSentPacketManager* sent_packet_manager) { - return sent_packet_manager->loss_algorithm_.get(); + return sent_packet_manager->loss_algorithm_; } // static void QuicSentPacketManagerPeer::SetLossAlgorithm( QuicSentPacketManager* sent_packet_manager, LossDetectionInterface* loss_detector) { - sent_packet_manager->loss_algorithm_.reset(loss_detector); + sent_packet_manager->loss_algorithm_ = loss_detector; } // static
diff --git a/net/quic/test_tools/quic_session_peer.cc b/net/quic/test_tools/quic_session_peer.cc index 169fe462..b4d49f7 100644 --- a/net/quic/test_tools/quic_session_peer.cc +++ b/net/quic/test_tools/quic_session_peer.cc
@@ -87,13 +87,13 @@ // static bool QuicSessionPeer::IsStreamCreated(QuicSession* session, QuicStreamId id) { DCHECK_NE(0u, id); - return ContainsKey(session->dynamic_streams(), id); + return base::ContainsKey(session->dynamic_streams(), id); } // static bool QuicSessionPeer::IsStreamAvailable(QuicSession* session, QuicStreamId id) { DCHECK_NE(0u, id); - return ContainsKey(session->available_streams_, id); + return base::ContainsKey(session->available_streams_, id); } // static
diff --git a/net/quic/test_tools/quic_stream_factory_peer.cc b/net/quic/test_tools/quic_stream_factory_peer.cc index afeeb11..4b3e9ccf 100644 --- a/net/quic/test_tools/quic_stream_factory_peer.cc +++ b/net/quic/test_tools/quic_stream_factory_peer.cc
@@ -147,8 +147,8 @@ bool QuicStreamFactoryPeer::SupportsQuicAtStartUp(QuicStreamFactory* factory, HostPortPair host_port_pair) { - return ContainsKey(factory->quic_supported_servers_at_startup_, - host_port_pair); + return base::ContainsKey(factory->quic_supported_servers_at_startup_, + host_port_pair); } bool QuicStreamFactoryPeer::CryptoConfigCacheIsEmpty(
diff --git a/net/quic/test_tools/quic_test_utils.cc b/net/quic/test_tools/quic_test_utils.cc index d447126..6069fa3 100644 --- a/net/quic/test_tools/quic_test_utils.cc +++ b/net/quic/test_tools/quic_test_utils.cc
@@ -251,7 +251,7 @@ helper, alarm_factory, perspective, - QuicSupportedVersions()) {} + AllSupportedVersions()) {} MockQuicConnection::MockQuicConnection(IPEndPoint address, MockQuicConnectionHelper* helper, @@ -262,7 +262,7 @@ helper, alarm_factory, perspective, - QuicSupportedVersions()) {} + AllSupportedVersions()) {} MockQuicConnection::MockQuicConnection(QuicConnectionId connection_id, MockQuicConnectionHelper* helper, @@ -273,7 +273,7 @@ helper, alarm_factory, perspective, - QuicSupportedVersions()) {} + CurrentSupportedVersions()) {} MockQuicConnection::MockQuicConnection( MockQuicConnectionHelper* helper, @@ -329,7 +329,7 @@ supported_versions) {} PacketSavingConnection::~PacketSavingConnection() { - STLDeleteElements(&encrypted_packets_); + base::STLDeleteElements(&encrypted_packets_); } void PacketSavingConnection::SendOrQueuePacket(SerializedPacket* packet) { @@ -350,7 +350,9 @@ .WillByDefault(testing::Return(QuicConsumedData(0, false))); } -MockQuicSession::~MockQuicSession() {} +MockQuicSession::~MockQuicSession() { + delete connection(); +} // static QuicConsumedData MockQuicSession::ConsumeAllData( @@ -371,7 +373,9 @@ .WillByDefault(testing::Return(QuicConsumedData(0, false))); } -MockQuicSpdySession::~MockQuicSpdySession() {} +MockQuicSpdySession::~MockQuicSpdySession() { + delete connection(); +} TestQuicSpdyServerSession::TestQuicSpdyServerSession( QuicConnection* connection, @@ -392,7 +396,9 @@ .WillByDefault(testing::Return(true)); } -TestQuicSpdyServerSession::~TestQuicSpdyServerSession() {} +TestQuicSpdyServerSession::~TestQuicSpdyServerSession() { + delete connection(); +} QuicCryptoServerStreamBase* TestQuicSpdyServerSession::CreateQuicCryptoServerStream( @@ -502,11 +508,11 @@ } QuicVersion QuicVersionMax() { - return QuicSupportedVersions().front(); + return AllSupportedVersions().front(); } QuicVersion QuicVersionMin() { - return QuicSupportedVersions().back(); + return AllSupportedVersions().back(); } IPAddress Loopback4() { @@ -601,8 +607,9 @@ QuicFrame frame(&stream_frame); QuicFrames frames; frames.push_back(frame); - QuicFramer framer(versions != nullptr ? *versions : QuicSupportedVersions(), - QuicTime::Zero(), perspective); + QuicFramer framer( + versions != nullptr ? *versions : CurrentSupportedVersions(), + QuicTime::Zero(), perspective); std::unique_ptr<QuicPacket> packet( BuildUnsizedDataPacket(&framer, header, frames)); @@ -651,7 +658,7 @@ QuicFrame frame(&stream_frame); QuicFrames frames; frames.push_back(frame); - QuicFramer framer(versions != nullptr ? *versions : QuicSupportedVersions(), + QuicFramer framer(versions != nullptr ? *versions : AllSupportedVersions(), QuicTime::Zero(), perspective); std::unique_ptr<QuicPacket> packet( @@ -730,7 +737,7 @@ CryptoFramer crypto_framer; std::unique_ptr<QuicData> data( crypto_framer.ConstructHandshakeMessage(message)); - QuicFramer quic_framer(QuicSupportedVersions(), QuicTime::Zero(), + QuicFramer quic_framer(AllSupportedVersions(), QuicTime::Zero(), Perspective::IS_CLIENT); QuicPacketHeader header;
diff --git a/net/quic/test_tools/quic_test_utils.h b/net/quic/test_tools/quic_test_utils.h index edf176ee..32f4eb9 100644 --- a/net/quic/test_tools/quic_test_utils.h +++ b/net/quic/test_tools/quic_test_utils.h
@@ -76,7 +76,7 @@ void GenerateBody(std::string* body, int length); // Create an encrypted packet for testing. -// If versions == nullptr, uses &QuicSupportedVersions(). +// If versions == nullptr, uses &AllSupportedVersions(). // Note that the packet is encrypted with NullEncrypter, so to decrypt the // constructed packet, the framer must be set to use NullDecrypter. QuicEncryptedPacket* ConstructEncryptedPacket( @@ -93,7 +93,7 @@ Perspective perspective); // Create an encrypted packet for testing. -// If versions == nullptr, uses &QuicSupportedVersions(). +// If versions == nullptr, uses &AllSupportedVersions(). // Note that the packet is encrypted with NullEncrypter, so to decrypt the // constructed packet, the framer must be set to use NullDecrypter. QuicEncryptedPacket* ConstructEncryptedPacket( @@ -498,6 +498,7 @@ class MockQuicSession : public QuicSession { public: + // Takes ownership of |connection|. explicit MockQuicSession(QuicConnection* connection); ~MockQuicSession() override; @@ -554,6 +555,7 @@ class MockQuicSpdySession : public QuicSpdySession { public: + // Takes ownership of |connection|. explicit MockQuicSpdySession(QuicConnection* connection); ~MockQuicSpdySession() override; @@ -640,6 +642,7 @@ class TestQuicSpdyServerSession : public QuicServerSessionBase { public: + // Takes ownership of |connection|. TestQuicSpdyServerSession(QuicConnection* connection, const QuicConfig& config, const QuicCryptoServerConfig* crypto_config, @@ -750,12 +753,14 @@ MOCK_METHOD1(OnRttUpdated, void(QuicPacketNumber)); MOCK_CONST_METHOD0(RetransmissionDelay, QuicTime::Delta(void)); MOCK_CONST_METHOD0(GetCongestionWindow, QuicByteCount()); + MOCK_CONST_METHOD0(GetDebugState, std::string()); MOCK_CONST_METHOD0(InSlowStart, bool()); MOCK_CONST_METHOD0(InRecovery, bool()); MOCK_CONST_METHOD0(GetSlowStartThreshold, QuicByteCount()); MOCK_CONST_METHOD0(GetCongestionControlType, CongestionControlType()); MOCK_METHOD2(ResumeConnectionState, void(const CachedNetworkParameters&, bool)); + MOCK_METHOD1(OnApplicationLimited, void(QuicByteCount)); private: DISALLOW_COPY_AND_ASSIGN(MockSendAlgorithm); @@ -938,6 +943,7 @@ QuicPacketCount(QuicByteCount)); MOCK_CONST_METHOD0(GetCongestionWindowInBytes, QuicByteCount(void)); MOCK_CONST_METHOD0(GetSlowStartThresholdInTcpMss, QuicPacketCount(void)); + MOCK_CONST_METHOD0(GetDebugState, std::string()); MOCK_METHOD1(CancelRetransmissionsForStream, void(QuicStreamId)); MOCK_METHOD2(OnConnectionMigration, void(QuicPathId, PeerAddressChangeType)); MOCK_CONST_METHOD0(IsHandshakeConfirmed, bool(void)); @@ -949,6 +955,7 @@ MOCK_CONST_METHOD0(InSlowStart, bool(void)); MOCK_CONST_METHOD0(GetConsecutiveRtoCount, size_t(void)); MOCK_CONST_METHOD0(GetConsecutiveTlpCount, size_t(void)); + MOCK_METHOD0(OnApplicationLimited, void(void)); }; class MockConnectionCloseDelegate
diff --git a/net/quic/test_tools/simple_quic_framer.cc b/net/quic/test_tools/simple_quic_framer.cc index 2290417..2dcd179 100644 --- a/net/quic/test_tools/simple_quic_framer.cc +++ b/net/quic/test_tools/simple_quic_framer.cc
@@ -23,8 +23,8 @@ SimpleFramerVisitor() : error_(QUIC_NO_ERROR) {} ~SimpleFramerVisitor() override { - STLDeleteElements(&stream_frames_); - STLDeleteElements(&stream_data_); + base::STLDeleteElements(&stream_frames_); + base::STLDeleteElements(&stream_data_); } void OnError(QuicFramer* framer) override { error_ = framer->error(); } @@ -163,7 +163,7 @@ }; SimpleQuicFramer::SimpleQuicFramer() - : framer_(QuicSupportedVersions(), + : framer_(AllSupportedVersions(), QuicTime::Zero(), Perspective::IS_SERVER) {}
diff --git a/net/server/http_server.cc b/net/server/http_server.cc index ecda0170..08d0706 100644 --- a/net/server/http_server.cc +++ b/net/server/http_server.cc
@@ -45,8 +45,8 @@ } HttpServer::~HttpServer() { - STLDeleteContainerPairSecondPointers( - id_to_connection_.begin(), id_to_connection_.end()); + base::STLDeleteContainerPairSecondPointers(id_to_connection_.begin(), + id_to_connection_.end()); } void HttpServer::AcceptWebSocket(
diff --git a/net/socket/client_socket_pool_base.cc b/net/socket/client_socket_pool_base.cc index 9a9a166..43007d7 100644 --- a/net/socket/client_socket_pool_base.cc +++ b/net/socket/client_socket_pool_base.cc
@@ -240,7 +240,7 @@ void ClientSocketPoolBaseHelper::AddLowerLayeredPool( LowerLayeredPool* lower_pool) { DCHECK(pool_); - CHECK(!ContainsKey(lower_pools_, lower_pool)); + CHECK(!base::ContainsKey(lower_pools_, lower_pool)); lower_pools_.insert(lower_pool); lower_pool->AddHigherLayeredPool(pool_); } @@ -248,14 +248,14 @@ void ClientSocketPoolBaseHelper::AddHigherLayeredPool( HigherLayeredPool* higher_pool) { CHECK(higher_pool); - CHECK(!ContainsKey(higher_pools_, higher_pool)); + CHECK(!base::ContainsKey(higher_pools_, higher_pool)); higher_pools_.insert(higher_pool); } void ClientSocketPoolBaseHelper::RemoveHigherLayeredPool( HigherLayeredPool* higher_pool) { CHECK(higher_pool); - CHECK(ContainsKey(higher_pools_, higher_pool)); + CHECK(base::ContainsKey(higher_pools_, higher_pool)); higher_pools_.erase(higher_pool); } @@ -322,11 +322,11 @@ rv = RequestSocketInternal(group_name, request); if (rv < 0 && rv != ERR_IO_PENDING) { // We're encountering a synchronous error. Give up. - if (!ContainsKey(group_map_, group_name)) + if (!base::ContainsKey(group_map_, group_name)) deleted_group = true; break; } - if (!ContainsKey(group_map_, group_name)) { + if (!base::ContainsKey(group_map_, group_name)) { // Unexpected. The group should only be getting deleted on synchronous // error. NOTREACHED(); @@ -522,7 +522,7 @@ return; } - CHECK(ContainsKey(group_map_, group_name)); + CHECK(base::ContainsKey(group_map_, group_name)); Group* group = GetOrCreateGroup(group_name); @@ -544,7 +544,7 @@ } bool ClientSocketPoolBaseHelper::HasGroup(const std::string& group_name) const { - return ContainsKey(group_map_, group_name); + return base::ContainsKey(group_map_, group_name); } void ClientSocketPoolBaseHelper::CloseIdleSockets() { @@ -563,7 +563,7 @@ LoadState ClientSocketPoolBaseHelper::GetLoadState( const std::string& group_name, const ClientSocketHandle* handle) const { - if (ContainsKey(pending_callback_map_, handle)) + if (base::ContainsKey(pending_callback_map_, handle)) return LOAD_STATE_CONNECTING; GroupMap::const_iterator group_it = group_map_.find(group_name); @@ -928,7 +928,7 @@ void ClientSocketPoolBaseHelper::OnAvailableSocketSlot( const std::string& group_name, Group* group) { - DCHECK(ContainsKey(group_map_, group_name)); + DCHECK(base::ContainsKey(group_map_, group_name)); if (group->IsEmpty()) { RemoveGroup(group_name); } else if (group->has_pending_requests()) { @@ -1110,7 +1110,7 @@ void ClientSocketPoolBaseHelper::InvokeUserCallbackLater( ClientSocketHandle* handle, const CompletionCallback& callback, int rv) { - CHECK(!ContainsKey(pending_callback_map_, handle)); + CHECK(!base::ContainsKey(pending_callback_map_, handle)); pending_callback_map_[handle] = CallbackResultPair(callback, rv); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind(&ClientSocketPoolBaseHelper::InvokeUserCallback, @@ -1246,7 +1246,7 @@ SanityCheck(); // Delete active jobs. - STLDeleteElements(&jobs_); + base::STLDeleteElements(&jobs_); unassigned_job_count_ = 0; // Stop backup job timer.
diff --git a/net/socket/client_socket_pool_manager_impl.cc b/net/socket/client_socket_pool_manager_impl.cc index 305f05e..69569355 100644 --- a/net/socket/client_socket_pool_manager_impl.cc +++ b/net/socket/client_socket_pool_manager_impl.cc
@@ -212,11 +212,13 @@ const HostPortPair& socks_proxy) { SOCKSSocketPoolMap::const_iterator it = socks_socket_pools_.find(socks_proxy); if (it != socks_socket_pools_.end()) { - DCHECK(ContainsKey(transport_socket_pools_for_socks_proxies_, socks_proxy)); + DCHECK(base::ContainsKey(transport_socket_pools_for_socks_proxies_, + socks_proxy)); return it->second; } - DCHECK(!ContainsKey(transport_socket_pools_for_socks_proxies_, socks_proxy)); + DCHECK(!base::ContainsKey(transport_socket_pools_for_socks_proxies_, + socks_proxy)); int sockets_per_proxy_server = max_sockets_per_proxy_server(pool_type_); int sockets_per_group = std::min(sockets_per_proxy_server, max_sockets_per_group(pool_type_)); @@ -245,15 +247,19 @@ HTTPProxySocketPoolMap::const_iterator it = http_proxy_socket_pools_.find(http_proxy); if (it != http_proxy_socket_pools_.end()) { - DCHECK(ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy)); - DCHECK(ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy)); - DCHECK(ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy)); + DCHECK(base::ContainsKey(transport_socket_pools_for_http_proxies_, + http_proxy)); + DCHECK(base::ContainsKey(transport_socket_pools_for_https_proxies_, + http_proxy)); + DCHECK(base::ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy)); return it->second; } - DCHECK(!ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy)); - DCHECK(!ContainsKey(transport_socket_pools_for_https_proxies_, http_proxy)); - DCHECK(!ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy)); + DCHECK( + !base::ContainsKey(transport_socket_pools_for_http_proxies_, http_proxy)); + DCHECK(!base::ContainsKey(transport_socket_pools_for_https_proxies_, + http_proxy)); + DCHECK(!base::ContainsKey(ssl_socket_pools_for_https_proxies_, http_proxy)); int sockets_per_proxy_server = max_sockets_per_proxy_server(pool_type_); int sockets_per_group = std::min(sockets_per_proxy_server,
diff --git a/net/socket/client_socket_pool_manager_impl.h b/net/socket/client_socket_pool_manager_impl.h index 3fae145..e243e31 100644 --- a/net/socket/client_socket_pool_manager_impl.h +++ b/net/socket/client_socket_pool_manager_impl.h
@@ -44,9 +44,7 @@ static_assert(std::is_pointer<Value>::value, "value must be a pointer"); } - ~OwnedPoolMap() { - STLDeleteValues(this); - } + ~OwnedPoolMap() { base::STLDeleteValues(this); } }; } // namespace internal
diff --git a/net/socket/fuzzed_socket_factory.cc b/net/socket/fuzzed_socket_factory.cc index f77e36e..8b06c92 100644 --- a/net/socket/fuzzed_socket_factory.cc +++ b/net/socket/fuzzed_socket_factory.cc
@@ -99,10 +99,6 @@ // SSLClientSocket implementation: void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {} - NextProtoStatus GetNextProto(std::string* proto) const override { - return NextProtoStatus::kNextProtoUnsupported; - } - ChannelIDService* GetChannelIDService() const override { NOTREACHED(); return nullptr;
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc index 57cc360..ff3af38 100644 --- a/net/socket/socket_test_util.cc +++ b/net/socket/socket_test_util.cc
@@ -282,7 +282,7 @@ SSLSocketDataProvider::SSLSocketDataProvider(IoMode mode, int result) : connect(mode, result), - next_proto_status(SSLClientSocket::kNextProtoUnsupported), + next_proto(kProtoUnknown), client_cert_sent(false), cert_request_info(NULL), channel_id_sent(false), @@ -300,11 +300,6 @@ SSLSocketDataProvider::~SSLSocketDataProvider() { } -void SSLSocketDataProvider::SetNextProto(NextProto proto) { - next_proto_status = SSLClientSocket::kNextProtoNegotiated; - next_proto = SSLClientSocket::NextProtoToString(proto); -} - SequencedSocketData::SequencedSocketData(MockRead* reads, size_t reads_count, MockWrite* writes, @@ -802,6 +797,14 @@ return net_log_; } +bool MockClientSocket::WasNpnNegotiated() const { + return false; +} + +NextProto MockClientSocket::GetNegotiatedProtocol() const { + return kProtoUnknown; +} + void MockClientSocket::GetConnectionAttempts(ConnectionAttempts* out) const { out->clear(); } @@ -840,12 +843,6 @@ return NULL; } -SSLClientSocket::NextProtoStatus MockClientSocket::GetNextProto( - std::string* proto) const { - proto->clear(); - return SSLClientSocket::kNextProtoUnsupported; -} - MockClientSocket::~MockClientSocket() {} void MockClientSocket::RunCallbackAsync(const CompletionCallback& callback, @@ -1029,10 +1026,6 @@ data_->OnEnableTCPFastOpenIfSupported(); } -bool MockTCPClientSocket::WasNpnNegotiated() const { - return false; -} - bool MockTCPClientSocket::GetSSLInfo(SSLInfo* ssl_info) { return false; } @@ -1200,6 +1193,14 @@ return transport_->socket()->GetPeerAddress(address); } +bool MockSSLClientSocket::WasNpnNegotiated() const { + return data_->next_proto != kProtoUnknown; +} + +NextProto MockSSLClientSocket::GetNegotiatedProtocol() const { + return data_->next_proto; +} + bool MockSSLClientSocket::GetSSLInfo(SSLInfo* ssl_info) { ssl_info->Reset(); ssl_info->cert = data_->cert; @@ -1223,12 +1224,6 @@ } } -SSLClientSocket::NextProtoStatus MockSSLClientSocket::GetNextProto( - std::string* proto) const { - *proto = data_->next_proto; - return data_->next_proto_status; -} - ChannelIDService* MockSSLClientSocket::GetChannelIDService() const { return data_->channel_id_service; }
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h index de8ba34..5bc8688 100644 --- a/net/socket/socket_test_util.h +++ b/net/socket/socket_test_util.h
@@ -354,11 +354,8 @@ SSLSocketDataProvider(const SSLSocketDataProvider& other); ~SSLSocketDataProvider(); - void SetNextProto(NextProto proto); - MockConnect connect; - SSLClientSocket::NextProtoStatus next_proto_status; - std::string next_proto; + NextProto next_proto; NextProtoVector next_protos_expected_in_ssl_config; bool client_cert_sent; SSLCertRequestInfo* cert_request_info; @@ -571,6 +568,8 @@ const BoundNetLog& NetLog() const override; void SetSubresourceSpeculation() override {} void SetOmniboxSpeculation() override {} + bool WasNpnNegotiated() const override; + NextProto GetNegotiatedProtocol() const override; void GetConnectionAttempts(ConnectionAttempts* out) const override; void ClearConnectionAttempts() override {} void AddConnectionAttempts(const ConnectionAttempts& attempts) override {} @@ -583,7 +582,6 @@ const base::StringPiece& context, unsigned char* out, unsigned int outlen) override; - NextProtoStatus GetNextProto(std::string* proto) const override; ChannelIDService* GetChannelIDService() const override; Error GetSignedEKMForTokenBinding(crypto::ECPrivateKey* key, std::vector<uint8_t>* out) override; @@ -633,7 +631,6 @@ int GetPeerAddress(IPEndPoint* address) const override; bool WasEverUsed() const override; void EnableTCPFastOpenIfSupported() override; - bool WasNpnNegotiated() const override; bool GetSSLInfo(SSLInfo* ssl_info) override; void GetConnectionAttempts(ConnectionAttempts* out) const override; void ClearConnectionAttempts() override; @@ -696,14 +693,14 @@ bool IsConnectedAndIdle() const override; bool WasEverUsed() const override; int GetPeerAddress(IPEndPoint* address) const override; + bool WasNpnNegotiated() const override; + NextProto GetNegotiatedProtocol() const override; bool GetSSLInfo(SSLInfo* ssl_info) override; // SSLClientSocket implementation. void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override; Error GetSignedEKMForTokenBinding(crypto::ECPrivateKey* key, std::vector<uint8_t>* out) override; - NextProtoStatus GetNextProto(std::string* proto) const override; - // This MockSocket does not implement the manual async IO feature. void OnReadComplete(const MockRead& data) override; void OnWriteComplete(int rv) override;
diff --git a/net/socket/ssl_client_socket.cc b/net/socket/ssl_client_socket.cc index 833bc3d..c524ae4 100644 --- a/net/socket/ssl_client_socket.cc +++ b/net/socket/ssl_client_socket.cc
@@ -4,9 +4,11 @@ #include "net/socket/ssl_client_socket.h" +#include "base/feature_list.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/sparse_histogram.h" #include "base/strings/string_util.h" +#include "build/build_config.h" #include "crypto/ec_private_key.h" #include "net/base/net_errors.h" #include "net/socket/ssl_client_socket_impl.h" @@ -15,15 +17,19 @@ namespace net { +namespace { +#if !defined(OS_NACL) +const base::Feature kPostQuantumExperiment{"SSLPostQuantumExperiment", + base::FEATURE_DISABLED_BY_DEFAULT}; +#endif +} // namespace + SSLClientSocket::SSLClientSocket() : signed_cert_timestamps_received_(false), - stapled_ocsp_response_received_(false), - negotiation_extension_(kExtensionUnknown) { -} + stapled_ocsp_response_received_(false) {} // static -NextProto SSLClientSocket::NextProtoFromString( - const std::string& proto_string) { +NextProto SSLClientSocket::NextProtoFromString(base::StringPiece proto_string) { if (proto_string == "http1.1" || proto_string == "http/1.1") { return kProtoHTTP11; } else if (proto_string == "h2") { @@ -75,18 +81,6 @@ #endif } -bool SSLClientSocket::WasNpnNegotiated() const { - std::string unused_proto; - return GetNextProto(&unused_proto) == kNextProtoNegotiated; -} - -NextProto SSLClientSocket::GetNegotiatedProtocol() const { - std::string proto; - if (GetNextProto(&proto) != kNextProtoNegotiated) - return kProtoUnknown; - return NextProtoFromString(proto); -} - bool SSLClientSocket::IgnoreCertError(int error, int load_flags) { if (error == OK) return true; @@ -94,65 +88,13 @@ IsCertificateError(error); } -void SSLClientSocket::RecordNegotiationExtension() { - if (negotiation_extension_ == kExtensionUnknown) - return; - std::string proto; - SSLClientSocket::NextProtoStatus status = GetNextProto(&proto); - if (status == kNextProtoUnsupported) - return; - // Convert protocol into numerical value for histogram. - NextProto protocol_negotiated = SSLClientSocket::NextProtoFromString(proto); - base::HistogramBase::Sample sample = - static_cast<base::HistogramBase::Sample>(protocol_negotiated); - // In addition to the protocol negotiated, we want to record which TLS - // extension was used, and in case of NPN, whether there was overlap between - // server and client list of supported protocols. - if (negotiation_extension_ == kExtensionNPN) { - if (status == kNextProtoNoOverlap) { - sample += 1000; - } else { - sample += 500; - } - } else { - DCHECK_EQ(kExtensionALPN, negotiation_extension_); - } - UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSLProtocolNegotiation", sample); -} - // static -void SSLClientSocket::RecordChannelIDSupport( - ChannelIDService* channel_id_service, - bool negotiated_channel_id, - bool channel_id_enabled) { - // Since this enum is used for a histogram, do not change or re-use values. - enum { - DISABLED = 0, - CLIENT_ONLY = 1, - CLIENT_AND_SERVER = 2, - // CLIENT_NO_ECC is unused now. - // CLIENT_BAD_SYSTEM_TIME is unused now. - CLIENT_BAD_SYSTEM_TIME = 4, - CLIENT_NO_CHANNEL_ID_SERVICE = 5, - CHANNEL_ID_USAGE_MAX - } supported = DISABLED; - if (negotiated_channel_id) { - supported = CLIENT_AND_SERVER; - } else if (channel_id_enabled) { - if (!channel_id_service) - supported = CLIENT_NO_CHANNEL_ID_SERVICE; - else - supported = CLIENT_ONLY; - } - UMA_HISTOGRAM_ENUMERATION("DomainBoundCerts.Support", supported, - CHANNEL_ID_USAGE_MAX); -} - -// static -bool SSLClientSocket::IsChannelIDEnabled( - const SSLConfig& ssl_config, - ChannelIDService* channel_id_service) { - return ssl_config.channel_id_enabled && channel_id_service; +bool SSLClientSocket::IsPostQuantumExperimentEnabled() { +#if !defined(OS_NACL) + return base::FeatureList::IsEnabled(kPostQuantumExperiment); +#else + return false; +#endif } // static
diff --git a/net/socket/ssl_client_socket.h b/net/socket/ssl_client_socket.h index 494c6cbf..4bf6a084 100644 --- a/net/socket/ssl_client_socket.h +++ b/net/socket/ssl_client_socket.h
@@ -10,6 +10,7 @@ #include <string> #include "base/gtest_prod_util.h" +#include "base/strings/string_piece.h" #include "net/base/completion_callback.h" #include "net/base/load_flags.h" #include "net/base/net_errors.h" @@ -94,25 +95,12 @@ kExtensionNPN, }; - // StreamSocket: - bool WasNpnNegotiated() const override; - NextProto GetNegotiatedProtocol() const override; - // Gets the SSL CertificateRequest info of the socket after Connect failed // with ERR_SSL_CLIENT_AUTH_CERT_NEEDED. virtual void GetSSLCertRequestInfo( SSLCertRequestInfo* cert_request_info) = 0; - // Get the application level protocol that we negotiated with the server. - // *proto is set to the resulting protocol (n.b. that the string may have - // embedded NULs). - // kNextProtoUnsupported: *proto is cleared. - // kNextProtoNegotiated: *proto is set to the negotiated protocol. - // kNextProtoNoOverlap: *proto is set to the first protocol in the - // supported list. - virtual NextProtoStatus GetNextProto(std::string* proto) const = 0; - - static NextProto NextProtoFromString(const std::string& proto_string); + static NextProto NextProtoFromString(base::StringPiece proto_string); static const char* NextProtoToString(NextProto next_proto); @@ -151,12 +139,12 @@ // establishing the connection (or NULL if no channel ID was used). virtual crypto::ECPrivateKey* GetChannelIDKey() const = 0; - protected: - void set_negotiation_extension( - SSLNegotiationExtension negotiation_extension) { - negotiation_extension_ = negotiation_extension; - } + // Returns true if the CECPQ1 (experimental post-quantum) experiment is + // enabled. This should be removed after the experiment is ended, around + // 2017-18. + static bool IsPostQuantumExperimentEnabled(); + protected: void set_signed_cert_timestamps_received( bool signed_cert_timestamps_received) { signed_cert_timestamps_received_ = signed_cert_timestamps_received; @@ -166,21 +154,6 @@ stapled_ocsp_response_received_ = stapled_ocsp_response_received; } - // Record which TLS extension was used to negotiate protocol and protocol - // chosen in a UMA histogram. - void RecordNegotiationExtension(); - - // Records histograms for channel id support during full handshakes - resumed - // handshakes are ignored. - static void RecordChannelIDSupport(ChannelIDService* channel_id_service, - bool negotiated_channel_id, - bool channel_id_enabled); - - // Returns whether TLS channel ID is enabled. - static bool IsChannelIDEnabled( - const SSLConfig& ssl_config, - ChannelIDService* channel_id_service); - // Serialize |next_protos| in the wire format for ALPN and NPN: protocols are // listed in order, each prefixed by a one-byte length. static std::vector<uint8_t> SerializeNextProtos( @@ -202,8 +175,6 @@ bool signed_cert_timestamps_received_; // True if a stapled OCSP response was received. bool stapled_ocsp_response_received_; - // Protocol negotiation extension used. - SSLNegotiationExtension negotiation_extension_; }; } // namespace net
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc index e00ac6b..ac4b833 100644 --- a/net/socket/ssl_client_socket_impl.cc +++ b/net/socket/ssl_client_socket_impl.cc
@@ -17,7 +17,6 @@ #include "base/bind.h" #include "base/callback_helpers.h" -#include "base/feature_list.h" #include "base/lazy_instance.h" #include "base/macros.h" #include "base/memory/singleton.h" @@ -86,11 +85,6 @@ const uint8_t kTbMinProtocolVersionMajor = 0; const uint8_t kTbMinProtocolVersionMinor = 6; -#if !defined(OS_NACL) -const base::Feature kPostQuantumExperiment{"SSLPostQuantumExperiment", - base::FEATURE_DISABLED_BY_DEFAULT}; -#endif - bool EVP_MDToPrivateKeyHash(const EVP_MD* md, SSLPrivateKey::Hash* hash) { switch (EVP_MD_type(md)) { case NID_md5_sha1: @@ -198,9 +192,8 @@ dict->SetInteger("cipher_suite", SSLConnectionStatusToCipherSuite( ssl_info.connection_status)); - std::string next_proto; - socket->GetNextProto(&next_proto); - dict->SetString("next_proto", next_proto); + dict->SetString("next_proto", SSLClientSocket::NextProtoToString( + socket->GetNegotiatedProtocol())); return std::move(dict); } @@ -517,6 +510,8 @@ next_handshake_state_(STATE_NONE), disconnected_(false), npn_status_(kNextProtoUnsupported), + negotiated_protocol_(kProtoUnknown), + negotiation_extension_(kExtensionUnknown), channel_id_sent_(false), certificate_verified_(false), signature_result_(kNoPendingResult), @@ -550,12 +545,6 @@ cert_request_info->cert_key_types = cert_key_types_; } -SSLClientSocket::NextProtoStatus SSLClientSocketImpl::GetNextProto( - std::string* proto) const { - *proto = npn_proto_; - return npn_status_; -} - ChannelIDService* SSLClientSocketImpl::GetChannelIDService() const { return channel_id_service_; } @@ -704,7 +693,7 @@ start_cert_verification_time_ = base::TimeTicks(); npn_status_ = kNextProtoUnsupported; - npn_proto_.clear(); + negotiated_protocol_ = kProtoUnknown; channel_id_sent_ = false; tb_was_negotiated_ = false; @@ -780,6 +769,14 @@ return was_ever_used_; } +bool SSLClientSocketImpl::WasNpnNegotiated() const { + return negotiated_protocol_ != kProtoUnknown; +} + +NextProto SSLClientSocketImpl::GetNegotiatedProtocol() const { + return negotiated_protocol_; +} + bool SSLClientSocketImpl::GetSSLInfo(SSLInfo* ssl_info) { ssl_info->Reset(); if (server_cert_chain_->empty()) @@ -1005,8 +1002,7 @@ // supported. As DHE is being deprecated, don't add a cipher only to remove it // immediately. std::string command; -#if !defined(OS_NACL) - if (base::FeatureList::IsEnabled(kPostQuantumExperiment)) { + if (SSLClientSocket::IsPostQuantumExperimentEnabled()) { // These are experimental, non-standard ciphersuites. They are part of an // experiment in post-quantum cryptography. They're not intended to // represent a de-facto standard, and will be removed from BoringSSL in @@ -1025,7 +1021,6 @@ "CECPQ1-ECDSA-AES256-GCM-SHA384:"); } } -#endif command.append("ALL:!SHA256:!SHA384:!DHE-RSA-AES256-GCM-SHA384:!aPSK:!RC4"); if (ssl_config_.require_ecdhe) @@ -1054,7 +1049,7 @@ << rv; // TLS channel ids. - if (IsChannelIDEnabled(ssl_config_, channel_id_service_)) { + if (IsChannelIDEnabled()) { SSL_enable_tls_channel_id(ssl_); } @@ -1211,15 +1206,16 @@ unsigned alpn_len = 0; SSL_get0_alpn_selected(ssl_, &alpn_proto, &alpn_len); if (alpn_len > 0) { - npn_proto_.assign(reinterpret_cast<const char*>(alpn_proto), alpn_len); + base::StringPiece proto(reinterpret_cast<const char*>(alpn_proto), + alpn_len); + negotiated_protocol_ = NextProtoFromString(proto); npn_status_ = kNextProtoNegotiated; - set_negotiation_extension(kExtensionALPN); + negotiation_extension_ = kExtensionALPN; } } RecordNegotiationExtension(); - RecordChannelIDSupport(channel_id_service_, channel_id_sent_, - ssl_config_.channel_id_enabled); + RecordChannelIDSupport(); const uint8_t* ocsp_response_raw; size_t ocsp_response_len; @@ -1812,13 +1808,17 @@ ct_verify_result_.ct_policies_applied = true; ct_verify_result_.ev_policy_compliance = ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY; + + SCTList verified_scts = + ct::SCTsMatchingStatus(ct_verify_result_.scts, ct::SCT_STATUS_OK); + if (server_cert_verify_result_.cert_status & CERT_STATUS_IS_EV) { scoped_refptr<ct::EVCertsWhitelist> ev_whitelist = SSLConfigService::GetEVCertsWhitelist(); ct::EVPolicyCompliance ev_policy_compliance = policy_enforcer_->DoesConformToCTEVPolicy( server_cert_verify_result_.verified_cert.get(), ev_whitelist.get(), - ct_verify_result_.verified_scts, net_log_); + verified_scts, net_log_); ct_verify_result_.ev_policy_compliance = ev_policy_compliance; if (ev_policy_compliance != ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY && @@ -1833,8 +1833,8 @@ } ct_verify_result_.cert_policy_compliance = policy_enforcer_->DoesConformToCertPolicy( - server_cert_verify_result_.verified_cert.get(), - ct_verify_result_.verified_scts, net_log_); + server_cert_verify_result_.verified_cert.get(), verified_scts, + net_log_); if (ct_verify_result_.cert_policy_compliance != ct::CertPolicyCompliance::CERT_POLICY_COMPLIES_VIA_SCTS && @@ -2013,6 +2013,7 @@ if (in[i] == proto.size() && memcmp(&in[i + 1], proto.data(), in[i]) == 0) { // We found a match. + negotiated_protocol_ = next_proto; *out = const_cast<unsigned char*>(in) + i + 1; *outlen = in[i]; npn_status_ = kNextProtoNegotiated; @@ -2025,14 +2026,14 @@ // If we didn't find a protocol, we select the last one from our list. if (npn_status_ == kNextProtoNoOverlap) { + negotiated_protocol_ = ssl_config_.npn_protos.back(); // NextProtoToString returns a pointer to a static string. - const char* proto = NextProtoToString(ssl_config_.npn_protos.back()); + const char* proto = NextProtoToString(negotiated_protocol_); *out = reinterpret_cast<unsigned char*>(const_cast<char*>(proto)); *outlen = strlen(proto); } - npn_proto_.assign(reinterpret_cast<const char*>(*out), *outlen); - set_negotiation_extension(kExtensionNPN); + negotiation_extension_ = kExtensionNPN; return SSL_TLSEXT_ERR_OK; } @@ -2149,9 +2150,8 @@ if (npn_status_ == kNextProtoUnsupported) return ssl_config_.renego_allowed_default; - NextProto next_proto = NextProtoFromString(npn_proto_); for (NextProto allowed : ssl_config_.renego_allowed_for_protos) { - if (next_proto == allowed) + if (negotiated_protocol_ == allowed) return true; } return false; @@ -2338,4 +2338,54 @@ base::Bind(&NetLogSSLInfoCallback, base::Unretained(this))); } +void SSLClientSocketImpl::RecordNegotiationExtension() const { + if (negotiation_extension_ == kExtensionUnknown) + return; + if (npn_status_ == kNextProtoUnsupported) + return; + base::HistogramBase::Sample sample = + static_cast<base::HistogramBase::Sample>(negotiated_protocol_); + // In addition to the protocol negotiated, we want to record which TLS + // extension was used, and in case of NPN, whether there was overlap between + // server and client list of supported protocols. + if (negotiation_extension_ == kExtensionNPN) { + if (npn_status_ == kNextProtoNoOverlap) { + sample += 1000; + } else { + sample += 500; + } + } else { + DCHECK_EQ(kExtensionALPN, negotiation_extension_); + } + UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSLProtocolNegotiation", sample); +} + +void SSLClientSocketImpl::RecordChannelIDSupport() const { + // Since this enum is used for a histogram, do not change or re-use values. + enum { + DISABLED = 0, + CLIENT_ONLY = 1, + CLIENT_AND_SERVER = 2, + // CLIENT_NO_ECC is unused now. + // CLIENT_BAD_SYSTEM_TIME is unused now. + CLIENT_BAD_SYSTEM_TIME = 4, + CLIENT_NO_CHANNEL_ID_SERVICE = 5, + CHANNEL_ID_USAGE_MAX + } supported = DISABLED; + if (channel_id_sent_) { + supported = CLIENT_AND_SERVER; + } else if (ssl_config_.channel_id_enabled) { + if (!channel_id_service_) + supported = CLIENT_NO_CHANNEL_ID_SERVICE; + else + supported = CLIENT_ONLY; + } + UMA_HISTOGRAM_ENUMERATION("DomainBoundCerts.Support", supported, + CHANNEL_ID_USAGE_MAX); +} + +bool SSLClientSocketImpl::IsChannelIDEnabled() const { + return ssl_config_.channel_id_enabled && channel_id_service_; +} + } // namespace net
diff --git a/net/socket/ssl_client_socket_impl.h b/net/socket/ssl_client_socket_impl.h index 0abde087..ccb780b 100644 --- a/net/socket/ssl_client_socket_impl.h +++ b/net/socket/ssl_client_socket_impl.h
@@ -73,7 +73,6 @@ // SSLClientSocket implementation. void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override; - NextProtoStatus GetNextProto(std::string* proto) const override; ChannelIDService* GetChannelIDService() const override; Error GetSignedEKMForTokenBinding(crypto::ECPrivateKey* key, std::vector<uint8_t>* out) override; @@ -97,6 +96,8 @@ void SetSubresourceSpeculation() override; void SetOmniboxSpeculation() override; bool WasEverUsed() const override; + bool WasNpnNegotiated() const override; + NextProto GetNegotiatedProtocol() const override; bool GetSSLInfo(SSLInfo* ssl_info) override; void GetConnectionAttempts(ConnectionAttempts* out) const override; void ClearConnectionAttempts() override {} @@ -239,6 +240,17 @@ void LogConnectEndEvent(int rv); + // Record which TLS extension was used to negotiate protocol and protocol + // chosen in a UMA histogram. + void RecordNegotiationExtension() const; + + // Records histograms for channel id support during full handshakes - resumed + // handshakes are ignored. + void RecordChannelIDSupport() const; + + // Returns whether TLS channel ID is enabled. + bool IsChannelIDEnabled() const; + bool transport_send_busy_; bool transport_recv_busy_; @@ -342,7 +354,9 @@ bool disconnected_; NextProtoStatus npn_status_; - std::string npn_proto_; + NextProto negotiated_protocol_; + // Protocol negotiation extension used. + SSLNegotiationExtension negotiation_extension_; // Written by the |channel_id_service_|. std::unique_ptr<crypto::ECPrivateKey> channel_id_key_; // True if a channel ID was sent.
diff --git a/net/socket/ssl_client_socket_pool.cc b/net/socket/ssl_client_socket_pool.cc index 93642956..e8f643b 100644 --- a/net/socket/ssl_client_socket_pool.cc +++ b/net/socket/ssl_client_socket_pool.cc
@@ -373,6 +373,7 @@ const char *str, *cipher_str, *mac_str; bool is_aead; + bool is_cecpq1 = false; SSLCipherSuiteToStrings(&str, &cipher_str, &mac_str, &is_aead, cipher_suite); // UMA_HISTOGRAM_... macros cache the Histogram instance and thus only work @@ -384,7 +385,7 @@ UMA_HISTOGRAM_SPARSE_SLOWLY("Net.SSL_KeyExchange.ECDHE", ssl_info.key_exchange_info); } else if (strncmp(str, "CECPQ1_", 7) == 0) { - // Nothing. + is_cecpq1 = true; } else { DCHECK_EQ(0, strcmp(str, "RSA")); } @@ -427,6 +428,26 @@ base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), 100); + + // These are hosts that we expect to always offer CECPQ1. Connections + // to them, whether or not this browser is in the experiment group, form + // the basis of our comparisons. + bool cecpq1_supported = + (host == "play.google.com" || host == "checkout.google.com" || + host == "wallet.google.com"); + if (cecpq1_supported) { + UMA_HISTOGRAM_CUSTOM_TIMES( + "Net.SSL_Connection_Latency_PostQuantumSupported_Full_Handshake", + connect_duration, base::TimeDelta::FromMilliseconds(1), + base::TimeDelta::FromMinutes(1), 100); + if (SSLClientSocket::IsPostQuantumExperimentEnabled()) { + // But don't trust that these hosts offer CECPQ1: make sure. If + // we're doing everything right on the server side, |is_cecpq1| + // should always be true if we get here, modulo MITM. + UMA_HISTOGRAM_BOOLEAN("Net.SSL_Connection_PostQuantum_Negotiated", + is_cecpq1); + } + } } } }
diff --git a/net/socket/ssl_client_socket_pool_unittest.cc b/net/socket/ssl_client_socket_pool_unittest.cc index 0bc6a9bc..0fb292d 100644 --- a/net/socket/ssl_client_socket_pool_unittest.cc +++ b/net/socket/ssl_client_socket_pool_unittest.cc
@@ -384,7 +384,7 @@ StaticSocketDataProvider data; socket_factory_.AddSocketDataProvider(&data); SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP11); + ssl.next_proto = kProtoHTTP11; socket_factory_.AddSSLSocketDataProvider(&ssl); CreatePool(true /* tcp pool */, false, false); @@ -412,7 +412,7 @@ StaticSocketDataProvider data; socket_factory_.AddSocketDataProvider(&data); SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP11); + ssl.next_proto = kProtoHTTP11; socket_factory_.AddSSLSocketDataProvider(&ssl); CreatePool(true /* tcp pool */, false, false); @@ -438,7 +438,7 @@ StaticSocketDataProvider data; socket_factory_.AddSocketDataProvider(&data); SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; socket_factory_.AddSSLSocketDataProvider(&ssl); CreatePool(true /* tcp pool */, false, false); @@ -461,16 +461,14 @@ SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle.socket()); EXPECT_TRUE(ssl_socket->WasNpnNegotiated()); - std::string proto; - ssl_socket->GetNextProto(&proto); - EXPECT_EQ(kProtoHTTP2, SSLClientSocket::NextProtoFromString(proto)); + EXPECT_EQ(kProtoHTTP2, ssl_socket->GetNegotiatedProtocol()); } TEST_F(SSLClientSocketPoolTest, DirectGotBonusSPDY) { StaticSocketDataProvider data; socket_factory_.AddSocketDataProvider(&data); SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; socket_factory_.AddSSLSocketDataProvider(&ssl); CreatePool(true /* tcp pool */, false, false); @@ -493,9 +491,7 @@ SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle.socket()); EXPECT_TRUE(ssl_socket->WasNpnNegotiated()); - std::string proto; - ssl_socket->GetNextProto(&proto); - EXPECT_EQ(kProtoHTTP2, SSLClientSocket::NextProtoFromString(proto)); + EXPECT_EQ(kProtoHTTP2, ssl_socket->GetNegotiatedProtocol()); } TEST_F(SSLClientSocketPoolTest, SOCKSFail) { @@ -845,7 +841,7 @@ SSLSocketDataProvider ssl(ASYNC, OK); ssl.cert = X509Certificate::CreateFromBytes( reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)); - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; socket_factory_.AddSSLSocketDataProvider(&ssl); CreatePool(true /* tcp pool */, false, false); @@ -922,7 +918,7 @@ ssl.cert = X509Certificate::CreateFromBytes( reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)); ssl.client_cert_sent = true; - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; TestIPPoolingDisabled(&ssl); } @@ -930,7 +926,7 @@ TEST_F(SSLClientSocketPoolTest, IPPoolingChannelID) { SSLSocketDataProvider ssl(ASYNC, OK); ssl.channel_id_sent = true; - ssl.SetNextProto(kProtoHTTP2); + ssl.next_proto = kProtoHTTP2; TestIPPoolingDisabled(&ssl); }
diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc index 41c64f2..cb320c7 100644 --- a/net/socket/ssl_client_socket_unittest.cc +++ b/net/socket/ssl_client_socket_unittest.cc
@@ -3146,9 +3146,7 @@ ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv)); EXPECT_THAT(rv, IsOk()); - std::string proto; - EXPECT_EQ(SSLClientSocket::kNextProtoNegotiated, sock_->GetNextProto(&proto)); - EXPECT_EQ("h2", proto); + EXPECT_EQ(kProtoHTTP2, sock_->GetNegotiatedProtocol()); } // Server preference should win in ALPN. @@ -3181,9 +3179,7 @@ ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv)); EXPECT_THAT(rv, IsOk()); - std::string proto; - EXPECT_EQ(SSLClientSocket::kNextProtoUnsupported, - sock_->GetNextProto(&proto)); + EXPECT_EQ(kProtoUnknown, sock_->GetNegotiatedProtocol()); } TEST_F(SSLClientSocketTest, NPNServerDisabled) { @@ -3197,9 +3193,7 @@ ASSERT_TRUE(CreateAndConnectSSLClientSocket(client_config, &rv)); EXPECT_THAT(rv, IsOk()); - std::string proto; - EXPECT_EQ(SSLClientSocket::kNextProtoUnsupported, - sock_->GetNextProto(&proto)); + EXPECT_EQ(kProtoUnknown, sock_->GetNegotiatedProtocol()); } namespace {
diff --git a/net/spdy/bidirectional_stream_spdy_impl_unittest.cc b/net/spdy/bidirectional_stream_spdy_impl_unittest.cc index 574ad3d..9f5a0e8 100644 --- a/net/spdy/bidirectional_stream_spdy_impl_unittest.cc +++ b/net/spdy/bidirectional_stream_spdy_impl_unittest.cc
@@ -220,7 +220,7 @@ host_port_pair_(HostPortPair::FromURL(default_url_)), key_(host_port_pair_, ProxyServer::Direct(), PRIVACY_MODE_DISABLED), ssl_data_(SSLSocketDataProvider(ASYNC, OK)) { - ssl_data_.SetNextProto(kProtoHTTP2); + ssl_data_.next_proto = kProtoHTTP2; ssl_data_.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"); }
diff --git a/net/spdy/http2_write_scheduler.h b/net/spdy/http2_write_scheduler.h index 1fd2962..af27698 100644 --- a/net/spdy/http2_write_scheduler.h +++ b/net/spdy/http2_write_scheduler.h
@@ -168,7 +168,7 @@ StreamInfo* root_stream_info_; // Maps from stream IDs to StreamInfo objects. StreamInfoMap all_stream_infos_; - STLValueDeleter<StreamInfoMap> all_stream_infos_deleter_; + base::STLValueDeleter<StreamInfoMap> all_stream_infos_deleter_; // Queue containing all ready streams, ordered with streams of higher // priority before streams of lower priority, and, among streams of equal // priority, streams with lower ordinal before those with higher @@ -207,7 +207,7 @@ template <typename StreamIdType> bool Http2PriorityWriteScheduler<StreamIdType>::StreamRegistered( StreamIdType stream_id) const { - return ContainsKey(all_stream_infos_, stream_id); + return base::ContainsKey(all_stream_infos_, stream_id); } template <typename StreamIdType> @@ -224,7 +224,8 @@ StreamInfo* parent = FindStream(precedence.parent_id()); if (parent == nullptr) { - SPDY_BUG << "Parent stream " << precedence.parent_id() << " not registered"; + // parent_id may legitimately not be registered yet--see b/15676312. + DVLOG(1) << "Parent stream " << precedence.parent_id() << " not registered"; parent = root_stream_info_; } @@ -309,7 +310,9 @@ StreamIdType stream_id) const { const StreamInfo* stream_info = FindStream(stream_id); if (stream_info == nullptr) { - SPDY_BUG << "Stream " << stream_id << " not registered"; + // Unknown streams tolerated due to b/15676312. However, return lowest + // weight. + DVLOG(1) << "Stream " << stream_id << " not registered"; return StreamPrecedenceType(kHttp2RootStreamId, kHttp2MinStreamWeight, false); } @@ -345,7 +348,8 @@ StreamInfo* stream_info = FindStream(stream_id); if (stream_info == nullptr) { - SPDY_BUG << "Stream " << stream_id << " not registered"; + // TODO(mpw): add to all_stream_infos_ on demand--see b/15676312. + DVLOG(1) << "Stream " << stream_id << " not registered"; return; } UpdateStreamParent(stream_info, precedence.parent_id(), @@ -380,7 +384,8 @@ } StreamInfo* new_parent = FindStream(parent_id); if (new_parent == nullptr) { - SPDY_BUG << "Parent stream " << parent_id << " not registered"; + // parent_id may legitimately not be registered yet--see b/15676312. + DVLOG(1) << "Parent stream " << parent_id << " not registered"; return; }
diff --git a/net/spdy/http2_write_scheduler_test.cc b/net/spdy/http2_write_scheduler_test.cc index 08ee5bb1..62fc4e9 100644 --- a/net/spdy/http2_write_scheduler_test.cc +++ b/net/spdy/http2_write_scheduler_test.cc
@@ -90,9 +90,7 @@ EXPECT_EQ(kHttp2RootStreamId, scheduler_.GetStreamPrecedence(13).parent_id()); // The parent stream 19 doesn't exist, so this should use 0 as parent stream: - EXPECT_SPDY_BUG( - scheduler_.RegisterStream(7, SpdyStreamPrecedence(19, 70, false)), - "Parent stream 19 not registered"); + scheduler_.RegisterStream(7, SpdyStreamPrecedence(19, 70, false)); EXPECT_TRUE(scheduler_.StreamRegistered(7)); EXPECT_EQ(0u, scheduler_.GetStreamPrecedence(7).parent_id()); // Now stream 7 already exists, so this should fail: @@ -125,44 +123,37 @@ } TEST_F(Http2PriorityWriteSchedulerTest, GetStreamWeight) { - EXPECT_SPDY_BUG(EXPECT_EQ(kHttp2MinStreamWeight, - scheduler_.GetStreamPrecedence(3).weight()), - "Stream 3 not registered"); + // Unknown streams tolerated due to b/15676312. + EXPECT_EQ(kHttp2MinStreamWeight, scheduler_.GetStreamPrecedence(3).weight()); scheduler_.RegisterStream(3, SpdyStreamPrecedence(0, 130, true)); EXPECT_EQ(130, scheduler_.GetStreamPrecedence(3).weight()); scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(0, 50, true)); EXPECT_EQ(50, scheduler_.GetStreamPrecedence(3).weight()); scheduler_.UnregisterStream(3); - EXPECT_SPDY_BUG(EXPECT_EQ(kHttp2MinStreamWeight, - scheduler_.GetStreamPrecedence(3).weight()), - "Stream 3 not registered"); + EXPECT_EQ(kHttp2MinStreamWeight, scheduler_.GetStreamPrecedence(3).weight()); } TEST_F(Http2PriorityWriteSchedulerTest, GetStreamPriority) { - EXPECT_SPDY_BUG(EXPECT_EQ(kV3LowestPriority, - scheduler_.GetStreamPrecedence(3).spdy3_priority()), - "Stream 3 not registered"); + // Unknown streams tolerated due to b/15676312. + EXPECT_EQ(kV3LowestPriority, + scheduler_.GetStreamPrecedence(3).spdy3_priority()); scheduler_.RegisterStream(3, SpdyStreamPrecedence(0, 130, true)); EXPECT_EQ(3, scheduler_.GetStreamPrecedence(3).spdy3_priority()); scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(0, 50, true)); EXPECT_EQ(5, scheduler_.GetStreamPrecedence(3).spdy3_priority()); scheduler_.UnregisterStream(3); - EXPECT_SPDY_BUG(EXPECT_EQ(kV3LowestPriority, - scheduler_.GetStreamPrecedence(3).spdy3_priority()), - "Stream 3 not registered"); + EXPECT_EQ(kV3LowestPriority, + scheduler_.GetStreamPrecedence(3).spdy3_priority()); } TEST_F(Http2PriorityWriteSchedulerTest, GetStreamParent) { - EXPECT_SPDY_BUG(EXPECT_EQ(kHttp2RootStreamId, - scheduler_.GetStreamPrecedence(3).parent_id()), - "Stream 3 not registered"); + // Unknown streams tolerated due to b/15676312. + EXPECT_EQ(kHttp2RootStreamId, scheduler_.GetStreamPrecedence(3).parent_id()); scheduler_.RegisterStream(2, SpdyStreamPrecedence(0, 20, false)); scheduler_.RegisterStream(3, SpdyStreamPrecedence(2, 30, false)); EXPECT_EQ(2u, scheduler_.GetStreamPrecedence(3).parent_id()); scheduler_.UnregisterStream(3); - EXPECT_SPDY_BUG(EXPECT_EQ(kHttp2RootStreamId, - scheduler_.GetStreamPrecedence(3).parent_id()), - "Stream 3 not registered"); + EXPECT_EQ(kHttp2RootStreamId, scheduler_.GetStreamPrecedence(3).parent_id()); } TEST_F(Http2PriorityWriteSchedulerTest, GetStreamChildren) { @@ -182,9 +173,13 @@ EXPECT_SPDY_BUG( scheduler_.UpdateStreamPrecedence(0, SpdyStreamPrecedence(0, 10, false)), "Cannot set precedence of root stream"); - EXPECT_SPDY_BUG( - scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(0, 10, false)), - "Stream 3 not registered"); + + // For the moment, updating stream precedence on a non-registered stream + // should have no effect. In the future, it will lazily cause the stream to + // be registered (b/15676312). + scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(0, 10, false)); + EXPECT_FALSE(scheduler_.StreamRegistered(3)); + scheduler_.RegisterStream(3, SpdyStreamPrecedence(0, 10, false)); scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(0, 20, false)); EXPECT_EQ(20, scheduler_.GetStreamPrecedence(3).weight()); @@ -201,9 +196,6 @@ ASSERT_TRUE(peer_.ValidateInvariants()); scheduler_.UnregisterStream(3); - EXPECT_SPDY_BUG( - scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(0, 10, false)), - "Stream 3 not registered"); } // Basic case of reparenting a subtree. @@ -257,18 +249,28 @@ scheduler_.RegisterStream(1, SpdyStreamPrecedence(0, 100, false)); scheduler_.RegisterStream(2, SpdyStreamPrecedence(0, 100, false)); for (bool exclusive : {true, false}) { - EXPECT_SPDY_BUG(scheduler_.UpdateStreamPrecedence( - 1, SpdyStreamPrecedence(3, 100, exclusive)), - "Parent stream 3 not registered"); - EXPECT_SPDY_BUG(scheduler_.UpdateStreamPrecedence( - 4, SpdyStreamPrecedence(2, 100, exclusive)), - "Stream 4 not registered"); - EXPECT_SPDY_BUG(scheduler_.UpdateStreamPrecedence( - 3, SpdyStreamPrecedence(4, 100, exclusive)), - "Stream 3 not registered"); + // For the moment, updating stream precedence on a non-registered stream or + // attempting to set parent to a nonexistent stream should have no + // effect. In the future, it will lazily cause the stream(s) to be + // registered (b/15676312). + + // No-op: parent stream 3 not registered + scheduler_.UpdateStreamPrecedence(1, + SpdyStreamPrecedence(3, 100, exclusive)); + + // No-op: stream 4 not registered + scheduler_.UpdateStreamPrecedence(4, + SpdyStreamPrecedence(2, 100, exclusive)); + + // No-op: stream 3 not registered + scheduler_.UpdateStreamPrecedence(3, + SpdyStreamPrecedence(4, 100, exclusive)); + EXPECT_THAT(scheduler_.GetStreamChildren(0), UnorderedElementsAre(1, 2)); EXPECT_THAT(scheduler_.GetStreamChildren(1), IsEmpty()); EXPECT_THAT(scheduler_.GetStreamChildren(2), IsEmpty()); + EXPECT_FALSE(scheduler_.StreamRegistered(3)); + EXPECT_FALSE(scheduler_.StreamRegistered(4)); } ASSERT_TRUE(peer_.ValidateInvariants()); }
diff --git a/net/spdy/priority_write_scheduler.h b/net/spdy/priority_write_scheduler.h index 5072f68..2a8276c1 100644 --- a/net/spdy/priority_write_scheduler.h +++ b/net/spdy/priority_write_scheduler.h
@@ -47,10 +47,11 @@ const StreamPrecedenceType& precedence) override { SPDY_BUG_IF(!precedence.is_spdy3_priority()) << "Expected SPDY priority"; - // parent_id not used here, but may as well validate it + // parent_id not used here, but may as well validate it. However, + // parent_id may legitimately not be registered yet--see b/15676312. StreamIdType parent_id = precedence.parent_id(); - SPDY_BUG_IF(parent_id != kHttp2RootStreamId && !StreamRegistered(parent_id)) - << "Stream " << parent_id << " not registered"; + DVLOG_IF(1, parent_id != kHttp2RootStreamId && !StreamRegistered(parent_id)) + << "Parent stream " << parent_id << " not registered"; if (stream_id == kHttp2RootStreamId) { SPDY_BUG << "Stream " << kHttp2RootStreamId << " already registered"; @@ -85,7 +86,7 @@ StreamIdType stream_id) const override { auto it = stream_infos_.find(stream_id); if (it == stream_infos_.end()) { - SPDY_BUG << "Stream " << stream_id << " not registered"; + DVLOG(1) << "Stream " << stream_id << " not registered"; return StreamPrecedenceType(kV3LowestPriority); } return StreamPrecedenceType(it->second.priority); @@ -95,14 +96,16 @@ const StreamPrecedenceType& precedence) override { SPDY_BUG_IF(!precedence.is_spdy3_priority()) << "Expected SPDY priority"; - // parent_id not used here, but may as well validate it + // parent_id not used here, but may as well validate it. However, + // parent_id may legitimately not be registered yet--see b/15676312. StreamIdType parent_id = precedence.parent_id(); - SPDY_BUG_IF(parent_id != kHttp2RootStreamId && !StreamRegistered(parent_id)) - << "Stream " << parent_id << " not registered"; + DVLOG_IF(1, parent_id != kHttp2RootStreamId && !StreamRegistered(parent_id)) + << "Parent stream " << parent_id << " not registered"; auto it = stream_infos_.find(stream_id); if (it == stream_infos_.end()) { - SPDY_BUG << "Stream " << stream_id << " not registered"; + // TODO(mpw): add to stream_infos_ on demand--see b/15676312. + DVLOG(1) << "Stream " << stream_id << " not registered"; return; } StreamInfo& stream_info = it->second;
diff --git a/net/spdy/priority_write_scheduler_test.cc b/net/spdy/priority_write_scheduler_test.cc index 9df27fde..2a47f88 100644 --- a/net/spdy/priority_write_scheduler_test.cc +++ b/net/spdy/priority_write_scheduler_test.cc
@@ -83,16 +83,21 @@ EXPECT_TRUE(scheduler_.GetStreamPrecedence(1).is_spdy3_priority()); EXPECT_EQ(3, scheduler_.GetStreamPrecedence(1).spdy3_priority()); + // Registering stream with a non-existent parent stream is permissible, but + // parent stream will always be reset to 0. EXPECT_SPDY_BUG( scheduler_.RegisterStream(2, SpdyStreamPrecedence(3, 123, false)), "Expected SPDY priority"); EXPECT_TRUE(scheduler_.StreamRegistered(2)); + EXPECT_FALSE(scheduler_.StreamRegistered(3)); + EXPECT_EQ(kHttp2RootStreamId, scheduler_.GetStreamPrecedence(2).parent_id()); } TEST_F(PriorityWriteSchedulerTest, GetStreamPrecedence) { - EXPECT_SPDY_BUG(EXPECT_EQ(kV3LowestPriority, - scheduler_.GetStreamPrecedence(1).spdy3_priority()), - "Stream 1 not registered"); + // Unknown streams tolerated due to b/15676312. However, return lowest + // priority. + EXPECT_EQ(kV3LowestPriority, + scheduler_.GetStreamPrecedence(1).spdy3_priority()); scheduler_.RegisterStream(1, SpdyStreamPrecedence(3)); EXPECT_TRUE(scheduler_.GetStreamPrecedence(1).is_spdy3_priority()); @@ -121,9 +126,8 @@ EXPECT_EQ(6, scheduler_.GetStreamPrecedence(1).spdy3_priority()); scheduler_.UnregisterStream(1); - EXPECT_SPDY_BUG(EXPECT_EQ(kV3LowestPriority, - scheduler_.GetStreamPrecedence(1).spdy3_priority()), - "Stream 1 not registered"); + EXPECT_EQ(kV3LowestPriority, + scheduler_.GetStreamPrecedence(1).spdy3_priority()); } TEST_F(PriorityWriteSchedulerTest, PopNextReadyStreamAndPrecedence) { @@ -135,15 +139,16 @@ } TEST_F(PriorityWriteSchedulerTest, UpdateStreamPrecedence) { - // Updating priority of unregistered stream should have no effect. - EXPECT_SPDY_BUG(EXPECT_EQ(kV3LowestPriority, - scheduler_.GetStreamPrecedence(3).spdy3_priority()), - "Stream 3 not registered"); - EXPECT_SPDY_BUG(scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(1)), - "Stream 3 not registered"); - EXPECT_SPDY_BUG(EXPECT_EQ(kV3LowestPriority, - scheduler_.GetStreamPrecedence(3).spdy3_priority()), - "Stream 3 not registered"); + // For the moment, updating stream precedence on a non-registered stream + // should have no effect. In the future, it will lazily cause the stream to + // be registered (b/15676312). + EXPECT_EQ(kV3LowestPriority, + scheduler_.GetStreamPrecedence(3).spdy3_priority()); + EXPECT_FALSE(scheduler_.StreamRegistered(3)); + scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(1)); + EXPECT_FALSE(scheduler_.StreamRegistered(3)); + EXPECT_EQ(kV3LowestPriority, + scheduler_.GetStreamPrecedence(3).spdy3_priority()); scheduler_.RegisterStream(3, SpdyStreamPrecedence(1)); EXPECT_EQ(1, scheduler_.GetStreamPrecedence(3).spdy3_priority()); @@ -172,15 +177,15 @@ EXPECT_EQ(4u, scheduler_.PopNextReadyStream()); scheduler_.UnregisterStream(3); - EXPECT_SPDY_BUG(scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(1)), - "Stream 3 not registered"); } TEST_F(PriorityWriteSchedulerTest, UpdateStreamPrecedenceWithHttp2StreamDependency) { + // Unknown streams tolerated due to b/15676312, but should have no effect. EXPECT_SPDY_BUG( scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(0, 100, false)), "Expected SPDY priority"); + EXPECT_FALSE(scheduler_.StreamRegistered(3)); scheduler_.RegisterStream(3, SpdyStreamPrecedence(3)); EXPECT_SPDY_BUG( @@ -192,7 +197,8 @@ scheduler_.UnregisterStream(3); EXPECT_SPDY_BUG( scheduler_.UpdateStreamPrecedence(3, SpdyStreamPrecedence(0, 100, false)), - "Stream 3 not registered"); + "Expected SPDY priority"); + EXPECT_FALSE(scheduler_.StreamRegistered(3)); } TEST_F(PriorityWriteSchedulerTest, MarkStreamReadyBack) {
diff --git a/net/spdy/spdy_flags.cc b/net/spdy/spdy_flags.cc index a2d31d08..f6564ccc 100644 --- a/net/spdy/spdy_flags.cc +++ b/net/spdy/spdy_flags.cc
@@ -7,9 +7,5 @@ // Use NestedSpdyFramerDecoder. bool FLAGS_use_nested_spdy_framer_decoder = false; -// Enforce the limit we advertise on frame payload size with -// GOAWAY_FRAME_SIZE_ERROR. -bool FLAGS_chromium_http2_flag_enforce_max_frame_size = true; - // Use SpdyHeaderBlock::AppendValueOrAddHeader when adding to headers. bool FLAGS_chromium_http2_flag_use_new_spdy_header_block_header_joining = true;
diff --git a/net/spdy/spdy_flags.h b/net/spdy/spdy_flags.h index bd8375b..e00f61b 100644 --- a/net/spdy/spdy_flags.h +++ b/net/spdy/spdy_flags.h
@@ -8,7 +8,6 @@ #include "net/base/net_export.h" NET_EXPORT_PRIVATE extern bool FLAGS_use_nested_spdy_framer_decoder; -NET_EXPORT_PRIVATE extern bool FLAGS_chromium_http2_flag_enforce_max_frame_size; NET_EXPORT_PRIVATE extern bool FLAGS_chromium_http2_flag_use_new_spdy_header_block_header_joining;
diff --git a/net/spdy/spdy_framer.cc b/net/spdy/spdy_framer.cc index e6fa1d47..5cebf6f 100644 --- a/net/spdy/spdy_framer.cc +++ b/net/spdy/spdy_framer.cc
@@ -841,7 +841,7 @@ } } - if (enforce_max_frame_size_ && protocol_version_ == HTTP2 && + if (protocol_version_ == HTTP2 && payload_length_field > recv_frame_size_limit_) { set_error(SPDY_OVERSIZED_PAYLOAD); } @@ -961,14 +961,6 @@ // if we're here, then we have the common header all received. if (!is_control_frame) { - if (protocol_version_ == HTTP2) { - // Catch bogus tests sending oversized DATA frames. - // TODO(dahollings): Remove this SPDY_BUG when deprecating - // --gfe2_reloadable_flag_enforce_max_frame_size. - SPDY_BUG_IF(GetFrameMaximumSize() < current_frame_length_) - << "DATA frame too large for HTTP/2."; - } - uint8_t valid_data_flags = 0; if (protocol_version_ == SPDY3) { valid_data_flags = DATA_FLAG_FIN; @@ -1201,7 +1193,7 @@ return; } - if ((!enforce_max_frame_size_ || protocol_version_ == SPDY3) && + if (protocol_version_ == SPDY3 && current_frame_length_ > kSpdyInitialFrameSizeLimit + SpdyConstants::GetFrameHeaderSize(protocol_version_)) {
diff --git a/net/spdy/spdy_framer.h b/net/spdy/spdy_framer.h index 6ab74ee..fa63b75 100644 --- a/net/spdy/spdy_framer.h +++ b/net/spdy/spdy_framer.h
@@ -851,9 +851,6 @@ // If true, then ProcessInput returns after processing a full frame, // rather than reading all available input. bool process_single_input_frame_ = false; - - bool enforce_max_frame_size_ = - FLAGS_chromium_http2_flag_enforce_max_frame_size; }; } // namespace net
diff --git a/net/spdy/spdy_framer_test.cc b/net/spdy/spdy_framer_test.cc index c2c72fbc..d9976d5 100644 --- a/net/spdy/spdy_framer_test.cc +++ b/net/spdy/spdy_framer_test.cc
@@ -1004,8 +1004,6 @@ // Test that if we receive a frame with payload length larger than the // advertised max size, we set an error of SPDY_INVALID_CONTROL_FRAME_SIZE. TEST_P(SpdyFramerTest, ExceedMaxFrameSizeSetting) { - FLAGS_chromium_http2_flag_enforce_max_frame_size = true; - if (!IsHttp2()) { return; } @@ -1033,36 +1031,6 @@ << SpdyFramer::ErrorCodeToString(framer.error_code()); } -// Test demonstrating pre-flag behavior -TEST_P(SpdyFramerTest, ExceedMaxFrameSizeSettingFlagOff) { - FLAGS_chromium_http2_flag_enforce_max_frame_size = false; - - if (!IsHttp2()) { - return; - } - - testing::StrictMock<test::MockSpdyFramerVisitor> visitor; - SpdyFramer framer(spdy_version_); - framer.set_visitor(&visitor); - - // DATA frame with too large payload length. - unsigned char kH2FrameData[] = { - 0x00, 0x40, 0x01, // Length: 2^14 + 1 - 0x00, // Type: HEADERS - 0x00, // Flags: None - 0x00, 0x00, 0x00, 0x01, // Stream: 1 - 0x00, 0x00, 0x00, 0x00, // Junk payload - }; - - SpdySerializedFrame frame(reinterpret_cast<char*>(kH2FrameData), - sizeof(kH2FrameData), false); - EXPECT_CALL(visitor, OnDataFrameHeader(1, _, false)); - EXPECT_CALL(visitor, OnStreamFrameData(1, _, 4)); - EXPECT_SPDY_BUG(framer.ProcessInput(frame.data(), frame.size()), - "DATA frame too large for HTTP/2."); - EXPECT_FALSE(framer.HasError()); -} - // Test that if we receive a DATA frame with padding length larger than the // payload length, we set an error of SPDY_INVALID_PADDING TEST_P(SpdyFramerTest, OversizedDataPaddingError) {
diff --git a/net/spdy/spdy_http_stream.cc b/net/spdy/spdy_http_stream.cc index a05e7f8..31b033a 100644 --- a/net/spdy/spdy_http_stream.cc +++ b/net/spdy/spdy_http_stream.cc
@@ -49,7 +49,7 @@ more_read_data_pending_(false), direct_(direct), was_npn_negotiated_(false), - protocol_negotiated_(kProtoUnknown), + negotiated_protocol_(kProtoUnknown), weak_factory_(this) { DCHECK(spdy_session_.get()); } @@ -79,9 +79,7 @@ // |stream_| may be NULL even if OK was returned. if (stream_.get()) { DCHECK_EQ(stream_->type(), SPDY_PUSH_STREAM); - stream_->SetDelegate(this); - stream_->GetSSLInfo(&ssl_info_, &was_npn_negotiated_, - &protocol_negotiated_); + InitializeStreamHelper(); return OK; } } @@ -94,9 +92,7 @@ if (rv == OK) { stream_ = stream_request_.ReleaseStream(); - stream_->SetDelegate(this); - stream_->GetSSLInfo(&ssl_info_, &was_npn_negotiated_, - &protocol_negotiated_); + InitializeStreamHelper(); } return rv; @@ -335,7 +331,7 @@ // will take care of that part. response_info_->was_npn_negotiated = was_npn_negotiated_; response_info_->npn_negotiated_protocol = - SSLClientSocket::NextProtoToString(protocol_negotiated_); + SSLClientSocket::NextProtoToString(negotiated_protocol_); response_info_->request_time = stream_->GetRequestTime(); response_info_->connection_info = HttpResponseInfo::ConnectionInfoFromNextProto(kProtoHTTP2); @@ -426,9 +422,7 @@ int rv) { if (rv == OK) { stream_ = stream_request_.ReleaseStream(); - stream_->SetDelegate(this); - stream_->GetSSLInfo(&ssl_info_, &was_npn_negotiated_, - &protocol_negotiated_); + InitializeStreamHelper(); } callback.Run(rv); } @@ -452,6 +446,13 @@ OnRequestBodyReadCompleted(rv); } +void SpdyHttpStream::InitializeStreamHelper() { + stream_->SetDelegate(this); + stream_->GetSSLInfo(&ssl_info_); + was_npn_negotiated_ = stream_->WasNpnNegotiated(); + negotiated_protocol_ = stream_->GetNegotiatedProtocol(); +} + void SpdyHttpStream::ResetStreamInternal() { spdy_session_->ResetStream(stream()->stream_id(), RST_STREAM_INTERNAL_ERROR, std::string());
diff --git a/net/spdy/spdy_http_stream.h b/net/spdy/spdy_http_stream.h index 83829a5..0af46b49 100644 --- a/net/spdy/spdy_http_stream.h +++ b/net/spdy/spdy_http_stream.h
@@ -96,6 +96,10 @@ void OnClose(int status) override; private: + // Helper function used to initialize private members and to set delegate on + // stream when stream is created. + void InitializeStreamHelper(); + // Helper function used for resetting stream from inside the stream. void ResetStreamInternal(); @@ -190,7 +194,7 @@ SSLInfo ssl_info_; bool was_npn_negotiated_; - NextProto protocol_negotiated_; + NextProto negotiated_protocol_; base::WeakPtrFactory<SpdyHttpStream> weak_factory_;
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc index 78c70a7..473e7c5b 100644 --- a/net/spdy/spdy_network_transaction_unittest.cc +++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -222,10 +222,8 @@ SocketDataProvider* data, std::unique_ptr<SSLSocketDataProvider> ssl_provider) { data_vector_.push_back(data); - if (ssl_provider->next_proto_status == - SSLClientSocket::kNextProtoUnsupported) { - ssl_provider->SetNextProto(kProtoHTTP2); - } + if (ssl_provider->next_proto == kProtoUnknown) + ssl_provider->next_proto = kProtoHTTP2; session_deps_->socket_factory->AddSSLSocketDataProvider( ssl_provider.get()); @@ -457,10 +455,9 @@ rv = callback.WaitForResult(); // Request the pushed path. - std::unique_ptr<HttpNetworkTransaction> trans2( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - rv = trans2->Start( - &CreateGetPushRequest(), callback.callback(), BoundNetLog()); + HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session()); + rv = trans2.Start(&CreateGetPushRequest(), callback.callback(), + BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); base::RunLoop().RunUntilIdle(); @@ -469,7 +466,7 @@ // Read the server push body. std::string result2; - ReadResult(trans2.get(), &result2); + ReadResult(&trans2, &result2); // Read the response body. std::string result; ReadResult(trans, &result); @@ -484,7 +481,7 @@ EXPECT_TRUE(load_timing_info.push_end.is_null()); LoadTimingInfo load_timing_info2; - EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2)); + EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2)); EXPECT_FALSE(load_timing_info2.push_start.is_null()); EXPECT_FALSE(load_timing_info2.push_end.is_null()); @@ -497,7 +494,7 @@ // Verify the response HEADERS. // Copy the response info, because trans goes away. *response = *trans->GetResponseInfo(); - *push_response = *trans2->GetResponseInfo(); + *push_response = *trans2.GetResponseInfo(); VerifyStreamsClosed(helper); } @@ -510,14 +507,13 @@ static void StartTransactionCallback(HttpNetworkSession* session, GURL url, int result) { - std::unique_ptr<HttpNetworkTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session); TestCompletionCallback callback; HttpRequestInfo request; request.method = "GET"; request.url = url; request.load_flags = 0; - int rv = trans->Start(&request, callback.callback(), BoundNetLog()); + int rv = trans.Start(&request, callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); callback.WaitForResult(); } @@ -693,12 +689,9 @@ // on will negotiate SPDY and will be used for all requests. helper.AddData(&data_placeholder1); helper.AddData(&data_placeholder2); - std::unique_ptr<HttpNetworkTransaction> trans1( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - std::unique_ptr<HttpNetworkTransaction> trans2( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - std::unique_ptr<HttpNetworkTransaction> trans3( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); + HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session()); + HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session()); + HttpNetworkTransaction trans3(DEFAULT_PRIORITY, helper.session()); TestCompletionCallback callback1; TestCompletionCallback callback2; @@ -708,11 +701,11 @@ HttpRequestInfo httpreq2 = CreateGetRequest(); HttpRequestInfo httpreq3 = CreateGetRequest(); - out.rv = trans1->Start(&httpreq1, callback1.callback(), log); + out.rv = trans1.Start(&httpreq1, callback1.callback(), log); ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING)); - out.rv = trans2->Start(&httpreq2, callback2.callback(), log); + out.rv = trans2.Start(&httpreq2, callback2.callback(), log); ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING)); - out.rv = trans3->Start(&httpreq3, callback3.callback(), log); + out.rv = trans3.Start(&httpreq3, callback3.callback(), log); ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING)); out.rv = callback1.WaitForResult(); @@ -720,15 +713,15 @@ out.rv = callback3.WaitForResult(); ASSERT_THAT(out.rv, IsOk()); - const HttpResponseInfo* response1 = trans1->GetResponseInfo(); + const HttpResponseInfo* response1 = trans1.GetResponseInfo(); EXPECT_TRUE(response1->headers); EXPECT_TRUE(response1->was_fetched_via_spdy); out.status_line = response1->headers->GetStatusLine(); out.response_info = *response1; - trans2->GetResponseInfo(); + trans2.GetResponseInfo(); - out.rv = ReadTransaction(trans1.get(), &out.response_data); + out.rv = ReadTransaction(&trans1, &out.response_data); helper.VerifyDataConsumed(); EXPECT_THAT(out.rv, IsOk()); @@ -775,10 +768,8 @@ // the same time which results in two sockets being connected. The first // on will negotiate SPDY and will be used for all requests. helper.AddData(&data_placeholder); - std::unique_ptr<HttpNetworkTransaction> trans1( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - std::unique_ptr<HttpNetworkTransaction> trans2( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); + HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session()); + HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session()); TestCompletionCallback callback1; TestCompletionCallback callback2; @@ -786,9 +777,9 @@ HttpRequestInfo httpreq1 = CreateGetRequest(); HttpRequestInfo httpreq2 = CreateGetRequest(); - out.rv = trans1->Start(&httpreq1, callback1.callback(), log); + out.rv = trans1.Start(&httpreq1, callback1.callback(), log); ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING)); - out.rv = trans2->Start(&httpreq2, callback2.callback(), log); + out.rv = trans2.Start(&httpreq2, callback2.callback(), log); ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING)); out.rv = callback1.WaitForResult(); @@ -796,22 +787,22 @@ out.rv = callback2.WaitForResult(); ASSERT_THAT(out.rv, IsOk()); - const HttpResponseInfo* response1 = trans1->GetResponseInfo(); + const HttpResponseInfo* response1 = trans1.GetResponseInfo(); EXPECT_TRUE(response1->headers); EXPECT_TRUE(response1->was_fetched_via_spdy); out.status_line = response1->headers->GetStatusLine(); out.response_info = *response1; - out.rv = ReadTransaction(trans1.get(), &out.response_data); + out.rv = ReadTransaction(&trans1, &out.response_data); EXPECT_THAT(out.rv, IsOk()); EXPECT_EQ("HTTP/1.1 200", out.status_line); EXPECT_EQ("hello!hello!", out.response_data); - const HttpResponseInfo* response2 = trans2->GetResponseInfo(); + const HttpResponseInfo* response2 = trans2.GetResponseInfo(); EXPECT_TRUE(response2->headers); EXPECT_TRUE(response2->was_fetched_via_spdy); out.status_line = response2->headers->GetStatusLine(); out.response_info = *response2; - out.rv = ReadTransaction(trans2.get(), &out.response_data); + out.rv = ReadTransaction(&trans2, &out.response_data); EXPECT_THAT(out.rv, IsOk()); EXPECT_EQ("HTTP/1.1 200", out.status_line); EXPECT_EQ("hello!hello!", out.response_data); @@ -860,10 +851,8 @@ helper.AddData(&data_placeholder); helper.AddData(&data_placeholder); - std::unique_ptr<HttpNetworkTransaction> trans1( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - std::unique_ptr<HttpNetworkTransaction> trans2( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); + HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session()); + HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session()); TestCompletionCallback callback1; TestCompletionCallback callback2; @@ -876,9 +865,9 @@ http_stream_factory->PreconnectStreams(1, httpreq); - out.rv = trans1->Start(&httpreq, callback1.callback(), log); + out.rv = trans1.Start(&httpreq, callback1.callback(), log); ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING)); - out.rv = trans2->Start(&httpreq, callback2.callback(), log); + out.rv = trans2.Start(&httpreq, callback2.callback(), log); ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING)); out.rv = callback1.WaitForResult(); @@ -886,22 +875,22 @@ out.rv = callback2.WaitForResult(); ASSERT_THAT(out.rv, IsOk()); - const HttpResponseInfo* response1 = trans1->GetResponseInfo(); + const HttpResponseInfo* response1 = trans1.GetResponseInfo(); EXPECT_TRUE(response1->headers); EXPECT_TRUE(response1->was_fetched_via_spdy); out.status_line = response1->headers->GetStatusLine(); out.response_info = *response1; - out.rv = ReadTransaction(trans1.get(), &out.response_data); + out.rv = ReadTransaction(&trans1, &out.response_data); EXPECT_THAT(out.rv, IsOk()); EXPECT_EQ("HTTP/1.1 200", out.status_line); EXPECT_EQ("hello!hello!", out.response_data); - const HttpResponseInfo* response2 = trans2->GetResponseInfo(); + const HttpResponseInfo* response2 = trans2.GetResponseInfo(); EXPECT_TRUE(response2->headers); EXPECT_TRUE(response2->was_fetched_via_spdy); out.status_line = response2->headers->GetStatusLine(); out.response_info = *response2; - out.rv = ReadTransaction(trans2.get(), &out.response_data); + out.rv = ReadTransaction(&trans2, &out.response_data); EXPECT_THAT(out.rv, IsOk()); EXPECT_EQ("HTTP/1.1 200", out.status_line); EXPECT_EQ("hello!hello!", out.response_data); @@ -974,12 +963,9 @@ BoundNetLog(), NULL); helper.RunPreTestSetup(); helper.AddData(&data); - std::unique_ptr<HttpNetworkTransaction> trans1( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - std::unique_ptr<HttpNetworkTransaction> trans2( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - std::unique_ptr<HttpNetworkTransaction> trans3( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); + HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session()); + HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session()); + HttpNetworkTransaction trans3(DEFAULT_PRIORITY, helper.session()); TestCompletionCallback callback1; TestCompletionCallback callback2; @@ -989,16 +975,16 @@ HttpRequestInfo httpreq2 = CreateGetRequest(); HttpRequestInfo httpreq3 = CreateGetRequest(); - out.rv = trans1->Start(&httpreq1, callback1.callback(), log); + out.rv = trans1.Start(&httpreq1, callback1.callback(), log); ASSERT_EQ(out.rv, ERR_IO_PENDING); // Run transaction 1 through quickly to force a read of our SETTINGS // frame. out.rv = callback1.WaitForResult(); ASSERT_THAT(out.rv, IsOk()); - out.rv = trans2->Start(&httpreq2, callback2.callback(), log); + out.rv = trans2.Start(&httpreq2, callback2.callback(), log); ASSERT_EQ(out.rv, ERR_IO_PENDING); - out.rv = trans3->Start(&httpreq3, callback3.callback(), log); + out.rv = trans3.Start(&httpreq3, callback3.callback(), log); ASSERT_EQ(out.rv, ERR_IO_PENDING); out.rv = callback2.WaitForResult(); ASSERT_THAT(out.rv, IsOk()); @@ -1006,29 +992,29 @@ out.rv = callback3.WaitForResult(); ASSERT_THAT(out.rv, IsOk()); - const HttpResponseInfo* response1 = trans1->GetResponseInfo(); + const HttpResponseInfo* response1 = trans1.GetResponseInfo(); ASSERT_TRUE(response1); EXPECT_TRUE(response1->headers); EXPECT_TRUE(response1->was_fetched_via_spdy); out.status_line = response1->headers->GetStatusLine(); out.response_info = *response1; - out.rv = ReadTransaction(trans1.get(), &out.response_data); + out.rv = ReadTransaction(&trans1, &out.response_data); EXPECT_THAT(out.rv, IsOk()); EXPECT_EQ("HTTP/1.1 200", out.status_line); EXPECT_EQ("hello!hello!", out.response_data); - const HttpResponseInfo* response2 = trans2->GetResponseInfo(); + const HttpResponseInfo* response2 = trans2.GetResponseInfo(); out.status_line = response2->headers->GetStatusLine(); out.response_info = *response2; - out.rv = ReadTransaction(trans2.get(), &out.response_data); + out.rv = ReadTransaction(&trans2, &out.response_data); EXPECT_THAT(out.rv, IsOk()); EXPECT_EQ("HTTP/1.1 200", out.status_line); EXPECT_EQ("hello!hello!", out.response_data); - const HttpResponseInfo* response3 = trans3->GetResponseInfo(); + const HttpResponseInfo* response3 = trans3.GetResponseInfo(); out.status_line = response3->headers->GetStatusLine(); out.response_info = *response3; - out.rv = ReadTransaction(trans3.get(), &out.response_data); + out.rv = ReadTransaction(&trans3, &out.response_data); EXPECT_THAT(out.rv, IsOk()); EXPECT_EQ("HTTP/1.1 200", out.status_line); EXPECT_EQ("hello!hello!", out.response_data); @@ -1111,14 +1097,10 @@ helper.RunPreTestSetup(); helper.AddData(&data); - std::unique_ptr<HttpNetworkTransaction> trans1( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - std::unique_ptr<HttpNetworkTransaction> trans2( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - std::unique_ptr<HttpNetworkTransaction> trans3( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - std::unique_ptr<HttpNetworkTransaction> trans4( - new HttpNetworkTransaction(HIGHEST, helper.session())); + HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session()); + HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session()); + HttpNetworkTransaction trans3(DEFAULT_PRIORITY, helper.session()); + HttpNetworkTransaction trans4(HIGHEST, helper.session()); TestCompletionCallback callback1; TestCompletionCallback callback2; @@ -1130,17 +1112,17 @@ HttpRequestInfo httpreq3 = CreateGetRequest(); HttpRequestInfo httpreq4 = CreateGetRequest(); - out.rv = trans1->Start(&httpreq1, callback1.callback(), log); + out.rv = trans1.Start(&httpreq1, callback1.callback(), log); ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING)); // Run transaction 1 through quickly to force a read of our SETTINGS frame. out.rv = callback1.WaitForResult(); ASSERT_THAT(out.rv, IsOk()); - out.rv = trans2->Start(&httpreq2, callback2.callback(), log); + out.rv = trans2.Start(&httpreq2, callback2.callback(), log); ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING)); - out.rv = trans3->Start(&httpreq3, callback3.callback(), log); + out.rv = trans3.Start(&httpreq3, callback3.callback(), log); ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING)); - out.rv = trans4->Start(&httpreq4, callback4.callback(), log); + out.rv = trans4.Start(&httpreq4, callback4.callback(), log); ASSERT_THAT(out.rv, IsError(ERR_IO_PENDING)); out.rv = callback2.WaitForResult(); @@ -1149,40 +1131,40 @@ out.rv = callback3.WaitForResult(); ASSERT_THAT(out.rv, IsOk()); - const HttpResponseInfo* response1 = trans1->GetResponseInfo(); + const HttpResponseInfo* response1 = trans1.GetResponseInfo(); EXPECT_TRUE(response1->headers); EXPECT_TRUE(response1->was_fetched_via_spdy); out.status_line = response1->headers->GetStatusLine(); out.response_info = *response1; - out.rv = ReadTransaction(trans1.get(), &out.response_data); + out.rv = ReadTransaction(&trans1, &out.response_data); EXPECT_THAT(out.rv, IsOk()); EXPECT_EQ("HTTP/1.1 200", out.status_line); EXPECT_EQ("hello!hello!", out.response_data); - const HttpResponseInfo* response2 = trans2->GetResponseInfo(); + const HttpResponseInfo* response2 = trans2.GetResponseInfo(); out.status_line = response2->headers->GetStatusLine(); out.response_info = *response2; - out.rv = ReadTransaction(trans2.get(), &out.response_data); + out.rv = ReadTransaction(&trans2, &out.response_data); EXPECT_THAT(out.rv, IsOk()); EXPECT_EQ("HTTP/1.1 200", out.status_line); EXPECT_EQ("hello!hello!", out.response_data); // notice: response3 gets two hellos, response4 gets one // hello, so we know dequeuing priority was respected. - const HttpResponseInfo* response3 = trans3->GetResponseInfo(); + const HttpResponseInfo* response3 = trans3.GetResponseInfo(); out.status_line = response3->headers->GetStatusLine(); out.response_info = *response3; - out.rv = ReadTransaction(trans3.get(), &out.response_data); + out.rv = ReadTransaction(&trans3, &out.response_data); EXPECT_THAT(out.rv, IsOk()); EXPECT_EQ("HTTP/1.1 200", out.status_line); EXPECT_EQ("hello!hello!", out.response_data); out.rv = callback4.WaitForResult(); EXPECT_THAT(out.rv, IsOk()); - const HttpResponseInfo* response4 = trans4->GetResponseInfo(); + const HttpResponseInfo* response4 = trans4.GetResponseInfo(); out.status_line = response4->headers->GetStatusLine(); out.response_info = *response4; - out.rv = ReadTransaction(trans4.get(), &out.response_data); + out.rv = ReadTransaction(&trans4, &out.response_data); EXPECT_THAT(out.rv, IsOk()); EXPECT_EQ("HTTP/1.1 200", out.status_line); EXPECT_EQ("hello!", out.response_data); @@ -2858,18 +2840,17 @@ EXPECT_TRUE(response.headers); EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine()); - std::unique_ptr<HttpNetworkTransaction> trans2( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); + HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session()); TestCompletionCallback callback2; - rv = trans2->Start(&CreateGetPushRequest(), callback2.callback(), - BoundNetLog()); + rv = trans2.Start(&CreateGetPushRequest(), callback2.callback(), + BoundNetLog()); rv = callback2.GetResult(rv); EXPECT_THAT(rv, IsOk()); - response = *trans2->GetResponseInfo(); + response = *trans2.GetResponseInfo(); EXPECT_TRUE(response.headers); EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine()); std::string result; - ReadResult(trans2.get(), &result); + ReadResult(&trans2, &result); EXPECT_EQ(kPushedData, result); data.Resume(); @@ -3824,7 +3805,7 @@ ssl_provider0->next_protos_expected_in_ssl_config.push_back(kProtoHTTP2); ssl_provider0->next_protos_expected_in_ssl_config.push_back(kProtoHTTP11); // Force SPDY. - ssl_provider0->SetNextProto(kProtoHTTP2); + ssl_provider0->next_proto = kProtoHTTP2; helper.AddDataWithSSLSocketDataProvider(&data0, std::move(ssl_provider0)); // Second socket: falling back to HTTP/1.1. @@ -3844,7 +3825,7 @@ // Expect only HTTP/1.1 protocol in SSLConfig. ssl_provider1->next_protos_expected_in_ssl_config.push_back(kProtoHTTP11); // Force HTTP/1.1. - ssl_provider1->SetNextProto(kProtoHTTP11); + ssl_provider1->next_proto = kProtoHTTP11; helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1)); HttpServerProperties* http_server_properties = @@ -3902,7 +3883,7 @@ ssl_provider0->next_protos_expected_in_ssl_config.push_back(kProtoHTTP2); ssl_provider0->next_protos_expected_in_ssl_config.push_back(kProtoHTTP11); // Force SPDY. - ssl_provider0->SetNextProto(kProtoHTTP2); + ssl_provider0->next_proto = kProtoHTTP2; helper.AddDataWithSSLSocketDataProvider(&data0, std::move(ssl_provider0)); // Second socket: retry using HTTP/1.1. @@ -3932,7 +3913,7 @@ // Expect only HTTP/1.1 protocol in SSLConfig. ssl_provider1->next_protos_expected_in_ssl_config.push_back(kProtoHTTP11); // Force HTTP/1.1. - ssl_provider1->SetNextProto(kProtoHTTP11); + ssl_provider1->next_proto = kProtoHTTP11; helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1)); // A third socket is needed for the tunnelled connection. @@ -4195,12 +4176,11 @@ helper.RunPreTestSetup(); for (int i = 0; i < 2; ++i) { - std::unique_ptr<HttpNetworkTransaction> trans( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, helper.session()); TestCompletionCallback callback; - int rv = trans->Start( - &helper.request(), callback.callback(), BoundNetLog()); + int rv = + trans.Start(&helper.request(), callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // On the second transaction, we trigger the RST. if (i == 1) { @@ -4216,12 +4196,12 @@ rv = callback.WaitForResult(); EXPECT_THAT(rv, IsOk()); - const HttpResponseInfo* response = trans->GetResponseInfo(); + const HttpResponseInfo* response = trans.GetResponseInfo(); ASSERT_TRUE(response); EXPECT_TRUE(response->headers); EXPECT_TRUE(response->was_fetched_via_spdy); std::string response_data; - rv = ReadTransaction(trans.get(), &response_data); + rv = ReadTransaction(&trans, &response_data); EXPECT_THAT(rv, IsOk()); EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine()); EXPECT_EQ("hello!", response_data); @@ -4429,10 +4409,9 @@ // Request the pushed path. At this point, we've received the push, but the // headers are not yet complete. - std::unique_ptr<HttpNetworkTransaction> trans2( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - rv = trans2->Start( - &CreateGetPushRequest(), callback.callback(), BoundNetLog()); + HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session()); + rv = + trans2.Start(&CreateGetPushRequest(), callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); data.Resume(); data.RunUntilPaused(); @@ -4440,7 +4419,7 @@ // Read the server push body. std::string result2; - ReadResult(trans2.get(), &result2); + ReadResult(&trans2, &result2); // Read the response body. std::string result; ReadResult(trans, &result); @@ -4455,7 +4434,7 @@ // Verify the response headers. // Copy the response info, because trans goes away. response = *trans->GetResponseInfo(); - response2 = *trans2->GetResponseInfo(); + response2 = *trans2.GetResponseInfo(); VerifyStreamsClosed(helper); @@ -4545,10 +4524,9 @@ // Request the pushed path. At this point, we've received the push, but the // headers are not yet complete. - std::unique_ptr<HttpNetworkTransaction> trans2( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - rv = trans2->Start( - &CreateGetPushRequest(), callback.callback(), BoundNetLog()); + HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session()); + rv = + trans2.Start(&CreateGetPushRequest(), callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); data.Resume(); data.RunUntilPaused(); @@ -4560,7 +4538,7 @@ // Read the server push body. std::string result2; - ReadResult(trans2.get(), &result2); + ReadResult(&trans2, &result2); // Read the response body. std::string result; ReadResult(trans, &result); @@ -4571,7 +4549,7 @@ // Verify the response headers. // Copy the response info, because trans goes away. response = *trans->GetResponseInfo(); - response2 = *trans2->GetResponseInfo(); + response2 = *trans2.GetResponseInfo(); VerifyStreamsClosed(helper); @@ -4653,10 +4631,9 @@ // Request the pushed path. At this point, we've received the push, but the // headers are not yet complete. - std::unique_ptr<HttpNetworkTransaction> trans2( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - rv = trans2->Start( - &CreateGetPushRequest(), callback.callback(), BoundNetLog()); + HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session()); + rv = + trans2.Start(&CreateGetPushRequest(), callback.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); data.Resume(); data.RunUntilPaused(); @@ -4664,7 +4641,7 @@ // Read the server push body. std::string result2; - ReadResult(trans2.get(), &result2); + ReadResult(&trans2, &result2); // Read the response body. std::string result; ReadResult(trans, &result); @@ -4919,14 +4896,13 @@ EXPECT_EQ(1u, spdy_session->unclaimed_pushed_streams_.count(GURL(url_to_push))); - std::unique_ptr<HttpNetworkTransaction> trans1( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); + HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session()); HttpRequestInfo push_request; push_request.method = "GET"; push_request.url = GURL(url_to_push); push_request.load_flags = 0; TestCompletionCallback callback1; - rv = trans1->Start(&push_request, callback1.callback(), log); + rv = trans1.Start(&push_request, callback1.callback(), log); rv = callback1.GetResult(rv); EXPECT_THAT(rv, IsOk()); @@ -4944,12 +4920,12 @@ ReadResult(trans0, &result0); EXPECT_EQ("hello!", result0); - HttpResponseInfo push_response = *trans1->GetResponseInfo(); + HttpResponseInfo push_response = *trans1.GetResponseInfo(); EXPECT_TRUE(push_response.headers); EXPECT_EQ("HTTP/1.1 200", push_response.headers->GetStatusLine()); std::string result1; - ReadResult(trans1.get(), &result1); + ReadResult(&trans1, &result1); EXPECT_EQ(kPushedData, result1); } @@ -5041,14 +5017,13 @@ // Request |url_to_fetch1|, during which docs.example.org pushes // |url_to_push|, which happens to be for www.example.org, to which there is // already an open connection. - std::unique_ptr<HttpNetworkTransaction> trans1( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); + HttpNetworkTransaction trans1(DEFAULT_PRIORITY, helper.session()); HttpRequestInfo request1; request1.method = "GET"; request1.url = GURL(url_to_fetch1); request1.load_flags = 0; TestCompletionCallback callback1; - rv = trans1->Start(&request1, callback1.callback(), log); + rv = trans1.Start(&request1, callback1.callback(), log); rv = callback1.GetResult(rv); EXPECT_THAT(rv, IsOk()); @@ -5074,14 +5049,13 @@ spdy_session1->unclaimed_pushed_streams_.count(GURL(url_to_push))); // Request |url_to_push|, which should be served from the pushed resource. - std::unique_ptr<HttpNetworkTransaction> trans2( - new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); + HttpNetworkTransaction trans2(DEFAULT_PRIORITY, helper.session()); HttpRequestInfo push_request; push_request.method = "GET"; push_request.url = GURL(url_to_push); push_request.load_flags = 0; TestCompletionCallback callback2; - rv = trans2->Start(&push_request, callback2.callback(), log); + rv = trans2.Start(&push_request, callback2.callback(), log); rv = callback2.GetResult(rv); EXPECT_THAT(rv, IsOk()); @@ -5102,20 +5076,20 @@ ReadResult(trans0, &result0); EXPECT_EQ(kData0, result0); - HttpResponseInfo response1 = *trans1->GetResponseInfo(); + HttpResponseInfo response1 = *trans1.GetResponseInfo(); EXPECT_TRUE(response1.headers); EXPECT_EQ("HTTP/1.1 200", response1.headers->GetStatusLine()); std::string result1; - ReadResult(trans1.get(), &result1); + ReadResult(&trans1, &result1); EXPECT_EQ(kData1, result1); - HttpResponseInfo push_response = *trans2->GetResponseInfo(); + HttpResponseInfo push_response = *trans2.GetResponseInfo(); EXPECT_TRUE(push_response.headers); EXPECT_EQ("HTTP/1.1 200", push_response.headers->GetStatusLine()); std::string result2; - ReadResult(trans2.get(), &result2); + ReadResult(&trans2, &result2); EXPECT_EQ(kPushedData, result2); } @@ -5274,17 +5248,15 @@ // Now, start both new transactions HttpRequestInfo info2 = CreateGetRequest(); TestCompletionCallback callback2; - std::unique_ptr<HttpNetworkTransaction> trans2( - new HttpNetworkTransaction(MEDIUM, helper.session())); - rv = trans2->Start(&info2, callback2.callback(), BoundNetLog()); + HttpNetworkTransaction trans2(MEDIUM, helper.session()); + rv = trans2.Start(&info2, callback2.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); base::RunLoop().RunUntilIdle(); HttpRequestInfo info3 = CreateGetRequest(); TestCompletionCallback callback3; - std::unique_ptr<HttpNetworkTransaction> trans3( - new HttpNetworkTransaction(HIGHEST, helper.session())); - rv = trans3->Start(&info3, callback3.callback(), BoundNetLog()); + HttpNetworkTransaction trans3(HIGHEST, helper.session()); + rv = trans3.Start(&info3, callback3.callback(), BoundNetLog()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); base::RunLoop().RunUntilIdle();
diff --git a/net/spdy/spdy_proxy_client_socket.cc b/net/spdy/spdy_proxy_client_socket.cc index d33f59a..6fea1df4 100644 --- a/net/spdy/spdy_proxy_client_socket.cc +++ b/net/spdy/spdy_proxy_client_socket.cc
@@ -86,14 +86,8 @@ return true; } -NextProto SpdyProxyClientSocket::GetProtocolNegotiated() const { - // Save the negotiated protocol - SSLInfo ssl_info; - bool was_npn_negotiated; - NextProto protocol_negotiated; - spdy_stream_->GetSSLInfo(&ssl_info, &was_npn_negotiated, - &protocol_negotiated); - return protocol_negotiated; +NextProto SpdyProxyClientSocket::GetProxyNegotiatedProtocol() const { + return spdy_stream_->GetNegotiatedProtocol(); } HttpStream* SpdyProxyClientSocket::CreateConnectResponseStream() { @@ -179,10 +173,7 @@ } bool SpdyProxyClientSocket::GetSSLInfo(SSLInfo* ssl_info) { - bool was_npn_negotiated; - NextProto protocol_negotiated; - return spdy_stream_->GetSSLInfo(ssl_info, &was_npn_negotiated, - &protocol_negotiated); + return spdy_stream_->GetSSLInfo(ssl_info); } void SpdyProxyClientSocket::GetConnectionAttempts(
diff --git a/net/spdy/spdy_proxy_client_socket.h b/net/spdy/spdy_proxy_client_socket.h index 4d8baa8..c64b53a9 100644 --- a/net/spdy/spdy_proxy_client_socket.h +++ b/net/spdy/spdy_proxy_client_socket.h
@@ -59,7 +59,7 @@ const scoped_refptr<HttpAuthController>& GetAuthController() const override; int RestartWithAuth(const CompletionCallback& callback) override; bool IsUsingSpdy() const override; - NextProto GetProtocolNegotiated() const override; + NextProto GetProxyNegotiatedProtocol() const override; // StreamSocket implementation. int Connect(const CompletionCallback& callback) override;
diff --git a/net/spdy/spdy_read_queue.cc b/net/spdy/spdy_read_queue.cc index 7948ff4..adb06541 100644 --- a/net/spdy/spdy_read_queue.cc +++ b/net/spdy/spdy_read_queue.cc
@@ -52,7 +52,7 @@ } void SpdyReadQueue::Clear() { - STLDeleteElements(&queue_); + base::STLDeleteElements(&queue_); } } // namespace net
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc index 9daed1c..e915bd7d 100644 --- a/net/spdy/spdy_session.cc +++ b/net/spdy/spdy_session.cc
@@ -757,9 +757,7 @@ return false; SSLInfo ssl_info; - bool was_npn_negotiated; - NextProto protocol_negotiated = kProtoUnknown; - if (!GetSSLInfo(&ssl_info, &was_npn_negotiated, &protocol_negotiated)) + if (!GetSSLInfo(&ssl_info)) return true; // This is not a secure session, so all domains are okay. return CanPool(transport_security_state_, ssl_info, @@ -954,7 +952,7 @@ } SSLInfo ssl_info; - CHECK(connection_->socket()->GetSSLInfo(&ssl_info)); + CHECK(GetSSLInfo(&ssl_info)); // HTTP/2 requires TLS 1.2+ if (SSLConnectionStatusToVersion(ssl_info.connection_status) < @@ -1189,7 +1187,7 @@ } bool SpdySession::IsStreamActive(SpdyStreamId stream_id) const { - return ContainsKey(active_streams_, stream_id); + return base::ContainsKey(active_streams_, stream_id); } LoadState SpdySession::GetLoadState() const { @@ -1754,7 +1752,7 @@ dict->SetBoolean("is_secure", is_secure_); - dict->SetString("protocol_negotiated", + dict->SetString("negotiated_protocol", SSLClientSocket::NextProtoToString( connection_->socket()->GetNegotiatedProtocol())); @@ -1928,14 +1926,18 @@ host_port_pair().host(), host_port_pair().port()); } -bool SpdySession::GetSSLInfo(SSLInfo* ssl_info, - bool* was_npn_negotiated, - NextProto* protocol_negotiated) { - *was_npn_negotiated = connection_->socket()->WasNpnNegotiated(); - *protocol_negotiated = connection_->socket()->GetNegotiatedProtocol(); +bool SpdySession::GetSSLInfo(SSLInfo* ssl_info) const { return connection_->socket()->GetSSLInfo(ssl_info); } +bool SpdySession::WasNpnNegotiated() const { + return connection_->socket()->WasNpnNegotiated(); +} + +NextProto SpdySession::GetNegotiatedProtocol() const { + return connection_->socket()->GetNegotiatedProtocol(); +} + Error SpdySession::GetSignedEKMForTokenBinding(crypto::ECPrivateKey* key, std::vector<uint8_t>* out) { if (!is_secure_) { @@ -2288,9 +2290,7 @@ if (!gurl.SchemeIs("https")) return; SSLInfo ssl_info; - bool was_npn_negotiated; - NextProto protocol_negotiated = kProtoUnknown; - if (!GetSSLInfo(&ssl_info, &was_npn_negotiated, &protocol_negotiated)) + if (!GetSSLInfo(&ssl_info)) return; if (!CanPool(transport_security_state_, ssl_info, host_port_pair().host(), gurl.host())) { @@ -2594,7 +2594,7 @@ GURL associated_url(associated_it->second.stream->GetUrlFromHeaders()); if (associated_url.SchemeIs("https")) { SSLInfo ssl_info; - CHECK(connection_->socket()->GetSSLInfo(&ssl_info)); + CHECK(GetSSLInfo(&ssl_info)); if (!gurl.SchemeIs("https") || !CanPool(transport_security_state_, ssl_info, associated_url.host(), gurl.host())) {
diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h index b588ecc..e7c2ab1d6 100644 --- a/net/spdy/spdy_session.h +++ b/net/spdy/spdy_session.h
@@ -403,9 +403,14 @@ url::SchemeHostPort GetServer(); // Fills SSL info in |ssl_info| and returns true when SSL is in use. - bool GetSSLInfo(SSLInfo* ssl_info, - bool* was_npn_negotiated, - NextProto* protocol_negotiated); + bool GetSSLInfo(SSLInfo* ssl_info) const; + + // Returns true if ALPN was negotiated for the underlying socket. + // TODO(bnc): Rename to WasAlpnNegotiated(). + bool WasNpnNegotiated() const; + + // Returns the protocol negotiated via ALPN for the underlying socket. + NextProto GetNegotiatedProtocol() const; // Signs the EKM value for Token Binding from the TLS layer using |*key| and // puts the result in |*out|. Returns OK or ERR_FAILED.
diff --git a/net/spdy/spdy_session_pool.cc b/net/spdy/spdy_session_pool.cc index babda51a..eeacf6ed 100644 --- a/net/spdy/spdy_session_pool.cc +++ b/net/spdy/spdy_session_pool.cc
@@ -194,7 +194,7 @@ const base::WeakPtr<SpdySession>& available_session = available_session_it->second; - DCHECK(ContainsKey(sessions_, available_session.get())); + DCHECK(base::ContainsKey(sessions_, available_session.get())); // If the session is a secure one, we need to verify that the // server is authenticated to serve traffic for |host_port_proxy_pair| too. if (!available_session->VerifyDomainAuthentication( @@ -273,7 +273,7 @@ base::WeakPtr<SpdySession> spdy_session) { DCHECK(!url.is_empty()); // This SpdySessionPool must own |spdy_session|. - DCHECK(ContainsKey(sessions_, spdy_session.get())); + DCHECK(base::ContainsKey(sessions_, spdy_session.get())); UnclaimedPushedStreamMap::iterator url_it = unclaimed_pushed_streams_.lower_bound(url); if (url_it == unclaimed_pushed_streams_.end() || url_it->first != url) { @@ -384,7 +384,7 @@ void SpdySessionPool::MapKeyToAvailableSession( const SpdySessionKey& key, const base::WeakPtr<SpdySession>& session) { - DCHECK(ContainsKey(sessions_, session.get())); + DCHECK(base::ContainsKey(sessions_, session.get())); std::pair<AvailableSessionMap::iterator, bool> result = available_sessions_.insert(std::make_pair(key, session)); CHECK(result.second);
diff --git a/net/spdy/spdy_stream.cc b/net/spdy/spdy_stream.cc index e4148134..e3309627 100644 --- a/net/spdy/spdy_stream.cc +++ b/net/spdy/spdy_stream.cc
@@ -713,11 +713,16 @@ QueueNextDataFrame(); } -bool SpdyStream::GetSSLInfo(SSLInfo* ssl_info, - bool* was_npn_negotiated, - NextProto* protocol_negotiated) { - return session_->GetSSLInfo( - ssl_info, was_npn_negotiated, protocol_negotiated); +bool SpdyStream::GetSSLInfo(SSLInfo* ssl_info) const { + return session_->GetSSLInfo(ssl_info); +} + +bool SpdyStream::WasNpnNegotiated() const { + return session_->WasNpnNegotiated(); +} + +NextProto SpdyStream::GetNegotiatedProtocol() const { + return session_->GetNegotiatedProtocol(); } void SpdyStream::PossiblyResumeIfSendStalled() {
diff --git a/net/spdy/spdy_stream.h b/net/spdy/spdy_stream.h index ce30a0a..ee3cec5 100644 --- a/net/spdy/spdy_stream.h +++ b/net/spdy/spdy_stream.h
@@ -20,6 +20,7 @@ #include "net/base/net_export.h" #include "net/base/request_priority.h" #include "net/log/net_log.h" +#include "net/socket/next_proto.h" #include "net/socket/ssl_client_socket.h" #include "net/spdy/spdy_buffer.h" #include "net/spdy/spdy_framer.h" @@ -383,9 +384,14 @@ void SendData(IOBuffer* data, int length, SpdySendStatus send_status); // Fills SSL info in |ssl_info| and returns true when SSL is in use. - bool GetSSLInfo(SSLInfo* ssl_info, - bool* was_npn_negotiated, - NextProto* protocol_negotiated); + bool GetSSLInfo(SSLInfo* ssl_info) const; + + // Returns true if ALPN was negotiated for the underlying socket. + // TODO(bnc): Rename to WasAlpnNegotiated(). + bool WasNpnNegotiated() const; + + // Returns the protocol negotiated via ALPN for the underlying socket. + NextProto GetNegotiatedProtocol() const; // If the stream is stalled on sending data, but the session is not // stalled on sending data and |send_window_size_| is positive, then
diff --git a/net/spdy/spdy_stream_test_util.cc b/net/spdy/spdy_stream_test_util.cc index cbc53c2..9b250b2f 100644 --- a/net/spdy/spdy_stream_test_util.cc +++ b/net/spdy/spdy_stream_test_util.cc
@@ -92,9 +92,8 @@ size_t len = received_data_queue_.GetTotalSize(); std::string received_data(len, '\0'); if (len > 0) { - EXPECT_EQ( - len, - received_data_queue_.Dequeue(string_as_array(&received_data), len)); + EXPECT_EQ(len, received_data_queue_.Dequeue( + base::string_as_array(&received_data), len)); } return received_data; }
diff --git a/net/spdy/spdy_write_queue.cc b/net/spdy/spdy_write_queue.cc index b49573c..cc0d787e 100644 --- a/net/spdy/spdy_write_queue.cc +++ b/net/spdy/spdy_write_queue.cc
@@ -117,7 +117,7 @@ } queue->erase(out_it, queue->end()); removing_writes_ = false; - STLDeleteElements(&erased_buffer_producers); // Invokes callbacks. + base::STLDeleteElements(&erased_buffer_producers); // Invokes callbacks. } void SpdyWriteQueue::RemovePendingWritesForStreamsAfter( @@ -143,7 +143,7 @@ queue->erase(out_it, queue->end()); } removing_writes_ = false; - STLDeleteElements(&erased_buffer_producers); // Invokes callbacks. + base::STLDeleteElements(&erased_buffer_producers); // Invokes callbacks. } void SpdyWriteQueue::Clear() { @@ -159,7 +159,7 @@ queue_[i].clear(); } removing_writes_ = false; - STLDeleteElements(&erased_buffer_producers); // Invokes callbacks. + base::STLDeleteElements(&erased_buffer_producers); // Invokes callbacks. } } // namespace net
diff --git a/net/ssl/channel_id_service.cc b/net/ssl/channel_id_service.cc index 9adf74b..021504b 100644 --- a/net/ssl/channel_id_service.cc +++ b/net/ssl/channel_id_service.cc
@@ -285,7 +285,7 @@ weak_ptr_factory_(this) {} ChannelIDService::~ChannelIDService() { - STLDeleteValues(&inflight_); + base::STLDeleteValues(&inflight_); } // static
diff --git a/net/ssl/ssl_info.cc b/net/ssl/ssl_info.cc index ce7c949..12b3d4a 100644 --- a/net/ssl/ssl_info.cc +++ b/net/ssl/ssl_info.cc
@@ -77,18 +77,9 @@ void SSLInfo::UpdateCertificateTransparencyInfo( const ct::CTVerifyResult& ct_verify_result) { - for (const auto& sct : ct_verify_result.verified_scts) { - signed_certificate_timestamps.push_back( - SignedCertificateTimestampAndStatus(sct, ct::SCT_STATUS_OK)); - } - for (const auto& sct : ct_verify_result.invalid_scts) { - signed_certificate_timestamps.push_back( - SignedCertificateTimestampAndStatus(sct, ct::SCT_STATUS_INVALID)); - } - for (const auto& sct : ct_verify_result.unknown_logs_scts) { - signed_certificate_timestamps.push_back( - SignedCertificateTimestampAndStatus(sct, ct::SCT_STATUS_LOG_UNKNOWN)); - } + signed_certificate_timestamps.insert(signed_certificate_timestamps.end(), + ct_verify_result.scts.begin(), + ct_verify_result.scts.end()); ct_compliance_details_available = ct_verify_result.ct_policies_applied; ct_cert_policy_compliance = ct_verify_result.cert_policy_compliance;
diff --git a/net/test/ct_test_util.cc b/net/test/ct_test_util.cc index 3d79967f..c8b25f88 100644 --- a/net/test/ct_test_util.cc +++ b/net/test/ct_test_util.cc
@@ -399,15 +399,19 @@ bool CheckForSingleVerifiedSCTInResult(const ct::CTVerifyResult& result, const std::string& log_description) { - return (result.verified_scts.size() == 1U) && result.invalid_scts.empty() && - result.unknown_logs_scts.empty() && - result.verified_scts[0]->log_description == log_description; + return (result.scts.size() == 1 && + result.scts[0].status == ct::SCT_STATUS_OK && + result.scts[0].sct->log_description == log_description); } bool CheckForSCTOrigin(const ct::CTVerifyResult& result, ct::SignedCertificateTimestamp::Origin origin) { - return (result.verified_scts.size() > 0) && - (result.verified_scts[0]->origin == origin); + for (const auto& sct_and_status : result.scts) + if (sct_and_status.status == SCT_STATUS_OK && + sct_and_status.sct->origin == origin) + return true; + + return false; } } // namespace ct
diff --git a/net/test/embedded_test_server/embedded_test_server.cc b/net/test/embedded_test_server/embedded_test_server.cc index 28b65a5a..83f15f36 100644 --- a/net/test/embedded_test_server/embedded_test_server.cc +++ b/net/test/embedded_test_server/embedded_test_server.cc
@@ -170,8 +170,8 @@ DCHECK(io_thread_->task_runner()->BelongsToCurrentThread()); weak_factory_.InvalidateWeakPtrs(); listen_socket_.reset(); - STLDeleteContainerPairSecondPointers(connections_.begin(), - connections_.end()); + base::STLDeleteContainerPairSecondPointers(connections_.begin(), + connections_.end()); connections_.clear(); } @@ -343,8 +343,8 @@ } void EmbeddedTestServer::FlushAllSocketsAndConnections() { - STLDeleteContainerPairSecondPointers(connections_.begin(), - connections_.end()); + base::STLDeleteContainerPairSecondPointers(connections_.begin(), + connections_.end()); connections_.clear(); }
diff --git a/net/tools/cert_verify_tool/verify_using_path_builder.cc b/net/tools/cert_verify_tool/verify_using_path_builder.cc index 2520e6d0..bdfa120 100644 --- a/net/tools/cert_verify_tool/verify_using_path_builder.cc +++ b/net/tools/cert_verify_tool/verify_using_path_builder.cc
@@ -49,21 +49,34 @@ return result; } -// Dumps a chain of ParsedCertificate objects to a PEM file. -bool DumpParsedCertificateChain( - const base::FilePath& file_path, - const std::vector<scoped_refptr<net::ParsedCertificate>>& chain) { - std::vector<std::string> pem_encoded_chain; - for (const auto& cert : chain) { - std::string der_cert; - cert->der_cert().AsStringPiece().CopyToString(&der_cert); - std::string pem; - if (!net::X509Certificate::GetPEMEncodedFromDER(der_cert, &pem)) { - std::cerr << "ERROR: GetPEMEncodedFromDER failed\n"; - return false; - } - pem_encoded_chain.push_back(pem); +bool AddPemEncodedCert(const net::ParsedCertificate* cert, + std::vector<std::string>* pem_encoded_chain) { + std::string der_cert; + cert->der_cert().AsStringPiece().CopyToString(&der_cert); + std::string pem; + if (!net::X509Certificate::GetPEMEncodedFromDER(der_cert, &pem)) { + std::cerr << "ERROR: GetPEMEncodedFromDER failed\n"; + return false; } + pem_encoded_chain->push_back(pem); + return true; +} + +// Dumps a chain of ParsedCertificate objects to a PEM file. +bool DumpParsedCertificateChain(const base::FilePath& file_path, + const net::CertPath& chain) { + std::vector<std::string> pem_encoded_chain; + for (const auto& cert : chain.certs) { + if (!AddPemEncodedCert(cert.get(), &pem_encoded_chain)) + return false; + } + + if (chain.trust_anchor && chain.trust_anchor->cert()) { + if (!AddPemEncodedCert(chain.trust_anchor->cert().get(), + &pem_encoded_chain)) + return false; + } + return WriteToFile(file_path, base::JoinString(pem_encoded_chain, "")); } @@ -73,10 +86,9 @@ return base::HexEncode(hash.data(), hash.size()); } -// Returns a textual representation of the Subject of |cert|. -std::string SubjectFromParsedCertificate(const net::ParsedCertificate* cert) { +std::string SubjectToString(const net::der::Input& subject_tlv) { net::RDNSequence subject, issuer; - if (!net::ParseName(cert->tbs().subject_tlv, &subject)) + if (!net::ParseName(subject_tlv, &subject)) return std::string(); std::string subject_str; if (!net::ConvertToRFC2253(subject, &subject_str)) @@ -84,6 +96,11 @@ return subject_str; } +// Returns a textual representation of the Subject of |cert|. +std::string SubjectFromParsedCertificate(const net::ParsedCertificate* cert) { + return SubjectToString(cert->tbs().subject_tlv); +} + } // namespace // Verifies |target_der_cert| using CertPathBuilder. @@ -108,8 +125,10 @@ {}); if (!cert) PrintCertError("ERROR: ParsedCertificate failed:", der_cert); - else - trust_store.AddTrustedCertificate(cert); + else { + trust_store.AddTrustAnchor( + net::TrustAnchor::CreateFromCertificateNoConstraints(cert)); + } } net::CertIssuerSourceStatic intermediate_cert_issuer_source; @@ -172,10 +191,21 @@ std::cout << "path " << i << " " << net::ErrorToShortString(result.paths[i]->error) << ((result.best_result_index == i) ? " (best)" : "") << "\n"; - for (const auto& cert : result.paths[i]->path) { + for (const auto& cert : result.paths[i]->path.certs) { std::cout << " " << FingerPrintParsedCertificate(cert.get()) << " " << SubjectFromParsedCertificate(cert.get()) << "\n"; } + + const auto& trust_anchor = result.paths[i]->path.trust_anchor; + if (trust_anchor) { + std::string trust_anchor_cert_fingerprint = "<no cert>"; + if (trust_anchor->cert()) { + trust_anchor_cert_fingerprint = + FingerPrintParsedCertificate(trust_anchor->cert().get()); + } + std::cout << " " << trust_anchor_cert_fingerprint << " " + << SubjectToString(trust_anchor->normalized_subject()) << "\n"; + } } // TODO(mattm): add flag to dump all paths, not just the final one?
diff --git a/net/tools/epoll_server/epoll_server.cc b/net/tools/epoll_server/epoll_server.cc index 7aec113..042e403 100644 --- a/net/tools/epoll_server/epoll_server.cc +++ b/net/tools/epoll_server/epoll_server.cc
@@ -442,7 +442,7 @@ void EpollServer::RegisterAlarm(int64_t timeout_time_in_us, AlarmCB* ac) { CHECK(ac); - if (ContainsKey(all_alarms_, ac)) { + if (base::ContainsKey(all_alarms_, ac)) { LOG(FATAL) << "Alarm already exists " << ac; } VLOG(4) << "RegisteringAlarm at : " << timeout_time_in_us;
diff --git a/net/tools/quic/chlo_extractor.cc b/net/tools/quic/chlo_extractor.cc index 16972345..24c9ab0 100644 --- a/net/tools/quic/chlo_extractor.cc +++ b/net/tools/quic/chlo_extractor.cc
@@ -148,7 +148,9 @@ void ChloFramerVisitor::OnHandshakeMessage( const CryptoHandshakeMessage& message) { - delegate_->OnChlo(framer_->version(), connection_id_, message); + if (delegate_ != nullptr) { + delegate_->OnChlo(framer_->version(), connection_id_, message); + } found_chlo_ = true; }
diff --git a/net/tools/quic/chlo_extractor_test.cc b/net/tools/quic/chlo_extractor_test.cc index b5ec107..1be18208c 100644 --- a/net/tools/quic/chlo_extractor_test.cc +++ b/net/tools/quic/chlo_extractor_test.cc
@@ -48,7 +48,7 @@ header_.public_header.connection_id_length = PACKET_8BYTE_CONNECTION_ID; header_.public_header.version_flag = true; header_.public_header.versions = - SupportedVersions(QuicSupportedVersions().front()); + SupportedVersions(AllSupportedVersions().front()); header_.public_header.reset_flag = false; header_.public_header.packet_number_length = PACKET_6BYTE_PACKET_NUMBER; header_.packet_number = 1; @@ -88,7 +88,7 @@ string client_hello_str( client_hello.GetSerialized().AsStringPiece().as_string()); // Construct a CHLO with each supported version - for (QuicVersion version : QuicSupportedVersions()) { + for (QuicVersion version : AllSupportedVersions()) { QuicVersionVector versions(SupportedVersions(version)); header_.public_header.versions = versions; MakePacket( @@ -111,7 +111,7 @@ MakePacket( new QuicStreamFrame(kCryptoStreamId + 1, false, 0, client_hello_str)); EXPECT_FALSE( - ChloExtractor::Extract(*packet_, QuicSupportedVersions(), &delegate_)); + ChloExtractor::Extract(*packet_, AllSupportedVersions(), &delegate_)); } TEST_F(ChloExtractorTest, DoesNotFindValidChloOnWrongOffset) { @@ -122,13 +122,13 @@ client_hello.GetSerialized().AsStringPiece().as_string()); MakePacket(new QuicStreamFrame(kCryptoStreamId, false, 1, client_hello_str)); EXPECT_FALSE( - ChloExtractor::Extract(*packet_, QuicSupportedVersions(), &delegate_)); + ChloExtractor::Extract(*packet_, AllSupportedVersions(), &delegate_)); } TEST_F(ChloExtractorTest, DoesNotFindInvalidChlo) { MakePacket(new QuicStreamFrame(kCryptoStreamId, false, 0, "foo")); EXPECT_FALSE( - ChloExtractor::Extract(*packet_, QuicSupportedVersions(), &delegate_)); + ChloExtractor::Extract(*packet_, AllSupportedVersions(), &delegate_)); } } // namespace
diff --git a/net/tools/quic/end_to_end_test.cc b/net/tools/quic/end_to_end_test.cc index c6156a6..246c0aa3 100644 --- a/net/tools/quic/end_to_end_test.cc +++ b/net/tools/quic/end_to_end_test.cc
@@ -48,6 +48,7 @@ #include "net/tools/quic/quic_spdy_client_stream.h" #include "net/tools/quic/test_tools/http_message.h" #include "net/tools/quic/test_tools/packet_dropping_test_writer.h" +#include "net/tools/quic/test_tools/packet_reordering_writer.h" #include "net/tools/quic/test_tools/quic_client_peer.h" #include "net/tools/quic/test_tools/quic_dispatcher_peer.h" #include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h" @@ -100,7 +101,9 @@ bool server_uses_stateless_rejects_if_peer_supported, QuicTag congestion_control_tag, bool disable_hpack_dynamic_table, - bool force_hol_blocking) + bool force_hol_blocking, + bool use_cheap_stateless_reject, + bool buffer_packet_till_chlo) : client_supported_versions(client_supported_versions), server_supported_versions(server_supported_versions), negotiated_version(negotiated_version), @@ -109,7 +112,9 @@ server_uses_stateless_rejects_if_peer_supported), congestion_control_tag(congestion_control_tag), disable_hpack_dynamic_table(disable_hpack_dynamic_table), - force_hol_blocking(force_hol_blocking) {} + force_hol_blocking(force_hol_blocking), + use_cheap_stateless_reject(use_cheap_stateless_reject), + buffer_packet_till_chlo(buffer_packet_till_chlo) {} friend ostream& operator<<(ostream& os, const TestParams& p) { os << "{ server_supported_versions: " @@ -124,7 +129,9 @@ os << " congestion_control_tag: " << QuicUtils::TagToString(p.congestion_control_tag); os << " disable_hpack_dynamic_table: " << p.disable_hpack_dynamic_table; - os << " force_hol_blocking: " << p.force_hol_blocking << " }"; + os << " force_hol_blocking: " << p.force_hol_blocking; + os << " use_cheap_stateless_reject: " << p.use_cheap_stateless_reject; + os << " buffer_packet_till_chlo: " << p.buffer_packet_till_chlo << " }"; return os; } @@ -136,6 +143,8 @@ QuicTag congestion_control_tag; bool disable_hpack_dynamic_table; bool force_hol_blocking; + bool use_cheap_stateless_reject; + bool buffer_packet_till_chlo; }; // Constructs various test permutations. @@ -148,7 +157,7 @@ // these tests need to ensure that clients are never attempting // to do 0-RTT across incompatible versions. Chromium only supports // a single version at a time anyway. :) - QuicVersionVector all_supported_versions = QuicSupportedVersions(); + QuicVersionVector all_supported_versions = AllSupportedVersions(); QuicVersionVector version_buckets[4]; for (const QuicVersion version : all_supported_versions) { @@ -174,7 +183,7 @@ // This must be kept in sync with the number of nested for-loops below as it // is used to prune the number of tests that are run. - const int kMaxEnabledOptions = 4; + const int kMaxEnabledOptions = 6; int max_enabled_options = 0; vector<TestParams> params; for (bool server_uses_stateless_rejects_if_peer_supported : {true, false}) { @@ -182,73 +191,93 @@ for (const QuicTag congestion_control_tag : {kRENO, kQBIC}) { for (bool disable_hpack_dynamic_table : {false}) { for (bool force_hol_blocking : {true, false}) { - int enabled_options = 0; - if (force_hol_blocking) { - ++enabled_options; - } - if (congestion_control_tag != kQBIC) { - ++enabled_options; - } - if (disable_hpack_dynamic_table) { - ++enabled_options; - } - if (client_supports_stateless_rejects) { - ++enabled_options; - } - if (server_uses_stateless_rejects_if_peer_supported) { - ++enabled_options; - } - CHECK_GE(kMaxEnabledOptions, enabled_options); - if (enabled_options > max_enabled_options) { - max_enabled_options = enabled_options; - } + for (bool use_cheap_stateless_reject : {true, false}) { + for (bool buffer_packet_till_chlo : {true, false}) { + if (!buffer_packet_till_chlo && use_cheap_stateless_reject) { + // Doing stateless reject while not buffering packet + // before CHLO is not allowed. + break; + } + int enabled_options = 0; + if (force_hol_blocking) { + ++enabled_options; + } + if (congestion_control_tag != kQBIC) { + ++enabled_options; + } + if (disable_hpack_dynamic_table) { + ++enabled_options; + } + if (client_supports_stateless_rejects) { + ++enabled_options; + } + if (server_uses_stateless_rejects_if_peer_supported) { + ++enabled_options; + } + if (buffer_packet_till_chlo) { + ++enabled_options; + } + if (use_cheap_stateless_reject) { + ++enabled_options; + } + CHECK_GE(kMaxEnabledOptions, enabled_options); + if (enabled_options > max_enabled_options) { + max_enabled_options = enabled_options; + } - // Run tests with no options, a single option, or all the options - // enabled to avoid a combinatorial explosion. - if (enabled_options > 1 && enabled_options < kMaxEnabledOptions) { - continue; - } + // Run tests with no options, a single option, or all the + // options enabled to avoid a combinatorial explosion. + if (enabled_options > 1 && + enabled_options < kMaxEnabledOptions) { + continue; + } - for (const QuicVersionVector& client_versions : version_buckets) { - CHECK(!client_versions.empty()); - // Add an entry for server and client supporting all versions. - params.push_back(TestParams( - client_versions, all_supported_versions, - client_versions.front(), client_supports_stateless_rejects, - server_uses_stateless_rejects_if_peer_supported, - congestion_control_tag, disable_hpack_dynamic_table, - force_hol_blocking)); + for (const QuicVersionVector& client_versions : + version_buckets) { + CHECK(!client_versions.empty()); + // Add an entry for server and client supporting all versions. + params.push_back(TestParams( + client_versions, all_supported_versions, + client_versions.front(), + client_supports_stateless_rejects, + server_uses_stateless_rejects_if_peer_supported, + congestion_control_tag, disable_hpack_dynamic_table, + force_hol_blocking, use_cheap_stateless_reject, + buffer_packet_till_chlo)); - // Run version negotiation tests tests with no options, or all - // the options enabled to avoid a combinatorial explosion. - if (enabled_options > 0 && enabled_options < kMaxEnabledOptions) { - continue; - } + // Run version negotiation tests tests with no options, or all + // the options enabled to avoid a combinatorial explosion. + if (enabled_options > 0 && + enabled_options < kMaxEnabledOptions) { + continue; + } - // Test client supporting all versions and server - // supporting 1 version. Simulate an old server and - // exercise version downgrade in the client. Protocol - // negotiation should occur. Skip the i = 0 case - // because it is essentially the same as the default - // case. - for (size_t i = 1; i < client_versions.size(); ++i) { - QuicVersionVector server_supported_versions; - server_supported_versions.push_back(client_versions[i]); - params.push_back(TestParams( - client_versions, server_supported_versions, - server_supported_versions.front(), - client_supports_stateless_rejects, - server_uses_stateless_rejects_if_peer_supported, - congestion_control_tag, disable_hpack_dynamic_table, - force_hol_blocking)); - } - } - } - } - } - } + // Test client supporting all versions and server supporting 1 + // version. Simulate an old server and exercise version + // downgrade in the client. Protocol negotiation should occur. + // Skip the i = 0 case because it is essentially the same as + // the default case. + for (size_t i = 1; i < client_versions.size(); ++i) { + QuicVersionVector server_supported_versions; + server_supported_versions.push_back(client_versions[i]); + params.push_back(TestParams( + client_versions, server_supported_versions, + server_supported_versions.front(), + client_supports_stateless_rejects, + server_uses_stateless_rejects_if_peer_supported, + congestion_control_tag, disable_hpack_dynamic_table, + force_hol_blocking, use_cheap_stateless_reject, + buffer_packet_till_chlo)); + } // End of version for loop. + } // End of 2nd version for loop. + } // End of buffer_packet_till_chlo loop. + } // End of use_cheap_stateless_reject for loop. + } // End of force_hol_blocking loop. + } // End of disable_hpack_dynamic_table for loop. + } // End of congestion_control_tag for loop. + } // End of client_supports_stateless_rejects for loop. CHECK_EQ(kMaxEnabledOptions, max_enabled_options); - } + } // End of server_uses_stateless_rejects_if_peer_supported for loop. return params; } @@ -282,6 +311,8 @@ : initialized_(false), server_address_(IPEndPoint(Loopback4(), 0)), server_hostname_("test.example.com"), + client_writer_(nullptr), + server_writer_(nullptr), server_started_(false), strike_register_no_startup_period_(false), chlo_multiplier_(0), @@ -322,6 +353,10 @@ QuicInMemoryCachePeer::ResetForTests(); } + virtual void CreateClientWithWriter() { + client_.reset(CreateQuicClient(client_writer_)); + } + QuicTestClient* CreateQuicClient(QuicPacketWriterWrapper* writer) { QuicTestClient* client = new QuicTestClient( server_address_, server_hostname_, client_config_, @@ -394,7 +429,6 @@ } if (GetParam().force_hol_blocking) { client_config_.SetForceHolBlocking(); - QuicConfigPeer::SetReceivedForceHolBlocking(&server_config_); } client_config_.SetConnectionOptionsToSend(copt); @@ -402,16 +436,17 @@ // to connect to the server. StartServer(); - client_.reset(CreateQuicClient(client_writer_)); + CreateClientWithWriter(); static EpollEvent event(EPOLLOUT, false); - client_writer_->Initialize( - reinterpret_cast<QuicEpollConnectionHelper*>( - QuicConnectionPeer::GetHelper( - client_->client()->session()->connection())), - QuicConnectionPeer::GetAlarmFactory( - client_->client()->session()->connection()), - new ClientDelegate(client_->client())); - + if (client_writer_ != nullptr) { + client_writer_->Initialize( + reinterpret_cast<QuicEpollConnectionHelper*>( + QuicConnectionPeer::GetHelper( + client_->client()->session()->connection())), + QuicConnectionPeer::GetAlarmFactory( + client_->client()->session()->connection()), + new ClientDelegate(client_->client())); + } initialized_ = true; return client_->client()->connected(); } @@ -430,6 +465,9 @@ } void StartServer() { + FLAGS_quic_buffer_packet_till_chlo = GetParam().buffer_packet_till_chlo; + FLAGS_quic_use_cheap_stateless_rejects = + GetParam().use_cheap_stateless_reject; server_thread_.reset(new ServerThread( new QuicTestServer(CryptoTestUtils::ProofSourceForTesting(), server_config_, server_supported_versions_), @@ -2787,6 +2825,61 @@ } } +class EndToEndBufferedPacketsTest : public EndToEndTest { + public: + EndToEndBufferedPacketsTest() : EndToEndTest() { + FLAGS_quic_buffer_packet_till_chlo = true; + } + + void CreateClientWithWriter() override { + LOG(ERROR) << "create client with reorder_writer_ "; + reorder_writer_ = new PacketReorderingWriter(); + client_.reset(EndToEndTest::CreateQuicClient(reorder_writer_)); + } + + void SetUp() override { + // Don't initialize client writer in base class. + server_writer_ = new PacketDroppingTestWriter(); + } + + protected: + PacketReorderingWriter* reorder_writer_; +}; + +INSTANTIATE_TEST_CASE_P(EndToEndBufferedPacketsTests, + EndToEndBufferedPacketsTest, + testing::ValuesIn(GetTestParams())); + +TEST_P(EndToEndBufferedPacketsTest, Buffer0RttRequest) { + ASSERT_TRUE(Initialize()); + if (negotiated_version_ <= QUIC_VERSION_32) { + // Since no 0-rtt for v32 and under, and this test relies on 0-rtt, skip + // this test if QUIC doesn't do 0-rtt. + return; + } + // Finish one request to make sure handshake established. + client_->SendSynchronousRequest("/foo"); + // Disconnect for next 0-rtt request. + client_->Disconnect(); + + // Client get valid STK now. Do a 0-rtt request. + // Buffer a CHLO till another packets sent out. + reorder_writer_->SetDelay(1); + // Only send out a CHLO. + client_->client()->Initialize(); + client_->client()->StartConnect(); + ASSERT_TRUE(client_->client()->connected()); + // Send a request before handshake finishes. + HTTPMessage request(HttpConstants::HTTP_1_1, HttpConstants::GET, "/bar"); + client_->SendMessage(request); + client_->WaitForResponse(); + EXPECT_EQ(kBarResponseBody, client_->response_body()); + QuicConnectionStats client_stats = + client_->client()->session()->connection()->GetStats(); + EXPECT_EQ(0u, client_stats.packets_lost); + EXPECT_EQ(1, client_->client()->GetNumSentClientHellos()); +} + } // namespace } // namespace test } // namespace net
diff --git a/net/tools/quic/quic_client.cc b/net/tools/quic/quic_client.cc index c279720..5808caa 100644 --- a/net/tools/quic/quic_client.cc +++ b/net/tools/quic/quic_client.cc
@@ -89,8 +89,8 @@ ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); } - STLDeleteElements(&data_to_resend_on_connect_); - STLDeleteElements(&data_sent_before_handshake_); + base::STLDeleteElements(&data_to_resend_on_connect_); + base::STLDeleteElements(&data_sent_before_handshake_); CleanUpAllUDPSockets(); } @@ -193,7 +193,7 @@ for (QuicDataToResend* data : data_to_resend_on_connect_) { data->Resend(); } - STLDeleteElements(&data_to_resend_on_connect_); + base::STLDeleteElements(&data_to_resend_on_connect_); } if (session() != nullptr && session()->error() != QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { @@ -252,8 +252,8 @@ QUIC_PEER_GOING_AWAY, "Client disconnecting", ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); } - STLDeleteElements(&data_to_resend_on_connect_); - STLDeleteElements(&data_sent_before_handshake_); + base::STLDeleteElements(&data_to_resend_on_connect_); + base::STLDeleteElements(&data_sent_before_handshake_); CleanUpAllUDPSockets(); @@ -320,7 +320,7 @@ if (session()->IsCryptoHandshakeConfirmed()) { // The handshake is confirmed. No need to continue saving requests to // resend. - STLDeleteElements(&data_sent_before_handshake_); + base::STLDeleteElements(&data_sent_before_handshake_); delete data_to_resend; return; }
diff --git a/net/tools/quic/quic_client_base.h b/net/tools/quic/quic_client_base.h index ca2ecf3f..70aa0673 100644 --- a/net/tools/quic/quic_client_base.h +++ b/net/tools/quic/quic_client_base.h
@@ -165,6 +165,7 @@ } protected: + // Takes ownership of |connection|. virtual QuicClientSession* CreateQuicClientSession( QuicConnection* connection);
diff --git a/net/tools/quic/quic_client_bin.cc b/net/tools/quic/quic_client_bin.cc index 3b50518..065bb995 100644 --- a/net/tools/quic/quic_client_bin.cc +++ b/net/tools/quic/quic_client_bin.cc
@@ -239,7 +239,7 @@ net::EpollServer epoll_server; net::QuicServerId server_id(url.host(), url.EffectiveIntPort(), net::PRIVACY_MODE_DISABLED); - net::QuicVersionVector versions = net::QuicSupportedVersions(); + net::QuicVersionVector versions = net::AllSupportedVersions(); if (FLAGS_quic_version != -1) { versions.clear(); versions.push_back(static_cast<net::QuicVersion>(FLAGS_quic_version));
diff --git a/net/tools/quic/quic_client_session.h b/net/tools/quic/quic_client_session.h index 5057a52..af9ee09 100644 --- a/net/tools/quic/quic_client_session.h +++ b/net/tools/quic/quic_client_session.h
@@ -24,7 +24,8 @@ class QuicClientSession : public QuicClientSessionBase { public: - // Caller retains ownership of |promised_by_url|. + // Takes ownership of |connection|. Caller retains ownership of + // |promised_by_url|. QuicClientSession(const QuicConfig& config, QuicConnection* connection, const QuicServerId& server_id,
diff --git a/net/tools/quic/quic_client_session_test.cc b/net/tools/quic/quic_client_session_test.cc index 8ce9a39..d4ecd2b 100644 --- a/net/tools/quic/quic_client_session_test.cc +++ b/net/tools/quic/quic_client_session_test.cc
@@ -141,7 +141,7 @@ INSTANTIATE_TEST_CASE_P(Tests, QuicClientSessionTest, - ::testing::ValuesIn(QuicSupportedVersions())); + ::testing::ValuesIn(AllSupportedVersions())); TEST_P(QuicClientSessionTest, CryptoConnect) { CompleteCryptoHandshake();
diff --git a/net/tools/quic/quic_client_test.cc b/net/tools/quic/quic_client_test.cc index 74910aca..dd360de3 100644 --- a/net/tools/quic/quic_client_test.cc +++ b/net/tools/quic/quic_client_test.cc
@@ -43,7 +43,7 @@ IPEndPoint server_address(IPEndPoint(net::test::Loopback4(), port)); QuicServerId server_id("hostname", server_address.port(), PRIVACY_MODE_DISABLED); - QuicVersionVector versions = QuicSupportedVersions(); + QuicVersionVector versions = AllSupportedVersions(); QuicClient* client = new QuicClient(server_address, server_id, versions, eps, CryptoTestUtils::ProofVerifierForTesting());
diff --git a/net/tools/quic/quic_dispatcher.cc b/net/tools/quic/quic_dispatcher.cc index 6100b59..e471b15 100644 --- a/net/tools/quic/quic_dispatcher.cc +++ b/net/tools/quic/quic_dispatcher.cc
@@ -25,6 +25,10 @@ namespace net { +typedef QuicBufferedPacketStore::BufferedPacket BufferedPacket; +typedef QuicBufferedPacketStore::BufferedPacketList BufferedPacketList; +typedef QuicBufferedPacketStore::EnqueuePacketResult EnqueuePacketResult; + namespace { // An alarm that informs the QuicDispatcher to delete old sessions. @@ -211,8 +215,8 @@ } QuicDispatcher::~QuicDispatcher() { - STLDeleteValues(&session_map_); - STLDeleteElements(&closed_session_list_); + base::STLDeleteValues(&session_map_); + base::STLDeleteElements(&closed_session_list_); } void QuicDispatcher::InitializeWithWriter(QuicPacketWriter* writer) { @@ -327,23 +331,7 @@ } switch (fate) { case kFateProcess: { - // Create a session and process the packet. - QuicServerSessionBase* session = - CreateQuicSession(connection_id, current_client_address_); - DVLOG(1) << "Created new session for " << connection_id; - session_map_.insert(std::make_pair(connection_id, session)); - session->ProcessUdpPacket(current_server_address_, - current_client_address_, *current_packet_); - std::list<QuicBufferedPacketStore::BufferedPacket> packets = - buffered_packets_.DeliverPackets(connection_id); - for (const auto& packet : packets) { - SessionMap::iterator it = session_map_.find(connection_id); - if (it == session_map_.end()) { - break; - } - it->second->ProcessUdpPacket(packet.server_address, - packet.client_address, *packet.packet); - } + ProcessChlo(); break; } case kFateTimeWait: @@ -367,6 +355,11 @@ header.public_header.connection_id, header.packet_number, *current_packet_); break; + case kFateBuffer: + // This packet is a non-CHLO packet which has arrived out of order. + // Buffer it. + BufferEarlyPacket(connection_id); + break; case kFateDrop: // Do nothing with the packet. break; @@ -422,7 +415,7 @@ } void QuicDispatcher::DeleteSessions() { - STLDeleteElements(&closed_session_list_); + base::STLDeleteElements(&closed_session_list_); } void QuicDispatcher::OnCanWrite() { @@ -606,7 +599,25 @@ void QuicDispatcher::OnExpiredPackets( QuicConnectionId connection_id, - QuicBufferedPacketStore::BufferedPacketList early_arrived_packets) {} + BufferedPacketList early_arrived_packets) { + time_wait_list_manager_->AddConnectionIdToTimeWait( + connection_id, framer_.version(), false, nullptr); +} + +void QuicDispatcher::OnNewConnectionAdded(QuicConnectionId connection_id) { + VLOG(1) << "Received packet from new connection " << connection_id; +} + +// Return true if there is any packet buffered in the store. +bool QuicDispatcher::HasBufferedPackets(QuicConnectionId connection_id) { + return buffered_packets_.HasBufferedPackets(connection_id); +} + +void QuicDispatcher::OnBufferPacketFailure(EnqueuePacketResult result, + QuicConnectionId connection_id) { + DVLOG(1) << "Fail to buffer packet on connection " << connection_id + << " because of " << result; +} void QuicDispatcher::OnConnectionRejectedStatelessly() {} @@ -621,6 +632,43 @@ alarm_factory_.get()); } +void QuicDispatcher::BufferEarlyPacket(QuicConnectionId connection_id) { + bool is_new_connection = !buffered_packets_.HasBufferedPackets(connection_id); + EnqueuePacketResult rs = buffered_packets_.EnqueuePacket( + connection_id, *current_packet_, current_server_address_, + current_client_address_); + if (rs != EnqueuePacketResult::SUCCESS) { + OnBufferPacketFailure(rs, connection_id); + } else if (is_new_connection) { + OnNewConnectionAdded(connection_id); + } +} + +void QuicDispatcher::ProcessChlo() { + // Creates a new session and process all buffered packets for this connection. + QuicServerSessionBase* session = + CreateQuicSession(current_connection_id_, current_client_address_); + DVLOG(1) << "Created new session for " << current_connection_id_; + session_map_.insert(std::make_pair(current_connection_id_, session)); + std::list<BufferedPacket> packets = + buffered_packets_.DeliverPackets(current_connection_id_); + // Check if CHLO is the first packet arrived on this connection. + if (FLAGS_quic_buffer_packet_till_chlo && packets.empty()) { + OnNewConnectionAdded(current_connection_id_); + } + // Process CHLO at first. + session->ProcessUdpPacket(current_server_address_, current_client_address_, + *current_packet_); + + // Deliver queued-up packets in the same order as they arrived. + // Do this even when flag is off because there might be still some packets + // buffered in the store before flag is turned off. + for (const BufferedPacket& packet : packets) { + session->ProcessUdpPacket(packet.server_address, packet.client_address, + *(packet.packet)); + } +} + bool QuicDispatcher::HandlePacketForTimeWait( const QuicPacketPublicHeader& header) { if (header.reset_flag) { @@ -659,23 +707,34 @@ !FLAGS_enable_quic_stateless_reject_support || header.public_header.versions.front() <= QUIC_VERSION_32 || !ShouldAttemptCheapStatelessRejection()) { + // Not use cheap stateless reject. + if (FLAGS_quic_buffer_packet_till_chlo && + !ChloExtractor::Extract(*current_packet_, GetSupportedVersions(), + nullptr)) { + // Buffer non-CHLO packets. + return kFateBuffer; + } return kFateProcess; } - StatelessRejector rejector(header.public_header.versions.front(), - GetSupportedVersions(), crypto_config_, - &compressed_certs_cache_, helper()->GetClock(), - helper()->GetRandomGenerator(), - current_client_address_, current_server_address_); + StatelessRejector rejector( + header.public_header.versions.front(), GetSupportedVersions(), + crypto_config_, &compressed_certs_cache_, helper()->GetClock(), + helper()->GetRandomGenerator(), current_packet_->length(), + current_client_address_, current_server_address_); ChloValidator validator(session_helper_.get(), current_server_address_, &rejector); if (!ChloExtractor::Extract(*current_packet_, GetSupportedVersions(), &validator)) { - DVLOG(1) << "Buffering undecryptable packet."; - buffered_packets_.EnqueuePacket(connection_id, *current_packet_, - current_server_address_, - current_client_address_); - return kFateDrop; + if (!FLAGS_quic_buffer_packet_till_chlo) { + QUIC_BUG + << "Have to drop packet because buffering non-chlo packet is " + "not supported while trying to do stateless reject. " + "--gfe2_reloadable_flag_quic_buffer_packet_till_chlo false" + " --gfe2_reloadable_flag_quic_use_cheap_stateless_rejects true"; + return kFateDrop; + } + return kFateBuffer; } if (!validator.can_accept()) {
diff --git a/net/tools/quic/quic_dispatcher.h b/net/tools/quic/quic_dispatcher.h index 8c1cfca..583c685 100644 --- a/net/tools/quic/quic_dispatcher.h +++ b/net/tools/quic/quic_dispatcher.h
@@ -141,7 +141,7 @@ bool OnPathCloseFrame(const QuicPathCloseFrame& frame) override; void OnPacketComplete() override; - // QuicBufferedPacketStore::VisitorInterface + // QuicBufferedPacketStore::VisitorInterface implementation. void OnExpiredPackets(QuicConnectionId connection_id, QuicBufferedPacketStore::BufferedPacketList early_arrived_packets) override; @@ -170,6 +170,8 @@ kFateProcess, // Put the connection ID into time-wait state and send a public reset. kFateTimeWait, + // Buffer the packet. + kFateBuffer, // Drop the packet (ignore and give no response). kFateDrop, }; @@ -183,6 +185,14 @@ // will be owned by the dispatcher as time_wait_list_manager_ virtual QuicTimeWaitListManager* CreateQuicTimeWaitListManager(); + // Called when |current_packet_| is a data packet that has arrived before + // the CHLO. Buffers the current packet until the CHLO arrives. + void BufferEarlyPacket(QuicConnectionId connection_id); + + // Called when |current_packet_| is a CHLO packet. Creates a new connection + // and delivers any buffered packets for that connection id. + void ProcessChlo(); + QuicTimeWaitListManager* time_wait_list_manager() { return time_wait_list_manager_.get(); } @@ -233,6 +243,18 @@ virtual bool OnUnauthenticatedUnknownPublicHeader( const QuicPacketPublicHeader& header); + // Called when a new connection starts to be handled by this dispatcher. + // Either this connection is created or its packets is buffered while waiting + // for CHLO. + virtual void OnNewConnectionAdded(QuicConnectionId connection_id); + + bool HasBufferedPackets(QuicConnectionId connection_id); + + // Called when BufferEarlyPacket() fail to buffer the packet. + virtual void OnBufferPacketFailure( + QuicBufferedPacketStore::EnqueuePacketResult result, + QuicConnectionId connection_id); + private: friend class net::test::QuicDispatcherPeer; @@ -283,8 +305,8 @@ // The writer to write to the socket with. std::unique_ptr<QuicPacketWriter> writer_; - // Undecryptable packets which are buffered until a connection can be - // created to handle them. + // Packets which are buffered until a connection can be created to handle + // them. QuicBufferedPacketStore buffered_packets_; // Information about the packet currently being handled.
diff --git a/net/tools/quic/quic_dispatcher_test.cc b/net/tools/quic/quic_dispatcher_test.cc index 967474df..07df1e6 100644 --- a/net/tools/quic/quic_dispatcher_test.cc +++ b/net/tools/quic/quic_dispatcher_test.cc
@@ -9,7 +9,7 @@ #include <string> #include "base/macros.h" -#include "base/strings/string_piece.h" +#include "base/strings/string_number_conversions.h" #include "net/quic/core/crypto/crypto_handshake.h" #include "net/quic/core/crypto/quic_crypto_server_config.h" #include "net/quic/core/crypto/quic_random.h" @@ -17,18 +17,24 @@ #include "net/quic/core/quic_flags.h" #include "net/quic/core/quic_utils.h" #include "net/quic/test_tools/crypto_test_utils.h" +#include "net/quic/test_tools/quic_buffered_packet_store_peer.h" #include "net/quic/test_tools/quic_test_utils.h" +#include "net/test/gtest_util.h" #include "net/tools/epoll_server/epoll_server.h" +#include "net/tools/quic/chlo_extractor.h" #include "net/tools/quic/quic_epoll_alarm_factory.h" #include "net/tools/quic/quic_epoll_connection_helper.h" #include "net/tools/quic/quic_packet_writer_wrapper.h" #include "net/tools/quic/quic_simple_server_session_helper.h" #include "net/tools/quic/quic_time_wait_list_manager.h" +#include "net/tools/quic/stateless_rejector.h" #include "net/tools/quic/test_tools/mock_quic_time_wait_list_manager.h" #include "net/tools/quic/test_tools/quic_dispatcher_peer.h" #include "testing/gmock/include/gmock/gmock.h" +#include "testing/gmock_mutant.h" #include "testing/gtest/include/gtest/gtest.h" +using base::IntToString; using base::StringPiece; using net::EpollServer; using net::test::ConstructEncryptedPacket; @@ -36,14 +42,18 @@ using net::test::MockQuicConnection; using net::test::MockQuicConnectionHelper; using net::test::ValueRestore; +using std::ostream; using std::string; using std::vector; +using testing::CreateFunctor; using testing::DoAll; using testing::InSequence; using testing::Invoke; using testing::WithoutArgs; using testing::_; +static const size_t kDefaultMaxConnectionsInStore = 100; + namespace net { namespace test { namespace { @@ -61,7 +71,8 @@ crypto_config, compressed_certs_cache), crypto_stream_(QuicServerSessionBase::GetCryptoStream()) {} - ~TestQuicSpdyServerSession() override{}; + + ~TestQuicSpdyServerSession() override { delete connection(); }; MOCK_METHOD3(OnConnectionClosed, void(QuicErrorCode error, @@ -114,6 +125,8 @@ QuicServerSessionBase*(QuicConnectionId connection_id, const IPEndPoint& client_address)); + MOCK_METHOD1(OnNewConnectionAdded, void(QuicConnectionId connection_id)); + using QuicDispatcher::current_server_address; using QuicDispatcher::current_client_address; }; @@ -144,36 +157,12 @@ QuicDispatcher* dispatcher_; }; -QuicServerSessionBase* CreateSession( - QuicDispatcher* dispatcher, - const QuicConfig& config, - QuicConnectionId connection_id, - const IPEndPoint& client_address, - MockQuicConnectionHelper* helper, - MockAlarmFactory* alarm_factory, - const QuicCryptoServerConfig* crypto_config, - QuicCompressedCertsCache* compressed_certs_cache, - TestQuicSpdyServerSession** session) { - MockServerConnection* connection = new MockServerConnection( - connection_id, helper, alarm_factory, dispatcher); - *session = new TestQuicSpdyServerSession(config, connection, crypto_config, - compressed_certs_cache); - connection->set_visitor(*session); - ON_CALL(*connection, CloseConnection(_, _, _)) - .WillByDefault(WithoutArgs(Invoke( - connection, &MockServerConnection::UnregisterOnConnectionClosed))); - EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>((*session)->connection()), - ProcessUdpPacket(_, client_address, _)); - - return *session; -} - class QuicDispatcherTest : public ::testing::Test { public: QuicDispatcherTest() : helper_(&eps_, QuicAllocator::BUFFER_POOL), alarm_factory_(&eps_), - version_manager_(QuicSupportedVersions()), + version_manager_(AllSupportedVersions()), crypto_config_(QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(), CryptoTestUtils::ProofSourceForTesting()), @@ -183,7 +172,10 @@ &eps_)), time_wait_list_manager_(nullptr), session1_(nullptr), - session2_(nullptr) { + session2_(nullptr), + store_(nullptr) {} + + void SetUp() override { dispatcher_->InitializeWithWriter(new QuicDefaultPacketWriter(1)); } @@ -235,8 +227,8 @@ QuicPathId path_id, QuicPacketNumber packet_number) { ProcessPacket(client_address, connection_id, has_version_flag, - QuicSupportedVersions().front(), data, connection_id_length, - packet_number_length, packet_number); + CurrentSupportedVersions().front(), data, + connection_id_length, packet_number_length, packet_number); } // Processes a packet. @@ -255,14 +247,47 @@ std::unique_ptr<QuicReceivedPacket> received_packet( ConstructReceivedPacket(*packet, helper_.GetClock()->Now())); - data_ = string(packet->data(), packet->length()); + if (ChloExtractor::Extract(*packet, versions, nullptr)) { + // Add CHLO packet to the beginning to be verified first, because it is + // also processed first by new session. + data_connection_map_[connection_id].push_front( + string(packet->data(), packet->length())); + } else { + // For non-CHLO, always append to last. + data_connection_map_[connection_id].push_back( + string(packet->data(), packet->length())); + } dispatcher_->ProcessPacket(server_address_, client_address, *received_packet); } - void ValidatePacket(const QuicEncryptedPacket& packet) { - EXPECT_EQ(data_.length(), packet.AsStringPiece().length()); - EXPECT_EQ(data_, packet.AsStringPiece()); + void ValidatePacket(QuicConnectionId conn_id, + const QuicEncryptedPacket& packet) { + EXPECT_EQ(data_connection_map_[conn_id].front().length(), + packet.AsStringPiece().length()); + EXPECT_EQ(data_connection_map_[conn_id].front(), packet.AsStringPiece()); + data_connection_map_[conn_id].pop_front(); + } + + QuicServerSessionBase* CreateSession( + QuicDispatcher* dispatcher, + const QuicConfig& config, + QuicConnectionId connection_id, + const IPEndPoint& client_address, + MockQuicConnectionHelper* helper, + MockAlarmFactory* alarm_factory, + const QuicCryptoServerConfig* crypto_config, + QuicCompressedCertsCache* compressed_certs_cache, + TestQuicSpdyServerSession** session) { + MockServerConnection* connection = new MockServerConnection( + connection_id, helper, alarm_factory, dispatcher); + *session = new TestQuicSpdyServerSession(config, connection, crypto_config, + compressed_certs_cache); + connection->set_visitor(*session); + ON_CALL(*connection, CloseConnection(_, _, _)) + .WillByDefault(WithoutArgs(Invoke( + connection, &MockServerConnection::UnregisterOnConnectionClosed))); + return *session; } void CreateTimeWaitListManager() { @@ -293,7 +318,8 @@ MockTimeWaitListManager* time_wait_list_manager_; TestQuicSpdyServerSession* session1_; TestQuicSpdyServerSession* session2_; - string data_; + std::map<QuicConnectionId, std::list<string>> data_connection_map_; + QuicBufferedPacketStore* store_; }; TEST_F(QuicDispatcherTest, ProcessPackets) { @@ -305,6 +331,10 @@ dispatcher_.get(), config_, 1, client_address, &mock_helper_, &mock_alarm_factory_, &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); + EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), + ProcessUdpPacket(_, _, _)) + .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( + &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); ProcessPacket(client_address, 1, true, false, SerializeCHLO()); EXPECT_EQ(client_address, dispatcher_->current_client_address()); EXPECT_EQ(server_address_, dispatcher_->current_server_address()); @@ -314,13 +344,17 @@ dispatcher_.get(), config_, 2, client_address, &mock_helper_, &mock_alarm_factory_, &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))); + EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()), + ProcessUdpPacket(_, _, _)) + .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( + &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 2)))); ProcessPacket(client_address, 2, true, false, SerializeCHLO()); EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), ProcessUdpPacket(_, _, _)) .Times(1) - .WillOnce(testing::WithArgs<2>( - Invoke(this, &QuicDispatcherTest::ValidatePacket))); + .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( + &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); ProcessPacket(client_address, 1, false, false, "data"); } @@ -342,6 +376,10 @@ dispatcher_.get(), config_, 1, client_address, &mock_helper_, &mock_alarm_factory_, &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); + EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), + ProcessUdpPacket(_, _, _)) + .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( + &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); ProcessPacket(client_address, 1, true, false, SerializeCHLO()); @@ -362,6 +400,11 @@ dispatcher_.get(), config_, connection_id, client_address, &mock_helper_, &mock_alarm_factory_, &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); + EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), + ProcessUdpPacket(_, _, _)) + .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( + &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); + ProcessPacket(client_address, connection_id, true, false, SerializeCHLO()); // Close the connection by sending public reset packet. @@ -439,6 +482,10 @@ dispatcher_.get(), config_, 1, client_address, &mock_helper_, &mock_alarm_factory_, &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); + EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), + ProcessUdpPacket(_, _, _)) + .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( + &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); // A packet whose packet number is the largest that is allowed to start a // connection. ProcessPacket(client_address, connection_id, true, false, SerializeCHLO(), @@ -535,7 +582,8 @@ : public QuicDispatcherTest, public ::testing::WithParamInterface<StatelessRejectTestParams> { public: - QuicDispatcherStatelessRejectTest() : crypto_stream1_(nullptr) {} + QuicDispatcherStatelessRejectTest() + : QuicDispatcherTest(), crypto_stream1_(nullptr) {} ~QuicDispatcherStatelessRejectTest() override { if (crypto_stream1_) { @@ -546,6 +594,7 @@ // This test setup assumes that all testing will be done using // crypto_stream1_. void SetUp() override { + QuicDispatcherTest::SetUp(); FLAGS_enable_quic_stateless_reject_support = GetParam().enable_stateless_rejects_via_flag; } @@ -596,7 +645,11 @@ EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) .WillOnce(testing::Return( CreateSessionBasedOnTestParams(connection_id, client_address))); - + EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), + ProcessUdpPacket(_, _, _)) + .WillOnce(testing::WithArgs<2>( + Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, + base::Unretained(this), connection_id)))); // Process the first packet for the connection. ProcessPacket(client_address, connection_id, true, false, SerializeCHLO()); if (ExpectStatelessReject()) { @@ -622,13 +675,15 @@ ProcessUdpPacket(_, _, _)) .Times(1) .WillOnce(testing::WithArgs<2>( - Invoke(this, &QuicDispatcherTest::ValidatePacket))); + Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, + base::Unretained(this), connection_id)))); } ProcessPacket(client_address, connection_id, true, false, "data"); } TEST_P(QuicDispatcherStatelessRejectTest, CheapRejects) { FLAGS_quic_use_cheap_stateless_rejects = true; + FLAGS_quic_buffer_packet_till_chlo = true; CreateTimeWaitListManager(); IPEndPoint client_address(net::test::Loopback4(), 1); @@ -640,6 +695,10 @@ EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) .WillOnce(testing::Return( CreateSessionBasedOnTestParams(connection_id, client_address))); + EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), + ProcessUdpPacket(_, _, _)) + .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( + &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); } VLOG(1) << "ExpectStatelessReject: " << ExpectStatelessReject(); @@ -668,20 +727,41 @@ TEST_P(QuicDispatcherStatelessRejectTest, BufferNonChlo) { FLAGS_quic_use_cheap_stateless_rejects = true; + FLAGS_quic_always_log_bugs_for_tests = true; CreateTimeWaitListManager(); const IPEndPoint client_address(net::test::Loopback4(), 1); const QuicConnectionId connection_id = 1; - if (!GetParam().enable_stateless_rejects_via_flag) { - // If stateless rejects are not being used, then a connection will be - // created immediately. + if (!GetParam().enable_stateless_rejects_via_flag && + !FLAGS_quic_buffer_packet_till_chlo) { + // If stateless rejects are not being used and early arrived packets are not + // buffered, then a connection will be created immediately. EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) .WillOnce(testing::Return( CreateSessionBasedOnTestParams(connection_id, client_address))); + EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), + ProcessUdpPacket(_, client_address, _)) + .WillOnce(testing::WithArg<2>( + Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, + base::Unretained(this), connection_id)))); } - ProcessPacket(client_address, connection_id, true, false, - "NOT DATA FOR A CHLO"); + bool first_packet_dropped = GetParam().enable_stateless_rejects_via_flag && + !FLAGS_quic_buffer_packet_till_chlo; + if (first_packet_dropped) { + // Never do stateless reject while + // FLAGS_quic_buffer_packet_till_chlo is off. + EXPECT_DFATAL( + ProcessPacket(client_address, connection_id, true, false, + "NOT DATA FOR A CHLO"), + "Have to drop packet because buffering non-chlo packet is " + "not supported while trying to do stateless reject. " + "--gfe2_reloadable_flag_quic_buffer_packet_till_chlo false " + "--gfe2_reloadable_flag_quic_use_cheap_stateless_rejects true"); + } else { + ProcessPacket(client_address, connection_id, true, false, + "NOT DATA FOR A CHLO"); + } // Process the first packet for the connection. // clang-format off @@ -695,16 +775,33 @@ nullptr); // clang-format on - if (GetParam().enable_stateless_rejects_via_flag) { + if (GetParam().enable_stateless_rejects_via_flag || + FLAGS_quic_buffer_packet_till_chlo) { // If stateless rejects are enabled then a connection will be created now // and the buffered packet will be processed EXPECT_CALL(*dispatcher_, CreateQuicSession(connection_id, client_address)) .WillOnce(testing::Return( CreateSessionBasedOnTestParams(connection_id, client_address))); + EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), + ProcessUdpPacket(_, client_address, _)) + .WillOnce(testing::WithArg<2>( + Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, + base::Unretained(this), connection_id)))); } - EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), - ProcessUdpPacket(_, client_address, _)) - .RetiresOnSaturation(); + if (!first_packet_dropped) { + // Expect both packets to be passed to ProcessUdpPacket(). And one of them + // is already expected in CreateSessionBasedOnTestParams(). + EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), + ProcessUdpPacket(_, client_address, _)) + .WillOnce(testing::WithArg<2>( + Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, + base::Unretained(this), connection_id)))) + .RetiresOnSaturation(); + } else { + // Since first packet is dropped, remove it from map to skip + // ValidatePacket() on it. + data_connection_map_[connection_id].pop_front(); + } ProcessPacket(client_address, connection_id, true, false, client_hello.GetSerialized().AsStringPiece().as_string()); EXPECT_FALSE( @@ -758,6 +855,7 @@ class QuicDispatcherWriteBlockedListTest : public QuicDispatcherTest { public: void SetUp() override { + QuicDispatcherTest::SetUp(); writer_ = new BlockingWriter; QuicDispatcherPeer::UseWriter(dispatcher_.get(), writer_); @@ -768,6 +866,10 @@ dispatcher_.get(), config_, 1, client_address, &helper_, &alarm_factory_, &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); + EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), + ProcessUdpPacket(_, _, _)) + .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( + &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 1)))); ProcessPacket(client_address, 1, true, false, SerializeCHLO()); EXPECT_CALL(*dispatcher_, CreateQuicSession(_, client_address)) @@ -775,6 +877,10 @@ dispatcher_.get(), config_, 2, client_address, &helper_, &alarm_factory_, &crypto_config_, QuicDispatcherPeer::GetCache(dispatcher_.get()), &session2_))); + EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session2_->connection()), + ProcessUdpPacket(_, _, _)) + .WillOnce(testing::WithArgs<2>(Invoke(CreateFunctor( + &QuicDispatcherTest::ValidatePacket, base::Unretained(this), 2)))); ProcessPacket(client_address, 2, true, false, SerializeCHLO()); blocked_list_ = QuicDispatcherPeer::GetWriteBlockedList(dispatcher_.get()); @@ -931,6 +1037,251 @@ EXPECT_FALSE(dispatcher_->HasPendingWrites()); } +// Tests that bufferring packets works in stateful reject, expensive stateless +// reject and cheap stateless reject. +struct BufferedPacketStoreTestParams { + BufferedPacketStoreTestParams(bool enable_stateless_rejects_via_flag, + bool support_cheap_stateless_reject) + : enable_stateless_rejects_via_flag(enable_stateless_rejects_via_flag), + support_cheap_stateless_reject(support_cheap_stateless_reject) {} + + friend ostream& operator<<(ostream& os, + const BufferedPacketStoreTestParams& p) { + os << "{ enable_stateless_rejects_via_flag: " + << p.enable_stateless_rejects_via_flag << std::endl; + os << " support_cheap_stateless_reject: " + << p.support_cheap_stateless_reject << " }"; + return os; + } + + // This only enables the stateless reject feature via the feature-flag. + // This should be a no-op if the peer does not support them. + bool enable_stateless_rejects_via_flag; + // Whether to do cheap stateless or not. + bool support_cheap_stateless_reject; +}; + +vector<BufferedPacketStoreTestParams> GetBufferedPacketStoreTestParams() { + vector<BufferedPacketStoreTestParams> params; + for (bool enable_stateless_rejects_via_flag : {true, false}) { + for (bool support_cheap_stateless_reject : {true, false}) { + params.push_back(BufferedPacketStoreTestParams( + enable_stateless_rejects_via_flag, support_cheap_stateless_reject)); + } + } + return params; +} + +// A dispatcher whose stateless rejector will always ACCEPTs CHLO. +class BufferedPacketStoreTest + : public QuicDispatcherTest, + public ::testing::WithParamInterface<BufferedPacketStoreTestParams> { + public: + BufferedPacketStoreTest() + : QuicDispatcherTest(), client_addr_(Loopback4(), 1234) { + FLAGS_quic_buffer_packet_till_chlo = true; + FLAGS_quic_use_cheap_stateless_rejects = + GetParam().support_cheap_stateless_reject; + FLAGS_enable_quic_stateless_reject_support = + GetParam().enable_stateless_rejects_via_flag; + } + + void SetUp() override { + QuicDispatcherTest::SetUp(); + clock_ = QuicDispatcherPeer::GetHelper(dispatcher_.get())->GetClock(); + + QuicVersion version = AllSupportedVersions().front(); + CryptoHandshakeMessage chlo = CryptoTestUtils::GenerateDefaultInchoateCHLO( + clock_, version, &crypto_config_); + chlo.SetVector(net::kCOPT, net::QuicTagVector{net::kSREJ}); + // Pass an inchoate CHLO. + CryptoTestUtils::GenerateFullCHLO( + chlo, &crypto_config_, server_ip_, client_addr_, version, clock_, + &proof_, QuicDispatcherPeer::GetCache(dispatcher_.get()), &full_chlo_); + } + + string SerializeFullCHLO() { + return full_chlo_.GetSerialized().AsStringPiece().as_string(); + } + + protected: + IPAddress server_ip_; + IPEndPoint client_addr_; + QuicCryptoProof proof_; + const QuicClock* clock_; + CryptoHandshakeMessage full_chlo_; +}; + +INSTANTIATE_TEST_CASE_P( + BufferedPacketStoreTests, + BufferedPacketStoreTest, + ::testing::ValuesIn(GetBufferedPacketStoreTestParams())); + +TEST_P(BufferedPacketStoreTest, ProcessNonChloPacketsUptoLimitAndProcessChlo) { + InSequence s; + IPEndPoint client_address(Loopback4(), 1); + server_address_ = IPEndPoint(Any4(), 5); + QuicConnectionId conn_id = 1; + // A bunch of non-CHLO should be buffered upon arrival, and the first one + // should trigger OnNewConnectionAdded(). + EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)).Times(1); + for (size_t i = 1; i <= kDefaultMaxUndecryptablePackets + 1; ++i) { + ProcessPacket(client_address, conn_id, true, false, + "data packet " + IntToString(i + 1), + PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, + kDefaultPathId, + /*packet_number=*/i + 1); + } + EXPECT_EQ(0u, dispatcher_->session_map().size()) + << "No session should be created before CHLO arrives."; + + // Pop out the last packet as it is also be dropped by the store. + data_connection_map_[conn_id].pop_back(); + // When CHLO arrives, a new session should be created, and all packets + // buffered should be delivered to the session. + EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) + .WillOnce(testing::Return(CreateSession( + dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, + &mock_alarm_factory_, &crypto_config_, + QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); + + // Only |kDefaultMaxUndecryptablePackets| packets were buffered, and they + // should be delivered in arrival order. + EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), + ProcessUdpPacket(_, _, _)) + .Times(kDefaultMaxUndecryptablePackets + 1) // + 1 for CHLO. + .WillRepeatedly(testing::WithArg<2>( + Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, + base::Unretained(this), conn_id)))); + ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); +} + +TEST_P(BufferedPacketStoreTest, + ProcessNonChloPacketsForDifferentConnectionsUptoLimit) { + InSequence s; + server_address_ = IPEndPoint(Any4(), 5); + // A bunch of non-CHLO should be buffered upon arrival. + for (size_t i = 1; i <= kDefaultMaxConnectionsInStore + 1; ++i) { + IPEndPoint client_address(Loopback4(), i); + QuicConnectionId conn_id = i; + if (i <= kDefaultMaxConnectionsInStore) { + // As they are on different connection, they should trigger + // OnNewConnectionAdded(). The last packet should be dropped. + EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)); + } + ProcessPacket(client_address, conn_id, true, false, + "data packet on connection " + IntToString(i), + PACKET_8BYTE_CONNECTION_ID, PACKET_6BYTE_PACKET_NUMBER, + kDefaultPathId, + /*packet_number=*/2); + } + + // Pop out the packet on last connection as it shouldn't be enqueued in store + // as well. + data_connection_map_[kDefaultMaxConnectionsInStore + 1].pop_front(); + + // Process CHLOs. + for (size_t i = 1; i <= kDefaultMaxConnectionsInStore + 1; ++i) { + IPEndPoint client_address(Loopback4(), i); + QuicConnectionId conn_id = i; + EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) + .WillOnce(testing::Return(CreateSession( + dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, + &mock_alarm_factory_, &crypto_config_, + QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); + if (conn_id == kDefaultMaxConnectionsInStore + 1) { + // The last CHLO should trigger OnNewConnectionAdded() since it's the + // first packet arrives on that connection. + EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)); + } + // First |kDefaultMaxConnectionsInStore| connections should have buffered + // a packet in store. The rest should have been dropped. + if (i <= kDefaultMaxConnectionsInStore) { + EXPECT_CALL( + *reinterpret_cast<MockQuicConnection*>(session1_->connection()), + ProcessUdpPacket(_, client_address, _)) + .Times(2) + .WillRepeatedly(testing::WithArg<2>( + Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, + base::Unretained(this), conn_id)))); + } + ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); + } +} + +// Tests that store delivers empty packet list if CHLO arrives firstly. +TEST_P(BufferedPacketStoreTest, DeliverEmptyPackets) { + QuicConnectionId conn_id = 1; + IPEndPoint client_address(Loopback4(), 1); + EXPECT_CALL(*dispatcher_, OnNewConnectionAdded(conn_id)); + EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) + .WillOnce(testing::Return(CreateSession( + dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, + &mock_alarm_factory_, &crypto_config_, + QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); + ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); +} + +// Tests that by the time a retransmitted CHLO arrives, a connection for the +// CHLO should already be created. +TEST_P(BufferedPacketStoreTest, ReceiveRetransmittedCHLO) { + InSequence s; + IPEndPoint client_address(Loopback4(), 1); + server_address_ = IPEndPoint(Any4(), 5); + QuicConnectionId conn_id = 1; + ProcessPacket(client_address, conn_id, true, false, + "data packet " + IntToString(2), PACKET_8BYTE_CONNECTION_ID, + PACKET_6BYTE_PACKET_NUMBER, kDefaultPathId, + /*packet_number=*/2); + + // When CHLO arrives, a new session should be created, and all packets + // buffered should be delivered to the session. + EXPECT_CALL(*dispatcher_, CreateQuicSession(conn_id, client_address)) + .Times(1) // Only triggered by 1st CHLO. + .WillOnce(testing::Return(CreateSession( + dispatcher_.get(), config_, conn_id, client_address, &mock_helper_, + &mock_alarm_factory_, &crypto_config_, + QuicDispatcherPeer::GetCache(dispatcher_.get()), &session1_))); + EXPECT_CALL(*reinterpret_cast<MockQuicConnection*>(session1_->connection()), + ProcessUdpPacket(_, _, _)) + .Times(3) // Triggered by 1 data packet and 2 CHLOs. + .WillRepeatedly(testing::WithArg<2>( + Invoke(CreateFunctor(&QuicDispatcherTest::ValidatePacket, + base::Unretained(this), conn_id)))); + ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); + + ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); +} + +// Tests that expiration of a connection add connection id to time wait list. +TEST_P(BufferedPacketStoreTest, ReceiveCHLOAfterExpiration) { + InSequence s; + CreateTimeWaitListManager(); + QuicBufferedPacketStore* store = + QuicDispatcherPeer::GetBufferedPackets(dispatcher_.get()); + QuicBufferedPacketStorePeer::set_clock(store, mock_helper_.GetClock()); + + IPEndPoint client_address(Loopback4(), 1); + server_address_ = IPEndPoint(Any4(), 5); + QuicConnectionId conn_id = 1; + ProcessPacket(client_address, conn_id, true, false, + "data packet " + IntToString(2), PACKET_8BYTE_CONNECTION_ID, + PACKET_6BYTE_PACKET_NUMBER, kDefaultPathId, + /*packet_number=*/2); + + mock_helper_.AdvanceTime( + QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs)); + QuicAlarm* alarm = QuicBufferedPacketStorePeer::expiration_alarm(store); + // Cancel alarm as if it had been fired. + alarm->Cancel(); + store->OnExpirationTimeout(); + // New arrived CHLO will be dropped because this connection is in time wait + // list. + ASSERT_TRUE(time_wait_list_manager_->IsConnectionIdInTimeWait(conn_id)); + EXPECT_CALL(*time_wait_list_manager_, ProcessPacket(_, _, conn_id, _, _)); + ProcessPacket(client_address, conn_id, true, false, SerializeFullCHLO()); +} + } // namespace } // namespace test } // namespace net
diff --git a/net/tools/quic/quic_in_memory_cache.cc b/net/tools/quic/quic_in_memory_cache.cc index 66f073a..00b3e72f 100644 --- a/net/tools/quic/quic_in_memory_cache.cc +++ b/net/tools/quic/quic_in_memory_cache.cc
@@ -208,7 +208,7 @@ QuicInMemoryCache::QuicInMemoryCache() {} void QuicInMemoryCache::ResetForTests() { - STLDeleteValues(&responses_); + base::STLDeleteValues(&responses_); server_push_resources_.clear(); } @@ -279,7 +279,7 @@ } QuicInMemoryCache::~QuicInMemoryCache() { - STLDeleteValues(&responses_); + base::STLDeleteValues(&responses_); } void QuicInMemoryCache::AddResponseImpl(StringPiece host, @@ -290,7 +290,7 @@ SpdyHeaderBlock response_trailers) { DCHECK(!host.empty()) << "Host must be populated, e.g. \"www.google.com\""; string key = GetKey(host, path); - if (ContainsKey(responses_, key)) { + if (base::ContainsKey(responses_, key)) { QUIC_BUG << "Response for '" << key << "' already exists!"; return; }
diff --git a/net/tools/quic/quic_in_memory_cache_test.cc b/net/tools/quic/quic_in_memory_cache_test.cc index d31e8fd..d220e48 100644 --- a/net/tools/quic/quic_in_memory_cache_test.cc +++ b/net/tools/quic/quic_in_memory_cache_test.cc
@@ -69,7 +69,7 @@ const QuicInMemoryCache::Response* response = cache->GetResponse("www.google.com", "/"); ASSERT_TRUE(response); - ASSERT_TRUE(ContainsKey(response->headers(), ":status")); + ASSERT_TRUE(base::ContainsKey(response->headers(), ":status")); EXPECT_EQ("200", response->headers().find(":status")->second); EXPECT_EQ(response_body.size(), response->body().length()); } @@ -106,9 +106,9 @@ QuicInMemoryCache::GetInstance()->GetResponse("quic.test.url", "/index.html"); ASSERT_TRUE(response); - ASSERT_TRUE(ContainsKey(response->headers(), ":status")); + ASSERT_TRUE(base::ContainsKey(response->headers(), ":status")); EXPECT_EQ("200", response->headers().find(":status")->second); - ASSERT_TRUE(ContainsKey(response->headers(), "connection")); + ASSERT_TRUE(base::ContainsKey(response->headers(), "connection")); EXPECT_EQ("close", response->headers().find("connection")->second); EXPECT_LT(0U, response->body().length()); } @@ -137,9 +137,9 @@ QuicInMemoryCache::GetInstance()->GetResponse("quic.test.url", "/index.html"); ASSERT_TRUE(response); - ASSERT_TRUE(ContainsKey(response->headers(), ":status")); + ASSERT_TRUE(base::ContainsKey(response->headers(), ":status")); EXPECT_EQ("200", response->headers().find(":status")->second); - ASSERT_TRUE(ContainsKey(response->headers(), "connection")); + ASSERT_TRUE(base::ContainsKey(response->headers(), "connection")); EXPECT_EQ("close", response->headers().find("connection")->second); EXPECT_LT(0U, response->body().length()); } @@ -164,20 +164,20 @@ // Now we should get the default response for the original request. response = cache->GetResponse("www.google.com", "/"); ASSERT_TRUE(response); - ASSERT_TRUE(ContainsKey(response->headers(), ":status")); + ASSERT_TRUE(base::ContainsKey(response->headers(), ":status")); EXPECT_EQ("200", response->headers().find(":status")->second); // Now add a set response for / and make sure it is returned cache->AddSimpleResponse("www.google.com", "/", 302, ""); response = cache->GetResponse("www.google.com", "/"); ASSERT_TRUE(response); - ASSERT_TRUE(ContainsKey(response->headers(), ":status")); + ASSERT_TRUE(base::ContainsKey(response->headers(), ":status")); EXPECT_EQ("302", response->headers().find(":status")->second); // We should get the default response for other requests. response = cache->GetResponse("www.google.com", "/asd"); ASSERT_TRUE(response); - ASSERT_TRUE(ContainsKey(response->headers(), ":status")); + ASSERT_TRUE(base::ContainsKey(response->headers(), ":status")); EXPECT_EQ("200", response->headers().find(":status")->second); } @@ -249,7 +249,7 @@ const QuicInMemoryCache::Response* response = cache->GetResponse(host, path); ASSERT_TRUE(response); - ASSERT_TRUE(ContainsKey(response->headers(), ":status")); + ASSERT_TRUE(base::ContainsKey(response->headers(), ":status")); EXPECT_EQ(push_response_status[i++], response->headers().find(":status")->second); EXPECT_EQ(push_resource.body, response->body());
diff --git a/net/tools/quic/quic_packet_printer_bin.cc b/net/tools/quic/quic_packet_printer_bin.cc index 52eed58..8be7be5f 100644 --- a/net/tools/quic/quic_packet_printer_bin.cc +++ b/net/tools/quic/quic_packet_printer_bin.cc
@@ -184,7 +184,7 @@ return 1; } string hex = net::QuicUtils::HexDecode(ArgToString(args[1])); - net::QuicVersionVector versions = net::QuicSupportedVersions(); + net::QuicVersionVector versions = net::AllSupportedVersions(); // Fake a time since we're not actually generating acks. net::QuicTime start(net::QuicTime::Zero()); net::QuicFramer framer(versions, start, perspective);
diff --git a/net/tools/quic/quic_packet_reader.cc b/net/tools/quic/quic_packet_reader.cc index e239e58..0d0c613b 100644 --- a/net/tools/quic/quic_packet_reader.cc +++ b/net/tools/quic/quic_packet_reader.cc
@@ -98,7 +98,6 @@ return false; // recvmmsg failed. } - QuicTime fallback_timestamp = QuicTime::Zero(); QuicWallTime fallback_walltimestamp = QuicWallTime::Zero(); for (int i = 0; i < packets_read; ++i) { if (mmsg_hdr_[i].msg_len == 0) { @@ -114,12 +113,9 @@ IPEndPoint client_address = IPEndPoint(packets_[i].raw_address); IPAddress server_ip; - QuicTime packet_timestamp = QuicTime::Zero(); QuicWallTime packet_walltimestamp = QuicWallTime::Zero(); - bool latched_walltimestamps = FLAGS_quic_socket_walltimestamps; QuicSocketUtils::GetAddressAndTimestampFromMsghdr( - &mmsg_hdr_[i].msg_hdr, &server_ip, &packet_timestamp, - &packet_walltimestamp, latched_walltimestamps); + &mmsg_hdr_[i].msg_hdr, &server_ip, &packet_walltimestamp); if (!IsInitializedAddress(server_ip)) { QUIC_BUG << "Unable to get server address."; continue; @@ -127,24 +123,19 @@ // This isn't particularly desirable, but not all platforms support socket // timestamping. - if (latched_walltimestamps) { - if (packet_walltimestamp.IsZero()) { - if (fallback_walltimestamp.IsZero()) { - fallback_walltimestamp = clock.WallNow(); - } - packet_walltimestamp = fallback_walltimestamp; + if (packet_walltimestamp.IsZero()) { + if (fallback_walltimestamp.IsZero()) { + fallback_walltimestamp = clock.WallNow(); } - packet_timestamp = clock.ConvertWallTimeToQuicTime(packet_walltimestamp); - } else { - if (packet_timestamp == QuicTime::Zero()) { - if (fallback_timestamp == QuicTime::Zero()) { - fallback_timestamp = clock.Now(); - } - packet_timestamp = fallback_timestamp; - } + packet_walltimestamp = fallback_walltimestamp; } + QuicTime timestamp = clock.ConvertWallTimeToQuicTime(packet_walltimestamp); + int ttl = 0; + bool has_ttl = + QuicSocketUtils::GetTtlFromMsghdr(&mmsg_hdr_[i].msg_hdr, &ttl); QuicReceivedPacket packet(reinterpret_cast<char*>(packets_[i].iov.iov_base), - mmsg_hdr_[i].msg_len, packet_timestamp, false); + mmsg_hdr_[i].msg_len, timestamp, false, ttl, + has_ttl); IPEndPoint server_address(server_ip, port); processor->ProcessPacket(server_address, client_address, packet); } @@ -169,17 +160,14 @@ const QuicClock& clock, ProcessPacketInterface* processor, QuicPacketCount* packets_dropped) { - bool latched_walltimestamps = FLAGS_quic_socket_walltimestamps; char buf[kMaxPacketSize]; IPEndPoint client_address; IPAddress server_ip; - QuicTime timestamp = QuicTime::Zero(); QuicWallTime walltimestamp = QuicWallTime::Zero(); - int bytes_read = QuicSocketUtils::ReadPacket( - fd, buf, arraysize(buf), packets_dropped, &server_ip, ×tamp, - &walltimestamp, latched_walltimestamps, &client_address); - + int bytes_read = + QuicSocketUtils::ReadPacket(fd, buf, arraysize(buf), packets_dropped, + &server_ip, &walltimestamp, &client_address); if (bytes_read < 0) { return false; // ReadPacket failed. } @@ -190,16 +178,10 @@ } // This isn't particularly desirable, but not all platforms support socket // timestamping. - if (latched_walltimestamps) { - if (walltimestamp.IsZero()) { - walltimestamp = clock.WallNow(); - } - timestamp = clock.ConvertWallTimeToQuicTime(walltimestamp); - } else { - if (timestamp == QuicTime::Zero()) { - timestamp = clock.Now(); - } + if (walltimestamp.IsZero()) { + walltimestamp = clock.WallNow(); } + QuicTime timestamp = clock.ConvertWallTimeToQuicTime(walltimestamp); QuicReceivedPacket packet(buf, bytes_read, timestamp, false); IPEndPoint server_address(server_ip, port);
diff --git a/net/tools/quic/quic_server.cc b/net/tools/quic/quic_server.cc index 9f3235d..63d750a 100644 --- a/net/tools/quic/quic_server.cc +++ b/net/tools/quic/quic_server.cc
@@ -52,7 +52,7 @@ : QuicServer(std::move(proof_source), QuicConfig(), QuicCryptoServerConfig::ConfigOptions(), - QuicSupportedVersions()) {} + AllSupportedVersions()) {} QuicServer::QuicServer( std::unique_ptr<ProofSource> proof_source,
diff --git a/net/tools/quic/quic_server_bin.cc b/net/tools/quic/quic_server_bin.cc index 66800a3..b1eafd7 100644 --- a/net/tools/quic/quic_server_bin.cc +++ b/net/tools/quic/quic_server_bin.cc
@@ -86,7 +86,7 @@ CreateProofSource(line->GetSwitchValuePath("certificate_file"), line->GetSwitchValuePath("key_file")), config, net::QuicCryptoServerConfig::ConfigOptions(), - net::QuicSupportedVersions()); + net::AllSupportedVersions()); server.SetStrikeRegisterNoStartupPeriod(); int rc = server.CreateUDPSocketAndListen(net::IPEndPoint(ip, FLAGS_port));
diff --git a/net/tools/quic/quic_server_test.cc b/net/tools/quic/quic_server_test.cc index 92a89dd1..d9acf865 100644 --- a/net/tools/quic/quic_server_test.cc +++ b/net/tools/quic/quic_server_test.cc
@@ -28,7 +28,7 @@ : crypto_config_("blah", QuicRandom::GetInstance(), CryptoTestUtils::ProofSourceForTesting()), - version_manager_(QuicSupportedVersions()), + version_manager_(AllSupportedVersions()), dispatcher_( config_, &crypto_config_,
diff --git a/net/tools/quic/quic_simple_client.cc b/net/tools/quic/quic_simple_client.cc index aec9129..156d0716 100644 --- a/net/tools/quic/quic_simple_client.cc +++ b/net/tools/quic/quic_simple_client.cc
@@ -78,8 +78,8 @@ QUIC_PEER_GOING_AWAY, "Shutting down", ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); } - STLDeleteElements(&data_to_resend_on_connect_); - STLDeleteElements(&data_sent_before_handshake_); + base::STLDeleteElements(&data_to_resend_on_connect_); + base::STLDeleteElements(&data_sent_before_handshake_); } bool QuicSimpleClient::Initialize() { @@ -181,7 +181,7 @@ for (QuicDataToResend* data : data_to_resend_on_connect_) { data->Resend(); } - STLDeleteElements(&data_to_resend_on_connect_); + base::STLDeleteElements(&data_to_resend_on_connect_); } if (session() != nullptr && session()->error() != QUIC_CRYPTO_HANDSHAKE_STATELESS_REJECT) { @@ -238,8 +238,8 @@ QUIC_PEER_GOING_AWAY, "Client disconnecting", ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); } - STLDeleteElements(&data_to_resend_on_connect_); - STLDeleteElements(&data_sent_before_handshake_); + base::STLDeleteElements(&data_to_resend_on_connect_); + base::STLDeleteElements(&data_sent_before_handshake_); reset_writer(); packet_reader_.reset(); @@ -277,7 +277,7 @@ if (session()->IsCryptoHandshakeConfirmed()) { // The handshake is confirmed. No need to continue saving requests to // resend. - STLDeleteElements(&data_sent_before_handshake_); + base::STLDeleteElements(&data_sent_before_handshake_); delete data_to_resend; return; }
diff --git a/net/tools/quic/quic_simple_client_bin.cc b/net/tools/quic/quic_simple_client_bin.cc index df12f89a..33423db 100644 --- a/net/tools/quic/quic_simple_client_bin.cc +++ b/net/tools/quic/quic_simple_client_bin.cc
@@ -240,7 +240,7 @@ // Build the client, and try to connect. net::QuicServerId server_id(url.host(), url.EffectiveIntPort(), net::PRIVACY_MODE_DISABLED); - net::QuicVersionVector versions = net::QuicSupportedVersions(); + net::QuicVersionVector versions = net::AllSupportedVersions(); if (FLAGS_quic_version != -1) { versions.clear(); versions.push_back(static_cast<net::QuicVersion>(FLAGS_quic_version));
diff --git a/net/tools/quic/quic_simple_client_test.cc b/net/tools/quic/quic_simple_client_test.cc index 02a5807b..0a571a7 100644 --- a/net/tools/quic/quic_simple_client_test.cc +++ b/net/tools/quic/quic_simple_client_test.cc
@@ -18,7 +18,7 @@ IPEndPoint server_address(IPEndPoint(net::test::Loopback4(), 80)); QuicServerId server_id("hostname", server_address.port(), PRIVACY_MODE_DISABLED); - QuicVersionVector versions = QuicSupportedVersions(); + QuicVersionVector versions = AllSupportedVersions(); QuicSimpleClient client(server_address, server_id, versions, CryptoTestUtils::ProofVerifierForTesting()); EXPECT_TRUE(client.Initialize());
diff --git a/net/tools/quic/quic_simple_server_bin.cc b/net/tools/quic/quic_simple_server_bin.cc index e822159..f81a8272 100644 --- a/net/tools/quic/quic_simple_server_bin.cc +++ b/net/tools/quic/quic_simple_server_bin.cc
@@ -85,7 +85,7 @@ net::QuicSimpleServer server( CreateProofSource(line->GetSwitchValuePath("certificate_file"), line->GetSwitchValuePath("key_file")), - config, net::QuicSupportedVersions()); + config, net::AllSupportedVersions()); server.SetStrikeRegisterNoStartupPeriod(); int rc = server.Listen(net::IPEndPoint(ip, FLAGS_port));
diff --git a/net/tools/quic/quic_simple_server_session.cc b/net/tools/quic/quic_simple_server_session.cc index a869b38d..1624cee 100644 --- a/net/tools/quic/quic_simple_server_session.cc +++ b/net/tools/quic/quic_simple_server_session.cc
@@ -35,7 +35,9 @@ compressed_certs_cache), highest_promised_stream_id_(0) {} -QuicSimpleServerSession::~QuicSimpleServerSession() {} +QuicSimpleServerSession::~QuicSimpleServerSession() { + delete connection(); +} QuicCryptoServerStreamBase* QuicSimpleServerSession::CreateQuicCryptoServerStream(
diff --git a/net/tools/quic/quic_simple_server_session.h b/net/tools/quic/quic_simple_server_session.h index 135614d..407f5bd 100644 --- a/net/tools/quic/quic_simple_server_session.h +++ b/net/tools/quic/quic_simple_server_session.h
@@ -58,6 +58,7 @@ bool is_cancelled; }; + // Takes ownership of |connection|. QuicSimpleServerSession(const QuicConfig& config, QuicConnection* connection, QuicServerSessionBase::Visitor* visitor,
diff --git a/net/tools/quic/quic_simple_server_session_test.cc b/net/tools/quic/quic_simple_server_session_test.cc index c8c10d4..78ba420 100644 --- a/net/tools/quic/quic_simple_server_session_test.cc +++ b/net/tools/quic/quic_simple_server_session_test.cc
@@ -226,7 +226,7 @@ INSTANTIATE_TEST_CASE_P(Tests, QuicSimpleServerSessionTest, - ::testing::ValuesIn(QuicSupportedVersions())); + ::testing::ValuesIn(AllSupportedVersions())); TEST_P(QuicSimpleServerSessionTest, CloseStreamDueToReset) { // Open a stream, then reset it. @@ -520,7 +520,7 @@ INSTANTIATE_TEST_CASE_P(Tests, QuicSimpleServerSessionServerPushTest, - ::testing::ValuesIn(QuicSupportedVersions())); + ::testing::ValuesIn(AllSupportedVersions())); TEST_P(QuicSimpleServerSessionServerPushTest, TestPromisePushResources) { // Tests that given more than kMaxOpenStreamForTest resources, all their
diff --git a/net/tools/quic/quic_simple_server_stream.cc b/net/tools/quic/quic_simple_server_stream.cc index b7101b6..7b3c9ee 100644 --- a/net/tools/quic/quic_simple_server_stream.cc +++ b/net/tools/quic/quic_simple_server_stream.cc
@@ -136,8 +136,8 @@ } void QuicSimpleServerStream::SendResponse() { - if (!ContainsKey(request_headers_, ":authority") || - !ContainsKey(request_headers_, ":path")) { + if (!base::ContainsKey(request_headers_, ":authority") || + !base::ContainsKey(request_headers_, ":path")) { DVLOG(1) << "Request headers do not contain :authority or :path."; SendErrorResponse(); return;
diff --git a/net/tools/quic/quic_simple_server_stream_test.cc b/net/tools/quic/quic_simple_server_stream_test.cc index 36ea934..2a0de32 100644 --- a/net/tools/quic/quic_simple_server_stream_test.cc +++ b/net/tools/quic/quic_simple_server_stream_test.cc
@@ -244,7 +244,7 @@ INSTANTIATE_TEST_CASE_P(Tests, QuicSimpleServerStreamTest, - ::testing::ValuesIn(QuicSupportedVersions())); + ::testing::ValuesIn(AllSupportedVersions())); TEST_P(QuicSimpleServerStreamTest, TestFraming) { EXPECT_CALL(session_, WritevData(_, _, _, _, _, _))
diff --git a/net/tools/quic/quic_simple_server_test.cc b/net/tools/quic/quic_simple_server_test.cc index b4fad39..cf80fac 100644 --- a/net/tools/quic/quic_simple_server_test.cc +++ b/net/tools/quic/quic_simple_server_test.cc
@@ -25,7 +25,7 @@ : crypto_config_("blah", QuicRandom::GetInstance(), CryptoTestUtils::ProofSourceForTesting()), - version_manager_(QuicSupportedVersions()), + version_manager_(AllSupportedVersions()), dispatcher_( config_, &crypto_config_,
diff --git a/net/tools/quic/quic_socket_utils.cc b/net/tools/quic/quic_socket_utils.cc index 28a6f25..a6bc4c0c 100644 --- a/net/tools/quic/quic_socket_utils.cc +++ b/net/tools/quic/quic_socket_utils.cc
@@ -27,9 +27,7 @@ void QuicSocketUtils::GetAddressAndTimestampFromMsghdr( struct msghdr* hdr, IPAddress* address, - QuicTime* timestamp, - QuicWallTime* walltimestamp, - bool latched_walltimestamps) { + QuicWallTime* walltimestamp) { if (hdr->msg_controllen > 0) { for (cmsghdr* cmsg = CMSG_FIRSTHDR(hdr); cmsg != nullptr; cmsg = CMSG_NXTHDR(hdr, cmsg)) { @@ -52,12 +50,7 @@ timespec* ts = <s->systime; int64_t usec = (static_cast<int64_t>(ts->tv_sec) * 1000 * 1000) + (static_cast<int64_t>(ts->tv_nsec) / 1000); - if (latched_walltimestamps) { - *walltimestamp = QuicWallTime::FromUNIXMicroseconds(usec); - } else { - *timestamp = - QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(usec); - } + *walltimestamp = QuicWallTime::FromUNIXMicroseconds(usec); } } } @@ -80,6 +73,23 @@ } // static +bool QuicSocketUtils::GetTtlFromMsghdr(struct msghdr* hdr, int* ttl) { + if (hdr->msg_controllen > 0) { + struct cmsghdr* cmsg; + for (cmsg = CMSG_FIRSTHDR(hdr); cmsg != nullptr; + cmsg = CMSG_NXTHDR(hdr, cmsg)) { + if ((cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_TTL) || + (cmsg->cmsg_level == IPPROTO_IPV6 && + cmsg->cmsg_type == IPV6_HOPLIMIT)) { + *ttl = *(reinterpret_cast<int*>(CMSG_DATA(cmsg))); + return true; + } + } + } + return false; +} + +// static int QuicSocketUtils::SetGetAddressInfo(int fd, int address_family) { int get_local_ip = 1; int rc = setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &get_local_ip, @@ -122,9 +132,7 @@ size_t buf_len, QuicPacketCount* dropped_packets, IPAddress* self_address, - QuicTime* timestamp, QuicWallTime* walltimestamp, - bool latched_walltimestamps, IPEndPoint* peer_address) { DCHECK(peer_address != nullptr); char cbuf[kSpaceForCmsg]; @@ -176,13 +184,7 @@ walltimestamp = &stack_walltimestamp; } - QuicTime stack_timestamp = QuicTime::Zero(); - if (timestamp == nullptr) { - timestamp = &stack_timestamp; - } - - GetAddressAndTimestampFromMsghdr(&hdr, self_address, timestamp, walltimestamp, - latched_walltimestamps); + GetAddressAndTimestampFromMsghdr(&hdr, self_address, walltimestamp); if (raw_address.ss_family == AF_INET) { CHECK(peer_address->FromSockAddr(
diff --git a/net/tools/quic/quic_socket_utils.h b/net/tools/quic/quic_socket_utils.h index deaa4c8..f8cc539 100644 --- a/net/tools/quic/quic_socket_utils.h +++ b/net/tools/quic/quic_socket_utils.h
@@ -38,30 +38,31 @@ public: // The first integer is for overflow. The in6_pktinfo is the larger of the // address structures present. LinuxTimestamping is present for socket - // timestamping. + // timestamping. The subsequent int is for ttl. // The final int is a sentinel so the msg_controllen feedback // can be used to detect larger control messages than there is space for. static const int kSpaceForCmsg = CMSG_SPACE(CMSG_LEN(sizeof(int)) + CMSG_LEN(sizeof(in6_pktinfo)) + CMSG_LEN(sizeof(LinuxTimestamping)) + + CMSG_LEN(sizeof(int)) + CMSG_LEN(sizeof(int))); // Fills in |address| if |hdr| contains IP_PKTINFO or IPV6_PKTINFO. Fills in // |timestamp| if |hdr| contains |SO_TIMESTAMPING|. |address| and |timestamp| // must not be null. - // TODO(rjshade): Delete the |timestamp| argument when removing - // FLAGS_quic_socket_timestamps_walltime static void GetAddressAndTimestampFromMsghdr(struct msghdr* hdr, IPAddress* address, - QuicTime* timestamp, - QuicWallTime* walltimestamp, - bool latched_walltimestamps); + QuicWallTime* walltimestamp); // If the msghdr contains an SO_RXQ_OVFL entry, this will set dropped_packets // to the correct value and return true. Otherwise it will return false. static bool GetOverflowFromMsghdr(struct msghdr* hdr, QuicPacketCount* dropped_packets); + // If the msghdr contains an IP_TTL entry, this will set ttl to the correct + // value and return true. Otherwise it will return false. + static bool GetTtlFromMsghdr(struct msghdr* hdr, int* ttl); + // Sets either IP_PKTINFO or IPV6_PKTINFO on the socket, based on // address_family. Returns the return code from setsockopt. static int SetGetAddressInfo(int fd, int address_family); @@ -90,16 +91,12 @@ // received packet, assuming a packet was read and the platform supports // packet receipt timestamping. If the platform does not support packet // receipt timestamping, timestamp will not be changed. - // TODO(rjshade): Delete the |timestamp| argument when removing - // FLAGS_quic_socket_timestamps_walltime static int ReadPacket(int fd, char* buffer, size_t buf_len, QuicPacketCount* dropped_packets, IPAddress* self_address, - QuicTime* timestamp, QuicWallTime* walltimestamp, - bool latched_walltimestamps, IPEndPoint* peer_address); // Writes buf_len to the socket. If writing is successful, sets the result's
diff --git a/net/tools/quic/quic_time_wait_list_manager.cc b/net/tools/quic/quic_time_wait_list_manager.cc index ab2c66acd..4f99cb0 100644 --- a/net/tools/quic/quic_time_wait_list_manager.cc +++ b/net/tools/quic/quic_time_wait_list_manager.cc
@@ -91,7 +91,7 @@ QuicTimeWaitListManager::~QuicTimeWaitListManager() { connection_id_clean_up_alarm_->Cancel(); - STLDeleteElements(&pending_packets_queue_); + base::STLDeleteElements(&pending_packets_queue_); } void QuicTimeWaitListManager::AddConnectionIdToTimeWait( @@ -127,7 +127,7 @@ bool QuicTimeWaitListManager::IsConnectionIdInTimeWait( QuicConnectionId connection_id) const { - return ContainsKey(connection_id_map_, connection_id); + return base::ContainsKey(connection_id_map_, connection_id); } QuicVersion QuicTimeWaitListManager::GetQuicVersionFromConnectionId(
diff --git a/net/tools/quic/quic_time_wait_list_manager_test.cc b/net/tools/quic/quic_time_wait_list_manager_test.cc index 93a7c0f..ca5f85c 100644 --- a/net/tools/quic/quic_time_wait_list_manager_test.cc +++ b/net/tools/quic/quic_time_wait_list_manager_test.cc
@@ -176,7 +176,7 @@ const std::tr1::tuple<const char*, int> packet_buffer, testing::MatchResultListener* /* listener */) const override { FramerVisitorCapturingPublicReset visitor; - QuicFramer framer(QuicSupportedVersions(), QuicTime::Zero(), + QuicFramer framer(AllSupportedVersions(), QuicTime::Zero(), Perspective::IS_CLIENT); framer.set_visitor(&visitor); QuicEncryptedPacket encrypted(std::tr1::get<0>(packet_buffer), @@ -226,15 +226,14 @@ TEST_F(QuicTimeWaitListManagerTest, SendVersionNegotiationPacket) { std::unique_ptr<QuicEncryptedPacket> packet( QuicFramer::BuildVersionNegotiationPacket(connection_id_, - QuicSupportedVersions())); + AllSupportedVersions())); EXPECT_CALL(writer_, WritePacket(_, packet->length(), server_address_.address(), client_address_, _)) .WillOnce(Return(WriteResult(WRITE_STATUS_OK, 1))); time_wait_list_manager_.SendVersionNegotiationPacket( - connection_id_, QuicSupportedVersions(), server_address_, - client_address_); + connection_id_, AllSupportedVersions(), server_address_, client_address_); EXPECT_EQ(0u, time_wait_list_manager_.num_connections()); }
diff --git a/net/tools/quic/stateless_rejector.cc b/net/tools/quic/stateless_rejector.cc index 5973a9e..e85e0a6 100644 --- a/net/tools/quic/stateless_rejector.cc +++ b/net/tools/quic/stateless_rejector.cc
@@ -35,6 +35,7 @@ QuicCompressedCertsCache* compressed_certs_cache, const QuicClock* clock, QuicRandom* random, + QuicByteCount chlo_packet_size, const IPEndPoint& client_address, const IPEndPoint& server_address) : state_(FAILED), @@ -42,6 +43,7 @@ version_(version), versions_(versions), connection_id_(0), + chlo_packet_size_(chlo_packet_size), client_address_(client_address), server_address_(server_address), clock_(clock), @@ -86,8 +88,9 @@ /*reject_only=*/true, connection_id_, server_address_.address(), client_address_, version_, versions_, /*use_stateless_rejects=*/true, server_designated_connection_id_, clock_, - random_, compressed_certs_cache_, ¶ms, &proof_, &reply_, - &diversification_nonce, &error_details_); + random_, compressed_certs_cache_, ¶ms, &proof_, + QuicCryptoStream::CryptoMessageFramingOverhead(version_), + chlo_packet_size_, &reply_, &diversification_nonce, &error_details_); if (error != QUIC_NO_ERROR) { error_ = error; return;
diff --git a/net/tools/quic/stateless_rejector.h b/net/tools/quic/stateless_rejector.h index 9841798..39c03a1 100644 --- a/net/tools/quic/stateless_rejector.h +++ b/net/tools/quic/stateless_rejector.h
@@ -29,6 +29,7 @@ QuicCompressedCertsCache* compressed_certs_cache, const QuicClock* clock, QuicRandom* random, + QuicByteCount chlo_packet_size, const IPEndPoint& client_address, const IPEndPoint& server_address); @@ -70,6 +71,7 @@ QuicVersionVector versions_; QuicConnectionId connection_id_; QuicConnectionId server_designated_connection_id_; + QuicByteCount chlo_packet_size_; IPEndPoint client_address_; IPEndPoint server_address_; const QuicClock* clock_;
diff --git a/net/tools/quic/stateless_rejector_test.cc b/net/tools/quic/stateless_rejector_test.cc index 9e612bd8..95cbb924 100644 --- a/net/tools/quic/stateless_rejector_test.cc +++ b/net/tools/quic/stateless_rejector_test.cc
@@ -42,7 +42,7 @@ vector<TestParams> params; for (FlagsMode flags : {ENABLED, STATELESS_DISABLED, CHEAP_DISABLED, BOTH_DISABLED}) { - for (QuicVersion version : QuicSupportedVersions()) { + for (QuicVersion version : AllSupportedVersions()) { TestParams param; param.version = version; param.flags = flags; @@ -63,11 +63,12 @@ compressed_certs_cache_( QuicCompressedCertsCache::kQuicCompressedCertsCacheSize), rejector_(GetParam().version, - QuicSupportedVersions(), + AllSupportedVersions(), &config_, &compressed_certs_cache_, &clock_, QuicRandom::GetInstance(), + kDefaultMaxPacketSize, IPEndPoint(net::test::Loopback4(), 12345), IPEndPoint(net::test::Loopback4(), 443)) { FLAGS_enable_quic_stateless_reject_support =
diff --git a/net/tools/quic/test_tools/packet_reordering_writer.cc b/net/tools/quic/test_tools/packet_reordering_writer.cc new file mode 100644 index 0000000..a11f7d8e --- /dev/null +++ b/net/tools/quic/test_tools/packet_reordering_writer.cc
@@ -0,0 +1,50 @@ +// 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 "net/tools/quic/test_tools/packet_reordering_writer.h" + +namespace net { +namespace test { + +PacketReorderingWriter::PacketReorderingWriter() {} + +PacketReorderingWriter::~PacketReorderingWriter() {} + +WriteResult PacketReorderingWriter::WritePacket(const char* buffer, + size_t buf_len, + const IPAddress& self_address, + const IPEndPoint& peer_address, + PerPacketOptions* options) { + if (!delay_next_) { + WriteResult wr = QuicPacketWriterWrapper::WritePacket( + buffer, buf_len, self_address, peer_address, options); + --num_packets_to_wait_; + if (num_packets_to_wait_ == 0) { + // It's time to write the delayed packet. + QuicPacketWriterWrapper::WritePacket( + delayed_data_.data(), delayed_data_.length(), delayed_self_address_, + delayed_peer_address_, delayed_options_.get()); + } + return wr; + } + // Still have packet to wait. + DCHECK_LT(0u, num_packets_to_wait_) << "Only allow one packet to be delayed"; + delayed_data_ = std::string(buffer, buf_len); + delayed_self_address_ = self_address; + delayed_peer_address_ = peer_address; + if (options != nullptr) { + delayed_options_.reset(options->Clone()); + } + delay_next_ = false; + return WriteResult(WRITE_STATUS_OK, buf_len); +} + +void PacketReorderingWriter::SetDelay(size_t num_packets_to_wait) { + DCHECK_GT(num_packets_to_wait, 0u); + num_packets_to_wait_ = num_packets_to_wait; + delay_next_ = true; +} + +} // namespace test +} // namespace net
diff --git a/net/tools/quic/test_tools/packet_reordering_writer.h b/net/tools/quic/test_tools/packet_reordering_writer.h new file mode 100644 index 0000000..d09aeb84 --- /dev/null +++ b/net/tools/quic/test_tools/packet_reordering_writer.h
@@ -0,0 +1,45 @@ +// 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 NET_TOOLS_QUIC_TEST_TOOLS_PACKET_REORDERING_WRITER_H_ +#define NET_TOOLS_QUIC_TEST_TOOLS_PACKET_REORDERING_WRITER_H_ + +#include "net/tools/quic/quic_packet_writer_wrapper.h" + +namespace net { + +namespace test { + +// This packet writer allows delaying writing the next packet after +// SetDelay(num_packets_to_wait) +// is called and buffer this packet and write it after it writes next +// |num_packets_to_wait| packets. It doesn't support delaying a packet while +// there is already a packet delayed. +class PacketReorderingWriter : public QuicPacketWriterWrapper { + public: + PacketReorderingWriter(); + + ~PacketReorderingWriter() override; + + WriteResult WritePacket(const char* buffer, + size_t buf_len, + const IPAddress& self_address, + const IPEndPoint& peer_address, + PerPacketOptions* options) override; + + void SetDelay(size_t num_packets_to_wait); + + private: + bool delay_next_ = false; + size_t num_packets_to_wait_ = 0; + std::string delayed_data_; + IPAddress delayed_self_address_; + IPEndPoint delayed_peer_address_; + std::unique_ptr<PerPacketOptions> delayed_options_; +}; + +} // namespace test +} // namespace net + +#endif // NET_TOOLS_QUIC_TEST_TOOLS_PACKET_REORDERING_WRITER_H_
diff --git a/net/tools/quic/test_tools/quic_dispatcher_peer.cc b/net/tools/quic/test_tools/quic_dispatcher_peer.cc index 48a61f71..e7d61cf 100644 --- a/net/tools/quic/test_tools/quic_dispatcher_peer.cc +++ b/net/tools/quic/test_tools/quic_dispatcher_peer.cc
@@ -62,6 +62,12 @@ } // static +QuicBufferedPacketStore* QuicDispatcherPeer::GetBufferedPackets( + QuicDispatcher* dispatcher) { + return &(dispatcher->buffered_packets_); +} + +// static const QuicDispatcher::SessionMap& QuicDispatcherPeer::session_map( QuicDispatcher* dispatcher) { return dispatcher->session_map();
diff --git a/net/tools/quic/test_tools/quic_dispatcher_peer.h b/net/tools/quic/test_tools/quic_dispatcher_peer.h index 4ff4d2d..05a4a26 100644 --- a/net/tools/quic/test_tools/quic_dispatcher_peer.h +++ b/net/tools/quic/test_tools/quic_dispatcher_peer.h
@@ -41,6 +41,9 @@ // visitor's OnError() method. Then set that record to QUIC_NO_ERROR. static QuicErrorCode GetAndClearLastError(QuicDispatcher* dispatcher); + static QuicBufferedPacketStore* GetBufferedPackets( + QuicDispatcher* dispatcher); + static const QuicDispatcher::SessionMap& session_map( QuicDispatcher* dispatcher);
diff --git a/net/udp/udp_socket_unittest.cc b/net/udp/udp_socket_unittest.cc index 1f34ff6b..860b4a3c 100644 --- a/net/udp/udp_socket_unittest.cc +++ b/net/udp/udp_socket_unittest.cc
@@ -398,7 +398,7 @@ EXPECT_THAT(test_socket->GetLocalAddress(&client_address), IsOk()); EXPECT_EQ(used_ports.back(), client_address.port()); - STLDeleteElements(&sockets); + base::STLDeleteElements(&sockets); } // Return a privileged port (under 1024) so binding will fail.
diff --git a/net/url_request/report_sender.cc b/net/url_request/report_sender.cc index bc8e11d..c91ddd07 100644 --- a/net/url_request/report_sender.cc +++ b/net/url_request/report_sender.cc
@@ -29,7 +29,7 @@ ReportSender::~ReportSender() { // Cancel all of the uncompleted requests. - STLDeleteElements(&inflight_requests_); + base::STLDeleteElements(&inflight_requests_); } void ReportSender::Send(const GURL& report_uri, const std::string& report) {
diff --git a/net/url_request/url_fetcher_core.cc b/net/url_request/url_fetcher_core.cc index 0f75e67..3d49ad2 100644 --- a/net/url_request/url_fetcher_core.cc +++ b/net/url_request/url_fetcher_core.cc
@@ -50,12 +50,12 @@ URLFetcherCore::Registry::~Registry() {} void URLFetcherCore::Registry::AddURLFetcherCore(URLFetcherCore* core) { - DCHECK(!ContainsKey(fetchers_, core)); + DCHECK(!base::ContainsKey(fetchers_, core)); fetchers_.insert(core); } void URLFetcherCore::Registry::RemoveURLFetcherCore(URLFetcherCore* core) { - DCHECK(ContainsKey(fetchers_, core)); + DCHECK(base::ContainsKey(fetchers_, core)); fetchers_.erase(core); }
diff --git a/net/url_request/url_request_http_job_unittest.cc b/net/url_request/url_request_http_job_unittest.cc index e820f4f..c6eecb8 100644 --- a/net/url_request/url_request_http_job_unittest.cc +++ b/net/url_request/url_request_http_job_unittest.cc
@@ -348,7 +348,7 @@ MockRead("test.html")}; net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK); - ssl_socket_data_provider.SetNextProto(kProtoHTTP11); + ssl_socket_data_provider.next_proto = kProtoHTTP11; ssl_socket_data_provider.cert = ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider); @@ -409,7 +409,7 @@ }; net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK); - ssl_socket_data_provider.SetNextProto(kProtoHTTP11); + ssl_socket_data_provider.next_proto = kProtoHTTP11; ssl_socket_data_provider.cert = ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider); @@ -482,7 +482,7 @@ MockRead("test.html")}; net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK); - ssl_socket_data_provider.SetNextProto(kProtoHTTP11); + ssl_socket_data_provider.next_proto = kProtoHTTP11; ssl_socket_data_provider.cert = ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider); @@ -773,7 +773,7 @@ TEST_F(URLRequestHttpJobWithBrotliSupportTest, BrotliAdvertisement) { net::SSLSocketDataProvider ssl_socket_data_provider(net::ASYNC, net::OK); - ssl_socket_data_provider.SetNextProto(kProtoHTTP11); + ssl_socket_data_provider.next_proto = kProtoHTTP11; ssl_socket_data_provider.cert = ImportCertFromFile(GetTestCertsDirectory(), "unittest.selfsigned.der"); socket_factory_.AddSSLSocketDataProvider(&ssl_socket_data_provider);
diff --git a/net/url_request/url_request_job_factory_impl.cc b/net/url_request/url_request_job_factory_impl.cc index f69db49..8fe4703 100644 --- a/net/url_request/url_request_job_factory_impl.cc +++ b/net/url_request/url_request_job_factory_impl.cc
@@ -36,7 +36,7 @@ return true; } - if (ContainsKey(protocol_handler_map_, scheme)) + if (base::ContainsKey(protocol_handler_map_, scheme)) return false; protocol_handler_map_[scheme] = std::move(protocol_handler); return true; @@ -76,8 +76,8 @@ bool URLRequestJobFactoryImpl::IsHandledProtocol( const std::string& scheme) const { DCHECK(CalledOnValidThread()); - return ContainsKey(protocol_handler_map_, scheme) || - URLRequestJobManager::GetInstance()->SupportsScheme(scheme); + return base::ContainsKey(protocol_handler_map_, scheme) || + URLRequestJobManager::GetInstance()->SupportsScheme(scheme); } bool URLRequestJobFactoryImpl::IsHandledURL(const GURL& url) const {
diff --git a/net/websockets/websocket_basic_handshake_stream.cc b/net/websockets/websocket_basic_handshake_stream.cc index 89ce78c..3beff5d 100644 --- a/net/websockets/websocket_basic_handshake_stream.cc +++ b/net/websockets/websocket_basic_handshake_stream.cc
@@ -84,7 +84,8 @@ std::string GenerateHandshakeChallenge() { std::string raw_challenge(websockets::kRawChallengeLength, '\0'); - crypto::RandBytes(string_as_array(&raw_challenge), raw_challenge.length()); + crypto::RandBytes(base::string_as_array(&raw_challenge), + raw_challenge.length()); std::string encoded_challenge; base::Base64Encode(raw_challenge, &encoded_challenge); return encoded_challenge;
diff --git a/pdf/out_of_process_instance.cc b/pdf/out_of_process_instance.cc index c06523d..af5d1a5 100644 --- a/pdf/out_of_process_instance.cc +++ b/pdf/out_of_process_instance.cc
@@ -321,10 +321,9 @@ if (!document_url_var.is_string()) return false; std::string document_url = document_url_var.AsString(); - std::string extension_url = std::string(kChromeExtension); - std::string print_preview_url = std::string(kChromePrint); - if (!base::StringPiece(document_url).starts_with(kChromeExtension) && - !base::StringPiece(document_url).starts_with(kChromePrint)) { + base::StringPiece document_url_piece(document_url); + if (!document_url_piece.starts_with(kChromeExtension) && + !document_url_piece.starts_with(kChromePrint)) { return false; }
diff --git a/pdf/pdfium/pdfium_engine.cc b/pdf/pdfium/pdfium_engine.cc index 29f9a7ac..6859b01 100644 --- a/pdf/pdfium/pdfium_engine.cc +++ b/pdf/pdfium/pdfium_engine.cc
@@ -452,7 +452,7 @@ FPDFBookmark_GetFirstChild(doc, bookmark); child_bookmark; child_bookmark = FPDFBookmark_GetNextSibling(doc, child_bookmark)) { - if (ContainsKey(seen_bookmarks, child_bookmark)) + if (base::ContainsKey(seen_bookmarks, child_bookmark)) break; seen_bookmarks.insert(child_bookmark); @@ -647,7 +647,7 @@ } FPDFAvail_Destroy(fpdf_availability_); - STLDeleteElements(&pages_); + base::STLDeleteElements(&pages_); } #ifdef PDF_USE_XFA @@ -2671,7 +2671,7 @@ } bool PDFiumEngine::IsPageVisible(int index) const { - return ContainsValue(visible_pages_, index); + return base::ContainsValue(visible_pages_, index); } bool PDFiumEngine::CheckPageAvailable(int index, std::vector<int>* pending) { @@ -2683,7 +2683,7 @@ return true; if (!FPDFAvail_IsPageAvail(fpdf_availability_, index, &download_hints_)) { - if (!ContainsValue(*pending, index)) + if (!base::ContainsValue(*pending, index)) pending->push_back(index); return false; }
diff --git a/ppapi/native_client/tools/browser_tester/browsertester/browserlauncher.py b/ppapi/native_client/tools/browser_tester/browsertester/browserlauncher.py index 1abbb447..b07be10 100755 --- a/ppapi/native_client/tools/browser_tester/browsertester/browserlauncher.py +++ b/ppapi/native_client/tools/browser_tester/browsertester/browserlauncher.py
@@ -268,13 +268,12 @@ # https://code.google.com/p/chromium/issues/detail?id=171836) '--enable-logging', '--disable-web-resources', - '--disable-preconnect', + # This prevents Chrome from making "hidden" network requests at + # startup and navigation. These requests could be a source of + # non-determinism, and they also add noise to the netlogs. + '--disable-features=NetworkPrediction', # This is speculative, sync should not occur with a clean profile. '--disable-sync', - # This prevents Chrome from making "hidden" network requests at - # startup. These requests could be a source of non-determinism, - # and they also add noise to the netlogs. - '--dns-prefetch-disable', '--no-first-run', '--no-default-browser-check', '--log-level=1',
diff --git a/ppapi/proxy/file_system_resource.cc b/ppapi/proxy/file_system_resource.cc index 0be0ea5..37b2cc72 100644 --- a/ppapi/proxy/file_system_resource.cc +++ b/ppapi/proxy/file_system_resource.cc
@@ -95,12 +95,12 @@ } void FileSystemResource::OpenQuotaFile(PP_Resource file_io) { - DCHECK(!ContainsKey(files_, file_io)); + DCHECK(!base::ContainsKey(files_, file_io)); files_.insert(file_io); } void FileSystemResource::CloseQuotaFile(PP_Resource file_io) { - DCHECK(ContainsKey(files_, file_io)); + DCHECK(base::ContainsKey(files_, file_io)); files_.erase(file_io); }
diff --git a/remoting/android/BUILD.gn b/remoting/android/BUILD.gn index a1fb981c..2542aea 100644 --- a/remoting/android/BUILD.gn +++ b/remoting/android/BUILD.gn
@@ -65,6 +65,7 @@ "EGL", ] configs += [ "//remoting:enable_webrtc_remoting_client" ] + defines = [ "REMOTING_ANDROID_ENABLE_OPENGL_RENDERER=1" ] } _raw_resources_base_dir = "$target_gen_dir/remoting_android_raw_resources/res"
diff --git a/remoting/base/buffered_socket_writer.cc b/remoting/base/buffered_socket_writer.cc index 4e0fd2a..bd401f8 100644 --- a/remoting/base/buffered_socket_writer.cc +++ b/remoting/base/buffered_socket_writer.cc
@@ -47,7 +47,7 @@ BufferedSocketWriter::BufferedSocketWriter() : weak_factory_(this) {} BufferedSocketWriter::~BufferedSocketWriter() { - STLDeleteElements(&queue_); + base::STLDeleteElements(&queue_); } void BufferedSocketWriter::Start(
diff --git a/remoting/client/jni/jni_display_handler.cc b/remoting/client/jni/jni_display_handler.cc index cd51e52a..923a046 100644 --- a/remoting/client/jni/jni_display_handler.cc +++ b/remoting/client/jni/jni_display_handler.cc
@@ -102,7 +102,8 @@ // the data out of the buffer without mutating it, and doesn't keep any // reference to the buffer afterwards. Unfortunately, there seems to be no way // to create a read-only ByteBuffer from a pointer-to-const. - char* data = string_as_array(const_cast<std::string*>(&cursor_shape.data())); + char* data = + base::string_as_array(const_cast<std::string*>(&cursor_shape.data())); int cursor_total_bytes = cursor_shape.width() * cursor_shape.height() * kBytesPerPixel;
diff --git a/remoting/codec/audio_decoder_opus.cc b/remoting/codec/audio_decoder_opus.cc index 5d05d3c..5744487 100644 --- a/remoting/codec/audio_decoder_opus.cc +++ b/remoting/codec/audio_decoder_opus.cc
@@ -107,13 +107,13 @@ int buffer_pos = 0; for (int i = 0; i < packet->data_size(); ++i) { - int16_t* pcm_buffer = - reinterpret_cast<int16_t*>(string_as_array(decoded_data) + buffer_pos); + int16_t* pcm_buffer = reinterpret_cast<int16_t*>( + base::string_as_array(decoded_data) + buffer_pos); CHECK_LE(buffer_pos + max_frame_bytes, static_cast<int>(decoded_data->size())); std::string* frame = packet->mutable_data(i); unsigned char* frame_data = - reinterpret_cast<unsigned char*>(string_as_array(frame)); + reinterpret_cast<unsigned char*>(base::string_as_array(frame)); int result = opus_decode(decoder_, frame_data, frame->size(), pcm_buffer, max_frame_samples, 0); if (result < 0) {
diff --git a/remoting/codec/audio_encoder_opus.cc b/remoting/codec/audio_encoder_opus.cc index cc3e71c..8ebef6f 100644 --- a/remoting/codec/audio_encoder_opus.cc +++ b/remoting/codec/audio_encoder_opus.cc
@@ -198,7 +198,7 @@ // Encode. unsigned char* buffer = - reinterpret_cast<unsigned char*>(string_as_array(data)); + reinterpret_cast<unsigned char*>(base::string_as_array(data)); int result = opus_encode(encoder_, pcm_buffer, kFrameSamples, buffer, data->length()); if (result < 0) {
diff --git a/remoting/codec/video_encoder_verbatim.cc b/remoting/codec/video_encoder_verbatim.cc index 27221e03..6e01304 100644 --- a/remoting/codec/video_encoder_verbatim.cc +++ b/remoting/codec/video_encoder_verbatim.cc
@@ -19,7 +19,8 @@ static uint8_t* GetPacketOutputBuffer(VideoPacket* packet, size_t size) { packet->mutable_data()->resize(size); - return reinterpret_cast<uint8_t*>(string_as_array(packet->mutable_data())); + return reinterpret_cast<uint8_t*>( + base::string_as_array(packet->mutable_data())); } VideoEncoderVerbatim::VideoEncoderVerbatim() {}
diff --git a/remoting/host/desktop_session_proxy.cc b/remoting/host/desktop_session_proxy.cc index ed7ba98..ccfee25 100644 --- a/remoting/host/desktop_session_proxy.cc +++ b/remoting/host/desktop_session_proxy.cc
@@ -484,6 +484,10 @@ --pending_capture_frame_requests_; + if (!video_capturer_) { + return; + } + if (result != webrtc::DesktopCapturer::Result::SUCCESS) { video_capturer_->OnCaptureResult(result, nullptr); return;
diff --git a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc index edef673..04273a1d 100644 --- a/remoting/host/it2me/it2me_native_messaging_host_unittest.cc +++ b/remoting/host/it2me/it2me_native_messaging_host_unittest.cc
@@ -277,7 +277,7 @@ std::string message_json(length, '\0'); read_result = output_read_file_.ReadAtCurrentPos( - string_as_array(&message_json), length); + base::string_as_array(&message_json), length); if (read_result != static_cast<int>(length)) { LOG(ERROR) << "Message size (" << read_result << ") doesn't match the header (" << length << ").";
diff --git a/remoting/host/linux/audio_pipe_reader.cc b/remoting/host/linux/audio_pipe_reader.cc index 691e78bb..c8d090e 100644 --- a/remoting/host/linux/audio_pipe_reader.cc +++ b/remoting/host/linux/audio_pipe_reader.cc
@@ -161,8 +161,8 @@ data.resize(pos + bytes_to_read); while (pos < data.size()) { - int read_result = - pipe_.ReadAtCurrentPos(string_as_array(&data) + pos, data.size() - pos); + int read_result = pipe_.ReadAtCurrentPos(base::string_as_array(&data) + pos, + data.size() - pos); if (read_result > 0) { pos += read_result; } else {
diff --git a/remoting/host/native_messaging/native_messaging_reader.cc b/remoting/host/native_messaging/native_messaging_reader.cc index 6aad692..2ded6a7 100644 --- a/remoting/host/native_messaging/native_messaging_reader.cc +++ b/remoting/host/native_messaging/native_messaging_reader.cc
@@ -111,8 +111,8 @@ } std::string message_json(message_length, '\0'); - read_result = read_stream_.ReadAtCurrentPos(string_as_array(&message_json), - message_length); + read_result = read_stream_.ReadAtCurrentPos( + base::string_as_array(&message_json), message_length); if (read_result != static_cast<int>(message_length)) { LOG(ERROR) << "Failed to read message body, read returned " << read_result;
diff --git a/remoting/host/native_messaging/native_messaging_writer_unittest.cc b/remoting/host/native_messaging/native_messaging_writer_unittest.cc index 37963c0..b2f7ccfe 100644 --- a/remoting/host/native_messaging/native_messaging_writer_unittest.cc +++ b/remoting/host/native_messaging/native_messaging_writer_unittest.cc
@@ -48,7 +48,7 @@ int read = read_file_.ReadAtCurrentPos(reinterpret_cast<char*>(&length), 4); EXPECT_EQ(4, read); std::string content(length, '\0'); - read = read_file_.ReadAtCurrentPos(string_as_array(&content), length); + read = read_file_.ReadAtCurrentPos(base::string_as_array(&content), length); EXPECT_EQ(static_cast<int>(length), read); // |content| should now contain serialized |message|. @@ -80,7 +80,7 @@ read = read_file_.ReadAtCurrentPos(reinterpret_cast<char*>(&length), 4); EXPECT_EQ(4, read) << "i = " << i; content.resize(length); - read = read_file_.ReadAtCurrentPos(string_as_array(&content), length); + read = read_file_.ReadAtCurrentPos(base::string_as_array(&content), length); EXPECT_EQ(static_cast<int>(length), read) << "i = " << i; }
diff --git a/remoting/host/security_key/security_key_message_reader.cc b/remoting/host/security_key/security_key_message_reader.cc index 2e2cf33..a53d0d0 100644 --- a/remoting/host/security_key/security_key_message_reader.cc +++ b/remoting/host/security_key/security_key_message_reader.cc
@@ -86,8 +86,8 @@ } std::string message_data(total_message_size_bytes, '\0'); - read_result = read_stream_.ReadAtCurrentPos(string_as_array(&message_data), - total_message_size_bytes); + read_result = read_stream_.ReadAtCurrentPos( + base::string_as_array(&message_data), total_message_size_bytes); // The static cast is safe as we know the value is smaller than max int. if (read_result != static_cast<int>(total_message_size_bytes)) { LOG(ERROR) << "Failed to read message: " << read_result;
diff --git a/remoting/host/security_key/security_key_message_reader_impl.cc b/remoting/host/security_key/security_key_message_reader_impl.cc index d129c87c..0d283f9 100644 --- a/remoting/host/security_key/security_key_message_reader_impl.cc +++ b/remoting/host/security_key/security_key_message_reader_impl.cc
@@ -77,7 +77,8 @@ } std::string message_data(message_length_bytes, '\0'); - if (!ReadFromStream(string_as_array(&message_data), message_data.size())) { + if (!ReadFromStream(base::string_as_array(&message_data), + message_data.size())) { NotifyError(); return; }
diff --git a/remoting/host/security_key/security_key_message_writer_impl_unittest.cc b/remoting/host/security_key/security_key_message_writer_impl_unittest.cc index 7545ab6..ead0f8b 100644 --- a/remoting/host/security_key/security_key_message_writer_impl_unittest.cc +++ b/remoting/host/security_key/security_key_message_writer_impl_unittest.cc
@@ -66,16 +66,16 @@ std::string SecurityKeyMessageWriterImplTest::ReadMessage( int payload_length_bytes) { std::string message_header(SecurityKeyMessage::kHeaderSizeBytes, '\0'); - read_file_.ReadAtCurrentPos(string_as_array(&message_header), + read_file_.ReadAtCurrentPos(base::string_as_array(&message_header), SecurityKeyMessage::kHeaderSizeBytes); std::string message_type(SecurityKeyMessage::kMessageTypeSizeBytes, '\0'); - read_file_.ReadAtCurrentPos(string_as_array(&message_type), + read_file_.ReadAtCurrentPos(base::string_as_array(&message_type), SecurityKeyMessage::kMessageTypeSizeBytes); std::string message_data(payload_length_bytes, '\0'); if (payload_length_bytes) { - read_file_.ReadAtCurrentPos(string_as_array(&message_data), + read_file_.ReadAtCurrentPos(base::string_as_array(&message_data), payload_length_bytes); } @@ -173,8 +173,8 @@ // Retrieve and verify the message type. std::string message_type(length, '\0'); - int bytes_read = - read_file_.ReadAtCurrentPos(string_as_array(&message_type), length); + int bytes_read = read_file_.ReadAtCurrentPos( + base::string_as_array(&message_type), length); ASSERT_EQ(length, bytes_read); SecurityKeyMessageType type =
diff --git a/remoting/host/setup/me2me_native_messaging_host_unittest.cc b/remoting/host/setup/me2me_native_messaging_host_unittest.cc index 4f57748..6a28f4b 100644 --- a/remoting/host/setup/me2me_native_messaging_host_unittest.cc +++ b/remoting/host/setup/me2me_native_messaging_host_unittest.cc
@@ -418,7 +418,7 @@ std::string message_json(length, '\0'); read_result = output_read_file_.ReadAtCurrentPos( - string_as_array(&message_json), length); + base::string_as_array(&message_json), length); if (read_result != static_cast<int>(length)) { return nullptr; }
diff --git a/remoting/host/touch_injector_win_unittest.cc b/remoting/host/touch_injector_win_unittest.cc index f3d24d9..4e0fc17 100644 --- a/remoting/host/touch_injector_win_unittest.cc +++ b/remoting/host/touch_injector_win_unittest.cc
@@ -63,7 +63,7 @@ for (size_t i = 0; i < id_to_flag_map.size(); ++i) { const POINTER_TOUCH_INFO* touch_info = arg + i; const uint32_t id = touch_info->pointerInfo.pointerId; - if (!ContainsKey(id_to_flag_map, id)) + if (!base::ContainsKey(id_to_flag_map, id)) return false; if (id_to_flag_map.find(id)->second != touch_info->pointerInfo.pointerFlags)
diff --git a/remoting/protocol/channel_multiplexer.cc b/remoting/protocol/channel_multiplexer.cc index 983f8a8..5d34338 100644 --- a/remoting/protocol/channel_multiplexer.cc +++ b/remoting/protocol/channel_multiplexer.cc
@@ -145,7 +145,7 @@ ChannelMultiplexer::MuxChannel::~MuxChannel() { // Socket must be destroyed before the channel. DCHECK(!socket_); - STLDeleteElements(&pending_packets_); + base::STLDeleteElements(&pending_packets_); } std::unique_ptr<P2PStreamSocket> @@ -310,7 +310,7 @@ ChannelMultiplexer::~ChannelMultiplexer() { DCHECK(pending_channels_.empty()); - STLDeleteValues(&channels_); + base::STLDeleteValues(&channels_); // Cancel creation of the base channel if it hasn't finished. if (base_channel_factory_)
diff --git a/remoting/protocol/chromium_socket_factory.cc b/remoting/protocol/chromium_socket_factory.cc index 5b1db88..f9a0555 100644 --- a/remoting/protocol/chromium_socket_factory.cc +++ b/remoting/protocol/chromium_socket_factory.cc
@@ -6,7 +6,9 @@ #include <stddef.h> +#include <list> #include <memory> +#include <string> #include "base/bind.h" #include "base/logging.h" @@ -20,6 +22,7 @@ #include "remoting/protocol/socket_util.h" #include "third_party/webrtc/base/asyncpacketsocket.h" #include "third_party/webrtc/base/nethelpers.h" +#include "third_party/webrtc/base/socket.h" #include "third_party/webrtc/media/base/rtputils.h" namespace remoting { @@ -66,11 +69,13 @@ struct PendingPacket { PendingPacket(const void* buffer, int buffer_size, - const net::IPEndPoint& address); + const net::IPEndPoint& address, + int packet_id); scoped_refptr<net::IOBufferWithSize> data; net::IPEndPoint address; bool retried; + int packet_id; }; void OnBindCompleted(int error); @@ -100,13 +105,14 @@ DISALLOW_COPY_AND_ASSIGN(UdpPacketSocket); }; -UdpPacketSocket::PendingPacket::PendingPacket( - const void* buffer, - int buffer_size, - const net::IPEndPoint& address) +UdpPacketSocket::PendingPacket::PendingPacket(const void* buffer, + int buffer_size, + const net::IPEndPoint& address, + int packet_id) : data(new net::IOBufferWithSize(buffer_size)), address(address), - retried(false) { + retried(false), + packet_id(packet_id) { memcpy(data->data(), buffer, buffer_size); } @@ -197,7 +203,7 @@ return EWOULDBLOCK; } - PendingPacket packet(data, data_size, endpoint); + PendingPacket packet(data, data_size, endpoint, options.packet_id); cricket::ApplyPacketOptions( reinterpret_cast<uint8_t*>(packet.data->data()), data_size, options.packet_time_params, @@ -321,6 +327,10 @@ // Don't need to worry about partial sends because this is a datagram // socket. send_queue_size_ -= send_queue_.front().data->size(); + SignalSentPacket(this, rtc::SentPacket(send_queue_.front().packet_id, + (base::TimeTicks::Now() - + base::TimeTicks::UnixEpoch()) + .InMilliseconds())); send_queue_.pop_front(); DoSend(); }
diff --git a/remoting/protocol/jingle_session.cc b/remoting/protocol/jingle_session.cc index 16d9b7b..ddef7589 100644 --- a/remoting/protocol/jingle_session.cc +++ b/remoting/protocol/jingle_session.cc
@@ -72,10 +72,10 @@ } JingleSession::~JingleSession() { - STLDeleteContainerPointers(pending_requests_.begin(), - pending_requests_.end()); - STLDeleteContainerPointers(transport_info_requests_.begin(), - transport_info_requests_.end()); + base::STLDeleteContainerPointers(pending_requests_.begin(), + pending_requests_.end()); + base::STLDeleteContainerPointers(transport_info_requests_.begin(), + transport_info_requests_.end()); session_manager_->SessionDestroyed(this); }
diff --git a/remoting/protocol/message_decoder_unittest.cc b/remoting/protocol/message_decoder_unittest.cc index 25f05b8..1c5f0731 100644 --- a/remoting/protocol/message_decoder_unittest.cc +++ b/remoting/protocol/message_decoder_unittest.cc
@@ -107,7 +107,7 @@ EXPECT_EQ((index % 2) != 0, message->key_event().pressed()); ++index; } - STLDeleteElements(&message_list); + base::STLDeleteElements(&message_list); } TEST(MessageDecoderTest, SmallReads) {
diff --git a/remoting/protocol/message_reader_unittest.cc b/remoting/protocol/message_reader_unittest.cc index 5ac8a70d..33c916a 100644 --- a/remoting/protocol/message_reader_unittest.cc +++ b/remoting/protocol/message_reader_unittest.cc
@@ -50,7 +50,7 @@ reader_.reset(new MessageReader()); } - void TearDown() override { STLDeleteElements(&messages_); } + void TearDown() override { base::STLDeleteElements(&messages_); } void InitReader() { reader_->StartReading(
diff --git a/remoting/test/fake_socket_factory.cc b/remoting/test/fake_socket_factory.cc index a9faaa12..39a9e86 100644 --- a/remoting/test/fake_socket_factory.cc +++ b/remoting/test/fake_socket_factory.cc
@@ -10,6 +10,8 @@ #include <math.h> #include <stddef.h> +#include <string> + #include "base/bind.h" #include "base/callback.h" #include "base/location.h" @@ -21,6 +23,7 @@ #include "net/base/io_buffer.h" #include "remoting/test/leaky_bucket.h" #include "third_party/webrtc/base/asyncpacketsocket.h" +#include "third_party/webrtc/base/socket.h" #include "third_party/webrtc/media/base/rtputils.h" namespace remoting { @@ -121,6 +124,10 @@ reinterpret_cast<uint8_t*>(buffer->data()), data_size, options.packet_time_params, (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds()); + SignalSentPacket( + this, rtc::SentPacket(options.packet_id, (base::TimeTicks::Now() - + base::TimeTicks::UnixEpoch()) + .InMilliseconds())); dispatcher_->DeliverPacket(local_address_, address, buffer, data_size); return data_size; }
diff --git a/remoting/tools/build/remoting_copy_locales.py b/remoting/tools/build/remoting_copy_locales.py index 4d1d41a..255a7ef 100755 --- a/remoting/tools/build/remoting_copy_locales.py +++ b/remoting/tools/build/remoting_copy_locales.py
@@ -14,8 +14,10 @@ import os import sys -sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', - 'tools', 'grit')) +# Prepend the grit module from the source tree so it takes precedence over other +# grit versions that might present in the search path. +sys.path.insert(1, os.path.join(os.path.dirname(__file__), '..', '..', '..', + 'tools', 'grit')) from grit.format import data_pack # Some build paths defined by gyp.
diff --git a/remoting/tools/build/remoting_ios_localize.py b/remoting/tools/build/remoting_ios_localize.py index 04beb18..bc4ddc4 100755 --- a/remoting/tools/build/remoting_ios_localize.py +++ b/remoting/tools/build/remoting_ios_localize.py
@@ -76,8 +76,10 @@ import re import sys -sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', - 'tools', 'grit')) +# Prepend the grit module from the source tree so it takes precedence over other +# grit versions that might present in the search path. +sys.path.insert(1, os.path.join(os.path.dirname(__file__), '..', '..', '..', + 'tools', 'grit')) from grit.format import data_pack sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..',
diff --git a/sandbox/mac/os_compatibility.cc b/sandbox/mac/os_compatibility.cc index 0e8d08f5..dce874c 100644 --- a/sandbox/mac/os_compatibility.cc +++ b/sandbox/mac/os_compatibility.cc
@@ -96,7 +96,7 @@ void WriteServiceLookUpReply(IPCMessage message, mach_port_t service_port) override { - auto reply = reinterpret_cast<look_up2_reply_10_7*>(message.mach); + auto* reply = reinterpret_cast<look_up2_reply_10_7*>(message.mach); reply->Head.msgh_size = sizeof(*reply); reply->Head.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_MOVE_SEND_ONCE) | @@ -108,7 +108,7 @@ } bool IsSwapIntegerReadOnly(const IPCMessage message) override { - auto request = + auto* request = reinterpret_cast<const swap_integer_request_10_7*>(message.mach); return request->inkey == 0 && request->inval == 0 && request->outkey != 0; }
diff --git a/sandbox/win/src/broker_services.cc b/sandbox/win/src/broker_services.cc index 64a0afeca..b33889d 100644 --- a/sandbox/win/src/broker_services.cc +++ b/sandbox/win/src/broker_services.cc
@@ -136,7 +136,7 @@ return; } - STLDeleteElements(&tracker_list_); + base::STLDeleteElements(&tracker_list_); delete thread_pool_; ::DeleteCriticalSection(&lock_);
diff --git a/sandbox/win/src/handle_closer_agent.cc b/sandbox/win/src/handle_closer_agent.cc index 6b17f65..c18fef4e 100644 --- a/sandbox/win/src/handle_closer_agent.cc +++ b/sandbox/win/src/handle_closer_agent.cc
@@ -82,7 +82,7 @@ reinterpret_cast<uintptr_t>(dup_dummy) < reinterpret_cast<uintptr_t>(closed_handle)); - for (auto h : to_close) + for (HANDLE h : to_close) ::CloseHandle(h); // Useful to know when we're not able to stuff handles.
diff --git a/sandbox/win/src/handle_closer_test.cc b/sandbox/win/src/handle_closer_test.cc index ceba818..1e0ab49 100644 --- a/sandbox/win/src/handle_closer_test.cc +++ b/sandbox/win/src/handle_closer_test.cc
@@ -145,7 +145,7 @@ return SBOX_TEST_SUCCEEDED; case AFTER_REVERT: - for (auto handle : to_check) { + for (HANDLE handle : to_check) { // Set up buffers for the type info and the name. std::vector<BYTE> type_info_buffer(sizeof(OBJECT_TYPE_INFORMATION) + 32 * sizeof(wchar_t));
diff --git a/sandbox/win/src/process_mitigations_test.cc b/sandbox/win/src/process_mitigations_test.cc index bf89a9a..d546bbf 100644 --- a/sandbox/win/src/process_mitigations_test.cc +++ b/sandbox/win/src/process_mitigations_test.cc
@@ -393,7 +393,7 @@ ADD_FAILURE(); all_good = false; } else { - for (auto module : modules) { + for (HMODULE module : modules) { wchar_t name[MAX_PATH] = {}; if (::GetModuleFileNameExW(proc_info.hProcess, module, name, MAX_PATH) &&
diff --git a/sandbox/win/src/sharedmem_ipc_server.cc b/sandbox/win/src/sharedmem_ipc_server.cc index 672abfac..fbe85f1 100644 --- a/sandbox/win/src/sharedmem_ipc_server.cc +++ b/sandbox/win/src/sharedmem_ipc_server.cc
@@ -60,7 +60,7 @@ // Better to leak than to crash. return; } - STLDeleteElements(&server_contexts_); + base::STLDeleteElements(&server_contexts_); if (client_control_) ::UnmapViewOfFile(client_control_);
diff --git a/services/catalog/entry.cc b/services/catalog/entry.cc index 26c266b..6d8acdd 100644 --- a/services/catalog/entry.cc +++ b/services/catalog/entry.cc
@@ -278,8 +278,7 @@ const catalog::Entry& package = input.package() ? *input.package() : input; result->resolved_name = package.name(); result->qualifier = input.qualifier(); - result->capabilities = - shell::mojom::CapabilitySpec::From(input.capabilities()); + result->capabilities = input.capabilities(); result->package_path = package.path(); return result; }
diff --git a/services/catalog/entry.h b/services/catalog/entry.h index 74c3022..8067b85 100644 --- a/services/catalog/entry.h +++ b/services/catalog/entry.h
@@ -12,6 +12,7 @@ #include "base/files/file_path.h" #include "services/catalog/public/interfaces/catalog.mojom.h" #include "services/shell/public/cpp/capabilities.h" +#include "services/shell/public/interfaces/resolver.mojom.h" namespace base { class DictionaryValue;
diff --git a/services/catalog/instance.cc b/services/catalog/instance.cc index da9cb7f7..c22fc612 100644 --- a/services/catalog/instance.cc +++ b/services/catalog/instance.cc
@@ -14,7 +14,7 @@ namespace catalog { namespace { -void AddEntry(const Entry& entry, mojo::Array<mojom::EntryPtr>* ary) { +void AddEntry(const Entry& entry, std::vector<mojom::EntryPtr>* ary) { mojom::EntryPtr entry_ptr(mojom::Entry::New()); entry_ptr->name = entry.name(); entry_ptr->display_name = entry.display_name(); @@ -58,14 +58,17 @@ //////////////////////////////////////////////////////////////////////////////// // Instance, shell::mojom::Resolver: -void Instance::ResolveMojoName(const mojo::String& mojo_name, +void Instance::ResolveMojoName(const std::string& mojo_name, const ResolveMojoNameCallback& callback) { DCHECK(system_cache_); std::string type = shell::GetNameType(mojo_name); if (type != shell::kNameType_Mojo && type != shell::kNameType_Exe) { std::unique_ptr<Entry> entry(new Entry(mojo_name)); - callback.Run(shell::mojom::ResolveResult::From(*entry)); + shell::mojom::ResolveResultPtr result = + shell::mojom::ResolveResult::From(*entry); + result->capabilities = base::nullopt; + callback.Run(std::move(result)); return; } @@ -87,18 +90,17 @@ //////////////////////////////////////////////////////////////////////////////// // Instance, mojom::Catalog: -void Instance::GetEntries(mojo::Array<mojo::String> names, +void Instance::GetEntries(const base::Optional<std::vector<std::string>>& names, const GetEntriesCallback& callback) { DCHECK(system_cache_); - mojo::Array<mojom::EntryPtr> entries; - if (names.is_null()) { + std::vector<mojom::EntryPtr> entries; + if (!names.has_value()) { // TODO(beng): user catalog. for (const auto& entry : *system_cache_) AddEntry(*entry.second, &entries); } else { - std::vector<mojo::String> names_vec = names.PassStorage(); - for (const std::string& name : names_vec) { + for (const std::string& name : names.value()) { Entry* entry = nullptr; // TODO(beng): user catalog. if (system_cache_->find(name) != system_cache_->end()) @@ -112,9 +114,9 @@ } void Instance::GetEntriesProvidingClass( - const mojo::String& clazz, + const std::string& clazz, const GetEntriesProvidingClassCallback& callback) { - mojo::Array<mojom::EntryPtr> entries; + std::vector<mojom::EntryPtr> entries; for (const auto& entry : *system_cache_) if (entry.second->ProvidesClass(clazz)) entries.push_back(mojom::Entry::From(*entry.second)); @@ -122,13 +124,13 @@ } void Instance::GetEntriesConsumingMIMEType( - const mojo::String& mime_type, + const std::string& mime_type, const GetEntriesConsumingMIMETypeCallback& callback) { // TODO(beng): implement. } void Instance::GetEntriesSupportingScheme( - const mojo::String& scheme, + const std::string& scheme, const GetEntriesSupportingSchemeCallback& callback) { // TODO(beng): implement. }
diff --git a/services/catalog/instance.h b/services/catalog/instance.h index b9e1dfa0..0c82d47 100644 --- a/services/catalog/instance.h +++ b/services/catalog/instance.h
@@ -37,20 +37,20 @@ private: // shell::mojom::Resolver: - void ResolveMojoName(const mojo::String& mojo_name, + void ResolveMojoName(const std::string& mojo_name, const ResolveMojoNameCallback& callback) override; // mojom::Catalog: - void GetEntries(mojo::Array<mojo::String> names, + void GetEntries(const base::Optional<std::vector<std::string>>& names, const GetEntriesCallback& callback) override; void GetEntriesProvidingClass( - const mojo::String& clazz, + const std::string& clazz, const GetEntriesProvidingClassCallback& callback) override; void GetEntriesConsumingMIMEType( - const mojo::String& mime_type, + const std::string& mime_type, const GetEntriesConsumingMIMETypeCallback& callback) override; void GetEntriesSupportingScheme( - const mojo::String& scheme, + const std::string& scheme, const GetEntriesSupportingSchemeCallback& callback) override; // Populate/serialize the cache from/to the supplied store.
diff --git a/services/catalog/public/interfaces/BUILD.gn b/services/catalog/public/interfaces/BUILD.gn index d0ada79..77a6aaf1 100644 --- a/services/catalog/public/interfaces/BUILD.gn +++ b/services/catalog/public/interfaces/BUILD.gn
@@ -8,6 +8,4 @@ sources = [ "catalog.mojom", ] - - use_new_wrapper_types = false }
diff --git a/services/file/BUILD.gn b/services/file/BUILD.gn new file mode 100644 index 0000000..0db315f --- /dev/null +++ b/services/file/BUILD.gn
@@ -0,0 +1,41 @@ +# Copyright 2016 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("//services/shell/public/cpp/service.gni") +import("//services/shell/public/service_manifest.gni") + +source_set("lib") { + sources = [ + "file_service.cc", + "file_service.h", + "file_system.cc", + "file_system.h", + "user_id_map.cc", + "user_id_map.h", + ] + + deps = [ + "//base", + "//components/filesystem:lib", + "//components/filesystem/public/interfaces", + "//components/leveldb:lib", + "//components/leveldb/public/interfaces", + "//mojo/common", + "//mojo/common:common_base", + "//services/file/public/interfaces", + "//services/shell/public/cpp", + "//services/shell/public/interfaces", + "//services/tracing/public/cpp", + "//url", + ] + + data_deps = [ + ":manifest", + ] +} + +service_manifest("manifest") { + name = "file" + source = "manifest.json" +}
diff --git a/services/user/DEPS b/services/file/DEPS similarity index 100% rename from services/user/DEPS rename to services/file/DEPS
diff --git a/services/user/OWNERS b/services/file/OWNERS similarity index 100% rename from services/user/OWNERS rename to services/file/OWNERS
diff --git a/services/file/file_service.cc b/services/file/file_service.cc new file mode 100644 index 0000000..7a0c684 --- /dev/null +++ b/services/file/file_service.cc
@@ -0,0 +1,124 @@ +// Copyright 2016 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 "services/file/file_service.h" + +#include "base/bind.h" +#include "base/memory/ptr_util.h" +#include "base/memory/weak_ptr.h" +#include "components/filesystem/lock_table.h" +#include "components/leveldb/leveldb_service_impl.h" +#include "services/file/file_system.h" +#include "services/file/user_id_map.h" +#include "services/shell/public/cpp/connection.h" + +namespace file { + +class FileService::FileSystemObjects + : public base::SupportsWeakPtr<FileSystemObjects> { + public: + // Created on the main thread. + FileSystemObjects(base::FilePath user_dir) : user_dir_(user_dir) {} + + // Destroyed on the |file_service_runner_|. + ~FileSystemObjects() {} + + // Called on the |file_service_runner_|. + void OnFileSystemRequest(const shell::Identity& remote_identity, + mojom::FileSystemRequest request) { + if (!lock_table_) + lock_table_ = new filesystem::LockTable; + file_system_bindings_.AddBinding(new FileSystem(user_dir_, lock_table_), + std::move(request)); + } + + private: + mojo::BindingSet<mojom::FileSystem> file_system_bindings_; + scoped_refptr<filesystem::LockTable> lock_table_; + base::FilePath user_dir_; + + DISALLOW_COPY_AND_ASSIGN(FileSystemObjects); +}; + +class FileService::LevelDBServiceObjects + : public base::SupportsWeakPtr<LevelDBServiceObjects> { + public: + // Created on the main thread. + LevelDBServiceObjects(scoped_refptr<base::SingleThreadTaskRunner> task_runner) + : task_runner_(std::move(task_runner)) {} + + // Destroyed on the |leveldb_service_runner_|. + ~LevelDBServiceObjects() {} + + // Called on the |leveldb_service_runner_|. + void OnLevelDBServiceRequest(const shell::Identity& remote_identity, + leveldb::mojom::LevelDBServiceRequest request) { + if (!leveldb_service_) + leveldb_service_.reset(new leveldb::LevelDBServiceImpl(task_runner_)); + leveldb_bindings_.AddBinding(leveldb_service_.get(), std::move(request)); + } + + private: + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + + // Variables that are only accessible on the |leveldb_service_runner_| thread. + std::unique_ptr<leveldb::mojom::LevelDBService> leveldb_service_; + mojo::BindingSet<leveldb::mojom::LevelDBService> leveldb_bindings_; + + DISALLOW_COPY_AND_ASSIGN(LevelDBServiceObjects); +}; + +std::unique_ptr<shell::Service> CreateFileService( + scoped_refptr<base::SingleThreadTaskRunner> file_service_runner, + scoped_refptr<base::SingleThreadTaskRunner> leveldb_service_runner, + const base::Closure& quit_closure) { + return base::WrapUnique(new FileService( + std::move(file_service_runner), std::move(leveldb_service_runner))); +} + +FileService::FileService( + scoped_refptr<base::SingleThreadTaskRunner> file_service_runner, + scoped_refptr<base::SingleThreadTaskRunner> leveldb_service_runner) + : file_service_runner_(std::move(file_service_runner)), + leveldb_service_runner_(std::move(leveldb_service_runner)) {} + +FileService::~FileService() { + file_service_runner_->DeleteSoon(FROM_HERE, file_system_objects_.release()); + leveldb_service_runner_->DeleteSoon(FROM_HERE, leveldb_objects_.release()); +} + +void FileService::OnStart(const shell::Identity& identity) { + file_system_objects_.reset(new FileService::FileSystemObjects( + GetUserDirForUserId(identity.user_id()))); + leveldb_objects_.reset( + new FileService::LevelDBServiceObjects(leveldb_service_runner_)); +} + +bool FileService::OnConnect(const shell::Identity& remote_identity, + shell::InterfaceRegistry* registry) { + registry->AddInterface<leveldb::mojom::LevelDBService>(this); + registry->AddInterface<mojom::FileSystem>(this); + return true; +} + +void FileService::Create(const shell::Identity& remote_identity, + mojom::FileSystemRequest request) { + file_service_runner_->PostTask( + FROM_HERE, + base::Bind(&FileService::FileSystemObjects::OnFileSystemRequest, + file_system_objects_->AsWeakPtr(), remote_identity, + base::Passed(&request))); +} + +void FileService::Create(const shell::Identity& remote_identity, + leveldb::mojom::LevelDBServiceRequest request) { + leveldb_service_runner_->PostTask( + FROM_HERE, + base::Bind( + &FileService::LevelDBServiceObjects::OnLevelDBServiceRequest, + leveldb_objects_->AsWeakPtr(), remote_identity, + base::Passed(&request))); +} + +} // namespace user_service
diff --git a/services/file/file_service.h b/services/file/file_service.h new file mode 100644 index 0000000..9a8c78d --- /dev/null +++ b/services/file/file_service.h
@@ -0,0 +1,66 @@ +// Copyright 2016 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 SERVICES_FILE_FILE_SERVICE_H_ +#define SERVICES_FILE_FILE_SERVICE_H_ + +#include "base/callback_forward.h" +#include "base/memory/ref_counted.h" +#include "components/filesystem/lock_table.h" +#include "components/leveldb/public/interfaces/leveldb.mojom.h" +#include "mojo/public/cpp/bindings/binding_set.h" +#include "services/file/public/interfaces/file_system.mojom.h" +#include "services/shell/public/cpp/interface_factory.h" +#include "services/shell/public/cpp/service.h" + +namespace file { + +std::unique_ptr<shell::Service> CreateFileService( + scoped_refptr<base::SingleThreadTaskRunner> file_service_runner, + scoped_refptr<base::SingleThreadTaskRunner> leveldb_service_runner, + const base::Closure& quit_closure); + +class FileService + : public shell::Service, + public shell::InterfaceFactory<mojom::FileSystem>, + public shell::InterfaceFactory<leveldb::mojom::LevelDBService> { + public: + FileService( + scoped_refptr<base::SingleThreadTaskRunner> file_service_runner, + scoped_refptr<base::SingleThreadTaskRunner> leveldb_service_runner); + ~FileService() override; + + private: + // |Service| override: + void OnStart(const shell::Identity& identity) override; + bool OnConnect(const shell::Identity& remote_identity, + shell::InterfaceRegistry* registry) override; + + // |InterfaceFactory<mojom::FileSystem>| implementation: + void Create(const shell::Identity& remote_identity, + mojom::FileSystemRequest request) override; + + // |InterfaceFactory<LevelDBService>| implementation: + void Create(const shell::Identity& remote_identity, + leveldb::mojom::LevelDBServiceRequest request) override; + + void OnLevelDBServiceError(); + + scoped_refptr<base::SingleThreadTaskRunner> file_service_runner_; + scoped_refptr<base::SingleThreadTaskRunner> leveldb_service_runner_; + + // We create these two objects so we can delete them on the correct task + // runners. + class FileSystemObjects; + std::unique_ptr<FileSystemObjects> file_system_objects_; + + class LevelDBServiceObjects; + std::unique_ptr<LevelDBServiceObjects> leveldb_objects_; + + DISALLOW_COPY_AND_ASSIGN(FileService); +}; + +} // namespace file + +#endif // SERVICES_FILE_FILE_SERVICE_H_
diff --git a/services/file/file_system.cc b/services/file/file_system.cc new file mode 100644 index 0000000..17e5f80 --- /dev/null +++ b/services/file/file_system.cc
@@ -0,0 +1,57 @@ +// Copyright 2016 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 "services/file/file_system.h" + +#include "base/files/file.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" +#include "base/strings/utf_string_conversions.h" +#include "components/filesystem/directory_impl.h" +#include "components/filesystem/lock_table.h" +#include "components/filesystem/public/interfaces/types.mojom.h" +#include "services/shell/public/cpp/connection.h" + +namespace file { + +FileSystem::FileSystem(const base::FilePath& base_user_dir, + const scoped_refptr<filesystem::LockTable>& lock_table) + : lock_table_(lock_table), path_(base_user_dir) { + base::CreateDirectory(path_); +} + +FileSystem::~FileSystem() {} + +void FileSystem::GetDirectory(filesystem::mojom::DirectoryRequest request, + const GetDirectoryCallback& callback) { + new filesystem::DirectoryImpl(std::move(request), path_, + scoped_refptr<filesystem::SharedTempDir>(), + lock_table_); + callback.Run(); +} + +void FileSystem::GetSubDirectory(const std::string& sub_directory_path, + filesystem::mojom::DirectoryRequest request, + const GetSubDirectoryCallback& callback) { + // Ensure that we've made |subdirectory| recursively under our user dir. + base::FilePath subdir = path_.Append( +#if defined(OS_WIN) + base::UTF8ToWide(sub_directory_path)); +#else + sub_directory_path); +#endif + base::File::Error error; + if (!base::CreateDirectoryAndGetError(subdir, &error)) { + callback.Run(static_cast<filesystem::mojom::FileError>(error)); + return; + } + + new filesystem::DirectoryImpl(std::move(request), subdir, + scoped_refptr<filesystem::SharedTempDir>(), + lock_table_); + callback.Run(filesystem::mojom::FileError::OK); +} + +} // namespace file
diff --git a/services/file/file_system.h b/services/file/file_system.h new file mode 100644 index 0000000..3ecc0df --- /dev/null +++ b/services/file/file_system.h
@@ -0,0 +1,44 @@ +// Copyright 2016 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 SERVICES_FILE_FILE_SYSTEM_H_ +#define SERVICES_FILE_FILE_SYSTEM_H_ + +#include "base/files/file_path.h" +#include "components/filesystem/public/interfaces/directory.mojom.h" +#include "mojo/public/cpp/bindings/interface_request.h" +#include "mojo/public/cpp/bindings/strong_binding.h" +#include "services/file/public/interfaces/file_system.mojom.h" +#include "services/shell/public/cpp/connection.h" + +namespace filesystem { +class LockTable; +} + +namespace file { + +// A service which serves directories to callers. +class FileSystem : public mojom::FileSystem { + public: + FileSystem(const base::FilePath& base_user_dir, + const scoped_refptr<filesystem::LockTable>& lock_table); + ~FileSystem() override; + + // Overridden from mojom::FileSystem: + void GetDirectory(filesystem::mojom::DirectoryRequest request, + const GetDirectoryCallback& callback) override; + void GetSubDirectory(const std::string& sub_directory_path, + filesystem::mojom::DirectoryRequest request, + const GetSubDirectoryCallback& callback) override; + + private: + scoped_refptr<filesystem::LockTable> lock_table_; + base::FilePath path_; + + DISALLOW_COPY_AND_ASSIGN(FileSystem); +}; + +} // namespace file + +#endif // SERVICES_FILE_FILE_SYSTEM_H_
diff --git a/services/file/manifest.json b/services/file/manifest.json new file mode 100644 index 0000000..824377cf --- /dev/null +++ b/services/file/manifest.json
@@ -0,0 +1,11 @@ +{ + "manifest_version": 1, + "name": "mojo:file", + "process-group": "browser", + "display_name": "File Service", + "capabilities": { + "required": { + "*": { "classes": [ "app" ] } + } + } +}
diff --git a/services/user/public/cpp/BUILD.gn b/services/file/public/cpp/BUILD.gn similarity index 100% rename from services/user/public/cpp/BUILD.gn rename to services/file/public/cpp/BUILD.gn
diff --git a/services/file/public/cpp/constants.cc b/services/file/public/cpp/constants.cc new file mode 100644 index 0000000..8d8af2f --- /dev/null +++ b/services/file/public/cpp/constants.cc
@@ -0,0 +1,11 @@ +// Copyright 2016 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 "services/file/public/cpp/constants.h" + +namespace file { + +const char kFileServiceName[] = "mojo:file"; + +} // namespace file
diff --git a/services/file/public/cpp/constants.h b/services/file/public/cpp/constants.h new file mode 100644 index 0000000..e40a826 --- /dev/null +++ b/services/file/public/cpp/constants.h
@@ -0,0 +1,14 @@ +// Copyright 2016 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 SERVICES_FILE_PUBLIC_CPP_CONSTANTS_H_ +#define SERVICES_FILE_PUBLIC_CPP_CONSTANTS_H_ + +namespace file { + +extern const char kFileServiceName[]; + +} // namespace file + +#endif // SERVICES_FILE_PUBLIC_CPP_CONSTANTS_H_
diff --git a/services/file/public/interfaces/BUILD.gn b/services/file/public/interfaces/BUILD.gn new file mode 100644 index 0000000..8d8e767a --- /dev/null +++ b/services/file/public/interfaces/BUILD.gn
@@ -0,0 +1,15 @@ +# Copyright 2016 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("//mojo/public/tools/bindings/mojom.gni") + +mojom("interfaces") { + sources = [ + "file_system.mojom", + ] + + deps = [ + "//components/filesystem/public/interfaces", + ] +}
diff --git a/services/user/public/interfaces/OWNERS b/services/file/public/interfaces/OWNERS similarity index 100% rename from services/user/public/interfaces/OWNERS rename to services/file/public/interfaces/OWNERS
diff --git a/services/file/public/interfaces/file_system.mojom b/services/file/public/interfaces/file_system.mojom new file mode 100644 index 0000000..c3a422d --- /dev/null +++ b/services/file/public/interfaces/file_system.mojom
@@ -0,0 +1,19 @@ +// Copyright 2016 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 file.mojom; + +import "components/filesystem/public/interfaces/directory.mojom"; +import "components/filesystem/public/interfaces/types.mojom"; + +// Provide access to various directories within the requesting user's directory. +interface FileSystem { + // Returns the user's directory. + GetDirectory(filesystem.mojom.Directory& dir) => (); + + // Returns a subdirectory under the user's dir. Returns a filesystem error + // when we fail to create the subdirectory. + GetSubDirectory(string dir_path, filesystem.mojom.Directory& dir) + => (filesystem.mojom.FileError err); +};
diff --git a/services/file/user_id_map.cc b/services/file/user_id_map.cc new file mode 100644 index 0000000..1df31cf0 --- /dev/null +++ b/services/file/user_id_map.cc
@@ -0,0 +1,35 @@ +// Copyright 2016 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 "services/file/user_id_map.h" + +#include <map> + +#include "base/lazy_instance.h" + +namespace file { + +namespace { +base::LazyInstance<std::map<std::string, base::FilePath>> + g_user_id_to_data_dir = LAZY_INSTANCE_INITIALIZER; +} // namespace + +void AssociateShellUserIdWithUserDir(const std::string& user_id, + const base::FilePath& user_dir) { + g_user_id_to_data_dir.Get()[user_id] = user_dir; +} + +void ForgetShellUserIdUserDirAssociation(const std::string& user_id) { + auto it = g_user_id_to_data_dir.Get().find(user_id); + if (it != g_user_id_to_data_dir.Get().end()) + g_user_id_to_data_dir.Get().erase(it); +} + +base::FilePath GetUserDirForUserId(const std::string& user_id) { + auto it = g_user_id_to_data_dir.Get().find(user_id); + DCHECK(it != g_user_id_to_data_dir.Get().end()); + return it->second; +} + +} // namespace file
diff --git a/services/file/user_id_map.h b/services/file/user_id_map.h new file mode 100644 index 0000000..9703bd4 --- /dev/null +++ b/services/file/user_id_map.h
@@ -0,0 +1,23 @@ +// Copyright 2016 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 SERVICES_FILE_USER_ID_MAP_H_ +#define SERVICES_FILE_USER_ID_MAP_H_ + +#include <string> +#include "base/files/file_path.h" + +namespace file { + +// These methods are called from BrowserContext::Initialize() to associate +// the BrowserContext's shell user-id with its user directory. +void AssociateShellUserIdWithUserDir(const std::string& user_id, + const base::FilePath& user_dir); +void ForgetShellUserIdUserDirAssociation(const std::string& user_id); + +base::FilePath GetUserDirForUserId(const std::string& user_id); + +} // namespace file + +#endif // SERVICES_FILE_USER_ID_MAP_H_
diff --git a/services/shell/public/cpp/BUILD.gn b/services/shell/public/cpp/BUILD.gn index 3aa52698..f415b8a 100644 --- a/services/shell/public/cpp/BUILD.gn +++ b/services/shell/public/cpp/BUILD.gn
@@ -55,7 +55,9 @@ } if (!is_ios) { - static_library("application_support") { + # This cannot be a static library because it needs to export the symbols from + # initialize_base_and_icu.cc. + source_set("application_support") { sources = [ "lib/init_commandline.cc", "lib/initialize_base_and_icu.cc",
diff --git a/services/shell/public/cpp/OWNERS b/services/shell/public/cpp/OWNERS new file mode 100644 index 0000000..bb65116 --- /dev/null +++ b/services/shell/public/cpp/OWNERS
@@ -0,0 +1,2 @@ +per-file *_struct_traits*.*=set noparent +per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/services/shell/public/cpp/capabilities.h b/services/shell/public/cpp/capabilities.h index 9c76a96..e02c44f 100644 --- a/services/shell/public/cpp/capabilities.h +++ b/services/shell/public/cpp/capabilities.h
@@ -9,8 +9,6 @@ #include <set> #include <string> -#include "services/shell/public/interfaces/resolver.mojom.h" - namespace shell { using Class = std::string; @@ -44,34 +42,4 @@ } // namespace shell -namespace mojo { - -template <> -struct TypeConverter<shell::mojom::CapabilitySpecPtr, shell::CapabilitySpec> { - static shell::mojom::CapabilitySpecPtr Convert( - const shell::CapabilitySpec& input); -}; - -template <> -struct TypeConverter<shell::CapabilitySpec, shell::mojom::CapabilitySpecPtr> { - static shell::CapabilitySpec Convert( - const shell::mojom::CapabilitySpecPtr& input); -}; - -template <> -struct TypeConverter<shell::mojom::CapabilityRequestPtr, - shell::CapabilityRequest> { - static shell::mojom::CapabilityRequestPtr Convert( - const shell::CapabilityRequest& input); -}; - -template <> -struct TypeConverter<shell::CapabilityRequest, - shell::mojom::CapabilityRequestPtr> { - static shell::CapabilityRequest Convert( - const shell::mojom::CapabilityRequestPtr& input); -}; - -} // namespace mojo - #endif // SERVICES_SHELL_PUBLIC_CPP_CAPABILITIES_H_
diff --git a/services/shell/public/cpp/capabilities.typemap b/services/shell/public/cpp/capabilities.typemap new file mode 100644 index 0000000..95ddd90e --- /dev/null +++ b/services/shell/public/cpp/capabilities.typemap
@@ -0,0 +1,12 @@ +# Copyright 2016 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. + +mojom = "//services/shell/public/interfaces/capabilities.mojom" +public_headers = [ "//services/shell/public/cpp/capabilities.h" ] +traits_headers = [ "//services/shell/public/cpp/capabilities_struct_traits.h" ] + +type_mappings = [ + "shell.mojom.CapabilityRequest=::shell::CapabilityRequest", + "shell.mojom.CapabilitySpec=::shell::CapabilitySpec", +]
diff --git a/services/shell/public/cpp/capabilities_struct_traits.h b/services/shell/public/cpp/capabilities_struct_traits.h new file mode 100644 index 0000000..5356289 --- /dev/null +++ b/services/shell/public/cpp/capabilities_struct_traits.h
@@ -0,0 +1,83 @@ +// Copyright 2016 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 SERVICES_SHELL_PUBLIC_CPP_CAPABILITIES_STRUCT_TRAITS_H_ +#define SERVICES_SHELL_PUBLIC_CPP_CAPABILITIES_STRUCT_TRAITS_H_ + +#include "services/shell/public/cpp/capabilities.h" +#include "services/shell/public/interfaces/capabilities.mojom.h" + +namespace mojo { + +template <> +struct StructTraits<shell::mojom::CapabilityRequest, shell::CapabilityRequest> { + static const shell::Classes& classes( + const shell::CapabilityRequest& request) { + return request.classes; + } + static const shell::Interfaces& interfaces( + const shell::CapabilityRequest& request) { + return request.interfaces; + } + static bool Read(shell::mojom::CapabilityRequestDataView data, + shell::CapabilityRequest* out) { + ArrayDataView<StringDataView> classes_data_view; + data.GetClassesDataView(&classes_data_view); + for (size_t i = 0; i < classes_data_view.size(); ++i) { + std::string clazz; + if (!classes_data_view.Read(i, &clazz)) + return false; + out->classes.insert(std::move(clazz)); + } + + ArrayDataView<StringDataView> interfaces_data_view; + data.GetInterfacesDataView(&interfaces_data_view); + for (size_t i = 0; i < interfaces_data_view.size(); ++i) { + std::string interface; + if (!interfaces_data_view.Read(i, &interface)) + return false; + out->interfaces.insert(std::move(interface)); + } + return true; + } +}; + +template <> +struct StructTraits<shell::mojom::CapabilitySpec, shell::CapabilitySpec> { + static const std::map<shell::Class, shell::Interfaces>& provided( + const shell::CapabilitySpec& spec) { + return spec.provided; + } + static const std::map<shell::Name, shell::CapabilityRequest>& required( + const shell::CapabilitySpec& spec) { + return spec.required; + } + static bool Read(shell::mojom::CapabilitySpecDataView data, + shell::CapabilitySpec* out) { + MapDataView<StringDataView, ArrayDataView<StringDataView>> + provided_data_view; + data.GetProvidedDataView(&provided_data_view); + + for (size_t i = 0; i < provided_data_view.keys().size(); ++i) { + std::string clazz; + if (!provided_data_view.keys().Read(i, &clazz)) + return false; + + std::vector<std::string> interfaces_vec; + if (!provided_data_view.values().Read(i, &interfaces_vec)) + return false; + std::set<std::string> interfaces; + for (const auto& interface : interfaces_vec) + interfaces.insert(interface); + + out->provided[clazz] = std::move(interfaces); + } + + return data.ReadRequired(&out->required); + } +}; + +} // namespace mojo + +#endif // SERVICES_SHELL_PUBLIC_CPP_CAPABILITIES_STRUCT_TRAITS_H_
diff --git a/services/shell/public/cpp/connection.h b/services/shell/public/cpp/connection.h index 1035eb6..7dea805 100644 --- a/services/shell/public/cpp/connection.h +++ b/services/shell/public/cpp/connection.h
@@ -8,6 +8,7 @@ #include "base/memory/weak_ptr.h" #include "services/shell/public/cpp/identity.h" #include "services/shell/public/cpp/interface_provider.h" +#include "services/shell/public/interfaces/connector.mojom.h" namespace shell {
diff --git a/services/shell/public/cpp/identity.h b/services/shell/public/cpp/identity.h index 3c2cb0b..086b224 100644 --- a/services/shell/public/cpp/identity.h +++ b/services/shell/public/cpp/identity.h
@@ -7,8 +7,6 @@ #include <string> -#include "services/shell/public/interfaces/connector.mojom.h" - namespace shell { // Represents the identity of an application. @@ -43,18 +41,4 @@ } // namespace shell -namespace mojo { - -template <> -struct TypeConverter<shell::mojom::IdentityPtr, shell::Identity> { - static shell::mojom::IdentityPtr Convert(const shell::Identity& input); -}; - -template <> -struct TypeConverter<shell::Identity, shell::mojom::IdentityPtr> { - static shell::Identity Convert(const shell::mojom::IdentityPtr& input); -}; - -} // namespace mojo - #endif // SERVICES_SHELL_PUBLIC_CPP_IDENTITY_H_
diff --git a/services/shell/public/cpp/identity.typemap b/services/shell/public/cpp/identity.typemap new file mode 100644 index 0000000..dd5c0d8 --- /dev/null +++ b/services/shell/public/cpp/identity.typemap
@@ -0,0 +1,9 @@ +# Copyright 2016 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. + +mojom = "//services/shell/public/interfaces/connector.mojom" +public_headers = [ "//services/shell/public/cpp/identity.h" ] +traits_headers = [ "//services/shell/public/cpp/identity_struct_traits.h" ] + +type_mappings = [ "shell.mojom.Identity=::shell::Identity" ]
diff --git a/services/shell/public/cpp/identity_struct_traits.h b/services/shell/public/cpp/identity_struct_traits.h new file mode 100644 index 0000000..86ccc66 --- /dev/null +++ b/services/shell/public/cpp/identity_struct_traits.h
@@ -0,0 +1,42 @@ +// Copyright 2016 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 SERVICES_SHELL_PUBLIC_CPP_IDENTITY_STRUCT_TRAITS_H_ +#define SERVICES_SHELL_PUBLIC_CPP_IDENTITY_STRUCT_TRAITS_H_ + +#include "services/shell/public/cpp/identity.h" +#include "services/shell/public/interfaces/connector.mojom.h" + +namespace mojo { + +template <> +struct StructTraits<shell::mojom::Identity, shell::Identity> { + static const std::string& name(const shell::Identity& identity) { + return identity.name(); + } + static const std::string& user_id(const shell::Identity& identity) { + return identity.user_id(); + } + static const std::string& instance(const shell::Identity& identity) { + return identity.instance(); + } + static bool Read(shell::mojom::IdentityDataView data, shell::Identity* out) { + std::string name, user_id, instance; + if (!data.ReadName(&name)) + return false; + + if (!data.ReadUserId(&user_id)) + return false; + + if (!data.ReadInstance(&instance)) + return false; + + *out = shell::Identity(name, user_id, instance); + return true; + } +}; + +} // namespace mojo + +#endif // SERVICES_SHELL_PUBLIC_CPP_IDENTITY_STRUCT_TRAITS_H_
diff --git a/services/shell/public/cpp/interface_provider.h b/services/shell/public/cpp/interface_provider.h index 865ab8b..5cf1d95 100644 --- a/services/shell/public/cpp/interface_provider.h +++ b/services/shell/public/cpp/interface_provider.h
@@ -18,7 +18,7 @@ // Connection. class InterfaceProvider { public: - using ForwardCallback = base::Callback<void(const mojo::String&, + using ForwardCallback = base::Callback<void(const std::string&, mojo::ScopedMessagePipeHandle)>; class TestApi { public:
diff --git a/services/shell/public/cpp/interface_registry.h b/services/shell/public/cpp/interface_registry.h index e1cc51a..9f1051e0 100644 --- a/services/shell/public/cpp/interface_registry.h +++ b/services/shell/public/cpp/interface_registry.h
@@ -47,7 +47,7 @@ // class InterfaceRegistry : public mojom::InterfaceProvider { public: - using Binder = base::Callback<void(const mojo::String&, + using Binder = base::Callback<void(const std::string&, mojo::ScopedMessagePipeHandle)>; class TestApi { @@ -138,7 +138,7 @@ std::map<std::string, std::unique_ptr<InterfaceBinder>>; // mojom::InterfaceProvider: - void GetInterface(const mojo::String& interface_name, + void GetInterface(const std::string& interface_name, mojo::ScopedMessagePipeHandle handle) override; // Returns true if the binder was set, false if it was not set (e.g. by @@ -164,7 +164,7 @@ // Pending interface requests which can accumulate if GetInterface() is called // while binding is paused. - std::queue<std::pair<mojo::String, mojo::ScopedMessagePipeHandle>> + std::queue<std::pair<std::string, mojo::ScopedMessagePipeHandle>> pending_interface_requests_; base::WeakPtrFactory<InterfaceRegistry> weak_factory_;
diff --git a/services/shell/public/cpp/lib/capabilities.cc b/services/shell/public/cpp/lib/capabilities.cc index 51dcd0d..620feded 100644 --- a/services/shell/public/cpp/lib/capabilities.cc +++ b/services/shell/public/cpp/lib/capabilities.cc
@@ -4,6 +4,8 @@ #include "services/shell/public/cpp/capabilities.h" +#include <tuple> + namespace shell { CapabilityRequest::CapabilityRequest() {} @@ -33,53 +35,3 @@ } } // namespace shell - -namespace mojo { - -// static -shell::mojom::CapabilitySpecPtr -TypeConverter<shell::mojom::CapabilitySpecPtr, shell::CapabilitySpec>::Convert( - const shell::CapabilitySpec& input) { - shell::mojom::CapabilitySpecPtr spec(shell::mojom::CapabilitySpec::New()); - spec->provided = - mojo::Map<mojo::String, mojo::Array<mojo::String>>::From(input.provided); - spec->required = - mojo::Map<mojo::String, shell::mojom::CapabilityRequestPtr>::From( - input.required); - return spec; -} - -// static -shell::CapabilitySpec -TypeConverter<shell::CapabilitySpec, shell::mojom::CapabilitySpecPtr>::Convert( - const shell::mojom::CapabilitySpecPtr& input) { - shell::CapabilitySpec spec; - spec.provided = - input->provided.To<std::map<shell::Class, shell::Interfaces>>(); - spec.required = - input->required.To<std::map<shell::Name, shell::CapabilityRequest>>(); - return spec; -} - -// static -shell::mojom::CapabilityRequestPtr TypeConverter< - shell::mojom::CapabilityRequestPtr, - shell::CapabilityRequest>::Convert(const shell::CapabilityRequest& input) { - shell::mojom::CapabilityRequestPtr request( - shell::mojom::CapabilityRequest::New()); - request->classes = mojo::Array<mojo::String>::From(input.classes); - request->interfaces = mojo::Array<mojo::String>::From(input.interfaces); - return request; -} - -// static -shell::CapabilityRequest -TypeConverter<shell::CapabilityRequest, shell::mojom::CapabilityRequestPtr>:: - Convert(const shell::mojom::CapabilityRequestPtr& input) { - shell::CapabilityRequest request; - request.classes = input->classes.To<std::set<std::string>>(); - request.interfaces = input->interfaces.To<std::set<std::string>>(); - return request; -} - -} // namespace mojo
diff --git a/services/shell/public/cpp/lib/connection_impl.cc b/services/shell/public/cpp/lib/connection_impl.cc index 870727c..d699af7 100644 --- a/services/shell/public/cpp/lib/connection_impl.cc +++ b/services/shell/public/cpp/lib/connection_impl.cc
@@ -80,7 +80,7 @@ // ConnectionImpl, private: void ConnectionImpl::OnConnectionCompleted(shell::mojom::ConnectResult result, - mojo::String target_user_id) { + const std::string& target_user_id) { DCHECK(State::PENDING == state_); result_ = result;
diff --git a/services/shell/public/cpp/lib/connection_impl.h b/services/shell/public/cpp/lib/connection_impl.h index 363ef4f..ec205abd 100644 --- a/services/shell/public/cpp/lib/connection_impl.h +++ b/services/shell/public/cpp/lib/connection_impl.h
@@ -52,7 +52,7 @@ base::WeakPtr<Connection> GetWeakPtr() override; void OnConnectionCompleted(shell::mojom::ConnectResult result, - mojo::String target_user_id); + const std::string& target_user_id); Identity remote_;
diff --git a/services/shell/public/cpp/lib/connector_impl.cc b/services/shell/public/cpp/lib/connector_impl.cc index f464137..5be6b79 100644 --- a/services/shell/public/cpp/lib/connector_impl.cc +++ b/services/shell/public/cpp/lib/connector_impl.cc
@@ -78,8 +78,7 @@ << "both must be valid."; return std::move(connection); } - connector_->Connect(mojom::Identity::From(params->target()), - std::move(remote_request), + connector_->Connect(params->target(), std::move(remote_request), std::move(client_process_connection), connection->GetConnectCallback()); return std::move(connection);
diff --git a/services/shell/public/cpp/lib/identity.cc b/services/shell/public/cpp/lib/identity.cc index dc49424..5193207f 100644 --- a/services/shell/public/cpp/lib/identity.cc +++ b/services/shell/public/cpp/lib/identity.cc
@@ -41,25 +41,3 @@ } } // namespace shell - -namespace mojo { - -// static -shell::mojom::IdentityPtr -TypeConverter<shell::mojom::IdentityPtr, shell::Identity>::Convert( - const shell::Identity& input) { - shell::mojom::IdentityPtr identity(shell::mojom::Identity::New()); - identity->name = input.name(); - identity->user_id = input.user_id(); - identity->instance = input.instance(); - return identity; -} - -// static -shell::Identity -TypeConverter<shell::Identity, shell::mojom::IdentityPtr>::Convert( - const shell::mojom::IdentityPtr& input) { - return shell::Identity(input->name, input->user_id, input->instance); -} - -} // namespace mojo
diff --git a/services/shell/public/cpp/lib/initialize_base_and_icu.cc b/services/shell/public/cpp/lib/initialize_base_and_icu.cc index 7c50d49..6a7be7b1 100644 --- a/services/shell/public/cpp/lib/initialize_base_and_icu.cc +++ b/services/shell/public/cpp/lib/initialize_base_and_icu.cc
@@ -15,6 +15,7 @@ #include "base/i18n/icu_util.h" #include "base/rand_util.h" #include "base/sys_info.h" +#include "build/build_config.h" #include "mojo/public/c/system/types.h" #if !defined(OS_ANDROID) @@ -22,7 +23,7 @@ #endif extern "C" { -#if defined(WIN32) +#if defined(OS_WIN) __declspec(dllexport) void __cdecl #else void __attribute__((visibility("default")))
diff --git a/services/shell/public/cpp/lib/interface_registry.cc b/services/shell/public/cpp/lib/interface_registry.cc index 6a82a77..78ab5f8a 100644 --- a/services/shell/public/cpp/lib/interface_registry.cc +++ b/services/shell/public/cpp/lib/interface_registry.cc
@@ -78,7 +78,7 @@ } // mojom::InterfaceProvider: -void InterfaceRegistry::GetInterface(const mojo::String& interface_name, +void InterfaceRegistry::GetInterface(const std::string& interface_name, mojo::ScopedMessagePipeHandle handle) { if (is_paused_) { pending_interface_requests_.emplace(interface_name, std::move(handle));
diff --git a/services/shell/public/cpp/lib/service_context.cc b/services/shell/public/cpp/lib/service_context.cc index 92ee74fce0..939faba4 100644 --- a/services/shell/public/cpp/lib/service_context.cc +++ b/services/shell/public/cpp/lib/service_context.cc
@@ -47,9 +47,9 @@ //////////////////////////////////////////////////////////////////////////////// // ServiceContext, mojom::Service implementation: -void ServiceContext::OnStart(mojom::IdentityPtr identity, +void ServiceContext::OnStart(const shell::Identity& identity, const OnStartCallback& callback) { - identity_ = identity.To<Identity>(); + identity_ = identity; if (!initialize_handler_.is_null()) initialize_handler_.Run(); @@ -63,16 +63,14 @@ } void ServiceContext::OnConnect( - mojom::IdentityPtr source, + const Identity& source, mojom::InterfaceProviderRequest interfaces, - mojom::CapabilityRequestPtr allowed_capabilities) { - shell::Identity remote_identity = source.To<Identity>(); + const CapabilityRequest& allowed_capabilities) { std::unique_ptr<InterfaceRegistry> registry( - new InterfaceRegistry(remote_identity, - allowed_capabilities.To<CapabilityRequest>())); + new InterfaceRegistry(source, allowed_capabilities)); registry->Bind(std::move(interfaces)); - if (!service_->OnConnect(remote_identity, registry.get())) + if (!service_->OnConnect(source, registry.get())) return; // TODO(beng): it appears we never prune this list. We should, when the
diff --git a/services/shell/public/cpp/service_context.h b/services/shell/public/cpp/service_context.h index eec15ad..e162d02 100644 --- a/services/shell/public/cpp/service_context.h +++ b/services/shell/public/cpp/service_context.h
@@ -65,11 +65,11 @@ private: // mojom::Service: - void OnStart(mojom::IdentityPtr identity, + void OnStart(const Identity& identity, const OnStartCallback& callback) override; - void OnConnect(mojom::IdentityPtr source, + void OnConnect(const Identity& source, mojom::InterfaceProviderRequest interfaces, - mojom::CapabilityRequestPtr allowed_capabilities) override; + const CapabilityRequest& allowed_capabilities) override; void OnConnectionError();
diff --git a/services/shell/public/cpp/typemaps.gni b/services/shell/public/cpp/typemaps.gni new file mode 100644 index 0000000..3bc708c --- /dev/null +++ b/services/shell/public/cpp/typemaps.gni
@@ -0,0 +1,4 @@ +typemaps = [ + "//services/shell/public/cpp/capabilities.typemap", + "//services/shell/public/cpp/identity.typemap", +]
diff --git a/services/shell/public/interfaces/BUILD.gn b/services/shell/public/interfaces/BUILD.gn index c58e0d1..ceb90006 100644 --- a/services/shell/public/interfaces/BUILD.gn +++ b/services/shell/public/interfaces/BUILD.gn
@@ -19,6 +19,4 @@ public_deps = [ "//mojo/common:common_custom_types", ] - - use_new_wrapper_types = false }
diff --git a/services/shell/public/interfaces/resolver.mojom b/services/shell/public/interfaces/resolver.mojom index 3e85fcc..bee6c98 100644 --- a/services/shell/public/interfaces/resolver.mojom +++ b/services/shell/public/interfaces/resolver.mojom
@@ -23,7 +23,7 @@ string qualifier; // The set of capabilities provided and required by |name|. - CapabilitySpec capabilities; + CapabilitySpec? capabilities; // A path to the package file specified by |name|. mojo.common.mojom.FilePath package_path;
diff --git a/services/shell/public/java/BUILD.gn b/services/shell/public/java/BUILD.gn index 925916f..c5066c7 100644 --- a/services/shell/public/java/BUILD.gn +++ b/services/shell/public/java/BUILD.gn
@@ -4,16 +4,13 @@ import("//build/config/android/rules.gni") -android_library("application") { +android_library("shell_java") { java_files = [ - "src/org/chromium/mojo/application/ApplicationConnection.java", - "src/org/chromium/mojo/application/ApplicationDelegate.java", - "src/org/chromium/mojo/application/ApplicationImpl.java", - "src/org/chromium/mojo/application/ApplicationRunner.java", - "src/org/chromium/mojo/application/ServiceFactoryBinder.java", - "src/org/chromium/mojo/application/ShellHelper.java", + "src/org/chromium/services/shell/InterfaceFactory.java", + "src/org/chromium/services/shell/InterfaceRegistry.java", ] deps = [ + "//base:base_java", "//mojo/public/java:bindings", "//mojo/public/java:system", "//services/shell/public/interfaces:interfaces_java",
diff --git a/services/shell/public/java/src/org/chromium/mojo/application/ApplicationConnection.java b/services/shell/public/java/src/org/chromium/mojo/application/ApplicationConnection.java deleted file mode 100644 index 6b0e5487..0000000 --- a/services/shell/public/java/src/org/chromium/mojo/application/ApplicationConnection.java +++ /dev/null
@@ -1,107 +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.mojo.application; - -import org.chromium.mojo.bindings.Interface; -import org.chromium.mojo.system.MessagePipeHandle; -import org.chromium.mojo.system.MojoException; -import org.chromium.mojom.mojo.ServiceProvider; - -import java.io.Closeable; -import java.util.HashMap; -import java.util.Map; - -/** - * Represents a connection to another application. - */ -public class ApplicationConnection implements Closeable { - private final String mConnectionUrl; - private final ServiceProvider mExposedServices; - private final String mRequestorUrl; - private final ServiceProviderImpl mServiceProviderImpl; - - /** - * @param requestorUrl URL of the application requesting this connection. - * @param exposedServices ServiceProvider for services exposed by the remote application. - */ - public ApplicationConnection( - String requestorUrl, ServiceProvider exposedServices, String connectionUrl) { - mRequestorUrl = requestorUrl; - mExposedServices = exposedServices; - mConnectionUrl = connectionUrl; - mServiceProviderImpl = new ServiceProviderImpl(); - } - - /** - * @return URL of the application requesting this connection. - */ - public String getRequestorUrl() { - return mRequestorUrl; - } - - /** - * @return URL that was used by the source application to establish this connection. - */ - public String connectionUrl() { - return mConnectionUrl; - } - - /** - * @return ServiceProvider for services exposed by the remote application. - */ - public ServiceProvider getRemoteServiceProvider() { - return mExposedServices; - } - - /** - * Add a new service for this application. - * - * @param binder Handle to a ServiceFactoryBinder which contains a service implementation. - */ - public void addService(ServiceFactoryBinder<? extends Interface> binder) { - mServiceProviderImpl.addService(binder); - } - - /** - * @return ServiceProvider for this application. - */ - public ServiceProvider getLocalServiceProvider() { - return mServiceProviderImpl; - } - - @Override - public void close() { - mServiceProviderImpl.close(); - if (mExposedServices != null) { - mExposedServices.close(); - } - } -} - -class ServiceProviderImpl implements ServiceProvider { - private final Map<String, ServiceFactoryBinder<? extends Interface>> mNameToServiceMap = - new HashMap<String, ServiceFactoryBinder<? extends Interface>>(); - - ServiceProviderImpl() {} - - public void addService(ServiceFactoryBinder<? extends Interface> binder) { - mNameToServiceMap.put(binder.getInterfaceName(), binder); - } - - @Override - public void connectToService(String interfaceName, MessagePipeHandle pipe) { - if (mNameToServiceMap.containsKey(interfaceName)) { - mNameToServiceMap.get(interfaceName).bindNewInstanceToMessagePipe(pipe); - } else { - pipe.close(); - } - } - - @Override - public void close() {} - - @Override - public void onConnectionError(MojoException e) {} -} \ No newline at end of file
diff --git a/services/shell/public/java/src/org/chromium/mojo/application/ApplicationDelegate.java b/services/shell/public/java/src/org/chromium/mojo/application/ApplicationDelegate.java deleted file mode 100644 index 72b1c62..0000000 --- a/services/shell/public/java/src/org/chromium/mojo/application/ApplicationDelegate.java +++ /dev/null
@@ -1,37 +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.mojo.application; - -import org.chromium.mojom.mojo.Shell; - -/** - * Applications should implement this interface to control various behaviors of Mojo application - * interface. - */ -public interface ApplicationDelegate { - /** - * Called exactly once before any other method. - * - * @param shell A handle to the shell interface. - * @param args Arguments used for this application. - * @param url URL of this application. - */ - public void initialize(Shell shell, String[] args, String url); - - /** - * This method is used to configure what services a connection supports when being connected to. - * Return false to reject the connection entirely. - * - * @param connection A handle to the connection. - * @return If this application accepts any incoming connection. - */ - public boolean configureIncomingConnection(ApplicationConnection connection); - - /** - * Called before exiting. After returning from this call, the delegate cannot expect RunLoop to - * still be running. - */ - public void quit(); -}
diff --git a/services/shell/public/java/src/org/chromium/mojo/application/ApplicationImpl.java b/services/shell/public/java/src/org/chromium/mojo/application/ApplicationImpl.java deleted file mode 100644 index 7768b8d..0000000 --- a/services/shell/public/java/src/org/chromium/mojo/application/ApplicationImpl.java +++ /dev/null
@@ -1,71 +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.mojo.application; - -import org.chromium.mojo.bindings.InterfaceRequest; -import org.chromium.mojo.system.Core; -import org.chromium.mojo.system.MessagePipeHandle; -import org.chromium.mojo.system.MojoException; -import org.chromium.mojom.mojo.Application; -import org.chromium.mojom.mojo.ServiceProvider; -import org.chromium.mojom.mojo.Shell; - -import java.util.ArrayList; - -/** - * Utility class for communicating with the Shell, and provide Services to clients. - */ -class ApplicationImpl implements Application { - private final ApplicationDelegate mApplicationDelegate; - private final ArrayList<ApplicationConnection> mIncomingConnections = - new ArrayList<ApplicationConnection>(); - private final Core mCore; - private Shell mShell; - - public ApplicationImpl( - ApplicationDelegate delegate, Core core, MessagePipeHandle applicationRequest) { - mApplicationDelegate = delegate; - mCore = core; - ApplicationImpl.MANAGER.bind(this, applicationRequest); - } - - @Override - public void initialize(Shell shell, String[] args, String url) { - mShell = shell; - mApplicationDelegate.initialize(shell, args, url); - } - - @Override - public void acceptConnection(String requestorUrl, InterfaceRequest<ServiceProvider> services, - ServiceProvider exposedServices, String connectionUrl) { - ApplicationConnection connection = - new ApplicationConnection(requestorUrl, exposedServices, connectionUrl); - if (services != null && mApplicationDelegate.configureIncomingConnection(connection)) { - ServiceProvider.MANAGER.bind(connection.getLocalServiceProvider(), services); - mIncomingConnections.add(connection); - } else { - connection.close(); - } - } - - @Override - public void requestQuit() { - mApplicationDelegate.quit(); - for (ApplicationConnection connection : mIncomingConnections) { - connection.close(); - } - mCore.getCurrentRunLoop().quit(); - } - - @Override - public void close() { - if (mShell != null) { - mShell.close(); - } - } - - @Override - public void onConnectionError(MojoException e) {} -}
diff --git a/services/shell/public/java/src/org/chromium/mojo/application/ApplicationRunner.java b/services/shell/public/java/src/org/chromium/mojo/application/ApplicationRunner.java deleted file mode 100644 index 1a903b4..0000000 --- a/services/shell/public/java/src/org/chromium/mojo/application/ApplicationRunner.java +++ /dev/null
@@ -1,32 +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.mojo.application; - -import org.chromium.mojo.system.Core; -import org.chromium.mojo.system.MessagePipeHandle; -import org.chromium.mojo.system.RunLoop; - -/** - * A utility for running an Application. - * - */ -public class ApplicationRunner { - /** - * Runs the delegate in a RunLoop. - * - * @param delegate Application specific functionality. - * @param core Core mojo interface. - * @param applicationRequest Handle for the application request. - */ - public static void run( - ApplicationDelegate delegate, Core core, MessagePipeHandle applicationRequest) { - try (RunLoop runLoop = core.createDefaultRunLoop()) { - try (ApplicationImpl application = - new ApplicationImpl(delegate, core, applicationRequest)) { - runLoop.run(); - } - } - } -}
diff --git a/services/shell/public/java/src/org/chromium/mojo/application/ServiceFactoryBinder.java b/services/shell/public/java/src/org/chromium/mojo/application/ServiceFactoryBinder.java deleted file mode 100644 index 462d74e..0000000 --- a/services/shell/public/java/src/org/chromium/mojo/application/ServiceFactoryBinder.java +++ /dev/null
@@ -1,30 +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.mojo.application; - -import org.chromium.mojo.bindings.Interface; -import org.chromium.mojo.system.MessagePipeHandle; - -/** - * ServiceFactoryBinder holds the necessary information to bind a service interface to a message - * pipe. - * - * @param <T> A mojo service interface. - */ -public interface ServiceFactoryBinder<T extends Interface> { - /** - * An application implements to bind a service implementation to |pipe|. - * - * @param pipe A handle to the incoming connection pipe. - */ - public void bindNewInstanceToMessagePipe(MessagePipeHandle pipe); - - /** - * Name of the service interface being implemented. - * - * @return Service interface name. - */ - public String getInterfaceName(); -}
diff --git a/services/shell/public/java/src/org/chromium/mojo/application/ShellHelper.java b/services/shell/public/java/src/org/chromium/mojo/application/ShellHelper.java deleted file mode 100644 index 705e22e1..0000000 --- a/services/shell/public/java/src/org/chromium/mojo/application/ShellHelper.java +++ /dev/null
@@ -1,40 +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.mojo.application; - -import org.chromium.mojo.bindings.Interface; -import org.chromium.mojo.bindings.Interface.Proxy; -import org.chromium.mojo.bindings.InterfaceRequest; -import org.chromium.mojo.system.Core; -import org.chromium.mojo.system.Pair; -import org.chromium.mojom.mojo.ServiceProvider; -import org.chromium.mojom.mojo.Shell; - -/** - * Helper class to help connecting to other application through the shell. - */ -public class ShellHelper { - /** - * Connects to a service in another application. - * - * @param core Implementation of the {@link Core} api. - * @param shell Instance of the shell. - * @param application URL to the application to use. - * @param manager {@link org.chromium.mojo.bindings.Interface.Manager} for the service to - * connect to. - * @return a proxy to the service. - */ - public static <I extends Interface, P extends Proxy> P connectToService( - Core core, Shell shell, String application, Interface.Manager<I, P> manager) { - Pair<ServiceProvider.Proxy, InterfaceRequest<ServiceProvider>> providerRequest = - ServiceProvider.MANAGER.getInterfaceRequest(core); - try (ServiceProvider.Proxy provider = providerRequest.first) { - shell.connectToApplication(application, providerRequest.second, null); - Pair<P, InterfaceRequest<I>> serviceRequest = manager.getInterfaceRequest(core); - provider.connectToService(manager.getName(), serviceRequest.second.passHandle()); - return serviceRequest.first; - } - } -}
diff --git a/services/shell/public/java/src/org/chromium/services/shell/InterfaceFactory.java b/services/shell/public/java/src/org/chromium/services/shell/InterfaceFactory.java new file mode 100644 index 0000000..8dcf260 --- /dev/null +++ b/services/shell/public/java/src/org/chromium/services/shell/InterfaceFactory.java
@@ -0,0 +1,19 @@ +// Copyright 2016 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.services.shell; + +import org.chromium.mojo.bindings.Interface; + +/** + * A factory that creates implementations of a mojo interface. + * + * @param <I> the mojo interface + */ +public interface InterfaceFactory<I extends Interface> { + /** + * Returns an implementation of the mojo interface. + */ + I createImpl(); +}
diff --git a/services/shell/public/java/src/org/chromium/services/shell/InterfaceRegistry.java b/services/shell/public/java/src/org/chromium/services/shell/InterfaceRegistry.java new file mode 100644 index 0000000..90b7d904 --- /dev/null +++ b/services/shell/public/java/src/org/chromium/services/shell/InterfaceRegistry.java
@@ -0,0 +1,73 @@ +// Copyright 2016 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.services.shell; + +import org.chromium.mojo.bindings.Interface; +import org.chromium.mojo.system.MessagePipeHandle; +import org.chromium.mojo.system.MojoException; +import org.chromium.mojom.shell.mojom.InterfaceProvider; + +import java.util.HashMap; +import java.util.Map; + +/** + * A registry where interfaces may be registered to be exposed to another application. + * + * To use, define a class that implements your specific interface. Then + * implement an InterfaceFactory that creates instances of your implementation + * and register that on the registry with a Manager for the interface like this: + * + * registry.addInterface(factory, InterfaceType.MANAGER); + */ +public class InterfaceRegistry implements InterfaceProvider { + private final Map<String, InterfaceBinder> mBinders = new HashMap<String, InterfaceBinder>(); + + public <I extends Interface> void addInterface( + Interface.Manager<I, ? extends I.Proxy> manager, InterfaceFactory<I> factory) { + mBinders.put(manager.getName(), new InterfaceBinder<I>(manager, factory)); + } + + public static InterfaceRegistry create(MessagePipeHandle pipe) { + InterfaceRegistry registry = new InterfaceRegistry(); + InterfaceProvider.MANAGER.bind(registry, pipe); + return registry; + } + + @Override + public void getInterface(String name, MessagePipeHandle pipe) { + InterfaceBinder binder = mBinders.get(name); + if (binder == null) { + return; + } + binder.bindToMessagePipe(pipe); + } + + @Override + public void close() { + mBinders.clear(); + } + + @Override + public void onConnectionError(MojoException e) { + close(); + } + + InterfaceRegistry() {} + + private static class InterfaceBinder<I extends Interface> { + private Interface.Manager<I, ? extends I.Proxy> mManager; + private InterfaceFactory<I> mFactory; + + public InterfaceBinder( + Interface.Manager<I, ? extends I.Proxy> manager, InterfaceFactory<I> factory) { + mManager = manager; + mFactory = factory; + } + + public void bindToMessagePipe(MessagePipeHandle pipe) { + mManager.bind(mFactory.createImpl(), pipe); + } + } +}
diff --git a/services/shell/runner/init.cc b/services/shell/runner/init.cc index 8d095f0f..2e60194 100644 --- a/services/shell/runner/init.cc +++ b/services/shell/runner/init.cc
@@ -60,7 +60,7 @@ } } } - if (apps_to_debug.empty() || ContainsValue(apps_to_debug, app)) { + if (apps_to_debug.empty() || base::ContainsValue(apps_to_debug, app)) { #if defined(OS_WIN) base::string16 appw = base::UTF8ToUTF16(app); base::string16 message = base::UTF8ToUTF16( @@ -83,12 +83,11 @@ reinterpret_cast<LibraryEarlyInitFunction>( base::GetFunctionPointerFromNativeLibrary(app_library, "InitializeBase")); - if (init_function) { - // Get the ICU data that we prewarmed in the runner and then pass it to - // the copy of icu in the mojo binary that we're running. - const uint8_t* icu_data = base::i18n::GetRawIcuMemory(); - init_function(icu_data); - } + CHECK(init_function); + // Get the ICU data that we prewarmed in the runner and then pass it to + // the copy of icu in the mojo binary that we're running. + const uint8_t* icu_data = base::i18n::GetRawIcuMemory(); + init_function(icu_data); #endif // ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE // TODO(erg): All chromium binaries load base. We might want to make a
diff --git a/services/shell/service_manager.cc b/services/shell/service_manager.cc index aa096e64..f0aa9d4f 100644 --- a/services/shell/service_manager.cc +++ b/services/shell/service_manager.cc
@@ -192,9 +192,8 @@ request.interfaces.erase("*"); } - service_->OnConnect(mojom::Identity::From(params->source()), - params->TakeRemoteInterfaces(), - mojom::CapabilityRequest::From(request)); + service_->OnConnect(params->source(), params->TakeRemoteInterfaces(), + request); return true; } @@ -204,7 +203,7 @@ service_.set_connection_error_handler( base::Bind(&Instance::OnServiceLost, base::Unretained(this), service_manager_->GetWeakPtr())); - service_->OnStart(mojom::Identity::From(identity_), + service_->OnStart(identity_, base::Bind(&Instance::OnInitializeResponse, base::Unretained(this))); } @@ -233,7 +232,7 @@ mojom::ServiceInfoPtr CreateServiceInfo() const { mojom::ServiceInfoPtr info(mojom::ServiceInfo::New()); info->id = id_; - info->identity = mojom::Identity::From(identity_); + info->identity = identity_; info->pid = pid_; return info; } @@ -253,11 +252,11 @@ private: // mojom::Connector implementation: - void Connect(mojom::IdentityPtr target_ptr, + void Connect(const shell::Identity& in_target, mojom::InterfaceProviderRequest remote_interfaces, mojom::ClientProcessConnectionPtr client_process_connection, const ConnectCallback& callback) override { - Identity target = target_ptr.To<Identity>(); + Identity target = in_target; if (target.user_id() == mojom::kInheritUserID) target.set_user_id(identity_.user_id()); @@ -592,7 +591,7 @@ identity_to_instance_.erase(it); listeners_.ForAllPtrs( [this, identity](mojom::ServiceManagerListener* listener) { - listener->OnServiceStopped(mojom::Identity::From(identity)); + listener->OnServiceStopped(identity); }); delete instance; if (!instance_quit_callback_.is_null()) @@ -651,7 +650,7 @@ base::ProcessId pid) { listeners_.ForAllPtrs( [identity, pid](mojom::ServiceManagerListener* listener) { - listener->OnServiceStarted(mojom::Identity::From(identity), pid); + listener->OnServiceStarted(identity, pid); }); } @@ -682,7 +681,8 @@ void ServiceManager::AddListener(mojom::ServiceManagerListenerPtr listener) { // TODO(beng): filter instances provided by those visible to this service. - mojo::Array<mojom::ServiceInfoPtr> instances; + std::vector<mojom::ServiceInfoPtr> instances; + instances.reserve(identity_to_instance_.size()); for (auto& instance : identity_to_instance_) instances.push_back(instance.second->CreateServiceInfo()); listener->OnInit(std::move(instances)); @@ -748,11 +748,11 @@ return; Identity source = params->source(); - // |capabilities_ptr| can be null when there is no manifest, e.g. for URL + // |result->capabilities| can be null when there is no manifest, e.g. for URL // types not resolvable by the resolver. CapabilitySpec capabilities = GetPermissiveCapabilities(); - if (!result->capabilities.is_null()) - capabilities = result->capabilities.To<CapabilitySpec>(); + if (result->capabilities.has_value()) + capabilities = result->capabilities.value(); // Services that request "all_users" class from the Service Manager are // allowed to field connection requests from any user. They also run with a @@ -788,7 +788,7 @@ } else { // Otherwise we create a new Service pipe. mojom::ServiceRequest request = GetProxy(&service); - CHECK(!result->package_path.empty() && !result->capabilities.is_null()); + CHECK(!result->package_path.empty() && result->capabilities.has_value()); if (target.name() != result->resolved_name) { instance->StartWithService(std::move(service));
diff --git a/services/shell/standalone/context.cc b/services/shell/standalone/context.cc index 0447367..c53d82c 100644 --- a/services/shell/standalone/context.cc +++ b/services/shell/standalone/context.cc
@@ -69,7 +69,7 @@ ~TracingInterfaceProvider() override {} // mojom::InterfaceProvider: - void GetInterface(const mojo::String& interface_name, + void GetInterface(const std::string& interface_name, mojo::ScopedMessagePipeHandle client_handle) override { if (tracer_ && interface_name == tracing::mojom::Provider::Name_) { tracer_->ConnectToProvider(
diff --git a/services/shell/tests/connect/BUILD.gn b/services/shell/tests/connect/BUILD.gn index 6d5f70b..c981167 100644 --- a/services/shell/tests/connect/BUILD.gn +++ b/services/shell/tests/connect/BUILD.gn
@@ -39,8 +39,6 @@ deps = [ "//services/shell/public/interfaces", ] - - use_new_wrapper_types = false } service_manifest("manifest") {
diff --git a/services/shell/tests/connect/connect_test_app.cc b/services/shell/tests/connect/connect_test_app.cc index e367e0c0..0c70726 100644 --- a/services/shell/tests/connect/connect_test_app.cc +++ b/services/shell/tests/connect/connect_test_app.cc
@@ -29,7 +29,7 @@ void ReceiveString(std::string* string, base::RunLoop* loop, - mojo::String response) { + const std::string& response) { *string = response; loop->Quit(); } @@ -169,9 +169,9 @@ // test::mojom::UserIdTest: void ConnectToClassAppAsDifferentUser( - mojom::IdentityPtr target, + const shell::Identity& target, const ConnectToClassAppAsDifferentUserCallback& callback) override { - Connector::ConnectParams params(target.To<Identity>()); + Connector::ConnectParams params(target); std::unique_ptr<Connection> connection = connector()->Connect(¶ms); { @@ -182,7 +182,7 @@ loop.Run(); } callback.Run(static_cast<int32_t>(connection->GetResult()), - mojom::Identity::From(connection->GetRemoteIdentity())); + connection->GetRemoteIdentity()); } void OnConnectionBlocked( @@ -195,7 +195,7 @@ void OnGotTitle( const ConnectToAllowedAppInBlockedPackageCallback& callback, base::RunLoop* run_loop, - mojo::String title) { + const std::string& title) { callback.Run(title); run_loop->Quit(); }
diff --git a/services/shell/tests/connect/connect_test_driver.cc b/services/shell/tests/connect/connect_test_driver.cc index 27b31cb..17ecdbb 100644 --- a/services/shell/tests/connect/connect_test_driver.cc +++ b/services/shell/tests/connect/connect_test_driver.cc
@@ -63,7 +63,7 @@ shell::mojom::kInheritUserID), connector(), &process); callback.Run(static_cast<int32_t>(connection->GetResult()), - shell::mojom::Identity::From(connection->GetRemoteIdentity())); + connection->GetRemoteIdentity()); } mojo::BindingSet<ClientProcessTest> bindings_;
diff --git a/services/shell/tests/connect/connect_test_package.cc b/services/shell/tests/connect/connect_test_package.cc index e913c1e..7918941 100644 --- a/services/shell/tests/connect/connect_test_package.cc +++ b/services/shell/tests/connect/connect_test_package.cc
@@ -118,9 +118,9 @@ // test::mojom::UserIdTest: void ConnectToClassAppAsDifferentUser( - mojom::IdentityPtr target, + const shell::Identity& target, const ConnectToClassAppAsDifferentUserCallback& callback) override { - Connector::ConnectParams params(target.To<Identity>()); + Connector::ConnectParams params(target); std::unique_ptr<Connection> connection = connector()->Connect(¶ms); { @@ -131,7 +131,7 @@ loop.Run(); } callback.Run(static_cast<int32_t>(connection->GetResult()), - mojom::Identity::From(connection->GetRemoteIdentity())); + connection->GetRemoteIdentity()); } // base::SimpleThread: @@ -196,7 +196,7 @@ // mojom::ServiceFactory: void CreateService(mojom::ServiceRequest request, - const mojo::String& name) override { + const std::string& name) override { if (name == "mojo:connect_test_a") new ProvidedService("A", std::move(request)); else if (name == "mojo:connect_test_b")
diff --git a/services/shell/tests/connect/connect_unittest.cc b/services/shell/tests/connect/connect_unittest.cc index 5c2401e..736b530c 100644 --- a/services/shell/tests/connect/connect_unittest.cc +++ b/services/shell/tests/connect/connect_unittest.cc
@@ -37,7 +37,7 @@ void ReceiveOneString(std::string* out_string, base::RunLoop* loop, - mojo::String in_string) { + const std::string& in_string) { *out_string = in_string; loop->Quit(); } @@ -45,8 +45,8 @@ void ReceiveTwoStrings(std::string* out_string_1, std::string* out_string_2, base::RunLoop* loop, - mojo::String in_string_1, - mojo::String in_string_2) { + const std::string& in_string_1, + const std::string& in_string_2) { *out_string_1 = in_string_1; *out_string_2 = in_string_2; loop->Quit(); @@ -56,9 +56,9 @@ Identity* out_target, base::RunLoop* loop, int32_t in_result, - mojom::IdentityPtr in_identity) { + const shell::Identity& in_identity) { *out_result = static_cast<mojom::ConnectResult>(in_result); - *out_target = in_identity.To<Identity>(); + *out_target = in_identity; loop->Quit(); } @@ -338,7 +338,7 @@ { base::RunLoop loop; user_id_test->ConnectToClassAppAsDifferentUser( - mojom::Identity::From(target), + target, base::Bind(&ReceiveConnectionResult, &result, &result_identity, &loop)); loop.Run(); } @@ -356,7 +356,7 @@ { base::RunLoop loop; user_id_test->ConnectToClassAppAsDifferentUser( - mojom::Identity::From(target), + target, base::Bind(&ReceiveConnectionResult, &result, &result_identity, &loop)); loop.Run(); }
diff --git a/services/shell/tests/lifecycle/BUILD.gn b/services/shell/tests/lifecycle/BUILD.gn index 923cfbb..2807bb6 100644 --- a/services/shell/tests/lifecycle/BUILD.gn +++ b/services/shell/tests/lifecycle/BUILD.gn
@@ -36,8 +36,6 @@ sources = [ "lifecycle_unittest.mojom", ] - - use_new_wrapper_types = false } service_manifest("manifest") {
diff --git a/services/shell/tests/lifecycle/lifecycle_unittest.cc b/services/shell/tests/lifecycle/lifecycle_unittest.cc index 7f1181af..7d985e4 100644 --- a/services/shell/tests/lifecycle/lifecycle_unittest.cc +++ b/services/shell/tests/lifecycle/lifecycle_unittest.cc
@@ -69,21 +69,20 @@ private: // mojom::ServiceManagerListener: - void OnInit(mojo::Array<mojom::ServiceInfoPtr> instances) override { + void OnInit(std::vector<mojom::ServiceInfoPtr> instances) override { for (const auto& instance : instances) { - Instance i(instance->identity.To<Identity>(), instance->pid); + Instance i(instance->identity, instance->pid); initial_instances_[i.identity.name()] = i; instances_[i.identity.name()] = i; } loop_->Quit(); } void OnServiceCreated(mojom::ServiceInfoPtr instance) override { - instances_[instance->identity->name] = - Instance(instance->identity.To<Identity>(), instance->pid); + instances_[instance->identity.name()] = + Instance(instance->identity, instance->pid); } - void OnServiceStarted(mojom::IdentityPtr identity_ptr, + void OnServiceStarted(const shell::Identity& identity, uint32_t pid) override { - Identity identity = identity_ptr.To<Identity>(); for (auto& instance : instances_) { if (instance.second.identity == identity) { instance.second.pid = pid; @@ -91,8 +90,7 @@ } } } - void OnServiceStopped(mojom::IdentityPtr identity_ptr) override { - Identity identity = identity_ptr.To<Identity>(); + void OnServiceStopped(const shell::Identity& identity) override { for (auto it = instances_.begin(); it != instances_.end(); ++it) { if (it->second.identity == identity) { instances_.erase(it);
diff --git a/services/shell/tests/lifecycle/package.cc b/services/shell/tests/lifecycle/package.cc index 1926faf..c2a0335 100644 --- a/services/shell/tests/lifecycle/package.cc +++ b/services/shell/tests/lifecycle/package.cc
@@ -114,7 +114,7 @@ // shell::mojom::ServiceFactory: void CreateService(shell::mojom::ServiceRequest request, - const mojo::String& name) override { + const std::string& name) override { ++shell_connection_refcount_; apps_.push_back( new PackagedApp(std::move(request),
diff --git a/services/shell/tests/shell/BUILD.gn b/services/shell/tests/shell/BUILD.gn index bbce4bc..7d702746 100644 --- a/services/shell/tests/shell/BUILD.gn +++ b/services/shell/tests/shell/BUILD.gn
@@ -38,8 +38,6 @@ deps = [ "//services/shell/public/interfaces", ] - - use_new_wrapper_types = false } service_manifest("manifest") {
diff --git a/services/shell/tests/shell/shell_unittest.cc b/services/shell/tests/shell/shell_unittest.cc index 19f6126..40a54ad 100644 --- a/services/shell/tests/shell/shell_unittest.cc +++ b/services/shell/tests/shell/shell_unittest.cc
@@ -53,8 +53,8 @@ } // test::mojom::CreateInstanceTest: - void SetTargetIdentity(shell::mojom::IdentityPtr identity) override { - target_identity_ = identity.To<Identity>(); + void SetTargetIdentity(const shell::Identity& identity) override { + target_identity_ = identity; base::MessageLoop::current()->QuitWhenIdle(); } @@ -128,21 +128,18 @@ } // mojom::ServiceManagerListener: - void OnInit(mojo::Array<mojom::ServiceInfoPtr> instances) override { - for (size_t i = 0; i < instances.size(); ++i) { - initial_instances_.push_back( - InstanceInfo(instances[i]->identity.To<Identity>())); - } + void OnInit(std::vector<mojom::ServiceInfoPtr> instances) override { + for (size_t i = 0; i < instances.size(); ++i) + initial_instances_.push_back(InstanceInfo(instances[i]->identity)); DCHECK(wait_for_instances_loop_); wait_for_instances_loop_->Quit(); } void OnServiceCreated(mojom::ServiceInfoPtr instance) override { - instances_.push_back(InstanceInfo(instance->identity.To<Identity>())); + instances_.push_back(InstanceInfo(instance->identity)); } - void OnServiceStarted(shell::mojom::IdentityPtr identity_ptr, + void OnServiceStarted(const shell::Identity& identity, uint32_t pid) override { - Identity identity = identity_ptr.To<Identity>(); for (auto& instance : instances_) { if (instance.identity == identity) { instance.pid = pid; @@ -150,8 +147,7 @@ } } } - void OnServiceStopped(shell::mojom::IdentityPtr identity_ptr) override { - Identity identity = identity_ptr.To<Identity>(); + void OnServiceStopped(const shell::Identity& identity) override { for (auto it = instances_.begin(); it != instances_.end(); ++it) { auto& instance = *it; if (instance.identity == identity) {
diff --git a/services/shell/tests/shell/target.cc b/services/shell/tests/shell/target.cc index 4159489..8784231 100644 --- a/services/shell/tests/shell/target.cc +++ b/services/shell/tests/shell/target.cc
@@ -26,7 +26,7 @@ void OnStart(const shell::Identity& identity) override { CreateInstanceTestPtr service; connector()->ConnectToInterface("mojo:shell_unittest", &service); - service->SetTargetIdentity(shell::mojom::Identity::From(identity)); + service->SetTargetIdentity(identity); } DISALLOW_COPY_AND_ASSIGN(Target);
diff --git a/services/shell/tests/shutdown/BUILD.gn b/services/shell/tests/shutdown/BUILD.gn index 12c6239..10a52d5 100644 --- a/services/shell/tests/shutdown/BUILD.gn +++ b/services/shell/tests/shutdown/BUILD.gn
@@ -35,8 +35,6 @@ sources = [ "shutdown_unittest.mojom", ] - - use_new_wrapper_types = false } service_manifest("shutdown_unittest_manifest") {
diff --git a/services/ui/common/BUILD.gn b/services/ui/common/BUILD.gn index c2a2447..98ff933 100644 --- a/services/ui/common/BUILD.gn +++ b/services/ui/common/BUILD.gn
@@ -12,18 +12,8 @@ "event_matcher_util.h", "generic_shared_memory_id_generator.cc", "generic_shared_memory_id_generator.h", - "gpu_memory_buffer_impl.cc", - "gpu_memory_buffer_impl.h", - "gpu_service.cc", - "gpu_service.h", "gpu_type_converters.cc", "gpu_type_converters.h", - "mojo_buffer_backing.cc", - "mojo_buffer_backing.h", - "mojo_gpu_memory_buffer.cc", - "mojo_gpu_memory_buffer.h", - "mojo_gpu_memory_buffer_manager.cc", - "mojo_gpu_memory_buffer_manager.h", "mus_common_export.h", "switches.cc", "switches.h", @@ -51,10 +41,6 @@ "//services/ui/public/interfaces", "//ui/base", ] - - if (use_ozone) { - deps += [ "//ui/ozone" ] - } } source_set("run_all_shelltests") {
diff --git a/services/ui/common/gpu_memory_buffer_impl.cc b/services/ui/common/gpu_memory_buffer_impl.cc deleted file mode 100644 index 99a1a87a..0000000 --- a/services/ui/common/gpu_memory_buffer_impl.cc +++ /dev/null
@@ -1,46 +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 "services/ui/common/gpu_memory_buffer_impl.h" - -namespace ui { - -GpuMemoryBufferImpl::GpuMemoryBufferImpl(gfx::GpuMemoryBufferId id, - const gfx::Size& size, - gfx::BufferFormat format) - : id_(id), size_(size), format_(format), mapped_(false) {} - -GpuMemoryBufferImpl::~GpuMemoryBufferImpl() { - DCHECK(!mapped_); -} - -// static -GpuMemoryBufferImpl* GpuMemoryBufferImpl::FromClientBuffer( - ClientBuffer buffer) { - return reinterpret_cast<GpuMemoryBufferImpl*>(buffer); -} - -gfx::Size GpuMemoryBufferImpl::GetSize() const { - return size_; -} - -gfx::BufferFormat GpuMemoryBufferImpl::GetFormat() const { - return format_; -} - -gfx::GpuMemoryBufferId GpuMemoryBufferImpl::GetId() const { - return id_; -} - -ClientBuffer GpuMemoryBufferImpl::AsClientBuffer() { - return reinterpret_cast<ClientBuffer>(this); -} - -#if defined(USE_OZONE) -scoped_refptr<ui::NativePixmap> GpuMemoryBufferImpl::GetNativePixmap() { - return scoped_refptr<ui::NativePixmap>(); -} -#endif - -} // namespace ui
diff --git a/services/ui/common/gpu_memory_buffer_impl.h b/services/ui/common/gpu_memory_buffer_impl.h deleted file mode 100644 index 90750419..0000000 --- a/services/ui/common/gpu_memory_buffer_impl.h +++ /dev/null
@@ -1,61 +0,0 @@ -// Copyright 2016 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 SERVICES_UI_COMMON_GPU_MEMORY_BUFFER_IMPL_H_ -#define SERVICES_UI_COMMON_GPU_MEMORY_BUFFER_IMPL_H_ - -#include <memory> - -#include "base/callback.h" -#include "base/macros.h" -#include "gpu/command_buffer/common/sync_token.h" -#include "services/ui/common/mus_common_export.h" -#include "ui/gfx/geometry/size.h" -#include "ui/gfx/gpu_memory_buffer.h" - -#if defined(USE_OZONE) -#include "ui/ozone/public/native_pixmap.h" -#endif - -namespace ui { - -// Provides common implementation of a GPU memory buffer. -class MUS_COMMON_EXPORT GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer { - public: - ~GpuMemoryBufferImpl() override; - - // Type-checking upcast routine. Returns an NULL on failure. - static GpuMemoryBufferImpl* FromClientBuffer(ClientBuffer buffer); - - // Overridden from gfx::GpuMemoryBuffer: - gfx::Size GetSize() const override; - gfx::BufferFormat GetFormat() const override; - gfx::GpuMemoryBufferId GetId() const override; - ClientBuffer AsClientBuffer() override; - - // Returns the type of this GpuMemoryBufferImpl. - virtual gfx::GpuMemoryBufferType GetBufferType() const = 0; - -#if defined(USE_OZONE) - // Returns a ui::NativePixmap when one is available. - virtual scoped_refptr<ui::NativePixmap> GetNativePixmap(); -#endif - - protected: - GpuMemoryBufferImpl(gfx::GpuMemoryBufferId id, - const gfx::Size& size, - gfx::BufferFormat format); - - const gfx::GpuMemoryBufferId id_; - const gfx::Size size_; - const gfx::BufferFormat format_; - bool mapped_; - - private: - DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferImpl); -}; - -} // namespace ui - -#endif // SERVICES_UI_COMMON_GPU_MEMORY_BUFFER_IMPL_H_
diff --git a/services/ui/common/gpu_service.cc b/services/ui/common/gpu_service.cc deleted file mode 100644 index 113d086..0000000 --- a/services/ui/common/gpu_service.cc +++ /dev/null
@@ -1,237 +0,0 @@ -// Copyright 2016 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 "services/ui/common/gpu_service.h" - -#include "base/command_line.h" -#include "base/memory/singleton.h" -#include "base/threading/thread_task_runner_handle.h" -#include "build/build_config.h" -#include "mojo/public/cpp/bindings/sync_call_restrictions.h" -#include "mojo/public/cpp/system/platform_handle.h" -#include "services/shell/public/cpp/connector.h" -#include "services/ui/common/gpu_type_converters.h" -#include "services/ui/common/mojo_gpu_memory_buffer_manager.h" -#include "services/ui/common/switches.h" -#include "services/ui/public/interfaces/gpu_service.mojom.h" - -namespace ui { - -namespace { - -void PostTask(scoped_refptr<base::SingleThreadTaskRunner> runner, - const tracked_objects::Location& from_here, - const gpu::GpuChannelEstablishedCallback& callback, - scoped_refptr<gpu::GpuChannelHost> established_channel_host) { - runner->PostTask(from_here, - base::Bind(callback, std::move(established_channel_host))); -} - -GpuService* g_gpu_service = nullptr; -} - -GpuService::GpuService(shell::Connector* connector) - : main_task_runner_(base::ThreadTaskRunnerHandle::Get()), - connector_(connector), - shutdown_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED), - io_thread_("GPUIOThread"), - gpu_memory_buffer_manager_(new MojoGpuMemoryBufferManager), - is_establishing_(false), - establishing_condition_(&lock_) { - DCHECK(main_task_runner_); - DCHECK(connector_); - base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0); - thread_options.priority = base::ThreadPriority::NORMAL; - CHECK(io_thread_.StartWithOptions(thread_options)); -} - -GpuService::~GpuService() { - DCHECK(IsMainThread()); - DCHECK_EQ(this, g_gpu_service); - if (gpu_channel_) - gpu_channel_->DestroyChannel(); - g_gpu_service = nullptr; -} - -// static -std::unique_ptr<GpuService> GpuService::Initialize( - shell::Connector* connector) { - DCHECK(!g_gpu_service); - g_gpu_service = new GpuService(connector); - return base::WrapUnique(g_gpu_service); -} - -// static -GpuService* GpuService::GetInstance() { - DCHECK(g_gpu_service); - return g_gpu_service; -} - -void GpuService::EstablishGpuChannel( - const gpu::GpuChannelEstablishedCallback& callback) { - base::AutoLock auto_lock(lock_); - auto runner = base::ThreadTaskRunnerHandle::Get(); - scoped_refptr<gpu::GpuChannelHost> channel = GetGpuChannelLocked(); - if (channel) { - PostTask(runner, FROM_HERE, callback, std::move(channel)); - return; - } - establish_callbacks_.push_back( - base::Bind(PostTask, runner, FROM_HERE, callback)); - if (!is_establishing_) { - is_establishing_ = true; - main_task_runner_->PostTask( - FROM_HERE, base::Bind(&GpuService::EstablishGpuChannelOnMainThread, - base::Unretained(this))); - } -} - -scoped_refptr<gpu::GpuChannelHost> GpuService::EstablishGpuChannelSync() { - base::AutoLock auto_lock(lock_); - if (GetGpuChannelLocked()) - return gpu_channel_; - - if (IsMainThread()) { - is_establishing_ = true; - EstablishGpuChannelOnMainThreadSyncLocked(); - } else { - if (!is_establishing_) { - // Create an establishing gpu channel task, if there isn't one. - is_establishing_ = true; - main_task_runner_->PostTask( - FROM_HERE, base::Bind(&GpuService::EstablishGpuChannelOnMainThread, - base::Unretained(this))); - } - - // Wait until the pending establishing task is finished. - do { - establishing_condition_.Wait(); - } while (is_establishing_); - } - return gpu_channel_; -} - -scoped_refptr<gpu::GpuChannelHost> GpuService::GetGpuChannelLocked() { - if (gpu_channel_ && gpu_channel_->IsLost()) { - main_task_runner_->PostTask( - FROM_HERE, - base::Bind(&gpu::GpuChannelHost::DestroyChannel, gpu_channel_)); - gpu_channel_ = nullptr; - } - return gpu_channel_; -} - -void GpuService::EstablishGpuChannelOnMainThread() { - base::AutoLock auto_lock(lock_); - DCHECK(IsMainThread()); - - // In GpuService::EstablishGpuChannelOnMainThreadSyncLocked(), we use the sync - // mojo EstablishGpuChannel call, after that call the gpu_service_ will be - // reset immediatelly. So gpu_service_ should be always null here. - DCHECK(!gpu_service_); - - // is_establishing_ is false, it means GpuService::EstablishGpuChannelSync() - // has been used, and we don't need try to establish a new GPU channel - // anymore. - if (!is_establishing_) - return; - - connector_->ConnectToInterface("mojo:ui", &gpu_service_); - const bool locked = false; - gpu_service_->EstablishGpuChannel( - base::Bind(&GpuService::EstablishGpuChannelOnMainThreadDone, - base::Unretained(this), locked)); -} - -void GpuService::EstablishGpuChannelOnMainThreadSyncLocked() { - DCHECK(IsMainThread()); - DCHECK(is_establishing_); - - // In browser process, EstablishGpuChannelSync() is only used by testing & - // GpuProcessTransportFactory::GetGLHelper(). For GetGLHelper(), it expects - // the gpu channel has been established, so it should not reach here. - // For testing, the asyc method should not be used. - // In renderer process, we only use EstablishGpuChannelSync(). - // So the gpu_service_ should be null here. - DCHECK(!gpu_service_); - - int client_id = 0; - mojom::ChannelHandlePtr channel_handle; - mojom::GpuInfoPtr gpu_info; - connector_->ConnectToInterface("mojo:ui", &gpu_service_); - { - base::AutoUnlock auto_unlock(lock_); - mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync_call; - if (!gpu_service_->EstablishGpuChannel(&client_id, &channel_handle, - &gpu_info)) { - DLOG(WARNING) - << "Channel encountered error while establishing gpu channel."; - return; - } - } - const bool locked = true; - EstablishGpuChannelOnMainThreadDone( - locked, client_id, std::move(channel_handle), std::move(gpu_info)); -} - -void GpuService::EstablishGpuChannelOnMainThreadDone( - bool locked, - int client_id, - mojom::ChannelHandlePtr channel_handle, - mojom::GpuInfoPtr gpu_info) { - DCHECK(IsMainThread()); - scoped_refptr<gpu::GpuChannelHost> gpu_channel; - if (client_id) { - // TODO(penghuang): Get the real gpu info from mus. - gpu_channel = gpu::GpuChannelHost::Create( - this, client_id, gpu::GPUInfo(), - channel_handle.To<IPC::ChannelHandle>(), &shutdown_event_, - gpu_memory_buffer_manager_.get()); - } - - auto auto_lock = base::WrapUnique<base::AutoLock>( - locked ? nullptr : new base::AutoLock(lock_)); - DCHECK(is_establishing_); - DCHECK(!gpu_channel_); - - is_establishing_ = false; - gpu_channel_ = gpu_channel; - establishing_condition_.Broadcast(); - gpu_service_.reset(); - - for (const auto& i : establish_callbacks_) - i.Run(gpu_channel_); - establish_callbacks_.clear(); -} - -bool GpuService::IsMainThread() { - return main_task_runner_->BelongsToCurrentThread(); -} - -scoped_refptr<base::SingleThreadTaskRunner> -GpuService::GetIOThreadTaskRunner() { - return io_thread_.task_runner(); -} - -std::unique_ptr<base::SharedMemory> GpuService::AllocateSharedMemory( - size_t size) { - mojo::ScopedSharedBufferHandle handle = - mojo::SharedBufferHandle::Create(size); - if (!handle.is_valid()) - return nullptr; - - base::SharedMemoryHandle platform_handle; - size_t shared_memory_size; - bool readonly; - MojoResult result = mojo::UnwrapSharedMemoryHandle( - std::move(handle), &platform_handle, &shared_memory_size, &readonly); - if (result != MOJO_RESULT_OK) - return nullptr; - DCHECK_EQ(shared_memory_size, size); - - return base::MakeUnique<base::SharedMemory>(platform_handle, readonly); -} - -} // namespace ui
diff --git a/services/ui/common/gpu_service.h b/services/ui/common/gpu_service.h deleted file mode 100644 index d15ba7116..0000000 --- a/services/ui/common/gpu_service.h +++ /dev/null
@@ -1,86 +0,0 @@ -// Copyright 2016 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 SERVICES_UI_COMMON_GPU_SERVICE_H_ -#define SERVICES_UI_COMMON_GPU_SERVICE_H_ - -#include <stdint.h> -#include <vector> - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/single_thread_task_runner.h" -#include "base/synchronization/lock.h" -#include "base/synchronization/waitable_event.h" -#include "base/threading/thread.h" -#include "gpu/ipc/client/gpu_channel_host.h" -#include "services/ui/common/mojo_gpu_memory_buffer_manager.h" -#include "services/ui/common/mus_common_export.h" -#include "services/ui/public/interfaces/gpu_service.mojom.h" - -namespace shell { -class Connector; -} - -namespace ui { - -class MUS_COMMON_EXPORT GpuService : public gpu::GpuChannelHostFactory, - public gpu::GpuChannelEstablishFactory { - public: - ~GpuService() override; - - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager() const { - return gpu_memory_buffer_manager_.get(); - } - - // The GpuService has to be initialized in the main thread before establishing - // the gpu channel. - static std::unique_ptr<GpuService> Initialize(shell::Connector* connector); - static GpuService* GetInstance(); - - // gpu::GpuChannelEstablishFactory: - void EstablishGpuChannel( - const gpu::GpuChannelEstablishedCallback& callback) override; - scoped_refptr<gpu::GpuChannelHost> EstablishGpuChannelSync() override; - - private: - friend struct base::DefaultSingletonTraits<GpuService>; - - explicit GpuService(shell::Connector* connector); - - scoped_refptr<gpu::GpuChannelHost> GetGpuChannelLocked(); - void EstablishGpuChannelOnMainThread(); - void EstablishGpuChannelOnMainThreadSyncLocked(); - void EstablishGpuChannelOnMainThreadDone( - bool locked, - int client_id, - mojom::ChannelHandlePtr channel_handle, - mojom::GpuInfoPtr gpu_info); - - // gpu::GpuChannelHostFactory overrides: - bool IsMainThread() override; - scoped_refptr<base::SingleThreadTaskRunner> GetIOThreadTaskRunner() override; - std::unique_ptr<base::SharedMemory> AllocateSharedMemory( - size_t size) override; - - scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; - shell::Connector* connector_; - base::WaitableEvent shutdown_event_; - base::Thread io_thread_; - std::unique_ptr<MojoGpuMemoryBufferManager> gpu_memory_buffer_manager_; - - // Lock for |gpu_channel_|, |establish_callbacks_| & |is_establishing_|. - base::Lock lock_; - bool is_establishing_; - ui::mojom::GpuServicePtr gpu_service_; - scoped_refptr<gpu::GpuChannelHost> gpu_channel_; - std::vector<gpu::GpuChannelEstablishedCallback> establish_callbacks_; - base::ConditionVariable establishing_condition_; - - DISALLOW_COPY_AND_ASSIGN(GpuService); -}; - -} // namespace ui - -#endif // COMPONENTS_MUS_PUBLIC_CPP_LIB_GPU_SERVICE_CONNECTION_H_
diff --git a/services/ui/common/mojo_buffer_backing.cc b/services/ui/common/mojo_buffer_backing.cc deleted file mode 100644 index de377f49..0000000 --- a/services/ui/common/mojo_buffer_backing.cc +++ /dev/null
@@ -1,34 +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 "services/ui/common/mojo_buffer_backing.h" - -#include "base/logging.h" -#include "base/memory/ptr_util.h" - -namespace ui { - -MojoBufferBacking::MojoBufferBacking(mojo::ScopedSharedBufferMapping mapping, - size_t size) - : mapping_(std::move(mapping)), size_(size) {} - -MojoBufferBacking::~MojoBufferBacking() = default; - -// static -std::unique_ptr<gpu::BufferBacking> MojoBufferBacking::Create( - mojo::ScopedSharedBufferHandle handle, - size_t size) { - mojo::ScopedSharedBufferMapping mapping = handle->Map(size); - if (!mapping) - return nullptr; - return base::MakeUnique<MojoBufferBacking>(std::move(mapping), size); -} -void* MojoBufferBacking::GetMemory() const { - return mapping_.get(); -} -size_t MojoBufferBacking::GetSize() const { - return size_; -} - -} // namespace ui
diff --git a/services/ui/common/mojo_buffer_backing.h b/services/ui/common/mojo_buffer_backing.h deleted file mode 100644 index d01b7365..0000000 --- a/services/ui/common/mojo_buffer_backing.h +++ /dev/null
@@ -1,40 +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 SERVICES_UI_COMMON_MOJO_BUFFER_BACKING_H_ -#define SERVICES_UI_COMMON_MOJO_BUFFER_BACKING_H_ - -#include <stddef.h> - -#include <memory> - -#include "base/macros.h" -#include "gpu/command_buffer/common/buffer.h" -#include "mojo/public/cpp/system/core.h" -#include "services/ui/common/mus_common_export.h" - -namespace ui { - -class MUS_COMMON_EXPORT MojoBufferBacking : public gpu::BufferBacking { - public: - MojoBufferBacking(mojo::ScopedSharedBufferMapping mapping, size_t size); - ~MojoBufferBacking() override; - - static std::unique_ptr<gpu::BufferBacking> Create( - mojo::ScopedSharedBufferHandle handle, - size_t size); - - void* GetMemory() const override; - size_t GetSize() const override; - - private: - mojo::ScopedSharedBufferMapping mapping_; - size_t size_; - - DISALLOW_COPY_AND_ASSIGN(MojoBufferBacking); -}; - -} // namespace ui - -#endif // SERVICES_UI_COMMON_MOJO_BUFFER_BACKING_H_
diff --git a/services/ui/common/mojo_gpu_memory_buffer.cc b/services/ui/common/mojo_gpu_memory_buffer.cc deleted file mode 100644 index d5c2efa..0000000 --- a/services/ui/common/mojo_gpu_memory_buffer.cc +++ /dev/null
@@ -1,107 +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. - -#include "services/ui/common/mojo_gpu_memory_buffer.h" - -#include <stdint.h> - -#include "base/logging.h" -#include "base/memory/ptr_util.h" -#include "base/memory/shared_memory.h" -#include "base/numerics/safe_conversions.h" -#include "build/build_config.h" -#include "mojo/public/cpp/system/buffer.h" -#include "mojo/public/cpp/system/platform_handle.h" -#include "ui/gfx/buffer_format_util.h" - -namespace ui { - -MojoGpuMemoryBufferImpl::MojoGpuMemoryBufferImpl( - const gfx::Size& size, - gfx::BufferFormat format, - std::unique_ptr<base::SharedMemory> shared_memory) - : GpuMemoryBufferImpl(gfx::GenericSharedMemoryId(0), size, format), - shared_memory_(std::move(shared_memory)) {} - -// TODO(rjkroege): Support running a destructor callback as necessary. -MojoGpuMemoryBufferImpl::~MojoGpuMemoryBufferImpl() {} - -std::unique_ptr<gfx::GpuMemoryBuffer> MojoGpuMemoryBufferImpl::Create( - const gfx::Size& size, - gfx::BufferFormat format, - gfx::BufferUsage usage) { - size_t bytes = gfx::BufferSizeForBufferFormat(size, format); - - mojo::ScopedSharedBufferHandle handle = - mojo::SharedBufferHandle::Create(bytes); - if (!handle.is_valid()) - return nullptr; - - base::SharedMemoryHandle platform_handle; - size_t shared_memory_size; - bool readonly; - MojoResult result = mojo::UnwrapSharedMemoryHandle( - std::move(handle), &platform_handle, &shared_memory_size, &readonly); - if (result != MOJO_RESULT_OK) - return nullptr; - DCHECK_EQ(shared_memory_size, bytes); - - auto shared_memory = - base::MakeUnique<base::SharedMemory>(platform_handle, readonly); - return base::WrapUnique<gfx::GpuMemoryBuffer>( - new MojoGpuMemoryBufferImpl(size, format, std::move(shared_memory))); -} - -MojoGpuMemoryBufferImpl* MojoGpuMemoryBufferImpl::FromClientBuffer( - ClientBuffer buffer) { - return reinterpret_cast<MojoGpuMemoryBufferImpl*>(buffer); -} - -const unsigned char* MojoGpuMemoryBufferImpl::GetMemory() const { - return static_cast<const unsigned char*>(shared_memory_->memory()); -} - -bool MojoGpuMemoryBufferImpl::Map() { - DCHECK(!mapped_); - if (!shared_memory_->Map(gfx::BufferSizeForBufferFormat(size_, format_))) - return false; - mapped_ = true; - return true; -} - -void* MojoGpuMemoryBufferImpl::memory(size_t plane) { - DCHECK(mapped_); - DCHECK_LT(plane, gfx::NumberOfPlanesForBufferFormat(format_)); - return reinterpret_cast<uint8_t*>(shared_memory_->memory()) + - gfx::BufferOffsetForBufferFormat(size_, format_, plane); -} - -void MojoGpuMemoryBufferImpl::Unmap() { - DCHECK(mapped_); - shared_memory_->Unmap(); - mapped_ = false; -} - -int MojoGpuMemoryBufferImpl::stride(size_t plane) const { - DCHECK_LT(plane, gfx::NumberOfPlanesForBufferFormat(format_)); - return base::checked_cast<int>(gfx::RowSizeForBufferFormat( - size_.width(), format_, static_cast<int>(plane))); -} - -gfx::GpuMemoryBufferHandle MojoGpuMemoryBufferImpl::GetHandle() const { - gfx::GpuMemoryBufferHandle handle; - handle.type = gfx::SHARED_MEMORY_BUFFER; - handle.handle = shared_memory_->handle(); - handle.offset = 0; - handle.stride = static_cast<int32_t>( - gfx::RowSizeForBufferFormat(size_.width(), format_, 0)); - - return handle; -} - -gfx::GpuMemoryBufferType MojoGpuMemoryBufferImpl::GetBufferType() const { - return gfx::SHARED_MEMORY_BUFFER; -} - -} // namespace ui
diff --git a/services/ui/common/mojo_gpu_memory_buffer.h b/services/ui/common/mojo_gpu_memory_buffer.h deleted file mode 100644 index 21ab5f3..0000000 --- a/services/ui/common/mojo_gpu_memory_buffer.h +++ /dev/null
@@ -1,54 +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. - -#ifndef SERVICES_UI_COMMON_MOJO_GPU_MEMORY_BUFFER_H_ -#define SERVICES_UI_COMMON_MOJO_GPU_MEMORY_BUFFER_H_ - -#include <stddef.h> - -#include <memory> - -#include "base/macros.h" -#include "services/ui/common/gpu_memory_buffer_impl.h" -#include "services/ui/common/mus_common_export.h" -#include "ui/gfx/geometry/size.h" -#include "ui/gfx/gpu_memory_buffer.h" - -namespace ui { - -class MUS_COMMON_EXPORT MojoGpuMemoryBufferImpl - : public ui::GpuMemoryBufferImpl { - public: - MojoGpuMemoryBufferImpl(const gfx::Size& size, - gfx::BufferFormat format, - std::unique_ptr<base::SharedMemory> shared_memory); - ~MojoGpuMemoryBufferImpl() override; - - static std::unique_ptr<gfx::GpuMemoryBuffer> Create(const gfx::Size& size, - gfx::BufferFormat format, - gfx::BufferUsage usage); - - static MojoGpuMemoryBufferImpl* FromClientBuffer(ClientBuffer buffer); - - const unsigned char* GetMemory() const; - - // Overridden from gfx::GpuMemoryBuffer: - bool Map() override; - void* memory(size_t plane) override; - void Unmap() override; - int stride(size_t plane) const override; - gfx::GpuMemoryBufferHandle GetHandle() const override; - - // Overridden from gfx::GpuMemoryBufferImpl - gfx::GpuMemoryBufferType GetBufferType() const override; - - private: - std::unique_ptr<base::SharedMemory> shared_memory_; - - DISALLOW_COPY_AND_ASSIGN(MojoGpuMemoryBufferImpl); -}; - -} // namespace ui - -#endif // SERVICES_UI_COMMON_MOJO_GPU_MEMORY_BUFFER_H_
diff --git a/services/ui/common/mojo_gpu_memory_buffer_manager.cc b/services/ui/common/mojo_gpu_memory_buffer_manager.cc deleted file mode 100644 index 7300833..0000000 --- a/services/ui/common/mojo_gpu_memory_buffer_manager.cc +++ /dev/null
@@ -1,46 +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. - -#include "services/ui/common/mojo_gpu_memory_buffer_manager.h" - -#include "base/logging.h" -#include "services/ui/common/mojo_gpu_memory_buffer.h" - -namespace ui { - -MojoGpuMemoryBufferManager::MojoGpuMemoryBufferManager() {} - -MojoGpuMemoryBufferManager::~MojoGpuMemoryBufferManager() {} - -std::unique_ptr<gfx::GpuMemoryBuffer> -MojoGpuMemoryBufferManager::AllocateGpuMemoryBuffer( - const gfx::Size& size, - gfx::BufferFormat format, - gfx::BufferUsage usage, - gpu::SurfaceHandle surface_handle) { - return MojoGpuMemoryBufferImpl::Create(size, format, usage); -} - -std::unique_ptr<gfx::GpuMemoryBuffer> -MojoGpuMemoryBufferManager::CreateGpuMemoryBufferFromHandle( - const gfx::GpuMemoryBufferHandle& handle, - const gfx::Size& size, - gfx::BufferFormat format) { - NOTIMPLEMENTED(); - return nullptr; -} - -gfx::GpuMemoryBuffer* -MojoGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer( - ClientBuffer buffer) { - return MojoGpuMemoryBufferImpl::FromClientBuffer(buffer); -} - -void MojoGpuMemoryBufferManager::SetDestructionSyncToken( - gfx::GpuMemoryBuffer* buffer, - const gpu::SyncToken& sync_token) { - NOTIMPLEMENTED(); -} - -} // namespace ui
diff --git a/services/ui/common/mojo_gpu_memory_buffer_manager.h b/services/ui/common/mojo_gpu_memory_buffer_manager.h deleted file mode 100644 index 85f91d6a..0000000 --- a/services/ui/common/mojo_gpu_memory_buffer_manager.h +++ /dev/null
@@ -1,43 +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. - -#ifndef SERVICES_UI_COMMON_MOJO_GPU_MEMORY_BUFFER_MANAGER_H_ -#define SERVICES_UI_COMMON_MOJO_GPU_MEMORY_BUFFER_MANAGER_H_ - -#include <memory> - -#include "base/macros.h" -#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" -#include "services/ui/common/mus_common_export.h" - -namespace ui { - -class MUS_COMMON_EXPORT MojoGpuMemoryBufferManager - : public gpu::GpuMemoryBufferManager { - public: - MojoGpuMemoryBufferManager(); - ~MojoGpuMemoryBufferManager() override; - - // Overridden from gpu::GpuMemoryBufferManager: - std::unique_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBuffer( - const gfx::Size& size, - gfx::BufferFormat format, - gfx::BufferUsage usage, - gpu::SurfaceHandle surface_handle) override; - std::unique_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBufferFromHandle( - const gfx::GpuMemoryBufferHandle& handle, - const gfx::Size& size, - gfx::BufferFormat format) override; - gfx::GpuMemoryBuffer* GpuMemoryBufferFromClientBuffer( - ClientBuffer buffer) override; - void SetDestructionSyncToken(gfx::GpuMemoryBuffer* buffer, - const gpu::SyncToken& sync_token) override; - - private: - DISALLOW_COPY_AND_ASSIGN(MojoGpuMemoryBufferManager); -}; - -} // namespace ui - -#endif // SERVICES_UI_COMMON_MOJO_GPU_MEMORY_BUFFER_MANAGER_H_
diff --git a/services/ui/demo/mus_demo.cc b/services/ui/demo/mus_demo.cc index 30994adf..0c738f7 100644 --- a/services/ui/demo/mus_demo.cc +++ b/services/ui/demo/mus_demo.cc
@@ -6,8 +6,8 @@ #include "base/time/time.h" #include "services/shell/public/cpp/connector.h" -#include "services/ui/common/gpu_service.h" #include "services/ui/public/cpp/bitmap_uploader.h" +#include "services/ui/public/cpp/gpu_service.h" #include "services/ui/public/cpp/window.h" #include "services/ui/public/cpp/window_tree_client.h" #include "third_party/skia/include/core/SkCanvas.h" @@ -116,7 +116,7 @@ window_ = window; // Initialize bitmap uploader for sending frames to MUS. - uploader_.reset(new ui::BitmapUploader(window_)); + uploader_.reset(new ui::BitmapUploader(window_, gpu_service_.get())); uploader_->Init(); // Draw initial frame and start the timer to regularly draw frames.
diff --git a/services/ui/display/platform_screen.h b/services/ui/display/platform_screen.h index da8aa743..4c3aa45 100644 --- a/services/ui/display/platform_screen.h +++ b/services/ui/display/platform_screen.h
@@ -36,6 +36,8 @@ // its id and bounds for it via |callback|. virtual void ConfigurePhysicalDisplay( const ConfiguredDisplayCallback& callback) = 0; + + virtual int64_t GetPrimaryDisplayId() const = 0; }; } // namespace display
diff --git a/services/ui/display/platform_screen_impl.cc b/services/ui/display/platform_screen_impl.cc index 960c4ca..702906fb 100644 --- a/services/ui/display/platform_screen_impl.cc +++ b/services/ui/display/platform_screen_impl.cc
@@ -13,9 +13,11 @@ namespace display { namespace { +const int64_t kDisplayId = 1; + void FixedSizeScreenConfiguration( const PlatformScreen::ConfiguredDisplayCallback& callback) { - callback.Run(1, gfx::Rect(1024, 768)); + callback.Run(kDisplayId, gfx::Rect(1024, 768)); } } // namespace @@ -37,4 +39,8 @@ FROM_HERE, base::Bind(&FixedSizeScreenConfiguration, callback)); } +int64_t PlatformScreenImpl::GetPrimaryDisplayId() const { + return kDisplayId; +} + } // namespace display
diff --git a/services/ui/display/platform_screen_impl.h b/services/ui/display/platform_screen_impl.h index 1bf5c469..0b5ff5a 100644 --- a/services/ui/display/platform_screen_impl.h +++ b/services/ui/display/platform_screen_impl.h
@@ -24,6 +24,7 @@ void Init() override; void ConfigurePhysicalDisplay( const PlatformScreen::ConfiguredDisplayCallback& callback) override; + int64_t GetPrimaryDisplayId() const override; DISALLOW_COPY_AND_ASSIGN(PlatformScreenImpl); };
diff --git a/services/ui/display/platform_screen_impl_ozone.cc b/services/ui/display/platform_screen_impl_ozone.cc index 9ab9d72..c4f1ada 100644 --- a/services/ui/display/platform_screen_impl_ozone.cc +++ b/services/ui/display/platform_screen_impl_ozone.cc
@@ -4,6 +4,8 @@ #include "services/ui/display/platform_screen_impl_ozone.h" +#include <memory> + #include "base/command_line.h" #include "base/memory/ptr_util.h" #include "base/sys_info.h" @@ -18,24 +20,6 @@ namespace display { namespace { -// TODO(rjkroege): Remove this code once ozone headless has the same -// display creation semantics as ozone drm. -// Some ozone platforms do not configure physical displays and so do not -// callback into this class via the implementation of NativeDisplayObserver. -// FixedSizeScreenConfiguration() short-circuits the implementation of display -// configuration in this case by calling the |callback| provided to -// ConfigurePhysicalDisplay() with a hard-coded |id| and |bounds|. -void FixedSizeScreenConfiguration( - const PlatformScreen::ConfiguredDisplayCallback& callback) { - if (base::CommandLine::ForCurrentProcess()->HasSwitch("multi-display")) { - // This really doesn't work properly. Use at your own risk. - callback.Run(100, gfx::Rect(800, 800)); - callback.Run(200, gfx::Rect(800, 0, 800, 800)); - } else { - callback.Run(100, gfx::Rect(0, 0, 1024, 768)); - } -} - // Needed for DisplayConfigurator::ForceInitialConfigure. const SkColor kChromeOsBootColor = SkColorSetRGB(0xfe, 0xfe, 0xfe); @@ -53,6 +37,9 @@ } void PlatformScreenImplOzone::Init() { + // We want display configuration to happen even off device to keep the control + // flow similar. + display_configurator_.set_configure_display(true); display_configurator_.AddObserver(this); display_configurator_.Init( ui::OzonePlatform::GetInstance()->CreateNativeDisplayDelegate(), false); @@ -60,45 +47,65 @@ void PlatformScreenImplOzone::ConfigurePhysicalDisplay( const PlatformScreen::ConfiguredDisplayCallback& callback) { + callback_ = callback; + if (base::SysInfo::IsRunningOnChromeOS()) { - callback_ = callback; display_configurator_.ForceInitialConfigure(kChromeOsBootColor); } else { - // PostTask()ed to maximize control flow similarity with the ChromeOS case. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&FixedSizeScreenConfiguration, callback)); + if (base::CommandLine::ForCurrentProcess()->HasSwitch("multi-display")) { + // This really doesn't work properly. Use at your own risk. + display_configurator_.AddVirtualDisplay(gfx::Size(800, 800)); + display_configurator_.AddVirtualDisplay(gfx::Size(800, 800)); + } else { + display_configurator_.AddVirtualDisplay(gfx::Size(1024, 768)); + } } } +int64_t PlatformScreenImplOzone::GetPrimaryDisplayId() const { + return primary_display_id_; +} + void PlatformScreenImplOzone::OnDisplayModeChanged( const ui::DisplayConfigurator::DisplayStateList& displays) { - // TODO(kylechar): Remove check when adding/removing displays is supported. - CHECK(!callback_.is_null()); - if (displays.size() > 1) { LOG(ERROR) << "Mus doesn't really support multiple displays, expect it to crash"; } - gfx::Point origin; - for (auto* display : displays) { - const ui::DisplayMode* current_mode = display->current_mode(); - gfx::Rect bounds(origin, current_mode->size()); + // TODO(kylechar): Use DisplayLayout/DisplayLayoutStore here when possible. + std::set<uint64_t> all_displays; + for (ui::DisplaySnapshot* display : displays) { + const int64_t id = display->display_id(); - callback_.Run(display->display_id(), bounds); + all_displays.insert(id); + + if (displays_.find(id) != displays_.end()) + continue; + + const ui::DisplayMode* current_mode = display->current_mode(); + gfx::Rect bounds(next_display_origin_, current_mode->size()); // Move the origin so that next display is to the right of current display. - origin.Offset(current_mode->size().width(), 0); + next_display_origin_.Offset(current_mode->size().width(), 0); + + // The first display added will be our primary display. + if (displays_.empty()) + primary_display_id_ = id; + + // Keep track of what displays have already been added. + displays_.insert(display->display_id()); + + callback_.Run(id, bounds); } - callback_.Reset(); + DCHECK(displays_ == all_displays) << "Removing displays is not supported."; } void PlatformScreenImplOzone::OnDisplayModeChangeFailed( const ui::DisplayConfigurator::DisplayStateList& displays, ui::MultipleDisplayState failed_new_state) { LOG(ERROR) << "OnDisplayModeChangeFailed from DisplayConfigurator"; - callback_.Reset(); } } // namespace display
diff --git a/services/ui/display/platform_screen_impl_ozone.h b/services/ui/display/platform_screen_impl_ozone.h index 025d0c42..0e89b57a 100644 --- a/services/ui/display/platform_screen_impl_ozone.h +++ b/services/ui/display/platform_screen_impl_ozone.h
@@ -7,12 +7,14 @@ #include <stdint.h> +#include <set> #include <vector> #include "base/callback.h" #include "base/macros.h" #include "services/ui/display/platform_screen.h" #include "ui/display/chromeos/display_configurator.h" +#include "ui/display/display.h" namespace display { @@ -30,6 +32,7 @@ // initialized. void ConfigurePhysicalDisplay( const ConfiguredDisplayCallback& callback) override; + int64_t GetPrimaryDisplayId() const override; // ui::DisplayConfigurator::Observer: void OnDisplayModeChanged( @@ -40,7 +43,12 @@ ui::DisplayConfigurator display_configurator_; - // Callback to called when new displays are configured. + // TODO(kylechar): These values can/should be replaced by DisplayLayout. + int64_t primary_display_id_ = display::Display::kInvalidDisplayID; + std::set<uint64_t> displays_; + gfx::Point next_display_origin_; + + // Callback for when new displays are configured. ConfiguredDisplayCallback callback_; DISALLOW_COPY_AND_ASSIGN(PlatformScreenImplOzone);
diff --git a/services/ui/public/cpp/BUILD.gn b/services/ui/public/cpp/BUILD.gn index a4a14d7..72dc57bd 100644 --- a/services/ui/public/cpp/BUILD.gn +++ b/services/ui/public/cpp/BUILD.gn
@@ -2,12 +2,16 @@ # 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") + # This is the public target. It contains only the public headers. The # implementation (and private haders) are in 'internal'. source_set("cpp") { sources = [ "bitmap_uploader.h", + "gpu_service.h", "input_event_handler.h", + "mojo_gpu_memory_buffer_manager.h", "output_surface.h", "property_type_converters.h", "raster_thread_helper.h", @@ -95,8 +99,16 @@ "context_provider.h", "gles2_context.cc", "gles2_context.h", + "gpu_memory_buffer_impl.cc", + "gpu_memory_buffer_impl.h", + "gpu_service.cc", "in_flight_change.cc", "in_flight_change.h", + "mojo_buffer_backing.cc", + "mojo_buffer_backing.h", + "mojo_gpu_memory_buffer.cc", + "mojo_gpu_memory_buffer.h", + "mojo_gpu_memory_buffer_manager.cc", "output_surface.cc", "property_type_converters.cc", "raster_thread_helper.cc", @@ -140,4 +152,8 @@ ] defines = [ "GL_GLEXT_PROTOTYPES" ] + + if (use_ozone) { + deps += [ "//ui/ozone" ] + } }
diff --git a/services/ui/public/cpp/bitmap_uploader.cc b/services/ui/public/cpp/bitmap_uploader.cc index 75af7b3..53e6c17 100644 --- a/services/ui/public/cpp/bitmap_uploader.cc +++ b/services/ui/public/cpp/bitmap_uploader.cc
@@ -27,8 +27,9 @@ const char kBitmapUploaderForAcceleratedWidget[] = "__BITMAP_UPLOADER_ACCELERATED_WIDGET__"; -BitmapUploader::BitmapUploader(Window* window) +BitmapUploader::BitmapUploader(Window* window, GpuService* gpu_service) : window_(window), + gpu_service_(gpu_service), color_(g_transparent_color), width_(0), height_(0), @@ -43,7 +44,7 @@ surface_->BindToThread(); surface_->set_client(this); - gles2_context_ = GLES2Context::CreateOffscreenContext(std::vector<int32_t>()); + gles2_context_ = GLES2Context::CreateOffscreenContext(gpu_service_); // CreateOffscreenContext() may return null. }
diff --git a/services/ui/public/cpp/bitmap_uploader.h b/services/ui/public/cpp/bitmap_uploader.h index 1f0898e..ca659515 100644 --- a/services/ui/public/cpp/bitmap_uploader.h +++ b/services/ui/public/cpp/bitmap_uploader.h
@@ -20,6 +20,7 @@ namespace ui { class GLES2Context; +class GpuService; extern const char kBitmapUploaderForAcceleratedWidget[]; @@ -27,7 +28,7 @@ // Window. class BitmapUploader : public WindowSurfaceClient { public: - explicit BitmapUploader(Window* window); + BitmapUploader(Window* window, GpuService* gpu_service); ~BitmapUploader() override; void Init(); @@ -62,11 +63,12 @@ WindowSurface* surface, mojo::Array<cc::ReturnedResource> resources) override; - ui::Window* window_; - std::unique_ptr<ui::WindowSurface> surface_; + Window* window_; + std::unique_ptr<WindowSurface> surface_; // This may be null if there is an error contacting mus/initializing. We // assume we'll be shutting down soon and do nothing in this case. - std::unique_ptr<ui::GLES2Context> gles2_context_; + std::unique_ptr<GLES2Context> gles2_context_; + GpuService* gpu_service_; uint32_t color_; int width_;
diff --git a/services/ui/public/cpp/command_buffer_client_impl.cc b/services/ui/public/cpp/command_buffer_client_impl.cc index 61b3567..1c8d95e 100644 --- a/services/ui/public/cpp/command_buffer_client_impl.cc +++ b/services/ui/public/cpp/command_buffer_client_impl.cc
@@ -19,8 +19,8 @@ #include "gpu/command_buffer/common/sync_token.h" #include "mojo/public/cpp/system/platform_handle.h" #include "services/ui/common/gpu_type_converters.h" -#include "services/ui/common/mojo_buffer_backing.h" -#include "services/ui/common/mojo_gpu_memory_buffer.h" +#include "services/ui/public/cpp/mojo_buffer_backing.h" +#include "services/ui/public/cpp/mojo_gpu_memory_buffer.h" namespace ui {
diff --git a/services/ui/public/cpp/context_provider.cc b/services/ui/public/cpp/context_provider.cc index bed839e..ec1991c3 100644 --- a/services/ui/public/cpp/context_provider.cc +++ b/services/ui/public/cpp/context_provider.cc
@@ -11,10 +11,11 @@ namespace ui { -ContextProvider::ContextProvider() {} +ContextProvider::ContextProvider(GpuService* gpu_service) + : gpu_service_(gpu_service) {} bool ContextProvider::BindToCurrentThread() { - context_ = GLES2Context::CreateOffscreenContext(std::vector<int32_t>()); + context_ = GLES2Context::CreateOffscreenContext(gpu_service_); return !!context_; }
diff --git a/services/ui/public/cpp/context_provider.h b/services/ui/public/cpp/context_provider.h index f17131e..35c3151 100644 --- a/services/ui/public/cpp/context_provider.h +++ b/services/ui/public/cpp/context_provider.h
@@ -21,10 +21,11 @@ namespace ui { class GLES2Context; +class GpuService; class ContextProvider : public cc::ContextProvider { public: - ContextProvider(); + explicit ContextProvider(GpuService* gpu_service); // cc::ContextProvider implementation. bool BindToCurrentThread() override; @@ -44,6 +45,7 @@ private: std::unique_ptr<GLES2Context> context_; + GpuService* gpu_service_; DISALLOW_COPY_AND_ASSIGN(ContextProvider); };
diff --git a/services/ui/public/cpp/gles2_context.cc b/services/ui/public/cpp/gles2_context.cc index 2049dfb..42fd611 100644 --- a/services/ui/public/cpp/gles2_context.cc +++ b/services/ui/public/cpp/gles2_context.cc
@@ -13,9 +13,10 @@ #include "gpu/command_buffer/client/shared_memory_limits.h" #include "gpu/command_buffer/client/transfer_buffer.h" #include "gpu/ipc/client/command_buffer_proxy_impl.h" +#include "gpu/ipc/client/gpu_channel_host.h" #include "mojo/public/cpp/system/core.h" -#include "services/ui/common/gpu_service.h" #include "services/ui/public/cpp/command_buffer_client_impl.h" +#include "services/ui/public/cpp/gpu_service.h" #include "services/ui/public/interfaces/command_buffer.mojom.h" #include "services/ui/public/interfaces/gpu_service.mojom.h" #include "url/gurl.h" @@ -26,9 +27,9 @@ GLES2Context::~GLES2Context() {} -bool GLES2Context::Initialize(const std::vector<int32_t>& attribs) { +bool GLES2Context::Initialize(GpuService* gpu_service) { scoped_refptr<gpu::GpuChannelHost> gpu_channel_host = - GpuService::GetInstance()->EstablishGpuChannelSync(); + gpu_service->EstablishGpuChannelSync(); if (!gpu_channel_host) return false; gpu::SurfaceHandle surface_handle = gfx::kNullAcceleratedWidget; @@ -41,8 +42,6 @@ GURL active_url; scoped_refptr<base::SingleThreadTaskRunner> task_runner = base::ThreadTaskRunnerHandle::Get(); - if (!attributes.Parse(attribs)) - return false; command_buffer_proxy_impl_ = gpu::CommandBufferProxyImpl::Create( std::move(gpu_channel_host), surface_handle, shared_command_buffer, stream_id, stream_priority, attributes, active_url, @@ -79,9 +78,9 @@ // static std::unique_ptr<GLES2Context> GLES2Context::CreateOffscreenContext( - const std::vector<int32_t>& attribs) { + GpuService* gpu_service) { std::unique_ptr<GLES2Context> gles2_context(new GLES2Context); - if (!gles2_context->Initialize(attribs)) + if (!gles2_context->Initialize(gpu_service)) gles2_context.reset(); return gles2_context; }
diff --git a/services/ui/public/cpp/gles2_context.h b/services/ui/public/cpp/gles2_context.h index d26499d7..a4e5603 100644 --- a/services/ui/public/cpp/gles2_context.h +++ b/services/ui/public/cpp/gles2_context.h
@@ -25,6 +25,7 @@ namespace ui { class CommandBufferClientImpl; +class GpuService; class GLES2Context { public: @@ -35,11 +36,11 @@ gpu::ContextSupport* context_support() const { return implementation_.get(); } static std::unique_ptr<GLES2Context> CreateOffscreenContext( - const std::vector<int32_t>& attribs); + GpuService* gpu_service); private: GLES2Context(); - bool Initialize(const std::vector<int32_t>& attribs); + bool Initialize(GpuService* gpu_service); std::unique_ptr<CommandBufferClientImpl> command_buffer_client_impl_; std::unique_ptr<gpu::CommandBufferProxyImpl> command_buffer_proxy_impl_;
diff --git a/services/ui/public/cpp/gpu_memory_buffer_impl.cc b/services/ui/public/cpp/gpu_memory_buffer_impl.cc new file mode 100644 index 0000000..a4bac65 --- /dev/null +++ b/services/ui/public/cpp/gpu_memory_buffer_impl.cc
@@ -0,0 +1,46 @@ +// 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 "services/ui/public/cpp/gpu_memory_buffer_impl.h" + +namespace ui { + +GpuMemoryBufferImpl::GpuMemoryBufferImpl(gfx::GpuMemoryBufferId id, + const gfx::Size& size, + gfx::BufferFormat format) + : id_(id), size_(size), format_(format), mapped_(false) {} + +GpuMemoryBufferImpl::~GpuMemoryBufferImpl() { + DCHECK(!mapped_); +} + +// static +GpuMemoryBufferImpl* GpuMemoryBufferImpl::FromClientBuffer( + ClientBuffer buffer) { + return reinterpret_cast<GpuMemoryBufferImpl*>(buffer); +} + +gfx::Size GpuMemoryBufferImpl::GetSize() const { + return size_; +} + +gfx::BufferFormat GpuMemoryBufferImpl::GetFormat() const { + return format_; +} + +gfx::GpuMemoryBufferId GpuMemoryBufferImpl::GetId() const { + return id_; +} + +ClientBuffer GpuMemoryBufferImpl::AsClientBuffer() { + return reinterpret_cast<ClientBuffer>(this); +} + +#if defined(USE_OZONE) +scoped_refptr<ui::NativePixmap> GpuMemoryBufferImpl::GetNativePixmap() { + return scoped_refptr<ui::NativePixmap>(); +} +#endif + +} // namespace ui
diff --git a/services/ui/public/cpp/gpu_memory_buffer_impl.h b/services/ui/public/cpp/gpu_memory_buffer_impl.h new file mode 100644 index 0000000..9ff1852 --- /dev/null +++ b/services/ui/public/cpp/gpu_memory_buffer_impl.h
@@ -0,0 +1,60 @@ +// Copyright 2016 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 SERVICES_UI_PUBLIC_CPP_GPU_MEMORY_BUFFER_IMPL_H_ +#define SERVICES_UI_PUBLIC_CPP_GPU_MEMORY_BUFFER_IMPL_H_ + +#include <memory> + +#include "base/callback.h" +#include "base/macros.h" +#include "gpu/command_buffer/common/sync_token.h" +#include "ui/gfx/geometry/size.h" +#include "ui/gfx/gpu_memory_buffer.h" + +#if defined(USE_OZONE) +#include "ui/ozone/public/native_pixmap.h" +#endif + +namespace ui { + +// Provides common implementation of a GPU memory buffer. +class GpuMemoryBufferImpl : public gfx::GpuMemoryBuffer { + public: + ~GpuMemoryBufferImpl() override; + + // Type-checking upcast routine. Returns an NULL on failure. + static GpuMemoryBufferImpl* FromClientBuffer(ClientBuffer buffer); + + // Overridden from gfx::GpuMemoryBuffer: + gfx::Size GetSize() const override; + gfx::BufferFormat GetFormat() const override; + gfx::GpuMemoryBufferId GetId() const override; + ClientBuffer AsClientBuffer() override; + + // Returns the type of this GpuMemoryBufferImpl. + virtual gfx::GpuMemoryBufferType GetBufferType() const = 0; + +#if defined(USE_OZONE) + // Returns a ui::NativePixmap when one is available. + virtual scoped_refptr<ui::NativePixmap> GetNativePixmap(); +#endif + + protected: + GpuMemoryBufferImpl(gfx::GpuMemoryBufferId id, + const gfx::Size& size, + gfx::BufferFormat format); + + const gfx::GpuMemoryBufferId id_; + const gfx::Size size_; + const gfx::BufferFormat format_; + bool mapped_; + + private: + DISALLOW_COPY_AND_ASSIGN(GpuMemoryBufferImpl); +}; + +} // namespace ui + +#endif // SERVICES_UI_PUBLIC_CPP_GPU_MEMORY_BUFFER_IMPL_H_
diff --git a/services/ui/public/cpp/gpu_service.cc b/services/ui/public/cpp/gpu_service.cc new file mode 100644 index 0000000..5951e69 --- /dev/null +++ b/services/ui/public/cpp/gpu_service.cc
@@ -0,0 +1,226 @@ +// Copyright 2016 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 "services/ui/public/cpp/gpu_service.h" + +#include "base/command_line.h" +#include "base/memory/singleton.h" +#include "base/threading/thread_task_runner_handle.h" +#include "build/build_config.h" +#include "mojo/public/cpp/bindings/sync_call_restrictions.h" +#include "mojo/public/cpp/system/platform_handle.h" +#include "services/shell/public/cpp/connector.h" +#include "services/ui/common/gpu_type_converters.h" +#include "services/ui/common/switches.h" +#include "services/ui/public/cpp/mojo_gpu_memory_buffer_manager.h" +#include "services/ui/public/interfaces/gpu_service.mojom.h" + +namespace ui { + +namespace { + +void PostTask(scoped_refptr<base::SingleThreadTaskRunner> runner, + const tracked_objects::Location& from_here, + const gpu::GpuChannelEstablishedCallback& callback, + scoped_refptr<gpu::GpuChannelHost> established_channel_host) { + runner->PostTask(from_here, + base::Bind(callback, std::move(established_channel_host))); +} + +} // namespace + +GpuService::GpuService(shell::Connector* connector) + : main_task_runner_(base::ThreadTaskRunnerHandle::Get()), + connector_(connector), + shutdown_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC, + base::WaitableEvent::InitialState::NOT_SIGNALED), + io_thread_("GPUIOThread"), + gpu_memory_buffer_manager_(new MojoGpuMemoryBufferManager), + is_establishing_(false), + establishing_condition_(&lock_) { + DCHECK(main_task_runner_); + DCHECK(connector_); + base::Thread::Options thread_options(base::MessageLoop::TYPE_IO, 0); + thread_options.priority = base::ThreadPriority::NORMAL; + CHECK(io_thread_.StartWithOptions(thread_options)); +} + +GpuService::~GpuService() { + DCHECK(IsMainThread()); + if (gpu_channel_) + gpu_channel_->DestroyChannel(); +} + +// static +std::unique_ptr<GpuService> GpuService::Initialize( + shell::Connector* connector) { + return base::WrapUnique(new GpuService(connector)); +} + +void GpuService::EstablishGpuChannel( + const gpu::GpuChannelEstablishedCallback& callback) { + base::AutoLock auto_lock(lock_); + auto runner = base::ThreadTaskRunnerHandle::Get(); + scoped_refptr<gpu::GpuChannelHost> channel = GetGpuChannelLocked(); + if (channel) { + PostTask(runner, FROM_HERE, callback, std::move(channel)); + return; + } + establish_callbacks_.push_back( + base::Bind(PostTask, runner, FROM_HERE, callback)); + if (!is_establishing_) { + is_establishing_ = true; + main_task_runner_->PostTask( + FROM_HERE, base::Bind(&GpuService::EstablishGpuChannelOnMainThread, + base::Unretained(this))); + } +} + +scoped_refptr<gpu::GpuChannelHost> GpuService::EstablishGpuChannelSync() { + base::AutoLock auto_lock(lock_); + if (GetGpuChannelLocked()) + return gpu_channel_; + + if (IsMainThread()) { + is_establishing_ = true; + EstablishGpuChannelOnMainThreadSyncLocked(); + } else { + if (!is_establishing_) { + // Create an establishing gpu channel task, if there isn't one. + is_establishing_ = true; + main_task_runner_->PostTask( + FROM_HERE, base::Bind(&GpuService::EstablishGpuChannelOnMainThread, + base::Unretained(this))); + } + + // Wait until the pending establishing task is finished. + do { + establishing_condition_.Wait(); + } while (is_establishing_); + } + return gpu_channel_; +} + +scoped_refptr<gpu::GpuChannelHost> GpuService::GetGpuChannelLocked() { + if (gpu_channel_ && gpu_channel_->IsLost()) { + main_task_runner_->PostTask( + FROM_HERE, + base::Bind(&gpu::GpuChannelHost::DestroyChannel, gpu_channel_)); + gpu_channel_ = nullptr; + } + return gpu_channel_; +} + +void GpuService::EstablishGpuChannelOnMainThread() { + base::AutoLock auto_lock(lock_); + DCHECK(IsMainThread()); + + // In GpuService::EstablishGpuChannelOnMainThreadSyncLocked(), we use the sync + // mojo EstablishGpuChannel call, after that call the gpu_service_ will be + // reset immediatelly. So gpu_service_ should be always null here. + DCHECK(!gpu_service_); + + // is_establishing_ is false, it means GpuService::EstablishGpuChannelSync() + // has been used, and we don't need try to establish a new GPU channel + // anymore. + if (!is_establishing_) + return; + + connector_->ConnectToInterface("mojo:ui", &gpu_service_); + const bool locked = false; + gpu_service_->EstablishGpuChannel( + base::Bind(&GpuService::EstablishGpuChannelOnMainThreadDone, + base::Unretained(this), locked)); +} + +void GpuService::EstablishGpuChannelOnMainThreadSyncLocked() { + DCHECK(IsMainThread()); + DCHECK(is_establishing_); + + // In browser process, EstablishGpuChannelSync() is only used by testing & + // GpuProcessTransportFactory::GetGLHelper(). For GetGLHelper(), it expects + // the gpu channel has been established, so it should not reach here. + // For testing, the asyc method should not be used. + // In renderer process, we only use EstablishGpuChannelSync(). + // So the gpu_service_ should be null here. + DCHECK(!gpu_service_); + + int client_id = 0; + mojom::ChannelHandlePtr channel_handle; + mojom::GpuInfoPtr gpu_info; + connector_->ConnectToInterface("mojo:ui", &gpu_service_); + { + base::AutoUnlock auto_unlock(lock_); + mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync_call; + if (!gpu_service_->EstablishGpuChannel(&client_id, &channel_handle, + &gpu_info)) { + DLOG(WARNING) + << "Channel encountered error while establishing gpu channel."; + return; + } + } + const bool locked = true; + EstablishGpuChannelOnMainThreadDone( + locked, client_id, std::move(channel_handle), std::move(gpu_info)); +} + +void GpuService::EstablishGpuChannelOnMainThreadDone( + bool locked, + int client_id, + mojom::ChannelHandlePtr channel_handle, + mojom::GpuInfoPtr gpu_info) { + DCHECK(IsMainThread()); + scoped_refptr<gpu::GpuChannelHost> gpu_channel; + if (client_id) { + // TODO(penghuang): Get the real gpu info from mus. + gpu_channel = gpu::GpuChannelHost::Create( + this, client_id, gpu::GPUInfo(), + channel_handle.To<IPC::ChannelHandle>(), &shutdown_event_, + gpu_memory_buffer_manager_.get()); + } + + auto auto_lock = base::WrapUnique<base::AutoLock>( + locked ? nullptr : new base::AutoLock(lock_)); + DCHECK(is_establishing_); + DCHECK(!gpu_channel_); + + is_establishing_ = false; + gpu_channel_ = gpu_channel; + establishing_condition_.Broadcast(); + gpu_service_.reset(); + + for (const auto& i : establish_callbacks_) + i.Run(gpu_channel_); + establish_callbacks_.clear(); +} + +bool GpuService::IsMainThread() { + return main_task_runner_->BelongsToCurrentThread(); +} + +scoped_refptr<base::SingleThreadTaskRunner> +GpuService::GetIOThreadTaskRunner() { + return io_thread_.task_runner(); +} + +std::unique_ptr<base::SharedMemory> GpuService::AllocateSharedMemory( + size_t size) { + mojo::ScopedSharedBufferHandle handle = + mojo::SharedBufferHandle::Create(size); + if (!handle.is_valid()) + return nullptr; + + base::SharedMemoryHandle platform_handle; + size_t shared_memory_size; + bool readonly; + MojoResult result = mojo::UnwrapSharedMemoryHandle( + std::move(handle), &platform_handle, &shared_memory_size, &readonly); + if (result != MOJO_RESULT_OK) + return nullptr; + DCHECK_EQ(shared_memory_size, size); + + return base::MakeUnique<base::SharedMemory>(platform_handle, readonly); +} + +} // namespace ui
diff --git a/services/ui/public/cpp/gpu_service.h b/services/ui/public/cpp/gpu_service.h new file mode 100644 index 0000000..ad208913 --- /dev/null +++ b/services/ui/public/cpp/gpu_service.h
@@ -0,0 +1,84 @@ +// Copyright 2016 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 SERVICES_UI_PUBLIC_CPP_GPU_SERVICE_H_ +#define SERVICES_UI_PUBLIC_CPP_GPU_SERVICE_H_ + +#include <stdint.h> +#include <vector> + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/single_thread_task_runner.h" +#include "base/synchronization/lock.h" +#include "base/synchronization/waitable_event.h" +#include "base/threading/thread.h" +#include "gpu/ipc/client/gpu_channel_host.h" +#include "services/ui/public/cpp/mojo_gpu_memory_buffer_manager.h" +#include "services/ui/public/interfaces/gpu_service.mojom.h" + +namespace shell { +class Connector; +} + +namespace ui { + +class GpuService : public gpu::GpuChannelHostFactory, + public gpu::GpuChannelEstablishFactory { + public: + ~GpuService() override; + + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager() const { + return gpu_memory_buffer_manager_.get(); + } + + // The GpuService has to be initialized in the main thread before establishing + // the gpu channel. + static std::unique_ptr<GpuService> Initialize(shell::Connector* connector); + + // gpu::GpuChannelEstablishFactory: + void EstablishGpuChannel( + const gpu::GpuChannelEstablishedCallback& callback) override; + scoped_refptr<gpu::GpuChannelHost> EstablishGpuChannelSync() override; + + private: + friend struct base::DefaultSingletonTraits<GpuService>; + + explicit GpuService(shell::Connector* connector); + + scoped_refptr<gpu::GpuChannelHost> GetGpuChannelLocked(); + void EstablishGpuChannelOnMainThread(); + void EstablishGpuChannelOnMainThreadSyncLocked(); + void EstablishGpuChannelOnMainThreadDone( + bool locked, + int client_id, + mojom::ChannelHandlePtr channel_handle, + mojom::GpuInfoPtr gpu_info); + + // gpu::GpuChannelHostFactory overrides: + bool IsMainThread() override; + scoped_refptr<base::SingleThreadTaskRunner> GetIOThreadTaskRunner() override; + std::unique_ptr<base::SharedMemory> AllocateSharedMemory( + size_t size) override; + + scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; + shell::Connector* connector_; + base::WaitableEvent shutdown_event_; + base::Thread io_thread_; + std::unique_ptr<MojoGpuMemoryBufferManager> gpu_memory_buffer_manager_; + + // Lock for |gpu_channel_|, |establish_callbacks_| & |is_establishing_|. + base::Lock lock_; + bool is_establishing_; + ui::mojom::GpuServicePtr gpu_service_; + scoped_refptr<gpu::GpuChannelHost> gpu_channel_; + std::vector<gpu::GpuChannelEstablishedCallback> establish_callbacks_; + base::ConditionVariable establishing_condition_; + + DISALLOW_COPY_AND_ASSIGN(GpuService); +}; + +} // namespace ui + +#endif // SERVICES_UI_PUBLIC_CPP_GPU_SERVICE_H_
diff --git a/services/ui/public/cpp/mojo_buffer_backing.cc b/services/ui/public/cpp/mojo_buffer_backing.cc new file mode 100644 index 0000000..6811201 --- /dev/null +++ b/services/ui/public/cpp/mojo_buffer_backing.cc
@@ -0,0 +1,34 @@ +// 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 "services/ui/public/cpp/mojo_buffer_backing.h" + +#include "base/logging.h" +#include "base/memory/ptr_util.h" + +namespace ui { + +MojoBufferBacking::MojoBufferBacking(mojo::ScopedSharedBufferMapping mapping, + size_t size) + : mapping_(std::move(mapping)), size_(size) {} + +MojoBufferBacking::~MojoBufferBacking() = default; + +// static +std::unique_ptr<gpu::BufferBacking> MojoBufferBacking::Create( + mojo::ScopedSharedBufferHandle handle, + size_t size) { + mojo::ScopedSharedBufferMapping mapping = handle->Map(size); + if (!mapping) + return nullptr; + return base::MakeUnique<MojoBufferBacking>(std::move(mapping), size); +} +void* MojoBufferBacking::GetMemory() const { + return mapping_.get(); +} +size_t MojoBufferBacking::GetSize() const { + return size_; +} + +} // namespace ui
diff --git a/services/ui/public/cpp/mojo_buffer_backing.h b/services/ui/public/cpp/mojo_buffer_backing.h new file mode 100644 index 0000000..c1b94df --- /dev/null +++ b/services/ui/public/cpp/mojo_buffer_backing.h
@@ -0,0 +1,39 @@ +// 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 SERVICES_UI_PUBLIC_CPP_MOJO_BUFFER_BACKING_H_ +#define SERVICES_UI_PUBLIC_CPP_MOJO_BUFFER_BACKING_H_ + +#include <stddef.h> + +#include <memory> + +#include "base/macros.h" +#include "gpu/command_buffer/common/buffer.h" +#include "mojo/public/cpp/system/core.h" + +namespace ui { + +class MojoBufferBacking : public gpu::BufferBacking { + public: + MojoBufferBacking(mojo::ScopedSharedBufferMapping mapping, size_t size); + ~MojoBufferBacking() override; + + static std::unique_ptr<gpu::BufferBacking> Create( + mojo::ScopedSharedBufferHandle handle, + size_t size); + + void* GetMemory() const override; + size_t GetSize() const override; + + private: + mojo::ScopedSharedBufferMapping mapping_; + size_t size_; + + DISALLOW_COPY_AND_ASSIGN(MojoBufferBacking); +}; + +} // namespace ui + +#endif // SERVICES_UI_PUBLIC_CPP_MOJO_BUFFER_BACKING_H_
diff --git a/services/ui/public/cpp/mojo_gpu_memory_buffer.cc b/services/ui/public/cpp/mojo_gpu_memory_buffer.cc new file mode 100644 index 0000000..fcc89b5 --- /dev/null +++ b/services/ui/public/cpp/mojo_gpu_memory_buffer.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 "services/ui/public/cpp/mojo_gpu_memory_buffer.h" + +#include <stdint.h> + +#include "base/logging.h" +#include "base/memory/ptr_util.h" +#include "base/memory/shared_memory.h" +#include "base/numerics/safe_conversions.h" +#include "build/build_config.h" +#include "mojo/public/cpp/system/buffer.h" +#include "mojo/public/cpp/system/platform_handle.h" +#include "ui/gfx/buffer_format_util.h" + +namespace ui { + +MojoGpuMemoryBufferImpl::MojoGpuMemoryBufferImpl( + const gfx::Size& size, + gfx::BufferFormat format, + std::unique_ptr<base::SharedMemory> shared_memory) + : GpuMemoryBufferImpl(gfx::GenericSharedMemoryId(0), size, format), + shared_memory_(std::move(shared_memory)) {} + +// TODO(rjkroege): Support running a destructor callback as necessary. +MojoGpuMemoryBufferImpl::~MojoGpuMemoryBufferImpl() {} + +std::unique_ptr<gfx::GpuMemoryBuffer> MojoGpuMemoryBufferImpl::Create( + const gfx::Size& size, + gfx::BufferFormat format, + gfx::BufferUsage usage) { + size_t bytes = gfx::BufferSizeForBufferFormat(size, format); + + mojo::ScopedSharedBufferHandle handle = + mojo::SharedBufferHandle::Create(bytes); + if (!handle.is_valid()) + return nullptr; + + base::SharedMemoryHandle platform_handle; + size_t shared_memory_size; + bool readonly; + MojoResult result = mojo::UnwrapSharedMemoryHandle( + std::move(handle), &platform_handle, &shared_memory_size, &readonly); + if (result != MOJO_RESULT_OK) + return nullptr; + DCHECK_EQ(shared_memory_size, bytes); + + auto shared_memory = + base::MakeUnique<base::SharedMemory>(platform_handle, readonly); + return base::WrapUnique<gfx::GpuMemoryBuffer>( + new MojoGpuMemoryBufferImpl(size, format, std::move(shared_memory))); +} + +MojoGpuMemoryBufferImpl* MojoGpuMemoryBufferImpl::FromClientBuffer( + ClientBuffer buffer) { + return reinterpret_cast<MojoGpuMemoryBufferImpl*>(buffer); +} + +const unsigned char* MojoGpuMemoryBufferImpl::GetMemory() const { + return static_cast<const unsigned char*>(shared_memory_->memory()); +} + +bool MojoGpuMemoryBufferImpl::Map() { + DCHECK(!mapped_); + if (!shared_memory_->Map(gfx::BufferSizeForBufferFormat(size_, format_))) + return false; + mapped_ = true; + return true; +} + +void* MojoGpuMemoryBufferImpl::memory(size_t plane) { + DCHECK(mapped_); + DCHECK_LT(plane, gfx::NumberOfPlanesForBufferFormat(format_)); + return reinterpret_cast<uint8_t*>(shared_memory_->memory()) + + gfx::BufferOffsetForBufferFormat(size_, format_, plane); +} + +void MojoGpuMemoryBufferImpl::Unmap() { + DCHECK(mapped_); + shared_memory_->Unmap(); + mapped_ = false; +} + +int MojoGpuMemoryBufferImpl::stride(size_t plane) const { + DCHECK_LT(plane, gfx::NumberOfPlanesForBufferFormat(format_)); + return base::checked_cast<int>(gfx::RowSizeForBufferFormat( + size_.width(), format_, static_cast<int>(plane))); +} + +gfx::GpuMemoryBufferHandle MojoGpuMemoryBufferImpl::GetHandle() const { + gfx::GpuMemoryBufferHandle handle; + handle.type = gfx::SHARED_MEMORY_BUFFER; + handle.handle = shared_memory_->handle(); + handle.offset = 0; + handle.stride = static_cast<int32_t>( + gfx::RowSizeForBufferFormat(size_.width(), format_, 0)); + + return handle; +} + +gfx::GpuMemoryBufferType MojoGpuMemoryBufferImpl::GetBufferType() const { + return gfx::SHARED_MEMORY_BUFFER; +} + +} // namespace ui
diff --git a/services/ui/public/cpp/mojo_gpu_memory_buffer.h b/services/ui/public/cpp/mojo_gpu_memory_buffer.h new file mode 100644 index 0000000..4ba125b2 --- /dev/null +++ b/services/ui/public/cpp/mojo_gpu_memory_buffer.h
@@ -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. + +#ifndef SERVICES_UI_PUBLIC_CPP_MOJO_GPU_MEMORY_BUFFER_H_ +#define SERVICES_UI_PUBLIC_CPP_MOJO_GPU_MEMORY_BUFFER_H_ + +#include <stddef.h> + +#include <memory> + +#include "base/macros.h" +#include "services/ui/public/cpp/gpu_memory_buffer_impl.h" +#include "ui/gfx/geometry/size.h" +#include "ui/gfx/gpu_memory_buffer.h" + +namespace ui { + +class MojoGpuMemoryBufferImpl : public ui::GpuMemoryBufferImpl { + public: + MojoGpuMemoryBufferImpl(const gfx::Size& size, + gfx::BufferFormat format, + std::unique_ptr<base::SharedMemory> shared_memory); + ~MojoGpuMemoryBufferImpl() override; + + static std::unique_ptr<gfx::GpuMemoryBuffer> Create(const gfx::Size& size, + gfx::BufferFormat format, + gfx::BufferUsage usage); + + static MojoGpuMemoryBufferImpl* FromClientBuffer(ClientBuffer buffer); + + const unsigned char* GetMemory() const; + + // Overridden from gfx::GpuMemoryBuffer: + bool Map() override; + void* memory(size_t plane) override; + void Unmap() override; + int stride(size_t plane) const override; + gfx::GpuMemoryBufferHandle GetHandle() const override; + + // Overridden from gfx::GpuMemoryBufferImpl + gfx::GpuMemoryBufferType GetBufferType() const override; + + private: + std::unique_ptr<base::SharedMemory> shared_memory_; + + DISALLOW_COPY_AND_ASSIGN(MojoGpuMemoryBufferImpl); +}; + +} // namespace ui + +#endif // SERVICES_UI_PUBLIC_CPP_MOJO_GPU_MEMORY_BUFFER_H_
diff --git a/services/ui/public/cpp/mojo_gpu_memory_buffer_manager.cc b/services/ui/public/cpp/mojo_gpu_memory_buffer_manager.cc new file mode 100644 index 0000000..029b1c8 --- /dev/null +++ b/services/ui/public/cpp/mojo_gpu_memory_buffer_manager.cc
@@ -0,0 +1,46 @@ +// 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 "services/ui/public/cpp/mojo_gpu_memory_buffer_manager.h" + +#include "base/logging.h" +#include "services/ui/public/cpp/mojo_gpu_memory_buffer.h" + +namespace ui { + +MojoGpuMemoryBufferManager::MojoGpuMemoryBufferManager() {} + +MojoGpuMemoryBufferManager::~MojoGpuMemoryBufferManager() {} + +std::unique_ptr<gfx::GpuMemoryBuffer> +MojoGpuMemoryBufferManager::AllocateGpuMemoryBuffer( + const gfx::Size& size, + gfx::BufferFormat format, + gfx::BufferUsage usage, + gpu::SurfaceHandle surface_handle) { + return MojoGpuMemoryBufferImpl::Create(size, format, usage); +} + +std::unique_ptr<gfx::GpuMemoryBuffer> +MojoGpuMemoryBufferManager::CreateGpuMemoryBufferFromHandle( + const gfx::GpuMemoryBufferHandle& handle, + const gfx::Size& size, + gfx::BufferFormat format) { + NOTIMPLEMENTED(); + return nullptr; +} + +gfx::GpuMemoryBuffer* +MojoGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer( + ClientBuffer buffer) { + return MojoGpuMemoryBufferImpl::FromClientBuffer(buffer); +} + +void MojoGpuMemoryBufferManager::SetDestructionSyncToken( + gfx::GpuMemoryBuffer* buffer, + const gpu::SyncToken& sync_token) { + NOTIMPLEMENTED(); +} + +} // namespace ui
diff --git a/services/ui/public/cpp/mojo_gpu_memory_buffer_manager.h b/services/ui/public/cpp/mojo_gpu_memory_buffer_manager.h new file mode 100644 index 0000000..a390ff6 --- /dev/null +++ b/services/ui/public/cpp/mojo_gpu_memory_buffer_manager.h
@@ -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. + +#ifndef SERVICES_UI_PUBLIC_CPP_MOJO_GPU_MEMORY_BUFFER_MANAGER_H_ +#define SERVICES_UI_PUBLIC_CPP_MOJO_GPU_MEMORY_BUFFER_MANAGER_H_ + +#include <memory> + +#include "base/macros.h" +#include "gpu/command_buffer/client/gpu_memory_buffer_manager.h" + +namespace ui { + +class MojoGpuMemoryBufferManager : public gpu::GpuMemoryBufferManager { + public: + MojoGpuMemoryBufferManager(); + ~MojoGpuMemoryBufferManager() override; + + // Overridden from gpu::GpuMemoryBufferManager: + std::unique_ptr<gfx::GpuMemoryBuffer> AllocateGpuMemoryBuffer( + const gfx::Size& size, + gfx::BufferFormat format, + gfx::BufferUsage usage, + gpu::SurfaceHandle surface_handle) override; + std::unique_ptr<gfx::GpuMemoryBuffer> CreateGpuMemoryBufferFromHandle( + const gfx::GpuMemoryBufferHandle& handle, + const gfx::Size& size, + gfx::BufferFormat format) override; + gfx::GpuMemoryBuffer* GpuMemoryBufferFromClientBuffer( + ClientBuffer buffer) override; + void SetDestructionSyncToken(gfx::GpuMemoryBuffer* buffer, + const gpu::SyncToken& sync_token) override; + + private: + DISALLOW_COPY_AND_ASSIGN(MojoGpuMemoryBufferManager); +}; + +} // namespace ui + +#endif // SERVICES_UI_PUBLIC_CPP_MOJO_GPU_MEMORY_BUFFER_MANAGER_H_
diff --git a/services/ui/public/cpp/output_surface.cc b/services/ui/public/cpp/output_surface.cc index 5b96e91..ed23696 100644 --- a/services/ui/public/cpp/output_surface.cc +++ b/services/ui/public/cpp/output_surface.cc
@@ -12,8 +12,9 @@ namespace ui { -OutputSurface::OutputSurface(std::unique_ptr<ui::WindowSurface> surface) - : cc::OutputSurface(make_scoped_refptr(new ContextProvider()), +OutputSurface::OutputSurface(GpuService* gpu_service, + std::unique_ptr<ui::WindowSurface> surface) + : cc::OutputSurface(make_scoped_refptr(new ContextProvider(gpu_service)), nullptr, nullptr), surface_(std::move(surface)) {
diff --git a/services/ui/public/cpp/output_surface.h b/services/ui/public/cpp/output_surface.h index fb38073b..1d3c560 100644 --- a/services/ui/public/cpp/output_surface.h +++ b/services/ui/public/cpp/output_surface.h
@@ -14,9 +14,12 @@ namespace ui { +class GpuService; + class OutputSurface : public cc::OutputSurface, public WindowSurfaceClient { public: - explicit OutputSurface(std::unique_ptr<WindowSurface> surface); + OutputSurface(GpuService* gpu_service, + std::unique_ptr<WindowSurface> surface); ~OutputSurface() override; // cc::OutputSurface implementation.
diff --git a/services/ui/public/cpp/tests/BUILD.gn b/services/ui/public/cpp/tests/BUILD.gn index 9467ffa5..98cdbb2 100644 --- a/services/ui/public/cpp/tests/BUILD.gn +++ b/services/ui/public/cpp/tests/BUILD.gn
@@ -22,6 +22,7 @@ "//base", "//services/ui/public/cpp", "//services/ui/public/cpp:internal_or_test", + "//services/ui/public/interfaces", "//testing/gtest", "//ui/display", "//ui/gfx/geometry/mojo",
diff --git a/services/ui/public/cpp/tests/window_tree_client_private.cc b/services/ui/public/cpp/tests/window_tree_client_private.cc index 2595f25..e3a88fe5 100644 --- a/services/ui/public/cpp/tests/window_tree_client_private.cc +++ b/services/ui/public/cpp/tests/window_tree_client_private.cc
@@ -5,6 +5,7 @@ #include "services/ui/public/cpp/tests/window_tree_client_private.h" #include "services/ui/public/cpp/window.h" +#include "services/ui/public/cpp/window_private.h" #include "services/ui/public/cpp/window_tree_client.h" #include "ui/display/display.h" @@ -57,6 +58,13 @@ std::move(event), observer_id); } +void WindowTreeClientPrivate::CallOnCaptureChanged(Window* new_capture, + Window* old_capture) { + tree_client_impl_->OnCaptureChanged( + new_capture ? WindowPrivate(new_capture).server_id() : 0, + old_capture ? WindowPrivate(old_capture).server_id() : 0); +} + void WindowTreeClientPrivate::SetTreeAndClientId(mojom::WindowTree* window_tree, ClientSpecificId client_id) { tree_client_impl_->tree_ = window_tree;
diff --git a/services/ui/public/cpp/tests/window_tree_client_private.h b/services/ui/public/cpp/tests/window_tree_client_private.h index 766b49a..7582c17 100644 --- a/services/ui/public/cpp/tests/window_tree_client_private.h +++ b/services/ui/public/cpp/tests/window_tree_client_private.h
@@ -45,6 +45,8 @@ // Pretends that |event| has been received from the window server. void CallOnWindowInputEvent(Window* window, std::unique_ptr<ui::Event> event); + void CallOnCaptureChanged(Window* new_capture, Window* old_capture); + // Sets the WindowTree and client id. void SetTreeAndClientId(mojom::WindowTree* window_tree, ClientSpecificId client_id);
diff --git a/services/ui/public/cpp/tests/window_tree_client_unittest.cc b/services/ui/public/cpp/tests/window_tree_client_unittest.cc index 14b83a2..b870798a 100644 --- a/services/ui/public/cpp/tests/window_tree_client_unittest.cc +++ b/services/ui/public/cpp/tests/window_tree_client_unittest.cc
@@ -21,6 +21,7 @@ #include "services/ui/public/cpp/window_property.h" #include "services/ui/public/cpp/window_tracker.h" #include "services/ui/public/cpp/window_tree_client_delegate.h" +#include "services/ui/public/cpp/window_tree_client_observer.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/events/event.h" #include "ui/events/event_utils.h" @@ -952,7 +953,7 @@ uint32_t change_id2; ASSERT_FALSE(setup.window_tree()->GetAndClearChangeId(&change_id2)); - setup.window_tree_client()->OnLostCapture(server_id(root)); + setup.window_tree_client()->OnCaptureChanged(0, server_id(root)); EXPECT_FALSE(root->HasCapture()); } @@ -975,7 +976,7 @@ uint32_t change_id2; ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id2)); - setup.window_tree_client()->OnLostCapture(server_id(root)); + setup.window_tree_client()->OnCaptureChanged(0, server_id(root)); EXPECT_FALSE(root->HasCapture()); setup.window_tree_client()->OnChangeCompleted(change_id2, false); @@ -1011,7 +1012,7 @@ EXPECT_FALSE(child->HasCapture()); EXPECT_TRUE(root->HasCapture()); - setup.window_tree_client()->OnLostCapture(server_id(root)); + setup.window_tree_client()->OnCaptureChanged(0, server_id(root)); EXPECT_FALSE(root->HasCapture()); } @@ -1045,4 +1046,86 @@ EXPECT_TRUE(child->HasCapture()); } +namespace { + +class CaptureRecorder : public WindowTreeClientObserver { + public: + explicit CaptureRecorder(WindowTreeClient* tree_client) + : tree_client_(tree_client) { + tree_client_->AddObserver(this); + } + + ~CaptureRecorder() override { tree_client_->RemoveObserver(this); } + + void reset_capture_captured_count() { capture_changed_count_ = 0; } + int capture_changed_count() const { return capture_changed_count_; } + int last_gained_capture_window_id() const { + return last_gained_capture_window_id_; + } + int last_lost_capture_window_id() const { + return last_lost_capture_window_id_; + } + + // WindowTreeClientObserver: + void OnWindowTreeCaptureChanged(Window* gained_capture, + Window* lost_capture) override { + capture_changed_count_++; + last_gained_capture_window_id_ = + gained_capture ? gained_capture->local_id() : 0; + last_lost_capture_window_id_ = lost_capture ? lost_capture->local_id() : 0; + } + + private: + WindowTreeClient* tree_client_; + int capture_changed_count_ = 0; + int last_gained_capture_window_id_ = 0; + int last_lost_capture_window_id_ = 0; + + DISALLOW_COPY_AND_ASSIGN(CaptureRecorder); +}; + +} // namespace + +TEST_F(WindowTreeClientTest, OnWindowTreeCaptureChanged) { + WindowTreeSetup setup; + CaptureRecorder capture_recorder(setup.client()); + Window* root = setup.GetFirstRoot(); + Window* child1 = setup.client()->NewWindow(); + const int child1_id = 1; + child1->set_local_id(child1_id); + child1->SetVisible(true); + root->AddChild(child1); + Window* child2 = setup.client()->NewWindow(); + const int child2_id = 2; + child2->set_local_id(child2_id); + child2->SetVisible(true); + root->AddChild(child2); + + EXPECT_EQ(0, capture_recorder.capture_changed_count()); + // Give capture to child1 and ensure everyone is notified correctly. + child1->SetCapture(); + uint32_t change_id; + ASSERT_TRUE(setup.window_tree()->GetAndClearChangeId(&change_id)); + setup.window_tree_client()->OnChangeCompleted(change_id, true); + EXPECT_EQ(1, capture_recorder.capture_changed_count()); + EXPECT_EQ(child1_id, capture_recorder.last_gained_capture_window_id()); + EXPECT_EQ(0, capture_recorder.last_lost_capture_window_id()); + capture_recorder.reset_capture_captured_count(); + + // Deleting a window with capture should notify observers as well. + child1->Destroy(); + child1 = nullptr; + EXPECT_EQ(1, capture_recorder.capture_changed_count()); + EXPECT_EQ(0, capture_recorder.last_gained_capture_window_id()); + EXPECT_EQ(child1_id, capture_recorder.last_lost_capture_window_id()); + capture_recorder.reset_capture_captured_count(); + + // Changes originating from server should notify observers too. + WindowTreeClientPrivate(setup.client()).CallOnCaptureChanged(child2, nullptr); + EXPECT_EQ(1, capture_recorder.capture_changed_count()); + EXPECT_EQ(child2_id, capture_recorder.last_gained_capture_window_id()); + EXPECT_EQ(0, capture_recorder.last_lost_capture_window_id()); + capture_recorder.reset_capture_captured_count(); +} + } // namespace ui
diff --git a/services/ui/public/cpp/window_tree_client.cc b/services/ui/public/cpp/window_tree_client.cc index e500935..f753fcba 100644 --- a/services/ui/public/cpp/window_tree_client.cc +++ b/services/ui/public/cpp/window_tree_client.cc
@@ -387,6 +387,8 @@ FOR_EACH_OBSERVER(WindowObserver, *WindowPrivate(lost_capture).observers(), OnWindowLostCapture(lost_capture)); } + FOR_EACH_OBSERVER(WindowTreeClientObserver, observers_, + OnWindowTreeCaptureChanged(window, lost_capture)); } void WindowTreeClient::LocalSetFocus(Window* focused) { @@ -752,16 +754,18 @@ WindowPrivate(window).LocalDestroy(); } -void WindowTreeClient::OnLostCapture(Id window_id) { - Window* window = GetWindowByServerId(window_id); - if (!window) +void WindowTreeClient::OnCaptureChanged(Id new_capture_window_id, + Id old_capture_window_id) { + Window* new_capture_window = GetWindowByServerId(new_capture_window_id); + Window* lost_capture_window = GetWindowByServerId(old_capture_window_id); + if (!new_capture_window && !lost_capture_window) return; - InFlightCaptureChange reset_change(this, nullptr); - if (ApplyServerChangeToExistingInFlightChange(reset_change)) + InFlightCaptureChange change(this, new_capture_window); + if (ApplyServerChangeToExistingInFlightChange(change)) return; - LocalSetCapture(nullptr); + LocalSetCapture(new_capture_window); } void WindowTreeClient::OnTopLevelCreated(uint32_t change_id,
diff --git a/services/ui/public/cpp/window_tree_client.h b/services/ui/public/cpp/window_tree_client.h index df1cf0b2..a0223be 100644 --- a/services/ui/public/cpp/window_tree_client.h +++ b/services/ui/public/cpp/window_tree_client.h
@@ -274,7 +274,8 @@ bool drawn) override; void OnEmbeddedAppDisconnected(Id window_id) override; void OnUnembed(Id window_id) override; - void OnLostCapture(Id window_id) override; + void OnCaptureChanged(Id new_capture_window_id, + Id old_capture_window_id) override; void OnTopLevelCreated(uint32_t change_id, mojom::WindowDataPtr data, int64_t display_id,
diff --git a/services/ui/public/cpp/window_tree_client_observer.h b/services/ui/public/cpp/window_tree_client_observer.h index 65f45e1..16d7082 100644 --- a/services/ui/public/cpp/window_tree_client_observer.h +++ b/services/ui/public/cpp/window_tree_client_observer.h
@@ -15,6 +15,9 @@ virtual void OnWindowTreeFocusChanged(Window* gained_focus, Window* lost_focus) {} + virtual void OnWindowTreeCaptureChanged(Window* gained_capture, + Window* lost_capture) {} + // Called early on in the destructor of WindowTreeClient; before any windows // have been destroyed. virtual void OnWillDestroyClient(WindowTreeClient* client) {}
diff --git a/services/ui/public/interfaces/window_tree.mojom b/services/ui/public/interfaces/window_tree.mojom index 14b49d1..e71dd7f 100644 --- a/services/ui/public/interfaces/window_tree.mojom +++ b/services/ui/public/interfaces/window_tree.mojom
@@ -72,8 +72,9 @@ // allowed if the window is processing an event. When a window gains capture, // current input events are canceled. The given window will receive all // subsequent input until an alternate window is set via SetCapture, or - // ReleaseCapture is called for |window_id|. OnLostCapture is called to notify - // of capture ending. + // ReleaseCapture is called for |window_id|. OnCaptureChanged() is called to + // notify of capture changing (as long as the client did not initiate the + // change). SetCapture(uint32 change_id, uint32 window_id); // Releases input event capture for the given |window_id|. This does nothing @@ -301,8 +302,9 @@ // previously embedded in. See Embed() for more information. OnUnembed(uint32 window); - // Sent when a window loses capture. - OnLostCapture(uint32 window); + // Sent when capture changes. This is not sent if the client initiated the + // change. + OnCaptureChanged(uint32 new_capture, uint32 old_capture); // Called in response to NewTopLevelWindow() successfully completing. // |parent_drawn| is true if the parent of the window is drawn, see
diff --git a/services/ui/service.cc b/services/ui/service.cc index 26ad603..d5112ea 100644 --- a/services/ui/service.cc +++ b/services/ui/service.cc
@@ -357,6 +357,7 @@ void Service::OnCreatedPhysicalDisplay(int64_t id, const gfx::Rect& bounds) { platform_display_init_params_.display_bounds = bounds; platform_display_init_params_.display_id = id; + platform_display_init_params_.platform_screen = platform_screen_.get(); // Display manages its own lifetime. ws::Display* host_impl =
diff --git a/services/ui/surfaces/direct_output_surface_ozone.cc b/services/ui/surfaces/direct_output_surface_ozone.cc index 50cd34be..1ba30ea5 100644 --- a/services/ui/surfaces/direct_output_surface_ozone.cc +++ b/services/ui/surfaces/direct_output_surface_ozone.cc
@@ -15,8 +15,6 @@ #include "components/display_compositor/buffer_queue.h" #include "gpu/command_buffer/client/context_support.h" #include "gpu/command_buffer/client/gles2_interface.h" -#include "services/ui/common/gpu_service.h" -#include "services/ui/common/mojo_gpu_memory_buffer_manager.h" #include "services/ui/gpu/mus_gpu_memory_buffer_manager.h" #include "services/ui/surfaces/surfaces_context_provider.h" #include "ui/display/types/display_snapshot.h"
diff --git a/services/ui/ws/display.cc b/services/ui/ws/display.cc index c58c9816..b247f976 100644 --- a/services/ui/ws/display.cc +++ b/services/ui/ws/display.cc
@@ -88,10 +88,9 @@ mojom::WsDisplayPtr display_ptr = mojom::WsDisplay::New(); display_ptr->display = ToDisplay(); + display_ptr->is_primary = platform_display_->IsPrimaryDisplay(); // TODO(sky): make this real. - display_ptr->is_primary = true; - // TODO(sky): make this real. display_ptr->frame_decoration_values = mojom::FrameDecorationValues::New(); return display_ptr; } @@ -99,9 +98,7 @@ display::Display Display::ToDisplay() const { display::Display display(GetId()); - // TODO(sky): Display should know its origin. - display.set_bounds(gfx::Rect(0, 0, root_->bounds().size().width(), - root_->bounds().size().height())); + display.set_bounds(platform_display_->GetBounds()); // TODO(sky): window manager needs an API to set the work area. display.set_work_area(display.bounds()); display.set_device_scale_factor(platform_display_->GetDeviceScaleFactor()); @@ -134,7 +131,7 @@ } gfx::Size Display::GetSize() const { - return root_->bounds().size(); + return platform_display_->GetBounds().size(); } ServerWindow* Display::GetRootWithId(const WindowId& id) { @@ -321,9 +318,8 @@ InitWindowManagerDisplayRootsIfNecessary(); } else { root_->SetBounds(new_metrics.bounds); - const gfx::Rect wm_bounds(root_->bounds().size()); for (auto& pair : window_manager_display_root_map_) - pair.second->root()->SetBounds(wm_bounds); + pair.second->root()->SetBounds(new_metrics.bounds); } display_manager()->OnDisplayUpdate(this); }
diff --git a/services/ui/ws/event_dispatcher.cc b/services/ui/ws/event_dispatcher.cc index d86edb2..06c6323 100644 --- a/services/ui/ws/event_dispatcher.cc +++ b/services/ui/ws/event_dispatcher.cc
@@ -136,7 +136,6 @@ if (capture_window_) { // Stop observing old capture window. |pointer_targets_| are cleared on // initial setting of a capture window. - delegate_->OnServerWindowCaptureLost(capture_window_); UnobserveWindow(capture_window_); } else { // Cancel implicit capture to all other windows. @@ -166,10 +165,13 @@ // Set the capture before changing native capture; otherwise, the callback // from native platform might try to set the capture again. - bool had_capture_window = capture_window_ != nullptr; + const bool had_capture_window = capture_window_ != nullptr; + ServerWindow* old_capture_window = capture_window_; capture_window_ = window; capture_window_client_id_ = client_id; + delegate_->OnCaptureChanged(capture_window_, old_capture_window); + // Begin tracking the capture window if it is not yet being observed. if (window) { ObserveWindow(window); @@ -320,7 +322,7 @@ event.IsMousePointerEvent() || event.IsMouseWheelEvent(); if (is_mouse_event) { - mouse_pointer_last_location_ = event.location(); + mouse_pointer_last_location_ = event.root_location(); delegate_->OnMouseCursorLocationChanged(event.root_location()); } @@ -437,7 +439,7 @@ EventDispatcher::PointerTarget EventDispatcher::PointerTargetForEvent( const ui::LocatedEvent& event) { PointerTarget pointer_target; - gfx::Point location(event.location()); + gfx::Point location(event.root_location()); ServerWindow* target_window = FindDeepestVisibleWindowForEvents(&location); pointer_target.window = modal_window_controller_.GetTargetForWindow(target_window); @@ -494,7 +496,7 @@ // A window only cares to be informed that it lost capture if it explicitly // requested capture. A window can lose capture if another window gains // explicit capture. - delegate_->OnServerWindowCaptureLost(window); + delegate_->OnCaptureChanged(nullptr, window); delegate_->ReleaseNativeCapture(); UpdateCursorProviderByLastKnownLocation(); return; @@ -538,7 +540,7 @@ ServerWindow* EventDispatcher::FindDeepestVisibleWindowForEvents( gfx::Point* location) { - ServerWindow* root = delegate_->GetRootWindowContaining(*location); + ServerWindow* root = delegate_->GetRootWindowContaining(location); if (!root) return nullptr;
diff --git a/services/ui/ws/event_dispatcher_delegate.h b/services/ui/ws/event_dispatcher_delegate.h index 6bba319..82a5216 100644 --- a/services/ui/ws/event_dispatcher_delegate.h +++ b/services/ui/ws/event_dispatcher_delegate.h
@@ -41,13 +41,16 @@ // Called when capture should be set on the native display. |window| is the // window capture is being set on. virtual void SetNativeCapture(ServerWindow* window) = 0; + // Called when the native display is having capture released. There is no // longer a ServerWindow holding capture. virtual void ReleaseNativeCapture() = 0; + // Called when |window| has lost capture. The native display may still be // holding capture. The delegate should not change native display capture. // ReleaseNativeCapture() is invoked if appropriate. - virtual void OnServerWindowCaptureLost(ServerWindow* window) = 0; + virtual void OnCaptureChanged(ServerWindow* new_capture, + ServerWindow* old_capture) = 0; virtual void OnMouseCursorLocationChanged(const gfx::Point& point) = 0; @@ -63,8 +66,10 @@ bool in_nonclient_area) = 0; // Returns the window to start searching from at the specified location, or - // null if there is a no window containing |location|. - virtual ServerWindow* GetRootWindowContaining(const gfx::Point& location) = 0; + // null if there is a no window containing |location|. |location| should be in + // screen coordinates and if a window is returned then |location| will be + // updated to be relative to the origin of the window. + virtual ServerWindow* GetRootWindowContaining(gfx::Point* location) = 0; // Called when event dispatch could not find a target. OnAccelerator may still // be called.
diff --git a/services/ui/ws/event_dispatcher_unittest.cc b/services/ui/ws/event_dispatcher_unittest.cc index 066aaae..832361d 100644 --- a/services/ui/ws/event_dispatcher_unittest.cc +++ b/services/ui/ws/event_dispatcher_unittest.cc
@@ -120,8 +120,9 @@ if (delegate_) delegate_->ReleaseCapture(); } - void OnServerWindowCaptureLost(ServerWindow* window) override { - lost_capture_window_ = window; + void OnCaptureChanged(ServerWindow* new_capture_window, + ServerWindow* old_capture_window) override { + lost_capture_window_ = old_capture_window; } void OnMouseCursorLocationChanged(const gfx::Point& point) override {} void DispatchInputEventToWindow(ServerWindow* target, @@ -139,7 +140,7 @@ bool in_nonclient_area) override { return in_nonclient_area ? kNonclientAreaId : kClientAreaId; } - ServerWindow* GetRootWindowContaining(const gfx::Point& location) override { + ServerWindow* GetRootWindowContaining(gfx::Point* location) override { return root_; } void OnEventTargetNotFound(const ui::Event& event) override {
diff --git a/services/ui/ws/modal_window_controller.cc b/services/ui/ws/modal_window_controller.cc index 07c2e11..dcb25b5 100644 --- a/services/ui/ws/modal_window_controller.cc +++ b/services/ui/ws/modal_window_controller.cc
@@ -45,7 +45,7 @@ void ModalWindowController::AddSystemModalWindow(ServerWindow* window) { DCHECK(window); - DCHECK(!ContainsValue(system_modal_windows_, window)); + DCHECK(!base::ContainsValue(system_modal_windows_, window)); window->SetModal(); system_modal_windows_.push_back(window);
diff --git a/services/ui/ws/platform_display.cc b/services/ui/ws/platform_display.cc index bb9c4777..4fe70ee 100644 --- a/services/ui/ws/platform_display.cc +++ b/services/ui/ws/platform_display.cc
@@ -55,12 +55,12 @@ DefaultPlatformDisplay::DefaultPlatformDisplay( const PlatformDisplayInitParams& init_params) : id_(init_params.display_id), + platform_screen_(init_params.platform_screen), #if !defined(OS_ANDROID) cursor_loader_(ui::CursorLoader::Create()), #endif frame_generator_(new FrameGenerator(this, init_params.surfaces_state)) { metrics_.bounds = init_params.display_bounds; - // TODO(rjkroege): Preserve the display_id when Ozone platform can use it. } void DefaultPlatformDisplay::Init(PlatformDisplayDelegate* delegate) { @@ -168,23 +168,36 @@ return metrics_.bounds; } +bool DefaultPlatformDisplay::IsPrimaryDisplay() const { + return platform_screen_->GetPrimaryDisplayId() == id_; +} + void DefaultPlatformDisplay::UpdateMetrics(const gfx::Rect& bounds, float device_scale_factor) { if (display::Display::HasForceDeviceScaleFactor()) device_scale_factor = display::Display::GetForcedDeviceScaleFactor(); - if (metrics_.bounds == bounds && + + // We don't care about the origin of the platform window, as that may not be + // related to the origin of the display in our screen space. + if (metrics_.bounds.size() == bounds.size() && metrics_.device_scale_factor == device_scale_factor) return; + // TODO(kylechar): If the window size is updated then we may need to update + // the origin for any other windows. ViewportMetrics old_metrics = metrics_; - metrics_.bounds = bounds; + metrics_.bounds.set_size(bounds.size()); metrics_.device_scale_factor = device_scale_factor; delegate_->OnViewportMetricsChanged(old_metrics, metrics_); } +void DefaultPlatformDisplay::UpdateEventRootLocation(ui::LocatedEvent* event) { + gfx::Point location = event->location(); + location.Offset(metrics_.bounds.x(), metrics_.bounds.y()); + event->set_root_location(location); +} + void DefaultPlatformDisplay::OnBoundsChanged(const gfx::Rect& new_bounds) { - // TODO(kylechar): We should keep track of the actual top left of the window - // and also the internal top left of the window (eg. first window is at 0,0). UpdateMetrics(new_bounds, metrics_.device_scale_factor); } @@ -193,6 +206,9 @@ } void DefaultPlatformDisplay::DispatchEvent(ui::Event* event) { + if (event->IsLocatedEvent()) + UpdateEventRootLocation(event->AsLocatedEvent()); + if (event->IsScrollEvent()) { // TODO(moshayedi): crbug.com/602859. Dispatch scroll events as // they are once we have proper support for scroll events.
diff --git a/services/ui/ws/platform_display.h b/services/ui/ws/platform_display.h index f967a248..2209d45 100644 --- a/services/ui/ws/platform_display.h +++ b/services/ui/ws/platform_display.h
@@ -15,6 +15,7 @@ #include "base/memory/weak_ptr.h" #include "base/strings/string16.h" #include "build/build_config.h" +#include "services/ui/display/platform_screen.h" #include "services/ui/public/interfaces/window_manager.mojom.h" #include "services/ui/public/interfaces/window_manager_constants.mojom.h" #include "services/ui/public/interfaces/window_tree.mojom.h" @@ -89,6 +90,8 @@ virtual gfx::Rect GetBounds() const = 0; + virtual bool IsPrimaryDisplay() const = 0; + // Overrides factory for testing. Default (NULL) value indicates regular // (non-test) environment. static void set_factory_for_testing(PlatformDisplayFactory* factory) { @@ -127,10 +130,17 @@ void RequestCopyOfOutput( std::unique_ptr<cc::CopyOutputRequest> output_request) override; gfx::Rect GetBounds() const override; + bool IsPrimaryDisplay() const override; private: void UpdateMetrics(const gfx::Rect& bounds, float device_scale_factor); + // Update the root_location of located events to be relative to the origin + // of this display. For example, if the origin of this display is (1800, 0) + // and the location of the event is (100, 200) then the root_location will be + // updated to be (1900, 200). + void UpdateEventRootLocation(ui::LocatedEvent* event); + // ui::PlatformWindowDelegate: void OnBoundsChanged(const gfx::Rect& new_bounds) override; void OnDamageRect(const gfx::Rect& damaged_region) override; @@ -151,6 +161,7 @@ const ViewportMetrics& GetViewportMetrics() override; int64_t id_; + display::PlatformScreen* platform_screen_; #if !defined(OS_ANDROID) std::unique_ptr<ui::CursorLoader> cursor_loader_;
diff --git a/services/ui/ws/platform_display_init_params.cc b/services/ui/ws/platform_display_init_params.cc index e0544cb..7fbb50e 100644 --- a/services/ui/ws/platform_display_init_params.cc +++ b/services/ui/ws/platform_display_init_params.cc
@@ -4,6 +4,7 @@ #include "services/ui/ws/platform_display_init_params.h" +#include "services/ui/display/platform_screen.h" #include "services/ui/surfaces/surfaces_state.h" namespace ui {
diff --git a/services/ui/ws/platform_display_init_params.h b/services/ui/ws/platform_display_init_params.h index 99bda3f..af4560e3 100644 --- a/services/ui/ws/platform_display_init_params.h +++ b/services/ui/ws/platform_display_init_params.h
@@ -10,6 +10,10 @@ #include "base/memory/ref_counted.h" #include "ui/gfx/geometry/rect.h" +namespace display { +class PlatformScreen; +} + namespace shell { class Connector; } @@ -30,6 +34,7 @@ gfx::Rect display_bounds; int64_t display_id; + display::PlatformScreen* platform_screen = nullptr; }; } // namespace ws
diff --git a/services/ui/ws/server_window.cc b/services/ui/ws/server_window.cc index 1c21787e..ad93327 100644 --- a/services/ui/ws/server_window.cc +++ b/services/ui/ws/server_window.cc
@@ -55,7 +55,7 @@ // parent, as destroying an active transient child may otherwise attempt to // refocus us. Windows transient_children(transient_children_); - STLDeleteElements(&transient_children); + base::STLDeleteElements(&transient_children); DCHECK(transient_children_.empty()); while (!children_.empty())
diff --git a/services/ui/ws/test_change_tracker.cc b/services/ui/ws/test_change_tracker.cc index 3ad10d5..52862ff 100644 --- a/services/ui/ws/test_change_tracker.cc +++ b/services/ui/ws/test_change_tracker.cc
@@ -51,9 +51,10 @@ return base::StringPrintf("OnUnembed window=%s", WindowIdToString(change.window_id).c_str()); - case CHANGE_TYPE_LOST_CAPTURE: - return base::StringPrintf("OnLostCapture window=%s", - WindowIdToString(change.window_id).c_str()); + case CHANGE_TYPE_CAPTURE_CHANGED: + return base::StringPrintf("OnCaptureChanged new_window=%s old_window=%s", + WindowIdToString(change.window_id).c_str(), + WindowIdToString(change.window_id2).c_str()); case CHANGE_TYPE_NODE_ADD_TRANSIENT_WINDOW: return base::StringPrintf("AddTransientWindow parent = %s child = %s", @@ -285,10 +286,12 @@ AddChange(change); } -void TestChangeTracker::OnLostCapture(Id window_id) { +void TestChangeTracker::OnCaptureChanged(Id new_capture_window_id, + Id old_capture_window_id) { Change change; - change.type = CHANGE_TYPE_LOST_CAPTURE; - change.window_id = window_id; + change.type = CHANGE_TYPE_CAPTURE_CHANGED; + change.window_id = new_capture_window_id; + change.window_id2 = old_capture_window_id; AddChange(change); }
diff --git a/services/ui/ws/test_change_tracker.h b/services/ui/ws/test_change_tracker.h index b7a63ebc..a5e32272 100644 --- a/services/ui/ws/test_change_tracker.h +++ b/services/ui/ws/test_change_tracker.h
@@ -21,10 +21,10 @@ namespace ws { enum ChangeType { + CHANGE_TYPE_CAPTURE_CHANGED, CHANGE_TYPE_EMBED, CHANGE_TYPE_EMBEDDED_APP_DISCONNECTED, CHANGE_TYPE_UNEMBED, - CHANGE_TYPE_LOST_CAPTURE, // TODO(sky): nuke NODE. CHANGE_TYPE_NODE_ADD_TRANSIENT_WINDOW, CHANGE_TYPE_NODE_BOUNDS_CHANGED, @@ -138,7 +138,7 @@ bool drawn); void OnEmbeddedAppDisconnected(Id window_id); void OnUnembed(Id window_id); - void OnLostCapture(Id window_id); + void OnCaptureChanged(Id new_capture_window_id, Id old_capture_window_id); void OnTransientWindowAdded(Id window_id, Id transient_window_id); void OnTransientWindowRemoved(Id window_id, Id transient_window_id); void OnWindowBoundsChanged(Id window_id,
diff --git a/services/ui/ws/test_utils.cc b/services/ui/ws/test_utils.cc index 7387a8d..82dc1c0 100644 --- a/services/ui/ws/test_utils.cc +++ b/services/ui/ws/test_utils.cc
@@ -27,8 +27,12 @@ // Empty implementation of PlatformDisplay. class TestPlatformDisplay : public PlatformDisplay { public: - explicit TestPlatformDisplay(int64_t id, int32_t* cursor_id_storage) - : id_(id), cursor_id_storage_(cursor_id_storage) { + explicit TestPlatformDisplay(int64_t id, + bool is_primary, + int32_t* cursor_id_storage) + : id_(id), + is_primary_(is_primary), + cursor_id_storage_(cursor_id_storage) { display_metrics_.bounds = gfx::Rect(0, 0, 400, 300); display_metrics_.device_scale_factor = 1.f; } @@ -61,11 +65,13 @@ void RequestCopyOfOutput( std::unique_ptr<cc::CopyOutputRequest> output_request) override {} gfx::Rect GetBounds() const override { return display_metrics_.bounds; } + bool IsPrimaryDisplay() const override { return is_primary_; } private: ViewportMetrics display_metrics_; int64_t id_; + bool is_primary_; int32_t* cursor_id_storage_; DISALLOW_COPY_AND_ASSIGN(TestPlatformDisplay); @@ -104,14 +110,19 @@ // TestPlatformDisplayFactory ------------------------------------------------- +const int64_t TestPlatformDisplayFactory::kFirstDisplayId = 1; + TestPlatformDisplayFactory::TestPlatformDisplayFactory( int32_t* cursor_id_storage) - : cursor_id_storage_(cursor_id_storage) {} + : cursor_id_storage_(cursor_id_storage), + next_display_id_(kFirstDisplayId) {} TestPlatformDisplayFactory::~TestPlatformDisplayFactory() {} PlatformDisplay* TestPlatformDisplayFactory::CreatePlatformDisplay() { - return new TestPlatformDisplay(next_display_id_++, cursor_id_storage_); + bool is_primary = (next_display_id_ == kFirstDisplayId); + return new TestPlatformDisplay(next_display_id_++, is_primary, + cursor_id_storage_); } // TestFrameGeneratorDelegate ------------------------------------------------- @@ -242,7 +253,10 @@ tracker_.OnUnembed(window_id); } -void TestWindowTreeClient::OnLostCapture(Id window_id) {} +void TestWindowTreeClient::OnCaptureChanged(Id new_capture_window_id, + Id old_capture_window_id) { + tracker_.OnCaptureChanged(new_capture_window_id, old_capture_window_id); +} void TestWindowTreeClient::OnTopLevelCreated(uint32_t change_id, mojom::WindowDataPtr data,
diff --git a/services/ui/ws/test_utils.h b/services/ui/ws/test_utils.h index b7dd8fa..8b608e5 100644 --- a/services/ui/ws/test_utils.h +++ b/services/ui/ws/test_utils.h
@@ -237,6 +237,8 @@ // Factory that dispenses TestPlatformDisplays. class TestPlatformDisplayFactory : public PlatformDisplayFactory { public: + static const int64_t kFirstDisplayId; + explicit TestPlatformDisplayFactory(int32_t* cursor_id_storage); ~TestPlatformDisplayFactory(); @@ -245,7 +247,7 @@ private: int32_t* cursor_id_storage_; - int64_t next_display_id_ = 1; + int64_t next_display_id_; DISALLOW_COPY_AND_ASSIGN(TestPlatformDisplayFactory); }; @@ -365,7 +367,8 @@ bool drawn) override; void OnEmbeddedAppDisconnected(uint32_t window) override; void OnUnembed(Id window_id) override; - void OnLostCapture(Id window_id) override; + void OnCaptureChanged(Id new_capture_window_id, + Id old_capture_window_id) override; void OnTopLevelCreated(uint32_t change_id, mojom::WindowDataPtr data, int64_t display_id,
diff --git a/services/ui/ws/window_manager_state.cc b/services/ui/ws/window_manager_state.cc index 943d3c23..f2545315 100644 --- a/services/ui/ws/window_manager_state.cc +++ b/services/ui/ws/window_manager_state.cc
@@ -4,6 +4,8 @@ #include "services/ui/ws/window_manager_state.h" +#include <utility> + #include "base/memory/weak_ptr.h" #include "services/shell/public/interfaces/connector.mojom.h" #include "services/ui/common/event_matcher_util.h" @@ -457,9 +459,9 @@ platform_display_with_capture_ = nullptr; } -void WindowManagerState::OnServerWindowCaptureLost(ServerWindow* window) { - DCHECK(window); - window_server()->ProcessLostCapture(window); +void WindowManagerState::OnCaptureChanged(ServerWindow* new_capture, + ServerWindow* old_capture) { + window_server()->ProcessCaptureChanged(new_capture, old_capture); } void WindowManagerState::OnMouseCursorLocationChanged(const gfx::Point& point) { @@ -522,16 +524,36 @@ } ServerWindow* WindowManagerState::GetRootWindowContaining( - const gfx::Point& location) { + gfx::Point* location) { if (display_manager()->displays().empty()) + return nullptr; + + Display* target_display = nullptr; + for (Display* display : display_manager()->displays()) { + if (display->platform_display()->GetBounds().Contains(*location)) { + target_display = display; + break; + } + } + + // TODO(kylechar): Better handle locations outside the window. Overlapping X11 + // windows, dragging and touch sensors need to be handled properly. + if (!target_display) { + DVLOG(1) << "Invalid event location " << location->ToString(); + target_display = *(display_manager()->displays().begin()); + } + + WindowManagerDisplayRoot* display_root = + target_display->GetWindowManagerDisplayRootForUser(user_id()); + + if (!display_root) return nullptr; - // TODO(sky): this isn't right. To correctly implement need bounds of - // Display, which we aren't tracking yet. For now, use the first display. - Display* display = *(display_manager()->displays().begin()); - WindowManagerDisplayRoot* display_root = - display->GetWindowManagerDisplayRootForUser(user_id()); - return display_root ? display_root->root() : nullptr; + // Translate the location to be relative to the display instead of relative + // to the screen space. + gfx::Point origin = target_display->platform_display()->GetBounds().origin(); + *location -= origin.OffsetFromOrigin(); + return display_root->root(); } void WindowManagerState::OnEventTargetNotFound(const ui::Event& event) {
diff --git a/services/ui/ws/window_manager_state.h b/services/ui/ws/window_manager_state.h index 685f123..c78d3a9 100644 --- a/services/ui/ws/window_manager_state.h +++ b/services/ui/ws/window_manager_state.h
@@ -8,6 +8,7 @@ #include <stdint.h> #include <memory> +#include <queue> #include <vector> #include "base/memory/weak_ptr.h" @@ -182,7 +183,8 @@ ServerWindow* GetFocusedWindowForEventDispatcher() override; void SetNativeCapture(ServerWindow* window) override; void ReleaseNativeCapture() override; - void OnServerWindowCaptureLost(ServerWindow* window) override; + void OnCaptureChanged(ServerWindow* new_capture, + ServerWindow* old_capture) override; void OnMouseCursorLocationChanged(const gfx::Point& point) override; void DispatchInputEventToWindow(ServerWindow* target, ClientSpecificId client_id, @@ -190,7 +192,7 @@ Accelerator* accelerator) override; ClientSpecificId GetEventTargetClientId(const ServerWindow* window, bool in_nonclient_area) override; - ServerWindow* GetRootWindowContaining(const gfx::Point& location) override; + ServerWindow* GetRootWindowContaining(gfx::Point* location) override; void OnEventTargetNotFound(const ui::Event& event) override; // The single WindowTree this WindowManagerState is associated with.
diff --git a/services/ui/ws/window_server.cc b/services/ui/ws/window_server.cc index 29b3b55..058cf744 100644 --- a/services/ui/ws/window_server.cc +++ b/services/ui/ws/window_server.cc
@@ -373,9 +373,12 @@ } } -void WindowServer::ProcessLostCapture(const ServerWindow* window) { - for (auto& pair : tree_map_) - pair.second->ProcessLostCapture(window, IsOperationSource(pair.first)); +void WindowServer::ProcessCaptureChanged(const ServerWindow* new_capture, + const ServerWindow* old_capture) { + for (auto& pair : tree_map_) { + pair.second->ProcessCaptureChanged(new_capture, old_capture, + IsOperationSource(pair.first)); + } } void WindowServer::ProcessWillChangeWindowHierarchy(
diff --git a/services/ui/ws/window_server.h b/services/ui/ws/window_server.h index 9650e7dd..542041b 100644 --- a/services/ui/ws/window_server.h +++ b/services/ui/ws/window_server.h
@@ -178,7 +178,8 @@ const ServerWindow* window, const gfx::Insets& new_client_area, const std::vector<gfx::Rect>& new_additional_client_areas); - void ProcessLostCapture(const ServerWindow* window); + void ProcessCaptureChanged(const ServerWindow* new_capture, + const ServerWindow* old_capture); void ProcessWillChangeWindowHierarchy(const ServerWindow* window, const ServerWindow* new_parent, const ServerWindow* old_parent);
diff --git a/services/ui/ws/window_tree.cc b/services/ui/ws/window_tree.cc index ea1f29e..0c9b870 100644 --- a/services/ui/ws/window_tree.cc +++ b/services/ui/ws/window_tree.cc
@@ -230,11 +230,30 @@ access_policy_->CanSetCapture(window) && (!current_capture_window || access_policy_->CanSetCapture(current_capture_window))) { + Operation op(this, window_server_, OperationType::SET_CAPTURE); return display_root->window_manager_state()->SetCapture(window, id_); } return false; } +bool WindowTree::ReleaseCapture(const ClientWindowId& client_window_id) { + ServerWindow* window = GetWindowByClientId(client_window_id); + WindowManagerDisplayRoot* display_root = GetWindowManagerDisplayRoot(window); + ServerWindow* current_capture_window = + display_root ? display_root->window_manager_state()->capture_window() + : nullptr; + if (!window || !display_root || + !display_root->window_manager_state()->IsActive() || + (current_capture_window && + !access_policy_->CanSetCapture(current_capture_window)) || + window != current_capture_window) { + return false; + } + Operation op(this, window_server_, OperationType::RELEASE_CAPTURE); + return display_root->window_manager_state()->SetCapture(nullptr, + kInvalidClientId); +} + bool WindowTree::NewWindow( const ClientWindowId& client_window_id, const std::map<std::string, std::vector<uint8_t>>& properties) { @@ -737,15 +756,27 @@ window->id().client_id; } -void WindowTree::ProcessLostCapture(const ServerWindow* old_capture_window, - bool originated_change) { - if ((originated_change && - window_server_->current_operation_type() == - OperationType::RELEASE_CAPTURE) || - !IsWindowKnown(old_capture_window)) { +void WindowTree::ProcessCaptureChanged(const ServerWindow* new_capture, + const ServerWindow* old_capture, + bool originated_change) { + ClientWindowId new_capture_window_client_id; + ClientWindowId old_capture_window_client_id; + const bool new_capture_window_known = + IsWindowKnown(new_capture, &new_capture_window_client_id); + const bool old_capture_window_known = + IsWindowKnown(old_capture, &old_capture_window_client_id); + if (!new_capture_window_known && !old_capture_window_known) + return; + + if (originated_change && ((window_server_->current_operation_type() == + OperationType::RELEASE_CAPTURE) || + (window_server_->current_operation_type() == + OperationType::SET_CAPTURE))) { return; } - client()->OnLostCapture(WindowIdToTransportId(old_capture_window->id())); + + client()->OnCaptureChanged(new_capture_window_client_id.id, + old_capture_window_client_id.id); } ClientWindowId WindowTree::ClientWindowIdForWindow( @@ -952,7 +983,7 @@ if (transient_parent) transient_parent->RemoveTransientWindow(pair.second); } - STLDeleteValues(&created_window_map_copy); + base::STLDeleteValues(&created_window_map_copy); } bool WindowTree::CanEmbed(const ClientWindowId& window_id) const { @@ -1161,22 +1192,8 @@ } void WindowTree::ReleaseCapture(uint32_t change_id, Id window_id) { - ServerWindow* window = GetWindowByClientId(ClientWindowId(window_id)); - WindowManagerDisplayRoot* display_root = GetWindowManagerDisplayRoot(window); - ServerWindow* current_capture_window = - display_root ? display_root->window_manager_state()->capture_window() - : nullptr; - bool success = window && display_root && - display_root->window_manager_state()->IsActive() && - (!current_capture_window || - access_policy_->CanSetCapture(current_capture_window)) && - window == current_capture_window; - if (success) { - Operation op(this, window_server_, OperationType::RELEASE_CAPTURE); - success = display_root->window_manager_state()->SetCapture( - nullptr, kInvalidClientId); - } - client()->OnChangeCompleted(change_id, success); + client()->OnChangeCompleted(change_id, + ReleaseCapture(ClientWindowId(window_id))); } void WindowTree::StartPointerWatcher(bool want_moves,
diff --git a/services/ui/ws/window_tree.h b/services/ui/ws/window_tree.h index 55c1b9a..b330514 100644 --- a/services/ui/ws/window_tree.h +++ b/services/ui/ws/window_tree.h
@@ -155,6 +155,7 @@ // These functions are synchronous variants of those defined in the mojom. The // WindowTree implementations all call into these. See the mojom for details. bool SetCapture(const ClientWindowId& client_window_id); + bool ReleaseCapture(const ClientWindowId& client_window_id); bool NewWindow(const ClientWindowId& client_window_id, const std::map<std::string, std::vector<uint8_t>>& properties); bool AddWindow(const ClientWindowId& parent_id, @@ -232,8 +233,9 @@ bool originated_change); void ProcessFocusChanged(const ServerWindow* old_focused_window, const ServerWindow* new_focused_window); - void ProcessLostCapture(const ServerWindow* old_lost_capture, - bool originated_change); + void ProcessCaptureChanged(const ServerWindow* new_capture, + const ServerWindow* old_capture, + bool originated_change); void ProcessTransientWindowAdded(const ServerWindow* window, const ServerWindow* transient_window, bool originated_change);
diff --git a/services/ui/ws/window_tree_client_unittest.cc b/services/ui/ws/window_tree_client_unittest.cc index b65c0c5..63c271ca 100644 --- a/services/ui/ws/window_tree_client_unittest.cc +++ b/services/ui/ws/window_tree_client_unittest.cc
@@ -289,8 +289,9 @@ tracker()->OnEmbeddedAppDisconnected(window_id); } void OnUnembed(Id window_id) override { tracker()->OnUnembed(window_id); } - void OnLostCapture(Id window_id) override { - tracker()->OnLostCapture(window_id); + void OnCaptureChanged(Id new_capture_window_id, + Id old_capture_window_id) override { + tracker()->OnCaptureChanged(new_capture_window_id, old_capture_window_id); } void OnTopLevelCreated(uint32_t change_id, mojom::WindowDataPtr data,
diff --git a/services/ui/ws/window_tree_unittest.cc b/services/ui/ws/window_tree_unittest.cc index 393e3cbee..b8234b1c 100644 --- a/services/ui/ws/window_tree_unittest.cc +++ b/services/ui/ws/window_tree_unittest.cc
@@ -1104,9 +1104,16 @@ ->PerformWindowMove(change_id, embed_window_id2_in_child.id, mojom::MoveLoopSource::MOUSE, gfx::Point(0, 0)); + // There should be three changes, the first two relating to capture changing, + // the last for the completion. + std::vector<Change>* child_changes = + child_binding->client()->tracker()->changes(); + ASSERT_EQ(3u, child_changes->size()); + EXPECT_EQ(CHANGE_TYPE_CAPTURE_CHANGED, (*child_changes)[0].type); + EXPECT_EQ(CHANGE_TYPE_CAPTURE_CHANGED, (*child_changes)[1].type); + child_changes->erase(child_changes->begin(), child_changes->begin() + 2); EXPECT_EQ("ChangeCompleted id=7 sucess=true", - SingleChangeToDescription( - *child_binding->client()->tracker()->changes())); + SingleChangeToDescription(*child_changes)); } TEST_F(WindowTreeTest, WindowManagerCantMoveLoop) { @@ -1242,6 +1249,49 @@ EXPECT_FALSE(window->can_accept_events()); } +// Verifies wm observers capture changes in client. +TEST_F(WindowTreeTest, CaptureNotifiesWm) { + ServerWindow* window = window_event_targeting_helper_.CreatePrimaryTree( + gfx::Rect(0, 0, 100, 100), gfx::Rect(0, 0, 50, 50)); + TestWindowTreeClient* embed_client = last_window_tree_client(); + WindowTree* owning_tree = + window_server()->GetTreeWithId(window->id().client_id); + WindowTree* embed_tree = window_server()->GetTreeWithRoot(window); + ASSERT_NE(owning_tree, embed_tree); + + const ClientWindowId embed_child_window_id = + BuildClientWindowId(embed_tree, 2); + ASSERT_TRUE( + embed_tree->NewWindow(embed_child_window_id, ServerWindow::Properties())); + EXPECT_TRUE(embed_tree->SetWindowVisibility(embed_child_window_id, true)); + EXPECT_TRUE( + embed_tree->AddWindow(FirstRootId(embed_tree), embed_child_window_id)); + wm_client()->tracker()->changes()->clear(); + embed_client->tracker()->changes()->clear(); + EXPECT_TRUE(embed_tree->SetCapture(embed_child_window_id)); + ASSERT_TRUE(!wm_client()->tracker()->changes()->empty()); + EXPECT_EQ("OnCaptureChanged new_window=2,1 old_window=null", + ChangesToDescription1(*wm_client()->tracker()->changes())[0]); + EXPECT_TRUE(embed_client->tracker()->changes()->empty()); + + // Set capture to embed window, and ensure notified as well. + wm_client()->tracker()->changes()->clear(); + EXPECT_TRUE(embed_tree->SetCapture(FirstRootId(embed_tree))); + ASSERT_TRUE(!wm_client()->tracker()->changes()->empty()); + EXPECT_EQ("OnCaptureChanged new_window=1,1 old_window=2,1", + ChangesToDescription1(*wm_client()->tracker()->changes())[0]); + EXPECT_TRUE(embed_client->tracker()->changes()->empty()); + wm_client()->tracker()->changes()->clear(); + + // Set capture from server and ensure embedded tree notified. + EXPECT_TRUE(owning_tree->ReleaseCapture( + ClientWindowIdForWindow(owning_tree, FirstRoot(embed_tree)))); + EXPECT_TRUE(wm_client()->tracker()->changes()->empty()); + ASSERT_TRUE(!embed_client->tracker()->changes()->empty()); + EXPECT_EQ("OnCaptureChanged new_window=null old_window=1,1", + ChangesToDescription1(*embed_client->tracker()->changes())[0]); +} + } // namespace test } // namespace ws } // namespace ui
diff --git a/services/user/BUILD.gn b/services/user/BUILD.gn deleted file mode 100644 index 6cc30861..0000000 --- a/services/user/BUILD.gn +++ /dev/null
@@ -1,41 +0,0 @@ -# Copyright 2016 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("//services/shell/public/cpp/service.gni") -import("//services/shell/public/service_manifest.gni") - -source_set("lib") { - sources = [ - "user_id_map.cc", - "user_id_map.h", - "user_service.cc", - "user_service.h", - "user_shell_client.cc", - "user_shell_client.h", - ] - - deps = [ - "//base", - "//components/filesystem:lib", - "//components/filesystem/public/interfaces", - "//components/leveldb:lib", - "//components/leveldb/public/interfaces", - "//mojo/common", - "//mojo/common:common_base", - "//services/shell/public/cpp", - "//services/shell/public/interfaces", - "//services/tracing/public/cpp", - "//services/user/public/interfaces", - "//url", - ] - - data_deps = [ - ":manifest", - ] -} - -service_manifest("manifest") { - name = "user" - source = "manifest.json" -}
diff --git a/services/user/manifest.json b/services/user/manifest.json deleted file mode 100644 index 246d392..0000000 --- a/services/user/manifest.json +++ /dev/null
@@ -1,11 +0,0 @@ -{ - "manifest_version": 1, - "name": "mojo:user", - "process-group": "browser", - "display_name": "User Service", - "capabilities": { - "required": { - "*": { "classes": [ "app" ] } - } - } -}
diff --git a/services/user/public/cpp/constants.cc b/services/user/public/cpp/constants.cc deleted file mode 100644 index 963fb12..0000000 --- a/services/user/public/cpp/constants.cc +++ /dev/null
@@ -1,11 +0,0 @@ -// Copyright 2016 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 "services/user/public/cpp/constants.h" - -namespace user_service { - -const char kUserServiceName[] = "mojo:user"; - -} // namespace user_service
diff --git a/services/user/public/cpp/constants.h b/services/user/public/cpp/constants.h deleted file mode 100644 index 64a18c2b..0000000 --- a/services/user/public/cpp/constants.h +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright 2016 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 SERVICES_USER_PUBLIC_CPP_CONSTANTS_H_ -#define SERVICES_USER_PUBLIC_CPP_CONSTANTS_H_ - -namespace user_service { - -extern const char kUserServiceName[]; - -} // namespace user_service - -#endif // SERVICES_USER_PUBLIC_CPP_CONSTANTS_H_
diff --git a/services/user/public/interfaces/BUILD.gn b/services/user/public/interfaces/BUILD.gn deleted file mode 100644 index 91ca012..0000000 --- a/services/user/public/interfaces/BUILD.gn +++ /dev/null
@@ -1,17 +0,0 @@ -# Copyright 2016 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("//mojo/public/tools/bindings/mojom.gni") - -mojom("interfaces") { - sources = [ - "user_service.mojom", - ] - - deps = [ - "//components/filesystem/public/interfaces", - ] - - use_new_wrapper_types = false -}
diff --git a/services/user/public/interfaces/user_service.mojom b/services/user/public/interfaces/user_service.mojom deleted file mode 100644 index f1cf6337..0000000 --- a/services/user/public/interfaces/user_service.mojom +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2016 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 user_service.mojom; - -import "components/filesystem/public/interfaces/directory.mojom"; -import "components/filesystem/public/interfaces/types.mojom"; - -// An encapsulation around the per-profile storage. -// -// TODO(erg): An instance of UserService should be strongly bound to a specific -// user id; eventually during startup of the User Service process, we sandbox -// the process so the only directory it has access to is the user's directory. -interface UserService { - // Returns the user profile directory. - GetDirectory(filesystem.mojom.Directory& dir) => (); - - // Returns a subdirectory under the profile dir. Returns a filesystem error - // when we fail to create the subdirectory. - GetSubDirectory(string dir_path, filesystem.mojom.Directory& dir) - => (filesystem.mojom.FileError err); -};
diff --git a/services/user/user.gyp b/services/user/user.gyp deleted file mode 100644 index 6b234cfb..0000000 --- a/services/user/user.gyp +++ /dev/null
@@ -1,95 +0,0 @@ -# Copyright 2016 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': { - # This turns on e.g. the filename-based detection of which - # platforms to include source files on (e.g. files ending in - # _mac.h or _mac.cc are only compiled on MacOSX). - 'chromium_code': 1, - }, - 'targets': [ - { - # GN version: //services/user:lib - 'target_name': 'user_service_lib', - 'type': 'static_library', - 'include_dirs': [ - '../..', - ], - 'sources': [ - 'user_id_map.cc', - 'user_id_map.h', - 'user_service.cc', - 'user_service.h', - 'user_shell_client.cc', - 'user_shell_client.h', - ], - 'dependencies': [ - 'user_app_manifest', - 'user_service_bindings', - '../../base/base.gyp:base', - '../../components/filesystem/filesystem.gyp:filesystem_lib', - '../../components/leveldb/leveldb.gyp:leveldb_lib', - '../../services/shell/shell_public.gyp:shell_public', - '../../services/tracing/tracing.gyp:tracing_lib', - '../../mojo/mojo_edk.gyp:mojo_system_impl', - '../../mojo/mojo_public.gyp:mojo_cpp_bindings', - '../../url/url.gyp:url_lib', - ], - 'export_dependent_settings': [ - 'user_service_bindings', - ], - }, - { - # GN version: //services/user/public/interfaces - 'target_name': 'user_service_bindings', - 'type': 'static_library', - 'dependencies': [ - 'user_service_bindings_mojom', - ], - }, - { - 'target_name': 'user_service_bindings_mojom', - 'type': 'none', - 'variables': { - 'mojom_files': [ - 'public/interfaces/user_service.mojom', - ], - 'use_new_wrapper_types': 'false', - }, - 'dependencies': [ - '../../components/filesystem/filesystem.gyp:filesystem_bindings_mojom', - '../../components/leveldb/leveldb.gyp:leveldb_bindings_mojom', - ], - 'includes': [ - '../../mojo/mojom_bindings_generator_explicit.gypi', - ], - }, - { - 'target_name': 'user_service_public_lib', - 'type': 'static_library', - 'sources': [ - 'public/cpp/constants.cc', - 'public/cpp/constants.h', - ], - 'include_dirs': [ - '../..', - ], - }, - { - # GN version: //services/user:manifest - 'target_name': 'user_app_manifest', - 'type': 'none', - 'variables': { - 'type': 'mojo', - 'name': 'user', - 'source_manifest': '<(DEPTH)/services/user/manifest.json', - }, - 'includes': [ - '../shell/public/service_manifest.gypi', - ], - 'hard_dependency': 1, - }, - ], -}
diff --git a/services/user/user_id_map.cc b/services/user/user_id_map.cc deleted file mode 100644 index 143808c..0000000 --- a/services/user/user_id_map.cc +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2016 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 "services/user/user_id_map.h" - -#include <map> - -#include "base/lazy_instance.h" - -namespace user_service { - -namespace { -base::LazyInstance<std::map<std::string, base::FilePath>> - g_user_id_to_data_dir = LAZY_INSTANCE_INITIALIZER; -} // namespace - -void AssociateShellUserIdWithUserDir(const std::string& user_id, - const base::FilePath& user_dir) { - g_user_id_to_data_dir.Get()[user_id] = user_dir; -} - -void ForgetShellUserIdUserDirAssociation(const std::string& user_id) { - auto it = g_user_id_to_data_dir.Get().find(user_id); - if (it != g_user_id_to_data_dir.Get().end()) - g_user_id_to_data_dir.Get().erase(it); -} - -base::FilePath GetUserDirForUserId(const std::string& user_id) { - auto it = g_user_id_to_data_dir.Get().find(user_id); - DCHECK(it != g_user_id_to_data_dir.Get().end()); - return it->second; -} - -} // namespace user_service
diff --git a/services/user/user_id_map.h b/services/user/user_id_map.h deleted file mode 100644 index c0ccc42..0000000 --- a/services/user/user_id_map.h +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2016 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 SERVICES_USER_USER_ID_MAP_H_ -#define SERVICES_USER_USER_ID_MAP_H_ - -#include <string> -#include "base/files/file_path.h" - -namespace user_service { - -// Currently, UserApp is run from within the chrome process. This means that -// the ApplicationLoader is registered during MojoShellContext startup, even -// though the application itself is not started. As soon as a BrowserContext is -// created, the BrowserContext will choose a |user_id| for itself and call us -// to register the mapping from |user_id| to |user_dir|. -// -// This data is then accessed when we get our Initialize() call. -// -// TODO(erg): This is a temporary hack until we redo how we initialize mojo -// applications inside of chrome in general; this system won't work once -// UserApp gets put in its own sandboxed process. -void AssociateShellUserIdWithUserDir(const std::string& user_id, - const base::FilePath& user_dir); -void ForgetShellUserIdUserDirAssociation(const std::string& user_id); - -base::FilePath GetUserDirForUserId(const std::string& user_id); - -} // namespace user_service - -#endif // SERVICES_USER_USER_ID_MAP_H_
diff --git a/services/user/user_service.cc b/services/user/user_service.cc deleted file mode 100644 index 59d91107..0000000 --- a/services/user/user_service.cc +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright 2016 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 "services/user/user_service.h" - -#include "base/files/file.h" -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "base/strings/utf_string_conversions.h" -#include "components/filesystem/directory_impl.h" -#include "components/filesystem/lock_table.h" -#include "components/filesystem/public/interfaces/types.mojom.h" -#include "services/shell/public/cpp/connection.h" - -namespace user_service { - -UserService::UserService(const base::FilePath& base_user_dir, - const scoped_refptr<filesystem::LockTable>& lock_table) - : lock_table_(lock_table), path_(base_user_dir) { - base::CreateDirectory(path_); -} - -UserService::~UserService() {} - -void UserService::GetDirectory(filesystem::mojom::DirectoryRequest request, - const GetDirectoryCallback& callback) { - new filesystem::DirectoryImpl(std::move(request), path_, - scoped_refptr<filesystem::SharedTempDir>(), - lock_table_); - callback.Run(); -} - -void UserService::GetSubDirectory(const mojo::String& sub_directory_path, - filesystem::mojom::DirectoryRequest request, - const GetSubDirectoryCallback& callback) { - // Ensure that we've made |subdirectory| recursively under our user dir. - base::FilePath subdir = path_.Append( -#if defined(OS_WIN) - base::UTF8ToWide(sub_directory_path.To<std::string>())); -#else - sub_directory_path.To<std::string>()); -#endif - base::File::Error error; - if (!base::CreateDirectoryAndGetError(subdir, &error)) { - callback.Run(static_cast<filesystem::mojom::FileError>(error)); - return; - } - - new filesystem::DirectoryImpl(std::move(request), subdir, - scoped_refptr<filesystem::SharedTempDir>(), - lock_table_); - callback.Run(filesystem::mojom::FileError::OK); -} - -} // namespace user_service
diff --git a/services/user/user_service.h b/services/user/user_service.h deleted file mode 100644 index 2aeee76..0000000 --- a/services/user/user_service.h +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2016 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 SERVICES_USER_USER_SERVICE_IMPL_H_ -#define SERVICES_USER_USER_SERVICE_IMPL_H_ - -#include "base/files/file_path.h" -#include "components/filesystem/public/interfaces/directory.mojom.h" -#include "mojo/public/cpp/bindings/interface_request.h" -#include "mojo/public/cpp/bindings/strong_binding.h" -#include "services/shell/public/cpp/connection.h" -#include "services/user/public/interfaces/user_service.mojom.h" - -namespace filesystem { -class LockTable; -} - -namespace user_service { - -// A service which serves directories to callers. -class UserService : public mojom::UserService { - public: - UserService(const base::FilePath& base_user_dir, - const scoped_refptr<filesystem::LockTable>& lock_table); - ~UserService() override; - - // Overridden from mojom::UserService: - void GetDirectory(filesystem::mojom::DirectoryRequest request, - const GetDirectoryCallback& callback) override; - void GetSubDirectory(const mojo::String& sub_directory_path, - filesystem::mojom::DirectoryRequest request, - const GetSubDirectoryCallback& callback) override; - - private: - scoped_refptr<filesystem::LockTable> lock_table_; - base::FilePath path_; - - DISALLOW_COPY_AND_ASSIGN(UserService); -}; - -} // namespace user_service - -#endif // SERVICES_USER_USER_SERVICE_IMPL_H_
diff --git a/services/user/user_shell_client.cc b/services/user/user_shell_client.cc deleted file mode 100644 index aa70576..0000000 --- a/services/user/user_shell_client.cc +++ /dev/null
@@ -1,124 +0,0 @@ -// Copyright 2016 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 "services/user/user_shell_client.h" - -#include "base/bind.h" -#include "base/memory/ptr_util.h" -#include "base/memory/weak_ptr.h" -#include "components/filesystem/lock_table.h" -#include "components/leveldb/leveldb_service_impl.h" -#include "services/shell/public/cpp/connection.h" -#include "services/user/user_id_map.h" -#include "services/user/user_service.h" - -namespace user_service { - -class UserShellClient::UserServiceObjects - : public base::SupportsWeakPtr<UserServiceObjects> { - public: - // Created on the main thread. - UserServiceObjects(base::FilePath user_dir) : user_dir_(user_dir) {} - - // Destroyed on the |user_service_runner_|. - ~UserServiceObjects() {} - - // Called on the |user_service_runner_|. - void OnUserServiceRequest(const shell::Identity& remote_identity, - mojom::UserServiceRequest request) { - if (!lock_table_) - lock_table_ = new filesystem::LockTable; - user_service_bindings_.AddBinding(new UserService(user_dir_, lock_table_), - std::move(request)); - } - - private: - mojo::BindingSet<mojom::UserService> user_service_bindings_; - scoped_refptr<filesystem::LockTable> lock_table_; - base::FilePath user_dir_; - - DISALLOW_COPY_AND_ASSIGN(UserServiceObjects); -}; - -class UserShellClient::LevelDBServiceObjects - : public base::SupportsWeakPtr<LevelDBServiceObjects> { - public: - // Created on the main thread. - LevelDBServiceObjects(scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : task_runner_(std::move(task_runner)) {} - - // Destroyed on the |leveldb_service_runner_|. - ~LevelDBServiceObjects() {} - - // Called on the |leveldb_service_runner_|. - void OnLevelDBServiceRequest(const shell::Identity& remote_identity, - leveldb::mojom::LevelDBServiceRequest request) { - if (!leveldb_service_) - leveldb_service_.reset(new leveldb::LevelDBServiceImpl(task_runner_)); - leveldb_bindings_.AddBinding(leveldb_service_.get(), std::move(request)); - } - - private: - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - - // Variables that are only accessible on the |leveldb_service_runner_| thread. - std::unique_ptr<leveldb::mojom::LevelDBService> leveldb_service_; - mojo::BindingSet<leveldb::mojom::LevelDBService> leveldb_bindings_; - - DISALLOW_COPY_AND_ASSIGN(LevelDBServiceObjects); -}; - -std::unique_ptr<shell::Service> CreateUserService( - scoped_refptr<base::SingleThreadTaskRunner> user_service_runner, - scoped_refptr<base::SingleThreadTaskRunner> leveldb_service_runner, - const base::Closure& quit_closure) { - return base::WrapUnique(new UserShellClient( - std::move(user_service_runner), std::move(leveldb_service_runner))); -} - -UserShellClient::UserShellClient( - scoped_refptr<base::SingleThreadTaskRunner> user_service_runner, - scoped_refptr<base::SingleThreadTaskRunner> leveldb_service_runner) - : user_service_runner_(std::move(user_service_runner)), - leveldb_service_runner_(std::move(leveldb_service_runner)) {} - -UserShellClient::~UserShellClient() { - user_service_runner_->DeleteSoon(FROM_HERE, user_objects_.release()); - leveldb_service_runner_->DeleteSoon(FROM_HERE, leveldb_objects_.release()); -} - -void UserShellClient::OnStart(const shell::Identity& identity) { - user_objects_.reset(new UserShellClient::UserServiceObjects( - GetUserDirForUserId(identity.user_id()))); - leveldb_objects_.reset( - new UserShellClient::LevelDBServiceObjects(leveldb_service_runner_)); -} - -bool UserShellClient::OnConnect(const shell::Identity& remote_identity, - shell::InterfaceRegistry* registry) { - registry->AddInterface<leveldb::mojom::LevelDBService>(this); - registry->AddInterface<mojom::UserService>(this); - return true; -} - -void UserShellClient::Create(const shell::Identity& remote_identity, - mojom::UserServiceRequest request) { - user_service_runner_->PostTask( - FROM_HERE, - base::Bind(&UserShellClient::UserServiceObjects::OnUserServiceRequest, - user_objects_->AsWeakPtr(), remote_identity, - base::Passed(&request))); -} - -void UserShellClient::Create(const shell::Identity& remote_identity, - leveldb::mojom::LevelDBServiceRequest request) { - leveldb_service_runner_->PostTask( - FROM_HERE, - base::Bind( - &UserShellClient::LevelDBServiceObjects::OnLevelDBServiceRequest, - leveldb_objects_->AsWeakPtr(), remote_identity, - base::Passed(&request))); -} - -} // namespace user_service
diff --git a/services/user/user_shell_client.h b/services/user/user_shell_client.h deleted file mode 100644 index e0e1c651..0000000 --- a/services/user/user_shell_client.h +++ /dev/null
@@ -1,66 +0,0 @@ -// Copyright 2016 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 SERVICES_USER_USER_SHELL_CLIENT_H_ -#define SERVICES_USER_USER_SHELL_CLIENT_H_ - -#include "base/callback_forward.h" -#include "base/memory/ref_counted.h" -#include "components/filesystem/lock_table.h" -#include "components/leveldb/public/interfaces/leveldb.mojom.h" -#include "mojo/public/cpp/bindings/binding_set.h" -#include "services/shell/public/cpp/interface_factory.h" -#include "services/shell/public/cpp/service.h" -#include "services/user/public/interfaces/user_service.mojom.h" - -namespace user_service { - -std::unique_ptr<shell::Service> CreateUserService( - scoped_refptr<base::SingleThreadTaskRunner> user_service_runner, - scoped_refptr<base::SingleThreadTaskRunner> leveldb_service_runner, - const base::Closure& quit_closure); - -class UserShellClient - : public shell::Service, - public shell::InterfaceFactory<mojom::UserService>, - public shell::InterfaceFactory<leveldb::mojom::LevelDBService> { - public: - UserShellClient( - scoped_refptr<base::SingleThreadTaskRunner> user_service_runner, - scoped_refptr<base::SingleThreadTaskRunner> leveldb_service_runner); - ~UserShellClient() override; - - private: - // |Service| override: - void OnStart(const shell::Identity& identity) override; - bool OnConnect(const shell::Identity& remote_identity, - shell::InterfaceRegistry* registry) override; - - // |InterfaceFactory<mojom::UserService>| implementation: - void Create(const shell::Identity& remote_identity, - mojom::UserServiceRequest request) override; - - // |InterfaceFactory<LevelDBService>| implementation: - void Create(const shell::Identity& remote_identity, - leveldb::mojom::LevelDBServiceRequest request) override; - - void OnLevelDBServiceError(); - - scoped_refptr<base::SingleThreadTaskRunner> user_service_runner_; - scoped_refptr<base::SingleThreadTaskRunner> leveldb_service_runner_; - - // We create these two objects so we can delete them on the correct task - // runners. - class UserServiceObjects; - std::unique_ptr<UserServiceObjects> user_objects_; - - class LevelDBServiceObjects; - std::unique_ptr<LevelDBServiceObjects> leveldb_objects_; - - DISALLOW_COPY_AND_ASSIGN(UserShellClient); -}; - -} // namespace user_service - -#endif // SERVICES_USER_USER_SHELL_CLIENT_H_
diff --git a/testing/android/junit/java/src/org/chromium/testing/local/BackgroundShadowAsyncTask.java b/testing/android/junit/java/src/org/chromium/testing/local/BackgroundShadowAsyncTask.java index e542128..ae53ee1 100644 --- a/testing/android/junit/java/src/org/chromium/testing/local/BackgroundShadowAsyncTask.java +++ b/testing/android/junit/java/src/org/chromium/testing/local/BackgroundShadowAsyncTask.java
@@ -47,6 +47,16 @@ } } + @Implementation + public final Result get() { + try { + runBackgroundTasks(); + return BackgroundShadowAsyncTask.super.get(); + } catch (Exception e) { + return null; + } + } + public static void runBackgroundTasks() throws Exception { sExecutorService.submit(new Runnable() { @Override @@ -55,4 +65,4 @@ } }).get(); } -} \ No newline at end of file +}
diff --git a/testing/android/proguard_for_test.flags b/testing/android/proguard_for_test.flags index a0f074a..3326074 100644 --- a/testing/android/proguard_for_test.flags +++ b/testing/android/proguard_for_test.flags
@@ -23,6 +23,6 @@ # then makes our calls to them use the implementation that we find in our .dex # file, which is broken. We need to rely on these calls resolving to the # system's implementation. See crbug.com/488192#c36. --keep class org.apache.** { +-keepnames class org.apache.** { *; }
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 1e9e202..5a71b48 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -6,6 +6,7 @@ "chrome_public_test_apk", "content_shell_apk", "content_shell_test_apk", + "mojo_test_apk", "system_webview_apk" ] }, @@ -18,13 +19,30 @@ "override_isolate_target": "android_webview_test_apk", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } ], - "hard_timeout": 1800 + "hard_timeout": 1800, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "android_webview_test_apk" }, @@ -32,11 +50,28 @@ "override_isolate_target": "android_webview_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "android_webview_unittests" @@ -45,11 +80,28 @@ "override_isolate_target": "base_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "base_unittests" @@ -61,13 +113,30 @@ "override_isolate_target": "blimp_test_apk", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } ], - "hard_timeout": 960 + "hard_timeout": 960, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "blimp_test_apk" }, @@ -75,11 +144,28 @@ "override_isolate_target": "blimp_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "blimp_unittests" @@ -88,13 +174,30 @@ "override_isolate_target": "blink_heap_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } ], - "hard_timeout": 120 + "hard_timeout": 120, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "blink_heap_unittests" }, @@ -102,11 +205,28 @@ "override_isolate_target": "breakpad_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "breakpad_unittests" @@ -115,11 +235,28 @@ "override_isolate_target": "capture_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "capture_unittests" @@ -128,11 +265,28 @@ "override_isolate_target": "cc_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "cc_unittests" @@ -144,13 +298,30 @@ "override_isolate_target": "chrome_public_test_apk", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } ], - "hard_timeout": 3600 + "hard_timeout": 3600, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "chrome_public_test_apk" }, @@ -161,13 +332,30 @@ "override_isolate_target": "chrome_sync_shell_test_apk", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } ], - "hard_timeout": 960 + "hard_timeout": 960, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "chrome_sync_shell_test_apk" }, @@ -175,11 +363,28 @@ "override_isolate_target": "components_browsertests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "components_browsertests" @@ -188,11 +393,28 @@ "override_isolate_target": "components_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "components_unittests" @@ -201,13 +423,30 @@ "override_isolate_target": "content_browsertests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } ], - "hard_timeout": 960 + "hard_timeout": 960, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "content_browsertests" }, @@ -218,13 +457,30 @@ "override_isolate_target": "content_shell_test_apk", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } ], - "hard_timeout": 960 + "hard_timeout": 960, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "content_shell_test_apk" }, @@ -232,11 +488,28 @@ "override_isolate_target": "content_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "content_unittests" @@ -245,11 +518,28 @@ "override_isolate_target": "device_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "device_unittests" @@ -258,11 +548,28 @@ "override_isolate_target": "events_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "events_unittests" @@ -271,11 +578,28 @@ "override_isolate_target": "gl_tests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "gl_tests" @@ -284,13 +608,30 @@ "override_isolate_target": "gl_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } ], - "hard_timeout": 60 + "hard_timeout": 60, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "gl_unittests" }, @@ -298,11 +639,28 @@ "override_isolate_target": "gpu_ipc_service_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "gpu_ipc_service_unittests" @@ -311,11 +669,28 @@ "override_isolate_target": "gpu_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "gpu_unittests" @@ -324,11 +699,28 @@ "override_isolate_target": "ipc_tests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "ipc_tests" @@ -337,11 +729,28 @@ "override_isolate_target": "media_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "media_unittests" @@ -350,13 +759,30 @@ "override_isolate_target": "mojo_common_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } ], - "hard_timeout": 60 + "hard_timeout": 60, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "mojo_common_unittests" }, @@ -364,13 +790,30 @@ "override_isolate_target": "mojo_public_application_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } ], - "hard_timeout": 60 + "hard_timeout": 60, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "mojo_public_application_unittests" }, @@ -378,13 +821,30 @@ "override_isolate_target": "mojo_public_bindings_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } ], - "hard_timeout": 60 + "hard_timeout": 60, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "mojo_public_bindings_unittests" }, @@ -392,13 +852,30 @@ "override_isolate_target": "mojo_public_system_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } ], - "hard_timeout": 60 + "hard_timeout": 60, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "mojo_public_system_unittests" }, @@ -406,13 +883,30 @@ "override_isolate_target": "mojo_runner_host_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } ], - "hard_timeout": 60 + "hard_timeout": 60, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "mojo_runner_host_unittests" }, @@ -420,25 +914,93 @@ "override_isolate_target": "mojo_system_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } ], - "hard_timeout": 120 + "hard_timeout": 120, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "mojo_system_unittests" }, { + "override_compile_targets": [ + "mojo_test_apk" + ], + "override_isolate_target": "mojo_test_apk", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], + "dimension_sets": [ + { + "device_os": "MMB29Q", + "device_type": "bullhead" + } + ], + "hard_timeout": 300, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "mojo_test_apk" + }, + { "override_isolate_target": "net_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "net_unittests" @@ -447,11 +1009,28 @@ "override_isolate_target": "sandbox_linux_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "sandbox_linux_unittests" @@ -460,11 +1039,28 @@ "override_isolate_target": "sql_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "sql_unittests" @@ -473,11 +1069,28 @@ "override_isolate_target": "ui_android_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "ui_android_unittests" @@ -486,11 +1099,28 @@ "override_isolate_target": "ui_base_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "ui_base_unittests" @@ -499,11 +1129,28 @@ "override_isolate_target": "ui_touch_selection_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "ui_touch_selection_unittests" @@ -512,11 +1159,28 @@ "override_isolate_target": "unit_tests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "MMB29Q", "device_type": "bullhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "unit_tests" @@ -556,13 +1220,30 @@ "override_isolate_target": "android_webview_test_apk", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } ], - "hard_timeout": 960 + "hard_timeout": 960, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "android_webview_test_apk" }, @@ -570,11 +1251,28 @@ "override_isolate_target": "android_webview_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "android_webview_unittests" @@ -583,11 +1281,28 @@ "override_isolate_target": "base_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "base_unittests" @@ -599,13 +1314,30 @@ "override_isolate_target": "blimp_test_apk", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } ], - "hard_timeout": 960 + "hard_timeout": 960, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "blimp_test_apk" }, @@ -613,11 +1345,28 @@ "override_isolate_target": "blimp_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "blimp_unittests" @@ -626,13 +1375,30 @@ "override_isolate_target": "blink_heap_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } ], - "hard_timeout": 60 + "hard_timeout": 60, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "blink_heap_unittests" }, @@ -640,11 +1406,28 @@ "override_isolate_target": "breakpad_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "breakpad_unittests" @@ -653,11 +1436,28 @@ "override_isolate_target": "capture_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "capture_unittests" @@ -666,11 +1466,28 @@ "override_isolate_target": "cc_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "cc_unittests" @@ -682,13 +1499,30 @@ "override_isolate_target": "chrome_public_test_apk", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } ], - "hard_timeout": 1200 + "hard_timeout": 1200, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "chrome_public_test_apk" }, @@ -699,13 +1533,30 @@ "override_isolate_target": "chrome_sync_shell_test_apk", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } ], - "hard_timeout": 960 + "hard_timeout": 960, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "chrome_sync_shell_test_apk" }, @@ -713,11 +1564,28 @@ "override_isolate_target": "components_browsertests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "components_browsertests" @@ -726,11 +1594,28 @@ "override_isolate_target": "components_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "components_unittests" @@ -739,13 +1624,30 @@ "override_isolate_target": "content_browsertests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } ], - "hard_timeout": 960 + "hard_timeout": 960, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "content_browsertests" }, @@ -756,13 +1658,30 @@ "override_isolate_target": "content_shell_test_apk", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } ], - "hard_timeout": 960 + "hard_timeout": 960, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "content_shell_test_apk" }, @@ -770,11 +1689,28 @@ "override_isolate_target": "content_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "content_unittests" @@ -783,11 +1719,28 @@ "override_isolate_target": "device_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "device_unittests" @@ -796,11 +1749,28 @@ "override_isolate_target": "events_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "events_unittests" @@ -809,11 +1779,28 @@ "override_isolate_target": "gl_tests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "gl_tests" @@ -822,13 +1809,30 @@ "override_isolate_target": "gl_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } ], - "hard_timeout": 30 + "hard_timeout": 30, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "gl_unittests" }, @@ -836,11 +1840,28 @@ "override_isolate_target": "gpu_ipc_service_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "gpu_ipc_service_unittests" @@ -849,11 +1870,28 @@ "override_isolate_target": "gpu_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "gpu_unittests" @@ -862,11 +1900,28 @@ "override_isolate_target": "ipc_tests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "ipc_tests" @@ -875,11 +1930,28 @@ "override_isolate_target": "media_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "media_unittests" @@ -888,27 +1960,68 @@ "override_isolate_target": "mojo_common_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } ], - "hard_timeout": 30 + "hard_timeout": 30, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "mojo_common_unittests" }, { + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "override_isolate_target": "mojo_public_application_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } ], - "hard_timeout": 30 + "hard_timeout": 30, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "mojo_public_application_unittests" }, @@ -916,13 +2029,30 @@ "override_isolate_target": "mojo_public_bindings_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } ], - "hard_timeout": 30 + "hard_timeout": 30, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "mojo_public_bindings_unittests" }, @@ -930,13 +2060,30 @@ "override_isolate_target": "mojo_public_system_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } ], - "hard_timeout": 30 + "hard_timeout": 30, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "mojo_public_system_unittests" }, @@ -944,13 +2091,30 @@ "override_isolate_target": "mojo_runner_host_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } ], - "hard_timeout": 30 + "hard_timeout": 30, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "mojo_runner_host_unittests" }, @@ -958,25 +2122,93 @@ "override_isolate_target": "mojo_system_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } ], - "hard_timeout": 60 + "hard_timeout": 60, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "mojo_system_unittests" }, { + "override_compile_targets": [ + "mojo_test_apk" + ], + "override_isolate_target": "mojo_test_apk", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], + "dimension_sets": [ + { + "device_os": "KTU84P", + "device_type": "hammerhead" + } + ], + "hard_timeout": 300, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "mojo_test_apk" + }, + { "override_isolate_target": "net_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "net_unittests" @@ -985,11 +2217,28 @@ "override_isolate_target": "sandbox_linux_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "sandbox_linux_unittests" @@ -998,11 +2247,28 @@ "override_isolate_target": "sql_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "sql_unittests" @@ -1011,11 +2277,28 @@ "override_isolate_target": "ui_android_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "ui_android_unittests" @@ -1024,11 +2307,28 @@ "override_isolate_target": "ui_base_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "ui_base_unittests" @@ -1037,11 +2337,28 @@ "override_isolate_target": "ui_touch_selection_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "ui_touch_selection_unittests" @@ -1050,11 +2367,28 @@ "override_isolate_target": "unit_tests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "unit_tests"
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index ecd29d8..de15aab 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -7,11 +7,28 @@ "override_isolate_target": "angle_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "gpu": "0000:0000", "os": "Android" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "angle_unittests", @@ -21,11 +38,28 @@ "override_isolate_target": "gl_tests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "gpu": "0000:0000", "os": "Android" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "gl_tests", @@ -35,11 +69,28 @@ "override_isolate_target": "gl_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "gpu": "0000:0000", "os": "Android" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "gl_unittests", @@ -282,12 +333,29 @@ "override_isolate_target": "angle_end2end_tests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "M", "device_type": "bullhead", "os": "Android" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "angle_end2end_tests", @@ -297,12 +365,29 @@ "override_isolate_target": "angle_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "M", "device_type": "bullhead", "os": "Android" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "angle_unittests", @@ -312,12 +397,29 @@ "override_isolate_target": "gl_tests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "M", "device_type": "bullhead", "os": "Android" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "gl_tests", @@ -327,12 +429,29 @@ "override_isolate_target": "gl_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "device_os": "M", "device_type": "bullhead", "os": "Android" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "gl_unittests", @@ -584,11 +703,28 @@ "override_isolate_target": "angle_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "gpu": "0000:0000", "os": "Android" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "angle_unittests", @@ -598,11 +734,28 @@ "override_isolate_target": "gl_tests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "gpu": "0000:0000", "os": "Android" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "gl_tests", @@ -612,11 +765,28 @@ "override_isolate_target": "gl_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "gpu": "0000:0000", "os": "Android" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "gl_unittests", @@ -859,11 +1029,28 @@ "override_isolate_target": "angle_end2end_tests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "gpu": "0000:0000", "os": "Android" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "angle_end2end_tests", @@ -873,11 +1060,28 @@ "override_isolate_target": "angle_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "gpu": "0000:0000", "os": "Android" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "angle_unittests", @@ -887,11 +1091,28 @@ "override_isolate_target": "gl_tests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "gpu": "0000:0000", "os": "Android" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "gl_tests", @@ -901,11 +1122,28 @@ "override_isolate_target": "gl_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "gpu": "0000:0000", "os": "Android" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "gl_unittests", @@ -1148,11 +1386,28 @@ "override_isolate_target": "angle_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "gpu": "0000:0000", "os": "Android" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "angle_unittests", @@ -1162,11 +1417,28 @@ "override_isolate_target": "gl_tests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "gpu": "0000:0000", "os": "Android" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "gl_tests", @@ -1176,11 +1448,28 @@ "override_isolate_target": "gl_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "gpu": "0000:0000", "os": "Android" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "gl_unittests", @@ -1423,11 +1712,28 @@ "override_isolate_target": "angle_end2end_tests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "gpu": "0000:0000", "os": "Android" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "angle_end2end_tests", @@ -1437,11 +1743,28 @@ "override_isolate_target": "angle_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "gpu": "0000:0000", "os": "Android" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "angle_unittests", @@ -1451,11 +1774,28 @@ "override_isolate_target": "gl_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "gpu": "0000:0000", "os": "Android" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "gl_unittests", @@ -5780,32 +6120,6 @@ "--show-stdout", "--browser=release", "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", - "--webgl-conformance-version=2.0.0", - "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json" - ], - "isolate_name": "telemetry_gpu_integration_test", - "name": "webgl2_conformance_tests", - "override_compile_targets": [ - "telemetry_gpu_integration_test_run" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0a2e", - "os": "Mac-10.10" - } - ], - "shards": 15 - } - }, - { - "args": [ - "webgl_conformance", - "--show-stdout", - "--browser=release", - "-v", "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc" ], "isolate_name": "telemetry_gpu_integration_test", @@ -7402,34 +7716,7 @@ "use_xvfb": false } ], - "isolated_scripts": [ - { - "args": [ - "webgl_conformance", - "--show-stdout", - "--browser=release", - "-v", - "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", - "--webgl-conformance-version=2.0.0", - "--read-abbreviated-json-results-from=../../content/test/data/gpu/webgl2_conformance_tests_output.json" - ], - "isolate_name": "telemetry_gpu_integration_test", - "name": "webgl2_conformance_tests", - "override_compile_targets": [ - "telemetry_gpu_integration_test_run" - ], - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "8086:0a2e", - "os": "Mac-10.10" - } - ], - "shards": 15 - } - } - ] + "isolated_scripts": [] }, "Optional Mac 10.10 Retina Release (AMD)": { "gtest_tests": [
diff --git a/testing/buildbot/chromium.linux.json b/testing/buildbot/chromium.linux.json index f04ba7e..2addd4a 100644 --- a/testing/buildbot/chromium.linux.json +++ b/testing/buildbot/chromium.linux.json
@@ -29,6 +29,13 @@ "override_isolate_target": "android_webview_test_apk", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "6", @@ -36,7 +43,17 @@ "device_type": "hammerhead" } ], - "hard_timeout": 960 + "hard_timeout": 960, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "android_webview_test_apk" }, @@ -44,12 +61,29 @@ "override_isolate_target": "android_webview_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "android_webview_unittests" @@ -58,12 +92,29 @@ "override_isolate_target": "base_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "base_unittests" @@ -75,6 +126,13 @@ "override_isolate_target": "blimp_test_apk", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", @@ -82,7 +140,17 @@ "device_type": "hammerhead" } ], - "hard_timeout": 600 + "hard_timeout": 600, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "blimp_test_apk" }, @@ -90,12 +158,29 @@ "override_isolate_target": "blimp_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "blimp_unittests" @@ -104,6 +189,13 @@ "override_isolate_target": "blink_heap_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", @@ -111,7 +203,17 @@ "device_type": "hammerhead" } ], - "hard_timeout": 120 + "hard_timeout": 120, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "blink_heap_unittests" }, @@ -119,12 +221,29 @@ "override_isolate_target": "breakpad_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "breakpad_unittests" @@ -133,12 +252,29 @@ "override_isolate_target": "capture_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "capture_unittests" @@ -147,12 +283,29 @@ "override_isolate_target": "cc_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "cc_unittests" @@ -164,6 +317,13 @@ "override_isolate_target": "chrome_public_test_apk", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "6", @@ -171,7 +331,17 @@ "device_type": "hammerhead" } ], - "hard_timeout": 1200 + "hard_timeout": 1200, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "chrome_public_test_apk" }, @@ -182,6 +352,13 @@ "override_isolate_target": "chrome_sync_shell_test_apk", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", @@ -189,7 +366,17 @@ "device_type": "hammerhead" } ], - "hard_timeout": 600 + "hard_timeout": 600, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "chrome_sync_shell_test_apk" }, @@ -197,12 +384,29 @@ "override_isolate_target": "components_browsertests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "components_browsertests" @@ -211,12 +415,29 @@ "override_isolate_target": "components_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "components_unittests" @@ -225,6 +446,13 @@ "override_isolate_target": "content_browsertests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "6", @@ -232,7 +460,17 @@ "device_type": "hammerhead" } ], - "hard_timeout": 960 + "hard_timeout": 960, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "content_browsertests" }, @@ -243,6 +481,13 @@ "override_isolate_target": "content_shell_test_apk", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", @@ -250,7 +495,17 @@ "device_type": "hammerhead" } ], - "hard_timeout": 1920 + "hard_timeout": 1920, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "content_shell_test_apk" }, @@ -258,12 +513,29 @@ "override_isolate_target": "content_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "content_unittests" @@ -272,12 +544,29 @@ "override_isolate_target": "device_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "device_unittests" @@ -286,12 +575,29 @@ "override_isolate_target": "events_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "events_unittests" @@ -300,12 +606,29 @@ "override_isolate_target": "gl_tests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "gl_tests" @@ -314,6 +637,13 @@ "override_isolate_target": "gl_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", @@ -321,7 +651,17 @@ "device_type": "hammerhead" } ], - "hard_timeout": 60 + "hard_timeout": 60, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "gl_unittests" }, @@ -329,12 +669,29 @@ "override_isolate_target": "gpu_ipc_service_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "gpu_ipc_service_unittests" @@ -343,12 +700,29 @@ "override_isolate_target": "gpu_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "gpu_unittests" @@ -357,12 +731,29 @@ "override_isolate_target": "ipc_tests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "ipc_tests" @@ -371,12 +762,29 @@ "override_isolate_target": "media_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "media_unittests" @@ -385,6 +793,13 @@ "override_isolate_target": "mojo_common_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", @@ -392,7 +807,17 @@ "device_type": "hammerhead" } ], - "hard_timeout": 60 + "hard_timeout": 60, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "mojo_common_unittests" }, @@ -400,6 +825,13 @@ "override_isolate_target": "mojo_public_application_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", @@ -407,7 +839,17 @@ "device_type": "hammerhead" } ], - "hard_timeout": 60 + "hard_timeout": 60, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "mojo_public_application_unittests" }, @@ -415,6 +857,13 @@ "override_isolate_target": "mojo_public_bindings_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", @@ -422,7 +871,17 @@ "device_type": "hammerhead" } ], - "hard_timeout": 60 + "hard_timeout": 60, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "mojo_public_bindings_unittests" }, @@ -430,6 +889,13 @@ "override_isolate_target": "mojo_public_system_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", @@ -437,7 +903,17 @@ "device_type": "hammerhead" } ], - "hard_timeout": 60 + "hard_timeout": 60, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "mojo_public_system_unittests" }, @@ -445,6 +921,13 @@ "override_isolate_target": "mojo_runner_host_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", @@ -452,7 +935,17 @@ "device_type": "hammerhead" } ], - "hard_timeout": 60 + "hard_timeout": 60, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "mojo_runner_host_unittests" }, @@ -460,6 +953,13 @@ "override_isolate_target": "mojo_system_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", @@ -467,20 +967,82 @@ "device_type": "hammerhead" } ], - "hard_timeout": 120 + "hard_timeout": 120, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] }, "test": "mojo_system_unittests" }, { - "override_isolate_target": "net_unittests", + "override_compile_targets": [ + "mojo_test_apk" + ], + "override_isolate_target": "mojo_test_apk", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "hard_timeout": 300, + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } + ] + }, + "test": "mojo_test_apk" + }, + { + "override_isolate_target": "net_unittests", + "swarming": { + "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], + "dimension_sets": [ + { + "android_devices": "4", + "device_os": "KTU84P", + "device_type": "hammerhead" + } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "net_unittests" @@ -489,12 +1051,29 @@ "override_isolate_target": "sandbox_linux_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "sandbox_linux_unittests" @@ -503,12 +1082,29 @@ "override_isolate_target": "sql_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "sql_unittests" @@ -517,12 +1113,29 @@ "override_isolate_target": "ui_android_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "ui_android_unittests" @@ -531,12 +1144,29 @@ "override_isolate_target": "ui_base_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "ui_base_unittests" @@ -545,12 +1175,29 @@ "override_isolate_target": "ui_touch_selection_unittests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "ui_touch_selection_unittests" @@ -559,12 +1206,29 @@ "override_isolate_target": "unit_tests", "swarming": { "can_use_on_swarming_builders": true, + "cipd_packages": [ + { + "cipd_package": "infra/tools/luci/logdog/butler/${platform}", + "location": "bin", + "revision": "git_revision:3ff24775a900b675866fbcacf2a8f98a18b2a16a" + } + ], "dimension_sets": [ { "android_devices": "4", "device_os": "KTU84P", "device_type": "hammerhead" } + ], + "output_links": [ + { + "link": [ + "https://luci-logdog.appspot.com/v/?s", + "=android%2Fswarming%2Flogcats%2F", + "${TASK_ID}%2F%2B%2Funified_logcats" + ], + "name": "shard #${SHARD_INDEX} logcats" + } ] }, "test": "unit_tests" @@ -757,6 +1421,9 @@ }, { "test": "content_shell_test_apk" + }, + { + "test": "mojo_test_apk" } ], "junit_tests": [
diff --git a/testing/buildbot/filters/browser-side-navigation.linux.browser_tests.filter b/testing/buildbot/filters/browser-side-navigation.linux.browser_tests.filter index 403811f154..67bce41 100644 --- a/testing/buildbot/filters/browser-side-navigation.linux.browser_tests.filter +++ b/testing/buildbot/filters/browser-side-navigation.linux.browser_tests.filter
@@ -29,7 +29,6 @@ -ChromeMainTest.SecondLaunchFromIncognitoWithNormalUrl -ChromeRenderProcessHostTest.DevToolsOnSelfInOwnProcess -ChromeRenderProcessHostTest.DevToolsOnSelfInOwnProcessPPT --ChromeResourceDispatcherHostDelegateBrowserTest.PolicyHeaderForRedirect -ChromeSecurityStateModelClientTest.AddedTab -ChromeSecurityStateModelClientTest.HttpsPage -ChromeSecurityStateModelClientTest.MixedContent @@ -153,7 +152,6 @@ -ProcessesApiTest.Processes -PushMessaging* -RedirectTest.ClientServerServer --RedirectTest.Server -ReferrerPolicyTest.HttpLeftClickRedirectToHTTPOriginWhenCrossOrigin -ReferrerPolicyTest.HttpsMiddleClickOrigin -ReferrerPolicyTest.HttpsMiddleClickRedirect
diff --git a/testing/buildbot/filters/browser-side-navigation.linux.content_browsertests.filter b/testing/buildbot/filters/browser-side-navigation.linux.content_browsertests.filter index c1c5de1..4f38af10 100644 --- a/testing/buildbot/filters/browser-side-navigation.linux.content_browsertests.filter +++ b/testing/buildbot/filters/browser-side-navigation.linux.content_browsertests.filter
@@ -2,6 +2,7 @@ -IFrameZoomBrowserTest.RedirectToPageWithSubframeZoomsCorrectly -IFrameZoomBrowserTest.SubframesDontZoomIndependently -NavigationControllerBrowserTest.BackTwiceToIframeWithContent +-NavigationControllerBrowserTest.EnsureSamePageNavigationUpdatesFrameNavigationEntry -NavigationControllerBrowserTest.FrameNavigationEntry_BackWithRedirect -NavigationControllerBrowserTest.FrameNavigationEntry_SameOriginBackWithRedirect -NavigationHandleImplBrowserTest.VerifyFormRequestContextType @@ -9,4 +10,4 @@ -RenderFrameHostManagerTest.RestoreSubframeFileAccessForHistoryNavigation -RequestDataResourceDispatcherHostBrowserTest.* -ServiceWorker* --SitePerProcessIgnoreCertErrorsBrowserTest.CrossSiteRedirectCertificateStore \ No newline at end of file +-SitePerProcessIgnoreCertErrorsBrowserTest.CrossSiteRedirectCertificateStore
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index 72853ff..85f6a1e 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -452,6 +452,10 @@ "label": "//mojo/edk/system:mojo_system_unittests", "type": "console_test_launcher", }, + "mojo_test_apk": { + "label": "//mojo/android:mojo_test_apk", + "type": "console_test_launcher", + }, "mus_clipboard_unittests": { "label": "//services/ui/clipboard:mus_clipboard_unittests", "type": "windowed_test_launcher",
diff --git a/testing/iossim/iossim.mm b/testing/iossim/iossim.mm index ebe6249f..22b97a6f 100644 --- a/testing/iossim/iossim.mm +++ b/testing/iossim/iossim.mm
@@ -89,6 +89,14 @@ [_task waitUntilExit]; } +- (void)launch { + [_task launch]; +} + +- (void)waitUntilExit { + [_task waitUntilExit]; +} + @end // Return array of available iOS runtime dictionaries. Unavailable (old Xcode @@ -127,9 +135,16 @@ initWithArguments:@[ @"simctl", @"list", @"-j" ]] autorelease]; NSPipe* out = [NSPipe pipe]; [task setStandardOutput:out]; - [task run]; + // In the rest of the this file we read from the pipe after -waitUntilExit + // (We normally wrap -launch and -waitUntilExit in one -run method). However, + // on some swarming slaves this led to a hang on simctl's pipe. Since the + // output of simctl is so instant, reading it before exit seems to work, and + // seems to avoid the hang. + [task launch]; NSData* data = [[out fileHandleForReading] readDataToEndOfFile]; + [task waitUntilExit]; + NSError* error = nil; return [NSJSONSerialization JSONObjectWithData:data options:kNilOptions
diff --git a/testing/libfuzzer/fuzzers/dicts/xml.dict b/testing/libfuzzer/fuzzers/dicts/xml.dict index ff44a298..8449cb0 100644 --- a/testing/libfuzzer/fuzzers/dicts/xml.dict +++ b/testing/libfuzzer/fuzzers/dicts/xml.dict
@@ -23,57 +23,94 @@ entity_external="&a;" entity_hex="" -string_any="ANY" -string_brackets="[]" -string_cdata="CDATA" +# keywords +"ANY" +"ATTLIST" +"CDATA" +"DOCTYPE" +"ELEMENT" +"EMPTY" +"ENTITIES" +"ENTITY" +"FIXED" +"ID" +"IDREF" +"IDREFS" +"IGNORE" +"IMPLIED" +"INCLUDE" +"NDATA" +"NMTOKEN" +"NMTOKENS" +"NOTATION" +"PCDATA" +"PUBLIC" +"REQUIRED" +"SYSTEM" + +# Various tag parts +"<" +">" +"/>" +"</" +"<?" +"?>" +"<!" +"!>" +"[]" +"]]" +"<![CDATA[" +"<![CDATA[]]>" +"\"\"" +"''" +"=\"\"" +"=''" + +# DTD +"<!ATTLIST" +"<!DOCTYPE" +"<!ELEMENT" +"<!ENTITY" +"<![IGNORE[" +"<![INCLUDE[" +"<!NOTATION" +"#CDATA" +"#FIXED" +"#IMPLIED" +"#PCDATA" +"#REQUIRED" + +# Encodings +"ISO-8859-1" +"US-ASCII" +"UTF-8" +"UTF-16" +"UTF-16BE" +"UTF-16LE" + +# Namespaces and schemas +"xmlns" +"xmlns:" +"xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"" +"xmlns:xml=\"http://www.w3.org/XML/1998/namespace\"" +"xmlns:xmlns=\"http://www.w3.org/2000/xmlns\"" + string_col_fallback=":fallback" string_col_generic=":a" string_col_include=":include" string_dashes="--" -string_empty="EMPTY" -string_empty_dblquotes="\"\"" -string_empty_quotes="''" -string_entities="ENTITIES" -string_entity="ENTITY" -string_fixed="#FIXED" -string_id="ID" -string_idref="IDREF" -string_idrefs="IDREFS" -string_implied="#IMPLIED" -string_nmtoken="NMTOKEN" -string_nmtokens="NMTOKENS" -string_notation="NOTATION" string_parentheses="()" -string_pcdata="#PCDATA" string_percent="%a" -string_public="PUBLIC" -string_required="#REQUIRED" string_schema=":schema" -string_system="SYSTEM" string_ucs4="UCS-4" -string_utf16="UTF-16" -string_utf8="UTF-8" -string_xmlns="xmlns:" - -tag_attlist="<!ATTLIST" -tag_cdata="<![CDATA[" tag_close="</a>" -tag_doctype="<!DOCTYPE" -tag_element="<!ELEMENT" -tag_entity="<!ENTITY" -tag_ignore="<![IGNORE[" -tag_include="<![INCLUDE[" -tag_notation="<!NOTATION" tag_open="<a>" tag_open_close="<a />" -tag_open_exclamation="<!" -tag_open_q="<?" -tag_sq2_close="]]>" -tag_xml_q="<?xml?>" + + +"<?xml?>" "http://docboo" "http://www.w" -"UTF-16LE" -"xmlns" "he30" "he2" "IET"
diff --git a/testing/libfuzzer/fuzzers/sqlite3_prepare_v2_fuzzer.cc b/testing/libfuzzer/fuzzers/sqlite3_prepare_v2_fuzzer.cc index cd7e3b4..8f7d90a6 100644 --- a/testing/libfuzzer/fuzzers/sqlite3_prepare_v2_fuzzer.cc +++ b/testing/libfuzzer/fuzzers/sqlite3_prepare_v2_fuzzer.cc
@@ -42,7 +42,13 @@ return 0; sqlite3* db; - if (SQLITE_OK != sqlite3_open(":memory:", &db)) + int return_code = sqlite3_open_v2( + "db.db", + &db, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY, 0); + + + if (SQLITE_OK != return_code) return 0; // Use first byte as random selector for other parameters.
diff --git a/testing/variations/fieldtrial_testing_config_android.json b/testing/variations/fieldtrial_testing_config_android.json index 7476b6e..8bead13 100644 --- a/testing/variations/fieldtrial_testing_config_android.json +++ b/testing/variations/fieldtrial_testing_config_android.json
@@ -305,6 +305,18 @@ "group_name": "Enabled" } ], + "ParseHTMLOnMainThread": [ + { + "enable_features": [ + "ParseHTMLOnMainThread" + ], + "group_name": "Enabled", + "params": { + "parseHTMLOnMainThreadCoalesceChunks": "false", + "parseHTMLOnMainThreadSyncTokenize": "false" + } + } + ], "PassiveDocumentEventListeners": [ { "enable_features": [
diff --git a/testing/variations/fieldtrial_testing_config_linux.json b/testing/variations/fieldtrial_testing_config_linux.json index a60bc56..47848baf8 100644 --- a/testing/variations/fieldtrial_testing_config_linux.json +++ b/testing/variations/fieldtrial_testing_config_linux.json
@@ -116,6 +116,14 @@ "group_name": "Enabled" } ], + "MaterialDesignUserManager": [ + { + "enable_features": [ + "MaterialDesignUserManager" + ], + "group_name": "Enabled" + } + ], "MojoChannel": [ { "group_name": "Enabled" @@ -160,6 +168,18 @@ "group_name": "Enabled" } ], + "ParseHTMLOnMainThread": [ + { + "enable_features": [ + "ParseHTMLOnMainThread" + ], + "group_name": "Enabled", + "params": { + "parseHTMLOnMainThreadCoalesceChunks": "false", + "parseHTMLOnMainThreadSyncTokenize": "false" + } + } + ], "PassiveDocumentEventListeners": [ { "enable_features": [
diff --git a/testing/variations/fieldtrial_testing_config_mac.json b/testing/variations/fieldtrial_testing_config_mac.json index 6c5b79d..dce91460 100644 --- a/testing/variations/fieldtrial_testing_config_mac.json +++ b/testing/variations/fieldtrial_testing_config_mac.json
@@ -152,6 +152,14 @@ "group_name": "Enabled" } ], + "MaterialDesignUserManager": [ + { + "enable_features": [ + "MaterialDesignUserManager" + ], + "group_name": "Enabled" + } + ], "MojoChannel": [ { "group_name": "Enabled" @@ -196,6 +204,18 @@ "group_name": "Enabled" } ], + "ParseHTMLOnMainThread": [ + { + "enable_features": [ + "ParseHTMLOnMainThread" + ], + "group_name": "Enabled", + "params": { + "parseHTMLOnMainThreadCoalesceChunks": "false", + "parseHTMLOnMainThreadSyncTokenize": "false" + } + } + ], "PassiveDocumentEventListeners": [ { "enable_features": [
diff --git a/testing/variations/fieldtrial_testing_config_win.json b/testing/variations/fieldtrial_testing_config_win.json index 6453653..38d6409 100644 --- a/testing/variations/fieldtrial_testing_config_win.json +++ b/testing/variations/fieldtrial_testing_config_win.json
@@ -100,6 +100,14 @@ "group_name": "Enabled" } ], + "EnableWin32kLockDownMimeTypes": [ + { + "group_name": "PPAPILockdown_Enabled", + "params": { + "*": "Enabled" + } + } + ], "ExpectCTReporting": [ { "enable_features": [ @@ -161,6 +169,14 @@ "group_name": "Enabled" } ], + "MaterialDesignUserManager": [ + { + "enable_features": [ + "MaterialDesignUserManager" + ], + "group_name": "Enabled" + } + ], "MojoChannel": [ { "group_name": "Enabled" @@ -236,6 +252,18 @@ "group_name": "Enabled" } ], + "ParseHTMLOnMainThread": [ + { + "enable_features": [ + "ParseHTMLOnMainThread" + ], + "group_name": "Enabled", + "params": { + "parseHTMLOnMainThreadCoalesceChunks": "false", + "parseHTMLOnMainThreadSyncTokenize": "false" + } + } + ], "PassiveDocumentEventListeners": [ { "enable_features": [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation b/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation index 0ee8d4e5..979a9f0 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-browser-side-navigation
@@ -64,11 +64,6 @@ # https://crbug.com/576272: PlzNavigate: Navigation Timing API support http/tests/misc/timer-vs-loading.html [ Crash ] - http/tests/misc/webtiming-cross-origin-and-back.html [ Failure ] - http/tests/misc/webtiming-one-redirect.php [ Failure ] - http/tests/misc/webtiming-two-redirects.php [ Failure ] - http/tests/w3c/webperf/approved/navigation-timing/html/test_timing_attributes_order.html [ Failure ] - http/tests/w3c/webperf/approved/navigation-timing/html/test_timing_server_redirect.html [ Failure ] http/tests/w3c/webperf/submission/Google/resource-timing/html/test_resource_redirects.html [ Failure ] http/tests/w3c/webperf/submission/Intel/resource-timing/test_resource_timing_cross_origin_redirect_chain_allow_timing.html [ Timeout ] http/tests/w3c/webperf/submission/Intel/resource-timing/test_resource_timing_cross_origin_redirect_chain.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 index da40741..d3180834 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2 +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-slimming-paint-v2
@@ -105,7 +105,6 @@ compositing/contents-opaque/layer-opacity.html [ Failure ] compositing/contents-opaque/layer-transform.html [ Failure ] compositing/contents-opaque/overflow-hidden-child-layers.html [ Failure ] -compositing/culling/clear-fixed-iframe.html [ Failure ] compositing/culling/filter-occlusion-alpha-large.html [ Failure ] compositing/culling/filter-occlusion-alpha.html [ Failure ] compositing/culling/filter-occlusion-blur-large.html [ Failure ] @@ -318,7 +317,9 @@ compositing/overflow/opt-in-if-composited.html [ Failure ] compositing/overflow/overflow-compositing-descendant.html [ Failure ] compositing/overflow/overflow-scaled-descendant-overlapping.html [ Crash Timeout ] +compositing/overflow/overflow-scroll-with-opaque-background.html [ Failure ] compositing/overflow/overflow-scroll-with-pointer-events-toggle.html [ Failure ] +compositing/overflow/overflow-scroll-with-transparent-background.html [ Failure ] compositing/overflow/overflow-scrollbar-layers.html [ Failure ] compositing/overflow/reparented-scrollbars-non-sc-anc.html [ Failure ] compositing/overflow/resize-painting.html [ Failure ] @@ -340,6 +341,9 @@ compositing/overflow/updating-scrolling-container-and-content.html [ Failure ] compositing/overflow/updating-scrolling-container.html [ Failure ] compositing/overflow/updating-scrolling-content.html [ Failure ] +compositing/overlap-blending/children-opacity-huge.html [ Failure ] +compositing/overlap-blending/children-opacity-no-overlap.html [ Failure ] +compositing/overlap-blending/reflection-opacity-huge.html [ Failure ] compositing/overlap-test-with-filter.html [ Failure ] compositing/perpendicular-layer-sorting.html [ Failure ] compositing/plugins/webplugin-reflection.html [ Failure ] @@ -410,9 +414,7 @@ compositing/scrollbars/nested-overlay-scrollbars.html [ Failure ] compositing/self-painting-layers.html [ Failure ] compositing/shadows/shadow-drawing.html [ Failure ] -compositing/sibling-positioning.html [ Failure ] compositing/squashing/add-remove-squashed-layers.html [ Failure ] -compositing/squashing/animation-repaint-crash.html [ Crash ] compositing/squashing/clipping-ancestor.html [ Failure ] compositing/squashing/composited-bounds-for-negative-z.html [ Failure ] compositing/squashing/do-not-squash-non-self-painting-layer.html [ Failure ] @@ -464,7 +466,6 @@ compositing/tiled-layers-hidpi.html [ Failure ] compositing/transitions/scale-transition-no-start.html [ Failure ] compositing/update-paint-phases.html [ Failure ] -compositing/video-frame-size-change.html [ Crash Failure ] compositing/video/video-poster.html [ Crash Failure ] compositing/video/video-reflection.html [ Crash ] compositing/visibility/layer-visible-content.html [ Failure ] @@ -474,7 +475,6 @@ compositing/visibility/visibility-image-layers.html [ Failure ] compositing/visibility/visibility-simple-video-layer.html [ Failure ] compositing/webgl/webgl-reflection.html [ Failure ] -compositing/webgl/webgl-repaint.html [ Crash Failure ] compositing/webgl/webgl-with-accelerated-background-color.html [ Failure ] compositing/will-change/composited-layers.html [ Failure ] compositing/will-change/containing-block-added.html [ Failure ] @@ -525,6 +525,7 @@ fast/block/positioning/047.html [ Failure ] fast/block/positioning/051.html [ Failure ] fast/block/positioning/055.html [ Failure ] +fast/block/positioning/absolute-length-of-neg-666666.html [ Failure ] fast/block/positioning/auto/007.html [ Failure ] fast/block/positioning/auto/vertical-lr/005.html [ Failure ] fast/block/positioning/auto/vertical-rl/005.html [ Failure ] @@ -581,8 +582,6 @@ fast/box-shadow/box-shadow-clipped-slices.html [ Failure Timeout ] fast/box-shadow/box-shadow-transformed.html [ Failure ] fast/box-shadow/box-shadow.html [ Failure ] -fast/box-shadow/negative-shadow-box-expand.html [ Failure ] -fast/box-shadow/negative-shadow-box-shrink.html [ Failure ] fast/box-shadow/scaled-box-shadow.html [ Failure ] fast/box-shadow/single-pixel-shadow.html [ Failure ] fast/box-sizing/box-sizing.html [ Failure ] @@ -591,11 +590,8 @@ fast/canvas/alpha.html [ Failure ] fast/canvas/canvas-composite-repaint-by-all-imagesource.html [ Crash Failure ] fast/canvas/canvas-composite-video.html [ Failure ] -fast/canvas/canvas-createImageBitmap-svg-no-intrinsic-size.html [ Crash ] -fast/canvas/canvas-createImageBitmap-svg.html [ Crash ] fast/canvas/canvas-css-clip-path.html [ Failure ] fast/canvas/webgl/pixelated.html [ Failure ] -fast/canvas/webgl/webgl-layer-update.html [ Crash Failure ] fast/clip/010.html [ Crash ] fast/clip/nestedTransparencyClip.html [ Failure ] fast/clip/outline-overflowClip.html [ Failure ] @@ -606,8 +602,6 @@ fast/clip/overflow-border-radius-fixed-position.html [ Failure ] fast/clip/overflow-border-radius-transformed.html [ Failure ] fast/css-generated-content/014.html [ Failure ] -fast/css-generated-content/after-order.html [ Failure ] -fast/css-generated-content/drag-state.html [ Crash Timeout ] fast/css-generated-content/table-parts-before-and-after.html [ Failure ] fast/css-grid-layout/grid-element-change-columns-repaint.html [ Failure ] fast/css-grid-layout/grid-element-change-rows-repaint.html [ Failure ] @@ -643,14 +637,7 @@ fast/css/only-child-pseudo-class.html [ Failure ] fast/css/only-of-type-pseudo-class.html [ Failure ] fast/css/outline-auto-empty-rects.html [ Failure ] -fast/css/relative-positioned-block-nested-with-inline-parent-dynamic-removed.html [ Failure ] -fast/css/relative-positioned-block-nested-with-inline-parent-dynamic.html [ Failure ] -fast/css/relative-positioned-block-nested-with-inline-parent-multiple-descendant-blocks-dynamic.html [ Failure ] -fast/css/relative-positioned-block-with-inline-ancestor-and-parent-dynamic.html [ Failure ] -fast/css/relative-positioned-block-with-inline-ancestor-dynamic-removed.html [ Failure ] -fast/css/relative-positioned-block-with-inline-ancestor-dynamic.html [ Failure ] -fast/css/relative-positioned-block-with-inline-parent-dynamic-removed.html [ Failure ] -fast/css/relative-positioned-block-with-inline-parent-dynamic.html [ Failure ] +fast/css/outline-offset-large.html [ Failure ] fast/css/resize-corner-tracking-transformed-iframe.html [ Failure ] fast/css/resize-corner-tracking-transformed.html [ Failure ] fast/css/rtl-ordering.html [ Failure ] @@ -669,8 +656,6 @@ fast/css/vertical-text-overflow-ellipsis-text-align-justify.html [ Failure ] fast/css/vertical-text-overflow-ellipsis-text-align-left.html [ Failure ] fast/css/vertical-text-overflow-ellipsis-text-align-right.html [ Failure ] -fast/css/ZeroOpacityLayers.html [ Failure ] -fast/css/ZeroOpacityLayers2.html [ Failure ] fast/deprecated-flexbox/009-horizontal.html [ Failure ] fast/deprecated-flexbox/009.html [ Failure ] fast/deprecated-flexbox/016.html [ Failure ] @@ -682,15 +667,11 @@ fast/dom/Window/open-existing-pop-up-blocking.html [ Failure ] fast/dom/Window/property-access-on-cached-properties-after-frame-navigated.html [ Failure ] fast/dynamic/anchor-lock.html [ Failure ] -fast/dynamic/anonymous-block-layer-lost.html [ Failure ] fast/dynamic/first-letter-after-list-marker.html [ Failure ] fast/encoding/utf-16-big-endian.html [ Failure ] fast/encoding/utf-16-little-endian.html [ Failure ] fast/events/autoscroll.html [ Failure ] fast/events/context-no-deselect.html [ Failure ] -fast/events/drag-display-none-element.html [ Crash Timeout ] -fast/events/move-event-handler-between-framehosts.html [ Failure ] -fast/events/onunload-not-on-body.html [ Crash ] fast/events/reveal-link-when-focused.html [ Failure ] fast/events/scale-and-scroll-body.html [ Crash Timeout ] fast/events/scale-and-scroll-iframe-body.html [ Crash Timeout ] @@ -704,7 +685,6 @@ fast/events/touch/compositor-touch-hit-rects-squashing.html [ Failure ] fast/events/touch/compositor-touch-hit-rects.html [ Failure ] fast/events/touch/touch-rect-crash-on-unpromote-layer.html [ Failure ] -fast/files/domurl-script-execution-context-crash.html [ Failure ] fast/files/file-in-input-display.html [ Failure ] fast/forms/001.html [ Failure ] fast/forms/basic-buttons.html [ Failure ] @@ -725,32 +705,13 @@ fast/forms/calendar-picker/calendar-picker-appearance-zoom125.html [ Crash Timeout ] fast/forms/calendar-picker/calendar-picker-appearance-zoom200.html [ Crash Timeout ] fast/forms/calendar-picker/calendar-picker-appearance.html [ Crash Timeout ] -fast/forms/calendar-picker/calendar-picker-date-types.html [ Crash ] -fast/forms/calendar-picker/calendar-picker-datetimelocal-with-step.html [ Crash ] -fast/forms/calendar-picker/calendar-picker-mouse-operations.html [ Crash ] -fast/forms/calendar-picker/calendar-picker-touch-operations.html [ Crash ] -fast/forms/calendar-picker/calendar-picker-with-step.html [ Crash ] -fast/forms/calendar-picker/date-open-picker-with-f4-key.html [ Crash ] -fast/forms/calendar-picker/date-picker-ax.html [ Crash ] -fast/forms/calendar-picker/date-picker-events.html [ Crash ] -fast/forms/calendar-picker/datetimelocal-open-picker-with-f4-key.html [ Crash ] -fast/forms/calendar-picker/month-open-picker-with-f4-key.html [ Crash ] fast/forms/calendar-picker/month-picker-appearance-step.html [ Crash Timeout ] fast/forms/calendar-picker/month-picker-appearance.html [ Crash Timeout ] -fast/forms/calendar-picker/month-picker-ax.html [ Crash ] -fast/forms/calendar-picker/month-picker-mouse-operations.html [ Crash ] -fast/forms/calendar-picker/month-picker-touch-operations.html [ Crash ] -fast/forms/calendar-picker/month-picker-with-step.html [ Crash ] -fast/forms/calendar-picker/week-open-picker-with-f4-key.html [ Crash ] fast/forms/calendar-picker/week-picker-appearance-step.html [ Crash Timeout ] fast/forms/calendar-picker/week-picker-appearance.html [ Crash Timeout ] -fast/forms/calendar-picker/week-picker-ax.html [ Crash ] -fast/forms/calendar-picker/week-picker-mouse-operations.html [ Crash ] -fast/forms/calendar-picker/week-picker-touch-operations.html [ Crash ] fast/forms/color/color-suggestion-picker-appearance-zoom125.html [ Crash Timeout ] fast/forms/color/color-suggestion-picker-appearance-zoom200.html [ Crash Timeout ] fast/forms/color/color-suggestion-picker-appearance.html [ Crash Timeout ] -fast/forms/color/color-suggestion-picker-crash-on-set-value.html [ Crash ] fast/forms/color/color-suggestion-picker-one-row-appearance.html [ Crash Timeout ] fast/forms/color/color-suggestion-picker-two-row-appearance.html [ Crash Timeout ] fast/forms/color/color-suggestion-picker-with-scrollbar-appearance.html [ Crash Timeout ] @@ -763,13 +724,11 @@ fast/forms/file/file-input-direction.html [ Failure ] fast/forms/file/file-input-disabled.html [ Failure ] fast/forms/file/file-input-pressed-state.html [ Failure ] -fast/forms/file/file-input-reset.html [ Failure ] fast/forms/file/input-file-re-render.html [ Failure ] fast/forms/form-element-geometry.html [ Failure ] fast/forms/formmove3.html [ Failure ] fast/forms/huge-mac-input-clamped-height.html [ Failure ] fast/forms/huge-mac-input-clamped-width.html [ Failure ] -fast/forms/indeterminate.html [ Failure ] fast/forms/input-appearance-height.html [ Failure ] fast/forms/input-button-sizes.html [ Failure ] fast/forms/input-value.html [ Failure ] @@ -778,8 +737,6 @@ fast/forms/number/number-appearance-rtl.html [ Failure ] fast/forms/number/number-appearance-spinbutton-disabled-readonly.html [ Failure ] fast/forms/number/number-appearance-spinbutton-layer.html [ Failure ] -fast/forms/page-popup/page-popup-adjust-rect.html [ Crash ] -fast/forms/page-popup/page-popup-hide-window.html [ Crash ] fast/forms/placeholder-position.html [ Failure ] fast/forms/plaintext-mode-2.html [ Failure ] fast/forms/range/input-appearance-range.html [ Failure ] @@ -800,19 +757,6 @@ fast/forms/select-popup/popup-menu-appearance-zoom.html [ Crash ] fast/forms/select-popup/popup-menu-appearance-zoom090.html [ Crash ] fast/forms/select-popup/popup-menu-appearance.html [ Crash ] -fast/forms/select-popup/popup-menu-ax.html [ Crash ] -fast/forms/select-popup/popup-menu-crash-on-close.html [ Crash ] -fast/forms/select-popup/popup-menu-crash-on-select.html [ Crash ] -fast/forms/select-popup/popup-menu-mouse-operations.html [ Crash ] -fast/forms/select-popup/popup-menu-multiline-title.html [ Crash ] -fast/forms/select-popup/popup-menu-nested-style.html [ Crash ] -fast/forms/select-popup/popup-menu-non-latin-update-from-element.html [ Crash ] -fast/forms/select-popup/popup-menu-open-partially-visible.html [ Crash ] -fast/forms/select-popup/popup-menu-position.html [ Crash ] -fast/forms/select-popup/popup-menu-resize-after-open.html [ Crash ] -fast/forms/select-popup/popup-menu-size.html [ Crash ] -fast/forms/select-popup/popup-menu-touch-operations.html [ Crash ] -fast/forms/select-popup/popup-menu-update-from-element.html [ Crash ] fast/forms/select/003.html [ Failure ] fast/forms/select/004.html [ Failure ] fast/forms/select/basic-selects.html [ Failure ] @@ -832,13 +776,9 @@ fast/forms/select/menulist-deselect-update.html [ Crash Failure ] fast/forms/select/menulist-no-overflow.html [ Failure ] fast/forms/select/menulist-option-wrap.html [ Failure ] -fast/forms/select/menulist-popup-item-style.html [ Crash ] -fast/forms/select/menulist-popup-type-ahead-style-change.html [ Crash ] fast/forms/select/menulist-restrict-line-height.html [ Failure ] fast/forms/select/menulist-style-color.html [ Failure ] -fast/forms/select/menulist-update-text-popup.html [ Crash ] fast/forms/select/menulist-width-change.html [ Crash Failure ] -fast/forms/select/optgroup-clicking.html [ Crash ] fast/forms/select/optgroup-rendering.html [ Failure ] fast/forms/select/option-script.html [ Failure ] fast/forms/select/option-strip-whitespace.html [ Failure ] @@ -868,40 +808,20 @@ fast/forms/suggestion-picker/date-suggestion-picker-appearance-zoom125.html [ Crash Timeout ] fast/forms/suggestion-picker/date-suggestion-picker-appearance-zoom200.html [ Crash Timeout ] fast/forms/suggestion-picker/date-suggestion-picker-appearance.html [ Crash Timeout ] -fast/forms/suggestion-picker/date-suggestion-picker-key-operations.html [ Crash ] -fast/forms/suggestion-picker/date-suggestion-picker-min-max-attribute.html [ Crash ] -fast/forms/suggestion-picker/date-suggestion-picker-mouse-operations.html [ Crash ] -fast/forms/suggestion-picker/date-suggestion-picker-step-attribute.html [ Crash ] fast/forms/suggestion-picker/datetimelocal-suggestion-picker-appearance-locale-hebrew.html [ Crash Timeout ] fast/forms/suggestion-picker/datetimelocal-suggestion-picker-appearance-rtl.html [ Crash Timeout ] fast/forms/suggestion-picker/datetimelocal-suggestion-picker-appearance-with-scroll-bar.html [ Crash Timeout ] fast/forms/suggestion-picker/datetimelocal-suggestion-picker-appearance.html [ Crash Timeout ] -fast/forms/suggestion-picker/datetimelocal-suggestion-picker-key-operations.html [ Crash ] -fast/forms/suggestion-picker/datetimelocal-suggestion-picker-min-max-attribute.html [ Crash ] -fast/forms/suggestion-picker/datetimelocal-suggestion-picker-mouse-operations.html [ Crash ] -fast/forms/suggestion-picker/datetimelocal-suggestion-picker-step-attribute.html [ Crash ] fast/forms/suggestion-picker/month-suggestion-picker-appearance-rtl.html [ Crash Timeout ] fast/forms/suggestion-picker/month-suggestion-picker-appearance-with-scroll-bar.html [ Crash Timeout ] fast/forms/suggestion-picker/month-suggestion-picker-appearance.html [ Crash Timeout ] -fast/forms/suggestion-picker/month-suggestion-picker-key-operations.html [ Crash ] -fast/forms/suggestion-picker/month-suggestion-picker-min-max-attribute.html [ Crash ] -fast/forms/suggestion-picker/month-suggestion-picker-mouse-operations.html [ Crash ] -fast/forms/suggestion-picker/month-suggestion-picker-step-attribute.html [ Crash ] fast/forms/suggestion-picker/time-suggestion-picker-appearance-locale-hebrew.html [ Crash Timeout ] fast/forms/suggestion-picker/time-suggestion-picker-appearance-rtl.html [ Crash Timeout ] fast/forms/suggestion-picker/time-suggestion-picker-appearance-with-scroll-bar.html [ Crash Timeout ] fast/forms/suggestion-picker/time-suggestion-picker-appearance.html [ Crash Timeout ] -fast/forms/suggestion-picker/time-suggestion-picker-key-operations.html [ Crash ] -fast/forms/suggestion-picker/time-suggestion-picker-min-max-attribute.html [ Crash ] -fast/forms/suggestion-picker/time-suggestion-picker-mouse-operations.html [ Crash ] -fast/forms/suggestion-picker/time-suggestion-picker-step-attribute.html [ Crash ] fast/forms/suggestion-picker/week-suggestion-picker-appearance-rtl.html [ Crash Timeout ] fast/forms/suggestion-picker/week-suggestion-picker-appearance-with-scroll-bar.html [ Crash Timeout ] fast/forms/suggestion-picker/week-suggestion-picker-appearance.html [ Crash Timeout ] -fast/forms/suggestion-picker/week-suggestion-picker-key-operations.html [ Crash ] -fast/forms/suggestion-picker/week-suggestion-picker-min-max-attribute.html [ Crash ] -fast/forms/suggestion-picker/week-suggestion-picker-mouse-operations.html [ Crash ] -fast/forms/suggestion-picker/week-suggestion-picker-step-attribute.html [ Crash ] fast/forms/tabbing-input-iframe.html [ Failure ] fast/forms/targeted-frame-submission.html [ Failure ] fast/forms/text/input-appearance-bkcolor.html [ Failure ] @@ -928,7 +848,6 @@ fast/forms/text/placeholder-pseudo-style.html [ Failure ] fast/forms/text/text-appearance-basic.html [ Failure ] fast/forms/text/text-appearance-datalist.html [ Failure ] -fast/forms/text/text-font-height-mismatch.html [ Failure ] fast/forms/text/textfield-focus-ring.html [ Failure ] fast/forms/text/textfield-outline.html [ Failure ] fast/forms/text/textfield-overflow.html [ Failure ] @@ -948,7 +867,6 @@ fast/forms/textarea/textAreaLineHeight.html [ Failure ] fast/forms/time/time-appearance-basic.html [ Failure ] fast/forms/week/week-appearance-basic.html [ Failure ] -fast/frames/expand-grid-with-zero-size-child-frameset-crash.html [ Crash ] fast/frames/frame-navigation.html [ Failure ] fast/frames/frame-set-rotation-hit.html [ Crash Timeout ] fast/frames/frame-set-scaling-centered.html [ Failure ] @@ -956,20 +874,12 @@ fast/frames/frame-set-scaling-rotate.html [ Failure ] fast/frames/frame-set-scaling-skew.html [ Failure ] fast/frames/frame-set-scaling.html [ Failure ] -fast/frames/frame-set-too-many-frames.html [ Crash ] -fast/frames/frameset-frameborder-boolean-values.html [ Crash ] -fast/frames/frameset-frameborder-inheritance.html [ Crash ] -fast/frames/frameset-frameborder-overrides-border.html [ Crash ] fast/frames/frameset-style-recalc.html [ Failure ] -fast/frames/iframe-reparenting-unique-name.html [ Crash ] fast/frames/iframe-scaling-with-scroll.html [ Failure ] fast/frames/iframe-scrolling-attribute.html [ Failure ] fast/frames/transparent-scrollbar.html [ Failure ] fast/gradients/background-clipped.html [ Failure ] fast/gradients/css3-color-stop-units.html [ Failure ] -fast/hidpi/clip-text-in-hidpi.html [ Failure ] -fast/hidpi/image-set-without-specified-width.html [ Failure ] -fast/hidpi/resize-corner-hidpi.html [ Failure ] fast/html/details-add-summary-1-and-click.html [ Failure ] fast/html/details-add-summary-10-and-click.html [ Failure ] fast/html/details-add-summary-2-and-click.html [ Failure ] @@ -980,7 +890,6 @@ fast/html/details-add-summary-7-and-click.html [ Failure ] fast/html/details-add-summary-8-and-click.html [ Failure ] fast/html/details-add-summary-9-and-click.html [ Failure ] -fast/html/details-add-summary-9.html [ Failure ] fast/html/details-position.html [ Failure ] fast/html/details-remove-summary-1-and-click.html [ Failure ] fast/html/details-remove-summary-2-and-click.html [ Failure ] @@ -1002,40 +911,26 @@ fast/images/color-profile-border-fade.html [ Failure ] fast/images/color-profile-border-radius.html [ Failure ] fast/images/color-profile-filter.html [ Failure ] -fast/images/color-profile-group.html [ Failure ] -fast/images/color-profile-image-canvas-svg.html [ Crash ] fast/images/color-profile-image-filter-all.html [ Failure ] -fast/images/color-profile-image-object-fit.html [ Failure ] fast/images/color-profile-image-pseudo-content.html [ Failure ] fast/images/color-profile-image-shape.html [ Failure ] fast/images/color-profile-layer-filter.html [ Failure ] fast/images/color-profile-layer.html [ Failure ] fast/images/color-profile-mask-image-svg.html [ Failure ] -fast/images/color-profile-munsell-adobe-to-srgb.html [ Crash Failure ] -fast/images/color-profile-munsell-srgb-to-srgb.html [ Crash Failure ] fast/images/color-profile-reflection.html [ Crash Failure ] fast/images/color-profile-svg-fill-text.html [ Failure ] fast/images/color-profile-svg-foreign-object.html [ Failure ] fast/images/content-url-image-with-alt-text-dynamic-2.html [ Pass Failure ] -fast/images/content-url-image-with-alt-text-dynamic.html [ Failure ] -fast/images/content-url-image-with-alt-text.html [ Crash Failure ] -fast/images/embed-image.html [ Failure ] -fast/images/exif-orientation-css.html [ Failure ] fast/images/fixed-img-src-change-after-scroll.html [ Failure ] fast/images/imagemap-case.html [ Failure ] -fast/images/imagemap-overflowing-circle-focus-ring.html [ Failure ] fast/images/mask-box-image-crash.html [ Failure ] fast/images/pixel-crack-image-background-webkit-transform-scale.html [ Failure ] fast/images/sprite-no-bleed.html [ Failure ] fast/inline/inline-borders-with-bidi-override.html [ Failure ] fast/inline/inline-continuation-borders.html [ Failure ] fast/invalid/014.html [ Failure ] -fast/layers/add-layer-with-nested-stacking.html [ Failure ] -fast/layers/nested-layers-2.html [ Crash ] -fast/layers/nested-layers-4.html [ Crash ] fast/layers/normal-flow-hit-test.html [ Crash Failure ] fast/layers/opacity-outline.html [ Failure ] -fast/layers/opacity-stacking.html [ Failure ] fast/layers/opacity-transforms.html [ Failure ] fast/layers/overflow-hidden-clip-path-occlusion.html [ Failure ] fast/layers/overflow-hidden-rounded-corners-occlusion.html [ Failure ] @@ -1044,12 +939,9 @@ fast/layers/scroll-rect-to-visible.html [ Failure ] fast/layers/scroll-with-transform-layer.html [ Failure ] fast/lists/008.html [ Failure ] -fast/lists/ol-display-types.html [ Failure ] fast/lists/ol-start-parsing.html [ Failure ] fast/lists/olstart.html [ Failure ] fast/masking/clip-path-inset-large-radii.html [ Failure ] -fast/media/mq-js-stylesheet-media-03.html [ Failure ] -fast/mediacapturefromelement/CanvasCaptureMediaStream-exceptions.html [ Crash ] fast/multicol/abspos-after-break-after.html [ Failure ] fast/multicol/abspos-in-overflow-hidden-in-2nd-column.html [ Failure ] fast/multicol/balance-breakafter-before-nested-block.html [ Failure ] @@ -1090,7 +982,6 @@ fast/multicol/dynamic/insert-spanner-after-spanner-before-content.html [ Failure ] fast/multicol/dynamic/insert-spanner-before-content.html [ Failure ] fast/multicol/dynamic/insert-spanner-into-content.html [ Failure ] -fast/multicol/dynamic/insert-spanner-pseudo-after.html [ Failure ] fast/multicol/dynamic/remove-abspos-next-to-spanner.html [ Failure ] fast/multicol/dynamic/remove-and-insert-block-after-spanner.html [ Failure ] fast/multicol/dynamic/remove-and-insert-block-before-spanner.html [ Failure ] @@ -1120,7 +1011,6 @@ fast/multicol/float-paginate-empty-lines.html [ Failure ] fast/multicol/float-paginate.html [ Failure ] fast/multicol/foreignObject.html [ Failure ] -fast/multicol/hit-test-float.html [ Failure ] fast/multicol/inline-block-baseline.html [ Failure ] fast/multicol/inner-multicol-in-second-column.html [ Failure ] fast/multicol/layers-in-multicol.html [ Failure ] @@ -1164,7 +1054,6 @@ fast/multicol/overflow-across-columns.html [ Failure ] fast/multicol/overflow-into-columngap.html [ Failure ] fast/multicol/overflow-unsplittable.html [ Failure ] -fast/multicol/paged-becomes-multicol-fixed-height.html [ Failure ] fast/multicol/paginate-block-replaced.html [ Failure ] fast/multicol/percent-height.html [ Failure ] fast/multicol/positioned-outside-of-columns.html [ Failure ] @@ -1248,7 +1137,6 @@ fast/overflow/003.xml [ Failure ] fast/overflow/006.html [ Failure ] fast/overflow/007.html [ Failure ] -fast/overflow/add-visual-overflow-and-change-container-position.html [ Failure ] fast/overflow/border-radius-clipping.html [ Failure ] fast/overflow/childFocusRingClip.html [ Failure ] fast/overflow/clip-rects-fixed-ancestor.html [ Failure ] @@ -1256,7 +1144,6 @@ fast/overflow/float-in-relpositioned.html [ Failure ] fast/overflow/hit-test-overflow-controls.html [ Failure ] fast/overflow/image-selection-highlight.html [ Failure ] -fast/overflow/line-clamp.html [ Failure ] fast/overflow/overflow-float-stacking.html [ Crash Failure ] fast/overflow/overflow-focus-ring.html [ Failure ] fast/overflow/overflow-rtl-vertical.html [ Failure ] @@ -1285,112 +1172,62 @@ fast/reflections/transparent-reflected-sublayers.html [ Crash Failure ] fast/repaint/4776765.html [ Failure ] fast/repaint/absolute-position-change-containing-block.html [ Failure ] -fast/repaint/abspos-shift-image-incorrect-repaint.html [ Crash Failure ] -fast/repaint/add-table-overpaint.html [ Failure ] -fast/repaint/align-content-change-keeping-geometry.html [ Failure ] -fast/repaint/align-content-change.html [ Failure ] -fast/repaint/align-content-distribution-change-grid.html [ Failure ] -fast/repaint/align-content-position-change-grid.html [ Failure ] -fast/repaint/align-self-change-grid.html [ Failure ] -fast/repaint/align-self-change-no-flex.html [ Failure ] fast/repaint/align-self-change.html [ Failure ] fast/repaint/align-self-overflow-change.html [ Failure ] -fast/repaint/background-generated.html [ Failure ] fast/repaint/background-image-paint-invalidation-large-abspos-div.html [ Failure ] fast/repaint/background-resize-height.html [ Failure ] fast/repaint/background-resize-width.html [ Failure ] fast/repaint/background-scaling.html [ Crash Timeout ] fast/repaint/backgroundSizeRepaint.html [ Failure ] -fast/repaint/block-no-inflow-children.html [ Failure ] -fast/repaint/block-shift-repaint.html [ Failure ] fast/repaint/border-box-sizing-invalidation.html [ Crash ] -fast/repaint/border-image-outset-change-repaint.html [ Failure ] fast/repaint/border-radius-repaint-2.html [ Failure ] fast/repaint/border-radius-repaint.html [ Failure ] fast/repaint/border-radius-without-border.html [ Failure ] fast/repaint/border-repaint-glitch.html [ Failure ] -fast/repaint/box-inline-resize.html [ Crash Failure ] -fast/repaint/box-shadow-dynamic.html [ Failure ] -fast/repaint/box-shadow-inset-repaint.html [ Failure ] fast/repaint/box-sizing.html [ Failure ] -fast/repaint/bugzilla-5699.html [ Failure ] fast/repaint/bugzilla-6278.html [ Failure ] -fast/repaint/bugzilla-6388.html [ Crash Failure ] -fast/repaint/bugzilla-6473.html [ Failure ] fast/repaint/canvas-resize-no-full-invalidation.html [ Failure ] fast/repaint/canvas-resize.html [ Failure ] fast/repaint/caret-invalidation-in-overflow-scroll.html [ Failure ] fast/repaint/caret-with-transformation.html [ Failure ] -fast/repaint/change-transform.html [ Failure ] fast/repaint/child-of-sub-pixel-offset-composited-layer.html [ Failure ] fast/repaint/clip-path-constant-repaint.html [ Failure ] fast/repaint/clip-unclip-and-change.html [ Failure ] -fast/repaint/clip-with-layout-delta.html [ Failure ] fast/repaint/clipped-overflow-visible-subtree.html [ Crash Failure ] -fast/repaint/clipped-relative.html [ Failure ] fast/repaint/composited-iframe-scroll-repaint.html [ Failure ] fast/repaint/containing-block-position-change.html [ Failure ] fast/repaint/content-into-overflow.html [ Failure ] -fast/repaint/continuation-after-outline.html [ Failure ] -fast/repaint/crbug-371640-2.html [ Crash Failure ] -fast/repaint/crbug-371640-3.html [ Crash Failure ] -fast/repaint/crbug-371640-4.html [ Crash Failure ] -fast/repaint/crbug-371640.html [ Crash Failure ] fast/repaint/delete-into-nested-block.html [ Failure ] fast/repaint/destroy-composited-scrollbar.html [ Failure ] -fast/repaint/destroy-overlay-scrollbar.html [ Failure ] -fast/repaint/destroy-scrollbar.html [ Failure ] -fast/repaint/details-open-repaint.html [ Failure ] fast/repaint/dont-invalidate-root-layer-when-composited-layer-becomes-visible.html [ Failure ] -fast/repaint/dynamic-table-vertical-alignment-change.html [ Failure ] -fast/repaint/erase-overflow.html [ Failure ] fast/repaint/filter-invalidation-with-composited-container-change.html [ Failure ] fast/repaint/filter-repaint-accelerated-child-with-filter-child.html [ Failure ] fast/repaint/filter-repaint-accelerated-on-accelerated-filter.html [ Failure ] fast/repaint/filter-repaint-on-accelerated-layer.html [ Failure ] -fast/repaint/fixed-after-scroll.html [ Failure ] fast/repaint/fixed-and-absolute-position-scrolled.html [ Failure ] fast/repaint/fixed-child-move-after-scroll.html [ Failure ] fast/repaint/fixed-child-of-fixed-move-after-scroll.html [ Failure ] fast/repaint/fixed-child-of-transformed-move-after-scroll.html [ Failure ] -fast/repaint/fixed-child-of-transformed-scrolled.html [ Failure ] -fast/repaint/fixed-descendant-of-transformed-scrolled.html [ Failure ] fast/repaint/fixed-element-repaint-after-compositing-update.html [ Failure ] fast/repaint/fixed-in-page-scale.html [ Crash Timeout ] fast/repaint/fixed-move-after-scroll.html [ Failure ] fast/repaint/fixed-right-bottom-in-page-scale.html [ Crash Timeout ] fast/repaint/fixed-right-in-page-scale.html [ Crash Timeout ] -fast/repaint/fixed-to-relative-position-with-absolute-child.html [ Failure ] fast/repaint/fixed-tranformed.html [ Failure ] fast/repaint/fixed-under-composited-absolute-scrolled.html [ Failure ] fast/repaint/fixed-under-composited-fixed-scrolled.html [ Failure ] fast/repaint/fixed.html [ Failure ] -fast/repaint/float-overflow-right.html [ Crash Failure ] -fast/repaint/float-overflow.html [ Crash Failure ] fast/repaint/focus-ring.html [ Failure ] fast/repaint/full-viewport-repaint-for-background-attachment-fixed.html [ Failure ] fast/repaint/hover-invalidation-table.html [ Failure ] fast/repaint/image-resize.html [ Failure ] -fast/repaint/in-scaled-iframe.html [ Failure ] fast/repaint/inline-focus.html [ Failure ] fast/repaint/inline-outline-repaint.html [ Failure ] fast/repaint/inline-style-change-in-scrolled-view.html [ Failure ] -fast/repaint/inline-vertical-lr-overflow.html [ Failure ] -fast/repaint/inline-vertical-rl-overflow.html [ Failure ] -fast/repaint/intermediate-layout-position-clip.html [ Failure ] fast/repaint/intermediate-layout-position.html [ Failure ] -fast/repaint/invalidate-paint-for-fixed-pos-inside-iframe.html [ Failure ] fast/repaint/invalidate-paint-in-iframe-in-composited-layer.html [ Failure ] fast/repaint/invalidation-after-opacity-change-subtree.html [ Failure ] -fast/repaint/invalidation-with-zero-size-object.html [ Failure ] -fast/repaint/justify-content-change.html [ Failure ] fast/repaint/justify-content-distribution-change-grid.html [ Failure ] -fast/repaint/justify-content-position-change-grid.html [ Failure ] -fast/repaint/justify-content-position-change.html [ Failure ] -fast/repaint/justify-self-change.html [ Failure ] -fast/repaint/justify-self-overflow-change.html [ Failure ] -fast/repaint/layout-state-scrolloffset3.html [ Failure ] -fast/repaint/layoutstate-invalid-invalidation-inline-relative-positioned.html [ Crash Failure ] fast/repaint/line-flow-with-floats-1.html [ Failure ] fast/repaint/line-flow-with-floats-10.html [ Failure ] fast/repaint/line-flow-with-floats-2.html [ Failure ] @@ -1401,27 +1238,15 @@ fast/repaint/line-flow-with-floats-7.html [ Failure ] fast/repaint/line-flow-with-floats-8.html [ Failure ] fast/repaint/line-flow-with-floats-9.html [ Failure ] -fast/repaint/line-in-scrolled-clipped-block.html [ Failure ] -fast/repaint/list-marker-2.html [ Failure ] -fast/repaint/margin.html [ Failure ] -fast/repaint/mix-blend-mode-separate-stacking-context.html [ Failure ] fast/repaint/multicol-as-paint-container.html [ Failure ] fast/repaint/multicol-nested.html [ Failure ] fast/repaint/multicol-repaint.html [ Failure ] -fast/repaint/multicol-with-abspos-in-relpos.html [ Failure ] -fast/repaint/multicol-with-block.html [ Failure ] -fast/repaint/multicol-with-inline.html [ Failure ] -fast/repaint/multicol-with-overflowing-block-rl.html [ Failure ] -fast/repaint/multicol-with-relpos.html [ Failure ] -fast/repaint/multicol-with-text.html [ Failure ] fast/repaint/multiple-backgrounds-style-change.html [ Failure ] fast/repaint/nested-fixed-iframe-scrolled.html [ Failure ] fast/repaint/offset-change-wrong-invalidation-with-float.html [ Crash Failure ] fast/repaint/opacity-change-on-overflow-float.html [ Failure ] -fast/repaint/outline-child-repaint.html [ Crash Failure ] fast/repaint/outline-inset.html [ Failure ] fast/repaint/outline-repaint-glitch.html [ Failure ] -fast/repaint/overflow-auto-in-overflow-auto-scrolled.html [ Failure ] fast/repaint/overflow-changed-on-child-of-composited-layer.html [ Failure ] fast/repaint/overflow-into-content.html [ Failure ] fast/repaint/overflow-move-after-scroll.html [ Failure ] @@ -1429,41 +1254,28 @@ fast/repaint/overflow-scroll-body-appear.html [ Failure ] fast/repaint/overflow-scroll-composited-non-stacking-child.html [ Failure ] fast/repaint/overflow-scroll-delete.html [ Failure ] -fast/repaint/overflow-scroll-in-overflow-scroll-scrolled.html [ Failure ] fast/repaint/padding-keeping-content-size.html [ Failure ] fast/repaint/paged-with-overflowing-block-rl.html [ Failure ] fast/repaint/paint-invalidation-with-reparent-across-frame-boundaries.html [ Failure ] fast/repaint/percent-size-image-resize-container.html [ Failure ] -fast/repaint/position-change-keeping-geometry.html [ Failure ] -fast/repaint/positioned-document-element.html [ Failure ] -fast/repaint/positioned-great-grandparent-change-location.html [ Crash Failure ] -fast/repaint/positioned-list-offset-change-repaint.html [ Failure ] -fast/repaint/push-block-with-first-line.html [ Crash Failure ] fast/repaint/reflection-invalidation-positioned-child.html [ Crash Failure ] fast/repaint/reflection-repaint-test.html [ Crash Failure ] fast/repaint/relative-inline-positioned-movement-repaint.html [ Failure ] -fast/repaint/relative-margin-change-repaint.html [ Failure ] fast/repaint/relative-positioned-movement-repaint.html [ Crash Failure ] fast/repaint/relayout-fixed-position-after-scale.html [ Crash Timeout ] -fast/repaint/remove-inline-after-layout.html [ Failure ] -fast/repaint/remove-inline-block-descendant-of-flex.html [ Failure ] fast/repaint/renderer-destruction-by-invalidateSelection-crash.html [ Failure ] fast/repaint/repaint-composited-child-in-scrolled-container.html [ Failure ] fast/repaint/repaint-descandant-on-ancestor-layer-move.html [ Crash Failure ] fast/repaint/repaint-during-scroll-with-zoom.html [ Failure ] fast/repaint/repaint-during-scroll.html [ Failure ] fast/repaint/repaint-resized-overflow.html [ Failure ] -fast/repaint/repaint-table-row-in-composited-document.html [ Failure ] -fast/repaint/replaced-clipped-positioned-not-wrong-incremental-repainting.html [ Crash Failure ] fast/repaint/resize-child-within-overflow.html [ Failure ] +fast/repaint/resize-iframe-text.html [ Failure ] fast/repaint/resize-scrollable-div.html [ Failure ] -fast/repaint/resize-scrollable-iframe.html [ Failure ] -fast/repaint/resize-skewed.html [ Failure ] fast/repaint/resize-with-border-clipped.html [ Failure ] fast/repaint/resize-with-border.html [ Failure ] fast/repaint/scale-page-shrink.html [ Crash Timeout ] fast/repaint/scroll-absolute-layer-with-reflection.html [ Crash Failure ] -fast/repaint/scroll-fixed-layer-with-no-visible-content.html [ Failure ] fast/repaint/scroll-fixed-layer-with-reflection.html [ Crash Failure ] fast/repaint/scroll-fixed-layer-with-transformed-parent-layer.html [ Failure ] fast/repaint/scroll-fixed-reflected-layer.html [ Crash Failure ] @@ -1471,75 +1283,42 @@ fast/repaint/scroll-stacking-context-backface-visiblity-leaves-traces.html [ Failure ] fast/repaint/scroll-with-transformed-parent-layer.html [ Failure ] fast/repaint/scrollbar-damage-and-full-viewport-repaint.html [ Failure ] -fast/repaint/scrollbar-invalidation-on-resize-with-border.html [ Failure ] fast/repaint/scrolled-iframe-scrollbar-change.html [ Failure ] fast/repaint/selection-after-delete.html [ Failure ] -fast/repaint/selection-clear-after-move.html [ Crash Failure ] -fast/repaint/selection-clear.html [ Failure ] -fast/repaint/set-text-content-same.html [ Failure ] fast/repaint/shift-relative-positioned-container-with-image-addition.html [ Crash Failure ] -fast/repaint/shift-relative-positioned-container-with-image-removal.html [ Crash Failure ] -fast/repaint/stacked-diacritics.html [ Failure ] fast/repaint/stacking-context-lost.html [ Failure ] fast/repaint/subtree-layoutstate-transform.html [ Failure ] fast/repaint/subtree-root-skipped.html [ Failure ] -fast/repaint/table-cell-move.html [ Crash Failure ] -fast/repaint/table-col-background-offset.html [ Crash Failure ] -fast/repaint/table-col-background.html [ Crash Failure ] fast/repaint/table-collapsed-border.html [ Failure ] -fast/repaint/table-overflow-auto-in-overflow-auto-scrolled.html [ Failure ] fast/repaint/table-overflow-scroll-in-overflow-scroll-scrolled.html [ Failure ] -fast/repaint/table-row-bg-change.html [ Crash Failure ] -fast/repaint/table-row.html [ Failure ] -fast/repaint/table-section-overflow.html [ Crash Failure ] fast/repaint/table-section-repaint.html [ Crash Failure ] fast/repaint/table-shrink-row-repaint.html [ Crash Failure ] fast/repaint/table-two-pass-layout-overpaint.html [ Failure ] -fast/repaint/table-with-padding-row-invalidation.html [ Crash Failure ] -fast/repaint/text-in-relative-positioned-inline.html [ Failure ] fast/repaint/text-match-document-change.html [ Failure ] fast/repaint/text-selection-rect-in-overflow-2.html [ Failure ] -fast/repaint/text-selection-rect-in-overflow.html [ Failure ] -fast/repaint/text-shadow.html [ Failure ] fast/repaint/transform-disable-layoutstate.html [ Failure ] -fast/repaint/transform-inline-layered-child.html [ Failure ] -fast/repaint/transform-layout-repaint.html [ Failure ] fast/repaint/transform-replaced-shadows.html [ Failure ] -fast/repaint/transform-rotate-and-remove.html [ Failure ] -fast/repaint/vertical-align-length1.html [ Failure ] fast/repaint/vertical-align1.html [ Failure ] -fast/repaint/vertical-align2.html [ Failure ] fast/repaint/vertical-overflow-parent.html [ Failure ] fast/repaint/vertical-overflow-same.html [ Failure ] fast/repaint/vertical-rl-as-paint-container.html [ Failure ] fast/repaint/video-mute-repaint.html [ Crash Failure ] fast/repaint/video-unmute-repaint.html [ Crash Failure ] -fast/repaint/window-resize-background-image-fixed-centered-composited.html [ Failure ] -fast/repaint/window-resize-background-image-fixed-centered.html [ Failure ] -fast/repaint/window-resize-centered-inline-under-fixed-pos.html [ Failure ] -fast/repaint/window-resize-no-layout-change1.html [ Failure ] -fast/repaint/window-resize-no-layout-change2.html [ Failure ] fast/repaint/window-resize-percent-html.html [ Failure ] fast/repaint/window-resize-percent-width-height.html [ Failure ] -fast/repaint/window-resize-positioned-bottom.html [ Failure ] -fast/repaint/window-resize-positioned-percent-top.html [ Failure ] fast/repaint/window-resize-vertical-writing-mode.html [ Failure ] fast/repaint/window-resize-viewport-percent.html [ Failure ] -fast/replaced/007.html [ Failure ] fast/replaced/border-radius-clip-content-edge.html [ Failure ] fast/replaced/border-radius-clip.html [ Failure ] fast/replaced/outline-replaced-elements.html [ Failure ] -fast/replaced/percent-height-in-anonymous-block-widget.html [ Failure ] fast/replaced/replaced-breaking-mixture.html [ Failure ] fast/replaced/replaced-breaking.html [ Failure ] fast/replaced/selection-rect-transform.html [ Failure ] fast/replaced/width100percent-button.html [ Failure ] fast/replaced/width100percent-textarea.html [ Failure ] -fast/ruby/rubyDOM-remove-text2.html [ Failure ] fast/scrolling/background-paint-scrolled.html [ Failure ] fast/scrolling/overflow-clip-with-page-scale.html [ Crash Timeout ] fast/scrolling/scrollbar-tickmarks-styled.html [ Failure ] -fast/selectors/054.html [ Failure ] fast/selectors/166.html [ Failure ] fast/selectors/input-with-selection-pseudo-element.html [ Failure ] fast/shapes/shape-outside-floats/shape-outside-boxes-001.html [ Failure ] @@ -1547,12 +1326,6 @@ fast/shapes/shape-outside-floats/shape-outside-boxes-003.html [ Failure ] fast/shapes/shape-outside-floats/shape-outside-dynamic-shape-margin.html [ Failure ] fast/shapes/shape-outside-floats/shape-outside-dynamic-shape-overhang.html [ Failure ] -fast/shapes/shape-outside-floats/shape-outside-floats-image-threshold-002.html [ Crash ] -fast/shapes/shape-outside-floats/shape-outside-floats-margin-crash.html [ Crash ] -fast/shapes/shape-outside-floats/shape-outside-image-fit-001.html [ Crash ] -fast/shapes/shape-outside-floats/shape-outside-image-set.html [ Crash ] -fast/shapes/shape-outside-floats/shape-outside-relative-size-svg.html [ Crash ] -fast/spatial-navigation/snav-hidden-iframe-zero-size.html [ Crash ] fast/spatial-navigation/snav-multiple-select-focusring.html [ Failure ] fast/sub-pixel/clip-rect-box-consistent-rounding.html [ Failure ] fast/sub-pixel/column-clipping.html [ Failure ] @@ -1560,7 +1333,6 @@ fast/sub-pixel/repaint-subpixel-layer-in-subpixel-composited-layer.html [ Failure ] fast/sub-pixel/should-not-repaint-subpixel-composited-layer.html [ Failure ] fast/sub-pixel/sub-pixel-composited-layer-with-transform.html [ Failure ] -fast/sub-pixel/sub-pixel-iframe-copy-on-scroll.html [ Failure ] fast/sub-pixel/transformed-iframe-copy-on-scroll.html [ Failure ] fast/table/007.html [ Failure ] fast/table/023.html [ Failure ] @@ -1568,43 +1340,39 @@ fast/table/040-vertical.html [ Failure ] fast/table/040.html [ Failure ] fast/table/border-collapsing/004.html [ Failure ] -fast/table/border-collapsing/border-collapse-change-collapse-to-separate.html [ Failure ] -fast/table/border-collapsing/border-collapse-change-separate-to-collapse.html [ Failure ] fast/table/border-collapsing/cached-change-cell-border-width.html [ Failure ] fast/table/border-collapsing/cached-change-col-border-width.html [ Failure ] fast/table/border-collapsing/cached-change-colgroup-border-width.html [ Failure ] fast/table/border-collapsing/cached-change-row-border-width.html [ Failure ] fast/table/border-collapsing/cached-change-tbody-border-width.html [ Failure ] -fast/table/change-tbody-border-width-crash.html [ Crash ] fast/table/dynamic-caption-add-before-child.xhtml [ Failure ] fast/table/edge-offsets.html [ Failure ] fast/table/empty-cells.html [ Failure ] fast/table/form-with-table-style.html [ Failure ] fast/table/frame-and-rules.html [ Failure ] fast/table/height-percent-test.html [ Failure ] -fast/table/insert-cell-before-form.html [ Failure ] fast/table/multiple-captions-display.xhtml [ Failure ] fast/table/overflowHidden.html [ Failure ] fast/table/prepend-in-anonymous-table.html [ Failure ] fast/table/resize-table-repaint-percent-size-cell.html [ Failure ] -fast/table/resize-table-repaint-vertical-align-cell.html [ Failure ] -fast/table/resize-table-row-repaint.html [ Failure ] -fast/table/split-table-section-before-anonymous-block-2.html [ Failure ] fast/table/table-display-types-vertical.html [ Failure ] -fast/table/table-with-border-radius.html [ Failure ] fast/table/text-field-baseline.html [ Failure ] fast/text-autosizing/hackernews-comments.html [ Failure ] -fast/text-autosizing/print-autosizing.html [ Crash Timeout ] fast/text/capitalize-boundaries.html [ Failure ] fast/text/caps-lock-indicator-disabled.html [ Failure ] fast/text/caps-lock-indicator-enabled-rtl.html [ Failure ] fast/text/caps-lock-indicator-enabled.html [ Failure ] fast/text/color-emoji.html [ Failure ] -fast/text/complex-text-opacity.html [ Failure ] fast/text/decorations-transformed.html [ Failure ] fast/text/descent-clip-in-scaled-page.html [ Crash Timeout ] fast/text/drawBidiText.html [ Failure ] +fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition.html [ Failure ] +fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition.html [ Failure ] +fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition.html [ Failure ] +fast/text/ellipsis-rtl-text-in-ltr-flow-underline.html [ Failure ] fast/text/ellipsis-rtl-text-in-ltr-flow.html [ Failure ] +fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition.html [ Failure ] +fast/text/ellipsis-rtl-text-in-rtl-flow-underline.html [ Failure ] fast/text/ellipsis-rtl-text-in-rtl-flow.html [ Failure ] fast/text/ellipsis-stroked.html [ Failure ] fast/text/emoticons.html [ Failure ] @@ -1622,7 +1390,7 @@ fast/text/letter-spacing-negative-opacity.html [ Failure ] fast/text/selection-hard-linebreak.html [ Failure ] fast/text/softHyphen.html [ Failure ] -fast/text/sub-pixel/text-scaling-rtl.html [ Failure ] +fast/text/text-letter-spacing.html [ Failure ] fast/text/textIteratorNilRenderer.html [ Failure ] fast/text/unicode-fallback-font.html [ Failure ] fast/text/whitespace/024.html [ Failure ] @@ -1653,30 +1421,13 @@ svg/animations/animateMotion-accumulate-2a.svg [ Failure ] svg/animations/animateMotion-accumulate-2b.svg [ Failure ] svg/animations/filter-primitive-region.html [ Failure ] -svg/as-background-image/animated-svg-as-background.html [ Crash ] -svg/as-background-image/svg-background-partial-redraw.html [ Crash ] svg/as-background-image/svg-transformed-background.html [ Failure ] svg/as-background-image/tiled-background-image.html [ Crash Timeout ] -svg/as-image/animated-svg-as-image-visited-link.html [ Crash ] -svg/as-image/image-change-with-equal-sizes.html [ Crash ] svg/as-image/image-preserveAspectRatio-all.svg [ Failure ] svg/as-image/image-respects-pageScaleFactor.html [ Crash Timeout ] svg/as-image/img-preserveAspectRatio-support-1.html [ Failure ] svg/as-image/img-preserveAspectRatio-support-2.html [ Crash Failure ] -svg/as-image/svg-as-image-canvas.html [ Crash ] -svg/as-image/svg-as-image-intrinsic-size.html [ Crash ] -svg/as-image/svg-canvas-link-not-colored.html [ Crash ] -svg/as-image/svg-canvas-not-tainted.html [ Crash ] -svg/as-image/svg-canvas-svg-with-image-with-link-tainted.html [ Crash ] -svg/as-image/svg-canvas-xhtml-tainted.html [ Crash ] -svg/as-image/svg-image-change-content-size.xhtml [ Crash ] -svg/as-image/svg-image-leak-cached-data.html [ Crash ] -svg/as-image/svg-image-leak-loader.html [ Crash ] -svg/as-image/svg-image-with-css-animation.html [ Crash Failure ] -svg/as-image/svg-image-with-nested-data-uri.html [ Crash ] -svg/as-image/svgview-references-use-counters.html [ Crash ] svg/as-image/svgview-references.html [ Failure ] -svg/as-list-image/svg-list-image-intrinsic-size-zoom.html [ Crash ] svg/as-object/deep-nested-embedded-svg-size-changes-no-layout-triggers-1.html [ Failure ] svg/as-object/deep-nested-embedded-svg-size-changes-no-layout-triggers-2.html [ Failure ] svg/as-object/embedded-svg-immediate-offsetWidth-query.html [ Crash Failure ] @@ -1720,14 +1471,6 @@ svg/batik/text/textStyles.svg [ Failure ] svg/batik/text/verticalText.svg [ Failure ] svg/batik/text/verticalTextOnPath.svg [ Failure ] -svg/canvas/canvas-default-object-sizing.html [ Crash ] -svg/canvas/canvas-draw-image-globalalpha.html [ Crash ] -svg/canvas/canvas-draw-image-size.html [ Crash ] -svg/canvas/canvas-draw-image-svg-fragment.html [ Crash ] -svg/canvas/canvas-draw-pattern-size.html [ Crash ] -svg/canvas/canvas-draw-pattern-svg-fragment.html [ Crash Timeout ] -svg/canvas/canvas-pattern-svg.html [ Crash ] -svg/canvas/image-svg-intrinsic-size.html [ Crash ] svg/carto.net/button.svg [ Failure ] svg/carto.net/colourpicker.svg [ Failure ] svg/carto.net/combobox.svg [ Failure ] @@ -1780,7 +1523,6 @@ svg/clip-path/deep-nested-clip-in-mask-different-unitTypes.svg [ Failure ] svg/clip-path/deep-nested-clip-in-mask-panning.svg [ Failure ] svg/clip-path/deep-nested-clip-in-mask.svg [ Failure ] -svg/clip-path/multiple-nested-clip-paths-crash.html [ Failure ] svg/clip-path/nested-clip-in-mask-image-based-clipping.svg [ Failure ] svg/clip-path/nested-clip-in-mask-path-and-image-based-clipping.svg [ Failure ] svg/clip-path/nested-clip-in-mask-path-based-clipping.svg [ Failure ] @@ -1788,7 +1530,6 @@ svg/clip-path/transformed-clip.svg [ Failure ] svg/css/path-gradient-stroke-shadow.svg [ Failure ] svg/css/rect-gradient-stroke-shadow.svg [ Failure ] -svg/css/svg-resource-fragment-identifier-img-src.html [ Crash Timeout ] svg/css/text-shadow-multiple.xhtml [ Failure ] svg/custom/absolute-root-position-masking.xhtml [ Failure ] svg/custom/absolute-sized-content-with-resources.xhtml [ Failure ] @@ -1796,7 +1537,6 @@ svg/custom/animate-path-discrete.svg [ Failure ] svg/custom/bug45331.svg [ Failure ] svg/custom/circle-move-invalidation.svg [ Failure ] -svg/custom/circular-clip-path-references-crash.svg [ Failure ] svg/custom/circular-marker-reference-1.svg [ Failure ] svg/custom/circular-marker-reference-2.svg [ Failure ] svg/custom/circular-marker-reference-3.svg [ Failure ] @@ -1861,7 +1601,6 @@ svg/custom/js-late-mask-creation.svg [ Failure ] svg/custom/js-late-pattern-and-object-creation.svg [ Failure ] svg/custom/js-late-pattern-creation.svg [ Failure ] -svg/custom/js-update-bounce.svg [ Failure ] svg/custom/js-update-container.svg [ Failure ] svg/custom/junk-data.svg [ Failure ] svg/custom/lazy-attach-use.html [ Failure ] @@ -1873,14 +1612,11 @@ svg/custom/load-non-wellformed.svg [ Failure ] svg/custom/local-url-references.html [ Failure ] svg/custom/marker-default-width-height.svg [ Failure ] -svg/custom/marker-opacity.svg [ Failure ] svg/custom/marker-orient-auto.html [ Failure ] svg/custom/marker-referencePoint.svg [ Failure ] -svg/custom/marker-zero-length-linecaps.svg [ Failure ] svg/custom/mask-changes.svg [ Failure ] svg/custom/mask-child-changes.svg [ Failure ] svg/custom/mask-colorspace.svg [ Failure ] -svg/custom/mask-excessive-malloc.svg [ Failure ] svg/custom/mask-inside-defs.svg [ Failure ] svg/custom/mask-invalidation.svg [ Failure ] svg/custom/mask-on-multiple-objects.svg [ Failure ] @@ -1915,29 +1651,23 @@ svg/custom/relative-sized-inner-svg.xhtml [ Failure ] svg/custom/relative-sized-use-on-symbol.xhtml [ Failure ] svg/custom/relative-sized-use-without-attributes-on-symbol.xhtml [ Failure ] -svg/custom/repaint-moving-svg-and-div.xhtml [ Crash Failure ] -svg/custom/resource-client-removal.svg [ Failure ] svg/custom/resource-invalidate-on-target-update.svg [ Failure ] -svg/custom/resources-css-scaled.html [ Failure ] svg/custom/root-container-opacity-clip-viewBox.svg [ Failure ] svg/custom/root-size-attribute-changes.html [ Failure ] svg/custom/scrolling-embedded-svg-file-image-repaint-problem.html [ Failure ] svg/custom/shape-rendering.svg [ Failure ] svg/custom/shapes-supporting-markers.svg [ Failure ] -svg/custom/small-rect-scale.svg [ Failure ] svg/custom/stroke-opacity-update.svg [ Failure ] svg/custom/stroke-width-large.svg [ Failure ] svg/custom/stroked-pattern.svg [ Failure ] svg/custom/subpaths-moveto-only-rendering.svg [ Failure ] svg/custom/svg-float-border-padding.xml [ Failure ] svg/custom/svg-image-par-none-no-intrinsic-size.html [ Failure ] -svg/custom/svg-image-par-resize.html [ Crash ] svg/custom/svg-overflow-types.svg [ Failure ] svg/custom/svg-root-padding-border-margin.html [ Failure ] svg/custom/text-dom-01-f.svg [ Failure ] svg/custom/text-dom-removal.svg [ Failure ] svg/custom/text-filter.svg [ Failure ] -svg/custom/text-image-opacity.svg [ Failure ] svg/custom/text-match-highlight.html [ Failure ] svg/custom/text-repaint-including-stroke.svg [ Failure ] svg/custom/text-rotated-gradient.svg [ Failure ] @@ -1947,7 +1677,6 @@ svg/custom/transformed-outlines.svg [ Failure ] svg/custom/transformed-pattern-clamp-svg-root.svg [ Failure ] svg/custom/transformed-text-pattern.html [ Failure ] -svg/custom/transformedMaskFails.svg [ Failure ] svg/custom/use-attribute-invalidations.html [ Failure ] svg/custom/use-clipped-hit.svg [ Failure ] svg/custom/use-css-no-effect-on-shadow-tree.svg [ Failure ] @@ -1977,7 +1706,6 @@ svg/custom/use-property-changes-through-dom.svg [ Failure ] svg/custom/use-property-changes-through-svg-dom.svg [ Failure ] svg/custom/use-referencing-nonexisting-symbol.svg [ Failure ] -svg/custom/use-setAttribute-crash.svg [ Failure ] svg/custom/use-transform.svg [ Failure ] svg/custom/viewBox-hit.svg [ Failure ] svg/custom/viewbox-syntax.svg [ Failure ] @@ -2206,10 +1934,6 @@ svg/dynamic-updates/SVGFilterPrimitiveStandardAttributes-svgdom-width-prop.html [ Failure ] svg/dynamic-updates/SVGFilterPrimitiveStandardAttributes-svgdom-x-prop.html [ Failure ] svg/dynamic-updates/SVGFilterPrimitiveStandardAttributes-svgdom-y-prop.html [ Failure ] -svg/dynamic-updates/SVGForeignObjectElement-dom-x-attr.html [ Crash Failure ] -svg/dynamic-updates/SVGForeignObjectElement-dom-y-attr.html [ Crash Failure ] -svg/dynamic-updates/SVGForeignObjectElement-svgdom-x-prop.html [ Crash Failure ] -svg/dynamic-updates/SVGForeignObjectElement-svgdom-y-prop.html [ Crash Failure ] svg/dynamic-updates/SVGLinearGradientElement-dom-gradientTransform-attr.html [ Failure ] svg/dynamic-updates/SVGLinearGradientElement-dom-gradientUnits-attr.html [ Failure ] svg/dynamic-updates/SVGLinearGradientElement-dom-x1-attr.html [ Failure ] @@ -2255,12 +1979,13 @@ svg/filters/big-height-filter.svg [ Failure ] svg/filters/big-sized-filter-2.svg [ Failure ] svg/filters/big-sized-filter.svg [ Failure ] +svg/filters/big-viewbox.svg [ Failure ] svg/filters/big-width-filter.svg [ Failure ] svg/filters/color-clear-input.svg [ Failure ] svg/filters/color-interpolation-filters.svg [ Failure ] svg/filters/color-space-conversion.svg [ Failure ] svg/filters/container-with-filters.svg [ Failure ] -svg/filters/feBlend-all-modes.html [ Timeout ] +svg/filters/feBlend-all-modes.html [ Failure Timeout ] svg/filters/feColorMatrix-default-type.svg [ Failure ] svg/filters/feColorMatrix-offset.svg [ Failure ] svg/filters/feColorMatrix-saturate.svg [ Failure ] @@ -2286,7 +2011,6 @@ svg/filters/feDisplacementMap.svg [ Failure ] svg/filters/feDropShadow-flood-opacity-1.svg [ Failure ] svg/filters/feDropShadow-flood-opacity-2.svg [ Failure ] -svg/filters/feDropShadow-linearrgb-flood-color.svg [ Failure ] svg/filters/feDropShadow-subregion.svg [ Failure ] svg/filters/feDropShadow-zero-deviation.svg [ Failure ] svg/filters/feDropShadow.svg [ Failure ] @@ -2311,9 +2035,6 @@ svg/filters/feImage-preserveAspectratio.svg [ Failure ] svg/filters/feImage-reference-invalidation.svg [ Failure ] svg/filters/feImage-reference-svg-primitive.svg [ Failure ] -svg/filters/feImage-scaled-viewport.svg [ Failure ] -svg/filters/feImage-self-and-other-referencing.html [ Crash ] -svg/filters/feImage-self-referencing.html [ Crash ] svg/filters/feImage-subregions-preseveAspectRatio-none-with-viewBox.svg [ Failure ] svg/filters/feImage-subregions-preseveAspectRatio-none.svg [ Failure ] svg/filters/feImage-subregions.svg [ Failure ] @@ -2366,7 +2087,6 @@ svg/filters/subRegion-one-effect.svg [ Failure ] svg/filters/subRegion-two-effects.svg [ Failure ] svg/filters/svg-element-invalid-filter.html [ Failure ] -svg/filters/svg-filter-child-box-reflect.html [ Failure ] svg/filters/svg-filter-root-box-reflect.html [ Failure ] svg/foreignObject/clip.html [ Failure ] svg/foreignObject/filter-repaint.svg [ Failure ] @@ -2410,24 +2130,16 @@ svg/overflow/overflow-on-outermost-svg-element-in-xhtml-defaults.xhtml [ Failure ] svg/overflow/overflow-on-outermost-svg-element-in-xhtml-hidden.xhtml [ Failure ] svg/overflow/overflow-on-outermost-svg-element-in-xhtml-scroll.xhtml [ Failure ] -svg/repaint/buffered-rendering-dynamic-image.html [ Crash ] -svg/repaint/buffered-rendering-static-image.html [ Crash ] svg/repaint/filter-child-repaint.svg [ Failure ] svg/repaint/filter-repaint.svg [ Failure ] svg/repaint/focus-element.html [ Failure ] svg/repaint/foreign-object-repaint.svg [ Failure ] -svg/repaint/image-animation-with-zoom.html [ Crash ] -svg/repaint/image-with-clip-path.svg [ Failure ] -svg/repaint/inner-svg-change-viewPort-relative.svg [ Failure ] svg/repaint/mask-clip-target-transform.svg [ Failure ] svg/repaint/paintorder-filtered.svg [ Failure ] svg/repaint/repaint-in-scrolled-view.html [ Failure ] svg/repaint/repaint-paintorder.svg [ Failure ] svg/repaint/svg-length-rem-unit-font-size-change.html [ Failure ] svg/repaint/text-mask-update.svg [ Failure ] -svg/repaint/text-pattern-update-2.html [ Crash Failure ] -svg/repaint/text-pattern-update.html [ Crash Failure ] -svg/repaint/tspan-pattern-update.html [ Crash Failure ] svg/stroke/non-scaling-stroke-zero-length-subpath-linecaps.html [ Failure ] svg/stroke/zero-length-arc-linecaps-rendering.svg [ Failure ] svg/stroke/zero-length-path-linecap-rendering.svg [ Failure ] @@ -2480,7 +2192,6 @@ svg/text/text-fill-opacity.svg [ Failure ] svg/text/text-layout-crash.html [ Failure ] svg/text/text-repaint-rects.xhtml [ Failure ] -svg/text/text-rescale.html [ Failure ] svg/text/text-selection-align-01-b.svg [ Failure ] svg/text/text-selection-align-02-b.svg [ Failure ] svg/text/text-selection-align-03-b.svg [ Failure ] @@ -2505,7 +2216,6 @@ svg/text/text-selection-tspan-01-b.svg [ Failure ] svg/text/text-selection-ws-01-t.svg [ Failure ] svg/text/text-selection-ws-02-t.svg [ Failure ] -svg/text/text-viewbox-rescale.html [ Failure ] svg/text/text-with-geometric-precision.svg [ Crash Failure ] svg/text/textPathBoundsBug.svg [ Failure ] svg/transforms/animated-path-inside-transformed-html.xhtml [ Failure ] @@ -2593,7 +2303,6 @@ svg/W3C-SVG-1.1/animate-elem-17-t.svg [ Failure ] svg/W3C-SVG-1.1/animate-elem-18-t.svg [ Failure ] svg/W3C-SVG-1.1/animate-elem-19-t.svg [ Failure ] -svg/W3C-SVG-1.1/animate-elem-22-b.svg [ Failure ] svg/W3C-SVG-1.1/animate-elem-24-t.svg [ Failure ] svg/W3C-SVG-1.1/animate-elem-25-t.svg [ Failure ] svg/W3C-SVG-1.1/animate-elem-28-t.svg [ Failure ] @@ -2755,14 +2464,11 @@ svg/W3C-SVG-1.2-Tiny/struct-use-recursion-01-t.svg [ Failure ] svg/W3C-SVG-1.2-Tiny/struct-use-recursion-02-t.svg [ Failure ] svg/W3C-SVG-1.2-Tiny/struct-use-recursion-03-t.svg [ Failure ] -svg/wicd/rightsizing-grid.html [ Failure ] -svg/wicd/test-rightsizing-a.xhtml [ Failure ] svg/wicd/test-rightsizing-b.xhtml [ Crash ] svg/wicd/test-scalable-background-image1.xhtml [ Failure ] svg/zoom/page/absolute-sized-document-no-scrollbars.svg [ Failure ] svg/zoom/page/absolute-sized-document-scrollbars.svg [ Failure ] svg/zoom/page/relative-sized-document-scrollbars.svg [ Failure ] -svg/zoom/page/zoom-background-image-tiled.html [ Crash ] svg/zoom/page/zoom-clip-path.html [ Failure ] svg/zoom/page/zoom-coords-viewattr-01-b.svg [ Failure ] svg/zoom/page/zoom-foreign-content.svg [ Failure ] @@ -2772,10 +2478,7 @@ svg/zoom/page/zoom-img-preserveAspectRatio-support-1.html [ Crash Failure Timeout ] svg/zoom/page/zoom-mask-with-percentages.svg [ Failure ] svg/zoom/page/zoom-replaced-intrinsic-ratio-001.htm [ Failure ] -svg/zoom/page/zoom-svg-as-background-with-relative-size-and-viewBox.html [ Crash ] -svg/zoom/page/zoom-svg-as-image.html [ Crash ] svg/zoom/page/zoom-svg-as-object.html [ Failure ] -svg/zoom/page/zoom-svg-as-relative-image.html [ Crash ] svg/zoom/page/zoom-svg-float-border-padding.xml [ Failure ] svg/zoom/page/zoom-svg-through-object-with-absolute-size-2.xhtml [ Failure ] svg/zoom/page/zoom-svg-through-object-with-absolute-size.xhtml [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process index 502c5c9..5f9177e6 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process +++ b/third_party/WebKit/LayoutTests/FlagExpectations/site-per-process
@@ -8,9 +8,6 @@ http/tests/security/upgrade-insecure-requests/iframe-upgrade.https.html [ Crash ] http/tests/security/upgrade-insecure-requests/iframe-upgrade-csp.https.html [ Crash ] -# https://crbug.com/635400 - Origin header is set to "null" in HTTP POST request made using OpenURL code path. -http/tests/navigation/form-targets-cross-site-frame-post.html [ Failure ] - # https://crbug.com/582494 - [sigsegv / av] blink::Document::styleEngine. http/tests/security/mixedContent/insecure-plugin-in-iframe.html [ Crash ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 8a96a90..96c5f18 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -31,174 +31,21 @@ # existing tests. We have skipped the entire spv2 directory and are adding [ Pass ] lines # as we go. Please remove [ Pass ] lines instead of rebaselining these tests. crbug.com/537409 virtual/spv2/ [ Skip ] -crbug.com/537409 virtual/spv2/paint/subpixel [ Pass ] -crbug.com/537409 virtual/spv2/fast/clip [ Pass ] -crbug.com/537409 virtual/spv2/fast/overflow [ Pass ] crbug.com/563667 virtual/spv2/fast/block/basic/001.html [ Pass ] -crbug.com/563667 virtual/spv2/fast/block/positioning/static-distance-with-positioned-ancestor.html [ Pass ] -crbug.com/563667 virtual/spv2/fast/block/float/clamped-right-float.html [ Pass ] crbug.com/580355 virtual/spv2/fast/block/basic/018.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/basic/adding-near-anonymous-block.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/basic/text-indent-rtl.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/basic/white-space-pre-wraps.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/float/001.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/float/independent-align-positioning.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/float/intruding-painted-twice.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/float/shrink-to-fit-width.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/float/table-relayout.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/float/vertical-move-relayout.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/margin-collapse/001.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/margin-collapse/005.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/margin-collapse/012.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/margin-collapse/015.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/margin-collapse/016.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/margin-collapse/019.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/margin-collapse/020.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/margin-collapse/056.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/margin-collapse/059.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/margin-collapse/block-inside-inline/001.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/margin-collapse/block-inside-inline/005.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/margin-collapse/block-inside-inline/012.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/margin-collapse/block-inside-inline/015.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/margin-collapse/block-inside-inline/016.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/margin-collapse/block-inside-inline/019.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/margin-collapse/block-inside-inline/020.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/positioning/height-change.html [ Pass ] -crbug.com/580355 virtual/spv2/fast/block/positioning/relayout-on-position-change.html [ Pass ] -crbug.com/587236 virtual/spv2/compositing/backface-visibility/backface-visibility-3d.html [ Pass ] -crbug.com/587236 virtual/spv2/compositing/backface-visibility/backface-visibility-simple.html [ Pass ] -crbug.com/587970 virtual/spv2/compositing/plugins/webplugin-alpha.html [ Pass ] -crbug.com/587970 virtual/spv2/compositing/plugins/webplugin-no-alpha.html [ Pass ] crbug.com/596780 virtual/spv2/compositing/framesets/composited-frame-alignment.html [ Pass ] crbug.com/596780 virtual/spv2/compositing/geometry/outline-change.html [ Pass ] -crbug.com/596780 virtual/spv2/compositing/squashing/incorrect-clip-after-remove-compositing.html [ Pass ] -crbug.com/600618 virtual/spv2/svg/custom/fill-update.svg [ Pass ] -crbug.com/600618 virtual/spv2/svg/custom/getscreenctm-in-mixed-content.xhtml [ Pass ] -crbug.com/600618 virtual/spv2/svg/custom/non-scaling-stroke-markers.svg [ Pass ] crbug.com/600618 virtual/spv2/svg/custom/object-current-scale.html [ Pass ] crbug.com/600618 virtual/spv2/svg/custom/object-sizing-explicit-height.xhtml [ Pass ] -crbug.com/600618 virtual/spv2/svg/custom/object-sizing-explicit-width-height.xhtml [ Pass ] -crbug.com/600618 virtual/spv2/svg/custom/object-sizing-explicit-width.xhtml [ Pass ] -crbug.com/600618 virtual/spv2/svg/custom/svg-root-padding-left.html [ Pass ] -crbug.com/600618 virtual/spv2/svg/custom/svg-root-padding-top.html [ Pass ] -crbug.com/600618 virtual/spv2/svg/css/max-height.html [ Pass ] -crbug.com/600618 virtual/spv2/svg/css/max-width.html [ Pass ] -crbug.com/614257 virtual/spv2/fast/block/positioning [ Pass ] -crbug.com/619427 [ Linux ] virtual/spv2/fast/overflow/overflow-height-float-not-removed-crash3.html [ Pass Failure ] - -crbug.com/510908 virtual/spv2/svg/custom/object-sizing-no-width-height-change-content-box-size.xhtml [ Failure ] -crbug.com/524134 virtual/spv2/paint/invalidation/invalidate-after-composited-scroll.html [ Failure ] -crbug.com/524134 virtual/spv2/fast/repaint/focus-ring-on-continuation-move.html [ Failure ] -crbug.com/524236 virtual/spv2/compositing/overflow/updating-scrolling-content.html [ Failure ] -crbug.com/524236 virtual/spv2/compositing/overflow/scrolling-without-painting.html [ Failure ] -crbug.com/524236 virtual/spv2/compositing/repaint/clipping-should-not-repaint-composited-descendants.html [ Failure ] -crbug.com/524236 virtual/spv2/compositing/repaint/scroll-fixed-layer-no-content.html [ Failure ] -crbug.com/524236 virtual/spv2/compositing/repaint/scroll-fixed-layer-out-of-view.html [ Failure ] -crbug.com/524236 virtual/spv2/compositing/repaint/scroll-fixed-squahed-layer.html [ Failure ] -crbug.com/524236 virtual/spv2/compositing/repaint/should-not-repaint-composited-descendants-on-overflow-change.html [ Failure ] -crbug.com/524236 virtual/spv2/compositing/repaint/should-not-repaint-composited-descendants.html [ Failure ] -crbug.com/524236 virtual/spv2/compositing/repaint/should-not-repaint-composited-filter.html [ Failure ] -crbug.com/524236 virtual/spv2/compositing/repaint/should-not-repaint-composited-opacity.html [ Failure ] -crbug.com/524236 virtual/spv2/compositing/repaint/should-not-repaint-composited-transform.html [ Failure ] -crbug.com/524236 virtual/spv2/fast/repaint/clip-path-constant-repaint.html [ Failure ] -crbug.com/524236 crbug.com/619103 virtual/spv2/fast/repaint/relative-positioned-movement-repaint.html [ Failure Crash Timeout ] - -# PaintArtifactCompositor doesn't implement effects yet. -crbug.com/563667 virtual/spv2/fast/overflow/007.html [ Failure ] - -# Sub-pixel differences in layout tests for SPv2 -crbug.com/589265 virtual/spv2/fast/clip/nestedTransparencyClip.html [ Failure ] -crbug.com/589265 virtual/spv2/fast/clip/outline-overflowClip.html [ Failure ] -crbug.com/589265 virtual/spv2/fast/block/float/002.html [ Failure ] -crbug.com/589265 virtual/spv2/fast/overflow/001.html [ Failure ] -crbug.com/589265 virtual/spv2/fast/overflow/003.xml [ Failure ] -crbug.com/589265 virtual/spv2/fast/overflow/border-radius-clipping.html [ Failure ] -crbug.com/589265 virtual/spv2/fast/overflow/childFocusRingClip.html [ Failure ] -crbug.com/589265 virtual/spv2/fast/overflow/clip-rects-fixed-ancestor.html [ Failure ] -crbug.com/589265 virtual/spv2/fast/overflow/dynamic-hidden.html [ Failure ] -crbug.com/589265 virtual/spv2/fast/overflow/float-in-relpositioned.html [ Failure ] -crbug.com/589265 virtual/spv2/fast/overflow/hit-test-overflow-controls.html [ Failure ] -crbug.com/589265 virtual/spv2/fast/overflow/image-selection-highlight.html [ Failure ] -crbug.com/589265 virtual/spv2/fast/overflow/overflow-float-stacking.html [ Failure ] -crbug.com/589265 virtual/spv2/fast/overflow/overflow-focus-ring.html [ Failure ] -crbug.com/589265 virtual/spv2/fast/overflow/overflow-stacking.html [ Failure ] -crbug.com/589265 virtual/spv2/fast/overflow/overflow-text-hit-testing.html [ Failure ] -crbug.com/589265 virtual/spv2/fast/overflow/overflow-update-transform.html [ Failure ] -crbug.com/589265 virtual/spv2/fast/overflow/overflow-with-local-background-attachment.html [ Failure ] -crbug.com/589265 virtual/spv2/fast/overflow/scroll-nested-positioned-layer-in-overflow.html [ Failure ] -crbug.com/589265 virtual/spv2/fast/overflow/scrollbar-position-update.html [ Failure ] -crbug.com/589265 virtual/spv2/compositing/geometry/root-layer-update.html [ Failure ] - -# Implement scrollbars in FramePainter for SPv2 -crbug.com/589279 virtual/spv2/fast/overflow/006.html [ Failure ] -crbug.com/589279 virtual/spv2/fast/overflow/hidden-viewport-x.html [ Failure ] -crbug.com/589279 virtual/spv2/fast/overflow/hidden-viewport-y.html [ Failure ] -crbug.com/589279 virtual/spv2/fast/overflow/overflow-x-y.html [ Failure ] -crbug.com/589279 virtual/spv2/fast/overflow/position-fixed-transform-clipping.html [ Failure ] -crbug.com/589279 virtual/spv2/fast/overflow/scrollRevealButton.html [ Failure ] -crbug.com/589279 virtual/spv2/fast/block/positioning/047.html [ Failure ] -crbug.com/589279 virtual/spv2/fast/block/positioning/051.html [ Failure ] -crbug.com/589279 virtual/spv2/fast/block/positioning/055.html [ Failure ] -crbug.com/589279 virtual/spv2/fast/block/positioning/auto/007.html [ Failure ] -crbug.com/589279 virtual/spv2/fast/block/positioning/fixed-positioning-scrollbar-bug.html [ Failure ] -crbug.com/589279 virtual/spv2/fast/block/positioning/relative-overflow-block.html [ Failure ] -crbug.com/589279 virtual/spv2/fast/block/positioning/relative-overflow-replaced-float.html [ Failure ] -crbug.com/589279 virtual/spv2/fast/block/positioning/relative-overflow-replaced.html [ Failure ] -crbug.com/589279 virtual/spv2/fast/block/positioning/vertical-lr/002.html [ Failure ] -crbug.com/589279 virtual/spv2/fast/block/positioning/vertical-rl/002.html [ Failure ] -crbug.com/589279 virtual/spv2/fast/block/positioning/auto/vertical-lr/005.html [ Failure ] -crbug.com/589279 virtual/spv2/fast/block/positioning/auto/vertical-rl/005.html [ Failure ] - -# Implement table walk in PaintPropertyTreeBuilder. -crbug.com/593525 virtual/spv2/fast/overflow/002.html [ Failure ] -crbug.com/593525 virtual/spv2/fast/overflow/overflow-rtl-vertical.html [ Failure ] -crbug.com/593525 virtual/spv2/fast/overflow/overflow-rtl.html [ Failure ] -crbug.com/593525 virtual/spv2/fast/overflow/table-overflow-float.html [ Failure ] - -# These failures have been manually verified to be only paint invalidation text differences. -crbug.com/596780 virtual/spv2/compositing/geometry/bounds-clipped-composited-child.html [ Failure ] -crbug.com/596780 virtual/spv2/compositing/geometry/bounds-ignores-hidden-dynamic-negzindex.html [ Failure ] -crbug.com/596780 virtual/spv2/compositing/geometry/bounds-ignores-hidden-dynamic.html [ Failure ] -crbug.com/596780 virtual/spv2/compositing/rtl/rtl-iframe-absolute-overflow.html [ Failure ] -crbug.com/596780 virtual/spv2/compositing/rtl/rtl-iframe-absolute.html [ Failure ] -crbug.com/596780 virtual/spv2/compositing/rtl/rtl-iframe-fixed-overflow.html [ Failure ] -crbug.com/596780 virtual/spv2/compositing/rtl/rtl-iframe-fixed.html [ Failure ] -crbug.com/596780 virtual/spv2/compositing/rtl/rtl-iframe-relative.html [ Failure ] -crbug.com/596780 virtual/spv2/compositing/visibility/layer-visible-content.html [ Failure ] - -# [SPv2] Handle transform space reversion in PaintArtifactCompositor -crbug.com/597156 virtual/spv2/fast/clip/010.html [ Crash Failure Timeout ] - -# [SPv2] Implement border radius rasterizing / drawing -crbug.com/597158 virtual/spv2/fast/clip/overflow-border-radius-clip.html [ Failure ] -crbug.com/597158 virtual/spv2/fast/clip/overflow-border-radius-combinations.html [ Failure ] -crbug.com/597158 virtual/spv2/fast/clip/overflow-border-radius-composited-parent.html [ Failure ] -crbug.com/597158 virtual/spv2/fast/clip/overflow-border-radius-composited.html [ Failure ] -crbug.com/597158 virtual/spv2/fast/clip/overflow-border-radius-fixed-position.html [ Failure ] -crbug.com/597158 virtual/spv2/fast/clip/overflow-border-radius-transformed.html [ Failure ] - -# This test has a paint invalidation failure that needs to be investigated. -crbug.com/600618 virtual/spv2/svg/as-image/svg-image-with-data-uri.html [ Failure Crash ] - # SkiaBitLocker should avoid allocating huge offscreen buffer crbug.com/605812 [ Mac ] virtual/spv2/fast/overflow/overflow-height-float-not-removed-crash.html [ Skip ] crbug.com/605812 [ Mac ] virtual/spv2/fast/overflow/overflow-height-float-not-removed-crash2.html [ Skip ] - -# Multicolumn still fails to fragment in spv2. -crbug.com/616287 virtual/spv2/fast/block/positioning/offsetLeft-offsetTop-multicolumn.html [ Failure ] - # --- End SPV2 Tests --- -crbug.com/240374 compositing/overlap-blending/reflection-opacity-huge.html [ Failure ] -crbug.com/240374 compositing/overlap-blending/children-opacity-huge.html [ Failure ] -crbug.com/240374 compositing/overlap-blending/children-opacity-no-overlap.html [ Failure ] - crbug.com/245556 compositing/transitions/transform-on-large-layer.html [ Failure ] crbug.com/309675 compositing/gestures/gesture-tapHighlight-simple-longPress.html [ Failure ] -crbug.com/320139 fast/repaint/block-layout-inline-children-replaced.html [ Pass Failure ] - # Started failing after r162705. crbug.com/324370 compositing/video/video-reflection.html [ Failure ] @@ -260,8 +107,6 @@ crbug.com/619103 fast/layers/remove-layer-with-nested-stacking.html [ Pass Crash Timeout ] crbug.com/619103 compositing/iframes/become-composited-nested-iframes.html [ Pass Crash Timeout ] -crbug.com/622368 [ Linux Win Debug ] fast/repaint/obscured-background-no-repaint.html [ Pass Failure ] - # TODO(fmalita): re-enable # crbug.com/624709 [ Win ] virtual/gpu-rasterization/fast/images/png-with-color-profile.html [ Failure ] crbug.com/624709 [ Win ] virtual/gpu-rasterization/fast/images/webp-color-profile-lossy.html [ Failure ] @@ -291,9 +136,13 @@ crbug.com/636222 [ Mac10.10 ] fast/repaint/fixed-and-absolute-position-scrolled.html [ Failure ] crbug.com/636271 [ Mac10.10 ] fast/repaint/resize-iframe-text.html [ Pass Failure ] +crbug.com/636271 [ Linux ] fast/repaint/resize-iframe-text.html [ Pass Failure ] +crbug.com/636271 [ Win ] fast/repaint/resize-iframe-text.html [ Pass Failure ] crbug.com/636311 [ Win10 ] svg/custom/use-clipped-hit.svg [ Pass Failure ] +crbug.com/637069 fast/repaint/block-layout-inline-children-replaced.html [ Pass Failure ] + # ====== Paint team owned tests to here ====== # Run these tests with under virtual/scalefactor... only. @@ -557,6 +406,8 @@ crbug.com/525889 imported/wpt/html/webappapis/scripting/processing-model-2/runtime-error-in-setInterval.html [ Failure ] crbug.com/525889 imported/wpt/html/webappapis/scripting/processing-model-2/runtime-error-in-setTimeout.html [ Failure ] +crbug.com/636961 [ Linux Debug ] virtual/threaded/fast/scroll-behavior/smooth-scroll/ongoing-smooth-scroll-vertical-rl-anchors.html [ Pass Failure ] + crbug.com/552532 [ Win10 ] fast/replaced/no-focus-ring-embed.html [ Pass Crash ] crbug.com/552532 [ Win10 ] fast/replaced/no-focus-ring-object.html [ Pass Crash ] crbug.com/552532 [ Win10 ] plugins/focus.html [ Pass Crash ] @@ -724,6 +575,18 @@ # Test sometimes flakes on most platforms crbug.com/571531 imported/csswg-test/css-flexbox-1/css-flexbox-height-animation-stretch.html [ Pass Failure ] +crbug.com/637055 fast/css/outline-offset-large.html [ Skip ] + +crbug.com/529938 virtual/spv2/fast/block/positioning/absolute-length-of-neg-666666.html [ Skip ] + +crbug.com/617785 fast/borders/block-mask-overlay-image-outset.html [ Skip ] + +# Some SVG tests fail due to incorrect visual rects. +crbug.com/598051 css3/filters/effect-reference-hidpi.html [ Skip ] +crbug.com/598051 svg/custom/absolute-sized-content-with-resources.xhtml [ Skip ] +crbug.com/598051 svg/overflow/overflow-on-foreignObject.svg [ Skip ] +crbug.com/598051 svg/zoom/page/zoom-foreignObject.svg [ Skip ] + # Either "combo" or split should run: http://testthewebforward.org/docs/css-naming.html crbug.com/410320 imported/csswg-test/css-writing-modes-3/orthogonal-parent-shrink-to-fit-001.html [ Skip ] crbug.com/492664 imported/csswg-test/css-writing-modes-3/text-orientation-script-001.html [ Skip ] @@ -736,6 +599,7 @@ crbug.com/621515 inspector/sources/debugger-async/async-await/async-callstack-async-await1.html [ Skip ] crbug.com/621515 inspector/sources/debugger-async/async-await/async-callstack-async-await2.html [ Skip ] crbug.com/621515 inspector/sources/debugger-async/async-await/async-callstack-async-await3.html [ Skip ] +crbug.com/636837 [ Win7 Debug ] virtual/asyncawait/inspector/sources/debugger-async/async-await/async-callstack-async-await2.html [ Timeout ] # These tests pass but images do not match because of position: absolute in vertical flow bug crbug.com/492664 imported/csswg-test/css-writing-modes-3/block-flow-direction-vrl-009.xht [ Failure ] @@ -749,6 +613,9 @@ crbug.com/492664 imported/csswg-test/css-writing-modes-3/clip-rect-vrl-008.xht [ Failure ] crbug.com/492664 imported/csswg-test/css-writing-modes-3/line-box-direction-vrl-009.xht [ Failure ] +crbug.com/637255 [ Win10 ] media/video-transformed.html [ Pass Failure ] +crbug.com/637255 [ Win10 ] media/video-layer-crash.html [ Pass Failure ] + # These tests pass but images do not match because tests are stricter than the spec. crbug.com/492664 imported/csswg-test/css-writing-modes-3/text-combine-upright-value-all-001.html [ Failure ] crbug.com/492664 imported/csswg-test/css-writing-modes-3/text-combine-upright-value-all-002.html [ Failure ] @@ -1271,8 +1138,6 @@ crbug.com/575766 http/tests/inspector/resource-tree/resource-tree-frame-add.html [ Timeout Pass ] crbug.com/581468 http/tests/inspector/resource-tree/resource-tree-non-unique-url.html [ Pass Failure ] -crbug.com/571710 http/tests/inspector/search/source-frame-search.html [ Timeout Pass ] - crbug.com/399951 http/tests/mime/javascript-mimetype-usecounters.html [ Pass Failure ] crbug.com/579493 http/tests/security/xss-DENIED-xsl-document-securityOrigin.xml [ Timeout ] @@ -1348,7 +1213,8 @@ crbug.com/487344 fast/hidpi/video-controls-in-hidpi.html [ Failure ] crbug.com/487344 fast/layers/video-layer.html [ Failure ] -crbug.com/487344 http/tests/media/video-buffered-range-contains-currentTime.html [ Failure ] +# Commented out temporarily for manual rebase and it will be restored after that. +#crbug.com/487344 http/tests/media/video-buffered-range-contains-currentTime.html [ Failure ] crbug.com/487344 media/audio-controls-rendering.html [ Failure ] crbug.com/487344 media/audio-repaint.html [ Failure ] crbug.com/487344 media/controls-after-reload.html [ Failure ] @@ -1379,8 +1245,6 @@ # Note: this test was previously marked as slow on Debug builds. Skipping until crash is fixed crbug.com/619978 fast/css/giant-stylesheet-crash.html [ Skip ] -crbug.com/622819 imported/wpt/IndexedDB/transaction-lifetime-empty.html [ Skip ] - crbug.com/621892 css3/filters/effect-brightness-clamping-hw.html [ Pass Failure ] crbug.com/621892 css3/filters/effect-brightness-hw.html [ Pass Failure ] crbug.com/621892 css3/filters/effect-hue-rotate-hw.html [ Pass Failure ] @@ -1398,6 +1262,7 @@ # Very slight rendering changes caused by Skia rect clipping change. crbug.com/627844 virtual/gpu/fast/canvas/canvas-createImageBitmap-colorClamping.html [ Pass Failure ] +crbug.com/588956 http/tests/media/video-buffered-range-contains-currentTime.html [ NeedsManualRebaseline ] crbug.com/629711 [ Linux Debug ] fast/workers/shared-worker-exception.html [ Crash Pass ] crbug.com/629711 [ Linux Debug ] virtual/sharedarraybuffer/fast/workers/shared-worker-exception.html [ Crash Pass ] @@ -1411,6 +1276,23 @@ crbug.com/631039 [ Win7 ] virtual/threaded/fast/scroll-behavior/main-frame-scroll.html [ Pass Failure ] crbug.com/631039 [ Win7 ] virtual/threaded/fast/scroll-behavior/overflow-scroll-scroll.html [ Pass Failure ] +crbug.com/637245 [ Mac10.11 Retina ] fast/html/details-add-summary-5-and-click.html [ Pass Failure ] +crbug.com/637245 [ Mac10.11 Retina ] fast/html/details-add-summary-8-and-click.html [ Pass Failure ] +crbug.com/637245 [ Mac10.11 Retina ] fast/html/details-add-summary-1-and-click.html [ Pass Failure ] +crbug.com/637245 [ Mac10.11 Retina ] fast/html/details-add-summary-2-and-click.html [ Pass Failure ] +crbug.com/637245 [ Mac10.11 Retina ] fast/html/details-add-summary-10-and-click.html [ Pass Failure ] +crbug.com/637245 [ Mac10.11 Retina ] fast/html/details-remove-summary-6-and-click.html [ Pass Failure ] +crbug.com/637245 [ Mac10.11 Retina ] fast/html/details-add-summary-7-and-click.html [ Pass Failure ] +crbug.com/637245 [ Mac10.11 Retina ] fast/html/details-remove-summary-5-and-click.html [ Pass Failure ] +crbug.com/637245 [ Mac10.11 Retina ] fast/html/details-remove-summary-1-and-click.html [ Pass Failure ] +crbug.com/637245 [ Mac10.11 Retina ] fast/html/details-add-summary-6-and-click.html [ Pass Failure ] +crbug.com/637245 [ Mac10.11 Retina ] fast/html/details-add-summary-9-and-click.html [ Pass Failure ] +crbug.com/637245 [ Mac10.11 Retina ] fast/html/details-remove-summary-4-and-click.html [ Pass Failure ] +crbug.com/637245 [ Mac10.11 Retina ] fast/html/details-remove-summary-3-and-click.html [ Pass Failure ] +crbug.com/637245 [ Mac10.11 Retina ] fast/html/details-add-summary-4-and-click.html [ Pass Failure ] +crbug.com/637245 [ Mac10.11 Retina ] fast/html/details-remove-summary-2-and-click.html [ Pass Failure ] +crbug.com/637245 [ Mac10.11 Retina ] fast/html/details-add-summary-3-and-click.html [ Pass Failure ] + # Flaky on Win7 dbg and Mac10.11 (retina) crbug.com/634019 [ Win7 Debug Mac10.11 Retina ] virtual/asyncawait/inspector/sources/debugger-async/async-await/async-callstack-async-await1.html [ Pass Timeout ]
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites index a73430f..56aaf40 100644 --- a/third_party/WebKit/LayoutTests/VirtualTestSuites +++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -263,5 +263,20 @@ "prefix": "asyncawait", "base": "inspector/sources/debugger-async/async-await", "args": ["--js-flags=--harmony-async-await"] + }, + { + "prefix": "parsehtmlonmainthread_sync", + "base": "fast/parser", + "args": ["--blink-settings=parseHTMLOnMainThreadSyncTokenize=true"] + }, + { + "prefix": "parsehtmlonmainthread_coalesce", + "base": "fast/parser", + "args": ["--disable-blink-features=ParseHTMLOnMainThread", "--blink-settings=parseHTMLOnMainThreadCoalesceChunks=true"] + }, + { + "prefix": "mojo-loading", + "base": "webexposed", + "args": ["--enable-blink-features=LoadingWithMojo"] } ]
diff --git a/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal-expected.txt b/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal-expected.txt index 3534050b..d620d48 100644 --- a/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal-expected.txt +++ b/third_party/WebKit/LayoutTests/accessibility/element-role-mapping-normal-expected.txt
@@ -95,9 +95,10 @@ AXRole: AXInlineTextBox "b" AXRole: AXMain AXRole: AXArticle - AXRole: AXHeading "Most important heading here" - AXRole: AXStaticText "Most important heading here" - AXRole: AXInlineTextBox "Most important heading here" + AXRole: AXGroup + AXRole: AXHeading "Most important heading here" + AXRole: AXStaticText "Most important heading here" + AXRole: AXInlineTextBox "Most important heading here" AXRole: AXHeading "Google Chrome" AXRole: AXStaticText "Google Chrome" AXRole: AXInlineTextBox "Google Chrome" @@ -105,9 +106,10 @@ AXRole: AXStaticText "Google Chrome is a free, open-source web browser developed by Google, released in 2008." AXRole: AXInlineTextBox "Google Chrome is a free, open-source web browser developed by Google, " AXRole: AXInlineTextBox "released in 2008." - AXRole: AXParagraph - AXRole: AXStaticText "Footer in article" - AXRole: AXInlineTextBox "Footer in article" + AXRole: AXGroup + AXRole: AXParagraph + AXRole: AXStaticText "Footer in article" + AXRole: AXInlineTextBox "Footer in article" AXRole: AXNavigation AXRole: AXLink "HTML" AXRole: AXStaticText "HTML" @@ -139,15 +141,17 @@ AXRole: AXInlineTextBox " " AXRole: AXRegion - AXRole: AXHeading "Most important heading here" - AXRole: AXStaticText "Most important heading here" - AXRole: AXInlineTextBox "Most important heading here" + AXRole: AXGroup + AXRole: AXHeading "Most important heading here" + AXRole: AXStaticText "Most important heading here" + AXRole: AXInlineTextBox "Most important heading here" AXRole: AXParagraph AXRole: AXStaticText "Section" AXRole: AXInlineTextBox "Section" - AXRole: AXParagraph - AXRole: AXStaticText "Footer in section" - AXRole: AXInlineTextBox "Footer in section" + AXRole: AXGroup + AXRole: AXParagraph + AXRole: AXStaticText "Footer in section" + AXRole: AXInlineTextBox "Footer in section" AXRole: AXContentInfo AXRole: AXStaticText "Written by Julie" AXRole: AXInlineTextBox "Written by Julie"
diff --git a/third_party/WebKit/LayoutTests/compositing/overlap-blending/children-opacity-huge-expected.html b/third_party/WebKit/LayoutTests/compositing/overlap-blending/children-opacity-huge-expected.html deleted file mode 100644 index ab141db..0000000 --- a/third_party/WebKit/LayoutTests/compositing/overlap-blending/children-opacity-huge-expected.html +++ /dev/null
@@ -1,33 +0,0 @@ -<!DOCTYPE HTML> -<html> - <head> - <meta http-equiv="Content-type" content="text/html; charset=utf-8"> - <style type="text/css" media="screen"> - - div { - -webkit-box-sizing: border-box; - } - .solid { - position: absolute; - width: 2150px; - height: 200px; - background-color: green; - } - - .opacity { opacity: .5; } - .a { top: 0px; left: 0px;} - .b { top: 100px; left: 0px;} - - .composited { - transform: translateZ(0); - } - * { margin: 0; padding: 0; } - - </style> - </head> - <div class="opacity"> - <div class="solid a">1</div> - <div class="solid b">2</div> - </div> - -</html>
diff --git a/third_party/WebKit/LayoutTests/compositing/overlap-blending/children-opacity-no-overlap-expected.html b/third_party/WebKit/LayoutTests/compositing/overlap-blending/children-opacity-no-overlap-expected.html deleted file mode 100644 index 561c9a6..0000000 --- a/third_party/WebKit/LayoutTests/compositing/overlap-blending/children-opacity-no-overlap-expected.html +++ /dev/null
@@ -1,36 +0,0 @@ -<!DOCTYPE HTML> -<html> - <head> - <meta http-equiv="Content-type" content="text/html; charset=utf-8"> - <style type="text/css" media="screen"> - - div { - -webkit-box-sizing: border-box; - } - .solid { - position: absolute; - width: 100px; - height: 100px; - background-color: green; - } - - .opacity { opacity: .5; } - .a { top: 0px; left: 0px;} - .b { top: 200px; left: 200px;} - .c { top: 200px; left: 0px;} - .d { top: 0px; left: 200px;} - * { margin: 0; padding: 0; } - .composited { - transform: translateZ(0); - } - - </style> - </head> - <div class="opacity"> - <div class="solid a">1</div> - <div class="solid b">2</div> - <div class="solid c">3</div> - <div class="solid d"></div> - </div> - -</html>
diff --git a/third_party/WebKit/LayoutTests/compositing/overlap-blending/reflection-opacity-huge-expected.html b/third_party/WebKit/LayoutTests/compositing/overlap-blending/reflection-opacity-huge-expected.html deleted file mode 100644 index 149b14c..0000000 --- a/third_party/WebKit/LayoutTests/compositing/overlap-blending/reflection-opacity-huge-expected.html +++ /dev/null
@@ -1,24 +0,0 @@ -<!DOCTYPE HTML> -<html> - <head> - <meta http-equiv="Content-type" content="text/html; charset=utf-8"> - <style type="text/css" media="screen"> - .reflected { - position: relative; - width: 2150px; - height: 200px; - background-color: green; - opacity: 0.5; - -webkit-box-reflect: below -50px; - } - - * { margin: 0; padding: 0; } - - </style> - </head> - - <p>Opacity should be applied after reflection, so you should see a green rectangle below. The overlap between the original and reflection should not be visible.</p> - <div class="reflected">1 - </div> - -</html>
diff --git a/third_party/WebKit/LayoutTests/compositing/repaint/should-not-repaint-composited-descendants-expected.txt b/third_party/WebKit/LayoutTests/compositing/repaint/should-not-repaint-composited-descendants-expected.txt index 9070975..43cf41a8 100644 --- a/third_party/WebKit/LayoutTests/compositing/repaint/should-not-repaint-composited-descendants-expected.txt +++ b/third_party/WebKit/LayoutTests/compositing/repaint/should-not-repaint-composited-descendants-expected.txt
@@ -28,7 +28,7 @@ }, { "object": "LayoutBlockFlow DIV class='child'", - "rect": [-30, -30, 50, 50], + "rect": [0, 0, 20, 20], "reason": "subtree" } ],
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/ecdh/import-export-raw-expected.txt b/third_party/WebKit/LayoutTests/crypto/subtle/ecdh/import-export-raw-expected.txt new file mode 100644 index 0000000..f5abcf0cf --- /dev/null +++ b/third_party/WebKit/LayoutTests/crypto/subtle/ecdh/import-export-raw-expected.txt
@@ -0,0 +1,27 @@ +Test importing and exporting an EC public key in raw format. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +Importing raw (uncompressed) public key... +PASS publicKey.toString() is '[object CryptoKey]' +PASS publicKey.type is 'public' +PASS publicKey.usages is [] +PASS publicKey.algorithm.name is 'ECDH' +PASS publicKey.algorithm.namedCurve is 'P-256' +Exporting to raw... +PASS: Exported to raw should be [044ea34391aa73885454bc45df3fdcc4a70262fa4621ffe25b5790590c340a4bd9265ef2b3f9a86e2959a960d90323465d60cd4a90d314c5de3f869ad0d4bf6c10] and was +Importing raw (compressed) public key... +PASS publicKey.toString() is '[object CryptoKey]' +PASS publicKey.type is 'public' +PASS publicKey.usages is [] +PASS publicKey.algorithm.name is 'ECDH' +PASS publicKey.algorithm.namedCurve is 'P-256' +Exporting to raw... +PASS: Exported to raw should be [044ea34391aa73885454bc45df3fdcc4a70262fa4621ffe25b5790590c340a4bd9265ef2b3f9a86e2959a960d90323465d60cd4a90d314c5de3f869ad0d4bf6c10] and was +Importing invalid raw public key... +error is: DataError: +PASS successfullyParsed is true + +TEST COMPLETE +
diff --git a/third_party/WebKit/LayoutTests/crypto/subtle/ecdh/import-export-raw.html b/third_party/WebKit/LayoutTests/crypto/subtle/ecdh/import-export-raw.html new file mode 100644 index 0000000..005e912 --- /dev/null +++ b/third_party/WebKit/LayoutTests/crypto/subtle/ecdh/import-export-raw.html
@@ -0,0 +1,62 @@ +<!DOCTYPE html> +<html> +<head> +<script src="../../../resources/js-test.js"></script> +<script src="../resources/common.js"></script> +</head> +<body> +<p id="description"></p> +<div id="console"></div> + +<script> +description("Test importing and exporting an EC public key in raw format."); + +jsTestIsAsync = true; + +// P-256 key in uncompressed form +var kUncompressedHex = "044EA34391AA73885454BC45DF3FDCC4A70262FA4621FFE25B5790590C340A4BD9265EF2B3F9A86E2959A960D90323465D60CD4A90D314C5DE3F869AD0D4BF6C10"; + +// The same key as above but in compressed form. +var kCompressedHex = "024ea34391aa73885454bc45df3fdcc4a70262fa4621ffe25b5790590c340a4bd9"; + +var algorithm = {name: "ECDH", namedCurve: "P-256"}; +var extractable = true; + +debug("Importing raw (uncompressed) public key..."); +crypto.subtle.importKey("raw", hexStringToUint8Array(kUncompressedHex), algorithm, extractable, []).then(function(result) { + publicKey = result; + shouldBe("publicKey.toString()", "'[object CryptoKey]'"); + shouldBe("publicKey.type", "'public'"); + shouldBe("publicKey.usages", "[]"); + shouldBe("publicKey.algorithm.name", "'ECDH'"); + shouldBe("publicKey.algorithm.namedCurve", "'P-256'"); + + debug("Exporting to raw..."); + return crypto.subtle.exportKey("raw", publicKey); +}).then(function(result) { + bytesShouldMatchHexString("Exported to raw", kUncompressedHex, result) + + debug("Importing raw (compressed) public key..."); + return crypto.subtle.importKey("raw", hexStringToUint8Array(kCompressedHex), algorithm, extractable, []); +}).then(function(result) { + publicKey = result; + shouldBe("publicKey.toString()", "'[object CryptoKey]'"); + shouldBe("publicKey.type", "'public'"); + shouldBe("publicKey.usages", "[]"); + shouldBe("publicKey.algorithm.name", "'ECDH'"); + shouldBe("publicKey.algorithm.namedCurve", "'P-256'"); + + debug("Exporting to raw..."); + return crypto.subtle.exportKey("raw", publicKey); +}).then(function(result) { + bytesShouldMatchHexString("Exported to raw", kUncompressedHex, result) + + debug("Importing invalid raw public key..."); + return crypto.subtle.importKey("raw", hexStringToUint8Array("040708"), algorithm, extractable, []); +}).then(failAndFinishJSTest, function(result) { + logError(result); +}).then(finishJSTest, failAndFinishJSTest); +</script> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/css3/filters/filter-region-transformed-composited-child-expected.html b/third_party/WebKit/LayoutTests/css3/filters/filter-region-transformed-composited-child-expected.html new file mode 100644 index 0000000..1a8ab40 --- /dev/null +++ b/third_party/WebKit/LayoutTests/css3/filters/filter-region-transformed-composited-child-expected.html
@@ -0,0 +1,34 @@ +<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="0" height="0"> + <defs> + <filter id="filter" x="25%" y="0%" width="50%" height="100%"> + <feComponentTransfer> + <feFuncR type="linear" intercept="0" slope="1"/> + <feFuncG type="linear" intercept="0" slope="0"/> + <feFuncB type="linear" intercept="0" slope="0"/> + <feFuncA type="linear" intercept="0" slope="1"/> + </feComponentTransfer> + </filter> + </defs> +</svg> +<style> +div { + position: absolute; + filter: url(#filter); + background-color: gray; + width: 50px; + height: 50px; + will-change: transform; +} +.p1 { + left: 50px; + top: 50px; + transform: translate(0px, 25px); +} +.p2 { + left: 150px; + top: 50px; + transform: translate(0px, -25px); +} +</style> +<div class="p1"></div> +<div class="p2"></div>
diff --git a/third_party/WebKit/LayoutTests/css3/filters/filter-region-transformed-composited-child.html b/third_party/WebKit/LayoutTests/css3/filters/filter-region-transformed-composited-child.html new file mode 100644 index 0000000..f0ab1ce --- /dev/null +++ b/third_party/WebKit/LayoutTests/css3/filters/filter-region-transformed-composited-child.html
@@ -0,0 +1,43 @@ +<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="0" height="0"> + <defs> + <filter id="filter" x="25%" y="0%" width="50%" height="100%"> + <feComponentTransfer> + <feFuncR type="linear" intercept="0" slope="1"/> + <feFuncG type="linear" intercept="0" slope="0"/> + <feFuncB type="linear" intercept="0" slope="0"/> + <feFuncA type="linear" intercept="0" slope="1"/> + </feComponentTransfer> + </filter> + </defs> +</svg> +<style> +div { + position: absolute; +} +.filtered { + filter: url(#filter); +} +.child { + background-color: gray; + width: 50px; + height: 50px; + position: absolute; + will-change: transform; +} +.p1 { + left: 50px; + top: 50px; +} +.c1 { + transform: translate(0px, 25px); +} +.p2 { + left: 150px; + top: 50px; +} +.c2 { + transform: translate(0px, -25px); +} +</style> +<div class="filtered p1"><div class="child c1"></div></div> +<div class="filtered p2"><div class="child c2"></div></div>
diff --git a/third_party/WebKit/LayoutTests/editing/pasteboard/cut-paste-formatting-tag.html b/third_party/WebKit/LayoutTests/editing/pasteboard/cut-paste-formatting-tag.html new file mode 100644 index 0000000..b937e3b --- /dev/null +++ b/third_party/WebKit/LayoutTests/editing/pasteboard/cut-paste-formatting-tag.html
@@ -0,0 +1,16 @@ +<!doctype HTML> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="../assert_selection.js"></script> +<script> + +test(() => assert_selection( + '<div contenteditable style="width: 300px; height: 250px; border: 1px solid black"><div><b>^<br></b></div><b>foo|</b></div>', + selection => { + selection.document.execCommand('cut'); + selection.document.execCommand('paste'); + }, + '<div contenteditable style="width: 300px; height: 250px; border: 1px solid black"><br><div><b>foo|</b></div></div>'), + 'Cut all tags and paste them'); + +</script>
diff --git a/third_party/WebKit/LayoutTests/editing/spelling/grammar-paste-expected.txt b/third_party/WebKit/LayoutTests/editing/spelling/grammar-paste-expected.txt deleted file mode 100644 index f5d1a94d..0000000 --- a/third_party/WebKit/LayoutTests/editing/spelling/grammar-paste-expected.txt +++ /dev/null
@@ -1,27 +0,0 @@ -Grammar checking for pasted text. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS DIV ungrammatical phrase 'has' on 'You has the right.' -PASS verifyMarker(destination, ungrammaticalPhrase) became true -PASS DIV ungrammatical phrase 'a' on 'I have a<b>n ki</b>wi. I have no idea.' -PASS verifyMarker(destination, ungrammaticalPhrase) became true -PASS DIV ungrammatical phrase 'an,an' on 'I have an grape. I have an muscat. I don't know.' -PASS verifyMarker(destination, ungrammaticalPhrase) became true -PASS INPUT ungrammatical phrase 'has' on 'You has the right.' -PASS verifyMarker(destination, ungrammaticalPhrase) became true -PASS INPUT ungrammatical phrase 'an' on 'I have an kiwi. I have no idea.' -PASS verifyMarker(destination, ungrammaticalPhrase) became true -PASS INPUT ungrammatical phrase 'an,an' on 'I have an grape. I have an muscat. I don't know.' -PASS verifyMarker(destination, ungrammaticalPhrase) became true -PASS TEXTAREA ungrammatical phrase 'has' on 'You has the right.' -PASS verifyMarker(destination, ungrammaticalPhrase) became true -PASS TEXTAREA ungrammatical phrase 'an' on 'I have an kiwi. I have no idea.' -PASS verifyMarker(destination, ungrammaticalPhrase) became true -PASS TEXTAREA ungrammatical phrase 'an,an' on 'I have an grape. I have an muscat. I don't know.' -PASS verifyMarker(destination, ungrammaticalPhrase) became true -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/editing/spelling/grammar-paste.html b/third_party/WebKit/LayoutTests/editing/spelling/grammar-paste.html index 73f2f1a..7eb7acd 100644 --- a/third_party/WebKit/LayoutTests/editing/spelling/grammar-paste.html +++ b/third_party/WebKit/LayoutTests/editing/spelling/grammar-paste.html
@@ -1,55 +1,29 @@ -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> +<!doctype html> <html> <head> -<script src="../../resources/js-test.js"></script> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script src="resources/util.js"></script> </head> <body> -<p id="description"></p> -<div id="console"></div> +<div> +<textarea id="testTextArea"></textarea> +<input id="testInput" type="text"></input> +<div id="testEditable" contenteditable></div> +<div id="testSourcePlain">You has the right.</div> +<div id="testSourceDecorated">I have a<b>n ki</b>wi. I have no idea.</div> +<div id="testSourceMulti">I have an grape. I have an muscat. I don't know.</div> +</div> <script> -description('Grammar checking for pasted text.'); - -jsTestIsAsync = true; - -var testRoot = document.createElement("div"); -document.body.insertBefore(testRoot, document.body.firstChild); - -var testTextArea = document.createElement("textarea"); -testRoot.appendChild(testTextArea); - -var testInput = document.createElement("input"); -testInput.setAttribute("type", "text"); -testRoot.appendChild(testInput); - -var testEditable = document.createElement("div"); -testEditable.setAttribute("contentEditable", "true"); -testRoot.appendChild(testEditable); - -var testSourcePlain = document.createElement("div"); -testSourcePlain.innerHTML = "You has the right."; -testRoot.appendChild(testSourcePlain); - -var testSourceDecorated = document.createElement("div"); -testSourceDecorated.innerHTML = "I have a<b>n ki</b>wi. I have no idea."; -testRoot.appendChild(testSourceDecorated); - -var testSourceMulti = document.createElement("div"); -testSourceMulti.innerHTML = "I have an grape. I have an muscat. I don't know."; -testRoot.appendChild(testSourceMulti); +var testTextArea = document.getElementById('testTextArea'); +var testInput = document.getElementById('testInput'); +var testEditable = document.getElementById('testEditable'); +var testSourcePlain = document.getElementById('testSourcePlain'); +var testSourceDecorated = document.getElementById('testSourceDecorated'); +var testSourceMulti = document.getElementById('testSourceMulti'); var sel = window.getSelection(); -var tests = []; - -function done() -{ - var next = tests.shift(); - if (next) - return window.setTimeout(next, 0); - testRoot.style.display = "none"; - finishJSTest(); -} - function findFirstTextNode(node) { function iterToFindFirstTextNode(node) @@ -82,58 +56,58 @@ sel.selectAllChildren(node); var textNode = findFirstTextNode(node); - var num = internals.markerCountForNode(textNode, "grammar"); - if (num != expectedMarked.length) - return false; + var num = internals.markerCountForNode(textNode, 'grammar'); + assert_equals(num, expectedMarked.length); + for (var i = 0; i < num; ++i) { - var range = internals.markerRangeForNode(textNode, "grammar", i); - if (range.toString() != expectedMarked[i]) - return false; + var range = internals.markerRangeForNode(textNode, 'grammar', i); + assert_equals(range.toString(), expectedMarked[i]); } - - var nodeContent = node instanceof HTMLInputElement || node instanceof HTMLTextAreaElement ? node.value : node.innerHTML; - testPassed(node.tagName + " ungrammatical phrase '" + expectedMarked + "' on '" + nodeContent + "'"); - - return true; } -var destination = null; -var expectedMarked = null; -function pasteAndVerify(source, dest, expectedMarked) +function pasteText(source, dest) { sel.selectAllChildren(source); - document.execCommand("Copy"); + document.execCommand('Copy'); if (dest instanceof HTMLInputElement || dest instanceof HTMLTextAreaElement) { - dest.value = ""; + dest.value = ''; dest.focus(); } else { - dest.innerHTML = ""; + dest.innerHTML = ''; sel.selectAllChildren(dest); } - document.execCommand("Paste"); - - if (window.internals) { - destination = dest; - ungrammaticalPhrase = expectedMarked; - shouldBecomeEqual('verifyMarker(destination, ungrammaticalPhrase)', 'true', done); - } + document.execCommand('Paste'); }; -tests.push(function() { pasteAndVerify(testSourcePlain, testEditable, ["has"]); }); -tests.push(function() { pasteAndVerify(testSourceDecorated, testEditable, ["a"]); }); // Checks only 'a'. -tests.push(function() { pasteAndVerify(testSourceMulti, testEditable, ["an", "an"]); }); +var steps = [ + () => pasteText(testSourcePlain, testEditable), + () => pasteText(testSourceDecorated, testEditable), + () => pasteText(testSourceMulti, testEditable), -tests.push(function() { pasteAndVerify(testSourcePlain, testInput, ["has"]); }); -tests.push(function() { pasteAndVerify(testSourceDecorated, testInput, ["an"]); }); -tests.push(function() { pasteAndVerify(testSourceMulti, testInput, ["an", "an"]); }); + () => pasteText(testSourcePlain, testInput), + () => pasteText(testSourceDecorated, testInput), + () => pasteText(testSourceMulti, testInput), -tests.push(function() { pasteAndVerify(testSourcePlain, testTextArea, ["has"]); }); -tests.push(function() { pasteAndVerify(testSourceDecorated, testTextArea, ["an"]); }); -tests.push(function() { pasteAndVerify(testSourceMulti, testTextArea, ["an", "an"]); }); + () => pasteText(testSourcePlain, testTextArea), + () => pasteText(testSourceDecorated, testTextArea), + () => pasteText(testSourceMulti, testTextArea) +]; -done(); +var assertions = [ + () => verifyMarker(testEditable, ['has']), + () => verifyMarker(testEditable, ['a']), // Checks only 'a'. + () => verifyMarker(testEditable, ['an', 'an']), -var successfullyParsed = true; + () => verifyMarker(testInput, ['has']), + () => verifyMarker(testInput, ['an']), + () => verifyMarker(testInput, ['an', 'an']), + + () => verifyMarker(testTextArea, ['has']), + () => verifyMarker(testTextArea, ['an']), + () => verifyMarker(testTextArea, ['an', 'an']), +]; + +runSpellingTest(steps, assertions, 'Grammar checking for pasted text.'); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/rendering-contexts-back-references.html b/third_party/WebKit/LayoutTests/fast/canvas/rendering-contexts-back-references.html new file mode 100644 index 0000000..ae55184 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/canvas/rendering-contexts-back-references.html
@@ -0,0 +1,28 @@ +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> +function make_canvas(type) +{ + if (type == "html") + return document.createElement("canvas"); + return new OffscreenCanvas(10, 10); +} + +function test_back_ref(contextType, canvasType) +{ + var canvas = make_canvas(canvasType); + var ctx = canvas.getContext(contextType); + assert_equals(ctx.canvas, canvas, "Back reference to canvas should work."); + var anotherCanvas = make_canvas(canvasType); + ctx.canvas = anotherCanvas; + assert_not_equals(ctx.canvas, anotherCanvas, "Canvas attribute is read only."); +} + +generate_tests(test_back_ref, [ + ["2d context on html canvas", "2d", "html"], + ["webgl context on html canvas", "webgl", "html"], + ["bitmaprenderer context on html canvas", "bitmaprenderer", "html"], + ["2d context on offscreen canvas", "2d", "offscreen"], + ["webgl context on offscreen canvas", "webgl", "offscreen"], +]); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/invalidation/nth-pseudo.html b/third_party/WebKit/LayoutTests/fast/css/invalidation/nth-pseudo.html index bcf504a1..9cffe1b 100644 --- a/third_party/WebKit/LayoutTests/fast/css/invalidation/nth-pseudo.html +++ b/third_party/WebKit/LayoutTests/fast/css/invalidation/nth-pseudo.html
@@ -2,10 +2,13 @@ <script src="../../../resources/testharness.js"></script> <script src="../../../resources/testharnessreport.js"></script> <style> - #t1 > :nth-child(even) { + #t1 > span:nth-child(even) { background-color: green } - #t2 > :nth-last-child(even) { + #t2 > span:nth-last-child(even) { + background-color: green + } + #t3 > .second:nth-child(2) { background-color: green } </style> @@ -15,6 +18,12 @@ <div id="t2"> <span></span> </div> +<div id="t3"> + <div class="second"></div> + <div></div> + <div></div> + <div></div> +</div> <script> function backgroundIsGreen(element) { @@ -40,4 +49,13 @@ assert_equals(internals.updateStyleAndReturnAffectedElementCount(), 1); }, "Prepending an element sibling should not affect :nth-last-child of succeeding siblings."); + test(() => { + t3.offsetTop; + let second = t3.querySelector(".second"); + backgroundIsTransparent(second); + t3.insertBefore(document.createElement("div"), t3.firstChild); + assert_equals(internals.updateStyleAndReturnAffectedElementCount(), 2); + backgroundIsGreen(second); + }, "Prepending an element sibling should not affect :nth-last-child of succeeding siblings."); + </script>
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/span/padding-before-unbreakable-content-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/multicol/span/padding-before-unbreakable-content-crash-expected.txt new file mode 100644 index 0000000..9c314504 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/multicol/span/padding-before-unbreakable-content-crash-expected.txt
@@ -0,0 +1,3 @@ +PASS if no crash or assertion failure. + +
diff --git a/third_party/WebKit/LayoutTests/fast/multicol/span/padding-before-unbreakable-content-crash.html b/third_party/WebKit/LayoutTests/fast/multicol/span/padding-before-unbreakable-content-crash.html new file mode 100644 index 0000000..819160e --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/multicol/span/padding-before-unbreakable-content-crash.html
@@ -0,0 +1,14 @@ +<!DOCTYPE html> +<script> + if (window.testRunner) + testRunner.dumpAsText(); +</script> +<p>PASS if no crash or assertion failure.</p> +<div style="columns:2;"> + <div style="height:5px;"></div> + <div style="padding-top:10px;"> + <div style="height:20px; break-inside:avoid;"></div> + <div style="column-span:all;"></div> + <div style="height:2px; break-inside:avoid;"></div> + </div> +</div>
diff --git a/third_party/WebKit/LayoutTests/fast/parser/force-plaintext.html b/third_party/WebKit/LayoutTests/fast/parser/force-plaintext.html new file mode 100644 index 0000000..726abeb --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/parser/force-plaintext.html
@@ -0,0 +1,14 @@ +<!DOCTYPE html> +<p>plaintest test with postMessage</p> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> +var t = async_test("Do not parse plain text as HTML"); +window.addEventListener('message', function() { + assert_unreached("Child should not be executable"); +}); +var iframe = document.createElement('iframe'); +iframe.src = "data:text/plain,<script>parent.postMessage('Hello','" + location.origin+"');<\/script>"; +iframe.onload = () => t.done(); +document.body.appendChild(iframe); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/repaint/block-layout-inline-children-replaced-expected.html b/third_party/WebKit/LayoutTests/fast/repaint/block-layout-inline-children-replaced-expected.html index e82d176..44e08daf 100644 --- a/third_party/WebKit/LayoutTests/fast/repaint/block-layout-inline-children-replaced-expected.html +++ b/third_party/WebKit/LayoutTests/fast/repaint/block-layout-inline-children-replaced-expected.html
@@ -11,9 +11,9 @@ </head> <body style="margin: 0;"> - <p>This is a test for regression against <a href="https://bugs.webkit.org/show_bug.cgi?id=40142">https://bugs.webkit.org/show_bug.cgi?id=40142</a></p> + <p style="height: 100px">This is a test for regression against <a href="https://bugs.webkit.org/show_bug.cgi?id=40142">https://bugs.webkit.org/show_bug.cgi?id=40142</a></p> <div> - <div class="target" id="target"><img style="height: 100px;" src="resources/apple.jpg"></div> + <div class="target" id="target"><img style="width: 100px; height: 100px; background-color: green"></div> </div> </body>
diff --git a/third_party/WebKit/LayoutTests/fast/repaint/block-layout-inline-children-replaced-expected.txt b/third_party/WebKit/LayoutTests/fast/repaint/block-layout-inline-children-replaced-expected.txt new file mode 100644 index 0000000..630d1f1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/repaint/block-layout-inline-children-replaced-expected.txt
@@ -0,0 +1,39 @@ +{ + "name": "Content Root Layer", + "bounds": [800, 600], + "children": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "paintInvalidations": [ + { + "object": "LayoutBlockFlow DIV id='target' class='target'", + "rect": [0, 116, 402, 152], + "reason": "forced by layout" + }, + { + "object": "LayoutImage IMG", + "rect": [151, 117, 100, 100], + "reason": "layoutObject insertion" + } + ] + } + ], + "objectPaintInvalidations": [ + { + "object": "LayoutBlockFlow DIV id='target' class='target'", + "reason": "forced by layout" + }, + { + "object": "RootInlineBox", + "reason": "forced by layout" + }, + { + "object": "LayoutImage IMG", + "reason": "layoutObject insertion" + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/fast/repaint/block-layout-inline-children-replaced.html b/third_party/WebKit/LayoutTests/fast/repaint/block-layout-inline-children-replaced.html index 19da71ec..1fbb792 100644 --- a/third_party/WebKit/LayoutTests/fast/repaint/block-layout-inline-children-replaced.html +++ b/third_party/WebKit/LayoutTests/fast/repaint/block-layout-inline-children-replaced.html
@@ -13,19 +13,15 @@ <body style="margin: 0;" onload="runRepaintAndPixelTest()"> <script src="resources/text-based-repaint.js"></script> <script> - window.testIsAsync = true; - function repaintTest() { var target = document.getElementById("target"); - target.innerHTML += - '<img style="height: 100px;" src="resources/apple.jpg" >'; - target.firstChild.addEventListener("load", finishRepaintTest, false); + target.innerHTML += '<img style="width: 100px; height: 100px; background-color: green">'; } </script> - <p>This is a test for regression against <a href="https://bugs.webkit.org/show_bug.cgi?id=40142">https://bugs.webkit.org/show_bug.cgi?id=40142</a></p> + <p style="height: 100px">This is a test for regression against <a href="https://bugs.webkit.org/show_bug.cgi?id=40142">https://bugs.webkit.org/show_bug.cgi?id=40142</a></p> <div> <div class="target" id="target"></div>
diff --git a/third_party/WebKit/LayoutTests/fast/repaint/obscured-background-no-repaint-expected.txt b/third_party/WebKit/LayoutTests/fast/repaint/obscured-background-no-repaint-expected.txt index d560c3eb..df979e4 100644 --- a/third_party/WebKit/LayoutTests/fast/repaint/obscured-background-no-repaint-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/repaint/obscured-background-no-repaint-expected.txt
@@ -1,13 +1,4 @@ -{ - "name": "Content Root Layer", - "bounds": [785, 672], - "children": [ - { - "name": "LayoutView #document", - "bounds": [785, 672], - "contentsOpaque": true, - "drawsContent": true - } - ] -} + + +PASS
diff --git a/third_party/WebKit/LayoutTests/fast/repaint/obscured-background-no-repaint.html b/third_party/WebKit/LayoutTests/fast/repaint/obscured-background-no-repaint.html index c3157a5..3a9ad4f6 100644 --- a/third_party/WebKit/LayoutTests/fast/repaint/obscured-background-no-repaint.html +++ b/third_party/WebKit/LayoutTests/fast/repaint/obscured-background-no-repaint.html
@@ -1,7 +1,5 @@ <html> <head> -<script src="../../resources/run-after-layout-and-paint.js"></script> -<script src="resources/text-based-repaint.js"></script> <style type="text/css"> #test1 div { height: 100px; @@ -46,42 +44,82 @@ </style> <script> // Test that obscured animated gif does not trigger repaints. - if (window.testRunner) + if (window.testRunner) { testRunner.waitUntilDone(); - window.testIsAsync = true; - function repaintTest() - { - runAfterLayoutAndPaint(finishRepaintTest); + testRunner.dumpAsText(); + } + + if (window.internals) { + internals.settings.setUseDefaultImageInterpolationQuality(true); + internals.runtimeFlags.slimmingPaintUnderInvalidationCheckingEnabled = true; + } + + function finish() { + var layerTree = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_PAINT_INVALIDATIONS); + var invalidations = JSON.parse(layerTree).objectPaintInvalidations; + // Passes if there is no invalidations other than imgForAdvanceImageAnimation, + // or only invalidations because of background obscuration change. + // This is because before the delayed image decoder finishes decoding the image, + // we first assume the image is not opaque. If the image is found actually opaque + // after decoding, the background obscuration status of covered elements will + // change and cause paint invalidation. + var invalidatedObjects = {}; + if (invalidations) { + for (var i = 0; i < invalidations.length; ++i) { + var object = invalidations[i].object; + if (object.indexOf('imgForAdvanceImageAnimation') != -1) + continue; + if ((object.indexOf('target3') != -1 || object.indexOf('target4') != -1) && invalidations[i].reason == 'background obscuration change') + continue; + invalidatedObjects[object] = true; + } + } + + if (Object.keys(invalidatedObjects).length) + output.textContent = 'FAIL: Unexpected paint invalidations: ' + JSON.stringify(invalidatedObjects) + '\n' + layerTree; + else + output.textContent = 'PASS'; + testRunner.notifyDone(); } function start() { if (!window.testRunner || !window.internals) return; - var img = new Image(); - img.onload = runRepaintTest; - img.src = "resources/animated.gif"; + // Ensure the deferred decoder has decoded resources/apple.jpg. + testRunner.capturePixelsAsyncThen(function() { + internals.startTrackingRepaints(document); + internals.advanceImageAnimation(imgForAdvanceImageAnimation); + testRunner.layoutAndPaintAsyncThen(function() { + internals.advanceImageAnimation(imgForAdvanceImageAnimation); + testRunner.layoutAndPaintAsyncThen(function() { + internals.advanceImageAnimation(imgForAdvanceImageAnimation); + testRunner.layoutAndPaintAsyncThen(finish); + }); + }); + }); } + </script> </head> <body onload="start()"> <div id="test1"> - <div class="parent"> + <div id="target1" class="parent"> <div class="child"> </div> </div> </div> <div id="test2"> - <div class="parent"> + <div id="target2" class="parent"> <div class="child"> </div> </div> </div> <div id="test3"> - <img src="resources/apple.jpg"> + <img id="target3" src="resources/apple.jpg"> </div> <div id="test4"> - <div class="parent"> + <div id="target4" class="parent"> <a> <div></div> <div> @@ -90,5 +128,7 @@ </a> </div> </div> +<img id="imgForAdvanceImageAnimation" src="resources/animated.gif"> +<pre id="output"></pre> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-insert-svg-shape-expected.html b/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-insert-svg-shape-expected.html index 81cd473..d12051f 100644 --- a/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-insert-svg-shape-expected.html +++ b/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-insert-svg-shape-expected.html
@@ -1,5 +1,6 @@ <html> <head> +<script src="../../../resources/ahem.js"></script> <style> .container { font: 50px/1 Ahem, sans-serif;
diff --git a/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-insert-svg-shape.html b/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-insert-svg-shape.html index 3f897dab..00c6c0a0 100644 --- a/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-insert-svg-shape.html +++ b/third_party/WebKit/LayoutTests/fast/shapes/shape-outside-floats/shape-outside-insert-svg-shape.html
@@ -1,6 +1,7 @@ <html> <head> <script src="../../../resources/ahem.js"></script> +<script src="../../../resources/run-after-layout-and-paint.js"></script> <style> .container { font: 50px/1 Ahem, sans-serif; @@ -16,10 +17,12 @@ </style> <script> window.onload = function() { + runAfterLayoutAndPaint(function() { var container = document.querySelector('.container'); var shape = document.createElement('div'); shape.className = 'shape-outside'; container.insertBefore(shape, container.firstChild); + }, true); } </script> </head>
diff --git a/third_party/WebKit/LayoutTests/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition.html b/third_party/WebKit/LayoutTests/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition.html new file mode 100644 index 0000000..4ab8e10 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<meta charset='utf-8'> +<style> +div { + width: 125px; + height: 20px; + font: 12px; + overflow: hidden; + white-space: pre; + text-overflow: ellipsis; + direction: ltr; +} +</style> +<p>crbug.com/636060: Ltr text in a ltr flow should truncate the text left-to-right and underline correctly in composition mode.</p> +<p>You should see an underline beneath the text.</p> +<div id="textarea" contenteditable="true"></div> +<script> +if (window.testRunner) { + var textarea = document.getElementById("textarea"); + textarea.focus(); + textInputController.setComposition("abcdefghijklmnopqrstuv"); +} +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition.html b/third_party/WebKit/LayoutTests/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition.html new file mode 100644 index 0000000..efe74c8d --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<meta charset='utf-8'> +<style> +div { + width: 125px; + height: 20px; + font: 12px; + overflow: hidden; + white-space: pre; + text-overflow: ellipsis; + direction: rtl; +} +</style> +<p>crbug.com/636060: Ltr text in a rtl flow should truncate the text left-to-right and underline correctly in composition mode.</p> +<p>You should see an underline beneath the text.</p> +<div id="textarea" contenteditable="true"></div> +<script> +if (window.testRunner) { + var textarea = document.getElementById("textarea"); + textarea.focus(); + textInputController.setComposition("abcdefghijklmnopqrstuv"); +} +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition.html b/third_party/WebKit/LayoutTests/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition.html new file mode 100644 index 0000000..c490f2c --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<meta charset='utf-8'> +<style> +div { + width: 125px; + height: 20px; + font: 12px; + overflow: hidden; + white-space: pre; + text-overflow: ellipsis; + direction: ltr; +} +</style> +<p>crbug.com/636060: rtl text in a ltr flow should truncate the text left-to-right and underline correctly in composition mode.</p> +<p>You should see an underline beneath the text.</p> +<div id="textarea" contenteditable="true"></div> +<script> +if (window.testRunner) { + var textarea = document.getElementById("textarea"); + textarea.focus(); + textInputController.setComposition("אבגדהוזחטיכךלמםסעפףצץקרשת<"); +} +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition.html b/third_party/WebKit/LayoutTests/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition.html new file mode 100644 index 0000000..c550d52 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<meta charset='utf-8'> +<style> +div { + width: 125px; + height: 20px; + font: 12px; + overflow: hidden; + white-space: pre; + text-overflow: ellipsis; + direction: rtl; +} +</style> +<p>crbug.com/636060: rtl text in a rtl flow should truncate the text left-to-right and underline correctly in composition mode.</p> +<p>You should see an underline beneath the text.</p> +<div id="textarea" contenteditable="true"></div> +<script> +if (window.testRunner) { + var textarea = document.getElementById("textarea"); + textarea.focus(); + textInputController.setComposition("אבגדהוזחטיכךלמםסעפףצץקרשת<"); +} +</script>
diff --git a/third_party/WebKit/LayoutTests/fragmentation/repeating-thead-multiple-tables-page-border-expected.html b/third_party/WebKit/LayoutTests/fragmentation/repeating-thead-multiple-tables-page-border-expected.html new file mode 100644 index 0000000..43277c1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fragmentation/repeating-thead-multiple-tables-page-border-expected.html
@@ -0,0 +1,39 @@ +<!DOCTYPE html> +<style> +table { + border-collapse: collapse; +} +tr { + break-inside: avoid; +} +</style> +<p>crbug.com/621258: Don't let repeating headers overlap on pages that contain two tables.</p> +<div style="-webkit-columns:3; line-height: 20px; column-fill: auto; height:190px;"> + <table> + <tr> + <th colspan="2"><div>Col 1</div></th> + </tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr> + <th colspan="2"><div>Col 2</div></th> + </tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr> + <th colspan="2"><div>Col 2</div></th> + </tr> + <tr><td>Te</td><td>xt</td></tr> + </table> +</div> +
diff --git a/third_party/WebKit/LayoutTests/fragmentation/repeating-thead-multiple-tables-page-border.html b/third_party/WebKit/LayoutTests/fragmentation/repeating-thead-multiple-tables-page-border.html new file mode 100644 index 0000000..06b651f --- /dev/null +++ b/third_party/WebKit/LayoutTests/fragmentation/repeating-thead-multiple-tables-page-border.html
@@ -0,0 +1,42 @@ +<!DOCTYPE html> +<style> +table { + border-collapse: collapse; +} +thead, tr { + break-inside: avoid; +} +</style> +<p>crbug.com/621258: Don't let repeating headers overlap on pages that contain two tables.</p> +<div style="-webkit-columns:3; line-height: 20px; column-fill: auto; height:190px;"> + <table> + <thead> + <tr> + <th colspan="2"><div>Col 1</div></th> + </tr> + </thead> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + </table> + <table> + <thead> + <tr> + <th colspan="2">Col 2</th> + </tr> + </thead> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + </table> +</div> +
diff --git a/third_party/WebKit/LayoutTests/fragmentation/single-cells-multiple-tables-no-repeating-thead-expected.txt b/third_party/WebKit/LayoutTests/fragmentation/single-cells-multiple-tables-no-repeating-thead-expected.txt new file mode 100644 index 0000000..6e3ca12 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fragmentation/single-cells-multiple-tables-no-repeating-thead-expected.txt
@@ -0,0 +1,20 @@ +crbug.com/621258: Don't let repeating headers overlap on pages that contain two tables. + +Col 1 +Te xt +Te xt +Te xt +Te xt +Te xt +Te xt +Te xt +Col 2 +Te xt +Te xt +Te xt +Te xt +Te xt +Te xt +Te xt +Te xt +PASS
diff --git a/third_party/WebKit/LayoutTests/fragmentation/single-cells-multiple-tables-no-repeating-thead.html b/third_party/WebKit/LayoutTests/fragmentation/single-cells-multiple-tables-no-repeating-thead.html new file mode 100644 index 0000000..1adda7f0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fragmentation/single-cells-multiple-tables-no-repeating-thead.html
@@ -0,0 +1,47 @@ +<!DOCTYPE html> +<style> +table { + border-collapse: collapse; +} +tr { + break-inside: avoid; +} +</style> +<p>crbug.com/621258: Don't let repeating headers overlap on pages that contain two tables.</p> +<div style="-webkit-columns:3; line-height: 20px; column-fill: auto; height:190px;"> + <table> + <thead> + <tr> + <th colspan="2"><div>Col 1</div></th> + </tr> + </thead> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + </table> + <table> + <thead> + <tr> + <th colspan="2">Col 2</th> + </tr> + </thead> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td>Te</td><td>xt</td></tr> + <tr><td id="cell" data-total-y=204>Te</td><td>xt</td></tr> + </table> +</div> +<div id="console"></div> +<script src="../resources/check-layout.js"></script> +<script> +checkLayout("#cell", document.getElementById("console")); +</script> +
diff --git a/third_party/WebKit/LayoutTests/http/tests/budget/interfaces.html b/third_party/WebKit/LayoutTests/http/tests/budget/interfaces.html index 2dc5fa6..b1489a7 100644 --- a/third_party/WebKit/LayoutTests/http/tests/budget/interfaces.html +++ b/third_party/WebKit/LayoutTests/http/tests/budget/interfaces.html
@@ -9,8 +9,8 @@ <script> promise_test(function() { assert_own_property(Navigator.prototype, 'budget'); - assert_own_property(Budget.prototype, 'getCost'); - assert_own_property(Budget.prototype, 'getBudget'); + assert_own_property(BudgetService.prototype, 'getCost'); + assert_own_property(BudgetService.prototype, 'getBudget'); assert_equals(navigator.budget, navigator.budget); navigator.budget.getCost()
diff --git a/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-storage-match.js b/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-storage-match.js index 21517b1e..6bc30fb 100644 --- a/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-storage-match.js +++ b/third_party/WebKit/LayoutTests/http/tests/cachestorage/script-tests/cache-storage-match.js
@@ -133,4 +133,36 @@ }); }, 'CacheStorageMatch with no caches available but name provided'); +cache_test(function(cache) { + var transaction = create_unique_transaction(); + + return self.caches.delete('') + .then(function() { + return self.caches.has(''); + }) + .then(function(has_cache) { + assert_false(has_cache, "The cache should not exist."); + return cache.put(transaction.request, transaction.response.clone()); + }) + .then(function() { + return self.caches.match(transaction.request, {cacheName: ''}); + }) + .then(function(response) { + assert_equals(response, undefined, + 'The response should not be found.'); + return self.caches.open(''); + }) + .then(function(cache) { + return cache.put(transaction.request, transaction.response); + }) + .then(function() { + return self.caches.match(transaction.request, {cacheName: ''}); + }) + .then(function(response) { + assert_response_equals(response, transaction.response, + 'The response should be matched.'); + return self.caches.delete(''); + }); +}, 'CacheStorageMatch with empty cache name provided'); + done();
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/injected-script-discard.html b/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/injected-script-discard.html index 8fe5ce8e..9bc9b980 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/injected-script-discard.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/injected-script-discard.html
@@ -27,7 +27,7 @@ { InspectorTest.RuntimeAgent.evaluate("window.objectId", dispatch); - function dispatch(error, result, wasThrown) + function dispatch(error, result, exceptionDetails) { if (result.type !== "string") { InspectorTest.evaluateInPage("console.log('Opening front-end for the first time')"); @@ -42,7 +42,7 @@ { InspectorTest.RuntimeAgent.evaluate("({ handle : \"handle\" })", storeIdInTargetWindow); - function storeIdInTargetWindow(error, result, wasThrown) + function storeIdInTargetWindow(error, result, exceptionDetails) { checkHandleInInjectedScript(result.objectId, reopenInspector);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/reattach-after-editing-styles.html b/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/reattach-after-editing-styles.html index 9cf07ca..b844dba 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/reattach-after-editing-styles.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/reattach-after-editing-styles.html
@@ -34,7 +34,7 @@ { InspectorTest.RuntimeAgent.evaluate("window.didReopen", dispatch); - function dispatch(error, result, wasThrown) + function dispatch(error, result, exceptionDetails) { if (result.type !== "number") { InspectorTest.addResult("Opening front-end for the first time");
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/shadow-dom-rules-restart.html b/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/shadow-dom-rules-restart.html index 4b3ee1d8..e10a6951 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/shadow-dom-rules-restart.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-enabled/shadow-dom-rules-restart.html
@@ -31,7 +31,7 @@ { InspectorTest.RuntimeAgent.evaluate("window.didReopen", dispatch); - function dispatch(error, result, wasThrown) + function dispatch(error, result, exceptionDetails) { if (result.type !== "number") { InspectorTest.evaluateInPage("console.log('Opening front-end for the first time')"); @@ -50,7 +50,7 @@ function runTests(callback) { InspectorTest.selectNodeAndWaitForStyles("inner", step2); - + function step2() { InspectorTest.dumpSelectedElementStyles(true);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/access-inspected-object.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/access-inspected-object.html index 6b54d769..d8b1d71 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/access-inspected-object.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/access-inspected-object.html
@@ -57,7 +57,7 @@ function didEvaluate(messageObject) { - if (messageObject.result.wasThrown) + if (!!messageObject.result.exceptionDetails) InspectorTest.log("FAIL: unexpected exception: " + JSON.stringify(messageObject, null, 2)); if (messageObject.result.result.value !== null) InspectorTest.log("FAIL: unexpected value: " + JSON.stringify(messageObject, null, 2));
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/protocol-test.html b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/protocol-test.html index fc3cbd3a..1d6088d 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/protocol-test.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/resources/protocol-test.html
@@ -83,6 +83,17 @@ return promise; } +InspectorTest.waitForEventPromise = function(eventName) +{ + return new Promise(fulfill => InspectorTest.eventHandler[eventName] = fullfillAndClearListener.bind(null, fulfill)); + + function fullfillAndClearListener(fulfill, result) + { + fulfill(result); + delete InspectorTest.eventHandler[eventName]; + } +} + InspectorTest.domUndo = function(callback) { InspectorTest.sendCommandOrDie("DOM.undo", {}, callback); @@ -285,7 +296,7 @@ InspectorTest.evaluateInPageAsync = function(expression) { - return InspectorTest.sendCommandPromise("Runtime.evaluate", { "expression": expression, awaitPromise: true }).then((message) => message.result.result.value); + return InspectorTest.sendCommandPromise("Runtime.evaluate", { "expression": expression, awaitPromise: true, returnByValue: true }).then((message) => message.result.result.value); } InspectorTest.completeTestIfError = function(messageObject)
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/tracing-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/tracing-test.js index 230a012..7524497 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/tracing-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/tracing-test.js
@@ -126,43 +126,8 @@ function onStart() { - InspectorTest.invokePageFunctionAsync(functionName, done); + InspectorTest.evaluateInPageAsync(functionName + "()").then((data) => InspectorTest.stopTracing((devtoolsEvents) => callback(devtoolsEvents, data))); } - - function done() - { - InspectorTest.stopTracing(callback); - } -} - -InspectorTest._lastEvalId = 0; -InspectorTest._pendingEvalRequests = {}; - -InspectorTest.invokePageFunctionAsync = function(functionName, callback) -{ - var id = ++InspectorTest._lastEvalId; - InspectorTest._pendingEvalRequests[id] = callback; - var asyncEvalWrapper = function(callId, functionName) - { - function evalCallback(result) - { - evaluateInFrontend("InspectorTest.didInvokePageFunctionAsync(" + callId + ", " + JSON.stringify(result) + ");"); - } - eval(functionName + "(" + evalCallback + ")"); - } - InspectorTest.evaluateInPage("(" + asyncEvalWrapper.toString() + ")(" + id + ", unescape('" + escape(functionName) + "'))", function() { }); -} - -InspectorTest.didInvokePageFunctionAsync = function(callId, value) -{ - var callback = InspectorTest._pendingEvalRequests[callId]; - - if (!callback) { - InspectorTest.addResult("Missing callback for async eval " + callId + ", perhaps callback invoked twice?"); - return; - } - delete InspectorTest._pendingEvalRequests[callId]; - callback(value); } }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/console-fetch-logging-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/console-fetch-logging-expected.txt index a45e940..950b974 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/console-fetch-logging-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/console-fetch-logging-expected.txt
@@ -11,17 +11,17 @@ Tests that fetch logging works when XMLHttpRequest Logging is Enabled and doesn't show logs when it is Disabled. console-fetch-logging.html:4 sending a GET request to resources/xhr-exists.html -network-test.js:48 Fetch complete: GET "http://127.0.0.1:8000/inspector/resources/xhr-exists.html".makeFetch @ network-test.js:48requestHelper @ console-fetch-logging.html:11step1 @ console-fetch-logging.html:21makeRequests @ console-fetch-logging.html:16(anonymous function) @ VM:1(anonymous function) @ VM:11(anonymous function) @ VM:16 +network-test.js:48 Fetch complete: GET "http://127.0.0.1:8000/inspector/resources/xhr-exists.html".makeFetch @ network-test.js:48requestHelper @ console-fetch-logging.html:11step1 @ console-fetch-logging.html:24makeRequests @ console-fetch-logging.html:18(anonymous function) @ VM:1 console-fetch-logging.html:4 sending a GET request to resources/xhr-does-not-exist.html -network-test.js:48 GET http://127.0.0.1:8000/inspector/resources/xhr-does-not-exist.html 404 (Not Found)makeFetch @ network-test.js:48requestHelper @ console-fetch-logging.html:11step2 @ console-fetch-logging.html:27 -network-test.js:48 Fetch complete: GET "http://127.0.0.1:8000/inspector/resources/xhr-does-not-exist.html".makeFetch @ network-test.js:48requestHelper @ console-fetch-logging.html:11step2 @ console-fetch-logging.html:27 +network-test.js:48 GET http://127.0.0.1:8000/inspector/resources/xhr-does-not-exist.html 404 (Not Found)makeFetch @ network-test.js:48requestHelper @ console-fetch-logging.html:11step2 @ console-fetch-logging.html:30 +network-test.js:48 Fetch complete: GET "http://127.0.0.1:8000/inspector/resources/xhr-does-not-exist.html".makeFetch @ network-test.js:48requestHelper @ console-fetch-logging.html:11step2 @ console-fetch-logging.html:30 console-fetch-logging.html:4 sending a POST request to resources/post-target.cgi -network-test.js:48 Fetch complete: POST "http://127.0.0.1:8000/inspector/resources/post-target.cgi".makeFetch @ network-test.js:48requestHelper @ console-fetch-logging.html:11step3 @ console-fetch-logging.html:33 +network-test.js:48 Fetch complete: POST "http://127.0.0.1:8000/inspector/resources/post-target.cgi".makeFetch @ network-test.js:48requestHelper @ console-fetch-logging.html:11step3 @ console-fetch-logging.html:36 console-fetch-logging.html:4 sending a GET request to http://localhost:8000/inspector/resources/xhr-exists.html console-fetch-logging.html:1 Fetch API cannot load http://localhost:8000/inspector/resources/xhr-exists.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. console-fetch-logging.html:4 sending a GET request to resources/xhr-exists.html console-fetch-logging.html:4 sending a GET request to resources/xhr-does-not-exist.html -network-test.js:48 GET http://127.0.0.1:8000/inspector/resources/xhr-does-not-exist.html 404 (Not Found)makeFetch @ network-test.js:48requestHelper @ console-fetch-logging.html:11step2 @ console-fetch-logging.html:27 +network-test.js:48 GET http://127.0.0.1:8000/inspector/resources/xhr-does-not-exist.html 404 (Not Found)makeFetch @ network-test.js:48requestHelper @ console-fetch-logging.html:11step2 @ console-fetch-logging.html:30 console-fetch-logging.html:4 sending a POST request to resources/post-target.cgi console-fetch-logging.html:4 sending a GET request to http://localhost:8000/inspector/resources/xhr-exists.html console-fetch-logging.html:1 Fetch API cannot load http://localhost:8000/inspector/resources/xhr-exists.html. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8000' is therefore not allowed access. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/console-fetch-logging.html b/third_party/WebKit/LayoutTests/http/tests/inspector/console-fetch-logging.html index 5be77c4..6ec9885 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/console-fetch-logging.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/console-fetch-logging.html
@@ -13,12 +13,15 @@ { setTimeout(callback, 0); } - makeFetch(url, {method: method}, delayCallback); + makeFetch(url, {method: method}).then(delayCallback); } -function makeRequests(callback) +function makeRequests() { + var callback; + var promise = new Promise((fulfill) => callback = fulfill); step1(); + return promise; function step1() { @@ -53,7 +56,7 @@ { function callback() { - InspectorTest.invokePageFunctionAsync("makeRequests", step2); + InspectorTest.callFunctionInPageAsync("makeRequests").then(step2); } InspectorTest.NetworkAgent.setMonitoringXHREnabled(true, callback); } @@ -62,7 +65,7 @@ { function callback() { - InspectorTest.invokePageFunctionAsync("makeRequests", step3); + InspectorTest.callFunctionInPageAsync("makeRequests").then(step3); } InspectorTest.NetworkAgent.setMonitoringXHREnabled(false, callback); }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/debugger-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/debugger-test.js index bc9ecc7..5a8a109 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/debugger-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/debugger-test.js
@@ -529,7 +529,7 @@ var endLine = startLine + lineCount - 1; var endColumn = lineCount === 1 ? startColumn + source.length : source.length - source.computeLineEndings()[lineCount - 2]; var hasSourceURL = !!source.match(/\/\/#\ssourceURL=\s*(\S*?)\s*$/m) || !!source.match(/\/\/@\ssourceURL=\s*(\S*?)\s*$/m); - var script = new WebInspector.Script(debuggerModel, scriptId, url, startLine, startColumn, endLine, endColumn, 0, "", isContentScript, false, false, undefined, hasSourceURL); + var script = new WebInspector.Script(debuggerModel, scriptId, url, startLine, startColumn, endLine, endColumn, 0, "", isContentScript, false, undefined, hasSourceURL); script.requestContent = function() { var trimmedSource = WebInspector.Script._trimSourceURLComment(source);
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/debugger/fetch-breakpoints.html b/third_party/WebKit/LayoutTests/http/tests/inspector/debugger/fetch-breakpoints.html index 689d3d1d..a9ce3eb5 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/debugger/fetch-breakpoints.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/debugger/fetch-breakpoints.html
@@ -11,7 +11,7 @@ function test() { - var pane = WebInspector.panels.sources.sidebarPanes.xhrBreakpoints; + var pane = self.runtime.sharedInstance(WebInspector.XHRBreakpointsSidebarPane); InspectorTest.runDebuggerTestSuite([ function testFetchBreakpoint(next) {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/event-listeners-framework-with-service-worker.html b/third_party/WebKit/LayoutTests/http/tests/inspector/elements/event-listeners-framework-with-service-worker.html index dfd8bf9..6a2d349 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/elements/event-listeners-framework-with-service-worker.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/elements/event-listeners-framework-with-service-worker.html
@@ -14,7 +14,7 @@ InspectorTest.waitForServiceWorker(step1); InspectorTest.registerServiceWorker(scriptURL, scope); - var objectEventListenersPane = WebInspector.panels.sources.sidebarPanes.objectEventListeners; + var objectEventListenersPane = self.runtime.sharedInstance(WebInspector.ObjectEventListenersSidebarPane); function isDedicatedWorker() { @@ -33,7 +33,7 @@ InspectorTest.selectThread(executionContext.target()); InspectorTest.addResult("Context is dedicated worker: " + isDedicatedWorker()); InspectorTest.addResult("Dumping listeners"); - objectEventListenersPane.revealView().then(() => { + WebInspector.viewManager.showView("sources.globalListeners").then(() => { objectEventListenersPane.update(); InspectorTest.expandAndDumpEventListeners(objectEventListenersPane._eventListenersView, step3); });
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js index c734b2d..760cf80 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js
@@ -43,10 +43,10 @@ { callback = InspectorTest.safeWrap(callback); - function mycallback(error, result, wasThrown) + function mycallback(error, result, exceptionDetails) { if (!error) - callback(InspectorTest.runtimeModel.createRemoteObject(result), wasThrown); + callback(InspectorTest.runtimeModel.createRemoteObject(result), exceptionDetails); } InspectorTest.RuntimeAgent.evaluate(code, "console", false, mycallback); } @@ -71,9 +71,9 @@ /* awaitPromise */ true, mycallback); - function mycallback(error, result, wasThrown, exceptionDetails) + function mycallback(error, result, exceptionDetails) { - if (!error && !wasThrown) { + if (!error && !exceptionDetails) { callback(InspectorTest.runtimeModel.createRemoteObject(result)); } else { if (error) @@ -104,62 +104,12 @@ var mainContext = InspectorTest.runtimeModel.executionContexts()[0]; mainContext.evaluate(expression, "", false, false, true, false, false, wrapCallback); - function wrapCallback(val, err, result) + function wrapCallback(result, exceptionDetails) { callback(result.value) } } -InspectorTest.waitForOverlayRepaint = function(callback) -{ - InspectorTest.invokePageFunctionAsync("requestAnimationFrame", callback); -} - -var lastEvalId = 0; -var pendingEvalRequests = {}; - -/** - * @param {string} functionName - * @param {...} varArgs - * @param {function()} callback - */ -InspectorTest.invokePageFunctionAsync = function(functionName, varArgs) -{ - var id = ++lastEvalId; - var args = Array.prototype.slice.call(arguments, 1); - var callback = args.pop(); - pendingEvalRequests[id] = InspectorTest.safeWrap(callback); - var asyncEvalWrapper = function(callId, functionName, argsString) - { - function evalCallback(result) - { - testRunner.evaluateInWebInspector(evalCallbackCallId, "InspectorTest.didInvokePageFunctionAsync(" + callId + ", " + JSON.stringify(result) + ");"); - } - var argsArray = argsString.replace(/^\[(.*)\]$/, "$1"); - if (argsArray.length) - argsArray += ","; - try { - eval(functionName + "(" + argsArray + evalCallback + ")"); - } catch(e) { - InspectorTest.addResult("Error: " + e); - evalCallback(String(e)); - } - } - var escapedJSONArgs = JSON.stringify(JSON.stringify(args)); - InspectorTest.evaluateInPage("(" + asyncEvalWrapper.toString() + ")(" + id + ", unescape('" + escape(functionName) + "')," + escapedJSONArgs + ")"); -} - -InspectorTest.didInvokePageFunctionAsync = function(callId, value) -{ - var callback = pendingEvalRequests[callId]; - if (!callback) { - InspectorTest.addResult("Missing callback for async eval " + callId + ", perhaps callback invoked twice?"); - return; - } - delete pendingEvalRequests[callId]; - callback(value); -} - InspectorTest.check = function(passCondition, failureText) { if (!passCondition)
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/network-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/network-test.js index 3025527b..92d9867 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/network-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/network-test.js
@@ -43,9 +43,9 @@ makeXHR(args.method, args.url, args.async, args.user, args.password, args.headers || [], args.withCredentials, args.payload, args.type, xhrLoadedCallback); } -function makeFetch(url, requestInitializer, callback) +function makeFetch(url, requestInitializer) { - fetch(url, requestInitializer).then(callback).catch(callback); + return fetch(url, requestInitializer).catch(e => e); } var initialize_NetworkTest = function() { @@ -117,7 +117,7 @@ InspectorTest.makeFetch = function(url, requestInitializer, callback) { - InspectorTest.invokePageFunctionAsync("makeFetch", url, requestInitializer, callback); + InspectorTest.callFunctionInPageAsync("makeFetch", [url, requestInitializer]).then(callback); } InspectorTest.HARPropertyFormatters = {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-eventsource.html b/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-eventsource.html index 4851bfc..7bd39fe 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-eventsource.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/network/network-eventsource.html
@@ -4,11 +4,14 @@ <script src="../network-test.js"></script> <script> -function receiveEvent(callback) +function receiveEvent() { + var callback; + var promise = new Promise((fulfill) => callback = fulfill); var es = new EventSource("resources/event-stream.asis"); es.onmessage = onMessage; es.onerror = onError; + return promise; function onMessage(data) { output("got event: " + event.data); @@ -24,7 +27,7 @@ function test() { InspectorTest.recordNetwork(); - InspectorTest.invokePageFunctionAsync("receiveEvent", step2); + InspectorTest.callFunctionInPageAsync("receiveEvent").then(step2); function step2() {
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resources-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/resources-test.js index 8e42afc..d0f86621 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/resources-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/resources-test.js
@@ -18,22 +18,22 @@ InspectorTest.runAfterResourcesAreFinished = function(resourceURLs, callback) { - var resourceURLsMap = resourceURLs.keySet(); + var resourceURLsMap = new Set(resourceURLs); function checkResources() { - for (url in resourceURLsMap) { + for (var url of resourceURLsMap) { var resource = InspectorTest.resourceMatchingURL(url); if (resource) - delete resourceURLsMap[url]; + resourceURLsMap.delete(url); } - if (!Object.keys(resourceURLsMap).length) { + if (!resourceURLsMap.size) { InspectorTest.resourceTreeModel.removeEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, checkResources); callback(); } } checkResources(); - if (Object.keys(resourceURLsMap).length) + if (resourceURLsMap.size) InspectorTest.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, checkResources); }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/resources/extension-main.js b/third_party/WebKit/LayoutTests/http/tests/inspector/resources/extension-main.js index 5bd6c2e..63c40089 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/resources/extension-main.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/resources/extension-main.js
@@ -16,7 +16,7 @@ for (var property in object) propertyNames.push(property); propertyNames.sort(); - + for (var i = 0; i < propertyNames.length; ++i) { var prop = propertyNames[i]; var prefixWithName = prefix + " " + prop + " : "; @@ -52,7 +52,7 @@ function invokePageFunctionAsync(functionName, callback) { - evaluateOnFrontend("InspectorTest.invokePageFunctionAsync('" + functionName + "', reply)", callback); + evaluateOnFrontend("InspectorTest.callFunctionInPageAsync('" + functionName + "').then(() => reply())", callback); } function output(message)
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-search.html b/third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-search.html index c7c5e367..da5a509a 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-search.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/search/source-frame-search.html
@@ -7,7 +7,7 @@ <script> function test() { - function dumpSearchResultsForConfig(sourceFrame, searchConfig, callback) + function dumpSearchResultsForConfig(sourceFrame, searchConfig) { var modifiers = []; if (searchConfig.isRegex) @@ -17,21 +17,17 @@ var modifiersString = modifiers.length ? " (" + modifiers.join(", ") + ")" : ""; InspectorTest.addResult("Running search test for query = " + searchConfig.query + modifiersString + ":"); - sourceFrame.performSearch(searchConfig, false, false, innerCallback); + sourceFrame.performSearch(searchConfig, false, false); - function innerCallback() - { - var searchResults = sourceFrame._searchResults; - for (var i = 0; i < searchResults.length; ++i) { - var range = searchResults[i]; - var prefixRange = new WebInspector.TextRange(range.startLine, 0, range.startLine, range.startColumn); - var postfixRange = new WebInspector.TextRange(range.endLine, range.endColumn, range.endLine, sourceFrame._textEditor.line(range.endLine).length); - var prefix = sourceFrame._textEditor.copyRange(prefixRange); - var result = sourceFrame._textEditor.copyRange(range); - var postfix = sourceFrame._textEditor.copyRange(postfixRange); - InspectorTest.addResult(" - " + prefix + "<" + result + ">" + postfix); - } - callback(); + var searchResults = sourceFrame._searchResults; + for (var i = 0; i < searchResults.length; ++i) { + var range = searchResults[i]; + var prefixRange = new WebInspector.TextRange(range.startLine, 0, range.startLine, range.startColumn); + var postfixRange = new WebInspector.TextRange(range.endLine, range.endColumn, range.endLine, sourceFrame._textEditor.line(range.endLine).length); + var prefix = sourceFrame._textEditor.copyRange(prefixRange); + var result = sourceFrame._textEditor.copyRange(range); + var postfix = sourceFrame._textEditor.copyRange(postfixRange); + InspectorTest.addResult(" - " + prefix + "<" + result + ">" + postfix); } } @@ -45,35 +41,40 @@ { var query = "searchTestUniqueString"; var searchConfig = new WebInspector.SearchableView.SearchConfig(query, false, false); - dumpSearchResultsForConfig(sourceFrame, searchConfig, next); + dumpSearchResultsForConfig(sourceFrame, searchConfig); + next(); }, function testSearchCaseSensitive(next) { var query = "SEARCHTestUniqueString"; var searchConfig = new WebInspector.SearchableView.SearchConfig(query, true, false); - dumpSearchResultsForConfig(sourceFrame, searchConfig, next); + dumpSearchResultsForConfig(sourceFrame, searchConfig); + next(); }, function testSearchRegex(next) { var query = "searchTestUnique.*"; var searchConfig = new WebInspector.SearchableView.SearchConfig(query, false, true); - dumpSearchResultsForConfig(sourceFrame, searchConfig, next); + dumpSearchResultsForConfig(sourceFrame, searchConfig); + next(); }, function testSearchCaseSensitiveRegex(next) { var query = "searchTestUnique.*"; var searchConfig = new WebInspector.SearchableView.SearchConfig(query, true, true); - dumpSearchResultsForConfig(sourceFrame, searchConfig, next); + dumpSearchResultsForConfig(sourceFrame, searchConfig); + next(); }, function testSearchConsequent(next) { var query = "AAAAA"; var searchConfig = new WebInspector.SearchableView.SearchConfig(query, false, false); - dumpSearchResultsForConfig(sourceFrame, searchConfig, next); + dumpSearchResultsForConfig(sourceFrame, searchConfig); + next(); } ]); }
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/interstitial-sidebar-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/security/interstitial-sidebar-expected.txt new file mode 100644 index 0000000..ace744c5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/security/interstitial-sidebar-expected.txt
@@ -0,0 +1,396 @@ +Tests that the sidebar origin list disappears and appers when an interstitial is shown or hidden. + +Before interstitial is shown: +<DIV class=sidebar-tree > + <#document-fragment > + <STYLE type=text/css > + </STYLE> + <STYLE type=text/css > + </STYLE> + <STYLE type=text/css > + </STYLE> + <DIV class=tree-outline-disclosure > + <OL class=tree-outline tabindex=0 > + <LI class=sidebar-tree-item security-main-view-sidebar-tree-item selected > + <DIV class=selection fill > + </DIV> + <DIV class=icon lock-icon lock-icon-unknown > + </DIV> + <DIV class=status > + </DIV> + <DIV class=titles no-subtitle > + <SPAN class=title-container > + <SPAN class=title > +Overview + </SPAN> + </SPAN> + <SPAN class=subtitle > + </SPAN> + </DIV> + </LI> + <OL class=children > + </OL> + <LI class=parent expanded security-sidebar-origins sidebar-tree-section > + <DIV class=selection fill > + </DIV> + <SPAN class=tree-element-title > +Main Origin + </SPAN> + </LI> + <OL class=children expanded > + <LI class=sidebar-tree-item security-main-view-reload-message > + <DIV class=selection fill > + </DIV> + <DIV class=icon > + </DIV> + <DIV class=status > + </DIV> + <DIV class=titles no-subtitle > + <SPAN class=title-container > + <SPAN class=title > +Reload to view details + </SPAN> + </SPAN> + <SPAN class=subtitle > + </SPAN> + </DIV> + </LI> + <OL class=children > + </OL> + </OL> + <LI class=parent expanded security-sidebar-origins sidebar-tree-section hidden > + <DIV class=selection fill > + </DIV> + <SPAN class=tree-element-title > +Non-Secure Origins + </SPAN> + </LI> + <OL class=children expanded hidden > + </OL> + <LI class=parent expanded security-sidebar-origins sidebar-tree-section > + <DIV class=selection fill > + </DIV> + <SPAN class=tree-element-title > +Secure Origins + </SPAN> + </LI> + <OL class=children expanded > + <LI class=sidebar-tree-item security-sidebar-tree-item > + <DIV class=selection fill > + </DIV> + <DIV class=icon security-property security-property-secure > + </DIV> + <DIV class=status > + </DIV> + <DIV class=titles no-subtitle > + <SPAN class=title-container > + <SPAN class=title > +https://foo.test + </SPAN> + </SPAN> + <SPAN class=subtitle > + </SPAN> + </DIV> + </LI> + <OL class=children > + </OL> + <LI class=sidebar-tree-item security-sidebar-tree-item > + <DIV class=selection fill > + </DIV> + <DIV class=icon security-property security-property-secure > + </DIV> + <DIV class=status > + </DIV> + <DIV class=titles no-subtitle > + <SPAN class=title-container > + <SPAN class=title > +https://bar.test + </SPAN> + </SPAN> + <SPAN class=subtitle > + </SPAN> + </DIV> + </LI> + <OL class=children > + </OL> + </OL> + <LI class=parent expanded security-sidebar-origins sidebar-tree-section hidden > + <DIV class=selection fill > + </DIV> + <SPAN class=tree-element-title > +Unknown / Canceled + </SPAN> + </LI> + <OL class=children expanded hidden > + </OL> + </OL> + </DIV> + <STYLE type=text/css > + </STYLE> + <STYLE type=text/css > + </STYLE> + </#document-fragment> +</DIV> +After interstitial is shown: +<DIV class=sidebar-tree > + <#document-fragment > + <STYLE type=text/css > + </STYLE> + <STYLE type=text/css > + </STYLE> + <STYLE type=text/css > + </STYLE> + <DIV class=tree-outline-disclosure > + <OL class=tree-outline tabindex=0 > + <LI class=sidebar-tree-item security-main-view-sidebar-tree-item selected > + <DIV class=selection fill > + </DIV> + <DIV class=icon lock-icon lock-icon-unknown > + </DIV> + <DIV class=status > + </DIV> + <DIV class=titles no-subtitle > + <SPAN class=title-container > + <SPAN class=title > +Overview + </SPAN> + </SPAN> + <SPAN class=subtitle > + </SPAN> + </DIV> + </LI> + <OL class=children > + </OL> + <LI class=parent expanded security-sidebar-origins sidebar-tree-section hidden > + <DIV class=selection fill > + </DIV> + <SPAN class=tree-element-title > +Main Origin + </SPAN> + </LI> + <OL class=children expanded hidden > + <LI class=sidebar-tree-item security-main-view-reload-message > + <DIV class=selection fill > + </DIV> + <DIV class=icon > + </DIV> + <DIV class=status > + </DIV> + <DIV class=titles no-subtitle > + <SPAN class=title-container > + <SPAN class=title > +Reload to view details + </SPAN> + </SPAN> + <SPAN class=subtitle > + </SPAN> + </DIV> + </LI> + <OL class=children > + </OL> + </OL> + <LI class=parent expanded security-sidebar-origins sidebar-tree-section hidden > + <DIV class=selection fill > + </DIV> + <SPAN class=tree-element-title > +Non-Secure Origins + </SPAN> + </LI> + <OL class=children expanded hidden > + </OL> + <LI class=parent expanded security-sidebar-origins sidebar-tree-section hidden > + <DIV class=selection fill > + </DIV> + <SPAN class=tree-element-title > +Secure Origins + </SPAN> + </LI> + <OL class=children expanded hidden > + <LI class=sidebar-tree-item security-sidebar-tree-item > + <DIV class=selection fill > + </DIV> + <DIV class=icon security-property security-property-secure > + </DIV> + <DIV class=status > + </DIV> + <DIV class=titles no-subtitle > + <SPAN class=title-container > + <SPAN class=title > +https://foo.test + </SPAN> + </SPAN> + <SPAN class=subtitle > + </SPAN> + </DIV> + </LI> + <OL class=children > + </OL> + <LI class=sidebar-tree-item security-sidebar-tree-item > + <DIV class=selection fill > + </DIV> + <DIV class=icon security-property security-property-secure > + </DIV> + <DIV class=status > + </DIV> + <DIV class=titles no-subtitle > + <SPAN class=title-container > + <SPAN class=title > +https://bar.test + </SPAN> + </SPAN> + <SPAN class=subtitle > + </SPAN> + </DIV> + </LI> + <OL class=children > + </OL> + </OL> + <LI class=parent expanded security-sidebar-origins sidebar-tree-section hidden > + <DIV class=selection fill > + </DIV> + <SPAN class=tree-element-title > +Unknown / Canceled + </SPAN> + </LI> + <OL class=children expanded hidden > + </OL> + </OL> + </DIV> + <STYLE type=text/css > + </STYLE> + <STYLE type=text/css > + </STYLE> + </#document-fragment> +</DIV> +After interstitial is hidden: +<DIV class=sidebar-tree > + <#document-fragment > + <STYLE type=text/css > + </STYLE> + <STYLE type=text/css > + </STYLE> + <STYLE type=text/css > + </STYLE> + <DIV class=tree-outline-disclosure > + <OL class=tree-outline tabindex=0 > + <LI class=sidebar-tree-item security-main-view-sidebar-tree-item selected > + <DIV class=selection fill > + </DIV> + <DIV class=icon lock-icon lock-icon-unknown > + </DIV> + <DIV class=status > + </DIV> + <DIV class=titles no-subtitle > + <SPAN class=title-container > + <SPAN class=title > +Overview + </SPAN> + </SPAN> + <SPAN class=subtitle > + </SPAN> + </DIV> + </LI> + <OL class=children > + </OL> + <LI class=parent expanded security-sidebar-origins sidebar-tree-section > + <DIV class=selection fill > + </DIV> + <SPAN class=tree-element-title > +Main Origin + </SPAN> + </LI> + <OL class=children expanded > + <LI class=sidebar-tree-item security-main-view-reload-message > + <DIV class=selection fill > + </DIV> + <DIV class=icon > + </DIV> + <DIV class=status > + </DIV> + <DIV class=titles no-subtitle > + <SPAN class=title-container > + <SPAN class=title > +Reload to view details + </SPAN> + </SPAN> + <SPAN class=subtitle > + </SPAN> + </DIV> + </LI> + <OL class=children > + </OL> + </OL> + <LI class=parent expanded security-sidebar-origins sidebar-tree-section > + <DIV class=selection fill > + </DIV> + <SPAN class=tree-element-title > +Non-Secure Origins + </SPAN> + </LI> + <OL class=children expanded > + </OL> + <LI class=parent expanded security-sidebar-origins sidebar-tree-section > + <DIV class=selection fill > + </DIV> + <SPAN class=tree-element-title > +Secure Origins + </SPAN> + </LI> + <OL class=children expanded > + <LI class=sidebar-tree-item security-sidebar-tree-item > + <DIV class=selection fill > + </DIV> + <DIV class=icon security-property security-property-secure > + </DIV> + <DIV class=status > + </DIV> + <DIV class=titles no-subtitle > + <SPAN class=title-container > + <SPAN class=title > +https://foo.test + </SPAN> + </SPAN> + <SPAN class=subtitle > + </SPAN> + </DIV> + </LI> + <OL class=children > + </OL> + <LI class=sidebar-tree-item security-sidebar-tree-item > + <DIV class=selection fill > + </DIV> + <DIV class=icon security-property security-property-secure > + </DIV> + <DIV class=status > + </DIV> + <DIV class=titles no-subtitle > + <SPAN class=title-container > + <SPAN class=title > +https://bar.test + </SPAN> + </SPAN> + <SPAN class=subtitle > + </SPAN> + </DIV> + </LI> + <OL class=children > + </OL> + </OL> + <LI class=parent expanded security-sidebar-origins sidebar-tree-section > + <DIV class=selection fill > + </DIV> + <SPAN class=tree-element-title > +Unknown / Canceled + </SPAN> + </LI> + <OL class=children expanded > + </OL> + </OL> + </DIV> + <STYLE type=text/css > + </STYLE> + <STYLE type=text/css > + </STYLE> + </#document-fragment> +</DIV> +
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/security/interstitial-sidebar.html b/third_party/WebKit/LayoutTests/http/tests/inspector/security/interstitial-sidebar.html new file mode 100644 index 0000000..b53fd5d --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/security/interstitial-sidebar.html
@@ -0,0 +1,37 @@ +<html> +<head> +<script src="../inspector-test.js"></script> +<script src="../security-test.js"></script> +<script> +function test() +{ + + var request1 = new WebInspector.NetworkRequest(InspectorTest.mainTarget, 0, "https://foo.test/", "https://foo.test", 0, 0, null); + request1.setSecurityState(SecurityAgent.SecurityState.Secure); + InspectorTest.dispatchRequestFinished(request1); + + var request2 = new WebInspector.NetworkRequest(InspectorTest.mainTarget, 0, "https://bar.test/foo.jpg", "https://bar.test", 0, 0, null); + request2.setSecurityState(SecurityAgent.SecurityState.Secure); + InspectorTest.dispatchRequestFinished(request2); + + InspectorTest.addResult("Before interstitial is shown:"); + InspectorTest.dumpDeepInnerHTML(WebInspector.SecurityPanel._instance()._sidebarTree.element); + + // Test that the sidebar is hidden when an interstitial is shown. https://crbug.com/559150 + InspectorTest.mainTarget.model(WebInspector.ResourceTreeModel).dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.InterstitialShown); + InspectorTest.addResult("After interstitial is shown:"); + InspectorTest.dumpDeepInnerHTML(WebInspector.SecurityPanel._instance()._sidebarTree.element); + + // Test that the sidebar is shown again when the interstitial is hidden. https://crbug.com/559150 + InspectorTest.mainTarget.model(WebInspector.ResourceTreeModel).dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.InterstitialHidden); + InspectorTest.addResult("After interstitial is hidden:"); + InspectorTest.dumpDeepInnerHTML(WebInspector.SecurityPanel._instance()._sidebarTree.element); + + InspectorTest.completeTest(); +} +</script> +</head> +<body onload="runTest()"> +<p>Tests that the sidebar origin list disappears and appers when an interstitial is shown or hidden.</p> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js index 5df5b56a..43075d74 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js
@@ -93,7 +93,7 @@ function tracingStarted() { - InspectorTest.invokePageFunctionAsync(functionName, onPageActionsDone); + InspectorTest.callFunctionInPageAsync(functionName).then(onPageActionsDone); } function onPageActionsDone() @@ -173,7 +173,7 @@ InspectorTest.startTimeline(step1); function step1() { - InspectorTest.invokePageFunctionAsync(functionName, step2); + InspectorTest.callFunctionInPageAsync(functionName).then(step2); } function step2() @@ -461,19 +461,27 @@ }; -function generateFrames(count, callback) +function generateFrames(count) { - makeFrame(); - function makeFrame() + var promise = Promise.resolve(); + for (let i = count; i > 0; --i) + promise = promise.then(changeBackgroundAndWaitForFrame.bind(null, i)); + return promise; + + function changeBackgroundAndWaitForFrame(i) { - document.body.style.backgroundColor = count & 1 ? "rgb(200, 200, 200)" : "rgb(240, 240, 240)"; - if (!--count) { - callback(); - return; - } - if (window.testRunner) - testRunner.capturePixelsAsyncThen(requestAnimationFrame.bind(window, makeFrame)); - else - window.requestAnimationFrame(makeFrame); + document.body.style.backgroundColor = i & 1 ? "rgb(200, 200, 200)" : "rgb(240, 240, 240)"; + return waitForFrame(); } } + +function waitForFrame() +{ + var callback; + var promise = new Promise((fulfill) => callback = fulfill); + if (window.testRunner) + testRunner.capturePixelsAsyncThen(() => window.requestAnimationFrame(callback)); + else + window.requestAnimationFrame(callback); + return promise; +}
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/tracing/timeline-script-parse.html b/third_party/WebKit/LayoutTests/http/tests/inspector/tracing/timeline-script-parse.html index ce66fb8..5431a42c 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/tracing/timeline-script-parse.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/tracing/timeline-script-parse.html
@@ -5,13 +5,16 @@ <script src="../network-test.js"></script> <script> -function performActions(callback) +function performActions() { + var callback; + var promise = new Promise((fulfill) => callback = fulfill); var script = document.createElement("script"); script.src = "resources/timeline-script-parse.php"; script.async = true; script.onload = callback; document.body.appendChild(script); + return promise; } function test()
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/tracing/timeline-xhr-event.html b/third_party/WebKit/LayoutTests/http/tests/inspector/tracing/timeline-xhr-event.html index 8e56779..bda38cc 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/tracing/timeline-xhr-event.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/tracing/timeline-xhr-event.html
@@ -5,13 +5,16 @@ <script src="../network-test.js"></script> <script> -function performActions(callback) +function performActions() { + var callback; + var promise = new Promise((fulfill) => callback = fulfill); var xhr = new XMLHttpRequest(); xhr.open("GET", "network/resources/resource.php", true); xhr.onload = callback; // This is necessary for XHRLoad event. xhr.onreadystatechange = function () { }; // This is necessary for XHRReadyStateChange event. xhr.send(null); + return promise; } function test()
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/tracing/timeline-xhr-response-type-blob-event.html b/third_party/WebKit/LayoutTests/http/tests/inspector/tracing/timeline-xhr-response-type-blob-event.html index 6b6c6c3..3646f48 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/tracing/timeline-xhr-response-type-blob-event.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/tracing/timeline-xhr-response-type-blob-event.html
@@ -5,8 +5,10 @@ <script src="../network-test.js"></script> <script> -function performActions(callback) +function performActions() { + var callback; + var promise = new Promise((fulfill) => callback = fulfill); var xhr = new XMLHttpRequest(); xhr.responseType = "blob"; xhr.open("GET", "network/resources/resource.php", true); @@ -19,6 +21,7 @@ callback(); } xhr.send(null); + return promise; } function test()
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/tracing/websocket/timeline-websocket-event.html b/third_party/WebKit/LayoutTests/http/tests/inspector/tracing/websocket/timeline-websocket-event.html index 29a5270ac..bb263a7 100644 --- a/third_party/WebKit/LayoutTests/http/tests/inspector/tracing/websocket/timeline-websocket-event.html +++ b/third_party/WebKit/LayoutTests/http/tests/inspector/tracing/websocket/timeline-websocket-event.html
@@ -4,10 +4,10 @@ <script src="../../timeline-test.js"></script> <script> -function performActions(callback) +function performActions() { var ws = new WebSocket("ws://127.0.0.1:8880/simple"); - ws.onclose = callback; + return new Promise((fulfill) => ws.onclose = fulfill); } function test()
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/video-buffered-expected.txt b/third_party/WebKit/LayoutTests/http/tests/media/video-buffered-expected.txt deleted file mode 100644 index 058685ce..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/media/video-buffered-expected.txt +++ /dev/null
@@ -1,9 +0,0 @@ -Start playing a video with preloading enabled, do a seek near the end and check multiple buffered timeranges have been created. - -EVENT(playing) -EXPECTED (video.buffered.length == '1') OK -RUN(video.currentTime = video.duration - 0.5) -EVENT(ended) -EXPECTED (video.buffered.length == '2'), OBSERVED '1' FAIL -END OF TEST -
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/video-buffered-range-contains-currentTime.html b/third_party/WebKit/LayoutTests/http/tests/media/video-buffered-range-contains-currentTime.html index ff27ded..cefe753 100644 --- a/third_party/WebKit/LayoutTests/http/tests/media/video-buffered-range-contains-currentTime.html +++ b/third_party/WebKit/LayoutTests/http/tests/media/video-buffered-range-contains-currentTime.html
@@ -1,33 +1,24 @@ -<html> - <head> - <script src=../../media-resources/media-file.js></script> - <!-- TODO(foolip): Convert test to testharness.js. crbug.com/588956 - (Please avoid writing new tests using video-test.js) --> - <script src=../../media-resources/video-test.js></script> - <script> - if (window.testRunner) - testRunner.dumpAsTextWithPixelResults(); // To get pixels. +<!DOCTYPE html> +<title>Test that the painted buffered range contains currentTime.</title> +<script src="../../media-resources/media-file.js"></script> +<video controls></video> +<script> +var video = document.querySelector("video"); - function start() { - findMediaElement(); +testRunner.waitUntilDone(); +video.onended = function() { + testRunner.notifyDone(); +}; - waitForEventAndEnd('ended'); - waitForEvent('seeked', function() { - video.play(); - }); - waitForEvent('loadedmetadata', function() { - video.currentTime = video.duration - 0.5; - } ); +video.onseeked = function() { + video.play(); +}; - var mediaFile = findMediaFile("audio", "../../../media/content/test"); - var type = mimeTypeForExtension(mediaFile.split('.').pop()); - video.src = "http://127.0.0.1:8000/media/video-throttled-load.cgi?name=" + mediaFile + "&throttle=50&nph=1&type=" + type; - video.load(); - } - </script> - </head> - <body onload="start()"> - <video controls></video> - <p>Test that the painted buffered range contains currentTime.</p> - </body> -</html> +video.onloadedmetadata = function() { + video.currentTime = video.duration - 0.5; +}; + +var mediaFile = findMediaFile("audio", "../../../media/content/test"); +var type = mimeTypeForExtension(mediaFile.split(".").pop()); +video.src = "http://127.0.0.1:8000/media/video-throttled-load.cgi?name=" + mediaFile + "&throttle=5000&nph=1&type=" + type; +</script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/http/tests/media/video-buffered.html b/third_party/WebKit/LayoutTests/http/tests/media/video-buffered.html index d9903eb..9a31cbcd 100644 --- a/third_party/WebKit/LayoutTests/http/tests/media/video-buffered.html +++ b/third_party/WebKit/LayoutTests/http/tests/media/video-buffered.html
@@ -1,34 +1,26 @@ -<html> -<head> -</head> -<body onload="start()"> -<p>Start playing a video with preloading enabled, do a seek near the - end and check multiple buffered timeranges have been created.</p> -<video id="video" preload="auto" autobuffer></video> -<!-- TODO(foolip): Convert test to testharness.js. crbug.com/588956 - (Please avoid writing new tests using video-test.js) --> -<script src=../../media-resources/video-test.js></script> -<script src=../../media-resources/media-file.js></script> +<!DOCTYPE html> +<title>Check multiple buffered timeranges with video preload.</title> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<script src="../../media-resources/media-file.js"></script> +<video preload="auto"></video> <script> - waitForEvent("ended", ended); - waitForEventOnce('playing', function() { - testExpected("video.buffered.length", 1, "=="); - run("video.currentTime = video.duration - 0.5"); +async_test(function(t) { + var video = document.querySelector("video"); + + video.onended = t.step_func_done(function() { + assert_equals(video.buffered.length, 2); }); - function ended() { - testExpected("video.buffered.length", 2, "=="); - endTest(); - } + video.onplaying = t.step_func(function() { + video.onplaying = null; + video.currentTime = video.duration - 0.5; + }); - function start () { - video = document.getElementById('video'); - var mediaFile = findMediaFile("audio", "../../../media/content/test"); - var type = mimeTypeForExtension(mediaFile.split('.').pop()); - video.src = "http://127.0.0.1:8000/media/video-throttled-load.cgi?nph=1&name=" + mediaFile + "&throttle=100&type=" + type; - - video.play(); - } -</script> -</body> -</html> + // This test needs a large media file to test multiple buffered timeranges. + var mediaFile = "../../../media/resources/frame_size_change.webm"; + var type = mimeTypeForExtension(mediaFile.split(".").pop()); + video.src = "http://127.0.0.1:8000/media/video-throttled-load.cgi?nph=1&name=" + mediaFile + "&throttle=100000&type=" + type; + video.play(); +}); +</script> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/http/tests/navigation/form-targets-cross-site-frame-no-referrer-expected.txt b/third_party/WebKit/LayoutTests/http/tests/navigation/form-targets-cross-site-frame-no-referrer-expected.txt new file mode 100644 index 0000000..e9e9393 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/navigation/form-targets-cross-site-frame-no-referrer-expected.txt
@@ -0,0 +1,18 @@ +Test field: + + +-------- +Frame: 'cross-site-frame' +-------- +This page was requested with the HTTP method POST. + +Parameters: + +test-field = test-value +Http headers: + +HTTP_CACHE_CONTROL = max-age=0 +HTTP_CONNECTION = keep-alive +HTTP_HOST = localhost:8080 +HTTP_ORIGIN = null +HTTP_UPGRADE_INSECURE_REQUESTS = 1
diff --git a/third_party/WebKit/LayoutTests/http/tests/navigation/form-targets-cross-site-frame-no-referrer.html b/third_party/WebKit/LayoutTests/http/tests/navigation/form-targets-cross-site-frame-no-referrer.html new file mode 100644 index 0000000..d564b68b --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/navigation/form-targets-cross-site-frame-no-referrer.html
@@ -0,0 +1,40 @@ +<!DOCTYPE html> +<!-- +The test verifies that a form with target="crossSiteFrame" works fine +(especially in presence of out-of-process-iframes, aka OOPIFs, aka +blink::RemoteFrames which are present in --site-per-process mode). + +The test finishes successfully, if form-target.pl ends up calling +testRunner.notifyDone() after main frame calls testRuner.waitUntilDone +and submits the form. Expected test output helps verify that the +correct HTTP method was used and that test field's value from the form +was propagated correctly. +--> +<html> +<meta name="referrer" content="no-referrer"> +<script> + if (window.testRunner) { + testRunner.dumpAsText(); + testRunner.dumpChildFramesAsText(); + } + + function onLoad() { + if (window.testRunner) + testRunner.waitUntilDone(); + document.forms[0].submit(); + } +</script> +<body onload="onLoad();"> +<form + method="POST" + action="http://localhost:8080/navigation/resources/form-target.pl" + target="cross-site-frame"> + Test field: + <input name="test-field" type="text" value="test-value"> + <input type="submit" value="Submit"> +</form> +<iframe + name="cross-site-frame" + src="http://localhost:8080/navigation/resources/otherpage.html"></iframe> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index 43c5288..1ebd439 100644 --- a/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt
@@ -478,6 +478,7 @@ setter height setter width interface OffscreenCanvasRenderingContext2D + getter canvas getter fillStyle getter imageSmoothingEnabled getter imageSmoothingQuality @@ -486,7 +487,6 @@ getter lineJoin getter lineWidth getter miterLimit - getter offscreenCanvas getter shadowBlur getter shadowColor getter shadowOffsetX
diff --git a/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt b/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt index 61bf12b..3602902 100644 --- a/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/worklet/webexposed/global-interface-listing-paint-worklet-expected.txt
@@ -24,6 +24,11 @@ CONSOLE MESSAGE: line 137: getter vmin CONSOLE MESSAGE: line 137: getter vw CONSOLE MESSAGE: line 137: method constructor +CONSOLE MESSAGE: line 137: interface CSSImageValue : CSSResourceValue +CONSOLE MESSAGE: line 137: getter intrinsicHeight +CONSOLE MESSAGE: line 137: getter intrinsicRatio +CONSOLE MESSAGE: line 137: getter intrinsicWidth +CONSOLE MESSAGE: line 137: method constructor CONSOLE MESSAGE: line 137: interface CSSKeywordValue : CSSStyleValue CONSOLE MESSAGE: line 137: getter keywordValue CONSOLE MESSAGE: line 137: method constructor
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/console/console-let-const-with-api-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/console/console-let-const-with-api-expected.txt index f8712f89..3b40d6c 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/console/console-let-const-with-api-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/console/console-let-const-with-api-expected.txt
@@ -1,7 +1,7 @@ first "let a = 1;" result: wasThrown = false second "let a = 1;" result: wasThrown = true exception message: Uncaught SyntaxError: Identifier 'a' has already been declared -{"result":{"type":"number","value":42,"description":"42"},"wasThrown":false} +{"result":{"type":"number","value":42,"description":"42"}} function $(selector, [startNode]) { [Command Line API] } function $$(selector, [startNode]) { [Command Line API] } function $x(xpath, [startNode]) { [Command Line API] }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/console/console-let-const-with-api.html b/third_party/WebKit/LayoutTests/inspector-protocol/console/console-let-const-with-api.html index c6c0b0d..e1e592dd 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/console/console-let-const-with-api.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/console/console-let-const-with-api.html
@@ -10,15 +10,15 @@ function step2(response) { failIfError(response); - InspectorTest.log("first \"let a = 1;\" result: wasThrown = " + response.result.wasThrown); + InspectorTest.log("first \"let a = 1;\" result: wasThrown = " + !!response.result.exceptionDetails); InspectorTest.sendCommand("Runtime.evaluate", { expression: "let a = 239;" }, step3); } function step3(response) { failIfError(response); - InspectorTest.log("second \"let a = 1;\" result: wasThrown = " + response.result.wasThrown); - if (response.result.wasThrown) + InspectorTest.log("second \"let a = 1;\" result: wasThrown = " + !!response.result.exceptionDetails); + if (response.result.exceptionDetails) InspectorTest.log("exception message: " + response.result.exceptionDetails.text); InspectorTest.sendCommand("Runtime.evaluate", { expression: "a" }, step4); }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/console/console-memory-setter-in-strict-mode-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/console/console-memory-setter-in-strict-mode-expected.txt index 3b57d34..f432d7a 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/console/console-memory-setter-in-strict-mode-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/console/console-memory-setter-in-strict-mode-expected.txt
@@ -5,7 +5,6 @@ result : { type : undefined } - wasThrown : false } }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/debugger/step-into-inline-event-handler-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/debugger/step-into-inline-event-handler-expected.txt new file mode 100644 index 0000000..fd7f45ad --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/debugger/step-into-inline-event-handler-expected.txt
@@ -0,0 +1,3 @@ +Tests that Debugger.stepInto doesn't ignore inline event listeners. +functionName (should be empty): empty +
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/debugger/step-into-inline-event-handler.html b/third_party/WebKit/LayoutTests/inspector-protocol/debugger/step-into-inline-event-handler.html new file mode 100644 index 0000000..5c6e12fa --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector-protocol/debugger/step-into-inline-event-handler.html
@@ -0,0 +1,54 @@ +<html> +<head> +<script type="text/javascript" src="../../http/tests/inspector-protocol/inspector-protocol-test.js"></script> +<script> + +function testFunction() +{ + var e = document.getElementById("div"); + debugger; + e.click(); +} + +function shouldNotBeThisFunction() +{ + return 239; +} + +function test() +{ + InspectorTest.waitForEventPromise("Debugger.paused").then(makeStepping); + + InspectorTest.sendCommandPromise("Debugger.enable", {}) + .then((result) => InspectorTest.sendCommandPromise("Runtime.evaluate", { expression: "testFunction()" })) + .then(() => InspectorTest.completeTest()); + + function makeStepping() + { + sendCommandAndWaitForPause("Debugger.stepInto") + .then(() => sendCommandAndWaitForPause("Debugger.stepInto")) + .then((result) => dumpTopCallFrame(result)) + .then(() => InspectorTest.sendCommandPromise("Debugger.resume")); + } + + function sendCommandAndWaitForPause(command) + { + InspectorTest.sendCommand(command, {}); + return InspectorTest.waitForEventPromise("Debugger.paused"); + } + + function dumpTopCallFrame(result) + { + var frame = result.params.callFrames[0]; + InspectorTest.log("functionName (should be empty): " + (frame.functionName.length ? frame.functionName : "empty")); + } +} +</script> +</head> +<div id="div" onclick="shouldNotBeThisFunction()"> +</div> +<body onLoad="runTest();"> +Tests that Debugger.stepInto doesn't ignore inline event listeners. +</body> +</html> +
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/debugger/updateCallFrameScopes.html b/third_party/WebKit/LayoutTests/inspector-protocol/debugger/updateCallFrameScopes.html index 1adeb75f..6de9574 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/debugger/updateCallFrameScopes.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/debugger/updateCallFrameScopes.html
@@ -7,38 +7,40 @@ { var a = 2; debugger; + debugger; } function test() { var newVariableValue = 55; - + InspectorTest.sendCommand("Debugger.enable", {}); InspectorTest.eventHandler["Debugger.paused"] = handleDebuggerPaused; InspectorTest.sendCommand("Runtime.evaluate", { "expression": "setTimeout(TestFunction, 0)" }); - + function handleDebuggerPaused(messageObject) { InspectorTest.log("Paused on 'debugger;'"); InspectorTest.eventHandler["Debugger.paused"] = undefined; - + var topFrame = messageObject.params.callFrames[0]; var topFrameId = topFrame.callFrameId; InspectorTest.sendCommand("Debugger.evaluateOnCallFrame", { "callFrameId": topFrameId, "expression": "a = " + newVariableValue }, callbackChangeValue); } - + function callbackChangeValue(response) { InspectorTest.log("Variable value changed"); - InspectorTest.sendCommand("Debugger.getBacktrace", { }, callbackGetBacktrace); + InspectorTest.eventHandler["Debugger.paused"] = callbackGetBacktrace; + InspectorTest.sendCommand("Debugger.resume", { }); } function callbackGetBacktrace(response) { InspectorTest.log("Stacktrace re-read again"); - var localScope = response.result.callFrames[0].scopeChain[0]; + var localScope = response.params.callFrames[0].scopeChain[0]; InspectorTest.sendCommand("Runtime.getProperties", { "objectId": localScope.object.objectId }, callbackGetProperties); } @@ -57,7 +59,7 @@ var actualValue = varNamedA.value.value; InspectorTest.log("New variable is " + actualValue + ", expected is " + newVariableValue + ", old was: 2"); InspectorTest.log(actualValue == newVariableValue ? "SUCCESS" : "FAIL"); - } else { + } else { InspectorTest.log("Failed to find variable in scope"); } InspectorTest.completeTest();
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/json-parse-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/json-parse-expected.txt index f952527..fc559a5a 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/json-parse-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/json-parse-expected.txt
@@ -5,7 +5,6 @@ type : string value : Привет мир } - wasThrown : false } }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-await-promise-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-await-promise-expected.txt index b35547d3..6ae36c0 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-await-promise-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-await-promise-expected.txt
@@ -30,7 +30,6 @@ a : 1 } } - wasThrown : true } Running test: testRejectedPromiseWithStack @@ -69,7 +68,6 @@ type : number value : 239 } - wasThrown : true } Running test: testPendingPromise
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-callFunctionOn-async-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-callFunctionOn-async-expected.txt index 6adaac2..23f7457 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-callFunctionOn-async-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-callFunctionOn-async-expected.txt
@@ -7,7 +7,6 @@ type : string value : undefined|NaN|[object Object]|[object Window] } - wasThrown : false } Running test: testSyntaxErrorInFunction @@ -25,7 +24,6 @@ subtype : error type : object } - wasThrown : true } Running test: testExceptionInFunctionExpression @@ -43,7 +41,6 @@ subtype : error type : object } - wasThrown : true } Running test: testFunctionReturnNotPromise @@ -102,6 +99,5 @@ a : 3 } } - wasThrown : true }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-clear-of-command-line-api-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-clear-of-command-line-api-expected.txt index 1b4ddc98..db9f0d6 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-clear-of-command-line-api-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-clear-of-command-line-api-expected.txt
@@ -6,7 +6,6 @@ type : number value : 15 } - wasThrown : false } { result : { @@ -14,7 +13,6 @@ type : number value : 0 } - wasThrown : false } setPropertyForMethod() { @@ -23,7 +21,6 @@ type : number value : 14 } - wasThrown : false } { result : { @@ -31,7 +28,6 @@ type : number value : 0 } - wasThrown : false } { result : { @@ -39,7 +35,6 @@ type : number value : 42 } - wasThrown : false } defineValuePropertyForMethod() { @@ -48,7 +43,6 @@ type : number value : 14 } - wasThrown : false } { result : { @@ -56,7 +50,6 @@ type : number value : 0 } - wasThrown : false } { result : { @@ -64,7 +57,6 @@ type : number value : 42 } - wasThrown : false } definePropertiesForMethod() { @@ -73,7 +65,6 @@ type : number value : 14 } - wasThrown : false } { result : { @@ -81,7 +72,6 @@ type : number value : 0 } - wasThrown : false } { result : { @@ -89,7 +79,6 @@ type : number value : 42 } - wasThrown : false } defineAccessorPropertyForMethod() { @@ -98,7 +87,6 @@ type : number value : 14 } - wasThrown : false } { result : { @@ -106,7 +94,6 @@ type : number value : 0 } - wasThrown : false } { result : { @@ -114,7 +101,6 @@ type : number value : 42 } - wasThrown : false } redefineGetOwnPropertyDescriptors() { @@ -123,7 +109,6 @@ type : number value : 14 } - wasThrown : false } { result : { @@ -131,7 +116,6 @@ type : number value : 0 } - wasThrown : false } { result : { @@ -139,6 +123,5 @@ type : number value : 42 } - wasThrown : false }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-async-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-async-expected.txt index 95cf9bf..60ac70e5 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-async-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-async-expected.txt
@@ -27,7 +27,6 @@ type : number value : 239 } - wasThrown : true } Running test: testPrimitiveValueInsteadOfPromise @@ -65,6 +64,5 @@ type : number value : 239 } - wasThrown : true }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-in-default-context-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-in-default-context-expected.txt index 551fa7ce..8545625 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-in-default-context-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-evaluate-in-default-context-expected.txt
@@ -7,7 +7,6 @@ type : number value : 42 } - wasThrown : false } }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-get-properties-on-proxy-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-get-properties-on-proxy-expected.txt index 55b0130..151ea38 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-get-properties-on-proxy-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-get-properties-on-proxy-expected.txt
@@ -5,6 +5,5 @@ type : number value : 0 } - wasThrown : false }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-property-on-console-proto-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-property-on-console-proto-expected.txt index e5f0adfc..c7fbadb4 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-property-on-console-proto-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-property-on-console-proto-expected.txt
@@ -7,7 +7,6 @@ type : number value : 0 } - wasThrown : false } }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-runScript-async-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-runScript-async-expected.txt index 10a1404..ba6ad4b 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-runScript-async-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/runtime/runtime-runScript-async-expected.txt
@@ -47,7 +47,6 @@ subtype : error type : object } - wasThrown : true } Running test: testRunNotCompiledScript @@ -86,7 +85,6 @@ } type : object } - wasThrown : false } Running test: testRunScriptReturnByValue @@ -97,7 +95,6 @@ a : 1 } } - wasThrown : false } Running test: testAwaitNotPromise @@ -134,6 +131,5 @@ a : 1 } } - wasThrown : true }
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/timeline/fetch-as-stream.html b/third_party/WebKit/LayoutTests/inspector-protocol/timeline/fetch-as-stream.html index f855237..9915d15 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/timeline/fetch-as-stream.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/timeline/fetch-as-stream.html
@@ -11,12 +11,11 @@ <script type="text/javascript" src="../../http/tests/inspector-protocol/inspector-protocol-test.js"></script> <script type="text/javascript" src="../../http/tests/inspector-protocol/tracing-test.js"></script> <script> -function performActions(callback) +function performActions() { var element = document.getElementById("test"); element.style.display = "block"; var unused = element.clientWidth; - callback(); } function test() @@ -25,7 +24,7 @@ function onStart() { - InspectorTest.invokePageFunctionAsync("performActions", evalDone); + InspectorTest.evaluateInPage("performActions()", evalDone); } function evalDone()
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/timeline/timeline-dispatchEvent.html b/third_party/WebKit/LayoutTests/inspector-protocol/timeline/timeline-dispatchEvent.html index 408512a4..8d946ea 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/timeline/timeline-dispatchEvent.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/timeline/timeline-dispatchEvent.html
@@ -4,7 +4,7 @@ <script type="text/javascript" src="../../http/tests/inspector-protocol/tracing-test.js"></script> <script> -function performAction(callback) +function performAction() { var div = document.querySelector("#my-div"); div.addEventListener("click", function(e) { }, false); @@ -12,7 +12,7 @@ var iframe = document.createElement("iframe"); div.appendChild(iframe); - callback(); + return Promise.resolve(); } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/timeline/timeline-layout.html b/third_party/WebKit/LayoutTests/inspector-protocol/timeline/timeline-layout.html index f9a3484a..f998ee4 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/timeline/timeline-layout.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/timeline/timeline-layout.html
@@ -10,12 +10,12 @@ <script type="text/javascript" src="../../http/tests/inspector-protocol/tracing-test.js"></script> <script> -function performActions(callback) +function performActions() { var div = document.querySelector("#myDiv"); div.classList.add("my-class"); div.offsetWidth; - callback(); + return Promise.resolve(); } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/timeline/timeline-raf-expected.txt b/third_party/WebKit/LayoutTests/inspector-protocol/timeline/timeline-raf-expected.txt index 99b45c7d..c7986ef9 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/timeline/timeline-raf-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector-protocol/timeline/timeline-raf-expected.txt
@@ -1,6 +1,5 @@ DIV Recording started -SUCCESS: testFunctionRequestAnimationFrame Tracing complete RequestAnimationFrame has frame: true RequestAnimationFrame frames match: true
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/timeline/timeline-raf.html b/third_party/WebKit/LayoutTests/inspector-protocol/timeline/timeline-raf.html index 61d0a958..8aaf9aa 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/timeline/timeline-raf.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/timeline/timeline-raf.html
@@ -4,33 +4,26 @@ <script type="text/javascript" src="../../http/tests/inspector-protocol/tracing-test.js"></script> <script> -function performActions(callback) +function performActions() { - var rafId1 = requestAnimationFrame(function() - { - evaluateInFrontend("InspectorTest.testFunctionRequestAnimationFrame(" + rafId1 + ", " + rafId2 + ")"); - callback(); - }); - - var rafId2 = requestAnimationFrame(function() { }); + var callback; + var promise = new Promise((fulfill) => callback = fulfill); + var rafId2; + var rafId1 = requestAnimationFrame(() => callback({ rafId1: rafId1, rafId2: rafId2 })); + rafId2 = requestAnimationFrame(function() { }); cancelAnimationFrame(rafId2); + return promise; } function test() { InspectorTest.invokeAsyncWithTracing("performActions", finish); - var firedRaf; - var canceledRaf; - InspectorTest.testFunctionRequestAnimationFrame = function(rafId1, rafId2) + function finish(devtoolsEvents, data) { - firedRaf = rafId1; - canceledRaf = rafId2; - InspectorTest.log("SUCCESS: testFunctionRequestAnimationFrame"); - } + var firedRaf = data.rafId1; + var canceledRaf = data.rafId2; - function finish(devtoolsEvents) - { function hasRafId(id, e) { return e.args.data.id === id} var raf1 = InspectorTest.findEvent("RequestAnimationFrame", "I", hasRafId.bind(this, firedRaf));
diff --git a/third_party/WebKit/LayoutTests/inspector-protocol/timeline/timeline-timer.html b/third_party/WebKit/LayoutTests/inspector-protocol/timeline/timeline-timer.html index d0d4e2d2..78b64b5 100644 --- a/third_party/WebKit/LayoutTests/inspector-protocol/timeline/timeline-timer.html +++ b/third_party/WebKit/LayoutTests/inspector-protocol/timeline/timeline-timer.html
@@ -4,8 +4,10 @@ <script type="text/javascript" src="../../http/tests/inspector-protocol/tracing-test.js"></script> <script> -function performActions(callback) +function performActions() { + var callback; + var promise = new Promise((fulfill) => callback = fulfill); var timerId = setTimeout(function() { evaluateInFrontend("InspectorTest.testFunctionTimerFired(" + timerId + ", " + timerId2 + ")"); @@ -14,7 +16,7 @@ var timerId2 = setTimeout(function() { }, 0); clearTimeout(timerId2); - return timerId; + return promise; } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-log-side-effects-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-log-side-effects-expected.txt index 5a83773..2590455 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/console-log-side-effects-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/console/console-log-side-effects-expected.txt
@@ -7,7 +7,7 @@ CONSOLE MESSAGE: line 23: -Infinity CONSOLE MESSAGE: line 24: 0 CONSOLE MESSAGE: line 25: 42 -CONSOLE MESSAGE: line 26: -4.24200e-11 +CONSOLE MESSAGE: line 26: -4.242e-11 CONSOLE MESSAGE: line 27: true CONSOLE MESSAGE: line 28: foo CONSOLE MESSAGE: line 29: [object Object]
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-save-to-temp-var.html b/third_party/WebKit/LayoutTests/inspector/console/console-save-to-temp-var.html index 5ade9da7..8a49a21 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/console-save-to-temp-var.html +++ b/third_party/WebKit/LayoutTests/inspector/console/console-save-to-temp-var.html
@@ -40,9 +40,9 @@ return; } - function didEvaluate(result, wasThrown) + function didEvaluate(result, exceptionDetails) { - InspectorTest.assertTrue(!wasThrown, "FAIL: was thrown. Expression: " + expression); + InspectorTest.assertTrue(!exceptionDetails, "FAIL: was thrown. Expression: " + expression); WebInspector.panels.sources._saveToTempVariable(result); InspectorTest.waitUntilNthMessageReceived(2, evaluateNext); }
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-tainted-globals.html b/third_party/WebKit/LayoutTests/inspector/console/console-tainted-globals.html index 5c0ad39..329ed5e 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/console-tainted-globals.html +++ b/third_party/WebKit/LayoutTests/inspector/console/console-tainted-globals.html
@@ -158,7 +158,7 @@ { InspectorTest.RuntimeAgent.evaluate("({ a : 1, b : 2 })", step1); - function step1(error, result, wasThrown) + function step1(error, result) { function sum() { @@ -167,7 +167,7 @@ InspectorTest.RuntimeAgent.callFunctionOn(result.objectId, sum.toString(), step2); } - function step2(error, result, wasThrown) + function step2(error, result) { InspectorTest.assertEquals(3, result.value); next();
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-viewport-stick-to-bottom-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-viewport-stick-to-bottom-expected.txt index e3888ae..943b798 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/console-viewport-stick-to-bottom-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/console/console-viewport-stick-to-bottom-expected.txt
@@ -603,11 +603,28 @@ Viewport contains 13 messages Running: testScrollViewportToBottom -Last visible message: 149 +Is at bottom: true, should stick: true Running: testConsoleSticksToBottom -Last visible message: 299 +Is at bottom: true, should stick: true -Running: testManualScrollDoesNotStickToBottom -Scroll preserved: true +Running: testSmoothScrollDoesNotStickToBottom +Is at bottom: false, should stick: false + +Running: testEscShouldNotJumpToBottom +Is at bottom: false, should stick: false + +Running: testTypingShouldJumpToBottom +Is at bottom: true, should stick: true + +Running: testViewportMutationsShouldPreserveStickToBottom +Is at bottom: true, should stick: true +Is at bottom: false, should stick: false + +Running: testMuteUpdatesWhileScrolling +New messages were muted: true +Refresh was scheduled after dirty state + +Running: testShouldNotJumpToBottomWhenPromptFillsEntireViewport +Is at bottom: false, should stick: true
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-viewport-stick-to-bottom.html b/third_party/WebKit/LayoutTests/inspector/console/console-viewport-stick-to-bottom.html index fc4901a..2d7a9f5 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/console-viewport-stick-to-bottom.html +++ b/third_party/WebKit/LayoutTests/inspector/console/console-viewport-stick-to-bottom.html
@@ -17,7 +17,8 @@ function test() { - InspectorTest.fixConsoleViewportDimensions(600, 200); + var viewportHeight = 200; + InspectorTest.fixConsoleViewportDimensions(600, viewportHeight); var consoleView = WebInspector.ConsoleView.instance(); var viewport = consoleView._viewport; const minimumViewportMessagesCount = 10; @@ -45,9 +46,7 @@ function testScrollViewportToBottom(next) { consoleView._immediatelyScrollToBottom(); - viewport.refresh(); - InspectorTest.addResult("Last visible message: " + viewport.lastVisibleIndex()); - next(); + dumpAndContinue(next); }, function testConsoleSticksToBottom(next) @@ -56,27 +55,114 @@ function onMessagesDumped() { - viewport.invalidate(); - // Force refresh which has been scheduled via invalidate() method. - viewport.refresh(); - InspectorTest.addResult("Last visible message: " + viewport.lastVisibleIndex()); + dumpAndContinue(next); + } + }, + + function testSmoothScrollDoesNotStickToBottom(next) + { + InspectorTest.addSniffer(WebInspector.ConsoleView.prototype, "_updateViewportStickinessForTest", onUpdateTimeout); + sendPageUp(); + + function onUpdateTimeout() + { + dumpAndContinue(next); + } + }, + + function testEscShouldNotJumpToBottom(next) + { + var keyEvent = InspectorTest.createKeyEvent("Escape"); + viewport._contentElement.dispatchEvent(keyEvent); + dumpAndContinue(next); + }, + + function testTypingShouldJumpToBottom(next) + { + var keyEvent = InspectorTest.createKeyEvent("a"); + viewport._contentElement.dispatchEvent(keyEvent); + consoleView._prompt._proxyElement.dispatchEvent(new Event('input')); + + dumpAndContinue(next); + }, + + function testViewportMutationsShouldPreserveStickToBottom(next) + { + viewport._contentElement.children[1].innerText = "More than 2 lines: foo\n\nbar"; + dumpAndContinue(onMessagesDumped); + + function onMessagesDumped() + { + viewport.setStickToBottom(false); + viewport._contentElement.children[1].innerText = "More than 3 lines: foo\n\n\nbar"; + dumpAndContinue(next); + } + }, + + function testMuteUpdatesWhileScrolling(next) + { + consoleView._updateStickToBottomOnMouseDown(); + viewport.element.scrollTop -= 10; + + InspectorTest.addSniffer(WebInspector.ConsoleView.prototype, "_scheduleViewportRefreshForTest", onMessageAdded); + InspectorTest.evaluateInConsole("1 + 1"); + + /** + * @param {boolean} muted + */ + function onMessageAdded(muted) + { + InspectorTest.addResult("New messages were muted: " + muted); + InspectorTest.addSniffer(WebInspector.ConsoleView.prototype, "_scheduleViewportRefreshForTest", onMouseUpScheduledRefresh); + InspectorTest.addSniffer(WebInspector.ConsoleView.prototype, "_updateViewportStickinessForTest", onUpdateStickiness); + consoleView._updateStickToBottomOnMouseUp(); + } + + /** + * @param {boolean} muted + */ + function onMouseUpScheduledRefresh(muted) + { + InspectorTest.addResult("Refresh was scheduled after dirty state"); + } + + function onUpdateStickiness() + { next(); } }, - function testManualScrollDoesNotStickToBottom(next) + function testShouldNotJumpToBottomWhenPromptFillsEntireViewport(next) { - const manualScrollValue = 3; - var initialScrollTop = viewport.element.scrollTop; - viewport.element.scrollTop = initialScrollTop - manualScrollValue; - viewport.refresh(); - var newScrollTop = viewport.element.scrollTop; - var isScrollPreserved = initialScrollTop - newScrollTop === manualScrollValue; - InspectorTest.addResult("Scroll preserved: " + isScrollPreserved); - next(); - }, + var text = "Foo"; + for (var i = 0; i < viewportHeight; i++) + text += "\n"; + consoleView._promptElement.textContent = text; + WebInspector.ConsoleView.clearConsole(); + viewport.element.scrollTop -= 10; + + var keyEvent = InspectorTest.createKeyEvent("a"); + viewport._contentElement.dispatchEvent(keyEvent); + consoleView._prompt._proxyElement.dispatchEvent(new Event('input')); + + dumpAndContinue(next); + } ]; + function sendPageUp() + { + var keyEvent = InspectorTest.createKeyEvent("PageUp"); + consoleView._prompt._proxyElement.dispatchEvent(keyEvent); + viewport.element.scrollTop -= 10; + } + + function dumpAndContinue(callback) + { + viewport.refresh(); + InspectorTest.addResult("Is at bottom: " + viewport.element.isScrolledToBottom() + ", should stick: " + viewport.stickToBottom()); + callback(); + } + function logMessagesToConsole(count, callback) { var awaitingMessagesCount = count;
diff --git a/third_party/WebKit/LayoutTests/inspector/console/inspect-html-all-collection.html b/third_party/WebKit/LayoutTests/inspector/console/inspect-html-all-collection.html index d044a1fe..251cb39 100644 --- a/third_party/WebKit/LayoutTests/inspector/console/inspect-html-all-collection.html +++ b/third_party/WebKit/LayoutTests/inspector/console/inspect-html-all-collection.html
@@ -6,9 +6,9 @@ function test() { InspectorTest.RuntimeAgent.evaluate("document.all", "console", false, didGetHTMLAllCollection.bind(this)); - function didGetHTMLAllCollection(error, result, wasThrown) + function didGetHTMLAllCollection(error, result, exceptionDetails) { - if (error || wasThrown) { + if (error || exceptionDetails) { InspectorTest.addResult("FAILED: " + error); InspectorTest.completeTest(); return;
diff --git a/third_party/WebKit/LayoutTests/inspector/domdebugger/domdebugger-getEventListeners.html b/third_party/WebKit/LayoutTests/inspector/domdebugger/domdebugger-getEventListeners.html index 875d7e56..183014f 100644 --- a/third_party/WebKit/LayoutTests/inspector/domdebugger/domdebugger-getEventListeners.html +++ b/third_party/WebKit/LayoutTests/inspector/domdebugger/domdebugger-getEventListeners.html
@@ -31,19 +31,19 @@ { InspectorTest.RuntimeAgent.evaluate("window", "get-event-listeners-test", step1); - function step1(error, result, wasThrown) + function step1(error, result, exceptionDetails) { windowObject = InspectorTest.runtimeModel.createRemoteObject(result); InspectorTest.RuntimeAgent.evaluate("document.getElementById(\"with-handlers\")", "get-event-listeners-test", step2); } - function step2(error, result, wasThrown) + function step2(error, result, exceptionDetails) { divWithHandlers = InspectorTest.runtimeModel.createRemoteObject(result); InspectorTest.RuntimeAgent.evaluate("document.getElementById(\"without-handlers\")", "get-event-listeners-test", step3); } - function step3(error, result, wasThrown) + function step3(error, result, exceptionDetails) { divWithoutHandlers = InspectorTest.runtimeModel.createRemoteObject(result); next();
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/css-rule-hover-highlights-selectors.html b/third_party/WebKit/LayoutTests/inspector/elements/css-rule-hover-highlights-selectors.html index 1795954..62a3434 100644 --- a/third_party/WebKit/LayoutTests/inspector/elements/css-rule-hover-highlights-selectors.html +++ b/third_party/WebKit/LayoutTests/inspector/elements/css-rule-hover-highlights-selectors.html
@@ -9,6 +9,11 @@ </style> <script> +function requestAnimationFramePromise() +{ + return new Promise(fulfill => requestAnimationFrame(fulfill)); +} + function buildShadowDOM() { var host = document.querySelector("body"); @@ -42,7 +47,7 @@ { var section = InspectorTest.firstMatchedStyleSection(); section._highlight(); - InspectorTest.waitForOverlayRepaint(onHighlighted); + InspectorTest.callFunctionInPageAsync("requestAnimationFramePromise").then(onHighlighted) } function onHighlighted() @@ -64,7 +69,7 @@ { var section = InspectorTest.firstMatchedStyleSection(); section._highlight(); - InspectorTest.waitForOverlayRepaint(onHighlighted); + InspectorTest.callFunctionInPageAsync("requestAnimationFramePromise").then(onHighlighted) } function onHighlighted()
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/resolve-alien-node.html b/third_party/WebKit/LayoutTests/inspector/elements/resolve-alien-node.html index 69d867d..c33ff51d8 100644 --- a/third_party/WebKit/LayoutTests/inspector/elements/resolve-alien-node.html +++ b/third_party/WebKit/LayoutTests/inspector/elements/resolve-alien-node.html
@@ -7,7 +7,7 @@ { InspectorTest.RuntimeAgent.evaluate("var doc = document.implementation.createHTMLDocument(''); doc.lastChild.innerHTML = '<span></span>'; doc.lastChild", step1); - function step1(error, result, wasThrown) + function step1(error, result, exceptionDetails) { var spanWrapper = InspectorTest.runtimeModel.createRemoteObject(result); InspectorTest.domModel.pushObjectAsNodeToFrontend(spanWrapper, step2);
diff --git a/third_party/WebKit/LayoutTests/inspector/elements/resolve-node-blocked.html b/third_party/WebKit/LayoutTests/inspector/elements/resolve-node-blocked.html index bc0f0f69..c684567 100644 --- a/third_party/WebKit/LayoutTests/inspector/elements/resolve-node-blocked.html +++ b/third_party/WebKit/LayoutTests/inspector/elements/resolve-node-blocked.html
@@ -7,7 +7,7 @@ function test() { InspectorTest.evaluateInPage("document", didReceiveDocumentObject); - function didReceiveDocumentObject(remoteObject, wasThrown) + function didReceiveDocumentObject(remoteObject) { InspectorTest.addResult("didReceiveDocumentObject"); InspectorTest.DOMAgent.requestNode(remoteObject.objectId, didRequestNode);
diff --git a/third_party/WebKit/LayoutTests/inspector/extensions/extensions-resources.html b/third_party/WebKit/LayoutTests/inspector/extensions/extensions-resources.html index 31573919..b45d798 100644 --- a/third_party/WebKit/LayoutTests/inspector/extensions/extensions-resources.html +++ b/third_party/WebKit/LayoutTests/inspector/extensions/extensions-resources.html
@@ -5,12 +5,15 @@ <script src="../../http/tests/inspector/extensions-test.js"></script> <script src="../../http/tests/inspector/debugger-test.js"></script> <script type="text/javascript"> -function loadFrame(callback) +function loadFrame() { + var callback; + var promise = new Promise((fulfill) => callback = fulfill); var iframe = document.createElement("iframe"); iframe.src = "resources/subframe.html"; iframe.addEventListener("load", callback); document.body.appendChild(iframe); + return promise; } function logMessage()
diff --git a/third_party/WebKit/LayoutTests/inspector/local-object.html b/third_party/WebKit/LayoutTests/inspector/local-object.html index feb054e9..265f628 100644 --- a/third_party/WebKit/LayoutTests/inspector/local-object.html +++ b/third_party/WebKit/LayoutTests/inspector/local-object.html
@@ -26,14 +26,14 @@ return "Done"; } - function compareAndSwapCallback(result, wasThrown) + function compareAndSwapCallback(result) { InspectorTest.addResult("compareAndSwap(1, 28, 42) result: " + result.description); } - function exceptionCallback(result, wasThrown) + function exceptionCallback(result, exceptionDetails) { - InspectorTest.addResult("compareAndSwap(1, 28, 42) throws exception: " + wasThrown); + InspectorTest.addResult("compareAndSwap(1, 28, 42) throws exception: " + !!exceptionDetails); } function guessWhat() @@ -41,7 +41,7 @@ return 42; } - function guessWhatCallback(result, wasThrown) + function guessWhatCallback(result) { InspectorTest.addResult("guessWhat() result: " + result.description); }
diff --git a/third_party/WebKit/LayoutTests/inspector/runtime/runtime-callFunctionOn.html b/third_party/WebKit/LayoutTests/inspector/runtime/runtime-callFunctionOn.html index 5851469..ce8d50f2 100644 --- a/third_party/WebKit/LayoutTests/inspector/runtime/runtime-callFunctionOn.html +++ b/third_party/WebKit/LayoutTests/inspector/runtime/runtime-callFunctionOn.html
@@ -12,7 +12,7 @@ { InspectorTest.RuntimeAgent.evaluate("({ a : 1, b : 2 })", step1); - function step1(error, result, wasThrown) + function step1(error, result, exceptionDetails) { function sum() @@ -24,7 +24,7 @@ InspectorTest.RuntimeAgent.callFunctionOn(obj1.objectId, sum.toString(), step2); } - function step2(error, result, wasThrown) + function step2(error, result, exceptionDetails) { InspectorTest.addResult(result.value); next(); @@ -35,7 +35,7 @@ { InspectorTest.RuntimeAgent.evaluate("({ c : 1, d : 2 })", step1); - function step1(error, result, wasThrown) + function step1(error, result, exceptionDetails) { function format(aobj1, aobj2, val, undef) { @@ -46,7 +46,7 @@ InspectorTest.RuntimeAgent.callFunctionOn(obj1.objectId, format.toString(), [obj1, obj2, {value:4}, {}], step2); } - function step2(error, result, wasThrown) + function step2(error, result, exceptionDetails) { InspectorTest.addResult(result.value); next();
diff --git a/third_party/WebKit/LayoutTests/inspector/runtime/runtime-es6-setSymbolPropertyValue.html b/third_party/WebKit/LayoutTests/inspector/runtime/runtime-es6-setSymbolPropertyValue.html index a8367911..7298b64 100644 --- a/third_party/WebKit/LayoutTests/inspector/runtime/runtime-es6-setSymbolPropertyValue.html +++ b/third_party/WebKit/LayoutTests/inspector/runtime/runtime-es6-setSymbolPropertyValue.html
@@ -28,13 +28,13 @@ InspectorTest.RuntimeAgent.evaluate("object1", step1); } - function step1(error, result, wasThrown) + function step1(error, result, exceptionDetails) { obj1 = InspectorTest.runtimeModel.createRemoteObject(result); InspectorTest.RuntimeAgent.evaluate("symbol1", step2); } - function step2(error, result, wasThrown) + function step2(error, result, exceptionDetails) { name = WebInspector.RemoteObject.toCallArgument(InspectorTest.runtimeModel.createRemoteObject(result)); next();
diff --git a/third_party/WebKit/LayoutTests/inspector/runtime/runtime-getProperties.html b/third_party/WebKit/LayoutTests/inspector/runtime/runtime-getProperties.html index 40485d4..390af85 100644 --- a/third_party/WebKit/LayoutTests/inspector/runtime/runtime-getProperties.html +++ b/third_party/WebKit/LayoutTests/inspector/runtime/runtime-getProperties.html
@@ -27,13 +27,13 @@ InspectorTest.RuntimeAgent.evaluate("object1", step1); } - function step1(error, result, wasThrown) + function step1(error, result, exceptionDetails) { obj1 = InspectorTest.runtimeModel.createRemoteObject(result); InspectorTest.RuntimeAgent.evaluate("object2", step2); } - function step2(error, result, wasThrown) + function step2(error, result, exceptionDetails) { obj2 = InspectorTest.runtimeModel.createRemoteObject(result); next();
diff --git a/third_party/WebKit/LayoutTests/inspector/runtime/runtime-localStorage-getProperties.html b/third_party/WebKit/LayoutTests/inspector/runtime/runtime-localStorage-getProperties.html index 3cd3420..fe69b1be 100644 --- a/third_party/WebKit/LayoutTests/inspector/runtime/runtime-localStorage-getProperties.html +++ b/third_party/WebKit/LayoutTests/inspector/runtime/runtime-localStorage-getProperties.html
@@ -9,7 +9,7 @@ { InspectorTest.RuntimeAgent.evaluate("localStorage", step1); - function step1(error, result, wasThrown) + function step1(error, result, exceptionDetails) { var localStorageHandle = InspectorTest.runtimeModel.createRemoteObject(result); localStorageHandle.getOwnProperties(step2); @@ -21,7 +21,7 @@ var property = properties[i]; if (property.name !== "testProperty") continue; - property.value = { type: property.value.type, description: property.value.description }; + property.value = { type: property.value.type, description: property.value.description }; InspectorTest.dump(property); } InspectorTest.completeTest();
diff --git a/third_party/WebKit/LayoutTests/inspector/runtime/runtime-setPropertyValue.html b/third_party/WebKit/LayoutTests/inspector/runtime/runtime-setPropertyValue.html index 70d23e1..1ea7fdb 100644 --- a/third_party/WebKit/LayoutTests/inspector/runtime/runtime-setPropertyValue.html +++ b/third_party/WebKit/LayoutTests/inspector/runtime/runtime-setPropertyValue.html
@@ -41,13 +41,13 @@ InspectorTest.RuntimeAgent.evaluate("object1", step1); } - function step1(error, result, wasThrown) + function step1(error, result, exceptionDetails) { obj1 = InspectorTest.runtimeModel.createRemoteObject(result); InspectorTest.RuntimeAgent.evaluate("object2", step2); } - function step2(error, result, wasThrown) + function step2(error, result, exceptionDetails) { obj2 = InspectorTest.runtimeModel.createRemoteObject(result); next();
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/event-listener-breakpoints-after-suspension.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/event-listener-breakpoints-after-suspension.html index 77bb60e5..f8d2ca1 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/event-listener-breakpoints-after-suspension.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/event-listener-breakpoints-after-suspension.html
@@ -22,7 +22,7 @@ function start() { - var pane = WebInspector.panels.sources.sidebarPanes.eventListenerBreakpoints; + var pane = self.runtime.sharedInstance(WebInspector.EventListenerBreakpointsSidebarPane); pane._setBreakpoint("listener:click"); InspectorTest.waitUntilPaused(paused); InspectorTest.evaluateInPageWithTimeout("addListenerAndClick()");
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/event-listener-breakpoints-script-first-stmt.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/event-listener-breakpoints-script-first-stmt.html index 33eda60..a4f1230 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/event-listener-breakpoints-script-first-stmt.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/event-listener-breakpoints-script-first-stmt.html
@@ -29,7 +29,7 @@ function test() { - var pane = WebInspector.panels.sources.sidebarPanes.eventListenerBreakpoints; + var pane = self.runtime.sharedInstance(WebInspector.EventListenerBreakpointsSidebarPane); var numberOfPauses = 2; InspectorTest.startDebuggerTest(step1, true);
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/event-listener-breakpoints-xhr.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/event-listener-breakpoints-xhr.html index 67143891..1d40b4f2 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/event-listener-breakpoints-xhr.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/event-listener-breakpoints-xhr.html
@@ -49,7 +49,7 @@ function test() { - var pane = WebInspector.panels.sources.sidebarPanes.eventListenerBreakpoints; + var pane = self.runtime.sharedInstance(WebInspector.EventListenerBreakpointsSidebarPane); var xhrTargetNames = ["XMLHttpRequest", "XMLHttpRequestUpload"]; InspectorTest.setQuiet(true);
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/event-listener-breakpoints.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/event-listener-breakpoints.html index 9f4619d..68727f7 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/event-listener-breakpoints.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/event-listener-breakpoints.html
@@ -65,7 +65,7 @@ function test() { - var pane = WebInspector.panels.sources.sidebarPanes.eventListenerBreakpoints; + var pane = self.runtime.sharedInstance(WebInspector.EventListenerBreakpointsSidebarPane); var testFunctions = [ function testClickBreakpoint(next) {
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/xhr-breakpoints.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/xhr-breakpoints.html index fedace4..c2c01cc 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/xhr-breakpoints.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-breakpoints/xhr-breakpoints.html
@@ -13,7 +13,7 @@ function test() { - var pane = WebInspector.panels.sources.sidebarPanes.xhrBreakpoints; + var pane = self.runtime.sharedInstance(WebInspector.XHRBreakpointsSidebarPane); InspectorTest.runDebuggerTestSuite([ function testXHRBreakpoint(next) {
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-frameworks/frameworks-dom-xhr-event-breakpoints.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-frameworks/frameworks-dom-xhr-event-breakpoints.html index 2727749..d43006369 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-frameworks/frameworks-dom-xhr-event-breakpoints.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-frameworks/frameworks-dom-xhr-event-breakpoints.html
@@ -93,7 +93,7 @@ function testXHRBreakpoint(next) { - var pane = WebInspector.panels.sources.sidebarPanes.xhrBreakpoints; + var pane = self.runtime.sharedInstance(WebInspector.XHRBreakpointsSidebarPane); pane._setBreakpoint("foo", true); InspectorTest.evaluateInPageWithTimeout("sendXHR('/foo?a=b')"); InspectorTest.waitUntilPausedAndDumpStackAndResume(next); @@ -101,7 +101,7 @@ function testEventListenerBreakpoint(next) { - var pane = WebInspector.panels.sources.sidebarPanes.eventListenerBreakpoints; + var pane = self.runtime.sharedInstance(WebInspector.EventListenerBreakpointsSidebarPane); pane._setBreakpoint("listener:click"); InspectorTest.evaluateInPageWithTimeout("addListenerAndClick(false)"); InspectorTest.waitUntilPausedAndPerformSteppingActions([ @@ -112,7 +112,7 @@ function testSteppingThroughEventListenerBreakpoint(next) { - var pane = WebInspector.panels.sources.sidebarPanes.eventListenerBreakpoints; + var pane = self.runtime.sharedInstance(WebInspector.EventListenerBreakpointsSidebarPane); pane._setBreakpoint("listener:click"); InspectorTest.evaluateInPageWithTimeout("addListenerAndClick(true)"); InspectorTest.waitUntilPausedAndPerformSteppingActions([ @@ -127,7 +127,7 @@ function testSteppingOutOnEventListenerBreakpoint(next) { - var pane = WebInspector.panels.sources.sidebarPanes.eventListenerBreakpoints; + var pane = self.runtime.sharedInstance(WebInspector.EventListenerBreakpointsSidebarPane); pane._setBreakpoint("listener:click"); InspectorTest.evaluateInPageWithTimeout("addListenerAndClick(true)"); InspectorTest.waitUntilPausedAndPerformSteppingActions([ @@ -140,7 +140,7 @@ function testSteppingOutOnEventListenerBreakpointAllBlackboxed(next) { - var pane = WebInspector.panels.sources.sidebarPanes.eventListenerBreakpoints; + var pane = self.runtime.sharedInstance(WebInspector.EventListenerBreakpointsSidebarPane); pane._setBreakpoint("listener:click"); InspectorTest.evaluateInPageWithTimeout("addFewBlackboxedListenersAndClick(false)"); InspectorTest.waitUntilPausedAndPerformSteppingActions([ @@ -151,7 +151,7 @@ function testSteppingOutOnEventListenerBreakpointAllBlackboxedButOne(next) { - var pane = WebInspector.panels.sources.sidebarPanes.eventListenerBreakpoints; + var pane = self.runtime.sharedInstance(WebInspector.EventListenerBreakpointsSidebarPane); pane._setBreakpoint("listener:click"); InspectorTest.evaluateInPageWithTimeout("addFewBlackboxedListenersAndClick(true)"); InspectorTest.waitUntilPausedAndPerformSteppingActions([ @@ -164,8 +164,8 @@ function tearDown(next) { - WebInspector.panels.sources.sidebarPanes.xhrBreakpoints._removeBreakpoint("foo"); - WebInspector.panels.sources.sidebarPanes.eventListenerBreakpoints._removeBreakpoint("listener:click"); + self.runtime.sharedInstance(WebInspector.XHRBreakpointsSidebarPane)._removeBreakpoint("foo"); + self.runtime.sharedInstance(WebInspector.EventListenerBreakpointsSidebarPane)._removeBreakpoint("listener:click"); next(); } ]);
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-frameworks/frameworks-skip-break-program.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-frameworks/frameworks-skip-break-program.html index 4d9e711..94a64f5 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-frameworks/frameworks-skip-break-program.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-frameworks/frameworks-skip-break-program.html
@@ -27,7 +27,7 @@ var frameworkRegexString = "/framework\\.js$"; WebInspector.settingForTest("skipStackFramesPattern").set(frameworkRegexString); - var pane = WebInspector.panels.sources.sidebarPanes.eventListenerBreakpoints; + var pane = self.runtime.sharedInstance(WebInspector.EventListenerBreakpointsSidebarPane); InspectorTest.startDebuggerTest(step1, true);
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-frameworks/frameworks-step-from-framework.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-frameworks/frameworks-step-from-framework.html index c01dde01..5a43b31 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-frameworks/frameworks-step-from-framework.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-frameworks/frameworks-step-from-framework.html
@@ -25,7 +25,7 @@ function step1() { - xhrPane = WebInspector.panels.sources.sidebarPanes.xhrBreakpoints; + xhrPane = self.runtime.sharedInstance(WebInspector.XHRBreakpointsSidebarPane); xhrPane._setBreakpoint("foo", true); InspectorTest.runTestFunctionAndWaitUntilPaused(step2); }
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-pause/skip-pauses-until-reload.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-pause/skip-pauses-until-reload.html index 812fc0d..eed5d26 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-pause/skip-pauses-until-reload.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-pause/skip-pauses-until-reload.html
@@ -82,7 +82,7 @@ function setUpEventBreakpoints() { testRunner.logToStderr("setUpEventBreakpoints"); - var pane = WebInspector.panels.sources.sidebarPanes.eventListenerBreakpoints; + var pane = self.runtime.sharedInstance(WebInspector.EventListenerBreakpointsSidebarPane); InspectorTest.addResult("Set up Event breakpoints."); pane._setBreakpoint("listener:click"); InspectorTest.deprecatedRunAfterPendingDispatches(didSetUp); @@ -136,7 +136,7 @@ function completeTest() { testRunner.logToStderr("completeTest"); - var pane = WebInspector.panels.sources.sidebarPanes.eventListenerBreakpoints; + var pane = self.runtime.sharedInstance(WebInspector.EventListenerBreakpointsSidebarPane); pane._removeBreakpoint("listener:click"); InspectorTest.completeDebuggerTest(); }
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-step/step-through-event-listeners.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-step/step-through-event-listeners.html index 48f8ac1c..f3130dfc 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-step/step-through-event-listeners.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-step/step-through-event-listeners.html
@@ -28,7 +28,7 @@ function test() { - var pane = WebInspector.panels.sources.sidebarPanes.eventListenerBreakpoints; + var pane = self.runtime.sharedInstance(WebInspector.EventListenerBreakpointsSidebarPane); InspectorTest.runDebuggerTestSuite([ function testClickBreakpoint(next) {
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/break-on-empty-event-listener.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/break-on-empty-event-listener.html index aa6afe09..bf8b76da 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/break-on-empty-event-listener.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/break-on-empty-event-listener.html
@@ -21,19 +21,20 @@ var test = function() { + var pane = self.runtime.sharedInstance(WebInspector.EventListenerBreakpointsSidebarPane); InspectorTest.startDebuggerTest(step1, true); function step1() { var actions = [ "Print" ]; InspectorTest.waitUntilPausedAndPerformSteppingActions(actions, step2); - WebInspector.panels.sources.sidebarPanes.eventListenerBreakpoints._setBreakpoint("listener:click"); + pane._setBreakpoint("listener:click"); InspectorTest.evaluateInPageWithTimeout("addEmptyEventListenerAndClick()"); } function step2() { - WebInspector.panels.sources.sidebarPanes.eventListenerBreakpoints._removeBreakpoint("listener:click"); + pane._removeBreakpoint("listener:click"); InspectorTest.completeDebuggerTest(); } }
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/debugger-save-to-temp-var.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/debugger-save-to-temp-var.html index 5e38295..199bd60 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/debugger-save-to-temp-var.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/debugger-save-to-temp-var.html
@@ -81,9 +81,9 @@ return; } - function didEvaluate(result, wasThrown) + function didEvaluate(result, exceptionDetails) { - InspectorTest.assertTrue(!wasThrown, "FAIL: was thrown. Expression: " + expression); + InspectorTest.assertTrue(!exceptionDetails, "FAIL: was thrown. Expression: " + expression); WebInspector.panels.sources._saveToTempVariable(result); InspectorTest.waitUntilNthMessageReceived(2, evaluateNext); }
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/script-snippet-model.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/script-snippet-model.html index 4f2a1bd..0c949ff 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/script-snippet-model.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/script-snippet-model.html
@@ -24,7 +24,7 @@ InspectorTest.assertEquals(snippetId, WebInspector.scriptSnippetModel._snippetIdForSourceURL(evaluationSourceURL), "Snippet can not be identified by its evaluation sourceURL."); - function dumpResult(target, result, wasThrown) + function dumpResult(target, result) { InspectorTest.addResult("Snippet execution result: " + result.description); callback(); @@ -230,7 +230,7 @@ InspectorTest.addSniffer(WebInspector.ScriptSnippetModel.prototype, "_printRunScriptResult", snippetFinished); WebInspector.scriptSnippetModel.evaluateScriptSnippet(WebInspector.context.flavor(WebInspector.ExecutionContext), uiSourceCode); - function snippetFinished(result, wasThrown) + function snippetFinished(result) { var script = snippetScriptMapping._scriptForUISourceCode.get(uiSourceCode); InspectorTest.addResult("Snippet execution result: " + result.description);
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/show-function-definition.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/show-function-definition.html index afcff3c..38fdb71 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/show-function-definition.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/show-function-definition.html
@@ -20,9 +20,9 @@ InspectorTest.addSniffer(panel, "showUISourceCode", showUISourceCodeHook); WebInspector.context.flavor(WebInspector.ExecutionContext).evaluate("jumpToMe", "", false, true, false, false, false, didGetFunction); - function didGetFunction(funcObject, wasThrown) + function didGetFunction(funcObject, exceptionDetails) { - var error = !funcObject || wasThrown; + var error = !funcObject || !!exceptionDetails; InspectorTest.assertTrue(!error); panel._showFunctionDefinition(funcObject); }
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger/debugger-compile-and-run.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger/debugger-compile-and-run.html index 6ace306..15d23ff0 100644 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger/debugger-compile-and-run.html +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger/debugger-compile-and-run.html
@@ -41,10 +41,10 @@ InspectorTest.RuntimeAgent.runScript(scriptId, contextId, "console", false, runCallback.bind(this)); } - function runCallback(error, result, wasThrown, exceptionDetails) + function runCallback(error, result, exceptionDetails) { InspectorTest.assertTrue(!error); - InspectorTest.assertTrue(!wasThrown); + InspectorTest.assertTrue(!exceptionDetails); InspectorTest.addResult("Script result: " + result.value); next(); } @@ -65,10 +65,10 @@ InspectorTest.RuntimeAgent.runScript(scriptId, contextId, "console", false, runCallback.bind(this)); } - function runCallback(error, result, wasThrown, exceptionDetails) + function runCallback(error, result, exceptionDetails) { InspectorTest.assertTrue(!error); - InspectorTest.assertTrue(wasThrown); + InspectorTest.assertTrue(!!exceptionDetails); printExceptionDetails(exceptionDetails); next(); }
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger/dont-report-injected-script-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger/dont-report-injected-script-expected.txt new file mode 100644 index 0000000..e654302a --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger/dont-report-injected-script-expected.txt
@@ -0,0 +1,6 @@ +CONSOLE MESSAGE: line 1: 42 +Tests that injected script isn't reported to frontend. + +foo.js +239.js +
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger/dont-report-injected-script.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger/dont-report-injected-script.html new file mode 100644 index 0000000..c7bf0e2c --- /dev/null +++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger/dont-report-injected-script.html
@@ -0,0 +1,34 @@ +<html> +<head> +<script src="../../../http/tests/inspector/inspector-test.js"></script> +<script src="../../../http/tests/inspector/console-test.js"></script> + +<script> +function newWorld() +{ + testRunner.evaluateScriptInIsolatedWorld(239, "console.log(42);\n//# sourceURL=239.js"); +} + +function test() +{ + InspectorTest.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, step2); + InspectorTest.evaluateInPage("newWorld()\n//# sourceURL=foo.js"); + + var expectedScriptParsed = 2; + function step2(event) + { + var script = event.data; + InspectorTest.addResult(script.sourceURL); + --expectedScriptParsed; + if (!expectedScriptParsed) + InspectorTest.completeTest(); + } +} +</script> +</head> +<body onload="runTest()"> +<p> +Tests that injected script isn't reported to frontend. +</p> +</body> +</html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger/internal-script-flag-for-injected-script-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger/internal-script-flag-for-injected-script-expected.txt deleted file mode 100644 index 67d14e7..0000000 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger/internal-script-flag-for-injected-script-expected.txt +++ /dev/null
@@ -1,6 +0,0 @@ -CONSOLE MESSAGE: line 1: 42 -Tests that injected script has isInternalScript flag. - -:Internal script -foo.js:Not internal script -
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger/internal-script-flag-for-injected-script.html b/third_party/WebKit/LayoutTests/inspector/sources/debugger/internal-script-flag-for-injected-script.html deleted file mode 100644 index 26679c6f..0000000 --- a/third_party/WebKit/LayoutTests/inspector/sources/debugger/internal-script-flag-for-injected-script.html +++ /dev/null
@@ -1,34 +0,0 @@ -<html> -<head> -<script src="../../../http/tests/inspector/inspector-test.js"></script> -<script src="../../../http/tests/inspector/console-test.js"></script> - -<script> -function newWorld() -{ - testRunner.evaluateScriptInIsolatedWorld(239, "console.log(42);\n//# sourceURL=239.js"); -} - -function test() -{ - InspectorTest.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.ParsedScriptSource, step2); - InspectorTest.evaluateInPage("newWorld()\n//# sourceURL=foo.js"); - - var expectedScriptParsed = 2; - function step2(event) - { - var script = event.data; - InspectorTest.addResult(script.sourceURL + ":" + (script._isInternalScript ? "Internal script" : "Not internal script")); - --expectedScriptParsed; - if (!expectedScriptParsed) - InspectorTest.completeTest(); - } -} -</script> -</head> -<body onload="runTest()"> -<p> -Tests that injected script has isInternalScript flag. -</p> -</body> -</html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing-session-id.html b/third_party/WebKit/LayoutTests/inspector/tracing-session-id.html index d90cea8c..fe5b0a8 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing-session-id.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing-session-id.html
@@ -6,7 +6,7 @@ <script> function test() { - InspectorTest.invokeWithTracing("(function(callback) { callback(); })", processTracingEvents); + InspectorTest.evaluateWithTimeline("(function() {})", processTracingEvents); function processTracingEvents() {
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/anonymous-image-object.html b/third_party/WebKit/LayoutTests/inspector/tracing/anonymous-image-object.html index 47b299a..9c3ef519 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/anonymous-image-object.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/anonymous-image-object.html
@@ -9,8 +9,10 @@ <script src="../../http/tests/inspector/timeline-test.js"></script> <script> -function doActions(callback) +function doActions() { + var callback; + var promise = new Promise((fulfill) => callback = fulfill); document.getElementById("marker").classList.add("marker"); var img = document.createElement("img"); img.src = "resources/test.bmp"; @@ -19,6 +21,7 @@ { testRunner.layoutAndPaintAsyncThen(callback); } + return promise; } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/decode-resize.html b/third_party/WebKit/LayoutTests/inspector/tracing/decode-resize.html index 2a0d305..830f37b 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/decode-resize.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/decode-resize.html
@@ -37,26 +37,24 @@ ["./resources/big.png", "150", "150"] ]; -function showImages(callback) +function showImages() { - var nextImageIndex = 0; + var promise = Promise.resolve(); + for (let image of images) { + promise = promise + .then(() => addImage(image)) + .then(() => new Promise((fulfill) => testRunner.layoutAndPaintAsyncThen(fulfill))); + } + return promise.then(() => generateFrames(3)); - addImages(); - - function addImages() + function addImage(image) { - if (nextImageIndex >= images.length) { - // Allow several frames for image decoding to complete on rasterizer threads. - generateFrames(3, callback); - return; - } - var imgContainer = document.createElement("div"); imgContainer.className = "img-container"; document.body.appendChild(imgContainer); var imgElement = document.createElement("img"); - imgElement.addEventListener("load", testRunner.layoutAndPaintAsyncThen.bind(testRunner, addImages)); + var promise = new Promise((fulfill) => imgElement.onload = fulfill); imgContainer.appendChild(imgElement); var backgroundElement = document.createElement("div"); @@ -67,16 +65,16 @@ borderElement.className = "border"; document.body.appendChild(borderElement); - var image = images[nextImageIndex++]; imgElement.width = image[1]; imgElement.height = image[2]; imgElement.src = image[0]; backgroundElement.style.backgroundImage = "url(" + image[0] + "?background)"; borderElement.style.borderImage = "url(" + image[0] + "?border)"; + + return promise; } } - function test() { InspectorTest.invokeWithTracing("showImages", InspectorTest.safeWrap(onTracingComplete));
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/frame-model-instrumentation.html b/third_party/WebKit/LayoutTests/inspector/tracing/frame-model-instrumentation.html index 73abca0..a6eb4160 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/frame-model-instrumentation.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/frame-model-instrumentation.html
@@ -5,9 +5,9 @@ <script src="../tracing-test.js"></script> <script> -function doActions(callback) +function doActions() { - generateFrames(3, callback); + return generateFrames(3); } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/scroll-invalidations.html b/third_party/WebKit/LayoutTests/inspector/tracing/scroll-invalidations.html index fc6d9b20..58ca711a 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/scroll-invalidations.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/scroll-invalidations.html
@@ -4,11 +4,12 @@ <script src="../../http/tests/inspector/inspector-test.js"></script> <script src="../../http/tests/inspector/timeline-test.js"></script> <script> -function scrollAndDisplay(callback) +function scrollAndDisplay() { scrollTo(0, 200); if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); + return new Promise((fulfill) => testRunner.layoutAndPaintAsyncThen(fulfill)); + return Promise.reject(); } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-js/timeline-gc-event.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-js/timeline-gc-event.html index bf1d5cd..fb71eb6 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-js/timeline-gc-event.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-js/timeline-gc-event.html
@@ -4,12 +4,13 @@ <script src="../../../http/tests/inspector/timeline-test.js"></script> <script> -function produceGarbageForGCEvents(callback) +function produceGarbageForGCEvents() { if (window.testRunner) { window.gc(); - testRunner.layoutAndPaintAsyncThen(callback); + return new Promise((fulfill) => testRunner.layoutAndPaintAsyncThen(fulfill)); } + return Promise.reject(); } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-js/timeline-script-id-expected.txt b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-js/timeline-script-id-expected.txt index e908e613..cf78174 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-js/timeline-script-id-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-js/timeline-script-id-expected.txt
@@ -2,14 +2,14 @@ It expects two FunctionCall for InjectedScript, two TimerInstall events, two FunctionCall events and one TimerRemove event to be logged with performActions.js script name and some line number. -detailsTextContent for TimerInstall event: 'performActions.js:3' -details.textContent for TimerInstall event: 'performActions.js:3' -detailsTextContent for TimerInstall event: 'performActions.js:4' -details.textContent for TimerInstall event: 'performActions.js:4' -detailsTextContent for FunctionCall event: 'performActions.js:7' -details.textContent for FunctionCall event: 'intervalTimerWork @ performActions.js:7' -detailsTextContent for FunctionCall event: 'performActions.js:7' -details.textContent for FunctionCall event: 'intervalTimerWork @ performActions.js:7' -detailsTextContent for TimerRemove event: 'performActions.js:11' -details.textContent for TimerRemove event: 'performActions.js:11' +detailsTextContent for TimerInstall event: 'performActions.js:5' +details.textContent for TimerInstall event: 'performActions.js:5' +detailsTextContent for TimerInstall event: 'performActions.js:6' +details.textContent for TimerInstall event: 'performActions.js:6' +detailsTextContent for FunctionCall event: 'performActions.js:10' +details.textContent for FunctionCall event: 'intervalTimerWork @ performActions.js:10' +detailsTextContent for FunctionCall event: 'performActions.js:10' +details.textContent for FunctionCall event: 'intervalTimerWork @ performActions.js:10' +detailsTextContent for TimerRemove event: 'performActions.js:14' +details.textContent for TimerRemove event: 'performActions.js:14'
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-js/timeline-script-id.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-js/timeline-script-id.html index b0e22aa7..a2d24aa 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-js/timeline-script-id.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-js/timeline-script-id.html
@@ -6,11 +6,14 @@ function test() { - function performActions(callback) + function performActions() { + var callback; + var promise = new Promise((fulfill) => callback = fulfill); var timerOne = setTimeout("1 + 1", 10); var timerTwo = setInterval(intervalTimerWork, 20); var iteration = 0; + return promise; function intervalTimerWork() {
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-layout/timeline-layout-with-invalidations-expected.txt b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-layout/timeline-layout-with-invalidations-expected.txt index 4ddcd95..973d3fad 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-layout/timeline-layout-with-invalidations-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-layout/timeline-layout-with-invalidations-expected.txt
@@ -6,7 +6,7 @@ Running: testLocalFrame first layout invalidations[ { - cause : {reason: Style changed, stackTrace: .../inspector/tracing/timeline-layout/timeline-layout-with-invalidations.html:11} + cause : {reason: Style changed, stackTrace: .../inspector/tracing/timeline-layout/timeline-layout-with-invalidations.html:10} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -19,7 +19,7 @@ ] second layout invalidations[ { - cause : {reason: Style changed, stackTrace: .../inspector/tracing/timeline-layout/timeline-layout-with-invalidations.html:13} + cause : {reason: Style changed, stackTrace: .../inspector/tracing/timeline-layout/timeline-layout-with-invalidations.html:12} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -34,7 +34,7 @@ Running: testSubframe first layout invalidations[ { - cause : {reason: Style changed, stackTrace: .../inspector/tracing/timeline-layout/timeline-layout-with-invalidations.html:23} + cause : {reason: Style changed, stackTrace: .../inspector/tracing/timeline-layout/timeline-layout-with-invalidations.html:19} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -47,7 +47,7 @@ ] second layout invalidations[ { - cause : {reason: Style changed, stackTrace: .../inspector/tracing/timeline-layout/timeline-layout-with-invalidations.html:25} + cause : {reason: Style changed, stackTrace: .../inspector/tracing/timeline-layout/timeline-layout-with-invalidations.html:21} changedAttribute : undefined changedClass : undefined changedId : undefined
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-layout/timeline-layout-with-invalidations.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-layout/timeline-layout-with-invalidations.html index 0c16a28..f91a977 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-layout/timeline-layout-with-invalidations.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-layout/timeline-layout-with-invalidations.html
@@ -4,28 +4,22 @@ <script src="../../../http/tests/inspector/inspector-test.js"></script> <script src="../../../http/tests/inspector/timeline-test.js"></script> <script> -function display(callback) +function display() { - requestAnimationFrame(function() { - document.getElementById("testElement").style.width = "100px"; - var forceLayout1 = document.body.offsetTop; - document.getElementById("testElement").style.width = "110px"; - var forceLayout2 = document.body.offsetTop; - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + document.getElementById("testElement").style.width = "100px"; + var forceLayout1 = document.body.offsetTop; + document.getElementById("testElement").style.width = "110px"; + var forceLayout2 = document.body.offsetTop; + return waitForFrame(); } -function updateSubframeAndDisplay(callback) +function updateSubframeAndDisplay() { - requestAnimationFrame(function() { - frames[0].document.body.children[0].style.width = "10px"; - var forceLayout1 = frames[0].document.body.offsetTop; - frames[0].document.body.children[0].style.width = "20px"; - var forceLayout2 = frames[0].document.body.offsetTop; - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + frames[0].document.body.children[0].style.width = "10px"; + var forceLayout1 = frames[0].document.body.offsetTop; + frames[0].document.body.children[0].style.width = "20px"; + var forceLayout2 = frames[0].document.body.offsetTop; + return waitForFrame(); } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-animation-frame-expected.txt b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-animation-frame-expected.txt index 2022df56..0d7b14d 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-animation-frame-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-animation-frame-expected.txt
@@ -13,7 +13,7 @@ startTime : <number> type : "RequestAnimationFrame" } -Text details for RequestAnimationFrame: timeline-animation-frame.html:8 +Text details for RequestAnimationFrame: timeline-animation-frame.html:10 FireAnimationFrame Properties: { data : { @@ -25,7 +25,7 @@ startTime : <number> type : "FireAnimationFrame" } -Text details for FireAnimationFrame: timeline-animation-frame.html:8 +Text details for FireAnimationFrame: timeline-animation-frame.html:10 CancelAnimationFrame Properties: { data : { @@ -39,5 +39,5 @@ startTime : <number> type : "CancelAnimationFrame" } -Text details for CancelAnimationFrame: timeline-animation-frame.html:11 +Text details for CancelAnimationFrame: timeline-animation-frame.html:13
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-animation-frame.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-animation-frame.html index 6556301..05e61177 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-animation-frame.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-animation-frame.html
@@ -3,8 +3,10 @@ <script src="../../../http/tests/inspector/inspector-test.js"></script> <script src="../../../http/tests/inspector/timeline-test.js"></script> <script> -function performActions(callback) +function performActions() { + var callback; + var promise = new Promise((fulfill) => callback = fulfill); var requestId = window.requestAnimationFrame(animationFrameCallback); function animationFrameCallback() { @@ -12,6 +14,7 @@ if (callback) callback(); } + return promise; } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-event-causes-expected.txt b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-event-causes-expected.txt index 7099f38..383abeb 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-event-causes-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-event-causes-expected.txt
@@ -2,10 +2,10 @@ Running: testTimerInstall -PASS - record contained Timer InstalledsetTimeoutFunction @ setTimeoutFunction.js: +PASS - record contained Timer InstalledPromise @ setTimeoutFunction.js: Running: testRequestAnimationFrame -PASS - record contained Animation Frame RequestedrequestAnimationFrameFunction @ requestAnimationFrameFunction.js: +PASS - record contained Animation Frame RequestedPromise @ requestAnimationFrameFunction.js: Running: testStyleRecalc PASS - record contained First InvalidatedstyleRecalcFunction @ styleRecalcFunction.js:
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-event-causes.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-event-causes.html index 5b98db76..92ba023 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-event-causes.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-event-causes.html
@@ -15,9 +15,9 @@ InspectorTest.runTestSuite([ function testTimerInstall(next) { - function setTimeoutFunction(callback) + function setTimeoutFunction() { - setTimeout(callback, 0); + return new Promise((fulfill) => setTimeout(fulfill, 0)); } var source = setTimeoutFunction.toString(); @@ -35,7 +35,7 @@ WebInspector.TimelineUIUtils._generateCauses(event, InspectorTest.timelineModel().targetByEvent(event), null, contentHelper); var causes = contentHelper.element.deepTextContent(); InspectorTest.check(causes, "Should generate causes"); - checkStringContains(causes, "Timer InstalledsetTimeoutFunction @ setTimeoutFunction.js:"); + checkStringContains(causes, "Timer InstalledPromise @ setTimeoutFunction.js:"); next(); } }, @@ -44,7 +44,7 @@ { function requestAnimationFrameFunction(callback) { - requestAnimationFrame(callback); + return new Promise((fulfill) => requestAnimationFrame(fulfill)); } var source = requestAnimationFrameFunction.toString(); @@ -62,7 +62,7 @@ WebInspector.TimelineUIUtils._generateCauses(event, InspectorTest.timelineModel().targetByEvent(event), null, contentHelper); var causes = contentHelper.element.deepTextContent(); InspectorTest.check(causes, "Should generate causes"); - checkStringContains(causes, "Animation Frame RequestedrequestAnimationFrameFunction @ requestAnimationFrameFunction.js:"); + checkStringContains(causes, "Animation Frame RequestedPromise @ requestAnimationFrameFunction.js:"); next(); } },
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-grouped-invalidations-expected.txt b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-grouped-invalidations-expected.txt index 2b3be27..fbf25beb 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-grouped-invalidations-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-grouped-invalidations-expected.txt
@@ -6,7 +6,7 @@ S paint invalidations[ { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-misc/timeline-grouped-invalidations.html:12} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-misc/timeline-grouped-invalidations.html:14} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -17,7 +17,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-misc/timeline-grouped-invalidations.html:13} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-misc/timeline-grouped-invalidations.html:15} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -28,7 +28,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-misc/timeline-grouped-invalidations.html:12} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-misc/timeline-grouped-invalidations.html:14} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -39,7 +39,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-misc/timeline-grouped-invalidations.html:13} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-misc/timeline-grouped-invalidations.html:15} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -50,7 +50,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-misc/timeline-grouped-invalidations.html:12} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-misc/timeline-grouped-invalidations.html:14} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -61,7 +61,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-misc/timeline-grouped-invalidations.html:13} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-misc/timeline-grouped-invalidations.html:15} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -72,7 +72,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-misc/timeline-grouped-invalidations.html:12} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-misc/timeline-grouped-invalidations.html:14} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -83,7 +83,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-misc/timeline-grouped-invalidations.html:13} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-misc/timeline-grouped-invalidations.html:15} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -94,6 +94,6 @@ type : "StyleRecalcInvalidationTracking" } ] -PASS - record contained Inline CSS style declaration was mutated for [ DIV class='testElement' ], [ DIV class='testElement' ], and 2 others. (anonymous function) @ timeline-grouped-invalidations.html:12 -PASS - record contained Inline CSS style declaration was mutated for [ DIV class='testElement' ], [ DIV class='testElement' ], and 2 others. (anonymous function) @ timeline-grouped-invalidations.html:13 +PASS - record contained Inline CSS style declaration was mutated for [ DIV class='testElement' ], [ DIV class='testElement' ], and 2 others. (anonymous function) @ timeline-grouped-invalidations.html:14 +PASS - record contained Inline CSS style declaration was mutated for [ DIV class='testElement' ], [ DIV class='testElement' ], and 2 others. (anonymous function) @ timeline-grouped-invalidations.html:15
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-grouped-invalidations.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-grouped-invalidations.html index fa44b06..da70bf2 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-grouped-invalidations.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-grouped-invalidations.html
@@ -4,8 +4,10 @@ <script src="../../../http/tests/inspector/inspector-test.js"></script> <script src="../../../http/tests/inspector/timeline-test.js"></script> <script> -function display(callback) +function display() { + var callback; + var promise = new Promise((fulfill) => callback = fulfill); requestAnimationFrame(function() { var testElements = document.body.getElementsByClassName("testElement"); for (var i = 0; i < testElements.length; i++) { @@ -15,6 +17,7 @@ if (window.testRunner) testRunner.layoutAndPaintAsyncThen(callback); }); + return promise; } function test() @@ -34,8 +37,8 @@ WebInspector.TimelineUIUtils._generateCauses(event, target, null, contentHelper); var invalidationsTree = contentHelper.element.getElementsByClassName("invalidations-tree")[0]; var invalidations = invalidationsTree.shadowRoot.textContent; - checkStringContains(invalidations, "Inline CSS style declaration was mutated for [ DIV class='testElement' ], [ DIV class='testElement' ], and 2 others. (anonymous function) @ timeline-grouped-invalidations.html:12"); - checkStringContains(invalidations, "Inline CSS style declaration was mutated for [ DIV class='testElement' ], [ DIV class='testElement' ], and 2 others. (anonymous function) @ timeline-grouped-invalidations.html:13"); + checkStringContains(invalidations, "Inline CSS style declaration was mutated for [ DIV class='testElement' ], [ DIV class='testElement' ], and 2 others. (anonymous function) @ timeline-grouped-invalidations.html:14"); + checkStringContains(invalidations, "Inline CSS style declaration was mutated for [ DIV class='testElement' ], [ DIV class='testElement' ], and 2 others. (anonymous function) @ timeline-grouped-invalidations.html:15"); InspectorTest.completeTest(); });
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-load-event.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-load-event.html index f059bb51..d133e07 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-load-event.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-load-event.html
@@ -3,8 +3,10 @@ <script src="../../../http/tests/inspector/inspector-test.js"></script> <script src="../../../http/tests/inspector/timeline-test.js"></script> <script> -function display(callback) +function display() { + var callback; + var promise = new Promise((fulfill) => callback = fulfill); if (window.testRunner) testRunner.setCanOpenWindows(true); var popup = window.open("data:text/html,<b>Hello, world</b>"); @@ -12,6 +14,7 @@ { requestAnimationFrame(testRunner.capturePixelsAsyncThen.bind(testRunner, callback)); } + return promise; } function test() @@ -21,7 +24,7 @@ function pageReloaded() { - InspectorTest.invokePageFunctionAsync("display", displayDone); + InspectorTest.callFunctionInPageAsync("display").then(displayDone); } function displayDone()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-receive-response-event.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-receive-response-event.html index efec261..49f3a4e 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-receive-response-event.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-receive-response-event.html
@@ -4,8 +4,10 @@ <script src="../../../http/tests/inspector/timeline-test.js"></script> <script> -function performActions(callback) +function performActions() { + var callback; + var promise = new Promise((fulfill) => callback = fulfill); var image = new Image(); image.onload = bar; image.src = "../resources/anImage.png"; @@ -16,6 +18,7 @@ image.onload = function(event) { callback(); } // do not pass event argument to the callback. image.src = "../resources/anotherImage.png"; } + return promise; } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-network/timeline-network-received-data.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-network/timeline-network-received-data.html index 34954c0..ae17be6 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-network/timeline-network-received-data.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-network/timeline-network-received-data.html
@@ -4,30 +4,18 @@ <script src="../../../http/tests/inspector/timeline-test.js"></script> <script> -function performActions(callback) +function performActions() { - function onImageLoad() - { - window._imageLoaded = true; - if (window._scriptEvaluated) - callback(); - } - - function scriptEvaluated() - { - window._scriptEvaluated = true; - if (window._imageLoaded) - callback(); - } - var image = new Image(); - image.onload = onImageLoad; + var imagePromise = new Promise((fulfill) => image.onload = fulfill); image.src = "../resources/anImage.png"; + + var scriptPromise = new Promise((fulfill) => window.timelineNetworkResourceEvaluated = fulfill); var script = document.createElement("script"); script.src = "timeline-network-resource.js"; document.body.appendChild(script); - window.timelineNetworkResourceEvaluated = scriptEvaluated; + return Promise.all([imagePromise, scriptPromise]); } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-network/timeline-network-resource-details-expected.txt b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-network/timeline-network-resource-details-expected.txt index 5276c3b..2051ff30 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-network/timeline-network-resource-details-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-network/timeline-network-resource-details-expected.txt
@@ -6,7 +6,7 @@ Request Method: GET Priority: Low Mime Type: string -Initiator: timeline-network-resource-details.html:22 +Initiator: timeline-network-resource-details.html:15 URL: anImage.png Duration: string Request Method: GET
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-network/timeline-network-resource-details.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-network/timeline-network-resource-details.html index 58da539f..9f075cf1 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-network/timeline-network-resource-details.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-network/timeline-network-resource-details.html
@@ -4,23 +4,18 @@ <script src="../../../http/tests/inspector/timeline-test.js"></script> <script> -function performActions(callback) +function performActions() { - function onRequestFinished() - { - if (!--requestsPending) - callback(); - } - - var requestsPending = 2; var image = new Image(); - image.onload = onRequestFinished; + var imagePromise = new Promise((fulfill) => image.onload = fulfill); image.src = "../resources/anImage.png"; var script = document.createElement("script"); script.src = "timeline-network-resource.js"; document.body.appendChild(script); - window.timelineNetworkResourceEvaluated = onRequestFinished; + var scriptPromise = new Promise((fulfill) => window.timelineNetworkResourceEvaluated = fulfill); + + return Promise.all([imagePromise, scriptPromise]); } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-network/timeline-network-resource.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-network/timeline-network-resource.html index e5de92e0b..545d0d4 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-network/timeline-network-resource.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-network/timeline-network-resource.html
@@ -6,12 +6,13 @@ var scriptUrl = "timeline-network-resource.js"; -function performActions(callback) +function performActions() { - window.timelineNetworkResourceEvaluated = callback; + var promise = new Promise((fulfill) => window.timelineNetworkResourceEvaluated = fulfill); var script = document.createElement("script"); script.src = scriptUrl; document.body.appendChild(script); + return promise; } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/layer-tree.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/layer-tree.html index 5a3715c3e..f408ffe9 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/layer-tree.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/layer-tree.html
@@ -6,7 +6,7 @@ <script src="../../tracing-test.js"></script> <script> -function doActions(callback) +function doActions() { var div = document.createElement("div"); div.id = "b4"; @@ -16,7 +16,7 @@ var style = document.createElement("style"); style.textContent = ".layer { transform: translateZ(10px); opacity: 0.8; }"; document.head.appendChild(style); - generateFrames(3, callback); + return generateFrames(3); } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/paint-profiler-update.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/paint-profiler-update.html index b8b5d787..7a0b2ec 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/paint-profiler-update.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/paint-profiler-update.html
@@ -3,8 +3,10 @@ <script src="../../../http/tests/inspector/inspector-test.js"></script> <script src="../../../http/tests/inspector/timeline-test.js"></script> <script> -function performActions(callback) +function performActions() { + var callback; + var promise = new Promise((fulfill) => callback = fulfill); var square = document.getElementById("square"); step1(); @@ -19,6 +21,7 @@ square.style.backgroundColor = "black"; testRunner.layoutAndPaintAsyncThen(callback); } + return promise; } function test() @@ -36,7 +39,7 @@ for (var event of events) { if (event.name === WebInspector.TimelineModel.RecordType.Paint) { paintEvents.push(event); - if (!event.picture) + if (!event.picture) InspectorTest.addResult("Event without picture at " + paintEvents.length); } }
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations-expected.txt b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations-expected.txt index dcc6f15..4f28de0 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations-expected.txt
@@ -5,7 +5,7 @@ PASS first style recalc[ { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations.html:10} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations.html:9} changedAttribute : undefined changedClass : "red" changedId : undefined @@ -19,7 +19,7 @@ ] second style recalc[ { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations.html:12} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations.html:11} changedAttribute : undefined changedClass : "snow" changedId : undefined @@ -31,7 +31,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations.html:12} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations.html:11} changedAttribute : undefined changedClass : "red" changedId : undefined @@ -45,7 +45,7 @@ ] first paint[ { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations.html:10} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations.html:9} changedAttribute : undefined changedClass : "red" changedId : undefined @@ -57,7 +57,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations.html:12} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations.html:11} changedAttribute : undefined changedClass : "snow" changedId : undefined @@ -69,7 +69,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations.html:12} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations.html:11} changedAttribute : undefined changedClass : "red" changedId : undefined
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations.html index 0d9381c..69b8172 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-and-multiple-style-invalidations.html
@@ -4,16 +4,13 @@ <script src="../../../http/tests/inspector/inspector-test.js"></script> <script src="../../../http/tests/inspector/timeline-test.js"></script> <script> -function multipleStyleRecalcsAndDisplay(callback) +function multipleStyleRecalcsAndDisplay() { - requestAnimationFrame(function() { - document.getElementById("testElementOne").className = "red"; - var forceStyleRecalc1 = document.body.offsetTop; - document.getElementById("testElementOne").className = "snow"; - var forceStyleRecalc2 = document.body.offsetTop; - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + document.getElementById("testElementOne").className = "red"; + var forceStyleRecalc1 = document.body.offsetTop; + document.getElementById("testElementOne").className = "snow"; + var forceStyleRecalc2 = document.body.offsetTop; + return waitForFrame(); }
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-expected.txt b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-expected.txt index aeab905..d75299c 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-expected.txt
@@ -6,7 +6,7 @@ Running: testLocalFrame paint invalidations[ { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations.html:10} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations.html:9} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -17,7 +17,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations.html:11} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations.html:10} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -28,7 +28,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Style changed, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations.html:12} + cause : {reason: Style changed, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations.html:11} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -43,7 +43,7 @@ Running: testSubframe second paint invalidations[ { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations.html:21} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations.html:17} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -54,7 +54,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Style changed, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations.html:22} + cause : {reason: Style changed, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations.html:18} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -65,7 +65,7 @@ type : "LayoutInvalidationTracking" } { - cause : {reason: Unknown, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations.html:22} + cause : {reason: Unknown, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations.html:18} changedAttribute : undefined changedClass : undefined changedId : undefined
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node-expected.txt b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node-expected.txt index 040d739..f251fd46 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node-expected.txt
@@ -5,7 +5,7 @@ Running: testLocalFrame paint invalidations[ { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.html:10} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.html:9} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -16,7 +16,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.html:12} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.html:11} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -27,7 +27,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Style changed, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.html:13} + cause : {reason: Style changed, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.html:12} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -38,7 +38,7 @@ type : "LayoutInvalidationTracking" } { - cause : {reason: Removed from layout, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.html:14} + cause : {reason: Removed from layout, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.html:13} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -49,7 +49,7 @@ type : "LayoutInvalidationTracking" } { - cause : {reason: Removed from layout, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.html:14} + cause : {reason: Removed from layout, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.html:13} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -64,7 +64,7 @@ Running: testSubframe second paint invalidations[ { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.html:24} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.html:20} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -75,7 +75,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Style changed, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.html:25} + cause : {reason: Style changed, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.html:21} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -86,7 +86,7 @@ type : "LayoutInvalidationTracking" } { - cause : {reason: Removed from layout, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.html:26} + cause : {reason: Removed from layout, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.html:22} changedAttribute : undefined changedClass : undefined changedId : undefined
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.html index 33eadbf3..3d924cc 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations-on-deleted-node.html
@@ -4,29 +4,23 @@ <script src="../../../http/tests/inspector/inspector-test.js"></script> <script src="../../../http/tests/inspector/timeline-test.js"></script> <script> -function display(callback) +function display() { - requestAnimationFrame(function() { - document.body.style.backgroundColor = "blue"; - var element = document.getElementById("testElement"); - element.style.width = "100px"; - var forceLayout = document.body.offsetTop; - element.parentElement.removeChild(element); - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + document.body.style.backgroundColor = "blue"; + var element = document.getElementById("testElement"); + element.style.width = "100px"; + var forceLayout = document.body.offsetTop; + element.parentElement.removeChild(element); + return waitForFrame(); } -function updateSubframeAndDisplay(callback) +function updateSubframeAndDisplay() { - requestAnimationFrame(function() { - var element = frames[0].document.body.children[0]; - element.style.width = "200px"; - var forceLayout = frames[0].document.body.offsetTop; - element.parentElement.removeChild(element); - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + var element = frames[0].document.body.children[0]; + element.style.width = "200px"; + var forceLayout = frames[0].document.body.offsetTop; + element.parentElement.removeChild(element); + return waitForFrame(); } function test() @@ -41,7 +35,6 @@ InspectorTest.invokeAsyncWithTimeline("display", function() { var record = InspectorTest.findFirstTimelineRecord(WebInspector.TimelineModel.RecordType.Paint); InspectorTest.addArray(record._event.invalidationTrackingEvents, InspectorTest.InvalidationFormatters, "", "paint invalidations"); - next(); }); },
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations.html index 32c5fb2..e9672a99 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-layout-invalidations.html
@@ -4,25 +4,19 @@ <script src="../../../http/tests/inspector/inspector-test.js"></script> <script src="../../../http/tests/inspector/timeline-test.js"></script> <script> -function display(callback) +function display() { - requestAnimationFrame(function() { - document.body.style.backgroundColor = "blue"; - document.getElementById("testElement").style.width = "100px"; - var forceLayout = document.body.offsetTop; - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + document.body.style.backgroundColor = "blue"; + document.getElementById("testElement").style.width = "100px"; + var forceLayout = document.body.offsetTop; + return waitForFrame(); } -function updateSubframeAndDisplay(callback) +function updateSubframeAndDisplay() { - requestAnimationFrame(function() { - frames[0].document.body.children[0].style.width = "200px"; - var forceLayout = frames[0].document.body.offsetTop; - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + frames[0].document.body.children[0].style.width = "200px"; + var forceLayout = frames[0].document.body.offsetTop; + return waitForFrame(); } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-style-recalc-invalidations-expected.txt b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-style-recalc-invalidations-expected.txt index ae8173b..d316259a0 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-style-recalc-invalidations-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-style-recalc-invalidations-expected.txt
@@ -6,7 +6,7 @@ Running: testLocalFrame first paint invalidations[ { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-style-recalc-invalidations.html:10} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-style-recalc-invalidations.html:9} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -17,7 +17,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-style-recalc-invalidations.html:11} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-style-recalc-invalidations.html:10} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -32,7 +32,7 @@ Running: testSubframe second paint invalidations[ { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-style-recalc-invalidations.html:20} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-paint/timeline-paint-with-style-recalc-invalidations.html:16} changedAttribute : undefined changedClass : undefined changedId : undefined
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-style-recalc-invalidations.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-style-recalc-invalidations.html index 9cb6312..bea8789 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-style-recalc-invalidations.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint-with-style-recalc-invalidations.html
@@ -4,23 +4,17 @@ <script src="../../../http/tests/inspector/inspector-test.js"></script> <script src="../../../http/tests/inspector/timeline-test.js"></script> <script> -function display(callback) +function display() { - requestAnimationFrame(function() { - document.body.style.backgroundColor = "blue"; - document.getElementById("testElement").style.backgroundColor = "salmon"; - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + document.body.style.backgroundColor = "blue"; + document.getElementById("testElement").style.backgroundColor = "salmon"; + return waitForFrame(); } -function updateSubframeAndDisplay(callback) +function updateSubframeAndDisplay() { - requestAnimationFrame(function() { - frames[0].document.body.children[0].style.backgroundColor = "green"; - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + frames[0].document.body.children[0].style.backgroundColor = "green"; + return waitForFrame(); } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint.html index a49206c..855d02e 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/timeline-paint.html
@@ -4,22 +4,16 @@ <script src="../../../http/tests/inspector/timeline-test.js"></script> <script> -function display(callback) +function display() { - requestAnimationFrame(function() { - document.body.style.backgroundColor = "blue"; - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + document.body.style.backgroundColor = "blue"; + return waitForFrame(); } -function updateSubframeAndDisplay(callback) +function updateSubframeAndDisplay() { - requestAnimationFrame(function() { - frames[0].document.body.children[0].style.backgroundColor = "green"; - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + frames[0].document.body.children[0].style.backgroundColor = "green"; + return waitForFrame(); } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/update-layer-tree.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/update-layer-tree.html index a62404e..32e686c 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/update-layer-tree.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-paint/update-layer-tree.html
@@ -12,14 +12,12 @@ <script src="../../../http/tests/inspector/timeline-test.js"></script> <script> -function doActions(callback) +function doActions() { var layer = document.createElement("div"); layer.classList.add("layer"); document.getElementById("parent-layer").appendChild(layer); - - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); + return new Promise((fulfill) => testRunner.layoutAndPaintAsyncThen(fulfill)); } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/parse-author-style-sheet.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/parse-author-style-sheet.html index 91c39511..59ffabfa 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/parse-author-style-sheet.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/parse-author-style-sheet.html
@@ -5,14 +5,14 @@ <script src="../../tracing-test.js"></script> <script> -function importStyle(onComplete) +function importStyle() { var link = document.createElement('link'); link.setAttribute('rel', 'stylesheet'); link.type = 'text/css'; link.href = '../resources/style.css'; - document.head.appendChild(link); - link.onload = onComplete.bind(this, null); + document.head.appendChild(link); + return new Promise((fulfill) => link.onload = fulfill); } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types-expected.txt b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types-expected.txt index 3234b879..b362410 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types-expected.txt
@@ -7,7 +7,7 @@ Running: testClassName [ { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:10} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:9} changedAttribute : undefined changedClass : "red" changedId : undefined @@ -19,7 +19,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:11} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:10} changedAttribute : undefined changedClass : "red" changedId : undefined @@ -37,7 +37,7 @@ Running: testId [ { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:32} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:25} changedAttribute : undefined changedClass : undefined changedId : "testElementFour" @@ -49,7 +49,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:33} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:26} changedAttribute : undefined changedClass : undefined changedId : "testElementFive" @@ -65,7 +65,7 @@ Running: testStyleAttributeChange [ { - cause : {reason: StyleSheetChange, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:43} + cause : {reason: StyleSheetChange, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:33} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -76,7 +76,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: StyleSheetChange, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:44} + cause : {reason: StyleSheetChange, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:34} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -91,7 +91,7 @@ Running: testAttributeChange [ { - cause : {reason: Attribute, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:54} + cause : {reason: Attribute, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:41} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -102,7 +102,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Attribute, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:55} + cause : {reason: Attribute, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:42} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -113,7 +113,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:54} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:41} changedAttribute : "dir" changedClass : undefined changedId : undefined @@ -125,7 +125,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:55} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:42} changedAttribute : "dir" changedClass : undefined changedId : undefined @@ -141,7 +141,7 @@ Running: testPseudoChange [ { - cause : {reason: PseudoClass, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:67} + cause : {reason: PseudoClass, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html:51} changedAttribute : undefined changedClass : undefined changedId : undefined
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html index d805373..7154898 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-all-invalidator-types.html
@@ -4,72 +4,54 @@ <script src="../../../http/tests/inspector/inspector-test.js"></script> <script src="../../../http/tests/inspector/timeline-test.js"></script> <script> -function changeClassNameAndDisplay(callback) +function changeClassNameAndDisplay() { - requestAnimationFrame(function() { - document.getElementById("testElementOne").className = "red"; - document.getElementById("testElementTwo").className = "red"; - var forceStyleRecalc = document.body.offsetTop; - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + document.getElementById("testElementOne").className = "red"; + document.getElementById("testElementTwo").className = "red"; + var forceStyleRecalc = document.body.offsetTop; + return waitForFrame(); } -function changeIdWithoutStyleChangeAndDisplay(callback) +function changeIdWithoutStyleChangeAndDisplay() { - requestAnimationFrame(function() { - document.getElementById("testElementOne").id = "testElementNoMatchingStyles1"; - document.getElementById("testElementTwo").id = "testElementNoMatchingStyles2"; - var forceStyleRecalc = document.body.offsetTop; - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + document.getElementById("testElementOne").id = "testElementNoMatchingStyles1"; + document.getElementById("testElementTwo").id = "testElementNoMatchingStyles2"; + var forceStyleRecalc = document.body.offsetTop; + return waitForFrame(); } -function changeIdAndDisplay(callback) +function changeIdAndDisplay() { - requestAnimationFrame(function() { - document.getElementById("testElementNoMatchingStyles1").id = "testElementFour"; - document.getElementById("testElementNoMatchingStyles2").id = "testElementFive"; - var forceStyleRecalc = document.body.offsetTop; - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + document.getElementById("testElementNoMatchingStyles1").id = "testElementFour"; + document.getElementById("testElementNoMatchingStyles2").id = "testElementFive"; + var forceStyleRecalc = document.body.offsetTop; + return waitForFrame(); } -function changeStyleAttributeAndDisplay(callback) +function changeStyleAttributeAndDisplay() { - requestAnimationFrame(function() { - document.getElementById("testElementFour").setAttribute("style", "color: purple"); - document.getElementById("testElementFive").setAttribute("style", "color: pink"); - var forceStyleRecalc = document.body.offsetTop; - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + document.getElementById("testElementFour").setAttribute("style", "color: purple"); + document.getElementById("testElementFive").setAttribute("style", "color: pink"); + var forceStyleRecalc = document.body.offsetTop; + return waitForFrame(); } -function changeAttributeAndDisplay(callback) +function changeAttributeAndDisplay() { - requestAnimationFrame(function() { - document.getElementById("testElementFour").setAttribute("dir", "rtl"); - document.getElementById("testElementFive").setAttribute("dir", "rtl"); - var forceStyleRecalc = document.body.offsetTop; - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + document.getElementById("testElementFour").setAttribute("dir", "rtl"); + document.getElementById("testElementFive").setAttribute("dir", "rtl"); + var forceStyleRecalc = document.body.offsetTop; + return waitForFrame(); } -function changePseudoAndDisplay(callback) +function changePseudoAndDisplay() { - requestAnimationFrame(function() { - var element1 = document.getElementById("testElementFour"); - var element2 = document.getElementById("testElementFive"); - eventSender.mouseMoveTo(element2.offsetLeft + 2, element2.offsetTop + 2); - requestAnimationFrame(function() { - var forceStyleRecalc = document.body.offsetTop; - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + var element1 = document.getElementById("testElementFour"); + var element2 = document.getElementById("testElementFive"); + eventSender.mouseMoveTo(element2.offsetLeft + 2, element2.offsetTop + 2); + return waitForFrame().then(function() { + var forceStyleRecalc = document.body.offsetTop; + return waitForFrame(); }); }
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations-expected.txt b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations-expected.txt index ae643db..f5b2caca 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations-expected.txt
@@ -8,7 +8,7 @@ Running: testLocalFrame first recalc style invalidations[ { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html:10} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html:9} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -19,7 +19,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html:11} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html:10} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -34,7 +34,7 @@ Running: multipleStyleRecalcs first recalc style invalidations[ { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html:25} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html:21} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -47,7 +47,7 @@ ] second recalc style invalidations[ { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html:27} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html:23} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -58,7 +58,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html:28} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html:24} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -71,7 +71,7 @@ ] third recalc style invalidations[ { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html:30} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html:26} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -82,7 +82,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html:31} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html:27} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -93,7 +93,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html:32} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html:28} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -108,7 +108,7 @@ Running: testSubframe first recalc style invalidations[ { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html:43} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html:35} changedAttribute : undefined changedClass : undefined changedId : undefined @@ -119,7 +119,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html:44} + cause : {reason: Inline CSS style declaration was mutated, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html:36} changedAttribute : undefined changedClass : undefined changedId : undefined
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html index 3cac78a4..0123f07 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-with-invalidations.html
@@ -4,48 +4,38 @@ <script src="../../../http/tests/inspector/inspector-test.js"></script> <script src="../../../http/tests/inspector/timeline-test.js"></script> <script> -function changeStylesAndDisplay(callback) +function changeStylesAndDisplay() { - requestAnimationFrame(function() { - document.getElementById("testElementOne").style.color = "red"; - document.getElementById("testElementTwo").style.color = "blue"; - var forceLayout = document.body.offsetTop; - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + document.getElementById("testElementOne").style.color = "red"; + document.getElementById("testElementTwo").style.color = "blue"; + var forceLayout = document.body.offsetTop; + return waitForFrame(); } -function changeMultipleStylesAndDisplay(callback) +function changeMultipleStylesAndDisplay() { - requestAnimationFrame(function() { - var elementOne = document.getElementById("testElementOne"); - var elementTwo = document.getElementById("testElementTwo"); - var elementThree = document.getElementById("testElementThree"); + var elementOne = document.getElementById("testElementOne"); + var elementTwo = document.getElementById("testElementTwo"); + var elementThree = document.getElementById("testElementThree"); - elementOne.style.backgroundColor = "orangered"; - var forceStyleRecalc1 = document.body.offsetTop; - elementOne.style.color = "mediumvioletred"; - elementTwo.style.color = "deepskyblue"; - var forceStyleRecalc2 = document.body.offsetTop; - elementOne.style.color = "tomato"; - elementTwo.style.color = "mediumslateblue"; - elementThree.style.color = "mediumspringgreen"; - var forceStyleRecalc3 = document.body.offsetTop; - - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + elementOne.style.backgroundColor = "orangered"; + var forceStyleRecalc1 = document.body.offsetTop; + elementOne.style.color = "mediumvioletred"; + elementTwo.style.color = "deepskyblue"; + var forceStyleRecalc2 = document.body.offsetTop; + elementOne.style.color = "tomato"; + elementTwo.style.color = "mediumslateblue"; + elementThree.style.color = "mediumspringgreen"; + var forceStyleRecalc3 = document.body.offsetTop; + return waitForFrame(); } -function changeSubframeStylesAndDisplay(callback) +function changeSubframeStylesAndDisplay() { - requestAnimationFrame(function() { - frames[0].document.body.style.backgroundColor = "papayawhip"; - frames[0].document.body.children[0].style.width = "200px"; - var forceLayout = frames[0].document.body.offsetTop; - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + frames[0].document.body.style.backgroundColor = "papayawhip"; + frames[0].document.body.children[0].style.width = "200px"; + var forceLayout = frames[0].document.body.offsetTop; + return waitForFrame(); } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations-expected.txt b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations-expected.txt index 2d1031b..83f5bb5 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations-expected.txt
@@ -8,7 +8,7 @@ Running: testLocalFrame first recalculate styles[ { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:10} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:9} changedAttribute : undefined changedClass : "red" changedId : undefined @@ -20,7 +20,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:11} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:10} changedAttribute : undefined changedClass : "red" changedId : undefined @@ -36,7 +36,7 @@ Running: multipleStyleRecalcs first recalculate styles[ { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:24} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:20} changedAttribute : undefined changedClass : "green" changedId : undefined @@ -48,7 +48,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:24} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:20} changedAttribute : undefined changedClass : "red" changedId : undefined @@ -62,7 +62,7 @@ ] second recalculate styles[ { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:26} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:22} changedAttribute : undefined changedClass : "blue" changedId : undefined @@ -74,7 +74,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:26} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:22} changedAttribute : undefined changedClass : "green" changedId : undefined @@ -86,7 +86,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:27} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:23} changedAttribute : undefined changedClass : "blue" changedId : undefined @@ -98,7 +98,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:27} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:23} changedAttribute : undefined changedClass : "red" changedId : undefined @@ -112,7 +112,7 @@ ] third recalculate styles[ { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:29} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:25} changedAttribute : undefined changedClass : "snow" changedId : undefined @@ -124,7 +124,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:29} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:25} changedAttribute : undefined changedClass : "blue" changedId : undefined @@ -136,7 +136,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:30} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:26} changedAttribute : undefined changedClass : "snow" changedId : undefined @@ -148,7 +148,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:30} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:26} changedAttribute : undefined changedClass : "blue" changedId : undefined @@ -160,7 +160,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:31} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:27} changedAttribute : undefined changedClass : "snow" changedId : undefined @@ -176,7 +176,7 @@ Running: testSubframe first recalculate styles[ { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:45} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:38} changedAttribute : undefined changedClass : "green" changedId : undefined @@ -190,7 +190,7 @@ ] second recalculate styles[ { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:47} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:40} changedAttribute : undefined changedClass : "blue" changedId : undefined @@ -202,7 +202,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:47} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:40} changedAttribute : undefined changedClass : "green" changedId : undefined @@ -214,7 +214,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:48} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:41} changedAttribute : undefined changedClass : "blue" changedId : undefined @@ -228,7 +228,7 @@ ] third recalculate styles[ { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:50} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:43} changedAttribute : undefined changedClass : "snow" changedId : undefined @@ -240,7 +240,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:50} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:43} changedAttribute : undefined changedClass : "blue" changedId : undefined @@ -252,7 +252,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:51} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:44} changedAttribute : undefined changedClass : "snow" changedId : undefined @@ -264,7 +264,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:51} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:44} changedAttribute : undefined changedClass : "blue" changedId : undefined @@ -276,7 +276,7 @@ type : "StyleRecalcInvalidationTracking" } { - cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:52} + cause : {reason: Element has pending invalidation list, stackTrace: .../inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html:45} changedAttribute : undefined changedClass : "snow" changedId : undefined
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html index 5ab8b8e..400a439 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-style/timeline-style-recalc-with-invalidator-invalidations.html
@@ -4,56 +4,47 @@ <script src="../../../http/tests/inspector/inspector-test.js"></script> <script src="../../../http/tests/inspector/timeline-test.js"></script> <script> -function changeStylesAndDisplay(callback) +function changeStylesAndDisplay() { - requestAnimationFrame(function() { - document.getElementById("testElementOne").className = "red"; - document.getElementById("testElementTwo").className = "red"; - var forceStyleRecalc = document.body.offsetTop; - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + document.getElementById("testElementOne").className = "red"; + document.getElementById("testElementTwo").className = "red"; + var forceStyleRecalc = document.body.offsetTop; + return waitForFrame(); } -function changeMultipleStylesAndDisplay(callback) +function changeMultipleStylesAndDisplay() { - requestAnimationFrame(function() { - var elementOne = document.getElementById("testElementOne"); - var elementTwo = document.getElementById("testElementTwo"); - var elementThree = document.getElementById("testElementThree"); - elementOne.className = "green"; - var forceStyleRecalc1 = document.body.offsetTop; - elementOne.className = "blue"; - elementTwo.className = "blue"; - var forceStyleRecalc2 = document.body.offsetTop; - elementOne.className = "snow"; - elementTwo.className = "snow"; - elementThree.className = "snow"; - var forceStyleRecalc3 = document.body.offsetTop; - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + var elementOne = document.getElementById("testElementOne"); + var elementTwo = document.getElementById("testElementTwo"); + var elementThree = document.getElementById("testElementThree"); + elementOne.className = "green"; + var forceStyleRecalc1 = document.body.offsetTop; + elementOne.className = "blue"; + elementTwo.className = "blue"; + var forceStyleRecalc2 = document.body.offsetTop; + elementOne.className = "snow"; + elementTwo.className = "snow"; + elementThree.className = "snow"; + var forceStyleRecalc3 = document.body.offsetTop; + return waitForFrame(); } -function changeMultipleSubframeStylesAndDisplay(callback) +function changeMultipleSubframeStylesAndDisplay() { - requestAnimationFrame(function() { - var innerDocument = frames[0].document; - var elementOne = innerDocument.getElementById("testElementOne"); - var elementTwo = innerDocument.getElementById("testElementTwo"); - var elementThree = innerDocument.getElementById("testElementThree"); - elementOne.className = "green"; - var forceStyleRecalc1 = innerDocument.body.offsetTop; - elementOne.className = "blue"; - elementTwo.className = "blue"; - var forceStyleRecalc2 = innerDocument.body.offsetTop; - elementOne.className = "snow"; - elementTwo.className = "snow"; - elementThree.className = "snow"; - var forceStyleRecalc3 = innerDocument.body.offsetTop; - if (window.testRunner) - testRunner.layoutAndPaintAsyncThen(callback); - }); + var innerDocument = frames[0].document; + var elementOne = innerDocument.getElementById("testElementOne"); + var elementTwo = innerDocument.getElementById("testElementTwo"); + var elementThree = innerDocument.getElementById("testElementThree"); + elementOne.className = "green"; + var forceStyleRecalc1 = innerDocument.body.offsetTop; + elementOne.className = "blue"; + elementTwo.className = "blue"; + var forceStyleRecalc2 = innerDocument.body.offsetTop; + elementOne.className = "snow"; + elementTwo.className = "snow"; + elementThree.className = "snow"; + var forceStyleRecalc3 = innerDocument.body.offsetTop; + return waitForFrame(); } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-time/timeline-timer-expected.txt b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-time/timeline-timer-expected.txt index 4875c48..747ec425 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-time/timeline-timer-expected.txt +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-time/timeline-timer-expected.txt
@@ -15,7 +15,7 @@ startTime : <number> type : "TimerInstall" } -Text details for TimerInstall: timeline-timer.html:9 +Text details for TimerInstall: timeline-timer.html:11 TimerInstall Properties: { data : { @@ -31,7 +31,7 @@ startTime : <number> type : "TimerInstall" } -Text details for TimerInstall: timeline-timer.html:10 +Text details for TimerInstall: timeline-timer.html:12 TimerFire Properties: { data : { @@ -43,7 +43,7 @@ startTime : <number> type : "TimerFire" } -Text details for TimerFire: timeline-timer.html:9 +Text details for TimerFire: timeline-timer.html:11 TimerFire Properties: { data : { @@ -55,7 +55,7 @@ startTime : <number> type : "TimerFire" } -Text details for TimerFire: timeline-timer.html:10 +Text details for TimerFire: timeline-timer.html:12 TimerFire Properties: { data : { @@ -67,7 +67,7 @@ startTime : <number> type : "TimerFire" } -Text details for TimerFire: timeline-timer.html:10 +Text details for TimerFire: timeline-timer.html:12 TimerRemove Properties: { data : { @@ -81,7 +81,7 @@ startTime : <number> type : "TimerRemove" } -Text details for TimerRemove: timeline-timer.html:17 +Text details for TimerRemove: timeline-timer.html:19 FunctionCall Properties: { data : {
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-time/timeline-timer-fired-from-eval-call-site.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-time/timeline-timer-fired-from-eval-call-site.html index 7bc3e4d..408bebd 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-time/timeline-timer-fired-from-eval-call-site.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-time/timeline-timer-fired-from-eval-call-site.html
@@ -4,10 +4,10 @@ <script src="../../../http/tests/inspector/timeline-test.js"></script> <script> -function performActions(callback) +function performActions() { - window.callWhenDone = callback; - var content = "" + + var promise = new Promise((fulfill) => window.callWhenDone = fulfill); + var content = "" + "var fn2 = function() {" + " console.markTimeline(\"Script evaluated\");" + " window.callWhenDone();" + @@ -23,6 +23,7 @@ scriptElement.appendChild(contentNode); document.body.appendChild(scriptElement); document.body.removeChild(scriptElement); + return promise; } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-time/timeline-timer.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-time/timeline-timer.html index beaed25..4b6370c5 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-time/timeline-timer.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-time/timeline-timer.html
@@ -4,8 +4,10 @@ <script src="../../../http/tests/inspector/timeline-test.js"></script> <script> -function performActions(callback) +function performActions() { + var callback; + var promise = new Promise((fulfill) => callback = fulfill); var timerOne = setTimeout("1 + 1", 10); var timerTwo = setInterval(intervalTimerWork, 20); var iteration = 0; @@ -17,6 +19,7 @@ clearInterval(timerTwo); callback(); } + return promise; } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/worker-events.html b/third_party/WebKit/LayoutTests/inspector/tracing/worker-events.html index 54a66c6..52544d0a 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/worker-events.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/worker-events.html
@@ -25,15 +25,11 @@ } } -function startSecondWorker(onActionComplete) +function startSecondWorker() { worker2 = new Worker("resources/worker.js"); worker2.postMessage(""); - worker2.onmessage = function(event) - { - onActionComplete(); - worker2.onmessage = null; - } + return new Promise((fulfill) => worker2.onmessage = fulfill); } function test()
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/worker-js-frames.html b/third_party/WebKit/LayoutTests/inspector/tracing/worker-js-frames.html index 8be42e0..efb2a97 100644 --- a/third_party/WebKit/LayoutTests/inspector/tracing/worker-js-frames.html +++ b/third_party/WebKit/LayoutTests/inspector/tracing/worker-js-frames.html
@@ -33,8 +33,10 @@ } } -function startSecondWorker(onActionComplete) +function startSecondWorker() { + var callback; + var promise = new Promise((fulfill) => callback = fulfill); // Make sure there is at least one trace event recorded for the first worker. worker1.onmessage = gotResponseFromFirstWorker; worker1.postMessage(""); @@ -50,9 +52,10 @@ { worker2.onmessage = null; makeDOMEvent(); - onActionComplete(); + callback(); } } + return promise; } function test()
diff --git a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-generate-request-disallowed-input.html b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-generate-request-disallowed-input.html index a973ac6..98c9fd7 100644 --- a/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-generate-request-disallowed-input.html +++ b/third_party/WebKit/LayoutTests/media/encrypted-media/encrypted-media-generate-request-disallowed-input.html
@@ -72,7 +72,7 @@ { // Invalid data as type = 'psss'. var initData = new Uint8Array([ - 0x00, 0x00, 0x00, 0x20, // size = 0 + 0x00, 0x00, 0x00, 0x20, // size = 32 0x70, 0x73, 0x73, 0x73, // 'psss' 0x00, // version = 0 0x00, 0x00, 0x00, // flags
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/column-rule-change-expected.html b/third_party/WebKit/LayoutTests/paint/invalidation/column-rule-change-expected.html new file mode 100644 index 0000000..4168cbc --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/column-rule-change-expected.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<p style="height: 100px"> +Tests paint invalidation of column rules when column changes without changing geometry of the column and the column set. +Passes if no under-invalidation is reported. +</p> +<div id="columns" style="columns: 2; background-color: blue; column-rule: 2px solid green; width: 200px; height: 200px"> + <div id="content1" style="display: inline-block; width: 50px; height: 200px; background-color: yellow"></div><br> + <div id="content2" style="display: inline-block; width: 50px; height: 100px; background-color: yellow"></div> +</div>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/column-rule-change.html b/third_party/WebKit/LayoutTests/paint/invalidation/column-rule-change.html new file mode 100644 index 0000000..1a6d6a7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/column-rule-change.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<p style="height: 100px"> +Tests paint invalidation of column rules when column changes without changing geometry of the column and the column set. +Passes if no under-invalidation is reported. +</p> +<div id="columns" style="columns: 1; background-color: blue; column-rule: 2px solid green; width: 200px; height: 200px"> + <div id="content1" style="display: inline-block; width: 50px; height: 100px; background-color: yellow"></div><br> + <div id="content2" style="display: inline-block; width: 50px; height: 100px; background-color: yellow"></div> +</div> +<script src="../../resources/run-after-layout-and-paint.js"></script> +<script> +runAfterLayoutAndPaint(function() { + columns.style.columns = 2; + content1.style.height = '200px'; +}, true); +</script>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/composited-overflow-with-local-background-expected.txt b/third_party/WebKit/LayoutTests/paint/invalidation/composited-overflow-with-local-background-expected.txt new file mode 100644 index 0000000..7ca439f --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/composited-overflow-with-local-background-expected.txt
@@ -0,0 +1,80 @@ +{ + "name": "Content Root Layer", + "bounds": [800, 600], + "children": [ + { + "name": "LayoutView #document", + "bounds": [800, 600], + "contentsOpaque": true, + "drawsContent": true, + "children": [ + { + "name": "LayoutBlockFlow DIV id='scroller'", + "position": [8, 8], + "bounds": [200, 200], + "shouldFlattenTransform": false, + "drawsContent": true, + "backgroundColor": "#008000", + "paintInvalidations": [ + { + "object": "LayoutBlockFlow DIV id='scroller'", + "rect": [0, 0, 200, 200], + "reason": "style change" + } + ], + "children": [ + { + "name": "Scrolling Layer", + "bounds": [185, 185], + "shouldFlattenTransform": false, + "children": [ + { + "name": "Scrolling Contents Layer", + "bounds": [185, 300], + "contentsOpaque": true, + "drawsContent": true, + "paintInvalidations": [ + { + "object": "LayoutBlockFlow DIV id='scroller'", + "rect": [0, 0, 185, 300], + "reason": "style change" + } + ] + } + ] + }, + { + "name": "Overflow Controls Host Layer", + "bounds": [200, 200], + "children": [ + { + "name": "Horizontal Scrollbar Layer", + "position": [0, 185], + "bounds": [185, 15] + }, + { + "name": "Vertical Scrollbar Layer", + "position": [185, 0], + "bounds": [15, 185] + }, + { + "name": "Scroll Corner Layer", + "position": [185, 185], + "bounds": [15, 15], + "drawsContent": true + } + ] + } + ] + } + ] + } + ], + "objectPaintInvalidations": [ + { + "object": "LayoutBlockFlow DIV id='scroller'", + "reason": "style change" + } + ] +} +
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/composited-overflow-with-local-background.html b/third_party/WebKit/LayoutTests/paint/invalidation/composited-overflow-with-local-background.html new file mode 100644 index 0000000..1601f63 --- /dev/null +++ b/third_party/WebKit/LayoutTests/paint/invalidation/composited-overflow-with-local-background.html
@@ -0,0 +1,25 @@ +<script src="../../fast/repaint/resources/text-based-repaint.js"></script> +<script> +function repaintTest() { + document.getElementById('scroller').style.background = 'green local'; +} +onload = runRepaintTest; +</script> +<style> +#scroller { + background: red local; + overflow: scroll; + width: 200px; + height: 200px; + will-change: transform; +} + +.spacer { + height: 300px; +} +</style> +<!-- #scroller has a locally attached background which will be painted into the + scrolling contents layer. When the color changes it should repaint. --> +<div id="scroller"> + <div class="spacer"></div> +</div>
diff --git a/third_party/WebKit/LayoutTests/platform/android/fast/repaint/block-layout-inline-children-replaced-expected.txt b/third_party/WebKit/LayoutTests/platform/android/fast/repaint/block-layout-inline-children-replaced-expected.txt deleted file mode 100644 index d4774e8..0000000 --- a/third_party/WebKit/LayoutTests/platform/android/fast/repaint/block-layout-inline-children-replaced-expected.txt +++ /dev/null
@@ -1,25 +0,0 @@ -{ - "bounds": [800, 600], - "children": [ - { - "bounds": [800, 600], - "contentsOpaque": true, - "drawsContent": true, - "repaintRects": [ - [155, 37, 92, 100], - [0, 37, 402, 100], - [0, 36, 402, 152] - ], - "paintInvalidationClients": [ - "LayoutBlockFlow DIV id='target' class='target'", - "RootInlineBox", - "LayoutImage IMG", - "InlineBox", - "RootInlineBox", - "LayoutBlockFlow DIV id='target' class='target'", - "LayoutImage IMG" - ] - } - ] -} -
diff --git a/third_party/WebKit/LayoutTests/platform/android/svg/text/text-rescale-expected.txt b/third_party/WebKit/LayoutTests/platform/android/svg/text/text-rescale-expected.txt deleted file mode 100644 index 0f657294..0000000 --- a/third_party/WebKit/LayoutTests/platform/android/svg/text/text-rescale-expected.txt +++ /dev/null
@@ -1,116 +0,0 @@ -{ - "bounds": [800, 600], - "children": [ - { - "bounds": [800, 600], - "contentsOpaque": true, - "drawsContent": true, - "repaintRects": [ - [310, 114, 92, 46], - [310, 114, 92, 46], - [310, 114, 92, 46], - [310, 64, 92, 46], - [310, 14, 92, 46], - [310, 14, 92, 46], - [310, 14, 92, 46], - [210, 114, 92, 46], - [210, 113, 100, 87], - [210, 113, 100, 48], - [210, 14, 92, 46], - [210, 13, 100, 100], - [210, 13, 100, 48], - [9, 3, 5, 2], - [9, 3, 5, 2], - [9, 3, 5, 2], - [6, 3, 4, 4], - [6, 3, 4, 2], - [6, 3, 4, 2], - [0, 114, 193, 46], - [0, 114, 193, 46], - [0, 114, 193, 46], - [0, 114, 193, 46], - [0, 114, 193, 46], - [0, 113, 402, 87], - [0, 64, 193, 46], - [0, 63, 402, 100], - [0, 14, 193, 46], - [0, 14, 193, 46], - [0, 14, 193, 46], - [0, 14, 193, 46], - [0, 14, 193, 46], - [0, 13, 402, 187], - [0, 13, 402, 100], - [0, 3, 14, 4], - [0, 3, 8, 2], - [0, 3, 8, 2], - [0, 3, 8, 2], - [0, 3, 8, 2], - [0, 3, 8, 2], - [0, 0, 402, 163], - [0, 0, 1, 1], - [0, 0, 1, 1], - [0, 0, 1, 1], - [0, 0, 1, 1] - ], - "paintInvalidationClients": [ - "RootInlineBox", - "InlineTextBox 'PASS '", - "InlineFlowBox", - "InlineTextBox 'PASS'", - "RootInlineBox", - "InlineTextBox 'PASS'", - "RootInlineBox", - "InlineTextBox 'PASS '", - "InlineFlowBox", - "InlineTextBox 'PASS'", - "RootInlineBox", - "InlineTextBox 'PASS'", - "RootInlineBox", - "InlineTextBox 'PASS '", - "InlineFlowBox", - "InlineTextBox 'PASS'", - "RootInlineBox", - "InlineTextBox 'PASS'", - "LayoutSVGRoot (positioned) svg", - "LayoutSVGContainer g id='text1g'", - "LayoutSVGText text", - "LayoutSVGInlineText #text", - "InlineTextBox 'PASS '", - "LayoutSVGTSpan tspan", - "InlineFlowBox", - "LayoutSVGInlineText #text", - "InlineTextBox 'PASS'", - "LayoutSVGInlineText #text", - "LayoutSVGForeignObject foreignObject", - "LayoutBlockFlow P", - "LayoutText #text", - "InlineTextBox 'PASS'", - "LayoutSVGViewportContainer svg", - "LayoutSVGText text", - "LayoutSVGInlineText #text", - "InlineTextBox 'PASS'", - "LayoutSVGContainer g id='text2g'", - "LayoutSVGText text", - "LayoutSVGText text", - "LayoutSVGContainer g id='text3g'", - "LayoutSVGText text", - "LayoutSVGInlineText #text", - "InlineTextBox 'PASS '", - "LayoutSVGTSpan tspan", - "InlineFlowBox", - "LayoutSVGInlineText #text", - "InlineTextBox 'PASS'", - "LayoutSVGInlineText #text", - "LayoutSVGForeignObject foreignObject", - "LayoutBlockFlow P", - "LayoutText #text", - "InlineTextBox 'PASS'", - "LayoutSVGViewportContainer svg", - "LayoutSVGText text", - "LayoutSVGInlineText #text", - "InlineTextBox 'PASS'" - ] - } - ] -} -
diff --git a/third_party/WebKit/LayoutTests/platform/linux-precise/transforms/2d/hindi-rotated-expected.png b/third_party/WebKit/LayoutTests/platform/linux-precise/transforms/2d/hindi-rotated-expected.png index 24572a5..5773820 100644 --- a/third_party/WebKit/LayoutTests/platform/linux-precise/transforms/2d/hindi-rotated-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux-precise/transforms/2d/hindi-rotated-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers-expected.png b/third_party/WebKit/LayoutTests/platform/linux/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers-expected.png index 7f50d7d..2063f25 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/compositing/overlap-blending/children-opacity-huge-expected.png b/third_party/WebKit/LayoutTests/platform/linux/compositing/overlap-blending/children-opacity-huge-expected.png new file mode 100644 index 0000000..1fdaa84 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/compositing/overlap-blending/children-opacity-huge-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/compositing/overlap-blending/children-opacity-huge-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/compositing/overlap-blending/children-opacity-huge-expected.txt new file mode 100644 index 0000000..488cb054 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/compositing/overlap-blending/children-opacity-huge-expected.txt
@@ -0,0 +1,15 @@ +layer at (0,0) size 800x600 clip at (0,0) size 800x585 scrollWidth 2150 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x0 + LayoutBlockFlow {HTML} at (0,0) size 800x0 + LayoutBlockFlow {BODY} at (0,0) size 800x0 +layer at (0,0) size 800x0 transparent + LayoutBlockFlow {DIV} at (0,0) size 800x0 +layer at (0,0) size 2150x200 backgroundClip at (0,0) size 800x585 clip at (0,0) size 800x585 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 2150x200 [bgcolor=#008000] + LayoutText {#text} at (0,0) size 8x19 + text run at (0,0) width 8: "1" +layer at (0,100) size 2150x200 backgroundClip at (0,0) size 800x585 clip at (0,0) size 800x585 + LayoutBlockFlow (positioned) {DIV} at (0,100) size 2150x200 [bgcolor=#008000] + LayoutText {#text} at (0,0) size 8x19 + text run at (0,0) width 8: "2"
diff --git a/third_party/WebKit/LayoutTests/platform/linux/compositing/overlap-blending/children-opacity-no-overlap-expected.png b/third_party/WebKit/LayoutTests/platform/linux/compositing/overlap-blending/children-opacity-no-overlap-expected.png new file mode 100644 index 0000000..dc882d2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/compositing/overlap-blending/children-opacity-no-overlap-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/compositing/overlap-blending/children-opacity-no-overlap-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/compositing/overlap-blending/children-opacity-no-overlap-expected.txt new file mode 100644 index 0000000..0b575db --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/compositing/overlap-blending/children-opacity-no-overlap-expected.txt
@@ -0,0 +1,21 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x0 + LayoutBlockFlow {HTML} at (0,0) size 800x0 + LayoutBlockFlow {BODY} at (0,0) size 800x0 +layer at (0,0) size 800x0 transparent + LayoutBlockFlow {DIV} at (0,0) size 800x0 +layer at (0,0) size 100x100 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 100x100 [bgcolor=#008000] + LayoutText {#text} at (0,0) size 8x19 + text run at (0,0) width 8: "1" +layer at (200,200) size 100x100 + LayoutBlockFlow (positioned) {DIV} at (200,200) size 100x100 [bgcolor=#008000] + LayoutText {#text} at (0,0) size 8x19 + text run at (0,0) width 8: "2" +layer at (0,200) size 100x100 + LayoutBlockFlow (positioned) {DIV} at (0,200) size 100x100 [bgcolor=#008000] + LayoutText {#text} at (0,0) size 8x19 + text run at (0,0) width 8: "3" +layer at (200,0) size 100x100 + LayoutBlockFlow (positioned) {DIV} at (200,0) size 100x100 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/compositing/overlap-blending/reflection-opacity-huge-expected.png b/third_party/WebKit/LayoutTests/platform/linux/compositing/overlap-blending/reflection-opacity-huge-expected.png new file mode 100644 index 0000000..4209878 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/compositing/overlap-blending/reflection-opacity-huge-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/compositing/overlap-blending/reflection-opacity-huge-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/compositing/overlap-blending/reflection-opacity-huge-expected.txt new file mode 100644 index 0000000..1bb2d537 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/compositing/overlap-blending/reflection-opacity-huge-expected.txt
@@ -0,0 +1,13 @@ +layer at (0,0) size 800x600 clip at (0,0) size 800x585 scrollWidth 2150 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x240 + LayoutBlockFlow {HTML} at (0,0) size 800x240 + LayoutBlockFlow {BODY} at (0,0) size 800x240 + LayoutBlockFlow {P} at (0,0) size 800x40 + LayoutText {#text} at (0,0) size 798x39 + text run at (0,0) width 798: "Opacity should be applied after reflection, so you should see a green rectangle below. The overlap between the original and reflection" + text run at (0,20) width 126: "should not be visible." +layer at (0,40) size 2150x200 backgroundClip at (0,0) size 800x585 clip at (0,0) size 800x585 transparent + LayoutBlockFlow (relative positioned) {DIV} at (0,40) size 2150x200 [bgcolor=#008000] + LayoutText {#text} at (0,0) size 8x19 + text run at (0,0) width 8: "1"
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css3/blending/background-blend-mode-overlapping-accelerated-elements-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css3/blending/background-blend-mode-overlapping-accelerated-elements-expected.png index b6e878a..8aa8f5a4 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/css3/blending/background-blend-mode-overlapping-accelerated-elements-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/css3/blending/background-blend-mode-overlapping-accelerated-elements-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css3/filters/filter-repaint-composited-fallback-crash-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css3/filters/filter-repaint-composited-fallback-crash-expected.png index dd24593b..a63ed180 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/css3/filters/filter-repaint-composited-fallback-crash-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/css3/filters/filter-repaint-composited-fallback-crash-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css3/filters/filter-repaint-composited-fallback-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css3/filters/filter-repaint-composited-fallback-expected.png index dd24593b..a63ed180 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/css3/filters/filter-repaint-composited-fallback-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/css3/filters/filter-repaint-composited-fallback-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png index 502597b8..84cdf69c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-expected.png index ba3aa66..a08a75eb 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png index 1581b1f..2accd91 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png index fcc0c2f..062b98b 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png index f23c7b58..dada6dc 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png index 96bb9863..2a03708b 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png index 5d57186..db7fe35 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-expected.png index da641d6..fd6394a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-step-expected.png index 6496000a..62bf85b 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-expected.png index d596d52..5c24be1 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-step-expected.png index 30d1714..352610d 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-empty-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-empty-expected.png index c51a4ac..bd31bd16 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-empty-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-empty-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-expected.png index 03f26d6..56574d2a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-fractional-width-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-fractional-width-expected.png index d29be57c..494742a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-fractional-width-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-fractional-width-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-long-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-long-expected.png index 920366d..fd07e66 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-long-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-long-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-many-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-many-expected.png index d669478..eb98be5 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-many-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-many-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-rtl-default-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-rtl-default-expected.png index 8b8cc5b..debbe46 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-rtl-default-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-rtl-default-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-rtl-expected.png index 72a040c4..f454762 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-rtl-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-rtl-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-single-option-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-single-option-expected.png index 795e838..bbb2fab8e 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-single-option-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-single-option-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-styled-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-styled-expected.png index 3b5590d..82ec45b 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-styled-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-styled-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-texttransform-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-texttransform-expected.png index c1120b6..8bd7635 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-texttransform-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-texttransform-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-transform-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-transform-expected.png index a02e4d9..82c47536 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-transform-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-transform-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-zoom-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-zoom-expected.png index 0c6c3a2..bc2329c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-zoom-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-zoom-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-zoom090-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-zoom090-expected.png index 2396e59..9b7f787 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-zoom090-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select-popup/popup-menu-appearance-zoom090-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-1-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-1-and-click-expected.png index 80fe0a8..cdf8c0c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-1-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-1-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-10-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-10-and-click-expected.png index ec02746..e35b96d 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-10-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-10-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-2-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-2-and-click-expected.png index 38a7bb2..f4a36aa 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-2-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-2-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-3-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-3-and-click-expected.png index 69e977d..8a150de 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-3-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-3-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-4-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-4-and-click-expected.png index ae9553e..dad873b1 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-4-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-4-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-5-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-5-and-click-expected.png index 50a5d13..4d7df657 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-5-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-5-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-6-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-6-and-click-expected.png index ec02746..e35b96d 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-6-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-6-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-7-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-7-and-click-expected.png index ec02746..e35b96d 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-7-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-7-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-8-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-8-and-click-expected.png index 02fca1b..71a39e8 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-8-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-8-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-9-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-9-and-click-expected.png index fd8f2b53..90c3a64 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-9-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-add-summary-9-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-1-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-1-and-click-expected.png index 165d197..1e66c86 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-1-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-1-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-2-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-2-and-click-expected.png index 35157ab..b0eda67 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-2-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-2-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-3-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-3-and-click-expected.png index 40ebc65..201606d 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-3-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-3-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-4-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-4-and-click-expected.png index 2c39f0a..61b3c6b 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-4-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-4-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-5-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-5-and-click-expected.png index 18c70840..bf1a02e7d 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-5-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-5-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-6-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-6-and-click-expected.png index 365508c..c20fc9c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-6-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/html/details-remove-summary-6-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/repaint/block-layout-inline-children-replaced-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/repaint/block-layout-inline-children-replaced-expected.txt deleted file mode 100644 index ce294c7..0000000 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/repaint/block-layout-inline-children-replaced-expected.txt +++ /dev/null
@@ -1,27 +0,0 @@ -{ - "bounds": [800, 600], - "children": [ - { - "bounds": [800, 600], - "contentsOpaque": true, - "drawsContent": true, - "paintInvalidations": [ - { - "object": "LayoutBlockFlow DIV id='target' class='target'", - "rect": [0, 36, 402, 152], - "reason": "forced by layout" - }, - { - "object": "LayoutImage IMG", - "rect": [154, 37, 94, 100], - "reason": "location change" - }, - { - "object": "RootInlineBox", - "reason": "full" - } - ] - } - ] -} -
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/repaint/inline-focus-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/repaint/inline-focus-expected.png index dddd4efb..ea869d7 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/fast/repaint/inline-focus-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/repaint/inline-focus-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.png new file mode 100644 index 0000000..f08f1c5c --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.txt new file mode 100644 index 0000000..c09f503 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.txt
@@ -0,0 +1,16 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x116 + LayoutBlockFlow {HTML} at (0,0) size 800x116 + LayoutBlockFlow {BODY} at (8,16) size 784x92 + LayoutBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 727x19 + text run at (0,0) width 727: "crbug.com/636060: Ltr text in a ltr flow should truncate the text left-to-right and underline correctly in composition mode." + LayoutBlockFlow {P} at (0,36) size 784x20 + LayoutText {#text} at (0,0) size 271x19 + text run at (0,0) width 271: "You should see an underline beneath the text." +layer at (8,88) size 125x20 scrollX 19.00 scrollWidth 145 + LayoutBlockFlow {DIV} at (0,72) size 125x20 + LayoutText {#text} at (0,0) size 144x19 + text run at (0,0) width 144: "abcdefghijklmnopqrstuv" +caret: position 22 of child 0 {#text} of child 4 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.png new file mode 100644 index 0000000..8bb4adb --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.txt new file mode 100644 index 0000000..ebc9ae5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.txt
@@ -0,0 +1,16 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x116 + LayoutBlockFlow {HTML} at (0,0) size 800x116 + LayoutBlockFlow {BODY} at (8,16) size 784x92 + LayoutBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 727x19 + text run at (0,0) width 727: "crbug.com/636060: Ltr text in a rtl flow should truncate the text left-to-right and underline correctly in composition mode." + LayoutBlockFlow {P} at (0,36) size 784x20 + LayoutText {#text} at (0,0) size 271x19 + text run at (0,0) width 271: "You should see an underline beneath the text." +layer at (8,88) size 125x20 scrollWidth 144 + LayoutBlockFlow {DIV} at (0,72) size 125x20 + LayoutText {#text} at (-19,0) size 144x19 + text run at (-19,0) width 144: "abcdefghijklmnopqrstuv" +caret: position 22 of child 0 {#text} of child 4 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.png new file mode 100644 index 0000000..5641591e --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.txt new file mode 100644 index 0000000..005ccf58 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.txt
@@ -0,0 +1,17 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x116 + LayoutBlockFlow {HTML} at (0,0) size 800x116 + LayoutBlockFlow {BODY} at (8,16) size 784x92 + LayoutBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 721x19 + text run at (0,0) width 721: "crbug.com/636060: rtl text in a ltr flow should truncate the text left-to-right and underline correctly in composition mode." + LayoutBlockFlow {P} at (0,36) size 784x20 + LayoutText {#text} at (0,0) size 271x19 + text run at (0,0) width 271: "You should see an underline beneath the text." +layer at (8,88) size 125x20 scrollX 63.00 scrollWidth 189 + LayoutBlockFlow {DIV} at (0,72) size 125x20 + LayoutText {#text} at (0,0) size 188x19 + text run at (0,0) width 179 RTL: "\x{5D0}\x{5D1}\x{5D2}\x{5D3}\x{5D4}\x{5D5}\x{5D6}\x{5D7}\x{5D8}\x{5D9}\x{5DB}\x{5DA}\x{5DC}\x{5DE}\x{5DD}\x{5E1}\x{5E2}\x{5E4}\x{5E3}\x{5E6}\x{5E5}\x{5E7}\x{5E8}\x{5E9}\x{5EA}" + text run at (179,0) width 9: "<" +caret: position 26 of child 0 {#text} of child 4 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.png new file mode 100644 index 0000000..f5044cf --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.txt new file mode 100644 index 0000000..e0445d91 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/linux/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.txt
@@ -0,0 +1,16 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x116 + LayoutBlockFlow {HTML} at (0,0) size 800x116 + LayoutBlockFlow {BODY} at (8,16) size 784x92 + LayoutBlockFlow {P} at (0,0) size 784x20 + LayoutText {#text} at (0,0) size 721x19 + text run at (0,0) width 721: "crbug.com/636060: rtl text in a rtl flow should truncate the text left-to-right and underline correctly in composition mode." + LayoutBlockFlow {P} at (0,36) size 784x20 + LayoutText {#text} at (0,0) size 271x19 + text run at (0,0) width 271: "You should see an underline beneath the text." +layer at (8,88) size 125x20 scrollWidth 188 + LayoutBlockFlow {DIV} at (0,72) size 125x20 + LayoutText {#text} at (-63,0) size 188x19 + text run at (-63,0) width 188 RTL: "\x{5D0}\x{5D1}\x{5D2}\x{5D3}\x{5D4}\x{5D5}\x{5D6}\x{5D7}\x{5D8}\x{5D9}\x{5DB}\x{5DA}\x{5DC}\x{5DE}\x{5DD}\x{5E1}\x{5E2}\x{5E4}\x{5E3}\x{5E6}\x{5E5}\x{5E7}\x{5E8}\x{5E9}\x{5EA}<" +caret: position 26 of child 0 {#text} of child 4 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/video-layer-crash-expected.png b/third_party/WebKit/LayoutTests/platform/linux/media/video-layer-crash-expected.png index 1b3157e1..6a3341a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/video-layer-crash-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/media/video-layer-crash-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/media/video-transformed-expected.png b/third_party/WebKit/LayoutTests/platform/linux/media/video-transformed-expected.png index aa656fe..a8e369c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/media/video-transformed-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/media/video-transformed-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/struct-image-06-t-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/struct-image-06-t-expected.txt index 9fb9935..bc4b186b 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/struct-image-06-t-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/struct-image-06-t-expected.txt
@@ -43,9 +43,9 @@ LayoutSVGText {text} at (0,-30) size 81x12 contains 1 chunk(s) LayoutSVGInlineText {#text} at (0,0) size 81x12 chunk 1 text run 1 at (0.00,-20.00) startOffset 0 endOffset 26 width 81.00: "---------- meet ----------" - LayoutSVGContainer {g} at (379,35) size 31x75 [transform={m=((1.00,0.00)(0.00,1.00)) t=(30.00,0.00)}] - LayoutSVGText {text} at (-1,-15) size 25x12 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (0,0) size 25x12 + LayoutSVGContainer {g} at (380,35) size 30x75 [transform={m=((1.00,0.00)(0.00,1.00)) t=(30.00,0.00)}] + LayoutSVGText {text} at (0,-15) size 24x12 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (0,0) size 24x12 chunk 1 text run 1 at (0.00,-5.00) startOffset 0 endOffset 5 width 24.00: "*none" LayoutSVGRect {rect} at (380,50) size 30x60 [stroke={[type=SOLID] [color=#0000FF]}] [x=0.50] [y=0.50] [width=29.00] [height=59.00] LayoutSVGImage {image} at (380,50) size 30x60
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/carto.net/tabgroup-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/carto.net/tabgroup-expected.png index 1fca903..11e0c05 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/carto.net/tabgroup-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/carto.net/tabgroup-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/text-rescale-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/text/text-rescale-expected.txt index b098b46..3e2f3d7d 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/text-rescale-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/text-rescale-expected.txt
@@ -340,6 +340,10 @@ "reason": "location change" }, { + "object": "RootInlineBox", + "reason": "location change" + }, + { "object": "LayoutSVGInlineText #text", "reason": "location change" }, @@ -376,6 +380,10 @@ "reason": "location change" }, { + "object": "RootInlineBox", + "reason": "location change" + }, + { "object": "LayoutText #text", "reason": "location change" }, @@ -392,6 +400,10 @@ "reason": "location change" }, { + "object": "RootInlineBox", + "reason": "location change" + }, + { "object": "LayoutSVGInlineText #text", "reason": "location change" },
diff --git a/third_party/WebKit/LayoutTests/platform/linux/transforms/2d/hindi-rotated-expected.png b/third_party/WebKit/LayoutTests/platform/linux/transforms/2d/hindi-rotated-expected.png index 4821a4d..343623a 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/transforms/2d/hindi-rotated-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/transforms/2d/hindi-rotated-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/prefer_compositing_to_lcd_text/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/prefer_compositing_to_lcd_text/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers-expected.png index 7f50d7d..2063f25 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/prefer_compositing_to_lcd_text/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/prefer_compositing_to_lcd_text/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-appearance-expected.png index 7c7895b9..8944a5c 100644 --- a/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png index 66456c5..4be3801 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-expected.png index b9c3a55..b875d523 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png index b31243a..44cd271 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png index f678ff0..e81f646 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png index 171028d4..f2feb7a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png index a5f09481..2d9b023 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png index 65cad2e..3882341 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-expected.png index 98a38286..24c856f5 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-step-expected.png index 35e92a3..c480fe9 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-expected.png index f8f27f21..adc31e8 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-step-expected.png index 99703fdd..375d16f 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.png new file mode 100644 index 0000000..ccb6aa84 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.png new file mode 100644 index 0000000..871d67a --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.png new file mode 100644 index 0000000..7f00d0a --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.png new file mode 100644 index 0000000..4a9169e6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png index 48c013b..80bf1a3e 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-expected.png index 5a83912..96ee0c1 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png index 96643b6..6a594c7 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png index aa673444..ec6cd7a 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png index 90d8ae9..824eea7 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png index 780556c..69dc326 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png index c8f262f..c3d14b2d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-expected.png index de2f1de..dab938c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-step-expected.png index 82adc5b..694dd66 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-expected.png index f3dd6ff..4314835 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-step-expected.png index 94e2197..febd96d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.png new file mode 100644 index 0000000..da9e6988 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.png new file mode 100644 index 0000000..665ecdb2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.png new file mode 100644 index 0000000..738d7f31 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.png new file mode 100644 index 0000000..726d244 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/transforms/2d/hindi-rotated-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/transforms/2d/hindi-rotated-expected.png index 2aa0726..a42698bd 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/transforms/2d/hindi-rotated-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/transforms/2d/hindi-rotated-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-1-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-1-and-click-expected.png new file mode 100644 index 0000000..85ebc38 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-1-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-1-and-click-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-1-and-click-expected.txt new file mode 100644 index 0000000..73d555d --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-1-and-click-expected.txt
@@ -0,0 +1,10 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (0,0) size 800x600 + LayoutBlockFlow {DETAILS} at (0,0) size 800x18 + LayoutBlockFlow {SUMMARY} at (0,0) size 800x18 + LayoutDetailsMarker {DIV} at (0,3) size 10.55x10.55: right + LayoutText {#text} at (16,0) size 47x18 + text run at (16,0) width 47: "Details"
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-10-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-10-and-click-expected.png new file mode 100644 index 0000000..4b0c6bc --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-10-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-10-and-click-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-10-and-click-expected.txt new file mode 100644 index 0000000..9a2f15e2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-10-and-click-expected.txt
@@ -0,0 +1,11 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (0,0) size 800x600 + LayoutBlockFlow {DETAILS} at (0,0) size 800x18 + LayoutBlockFlow {SUMMARY} at (0,0) size 800x18 + LayoutDetailsMarker {DIV} at (0,3) size 10.55x10.55: down + LayoutText {#text} at (16,0) size 61x18 + text run at (16,0) width 61: "summary" + LayoutBlockFlow {DIV} at (0,18) size 800x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-2-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-2-and-click-expected.png new file mode 100644 index 0000000..85ebc38 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-2-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-2-and-click-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-2-and-click-expected.txt new file mode 100644 index 0000000..73d555d --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-2-and-click-expected.txt
@@ -0,0 +1,10 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (0,0) size 800x600 + LayoutBlockFlow {DETAILS} at (0,0) size 800x18 + LayoutBlockFlow {SUMMARY} at (0,0) size 800x18 + LayoutDetailsMarker {DIV} at (0,3) size 10.55x10.55: right + LayoutText {#text} at (16,0) size 47x18 + text run at (16,0) width 47: "Details"
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-3-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-3-and-click-expected.png new file mode 100644 index 0000000..85ebc38 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-3-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-3-and-click-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-3-and-click-expected.txt new file mode 100644 index 0000000..73d555d --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-3-and-click-expected.txt
@@ -0,0 +1,10 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (0,0) size 800x600 + LayoutBlockFlow {DETAILS} at (0,0) size 800x18 + LayoutBlockFlow {SUMMARY} at (0,0) size 800x18 + LayoutDetailsMarker {DIV} at (0,3) size 10.55x10.55: right + LayoutText {#text} at (16,0) size 47x18 + text run at (16,0) width 47: "Details"
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-4-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-4-and-click-expected.png new file mode 100644 index 0000000..2bc1e2f --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-4-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-4-and-click-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-4-and-click-expected.txt new file mode 100644 index 0000000..2d2bc0c --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-4-and-click-expected.txt
@@ -0,0 +1,10 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (0,0) size 800x600 + LayoutBlockFlow {DETAILS} at (0,0) size 800x18 + LayoutBlockFlow {SUMMARY} at (0,0) size 800x18 + LayoutDetailsMarker {DIV} at (0,3) size 10.55x10.55: right + LayoutText {#text} at (16,0) size 61x18 + text run at (16,0) width 61: "summary"
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-5-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-5-and-click-expected.png new file mode 100644 index 0000000..2bc1e2f --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-5-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-5-and-click-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-5-and-click-expected.txt new file mode 100644 index 0000000..2d2bc0c --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-5-and-click-expected.txt
@@ -0,0 +1,10 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (0,0) size 800x600 + LayoutBlockFlow {DETAILS} at (0,0) size 800x18 + LayoutBlockFlow {SUMMARY} at (0,0) size 800x18 + LayoutDetailsMarker {DIV} at (0,3) size 10.55x10.55: right + LayoutText {#text} at (16,0) size 61x18 + text run at (16,0) width 61: "summary"
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-6-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-6-and-click-expected.png new file mode 100644 index 0000000..14782c0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-6-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-6-and-click-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-6-and-click-expected.txt new file mode 100644 index 0000000..703e801 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-6-and-click-expected.txt
@@ -0,0 +1,11 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (0,0) size 800x600 + LayoutBlockFlow {DETAILS} at (0,0) size 800x18 + LayoutBlockFlow {SUMMARY} at (0,0) size 800x18 + LayoutDetailsMarker {DIV} at (0,3) size 10.55x10.55: down + LayoutText {#text} at (16,0) size 47x18 + text run at (16,0) width 47: "Details" + LayoutBlockFlow {DIV} at (0,18) size 800x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-7-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-7-and-click-expected.png new file mode 100644 index 0000000..14782c0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-7-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-7-and-click-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-7-and-click-expected.txt new file mode 100644 index 0000000..703e801 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-7-and-click-expected.txt
@@ -0,0 +1,11 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (0,0) size 800x600 + LayoutBlockFlow {DETAILS} at (0,0) size 800x18 + LayoutBlockFlow {SUMMARY} at (0,0) size 800x18 + LayoutDetailsMarker {DIV} at (0,3) size 10.55x10.55: down + LayoutText {#text} at (16,0) size 47x18 + text run at (16,0) width 47: "Details" + LayoutBlockFlow {DIV} at (0,18) size 800x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-8-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-8-and-click-expected.png new file mode 100644 index 0000000..14782c0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-8-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-8-and-click-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-8-and-click-expected.txt new file mode 100644 index 0000000..703e801 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-8-and-click-expected.txt
@@ -0,0 +1,11 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (0,0) size 800x600 + LayoutBlockFlow {DETAILS} at (0,0) size 800x18 + LayoutBlockFlow {SUMMARY} at (0,0) size 800x18 + LayoutDetailsMarker {DIV} at (0,3) size 10.55x10.55: down + LayoutText {#text} at (16,0) size 47x18 + text run at (16,0) width 47: "Details" + LayoutBlockFlow {DIV} at (0,18) size 800x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-9-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-9-and-click-expected.png new file mode 100644 index 0000000..4b0c6bc --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-9-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-9-and-click-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-9-and-click-expected.txt new file mode 100644 index 0000000..9a2f15e2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-add-summary-9-and-click-expected.txt
@@ -0,0 +1,11 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (0,0) size 800x600 + LayoutBlockFlow {DETAILS} at (0,0) size 800x18 + LayoutBlockFlow {SUMMARY} at (0,0) size 800x18 + LayoutDetailsMarker {DIV} at (0,3) size 10.55x10.55: down + LayoutText {#text} at (16,0) size 61x18 + text run at (16,0) width 61: "summary" + LayoutBlockFlow {DIV} at (0,18) size 800x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-1-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-1-and-click-expected.png new file mode 100644 index 0000000..2bc1e2f --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-1-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-1-and-click-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-1-and-click-expected.txt new file mode 100644 index 0000000..2d2bc0c --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-1-and-click-expected.txt
@@ -0,0 +1,10 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (0,0) size 800x600 + LayoutBlockFlow {DETAILS} at (0,0) size 800x18 + LayoutBlockFlow {SUMMARY} at (0,0) size 800x18 + LayoutDetailsMarker {DIV} at (0,3) size 10.55x10.55: right + LayoutText {#text} at (16,0) size 61x18 + text run at (16,0) width 61: "summary"
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-2-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-2-and-click-expected.png new file mode 100644 index 0000000..db91931 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-2-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-2-and-click-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-2-and-click-expected.txt new file mode 100644 index 0000000..b1f8421c07 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-2-and-click-expected.txt
@@ -0,0 +1,10 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (0,0) size 800x600 + LayoutBlockFlow {DETAILS} at (0,0) size 800x18 + LayoutBlockFlow {SUMMARY} at (0,0) size 800x18 + LayoutDetailsMarker {DIV} at (0,3) size 10.55x10.55: right + LayoutText {#text} at (16,0) size 73x18 + text run at (16,0) width 73: "summary 1"
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-3-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-3-and-click-expected.png new file mode 100644 index 0000000..db91931 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-3-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-3-and-click-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-3-and-click-expected.txt new file mode 100644 index 0000000..b1f8421c07 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-3-and-click-expected.txt
@@ -0,0 +1,10 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (0,0) size 800x600 + LayoutBlockFlow {DETAILS} at (0,0) size 800x18 + LayoutBlockFlow {SUMMARY} at (0,0) size 800x18 + LayoutDetailsMarker {DIV} at (0,3) size 10.55x10.55: right + LayoutText {#text} at (16,0) size 73x18 + text run at (16,0) width 73: "summary 1"
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-4-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-4-and-click-expected.png new file mode 100644 index 0000000..4b0c6bc --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-4-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-4-and-click-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-4-and-click-expected.txt new file mode 100644 index 0000000..9a2f15e2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-4-and-click-expected.txt
@@ -0,0 +1,11 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (0,0) size 800x600 + LayoutBlockFlow {DETAILS} at (0,0) size 800x18 + LayoutBlockFlow {SUMMARY} at (0,0) size 800x18 + LayoutDetailsMarker {DIV} at (0,3) size 10.55x10.55: down + LayoutText {#text} at (16,0) size 61x18 + text run at (16,0) width 61: "summary" + LayoutBlockFlow {DIV} at (0,18) size 800x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-5-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-5-and-click-expected.png new file mode 100644 index 0000000..9c229dad --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-5-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-5-and-click-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-5-and-click-expected.txt new file mode 100644 index 0000000..0dcb95f --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-5-and-click-expected.txt
@@ -0,0 +1,14 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (0,0) size 800x600 + LayoutBlockFlow {DETAILS} at (0,0) size 800x36 + LayoutBlockFlow {SUMMARY} at (0,0) size 800x18 + LayoutDetailsMarker {DIV} at (0,3) size 10.55x10.55: down + LayoutText {#text} at (16,0) size 73x18 + text run at (16,0) width 73: "summary 1" + LayoutBlockFlow {DIV} at (0,18) size 800x18 + LayoutBlockFlow {SUMMARY} at (0,0) size 800x18 + LayoutText {#text} at (0,0) size 72x18 + text run at (0,0) width 72: "summary 2"
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-6-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-6-and-click-expected.png new file mode 100644 index 0000000..9c229dad --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-6-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-6-and-click-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-6-and-click-expected.txt new file mode 100644 index 0000000..0dcb95f --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/html/details-remove-summary-6-and-click-expected.txt
@@ -0,0 +1,14 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (0,0) size 800x600 + LayoutBlockFlow {DETAILS} at (0,0) size 800x36 + LayoutBlockFlow {SUMMARY} at (0,0) size 800x18 + LayoutDetailsMarker {DIV} at (0,3) size 10.55x10.55: down + LayoutText {#text} at (16,0) size 73x18 + text run at (16,0) width 73: "summary 1" + LayoutBlockFlow {DIV} at (0,18) size 800x18 + LayoutBlockFlow {SUMMARY} at (0,0) size 800x18 + LayoutText {#text} at (0,0) size 72x18 + text run at (0,0) width 72: "summary 2"
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/media/video-layer-crash-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-retina/media/video-layer-crash-expected.txt deleted file mode 100644 index 1cb5593..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac-retina/media/video-layer-crash-expected.txt +++ /dev/null
@@ -1,32 +0,0 @@ -layer at (0,0) size 800x600 - LayoutView at (0,0) size 800x600 -layer at (0,0) size 800x600 - LayoutBlockFlow {HTML} at (0,0) size 800x600 - LayoutBlockFlow {BODY} at (8,8) size 784x584 - LayoutBlockFlow {P} at (0,0) size 784x18 - LayoutText {#text} at (0,0) size 367x18 - text run at (0,0) width 367: "Test dynamic removal of transformed and reflected video" - LayoutBlockFlow (anonymous) at (0,34) size 784x338 - LayoutText {#text} at (0,0) size 4x18 - text run at (0,0) width 4: " " - LayoutBR {BR} at (4,14) size 0x0 - LayoutText {#text} at (0,160) size 4x18 - text run at (0,160) width 4: " " - LayoutBR {BR} at (210,174) size 0x0 - LayoutText {#text} at (0,320) size 4x18 - text run at (0,320) width 4: " " - LayoutBR {BR} at (210,334) size 0x0 -layer at (12,60) size 206x156 - LayoutVideo {VIDEO} at (4,18) size 206x156 [border: (3px solid #FF0000)] -layer at (15,63) size 200x150 - LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 - LayoutBlockFlow {DIV} at (0,118) size 200x32 -layer at (15,63) size 200x108 - LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x108 -layer at (12,220) size 206x156 - LayoutVideo {VIDEO} at (4,178) size 206x156 [border: (3px solid #FF0000)] -layer at (15,223) size 200x150 - LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 - LayoutBlockFlow {DIV} at (0,118) size 200x32 -layer at (15,223) size 200x108 - LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x108
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/overlap-blending/children-opacity-huge-expected.png b/third_party/WebKit/LayoutTests/platform/mac/compositing/overlap-blending/children-opacity-huge-expected.png new file mode 100644 index 0000000..7ed0db5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/overlap-blending/children-opacity-huge-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/overlap-blending/children-opacity-huge-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/compositing/overlap-blending/children-opacity-huge-expected.txt new file mode 100644 index 0000000..510f1955 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/overlap-blending/children-opacity-huge-expected.txt
@@ -0,0 +1,15 @@ +layer at (0,0) size 800x600 clip at (0,0) size 800x585 scrollWidth 2150 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x0 + LayoutBlockFlow {HTML} at (0,0) size 800x0 + LayoutBlockFlow {BODY} at (0,0) size 800x0 +layer at (0,0) size 800x0 transparent + LayoutBlockFlow {DIV} at (0,0) size 800x0 +layer at (0,0) size 2150x200 backgroundClip at (0,0) size 800x585 clip at (0,0) size 800x585 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 2150x200 [bgcolor=#008000] + LayoutText {#text} at (0,0) size 8x18 + text run at (0,0) width 8: "1" +layer at (0,100) size 2150x200 backgroundClip at (0,0) size 800x585 clip at (0,0) size 800x585 + LayoutBlockFlow (positioned) {DIV} at (0,100) size 2150x200 [bgcolor=#008000] + LayoutText {#text} at (0,0) size 8x18 + text run at (0,0) width 8: "2"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/overlap-blending/children-opacity-no-overlap-expected.png b/third_party/WebKit/LayoutTests/platform/mac/compositing/overlap-blending/children-opacity-no-overlap-expected.png new file mode 100644 index 0000000..f417c40 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/overlap-blending/children-opacity-no-overlap-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/overlap-blending/children-opacity-no-overlap-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/compositing/overlap-blending/children-opacity-no-overlap-expected.txt new file mode 100644 index 0000000..0d522f94 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/overlap-blending/children-opacity-no-overlap-expected.txt
@@ -0,0 +1,21 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x0 + LayoutBlockFlow {HTML} at (0,0) size 800x0 + LayoutBlockFlow {BODY} at (0,0) size 800x0 +layer at (0,0) size 800x0 transparent + LayoutBlockFlow {DIV} at (0,0) size 800x0 +layer at (0,0) size 100x100 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 100x100 [bgcolor=#008000] + LayoutText {#text} at (0,0) size 8x18 + text run at (0,0) width 8: "1" +layer at (200,200) size 100x100 + LayoutBlockFlow (positioned) {DIV} at (200,200) size 100x100 [bgcolor=#008000] + LayoutText {#text} at (0,0) size 8x18 + text run at (0,0) width 8: "2" +layer at (0,200) size 100x100 + LayoutBlockFlow (positioned) {DIV} at (0,200) size 100x100 [bgcolor=#008000] + LayoutText {#text} at (0,0) size 8x18 + text run at (0,0) width 8: "3" +layer at (200,0) size 100x100 + LayoutBlockFlow (positioned) {DIV} at (200,0) size 100x100 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/overlap-blending/reflection-opacity-huge-expected.png b/third_party/WebKit/LayoutTests/platform/mac/compositing/overlap-blending/reflection-opacity-huge-expected.png new file mode 100644 index 0000000..004a598a --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/overlap-blending/reflection-opacity-huge-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/overlap-blending/reflection-opacity-huge-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/compositing/overlap-blending/reflection-opacity-huge-expected.txt new file mode 100644 index 0000000..a7703db --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/overlap-blending/reflection-opacity-huge-expected.txt
@@ -0,0 +1,13 @@ +layer at (0,0) size 800x600 clip at (0,0) size 800x585 scrollWidth 2150 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x236 + LayoutBlockFlow {HTML} at (0,0) size 800x236 + LayoutBlockFlow {BODY} at (0,0) size 800x236 + LayoutBlockFlow {P} at (0,0) size 800x36 + LayoutText {#text} at (0,0) size 789x36 + text run at (0,0) width 789: "Opacity should be applied after reflection, so you should see a green rectangle below. The overlap between the original and" + text run at (0,18) width 202: "reflection should not be visible." +layer at (0,36) size 2150x200 backgroundClip at (0,0) size 800x585 clip at (0,0) size 800x585 transparent + LayoutBlockFlow (relative positioned) {DIV} at (0,36) size 2150x200 [bgcolor=#008000] + LayoutText {#text} at (0,0) size 8x18 + text run at (0,0) width 8: "1"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-overlapping-accelerated-elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-overlapping-accelerated-elements-expected.png index cb048616..20c0624 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-overlapping-accelerated-elements-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-overlapping-accelerated-elements-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/filter-repaint-composited-fallback-crash-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/filter-repaint-composited-fallback-crash-expected.png index dd24593b..a63ed180 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/filter-repaint-composited-fallback-crash-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/filter-repaint-composited-fallback-crash-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/filter-repaint-composited-fallback-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/filter-repaint-composited-fallback-expected.png index dd24593b..a63ed180 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/css3/filters/filter-repaint-composited-fallback-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/css3/filters/filter-repaint-composited-fallback-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png index 062bf92..e30ffbb 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-expected.png index a68f08e4..6865efb 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png index 6043915..c4d1dcf 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png index 9ae4e20b..ff2382d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png index 25cc4ca..833aebf 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png index 262841a..95b8d6828 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png index 73e231e..83e067b 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-expected.png index b9ad0cb..304f1e2 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-step-expected.png index 2431e8a..5efe5c8 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-expected.png index c8e49585..f7775a4 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-step-expected.png index dd318fa..f07dba90 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/listbox-with-display-none-option-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/listbox-with-display-none-option-expected.png index 34e77e6..970ee95d 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/listbox-with-display-none-option-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/listbox-with-display-none-option-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/listbox-with-display-none-option-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/listbox-with-display-none-option-expected.txt index 1fd0155..25252c9 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/listbox-with-display-none-option-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/listbox-with-display-none-option-expected.txt
@@ -11,10 +11,10 @@ text run at (48,97) width 5: " " LayoutText {#text} at (117,97) size 5x18 text run at (117,97) width 5: " " - LayoutText {#text} at (186,97) size 5x18 - text run at (186,97) width 5: " " - LayoutText {#text} at (239,97) size 5x18 - text run at (239,97) width 5: " " + LayoutText {#text} at (185,97) size 5x18 + text run at (185,97) width 5: " " + LayoutText {#text} at (238,97) size 5x18 + text run at (238,97) width 5: " " LayoutText {#text} at (291,97) size 5x18 text run at (291,97) width 5: " " LayoutText {#text} at (0,0) size 0x0 @@ -39,56 +39,56 @@ LayoutBlockFlow {OPTION} at (1,71.94) size 35.64x14.19 LayoutText {#text} at (2,0) size 32x13 text run at (2,0) width 32: "Seven" -layer at (61,64) size 65x101 clip at (62,65) size 52x99 - LayoutListBox {SELECT} at (52.64,13.69) size 64.98x101.31 [bgcolor=#FFFFFF] [border: (1px solid #999999)] - LayoutBlockFlow {OPTION} at (1,1) size 51.98x14.19 +layer at (61,64) size 64x101 clip at (62,65) size 51x99 + LayoutListBox {SELECT} at (52.64,13.69) size 64.55x101.31 [bgcolor=#FFFFFF] [border: (1px solid #999999)] + LayoutBlockFlow {OPTION} at (1,1) size 51.55x14.19 LayoutText {#text} at (2,0) size 22x13 text run at (2,0) width 22: "One" - LayoutBlockFlow {OPTION} at (1,15.19) size 51.98x14.19 + LayoutBlockFlow {OPTION} at (1,15.19) size 51.55x14.19 LayoutText {#text} at (2,0) size 22x13 text run at (2,0) width 22: "Two" - LayoutBlockFlow {OPTION} at (1,29.38) size 51.98x14.19 + LayoutBlockFlow {OPTION} at (1,29.38) size 51.55x14.19 LayoutText {#text} at (2,0) size 31x13 text run at (2,0) width 31: "Three" - LayoutBlockFlow {OPTGROUP} at (1,43.56) size 51.98x28.38 - LayoutBlockFlow {DIV} at (0,0) size 51.98x14.19 + LayoutBlockFlow {OPTGROUP} at (1,43.56) size 51.55x28.38 + LayoutBlockFlow {DIV} at (0,0) size 51.55x14.19 LayoutText {#text} at (2,0) size 48x13 text run at (2,0) width 48: "***45***" - LayoutBlockFlow {OPTION} at (0,14.19) size 51.98x14.19 + LayoutBlockFlow {OPTION} at (0,14.19) size 51.55x14.19 LayoutInline {<pseudo:before>} at (0,0) size 13x13 LayoutTextFragment (anonymous) at (2,0) size 13x13 text run at (2,0) width 13: " " LayoutText {#text} at (14,0) size 22x13 text run at (14,0) width 22: "Five" - LayoutBlockFlow {OPTION} at (1,71.94) size 51.98x14.19 + LayoutBlockFlow {OPTION} at (1,71.94) size 51.55x14.19 LayoutText {#text} at (2,0) size 32x13 text run at (2,0) width 32: "Seven" -layer at (130,64) size 65x101 clip at (131,65) size 52x99 - LayoutListBox {SELECT} at (121.63,13.69) size 64.98x101.31 [bgcolor=#FFFFFF] [border: (1px solid #999999)] - LayoutBlockFlow {OPTION} at (1,1) size 51.98x14.19 +layer at (129,64) size 65x101 clip at (130,65) size 52x99 + LayoutListBox {SELECT} at (121.19,13.69) size 64.55x101.31 [bgcolor=#FFFFFF] [border: (1px solid #999999)] + LayoutBlockFlow {OPTION} at (1,1) size 51.55x14.19 LayoutText {#text} at (2,0) size 22x13 text run at (2,0) width 22: "One" - LayoutBlockFlow {OPTION} at (1,15.19) size 51.98x14.19 + LayoutBlockFlow {OPTION} at (1,15.19) size 51.55x14.19 LayoutText {#text} at (2,0) size 22x13 text run at (2,0) width 22: "Two" - LayoutBlockFlow {OPTGROUP} at (1,29.38) size 51.98x28.38 - LayoutBlockFlow {DIV} at (0,0) size 51.98x14.19 + LayoutBlockFlow {OPTGROUP} at (1,29.38) size 51.55x28.38 + LayoutBlockFlow {DIV} at (0,0) size 51.55x14.19 LayoutText {#text} at (2,0) size 48x13 text run at (2,0) width 48: "***45***" - LayoutBlockFlow {OPTION} at (0,14.19) size 51.98x14.19 + LayoutBlockFlow {OPTION} at (0,14.19) size 51.55x14.19 LayoutInline {<pseudo:before>} at (0,0) size 13x13 LayoutTextFragment (anonymous) at (2,0) size 13x13 text run at (2,0) width 13: " " LayoutText {#text} at (14,0) size 24x13 text run at (14,0) width 24: "Four" - LayoutBlockFlow {OPTION} at (1,57.75) size 51.98x14.19 + LayoutBlockFlow {OPTION} at (1,57.75) size 51.55x14.19 LayoutText {#text} at (2,0) size 16x13 text run at (2,0) width 16: "Six" - LayoutBlockFlow {OPTION} at (1,71.94) size 51.98x14.19 + LayoutBlockFlow {OPTION} at (1,71.94) size 51.55x14.19 LayoutText {#text} at (2,0) size 32x13 text run at (2,0) width 32: "Seven" -layer at (199,50) size 48x115 clip at (200,51) size 35x113 - LayoutListBox {SELECT} at (190.61,-0.50) size 48.64x115.50 [bgcolor=#FFFFFF] [border: (1px solid #999999)] +layer at (198,50) size 48x115 clip at (199,51) size 35x113 + LayoutListBox {SELECT} at (189.73,-0.50) size 48.64x115.50 [bgcolor=#FFFFFF] [border: (1px solid #999999)] LayoutBlockFlow {OPTION} at (1,1) size 35.64x14.19 LayoutText {#text} at (2,0) size 22x13 text run at (2,0) width 22: "One" @@ -101,8 +101,8 @@ LayoutBlockFlow {OPTION} at (1,43.56) size 35.64x14.19 LayoutText {#text} at (2,0) size 32x13 text run at (2,0) width 32: "Seven" -layer at (251,50) size 49x115 clip at (252,51) size 36x113 - LayoutListBox {SELECT} at (243.25,-0.50) size 48.64x115.50 [bgcolor=#FFFFFF] [border: (1px solid #999999)] +layer at (250,50) size 49x115 clip at (251,51) size 36x113 + LayoutListBox {SELECT} at (242.38,-0.50) size 48.64x115.50 [bgcolor=#FFFFFF] [border: (1px solid #999999)] LayoutBlockFlow {OPTION} at (1,1) size 35.64x14.19 LayoutText {#text} at (2,0) size 22x13 text run at (2,0) width 22: "One" @@ -115,39 +115,39 @@ LayoutBlockFlow {OPTION} at (1,43.56) size 35.64x14.19 LayoutText {#text} at (2,0) size 32x13 text run at (2,0) width 32: "Seven" -layer at (304,50) size 61x115 clip at (305,51) size 48x113 - LayoutListBox {SELECT} at (295.89,-0.50) size 61.47x115.50 [bgcolor=#FFFFFF] [border: (1px solid #999999)] - LayoutBlockFlow {OPTION} at (1,1) size 48.47x14.19 +layer at (303,50) size 61x115 clip at (304,51) size 48x113 + LayoutListBox {SELECT} at (295.02,-0.50) size 61.05x115.50 [bgcolor=#FFFFFF] [border: (1px solid #999999)] + LayoutBlockFlow {OPTION} at (1,1) size 48.05x14.19 LayoutText {#text} at (2,0) size 22x13 text run at (2,0) width 22: "One" - LayoutBlockFlow {OPTION} at (1,15.19) size 48.47x14.19 + LayoutBlockFlow {OPTION} at (1,15.19) size 48.05x14.19 LayoutText {#text} at (2,0) size 22x13 text run at (2,0) width 22: "Two" - LayoutBlockFlow {OPTION} at (1,29.38) size 48.47x14.19 + LayoutBlockFlow {OPTION} at (1,29.38) size 48.05x14.19 LayoutText {#text} at (2,0) size 31x13 text run at (2,0) width 31: "Three" - LayoutBlockFlow {OPTGROUP} at (1,43.56) size 48.47x56.75 - LayoutBlockFlow {DIV} at (0,0) size 48.47x14.19 + LayoutBlockFlow {OPTGROUP} at (1,43.56) size 48.05x56.75 + LayoutBlockFlow {DIV} at (0,0) size 48.05x14.19 LayoutText {#text} at (2,0) size 45x13 text run at (2,0) width 45: "**456**" - LayoutBlockFlow {OPTION} at (0,14.19) size 48.47x14.19 + LayoutBlockFlow {OPTION} at (0,14.19) size 48.05x14.19 LayoutInline {<pseudo:before>} at (0,0) size 13x13 LayoutTextFragment (anonymous) at (2,0) size 13x13 text run at (2,0) width 13: " " LayoutText {#text} at (14,0) size 24x13 text run at (14,0) width 24: "Four" - LayoutBlockFlow {OPTION} at (0,28.38) size 48.47x14.19 + LayoutBlockFlow {OPTION} at (0,28.38) size 48.05x14.19 LayoutInline {<pseudo:before>} at (0,0) size 13x13 LayoutTextFragment (anonymous) at (2,0) size 13x13 text run at (2,0) width 13: " " LayoutText {#text} at (14,0) size 22x13 text run at (14,0) width 22: "Five" - LayoutBlockFlow {OPTION} at (0,42.56) size 48.47x14.19 + LayoutBlockFlow {OPTION} at (0,42.56) size 48.05x14.19 LayoutInline {<pseudo:before>} at (0,0) size 13x13 LayoutTextFragment (anonymous) at (2,0) size 13x13 text run at (2,0) width 13: " " LayoutText {#text} at (14,0) size 16x13 text run at (14,0) width 16: "Six" - LayoutBlockFlow {OPTION} at (1,100.31) size 48.47x14.19 + LayoutBlockFlow {OPTION} at (1,100.31) size 48.05x14.19 LayoutText {#text} at (2,0) size 32x13 text run at (2,0) width 32: "Seven"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/repaint/block-layout-inline-children-replaced-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/repaint/block-layout-inline-children-replaced-expected.txt deleted file mode 100644 index 0e3670f..0000000 --- a/third_party/WebKit/LayoutTests/platform/mac/fast/repaint/block-layout-inline-children-replaced-expected.txt +++ /dev/null
@@ -1,27 +0,0 @@ -{ - "bounds": [800, 600], - "children": [ - { - "bounds": [800, 600], - "contentsOpaque": true, - "drawsContent": true, - "paintInvalidations": [ - { - "object": "LayoutBlockFlow DIV id='target' class='target'", - "rect": [0, 34, 402, 152], - "reason": "forced by layout" - }, - { - "object": "LayoutImage IMG", - "rect": [154, 35, 94, 100], - "reason": "location change" - }, - { - "object": "RootInlineBox", - "reason": "full" - } - ] - } - ] -} -
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.png new file mode 100644 index 0000000..7edd5df --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.txt new file mode 100644 index 0000000..67d0d014 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.txt
@@ -0,0 +1,16 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x112 + LayoutBlockFlow {HTML} at (0,0) size 800x112 + LayoutBlockFlow {BODY} at (8,16) size 784x88 + LayoutBlockFlow {P} at (0,0) size 784x18 + LayoutText {#text} at (0,0) size 783x18 + text run at (0,0) width 783: "crbug.com/636060: Ltr text in a ltr flow should truncate the text left-to-right and underline correctly in composition mode." + LayoutBlockFlow {P} at (0,34) size 784x18 + LayoutText {#text} at (0,0) size 290x18 + text run at (0,0) width 290: "You should see an underline beneath the text." +layer at (8,84) size 125x20 scrollX 31.00 scrollWidth 157 + LayoutBlockFlow {DIV} at (0,68) size 125x20 + LayoutText {#text} at (0,0) size 157x18 + text run at (0,0) width 157: "abcdefghijklmnopqrstuv" +caret: position 22 of child 0 {#text} of child 4 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.png new file mode 100644 index 0000000..a154944 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.txt new file mode 100644 index 0000000..8c0c5ac --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.txt
@@ -0,0 +1,16 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x112 + LayoutBlockFlow {HTML} at (0,0) size 800x112 + LayoutBlockFlow {BODY} at (8,16) size 784x88 + LayoutBlockFlow {P} at (0,0) size 784x18 + LayoutText {#text} at (0,0) size 783x18 + text run at (0,0) width 783: "crbug.com/636060: Ltr text in a rtl flow should truncate the text left-to-right and underline correctly in composition mode." + LayoutBlockFlow {P} at (0,34) size 784x18 + LayoutText {#text} at (0,0) size 290x18 + text run at (0,0) width 290: "You should see an underline beneath the text." +layer at (8,84) size 125x20 scrollWidth 156 + LayoutBlockFlow {DIV} at (0,68) size 125x20 + LayoutText {#text} at (-31,0) size 157x18 + text run at (-31,0) width 156: "abcdefghijklmnopqrstuv" +caret: position 22 of child 0 {#text} of child 4 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.png new file mode 100644 index 0000000..7d6dc52 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.txt new file mode 100644 index 0000000..23a615ec --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.txt
@@ -0,0 +1,17 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x112 + LayoutBlockFlow {HTML} at (0,0) size 800x112 + LayoutBlockFlow {BODY} at (8,16) size 784x88 + LayoutBlockFlow {P} at (0,0) size 784x18 + LayoutText {#text} at (0,0) size 778x18 + text run at (0,0) width 778: "crbug.com/636060: rtl text in a ltr flow should truncate the text left-to-right and underline correctly in composition mode." + LayoutBlockFlow {P} at (0,34) size 784x18 + LayoutText {#text} at (0,0) size 290x18 + text run at (0,0) width 290: "You should see an underline beneath the text." +layer at (8,84) size 125x20 scrollX 111.00 scrollWidth 237 + LayoutBlockFlow {DIV} at (0,68) size 125x20 + LayoutText {#text} at (0,1) size 237x18 + text run at (0,1) width 228 RTL: "\x{5D0}\x{5D1}\x{5D2}\x{5D3}\x{5D4}\x{5D5}\x{5D6}\x{5D7}\x{5D8}\x{5D9}\x{5DB}\x{5DA}\x{5DC}\x{5DE}\x{5DD}\x{5E1}\x{5E2}\x{5E4}\x{5E3}\x{5E6}\x{5E5}\x{5E7}\x{5E8}\x{5E9}\x{5EA}" + text run at (227,1) width 10: "<" +caret: position 26 of child 0 {#text} of child 4 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.png new file mode 100644 index 0000000..f03870f --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.txt new file mode 100644 index 0000000..4714c8c8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/mac/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.txt
@@ -0,0 +1,16 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x112 + LayoutBlockFlow {HTML} at (0,0) size 800x112 + LayoutBlockFlow {BODY} at (8,16) size 784x88 + LayoutBlockFlow {P} at (0,0) size 784x18 + LayoutText {#text} at (0,0) size 778x18 + text run at (0,0) width 778: "crbug.com/636060: rtl text in a rtl flow should truncate the text left-to-right and underline correctly in composition mode." + LayoutBlockFlow {P} at (0,34) size 784x18 + LayoutText {#text} at (0,0) size 290x18 + text run at (0,0) width 290: "You should see an underline beneath the text." +layer at (8,84) size 125x20 scrollWidth 236 + LayoutBlockFlow {DIV} at (0,68) size 125x20 + LayoutText {#text} at (-111,1) size 237x18 + text run at (-111,1) width 236 RTL: "\x{5D0}\x{5D1}\x{5D2}\x{5D3}\x{5D4}\x{5D5}\x{5D6}\x{5D7}\x{5D8}\x{5D9}\x{5DB}\x{5DA}\x{5DC}\x{5DE}\x{5DD}\x{5E1}\x{5E2}\x{5E4}\x{5E3}\x{5E6}\x{5E5}\x{5E7}\x{5E8}\x{5E9}\x{5EA}<" +caret: position 26 of child 0 {#text} of child 4 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/video-layer-crash-expected.png b/third_party/WebKit/LayoutTests/platform/mac/media/video-layer-crash-expected.png index fd2ad5f..fe2e6a3 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/video-layer-crash-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/media/video-layer-crash-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/media/video-transformed-expected.png b/third_party/WebKit/LayoutTests/platform/mac/media/video-transformed-expected.png index 2d510639..67f1b35c 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/media/video-transformed-expected.png +++ b/third_party/WebKit/LayoutTests/platform/mac/media/video-transformed-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/text-rescale-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/text/text-rescale-expected.txt index 32312915..45c62b4 100644 --- a/third_party/WebKit/LayoutTests/platform/mac/svg/text/text-rescale-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/text-rescale-expected.txt
@@ -340,6 +340,10 @@ "reason": "location change" }, { + "object": "RootInlineBox", + "reason": "location change" + }, + { "object": "LayoutSVGInlineText #text", "reason": "location change" }, @@ -376,6 +380,10 @@ "reason": "location change" }, { + "object": "RootInlineBox", + "reason": "location change" + }, + { "object": "LayoutText #text", "reason": "location change" }, @@ -392,6 +400,10 @@ "reason": "location change" }, { + "object": "RootInlineBox", + "reason": "location change" + }, + { "object": "LayoutSVGInlineText #text", "reason": "location change" },
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers-expected.png b/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers-expected.png index abfdbffb4..6bacca9 100644 --- a/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/overlap-blending/children-opacity-huge-expected.png b/third_party/WebKit/LayoutTests/platform/win/compositing/overlap-blending/children-opacity-huge-expected.png new file mode 100644 index 0000000..1d496c8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/compositing/overlap-blending/children-opacity-huge-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/overlap-blending/children-opacity-huge-expected.txt b/third_party/WebKit/LayoutTests/platform/win/compositing/overlap-blending/children-opacity-huge-expected.txt new file mode 100644 index 0000000..05cd3ed --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/compositing/overlap-blending/children-opacity-huge-expected.txt
@@ -0,0 +1,15 @@ +layer at (0,0) size 800x600 clip at (0,0) size 800x585 scrollWidth 2150 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x0 + LayoutBlockFlow {HTML} at (0,0) size 800x0 + LayoutBlockFlow {BODY} at (0,0) size 800x0 +layer at (0,0) size 800x0 transparent + LayoutBlockFlow {DIV} at (0,0) size 800x0 +layer at (0,0) size 2150x200 backgroundClip at (0,0) size 800x585 clip at (0,0) size 800x585 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 2150x200 [bgcolor=#008000] + LayoutText {#text} at (0,0) size 8x17 + text run at (0,0) width 8: "1" +layer at (0,100) size 2150x200 backgroundClip at (0,0) size 800x585 clip at (0,0) size 800x585 + LayoutBlockFlow (positioned) {DIV} at (0,100) size 2150x200 [bgcolor=#008000] + LayoutText {#text} at (0,0) size 8x17 + text run at (0,0) width 8: "2"
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/overlap-blending/children-opacity-no-overlap-expected.png b/third_party/WebKit/LayoutTests/platform/win/compositing/overlap-blending/children-opacity-no-overlap-expected.png new file mode 100644 index 0000000..421588f --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/compositing/overlap-blending/children-opacity-no-overlap-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/overlap-blending/children-opacity-no-overlap-expected.txt b/third_party/WebKit/LayoutTests/platform/win/compositing/overlap-blending/children-opacity-no-overlap-expected.txt new file mode 100644 index 0000000..20882d6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/compositing/overlap-blending/children-opacity-no-overlap-expected.txt
@@ -0,0 +1,21 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x0 + LayoutBlockFlow {HTML} at (0,0) size 800x0 + LayoutBlockFlow {BODY} at (0,0) size 800x0 +layer at (0,0) size 800x0 transparent + LayoutBlockFlow {DIV} at (0,0) size 800x0 +layer at (0,0) size 100x100 + LayoutBlockFlow (positioned) {DIV} at (0,0) size 100x100 [bgcolor=#008000] + LayoutText {#text} at (0,0) size 8x17 + text run at (0,0) width 8: "1" +layer at (200,200) size 100x100 + LayoutBlockFlow (positioned) {DIV} at (200,200) size 100x100 [bgcolor=#008000] + LayoutText {#text} at (0,0) size 8x17 + text run at (0,0) width 8: "2" +layer at (0,200) size 100x100 + LayoutBlockFlow (positioned) {DIV} at (0,200) size 100x100 [bgcolor=#008000] + LayoutText {#text} at (0,0) size 8x17 + text run at (0,0) width 8: "3" +layer at (200,0) size 100x100 + LayoutBlockFlow (positioned) {DIV} at (200,0) size 100x100 [bgcolor=#008000]
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/overlap-blending/reflection-opacity-huge-expected.png b/third_party/WebKit/LayoutTests/platform/win/compositing/overlap-blending/reflection-opacity-huge-expected.png new file mode 100644 index 0000000..da5bc62c --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/compositing/overlap-blending/reflection-opacity-huge-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/overlap-blending/reflection-opacity-huge-expected.txt b/third_party/WebKit/LayoutTests/platform/win/compositing/overlap-blending/reflection-opacity-huge-expected.txt new file mode 100644 index 0000000..dfd56e83 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/compositing/overlap-blending/reflection-opacity-huge-expected.txt
@@ -0,0 +1,13 @@ +layer at (0,0) size 800x600 clip at (0,0) size 800x585 scrollWidth 2150 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x236 + LayoutBlockFlow {HTML} at (0,0) size 800x236 + LayoutBlockFlow {BODY} at (0,0) size 800x236 + LayoutBlockFlow {P} at (0,0) size 800x36 + LayoutText {#text} at (0,0) size 790x35 + text run at (0,0) width 790: "Opacity should be applied after reflection, so you should see a green rectangle below. The overlap between the original and" + text run at (0,18) width 203: "reflection should not be visible." +layer at (0,36) size 2150x200 backgroundClip at (0,0) size 800x585 clip at (0,0) size 800x585 transparent + LayoutBlockFlow (relative positioned) {DIV} at (0,36) size 2150x200 [bgcolor=#008000] + LayoutText {#text} at (0,0) size 8x17 + text run at (0,0) width 8: "1"
diff --git a/third_party/WebKit/LayoutTests/platform/win/css3/blending/background-blend-mode-overlapping-accelerated-elements-expected.png b/third_party/WebKit/LayoutTests/platform/win/css3/blending/background-blend-mode-overlapping-accelerated-elements-expected.png index b16a1966..ef6760c2 100644 --- a/third_party/WebKit/LayoutTests/platform/win/css3/blending/background-blend-mode-overlapping-accelerated-elements-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/css3/blending/background-blend-mode-overlapping-accelerated-elements-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css3/filters/filter-repaint-composited-fallback-crash-expected.png b/third_party/WebKit/LayoutTests/platform/win/css3/filters/filter-repaint-composited-fallback-crash-expected.png index e710e20..29e02c4 100644 --- a/third_party/WebKit/LayoutTests/platform/win/css3/filters/filter-repaint-composited-fallback-crash-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/css3/filters/filter-repaint-composited-fallback-crash-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css3/filters/filter-repaint-composited-fallback-expected.png b/third_party/WebKit/LayoutTests/platform/win/css3/filters/filter-repaint-composited-fallback-expected.png index e710e20..29e02c4 100644 --- a/third_party/WebKit/LayoutTests/platform/win/css3/filters/filter-repaint-composited-fallback-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/css3/filters/filter-repaint-composited-fallback-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png index bae2260..dd0917b 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-expected.png index 741e546..3a7cb8d 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png index ba0074fc..2e7d360 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png index 0de07c0..72e190cd 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png index 378f838..c71d099 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png index 40cfd29..e4caf39a 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png index d73cd068..02b5169 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-expected.png index 4785968..c9af26e 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-step-expected.png index ef7cae95..ea801ae1 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-expected.png index b32c013..0a6bd1b 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-step-expected.png index 2e8e090..1dd010f 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-empty-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-empty-expected.png index 83fb40ba..fbd345e 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-empty-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-empty-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-expected.png index f2aef43..9eadb156 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-fractional-width-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-fractional-width-expected.png index 5afb7ba..5394943b 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-fractional-width-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-fractional-width-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-long-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-long-expected.png index 5b80816..3c9e759 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-long-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-long-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-many-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-many-expected.png index 5e60246..51e604a 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-many-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-many-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-rtl-default-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-rtl-default-expected.png index 02f73821..77fd147 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-rtl-default-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-rtl-default-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-rtl-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-rtl-expected.png index 07c750a..f3fb89c6 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-rtl-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-rtl-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-single-option-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-single-option-expected.png index fef3a2d7..ae0d8b2 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-single-option-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-single-option-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-styled-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-styled-expected.png index 560c140..e5d16ba 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-styled-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-styled-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-texttransform-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-texttransform-expected.png index 103a2ed..b5260a7 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-texttransform-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-texttransform-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-transform-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-transform-expected.png index 3b7caa47..f6f36477c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-transform-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-transform-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-zoom-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-zoom-expected.png index 50a44fc..a8d96e75 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-zoom-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-zoom-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-zoom090-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-zoom090-expected.png index 14906d4..78d8221e2 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-zoom090-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select-popup/popup-menu-appearance-zoom090-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-1-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-1-and-click-expected.png index 97c0a45..7f0f5750 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-1-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-1-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-10-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-10-and-click-expected.png index 05c613ae..7341dfe 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-10-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-10-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-2-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-2-and-click-expected.png index 1455c26..b674a3c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-2-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-2-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-3-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-3-and-click-expected.png index b8d63d6d..2fab69f 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-3-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-3-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-4-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-4-and-click-expected.png index b8808f84..caa645c4 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-4-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-4-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-5-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-5-and-click-expected.png index f07b573..3111b2c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-5-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-5-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-6-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-6-and-click-expected.png index 05c613ae..7341dfe 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-6-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-6-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-7-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-7-and-click-expected.png index 05c613ae..7341dfe 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-7-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-7-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-8-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-8-and-click-expected.png index 8ec96999..50d3091 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-8-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-8-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-9-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-9-and-click-expected.png index b911a9f2..f25cf1c4 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-9-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-add-summary-9-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-1-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-1-and-click-expected.png index 91007b5..797988a 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-1-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-1-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-2-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-2-and-click-expected.png index 88b0ad7..989bb738 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-2-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-2-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-3-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-3-and-click-expected.png index 2f1d660..7edad51 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-3-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-3-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-4-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-4-and-click-expected.png index 456b756..ea7c0bd 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-4-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-4-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-5-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-5-and-click-expected.png index 8fec370..f51cf93 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-5-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-5-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-6-and-click-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-6-and-click-expected.png index c68d7ab..4d316c9 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-6-and-click-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/html/details-remove-summary-6-and-click-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/repaint/block-layout-inline-children-replaced-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/repaint/block-layout-inline-children-replaced-expected.txt deleted file mode 100644 index 7035e3b9..0000000 --- a/third_party/WebKit/LayoutTests/platform/win/fast/repaint/block-layout-inline-children-replaced-expected.txt +++ /dev/null
@@ -1,44 +0,0 @@ -{ - "bounds": [800, 600], - "children": [ - { - "bounds": [800, 600], - "contentsOpaque": true, - "drawsContent": true, - "paintInvalidations": [ - { - "object": "LayoutBlockFlow DIV id='target' class='target'", - "rect": [0, 34, 402, 152], - "reason": "forced by layout" - }, - { - "object": "LayoutBlockFlow DIV id='target' class='target'", - "rect": [0, 35, 402, 100], - "reason": "invalidate paint rectangle" - }, - { - "object": "LayoutImage IMG", - "rect": [154, 35, 94, 100], - "reason": "location change" - }, - { - "object": "InlineBox", - "reason": "full" - }, - { - "object": "LayoutImage IMG", - "reason": "location change" - }, - { - "object": "RootInlineBox", - "reason": "full" - }, - { - "object": "RootInlineBox", - "reason": "full" - } - ] - } - ] -} -
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/repaint/inline-focus-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/repaint/inline-focus-expected.png index 4dc5005c..e4b7629 100644 --- a/third_party/WebKit/LayoutTests/platform/win/fast/repaint/inline-focus-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/fast/repaint/inline-focus-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.png new file mode 100644 index 0000000..08ba11c --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.txt new file mode 100644 index 0000000..8445e2e5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-ltr-text-in-ltr-flow-underline-composition-expected.txt
@@ -0,0 +1,16 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x112 + LayoutBlockFlow {HTML} at (0,0) size 800x112 + LayoutBlockFlow {BODY} at (8,16) size 784x88 + LayoutBlockFlow {P} at (0,0) size 784x18 + LayoutText {#text} at (0,0) size 784x17 + text run at (0,0) width 784: "crbug.com/636060: Ltr text in a ltr flow should truncate the text left-to-right and underline correctly in composition mode." + LayoutBlockFlow {P} at (0,34) size 784x18 + LayoutText {#text} at (0,0) size 290x17 + text run at (0,0) width 290: "You should see an underline beneath the text." +layer at (8,84) size 125x20 scrollX 31.00 scrollWidth 157 + LayoutBlockFlow {DIV} at (0,68) size 125x20 + LayoutText {#text} at (0,0) size 157x17 + text run at (0,0) width 157: "abcdefghijklmnopqrstuv" +caret: position 22 of child 0 {#text} of child 4 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.png new file mode 100644 index 0000000..f2b9af0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.txt new file mode 100644 index 0000000..00b8224 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-ltr-text-in-rtl-flow-underline-composition-expected.txt
@@ -0,0 +1,16 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x112 + LayoutBlockFlow {HTML} at (0,0) size 800x112 + LayoutBlockFlow {BODY} at (8,16) size 784x88 + LayoutBlockFlow {P} at (0,0) size 784x18 + LayoutText {#text} at (0,0) size 784x17 + text run at (0,0) width 784: "crbug.com/636060: Ltr text in a rtl flow should truncate the text left-to-right and underline correctly in composition mode." + LayoutBlockFlow {P} at (0,34) size 784x18 + LayoutText {#text} at (0,0) size 290x17 + text run at (0,0) width 290: "You should see an underline beneath the text." +layer at (8,84) size 125x20 scrollWidth 156 + LayoutBlockFlow {DIV} at (0,68) size 125x20 + LayoutText {#text} at (-31,0) size 157x17 + text run at (-31,0) width 156: "abcdefghijklmnopqrstuv" +caret: position 22 of child 0 {#text} of child 4 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.png new file mode 100644 index 0000000..bdd0fee --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.txt new file mode 100644 index 0000000..42a618b --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-rtl-text-in-ltr-flow-underline-composition-expected.txt
@@ -0,0 +1,17 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x112 + LayoutBlockFlow {HTML} at (0,0) size 800x112 + LayoutBlockFlow {BODY} at (8,16) size 784x88 + LayoutBlockFlow {P} at (0,0) size 784x18 + LayoutText {#text} at (0,0) size 779x17 + text run at (0,0) width 779: "crbug.com/636060: rtl text in a ltr flow should truncate the text left-to-right and underline correctly in composition mode." + LayoutBlockFlow {P} at (0,34) size 784x18 + LayoutText {#text} at (0,0) size 290x17 + text run at (0,0) width 290: "You should see an underline beneath the text." +layer at (8,84) size 125x20 scrollX 61.00 scrollWidth 187 + LayoutBlockFlow {DIV} at (0,68) size 125x20 + LayoutText {#text} at (0,0) size 187x17 + text run at (0,0) width 178 RTL: "\x{5D0}\x{5D1}\x{5D2}\x{5D3}\x{5D4}\x{5D5}\x{5D6}\x{5D7}\x{5D8}\x{5D9}\x{5DB}\x{5DA}\x{5DC}\x{5DE}\x{5DD}\x{5E1}\x{5E2}\x{5E4}\x{5E3}\x{5E6}\x{5E5}\x{5E7}\x{5E8}\x{5E9}\x{5EA}" + text run at (177,0) width 10: "<" +caret: position 26 of child 0 {#text} of child 4 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.png new file mode 100644 index 0000000..6ea34ae61 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.txt new file mode 100644 index 0000000..8cfc816 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win/fast/text/ellipsis-rtl-text-in-rtl-flow-underline-composition-expected.txt
@@ -0,0 +1,16 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x112 + LayoutBlockFlow {HTML} at (0,0) size 800x112 + LayoutBlockFlow {BODY} at (8,16) size 784x88 + LayoutBlockFlow {P} at (0,0) size 784x18 + LayoutText {#text} at (0,0) size 779x17 + text run at (0,0) width 779: "crbug.com/636060: rtl text in a rtl flow should truncate the text left-to-right and underline correctly in composition mode." + LayoutBlockFlow {P} at (0,34) size 784x18 + LayoutText {#text} at (0,0) size 290x17 + text run at (0,0) width 290: "You should see an underline beneath the text." +layer at (8,84) size 125x20 scrollWidth 186 + LayoutBlockFlow {DIV} at (0,68) size 125x20 + LayoutText {#text} at (-61,0) size 187x17 + text run at (-61,0) width 186 RTL: "\x{5D0}\x{5D1}\x{5D2}\x{5D3}\x{5D4}\x{5D5}\x{5D6}\x{5D7}\x{5D8}\x{5D9}\x{5DB}\x{5DA}\x{5DC}\x{5DE}\x{5DD}\x{5E1}\x{5E2}\x{5E4}\x{5E3}\x{5E6}\x{5E5}\x{5E7}\x{5E8}\x{5E9}\x{5EA}<" +caret: position 26 of child 0 {#text} of child 4 {DIV} of body
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/video-layer-crash-expected.png b/third_party/WebKit/LayoutTests/platform/win/media/video-layer-crash-expected.png index 430e6317..f23e74c1 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/video-layer-crash-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/media/video-layer-crash-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/video-layer-crash-expected.txt b/third_party/WebKit/LayoutTests/platform/win/media/video-layer-crash-expected.txt index 16d87b3..4ca76ea 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/video-layer-crash-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/media/video-layer-crash-expected.txt
@@ -6,27 +6,43 @@ LayoutBlockFlow {P} at (0,0) size 784x18 LayoutText {#text} at (0,0) size 368x17 text run at (0,0) width 368: "Test dynamic removal of transformed and reflected video" - LayoutBlockFlow (anonymous) at (0,34) size 784x338 - LayoutText {#text} at (0,0) size 4x17 - text run at (0,0) width 4: " " - LayoutBR {BR} at (4,14) size 0x0 - LayoutText {#text} at (0,160) size 4x17 - text run at (0,160) width 4: " " - LayoutBR {BR} at (210,174) size 0x0 - LayoutText {#text} at (0,320) size 4x17 - text run at (0,320) width 4: " " - LayoutBR {BR} at (210,334) size 0x0 -layer at (12,60) size 206x156 - LayoutVideo {VIDEO} at (4,18) size 206x156 [border: (3px solid #FF0000)] -layer at (15,63) size 200x150 - LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 - LayoutBlockFlow {DIV} at (0,118) size 200x32 -layer at (15,63) size 200x108 - LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x108 -layer at (12,220) size 206x156 - LayoutVideo {VIDEO} at (4,178) size 206x156 [border: (3px solid #FF0000)] -layer at (15,223) size 200x150 - LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 - LayoutBlockFlow {DIV} at (0,118) size 200x32 -layer at (15,223) size 200x108 - LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x108 + LayoutBlockFlow (anonymous) at (0,34) size 784x330 + LayoutText {#text} at (0,92) size 4x17 + text run at (0,92) width 4: " " + LayoutBR {BR} at (210,106) size 0x0 + LayoutText {#text} at (0,202) size 4x17 + text run at (0,202) width 4: " " + LayoutBR {BR} at (210,216) size 0x0 + LayoutText {#text} at (0,312) size 4x17 + text run at (0,312) width 4: " " + LayoutBR {BR} at (210,326) size 0x0 +layer at (12,42) size 206x106 + LayoutVideo {VIDEO} at (4,0) size 206x106 [border: (3px solid #FF0000)] +layer at (15,45) size 200x100 + LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x100 + LayoutBlockFlow {DIV} at (0,68) size 200x32 +layer at (15,45) size 200x58 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x58 +layer at (15,113) size 200x32 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x32 [bgcolor=#FAFAFA] + LayoutButton {INPUT} at (0,0) size 32x32 +layer at (12,152) size 206x106 + LayoutVideo {VIDEO} at (4,110) size 206x106 [border: (3px solid #FF0000)] +layer at (15,155) size 200x100 + LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x100 + LayoutBlockFlow {DIV} at (0,68) size 200x32 +layer at (15,155) size 200x58 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x58 +layer at (15,223) size 200x32 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x32 [bgcolor=#FAFAFA] + LayoutButton {INPUT} at (0,0) size 32x32 +layer at (12,262) size 206x106 + LayoutVideo {VIDEO} at (4,220) size 206x106 [border: (3px solid #FF0000)] +layer at (15,265) size 200x100 + LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x100 + LayoutBlockFlow {DIV} at (0,68) size 200x32 +layer at (15,265) size 200x58 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x58 +layer at (15,333) size 200x32 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x32 [bgcolor=#FAFAFA] + LayoutButton {INPUT} at (0,0) size 32x32
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/video-transformed-expected.png b/third_party/WebKit/LayoutTests/platform/win/media/video-transformed-expected.png index 76b08a5..ef44fd2 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/video-transformed-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/media/video-transformed-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/media/video-transformed-expected.txt b/third_party/WebKit/LayoutTests/platform/win/media/video-transformed-expected.txt index 64bc5e3..ae159040 100644 --- a/third_party/WebKit/LayoutTests/platform/win/media/video-transformed-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/media/video-transformed-expected.txt
@@ -6,34 +6,43 @@ LayoutBlockFlow {P} at (0,0) size 784x18 LayoutText {#text} at (0,0) size 222x17 text run at (0,0) width 222: "Test painting of transformed video" - LayoutBlockFlow (anonymous) at (0,34) size 784x480 - LayoutText {#text} at (0,142) size 4x17 - text run at (0,142) width 4: " " - LayoutBR {BR} at (210,156) size 0x0 - LayoutText {#text} at (0,302) size 4x17 - text run at (0,302) width 4: " " - LayoutBR {BR} at (210,316) size 0x0 - LayoutText {#text} at (0,462) size 4x17 - text run at (0,462) width 4: " " - LayoutBR {BR} at (210,476) size 0x0 -layer at (12,42) size 206x156 - LayoutVideo {VIDEO} at (4,0) size 206x156 [border: (3px solid #FF0000)] -layer at (15,45) size 200x150 - LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 - LayoutBlockFlow {DIV} at (0,118) size 200x32 -layer at (15,45) size 200x108 - LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x108 -layer at (12,202) size 206x156 - LayoutVideo {VIDEO} at (4,160) size 206x156 [border: (3px solid #FF0000)] -layer at (15,205) size 200x150 - LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 - LayoutBlockFlow {DIV} at (0,118) size 200x32 -layer at (15,205) size 200x108 - LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x108 -layer at (12,362) size 206x156 - LayoutVideo {VIDEO} at (4,320) size 206x156 [border: (3px solid #FF0000)] -layer at (15,365) size 200x150 - LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 - LayoutBlockFlow {DIV} at (0,118) size 200x32 -layer at (15,365) size 200x108 - LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x108 + LayoutBlockFlow (anonymous) at (0,34) size 784x330 + LayoutText {#text} at (0,92) size 4x17 + text run at (0,92) width 4: " " + LayoutBR {BR} at (210,106) size 0x0 + LayoutText {#text} at (0,202) size 4x17 + text run at (0,202) width 4: " " + LayoutBR {BR} at (210,216) size 0x0 + LayoutText {#text} at (0,312) size 4x17 + text run at (0,312) width 4: " " + LayoutBR {BR} at (210,326) size 0x0 +layer at (12,42) size 206x106 + LayoutVideo {VIDEO} at (4,0) size 206x106 [border: (3px solid #FF0000)] +layer at (15,45) size 200x100 + LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x100 + LayoutBlockFlow {DIV} at (0,68) size 200x32 +layer at (15,45) size 200x58 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x58 +layer at (15,113) size 200x32 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x32 [bgcolor=#FAFAFA] + LayoutButton {INPUT} at (0,0) size 32x32 +layer at (12,152) size 206x106 + LayoutVideo {VIDEO} at (4,110) size 206x106 [border: (3px solid #FF0000)] +layer at (15,155) size 200x100 + LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x100 + LayoutBlockFlow {DIV} at (0,68) size 200x32 +layer at (15,155) size 200x58 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x58 +layer at (15,223) size 200x32 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x32 [bgcolor=#FAFAFA] + LayoutButton {INPUT} at (0,0) size 32x32 +layer at (12,262) size 206x106 + LayoutVideo {VIDEO} at (4,220) size 206x106 [border: (3px solid #FF0000)] +layer at (15,265) size 200x100 + LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x100 + LayoutBlockFlow {DIV} at (0,68) size 200x32 +layer at (15,265) size 200x58 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x58 +layer at (15,333) size 200x32 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x32 [bgcolor=#FAFAFA] + LayoutButton {INPUT} at (0,0) size 32x32
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/struct-image-06-t-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/struct-image-06-t-expected.txt index ddfbea8..1b18d23 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/struct-image-06-t-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/struct-image-06-t-expected.txt
@@ -43,9 +43,9 @@ LayoutSVGText {text} at (0,-30) size 81x12 contains 1 chunk(s) LayoutSVGInlineText {#text} at (0,0) size 81x12 chunk 1 text run 1 at (0.00,-20.00) startOffset 0 endOffset 26 width 81.00: "---------- meet ----------" - LayoutSVGContainer {g} at (379,35) size 31x75 [transform={m=((1.00,0.00)(0.00,1.00)) t=(30.00,0.00)}] - LayoutSVGText {text} at (-1,-15) size 25x12 contains 1 chunk(s) - LayoutSVGInlineText {#text} at (0,0) size 25x12 + LayoutSVGContainer {g} at (380,35) size 30x75 [transform={m=((1.00,0.00)(0.00,1.00)) t=(30.00,0.00)}] + LayoutSVGText {text} at (0,-15) size 24x12 contains 1 chunk(s) + LayoutSVGInlineText {#text} at (0,0) size 24x12 chunk 1 text run 1 at (0.00,-5.00) startOffset 0 endOffset 5 width 24.00: "*none" LayoutSVGRect {rect} at (380,50) size 30x60 [stroke={[type=SOLID] [color=#0000FF]}] [x=0.50] [y=0.50] [width=29.00] [height=59.00] LayoutSVGImage {image} at (380,50) size 30x60
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/carto.net/tabgroup-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/carto.net/tabgroup-expected.png index c571b1a..c032322 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/carto.net/tabgroup-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/svg/carto.net/tabgroup-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/text-rescale-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/text/text-rescale-expected.txt index dbe1adf..ca8721ad 100644 --- a/third_party/WebKit/LayoutTests/platform/win/svg/text/text-rescale-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/text-rescale-expected.txt
@@ -300,6 +300,10 @@ "reason": "location change" }, { + "object": "RootInlineBox", + "reason": "location change" + }, + { "object": "LayoutSVGInlineText #text", "reason": "location change" }, @@ -336,6 +340,10 @@ "reason": "location change" }, { + "object": "RootInlineBox", + "reason": "location change" + }, + { "object": "LayoutText #text", "reason": "location change" }, @@ -352,6 +360,10 @@ "reason": "location change" }, { + "object": "RootInlineBox", + "reason": "location change" + }, + { "object": "LayoutSVGInlineText #text", "reason": "location change" },
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/prefer_compositing_to_lcd_text/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/prefer_compositing_to_lcd_text/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers-expected.png index abfdbffb4..6bacca9 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/prefer_compositing_to_lcd_text/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/prefer_compositing_to_lcd_text/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor150/fast/hidpi/static/popup-menu-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor150/fast/hidpi/static/popup-menu-appearance-expected.png index 38e0c9f..cd8a13c 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor150/fast/hidpi/static/popup-menu-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor150/fast/hidpi/static/popup-menu-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200/fast/hidpi/static/popup-menu-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200/fast/hidpi/static/popup-menu-appearance-expected.png index 890a68e2..f5439f0 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200/fast/hidpi/static/popup-menu-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200/fast/hidpi/static/popup-menu-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-appearance-expected.png index 890a68e2..f5439f0 100644 --- a/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200withzoom/fast/hidpi/static/popup-menu-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png index dd1b50f..3cfe321 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-expected.png index 3ddb3c2..a7673fa2 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png index 5f79ae6..1a6c3b8 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png index 76845e8..7d94e1b 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png index 9a7f8fe..645d9fe6 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png index be9c858..c4387d2 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-expected.png index c1842fe..cf05c0a 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-step-expected.png index 2a6f5fd..c219a88 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-expected.png index 479454a6..e348899 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-step-expected.png index 8fba041c0..1a6f7e03 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-step-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-step-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/select-popup/popup-menu-appearance-styled-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/select-popup/popup-menu-appearance-styled-expected.png index 4c5824e..de78198 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/select-popup/popup-menu-appearance-styled-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/select-popup/popup-menu-appearance-styled-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/media/video-layer-crash-expected.png b/third_party/WebKit/LayoutTests/platform/win7/media/video-layer-crash-expected.png new file mode 100644 index 0000000..db7ff95 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win7/media/video-layer-crash-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/media/video-layer-crash-expected.txt b/third_party/WebKit/LayoutTests/platform/win7/media/video-layer-crash-expected.txt new file mode 100644 index 0000000..16d87b3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win7/media/video-layer-crash-expected.txt
@@ -0,0 +1,32 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (8,8) size 784x584 + LayoutBlockFlow {P} at (0,0) size 784x18 + LayoutText {#text} at (0,0) size 368x17 + text run at (0,0) width 368: "Test dynamic removal of transformed and reflected video" + LayoutBlockFlow (anonymous) at (0,34) size 784x338 + LayoutText {#text} at (0,0) size 4x17 + text run at (0,0) width 4: " " + LayoutBR {BR} at (4,14) size 0x0 + LayoutText {#text} at (0,160) size 4x17 + text run at (0,160) width 4: " " + LayoutBR {BR} at (210,174) size 0x0 + LayoutText {#text} at (0,320) size 4x17 + text run at (0,320) width 4: " " + LayoutBR {BR} at (210,334) size 0x0 +layer at (12,60) size 206x156 + LayoutVideo {VIDEO} at (4,18) size 206x156 [border: (3px solid #FF0000)] +layer at (15,63) size 200x150 + LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 + LayoutBlockFlow {DIV} at (0,118) size 200x32 +layer at (15,63) size 200x108 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x108 +layer at (12,220) size 206x156 + LayoutVideo {VIDEO} at (4,178) size 206x156 [border: (3px solid #FF0000)] +layer at (15,223) size 200x150 + LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 + LayoutBlockFlow {DIV} at (0,118) size 200x32 +layer at (15,223) size 200x108 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x108
diff --git a/third_party/WebKit/LayoutTests/platform/win7/media/video-transformed-expected.png b/third_party/WebKit/LayoutTests/platform/win7/media/video-transformed-expected.png new file mode 100644 index 0000000..e3f31f9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win7/media/video-transformed-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/media/video-transformed-expected.txt b/third_party/WebKit/LayoutTests/platform/win7/media/video-transformed-expected.txt new file mode 100644 index 0000000..64bc5e3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/platform/win7/media/video-transformed-expected.txt
@@ -0,0 +1,39 @@ +layer at (0,0) size 800x600 + LayoutView at (0,0) size 800x600 +layer at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x600 + LayoutBlockFlow {BODY} at (8,8) size 784x584 + LayoutBlockFlow {P} at (0,0) size 784x18 + LayoutText {#text} at (0,0) size 222x17 + text run at (0,0) width 222: "Test painting of transformed video" + LayoutBlockFlow (anonymous) at (0,34) size 784x480 + LayoutText {#text} at (0,142) size 4x17 + text run at (0,142) width 4: " " + LayoutBR {BR} at (210,156) size 0x0 + LayoutText {#text} at (0,302) size 4x17 + text run at (0,302) width 4: " " + LayoutBR {BR} at (210,316) size 0x0 + LayoutText {#text} at (0,462) size 4x17 + text run at (0,462) width 4: " " + LayoutBR {BR} at (210,476) size 0x0 +layer at (12,42) size 206x156 + LayoutVideo {VIDEO} at (4,0) size 206x156 [border: (3px solid #FF0000)] +layer at (15,45) size 200x150 + LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 + LayoutBlockFlow {DIV} at (0,118) size 200x32 +layer at (15,45) size 200x108 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x108 +layer at (12,202) size 206x156 + LayoutVideo {VIDEO} at (4,160) size 206x156 [border: (3px solid #FF0000)] +layer at (15,205) size 200x150 + LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 + LayoutBlockFlow {DIV} at (0,118) size 200x32 +layer at (15,205) size 200x108 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x108 +layer at (12,362) size 206x156 + LayoutVideo {VIDEO} at (4,320) size 206x156 [border: (3px solid #FF0000)] +layer at (15,365) size 200x150 + LayoutFlexibleBox (relative positioned) {DIV} at (3,3) size 200x150 + LayoutBlockFlow {DIV} at (0,118) size 200x32 +layer at (15,365) size 200x108 + LayoutFlexibleBox (relative positioned) {DIV} at (0,0) size 200x108
diff --git a/third_party/WebKit/LayoutTests/platform/win7/transforms/2d/hindi-rotated-expected.png b/third_party/WebKit/LayoutTests/platform/win7/transforms/2d/hindi-rotated-expected.png index 123900c2..c3463739 100644 --- a/third_party/WebKit/LayoutTests/platform/win7/transforms/2d/hindi-rotated-expected.png +++ b/third_party/WebKit/LayoutTests/platform/win7/transforms/2d/hindi-rotated-expected.png Binary files differ
diff --git a/third_party/WebKit/LayoutTests/scrollbars/auto-scrollbar-fit-content-expected.txt b/third_party/WebKit/LayoutTests/scrollbars/auto-scrollbar-fit-content-expected.txt deleted file mode 100644 index cc3098a..0000000 --- a/third_party/WebKit/LayoutTests/scrollbars/auto-scrollbar-fit-content-expected.txt +++ /dev/null
@@ -1,10 +0,0 @@ -Make sure a parent block that fits content expands when a child adds an auto scrollbar. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS scroller.clientWidth is scroller.scrollWidth -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/scrollbars/auto-scrollbar-fit-content.html b/third_party/WebKit/LayoutTests/scrollbars/auto-scrollbar-fit-content.html index 941e9f5..ef22a70a 100644 --- a/third_party/WebKit/LayoutTests/scrollbars/auto-scrollbar-fit-content.html +++ b/third_party/WebKit/LayoutTests/scrollbars/auto-scrollbar-fit-content.html
@@ -1,17 +1,18 @@ <!DOCTYPE html> -<script src="../resources/js-test.js"></script> +<title>Make sure a parent block that fits content expands when a child adds an auto scrollbar.</title> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> <div id="top" style="float:left; display:none;"> <div id="scroller" style="overflow: auto; height: 100px;"> <div style="width: 100px; height: 200px; border: 2px solid blue;"></div> </div> </div> - <script> -description("Make sure a parent block that fits content expands when a child adds an auto scrollbar."); - -var topDiv = document.getElementById("top"); -var scroller = document.getElementById("scroller"); -topDiv.style.display = "block"; -topDiv.offsetTop; -shouldBe("scroller.clientWidth", "scroller.scrollWidth"); +test(function() { + var topDiv = document.getElementById("top"); + var scroller = document.getElementById("scroller"); + topDiv.style.display = "block"; + topDiv.offsetTop; + assert_equals(scroller.clientWidth, scroller.scrollWidth); +}); </script>
diff --git a/third_party/WebKit/LayoutTests/scrollbars/custom-scrollbar-not-inherited-by-iframe-expected.txt b/third_party/WebKit/LayoutTests/scrollbars/custom-scrollbar-not-inherited-by-iframe-expected.txt deleted file mode 100644 index f70e3acc..0000000 --- a/third_party/WebKit/LayoutTests/scrollbars/custom-scrollbar-not-inherited-by-iframe-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -PASS successfullyParsed is true - -TEST COMPLETE -PASS 285 is 285 -
diff --git a/third_party/WebKit/LayoutTests/scrollbars/custom-scrollbar-not-inherited-by-iframe.html b/third_party/WebKit/LayoutTests/scrollbars/custom-scrollbar-not-inherited-by-iframe.html index 2239ebe..accb339 100644 --- a/third_party/WebKit/LayoutTests/scrollbars/custom-scrollbar-not-inherited-by-iframe.html +++ b/third_party/WebKit/LayoutTests/scrollbars/custom-scrollbar-not-inherited-by-iframe.html
@@ -1,5 +1,6 @@ <!DOCTYPE html> -<script src="../resources/js-test.js"></script> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> <style> ::-webkit-scrollbar { width: 150px; @@ -17,8 +18,10 @@ </style> "></iframe> <script> -onload = function() { - var body = document.querySelector("iframe").contentDocument.body; - shouldBe("285", String(body.clientWidth)); -}; -</script> \ No newline at end of file +async_test(function(t) { + onload = t.step_func_done(function() { + var body = document.querySelector("iframe").contentDocument.body; + assert_equals(285, body.clientWidth); + }); +}); +</script>
diff --git a/third_party/WebKit/LayoutTests/scrollbars/drag-rtl-resizer-expected.txt b/third_party/WebKit/LayoutTests/scrollbars/drag-rtl-resizer-expected.txt deleted file mode 100644 index 346b028..0000000 --- a/third_party/WebKit/LayoutTests/scrollbars/drag-rtl-resizer-expected.txt +++ /dev/null
@@ -1,10 +0,0 @@ -Test that an RTL element renders a resizer to its bottom-left corner and dragging this resizer to the left changes its width. To test manually, dragging the resizer of the below element to left, and see this element increases its width. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS document.getElementById('overflow').offsetWidth > offsetWidth is true -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/scrollbars/drag-rtl-resizer.html b/third_party/WebKit/LayoutTests/scrollbars/drag-rtl-resizer.html index 420b85a..b844be4 100644 --- a/third_party/WebKit/LayoutTests/scrollbars/drag-rtl-resizer.html +++ b/third_party/WebKit/LayoutTests/scrollbars/drag-rtl-resizer.html
@@ -1,42 +1,27 @@ <!DOCTYPE html> -<html> -<head> -<title>Bug 9223</title> -<script src="../resources/js-test.js"></script> -</head> -<body dir="rtl" style="margin:0px"> -<div id="overflow" dir="rtl" style="border:2px solid black; overflow:auto; width: 400px; height: 400px; resize:both;"> -<div style="background-color:red;height:720px"></div> -<div style="background-color:green;height:1600px"></div> +<title>Bug 9223: Test that an RTL element renders a resizer to its bottom-left corner and dragging this resizer to the left changes its width. To test manually, dragging the resizer of the below element to left, and see this element increases its width.</title> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<body dir="rtl" style="margin: 0px"> +<div id="overflow" dir="rtl" style="border: 2px solid black; overflow: auto; width: 400px; height: 400px; resize: both;"> +<div style="background-color: red; height: 720px"></div> +<div style="background-color: green; height: 1600px"></div> </div> <script> -description('Test that an RTL element renders a resizer to its bottom-left corner and ' + - 'dragging this resizer to the left changes its width. ' + - 'To test manually, dragging the resizer of the below element to left, and ' + - 'see this element increases its width.'); - -// This test must be async because it needs to wait for WebKit to finish re-layouting elements -// after sending mouse events. -jsTestIsAsync = true; - -function finished() -{ - shouldBeTrue('document.getElementById(\'overflow\').offsetWidth > offsetWidth'); - finishJSTest(); -} - -var offsetWidth = document.getElementById('overflow').offsetWidth; - -if (window.eventSender) { +async_test(function(t) { + // This test must be async because it needs to wait for WebKit to finish + // re-layouting elements after sending mouse events. var node = document.getElementById('overflow'); + var offsetWidth = node.offsetWidth; var offsetLeft = node.offsetLeft + 5; var offsetTop = node.offsetTop + node.offsetHeight - 5; eventSender.mouseMoveTo(offsetLeft, offsetTop); eventSender.mouseDown(); eventSender.mouseMoveTo(offsetLeft - 30, offsetTop); eventSender.mouseUp(); - setTimeout(finished, 0); -} + setTimeout(t.step_func_done(function() { + assert_greater_than(node.offsetWidth, offsetWidth); + }), 0); +}); </script> </body> -</html>
diff --git a/third_party/WebKit/LayoutTests/scrollbars/iframe-scrollbar-becomes-custom-expected.txt b/third_party/WebKit/LayoutTests/scrollbars/iframe-scrollbar-becomes-custom-expected.txt deleted file mode 100644 index 2f320e7b..0000000 --- a/third_party/WebKit/LayoutTests/scrollbars/iframe-scrollbar-becomes-custom-expected.txt +++ /dev/null
@@ -1,6 +0,0 @@ -PASS 250 is 250 -PASS width < origWidth is true -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/scrollbars/iframe-scrollbar-becomes-custom.html b/third_party/WebKit/LayoutTests/scrollbars/iframe-scrollbar-becomes-custom.html index be1a938..a07984f6 100644 --- a/third_party/WebKit/LayoutTests/scrollbars/iframe-scrollbar-becomes-custom.html +++ b/third_party/WebKit/LayoutTests/scrollbars/iframe-scrollbar-becomes-custom.html
@@ -1,27 +1,31 @@ <!DOCTYPE HTML> -<script src="../resources/js-test.js"></script> -<iframe id="i" frameborder="0" style="margin-top: 10px"></iframe> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<iframe frameborder="0" style="margin-top: 10px"></iframe> <div id="content" style="display: none"> <div id="block1" style='background-color: #ccc'>100% width</div><br> <div style='background-color: #ddf; width: 400px; height: 300px'></div> </div> <script> +test(function() { + var iframedoc = document.querySelector("iframe").contentDocument; + var sheet = iframedoc.head.appendChild(iframedoc.createElement("style")).sheet; -var idoc = document.querySelector("#i").contentDocument; -var sheet = idoc.head.appendChild(idoc.createElement("style")).sheet; -idoc.body.style.margin = '0'; -idoc.body.innerHTML = document.querySelector('#content').innerHTML; + iframedoc.body.style.margin = "0"; + iframedoc.body.innerHTML = document.querySelector("#content").innerHTML; -var block = idoc.querySelector("#block1"); -var origWidth = block.offsetWidth; -sheet.insertRule("::-webkit-scrollbar { width: 50px; height: 20px; }", 0); -sheet.insertRule("::-webkit-scrollbar-thumb { background: #cce; }", 1); + var block = iframedoc.querySelector("#block1"); + var origWidth = block.offsetWidth; -var width = block.offsetWidth; -shouldBe("250", String(width)); -shouldBeTrue("width < origWidth"); + sheet.insertRule("::-webkit-scrollbar { width: 50px; height: 20px; }", 0); + sheet.insertRule("::-webkit-scrollbar-thumb { background: #cce; }", 1); + var width = block.offsetWidth; + + assert_equals(250, width); + assert_less_than(width, origWidth); +}); </script>
diff --git a/third_party/WebKit/LayoutTests/scrollbars/rtl/div-absolute-expected.txt b/third_party/WebKit/LayoutTests/scrollbars/rtl/div-absolute-expected.txt deleted file mode 100644 index 3069c44..0000000 --- a/third_party/WebKit/LayoutTests/scrollbars/rtl/div-absolute-expected.txt +++ /dev/null
@@ -1,18 +0,0 @@ -Test if the widths of RTL elements are the same as the widths of the LTR elements when they include absolutely-positioned children. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -Verify the widths of the outer RTL element are the same as the widths of the outer LTR element. -PASS outerLTR.offsetWidth == outerRTL.offsetWidth is true -PASS outerLTR.clientWidth == outerRTL.clientWidth is true -PASS outerLTR.scrollWidth == outerRTL.scrollWidth is true -Verify the widths of the inner RTL element are the same as the widths of the inner LTR element. -PASS innerLTR.offsetWidth == innerRTL.offsetWidth is true -PASS innerLTR.clientWidth == innerRTL.clientWidth is true -PASS innerLTR.scrollWidth == innerRTL.scrollWidth is true -PASS successfullyParsed is true - -TEST COMPLETE -foo -foo
diff --git a/third_party/WebKit/LayoutTests/scrollbars/rtl/div-absolute.html b/third_party/WebKit/LayoutTests/scrollbars/rtl/div-absolute.html index 0b187db6..6d9dba93 100644 --- a/third_party/WebKit/LayoutTests/scrollbars/rtl/div-absolute.html +++ b/third_party/WebKit/LayoutTests/scrollbars/rtl/div-absolute.html
@@ -1,33 +1,30 @@ <!DOCTYPE html> -<html> -<head> -<title>Bug 91756</title> -<script src="../../resources/js-test.js"></script> +<title>Bug 91756: Test if the widths of RTL elements are the same as the widths of the LTR elements when they include absolutely-positioned children.</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <style> div.outer { overflow: auto; width: 100px; position: relative; height: 100px; border: solid; } div.inner { position: absolute; top: 250px; } </style> -</head> <body> <div id="outerLTR" class="outer"><div id="innerLTR" class="inner" style="left: 200px;">foo</div></div> <div id="outerRTL" class="outer" style="direction: rtl;"><div id="innerRTL" class="inner" style="right: 200px;">foo</div> </div> -<script type="text/javascript"> -description('Test if the widths of RTL elements are the same as the widths of the LTR elements when they include absolutely-positioned children.'); +<script> +test(function() { + // Verify the widths of the outer RTL element are the same as the widths of the outer LTR element. + var outerLTR = document.getElementById("outerLTR"); + var outerRTL = document.getElementById("outerRTL"); + assert_equals(outerLTR.offsetWidth, outerRTL.offsetWidth); + assert_equals(outerLTR.clientWidth, outerRTL.clientWidth); + assert_equals(outerLTR.scrollWidth, outerRTL.scrollWidth); -debug('Verify the widths of the outer RTL element are the same as the widths of the outer LTR element.'); -var outerLTR = document.getElementById('outerLTR'); -var outerRTL = document.getElementById('outerRTL'); -shouldBeTrue('outerLTR.offsetWidth == outerRTL.offsetWidth'); -shouldBeTrue('outerLTR.clientWidth == outerRTL.clientWidth'); -shouldBeTrue('outerLTR.scrollWidth == outerRTL.scrollWidth'); - -debug('Verify the widths of the inner RTL element are the same as the widths of the inner LTR element.'); -var innerLTR = document.getElementById('innerLTR'); -var innerRTL = document.getElementById('innerRTL'); -shouldBeTrue('innerLTR.offsetWidth == innerRTL.offsetWidth'); -shouldBeTrue('innerLTR.clientWidth == innerRTL.clientWidth'); -shouldBeTrue('innerLTR.scrollWidth == innerRTL.scrollWidth'); + // Verify the widths of the inner RTL element are the same as the widths of the inner LTR element. + var innerLTR = document.getElementById("innerLTR"); + var innerRTL = document.getElementById("innerRTL"); + assert_equals(innerLTR.offsetWidth, innerRTL.offsetWidth); + assert_equals(innerLTR.clientWidth, innerRTL.clientWidth); + assert_equals(innerLTR.scrollWidth, innerRTL.scrollWidth); + }); </script> </body> -</html>
diff --git a/third_party/WebKit/LayoutTests/scrollbars/rtl/div-horizontal-expected.txt b/third_party/WebKit/LayoutTests/scrollbars/rtl/div-horizontal-expected.txt deleted file mode 100644 index 61ad6a9..0000000 --- a/third_party/WebKit/LayoutTests/scrollbars/rtl/div-horizontal-expected.txt +++ /dev/null
@@ -1,20 +0,0 @@ -Test if WebKit can show the left side of the inner elements regardless of the position of its scrollbars. To test manually, open this document and verify we can see "ABC" both in the LTR element and in the RTL element. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -Verify the widths of the outer RTL elements are the same as the widths of the outer LTR elements. -PASS outerLTR.offsetWidth == outerRTL.offsetWidth is true -PASS outerLTR.clientWidth == outerRTL.clientWidth is true -PASS outerLTR.scrollWidth == outerRTL.scrollWidth is true -Verify the widths of the inner RTL elements are the same as the widths of the inner LTR elements. -PASS innerLTR.offsetWidth == innerRTL.offsetWidth is true -PASS innerLTR.clientWidth == innerRTL.clientWidth is true -PASS innerLTR.scrollWidth == innerRTL.scrollWidth is true -Verify the width of the vertical scrollbar of the outer RTL element is the same as the one of the outer LTR element regardless of their scrollbar positions. -PASS scrollbarWidthLTR == scrollbarWidthRTL is true -PASS successfullyParsed is true - -TEST COMPLETE -ABC -ABC
diff --git a/third_party/WebKit/LayoutTests/scrollbars/rtl/div-horizontal-with-vertical-scrollbar-expected.txt b/third_party/WebKit/LayoutTests/scrollbars/rtl/div-horizontal-with-vertical-scrollbar-expected.txt deleted file mode 100644 index 1443d10b..0000000 --- a/third_party/WebKit/LayoutTests/scrollbars/rtl/div-horizontal-with-vertical-scrollbar-expected.txt +++ /dev/null
@@ -1,21 +0,0 @@ -Test that horizontal scrollbar should appear as the content width encroaches upon the vertical scrollbar and also test if WebKit can show the left side of the inner elements regardless of the position of its scrollbars. To test manually, open this document and verify we can see "ABC" both in the LTR element and in the RTL element. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -Verify the widths of the outer RTL elements are the same as the widths of the outer LTR elements. -PASS outerLTR.offsetWidth == outerRTL.offsetWidth is true -PASS outerLTR.clientWidth == outerRTL.clientWidth is true -PASS outerLTR.scrollWidth == outerRTL.scrollWidth is true -Verify the widths of the inner RTL elements are the same as the widths of the inner LTR elements. -PASS innerLTR.offsetWidth == innerRTL.offsetWidth is true -PASS innerLTR.clientWidth == innerRTL.clientWidth is true -PASS innerLTR.scrollWidth == innerRTL.scrollWidth is true -Verify the width of the vertical scrollbar of the outer RTL element is the same as the one of the outer LTR element regardless of their scrollbar positions. -PASS scrollbarWidthLTR == scrollbarWidthRTL is true -PASS outerRTL.clientLeft == scrollbarWidthRTL is true -PASS successfullyParsed is true - -TEST COMPLETE -ABC -ABC
diff --git a/third_party/WebKit/LayoutTests/scrollbars/rtl/div-horizontal-with-vertical-scrollbar.html b/third_party/WebKit/LayoutTests/scrollbars/rtl/div-horizontal-with-vertical-scrollbar.html index ba10654..28748fd 100644 --- a/third_party/WebKit/LayoutTests/scrollbars/rtl/div-horizontal-with-vertical-scrollbar.html +++ b/third_party/WebKit/LayoutTests/scrollbars/rtl/div-horizontal-with-vertical-scrollbar.html
@@ -1,8 +1,8 @@ <!DOCTYPE html> <html> -<head> -<script src="../../resources/js-test.js"></script> -</head> +<title>Test that horizontal scrollbar should appear as the content width encroaches upon the vertical scrollbar and also test if WebKit can show the left side of the inner elements regardless of the position of its scrollbars. To test manually, open this document and verify we can see "ABC" both in the LTR element and in the RTL element.</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <body dir="ltr"> <div dir="ltr" id="outer-ltr" style="width: 200px; height: 200px; overflow: auto;"> <div id="inner-ltr" style="text-align: left; width: 195px; height: 300px;">ABC</div> @@ -10,31 +10,31 @@ <div dir="rtl" id="outer-rtl" style="width: 200px; height: 200px; overflow: auto;"> <div id="inner-rtl" style="text-align: left; width: 195px; height: 300px;">ABC</div> </div> -<script type="text/javascript"> -description('Test that horizontal scrollbar should appear as the content width encroaches upon the vertical scrollbar and also test if WebKit can show the left side of the inner elements regardless of the position of its scrollbars. To test manually, open this document and verify we can see "ABC" both in the LTR element and in the RTL element.'); +<script> +test(function() { + var outerLTR = document.getElementById("outer-ltr"); + var innerLTR = document.getElementById("inner-ltr"); + var outerRTL = document.getElementById("outer-rtl"); + var innerRTL = document.getElementById("inner-rtl"); + outerLTR.scrollLeft = 0; + outerRTL.scrollLeft = 0; -var outerLTR = document.getElementById('outer-ltr'); -var innerLTR = document.getElementById('inner-ltr'); -var outerRTL = document.getElementById('outer-rtl'); -var innerRTL = document.getElementById('inner-rtl'); -outerLTR.scrollLeft = 0; -outerRTL.scrollLeft = 0; + // Verify the widths of the outer RTL elements are the same as the widths of the outer LTR elements. + assert_equals(outerLTR.offsetWidth, outerRTL.offsetWidth); + assert_equals(outerLTR.clientWidth, outerRTL.clientWidth); + assert_equals(outerLTR.scrollWidth, outerRTL.scrollWidth); -debug('Verify the widths of the outer RTL elements are the same as the widths of the outer LTR elements.'); -shouldBeTrue('outerLTR.offsetWidth == outerRTL.offsetWidth'); -shouldBeTrue('outerLTR.clientWidth == outerRTL.clientWidth'); -shouldBeTrue('outerLTR.scrollWidth == outerRTL.scrollWidth'); + // Verify the widths of the inner RTL elements are the same as the widths of the inner LTR elements. + assert_equals(innerLTR.offsetWidth, innerRTL.offsetWidth); + assert_equals(innerLTR.clientWidth, innerRTL.clientWidth); + assert_equals(innerLTR.scrollWidth, innerRTL.scrollWidth); -debug('Verify the widths of the inner RTL elements are the same as the widths of the inner LTR elements.'); -shouldBeTrue('innerLTR.offsetWidth == innerRTL.offsetWidth'); -shouldBeTrue('innerLTR.clientWidth == innerRTL.clientWidth'); -shouldBeTrue('innerLTR.scrollWidth == innerRTL.scrollWidth'); - -debug('Verify the width of the vertical scrollbar of the outer RTL element is the same as the one of the outer LTR element regardless of their scrollbar positions.'); -var scrollbarWidthLTR = outerLTR.offsetWidth - outerLTR.clientWidth; -var scrollbarWidthRTL = outerRTL.offsetWidth - outerRTL.clientWidth; -shouldBeTrue('scrollbarWidthLTR == scrollbarWidthRTL'); -shouldBeTrue('outerRTL.clientLeft == scrollbarWidthRTL'); + // Verify the width of the vertical scrollbar of the outer RTL element is the same as the one of the outer LTR element regardless of their scrollbar positions. + var scrollbarWidthLTR = outerLTR.offsetWidth - outerLTR.clientWidth; + var scrollbarWidthRTL = outerRTL.offsetWidth - outerRTL.clientWidth; + assert_equals(scrollbarWidthLTR, scrollbarWidthRTL); + assert_equals(outerRTL.clientLeft, scrollbarWidthRTL); +}); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/scrollbars/rtl/div-horizontal.html b/third_party/WebKit/LayoutTests/scrollbars/rtl/div-horizontal.html index e2ff7f8b..2837f7d 100644 --- a/third_party/WebKit/LayoutTests/scrollbars/rtl/div-horizontal.html +++ b/third_party/WebKit/LayoutTests/scrollbars/rtl/div-horizontal.html
@@ -1,9 +1,7 @@ <!DOCTYPE html> -<html> -<head> -<title>Bug 85856</title> -<script src="../../resources/js-test.js"></script> -</head> +<title>Bug 85856: Test if WebKit can show the left side of the inner elements regardless of the position of its scrollbars. To test manually, open this document and verify we can see "ABC" both in the LTR element and in the RTL element.</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <body dir="ltr"> <div dir="ltr" id="outer-ltr" style="width: 200px; height: 200px; overflow: scroll;"> <div id="inner-ltr" style="text-align: left; width: 300px; height: 300px;">ABC</div> @@ -11,30 +9,29 @@ <div dir="rtl" id="outer-rtl" style="width: 200px; height: 200px; overflow: scroll;"> <div id="inner-rtl" style="text-align: left; width: 300px; height: 300px;">ABC</div> </div> -<script type="text/javascript"> -description('Test if WebKit can show the left side of the inner elements regardless of the position of its scrollbars. To test manually, open this document and verify we can see "ABC" both in the LTR element and in the RTL element.'); +<script> +test(function() { + var outerLTR = document.getElementById("outer-ltr"); + var innerLTR = document.getElementById("inner-ltr"); + var outerRTL = document.getElementById("outer-rtl"); + var innerRTL = document.getElementById("inner-rtl"); + outerLTR.scrollLeft = 0; + outerRTL.scrollLeft = 0; -var outerLTR = document.getElementById('outer-ltr'); -var innerLTR = document.getElementById('inner-ltr'); -var outerRTL = document.getElementById('outer-rtl'); -var innerRTL = document.getElementById('inner-rtl'); -outerLTR.scrollLeft = 0; -outerRTL.scrollLeft = 0; + // Verify the widths of the outer RTL elements are the same as the widths of the outer LTR elements. + assert_equals(outerLTR.offsetWidth, outerRTL.offsetWidth); + assert_equals(outerLTR.clientWidth, outerRTL.clientWidth); + assert_equals(outerLTR.scrollWidth, outerRTL.scrollWidth); -debug('Verify the widths of the outer RTL elements are the same as the widths of the outer LTR elements.'); -shouldBeTrue('outerLTR.offsetWidth == outerRTL.offsetWidth'); -shouldBeTrue('outerLTR.clientWidth == outerRTL.clientWidth'); -shouldBeTrue('outerLTR.scrollWidth == outerRTL.scrollWidth'); + // Verify the widths of the inner RTL elements are the same as the widths of the inner LTR elements. + assert_equals(innerLTR.offsetWidth, innerRTL.offsetWidth); + assert_equals(innerLTR.clientWidth, innerRTL.clientWidth); + assert_equals(innerLTR.scrollWidth, innerRTL.scrollWidth); -debug('Verify the widths of the inner RTL elements are the same as the widths of the inner LTR elements.'); -shouldBeTrue('innerLTR.offsetWidth == innerRTL.offsetWidth'); -shouldBeTrue('innerLTR.clientWidth == innerRTL.clientWidth'); -shouldBeTrue('innerLTR.scrollWidth == innerRTL.scrollWidth'); - -debug('Verify the width of the vertical scrollbar of the outer RTL element is the same as the one of the outer LTR element regardless of their scrollbar positions.'); -var scrollbarWidthLTR = outerLTR.offsetWidth - outerLTR.clientWidth; -var scrollbarWidthRTL = outerRTL.offsetWidth - outerRTL.clientWidth; -shouldBeTrue('scrollbarWidthLTR == scrollbarWidthRTL'); + // Verify the width of the vertical scrollbar of the outer RTL element is the same as the one of the outer LTR element regardless of their scrollbar positions. + var scrollbarWidthLTR = outerLTR.offsetWidth - outerLTR.clientWidth; + var scrollbarWidthRTL = outerRTL.offsetWidth - outerRTL.clientWidth; + assert_equals(scrollbarWidthLTR, scrollbarWidthRTL); +}); </script> </body> -</html>
diff --git a/third_party/WebKit/LayoutTests/scrollbars/rtl/div-vertical-expected.txt b/third_party/WebKit/LayoutTests/scrollbars/rtl/div-vertical-expected.txt deleted file mode 100644 index 61ad6a9..0000000 --- a/third_party/WebKit/LayoutTests/scrollbars/rtl/div-vertical-expected.txt +++ /dev/null
@@ -1,20 +0,0 @@ -Test if WebKit can show the left side of the inner elements regardless of the position of its scrollbars. To test manually, open this document and verify we can see "ABC" both in the LTR element and in the RTL element. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -Verify the widths of the outer RTL elements are the same as the widths of the outer LTR elements. -PASS outerLTR.offsetWidth == outerRTL.offsetWidth is true -PASS outerLTR.clientWidth == outerRTL.clientWidth is true -PASS outerLTR.scrollWidth == outerRTL.scrollWidth is true -Verify the widths of the inner RTL elements are the same as the widths of the inner LTR elements. -PASS innerLTR.offsetWidth == innerRTL.offsetWidth is true -PASS innerLTR.clientWidth == innerRTL.clientWidth is true -PASS innerLTR.scrollWidth == innerRTL.scrollWidth is true -Verify the width of the vertical scrollbar of the outer RTL element is the same as the one of the outer LTR element regardless of their scrollbar positions. -PASS scrollbarWidthLTR == scrollbarWidthRTL is true -PASS successfullyParsed is true - -TEST COMPLETE -ABC -ABC
diff --git a/third_party/WebKit/LayoutTests/scrollbars/rtl/div-vertical.html b/third_party/WebKit/LayoutTests/scrollbars/rtl/div-vertical.html index d74ef21..495620a 100644 --- a/third_party/WebKit/LayoutTests/scrollbars/rtl/div-vertical.html +++ b/third_party/WebKit/LayoutTests/scrollbars/rtl/div-vertical.html
@@ -1,9 +1,7 @@ <!DOCTYPE html> -<html> -<head> -<title>Bug 85856</title> -<script src="../../resources/js-test.js"></script> -</head> +<title>Bug 85856: Test if WebKit can show the left side of the inner elements regardless of the position of its scrollbars. To test manually, open this document and verify we can see "ABC" both in the LTR element and in the RTL element.</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <body dir="ltr" style="-webkit-writing-mode: vertical-rl;"> <div dir="ltr" id="outer-ltr" style="width: 200px; height: 200px; overflow: scroll;"> <div id="inner-ltr" style="text-align: left; width: 300px; height: 300px;">ABC</div> @@ -11,30 +9,29 @@ <div dir="rtl" id="outer-rtl" style="width: 200px; height: 200px; overflow: scroll;"> <div id="inner-rtl" style="text-align: left; width: 300px; height: 300px;">ABC</div> </div> -<script type="text/javascript"> -description('Test if WebKit can show the left side of the inner elements regardless of the position of its scrollbars. To test manually, open this document and verify we can see "ABC" both in the LTR element and in the RTL element.'); +<script> +test(function() { + var outerLTR = document.getElementById("outer-ltr"); + var innerLTR = document.getElementById("inner-ltr"); + var outerRTL = document.getElementById("outer-rtl"); + var innerRTL = document.getElementById("inner-rtl"); + outerLTR.scrollLeft = 0; + outerRTL.scrollLeft = 0; -var outerLTR = document.getElementById('outer-ltr'); -var innerLTR = document.getElementById('inner-ltr'); -var outerRTL = document.getElementById('outer-rtl'); -var innerRTL = document.getElementById('inner-rtl'); -outerLTR.scrollLeft = 0; -outerRTL.scrollLeft = 0; + // Verify the widths of the outer RTL elements are the same as the widths of the outer LTR elements. + assert_equals(outerLTR.offsetWidth, outerRTL.offsetWidth); + assert_equals(outerLTR.clientWidth, outerRTL.clientWidth); + assert_equals(outerLTR.scrollWidth, outerRTL.scrollWidth); -debug('Verify the widths of the outer RTL elements are the same as the widths of the outer LTR elements.'); -shouldBeTrue('outerLTR.offsetWidth == outerRTL.offsetWidth'); -shouldBeTrue('outerLTR.clientWidth == outerRTL.clientWidth'); -shouldBeTrue('outerLTR.scrollWidth == outerRTL.scrollWidth'); + // Verify the widths of the inner RTL elements are the same as the widths of the inner LTR elements. + assert_equals(innerLTR.offsetWidth, innerRTL.offsetWidth); + assert_equals(innerLTR.clientWidth, innerRTL.clientWidth); + assert_equals(innerLTR.scrollWidth, innerRTL.scrollWidth); -debug('Verify the widths of the inner RTL elements are the same as the widths of the inner LTR elements.'); -shouldBeTrue('innerLTR.offsetWidth == innerRTL.offsetWidth'); -shouldBeTrue('innerLTR.clientWidth == innerRTL.clientWidth'); -shouldBeTrue('innerLTR.scrollWidth == innerRTL.scrollWidth'); - -debug('Verify the width of the vertical scrollbar of the outer RTL element is the same as the one of the outer LTR element regardless of their scrollbar positions.'); -var scrollbarWidthLTR = outerLTR.offsetWidth - outerLTR.clientWidth; -var scrollbarWidthRTL = outerRTL.offsetWidth - outerRTL.clientWidth; -shouldBeTrue('scrollbarWidthLTR == scrollbarWidthRTL'); + // Verify the width of the vertical scrollbar of the outer RTL element is the same as the one of the outer LTR element regardless of their scrollbar positions. + var scrollbarWidthLTR = outerLTR.offsetWidth - outerLTR.clientWidth; + var scrollbarWidthRTL = outerRTL.offsetWidth - outerRTL.clientWidth; + assert_equals(scrollbarWidthLTR, scrollbarWidthRTL); +}); </script> </body> -</html>
diff --git a/third_party/WebKit/LayoutTests/scrollbars/scrollable-iframe-click-gets-focus-expected.txt b/third_party/WebKit/LayoutTests/scrollbars/scrollable-iframe-click-gets-focus-expected.txt deleted file mode 100644 index 023b181..0000000 --- a/third_party/WebKit/LayoutTests/scrollbars/scrollable-iframe-click-gets-focus-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -For the bug that click on the green strip in the scrollable iframe will not make the iframe get the focus. crbug.com/531929 - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS -PASS successfullyParsed is true - -TEST COMPLETE - -
diff --git a/third_party/WebKit/LayoutTests/scrollbars/scrollable-iframe-click-gets-focus.html b/third_party/WebKit/LayoutTests/scrollbars/scrollable-iframe-click-gets-focus.html index 2b0b595..211f3879 100644 --- a/third_party/WebKit/LayoutTests/scrollbars/scrollable-iframe-click-gets-focus.html +++ b/third_party/WebKit/LayoutTests/scrollbars/scrollable-iframe-click-gets-focus.html
@@ -1,33 +1,24 @@ <!DOCTYPE html> -<input id='textField' type='text' style="position:relative;"> <br> -<iframe onload="runTest();" id="anIFrame" style="left:50px;width:200px;height:200px;position:absolute;" src="resources/scrollable-iframe-with-click-strip.html"> </iframe> -<script src="../resources/js-test.js"></script> +<title>For the bug that click on the green strip in the scrollable iframe will not make the iframe get the focus. crbug.com/531929</title> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> +<input type='text' style="position: relative;"> <br> +<iframe style="left: 50px; width: 200px; height: 200px; position: absolute;" src="resources/scrollable-iframe-with-click-strip.html"> </iframe> <script> +async_test(function(t) { + var iframe = document.querySelector("iframe"); + iframe.onload = t.step_func_done(function() { + document.querySelector("input").focus(); + var strip = iframe.contentDocument.getElementById("strip"); -setPrintTestResultsLazily(); -description("For the bug that click on the green strip in the scrollable iframe will not make the iframe get the focus. crbug.com/531929") + var x = iframe.offsetLeft + strip.offsetLeft + 5; + var y = iframe.offsetTop + 5; -window.jsTestIsAsync = true; - -function runTest() { - document.getElementById("textField").focus(); - if (window.eventSender) { - var frame = document.getElementById("anIFrame"); - var frame_doc = window.frames[0].document; - var strip = frame_doc.getElementById("strip"); - - var x = frame.offsetLeft + strip.offsetLeft + 5; - var y = frame.offsetTop + 5; - - // send mouse event to click iframe's green strip; - eventSender.mouseMoveTo(x, y); - eventSender.mouseDown(); - eventSender.mouseUp(); - if (window.frames[0].document.hasFocus()) - debug("PASS"); - else - debug("FAIL"); - } - finishJSTest(); -} + // send mouse event to click iframe's green strip; + eventSender.mouseMoveTo(x, y); + eventSender.mouseDown(); + eventSender.mouseUp(); + assert_true(iframe.contentDocument.hasFocus()); + }); +}); </script>
diff --git a/third_party/WebKit/LayoutTests/svg/animations/animateMotion_changingPath-expected.html b/third_party/WebKit/LayoutTests/svg/animations/animateMotion_changingPath-expected.html new file mode 100644 index 0000000..0bc427d --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/animations/animateMotion_changingPath-expected.html
@@ -0,0 +1,12 @@ +<!DOCTYPE html> +<style> +#track { + stroke: blue; +} +</style> +<svg width="200" height="200"> + + <path id="track" d="M20,100 H180"/> + + <circle r="10" cx="100" cy="180" fill="green"/> +</svg>
diff --git a/third_party/WebKit/LayoutTests/svg/animations/animateMotion_changingPath.html b/third_party/WebKit/LayoutTests/svg/animations/animateMotion_changingPath.html new file mode 100644 index 0000000..33d23c55 --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/animations/animateMotion_changingPath.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<script src="../../resources/run-after-layout-and-paint.js"></script> +<style> +#track { + d: path('M20,100 H180'); + stroke: blue; +} +</style> +<svg id="svgRoot" width="200" height="200"> + + <path id="track" d="M20,20 H180"/> + + <circle r="10" cx="0" cy="0" fill="green"> + <animateMotion dur="5s" fill="freeze"> + <mpath xlink:href="#track"/> + </animateMotion> + </circle> +</svg> +<script> +'use strict'; +runAfterLayoutAndPaint(function() { + document.getElementById('track').setAttribute('d', 'M100,20 V180'); + document.getElementById('svgRoot').setCurrentTime(5); +}, true); +</script>
diff --git a/third_party/WebKit/LayoutTests/svg/custom/detached-outermost-svg-crash-expected.txt b/third_party/WebKit/LayoutTests/svg/custom/detached-outermost-svg-crash-expected.txt index af2fdd84..cfd0f953 100644 --- a/third_party/WebKit/LayoutTests/svg/custom/detached-outermost-svg-crash-expected.txt +++ b/third_party/WebKit/LayoutTests/svg/custom/detached-outermost-svg-crash-expected.txt
@@ -1,3 +1,4 @@ +CONSOLE WARNING: line 10: SVGSVGElement.viewport is deprecated and will be removed in M55, around November 2016. See https://www.chromestatus.com/features/5686865248124928 for more details. CONSOLE WARNING: line 10: SVGSVGElement.useCurrentView is deprecated and will be removed in M56, around January 2017. See https://www.chromestatus.com/features/4511711998509056 for more details. CONSOLE WARNING: line 10: SVGSVGElement.currentView is deprecated and will be removed in M56, around January 2017. See https://www.chromestatus.com/features/4511711998509056 for more details. PASSED -- webkit did not crash in SVGSVGElement::isOutermostSVG(). See https://bugs.webkit.org/show_bug.cgi?id=25105
diff --git a/third_party/WebKit/LayoutTests/svg/custom/immutable-properties-expected.txt b/third_party/WebKit/LayoutTests/svg/custom/immutable-properties-expected.txt index 1f8e471..2b403ef16 100644 --- a/third_party/WebKit/LayoutTests/svg/custom/immutable-properties-expected.txt +++ b/third_party/WebKit/LayoutTests/svg/custom/immutable-properties-expected.txt
@@ -1,3 +1,4 @@ +CONSOLE WARNING: line 6: SVGSVGElement.viewport is deprecated and will be removed in M55, around November 2016. See https://www.chromestatus.com/features/5686865248124928 for more details. Tests whether immutable properties can not be modified. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
diff --git a/third_party/WebKit/LayoutTests/svg/hittest/empty-container.html b/third_party/WebKit/LayoutTests/svg/hittest/empty-container.html new file mode 100644 index 0000000..6df26ab --- /dev/null +++ b/third_party/WebKit/LayoutTests/svg/hittest/empty-container.html
@@ -0,0 +1,24 @@ +<!DOCTYPE html> +<title>Hit testing an empty container should not crash.</title> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<style> + * { + margin: 0; + } + svg { + pointer-events: bounding-box; + } +</style> +<svg id="svg" width="200" height="200"> + <g></g> +</svg> +<script> + test(function() { + var checkOrigin = document.elementFromPoint(0, 0); + assert_equals(checkOrigin, svg, "element @ 0, 0"); + + var checkPoint = document.elementFromPoint(50, 50); + assert_equals(checkPoint, svg, "element @ 50, 50"); + }); +</script>
diff --git a/third_party/WebKit/LayoutTests/virtual/mojo-loading/webexposed/README.txt b/third_party/WebKit/LayoutTests/virtual/mojo-loading/webexposed/README.txt new file mode 100644 index 0000000..ce19c5e --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/mojo-loading/webexposed/README.txt
@@ -0,0 +1,4 @@ +This directory is for testing loading with mojo. + +We use "webexposed" directory for testing basic loading functionalities +through fetching html files.
diff --git a/third_party/WebKit/LayoutTests/virtual/parsehtmlonmainthread_coalesce/fast/parser/README.txt b/third_party/WebKit/LayoutTests/virtual/parsehtmlonmainthread_coalesce/fast/parser/README.txt new file mode 100644 index 0000000..31dc0da --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/parsehtmlonmainthread_coalesce/fast/parser/README.txt
@@ -0,0 +1,3 @@ +# This suite runs the tests in fast/parser with +# --disable-blink-features=ParseHTMLOnMainThread and +# --blink-settings=parseHTMLOnMainThreadCoalesceChunks=true
diff --git a/third_party/WebKit/LayoutTests/virtual/parsehtmlonmainthread_sync/fast/parser/README.txt b/third_party/WebKit/LayoutTests/virtual/parsehtmlonmainthread_sync/fast/parser/README.txt new file mode 100644 index 0000000..1873929 --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/parsehtmlonmainthread_sync/fast/parser/README.txt
@@ -0,0 +1,3 @@ +# This suite runs the tests in fast/parser with +# --enable-blink-features=ParseHTMLOnMainThread and +# --blink-settings=parseHTMLOnMainThreadSyncTokenize=true
diff --git a/third_party/WebKit/LayoutTests/virtual/prefer_compositing_to_lcd_text/scrollbars/rtl/div-absolute-expected.txt b/third_party/WebKit/LayoutTests/virtual/prefer_compositing_to_lcd_text/scrollbars/rtl/div-absolute-expected.txt deleted file mode 100644 index 3069c44..0000000 --- a/third_party/WebKit/LayoutTests/virtual/prefer_compositing_to_lcd_text/scrollbars/rtl/div-absolute-expected.txt +++ /dev/null
@@ -1,18 +0,0 @@ -Test if the widths of RTL elements are the same as the widths of the LTR elements when they include absolutely-positioned children. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -Verify the widths of the outer RTL element are the same as the widths of the outer LTR element. -PASS outerLTR.offsetWidth == outerRTL.offsetWidth is true -PASS outerLTR.clientWidth == outerRTL.clientWidth is true -PASS outerLTR.scrollWidth == outerRTL.scrollWidth is true -Verify the widths of the inner RTL element are the same as the widths of the inner LTR element. -PASS innerLTR.offsetWidth == innerRTL.offsetWidth is true -PASS innerLTR.clientWidth == innerRTL.clientWidth is true -PASS innerLTR.scrollWidth == innerRTL.scrollWidth is true -PASS successfullyParsed is true - -TEST COMPLETE -foo -foo
diff --git a/third_party/WebKit/LayoutTests/virtual/threaded/inspector/tracing/idle-callback-expected.txt b/third_party/WebKit/LayoutTests/virtual/threaded/inspector/tracing/idle-callback-expected.txt index 91a580f..524a294 100644 --- a/third_party/WebKit/LayoutTests/virtual/threaded/inspector/tracing/idle-callback-expected.txt +++ b/third_party/WebKit/LayoutTests/virtual/threaded/inspector/tracing/idle-callback-expected.txt
@@ -14,21 +14,6 @@ startTime : <number> type : "RequestIdleCallback" } -Text details for RequestIdleCallback: idle-callback.html:8 -RequestIdleCallback Properties: -{ - data : { - frame : <string> - id : <number> - stackTrace : <object> - timeout : 0 - } - endTime : <number> - frameId : <string> - stackTrace : <object> - startTime : <number> - type : "RequestIdleCallback" -} Text details for RequestIdleCallback: idle-callback.html:10 RequestIdleCallback Properties: { @@ -44,7 +29,22 @@ startTime : <number> type : "RequestIdleCallback" } -Text details for RequestIdleCallback: idle-callback.html:13 +Text details for RequestIdleCallback: idle-callback.html:12 +RequestIdleCallback Properties: +{ + data : { + frame : <string> + id : <number> + stackTrace : <object> + timeout : 0 + } + endTime : <number> + frameId : <string> + stackTrace : <object> + startTime : <number> + type : "RequestIdleCallback" +} +Text details for RequestIdleCallback: idle-callback.html:15 CancelIdleCallback Properties: { data : { @@ -58,7 +58,7 @@ startTime : <number> type : "CancelIdleCallback" } -Text details for CancelIdleCallback: idle-callback.html:9 +Text details for CancelIdleCallback: idle-callback.html:11 FireIdleCallback Properties: { data : { @@ -72,7 +72,7 @@ startTime : <number> type : "FireIdleCallback" } -Text details for FireIdleCallback: idle-callback.html:10 +Text details for FireIdleCallback: idle-callback.html:12 FireIdleCallback Properties: { data : { @@ -86,6 +86,6 @@ startTime : <number> type : "FireIdleCallback" } -Text details for FireIdleCallback: idle-callback.html:13 +Text details for FireIdleCallback: idle-callback.html:15 FireIdleCallback has a warning
diff --git a/third_party/WebKit/LayoutTests/virtual/threaded/inspector/tracing/idle-callback.html b/third_party/WebKit/LayoutTests/virtual/threaded/inspector/tracing/idle-callback.html index 6f7ae12..d0437f0 100644 --- a/third_party/WebKit/LayoutTests/virtual/threaded/inspector/tracing/idle-callback.html +++ b/third_party/WebKit/LayoutTests/virtual/threaded/inspector/tracing/idle-callback.html
@@ -3,8 +3,10 @@ <script src="../../../../http/tests/inspector/inspector-test.js"></script> <script src="../../../../http/tests/inspector/timeline-test.js"></script> <script> -function performActions(callback) +function performActions() { + var callback; + var promise = new Promise((fulfill) => callback = fulfill); var requestId = window.requestIdleCallback(idleCallback); window.cancelIdleCallback(requestId); window.requestIdleCallback(idleCallback); @@ -18,6 +20,7 @@ if (callback) callback(); } + return promise; } function test()
diff --git a/third_party/WebKit/LayoutTests/webaudio/resources/audio-testing.js b/third_party/WebKit/LayoutTests/webaudio/resources/audio-testing.js index 09f2bf7..5cbe92c 100644 --- a/third_party/WebKit/LayoutTests/webaudio/resources/audio-testing.js +++ b/third_party/WebKit/LayoutTests/webaudio/resources/audio-testing.js
@@ -604,9 +604,11 @@ // Result: // "PASS Zero is equal to 0." ShouldModel.prototype.beEqualTo = function (value) { - var type = typeof value; - this._assert(type === 'number' || type === 'string', - 'value should be number or string for', value); + if (value != null) { + var type = typeof value; + this._assert(type === 'number' || type === 'string' || type === 'boolean', + 'value should be number, string, or boolean for', value); + } this._checkNaN(value, 'EXPECTED'); @@ -1138,6 +1140,22 @@ }.bind(this)); }; + // A summary message + // + // Example: + // Should("Summary1", true).summarize("passed1", "failed1"); + // Should("Summary2", false).summarize("passed2", "failed2"); + // Result: + // "PASS Summary1: passed1." + // "FAIL Summary2: failed2." + ShouldModel.prototype.summarize = function (pass, fail) { + if (this.target) + this._testPassed(pass); + else + this._testFailed(fail); + return this._success; + } + // Should() method. // // |desc| is the description of the task or check and |target| is a value
diff --git a/third_party/WebKit/LayoutTests/webaudio/waveshaper-copy-curve.html b/third_party/WebKit/LayoutTests/webaudio/waveshaper-copy-curve.html new file mode 100644 index 0000000..5ebed9d00 --- /dev/null +++ b/third_party/WebKit/LayoutTests/webaudio/waveshaper-copy-curve.html
@@ -0,0 +1,87 @@ +<!doctype html> +<html> + <head> + <title>Test WaveShaper Copies Curve Data</title> + <script src="../resources/testharness.js"></script> + <script src="../resources/testharnessreport.js"></script> + <script src="resources/audio-testing.js"></script> + </head> + + <body> + <script> + // Sample rate and number of frames are fairly arbitrary. We need to + // render, however, at least 384 frames. 1024 is a nice small value. + var sampleRate = 16000; + var renderFrames = 1024; + + var audit = Audit.createTaskRunner(); + + audit.defineTask("test copying", function (taskDone) { + // Two-channel context; channel 0 contains the test data and channel 1 + // contains the expected result. Channel 1 has the normal WaveShaper + // output and channel 0 has the WaveShaper output with a modified curve. + var context = new OfflineAudioContext(2, renderFrames, sampleRate); + + // Just use a default oscillator as the source. Doesn't really matter + // what we use. + var src = context.createOscillator(); + src.type = "sawtooth"; + + // Create the wave shapers: ws0 is the test shaper, and ws1 is the + // reference wave shaper. + var ws0 = context.createWaveShaper(); + var ws1 = context.createWaveShaper(); + + // Wave shaper curves. Doesn't really matter what we use as long as it + // modifies the input in some way. Thus, keep it simple and just invert + // the input. + var desiredCurve = [1, 0, -1]; + var curve0 = Float32Array.from(desiredCurve); + var curve1 = Float32Array.from(desiredCurve); + + ws0.curve = curve0; + ws1.curve = curve1; + + var merger = context.createChannelMerger(2); + + // Connect the graph + src.connect(ws0); + src.connect(ws1); + + ws0.connect(merger, 0, 0); + ws1.connect(merger, 0, 1); + + merger.connect(context.destination); + + // Let the context run for a bit and then modify the curve for ws0. + // Doesn't really matter what we modify the curve to as long as it's + // different. + context.suspend(256 / context.sampleRate) + .then(function () { + curve0[0] = -0.5; + curve0[1] = 0.125; + curve0[2] = 0.75; + }) + .then(context.resume.bind(context)); + + src.start(); + + context.startRendering().then(function (renderedBuffer) { + var actual = renderedBuffer.getChannelData(0); + var expected = renderedBuffer.getChannelData(1); + + // Modifying the wave shaper curve should not modify the output so the + // outputs from the two wave shaper nodes should be exactly identical. + var success = Should("WaveShaper with modified curve", actual) + .beEqualToArray(expected); + + Should("Summary: ", success).summarize( + "Output correctly did not change with modified WaveShaper curve.", + "Output incorrectly changed due to modified WaveShaper curve."); + }).then(taskDone); + }); + + audit.runTasks(); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/webaudio/waveshaper-simple.html b/third_party/WebKit/LayoutTests/webaudio/waveshaper-simple.html new file mode 100644 index 0000000..53a6332d --- /dev/null +++ b/third_party/WebKit/LayoutTests/webaudio/waveshaper-simple.html
@@ -0,0 +1,48 @@ +<!doctype html> +<html> + <head> + <title>Simple Tests of WaveShaperNode</title> + <script src="../resources/testharness.js"></script> + <script src="../resources/testharnessreport.js"></script> + <script src="resources/audio-testing.js"></script> + </head> + + <body> + <script> + var audit = Audit.createTaskRunner(); + + audit.defineTask("simple", function (taskDone) { + var context = new OfflineAudioContext(1, 1, 48000); + var shaper = context.createWaveShaper(); + + // Verify default values are correct. + Should("WaveShaper.curve", shaper.curve).beEqualTo(null); + Should("WaveShaper.oversample", shaper.oversample).beEqualTo("none"); + + // Set oversample and verify that it is set correctly. + shaper.oversample = "2x"; + Should('Waveshaper.oversample = "2x"', shaper.oversample).beEqualTo("2x"); + + shaper.oversample = "4x"; + Should('Waveshaper.oversample = "4x"', shaper.oversample).beEqualTo("4x"); + + shaper.oversample = "invalid"; + Should('Waveshaper.oversample = "invalid"', shaper.oversample).beEqualTo("4x"); + + // Set the curve and verify that the returned curve is the same as what + // it was set to. + var curve = Float32Array.from([-1, 0.25, .75]); + shaper.curve = curve; + Should("WaveShaper.curve", shaper.curve).beEqualToArray(curve); + + // Verify setting the curve to null works. + shaper.curve = null; + Should("Waveshaper.curve = null", shaper.curve).beEqualTo(null); + + taskDone(); + }); + + audit.runTasks(); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt index eda9a0d..bdc000f 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-dedicated-worker-expected.txt
@@ -504,6 +504,7 @@ [Worker] setter width [Worker] interface OffscreenCanvasRenderingContext2D [Worker] attribute @@toStringTag +[Worker] getter canvas [Worker] getter fillStyle [Worker] getter imageSmoothingEnabled [Worker] getter imageSmoothingQuality @@ -512,7 +513,6 @@ [Worker] getter lineJoin [Worker] getter lineWidth [Worker] getter miterLimit -[Worker] getter offscreenCanvas [Worker] getter shadowBlur [Worker] getter shadowColor [Worker] getter shadowOffsetX
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt index da55afb..0a33c7c 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-expected.txt
@@ -389,7 +389,7 @@ method constructor method postMessage setter onmessage -interface Budget +interface BudgetService attribute @@toStringTag method constructor method getBudget @@ -440,6 +440,12 @@ method constructor method deleteRule method insertRule +interface CSSImageValue : CSSResourceValue + attribute @@toStringTag + getter intrinsicHeight + getter intrinsicRatio + getter intrinsicWidth + method constructor interface CSSImportRule : CSSRule attribute @@toStringTag getter href @@ -4187,6 +4193,7 @@ setter width interface OffscreenCanvasRenderingContext2D attribute @@toStringTag + getter canvas getter fillStyle getter filter getter imageSmoothingEnabled @@ -4196,7 +4203,6 @@ getter lineJoin getter lineWidth getter miterLimit - getter offscreenCanvas getter shadowBlur getter shadowColor getter shadowOffsetX
diff --git a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt index 508df3b..cec176a0 100644 --- a/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/WebKit/LayoutTests/webexposed/global-interface-listing-shared-worker-expected.txt
@@ -491,6 +491,7 @@ [Worker] setter width [Worker] interface OffscreenCanvasRenderingContext2D [Worker] attribute @@toStringTag +[Worker] getter canvas [Worker] getter fillStyle [Worker] getter imageSmoothingEnabled [Worker] getter imageSmoothingQuality @@ -499,7 +500,6 @@ [Worker] getter lineJoin [Worker] getter lineWidth [Worker] getter miterLimit -[Worker] getter offscreenCanvas [Worker] getter shadowBlur [Worker] getter shadowColor [Worker] getter shadowOffsetX
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScheduledAction.cpp b/third_party/WebKit/Source/bindings/core/v8/ScheduledAction.cpp index d15d3385..20bd64c 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScheduledAction.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScheduledAction.cpp
@@ -40,7 +40,6 @@ #include "core/frame/LocalFrame.h" #include "core/workers/WorkerGlobalScope.h" #include "core/workers/WorkerThread.h" -#include "platform/Logging.h" #include "platform/TraceEvent.h" namespace blink {
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8Binding.cpp b/third_party/WebKit/Source/bindings/core/v8/V8Binding.cpp index 455e8b3..fa81e2e 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8Binding.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8Binding.cpp
@@ -36,6 +36,7 @@ #include "bindings/core/v8/V8BindingMacros.h" #include "bindings/core/v8/V8Element.h" #include "bindings/core/v8/V8EventTarget.h" +#include "bindings/core/v8/V8HTMLLinkElement.h" #include "bindings/core/v8/V8NodeFilter.h" #include "bindings/core/v8/V8NodeFilterCondition.h" #include "bindings/core/v8/V8ObjectConstructor.h" @@ -809,8 +810,16 @@ // configuration of origin trial enabled attibutes and interfaces in IDL // files. (crbug.com/615060) - // Initialization code for origin trials for core bindings, if necessary, - // should go here. + ExecutionContext* executionContext = scriptState->getExecutionContext(); + OriginTrialContext* originTrialContext = OriginTrialContext::from(executionContext, OriginTrialContext::DontCreateIfNotExists); + if (!originTrialContext) + return; + + if (!originTrialContext->featureBindingsInstalled("LinkServiceWorker") && (RuntimeEnabledFeatures::linkServiceWorkerEnabled() || originTrialContext->isFeatureEnabled("ForeignFetch"))) { + if (executionContext->isDocument()) { + V8HTMLLinkElement::installLinkServiceWorker(scriptState); + } + } } namespace { @@ -837,6 +846,14 @@ if (!originTrialContext->featureBindingsInstalled("WebBluetooth") && (RuntimeEnabledFeatures::webBluetoothEnabled() || originTrialContext->isFeatureEnabled("WebBluetooth"))) { originTrialContext->setFeatureBindingsInstalled("WebBluetooth"); } + + if (!originTrialContext->featureBindingsInstalled("LinkServiceWorker") && (RuntimeEnabledFeatures::linkServiceWorkerEnabled() || originTrialContext->isFeatureEnabled("ForeignFetch"))) { + originTrialContext->setFeatureBindingsInstalled("LinkServiceWorker"); + } + + if (!originTrialContext->featureBindingsInstalled("ForeignFetch") && (RuntimeEnabledFeatures::foreignFetchEnabled() || originTrialContext->isFeatureEnabled("ForeignFetch"))) { + originTrialContext->setFeatureBindingsInstalled("ForeignFetch"); + } } InstallOriginTrialsFunction setInstallOriginTrialsFunction(InstallOriginTrialsFunction newInstallOriginTrialsFunction)
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8LazyEventListener.cpp b/third_party/WebKit/Source/bindings/core/v8/V8LazyEventListener.cpp index d714761..9bace83 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8LazyEventListener.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8LazyEventListener.cpp
@@ -167,8 +167,6 @@ v8String(isolate(), m_sourceURL), v8::Integer::New(isolate(), m_position.m_line.zeroBasedInt()), v8::Integer::New(isolate(), m_position.m_column.zeroBasedInt()), - v8::True(isolate()), - v8::Local<v8::Integer>(), v8::True(isolate())); v8::ScriptCompiler::Source source(v8String(isolate(), m_code), origin);
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8StringResource.h b/third_party/WebKit/Source/bindings/core/v8/V8StringResource.h index b65cfad..9194e856 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8StringResource.h +++ b/third_party/WebKit/Source/bindings/core/v8/V8StringResource.h
@@ -48,7 +48,7 @@ m_threadId = WTF::currentThread(); #endif ASSERT(!string.isNull()); - v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(memoryConsumption(string)); + v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(string.charactersSizeInBytes()); } explicit WebCoreStringResourceBase(const AtomicString& string) @@ -59,7 +59,7 @@ m_threadId = WTF::currentThread(); #endif ASSERT(!string.isNull()); - v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(memoryConsumption(string)); + v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(string.charactersSizeInBytes()); } virtual ~WebCoreStringResourceBase() @@ -67,10 +67,10 @@ #if ENABLE(ASSERT) ASSERT(m_threadId == WTF::currentThread()); #endif - int reducedExternalMemory = -memoryConsumption(m_plainString); + int64_t reducedExternalMemory = m_plainString.charactersSizeInBytes(); if (m_plainString.impl() != m_atomicString.impl() && !m_atomicString.isNull()) - reducedExternalMemory -= memoryConsumption(m_atomicString); - v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(reducedExternalMemory); + reducedExternalMemory += m_atomicString.charactersSizeInBytes(); + v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-reducedExternalMemory); } const String& webcoreString() { return m_plainString; } @@ -84,7 +84,7 @@ m_atomicString = AtomicString(m_plainString); ASSERT(!m_atomicString.isNull()); if (m_plainString.impl() != m_atomicString.impl()) - v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(memoryConsumption(m_atomicString.getString())); + v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(m_atomicString.charactersSizeInBytes()); } return m_atomicString; } @@ -100,10 +100,6 @@ AtomicString m_atomicString; private: - static int memoryConsumption(const String& string) - { - return string.length() * (string.is8Bit() ? sizeof(LChar) : sizeof(UChar)); - } #if ENABLE(ASSERT) WTF::ThreadIdentifier m_threadId; #endif
diff --git a/third_party/WebKit/Source/bindings/core/v8/generated.gni b/third_party/WebKit/Source/bindings/core/v8/generated.gni index 440d3a3f..233aa19 100644 --- a/third_party/WebKit/Source/bindings/core/v8/generated.gni +++ b/third_party/WebKit/Source/bindings/core/v8/generated.gni
@@ -109,6 +109,8 @@ "$bindings_core_v8_output_dir/CSSStyleValueOrCSSStyleValueSequence.h", "$bindings_core_v8_output_dir/CSSStyleValueOrCSSStyleValueSequenceOrString.cpp", "$bindings_core_v8_output_dir/CSSStyleValueOrCSSStyleValueSequenceOrString.h", + "$bindings_core_v8_output_dir/DictionarySequenceOrDictionary.cpp", + "$bindings_core_v8_output_dir/DictionarySequenceOrDictionary.h", "$bindings_core_v8_output_dir/DoubleOrAutoKeyword.cpp", "$bindings_core_v8_output_dir/DoubleOrAutoKeyword.h", "$bindings_core_v8_output_dir/DoubleOrDoubleArray.cpp", @@ -121,8 +123,6 @@ "$bindings_core_v8_output_dir/DoubleOrStringOrStringArray.h", "$bindings_core_v8_output_dir/DoubleOrStringOrStringSequence.cpp", "$bindings_core_v8_output_dir/DoubleOrStringOrStringSequence.h", - "$bindings_core_v8_output_dir/EffectModelOrDictionarySequenceOrDictionary.cpp", - "$bindings_core_v8_output_dir/EffectModelOrDictionarySequenceOrDictionary.h", "$bindings_core_v8_output_dir/EventListenerOptionsOrBoolean.cpp", "$bindings_core_v8_output_dir/EventListenerOptionsOrBoolean.h", "$bindings_core_v8_output_dir/FileOrUSVString.cpp",
diff --git a/third_party/WebKit/Source/bindings/core/v8/generated.gypi b/third_party/WebKit/Source/bindings/core/v8/generated.gypi index 4371776..e0baddb 100644 --- a/third_party/WebKit/Source/bindings/core/v8/generated.gypi +++ b/third_party/WebKit/Source/bindings/core/v8/generated.gypi
@@ -18,6 +18,8 @@ '<(bindings_core_v8_output_dir)/CSSStyleValueOrCSSStyleValueSequence.h', '<(bindings_core_v8_output_dir)/CSSStyleValueOrCSSStyleValueSequenceOrString.cpp', '<(bindings_core_v8_output_dir)/CSSStyleValueOrCSSStyleValueSequenceOrString.h', + '<(bindings_core_v8_output_dir)/DictionarySequenceOrDictionary.cpp', + '<(bindings_core_v8_output_dir)/DictionarySequenceOrDictionary.h', '<(bindings_core_v8_output_dir)/DoubleOrAutoKeyword.cpp', '<(bindings_core_v8_output_dir)/DoubleOrAutoKeyword.h', '<(bindings_core_v8_output_dir)/DoubleOrDoubleArray.cpp', @@ -30,8 +32,6 @@ '<(bindings_core_v8_output_dir)/DoubleOrStringOrStringArray.h', '<(bindings_core_v8_output_dir)/DoubleOrStringOrStringSequence.cpp', '<(bindings_core_v8_output_dir)/DoubleOrStringOrStringSequence.h', - '<(bindings_core_v8_output_dir)/EffectModelOrDictionarySequenceOrDictionary.cpp', - '<(bindings_core_v8_output_dir)/EffectModelOrDictionarySequenceOrDictionary.h', '<(bindings_core_v8_output_dir)/EventListenerOptionsOrBoolean.cpp', '<(bindings_core_v8_output_dir)/EventListenerOptionsOrBoolean.h', '<(bindings_core_v8_output_dir)/FileOrUSVString.cpp',
diff --git a/third_party/WebKit/Source/bindings/modules/v8/V8BindingForModules.cpp b/third_party/WebKit/Source/bindings/modules/v8/V8BindingForModules.cpp index 9be9161..7fca51f6c 100644 --- a/third_party/WebKit/Source/bindings/modules/v8/V8BindingForModules.cpp +++ b/third_party/WebKit/Source/bindings/modules/v8/V8BindingForModules.cpp
@@ -568,6 +568,12 @@ V8NavigatorPartial::installWebBluetooth(scriptState); } } + + if (!originTrialContext->featureBindingsInstalled("ForeignFetch") && (RuntimeEnabledFeatures::foreignFetchEnabled() || originTrialContext->isFeatureEnabled("ForeignFetch"))) { + if (executionContext->isServiceWorkerGlobalScope()) { + V8ServiceWorkerGlobalScope::installForeignFetch(scriptState, global); + } + } } void registerInstallOriginTrialsForModules()
diff --git a/third_party/WebKit/Source/bindings/modules/v8/generated.gni b/third_party/WebKit/Source/bindings/modules/v8/generated.gni index e4f7a52..7d2ba8d 100644 --- a/third_party/WebKit/Source/bindings/modules/v8/generated.gni +++ b/third_party/WebKit/Source/bindings/modules/v8/generated.gni
@@ -121,6 +121,8 @@ "$bindings_modules_v8_output_dir/DoubleOrConstrainDoubleRange.h", "$bindings_modules_v8_output_dir/FormDataOrURLSearchParams.cpp", "$bindings_modules_v8_output_dir/FormDataOrURLSearchParams.h", + "$bindings_modules_v8_output_dir/HTMLCanvasElementOrOffscreenCanvas.cpp", + "$bindings_modules_v8_output_dir/HTMLCanvasElementOrOffscreenCanvas.h", "$bindings_modules_v8_output_dir/HTMLImageElementOrHTMLVideoElementOrHTMLCanvasElementOrImageBitmap.cpp", "$bindings_modules_v8_output_dir/HTMLImageElementOrHTMLVideoElementOrHTMLCanvasElementOrImageBitmap.h", "$bindings_modules_v8_output_dir/LongOrConstrainLongRange.cpp",
diff --git a/third_party/WebKit/Source/core/animation/Animation.cpp b/third_party/WebKit/Source/core/animation/Animation.cpp index 6fe5a0f..02b9602 100644 --- a/third_party/WebKit/Source/core/animation/Animation.cpp +++ b/third_party/WebKit/Source/core/animation/Animation.cpp
@@ -991,11 +991,11 @@ bool wasActive = oldPlayState == Pending || oldPlayState == Running; bool isActive = newPlayState == Pending || newPlayState == Running; if (!wasActive && isActive) - TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("blink.animations,devtools.timeline,benchmark", "Animation", m_animation, "data", InspectorAnimationEvent::data(*m_animation)); + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1("blink.animations,devtools.timeline,benchmark,rail", "Animation", m_animation, "data", InspectorAnimationEvent::data(*m_animation)); else if (wasActive && !isActive) - TRACE_EVENT_NESTABLE_ASYNC_END1("blink.animations,devtools.timeline,benchmark", "Animation", m_animation, "endData", InspectorAnimationStateEvent::data(*m_animation)); + TRACE_EVENT_NESTABLE_ASYNC_END1("blink.animations,devtools.timeline,benchmark,rail", "Animation", m_animation, "endData", InspectorAnimationStateEvent::data(*m_animation)); else - TRACE_EVENT_NESTABLE_ASYNC_INSTANT1("blink.animations,devtools.timeline,benchmark", "Animation", m_animation, "data", InspectorAnimationStateEvent::data(*m_animation)); + TRACE_EVENT_NESTABLE_ASYNC_INSTANT1("blink.animations,devtools.timeline,benchmark,rail", "Animation", m_animation, "data", InspectorAnimationStateEvent::data(*m_animation)); } // Ordering is important, the ready promise should resolve/reject before
diff --git a/third_party/WebKit/Source/core/animation/AnimationEffect.cpp b/third_party/WebKit/Source/core/animation/AnimationEffect.cpp index a59ed55..82c4d95 100644 --- a/third_party/WebKit/Source/core/animation/AnimationEffect.cpp +++ b/third_party/WebKit/Source/core/animation/AnimationEffect.cpp
@@ -121,7 +121,6 @@ duration.setUnrestrictedDouble(iterationDuration() * 1000); computedTiming.setDuration(duration); - computedTiming.setPlaybackRate(specifiedTiming().playbackRate); computedTiming.setDirection(Timing::playbackDirectionString(specifiedTiming().direction)); computedTiming.setEasing(specifiedTiming().timingFunction->toString()); }
diff --git a/third_party/WebKit/Source/core/animation/AnimationEffectTimingProperties.idl b/third_party/WebKit/Source/core/animation/AnimationEffectTimingProperties.idl index 4fc30330..005894a 100644 --- a/third_party/WebKit/Source/core/animation/AnimationEffectTimingProperties.idl +++ b/third_party/WebKit/Source/core/animation/AnimationEffectTimingProperties.idl
@@ -14,8 +14,6 @@ double iterationStart = 0.0; unrestricted double iterations = 1.0; (unrestricted double or DOMString) duration = "auto"; - // TODO(alancutter): Remove playbackRate. - double playbackRate = 1.0; PlaybackDirection direction = "normal"; DOMString easing = "linear"; };
diff --git a/third_party/WebKit/Source/core/animation/EffectInput.cpp b/third_party/WebKit/Source/core/animation/EffectInput.cpp index ea361f4..0cb9f36e 100644 --- a/third_party/WebKit/Source/core/animation/EffectInput.cpp +++ b/third_party/WebKit/Source/core/animation/EffectInput.cpp
@@ -31,7 +31,7 @@ #include "core/animation/EffectInput.h" #include "bindings/core/v8/Dictionary.h" -#include "bindings/core/v8/EffectModelOrDictionarySequenceOrDictionary.h" +#include "bindings/core/v8/DictionarySequenceOrDictionary.h" #include "core/animation/AnimationInputHelpers.h" #include "core/animation/CompositorAnimations.h" #include "core/animation/KeyframeEffectModel.h" @@ -138,11 +138,8 @@ } // namespace // Spec: http://w3c.github.io/web-animations/#processing-a-frames-argument -EffectModel* EffectInput::convert(Element* element, const EffectModelOrDictionarySequenceOrDictionary& effectInput, ExecutionContext* executionContext, ExceptionState& exceptionState) +EffectModel* EffectInput::convert(Element* element, const DictionarySequenceOrDictionary& effectInput, ExecutionContext* executionContext, ExceptionState& exceptionState) { - if (effectInput.isEffectModel()) - return effectInput.getAsEffectModel(); - if (effectInput.isNull() || !element) return nullptr;
diff --git a/third_party/WebKit/Source/core/animation/EffectInput.h b/third_party/WebKit/Source/core/animation/EffectInput.h index 372aee5..839e4aa 100644 --- a/third_party/WebKit/Source/core/animation/EffectInput.h +++ b/third_party/WebKit/Source/core/animation/EffectInput.h
@@ -13,7 +13,7 @@ namespace blink { class EffectModel; -class EffectModelOrDictionarySequenceOrDictionary; +class DictionarySequenceOrDictionary; class Dictionary; class Element; class ExceptionState; @@ -23,7 +23,7 @@ STATIC_ONLY(EffectInput); public: // TODO(alancutter): Replace Element* parameter with Document&. - static EffectModel* convert(Element*, const EffectModelOrDictionarySequenceOrDictionary&, ExecutionContext*, ExceptionState&); + static EffectModel* convert(Element*, const DictionarySequenceOrDictionary&, ExecutionContext*, ExceptionState&); private: static EffectModel* convertArrayForm(Element&, const Vector<Dictionary>& keyframes, ExceptionState&);
diff --git a/third_party/WebKit/Source/core/animation/EffectInputTest.cpp b/third_party/WebKit/Source/core/animation/EffectInputTest.cpp index 32cf30f..f8d63b5 100644 --- a/third_party/WebKit/Source/core/animation/EffectInputTest.cpp +++ b/third_party/WebKit/Source/core/animation/EffectInputTest.cpp
@@ -5,7 +5,7 @@ #include "core/animation/EffectInput.h" #include "bindings/core/v8/Dictionary.h" -#include "bindings/core/v8/EffectModelOrDictionarySequenceOrDictionary.h" +#include "bindings/core/v8/DictionarySequenceOrDictionary.h" #include "bindings/core/v8/V8BindingForTesting.h" #include "core/animation/AnimationTestHelper.h" #include "core/animation/KeyframeEffectModel.h" @@ -42,7 +42,7 @@ jsKeyframes.append(Dictionary(keyframe2, scope.isolate(), scope.getExceptionState())); Element* element = appendElement(scope.document()); - EffectModel* animationEffect = EffectInput::convert(element, EffectModelOrDictionarySequenceOrDictionary::fromDictionarySequence(jsKeyframes), nullptr, scope.getExceptionState()); + EffectModel* animationEffect = EffectInput::convert(element, DictionarySequenceOrDictionary::fromDictionarySequence(jsKeyframes), nullptr, scope.getExceptionState()); EXPECT_FALSE(scope.getExceptionState().hadException()); const KeyframeEffectModelBase& keyframeEffect = *toKeyframeEffectModelBase(animationEffect); EXPECT_EQ(1.0, keyframeEffect.getFrames()[1]->offset()); @@ -64,7 +64,7 @@ jsKeyframes.append(Dictionary(keyframe2, scope.isolate(), scope.getExceptionState())); Element* element = appendElement(scope.document()); - EffectInput::convert(element, EffectModelOrDictionarySequenceOrDictionary::fromDictionarySequence(jsKeyframes), nullptr, scope.getExceptionState()); + EffectInput::convert(element, DictionarySequenceOrDictionary::fromDictionarySequence(jsKeyframes), nullptr, scope.getExceptionState()); EXPECT_TRUE(scope.getExceptionState().hadException()); EXPECT_EQ(V8TypeError, scope.getExceptionState().code()); } @@ -88,7 +88,7 @@ jsKeyframes.append(Dictionary(keyframe3, scope.isolate(), scope.getExceptionState())); Element* element = appendElement(scope.document()); - EffectModel* animationEffect = EffectInput::convert(element, EffectModelOrDictionarySequenceOrDictionary::fromDictionarySequence(jsKeyframes), nullptr, scope.getExceptionState()); + EffectModel* animationEffect = EffectInput::convert(element, DictionarySequenceOrDictionary::fromDictionarySequence(jsKeyframes), nullptr, scope.getExceptionState()); EXPECT_FALSE(scope.getExceptionState().hadException()); const KeyframeEffectModelBase& keyframeEffect = *toKeyframeEffectModelBase(animationEffect); EXPECT_EQ(1, keyframeEffect.getFrames()[2]->offset()); @@ -117,7 +117,7 @@ jsKeyframes.append(Dictionary(keyframe4, scope.isolate(), scope.getExceptionState())); Element* element = appendElement(scope.document()); - EffectInput::convert(element, EffectModelOrDictionarySequenceOrDictionary::fromDictionarySequence(jsKeyframes), nullptr, scope.getExceptionState()); + EffectInput::convert(element, DictionarySequenceOrDictionary::fromDictionarySequence(jsKeyframes), nullptr, scope.getExceptionState()); EXPECT_TRUE(scope.getExceptionState().hadException()); } @@ -141,7 +141,7 @@ jsKeyframes.append(Dictionary(keyframe3, scope.isolate(), scope.getExceptionState())); Element* element = appendElement(scope.document()); - EffectInput::convert(element, EffectModelOrDictionarySequenceOrDictionary::fromDictionarySequence(jsKeyframes), nullptr, scope.getExceptionState()); + EffectInput::convert(element, DictionarySequenceOrDictionary::fromDictionarySequence(jsKeyframes), nullptr, scope.getExceptionState()); EXPECT_TRUE(scope.getExceptionState().hadException()); EXPECT_EQ(V8TypeError, scope.getExceptionState().code()); }
diff --git a/third_party/WebKit/Source/core/animation/EffectModel.h b/third_party/WebKit/Source/core/animation/EffectModel.h index cdf0cb6..b0f7a943 100644 --- a/third_party/WebKit/Source/core/animation/EffectModel.h +++ b/third_party/WebKit/Source/core/animation/EffectModel.h
@@ -31,7 +31,6 @@ #ifndef EffectModel_h #define EffectModel_h -#include "bindings/core/v8/ScriptWrappable.h" #include "core/CSSPropertyNames.h" #include "core/CoreExport.h" #include "core/animation/PropertyHandle.h" @@ -44,8 +43,7 @@ // Time independent representation of an Animation's content. // Can be sampled for the active pairs of Keyframes (represented by Interpolations) at a given time fraction. -class CORE_EXPORT EffectModel : public GarbageCollectedFinalized<EffectModel>, public ScriptWrappable { - DEFINE_WRAPPERTYPEINFO(); +class CORE_EXPORT EffectModel : public GarbageCollectedFinalized<EffectModel> { public: enum CompositeOperation { CompositeReplace,
diff --git a/third_party/WebKit/Source/core/animation/EffectModel.idl b/third_party/WebKit/Source/core/animation/EffectModel.idl deleted file mode 100644 index 888e02a..0000000 --- a/third_party/WebKit/Source/core/animation/EffectModel.idl +++ /dev/null
@@ -1,14 +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. - -// http://www.w3.org/TR/web-animations/#the-animationeffect-interface - -// TODO(dstockwell): This interface has been removed in the latest spec: -// https://w3c.github.io/web-animations/ - -[ - RuntimeEnabled=WebAnimationsAPI, - NoInterfaceObject, -] interface EffectModel { -};
diff --git a/third_party/WebKit/Source/core/animation/ElementAnimation.h b/third_party/WebKit/Source/core/animation/ElementAnimation.h index ce647b91..4c1ad099 100644 --- a/third_party/WebKit/Source/core/animation/ElementAnimation.h +++ b/third_party/WebKit/Source/core/animation/ElementAnimation.h
@@ -31,7 +31,7 @@ #ifndef ElementAnimation_h #define ElementAnimation_h -#include "bindings/core/v8/EffectModelOrDictionarySequenceOrDictionary.h" +#include "bindings/core/v8/DictionarySequenceOrDictionary.h" #include "core/animation/DocumentTimeline.h" #include "core/animation/EffectInput.h" #include "core/animation/ElementAnimations.h" @@ -50,7 +50,7 @@ class ElementAnimation { STATIC_ONLY(ElementAnimation); public: - static Animation* animate(ExecutionContext* executionContext, Element& element, const EffectModelOrDictionarySequenceOrDictionary& effectInput, double duration, ExceptionState& exceptionState) + static Animation* animate(ExecutionContext* executionContext, Element& element, const DictionarySequenceOrDictionary& effectInput, double duration, ExceptionState& exceptionState) { EffectModel* effect = EffectInput::convert(&element, effectInput, executionContext, exceptionState); if (exceptionState.hadException()) @@ -63,7 +63,7 @@ return animateInternal(element, effect, timing); } - static Animation* animate(ExecutionContext* executionContext, Element& element, const EffectModelOrDictionarySequenceOrDictionary& effectInput, const KeyframeEffectOptions& options, ExceptionState& exceptionState) + static Animation* animate(ExecutionContext* executionContext, Element& element, const DictionarySequenceOrDictionary& effectInput, const KeyframeEffectOptions& options, ExceptionState& exceptionState) { EffectModel* effect = EffectInput::convert(&element, effectInput, executionContext, exceptionState); if (exceptionState.hadException()) @@ -78,7 +78,7 @@ return animation; } - static Animation* animate(ExecutionContext* executionContext, Element& element, const EffectModelOrDictionarySequenceOrDictionary& effectInput, ExceptionState& exceptionState) + static Animation* animate(ExecutionContext* executionContext, Element& element, const DictionarySequenceOrDictionary& effectInput, ExceptionState& exceptionState) { EffectModel* effect = EffectInput::convert(&element, effectInput, executionContext, exceptionState); if (exceptionState.hadException())
diff --git a/third_party/WebKit/Source/core/animation/ElementAnimation.idl b/third_party/WebKit/Source/core/animation/ElementAnimation.idl index ba43f66..3c5e42ba 100644 --- a/third_party/WebKit/Source/core/animation/ElementAnimation.idl +++ b/third_party/WebKit/Source/core/animation/ElementAnimation.idl
@@ -37,8 +37,8 @@ partial interface Element { // FIXME: Union types with dictionary type members doesn't work (yet). - // Animation animate((EffectModel or sequence<Dictionary> or Dictionary)? effect, optional (double or KeyframeEffectOptions) timing); - [CallWith=ExecutionContext, Measure, RaisesException] Animation animate((EffectModel or sequence<Dictionary> or Dictionary)? effect, optional double timing); - [CallWith=ExecutionContext, Measure, RaisesException] Animation animate((EffectModel or sequence<Dictionary> or Dictionary)? effect, KeyframeEffectOptions timing); + // Animation animate((sequence<Dictionary> or Dictionary)? effect, optional (double or KeyframeEffectOptions) timing); + [CallWith=ExecutionContext, Measure, RaisesException] Animation animate((sequence<Dictionary> or Dictionary)? effect, optional double timing); + [CallWith=ExecutionContext, Measure, RaisesException] Animation animate((sequence<Dictionary> or Dictionary)? effect, KeyframeEffectOptions timing); [RuntimeEnabled=WebAnimationsAPI] sequence<Animation> getAnimations(); };
diff --git a/third_party/WebKit/Source/core/animation/InterpolationEffect.cpp b/third_party/WebKit/Source/core/animation/InterpolationEffect.cpp index c6658cd1..7f30243 100644 --- a/third_party/WebKit/Source/core/animation/InterpolationEffect.cpp +++ b/third_party/WebKit/Source/core/animation/InterpolationEffect.cpp
@@ -4,6 +4,8 @@ #include "core/animation/InterpolationEffect.h" +#include "platform/animation/AnimationUtilities.h" + namespace blink { void InterpolationEffect::getActiveInterpolations(double fraction, double iterationDuration, Vector<RefPtr<Interpolation>>& result) const
diff --git a/third_party/WebKit/Source/core/animation/KeyframeEffect.cpp b/third_party/WebKit/Source/core/animation/KeyframeEffect.cpp index 5d480ed..b5982907 100644 --- a/third_party/WebKit/Source/core/animation/KeyframeEffect.cpp +++ b/third_party/WebKit/Source/core/animation/KeyframeEffect.cpp
@@ -53,7 +53,7 @@ return new KeyframeEffect(target, model, timing, priority, eventDelegate); } -KeyframeEffect* KeyframeEffect::create(ExecutionContext* executionContext, Element* element, const EffectModelOrDictionarySequenceOrDictionary& effectInput, double duration, ExceptionState& exceptionState) +KeyframeEffect* KeyframeEffect::create(ExecutionContext* executionContext, Element* element, const DictionarySequenceOrDictionary& effectInput, double duration, ExceptionState& exceptionState) { ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled()); if (element) @@ -64,7 +64,7 @@ return create(element, EffectInput::convert(element, effectInput, executionContext, exceptionState), timing); } -KeyframeEffect* KeyframeEffect::create(ExecutionContext* executionContext, Element* element, const EffectModelOrDictionarySequenceOrDictionary& effectInput, const KeyframeEffectOptions& timingInput, ExceptionState& exceptionState) +KeyframeEffect* KeyframeEffect::create(ExecutionContext* executionContext, Element* element, const DictionarySequenceOrDictionary& effectInput, const KeyframeEffectOptions& timingInput, ExceptionState& exceptionState) { ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled()); if (element) @@ -76,7 +76,7 @@ return create(element, EffectInput::convert(element, effectInput, executionContext, exceptionState), timing); } -KeyframeEffect* KeyframeEffect::create(ExecutionContext* executionContext, Element* element, const EffectModelOrDictionarySequenceOrDictionary& effectInput, ExceptionState& exceptionState) +KeyframeEffect* KeyframeEffect::create(ExecutionContext* executionContext, Element* element, const DictionarySequenceOrDictionary& effectInput, ExceptionState& exceptionState) { ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled()); if (element)
diff --git a/third_party/WebKit/Source/core/animation/KeyframeEffect.h b/third_party/WebKit/Source/core/animation/KeyframeEffect.h index a17002ed..debc5b65 100644 --- a/third_party/WebKit/Source/core/animation/KeyframeEffect.h +++ b/third_party/WebKit/Source/core/animation/KeyframeEffect.h
@@ -57,9 +57,9 @@ static KeyframeEffect* create(Element*, EffectModel*, const Timing&, Priority = DefaultPriority, EventDelegate* = nullptr); // Web Animations API Bindings constructors. - static KeyframeEffect* create(ExecutionContext*, Element*, const EffectModelOrDictionarySequenceOrDictionary& effectInput, double duration, ExceptionState&); - static KeyframeEffect* create(ExecutionContext*, Element*, const EffectModelOrDictionarySequenceOrDictionary& effectInput, const KeyframeEffectOptions& timingInput, ExceptionState&); - static KeyframeEffect* create(ExecutionContext*, Element*, const EffectModelOrDictionarySequenceOrDictionary& effectInput, ExceptionState&); + static KeyframeEffect* create(ExecutionContext*, Element*, const DictionarySequenceOrDictionary& effectInput, double duration, ExceptionState&); + static KeyframeEffect* create(ExecutionContext*, Element*, const DictionarySequenceOrDictionary& effectInput, const KeyframeEffectOptions& timingInput, ExceptionState&); + static KeyframeEffect* create(ExecutionContext*, Element*, const DictionarySequenceOrDictionary& effectInput, ExceptionState&); ~KeyframeEffect() override;
diff --git a/third_party/WebKit/Source/core/animation/KeyframeEffect.idl b/third_party/WebKit/Source/core/animation/KeyframeEffect.idl index 37a6112..99b6eaf 100644 --- a/third_party/WebKit/Source/core/animation/KeyframeEffect.idl +++ b/third_party/WebKit/Source/core/animation/KeyframeEffect.idl
@@ -32,8 +32,8 @@ [ // TODO(dstockwell): the third argument should be "optional (unrestricted double or KeyframeEffectOptions) timing". - Constructor(Element? target, (EffectModel or sequence<Dictionary> or Dictionary)? effect, optional unrestricted double timing), - Constructor(Element? target, (EffectModel or sequence<Dictionary> or Dictionary)? effect, KeyframeEffectOptions timing), + Constructor(Element? target, (sequence<Dictionary> or Dictionary)? effect, optional unrestricted double timing), + Constructor(Element? target, (sequence<Dictionary> or Dictionary)? effect, KeyframeEffectOptions timing), ConstructorCallWith=ExecutionContext, RaisesException=Constructor, RuntimeEnabled=WebAnimationsAPI,
diff --git a/third_party/WebKit/Source/core/animation/KeyframeEffectTest.cpp b/third_party/WebKit/Source/core/animation/KeyframeEffectTest.cpp index c38f847..55e2ae69 100644 --- a/third_party/WebKit/Source/core/animation/KeyframeEffectTest.cpp +++ b/third_party/WebKit/Source/core/animation/KeyframeEffectTest.cpp
@@ -5,7 +5,7 @@ #include "core/animation/KeyframeEffect.h" #include "bindings/core/v8/Dictionary.h" -#include "bindings/core/v8/EffectModelOrDictionarySequenceOrDictionary.h" +#include "bindings/core/v8/DictionarySequenceOrDictionary.h" #include "bindings/core/v8/V8BindingForTesting.h" #include "bindings/core/v8/V8KeyframeEffectOptions.h" #include "core/animation/AnimationClock.h" @@ -46,11 +46,11 @@ template<typename T> static KeyframeEffect* createAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector, T timingInput, ExceptionState& exceptionState) { - return KeyframeEffect::create(nullptr, element, EffectModelOrDictionarySequenceOrDictionary::fromDictionarySequence(keyframeDictionaryVector), timingInput, exceptionState); + return KeyframeEffect::create(nullptr, element, DictionarySequenceOrDictionary::fromDictionarySequence(keyframeDictionaryVector), timingInput, exceptionState); } static KeyframeEffect* createAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector, ExceptionState& exceptionState) { - return KeyframeEffect::create(nullptr, element, EffectModelOrDictionarySequenceOrDictionary::fromDictionarySequence(keyframeDictionaryVector), exceptionState); + return KeyframeEffect::create(nullptr, element, DictionarySequenceOrDictionary::fromDictionarySequence(keyframeDictionaryVector), exceptionState); } }; @@ -127,7 +127,6 @@ setV8ObjectPropertyAsString(scope.isolate(), timingInput, "fill", "backwards"); setV8ObjectPropertyAsNumber(scope.isolate(), timingInput, "iterationStart", 2); setV8ObjectPropertyAsNumber(scope.isolate(), timingInput, "iterations", 10); - setV8ObjectPropertyAsNumber(scope.isolate(), timingInput, "playbackRate", 2); setV8ObjectPropertyAsString(scope.isolate(), timingInput, "direction", "reverse"); setV8ObjectPropertyAsString(scope.isolate(), timingInput, "easing", "step-start"); KeyframeEffectOptions timingInputDictionary; @@ -141,7 +140,6 @@ EXPECT_EQ("backwards", specified->fill()); EXPECT_EQ(2, specified->iterationStart()); EXPECT_EQ(10, specified->iterations()); - EXPECT_EQ(2, specified->playbackRate()); EXPECT_EQ("reverse", specified->direction()); EXPECT_EQ("step-start", specified->easing()); }
diff --git a/third_party/WebKit/Source/core/animation/StringKeyframe.cpp b/third_party/WebKit/Source/core/animation/StringKeyframe.cpp index 1c08669..d8b72b9 100644 --- a/third_party/WebKit/Source/core/animation/StringKeyframe.cpp +++ b/third_party/WebKit/Source/core/animation/StringKeyframe.cpp
@@ -33,7 +33,7 @@ { ASSERT(property != CSSPropertyInvalid); ASSERT(CSSAnimations::isAnimatableProperty(property)); - m_cssPropertyMap->setProperty(property, &value, false); + m_cssPropertyMap->setProperty(property, value, false); } void StringKeyframe::setPresentationAttributeValue(CSSPropertyID property, const String& value, Element* element, StyleSheetContents* styleSheetContents)
diff --git a/third_party/WebKit/Source/core/animation/Timing.h b/third_party/WebKit/Source/core/animation/Timing.h index 14ae79a5..5751966 100644 --- a/third_party/WebKit/Source/core/animation/Timing.h +++ b/third_party/WebKit/Source/core/animation/Timing.h
@@ -116,6 +116,8 @@ double iterationStart; double iterationCount; double iterationDuration; + + // TODO(crbug.com/630915) Remove playbackRate double playbackRate; PlaybackDirection direction; RefPtr<TimingFunction> timingFunction;
diff --git a/third_party/WebKit/Source/core/animation/TimingInput.cpp b/third_party/WebKit/Source/core/animation/TimingInput.cpp index e8f197e..910a78b 100644 --- a/third_party/WebKit/Source/core/animation/TimingInput.cpp +++ b/third_party/WebKit/Source/core/animation/TimingInput.cpp
@@ -130,7 +130,7 @@ if (!setIterationDuration(timingOutput, timingInput.duration(), exceptionState)) return false; - setPlaybackRate(timingOutput, timingInput.playbackRate()); + setPlaybackRate(timingOutput, 1.0); setPlaybackDirection(timingOutput, timingInput.direction()); if (!setTimingFunction(timingOutput, timingInput.easing(), document, exceptionState))
diff --git a/third_party/WebKit/Source/core/animation/TimingInputTest.cpp b/third_party/WebKit/Source/core/animation/TimingInputTest.cpp index 694aa3d..fa3dbde 100644 --- a/third_party/WebKit/Source/core/animation/TimingInputTest.cpp +++ b/third_party/WebKit/Source/core/animation/TimingInputTest.cpp
@@ -155,18 +155,6 @@ EXPECT_FALSE(success); } -TEST(AnimationTimingInputTest, TimingInputPlaybackRate) -{ - V8TestingScope scope; - bool ignoredSuccess; - EXPECT_EQ(2.1, applyTimingInputNumber(scope.isolate(), "playbackRate", 2.1, ignoredSuccess).playbackRate); - EXPECT_EQ(-1, applyTimingInputNumber(scope.isolate(), "playbackRate", -1, ignoredSuccess).playbackRate); - EXPECT_EQ(1, applyTimingInputString(scope.isolate(), "playbackRate", "Infinity", ignoredSuccess).playbackRate); - EXPECT_EQ(1, applyTimingInputString(scope.isolate(), "playbackRate", "-Infinity", ignoredSuccess).playbackRate); - EXPECT_EQ(1, applyTimingInputString(scope.isolate(), "playbackRate", "NaN", ignoredSuccess).playbackRate); - EXPECT_EQ(1, applyTimingInputString(scope.isolate(), "playbackRate", "rubbish", ignoredSuccess).playbackRate); -} - TEST(AnimationTimingInputTest, TimingInputDirection) { V8TestingScope scope;
diff --git a/third_party/WebKit/Source/core/core.gypi b/third_party/WebKit/Source/core/core.gypi index 83cbac15..cb40f8f 100644 --- a/third_party/WebKit/Source/core/core.gypi +++ b/third_party/WebKit/Source/core/core.gypi
@@ -6,7 +6,6 @@ # Files for which bindings (.cpp and .h files) will be generated 'core_idl_files': [ 'animation/KeyframeEffect.idl', - 'animation/EffectModel.idl', 'animation/AnimationEffectReadOnly.idl', 'animation/AnimationEffectTiming.idl', 'animation/Animation.idl', @@ -42,6 +41,7 @@ 'css/WebKitCSSMatrix.idl', 'css/cssom/CSSAngleValue.idl', 'css/cssom/CSSCalcLength.idl', + 'css/cssom/CSSImageValue.idl', 'css/cssom/CSSKeywordValue.idl', 'css/cssom/CSSLengthValue.idl', 'css/cssom/CSSMatrixTransformComponent.idl', @@ -546,17 +546,21 @@ 'layout/ng/ng_block_layout_algorithm.h', 'layout/ng/ng_box.cc', 'layout/ng/ng_box.h', + 'layout/ng/ng_box_iterator.cc', + 'layout/ng/ng_box_iterator.h', 'layout/ng/ng_constraint_space.cc', 'layout/ng/ng_constraint_space.h', + 'layout/ng/ng_derived_constraint_space.h', 'layout/ng/ng_fragment_base.cc', 'layout/ng/ng_fragment_base.h', 'layout/ng/ng_fragment.cc', 'layout/ng/ng_fragment.h', + 'layout/ng/ng_layout_input_text.h', 'layout/ng/ng_length_utils.cc', 'layout/ng/ng_length_utils.h', 'layout/ng/ng_margin_strut.h', - 'layout/ng/ng_text.cc', - 'layout/ng/ng_text.h', + 'layout/ng/ng_text_fragment.cc', + 'layout/ng/ng_text_fragment.h', 'layout/ng/ng_units.h', 'layout/BidiRun.h', 'layout/BidiRunForLine.cpp', @@ -1379,6 +1383,8 @@ 'css/cssom/CSSSimpleLength.h', 'css/cssom/CSSSkew.cpp', 'css/cssom/CSSSkew.h', + 'css/cssom/CSSStyleImageValue.cpp', + 'css/cssom/CSSStyleImageValue.h', 'css/cssom/CSSStyleValue.cpp', 'css/cssom/CSSStyleValue.h', 'css/cssom/CSSStyleVariableReferenceValue.h', @@ -1711,6 +1717,7 @@ 'fetch/ResourceLoaderOptions.h', 'fetch/ResourceLoaderSet.cpp', 'fetch/ResourceLoaderSet.h', + 'fetch/ResourceLoadingLog.h', 'fetch/ScriptResource.cpp', 'fetch/ScriptResource.h', 'fetch/SubstituteData.h', @@ -1919,8 +1926,6 @@ 'inspector/WorkerInspectorController.h', 'inspector/WorkerThreadDebugger.cpp', 'inspector/WorkerThreadDebugger.h', - 'loader/BeaconLoader.cpp', - 'loader/BeaconLoader.h', 'loader/CookieJar.cpp', 'loader/CrossOriginPreflightResultCache.cpp', 'loader/DocumentLoadTiming.cpp', @@ -1969,7 +1974,6 @@ 'loader/TextTrackLoader.h', 'loader/ThreadableLoader.cpp', 'loader/ThreadableLoaderClient.h', - 'loader/ThreadableLoaderClientWrapper.h', 'loader/WorkerThreadableLoader.cpp', 'loader/WorkerThreadableLoader.h', 'loader/appcache/ApplicationCache.cpp', @@ -2051,6 +2055,8 @@ 'page/scrolling/ViewportScrollCallback.h', 'paint/BackgroundImageGeometry.cpp', 'paint/BackgroundImageGeometry.h', + 'paint/BlockFlowPaintInvalidator.cpp', + 'paint/BlockFlowPaintInvalidator.h', 'paint/BlockFlowPainter.cpp', 'paint/BlockFlowPainter.h', 'paint/BlockPainter.cpp', @@ -2061,6 +2067,8 @@ 'paint/BoxClipper.h', 'paint/BoxDecorationData.cpp', 'paint/BoxDecorationData.h', + 'paint/BoxPaintInvalidator.cpp', + 'paint/BoxPaintInvalidator.h', 'paint/BoxPainter.cpp', 'paint/BoxPainter.h', 'paint/BoxReflectionUtils.cpp', @@ -2079,6 +2087,8 @@ 'paint/FilterEffectBuilder.h', 'paint/FilterPainter.cpp', 'paint/FilterPainter.h', + 'paint/FirstMeaningfulPaintDetector.cpp', + 'paint/FirstMeaningfulPaintDetector.h', 'paint/FloatClipRecorder.cpp', 'paint/FloatClipRecorder.h', 'paint/FramePainter.cpp', @@ -2087,6 +2097,8 @@ 'paint/FrameSetPainter.h', 'paint/GridPainter.cpp', 'paint/GridPainter.h', + 'paint/HTMLCanvasPaintInvalidator.cpp', + 'paint/HTMLCanvasPaintInvalidator.h', 'paint/HTMLCanvasPainter.cpp', 'paint/HTMLCanvasPainter.h', 'paint/ImagePainter.cpp', @@ -2115,6 +2127,8 @@ 'paint/NinePieceImagePainter.cpp', 'paint/NinePieceImagePainter.h', 'paint/ObjectPaintProperties.h', + 'paint/ObjectPaintInvalidator.cpp', + 'paint/ObjectPaintInvalidator.h', 'paint/ObjectPainter.cpp', 'paint/ObjectPainter.h', 'paint/PaintInfo.cpp', @@ -2171,6 +2185,8 @@ 'paint/SVGInlineTextBoxPainter.h', 'paint/SVGMaskPainter.cpp', 'paint/SVGMaskPainter.h', + 'paint/SVGModelObjectPaintInvalidator.cpp', + 'paint/SVGModelObjectPaintInvalidator.h', 'paint/SVGPaintContext.cpp', 'paint/SVGPaintContext.h', 'paint/SVGRootInlineBoxPainter.cpp', @@ -2189,6 +2205,8 @@ 'paint/ScrollRecorder.h', 'paint/TableCellPainter.cpp', 'paint/TableCellPainter.h', + 'paint/TablePaintInvalidator.cpp', + 'paint/TablePaintInvalidator.h', 'paint/TablePainter.cpp', 'paint/TablePainter.h', 'paint/TableRowPainter.cpp', @@ -4038,6 +4056,7 @@ 'css/RuleSetTest.cpp', 'css/StyleSheetContentsTest.cpp', 'css/cssom/CSSResourceValueTest.cpp', + 'css/cssom/CSSStyleImageValueTest.cpp', 'css/cssom/CSSTokenStreamValueTest.cpp', 'css/cssom/CSSVariableReferenceValueTest.cpp', 'css/cssom/FilteredComputedStylePropertyMapTest.cpp', @@ -4208,6 +4227,7 @@ 'layout/VisualRectMappingTest.cpp', 'layout/compositing/CompositedLayerMappingTest.cpp', 'layout/ng/ng_block_layout_algorithm_test.cc', + 'layout/ng/ng_length_utils_test.cc', 'layout/shapes/BoxShapeTest.cpp', 'layout/svg/LayoutSVGRootTest.cpp', 'loader/DocumentLoadTimingTest.cpp', @@ -4231,6 +4251,7 @@ 'paint/LayerClipRecorderTest.cpp', 'paint/LayoutObjectDrawingRecorderTest.cpp', 'paint/NinePieceImageGridTest.cpp', + 'paint/FirstMeaningfulPaintDetectorTest.cpp', 'paint/PaintControllerPaintTest.cpp', 'paint/PaintControllerPaintTest.h', 'paint/PaintInfoTest.cpp',
diff --git a/third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp b/third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp index 64b5fe37..26bba4bd 100644 --- a/third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp +++ b/third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp
@@ -558,7 +558,7 @@ return CSSPrimitiveValue::UnitType::Unknown; } -static String formatNumber(double number, const char* suffix, unsigned suffixLength) +static String formatNumber(double number, const StringView& suffix) { #if OS(WIN) && _MSC_VER < 1900 unsigned oldFormat = _set_output_format(_TWO_DIGIT_EXPONENT); @@ -567,21 +567,10 @@ #if OS(WIN) && _MSC_VER < 1900 _set_output_format(oldFormat); #endif - result.append(suffix, suffixLength); + result.append(suffix); return result; } -template <unsigned characterCount> -ALWAYS_INLINE static String formatNumber(double number, const char (&characters)[characterCount]) -{ - return formatNumber(number, characters, characterCount - 1); -} - -static String formatNumber(double number, const char* characters) -{ - return formatNumber(number, characters, strlen(characters)); -} - const char* CSSPrimitiveValue::unitTypeToString(UnitType type) { switch (type) {
diff --git a/third_party/WebKit/Source/core/css/CSSValue.cpp b/third_party/WebKit/Source/core/css/CSSValue.cpp index d0a7b501..f2b2906 100644 --- a/third_party/WebKit/Source/core/css/CSSValue.cpp +++ b/third_party/WebKit/Source/core/css/CSSValue.cpp
@@ -281,136 +281,6 @@ return String(); } -void CSSValue::destroy() -{ - switch (getClassType()) { - case BasicShapeCircleClass: - delete toCSSBasicShapeCircleValue(this); - return; - case BasicShapeEllipseClass: - delete toCSSBasicShapeEllipseValue(this); - return; - case BasicShapePolygonClass: - delete toCSSBasicShapePolygonValue(this); - return; - case BasicShapeInsetClass: - delete toCSSBasicShapeInsetValue(this); - return; - case BorderImageSliceClass: - delete toCSSBorderImageSliceValue(this); - return; - case ColorClass: - delete toCSSColorValue(this); - return; - case CounterClass: - delete toCSSCounterValue(this); - return; - case CursorImageClass: - delete toCSSCursorImageValue(this); - return; - case FontFaceSrcClass: - delete toCSSFontFaceSrcValue(this); - return; - case FontFamilyClass: - delete toCSSFontFamilyValue(this); - return; - case FontFeatureClass: - delete toCSSFontFeatureValue(this); - return; - case FunctionClass: - delete toCSSFunctionValue(this); - return; - case LinearGradientClass: - delete toCSSLinearGradientValue(this); - return; - case RadialGradientClass: - delete toCSSRadialGradientValue(this); - return; - case CrossfadeClass: - delete toCSSCrossfadeValue(this); - return; - case PaintClass: - delete toCSSPaintValue(this); - return; - case CustomIdentClass: - delete toCSSCustomIdentValue(this); - return; - case ImageClass: - delete toCSSImageValue(this); - return; - case InheritedClass: - delete toCSSInheritedValue(this); - return; - case InitialClass: - delete toCSSInitialValue(this); - return; - case UnsetClass: - delete toCSSUnsetValue(this); - return; - case GridAutoRepeatClass: - delete toCSSGridAutoRepeatValue(this); - return; - case GridLineNamesClass: - delete toCSSGridLineNamesValue(this); - return; - case GridTemplateAreasClass: - delete toCSSGridTemplateAreasValue(this); - return; - case PathClass: - delete toCSSPathValue(this); - return; - case PrimitiveClass: - delete toCSSPrimitiveValue(this); - return; - case QuadClass: - delete toCSSQuadValue(this); - return; - case ReflectClass: - delete toCSSReflectValue(this); - return; - case ShadowClass: - delete toCSSShadowValue(this); - return; - case StringClass: - delete toCSSStringValue(this); - return; - case CubicBezierTimingFunctionClass: - delete toCSSCubicBezierTimingFunctionValue(this); - return; - case StepsTimingFunctionClass: - delete toCSSStepsTimingFunctionValue(this); - return; - case UnicodeRangeClass: - delete toCSSUnicodeRangeValue(this); - return; - case URIClass: - delete toCSSURIValue(this); - return; - case ValuePairClass: - delete toCSSValuePair(this); - return; - case ValueListClass: - delete toCSSValueList(this); - return; - case ImageSetClass: - delete toCSSImageSetValue(this); - return; - case CSSContentDistributionClass: - delete toCSSContentDistributionValue(this); - return; - case VariableReferenceClass: - delete toCSSVariableReferenceValue(this); - return; - case CustomPropertyDeclarationClass: - delete toCSSCustomPropertyDeclaration(this); - return; - case PendingSubstitutionValueClass: - delete toCSSPendingSubstitutionValue(this); - return; - } - ASSERT_NOT_REACHED(); -} - void CSSValue::finalizeGarbageCollectedObject() { switch (getClassType()) {
diff --git a/third_party/WebKit/Source/core/css/CSSValue.h b/third_party/WebKit/Source/core/css/CSSValue.h index b529e27..011851b 100644 --- a/third_party/WebKit/Source/core/css/CSSValue.h +++ b/third_party/WebKit/Source/core/css/CSSValue.h
@@ -196,9 +196,6 @@ // NOTE: This class is non-virtual for memory and performance reasons. // Don't go making it virtual again unless you know exactly what you're doing! -private: - void destroy(); - protected: // The bits in this section are only used by specific subclasses but kept here // to maximize struct packing.
diff --git a/third_party/WebKit/Source/core/css/RuleFeature.cpp b/third_party/WebKit/Source/core/css/RuleFeature.cpp index fa526804..74858be 100644 --- a/third_party/WebKit/Source/core/css/RuleFeature.cpp +++ b/third_party/WebKit/Source/core/css/RuleFeature.cpp
@@ -303,6 +303,9 @@ features.customPseudoElement = true; return true; } + // Returning false for ::before and ::after as they are not used as + // invalidation set features, only used later to generate invalidation sets + // for attributes present in "content: attr(...)" declarations. if (selector.getPseudoType() == CSSSelector::PseudoBefore || selector.getPseudoType() == CSSSelector::PseudoAfter) features.hasBeforeOrAfter = true; return false; @@ -351,6 +354,14 @@ case CSSSelector::PseudoUnresolved: case CSSSelector::PseudoDefined: return &ensurePseudoInvalidationSet(selector.getPseudoType(), type); + case CSSSelector::PseudoFirstOfType: + case CSSSelector::PseudoLastOfType: + case CSSSelector::PseudoOnlyOfType: + case CSSSelector::PseudoNthChild: + case CSSSelector::PseudoNthOfType: + case CSSSelector::PseudoNthLastChild: + case CSSSelector::PseudoNthLastOfType: + return &ensureNthInvalidationSet(); default: break; } @@ -371,9 +382,12 @@ InvalidationSetFeatures features; auto result = extractInvalidationSetFeatures(ruleData.selector(), features, Subject); + features.forceSubtree = result.second == ForceSubtree; if (result.first) { - features.forceSubtree = result.second == ForceSubtree; addFeaturesToInvalidationSets(result.first, features.adjacent ? &features : nullptr, features); + } else if (features.hasNthPseudo) { + DCHECK(m_nthInvalidationSet); + addFeaturesToInvalidationSet(*m_nthInvalidationSet, features); } // If any ::before and ::after rules specify 'content: attr(...)', we @@ -416,8 +430,12 @@ foundFeatures |= extractInvalidationSetFeature(*current, features); // Initialize the entry in the invalidation set map, if supported. if (InvalidationSet* invalidationSet = invalidationSetForSelector(*current, InvalidateDescendants)) { - if (position == Subject) - invalidationSet->setInvalidatesSelf(); + if (position == Subject) { + if (invalidationSet == m_nthInvalidationSet) + features.hasNthPseudo = true; + else + invalidationSet->setInvalidatesSelf(); + } } else { if (requiresSubtreeInvalidation(*current)) { // Fall back to use subtree invalidations, even for features in the @@ -452,6 +470,14 @@ if (current->relation() == CSSSelector::SubSelector) continue; + if (features.hasNthPseudo && position == Subject) { + DCHECK(m_nthInvalidationSet); + if (foundFeatures) + addFeaturesToInvalidationSet(*m_nthInvalidationSet, features); + else + m_nthInvalidationSet->setWholeSubtreeInvalid(); + } + features.treeBoundaryCrossing = current->isShadowSelector(); if (current->relationIsAffectedByPseudoContent()) { features.contentPseudoCrossing = true; @@ -462,7 +488,7 @@ features.maxDirectAdjacentSelectors = 1; return std::make_pair(current->tagHistory(), foundFeatures ? UseFeatures : ForceSubtree); } - return std::make_pair(nullptr, foundFeatures ? UseFeatures : ForceSubtree); + return std::make_pair(nullptr, foundFeatures ? UseFeatures : ForceSubtree); } // Add features extracted from the rightmost compound selector to descendant invalidation @@ -516,7 +542,7 @@ if (InvalidationSet* invalidationSet = invalidationSetForSelector(*current, type)) { if (current->match() != CSSSelector::PseudoClass) universalCompound = false; - if (siblingFeatures) { + if (siblingFeatures && invalidationSet != m_nthInvalidationSet) { SiblingInvalidationSet* siblingInvalidationSet = toSiblingInvalidationSet(invalidationSet); siblingInvalidationSet->updateMaxDirectAdjacentSelectors(siblingFeatures->maxDirectAdjacentSelectors); @@ -698,6 +724,8 @@ ensureInvalidationSet(m_pseudoInvalidationSets, static_cast<CSSSelector::PseudoType>(entry.key), entry.value->type()).combine(*entry.value); if (other.m_universalSiblingInvalidationSet) ensureUniversalSiblingInvalidationSet().combine(*other.m_universalSiblingInvalidationSet); + if (other.m_nthInvalidationSet) + ensureNthInvalidationSet().combine(*other.m_nthInvalidationSet); m_metadata.add(other.m_metadata); @@ -867,6 +895,19 @@ return *m_universalSiblingInvalidationSet; } +void RuleFeatureSet::collectNthInvalidationSet(InvalidationLists& invalidationLists) const +{ + if (m_nthInvalidationSet) + invalidationLists.descendants.append(m_nthInvalidationSet); +} + +DescendantInvalidationSet& RuleFeatureSet::ensureNthInvalidationSet() +{ + if (!m_nthInvalidationSet) + m_nthInvalidationSet = DescendantInvalidationSet::create(); + return *m_nthInvalidationSet; +} + void RuleFeatureSet::addFeaturesToUniversalSiblingInvalidationSet(const InvalidationSetFeatures& siblingFeatures, const InvalidationSetFeatures& descendantFeatures) { SiblingInvalidationSet& universalSet = ensureUniversalSiblingInvalidationSet();
diff --git a/third_party/WebKit/Source/core/css/RuleFeature.h b/third_party/WebKit/Source/core/css/RuleFeature.h index 45926f9..0c80b4d8 100644 --- a/third_party/WebKit/Source/core/css/RuleFeature.h +++ b/third_party/WebKit/Source/core/css/RuleFeature.h
@@ -102,6 +102,7 @@ void collectSiblingInvalidationSetForId(InvalidationLists&, Element&, const AtomicString& id, unsigned minDirectAdjacent) const; void collectSiblingInvalidationSetForAttribute(InvalidationLists&, Element&, const QualifiedName& attributeName, unsigned minDirectAdjacent) const; void collectUniversalSiblingInvalidationSet(InvalidationLists&, unsigned minDirectAdjacent) const; + void collectNthInvalidationSet(InvalidationLists&) const; bool hasIdsInSelectors() const { @@ -141,6 +142,7 @@ InvalidationSet& ensureIdInvalidationSet(const AtomicString& id, InvalidationType); InvalidationSet& ensurePseudoInvalidationSet(CSSSelector::PseudoType, InvalidationType); SiblingInvalidationSet& ensureUniversalSiblingInvalidationSet(); + DescendantInvalidationSet& ensureNthInvalidationSet(); void updateInvalidationSets(const RuleData&); void updateInvalidationSetsForContentAttribute(const RuleData&); @@ -161,6 +163,7 @@ bool forceSubtree = false; bool contentPseudoCrossing = false; bool invalidatesSlotted = false; + bool hasNthPseudo = false; }; static bool extractInvalidationSetFeature(const CSSSelector&, InvalidationSetFeatures&); @@ -182,6 +185,7 @@ InvalidationSetMap m_idInvalidationSets; PseudoTypeInvalidationSetMap m_pseudoInvalidationSets; RefPtr<SiblingInvalidationSet> m_universalSiblingInvalidationSet; + RefPtr<DescendantInvalidationSet> m_nthInvalidationSet; friend class RuleFeatureSetTest; };
diff --git a/third_party/WebKit/Source/core/css/RuleFeatureSetTest.cpp b/third_party/WebKit/Source/core/css/RuleFeatureSetTest.cpp index 1bc908f..4afd7ba6 100644 --- a/third_party/WebKit/Source/core/css/RuleFeatureSetTest.cpp +++ b/third_party/WebKit/Source/core/css/RuleFeatureSetTest.cpp
@@ -114,6 +114,11 @@ m_ruleFeatureSet->collectUniversalSiblingInvalidationSet(invalidationLists, 1); } + void collectNthInvalidationSet(InvalidationLists& invalidationLists) + { + m_ruleFeatureSet->collectNthInvalidationSet(invalidationLists); + } + const HashSet<AtomicString>& classSet(const InvalidationSet& invalidationSet) { return invalidationSet.classSetForTesting(); @@ -151,6 +156,12 @@ EXPECT_FALSE(invalidationSets[0]->invalidatesSelf()); } + void expectWholeSubtreeInvalidation(InvalidationSetVector& invalidationSets) + { + EXPECT_EQ(1u, invalidationSets.size()); + EXPECT_TRUE(invalidationSets[0]->wholeSubtreeInvalid()); + } + void expectClassInvalidation(const AtomicString& className, InvalidationSetVector& invalidationSets) { EXPECT_EQ(1u, invalidationSets.size()); @@ -723,4 +734,138 @@ expectNoInvalidation(invalidationLists.siblings); } +TEST_F(RuleFeatureSetTest, nthInvalidationUniversal) +{ + EXPECT_EQ(RuleFeatureSet::SelectorMayMatch, collectFeatures(":nth-child(2n)")); + + InvalidationLists invalidationLists; + collectNthInvalidationSet(invalidationLists); + + expectNoSelfInvalidation(invalidationLists.descendants); + expectWholeSubtreeInvalidation(invalidationLists.descendants); +} + +TEST_F(RuleFeatureSetTest, nthInvalidationClass) +{ + EXPECT_EQ(RuleFeatureSet::SelectorMayMatch, collectFeatures(".a:nth-child(2n)")); + + InvalidationLists invalidationLists; + collectNthInvalidationSet(invalidationLists); + + expectNoSelfInvalidation(invalidationLists.descendants); + expectClassInvalidation("a", invalidationLists.descendants); +} + +TEST_F(RuleFeatureSetTest, nthInvalidationUniversalDescendant) +{ + EXPECT_EQ(RuleFeatureSet::SelectorMayMatch, collectFeatures(":nth-child(2n) *")); + + InvalidationLists invalidationLists; + collectNthInvalidationSet(invalidationLists); + + expectNoSelfInvalidation(invalidationLists.descendants); + expectWholeSubtreeInvalidation(invalidationLists.descendants); +} + +TEST_F(RuleFeatureSetTest, nthInvalidationDescendant) +{ + EXPECT_EQ(RuleFeatureSet::SelectorMayMatch, collectFeatures(":nth-child(2n) .a")); + + InvalidationLists invalidationLists; + collectNthInvalidationSet(invalidationLists); + + expectNoSelfInvalidation(invalidationLists.descendants); + expectClassInvalidation("a", invalidationLists.descendants); +} + +TEST_F(RuleFeatureSetTest, nthInvalidationSibling) +{ + EXPECT_EQ(RuleFeatureSet::SelectorMayMatch, collectFeatures(":nth-child(2n) + .a")); + + InvalidationLists invalidationLists; + collectNthInvalidationSet(invalidationLists); + + expectNoInvalidation(invalidationLists.siblings); + expectNoSelfInvalidation(invalidationLists.descendants); + expectClassInvalidation("a", invalidationLists.descendants); +} + +TEST_F(RuleFeatureSetTest, nthInvalidationSiblingDescendant) +{ + EXPECT_EQ(RuleFeatureSet::SelectorMayMatch, collectFeatures(":nth-child(2n) + .a .b")); + + InvalidationLists invalidationLists; + collectNthInvalidationSet(invalidationLists); + + expectNoInvalidation(invalidationLists.siblings); + expectNoSelfInvalidation(invalidationLists.descendants); + expectClassInvalidation("b", invalidationLists.descendants); +} + +TEST_F(RuleFeatureSetTest, nthInvalidationNot) +{ + EXPECT_EQ(RuleFeatureSet::SelectorMayMatch, collectFeatures(":not(:nth-child(2n))")); + + InvalidationLists invalidationLists; + collectNthInvalidationSet(invalidationLists); + + expectNoSelfInvalidation(invalidationLists.descendants); + expectWholeSubtreeInvalidation(invalidationLists.descendants); +} + +TEST_F(RuleFeatureSetTest, nthInvalidationNotClass) +{ + EXPECT_EQ(RuleFeatureSet::SelectorMayMatch, collectFeatures(".a:not(:nth-child(2n))")); + + InvalidationLists invalidationLists; + collectNthInvalidationSet(invalidationLists); + + expectNoSelfInvalidation(invalidationLists.descendants); + expectClassInvalidation("a", invalidationLists.descendants); +} + +TEST_F(RuleFeatureSetTest, nthInvalidationNotDescendant) +{ + EXPECT_EQ(RuleFeatureSet::SelectorMayMatch, collectFeatures(".blah:not(:nth-child(2n)) .a")); + + InvalidationLists invalidationLists; + collectNthInvalidationSet(invalidationLists); + + expectNoSelfInvalidation(invalidationLists.descendants); + expectClassInvalidation("a", invalidationLists.descendants); +} + +TEST_F(RuleFeatureSetTest, nthInvalidationAny) +{ + EXPECT_EQ(RuleFeatureSet::SelectorMayMatch, collectFeatures(":-webkit-any(#nomatch, :nth-child(2n))")); + + InvalidationLists invalidationLists; + collectNthInvalidationSet(invalidationLists); + + expectNoSelfInvalidation(invalidationLists.descendants); + expectWholeSubtreeInvalidation(invalidationLists.descendants); +} + +TEST_F(RuleFeatureSetTest, nthInvalidationAnyClass) +{ + EXPECT_EQ(RuleFeatureSet::SelectorMayMatch, collectFeatures(".a:-webkit-any(#nomatch, :nth-child(2n))")); + + InvalidationLists invalidationLists; + collectNthInvalidationSet(invalidationLists); + + expectNoSelfInvalidation(invalidationLists.descendants); + expectClassInvalidation("a", invalidationLists.descendants); +} + +TEST_F(RuleFeatureSetTest, nthInvalidationAnyDescendant) +{ + EXPECT_EQ(RuleFeatureSet::SelectorMayMatch, collectFeatures(".blah:-webkit-any(#nomatch, :nth-child(2n)) .a")); + + InvalidationLists invalidationLists; + collectNthInvalidationSet(invalidationLists); + + expectNoSelfInvalidation(invalidationLists.descendants); + expectClassInvalidation("a", invalidationLists.descendants); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/css/StylePropertySet.cpp b/third_party/WebKit/Source/core/css/StylePropertySet.cpp index a3bcaea4..42c1d08 100644 --- a/third_party/WebKit/Source/core/css/StylePropertySet.cpp +++ b/third_party/WebKit/Source/core/css/StylePropertySet.cpp
@@ -309,18 +309,18 @@ return CSSParser::parseValueForCustomProperty(this, customPropertyName, value, important, contextStyleSheet); } -void MutableStylePropertySet::setProperty(CSSPropertyID propertyID, const CSSValue* value, bool important) +void MutableStylePropertySet::setProperty(CSSPropertyID propertyID, const CSSValue& value, bool important) { StylePropertyShorthand shorthand = shorthandForProperty(propertyID); if (!shorthand.length()) { - setProperty(CSSProperty(propertyID, *value, important)); + setProperty(CSSProperty(propertyID, value, important)); return; } removePropertiesInSet(shorthand.properties(), shorthand.length()); for (unsigned i = 0; i < shorthand.length(); ++i) - m_propertyVector.append(CSSProperty(shorthand.properties()[i], *value, important)); + m_propertyVector.append(CSSProperty(shorthand.properties()[i], value, important)); } bool MutableStylePropertySet::setProperty(const CSSProperty& property, CSSProperty* slot)
diff --git a/third_party/WebKit/Source/core/css/StylePropertySet.h b/third_party/WebKit/Source/core/css/StylePropertySet.h index 264bf320..7d4e19a 100644 --- a/third_party/WebKit/Source/core/css/StylePropertySet.h +++ b/third_party/WebKit/Source/core/css/StylePropertySet.h
@@ -201,8 +201,7 @@ // These expand shorthand properties into multiple properties. bool setProperty(CSSPropertyID unresolvedProperty, const String& value, bool important = false, StyleSheetContents* contextStyleSheet = 0); bool setProperty(const AtomicString& customPropertyName, const String& value, bool important = false, StyleSheetContents* contextStyleSheet = 0); - // TODO(sashab): Make this take a const CSSValue& - void setProperty(CSSPropertyID, const CSSValue*, bool important = false); + void setProperty(CSSPropertyID, const CSSValue&, bool important = false); // These do not. FIXME: This is too messy, we can do better. bool setProperty(CSSPropertyID, CSSValueID identifier, bool important = false);
diff --git a/third_party/WebKit/Source/core/css/StyleRule.cpp b/third_party/WebKit/Source/core/css/StyleRule.cpp index d1d8511..ffc73fe8 100644 --- a/third_party/WebKit/Source/core/css/StyleRule.cpp +++ b/third_party/WebKit/Source/core/css/StyleRule.cpp
@@ -132,46 +132,6 @@ ASSERT_NOT_REACHED(); } -void StyleRuleBase::destroy() -{ - switch (type()) { - case Charset: - delete toStyleRuleCharset(this); - return; - case Style: - delete toStyleRule(this); - return; - case Page: - delete toStyleRulePage(this); - return; - case FontFace: - delete toStyleRuleFontFace(this); - return; - case Media: - delete toStyleRuleMedia(this); - return; - case Supports: - delete toStyleRuleSupports(this); - return; - case Import: - delete toStyleRuleImport(this); - return; - case Keyframes: - delete toStyleRuleKeyframes(this); - return; - case Keyframe: - delete toStyleRuleKeyframe(this); - return; - case Namespace: - delete toStyleRuleNamespace(this); - return; - case Viewport: - delete toStyleRuleViewport(this); - return; - } - ASSERT_NOT_REACHED(); -} - StyleRuleBase* StyleRuleBase::copy() const { switch (type()) {
diff --git a/third_party/WebKit/Source/core/css/StyleRule.h b/third_party/WebKit/Source/core/css/StyleRule.h index 28f7e63..f7098eca 100644 --- a/third_party/WebKit/Source/core/css/StyleRule.h +++ b/third_party/WebKit/Source/core/css/StyleRule.h
@@ -85,8 +85,6 @@ StyleRuleBase(const StyleRuleBase& o) : m_type(o.m_type) { } private: - void destroy(); - CSSRule* createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const; unsigned m_type : 5;
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSImageValue.idl b/third_party/WebKit/Source/core/css/cssom/CSSImageValue.idl new file mode 100644 index 0000000..b0160127 --- /dev/null +++ b/third_party/WebKit/Source/core/css/cssom/CSSImageValue.idl
@@ -0,0 +1,13 @@ +// Copyright 2016 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. + +[ + Exposed=(Window,PaintWorklet), + RuntimeEnabled=CSSTypedOM, + ImplementedAs=CSSStyleImageValue +] interface CSSImageValue : CSSResourceValue { + readonly attribute double? intrinsicWidth; + readonly attribute double? intrinsicHeight; + readonly attribute double? intrinsicRatio; +};
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.cpp b/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.cpp new file mode 100644 index 0000000..3f6a5c0 --- /dev/null +++ b/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.cpp
@@ -0,0 +1,38 @@ +// Copyright 2016 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 "core/css/cssom/CSSStyleImageValue.h" + +namespace blink { + +double CSSStyleImageValue::intrinsicWidth(bool& isNull) +{ + isNull = isCachePending(); + if (isNull) + return 0; + return imageLayoutSize().width().toDouble(); +} + +double CSSStyleImageValue::intrinsicHeight(bool& isNull) +{ + isNull = isCachePending(); + if (isNull) + return 0; + return imageLayoutSize().height().toDouble(); +} + +double CSSStyleImageValue::intrinsicRatio(bool& isNull) +{ + isNull = isCachePending(); + if (isNull) { + return 0; + } + if (intrinsicHeight(isNull) == 0) { + isNull = true; + return 0; + } + return intrinsicWidth(isNull) / intrinsicHeight(isNull); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.h b/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.h new file mode 100644 index 0000000..ccba062 --- /dev/null +++ b/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValue.h
@@ -0,0 +1,61 @@ +// Copyright 2016 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 CSSStyleImageValue_h +#define CSSStyleImageValue_h + +#include "core/css/CSSImageValue.h" +#include "core/css/cssom/CSSResourceValue.h" +#include "core/fetch/ImageResource.h" +#include "core/style/StyleImage.h" + + +namespace blink { + +class CORE_EXPORT CSSStyleImageValue : public CSSResourceValue { + WTF_MAKE_NONCOPYABLE(CSSStyleImageValue); + DEFINE_WRAPPERTYPEINFO(); +public: + virtual ~CSSStyleImageValue() { } + + StyleValueType type() const override { return ImageType; } + + double intrinsicWidth(bool& isNull); + double intrinsicHeight(bool& isNull); + double intrinsicRatio(bool& isNull); + + DEFINE_INLINE_VIRTUAL_TRACE() + { + visitor->trace(m_imageValue); + CSSStyleValue::trace(visitor); + CSSResourceValue::trace(visitor); + } + +protected: + CSSStyleImageValue(const CSSImageValue* imageValue) + : m_imageValue(imageValue) + { + } + + Member<const CSSImageValue> m_imageValue; + + virtual LayoutSize imageLayoutSize() const + { + DCHECK(!m_imageValue->isCachePending()); + return m_imageValue->cachedImage()->cachedImage()->imageSize(DoNotRespectImageOrientation, 1, ImageResource::IntrinsicSize); + } + + virtual bool isCachePending() const { return m_imageValue->isCachePending(); } + + Resource::Status status() const override + { + if (isCachePending()) + return Resource::Status::NotStarted; + return m_imageValue->cachedImage()->cachedImage()->getStatus(); + } +}; + +} // namespace blink + +#endif // CSSResourceValue_h
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValueTest.cpp b/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValueTest.cpp new file mode 100644 index 0000000..efe58c4 --- /dev/null +++ b/third_party/WebKit/Source/core/css/cssom/CSSStyleImageValueTest.cpp
@@ -0,0 +1,54 @@ +// Copyright 2016 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 "core/css/cssom/CSSStyleImageValue.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +namespace { + +class FakeCSSStyleImageValue : public CSSStyleImageValue { +public: + FakeCSSStyleImageValue(CSSImageValue* imageValue, bool cachePending, LayoutSize layoutSize) + : CSSStyleImageValue(imageValue) + , m_cachePending(cachePending) + , m_layoutSize(layoutSize) + { + } + + bool m_cachePending; + LayoutSize m_layoutSize; + + CSSValue* toCSSValue() const override { return nullptr; } + + bool isCachePending() const override { return m_cachePending; } + + LayoutSize imageLayoutSize() const override { return m_layoutSize; } +}; + +TEST(CSSStyleImageValueTest, PendingCache) +{ + FakeCSSStyleImageValue* styleImageValue = new FakeCSSStyleImageValue(CSSImageValue::create(""), true, LayoutSize(100, 100)); + bool isNull; + EXPECT_EQ(styleImageValue->intrinsicWidth(isNull), 0); + EXPECT_EQ(styleImageValue->intrinsicHeight(isNull), 0); + EXPECT_EQ(styleImageValue->intrinsicRatio(isNull), 0); + EXPECT_TRUE(isNull); +} + +TEST(CSSStyleImageValueTest, ValidLoadedImage) +{ + FakeCSSStyleImageValue* styleImageValue = new FakeCSSStyleImageValue(CSSImageValue::create(""), false, LayoutSize(480, 120)); + bool isNull; + EXPECT_EQ(styleImageValue->intrinsicWidth(isNull), 480); + EXPECT_EQ(styleImageValue->intrinsicHeight(isNull), 120); + EXPECT_EQ(styleImageValue->intrinsicRatio(isNull), 4); + EXPECT_FALSE(isNull); +} + +} // namespace + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.h b/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.h index 8e919d7..1dc36c2 100644 --- a/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.h +++ b/third_party/WebKit/Source/core/css/cssom/CSSStyleValue.h
@@ -24,6 +24,7 @@ Unknown, AngleType, CalcLengthType, + ImageType, KeywordType, NumberType, PositionType,
diff --git a/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp b/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp index bdd72536..c53ebee 100644 --- a/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp +++ b/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.cpp
@@ -41,34 +41,34 @@ m_pendingInvalidationMap.clear(); } -void StyleInvalidator::scheduleInvalidationSetsForElement(const InvalidationLists& invalidationLists, Element& element) +void StyleInvalidator::scheduleInvalidationSetsForNode(const InvalidationLists& invalidationLists, ContainerNode& node) { - ASSERT(element.inActiveDocument()); + DCHECK(node.inActiveDocument()); bool requiresDescendantInvalidation = false; - if (element.getStyleChangeType() < SubtreeStyleChange) { + if (node.getStyleChangeType() < SubtreeStyleChange) { for (auto& invalidationSet : invalidationLists.descendants) { if (invalidationSet->wholeSubtreeInvalid()) { - element.setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::StyleInvalidator)); + node.setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::StyleInvalidator)); requiresDescendantInvalidation = false; break; } if (invalidationSet->invalidatesSelf()) - element.setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::StyleInvalidator)); + node.setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::StyleInvalidator)); if (!invalidationSet->isEmpty()) requiresDescendantInvalidation = true; } } - if (!requiresDescendantInvalidation && (invalidationLists.siblings.isEmpty() || !element.nextSibling())) + if (!requiresDescendantInvalidation && (invalidationLists.siblings.isEmpty() || !node.nextSibling())) return; - element.setNeedsStyleInvalidation(); + node.setNeedsStyleInvalidation(); - PendingInvalidations& pendingInvalidations = ensurePendingInvalidations(element); - if (element.nextSibling()) { + PendingInvalidations& pendingInvalidations = ensurePendingInvalidations(node); + if (node.nextSibling()) { for (auto& invalidationSet : invalidationLists.siblings) { if (pendingInvalidations.siblings().contains(invalidationSet)) continue; @@ -80,7 +80,7 @@ return; for (auto& invalidationSet : invalidationLists.descendants) { - ASSERT(!invalidationSet->wholeSubtreeInvalid()); + DCHECK(!invalidationSet->wholeSubtreeInvalid()); if (invalidationSet->isEmpty()) continue; if (pendingInvalidations.descendants().contains(invalidationSet)) @@ -91,6 +91,8 @@ void StyleInvalidator::scheduleSiblingInvalidationsAsDescendants(const InvalidationLists& invalidationLists, ContainerNode& schedulingParent) { + DCHECK(invalidationLists.descendants.isEmpty()); + if (invalidationLists.siblings.isEmpty()) return; @@ -145,9 +147,9 @@ void StyleInvalidator::RecursionData::pushInvalidationSet(const InvalidationSet& invalidationSet) { - ASSERT(!m_wholeSubtreeInvalid); - ASSERT(!invalidationSet.wholeSubtreeInvalid()); - ASSERT(!invalidationSet.isEmpty()); + DCHECK(!m_wholeSubtreeInvalid); + DCHECK(!invalidationSet.wholeSubtreeInvalid()); + DCHECK(!invalidationSet.isEmpty()); if (invalidationSet.treeBoundaryCrossing()) m_treeBoundaryCrossing = true; if (invalidationSet.insertionPointCrossing()) @@ -178,7 +180,7 @@ bool StyleInvalidator::RecursionData::matchesCurrentInvalidationSetsAsSlotted(Element& element) const { - ASSERT(m_invalidatesSlotted); + DCHECK(m_invalidatesSlotted); for (const auto& invalidationSet : m_invalidationSets) { if (!invalidationSet->invalidatesSlotted()) @@ -202,7 +204,7 @@ bool StyleInvalidator::SiblingData::matchCurrentInvalidationSets(Element& element, RecursionData& recursionData) { bool thisElementNeedsStyleRecalc = false; - ASSERT(!recursionData.wholeSubtreeInvalid()); + DCHECK(!recursionData.wholeSubtreeInvalid()); unsigned index = 0; while (index < m_invalidationEntries.size()) { @@ -238,7 +240,7 @@ void StyleInvalidator::pushInvalidationSetsForContainerNode(ContainerNode& node, RecursionData& recursionData, SiblingData& siblingData) { PendingInvalidations* pendingInvalidations = m_pendingInvalidationMap.get(&node); - ASSERT(pendingInvalidations); + DCHECK(pendingInvalidations); for (const auto& invalidationSet : pendingInvalidations->siblings()) siblingData.pushInvalidationSet(toSiblingInvalidationSet(*invalidationSet)); @@ -325,7 +327,7 @@ someChildrenNeedStyleRecalc = invalidateChildren(element, recursionData); if (thisElementNeedsStyleRecalc) { - ASSERT(!recursionData.wholeSubtreeInvalid()); + DCHECK(!recursionData.wholeSubtreeInvalid()); element.setNeedsStyleRecalc(LocalStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::StyleInvalidator)); } else if (recursionData.hasInvalidationSets() && someChildrenNeedStyleRecalc) { // Clone the ComputedStyle in order to preserve correct style sharing, if possible. Otherwise recalc style.
diff --git a/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h b/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h index 9008c15..70e6cbeb 100644 --- a/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h +++ b/third_party/WebKit/Source/core/css/invalidation/StyleInvalidator.h
@@ -26,7 +26,7 @@ StyleInvalidator(); ~StyleInvalidator(); void invalidate(Document&); - void scheduleInvalidationSetsForElement(const InvalidationLists&, Element&); + void scheduleInvalidationSetsForNode(const InvalidationLists&, ContainerNode&); void scheduleSiblingInvalidationsAsDescendants(const InvalidationLists&, ContainerNode& schedulingParent); void clearInvalidation(ContainerNode&);
diff --git a/third_party/WebKit/Source/core/css/parser/CSSParserFastPaths.cpp b/third_party/WebKit/Source/core/css/parser/CSSParserFastPaths.cpp index 1bb13ac6a..33d9aa8 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSParserFastPaths.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSParserFastPaths.cpp
@@ -538,7 +538,7 @@ case CSSPropertyFontStretch: // normal | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded return valueID == CSSValueNormal || (valueID >= CSSValueUltraCondensed && valueID <= CSSValueUltraExpanded); case CSSPropertyImageRendering: // auto | optimizeContrast | pixelated - return valueID == CSSValueAuto || valueID == CSSValueWebkitOptimizeContrast || (RuntimeEnabledFeatures::imageRenderingPixelatedEnabled() && valueID == CSSValuePixelated); + return valueID == CSSValueAuto || valueID == CSSValueWebkitOptimizeContrast || valueID == CSSValuePixelated; case CSSPropertyIsolation: // auto | isolate return valueID == CSSValueAuto || valueID == CSSValueIsolate; case CSSPropertyListStylePosition: // inside | outside
diff --git a/third_party/WebKit/Source/core/dom/ContainerNode.cpp b/third_party/WebKit/Source/core/dom/ContainerNode.cpp index 56e6d7f..f995b38 100644 --- a/third_party/WebKit/Source/core/dom/ContainerNode.cpp +++ b/third_party/WebKit/Source/core/dom/ContainerNode.cpp
@@ -1232,22 +1232,16 @@ Element* elementAfterChange = !nodeAfterChange || nodeAfterChange->isElementNode() ? toElement(nodeAfterChange) : ElementTraversal::nextSibling(*nodeAfterChange); Element* elementBeforeChange = !nodeBeforeChange || nodeBeforeChange->isElementNode() ? toElement(nodeBeforeChange) : ElementTraversal::previousSibling(*nodeBeforeChange); + // TODO(rune@opera.com): move this code into StyleEngine and collect the + // various invalidation sets into a single InvalidationLists object and + // schedule with a single scheduleInvalidationSetsForNode for efficiency. + // Forward positional selectors include :nth-child, :nth-of-type, - // :first-of-type, and only-of-type. The indirect adjacent selector is the ~ - // selector. Backward positional selectors include :nth-last-child, - // :nth-last-of-type, :last-of-type, and :only-of-type. We have to - // invalidate everything following the insertion point in the forward and - // indirect adjacent case, and everything before the insertion point in the - // backward case. |nodeAfterChange| is nullptr in the parser callback case, - // so we won't do any work for the forward case if we don't have to. - // For performance reasons we just mark the parent node as changed, since we - // don't want to make childrenChanged O(n^2) by crawling all our kids here. - // recalcStyle will then force a walk of the children when it sees that this - // has happened. + // :first-of-type, and only-of-type. Backward positional selectors include + // :nth-last-child, :nth-last-of-type, :last-of-type, and :only-of-type. if ((childrenAffectedByForwardPositionalRules() && elementAfterChange) || (childrenAffectedByBackwardPositionalRules() && elementBeforeChange)) { - setNeedsStyleRecalc(SubtreeStyleChange, StyleChangeReasonForTracing::create(StyleChangeReason::SiblingSelector)); - return; + document().styleEngine().scheduleNthPseudoInvalidations(*this); } if (childrenAffectedByFirstChildRules() && !elementBeforeChange && elementAfterChange && elementAfterChange->affectedByFirstChildRules()) {
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp index 749d9d1..8ba679e 100644 --- a/third_party/WebKit/Source/core/dom/Document.cpp +++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -220,7 +220,6 @@ #include "platform/Histogram.h" #include "platform/Language.h" #include "platform/LengthFunctions.h" -#include "platform/Logging.h" #include "platform/PluginScriptForbiddenScope.h" #include "platform/RuntimeEnabledFeatures.h" #include "platform/ScriptForbiddenScope.h"
diff --git a/third_party/WebKit/Source/core/dom/DocumentTiming.cpp b/third_party/WebKit/Source/core/dom/DocumentTiming.cpp index ae2448d..2b9a1571 100644 --- a/third_party/WebKit/Source/core/dom/DocumentTiming.cpp +++ b/third_party/WebKit/Source/core/dom/DocumentTiming.cpp
@@ -34,42 +34,42 @@ void DocumentTiming::markDomLoading() { m_domLoading = monotonicallyIncreasingTime(); - TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing", "domLoading", m_domLoading, "frame", frame()); + TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing,rail", "domLoading", m_domLoading, "frame", frame()); notifyDocumentTimingChanged(); } void DocumentTiming::markDomInteractive() { m_domInteractive = monotonicallyIncreasingTime(); - TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing", "domInteractive", m_domInteractive, "frame", frame()); + TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing,rail", "domInteractive", m_domInteractive, "frame", frame()); notifyDocumentTimingChanged(); } void DocumentTiming::markDomContentLoadedEventStart() { m_domContentLoadedEventStart = monotonicallyIncreasingTime(); - TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing", "domContentLoadedEventStart", m_domContentLoadedEventStart, "frame", frame()); + TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing,rail", "domContentLoadedEventStart", m_domContentLoadedEventStart, "frame", frame()); notifyDocumentTimingChanged(); } void DocumentTiming::markDomContentLoadedEventEnd() { m_domContentLoadedEventEnd = monotonicallyIncreasingTime(); - TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing", "domContentLoadedEventEnd", m_domContentLoadedEventEnd, "frame", frame()); + TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing,rail", "domContentLoadedEventEnd", m_domContentLoadedEventEnd, "frame", frame()); notifyDocumentTimingChanged(); } void DocumentTiming::markDomComplete() { m_domComplete = monotonicallyIncreasingTime(); - TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing", "domComplete", m_domComplete, "frame", frame()); + TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing,rail", "domComplete", m_domComplete, "frame", frame()); notifyDocumentTimingChanged(); } void DocumentTiming::markFirstLayout() { m_firstLayout = monotonicallyIncreasingTime(); - TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing", "firstLayout", m_firstLayout, "frame", frame()); + TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing,rail", "firstLayout", m_firstLayout, "frame", frame()); notifyDocumentTimingChanged(); }
diff --git a/third_party/WebKit/Source/core/dom/Element.cpp b/third_party/WebKit/Source/core/dom/Element.cpp index 66d497b9..881fc63a 100644 --- a/third_party/WebKit/Source/core/dom/Element.cpp +++ b/third_party/WebKit/Source/core/dom/Element.cpp
@@ -3637,7 +3637,7 @@ void Element::setInlineStyleProperty(CSSPropertyID propertyID, const CSSValue* value, bool important) { DCHECK(isStyledElement()); - ensureMutableInlineStyle().setProperty(propertyID, value, important); + ensureMutableInlineStyle().setProperty(propertyID, *value, important); inlineStyleChanged(); } @@ -3682,13 +3682,13 @@ void Element::addPropertyToPresentationAttributeStyle(MutableStylePropertySet* style, CSSPropertyID propertyID, CSSValueID identifier) { DCHECK(isStyledElement()); - style->setProperty(propertyID, CSSPrimitiveValue::createIdentifier(identifier)); + style->setProperty(propertyID, *CSSPrimitiveValue::createIdentifier(identifier)); } void Element::addPropertyToPresentationAttributeStyle(MutableStylePropertySet* style, CSSPropertyID propertyID, double value, CSSPrimitiveValue::UnitType unit) { DCHECK(isStyledElement()); - style->setProperty(propertyID, CSSPrimitiveValue::create(value, unit)); + style->setProperty(propertyID, *CSSPrimitiveValue::create(value, unit)); } void Element::addPropertyToPresentationAttributeStyle(MutableStylePropertySet* style, CSSPropertyID propertyID, const String& value) @@ -3700,7 +3700,7 @@ void Element::addPropertyToPresentationAttributeStyle(MutableStylePropertySet* style, CSSPropertyID propertyID, const CSSValue* value) { DCHECK(isStyledElement()); - style->setProperty(propertyID, value); + style->setProperty(propertyID, *value); } bool Element::supportsStyleSharing() const
diff --git a/third_party/WebKit/Source/core/dom/Element.h b/third_party/WebKit/Source/core/dom/Element.h index bf54f522..44adfa1e 100644 --- a/third_party/WebKit/Source/core/dom/Element.h +++ b/third_party/WebKit/Source/core/dom/Element.h
@@ -290,6 +290,7 @@ void setInlineStyleProperty(CSSPropertyID, CSSValueID identifier, bool important = false); void setInlineStyleProperty(CSSPropertyID, double value, CSSPrimitiveValue::UnitType, bool important = false); + // TODO(sashab): Make this take a const CSSValue&. void setInlineStyleProperty(CSSPropertyID, const CSSValue*, bool important = false); bool setInlineStyleProperty(CSSPropertyID, const String& value, bool important = false); @@ -601,6 +602,7 @@ void addPropertyToPresentationAttributeStyle(MutableStylePropertySet*, CSSPropertyID, CSSValueID identifier); void addPropertyToPresentationAttributeStyle(MutableStylePropertySet*, CSSPropertyID, double value, CSSPrimitiveValue::UnitType); void addPropertyToPresentationAttributeStyle(MutableStylePropertySet*, CSSPropertyID, const String& value); + // TODO(sashab): Make this take a const CSSValue&. void addPropertyToPresentationAttributeStyle(MutableStylePropertySet*, CSSPropertyID, const CSSValue*); InsertionNotificationRequest insertedInto(ContainerNode*) override;
diff --git a/third_party/WebKit/Source/core/dom/ElementVisibilityObserver.cpp b/third_party/WebKit/Source/core/dom/ElementVisibilityObserver.cpp index 6c6de4357..05f57138 100644 --- a/third_party/WebKit/Source/core/dom/ElementVisibilityObserver.cpp +++ b/third_party/WebKit/Source/core/dom/ElementVisibilityObserver.cpp
@@ -4,41 +4,28 @@ #include "core/dom/ElementVisibilityObserver.h" -#include "bindings/core/v8/ExceptionState.h" #include "core/dom/Element.h" -#include "core/dom/IntersectionObserver.h" #include "core/dom/IntersectionObserverEntry.h" -#include "core/dom/IntersectionObserverInit.h" #include "wtf/Functional.h" namespace blink { -ElementVisibilityObserver* ElementVisibilityObserver::create(Element* element, Client* client) +ElementVisibilityObserver::ElementVisibilityObserver(Element* element, std::unique_ptr<VisibilityCallback> callback) + : m_element(element) + , m_callback(std::move(callback)) { - ElementVisibilityObserver* observer = new ElementVisibilityObserver(client); - observer->start(element); - return observer; -} - -ElementVisibilityObserver::ElementVisibilityObserver(Client* client) - : m_client(client) -{ - DCHECK(m_client); } ElementVisibilityObserver::~ElementVisibilityObserver() = default; -void ElementVisibilityObserver::start(Element* element) +void ElementVisibilityObserver::start() { - IntersectionObserverInit options; - DoubleOrDoubleArray threshold; - threshold.setDouble(std::numeric_limits<float>::min()); - options.setThreshold(threshold); - DCHECK(!m_intersectionObserver); - m_intersectionObserver = IntersectionObserver::create(options, *this, ASSERT_NO_EXCEPTION); + m_intersectionObserver = IntersectionObserver::create( + Vector<Length>(), Vector<float>({std::numeric_limits<float>::min()}), &m_element->document(), + WTF::bind(&ElementVisibilityObserver::onVisibilityChanged, wrapWeakPersistent(this))); DCHECK(m_intersectionObserver); - m_intersectionObserver->observe(element); + m_intersectionObserver->observe(m_element.release()); } void ElementVisibilityObserver::stop() @@ -47,30 +34,18 @@ m_intersectionObserver->disconnect(); m_intersectionObserver = nullptr; - // Client will no longer be called upon, release. - m_client = nullptr; -} - -void ElementVisibilityObserver::handleEvent(const HeapVector<Member<IntersectionObserverEntry>>& entries, IntersectionObserver&) -{ - if (!m_client) - return; - bool isVisible = entries.last()->intersectionRatio() > 0.f; - m_client->onVisibilityChanged(isVisible); -} - -ExecutionContext* ElementVisibilityObserver::getExecutionContext() const -{ - if (!m_client) - return nullptr; - return m_client->getElementVisibilityExecutionContext(); } DEFINE_TRACE(ElementVisibilityObserver) { - visitor->trace(m_client); + visitor->trace(m_element); visitor->trace(m_intersectionObserver); - IntersectionObserverCallback::trace(visitor); +} + +void ElementVisibilityObserver::onVisibilityChanged(const HeapVector<Member<IntersectionObserverEntry>>& entries) +{ + bool isVisible = entries.last()->intersectionRatio() > 0.f; + (*m_callback.get())(isVisible); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/ElementVisibilityObserver.h b/third_party/WebKit/Source/core/dom/ElementVisibilityObserver.h index 7a01edf..be62f5b 100644 --- a/third_party/WebKit/Source/core/dom/ElementVisibilityObserver.h +++ b/third_party/WebKit/Source/core/dom/ElementVisibilityObserver.h
@@ -5,51 +5,44 @@ #ifndef ElementVisibilityObserver_h #define ElementVisibilityObserver_h -#include "core/CoreExport.h" -#include "core/dom/IntersectionObserverCallback.h" -#include "platform/heap/Handle.h" +#include "core/dom/IntersectionObserver.h" +#include "platform/heap/Heap.h" +#include "platform/heap/Member.h" namespace blink { class Element; -class IntersectionObserver; -class IntersectionObserverEntry; // ElementVisibilityObserver is a helper class to be used to track the -// visibility of an Element in the viewport; it is implemented on top of -// IntersectionObserver. -// -// When creating an ElementVisibilityObserver instance, alongside the element -// reference, the caller will have to supply an object reference implementing -// the |Client| interface and its |onVisibilityChanged| method. The callback -// method will be invoked when the element changes visibility state, -// the boolean argument indicating which. -class ElementVisibilityObserver final : public IntersectionObserverCallback { +// visibility of an Element in the viewport. Creating an +// ElementVisibilityObserver is a no-op with regards to CPU cycle. The observing +// has be started by calling |start()| and can be stopped with |stop()|. +// When creating an instance, the caller will have to pass a callback taking +// a boolean as an argument. The boolean will be the new visibility state. +// The ElementVisibilityObserver is implemented on top of IntersectionObserver. +// It is a layer meant to simplify the usage for C++ Blink code checking for the +// visibility of an element. +class ElementVisibilityObserver final : public GarbageCollectedFinalized<ElementVisibilityObserver> { WTF_MAKE_NONCOPYABLE(ElementVisibilityObserver); public: - class CORE_EXPORT Client : public GarbageCollectedMixin { - public: - virtual void onVisibilityChanged(bool isVisible) = 0; - virtual ExecutionContext* getElementVisibilityExecutionContext() const = 0; - }; + using VisibilityCallback = Function<void(bool), WTF::SameThreadAffinity>; - static ElementVisibilityObserver* create(Element*, Client*); - ~ElementVisibilityObserver(); - DECLARE_VIRTUAL_TRACE(); + ElementVisibilityObserver(Element*, std::unique_ptr<VisibilityCallback>); + virtual ~ElementVisibilityObserver(); + void start(); void stop(); - // IntersectionObserverCallback implementation: - void handleEvent(const HeapVector<Member<IntersectionObserverEntry>>&, IntersectionObserver&) override; - ExecutionContext* getExecutionContext() const override; + DECLARE_VIRTUAL_TRACE(); private: - explicit ElementVisibilityObserver(Client*); + class ElementVisibilityCallback; - void start(Element*); + void onVisibilityChanged(const HeapVector<Member<IntersectionObserverEntry>>&); - Member<Client> m_client; + Member<Element> m_element; Member<IntersectionObserver> m_intersectionObserver; + std::unique_ptr<VisibilityCallback> m_callback; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/IntersectionObserver.h b/third_party/WebKit/Source/core/dom/IntersectionObserver.h index a21b08c5..1dbac53 100644 --- a/third_party/WebKit/Source/core/dom/IntersectionObserver.h +++ b/third_party/WebKit/Source/core/dom/IntersectionObserver.h
@@ -30,7 +30,6 @@ using EventCallback = Function<void(const HeapVector<Member<IntersectionObserverEntry>>&), WTF::SameThreadAffinity>; static IntersectionObserver* create(const IntersectionObserverInit&, IntersectionObserverCallback&, ExceptionState&); - // TODO(sof): unused, consider retiring? static IntersectionObserver* create(const Vector<Length>& rootMargin, const Vector<float>& thresholds, Document*, std::unique_ptr<EventCallback>); static void resumeSuspendedObservers();
diff --git a/third_party/WebKit/Source/core/dom/Node.cpp b/third_party/WebKit/Source/core/dom/Node.cpp index 8887dc3..b5d634e 100644 --- a/third_party/WebKit/Source/core/dom/Node.cpp +++ b/third_party/WebKit/Source/core/dom/Node.cpp
@@ -267,6 +267,8 @@ // this condition (we cannot directly access it here.) RELEASE_ASSERT(hasRareData() || !layoutObject()); InstanceCounters::decrementCounter(InstanceCounters::NodeCounter); + if (!hasRareData() && m_data.m_computedStyle) + m_data.m_computedStyle->deref(); } NodeRareData* Node::rareData() const @@ -281,9 +283,9 @@ return *rareData(); if (isElementNode()) - m_data.m_rareData = ElementRareData::create(m_data.m_layoutObject); + m_data.m_rareData = ElementRareData::create(layoutObject()); else - m_data.m_rareData = NodeRareData::create(m_data.m_layoutObject); + m_data.m_rareData = NodeRareData::create(layoutObject()); DCHECK(m_data.m_rareData);
diff --git a/third_party/WebKit/Source/core/dom/Node.h b/third_party/WebKit/Source/core/dom/Node.h index ec0f9f4b..c2f9e88 100644 --- a/third_party/WebKit/Source/core/dom/Node.h +++ b/third_party/WebKit/Source/core/dom/Node.h
@@ -477,13 +477,19 @@ // As layoutObject() includes a branch you should avoid calling it repeatedly in hot code paths. // Note that if a Node has a layoutObject, it's parentNode is guaranteed to have one as well. - LayoutObject* layoutObject() const { return hasRareData() ? m_data.m_rareData->layoutObject() : m_data.m_layoutObject; } + LayoutObject* layoutObject() const + { + if (hasRareData()) + return m_data.m_rareData->layoutObject(); + return hasLayoutObject() ? m_data.m_layoutObject : nullptr; + } void setLayoutObject(LayoutObject* layoutObject) { if (hasRareData()) m_data.m_rareData->setLayoutObject(layoutObject); else m_data.m_layoutObject = layoutObject; + setFlag(static_cast<bool>(layoutObject), HasLayoutObjectFlag); } // Use these two methods with caution. @@ -697,10 +703,12 @@ V0CustomElementFlag = 1 << 28, V0CustomElementUpgradedFlag = 1 << 29, + HasLayoutObjectFlag = 1 << 30, + DefaultNodeFlags = IsFinishedParsingChildrenFlag | NeedsReattachStyleChange }; - // 3 bits remaining. + // 1 bit remaining. bool getFlag(NodeFlags mask) const { return m_nodeFlags & mask; } void setFlag(bool f, NodeFlags mask) { m_nodeFlags = (m_nodeFlags & ~mask) | (-(int32_t)f & mask); } @@ -732,6 +740,7 @@ static void reattachWhitespaceSiblingsIfNeeded(Text* start); + bool hasLayoutObject() const { return getFlag(HasLayoutObjectFlag); } bool hasRareData() const { return getFlag(HasRareDataFlag); } NodeRareData* rareData() const; @@ -786,6 +795,7 @@ // When a node has rare data we move the layoutObject into the rare data. union DataUnion { DataUnion() : m_layoutObject(nullptr) { } + ComputedStyle* m_computedStyle; // LayoutObjects are fully owned by their DOM node. See LayoutObject's // LIFETIME documentation section. LayoutObject* m_layoutObject;
diff --git a/third_party/WebKit/Source/core/dom/NodeComputedStyle.h b/third_party/WebKit/Source/core/dom/NodeComputedStyle.h index 78872cd..a5a9f39 100644 --- a/third_party/WebKit/Source/core/dom/NodeComputedStyle.h +++ b/third_party/WebKit/Source/core/dom/NodeComputedStyle.h
@@ -25,8 +25,10 @@ #ifndef NodeComputedStyle_h #define NodeComputedStyle_h +#include "core/dom/ElementRareData.h" #include "core/dom/LayoutTreeBuilderTraversal.h" #include "core/dom/Node.h" +#include "core/dom/NodeRareData.h" #include "core/dom/shadow/InsertionPoint.h" #include "core/html/HTMLOptGroupElement.h" #include "core/layout/LayoutObject.h" @@ -41,14 +43,19 @@ inline ComputedStyle* Node::mutableComputedStyle() const { - if (LayoutObject* layoutObject = this->layoutObject()) - return layoutObject->mutableStyle(); + if (hasLayoutObject()) + return layoutObject()->mutableStyle(); // <option> and <optgroup> can be styled even if they don't get layout objects, // so they store their style internally and return it through nonLayoutObjectComputedStyle(). // We check here explicitly to avoid the virtual call in the common case. if (isHTMLOptGroupElement(*this) || isHTMLOptionElement(this)) return nonLayoutObjectComputedStyle(); - return 0; + if (hasRareData()) { + NodeRareData* rareData = this->rareData(); + DCHECK(rareData->isElementRareData()); + return static_cast<ElementRareData*>(rareData)->computedStyle(); + } + return m_data.m_computedStyle; } inline const ComputedStyle* Node::parentComputedStyle() const
diff --git a/third_party/WebKit/Source/core/dom/NodeRareData.cpp b/third_party/WebKit/Source/core/dom/NodeRareData.cpp index 9b60294..ce200b3 100644 --- a/third_party/WebKit/Source/core/dom/NodeRareData.cpp +++ b/third_party/WebKit/Source/core/dom/NodeRareData.cpp
@@ -58,7 +58,7 @@ DEFINE_TRACE(NodeRareData) { - if (m_isElementRareData) + if (isElementRareData()) static_cast<ElementRareData*>(this)->traceAfterDispatch(visitor); else traceAfterDispatch(visitor); @@ -66,7 +66,7 @@ DEFINE_TRACE_WRAPPERS(NodeRareData) { - if (m_isElementRareData) + if (isElementRareData()) static_cast<const ElementRareData*>(this)->traceWrappersAfterDispatch(visitor); else traceWrappersAfterDispatch(visitor); @@ -81,7 +81,7 @@ void NodeRareData::finalizeGarbageCollectedObject() { RELEASE_ASSERT(!layoutObject()); - if (m_isElementRareData) + if (isElementRareData()) static_cast<ElementRareData*>(this)->~ElementRareData(); else this->~NodeRareData();
diff --git a/third_party/WebKit/Source/core/dom/NodeRareData.h b/third_party/WebKit/Source/core/dom/NodeRareData.h index 5103db61..e15503e 100644 --- a/third_party/WebKit/Source/core/dom/NodeRareData.h +++ b/third_party/WebKit/Source/core/dom/NodeRareData.h
@@ -93,6 +93,8 @@ --m_connectedFrameCount; } + bool isElementRareData() const { return m_isElementRareData; } + bool hasElementFlag(ElementFlags mask) const { return m_elementFlags & mask; } void setElementFlag(ElementFlags mask, bool value) { m_elementFlags = (m_elementFlags & ~mask) | (-(int32_t)value & mask); } void clearElementFlag(ElementFlags mask) { m_elementFlags &= ~mask; }
diff --git a/third_party/WebKit/Source/core/dom/ScriptedAnimationController.cpp b/third_party/WebKit/Source/core/dom/ScriptedAnimationController.cpp index fdf4df6..ffd123d 100644 --- a/third_party/WebKit/Source/core/dom/ScriptedAnimationController.cpp +++ b/third_party/WebKit/Source/core/dom/ScriptedAnimationController.cpp
@@ -34,7 +34,6 @@ #include "core/inspector/InspectorInstrumentation.h" #include "core/inspector/InspectorTraceEvents.h" #include "core/loader/DocumentLoader.h" -#include "platform/Logging.h" namespace blink {
diff --git a/third_party/WebKit/Source/core/dom/ScriptedIdleTaskController.cpp b/third_party/WebKit/Source/core/dom/ScriptedIdleTaskController.cpp index 1e6dde1..0dd41b78 100644 --- a/third_party/WebKit/Source/core/dom/ScriptedIdleTaskController.cpp +++ b/third_party/WebKit/Source/core/dom/ScriptedIdleTaskController.cpp
@@ -9,7 +9,6 @@ #include "core/dom/IdleRequestOptions.h" #include "core/inspector/InspectorTraceEvents.h" #include "platform/Histogram.h" -#include "platform/Logging.h" #include "platform/TraceEvent.h" #include "public/platform/Platform.h" #include "public/platform/WebScheduler.h"
diff --git a/third_party/WebKit/Source/core/dom/StyleEngine.cpp b/third_party/WebKit/Source/core/dom/StyleEngine.cpp index cb6e0a484..8807b83 100644 --- a/third_party/WebKit/Source/core/dom/StyleEngine.cpp +++ b/third_party/WebKit/Source/core/dom/StyleEngine.cpp
@@ -606,7 +606,7 @@ RuleFeatureSet& ruleFeatureSet = ensureResolver().ensureUpdatedRuleFeatureSet(); for (unsigned i = 0; i < changedSize; ++i) ruleFeatureSet.collectInvalidationSetsForClass(invalidationLists, element, changedClasses[i]); - m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, element); + m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, element); } void StyleEngine::classChangedForElement(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, Element& element) @@ -649,7 +649,7 @@ ruleFeatureSet.collectInvalidationSetsForClass(invalidationLists, element, oldClasses[i]); } - m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, element); + m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, element); } void StyleEngine::attributeChangedForElement(const QualifiedName& attributeName, Element& element) @@ -659,7 +659,7 @@ InvalidationLists invalidationLists; ensureResolver().ensureUpdatedRuleFeatureSet().collectInvalidationSetsForAttribute(invalidationLists, element, attributeName); - m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, element); + m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, element); } void StyleEngine::idChangedForElement(const AtomicString& oldId, const AtomicString& newId, Element& element) @@ -673,7 +673,7 @@ ruleFeatureSet.collectInvalidationSetsForId(invalidationLists, element, oldId); if (!newId.isEmpty()) ruleFeatureSet.collectInvalidationSetsForId(invalidationLists, element, newId); - m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, element); + m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, element); } void StyleEngine::pseudoStateChangedForElement(CSSSelector::PseudoType pseudoType, Element& element) @@ -683,7 +683,7 @@ InvalidationLists invalidationLists; ensureResolver().ensureUpdatedRuleFeatureSet().collectInvalidationSetsForPseudoClass(invalidationLists, element, pseudoType); - m_styleInvalidator.scheduleInvalidationSetsForElement(invalidationLists, element); + m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, element); } void StyleEngine::scheduleSiblingInvalidationsForElement(Element& element, ContainerNode& schedulingParent, unsigned minDirectAdjacent) @@ -739,6 +739,13 @@ scheduleSiblingInvalidationsForElement(*beforeElement, *schedulingParent, i); } +void StyleEngine::scheduleNthPseudoInvalidations(ContainerNode& nthParent) +{ + InvalidationLists invalidationLists; + ensureResolver().ensureUpdatedRuleFeatureSet().collectNthInvalidationSet(invalidationLists); + m_styleInvalidator.scheduleInvalidationSetsForNode(invalidationLists, nthParent); +} + void StyleEngine::setStatsEnabled(bool enabled) { if (!enabled) {
diff --git a/third_party/WebKit/Source/core/dom/StyleEngine.h b/third_party/WebKit/Source/core/dom/StyleEngine.h index 9cf5148..06626e74 100644 --- a/third_party/WebKit/Source/core/dom/StyleEngine.h +++ b/third_party/WebKit/Source/core/dom/StyleEngine.h
@@ -176,6 +176,8 @@ void scheduleSiblingInvalidationsForElement(Element&, ContainerNode& schedulingParent, unsigned minDirectAdjacent); void scheduleInvalidationsForInsertedSibling(Element* beforeElement, Element& insertedElement); void scheduleInvalidationsForRemovedSibling(Element* beforeElement, Element& removedElement, Element& afterElement); + void scheduleNthPseudoInvalidations(ContainerNode&); + unsigned styleForElementCount() const { return m_styleForElementCount; } void incStyleForElementCount() { m_styleForElementCount++; }
diff --git a/third_party/WebKit/Source/core/dom/TreeScope.cpp b/third_party/WebKit/Source/core/dom/TreeScope.cpp index 8973a83..60654ec 100644 --- a/third_party/WebKit/Source/core/dom/TreeScope.cpp +++ b/third_party/WebKit/Source/core/dom/TreeScope.cpp
@@ -228,6 +228,9 @@ if (!pointWithScrollAndZoomIfPossible(*document, hitPoint)) return HitTestResult(); + if (!document->isActive()) + return HitTestResult(); + HitTestResult result(request, hitPoint); document->layoutViewItem().hitTest(result); return result;
diff --git a/third_party/WebKit/Source/core/editing/EditingStyle.cpp b/third_party/WebKit/Source/core/editing/EditingStyle.cpp index edca536..5c012479 100644 --- a/third_party/WebKit/Source/core/editing/EditingStyle.cpp +++ b/third_party/WebKit/Source/core/editing/EditingStyle.cpp
@@ -1140,16 +1140,16 @@ return wrappingStyle; } -static CSSValueList* mergeTextDecorationValues(const CSSValueList& mergedValue, const CSSValueList& valueToMerge) +static const CSSValueList& mergeTextDecorationValues(const CSSValueList& mergedValue, const CSSValueList& valueToMerge) { DEFINE_STATIC_LOCAL(CSSPrimitiveValue, underline, (CSSPrimitiveValue::createIdentifier(CSSValueUnderline))); DEFINE_STATIC_LOCAL(CSSPrimitiveValue, lineThrough, (CSSPrimitiveValue::createIdentifier(CSSValueLineThrough))); - CSSValueList* result = mergedValue.copy(); + CSSValueList& result = *mergedValue.copy(); if (valueToMerge.hasValue(underline) && !mergedValue.hasValue(underline)) - result->append(underline); + result.append(underline); if (valueToMerge.hasValue(lineThrough) && !mergedValue.hasValue(lineThrough)) - result->append(lineThrough); + result.append(lineThrough); return result; } @@ -1172,7 +1172,7 @@ // text decorations never override values if ((property.id() == textDecorationPropertyForEditing() || property.id() == CSSPropertyWebkitTextDecorationsInEffect) && property.value().isValueList() && value) { if (value->isValueList()) { - CSSValueList* result = mergeTextDecorationValues(*toCSSValueList(value), toCSSValueList(property.value())); + const CSSValueList& result = mergeTextDecorationValues(*toCSSValueList(value), toCSSValueList(property.value())); m_mutableStyle->setProperty(property.id(), result, property.isImportant()); continue; } @@ -1307,10 +1307,10 @@ } m_mutableStyle->setProperty(CSSPropertyPosition, CSSValueAbsolute); - m_mutableStyle->setProperty(CSSPropertyLeft, CSSPrimitiveValue::create(x, CSSPrimitiveValue::UnitType::Pixels)); - m_mutableStyle->setProperty(CSSPropertyTop, CSSPrimitiveValue::create(y, CSSPrimitiveValue::UnitType::Pixels)); - m_mutableStyle->setProperty(CSSPropertyWidth, CSSPrimitiveValue::create(width, CSSPrimitiveValue::UnitType::Pixels)); - m_mutableStyle->setProperty(CSSPropertyHeight, CSSPrimitiveValue::create(height, CSSPrimitiveValue::UnitType::Pixels)); + m_mutableStyle->setProperty(CSSPropertyLeft, *CSSPrimitiveValue::create(x, CSSPrimitiveValue::UnitType::Pixels)); + m_mutableStyle->setProperty(CSSPropertyTop, *CSSPrimitiveValue::create(y, CSSPrimitiveValue::UnitType::Pixels)); + m_mutableStyle->setProperty(CSSPropertyWidth, *CSSPrimitiveValue::create(width, CSSPrimitiveValue::UnitType::Pixels)); + m_mutableStyle->setProperty(CSSPropertyHeight, *CSSPrimitiveValue::create(height, CSSPrimitiveValue::UnitType::Pixels)); } void EditingStyle::forceInline()
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp index 05f2fd0..0b872ea 100644 --- a/third_party/WebKit/Source/core/editing/EditingUtilities.cpp +++ b/third_party/WebKit/Source/core/editing/EditingUtilities.cpp
@@ -1136,6 +1136,16 @@ return n && n->layoutObject() && n->layoutObject()->isListItem(); } +bool isPresentationalHTMLElement(const Node* node) +{ + if (!node->isHTMLElement()) + return false; + + const HTMLElement& element = toHTMLElement(*node); + return element.hasTagName(uTag) || element.hasTagName(sTag) || element.hasTagName(strikeTag) + || element.hasTagName(iTag) || element.hasTagName(emTag) || element.hasTagName(bTag) || element.hasTagName(strongTag); +} + Element* associatedElementOf(const Position& position) { Node* node = position.anchorNode();
diff --git a/third_party/WebKit/Source/core/editing/EditingUtilities.h b/third_party/WebKit/Source/core/editing/EditingUtilities.h index e25cfd8..6c5bb45f 100644 --- a/third_party/WebKit/Source/core/editing/EditingUtilities.h +++ b/third_party/WebKit/Source/core/editing/EditingUtilities.h
@@ -166,6 +166,7 @@ bool isTableStructureNode(const Node*); bool isHTMLListElement(Node*); bool isListItem(const Node*); +bool isPresentationalHTMLElement(const Node*); bool isNodeRendered(const Node&); bool isNodeVisiblyContainedWithin(Node&, const Range&); bool isRenderedAsNonInlineTableImageOrHR(const Node*);
diff --git a/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp b/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp index 1659362f..f4575f00 100644 --- a/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp +++ b/third_party/WebKit/Source/core/editing/FrameSelectionTest.cpp
@@ -94,6 +94,40 @@ EXPECT_FALSE(selection().isCaretBoundsDirty()); } +TEST_F(FrameSelectionTest, PaintCaretShouldNotLayout) +{ + Text* text = appendTextNode("Hello, World!"); + document().view()->updateAllLifecyclePhases(); + + document().body()->setContentEditable("true", ASSERT_NO_EXCEPTION); + document().body()->focus(); + EXPECT_TRUE(document().body()->focused()); + + VisibleSelection validSelection(Position(text, 0), Position(text, 0)); + selection().setCaretVisible(true); + setSelection(validSelection); + EXPECT_TRUE(selection().isCaret()); + EXPECT_TRUE(shouldPaintCaretForTesting()); + + int startCount = layoutCount(); + { + // To force layout in next updateLayout calling, widen view. + FrameView& frameView = dummyPageHolder().frameView(); + IntRect frameRect = frameView.frameRect(); + frameRect.setWidth(frameRect.width() + 1); + frameRect.setHeight(frameRect.height() + 1); + dummyPageHolder().frameView().setFrameRect(frameRect); + } + std::unique_ptr<PaintController> paintController = PaintController::create(); + { + GraphicsContext context(*paintController); + DrawingRecorder drawingRecorder(context, *dummyPageHolder().frameView().layoutView(), DisplayItem::Caret, LayoutRect::infiniteIntRect()); + selection().paintCaret(context, LayoutPoint()); + } + paintController->commitNewDisplayItems(); + EXPECT_EQ(startCount, layoutCount()); +} + TEST_F(FrameSelectionTest, InvalidatePreviousCaretAfterRemovingLastCharacter) { Text* text = appendTextNode("Hello, World!");
diff --git a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp index ce8de63..ec2f1742 100644 --- a/third_party/WebKit/Source/core/editing/VisibleUnits.cpp +++ b/third_party/WebKit/Source/core/editing/VisibleUnits.cpp
@@ -60,7 +60,6 @@ #include "core/layout/api/LineLayoutItem.h" #include "core/layout/line/InlineIterator.h" #include "core/layout/line/InlineTextBox.h" -#include "platform/Logging.h" #include "platform/heap/Handle.h" #include "platform/text/TextBoundaries.h" #include "platform/text/TextBreakIterator.h"
diff --git a/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp b/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp index eeae6a4e..fcffe70 100644 --- a/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/ApplyStyleCommand.cpp
@@ -445,7 +445,7 @@ currentFontSize = computedFontSize(node); } if (currentFontSize != desiredFontSize) { - inlineStyle->setProperty(CSSPropertyFontSize, CSSPrimitiveValue::create(desiredFontSize, CSSPrimitiveValue::UnitType::Pixels), false); + inlineStyle->setProperty(CSSPropertyFontSize, *CSSPrimitiveValue::create(desiredFontSize, CSSPrimitiveValue::UnitType::Pixels), false); setNodeAttribute(element, styleAttr, AtomicString(inlineStyle->asText())); } if (inlineStyle->isEmpty()) {
diff --git a/third_party/WebKit/Source/core/editing/serializers/Serialization.cpp b/third_party/WebKit/Source/core/editing/serializers/Serialization.cpp index 859e0cd..230319f 100644 --- a/third_party/WebKit/Source/core/editing/serializers/Serialization.cpp +++ b/third_party/WebKit/Source/core/editing/serializers/Serialization.cpp
@@ -169,16 +169,6 @@ return toCSSPrimitiveValue(value)->getValueID() == CSSValueNone; } -static bool isPresentationalHTMLElement(const Node* node) -{ - if (!node->isHTMLElement()) - return false; - - const HTMLElement& element = toHTMLElement(*node); - return element.hasTagName(uTag) || element.hasTagName(sTag) || element.hasTagName(strikeTag) - || element.hasTagName(iTag) || element.hasTagName(emTag) || element.hasTagName(bTag) || element.hasTagName(strongTag); -} - template<typename Strategy> static HTMLElement* highestAncestorToWrapMarkup(const PositionTemplate<Strategy>& startPosition, const PositionTemplate<Strategy>& endPosition, EAnnotateForInterchange shouldAnnotate, Node* constrainingAncestor) {
diff --git a/third_party/WebKit/Source/core/editing/serializers/StyledMarkupSerializer.cpp b/third_party/WebKit/Source/core/editing/serializers/StyledMarkupSerializer.cpp index 0929a85..b4e0748 100644 --- a/third_party/WebKit/Source/core/editing/serializers/StyledMarkupSerializer.cpp +++ b/third_party/WebKit/Source/core/editing/serializers/StyledMarkupSerializer.cpp
@@ -189,8 +189,18 @@ } } - if (!m_lastClosed) + // If there is no the highest node in the selected nodes, |m_lastClosed| can be #text + // when its parent is a formatting tag. In this case, #text is wrapped by <span> tag, + // but this text should be wrapped by the formatting tag. See http://crbug.com/634482 + bool shouldAppendParentTag = false; + if (!m_lastClosed) { m_lastClosed = StyledMarkupTraverser<Strategy>().traverse(firstNode, pastEnd); + if (m_lastClosed && m_lastClosed->isTextNode() && isPresentationalHTMLElement(m_lastClosed->parentNode())) { + m_lastClosed = m_lastClosed->parentElement(); + shouldAppendParentTag = true; + } + } + StyledMarkupTraverser<Strategy> traverser(&markupAccumulator, m_lastClosed); Node* lastClosed = traverser.traverse(firstNode, pastEnd); @@ -240,6 +250,9 @@ if (ancestor == m_highestNodeToBeSerialized) break; } + } else if (shouldAppendParentTag) { + EditingStyle* style = traverser.createInlineStyleIfNeeded(*m_lastClosed); + traverser.wrapWithNode(*toContainerNode(m_lastClosed), style); } // FIXME: The interchange newline should be placed in the block that it's in, not after all of the content, unconditionally.
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp index 3304bc2..32854e4 100644 --- a/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp +++ b/third_party/WebKit/Source/core/editing/spellcheck/SpellChecker.cpp
@@ -226,89 +226,30 @@ int searchEndOffsetAfterWrap = spellingSearchEnd.offsetInContainerNode(); int misspellingOffset = 0; - GrammarDetail grammarDetail; - int grammarPhraseOffset = 0; - Position grammarSearchStart, grammarSearchEnd; - String badGrammarPhrase; String misspelledWord; - bool isSpelling = true; - int foundOffset = 0; - String foundItem; if (unifiedTextCheckerEnabled()) { - grammarSearchStart = spellingSearchStart; - grammarSearchEnd = spellingSearchEnd; - foundItem = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspellingOrBadGrammar(isSpelling, foundOffset, grammarDetail); - if (isSpelling) { - misspelledWord = foundItem; - misspellingOffset = foundOffset; - } else { - badGrammarPhrase = foundItem; - grammarPhraseOffset = foundOffset; - } + misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspellingOrBadGrammar(misspellingOffset); } else { misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspelling(misspellingOffset, false); - grammarSearchStart = spellingSearchStart; - grammarSearchEnd = spellingSearchEnd; - if (!misspelledWord.isEmpty()) { - // Stop looking at start of next misspelled word - CharacterIterator chars(grammarSearchStart, grammarSearchEnd); - chars.advance(misspellingOffset); - grammarSearchEnd = chars.startPosition(); - } - - badGrammarPhrase = TextCheckingHelper(spellCheckerClient(), grammarSearchStart, grammarSearchEnd).findFirstBadGrammar(grammarDetail, grammarPhraseOffset, false); } - // If we found neither bad grammar nor a misspelled word, wrap and try again (but don't bother if we started at the beginning of the + // If we did not find a misspelled word, wrap and try again (but don't bother if we started at the beginning of the // block rather than at a selection). - if (startedWithSelection && !misspelledWord && !badGrammarPhrase) { + if (startedWithSelection && !misspelledWord) { spellingSearchStart = Position::editingPositionOf(topNode, 0); // going until the end of the very first chunk we tested is far enough spellingSearchEnd = Position::editingPositionOf(searchEndNodeAfterWrap, searchEndOffsetAfterWrap); if (unifiedTextCheckerEnabled()) { - grammarSearchStart = spellingSearchStart; - grammarSearchEnd = spellingSearchEnd; - foundItem = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspellingOrBadGrammar(isSpelling, foundOffset, grammarDetail); - if (isSpelling) { - misspelledWord = foundItem; - misspellingOffset = foundOffset; - } else { - badGrammarPhrase = foundItem; - grammarPhraseOffset = foundOffset; - } + misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspellingOrBadGrammar(misspellingOffset); } else { misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearchStart, spellingSearchEnd).findFirstMisspelling(misspellingOffset, false); - grammarSearchStart = spellingSearchStart; - grammarSearchEnd = spellingSearchEnd; - if (!misspelledWord.isEmpty()) { - // Stop looking at start of next misspelled word - CharacterIterator chars(grammarSearchStart, grammarSearchEnd); - chars.advance(misspellingOffset); - grammarSearchEnd = chars.startPosition(); - } - - badGrammarPhrase = TextCheckingHelper(spellCheckerClient(), grammarSearchStart, grammarSearchEnd).findFirstBadGrammar(grammarDetail, grammarPhraseOffset, false); } } - if (!badGrammarPhrase.isEmpty()) { - // We found bad grammar. Since we only searched for bad grammar up to the first misspelled word, the bad grammar - // takes precedence and we ignore any potential misspelled word. Select the grammar detail, update the spelling - // panel, and store a marker so we draw the green squiggle later. - - DCHECK_GT(badGrammarPhrase.length(), 0u); - DCHECK_NE(grammarDetail.location, -1); - DCHECK_GT(grammarDetail.length, 0); - - // FIXME 4859190: This gets confused with doubled punctuation at the end of a paragraph - const EphemeralRange badGrammarRange = calculateCharacterSubrange(EphemeralRange(grammarSearchStart, grammarSearchEnd), grammarPhraseOffset + grammarDetail.location, grammarDetail.length); - frame().selection().setSelection(VisibleSelection(badGrammarRange)); - frame().selection().revealSelection(); - frame().document()->markers().addMarker(badGrammarRange.startPosition(), badGrammarRange.endPosition(), DocumentMarker::Grammar, grammarDetail.userDescription); - } else if (!misspelledWord.isEmpty()) { - // We found a misspelling, but not any earlier bad grammar. Select the misspelling, update the spelling panel, and store + if (!misspelledWord.isEmpty()) { + // We found a misspelling. Select the misspelling, update the spelling panel, and store // a marker so we draw the red squiggle later. const EphemeralRange misspellingRange = calculateCharacterSubrange(EphemeralRange(spellingSearchStart, spellingSearchEnd), misspellingOffset, misspelledWord.length()); @@ -411,7 +352,6 @@ if (checkSpelling) return checker.markAllMisspellings(); - checker.markAllBadGrammar(); return false; }
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/TextCheckingHelper.cpp b/third_party/WebKit/Source/core/editing/spellcheck/TextCheckingHelper.cpp index 975ef0a..407cea5 100644 --- a/third_party/WebKit/Source/core/editing/spellcheck/TextCheckingHelper.cpp +++ b/third_party/WebKit/Source/core/editing/spellcheck/TextCheckingHelper.cpp
@@ -41,39 +41,16 @@ namespace blink { -static void findBadGrammars(TextCheckerClient& client, const UChar* text, int start, int length, Vector<TextCheckingResult>& results) +static void findMisspellings(TextCheckerClient& client, const String& text, Vector<TextCheckingResult>& results) { - int checkLocation = start; - int checkLength = length; + Vector<UChar> characters; + text.appendTo(characters); + unsigned length = text.length(); - while (0 < checkLength) { - int badGrammarLocation = -1; - int badGrammarLength = 0; - Vector<GrammarDetail> badGrammarDetails; - client.checkGrammarOfString(String(text + checkLocation, checkLength), badGrammarDetails, &badGrammarLocation, &badGrammarLength); - if (!badGrammarLength) - break; - DCHECK_LE(0, badGrammarLocation); - DCHECK_LE(badGrammarLocation, checkLength); - DCHECK_LT(0, badGrammarLength); - DCHECK_LE(badGrammarLocation + badGrammarLength, checkLength); - TextCheckingResult badGrammar; - badGrammar.decoration = TextDecorationTypeGrammar; - badGrammar.location = checkLocation + badGrammarLocation; - badGrammar.length = badGrammarLength; - badGrammar.details.swap(badGrammarDetails); - results.append(badGrammar); - - checkLocation += (badGrammarLocation + badGrammarLength); - checkLength -= (badGrammarLocation + badGrammarLength); - } -} - -static void findMisspellings(TextCheckerClient& client, const UChar* text, int start, int length, Vector<TextCheckingResult>& results) -{ - TextBreakIterator* iterator = wordBreakIterator(text + start, length); + TextBreakIterator* iterator = wordBreakIterator(characters.data(), length); if (!iterator) return; + int wordStart = iterator->current(); while (0 <= wordStart) { int wordEnd = iterator->next(); @@ -82,7 +59,7 @@ int wordLength = wordEnd - wordStart; int misspellingLocation = -1; int misspellingLength = 0; - client.checkSpellingOfString(String(text + start + wordStart, wordLength), &misspellingLocation, &misspellingLength); + client.checkSpellingOfString(String(characters.data() + wordStart, wordLength), &misspellingLocation, &misspellingLength); if (0 < misspellingLength) { DCHECK_LE(0, misspellingLocation); DCHECK_LE(misspellingLocation, wordLength); @@ -90,7 +67,7 @@ DCHECK_LE(misspellingLocation + misspellingLength, wordLength); TextCheckingResult misspelling; misspelling.decoration = TextDecorationTypeSpelling; - misspelling.location = start + wordStart + misspellingLocation; + misspelling.location = wordStart + misspellingLocation; misspelling.length = misspellingLength; results.append(misspelling); } @@ -314,22 +291,16 @@ return firstMisspelling; } -String TextCheckingHelper::findFirstMisspellingOrBadGrammar(bool& outIsSpelling, int& outFirstFoundOffset, GrammarDetail& outGrammarDetail) +String TextCheckingHelper::findFirstMisspellingOrBadGrammar(int& outFirstFoundOffset) { if (!unifiedTextCheckerEnabled()) return ""; String firstFoundItem; String misspelledWord; - String badGrammarPhrase; - // Initialize out parameters; these will be updated if we find something to return. - outIsSpelling = true; + // Initialize out parameter; it will be updated if we find something to return. outFirstFoundOffset = 0; - outGrammarDetail.location = -1; - outGrammarDetail.length = 0; - outGrammarDetail.guesses.clear(); - outGrammarDetail.userDescription = ""; // Expand the search range to encompass entire paragraphs, since text checking needs that much context. // Determine the character offset from the start of the paragraph to the start of the original search range, @@ -345,7 +316,7 @@ bool firstIteration = true; bool lastIteration = false; while (totalLengthProcessed < totalRangeLength) { - // Iterate through the search range by paragraphs, checking each one for spelling and grammar. + // Iterate through the search range by paragraphs, checking each one for spelling. int currentLength = TextIterator::rangeLength(paragraphStart, paragraphEnd); int currentStartOffset = firstIteration ? rangeStartOffset : 0; int currentEndOffset = currentLength; @@ -358,14 +329,10 @@ if (currentStartOffset < currentEndOffset) { String paragraphString = plainText(EphemeralRange(paragraphStart, paragraphEnd)); if (paragraphString.length() > 0) { - bool foundGrammar = false; int spellingLocation = 0; - int grammarPhraseLocation = 0; - int grammarDetailLocation = 0; - unsigned grammarDetailIndex = 0; Vector<TextCheckingResult> results; - checkTextOfParagraph(m_client->textChecker(), paragraphString, results); + findMisspellings(m_client->textChecker(), paragraphString, results); for (unsigned i = 0; i < results.size(); i++) { const TextCheckingResult* result = &results[i]; @@ -377,50 +344,16 @@ DCHECK(misspelledWord.length()); break; } - if (result->decoration == TextDecorationTypeGrammar && result->location < currentEndOffset && result->location + result->length > currentStartOffset) { - DCHECK_GT(result->length, 0); - DCHECK_GE(result->location, 0); - // We can't stop after the first grammar result, since there might still be a spelling result after - // it begins but before the first detail in it, but we can stop if we find a second grammar result. - if (foundGrammar) - break; - for (unsigned j = 0; j < result->details.size(); j++) { - const GrammarDetail* detail = &result->details[j]; - DCHECK_GT(detail->length, 0); - DCHECK_GE(detail->location, 0); - if (result->location + detail->location >= currentStartOffset && result->location + detail->location + detail->length <= currentEndOffset && (!foundGrammar || result->location + detail->location < grammarDetailLocation)) { - grammarDetailIndex = j; - grammarDetailLocation = result->location + detail->location; - foundGrammar = true; - } - } - if (foundGrammar) { - grammarPhraseLocation = result->location; - outGrammarDetail = result->details[grammarDetailIndex]; - badGrammarPhrase = paragraphString.substring(result->location, result->length); - DCHECK(badGrammarPhrase.length()); - } - } } - if (!misspelledWord.isEmpty() && (badGrammarPhrase.isEmpty() || spellingLocation <= grammarDetailLocation)) { + if (!misspelledWord.isEmpty()) { int spellingOffset = spellingLocation - currentStartOffset; if (!firstIteration) spellingOffset += TextIterator::rangeLength(m_start, paragraphStart); - outIsSpelling = true; outFirstFoundOffset = spellingOffset; firstFoundItem = misspelledWord; break; } - if (!badGrammarPhrase.isEmpty()) { - int grammarPhraseOffset = grammarPhraseLocation - currentStartOffset; - if (!firstIteration) - grammarPhraseOffset += TextIterator::rangeLength(m_start, paragraphStart); - outIsSpelling = false; - outFirstFoundOffset = grammarPhraseOffset; - firstFoundItem = badGrammarPhrase; - break; - } } } if (lastIteration || totalLengthProcessed + currentLength >= totalRangeLength) @@ -434,101 +367,6 @@ return firstFoundItem; } -int TextCheckingHelper::findFirstGrammarDetail(const Vector<GrammarDetail>& grammarDetails, int badGrammarPhraseLocation, int startOffset, int endOffset, bool markAll) const -{ - // Found some bad grammar. Find the earliest detail range that starts in our search range (if any). - // Optionally add a DocumentMarker for each detail in the range. - int earliestDetailLocationSoFar = -1; - int earliestDetailIndex = -1; - for (unsigned i = 0; i < grammarDetails.size(); i++) { - const GrammarDetail* detail = &grammarDetails[i]; - DCHECK_GT(detail->length, 0); - DCHECK_GE(detail->location, 0); - - int detailStartOffsetInParagraph = badGrammarPhraseLocation + detail->location; - - // Skip this detail if it starts before the original search range - if (detailStartOffsetInParagraph < startOffset) - continue; - - // Skip this detail if it starts after the original search range - if (detailStartOffsetInParagraph >= endOffset) - continue; - - if (markAll) { - const EphemeralRange badGrammarRange = calculateCharacterSubrange(EphemeralRange(m_start, m_end), badGrammarPhraseLocation - startOffset + detail->location, detail->length); - badGrammarRange.document().markers().addMarker(badGrammarRange.startPosition(), badGrammarRange.endPosition(), DocumentMarker::Grammar, detail->userDescription); - } - - // Remember this detail only if it's earlier than our current candidate (the details aren't in a guaranteed order) - if (earliestDetailIndex < 0 || earliestDetailLocationSoFar > detail->location) { - earliestDetailIndex = i; - earliestDetailLocationSoFar = detail->location; - } - } - - return earliestDetailIndex; -} - -String TextCheckingHelper::findFirstBadGrammar(GrammarDetail& outGrammarDetail, int& outGrammarPhraseOffset, bool markAll) -{ - // Initialize out parameters; these will be updated if we find something to return. - outGrammarDetail.location = -1; - outGrammarDetail.length = 0; - outGrammarDetail.guesses.clear(); - outGrammarDetail.userDescription = ""; - outGrammarPhraseOffset = 0; - - String firstBadGrammarPhrase; - - // Expand the search range to encompass entire paragraphs, since grammar checking needs that much context. - // Determine the character offset from the start of the paragraph to the start of the original search range, - // since we will want to ignore results in this area. - TextCheckingParagraph paragraph(EphemeralRange(m_start, m_end)); - - // Start checking from beginning of paragraph, but skip past results that occur before the start of the original search range. - int startOffset = 0; - while (startOffset < paragraph.checkingEnd()) { - Vector<GrammarDetail> grammarDetails; - int badGrammarPhraseLocation = -1; - int badGrammarPhraseLength = 0; - m_client->textChecker().checkGrammarOfString(paragraph.textSubstring(startOffset), grammarDetails, &badGrammarPhraseLocation, &badGrammarPhraseLength); - - if (!badGrammarPhraseLength) { - DCHECK_EQ(badGrammarPhraseLocation, -1); - return String(); - } - - DCHECK_GE(badGrammarPhraseLocation, 0); - badGrammarPhraseLocation += startOffset; - - - // Found some bad grammar. Find the earliest detail range that starts in our search range (if any). - int badGrammarIndex = findFirstGrammarDetail(grammarDetails, badGrammarPhraseLocation, paragraph.checkingStart(), paragraph.checkingEnd(), markAll); - if (badGrammarIndex >= 0) { - DCHECK_LT(static_cast<unsigned>(badGrammarIndex), grammarDetails.size()); - outGrammarDetail = grammarDetails[badGrammarIndex]; - } - - // If we found a detail in range, then we have found the first bad phrase (unless we found one earlier but - // kept going so we could mark all instances). - if (badGrammarIndex >= 0 && firstBadGrammarPhrase.isEmpty()) { - outGrammarPhraseOffset = badGrammarPhraseLocation - paragraph.checkingStart(); - firstBadGrammarPhrase = paragraph.textSubstring(badGrammarPhraseLocation, badGrammarPhraseLength); - - // Found one. We're done now, unless we're marking each instance. - if (!markAll) - break; - } - - // These results were all between the start of the paragraph and the start of the search range; look - // beyond this phrase. - startOffset = badGrammarPhraseLocation + badGrammarPhraseLength; - } - - return firstBadGrammarPhrase; -} - bool TextCheckingHelper::markAllMisspellings() { // Use the "markAll" feature of findFirstMisspelling. Ignore the return value and the "out parameter"; @@ -537,15 +375,6 @@ return findFirstMisspelling(ignoredOffset, true).isEmpty(); } -void TextCheckingHelper::markAllBadGrammar() -{ - // Use the "markAll" feature of findFirstBadGrammar. Ignore the return value and "out parameters"; all we need to - // do is mark every instance. - GrammarDetail ignoredGrammarDetail; - int ignoredOffset; - findFirstBadGrammar(ignoredGrammarDetail, ignoredOffset, true); -} - bool TextCheckingHelper::unifiedTextCheckerEnabled() const { DCHECK(m_start.isNotNull()); @@ -553,36 +382,6 @@ return blink::unifiedTextCheckerEnabled(doc.frame()); } -void checkTextOfParagraph(TextCheckerClient& client, const String& text, Vector<TextCheckingResult>& results) -{ - Vector<UChar> characters; - text.appendTo(characters); - unsigned length = text.length(); - - Vector<TextCheckingResult> spellingResult; - findMisspellings(client, characters.data(), 0, length, spellingResult); - - // Only checks grammartical error before the first misspellings - int grammarCheckLength = length; - for (const auto& spelling : spellingResult) { - if (spelling.location < grammarCheckLength) - grammarCheckLength = spelling.location; - } - - Vector<TextCheckingResult> grammarResult; - findBadGrammars(client, characters.data(), 0, grammarCheckLength, grammarResult); - - if (grammarResult.size()) - results.swap(grammarResult); - - if (spellingResult.size()) { - if (results.isEmpty()) - results.swap(spellingResult); - else - results.appendVector(spellingResult); - } -} - bool unifiedTextCheckerEnabled(const LocalFrame* frame) { if (!frame)
diff --git a/third_party/WebKit/Source/core/editing/spellcheck/TextCheckingHelper.h b/third_party/WebKit/Source/core/editing/spellcheck/TextCheckingHelper.h index 42334f3..3838545 100644 --- a/third_party/WebKit/Source/core/editing/spellcheck/TextCheckingHelper.h +++ b/third_party/WebKit/Source/core/editing/spellcheck/TextCheckingHelper.h
@@ -89,21 +89,17 @@ ~TextCheckingHelper(); String findFirstMisspelling(int& firstMisspellingOffset, bool markAll); - String findFirstMisspellingOrBadGrammar(bool& outIsSpelling, int& outFirstFoundOffset, GrammarDetail& outGrammarDetail); - String findFirstBadGrammar(GrammarDetail& outGrammarDetail, int& outGrammarPhraseOffset, bool markAll); + String findFirstMisspellingOrBadGrammar(int& outFirstFoundOffset); bool markAllMisspellings(); - void markAllBadGrammar(); private: SpellCheckerClient* m_client; Position m_start; Position m_end; - int findFirstGrammarDetail(const Vector<GrammarDetail>& grammarDetails, int badGrammarPhraseLocation, int startOffset, int endOffset, bool markAll) const; bool unifiedTextCheckerEnabled() const; }; -void checkTextOfParagraph(TextCheckerClient&, const String&, Vector<TextCheckingResult>&); bool unifiedTextCheckerEnabled(const LocalFrame*); } // namespace blink
diff --git a/third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp b/third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp index 1ee83aaa..74dd9191 100644 --- a/third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp +++ b/third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp
@@ -135,6 +135,9 @@ DEFINE_THREAD_SAFE_STATIC_LOCAL(AtomicString, allowCredentialsHeaderName, (new AtomicString("access-control-allow-credentials"))); DEFINE_THREAD_SAFE_STATIC_LOCAL(AtomicString, allowSuboriginHeaderName, (new AtomicString("access-control-allow-suborigin"))); + // TODO(esprehn): This code is using String::append extremely inefficiently + // causing tons of copies. It should pass around a StringBuilder instead. + int statusCode = response.httpStatusCode(); if (!statusCode) { @@ -172,8 +175,11 @@ if (allowOriginHeaderValue.isNull()) { errorDescription = buildAccessControlFailureMessage("No 'Access-Control-Allow-Origin' header is present on the requested resource.", securityOrigin); - if (isInterestingStatusCode(statusCode)) - errorDescription.append(" The response had HTTP status code " + String::number(statusCode) + "."); + if (isInterestingStatusCode(statusCode)) { + errorDescription.append(" The response had HTTP status code "); + errorDescription.append(String::number(statusCode)); + errorDescription.append('.'); + } if (context == WebURLRequest::RequestContextFetch) errorDescription.append(" If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.");
diff --git a/third_party/WebKit/Source/core/fetch/ImageResource.cpp b/third_party/WebKit/Source/core/fetch/ImageResource.cpp index 6dd5090..de3909e 100644 --- a/third_party/WebKit/Source/core/fetch/ImageResource.cpp +++ b/third_party/WebKit/Source/core/fetch/ImageResource.cpp
@@ -29,8 +29,8 @@ #include "core/fetch/ResourceClientOrObserverWalker.h" #include "core/fetch/ResourceFetcher.h" #include "core/fetch/ResourceLoader.h" +#include "core/fetch/ResourceLoadingLog.h" #include "core/svg/graphics/SVGImage.h" -#include "platform/Logging.h" #include "platform/RuntimeEnabledFeatures.h" #include "platform/SharedBuffer.h" #include "platform/TraceEvent.h" @@ -65,7 +65,7 @@ , m_image(nullptr) , m_hasDevicePixelRatioHeaderValue(false) { - WTF_LOG(ResourceLoading, "new ImageResource(ResourceRequest) %p", this); + RESOURCE_LOADING_DVLOG(1) << "new ImageResource(ResourceRequest) " << this; } ImageResource::ImageResource(blink::Image* image, const ResourceLoaderOptions& options) @@ -74,13 +74,13 @@ , m_image(image) , m_hasDevicePixelRatioHeaderValue(false) { - WTF_LOG(ResourceLoading, "new ImageResource(Image) %p", this); + RESOURCE_LOADING_DVLOG(1) << "new ImageResource(Image) " << this; setStatus(Cached); } ImageResource::~ImageResource() { - WTF_LOG(ResourceLoading, "~ImageResource %p", this); + RESOURCE_LOADING_DVLOG(1) << "~ImageResource " << this; clearImage(); }
diff --git a/third_party/WebKit/Source/core/fetch/MemoryCache.cpp b/third_party/WebKit/Source/core/fetch/MemoryCache.cpp index 68ef8fe..d6957b64 100644 --- a/third_party/WebKit/Source/core/fetch/MemoryCache.cpp +++ b/third_party/WebKit/Source/core/fetch/MemoryCache.cpp
@@ -22,7 +22,7 @@ #include "core/fetch/MemoryCache.h" -#include "platform/Logging.h" +#include "core/fetch/ResourceLoadingLog.h" #include "platform/TraceEvent.h" #include "platform/weborigin/SecurityOrigin.h" #include "platform/weborigin/SecurityOriginHash.h" @@ -167,7 +167,7 @@ resources->set(url, MemoryCacheEntry::create(resource)); update(resource, 0, resource->size(), true); - WTF_LOG(ResourceLoading, "MemoryCache::add Added '%s', resource %p\n", resource->url().getString().latin1().data(), resource); + RESOURCE_LOADING_DVLOG(1) << "MemoryCache::add Added " << resource->url().getString() << ", resource " << resource; } void MemoryCache::remove(Resource* resource) @@ -365,7 +365,7 @@ ASSERT(WTF::isMainThread()); Resource* resource = entry->resource(); - WTF_LOG(ResourceLoading, "Evicting resource %p for '%s' from cache", resource, resource->url().getString().latin1().data()); + RESOURCE_LOADING_DVLOG(1) << "Evicting resource " << resource << " for " << resource->url().getString() << " from cache"; TRACE_EVENT1("blink", "MemoryCache::evict", "resource", resource->url().getString().utf8()); // The resource may have already been removed by someone other than our caller, // who needed a fresh copy for a reload. See <http://bugs.webkit.org/show_bug.cgi?id=12479#c6>.
diff --git a/third_party/WebKit/Source/core/fetch/RawResource.cpp b/third_party/WebKit/Source/core/fetch/RawResource.cpp index 9fde91c..c1cb865 100644 --- a/third_party/WebKit/Source/core/fetch/RawResource.cpp +++ b/third_party/WebKit/Source/core/fetch/RawResource.cpp
@@ -104,21 +104,20 @@ return; ASSERT(RawResourceClient::isExpectedType(c)); RawResourceClient* client = static_cast<RawResourceClient*>(c); - WeakPtr<RawResourceClient> clientWeak = client->createWeakPtr(); for (const auto& redirect : redirectChain()) { ResourceRequest request(redirect.m_request); client->redirectReceived(this, request, redirect.m_redirectResponse); - if (!clientWeak || !hasClient(c)) + if (!hasClient(c)) return; } if (!response().isNull()) client->responseReceived(this, response(), nullptr); - if (!clientWeak || !hasClient(c)) + if (!hasClient(c)) return; if (data()) client->dataReceived(this, data()->data(), data()->size()); - if (!clientWeak || !hasClient(c)) + if (!hasClient(c)) return; Resource::didAddClient(client); }
diff --git a/third_party/WebKit/Source/core/fetch/RawResource.h b/third_party/WebKit/Source/core/fetch/RawResource.h index a2328a2..d8a0d52 100644 --- a/third_party/WebKit/Source/core/fetch/RawResource.h +++ b/third_party/WebKit/Source/core/fetch/RawResource.h
@@ -102,12 +102,8 @@ return static_cast<RawResource*>(resource); } -class CORE_EXPORT RawResourceClient : public ResourceClient { +class CORE_EXPORT RawResourceClient : public GarbageCollectedMixin, public ResourceClient { public: - RawResourceClient() - : m_weakFactory(this) { } - WeakPtr<RawResourceClient> createWeakPtr() { return m_weakFactory.createWeakPtr(); } - ~RawResourceClient() override {} static bool isExpectedType(ResourceClient* client) { return client->getResourceClientType() == RawResourceType; } ResourceClientType getResourceClientType() const final { return RawResourceType; } @@ -120,8 +116,7 @@ virtual void dataDownloaded(Resource*, int) { } virtual void didReceiveResourceTiming(Resource*, const ResourceTimingInfo&) { } -private: - WeakPtrFactory<RawResourceClient> m_weakFactory; + DEFINE_INLINE_VIRTUAL_TRACE() {} }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/fetch/RawResourceTest.cpp b/third_party/WebKit/Source/core/fetch/RawResourceTest.cpp index 973137c..37374b3 100644 --- a/third_party/WebKit/Source/core/fetch/RawResourceTest.cpp +++ b/third_party/WebKit/Source/core/fetch/RawResourceTest.cpp
@@ -58,6 +58,7 @@ } class DummyClient final : public GarbageCollectedFinalized<DummyClient>, public RawResourceClient { + USING_GARBAGE_COLLECTED_MIXIN(DummyClient); public: DummyClient() : m_called(false), m_numberOfRedirectsReceived(0) {} ~DummyClient() override {} @@ -82,7 +83,10 @@ bool called() { return m_called; } int numberOfRedirectsReceived() const { return m_numberOfRedirectsReceived; } const Vector<char>& data() { return m_data; } - DEFINE_INLINE_TRACE() {} + DEFINE_INLINE_TRACE() + { + RawResourceClient::trace(visitor); + } private: bool m_called; @@ -92,6 +96,7 @@ // This client adds another client when notified. class AddingClient final : public GarbageCollectedFinalized<AddingClient>, public RawResourceClient { + USING_GARBAGE_COLLECTED_MIXIN(AddingClient); public: AddingClient(DummyClient* client, Resource* resource) : m_dummyClient(client) @@ -119,6 +124,7 @@ { visitor->trace(m_dummyClient); visitor->trace(m_resource); + RawResourceClient::trace(visitor); } private: @@ -349,6 +355,7 @@ // This client removes another client when notified. class RemovingClient : public GarbageCollectedFinalized<RemovingClient>, public RawResourceClient { + USING_GARBAGE_COLLECTED_MIXIN(RemovingClient); public: RemovingClient(DummyClient* client) : m_dummyClient(client) {} @@ -365,6 +372,7 @@ DEFINE_INLINE_TRACE() { visitor->trace(m_dummyClient); + RawResourceClient::trace(visitor); } private:
diff --git a/third_party/WebKit/Source/core/fetch/Resource.cpp b/third_party/WebKit/Source/core/fetch/Resource.cpp index adf843d..96c1129 100644 --- a/third_party/WebKit/Source/core/fetch/Resource.cpp +++ b/third_party/WebKit/Source/core/fetch/Resource.cpp
@@ -32,7 +32,6 @@ #include "core/fetch/ResourceLoader.h" #include "core/inspector/InstanceCounters.h" #include "platform/Histogram.h" -#include "platform/Logging.h" #include "platform/RuntimeEnabledFeatures.h" #include "platform/SharedBuffer.h" #include "platform/TraceEvent.h"
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp index 5380548..c4ab711b 100644 --- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp +++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.cpp
@@ -34,9 +34,9 @@ #include "core/fetch/MemoryCache.h" #include "core/fetch/ResourceLoader.h" #include "core/fetch/ResourceLoaderSet.h" +#include "core/fetch/ResourceLoadingLog.h" #include "core/fetch/UniqueIdentifier.h" #include "platform/Histogram.h" -#include "platform/Logging.h" #include "platform/RuntimeEnabledFeatures.h" #include "platform/TraceEvent.h" #include "platform/TracedValue.h" @@ -591,7 +591,7 @@ const String cacheIdentifier = getCacheIdentifier(); ASSERT(!memoryCache()->resourceForURL(request.resourceRequest().url(), cacheIdentifier)); - WTF_LOG(ResourceLoading, "Loading Resource for '%s'.", request.resourceRequest().url().elidedString().latin1().data()); + RESOURCE_LOADING_DVLOG(1) << "Loading Resource for " << request.resourceRequest().url().elidedString(); Resource* resource = factory.create(request.resourceRequest(), request.options(), charset); resource->setLinkPreload(request.isLinkPreload()); @@ -669,7 +669,7 @@ // We really should discard the new prefetch since the preload has more // specific type information! crbug.com/379893 // fast/dom/HTMLLinkElement/link-and-subresource-test hits this case. - WTF_LOG(ResourceLoading, "ResourceFetcher::determineRevalidationPolicy reloading due to type mismatch."); + RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy reloading due to type mismatch."; return Reload; } @@ -734,7 +734,7 @@ // Don't reuse resources with Cache-control: no-store. if (existingResource->hasCacheControlNoStoreHeader()) { - WTF_LOG(ResourceLoading, "ResourceFetcher::determineRevalidationPolicy reloading due to Cache-control: no-store."); + RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy reloading due to Cache-control: no-store."; return Reload; } @@ -745,7 +745,7 @@ // "Access-Control-Allow-Origin: *" all the time, but some of the // client's requests are made without CORS and some with. if (existingResource->resourceRequest().allowStoredCredentials() != request.allowStoredCredentials()) { - WTF_LOG(ResourceLoading, "ResourceFetcher::determineRevalidationPolicy reloading due to difference in credentials settings."); + RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy reloading due to difference in credentials settings."; return Reload; } @@ -766,13 +766,13 @@ // CachePolicyReload always reloads if (cachePolicy == CachePolicyReload) { - WTF_LOG(ResourceLoading, "ResourceFetcher::determineRevalidationPolicy reloading due to CachePolicyReload."); + RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy reloading due to CachePolicyReload."; return Reload; } // We'll try to reload the resource if it failed last time. if (existingResource->errorOccurred()) { - WTF_LOG(ResourceLoading, "ResourceFetcher::determineRevalidationPolicye reloading due to resource being in the error state"); + RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicye reloading due to resource being in the error state"; return Reload; } @@ -787,7 +787,7 @@ // If any of the redirects in the chain to loading the resource were not cacheable, we cannot reuse our cached resource. if (!existingResource->canReuseRedirectChain()) { - WTF_LOG(ResourceLoading, "ResourceFetcher::determineRevalidationPolicy reloading due to an uncacheable redirect"); + RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy reloading due to an uncacheable redirect"; return Reload; } @@ -807,7 +807,7 @@ } // No, must reload. - WTF_LOG(ResourceLoading, "ResourceFetcher::determineRevalidationPolicy reloading due to missing cache validators."); + RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::determineRevalidationPolicy reloading due to missing cache validators."; return Reload; } @@ -864,6 +864,11 @@ return m_loaders.size(); } +bool ResourceFetcher::hasPendingRequest() const +{ + return m_loaders.size() > 0 && m_nonBlockingLoaders.size() > 0; +} + void ResourceFetcher::preloadStarted(Resource* resource) { if (m_preloads && m_preloads->contains(resource))
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcher.h b/third_party/WebKit/Source/core/fetch/ResourceFetcher.h index b10027b..32e4f390 100644 --- a/third_party/WebKit/Source/core/fetch/ResourceFetcher.h +++ b/third_party/WebKit/Source/core/fetch/ResourceFetcher.h
@@ -91,6 +91,7 @@ void clearContext(); int requestCount() const; + bool hasPendingRequest() const; enum ClearPreloadsPolicy { ClearAllPreloads, ClearSpeculativeMarkupPreloads };
diff --git a/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp b/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp index c9e2c16..fd6a3c46 100644 --- a/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp +++ b/third_party/WebKit/Source/core/fetch/ResourceFetcherTest.cpp
@@ -238,6 +238,7 @@ } class RequestSameResourceOnComplete : public GarbageCollectedFinalized<RequestSameResourceOnComplete>, public RawResourceClient { + USING_GARBAGE_COLLECTED_MIXIN(RequestSameResourceOnComplete); public: explicit RequestSameResourceOnComplete(Resource* resource) : m_resource(resource) @@ -261,6 +262,7 @@ DEFINE_INLINE_TRACE() { visitor->trace(m_resource); + RawResourceClient::trace(visitor); } String debugName() const override { return "RequestSameResourceOnComplete"; } @@ -363,6 +365,7 @@ } class ServeRequestsOnCompleteClient final : public GarbageCollectedFinalized<ServeRequestsOnCompleteClient>, public RawResourceClient { + USING_GARBAGE_COLLECTED_MIXIN(ServeRequestsOnCompleteClient); public: void notifyFinished(Resource*) override { @@ -379,7 +382,10 @@ void dataDownloaded(Resource*, int) override { ASSERT_TRUE(false); } void didReceiveResourceTiming(Resource*, const ResourceTimingInfo&) override { ASSERT_TRUE(false); } - DEFINE_INLINE_TRACE() {} + DEFINE_INLINE_TRACE() + { + RawResourceClient::trace(visitor); + } String debugName() const override { return "ServeRequestsOnCompleteClient"; } };
diff --git a/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp b/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp index d31520dd4..5085721 100644 --- a/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp +++ b/third_party/WebKit/Source/core/fetch/ResourceLoader.cpp
@@ -32,7 +32,6 @@ #include "core/fetch/CSSStyleSheetResource.h" #include "core/fetch/Resource.h" #include "core/fetch/ResourceFetcher.h" -#include "platform/Logging.h" #include "platform/SharedBuffer.h" #include "platform/exported/WrappedResourceRequest.h" #include "platform/exported/WrappedResourceResponse.h"
diff --git a/third_party/WebKit/Source/core/fetch/ResourceLoadingLog.h b/third_party/WebKit/Source/core/fetch/ResourceLoadingLog.h new file mode 100644 index 0000000..2b9219c --- /dev/null +++ b/third_party/WebKit/Source/core/fetch/ResourceLoadingLog.h
@@ -0,0 +1,20 @@ +// Copyright 2016 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 ResourceLoadingLog_h +#define ResourceLoadingLog_h + +#include "wtf/Assertions.h" + +#if DCHECK_IS_ON() +// We can see logs with |--v=N| or |--vmodule=ResourceLoadingLog=N| where N is a +// verbose level. +#define RESOURCE_LOADING_DVLOG(verbose_level) \ + LAZY_STREAM(VLOG_STREAM(verbose_level), \ + ((verbose_level) <= ::logging::GetVlogLevel("ResourceLoadingLog.h"))) +#else +#define RESOURCE_LOADING_DVLOG(verbose_level) EAT_STREAM_PARAMETERS +#endif + +#endif // ResourceLoadingLog_h
diff --git a/third_party/WebKit/Source/core/fetch/ScriptResource.cpp b/third_party/WebKit/Source/core/fetch/ScriptResource.cpp index b5a1aeb0..19785d0 100644 --- a/third_party/WebKit/Source/core/fetch/ScriptResource.cpp +++ b/third_party/WebKit/Source/core/fetch/ScriptResource.cpp
@@ -76,7 +76,7 @@ Resource::onMemoryDump(levelOfDetail, memoryDump); const String name = getMemoryDumpName() + "/decoded_script"; auto dump = memoryDump->createMemoryAllocatorDump(name); - dump->addScalar("size", "bytes", m_script.getString().sizeInBytes()); + dump->addScalar("size", "bytes", m_script.charactersSizeInBytes()); memoryDump->addSuballocation(dump->guid(), String(WTF::Partitions::kAllocatedObjectPoolName)); } @@ -91,7 +91,7 @@ // We lie a it here and claim that script counts as encoded data (even though it's really decoded data). // That's because the MemoryCache thinks that it can clear out decoded data by calling destroyDecodedData(), // but we can't destroy script in destroyDecodedData because that's our only copy of the data! - setEncodedSize(script.sizeInBytes()); + setEncodedSize(script.charactersSizeInBytes()); m_script = AtomicString(script); }
diff --git a/third_party/WebKit/Source/core/fileapi/FileReader.cpp b/third_party/WebKit/Source/core/fileapi/FileReader.cpp index 1374357..4722f6db 100644 --- a/third_party/WebKit/Source/core/fileapi/FileReader.cpp +++ b/third_party/WebKit/Source/core/fileapi/FileReader.cpp
@@ -40,7 +40,6 @@ #include "core/events/ProgressEvent.h" #include "core/fileapi/File.h" #include "core/inspector/InspectorInstrumentation.h" -#include "platform/Logging.h" #include "platform/Supplementable.h" #include "wtf/AutoReset.h" #include "wtf/CurrentTime.h"
diff --git a/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp b/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp index 725678f..d8bf5e0 100644 --- a/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp +++ b/third_party/WebKit/Source/core/fileapi/FileReaderLoader.cpp
@@ -307,7 +307,7 @@ } } -DOMArrayBuffer* FileReaderLoader::arrayBufferResult() const +DOMArrayBuffer* FileReaderLoader::arrayBufferResult() { ASSERT(m_readType == ReadAsArrayBuffer); @@ -315,7 +315,14 @@ if (!m_rawData || m_errorCode) return nullptr; - return DOMArrayBuffer::create(m_rawData->toArrayBuffer()); + if (m_arrayBufferResult) + return m_arrayBufferResult; + + DOMArrayBuffer* result = DOMArrayBuffer::create(m_rawData->toArrayBuffer()); + if (m_finishedLoading) { + m_arrayBufferResult = result; + } + return result; } String FileReaderLoader::stringResult()
diff --git a/third_party/WebKit/Source/core/fileapi/FileReaderLoader.h b/third_party/WebKit/Source/core/fileapi/FileReaderLoader.h index dedf9c2f..40a1d23 100644 --- a/third_party/WebKit/Source/core/fileapi/FileReaderLoader.h +++ b/third_party/WebKit/Source/core/fileapi/FileReaderLoader.h
@@ -34,6 +34,7 @@ #include "core/CoreExport.h" #include "core/fileapi/FileError.h" #include "core/loader/ThreadableLoaderClient.h" +#include "platform/heap/Handle.h" #include "platform/weborigin/KURL.h" #include "wtf/Forward.h" #include "wtf/PtrUtil.h" @@ -81,8 +82,8 @@ void didFinishLoading(unsigned long, double) override; void didFail(const ResourceError&) override; + DOMArrayBuffer* arrayBufferResult(); String stringResult(); - DOMArrayBuffer* arrayBufferResult() const; // Returns the total bytes received. Bytes ignored by m_rawData won't be // counted. @@ -123,11 +124,12 @@ KURL m_urlForReading; bool m_urlForReadingIsStream; - std::unique_ptr<ThreadableLoader> m_loader; + Persistent<ThreadableLoader> m_loader; std::unique_ptr<ArrayBufferBuilder> m_rawData; bool m_isRawDataConverted; + Persistent<DOMArrayBuffer> m_arrayBufferResult; String m_stringResult; // The decoder used to decode the text data.
diff --git a/third_party/WebKit/Source/core/frame/Deprecation.cpp b/third_party/WebKit/Source/core/frame/Deprecation.cpp index fe52c71..96d16a6 100644 --- a/third_party/WebKit/Source/core/frame/Deprecation.cpp +++ b/third_party/WebKit/Source/core/frame/Deprecation.cpp
@@ -391,6 +391,9 @@ case UseCounter::V8SVGSVGElement_CurrentView_AttributeGetter: return willBeRemoved("SVGSVGElement.currentView", 56, "4511711998509056"); + case UseCounter::V8SVGSVGElement_Viewport_AttributeGetter: + return willBeRemoved("SVGSVGElement.viewport", 55, "5686865248124928"); + // Features that aren't deprecated don't have a deprecation message. default: return String();
diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp index 15cff79b..1d4d771 100644 --- a/third_party/WebKit/Source/core/frame/FrameView.cpp +++ b/third_party/WebKit/Source/core/frame/FrameView.cpp
@@ -167,6 +167,7 @@ , m_crossOriginForThrottling(false) , m_subtreeThrottled(false) , m_currentUpdateLifecyclePhasesTargetState(DocumentLifecycle::Uninitialized) + , m_needsScrollbarsUpdate(false) , m_suppressAdjustViewSize(false) , m_allowsLayoutInvalidationAfterLayoutClean(true) { @@ -229,6 +230,7 @@ m_visuallyNonEmptyCharacterCount = 0; m_visuallyNonEmptyPixelCount = 0; m_isVisuallyNonEmpty = false; + m_layoutObjectCounter.reset(); clearFragmentAnchor(); m_viewportConstrainedObjects.reset(); m_layoutSubtreeRootList.clear(); @@ -392,29 +394,34 @@ return; Widget::setFrameRect(newRect); - frameRectsChanged(); - if (oldRect.size() == newRect.size()) - return; + const bool frameSizeChanged = oldRect.size() != newRect.size(); + m_needsScrollbarsUpdate = frameSizeChanged; // TODO(wjmaclean): find out why scrollbars fail to resize for complex // subframes after changing the zoom level. For now always calling // updateScrollbarsIfNeeded() here fixes the issue, but it would be good to // discover the deeper cause of this. http://crbug.com/607987. - updateScrollbars(); + updateScrollbarsIfNeeded(); + + frameRectsChanged(); updateScrollableAreaSet(); if (LayoutViewItem layoutView = this->layoutViewItem()) { + // TODO(majidvp): It seems that this only needs to be called when size + // is updated ignoring any change in the location. if (layoutView.usesCompositing()) layoutView.compositor()->frameViewDidChangeSize(); } - viewportSizeChanged(newRect.width() != oldRect.width(), newRect.height() != oldRect.height()); + if (frameSizeChanged) { + viewportSizeChanged(newRect.width() != oldRect.width(), newRect.height() != oldRect.height()); - if (m_frame->isMainFrame()) - m_frame->host()->visualViewport().mainFrameDidChangeSize(); - frame().loader().restoreScrollPositionAndViewState(); + if (m_frame->isMainFrame()) + m_frame->host()->visualViewport().mainFrameDidChangeSize(); + frame().loader().restoreScrollPositionAndViewState(); + } } Page* FrameView::page() const @@ -857,14 +864,15 @@ return value; } -#define PERFORM_LAYOUT_TRACE_CATEGORIES "blink,benchmark," TRACE_DISABLED_BY_DEFAULT("blink.debug.layout") +#define PERFORM_LAYOUT_TRACE_CATEGORIES "blink,benchmark,rail," TRACE_DISABLED_BY_DEFAULT("blink.debug.layout") void FrameView::performLayout(bool inSubtreeLayout) { ASSERT(inSubtreeLayout || m_layoutSubtreeRootList.isEmpty()); + int contentsHeightBeforeLayout = layoutViewItem().documentRect().height(); TRACE_EVENT_BEGIN1(PERFORM_LAYOUT_TRACE_CATEGORIES, "FrameView::performLayout", - "contentsHeightBeforeLayout", layoutViewItem().documentRect().height()); + "contentsHeightBeforeLayout", contentsHeightBeforeLayout); prepareLayoutAnalyzer(); ScriptForbiddenScope forbidScript; @@ -906,6 +914,7 @@ TRACE_EVENT_END1(PERFORM_LAYOUT_TRACE_CATEGORIES, "FrameView::performLayout", "counters", analyzerCounters()); + FirstMeaningfulPaintDetector::from(*m_frame->document()).markNextPaintAsMeaningfulIfNeeded(m_layoutObjectCounter, contentsHeightBeforeLayout, layoutViewItem().documentRect().height(), visibleHeight()); } void FrameView::scheduleOrPerformPostLayoutTasks() @@ -1718,12 +1727,23 @@ CompositedSelection selection; LocalFrame* focusedFrame = page->focusController().focusedFrame(); LocalFrame* localFrame = (focusedFrame && (focusedFrame->localFrameRoot() == m_frame->localFrameRoot())) ? focusedFrame : nullptr; - if (!localFrame || !computeCompositedSelection(*localFrame, selection)) { - page->chromeClient().clearCompositedSelection(); - return; - } - page->chromeClient().updateCompositedSelection(selection); + if (localFrame && computeCompositedSelection(*localFrame, selection)) { + page->chromeClient().updateCompositedSelection(localFrame, selection); + } else { + if (!localFrame) { + // Clearing the mainframe when there is no focused frame (and hence + // no localFrame) is legacy behaviour, and implemented here to + // satisfy ParameterizedWebFrameTest.CompositedSelectionBoundsCleared's + // first check that the composited selection has been cleared even + // though no frame has focus yet. If this is not desired, then the + // expectation needs to be removed from the test. + localFrame = m_frame->localFrameRoot(); + } + + if (localFrame) + page->chromeClient().clearCompositedSelection(localFrame); + } } HostWindow* FrameView::getHostWindow() const @@ -2802,7 +2822,7 @@ // Process objects needing paint invalidation on the next frame. See the definition of PaintInvalidationDelayedFull for more details. for (auto& target : pendingDelayedPaintInvalidations) - target->getMutableForPainting().setShouldDoDelayedFullPaintInvalidation(); + target->getMutableForPainting().setShouldDoFullPaintInvalidation(PaintInvalidationDelayedFull); } void FrameView::enableAutoSizeMode(const IntSize& minSize, const IntSize& maxSize) @@ -3579,12 +3599,14 @@ void FrameView::updateScrollbarsIfNeeded() { - if (needsScrollbarReconstruction() || scrollOriginChanged()) + if (m_needsScrollbarsUpdate || needsScrollbarReconstruction() || scrollOriginChanged()) updateScrollbars(); } void FrameView::updateScrollbars() { + m_needsScrollbarsUpdate = false; + if (m_frame->settings() && m_frame->settings()->rootLayerScrolls()) return;
diff --git a/third_party/WebKit/Source/core/frame/FrameView.h b/third_party/WebKit/Source/core/frame/FrameView.h index 7cf81e9..ee8bab74b 100644 --- a/third_party/WebKit/Source/core/frame/FrameView.h +++ b/third_party/WebKit/Source/core/frame/FrameView.h
@@ -32,6 +32,7 @@ #include "core/frame/RootFrameViewport.h" #include "core/layout/ScrollAnchor.h" #include "core/layout/api/LayoutViewItem.h" +#include "core/paint/FirstMeaningfulPaintDetector.h" #include "core/paint/PaintInvalidationCapableScrollableArea.h" #include "core/paint/PaintPhase.h" #include "platform/RuntimeEnabledFeatures.h" @@ -262,6 +263,7 @@ bool invalidateViewportConstrainedObjects(); + void incrementLayoutObjectCount() { m_layoutObjectCounter.increment(); } void incrementVisuallyNonEmptyCharacterCount(unsigned); void incrementVisuallyNonEmptyPixelCount(const IntSize&); bool isVisuallyNonEmpty() const { return m_isVisuallyNonEmpty; } @@ -826,6 +828,7 @@ unsigned m_visuallyNonEmptyCharacterCount; uint64_t m_visuallyNonEmptyPixelCount; bool m_isVisuallyNonEmpty; + FirstMeaningfulPaintDetector::LayoutObjectCounter m_layoutObjectCounter; Member<Node> m_fragmentAnchor; @@ -925,6 +928,7 @@ ScrollAnchor m_scrollAnchor; + bool m_needsScrollbarsUpdate; bool m_suppressAdjustViewSize; bool m_allowsLayoutInvalidationAfterLayoutClean;
diff --git a/third_party/WebKit/Source/core/frame/Settings.in b/third_party/WebKit/Source/core/frame/Settings.in index fb75a19a..5e39b9c5 100644 --- a/third_party/WebKit/Source/core/frame/Settings.in +++ b/third_party/WebKit/Source/core/frame/Settings.in
@@ -417,3 +417,5 @@ # Variant of the ParseHTMLOnMainThread experiment. This is designed to coalesce # TokenizedChunks when the experiment is running in threaded mode. parseHTMLOnMainThreadCoalesceChunks initial=false + +browserSideNavigationEnabled initial=false
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.cpp b/third_party/WebKit/Source/core/frame/UseCounter.cpp index 9ebca1e..dba648fb 100644 --- a/third_party/WebKit/Source/core/frame/UseCounter.cpp +++ b/third_party/WebKit/Source/core/frame/UseCounter.cpp
@@ -36,6 +36,7 @@ #include "core/inspector/ConsoleMessage.h" #include "core/workers/WorkerGlobalScope.h" #include "platform/Histogram.h" +#include "platform/TraceEvent.h" namespace blink { @@ -599,6 +600,17 @@ m_muteCount--; } +void UseCounter::recordMeasurement(Feature feature) +{ + if (m_muteCount) + return; + + if (!m_countBits.hasRecordedMeasurement(feature)) { + TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.feature_usage"), "FeatureFirstUsed", "feature", feature); + } + m_countBits.recordMeasurement(feature); +} + UseCounter::UseCounter() : m_muteCount(0) { @@ -662,8 +674,7 @@ if (!host) return; - ASSERT(Deprecation::deprecationMessage(feature).isEmpty()); - host->useCounter().recordMeasurement(feature); + host->useCounter().count(feature); } void UseCounter::count(const Document& document, Feature feature) @@ -751,6 +762,9 @@ if (!isUseCounterEnabledForMode(cssParserMode) || m_muteCount) return; + if (!m_CSSFeatureBits.quickGet(feature)) { + TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.feature_usage"), "CSSFeatureFirstUsed", "feature", feature); + } m_CSSFeatureBits.quickSet(feature); }
diff --git a/third_party/WebKit/Source/core/frame/UseCounter.h b/third_party/WebKit/Source/core/frame/UseCounter.h index 3a7671b..a585e653 100644 --- a/third_party/WebKit/Source/core/frame/UseCounter.h +++ b/third_party/WebKit/Source/core/frame/UseCounter.h
@@ -1275,6 +1275,7 @@ ChromeLoadTimesUnknown = 1499, SVGViewElement = 1500, + WebShareShare = 1501, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots. @@ -1322,11 +1323,7 @@ void muteForInspector(); void unmuteForInspector(); - void recordMeasurement(Feature feature) - { - if (!m_muteCount) - m_countBits.recordMeasurement(feature); - } + void recordMeasurement(Feature); void updateMeasurements(); bool hasRecordedMeasurement(Feature feature) const { return m_countBits.hasRecordedMeasurement(feature); }
diff --git a/third_party/WebKit/Source/core/frame/Window.idl b/third_party/WebKit/Source/core/frame/Window.idl index 310e28b0..9cf787f 100644 --- a/third_party/WebKit/Source/core/frame/Window.idl +++ b/third_party/WebKit/Source/core/frame/Window.idl
@@ -131,7 +131,7 @@ // Visual Viewport API // https://github.com/WICG/ViewportAPI - [RuntimeEnabled=VisualViewportAPI] readonly attribute VisualViewport? visualViewport; + [RuntimeEnabled=VisualViewportAPI, Replaceable, SameObject] readonly attribute VisualViewport? visualViewport; // client [Replaceable] readonly attribute long screenX;
diff --git a/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.cpp b/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.cpp index d1b3c3b..7227528 100644 --- a/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.cpp +++ b/third_party/WebKit/Source/core/html/AutoplayExperimentHelper.cpp
@@ -8,7 +8,6 @@ #include "core/frame/Settings.h" #include "core/html/HTMLMediaElement.h" #include "core/page/Page.h" -#include "platform/Logging.h" #include "platform/UserGestureIndicator.h" #include "platform/geometry/IntRect.h"
diff --git a/third_party/WebKit/Source/core/html/HTMLElement.cpp b/third_party/WebKit/Source/core/html/HTMLElement.cpp index 77fcde2..b2161ea 100644 --- a/third_party/WebKit/Source/core/html/HTMLElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLElement.cpp
@@ -996,7 +996,7 @@ if (!parseColorWithLegacyRules(attributeValue, parsedColor)) return; - style->setProperty(propertyID, CSSColorValue::create(parsedColor.rgb())); + style->setProperty(propertyID, *CSSColorValue::create(parsedColor.rgb())); } bool HTMLElement::isInteractiveContent() const
diff --git a/third_party/WebKit/Source/core/html/HTMLEmbedElement.cpp b/third_party/WebKit/Source/core/html/HTMLEmbedElement.cpp index b10434d..d32ac27 100644 --- a/third_party/WebKit/Source/core/html/HTMLEmbedElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLEmbedElement.cpp
@@ -147,12 +147,14 @@ if (!layoutObject()) return; - // Overwrites the URL and MIME type of a Flash embed to use an - // HTML5 embed when possible. - KURL overridenUrl = document().frame()->loader().client()->overrideFlashEmbedWithHTML(document().completeURL(m_url)); - if (!overridenUrl.isEmpty()) { - m_url = overridenUrl.getString(); - m_serviceType = "text/html"; + // Overwrites the URL and MIME type of a Flash embed to use an HTML5 embed + // when outside of a PluginDocument. + if (!document().isPluginDocument()) { + KURL overridenUrl = document().frame()->loader().client()->overrideFlashEmbedWithHTML(document().completeURL(m_url)); + if (!overridenUrl.isEmpty()) { + m_url = overridenUrl.getString(); + m_serviceType = "text/html"; + } } requestObject(m_url, m_serviceType, paramNames, paramValues);
diff --git a/third_party/WebKit/Source/core/html/HTMLHRElement.cpp b/third_party/WebKit/Source/core/html/HTMLHRElement.cpp index 6a67cc7..00ce4c7 100644 --- a/third_party/WebKit/Source/core/html/HTMLHRElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLHRElement.cpp
@@ -76,7 +76,7 @@ if (!hasAttribute(colorAttr)) { addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderStyle, CSSValueSolid); - CSSColorValue* darkGrayValue = CSSColorValue::create(Color::darkGray); + const CSSColorValue& darkGrayValue = *CSSColorValue::create(Color::darkGray); style->setProperty(CSSPropertyBorderColor, darkGrayValue); style->setProperty(CSSPropertyBackgroundColor, darkGrayValue); }
diff --git a/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp b/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp index 94fdae7..fdaa2f14 100644 --- a/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp +++ b/third_party/WebKit/Source/core/html/HTMLImageLoader.cpp
@@ -25,11 +25,11 @@ #include "core/dom/Element.h" #include "core/events/Event.h" #include "core/fetch/ImageResource.h" +#include "core/fetch/ResourceLoadingLog.h" #include "core/html/HTMLImageElement.h" #include "core/html/HTMLInputElement.h" #include "core/html/HTMLObjectElement.h" #include "core/html/parser/HTMLParserIdioms.h" -#include "platform/Logging.h" namespace blink { @@ -46,7 +46,7 @@ void HTMLImageLoader::dispatchLoadEvent() { - WTF_LOG(ResourceLoading, "HTMLImageLoader::dispatchLoadEvent %p", this); + RESOURCE_LOADING_DVLOG(1) << "HTMLImageLoader::dispatchLoadEvent " << this; // HTMLVideoElement uses this class to load the poster image, but it should not fire events for loading or failure. if (isHTMLVideoElement(*element()))
diff --git a/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp b/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp index 5a9d71f..b4b4d92 100644 --- a/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLLinkElement.cpp
@@ -50,6 +50,7 @@ #include "core/loader/FrameLoader.h" #include "core/loader/FrameLoaderClient.h" #include "core/loader/NetworkHintsInterface.h" +#include "core/origin_trials/OriginTrials.h" #include "core/style/StyleInheritedData.h" #include "platform/ContentType.h" #include "platform/Histogram.h" @@ -153,7 +154,7 @@ m_link = LinkImport::create(this); } else if (m_relAttribute.isManifest()) { m_link = LinkManifest::create(this); - } else if (RuntimeEnabledFeatures::linkServiceWorkerEnabled() && m_relAttribute.isServiceWorker()) { + } else if (m_relAttribute.isServiceWorker() && OriginTrials::linkServiceWorkerEnabled(getExecutionContext())) { if (document().frame()) m_link = document().frame()->loader().client()->createServiceWorkerLinkResource(this); } else {
diff --git a/third_party/WebKit/Source/core/html/HTMLLinkElement.idl b/third_party/WebKit/Source/core/html/HTMLLinkElement.idl index 112a4f0..c59cb9b 100644 --- a/third_party/WebKit/Source/core/html/HTMLLinkElement.idl +++ b/third_party/WebKit/Source/core/html/HTMLLinkElement.idl
@@ -55,5 +55,5 @@ // Service workers // http://mkruisselbrink.github.io/ServiceWorker/spec/service_worker/#link-element-interface-section - [Reflect, RuntimeEnabled=LinkServiceWorker] attribute USVString scope; + [Reflect, OriginTrialEnabled=LinkServiceWorker] attribute USVString scope; };
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp index 477cbbb..ace56247 100644 --- a/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.cpp
@@ -72,7 +72,6 @@ #include "platform/ContentType.h" #include "platform/Histogram.h" #include "platform/LayoutTestSupport.h" -#include "platform/Logging.h" #include "platform/MIMETypeFromURL.h" #include "platform/MIMETypeRegistry.h" #include "platform/RuntimeEnabledFeatures.h" @@ -1659,8 +1658,10 @@ // We might end up in a situation where the previous // observer didn't had time to fire yet. We can avoid // creating a new one in this case. - if (!m_autoplayVisibilityObserver) - m_autoplayVisibilityObserver = ElementVisibilityObserver::create(this, this); + if (!m_autoplayVisibilityObserver) { + m_autoplayVisibilityObserver = new ElementVisibilityObserver(this, WTF::bind(&HTMLMediaElement::onVisibilityChangedForAutoplay, wrapWeakPersistent(this))); + m_autoplayVisibilityObserver->start(); + } } else { m_paused = false; invalidateCachedTime(); @@ -3673,8 +3674,8 @@ visitor->trace(m_srcObject); visitor->trace(m_autoplayVisibilityObserver); visitor->template registerWeakMembers<HTMLMediaElement, &HTMLMediaElement::clearWeakMembers>(this); - HTMLElement::trace(visitor); Supplementable<HTMLMediaElement>::trace(visitor); + HTMLElement::trace(visitor); ActiveDOMObject::trace(visitor); } @@ -3912,7 +3913,7 @@ autoplayUnmuteHistogram.count(status); } -void HTMLMediaElement::onVisibilityChanged(bool isVisible) +void HTMLMediaElement::onVisibilityChangedForAutoplay(bool isVisible) { if (!isVisible) return;
diff --git a/third_party/WebKit/Source/core/html/HTMLMediaElement.h b/third_party/WebKit/Source/core/html/HTMLMediaElement.h index 2f3a196..b880685 100644 --- a/third_party/WebKit/Source/core/html/HTMLMediaElement.h +++ b/third_party/WebKit/Source/core/html/HTMLMediaElement.h
@@ -30,7 +30,6 @@ #include "bindings/core/v8/ScriptPromise.h" #include "core/CoreExport.h" #include "core/dom/ActiveDOMObject.h" -#include "core/dom/ElementVisibilityObserver.h" #include "core/dom/ExceptionCode.h" #include "core/events/GenericEventQueue.h" #include "core/html/AutoplayExperimentHelper.h" @@ -71,7 +70,7 @@ class WebLayer; class WebRemotePlaybackClient; -class CORE_EXPORT HTMLMediaElement : public HTMLElement, public Supplementable<HTMLMediaElement>, public ActiveScriptWrappable, public ActiveDOMObject, private WebMediaPlayerClient, private ElementVisibilityObserver::Client { +class CORE_EXPORT HTMLMediaElement : public HTMLElement, public Supplementable<HTMLMediaElement>, public ActiveScriptWrappable, public ActiveDOMObject, private WebMediaPlayerClient { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(HTMLMediaElement); USING_PRE_FINALIZER(HTMLMediaElement, dispose); @@ -503,9 +502,7 @@ void recordAutoplaySourceMetric(int source); void recordAutoplayUnmuteStatus(AutoplayUnmuteActionStatus); - // ElementVisibilityObserver::Client implementation - void onVisibilityChanged(bool isVisible) override; - ExecutionContext* getElementVisibilityExecutionContext() const override { return getExecutionContext(); } + void onVisibilityChangedForAutoplay(bool isVisible); UnthrottledThreadTimer<HTMLMediaElement> m_loadTimer; UnthrottledThreadTimer<HTMLMediaElement> m_progressEventTimer;
diff --git a/third_party/WebKit/Source/core/html/HTMLOptGroupElement.h b/third_party/WebKit/Source/core/html/HTMLOptGroupElement.h index 1e12275..e244034 100644 --- a/third_party/WebKit/Source/core/html/HTMLOptGroupElement.h +++ b/third_party/WebKit/Source/core/html/HTMLOptGroupElement.h
@@ -65,6 +65,7 @@ void updateGroupLabel(); + // TODO(bugsnash): Use Node's ComputedStyle instead RefPtr<ComputedStyle> m_style; };
diff --git a/third_party/WebKit/Source/core/html/HTMLOptionElement.h b/third_party/WebKit/Source/core/html/HTMLOptionElement.h index 14254d39..4be991d 100644 --- a/third_party/WebKit/Source/core/html/HTMLOptionElement.h +++ b/third_party/WebKit/Source/core/html/HTMLOptionElement.h
@@ -117,6 +117,7 @@ // Represents 'dirtiness'. // https://html.spec.whatwg.org/multipage/forms.html#concept-option-dirtiness bool m_isDirty = false; + // TODO(bugsnash): Use Node's ComputedStyle instead RefPtr<ComputedStyle> m_style; };
diff --git a/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp b/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp index b9c293c4..c1f94c09 100644 --- a/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLPlugInElement.cpp
@@ -46,7 +46,6 @@ #include "core/page/scrolling/ScrollingCoordinator.h" #include "core/plugins/PluginView.h" #include "platform/Histogram.h" -#include "platform/Logging.h" #include "platform/MIMETypeFromURL.h" #include "platform/MIMETypeRegistry.h" #include "platform/Widget.h"
diff --git a/third_party/WebKit/Source/core/html/HTMLSourceElement.cpp b/third_party/WebKit/Source/core/html/HTMLSourceElement.cpp index a1269b7..3029e047 100644 --- a/third_party/WebKit/Source/core/html/HTMLSourceElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLSourceElement.cpp
@@ -34,7 +34,6 @@ #include "core/events/EventSender.h" #include "core/html/HTMLMediaElement.h" #include "core/html/HTMLPictureElement.h" -#include "platform/Logging.h" #define SOURCE_LOG_LEVEL 3
diff --git a/third_party/WebKit/Source/core/html/HTMLTableElement.cpp b/third_party/WebKit/Source/core/html/HTMLTableElement.cpp index 78ff458..dbb9aae7 100644 --- a/third_party/WebKit/Source/core/html/HTMLTableElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLTableElement.cpp
@@ -457,24 +457,24 @@ style->setProperty(CSSPropertyBorderRightWidth, CSSValueThin); style->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid); style->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid); - style->setProperty(CSSPropertyBorderColor, CSSInheritedValue::create()); + style->setProperty(CSSPropertyBorderColor, *CSSInheritedValue::create()); break; case SolidBordersRowsOnly: style->setProperty(CSSPropertyBorderTopWidth, CSSValueThin); style->setProperty(CSSPropertyBorderBottomWidth, CSSValueThin); style->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid); style->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid); - style->setProperty(CSSPropertyBorderColor, CSSInheritedValue::create()); + style->setProperty(CSSPropertyBorderColor, *CSSInheritedValue::create()); break; case SolidBorders: - style->setProperty(CSSPropertyBorderWidth, CSSPrimitiveValue::create(1, CSSPrimitiveValue::UnitType::Pixels)); - style->setProperty(CSSPropertyBorderStyle, CSSPrimitiveValue::createIdentifier(CSSValueSolid)); - style->setProperty(CSSPropertyBorderColor, CSSInheritedValue::create()); + style->setProperty(CSSPropertyBorderWidth, *CSSPrimitiveValue::create(1, CSSPrimitiveValue::UnitType::Pixels)); + style->setProperty(CSSPropertyBorderStyle, *CSSPrimitiveValue::createIdentifier(CSSValueSolid)); + style->setProperty(CSSPropertyBorderColor, *CSSInheritedValue::create()); break; case InsetBorders: - style->setProperty(CSSPropertyBorderWidth, CSSPrimitiveValue::create(1, CSSPrimitiveValue::UnitType::Pixels)); - style->setProperty(CSSPropertyBorderStyle, CSSPrimitiveValue::createIdentifier(CSSValueInset)); - style->setProperty(CSSPropertyBorderColor, CSSInheritedValue::create()); + style->setProperty(CSSPropertyBorderWidth, *CSSPrimitiveValue::create(1, CSSPrimitiveValue::UnitType::Pixels)); + style->setProperty(CSSPropertyBorderStyle, *CSSPrimitiveValue::createIdentifier(CSSValueInset)); + style->setProperty(CSSPropertyBorderColor, *CSSInheritedValue::create()); break; case NoBorders: // If 'rules=none' then allow any borders set at cell level to take effect. @@ -482,7 +482,7 @@ } if (m_padding) - style->setProperty(CSSPropertyPadding, CSSPrimitiveValue::create(m_padding, CSSPrimitiveValue::UnitType::Pixels)); + style->setProperty(CSSPropertyPadding, *CSSPrimitiveValue::create(m_padding, CSSPrimitiveValue::UnitType::Pixels)); return style; }
diff --git a/third_party/WebKit/Source/core/html/HTMLTrackElement.cpp b/third_party/WebKit/Source/core/html/HTMLTrackElement.cpp index 5a92eed..651c5d1 100644 --- a/third_party/WebKit/Source/core/html/HTMLTrackElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLTrackElement.cpp
@@ -32,7 +32,6 @@ #include "core/html/CrossOriginAttribute.h" #include "core/html/HTMLMediaElement.h" #include "core/html/track/LoadableTextTrack.h" -#include "platform/Logging.h" #define TRACK_LOG_LEVEL 3
diff --git a/third_party/WebKit/Source/core/html/PluginDocument.cpp b/third_party/WebKit/Source/core/html/PluginDocument.cpp index 221c5a4..8f4f311 100644 --- a/third_party/WebKit/Source/core/html/PluginDocument.cpp +++ b/third_party/WebKit/Source/core/html/PluginDocument.cpp
@@ -178,7 +178,7 @@ Widget* PluginDocument::pluginWidget() { if (m_pluginNode && m_pluginNode->layoutObject()) { - ASSERT(m_pluginNode->layoutObject()->isEmbeddedObject()); + CHECK(m_pluginNode->layoutObject()->isEmbeddedObject()); return toLayoutEmbeddedObject(m_pluginNode->layoutObject())->widget(); } return 0;
diff --git a/third_party/WebKit/Source/core/html/RelList.cpp b/third_party/WebKit/Source/core/html/RelList.cpp index a05e349..4d1cf239 100644 --- a/third_party/WebKit/Source/core/html/RelList.cpp +++ b/third_party/WebKit/Source/core/html/RelList.cpp
@@ -5,6 +5,7 @@ #include "core/html/RelList.h" #include "core/dom/Document.h" +#include "core/origin_trials/OriginTrials.h" #include "platform/RuntimeEnabledFeatures.h" #include "wtf/HashMap.h" @@ -57,8 +58,6 @@ "apple-touch-icon", "apple-touch-icon-precomposed", }; - if (RuntimeEnabledFeatures::linkServiceWorkerEnabled()) - tokens.add("serviceworker"); } return tokens; @@ -66,7 +65,9 @@ bool RelList::validateTokenValue(const AtomicString& tokenValue, ExceptionState&) const { - return supportedTokens().contains(tokenValue); + if (supportedTokens().contains(tokenValue)) + return true; + return OriginTrials::linkServiceWorkerEnabled(m_element->getExecutionContext()) && tokenValue == "serviceworker"; } DEFINE_TRACE(RelList)
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp index ed5d359..20960c46 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp +++ b/third_party/WebKit/Source/core/html/parser/HTMLDocumentParser.cpp
@@ -573,7 +573,9 @@ if (!m_haveBackgroundParser) startBackgroundParser(); - postTaskToLookaheadParser(Asynchronous, &BackgroundHTMLParser::forcePlaintextForTextDocument, m_backgroundParser); + // This task should be synchronous, because otherwise synchronous + // tokenizing can happen before plaintext is forced. + postTaskToLookaheadParser(Synchronous, &BackgroundHTMLParser::forcePlaintextForTextDocument, m_backgroundParser); } else m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState); }
diff --git a/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp b/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp index 58a4dbec..e7d1da0 100644 --- a/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp +++ b/third_party/WebKit/Source/core/html/track/vtt/VTTRegion.cpp
@@ -39,7 +39,6 @@ #include "core/html/HTMLDivElement.h" #include "core/html/track/vtt/VTTParser.h" #include "core/html/track/vtt/VTTScanner.h" -#include "platform/Logging.h" #include "wtf/MathExtras.h" #include "wtf/text/StringBuilder.h"
diff --git a/third_party/WebKit/Source/core/inspector/BUILD.gn b/third_party/WebKit/Source/core/inspector/BUILD.gn index 815a1c4..9033b6d 100644 --- a/third_party/WebKit/Source/core/inspector/BUILD.gn +++ b/third_party/WebKit/Source/core/inspector/BUILD.gn
@@ -35,15 +35,37 @@ ":protocol_version", ] sources = [ + "../../platform/inspector_protocol/Allocator_h.template", + "../../platform/inspector_protocol/Array_h.template", + "../../platform/inspector_protocol/BackendCallback_h.template", "../../platform/inspector_protocol/CodeGenerator.py", + "../../platform/inspector_protocol/Collections_h.template", + "../../platform/inspector_protocol/DispatcherBase_cpp.template", + "../../platform/inspector_protocol/DispatcherBase_h.template", + "../../platform/inspector_protocol/ErrorSupport_cpp.template", + "../../platform/inspector_protocol/ErrorSupport_h.template", "../../platform/inspector_protocol/Exported_h.template", + "../../platform/inspector_protocol/FrontendChannel_h.template", "../../platform/inspector_protocol/Imported_h.template", + "../../platform/inspector_protocol/InspectorProtocol_cpp.template", + "../../platform/inspector_protocol/Maybe_h.template", + "../../platform/inspector_protocol/Object_cpp.template", + "../../platform/inspector_protocol/Object_h.template", + "../../platform/inspector_protocol/Parser_cpp.template", + "../../platform/inspector_protocol/Parser_h.template", + "../../platform/inspector_protocol/Platform_h.template", + "../../platform/inspector_protocol/String16_cpp.template", + "../../platform/inspector_protocol/String16_h.template", "../../platform/inspector_protocol/TypeBuilder_cpp.template", "../../platform/inspector_protocol/TypeBuilder_h.template", + "../../platform/inspector_protocol/ValueConversions_h.template", + "../../platform/inspector_protocol/Values_cpp.template", + "../../platform/inspector_protocol/Values_h.template", ] inputs = [ "browser_protocol.json", "../../platform/v8_inspector/js_protocol.json", + "inspector_protocol_config.json", ] outputs = [ "$blink_core_output_dir/inspector/protocol/Accessibility.cpp", @@ -103,20 +125,10 @@ ] args = [ - "--protocol", - rebase_path("browser_protocol.json", root_build_dir), - "--include", - rebase_path("../../platform/v8_inspector/js_protocol.json", root_build_dir), - "--include_package", - "platform/v8_inspector/public/protocol", - "--string_type", - "String", - "--export_macro", - "CORE_EXPORT", - "--output_dir", - rebase_path(blink_core_output_dir + "/inspector/protocol", root_build_dir), - "--output_package", - "core/inspector/protocol", + "--output_base", + rebase_path(blink_core_output_dir, root_build_dir), + "--config", + rebase_path("inspector_protocol_config.json", root_build_dir), ] }
diff --git a/third_party/WebKit/Source/core/inspector/DOMEditor.h b/third_party/WebKit/Source/core/inspector/DOMEditor.h index cb69ff1..62502423 100644 --- a/third_party/WebKit/Source/core/inspector/DOMEditor.h +++ b/third_party/WebKit/Source/core/inspector/DOMEditor.h
@@ -32,7 +32,7 @@ #define DOMEditor_h #include "platform/heap/Handle.h" -#include "platform/inspector_protocol/ErrorSupport.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "wtf/text/WTFString.h" namespace blink {
diff --git a/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.cpp index 1b810a0d..dd386a8 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorAnimationAgent.cpp
@@ -114,7 +114,6 @@ std::unique_ptr<protocol::Animation::AnimationEffect> animationObject = protocol::Animation::AnimationEffect::create() .setDelay(delay) .setEndDelay(computedTiming.endDelay()) - .setPlaybackRate(computedTiming.playbackRate()) .setIterationStart(computedTiming.iterationStart()) .setIterations(computedTiming.iterations()) .setDuration(duration)
diff --git a/third_party/WebKit/Source/core/inspector/InspectorBaseAgent.h b/third_party/WebKit/Source/core/inspector/InspectorBaseAgent.h index 3385393c..88fb016 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorBaseAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorBaseAgent.h
@@ -34,9 +34,7 @@ #include "core/CoreExport.h" #include "core/InstrumentingAgents.h" #include "platform/heap/Handle.h" -#include "platform/inspector_protocol/DispatcherBase.h" -#include "platform/inspector_protocol/Maybe.h" -#include "platform/inspector_protocol/Values.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "wtf/Forward.h" #include "wtf/text/WTFString.h"
diff --git a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.h b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.h index d6cff44..8d5898de 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorCSSAgent.h
@@ -33,7 +33,6 @@ #include "core/inspector/InspectorDOMAgent.h" #include "core/inspector/InspectorStyleSheet.h" #include "core/inspector/protocol/CSS.h" -#include "platform/inspector_protocol/Values.h" #include "wtf/HashCountedSet.h" #include "wtf/HashMap.h" #include "wtf/HashSet.h"
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h index 446e0c67..ef8b36b5 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h +++ b/third_party/WebKit/Source/core/inspector/InspectorDOMAgent.h
@@ -37,7 +37,6 @@ #include "core/inspector/protocol/DOM.h" #include "core/style/ComputedStyleConstants.h" #include "platform/geometry/FloatQuad.h" -#include "platform/inspector_protocol/Values.h" #include "platform/v8_inspector/public/V8InspectorSession.h" #include "wtf/HashMap.h" #include "wtf/HashSet.h"
diff --git a/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp index 0bf4108..9f20a0d 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorDOMDebuggerAgent.cpp
@@ -38,7 +38,6 @@ #include "core/events/EventTarget.h" #include "core/frame/LocalDOMWindow.h" #include "core/inspector/InspectorDOMAgent.h" -#include "platform/inspector_protocol/Values.h" #include "platform/v8_inspector/public/V8InspectorSession.h" namespace {
diff --git a/third_party/WebKit/Source/core/inspector/InspectorInputAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorInputAgent.cpp index cef639e..34d0517 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorInputAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorInputAgent.cpp
@@ -42,7 +42,6 @@ #include "platform/geometry/IntPoint.h" #include "platform/geometry/IntRect.h" #include "platform/geometry/IntSize.h" -#include "platform/inspector_protocol/Values.h" #include "wtf/CurrentTime.h" namespace {
diff --git a/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp index 4d2887f..bcf8b99 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorLayerTreeAgent.cpp
@@ -51,7 +51,6 @@ #include "platform/graphics/PictureSnapshot.h" #include "platform/graphics/paint/SkPictureBuilder.h" #include "platform/image-encoders/PNGImageEncoder.h" -#include "platform/inspector_protocol/Parser.h" #include "platform/transforms/TransformationMatrix.h" #include "public/platform/WebFloatPoint.h" #include "public/platform/WebLayer.h"
diff --git a/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp index eb417151..7da58c0 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorNetworkAgent.cpp
@@ -60,7 +60,6 @@ #include "core/page/Page.h" #include "core/xmlhttprequest/XMLHttpRequest.h" #include "platform/blob/BlobData.h" -#include "platform/inspector_protocol/Values.h" #include "platform/network/HTTPHeaderMap.h" #include "platform/network/ResourceError.h" #include "platform/network/ResourceLoadTiming.h"
diff --git a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp index 9abe2d5..436dc74 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorPageAgent.cpp
@@ -62,7 +62,6 @@ #include "platform/MIMETypeRegistry.h" #include "platform/PlatformResourceLoader.h" #include "platform/UserGestureIndicator.h" -#include "platform/inspector_protocol/Values.h" #include "platform/v8_inspector/public/V8InspectorSession.h" #include "platform/weborigin/SecurityOrigin.h" #include "wtf/CurrentTime.h"
diff --git a/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp b/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp index 56e24b1..f7547475 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorResourceContentLoader.cpp
@@ -43,6 +43,7 @@ { visitor->trace(m_loader); StyleSheetResourceClient::trace(visitor); + RawResourceClient::trace(visitor); } private:
diff --git a/third_party/WebKit/Source/core/inspector/InspectorSession.cpp b/third_party/WebKit/Source/core/inspector/InspectorSession.cpp index 3b24e37d..fd7f04c 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorSession.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorSession.cpp
@@ -9,7 +9,6 @@ #include "core/frame/UseCounter.h" #include "core/inspector/InspectorBaseAgent.h" #include "core/inspector/InspectorInstrumentation.h" -#include "platform/inspector_protocol/Parser.h" #include "platform/v8_inspector/public/V8Inspector.h" #include "platform/v8_inspector/public/V8InspectorSession.h"
diff --git a/third_party/WebKit/Source/core/inspector/InspectorSession.h b/third_party/WebKit/Source/core/inspector/InspectorSession.h index 1845fd0c..22addfe8 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorSession.h +++ b/third_party/WebKit/Source/core/inspector/InspectorSession.h
@@ -7,9 +7,7 @@ #include "core/CoreExport.h" #include "platform/heap/Handle.h" -#include "platform/inspector_protocol/DispatcherBase.h" -#include "platform/inspector_protocol/FrontendChannel.h" -#include "platform/inspector_protocol/Values.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "wtf/Forward.h" #include "wtf/Vector.h" #include "wtf/text/WTFString.h"
diff --git a/third_party/WebKit/Source/core/inspector/InspectorStyleSheet.h b/third_party/WebKit/Source/core/inspector/InspectorStyleSheet.h index ae97a33..8bfdba6a 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorStyleSheet.h +++ b/third_party/WebKit/Source/core/inspector/InspectorStyleSheet.h
@@ -29,7 +29,7 @@ #include "core/css/CSSStyleDeclaration.h" #include "core/inspector/protocol/CSS.h" #include "platform/heap/Handle.h" -#include "platform/inspector_protocol/Values.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "wtf/HashMap.h" #include "wtf/PassRefPtr.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/core/inspector/LayoutEditor.cpp b/third_party/WebKit/Source/core/inspector/LayoutEditor.cpp index 8294dc9..7e04c6932 100644 --- a/third_party/WebKit/Source/core/inspector/LayoutEditor.cpp +++ b/third_party/WebKit/Source/core/inspector/LayoutEditor.cpp
@@ -18,7 +18,6 @@ #include "core/inspector/InspectorHighlight.h" #include "core/style/ComputedStyle.h" #include "platform/ScriptForbiddenScope.h" -#include "platform/inspector_protocol/Values.h" namespace blink {
diff --git a/third_party/WebKit/Source/core/inspector/LayoutEditor.h b/third_party/WebKit/Source/core/inspector/LayoutEditor.h index ae2a279e..5b5e6bc 100644 --- a/third_party/WebKit/Source/core/inspector/LayoutEditor.h +++ b/third_party/WebKit/Source/core/inspector/LayoutEditor.h
@@ -11,7 +11,7 @@ #include "core/css/CSSRuleList.h" #include "core/dom/Element.h" #include "platform/heap/Handle.h" -#include "platform/inspector_protocol/Values.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "wtf/RefPtr.h" #include "wtf/text/WTFString.h"
diff --git a/third_party/WebKit/Source/core/inspector/MainThreadDebugger.cpp b/third_party/WebKit/Source/core/inspector/MainThreadDebugger.cpp index 23b9550..4e418ea 100644 --- a/third_party/WebKit/Source/core/inspector/MainThreadDebugger.cpp +++ b/third_party/WebKit/Source/core/inspector/MainThreadDebugger.cpp
@@ -61,7 +61,6 @@ #include "core/xml/XPathEvaluator.h" #include "core/xml/XPathResult.h" #include "platform/UserGestureIndicator.h" -#include "platform/inspector_protocol/Values.h" #include "platform/v8_inspector/public/V8Inspector.h" #include "wtf/PtrUtil.h" #include "wtf/ThreadingPrimitives.h"
diff --git a/third_party/WebKit/Source/core/inspector/NetworkResourcesData.cpp b/third_party/WebKit/Source/core/inspector/NetworkResourcesData.cpp index fd93123..f159f540 100644 --- a/third_party/WebKit/Source/core/inspector/NetworkResourcesData.cpp +++ b/third_party/WebKit/Source/core/inspector/NetworkResourcesData.cpp
@@ -95,14 +95,9 @@ m_base64Encoded = base64Encoded; } -static size_t contentSizeInBytes(const String& content) +size_t NetworkResourcesData::ResourceData::removeContent() { - return content.isNull() ? 0 : content.impl()->sizeInBytes(); -} - -unsigned NetworkResourcesData::ResourceData::removeContent() -{ - unsigned result = 0; + size_t result = 0; if (hasData()) { ASSERT(!hasContent()); result = m_dataBuffer->size(); @@ -111,13 +106,13 @@ if (hasContent()) { ASSERT(!hasData()); - result = contentSizeInBytes(m_content); + result = m_content.charactersSizeInBytes(); m_content = String(); } return result; } -unsigned NetworkResourcesData::ResourceData::evictContent() +size_t NetworkResourcesData::ResourceData::evictContent() { m_isContentEvicted = true; return removeContent(); @@ -170,7 +165,7 @@ bool success = InspectorPageAgent::sharedBufferContent(m_dataBuffer, m_mimeType, m_textEncodingName, &m_content, &m_base64Encoded); DCHECK(success); m_dataBuffer = nullptr; - return contentSizeInBytes(m_content) - dataLength; + return m_content.charactersSizeInBytes() - dataLength; } // NetworkResourcesData @@ -243,7 +238,7 @@ ResourceData* resourceData = resourceDataForRequestId(requestId); if (!resourceData) return; - size_t dataLength = contentSizeInBytes(content); + size_t dataLength = content.charactersSizeInBytes(); if (dataLength > m_maximumSingleResourceContentSize) return; if (resourceData->isContentEvicted()) @@ -282,7 +277,7 @@ if (!resourceData->hasData()) return; m_contentSize += resourceData->decodeDataToContent(); - size_t dataLength = contentSizeInBytes(resourceData->content()); + size_t dataLength = resourceData->content().charactersSizeInBytes(); if (dataLength > m_maximumSingleResourceContentSize) m_contentSize -= resourceData->evictContent(); }
diff --git a/third_party/WebKit/Source/core/inspector/NetworkResourcesData.h b/third_party/WebKit/Source/core/inspector/NetworkResourcesData.h index 57115410..86c60cc 100644 --- a/third_party/WebKit/Source/core/inspector/NetworkResourcesData.h +++ b/third_party/WebKit/Source/core/inspector/NetworkResourcesData.h
@@ -98,9 +98,9 @@ bool base64Encoded() const { return m_base64Encoded; } - unsigned removeContent(); + size_t removeContent(); bool isContentEvicted() const { return m_isContentEvicted; } - unsigned evictContent(); + size_t evictContent(); InspectorPageAgent::ResourceType type() const { return m_type; } void setType(InspectorPageAgent::ResourceType type) { m_type = type; }
diff --git a/third_party/WebKit/Source/core/inspector/ThreadDebugger.cpp b/third_party/WebKit/Source/core/inspector/ThreadDebugger.cpp index 0a6ccae..7ce90d0 100644 --- a/third_party/WebKit/Source/core/inspector/ThreadDebugger.cpp +++ b/third_party/WebKit/Source/core/inspector/ThreadDebugger.cpp
@@ -108,13 +108,13 @@ m_v8Inspector->asyncTaskFinished(task); } -unsigned ThreadDebugger::promiseRejected(v8::Local<v8::Context> context, const String16& errorMessage, v8::Local<v8::Value> exception, std::unique_ptr<SourceLocation> location) +unsigned ThreadDebugger::promiseRejected(v8::Local<v8::Context> context, const String& errorMessage, v8::Local<v8::Value> exception, std::unique_ptr<SourceLocation> location) { - const String16 defaultMessage = "Uncaught (in promise)"; - String16 message = errorMessage; + const String defaultMessage = "Uncaught (in promise)"; + String message = errorMessage; if (message.isEmpty()) message = defaultMessage; - else if (message.startWith("Uncaught ")) + else if (message.startsWith("Uncaught ")) message = message.substring(0, 8) + " (in promise)" + message.substring(8); reportConsoleMessage(toExecutionContext(context), JSMessageSource, ErrorMessageLevel, message, location.get()); @@ -123,7 +123,7 @@ void ThreadDebugger::promiseRejectionRevoked(v8::Local<v8::Context> context, unsigned promiseRejectionId) { - const String16 message = "Handler added to rejected promise"; + const String message = "Handler added to rejected promise"; v8Inspector()->exceptionRevoked(context, promiseRejectionId, message); }
diff --git a/third_party/WebKit/Source/core/inspector/ThreadDebugger.h b/third_party/WebKit/Source/core/inspector/ThreadDebugger.h index 3839abb2..07993bc 100644 --- a/third_party/WebKit/Source/core/inspector/ThreadDebugger.h +++ b/third_party/WebKit/Source/core/inspector/ThreadDebugger.h
@@ -43,7 +43,7 @@ void allAsyncTasksCanceled(); void asyncTaskStarted(void* task); void asyncTaskFinished(void* task); - unsigned promiseRejected(v8::Local<v8::Context>, const String16& errorMessage, v8::Local<v8::Value> exception, std::unique_ptr<SourceLocation>); + unsigned promiseRejected(v8::Local<v8::Context>, const String& errorMessage, v8::Local<v8::Value> exception, std::unique_ptr<SourceLocation>); void promiseRejectionRevoked(v8::Local<v8::Context>, unsigned promiseRejectionId); protected:
diff --git a/third_party/WebKit/Source/core/inspector/WorkerInspectorController.cpp b/third_party/WebKit/Source/core/inspector/WorkerInspectorController.cpp index 92f2a773..8575b46 100644 --- a/third_party/WebKit/Source/core/inspector/WorkerInspectorController.cpp +++ b/third_party/WebKit/Source/core/inspector/WorkerInspectorController.cpp
@@ -38,7 +38,7 @@ #include "core/workers/WorkerReportingProxy.h" #include "core/workers/WorkerThread.h" #include "platform/WebThreadSupportingGC.h" -#include "platform/inspector_protocol/DispatcherBase.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "platform/v8_inspector/public/V8Inspector.h" #include "platform/v8_inspector/public/V8InspectorSession.h"
diff --git a/third_party/WebKit/Source/core/inspector/browser_protocol.json b/third_party/WebKit/Source/core/inspector/browser_protocol.json index df48813..104cb9e2 100644 --- a/third_party/WebKit/Source/core/inspector/browser_protocol.json +++ b/third_party/WebKit/Source/core/inspector/browser_protocol.json
@@ -3927,7 +3927,6 @@ "properties": [ { "name": "delay", "type": "number", "description": "<code>AnimationEffect</code>'s delay." }, { "name": "endDelay", "type": "number", "description": "<code>AnimationEffect</code>'s end delay." }, - { "name": "playbackRate", "type": "number", "description": "<code>AnimationEffect</code>'s playbackRate." }, { "name": "iterationStart", "type": "number", "description": "<code>AnimationEffect</code>'s iteration start." }, { "name": "iterations", "type": "number", "description": "<code>AnimationEffect</code>'s iterations." }, { "name": "duration", "type": "number", "description": "<code>AnimationEffect</code>'s iteration duration." },
diff --git a/third_party/WebKit/Source/core/inspector/inspector.gyp b/third_party/WebKit/Source/core/inspector/inspector.gyp index a67b70e..435067f 100644 --- a/third_party/WebKit/Source/core/inspector/inspector.gyp +++ b/third_party/WebKit/Source/core/inspector/inspector.gyp
@@ -52,16 +52,38 @@ 'action_name': 'generateInspectorProtocolBackendSources', 'inputs': [ '<@(jinja_module_files)', - # The python script in action below. - '../../platform/inspector_protocol/CodeGenerator.py', # Source code templates. + '../../platform/inspector_protocol/Allocator_h.template', + '../../platform/inspector_protocol/Array_h.template', + '../../platform/inspector_protocol/BackendCallback_h.template', + '../../platform/inspector_protocol/CodeGenerator.py', + '../../platform/inspector_protocol/Collections_h.template', + '../../platform/inspector_protocol/DispatcherBase_cpp.template', + '../../platform/inspector_protocol/DispatcherBase_h.template', + '../../platform/inspector_protocol/ErrorSupport_cpp.template', + '../../platform/inspector_protocol/ErrorSupport_h.template', '../../platform/inspector_protocol/Exported_h.template', + '../../platform/inspector_protocol/FrontendChannel_h.template', '../../platform/inspector_protocol/Imported_h.template', - '../../platform/inspector_protocol/TypeBuilder_h.template', + '../../platform/inspector_protocol/InspectorProtocol_cpp.template', + '../../platform/inspector_protocol/Maybe_h.template', + '../../platform/inspector_protocol/Object_cpp.template', + '../../platform/inspector_protocol/Object_h.template', + '../../platform/inspector_protocol/Parser_cpp.template', + '../../platform/inspector_protocol/Parser_h.template', + '../../platform/inspector_protocol/Platform_h.template', + '../../platform/inspector_protocol/String16_cpp.template', + '../../platform/inspector_protocol/String16_h.template', '../../platform/inspector_protocol/TypeBuilder_cpp.template', + '../../platform/inspector_protocol/TypeBuilder_h.template', + '../../platform/inspector_protocol/ValueConversions_h.template', + '../../platform/inspector_protocol/Values_cpp.template', + '../../platform/inspector_protocol/Values_h.template', # Protocol definition 'browser_protocol.json', '../../platform/v8_inspector/js_protocol.json', + # Config + 'inspector_protocol_config.json' ], 'outputs': [ '<(blink_core_output_dir)/inspector/protocol/Accessibility.cpp', @@ -122,13 +144,8 @@ 'action': [ 'python', '../../platform/inspector_protocol/CodeGenerator.py', - '--protocol', 'browser_protocol.json', - '--include', '../../platform/v8_inspector/js_protocol.json', - '--include_package', 'platform/v8_inspector/public/protocol', - '--string_type', 'String', - '--export_macro', 'CORE_EXPORT', - '--output_dir', '<(blink_core_output_dir)/inspector/protocol', - '--output_package', 'core/inspector/protocol', + '--output_base', '<(blink_core_output_dir)', + '--config', 'inspector_protocol_config.json', ], 'message': 'Generating Inspector protocol backend sources from json definitions', },
diff --git a/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json b/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json new file mode 100644 index 0000000..c7a4628 --- /dev/null +++ b/third_party/WebKit/Source/core/inspector/inspector_protocol_config.json
@@ -0,0 +1,23 @@ +{ + "protocol": { + "path": "browser_protocol.json", + "package": "core/inspector/protocol", + "output": "inspector/protocol" + }, + + "import": { + "path": "../../platform/v8_inspector/js_protocol.json", + "package": "platform/v8_inspector/public/protocol" + }, + + "string": { + "class_name": "WTF::String" + }, + + "lib_package": "platform/inspector_protocol", + + "class_export": { + "macro": "CORE_EXPORT", + "header_path": "core/CoreExport.h" + } +}
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp index af0e52e..3cab244a 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp
@@ -48,6 +48,7 @@ #include "core/layout/line/InlineTextBox.h" #include "core/layout/line/LineWidth.h" #include "core/layout/shapes/ShapeOutsideInfo.h" +#include "core/paint/BlockFlowPaintInvalidator.h" #include "core/paint/PaintLayer.h" #include "wtf/PtrUtil.h" #include <memory> @@ -166,6 +167,18 @@ , m_previousBreakAfterValue(BreakAuto) , m_isAtFirstInFlowChild(true) { } + // Store multicol layout state before first layout of a block child. The child may contain a + // column spanner. If we need to re-lay out the block child because our initial logical top + // estimate was wrong, we need to roll back to how things were before laying out the child. + void storeMultiColumnLayoutState(const LayoutFlowThread& flowThread) + { + m_multiColumnLayoutState = flowThread.multiColumnLayoutState(); + } + void rollBackToInitialMultiColumnLayoutState(LayoutFlowThread& flowThread) + { + flowThread.restoreMultiColumnLayoutState(m_multiColumnLayoutState); + } + const MarginInfo& marginInfo() const { return m_marginInfo; } MarginInfo& marginInfo() { return m_marginInfo; } LayoutUnit& previousFloatLogicalBottom() { return m_previousFloatLogicalBottom; } @@ -177,6 +190,7 @@ void clearIsAtFirstInFlowChild() { m_isAtFirstInFlowChild = false; } private: + MultiColumnLayoutState m_multiColumnLayoutState; MarginInfo m_marginInfo; LayoutUnit m_previousFloatLogicalBottom; EBreak m_previousBreakAfterValue; @@ -623,6 +637,9 @@ bool LayoutBlockFlow::positionAndLayoutOnceIfNeeded(LayoutBox& child, LayoutUnit newLogicalTop, BlockChildrenLayoutInfo& layoutInfo) { + if (LayoutFlowThread* flowThread = flowThreadContainingBlock()) + layoutInfo.rollBackToInitialMultiColumnLayoutState(*flowThread); + if (child.isLayoutBlockFlow()) { LayoutUnit& previousFloatLogicalBottom = layoutInfo.previousFloatLogicalBottom(); LayoutBlockFlow& childBlockFlow = toLayoutBlockFlow(child); @@ -698,6 +715,9 @@ // Cache our old rect so that we can dirty the proper paint invalidation rects if the child moves. LayoutRect oldRect = child.frameRect(); + if (LayoutFlowThread* flowThread = flowThreadContainingBlock()) + layoutInfo.storeMultiColumnLayoutState(*flowThread); + // Use the estimated block position and lay out the child if needed. After child layout, when // we have enough information to perform proper margin collapsing, float clearing and // pagination, we may have to reposition and lay out again if the estimate was wrong. @@ -3781,4 +3801,9 @@ inlineElementContinuation->addOutlineRects(rects, additionalOffset + (inlineElementContinuation->containingBlock()->location() - location()), includeBlockOverflows); } +PaintInvalidationReason LayoutBlockFlow::invalidatePaintIfNeeded(const PaintInvalidatorContext& context) const +{ + return BlockFlowPaintInvalidator(*this, context).invalidatePaintIfNeeded(); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h index a2547141..1aad8d3 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h +++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h
@@ -343,6 +343,7 @@ bool paintedOutputOfObjectHasNoEffect() const override; PaintInvalidationReason invalidatePaintIfNeeded(const PaintInvalidationState&) override; + PaintInvalidationReason invalidatePaintIfNeeded(const PaintInvalidatorContext&) const override; Node* nodeForHitTest() const final; bool hitTestChildren(HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override;
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp index 6d210be..03b7947 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlowLine.cpp
@@ -2076,18 +2076,7 @@ if (containsFloats()) paintInvalidationState.paintingLayer().setNeedsPaintPhaseFloat(); - PaintInvalidationReason reason = LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); - if (reason == PaintInvalidationNone || reason == PaintInvalidationDelayedFull) - return reason; - - RootInlineBox* line = firstRootBox(); - if (!line || !line->isFirstLineStyle()) - return reason; - // It's the RootInlineBox that paints the ::first-line background. Note that since it may be - // expensive to figure out if the first line is affected by any ::first-line selectors at all, - // we just invalidate it unconditionally, since that's typically cheaper. - invalidateDisplayItemClient(*line, reason); - return reason; + return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp index 0f97f057..b2de1e3 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -54,6 +54,7 @@ #include "core/page/Page.h" #include "core/page/scrolling/SnapCoordinator.h" #include "core/paint/BackgroundImageGeometry.h" +#include "core/paint/BoxPaintInvalidator.h" #include "core/paint/BoxPainter.h" #include "core/paint/PaintLayer.h" #include "core/style/ShadowList.h" @@ -132,6 +133,8 @@ ShapeOutsideInfo::removeInfo(*this); + BoxPaintInvalidator::boxWillBeDestroyed(*this); + LayoutBoxModelObject::willBeDestroyed(); } @@ -1008,19 +1011,35 @@ return result; } + +LayoutRect LayoutBox::clippingRect() const +{ + LayoutRect result = LayoutRect(LayoutRect::infiniteIntRect()); + if (hasOverflowClip() || style()->containsPaint()) + result = overflowClipRect(LayoutPoint()); + + if (hasClip()) + result.intersect(clipRect(LayoutPoint())); + + return result; +} + bool LayoutBox::mapScrollingContentsRectToBoxSpace(LayoutRect& rect, ApplyOverflowClipFlag applyOverflowClip, VisualRectFlags visualRectFlags) const { - if (!hasOverflowClip()) + if (!hasClipRelatedProperty()) return true; - if (applyOverflowClip == ApplyNonScrollOverflowClip && scrollsOverflow()) { + if (applyOverflowClip == ApplyNonScrollOverflowClip && scrollsOverflow()) return true; + + if (hasOverflowClip()) { + LayoutSize offset = LayoutSize(-scrolledContentOffset()); + rect.move(offset); } - LayoutSize offset = LayoutSize(-scrolledContentOffset()); - rect.move(offset); - - LayoutRect clipRect = overflowClipRect(LayoutPoint()); + // This won't work fully correctly for fixed-position elements, who should receive CSS clip but for whom the current object + // is not in the containing block chain. + LayoutRect clipRect = clippingRect(); bool doesIntersect; if (visualRectFlags & EdgeInclusive) { @@ -1029,6 +1048,7 @@ rect.intersect(clipRect); doesIntersect = !rect.isEmpty(); } + return doesIntersect; } @@ -1481,10 +1501,30 @@ void LayoutBox::imageChanged(WrappedImagePtr image, const IntRect*) { // TODO(chrishtr): support PaintInvalidationDelayedFull for animated border images. - if ((style()->borderImage().image() && style()->borderImage().image()->data() == image) - || (style()->maskBoxImage().image() && style()->maskBoxImage().image()->data() == image)) { + if ((styleRef().borderImage().image() && styleRef().borderImage().image()->data() == image) + || (styleRef().maskBoxImage().image() && styleRef().maskBoxImage().image()->data() == image)) { setShouldDoFullPaintInvalidation(); - return; + } else { + for (const FillLayer* layer = &styleRef().maskLayers(); layer; layer = layer->next()) { + if (layer->image() && image == layer->image()->data()) { + setShouldDoFullPaintInvalidation(); + break; + } + } + } + + if (!isDocumentElement() && !backgroundStolenForBeingBody()) { + for (const FillLayer* layer = &styleRef().backgroundLayers(); layer; layer = layer->next()) { + if (layer->image() && image == layer->image()->data()) { + invalidateBackgroundObscurationStatus(); + bool maybeAnimated = layer->image()->cachedImage() && layer->image()->cachedImage()->getImage() && layer->image()->cachedImage()->getImage()->maybeAnimated(); + if (maybeAnimated) + setMayNeedPaintInvalidationAnimatgedBackgroundImage(); + else + setShouldDoFullPaintInvalidation(); + break; + } + } } ShapeValue* shapeOutsideValue = style()->shapeOutside(); @@ -1495,9 +1535,6 @@ markShapeOutsideDependentsForLayout(); } } - - if (!invalidatePaintOfLayerRectsForImage(image, style()->backgroundLayers(), true)) - invalidatePaintOfLayerRectsForImage(image, style()->maskLayers(), false); } ResourcePriority LayoutBox::computeResourcePriority() const @@ -1525,27 +1562,7 @@ return ResourcePriority(isVisible ? ResourcePriority::Visible : ResourcePriority::NotVisible, screenArea); } -bool LayoutBox::invalidatePaintOfLayerRectsForImage(WrappedImagePtr image, const FillLayer& layers, bool drawingBackground) -{ - if (drawingBackground && (isDocumentElement() || backgroundStolenForBeingBody())) - return false; - for (const FillLayer* curLayer = &layers; curLayer; curLayer = curLayer->next()) { - if (curLayer->image() && image == curLayer->image()->data()) { - bool maybeAnimated = curLayer->image()->cachedImage() && curLayer->image()->cachedImage()->getImage() && curLayer->image()->cachedImage()->getImage()->maybeAnimated(); - if (maybeAnimated && drawingBackground) - setShouldDoFullPaintInvalidation(PaintInvalidationDelayedFull); - else - setShouldDoFullPaintInvalidation(); - - if (drawingBackground) - invalidateBackgroundObscurationStatus(); - return true; - } - } - return false; -} - -bool LayoutBox::intersectsVisibleViewport() +bool LayoutBox::intersectsVisibleViewport() const { LayoutRect rect = visualOverflowRect(); LayoutView* layoutView = view(); @@ -1565,26 +1582,12 @@ layer.setNeedsPaintPhaseDescendantBlockBackgrounds(); } - PaintInvalidationReason fullInvalidationReason = fullPaintInvalidationReason(); - // If the current paint invalidation reason is PaintInvalidationDelayedFull, then this paint invalidation can delayed if the - // LayoutBox in question is not on-screen. The logic to decide whether this is appropriate exists at the site of the original - // paint invalidation that chose PaintInvalidationDelayedFull. - if (fullInvalidationReason == PaintInvalidationDelayedFull) { - if (!intersectsVisibleViewport()) - return PaintInvalidationDelayedFull; + return LayoutBoxModelObject::invalidatePaintIfNeeded(paintInvalidationState); +} - // Reset state back to regular full paint invalidation if the object is onscreen. - setShouldDoFullPaintInvalidation(PaintInvalidationFull); - } - - PaintInvalidationReason reason = LayoutBoxModelObject::invalidatePaintIfNeeded(paintInvalidationState); - - if (PaintLayerScrollableArea* area = getScrollableArea()) - area->invalidatePaintOfScrollControlsIfNeeded(paintInvalidationState); - - // This is for the next invalidatePaintIfNeeded so must be at the end. - savePreviousBoxSizesIfNeeded(); - return reason; +PaintInvalidationReason LayoutBox::invalidatePaintIfNeeded(const PaintInvalidatorContext& context) const +{ + return BoxPaintInvalidator(*this, context).invalidatePaintIfNeeded(); } void LayoutBox::invalidatePaintOfSubtreesIfNeeded(const PaintInvalidationState& childPaintInvalidationState) @@ -3981,161 +3984,6 @@ return false; } -PaintInvalidationReason LayoutBox::getPaintInvalidationReason(const PaintInvalidationState& paintInvalidationState, - const LayoutRect& oldBounds, const LayoutPoint& oldLocation, const LayoutRect& newBounds, const LayoutPoint& newLocation) const -{ - PaintInvalidationReason invalidationReason = LayoutBoxModelObject::getPaintInvalidationReason(paintInvalidationState, oldBounds, oldLocation, newBounds, newLocation); - if (isFullPaintInvalidationReason(invalidationReason)) - return invalidationReason; - - if (isLayoutView()) { - const LayoutView* layoutView = toLayoutView(this); - // In normal compositing mode, root background doesn't need to be invalidated for - // box changes, because the background always covers the whole document rect - // and clipping is done by compositor()->m_containerLayer. Also the scrollbars - // are always composited. There are no other box decoration on the LayoutView thus - // we can safely exit here. - if (layoutView->usesCompositing() && (!document().settings() || !document().settings()->rootLayerScrolls())) - return invalidationReason; - } - - // If the transform is not identity or translation, incremental invalidation is not applicable - // because the difference between oldBounds and newBounds doesn't cover all area needing invalidation. - // FIXME: Should also consider ancestor transforms since paintInvalidationContainer. crbug.com/426111. - if (invalidationReason == PaintInvalidationIncremental - && paintInvalidationState.paintInvalidationContainer() != this - && hasLayer() && layer()->transform() && !layer()->transform()->isIdentityOrTranslation()) - return PaintInvalidationBoundsChange; - - if (style()->backgroundLayers().thisOrNextLayersUseContentBox() || style()->maskLayers().thisOrNextLayersUseContentBox() || style()->boxSizing() == BoxSizingBorderBox) { - LayoutRect oldContentBoxRect = m_rareData ? m_rareData->m_previousContentBoxRect : LayoutRect(); - LayoutRect newContentBoxRect = contentBoxRect(); - if (oldContentBoxRect != newContentBoxRect) - return PaintInvalidationContentBoxChange; - } - - if (!style()->hasBackground() && !style()->hasBoxDecorations()) { - // We could let incremental invalidation cover non-composited scrollbars, but just - // do a full invalidation because incremental invalidation will go away with slimming paint. - if (invalidationReason == PaintInvalidationIncremental && hasNonCompositedScrollbars()) - return PaintInvalidationBorderBoxChange; - return invalidationReason; - } - - if (style()->backgroundLayers().thisOrNextLayersHaveLocalAttachment()) { - LayoutRect oldLayoutOverflowRect = m_rareData ? m_rareData->m_previousLayoutOverflowRect : LayoutRect(); - LayoutRect newLayoutOverflowRect = layoutOverflowRect(); - if (oldLayoutOverflowRect != newLayoutOverflowRect) - return PaintInvalidationLayoutOverflowBoxChange; - } - - LayoutSize oldBorderBoxSize = computePreviousBorderBoxSize(oldBounds.size()); - LayoutSize newBorderBoxSize = size(); - - if (oldBorderBoxSize == newBorderBoxSize) - return invalidationReason; - - // LayoutBox::incrementallyInvalidatePaint() depends on positionFromPaintInvalidationBacking - // which is not available when slimmingPaintOffsetCachingEnabled. - if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() && (style()->hasBoxDecorations() || style()->hasBackground())) - return PaintInvalidationBorderBoxChange; - - // TODO(wangxianzhu): Remove incremental invalidation when we remove rect-based paint invalidation. - // See another hasNonCompositedScrollbars() callsite above. - if (hasNonCompositedScrollbars()) - return PaintInvalidationBorderBoxChange; - - if (style()->hasVisualOverflowingEffect() || style()->hasAppearance() || style()->hasFilterInducingProperty() || style()->resize() != RESIZE_NONE) - return PaintInvalidationBorderBoxChange; - - if (style()->hasBorderRadius()) { - // If a border-radius exists and width/height is smaller than radius width/height, - // we need to fully invalidate to cover the changed radius. - FloatRoundedRect oldRoundedRect = style()->getRoundedBorderFor(LayoutRect(LayoutPoint(0, 0), oldBorderBoxSize)); - FloatRoundedRect newRoundedRect = style()->getRoundedBorderFor(LayoutRect(LayoutPoint(0, 0), newBorderBoxSize)); - if (oldRoundedRect.getRadii() != newRoundedRect.getRadii()) - return PaintInvalidationBorderBoxChange; - } - - if (oldBorderBoxSize.width() != newBorderBoxSize.width() && mustInvalidateBackgroundOrBorderPaintOnWidthChange()) - return PaintInvalidationBorderBoxChange; - if (oldBorderBoxSize.height() != newBorderBoxSize.height() && mustInvalidateBackgroundOrBorderPaintOnHeightChange()) - return PaintInvalidationBorderBoxChange; - - return styleRef().hasBackground() || styleRef().hasBoxDecorations() ? PaintInvalidationIncremental : invalidationReason; -} - -void LayoutBox::incrementallyInvalidatePaint(const LayoutBoxModelObject& paintInvalidationContainer, const LayoutRect& oldBounds, const LayoutRect& newBounds, const LayoutPoint& positionFromPaintInvalidationBacking) -{ - LayoutObject::incrementallyInvalidatePaint(paintInvalidationContainer, oldBounds, newBounds, positionFromPaintInvalidationBacking); - - bool hasBoxDecorations = style()->hasBoxDecorations(); - if (!style()->hasBackground() && !hasBoxDecorations) - return; - - LayoutSize oldBorderBoxSize = computePreviousBorderBoxSize(oldBounds.size()); - LayoutSize newBorderBoxSize = size(); - - // If border box size didn't change, LayoutObject's incrementallyInvalidatePaint() is good. - if (oldBorderBoxSize == newBorderBoxSize) - return; - - // If size of the paint invalidation rect equals to size of border box, LayoutObject::incrementallyInvalidatePaint() - // is good for boxes having background without box decorations. - ASSERT(oldBounds.location() == newBounds.location()); // Otherwise we won't do incremental invalidation. - if (!hasBoxDecorations - && positionFromPaintInvalidationBacking == newBounds.location() - && oldBorderBoxSize == oldBounds.size() - && newBorderBoxSize == newBounds.size()) - return; - - // Invalidate the right delta part and the right border of the old or new box which has smaller width. - LayoutUnit deltaWidth = absoluteValue(oldBorderBoxSize.width() - newBorderBoxSize.width()); - if (deltaWidth) { - LayoutUnit smallerWidth = std::min(oldBorderBoxSize.width(), newBorderBoxSize.width()); - LayoutUnit borderTopRightRadiusWidth = valueForLength(style()->borderTopRightRadius().width(), smallerWidth); - LayoutUnit borderBottomRightRadiusWidth = valueForLength(style()->borderBottomRightRadius().width(), smallerWidth); - LayoutUnit borderWidth = std::max(LayoutUnit(borderRight()), std::max(borderTopRightRadiusWidth, borderBottomRightRadiusWidth)); - LayoutRect rightDeltaRect(positionFromPaintInvalidationBacking.x() + smallerWidth - borderWidth, - positionFromPaintInvalidationBacking.y(), - deltaWidth + borderWidth, - std::max(oldBorderBoxSize.height(), newBorderBoxSize.height())); - invalidatePaintRectClippedByOldAndNewBounds(paintInvalidationContainer, rightDeltaRect, oldBounds, newBounds); - } - - // Invalidate the bottom delta part and the bottom border of the old or new box which has smaller height. - LayoutUnit deltaHeight = absoluteValue(oldBorderBoxSize.height() - newBorderBoxSize.height()); - if (deltaHeight) { - LayoutUnit smallerHeight = std::min(oldBorderBoxSize.height(), newBorderBoxSize.height()); - LayoutUnit borderBottomLeftRadiusHeight = valueForLength(style()->borderBottomLeftRadius().height(), smallerHeight); - LayoutUnit borderBottomRightRadiusHeight = valueForLength(style()->borderBottomRightRadius().height(), smallerHeight); - LayoutUnit borderHeight = std::max(LayoutUnit(borderBottom()), std::max(borderBottomLeftRadiusHeight, borderBottomRightRadiusHeight)); - LayoutRect bottomDeltaRect(positionFromPaintInvalidationBacking.x(), - positionFromPaintInvalidationBacking.y() + smallerHeight - borderHeight, - std::max(oldBorderBoxSize.width(), newBorderBoxSize.width()), - deltaHeight + borderHeight); - invalidatePaintRectClippedByOldAndNewBounds(paintInvalidationContainer, bottomDeltaRect, oldBounds, newBounds); - } -} - -void LayoutBox::invalidatePaintRectClippedByOldAndNewBounds(const LayoutBoxModelObject& paintInvalidationContainer, const LayoutRect& rect, const LayoutRect& oldBounds, const LayoutRect& newBounds) -{ - if (rect.isEmpty()) - return; - LayoutRect rectClippedByOldBounds = intersection(rect, oldBounds); - LayoutRect rectClippedByNewBounds = intersection(rect, newBounds); - // Invalidate only once if the clipped rects equal. - if (rectClippedByOldBounds == rectClippedByNewBounds) { - invalidatePaintUsingContainer(paintInvalidationContainer, rectClippedByOldBounds, PaintInvalidationIncremental); - return; - } - // Invalidate the bigger one if one contains another. Otherwise invalidate both. - if (!rectClippedByNewBounds.contains(rectClippedByOldBounds)) - invalidatePaintUsingContainer(paintInvalidationContainer, rectClippedByOldBounds, PaintInvalidationIncremental); - if (!rectClippedByOldBounds.contains(rectClippedByNewBounds)) - invalidatePaintUsingContainer(paintInvalidationContainer, rectClippedByNewBounds, PaintInvalidationIncremental); -} - void LayoutBox::markForPaginationRelayoutIfNeeded(SubtreeLayoutScope& layoutScope) { ASSERT(!needsLayout()); @@ -4658,63 +4506,6 @@ ensureRareData().m_pageLogicalOffset = offset; } -bool LayoutBox::needToSavePreviousBoxSizes() -{ - // If m_rareData is already created, always save. - if (m_rareData) - return true; - - LayoutSize paintInvalidationSize = previousPaintInvalidationRectSize(); - // Don't save old box sizes if the paint rect is empty because we'll - // full invalidate once the paint rect becomes non-empty. - if (paintInvalidationSize.isEmpty()) - return false; - - // If we use border-box sizing we need to track changes in the size of the content box. - if (style()->boxSizing() == BoxSizingBorderBox) - return true; - - // We need the old box sizes only when the box has background, decorations, or masks. - // Main LayoutView paints base background, thus interested in box size. - if (!isLayoutView() && !style()->hasBackground() && !style()->hasBoxDecorations() && !style()->hasMask()) - return false; - - // No need to save old border box size if we can use size of the old paint - // rect as the old border box size in the next invalidation. - if (paintInvalidationSize != size()) - return true; - - // Background and mask layers can depend on other boxes than border box. See crbug.com/490533 - if (style()->backgroundLayers().thisOrNextLayersUseContentBox() || style()->backgroundLayers().thisOrNextLayersHaveLocalAttachment() - || style()->maskLayers().thisOrNextLayersUseContentBox()) - return true; - - return false; -} - -void LayoutBox::savePreviousBoxSizesIfNeeded() -{ - if (!needToSavePreviousBoxSizes()) - return; - - LayoutBoxRareData& rareData = ensureRareData(); - rareData.m_previousBorderBoxSize = size(); - rareData.m_previousContentBoxRect = contentBoxRect(); - rareData.m_previousLayoutOverflowRect = layoutOverflowRect(); -} - -LayoutSize LayoutBox::computePreviousBorderBoxSize(const LayoutSize& previousBoundsSize) const -{ - // PreviousBorderBoxSize is only valid when there is background or box decorations. - ASSERT(style()->hasBackground() || style()->hasBoxDecorations()); - - if (m_rareData && m_rareData->m_previousBorderBoxSize.width() != -1) - return m_rareData->m_previousBorderBoxSize; - - // We didn't save the old border box size because it was the same as the size of oldBounds. - return previousBoundsSize; -} - void LayoutBox::logicalExtentAfterUpdatingLogicalWidth(const LayoutUnit& newLogicalTop, LayoutBox::LogicalExtentComputedValues& computedValues) { // FIXME: None of this is right for perpendicular writing-mode children. @@ -4739,7 +4530,7 @@ setMarginRight(oldMarginRight); } -bool LayoutBox::mustInvalidateFillLayersPaintOnHeightChange(const FillLayer& layer) const +bool LayoutBox::mustInvalidateFillLayersPaintOnHeightChange(const FillLayer& layer) { // Nobody will use multiple layers without wanting fancy positioning. if (layer.next()) @@ -4778,7 +4569,7 @@ return false; } -bool LayoutBox::mustInvalidateFillLayersPaintOnWidthChange(const FillLayer& layer) const +bool LayoutBox::mustInvalidateFillLayersPaintOnWidthChange(const FillLayer& layer) { // Nobody will use multiple layers without wanting fancy positioning. if (layer.next())
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.h b/third_party/WebKit/Source/core/layout/LayoutBox.h index 99c342b..e92d002 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBox.h +++ b/third_party/WebKit/Source/core/layout/LayoutBox.h
@@ -63,7 +63,6 @@ : m_spannerPlaceholder(nullptr) , m_overrideLogicalContentHeight(-1) , m_overrideLogicalContentWidth(-1) - , m_previousBorderBoxSize(LayoutUnit(-1), LayoutUnit(-1)) , m_percentHeightContainer(nullptr) , m_snapContainer(nullptr) , m_snapAreas(nullptr) @@ -76,13 +75,7 @@ LayoutUnit m_overrideLogicalContentHeight; LayoutUnit m_overrideLogicalContentWidth; - // Set by LayoutBox::savePreviousBoxSizesIfNeeded(). - LayoutSize m_previousBorderBoxSize; - LayoutRect m_previousContentBoxRect; - LayoutRect m_previousLayoutOverflowRect; - LayoutUnit m_pageLogicalOffset; - LayoutUnit m_paginationStrut; LayoutBlock* m_percentHeightContainer; @@ -803,6 +796,9 @@ virtual bool hasControlClip() const { return false; } virtual LayoutRect controlClipRect(const LayoutPoint&) const { return LayoutRect(); } + // Returns the combination of overflow clip, contain: paint clip and CSS clip for this object, in local space. + LayoutRect clippingRect() const; + virtual void paintBoxDecorationBackground(const PaintInfo&, const LayoutPoint&) const; virtual void paintMask(const PaintInfo&, const LayoutPoint&) const; void imageChanged(WrappedImagePtr, const IntRect* = nullptr) override; @@ -966,8 +962,16 @@ bool hitTestClippedOutByRoundedBorder(const HitTestLocation& locationInContainer, const LayoutPoint& borderBoxLocation) const; - bool mustInvalidateFillLayersPaintOnWidthChange(const FillLayer&) const; - bool mustInvalidateFillLayersPaintOnHeightChange(const FillLayer&) const; + static bool mustInvalidateFillLayersPaintOnWidthChange(const FillLayer&); + static bool mustInvalidateFillLayersPaintOnHeightChange(const FillLayer&); + + bool mustInvalidateBackgroundOrBorderPaintOnHeightChange() const; + bool mustInvalidateBackgroundOrBorderPaintOnWidthChange() const; + + // Returns true if the box intersects the viewport visible to the user. + bool intersectsVisibleViewport() const; + + bool hasNonCompositedScrollbars() const final; protected: void willBeDestroyed() override; @@ -999,17 +1003,12 @@ void addLayerHitTestRects(LayerHitTestRects&, const PaintLayer* currentCompositedLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const override; void computeSelfHitTestRects(Vector<LayoutRect>&, const LayoutPoint& layerOffset) const override; - PaintInvalidationReason getPaintInvalidationReason(const PaintInvalidationState&, - const LayoutRect& oldBounds, const LayoutPoint& oldPositionFromPaintInvalidationContainer, - const LayoutRect& newBounds, const LayoutPoint& newPositionFromPaintInvalidationContainer) const override; - void incrementallyInvalidatePaint(const LayoutBoxModelObject& paintInvalidationContainer, const LayoutRect& oldBounds, const LayoutRect& newBounds, const LayoutPoint& positionFromPaintInvalidationContainer) override; - PaintInvalidationReason invalidatePaintIfNeeded(const PaintInvalidationState&) override; + PaintInvalidationReason invalidatePaintIfNeeded(const PaintInvalidatorContext&) const override; void invalidatePaintOfSubtreesIfNeeded(const PaintInvalidationState& childPaintInvalidationState) override; bool hasStretchedLogicalWidth() const; - bool hasNonCompositedScrollbars() const final; void excludeScrollbars(LayoutRect&, OverlayScrollbarClipBehavior = IgnoreOverlayScrollbarSize) const; LayoutUnit containingBlockLogicalWidthForPositioned(const LayoutBoxModelObject* containingBlock, bool checkForPerpendicularWritingMode = true) const; @@ -1021,11 +1020,6 @@ static void computeLogicalTopPositionedOffset(LayoutUnit& logicalTopPos, const LayoutBox* child, LayoutUnit logicalHeightValue, const LayoutBoxModelObject* containerBlock, LayoutUnit containerLogicalHeight); private: - bool mustInvalidateBackgroundOrBorderPaintOnHeightChange() const; - bool mustInvalidateBackgroundOrBorderPaintOnWidthChange() const; - - void invalidatePaintRectClippedByOldAndNewBounds(const LayoutBoxModelObject& paintInvalidationContainer, const LayoutRect&, const LayoutRect& oldBounds, const LayoutRect& newBounds); - void updateShapeOutsideInfoAfterStyleChange(const ComputedStyle&, const ComputedStyle* oldStyle); void updateGridPositionAfterStyleChange(const ComputedStyle*); void updateScrollSnapMappingAfterStyleChange(const ComputedStyle*, const ComputedStyle* oldStyle); @@ -1035,9 +1029,6 @@ bool autoWidthShouldFitContent() const; LayoutUnit shrinkToFitLogicalWidth(LayoutUnit availableLogicalWidth, LayoutUnit bordersPlusPadding) const; - // Returns true if we queued up a paint invalidation. - bool invalidatePaintOfLayerRectsForImage(WrappedImagePtr, const FillLayer&, bool drawingBackground); - bool stretchesToViewportInQuirksMode() const; bool skipContainingBlockForPercentHeightCalculation(const LayoutBox* containingBlock) const; @@ -1081,10 +1072,6 @@ return *m_rareData.get(); } - bool needToSavePreviousBoxSizes(); - void savePreviousBoxSizesIfNeeded(); - LayoutSize computePreviousBorderBoxSize(const LayoutSize& previousBoundsSize) const; - bool logicalHeightComputesAsNone(SizeType) const; bool isBox() const = delete; // This will catch anyone doing an unnecessary check. @@ -1097,9 +1084,6 @@ setMayNeedPaintInvalidation(); } - // Returns true if the box intersects the viewport visible to the user. - bool intersectsVisibleViewport(); - virtual bool isInSelfHitTestingPhase(HitTestAction hitTestAction) const { return hitTestAction == HitTestForeground; } void updateBackgroundAttachmentFixedStatusAfterStyleChange();
diff --git a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp index 3ea4a886..560fe89 100644 --- a/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutBoxModelObject.cpp
@@ -379,7 +379,7 @@ void LayoutBoxModelObject::invalidateTreeIfNeeded(const PaintInvalidationState& paintInvalidationState) { - ASSERT(!needsLayout()); + ensureIsReadyForPaintInvalidation(); PaintInvalidationState newPaintInvalidationState(paintInvalidationState, *this); if (!shouldCheckForPaintInvalidation(newPaintInvalidationState)) @@ -391,7 +391,7 @@ LayoutRect previousPaintInvalidationRect = this->previousPaintInvalidationRect(); LayoutPoint previousPosition = previousPositionFromPaintInvalidationBacking(); PaintInvalidationReason reason = invalidatePaintIfNeeded(newPaintInvalidationState); - clearPaintInvalidationFlags(newPaintInvalidationState); + clearPaintInvalidationFlags(); if (previousPosition != previousPositionFromPaintInvalidationBacking()) newPaintInvalidationState.setForceSubtreeInvalidationCheckingWithinContainer(); @@ -434,6 +434,12 @@ } else if (object.compositedScrollsWithRespectTo(*this)) { layer()->compositedLayerMapping()->setScrollingContentsNeedDisplayInRect(r, invalidationReason, object); } else if (usesCompositedScrolling()) { + if (layer()->compositedLayerMapping()->shouldPaintBackgroundOntoScrollingContentsLayer()) { + // TODO(flackr): Get a correct rect in the context of the scrolling contents layer to update + // rather than updating the entire rect. + const LayoutRect& scrollingContentsRect = toLayoutBox(this)->layoutOverflowRect(); + layer()->compositedLayerMapping()->setScrollingContentsNeedDisplayInRect(scrollingContentsRect, invalidationReason, object); + } layer()->compositedLayerMapping()->setNonScrollingContentsNeedDisplayInRect(r, invalidationReason, object); } else { // Otherwise invalidate everything.
diff --git a/third_party/WebKit/Source/core/layout/LayoutFlowThread.h b/third_party/WebKit/Source/core/layout/LayoutFlowThread.h index e0bf6709..19a52b0 100644 --- a/third_party/WebKit/Source/core/layout/LayoutFlowThread.h +++ b/third_party/WebKit/Source/core/layout/LayoutFlowThread.h
@@ -41,6 +41,21 @@ typedef ListHashSet<LayoutMultiColumnSet*> LayoutMultiColumnSetList; +// Layout state for multicol. To be stored when laying out a block child, so that we can roll back +// to the initial state if we need to re-lay out said block child. +class MultiColumnLayoutState { + friend class LayoutMultiColumnFlowThread; + +public: + MultiColumnLayoutState() : m_columnSet(nullptr) { } + +private: + explicit MultiColumnLayoutState(LayoutMultiColumnSet* columnSet) : m_columnSet(columnSet) { } + LayoutMultiColumnSet* columnSet() const { return m_columnSet; } + + LayoutMultiColumnSet* m_columnSet; +}; + // LayoutFlowThread is used to collect all the layout objects that participate in a flow thread. It // will also help in doing the layout. However, it will not layout directly to screen. Instead, // LayoutMultiColumnSet objects will redirect their paint and nodeAtPoint methods to this @@ -88,6 +103,9 @@ virtual void contentWasLaidOut(LayoutUnit logicalBottomInFlowThreadAfterPagination) = 0; virtual bool canSkipLayout(const LayoutBox&) const = 0; + virtual MultiColumnLayoutState multiColumnLayoutState() const = 0; + virtual void restoreMultiColumnLayoutState(const MultiColumnLayoutState&) = 0; + // Find and return the next logical top after |flowThreadOffset| that can fit unbreakable // content as tall as |contentLogicalHeight|. |flowThreadOffset| is expected to be at the exact // top of a column that's known to not have enough space for |contentLogicalHeight|. This method
diff --git a/third_party/WebKit/Source/core/layout/LayoutHTMLCanvas.cpp b/third_party/WebKit/Source/core/layout/LayoutHTMLCanvas.cpp index ce9b4d10..134d248 100644 --- a/third_party/WebKit/Source/core/layout/LayoutHTMLCanvas.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutHTMLCanvas.cpp
@@ -30,6 +30,7 @@ #include "core/html/HTMLCanvasElement.h" #include "core/layout/LayoutView.h" #include "core/page/Page.h" +#include "core/paint/HTMLCanvasPaintInvalidator.h" #include "core/paint/HTMLCanvasPainter.h" namespace blink { @@ -83,16 +84,9 @@ setNeedsLayout(LayoutInvalidationReason::SizeChanged); } -PaintInvalidationReason LayoutHTMLCanvas::invalidatePaintIfNeeded(const PaintInvalidationState& paintInvalidationState) +PaintInvalidationReason LayoutHTMLCanvas::invalidatePaintIfNeeded(const PaintInvalidatorContext& context) const { - PaintInvalidationReason reason = LayoutBox::invalidatePaintIfNeeded(paintInvalidationState); - HTMLCanvasElement* element = toHTMLCanvasElement(node()); - if (element->isDirty()) { - element->doDeferredPaintInvalidation(); - if (reason < PaintInvalidationRectangle) - reason = PaintInvalidationRectangle; - } - return reason; + return HTMLCanvasPaintInvalidator(*this, context).invalidatePaintIfNeeded(); } CompositingReasons LayoutHTMLCanvas::additionalCompositingReasons() const
diff --git a/third_party/WebKit/Source/core/layout/LayoutHTMLCanvas.h b/third_party/WebKit/Source/core/layout/LayoutHTMLCanvas.h index ca367de0..443e4992 100644 --- a/third_party/WebKit/Source/core/layout/LayoutHTMLCanvas.h +++ b/third_party/WebKit/Source/core/layout/LayoutHTMLCanvas.h
@@ -38,7 +38,8 @@ bool isOfType(LayoutObjectType type) const override { return type == LayoutObjectCanvas || LayoutReplaced::isOfType(type); } PaintLayerType layerTypeRequired() const override; - PaintInvalidationReason invalidatePaintIfNeeded(const PaintInvalidationState&) final; + + PaintInvalidationReason invalidatePaintIfNeeded(const PaintInvalidatorContext&) const final; void canvasSizeChanged();
diff --git a/third_party/WebKit/Source/core/layout/LayoutImage.cpp b/third_party/WebKit/Source/core/layout/LayoutImage.cpp index e2c218e..41032bd 100644 --- a/third_party/WebKit/Source/core/layout/LayoutImage.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutImage.cpp
@@ -216,7 +216,7 @@ { if (!m_imageResource->hasImage() || m_imageResource->errorOccurred()) return false; - if (m_imageResource->cachedImage() && !m_imageResource->cachedImage()->isLoaded()) + if (!m_imageResource->cachedImage() || !m_imageResource->cachedImage()->isLoaded()) return false; if (!contentBoxRect().contains(localRect)) return false; @@ -234,8 +234,6 @@ ObjectFit objectFit = style()->getObjectFit(); if (objectFit != ObjectFitFill && objectFit != ObjectFitCover) return false; - if (!m_imageResource->cachedImage()) - return false; // Check for image with alpha. TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", "data", InspectorPaintImageEvent::data(this, *m_imageResource->cachedImage())); return m_imageResource->cachedImage()->getImage()->currentFrameKnownToBeOpaque(Image::PreCacheMetadata);
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp index 2e8ca57..f5ffc24 100644 --- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.cpp
@@ -1047,4 +1047,14 @@ return true; } +MultiColumnLayoutState LayoutMultiColumnFlowThread::multiColumnLayoutState() const +{ + return MultiColumnLayoutState(m_lastSetWorkedOn); +} + +void LayoutMultiColumnFlowThread::restoreMultiColumnLayoutState(const MultiColumnLayoutState& state) +{ + m_lastSetWorkedOn = state.columnSet(); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h index fa794bc..598d7669 100644 --- a/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h +++ b/third_party/WebKit/Source/core/layout/LayoutMultiColumnFlowThread.h
@@ -263,6 +263,8 @@ void updateLogicalWidth() override; void contentWasLaidOut(LayoutUnit logicalBottomInFlowThreadAfterPagination) override; bool canSkipLayout(const LayoutBox&) const override; + MultiColumnLayoutState multiColumnLayoutState() const override; + void restoreMultiColumnLayoutState(const MultiColumnLayoutState&) override; // The last set we worked on. It's not to be used as the "current set". The concept of a // "current set" is difficult, since layout may jump back and forth in the tree, due to wrong
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.cpp b/third_party/WebKit/Source/core/layout/LayoutObject.cpp index b4c72b2..4f5050a 100644 --- a/third_party/WebKit/Source/core/layout/LayoutObject.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutObject.cpp
@@ -69,6 +69,7 @@ #include "core/layout/ng/layout_ng_block_flow.h" #include "core/page/AutoscrollController.h" #include "core/page/Page.h" +#include "core/paint/ObjectPaintInvalidator.h" #include "core/paint/ObjectPaintProperties.h" #include "core/paint/PaintLayer.h" #include "core/style/ContentData.h" @@ -133,9 +134,6 @@ bool LayoutObject::s_affectsParentBlock = false; -typedef HashMap<const LayoutObject*, LayoutRect> SelectionPaintInvalidationMap; -static SelectionPaintInvalidationMap* selectionPaintInvalidationMap = nullptr; - // The pointer to paint properties is implemented as a global hash map temporarily, // to avoid memory regression during the transition towards SPv2. typedef HashMap<const LayoutObject*, std::unique_ptr<ObjectPaintProperties>> ObjectPaintPropertiesMap; @@ -240,6 +238,8 @@ if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) m_previousPositionFromPaintInvalidationBacking = uninitializedPaintOffset(); InstanceCounters::incrementCounter(InstanceCounters::LayoutObjectCounter); + if (m_node) + frameView()->incrementLayoutObjectCount(); } LayoutObject::~LayoutObject() @@ -1108,15 +1108,6 @@ value->endDictionary(); } -template <typename T> -void addJsonObjectForPoint(TracedValue* value, const char* name, const T& point) -{ - value->beginDictionary(name); - value->setDouble("x", point.x()); - value->setDouble("y", point.y()); - value->endDictionary(); -} - static std::unique_ptr<TracedValue> jsonObjectForPaintInvalidationInfo(const LayoutRect& rect, const String& invalidationReason) { std::unique_ptr<TracedValue> value = TracedValue::create(); @@ -1207,12 +1198,6 @@ invalidateDisplayItemClient(*this, reason); } -void LayoutObject::invalidateDisplayItemClientsWithPaintInvalidationState(const PaintInvalidationState& paintInvalidationState, PaintInvalidationReason reason) const -{ - paintInvalidationState.paintingLayer().setNeedsRepaint(); - invalidateDisplayItemClients(reason); -} - bool LayoutObject::compositedScrollsWithRespectTo(const LayoutBoxModelObject& paintInvalidationContainer) const { return paintInvalidationContainer.usesCompositedScrolling() && this != &paintInvalidationContainer; @@ -1253,7 +1238,7 @@ void LayoutObject::invalidateTreeIfNeeded(const PaintInvalidationState& paintInvalidationState) { - ASSERT(!needsLayout()); + ensureIsReadyForPaintInvalidation(); // If we didn't need paint invalidation then our children don't need as well. // Skip walking down the tree as everything should be fine below us. @@ -1266,7 +1251,7 @@ newPaintInvalidationState.setForceSubtreeInvalidationCheckingWithinContainer(); PaintInvalidationReason reason = invalidatePaintIfNeeded(newPaintInvalidationState); - clearPaintInvalidationFlags(newPaintInvalidationState); + clearPaintInvalidationFlags(); newPaintInvalidationState.updateForChildren(reason); invalidatePaintOfSubtreesIfNeeded(newPaintInvalidationState); @@ -1283,16 +1268,6 @@ } } -static std::unique_ptr<TracedValue> jsonObjectForOldAndNewRects(const LayoutRect& oldRect, const LayoutPoint& oldLocation, const LayoutRect& newRect, const LayoutPoint& newLocation) -{ - std::unique_ptr<TracedValue> value = TracedValue::create(); - addJsonObjectForRect(value.get(), "oldRect", oldRect); - addJsonObjectForPoint(value.get(), "oldLocation", oldLocation); - addJsonObjectForRect(value.get(), "newRect", newRect); - addJsonObjectForPoint(value.get(), "newLocation", newLocation); - return value; -} - LayoutRect LayoutObject::selectionRectInViewCoordinates() const { LayoutRect selectionRect = localSelectionRect(); @@ -1301,54 +1276,9 @@ return selectionRect; } -LayoutRect LayoutObject::previousSelectionRectForPaintInvalidation() const -{ - if (!selectionPaintInvalidationMap) - return LayoutRect(); - - return selectionPaintInvalidationMap->get(this); -} - -void LayoutObject::setPreviousSelectionRectForPaintInvalidation(const LayoutRect& selectionRect) -{ - if (!selectionPaintInvalidationMap) { - if (selectionRect.isEmpty()) - return; - selectionPaintInvalidationMap = new SelectionPaintInvalidationMap(); - } - - if (selectionRect.isEmpty()) - selectionPaintInvalidationMap->remove(this); - else - selectionPaintInvalidationMap->set(this, selectionRect); -} - -inline void LayoutObject::invalidateSelectionIfNeeded(const LayoutBoxModelObject& paintInvalidationContainer, const PaintInvalidationState& paintInvalidationState, PaintInvalidationReason invalidationReason) -{ - // Update selection rect when we are doing full invalidation (in case that the object is moved, composite status changed, etc.) - // or shouldInvalidationSelection is set (in case that the selection itself changed). - bool fullInvalidation = isFullPaintInvalidationReason(invalidationReason); - if (!fullInvalidation && !shouldInvalidateSelection()) - return; - - LayoutRect oldSelectionRect = previousSelectionRectForPaintInvalidation(); - LayoutRect newSelectionRect = localSelectionRect(); - if (!newSelectionRect.isEmpty()) - paintInvalidationState.mapLocalRectToPaintInvalidationBacking(newSelectionRect); - - newSelectionRect.move(scrollAdjustmentForPaintInvalidation(paintInvalidationContainer)); - - setPreviousSelectionRectForPaintInvalidation(newSelectionRect); - - if (!fullInvalidation) { - fullyInvalidatePaint(paintInvalidationContainer, PaintInvalidationSelection, oldSelectionRect, newSelectionRect); - invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidationState, PaintInvalidationSelection); - } -} - PaintInvalidationReason LayoutObject::invalidatePaintIfNeeded(const PaintInvalidationState& paintInvalidationState) { - ASSERT(&paintInvalidationState.currentObject() == this); + DCHECK(&paintInvalidationState.currentObject() == this); if (styleRef().hasOutline()) { PaintLayer& layer = paintInvalidationState.paintingLayer(); @@ -1360,107 +1290,34 @@ if (v->document().printing()) return PaintInvalidationNone; // Don't invalidate paints if we're printing. - const LayoutBoxModelObject& paintInvalidationContainer = paintInvalidationState.paintInvalidationContainer(); - ASSERT(paintInvalidationContainer == containerForPaintInvalidation()); + PaintInvalidatorContextAdapter context(paintInvalidationState); - const LayoutRect oldBounds = previousPaintInvalidationRect(); - const LayoutPoint oldLocation = RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() ? LayoutPoint() : previousPositionFromPaintInvalidationBacking(); - LayoutRect newBounds = paintInvalidationState.computePaintInvalidationRectInBacking(); - LayoutPoint newLocation = RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() ? LayoutPoint() : paintInvalidationState.computePositionFromPaintInvalidationBacking(); + const LayoutBoxModelObject& paintInvalidationContainer = paintInvalidationState.paintInvalidationContainer(); + DCHECK(paintInvalidationContainer == containerForPaintInvalidation()); + + context.oldBounds = previousPaintInvalidationRect(); + context.oldLocation = previousPositionFromPaintInvalidationBacking(); + context.newBounds = paintInvalidationState.computePaintInvalidationRectInBacking(); + context.newLocation = paintInvalidationState.computePositionFromPaintInvalidationBacking(); IntSize adjustment = scrollAdjustmentForPaintInvalidation(paintInvalidationContainer); - newLocation.move(adjustment); - newBounds.move(adjustment); + context.newLocation.move(adjustment); + context.newBounds.move(adjustment); - setPreviousPaintInvalidationRect(newBounds); - if (!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) - setPreviousPositionFromPaintInvalidationBacking(newLocation); + setPreviousPaintInvalidationRect(context.newBounds); + setPreviousPositionFromPaintInvalidationBacking(context.newLocation); if (!shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState() && paintInvalidationState.forcedSubtreeInvalidationRectUpdateWithinContainerOnly()) { // We are done updating the paint invalidation rect. No other paint invalidation work to do for this object. return PaintInvalidationNone; } - PaintInvalidationReason invalidationReason = getPaintInvalidationReason(paintInvalidationState, oldBounds, oldLocation, newBounds, newLocation); - - // We need to invalidate the selection before checking for whether we are doing a full invalidation. - // This is because we need to update the old rect regardless. - invalidateSelectionIfNeeded(paintInvalidationContainer, paintInvalidationState, invalidationReason); - - TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), "LayoutObject::invalidatePaintIfNeeded()", - "object", this->debugName().ascii(), - "info", jsonObjectForOldAndNewRects(oldBounds, oldLocation, newBounds, newLocation)); - - bool backgroundObscured = backgroundIsKnownToBeObscured(); - if (!isFullPaintInvalidationReason(invalidationReason) && backgroundObscured != m_bitfields.previousBackgroundObscured()) - invalidationReason = PaintInvalidationBackgroundObscurationChange; - m_bitfields.setPreviousBackgroundObscured(backgroundObscured); - - if (invalidationReason == PaintInvalidationNone) { - // TODO(trchen): Currently we don't keep track of paint offset of layout objects. - // There are corner cases that the display items need to be invalidated for paint offset - // mutation, but incurs no pixel difference (i.e. bounds stay the same) so no rect-based - // invalidation is issued. See crbug.com/508383 and crbug.com/515977. - // This is a workaround to force display items to update paint offset. - if (!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() && paintInvalidationState.forcedSubtreeInvalidationCheckingWithinContainer()) - invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidationState, PaintInvalidationLocationChange); - - return invalidationReason; - } - - if (invalidationReason == PaintInvalidationIncremental) - incrementallyInvalidatePaint(paintInvalidationContainer, oldBounds, newBounds, newLocation); - else - fullyInvalidatePaint(paintInvalidationContainer, invalidationReason, oldBounds, newBounds); - - invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidationState, invalidationReason); - return invalidationReason; + return invalidatePaintIfNeeded(context); } -PaintInvalidationReason LayoutObject::getPaintInvalidationReason(const PaintInvalidationState& paintInvalidationState, - const LayoutRect& oldBounds, const LayoutPoint& oldPositionFromPaintInvalidationBacking, - const LayoutRect& newBounds, const LayoutPoint& newPositionFromPaintInvalidationBacking) const +PaintInvalidationReason LayoutObject::invalidatePaintIfNeeded(const PaintInvalidatorContext& context) const { - if (paintInvalidationState.forcedSubtreeFullInvalidationWithinContainer()) - return PaintInvalidationSubtree; - - if (shouldDoFullPaintInvalidation()) - return m_bitfields.fullPaintInvalidationReason(); - - if (paintedOutputOfObjectHasNoEffect()) - return PaintInvalidationNone; - - // The outline may change shape because of position change of descendants. For simplicity, - // just force full paint invalidation if this object is marked for checking paint invalidation - // for any reason. - if (styleRef().hasOutline()) - return PaintInvalidationOutline; - - bool locationChanged = newPositionFromPaintInvalidationBacking != oldPositionFromPaintInvalidationBacking; - - // If the bounds are the same then we know that none of the statements below - // can match, so we can early out. - if (oldBounds == newBounds) - return locationChanged && !oldBounds.isEmpty() ? PaintInvalidationLocationChange : PaintInvalidationNone; - - // If we shifted, we don't know the exact reason so we are conservative and trigger a full invalidation. Shifting could - // be caused by some layout property (left / top) or some in-flow layoutObject inserted / removed before us in the tree. - if (newBounds.location() != oldBounds.location()) - return PaintInvalidationBoundsChange; - - // If the size is zero on one of our bounds then we know we're going to have - // to do a full invalidation of either old bounds or new bounds. If we fall - // into the incremental invalidation we'll issue two invalidations instead - // of one. - if (oldBounds.isEmpty()) - return PaintInvalidationBecameVisible; - if (newBounds.isEmpty()) - return PaintInvalidationBecameInvisible; - - if (locationChanged) - return PaintInvalidationLocationChange; - - return PaintInvalidationIncremental; + return ObjectPaintInvalidator(*this, context).invalidatePaintIfNeeded(); } void LayoutObject::adjustInvalidationRectForCompositedScrolling(LayoutRect& rect, const LayoutBoxModelObject& paintInvalidationContainer) const @@ -1492,44 +1349,6 @@ setShouldDoFullPaintInvalidation(); } -void LayoutObject::incrementallyInvalidatePaint(const LayoutBoxModelObject& paintInvalidationContainer, const LayoutRect& oldBounds, const LayoutRect& newBounds, const LayoutPoint& positionFromPaintInvalidationBacking) -{ - ASSERT(oldBounds.location() == newBounds.location()); - - LayoutUnit deltaRight = newBounds.maxX() - oldBounds.maxX(); - if (deltaRight > 0) { - LayoutRect invalidationRect(oldBounds.maxX(), newBounds.y(), deltaRight, newBounds.height()); - invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRect, PaintInvalidationIncremental); - } else if (deltaRight < 0) { - LayoutRect invalidationRect(newBounds.maxX(), oldBounds.y(), -deltaRight, oldBounds.height()); - invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRect, PaintInvalidationIncremental); - } - - LayoutUnit deltaBottom = newBounds.maxY() - oldBounds.maxY(); - if (deltaBottom > 0) { - LayoutRect invalidationRect(newBounds.x(), oldBounds.maxY(), newBounds.width(), deltaBottom); - invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRect, PaintInvalidationIncremental); - } else if (deltaBottom < 0) { - LayoutRect invalidationRect(oldBounds.x(), newBounds.maxY(), oldBounds.width(), -deltaBottom); - invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRect, PaintInvalidationIncremental); - } -} - -void LayoutObject::fullyInvalidatePaint(const LayoutBoxModelObject& paintInvalidationContainer, PaintInvalidationReason invalidationReason, const LayoutRect& oldBounds, const LayoutRect& newBounds) -{ - // The following logic avoids invalidating twice if one set of bounds contains the other. - if (!newBounds.contains(oldBounds)) { - LayoutRect invalidationRect = oldBounds; - invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRect, invalidationReason); - - if (oldBounds.contains(newBounds)) - return; - } - - LayoutRect invalidationRect = newBounds; - invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRect, invalidationReason); -} - LayoutRect LayoutObject::absoluteClippedOverflowRect() const { LayoutRect rect = localOverflowRectForPaintInvalidation(); @@ -2615,8 +2434,7 @@ setAncestorLineBoxDirty(false); - if (selectionPaintInvalidationMap) - selectionPaintInvalidationMap->remove(this); + ObjectPaintInvalidator::objectWillBeDestroyed(*this); if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) objectPaintPropertiesMap().remove(this); @@ -3429,7 +3247,15 @@ setMayNeedPaintInvalidation(); } -void LayoutObject::clearPaintInvalidationFlags(const PaintInvalidationState& paintInvalidationState) +void LayoutObject::setMayNeedPaintInvalidationAnimatgedBackgroundImage() +{ + if (mayNeedPaintInvalidationAnimatedBackgroundImage()) + return; + m_bitfields.setMayNeedPaintInvalidationAnimatedBackgroundImage(true); + setMayNeedPaintInvalidation(); +} + +void LayoutObject::clearPaintInvalidationFlags() { // paintInvalidationStateIsDirty should be kept in sync with the // booleans that are cleared below. @@ -3438,6 +3264,7 @@ m_bitfields.setChildShouldCheckForPaintInvalidation(false); m_bitfields.setMayNeedPaintInvalidation(false); m_bitfields.setMayNeedPaintInvalidationSubtree(false); + m_bitfields.setMayNeedPaintInvalidationAnimatedBackgroundImage(false); m_bitfields.setShouldInvalidateSelection(false); }
diff --git a/third_party/WebKit/Source/core/layout/LayoutObject.h b/third_party/WebKit/Source/core/layout/LayoutObject.h index d2d2015..1d8e509 100644 --- a/third_party/WebKit/Source/core/layout/LayoutObject.h +++ b/third_party/WebKit/Source/core/layout/LayoutObject.h
@@ -68,6 +68,7 @@ class TransformState; struct PaintInfo; +struct PaintInvalidatorContext; enum CursorDirective { SetCursorBasedOnStyle, @@ -1141,7 +1142,7 @@ // output as if |ancestor| was the root of the page: the rect is modified by any intervening clips, transforms // and scrolls between |this| and |ancestor| (not inclusive of |ancestor|), but not any above |ancestor|. // The output is in the physical, painted coordinate pixel space of |ancestor|. - // Overflow clipping and scrolling is *not* applied for |ancestor| itself if |ancestor| scrolls overflow. + // Overflow clipping, CSS clipping and scrolling is *not* applied for |ancestor| itself if |ancestor| scrolls overflow. // The output rect is suitable for purposes such as paint invalidation. // // If visualRectFlags has the EdgeInclusive bit set, clipping operations will use @@ -1307,16 +1308,8 @@ void adjustPreviousPaintInvalidationForScrollIfNeeded(const DoubleSize& scrollDelta); // The previous position of the top-left corner of the object in its previous paint backing. - const LayoutPoint& previousPositionFromPaintInvalidationBacking() const - { - ASSERT(!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()); - return m_previousPositionFromPaintInvalidationBacking; - } - void setPreviousPositionFromPaintInvalidationBacking(const LayoutPoint& positionFromPaintInvalidationBacking) - { - ASSERT(!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()); - m_previousPositionFromPaintInvalidationBacking = positionFromPaintInvalidationBacking; - } + const LayoutPoint& previousPositionFromPaintInvalidationBacking() const { return m_previousPositionFromPaintInvalidationBacking; } + void setPreviousPositionFromPaintInvalidationBacking(const LayoutPoint& positionFromPaintInvalidationBacking) { m_previousPositionFromPaintInvalidationBacking = positionFromPaintInvalidationBacking; } bool paintOffsetChanged(const LayoutPoint& newPaintOffset) const { @@ -1334,7 +1327,7 @@ void setShouldDoFullPaintInvalidation(PaintInvalidationReason = PaintInvalidationFull); void clearShouldDoFullPaintInvalidation() { m_bitfields.setFullPaintInvalidationReason(PaintInvalidationNone); } - virtual void clearPaintInvalidationFlags(const PaintInvalidationState&); + virtual void clearPaintInvalidationFlags(); bool mayNeedPaintInvalidation() const { return m_bitfields.mayNeedPaintInvalidation(); } void setMayNeedPaintInvalidation(); @@ -1342,6 +1335,9 @@ bool mayNeedPaintInvalidationSubtree() const { return m_bitfields.mayNeedPaintInvalidationSubtree(); } void setMayNeedPaintInvalidationSubtree(); + bool mayNeedPaintInvalidationAnimatedBackgroundImage() const { return m_bitfields.mayNeedPaintInvalidationAnimatedBackgroundImage(); } + void setMayNeedPaintInvalidationAnimatgedBackgroundImage(); + bool shouldInvalidateSelection() const { return m_bitfields.shouldInvalidateSelection(); } void setShouldInvalidateSelection(); @@ -1378,6 +1374,20 @@ void invalidateDisplayItemClientsIncludingNonCompositingDescendants(PaintInvalidationReason) const; + // New version to replace the above old version. + virtual PaintInvalidationReason invalidatePaintIfNeeded(const PaintInvalidatorContext&) const; + + // When this object is invalidated for paint, this method is called to invalidate any DisplayItemClients + // owned by this object, including the object itself, LayoutText/LayoutInline line boxes, etc., + // not including children which will be invalidated normally during invalidateTreeIfNeeded() and + // parts which are invalidated separately (e.g. scrollbars). + // The caller should ensure the painting layer has been setNeedsRepaint before calling this function. + virtual void invalidateDisplayItemClients(PaintInvalidationReason) const; + + const LayoutRect& previousPaintInvalidationRect() const { return m_previousPaintInvalidationRect; } + + virtual bool hasNonCompositedScrollbars() const { return false; } + // Called before anonymousChild.setStyle(). Override to set custom styles for the child. virtual void updateAnonymousChildStyle(const LayoutObject& anonymousChild, ComputedStyle& style) const { } @@ -1385,11 +1395,15 @@ class MutableForPainting { public: void setPreviousPaintOffset(const LayoutPoint& paintOffset) { m_layoutObject.setPreviousPaintOffset(paintOffset); } - PaintInvalidationReason invalidatePaintIfNeeded(const PaintInvalidationState& paintInvalidationState) { return m_layoutObject.invalidatePaintIfNeeded(paintInvalidationState); } - void clearPaintInvalidationFlags(const PaintInvalidationState& paintInvalidationState) { m_layoutObject.clearPaintInvalidationFlags(paintInvalidationState); } - void setShouldDoDelayedFullPaintInvalidation() { m_layoutObject.setShouldDoFullPaintInvalidation(PaintInvalidationDelayedFull); } + void clearPaintInvalidationFlags() { m_layoutObject.clearPaintInvalidationFlags(); } + void setShouldDoFullPaintInvalidation(PaintInvalidationReason reason) { m_layoutObject.setShouldDoFullPaintInvalidation(reason); } + void ensureIsReadyForPaintInvalidation() { m_layoutObject.ensureIsReadyForPaintInvalidation(); } - private: + void setPreviousPaintInvalidationRect(const LayoutRect& r) { m_layoutObject.setPreviousPaintInvalidationRect(r); } + void setPreviousPositionFromPaintInvalidationBacking(const LayoutPoint& p) { m_layoutObject.setPreviousPositionFromPaintInvalidationBacking(p); } + void setPreviousBackgroundObscured(bool b) { m_layoutObject.setPreviousBackgroundObscured(b); } + + protected: friend class PaintPropertyTreeBuilder; // The following two functions can be called from PaintPropertyTreeBuilder only. ObjectPaintProperties& ensureObjectPaintProperties() { return m_layoutObject.ensureObjectPaintProperties(); } @@ -1411,6 +1425,9 @@ bool compositedScrollsWithRespectTo(const LayoutBoxModelObject& paintInvalidationContainer) const; IntSize scrollAdjustmentForPaintInvalidation(const LayoutBoxModelObject& paintInvalidationContainer) const; + bool previousBackgroundObscured() const { return m_bitfields.previousBackgroundObscured(); } + void setPreviousBackgroundObscured(bool b) { m_bitfields.setPreviousBackgroundObscured(b); } + protected: enum LayoutObjectType { LayoutObjectBr, @@ -1532,25 +1549,6 @@ void setPreviousPaintInvalidationRect(const LayoutRect& rect) { m_previousPaintInvalidationRect = rect; } - virtual PaintInvalidationReason getPaintInvalidationReason(const PaintInvalidationState&, - const LayoutRect& oldPaintInvalidationRect, const LayoutPoint& oldPositionFromPaintInvalidationBacking, - const LayoutRect& newPaintInvalidationRect, const LayoutPoint& newPositionFromPaintInvalidationBacking) const; - - // This function tries to minimize the amount of invalidation - // generated by invalidating the "difference" between |oldBounds| - // and |newBounds|. This means invalidating the union of the - // previous rectangles but not their intersection. - // - // The use case is when an element only requires a paint - // invalidation (which means that its content didn't change) - // and its bounds changed but its location didn't. - // - // If we don't meet the criteria for an incremental paint, the - // alternative is a full paint invalidation. - virtual void incrementallyInvalidatePaint(const LayoutBoxModelObject& paintInvalidationContainer, const LayoutRect& oldBounds, const LayoutRect& newBounds, const LayoutPoint& positionFromPaintInvalidationBacking); - - virtual bool hasNonCompositedScrollbars() const { return false; } - #if ENABLE(ASSERT) virtual bool paintInvalidationStateIsDirty() const { @@ -1558,6 +1556,12 @@ } #endif + // Called before paint invalidation. + virtual void ensureIsReadyForPaintInvalidation() + { + DCHECK(!needsLayout()); + } + // This function walks the descendants of |this|, following a // layout ordering. // @@ -1574,17 +1578,6 @@ // by invalidatePaintOfSubtreesIfNeeded. virtual PaintInvalidationReason invalidatePaintIfNeeded(const PaintInvalidationState&); - // When this object is invalidated for paint, this method is called to invalidate any DisplayItemClients - // owned by this object, including the object itself, LayoutText/LayoutInline line boxes, etc., - // not including children which will be invalidated normally during invalidateTreeIfNeeded() and - // parts which are invalidated separately (e.g. scrollbars). - // The caller should ensure the painting layer has been setNeedsRepaint before calling this function. - virtual void invalidateDisplayItemClients(PaintInvalidationReason) const; - - // Sets painting layer needsRepaint, then calls invalidateDisplayItemClients(). - // Should use this version when PaintInvalidationState is available. - void invalidateDisplayItemClientsWithPaintInvalidationState(const PaintInvalidationState&, PaintInvalidationReason) const; - void setIsBackgroundAttachmentFixedObject(bool); void clearSelfNeedsOverflowRecalcAfterStyleChange() { m_bitfields.setSelfNeedsOverflowRecalcAfterStyleChange(false); } @@ -1596,16 +1589,7 @@ bool containsInlineWithOutlineAndContinuation() const { return m_bitfields.containsInlineWithOutlineAndContinuation(); } void setContainsInlineWithOutlineAndContinuation(bool b) { m_bitfields.setContainsInlineWithOutlineAndContinuation(b); } - const LayoutRect& previousPaintInvalidationRect() const { return m_previousPaintInvalidationRect; } - private: - // This function generates a full invalidation, which - // means invalidating both |oldBounds| and |newBounds|. - // - // This is the default choice when generating an invalidation, - // as it is always correct, albeit it may force some extra painting. - void fullyInvalidatePaint(const LayoutBoxModelObject& paintInvalidationContainer, PaintInvalidationReason, const LayoutRect& oldBounds, const LayoutRect& newBounds); - // Adjusts a paint invalidation rect in the space of |m_previousPaintInvalidationRect| and |m_previousPositionFromPaintInvalidationBacking| // to be in the space of the |paintInvalidationContainer|, // if needed. They can be different only if |paintInvalidationContainer| is a composited scroller. @@ -1631,8 +1615,6 @@ inline void markAncestorsForPaintInvalidation(); - inline void invalidateSelectionIfNeeded(const LayoutBoxModelObject& paintInvalidationContainer, const PaintInvalidationState&, PaintInvalidationReason); - inline void invalidateContainerPreferredLogicalWidths(); void invalidatePaintIncludingNonSelfPaintingLayerDescendantsInternal(const LayoutBoxModelObject& paintInvalidationContainer); @@ -1640,9 +1622,6 @@ // The caller should ensure the painting layer has been setNeedsRepaint before calling this function. void invalidatePaintOfPreviousPaintInvalidationRect(const LayoutBoxModelObject& paintInvalidationContainer, PaintInvalidationReason); - LayoutRect previousSelectionRectForPaintInvalidation() const; - void setPreviousSelectionRectForPaintInvalidation(const LayoutRect&); - LayoutObject* containerForAbsolutePosition(const LayoutBoxModelObject* ancestor = nullptr, bool* ancestorSkipped = nullptr, bool* filterOrReflectionSkipped = nullptr) const; const LayoutBoxModelObject* enclosingCompositedContainer() const; @@ -1735,6 +1714,7 @@ , m_childShouldCheckForPaintInvalidation(false) , m_mayNeedPaintInvalidation(false) , m_mayNeedPaintInvalidationSubtree(false) + , m_mayNeedPaintInvalidationAnimatedBackgroundImage(false) , m_shouldInvalidateSelection(false) , m_floating(false) , m_isAnonymous(!node) @@ -1770,7 +1750,7 @@ { } - // 32 bits have been used in the first word, and 17 in the second. + // 32 bits have been used in the first word, and 18 in the second. // Self needs layout means that this layout object is marked for a full layout. // This is the default layout but it is expensive as it recomputes everything. @@ -1821,6 +1801,7 @@ ADD_BOOLEAN_BITFIELD(childShouldCheckForPaintInvalidation, ChildShouldCheckForPaintInvalidation); ADD_BOOLEAN_BITFIELD(mayNeedPaintInvalidation, MayNeedPaintInvalidation); ADD_BOOLEAN_BITFIELD(mayNeedPaintInvalidationSubtree, MayNeedPaintInvalidationSubtree); + ADD_BOOLEAN_BITFIELD(mayNeedPaintInvalidationAnimatedBackgroundImage, MayNeedPaintInvalidationAnimatedBackgroundImage); ADD_BOOLEAN_BITFIELD(shouldInvalidateSelection, ShouldInvalidateSelection); // This boolean is the cached value of 'float'
diff --git a/third_party/WebKit/Source/core/layout/LayoutPart.cpp b/third_party/WebKit/Source/core/layout/LayoutPart.cpp index d56ac9de7..9f52b72 100644 --- a/third_party/WebKit/Source/core/layout/LayoutPart.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutPart.cpp
@@ -300,12 +300,23 @@ if (!widget || !node()) // Check the node in case destroy() has been called. return; + LayoutRect newFrame = replacedContentRect(); + DCHECK(newFrame.size() == roundedIntSize(newFrame.size())); + bool boundsWillChange = LayoutSize(widget->frameRect().size()) != newFrame.size(); + + FrameView* frameView = widget->isFrameView() ? toFrameView(widget) : nullptr; + + // If frame bounds are changing mark the view for layout. Also check the + // frame's page to make sure that the frame isn't in the process of being + // destroyed. + if (frameView && boundsWillChange && frameView->frame().page()) + frameView->setNeedsLayout(); + updateWidgetGeometryInternal(); // If view needs layout, either because bounds have changed or possibly // indicating content size is wrong, we have to do a layout to set the right // widget size. - FrameView* frameView = widget->isFrameView() ? toFrameView(widget) : nullptr; if (frameView && frameView->needsLayout() && frameView->frame().page()) frameView->layout();
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.cpp b/third_party/WebKit/Source/core/layout/LayoutTable.cpp index 38961ef..49cb722 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTable.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTable.cpp
@@ -42,6 +42,7 @@ #include "core/layout/TextAutosizer.h" #include "core/paint/BoxPainter.h" #include "core/paint/PaintLayer.h" +#include "core/paint/TablePaintInvalidator.h" #include "core/paint/TablePainter.h" #include "core/style/StyleInheritedData.h" #include "wtf/PtrUtil.h" @@ -543,9 +544,15 @@ section->setLogicalTop(logicalOffset); section->layoutRows(); logicalOffset += section->logicalHeight(); - if (isPaginated && m_head && m_head == section && section->logicalHeight() < section->pageLogicalHeightForOffset(logicalOffset)) { + // If the section is a repeating header group that allows at least one row of content then store the + // offset for other sections to offset their rows against. + if (isPaginated && m_head && m_head == section && section->logicalHeight() < section->pageLogicalHeightForOffset(logicalOffset) + && section->getPaginationBreakability() != LayoutBox::AllowAnyBreaks) { LayoutUnit offsetForTableHeaders = state.heightOffsetForTableHeaders(); + // Don't include any strut in the header group - we only want the height from its content. offsetForTableHeaders += section->logicalHeight(); + if (LayoutTableRow* row = section->firstRow()) + offsetForTableHeaders -= section->paginationStrutForRow(row, section->logicalTop()); state.setHeightOffsetForTableHeaders(offsetForTableHeaders); } } @@ -1422,63 +1429,23 @@ return style()->borderStart(); } +void LayoutTable::ensureIsReadyForPaintInvalidation() +{ + LayoutBlock::ensureIsReadyForPaintInvalidation(); + recalcCollapsedBordersIfNeeded(); +} + PaintInvalidationReason LayoutTable::invalidatePaintIfNeeded(const PaintInvalidationState& paintInvalidationState) { - // Information of collapsed borders doesn't affect layout and are for painting only. - // Do it now instead of during painting to invalidate table cells if needed. - recalcCollapsedBordersIfNeeded(); if (collapseBorders() && !m_collapsedBorders.isEmpty()) paintInvalidationState.paintingLayer().setNeedsPaintPhaseDescendantBlockBackgrounds(); return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); } -void LayoutTable::invalidatePaintOfSubtreesIfNeeded(const PaintInvalidationState& childPaintInvalidationState) +PaintInvalidationReason LayoutTable::invalidatePaintIfNeeded(const PaintInvalidatorContext& context) const { - // Table cells paint background from the containing column group, column, section and row. - // If background of any of them changed, we need to invalidate all affected cells. - // Here use shouldDoFullPaintInvalidation() as a broader condition of background change. - - // If any col changed background, we'll check all cells for background changes. - bool hasColChangedBackground = false; - for (LayoutTableCol* col = firstColumn(); col; col = col->nextColumn()) { - if (col->backgroundChangedSinceLastPaintInvalidation()) { - hasColChangedBackground = true; - break; - } - } - for (LayoutObject* child = firstChild(); child; child = child->nextSibling()) { - if (!child->isTableSection()) - continue; - LayoutTableSection* section = toLayoutTableSection(child); - if (!hasColChangedBackground && !section->shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()) - continue; - for (LayoutTableRow* row = section->firstRow(); row; row = row->nextRow()) { - if (!hasColChangedBackground && !section->backgroundChangedSinceLastPaintInvalidation() && !row->backgroundChangedSinceLastPaintInvalidation()) - continue; - for (LayoutTableCell* cell = row->firstCell(); cell; cell = cell->nextCell()) { - bool invalidated = false; - // Table cells paint container's background on the container's backing instead of its own (if any), - // so we must invalidate it by the containers. - if (section->backgroundChangedSinceLastPaintInvalidation()) { - section->slowSetPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient(*cell, PaintInvalidationStyleChange); - invalidated = true; - } else if (hasColChangedBackground) { - ColAndColGroup colAndColGroup = colElementAtAbsoluteColumn(cell->absoluteColumnIndex()); - LayoutTableCol* column = colAndColGroup.col; - LayoutTableCol* columnGroup = colAndColGroup.colgroup; - if ((columnGroup && columnGroup->backgroundChangedSinceLastPaintInvalidation()) - || (column && column->backgroundChangedSinceLastPaintInvalidation())) { - section->slowSetPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient(*cell, PaintInvalidationStyleChange); - invalidated = true; - } - } - if ((!invalidated || row->hasSelfPaintingLayer()) && row->backgroundChangedSinceLastPaintInvalidation()) - row->slowSetPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient(*cell, PaintInvalidationStyleChange); - } - } - } - LayoutBlock::invalidatePaintOfSubtreesIfNeeded(childPaintInvalidationState); + return TablePaintInvalidator(*this, context).invalidatePaintIfNeeded(); } LayoutUnit LayoutTable::paddingTop() const
diff --git a/third_party/WebKit/Source/core/layout/LayoutTable.h b/third_party/WebKit/Source/core/layout/LayoutTable.h index 2c0f062..c0c476ed 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTable.h +++ b/third_party/WebKit/Source/core/layout/LayoutTable.h
@@ -402,8 +402,9 @@ void styleDidChange(StyleDifference, const ComputedStyle* oldStyle) override; void simplifiedNormalFlowLayout() override; bool recalcChildOverflowAfterStyleChange() override; + void ensureIsReadyForPaintInvalidation() override; PaintInvalidationReason invalidatePaintIfNeeded(const PaintInvalidationState&) override; - void invalidatePaintOfSubtreesIfNeeded(const PaintInvalidationState&) override; + PaintInvalidationReason invalidatePaintIfNeeded(const PaintInvalidatorContext&) const override; private: bool isOfType(LayoutObjectType type) const override { return type == LayoutObjectTable || LayoutBlock::isOfType(type); }
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableBoxComponent.h b/third_party/WebKit/Source/core/layout/LayoutTableBoxComponent.h index 58c01307..802e6d32 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTableBoxComponent.h +++ b/third_party/WebKit/Source/core/layout/LayoutTableBoxComponent.h
@@ -34,9 +34,9 @@ void styleDidChange(StyleDifference, const ComputedStyle* oldStyle) override; void imageChanged(WrappedImagePtr, const IntRect* = nullptr) override; - void clearPaintInvalidationFlags(const PaintInvalidationState& paintInvalidationState) override + void clearPaintInvalidationFlags() override { - LayoutBox::clearPaintInvalidationFlags(paintInvalidationState); + LayoutBox::clearPaintInvalidationFlags(); m_backgroundChangedSinceLastPaintInvalidation = false; }
diff --git a/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp b/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp index 0b6d301..d03f1887 100644 --- a/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutTableSection.cpp
@@ -1135,6 +1135,7 @@ int LayoutTableSection::paginationStrutForRow(LayoutTableRow* row, LayoutUnit logicalOffset) const { + DCHECK(row); // Even if the row allows us to break-inside, we will want to put a strut on the row if we have a header // group that wants to appear at the top of each page. bool tableHeaderForcesStrut = table()->header() ? table()->header()->getPaginationBreakability() != AllowAnyBreaks : false;
diff --git a/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp b/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp index 38b0386..6a243e2 100644 --- a/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp +++ b/third_party/WebKit/Source/core/layout/PaintInvalidationState.cpp
@@ -12,7 +12,9 @@ #include "core/layout/LayoutView.h" #include "core/layout/svg/LayoutSVGRoot.h" #include "core/layout/svg/SVGLayoutSupport.h" +#include "core/paint/PaintInvalidator.h" #include "core/paint/PaintLayer.h" +#include "core/paint/PaintPropertyTreeBuilder.h" namespace blink { @@ -80,7 +82,7 @@ , m_canCheckFastPathSlowPathEquality(parentState.m_canCheckFastPathSlowPathEquality) #endif { - ASSERT(&m_paintingLayer == currentObject.paintingLayer()); + DCHECK(&m_paintingLayer == currentObject.paintingLayer()); if (currentObject == parentState.m_currentObject) { // Sometimes we create a new PaintInvalidationState from parentState on the same object @@ -92,7 +94,9 @@ return; } - ASSERT(parentState.m_didUpdateForChildren); +#if ENABLE(ASSERT) + DCHECK(parentState.m_didUpdateForChildren); +#endif if (currentObject.isPaintInvalidationContainer()) { m_paintInvalidationContainer = toLayoutBoxModelObject(¤tObject); @@ -117,8 +121,8 @@ // descendants if possible; or // - Track offset between the two paintInvalidationContainers. m_cachedOffsetsEnabled = false; - if (m_forcedSubtreeInvalidationFlags & FullInvalidationForStackedContents) - m_forcedSubtreeInvalidationFlags |= FullInvalidation; + if (m_forcedSubtreeInvalidationFlags & PaintInvalidatorContext::ForcedSubtreeFullInvalidationForStackedContents) + m_forcedSubtreeInvalidationFlags |= PaintInvalidatorContext::ForcedSubtreeFullInvalidation; } if (!currentObject.isBoxModelObject() && !currentObject.isSVG()) @@ -133,7 +137,7 @@ // Don't early return here, because the SVGRoot object needs to execute the later code // as a normal LayoutBox. } else { - ASSERT(currentObject != m_paintInvalidationContainer); + DCHECK(currentObject != m_paintInvalidationContainer); m_svgTransform *= currentObject.localToSVGParentTransform(); return; } @@ -148,7 +152,7 @@ // However, we need to keep the FullInvalidationForStackedContents flag // if the current object isn't the paint invalidation container of // stacked contents. - m_forcedSubtreeInvalidationFlags &= FullInvalidationForStackedContents; + m_forcedSubtreeInvalidationFlags &= PaintInvalidatorContext::ForcedSubtreeFullInvalidationForStackedContents; } else { m_forcedSubtreeInvalidationFlags = 0; if (currentObject != m_containerForAbsolutePosition @@ -182,7 +186,7 @@ return; if (m_currentObject.isLayoutView()) { - ASSERT(&parentState.m_currentObject == toLayoutView(m_currentObject).frame()->ownerLayoutObject()); + DCHECK(&parentState.m_currentObject == toLayoutView(m_currentObject).frame()->ownerLayoutObject()); m_paintOffset += toLayoutBox(parentState.m_currentObject).contentBoxOffset(); // a LayoutView paints with a defined size but a pixel-rounded offset. m_paintOffset = LayoutSize(roundedIntSize(m_paintOffset)); @@ -243,7 +247,7 @@ void PaintInvalidationState::updateForChildren(PaintInvalidationReason reason) { #if ENABLE(ASSERT) - ASSERT(!m_didUpdateForChildren); + DCHECK(!m_didUpdateForChildren); m_didUpdateForChildren = true; #endif @@ -252,7 +256,7 @@ m_pendingDelayedPaintInvalidations.append(&m_currentObject); break; case PaintInvalidationSubtree: - m_forcedSubtreeInvalidationFlags |= (FullInvalidation | FullInvalidationForStackedContents); + m_forcedSubtreeInvalidationFlags |= (PaintInvalidatorContext::ForcedSubtreeFullInvalidation | PaintInvalidatorContext::ForcedSubtreeFullInvalidationForStackedContents); break; case PaintInvalidationSVGResourceChange: setForceSubtreeInvalidationCheckingWithinContainer(); @@ -307,7 +311,7 @@ m_paintOffset -= toLayoutBox(m_currentObject).locationOffset(); } - if (!m_currentObject.hasOverflowClip()) + if (!m_currentObject.hasClipRelatedProperty()) return; const LayoutBox& box = toLayoutBox(m_currentObject); @@ -315,10 +319,13 @@ // Do not clip or scroll for the paint invalidation container, if it scrolls overflow, because it will always use composited // scrolling in this case. if (box == m_paintInvalidationContainer && box.scrollsOverflow()) { - ASSERT(!m_clipped); // The box establishes paint invalidation container, so no m_clipped inherited. + DCHECK(!m_clipped); // The box establishes paint invalidation container, so no m_clipped inherited. } else { - addClipRectRelativeToPaintOffset(box.overflowClipRect(LayoutPoint())); - m_paintOffset -= box.scrolledContentOffset(); + // This won't work fully correctly for fixed-position elements, who should receive CSS clip but for whom the current object + // is not in the containing block chain. + addClipRectRelativeToPaintOffset(box.clippingRect()); + if (box.hasOverflowClip()) + m_paintOffset -= box.scrolledContentOffset(); } // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip if present. @@ -340,7 +347,9 @@ LayoutPoint PaintInvalidationState::computePositionFromPaintInvalidationBacking() const { - ASSERT(!m_didUpdateForChildren); +#if ENABLE(ASSERT) + DCHECK(!m_didUpdateForChildren); +#endif FloatPoint point; if (m_paintInvalidationContainer != &m_currentObject) { @@ -349,8 +358,7 @@ point = m_svgTransform.mapPoint(point); point += FloatPoint(m_paintOffset); #ifdef CHECK_FAST_PATH_SLOW_PATH_EQUALITY - // TODO(wangxianzhu): We can't enable this ASSERT for now because of crbug.com/597745. - // ASSERT(point == slowLocalOriginToAncestorPoint(m_currentObject, m_paintInvalidationContainer, FloatPoint()); + DCHECK(point == slowLocalOriginToAncestorPoint(m_currentObject, m_paintInvalidationContainer, FloatPoint()); #endif } else { point = slowLocalToAncestorPoint(m_currentObject, *m_paintInvalidationContainer, FloatPoint()); @@ -365,7 +373,9 @@ LayoutRect PaintInvalidationState::computePaintInvalidationRectInBacking() const { - ASSERT(!m_didUpdateForChildren); +#if ENABLE(ASSERT) + DCHECK(!m_didUpdateForChildren); +#endif if (m_currentObject.isSVG() && !m_currentObject.isSVGRoot()) return computePaintInvalidationRectInBackingForSVG(); @@ -416,7 +426,9 @@ void PaintInvalidationState::mapLocalRectToPaintInvalidationContainer(LayoutRect& rect) const { - ASSERT(!m_didUpdateForChildren); +#if ENABLE(ASSERT) + DCHECK(!m_didUpdateForChildren); +#endif if (m_cachedOffsetsEnabled) { #ifdef CHECK_FAST_PATH_SLOW_PATH_EQUALITY @@ -456,7 +468,7 @@ PaintLayer& PaintInvalidationState::paintingLayer() const { - ASSERT(&m_paintingLayer == m_currentObject.paintingLayer()); + DCHECK(&m_paintingLayer == m_currentObject.paintingLayer()); return m_paintingLayer; } @@ -512,4 +524,26 @@ #endif // CHECK_FAST_PATH_SLOW_PATH_EQUALITY +static const PaintPropertyTreeBuilderContext& dummyTreeBuilderContext() +{ + DEFINE_STATIC_LOCAL(PaintPropertyTreeBuilderContext, dummyContext, ()); + return dummyContext; +} + +PaintInvalidatorContextAdapter::PaintInvalidatorContextAdapter(const PaintInvalidationState& paintInvalidationState) + : PaintInvalidatorContext(dummyTreeBuilderContext()) + , m_paintInvalidationState(paintInvalidationState) +{ + forcedSubtreeInvalidationFlags = paintInvalidationState.m_forcedSubtreeInvalidationFlags; + paintInvalidationContainer = &paintInvalidationState.paintInvalidationContainer(); + paintingLayer = &paintInvalidationState.paintingLayer(); +} + + +void PaintInvalidatorContextAdapter::mapLocalRectToPaintInvalidationBacking(const LayoutObject& object, LayoutRect& rect) const +{ + DCHECK(&object == &m_paintInvalidationState.currentObject()); + m_paintInvalidationState.mapLocalRectToPaintInvalidationBacking(rect); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/PaintInvalidationState.h b/third_party/WebKit/Source/core/layout/PaintInvalidationState.h index 014b68ef..c7400eb 100644 --- a/third_party/WebKit/Source/core/layout/PaintInvalidationState.h +++ b/third_party/WebKit/Source/core/layout/PaintInvalidationState.h
@@ -6,6 +6,7 @@ #define PaintInvalidationState_h #include "core/CoreExport.h" +#include "core/paint/PaintInvalidator.h" #include "platform/geometry/LayoutRect.h" #include "platform/graphics/PaintInvalidationReason.h" #include "platform/transforms/AffineTransform.h" @@ -56,13 +57,13 @@ bool hasForcedSubtreeInvalidationFlags() const { return m_forcedSubtreeInvalidationFlags; } - bool forcedSubtreeInvalidationCheckingWithinContainer() const { return m_forcedSubtreeInvalidationFlags & InvalidationChecking; } - void setForceSubtreeInvalidationCheckingWithinContainer() { m_forcedSubtreeInvalidationFlags |= InvalidationChecking; } + bool forcedSubtreeInvalidationCheckingWithinContainer() const { return m_forcedSubtreeInvalidationFlags & PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; } + void setForceSubtreeInvalidationCheckingWithinContainer() { m_forcedSubtreeInvalidationFlags |= PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; } - bool forcedSubtreeFullInvalidationWithinContainer() const { return m_forcedSubtreeInvalidationFlags & FullInvalidation; } + bool forcedSubtreeFullInvalidationWithinContainer() const { return m_forcedSubtreeInvalidationFlags & PaintInvalidatorContext::ForcedSubtreeFullInvalidation; } - bool forcedSubtreeInvalidationRectUpdateWithinContainerOnly() const { return m_forcedSubtreeInvalidationFlags == InvalidationRectUpdate; } - void setForceSubtreeInvalidationRectUpdateWithinContainer() { m_forcedSubtreeInvalidationFlags |= InvalidationRectUpdate; } + bool forcedSubtreeInvalidationRectUpdateWithinContainerOnly() const { return m_forcedSubtreeInvalidationFlags == PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; } + void setForceSubtreeInvalidationRectUpdateWithinContainer() { m_forcedSubtreeInvalidationFlags |= PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate; } const LayoutBoxModelObject& paintInvalidationContainer() const { return *m_paintInvalidationContainer; } @@ -78,12 +79,11 @@ PaintLayer& paintingLayer() const; -#if ENABLE(ASSERT) const LayoutObject& currentObject() const { return m_currentObject; } -#endif private: friend class VisualRectMappingTest; + friend class PaintInvalidatorContextAdapter; void mapLocalRectToPaintInvalidationContainer(LayoutRect&) const; @@ -96,12 +96,6 @@ const LayoutObject& m_currentObject; - enum ForcedSubtreeInvalidationFlag { - InvalidationChecking = 1 << 0, - InvalidationRectUpdate = 1 << 1, - FullInvalidation = 1 << 2, - FullInvalidationForStackedContents = 1 << 3, - }; unsigned m_forcedSubtreeInvalidationFlags; bool m_clipped; @@ -160,6 +154,15 @@ #endif }; +// This is temporary to adapt legacy PaintInvalidationState to PaintInvalidatorContext +class PaintInvalidatorContextAdapter : public PaintInvalidatorContext { +public: + PaintInvalidatorContextAdapter(const PaintInvalidationState&); + void mapLocalRectToPaintInvalidationBacking(const LayoutObject&, LayoutRect&) const override; +private: + const PaintInvalidationState& m_paintInvalidationState; +}; + } // namespace blink #endif // PaintInvalidationState_h
diff --git a/third_party/WebKit/Source/core/layout/VisualRectMappingTest.cpp b/third_party/WebKit/Source/core/layout/VisualRectMappingTest.cpp index 1080574..a0ec91f 100644 --- a/third_party/WebKit/Source/core/layout/VisualRectMappingTest.cpp +++ b/third_party/WebKit/Source/core/layout/VisualRectMappingTest.cpp
@@ -578,4 +578,40 @@ checkPaintInvalidationStateRectMapping(rect, absoluteOverflowRect, *absolute, layoutView(), *stackingContext); } +TEST_F(VisualRectMappingTest, CSSClip) +{ + setBodyInnerHTML( + "<div id='container' style='position: absolute; top: 0px; left: 0px; clip: rect(0px, 200px, 200px, 0px)'>" + " <div id='target' style='width: 400px; height: 400px'></div>" + " </div>" + "</div>"); + + LayoutBox* target = toLayoutBox(getLayoutObjectByElementId("target")); + + LayoutRect targetOverflowRect = target->localOverflowRectForPaintInvalidation(); + EXPECT_EQ(LayoutRect(0, 0, 400, 400), targetOverflowRect); + LayoutRect rect = targetOverflowRect; + EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect)); + EXPECT_EQ(LayoutRect(0, 0, 200, 200), rect); + checkPaintInvalidationStateRectMapping(rect, targetOverflowRect, *target, layoutView(), layoutView()); +} + +TEST_F(VisualRectMappingTest, ContainPaint) +{ + setBodyInnerHTML( + "<div id='container' style='position: absolute; top: 0px; left: 0px; width: 200px; height: 200px; contain: paint'>" + " <div id='target' style='width: 400px; height: 400px'></div>" + " </div>" + "</div>"); + + LayoutBox* target = toLayoutBox(getLayoutObjectByElementId("target")); + + LayoutRect targetOverflowRect = target->localOverflowRectForPaintInvalidation(); + EXPECT_EQ(LayoutRect(0, 0, 400, 400), targetOverflowRect); + LayoutRect rect = targetOverflowRect; + EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect)); + EXPECT_EQ(LayoutRect(0, 0, 200, 200), rect); + checkPaintInvalidationStateRectMapping(rect, targetOverflowRect, *target, layoutView(), layoutView()); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp index f10007a..6248097b 100644 --- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp +++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.cpp
@@ -581,14 +581,8 @@ static IntRect clipBox(LayoutBox* layoutObject) { - LayoutRect result = LayoutRect(LayoutRect::infiniteIntRect()); - if (layoutObject->hasOverflowClip() || layoutObject->style()->containsPaint()) - result = layoutObject->overflowClipRect(LayoutPoint()); - - if (layoutObject->hasClip()) - result.intersect(layoutObject->clipRect(LayoutPoint())); - - return pixelSnappedIntRect(result); + // TODO(chrishtr): pixel snapping is most likely incorrect here. + return pixelSnappedIntRect(layoutObject->clippingRect()); } static LayoutPoint computeOffsetFromCompositedAncestor(const PaintLayer* layer, const PaintLayer* compositedAncestor) @@ -2434,7 +2428,7 @@ page->setIsPainting(true); #endif - TRACE_EVENT1("devtools.timeline", "Paint", "data", InspectorPaintEvent::data(m_owningLayer.layoutObject(), LayoutRect(interestRect), graphicsLayer)); + TRACE_EVENT1("devtools.timeline,rail", "Paint", "data", InspectorPaintEvent::data(m_owningLayer.layoutObject(), LayoutRect(interestRect), graphicsLayer)); PaintLayerFlags paintLayerFlags = 0; if (graphicsLayerPaintingPhase & GraphicsLayerPaintBackground) @@ -2543,22 +2537,10 @@ } #endif -void CompositedLayerMapping::notifyFirstPaint() +void CompositedLayerMapping::notifyPaint(bool isFirstPaint, bool textPainted, bool imagePainted) { if (PaintTiming* timing = m_owningLayer.paintTiming()) - timing->markFirstPaint(); -} - -void CompositedLayerMapping::notifyFirstTextPaint() -{ - if (PaintTiming* timing = m_owningLayer.paintTiming()) - timing->markFirstTextPaint(); -} - -void CompositedLayerMapping::notifyFirstImagePaint() -{ - if (PaintTiming* timing = m_owningLayer.paintTiming()) - timing->markFirstImagePaint(); + timing->notifyPaint(isFirstPaint, textPainted, imagePainted); } IntRect CompositedLayerMapping::pixelSnappedCompositedBounds() const
diff --git a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h index d711756..bd7baaed 100644 --- a/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h +++ b/third_party/WebKit/Source/core/layout/compositing/CompositedLayerMapping.h
@@ -155,9 +155,7 @@ void updateElementIdAndCompositorMutableProperties(); // GraphicsLayerClient interface - void notifyFirstPaint() override; - void notifyFirstTextPaint() override; - void notifyFirstImagePaint() override; + void notifyPaint(bool isFirstPaint, bool textPainted, bool imagePainted) override; IntRect computeInterestRect(const GraphicsLayer*, const IntRect& previousInterestRect) const override; LayoutSize subpixelAccumulation() const final; @@ -219,6 +217,13 @@ void adjustForCompositedScrolling(const GraphicsLayer*, IntSize& offset) const; + // Returns true for layers with scrollable overflow which have a background + // that can be painted into the composited scrolling contents layer (i.e. + // the background can scroll with the content). When the background is also + // opaque this allows us to composite the scroller even on low DPI as we can + // draw with subpixel anti-aliasing. + bool shouldPaintBackgroundOntoScrollingContentsLayer() const; + private: IntRect recomputeInterestRect(const GraphicsLayer*) const; static bool interestRectChangedEnoughToRepaint(const IntRect& previousInterestRect, const IntRect& newInterestRect, const IntSize& layerSize); @@ -329,13 +334,6 @@ // not appear earlier in the set of layers for this object. bool invalidateLayerIfNoPrecedingEntry(size_t); - // Returns true for layers with scrollable overflow which have a background - // that can be painted into the composited scrolling contents layer (i.e. - // the background can scroll with the content). When the background is also - // opaque this allows us to composite the scroller even on low DPI as we can - // draw with subpixel anti-aliasing. - bool shouldPaintBackgroundOntoScrollingContentsLayer() const; - PaintLayer& m_owningLayer; // The hierarchy of layers that is maintained by the CompositedLayerMapping looks like this:
diff --git a/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc b/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc index 027e1f7..4411e3b 100644 --- a/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc +++ b/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.cc
@@ -3,6 +3,11 @@ // found in the LICENSE file. #include "core/layout/ng/layout_ng_block_flow.h" +#include "core/layout/ng/ng_constraint_space.h" +#include "core/layout/ng/ng_block_layout_algorithm.h" +#include "core/layout/ng/ng_box_iterator.h" +#include "core/layout/ng/ng_fragment.h" +#include "core/layout/LayoutAnalyzer.h" namespace blink { @@ -13,4 +18,13 @@ return type == LayoutObjectNGBlockFlow || LayoutBlockFlow::isOfType(type); } +void LayoutNGBlockFlow::layoutBlock(bool relayoutChildren) { + LayoutAnalyzer::BlockScope analyzer(*this); + + const auto& constraintSpace = NGConstraintSpace::fromLayoutObject(*this); + NGBox box(this); + box.layout(constraintSpace); + clearNeedsLayout(); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.h b/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.h index 0dd7a3b..70ae361 100644 --- a/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.h +++ b/third_party/WebKit/Source/core/layout/ng/layout_ng_block_flow.h
@@ -15,6 +15,8 @@ explicit LayoutNGBlockFlow(Element*); ~LayoutNGBlockFlow() override = default; + void layoutBlock(bool relayoutChildren) override; + private: bool isOfType(LayoutObjectType) const override; };
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc index 56d0fad..ba6d02ee 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
@@ -15,8 +15,8 @@ NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm( PassRefPtr<const ComputedStyle> style, - NGBox firstChild) - : m_style(style), m_firstChild(firstChild) {} + NGBoxIterator boxIterator) + : m_style(style), m_boxIterator(boxIterator) {} NGFragment* NGBlockLayoutAlgorithm::layout( const NGConstraintSpace& constraintSpace) { @@ -24,10 +24,9 @@ computeInlineSizeForFragment(constraintSpace, *m_style); HeapVector<Member<const NGFragmentBase>> childFragments; - LayoutUnit contentSize; - for (NGBox curr = m_firstChild; curr; curr.nextSibling()) { - NGFragment* fragment = curr.layout(constraintSpace); + for (NGBox box : m_boxIterator) { + NGFragment* fragment = box.layout(constraintSpace); // TODO(layout-ng): Take margins into account fragment->setOffset(LayoutUnit(), contentSize); contentSize += fragment->blockSize(); @@ -36,9 +35,9 @@ LayoutUnit blockSize = computeBlockSizeForFragment(constraintSpace, *m_style, contentSize); - NGFragment* returnFragment = new NGFragment( - inlineSize, blockSize, inlineSize, blockSize, - NGFragmentBase::HorizontalTopBottom, NGFragmentBase::LeftToRight); + NGFragment* returnFragment = + new NGFragment(inlineSize, blockSize, inlineSize, blockSize, + HorizontalTopBottom, LeftToRight); returnFragment->swapChildren(childFragments); return returnFragment; }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h index 9f5f30b..54ffa527 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
@@ -7,6 +7,8 @@ #include "core/CoreExport.h" #include "core/layout/ng/ng_box.h" +#include "core/layout/ng/ng_box_iterator.h" +#include "core/layout/ng/ng_layout_algorithm.h" #include "wtf/RefPtr.h" namespace blink { @@ -17,20 +19,23 @@ // A class for general block layout (e.g. a <div> with no special style). // Lays out the children in sequence. -class CORE_EXPORT NGBlockLayoutAlgorithm { +class CORE_EXPORT NGBlockLayoutAlgorithm : public NGLayoutAlgorithm { public: - NGBlockLayoutAlgorithm(PassRefPtr<const ComputedStyle>, NGBox); + // Default constructor. + // @param style Style reference of the block that is being laid out. + // @param boxIterator Iterator for the block's children. + NGBlockLayoutAlgorithm(PassRefPtr<const ComputedStyle>, NGBoxIterator); // Actual layout implementation. Lays out the children in sequence within the // constraints given by the NGConstraintSpace. Returns a fragment with the // resulting layout information. // This function can not be const because for interruptible layout, we have // to be able to store state information. - NGFragment* layout(const NGConstraintSpace&); + NGFragment* layout(const NGConstraintSpace&) override; private: RefPtr<const ComputedStyle> m_style; - NGBox m_firstChild; + NGBoxIterator m_boxIterator; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc index f008d68..6d2432b 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
@@ -4,7 +4,7 @@ #include "core/layout/ng/ng_block_layout_algorithm.h" -#include "core/layout/ng/ng_box.h" +#include "core/layout/ng/ng_box_iterator.h" #include "core/layout/ng/ng_constraint_space.h" #include "core/layout/ng/ng_fragment.h" #include "core/style/ComputedStyle.h" @@ -15,9 +15,7 @@ class NGBlockLayoutAlgorithmTest : public ::testing::Test { protected: - void SetUp() override { - style_ = ComputedStyle::create(); - } + void SetUp() override { style_ = ComputedStyle::create(); } RefPtr<ComputedStyle> style_; }; @@ -26,9 +24,12 @@ style_->setWidth(Length(30, Fixed)); style_->setHeight(Length(40, Fixed)); - NGConstraintSpace space(LayoutUnit(100), LayoutUnit(-1)); + NGLogicalSize container_size; + container_size.inlineSize = LayoutUnit(100); + container_size.blockSize = LayoutUnit(-1); + NGConstraintSpace space(container_size); - NGBlockLayoutAlgorithm algorithm(style_, NGBox(nullptr)); + NGBlockLayoutAlgorithm algorithm(style_, NGBoxIterator(NGBox())); NGFragment* frag = algorithm.layout(space); EXPECT_EQ(frag->inlineSize(), LayoutUnit(30)); EXPECT_EQ(frag->blockSize(), LayoutUnit(40));
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_box.cc b/third_party/WebKit/Source/core/layout/ng/ng_box.cc index 7f8a30f..a32d985 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_box.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_box.cc
@@ -6,24 +6,34 @@ #include "core/layout/LayoutObject.h" #include "core/layout/ng/ng_block_layout_algorithm.h" +#include "core/layout/ng/ng_box_iterator.h" +#include "core/layout/ng/ng_fragment.h" +#include "core/layout/LayoutBox.h" namespace blink { NGFragment* NGBox::layout(const NGConstraintSpace& constraintSpace) { - NGBlockLayoutAlgorithm algorithm(style(), firstChild()); - return algorithm.layout(constraintSpace); + NGBlockLayoutAlgorithm algorithm(style(), childIterator()); + m_layoutBox->clearNeedsLayout(); + NGFragment* fragment = algorithm.layout(constraintSpace); + m_layoutBox->setLogicalWidth(fragment->inlineSize()); + m_layoutBox->setLogicalHeight(fragment->blockSize()); + return fragment; } const ComputedStyle* NGBox::style() const { - return m_layoutObject->style(); + return m_layoutBox->style(); } -const NGBox NGBox::firstChild() const { - return NGBox(m_layoutObject->slowFirstChild()); +NGBoxIterator NGBox::childIterator() { + return NGBoxIterator(firstChild()); } -const NGBox NGBox::nextSibling() const { - return NGBox(m_layoutObject->nextSibling()); +NGBox NGBox::nextSibling() const { + return m_layoutBox ? NGBox(m_layoutBox->nextSibling()) : NGBox(); } +NGBox NGBox::firstChild() const { + return m_layoutBox ? NGBox(m_layoutBox->slowFirstChild()) : NGBox(); +} } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_box.h b/third_party/WebKit/Source/core/layout/ng/ng_box.h index e2a9e2c34..39d5e83 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_box.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_box.h
@@ -5,33 +5,39 @@ #ifndef NGBox_h #define NGBox_h +#include "core/layout/LayoutBox.h" #include "core/CoreExport.h" #include "platform/heap/Handle.h" namespace blink { class ComputedStyle; -class LayoutObject; +class LayoutBox; +class NGBoxIterator; class NGConstraintSpace; class NGFragment; // Represents a node to be laid out. class CORE_EXPORT NGBox final { public: - explicit NGBox(const LayoutObject* layoutObject) - : m_layoutObject(layoutObject) {} + explicit NGBox(LayoutObject* layoutObject) + : m_layoutBox(toLayoutBox(layoutObject)) {} - operator bool() const { return m_layoutObject; } + NGBox() : m_layoutBox(nullptr) {} + + // Returns an iterator that will iterate over this box's children, if any. + NGBoxIterator childIterator(); + operator bool() const { return m_layoutBox; } NGFragment* layout(const NGConstraintSpace&); const ComputedStyle* style() const; - // TODO(layout-ng): Returning a children iterator would be better here. - const NGBox firstChild() const; - const NGBox nextSibling() const; + NGBox nextSibling() const; + + NGBox firstChild() const; private: - const LayoutObject* m_layoutObject; + LayoutBox* m_layoutBox; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_box_iterator.cc b/third_party/WebKit/Source/core/layout/ng/ng_box_iterator.cc new file mode 100644 index 0000000..3560086a --- /dev/null +++ b/third_party/WebKit/Source/core/layout/ng/ng_box_iterator.cc
@@ -0,0 +1,35 @@ +// Copyright 2016 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 "core/layout/ng/ng_box_iterator.h" +#include "core/layout/ng/ng_box.h" + +namespace blink { + +NGBoxIterator::NGBoxIterator(NGBox box) : box_(box) {} + +NGBoxIterator::iterator& NGBoxIterator::iterator::operator=( + const NGBoxIterator::iterator& otherValue) { + box_ = otherValue.box_; + return (*this); +} + +NGBoxIterator::iterator& NGBoxIterator::iterator::operator++() { + box_ = box_.nextSibling(); + return (*this); +} + +bool NGBoxIterator::iterator::operator!=(const iterator& other) { + return box_ != other.box_; +} + +NGBox NGBoxIterator::iterator::operator*() { + return box_; +} + +NGBoxIterator::iterator NGBoxIterator::begin() const { + return iterator(box_); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_box_iterator.h b/third_party/WebKit/Source/core/layout/ng/ng_box_iterator.h new file mode 100644 index 0000000..8d314ed --- /dev/null +++ b/third_party/WebKit/Source/core/layout/ng/ng_box_iterator.h
@@ -0,0 +1,40 @@ +// Copyright 2016 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 NGBoxIterator_h +#define NGBoxIterator_h + +#include "core/layout/LayoutObject.h" +#include "core/layout/ng/ng_box.h" + +namespace blink { + +class NGBox; + +// NG Box iterator over siblings of the layout object. +class CORE_EXPORT NGBoxIterator + : public std::iterator<std::forward_iterator_tag, NGBox> { + public: + class iterator { + public: + iterator& operator=(const iterator& otherValue); + iterator(NGBox box) : box_(box) {} + iterator& operator++(); + bool operator!=(const iterator& other); + NGBox operator*(); + + private: + NGBox box_; + }; + explicit NGBoxIterator(NGBox); + + iterator begin() const; + iterator end() const { return iterator(NGBox()); } + + private: + NGBox box_; +}; + +} // namespace blink +#endif // NGBoxIterator_h
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc index f0f49438..f96e1225 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
@@ -9,10 +9,8 @@ namespace blink { -NGConstraintSpace::NGConstraintSpace(LayoutUnit inlineContainerSize, - LayoutUnit blockContainerSize) { - m_inlineContainerSize = inlineContainerSize; - m_blockContainerSize = blockContainerSize; +NGConstraintSpace::NGConstraintSpace(NGLogicalSize container_size) { + container_size_ = container_size; m_inlineTriggersScrollbar = 0; m_blockTriggersScrollbar = 0; m_fixedInlineSize = 0; @@ -36,7 +34,10 @@ containerLogicalWidth = child.overrideLogicalContentHeight(); fixedBlock = true; } - NGConstraintSpace space(containerLogicalWidth, containerLogicalHeight); + NGLogicalSize size; + size.inlineSize = containerLogicalWidth; + size.blockSize = containerLogicalHeight; + NGConstraintSpace space(size); space.setOverflowTriggersScrollbar( child.styleRef().overflowInlineDirection() == OverflowAuto, child.styleRef().overflowBlockDirection() == OverflowAuto);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h index e4ee8b10..ea6f03e3 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
@@ -6,7 +6,7 @@ #define NGConstraintSpace_h #include "core/CoreExport.h" -#include "platform/LayoutUnit.h" +#include "core/layout/ng/ng_units.h" #include "wtf/DoublyLinkedList.h" namespace blink { @@ -40,6 +40,16 @@ ExcludeInlineBoth }; +enum NGWritingMode { + HorizontalTopBottom = 0, + VerticalRightLeft = 1, + VerticalLeftRight = 2, + SidewaysRightLeft = 3, + SidewaysLeftRight = 4 +}; + +enum NGDirection { LeftToRight = 0, RightToLeft = 1 }; + class NGExclusion { public: NGExclusion(); @@ -48,9 +58,8 @@ class CORE_EXPORT NGConstraintSpace { public: - NGConstraintSpace(LayoutUnit inlineContainerSize, - LayoutUnit blockContainerSize); - ~NGConstraintSpace() {} + NGConstraintSpace(NGLogicalSize container_size); + virtual ~NGConstraintSpace() {} // Constructs Layout NG constraint space from legacy layout object. static NGConstraintSpace fromLayoutObject(const LayoutBox&); @@ -60,15 +69,18 @@ void setFixedSize(bool inlineFixed, bool blockFixed); void setFragmentationType(NGFragmentationType); - // Size of the container in each direction. Used for the following - // three cases: + // Size of the container. Used for the following three cases: // 1) Percentage resolution. // 2) Resolving absolute positions of children. // 3) Defining the threashold that triggers the presence of a scrollbar. Only // applies if the corresponding scrollbarTrigger flag has been set for the // direction. - LayoutUnit inlineContainerSize() const { return m_inlineContainerSize; } - LayoutUnit blockContainerSize() const { return m_blockContainerSize; } + NGLogicalSize ContainerSize() const { return container_size_; } + + // Returns the effective size of the constraint space. Defaults to + // ContainerSize() for the root constraint space but derived constraint spaces + // overrides it to return the size of the layout opportunity. + virtual NGLogicalSize Size() const { return ContainerSize(); } // Whether exceeding the containerSize triggers the presence of a scrollbar // for the indicated direction. @@ -102,8 +114,7 @@ void subtract(const NGFragment); private: - LayoutUnit m_inlineContainerSize; - LayoutUnit m_blockContainerSize; + NGLogicalSize container_size_; unsigned m_fixedInlineSize : 1; unsigned m_fixedBlockSize : 1; @@ -130,25 +141,6 @@ NGExclusionFlowType m_avoid; }; -class CORE_EXPORT NGDerivedConstraintSpace final : NGConstraintSpace { - public: - ~NGDerivedConstraintSpace(); - - LayoutUnit inlineOffset() const; - LayoutUnit blockOffset() const; - LayoutUnit inlineSize() const; - LayoutUnit blockSize() const; - - private: - NGDerivedConstraintSpace(); - - LayoutUnit m_inlineOffset; - LayoutUnit m_blockOffset; - LayoutUnit m_inlineSize; - LayoutUnit m_blockSize; - NGConstraintSpace* m_original; -}; - } // namespace blink #endif // NGConstraintSpace_h
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_derived_constraint_space.h b/third_party/WebKit/Source/core/layout/ng/ng_derived_constraint_space.h new file mode 100644 index 0000000..c11e4613 --- /dev/null +++ b/third_party/WebKit/Source/core/layout/ng/ng_derived_constraint_space.h
@@ -0,0 +1,44 @@ +// Copyright 2016 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 NGConstraintSpace_h +#define NGConstraintSpace_h + +#include "core/CoreExport.h" +#include "core/layout/ng/ng_constraint_space.h" +#include "core/layout/ng/ng_units.h" +#include "platform/LayoutUnit.h" +#include "wtf/DoublyLinkedList.h" + +namespace blink { + +class CORE_EXPORT NGDerivedConstraintSpace final : public NGConstraintSpace { + public: + ~NGDerivedConstraintSpace(); + + NGLogicalOffset Offset() const { return offset_; } + NGLogicalSize Size() const override { return size_; } + + private: + NGDerivedConstraintSpace(const NGConstraintSpace* original, + NGLogicalOffset offset, + NGLogicalSize size, + NGWritingMode writingMode, + NGDirection direction) + : original_(original), + offset_(offset), + size_(size), + writingMode_(writingMode), + direction_(direction) {} + + const NGConstraintSpace* original_; + NGLogicalOffset offset_; + NGLogicalSize size_; + NGWritingMode writingMode_; + NGDirection direction_; +}; + +} // namespace blink + +#endif // NGConstraintSpace_h
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_fragment.h index 59ebae85..5b5c13d 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_fragment.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment.h
@@ -7,6 +7,7 @@ #include "core/CoreExport.h" #include "core/layout/ng/ng_fragment_base.h" +#include "core/layout/ng/ng_constraint_space.h" #include "platform/LayoutUnit.h" #include "platform/heap/Handle.h" #include "wtf/Vector.h"
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_base.cc b/third_party/WebKit/Source/core/layout/ng/ng_fragment_base.cc index 223475b..f94e94f8 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_base.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_base.cc
@@ -4,7 +4,7 @@ #include "core/layout/ng/ng_fragment_base.h" #include "core/layout/ng/ng_fragment.h" -#include "core/layout/ng/ng_text.h" +#include "core/layout/ng/ng_text_fragment.h" namespace blink { @@ -35,7 +35,7 @@ DEFINE_TRACE(NGFragmentBase) { if (type() == FragmentText) - static_cast<NGText*>(this)->traceAfterDispatch(visitor); + static_cast<NGTextFragment*>(this)->traceAfterDispatch(visitor); else static_cast<NGFragment*>(this)->traceAfterDispatch(visitor); }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_base.h b/third_party/WebKit/Source/core/layout/ng/ng_fragment_base.h index 03c5df9..c9260b9 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_base.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_base.h
@@ -6,6 +6,7 @@ #define NGFragmentBase_h #include "core/CoreExport.h" +#include "core/layout/ng/ng_constraint_space.h" #include "platform/LayoutUnit.h" #include "platform/heap/Handle.h" #include "wtf/Vector.h" @@ -16,16 +17,6 @@ public: enum NGFragmentType { FragmentBox = 0, FragmentText = 1 }; - // TODO(eae): We might want to re-use WritingMode and Direction from style. - enum NGWritingMode { - HorizontalTopBottom = 0, - VerticalRightLeft = 1, - VerticalLeftRight = 2, - SidewaysRightLeft = 3, - SidewaysLeftRight = 4 - }; - enum NGDirection { LeftToRight = 0, RightToLeft = 1 }; - NGFragmentType type() const { return static_cast<NGFragmentType>(m_type); } NGWritingMode writingMode() const { return static_cast<NGWritingMode>(m_writingMode);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_layout_algorithm.h new file mode 100644 index 0000000..b77f270 --- /dev/null +++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_algorithm.h
@@ -0,0 +1,35 @@ +// Copyright 2016 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 NGLayoutAlgorithm_h +#define NGLayoutAlgorithm_h + +#include "core/CoreExport.h" +#include "wtf/Allocator.h" +#include "wtf/Noncopyable.h" + +namespace blink { + +class NGConstraintSpace; +class NGFragment; + +// Base class for all LayoutNG algorithms. +class CORE_EXPORT NGLayoutAlgorithm { + WTF_MAKE_NONCOPYABLE(NGLayoutAlgorithm); + USING_FAST_MALLOC(NGLayoutAlgorithm); + + public: + NGLayoutAlgorithm() {} + + // Actual layout function. Lays out the children and descendents within the + // constraints given by the NGConstraintSpace. Returns a fragment with the + // resulting layout information. + // This function can not be const because for interruptible layout, we have + // to be able to store state information. + virtual NGFragment* layout(const NGConstraintSpace&) = 0; +}; + +} // namespace blink + +#endif // NGLayoutAlgorithm_h
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_input_text.h b/third_party/WebKit/Source/core/layout/ng/ng_layout_input_text.h new file mode 100644 index 0000000..146b57b --- /dev/null +++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_input_text.h
@@ -0,0 +1,62 @@ +// Copyright 2016 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 NGLayoutInputText_h +#define NGLayoutInputText_h + +#include "core/CoreExport.h" +#include "core/style/ComputedStyle.h" +#include "platform/fonts/shaping/CachingWordShaper.h" +#include "platform/fonts/shaping/ShapeResult.h" +#include "platform/heap/Handle.h" +#include "wtf/Vector.h" +#include "wtf/text/WTFString.h" + +namespace blink { + +// Struct representing a single text node or styled inline element with text +// content. In this representation TextNodes are merged up into their parent +// inline element where possible. +struct NGLayoutInputTextItem { + unsigned start_offset; + unsigned end_offset; + RefPtr<ComputedStyle> style; +}; + +// Class representing all text content for a given inline layout root in the +// layout input tree. +// The content is stored as a single string with collapsed white-space (if +// applicable) to allow cross-element shaping. Each item contains a start and +// end offset representing the content of said item. +class CORE_EXPORT NGLayoutInputText final + : public GarbageCollectedFinalized<NGLayoutInputText> { + public: + using const_iterator = Vector<NGLayoutInputTextItem>::const_iterator; + + NGLayoutInputText() {} + + void Shape(); + const_iterator begin() const { return items_.begin(); } + const_iterator end() const { return items_.end(); } + String Text(unsigned start_offset, unsigned end_offset) const { + return text_.substring(start_offset, end_offset); + } + + DEFINE_INLINE_TRACE() {} + + private: + // TODO(eae): This should probably always be utf-8 to reduce the + // memory and conversion overhead. We can't really re-use the + // TextContent string as this is stored post white-space + // collapsing. Also note that shaping can be done in either + // utf-8 or utf-16. Currently we always shape in utf16 and + // upconvert latin-1. + String text_; + RefPtr<ShapeResult> shape_result_; + Vector<NGLayoutInputTextItem> items_; +}; + +} // namespace blink + +#endif // NGLayoutInputText_h
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc index 0f039e89..30fb60a 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc +++ b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.cc
@@ -15,69 +15,88 @@ // - positioned and/or replaced calculations // - Handle margins for fill-available and width: auto -LayoutUnit resolveInlineLength(LengthResolveType type, +LayoutUnit resolveInlineLength(const NGConstraintSpace& constraintSpace, const Length& length, - const NGConstraintSpace& constraintSpace) { + LengthResolveType type) { + // TODO(layout-ng): Handle min/max/fit-content DCHECK(!length.isMaxSizeNone()); + if (type == LengthResolveType::MinSize && length.isAuto()) return LayoutUnit(); - // TODO(layout-ng): Handle min/max/fit-content - return valueForLength(length, constraintSpace.inlineContainerSize()); + + return valueForLength(length, constraintSpace.ContainerSize().inlineSize); } -LayoutUnit resolveBlockLength(LengthResolveType type, +LayoutUnit resolveBlockLength(const NGConstraintSpace& constraintSpace, const Length& length, - const NGConstraintSpace& constraintSpace, - LayoutUnit contentContribution) { + LayoutUnit contentSize, + LengthResolveType type) { DCHECK(!length.isMaxSizeNone()); + if (type == LengthResolveType::MinSize && length.isAuto()) return LayoutUnit(); + if (length.isAuto()) - return contentContribution; + return contentSize; + if (length.isMinContent() || length.isMaxContent() || length.isFitContent()) - return contentContribution; - return valueForLength(length, constraintSpace.blockContainerSize()); + return contentSize; + + return valueForLength(length, constraintSpace.ContainerSize().blockSize); } LayoutUnit computeInlineSizeForFragment( const NGConstraintSpace& constraintSpace, const ComputedStyle& style) { - LayoutUnit extent = resolveInlineLength( - LengthResolveType::ContentSize, style.logicalWidth(), constraintSpace); + if (constraintSpace.fixedInlineSize()) + return constraintSpace.ContainerSize().inlineSize; + + LayoutUnit extent = resolveInlineLength(constraintSpace, style.logicalWidth(), + LengthResolveType::ContentSize); + Length maxLength = style.logicalMaxWidth(); if (!maxLength.isMaxSizeNone()) { - LayoutUnit max = resolveInlineLength(LengthResolveType::MaxSize, maxLength, - constraintSpace); + LayoutUnit max = resolveInlineLength(constraintSpace, maxLength, + LengthResolveType::MaxSize); extent = std::min(extent, max); } - LayoutUnit min = resolveInlineLength( - LengthResolveType::MinSize, style.logicalMinWidth(), constraintSpace); + + LayoutUnit min = resolveInlineLength(constraintSpace, style.logicalMinWidth(), + LengthResolveType::MinSize); extent = std::max(extent, min); + if (style.boxSizing() == BoxSizingContentBox) { // TODO(layout-ng): Compute border/padding size and add it } + return extent; } LayoutUnit computeBlockSizeForFragment(const NGConstraintSpace& constraintSpace, const ComputedStyle& style, - LayoutUnit contentContribution) { + LayoutUnit contentSize) { + if (constraintSpace.fixedBlockSize()) + return constraintSpace.ContainerSize().blockSize; + LayoutUnit extent = - resolveBlockLength(LengthResolveType::ContentSize, style.logicalHeight(), - constraintSpace, contentContribution); + resolveBlockLength(constraintSpace, style.logicalHeight(), contentSize, + LengthResolveType::ContentSize); Length maxLength = style.logicalMaxHeight(); + if (!maxLength.isMaxSizeNone()) { - LayoutUnit max = resolveBlockLength(LengthResolveType::MaxSize, maxLength, - constraintSpace, contentContribution); + LayoutUnit max = resolveBlockLength(constraintSpace, maxLength, contentSize, + LengthResolveType::MaxSize); extent = std::min(extent, max); } - LayoutUnit min = - resolveBlockLength(LengthResolveType::MinSize, style.logicalMinHeight(), - constraintSpace, contentContribution); + + LayoutUnit min = resolveBlockLength(constraintSpace, style.logicalMinHeight(), + contentSize, LengthResolveType::MinSize); extent = std::max(extent, min); + if (style.boxSizing() == BoxSizingContentBox) { // TODO(layout-ng): Compute border/padding size and add it } + return extent; }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.h b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.h index c5956db..a42f1da 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_length_utils.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_length_utils.h
@@ -17,16 +17,16 @@ // Convert an inline-axis length to a layout unit using the given constraint // space. -CORE_EXPORT LayoutUnit resolveInlineLength(LengthResolveType, +CORE_EXPORT LayoutUnit resolveInlineLength(const NGConstraintSpace&, const Length&, - const NGConstraintSpace&); + LengthResolveType); // Convert a block-axis length to a layout unit using the given constraint -// space. -CORE_EXPORT LayoutUnit resolveBlockLength(LengthResolveType, +// space and content size. +CORE_EXPORT LayoutUnit resolveBlockLength(const NGConstraintSpace&, const Length&, - const NGConstraintSpace&, - LayoutUnit contentContribution); + LayoutUnit contentSize, + LengthResolveType); // Resolves the given length to a layout unit, constraining it by the min // logical width and max logical width properties from the ComputedStyle @@ -37,10 +37,9 @@ // Resolves the given length to a layout unit, constraining it by the min // logical height and max logical height properties from the ComputedStyle // object. -CORE_EXPORT LayoutUnit -computeBlockSizeForFragment(const NGConstraintSpace&, - const ComputedStyle& style, - LayoutUnit contentContribution); +CORE_EXPORT LayoutUnit computeBlockSizeForFragment(const NGConstraintSpace&, + const ComputedStyle& style, + LayoutUnit contentSize); } // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_length_utils_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_length_utils_test.cc new file mode 100644 index 0000000..f65529e5 --- /dev/null +++ b/third_party/WebKit/Source/core/layout/ng/ng_length_utils_test.cc
@@ -0,0 +1,162 @@ +// Copyright 2016 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 "core/layout/ng/ng_length_utils.h" + +#include "core/layout/ng/ng_constraint_space.h" +#include "core/style/ComputedStyle.h" +#include "platform/CalculationValue.h" +#include "platform/LayoutUnit.h" +#include "platform/Length.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "wtf/RefPtr.h" + +namespace blink { +namespace { + +class NGLengthUtilsTest : public ::testing::Test { + protected: + void SetUp() override { style_ = ComputedStyle::create(); } + + static NGConstraintSpace constructConstraintSpace(int inline_size, + int block_size) { + NGLogicalSize container_size; + container_size.inlineSize = LayoutUnit(inline_size); + container_size.blockSize = LayoutUnit(block_size); + return NGConstraintSpace(container_size); + } + + LayoutUnit resolveInlineLength( + const Length& length, + LengthResolveType type = LengthResolveType::ContentSize) { + NGConstraintSpace constraintSpace = constructConstraintSpace(200, 300); + return ::blink::resolveInlineLength(constraintSpace, length, type); + } + + LayoutUnit resolveBlockLength( + const Length& length, + LengthResolveType type = LengthResolveType::ContentSize, + LayoutUnit contentSize = LayoutUnit()) { + NGConstraintSpace constraintSpace = constructConstraintSpace(200, 300); + return ::blink::resolveBlockLength(constraintSpace, length, contentSize, + type); + } + + LayoutUnit computeInlineSizeForFragment( + const NGConstraintSpace constraintSpace = constructConstraintSpace(200, + 300)) { + return ::blink::computeInlineSizeForFragment(constraintSpace, *style_); + } + + LayoutUnit computeBlockSizeForFragment( + const NGConstraintSpace constraintSpace = constructConstraintSpace(200, + 300), + LayoutUnit contentSize = LayoutUnit()) { + return ::blink::computeBlockSizeForFragment(constraintSpace, *style_, + contentSize); + } + + RefPtr<ComputedStyle> style_; +}; + +TEST_F(NGLengthUtilsTest, testResolveInlineLength) { + EXPECT_EQ(LayoutUnit(60), resolveInlineLength(Length(30, Percent))); + EXPECT_EQ(LayoutUnit(150), resolveInlineLength(Length(150, Fixed))); + EXPECT_EQ(LayoutUnit(0), + resolveInlineLength(Length(Auto), LengthResolveType::MinSize)); + EXPECT_EQ(LayoutUnit(200), resolveInlineLength(Length(Auto))); + EXPECT_EQ(LayoutUnit(200), resolveInlineLength(Length(FillAvailable))); + + EXPECT_EQ(LayoutUnit(200), + resolveInlineLength(Length(Auto), LengthResolveType::MaxSize)); + EXPECT_EQ(LayoutUnit(200), resolveInlineLength(Length(FillAvailable), + LengthResolveType::MaxSize)); +} + +TEST_F(NGLengthUtilsTest, testResolveBlockLength) { + EXPECT_EQ(LayoutUnit(90), resolveBlockLength(Length(30, Percent))); + EXPECT_EQ(LayoutUnit(150), resolveBlockLength(Length(150, Fixed))); + EXPECT_EQ(LayoutUnit(0), resolveBlockLength(Length(Auto))); + EXPECT_EQ(LayoutUnit(300), resolveBlockLength(Length(FillAvailable))); + + EXPECT_EQ(LayoutUnit(0), + resolveBlockLength(Length(Auto), LengthResolveType::ContentSize)); + EXPECT_EQ(LayoutUnit(300), + resolveBlockLength(Length(FillAvailable), + LengthResolveType::ContentSize)); +} + +TEST_F(NGLengthUtilsTest, testComputeInlineSizeForFragment) { + style_->setLogicalWidth(Length(30, Percent)); + EXPECT_EQ(LayoutUnit(60), computeInlineSizeForFragment()); + + style_->setLogicalWidth(Length(150, Fixed)); + EXPECT_EQ(LayoutUnit(150), computeInlineSizeForFragment()); + + style_->setLogicalWidth(Length(Auto)); + EXPECT_EQ(LayoutUnit(200), computeInlineSizeForFragment()); + + style_->setLogicalWidth(Length(FillAvailable)); + EXPECT_EQ(LayoutUnit(200), computeInlineSizeForFragment()); + + style_->setLogicalWidth(Length(CalculationValue::create( + PixelsAndPercent(100, -10), ValueRangeNonNegative))); + EXPECT_EQ(LayoutUnit(80), computeInlineSizeForFragment()); + + NGConstraintSpace constraintSpace = constructConstraintSpace(120, 120); + constraintSpace.setFixedSize(true, true); + style_->setLogicalWidth(Length(150, Fixed)); + EXPECT_EQ(LayoutUnit(120), computeInlineSizeForFragment(constraintSpace)); + + style_->setLogicalWidth(Length(200, Fixed)); + style_->setMaxWidth(Length(80, Percent)); + EXPECT_EQ(LayoutUnit(160), computeInlineSizeForFragment()); + + style_->setLogicalWidth(Length(100, Fixed)); + style_->setMinWidth(Length(80, Percent)); + EXPECT_EQ(LayoutUnit(160), computeInlineSizeForFragment()); + + // TODO(layout-ng): test {min,max}-content on max-width. +} + +TEST_F(NGLengthUtilsTest, testComputeBlockSizeForFragment) { + style_->setLogicalHeight(Length(30, Percent)); + EXPECT_EQ(LayoutUnit(90), computeBlockSizeForFragment()); + + style_->setLogicalHeight(Length(150, Fixed)); + EXPECT_EQ(LayoutUnit(150), computeBlockSizeForFragment()); + + style_->setLogicalHeight(Length(Auto)); + EXPECT_EQ(LayoutUnit(0), computeBlockSizeForFragment()); + + style_->setLogicalHeight(Length(Auto)); + EXPECT_EQ(LayoutUnit(120), + computeBlockSizeForFragment(constructConstraintSpace(200, 300), + LayoutUnit(120))); + + style_->setLogicalHeight(Length(FillAvailable)); + EXPECT_EQ(LayoutUnit(300), computeBlockSizeForFragment()); + + style_->setLogicalHeight(Length(CalculationValue::create( + PixelsAndPercent(100, -10), ValueRangeNonNegative))); + EXPECT_EQ(LayoutUnit(70), computeBlockSizeForFragment()); + + NGConstraintSpace constraintSpace = constructConstraintSpace(200, 200); + constraintSpace.setFixedSize(true, true); + style_->setLogicalHeight(Length(150, Fixed)); + EXPECT_EQ(LayoutUnit(200), computeBlockSizeForFragment(constraintSpace)); + + style_->setLogicalHeight(Length(300, Fixed)); + style_->setMaxHeight(Length(80, Percent)); + EXPECT_EQ(LayoutUnit(240), computeBlockSizeForFragment()); + + style_->setLogicalHeight(Length(100, Fixed)); + style_->setMinHeight(Length(80, Percent)); + EXPECT_EQ(LayoutUnit(240), computeBlockSizeForFragment()); + + // TODO(layout-ng): test {min,max}-content on max-height. +} + +} // namespace +} // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_text.cc b/third_party/WebKit/Source/core/layout/ng/ng_text.cc deleted file mode 100644 index 6e0bd35e..0000000 --- a/third_party/WebKit/Source/core/layout/ng/ng_text.cc +++ /dev/null
@@ -1,7 +0,0 @@ -// Copyright 2016 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 "core/layout/ng/ng_text.h" - -namespace blink {} // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_text.h b/third_party/WebKit/Source/core/layout/ng/ng_text.h deleted file mode 100644 index 117bae95..0000000 --- a/third_party/WebKit/Source/core/layout/ng/ng_text.h +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2016 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 NGText_h -#define NGText_h - -#include "core/CoreExport.h" -#include "core/layout/ng/ng_fragment_base.h" -#include "platform/LayoutUnit.h" -#include "wtf/text/WTFString.h" - -namespace blink { - -class CORE_EXPORT NGText final : public NGFragmentBase { - public: - NGText(LayoutUnit inlineSize, - LayoutUnit blockSize, - LayoutUnit inlineOverflow, - LayoutUnit blockOverflow, - NGWritingMode writingMode, - NGDirection direction) - : NGFragmentBase(inlineSize, - blockSize, - inlineOverflow, - blockOverflow, - writingMode, - direction, - FragmentText) {} - - const String text() const { return String(); } - - DEFINE_INLINE_TRACE_AFTER_DISPATCH() { - NGFragmentBase::traceAfterDispatch(visitor); - } -}; - -} // namespace blink - -#endif // NGText_h
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_text_fragment.cc b/third_party/WebKit/Source/core/layout/ng/ng_text_fragment.cc new file mode 100644 index 0000000..6d9d8a8 --- /dev/null +++ b/third_party/WebKit/Source/core/layout/ng/ng_text_fragment.cc
@@ -0,0 +1,13 @@ +// Copyright 2016 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 "core/layout/ng/ng_text_fragment.h" + +namespace blink { + +String NGTextFragment::text() const { + return text_list_->Text(start_offset_, end_offset_); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_text_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_text_fragment.h new file mode 100644 index 0000000..880ce9f --- /dev/null +++ b/third_party/WebKit/Source/core/layout/ng/ng_text_fragment.h
@@ -0,0 +1,48 @@ +// Copyright 2016 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 NGTextFragment_h +#define NGTextFragment_h + +#include "core/CoreExport.h" +#include "core/layout/ng/ng_fragment_base.h" +#include "core/layout/ng/ng_layout_input_text.h" +#include "platform/LayoutUnit.h" +#include "platform/heap/Handle.h" +#include "wtf/text/WTFString.h" + +namespace blink { + +class CORE_EXPORT NGTextFragment final : public NGFragmentBase { + public: + NGTextFragment(LayoutUnit inlineSize, + LayoutUnit blockSize, + LayoutUnit inlineOverflow, + LayoutUnit blockOverflow, + NGWritingMode writingMode, + NGDirection direction) + : NGFragmentBase(inlineSize, + blockSize, + inlineOverflow, + blockOverflow, + writingMode, + direction, + FragmentText) {} + + String text() const; + + DEFINE_INLINE_TRACE_AFTER_DISPATCH() { + visitor->trace(text_list_); + NGFragmentBase::traceAfterDispatch(visitor); + } + + private: + Member<NGLayoutInputText> text_list_; + unsigned start_offset_; + unsigned end_offset_; +}; + +} // namespace blink + +#endif // NGTextFragment_h
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_units.h b/third_party/WebKit/Source/core/layout/ng/ng_units.h index e0975f4..8a558263 100644 --- a/third_party/WebKit/Source/core/layout/ng/ng_units.h +++ b/third_party/WebKit/Source/core/layout/ng/ng_units.h
@@ -5,6 +5,8 @@ #ifndef NGUnits_h #define NGUnits_h +#include "platform/LayoutUnit.h" + namespace blink { class LayoutUnit;
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGBlock.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGBlock.cpp index 84f44525..0f18179 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGBlock.cpp +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGBlock.cpp
@@ -82,9 +82,9 @@ SVGResourcesCache::clientStyleChanged(this, diff, styleRef()); } -void LayoutSVGBlock::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState& transformState, MapCoordinatesFlags) const +void LayoutSVGBlock::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState& transformState, MapCoordinatesFlags flags) const { - SVGLayoutSupport::mapLocalToAncestor(this, ancestor, transformState); + SVGLayoutSupport::mapLocalToAncestor(this, ancestor, transformState, flags); } void LayoutSVGBlock::mapAncestorToLocal(const LayoutBoxModelObject* ancestor, TransformState& transformState, MapCoordinatesFlags) const
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGContainer.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGContainer.cpp index 1e62ca9..81ee3f7 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGContainer.cpp +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGContainer.cpp
@@ -187,10 +187,10 @@ } } - // pointer-events=boundingBox makes it possible for containers to be direct targets + // pointer-events: bounding-box makes it possible for containers to be direct targets. if (style()->pointerEvents() == PE_BOUNDINGBOX) { - ASSERT(isObjectBoundingBoxValid()); - if (objectBoundingBox().contains(localPoint)) { + // Check for a valid bounding box because it will be invalid for empty containers. + if (isObjectBoundingBoxValid() && objectBoundingBox().contains(localPoint)) { const LayoutPoint& localLayoutPoint = roundedLayoutPoint(localPoint); updateHitTestResult(result, localLayoutPoint); if (result.addNodeToListBasedTestResult(element(), localLayoutPoint) == StopHitTesting)
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGInline.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGInline.cpp index d8899c7..0ab1760 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGInline.cpp +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGInline.cpp
@@ -89,9 +89,9 @@ return SVGLayoutSupport::clippedOverflowRectForPaintInvalidation(*this, *view()); } -void LayoutSVGInline::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState& transformState, MapCoordinatesFlags) const +void LayoutSVGInline::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState& transformState, MapCoordinatesFlags flags) const { - SVGLayoutSupport::mapLocalToAncestor(this, ancestor, transformState); + SVGLayoutSupport::mapLocalToAncestor(this, ancestor, transformState, flags); } const LayoutObject* LayoutSVGInline::pushMappingToContainer(const LayoutBoxModelObject* ancestorToStopAt, LayoutGeometryMap& geometryMap) const
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.cpp b/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.cpp index d79f02b5..4ca014f 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.cpp +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.cpp
@@ -36,6 +36,7 @@ #include "core/layout/svg/SVGLayoutSupport.h" #include "core/layout/svg/SVGResourcesCache.h" #include "core/paint/PaintLayer.h" +#include "core/paint/SVGModelObjectPaintInvalidator.h" #include "core/svg/SVGGraphicsElement.h" namespace blink { @@ -50,9 +51,9 @@ return child->isSVG() && !(child->isSVGInline() || child->isSVGInlineText() || child->isSVGGradientStop()); } -void LayoutSVGModelObject::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState& transformState, MapCoordinatesFlags) const +void LayoutSVGModelObject::mapLocalToAncestor(const LayoutBoxModelObject* ancestor, TransformState& transformState, MapCoordinatesFlags flags) const { - SVGLayoutSupport::mapLocalToAncestor(this, ancestor, transformState); + SVGLayoutSupport::mapLocalToAncestor(this, ancestor, transformState, flags); } LayoutRect LayoutSVGModelObject::absoluteClippedOverflowRect() const @@ -88,18 +89,9 @@ LayoutObject::willBeDestroyed(); } -PaintInvalidationReason LayoutSVGModelObject::getPaintInvalidationReason(const PaintInvalidationState& paintInvalidationState, - const LayoutRect& oldBounds, const LayoutPoint& oldLocation, const LayoutRect& newBounds, const LayoutPoint& newLocation) const +PaintInvalidationReason LayoutSVGModelObject::invalidatePaintIfNeeded(const PaintInvalidatorContext& context) const { - PaintInvalidationReason invalidationReason = LayoutObject::getPaintInvalidationReason(paintInvalidationState, oldBounds, oldLocation, newBounds, newLocation); - - // Disable incremental invalidation for SVG objects to prevent under- - // invalidation. Unlike boxes, it is non-trivial (and rare) for SVG objects - // to be able to be incrementally invalidated (e.g., on height changes). - if (invalidationReason == PaintInvalidationIncremental) - return PaintInvalidationFull; - - return invalidationReason; + return SVGModelObjectPaintInvalidator(*this, context).invalidatePaintIfNeeded(); } void LayoutSVGModelObject::computeLayerHitTestRects(LayerHitTestRects& rects) const
diff --git a/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.h b/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.h index 429204e2..4d0323b 100644 --- a/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.h +++ b/third_party/WebKit/Source/core/layout/svg/LayoutSVGModelObject.h
@@ -68,7 +68,8 @@ void addLayerHitTestRects(LayerHitTestRects&, const PaintLayer* currentCompositedLayer, const LayoutPoint& layerOffset, const LayoutRect& containerRect) const final; void willBeDestroyed() override; - PaintInvalidationReason getPaintInvalidationReason(const PaintInvalidationState&, const LayoutRect&, const LayoutPoint&, const LayoutRect&, const LayoutPoint&) const final; + PaintInvalidationReason invalidatePaintIfNeeded(const PaintInvalidatorContext&) const final; + private: // LayoutSVGModelObject subclasses should use element() instead. void node() const = delete;
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp index 18a95646..e411f2e 100644 --- a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp +++ b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.cpp
@@ -139,7 +139,7 @@ return svgRoot.mapToVisualRectInAncestorSpace(ancestor, resultRect, visualRectFlags); } -void SVGLayoutSupport::mapLocalToAncestor(const LayoutObject* object, const LayoutBoxModelObject* ancestor, TransformState& transformState) +void SVGLayoutSupport::mapLocalToAncestor(const LayoutObject* object, const LayoutBoxModelObject* ancestor, TransformState& transformState, MapCoordinatesFlags flags) { transformState.applyTransform(object->localToSVGParentTransform()); @@ -151,8 +151,7 @@ if (parent->isSVGRoot()) transformState.applyTransform(toLayoutSVGRoot(parent)->localToBorderBoxTransform()); - MapCoordinatesFlags mode = UseTransforms; - parent->mapLocalToAncestor(ancestor, transformState, mode); + parent->mapLocalToAncestor(ancestor, transformState, flags); } void SVGLayoutSupport::mapAncestorToLocal(const LayoutObject& object, const LayoutBoxModelObject* ancestor, TransformState& transformState)
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.h b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.h index 43b7ddb..db1ada83 100644 --- a/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.h +++ b/third_party/WebKit/Source/core/layout/svg/SVGLayoutSupport.h
@@ -79,7 +79,7 @@ static LayoutRect clippedOverflowRectForPaintInvalidation(const LayoutObject&, const LayoutBoxModelObject& paintInvalidationContainer); static LayoutRect transformPaintInvalidationRect(const LayoutObject&, const AffineTransform&, const FloatRect&); static bool mapToVisualRectInAncestorSpace(const LayoutObject&, const LayoutBoxModelObject* ancestor, const FloatRect& localPaintInvalidationRect, LayoutRect& resultRect, VisualRectFlags = DefaultVisualRectFlags); - static void mapLocalToAncestor(const LayoutObject*, const LayoutBoxModelObject* ancestor, TransformState&); + static void mapLocalToAncestor(const LayoutObject*, const LayoutBoxModelObject* ancestor, TransformState&, MapCoordinatesFlags); static void mapAncestorToLocal(const LayoutObject&, const LayoutBoxModelObject* ancestor, TransformState&); static const LayoutObject* pushMappingToContainer(const LayoutObject*, const LayoutBoxModelObject* ancestorToStopAt, LayoutGeometryMap&);
diff --git a/third_party/WebKit/Source/core/loader/BeaconLoader.cpp b/third_party/WebKit/Source/core/loader/BeaconLoader.cpp deleted file mode 100644 index ced714c..0000000 --- a/third_party/WebKit/Source/core/loader/BeaconLoader.cpp +++ /dev/null
@@ -1,275 +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 "core/loader/BeaconLoader.h" - -#include "core/dom/DOMArrayBufferView.h" -#include "core/dom/Document.h" -#include "core/fetch/CrossOriginAccessControl.h" -#include "core/fetch/FetchContext.h" -#include "core/fetch/FetchInitiatorTypeNames.h" -#include "core/fetch/FetchUtils.h" -#include "core/fetch/ResourceFetcher.h" -#include "core/fileapi/File.h" -#include "core/frame/LocalFrame.h" -#include "core/html/FormData.h" -#include "core/inspector/ConsoleMessage.h" -#include "core/loader/MixedContentChecker.h" -#include "platform/exported/WrappedResourceRequest.h" -#include "platform/exported/WrappedResourceResponse.h" -#include "platform/network/EncodedFormData.h" -#include "platform/network/ParsedContentType.h" -#include "platform/network/ResourceRequest.h" -#include "public/platform/WebURLRequest.h" -#include "wtf/Functional.h" - -namespace blink { - -namespace { - -class Beacon { - STACK_ALLOCATED(); -public: - virtual bool serialize(ResourceRequest&, int, int&) const = 0; - virtual unsigned long long size() const = 0; - virtual const AtomicString getContentType() const = 0; -}; - -class BeaconString final : public Beacon { -public: - explicit BeaconString(const String& data) - : m_data(data) - { - } - - unsigned long long size() const override - { - return m_data.sizeInBytes(); - } - - bool serialize(ResourceRequest& request, int, int&) const override - { - RefPtr<EncodedFormData> entityBody = EncodedFormData::create(m_data.utf8()); - request.setHTTPBody(entityBody); - request.setHTTPContentType(getContentType()); - return true; - } - - const AtomicString getContentType() const { return AtomicString("text/plain;charset=UTF-8"); } - -private: - const String m_data; -}; - -class BeaconBlob final : public Beacon { -public: - explicit BeaconBlob(Blob* data) - : m_data(data) - { - const String& blobType = m_data->type(); - if (!blobType.isEmpty() && isValidContentType(blobType)) - m_contentType = AtomicString(blobType); - } - - unsigned long long size() const override - { - return m_data->size(); - } - - bool serialize(ResourceRequest& request, int, int&) const override - { - ASSERT(m_data); - RefPtr<EncodedFormData> entityBody = EncodedFormData::create(); - if (m_data->hasBackingFile()) - entityBody->appendFile(toFile(m_data)->path()); - else - entityBody->appendBlob(m_data->uuid(), m_data->blobDataHandle()); - - request.setHTTPBody(entityBody.release()); - - if (!m_contentType.isEmpty()) - request.setHTTPContentType(m_contentType); - - return true; - } - - const AtomicString getContentType() const { return m_contentType; } - -private: - const Member<Blob> m_data; - AtomicString m_contentType; -}; - -class BeaconDOMArrayBufferView final : public Beacon { -public: - explicit BeaconDOMArrayBufferView(DOMArrayBufferView* data) - : m_data(data) - { - } - - unsigned long long size() const override - { - return m_data->byteLength(); - } - - bool serialize(ResourceRequest& request, int, int&) const override - { - ASSERT(m_data); - RefPtr<EncodedFormData> entityBody = EncodedFormData::create(m_data->baseAddress(), m_data->byteLength()); - request.setHTTPBody(entityBody.release()); - - // FIXME: a reasonable choice, but not in the spec; should it give a default? - AtomicString contentType = AtomicString("application/octet-stream"); - request.setHTTPContentType(contentType); - - return true; - } - - const AtomicString getContentType() const { return nullAtom; } - -private: - const Member<DOMArrayBufferView> m_data; -}; - -class BeaconFormData final : public Beacon { -public: - explicit BeaconFormData(FormData* data) - : m_data(data) - , m_entityBody(m_data->encodeMultiPartFormData()) - { - m_contentType = AtomicString("multipart/form-data; boundary=") + m_entityBody->boundary().data(); - } - - unsigned long long size() const override - { - // FormData's size cannot be determined until serialized. - return 0; - } - - bool serialize(ResourceRequest& request, int allowance, int& payloadLength) const override - { - unsigned long long entitySize = m_entityBody->sizeInBytes(); - if (allowance > 0 && static_cast<unsigned long long>(allowance) < entitySize) - return false; - - request.setHTTPBody(m_entityBody.get()); - request.setHTTPContentType(m_contentType); - - payloadLength = entitySize; - return true; - } - - const AtomicString getContentType() const { return m_contentType; } - -private: - const Member<FormData> m_data; - RefPtr<EncodedFormData> m_entityBody; - AtomicString m_contentType; -}; - -} // namespace - -class BeaconLoader::Sender { -public: - static bool send(LocalFrame* frame, int allowance, const KURL& beaconURL, const Beacon& beacon, int& payloadLength) - { - if (!frame->document()) - return false; - - unsigned long long entitySize = beacon.size(); - if (allowance > 0 && static_cast<unsigned long long>(allowance) < entitySize) - return false; - - ResourceRequest request(beaconURL); - request.setRequestContext(WebURLRequest::RequestContextBeacon); - request.setHTTPMethod(HTTPNames::POST); - request.setHTTPHeaderField(HTTPNames::Cache_Control, "max-age=0"); - request.setAllowStoredCredentials(true); - frame->document()->fetcher()->context().addAdditionalRequestHeaders(request, FetchSubresource); - frame->document()->fetcher()->context().populateRequestData(request); - - if (MixedContentChecker::shouldBlockFetch(frame, request, request.url())) - return false; - - payloadLength = entitySize; - if (!beacon.serialize(request, allowance, payloadLength)) - return false; - - const AtomicString contentType = beacon.getContentType(); - CORSEnabled corsEnabled = IsCORSEnabled; - if (!contentType.isNull() && FetchUtils::isSimpleHeader(AtomicString("content-type"), contentType)) - corsEnabled = NotCORSEnabled; - - FetchInitiatorInfo initiatorInfo; - initiatorInfo.name = FetchInitiatorTypeNames::beacon; - - // The loader keeps itself alive until it receives a response and disposes itself. - BeaconLoader* loader = new BeaconLoader(frame, request, initiatorInfo, AllowStoredCredentials, corsEnabled); - ASSERT_UNUSED(loader, loader); - return true; - } -}; - -bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beaconURL, const String& data, int& payloadLength) -{ - BeaconString beacon(data); - return Sender::send(frame, allowance, beaconURL, beacon, payloadLength); -} - -bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beaconURL, DOMArrayBufferView* data, int& payloadLength) -{ - BeaconDOMArrayBufferView beacon(data); - return Sender::send(frame, allowance, beaconURL, beacon, payloadLength); -} - -bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beaconURL, FormData* data, int& payloadLength) -{ - BeaconFormData beacon(data); - return Sender::send(frame, allowance, beaconURL, beacon, payloadLength); -} - -bool BeaconLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beaconURL, Blob* data, int& payloadLength) -{ - BeaconBlob beacon(data); - return Sender::send(frame, allowance, beaconURL, beacon, payloadLength); -} - -BeaconLoader::BeaconLoader(LocalFrame* frame, ResourceRequest& request, const FetchInitiatorInfo& initiatorInfo, StoredCredentials credentialsAllowed, CORSEnabled corsMode) - : PingLoader(frame, request, initiatorInfo, credentialsAllowed) - , m_beaconOrigin(frame->document()->getSecurityOrigin()) - , m_redirectsFollowCORS(corsMode == IsCORSEnabled) -{ -} - -void BeaconLoader::willFollowRedirect(WebURLLoader*, WebURLRequest& passedNewRequest, const WebURLResponse& passedRedirectResponse, int64_t encodedDataLength) -{ - passedNewRequest.setAllowStoredCredentials(true); - if (!m_redirectsFollowCORS) - return; - - ResourceRequest& newRequest(passedNewRequest.toMutableResourceRequest()); - const ResourceResponse& redirectResponse(passedRedirectResponse.toResourceResponse()); - - ASSERT(!newRequest.isNull()); - ASSERT(!redirectResponse.isNull()); - - String errorDescription; - StoredCredentials withCredentials = AllowStoredCredentials; - ResourceLoaderOptions options; - if (!CrossOriginAccessControl::handleRedirect(m_beaconOrigin.get(), newRequest, redirectResponse, withCredentials, options, errorDescription)) { - if (LocalFrame* localFrame = frame()) { - if (localFrame->document()) - localFrame->document()->addConsoleMessage(ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorDescription)); - } - // Cancel the load and self destruct. - dispose(); - // Signal WebURLLoader that the redirect musn't be followed. - passedNewRequest = WebURLRequest(); - return; - } - // FIXME: http://crbug.com/427429 is needed to correctly propagate - // updates of Origin: following this successful redirect. -} - -} // namespace blink
diff --git a/third_party/WebKit/Source/core/loader/BeaconLoader.h b/third_party/WebKit/Source/core/loader/BeaconLoader.h deleted file mode 100644 index 4b0b59a3..0000000 --- a/third_party/WebKit/Source/core/loader/BeaconLoader.h +++ /dev/null
@@ -1,51 +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 BeaconLoader_h -#define BeaconLoader_h - -#include "core/CoreExport.h" -#include "core/fetch/ResourceLoaderOptions.h" // CORSEnabled -#include "core/loader/PingLoader.h" -#include "platform/heap/Handle.h" -#include "public/platform/WebURLLoaderClient.h" -#include "wtf/Forward.h" -#include "wtf/Noncopyable.h" - -namespace blink { - -class Blob; -class DOMArrayBufferView; -class FormData; -class KURL; -class LocalFrame; -class SecurityOrigin; - -// Issue asynchronous beacon transmission loads independent of LocalFrame -// staying alive. PingLoader providing the service. -class CORE_EXPORT BeaconLoader final : public PingLoader { - WTF_MAKE_NONCOPYABLE(BeaconLoader); -public: - ~BeaconLoader() override { } - - static bool sendBeacon(LocalFrame*, int, const KURL&, const String&, int&); - static bool sendBeacon(LocalFrame*, int, const KURL&, DOMArrayBufferView*, int&); - static bool sendBeacon(LocalFrame*, int, const KURL&, Blob*, int&); - static bool sendBeacon(LocalFrame*, int, const KURL&, FormData*, int&); - -private: - class Sender; - - BeaconLoader(LocalFrame*, ResourceRequest&, const FetchInitiatorInfo&, StoredCredentials, CORSEnabled); - - RefPtr<SecurityOrigin> m_beaconOrigin; - bool m_redirectsFollowCORS; - - // WebURLLoaderClient - void willFollowRedirect(WebURLLoader*, WebURLRequest&, const WebURLResponse&, int64_t encodedDataLength) override; -}; - -} // namespace blink - -#endif // BeaconLoader_h
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoadTiming.cpp b/third_party/WebKit/Source/core/loader/DocumentLoadTiming.cpp index 6c5b7cea..4968b49 100644 --- a/third_party/WebKit/Source/core/loader/DocumentLoadTiming.cpp +++ b/third_party/WebKit/Source/core/loader/DocumentLoadTiming.cpp
@@ -142,6 +142,20 @@ m_hasCrossOriginRedirect |= !redirectedSecurityOrigin->canRequest(redirectingUrl); } +void DocumentLoadTiming::setRedirectStart(double redirectStart) +{ + m_redirectStart = redirectStart; + TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing", "redirectStart", m_redirectStart, "frame", frame()); + notifyDocumentTimingChanged(); +} + +void DocumentLoadTiming::setRedirectEnd(double redirectEnd) +{ + m_redirectEnd = redirectEnd; + TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing", "redirectEnd", m_redirectEnd, "frame", frame()); + notifyDocumentTimingChanged(); +} + void DocumentLoadTiming::markUnloadEventStart() { m_unloadEventStart = monotonicallyIncreasingTime(); @@ -158,7 +172,12 @@ void DocumentLoadTiming::markFetchStart() { - m_fetchStart = monotonicallyIncreasingTime(); + setFetchStart(monotonicallyIncreasingTime()); +} + +void DocumentLoadTiming::setFetchStart(double fetchStart) +{ + m_fetchStart = fetchStart; TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing", "fetchStart", m_fetchStart, "frame", frame()); notifyDocumentTimingChanged(); } @@ -184,13 +203,6 @@ notifyDocumentTimingChanged(); } -void DocumentLoadTiming::setRedirectStart(double redirectStart) -{ - m_redirectStart = redirectStart; - TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing", "redirectStart", m_redirectStart, "frame", frame()); - notifyDocumentTimingChanged(); -} - void DocumentLoadTiming::markRedirectEnd() { m_redirectEnd = monotonicallyIncreasingTime();
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoadTiming.h b/third_party/WebKit/Source/core/loader/DocumentLoadTiming.h index cac157bb5..03e965ed 100644 --- a/third_party/WebKit/Source/core/loader/DocumentLoadTiming.h +++ b/third_party/WebKit/Source/core/loader/DocumentLoadTiming.h
@@ -47,12 +47,21 @@ void markNavigationStart(); void setNavigationStart(double); + void addRedirect(const KURL& redirectingUrl, const KURL& redirectedUrl); + void setRedirectStart(double); + void setRedirectEnd(double); + void setRedirectCount(short value) { m_redirectCount = value; } + void setHasCrossOriginRedirect(bool value) { m_hasCrossOriginRedirect = value; } void markUnloadEventStart(); void markUnloadEventEnd(); + void markFetchStart(); + void setFetchStart(double); + void setResponseEnd(double); + void markLoadEventStart(); void markLoadEventEnd(); @@ -76,7 +85,6 @@ DECLARE_TRACE(); private: - void setRedirectStart(double); void markRedirectEnd(); void notifyDocumentTimingChanged(); void ensureReferenceTimesSet();
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp index 98515ba..e80d27fe5 100644 --- a/third_party/WebKit/Source/core/loader/DocumentLoader.cpp +++ b/third_party/WebKit/Source/core/loader/DocumentLoader.cpp
@@ -61,7 +61,6 @@ #include "core/page/FrameTree.h" #include "core/page/Page.h" #include "platform/HTTPNames.h" -#include "platform/Logging.h" #include "platform/UserGestureIndicator.h" #include "platform/mhtml/ArchiveResource.h" #include "platform/network/ContentSecurityPolicyResponseHeaders.h" @@ -145,6 +144,7 @@ visitor->trace(m_documentLoadTiming); visitor->trace(m_applicationCacheHost); visitor->trace(m_contentSecurityPolicy); + RawResourceClient::trace(visitor); } unsigned long DocumentLoader::mainResourceIdentifier() const @@ -648,8 +648,13 @@ return; ASSERT(timing().navigationStart()); - ASSERT(!timing().fetchStart()); - timing().markFetchStart(); + + // PlzNavigate: + // The fetch has already started in the browser. Don't mark it again. + if (!m_frame->settings()->browserSideNavigationEnabled()) { + DCHECK(!timing().fetchStart()); + timing().markFetchStart(); + } DEFINE_STATIC_LOCAL(ResourceLoaderOptions, mainResourceLoadOptions, (DoNotBufferData, AllowStoredCredentials, ClientRequestedCredentials, CheckContentSecurityPolicy, DocumentContext));
diff --git a/third_party/WebKit/Source/core/loader/DocumentLoader.h b/third_party/WebKit/Source/core/loader/DocumentLoader.h index b3c61239..a97fb85 100644 --- a/third_party/WebKit/Source/core/loader/DocumentLoader.h +++ b/third_party/WebKit/Source/core/loader/DocumentLoader.h
@@ -64,6 +64,7 @@ struct ViewportDescriptionWrapper; class CORE_EXPORT DocumentLoader : public GarbageCollectedFinalized<DocumentLoader>, private RawResourceClient { + USING_GARBAGE_COLLECTED_MIXIN(DocumentLoader); public: static DocumentLoader* create(LocalFrame* frame, const ResourceRequest& request, const SubstituteData& data) {
diff --git a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp index 1b504ec..4852079 100644 --- a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp +++ b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.cpp
@@ -126,14 +126,12 @@ void DocumentThreadableLoader::loadResourceSynchronously(Document& document, const ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions) { - // The loader will be deleted as soon as this function exits. - std::unique_ptr<DocumentThreadableLoader> loader = wrapUnique(new DocumentThreadableLoader(document, &client, LoadSynchronously, options, resourceLoaderOptions)); - loader->start(request); + (new DocumentThreadableLoader(document, &client, LoadSynchronously, options, resourceLoaderOptions))->start(request); } -std::unique_ptr<DocumentThreadableLoader> DocumentThreadableLoader::create(Document& document, ThreadableLoaderClient* client, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions) +DocumentThreadableLoader* DocumentThreadableLoader::create(Document& document, ThreadableLoaderClient* client, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions) { - return wrapUnique(new DocumentThreadableLoader(document, client, LoadAsynchronously, options, resourceLoaderOptions)); + return new DocumentThreadableLoader(document, client, LoadAsynchronously, options, resourceLoaderOptions); } DocumentThreadableLoader::DocumentThreadableLoader(Document& document, ThreadableLoaderClient* client, BlockingBehavior blockingBehavior, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions) @@ -172,7 +170,6 @@ ThreadableLoaderClient* client = m_client; clear(); client->didFail(ResourceError(errorDomainBlinkInternal, 0, request.url().getString(), "Cross origin requests are not supported.")); - // |this| may be dead here. return; } @@ -253,26 +250,22 @@ m_fallbackRequestForServiceWorker.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::Controlling); } loadRequest(newRequest, m_resourceLoaderOptions); - // |this| may be dead here. return; } dispatchInitialRequest(newRequest); - // |this| may be dead here in async mode. } void DocumentThreadableLoader::dispatchInitialRequest(const ResourceRequest& request) { if (!request.isExternalRequest() && (m_sameOriginRequest || m_options.crossOriginRequestPolicy == AllowCrossOriginRequests)) { loadRequest(request, m_resourceLoaderOptions); - // |this| may be dead here in async mode. return; } ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl || request.isExternalRequest()); makeCrossOriginAccessRequest(request); - // |this| may be dead here in async mode. } void DocumentThreadableLoader::makeCrossOriginAccessRequest(const ResourceRequest& request) @@ -290,7 +283,6 @@ ThreadableLoaderClient* client = m_client; clear(); client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal, 0, request.url().getString(), "Cross origin requests are only supported for protocol schemes: " + SchemeRegistry::listOfCORSEnabledURLSchemes() + ".")); - // |this| may be dead here in async mode. return; } @@ -299,7 +291,6 @@ ThreadableLoaderClient* client = m_client; clear(); client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal, 0, request.url().getString(), "Requests to internal network resources are not allowed from non-secure contexts (see https://goo.gl/Y0ZkNV). This is an experimental restriction which is part of 'https://mikewest.github.io/cors-rfc1918/'.")); - // |this| may be dead here in async mode. return; } @@ -319,7 +310,6 @@ crossOriginRequest.setHTTPReferrer(SecurityPolicy::generateReferrer(m_referrerAfterRedirect.referrerPolicy, crossOriginRequest.url(), m_referrerAfterRedirect.referrer)); } loadRequest(crossOriginRequest, crossOriginOptions); - // |this| may be dead here in async mode. } else { m_crossOriginNonSimpleRequest = true; // Do not set the Origin header for preflight requests. @@ -338,14 +328,12 @@ bool canSkipPreflight = CrossOriginPreflightResultCache::shared().canSkipPreflight(getSecurityOrigin()->toString(), m_actualRequest.url(), effectiveAllowCredentials(), m_actualRequest.httpMethod(), m_actualRequest.httpHeaderFields()); if (canSkipPreflight && !shouldForcePreflight) { loadActualRequest(); - // |this| may be dead here in async mode. } else { ResourceRequest preflightRequest = createAccessControlPreflightRequest(m_actualRequest, getSecurityOrigin()); // Create a ResourceLoaderOptions for preflight. ResourceLoaderOptions preflightOptions = m_actualOptions; preflightOptions.allowCredentials = DoNotAllowStoredCredentials; loadRequest(preflightRequest, preflightOptions); - // |this| may be dead here in async mode. } } } @@ -385,7 +373,6 @@ void DocumentThreadableLoader::cancel() { cancelWithError(ResourceError()); - // |this| may be dead here. } void DocumentThreadableLoader::cancelWithError(const ResourceError& error) @@ -406,7 +393,6 @@ ThreadableLoaderClient* client = m_client; clear(); client->didFail(errorForCallback); - // |this| may be dead here in async mode. } void DocumentThreadableLoader::setDefersLoading(bool value) @@ -439,7 +425,6 @@ reportResponseReceived(resource->identifier(), redirectResponse); handlePreflightFailure(redirectResponse.url().getString(), "Response for preflight is invalid (redirect)"); - // |this| may be dead here. request = ResourceRequest(); @@ -482,7 +467,6 @@ ThreadableLoaderClient* client = m_client; clear(); client->didFailRedirectCheck(); - // |this| may be dead here. request = ResourceRequest(); @@ -500,10 +484,7 @@ ThreadableLoaderClient* client = m_client; clear(); client->didFailRedirectCheck(); - // |this| may be dead here. - request = ResourceRequest(); - return; } @@ -532,10 +513,7 @@ ThreadableLoaderClient* client = m_client; clear(); client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal, 0, redirectResponse.url().getString(), accessControlErrorDescription)); - // |this| may be dead here. - request = ResourceRequest(); - return; } @@ -581,7 +559,6 @@ ThreadableLoaderClient* client = m_client; clear(); client->didFailRedirectCheck(); - // |this| may be dead here } void DocumentThreadableLoader::dataSent(Resource* resource, unsigned long long bytesSent, unsigned long long totalBytesToBeSent) @@ -591,7 +568,6 @@ ASSERT(m_async); m_client->didSendData(bytesSent, totalBytesToBeSent); - // |this| may be dead here. } void DocumentThreadableLoader::dataDownloaded(Resource* resource, int dataLength) @@ -602,7 +578,6 @@ ASSERT(m_async); m_client->didDownloadData(dataLength); - // |this| may be dead here. } void DocumentThreadableLoader::didReceiveResourceTiming(Resource* resource, const ResourceTimingInfo& info) @@ -612,7 +587,6 @@ ASSERT(m_async); m_client->didReceiveResourceTiming(info); - // |this| may be dead here. } void DocumentThreadableLoader::responseReceived(Resource* resource, const ResourceResponse& response, std::unique_ptr<WebDataConsumerHandle> handle) @@ -624,7 +598,6 @@ m_isUsingDataConsumerHandle = true; handleResponse(resource->identifier(), response, std::move(handle)); - // |this| may be dead here. } void DocumentThreadableLoader::handlePreflightResponse(const ResourceResponse& response) @@ -633,19 +606,16 @@ if (!passesAccessControlCheck(response, effectiveAllowCredentials(), getSecurityOrigin(), accessControlErrorDescription, m_requestContext)) { handlePreflightFailure(response.url().getString(), "Response to preflight request doesn't pass access control check: " + accessControlErrorDescription); - // |this| may be dead here in async mode. return; } if (!passesPreflightStatusCheck(response, accessControlErrorDescription)) { handlePreflightFailure(response.url().getString(), accessControlErrorDescription); - // |this| may be dead here in async mode. return; } if (m_actualRequest.isExternalRequest() && !passesExternalPreflightCheck(response, accessControlErrorDescription)) { handlePreflightFailure(response.url().getString(), accessControlErrorDescription); - // |this| may be dead here in async mode. return; } @@ -654,7 +624,6 @@ || !preflightResult->allowsCrossOriginMethod(m_actualRequest.httpMethod(), accessControlErrorDescription) || !preflightResult->allowsCrossOriginHeaders(m_actualRequest.httpHeaderFields(), accessControlErrorDescription)) { handlePreflightFailure(response.url().getString(), accessControlErrorDescription); - // |this| may be dead here in async mode. return; } @@ -682,7 +651,6 @@ if (!m_actualRequest.isNull()) { reportResponseReceived(identifier, response); handlePreflightResponse(response); - // |this| may be dead here in async mode. return; } @@ -695,7 +663,6 @@ ASSERT(!m_fallbackRequestForServiceWorker.isNull()); reportResponseReceived(identifier, response); loadFallbackRequestForServiceWorker(); - // |this| may be dead here in async mode. return; } m_fallbackRequestForServiceWorker = ResourceRequest(); @@ -723,7 +690,6 @@ ThreadableLoaderClient* client = m_client; clear(); client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal, 0, response.url().getString(), accessControlErrorDescription)); - // |this| may be dead here. return; } } @@ -736,7 +702,6 @@ if (!m_actualRequest.isNull()) return; m_client->didReceiveCachedMetadata(data, size); - // |this| may be dead here. } void DocumentThreadableLoader::dataReceived(Resource* resource, const char* data, size_t dataLength) @@ -750,7 +715,6 @@ // TODO(junov): Fix the ThreadableLoader ecosystem to use size_t. // Until then, we use safeCast to trap potential overflows. handleReceivedData(data, safeCast<unsigned>(dataLength)); - // |this| may be dead here. } void DocumentThreadableLoader::handleReceivedData(const char* data, size_t dataLength) @@ -764,7 +728,6 @@ ASSERT(m_fallbackRequestForServiceWorker.isNull()); m_client->didReceiveData(data, dataLength); - // |this| may be dead here in async mode. } void DocumentThreadableLoader::notifyFinished(Resource* resource) @@ -775,10 +738,8 @@ if (resource->errorOccurred()) { handleError(resource->resourceError()); - // |this| may be dead here. } else { handleSuccessfulFinish(resource->identifier(), resource->loadFinishTime()); - // |this| may be dead here. } } @@ -793,17 +754,15 @@ ASSERT(!m_sameOriginRequest); ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl); loadActualRequest(); - // |this| may be dead here in async mode. return; } ThreadableLoaderClient* client = m_client; // Protect the resource in |didFinishLoading| in order not to release the // downloaded file. - Persistent<Resource> resource = m_resource; + Persistent<Resource> protect = resource(); clear(); client->didFinishLoading(identifier, finishTime); - // |this| may be dead here in async mode. } void DocumentThreadableLoader::didTimeout(TimerBase* timer) @@ -816,7 +775,6 @@ ResourceError error("net", timeoutError, resource()->url(), String()); error.setIsTimeout(true); cancelWithError(error); - // |this| may be dead here. } void DocumentThreadableLoader::loadFallbackRequestForServiceWorker() @@ -825,7 +783,6 @@ ResourceRequest fallbackRequest(m_fallbackRequestForServiceWorker); m_fallbackRequestForServiceWorker = ResourceRequest(); dispatchInitialRequest(fallbackRequest); - // |this| may be dead here in async mode. } void DocumentThreadableLoader::loadActualRequest() @@ -846,7 +803,6 @@ actualRequest.setSkipServiceWorker(WebURLRequest::SkipServiceWorker::All); loadRequest(actualRequest, actualOptions); - // |this| may be dead here in async mode. } void DocumentThreadableLoader::handlePreflightFailure(const String& url, const String& errorDescription) @@ -859,7 +815,6 @@ ThreadableLoaderClient* client = m_client; clear(); client->didFailAccessControlCheck(error); - // |this| may be dead here in async mode. } void DocumentThreadableLoader::handleError(const ResourceError& error) @@ -872,7 +827,6 @@ ThreadableLoaderClient* client = m_client; clear(); client->didFail(copiedError); - // |this| may be dead here. } void DocumentThreadableLoader::loadRequest(const ResourceRequest& request, ResourceLoaderOptions resourceLoaderOptions) @@ -908,7 +862,6 @@ setResource(RawResource::fetch(newRequest, document().fetcher())); // setResource() might call notifyFinished() synchronously, and thus - // clear() might be called and |this| may be dead here. if (!self) return; @@ -922,7 +875,6 @@ if (!client) return; client->didFail(ResourceError(errorDomainBlinkInternal, 0, requestURL.getString(), "Failed to start loading.")); - // |this| may be dead here. return; } @@ -1017,4 +969,12 @@ return *m_document; } +DEFINE_TRACE(DocumentThreadableLoader) +{ + visitor->trace(m_resource); + visitor->trace(m_document); + ThreadableLoader::trace(visitor); + RawResourceClient::trace(visitor); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h index 1cb373d..8e01a24 100644 --- a/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h +++ b/third_party/WebKit/Source/core/loader/DocumentThreadableLoader.h
@@ -55,10 +55,10 @@ class ThreadableLoaderClient; class CORE_EXPORT DocumentThreadableLoader final : public ThreadableLoader, private RawResourceClient { - USING_FAST_MALLOC(DocumentThreadableLoader); + USING_GARBAGE_COLLECTED_MIXIN(DocumentThreadableLoader); public: static void loadResourceSynchronously(Document&, const ResourceRequest&, ThreadableLoaderClient&, const ThreadableLoaderOptions&, const ResourceLoaderOptions&); - static std::unique_ptr<DocumentThreadableLoader> create(Document&, ThreadableLoaderClient*, const ThreadableLoaderOptions&, const ResourceLoaderOptions&); + static DocumentThreadableLoader* create(Document&, ThreadableLoaderClient*, const ThreadableLoaderOptions&, const ResourceLoaderOptions&); ~DocumentThreadableLoader() override; void start(const ResourceRequest&) override; @@ -69,6 +69,8 @@ void cancel() override; void setDefersLoading(bool); + DECLARE_TRACE(); + private: enum BlockingBehavior { LoadSynchronously, @@ -169,14 +171,14 @@ m_resource->addClient(this); } } - Persistent<RawResource> m_resource; + Member<RawResource> m_resource; // End of ResourceOwner re-implementation, see above. SecurityOrigin* getSecurityOrigin() const; Document& document() const; ThreadableLoaderClient* m_client; - WeakPersistent<Document> m_document; + Member<Document> m_document; const ThreadableLoaderOptions m_options; // Some items may be overridden by m_forceDoNotAllowStoredCredentials
diff --git a/third_party/WebKit/Source/core/loader/EmptyClients.h b/third_party/WebKit/Source/core/loader/EmptyClients.h index 4095424..28762b9 100644 --- a/third_party/WebKit/Source/core/loader/EmptyClients.h +++ b/third_party/WebKit/Source/core/loader/EmptyClients.h
@@ -283,7 +283,6 @@ ~EmptyTextCheckerClient() { } void checkSpellingOfString(const String&, int*, int*) override {} - void checkGrammarOfString(const String&, Vector<GrammarDetail>&, int*, int*) override {} void requestCheckingOfString(TextCheckingRequest*) override; void cancelAllPendingRequests() override; };
diff --git a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp index 93bda38..dbd30ff 100644 --- a/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp +++ b/third_party/WebKit/Source/core/loader/FrameFetchContext.cpp
@@ -34,6 +34,7 @@ #include "core/dom/Document.h" #include "core/fetch/ClientHintsPreferences.h" #include "core/fetch/ResourceLoader.h" +#include "core/fetch/ResourceLoadingLog.h" #include "core/fetch/UniqueIdentifier.h" #include "core/frame/FrameConsole.h" #include "core/frame/FrameHost.h" @@ -58,10 +59,10 @@ #include "core/loader/appcache/ApplicationCacheHost.h" #include "core/page/NetworkStateNotifier.h" #include "core/page/Page.h" +#include "core/paint/FirstMeaningfulPaintDetector.h" #include "core/svg/graphics/SVGImageChromeClient.h" #include "core/timing/DOMWindowPerformance.h" #include "core/timing/Performance.h" -#include "platform/Logging.h" #include "platform/TracedValue.h" #include "platform/mhtml/MHTMLArchive.h" #include "platform/network/NetworkUtils.h" @@ -435,6 +436,8 @@ { if (resource->isLoadEventBlockingResourceType()) frame()->loader().checkCompleted(); + if (m_document) + FirstMeaningfulPaintDetector::from(*m_document).checkNetworkStable(); } void FrameFetchContext::addResourceTiming(const ResourceTimingInfo& info) @@ -499,7 +502,7 @@ if (originRestriction != FetchRequest::NoOriginRestriction && securityOrigin && !securityOrigin->canDisplay(url)) { if (!forPreload) FrameLoader::reportLocalLoadFailed(frame(), url.elidedString()); - WTF_LOG(ResourceLoading, "ResourceFetcher::requestResource URL was not allowed by SecurityOrigin::canDisplay"); + RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::requestResource URL was not allowed by SecurityOrigin::canDisplay"; return ResourceRequestBlockedReasonOther; }
diff --git a/third_party/WebKit/Source/core/loader/FrameLoader.cpp b/third_party/WebKit/Source/core/loader/FrameLoader.cpp index 320c250..31434e9 100644 --- a/third_party/WebKit/Source/core/loader/FrameLoader.cpp +++ b/third_party/WebKit/Source/core/loader/FrameLoader.cpp
@@ -83,7 +83,6 @@ #include "core/page/scrolling/ScrollingCoordinator.h" #include "core/svg/graphics/SVGImage.h" #include "core/xml/parser/XMLDocumentParser.h" -#include "platform/Logging.h" #include "platform/PluginScriptForbiddenScope.h" #include "platform/RuntimeEnabledFeatures.h" #include "platform/ScriptForbiddenScope.h"
diff --git a/third_party/WebKit/Source/core/loader/ImageLoader.cpp b/third_party/WebKit/Source/core/loader/ImageLoader.cpp index 9bbe25b..86f6561 100644 --- a/third_party/WebKit/Source/core/loader/ImageLoader.cpp +++ b/third_party/WebKit/Source/core/loader/ImageLoader.cpp
@@ -34,6 +34,7 @@ #include "core/fetch/FetchRequest.h" #include "core/fetch/MemoryCache.h" #include "core/fetch/ResourceFetcher.h" +#include "core/fetch/ResourceLoadingLog.h" #include "core/frame/LocalFrame.h" #include "core/frame/Settings.h" #include "core/frame/UseCounter.h" @@ -45,7 +46,6 @@ #include "core/layout/LayoutVideo.h" #include "core/layout/svg/LayoutSVGImage.h" #include "core/svg/graphics/SVGImage.h" -#include "platform/Logging.h" #include "platform/weborigin/SecurityOrigin.h" #include "platform/weborigin/SecurityPolicy.h" #include "public/platform/WebCachePolicy.h" @@ -155,7 +155,7 @@ , m_elementIsProtected(false) , m_suppressErrorEvents(false) { - WTF_LOG(ResourceLoading, "new ImageLoader %p", this); + RESOURCE_LOADING_DVLOG(1) << "new ImageLoader " << this; ThreadState::current()->registerPreFinalizer(this); } @@ -165,8 +165,9 @@ void ImageLoader::dispose() { - WTF_LOG(ResourceLoading, "~ImageLoader %p; m_hasPendingLoadEvent=%d, m_hasPendingErrorEvent=%d", - this, m_hasPendingLoadEvent, m_hasPendingErrorEvent); + RESOURCE_LOADING_DVLOG(1) << "~ImageLoader " << this + << "; m_hasPendingLoadEvent=" << m_hasPendingLoadEvent + << ", m_hasPendingErrorEvent=" << m_hasPendingErrorEvent; if (m_image) { m_image->removeObserver(this); @@ -433,8 +434,8 @@ void ImageLoader::imageNotifyFinished(ImageResource* resource) { - WTF_LOG(ResourceLoading, "ImageLoader::imageNotifyFinished %p; m_hasPendingLoadEvent=%d", - this, m_hasPendingLoadEvent); + RESOURCE_LOADING_DVLOG(1) << "ImageLoader::imageNotifyFinished " << this + << "; m_hasPendingLoadEvent=" << m_hasPendingLoadEvent; ASSERT(m_failedLoadURL.isEmpty()); ASSERT(resource == m_image.get()); @@ -545,7 +546,7 @@ void ImageLoader::dispatchPendingEvent(ImageEventSender* eventSender) { - WTF_LOG(ResourceLoading, "ImageLoader::dispatchPendingEvent %p", this); + RESOURCE_LOADING_DVLOG(1) << "ImageLoader::dispatchPendingEvent " << this; ASSERT(eventSender == &loadEventSender() || eventSender == &errorEventSender()); const AtomicString& eventType = eventSender->eventType(); if (eventType == EventTypeNames::load)
diff --git a/third_party/WebKit/Source/core/loader/MockThreadableLoader.h b/third_party/WebKit/Source/core/loader/MockThreadableLoader.h index 47691965..99a81061 100644 --- a/third_party/WebKit/Source/core/loader/MockThreadableLoader.h +++ b/third_party/WebKit/Source/core/loader/MockThreadableLoader.h
@@ -14,7 +14,7 @@ class MockThreadableLoader : public ThreadableLoader { public: - static std::unique_ptr<MockThreadableLoader> create() { return wrapUnique(new testing::StrictMock<MockThreadableLoader>); } + static MockThreadableLoader* create() { return new testing::StrictMock<MockThreadableLoader>; } MOCK_METHOD1(start, void(const ResourceRequest&)); MOCK_METHOD1(overrideTimeout, void(unsigned long));
diff --git a/third_party/WebKit/Source/core/loader/PingLoader.cpp b/third_party/WebKit/Source/core/loader/PingLoader.cpp index fcffd71..5657210 100644 --- a/third_party/WebKit/Source/core/loader/PingLoader.cpp +++ b/third_party/WebKit/Source/core/loader/PingLoader.cpp
@@ -31,13 +31,19 @@ #include "core/loader/PingLoader.h" +#include "core/dom/DOMArrayBufferView.h" #include "core/dom/Document.h" +#include "core/fetch/CrossOriginAccessControl.h" #include "core/fetch/FetchContext.h" #include "core/fetch/FetchInitiatorTypeNames.h" +#include "core/fetch/FetchUtils.h" #include "core/fetch/ResourceFetcher.h" #include "core/fetch/UniqueIdentifier.h" +#include "core/fileapi/File.h" #include "core/frame/FrameConsole.h" #include "core/frame/LocalFrame.h" +#include "core/html/FormData.h" +#include "core/inspector/ConsoleMessage.h" #include "core/inspector/InspectorInstrumentation.h" #include "core/inspector/InspectorTraceEvents.h" #include "core/loader/FrameLoader.h" @@ -45,6 +51,9 @@ #include "core/loader/MixedContentChecker.h" #include "core/page/Page.h" #include "platform/exported/WrappedResourceRequest.h" +#include "platform/exported/WrappedResourceResponse.h" +#include "platform/network/EncodedFormData.h" +#include "platform/network/ParsedContentType.h" #include "platform/network/ResourceError.h" #include "platform/network/ResourceRequest.h" #include "platform/network/ResourceResponse.h" @@ -55,98 +64,219 @@ #include "public/platform/WebURLLoader.h" #include "public/platform/WebURLRequest.h" #include "public/platform/WebURLResponse.h" +#include "wtf/Compiler.h" +#include "wtf/Functional.h" #include "wtf/PtrUtil.h" namespace blink { -static void finishPingRequestInitialization(ResourceRequest& request, LocalFrame* frame) -{ - request.setRequestContext(WebURLRequest::RequestContextPing); - frame->document()->fetcher()->context().addAdditionalRequestHeaders(request, FetchSubresource); - frame->document()->fetcher()->context().populateRequestData(request); -} +namespace { -void PingLoader::loadImage(LocalFrame* frame, const KURL& url) -{ - if (!frame->document()->getSecurityOrigin()->canDisplay(url)) { - FrameLoader::reportLocalLoadFailed(frame, url.getString()); - return; +class Beacon { + STACK_ALLOCATED(); +public: + virtual bool serialize(ResourceRequest&, int, int&) const = 0; + virtual unsigned long long size() const = 0; + virtual const AtomicString getContentType() const = 0; +}; + +class BeaconString final : public Beacon { +public: + explicit BeaconString(const String& data) + : m_data(data) + { } - ResourceRequest request(url); - request.setHTTPHeaderField(HTTPNames::Cache_Control, "max-age=0"); - finishPingRequestInitialization(request, frame); + unsigned long long size() const override + { + return m_data.charactersSizeInBytes(); + } - FetchInitiatorInfo initiatorInfo; - initiatorInfo.name = FetchInitiatorTypeNames::ping; - PingLoader::start(frame, request, initiatorInfo); -} + bool serialize(ResourceRequest& request, int, int&) const override + { + RefPtr<EncodedFormData> entityBody = EncodedFormData::create(m_data.utf8()); + request.setHTTPBody(entityBody); + request.setHTTPContentType(getContentType()); + return true; + } -// http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#hyperlink-auditing -void PingLoader::sendLinkAuditPing(LocalFrame* frame, const KURL& pingURL, const KURL& destinationURL) -{ - ResourceRequest request(pingURL); - request.setHTTPMethod(HTTPNames::POST); - request.setHTTPContentType("text/ping"); - request.setHTTPBody(EncodedFormData::create("PING")); - request.setHTTPHeaderField(HTTPNames::Cache_Control, "max-age=0"); - finishPingRequestInitialization(request, frame); + const AtomicString getContentType() const { return AtomicString("text/plain;charset=UTF-8"); } - RefPtr<SecurityOrigin> pingOrigin = SecurityOrigin::create(pingURL); - // addAdditionalRequestHeaders() will have added a referrer for same origin requests, - // but the spec omits the referrer. - request.clearHTTPReferrer(); +private: + const String m_data; +}; - request.setHTTPHeaderField(HTTPNames::Ping_To, AtomicString(destinationURL.getString())); +class BeaconBlob final : public Beacon { +public: + explicit BeaconBlob(Blob* data) + : m_data(data) + { + const String& blobType = m_data->type(); + if (!blobType.isEmpty() && isValidContentType(blobType)) + m_contentType = AtomicString(blobType); + } - // Ping-From follows the same rules as the default referrer beahavior for subresource requests. - if (!SecurityPolicy::shouldHideReferrer(pingURL, frame->document()->url().getString())) - request.setHTTPHeaderField(HTTPNames::Ping_From, AtomicString(frame->document()->url().getString())); + unsigned long long size() const override + { + return m_data->size(); + } - FetchInitiatorInfo initiatorInfo; - initiatorInfo.name = FetchInitiatorTypeNames::ping; - PingLoader::start(frame, request, initiatorInfo); -} + bool serialize(ResourceRequest& request, int, int&) const override + { + DCHECK(m_data); + RefPtr<EncodedFormData> entityBody = EncodedFormData::create(); + if (m_data->hasBackingFile()) + entityBody->appendFile(toFile(m_data)->path()); + else + entityBody->appendBlob(m_data->uuid(), m_data->blobDataHandle()); -void PingLoader::sendViolationReport(LocalFrame* frame, const KURL& reportURL, PassRefPtr<EncodedFormData> report, ViolationReportType type) -{ - ResourceRequest request(reportURL); - request.setHTTPMethod(HTTPNames::POST); - request.setHTTPContentType(type == ContentSecurityPolicyViolationReport ? "application/csp-report" : "application/json"); - request.setHTTPBody(report); - finishPingRequestInitialization(request, frame); + request.setHTTPBody(entityBody.release()); - FetchInitiatorInfo initiatorInfo; - initiatorInfo.name = FetchInitiatorTypeNames::violationreport; - PingLoader::start(frame, request, initiatorInfo, SecurityOrigin::create(reportURL)->isSameSchemeHostPort(frame->document()->getSecurityOrigin()) ? AllowStoredCredentials : DoNotAllowStoredCredentials); -} + if (!m_contentType.isEmpty()) + request.setHTTPContentType(m_contentType); -void PingLoader::start(LocalFrame* frame, ResourceRequest& request, const FetchInitiatorInfo& initiatorInfo, StoredCredentials credentialsAllowed) -{ - if (MixedContentChecker::shouldBlockFetch(frame, request, request.url())) - return; + return true; + } - // The loader keeps itself alive until it receives a response and disposes itself. - PingLoader* loader = new PingLoader(frame, request, initiatorInfo, credentialsAllowed); - ASSERT_UNUSED(loader, loader); -} + const AtomicString getContentType() const { return m_contentType; } -PingLoader::PingLoader(LocalFrame* frame, ResourceRequest& request, const FetchInitiatorInfo& initiatorInfo, StoredCredentials credentialsAllowed) +private: + const Member<Blob> m_data; + AtomicString m_contentType; +}; + +class BeaconDOMArrayBufferView final : public Beacon { +public: + explicit BeaconDOMArrayBufferView(DOMArrayBufferView* data) + : m_data(data) + { + } + + unsigned long long size() const override + { + return m_data->byteLength(); + } + + bool serialize(ResourceRequest& request, int, int&) const override + { + DCHECK(m_data); + RefPtr<EncodedFormData> entityBody = EncodedFormData::create(m_data->baseAddress(), m_data->byteLength()); + request.setHTTPBody(entityBody.release()); + + // FIXME: a reasonable choice, but not in the spec; should it give a default? + AtomicString contentType = AtomicString("application/octet-stream"); + request.setHTTPContentType(contentType); + + return true; + } + + const AtomicString getContentType() const { return nullAtom; } + +private: + const Member<DOMArrayBufferView> m_data; +}; + +class BeaconFormData final : public Beacon { +public: + explicit BeaconFormData(FormData* data) + : m_data(data) + , m_entityBody(m_data->encodeMultiPartFormData()) + { + m_contentType = AtomicString("multipart/form-data; boundary=") + m_entityBody->boundary().data(); + } + + unsigned long long size() const override + { + // FormData's size cannot be determined until serialized. + return 0; + } + + bool serialize(ResourceRequest& request, int allowance, int& payloadLength) const override + { + unsigned long long entitySize = m_entityBody->sizeInBytes(); + if (allowance > 0 && static_cast<unsigned long long>(allowance) < entitySize) + return false; + + request.setHTTPBody(m_entityBody.get()); + request.setHTTPContentType(m_contentType); + + payloadLength = entitySize; + return true; + } + + const AtomicString getContentType() const { return m_contentType; } + +private: + const Member<FormData> m_data; + RefPtr<EncodedFormData> m_entityBody; + AtomicString m_contentType; +}; + +class PingLoaderImpl : public GarbageCollectedFinalized<PingLoaderImpl>, public LocalFrameLifecycleObserver, private WebURLLoaderClient { + USING_GARBAGE_COLLECTED_MIXIN(PingLoaderImpl); + WTF_MAKE_NONCOPYABLE(PingLoaderImpl); +public: + PingLoaderImpl(LocalFrame*, ResourceRequest&, const AtomicString&, StoredCredentials, bool); + ~PingLoaderImpl() override; + + DECLARE_VIRTUAL_TRACE(); + +private: + void dispose(); + + // WebURLLoaderClient + void willFollowRedirect(WebURLLoader*, WebURLRequest&, const WebURLResponse&, int64_t encodedDataLength) override; + void didReceiveResponse(WebURLLoader*, const WebURLResponse&) final; + void didReceiveData(WebURLLoader*, const char*, int, int, int) final; + void didFinishLoading(WebURLLoader*, double, int64_t) final; + void didFail(WebURLLoader*, const WebURLError&) final; + + void timeout(TimerBase*); + + void didFailLoading(LocalFrame*); + + std::unique_ptr<WebURLLoader> m_loader; + Timer<PingLoaderImpl> m_timeout; + String m_url; + unsigned long m_identifier; + SelfKeepAlive<PingLoaderImpl> m_keepAlive; + + bool m_isBeacon; + + RefPtr<SecurityOrigin> m_origin; + CORSEnabled m_corsMode; +}; + +PingLoaderImpl::PingLoaderImpl(LocalFrame* frame, ResourceRequest& request, const AtomicString& initiator, StoredCredentials credentialsAllowed, bool isBeacon) : LocalFrameLifecycleObserver(frame) - , m_timeout(this, &PingLoader::timeout) + , m_timeout(this, &PingLoaderImpl::timeout) , m_url(request.url()) , m_identifier(createUniqueIdentifier()) , m_keepAlive(this) + , m_isBeacon(isBeacon) + , m_origin(frame->document()->getSecurityOrigin()) + , m_corsMode(IsCORSEnabled) { + const AtomicString contentType = request.httpContentType(); + if (!contentType.isNull() && FetchUtils::isSimpleHeader(AtomicString("content-type"), contentType)) + m_corsMode = NotCORSEnabled; + frame->loader().client()->didDispatchPingLoader(request.url()); - frame->document()->fetcher()->context().willStartLoadingResource(m_identifier, request, Resource::Image); - frame->document()->fetcher()->context().dispatchWillSendRequest(m_identifier, request, ResourceResponse(), initiatorInfo); + + FetchContext& fetchContext = frame->document()->fetcher()->context(); + + fetchContext.willStartLoadingResource(m_identifier, request, Resource::Image); + + FetchInitiatorInfo initiatorInfo; + initiatorInfo.name = initiator; + fetchContext.dispatchWillSendRequest(m_identifier, request, ResourceResponse(), initiatorInfo); + // Make sure the scheduler doesn't wait for the ping. if (frame->frameScheduler()) frame->frameScheduler()->didStopLoading(m_identifier); m_loader = wrapUnique(Platform::current()->createURLLoader()); - ASSERT(m_loader); + DCHECK(m_loader); WrappedResourceRequest wrappedRequest(request); wrappedRequest.setAllowStoredCredentials(credentialsAllowed == AllowStoredCredentials); m_loader->loadAsynchronously(wrappedRequest, this); @@ -156,13 +286,13 @@ m_timeout.startOneShot(60000, BLINK_FROM_HERE); } -PingLoader::~PingLoader() +PingLoaderImpl::~PingLoaderImpl() { if (m_loader) m_loader->cancel(); } -void PingLoader::dispose() +void PingLoaderImpl::dispose() { if (m_loader) { m_loader->cancel(); @@ -172,7 +302,42 @@ m_keepAlive.clear(); } -void PingLoader::didReceiveResponse(WebURLLoader*, const WebURLResponse& response) +void PingLoaderImpl::willFollowRedirect(WebURLLoader*, WebURLRequest& passedNewRequest, const WebURLResponse& passedRedirectResponse, int64_t encodedDataLength) +{ + if (!m_isBeacon) + return; + + // TODO(tyoshino): Check if setAllowStoredCredentials() should be called + // also for non beacon cases. + passedNewRequest.setAllowStoredCredentials(true); + if (m_corsMode == NotCORSEnabled) + return; + + ResourceRequest& newRequest(passedNewRequest.toMutableResourceRequest()); + const ResourceResponse& redirectResponse(passedRedirectResponse.toResourceResponse()); + + DCHECK(!newRequest.isNull()); + DCHECK(!redirectResponse.isNull()); + + String errorDescription; + ResourceLoaderOptions options; + if (!CrossOriginAccessControl::handleRedirect(m_origin.get(), newRequest, redirectResponse, AllowStoredCredentials, options, errorDescription)) { + if (LocalFrame* localFrame = frame()) { + if (localFrame->document()) + localFrame->document()->addConsoleMessage(ConsoleMessage::create(JSMessageSource, ErrorMessageLevel, errorDescription)); + } + // Cancel the load and self destruct. + dispose(); + // Signal WebURLLoader that the redirect musn't be followed. + passedNewRequest = WebURLRequest(); + return; + } + // FIXME: http://crbug.com/427429 is needed to correctly propagate + // updates of Origin: following this successful redirect. +} + + +void PingLoaderImpl::didReceiveResponse(WebURLLoader*, const WebURLResponse& response) { if (LocalFrame* frame = this->frame()) { TRACE_EVENT_INSTANT1("devtools.timeline", "ResourceFinish", TRACE_EVENT_SCOPE_THREAD, "data", InspectorResourceFinishEvent::data(m_identifier, 0, true)); @@ -183,7 +348,7 @@ dispose(); } -void PingLoader::didReceiveData(WebURLLoader*, const char*, int, int, int) +void PingLoaderImpl::didReceiveData(WebURLLoader*, const char*, int, int, int) { if (LocalFrame* frame = this->frame()) { TRACE_EVENT_INSTANT1("devtools.timeline", "ResourceFinish", TRACE_EVENT_SCOPE_THREAD, "data", InspectorResourceFinishEvent::data(m_identifier, 0, true)); @@ -192,7 +357,7 @@ dispose(); } -void PingLoader::didFinishLoading(WebURLLoader*, double, int64_t) +void PingLoaderImpl::didFinishLoading(WebURLLoader*, double, int64_t) { if (LocalFrame* frame = this->frame()) { TRACE_EVENT_INSTANT1("devtools.timeline", "ResourceFinish", TRACE_EVENT_SCOPE_THREAD, "data", InspectorResourceFinishEvent::data(m_identifier, 0, true)); @@ -201,7 +366,7 @@ dispose(); } -void PingLoader::didFail(WebURLLoader*, const WebURLError& resourceError) +void PingLoaderImpl::didFail(WebURLLoader*, const WebURLError& resourceError) { if (LocalFrame* frame = this->frame()) { TRACE_EVENT_INSTANT1("devtools.timeline", "ResourceFinish", TRACE_EVENT_SCOPE_THREAD, "data", InspectorResourceFinishEvent::data(m_identifier, 0, true)); @@ -210,7 +375,7 @@ dispose(); } -void PingLoader::timeout(TimerBase*) +void PingLoaderImpl::timeout(TimerBase*) { if (LocalFrame* frame = this->frame()) { TRACE_EVENT_INSTANT1("devtools.timeline", "ResourceFinish", TRACE_EVENT_SCOPE_THREAD, "data", InspectorResourceFinishEvent::data(m_identifier, 0, true)); @@ -219,15 +384,132 @@ dispose(); } -void PingLoader::didFailLoading(LocalFrame* frame) +void PingLoaderImpl::didFailLoading(LocalFrame* frame) { InspectorInstrumentation::didFailLoading(frame, m_identifier, ResourceError::cancelledError(m_url)); frame->console().didFailLoading(m_identifier, ResourceError::cancelledError(m_url)); } -DEFINE_TRACE(PingLoader) +DEFINE_TRACE(PingLoaderImpl) { LocalFrameLifecycleObserver::trace(visitor); } +void finishPingRequestInitialization(ResourceRequest& request, LocalFrame* frame, WebURLRequest::RequestContext requestContext) +{ + request.setRequestContext(requestContext); + FetchContext& fetchContext = frame->document()->fetcher()->context(); + fetchContext.addAdditionalRequestHeaders(request, FetchSubresource); + fetchContext.populateRequestData(request); +} + +bool sendPingCommon(LocalFrame* frame, ResourceRequest& request, const AtomicString& initiator, StoredCredentials credentialsAllowed, bool isBeacon) +{ + if (MixedContentChecker::shouldBlockFetch(frame, request, request.url())) + return false; + + // The loader keeps itself alive until it receives a response and disposes itself. + PingLoaderImpl* loader = new PingLoaderImpl(frame, request, initiator, AllowStoredCredentials, true); + DCHECK(loader); + ALLOW_UNUSED_LOCAL(loader); + + return true; +} + +bool sendBeaconCommon(LocalFrame* frame, int allowance, const KURL& beaconURL, const Beacon& beacon, int& payloadLength) +{ + if (!frame->document()) + return false; + + unsigned long long entitySize = beacon.size(); + if (allowance > 0 && static_cast<unsigned long long>(allowance) < entitySize) + return false; + + ResourceRequest request(beaconURL); + request.setHTTPMethod(HTTPNames::POST); + request.setHTTPHeaderField(HTTPNames::Cache_Control, "max-age=0"); + finishPingRequestInitialization(request, frame, WebURLRequest::RequestContextBeacon); + + payloadLength = entitySize; + if (!beacon.serialize(request, allowance, payloadLength)) + return false; + + return sendPingCommon(frame, request, FetchInitiatorTypeNames::beacon, AllowStoredCredentials, true); +} + +} // namespace + +void PingLoader::loadImage(LocalFrame* frame, const KURL& url) +{ + if (!frame->document()->getSecurityOrigin()->canDisplay(url)) { + FrameLoader::reportLocalLoadFailed(frame, url.getString()); + return; + } + + ResourceRequest request(url); + request.setHTTPHeaderField(HTTPNames::Cache_Control, "max-age=0"); + finishPingRequestInitialization(request, frame, WebURLRequest::RequestContextPing); + + sendPingCommon(frame, request, FetchInitiatorTypeNames::ping, AllowStoredCredentials, false); +} + +// http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#hyperlink-auditing +void PingLoader::sendLinkAuditPing(LocalFrame* frame, const KURL& pingURL, const KURL& destinationURL) +{ + ResourceRequest request(pingURL); + request.setHTTPMethod(HTTPNames::POST); + request.setHTTPContentType("text/ping"); + request.setHTTPBody(EncodedFormData::create("PING")); + request.setHTTPHeaderField(HTTPNames::Cache_Control, "max-age=0"); + finishPingRequestInitialization(request, frame, WebURLRequest::RequestContextPing); + + // addAdditionalRequestHeaders() will have added a referrer for same origin requests, + // but the spec omits the referrer. + request.clearHTTPReferrer(); + + request.setHTTPHeaderField(HTTPNames::Ping_To, AtomicString(destinationURL.getString())); + + // Ping-From follows the same rules as the default referrer beahavior for subresource requests. + if (!SecurityPolicy::shouldHideReferrer(pingURL, frame->document()->url().getString())) + request.setHTTPHeaderField(HTTPNames::Ping_From, AtomicString(frame->document()->url().getString())); + + sendPingCommon(frame, request, FetchInitiatorTypeNames::ping, AllowStoredCredentials, false); +} + +void PingLoader::sendViolationReport(LocalFrame* frame, const KURL& reportURL, PassRefPtr<EncodedFormData> report, ViolationReportType type) +{ + ResourceRequest request(reportURL); + request.setHTTPMethod(HTTPNames::POST); + request.setHTTPContentType(type == ContentSecurityPolicyViolationReport ? "application/csp-report" : "application/json"); + request.setHTTPBody(report); + finishPingRequestInitialization(request, frame, WebURLRequest::RequestContextPing); + + StoredCredentials credentialsAllowed = SecurityOrigin::create(reportURL)->isSameSchemeHostPort(frame->document()->getSecurityOrigin()) ? AllowStoredCredentials : DoNotAllowStoredCredentials; + sendPingCommon(frame, request, FetchInitiatorTypeNames::violationreport, credentialsAllowed, false); +} + +bool PingLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beaconURL, const String& data, int& payloadLength) +{ + BeaconString beacon(data); + return sendBeaconCommon(frame, allowance, beaconURL, beacon, payloadLength); +} + +bool PingLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beaconURL, DOMArrayBufferView* data, int& payloadLength) +{ + BeaconDOMArrayBufferView beacon(data); + return sendBeaconCommon(frame, allowance, beaconURL, beacon, payloadLength); +} + +bool PingLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beaconURL, FormData* data, int& payloadLength) +{ + BeaconFormData beacon(data); + return sendBeaconCommon(frame, allowance, beaconURL, beacon, payloadLength); +} + +bool PingLoader::sendBeacon(LocalFrame* frame, int allowance, const KURL& beaconURL, Blob* data, int& payloadLength) +{ + BeaconBlob beacon(data); + return sendBeaconCommon(frame, allowance, beaconURL, beacon, payloadLength); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/loader/PingLoader.h b/third_party/WebKit/Source/core/loader/PingLoader.h index a1fc6d0..cbcf3e5 100644 --- a/third_party/WebKit/Source/core/loader/PingLoader.h +++ b/third_party/WebKit/Source/core/loader/PingLoader.h
@@ -45,10 +45,14 @@ namespace blink { +class Blob; +class DOMArrayBufferView; class EncodedFormData; +class FormData; class LocalFrame; class KURL; class ResourceRequest; +class SecurityOrigin; // Issue an asynchronous, one-directional request at some resources, ignoring // any response. The request is made independent of any LocalFrame staying alive, @@ -58,13 +62,8 @@ // // The ping loader is used by audit pings, beacon transmissions and image loads // during page unloading. -// -class CORE_EXPORT PingLoader : public GarbageCollectedFinalized<PingLoader>, public LocalFrameLifecycleObserver, private WebURLLoaderClient { - USING_GARBAGE_COLLECTED_MIXIN(PingLoader); - WTF_MAKE_NONCOPYABLE(PingLoader); +class CORE_EXPORT PingLoader { public: - ~PingLoader() override; - enum ViolationReportType { ContentSecurityPolicyViolationReport, XSSAuditorViolationReport @@ -73,31 +72,10 @@ static void loadImage(LocalFrame*, const KURL&); static void sendLinkAuditPing(LocalFrame*, const KURL& pingURL, const KURL& destinationURL); static void sendViolationReport(LocalFrame*, const KURL& reportURL, PassRefPtr<EncodedFormData> report, ViolationReportType); - - DECLARE_VIRTUAL_TRACE(); - -protected: - PingLoader(LocalFrame*, ResourceRequest&, const FetchInitiatorInfo&, StoredCredentials); - - static void start(LocalFrame*, ResourceRequest&, const FetchInitiatorInfo&, StoredCredentials = AllowStoredCredentials); - - void dispose(); - -private: - void didReceiveResponse(WebURLLoader*, const WebURLResponse&) final; - void didReceiveData(WebURLLoader*, const char*, int, int, int) final; - void didFinishLoading(WebURLLoader*, double, int64_t) final; - void didFail(WebURLLoader*, const WebURLError&) final; - - void timeout(TimerBase*); - - void didFailLoading(LocalFrame*); - - std::unique_ptr<WebURLLoader> m_loader; - Timer<PingLoader> m_timeout; - String m_url; - unsigned long m_identifier; - SelfKeepAlive<PingLoader> m_keepAlive; + static bool sendBeacon(LocalFrame*, int, const KURL&, const String&, int&); + static bool sendBeacon(LocalFrame*, int, const KURL&, DOMArrayBufferView*, int&); + static bool sendBeacon(LocalFrame*, int, const KURL&, Blob*, int&); + static bool sendBeacon(LocalFrame*, int, const KURL&, FormData*, int&); }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/loader/ProgressTracker.cpp b/third_party/WebKit/Source/core/loader/ProgressTracker.cpp index 8feaf2ec..03bfef6 100644 --- a/third_party/WebKit/Source/core/loader/ProgressTracker.cpp +++ b/third_party/WebKit/Source/core/loader/ProgressTracker.cpp
@@ -34,7 +34,6 @@ #include "core/loader/DocumentLoader.h" #include "core/loader/FrameLoader.h" #include "core/loader/FrameLoaderClient.h" -#include "platform/Logging.h" #include "platform/network/ResourceResponse.h" #include "wtf/CurrentTime.h" #include "wtf/PtrUtil.h"
diff --git a/third_party/WebKit/Source/core/loader/TextTrackLoader.cpp b/third_party/WebKit/Source/core/loader/TextTrackLoader.cpp index ec13452..9862964 100644 --- a/third_party/WebKit/Source/core/loader/TextTrackLoader.cpp +++ b/third_party/WebKit/Source/core/loader/TextTrackLoader.cpp
@@ -31,7 +31,6 @@ #include "core/fetch/RawResource.h" #include "core/fetch/ResourceFetcher.h" #include "core/inspector/ConsoleMessage.h" -#include "platform/Logging.h" #include "platform/SharedBuffer.h" #include "platform/weborigin/SecurityOrigin.h"
diff --git a/third_party/WebKit/Source/core/loader/ThreadableLoader.cpp b/third_party/WebKit/Source/core/loader/ThreadableLoader.cpp index 16f78451..11d2d47 100644 --- a/third_party/WebKit/Source/core/loader/ThreadableLoader.cpp +++ b/third_party/WebKit/Source/core/loader/ThreadableLoader.cpp
@@ -33,15 +33,12 @@ #include "core/dom/Document.h" #include "core/dom/ExecutionContext.h" #include "core/loader/DocumentThreadableLoader.h" -#include "core/loader/ThreadableLoaderClientWrapper.h" #include "core/loader/WorkerThreadableLoader.h" #include "core/workers/WorkerGlobalScope.h" -#include "core/workers/WorkerThread.h" -#include <memory> namespace blink { -std::unique_ptr<ThreadableLoader> ThreadableLoader::create(ExecutionContext& context, ThreadableLoaderClient* client, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions) +ThreadableLoader* ThreadableLoader::create(ExecutionContext& context, ThreadableLoaderClient* client, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions) { ASSERT(client);
diff --git a/third_party/WebKit/Source/core/loader/ThreadableLoader.h b/third_party/WebKit/Source/core/loader/ThreadableLoader.h index 4d26431..9a1be36 100644 --- a/third_party/WebKit/Source/core/loader/ThreadableLoader.h +++ b/third_party/WebKit/Source/core/loader/ThreadableLoader.h
@@ -34,6 +34,7 @@ #include "core/CoreExport.h" #include "core/fetch/ResourceLoaderOptions.h" #include "platform/CrossThreadCopier.h" +#include "platform/heap/Handle.h" #include "wtf/Allocator.h" #include "wtf/Noncopyable.h" #include <memory> @@ -126,7 +127,7 @@ // - ResourceLoaderOptions argument will be passed to the FetchRequest // that this ThreadableLoader creates. It can be altered e.g. when // redirect happens. -class CORE_EXPORT ThreadableLoader { +class CORE_EXPORT ThreadableLoader : public GarbageCollectedFinalized<ThreadableLoader> { WTF_MAKE_NONCOPYABLE(ThreadableLoader); public: // ThreadableLoaderClient methods may not destroy the ThreadableLoader @@ -167,7 +168,7 @@ // - may call cancel() // - can destroy the ThreadableLoader instance in them (by clearing // std::unique_ptr<ThreadableLoader>). - static std::unique_ptr<ThreadableLoader> create(ExecutionContext&, ThreadableLoaderClient*, const ThreadableLoaderOptions&, const ResourceLoaderOptions&); + static ThreadableLoader* create(ExecutionContext&, ThreadableLoaderClient*, const ThreadableLoaderOptions&, const ResourceLoaderOptions&); // The methods on the ThreadableLoaderClient passed on create() call // may be called synchronous to start() call. @@ -184,6 +185,8 @@ virtual ~ThreadableLoader() { } + DEFINE_INLINE_VIRTUAL_TRACE() {} + protected: ThreadableLoader() { } };
diff --git a/third_party/WebKit/Source/core/loader/ThreadableLoaderClientWrapper.h b/third_party/WebKit/Source/core/loader/ThreadableLoaderClientWrapper.h deleted file mode 100644 index c78779b..0000000 --- a/third_party/WebKit/Source/core/loader/ThreadableLoaderClientWrapper.h +++ /dev/null
@@ -1,158 +0,0 @@ -/* - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ThreadableLoaderClientWrapper_h -#define ThreadableLoaderClientWrapper_h - -#include "core/loader/ThreadableLoaderClient.h" -#include "core/timing/WorkerGlobalScopePerformance.h" -#include "core/workers/WorkerGlobalScope.h" -#include "platform/heap/Handle.h" -#include "platform/network/ResourceResponse.h" -#include "platform/network/ResourceTimingInfo.h" -#include "wtf/Threading.h" -#include "wtf/Vector.h" -#include <memory> - -namespace blink { - -class ThreadableLoaderClientWrapper final : public GarbageCollected<ThreadableLoaderClientWrapper> { -public: - ThreadableLoaderClientWrapper(WorkerGlobalScope& workerGlobalScope, ThreadableLoaderClient* client) - : m_workerGlobalScope(workerGlobalScope) - , m_client(client) - { - } - - void clearClient() - { - m_done = true; - m_client = nullptr; - } - - bool done() const { return m_done; } - - void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) - { - if (m_client) - m_client->didSendData(bytesSent, totalBytesToBeSent); - } - - void didReceiveResponse(unsigned long identifier, std::unique_ptr<CrossThreadResourceResponseData> responseData, std::unique_ptr<WebDataConsumerHandle> handle) - { - ResourceResponse response(responseData.get()); - - if (m_client) - m_client->didReceiveResponse(identifier, response, std::move(handle)); - } - - void didReceiveData(std::unique_ptr<Vector<char>> data) - { - RELEASE_ASSERT(data->size() <= std::numeric_limits<unsigned>::max()); - - if (m_client) - m_client->didReceiveData(data->data(), data->size()); - } - - void didReceiveCachedMetadata(std::unique_ptr<Vector<char>> data) - { - if (m_client) - m_client->didReceiveCachedMetadata(data->data(), data->size()); - } - - void didFinishLoading(unsigned long identifier, double finishTime) - { - m_done = true; - if (m_client) { - ThreadableLoaderClient* client = m_client; - m_client = nullptr; - client->didFinishLoading(identifier, finishTime); - } - } - - void didFail(const ResourceError& error) - { - m_done = true; - if (m_client) { - ThreadableLoaderClient* client = m_client; - m_client = nullptr; - client->didFail(error); - } - } - - void didFailAccessControlCheck(const ResourceError& error) - { - m_done = true; - if (m_client) { - ThreadableLoaderClient* client = m_client; - m_client = nullptr; - client->didFailAccessControlCheck(error); - } - } - - void didFailRedirectCheck() - { - m_done = true; - if (m_client) { - ThreadableLoaderClient* client = m_client; - m_client = nullptr; - client->didFailRedirectCheck(); - } - } - - void didDownloadData(int dataLength) - { - if (m_client) - m_client->didDownloadData(dataLength); - } - - void didReceiveResourceTiming(std::unique_ptr<CrossThreadResourceTimingInfoData> timingData) - { - std::unique_ptr<ResourceTimingInfo> info(ResourceTimingInfo::adopt(std::move(timingData))); - if (m_client) { - WorkerGlobalScopePerformance::performance(*m_workerGlobalScope)->addResourceTiming(*info); - m_client->didReceiveResourceTiming(*info); - } - } - - DEFINE_INLINE_TRACE() - { - visitor->trace(m_workerGlobalScope); - } - -private: - Member<WorkerGlobalScope> m_workerGlobalScope; - ThreadableLoaderClient* m_client = nullptr; - bool m_done = false; -}; - -} // namespace blink - -#endif // ThreadableLoaderClientWrapper_h
diff --git a/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp b/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp index d9e53d2..668a004 100644 --- a/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp +++ b/third_party/WebKit/Source/core/loader/ThreadableLoaderTest.cpp
@@ -157,7 +157,7 @@ std::unique_ptr<DummyPageHolder> m_dummyPageHolder; Checkpoint m_checkpoint; - std::unique_ptr<DocumentThreadableLoader> m_loader; + Persistent<DocumentThreadableLoader> m_loader; }; class WorkerThreadableLoaderTestHelper : public ThreadableLoaderTestHelper, public WorkerLoaderProxyProvider { @@ -213,7 +213,7 @@ { ASSERT(m_workerThread); ASSERT(m_workerThread->isCurrentThread()); - m_loader.reset(); + m_loader = nullptr; } Checkpoint& checkpoint() override @@ -336,7 +336,7 @@ std::unique_ptr<DummyPageHolder> m_dummyPageHolder; Checkpoint m_checkpoint; // |m_loader| must be touched only from the worker thread only. - std::unique_ptr<ThreadableLoader> m_loader; + CrossThreadPersistent<ThreadableLoader> m_loader; }; class ThreadableLoaderTest : public ::testing::TestWithParam<ThreadableLoaderToTest> {
diff --git a/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp b/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp index 1eb6a66f..9a05a18 100644 --- a/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp +++ b/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp
@@ -208,74 +208,42 @@ const ResourceLoaderOptions& resourceLoaderOptions, BlockingBehavior blockingBehavior) : m_workerGlobalScope(&workerGlobalScope) - , m_workerClientWrapper(new ThreadableLoaderClientWrapper(workerGlobalScope, client)) - , m_bridge(new Bridge(m_workerClientWrapper, workerGlobalScope.thread()->workerLoaderProxy(), options, resourceLoaderOptions, blockingBehavior)) + , m_workerLoaderProxy(workerGlobalScope.thread()->workerLoaderProxy()) + , m_client(client) + , m_threadableLoaderOptions(options) + , m_resourceLoaderOptions(resourceLoaderOptions) + , m_blockingBehavior(blockingBehavior) { + DCHECK(client); } void WorkerThreadableLoader::loadResourceSynchronously(WorkerGlobalScope& workerGlobalScope, const ResourceRequest& request, ThreadableLoaderClient& client, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions) { - std::unique_ptr<WorkerThreadableLoader> loader = wrapUnique(new WorkerThreadableLoader(workerGlobalScope, &client, options, resourceLoaderOptions, LoadSynchronously)); - loader->start(request); + (new WorkerThreadableLoader(workerGlobalScope, &client, options, resourceLoaderOptions, LoadSynchronously))->start(request); } WorkerThreadableLoader::~WorkerThreadableLoader() { - DCHECK(m_workerClientWrapper->done()); - m_bridge->destroy(); + DCHECK(!m_mainThreadLoaderHolder); + DCHECK(!m_client); } -void WorkerThreadableLoader::start(const ResourceRequest& request) +void WorkerThreadableLoader::start(const ResourceRequest& originalRequest) { - ResourceRequest requestToPass(request); - if (!requestToPass.didSetHTTPReferrer()) - requestToPass.setHTTPReferrer(SecurityPolicy::generateReferrer(m_workerGlobalScope->getReferrerPolicy(), request.url(), m_workerGlobalScope->outgoingReferrer())); - m_bridge->start(requestToPass, *m_workerGlobalScope); -} + ResourceRequest request(originalRequest); + if (!request.didSetHTTPReferrer()) + request.setHTTPReferrer(SecurityPolicy::generateReferrer(m_workerGlobalScope->getReferrerPolicy(), request.url(), m_workerGlobalScope->outgoingReferrer())); -void WorkerThreadableLoader::overrideTimeout(unsigned long timeoutMilliseconds) -{ - m_bridge->overrideTimeout(timeoutMilliseconds); -} - -void WorkerThreadableLoader::cancel() -{ - m_bridge->cancel(); -} - -WorkerThreadableLoader::Bridge::Bridge( - ThreadableLoaderClientWrapper* clientWrapper, - PassRefPtr<WorkerLoaderProxy> loaderProxy, - const ThreadableLoaderOptions& threadableLoaderOptions, - const ResourceLoaderOptions& resourceLoaderOptions, - BlockingBehavior blockingBehavior) - : m_clientWrapper(clientWrapper) - , m_loaderProxy(loaderProxy) - , m_threadableLoaderOptions(threadableLoaderOptions) - , m_resourceLoaderOptions(resourceLoaderOptions) - , m_blockingBehavior(blockingBehavior) -{ - DCHECK(!isMainThread()); -} - -WorkerThreadableLoader::Bridge::~Bridge() -{ - DCHECK(!isMainThread()); - DCHECK(!m_peer); -} - -void WorkerThreadableLoader::Bridge::start(const ResourceRequest& request, const WorkerGlobalScope& workerGlobalScope) -{ DCHECK(!isMainThread()); RefPtr<WaitableEventWithTasks> eventWithTasks; if (m_blockingBehavior == LoadSynchronously) eventWithTasks = WaitableEventWithTasks::create(); - m_loaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask( - &Peer::createAndStart, + m_workerLoaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask( + &MainThreadLoaderHolder::createAndStart, wrapCrossThreadPersistent(this), - m_loaderProxy, - wrapCrossThreadPersistent(workerGlobalScope.thread()->getWorkerThreadLifecycleContext()), + m_workerLoaderProxy, + wrapCrossThreadPersistent(m_workerGlobalScope->thread()->getWorkerThreadLifecycleContext()), request, m_threadableLoaderOptions, m_resourceLoaderOptions, @@ -307,68 +275,153 @@ } } -void WorkerThreadableLoader::Bridge::overrideTimeout(unsigned long timeoutMilliseconds) +void WorkerThreadableLoader::overrideTimeout(unsigned long timeoutMilliseconds) { DCHECK(!isMainThread()); - if (!m_peer) + if (!m_mainThreadLoaderHolder) return; - m_loaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&Peer::overrideTimeout, m_peer, timeoutMilliseconds)); + m_workerLoaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&MainThreadLoaderHolder::overrideTimeout, m_mainThreadLoaderHolder, timeoutMilliseconds)); } -void WorkerThreadableLoader::Bridge::cancel() +void WorkerThreadableLoader::cancel() { DCHECK(!isMainThread()); - cancelPeer(); + if (m_mainThreadLoaderHolder) { + m_workerLoaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&MainThreadLoaderHolder::cancel, m_mainThreadLoaderHolder)); + m_mainThreadLoaderHolder = nullptr; + } - if (m_clientWrapper->done()) + if (!m_client) return; + // If the client hasn't reached a termination state, then transition it // by sending a cancellation error. // Note: no more client callbacks will be done after this method -- the // clearClient() call ensures that. ResourceError error(String(), 0, String(), String()); error.setIsCancellation(true); - m_clientWrapper->didFail(error); - m_clientWrapper->clearClient(); + didFail(error); + DCHECK(!m_client); } -void WorkerThreadableLoader::Bridge::destroy() +void WorkerThreadableLoader::didStart(MainThreadLoaderHolder* mainThreadLoaderHolder) { DCHECK(!isMainThread()); - cancelPeer(); - m_clientWrapper->clearClient(); -} - -void WorkerThreadableLoader::Bridge::didStart(Peer* peer) -{ - DCHECK(!isMainThread()); - DCHECK(!m_peer); - DCHECK(peer); - if (m_clientWrapper->done()) { + DCHECK(!m_mainThreadLoaderHolder); + DCHECK(mainThreadLoaderHolder); + if (!m_client) { // The thread is terminating. - m_loaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&Peer::cancel, wrapCrossThreadPersistent(peer))); + m_workerLoaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&MainThreadLoaderHolder::cancel, wrapCrossThreadPersistent(mainThreadLoaderHolder))); return; } - m_peer = peer; + m_mainThreadLoaderHolder = mainThreadLoaderHolder; } -DEFINE_TRACE(WorkerThreadableLoader::Bridge) -{ - visitor->trace(m_clientWrapper); -} - -void WorkerThreadableLoader::Bridge::cancelPeer() +void WorkerThreadableLoader::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) { DCHECK(!isMainThread()); - if (!m_peer) + if (!m_client) return; - m_loaderProxy->postTaskToLoader(BLINK_FROM_HERE, createCrossThreadTask(&Peer::cancel, m_peer)); - m_peer = nullptr; + m_client->didSendData(bytesSent, totalBytesToBeSent); } -void WorkerThreadableLoader::Peer::createAndStart( - Bridge* bridge, +void WorkerThreadableLoader::didReceiveResponse(unsigned long identifier, std::unique_ptr<CrossThreadResourceResponseData> responseData, std::unique_ptr<WebDataConsumerHandle> handle) +{ + DCHECK(!isMainThread()); + if (!m_client) + return; + ResourceResponse response(responseData.get()); + m_client->didReceiveResponse(identifier, response, std::move(handle)); +} + +void WorkerThreadableLoader::didReceiveData(std::unique_ptr<Vector<char>> data) +{ + DCHECK(!isMainThread()); + CHECK_LE(data->size(), std::numeric_limits<unsigned>::max()); + if (!m_client) + return; + m_client->didReceiveData(data->data(), data->size()); +} + +void WorkerThreadableLoader::didReceiveCachedMetadata(std::unique_ptr<Vector<char>> data) +{ + DCHECK(!isMainThread()); + if (!m_client) + return; + m_client->didReceiveCachedMetadata(data->data(), data->size()); +} + +void WorkerThreadableLoader::didFinishLoading(unsigned long identifier, double finishTime) +{ + DCHECK(!isMainThread()); + if (!m_client) + return; + auto* client = m_client; + m_client = nullptr; + m_mainThreadLoaderHolder = nullptr; + client->didFinishLoading(identifier, finishTime); +} + +void WorkerThreadableLoader::didFail(const ResourceError& error) +{ + DCHECK(!isMainThread()); + if (!m_client) + return; + auto* client = m_client; + m_client = nullptr; + m_mainThreadLoaderHolder = nullptr; + client->didFail(error); +} + +void WorkerThreadableLoader::didFailAccessControlCheck(const ResourceError& error) +{ + DCHECK(!isMainThread()); + if (!m_client) + return; + auto* client = m_client; + m_client = nullptr; + m_mainThreadLoaderHolder = nullptr; + client->didFailAccessControlCheck(error); +} + +void WorkerThreadableLoader::didFailRedirectCheck() +{ + DCHECK(!isMainThread()); + if (!m_client) + return; + auto* client = m_client; + m_client = nullptr; + m_mainThreadLoaderHolder = nullptr; + client->didFailRedirectCheck(); +} + +void WorkerThreadableLoader::didDownloadData(int dataLength) +{ + DCHECK(!isMainThread()); + if (!m_client) + return; + m_client->didDownloadData(dataLength); +} + +void WorkerThreadableLoader::didReceiveResourceTiming(std::unique_ptr<CrossThreadResourceTimingInfoData> timingData) +{ + DCHECK(!isMainThread()); + if (!m_client) + return; + std::unique_ptr<ResourceTimingInfo> info(ResourceTimingInfo::adopt(std::move(timingData))); + WorkerGlobalScopePerformance::performance(*m_workerGlobalScope)->addResourceTiming(*info); + m_client->didReceiveResourceTiming(*info); +} + +DEFINE_TRACE(WorkerThreadableLoader) +{ + visitor->trace(m_workerGlobalScope); + ThreadableLoader::trace(visitor); +} + +void WorkerThreadableLoader::MainThreadLoaderHolder::createAndStart( + WorkerThreadableLoader* workerLoader, PassRefPtr<WorkerLoaderProxy> passLoaderProxy, WorkerThreadLifecycleContext* workerThreadLifecycleContext, std::unique_ptr<CrossThreadResourceRequestData> request, @@ -385,25 +438,25 @@ else forwarder = new AsyncTaskForwarder(loaderProxy); - Peer* peer = new Peer(forwarder, workerThreadLifecycleContext); - if (peer->wasContextDestroyedBeforeObserverCreation()) { + MainThreadLoaderHolder* mainThreadLoaderHolder = new MainThreadLoaderHolder(forwarder, workerThreadLifecycleContext); + if (mainThreadLoaderHolder->wasContextDestroyedBeforeObserverCreation()) { // The thread is already terminating. forwarder->abort(); - peer->m_forwarder = nullptr; + mainThreadLoaderHolder->m_forwarder = nullptr; return; } - peer->m_clientWrapper = bridge->clientWrapper(); - peer->start(*toDocument(executionContext), std::move(request), options, resourceLoaderOptions); - forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&Bridge::didStart, wrapCrossThreadPersistent(bridge), wrapCrossThreadPersistent(peer))); + mainThreadLoaderHolder->m_workerLoader = workerLoader; + mainThreadLoaderHolder->start(*toDocument(executionContext), std::move(request), options, resourceLoaderOptions); + forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&WorkerThreadableLoader::didStart, wrapCrossThreadPersistent(workerLoader), wrapCrossThreadPersistent(mainThreadLoaderHolder))); } -WorkerThreadableLoader::Peer::~Peer() +WorkerThreadableLoader::MainThreadLoaderHolder::~MainThreadLoaderHolder() { DCHECK(isMainThread()); - DCHECK(!m_mainThreadLoader); + DCHECK(!m_workerLoader); } -void WorkerThreadableLoader::Peer::overrideTimeout(unsigned long timeoutMilliseconds) +void WorkerThreadableLoader::MainThreadLoaderHolder::overrideTimeout(unsigned long timeoutMilliseconds) { DCHECK(isMainThread()); if (!m_mainThreadLoader) @@ -411,7 +464,7 @@ m_mainThreadLoader->overrideTimeout(timeoutMilliseconds); } -void WorkerThreadableLoader::Peer::cancel() +void WorkerThreadableLoader::MainThreadLoaderHolder::cancel() { DCHECK(isMainThread()); if (!m_mainThreadLoader) @@ -420,125 +473,126 @@ m_mainThreadLoader = nullptr; } -void WorkerThreadableLoader::Peer::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) +void WorkerThreadableLoader::MainThreadLoaderHolder::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) { DCHECK(isMainThread()); - CrossThreadPersistent<ThreadableLoaderClientWrapper> clientWrapper = m_clientWrapper.get(); - if (!clientWrapper || !m_forwarder) + CrossThreadPersistent<WorkerThreadableLoader> workerLoader = m_workerLoader.get(); + if (!workerLoader || !m_forwarder) return; - m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didSendData, clientWrapper, bytesSent, totalBytesToBeSent)); + m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&WorkerThreadableLoader::didSendData, workerLoader, bytesSent, totalBytesToBeSent)); } -void WorkerThreadableLoader::Peer::didReceiveResponse(unsigned long identifier, const ResourceResponse& response, std::unique_ptr<WebDataConsumerHandle> handle) +void WorkerThreadableLoader::MainThreadLoaderHolder::didReceiveResponse(unsigned long identifier, const ResourceResponse& response, std::unique_ptr<WebDataConsumerHandle> handle) { DCHECK(isMainThread()); - CrossThreadPersistent<ThreadableLoaderClientWrapper> clientWrapper = m_clientWrapper.get(); - if (!clientWrapper || !m_forwarder) + CrossThreadPersistent<WorkerThreadableLoader> workerLoader = m_workerLoader.get(); + if (!workerLoader || !m_forwarder) return; - m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didReceiveResponse, clientWrapper, identifier, response, passed(std::move(handle)))); + m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&WorkerThreadableLoader::didReceiveResponse, workerLoader, identifier, response, passed(std::move(handle)))); } -void WorkerThreadableLoader::Peer::didReceiveData(const char* data, unsigned dataLength) +void WorkerThreadableLoader::MainThreadLoaderHolder::didReceiveData(const char* data, unsigned dataLength) { DCHECK(isMainThread()); - CrossThreadPersistent<ThreadableLoaderClientWrapper> clientWrapper = m_clientWrapper.get(); - if (!clientWrapper || !m_forwarder) + CrossThreadPersistent<WorkerThreadableLoader> workerLoader = m_workerLoader.get(); + if (!workerLoader || !m_forwarder) return; - m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didReceiveData, clientWrapper, passed(createVectorFromMemoryRegion(data, dataLength)))); + m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&WorkerThreadableLoader::didReceiveData, workerLoader, passed(createVectorFromMemoryRegion(data, dataLength)))); } -void WorkerThreadableLoader::Peer::didDownloadData(int dataLength) +void WorkerThreadableLoader::MainThreadLoaderHolder::didDownloadData(int dataLength) { DCHECK(isMainThread()); - CrossThreadPersistent<ThreadableLoaderClientWrapper> clientWrapper = m_clientWrapper.get(); - if (!clientWrapper || !m_forwarder) + CrossThreadPersistent<WorkerThreadableLoader> workerLoader = m_workerLoader.get(); + if (!workerLoader || !m_forwarder) return; - m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didDownloadData, clientWrapper, dataLength)); + m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&WorkerThreadableLoader::didDownloadData, workerLoader, dataLength)); } -void WorkerThreadableLoader::Peer::didReceiveCachedMetadata(const char* data, int dataLength) +void WorkerThreadableLoader::MainThreadLoaderHolder::didReceiveCachedMetadata(const char* data, int dataLength) { DCHECK(isMainThread()); - CrossThreadPersistent<ThreadableLoaderClientWrapper> clientWrapper = m_clientWrapper.get(); - if (!clientWrapper || !m_forwarder) + CrossThreadPersistent<WorkerThreadableLoader> workerLoader = m_workerLoader.get(); + if (!workerLoader || !m_forwarder) return; - m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didReceiveCachedMetadata, clientWrapper, passed(createVectorFromMemoryRegion(data, dataLength)))); + m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&WorkerThreadableLoader::didReceiveCachedMetadata, workerLoader, passed(createVectorFromMemoryRegion(data, dataLength)))); } -void WorkerThreadableLoader::Peer::didFinishLoading(unsigned long identifier, double finishTime) +void WorkerThreadableLoader::MainThreadLoaderHolder::didFinishLoading(unsigned long identifier, double finishTime) { DCHECK(isMainThread()); - CrossThreadPersistent<ThreadableLoaderClientWrapper> clientWrapper = m_clientWrapper.get(); - if (!clientWrapper || !m_forwarder) + CrossThreadPersistent<WorkerThreadableLoader> workerLoader = m_workerLoader.get(); + if (!workerLoader || !m_forwarder) return; - m_forwarder->forwardTaskWithDoneSignal(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didFinishLoading, clientWrapper, identifier, finishTime)); + m_forwarder->forwardTaskWithDoneSignal(BLINK_FROM_HERE, createCrossThreadTask(&WorkerThreadableLoader::didFinishLoading, workerLoader, identifier, finishTime)); m_forwarder = nullptr; } -void WorkerThreadableLoader::Peer::didFail(const ResourceError& error) +void WorkerThreadableLoader::MainThreadLoaderHolder::didFail(const ResourceError& error) { DCHECK(isMainThread()); - CrossThreadPersistent<ThreadableLoaderClientWrapper> clientWrapper = m_clientWrapper.get(); - if (!clientWrapper || !m_forwarder) + CrossThreadPersistent<WorkerThreadableLoader> workerLoader = m_workerLoader.get(); + if (!workerLoader || !m_forwarder) return; - m_forwarder->forwardTaskWithDoneSignal(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didFail, clientWrapper, error)); + m_forwarder->forwardTaskWithDoneSignal(BLINK_FROM_HERE, createCrossThreadTask(&WorkerThreadableLoader::didFail, workerLoader, error)); m_forwarder = nullptr; } -void WorkerThreadableLoader::Peer::didFailAccessControlCheck(const ResourceError& error) +void WorkerThreadableLoader::MainThreadLoaderHolder::didFailAccessControlCheck(const ResourceError& error) { DCHECK(isMainThread()); - CrossThreadPersistent<ThreadableLoaderClientWrapper> clientWrapper = m_clientWrapper.get(); - if (!clientWrapper || !m_forwarder) + CrossThreadPersistent<WorkerThreadableLoader> workerLoader = m_workerLoader.get(); + if (!workerLoader || !m_forwarder) return; - m_forwarder->forwardTaskWithDoneSignal(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didFailAccessControlCheck, clientWrapper, error)); + m_forwarder->forwardTaskWithDoneSignal(BLINK_FROM_HERE, createCrossThreadTask(&WorkerThreadableLoader::didFailAccessControlCheck, workerLoader, error)); m_forwarder = nullptr; } -void WorkerThreadableLoader::Peer::didFailRedirectCheck() +void WorkerThreadableLoader::MainThreadLoaderHolder::didFailRedirectCheck() { DCHECK(isMainThread()); - CrossThreadPersistent<ThreadableLoaderClientWrapper> clientWrapper = m_clientWrapper.get(); - if (!clientWrapper || !m_forwarder) + CrossThreadPersistent<WorkerThreadableLoader> workerLoader = m_workerLoader.get(); + if (!workerLoader || !m_forwarder) return; - m_forwarder->forwardTaskWithDoneSignal(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didFailRedirectCheck, clientWrapper)); + m_forwarder->forwardTaskWithDoneSignal(BLINK_FROM_HERE, createCrossThreadTask(&WorkerThreadableLoader::didFailRedirectCheck, workerLoader)); m_forwarder = nullptr; } -void WorkerThreadableLoader::Peer::didReceiveResourceTiming(const ResourceTimingInfo& info) +void WorkerThreadableLoader::MainThreadLoaderHolder::didReceiveResourceTiming(const ResourceTimingInfo& info) { DCHECK(isMainThread()); - CrossThreadPersistent<ThreadableLoaderClientWrapper> clientWrapper = m_clientWrapper.get(); - if (!clientWrapper || !m_forwarder) + CrossThreadPersistent<WorkerThreadableLoader> workerLoader = m_workerLoader.get(); + if (!workerLoader || !m_forwarder) return; - m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&ThreadableLoaderClientWrapper::didReceiveResourceTiming, clientWrapper, info)); + m_forwarder->forwardTask(BLINK_FROM_HERE, createCrossThreadTask(&WorkerThreadableLoader::didReceiveResourceTiming, workerLoader, info)); } -void WorkerThreadableLoader::Peer::contextDestroyed() +void WorkerThreadableLoader::MainThreadLoaderHolder::contextDestroyed() { DCHECK(isMainThread()); if (m_forwarder) { m_forwarder->abort(); m_forwarder = nullptr; } - m_clientWrapper = nullptr; + m_workerLoader = nullptr; cancel(); } -DEFINE_TRACE(WorkerThreadableLoader::Peer) +DEFINE_TRACE(WorkerThreadableLoader::MainThreadLoaderHolder) { visitor->trace(m_forwarder); + visitor->trace(m_mainThreadLoader); WorkerThreadLifecycleObserver::trace(visitor); } -WorkerThreadableLoader::Peer::Peer(TaskForwarder* forwarder, WorkerThreadLifecycleContext* context) +WorkerThreadableLoader::MainThreadLoaderHolder::MainThreadLoaderHolder(TaskForwarder* forwarder, WorkerThreadLifecycleContext* context) : WorkerThreadLifecycleObserver(context) , m_forwarder(forwarder) { DCHECK(isMainThread()); } -void WorkerThreadableLoader::Peer::start( +void WorkerThreadableLoader::MainThreadLoaderHolder::start( Document& document, std::unique_ptr<CrossThreadResourceRequestData> request, const ThreadableLoaderOptions& options,
diff --git a/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h b/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h index 700ec9a..bcd683ee 100644 --- a/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h +++ b/third_party/WebKit/Source/core/loader/WorkerThreadableLoader.h
@@ -34,14 +34,12 @@ #include "core/dom/ExecutionContextTask.h" #include "core/loader/ThreadableLoader.h" #include "core/loader/ThreadableLoaderClient.h" -#include "core/loader/ThreadableLoaderClientWrapper.h" #include "core/workers/WorkerThread.h" #include "core/workers/WorkerThreadLifecycleObserver.h" #include "platform/WaitableEvent.h" #include "platform/heap/Handle.h" #include "public/platform/WebTraceLocation.h" #include "wtf/PassRefPtr.h" -#include "wtf/PtrUtil.h" #include "wtf/RefPtr.h" #include "wtf/Threading.h" #include "wtf/Vector.h" @@ -56,25 +54,50 @@ class WorkerGlobalScope; class WorkerLoaderProxy; struct CrossThreadResourceRequestData; +struct CrossThreadResourceTimingInfoData; -// TODO(yhirano): Draw a diagram to illustrate the class relationship. -// TODO(yhirano): Rename inner classes so that readers can see in which thread -// they are living easily. +// A WorkerThreadableLoader is a ThreadableLoader implementation intended to +// be used in a WebWorker thread. Because Blink's ResourceFetcher and +// ResourceLoader work only in the main thread, a WorkerThreadableLoader holds +// a ThreadableLoader in the main thread and delegates tasks asynchronously +// to the loader. +// +// CTP: CrossThreadPersistent +// CTWP: CrossThreadWeakPersistent +// +// ---------------------------------------------------------------- +// +------------------------+ +// raw ptr | ThreadableLoaderClient | +// +--------> | worker thread | +// | +------------------------+ +// | +// +----+------------------+ CTP +------------------------+ +// + WorkerThreadableLoader|<--------+ MainThreadLoaderHolder | +// | worker thread +-------->| main thread | +// +-----------------------+ CTWP +----------------------+-+ +// | +// +------------------+ | Member +// | ThreadableLoader | <---+ +// | main thread | +// +------------------+ +// class WorkerThreadableLoader final : public ThreadableLoader { - USING_FAST_MALLOC(WorkerThreadableLoader); public: static void loadResourceSynchronously(WorkerGlobalScope&, const ResourceRequest&, ThreadableLoaderClient&, const ThreadableLoaderOptions&, const ResourceLoaderOptions&); - static std::unique_ptr<WorkerThreadableLoader> create(WorkerGlobalScope& workerGlobalScope, ThreadableLoaderClient* client, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions) + static WorkerThreadableLoader* create(WorkerGlobalScope& workerGlobalScope, ThreadableLoaderClient* client, const ThreadableLoaderOptions& options, const ResourceLoaderOptions& resourceLoaderOptions) { - return wrapUnique(new WorkerThreadableLoader(workerGlobalScope, client, options, resourceLoaderOptions, LoadAsynchronously)); + return new WorkerThreadableLoader(workerGlobalScope, client, options, resourceLoaderOptions, LoadAsynchronously); } ~WorkerThreadableLoader() override; + // ThreadableLoader functions void start(const ResourceRequest&) override; void overrideTimeout(unsigned long timeout) override; void cancel() override; + DECLARE_TRACE(); + private: enum BlockingBehavior { LoadSynchronously, @@ -96,47 +119,15 @@ class WaitableEventWithTasks; class SyncTaskForwarder; - class Peer; - // A Bridge instance lives in the worker thread and requests the associated - // Peer (which lives in the main thread) to process loading tasks. - class Bridge final : public GarbageCollectedFinalized<Bridge> { - public: - Bridge(ThreadableLoaderClientWrapper*, PassRefPtr<WorkerLoaderProxy>, const ThreadableLoaderOptions&, const ResourceLoaderOptions&, BlockingBehavior); - ~Bridge(); - - void start(const ResourceRequest&, const WorkerGlobalScope&); - void overrideTimeout(unsigned long timeoutMilliseconds); - void cancel(); - void destroy(); - - void didStart(Peer*); - - // This getter function is thread safe. - ThreadableLoaderClientWrapper* clientWrapper() { return m_clientWrapper.get(); } - - DECLARE_VIRTUAL_TRACE(); - - private: - void cancelPeer(); - - const Member<ThreadableLoaderClientWrapper> m_clientWrapper; - const RefPtr<WorkerLoaderProxy> m_loaderProxy; - const ThreadableLoaderOptions m_threadableLoaderOptions; - const ResourceLoaderOptions m_resourceLoaderOptions; - const BlockingBehavior m_blockingBehavior; - - // |*m_peer| lives in the main thread. - CrossThreadPersistent<Peer> m_peer; - }; - - // A Peer instance lives in the main thread. It is a ThreadableLoaderClient - // for a DocumentThreadableLoader and forward notifications to the - // ThreadableLoaderClientWrapper which lives in the worker thread. - class Peer final : public GarbageCollectedFinalized<Peer>, public ThreadableLoaderClient, public WorkerThreadLifecycleObserver { - USING_GARBAGE_COLLECTED_MIXIN(Peer); + // An instance of this class lives in the main thread. It is a + // ThreadableLoaderClient for a DocumentThreadableLoader and forward + // notifications to the associated WorkerThreadableLoader living in the + // worker thread. + class MainThreadLoaderHolder final : public GarbageCollectedFinalized<MainThreadLoaderHolder>, public ThreadableLoaderClient, public WorkerThreadLifecycleObserver { + USING_GARBAGE_COLLECTED_MIXIN(MainThreadLoaderHolder); public: static void createAndStart( - Bridge*, + WorkerThreadableLoader*, PassRefPtr<WorkerLoaderProxy>, WorkerThreadLifecycleContext*, std::unique_ptr<CrossThreadResourceRequestData>, @@ -144,7 +135,7 @@ const ResourceLoaderOptions&, PassRefPtr<WaitableEventWithTasks>, ExecutionContext*); - ~Peer() override; + ~MainThreadLoaderHolder() override; void overrideTimeout(unsigned long timeoutMillisecond); void cancel(); @@ -165,21 +156,40 @@ DECLARE_TRACE(); private: - Peer(TaskForwarder*, WorkerThreadLifecycleContext*); + MainThreadLoaderHolder(TaskForwarder*, WorkerThreadLifecycleContext*); void start(Document&, std::unique_ptr<CrossThreadResourceRequestData>, const ThreadableLoaderOptions&, const ResourceLoaderOptions&); Member<TaskForwarder> m_forwarder; - std::unique_ptr<ThreadableLoader> m_mainThreadLoader; + Member<ThreadableLoader> m_mainThreadLoader; - // |*m_clientWrapper| lives in the worker thread. - CrossThreadWeakPersistent<ThreadableLoaderClientWrapper> m_clientWrapper; + // |*m_workerLoader| lives in the worker thread. + CrossThreadWeakPersistent<WorkerThreadableLoader> m_workerLoader; }; WorkerThreadableLoader(WorkerGlobalScope&, ThreadableLoaderClient*, const ThreadableLoaderOptions&, const ResourceLoaderOptions&, BlockingBehavior); + void didStart(MainThreadLoaderHolder*); - Persistent<WorkerGlobalScope> m_workerGlobalScope; - const Persistent<ThreadableLoaderClientWrapper> m_workerClientWrapper; - const Persistent<Bridge> m_bridge; + void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent); + void didReceiveResponse(unsigned long identifier, std::unique_ptr<CrossThreadResourceResponseData>, std::unique_ptr<WebDataConsumerHandle>); + void didReceiveData(std::unique_ptr<Vector<char>> data); + void didReceiveCachedMetadata(std::unique_ptr<Vector<char>> data); + void didFinishLoading(unsigned long identifier, double finishTime); + void didFail(const ResourceError&); + void didFailAccessControlCheck(const ResourceError&); + void didFailRedirectCheck(); + void didDownloadData(int dataLength); + void didReceiveResourceTiming(std::unique_ptr<CrossThreadResourceTimingInfoData>); + + Member<WorkerGlobalScope> m_workerGlobalScope; + RefPtr<WorkerLoaderProxy> m_workerLoaderProxy; + ThreadableLoaderClient* m_client; + + ThreadableLoaderOptions m_threadableLoaderOptions; + ResourceLoaderOptions m_resourceLoaderOptions; + BlockingBehavior m_blockingBehavior; + + // |*m_mainThreadLoaderHolder| lives in the main thread. + CrossThreadPersistent<MainThreadLoaderHolder> m_mainThreadLoaderHolder; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/page/ChromeClient.h b/third_party/WebKit/Source/core/page/ChromeClient.h index 762d7844..fd65136 100644 --- a/third_party/WebKit/Source/core/page/ChromeClient.h +++ b/third_party/WebKit/Source/core/page/ChromeClient.h
@@ -211,8 +211,8 @@ virtual void enterFullScreenForElement(Element*) { } virtual void exitFullScreenForElement(Element*) { } - virtual void clearCompositedSelection() { } - virtual void updateCompositedSelection(const CompositedSelection&) { } + virtual void clearCompositedSelection(LocalFrame*) { } + virtual void updateCompositedSelection(LocalFrame*, const CompositedSelection&) { } virtual void setEventListenerProperties(WebEventListenerClass, WebEventListenerProperties) = 0; virtual WebEventListenerProperties eventListenerProperties(WebEventListenerClass) const = 0;
diff --git a/third_party/WebKit/Source/core/page/EventSource.cpp b/third_party/WebKit/Source/core/page/EventSource.cpp index 7a5b32e2..1cbd5d48 100644 --- a/third_party/WebKit/Source/core/page/EventSource.cpp +++ b/third_party/WebKit/Source/core/page/EventSource.cpp
@@ -360,6 +360,7 @@ DEFINE_TRACE(EventSource) { visitor->trace(m_parser); + visitor->trace(m_loader); EventTargetWithInlineData::trace(visitor); ActiveDOMObject::trace(visitor); EventSourceParser::Client::trace(visitor);
diff --git a/third_party/WebKit/Source/core/page/EventSource.h b/third_party/WebKit/Source/core/page/EventSource.h index 24c1598..0e6336e 100644 --- a/third_party/WebKit/Source/core/page/EventSource.h +++ b/third_party/WebKit/Source/core/page/EventSource.h
@@ -122,7 +122,7 @@ State m_state; Member<EventSourceParser> m_parser; - std::unique_ptr<ThreadableLoader> m_loader; + Member<ThreadableLoader> m_loader; Timer<EventSource> m_connectTimer; unsigned long long m_reconnectDelay;
diff --git a/third_party/WebKit/Source/core/page/Page.cpp b/third_party/WebKit/Source/core/page/Page.cpp index 8198308..887326ea 100644 --- a/third_party/WebKit/Source/core/page/Page.cpp +++ b/third_party/WebKit/Source/core/page/Page.cpp
@@ -286,16 +286,6 @@ deprecatedLocalMainFrame()->deviceScaleFactorChanged(); } -void Page::setDeviceColorProfile(const Vector<char>& profile) -{ - // FIXME: implement. -} - -void Page::resetDeviceColorProfileForTesting() -{ - RuntimeEnabledFeatures::setImageColorProfilesEnabled(false); -} - void Page::allVisitedStateChanged(bool invalidateVisitedLinkHashes) { for (const Page* page : ordinaryPages()) {
diff --git a/third_party/WebKit/Source/core/page/Page.h b/third_party/WebKit/Source/core/page/Page.h index a54f9c9..99eee3c 100644 --- a/third_party/WebKit/Source/core/page/Page.h +++ b/third_party/WebKit/Source/core/page/Page.h
@@ -173,8 +173,6 @@ float deviceScaleFactor() const { return m_deviceScaleFactor; } void setDeviceScaleFactor(float); - void setDeviceColorProfile(const Vector<char>&); - void resetDeviceColorProfileForTesting(); static void allVisitedStateChanged(bool invalidateVisitedLinkHashes); static void visitedStateChanged(LinkHash visitedHash);
diff --git a/third_party/WebKit/Source/core/page/PageAnimator.cpp b/third_party/WebKit/Source/core/page/PageAnimator.cpp index 32db0bc..5720f0a 100644 --- a/third_party/WebKit/Source/core/page/PageAnimator.cpp +++ b/third_party/WebKit/Source/core/page/PageAnimator.cpp
@@ -10,7 +10,6 @@ #include "core/page/ChromeClient.h" #include "core/page/Page.h" #include "core/svg/SVGDocumentExtensions.h" -#include "platform/Logging.h" #include "wtf/AutoReset.h" namespace blink { @@ -45,7 +44,7 @@ for (auto& document : documents) { ScopedFrameBlamer frameBlamer(document->frame()); - TRACE_EVENT0("blink", "PageAnimator::serviceScriptedAnimations"); + TRACE_EVENT0("blink,rail", "PageAnimator::serviceScriptedAnimations"); DocumentAnimations::updateAnimationTimingForAnimationFrame(*document); if (document->view()) { if (document->view()->shouldThrottleRendering())
diff --git a/third_party/WebKit/Source/core/paint/BlockFlowPaintInvalidator.cpp b/third_party/WebKit/Source/core/paint/BlockFlowPaintInvalidator.cpp new file mode 100644 index 0000000..7285733 --- /dev/null +++ b/third_party/WebKit/Source/core/paint/BlockFlowPaintInvalidator.cpp
@@ -0,0 +1,42 @@ +// Copyright 2016 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 "core/paint/BlockFlowPaintInvalidator.h" + +#include "core/layout/LayoutBlockFlow.h" +#include "core/paint/BoxPaintInvalidator.h" +#include "core/paint/PaintInvalidator.h" + +namespace blink { + +PaintInvalidationReason BlockFlowPaintInvalidator::invalidatePaintIfNeeded() +{ + PaintInvalidationReason reason = BoxPaintInvalidator(m_blockFlow, m_context).invalidatePaintIfNeeded(); + + // TODO(wangxianzhu): Refactor the following into invalidateDisplayItemClients(). + + if (reason == PaintInvalidationNone || reason == PaintInvalidationDelayedFull) + return reason; + + RootInlineBox* line = m_blockFlow.firstRootBox(); + if (line && line->isFirstLineStyle()) { + // It's the RootInlineBox that paints the ::first-line background. Note that since it may be + // expensive to figure out if the first line is affected by any ::first-line selectors at all, + // we just invalidate it unconditionally which is typically cheaper. + m_blockFlow.invalidateDisplayItemClient(*line, reason); + } + + if (m_blockFlow.multiColumnFlowThread()) { + // Invalidate child LayoutMultiColumnSets which may need to repaint column rules after + // m_blockFlow's column rule style and/or layout changed. + for (LayoutObject* child = m_blockFlow.firstChild(); child; child = child->nextSibling()) { + if (child->isLayoutMultiColumnSet() && !child->shouldDoFullPaintInvalidation()) + m_blockFlow.invalidateDisplayItemClient(*child, reason); + } + } + + return reason; +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/BlockFlowPaintInvalidator.h b/third_party/WebKit/Source/core/paint/BlockFlowPaintInvalidator.h new file mode 100644 index 0000000..960ec01 --- /dev/null +++ b/third_party/WebKit/Source/core/paint/BlockFlowPaintInvalidator.h
@@ -0,0 +1,31 @@ +// Copyright 2016 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 BlockFlowPaintInvalidator_h +#define BlockFlowPaintInvalidator_h + +#include "platform/graphics/PaintInvalidationReason.h" +#include "wtf/Allocator.h" + +namespace blink { + +class LayoutBlockFlow; +struct PaintInvalidatorContext; + +class BlockFlowPaintInvalidator { + STACK_ALLOCATED(); +public: + BlockFlowPaintInvalidator(const LayoutBlockFlow& blockFlow, const PaintInvalidatorContext& context) + : m_blockFlow(blockFlow), m_context(context) { } + + PaintInvalidationReason invalidatePaintIfNeeded(); + +private: + const LayoutBlockFlow& m_blockFlow; + const PaintInvalidatorContext& m_context; +}; + +} // namespace blink + +#endif
diff --git a/third_party/WebKit/Source/core/paint/BoxPaintInvalidator.cpp b/third_party/WebKit/Source/core/paint/BoxPaintInvalidator.cpp new file mode 100644 index 0000000..a1625c3a --- /dev/null +++ b/third_party/WebKit/Source/core/paint/BoxPaintInvalidator.cpp
@@ -0,0 +1,278 @@ +// Copyright 2016 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 "core/paint/BoxPaintInvalidator.h" + +#include "core/frame/Settings.h" +#include "core/layout/LayoutView.h" +#include "core/paint/ObjectPaintInvalidator.h" +#include "core/paint/PaintInvalidator.h" +#include "core/paint/PaintLayer.h" +#include "core/paint/PaintLayerScrollableArea.h" +#include "platform/geometry/LayoutRect.h" + +namespace blink { + +struct PreviousBoxSizes { + LayoutSize borderBoxSize; + LayoutRect contentBoxRect; + LayoutRect layoutOverflowRect; +}; + +typedef HashMap<const LayoutBox*, PreviousBoxSizes> PreviousBoxSizesMap; +static PreviousBoxSizesMap& previousBoxSizesMap() +{ + DEFINE_STATIC_LOCAL(PreviousBoxSizesMap, map, ()); + return map; +} + +void BoxPaintInvalidator::boxWillBeDestroyed(const LayoutBox& box) +{ + previousBoxSizesMap().remove(&box); +} + +// This is called when ObjectPaintInvalidator already did incremental invalidation, +// so this function just does what is additionally needed for the LayoutBox. +void BoxPaintInvalidator::incrementallyInvalidatePaint() +{ + bool hasBoxDecorations = m_box.styleRef().hasBoxDecorations(); + if (!m_box.styleRef().hasBackground() && !hasBoxDecorations) + return; + + const LayoutRect& oldBounds = m_context.oldBounds; + const LayoutRect& newBounds = m_context.newBounds; + + LayoutSize oldBorderBoxSize = computePreviousBorderBoxSize(oldBounds.size()); + LayoutSize newBorderBoxSize = m_box.size(); + + // If border m_box size didn't change, LayoutObject's incrementallyInvalidatePaint() is good. + if (oldBorderBoxSize == newBorderBoxSize) + return; + + // If size of the paint invalidation rect equals to size of border box, ObjectPaintInvalidator::incrementallyInvalidatePaint() + // is good for boxes having background without box decorations. + DCHECK(oldBounds.location() == newBounds.location()); // Otherwise we won't do incremental invalidation. + if (!hasBoxDecorations + && m_context.newLocation == newBounds.location() + && oldBorderBoxSize == oldBounds.size() + && newBorderBoxSize == newBounds.size()) + return; + + // Invalidate the right delta part and the right border of the old or new m_box which has smaller width. + if (LayoutUnit deltaWidth = (oldBorderBoxSize.width() - newBorderBoxSize.width()).abs()) { + LayoutUnit smallerWidth = std::min(oldBorderBoxSize.width(), newBorderBoxSize.width()); + LayoutUnit borderTopRightRadiusWidth = valueForLength(m_box.styleRef().borderTopRightRadius().width(), smallerWidth); + LayoutUnit borderBottomRightRadiusWidth = valueForLength(m_box.styleRef().borderBottomRightRadius().width(), smallerWidth); + LayoutUnit borderWidth = std::max(LayoutUnit(m_box.borderRight()), std::max(borderTopRightRadiusWidth, borderBottomRightRadiusWidth)); + LayoutRect rightDeltaRect(m_context.newLocation.x() + smallerWidth - borderWidth, m_context.newLocation.y(), + deltaWidth + borderWidth, std::max(oldBorderBoxSize.height(), newBorderBoxSize.height())); + invalidatePaintRectClippedByOldAndNewBounds(rightDeltaRect); + } + + // Invalidate the bottom delta part and the bottom border of the old or new m_box which has smaller height. + if (LayoutUnit deltaHeight = (oldBorderBoxSize.height() - newBorderBoxSize.height()).abs()) { + LayoutUnit smallerHeight = std::min(oldBorderBoxSize.height(), newBorderBoxSize.height()); + LayoutUnit borderBottomLeftRadiusHeight = valueForLength(m_box.styleRef().borderBottomLeftRadius().height(), smallerHeight); + LayoutUnit borderBottomRightRadiusHeight = valueForLength(m_box.styleRef().borderBottomRightRadius().height(), smallerHeight); + LayoutUnit borderHeight = std::max(LayoutUnit(m_box.borderBottom()), std::max(borderBottomLeftRadiusHeight, borderBottomRightRadiusHeight)); + LayoutRect bottomDeltaRect(m_context.newLocation.x(), m_context.newLocation.y() + smallerHeight - borderHeight, + std::max(oldBorderBoxSize.width(), newBorderBoxSize.width()), deltaHeight + borderHeight); + invalidatePaintRectClippedByOldAndNewBounds(bottomDeltaRect); + } +} + +void BoxPaintInvalidator::invalidatePaintRectClippedByOldAndNewBounds(const LayoutRect& rect) +{ + if (rect.isEmpty()) + return; + + LayoutRect rectClippedByOldBounds = intersection(rect, m_context.oldBounds); + LayoutRect rectClippedByNewBounds = intersection(rect, m_context.newBounds); + // Invalidate only once if the clipped rects equal. + if (rectClippedByOldBounds == rectClippedByNewBounds) { + m_box.invalidatePaintUsingContainer(*m_context.paintInvalidationContainer, rectClippedByOldBounds, PaintInvalidationIncremental); + return; + } + // Invalidate the bigger one if one contains another. Otherwise invalidate both. + if (!rectClippedByNewBounds.contains(rectClippedByOldBounds)) + m_box.invalidatePaintUsingContainer(*m_context.paintInvalidationContainer, rectClippedByOldBounds, PaintInvalidationIncremental); + if (!rectClippedByOldBounds.contains(rectClippedByNewBounds)) + m_box.invalidatePaintUsingContainer(*m_context.paintInvalidationContainer, rectClippedByNewBounds, PaintInvalidationIncremental); +} + +PaintInvalidationReason BoxPaintInvalidator::computePaintInvalidationReason() +{ + PaintInvalidationReason reason = ObjectPaintInvalidator(m_box, m_context).computePaintInvalidationReason(); + + if (reason != PaintInvalidationDelayedFull && isFullPaintInvalidationReason(reason)) + return reason; + + if (m_box.mayNeedPaintInvalidationAnimatedBackgroundImage() && !m_box.backgroundIsKnownToBeObscured()) + reason = PaintInvalidationDelayedFull; + + // If the current paint invalidation reason is PaintInvalidationDelayedFull, then this paint invalidation can delayed if the + // LayoutBox in question is not on-screen. The logic to decide whether this is appropriate exists at the site of the original + // paint invalidation that chose PaintInvalidationDelayedFull. + if (reason == PaintInvalidationDelayedFull) { + // Do regular full paint invalidation if the object is onscreen. + return m_box.intersectsVisibleViewport() ? PaintInvalidationFull : PaintInvalidationDelayedFull; + } + + if (m_box.isLayoutView()) { + const LayoutView& layoutView = toLayoutView(m_box); + // In normal compositing mode, root background doesn't need to be invalidated for + // box changes, because the background always covers the whole document rect + // and clipping is done by compositor()->m_containerLayer. Also the scrollbars + // are always composited. There are no other box decoration on the LayoutView thus + // we can safely exit here. + if (layoutView.usesCompositing() && (!layoutView.document().settings() || !layoutView.document().settings()->rootLayerScrolls())) + return reason; + } + + // If the transform is not identity or translation, incremental invalidation is not applicable + // because the difference between oldBounds and newBounds doesn't cover all area needing invalidation. + // FIXME: Should also consider ancestor transforms since paintInvalidationContainer. crbug.com/426111. + if (reason == PaintInvalidationIncremental + && m_context.paintInvalidationContainer != m_box + && m_box.hasLayer() && m_box.layer()->transform() + && !m_box.layer()->transform()->isIdentityOrTranslation()) + return PaintInvalidationBoundsChange; + + const ComputedStyle& style = m_box.styleRef(); + if (style.backgroundLayers().thisOrNextLayersUseContentBox() || style.maskLayers().thisOrNextLayersUseContentBox() || style.boxSizing() == BoxSizingBorderBox) { + if (previousBoxSizesMap().get(&m_box).contentBoxRect != m_box.contentBoxRect()) + return PaintInvalidationContentBoxChange; + } + + if (!style.hasBackground() && !style.hasBoxDecorations()) { + // We could let incremental invalidation cover non-composited scrollbars, but just + // do a full invalidation because incremental invalidation will go away with slimming paint. + if (reason == PaintInvalidationIncremental && m_box.hasNonCompositedScrollbars()) + return PaintInvalidationBorderBoxChange; + return reason; + } + + if (style.backgroundLayers().thisOrNextLayersHaveLocalAttachment()) { + if (previousBoxSizesMap().get(&m_box).layoutOverflowRect != m_box.layoutOverflowRect()) + return PaintInvalidationLayoutOverflowBoxChange; + } + + LayoutSize oldBorderBoxSize = computePreviousBorderBoxSize(m_context.oldBounds.size()); + LayoutSize newBorderBoxSize = m_box.size(); + + if (oldBorderBoxSize == newBorderBoxSize) + return reason; + + // LayoutBox::incrementallyInvalidatePaint() depends on positionFromPaintInvalidationBacking + // which is not available when slimmingPaintOffsetCachingEnabled. + if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() && (style.hasBoxDecorations() || style.hasBackground())) + return PaintInvalidationBorderBoxChange; + + // See another hasNonCompositedScrollbars() callsite above. + if (m_box.hasNonCompositedScrollbars()) + return PaintInvalidationBorderBoxChange; + + if (style.hasVisualOverflowingEffect() || style.hasAppearance() || style.hasFilterInducingProperty() || style.resize() != RESIZE_NONE) + return PaintInvalidationBorderBoxChange; + + if (style.hasBorderRadius()) { + // If a border-radius exists and width/height is smaller than radius width/height, + // we need to fully invalidate to cover the changed radius. + FloatRoundedRect oldRoundedRect = style.getRoundedBorderFor(LayoutRect(LayoutPoint(0, 0), oldBorderBoxSize)); + FloatRoundedRect newRoundedRect = style.getRoundedBorderFor(LayoutRect(LayoutPoint(0, 0), newBorderBoxSize)); + if (oldRoundedRect.getRadii() != newRoundedRect.getRadii()) + return PaintInvalidationBorderBoxChange; + } + + if (oldBorderBoxSize.width() != newBorderBoxSize.width() && m_box.mustInvalidateBackgroundOrBorderPaintOnWidthChange()) + return PaintInvalidationBorderBoxChange; + if (oldBorderBoxSize.height() != newBorderBoxSize.height() && m_box.mustInvalidateBackgroundOrBorderPaintOnHeightChange()) + return PaintInvalidationBorderBoxChange; + + if (reason == PaintInvalidationNone && (style.hasBackground() || style.hasBoxDecorations())) + reason = PaintInvalidationIncremental; + + return reason; +} + +PaintInvalidationReason BoxPaintInvalidator::invalidatePaintIfNeeded() +{ + PaintInvalidationReason reason = ObjectPaintInvalidator(m_box, m_context).invalidatePaintIfNeededWithComputedReason(computePaintInvalidationReason()); + + // For incremental invalidation, ObjectPaintInvalidator::incrementallyInvalidatePaint() is + // not enough for LayoutBox in some cases, e.g. having border, border-radius, etc. + // The following will do additional incremental invalidation for LayoutBox if needed. + if (reason == PaintInvalidationIncremental) + incrementallyInvalidatePaint(); + + if (PaintLayerScrollableArea* area = m_box.getScrollableArea()) + area->invalidatePaintOfScrollControlsIfNeeded(m_context); + + // This is for the next invalidatePaintIfNeeded so must be at the end. + savePreviousBoxSizesIfNeeded(); + + return reason; +} + +bool BoxPaintInvalidator::needsToSavePreviousBoxSizes() +{ + LayoutSize paintInvalidationSize = m_context.newBounds.size(); + // Don't save old box sizes if the paint rect is empty because we'll + // full invalidate once the paint rect becomes non-empty. + if (paintInvalidationSize.isEmpty()) + return false; + + const ComputedStyle& style = m_box.styleRef(); + + // If we use border-box sizing we need to track changes in the size of the content box. + if (style.boxSizing() == BoxSizingBorderBox) + return true; + + // We need the old box sizes only when the box has background, decorations, or masks. + // Main LayoutView paints base background, thus interested in box size. + if (!m_box.isLayoutView() && !style.hasBackground() && !style.hasBoxDecorations() && !style.hasMask()) + return false; + + // No need to save old border box size if we can use size of the old paint + // rect as the old border box size in the next invalidation. + if (paintInvalidationSize != m_box.size()) + return true; + + // Background and mask layers can depend on other boxes than border box. See crbug.com/490533 + if (style.backgroundLayers().thisOrNextLayersUseContentBox() || style.backgroundLayers().thisOrNextLayersHaveLocalAttachment() + || style.maskLayers().thisOrNextLayersUseContentBox()) + return true; + + return false; +} + +void BoxPaintInvalidator::savePreviousBoxSizesIfNeeded() +{ + if (!needsToSavePreviousBoxSizes()) { + previousBoxSizesMap().remove(&m_box); + return; + } + + PreviousBoxSizes sizes = { + m_box.size(), + m_box.contentBoxRect(), + m_box.layoutOverflowRect() + }; + previousBoxSizesMap().set(&m_box, sizes); +} + +LayoutSize BoxPaintInvalidator::computePreviousBorderBoxSize(const LayoutSize& previousBoundsSize) +{ + // PreviousBorderBoxSize is only valid when there is background or box decorations. + DCHECK(m_box.styleRef().hasBackground() || m_box.styleRef().hasBoxDecorations()); + + auto it = previousBoxSizesMap().find(&m_box); + if (it != previousBoxSizesMap().end()) + return it->value.borderBoxSize; + + // We didn't save the old border box size because it was the same as the size of oldBounds. + return previousBoundsSize; +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/BoxPaintInvalidator.h b/third_party/WebKit/Source/core/paint/BoxPaintInvalidator.h new file mode 100644 index 0000000..8ab4a212 --- /dev/null +++ b/third_party/WebKit/Source/core/paint/BoxPaintInvalidator.h
@@ -0,0 +1,44 @@ +// Copyright 2016 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 BoxPaintInvalidator_h +#define BoxPaintInvalidator_h + +#include "platform/graphics/PaintInvalidationReason.h" +#include "wtf/Allocator.h" + +namespace blink { + +class LayoutBox; +class LayoutRect; +class LayoutSize; +struct PaintInvalidatorContext; + +class BoxPaintInvalidator { + STACK_ALLOCATED(); +public: + BoxPaintInvalidator(const LayoutBox& box, const PaintInvalidatorContext& context) + : m_box(box), m_context(context) { } + + static void boxWillBeDestroyed(const LayoutBox&); + + PaintInvalidationReason invalidatePaintIfNeeded(); + +private: + PaintInvalidationReason computePaintInvalidationReason(); + + void incrementallyInvalidatePaint(); + void invalidatePaintRectClippedByOldAndNewBounds(const LayoutRect&); + + bool needsToSavePreviousBoxSizes(); + void savePreviousBoxSizesIfNeeded(); + LayoutSize computePreviousBorderBoxSize(const LayoutSize& previousBoundsSize); + + const LayoutBox& m_box; + const PaintInvalidatorContext& m_context; +}; + +} // namespace blink + +#endif
diff --git a/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp b/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp index 63b6bb9..c1fafc8 100644 --- a/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp +++ b/third_party/WebKit/Source/core/paint/FilterEffectBuilder.cpp
@@ -122,14 +122,14 @@ FloatRect computeReferenceBox(const Element& element, const FloatSize* zoomedReferenceBoxSize, float zoom) { - FloatSize size; + FloatRect box; if (zoomedReferenceBoxSize) { - size = *zoomedReferenceBoxSize; + box = FloatRect(FloatPoint(), *zoomedReferenceBoxSize); } else if (element.isConnected() && element.layoutObject() && element.layoutObject()->enclosingLayer()) { - size = FloatSize(element.layoutObject()->enclosingLayer()->physicalBoundingBoxIncludingReflectionAndStackingChildren(LayoutPoint()).size()); + box = FloatRect(element.layoutObject()->enclosingLayer()->physicalBoundingBoxIncludingReflectionAndStackingChildren(LayoutPoint(), PaintLayer::CalculateBoundsOptions::IncludeTransformsAndCompositedChildLayers)); } - size.scale(1.0f / zoom); - return FloatRect(FloatPoint(), size); + box.scale(1.0f / zoom); + return box; } } // namespace
diff --git a/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetector.cpp b/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetector.cpp new file mode 100644 index 0000000..199788a --- /dev/null +++ b/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetector.cpp
@@ -0,0 +1,115 @@ +// Copyright 2016 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 "core/paint/FirstMeaningfulPaintDetector.h" + +#include "core/css/FontFaceSet.h" +#include "core/fetch/ResourceFetcher.h" +#include "core/paint/PaintTiming.h" + +namespace blink { + +namespace { + +// Web fonts that laid out more than this number of characters block First +// Meaningful Paint. +const int kBlankCharactersThreshold = 200; + +// FirstMeaningfulPaintDetector stops observing layouts and reports First +// Meaningful Paint when this duration passed from last network activity. +const double kSecondsWithoutNetworkActivityThreshold = 2.0; + +} // namespace + +FirstMeaningfulPaintDetector& FirstMeaningfulPaintDetector::from(Document& document) +{ + return PaintTiming::from(document).firstMeaningfulPaintDetector(); +} + +FirstMeaningfulPaintDetector::FirstMeaningfulPaintDetector(PaintTiming* paintTiming) + : m_paintTiming(paintTiming) + , m_networkStableTimer(this, &FirstMeaningfulPaintDetector::networkStableTimerFired) +{ +} + +Document* FirstMeaningfulPaintDetector::document() +{ + return m_paintTiming->document(); +} + +// Computes "layout significance" (http://goo.gl/rytlPL) of a layout operation. +// Significance of a layout is the number of layout objects newly added to the +// layout tree, weighted by page height (before and after the layout). +// A paint after the most significance layout during page load is reported as +// First Meaningful Paint. +void FirstMeaningfulPaintDetector::markNextPaintAsMeaningfulIfNeeded( + const LayoutObjectCounter& counter, int contentsHeightBeforeLayout, + int contentsHeightAfterLayout, int visibleHeight) +{ + if (m_state == Reported) + return; + + unsigned delta = counter.count() - m_prevLayoutObjectCount; + m_prevLayoutObjectCount = counter.count(); + + if (visibleHeight == 0) + return; + + double ratioBefore = std::max(1.0, static_cast<double>(contentsHeightBeforeLayout) / visibleHeight); + double ratioAfter = std::max(1.0, static_cast<double>(contentsHeightAfterLayout) / visibleHeight); + double significance = delta / ((ratioBefore + ratioAfter) / 2); + + // If the page has many blank characters, the significance value is + // accumulated until the text become visible. + int approximateBlankCharacterCount = FontFaceSet::approximateBlankCharacterCount(*document()); + if (approximateBlankCharacterCount > kBlankCharactersThreshold) { + m_accumulatedSignificanceWhileHavingBlankText += significance; + } else { + significance += m_accumulatedSignificanceWhileHavingBlankText; + m_accumulatedSignificanceWhileHavingBlankText = 0; + if (significance > m_maxSignificanceSoFar) { + m_state = NextPaintIsMeaningful; + m_maxSignificanceSoFar = significance; + } + } +} + +void FirstMeaningfulPaintDetector::notifyPaint() +{ + if (m_state != NextPaintIsMeaningful) + return; + + // Skip document background-only paints. + if (m_paintTiming->firstPaint() == 0.0) + return; + + m_provisionalFirstMeaningfulPaint = monotonicallyIncreasingTime(); + m_state = NextPaintIsNotMeaningful; +} + +void FirstMeaningfulPaintDetector::checkNetworkStable() +{ + DCHECK(document()); + if (m_state == Reported || document()->fetcher()->hasPendingRequest()) + return; + + m_networkStableTimer.startOneShot(kSecondsWithoutNetworkActivityThreshold, BLINK_FROM_HERE); +} + +void FirstMeaningfulPaintDetector::networkStableTimerFired(TimerBase*) +{ + if (m_state == Reported || !document() || document()->fetcher()->hasPendingRequest()) + return; + + if (m_provisionalFirstMeaningfulPaint) + m_paintTiming->setFirstMeaningfulPaint(m_provisionalFirstMeaningfulPaint); + m_state = Reported; +} + +DEFINE_TRACE(FirstMeaningfulPaintDetector) +{ + visitor->trace(m_paintTiming); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetector.h b/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetector.h new file mode 100644 index 0000000..6980a5c --- /dev/null +++ b/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetector.h
@@ -0,0 +1,67 @@ +// Copyright 2016 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 FirstMeaningfulPaintDetector_h +#define FirstMeaningfulPaintDetector_h + +#include "core/CoreExport.h" +#include "platform/Timer.h" +#include "platform/heap/Handle.h" +#include "wtf/Noncopyable.h" + +namespace blink { + +class Document; +class PaintTiming; + +// FirstMeaningfulPaintDetector observes layout operations during page load +// until network stable (2 seconds of no network activity), and computes the +// layout-based First Meaningful Paint. +// See https://goo.gl/vpaxv6 and http://goo.gl/TEiMi4 for more details. +class CORE_EXPORT FirstMeaningfulPaintDetector : public GarbageCollectedFinalized<FirstMeaningfulPaintDetector> { + WTF_MAKE_NONCOPYABLE(FirstMeaningfulPaintDetector); +public: + // Used by FrameView to keep track of the number of layout objects created + // in the frame. + class LayoutObjectCounter { + public: + void reset() { m_count = 0; } + void increment() { m_count++; } + unsigned count() const { return m_count; } + private: + unsigned m_count = 0; + }; + + static FirstMeaningfulPaintDetector& from(Document&); + + FirstMeaningfulPaintDetector(PaintTiming*); + virtual ~FirstMeaningfulPaintDetector() { } + + void markNextPaintAsMeaningfulIfNeeded(const LayoutObjectCounter&, + int contentsHeightBeforeLayout, int contentsHeightAfterLayout, int visibleHeight); + void notifyPaint(); + void checkNetworkStable(); + + DECLARE_TRACE(); + +private: + friend class FirstMeaningfulPaintDetectorTest; + + Document* document(); + void networkStableTimerFired(TimerBase*); + + enum State { NextPaintIsNotMeaningful, NextPaintIsMeaningful, Reported }; + State m_state = NextPaintIsNotMeaningful; + + Member<PaintTiming> m_paintTiming; + double m_provisionalFirstMeaningfulPaint = 0.0; + double m_maxSignificanceSoFar = 0.0; + double m_accumulatedSignificanceWhileHavingBlankText = 0.0; + unsigned m_prevLayoutObjectCount = 0; + Timer<FirstMeaningfulPaintDetector> m_networkStableTimer; +}; + +} // namespace blink + +#endif
diff --git a/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetectorTest.cpp b/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetectorTest.cpp new file mode 100644 index 0000000..2dce61d --- /dev/null +++ b/third_party/WebKit/Source/core/paint/FirstMeaningfulPaintDetectorTest.cpp
@@ -0,0 +1,101 @@ +// Copyright 2016 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 "core/paint/FirstMeaningfulPaintDetector.h" + +#include "core/paint/PaintTiming.h" +#include "core/testing/DummyPageHolder.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +class FirstMeaningfulPaintDetectorTest : public testing::Test { +protected: + void SetUp() override + { + m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600)); + s_timeElapsed = 0.0; + m_originalTimeFunction = setTimeFunctionsForTesting(returnMockTime); + } + + void TearDown() override + { + setTimeFunctionsForTesting(m_originalTimeFunction); + } + + Document& document() { return m_dummyPageHolder->document(); } + PaintTiming& paintTiming() { return PaintTiming::from(document()); } + FirstMeaningfulPaintDetector& detector() { return paintTiming().firstMeaningfulPaintDetector(); } + + void simulateLayoutAndPaint(int newElements) + { + StringBuilder builder; + for (int i = 0; i < newElements; i++) + builder.append("<span>a</span>"); + document().write(builder.toString()); + document().updateStyleAndLayout(); + detector().notifyPaint(); + } + + void simulateNetworkStable() + { + detector().networkStableTimerFired(nullptr); + } + +private: + static double returnMockTime() + { + s_timeElapsed += 1.0; + return s_timeElapsed; + } + + std::unique_ptr<DummyPageHolder> m_dummyPageHolder; + TimeFunction m_originalTimeFunction; + static double s_timeElapsed; +}; + +double FirstMeaningfulPaintDetectorTest::s_timeElapsed; + +TEST_F(FirstMeaningfulPaintDetectorTest, NoFirstPaint) +{ + simulateLayoutAndPaint(1); + simulateNetworkStable(); + EXPECT_EQ(paintTiming().firstMeaningfulPaint(), 0.0); +} + +TEST_F(FirstMeaningfulPaintDetectorTest, OneLayout) +{ + paintTiming().markFirstPaint(); + simulateLayoutAndPaint(1); + double afterPaint = monotonicallyIncreasingTime(); + EXPECT_EQ(paintTiming().firstMeaningfulPaint(), 0.0); + simulateNetworkStable(); + EXPECT_GT(paintTiming().firstMeaningfulPaint(), paintTiming().firstPaint()); + EXPECT_LT(paintTiming().firstMeaningfulPaint(), afterPaint); +} + +TEST_F(FirstMeaningfulPaintDetectorTest, TwoLayoutsSignificantSecond) +{ + paintTiming().markFirstPaint(); + simulateLayoutAndPaint(1); + double afterLayout1 = monotonicallyIncreasingTime(); + simulateLayoutAndPaint(10); + double afterLayout2 = monotonicallyIncreasingTime(); + simulateNetworkStable(); + EXPECT_GT(paintTiming().firstMeaningfulPaint(), afterLayout1); + EXPECT_LT(paintTiming().firstMeaningfulPaint(), afterLayout2); +} + +TEST_F(FirstMeaningfulPaintDetectorTest, TwoLayoutsSignificantFirst) +{ + paintTiming().markFirstPaint(); + simulateLayoutAndPaint(10); + double afterLayout1 = monotonicallyIncreasingTime(); + simulateLayoutAndPaint(1); + simulateNetworkStable(); + EXPECT_GT(paintTiming().firstMeaningfulPaint(), paintTiming().firstPaint()); + EXPECT_LT(paintTiming().firstMeaningfulPaint(), afterLayout1); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/FramePainter.cpp b/third_party/WebKit/Source/core/paint/FramePainter.cpp index d03f1e6..6198b01 100644 --- a/third_party/WebKit/Source/core/paint/FramePainter.cpp +++ b/third_party/WebKit/Source/core/paint/FramePainter.cpp
@@ -109,7 +109,7 @@ // by the svg root issue (crbug.com/442939). ASSERT(document->lifecycle().state() >= DocumentLifecycle::CompositingClean); - TRACE_EVENT1("devtools.timeline", "Paint", "data", InspectorPaintEvent::data(layoutView, LayoutRect(rect), 0)); + TRACE_EVENT1("devtools.timeline,rail", "Paint", "data", InspectorPaintEvent::data(layoutView, LayoutRect(rect), 0)); bool isTopLevelPainter = !s_inPaintContents; s_inPaintContents = true;
diff --git a/third_party/WebKit/Source/core/paint/HTMLCanvasPaintInvalidator.cpp b/third_party/WebKit/Source/core/paint/HTMLCanvasPaintInvalidator.cpp new file mode 100644 index 0000000..c317802d --- /dev/null +++ b/third_party/WebKit/Source/core/paint/HTMLCanvasPaintInvalidator.cpp
@@ -0,0 +1,28 @@ +// Copyright 2016 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 "core/paint/HTMLCanvasPaintInvalidator.h" + +#include "core/html/HTMLCanvasElement.h" +#include "core/layout/LayoutHTMLCanvas.h" +#include "core/paint/BoxPaintInvalidator.h" +#include "core/paint/PaintInvalidator.h" + +namespace blink { + +PaintInvalidationReason HTMLCanvasPaintInvalidator::invalidatePaintIfNeeded() +{ + PaintInvalidationReason reason = BoxPaintInvalidator(m_htmlCanvas, m_context).invalidatePaintIfNeeded(); + + HTMLCanvasElement* element = toHTMLCanvasElement(m_htmlCanvas.node()); + if (element->isDirty()) { + element->doDeferredPaintInvalidation(); + if (reason < PaintInvalidationRectangle) + reason = PaintInvalidationRectangle; + } + + return reason; +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/HTMLCanvasPaintInvalidator.h b/third_party/WebKit/Source/core/paint/HTMLCanvasPaintInvalidator.h new file mode 100644 index 0000000..ac4f7fb --- /dev/null +++ b/third_party/WebKit/Source/core/paint/HTMLCanvasPaintInvalidator.h
@@ -0,0 +1,31 @@ +// Copyright 2016 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 HTMLCanvasPaintInvalidator_h +#define HTMLCanvasPaintInvalidator_h + +#include "platform/graphics/PaintInvalidationReason.h" +#include "wtf/Allocator.h" + +namespace blink { + +class LayoutHTMLCanvas; +struct PaintInvalidatorContext; + +class HTMLCanvasPaintInvalidator { + STACK_ALLOCATED(); +public: + HTMLCanvasPaintInvalidator(const LayoutHTMLCanvas& htmlCanvas, const PaintInvalidatorContext& context) + : m_htmlCanvas(htmlCanvas), m_context(context) { } + + PaintInvalidationReason invalidatePaintIfNeeded(); + +private: + const LayoutHTMLCanvas& m_htmlCanvas; + const PaintInvalidatorContext& m_context; +}; + +} // namespace blink + +#endif
diff --git a/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp b/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp index 5b9d362..9e74d887 100644 --- a/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp +++ b/third_party/WebKit/Source/core/paint/InlineTextBoxPainter.cpp
@@ -777,18 +777,23 @@ unsigned paintStart = underlinePaintStart(underline); unsigned paintEnd = underlinePaintEnd(underline); - // TODO(crbug.com/636060): Handle mixed-flow contexts correctly. // start of line to draw float start = paintStart == static_cast<unsigned>(m_inlineTextBox.start()) ? 0 : m_inlineTextBox.getLineLayoutItem().width(m_inlineTextBox.start(), paintStart - m_inlineTextBox.start(), m_inlineTextBox.textPos(), m_inlineTextBox.isLeftToRightDirection() ? LTR : RTL, m_inlineTextBox.isFirstLineStyle()); // how much line to draw - float width = (paintStart == static_cast<unsigned>(m_inlineTextBox.start()) && paintEnd == static_cast<unsigned>(m_inlineTextBox.end()) + 1) ? m_inlineTextBox.logicalWidth().toFloat() : - m_inlineTextBox.getLineLayoutItem().width(paintStart, paintEnd - paintStart, LayoutUnit(m_inlineTextBox.textPos() + start), m_inlineTextBox.isLeftToRightDirection() ? LTR : RTL, m_inlineTextBox.isFirstLineStyle()); + float width; + bool ltr = m_inlineTextBox.isLeftToRightDirection(); + bool flowIsLTR = m_inlineTextBox.getLineLayoutItem().style()->isLeftToRightDirection(); + if (paintStart == static_cast<unsigned>(m_inlineTextBox.start()) && paintEnd == static_cast<unsigned>(m_inlineTextBox.end()) + 1) { + width = m_inlineTextBox.logicalWidth().toFloat(); + } else { + width = m_inlineTextBox.getLineLayoutItem().width(ltr == flowIsLTR ? paintStart : paintEnd, ltr == flowIsLTR ? paintEnd - paintStart : m_inlineTextBox.len() - paintEnd, LayoutUnit(m_inlineTextBox.textPos() + start), flowIsLTR ? LTR : RTL, m_inlineTextBox.isFirstLineStyle()); + } // In RTL mode, start and width are computed from the right end of the text box: // starting at |logicalWidth| - |start| and continuing left by |width| to // |logicalWidth| - |start| - |width|. We will draw that line, but // backwards: |logicalWidth| - |start| - |width| to |logicalWidth| - |start|. - if (!m_inlineTextBox.isLeftToRightDirection()) + if (!flowIsLTR) start = m_inlineTextBox.logicalWidth().toFloat() - width - start;
diff --git a/third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp b/third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp new file mode 100644 index 0000000..9b3e8de --- /dev/null +++ b/third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.cpp
@@ -0,0 +1,187 @@ +// Copyright 2016 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 "core/paint/ObjectPaintInvalidator.h" + +#include "core/layout/LayoutBlockFlow.h" +#include "core/paint/PaintInvalidator.h" +#include "core/paint/PaintLayer.h" + +namespace blink { + +typedef HashMap<const LayoutObject*, LayoutRect> SelectionPaintInvalidationMap; +static SelectionPaintInvalidationMap& selectionPaintInvalidationMap() +{ + DEFINE_STATIC_LOCAL(SelectionPaintInvalidationMap, map, ()); + return map; +} + +static void setPreviousSelectionPaintInvalidationRect(const LayoutObject& object, const LayoutRect& rect) +{ + if (rect.isEmpty()) + selectionPaintInvalidationMap().remove(&object); + else + selectionPaintInvalidationMap().set(&object, rect); +} + +void ObjectPaintInvalidator::objectWillBeDestroyed(const LayoutObject& object) +{ + selectionPaintInvalidationMap().remove(&object); +} + +void ObjectPaintInvalidator::incrementallyInvalidatePaint() +{ + const LayoutRect& oldBounds = m_context.oldBounds; + const LayoutRect& newBounds = m_context.newBounds; + + DCHECK(oldBounds.location() == newBounds.location()); + + LayoutUnit deltaRight = newBounds.maxX() - oldBounds.maxX(); + if (deltaRight > 0) { + LayoutRect invalidationRect(oldBounds.maxX(), newBounds.y(), deltaRight, newBounds.height()); + m_object.invalidatePaintUsingContainer(*m_context.paintInvalidationContainer, invalidationRect, PaintInvalidationIncremental); + } else if (deltaRight < 0) { + LayoutRect invalidationRect(newBounds.maxX(), oldBounds.y(), -deltaRight, oldBounds.height()); + m_object.invalidatePaintUsingContainer(*m_context.paintInvalidationContainer, invalidationRect, PaintInvalidationIncremental); + } + + LayoutUnit deltaBottom = newBounds.maxY() - oldBounds.maxY(); + if (deltaBottom > 0) { + LayoutRect invalidationRect(newBounds.x(), oldBounds.maxY(), newBounds.width(), deltaBottom); + m_object.invalidatePaintUsingContainer(*m_context.paintInvalidationContainer, invalidationRect, PaintInvalidationIncremental); + } else if (deltaBottom < 0) { + LayoutRect invalidationRect(oldBounds.x(), newBounds.maxY(), oldBounds.width(), -deltaBottom); + m_object.invalidatePaintUsingContainer(*m_context.paintInvalidationContainer, invalidationRect, PaintInvalidationIncremental); + } +} + +void ObjectPaintInvalidator::fullyInvalidatePaint(PaintInvalidationReason reason, const LayoutRect& oldBounds, const LayoutRect& newBounds) +{ + // The following logic avoids invalidating twice if one set of bounds contains the other. + if (!newBounds.contains(oldBounds)) { + LayoutRect invalidationRect = oldBounds; + m_object.invalidatePaintUsingContainer(*m_context.paintInvalidationContainer, invalidationRect, reason); + + if (invalidationRect.contains(newBounds)) + return; + } + + m_object.invalidatePaintUsingContainer(*m_context.paintInvalidationContainer, newBounds, reason); +} + +PaintInvalidationReason ObjectPaintInvalidator::computePaintInvalidationReason() +{ + // This is before any early return to ensure the background obscuration status is saved. + bool backgroundObscurationChanged = false; + bool backgroundObscured = m_object.backgroundIsKnownToBeObscured(); + if (backgroundObscured != m_object.previousBackgroundObscured()) { + m_object.getMutableForPainting().setPreviousBackgroundObscured(backgroundObscured); + backgroundObscurationChanged = true; + } + + if (m_context.forcedSubtreeInvalidationFlags & PaintInvalidatorContext::ForcedSubtreeFullInvalidation) + return PaintInvalidationSubtree; + + if (m_object.shouldDoFullPaintInvalidation()) + return m_object.fullPaintInvalidationReason(); + + if (backgroundObscurationChanged) + return PaintInvalidationBackgroundObscurationChange; + + if (m_object.paintedOutputOfObjectHasNoEffect()) + return PaintInvalidationNone; + + const ComputedStyle& style = m_object.styleRef(); + + // The outline may change shape because of position change of descendants. For simplicity, + // just force full paint invalidation if this object is marked for checking paint invalidation + // for any reason. + // TODO(wangxianzhu): Optimize this. + if (style.hasOutline()) + return PaintInvalidationOutline; + + bool locationChanged = m_context.newLocation != m_context.oldLocation; + + // If the bounds are the same then we know that none of the statements below + // can match, so we can early out. + if (m_context.oldBounds == m_context.newBounds) + return locationChanged && !m_context.oldBounds.isEmpty() ? PaintInvalidationLocationChange : PaintInvalidationNone; + + // If we shifted, we don't know the exact reason so we are conservative and trigger a full invalidation. Shifting could + // be caused by some layout property (left / top) or some in-flow layoutObject inserted / removed before us in the tree. + if (m_context.newBounds.location() != m_context.oldBounds.location()) + return PaintInvalidationBoundsChange; + + // If the size is zero on one of our bounds then we know we're going to have + // to do a full invalidation of either old bounds or new bounds. + if (m_context.oldBounds.isEmpty()) + return PaintInvalidationBecameVisible; + if (m_context.newBounds.isEmpty()) + return PaintInvalidationBecameInvisible; + + if (locationChanged) + return PaintInvalidationLocationChange; + + return PaintInvalidationIncremental; +} + +void ObjectPaintInvalidator::invalidateSelectionIfNeeded(PaintInvalidationReason reason) +{ + // Update selection rect when we are doing full invalidation (in case that the object is moved, + // composite status changed, etc.) or shouldInvalidationSelection is set (in case that the + // selection itself changed). + bool fullInvalidation = isFullPaintInvalidationReason(reason); + if (!fullInvalidation && !m_object.shouldInvalidateSelection()) + return; + + LayoutRect oldSelectionRect = selectionPaintInvalidationMap().get(&m_object); + LayoutRect newSelectionRect = m_object.localSelectionRect(); + if (!newSelectionRect.isEmpty()) + m_context.mapLocalRectToPaintInvalidationBacking(m_object, newSelectionRect); + + newSelectionRect.move(m_object.scrollAdjustmentForPaintInvalidation(*m_context.paintInvalidationContainer)); + + setPreviousSelectionPaintInvalidationRect(m_object, newSelectionRect); + + if (!fullInvalidation) { + fullyInvalidatePaint(PaintInvalidationSelection, oldSelectionRect, newSelectionRect); + m_context.paintingLayer->setNeedsRepaint(); + m_object.invalidateDisplayItemClients(PaintInvalidationSelection); + } +} + +PaintInvalidationReason ObjectPaintInvalidator::invalidatePaintIfNeededWithComputedReason(PaintInvalidationReason reason) +{ + // We need to invalidate the selection before checking for whether we are doing a full invalidation. + // This is because we need to update the previous selection rect regardless. + invalidateSelectionIfNeeded(reason); + + switch (reason) { + case PaintInvalidationNone: + // TODO(trchen): Currently we don't keep track of paint offset of layout objects. + // There are corner cases that the display items need to be invalidated for paint offset + // mutation, but incurs no pixel difference (i.e. bounds stay the same) so no rect-based + // invalidation is issued. See crbug.com/508383 and crbug.com/515977. + // This is a workaround to force display items to update paint offset. + if (m_context.forcedSubtreeInvalidationFlags & PaintInvalidatorContext::ForcedSubtreeInvalidationChecking) { + reason = PaintInvalidationLocationChange; + break; + } + return PaintInvalidationNone; + case PaintInvalidationIncremental: + incrementallyInvalidatePaint(); + break; + case PaintInvalidationDelayedFull: + return PaintInvalidationDelayedFull; + default: + DCHECK(isFullPaintInvalidationReason(reason)); + fullyInvalidatePaint(reason, m_context.oldBounds, m_context.newBounds); + } + + m_context.paintingLayer->setNeedsRepaint(); + m_object.invalidateDisplayItemClients(reason); + return reason; +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.h b/third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.h new file mode 100644 index 0000000..d13d195f --- /dev/null +++ b/third_party/WebKit/Source/core/paint/ObjectPaintInvalidator.h
@@ -0,0 +1,50 @@ +// Copyright 2016 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 ObjectPaintInvalidator_h +#define ObjectPaintInvalidator_h + +#include "platform/graphics/PaintInvalidationReason.h" +#include "wtf/Allocator.h" + +namespace blink { + +class LayoutObject; +class LayoutRect; +struct PaintInvalidatorContext; + +class ObjectPaintInvalidator { + STACK_ALLOCATED(); +public: + ObjectPaintInvalidator(const LayoutObject& object, const PaintInvalidatorContext& context) + : m_object(object), m_context(context) { } + + static void objectWillBeDestroyed(const LayoutObject&); + + PaintInvalidationReason invalidatePaintIfNeeded() { return invalidatePaintIfNeededWithComputedReason(computePaintInvalidationReason()); } + + PaintInvalidationReason computePaintInvalidationReason(); + PaintInvalidationReason invalidatePaintIfNeededWithComputedReason(PaintInvalidationReason); + +private: + void invalidateSelectionIfNeeded(PaintInvalidationReason); + + // This function tries to minimize the amount of invalidation generated by invalidating the "difference" between + // |m_context.oldBounds| and |m_context.newBounds|. This means invalidating the union of the previous rectangles + // but not their intersection. The use case is when an element only requires a paint invalidation (which means + // that its content didn't change) and its bounds changed but its location didn't. + // If we don't meet the criteria for an incremental paint, the alternative is a full paint invalidation. + void incrementallyInvalidatePaint(); + + // This function generates a full invalidation, which means invalidating both |oldBounds| and |newBounds|. + // This is the default choice when generating an invalidation, as it is always correct, albeit it may force some extra painting. + void fullyInvalidatePaint(PaintInvalidationReason, const LayoutRect& oldBounds, const LayoutRect& newBounds); + + const LayoutObject& m_object; + const PaintInvalidatorContext& m_context; +}; + +} // namespace blink + +#endif
diff --git a/third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.cpp index e552529..b651257 100644 --- a/third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.cpp +++ b/third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.cpp
@@ -9,7 +9,7 @@ #include "core/layout/LayoutBox.h" #include "core/layout/LayoutScrollbar.h" #include "core/layout/LayoutScrollbarPart.h" -#include "core/layout/PaintInvalidationState.h" +#include "core/paint/PaintInvalidator.h" #include "core/paint/PaintLayer.h" #include "platform/graphics/GraphicsLayer.h" @@ -24,11 +24,11 @@ ScrollableArea::willRemoveScrollbar(scrollbar, orientation); } -static LayoutRect scrollControlPaintInvalidationRect(const IntRect& scrollControlRect, const LayoutBox& box, const PaintInvalidationState& paintInvalidationState) +static LayoutRect scrollControlPaintInvalidationRect(const IntRect& scrollControlRect, const LayoutBox& box, const PaintInvalidatorContext& context) { LayoutRect paintInvalidationRect(scrollControlRect); if (!paintInvalidationRect.isEmpty()) - paintInvalidationState.mapLocalRectToPaintInvalidationBacking(paintInvalidationRect); + context.mapLocalRectToPaintInvalidationBacking(box, paintInvalidationRect); return paintInvalidationRect; } @@ -47,14 +47,14 @@ return false; } -static void invalidatePaintOfScrollbarIfNeeded(Scrollbar* scrollbar, GraphicsLayer* graphicsLayer, bool& previouslyWasOverlay, LayoutRect& previousPaintInvalidationRect, bool needsPaintInvalidationArg, LayoutBox& box, const PaintInvalidationState& paintInvalidationState) +static void invalidatePaintOfScrollbarIfNeeded(Scrollbar* scrollbar, GraphicsLayer* graphicsLayer, bool& previouslyWasOverlay, LayoutRect& previousPaintInvalidationRect, bool needsPaintInvalidationArg, LayoutBox& box, const PaintInvalidatorContext& context) { bool isOverlay = scrollbar && scrollbar->isOverlayScrollbar(); // Calculate paint invalidation rect of the scrollbar, except overlay composited scrollbars because we invalidate the graphics layer only. LayoutRect newPaintInvalidationRect; if (scrollbar && !(graphicsLayer && isOverlay)) - newPaintInvalidationRect = scrollControlPaintInvalidationRect(scrollbar->frameRect(), box, paintInvalidationState); + newPaintInvalidationRect = scrollControlPaintInvalidationRect(scrollbar->frameRect(), box, context); bool needsPaintInvalidation = needsPaintInvalidationArg; if (needsPaintInvalidation && graphicsLayer) { @@ -73,15 +73,17 @@ // scrollbar width change, which may have some false-positives (e.g. the scrollbar changed length but // not width) but won't invalidate more than expected because in the false-positive case the box must // have changed size and have been invalidated. - const LayoutBoxModelObject& paintInvalidationContainer = paintInvalidationState.paintInvalidationContainer(); + const LayoutBoxModelObject& paintInvalidationContainer = *context.paintInvalidationContainer; LayoutSize newScrollbarUsedSpaceInBox; if (!isOverlay) newScrollbarUsedSpaceInBox = newPaintInvalidationRect.size(); LayoutSize previousScrollbarUsedSpaceInBox; if (!previouslyWasOverlay) previousScrollbarUsedSpaceInBox= previousPaintInvalidationRect.size(); - if (newScrollbarUsedSpaceInBox != previousScrollbarUsedSpaceInBox) - box.setPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient(paintInvalidationState, box, PaintInvalidationScroll); + if (newScrollbarUsedSpaceInBox != previousScrollbarUsedSpaceInBox) { + context.paintingLayer->setNeedsRepaint(); + box.invalidateDisplayItemClient(box, PaintInvalidationScroll); + } bool invalidated = invalidatePaintOfScrollControlIfNeeded(newPaintInvalidationRect, previousPaintInvalidationRect, needsPaintInvalidation, box, paintInvalidationContainer); @@ -91,19 +93,20 @@ if (!invalidated || !scrollbar || graphicsLayer) return; - box.setPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient(paintInvalidationState, *scrollbar, PaintInvalidationScroll); + context.paintingLayer->setNeedsRepaint(); + box.invalidateDisplayItemClient(*scrollbar, PaintInvalidationScroll); if (scrollbar->isCustomScrollbar()) toLayoutScrollbar(scrollbar)->invalidateDisplayItemClientsOfScrollbarParts(); } -void PaintInvalidationCapableScrollableArea::invalidatePaintOfScrollControlsIfNeeded(const PaintInvalidationState& paintInvalidationState) +void PaintInvalidationCapableScrollableArea::invalidatePaintOfScrollControlsIfNeeded(const PaintInvalidatorContext& context) { LayoutBox& box = *layoutBox(); - invalidatePaintOfScrollbarIfNeeded(horizontalScrollbar(), layerForHorizontalScrollbar(), m_horizontalScrollbarPreviouslyWasOverlay, m_horizontalScrollbarPreviousPaintInvalidationRect, horizontalScrollbarNeedsPaintInvalidation(), box, paintInvalidationState); - invalidatePaintOfScrollbarIfNeeded(verticalScrollbar(), layerForVerticalScrollbar(), m_verticalScrollbarPreviouslyWasOverlay, m_verticalScrollbarPreviousPaintInvalidationRect, verticalScrollbarNeedsPaintInvalidation(), box, paintInvalidationState); + invalidatePaintOfScrollbarIfNeeded(horizontalScrollbar(), layerForHorizontalScrollbar(), m_horizontalScrollbarPreviouslyWasOverlay, m_horizontalScrollbarPreviousPaintInvalidationRect, horizontalScrollbarNeedsPaintInvalidation(), box, context); + invalidatePaintOfScrollbarIfNeeded(verticalScrollbar(), layerForVerticalScrollbar(), m_verticalScrollbarPreviouslyWasOverlay, m_verticalScrollbarPreviousPaintInvalidationRect, verticalScrollbarNeedsPaintInvalidation(), box, context); - LayoutRect scrollCornerPaintInvalidationRect = scrollControlPaintInvalidationRect(scrollCornerAndResizerRect(), box, paintInvalidationState); - const LayoutBoxModelObject& paintInvalidationContainer = paintInvalidationState.paintInvalidationContainer(); + LayoutRect scrollCornerPaintInvalidationRect = scrollControlPaintInvalidationRect(scrollCornerAndResizerRect(), box, context); + const LayoutBoxModelObject& paintInvalidationContainer = *context.paintInvalidationContainer; if (invalidatePaintOfScrollControlIfNeeded(scrollCornerPaintInvalidationRect, m_scrollCornerAndResizerPreviousPaintInvalidationRect, scrollCornerNeedsPaintInvalidation(), box, paintInvalidationContainer)) { m_scrollCornerAndResizerPreviousPaintInvalidationRect = scrollCornerPaintInvalidationRect; if (LayoutScrollbarPart* scrollCorner = this->scrollCorner()) @@ -115,6 +118,11 @@ clearNeedsPaintInvalidationForScrollControls(); } +void PaintInvalidationCapableScrollableArea::invalidatePaintOfScrollControlsIfNeeded(const PaintInvalidationState& paintInvalidationState) +{ + invalidatePaintOfScrollControlsIfNeeded(PaintInvalidatorContextAdapter(paintInvalidationState)); +} + void PaintInvalidationCapableScrollableArea::clearPreviousPaintInvalidationRects() { m_horizontalScrollbarPreviousPaintInvalidationRect = LayoutRect();
diff --git a/third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.h b/third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.h index 4ef4a25..ba6be66 100644 --- a/third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.h +++ b/third_party/WebKit/Source/core/paint/PaintInvalidationCapableScrollableArea.h
@@ -16,6 +16,7 @@ class LayoutScrollbarPart; class PaintInvalidationContainer; class PaintInvalidationState; +struct PaintInvalidatorContext; // Base class of FrameView and PaintLayerScrollableArea to share paint invalidation code. // TODO(wangxianzhu): Combine this into PaintLayerScrollableArea when root-layer-scrolls launches. @@ -28,6 +29,7 @@ void willRemoveScrollbar(Scrollbar&, ScrollbarOrientation) override; void invalidatePaintOfScrollControlsIfNeeded(const PaintInvalidationState&); + void invalidatePaintOfScrollControlsIfNeeded(const PaintInvalidatorContext&); // Should be called when the previous paint invalidation rects are no longer valid. void clearPreviousPaintInvalidationRects();
diff --git a/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp b/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp index 2edd221a..f5c3267 100644 --- a/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp +++ b/third_party/WebKit/Source/core/paint/PaintInvalidator.cpp
@@ -4,37 +4,221 @@ #include "core/paint/PaintInvalidator.h" +#include "core/editing/FrameSelection.h" #include "core/frame/FrameView.h" +#include "core/frame/LocalFrame.h" +#include "core/frame/Settings.h" #include "core/layout/LayoutObject.h" +#include "core/layout/LayoutTable.h" +#include "core/layout/svg/SVGLayoutSupport.h" +#include "core/paint/PaintLayer.h" +#include "core/paint/PaintLayerScrollableArea.h" namespace blink { -void PaintInvalidator::invalidatePaintIfNeeded(FrameView& frameView, const PaintPropertyTreeBuilderContext& treeContext, Optional<PaintInvalidatorContext>& paintInvalidatorContext) +void PaintInvalidatorContext::mapLocalRectToPaintInvalidationBacking(const LayoutObject& object, LayoutRect& rect) const { - paintInvalidatorContext.emplace(*frameView.layoutView(), m_pendingDelayedPaintInvalidations); - frameView.invalidatePaintIfNeeded(*paintInvalidatorContext); + // TODO(wangxianzhu): For now this is the same as the slow path in PaintInvalidationState.cpp + // (slowMapToVisualRectInAncestorSpace()). Should implement this with GeometryMapper. + if (object.isBox()) + toLayoutBox(object).flipForWritingMode(rect); + + if (object.isLayoutView()) + toLayoutView(object).mapToVisualRectInAncestorSpace(paintInvalidationContainer, rect, InputIsInFrameCoordinates, DefaultVisualRectFlags); + else + object.mapToVisualRectInAncestorSpace(paintInvalidationContainer, rect); } -void PaintInvalidator::invalidatePaintIfNeeded(const LayoutObject& layoutObject, const PaintPropertyTreeBuilderContext& treeContext, const PaintInvalidatorContext& parentPaintInvalidatorContext, Optional<PaintInvalidatorContext>& paintInvalidatorContext) +static LayoutRect computePaintInvalidationRectInBacking(const LayoutObject& object, const PaintInvalidatorContext& context) { - if (!layoutObject.shouldCheckForPaintInvalidation(parentPaintInvalidatorContext)) + if (object.isSVG() && !object.isSVGRoot()) { + // TODO(wangxianzhu): For now this is the same as the slow path in PaintInvalidationState.cpp + // (PaintInvalidationState::computePaintInvalidationRectInBackingForSVG()). Should implement this with GeometryMapper. + LayoutRect rect = SVGLayoutSupport::clippedOverflowRectForPaintInvalidation(object, *context.paintInvalidationContainer); + if (context.paintInvalidationContainer->layer()->groupedMapping()) + PaintLayer::mapRectInPaintInvalidationContainerToBacking(*context.paintInvalidationContainer, rect); + return rect; + } + + LayoutRect rect = object.localOverflowRectForPaintInvalidation(); + context.mapLocalRectToPaintInvalidationBacking(object, rect); + return rect; +} + +static LayoutPoint computeLocationFromPaintInvalidationBacking(const LayoutObject& object, const PaintInvalidatorContext& context) +{ + // TODO(wangxianzhu): For now this is the same as the slow path in PaintInvalidationState.cpp + // (slowLocalToAncestorPoint()). Should implement this with GeometryMapper. + FloatPoint point; + if (object != context.paintInvalidationContainer) { + if (object.isLayoutView()) { + point = toLayoutView(object).localToAncestorPoint(point, context.paintInvalidationContainer, TraverseDocumentBoundaries | InputIsInFrameCoordinates); + } else { + point = object.localToAncestorPoint(point, context.paintInvalidationContainer, TraverseDocumentBoundaries); + // Paint invalidation does not include scroll of paintInvalidationContainer. + if (context.paintInvalidationContainer->isBox()) { + const LayoutBox* box = toLayoutBox(context.paintInvalidationContainer); + if (box->hasOverflowClip()) + point.move(box->scrolledContentOffset()); + } + } + } + + + if (context.paintInvalidationContainer->layer()->groupedMapping()) + PaintLayer::mapPointInPaintInvalidationContainerToBacking(*context.paintInvalidationContainer, point); + + return LayoutPoint(point); +} + +static void updatePaintingLayer(const LayoutObject& object, PaintInvalidatorContext& context) +{ + if (object.hasLayer() && toLayoutBoxModelObject(object).hasSelfPaintingLayer()) + context.paintingLayer = toLayoutBoxModelObject(object).layer(); + + if (object.isLayoutBlockFlow() && toLayoutBlockFlow(object).containsFloats()) + context.paintingLayer->setNeedsPaintPhaseFloat(); + + if (object == context.paintingLayer->layoutObject()) return; - paintInvalidatorContext.emplace(parentPaintInvalidatorContext, layoutObject); + if (object.styleRef().hasOutline()) + context.paintingLayer->setNeedsPaintPhaseDescendantOutlines(); - if (layoutObject.mayNeedPaintInvalidationSubtree()) - paintInvalidatorContext->setForceSubtreeInvalidationCheckingWithinContainer(); + if (object.hasBoxDecorationBackground() + // We also paint overflow controls in background phase. + || (object.hasOverflowClip() && toLayoutBox(object).getScrollableArea()->hasOverflowControls())) { + context.paintingLayer->setNeedsPaintPhaseDescendantBlockBackgrounds(); + } - PaintInvalidationReason reason = layoutObject.getMutableForPainting().invalidatePaintIfNeeded(*paintInvalidatorContext); - layoutObject.getMutableForPainting().clearPaintInvalidationFlags(*paintInvalidatorContext); + if (object.isTable()) { + const LayoutTable& table = toLayoutTable(object); + if (table.collapseBorders() && !table.collapsedBorders().isEmpty()) + context.paintingLayer->setNeedsPaintPhaseDescendantBlockBackgrounds(); + } +} - paintInvalidatorContext->updateForChildren(reason); +static void updateContext(const LayoutObject& object, PaintInvalidatorContext& context) +{ + if (object.isPaintInvalidationContainer()) { + context.paintInvalidationContainer = toLayoutBoxModelObject(&object); + if (object.styleRef().isStackingContext()) + context.paintInvalidationContainerForStackedContents = toLayoutBoxModelObject(&object); + } else if (object.isLayoutView()) { + // paintInvalidationContainerForStackedContents is only for stacked descendants in its own frame, + // because it doesn't establish stacking context for stacked contents in sub-frames. + // Contents stacked in the root stacking context in this frame should use this frame's paintInvalidationContainer. + context.paintInvalidationContainerForStackedContents = context.paintInvalidationContainer; + } else if (object.styleRef().isStacked() + // This is to exclude some objects (e.g. LayoutText) inheriting stacked style from parent but aren't actually stacked. + && object.hasLayer() + && context.paintInvalidationContainer != context.paintInvalidationContainerForStackedContents) { + // The current object is stacked, so we should use m_paintInvalidationContainerForStackedContents as its + // paint invalidation container on which the current object is painted. + context.paintInvalidationContainer = context.paintInvalidationContainerForStackedContents; + if (context.forcedSubtreeInvalidationFlags & PaintInvalidatorContext::ForcedSubtreeFullInvalidationForStackedContents) + context.forcedSubtreeInvalidationFlags |= PaintInvalidatorContext::ForcedSubtreeFullInvalidation; + } + + if (object == context.paintInvalidationContainer) { + // When we hit a new paint invalidation container, we don't need to + // continue forcing a check for paint invalidation, since we're + // descending into a different invalidation container. (For instance if + // our parents were moved, the entire container will just move.) + if (object != context.paintInvalidationContainerForStackedContents) { + // However, we need to keep the ForcedSubtreeFullInvalidationForStackedContents flag + // if the current object isn't the paint invalidation container of stacked contents. + context.forcedSubtreeInvalidationFlags &= PaintInvalidatorContext::ForcedSubtreeFullInvalidationForStackedContents; + } else { + context.forcedSubtreeInvalidationFlags = 0; + } + } + + DCHECK(context.paintInvalidationContainer == object.containerForPaintInvalidation()); + DCHECK(context.paintingLayer == object.paintingLayer()); + + if (object.mayNeedPaintInvalidationSubtree()) + context.forcedSubtreeInvalidationFlags |= PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; + + context.oldBounds = object.previousPaintInvalidationRect(); + context.oldLocation = object.previousPositionFromPaintInvalidationBacking(); + context.newBounds = computePaintInvalidationRectInBacking(object, context); + context.newLocation = computeLocationFromPaintInvalidationBacking(object, context); + + IntSize adjustment = object.scrollAdjustmentForPaintInvalidation(*context.paintInvalidationContainer); + context.newLocation.move(adjustment); + context.newBounds.move(adjustment); + + object.getMutableForPainting().setPreviousPaintInvalidationRect(context.newBounds); + object.getMutableForPainting().setPreviousPositionFromPaintInvalidationBacking(context.newLocation); +} + +void PaintInvalidator::invalidatePaintIfNeeded(FrameView& frameView, PaintInvalidatorContext& context) +{ + LayoutView* layoutView = frameView.layoutView(); + CHECK(layoutView); + + context.paintInvalidationContainer = context.paintInvalidationContainerForStackedContents = &layoutView->containerForPaintInvalidation(); + context.paintingLayer = layoutView->layer(); + + if (!frameView.frame().settings() || !frameView.frame().settings()->rootLayerScrolls()) + frameView.invalidatePaintOfScrollControlsIfNeeded(context); + + if (frameView.frame().selection().isCaretBoundsDirty()) + frameView.frame().selection().invalidateCaretRect(); + + // Temporary callback for crbug.com/487345,402044 + // TODO(ojan): Make this more general to be used by PositionObserver + // and rAF throttling. + IntRect visibleRect = frameView.rootFrameToContents(frameView.computeVisibleArea()); + layoutView->sendMediaPositionChangeNotifications(visibleRect); +} + +void PaintInvalidator::invalidatePaintIfNeeded(const LayoutObject& object, PaintInvalidatorContext& context) +{ + object.getMutableForPainting().ensureIsReadyForPaintInvalidation(); + + if (!context.forcedSubtreeInvalidationFlags && !object.shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()) + return; + + updatePaintingLayer(object, context); + + if (object.document().printing()) + return; // Don't invalidate paints if we're printing. + + TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), "PaintInvalidator::invalidatePaintIfNeeded()", "object", object.debugName().ascii()); + + updateContext(object, context); + + if (!object.shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState() && context.forcedSubtreeInvalidationFlags == PaintInvalidatorContext::ForcedSubtreeInvalidationRectUpdate) { + // We are done updating the paint invalidation rect. No other paint invalidation work to do for this object. + return; + } + + switch (object.invalidatePaintIfNeeded(context)) { + case PaintInvalidationDelayedFull: + m_pendingDelayedPaintInvalidations.append(&object); + break; + case PaintInvalidationSubtree: + context.forcedSubtreeInvalidationFlags |= (PaintInvalidatorContext::ForcedSubtreeFullInvalidation | PaintInvalidatorContext::ForcedSubtreeFullInvalidationForStackedContents); + break; + case PaintInvalidationSVGResourceChange: + context.forcedSubtreeInvalidationFlags |= PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; + break; + default: + break; + } + + if (context.oldLocation != context.newLocation) + context.forcedSubtreeInvalidationFlags |= PaintInvalidatorContext::ForcedSubtreeInvalidationChecking; + + object.getMutableForPainting().clearPaintInvalidationFlags(); } void PaintInvalidator::processPendingDelayedPaintInvalidations() { for (auto target : m_pendingDelayedPaintInvalidations) - target->getMutableForPainting().setShouldDoDelayedFullPaintInvalidation(); + target->getMutableForPainting().setShouldDoFullPaintInvalidation(PaintInvalidationDelayedFull); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/PaintInvalidator.h b/third_party/WebKit/Source/core/paint/PaintInvalidator.h index 3edca170..c305541 100644 --- a/third_party/WebKit/Source/core/paint/PaintInvalidator.h +++ b/third_party/WebKit/Source/core/paint/PaintInvalidator.h
@@ -5,24 +5,67 @@ #ifndef PaintInvalidator_h #define PaintInvalidator_h -#include "core/layout/PaintInvalidationState.h" -#include "wtf/Optional.h" +#include "platform/geometry/LayoutRect.h" #include "wtf/Vector.h" namespace blink { class FrameView; +class LayoutBoxModelObject; class LayoutObject; +class PaintLayer; struct PaintPropertyTreeBuilderContext; -// TODO(wangxianzhu): Move applicable PaintInvalidationState code into PaintInvalidator. -using PaintInvalidatorContext = PaintInvalidationState; +struct PaintInvalidatorContext { + PaintInvalidatorContext(const PaintPropertyTreeBuilderContext& treeBuilderContext) + : treeBuilderContext(treeBuilderContext) { } + + PaintInvalidatorContext(const PaintPropertyTreeBuilderContext& treeBuilderContext, const PaintInvalidatorContext& parentContext) + : treeBuilderContext(treeBuilderContext) + , forcedSubtreeInvalidationFlags(parentContext.forcedSubtreeInvalidationFlags) + , paintInvalidationContainer(parentContext.paintInvalidationContainer) + , paintInvalidationContainerForStackedContents(parentContext.paintInvalidationContainerForStackedContents) + , paintingLayer(parentContext.paintingLayer) + { } + + // This method is temporary to adapt PaintInvalidatorContext and the legacy PaintInvalidationState + // for code shared by old code and new code. + virtual void mapLocalRectToPaintInvalidationBacking(const LayoutObject&, LayoutRect&) const; + + const PaintPropertyTreeBuilderContext& treeBuilderContext; + + enum ForcedSubtreeInvalidationFlag { + ForcedSubtreeInvalidationChecking = 1 << 0, + ForcedSubtreeInvalidationRectUpdate = 1 << 1, + ForcedSubtreeFullInvalidation = 1 << 2, + ForcedSubtreeFullInvalidationForStackedContents = 1 << 3, + }; + unsigned forcedSubtreeInvalidationFlags = 0; + + // The following fields can be null only before PaintInvalidator::updateContext(). + + // The current paint invalidation container for normal flow objects. + // It is the enclosing composited object. + const LayoutBoxModelObject* paintInvalidationContainer = nullptr; + + // The current paint invalidation container for stacked contents (stacking contexts or positioned objects). + // It is the nearest ancestor composited object which establishes a stacking context. + // See Source/core/paint/README.md ### PaintInvalidationState for details on how stacked contents' + // paint invalidation containers differ. + const LayoutBoxModelObject* paintInvalidationContainerForStackedContents = nullptr; + + PaintLayer* paintingLayer = nullptr; + + LayoutRect oldBounds; + LayoutRect newBounds; + LayoutPoint oldLocation; + LayoutPoint newLocation; +}; class PaintInvalidator { public: - // TODO(wangxianzhu): Avoid Optional<> by using copy-and-update pattern for PaintInvalidatorContext. - void invalidatePaintIfNeeded(FrameView&, const PaintPropertyTreeBuilderContext&, Optional<PaintInvalidatorContext>&); - void invalidatePaintIfNeeded(const LayoutObject&, const PaintPropertyTreeBuilderContext&, const PaintInvalidatorContext&, Optional<PaintInvalidatorContext>&); + void invalidatePaintIfNeeded(FrameView&, PaintInvalidatorContext&); + void invalidatePaintIfNeeded(const LayoutObject&, PaintInvalidatorContext&); // Process objects needing paint invalidation on the next frame. // See the definition of PaintInvalidationDelayedFull for more details.
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.cpp b/third_party/WebKit/Source/core/paint/PaintLayer.cpp index 23c1b04d..e5e5c68 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayer.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayer.cpp
@@ -2168,7 +2168,7 @@ return false; } -static void expandRectForReflectionAndStackingChildren(const PaintLayer* ancestorLayer, LayoutRect& result) +static void expandRectForReflectionAndStackingChildren(const PaintLayer* ancestorLayer, LayoutRect& result, PaintLayer::CalculateBoundsOptions options) { if (ancestorLayer->reflectionInfo() && !ancestorLayer->reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping() && !RuntimeEnabledFeatures::cssBoxReflectFilterEnabled()) result.unite(ancestorLayer->reflectionInfo()->reflectionLayer()->boundingBoxForCompositing(ancestorLayer)); @@ -2186,19 +2186,19 @@ // for this Layer. For example, the bounds of squashed Layers // will be included in the computation of the appropriate squashing // GraphicsLayer. - if (node->layer()->compositingState() != NotComposited) + if (options != PaintLayer::CalculateBoundsOptions::IncludeTransformsAndCompositedChildLayers && node->layer()->compositingState() != NotComposited) continue; - result.unite(node->layer()->boundingBoxForCompositing(ancestorLayer)); + result.unite(node->layer()->boundingBoxForCompositing(ancestorLayer, options)); } } -LayoutRect PaintLayer::physicalBoundingBoxIncludingReflectionAndStackingChildren(const LayoutPoint& offsetFromRoot) const +LayoutRect PaintLayer::physicalBoundingBoxIncludingReflectionAndStackingChildren(const LayoutPoint& offsetFromRoot, CalculateBoundsOptions options) const { LayoutRect result = physicalBoundingBox(LayoutPoint()); const_cast<PaintLayer*>(this)->stackingNode()->updateLayerListsIfNeeded(); - expandRectForReflectionAndStackingChildren(this, result); + expandRectForReflectionAndStackingChildren(this, result, options); result.moveBy(offsetFromRoot); return result; @@ -2242,9 +2242,9 @@ // children of the parent, that need to be included in reflected composited bounds. // Fix this by including composited bounds of stacking children of the reflected Layer. if (hasCompositedLayerMapping() && parent() && parent()->reflectionInfo() && parent()->reflectionInfo()->reflectionLayer() == this) - expandRectForReflectionAndStackingChildren(parent(), result); + expandRectForReflectionAndStackingChildren(parent(), result, options); else - expandRectForReflectionAndStackingChildren(this, result); + expandRectForReflectionAndStackingChildren(this, result, options); // Only enlarge by the filter outsets if we know the filter is going to be rendered in software. // Accelerated filters will handle their own outsets. @@ -2252,7 +2252,7 @@ result = mapLayoutRectForFilter(result); } - if (transform() && paintsWithTransform(GlobalPaintNormalPhase) && (this != ancestorLayer || options == MaybeIncludeTransformForAncestorLayer)) + if (transform() && (options == IncludeTransformsAndCompositedChildLayers || ((paintsWithTransform(GlobalPaintNormalPhase) && (this != ancestorLayer || options == MaybeIncludeTransformForAncestorLayer))))) result = transform()->mapRect(result); if (shouldFragmentCompositedBounds(ancestorLayer)) { @@ -2414,7 +2414,7 @@ // We can't consult child layers if we clip, since they might cover // parts of the rect that are clipped out. - if (layoutObject()->hasOverflowClip() || layoutObject()->style()->containsPaint()) + if (layoutObject()->hasClipRelatedProperty()) return false; return childBackgroundIsKnownToBeOpaqueInRect(localRect);
diff --git a/third_party/WebKit/Source/core/paint/PaintLayer.h b/third_party/WebKit/Source/core/paint/PaintLayer.h index 469fe78..7cab7a2f 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayer.h +++ b/third_party/WebKit/Source/core/paint/PaintLayer.h
@@ -355,10 +355,18 @@ bool intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const LayoutPoint& offsetFromRoot) const; + // MaybeIncludeTransformForAncestorLayer means that a transform on |ancestorLayer| may be applied to the bounding box, + // in particular if paintsWithTransform() is true. + enum CalculateBoundsOptions { + MaybeIncludeTransformForAncestorLayer, + NeverIncludeTransformForAncestorLayer, + IncludeTransformsAndCompositedChildLayers, + }; + // Bounding box relative to some ancestor layer. Pass offsetFromRoot if known. LayoutRect physicalBoundingBox(const LayoutPoint& offsetFromRoot) const; LayoutRect physicalBoundingBox(const PaintLayer* ancestorLayer) const; - LayoutRect physicalBoundingBoxIncludingReflectionAndStackingChildren(const LayoutPoint& offsetFromRoot) const; + LayoutRect physicalBoundingBoxIncludingReflectionAndStackingChildren(const LayoutPoint& offsetFromRoot, CalculateBoundsOptions = MaybeIncludeTransformForAncestorLayer) const; LayoutRect fragmentsBoundingBox(const PaintLayer* ancestorLayer) const; LayoutRect boundingBoxForCompositingOverlapTest() const; @@ -366,13 +374,6 @@ // If true, this layer's children are included in its bounds for overlap testing. // We can't rely on the children's positions if this layer has a filter that could have moved the children's pixels around. bool overlapBoundsIncludeChildren() const; - - // MaybeIncludeTransformForAncestorLayer means that a transform on |ancestorLayer| may be applied to the bounding box, - // in particular if paintsWithTransform() is true. - enum CalculateBoundsOptions { - MaybeIncludeTransformForAncestorLayer, - NeverIncludeTransformForAncestorLayer, - }; LayoutRect boundingBoxForCompositing(const PaintLayer* ancestorLayer = 0, CalculateBoundsOptions = MaybeIncludeTransformForAncestorLayer) const; LayoutUnit staticInlinePosition() const { return m_staticInlinePosition; }
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp b/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp index e7957b1..00a1f74 100644 --- a/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp +++ b/third_party/WebKit/Source/core/paint/PaintLayerPainterTest.cpp
@@ -490,6 +490,10 @@ TEST_P(PaintLayerPainterTest, TableCollapsedBorderNeedsPaintPhaseDescendantBlockBackgrounds) { + // TODO(wangxianzhu): Enable this test slimmingPaintInvalidation when its fully functional. + if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) + return; + // "position: relative" makes the table and td self-painting layers. // The table's layer should be marked needsPaintPhaseDescendantBlockBackground because it // will paint collapsed borders in the phase. @@ -507,6 +511,10 @@ TEST_P(PaintLayerPainterTest, TableCollapsedBorderNeedsPaintPhaseDescendantBlockBackgroundsDynamic) { + // TODO(wangxianzhu): Enable this test slimmingPaintInvalidation when its fully functional. + if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) + return; + setBodyInnerHTML( "<table id='table' style='position: relative'>" " <tr><td style='position: relative; border: 1px solid green'>Cell</td></tr>"
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp index 68e572e1..ef1ebd9 100644 --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreeBuilderTest.cpp
@@ -52,7 +52,7 @@ bool m_originalSlimmingPaintV2Enabled; }; -#define CHECK_VISUAL_RECT(sourceLayoutObject, ancestorLayoutObject) \ +#define CHECK_VISUAL_RECT(sourceLayoutObject, ancestorLayoutObject, slopFactor) \ do { \ GeometryMapper geometryMapper; \ LayoutRect source(sourceLayoutObject->localOverflowRectForPaintInvalidation()); \ @@ -66,9 +66,13 @@ \ LayoutRect expected = sourceLayoutObject->localOverflowRectForPaintInvalidation(); \ sourceLayoutObject->mapToVisualRectInAncestorSpace(ancestorLayoutObject, expected); \ - EXPECT_EQ(expected, LayoutRect(actual)); \ + EXPECT_TRUE(expected.contains(LayoutRect(actual))); \ + actual.inflate(slopFactor); \ + EXPECT_TRUE(LayoutRect(actual).contains(expected)); \ } while (0); +#define CHECK_EXACT_VISUAL_RECT(sourceLayoutObject, ancestorLayoutObject) CHECK_VISUAL_RECT(sourceLayoutObject, ancestorLayoutObject, 0) + TEST_F(PaintPropertyTreeBuilderTest, FixedPosition) { loadTestData("fixed-position.html"); @@ -85,6 +89,7 @@ EXPECT_EQ(FloatRoundedRect(0, 0, 100, 100), target1Properties->overflowClip()->clipRect()); // Likewise, it inherits clip from the viewport, skipping overflow clip of the scroller. EXPECT_EQ(frameView->contentClip(), target1Properties->overflowClip()->parent()); + CHECK_EXACT_VISUAL_RECT(target1->layoutObject(), frameView->layoutView()); // target2 is a fixed-position element inside a transformed scrolling element. // It should be attached under the scrolled box of the transformed element. @@ -97,9 +102,7 @@ EXPECT_EQ(target2Properties->paintOffsetTranslation(), target2Properties->overflowClip()->localTransformSpace()); EXPECT_EQ(FloatRoundedRect(0, 0, 100, 100), target2Properties->overflowClip()->clipRect()); EXPECT_EQ(scrollerProperties->overflowClip(), target2Properties->overflowClip()->parent()); - - CHECK_VISUAL_RECT(target1->layoutObject(), frameView->layoutView()); - CHECK_VISUAL_RECT(target2->layoutObject(), frameView->layoutView()); + CHECK_EXACT_VISUAL_RECT(target2->layoutObject(), frameView->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, PositionAndScroll) @@ -116,6 +119,7 @@ EXPECT_EQ(frameView->scrollTranslation(), scrollerProperties->overflowClip()->localTransformSpace()); EXPECT_EQ(FloatRoundedRect(120, 340, 400, 300), scrollerProperties->overflowClip()->clipRect()); EXPECT_EQ(frameView->contentClip(), scrollerProperties->overflowClip()->parent()); + CHECK_EXACT_VISUAL_RECT(scroller->layoutObject(), frameView->layoutView()); // The relative-positioned element should have accumulated box offset (exclude scrolling), // and should be affected by ancestor scroll transforms. @@ -124,8 +128,9 @@ EXPECT_EQ(TransformationMatrix().translate(680, 1120), relPosProperties->paintOffsetTranslation()->matrix()); EXPECT_EQ(scrollerProperties->scrollTranslation(), relPosProperties->paintOffsetTranslation()->parent()); EXPECT_EQ(relPosProperties->transform(), relPosProperties->overflowClip()->localTransformSpace()); - EXPECT_EQ(FloatRoundedRect(0, 0, 400, 0), relPosProperties->overflowClip()->clipRect()); + EXPECT_EQ(FloatRoundedRect(0, 0, 100, 200), relPosProperties->overflowClip()->clipRect()); EXPECT_EQ(scrollerProperties->overflowClip(), relPosProperties->overflowClip()->parent()); + CHECK_EXACT_VISUAL_RECT(relPos->layoutObject(), frameView->layoutView()); // The absolute-positioned element should not be affected by non-positioned scroller at all. Element* absPos = document().getElementById("abs-pos"); @@ -133,8 +138,9 @@ EXPECT_EQ(TransformationMatrix().translate(123, 456), absPosProperties->paintOffsetTranslation()->matrix()); EXPECT_EQ(frameView->scrollTranslation(), absPosProperties->paintOffsetTranslation()->parent()); EXPECT_EQ(absPosProperties->transform(), absPosProperties->overflowClip()->localTransformSpace()); - EXPECT_EQ(FloatRoundedRect(), absPosProperties->overflowClip()->clipRect()); + EXPECT_EQ(FloatRoundedRect(0, 0, 300, 400), absPosProperties->overflowClip()->clipRect()); EXPECT_EQ(frameView->contentClip(), absPosProperties->overflowClip()->parent()); + CHECK_EXACT_VISUAL_RECT(absPos->layoutObject(), frameView->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, FrameScrollingTraditional) @@ -158,6 +164,7 @@ LayoutViewItem layoutViewItem = document().layoutViewItem(); const ObjectPaintProperties* layoutViewProperties = layoutViewItem.objectPaintProperties(); EXPECT_EQ(nullptr, layoutViewProperties->scrollTranslation()); + CHECK_EXACT_VISUAL_RECT(document().body()->layoutObject(), frameView->layoutView()); } // TODO(trchen): Settings::rootLayerScrolls cannot be switched after main frame being created. @@ -183,6 +190,7 @@ const ObjectPaintProperties* layoutViewProperties = layoutViewItem.objectPaintProperties(); EXPECT_EQ(TransformationMatrix().translate(0, -100), layoutViewProperties->scrollTranslation()->matrix()); EXPECT_EQ(frameView->scrollTranslation(), layoutViewProperties->scrollTranslation()->parent()); + CHECK_EXACT_VISUAL_RECT(document().body()->layoutObject(), frameView->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, Perspective) @@ -201,6 +209,7 @@ const ObjectPaintProperties* innerProperties = inner->layoutObject()->objectPaintProperties(); EXPECT_EQ(TransformationMatrix().translate(50, 100), innerProperties->paintOffsetTranslation()->matrix()); EXPECT_EQ(perspectiveProperties->perspective(), innerProperties->paintOffsetTranslation()->parent()); + CHECK_EXACT_VISUAL_RECT(inner->layoutObject(), document().view()->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, Transform) @@ -214,6 +223,7 @@ EXPECT_EQ(transformProperties->paintOffsetTranslation(), transformProperties->transform()->parent()); EXPECT_EQ(TransformationMatrix().translate(50, 100), transformProperties->paintOffsetTranslation()->matrix()); EXPECT_EQ(document().view()->scrollTranslation(), transformProperties->paintOffsetTranslation()->parent()); + CHECK_EXACT_VISUAL_RECT(transform->layoutObject(), document().view()->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, RelativePositionInline) @@ -224,90 +234,101 @@ const ObjectPaintProperties* inlineBlockProperties = inlineBlock->layoutObject()->objectPaintProperties(); EXPECT_EQ(TransformationMatrix().translate(135, 490), inlineBlockProperties->paintOffsetTranslation()->matrix()); EXPECT_EQ(document().view()->scrollTranslation(), inlineBlockProperties->paintOffsetTranslation()->parent()); + CHECK_EXACT_VISUAL_RECT(inlineBlock->layoutObject(), document().view()->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, NestedOpacityEffect) { setBodyInnerHTML( - "<div id='nodeWithoutOpacity'>" - " <div id='childWithOpacity' style='opacity: 0.5'>" - " <div id='grandChildWithoutOpacity'>" - " <div id='greatGrandChildWithOpacity' style='opacity: 0.2'/>" + "<div id='nodeWithoutOpacity' style='width: 100px; height: 200px'>" + " <div id='childWithOpacity' style='opacity: 0.5; width: 50px; height: 60px;'>" + " <div id='grandChildWithoutOpacity' style='width: 20px; height: 30px'>" + " <div id='greatGrandChildWithOpacity' style='opacity: 0.2; width: 10px; height: 15px'/>" " </div>" " </div>" "</div>"); - LayoutObject& nodeWithoutOpacity = *document().getElementById("nodeWithoutOpacity")->layoutObject(); - const ObjectPaintProperties* nodeWithoutOpacityProperties = nodeWithoutOpacity.objectPaintProperties(); + LayoutObject* nodeWithoutOpacity = document().getElementById("nodeWithoutOpacity")->layoutObject(); + const ObjectPaintProperties* nodeWithoutOpacityProperties = nodeWithoutOpacity->objectPaintProperties(); EXPECT_NE(nullptr, nodeWithoutOpacityProperties); + CHECK_EXACT_VISUAL_RECT(nodeWithoutOpacity, document().view()->layoutView()); - LayoutObject& childWithOpacity = *document().getElementById("childWithOpacity")->layoutObject(); - const ObjectPaintProperties* childWithOpacityProperties = childWithOpacity.objectPaintProperties(); + LayoutObject* childWithOpacity = document().getElementById("childWithOpacity")->layoutObject(); + const ObjectPaintProperties* childWithOpacityProperties = childWithOpacity->objectPaintProperties(); EXPECT_EQ(0.5f, childWithOpacityProperties->effect()->opacity()); // childWithOpacity is the root effect node. EXPECT_NE(nullptr, childWithOpacityProperties->effect()->parent()); + CHECK_EXACT_VISUAL_RECT(childWithOpacity, document().view()->layoutView()); - LayoutObject& grandChildWithoutOpacity = *document().getElementById("grandChildWithoutOpacity")->layoutObject(); - EXPECT_NE(nullptr, grandChildWithoutOpacity.objectPaintProperties()); + LayoutObject* grandChildWithoutOpacity = document().getElementById("grandChildWithoutOpacity")->layoutObject(); + EXPECT_NE(nullptr, grandChildWithoutOpacity->objectPaintProperties()); + CHECK_EXACT_VISUAL_RECT(grandChildWithoutOpacity, document().view()->layoutView()); - LayoutObject& greatGrandChildWithOpacity = *document().getElementById("greatGrandChildWithOpacity")->layoutObject(); - const ObjectPaintProperties* greatGrandChildWithOpacityProperties = greatGrandChildWithOpacity.objectPaintProperties(); + LayoutObject* greatGrandChildWithOpacity = document().getElementById("greatGrandChildWithOpacity")->layoutObject(); + const ObjectPaintProperties* greatGrandChildWithOpacityProperties = greatGrandChildWithOpacity->objectPaintProperties(); EXPECT_EQ(0.2f, greatGrandChildWithOpacityProperties->effect()->opacity()); EXPECT_EQ(childWithOpacityProperties->effect(), greatGrandChildWithOpacityProperties->effect()->parent()); + CHECK_EXACT_VISUAL_RECT(greatGrandChildWithOpacity, document().view()->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, TransformNodeDoesNotAffectEffectNodes) { setBodyInnerHTML( - "<div id='nodeWithOpacity' style='opacity: 0.6'>" - " <div id='childWithTransform' style='transform: translate3d(10px, 10px, 0px);'>" - " <div id='grandChildWithOpacity' style='opacity: 0.4'/>" + "<div id='nodeWithOpacity' style='opacity: 0.6' style='width: 100px; height: 200px'>" + " <div id='childWithTransform' style='transform: translate3d(10px, 10px, 0px); width: 50px; height: 60px;'>" + " <div id='grandChildWithOpacity' style='opacity: 0.4; width: 20px; height: 30px'/>" " </div>" "</div>"); - LayoutObject& nodeWithOpacity = *document().getElementById("nodeWithOpacity")->layoutObject(); - const ObjectPaintProperties* nodeWithOpacityProperties = nodeWithOpacity.objectPaintProperties(); + LayoutObject* nodeWithOpacity = document().getElementById("nodeWithOpacity")->layoutObject(); + const ObjectPaintProperties* nodeWithOpacityProperties = nodeWithOpacity->objectPaintProperties(); EXPECT_EQ(0.6f, nodeWithOpacityProperties->effect()->opacity()); EXPECT_NE(nullptr, nodeWithOpacityProperties->effect()->parent()); EXPECT_EQ(nullptr, nodeWithOpacityProperties->transform()); + CHECK_EXACT_VISUAL_RECT(nodeWithOpacity, document().view()->layoutView()); - LayoutObject& childWithTransform = *document().getElementById("childWithTransform")->layoutObject(); - const ObjectPaintProperties* childWithTransformProperties = childWithTransform.objectPaintProperties(); + LayoutObject* childWithTransform = document().getElementById("childWithTransform")->layoutObject(); + const ObjectPaintProperties* childWithTransformProperties = childWithTransform->objectPaintProperties(); EXPECT_EQ(nullptr, childWithTransformProperties->effect()); EXPECT_EQ(TransformationMatrix().translate(10, 10), childWithTransformProperties->transform()->matrix()); + CHECK_EXACT_VISUAL_RECT(childWithTransform, document().view()->layoutView()); - LayoutObject& grandChildWithOpacity = *document().getElementById("grandChildWithOpacity")->layoutObject(); - const ObjectPaintProperties* grandChildWithOpacityProperties = grandChildWithOpacity.objectPaintProperties(); + LayoutObject* grandChildWithOpacity = document().getElementById("grandChildWithOpacity")->layoutObject(); + const ObjectPaintProperties* grandChildWithOpacityProperties = grandChildWithOpacity->objectPaintProperties(); EXPECT_EQ(0.4f, grandChildWithOpacityProperties->effect()->opacity()); EXPECT_EQ(nodeWithOpacityProperties->effect(), grandChildWithOpacityProperties->effect()->parent()); EXPECT_EQ(nullptr, grandChildWithOpacityProperties->transform()); + CHECK_EXACT_VISUAL_RECT(grandChildWithOpacity, document().view()->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, EffectNodesAcrossStackingContext) { setBodyInnerHTML( - "<div id='nodeWithOpacity' style='opacity: 0.6'>" - " <div id='childWithStackingContext' style='position:absolute;'>" - " <div id='grandChildWithOpacity' style='opacity: 0.4'/>" + "<div id='nodeWithOpacity' style='opacity: 0.6; width: 100px; height: 200px'>" + " <div id='childWithStackingContext' style='position:absolute; width: 50px; height: 60px;'>" + " <div id='grandChildWithOpacity' style='opacity: 0.4; width: 20px; height: 30px'/>" " </div>" "</div>"); - LayoutObject& nodeWithOpacity = *document().getElementById("nodeWithOpacity")->layoutObject(); - const ObjectPaintProperties* nodeWithOpacityProperties = nodeWithOpacity.objectPaintProperties(); + LayoutObject* nodeWithOpacity = document().getElementById("nodeWithOpacity")->layoutObject(); + const ObjectPaintProperties* nodeWithOpacityProperties = nodeWithOpacity->objectPaintProperties(); EXPECT_EQ(0.6f, nodeWithOpacityProperties->effect()->opacity()); EXPECT_NE(nullptr, nodeWithOpacityProperties->effect()->parent()); EXPECT_EQ(nullptr, nodeWithOpacityProperties->transform()); + CHECK_EXACT_VISUAL_RECT(nodeWithOpacity, document().view()->layoutView()); - LayoutObject& childWithStackingContext = *document().getElementById("childWithStackingContext")->layoutObject(); - const ObjectPaintProperties* childWithStackingContextProperties = childWithStackingContext.objectPaintProperties(); + LayoutObject* childWithStackingContext = document().getElementById("childWithStackingContext")->layoutObject(); + const ObjectPaintProperties* childWithStackingContextProperties = childWithStackingContext->objectPaintProperties(); EXPECT_EQ(nullptr, childWithStackingContextProperties->effect()); EXPECT_EQ(nullptr, childWithStackingContextProperties->transform()); + CHECK_EXACT_VISUAL_RECT(childWithStackingContext, document().view()->layoutView()); - LayoutObject& grandChildWithOpacity = *document().getElementById("grandChildWithOpacity")->layoutObject(); - const ObjectPaintProperties* grandChildWithOpacityProperties = grandChildWithOpacity.objectPaintProperties(); + LayoutObject* grandChildWithOpacity = document().getElementById("grandChildWithOpacity")->layoutObject(); + const ObjectPaintProperties* grandChildWithOpacityProperties = grandChildWithOpacity->objectPaintProperties(); EXPECT_EQ(0.4f, grandChildWithOpacityProperties->effect()->opacity()); EXPECT_EQ(nodeWithOpacityProperties->effect(), grandChildWithOpacityProperties->effect()->parent()); EXPECT_EQ(nullptr, grandChildWithOpacityProperties->transform()); + CHECK_EXACT_VISUAL_RECT(grandChildWithOpacity, document().view()->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, EffectNodesInSVG) @@ -323,8 +344,8 @@ " </g>" "</svg>"); - LayoutObject& groupWithOpacity = *document().getElementById("groupWithOpacity")->layoutObject(); - const ObjectPaintProperties* groupWithOpacityProperties = groupWithOpacity.objectPaintProperties(); + LayoutObject* groupWithOpacity = document().getElementById("groupWithOpacity")->layoutObject(); + const ObjectPaintProperties* groupWithOpacityProperties = groupWithOpacity->objectPaintProperties(); EXPECT_EQ(0.6f, groupWithOpacityProperties->effect()->opacity()); EXPECT_NE(nullptr, groupWithOpacityProperties->effect()->parent()); @@ -612,11 +633,12 @@ "<input id='button' type='button' style='width:345px; height:123px' value='some text'/>"); FrameView* frameView = document().view(); - LayoutObject& button = *document().getElementById("button")->layoutObject(); - const ObjectPaintProperties* buttonProperties = button.objectPaintProperties(); + LayoutObject* button = document().getElementById("button")->layoutObject(); + const ObjectPaintProperties* buttonProperties = button->objectPaintProperties(); EXPECT_EQ(frameView->scrollTranslation(), buttonProperties->overflowClip()->localTransformSpace()); EXPECT_EQ(FloatRoundedRect(5, 5, 335, 113), buttonProperties->overflowClip()->clipRect()); EXPECT_EQ(frameView->contentClip(), buttonProperties->overflowClip()->parent()); + CHECK_EXACT_VISUAL_RECT(button, frameView->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, BorderRadiusClip) @@ -640,8 +662,8 @@ "<div id='div'></div>"); FrameView* frameView = document().view(); - LayoutObject& div = *document().getElementById("div")->layoutObject(); - const ObjectPaintProperties* divProperties = div.objectPaintProperties(); + LayoutObject* div = document().getElementById("div")->layoutObject(); + const ObjectPaintProperties* divProperties = div->objectPaintProperties(); EXPECT_EQ(frameView->scrollTranslation(), divProperties->overflowClip()->localTransformSpace()); // The overflow clip rect includes only the padding box. // padding box = border box(500+60+50, 400+45+55) - border outset(60+50, 45+55) - scrollbars(15, 15) @@ -662,6 +684,7 @@ FloatSize(6, 1)), // (bottom right) = max((56, 56) - (50, 55), (0, 0)) borderRadiusClip->clipRect()); EXPECT_EQ(frameView->contentClip(), borderRadiusClip->parent()); + CHECK_EXACT_VISUAL_RECT(div, frameView->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, TransformNodesAcrossSubframes) @@ -671,17 +694,21 @@ "<div id='divWithTransform' style='transform: translate3d(1px, 2px, 3px);'>" " <iframe id='frame'></iframe>" "</div>"); - Document& frameDocument = setupChildIframe("frame", "<style>body { margin: 0; }</style><div id='transform' style='transform: translate3d(4px, 5px, 6px);'></div>"); - document().view()->updateAllLifecyclePhases(); + Document& frameDocument = setupChildIframe("frame", + "<style>body { margin: 0; }</style><div id='transform' style='transform: translate3d(4px, 5px, 6px); width: 100px; height: 200px'></div>"); + FrameView* frameView = document().view(); + frameView->updateAllLifecyclePhases(); - LayoutObject& divWithTransform = *document().getElementById("divWithTransform")->layoutObject(); - const ObjectPaintProperties* divWithTransformProperties = divWithTransform.objectPaintProperties(); + LayoutObject* divWithTransform = document().getElementById("divWithTransform")->layoutObject(); + const ObjectPaintProperties* divWithTransformProperties = divWithTransform->objectPaintProperties(); EXPECT_EQ(TransformationMatrix().translate3d(1, 2, 3), divWithTransformProperties->transform()->matrix()); + CHECK_EXACT_VISUAL_RECT(divWithTransform, frameView->layoutView()); LayoutObject* innerDivWithTransform = frameDocument.getElementById("transform")->layoutObject(); const ObjectPaintProperties* innerDivWithTransformProperties = innerDivWithTransform->objectPaintProperties(); auto* innerDivTransform = innerDivWithTransformProperties->transform(); EXPECT_EQ(TransformationMatrix().translate3d(4, 5, 6), innerDivTransform->matrix()); + CHECK_EXACT_VISUAL_RECT(innerDivWithTransform, frameView->layoutView()); // Ensure that the inner div's transform is correctly rooted in the root frame's transform tree. // This asserts that we have the following tree structure: @@ -704,8 +731,10 @@ "<div id='divWithTransform' style='transform: translate3d(1px, 2px, 3px);'>" " <iframe id='frame' style='transform: translate3d(4px, 5px, 6px); border: 42px solid; margin: 7px;'></iframe>" "</div>"); - Document& frameDocument = setupChildIframe("frame", "<style>body { margin: 31px; }</style><div id='transform' style='transform: translate3d(7px, 8px, 9px);'></div>"); - document().view()->updateAllLifecyclePhases(); + Document& frameDocument = setupChildIframe("frame", + "<style>body { margin: 31px; }</style><div id='transform' style='transform: translate3d(7px, 8px, 9px); width: 100px; height: 200px'></div>"); + FrameView* frameView = document().view(); + frameView->updateAllLifecyclePhases(); // Assert that we have the following tree structure: // ... @@ -720,6 +749,7 @@ LayoutObject* innerDivWithTransform = frameDocument.getElementById("transform")->layoutObject(); auto* innerDivTransform = innerDivWithTransform->objectPaintProperties()->transform(); EXPECT_EQ(TransformationMatrix().translate3d(7, 8, 9), innerDivTransform->matrix()); + CHECK_EXACT_VISUAL_RECT(innerDivWithTransform, frameView->layoutView()); auto* innerDocumentPaintOffsetTranslation = innerDivTransform->parent(); EXPECT_EQ(TransformationMatrix().translate3d(31, 31, 0), innerDocumentPaintOffsetTranslation->matrix()); @@ -734,8 +764,9 @@ auto* divWithTransformTransform = iframePaintOffsetTranslation->parent(); EXPECT_EQ(TransformationMatrix().translate3d(1, 2, 3), divWithTransformTransform->matrix()); - LayoutObject& divWithTransform = *document().getElementById("divWithTransform")->layoutObject(); - EXPECT_EQ(divWithTransformTransform, divWithTransform.objectPaintProperties()->transform()); + LayoutObject* divWithTransform = document().getElementById("divWithTransform")->layoutObject(); + EXPECT_EQ(divWithTransformTransform, divWithTransform->objectPaintProperties()->transform()); + CHECK_EXACT_VISUAL_RECT(divWithTransform, frameView->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, TreeContextClipByNonStackingContext) @@ -746,19 +777,22 @@ setBodyInnerHTML( "<style>body { margin: 0; }</style>" "<div id='scroller' style='overflow:scroll; width:400px; height:300px;'>" - " <div id='child' style='position:relative;'></div>" + " <div id='child' style='position:relative; width:100px; height: 200px;'></div>" " <div style='height:10000px;'></div>" "</div>" ); + FrameView* frameView = document().view(); - LayoutObject& scroller = *document().getElementById("scroller")->layoutObject(); - const ObjectPaintProperties* scrollerProperties = scroller.objectPaintProperties(); - LayoutObject& child = *document().getElementById("child")->layoutObject(); - const ObjectPaintProperties* childProperties = child.objectPaintProperties(); + LayoutObject* scroller = document().getElementById("scroller")->layoutObject(); + const ObjectPaintProperties* scrollerProperties = scroller->objectPaintProperties(); + LayoutObject* child = document().getElementById("child")->layoutObject(); + const ObjectPaintProperties* childProperties = child->objectPaintProperties(); EXPECT_EQ(scrollerProperties->overflowClip(), childProperties->localBorderBoxProperties()->propertyTreeState.clip); EXPECT_EQ(scrollerProperties->scrollTranslation(), childProperties->localBorderBoxProperties()->propertyTreeState.transform); EXPECT_NE(nullptr, childProperties->localBorderBoxProperties()->propertyTreeState.effect); + CHECK_EXACT_VISUAL_RECT(scroller, frameView->layoutView()); + CHECK_EXACT_VISUAL_RECT(child, frameView->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, TreeContextUnclipFromParentStackingContext) @@ -770,20 +804,22 @@ setBodyInnerHTML( "<style>body { margin: 0; }</style>" "<div id='scroller' style='overflow:scroll; opacity:0.5;'>" - " <div id='child' style='position:absolute; left:0; top:0;'></div>" + " <div id='child' style='position:absolute; left:0; top:0; width: 100px; height: 200px'></div>" " <div style='height:10000px;'></div>" "</div>" ); FrameView* frameView = document().view(); - LayoutObject& scroller = *document().getElementById("scroller")->layoutObject(); - const ObjectPaintProperties* scrollerProperties = scroller.objectPaintProperties(); - LayoutObject& child = *document().getElementById("child")->layoutObject(); - const ObjectPaintProperties* childProperties = child.objectPaintProperties(); + LayoutObject* scroller = document().getElementById("scroller")->layoutObject(); + const ObjectPaintProperties* scrollerProperties = scroller->objectPaintProperties(); + LayoutObject* child = document().getElementById("child")->layoutObject(); + const ObjectPaintProperties* childProperties = child->objectPaintProperties(); EXPECT_EQ(frameView->contentClip(), childProperties->localBorderBoxProperties()->propertyTreeState.clip); EXPECT_EQ(frameView->scrollTranslation(), childProperties->localBorderBoxProperties()->propertyTreeState.transform); EXPECT_EQ(scrollerProperties->effect(), childProperties->localBorderBoxProperties()->propertyTreeState.effect); + CHECK_EXACT_VISUAL_RECT(scroller, frameView->layoutView()); + CHECK_EXACT_VISUAL_RECT(child, frameView->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, TableCellLayoutLocation) @@ -819,11 +855,12 @@ ); FrameView* frameView = document().view(); - LayoutObject& target = *document().getElementById("target")->layoutObject(); - const ObjectPaintProperties* targetProperties = target.objectPaintProperties(); + LayoutObject* target = document().getElementById("target")->layoutObject(); + const ObjectPaintProperties* targetProperties = target->objectPaintProperties(); EXPECT_EQ(LayoutPoint(170, 170), targetProperties->localBorderBoxProperties()->paintOffset); EXPECT_EQ(frameView->scrollTranslation(), targetProperties->localBorderBoxProperties()->propertyTreeState.transform); + CHECK_EXACT_VISUAL_RECT(target, frameView->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, CSSClipFixedPositionDescendant) @@ -844,6 +881,8 @@ " position: fixed;" " left: 654px;" " top: 321px;" + " width: 10px;" + " heght: 20px" " }" "</style>" "<div id='clip'><div id='fixed'></div></div>" @@ -854,18 +893,67 @@ FrameView* frameView = document().view(); - LayoutObject& clip = *document().getElementById("clip")->layoutObject(); - const ObjectPaintProperties* clipProperties = clip.objectPaintProperties(); + LayoutObject* clip = document().getElementById("clip")->layoutObject(); + const ObjectPaintProperties* clipProperties = clip->objectPaintProperties(); EXPECT_EQ(frameView->contentClip(), clipProperties->cssClip()->parent()); EXPECT_EQ(frameView->scrollTranslation(), clipProperties->cssClip()->localTransformSpace()); EXPECT_EQ(FloatRoundedRect(FloatRect(absoluteClipRect)), clipProperties->cssClip()->clipRect()); +// TODO(chrishtr): the old visual rect code is not able to apply CSS clip to fixed-position elements. +// CHECK_EXACT_VISUAL_RECT(clip, frameView->layoutView()); - LayoutObject& fixed = *document().getElementById("fixed")->layoutObject(); - const ObjectPaintProperties* fixedProperties = fixed.objectPaintProperties(); + LayoutObject* fixed = document().getElementById("fixed")->layoutObject(); + const ObjectPaintProperties* fixedProperties = fixed->objectPaintProperties(); EXPECT_EQ(clipProperties->cssClip(), fixedProperties->localBorderBoxProperties()->propertyTreeState.clip); EXPECT_EQ(frameView->preTranslation(), fixedProperties->localBorderBoxProperties()->propertyTreeState.transform->parent()); EXPECT_EQ(TransformationMatrix().translate(654, 321), fixedProperties->localBorderBoxProperties()->propertyTreeState.transform->matrix()); EXPECT_EQ(LayoutPoint(), fixedProperties->localBorderBoxProperties()->paintOffset); + CHECK_EXACT_VISUAL_RECT(fixed, frameView->layoutView()); +} + +TEST_F(PaintPropertyTreeBuilderTest, CSSClipAbsPositionDescendant) +{ + // This test verifies that clip tree hierarchy being generated correctly for the hard case + // such that a fixed position element getting clipped by an absolute position CSS clip. + setBodyInnerHTML( + "<style>" + " #clip {" + " position: absolute;" + " left: 123px;" + " top: 456px;" + " clip: rect(10px, 80px, 70px, 40px);" + " width: 100px;" + " height: 100px;" + " }" + " #abs {" + " position: absolute;" + " left: 654px;" + " top: 321px;" + " width: 10px;" + " heght: 20px" + " }" + "</style>" + "<div id='clip'><div id='absolute'></div></div>" + ); + LayoutRect localClipRect(40, 10, 40, 60); + LayoutRect absoluteClipRect = localClipRect; + absoluteClipRect.move(123, 456); + + FrameView* frameView = document().view(); + + LayoutObject* clip = document().getElementById("clip")->layoutObject(); + const ObjectPaintProperties* clipProperties = clip->objectPaintProperties(); + EXPECT_EQ(frameView->contentClip(), clipProperties->cssClip()->parent()); + EXPECT_EQ(frameView->scrollTranslation(), clipProperties->cssClip()->localTransformSpace()); + EXPECT_EQ(FloatRoundedRect(FloatRect(absoluteClipRect)), clipProperties->cssClip()->clipRect()); +// TODO(chrishtr): the old visual rect code is not able to apply CSS clip to fixed-position elements. +// CHECK_VISUAL_RECT(clip, frameView->layoutView()); + + LayoutObject* absolute = document().getElementById("absolute")->layoutObject(); + const ObjectPaintProperties* absPosProperties = absolute->objectPaintProperties(); + EXPECT_EQ(clipProperties->cssClip(), absPosProperties->localBorderBoxProperties()->propertyTreeState.clip); + EXPECT_EQ(frameView->preTranslation(), absPosProperties->localBorderBoxProperties()->propertyTreeState.transform->parent()); + EXPECT_EQ(LayoutPoint(123, 456), absPosProperties->localBorderBoxProperties()->paintOffset); + CHECK_EXACT_VISUAL_RECT(absolute, frameView->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, CSSClipFixedPositionDescendantNonShared) @@ -905,26 +993,29 @@ FrameView* frameView = document().view(); - LayoutObject& overflow = *document().getElementById("overflow")->layoutObject(); - const ObjectPaintProperties* overflowProperties = overflow.objectPaintProperties(); + LayoutObject* overflow = document().getElementById("overflow")->layoutObject(); + const ObjectPaintProperties* overflowProperties = overflow->objectPaintProperties(); EXPECT_EQ(frameView->contentClip(), overflowProperties->overflowClip()->parent()); EXPECT_EQ(frameView->scrollTranslation(), overflowProperties->scrollTranslation()->parent()); + CHECK_EXACT_VISUAL_RECT(overflow, frameView->layoutView()); - LayoutObject& clip = *document().getElementById("clip")->layoutObject(); - const ObjectPaintProperties* clipProperties = clip.objectPaintProperties(); + LayoutObject* clip = document().getElementById("clip")->layoutObject(); + const ObjectPaintProperties* clipProperties = clip->objectPaintProperties(); EXPECT_EQ(overflowProperties->overflowClip(), clipProperties->cssClip()->parent()); EXPECT_EQ(overflowProperties->scrollTranslation(), clipProperties->cssClip()->localTransformSpace()); EXPECT_EQ(FloatRoundedRect(FloatRect(absoluteClipRect)), clipProperties->cssClip()->clipRect()); EXPECT_EQ(frameView->contentClip(), clipProperties->cssClipFixedPosition()->parent()); EXPECT_EQ(overflowProperties->scrollTranslation(), clipProperties->cssClipFixedPosition()->localTransformSpace()); EXPECT_EQ(FloatRoundedRect(FloatRect(absoluteClipRect)), clipProperties->cssClipFixedPosition()->clipRect()); + CHECK_EXACT_VISUAL_RECT(clip, frameView->layoutView()); - LayoutObject& fixed = *document().getElementById("fixed")->layoutObject(); - const ObjectPaintProperties* fixedProperties = fixed.objectPaintProperties(); + LayoutObject* fixed = document().getElementById("fixed")->layoutObject(); + const ObjectPaintProperties* fixedProperties = fixed->objectPaintProperties(); EXPECT_EQ(clipProperties->cssClipFixedPosition(), fixedProperties->localBorderBoxProperties()->propertyTreeState.clip); EXPECT_EQ(frameView->preTranslation(), fixedProperties->localBorderBoxProperties()->propertyTreeState.transform->parent()); EXPECT_EQ(TransformationMatrix().translate(654, 321), fixedProperties->localBorderBoxProperties()->propertyTreeState.transform->matrix()); EXPECT_EQ(LayoutPoint(), fixedProperties->localBorderBoxProperties()->paintOffset); + CHECK_EXACT_VISUAL_RECT(fixed, frameView->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, ColumnSpannerUnderRelativePositioned) @@ -937,8 +1028,9 @@ "</div>" ); - LayoutObject& spanner = *getLayoutObjectByElementId("spanner"); - EXPECT_EQ(LayoutPoint(55, 44), spanner.objectPaintProperties()->localBorderBoxProperties()->paintOffset); + LayoutObject* spanner = getLayoutObjectByElementId("spanner"); + EXPECT_EQ(LayoutPoint(55, 44), spanner->objectPaintProperties()->localBorderBoxProperties()->paintOffset); + CHECK_EXACT_VISUAL_RECT(spanner, document().view()->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, FractionalPaintOffset) @@ -952,14 +1044,19 @@ " <div id='b' style='width: 40px; height: 40px; left: 0.5px; top: 11.1px;'></div>" "</div>" ); + FrameView* frameView = document().view(); - const ObjectPaintProperties* aProperties = document().getElementById("a")->layoutObject()->objectPaintProperties(); + LayoutObject* a = document().getElementById("a")->layoutObject(); + const ObjectPaintProperties* aProperties = a->objectPaintProperties(); LayoutPoint aPaintOffset = LayoutPoint(FloatPoint(0.1, 0.3)); EXPECT_EQ(aPaintOffset, aProperties->localBorderBoxProperties()->paintOffset); + CHECK_EXACT_VISUAL_RECT(a, frameView->layoutView()); - const ObjectPaintProperties* bProperties = document().getElementById("b")->layoutObject()->objectPaintProperties(); + LayoutObject* b = document().getElementById("b")->layoutObject(); + const ObjectPaintProperties* bProperties = b->objectPaintProperties(); LayoutPoint bPaintOffset = aPaintOffset + LayoutPoint(FloatPoint(0.5, 11.1)); EXPECT_EQ(bPaintOffset, bProperties->localBorderBoxProperties()->paintOffset); + CHECK_EXACT_VISUAL_RECT(a, frameView->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, PaintOffsetWithBasicPixelSnapping) @@ -975,19 +1072,27 @@ " </div>" "</div>" ); + FrameView* frameView = document().view(); - const ObjectPaintProperties* bProperties = document().getElementById("b")->layoutObject()->objectPaintProperties(); + LayoutObject* b = document().getElementById("b")->layoutObject(); + const ObjectPaintProperties* bProperties = b->objectPaintProperties(); EXPECT_EQ(TransformationMatrix().translate3d(0, 0, 0), bProperties->transform()->matrix()); // The paint offset transform should be snapped from (0.3,0.3) to (0,0). EXPECT_EQ(TransformationMatrix().translate(0, 0), bProperties->transform()->parent()->matrix()); // The residual subpixel adjustment should be (0.3,0.3) - (0,0) = (0.3,0.3). LayoutPoint subpixelAccumulation = LayoutPoint(FloatPoint(0.3, 0.3)); EXPECT_EQ(subpixelAccumulation, bProperties->localBorderBoxProperties()->paintOffset); + CHECK_EXACT_VISUAL_RECT(b, frameView->layoutView()); // c should be painted starting at subpixelAccumulation + (0.1,0.1) = (0.4,0.4). + LayoutObject* c = document().getElementById("c")->layoutObject(); LayoutPoint cPaintOffset = subpixelAccumulation + LayoutPoint(FloatPoint(0.1, 0.1)); - const ObjectPaintProperties* cProperties = document().getElementById("c")->layoutObject()->objectPaintProperties(); + const ObjectPaintProperties* cProperties = c->objectPaintProperties(); EXPECT_EQ(cPaintOffset, cProperties->localBorderBoxProperties()->paintOffset); + // Visual rects via the non-paint properties system use enclosingIntRect before applying transforms, + // because they are computed bottom-up and therefore can't apply pixel snapping. Therefore apply a + // slop of 1px. + CHECK_VISUAL_RECT(c, frameView->layoutView(), 1); } TEST_F(PaintPropertyTreeBuilderTest, PaintOffsetWithPixelSnappingThroughTransform) @@ -1003,19 +1108,27 @@ " </div>" "</div>" ); + FrameView* frameView = document().view(); - const ObjectPaintProperties* bProperties = document().getElementById("b")->layoutObject()->objectPaintProperties(); + LayoutObject* b = document().getElementById("b")->layoutObject(); + const ObjectPaintProperties* bProperties = b->objectPaintProperties(); EXPECT_EQ(TransformationMatrix().translate3d(0, 0, 0), bProperties->transform()->matrix()); // The paint offset transform should be snapped from (0.7,0.7) to (1,1). EXPECT_EQ(TransformationMatrix().translate(1, 1), bProperties->transform()->parent()->matrix()); // The residual subpixel adjustment should be (0.7,0.7) - (1,1) = (-0.3,-0.3). LayoutPoint subpixelAccumulation = LayoutPoint(LayoutPoint(FloatPoint(0.7, 0.7)) - LayoutPoint(1, 1)); EXPECT_EQ(subpixelAccumulation, bProperties->localBorderBoxProperties()->paintOffset); + CHECK_EXACT_VISUAL_RECT(b, frameView->layoutView()); // c should be painted starting at subpixelAccumulation + (0.7,0.7) = (0.4,0.4). + LayoutObject* c = document().getElementById("c")->layoutObject(); LayoutPoint cPaintOffset = subpixelAccumulation + LayoutPoint(FloatPoint(0.7, 0.7)); - const ObjectPaintProperties* cProperties = document().getElementById("c")->layoutObject()->objectPaintProperties(); + const ObjectPaintProperties* cProperties = c->objectPaintProperties(); EXPECT_EQ(cPaintOffset, cProperties->localBorderBoxProperties()->paintOffset); + // Visual rects via the non-paint properties system use enclosingIntRect before applying transforms, + // because they are computed bottom-up and therefore can't apply pixel snapping. Therefore apply a + // slop of 1px. + CHECK_VISUAL_RECT(c, frameView->layoutView(), 1); } TEST_F(PaintPropertyTreeBuilderTest, PaintOffsetWithPixelSnappingThroughMultipleTransforms) @@ -1033,27 +1146,37 @@ " </div>" "</div>" ); + FrameView* frameView = document().view(); - const ObjectPaintProperties* bProperties = document().getElementById("b")->layoutObject()->objectPaintProperties(); + LayoutObject* b = document().getElementById("b")->layoutObject(); + const ObjectPaintProperties* bProperties = b->objectPaintProperties(); EXPECT_EQ(TransformationMatrix().translate3d(5, 7, 0), bProperties->transform()->matrix()); // The paint offset transform should be snapped from (0.7,0.7) to (1,1). EXPECT_EQ(TransformationMatrix().translate(1, 1), bProperties->transform()->parent()->matrix()); // The residual subpixel adjustment should be (0.7,0.7) - (1,1) = (-0.3,-0.3). LayoutPoint subpixelAccumulation = LayoutPoint(LayoutPoint(FloatPoint(0.7, 0.7)) - LayoutPoint(1, 1)); EXPECT_EQ(subpixelAccumulation, bProperties->localBorderBoxProperties()->paintOffset); + CHECK_EXACT_VISUAL_RECT(b, frameView->layoutView()); - const ObjectPaintProperties* cProperties = document().getElementById("c")->layoutObject()->objectPaintProperties(); + LayoutObject* c = document().getElementById("c")->layoutObject(); + const ObjectPaintProperties* cProperties = c->objectPaintProperties(); EXPECT_EQ(TransformationMatrix().translate3d(11, 13, 0), cProperties->transform()->matrix()); // The paint offset should be (-0.3,-0.3) but the paint offset transform should still be at // (0,0) because it should be snapped. EXPECT_EQ(TransformationMatrix().translate(0, 0), cProperties->transform()->parent()->matrix()); // The residual subpixel adjustment should still be (-0.3,-0.3). EXPECT_EQ(subpixelAccumulation, cProperties->localBorderBoxProperties()->paintOffset); + CHECK_EXACT_VISUAL_RECT(c, frameView->layoutView()); // d should be painted starting at subpixelAccumulation + (0.7,0.7) = (0.4,0.4). + LayoutObject* d = document().getElementById("d")->layoutObject(); LayoutPoint dPaintOffset = subpixelAccumulation + LayoutPoint(FloatPoint(0.7, 0.7)); - const ObjectPaintProperties* dProperties = document().getElementById("d")->layoutObject()->objectPaintProperties(); + const ObjectPaintProperties* dProperties = d->objectPaintProperties(); EXPECT_EQ(dPaintOffset, dProperties->localBorderBoxProperties()->paintOffset); + // Visual rects via the non-paint properties system use enclosingIntRect before applying transforms, + // because they are computed bottom-up and therefore can't apply pixel snapping. Therefore apply a + // slop of 1px. + CHECK_VISUAL_RECT(d, frameView->layoutView(), 1); } TEST_F(PaintPropertyTreeBuilderTest, PaintOffsetWithPixelSnappingWithFixedPos) @@ -1070,23 +1193,33 @@ " </div>" "</div>" ); + FrameView* frameView = document().view(); - const ObjectPaintProperties* bProperties = document().getElementById("b")->layoutObject()->objectPaintProperties(); + LayoutObject* b = document().getElementById("b")->layoutObject(); + const ObjectPaintProperties* bProperties = b->objectPaintProperties(); EXPECT_EQ(TransformationMatrix().translate(0, 0), bProperties->transform()->matrix()); // The paint offset transform should be snapped from (0.7,0) to (1,0). EXPECT_EQ(TransformationMatrix().translate(1, 0), bProperties->transform()->parent()->matrix()); // The residual subpixel adjustment should be (0.7,0) - (1,0) = (-0.3,0). LayoutPoint subpixelAccumulation = LayoutPoint(LayoutPoint(FloatPoint(0.7, 0)) - LayoutPoint(1, 0)); EXPECT_EQ(subpixelAccumulation, bProperties->localBorderBoxProperties()->paintOffset); + CHECK_EXACT_VISUAL_RECT(b, frameView->layoutView()); - const ObjectPaintProperties* fixedProperties = document().getElementById("fixed")->layoutObject()->objectPaintProperties(); + LayoutObject* fixed = document().getElementById("fixed")->layoutObject(); + const ObjectPaintProperties* fixedProperties = fixed->objectPaintProperties(); // The residual subpixel adjustment should still be (-0.3,0). EXPECT_EQ(subpixelAccumulation, fixedProperties->localBorderBoxProperties()->paintOffset); + CHECK_EXACT_VISUAL_RECT(fixed, frameView->layoutView()); // d should be painted starting at subpixelAccumulation + (0.7,0) = (0.4,0). + LayoutObject* d = document().getElementById("d")->layoutObject(); LayoutPoint dPaintOffset = subpixelAccumulation + LayoutPoint(FloatPoint(0.7, 0)); - const ObjectPaintProperties* dProperties = document().getElementById("d")->layoutObject()->objectPaintProperties(); + const ObjectPaintProperties* dProperties = d->objectPaintProperties(); EXPECT_EQ(dPaintOffset, dProperties->localBorderBoxProperties()->paintOffset); + // Visual rects via the non-paint properties system use enclosingIntRect before applying transforms, + // because they are computed bottom-up and therefore can't apply pixel snapping. Therefore apply a + // slop of 1px. + CHECK_VISUAL_RECT(d, frameView->layoutView(), 1); } TEST_F(PaintPropertyTreeBuilderTest, SvgPixelSnappingShouldResetPaintOffset) @@ -1112,7 +1245,7 @@ TEST_F(PaintPropertyTreeBuilderTest, NoRenderingContextByDefault) { - setBodyInnerHTML("<div style=\"transform: translateZ(0)\"></div>"); + setBodyInnerHTML("<div style='transform: translateZ(0)'></div>"); const ObjectPaintProperties* properties = document().body()->firstChild()->layoutObject()->objectPaintProperties(); ASSERT_TRUE(properties->transform()); @@ -1122,54 +1255,68 @@ TEST_F(PaintPropertyTreeBuilderTest, Preserve3DCreatesSharedRenderingContext) { setBodyInnerHTML( - "<div style=\"transform-style: preserve-3d\">" - " <div id=\"a\" style=\"transform: translateZ(0)\"></div>" - " <div id=\"b\" style=\"transform: translateZ(0)\"></div>" + "<div style='transform-style: preserve-3d'>" + " <div id='a' style='transform: translateZ(0); width: 30px; height: 40px'></div>" + " <div id='b' style='transform: translateZ(0); width: 20px; height: 10px'></div>" "</div>"); + FrameView* frameView = document().view(); - const ObjectPaintProperties* aProperties = document().getElementById("a")->layoutObject()->objectPaintProperties(); - const ObjectPaintProperties* bProperties = document().getElementById("b")->layoutObject()->objectPaintProperties(); + LayoutObject* a = document().getElementById("a")->layoutObject(); + const ObjectPaintProperties* aProperties = a->objectPaintProperties(); + LayoutObject* b = document().getElementById("b")->layoutObject(); + const ObjectPaintProperties* bProperties = b->objectPaintProperties(); ASSERT_TRUE(aProperties->transform() && bProperties->transform()); EXPECT_NE(aProperties->transform(), bProperties->transform()); EXPECT_TRUE(aProperties->transform()->hasRenderingContext()); EXPECT_TRUE(bProperties->transform()->hasRenderingContext()); EXPECT_EQ(aProperties->transform()->renderingContextID(), bProperties->transform()->renderingContextID()); + CHECK_EXACT_VISUAL_RECT(a, frameView->layoutView()); + CHECK_EXACT_VISUAL_RECT(b, frameView->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, FlatTransformStyleEndsRenderingContext) { setBodyInnerHTML( - "<div style=\"transform-style: preserve-3d\">" - " <div id=\"a\" style=\"transform: translateZ(0)\">" - " <div id=\"b\" style=\"transform: translateZ(0)\"></div>" + "<div style='transform-style: preserve-3d'>" + " <div id='a' style='transform: translateZ(0); width: 30px; height: 40px'>" + " <div id='b' style='transform: translateZ(0); width: 10px; height: 20px'></div>" " </div>" "</div>"); + FrameView* frameView = document().view(); - ASSERT_FALSE(document().getElementById("a")->layoutObject()->styleRef().preserves3D()); - const ObjectPaintProperties* aProperties = document().getElementById("a")->layoutObject()->objectPaintProperties(); - const ObjectPaintProperties* bProperties = document().getElementById("b")->layoutObject()->objectPaintProperties(); + LayoutObject* a = document().getElementById("a")->layoutObject(); + const ObjectPaintProperties* aProperties = a->objectPaintProperties(); + LayoutObject* b = document().getElementById("b")->layoutObject(); + const ObjectPaintProperties* bProperties = b->objectPaintProperties(); + ASSERT_FALSE(a->styleRef().preserves3D()); + ASSERT_TRUE(aProperties->transform() && bProperties->transform()); // #a should participate in a rendering context (due to its parent), but its // child #b should not. EXPECT_TRUE(aProperties->transform()->hasRenderingContext()); EXPECT_FALSE(bProperties->transform()->hasRenderingContext()); + CHECK_EXACT_VISUAL_RECT(a, frameView->layoutView()); + CHECK_EXACT_VISUAL_RECT(b, frameView->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, NestedRenderingContexts) { setBodyInnerHTML( - "<div style=\"transform-style: preserve-3d\">" - " <div id=\"a\" style=\"transform: translateZ(0)\">" - " <div style=\"transform-style: preserve-3d\">" - " <div id=\"b\" style=\"transform: translateZ(0)\">" + "<div style='transform-style: preserve-3d'>" + " <div id='a' style='transform: translateZ(0); width: 50px; height: 60px'>" + " <div style='transform-style: preserve-3d; width: 30px; height: 40px'>" + " <div id='b' style='transform: translateZ(0); width: 10px; height: 20px'>" " </div>" " </div>" "</div>"); + FrameView* frameView = document().view(); - ASSERT_FALSE(document().getElementById("a")->layoutObject()->styleRef().preserves3D()); - const ObjectPaintProperties* aProperties = document().getElementById("a")->layoutObject()->objectPaintProperties(); - const ObjectPaintProperties* bProperties = document().getElementById("b")->layoutObject()->objectPaintProperties(); + LayoutObject* a = document().getElementById("a")->layoutObject(); + const ObjectPaintProperties* aProperties = a->objectPaintProperties(); + LayoutObject* b = document().getElementById("b")->layoutObject(); + const ObjectPaintProperties* bProperties = b->objectPaintProperties(); + ASSERT_FALSE(a->styleRef().preserves3D()); ASSERT_TRUE(aProperties->transform() && bProperties->transform()); // #a should participate in a rendering context (due to its parent). Its @@ -1179,6 +1326,8 @@ EXPECT_TRUE(aProperties->transform()->hasRenderingContext()); EXPECT_TRUE(bProperties->transform()->hasRenderingContext()); EXPECT_NE(aProperties->transform()->renderingContextID(), bProperties->transform()->renderingContextID()); + CHECK_EXACT_VISUAL_RECT(a, frameView->layoutView()); + CHECK_EXACT_VISUAL_RECT(b, frameView->layoutView()); } // Returns true if the first node has the second as an ancestor. @@ -1207,37 +1356,47 @@ TEST_F(PaintPropertyTreeBuilderTest, FlatTransformStylePropagatesToChildren) { setBodyInnerHTML( - "<div id=\"a\" style=\"transform: translateZ(0); transform-style: flat\">" - " <div id=\"b\" style=\"transform: translateZ(0)\"></div>" + "<div id='a' style='transform: translateZ(0); transform-style: flat; width: 30px; height: 40px'>" + " <div id='b' style='transform: translateZ(0); width: 10px; height: 10px'></div>" "</div>"); + FrameView* frameView = document().view(); - const auto* aTransform = document().getElementById("a")->layoutObject()->objectPaintProperties()->transform(); + LayoutObject* a = document().getElementById("a")->layoutObject(); + LayoutObject* b = document().getElementById("b")->layoutObject(); + const auto* aTransform = a->objectPaintProperties()->transform(); ASSERT_TRUE(aTransform); - const auto* bTransform = document().getElementById("b")->layoutObject()->objectPaintProperties()->transform(); + const auto* bTransform = b->objectPaintProperties()->transform(); ASSERT_TRUE(bTransform); ASSERT_TRUE(nodeHasAncestor(bTransform, aTransform)); // Some node must flatten the inherited transform from #a before it reaches // #b's transform. EXPECT_TRUE(someNodeFlattensTransform(bTransform, aTransform)); + CHECK_EXACT_VISUAL_RECT(a, frameView->layoutView()); + CHECK_EXACT_VISUAL_RECT(b, frameView->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, Preserve3DTransformStylePropagatesToChildren) { setBodyInnerHTML( - "<div id=\"a\" style=\"transform: translateZ(0); transform-style: preserve-3d\">" - " <div id=\"b\" style=\"transform: translateZ(0)\"></div>" + "<div id='a' style='transform: translateZ(0); transform-style: preserve-3d; width: 30px; height: 40px'>" + " <div id='b' style='transform: translateZ(0); width: 10px; height: 10px'></div>" "</div>"); + FrameView* frameView = document().view(); - const auto* aTransform = document().getElementById("a")->layoutObject()->objectPaintProperties()->transform(); + LayoutObject* a = document().getElementById("a")->layoutObject(); + LayoutObject* b = document().getElementById("b")->layoutObject(); + const auto* aTransform = a->objectPaintProperties()->transform(); ASSERT_TRUE(aTransform); - const auto* bTransform = document().getElementById("b")->layoutObject()->objectPaintProperties()->transform(); + const auto* bTransform = b->objectPaintProperties()->transform(); ASSERT_TRUE(bTransform); ASSERT_TRUE(nodeHasAncestor(bTransform, aTransform)); // No node may flatten the inherited transform from #a before it reaches // #b's transform. EXPECT_FALSE(someNodeFlattensTransform(bTransform, aTransform)); + CHECK_EXACT_VISUAL_RECT(a, frameView->layoutView()); + CHECK_EXACT_VISUAL_RECT(b, frameView->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, PerspectiveIsNotFlattened) @@ -1246,18 +1405,23 @@ // ones that combine with it preserve 3D. Otherwise, the perspective doesn't // do anything. setBodyInnerHTML( - "<div id=\"a\" style=\"perspective: 800px\">" - " <div id=\"b\" style=\"transform: translateZ(0)\"></div>" + "<div id='a' style='perspective: 800px; width: 30px; height: 40px'>" + " <div id='b' style='transform: translateZ(0); width: 10px; height: 20px'></div>" "</div>"); + FrameView* frameView = document().view(); - const ObjectPaintProperties* aProperties = document().getElementById("a")->layoutObject()->objectPaintProperties(); - const ObjectPaintProperties* bProperties = document().getElementById("b")->layoutObject()->objectPaintProperties(); + LayoutObject* a = document().getElementById("a")->layoutObject(); + LayoutObject* b = document().getElementById("b")->layoutObject(); + const ObjectPaintProperties* aProperties = a->objectPaintProperties(); + const ObjectPaintProperties* bProperties = b->objectPaintProperties(); const TransformPaintPropertyNode* aPerspective = aProperties->perspective(); ASSERT_TRUE(aPerspective); const TransformPaintPropertyNode* bTransform = bProperties->transform(); ASSERT_TRUE(bTransform); ASSERT_TRUE(nodeHasAncestor(bTransform, aPerspective)); EXPECT_FALSE(someNodeFlattensTransform(bTransform, aPerspective)); + CHECK_EXACT_VISUAL_RECT(a, frameView->layoutView()); + CHECK_EXACT_VISUAL_RECT(b, frameView->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, PerspectiveDoesNotEstablishRenderingContext) @@ -1266,28 +1430,34 @@ // ones that combine with it preserve 3D. Otherwise, the perspective doesn't // do anything. setBodyInnerHTML( - "<div id=\"a\" style=\"perspective: 800px\">" - " <div id=\"b\" style=\"transform: translateZ(0)\"></div>" + "<div id='a' style='perspective: 800px; width: 30px; height: 40px'>" + " <div id='b' style='transform: translateZ(0); width: 10px; height: 20px'></div>" "</div>"); + FrameView* frameView = document().view(); - const ObjectPaintProperties* aProperties = document().getElementById("a")->layoutObject()->objectPaintProperties(); - const ObjectPaintProperties* bProperties = document().getElementById("b")->layoutObject()->objectPaintProperties(); + LayoutObject* a = document().getElementById("a")->layoutObject(); + LayoutObject* b = document().getElementById("b")->layoutObject(); + const ObjectPaintProperties* aProperties = a->objectPaintProperties(); + const ObjectPaintProperties* bProperties = b->objectPaintProperties(); const TransformPaintPropertyNode* aPerspective = aProperties->perspective(); ASSERT_TRUE(aPerspective); EXPECT_FALSE(aPerspective->hasRenderingContext()); const TransformPaintPropertyNode* bTransform = bProperties->transform(); ASSERT_TRUE(bTransform); EXPECT_FALSE(bTransform->hasRenderingContext()); + CHECK_EXACT_VISUAL_RECT(a, frameView->layoutView()); + CHECK_EXACT_VISUAL_RECT(b, frameView->layoutView()); } TEST_F(PaintPropertyTreeBuilderTest, CachedProperties) { setBodyInnerHTML( - "<div id='a' style='transform: translate(33px, 44px)'>" - " <div id='b' style='transform: translate(55px, 66px)'>" - " <div id='c' style='transform: translate(77px, 88px)'>C<div>" + "<div id='a' style='transform: translate(33px, 44px); width: 50px; height: 60px'>" + " <div id='b' style='transform: translate(55px, 66px); width: 30px; height: 40px'>" + " <div id='c' style='transform: translate(77px, 88px); width: 10px; height: 20px'>C<div>" " </div>" "</div>"); + FrameView* frameView = document().view(); Element* a = document().getElementById("a"); const ObjectPaintProperties* aProperties = a->layoutObject()->objectPaintProperties(); @@ -1304,6 +1474,10 @@ const TransformPaintPropertyNode* cTransformNode = cProperties->transform(); EXPECT_EQ(TransformationMatrix().translate(77, 88), cTransformNode->matrix()); + CHECK_EXACT_VISUAL_RECT(a->layoutObject(), frameView->layoutView()); + CHECK_EXACT_VISUAL_RECT(b->layoutObject(), frameView->layoutView()); + CHECK_EXACT_VISUAL_RECT(c->layoutObject(), frameView->layoutView()); + // Change transform of b. B's transform node should be a new node with the new value, // and a and c's transform nodes should be unchanged (with c's parent adjusted). b->setAttribute(HTMLNames::styleAttr, "transform: translate(111px, 222px)"); @@ -1321,6 +1495,10 @@ EXPECT_EQ(cTransformNode, cProperties->transform()); EXPECT_EQ(bTransformNode, cTransformNode->parent()); + CHECK_EXACT_VISUAL_RECT(a->layoutObject(), frameView->layoutView()); + CHECK_EXACT_VISUAL_RECT(b->layoutObject(), frameView->layoutView()); + CHECK_EXACT_VISUAL_RECT(c->layoutObject(), frameView->layoutView()); + // Remove transform from b. B's transform node should be removed from the tree, // and a and c's transform nodes should be unchanged (with c's parent adjusted). b->setAttribute(HTMLNames::styleAttr, ""); @@ -1336,6 +1514,10 @@ EXPECT_EQ(cTransformNode, cProperties->transform()); EXPECT_EQ(aTransformNode, cTransformNode->parent()); + CHECK_EXACT_VISUAL_RECT(a->layoutObject(), frameView->layoutView()); + CHECK_EXACT_VISUAL_RECT(b->layoutObject(), frameView->layoutView()); + CHECK_EXACT_VISUAL_RECT(c->layoutObject(), frameView->layoutView()); + // Re-add transform to b. B's transform node should be inserted into the tree, // and a and c's transform nodes should be unchanged (with c's parent adjusted). b->setAttribute(HTMLNames::styleAttr, "transform: translate(4px, 5px)"); @@ -1352,6 +1534,10 @@ EXPECT_EQ(cProperties, c->layoutObject()->objectPaintProperties()); EXPECT_EQ(cTransformNode, cProperties->transform()); EXPECT_EQ(bTransformNode, cTransformNode->parent()); + + CHECK_EXACT_VISUAL_RECT(a->layoutObject(), frameView->layoutView()); + CHECK_EXACT_VISUAL_RECT(b->layoutObject(), frameView->layoutView()); + CHECK_EXACT_VISUAL_RECT(c->layoutObject(), frameView->layoutView()); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinter.h b/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinter.h index 148a928..3e2735f 100644 --- a/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinter.h +++ b/third_party/WebKit/Source/core/paint/PaintPropertyTreePrinter.h
@@ -5,14 +5,16 @@ #ifndef PaintPropertyTreePrinter_h #define PaintPropertyTreePrinter_h +#include "core/CoreExport.h" + #ifndef NDEBUG namespace blink { class FrameView; -void showTransformPropertyTree(const FrameView& rootFrame); -void showClipPropertyTree(const FrameView& rootFrame); -void showEffectPropertyTree(const FrameView& rootFrame); +CORE_EXPORT void showTransformPropertyTree(const FrameView& rootFrame); +CORE_EXPORT void showClipPropertyTree(const FrameView& rootFrame); +CORE_EXPORT void showEffectPropertyTree(const FrameView& rootFrame); } // namespace blink #endif
diff --git a/third_party/WebKit/Source/core/paint/PaintTiming.cpp b/third_party/WebKit/Source/core/paint/PaintTiming.cpp index 87fc0e0..c23493c 100644 --- a/third_party/WebKit/Source/core/paint/PaintTiming.cpp +++ b/third_party/WebKit/Source/core/paint/PaintTiming.cpp
@@ -51,7 +51,7 @@ return; m_firstTextPaint = monotonicallyIncreasingTime(); setFirstContentfulPaint(m_firstTextPaint); - TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing", "firstTextPaint", m_firstTextPaint, "frame", frame()); + TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing,rail", "firstTextPaint", m_firstTextPaint, "frame", frame()); notifyPaintTimingChanged(); } @@ -61,18 +61,39 @@ return; m_firstImagePaint = monotonicallyIncreasingTime(); setFirstContentfulPaint(m_firstImagePaint); - TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing", "firstImagePaint", m_firstImagePaint, "frame", frame()); + TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing,rail", "firstImagePaint", m_firstImagePaint, "frame", frame()); notifyPaintTimingChanged(); } +void PaintTiming::setFirstMeaningfulPaint(double stamp) +{ + DCHECK_EQ(m_firstMeaningfulPaint, 0.0); + m_firstMeaningfulPaint = stamp; + TRACE_EVENT_MARK_WITH_TIMESTAMP1("blink.user_timing", "firstMeaningfulPaint", m_firstMeaningfulPaint, "frame", frame()); + notifyPaintTimingChanged(); +} + +void PaintTiming::notifyPaint(bool isFirstPaint, bool textPainted, bool imagePainted) +{ + if (isFirstPaint) + markFirstPaint(); + if (textPainted) + markFirstTextPaint(); + if (imagePainted) + markFirstImagePaint(); + m_fmpDetector->notifyPaint(); +} + DEFINE_TRACE(PaintTiming) { visitor->trace(m_document); + visitor->trace(m_fmpDetector); Supplement<Document>::trace(visitor); } PaintTiming::PaintTiming(Document& document) : m_document(document) + , m_fmpDetector(new FirstMeaningfulPaintDetector(this)) { } @@ -92,7 +113,7 @@ if (m_firstPaint != 0.0) return; m_firstPaint = stamp; - TRACE_EVENT_INSTANT1("blink.user_timing", "firstPaint", TRACE_EVENT_SCOPE_PROCESS, "frame", frame()); + TRACE_EVENT_INSTANT1("blink.user_timing,rail", "firstPaint", TRACE_EVENT_SCOPE_PROCESS, "frame", frame()); } void PaintTiming::setFirstContentfulPaint(double stamp) @@ -101,7 +122,7 @@ return; setFirstPaint(stamp); m_firstContentfulPaint = stamp; - TRACE_EVENT_INSTANT1("blink.user_timing", "firstContentfulPaint", TRACE_EVENT_SCOPE_PROCESS, "frame", frame()); + TRACE_EVENT_INSTANT1("blink.user_timing,rail", "firstContentfulPaint", TRACE_EVENT_SCOPE_PROCESS, "frame", frame()); } } // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/PaintTiming.h b/third_party/WebKit/Source/core/paint/PaintTiming.h index f8e0aa24c..47993fe 100644 --- a/third_party/WebKit/Source/core/paint/PaintTiming.h +++ b/third_party/WebKit/Source/core/paint/PaintTiming.h
@@ -6,6 +6,7 @@ #define PaintTiming_h #include "core/dom/Document.h" +#include "core/paint/FirstMeaningfulPaintDetector.h" #include "platform/Supplementable.h" #include "platform/heap/Handle.h" #include "wtf/Noncopyable.h" @@ -16,7 +17,7 @@ // PaintTiming is responsible for tracking paint-related timings for a given // document. -class PaintTiming final : public GarbageCollectedFinalized<PaintTiming>, public Supplement<Document> { +class CORE_EXPORT PaintTiming final : public GarbageCollectedFinalized<PaintTiming>, public Supplement<Document> { WTF_MAKE_NONCOPYABLE(PaintTiming); USING_GARBAGE_COLLECTED_MIXIN(PaintTiming); public: @@ -39,6 +40,9 @@ void markFirstTextPaint(); void markFirstImagePaint(); + void setFirstMeaningfulPaint(double stamp); + void notifyPaint(bool isFirstPaint, bool textPainted, bool imagePainted); + // The getters below return monotonically-increasing seconds, or zero if the // given paint event has not yet occurred. See the comments for // monotonicallyIncreasingTime in wtf/CurrentTime.h for additional details. @@ -58,6 +62,13 @@ // firstImagePaint returns the first time that image content was painted. double firstImagePaint() const { return m_firstImagePaint; } + // firstMeaningfulPaint returns the first time that page's primary content + // was painted. + double firstMeaningfulPaint() const { return m_firstMeaningfulPaint; } + + Document* document() { return m_document.get(); } + FirstMeaningfulPaintDetector& firstMeaningfulPaintDetector() { return *m_fmpDetector; } + DECLARE_VIRTUAL_TRACE(); private: @@ -81,8 +92,10 @@ double m_firstTextPaint = 0.0; double m_firstImagePaint = 0.0; double m_firstContentfulPaint = 0.0; + double m_firstMeaningfulPaint = 0.0; Member<Document> m_document; + Member<FirstMeaningfulPaintDetector> m_fmpDetector; }; } // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp b/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp index be81d3c..12bdc0a 100644 --- a/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp +++ b/third_party/WebKit/Source/core/paint/PrePaintTreeWalk.cpp
@@ -14,14 +14,14 @@ namespace blink { struct PrePaintTreeWalkContext { - PrePaintTreeWalkContext() { } - PrePaintTreeWalkContext(const PaintPropertyTreeBuilderContext& parentTreeBuilderContext) - : treeBuilderContext(parentTreeBuilderContext) { } + PrePaintTreeWalkContext() : paintInvalidatorContext(treeBuilderContext) { } + PrePaintTreeWalkContext(const PrePaintTreeWalkContext& parentContext) + : treeBuilderContext(parentContext.treeBuilderContext) + , paintInvalidatorContext(treeBuilderContext, parentContext.paintInvalidatorContext) + { } PaintPropertyTreeBuilderContext treeBuilderContext; - // This will be initialized by PaintInvalidator::invalidatePaintIfNeeded(). - // TODO(wangxianzhu): Change to copy-and-update pattern like PaintPropertyTreeBuilderContext. - Optional<PaintInvalidatorContext> paintInvalidatorContext; + PaintInvalidatorContext paintInvalidatorContext; }; void PrePaintTreeWalk::walk(FrameView& rootFrame) @@ -36,11 +36,11 @@ void PrePaintTreeWalk::walk(FrameView& frameView, const PrePaintTreeWalkContext& context) { - PrePaintTreeWalkContext localContext(context.treeBuilderContext); + PrePaintTreeWalkContext localContext(context); m_propertyTreeBuilder.buildTreeNodes(frameView, localContext.treeBuilderContext); if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) - m_paintInvalidator.invalidatePaintIfNeeded(frameView, localContext.treeBuilderContext, localContext.paintInvalidatorContext); + m_paintInvalidator.invalidatePaintIfNeeded(frameView, localContext.paintInvalidatorContext); if (LayoutView* layoutView = frameView.layoutView()) walk(*layoutView, localContext); @@ -48,11 +48,11 @@ void PrePaintTreeWalk::walk(const LayoutObject& object, const PrePaintTreeWalkContext& context) { - PrePaintTreeWalkContext localContext(context.treeBuilderContext); + PrePaintTreeWalkContext localContext(context); m_propertyTreeBuilder.buildTreeNodes(object, localContext.treeBuilderContext); - if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() && context.paintInvalidatorContext) - m_paintInvalidator.invalidatePaintIfNeeded(object, localContext.treeBuilderContext, *context.paintInvalidatorContext, localContext.paintInvalidatorContext); + if (RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) + m_paintInvalidator.invalidatePaintIfNeeded(object, localContext.paintInvalidatorContext); for (const LayoutObject* child = object.slowFirstChild(); child; child = child->nextSibling()) { // Column spanners are walked through their placeholders. See below.
diff --git a/third_party/WebKit/Source/core/paint/SVGModelObjectPaintInvalidator.cpp b/third_party/WebKit/Source/core/paint/SVGModelObjectPaintInvalidator.cpp new file mode 100644 index 0000000..567e24b --- /dev/null +++ b/third_party/WebKit/Source/core/paint/SVGModelObjectPaintInvalidator.cpp
@@ -0,0 +1,25 @@ +// Copyright 2016 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 "core/paint/SVGModelObjectPaintInvalidator.h" + +#include "core/layout/svg/LayoutSVGModelObject.h" +#include "core/paint/ObjectPaintInvalidator.h" + +namespace blink { + +PaintInvalidationReason SVGModelObjectPaintInvalidator::invalidatePaintIfNeeded() +{ + PaintInvalidationReason reason = ObjectPaintInvalidator(m_object, m_context).computePaintInvalidationReason(); + + // Disable incremental invalidation for SVG objects to prevent under- + // invalidation. Unlike boxes, it is non-trivial (and rare) for SVG objects + // to be able to be incrementally invalidated (e.g., on height changes). + if (reason == PaintInvalidationIncremental) + reason = PaintInvalidationFull; + + return ObjectPaintInvalidator(m_object, m_context).invalidatePaintIfNeededWithComputedReason(reason); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/SVGModelObjectPaintInvalidator.h b/third_party/WebKit/Source/core/paint/SVGModelObjectPaintInvalidator.h new file mode 100644 index 0000000..367e2a0 --- /dev/null +++ b/third_party/WebKit/Source/core/paint/SVGModelObjectPaintInvalidator.h
@@ -0,0 +1,31 @@ +// Copyright 2016 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 SVGModelObjectPaintInvalidator_h +#define SVGModelObjectPaintInvalidator_h + +#include "platform/graphics/PaintInvalidationReason.h" +#include "wtf/Allocator.h" + +namespace blink { + +class LayoutSVGModelObject; +struct PaintInvalidatorContext; + +class SVGModelObjectPaintInvalidator { + STACK_ALLOCATED(); +public: + SVGModelObjectPaintInvalidator(const LayoutSVGModelObject& object, const PaintInvalidatorContext& context) + : m_object(object), m_context(context) { } + + PaintInvalidationReason invalidatePaintIfNeeded(); + +private: + const LayoutSVGModelObject& m_object; + const PaintInvalidatorContext& m_context; +}; + +} // namespace blink + +#endif
diff --git a/third_party/WebKit/Source/core/paint/TablePaintInvalidator.cpp b/third_party/WebKit/Source/core/paint/TablePaintInvalidator.cpp new file mode 100644 index 0000000..2d356fc --- /dev/null +++ b/third_party/WebKit/Source/core/paint/TablePaintInvalidator.cpp
@@ -0,0 +1,68 @@ +// Copyright 2016 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 "core/paint/TablePaintInvalidator.h" + +#include "core/layout/LayoutTable.h" +#include "core/layout/LayoutTableCell.h" +#include "core/layout/LayoutTableCol.h" +#include "core/layout/LayoutTableRow.h" +#include "core/layout/LayoutTableSection.h" +#include "core/paint/BoxPaintInvalidator.h" +#include "core/paint/PaintInvalidator.h" + +namespace blink { + +PaintInvalidationReason TablePaintInvalidator::invalidatePaintIfNeeded() +{ + PaintInvalidationReason reason = BoxPaintInvalidator(m_table, m_context).invalidatePaintIfNeeded(); + + // Table cells paint background from the containing column group, column, section and row. + // If background of any of them changed, we need to invalidate all affected cells. + // Here use shouldDoFullPaintInvalidation() as a broader condition of background change. + + // If any col changed background, we'll check all cells for background changes. + bool hasColChangedBackground = false; + for (LayoutTableCol* col = m_table.firstColumn(); col; col = col->nextColumn()) { + if (col->backgroundChangedSinceLastPaintInvalidation()) { + hasColChangedBackground = true; + break; + } + } + for (LayoutObject* child = m_table.firstChild(); child; child = child->nextSibling()) { + if (!child->isTableSection()) + continue; + LayoutTableSection* section = toLayoutTableSection(child); + if (!hasColChangedBackground && !section->shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()) + continue; + for (LayoutTableRow* row = section->firstRow(); row; row = row->nextRow()) { + if (!hasColChangedBackground && !section->backgroundChangedSinceLastPaintInvalidation() && !row->backgroundChangedSinceLastPaintInvalidation()) + continue; + for (LayoutTableCell* cell = row->firstCell(); cell; cell = cell->nextCell()) { + bool invalidated = false; + // Table cells paint container's background on the container's backing instead of its own (if any), + // so we must invalidate it by the containers. + if (section->backgroundChangedSinceLastPaintInvalidation()) { + section->slowSetPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient(*cell, PaintInvalidationStyleChange); + invalidated = true; + } else if (hasColChangedBackground) { + LayoutTable::ColAndColGroup colAndColGroup = m_table.colElementAtAbsoluteColumn(cell->absoluteColumnIndex()); + LayoutTableCol* column = colAndColGroup.col; + LayoutTableCol* columnGroup = colAndColGroup.colgroup; + if ((columnGroup && columnGroup->backgroundChangedSinceLastPaintInvalidation()) + || (column && column->backgroundChangedSinceLastPaintInvalidation())) { + section->slowSetPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient(*cell, PaintInvalidationStyleChange); + invalidated = true; + } + } + if ((!invalidated || row->hasSelfPaintingLayer()) && row->backgroundChangedSinceLastPaintInvalidation()) + row->slowSetPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient(*cell, PaintInvalidationStyleChange); + } + } + } + + return reason; +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/core/paint/TablePaintInvalidator.h b/third_party/WebKit/Source/core/paint/TablePaintInvalidator.h new file mode 100644 index 0000000..11020f1 --- /dev/null +++ b/third_party/WebKit/Source/core/paint/TablePaintInvalidator.h
@@ -0,0 +1,31 @@ +// Copyright 2016 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 TablePaintInvalidator_h +#define TablePaintInvalidator_h + +#include "platform/graphics/PaintInvalidationReason.h" +#include "wtf/Allocator.h" + +namespace blink { + +class LayoutTable; +struct PaintInvalidatorContext; + +class TablePaintInvalidator { + STACK_ALLOCATED(); +public: + TablePaintInvalidator(const LayoutTable& table, const PaintInvalidatorContext& context) + : m_table(table), m_context(context) { } + + PaintInvalidationReason invalidatePaintIfNeeded(); + +private: + const LayoutTable& m_table; + const PaintInvalidatorContext& m_context; +}; + +} // namespace blink + +#endif
diff --git a/third_party/WebKit/Source/core/paint/TableSectionPainter.cpp b/third_party/WebKit/Source/core/paint/TableSectionPainter.cpp index 7d12fba..d7388880 100644 --- a/third_party/WebKit/Source/core/paint/TableSectionPainter.cpp +++ b/third_party/WebKit/Source/core/paint/TableSectionPainter.cpp
@@ -45,7 +45,11 @@ LayoutUnit pageHeight = table->pageLogicalHeightForOffset(LayoutUnit()); // Move paginationOffset to the top of the next page. - LayoutUnit offsetToNextPage = pageHeight - intMod(table->pageLogicalOffset(), pageHeight); + // The header may have a pagination strut before it so we need to account for that when establishing its position. + LayoutUnit headerGroupOffset = table->pageLogicalOffset(); + if (LayoutTableRow* row = m_layoutTableSection.firstRow()) + headerGroupOffset += m_layoutTableSection.paginationStrutForRow(row, table->pageLogicalOffset()); + LayoutUnit offsetToNextPage = pageHeight - intMod(headerGroupOffset, pageHeight); paginationOffset.move(0, offsetToNextPage); // Now move paginationOffset to the top of the page the cull rect starts on. if (paintInfo.cullRect().m_rect.y() > paginationOffset.y())
diff --git a/third_party/WebKit/Source/core/paint/test_data/perspective.html b/third_party/WebKit/Source/core/paint/test_data/perspective.html index afe386b..bbf1dfb 100644 --- a/third_party/WebKit/Source/core/paint/test_data/perspective.html +++ b/third_party/WebKit/Source/core/paint/test_data/perspective.html
@@ -10,6 +10,8 @@ #inner { transform: translateZ(0); + width: 100px; + height: 200px; } </style> <div id="perspective">
diff --git a/third_party/WebKit/Source/core/paint/test_data/position-and-scroll.html b/third_party/WebKit/Source/core/paint/test_data/position-and-scroll.html index 22bdf638..375dd51 100644 --- a/third_party/WebKit/Source/core/paint/test_data/position-and-scroll.html +++ b/third_party/WebKit/Source/core/paint/test_data/position-and-scroll.html
@@ -20,6 +20,8 @@ position: relative; left: 560px; top: 780px; + width: 100px; + height: 200px; transform: translateZ(0); overflow: hidden; @@ -29,6 +31,8 @@ position: absolute; left: 123px; top: 456px; + width: 300px; + height: 400px; transform: translateZ(0); overflow: hidden;
diff --git a/third_party/WebKit/Source/core/paint/test_data/relative-position-inline.html b/third_party/WebKit/Source/core/paint/test_data/relative-position-inline.html index da72894..2828d4d 100644 --- a/third_party/WebKit/Source/core/paint/test_data/relative-position-inline.html +++ b/third_party/WebKit/Source/core/paint/test_data/relative-position-inline.html
@@ -14,6 +14,8 @@ position: relative; left: 12px; top: 34px; + width: 10px; + height: 20px; transform: translateZ(0); }
diff --git a/third_party/WebKit/Source/core/svg/SVGAnimateMotionElement.cpp b/third_party/WebKit/Source/core/svg/SVGAnimateMotionElement.cpp index ef0945c..e4af68d 100644 --- a/third_party/WebKit/Source/core/svg/SVGAnimateMotionElement.cpp +++ b/third_party/WebKit/Source/core/svg/SVGAnimateMotionElement.cpp
@@ -117,7 +117,7 @@ for (SVGMPathElement* mpath = Traversal<SVGMPathElement>::firstChild(*this); mpath; mpath = Traversal<SVGMPathElement>::nextSibling(*mpath)) { if (SVGPathElement* pathElement = mpath->pathElement()) { - m_animationPath = pathElement->asPath(); + m_animationPath = pathElement->attributePath(); foundMPath = true; break; }
diff --git a/third_party/WebKit/Source/core/svg/SVGPathElement.cpp b/third_party/WebKit/Source/core/svg/SVGPathElement.cpp index d2ef654..22631de 100644 --- a/third_party/WebKit/Source/core/svg/SVGPathElement.cpp +++ b/third_party/WebKit/Source/core/svg/SVGPathElement.cpp
@@ -70,6 +70,11 @@ DEFINE_NODE_FACTORY(SVGPathElement) +Path SVGPathElement::attributePath() const +{ + return m_path->currentValue()->stylePath()->path(); +} + const StylePath* SVGPathElement::stylePath() const { if (LayoutObject* layoutObject = this->layoutObject()) {
diff --git a/third_party/WebKit/Source/core/svg/SVGPathElement.h b/third_party/WebKit/Source/core/svg/SVGPathElement.h index 70779ef1..9e0d0e55 100644 --- a/third_party/WebKit/Source/core/svg/SVGPathElement.h +++ b/third_party/WebKit/Source/core/svg/SVGPathElement.h
@@ -37,6 +37,7 @@ DECLARE_NODE_FACTORY(SVGPathElement); Path asPath() const override; + Path attributePath() const; float getTotalLength(); SVGPointTearOff* getPointAtLength(float distance);
diff --git a/third_party/WebKit/Source/core/svg/SVGSVGElement.idl b/third_party/WebKit/Source/core/svg/SVGSVGElement.idl index ed8bc3e..4a662bf 100644 --- a/third_party/WebKit/Source/core/svg/SVGSVGElement.idl +++ b/third_party/WebKit/Source/core/svg/SVGSVGElement.idl
@@ -28,7 +28,7 @@ [MeasureAs=SVG1DOMSVGElement] readonly attribute SVGAnimatedLength width; [MeasureAs=SVG1DOMSVGElement] readonly attribute SVGAnimatedLength height; // TODO(foolip): viewport should be a DOMRectReadOnly. - [Measure] readonly attribute SVGRect viewport; + [DeprecateAs=V8SVGSVGElement_Viewport_AttributeGetter] readonly attribute SVGRect viewport; // TODO(foolip): useCurrentView and currentView have been removed: // https://github.com/w3c/svgwg/commit/4c26fd36937a65192024208d85c144a21071b057 [DeprecateAs=V8SVGSVGElement_UseCurrentView_AttributeGetter] readonly attribute boolean useCurrentView;
diff --git a/third_party/WebKit/Source/core/testing/InternalSettings.cpp b/third_party/WebKit/Source/core/testing/InternalSettings.cpp index 70ef482c..0010d9b2 100644 --- a/third_party/WebKit/Source/core/testing/InternalSettings.cpp +++ b/third_party/WebKit/Source/core/testing/InternalSettings.cpp
@@ -70,7 +70,6 @@ , m_imagesEnabled(settings->imagesEnabled()) , m_defaultVideoPosterURL(settings->defaultVideoPosterURL()) , m_originalLayerSquashingEnabled(settings->layerSquashingEnabled()) - , m_originalImageColorProfilesEnabled(RuntimeEnabledFeatures::imageColorProfilesEnabled()) , m_originalImageAnimationPolicy(settings->imageAnimationPolicy()) , m_originalScrollTopLeftInteropEnabled(RuntimeEnabledFeatures::scrollTopLeftInteropEnabled()) , m_originalCompositorWorkerEnabled(RuntimeEnabledFeatures::compositorWorkerEnabled()) @@ -94,7 +93,6 @@ settings->setImagesEnabled(m_imagesEnabled); settings->setDefaultVideoPosterURL(m_defaultVideoPosterURL); settings->genericFontFamilySettings().reset(); - RuntimeEnabledFeatures::setImageColorProfilesEnabled(m_originalImageColorProfilesEnabled); settings->setImageAnimationPolicy(m_originalImageAnimationPolicy); RuntimeEnabledFeatures::setScrollTopLeftInteropEnabled(m_originalScrollTopLeftInteropEnabled); RuntimeEnabledFeatures::setCompositorWorkerEnabled(m_originalCompositorWorkerEnabled); @@ -160,11 +158,6 @@ RuntimeEnabledFeatures::setExperimentalContentSecurityPolicyFeaturesEnabled(enabled); } -void InternalSettings::setImageColorProfilesEnabled(bool enabled) -{ - RuntimeEnabledFeatures::setImageColorProfilesEnabled(enabled); -} - void InternalSettings::setOverlayScrollbarsEnabled(bool enabled) { RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(enabled);
diff --git a/third_party/WebKit/Source/core/testing/InternalSettings.h b/third_party/WebKit/Source/core/testing/InternalSettings.h index 4b3abab..d6a62c17 100644 --- a/third_party/WebKit/Source/core/testing/InternalSettings.h +++ b/third_party/WebKit/Source/core/testing/InternalSettings.h
@@ -70,7 +70,6 @@ bool m_imagesEnabled; String m_defaultVideoPosterURL; bool m_originalLayerSquashingEnabled; - bool m_originalImageColorProfilesEnabled; ImageAnimationPolicy m_originalImageAnimationPolicy; bool m_originalScrollTopLeftInteropEnabled; bool m_originalCompositorWorkerEnabled; @@ -116,7 +115,6 @@ void setLangAttributeAwareFormControlUIEnabled(bool); void setOverlayScrollbarsEnabled(bool); void setExperimentalContentSecurityPolicyFeaturesEnabled(bool); - void setImageColorProfilesEnabled(bool); void setImageAnimationPolicy(const String&, ExceptionState&); void setScrollTopLeftInteropEnabled(bool);
diff --git a/third_party/WebKit/Source/core/testing/InternalSettings.idl b/third_party/WebKit/Source/core/testing/InternalSettings.idl index d46cc85d..391cd82c 100644 --- a/third_party/WebKit/Source/core/testing/InternalSettings.idl +++ b/third_party/WebKit/Source/core/testing/InternalSettings.idl
@@ -62,6 +62,5 @@ void setLangAttributeAwareFormControlUIEnabled(boolean enabled); void setOverlayScrollbarsEnabled(boolean enabled); void setExperimentalContentSecurityPolicyFeaturesEnabled(boolean enabled); - void setImageColorProfilesEnabled(boolean enabled); void setScrollTopLeftInteropEnabled(boolean enabled); };
diff --git a/third_party/WebKit/Source/core/testing/Internals.cpp b/third_party/WebKit/Source/core/testing/Internals.cpp index 618dd6a..b00e87e 100644 --- a/third_party/WebKit/Source/core/testing/Internals.cpp +++ b/third_party/WebKit/Source/core/testing/Internals.cpp
@@ -137,7 +137,6 @@ #include "platform/geometry/LayoutRect.h" #include "platform/graphics/GraphicsLayer.h" #include "platform/heap/Handle.h" -#include "platform/inspector_protocol/FrontendChannel.h" #include "platform/scroll/ProgrammaticScrollAnimator.h" #include "platform/weborigin/SchemeRegistry.h" #include "public/platform/Platform.h"
diff --git a/third_party/WebKit/Source/core/timing/PerformanceTiming.cpp b/third_party/WebKit/Source/core/timing/PerformanceTiming.cpp index 4f7cb4c..fe97e37 100644 --- a/third_party/WebKit/Source/core/timing/PerformanceTiming.cpp +++ b/third_party/WebKit/Source/core/timing/PerformanceTiming.cpp
@@ -361,6 +361,15 @@ return monotonicTimeToIntegerMilliseconds(timing->firstContentfulPaint()); } +unsigned long long PerformanceTiming::firstMeaningfulPaint() const +{ + const PaintTiming* timing = paintTiming(); + if (!timing) + return 0; + + return monotonicTimeToIntegerMilliseconds(timing->firstMeaningfulPaint()); +} + unsigned long long PerformanceTiming::parseStart() const { const DocumentParserTiming* timing = documentParserTiming();
diff --git a/third_party/WebKit/Source/core/timing/PerformanceTiming.h b/third_party/WebKit/Source/core/timing/PerformanceTiming.h index 2ebabc9..2238a1bf 100644 --- a/third_party/WebKit/Source/core/timing/PerformanceTiming.h +++ b/third_party/WebKit/Source/core/timing/PerformanceTiming.h
@@ -92,6 +92,9 @@ // The time of the first 'contentful' paint. A contentful paint is a paint // that includes content of some kind (for example, text or image content). unsigned long long firstContentfulPaint() const; + // The time of the first 'meaningful' paint, A meaningful paint is a paint + // where the page's primary content is visible. + unsigned long long firstMeaningfulPaint() const; unsigned long long parseStart() const; unsigned long long parseStop() const;
diff --git a/third_party/WebKit/Source/core/workers/WorkerScriptLoader.h b/third_party/WebKit/Source/core/workers/WorkerScriptLoader.h index 58131ad..59fe7583 100644 --- a/third_party/WebKit/Source/core/workers/WorkerScriptLoader.h +++ b/third_party/WebKit/Source/core/workers/WorkerScriptLoader.h
@@ -114,7 +114,7 @@ std::unique_ptr<WTF::Closure> m_responseCallback; std::unique_ptr<WTF::Closure> m_finishedCallback; - std::unique_ptr<ThreadableLoader> m_threadableLoader; + Persistent<ThreadableLoader> m_threadableLoader; String m_responseEncoding; std::unique_ptr<TextResourceDecoder> m_decoder; StringBuilder m_script;
diff --git a/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.cpp b/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.cpp index 7525edd..aea42d3f 100644 --- a/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.cpp +++ b/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.cpp
@@ -36,6 +36,7 @@ #include "core/dom/Comment.h" #include "core/dom/Document.h" #include "core/dom/DocumentFragment.h" +#include "core/dom/DocumentParserTiming.h" #include "core/dom/DocumentType.h" #include "core/dom/ProcessingInstruction.h" #include "core/dom/ScriptLoader.h" @@ -399,6 +400,7 @@ if (m_pendingScript) { m_pendingScript->removeClient(this); m_pendingScript = nullptr; + m_parserBlockingPendingScriptLoadStartTime = 0.0; } clearCurrentNodeStack(); ScriptableDocumentParser::detach(); @@ -462,6 +464,8 @@ ScriptSourceCode sourceCode(m_pendingScript.get()); bool errorOccurred = m_pendingScript->errorOccurred(); bool wasCanceled = m_pendingScript->wasCanceled(); + double scriptParserBlockingTime = m_parserBlockingPendingScriptLoadStartTime; + m_parserBlockingPendingScriptLoadStartTime = 0.0; m_pendingScript->removeClient(this); m_pendingScript = nullptr; @@ -475,6 +479,10 @@ if (errorOccurred) { scriptLoader->dispatchErrorEvent(); } else if (!wasCanceled) { + if (scriptParserBlockingTime > 0.0) { + DocumentParserTiming::from(*document()).recordParserBlockedOnScriptLoadDuration(monotonicallyIncreasingTime() - scriptParserBlockingTime, scriptLoader->wasCreatedDuringDocumentWrite()); + } + if (!scriptLoader->executeScript(sourceCode)) scriptLoader->dispatchErrorEvent(); else @@ -777,6 +785,7 @@ , m_finishCalled(false) , m_xmlErrors(&document) , m_scriptStartPosition(TextPosition::belowRangePosition()) + , m_parserBlockingPendingScriptLoadStartTime(0.0) , m_parsingFragment(false) { // This is XML being used as a document resource. @@ -1093,6 +1102,8 @@ } } else if (scriptLoader->willBeParserExecuted()) { m_pendingScript = scriptLoader->resource(); + DCHECK_EQ(m_parserBlockingPendingScriptLoadStartTime, 0.0); + m_parserBlockingPendingScriptLoadStartTime = monotonicallyIncreasingTime(); m_scriptElement = element; m_pendingScript->addClient(this); // m_pendingScript will be 0 if script was already loaded and
diff --git a/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.h b/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.h index 8a21eb1..987b332 100644 --- a/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.h +++ b/third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.h
@@ -188,6 +188,7 @@ Member<ScriptResource> m_pendingScript; Member<Element> m_scriptElement; TextPosition m_scriptStartPosition; + double m_parserBlockingPendingScriptLoadStartTime; bool m_parsingFragment; AtomicString m_defaultNamespaceURI;
diff --git a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp index ce55746..106d51f3 100644 --- a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp +++ b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.cpp
@@ -65,11 +65,11 @@ #include "platform/FileMetadata.h" #include "platform/HTTPNames.h" #include "platform/Histogram.h" -#include "platform/Logging.h" #include "platform/RuntimeEnabledFeatures.h" #include "platform/SharedBuffer.h" #include "platform/blob/BlobData.h" #include "platform/network/HTTPParsers.h" +#include "platform/network/NetworkLog.h" #include "platform/network/ParsedContentType.h" #include "platform/network/ResourceError.h" #include "platform/network/ResourceRequest.h" @@ -552,7 +552,7 @@ void XMLHttpRequest::open(const AtomicString& method, const KURL& url, bool async, ExceptionState& exceptionState) { - WTF_LOG(Network, "XMLHttpRequest %p open('%s', '%s', %d)", this, method.utf8().data(), url.elidedString().utf8().data(), async); + NETWORK_DVLOG(1) << this << " open(" << method << ", " << url.elidedString() << ", " << async << ")"; if (!internalAbort()) return; @@ -685,7 +685,7 @@ void XMLHttpRequest::send(Document* document, ExceptionState& exceptionState) { - WTF_LOG(Network, "XMLHttpRequest %p send() Document %p", this, document); + NETWORK_DVLOG(1) << this << " send() Document " << static_cast<void*>(document); ASSERT(document); @@ -711,7 +711,7 @@ void XMLHttpRequest::send(const String& body, ExceptionState& exceptionState) { - WTF_LOG(Network, "XMLHttpRequest %p send() String '%s'", this, body.utf8().data()); + NETWORK_DVLOG(1) << this << " send() String " << body; if (!initSend(exceptionState)) return; @@ -735,7 +735,7 @@ void XMLHttpRequest::send(Blob* body, ExceptionState& exceptionState) { - WTF_LOG(Network, "XMLHttpRequest %p send() Blob '%s'", this, body->uuid().utf8().data()); + NETWORK_DVLOG(1) << this << " send() Blob " << body->uuid(); if (!initSend(exceptionState)) return; @@ -770,7 +770,7 @@ void XMLHttpRequest::send(FormData* body, ExceptionState& exceptionState) { - WTF_LOG(Network, "XMLHttpRequest %p send() FormData %p", this, body); + NETWORK_DVLOG(1) << this << " send() FormData " << body; if (!initSend(exceptionState)) return; @@ -791,14 +791,14 @@ void XMLHttpRequest::send(DOMArrayBuffer* body, ExceptionState& exceptionState) { - WTF_LOG(Network, "XMLHttpRequest %p send() ArrayBuffer %p", this, body); + NETWORK_DVLOG(1) << this << " send() ArrayBuffer " << body; sendBytesData(body->data(), body->byteLength(), exceptionState); } void XMLHttpRequest::send(DOMArrayBufferView* body, ExceptionState& exceptionState) { - WTF_LOG(Network, "XMLHttpRequest %p send() ArrayBufferView %p", this, body); + NETWORK_DVLOG(1) << this << " send() ArrayBufferView " << body; sendBytesData(body->baseAddress(), body->byteLength(), exceptionState); } @@ -941,7 +941,7 @@ void XMLHttpRequest::abort() { - WTF_LOG(Network, "XMLHttpRequest %p abort()", this); + NETWORK_DVLOG(1) << this << " abort()"; // internalAbort() clears |m_loader|. Compute |sendFlag| now. // @@ -1020,7 +1020,7 @@ // If, window.onload contains open() and send(), m_loader will be set to // non 0 value. So, we cannot continue the outer open(). In such case, // just abort the outer open() by returning false. - std::unique_ptr<ThreadableLoader> loader = std::move(m_loader); + ThreadableLoader* loader = m_loader.release(); loader->cancel(); // If abort() called internalAbort() and a nested open() ended up @@ -1084,7 +1084,7 @@ void XMLHttpRequest::handleNetworkError() { - WTF_LOG(Network, "XMLHttpRequest %p handleNetworkError()", this); + NETWORK_DVLOG(1) << this << " handleNetworkError()"; // Response is cleared next, save needed progress event data. long long expectedLength = m_response.expectedContentLength(); @@ -1098,7 +1098,7 @@ void XMLHttpRequest::handleDidCancel() { - WTF_LOG(Network, "XMLHttpRequest %p handleDidCancel()", this); + NETWORK_DVLOG(1) << this << " handleDidCancel()"; // Response is cleared next, save needed progress event data. long long expectedLength = m_response.expectedContentLength(); @@ -1112,7 +1112,7 @@ void XMLHttpRequest::handleRequestError(ExceptionCode exceptionCode, const AtomicString& type, long long receivedLength, long long expectedLength) { - WTF_LOG(Network, "XMLHttpRequest %p handleRequestError()", this); + NETWORK_DVLOG(1) << this << " handleRequestError()"; InspectorInstrumentation::didFailXHRLoading(getExecutionContext(), this, this, m_method, m_url); @@ -1327,7 +1327,7 @@ void XMLHttpRequest::didFail(const ResourceError& error) { - WTF_LOG(Network, "XMLHttpRequest %p didFail()", this); + NETWORK_DVLOG(1) << this << " didFail()"; ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel); // If we are already in an error state, for instance we called abort(), bail out early. @@ -1356,7 +1356,7 @@ void XMLHttpRequest::didFailRedirectCheck() { - WTF_LOG(Network, "XMLHttpRequest %p didFailRedirectCheck()", this); + NETWORK_DVLOG(1) << this << " didFailRedirectCheck()"; ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel); handleNetworkError(); @@ -1365,7 +1365,7 @@ void XMLHttpRequest::didFinishLoading(unsigned long identifier, double) { - WTF_LOG(Network, "XMLHttpRequest %p didFinishLoading(%lu)", this, identifier); + NETWORK_DVLOG(1) << this << " didFinishLoading(" << identifier << ")"; ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel); if (m_error) @@ -1414,7 +1414,7 @@ void XMLHttpRequest::didFinishLoadingFromBlob() { - WTF_LOG(Network, "XMLHttpRequest %p didFinishLoadingFromBlob", this); + NETWORK_DVLOG(1) << this << " didFinishLoadingFromBlob"; ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel); didFinishLoadingInternal(); @@ -1422,7 +1422,7 @@ void XMLHttpRequest::didFailLoadingFromBlob() { - WTF_LOG(Network, "XMLHttpRequest %p didFailLoadingFromBlob()", this); + NETWORK_DVLOG(1) << this << " didFailLoadingFromBlob()"; ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel); if (m_error) @@ -1492,7 +1492,7 @@ void XMLHttpRequest::didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) { - WTF_LOG(Network, "XMLHttpRequest %p didSendData(%llu, %llu)", this, bytesSent, totalBytesToBeSent); + NETWORK_DVLOG(1) << this << " didSendData(" << bytesSent << ", " << totalBytesToBeSent << ")"; ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel); if (!m_upload) @@ -1511,7 +1511,7 @@ void XMLHttpRequest::didReceiveResponse(unsigned long identifier, const ResourceResponse& response, std::unique_ptr<WebDataConsumerHandle> handle) { ASSERT_UNUSED(handle, !handle); - WTF_LOG(Network, "XMLHttpRequest %p didReceiveResponse(%lu)", this, identifier); + NETWORK_DVLOG(1) << this << " didReceiveResponse(" << identifier << ")"; ScopedEventDispatchProtect protect(&m_eventDispatchRecursionLevel); m_response = response; @@ -1641,7 +1641,7 @@ void XMLHttpRequest::handleDidTimeout() { - WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this); + NETWORK_DVLOG(1) << this << " handleDidTimeout()"; // Response is cleared next, save needed progress event data. long long expectedLength = m_response.expectedContentLength(); @@ -1703,6 +1703,7 @@ { visitor->trace(m_responseBlob); visitor->trace(m_responseLegacyStream); + visitor->trace(m_loader); visitor->trace(m_responseDocument); visitor->trace(m_responseDocumentParser); visitor->trace(m_responseArrayBuffer); @@ -1722,4 +1723,9 @@ visitor->traceWrappers(m_responseArrayBuffer); } +std::ostream& operator<<(std::ostream& ostream, const XMLHttpRequest* xhr) +{ + return ostream << "XMLHttpRequest " << static_cast<const void*>(xhr); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.h b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.h index 526d9283b..d8f6862 100644 --- a/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.h +++ b/third_party/WebKit/Source/core/xmlhttprequest/XMLHttpRequest.h
@@ -265,7 +265,7 @@ Member<Blob> m_responseBlob; Member<Stream> m_responseLegacyStream; - std::unique_ptr<ThreadableLoader> m_loader; + Member<ThreadableLoader> m_loader; State m_state; ResourceResponse m_response; @@ -320,6 +320,8 @@ bool m_responseTextOverflow; }; +std::ostream& operator<<(std::ostream&, const XMLHttpRequest*); + } // namespace blink #endif // XMLHttpRequest_h
diff --git a/third_party/WebKit/Source/devtools/devtools.gypi b/third_party/WebKit/Source/devtools/devtools.gypi index 330a1e6..448a98e 100644 --- a/third_party/WebKit/Source/devtools/devtools.gypi +++ b/third_party/WebKit/Source/devtools/devtools.gypi
@@ -662,7 +662,6 @@ 'front_end/source_frame/TextEditorAutocompleteController.js', ], 'devtools_sources_js_files': [ - 'front_end/sources/addSourceMapURLDialog.css', 'front_end/sources/navigatorView.css', 'front_end/sources/revisionHistory.css', 'front_end/sources/serviceWorkersSidebar.css', @@ -747,6 +746,7 @@ ], 'devtools_ui_lazy_js_files': [ 'front_end/ui_lazy/dataGrid.css', + 'front_end/ui_lazy/dialog.css', 'front_end/ui_lazy/filteredListWidget.css', 'front_end/ui_lazy/flameChart.css', 'front_end/ui_lazy/overviewGrid.css', @@ -880,16 +880,12 @@ 'front_end/Images/resourcesTimeGraphIcon.png', 'front_end/Images/searchNext.png', 'front_end/Images/searchPrev.png', - 'front_end/Images/securityPropertyInfo.svg', - 'front_end/Images/securityPropertyInsecure.svg', - 'front_end/Images/securityPropertySecure.svg', - 'front_end/Images/securityPropertyWarning.svg', - 'front_end/Images/securityPropertyUnknown.svg', - 'front_end/Images/securityStateInsecure.svg', - 'front_end/Images/securityStateNeutral.svg', - 'front_end/Images/securityStateSecure.svg', + 'front_end/Images/securityIcons_2x.png', + 'front_end/Images/securityIcons.png', 'front_end/Images/settingsListRemove.png', 'front_end/Images/settingsListRemove_2x.png', + 'front_end/Images/smallIcons.png', + 'front_end/Images/smallIcons_2x.png', 'front_end/Images/speech.png', 'front_end/Images/toolbarButtonGlyphs.png', 'front_end/Images/toolbarButtonGlyphs_2x.png',
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/securityIcons.png b/third_party/WebKit/Source/devtools/front_end/Images/securityIcons.png new file mode 100644 index 0000000..1f328467 --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/Images/securityIcons.png Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/securityIcons_2x.png b/third_party/WebKit/Source/devtools/front_end/Images/securityIcons_2x.png new file mode 100644 index 0000000..fe71dbd9 --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/Images/securityIcons_2x.png Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/securityPropertyInfo.svg b/third_party/WebKit/Source/devtools/front_end/Images/securityPropertyInfo.svg deleted file mode 100644 index edb6b07..0000000 --- a/third_party/WebKit/Source/devtools/front_end/Images/securityPropertyInfo.svg +++ /dev/null
@@ -1,6 +0,0 @@ -<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"> - <g fill="none" fill-rule="evenodd"> - <rect fill="#7f7f7f" x="1" y="1" width="14" height="14" rx="2"/> - <path d="m8.75 12.481l-1.5.019v-6.188h1.5v6.169m-.75-7.481c-.414 0-.75-.336-.75-.75 0-.414.336-.75.75-.75.415 0 .75.336.75.75 0 .414-.335.75-.75.75" fill="#fff"/> - </g> -</svg> \ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/securityPropertyInsecure.svg b/third_party/WebKit/Source/devtools/front_end/Images/securityPropertyInsecure.svg deleted file mode 100644 index c32312b..0000000 --- a/third_party/WebKit/Source/devtools/front_end/Images/securityPropertyInsecure.svg +++ /dev/null
@@ -1,3 +0,0 @@ -<svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg"> - <path d="m 10 33 9 -9 -9 -9 5 -5 9 9 9 -9 5 5 -9 9 9 9 -5 5 -9 -9 -9 9 z" fill="#d8463c" fill-rule="evenodd"/> -</svg> \ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/securityPropertySecure.svg b/third_party/WebKit/Source/devtools/front_end/Images/securityPropertySecure.svg deleted file mode 100644 index 01b9bfd..0000000 --- a/third_party/WebKit/Source/devtools/front_end/Images/securityPropertySecure.svg +++ /dev/null
@@ -1,3 +0,0 @@ -<svg fill="#000000" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> - <circle cx="12" cy="12" fill="#1ac222" r="7"/> -</svg> \ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/securityPropertyUnknown.svg b/third_party/WebKit/Source/devtools/front_end/Images/securityPropertyUnknown.svg deleted file mode 100644 index 4cc08fc..0000000 --- a/third_party/WebKit/Source/devtools/front_end/Images/securityPropertyUnknown.svg +++ /dev/null
@@ -1,11 +0,0 @@ -<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> - <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> - <g id="Symbols" transform="translate(-80.000000, -280.000000)"> - <g id="Security-Icon-Info" transform="translate(80.000000, 280.000000)"> - <rect opacity="0.2" x="0" y="0" width="16" height="16"></rect> - <rect fill="#BFBFBF" x="1" y="1" width="14" height="14" rx="2"></rect> - <path d="M8.95,12.95 L7.05,12.95 L7.05,11.05 L8.95,11.05 L8.95,12.95 L8.95,12.95 Z M9.63,8.4 C9.15,8.88 8.8,9.55 8.8,10 L7.2,10 C7.2,9.17 7.66,8.48 8.13,8 L9.06,7.06 C9.33,6.79 9.5,6.41 9.5,6 C9.5,5.17 8.83,4.5 8,4.5 C7.17,4.5 6.5,5.17 6.5,6 L5,6 C5,4.34 6.34,3 8,3 C9.66,3 11,4.34 11,6 C11,6.66 10.73,7.26 10.3,7.69 C10.3,7.69 9.92,8.11 9.63,8.4 Z" fill="#FFFFFF"></path> - </g> - </g> - </g> -</svg> \ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/securityPropertyWarning.svg b/third_party/WebKit/Source/devtools/front_end/Images/securityPropertyWarning.svg deleted file mode 100644 index 1037fde..0000000 --- a/third_party/WebKit/Source/devtools/front_end/Images/securityPropertyWarning.svg +++ /dev/null
@@ -1,5 +0,0 @@ -<svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg"> - <g fill="none" fill-rule="evenodd"> - <path d="m 24 11.819 -15.227 24.363 30.453 0 L 24 11.819" fill="#ffb003"/> - </g> -</svg> \ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/securityStateInsecure.svg b/third_party/WebKit/Source/devtools/front_end/Images/securityStateInsecure.svg deleted file mode 100644 index 1f17f294..0000000 --- a/third_party/WebKit/Source/devtools/front_end/Images/securityStateInsecure.svg +++ /dev/null
@@ -1,10 +0,0 @@ -<svg viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg"> - <g fill="none" fill-rule="evenodd" transform="translate(8 8)"> - <path d="M 10,4 H70 V74 H10 z" fill="#fff"/> - <g fill="#db4437"> - <path d="M 45.5 42.02 L 40.1 47.42 L 34.688 42 L 32.18 44.504 L 37.6 49.92 L 32.12 55.4 L 34.62 57.9 L 40.1 52.42 L 45.49 57.808 L 47.992 55.3 L 42.604 49.92 L 48 44.516 L 45.5 42.02"/> - <path d="M 30 28 L 30 32 L 50 32 L 50 28 C 50 22.423 45.716 20 40 20 C 34.28 20 30 22.423 30 28"/> - <path d="M 73.33 0 L 6.667 0 C 2.983 0 0 2.983 0 6.667 L 0 73.33 C 0 77.02 2.983 80 6.667 80 L 73.33 80 C 77.02 80 80 77.02 80 73.33 L 80 6.667 C 80 2.983 77.02 0 73.33 0 M 54.28 66 L 25.716 66 C 22.856 66 20 63.14 20 60.28 L 20 37.428 C 20 34.572 23.14 32 26 32 L 26 28 C 26 19.428 31.428 16 40 16 C 48.572 16 54 19.428 54 28 L 54 32 C 56.86 32 60 34.572 60 37.428 L 60 60.28 C 60 63.14 57.14 66 54.28 66"/> - </g> - </g> -</svg> \ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/securityStateNeutral.svg b/third_party/WebKit/Source/devtools/front_end/Images/securityStateNeutral.svg deleted file mode 100644 index a295722..0000000 --- a/third_party/WebKit/Source/devtools/front_end/Images/securityStateNeutral.svg +++ /dev/null
@@ -1,5 +0,0 @@ -<svg viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg"> - <g fill="none" fill-rule="evenodd"> - <path d="M 52 20 L 28 20 L 28 76 L 68 76 L 68 36 L 52 20 M 62 36 L 52 36 L 52 26 L 62 36 M 64 72 L 32 72 L 32 24 L 48 24 L 48 40 L 64 40 L 64 72" fill="#5a5a5a"/> - </g> -</svg> \ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/securityStateSecure.svg b/third_party/WebKit/Source/devtools/front_end/Images/securityStateSecure.svg deleted file mode 100644 index c573dda2..0000000 --- a/third_party/WebKit/Source/devtools/front_end/Images/securityStateSecure.svg +++ /dev/null
@@ -1,10 +0,0 @@ -<svg viewBox="0 0 96 96" xmlns="http://www.w3.org/2000/svg"> - <g fill="none" fill-rule="evenodd" transform="translate(8 8)"> - <path d="M 10,6 H70 V76 H10 z" fill="#fff"/> - <g fill="#1ac222"> - <path d="M 30 28 L 30 32 L 50 32 C 50 32 50 28.13 50 28 C 49.872 22.534 45.585 20 40 20 C 34.28 20 30 22.288 30 28"/> - <path d="M 40 40.28 C 36.844 40.28 34.28 42.929 34.28 46.19 C 34.28 48.37 35.44 50.25 37.14 51.27 L 37.14 58 L 42.856 58 L 42.856 51.27 C 44.56 50.25 45.716 48.37 45.716 46.19 C 45.716 42.929 43.16 40.28 40 40.28"/> - <path d="M 73.33 0 L 6.667 0 C 2.983 0 0 2.983 0 6.667 L 0 73.33 C 0 77.02 2.983 80 6.667 80 L 73.33 80 C 77.02 80 80 77.02 80 73.33 L 80 6.667 C 80 2.983 77.02 0 73.33 0 M 54.28 66 L 25.716 66 C 22.856 66 20 63.14 20 60.28 L 20 37.428 C 20 34.572 23.14 32 26 32 L 26 28 C 26 19.428 31.428 16 40 16 C 48.572 16 54 19.428 54 28 L 54 32 C 56.86 32 60 34.572 60 37.428 L 60 60.28 C 60 63.14 57.14 66 54.28 66"/> - </g> - </g> -</svg> \ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/smallIcons.png b/third_party/WebKit/Source/devtools/front_end/Images/smallIcons.png new file mode 100644 index 0000000..b493ffa9 --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/Images/smallIcons.png Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/smallIcons_2x.png b/third_party/WebKit/Source/devtools/front_end/Images/smallIcons_2x.png new file mode 100644 index 0000000..87e18d3 --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/Images/smallIcons_2x.png Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes b/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes index f3169eb..bbc5d06 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes +++ b/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes
@@ -2,8 +2,9 @@ "resourceGlyphs.svg": "8e1947b1fa4aac49cbc081f85f44d412", "breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28", "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45", + "smallIcons.svg": "502937c3d719c885acb5c18184ac3eca", "settingsListRemove.svg": "ce9e7c5c5cdaef28e6ee51d9478d5485", - "toolbarButtonGlyphs.svg": "337f27abe1f69c6e5501ec2412476bf7", + "toolbarButtonGlyphs.svg": "195b979b5677122cf2f3b65e8a4d657e", "breakpoint.svg": "69cd92d807259c022791112809b97799", "search.svg": "fc990dd3836aec510d7ca1f36c2a3142" } \ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/securityIcons.svg b/third_party/WebKit/Source/devtools/front_end/Images/src/securityIcons.svg new file mode 100644 index 0000000..a8f063b --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/Images/src/securityIcons.svg
@@ -0,0 +1,97 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg width="160px" height="96px" viewBox="0 0 160 96" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <!-- Generator: Sketch 39.1 (31720) - http://www.bohemiancoding.com/sketch --> + <title>Non-Touch-Summary-Icons</title> + <desc>Created with Sketch.</desc> + <defs></defs> + <g id="Page" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> + <g id="Non-Touch-Summary-Icons" transform="translate(-128.000000, -192.000000)"> + <g id="Info-Grey" transform="translate(176.000000, 272.000000)" fill="#000000"> + <path d="M2,3.73208732 C2,2.77548191 2.77427769,2 3.72629963,2 L13.2737004,2 C14.2271093,2 15,2.76890868 15,3.73208732 L15,12.2679127 C15,13.2245181 14.2257223,14 13.2737004,14 L3.72629963,14 C2.77289067,14 2,13.2310913 2,12.2679127 L2,3.73208732 Z M8,6 L9,6 L9,5 L8,5 L8,6 L8,6 Z M8,11 L9,11 L9,7 L8,7 L8,11 L8,11 Z" id="Icon"></path> + </g> + <g id="Unkonwn-Grey" transform="translate(192.000000, 272.000000)"> + <g id="Icon-HTTP"> + <polygon id="Layout" points="0 0 16 0 16 16 0 16"></polygon> + </g> + <g id="ic_help_black_24dp" transform="translate(2.000000, 2.000000)" fill="#000000"> + <g id="Group"> + <path d="M0,1.73208732 C0,0.775481909 0.774277687,0 1.72629963,0 L11.2737004,0 C12.2271093,0 13,0.768908679 13,1.73208732 L13,10.2679127 C13,11.2245181 12.2257223,12 11.2737004,12 L1.72629963,12 C0.77289067,12 0,11.2310913 0,10.2679127 L0,1.73208732 Z M7,9 L6,9 L6,8 L7,8 L7,9 Z M8.035,5.125 L7.585,5.585 C7.225,5.95 7,6.25 7,7 L6.69726562,7 L6.3104248,7 L6,7 L6,6.75 C6,6.2 6.225,5.7 6.585,5.335 L7.205,4.705 C7.39,4.525 7.5,4.275 7.5,4 C7.5,3.45 7.05,3 6.5,3 C5.95,3 5.5,3.45 5.5,4 L4.5,4 C4.5,2.895 5.395,2 6.5,2 C7.605,2 8.5,2.895 8.5,4 C8.5,4.44 8.32,4.84 8.035,5.125 Z" id="Combined-Shape"></path> + </g> + </g> + </g> + <g id="Icon" transform="translate(128.000000, 272.000000)"> + <g id="Security-Icon-Green-Simple"> + <rect id="Layout" opacity="0.2" x="0" y="0" width="16" height="16"></rect> + <rect id="Green" fill="#000000" x="4" y="4" width="8" height="8" rx="1"></rect> + </g> + </g> + <g id="Icon" transform="translate(144.000000, 272.000000)"> + <g id="Security-Icon-Green-Simple"> + <rect id="Layout" opacity="0.2" x="0" y="0" width="16" height="16"></rect> + <rect id="Green" fill="#000000" x="4" y="4" width="8" height="8" rx="4"></rect> + </g> + </g> + <g id="Icon" transform="translate(160.000000, 272.000000)"> + <g id="Security-Icon-Green-Simple"> + <rect id="Layout" opacity="0.2" x="0" y="0" width="16" height="16"></rect> + <polygon id="Red" fill="#000000" points="8 3 13 12 3 12"></polygon> + </g> + </g> + <g id="Icon" transform="translate(160.000000, 256.000000)"> + <rect id="Layout" opacity="0.2" x="0" y="0" width="16" height="16"></rect> + <path d="M0.5,14 L15.5,14 L8,1 L0.5,14 L0.5,14 Z M9,12 L7,12 L7,10 L9,10 L9,12 L9,12 Z M9,9 L7,9 L7,6 L9,6 L9,9 L9,9 Z" fill="#000000"></path> + </g> + <g id="Icon" transform="translate(144.000000, 256.000000)"> + <polygon id="Layout" points="0 0 16 0 16 16 0 16"></polygon> + <path d="M8,1 C4.136,1 1,4.136 1,8 C1,11.864 4.136,15 8,15 C11.864,15 15,11.864 15,8 C15,4.136 11.864,1 8,1 L8,1 Z M2.5,8 C2.5,4.968125 4.968125,2.5 8,2.5 C11.031875,2.5 13.5,4.968125 13.5,8 C13.5,11.031875 11.031875,13.5 8,13.5 C4.968125,13.5 2.5,11.031875 2.5,8 Z M9,12 L9,7 L7,7 L7,12 L9,12 Z M7,6 L9,6 L9,4 L7,4 L7,6 L7,6 Z" fill="#000000"></path> + </g> + <g id="Icon" transform="translate(128.000000, 256.000000)"> + <polygon id="Layout" points="0 0 16 0 16 16 0 16"></polygon> + <path d="M10.5,6.49999992 L10.5,5.49999992 C10.5,4.11999512 9.38000488,3 8,3 C6.61999512,3.01017207 5.5,4.11999512 5.5,5.49999992 L5.5,6.49999992 C5.5,6.49999992 5.55000305,6.5 5,6.49999992 C4.44999695,6.49999983 4,6.95015331 4,7.49633781 L4,12.5 C4,13.0500031 4.45001221,13.5 5,13.5 C5.54998779,13.5 10.4500122,13.5 11,13.5 C11.5499878,13.5 12,13.0500031 12,12.5 C12,11.9499969 12,8.05000305 12,7.5 C12,6.97227107 11.5500031,6.5 11,6.49999992 C10.4499969,6.5 10.5,6.49999992 10.5,6.49999992 Z M6.5,6.51011411 L6.5,5.5 C6.5,4.66999817 7.16999817,4 8,4 C8.83000183,4 9.5,4.66999817 9.5,5.5 L9.5,6.51011411 L6.5,6.51011411 Z" fill="#000000"></path> + </g> + <g id="Icon" transform="translate(227.000000, 227.000000)" fill="#000000"> + <path d="M0,3.46603816 C0,1.55179814 1.54855537,0 3.46603816,0 L22.5339618,0 C24.4482019,0 26,1.54855537 26,3.46603816 L26,22.5339618 C26,24.4482019 24.4514446,26 22.5339618,26 L3.46603816,26 C1.55179814,26 0,24.4514446 0,22.5339618 L0,3.46603816 Z M12,9 L14,9 L14,7 L12,7 L12,9 L12,9 Z M12,19 L14,19 L14,11 L12,11 L12,19 L12,19 Z"></path> + </g> + <g id="Icon" transform="translate(256.000000, 224.000000)"> + <g id="Icon-HTTP"> + <polygon id="Layout" points="0 0 32 0 32 32 0 32"></polygon> + </g> + <g id="ic_help_black_24dp" transform="translate(3.000000, 3.000000)" fill="#000000"> + <g id="Group"> + <path d="M0,3.46603816 C0,1.55179814 1.54855537,0 3.46603816,0 L22.5339618,0 C24.4482019,0 26,1.54855537 26,3.46603816 L26,22.5339618 C26,24.4482019 24.4514446,26 22.5339618,26 L3.46603816,26 C1.55179814,26 0,24.4514446 0,22.5339618 L0,3.46603816 Z M14,19 L12,19 L12,17 L14,17 L14,19 Z M16.07,11.25 L15.17,12.17 C14.45,12.9 14,13.5 14,15 L13.3945312,15 L12.6208496,15 L12,15 L12,14.5 C12,13.4 12.45,12.4 13.17,11.67 L14.41,10.41 C14.78,10.05 15,9.55 15,9 C15,7.9 14.1,7 13,7 C11.9,7 11,7.9 11,9 L9,9 C9,6.79 10.79,5 13,5 C15.21,5 17,6.79 17,9 C17,9.88 16.64,10.68 16.07,11.25 Z" id="Combined-Shape"></path> + </g> + </g> + </g> + <g id="Icon" transform="translate(128.000000, 224.000000)"> + <g id="Security-Icon-Green-Simple"> + <rect id="Layout" opacity="0.2" x="0" y="0" width="32" height="32"></rect> + <rect id="Green" fill="#000000" x="8" y="8" width="16" height="16" rx="2"></rect> + </g> + </g> + <g id="Icon" transform="translate(160.000000, 224.000000)"> + <g id="Security-Icon-Green-Simple"> + <rect id="Layout" opacity="0.2" x="0" y="0" width="32" height="32"></rect> + <rect id="Green" fill="#000000" x="8" y="8" width="16" height="16" rx="8"></rect> + </g> + </g> + <g id="Icon" transform="translate(192.000000, 224.000000)"> + <g id="Security-Icon-Green-Simple"> + <rect id="Layout" opacity="0.2" x="0" y="0" width="32" height="32"></rect> + <polygon id="Red" fill="#000000" points="16 6 26 24 6 24"></polygon> + </g> + </g> + <g id="Icon" transform="translate(192.000000, 192.000000)"> + <rect id="Layout" opacity="0.2" x="0" y="0" width="32" height="32"></rect> + <path d="M4,27 L29,27 L16.5,5 L4,27 L4,27 Z M18,24 L15,24 L15,21 L18,21 L18,24 L18,24 Z M18,19 L15,19 L15,13 L18,13 L18,19 L18,19 Z" fill="#000000"></path> + </g> + <g id="Icon" transform="translate(160.000000, 192.000000)"> + <polygon id="Layout" points="0 0 32 0 32 32 0 32"></polygon> + <path d="M16.5,3 C9.048,3 3,9.048 3,16.5 C3,23.952 9.048,30 16.5,30 C23.952,30 30,23.952 30,16.5 C30,9.048 23.952,3 16.5,3 L16.5,3 Z M6,16.5 C6,10.711875 10.711875,6 16.5,6 C22.288125,6 27,10.711875 27,16.5 C27,22.288125 22.288125,27 16.5,27 C10.711875,27 6,22.288125 6,16.5 Z M15,23 L18,23 L18,15 L15,15 L15,23 L15,23 Z M15,13 L18,13 L18,10 L15,10 L15,13 L15,13 Z" fill="#000000"></path> + </g> + <g id="Icon" transform="translate(128.000000, 192.000000)"> + <polygon id="Layout" points="0 0 32 0 32 32 0 32"></polygon> + <path d="M21,12.9999998 L21,10.9999998 C21,8.23999023 18.7600098,6 16,6 C13.2399902,6.02034414 11,8.23999023 11,10.9999998 L11,12.9999998 C11,12.9999998 11.1000061,13 10,12.9999998 C8.8999939,12.9999997 8,13.9003066 8,14.9926756 L8,25 C8,26.1000061 8.90002441,27 10,27 C11.0999756,27 20.9000244,27 22,27 C23.0999756,27 24,26.1000061 24,25 C24,23.8999939 24,16.1000061 24,15 C24,13.9445421 23.1000061,13 22,12.9999998 C20.8999939,13 21,12.9999998 21,12.9999998 Z M13,13.0202282 L13,11 C13,9.33999634 14.3399963,8 16,8 C17.6600037,8 19,9.33999634 19,11 L19,13.0202282 L13,13.0202282 Z" fill="#000000"></path> + </g> + </g> + </g> +</svg> \ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/smallIcons.svg b/third_party/WebKit/Source/devtools/front_end/Images/src/smallIcons.svg new file mode 100644 index 0000000..1c247a8 --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/Images/src/smallIcons.svg
@@ -0,0 +1,504 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="190" + height="30" + id="svg3250" + version="1.1" + inkscape:version="0.48.4 r9939" + sodipodi:docname="smallIcons.svg"> + <defs + id="defs3252"> + <linearGradient + gradientTransform="matrix(0,-0.41666666,-0.41666666,0,218,106)" + gradientUnits="userSpaceOnUse" + id="p" + x1="0" + x2="24" + xlink:href="#l" + y1="0" + y2="0" /> + <linearGradient + id="l"> + <stop + offset="0" + stop-color="#d7687d" + id="stop3458" /> + <stop + offset="1" + stop-color="#b21402" + id="stop3460" /> + </linearGradient> + <linearGradient + y2="0" + x2="24" + y1="0" + x1="0" + gradientTransform="matrix(0,-0.41666666,-0.41666666,0,25,1032.3622)" + gradientUnits="userSpaceOnUse" + id="linearGradient3308" + xlink:href="#l" + inkscape:collect="always" /> + <linearGradient + inkscape:collect="always" + xlink:href="#l-0" + id="linearGradient3239" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0,-0.41666666,-0.41666666,0,249.99999,117)" + x1="0" + y1="0" + x2="24" + y2="0" /> + <linearGradient + id="l-0"> + <stop + offset="0" + stop-color="#d7687d" + id="stop3458-8" /> + <stop + offset="1" + stop-color="#b21402" + id="stop3460-8" /> + </linearGradient> + <linearGradient + gradientTransform="matrix(0.71428571,0,0,0.71428571,132.28571,37.714287)" + gradientUnits="userSpaceOnUse" + id="q" + x1="113" + x2="127" + xlink:href="#a" + y1="104" + y2="104" /> + <linearGradient + id="a"> + <stop + offset="0" + stop-color="#606eda" + id="stop3403" /> + <stop + offset="1" + stop-color="#021db2" + id="stop3405" /> + </linearGradient> + <linearGradient + y2="104" + x2="127" + y1="104" + x1="113" + gradientTransform="matrix(0.71428571,0,0,0.71428571,-0.71428982,953.07646)" + gradientUnits="userSpaceOnUse" + id="linearGradient3359" + xlink:href="#a" + inkscape:collect="always" /> + <linearGradient + gradientTransform="matrix(0,0.43965518,0.78048781,0,44.48744,928.48286)" + gradientUnits="userSpaceOnUse" + id="t" + x1="227.875" + x2="235.125" + xlink:href="#i" + y1="103.15625" + y2="103.15625" /> + <linearGradient + id="i"> + <stop + offset="0" + stop-color="#f00" + stop-opacity="0" + id="stop3443" /> + <stop + offset="1" + stop-color="#f0cb68" + stop-opacity="0.71" + id="stop3445" /> + </linearGradient> + <linearGradient + gradientTransform="matrix(0,-0.62931035,0.92682926,0,29.46895,1170.8907)" + gradientUnits="userSpaceOnUse" + id="s" + x1="227.875" + x2="235.125" + xlink:href="#j" + y1="103.15625" + y2="103.15625" /> + <linearGradient + id="j"> + <stop + offset="0" + stop-color="#e60000" + stop-opacity="0.65" + id="stop3448" /> + <stop + offset="1" + stop-color="#fff" + stop-opacity="0.91" + id="stop3450" /> + </linearGradient> + <linearGradient + gradientTransform="matrix(0,1.3793103,-1.3008129,0,363.08462,-218.35335)" + gradientUnits="userSpaceOnUse" + id="r" + x1="227.875" + x2="235.125" + xlink:href="#k" + y1="103.15625" + y2="103.15625" /> + <linearGradient + id="k"> + <stop + offset="0" + stop-color="#a10000" + id="stop3453" /> + <stop + offset="1" + stop-color="#c60000" + id="stop3455" /> + </linearGradient> + <linearGradient + y2="103.15625" + x2="235.125" + y1="103.15625" + x1="227.875" + gradientTransform="matrix(0,1.3793103,-1.3008129,0,259.08462,708.00888)" + gradientUnits="userSpaceOnUse" + id="linearGradient3398" + xlink:href="#k" + inkscape:collect="always" /> + <linearGradient + gradientTransform="matrix(-0.00480259,0.43959676,0.7803841,0.00852566,65.60742,927.52853)" + gradientUnits="userSpaceOnUse" + id="w" + x1="227.875" + x2="235.125" + xlink:href="#f" + y1="103.15625" + y2="103.15625" /> + <linearGradient + id="f"> + <stop + offset="0" + stop-color="#00d600" + stop-opacity="0" + id="stop3428" /> + <stop + offset="1" + stop-color="#d8fc7b" + stop-opacity="0.81" + id="stop3430" /> + </linearGradient> + <linearGradient + gradientTransform="matrix(0.00687428,-0.62922672,0.92670611,0.01012422,47.870946,1169.7969)" + gradientUnits="userSpaceOnUse" + id="v" + x1="227.875" + x2="235.125" + xlink:href="#g" + y1="103.15625" + y2="103.15625" /> + <linearGradient + id="g"> + <stop + offset="0" + stop-color="#00ba00" + id="stop3433" /> + <stop + offset="1" + stop-color="#fff" + stop-opacity="0.91" + id="stop3435" /> + </linearGradient> + <linearGradient + gradientTransform="matrix(-0.01506784,1.3792098,-1.3007182,-0.01421029,377.66542,-216.8212)" + gradientUnits="userSpaceOnUse" + id="u" + x1="227.875" + x2="235.125" + xlink:href="#h" + y1="103.15625" + y2="103.15625" /> + <linearGradient + id="h"> + <stop + offset="0" + stop-color="#00a104" + id="stop3438" /> + <stop + offset="1" + stop-color="#00c605" + id="stop3440" /> + </linearGradient> + <linearGradient + y2="103.15625" + x2="235.125" + y1="103.15625" + x1="227.875" + gradientTransform="matrix(-0.01506693,1.3791269,-1.30064,-0.01420944,282.65715,709.5601)" + gradientUnits="userSpaceOnUse" + id="linearGradient3426" + xlink:href="#h" + inkscape:collect="always" /> + <linearGradient + gradientTransform="matrix(0,0.43965518,0.78048781,0,84.443253,928.43867)" + gradientUnits="userSpaceOnUse" + id="y" + x1="227.875" + x2="235.125" + xlink:href="#d" + y1="103.15625" + y2="103.15625" /> + <linearGradient + id="d"> + <stop + offset="0" + stop-color="#ffa801" + stop-opacity="0" + id="stop3418" /> + <stop + offset="1" + stop-color="#f0fb3d" + id="stop3420" /> + </linearGradient> + <linearGradient + gradientTransform="matrix(0,-0.62931035,0.92682926,0,69.468953,1170.8907)" + gradientUnits="userSpaceOnUse" + id="x" + x1="227.875" + x2="235.125" + xlink:href="#e" + y1="103.15625" + y2="103.15625" /> + <linearGradient + id="e"> + <stop + offset="0" + stop-color="#ffbd00" + stop-opacity="0.65" + id="stop3423" /> + <stop + offset="1" + stop-color="#fff" + stop-opacity="0.91" + id="stop3425" /> + </linearGradient> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="5.5" + inkscape:cx="67.047764" + inkscape:cy="22.130842" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="true" + inkscape:window-width="1178" + inkscape:window-height="865" + inkscape:window-x="612" + inkscape:window-y="125" + inkscape:window-maximized="0"> + <inkscape:grid + type="xygrid" + id="grid3258" + empspacing="2" + visible="true" + enabled="true" + snapvisiblegridlinesonly="true" + spacingx="10px" + spacingy="10px" + dotted="false" /> + </sodipodi:namedview> + <metadata + id="metadata3255"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-1022.3622)"> + <path + d="m 25,1022.3622 c -2.76,0 -5,2.24 -5,5 0,2.76 2.24,5 5,5 2.76,0 5,-2.24 5,-5 0,-2.76 -2.24,-5 -5,-5" + id="path3699" + inkscape:connector-curvature="0" + style="fill:url(#linearGradient3308)" /> + <path + d="m 20.36,1027.3622 c 0,2.56 2.08,4.64 4.64,4.64 2.56,0 4.64,-2.08 4.64,-4.64 0,-2.56 -2.08,-4.64 -4.64,-4.64 -2.56,0 -4.64,2.08 -4.64,4.64" + id="path3701" + inkscape:connector-curvature="0" + style="fill:#eb3941" /> + <path + d="m 23,1025.3622 4,4" + id="path3703" + inkscape:connector-curvature="0" + style="stroke:#ffffff" /> + <path + d="m 27,1025.3622 -4,4" + id="path3705" + inkscape:connector-curvature="0" + style="stroke:#ffffff" /> + <g + id="g3234" + transform="translate(-205,915.3622)"> + <path + style="fill:url(#linearGradient3239)" + inkscape:connector-curvature="0" + id="path3699-5" + d="m 250,107 c -2.76,0 -5,2.24 -5,5 0,2.76 2.24,5 5,5 2.76,0 5,-2.24 5,-5 0,-2.76 -2.24,-5 -5,-5" /> + <path + id="path3701-0" + d="m 245.36,112 c 0,2.56 2.08,4.64 4.64,4.64 2.56,0 4.64,-2.08 4.64,-4.64 0,-2.56 -2.08,-4.64 -4.64,-4.64 -2.56,0 -4.64,2.08 -4.64,4.64" + inkscape:connector-curvature="0" + style="fill:#f4979b;fill-opacity:1" /> + <path + style="fill:#ffffff;fill-opacity:1" + id="path3689-2" + d="m 248.64912,113.55532 -1.12,-1.57887 -0.94113,0.9411 1.98332,2.80777 5.01668,-5.96555 -0.8711,-1.03445 z" + inkscape:connector-curvature="0" /> + </g> + <path + d="m 61,1031.3622 4,-8 4,8 z" + id="path3707" + inkscape:connector-curvature="0" + style="stroke:#c19600;stroke-width:2;stroke-linejoin:round" /> + <path + d="m 61,1031.3622 4,-8 4,8 z" + id="path3709" + inkscape:connector-curvature="0" + style="fill:#f4bd00;stroke:#f5bd00;stroke-width:1.5;stroke-linejoin:round" /> + <path + d="m 63.75,1025.1122 2.5,0 0,2.5 -0.5,1.75 -1.5,0 -0.5,-1.75 0,-2.5 m 0,5.25 2.5,0 0,1.25 -2.5,0" + id="path3711" + inkscape:connector-curvature="0" + style="fill:#ad8601" /> + <path + d="m 64,1025.3622 2,0 0,2.25 -0.5,1.75 -1,0 -0.5,-1.75 0,-2.25 m 0,5 2,0 0,1 -2,0" + id="path3713" + inkscape:connector-curvature="0" + style="fill:#ffffff" /> + <path + d="m 85,1022.3622 c -2.76,0 -5,2.24 -5,5 0,2.76 2.24,5 5,5 2.76,0 5,-2.24 5,-5 0,-2.76 -2.24,-5 -5,-5" + id="path3741" + inkscape:connector-curvature="0" + style="fill:url(#linearGradient3359)" /> + <path + d="m 80.36,1027.3622 c 0,2.56 2.08,4.64 4.64,4.64 2.56,0 4.64,-2.08 4.64,-4.64 0,-2.56 -2.08,-4.64 -4.64,-4.64 -2.56,0 -4.64,2.08 -4.64,4.64" + id="path3743" + inkscape:connector-curvature="0" + style="fill:#2a53cd" /> + <path + d="m 83.93,1024.5022 c -0.03,-0.53 0.55,-0.97 1.06,-0.83 0.5,0.12 0.79,0.73 0.56,1.18 -0.2,0.44 -0.79,0.61 -1.2,0.36 -0.26,-0.14 -0.42,-0.42 -0.42,-0.71 z m 1.7,5.46 c 0.22,0 0.45,0 0.67,0 0,0.18 0,0.35 0,0.53 -0.96,0 -1.93,0 -2.89,0 0,-0.18 0,-0.35 0,-0.53 0.22,0 0.44,0 0.66,0 0,-1.2 0,-2.41 0,-3.61 -0.22,0 -0.44,0 -0.66,0 0,-0.18 0,-0.35 0,-0.53 0.74,0 1.48,0 2.22,0 0,1.38 0,2.76 0,4.14 z" + id="path3745" + inkscape:connector-curvature="0" + style="fill:#ffffff" /> + <path + d="m 103.25,1022.3622 c -0.7,0 -1.25,0.5 -1.25,1.25 l 0,7.5 c 0,0.7 0.5,1.25 1.25,1.25 l 3.5,0 c 0.7,0 1.25,-0.5 1.25,-1.25 l 0,-7.5 c 0,-0.7 -0.5,-1.25 -1.25,-1.25 l -3.5,0 z m -0.25,1 4,0 0,7 -4,0 0,-7 z m 2,7.25 c 0.4,0 0.75,0.3 0.75,0.75 0,0.4 -0.3,0.75 -0.75,0.75 -0.4,0 -0.75,-0.3 -0.75,-0.75 0,-0.4 0.3,-0.75 0.75,-0.75 z" + id="path3765" + inkscape:connector-curvature="0" /> + <path + d="m 125,1032.3622 c -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 0,2.76 -2.24,5 -5,5 z" + id="path3715" + inkscape:connector-curvature="0" + style="fill:url(#linearGradient3398)" /> + <path + d="m 129.5,1027.3622 c 0,2.49 -2.01,4.5 -4.5,4.5 -2.49,0 -4.5,-2.01 -4.5,-4.5 0,-2.49 2.01,-4.5 4.5,-4.5 2.49,0 4.5,2.01 4.5,4.5 z" + id="path3717" + inkscape:connector-curvature="0" + style="fill:#dd0000" /> + <path + d="m 125.03,1022.8922 c 1.97,0 3.56,1.02 3.56,2.28 0,1.26 -1.59,2.28 -3.56,2.28 -1.97,0 -3.56,-1.02 -3.56,-2.28 0,-1.26 1.59,-2.28 3.56,-2.28 z" + id="path3719" + inkscape:connector-curvature="0" + style="fill:url(#s)" /> + <path + d="m 125.03,1031.8322 c 1.66,0 3,-0.71 3,-1.59 0,-0.88 -1.34,-1.59 -3,-1.59 -1.66,0 -3,0.71 -3,1.59 0,0.88 1.34,1.59 3,1.59 z" + id="path3721" + inkscape:connector-curvature="0" + style="fill:url(#t)" /> + <path + d="m 144.95,1032.3619 c -2.75983,-0.03 -4.9797,-2.2899 -4.9497,-5.0497 0.03,-2.7598 2.28986,-4.9797 5.0497,-4.9497 2.75983,0.03 4.9797,2.2899 4.9497,5.0497 -0.03,2.7598 -2.28986,4.9797 -5.0497,4.9497 z" + id="path3723" + inkscape:connector-curvature="0" + style="fill:url(#linearGradient3426)" /> + <path + d="m 149.49973,1027.4122 c -0.03,2.4898 -2.05988,4.4797 -4.54973,4.4497 -2.48985,-0.03 -4.47973,-2.0598 -4.44973,-4.5497 0.03,-2.4898 2.05988,-4.4797 4.54973,-4.4497 2.48985,0.03 4.47973,2.0598 4.44973,4.5497 z" + id="path3725" + inkscape:connector-curvature="0" + style="fill:#00be00" /> + <path + d="m 145.07999,1022.8925 c 1.96989,0.02 3.54979,1.0599 3.53979,2.3198 -0.01,1.26 -1.6199,2.2599 -3.58978,2.2399 -1.96988,-0.02 -3.54979,-1.0599 -3.53979,-2.3199 0.01,-1.2599 1.6199,-2.2598 3.58978,-2.2398 z" + id="path3727" + inkscape:connector-curvature="0" + style="fill:url(#v)" /> + <path + d="m 144.98,1031.7719 c 1.6599,0.02 3.00982,-0.6799 3.01982,-1.5599 0.01,-0.8799 -1.32992,-1.6099 -2.97982,-1.6299 -1.6599,-0.02 -3.00982,0.68 -3.01982,1.5599 -0.01,0.88 1.32992,1.6099 2.97982,1.6299 z" + id="path3729" + inkscape:connector-curvature="0" + style="fill:url(#w)" /> + <path + d="m 165,1032.3622 c -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 0,2.76 -2.24,5 -5,5 z" + id="path3731" + inkscape:connector-curvature="0" + style="fill:#e5a600" /> + <path + d="m 169.5,1027.3622 c 0,2.49 -2.01,4.5 -4.5,4.5 -2.49,0 -4.5,-2.01 -4.5,-4.5 0,-2.49 2.01,-4.5 4.5,-4.5 2.49,0 4.5,2.01 4.5,4.5 z" + id="path3733" + inkscape:connector-curvature="0" + style="fill:#ffbd00" /> + <path + d="m 165.03,1022.8922 c 1.97,0 3.56,1.02 3.56,2.28 0,1.26 -1.59,2.28 -3.56,2.28 -1.97,0 -3.56,-1.02 -3.56,-2.28 0,-1.26 1.59,-2.28 3.56,-2.28 z" + id="path3735" + inkscape:connector-curvature="0" + style="fill:url(#x)" /> + <path + d="m 164.99,1031.7822 c 1.66,0 3,-0.71 3,-1.59 0,-0.88 -1.34,-1.59 -3,-1.59 -1.66,0 -3,0.71 -3,1.59 0,0.88 1.34,1.59 3,1.59 z" + id="path3737" + inkscape:connector-curvature="0" + style="fill:url(#y)" /> + <path + inkscape:connector-curvature="0" + id="path3660" + d="m 180.5,1029.8622 4,0 0,2 5,-4.5 -5,-4.5 0,2 -4,0 z" + style="fill:#4688f1;fill-opacity:1" + sodipodi:nodetypes="cccccccc" /> + <path + d="m 3.25,1044.1122 3.5,3.25 -3.5,3.25" + id="path3693" + inkscape:connector-curvature="0" + style="fill:none;stroke:#939393;stroke-width:1.5" /> + <path + d="m 23.25,1044.1122 3.5,3.25 -3.5,3.25" + id="path3691" + inkscape:connector-curvature="0" + style="fill:none;stroke:#367cf1;stroke-width:1.5" /> + <path + d="m 46.5,1047.3622 c 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1" + id="path3695" + inkscape:connector-curvature="0" + style="fill:#bababa" /> + <path + d="m 45.75,1044.1122 -3.5,3.25 3.5,3.25" + id="path3697" + inkscape:connector-curvature="0" + style="fill:none;stroke:#bababa;stroke-width:1.5" /> + </g> +</svg>
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes b/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes index f3169eb..bbc5d06 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes +++ b/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes
@@ -2,8 +2,9 @@ "resourceGlyphs.svg": "8e1947b1fa4aac49cbc081f85f44d412", "breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28", "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45", + "smallIcons.svg": "502937c3d719c885acb5c18184ac3eca", "settingsListRemove.svg": "ce9e7c5c5cdaef28e6ee51d9478d5485", - "toolbarButtonGlyphs.svg": "337f27abe1f69c6e5501ec2412476bf7", + "toolbarButtonGlyphs.svg": "195b979b5677122cf2f3b65e8a4d657e", "breakpoint.svg": "69cd92d807259c022791112809b97799", "search.svg": "fc990dd3836aec510d7ca1f36c2a3142" } \ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/toolbarButtonGlyphs.svg b/third_party/WebKit/Source/devtools/front_end/Images/src/toolbarButtonGlyphs.svg index ecd70de..085a160 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/src/toolbarButtonGlyphs.svg +++ b/third_party/WebKit/Source/devtools/front_end/Images/src/toolbarButtonGlyphs.svg
@@ -21,13 +21,13 @@ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><sodipodi:namedview showgrid="true" id="namedview3397" - inkscape:zoom="13.420455" + inkscape:zoom="2.7223046" inkscape:cx="217.56822" - inkscape:cy="49.153235" + inkscape:cy="63.846668" inkscape:window-width="1766" inkscape:window-height="1118" - inkscape:window-x="238" - inkscape:window-y="158" + inkscape:window-x="2014" + inkscape:window-y="38" inkscape:window-maximized="0" inkscape:current-layer="svg3395" inkscape:snap-global="false" @@ -581,117 +581,6 @@ d="m 131.65,116.21 -1.44,-2.03 -1.21,1.21 2.55,3.61 6.45,-7.67 -1.12,-1.33 z" id="path3689" inkscape:connector-curvature="0" /><path - d="m 195.75,97.75 3.5,3.25 -3.5,3.25" - id="path3691" - inkscape:connector-curvature="0" - style="fill:none;stroke:#367cf1;stroke-width:1.5" /><path - d="m 195.75,108.75 3.5,3.25 -3.5,3.25" - id="path3693" - inkscape:connector-curvature="0" - style="fill:none;stroke:#939393;stroke-width:1.5" /><path - d="m 209,101 c 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1" - id="path3695" - inkscape:connector-curvature="0" - style="fill:#bababa" /><path - d="m 208.25,97.75 -3.5,3.25 3.5,3.25" - id="path3697" - inkscape:connector-curvature="0" - style="fill:none;stroke:#bababa;stroke-width:1.5" /><path - d="m 218,96 c -2.76,0 -5,2.24 -5,5 0,2.76 2.24,5 5,5 2.76,0 5,-2.24 5,-5 0,-2.76 -2.24,-5 -5,-5" - id="path3699" - inkscape:connector-curvature="0" - style="fill:url(#p)" /><path - d="m 213.36,101 c 0,2.56 2.08,4.64 4.64,4.64 2.56,0 4.64,-2.08 4.64,-4.64 0,-2.56 -2.08,-4.64 -4.64,-4.64 -2.56,0 -4.64,2.08 -4.64,4.64" - id="path3701" - inkscape:connector-curvature="0" - style="fill:#eb3941" /><path - d="m 216,99 4,4" - id="path3703" - inkscape:connector-curvature="0" - style="stroke:#ffffff" /><path - d="m 220,99 -4,4" - id="path3705" - inkscape:connector-curvature="0" - style="stroke:#ffffff" /><path - d="m 203,116 4,-8 4,8 z" - id="path3707" - inkscape:connector-curvature="0" - style="stroke:#c19600;stroke-width:2;stroke-linejoin:round" /><path - d="m 203,116 4,-8 4,8 z" - id="path3709" - inkscape:connector-curvature="0" - style="fill:#f4bd00;stroke:#f5bd00;stroke-width:1.5;stroke-linejoin:round" /><path - d="m 205.75,109.75 2.5,0 0,2.5 -0.5,1.75 -1.5,0 -0.5,-1.75 0,-2.5 m 0,5.25 2.5,0 0,1.25 -2.5,0" - id="path3711" - inkscape:connector-curvature="0" - style="fill:#ad8601" /><path - d="m 206,110 2,0 0,2.25 -0.5,1.75 -1,0 -0.5,-1.75 0,-2.25 m 0,5 2,0 0,1 -2,0" - id="path3713" - inkscape:connector-curvature="0" - style="fill:#ffffff" /><path - d="m 229,106 c -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 0,2.76 -2.24,5 -5,5 z" - id="path3715" - inkscape:connector-curvature="0" - style="fill:url(#r)" /><path - d="m 233.5,101 c 0,2.49 -2.01,4.5 -4.5,4.5 -2.49,0 -4.5,-2.01 -4.5,-4.5 0,-2.49 2.01,-4.5 4.5,-4.5 2.49,0 4.5,2.01 4.5,4.5 z" - id="path3717" - inkscape:connector-curvature="0" - style="fill:#dd0000" /><path - d="m 229.03,96.53 c 1.97,0 3.56,1.02 3.56,2.28 0,1.26 -1.59,2.28 -3.56,2.28 -1.97,0 -3.56,-1.02 -3.56,-2.28 0,-1.26 1.59,-2.28 3.56,-2.28 z" - id="path3719" - inkscape:connector-curvature="0" - style="fill:url(#s)" /><path - d="m 229.03,105.47 c 1.66,0 3,-0.71 3,-1.59 0,-0.88 -1.34,-1.59 -3,-1.59 -1.66,0 -3,0.71 -3,1.59 0,0.88 1.34,1.59 3,1.59 z" - id="path3721" - inkscape:connector-curvature="0" - style="fill:url(#t)" /><path - d="m 239.95,106 c -2.76,-0.03 -4.98,-2.29 -4.95,-5.05 0.03,-2.76 2.29,-4.98 5.05,-4.95 2.76,0.03 4.98,2.29 4.95,5.05 -0.03,2.76 -2.29,4.98 -5.05,4.95 z" - id="path3723" - inkscape:connector-curvature="0" - style="fill:url(#u)" /><path - d="m 244.5,101.05 c -0.03,2.49 -2.06,4.48 -4.55,4.45 -2.49,-0.03 -4.48,-2.06 -4.45,-4.55 0.03,-2.49 2.06,-4.48 4.55,-4.45 2.49,0.03 4.48,2.06 4.45,4.55 z" - id="path3725" - inkscape:connector-curvature="0" - style="fill:#00be00" /><path - d="m 240.08,96.53 c 1.97,0.02 3.55,1.06 3.54,2.32 -0.01,1.26 -1.62,2.26 -3.59,2.24 -1.97,-0.02 -3.55,-1.06 -3.54,-2.32 0.01,-1.26 1.62,-2.26 3.59,-2.24 z" - id="path3727" - inkscape:connector-curvature="0" - style="fill:url(#v)" /><path - d="m 239.98,105.41 c 1.66,0.02 3.01,-0.68 3.02,-1.56 0.01,-0.88 -1.33,-1.61 -2.98,-1.63 -1.66,-0.02 -3.01,0.68 -3.02,1.56 -0.01,0.88 1.33,1.61 2.98,1.63 z" - id="path3729" - inkscape:connector-curvature="0" - style="fill:url(#w)" /><path - d="m 251,106 c -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 0,2.76 -2.24,5 -5,5 z" - id="path3731" - inkscape:connector-curvature="0" - style="fill:#e5a600" /><path - d="m 255.5,101 c 0,2.49 -2.01,4.5 -4.5,4.5 -2.49,0 -4.5,-2.01 -4.5,-4.5 0,-2.49 2.01,-4.5 4.5,-4.5 2.49,0 4.5,2.01 4.5,4.5 z" - id="path3733" - inkscape:connector-curvature="0" - style="fill:#ffbd00" /><path - d="m 251.03,96.53 c 1.97,0 3.56,1.02 3.56,2.28 0,1.26 -1.59,2.28 -3.56,2.28 -1.97,0 -3.56,-1.02 -3.56,-2.28 0,-1.26 1.59,-2.28 3.56,-2.28 z" - id="path3735" - inkscape:connector-curvature="0" - style="fill:url(#x)" /><path - d="m 250.99,105.42 c 1.66,0 3,-0.71 3,-1.59 0,-0.88 -1.34,-1.59 -3,-1.59 -1.66,0 -3,0.71 -3,1.59 0,0.88 1.34,1.59 3,1.59 z" - id="path3737" - inkscape:connector-curvature="0" - style="fill:url(#y)" /><path - d="m 218,107 c -2.76,0 -5,2.24 -5,5 0,2.76 2.24,5 5,5 2.76,0 5,-2.24 5,-5 0,-2.76 -2.24,-5 -5,-5" - id="path3741" - inkscape:connector-curvature="0" - style="fill:url(#q)" /><path - d="m 213.36,112 c 0,2.56 2.08,4.64 4.64,4.64 2.56,0 4.64,-2.08 4.64,-4.64 0,-2.56 -2.08,-4.64 -4.64,-4.64 -2.56,0 -4.64,2.08 -4.64,4.64" - id="path3743" - inkscape:connector-curvature="0" - style="fill:#2a53cd" /><path - d="m 216.93,109.14 c -0.03,-0.53 0.55,-0.97 1.06,-0.83 0.5,0.12 0.79,0.73 0.56,1.18 -0.2,0.44 -0.79,0.61 -1.2,0.36 -0.26,-0.14 -0.42,-0.42 -0.42,-0.71 z m 1.7,5.46 c 0.22,0 0.45,0 0.67,0 0,0.18 0,0.35 0,0.53 -0.96,0 -1.93,0 -2.89,0 0,-0.18 0,-0.35 0,-0.53 0.22,0 0.44,0 0.66,0 0,-1.2 0,-2.41 0,-3.61 -0.22,0 -0.44,0 -0.66,0 0,-0.18 0,-0.35 0,-0.53 0.74,0 1.48,0 2.22,0 0,1.38 0,2.76 0,4.14 z" - id="path3745" - inkscape:connector-curvature="0" - style="fill:#ffffff" /><path - d="m 227.25,107 c -0.7,0 -1.25,0.5 -1.25,1.25 l 0,7.5 c 0,0.7 0.5,1.25 1.25,1.25 l 3.5,0 c 0.7,0 1.25,-0.5 1.25,-1.25 l 0,-7.5 c 0,-0.7 -0.5,-1.25 -1.25,-1.25 l -3.5,0 z m -0.25,1 4,0 0,7 -4,0 0,-7 z m 2,7.25 c 0.4,0 0.75,0.3 0.75,0.75 0,0.4 -0.3,0.75 -0.75,0.75 -0.4,0 -0.75,-0.3 -0.75,-0.75 0,-0.4 0.3,-0.75 0.75,-0.75 z" - id="path3765" - inkscape:connector-curvature="0" /><path style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" d="m 110.49999,127.4989 -1,0 2,-2 2,2 -1,0 c 0,0 -0.0345,4.6379 -0.0345,4.0345 l 4.03448,-0.034 0,-1 2,2 -2,2 0,-1 -4.03449,-0.034 0.0345,4.0346 1,0 -2,2 -2,-2 1,0 0.0345,-4.0346 -4.03448,0.034 0,1 -2,-2 2,-2 0,1 4.03448,0.034 z" id="path3550" @@ -739,20 +628,6 @@ id="path3963" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccc" /><g - id="g3234" - transform="translate(1,0)"><path - style="fill:url(#linearGradient3239)" - inkscape:connector-curvature="0" - id="path3699-5" - d="m 250,107 c -2.76,0 -5,2.24 -5,5 0,2.76 2.24,5 5,5 2.76,0 5,-2.24 5,-5 0,-2.76 -2.24,-5 -5,-5" /><path - id="path3701-0" - d="m 245.36,112 c 0,2.56 2.08,4.64 4.64,4.64 2.56,0 4.64,-2.08 4.64,-4.64 0,-2.56 -2.08,-4.64 -4.64,-4.64 -2.56,0 -4.64,2.08 -4.64,4.64" - inkscape:connector-curvature="0" - style="fill:#f4979b;fill-opacity:1" /><path - style="fill:#ffffff;fill-opacity:1" - id="path3689-2" - d="m 248.64912,113.55532 -1.12,-1.57887 -0.94113,0.9411 1.98332,2.80777 5.01668,-5.96555 -0.8711,-1.03445 z" - inkscape:connector-curvature="0" /></g><g id="Animations-Toggle" transform="translate(199.99866,124.00442)"><path d="M 6,2 12,8 6,14 0,8" @@ -1072,9 +947,4 @@ style="fill:#5b5b5b" inkscape:connector-curvature="0" d="M 10.192064,11.106277 C 9.4413335,11.667599 8.509485,12 7.5,12 5.0147186,12 3,9.9852814 3,7.5 3,5.0147186 5.0147186,3 7.5,3 9.9852814,3 12,5.0147186 12,7.5 c 0,1.1153728 -0.405792,2.1359679 -1.077795,2.922205 l 2.345562,2.345562 -0.707107,0.707107 -2.368596,-2.368597 z M 7.5,11 C 9.4329966,11 11,9.4329966 11,7.5 11,5.5670034 9.4329966,4 7.5,4 5.5670034,4 4,5.5670034 4,7.5 4,9.4329966 5.5670034,11 7.5,11 z" - id="path3730" /></g></g><path - inkscape:connector-curvature="0" - id="path3660" - d="m 236,115 4,0 0,2 5,-4.5 -5,-4.5 0,2 -4,0 z" - style="fill:#4688f1;fill-opacity:1" - sodipodi:nodetypes="cccccccc" /></svg> \ No newline at end of file + id="path3730" /></g></g></svg> \ No newline at end of file
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs.png b/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs.png index 6982b00..49c99a1 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs.png +++ b/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs.png Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs_2x.png b/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs_2x.png index ddf5f38..263d3e3 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs_2x.png +++ b/third_party/WebKit/Source/devtools/front_end/Images/toolbarButtonGlyphs_2x.png Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/animation/AnimationModel.js b/third_party/WebKit/Source/devtools/front_end/animation/AnimationModel.js index 18ee044..1c49a820 100644 --- a/third_party/WebKit/Source/devtools/front_end/animation/AnimationModel.js +++ b/third_party/WebKit/Source/devtools/front_end/animation/AnimationModel.js
@@ -467,14 +467,6 @@ /** * @return {number} */ - playbackRate: function() - { - return this._payload.playbackRate; - }, - - /** - * @return {number} - */ iterationStart: function() { return this._payload.iterationStart;
diff --git a/third_party/WebKit/Source/devtools/front_end/audits/auditResultTree.css b/third_party/WebKit/Source/devtools/front_end/audits/auditResultTree.css index c618aeb..b8c5227 100644 --- a/third_party/WebKit/Source/devtools/front_end/audits/auditResultTree.css +++ b/third_party/WebKit/Source/devtools/front_end/audits/auditResultTree.css
@@ -5,8 +5,8 @@ */ .severity { - background-image: url(Images/toolbarButtonGlyphs.png); - background-size: 352px 168px; + background-image: url(Images/smallIcons.png); + background-size: 190px 30px; display: inline-block; width: 11px; height: 11px; @@ -21,20 +21,20 @@ @media (-webkit-min-device-pixel-ratio: 1.5) { .severity { - background-image: url(Images/toolbarButtonGlyphs_2x.png); + background-image: url(Images/smallIcons_2x.png); } } /* media */ .severity.severe { - background-position: -224px -96px; + background-position: -120px 0; } .severity.warning { - background-position: -246px -96px; + background-position: -160px 0; } .severity.info { - background-position: -235px -96px; + background-position: -140px 0; } .audit-result { font-weight: bold;
diff --git a/third_party/WebKit/Source/devtools/front_end/common/Settings.js b/third_party/WebKit/Source/devtools/front_end/common/Settings.js index 5f12cc70..5c4f0484 100644 --- a/third_party/WebKit/Source/devtools/front_end/common/Settings.js +++ b/third_party/WebKit/Source/devtools/front_end/common/Settings.js
@@ -730,14 +730,14 @@ _migrateSettingsFromLocalStorage: function() { // This step migrates all the settings except for the ones below into the browser profile. - var localSettings = [ "advancedSearchConfig", "breakpoints", "consoleHistory", "domBreakpoints", "eventListenerBreakpoints", + var localSettings = new Set([ "advancedSearchConfig", "breakpoints", "consoleHistory", "domBreakpoints", "eventListenerBreakpoints", "fileSystemMapping", "lastSelectedSourcesSidebarPaneTab", "previouslyViewedFiles", - "savedURLs", "watchExpressions", "workspaceExcludedFolders", "xhrBreakpoints" ].keySet(); + "savedURLs", "watchExpressions", "workspaceExcludedFolders", "xhrBreakpoints" ]); if (!window.localStorage) return; for (var key in window.localStorage) { - if (key in localSettings) + if (localSettings.has(key)) continue; var value = window.localStorage[key]; window.localStorage.removeItem(key);
diff --git a/third_party/WebKit/Source/devtools/front_end/common/Worker.js b/third_party/WebKit/Source/devtools/front_end/common/Worker.js index bf3ceeb..5dd6087 100644 --- a/third_party/WebKit/Source/devtools/front_end/common/Worker.js +++ b/third_party/WebKit/Source/devtools/front_end/common/Worker.js
@@ -49,14 +49,18 @@ var isSharedWorker = !!workerName; if (isSharedWorker) { worker = new SharedWorker(url, workerName); - worker.port.onmessage = onMessage; + worker.port.onmessage = onMessage.bind(this); } else { worker = new Worker(url); - worker.onmessage = onMessage; + worker.onmessage = onMessage.bind(this); } + // Hold a reference to worker until the promise is resolved. + // Otherwise the worker could be GCed. + this._workerProtect = worker; /** * @param {!Event} event + * @this {WebInspector.Worker} */ function onMessage(event) { @@ -66,6 +70,7 @@ else worker.onmessage = null; callback(worker); + this._workerProtect = null; } }
diff --git a/third_party/WebKit/Source/devtools/front_end/components/BreakpointsSidebarPaneBase.js b/third_party/WebKit/Source/devtools/front_end/components/BreakpointsSidebarPaneBase.js index 251248e..949a68d 100644 --- a/third_party/WebKit/Source/devtools/front_end/components/BreakpointsSidebarPaneBase.js +++ b/third_party/WebKit/Source/devtools/front_end/components/BreakpointsSidebarPaneBase.js
@@ -30,12 +30,11 @@ /** * @constructor - * @extends {WebInspector.SimpleView} - * @param {string} title + * @extends {WebInspector.VBox} */ -WebInspector.BreakpointsSidebarPaneBase = function(title) +WebInspector.BreakpointsSidebarPaneBase = function() { - WebInspector.SimpleView.call(this, title); + WebInspector.VBox.call(this); this.registerRequiredCSS("components/breakpointsList.css"); this.listElement = createElement("ol"); @@ -46,6 +45,9 @@ this.emptyElement.textContent = WebInspector.UIString("No Breakpoints"); this.element.appendChild(this.emptyElement); + WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerPaused, this._update, this); + WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerResumed, this._update, this); + WebInspector.context.addFlavorChangeListener(WebInspector.Target, this._update, this); } WebInspector.BreakpointsSidebarPaneBase.prototype = { @@ -92,5 +94,19 @@ } }, - __proto__: WebInspector.SimpleView.prototype + _update: function() + { + var target = WebInspector.context.flavor(WebInspector.Target); + var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); + var details = debuggerModel ? debuggerModel.debuggerPausedDetails() : null; + this.highlightDetails(details); + }, + + /** + * @param {?WebInspector.DebuggerPausedDetails} details + * @protected + */ + highlightDetails: function(details) { }, + + __proto__: WebInspector.VBox.prototype }
diff --git a/third_party/WebKit/Source/devtools/front_end/components/DOMBreakpointsSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/components/DOMBreakpointsSidebarPane.js index 35d0bbf..6c38cbe 100644 --- a/third_party/WebKit/Source/devtools/front_end/components/DOMBreakpointsSidebarPane.js +++ b/third_party/WebKit/Source/devtools/front_end/components/DOMBreakpointsSidebarPane.js
@@ -34,7 +34,7 @@ */ WebInspector.DOMBreakpointsSidebarPane = function() { - WebInspector.BreakpointsSidebarPaneBase.call(this, WebInspector.UIString("DOM Breakpoints")); + WebInspector.BreakpointsSidebarPaneBase.call(this); this._domBreakpointsSetting = WebInspector.settings.createLocalSetting("domBreakpoints", []); this.listElement.classList.add("dom-breakpoints-list"); @@ -320,25 +320,29 @@ this._saveBreakpoints(); }, - highlightBreakpoint: function(auxData) + /** + * @override + * @param {?WebInspector.DebuggerPausedDetails} details + */ + highlightDetails: function(details) { + if (!details || details.reason !== WebInspector.DebuggerModel.BreakReason.DOM) { + if (this._highlightedElement) { + this._highlightedElement.classList.remove("breakpoint-hit"); + delete this._highlightedElement; + } + return; + } + var auxData = details.auxData; var breakpointId = this._createBreakpointId(auxData.nodeId, auxData.type); var element = this._breakpointElements[breakpointId]; if (!element) return; - this.revealView(); + WebInspector.viewManager.revealViewWithWidget(this); element.classList.add("breakpoint-hit"); this._highlightedElement = element; }, - clearBreakpointHighlight: function() - { - if (this._highlightedElement) { - this._highlightedElement.classList.remove("breakpoint-hit"); - delete this._highlightedElement; - } - }, - /** * @param {number} nodeId * @param {!DOMDebuggerAgent.DOMBreakpointType} type
diff --git a/third_party/WebKit/Source/devtools/front_end/components/DOMPresentationUtils.js b/third_party/WebKit/Source/devtools/front_end/components/DOMPresentationUtils.js index ac8dca3e..2347ad52 100644 --- a/third_party/WebKit/Source/devtools/front_end/components/DOMPresentationUtils.js +++ b/third_party/WebKit/Source/devtools/front_end/components/DOMPresentationUtils.js
@@ -452,21 +452,18 @@ continue; needsClassNames = true; - var ownClassNames = prefixedOwnClassNamesArray.keySet(); - var ownClassNameCount = 0; - for (var name in ownClassNames) - ++ownClassNameCount; - if (ownClassNameCount === 0) { + var ownClassNames = new Set(prefixedOwnClassNamesArray); + if (!ownClassNames.size) { needsNthChild = true; continue; } var siblingClassNamesArray = prefixedElementClassNames(sibling); for (var j = 0; j < siblingClassNamesArray.length; ++j) { var siblingClass = siblingClassNamesArray[j]; - if (!ownClassNames.hasOwnProperty(siblingClass)) + if (!ownClassNames.has(siblingClass)) continue; - delete ownClassNames[siblingClass]; - if (!--ownClassNameCount) { + ownClassNames.delete(siblingClass); + if (!ownClassNames.size) { needsNthChild = true; break; } @@ -479,7 +476,7 @@ if (needsNthChild) { result += ":nth-child(" + (ownIndex + 1) + ")"; } else if (needsClassNames) { - for (var prefixedName in prefixedOwnClassNamesArray.keySet()) + for (var prefixedName of prefixedOwnClassNamesArray) result += "." + escapeIdentifierIfNeeded(prefixedName.substr(1)); }
diff --git a/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js b/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js index 1c057b0..6635cbf0 100644 --- a/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js +++ b/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js
@@ -136,6 +136,7 @@ this._prompt.renderAsBlock(); var proxyElement = this._prompt.attach(this._promptElement); proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this), false); + proxyElement.addEventListener("input", this._promptInput.bind(this), false); this._consoleHistorySetting = WebInspector.settings.createLocalSetting("consoleHistory", []); var historyData = this._consoleHistorySetting.get(); @@ -154,6 +155,11 @@ this._initConsoleMessages(); WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext, this._executionContextChanged, this); + + this._messagesElement.addEventListener("mousedown", this._updateStickToBottomOnMouseDown.bind(this), false); + this._messagesElement.addEventListener("mouseup", this._updateStickToBottomOnMouseUp.bind(this), false); + this._messagesElement.addEventListener("mouseleave", this._updateStickToBottomOnMouseUp.bind(this), false); + this._messagesElement.addEventListener("wheel", this._updateStickToBottomOnWheel.bind(this), false); } WebInspector.ConsoleView.persistedHistorySize = 300; @@ -344,7 +350,7 @@ restoreScrollPositions: function() { - if (this._viewport.scrolledToBottom()) + if (this._viewport.stickToBottom()) this._immediatelyScrollToBottom(); else WebInspector.Widget.prototype.restoreScrollPositions.call(this); @@ -354,7 +360,7 @@ { this._scheduleViewportRefresh(); this._hidePromptSuggestBox(); - if (this._viewport.scrolledToBottom()) + if (this._viewport.stickToBottom()) this._immediatelyScrollToBottom(); for (var i = 0; i < this._visibleViewMessages.length; ++i) this._visibleViewMessages[i].onResize(); @@ -374,6 +380,10 @@ */ function invalidateViewport() { + if (this._muteViewportUpdates) { + this._maybeDirtyWhileMuted = true; + return Promise.resolve(); + } if (this._needsFullUpdate) { this._updateMessageList(); delete this._needsFullUpdate; @@ -382,12 +392,28 @@ } return Promise.resolve(); } + if (this._muteViewportUpdates) { + this._maybeDirtyWhileMuted = true; + this._scheduleViewportRefreshForTest(true); + return; + } else { + this._scheduleViewportRefreshForTest(false); + } this._viewportThrottler.schedule(invalidateViewport.bind(this)); }, + /** + * @param {boolean} muted + */ + _scheduleViewportRefreshForTest: function(muted) + { + // This functions is sniffed in tests. + }, + _immediatelyScrollToBottom: function() { // This will scroll viewport and trigger its refresh. + this._viewport.setStickToBottom(true); this._promptElement.scrollIntoView(true); }, @@ -744,6 +770,7 @@ _promptKeyDown: function(event) { + this._updateStickToBottomOnWheel(); if (isEnterKey(event)) { this._enterKeyPressed(event); return; @@ -774,18 +801,17 @@ /** * @param {?WebInspector.RemoteObject} result - * @param {boolean} wasThrown * @param {!WebInspector.ConsoleMessage} originatingConsoleMessage - * @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails + * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails */ - _printResult: function(result, wasThrown, originatingConsoleMessage, exceptionDetails) + _printResult: function(result, originatingConsoleMessage, exceptionDetails) { if (!result) return; - var level = wasThrown ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log; + var level = !!exceptionDetails ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log; var message; - if (!wasThrown) + if (!exceptionDetails) message = new WebInspector.ConsoleMessage(result.target(), WebInspector.ConsoleMessage.MessageSource.JS, level, "", WebInspector.ConsoleMessage.MessageType.Result, undefined, undefined, undefined, undefined, [result]); else message = new WebInspector.ConsoleMessage(result.target(), WebInspector.ConsoleMessage.MessageSource.JS, level, exceptionDetails.text, WebInspector.ConsoleMessage.MessageType.Result, undefined, exceptionDetails.lineNumber, exceptionDetails.columnNumber, undefined, [WebInspector.UIString("Uncaught"), result], exceptionDetails.stackTrace, undefined, undefined, exceptionDetails.scriptId); @@ -813,10 +839,10 @@ */ _commandEvaluated: function(event) { - var data = /** @type {{result: ?WebInspector.RemoteObject, wasThrown: boolean, text: string, commandMessage: !WebInspector.ConsoleMessage, exceptionDetails: (?RuntimeAgent.ExceptionDetails|undefined)}} */ (event.data); + var data = /** @type {{result: ?WebInspector.RemoteObject, text: string, commandMessage: !WebInspector.ConsoleMessage, exceptionDetails: (!RuntimeAgent.ExceptionDetails|undefined)}} */ (event.data); this._prompt.history().pushHistoryItem(data.text); this._consoleHistorySetting.set(this._prompt.history().historyData().slice(-WebInspector.ConsoleView.persistedHistorySize)); - this._printResult(data.result, data.wasThrown, data.commandMessage, data.exceptionDetails); + this._printResult(data.result, data.commandMessage, data.exceptionDetails); }, /** @@ -995,6 +1021,60 @@ highlightNode.scrollIntoViewIfNeeded(); }, + _updateStickToBottomOnMouseDown: function() + { + this._muteViewportUpdates = true; + this._viewport.setStickToBottom(false); + if (this._waitForScrollTimeout) { + clearTimeout(this._waitForScrollTimeout); + delete this._waitForScrollTimeout; + } + }, + + _updateStickToBottomOnMouseUp: function() + { + if (!this._muteViewportUpdates) + return; + + // Delay querying isScrolledToBottom to give time for smooth scroll + // events to arrive. The value for the longest timeout duration is + // retrieved from crbug.com/575409. + this._waitForScrollTimeout = setTimeout(updateViewportState.bind(this), 200); + + /** + * @this {!WebInspector.ConsoleView} + */ + function updateViewportState() + { + this._muteViewportUpdates = false; + this._viewport.setStickToBottom(this._messagesElement.isScrolledToBottom()); + if (this._maybeDirtyWhileMuted) { + this._scheduleViewportRefresh(); + delete this._maybeDirtyWhileMuted; + } + delete this._waitForScrollTimeout; + this._updateViewportStickinessForTest(); + } + }, + + _updateViewportStickinessForTest: function() + { + // This method is sniffed in tests. + }, + + _updateStickToBottomOnWheel: function() + { + this._updateStickToBottomOnMouseDown(); + this._updateStickToBottomOnMouseUp(); + }, + + _promptInput: function(event) + { + // Scroll to the bottom, except when the prompt is the only visible item. + if (this.itemCount() !== 0 && this._viewport.firstVisibleIndex() !== this.itemCount()) + this._immediatelyScrollToBottom(); + }, + __proto__: WebInspector.VBox.prototype }
diff --git a/third_party/WebKit/Source/devtools/front_end/console/consoleView.css b/third_party/WebKit/Source/devtools/front_end/console/consoleView.css index 3365122e..1f0a452 100644 --- a/third_party/WebKit/Source/devtools/front_end/console/consoleView.css +++ b/third_party/WebKit/Source/devtools/front_end/console/consoleView.css
@@ -65,11 +65,11 @@ } #console-prompt::before { - background-position: -192px -96px; + background-position: -20px -20px; } .console-log-level .console-user-command-result::before { - background-position: -202px -96px; + background-position: -40px -20px; } .console-message, @@ -109,8 +109,8 @@ height: 10px; margin-top: -4px; -webkit-user-select: none; - background-image: url(Images/toolbarButtonGlyphs.png); - background-size: 352px 168px; + background-image: url(Images/smallIcons.png); + background-size: 190px 30px; } @media (-webkit-min-device-pixel-ratio: 1.5) { @@ -118,7 +118,7 @@ .console-user-command::before, #console-prompt::before, .console-group-title::before { - background-image: url(Images/toolbarButtonGlyphs_2x.png); + background-image: url(Images/smallIcons_2x.png); } } /* media */ @@ -312,8 +312,8 @@ .console-warning-level .console-message::before, .console-debug-level .console-message::before, .console-info-level .console-message::before { - background-image: url(Images/toolbarButtonGlyphs.png); - background-size: 352px 168px; + background-image: url(Images/smallIcons.png); + background-size: 190px 30px; width: 10px; height: 10px; } @@ -324,24 +324,24 @@ .console-warning-level .console-message::before, .console-debug-level .console-message::before, .console-info-level .console-message::before { - background-image: url(Images/toolbarButtonGlyphs_2x.png); + background-image: url(Images/smallIcons_2x.png); } } /* media */ .console-warning-level .console-message::before { - background-position: -202px -107px; + background-position: -60px 0; } .console-error-level .console-message::before { - background-position: -213px -96px; + background-position: -20px 0; } .console-revokedError-level .console-message::before { - background-position: -245px -107px; + background-position: -40px 0; } .console-info-level .console-message::before { - background-position: -213px -107px; + background-position: -80px 0; } .console-user-command .console-message { @@ -351,7 +351,7 @@ } .console-user-command::before { - background-position: -192px -107px; + background-position: 0 -20px; } #console-messages .link {
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeElement.js b/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeElement.js index 3d040a3..f9545ac 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeElement.js +++ b/third_party/WebKit/Source/devtools/front_end/elements/ElementsTreeElement.js
@@ -56,15 +56,15 @@ // A union of HTML4 and HTML5-Draft elements that explicitly // or implicitly (for HTML5) forbid the closing tag. -WebInspector.ElementsTreeElement.ForbiddenClosingTagElements = [ +WebInspector.ElementsTreeElement.ForbiddenClosingTagElements = new Set([ "area", "base", "basefont", "br", "canvas", "col", "command", "embed", "frame", "hr", "img", "input", "keygen", "link", "menuitem", "meta", "param", "source", "track", "wbr" -].keySet(); +]); // These tags we do not allow editing their tag name. -WebInspector.ElementsTreeElement.EditTagBlacklist = [ +WebInspector.ElementsTreeElement.EditTagBlacklist = new Set([ "html", "head", "body" -].keySet(); +]); /** * @param {!WebInspector.ElementsTreeElement} treeElement @@ -725,7 +725,7 @@ } var tagName = tagNameElement.textContent; - if (WebInspector.ElementsTreeElement.EditTagBlacklist[tagName.toLowerCase()]) + if (WebInspector.ElementsTreeElement.EditTagBlacklist.has(tagName.toLowerCase())) return false; if (WebInspector.isBeingEdited(tagNameElement)) @@ -1438,7 +1438,7 @@ break; } - if (this.treeOutline.isXMLMimeType || !WebInspector.ElementsTreeElement.ForbiddenClosingTagElements[tagName]) + if (this.treeOutline.isXMLMimeType || !WebInspector.ElementsTreeElement.ForbiddenClosingTagElements.has(tagName)) this._buildTagDOM(titleDOM, tagName, true, false, updateRecord); break;
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/EventListenersWidget.js b/third_party/WebKit/Source/devtools/front_end/elements/EventListenersWidget.js index 61ace32..86886ee 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/EventListenersWidget.js +++ b/third_party/WebKit/Source/devtools/front_end/elements/EventListenersWidget.js
@@ -30,12 +30,13 @@ /** * @constructor * @extends {WebInspector.ThrottledWidget} + * @implements {WebInspector.ToolbarItem.ItemsProvider} */ WebInspector.EventListenersWidget = function() { WebInspector.ThrottledWidget.call(this); this.element.classList.add("events-pane"); - var toolbar = new WebInspector.Toolbar("", this.contentElement); + this._toolbarItems = []; this._showForAncestorsSetting = WebInspector.settings.moduleSetting("showEventListenersForAncestors"); this._showForAncestorsSetting.addChangeListener(this.update.bind(this)); @@ -49,8 +50,8 @@ var refreshButton = new WebInspector.ToolbarButton(WebInspector.UIString("Refresh"), "refresh-toolbar-item"); refreshButton.addEventListener("click", this.update.bind(this)); - toolbar.appendToolbarItem(refreshButton); - toolbar.appendToolbarItem(new WebInspector.ToolbarCheckbox(WebInspector.UIString("Ancestors"), WebInspector.UIString("Show listeners on the ancestors"), this._showForAncestorsSetting)); + this._toolbarItems.push(refreshButton); + this._toolbarItems.push(new WebInspector.ToolbarCheckbox(WebInspector.UIString("Ancestors"), WebInspector.UIString("Show listeners on the ancestors"), this._showForAncestorsSetting)); var dispatchFilter = new WebInspector.ToolbarComboBox(this._onDispatchFilterTypeChanged.bind(this)); /** @@ -68,8 +69,8 @@ addDispatchFilterOption.call(this, WebInspector.UIString("Passive"), WebInspector.EventListenersWidget.DispatchFilterBy.Passive); addDispatchFilterOption.call(this, WebInspector.UIString("Blocking"), WebInspector.EventListenersWidget.DispatchFilterBy.Blocking); dispatchFilter.setMaxWidth(200); - toolbar.appendToolbarItem(dispatchFilter); - toolbar.appendToolbarItem(new WebInspector.ToolbarCheckbox(WebInspector.UIString("Framework listeners"), WebInspector.UIString("Resolve event listeners bound with framework"), this._showFrameworkListenersSetting)); + this._toolbarItems.push(dispatchFilter); + this._toolbarItems.push(new WebInspector.ToolbarCheckbox(WebInspector.UIString("Framework listeners"), WebInspector.UIString("Resolve event listeners bound with framework"), this._showFrameworkListenersSetting)); WebInspector.context.addFlavorChangeListener(WebInspector.DOMNode, this.update, this); this.update(); @@ -118,6 +119,15 @@ }, /** + * @override + * @return {!Array<!WebInspector.ToolbarItem>} + */ + toolbarItems: function() + { + return this._toolbarItems; + }, + + /** * @param {!Event} event */ _onDispatchFilterTypeChanged: function(event)
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js index a392a8ee..da94dcc7 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js +++ b/third_party/WebKit/Source/devtools/front_end/elements/StylesSidebarPane.js
@@ -2927,7 +2927,7 @@ if (!word) return false; word = word.toLowerCase(); - return this._cssCompletions.keySet().hasOwnProperty(word); + return this._cssCompletions.indexOf(word) !== -1; }, /**
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/elementsPanel.css b/third_party/WebKit/Source/devtools/front_end/elements/elementsPanel.css index 64f3efd..15ec141 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/elementsPanel.css +++ b/third_party/WebKit/Source/devtools/front_end/elements/elementsPanel.css
@@ -657,15 +657,10 @@ fill: none; } -.swatch { - background-image: url(Images/checker.png); -} - li.child-editing .styles-clipboard-only { display: none; } -li.editing .swatch, li.editing .enabled-button { display: none !important; } @@ -689,17 +684,6 @@ border: 1px solid #C1C1C1; } -.swatch-inner { - width: 100%; - height: 100%; - display: inline-block; - border: 1px solid rgba(128, 128, 128, 0.6); -} - -.swatch-inner:hover { - border: 1px solid rgba(64, 64, 64, 0.8); -} - .animation-section-body { display: none; }
diff --git a/third_party/WebKit/Source/devtools/front_end/elements/module.json b/third_party/WebKit/Source/devtools/front_end/elements/module.json index 1bfc610..4dbbc3d3 100644 --- a/third_party/WebKit/Source/devtools/front_end/elements/module.json +++ b/third_party/WebKit/Source/devtools/front_end/elements/module.json
@@ -185,6 +185,7 @@ "id": "elements.eventListeners", "title": "Event Listeners", "order": 5, + "hasToolbar": true, "persistence": "permanent", "className": "WebInspector.EventListenersWidget" },
diff --git a/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionServer.js b/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionServer.js index 433b413..0690597 100644 --- a/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionServer.js +++ b/third_party/WebKit/Source/devtools/front_end/extensions/ExtensionServer.js
@@ -992,15 +992,15 @@ /** * @param {?Protocol.Error} error * @param {!RuntimeAgent.RemoteObject} result - * @param {boolean=} wasThrown + * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails */ - function onEvalute(error, result, wasThrown) + function onEvalute(error, result, exceptionDetails) { if (error) { - callback(error, null, wasThrown); + callback(error, null, !!exceptionDetails); return; } - callback(error, target.runtimeModel.createRemoteObject(result), wasThrown); + callback(error, target.runtimeModel.createRemoteObject(result), !!exceptionDetails); } },
diff --git a/third_party/WebKit/Source/devtools/front_end/formatter_worker/CSSRuleParser.js b/third_party/WebKit/Source/devtools/front_end/formatter_worker/CSSRuleParser.js index 831b188..06458dd 100644 --- a/third_party/WebKit/Source/devtools/front_end/formatter_worker/CSSRuleParser.js +++ b/third_party/WebKit/Source/devtools/front_end/formatter_worker/CSSRuleParser.js
@@ -33,7 +33,7 @@ var state = WebInspector.CSSParserStates.Initial; var rule; var property; - var UndefTokenType = {}; + var UndefTokenType = new Set(); var disabledRules = []; function disabledRulesCallback(chunk) @@ -49,10 +49,10 @@ */ function processToken(tokenValue, tokenTypes, column, newColumn) { - var tokenType = tokenTypes ? tokenTypes.split(" ").keySet() : UndefTokenType; + var tokenType = tokenTypes ? new Set(tokenTypes.split(" ")) : UndefTokenType; switch (state) { case WebInspector.CSSParserStates.Initial: - if (tokenType["qualifier"] || tokenType["builtin"] || tokenType["tag"]) { + if (tokenType.has("qualifier") || tokenType.has("builtin") || tokenType.has("tag")) { rule = { selectorText: tokenValue, lineNumber: lineNumber, @@ -60,7 +60,7 @@ properties: [], }; state = WebInspector.CSSParserStates.Selector; - } else if (tokenType["def"]) { + } else if (tokenType.has("def")) { rule = { atRule: tokenValue, lineNumber: lineNumber, @@ -88,7 +88,7 @@ } break; case WebInspector.CSSParserStates.Style: - if (tokenType["meta"] || tokenType["property"]) { + if (tokenType.has("meta") || tokenType.has("property")) { property = { name: tokenValue, value: "", @@ -101,7 +101,7 @@ rule.styleRange.endColumn = column; rules.push(rule); state = WebInspector.CSSParserStates.Initial; - } else if (tokenType["comment"]) { + } else if (tokenType.has("comment")) { // The |processToken| is called per-line, so no token spans more than one line. // Support only a one-line comments. if (tokenValue.substring(0, 2) !== "/*" || tokenValue.substring(tokenValue.length - 2) !== "*/") @@ -136,7 +136,7 @@ property.nameRange.endColumn = column; property.valueRange = createRange(lineNumber, newColumn); state = WebInspector.CSSParserStates.PropertyValue; - } else if (tokenType["property"]) { + } else if (tokenType.has("property")) { property.name += tokenValue; } break; @@ -156,7 +156,7 @@ } else { state = WebInspector.CSSParserStates.Style; } - } else if (!tokenType["comment"]) { + } else if (!tokenType.has("comment")) { property.value += tokenValue; } break;
diff --git a/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js b/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js index 313fc9a..2a52308 100644 --- a/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js +++ b/third_party/WebKit/Source/devtools/front_end/network/NetworkLogView.js
@@ -1021,7 +1021,9 @@ var re = this._searchRegex; if (!re) return false; - return re.test(request.name()) || (this._networkLogLargeRowsSetting.get() && re.test(request.path())); + + var text = this._networkLogLargeRowsSetting.get() ? request.path() + "/" + request.name() : request.name(); + return re.test(text); }, _clearSearchMatchedList: function() @@ -1216,7 +1218,7 @@ regex = this._textFilterUI.regex(); } - var filter = WebInspector.NetworkLogView._requestNameOrPathFilter.bind(null, regex); + var filter = WebInspector.NetworkLogView._requestPathFilter.bind(null, regex); if (negative) filter = WebInspector.NetworkLogView._negativeFilter.bind(null, filter); return filter; @@ -1514,11 +1516,12 @@ * @param {!WebInspector.NetworkRequest} request * @return {boolean} */ -WebInspector.NetworkLogView._requestNameOrPathFilter = function(regex, request) +WebInspector.NetworkLogView._requestPathFilter = function(regex, request) { if (!regex) return false; - return regex.test(request.name()) || regex.test(request.path()); + + return regex.test(request.path() + "/" + request.name()); } /**
diff --git a/third_party/WebKit/Source/devtools/front_end/network/RequestTimingView.js b/third_party/WebKit/Source/devtools/front_end/network/RequestTimingView.js index 5cda044..14196e4 100644 --- a/third_party/WebKit/Source/devtools/front_end/network/RequestTimingView.js +++ b/third_party/WebKit/Source/devtools/front_end/network/RequestTimingView.js
@@ -89,14 +89,14 @@ Waiting: "waiting" }; -WebInspector.RequestTimingView.ConnectionSetupRangeNames = [ +WebInspector.RequestTimingView.ConnectionSetupRangeNames = new Set([ WebInspector.RequestTimeRangeNames.Queueing, WebInspector.RequestTimeRangeNames.Blocking, WebInspector.RequestTimeRangeNames.Connecting, WebInspector.RequestTimeRangeNames.DNS, WebInspector.RequestTimeRangeNames.Proxy, WebInspector.RequestTimeRangeNames.SSL -].keySet(); +]); /** @typedef {{name: !WebInspector.RequestTimeRangeNames, start: number, end: number}} */ WebInspector.RequestTimeRange; @@ -248,7 +248,7 @@ } if (rangeName === WebInspector.RequestTimeRangeNames.Push) { createHeader(WebInspector.UIString("Server Push")); - } else if (WebInspector.RequestTimingView.ConnectionSetupRangeNames[rangeName]) { + } else if (WebInspector.RequestTimingView.ConnectionSetupRangeNames.has(rangeName)) { if (!connectionHeader) connectionHeader = createHeader(WebInspector.UIString("Connection Setup")); } else { @@ -284,8 +284,57 @@ note.appendChild(WebInspector.linkifyDocumentationURLAsNode("profile/network-performance/resource-loading#view-network-timing-details-for-a-specific-resource", WebInspector.UIString("Explanation"))); footer.createChild("td").createTextChild(Number.secondsToString(totalDuration, true)); + var serverTimings = request.serverTimings; + if (!serverTimings) + return tableElement; + + var lastTimingRightEdge = right === undefined ? 100 : right; + + var breakElement = tableElement.createChild("tr", "network-timing-table-header").createChild("td"); + breakElement.colSpan = 3; + breakElement.createChild("hr", "break"); + + var serverHeader = tableElement.createChild("tr", "network-timing-table-header"); + serverHeader.createChild("td").createTextChild(WebInspector.UIString("Server Timing")); + serverHeader.createChild("td"); + serverHeader.createChild("td").createTextChild(WebInspector.UIString("TIME")); + + serverTimings.filter(item => item.metric.toLowerCase() !== "total").forEach(item => addTiming(item, lastTimingRightEdge)); + serverTimings.filter(item => item.metric.toLowerCase() === "total").forEach(item => addTiming(item, lastTimingRightEdge)); + return tableElement; + + /** + * @param {!WebInspector.ServerTiming} serverTiming + * @param {number} right + */ + function addTiming(serverTiming, right) + { + var colorGenerator = new WebInspector.FlameChart.ColorGenerator( + { min: 0, max: 360, count:36 }, + { min: 50, max: 80 }, + 80 + ); + var isTotal = serverTiming.metric.toLowerCase() === "total"; + var tr = tableElement.createChild("tr", isTotal ? "network-timing-footer" : ""); + var metric = tr.createChild("td", "network-timing-metric"); + metric.createTextChild(serverTiming.description || serverTiming.metric); + var row = tr.createChild("td").createChild("div", "network-timing-row"); + var left = scale * (endTime - startTime - serverTiming.value); + if (serverTiming.value && left >= 0) { // don't chart values too big or too small + var bar = row.createChild("span", "network-timing-bar server-timing"); + bar.style.left = left + "%"; + bar.style.right = right + "%"; + bar.textContent = "\u200B"; // Important for 0-time items to have 0 width. + if (!isTotal) + bar.style.backgroundColor = colorGenerator.colorForID(serverTiming.metric); + } + var label = tr.createChild("td").createChild("div", "network-timing-bar-title"); + if (typeof serverTiming.value === "number") // a metric timing value is optional + label.textContent = Number.secondsToString(serverTiming.value, true); + } + /** * param {string} title */
diff --git a/third_party/WebKit/Source/devtools/front_end/network/networkPanel.css b/third_party/WebKit/Source/devtools/front_end/network/networkPanel.css index d8dfd184..696db809 100644 --- a/third_party/WebKit/Source/devtools/front_end/network/networkPanel.css +++ b/third_party/WebKit/Source/devtools/front_end/network/networkPanel.css
@@ -97,6 +97,12 @@ padding: 2px 0; } +.network-timing-table hr.break { + border: 0; + height: 1px; + background-image: linear-gradient(to right, #eee, #bbb, #eee); +} + .network-timing-footer td { border-top: 8px solid transparent; } @@ -168,6 +174,17 @@ background-color: #8CDBff; } +.network-timing-bar.server-timing, -theme-preserve { + background-color: #ddd; +} + +.network-timing-table td.network-timing-metric { + white-space: nowrap; + max-width: 150px; + overflow-x: hidden; + text-overflow: ellipsis; +} + .network-timing-bar.proxy, .network-timing-bar.dns, .network-timing-bar.ssl,
diff --git a/third_party/WebKit/Source/devtools/front_end/platform/utilities.js b/third_party/WebKit/Source/devtools/front_end/platform/utilities.js index 9e779027..2be0749b 100644 --- a/third_party/WebKit/Source/devtools/front_end/platform/utilities.js +++ b/third_party/WebKit/Source/devtools/front_end/platform/utilities.js
@@ -486,20 +486,6 @@ } }); -Object.defineProperty(Array.prototype, "keySet", { - /** - * @return {!Object.<string, boolean>} - * @this {Array.<*>} - */ - value: function() - { - var keys = {}; - for (var i = 0; i < this.length; ++i) - keys[this[i]] = true; - return keys; - } -}); - Object.defineProperty(Array.prototype, "pushAll", { /** * @param {!Array.<!T>} array
diff --git a/third_party/WebKit/Source/devtools/front_end/profiler/profilesPanel.css b/third_party/WebKit/Source/devtools/front_end/profiler/profilesPanel.css index cef860a..6f88c47 100644 --- a/third_party/WebKit/Source/devtools/front_end/profiler/profilesPanel.css +++ b/third_party/WebKit/Source/devtools/front_end/profiler/profilesPanel.css
@@ -130,9 +130,9 @@ } .profile-warn-marker { - background-image: url(Images/toolbarButtonGlyphs.png); - background-size: 352px 168px; - background-position: -202px -107px; + background-image: url(Images/smallIcons.png); + background-size: 190px 30px; + background-position: -60px 0; width: 10px; height: 10px; vertical-align: -1px;
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBModel.js b/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBModel.js index 3cfe28d..1682246b 100644 --- a/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBModel.js +++ b/third_party/WebKit/Source/devtools/front_end/resources/IndexedDBModel.js
@@ -258,17 +258,17 @@ */ _updateOriginDatabaseNames: function(securityOrigin, databaseNames) { - var newDatabaseNames = databaseNames.keySet(); - var oldDatabaseNames = this._databaseNamesBySecurityOrigin[securityOrigin].keySet(); + var newDatabaseNames = new Set(databaseNames); + var oldDatabaseNames = new Set(this._databaseNamesBySecurityOrigin[securityOrigin]); this._databaseNamesBySecurityOrigin[securityOrigin] = databaseNames; - for (var databaseName in oldDatabaseNames) { - if (!newDatabaseNames[databaseName]) + for (var databaseName of oldDatabaseNames) { + if (!newDatabaseNames.has(databaseName)) this._databaseRemoved(securityOrigin, databaseName); } - for (var databaseName in newDatabaseNames) { - if (!oldDatabaseNames[databaseName]) + for (var databaseName of newDatabaseNames) { + if (!oldDatabaseNames.has(databaseName)) this._databaseAdded(securityOrigin, databaseName); } },
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/resourcesPanel.css b/third_party/WebKit/Source/devtools/front_end/resources/resourcesPanel.css index dd8723a..62ae87f 100644 --- a/third_party/WebKit/Source/devtools/front_end/resources/resourcesPanel.css +++ b/third_party/WebKit/Source/devtools/front_end/resources/resourcesPanel.css
@@ -137,20 +137,20 @@ height: 10px; margin-top: -7px; -webkit-user-select: none; - background-image: url(Images/toolbarButtonGlyphs.png); - background-size: 352px 168px; + background-image: url(Images/smallIcons.png); + background-size: 190px 30px; } @media (-webkit-min-device-pixel-ratio: 1.5) { .database-user-query::before, .database-query-prompt::before, .database-query-result::before { - background-image: url(Images/toolbarButtonGlyphs_2x.png); + background-image: url(Images/smallIcons_2x.png); } } /* media */ .database-query-prompt::before { - background-position: -192px -96px; + background-position: -20px -20px; } .database-user-query { @@ -162,7 +162,7 @@ } .database-user-query::before { - background-position: -192px -107px; + background-position: 0 -20px; } .database-query-text { @@ -184,7 +184,7 @@ } .database-query-result.error::before { - background-position: -213px -96px; + background-position: -20px 0; } .resource-sidebar-tree-item .icon {
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js b/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js index 06d4f3c..c61880a1 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/CSSMetadata.js
@@ -107,7 +107,7 @@ */ isColorAwareProperty: function(propertyName) { - return !!WebInspector.CSSMetadata._colorAwareProperties[propertyName.toLowerCase()] || this.isCustomProperty(propertyName.toLowerCase()); + return !!WebInspector.CSSMetadata._colorAwareProperties.has(propertyName.toLowerCase()) || this.isCustomProperty(propertyName.toLowerCase()); }, /** @@ -119,7 +119,7 @@ propertyName = propertyName.toLowerCase(); if (propertyName === "line-height") return false; - return WebInspector.CSSMetadata._distanceProperties[propertyName] || propertyName.startsWith("margin") || propertyName.startsWith("padding") || propertyName.indexOf("width") !== -1 || propertyName.indexOf("height") !== -1; + return WebInspector.CSSMetadata._distanceProperties.has(propertyName) || propertyName.startsWith("margin") || propertyName.startsWith("padding") || propertyName.indexOf("width") !== -1 || propertyName.indexOf("height") !== -1; }, /** @@ -129,7 +129,7 @@ isBezierAwareProperty: function(propertyName) { propertyName = propertyName.toLowerCase(); - return !!WebInspector.CSSMetadata._bezierAwareProperties[propertyName] || this.isCustomProperty(propertyName); + return !!WebInspector.CSSMetadata._bezierAwareProperties.has(propertyName) || this.isCustomProperty(propertyName); }, /** @@ -229,17 +229,17 @@ return WebInspector.CSSMetadata._instance; } -WebInspector.CSSMetadata._distanceProperties = [ +WebInspector.CSSMetadata._distanceProperties = new Set([ "background-position", "border-spacing", "bottom", "font-size", "height", "left", "letter-spacing", "max-height", "max-width", "min-height", "min-width", "right", "text-indent", "top", "width", "word-spacing" -].keySet(); +]); -WebInspector.CSSMetadata._bezierAwareProperties = [ +WebInspector.CSSMetadata._bezierAwareProperties = new Set([ "animation", "animation-timing-function", "transition", "transition-timing-function", "-webkit-animation", "-webkit-animation-timing-function", "-webkit-transition", "-webkit-transition-timing-function" -].keySet(); +]); -WebInspector.CSSMetadata._colorAwareProperties = [ +WebInspector.CSSMetadata._colorAwareProperties = new Set([ "backdrop-filter", "background", "background-color", "background-image", "border", "border-color", "border-image", "border-image-source", "border-bottom", "border-bottom-color", "border-left", "border-left-color", "border-right", "border-right-color", "border-top", "border-top-color", "box-shadow", "color", "column-rule", "column-rule-color", "fill", @@ -249,7 +249,7 @@ "-webkit-column-rule-color", "-webkit-filter", "-webkit-mask", "-webkit-mask-box-image", "-webkit-mask-box-image-source", "-webkit-mask-image", "-webkit-tap-highlight-color", "-webkit-text-decoration-color", "-webkit-text-emphasis", "-webkit-text-emphasis-color", "-webkit-text-fill-color", "-webkit-text-stroke", "-webkit-text-stroke-color" -].keySet(); +]); WebInspector.CSSMetadata._propertyDataMap = { "table-layout": { values: [
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js index 0f353a4..988743d 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/ConsoleModel.js
@@ -190,11 +190,9 @@ /** * @param {?WebInspector.RemoteObject} result - * @param {boolean} wasThrown - * @param {?RuntimeAgent.RemoteObject=} valueResult - * @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails + * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails */ - function printResult(result, wasThrown, valueResult, exceptionDetails) + function printResult(result, exceptionDetails) { if (!result) return; @@ -202,7 +200,7 @@ WebInspector.console.showPromise().then(reportUponEvaluation); function reportUponEvaluation() { - target.consoleModel.dispatchEventToListeners(WebInspector.ConsoleModel.Events.CommandEvaluated, {result: result, wasThrown: wasThrown, text: requestedText, commandMessage: commandMessage, exceptionDetails: exceptionDetails}); + target.consoleModel.dispatchEventToListeners(WebInspector.ConsoleModel.Events.CommandEvaluated, {result: result, text: requestedText, commandMessage: commandMessage, exceptionDetails: exceptionDetails}); } }
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js index a5e5bb2..843f7eb 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/DebuggerModel.js
@@ -463,33 +463,23 @@ * @param {!RuntimeAgent.ExecutionContextId} executionContextId * @param {string} hash * @param {*|undefined} executionContextAuxData - * @param {boolean} isInternalScript * @param {boolean} isLiveEdit * @param {string=} sourceMapURL * @param {boolean=} hasSourceURL - * @param {boolean=} deprecatedCommentWasUsed * @param {boolean=} hasSyntaxError * @return {!WebInspector.Script} */ - _parsedScriptSource: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, executionContextAuxData, isInternalScript, isLiveEdit, sourceMapURL, hasSourceURL, deprecatedCommentWasUsed, hasSyntaxError) + _parsedScriptSource: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, executionContextAuxData, isLiveEdit, sourceMapURL, hasSourceURL, hasSyntaxError) { var isContentScript = false; if (executionContextAuxData && ("isDefault" in executionContextAuxData)) isContentScript = !executionContextAuxData["isDefault"]; - var script = new WebInspector.Script(this, scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, isContentScript, isInternalScript, isLiveEdit, sourceMapURL, hasSourceURL); + var script = new WebInspector.Script(this, scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, isContentScript, isLiveEdit, sourceMapURL, hasSourceURL); this._registerScript(script); if (!hasSyntaxError) this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ParsedScriptSource, script); else this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.FailedToParseScriptSource, script); - - if (deprecatedCommentWasUsed) { - var text = WebInspector.UIString("'//@ sourceURL' and '//@ sourceMappingURL' are deprecated, please use '//# sourceURL=' and '//# sourceMappingURL=' instead."); - var msg = new WebInspector.ConsoleMessage(this.target(), WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageLevel.Warning, text, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, scriptId); - var consoleModel = this.target().consoleModel; - if (consoleModel) - consoleModel.addMessage(msg); - } return script; }, @@ -624,27 +614,21 @@ * @param {boolean} doNotPauseOnExceptionsAndMuteConsole * @param {boolean} returnByValue * @param {boolean} generatePreview - * @param {function(?WebInspector.RemoteObject, boolean, ?RuntimeAgent.RemoteObject=, ?RuntimeAgent.ExceptionDetails=)} callback + * @param {function(?WebInspector.RemoteObject, !RuntimeAgent.ExceptionDetails=)} callback */ evaluateOnSelectedCallFrame: function(code, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, callback) { /** * @param {?RuntimeAgent.RemoteObject} result - * @param {boolean=} wasThrown - * @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails + * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails * @this {WebInspector.DebuggerModel} */ - function didEvaluate(result, wasThrown, exceptionDetails) + function didEvaluate(result, exceptionDetails) { if (!result) - callback(null, false); - else if (returnByValue) - callback(null, !!wasThrown, wasThrown ? null : result, exceptionDetails); + callback(null); else - callback(this.target().runtimeModel.createRemoteObject(result), !!wasThrown, undefined, exceptionDetails); - - if (objectGroup === "console") - this.dispatchEventToListeners(WebInspector.DebuggerModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame); + callback(this.target().runtimeModel.createRemoteObject(result), exceptionDetails); } this.selectedCallFrame().evaluate(code, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, didEvaluate.bind(this)); @@ -856,15 +840,13 @@ * @param {!RuntimeAgent.ExecutionContextId} executionContextId * @param {string} hash * @param {*=} executionContextAuxData - * @param {boolean=} isInternalScript * @param {boolean=} isLiveEdit * @param {string=} sourceMapURL * @param {boolean=} hasSourceURL - * @param {boolean=} deprecatedCommentWasUsed */ - scriptParsed: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, executionContextAuxData, isInternalScript, isLiveEdit, sourceMapURL, hasSourceURL, deprecatedCommentWasUsed) + scriptParsed: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, executionContextAuxData, isLiveEdit, sourceMapURL, hasSourceURL) { - this._debuggerModel._parsedScriptSource(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, executionContextAuxData, !!isInternalScript, !!isLiveEdit, sourceMapURL, hasSourceURL, deprecatedCommentWasUsed, false); + this._debuggerModel._parsedScriptSource(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, executionContextAuxData, !!isLiveEdit, sourceMapURL, hasSourceURL, false); }, /** @@ -878,14 +860,12 @@ * @param {!RuntimeAgent.ExecutionContextId} executionContextId * @param {string} hash * @param {*=} executionContextAuxData - * @param {boolean=} isInternalScript * @param {string=} sourceMapURL * @param {boolean=} hasSourceURL - * @param {boolean=} deprecatedCommentWasUsed */ - scriptFailedToParse: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, executionContextAuxData, isInternalScript, sourceMapURL, hasSourceURL, deprecatedCommentWasUsed) + scriptFailedToParse: function(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, executionContextAuxData, sourceMapURL, hasSourceURL) { - this._debuggerModel._parsedScriptSource(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, executionContextAuxData, !!isInternalScript, false, sourceMapURL, hasSourceURL, deprecatedCommentWasUsed, true); + this._debuggerModel._parsedScriptSource(scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, executionContextAuxData, false, sourceMapURL, hasSourceURL, true); }, /** @@ -1084,24 +1064,23 @@ * @param {boolean} doNotPauseOnExceptionsAndMuteConsole * @param {boolean} returnByValue * @param {boolean} generatePreview - * @param {function(?RuntimeAgent.RemoteObject, boolean=, ?RuntimeAgent.ExceptionDetails=)} callback + * @param {function(?RuntimeAgent.RemoteObject, !RuntimeAgent.ExceptionDetails=)} callback */ evaluate: function(code, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, callback) { /** * @param {?Protocol.Error} error * @param {!RuntimeAgent.RemoteObject} result - * @param {boolean=} wasThrown - * @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails + * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails */ - function didEvaluateOnCallFrame(error, result, wasThrown, exceptionDetails) + function didEvaluateOnCallFrame(error, result, exceptionDetails) { if (error) { console.error(error); - callback(null, false); + callback(null); return; } - callback(result, wasThrown, exceptionDetails); + callback(result, exceptionDetails); } this._debuggerAgent.evaluateOnCallFrame(this._payload.callFrameId, code, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, didEvaluateOnCallFrame); },
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/NetworkRequest.js b/third_party/WebKit/Source/devtools/front_end/sdk/NetworkRequest.js index 950dc6cb..6bdd17b 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/NetworkRequest.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/NetworkRequest.js
@@ -739,6 +739,7 @@ { this._responseHeaders = x; delete this._sortedResponseHeaders; + delete this._serverTimings; delete this._responseCookies; this._responseHeaderValues = {}; @@ -798,6 +799,16 @@ }, /** + * @return {?Array.<!WebInspector.ServerTiming>} + */ + get serverTimings() + { + if (typeof this._serverTimings === "undefined") + this._serverTimings = WebInspector.ServerTiming.parseHeaders(this.responseHeaders); + return this._serverTimings; + }, + + /** * @return {?string} */ queryString: function()
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/RemoteObject.js b/third_party/WebKit/Source/devtools/front_end/sdk/RemoteObject.js index 9b48adf..cf61a22 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/RemoteObject.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/RemoteObject.js
@@ -393,8 +393,9 @@ this._hasChildren = (type !== "symbol"); this._preview = preview; } else { - // Primitive or null object. - this._description = description || (value + ""); + this._description = description; + if (!this._description && (typeof value !== "object" || value === null)) + this._description = value + ""; this._hasChildren = false; if (typeof unserializableValue !== "undefined") { this._unserializableValue = unserializableValue; @@ -660,12 +661,12 @@ /** * @param {?Protocol.Error} error * @param {!RuntimeAgent.RemoteObject} result - * @param {boolean=} wasThrown + * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails * @this {WebInspector.RemoteObject} */ - function evaluatedCallback(error, result, wasThrown) + function evaluatedCallback(error, result, exceptionDetails) { - if (error || wasThrown) { + if (error || !!exceptionDetails) { callback(error || (result.type !== "string" ? result.description : /** @type {string} */(result.value))); return; } @@ -699,11 +700,11 @@ /** * @param {?Protocol.Error} error * @param {!RuntimeAgent.RemoteObject} result - * @param {boolean=} wasThrown + * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails */ - function propertySetCallback(error, result, wasThrown) + function propertySetCallback(error, result, exceptionDetails) { - if (error || wasThrown) { + if (error || !!exceptionDetails) { callback(error || result.description); return; } @@ -729,11 +730,11 @@ /** * @param {?Protocol.Error} error * @param {!RuntimeAgent.RemoteObject} result - * @param {boolean=} wasThrown + * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails */ - function deletePropertyCallback(error, result, wasThrown) + function deletePropertyCallback(error, result, exceptionDetails) { - if (error || wasThrown) { + if (error || !!exceptionDetails) { callback(error || result.description); return; } @@ -755,17 +756,17 @@ /** * @param {?Protocol.Error} error * @param {!RuntimeAgent.RemoteObject} result - * @param {boolean=} wasThrown + * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails * @this {WebInspector.RemoteObjectImpl} */ - function mycallback(error, result, wasThrown) + function mycallback(error, result, exceptionDetails) { if (!callback) return; if (error) callback(null, false); else - callback(this.target().runtimeModel.createRemoteObject(result), wasThrown); + callback(this.target().runtimeModel.createRemoteObject(result), !!exceptionDetails); } this._runtimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), args, true, undefined, undefined, undefined, undefined, mycallback.bind(this)); @@ -782,11 +783,11 @@ /** * @param {?Protocol.Error} error * @param {!RuntimeAgent.RemoteObject} result - * @param {boolean=} wasThrown + * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails */ - function mycallback(error, result, wasThrown) + function mycallback(error, result, exceptionDetails) { - callback((error || wasThrown) ? null : result.value); + callback((error || !!exceptionDetails) ? null : result.value); } this._runtimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), args, true, true, false, undefined, undefined, mycallback);
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js index 88489237..16ae069 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/ResourceTreeModel.js
@@ -75,7 +75,9 @@ WillReloadPage: "WillReloadPage", ScreencastFrame: "ScreencastFrame", ScreencastVisibilityChanged: "ScreencastVisibilityChanged", - ColorPicked: "ColorPicked" + ColorPicked: "ColorPicked", + InterstitialShown: "InterstitialShown", + InterstitialHidden: "InterstitialHidden" } /** @@ -917,7 +919,7 @@ */ interstitialShown: function() { - // Frontend is not interested in interstitials. + this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.InterstitialShown); }, /** @@ -925,7 +927,7 @@ */ interstitialHidden: function() { - // Frontend is not interested in interstitials. + this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.InterstitialHidden); }, /** @@ -933,7 +935,7 @@ */ navigationRequested: function() { - // Frontend is not interested in interstitials. + // Frontend is not interested in when navigations are requested. } }
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/RuntimeModel.js b/third_party/WebKit/Source/devtools/front_end/sdk/RuntimeModel.js index 83e423c5..86b44cd 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/RuntimeModel.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/RuntimeModel.js
@@ -256,11 +256,10 @@ /** * @param {?Protocol.Error} error - * @param {?RuntimeAgent.RemoteObject} result - * @param {boolean=} wasThrown - * @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails + * @param {!RuntimeAgent.RemoteObject} result + * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails */ - function innerCallback(error, result, wasThrown, exceptionDetails) + function innerCallback(error, result, exceptionDetails) { if (error) { console.error(error); @@ -552,7 +551,7 @@ * @param {boolean} returnByValue * @param {boolean} generatePreview * @param {boolean} userGesture - * @param {function(?WebInspector.RemoteObject, boolean, ?RuntimeAgent.RemoteObject=, ?RuntimeAgent.ExceptionDetails=)} callback + * @param {function(?WebInspector.RemoteObject, !RuntimeAgent.ExceptionDetails=)} callback */ evaluate: function(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, userGesture, callback) { @@ -566,13 +565,12 @@ /** * @param {string} objectGroup - * @param {boolean} returnByValue * @param {boolean} generatePreview - * @param {function(?WebInspector.RemoteObject, boolean, ?RuntimeAgent.RemoteObject=, ?RuntimeAgent.ExceptionDetails=)} callback + * @param {function(?WebInspector.RemoteObject, !RuntimeAgent.ExceptionDetails=)} callback */ - globalObject: function(objectGroup, returnByValue, generatePreview, callback) + globalObject: function(objectGroup, generatePreview, callback) { - this._evaluateGlobal("this", objectGroup, false, true, returnByValue, generatePreview, false, callback); + this._evaluateGlobal("this", objectGroup, false, true, false, generatePreview, false, callback); }, /** @@ -583,7 +581,7 @@ * @param {boolean} returnByValue * @param {boolean} generatePreview * @param {boolean} userGesture - * @param {function(?WebInspector.RemoteObject, boolean, ?RuntimeAgent.RemoteObject=, ?RuntimeAgent.ExceptionDetails=)} callback + * @param {function(?WebInspector.RemoteObject, !RuntimeAgent.ExceptionDetails=)} callback */ _evaluateGlobal: function(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, generatePreview, userGesture, callback) { @@ -596,21 +594,16 @@ * @this {WebInspector.ExecutionContext} * @param {?Protocol.Error} error * @param {!RuntimeAgent.RemoteObject} result - * @param {boolean=} wasThrown - * @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails + * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails */ - function evalCallback(error, result, wasThrown, exceptionDetails) + function evalCallback(error, result, exceptionDetails) { if (error) { console.error(error); - callback(null, false); + callback(null); return; } - - if (returnByValue) - callback(null, !!wasThrown, wasThrown ? null : result, exceptionDetails); - else - callback(this.runtimeModel.createRemoteObject(result), !!wasThrown, undefined, exceptionDetails); + callback(this.runtimeModel.createRemoteObject(result), exceptionDetails); } this.target().runtimeAgent().evaluate(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, this.id, returnByValue, generatePreview, userGesture, false, evalCallback.bind(this)); }, @@ -648,11 +641,13 @@ this.evaluate(expressionString, "completion", true, true, false, false, false, evaluated.bind(this)); /** + * @param {?WebInspector.RemoteObject} result + * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails * @this {WebInspector.ExecutionContext} */ - function evaluated(result, wasThrown) + function evaluated(result, exceptionDetails) { - if (!result || wasThrown) { + if (!result || !!exceptionDetails) { completionsReadyCallback([]); return; } @@ -736,15 +731,14 @@ } /** - * @param {?WebInspector.RemoteObject} notRelevant - * @param {boolean} wasThrown - * @param {?RuntimeAgent.RemoteObject=} result + * @param {?WebInspector.RemoteObject} result + * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails * @this {WebInspector.ExecutionContext} */ - function receivedPropertyNamesFromEval(notRelevant, wasThrown, result) + function receivedPropertyNamesFromEval(result, exceptionDetails) { this.target().runtimeAgent().releaseObjectGroup("completion"); - if (result && !wasThrown) + if (result && !exceptionDetails) receivedPropertyNames.call(this, /** @type {!Object} */(result.value)); else completionsReadyCallback([]);
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/Script.js b/third_party/WebKit/Source/devtools/front_end/sdk/Script.js index 2e91bac..ea09425 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/Script.js +++ b/third_party/WebKit/Source/devtools/front_end/sdk/Script.js
@@ -37,12 +37,11 @@ * @param {!RuntimeAgent.ExecutionContextId} executionContextId * @param {string} hash * @param {boolean} isContentScript - * @param {boolean} isInternalScript * @param {boolean} isLiveEdit * @param {string=} sourceMapURL * @param {boolean=} hasSourceURL */ -WebInspector.Script = function(debuggerModel, scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, isContentScript, isInternalScript, isLiveEdit, sourceMapURL, hasSourceURL) +WebInspector.Script = function(debuggerModel, scriptId, sourceURL, startLine, startColumn, endLine, endColumn, executionContextId, hash, isContentScript, isLiveEdit, sourceMapURL, hasSourceURL) { WebInspector.SDKObject.call(this, debuggerModel.target()); this.debuggerModel = debuggerModel; @@ -55,7 +54,6 @@ this._executionContextId = executionContextId; this.hash = hash; this._isContentScript = isContentScript; - this._isInternalScript = isInternalScript; this._isLiveEdit = isLiveEdit; this.sourceMapURL = sourceMapURL; this.hasSourceURL = hasSourceURL; @@ -89,6 +87,31 @@ return source.substr(0, sourceURLLineIndex) + source.substr(sourceURLLineIndex + sourceURLLine.length + 1); } +/** + * @param {!WebInspector.Script} script + * @param {string} source + */ +WebInspector.Script._reportDeprecatedCommentIfNeeded = function(script, source) +{ + var consoleModel = script.target().consoleModel; + if (!consoleModel) + return; + var linesToCheck = 5; + var offset = source.lastIndexOf("\n"); + while (linesToCheck && offset !== -1) { + offset = source.lastIndexOf("\n", offset - 1); + --linesToCheck; + } + offset = offset !== -1 ? offset : 0; + var sourceTail = source.substr(offset); + if (sourceTail.length > 5000) + return; + if (sourceTail.search(/^[\040\t]*\/\/@ source(mapping)?url=/mi) === -1) + return; + var text = WebInspector.UIString("'//@ sourceURL' and '//@ sourceMappingURL' are deprecated, please use '//# sourceURL=' and '//# sourceMappingURL=' instead."); + var msg = new WebInspector.ConsoleMessage(script.target(), WebInspector.ConsoleMessage.MessageSource.JS, WebInspector.ConsoleMessage.MessageLevel.Warning, text, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, script.scriptId); + consoleModel.addMessage(msg); +} WebInspector.Script.prototype = { /** @@ -100,14 +123,6 @@ }, /** - * @return {boolean} - */ - isInternalScript: function() - { - return this._isInternalScript; - }, - - /** * @return {?WebInspector.ExecutionContext} */ executionContext: function() @@ -164,6 +179,7 @@ */ function didGetScriptSource(error, source) { + WebInspector.Script._reportDeprecatedCommentIfNeeded(this, source); this._source = WebInspector.Script._trimSourceURLComment(error ? "" : source); callback(this._source); }
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/ServerTiming.js b/third_party/WebKit/Source/devtools/front_end/sdk/ServerTiming.js new file mode 100644 index 0000000..ab06bc2 --- /dev/null +++ b/third_party/WebKit/Source/devtools/front_end/sdk/ServerTiming.js
@@ -0,0 +1,57 @@ +// Copyright 2016 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 + * @param {string} metric + * @param {number} value + * @param {string} description + */ +WebInspector.ServerTiming = function(metric, value, description) +{ + this.metric = metric; + this.value = value; + this.description = description; +} + +/** + * @param {!Array<!WebInspector.NetworkRequest.NameValue>} headers + * @return {?Array<!WebInspector.ServerTiming>} + */ +WebInspector.ServerTiming.parseHeaders = function(headers) +{ + var rawServerTimingHeaders = headers.filter(item => item.name.toLowerCase() === "server-timing"); + if (!rawServerTimingHeaders.length) + return null; + + /** + * @param {?string} valueString + * @return {?Array<!WebInspector.ServerTiming>} + */ + function createFromHeaderValue(valueString) + { + // https://www.w3.org/TR/server-timing/ + var serverTimingMetricRegExp = /[ \t]*([\!\#\$\%\&\'\*\+\-\.\^\_\`\|\~0-9A-Za-z]+)[ \t]*(?:=[ \t]*(\d+(?:\.\d+)?))?[ \t]*(?:;[ \t]*(?:"([^"]+)"|([\!\#\$\%\&\'\*\+\-\.\^\_\`\|\~0-9A-Za-z]+)))?[ \t]*(?:,(.*))?/; + var metricMatch; + var result = []; + while (valueString && (metricMatch = serverTimingMetricRegExp.exec(valueString))) { + var metric = metricMatch[1]; + var value = metricMatch[2]; + var description = metricMatch[3] || metricMatch[4]; + if (value !== null) + value = Math.abs(parseFloat(metricMatch[2])); + valueString = metricMatch[5]; // comma delimited headers + result.push(new WebInspector.ServerTiming(metric, value, description)); + } + return result; + } + + var serverTimings = rawServerTimingHeaders.reduce((memo, header) => { + var timing = createFromHeaderValue(header.value); + Array.prototype.push.apply(memo, timing); + return memo; + }, []); + serverTimings.sort((a, b) => a.metric.toLowerCase().compareTo(b.metric.toLowerCase())); + return serverTimings; +}
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/module.json b/third_party/WebKit/Source/devtools/front_end/sdk/module.json index c7ee1ce6..1c4fd89e 100644 --- a/third_party/WebKit/Source/devtools/front_end/sdk/module.json +++ b/third_party/WebKit/Source/devtools/front_end/sdk/module.json
@@ -81,6 +81,7 @@ "ContentProviders.js", "CookieParser.js", "ProfileTreeModel.js", + "ServerTiming.js", "CPUProfileDataModel.js", "CPUProfilerModel.js", "CSSMatchedStyles.js",
diff --git a/third_party/WebKit/Source/devtools/front_end/security/SecurityPanel.js b/third_party/WebKit/Source/devtools/front_end/security/SecurityPanel.js index 3c115cdc..3ea499a 100644 --- a/third_party/WebKit/Source/devtools/front_end/security/SecurityPanel.js +++ b/third_party/WebKit/Source/devtools/front_end/security/SecurityPanel.js
@@ -248,8 +248,11 @@ this._target = target; - if (target.hasBrowserCapability()) + if (target.hasBrowserCapability()) { target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._onMainFrameNavigated, this); + target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InterstitialShown, this._onInterstitialShown, this); + target.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InterstitialHidden, this._onInterstitialHidden, this); + } var networkManager = WebInspector.NetworkManager.fromTarget(target); networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.ResponseReceived, this._onResponseReceived, this); @@ -275,7 +278,6 @@ var frame = /** type {!PageAgent.Frame}*/ (event.data); var request = this._lastResponseReceivedForLoaderId.get(frame.loaderId); - // Clear the origins list. this.selectAndSwitchToMainView(); this._sidebarTree.clearOrigins(); this._origins.clear(); @@ -292,6 +294,16 @@ } }, + _onInterstitialShown: function() + { + this._sidebarTree.toggleOriginsList(true /* hidden */); + }, + + _onInterstitialHidden: function() + { + this._sidebarTree.toggleOriginsList(false /* hidden */); + }, + __proto__: WebInspector.PanelWithSidebar.prototype } @@ -364,6 +376,19 @@ WebInspector.SecurityPanelSidebarTree.prototype = { /** + * @param {boolean} hidden + */ + toggleOriginsList: function(hidden) + { + for (var key in WebInspector.SecurityPanelSidebarTree.OriginGroupName) { + var originGroupName = WebInspector.SecurityPanelSidebarTree.OriginGroupName[key]; + var group = this._originGroups.get(originGroupName); + if (group) + group.hidden = hidden; + } + }, + + /** * @param {!WebInspector.SecurityPanel.Origin} origin * @param {!SecurityAgent.SecurityState} securityState */ @@ -544,9 +569,7 @@ var lockSpectrum = this._summarySection.createChild("div", "lock-spectrum"); lockSpectrum.createChild("div", "lock-icon lock-icon-secure").title = WebInspector.UIString("Secure"); - lockSpectrum.createChild("div", "security-summary-lock-spacer"); lockSpectrum.createChild("div", "lock-icon lock-icon-neutral").title = WebInspector.UIString("Not Secure"); - lockSpectrum.createChild("div", "security-summary-lock-spacer"); lockSpectrum.createChild("div", "lock-icon lock-icon-insecure").title = WebInspector.UIString("Insecure (Broken)"); this._summarySection.createChild("div", "triangle-pointer-container").createChild("div", "triangle-pointer-wrapper").createChild("div", "triangle-pointer");
diff --git a/third_party/WebKit/Source/devtools/front_end/security/lockIcon.css b/third_party/WebKit/Source/devtools/front_end/security/lockIcon.css index 68f7bdc..7dca99b 100644 --- a/third_party/WebKit/Source/devtools/front_end/security/lockIcon.css +++ b/third_party/WebKit/Source/devtools/front_end/security/lockIcon.css
@@ -5,47 +5,66 @@ .lock-icon, .security-property { - background-size: cover; height: 16px; width: 16px; + + -webkit-mask-image: url(Images/securityIcons.png); + -webkit-mask-size: 80px 32px; + + background-color: #888; } -.lock-icon-unknown { - background-image: url(Images/securityStateNeutral.svg); -} - -.lock-icon-neutral { - background-image: url(Images/securityStateNeutral.svg); -} - -.lock-icon-insecure { - background-image: url(Images/securityStateInsecure.svg); +@media (-webkit-min-device-pixel-ratio: 1.5) { + .lock-icon, + .security-property { + -webkit-mask-image: url(Images/securityIcons_2x.png); + } } .lock-icon-secure { - background-image: url(Images/securityStateSecure.svg); + -webkit-mask-position: 0px 0px; + background-color: #0B8043; } -.security-property-insecure { - background-image: url(Images/securityPropertyInsecure.svg); +.lock-icon-unknown, +.lock-icon-neutral { + -webkit-mask-position: -16px 0px; + background-color: #000000; /* Black for clarity on lower DPI screens */ } -.security-property-neutral { - background-image: url(Images/securityPropertyWarning.svg); +@media (-webkit-min-device-pixel-ratio: 1.5) { + .lock-icon-unknown, + .lock-icon-neutral { + background-color: #5A5A5A; /* Gray for hiDPI screens */ + } } -.security-property-warning { - background-image: url(Images/securityPropertyWarning.svg); -} - -.security-property-unknown { - background-image: url(Images/securityPropertyUnknown.svg); +.lock-icon-insecure { + -webkit-mask-position: -32px 0px; + background-color: #C63626; } .security-property-secure { - background-image: url(Images/securityPropertySecure.svg); + -webkit-mask-position: 0px -16px; + background-color: #0B8043; +} + +.security-property-neutral { + -webkit-mask-position: -16px -16px; + background-color: #C63626; +} + +.security-property-insecure { + -webkit-mask-position: -32px -16px; + background-color: #C63626; } .security-property-info { - background-image: url(Images/securityPropertyInfo.svg); + -webkit-mask-position: -48px -16px; + background-color: rgba(0, 0, 0, 0.5); +} + +.security-property-unknown { + -webkit-mask-position: -64px -16px; + background-color: rgba(0, 0, 0, 0.5); }
diff --git a/third_party/WebKit/Source/devtools/front_end/security/mainView.css b/third_party/WebKit/Source/devtools/front_end/security/mainView.css index df51db5d..af616ad 100644 --- a/third_party/WebKit/Source/devtools/front_end/security/mainView.css +++ b/third_party/WebKit/Source/devtools/front_end/security/mainView.css
@@ -20,63 +20,47 @@ .security-summary-section-title { font-size: 14px; - margin: 12px 24px; + margin: 12px 16px; } .lock-spectrum { - min-width: 180px; - max-width: 240px; - margin: 6px 12px; + margin: 8px 16px; display: flex; - align-items: center; + align-items: flex-start; } .security-summary .lock-icon { flex: none; - width: 32px; - height: 32px; - margin: 0 12px; - background-position: center center; - - /* Defaults for dynamic properties. */ - opacity: 0.5; + width: 16px; + height: 16px; + margin: 0 0; } -/* Shrink the margin for the page lock icon. */ +/* Separate the middle icon from the other two. */ .security-summary .lock-icon-neutral { - margin: 0 6px; + margin: 0 16px; } -.security-summary-secure .lock-icon-secure, -.security-summary-neutral .lock-icon-neutral, -.security-summary-insecure .lock-icon-insecure { - opacity: 1; -} - -.security-summary-lock-spacer { - flex: 1 1 auto; - height: 1px; - background: rgb(217, 217, 217); +.security-summary:not(.security-summary-secure) .lock-icon-secure, +.security-summary:not(.security-summary-neutral) .lock-icon-neutral, +.security-summary:not(.security-summary-insecure) .lock-icon-insecure { + background-color: rgba(90, 90, 90, 0.25); } .triangle-pointer-container { - /* Let (lock width) = (horizonal width of 1 lock icon, including both margins) */ - /* Horizontal margin is (lock width)/2 + (lock-spectrum horizontal margin) */ - margin: 8px 40px 0px; - /* Width is (lock spectrum width) - (lock width) */ - min-width: 124px; - max-width: 184px; + margin: 8px 24px 0; + padding: 0 0; } .triangle-pointer-wrapper { /* Defaults for dynamic properties. */ - transform: translateX(50%); + transform: translateX(0); transition: transform 0.3s; } .triangle-pointer { - width: 12px; - height: 12px; + width: 12px; + height: 12px; margin-bottom: -6px; margin-left: -6px; transform: rotate(-45deg); @@ -89,15 +73,15 @@ } .security-summary-secure .triangle-pointer-wrapper { - transform: translateX(0%); + transform: translateX(0px); } .security-summary-neutral .triangle-pointer-wrapper { - transform: translateX(50%); + transform: translateX(32px); } .security-summary-insecure .triangle-pointer-wrapper { - transform: translateX(100%); + transform: translateX(64px); } .security-summary-text { @@ -133,7 +117,7 @@ } .security-explanation { - padding: 12px; + padding: 16px; border-bottom: 1px solid rgb(230, 230, 230); background-color: #fff; @@ -161,10 +145,9 @@ .security-explanation .security-property { flex: none; - width: 18px; - height: 18px; - margin-left: 10px; - margin-right: 18px; + width: 16px; + height: 16px; + margin-right: 16px; } .security-explanation-title {
diff --git a/third_party/WebKit/Source/devtools/front_end/security/sidebar.css b/third_party/WebKit/Source/devtools/front_end/security/sidebar.css index f6b5440..6953121 100644 --- a/third_party/WebKit/Source/devtools/front_end/security/sidebar.css +++ b/third_party/WebKit/Source/devtools/front_end/security/sidebar.css
@@ -13,8 +13,10 @@ align-items: center; } -.tree-outline:focus li.selected .lock-icon-neutral { - background-color: #fff; +.tree-outline:focus li.selected .lock-icon, +.tree-outline:focus .security-sidebar-tree-item.selected .icon +{ + background-color: white; } .tree-outline .security-main-view-sidebar-tree-item { @@ -45,15 +47,10 @@ .tree-outline .sidebar-tree-item .lock-icon, .tree-outline .sidebar-tree-item .security-property { - margin-right: 2px; + margin-right: 4px; flex: none; } -.tree-outline:focus .security-sidebar-tree-item.selected .icon:not(.security-property-unknown) { - background-image: none; - background-color: #fff; -} - .security-sidebar-tree-item { padding: 2px 0; } @@ -63,30 +60,6 @@ margin-right: 5px; } -.tree-outline li.selected .lock-icon-neutral { - background-image: none; - background-color: #5a5a5a; - -webkit-mask-image: url(Images/securityStateNeutral.svg); - -webkit-mask-size: cover; -} - -.tree-outline .security-sidebar-tree-item.selected .security-property-insecure { - -webkit-mask-image: url(Images/securityPropertyInsecure.svg); -} - -.security-sidebar-tree-item.selected .security-property-neutral, -.security-sidebar-tree-item.selected .security-property-warning { - -webkit-mask-image: url(Images/securityPropertyWarning.svg); -} - -.tree-outline .security-sidebar-tree-item.selected .security-property-unknown { - -webkit-mask-image: url(Images/securityPropertyUnknown.svg); -} - -.security-sidebar-tree-item.selected .security-property-secure { - -webkit-mask-image: url(Images/securityPropertySecure.svg); -} - .sidebar-tree-item.security-main-view-reload-message .title { color: rgba(0, 0, 0, 0.5); padding-left: 8px;
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/AddSourceMapURLDialog.js b/third_party/WebKit/Source/devtools/front_end/sources/AddSourceMapURLDialog.js index c3aea93..6dcc0393 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/AddSourceMapURLDialog.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/AddSourceMapURLDialog.js
@@ -10,7 +10,7 @@ WebInspector.AddSourceMapURLDialog = function(callback) { WebInspector.HBox.call(this, true); - this.registerRequiredCSS("sources/addSourceMapURLDialog.css"); + this.registerRequiredCSS("ui_lazy/dialog.css"); this.contentElement.createChild("label").textContent = WebInspector.UIString("Source map URL: "); this._input = this.contentElement.createChild("input");
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/CallStackSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/sources/CallStackSidebarPane.js index 2126ac1..7e9c1d0 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/CallStackSidebarPane.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/CallStackSidebarPane.js
@@ -36,23 +36,23 @@ this.callFrameList.show(this.element); this._linkifier = new WebInspector.Linkifier(); WebInspector.moduleSetting("enableAsyncStackTraces").addChangeListener(this._asyncStackTracesStateChanged, this); - WebInspector.moduleSetting("skipStackFramesPattern").addChangeListener(this._blackboxingStateChanged, this); + WebInspector.moduleSetting("skipStackFramesPattern").addChangeListener(this._update, this); /** @type {!Array<!WebInspector.CallStackSidebarPane.CallFrame>} */ this.callFrames = []; this._locationPool = new WebInspector.LiveLocationPool(); -} - -/** @enum {string} */ -WebInspector.CallStackSidebarPane.Events = { - CallFrameSelected: "CallFrameSelected", + WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerPaused, this._update, this); + WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerResumed, this._update, this); + WebInspector.context.addFlavorChangeListener(WebInspector.Target, this._update, this); + WebInspector.context.addFlavorChangeListener(WebInspector.DebuggerModel.CallFrame, this._updateCallFrame, this); } WebInspector.CallStackSidebarPane.prototype = { - /** - * @param {?WebInspector.DebuggerPausedDetails} details - */ - update: function(details) + _update: function() { + var target = WebInspector.context.flavor(WebInspector.Target); + var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); + var details = debuggerModel ? debuggerModel.debuggerPausedDetails() : null; + this.callFrameList.detach(); this.callFrameList.clear(); this._linkifier.reset(); @@ -101,6 +101,7 @@ this.element.insertBefore(element, this.element.firstChild); this._hiddenCallFramesMessageElement = element; } + WebInspector.viewManager.revealViewWithWidget(this); }, /** @@ -248,19 +249,6 @@ } }, - _blackboxingStateChanged: function() - { - if (!this._debuggerModel) - return; - var details = this._debuggerModel.debuggerPausedDetails(); - if (!details) - return; - this.update(details); - var selectedCallFrame = this._debuggerModel.selectedCallFrame(); - if (selectedCallFrame) - this.setSelectedCallFrame(selectedCallFrame); - }, - _asyncStackTracesStateChanged: function() { var enabled = WebInspector.moduleSetting("enableAsyncStackTraces").get(); @@ -288,14 +276,12 @@ this._selectNextVisibleCallFrame(0); }, - /** - * @param {!WebInspector.DebuggerModel.CallFrame} x - */ - setSelectedCallFrame: function(x) + _updateCallFrame: function() { + var selectedCallFrame = WebInspector.context.flavor(WebInspector.DebuggerModel.CallFrame); for (var i = 0; i < this.callFrames.length; ++i) { var callFrame = this.callFrames[i]; - callFrame.setSelected(callFrame._debuggerCallFrame === x); + callFrame.setSelected(callFrame._debuggerCallFrame === selectedCallFrame); if (callFrame.isSelected() && callFrame.isHidden()) this._revealHiddenCallFrames(); } @@ -375,7 +361,7 @@ callFrameItem.element.scrollIntoViewIfNeeded(); var callFrame = callFrameItem._debuggerCallFrame; if (callFrame) - this.dispatchEventToListeners(WebInspector.CallStackSidebarPane.Events.CallFrameSelected, callFrame); + callFrame.debuggerModel.setSelectedCallFrame(callFrame); }, _copyStackTrace: function()
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/EventListenerBreakpointsSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/sources/EventListenerBreakpointsSidebarPane.js index 5876d0b..1323224 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/EventListenerBreakpointsSidebarPane.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/EventListenerBreakpointsSidebarPane.js
@@ -4,12 +4,12 @@ /** * @constructor - * @extends {WebInspector.SimpleView} + * @extends {WebInspector.VBox} * @implements {WebInspector.TargetManager.Observer} */ WebInspector.EventListenerBreakpointsSidebarPane = function() { - WebInspector.SimpleView.call(this, WebInspector.UIString("Event Listener Breakpoints")); + WebInspector.VBox.call(this); this.registerRequiredCSS("components/breakpointsList.css"); this._eventListenerBreakpointsSetting = WebInspector.settings.createLocalSetting("eventListenerBreakpoints", []); @@ -43,6 +43,9 @@ this._createCategory(WebInspector.UIString("XHR"), ["readystatechange", "load", "loadstart", "loadend", "abort", "error", "progress", "timeout"], false, ["XMLHttpRequest", "XMLHttpRequestUpload"]); WebInspector.targetManager.observeTargets(this, WebInspector.Target.Capability.DOM); + WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerPaused, this._update, this); + WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerResumed, this._update, this); + WebInspector.context.addFlavorChangeListener(WebInspector.Target, this._update, this); } WebInspector.EventListenerBreakpointsSidebarPane.categoryListener = "listener:"; @@ -146,6 +149,32 @@ this._categoryItems.push(categoryItem); }, + _update: function() + { + var target = WebInspector.context.flavor(WebInspector.Target); + var debuggerModel = WebInspector.DebuggerModel.fromTarget(target); + var details = debuggerModel ? debuggerModel.debuggerPausedDetails() : null; + + if (!details || details.reason !== WebInspector.DebuggerModel.BreakReason.EventListener) { + if (this._highlightedElement) { + this._highlightedElement.classList.remove("breakpoint-hit"); + delete this._highlightedElement; + } + return; + } + var eventName = details.auxData["eventName"]; + var targetName = details.auxData["targetName"]; + var breakpointItem = this._findBreakpointItem(eventName, targetName); + if (!breakpointItem || !breakpointItem.checkbox.checked) + breakpointItem = this._findBreakpointItem(eventName, WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny); + if (!breakpointItem) + return; + WebInspector.viewManager.revealViewWithWidget(this); + breakpointItem.parent.element.expand(); + breakpointItem.element.listItemElement.classList.add("breakpoint-hit"); + this._highlightedElement = breakpointItem.element.listItemElement; + }, + /** * @param {!Array.<string>} array * @return {!Array.<string>} @@ -292,31 +321,6 @@ return null; }, - /** - * @param {string} eventName - * @param {string=} targetName - */ - highlightBreakpoint: function(eventName, targetName) - { - var breakpointItem = this._findBreakpointItem(eventName, targetName); - if (!breakpointItem || !breakpointItem.checkbox.checked) - breakpointItem = this._findBreakpointItem(eventName, WebInspector.EventListenerBreakpointsSidebarPane.eventTargetAny); - if (!breakpointItem) - return; - this.revealView(); - breakpointItem.parent.element.expand(); - breakpointItem.element.listItemElement.classList.add("breakpoint-hit"); - this._highlightedElement = breakpointItem.element.listItemElement; - }, - - clearBreakpointHighlight: function() - { - if (this._highlightedElement) { - this._highlightedElement.classList.remove("breakpoint-hit"); - delete this._highlightedElement; - } - }, - _saveBreakpoints: function() { var breakpoints = []; @@ -344,5 +348,5 @@ } }, - __proto__: WebInspector.SimpleView.prototype + __proto__: WebInspector.VBox.prototype }
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js index ecf07a0c..d9f09fbe 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
@@ -68,7 +68,7 @@ this._updateScriptFile(targets[i]); } - if (this._scriptFileForTarget.size || uiSourceCode.extension() === "js") + if (this._scriptFileForTarget.size || uiSourceCode.extension() === "js" || uiSourceCode.project().type() === WebInspector.projectTypes.Snippets) this._compiler = new WebInspector.JavaScriptCompiler(this); WebInspector.moduleSetting("skipStackFramesPattern").addChangeListener(this._showBlackboxInfobarIfNeeded, this); @@ -583,10 +583,10 @@ /** * @param {?RuntimeAgent.RemoteObject} result - * @param {boolean=} wasThrown + * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails * @this {WebInspector.JavaScriptSourceFrame} */ - function showObjectPopover(result, wasThrown) + function showObjectPopover(result, exceptionDetails) { var target = WebInspector.context.flavor(WebInspector.Target); if (selectedCallFrame.target() !== target || !debuggerModel.isPaused() || !result) { @@ -594,7 +594,7 @@ return; } this._popoverAnchorBox = anchorBox; - showCallback(target.runtimeModel.createRemoteObject(result), wasThrown, this._popoverAnchorBox); + showCallback(target.runtimeModel.createRemoteObject(result), !!exceptionDetails, this._popoverAnchorBox); // Popover may have been removed by showCallback(). if (this._popoverAnchorBox) { var highlightRange = new WebInspector.TextRange(lineNumber, startHighlight, lineNumber, endHighlight);
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js b/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js index b90b2f91..8f852d49c 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/NavigatorView.js
@@ -486,6 +486,8 @@ break; if (!(node instanceof WebInspector.NavigatorGroupTreeNode || node instanceof WebInspector.NavigatorFolderTreeNode)) break; + if (node._type === WebInspector.NavigatorView.Types.Frame) + break; var folderId = this._folderNodeId(project, target, frame, uiSourceCode.origin(), node._folderPath); this._subfolderNodes.delete(folderId); @@ -905,7 +907,6 @@ this.tooltip = uiSourceCode.url(); this.createIcon(); - this._navigatorView = navigatorView; this._uiSourceCode = uiSourceCode; }
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/ObjectEventListenersSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/sources/ObjectEventListenersSidebarPane.js index ccc04e3e..333dda1d 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/ObjectEventListenersSidebarPane.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/ObjectEventListenersSidebarPane.js
@@ -4,17 +4,17 @@ /** * @constructor - * @extends {WebInspector.SimpleView} + * @extends {WebInspector.VBox} + * @implements {WebInspector.ToolbarItem.ItemsProvider} */ WebInspector.ObjectEventListenersSidebarPane = function() { - WebInspector.SimpleView.call(this, "Event Listeners"); + WebInspector.VBox.call(this); this.element.classList.add("event-listeners-sidebar-pane"); this._refreshButton = new WebInspector.ToolbarButton(WebInspector.UIString("Refresh"), "refresh-toolbar-item"); this._refreshButton.addEventListener("click", this._refreshClick.bind(this)); this._refreshButton.setEnabled(false); - this.addToolbarItem(this._refreshButton); this._eventListenersView = new WebInspector.EventListenersView(this.element, this.update.bind(this)); } @@ -22,6 +22,15 @@ WebInspector.ObjectEventListenersSidebarPane._objectGroupName = "object-event-listeners-sidebar-pane"; WebInspector.ObjectEventListenersSidebarPane.prototype = { + /** + * @override + * @return {!Array<!WebInspector.ToolbarItem>} + */ + toolbarItems: function() + { + return [this._refreshButton]; + }, + update: function() { if (this._lastRequestedContext) { @@ -40,7 +49,7 @@ wasShown: function() { - WebInspector.SimpleView.prototype.wasShown.call(this); + WebInspector.VBox.prototype.wasShown.call(this); WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext, this.update, this); this._refreshButton.setEnabled(true); this.update(); @@ -48,7 +57,7 @@ willHide: function() { - WebInspector.SimpleView.prototype.willHide.call(this); + WebInspector.VBox.prototype.willHide.call(this); WebInspector.context.removeFlavorChangeListener(WebInspector.ExecutionContext, this.update, this); this._refreshButton.setEnabled(false); }, @@ -89,5 +98,5 @@ this.update(); }, - __proto__: WebInspector.SimpleView.prototype + __proto__: WebInspector.VBox.prototype }
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/ScopeChainSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/sources/ScopeChainSidebarPane.js index 858a67e..bf8f418 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/ScopeChainSidebarPane.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/ScopeChainSidebarPane.js
@@ -33,16 +33,15 @@ WebInspector.SimpleView.call(this, WebInspector.UIString("Scope")); this._expandController = new WebInspector.ObjectPropertiesSectionExpandController(); this._linkifier = new WebInspector.Linkifier(); + WebInspector.context.addFlavorChangeListener(WebInspector.DebuggerModel.CallFrame, this._update, this); } WebInspector.ScopeChainSidebarPane._pathSymbol = Symbol("path"); WebInspector.ScopeChainSidebarPane.prototype = { - /** - * @param {?WebInspector.DebuggerModel.CallFrame} callFrame - */ - update: function(callFrame) + _update: function() { + var callFrame = WebInspector.context.flavor(WebInspector.DebuggerModel.CallFrame); this._linkifier.reset(); WebInspector.SourceMapNamesResolver.resolveThisObject(callFrame) .then(this._innerUpdate.bind(this, callFrame));
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js b/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js index f093016..aa7a895 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/SourcesPanel.js
@@ -87,14 +87,10 @@ this.sidebarPanes.threads = null; this.sidebarPanes.watchExpressions = new WebInspector.WatchExpressionsSidebarPane(); this.sidebarPanes.callstack = new WebInspector.CallStackSidebarPane(); - this.sidebarPanes.callstack.addEventListener(WebInspector.CallStackSidebarPane.Events.CallFrameSelected, this._callFrameSelectedInSidebar.bind(this)); this.sidebarPanes.callstack.registerShortcuts(this.registerShortcuts.bind(this)); this.sidebarPanes.scopechain = new WebInspector.ScopeChainSidebarPane(); this.sidebarPanes.jsBreakpoints = new WebInspector.JavaScriptBreakpointsSidebarPane(WebInspector.breakpointManager, this.showUISourceCode.bind(this)); - this.sidebarPanes.xhrBreakpoints = new WebInspector.XHRBreakpointsSidebarPane(); - this.sidebarPanes.eventListenerBreakpoints = new WebInspector.EventListenerBreakpointsSidebarPane(); - this.sidebarPanes.objectEventListeners = new WebInspector.ObjectEventListenersSidebarPane(); this._installDebuggerSidebarController(); @@ -113,8 +109,7 @@ WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerWasEnabled, this._debuggerWasEnabled, this); WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this); WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.DebuggerResumed, this._debuggerResumed, this); - WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.CallFrameSelected, this._callFrameSelected, this); - WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.ConsoleCommandEvaluatedInSelectedCallFrame, this._consoleCommandEvaluatedInSelectedCallFrame, this); + WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.CallFrameSelected, this._callFrameSelectedOnModel, this); WebInspector.targetManager.addModelListener(WebInspector.DebuggerModel, WebInspector.DebuggerModel.Events.GlobalObjectCleared, this._debuggerReset, this); new WebInspector.WorkspaceMappingTip(this, this._workspace); WebInspector.extensionServer.addEventListener(WebInspector.ExtensionServer.Events.SidebarPaneAdded, this._extensionSidebarPaneAdded, this); @@ -173,7 +168,7 @@ this._showDebuggerPausedDetails(/** @type {!WebInspector.DebuggerPausedDetails} */ (debuggerModel.debuggerPausedDetails())); var callFrame = debuggerModel.selectedCallFrame(); if (callFrame) - this._selectCallFrame(callFrame); + this._selectCallFrameInUI(callFrame); } else { this._paused = false; this._clearInterface(); @@ -258,15 +253,6 @@ return this._sourcesView.searchableView(); }, - _consoleCommandEvaluatedInSelectedCallFrame: function(event) - { - var debuggerModel = /** @type {!WebInspector.DebuggerModel} */ (event.target); - var target = debuggerModel.target(); - if (WebInspector.context.flavor(WebInspector.Target) !== target) - return; - this.sidebarPanes.scopechain.update(debuggerModel.selectedCallFrame()); - }, - /** * @param {!WebInspector.Event} event */ @@ -290,8 +276,6 @@ this._paused = true; this._updateDebuggerButtons(); - this.sidebarPanes.callstack.update(details); - /** * @param {!WebInspector.LiveLocation} liveLocation * @this {WebInspector.SourcesPanel} @@ -309,16 +293,12 @@ } if (details.reason === WebInspector.DebuggerModel.BreakReason.DOM) { - WebInspector.domBreakpointsSidebarPane.highlightBreakpoint(details.auxData); this.sidebarPanes.callstack.setStatus(WebInspector.domBreakpointsSidebarPane.createBreakpointHitStatusMessage(details)); } else if (details.reason === WebInspector.DebuggerModel.BreakReason.EventListener) { var eventName = details.auxData["eventName"]; - var targetName = details.auxData["targetName"]; - this.sidebarPanes.eventListenerBreakpoints.highlightBreakpoint(eventName, targetName); var eventNameForUI = WebInspector.EventListenerBreakpointsSidebarPane.eventNameForUI(eventName, details.auxData); this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a \"%s\" Event Listener.", eventNameForUI)); } else if (details.reason === WebInspector.DebuggerModel.BreakReason.XHR) { - this.sidebarPanes.xhrBreakpoints.highlightBreakpoint(details.auxData["breakpointURL"]); this.sidebarPanes.callstack.setStatus(WebInspector.UIString("Paused on a XMLHttpRequest.")); } else if (details.reason === WebInspector.DebuggerModel.BreakReason.Exception) { var description = details.auxData["description"] || ""; @@ -495,24 +475,20 @@ /** * @param {!WebInspector.Event} event */ - _callFrameSelected: function(event) + _callFrameSelectedOnModel: function(event) { var callFrame = /** @type {?WebInspector.DebuggerModel.CallFrame} */ (event.data); - if (!callFrame || callFrame.target() !== WebInspector.context.flavor(WebInspector.Target)) return; - - this._selectCallFrame(callFrame); + this._selectCallFrameInUI(callFrame); }, /** * @param {!WebInspector.DebuggerModel.CallFrame} callFrame */ - _selectCallFrame: function(callFrame) + _selectCallFrameInUI: function(callFrame) { - this.sidebarPanes.scopechain.update(callFrame); - this.sidebarPanes.watchExpressions.refreshExpressions(); - this.sidebarPanes.callstack.setSelectedCallFrame(callFrame); + WebInspector.context.setFlavor(WebInspector.DebuggerModel.CallFrame, callFrame); WebInspector.debuggerWorkspaceBinding.createCallFrameLiveLocation(callFrame.location(), this._executionLineChanged.bind(this), this._liveLocationPool); }, @@ -550,14 +526,7 @@ _clearInterface: function() { - this.sidebarPanes.callstack.update(null); - this.sidebarPanes.scopechain.update(null); this.sidebarPanes.jsBreakpoints.clearBreakpointHighlight(); - WebInspector.domBreakpointsSidebarPane.clearBreakpointHighlight(); - this.sidebarPanes.eventListenerBreakpoints.clearBreakpointHighlight(); - this.sidebarPanes.xhrBreakpoints.clearBreakpointHighlight(); - if (this.sidebarPanes.asyncOperationBreakpoints) - this.sidebarPanes.asyncOperationBreakpoints.clearBreakpointHighlight(); this._sourcesView.clearCurrentExecutionLine(); this._updateDebuggerButtons(); @@ -730,15 +699,6 @@ }, /** - * @param {!WebInspector.Event} event - */ - _callFrameSelectedInSidebar: function(event) - { - var callFrame = /** @type {!WebInspector.DebuggerModel.CallFrame} */ (event.data); - callFrame.debuggerModel.setSelectedCallFrame(callFrame); - }, - - /** * @param {!WebInspector.UILocation} uiLocation */ _continueToLocation: function(uiLocation) @@ -1018,12 +978,12 @@ if (!currentExecutionContext) return; - currentExecutionContext.globalObject("", false, false, didGetGlobalObject); + currentExecutionContext.globalObject("", false, didGetGlobalObject); /** * @param {?WebInspector.RemoteObject} global - * @param {boolean=} wasThrown + * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails */ - function didGetGlobalObject(global, wasThrown) + function didGetGlobalObject(global, exceptionDetails) { /** * @suppressReceiverCheck @@ -1040,7 +1000,7 @@ return name; } - if (wasThrown || !global) + if (!!exceptionDetails || !global) failedToSave(global); else global.callFunction(remoteFunction, [WebInspector.RemoteObject.toCallArgument(remoteObject)], didSave.bind(null, global)); @@ -1166,9 +1126,6 @@ // Populate the left stack. this._sidebarPaneStack.showView(this.sidebarPanes.jsBreakpoints); - this._sidebarPaneStack.appendView(this.sidebarPanes.xhrBreakpoints); - this._sidebarPaneStack.appendView(this.sidebarPanes.eventListenerBreakpoints); - this._sidebarPaneStack.appendView(this.sidebarPanes.objectEventListeners); var tabbedLocation = WebInspector.viewManager.createTabbedLocation(this._setAsCurrentPanel.bind(this)); splitWidget.setSidebarWidget(tabbedLocation.tabbedPane());
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/SourcesSearchScope.js b/third_party/WebKit/Source/devtools/front_end/sources/SourcesSearchScope.js index edf528a..a3f4e5a 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/SourcesSearchScope.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/SourcesSearchScope.js
@@ -178,7 +178,7 @@ var uiSourceCode = project.uiSourceCodeForURL(files[i]); if (uiSourceCode) { var script = WebInspector.DefaultScriptMapping.scriptForUISourceCode(uiSourceCode); - if (script && (script.isInternalScript() || !script.isAnonymousScript())) + if (script && !script.isAnonymousScript()) continue; uiSourceCodes.push(uiSourceCode); }
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/WatchExpressionsSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/sources/WatchExpressionsSidebarPane.js index bbcdf0fe..1325380 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/WatchExpressionsSidebarPane.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/WatchExpressionsSidebarPane.js
@@ -53,8 +53,8 @@ this._bodyElement.addEventListener("contextmenu", this._contextMenu.bind(this), false); this._expandController = new WebInspector.ObjectPropertiesSectionExpandController(); - WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext, this.refreshExpressions, this); - + WebInspector.context.addFlavorChangeListener(WebInspector.ExecutionContext, this._refreshExpressions, this); + WebInspector.context.addFlavorChangeListener(WebInspector.DebuggerModel.CallFrame, this._refreshExpressions, this); this._linkifier = new WebInspector.Linkifier(); } @@ -64,7 +64,7 @@ this._refreshExpressionsIfNeeded(); }, - refreshExpressions: function() + _refreshExpressions: function() { this._requiresUpdate = true; this._refreshExpressionsIfNeeded(); @@ -128,7 +128,7 @@ _refreshButtonClicked: function(event) { event.consume(); - this.refreshExpressions(); + this._refreshExpressions(); }, _rebuildWatchExpressions: function() @@ -233,7 +233,7 @@ this._editing = false; this._linkifier = linkifier; - this._createWatchExpression(null, false); + this._createWatchExpression(null); this.update(); } @@ -341,9 +341,9 @@ /** * @param {?WebInspector.RemoteObject} result - * @param {boolean} wasThrown + * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails */ - _createWatchExpression: function(result, wasThrown) + _createWatchExpression: function(result, exceptionDetails) { this._result = result; @@ -354,12 +354,12 @@ var titleElement = headerElement.createChild("div", "watch-expression-title"); this._nameElement = WebInspector.ObjectPropertiesSection.createNameElement(this._expression); - if (wasThrown || !result) { + if (!!exceptionDetails || !result) { this._valueElement = createElementWithClass("span", "error-message value"); titleElement.classList.add("dimmed"); this._valueElement.textContent = WebInspector.UIString("<not available>"); } else { - this._valueElement = WebInspector.ObjectPropertiesSection.createValueElementWithCustomSupport(result, wasThrown, titleElement, this._linkifier); + this._valueElement = WebInspector.ObjectPropertiesSection.createValueElementWithCustomSupport(result, !!exceptionDetails, titleElement, this._linkifier); } var separatorElement = createElementWithClass("span", "watch-expressions-separator"); separatorElement.textContent = ": "; @@ -367,7 +367,7 @@ this._element.removeChildren(); this._objectPropertiesSection = null; - if (!wasThrown && result && result.hasChildren && !result.customPreview()) { + if (!exceptionDetails && result && result.hasChildren && !result.customPreview()) { headerElement.classList.add("watch-expression-object-header"); this._objectPropertiesSection = new WebInspector.ObjectPropertiesSection(result, headerElement, this._linkifier); this._objectPresentationElement = this._objectPropertiesSection.element;
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/XHRBreakpointsSidebarPane.js b/third_party/WebKit/Source/devtools/front_end/sources/XHRBreakpointsSidebarPane.js index e6a37edd..0e228dd5 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/XHRBreakpointsSidebarPane.js +++ b/third_party/WebKit/Source/devtools/front_end/sources/XHRBreakpointsSidebarPane.js
@@ -6,18 +6,18 @@ * @constructor * @extends {WebInspector.BreakpointsSidebarPaneBase} * @implements {WebInspector.TargetManager.Observer} + * @implements {WebInspector.ToolbarItem.ItemsProvider} */ WebInspector.XHRBreakpointsSidebarPane = function() { - WebInspector.BreakpointsSidebarPaneBase.call(this, WebInspector.UIString("XHR Breakpoints")); + WebInspector.BreakpointsSidebarPaneBase.call(this); this._xhrBreakpointsSetting = WebInspector.settings.createLocalSetting("xhrBreakpoints", []); /** @type {!Map.<string, !Element>} */ this._breakpointElements = new Map(); - var addButton = new WebInspector.ToolbarButton(WebInspector.UIString("Add breakpoint"), "add-toolbar-item"); - addButton.addEventListener("click", this._addButtonClicked.bind(this)); - this.addToolbarItem(addButton); + this._addButton = new WebInspector.ToolbarButton(WebInspector.UIString("Add breakpoint"), "add-toolbar-item"); + this._addButton.addEventListener("click", this._addButtonClicked.bind(this)); this.emptyElement.addEventListener("contextmenu", this._emptyElementContextMenu.bind(this), true); @@ -40,6 +40,15 @@ */ targetRemoved: function(target) { }, + /** + * @override + * @return {!Array<!WebInspector.ToolbarItem>} + */ + toolbarItems: function() + { + return [this._addButton]; + }, + _emptyElementContextMenu: function(event) { var contextMenu = new WebInspector.ContextMenu(event); @@ -52,7 +61,7 @@ if (event) event.consume(); - this.revealView(); + WebInspector.viewManager.revealViewWithWidget(this); var inputElementContainer = createElementWithClass("p", "breakpoint-condition"); inputElementContainer.textContent = WebInspector.UIString("Break when URL contains:"); @@ -212,24 +221,28 @@ WebInspector.InplaceEditor.startEditing(inputElement, new WebInspector.InplaceEditor.Config(finishEditing.bind(this, true), finishEditing.bind(this, false))); }, - highlightBreakpoint: function(url) + /** + * @override + * @param {?WebInspector.DebuggerPausedDetails} details + */ + highlightDetails: function(details) { + if (!details || details.reason !== WebInspector.DebuggerModel.BreakReason.XHR) { + if (this._highlightedElement) { + this._highlightedElement.classList.remove("breakpoint-hit"); + delete this._highlightedElement; + } + return; + } + var url = details.auxData["breakpointURL"]; var element = this._breakpointElements.get(url); if (!element) return; - this.revealView(); + WebInspector.viewManager.revealViewWithWidget(this); element.classList.add("breakpoint-hit"); this._highlightedElement = element; }, - clearBreakpointHighlight: function() - { - if (this._highlightedElement) { - this._highlightedElement.classList.remove("breakpoint-hit"); - delete this._highlightedElement; - } - }, - _saveBreakpoints: function() { var breakpoints = [];
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/module.json b/third_party/WebKit/Source/devtools/front_end/sources/module.json index 1da852f6..ace91f8 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/module.json +++ b/third_party/WebKit/Source/devtools/front_end/sources/module.json
@@ -374,11 +374,40 @@ { "type": "view", "location": "sources-sidebar", + "id": "sources.xhrBreakpoints", + "title": "XHR Breakpoints", + "order": 5, + "hasToolbar": "true", + "persistence": "permanent", + "className": "WebInspector.XHRBreakpointsSidebarPane" + }, + { + "type": "view", + "location": "sources-sidebar", "id": "sources.domBreakpoints", "title": "DOM Breakpoints", "order": 7, "persistence": "permanent", "factoryName": "WebInspector.DOMBreakpointsSidebarPane.Proxy" + }, + { + "type": "view", + "location": "sources-sidebar", + "id": "sources.globalListeners", + "title": "Global Listeners", + "order": 8, + "hasToolbar": "true", + "persistence": "permanent", + "className": "WebInspector.ObjectEventListenersSidebarPane" + }, + { + "type": "view", + "location": "sources-sidebar", + "id": "sources.eventListenerBreakpoints", + "title": "Event Listener Breakpoints", + "order": 9, + "persistence": "permanent", + "className": "WebInspector.EventListenerBreakpointsSidebarPane" } ], "dependencies": [ @@ -427,7 +456,6 @@ "ObjectEventListenersSidebarPane.js" ], "resources": [ - "addSourceMapURLDialog.css", "uiList.css", "navigatorView.css", "revisionHistory.css",
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/uiList.css b/third_party/WebKit/Source/devtools/front_end/sources/uiList.css index af8b8f77..0cf14f83 100644 --- a/third_party/WebKit/Source/devtools/front_end/sources/uiList.css +++ b/third_party/WebKit/Source/devtools/front_end/sources/uiList.css
@@ -11,7 +11,6 @@ white-space: nowrap; line-height: 20px; border-bottom: 1px solid #eee; - background-position: -235px -107px; } .list-item:not(.ignore-hover):hover { @@ -53,9 +52,9 @@ } .list-item.selected::before { - background-image: url(Images/toolbarButtonGlyphs.png); - background-size: 352px 168px; - background-position: -235px -107px; + background-image: url(Images/smallIcons.png); + background-size: 190px 30px; + background-position: -180px 0; content: ""; position: absolute; top: 5px; @@ -66,6 +65,6 @@ @media (-webkit-min-device-pixel-ratio: 1.5) { .list-item.selected::before { - background-image: url(Images/toolbarButtonGlyphs_2x.png); + background-image: url(Images/smallIcons_2x.png); } } /* media */
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js index e58206b..873d39d 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
@@ -49,6 +49,7 @@ this._windowEndTime = Infinity; this._millisecondsToRecordAfterLoadEvent = 3000; this._toggleRecordAction = /** @type {!WebInspector.Action }*/ (WebInspector.actionRegistry.action("timeline.toggle-recording")); + this._customCPUThrottlingRate = 0; /** @type {!Array<!WebInspector.TimelineModel.Filter>} */ this._filters = []; @@ -406,25 +407,42 @@ if (Runtime.experiments.isEnabled("cpuThrottling")) { this._panelToolbar.appendSeparator(); this._cpuThrottlingCombobox = new WebInspector.ToolbarComboBox(this._onCPUThrottlingChanged.bind(this)); - /** - * @param {string} name - * @param {number} value - * @this {WebInspector.TimelinePanel} - */ - function addGroupingOption(name, value) - { - var option = this._cpuThrottlingCombobox.createOption(name, "", String(value)); - this._cpuThrottlingCombobox.addOption(option); - if (value === this._cpuThrottlingManager.rate()) - this._cpuThrottlingCombobox.select(option); - } - addGroupingOption.call(this, WebInspector.UIString("No CPU throttling"), 1); - addGroupingOption.call(this, WebInspector.UIString("High end device\u2003(2x slowdown)"), 2); - addGroupingOption.call(this, WebInspector.UIString("Low end device\u2003(5x slowdown)"), 5); this._panelToolbar.appendToolbarItem(this._cpuThrottlingCombobox); + this._populateCPUThrottingCombobox(); } }, + _populateCPUThrottingCombobox: function() + { + var cpuThrottlingCombobox = this._cpuThrottlingCombobox; + cpuThrottlingCombobox.removeOptions(); + var currentRate = this._cpuThrottlingManager.rate(); + var hasSelection = false; + /** + * @param {string} name + * @param {number} value + */ + function addGroupingOption(name, value) + { + var option = cpuThrottlingCombobox.createOption(name, "", String(value)); + cpuThrottlingCombobox.addOption(option); + if (hasSelection || (value && value !== currentRate)) + return; + cpuThrottlingCombobox.select(option); + hasSelection = true; + } + var predefinedRates = new Map([ + [1, WebInspector.UIString("No CPU throttling")], + [2, WebInspector.UIString("High end device (2\xD7 slowdown)")], + [5, WebInspector.UIString("Low end device (5\xD7 slowdown)")] + ]); + for (var rate of predefinedRates) + addGroupingOption(rate[1], rate[0]); + if (this._customCPUThrottlingRate && !predefinedRates.has(this._customCPUThrottlingRate)) + addGroupingOption(WebInspector.UIString("Custom rate (%d\xD7 slowdown)", this._customCPUThrottlingRate), this._customCPUThrottlingRate); + addGroupingOption(WebInspector.UIString("Set custom rate\u2026"), 0); + }, + _prepareToLoadTimeline: function() { console.assert(this._state === WebInspector.TimelinePanel.State.Idle); @@ -558,8 +576,21 @@ { if (!this._cpuThrottlingManager) return; - var value = Number.parseFloat(this._cpuThrottlingCombobox.selectedOption().value); - this._cpuThrottlingManager.setRate(value); + var value = this._cpuThrottlingCombobox.selectedOption().value; + var isLastOption = this._cpuThrottlingCombobox.selectedIndex() === this._cpuThrottlingCombobox.size() - 1; + this._populateCPUThrottingCombobox(); + var resultPromise = isLastOption + ? WebInspector.TimelinePanel.CustomCPUThrottlingRateDialog.show(this._cpuThrottlingCombobox.element) + : Promise.resolve(value); + resultPromise.then(text => { + var value = Number.parseFloat(text); + if (value >= 1) { + if (isLastOption) + this._customCPUThrottlingRate = value; + this._cpuThrottlingManager.setRate(value); + this._populateCPUThrottingCombobox(); + } + }); }, /** @@ -1992,6 +2023,10 @@ { this._throttlingRate = value; this._targets.forEach(target => target.emulationAgent().setCPUThrottlingRate(value)); + if (value !== 1) + WebInspector.inspectorView.setPanelIcon("timeline", "warning-icon", WebInspector.UIString("CPU throttling is enabled")); + else + WebInspector.inspectorView.setPanelIcon("timeline", "", ""); }, /** @@ -2023,3 +2058,71 @@ __proto__: WebInspector.Object.prototype } + +/** + * @constructor + * @extends {WebInspector.HBox} + */ +WebInspector.TimelinePanel.CustomCPUThrottlingRateDialog = function() +{ + WebInspector.HBox.call(this, true); + this.registerRequiredCSS("ui_lazy/dialog.css"); + this.contentElement.createChild("label").textContent = WebInspector.UIString("CPU Slowdown Rate: "); + + this._input = this.contentElement.createChild("input"); + this._input.setAttribute("type", "text"); + this._input.style.width = "64px"; + this._input.addEventListener("keydown", this._onKeyDown.bind(this), false); + + var addButton = this.contentElement.createChild("button"); + addButton.textContent = WebInspector.UIString("Set"); + addButton.addEventListener("click", this._apply.bind(this), false); + + this.setDefaultFocusedElement(this._input); + this.contentElement.tabIndex = 0; + this._resultPromise = new Promise(fulfill => this._callback = fulfill); +} + +/** + * @param {!Element=} anchor + * @return {!Promise<string>} + */ +WebInspector.TimelinePanel.CustomCPUThrottlingRateDialog.show = function(anchor) +{ + var dialog = new WebInspector.Dialog(); + var dialogContent = new WebInspector.TimelinePanel.CustomCPUThrottlingRateDialog(); + dialogContent.show(dialog.element); + dialog.setWrapsContent(true); + if (anchor) + dialog.setPosition(anchor.totalOffsetLeft() - 32, anchor.totalOffsetTop() + anchor.offsetHeight); + dialog.show(); + return dialogContent.result().then(value => (dialog.detach(), value)); +} + +WebInspector.TimelinePanel.CustomCPUThrottlingRateDialog.prototype = { + /** + * @return {!Promise<string>} + */ + result: function() + { + return this._resultPromise; + }, + + _apply: function() + { + this._callback(this._input.value); + }, + + /** + * @param {!Event} event + */ + _onKeyDown: function(event) + { + if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Enter.code) { + event.preventDefault(); + this._apply(); + } + }, + + __proto__: WebInspector.HBox.prototype +}
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/Toolbar.js b/third_party/WebKit/Source/devtools/front_end/ui/Toolbar.js index 9bc2472..584a011a 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/Toolbar.js +++ b/third_party/WebKit/Source/devtools/front_end/ui/Toolbar.js
@@ -622,6 +622,16 @@ } /** + * @param {string} actionId + * @return {?WebInspector.ToolbarItem} + */ +WebInspector.Toolbar.createActionButtonForId = function(actionId) +{ + var action = WebInspector.actionRegistry.action(actionId); + return /** @type {?WebInspector.ToolbarItem} */(action ? WebInspector.Toolbar.createActionButton(action) : null); +} + +/** * @constructor * @extends {WebInspector.ToolbarButton} * @param {function(!WebInspector.ContextMenu)} contextMenuHandler @@ -747,6 +757,20 @@ } /** + * @interface + */ +WebInspector.ToolbarItem.ItemsProvider = function() +{ +} + +WebInspector.ToolbarItem.ItemsProvider.prototype = { + /** + * @return {!Array<!WebInspector.ToolbarItem>} + */ + toolbarItems: function() {} +} + +/** * @constructor * @extends {WebInspector.ToolbarItem} * @param {?function(!Event)} changeHandler @@ -956,10 +980,8 @@ var descriptor = extension.descriptor(); if (descriptor["separator"]) return Promise.resolve(/** @type {?WebInspector.ToolbarItem} */(new WebInspector.ToolbarSeparator())); - if (descriptor["actionId"]) { - var action = WebInspector.actionRegistry.action(descriptor["actionId"]); - return Promise.resolve(/** @type {?WebInspector.ToolbarItem} */(action ? WebInspector.Toolbar.createActionButton(action) : null)); - } + if (descriptor["actionId"]) + return Promise.resolve(WebInspector.Toolbar.createActionButtonForId(descriptor["actionId"])); return extension.instance().then(fetchItemFromProvider); /**
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js b/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js index 73bb5c0..86f9ab8 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js +++ b/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
@@ -826,11 +826,11 @@ WebInspector.setCurrentFocusElement(null); } -WebInspector._textInputTypes = ["text", "search", "tel", "url", "email", "password"].keySet(); +WebInspector._textInputTypes = new Set(["text", "search", "tel", "url", "email", "password"]); WebInspector._isTextEditingElement = function(element) { if (element instanceof HTMLInputElement) - return element.type in WebInspector._textInputTypes; + return WebInspector._textInputTypes.has(element.type); if (element instanceof HTMLTextAreaElement) return true;
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/View.js b/third_party/WebKit/Source/devtools/front_end/ui/View.js index 8add555..5b866d8 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/View.js +++ b/third_party/WebKit/Source/devtools/front_end/ui/View.js
@@ -41,6 +41,8 @@ widget: function() { } } +WebInspector.View._symbol = Symbol("view"); + /** * @constructor * @extends {WebInspector.VBox} @@ -54,6 +56,7 @@ this._title = title; /** @type {!Array<!WebInspector.ToolbarItem>} */ this._toolbarItems = []; + this[WebInspector.View._symbol] = this; } WebInspector.SimpleView.prototype = { @@ -191,6 +194,19 @@ */ toolbarItems: function() { + var actionIds = this._extension.descriptor()["actionIds"]; + if (actionIds) { + var result = [] + for (var id of actionIds.split(",")) { + var item = WebInspector.Toolbar.createActionButtonForId(id.trim()); + if (item) + result.push(item); + } + return Promise.resolve(result); + } + + if (this._extension.descriptor()["hasToolbar"]) + return this.widget().then(widget => /** @type {!WebInspector.ToolbarItem.ItemsProvider} */ (widget).toolbarItems()); return Promise.resolve([]); }, @@ -200,7 +216,12 @@ */ widget: function() { - return /** @type {!Promise<!WebInspector.Widget>} */ (this._extension.instance()); + return this._extension.instance().then(widget => { + if (!(widget instanceof WebInspector.Widget)) + throw new Error("view className should point to a WebInspector.Widget"); + widget[WebInspector.View._symbol] = this; + return /** @type {!WebInspector.Widget} */ (widget); + }); } } @@ -281,6 +302,16 @@ WebInspector.ViewManager.prototype = { /** + * @param {!WebInspector.Widget} widget + */ + revealViewWithWidget: function(widget) + { + var view = widget[WebInspector.View._symbol]; + if (view) + this.revealView(view); + }, + + /** * @param {!WebInspector.View} view * @return {!Promise} */
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/ViewportControl.js b/third_party/WebKit/Source/devtools/front_end/ui/ViewportControl.js index 4774a14..b8edc11 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/ViewportControl.js +++ b/third_party/WebKit/Source/devtools/front_end/ui/ViewportControl.js
@@ -59,9 +59,13 @@ this._renderedItems = []; this._anchorSelection = null; this._headSelection = null; - this._stickToBottom = false; - this._scrolledToBottom = true; this._itemCount = 0; + + // Listen for any changes to descendants and trigger a refresh. This ensures + // that items updated asynchronously will not break stick-to-bottom behavior + // if they change the scroll height. + this._observer = new MutationObserver(this.refresh.bind(this)); + this._observerConfig = { childList: true, subtree: true }; } /** @@ -145,9 +149,9 @@ /** * @return {boolean} */ - scrolledToBottom: function() + stickToBottom: function() { - return this._scrolledToBottom; + return this._stickToBottom; }, /** @@ -156,6 +160,10 @@ setStickToBottom: function(value) { this._stickToBottom = value; + if (this._stickToBottom) + this._observer.observe(this._contentElement, this._observerConfig); + else + this._observer.disconnect(); }, /** @@ -376,6 +384,14 @@ refresh: function() { + this._observer.disconnect(); + this._innerRefresh(); + if (this._stickToBottom) + this._observer.observe(this._contentElement, this._observerConfig); + }, + + _innerRefresh: function() + { if (!this._visibleHeight()) return; // Do nothing for invisible controls. @@ -396,7 +412,6 @@ var visibleFrom = this.element.scrollTop; var visibleHeight = this._visibleHeight(); - this._scrolledToBottom = this.element.isScrolledToBottom(); var isInvalidating = !this._cumulativeHeights; for (var i = 0; i < this._renderedItems.length; ++i) { @@ -408,17 +423,19 @@ var oldFirstVisibleIndex = this._firstVisibleIndex; var oldLastVisibleIndex = this._lastVisibleIndex; - var shouldStickToBottom = this._stickToBottom && this._scrolledToBottom; - - if (shouldStickToBottom) { - this._lastVisibleIndex = this._itemCount - 1; + // When the viewport is scrolled to the bottom, using the cumulative heights estimate is not + // precise enough to determine next visible indices. This stickToBottom check avoids extra + // calls to refresh in those cases. + if (this._stickToBottom) { this._firstVisibleIndex = Math.max(this._itemCount - Math.ceil(visibleHeight / this._provider.minimumRowHeight()), 0); + this._lastVisibleIndex = this._itemCount - 1; } else { this._firstVisibleIndex = Math.max(Array.prototype.lowerBound.call(this._cumulativeHeights, visibleFrom + 1), 0); // Proactively render more rows in case some of them will be collapsed without triggering refresh. @see crbug.com/390169 this._lastVisibleIndex = this._firstVisibleIndex + Math.ceil(visibleHeight / this._provider.minimumRowHeight()) - 1; this._lastVisibleIndex = Math.min(this._lastVisibleIndex, this._itemCount - 1); } + var topGapHeight = this._cumulativeHeights[this._firstVisibleIndex - 1] || 0; var bottomGapHeight = this._cumulativeHeights[this._cumulativeHeights.length - 1] - this._cumulativeHeights[this._lastVisibleIndex]; @@ -442,7 +459,7 @@ // Should be the last call in the method as it might force layout. if (shouldRestoreSelection) this._restoreSelection(selection); - if (shouldStickToBottom) + if (this._stickToBottom) this.element.scrollTop = 10000000; }, @@ -612,8 +629,11 @@ */ forceScrollItemToBeFirst: function(index) { + this.setStickToBottom(false); this._rebuildCumulativeHeightsIfNeeded(); this.element.scrollTop = index > 0 ? this._cumulativeHeights[index - 1] : 0; + if (this.element.isScrolledToBottom()) + this.setStickToBottom(true); this.refresh(); }, @@ -622,8 +642,11 @@ */ forceScrollItemToBeLast: function(index) { + this.setStickToBottom(false); this._rebuildCumulativeHeightsIfNeeded(); this.element.scrollTop = this._cumulativeHeights[index] - this._visibleHeight(); + if (this.element.isScrolledToBottom()) + this.setStickToBottom(true); this.refresh(); },
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/smallIcon.css b/third_party/WebKit/Source/devtools/front_end/ui/smallIcon.css index 64eea1d..b65725b 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/smallIcon.css +++ b/third_party/WebKit/Source/devtools/front_end/ui/smallIcon.css
@@ -20,8 +20,8 @@ div.red-ball, div.green-ball, div.orange-ball { - background-image: url(Images/toolbarButtonGlyphs.png); - background-size: 352px 168px; + background-image: url(Images/smallIcons.png); + background-size: 190px 30px; } @media (-webkit-min-device-pixel-ratio: 1.5) { @@ -33,38 +33,38 @@ div.red-ball, div.green-ball, div.orange-ball { - background-image: url(Images/toolbarButtonGlyphs_2x.png); + background-image: url(Images/smallIcons_2x.png); } } /* media */ div.error-icon { - background-position: -213px -96px; + background-position: -20px 0; } div.revokedError-icon { - background-position: -246px -107px; + background-position: -40px 0; } div.warning-icon { - background-position: -202px -107px; + background-position: -60px 0; } div.info-icon { - background-position: -213px -107px; + background-position: -80px 0; } div.device-icon { - background-position: -224px -107px; + background-position: -100px 0; } div.red-ball { - background-position: -224px -96px; + background-position: -120px 0; } div.green-ball { - background-position: -235px -96px; + background-position: -140px 0; } div.orange-ball { - background-position: -246px -96px; + background-position: -160px 0; }
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/suggestBox.css b/third_party/WebKit/Source/devtools/front_end/ui/suggestBox.css index beb98f9..52bb4bb 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/suggestBox.css +++ b/third_party/WebKit/Source/devtools/front_end/ui/suggestBox.css
@@ -94,19 +94,19 @@ display: inline-block; content: ""; -webkit-user-select: none; - background-image: url(Images/toolbarButtonGlyphs.png); - background-size: 352px 168px; + background-image: url(Images/smallIcons.png); + background-size: 190px 30px; width: 10px; height: 10px; position: relative; top: 2px; margin-right: 4px; - background-position: -192px -96px; + background-position: -20px -20px; } @media (-webkit-min-device-pixel-ratio: 1.5) { .suggest-box .suggest-box-content-item.additional::before { - background-image: url(Images/toolbarButtonGlyphs_2x.png); + background-image: url(Images/smallIcons_2x.png); } } /* media */
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/addSourceMapURLDialog.css b/third_party/WebKit/Source/devtools/front_end/ui_lazy/dialog.css similarity index 100% rename from third_party/WebKit/Source/devtools/front_end/sources/addSourceMapURLDialog.css rename to third_party/WebKit/Source/devtools/front_end/ui_lazy/dialog.css
diff --git a/third_party/WebKit/Source/devtools/front_end/ui_lazy/module.json b/third_party/WebKit/Source/devtools/front_end/ui_lazy/module.json index ed9d2e9..037a124 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui_lazy/module.json +++ b/third_party/WebKit/Source/devtools/front_end/ui_lazy/module.json
@@ -38,6 +38,7 @@ ], "resources": [ "dataGrid.css", + "dialog.css", "filteredListWidget.css", "flameChart.css", "overviewGrid.css",
diff --git a/third_party/WebKit/Source/devtools/scripts/hosted_mode/server.js b/third_party/WebKit/Source/devtools/scripts/hosted_mode/server.js index 811bf70a..9bdf3cdb 100644 --- a/third_party/WebKit/Source/devtools/scripts/hosted_mode/server.js +++ b/third_party/WebKit/Source/devtools/scripts/hosted_mode/server.js
@@ -13,7 +13,10 @@ var devtoolsFolder = path.resolve(path.join(__dirname, "../..")); http.createServer(requestHandler).listen(serverPort); -console.log("Started hosted mode server at http://localhost:" + serverPort); +console.log(`Started hosted mode server at http://localhost:${serverPort}\n`); +console.log("For info on using the hosted mode server, see our contributing docs:"); +console.log("https://bit.ly/devtools-contribution-guide"); +console.log("Tip: Look for the 'Hosted Mode Server Options' section"); function requestHandler(request, response) { @@ -42,7 +45,7 @@ var absoluteFilePath = path.join(process.cwd(), filePath); if (!path.resolve(absoluteFilePath).startsWith(devtoolsFolder)) { console.log(`File requested is outside of devtools folder: ${devtoolsFolder}`); - sendResponse(403, "`403 - Access denied. File requested is outside of devtools folder: ${devtoolsFolder}`"); + sendResponse(403, `403 - Access denied. File requested is outside of devtools folder: ${devtoolsFolder}`); return; } @@ -93,8 +96,11 @@ { if (!(filePath in proxyFilePathToURL)) return null; + if (process.env.CHROMIUM_COMMIT) + return onProxyFileURL(proxyFilePathToURL[filePath](process.env.CHROMIUM_COMMIT)); return fetch(`http://localhost:${remoteDebuggingPort}/json/version`) - .then(onBrowserMetadata); + .then(onBrowserMetadata) + .then(onProxyFileURL); function onBrowserMetadata(metadata) { @@ -102,8 +108,13 @@ var match = metadataObject["WebKit-Version"].match(/\s\(@(\b[0-9a-f]{5,40}\b)/); var commitHash = match[1]; var proxyFileURL = proxyFilePathToURL[filePath](commitHash); + return proxyFileURL; + } + + function onProxyFileURL(proxyFileURL) + { if (proxyFileCache.has(proxyFileURL)) - return proxyFileCache.get(proxyFileURL); + return Promise.resolve(proxyFileCache.get(proxyFileURL)); return fetch(proxyFileURL) .then(cacheProxyFile.bind(null, proxyFileURL)); }
diff --git a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp index ec779e1..46c3df1 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
@@ -718,12 +718,17 @@ } return false; } + if (isHeading()) return false; if (isLandmarkRelated()) return false; + // Header and footer tags may also be exposed as landmark roles but not always. + if (getNode() && (getNode()->hasTagName(headerTag) || getNode()->hasTagName(footerTag))) + return false; + if (isLink()) return false;
diff --git a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp index 1db628f1..0b5202f 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp
@@ -494,12 +494,22 @@ } // There should only be one banner/contentInfo per page. If header/footer are being used within an article or section - // then it should not be exposed as whole page's banner/contentInfo - if (getNode()->hasTagName(headerTag) && !isDescendantOfElementType(articleTag) && !isDescendantOfElementType(sectionTag)) + // then it should not be exposed as whole page's banner/contentInfo but as a group role. + if (getNode()->hasTagName(headerTag)) { + if (isDescendantOfElementType(articleTag) || isDescendantOfElementType(sectionTag) + || (getNode()->parentElement() && getNode()->parentElement()->hasTagName(mainTag))) { + return GroupRole; + } return BannerRole; + } - if (getNode()->hasTagName(footerTag) && !isDescendantOfElementType(articleTag) && !isDescendantOfElementType(sectionTag)) + if (getNode()->hasTagName(footerTag)) { + if (isDescendantOfElementType(articleTag) || isDescendantOfElementType(sectionTag) + || (getNode()->parentElement() && getNode()->parentElement()->hasTagName(mainTag))) { + return GroupRole; + } return FooterRole; + } if (getNode()->hasTagName(blockquoteTag)) return BlockquoteRole;
diff --git a/third_party/WebKit/Source/modules/accessibility/InspectorAccessibilityAgent.cpp b/third_party/WebKit/Source/modules/accessibility/InspectorAccessibilityAgent.cpp index 78b6bf0..a9759da 100644 --- a/third_party/WebKit/Source/modules/accessibility/InspectorAccessibilityAgent.cpp +++ b/third_party/WebKit/Source/modules/accessibility/InspectorAccessibilityAgent.cpp
@@ -14,7 +14,6 @@ #include "modules/accessibility/AXObject.h" #include "modules/accessibility/AXObjectCacheImpl.h" #include "modules/accessibility/InspectorTypeBuilderHelper.h" -#include "platform/inspector_protocol/Values.h" #include <memory> namespace blink {
diff --git a/third_party/WebKit/Source/modules/beacon/NavigatorBeacon.cpp b/third_party/WebKit/Source/modules/beacon/NavigatorBeacon.cpp index b1893de4..5affdb5 100644 --- a/third_party/WebKit/Source/modules/beacon/NavigatorBeacon.cpp +++ b/third_party/WebKit/Source/modules/beacon/NavigatorBeacon.cpp
@@ -16,7 +16,7 @@ #include "core/frame/UseCounter.h" #include "core/frame/csp/ContentSecurityPolicy.h" #include "core/html/FormData.h" -#include "core/loader/BeaconLoader.h" +#include "core/loader/PingLoader.h" namespace blink { @@ -113,7 +113,7 @@ bool allowed; if (data.isArrayBufferView()) { - allowed = BeaconLoader::sendBeacon(impl.frame(), allowance, url, data.getAsArrayBufferView(), bytes); + allowed = PingLoader::sendBeacon(impl.frame(), allowance, url, data.getAsArrayBufferView(), bytes); } else if (data.isBlob()) { Blob* blob = data.getAsBlob(); if (!FetchUtils::isSimpleContentType(AtomicString(blob->type()))) { @@ -123,13 +123,13 @@ return false; } } - allowed = BeaconLoader::sendBeacon(impl.frame(), allowance, url, blob, bytes); + allowed = PingLoader::sendBeacon(impl.frame(), allowance, url, blob, bytes); } else if (data.isString()) { - allowed = BeaconLoader::sendBeacon(impl.frame(), allowance, url, data.getAsString(), bytes); + allowed = PingLoader::sendBeacon(impl.frame(), allowance, url, data.getAsString(), bytes); } else if (data.isFormData()) { - allowed = BeaconLoader::sendBeacon(impl.frame(), allowance, url, data.getAsFormData(), bytes); + allowed = PingLoader::sendBeacon(impl.frame(), allowance, url, data.getAsFormData(), bytes); } else { - allowed = BeaconLoader::sendBeacon(impl.frame(), allowance, url, String(), bytes); + allowed = PingLoader::sendBeacon(impl.frame(), allowance, url, String(), bytes); } return impl.beaconResult(context, allowed, bytes);
diff --git a/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannel.cpp b/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannel.cpp index 2e2b118..81a588b 100644 --- a/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannel.cpp +++ b/third_party/WebKit/Source/modules/broadcastchannel/BroadcastChannel.cpp
@@ -121,6 +121,8 @@ , m_name(name) , m_binding(this) { + ThreadState::current()->registerPreFinalizer(this); + mojom::blink::BroadcastChannelProviderPtr& provider = getThreadSpecificProvider(); // Local BroadcastChannelClient for messages send from the browser to this channel.
diff --git a/third_party/WebKit/Source/modules/budget/Budget.cpp b/third_party/WebKit/Source/modules/budget/Budget.cpp deleted file mode 100644 index 3708b13..0000000 --- a/third_party/WebKit/Source/modules/budget/Budget.cpp +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2016 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 "modules/budget/Budget.h" - -#include "bindings/core/v8/ScriptPromise.h" -#include "bindings/core/v8/ScriptPromiseResolver.h" -#include "bindings/core/v8/ScriptState.h" -#include "core/dom/DOMException.h" -#include "core/dom/ExceptionCode.h" - -namespace blink { - -Budget::Budget() {} - -ScriptPromise Budget::getCost(ScriptState* scriptState, const AtomicString& actionType) -{ - // TODO(harkness): Trigger the cost calculation. - return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError, "Not yet implemented")); -} - -ScriptPromise Budget::getBudget(ScriptState* scriptState) -{ - // TODO(harkness): Trigger the budget calculation. - return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError, "Not yet implemented")); -} - -} // namespace blink
diff --git a/third_party/WebKit/Source/modules/budget/Budget.h b/third_party/WebKit/Source/modules/budget/Budget.h deleted file mode 100644 index 186f7ca2..0000000 --- a/third_party/WebKit/Source/modules/budget/Budget.h +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2016 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 Budget_h -#define Budget_h - -#include "bindings/core/v8/ScriptWrappable.h" -#include "modules/ModulesExport.h" - -namespace blink { - -class ScriptPromise; -class ScriptState; - -// This is the entry point into the browser for the Budget API, which is -// designed to give origins the ability to perform background operations -// on the user's behalf. -class Budget final : public GarbageCollected<Budget>, public ScriptWrappable { - DEFINE_WRAPPERTYPEINFO(); - -public: - static Budget* create() - { - return new Budget(); - } - - ScriptPromise getCost(ScriptState*, const AtomicString& actionType); - ScriptPromise getBudget(ScriptState*); - - DEFINE_INLINE_TRACE() {} - -private: - Budget(); -}; - -} // namespace blink - -#endif // Budget_h
diff --git a/third_party/WebKit/Source/modules/budget/Budget.idl b/third_party/WebKit/Source/modules/budget/Budget.idl deleted file mode 100644 index e70f063e8..0000000 --- a/third_party/WebKit/Source/modules/budget/Budget.idl +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2016 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. - -// https://beverloo.github.io/budget-api/#budget-service-interface -// TODO(harkness): Link WICG spec when it exists. - -enum ActionType { - "silent-push" -}; - -[ - RuntimeEnabled=Budget -] interface Budget { - [CallWith=ScriptState] Promise<double> getCost(ActionType actionType); - [CallWith=ScriptState] Promise<FrozenArray<BudgetChunk>> getBudget(); -};
diff --git a/third_party/WebKit/Source/modules/budget/BudgetService.cpp b/third_party/WebKit/Source/modules/budget/BudgetService.cpp new file mode 100644 index 0000000..52ae315d --- /dev/null +++ b/third_party/WebKit/Source/modules/budget/BudgetService.cpp
@@ -0,0 +1,29 @@ +// Copyright 2016 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 "modules/budget/BudgetService.h" + +#include "bindings/core/v8/ScriptPromise.h" +#include "bindings/core/v8/ScriptPromiseResolver.h" +#include "bindings/core/v8/ScriptState.h" +#include "core/dom/DOMException.h" +#include "core/dom/ExceptionCode.h" + +namespace blink { + +BudgetService::BudgetService() {} + +ScriptPromise BudgetService::getCost(ScriptState* scriptState, const AtomicString& actionType) +{ + // TODO(harkness): Trigger the cost calculation. + return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError, "Not yet implemented")); +} + +ScriptPromise BudgetService::getBudget(ScriptState* scriptState) +{ + // TODO(harkness): Trigger the budget calculation. + return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError, "Not yet implemented")); +} + +} // namespace blink
diff --git a/third_party/WebKit/Source/modules/budget/BudgetService.h b/third_party/WebKit/Source/modules/budget/BudgetService.h new file mode 100644 index 0000000..6d858bc --- /dev/null +++ b/third_party/WebKit/Source/modules/budget/BudgetService.h
@@ -0,0 +1,39 @@ +// Copyright 2016 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 BudgetService_h +#define BudgetService_h + +#include "bindings/core/v8/ScriptWrappable.h" +#include "modules/ModulesExport.h" + +namespace blink { + +class ScriptPromise; +class ScriptState; + +// This is the entry point into the browser for the BudgetService API, which is +// designed to give origins the ability to perform background operations +// on the user's behalf. +class BudgetService final : public GarbageCollected<BudgetService>, public ScriptWrappable { + DEFINE_WRAPPERTYPEINFO(); + +public: + static BudgetService* create() + { + return new BudgetService(); + } + + ScriptPromise getCost(ScriptState*, const AtomicString& actionType); + ScriptPromise getBudget(ScriptState*); + + DEFINE_INLINE_TRACE() {} + +private: + BudgetService(); +}; + +} // namespace blink + +#endif // BudgetService_h
diff --git a/third_party/WebKit/Source/modules/budget/BudgetService.idl b/third_party/WebKit/Source/modules/budget/BudgetService.idl new file mode 100644 index 0000000..8ccf5329 --- /dev/null +++ b/third_party/WebKit/Source/modules/budget/BudgetService.idl
@@ -0,0 +1,17 @@ +// Copyright 2016 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. + +// https://beverloo.github.io/budget-api/#budget-service-interface +// TODO(harkness): Link WICG spec when it exists. + +enum ActionType { + "silent-push" +}; + +[ + RuntimeEnabled=Budget +] interface BudgetService { + [CallWith=ScriptState] Promise<double> getCost(ActionType actionType); + [CallWith=ScriptState] Promise<FrozenArray<BudgetChunk>> getBudget(); +};
diff --git a/third_party/WebKit/Source/modules/budget/NavigatorBudget.cpp b/third_party/WebKit/Source/modules/budget/NavigatorBudget.cpp index a7f36bd..c9ceb2d 100644 --- a/third_party/WebKit/Source/modules/budget/NavigatorBudget.cpp +++ b/third_party/WebKit/Source/modules/budget/NavigatorBudget.cpp
@@ -5,7 +5,7 @@ #include "modules/budget/NavigatorBudget.h" #include "core/frame/Navigator.h" -#include "modules/budget/Budget.h" +#include "modules/budget/BudgetService.h" namespace blink { @@ -32,15 +32,15 @@ return *navigatorBudget; } -Budget* NavigatorBudget::budget() +BudgetService* NavigatorBudget::budget() { if (!m_budget) - m_budget = Budget::create(); + m_budget = BudgetService::create(); return m_budget.get(); } // static -Budget* NavigatorBudget::budget(Navigator& navigator) +BudgetService* NavigatorBudget::budget(Navigator& navigator) { return NavigatorBudget::from(navigator).budget(); }
diff --git a/third_party/WebKit/Source/modules/budget/NavigatorBudget.h b/third_party/WebKit/Source/modules/budget/NavigatorBudget.h index 53d5e95..14578ce 100644 --- a/third_party/WebKit/Source/modules/budget/NavigatorBudget.h +++ b/third_party/WebKit/Source/modules/budget/NavigatorBudget.h
@@ -9,7 +9,7 @@ namespace blink { -class Budget; +class BudgetService; class Navigator; // This exposes the budget object on the Navigator partial interface. @@ -22,8 +22,8 @@ public: static NavigatorBudget& from(Navigator&); - static Budget* budget(Navigator&); - Budget* budget(); + static BudgetService* budget(Navigator&); + BudgetService* budget(); DECLARE_VIRTUAL_TRACE(); @@ -31,7 +31,7 @@ NavigatorBudget(); static const char* supplementName(); - Member<Budget> m_budget; + Member<BudgetService> m_budget; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/budget/NavigatorBudget.idl b/third_party/WebKit/Source/modules/budget/NavigatorBudget.idl index 788e07c..dd0bfe2 100644 --- a/third_party/WebKit/Source/modules/budget/NavigatorBudget.idl +++ b/third_party/WebKit/Source/modules/budget/NavigatorBudget.idl
@@ -9,5 +9,5 @@ RuntimeEnabled=Budget ] partial interface Navigator { // TODO(harkness): In the spec, this is not a partial interface. - readonly attribute Budget budget; + readonly attribute BudgetService budget; };
diff --git a/third_party/WebKit/Source/modules/cachestorage/InspectorCacheStorageAgent.cpp b/third_party/WebKit/Source/modules/cachestorage/InspectorCacheStorageAgent.cpp index de7b57d..5fefd320 100644 --- a/third_party/WebKit/Source/modules/cachestorage/InspectorCacheStorageAgent.cpp +++ b/third_party/WebKit/Source/modules/cachestorage/InspectorCacheStorageAgent.cpp
@@ -5,8 +5,6 @@ #include "modules/cachestorage/InspectorCacheStorageAgent.h" #include "platform/heap/Handle.h" -#include "platform/inspector_protocol/DispatcherBase.h" -#include "platform/inspector_protocol/Values.h" #include "platform/weborigin/KURL.h" #include "platform/weborigin/SecurityOrigin.h" #include "public/platform/Platform.h"
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/ContentDecryptionModuleResultPromise.cpp b/third_party/WebKit/Source/modules/encryptedmedia/ContentDecryptionModuleResultPromise.cpp index be1abd1..728f3544 100644 --- a/third_party/WebKit/Source/modules/encryptedmedia/ContentDecryptionModuleResultPromise.cpp +++ b/third_party/WebKit/Source/modules/encryptedmedia/ContentDecryptionModuleResultPromise.cpp
@@ -71,13 +71,16 @@ // Non-zero |systemCode| is appended to the |errorMessage|. If the // |errorMessage| is empty, we'll report "Rejected with system code // (systemCode)". - String errorString = errorMessage; + StringBuilder result; + result.append(errorMessage); if (systemCode != 0) { - if (errorString.isEmpty()) - errorString.append("Rejected with system code"); - errorString.append(" (" + String::number(systemCode) + ")"); + if (result.isEmpty()) + result.append("Rejected with system code"); + result.append(" ("); + result.appendNumber(systemCode); + result.append(')'); } - reject(WebCdmExceptionToExceptionCode(exceptionCode), errorString); + reject(WebCdmExceptionToExceptionCode(exceptionCode), result.toString()); } ScriptPromise ContentDecryptionModuleResultPromise::promise()
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.cpp b/third_party/WebKit/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.cpp index 52588923..67ddefc 100644 --- a/third_party/WebKit/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.cpp +++ b/third_party/WebKit/Source/modules/encryptedmedia/HTMLMediaElementEncryptedMedia.cpp
@@ -18,7 +18,6 @@ #include "modules/encryptedmedia/MediaEncryptedEvent.h" #include "modules/encryptedmedia/MediaKeys.h" #include "platform/ContentDecryptionModuleResult.h" -#include "platform/Logging.h" #include "wtf/Functional.h" #define EME_LOG_LEVEL 3 @@ -89,13 +88,16 @@ { // Non-zero |systemCode| is appended to the |message|. If the |message| // is empty, we'll report "Rejected with system code (systemCode)". - String errorString = message; + StringBuilder result; + result.append(message); if (systemCode != 0) { - if (errorString.isEmpty()) - errorString.append("Rejected with system code"); - errorString.append(" (" + String::number(systemCode) + ")"); + if (result.isEmpty()) + result.append("Rejected with system code"); + result.append(" ("); + result.appendNumber(systemCode); + result.append(')'); } - (*m_failureCallback)(WebCdmExceptionToExceptionCode(code), errorString); + (*m_failureCallback)(WebCdmExceptionToExceptionCode(code), result.toString()); } private:
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp index 0c7f134..8c283ef 100644 --- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp +++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySession.cpp
@@ -41,7 +41,6 @@ #include "modules/encryptedmedia/SimpleContentDecryptionModuleResultPromise.h" #include "platform/ContentDecryptionModuleResult.h" #include "platform/ContentType.h" -#include "platform/Logging.h" #include "platform/Timer.h" #include "public/platform/WebContentDecryptionModule.h" #include "public/platform/WebContentDecryptionModuleException.h"
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySystemAccess.cpp b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySystemAccess.cpp index 3c9dd43..09314c6 100644 --- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySystemAccess.cpp +++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeySystemAccess.cpp
@@ -13,7 +13,6 @@ #include "modules/encryptedmedia/MediaKeySession.h" #include "modules/encryptedmedia/MediaKeys.h" #include "modules/encryptedmedia/MediaKeysController.h" -#include "platform/Logging.h" #include "platform/Timer.h" #include "public/platform/WebContentDecryptionModule.h" #include "public/platform/WebEncryptedMediaTypes.h"
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.cpp b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.cpp index acdf6c3..32922bc 100644 --- a/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.cpp +++ b/third_party/WebKit/Source/modules/encryptedmedia/MediaKeys.cpp
@@ -34,7 +34,6 @@ #include "modules/encryptedmedia/EncryptedMediaUtils.h" #include "modules/encryptedmedia/MediaKeySession.h" #include "modules/encryptedmedia/SimpleContentDecryptionModuleResultPromise.h" -#include "platform/Logging.h" #include "platform/Timer.h" #include "public/platform/WebContentDecryptionModule.h" #include "wtf/RefPtr.h"
diff --git a/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp b/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp index 0a61829..a5cbf99 100644 --- a/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp +++ b/third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp
@@ -17,7 +17,6 @@ #include "modules/encryptedmedia/MediaKeysController.h" #include "platform/EncryptedMediaRequest.h" #include "platform/Histogram.h" -#include "platform/Logging.h" #include "platform/network/ParsedContentType.h" #include "public/platform/WebEncryptedMediaClient.h" #include "public/platform/WebEncryptedMediaRequest.h"
diff --git a/third_party/WebKit/Source/modules/fetch/BodyStreamBufferTest.cpp b/third_party/WebKit/Source/modules/fetch/BodyStreamBufferTest.cpp index ef277f8..a4efa2f8 100644 --- a/third_party/WebKit/Source/modules/fetch/BodyStreamBufferTest.cpp +++ b/third_party/WebKit/Source/modules/fetch/BodyStreamBufferTest.cpp
@@ -34,7 +34,7 @@ class FakeLoaderFactory : public FetchBlobDataConsumerHandle::LoaderFactory { public: - std::unique_ptr<ThreadableLoader> create(ExecutionContext&, ThreadableLoaderClient*, const ThreadableLoaderOptions&, const ResourceLoaderOptions&) override + ThreadableLoader* create(ExecutionContext&, ThreadableLoaderClient*, const ThreadableLoaderOptions&, const ResourceLoaderOptions&) override { ASSERT_NOT_REACHED(); return nullptr;
diff --git a/third_party/WebKit/Source/modules/fetch/DataConsumerHandleTestUtil.h b/third_party/WebKit/Source/modules/fetch/DataConsumerHandleTestUtil.h index 2506af4..52986bec 100644 --- a/third_party/WebKit/Source/modules/fetch/DataConsumerHandleTestUtil.h +++ b/third_party/WebKit/Source/modules/fetch/DataConsumerHandleTestUtil.h
@@ -88,18 +88,26 @@ void recordAttach(const String& handle) { MutexLocker locker(m_loggingMutex); - m_result.append("A reader is attached to " + handle + " on " + currentThreadName() + ".\n"); + m_result.append("A reader is attached to "); + m_result.append(handle); + m_result.append(" on "); + m_result.append(currentThreadName()); + m_result.append(".\n"); } void recordDetach(const String& handle) { MutexLocker locker(m_loggingMutex); - m_result.append("A reader is detached from " + handle + " on " + currentThreadName() + ".\n"); + m_result.append("A reader is detached from "); + m_result.append(handle); + m_result.append(" on "); + m_result.append(currentThreadName()); + m_result.append(".\n"); } - const String& result() + String result() { MutexLocker locker(m_loggingMutex); - return m_result; + return m_result.toString(); } void registerThreadHolder(ThreadHolder* holder) @@ -144,7 +152,7 @@ // Protects |m_result|. Mutex m_loggingMutex; - String m_result; + StringBuilder m_result; // Protects |m_holder|. Mutex m_holderMutex; @@ -216,7 +224,7 @@ void resetReader() { m_reader = nullptr; } void signalDone() { m_waitableEvent->signal(); } - const String& result() { return m_context->result(); } + String result() { return m_context->result(); } void postTaskToReadingThread(const WebTraceLocation& location, std::unique_ptr<CrossThreadClosure> task) { m_context->postTaskToReadingThread(location, std::move(task));
diff --git a/third_party/WebKit/Source/modules/fetch/FetchBlobDataConsumerHandle.cpp b/third_party/WebKit/Source/modules/fetch/FetchBlobDataConsumerHandle.cpp index 5db39ff..11474211 100644 --- a/third_party/WebKit/Source/modules/fetch/FetchBlobDataConsumerHandle.cpp +++ b/third_party/WebKit/Source/modules/fetch/FetchBlobDataConsumerHandle.cpp
@@ -76,7 +76,7 @@ m_updater->update(createUnexpectedErrorDataConsumerHandle()); if (m_loader) { m_loader->cancel(); - m_loader.reset(); + m_loader = nullptr; } } @@ -103,7 +103,7 @@ } private: - std::unique_ptr<ThreadableLoader> createLoader(ExecutionContext* executionContext, ThreadableLoaderClient* client) const + ThreadableLoader* createLoader(ExecutionContext* executionContext, ThreadableLoaderClient* client) const { ThreadableLoaderOptions options; options.preflightPolicy = ConsiderPreflight; @@ -134,14 +134,14 @@ void didFinishLoading(unsigned long, double) override { - m_loader.reset(); + m_loader = nullptr; } void didFail(const ResourceError&) override { if (!m_receivedResponse) m_updater->update(createUnexpectedErrorDataConsumerHandle()); - m_loader.reset(); + m_loader = nullptr; } void didFailRedirectCheck() override @@ -154,14 +154,14 @@ RefPtr<BlobDataHandle> m_blobDataHandle; Persistent<FetchBlobDataConsumerHandle::LoaderFactory> m_loaderFactory; - std::unique_ptr<ThreadableLoader> m_loader; + Persistent<ThreadableLoader> m_loader; bool m_receivedResponse; }; class DefaultLoaderFactory final : public FetchBlobDataConsumerHandle::LoaderFactory { public: - std::unique_ptr<ThreadableLoader> create( + ThreadableLoader* create( ExecutionContext& executionContext, ThreadableLoaderClient* client, const ThreadableLoaderOptions& options,
diff --git a/third_party/WebKit/Source/modules/fetch/FetchBlobDataConsumerHandle.h b/third_party/WebKit/Source/modules/fetch/FetchBlobDataConsumerHandle.h index d484f78..e7c867b7 100644 --- a/third_party/WebKit/Source/modules/fetch/FetchBlobDataConsumerHandle.h +++ b/third_party/WebKit/Source/modules/fetch/FetchBlobDataConsumerHandle.h
@@ -25,7 +25,7 @@ public: class MODULES_EXPORT LoaderFactory : public GarbageCollectedFinalized<LoaderFactory> { public: - virtual std::unique_ptr<ThreadableLoader> create(ExecutionContext&, ThreadableLoaderClient*, const ThreadableLoaderOptions&, const ResourceLoaderOptions&) = 0; + virtual ThreadableLoader* create(ExecutionContext&, ThreadableLoaderClient*, const ThreadableLoaderOptions&, const ResourceLoaderOptions&) = 0; virtual ~LoaderFactory() { } DEFINE_INLINE_VIRTUAL_TRACE() { } };
diff --git a/third_party/WebKit/Source/modules/fetch/FetchBlobDataConsumerHandleTest.cpp b/third_party/WebKit/Source/modules/fetch/FetchBlobDataConsumerHandleTest.cpp index 50c03d4..b49316ca 100644 --- a/third_party/WebKit/Source/modules/fetch/FetchBlobDataConsumerHandleTest.cpp +++ b/third_party/WebKit/Source/modules/fetch/FetchBlobDataConsumerHandleTest.cpp
@@ -53,12 +53,7 @@ class MockLoaderFactory : public FetchBlobDataConsumerHandle::LoaderFactory { public: - std::unique_ptr<ThreadableLoader> create(ExecutionContext& executionContext, ThreadableLoaderClient* client, const ThreadableLoaderOptions& threadableLoaderOptions, const ResourceLoaderOptions& resourceLoaderOptions) override - { - return wrapUnique(createInternal(executionContext, client, threadableLoaderOptions, resourceLoaderOptions)); - } - - MOCK_METHOD4(createInternal, ThreadableLoader*(ExecutionContext&, ThreadableLoaderClient*, const ThreadableLoaderOptions&, const ResourceLoaderOptions&)); + MOCK_METHOD4(create, ThreadableLoader*(ExecutionContext&, ThreadableLoaderClient*, const ThreadableLoaderOptions&, const ResourceLoaderOptions&)); }; PassRefPtr<BlobDataHandle> createBlobDataHandle(const char* s) @@ -100,18 +95,17 @@ ThreadableLoaderOptions options; ResourceLoaderOptions resourceLoaderOptions; - std::unique_ptr<MockThreadableLoader> loader = MockThreadableLoader::create(); - MockThreadableLoader* loaderPtr = loader.get(); + Persistent<MockThreadableLoader> loader = MockThreadableLoader::create(); InSequence s; EXPECT_CALL(checkpoint, Call(1)); - EXPECT_CALL(*factory, createInternal(Ref(document()), _, _, _)).WillOnce(DoAll( + EXPECT_CALL(*factory, create(Ref(document()), _, _, _)).WillOnce(DoAll( SaveArg<2>(&options), SaveArg<3>(&resourceLoaderOptions), - Return(loader.release()))); - EXPECT_CALL(*loaderPtr, start(_)).WillOnce(SaveArg<0>(&request)); + Return(loader.get()))); + EXPECT_CALL(*loader, start(_)).WillOnce(SaveArg<0>(&request)); EXPECT_CALL(checkpoint, Call(2)); - EXPECT_CALL(*loaderPtr, cancel()); + EXPECT_CALL(*loader, cancel()); RefPtr<BlobDataHandle> blobDataHandle = createBlobDataHandle("Once upon a time"); std::unique_ptr<WebDataConsumerHandle> handle @@ -145,15 +139,14 @@ auto factory = new StrictMock<MockLoaderFactory>; Checkpoint checkpoint; - std::unique_ptr<MockThreadableLoader> loader = MockThreadableLoader::create(); - MockThreadableLoader* loaderPtr = loader.get(); + Persistent<MockThreadableLoader> loader = MockThreadableLoader::create(); InSequence s; EXPECT_CALL(checkpoint, Call(1)); - EXPECT_CALL(*factory, createInternal(Ref(document()), _, _, _)).WillOnce(Return(loader.release())); - EXPECT_CALL(*loaderPtr, start(_)); + EXPECT_CALL(*factory, create(Ref(document()), _, _, _)).WillOnce(Return(loader.get())); + EXPECT_CALL(*loader, start(_)); EXPECT_CALL(checkpoint, Call(2)); - EXPECT_CALL(*loaderPtr, cancel()); + EXPECT_CALL(*loader, cancel()); EXPECT_CALL(checkpoint, Call(3)); RefPtr<BlobDataHandle> blobDataHandle = createBlobDataHandle("Once upon a time"); @@ -175,16 +168,15 @@ auto factory = new StrictMock<MockLoaderFactory>; Checkpoint checkpoint; - std::unique_ptr<MockThreadableLoader> loader = MockThreadableLoader::create(); - MockThreadableLoader* loaderPtr = loader.get(); + Persistent<MockThreadableLoader> loader = MockThreadableLoader::create(); InSequence s; EXPECT_CALL(checkpoint, Call(1)); - EXPECT_CALL(*factory, createInternal(Ref(document()), _, _, _)).WillOnce(Return(loader.release())); - EXPECT_CALL(*loaderPtr, start(_)); + EXPECT_CALL(*factory, create(Ref(document()), _, _, _)).WillOnce(Return(loader.get())); + EXPECT_CALL(*loader, start(_)); EXPECT_CALL(checkpoint, Call(2)); EXPECT_CALL(checkpoint, Call(3)); - EXPECT_CALL(*loaderPtr, cancel()); + EXPECT_CALL(*loader, cancel()); EXPECT_CALL(checkpoint, Call(4)); RefPtr<BlobDataHandle> blobDataHandle = createBlobDataHandle("Once upon a time"); @@ -210,16 +202,15 @@ auto factory = new StrictMock<MockLoaderFactory>; Checkpoint checkpoint; - std::unique_ptr<MockThreadableLoader> loader = MockThreadableLoader::create(); - MockThreadableLoader* loaderPtr = loader.get(); + Persistent<MockThreadableLoader> loader = MockThreadableLoader::create(); ThreadableLoaderClient* client = nullptr; InSequence s; EXPECT_CALL(checkpoint, Call(1)); - EXPECT_CALL(*factory, createInternal(Ref(document()), _, _, _)).WillOnce(DoAll(SaveArg<1>(&client), Return(loader.release()))); - EXPECT_CALL(*loaderPtr, start(_)); + EXPECT_CALL(*factory, create(Ref(document()), _, _, _)).WillOnce(DoAll(SaveArg<1>(&client), Return(loader.get()))); + EXPECT_CALL(*loader, start(_)); EXPECT_CALL(checkpoint, Call(2)); - EXPECT_CALL(*loaderPtr, cancel()); + EXPECT_CALL(*loader, cancel()); RefPtr<BlobDataHandle> blobDataHandle = createBlobDataHandle("Once upon a time"); std::unique_ptr<WebDataConsumerHandle> handle @@ -249,16 +240,15 @@ auto factory = new StrictMock<MockLoaderFactory>; Checkpoint checkpoint; - std::unique_ptr<MockThreadableLoader> loader = MockThreadableLoader::create(); - MockThreadableLoader* loaderPtr = loader.get(); + Persistent<MockThreadableLoader> loader = MockThreadableLoader::create(); ThreadableLoaderClient* client = nullptr; InSequence s; EXPECT_CALL(checkpoint, Call(1)); - EXPECT_CALL(*factory, createInternal(Ref(document()), _, _, _)).WillOnce(DoAll(SaveArg<1>(&client), Return(loader.release()))); - EXPECT_CALL(*loaderPtr, start(_)); + EXPECT_CALL(*factory, create(Ref(document()), _, _, _)).WillOnce(DoAll(SaveArg<1>(&client), Return(loader.get()))); + EXPECT_CALL(*loader, start(_)); EXPECT_CALL(checkpoint, Call(2)); - EXPECT_CALL(*loaderPtr, cancel()); + EXPECT_CALL(*loader, cancel()); RefPtr<BlobDataHandle> blobDataHandle = createBlobDataHandle("Once upon a time"); std::unique_ptr<WebDataConsumerHandle> handle @@ -288,14 +278,13 @@ auto factory = new StrictMock<MockLoaderFactory>; Checkpoint checkpoint; - std::unique_ptr<MockThreadableLoader> loader = MockThreadableLoader::create(); - MockThreadableLoader* loaderPtr = loader.get(); + Persistent<MockThreadableLoader> loader = MockThreadableLoader::create(); ThreadableLoaderClient* client = nullptr; InSequence s; EXPECT_CALL(checkpoint, Call(1)); - EXPECT_CALL(*factory, createInternal(Ref(document()), _, _, _)).WillOnce(DoAll(SaveArg<1>(&client), Return(loader.release()))); - EXPECT_CALL(*loaderPtr, start(_)); + EXPECT_CALL(*factory, create(Ref(document()), _, _, _)).WillOnce(DoAll(SaveArg<1>(&client), Return(loader.get()))); + EXPECT_CALL(*loader, start(_)); EXPECT_CALL(checkpoint, Call(2)); RefPtr<BlobDataHandle> blobDataHandle = createBlobDataHandle("Once upon a time"); @@ -318,16 +307,15 @@ auto factory = new StrictMock<MockLoaderFactory>; Checkpoint checkpoint; - std::unique_ptr<MockThreadableLoader> loader = MockThreadableLoader::create(); - MockThreadableLoader* loaderPtr = loader.get(); + Persistent<MockThreadableLoader> loader = MockThreadableLoader::create(); ThreadableLoaderClient* client = nullptr; InSequence s; EXPECT_CALL(checkpoint, Call(1)); - EXPECT_CALL(*factory, createInternal(Ref(document()), _, _, _)).WillOnce(DoAll(SaveArg<1>(&client), Return(loader.release()))); - EXPECT_CALL(*loaderPtr, start(_)); + EXPECT_CALL(*factory, create(Ref(document()), _, _, _)).WillOnce(DoAll(SaveArg<1>(&client), Return(loader.get()))); + EXPECT_CALL(*loader, start(_)); EXPECT_CALL(checkpoint, Call(2)); - EXPECT_CALL(*loaderPtr, cancel()); + EXPECT_CALL(*loader, cancel()); RefPtr<BlobDataHandle> blobDataHandle = createBlobDataHandle("Once upon a time"); std::unique_ptr<WebDataConsumerHandle> handle
diff --git a/third_party/WebKit/Source/modules/fetch/FetchFormDataConsumerHandleTest.cpp b/third_party/WebKit/Source/modules/fetch/FetchFormDataConsumerHandleTest.cpp index f45c7443..ae801dc 100644 --- a/third_party/WebKit/Source/modules/fetch/FetchFormDataConsumerHandleTest.cpp +++ b/third_party/WebKit/Source/modules/fetch/FetchFormDataConsumerHandleTest.cpp
@@ -52,14 +52,14 @@ explicit LoaderFactory(std::unique_ptr<WebDataConsumerHandle> handle) : m_client(nullptr) , m_handle(std::move(handle)) {} - std::unique_ptr<ThreadableLoader> create(ExecutionContext&, ThreadableLoaderClient* client, const ThreadableLoaderOptions&, const ResourceLoaderOptions&) override + ThreadableLoader* create(ExecutionContext&, ThreadableLoaderClient* client, const ThreadableLoaderOptions&, const ResourceLoaderOptions&) override { m_client = client; - std::unique_ptr<MockThreadableLoader> loader = MockThreadableLoader::create(); + MockThreadableLoader* loader = MockThreadableLoader::create(); EXPECT_CALL(*loader, start(_)).WillOnce(InvokeWithoutArgs(this, &LoaderFactory::handleDidReceiveResponse)); EXPECT_CALL(*loader, cancel()).Times(1); - return std::move(loader); + return loader; } private:
diff --git a/third_party/WebKit/Source/modules/fetch/FetchManager.cpp b/third_party/WebKit/Source/modules/fetch/FetchManager.cpp index a697e11..d229085 100644 --- a/third_party/WebKit/Source/modules/fetch/FetchManager.cpp +++ b/third_party/WebKit/Source/modules/fetch/FetchManager.cpp
@@ -169,7 +169,7 @@ Member<FetchManager> m_fetchManager; Member<ScriptPromiseResolver> m_resolver; Member<FetchRequestData> m_request; - std::unique_ptr<ThreadableLoader> m_loader; + Member<ThreadableLoader> m_loader; bool m_failed; bool m_finished; int m_responseHttpStatusCode; @@ -204,6 +204,7 @@ visitor->trace(m_fetchManager); visitor->trace(m_resolver); visitor->trace(m_request); + visitor->trace(m_loader); visitor->trace(m_integrityVerifier); visitor->trace(m_executionContext); } @@ -524,7 +525,7 @@ m_fetchManager = nullptr; if (m_loader) { m_loader->cancel(); - m_loader.reset(); + m_loader = nullptr; } m_executionContext = nullptr; }
diff --git a/third_party/WebKit/Source/modules/geolocation/Geolocation.cpp b/third_party/WebKit/Source/modules/geolocation/Geolocation.cpp index 8df54b66..a7893f2 100644 --- a/third_party/WebKit/Source/modules/geolocation/Geolocation.cpp +++ b/third_party/WebKit/Source/modules/geolocation/Geolocation.cpp
@@ -36,6 +36,7 @@ #include "platform/UserGestureIndicator.h" #include "platform/mojo/MojoHelper.h" #include "public/platform/InterfaceProvider.h" +#include "public/platform/Platform.h" #include "wtf/Assertions.h" #include "wtf/CurrentTime.h" @@ -525,6 +526,13 @@ void Geolocation::onGeolocationConnectionError() { + // If a request is outstanding at process shutdown, this error handler will + // be called. In that case, blink has already shut down so do nothing. + // + // TODO(sammc): Remove this once renderer shutdown is no longer graceful. + if (!Platform::current()) + return; + PositionError* error = PositionError::create(PositionError::kPositionUnavailable, failedToStartServiceErrorMessage); error->setIsFatal(true); handleError(error); @@ -532,6 +540,13 @@ void Geolocation::onPermissionConnectionError() { + // If a request is outstanding at process shutdown, this error handler will + // be called. In that case, blink has already shut down so do nothing. + // + // TODO(sammc): Remove this once renderer shutdown is no longer graceful. + if (!Platform::current()) + return; + onGeolocationPermissionUpdated(mojom::blink::PermissionStatus::DENIED); }
diff --git a/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp b/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp index 7b66553..002e506d 100644 --- a/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp +++ b/third_party/WebKit/Source/modules/indexeddb/InspectorIndexedDBAgent.cpp
@@ -55,7 +55,6 @@ #include "modules/indexeddb/IDBOpenDBRequest.h" #include "modules/indexeddb/IDBRequest.h" #include "modules/indexeddb/IDBTransaction.h" -#include "platform/inspector_protocol/Values.h" #include "platform/v8_inspector/public/V8InspectorSession.h" #include "platform/weborigin/SecurityOrigin.h" #include "public/platform/modules/indexeddb/WebIDBCursor.h"
diff --git a/third_party/WebKit/Source/modules/mediasource/MediaSource.cpp b/third_party/WebKit/Source/modules/mediasource/MediaSource.cpp index e111b52..e48dfd7 100644 --- a/third_party/WebKit/Source/modules/mediasource/MediaSource.cpp +++ b/third_party/WebKit/Source/modules/mediasource/MediaSource.cpp
@@ -41,7 +41,6 @@ #include "core/html/HTMLMediaElement.h" #include "modules/mediasource/MediaSourceRegistry.h" #include "platform/ContentType.h" -#include "platform/Logging.h" #include "platform/MIMETypeRegistry.h" #include "platform/RuntimeEnabledFeatures.h" #include "platform/TraceEvent.h"
diff --git a/third_party/WebKit/Source/modules/mediasource/SourceBuffer.cpp b/third_party/WebKit/Source/modules/mediasource/SourceBuffer.cpp index 7f4e113..14fb000 100644 --- a/third_party/WebKit/Source/modules/mediasource/SourceBuffer.cpp +++ b/third_party/WebKit/Source/modules/mediasource/SourceBuffer.cpp
@@ -51,7 +51,6 @@ #include "core/streams/Stream.h" #include "modules/mediasource/MediaSource.h" #include "modules/mediasource/SourceBufferTrackBaseSupplement.h" -#include "platform/Logging.h" #include "platform/RuntimeEnabledFeatures.h" #include "platform/TraceEvent.h" #include "public/platform/WebSourceBuffer.h"
diff --git a/third_party/WebKit/Source/modules/mediastream/MediaConstraintsImpl.cpp b/third_party/WebKit/Source/modules/mediastream/MediaConstraintsImpl.cpp index a7b2b5d..56c542d9 100644 --- a/third_party/WebKit/Source/modules/mediastream/MediaConstraintsImpl.cpp +++ b/third_party/WebKit/Source/modules/mediastream/MediaConstraintsImpl.cpp
@@ -37,7 +37,6 @@ #include "core/frame/UseCounter.h" #include "core/inspector/ConsoleMessage.h" #include "modules/mediastream/MediaTrackConstraints.h" -#include "platform/Logging.h" #include "platform/RuntimeEnabledFeatures.h" #include "wtf/Assertions.h" #include "wtf/HashMap.h"
diff --git a/third_party/WebKit/Source/modules/mediastream/NavigatorUserMedia.cpp b/third_party/WebKit/Source/modules/mediastream/NavigatorUserMedia.cpp index 8a9a65d..7446e378 100644 --- a/third_party/WebKit/Source/modules/mediastream/NavigatorUserMedia.cpp +++ b/third_party/WebKit/Source/modules/mediastream/NavigatorUserMedia.cpp
@@ -9,7 +9,6 @@ #include "core/frame/LocalFrame.h" #include "core/frame/Navigator.h" #include "modules/mediastream/MediaDevices.h" -#include "platform/Logging.h" namespace blink {
diff --git a/third_party/WebKit/Source/modules/modules.gypi b/third_party/WebKit/Source/modules/modules.gypi index 0f45df5..e9dd040 100644 --- a/third_party/WebKit/Source/modules/modules.gypi +++ b/third_party/WebKit/Source/modules/modules.gypi
@@ -27,7 +27,7 @@ 'bluetooth/BluetoothRemoteGATTService.idl', 'bluetooth/BluetoothUUID.idl', 'broadcastchannel/BroadcastChannel.idl', - 'budget/Budget.idl', + 'budget/BudgetService.idl', 'cachestorage/Cache.idl', 'cachestorage/CacheStorage.idl', 'canvas2d/CanvasGradient.idl', @@ -906,8 +906,8 @@ 'bluetooth/NavigatorBluetooth.h', 'broadcastchannel/BroadcastChannel.cpp', 'broadcastchannel/BroadcastChannel.h', - 'budget/Budget.h', - 'budget/Budget.cpp', + 'budget/BudgetService.h', + 'budget/BudgetService.cpp', 'budget/NavigatorBudget.h', 'budget/NavigatorBudget.cpp', 'cachestorage/Cache.cpp', @@ -1808,6 +1808,8 @@ 'webdatabase/SQLTransactionState.h', 'webdatabase/SQLTransactionStateMachine.cpp', 'webdatabase/SQLTransactionStateMachine.h', + 'webdatabase/StorageLog.h', + 'webdatabase/sqlite/SQLLog.h', 'webdatabase/sqlite/SQLValue.cpp', 'webdatabase/sqlite/SQLiteAuthorizer.cpp', 'webdatabase/sqlite/SQLiteDatabase.cpp',
diff --git a/third_party/WebKit/Source/modules/notifications/NotificationImageLoader.cpp b/third_party/WebKit/Source/modules/notifications/NotificationImageLoader.cpp index 298931c6..530aee3 100644 --- a/third_party/WebKit/Source/modules/notifications/NotificationImageLoader.cpp +++ b/third_party/WebKit/Source/modules/notifications/NotificationImageLoader.cpp
@@ -65,11 +65,7 @@ m_stopped = true; if (m_threadableLoader) { m_threadableLoader->cancel(); - // WorkerThreadableLoader keeps a Persistent<WorkerGlobalScope> to the - // ExecutionContext it received in |create|. Kill it to prevent - // reference cycles involving a mix of GC and non-GC types that fail to - // clear in ThreadState::cleanup. - m_threadableLoader.reset(); + m_threadableLoader = nullptr; } }
diff --git a/third_party/WebKit/Source/modules/notifications/NotificationImageLoader.h b/third_party/WebKit/Source/modules/notifications/NotificationImageLoader.h index 363b4fb..59f48804 100644 --- a/third_party/WebKit/Source/modules/notifications/NotificationImageLoader.h +++ b/third_party/WebKit/Source/modules/notifications/NotificationImageLoader.h
@@ -46,7 +46,10 @@ void didFail(const ResourceError&) override; void didFailRedirectCheck() override; - DEFINE_INLINE_TRACE() {} + DEFINE_INLINE_TRACE() + { + visitor->trace(m_threadableLoader); + } private: void runCallbackWithEmptyBitmap(); @@ -55,7 +58,7 @@ double m_startTime; RefPtr<SharedBuffer> m_data; std::unique_ptr<ImageCallback> m_imageCallback; - std::unique_ptr<ThreadableLoader> m_threadableLoader; + Member<ThreadableLoader> m_threadableLoader; }; } // namespace blink
diff --git a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.idl b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.idl index 0690292..6304230 100644 --- a/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.idl +++ b/third_party/WebKit/Source/modules/offscreencanvas2d/OffscreenCanvasRenderingContext2D.idl
@@ -9,7 +9,7 @@ RuntimeEnabled=ExperimentalCanvasFeatures, ] interface OffscreenCanvasRenderingContext2D { // back-reference to the canvas - [ImplementedAs=getOffscreenCanvas] readonly attribute OffscreenCanvas offscreenCanvas; + [ImplementedAs=getOffscreenCanvas] readonly attribute OffscreenCanvas canvas; // colors and styles attribute (DOMString or CanvasGradient or CanvasPattern) strokeStyle; // (default black)
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp index e2961a98..22f3dc1 100644 --- a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp +++ b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
@@ -694,6 +694,7 @@ void PaymentRequest::clearResolversAndCloseMojoConnection() { + m_completeTimer.stop(); m_completeResolver.clear(); m_showResolver.clear(); m_abortResolver.clear();
diff --git a/third_party/WebKit/Source/modules/permissions/Permissions.cpp b/third_party/WebKit/Source/modules/permissions/Permissions.cpp index 69d0cae..28372bfd 100644 --- a/third_party/WebKit/Source/modules/permissions/Permissions.cpp +++ b/third_party/WebKit/Source/modules/permissions/Permissions.cpp
@@ -17,7 +17,6 @@ #include "core/frame/LocalFrame.h" #include "modules/permissions/PermissionDescriptor.h" #include "modules/permissions/PermissionStatus.h" -#include "platform/Logging.h" #include "platform/UserGestureIndicator.h" #include "public/platform/InterfaceProvider.h" #include "public/platform/Platform.h" @@ -213,9 +212,8 @@ ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); - Vector<PermissionName> internalPermissionsCopy(internalPermissions); - service->RequestPermissions(std::move(internalPermissions), scriptState->getExecutionContext()->getSecurityOrigin()->toString(), UserGestureIndicator::processingUserGesture(), - convertToBaseCallback(WTF::bind(&Permissions::batchTaskComplete, wrapPersistent(this), wrapPersistent(resolver), std::move(internalPermissionsCopy), std::move(callerIndexToInternalIndex)))); + service->RequestPermissions(internalPermissions, scriptState->getExecutionContext()->getSecurityOrigin()->toString(), UserGestureIndicator::processingUserGesture(), + convertToBaseCallback(WTF::bind(&Permissions::batchTaskComplete, wrapPersistent(this), wrapPersistent(resolver), internalPermissions, callerIndexToInternalIndex))); return promise; } @@ -238,7 +236,7 @@ resolver->resolve(PermissionStatus::take(resolver, result, name)); } -void Permissions::batchTaskComplete(ScriptPromiseResolver* resolver, Vector<PermissionName> names, Vector<int> callerIndexToInternalIndex, mojo::WTFArray<mojom::blink::PermissionStatus> results) +void Permissions::batchTaskComplete(ScriptPromiseResolver* resolver, Vector<PermissionName> names, Vector<int> callerIndexToInternalIndex, const Vector<mojom::blink::PermissionStatus>& results) { if (!resolver->getExecutionContext() || resolver->getExecutionContext()->activeDOMObjectsAreStopped()) return;
diff --git a/third_party/WebKit/Source/modules/permissions/Permissions.h b/third_party/WebKit/Source/modules/permissions/Permissions.h index 3b4577e..5620cdc4 100644 --- a/third_party/WebKit/Source/modules/permissions/Permissions.h +++ b/third_party/WebKit/Source/modules/permissions/Permissions.h
@@ -37,7 +37,7 @@ mojom::blink::PermissionService* getService(ExecutionContext*); void serviceConnectionError(); void taskComplete(ScriptPromiseResolver*, mojom::blink::PermissionName, mojom::blink::PermissionStatus); - void batchTaskComplete(ScriptPromiseResolver*, Vector<mojom::blink::PermissionName>, Vector<int>, mojo::WTFArray<mojom::blink::PermissionStatus>); + void batchTaskComplete(ScriptPromiseResolver*, Vector<mojom::blink::PermissionName>, Vector<int>, const Vector<mojom::blink::PermissionStatus>&); mojom::blink::PermissionServicePtr m_service; };
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.idl b/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.idl index 8172ac7..cd7bf1fd 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchEvent.idl
@@ -7,7 +7,7 @@ Constructor(DOMString type, ForeignFetchEventInit eventInitDict), ConstructorCallWith=ScriptState, Exposed=ServiceWorker, - RuntimeEnabled=ForeignFetch, + OriginTrialEnabled=ForeignFetch, ] interface ForeignFetchEvent : ExtendableEvent { [SameObject] readonly attribute Request request; readonly attribute USVString origin;
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchOptions.idl b/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchOptions.idl index 61455fa..aaa2c55 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchOptions.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/ForeignFetchOptions.idl
@@ -4,9 +4,7 @@ // https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#dictdef-installevent-foreignfetchoptions -[ - RuntimeEnabled=ForeignFetch -] dictionary ForeignFetchOptions { +dictionary ForeignFetchOptions { required sequence<USVString> scopes; required sequence<USVString> origins; };
diff --git a/third_party/WebKit/Source/modules/serviceworkers/InstallEvent.idl b/third_party/WebKit/Source/modules/serviceworkers/InstallEvent.idl index 534fc7bb..f0c3b24 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/InstallEvent.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/InstallEvent.idl
@@ -7,7 +7,7 @@ [ Constructor(DOMString type, optional ExtendableEventInit eventInitDict), Exposed=ServiceWorker, - RuntimeEnabled=ForeignFetch, + OriginTrialEnabled=ForeignFetch, ] interface InstallEvent : ExtendableEvent { [CallWith=ExecutionContext, RaisesException] void registerForeignFetch(ForeignFetchOptions options); };
diff --git a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.idl b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.idl index 71ea34e..cb6d283 100644 --- a/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.idl +++ b/third_party/WebKit/Source/modules/serviceworkers/ServiceWorkerGlobalScope.idl
@@ -46,5 +46,5 @@ attribute EventHandler onfetch; attribute EventHandler oninstall; attribute EventHandler onmessage; - [RuntimeEnabled=ForeignFetch] attribute EventHandler onforeignfetch; + [OriginTrialEnabled=ForeignFetch] attribute EventHandler onforeignfetch; };
diff --git a/third_party/WebKit/Source/modules/storage/InspectorDOMStorageAgent.cpp b/third_party/WebKit/Source/modules/storage/InspectorDOMStorageAgent.cpp index d217ed64..d2b29561 100644 --- a/third_party/WebKit/Source/modules/storage/InspectorDOMStorageAgent.cpp +++ b/third_party/WebKit/Source/modules/storage/InspectorDOMStorageAgent.cpp
@@ -40,7 +40,6 @@ #include "modules/storage/Storage.h" #include "modules/storage/StorageNamespace.h" #include "modules/storage/StorageNamespaceController.h" -#include "platform/inspector_protocol/Values.h" #include "platform/weborigin/SecurityOrigin.h" namespace blink {
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioBufferSourceNode.cpp b/third_party/WebKit/Source/modules/webaudio/AudioBufferSourceNode.cpp index bcdae9a..7352d0e 100644 --- a/third_party/WebKit/Source/modules/webaudio/AudioBufferSourceNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/AudioBufferSourceNode.cpp
@@ -173,7 +173,8 @@ // Sanity check destinationFrameOffset, numberOfFrames. size_t destinationLength = bus->length(); - bool isLengthGood = destinationLength <= 4096 && numberOfFrames <= 4096; + bool isLengthGood = destinationLength <= AudioUtilities::kRenderQuantumFrames + && numberOfFrames <= AudioUtilities::kRenderQuantumFrames; ASSERT(isLengthGood); if (!isLengthGood) return false;
diff --git a/third_party/WebKit/Source/modules/webaudio/DefaultAudioDestinationNode.cpp b/third_party/WebKit/Source/modules/webaudio/DefaultAudioDestinationNode.cpp index 280a5a5..76c0cdaa 100644 --- a/third_party/WebKit/Source/modules/webaudio/DefaultAudioDestinationNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/DefaultAudioDestinationNode.cpp
@@ -27,7 +27,6 @@ #include "bindings/core/v8/ExceptionState.h" #include "core/dom/ExceptionCode.h" #include "modules/webaudio/BaseAudioContext.h" -#include "platform/Logging.h" namespace blink {
diff --git a/third_party/WebKit/Source/modules/webaudio/MediaElementAudioSourceNode.cpp b/third_party/WebKit/Source/modules/webaudio/MediaElementAudioSourceNode.cpp index 9659b09..c615923 100644 --- a/third_party/WebKit/Source/modules/webaudio/MediaElementAudioSourceNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/MediaElementAudioSourceNode.cpp
@@ -28,7 +28,6 @@ #include "modules/webaudio/AudioNodeOutput.h" #include "modules/webaudio/BaseAudioContext.h" #include "modules/webaudio/MediaElementAudioSourceNode.h" -#include "platform/Logging.h" #include "platform/audio/AudioUtilities.h" #include "platform/weborigin/SecurityOrigin.h" #include "wtf/Locker.h"
diff --git a/third_party/WebKit/Source/modules/webaudio/MediaStreamAudioSourceNode.cpp b/third_party/WebKit/Source/modules/webaudio/MediaStreamAudioSourceNode.cpp index bc503d7..0c94bf6 100644 --- a/third_party/WebKit/Source/modules/webaudio/MediaStreamAudioSourceNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/MediaStreamAudioSourceNode.cpp
@@ -27,7 +27,6 @@ #include "core/dom/ExceptionCode.h" #include "modules/webaudio/AudioNodeOutput.h" #include "modules/webaudio/BaseAudioContext.h" -#include "platform/Logging.h" #include "wtf/Locker.h" #include <memory>
diff --git a/third_party/WebKit/Source/modules/webaudio/WaveShaperDSPKernel.cpp b/third_party/WebKit/Source/modules/webaudio/WaveShaperDSPKernel.cpp index f841b05..4942b28f 100644 --- a/third_party/WebKit/Source/modules/webaudio/WaveShaperDSPKernel.cpp +++ b/third_party/WebKit/Source/modules/webaudio/WaveShaperDSPKernel.cpp
@@ -74,7 +74,7 @@ ASSERT(destination); ASSERT(getWaveShaperProcessor()); - DOMFloat32Array* curve = getWaveShaperProcessor()->curve(); + Vector<float>* curve = getWaveShaperProcessor()->curve(); if (!curve) { // Act as "straight wire" pass-through if no curve is set. memcpy(destination, source, sizeof(float) * framesToProcess); @@ -82,7 +82,7 @@ } float* curveData = curve->data(); - int curveLength = curve->length(); + int curveLength = curve->size(); ASSERT(curveData);
diff --git a/third_party/WebKit/Source/modules/webaudio/WaveShaperNode.cpp b/third_party/WebKit/Source/modules/webaudio/WaveShaperNode.cpp index c0046ed..e4d9ba1e 100644 --- a/third_party/WebKit/Source/modules/webaudio/WaveShaperNode.cpp +++ b/third_party/WebKit/Source/modules/webaudio/WaveShaperNode.cpp
@@ -76,7 +76,16 @@ DOMFloat32Array* WaveShaperNode::curve() { - return getWaveShaperProcessor()->curve(); + Vector<float>* curve = getWaveShaperProcessor()->curve(); + if (!curve) + return nullptr; + + unsigned size = curve->size(); + RefPtr<WTF::Float32Array> newCurve = WTF::Float32Array::create(size); + + memcpy(newCurve->data(), curve->data(), sizeof(float) * size); + + return DOMFloat32Array::create(newCurve.release()); } void WaveShaperNode::setOversample(const String& type)
diff --git a/third_party/WebKit/Source/modules/webaudio/WaveShaperProcessor.cpp b/third_party/WebKit/Source/modules/webaudio/WaveShaperProcessor.cpp index 3ad18df..9239d9d5 100644 --- a/third_party/WebKit/Source/modules/webaudio/WaveShaperProcessor.cpp +++ b/third_party/WebKit/Source/modules/webaudio/WaveShaperProcessor.cpp
@@ -51,7 +51,14 @@ // This synchronizes with process(). MutexLocker processLocker(m_processLock); - m_curve = curve; + // Copy the curve data, if any, to our internal buffer. + if (!curve) { + m_curve = nullptr; + return; + } + + m_curve = wrapUnique(new Vector<float>(curve->length())); + memcpy(m_curve->data(), curve->data(), sizeof(float)*curve->length()); } void WaveShaperProcessor::setOversample(OverSampleType oversample)
diff --git a/third_party/WebKit/Source/modules/webaudio/WaveShaperProcessor.h b/third_party/WebKit/Source/modules/webaudio/WaveShaperProcessor.h index b6b6708..024d337 100644 --- a/third_party/WebKit/Source/modules/webaudio/WaveShaperProcessor.h +++ b/third_party/WebKit/Source/modules/webaudio/WaveShaperProcessor.h
@@ -54,14 +54,14 @@ void process(const AudioBus* source, AudioBus* destination, size_t framesToProcess) override; void setCurve(DOMFloat32Array*); - DOMFloat32Array* curve() { return m_curve.get(); } + Vector<float>* curve() const { return m_curve.get(); }; void setOversample(OverSampleType); OverSampleType oversample() const { return m_oversample; } private: // m_curve represents the non-linear shaping curve. - CrossThreadPersistent<DOMFloat32Array> m_curve; + std::unique_ptr<Vector<float>> m_curve; OverSampleType m_oversample; };
diff --git a/third_party/WebKit/Source/modules/webdatabase/Database.cpp b/third_party/WebKit/Source/modules/webdatabase/Database.cpp index 4f1d7054..9895ccdf 100644 --- a/third_party/WebKit/Source/modules/webdatabase/Database.cpp +++ b/third_party/WebKit/Source/modules/webdatabase/Database.cpp
@@ -46,9 +46,9 @@ #include "modules/webdatabase/SQLTransactionClient.h" #include "modules/webdatabase/SQLTransactionCoordinator.h" #include "modules/webdatabase/SQLTransactionErrorCallback.h" +#include "modules/webdatabase/StorageLog.h" #include "modules/webdatabase/sqlite/SQLiteStatement.h" #include "modules/webdatabase/sqlite/SQLiteTransaction.h" -#include "platform/Logging.h" #include "platform/heap/SafePoint.h" #include "public/platform/Platform.h" #include "public/platform/WebDatabaseObserver.h" @@ -333,7 +333,7 @@ if (transaction && getDatabaseContext()->databaseThreadAvailable()) { std::unique_ptr<DatabaseTransactionTask> task = DatabaseTransactionTask::create(transaction); - WTF_LOG(StorageAPI, "Scheduling DatabaseTransactionTask %p for transaction %p\n", task.get(), task->transaction()); + STORAGE_DVLOG(1) << "Scheduling DatabaseTransactionTask " << task.get() << " for transaction " << task->transaction(); m_transactionInProgress = true; getDatabaseContext()->databaseThread()->scheduleTask(std::move(task)); } else { @@ -347,7 +347,7 @@ return; std::unique_ptr<DatabaseTransactionTask> task = DatabaseTransactionTask::create(transaction); - WTF_LOG(StorageAPI, "Scheduling DatabaseTransactionTask %p for the transaction step\n", task.get()); + STORAGE_DVLOG(1) << "Scheduling DatabaseTransactionTask " << task.get() << " for the transaction step"; getDatabaseContext()->databaseThread()->scheduleTask(std::move(task)); } @@ -445,7 +445,7 @@ if (entry != guidToVersionMap().end()) { // Map null string to empty string (see updateGuidVersionMap()). currentVersion = entry->value.isNull() ? emptyString() : entry->value.isolatedCopy(); - WTF_LOG(StorageAPI, "Current cached version for guid %i is %s", m_guid, currentVersion.ascii().data()); + STORAGE_DVLOG(1) << "Current cached version for guid " << m_guid << " is " << currentVersion; // Note: In multi-process browsers the cached value may be // inaccurate, but we cannot read the actual version from the @@ -463,7 +463,7 @@ } m_sqliteDatabase.setBusyTimeout(maxSqliteBusyWaitTime); } else { - WTF_LOG(StorageAPI, "No cached version for guid %i", m_guid); + STORAGE_DVLOG(1) << "No cached version for guid " << m_guid; SQLiteTransaction transaction(m_sqliteDatabase); transaction.begin(); @@ -494,9 +494,9 @@ } if (currentVersion.length()) { - WTF_LOG(StorageAPI, "Retrieved current version %s from database %s", currentVersion.ascii().data(), databaseDebugName().ascii().data()); + STORAGE_DVLOG(1) << "Retrieved current version " << currentVersion << " from database " << databaseDebugName(); } else if (!m_new || shouldSetVersionInNewDatabase) { - WTF_LOG(StorageAPI, "Setting version %s in database %s that was just created", m_expectedVersion.ascii().data(), databaseDebugName().ascii().data()); + STORAGE_DVLOG(1) << "Setting version " << m_expectedVersion << " in database " << databaseDebugName() << " that was just created"; if (!setVersionInDatabase(m_expectedVersion, false)) { reportOpenDatabaseResult(5, InvalidStateError, m_sqliteDatabase.lastError(), WTF::monotonicallyIncreasingTime() - callStartTime); errorMessage = formatErrorMessage("unable to open database, failed to write current version", m_sqliteDatabase.lastError(), m_sqliteDatabase.lastErrorMsg()); @@ -512,7 +512,7 @@ } if (currentVersion.isNull()) { - WTF_LOG(StorageAPI, "Database %s does not have its version set", databaseDebugName().ascii().data()); + STORAGE_DVLOG(1) << "Database " << databaseDebugName() << " does not have its version set"; currentVersion = ""; }
diff --git a/third_party/WebKit/Source/modules/webdatabase/DatabaseManager.cpp b/third_party/WebKit/Source/modules/webdatabase/DatabaseManager.cpp index 439d65d..a58beb10 100644 --- a/third_party/WebKit/Source/modules/webdatabase/DatabaseManager.cpp +++ b/third_party/WebKit/Source/modules/webdatabase/DatabaseManager.cpp
@@ -37,7 +37,7 @@ #include "modules/webdatabase/DatabaseContext.h" #include "modules/webdatabase/DatabaseTask.h" #include "modules/webdatabase/DatabaseTracker.h" -#include "platform/Logging.h" +#include "modules/webdatabase/StorageLog.h" #include "platform/weborigin/SecurityOrigin.h" #include "public/platform/WebTraceLocation.h" #include "wtf/PtrUtil.h" @@ -146,8 +146,7 @@ static void logOpenDatabaseError(ExecutionContext* context, const String& name) { - WTF_LOG(StorageAPI, "Database %s for origin %s not allowed to be established", name.ascii().data(), - context->getSecurityOrigin()->toString().ascii().data()); + STORAGE_DVLOG(1) << "Database " << name << " for origin " << context->getSecurityOrigin()->toString() << " not allowed to be established"; } Database* DatabaseManager::openDatabaseInternal(ExecutionContext* context, @@ -196,7 +195,7 @@ DatabaseClient::from(context)->didOpenDatabase(database, context->getSecurityOrigin()->host(), name, expectedVersion); if (database->isNew() && creationCallback) { - WTF_LOG(StorageAPI, "Scheduling DatabaseCreationCallbackTask for database %p\n", database); + STORAGE_DVLOG(1) << "Scheduling DatabaseCreationCallbackTask for database " << database; database->getExecutionContext()->postTask(BLINK_FROM_HERE, createSameThreadTask(&databaseCallbackHandleEvent, wrapPersistent(creationCallback), wrapPersistent(database)), "openDatabase"); }
diff --git a/third_party/WebKit/Source/modules/webdatabase/DatabaseTask.cpp b/third_party/WebKit/Source/modules/webdatabase/DatabaseTask.cpp index e7710a7..553fc52 100644 --- a/third_party/WebKit/Source/modules/webdatabase/DatabaseTask.cpp +++ b/third_party/WebKit/Source/modules/webdatabase/DatabaseTask.cpp
@@ -31,7 +31,7 @@ #include "modules/webdatabase/Database.h" #include "modules/webdatabase/DatabaseContext.h" #include "modules/webdatabase/DatabaseThread.h" -#include "platform/Logging.h" +#include "modules/webdatabase/StorageLog.h" namespace blink { @@ -65,9 +65,9 @@ #endif return; } - - WTF_LOG(StorageAPI, "Performing %s %p\n", debugTaskName(), this); - +#if DCHECK_IS_ON() + STORAGE_DVLOG(1) << "Performing " << debugTaskName() << " " << this; +#endif m_database->resetAuthorizer(); doPerformTask(); @@ -100,7 +100,7 @@ m_errorMessage = errorMessage.isolatedCopy(); } -#if !LOG_DISABLED +#if DCHECK_IS_ON() const char* Database::DatabaseOpenTask::debugTaskName() const { return "DatabaseOpenTask"; @@ -120,7 +120,7 @@ database()->close(); } -#if !LOG_DISABLED +#if DCHECK_IS_ON() const char* Database::DatabaseCloseTask::debugTaskName() const { return "DatabaseCloseTask"; @@ -158,7 +158,7 @@ m_transaction->notifyDatabaseThreadIsShuttingDown(); } -#if !LOG_DISABLED +#if DCHECK_IS_ON() const char* Database::DatabaseTransactionTask::debugTaskName() const { return "DatabaseTransactionTask"; @@ -180,7 +180,7 @@ m_tableNames = database()->performGetTableNames(); } -#if !LOG_DISABLED +#if DCHECK_IS_ON() const char* Database::DatabaseTableNamesTask::debugTaskName() const { return "DatabaseTableNamesTask";
diff --git a/third_party/WebKit/Source/modules/webdatabase/DatabaseTask.h b/third_party/WebKit/Source/modules/webdatabase/DatabaseTask.h index 6102d48..39d071d 100644 --- a/third_party/WebKit/Source/modules/webdatabase/DatabaseTask.h +++ b/third_party/WebKit/Source/modules/webdatabase/DatabaseTask.h
@@ -65,7 +65,7 @@ CrossThreadPersistent<Database> m_database; TaskSynchronizer* m_synchronizer; -#if !LOG_DISABLED +#if DCHECK_IS_ON() virtual const char* debugTaskName() const = 0; bool m_complete; #endif @@ -82,7 +82,7 @@ DatabaseOpenTask(Database*, bool setVersionInNewDatabase, TaskSynchronizer*, DatabaseError&, String& errorMessage, bool& success); void doPerformTask() override; -#if !LOG_DISABLED +#if DCHECK_IS_ON() const char* debugTaskName() const override; #endif @@ -103,7 +103,7 @@ DatabaseCloseTask(Database*, TaskSynchronizer*); void doPerformTask() override; -#if !LOG_DISABLED +#if DCHECK_IS_ON() const char* debugTaskName() const override; #endif }; @@ -125,7 +125,7 @@ void doPerformTask() override; void taskCancelled() override; -#if !LOG_DISABLED +#if DCHECK_IS_ON() const char* debugTaskName() const override; #endif @@ -143,7 +143,7 @@ DatabaseTableNamesTask(Database*, TaskSynchronizer*, Vector<String>& names); void doPerformTask() override; -#if !LOG_DISABLED +#if DCHECK_IS_ON() const char* debugTaskName() const override; #endif
diff --git a/third_party/WebKit/Source/modules/webdatabase/DatabaseThread.cpp b/third_party/WebKit/Source/modules/webdatabase/DatabaseThread.cpp index c11823d..13a9234c 100644 --- a/third_party/WebKit/Source/modules/webdatabase/DatabaseThread.cpp +++ b/third_party/WebKit/Source/modules/webdatabase/DatabaseThread.cpp
@@ -32,8 +32,8 @@ #include "modules/webdatabase/DatabaseTask.h" #include "modules/webdatabase/SQLTransactionClient.h" #include "modules/webdatabase/SQLTransactionCoordinator.h" +#include "modules/webdatabase/StorageLog.h" #include "platform/CrossThreadFunctional.h" -#include "platform/Logging.h" #include "platform/WebThreadSupportingGC.h" #include "public/platform/Platform.h" #include "wtf/PtrUtil.h" @@ -83,7 +83,7 @@ ASSERT(!m_terminationRequested); m_terminationRequested = true; m_cleanupSync = &sync; - WTF_LOG(StorageAPI, "DatabaseThread %p was asked to terminate\n", this); + STORAGE_DVLOG(1) << "DatabaseThread " << this << " was asked to terminate"; m_thread->postTask(BLINK_FROM_HERE, crossThreadBind(&DatabaseThread::cleanupDatabaseThread, wrapCrossThreadPersistent(this))); } sync.waitForTaskCompletion(); @@ -97,7 +97,7 @@ { DCHECK(isDatabaseThread()); - WTF_LOG(StorageAPI, "Cleaning up DatabaseThread %p", this); + STORAGE_DVLOG(1) << "Cleaning up DatabaseThread " << this; // Clean up the list of all pending transactions on this database thread m_transactionCoordinator->shutdown();
diff --git a/third_party/WebKit/Source/modules/webdatabase/InspectorDatabaseAgent.cpp b/third_party/WebKit/Source/modules/webdatabase/InspectorDatabaseAgent.cpp index 11d5dd6..cc2cfea 100644 --- a/third_party/WebKit/Source/modules/webdatabase/InspectorDatabaseAgent.cpp +++ b/third_party/WebKit/Source/modules/webdatabase/InspectorDatabaseAgent.cpp
@@ -46,7 +46,6 @@ #include "modules/webdatabase/SQLTransactionCallback.h" #include "modules/webdatabase/SQLTransactionErrorCallback.h" #include "modules/webdatabase/sqlite/SQLValue.h" -#include "platform/inspector_protocol/Values.h" #include "wtf/RefCounted.h" #include "wtf/Vector.h"
diff --git a/third_party/WebKit/Source/modules/webdatabase/SQLStatement.cpp b/third_party/WebKit/Source/modules/webdatabase/SQLStatement.cpp index e683a3c..52d4fce 100644 --- a/third_party/WebKit/Source/modules/webdatabase/SQLStatement.cpp +++ b/third_party/WebKit/Source/modules/webdatabase/SQLStatement.cpp
@@ -38,7 +38,6 @@ #include "modules/webdatabase/SQLTransaction.h" #include "modules/webdatabase/sqlite/SQLiteDatabase.h" #include "modules/webdatabase/sqlite/SQLiteStatement.h" -#include "platform/Logging.h" #include "wtf/text/CString.h" namespace blink {
diff --git a/third_party/WebKit/Source/modules/webdatabase/SQLStatementBackend.cpp b/third_party/WebKit/Source/modules/webdatabase/SQLStatementBackend.cpp index 84eb962..66cb18e 100644 --- a/third_party/WebKit/Source/modules/webdatabase/SQLStatementBackend.cpp +++ b/third_party/WebKit/Source/modules/webdatabase/SQLStatementBackend.cpp
@@ -31,9 +31,9 @@ #include "modules/webdatabase/Database.h" #include "modules/webdatabase/SQLError.h" #include "modules/webdatabase/SQLStatement.h" +#include "modules/webdatabase/StorageLog.h" #include "modules/webdatabase/sqlite/SQLiteDatabase.h" #include "modules/webdatabase/sqlite/SQLiteStatement.h" -#include "platform/Logging.h" #include "wtf/text/CString.h" @@ -133,7 +133,7 @@ int result = statement.prepare(); if (result != SQLResultOk) { - WTF_LOG(StorageAPI, "Unable to verify correctness of statement %s - error %i (%s)", m_statement.ascii().data(), result, database->lastErrorMsg()); + STORAGE_DVLOG(1) << "Unable to verify correctness of statement " << m_statement << " - error " << result << " (" << database->lastErrorMsg() << ")"; if (result == SQLResultInterrupt) m_error = SQLErrorData::create(SQLError::kDatabaseErr, "could not prepare statement", result, "interrupted"); else @@ -145,7 +145,7 @@ // FIXME: If the statement uses the ?### syntax supported by sqlite, the bind parameter count is very likely off from the number of question marks. // If this is the case, they might be trying to do something fishy or malicious if (statement.bindParameterCount() != m_arguments.size()) { - WTF_LOG(StorageAPI, "Bind parameter count doesn't match number of question marks"); + STORAGE_DVLOG(1) << "Bind parameter count doesn't match number of question marks"; m_error = SQLErrorData::create(SQLError::kSyntaxErr, "number of '?'s in statement string does not match argument count"); db->reportExecuteStatementResult(2, m_error->code(), 0); return false; @@ -159,7 +159,7 @@ } if (result != SQLResultOk) { - WTF_LOG(StorageAPI, "Failed to bind value index %i to statement for query '%s'", i + 1, m_statement.ascii().data()); + STORAGE_DVLOG(1) << "Failed to bind value index " << (i + 1) << " to statement for query " << m_statement; db->reportExecuteStatementResult(3, SQLError::kDatabaseErr, result); m_error = SQLErrorData::create(SQLError::kDatabaseErr, "could not bind value", result, database->lastErrorMsg()); return false;
diff --git a/third_party/WebKit/Source/modules/webdatabase/SQLTransaction.cpp b/third_party/WebKit/Source/modules/webdatabase/SQLTransaction.cpp index 603940a..d83a4cd 100644 --- a/third_party/WebKit/Source/modules/webdatabase/SQLTransaction.cpp +++ b/third_party/WebKit/Source/modules/webdatabase/SQLTransaction.cpp
@@ -43,7 +43,7 @@ #include "modules/webdatabase/SQLTransactionCallback.h" #include "modules/webdatabase/SQLTransactionClient.h" // FIXME: Should be used in the backend only. #include "modules/webdatabase/SQLTransactionErrorCallback.h" -#include "platform/Logging.h" +#include "modules/webdatabase/StorageLog.h" #include "wtf/StdLibExtras.h" #include "wtf/Vector.h" @@ -133,7 +133,9 @@ // modify is m_requestedState which is meant for this purpose. void SQLTransaction::requestTransitToState(SQLTransactionState nextState) { - WTF_LOG(StorageAPI, "Scheduling %s for transaction %p\n", nameForSQLTransactionState(nextState), this); +#if DCHECK_IS_ON() + STORAGE_DVLOG(1) << "Scheduling " << nameForSQLTransactionState(nextState) << " for transaction " << this; +#endif m_requestedState = nextState; m_database->scheduleTransactionCallback(this); } @@ -321,8 +323,9 @@ || m_nextState == SQLTransactionState::DeliverStatementCallback || m_nextState == SQLTransactionState::DeliverQuotaIncreaseCallback || m_nextState == SQLTransactionState::DeliverSuccessCallback); - - WTF_LOG(StorageAPI, "Callback %s\n", nameForSQLTransactionState(m_nextState)); +#if DCHECK_IS_ON() + STORAGE_DVLOG(1) << "Callback " << nameForSQLTransactionState(m_nextState); +#endif return false; }
diff --git a/third_party/WebKit/Source/modules/webdatabase/SQLTransactionBackend.cpp b/third_party/WebKit/Source/modules/webdatabase/SQLTransactionBackend.cpp index 37c24f2b..cd92b78 100644 --- a/third_party/WebKit/Source/modules/webdatabase/SQLTransactionBackend.cpp +++ b/third_party/WebKit/Source/modules/webdatabase/SQLTransactionBackend.cpp
@@ -38,9 +38,9 @@ #include "modules/webdatabase/SQLTransaction.h" #include "modules/webdatabase/SQLTransactionClient.h" #include "modules/webdatabase/SQLTransactionCoordinator.h" +#include "modules/webdatabase/StorageLog.h" #include "modules/webdatabase/sqlite/SQLValue.h" #include "modules/webdatabase/sqlite/SQLiteTransaction.h" -#include "platform/Logging.h" #include "wtf/PtrUtil.h" #include "wtf/StdLibExtras.h" #include <memory> @@ -485,8 +485,9 @@ || m_nextState == SQLTransactionState::PostflightAndCommit || m_nextState == SQLTransactionState::CleanupAndTerminate || m_nextState == SQLTransactionState::CleanupAfterTransactionErrorCallback); - - WTF_LOG(StorageAPI, "State %s\n", nameForSQLTransactionState(m_nextState)); +#if DCHECK_IS_ON() + STORAGE_DVLOG(1) << "State " << nameForSQLTransactionState(m_nextState); +#endif return; } @@ -496,7 +497,7 @@ m_nextState = SQLTransactionState::End; // If the database was stopped, don't do anything and cancel queued work - WTF_LOG(StorageAPI, "Database was stopped or interrupted - cancelling work for this transaction"); + STORAGE_DVLOG(1) << "Database was stopped or interrupted - cancelling work for this transaction"; // The current SQLite transaction should be stopped, as well if (m_sqliteTransaction) { @@ -556,7 +557,7 @@ ASSERT(!m_database->sqliteDatabase().transactionInProgress()); ASSERT(m_lockAcquired); - WTF_LOG(StorageAPI, "Opening and preflighting transaction %p", this); + STORAGE_DVLOG(1) << "Opening and preflighting transaction " << this; // Set the maximum usage for this transaction if this transactions is not read-only if (!m_readOnly) @@ -763,7 +764,7 @@ ASSERT(m_lockAcquired); // Spec 4.3.2.9: End transaction steps. There is no next step. - WTF_LOG(StorageAPI, "Transaction %p is complete\n", this); + STORAGE_DVLOG(1) << "Transaction " << this << " is complete"; ASSERT(!m_database->sqliteDatabase().transactionInProgress()); // Phase 5 cleanup. See comment on the SQLTransaction life-cycle above. @@ -787,7 +788,7 @@ { ASSERT(m_lockAcquired); - WTF_LOG(StorageAPI, "Transaction %p is complete with an error\n", this); + STORAGE_DVLOG(1) << "Transaction " << this << " is complete with an error"; m_database->disableAuthorizer(); if (m_sqliteTransaction) { // Spec 4.3.2.10: Rollback the transaction. @@ -808,7 +809,9 @@ // modify is m_requestedState which is meant for this purpose. void SQLTransactionBackend::requestTransitToState(SQLTransactionState nextState) { - WTF_LOG(StorageAPI, "Scheduling %s for transaction %p\n", nameForSQLTransactionState(nextState), this); +#if DCHECK_IS_ON() + STORAGE_DVLOG(1) << "Scheduling " << nameForSQLTransactionState(nextState) << " for transaction " << this; +#endif m_requestedState = nextState; ASSERT(m_requestedState != SQLTransactionState::End); m_database->scheduleTransactionStep(this);
diff --git a/third_party/WebKit/Source/modules/webdatabase/SQLTransactionStateMachine.cpp b/third_party/WebKit/Source/modules/webdatabase/SQLTransactionStateMachine.cpp index 7f1de76..a50f1d4 100644 --- a/third_party/WebKit/Source/modules/webdatabase/SQLTransactionStateMachine.cpp +++ b/third_party/WebKit/Source/modules/webdatabase/SQLTransactionStateMachine.cpp
@@ -25,12 +25,11 @@ #include "modules/webdatabase/SQLTransactionStateMachine.h" -#include "platform/Logging.h" #include "wtf/Assertions.h" namespace blink { -#if !LOG_DISABLED +#if DCHECK_IS_ON() const char* nameForSQLTransactionState(SQLTransactionState state) { switch (state) {
diff --git a/third_party/WebKit/Source/modules/webdatabase/SQLTransactionStateMachine.h b/third_party/WebKit/Source/modules/webdatabase/SQLTransactionStateMachine.h index de32e14..12492f0 100644 --- a/third_party/WebKit/Source/modules/webdatabase/SQLTransactionStateMachine.h +++ b/third_party/WebKit/Source/modules/webdatabase/SQLTransactionStateMachine.h
@@ -59,7 +59,7 @@ #endif }; -#if !LOG_DISABLED +#if DCHECK_IS_ON() extern const char* nameForSQLTransactionState(SQLTransactionState); #endif
diff --git a/third_party/WebKit/Source/modules/webdatabase/StorageLog.h b/third_party/WebKit/Source/modules/webdatabase/StorageLog.h new file mode 100644 index 0000000..5f0906f --- /dev/null +++ b/third_party/WebKit/Source/modules/webdatabase/StorageLog.h
@@ -0,0 +1,18 @@ +// Copyright 2016 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 StorageLog_h +#define StorageLog_h + +#include "wtf/Assertions.h" + +#if DCHECK_IS_ON() +// We can see logs with |--v=N| or |--vmodule=StorageLog=N| where N is a +// verbose level. +#define STORAGE_DVLOG(verbose_level) LAZY_STREAM(VLOG_STREAM(verbose_level), ((verbose_level) <= ::logging::GetVlogLevel("StorageLog.h"))) +#else +#define STORAGE_DVLOG(verbose_level) EAT_STREAM_PARAMETERS +#endif + +#endif // StorageLog_h
diff --git a/third_party/WebKit/Source/modules/webdatabase/sqlite/SQLLog.h b/third_party/WebKit/Source/modules/webdatabase/sqlite/SQLLog.h new file mode 100644 index 0000000..b42fc94 --- /dev/null +++ b/third_party/WebKit/Source/modules/webdatabase/sqlite/SQLLog.h
@@ -0,0 +1,18 @@ +// Copyright 2016 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 SQLLog_h +#define SQLLog_h + +#include "wtf/Assertions.h" + +#if DCHECK_IS_ON() +// We can see logs with |--v=N| or |--vmodule=SQLLog=N| where N is a +// verbose level. +#define SQL_DVLOG(verbose_level) LAZY_STREAM(VLOG_STREAM(verbose_level), ((verbose_level) <= ::logging::GetVlogLevel("SQLLog.h"))) +#else +#define SQL_DVLOG(verbose_level) EAT_STREAM_PARAMETERS +#endif + +#endif // SQLLog_h
diff --git a/third_party/WebKit/Source/modules/webdatabase/sqlite/SQLiteDatabase.cpp b/third_party/WebKit/Source/modules/webdatabase/sqlite/SQLiteDatabase.cpp index 9436031..0417713 100644 --- a/third_party/WebKit/Source/modules/webdatabase/sqlite/SQLiteDatabase.cpp +++ b/third_party/WebKit/Source/modules/webdatabase/sqlite/SQLiteDatabase.cpp
@@ -26,7 +26,7 @@ #include "modules/webdatabase/sqlite/SQLiteDatabase.h" -#include "platform/Logging.h" +#include "modules/webdatabase/sqlite/SQLLog.h" #include "modules/webdatabase/sqlite/SQLiteFileSystem.h" #include "modules/webdatabase/sqlite/SQLiteStatement.h" #include "modules/webdatabase/DatabaseAuthorizer.h" @@ -191,7 +191,7 @@ if (m_db) sqlite3_busy_timeout(m_db, ms); else - WTF_LOG(SQLDatabase, "BusyTimeout set on non-open database"); + SQL_DVLOG(1) << "BusyTimeout set on non-open database"; } bool SQLiteDatabase::executeCommand(const String& sql) @@ -214,7 +214,7 @@ int SQLiteDatabase::runVacuumCommand() { if (!executeCommand("VACUUM;")) - WTF_LOG(SQLDatabase, "Unable to vacuum database - %s", lastErrorMsg()); + SQL_DVLOG(1) << "Unable to vacuum database -" << lastErrorMsg(); return lastError(); } @@ -224,7 +224,7 @@ enableAuthorizer(false); if (!executeCommand("PRAGMA incremental_vacuum")) - WTF_LOG(SQLDatabase, "Unable to run incremental vacuum - %s", lastErrorMsg()); + SQL_DVLOG(1) << "Unable to run incremental vacuum - " << lastErrorMsg(); enableAuthorizer(true); return lastError();
diff --git a/third_party/WebKit/Source/modules/webdatabase/sqlite/SQLiteStatement.cpp b/third_party/WebKit/Source/modules/webdatabase/sqlite/SQLiteStatement.cpp index e10bcea..4dd1308 100644 --- a/third_party/WebKit/Source/modules/webdatabase/sqlite/SQLiteStatement.cpp +++ b/third_party/WebKit/Source/modules/webdatabase/sqlite/SQLiteStatement.cpp
@@ -25,8 +25,8 @@ #include "modules/webdatabase/sqlite/SQLiteStatement.h" +#include "modules/webdatabase/sqlite/SQLLog.h" #include "modules/webdatabase/sqlite/SQLValue.h" -#include "platform/Logging.h" #include "platform/heap/SafePoint.h" #include "third_party/sqlite/sqlite3.h" #include "wtf/Assertions.h" @@ -110,7 +110,7 @@ { SafePointScope scope(BlinkGC::HeapPointersOnStack); - WTF_LOG(SQLDatabase, "SQL - prepare - %s", query.data()); + SQL_DVLOG(1) << "SQL - prepare - " << query.data(); // Pass the length of the string including the null character to sqlite3_prepare_v2; // this lets SQLite avoid an extra string copy. @@ -121,7 +121,7 @@ m_statement = *statement; if (error != SQLITE_OK) - WTF_LOG(SQLDatabase, "sqlite3_prepare16 failed (%i)\n%s\n%s", error, query.data(), sqlite3_errmsg(m_database.sqlite3Handle())); + SQL_DVLOG(1) << "sqlite3_prepare16 failed (" << error << ")\n" << query.data() << "\n" << sqlite3_errmsg(m_database.sqlite3Handle()); else if (*tail && **tail) error = SQLITE_ERROR; @@ -143,11 +143,11 @@ // in order to compute properly the lastChanges() return value. m_database.updateLastChangesCount(); - WTF_LOG(SQLDatabase, "SQL - step - %s", m_query.ascii().data()); + SQL_DVLOG(1) << "SQL - step - " << m_query; int error = sqlite3_step(m_statement); if (error != SQLITE_DONE && error != SQLITE_ROW) { - WTF_LOG(SQLDatabase, "sqlite3_step failed (%i)\nQuery - %s\nError - %s", - error, m_query.ascii().data(), sqlite3_errmsg(m_database.sqlite3Handle())); + SQL_DVLOG(1) << "sqlite3_step failed (" << error << " )\nQuery - " + << m_query << "\nError - " << sqlite3_errmsg(m_database.sqlite3Handle()); } return restrictError(error); @@ -160,7 +160,7 @@ #endif if (!m_statement) return SQLITE_OK; - WTF_LOG(SQLDatabase, "SQL - finalize - %s", m_query.ascii().data()); + SQL_DVLOG(1) << "SQL - finalize - " << m_query; int result = sqlite3_finalize(m_statement); m_statement = 0; return restrictError(result);
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp index ec3b4820..5fbbbae 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -28,6 +28,7 @@ #include "bindings/core/v8/ExceptionMessages.h" #include "bindings/core/v8/ExceptionState.h" #include "bindings/core/v8/V8BindingMacros.h" +#include "bindings/modules/v8/HTMLCanvasElementOrOffscreenCanvas.h" #include "bindings/modules/v8/WebGLAny.h" #include "core/dom/DOMArrayBuffer.h" #include "core/dom/DOMTypedArray.h" @@ -514,28 +515,33 @@ Member<WebGLRenderingContextBase> m_context; }; -static void formatWebGLStatusString(const String& glInfo, const String& infostring, String& statusMessage) +static void formatWebGLStatusString(const StringView& glInfo, const StringView& infoString, StringBuilder& builder) { - if (!infostring.isEmpty()) - statusMessage.append(", " + glInfo + " = " + infostring); + if (infoString.isEmpty()) + return; + builder.append(", "); + builder.append(glInfo); + builder.append(" = "); + builder.append(infoString); } static String extractWebGLContextCreationError(const Platform::GraphicsInfo& info) { - String statusMessage("Could not create a WebGL context"); - formatWebGLStatusString("VENDOR", info.vendorId ? String::format("0x%04x", info.vendorId).utf8().data() : "0xffff", statusMessage); - formatWebGLStatusString("DEVICE", info.deviceId ? String::format("0x%04x", info.deviceId).utf8().data() : "0xffff", statusMessage); - formatWebGLStatusString("GL_VENDOR", info.vendorInfo.utf8().data(), statusMessage); - formatWebGLStatusString("GL_RENDERER", info.rendererInfo.utf8().data(), statusMessage); - formatWebGLStatusString("GL_VERSION", info.driverVersion.utf8().data(), statusMessage); - formatWebGLStatusString("Sandboxed", info.sandboxed ? "yes" : "no", statusMessage); - formatWebGLStatusString("Optimus", info.optimus ? "yes" : "no", statusMessage); - formatWebGLStatusString("AMD switchable", info.amdSwitchable ? "yes" : "no", statusMessage); - formatWebGLStatusString("Reset notification strategy", String::format("0x%04x", info.resetNotificationStrategy).utf8().data(), statusMessage); - formatWebGLStatusString("GPU process crash count", String::number(info.processCrashCount).utf8().data(), statusMessage); - formatWebGLStatusString("ErrorMessage", info.errorMessage.utf8().data(), statusMessage); - statusMessage.append('.'); - return statusMessage; + StringBuilder builder; + builder.append("Could not create a WebGL context"); + formatWebGLStatusString("VENDOR", info.vendorId ? String::format("0x%04x", info.vendorId) : "0xffff", builder); + formatWebGLStatusString("DEVICE", info.deviceId ? String::format("0x%04x", info.deviceId) : "0xffff", builder); + formatWebGLStatusString("GL_VENDOR", info.vendorInfo, builder); + formatWebGLStatusString("GL_RENDERER", info.rendererInfo, builder); + formatWebGLStatusString("GL_VERSION", info.driverVersion, builder); + formatWebGLStatusString("Sandboxed", info.sandboxed ? "yes" : "no", builder); + formatWebGLStatusString("Optimus", info.optimus ? "yes" : "no", builder); + formatWebGLStatusString("AMD switchable", info.amdSwitchable ? "yes" : "no", builder); + formatWebGLStatusString("Reset notification strategy", String::format("0x%04x", info.resetNotificationStrategy).utf8().data(), builder); + formatWebGLStatusString("GPU process crash count", String::number(info.processCrashCount), builder); + formatWebGLStatusString("ErrorMessage", info.errorMessage.utf8().data(), builder); + builder.append('.'); + return builder.toString(); } struct ContextProviderCreationInfo { @@ -6496,4 +6502,12 @@ contextGL()->PixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment); } +void WebGLRenderingContextBase::getHTMLOrOffscreenCanvas(HTMLCanvasElementOrOffscreenCanvas& result) const +{ + if (canvas()) + result.setHTMLCanvasElement(canvas()); + else + result.setOffscreenCanvas(getOffscreenCanvas()); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h index 40b9d7a..354141e7 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.h
@@ -72,6 +72,7 @@ class EXTsRGB; class EXTTextureFilterAnisotropic; class ExceptionState; +class HTMLCanvasElementOrOffscreenCanvas; class HTMLImageElement; class HTMLVideoElement; class ImageBitmap; @@ -413,6 +414,8 @@ void setFilterQuality(SkFilterQuality) override; bool isWebGL2OrHigher() { return version() >= 2; } + void getHTMLOrOffscreenCanvas(HTMLCanvasElementOrOffscreenCanvas&) const; + protected: friend class EXTDisjointTimerQuery; friend class WebGLDrawBuffers;
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.idl b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.idl index 7f1e949..9e24021 100644 --- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.idl +++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.idl
@@ -47,7 +47,7 @@ NoInterfaceObject, // Always used on target of 'implements' ] interface WebGLRenderingContextBase { - readonly attribute HTMLCanvasElement canvas; + [ImplementedAs=getHTMLOrOffscreenCanvas] readonly attribute (HTMLCanvasElement or OffscreenCanvas) canvas; /* ClearBufferMask */ const GLenum DEPTH_BUFFER_BIT = 0x00000100;
diff --git a/third_party/WebKit/Source/modules/webmidi/MIDIAccessInitializer.cpp b/third_party/WebKit/Source/modules/webmidi/MIDIAccessInitializer.cpp index dfd0837..336069cdad 100644 --- a/third_party/WebKit/Source/modules/webmidi/MIDIAccessInitializer.cpp +++ b/third_party/WebKit/Source/modules/webmidi/MIDIAccessInitializer.cpp
@@ -57,7 +57,7 @@ permissions[1] = PermissionName::MIDI_SYSEX; m_permissionService->RequestPermissions( - mojo::WTFArray<PermissionName>(std::move(permissions)), + permissions, getExecutionContext()->getSecurityOrigin()->toString(), UserGestureIndicator::processingUserGesture(), convertToBaseCallback(WTF::bind(&MIDIAccessInitializer::onPermissionsUpdated, wrapPersistent(this)))); @@ -123,10 +123,10 @@ return getScriptState()->getExecutionContext(); } -void MIDIAccessInitializer::onPermissionsUpdated(mojo::WTFArray<PermissionStatus> statusArray) +void MIDIAccessInitializer::onPermissionsUpdated(const Vector<PermissionStatus>& statusArray) { bool allowed = true; - for (const auto status : statusArray.storage()) { + for (const auto status : statusArray) { if (status != PermissionStatus::GRANTED) { allowed = false; break;
diff --git a/third_party/WebKit/Source/modules/webmidi/MIDIAccessInitializer.h b/third_party/WebKit/Source/modules/webmidi/MIDIAccessInitializer.h index 9bb871dc..5d67aaa6 100644 --- a/third_party/WebKit/Source/modules/webmidi/MIDIAccessInitializer.h +++ b/third_party/WebKit/Source/modules/webmidi/MIDIAccessInitializer.h
@@ -71,7 +71,7 @@ void contextDestroyed() override; - void onPermissionsUpdated(mojo::WTFArray<mojom::blink::PermissionStatus>); + void onPermissionsUpdated(const Vector<mojom::blink::PermissionStatus>&); void onPermissionUpdated(mojom::blink::PermissionStatus); std::unique_ptr<MIDIAccessor> m_accessor;
diff --git a/third_party/WebKit/Source/modules/webshare/NavigatorShare.cpp b/third_party/WebKit/Source/modules/webshare/NavigatorShare.cpp index 87fa7f0..6fb373c 100644 --- a/third_party/WebKit/Source/modules/webshare/NavigatorShare.cpp +++ b/third_party/WebKit/Source/modules/webshare/NavigatorShare.cpp
@@ -9,6 +9,7 @@ #include "core/dom/ExceptionCode.h" #include "core/frame/LocalFrame.h" #include "core/frame/Navigator.h" +#include "core/frame/UseCounter.h" #include "modules/webshare/ShareData.h" #include "platform/UserGestureIndicator.h" #include "platform/mojo/MojoHelper.h" @@ -82,14 +83,16 @@ ScriptPromise NavigatorShare::share(ScriptState* scriptState, const ShareData& shareData) { + Document* doc = toDocument(scriptState->getExecutionContext()); + DCHECK(doc); + UseCounter::count(*doc, UseCounter::WebShareShare); + if (!UserGestureIndicator::utilizeUserGesture()) { DOMException* error = DOMException::create(SecurityError, "Must be handling a user gesture to perform a share request."); return ScriptPromise::rejectWithDOMException(scriptState, error); } if (!m_service) { - Document* doc = toDocument(scriptState->getExecutionContext()); - DCHECK(doc); LocalFrame* frame = doc->frame(); DCHECK(frame); frame->interfaceProvider()->getInterface(mojo::GetProxy(&m_service));
diff --git a/third_party/WebKit/Source/modules/websockets/DOMWebSocket.cpp b/third_party/WebKit/Source/modules/websockets/DOMWebSocket.cpp index ee55c5bbc..0c2b631 100644 --- a/third_party/WebKit/Source/modules/websockets/DOMWebSocket.cpp +++ b/third_party/WebKit/Source/modules/websockets/DOMWebSocket.cpp
@@ -49,8 +49,8 @@ #include "core/inspector/ConsoleMessage.h" #include "modules/websockets/CloseEvent.h" #include "platform/Histogram.h" -#include "platform/Logging.h" #include "platform/blob/BlobData.h" +#include "platform/network/NetworkLog.h" #include "platform/weborigin/KnownPorts.h" #include "platform/weborigin/SecurityOrigin.h" #include "public/platform/Platform.h" @@ -284,7 +284,7 @@ { UseCounter::count(getExecutionContext(), UseCounter::WebSocket); - WTF_LOG(Network, "WebSocket %p connect() url='%s'", this, url.utf8().data()); + NETWORK_DVLOG(1) << "WebSocket " << this << " connect() url=" << url; m_url = KURL(KURL(), url); if (getExecutionContext()->securityContext().getInsecureRequestPolicy() & kUpgradeInsecureRequests && m_url.protocol() == "ws") { @@ -370,7 +370,7 @@ ASSERT(m_bufferedAmount >= m_consumedBufferedAmount); // Cast to unsigned long long is required since clang doesn't accept // combination of %llu and uint64_t (known as unsigned long). - WTF_LOG(Network, "WebSocket %p reflectBufferedAmountConsumption() %llu => %llu", this, static_cast<unsigned long long>(m_bufferedAmount), static_cast<unsigned long long>(m_bufferedAmount - m_consumedBufferedAmount)); + NETWORK_DVLOG(1) << "WebSocket " << this << " reflectBufferedAmountConsumption() " << m_bufferedAmount << " => " << (m_bufferedAmount - m_consumedBufferedAmount); m_bufferedAmount -= m_consumedBufferedAmount; m_consumedBufferedAmount = 0; @@ -394,7 +394,7 @@ { CString encodedMessage = message.utf8(); - WTF_LOG(Network, "WebSocket %p send() Sending String '%s'", this, encodedMessage.data()); + NETWORK_DVLOG(1) << "WebSocket " << this << " send() Sending String " << message; if (m_state == kConnecting) { setInvalidStateErrorForSendMethod(exceptionState); return; @@ -414,7 +414,7 @@ void DOMWebSocket::send(DOMArrayBuffer* binaryData, ExceptionState& exceptionState) { - WTF_LOG(Network, "WebSocket %p send() Sending ArrayBuffer %p", this, binaryData); + NETWORK_DVLOG(1) << "WebSocket " << this << " send() Sending ArrayBuffer " << binaryData; ASSERT(binaryData && binaryData->buffer()); if (m_state == kConnecting) { setInvalidStateErrorForSendMethod(exceptionState); @@ -433,7 +433,7 @@ void DOMWebSocket::send(DOMArrayBufferView* arrayBufferView, ExceptionState& exceptionState) { - WTF_LOG(Network, "WebSocket %p send() Sending ArrayBufferView %p", this, arrayBufferView); + NETWORK_DVLOG(1) << "WebSocket " << this << " send() Sending ArrayBufferView " << arrayBufferView; ASSERT(arrayBufferView); if (m_state == kConnecting) { setInvalidStateErrorForSendMethod(exceptionState); @@ -452,7 +452,7 @@ void DOMWebSocket::send(Blob* binaryData, ExceptionState& exceptionState) { - WTF_LOG(Network, "WebSocket %p send() Sending Blob '%s'", this, binaryData->uuid().utf8().data()); + NETWORK_DVLOG(1) << "WebSocket " << this << " send() Sending Blob " << binaryData->uuid(); ASSERT(binaryData); if (m_state == kConnecting) { setInvalidStateErrorForSendMethod(exceptionState); @@ -496,9 +496,9 @@ { String cleansedReason = reason; if (code == WebSocketChannel::CloseEventCodeNotSpecified) { - WTF_LOG(Network, "WebSocket %p close() without code and reason", this); + NETWORK_DVLOG(1) << "WebSocket " << this << " close() without code and reason"; } else { - WTF_LOG(Network, "WebSocket %p close() code=%d reason='%s'", this, code, reason.utf8().data()); + NETWORK_DVLOG(1) << "WebSocket " << this << " close() code=" << code << " reason=" << reason; if (!(code == WebSocketChannel::CloseEventCodeNormalClosure || (WebSocketChannel::CloseEventCodeMinimumUserDefined <= code && code <= WebSocketChannel::CloseEventCodeMaximumUserDefined))) { exceptionState.throwDOMException(InvalidAccessError, "The code must be either 1000, or between 3000 and 4999. " + String::number(code) + " is neither."); return; @@ -604,7 +604,7 @@ void DOMWebSocket::contextDestroyed() { - WTF_LOG(Network, "WebSocket %p contextDestroyed()", this); + NETWORK_DVLOG(1) << "WebSocket " << this << " contextDestroyed()"; DCHECK(!m_channel); DCHECK_EQ(kClosed, m_state); ActiveDOMObject::contextDestroyed(); @@ -640,7 +640,7 @@ void DOMWebSocket::didConnect(const String& subprotocol, const String& extensions) { - WTF_LOG(Network, "WebSocket %p didConnect()", this); + NETWORK_DVLOG(1) << "WebSocket " << this << " didConnect()"; if (m_state != kConnecting) return; m_state = kOpen; @@ -651,7 +651,7 @@ void DOMWebSocket::didReceiveTextMessage(const String& msg) { - WTF_LOG(Network, "WebSocket %p didReceiveTextMessage() Text message '%s'", this, msg.utf8().data()); + NETWORK_DVLOG(1) << "WebSocket " << this << " didReceiveTextMessage() Text message " << msg; if (m_state != kOpen) return; recordReceiveTypeHistogram(WebSocketReceiveTypeString); @@ -661,7 +661,7 @@ void DOMWebSocket::didReceiveBinaryMessage(std::unique_ptr<Vector<char>> binaryData) { - WTF_LOG(Network, "WebSocket %p didReceiveBinaryMessage() %lu byte binary message", this, static_cast<unsigned long>(binaryData->size())); + NETWORK_DVLOG(1) << "WebSocket " << this << " didReceiveBinaryMessage() " << binaryData->size() << " byte binary message"; switch (m_binaryType) { case BinaryTypeBlob: { size_t size = binaryData->size(); @@ -687,7 +687,7 @@ void DOMWebSocket::didError() { - WTF_LOG(Network, "WebSocket %p didError()", this); + NETWORK_DVLOG(1) << "WebSocket " << this << " didError()"; m_state = kClosed; logBinaryTypeChangesAfterOpen(); m_eventQueue->dispatch(Event::create(EventTypeNames::error)); @@ -696,9 +696,7 @@ void DOMWebSocket::didConsumeBufferedAmount(uint64_t consumed) { ASSERT(m_bufferedAmount >= consumed + m_consumedBufferedAmount); - // Cast to unsigned long long is required since clang doesn't accept - // combination of %llu and uint64_t (known as unsigned long). - WTF_LOG(Network, "WebSocket %p didConsumeBufferedAmount(%llu)", this, static_cast<unsigned long long>(consumed)); + NETWORK_DVLOG(1) << "WebSocket " << this << " didConsumeBufferedAmount(" << consumed << ")"; if (m_state == kClosed) return; m_consumedBufferedAmount += consumed; @@ -708,13 +706,13 @@ void DOMWebSocket::didStartClosingHandshake() { - WTF_LOG(Network, "WebSocket %p didStartClosingHandshake()", this); + NETWORK_DVLOG(1) << "WebSocket " << this << " didStartClosingHandshake()"; m_state = kClosing; } void DOMWebSocket::didClose(ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsigned short code, const String& reason) { - WTF_LOG(Network, "WebSocket %p didClose()", this); + NETWORK_DVLOG(1) << "WebSocket " << this << " didClose()"; if (!m_channel) return; bool allDataHasBeenConsumed = m_bufferedAmount == m_consumedBufferedAmount;
diff --git a/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.cpp b/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.cpp index 0f7f935..859fd645 100644 --- a/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.cpp +++ b/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.cpp
@@ -45,7 +45,7 @@ #include "modules/websockets/InspectorWebSocketEvents.h" #include "modules/websockets/WebSocketChannelClient.h" #include "modules/websockets/WebSocketFrame.h" -#include "platform/Logging.h" +#include "platform/network/NetworkLog.h" #include "platform/network/WebSocketHandshakeRequest.h" #include "platform/weborigin/SecurityOrigin.h" #include "public/platform/Platform.h" @@ -153,7 +153,7 @@ bool DocumentWebSocketChannel::connect(const KURL& url, const String& protocol) { - WTF_LOG(Network, "DocumentWebSocketChannel %p connect()", this); + NETWORK_DVLOG(1) << this << " connect()"; if (!m_handle) return false; @@ -192,7 +192,7 @@ void DocumentWebSocketChannel::send(const CString& message) { - WTF_LOG(Network, "DocumentWebSocketChannel %p sendText(%s)", this, message.data()); + NETWORK_DVLOG(1) << this << " sendText(" << message << ")"; // FIXME: Change the inspector API to show the entire message instead // of individual frames. InspectorInstrumentation::didSendWebSocketFrame(document(), m_identifier, WebSocketFrame::OpCodeText, true, message.data(), message.length()); @@ -202,7 +202,7 @@ void DocumentWebSocketChannel::send(PassRefPtr<BlobDataHandle> blobDataHandle) { - WTF_LOG(Network, "DocumentWebSocketChannel %p sendBlob(%s, %s, %llu)", this, blobDataHandle->uuid().utf8().data(), blobDataHandle->type().utf8().data(), blobDataHandle->size()); + NETWORK_DVLOG(1) << this << " sendBlob(" << blobDataHandle->uuid() << ", " << blobDataHandle->type() << ", " << blobDataHandle->size() << ")"; // FIXME: Change the inspector API to show the entire message instead // of individual frames. // FIXME: We can't access the data here. @@ -215,7 +215,7 @@ void DocumentWebSocketChannel::send(const DOMArrayBuffer& buffer, unsigned byteOffset, unsigned byteLength) { - WTF_LOG(Network, "DocumentWebSocketChannel %p sendArrayBuffer(%p, %u, %u)", this, buffer.data(), byteOffset, byteLength); + NETWORK_DVLOG(1) << this << " sendArrayBuffer(" << buffer.data() << ", " << byteOffset << ", " << byteLength << ")"; // FIXME: Change the inspector API to show the entire message instead // of individual frames. InspectorInstrumentation::didSendWebSocketFrame(document(), m_identifier, WebSocketFrame::OpCodeBinary, true, static_cast<const char*>(buffer.data()) + byteOffset, byteLength); @@ -228,7 +228,7 @@ void DocumentWebSocketChannel::sendTextAsCharVector(std::unique_ptr<Vector<char>> data) { - WTF_LOG(Network, "DocumentWebSocketChannel %p sendTextAsCharVector(%p, %llu)", this, data.get(), static_cast<unsigned long long>(data->size())); + NETWORK_DVLOG(1) << this << " sendTextAsCharVector(" << static_cast<void*>(data.get()) << ", " << data->size() << ")"; // FIXME: Change the inspector API to show the entire message instead // of individual frames. InspectorInstrumentation::didSendWebSocketFrame(document(), m_identifier, WebSocketFrame::OpCodeText, true, data->data(), data->size()); @@ -238,7 +238,7 @@ void DocumentWebSocketChannel::sendBinaryAsCharVector(std::unique_ptr<Vector<char>> data) { - WTF_LOG(Network, "DocumentWebSocketChannel %p sendBinaryAsCharVector(%p, %llu)", this, data.get(), static_cast<unsigned long long>(data->size())); + NETWORK_DVLOG(1) << this << " sendBinaryAsCharVector(" << static_cast<void*>(data.get()) << ", " << data->size() << ")"; // FIXME: Change the inspector API to show the entire message instead // of individual frames. InspectorInstrumentation::didSendWebSocketFrame(document(), m_identifier, WebSocketFrame::OpCodeBinary, true, data->data(), data->size()); @@ -248,7 +248,7 @@ void DocumentWebSocketChannel::close(int code, const String& reason) { - WTF_LOG(Network, "DocumentWebSocketChannel %p close(%d, %s)", this, code, reason.utf8().data()); + NETWORK_DVLOG(1) << this << " close(" << code << ", " << reason << ")"; ASSERT(m_handle); unsigned short codeToSend = static_cast<unsigned short>(code == CloseEventCodeNotSpecified ? CloseEventCodeNoStatusRcvd : code); m_messages.append(new Message(codeToSend, reason)); @@ -257,7 +257,7 @@ void DocumentWebSocketChannel::fail(const String& reason, MessageLevel level, std::unique_ptr<SourceLocation> location) { - WTF_LOG(Network, "DocumentWebSocketChannel %p fail(%s)", this, reason.utf8().data()); + NETWORK_DVLOG(1) << this << " fail(" << reason << ")"; // m_handle and m_client can be null here. InspectorInstrumentation::didReceiveWebSocketFrameError(document(), m_identifier, reason); @@ -274,7 +274,7 @@ void DocumentWebSocketChannel::disconnect() { - WTF_LOG(Network, "DocumentWebSocketChannel %p disconnect()", this); + NETWORK_DVLOG(1) << this << " disconnect()"; if (m_identifier) { TRACE_EVENT_INSTANT1("devtools.timeline", "WebSocketDestroy", TRACE_EVENT_SCOPE_THREAD, "data", InspectorWebSocketEvent::data(document(), m_identifier)); InspectorInstrumentation::didCloseWebSocket(document(), m_identifier); @@ -413,7 +413,7 @@ void DocumentWebSocketChannel::didConnect(WebSocketHandle* handle, const WebString& selectedProtocol, const WebString& extensions) { - WTF_LOG(Network, "DocumentWebSocketChannel %p didConnect(%p, %s, %s)", this, handle, selectedProtocol.utf8().c_str(), extensions.utf8().c_str()); + NETWORK_DVLOG(1) << this << " didConnect(" << handle << ", " << String(selectedProtocol) << ", " << String(extensions) << ")"; ASSERT(m_handle); ASSERT(handle == m_handle.get()); @@ -424,7 +424,7 @@ void DocumentWebSocketChannel::didStartOpeningHandshake(WebSocketHandle* handle, const WebSocketHandshakeRequestInfo& request) { - WTF_LOG(Network, "DocumentWebSocketChannel %p didStartOpeningHandshake(%p)", this, handle); + NETWORK_DVLOG(1) << this << " didStartOpeningHandshake(" << handle << ")"; ASSERT(m_handle); ASSERT(handle == m_handle.get()); @@ -436,7 +436,7 @@ void DocumentWebSocketChannel::didFinishOpeningHandshake(WebSocketHandle* handle, const WebSocketHandshakeResponseInfo& response) { - WTF_LOG(Network, "DocumentWebSocketChannel %p didFinishOpeningHandshake(%p)", this, handle); + NETWORK_DVLOG(1) << this << " didFinishOpeningHandshake(" << handle << ")"; ASSERT(m_handle); ASSERT(handle == m_handle.get()); @@ -448,7 +448,7 @@ void DocumentWebSocketChannel::didFail(WebSocketHandle* handle, const WebString& message) { - WTF_LOG(Network, "DocumentWebSocketChannel %p didFail(%p, %s)", this, handle, message.utf8().data()); + NETWORK_DVLOG(1) << this << " didFail(" << handle << ", " << String(message) << ")"; ASSERT(m_handle); ASSERT(handle == m_handle.get()); @@ -462,7 +462,7 @@ void DocumentWebSocketChannel::didReceiveData(WebSocketHandle* handle, bool fin, WebSocketHandle::MessageType type, const char* data, size_t size) { - WTF_LOG(Network, "DocumentWebSocketChannel %p didReceiveData(%p, %d, %d, (%p, %zu))", this, handle, fin, type, data, size); + NETWORK_DVLOG(1) << this << " didReceiveData(" << handle << ", " << fin << ", " << type << ", (" << static_cast<const void*>(data) << ", " << size << "))"; ASSERT(m_handle); ASSERT(handle == m_handle.get()); @@ -513,7 +513,7 @@ void DocumentWebSocketChannel::didClose(WebSocketHandle* handle, bool wasClean, unsigned short code, const WebString& reason) { - WTF_LOG(Network, "DocumentWebSocketChannel %p didClose(%p, %d, %u, %s)", this, handle, wasClean, code, String(reason).utf8().data()); + NETWORK_DVLOG(1) << this << " didClose(" << handle << ", " << wasClean << ", " << code << ", " << String(reason) << ")"; ASSERT(m_handle); ASSERT(handle == m_handle.get()); @@ -532,7 +532,7 @@ void DocumentWebSocketChannel::didReceiveFlowControl(WebSocketHandle* handle, int64_t quota) { - WTF_LOG(Network, "DocumentWebSocketChannel %p didReceiveFlowControl(%p, %ld)", this, handle, static_cast<long>(quota)); + NETWORK_DVLOG(1) << this << " didReceiveFlowControl(" << handle << ", " << quota << ")"; ASSERT(m_handle); ASSERT(handle == m_handle.get()); @@ -544,7 +544,7 @@ void DocumentWebSocketChannel::didStartClosingHandshake(WebSocketHandle* handle) { - WTF_LOG(Network, "DocumentWebSocketChannel %p didStartClosingHandshake(%p)", this, handle); + NETWORK_DVLOG(1) << this << " didStartClosingHandshake(" << handle << ")"; ASSERT(m_handle); ASSERT(handle == m_handle.get()); @@ -585,4 +585,9 @@ ContextLifecycleObserver::trace(visitor); } +std::ostream& operator<<(std::ostream& ostream, const DocumentWebSocketChannel* channel) +{ + return ostream << "DocumentWebSocketChannel " << static_cast<const void*>(channel); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.h b/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.h index 42b53be..f56e613 100644 --- a/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.h +++ b/third_party/WebKit/Source/modules/websockets/DocumentWebSocketChannel.h
@@ -154,6 +154,8 @@ static const uint64_t receivedDataSizeForFlowControlHighWaterMark = 1 << 15; }; +std::ostream& operator<<(std::ostream&, const DocumentWebSocketChannel*); + } // namespace blink #endif // DocumentWebSocketChannel_h
diff --git a/third_party/WebKit/Source/platform/BUILD.gn b/third_party/WebKit/Source/platform/BUILD.gn index ffa75b7..8512b58 100644 --- a/third_party/WebKit/Source/platform/BUILD.gn +++ b/third_party/WebKit/Source/platform/BUILD.gn
@@ -195,16 +195,40 @@ ":inspector_protocol_version", ] sources = [ + "inspector_protocol/Allocator_h.template", + "inspector_protocol/Array_h.template", + "inspector_protocol/BackendCallback_h.template", "inspector_protocol/CodeGenerator.py", + "inspector_protocol/Collections_h.template", + "inspector_protocol/DispatcherBase_cpp.template", + "inspector_protocol/DispatcherBase_h.template", + "inspector_protocol/ErrorSupport_cpp.template", + "inspector_protocol/ErrorSupport_h.template", "inspector_protocol/Exported_h.template", + "inspector_protocol/FrontendChannel_h.template", "inspector_protocol/Imported_h.template", + "inspector_protocol/InspectorProtocol_cpp.template", + "inspector_protocol/Maybe_h.template", + "inspector_protocol/Object_cpp.template", + "inspector_protocol/Object_h.template", + "inspector_protocol/Parser_cpp.template", + "inspector_protocol/Parser_h.template", + "inspector_protocol/Platform_h.template", + "inspector_protocol/String16_cpp.template", + "inspector_protocol/String16_h.template", "inspector_protocol/TypeBuilder_cpp.template", "inspector_protocol/TypeBuilder_h.template", + "inspector_protocol/ValueConversions_h.template", + "inspector_protocol/Values_cpp.template", + "inspector_protocol/Values_h.template", ] inputs = [ "v8_inspector/js_protocol.json", + "v8_inspector/inspector_protocol_config.json", ] outputs = [ + "$blink_platform_output_dir/inspector_protocol/InspectorProtocol.cpp", + "$blink_platform_output_dir/inspector_protocol/InspectorProtocol.h", "$blink_platform_output_dir/v8_inspector/protocol/Console.cpp", "$blink_platform_output_dir/v8_inspector/protocol/Console.h", "$blink_platform_output_dir/v8_inspector/protocol/Debugger.cpp", @@ -220,22 +244,10 @@ ] args = [ - "--protocol", - rebase_path("v8_inspector/js_protocol.json", root_build_dir), - "--string_type", - "String16", - "--export_macro", - "PLATFORM_EXPORT", - "--output_dir", - rebase_path(blink_platform_output_dir + "/v8_inspector/protocol", - root_build_dir), - "--output_package", - "platform/v8_inspector/protocol", - "--exported_dir", - rebase_path(blink_platform_output_dir + "/v8_inspector/public/protocol", - root_build_dir), - "--exported_package", - "platform/v8_inspector/public/protocol", + "--output_base", + rebase_path(blink_platform_output_dir, root_build_dir), + "--config", + rebase_path("v8_inspector/inspector_protocol_config.json", root_build_dir), ] }
diff --git a/third_party/WebKit/Source/platform/LayoutLocaleTest.cpp b/third_party/WebKit/Source/platform/LayoutLocaleTest.cpp index b634c0c..ae75632 100644 --- a/third_party/WebKit/Source/platform/LayoutLocaleTest.cpp +++ b/third_party/WebKit/Source/platform/LayoutLocaleTest.cpp
@@ -4,7 +4,6 @@ #include "platform/LayoutLocale.h" -#include "platform/Logging.h" #include "testing/gtest/include/gtest/gtest.h" namespace blink {
diff --git a/third_party/WebKit/Source/platform/LifecycleObserver.h b/third_party/WebKit/Source/platform/LifecycleObserver.h index f2d31d9..34a491f 100644 --- a/third_party/WebKit/Source/platform/LifecycleObserver.h +++ b/third_party/WebKit/Source/platform/LifecycleObserver.h
@@ -31,11 +31,9 @@ namespace blink { -template<typename T, typename Observer> +template<typename Context, typename Observer> class LifecycleObserver : public GarbageCollectedMixin { public: - using Context = T; - DEFINE_INLINE_VIRTUAL_TRACE() { visitor->trace(m_lifecycleContext); @@ -63,8 +61,8 @@ WeakMember<Context> m_lifecycleContext; }; -template<typename T, typename Observer> -inline void LifecycleObserver<T, Observer>::setContext(Context* context) +template<typename Context, typename Observer> +inline void LifecycleObserver<Context, Observer>::setContext(Context* context) { if (m_lifecycleContext) m_lifecycleContext->removeObserver(static_cast<Observer*>(this));
diff --git a/third_party/WebKit/Source/platform/Logging.cpp b/third_party/WebKit/Source/platform/Logging.cpp index 470ce598..830ffdb 100644 --- a/third_party/WebKit/Source/platform/Logging.cpp +++ b/third_party/WebKit/Source/platform/Logging.cpp
@@ -31,28 +31,8 @@ namespace blink { -WTFLogChannel LogNetwork = { WTFLogChannelOff }; -WTFLogChannel LogResourceLoading = { WTFLogChannelOff }; -WTFLogChannel LogSQLDatabase = { WTFLogChannelOff }; -WTFLogChannel LogStorageAPI = { WTFLogChannelOff }; - WTFLogChannel* getChannelFromName(const String& channelName) { - if (!(channelName.length() >= 2)) - return 0; - - if (equalIgnoringCase(channelName, String("Network"))) - return &LogNetwork; - - if (equalIgnoringCase(channelName, String("ResourceLoading"))) - return &LogResourceLoading; - - if (equalIgnoringCase(channelName, String("SQLDatabase"))) - return &LogSQLDatabase; - - if (equalIgnoringCase(channelName, String("StorageAPI"))) - return &LogStorageAPI; - return 0; }
diff --git a/third_party/WebKit/Source/platform/Logging.h b/third_party/WebKit/Source/platform/Logging.h index b8243d9b..0216bed 100644 --- a/third_party/WebKit/Source/platform/Logging.h +++ b/third_party/WebKit/Source/platform/Logging.h
@@ -26,6 +26,8 @@ #ifndef Logging_h #define Logging_h +// This is deprecated. We'll remove this soon. + #include "platform/PlatformExport.h" #include "wtf/Assertions.h" #include "wtf/Forward.h" @@ -38,12 +40,6 @@ namespace blink { -// WTFLogChannel is deprecated. Do not add new channels. -PLATFORM_EXPORT extern WTFLogChannel LogNetwork; -PLATFORM_EXPORT extern WTFLogChannel LogResourceLoading; -PLATFORM_EXPORT extern WTFLogChannel LogSQLDatabase; -PLATFORM_EXPORT extern WTFLogChannel LogStorageAPI; - PLATFORM_EXPORT WTFLogChannel* getChannelFromName(const String& channelName); }
diff --git a/third_party/WebKit/Source/platform/PODIntervalTreeTest.cpp b/third_party/WebKit/Source/platform/PODIntervalTreeTest.cpp index 0cc3fa8..5b27042e 100644 --- a/third_party/WebKit/Source/platform/PODIntervalTreeTest.cpp +++ b/third_party/WebKit/Source/platform/PODIntervalTreeTest.cpp
@@ -27,7 +27,6 @@ #include "platform/PODIntervalTree.h" -#include "platform/Logging.h" #include "platform/testing/TreeTestHelpers.h" #include "testing/gtest/include/gtest/gtest.h" #include "wtf/Vector.h"
diff --git a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in index 0b860b9..23b1dac 100644 --- a/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in +++ b/third_party/WebKit/Source/platform/RuntimeEnabledFeatures.in
@@ -41,6 +41,7 @@ Canvas2dImageChromium status=experimental ClientHints status=stable CompositeOpaqueScrollers +ColorCorrectRendering status=experimental, settable_from_internals=True CompositedSelectionUpdate CompositorWorker status=experimental ContextMenu status=test @@ -92,7 +93,7 @@ FastMobileScrolling FileAPIBlobClose status=experimental FileSystem status=stable -ForeignFetch status=experimental +ForeignFetch status=experimental, origin_trial_feature_name=ForeignFetch FullscreenUnprefixed status=test FrameTimingSupport status=experimental GeometryInterfaces status=test @@ -100,9 +101,7 @@ GlobalCacheStorage status=stable IDBObserver status=experimental ImageCapture status=experimental -ImageColorProfiles ImageOrientation status=test -ImageRenderingPixelated status=stable IndexedDBExperimental status=experimental InertTopControls status=experimental InputEvent status=experimental @@ -113,8 +112,9 @@ LangAttributeAwareFormControlUI LayoutNG LinkPreload status=stable -LinkServiceWorker status=experimental +LinkServiceWorker status=experimental, origin_trial_feature_name=ForeignFetch FractionalScrollOffsets +LoadingWithMojo MediaCapture MediaCaptureFromCanvas status=stable MediaCaptureFromVideo status=experimental
diff --git a/third_party/WebKit/Source/platform/animation/CubicBezierControlPoints.cpp b/third_party/WebKit/Source/platform/animation/CubicBezierControlPoints.cpp deleted file mode 100644 index 05cdeb0..0000000 --- a/third_party/WebKit/Source/platform/animation/CubicBezierControlPoints.cpp +++ /dev/null
@@ -1,216 +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. - -#include "platform/animation/CubicBezierControlPoints.h" - -#include "platform/animation/AnimationUtilities.h" -#include <algorithm> - -namespace blink { - -static inline double square(double x) -{ - return x*x; -} - -// Divide the Bezier curve into two pieces at the given value of t using -// de Casteljau's algorithm. -void CubicBezierControlPoints::divide(double t, CubicBezierControlPoints& left, CubicBezierControlPoints& right) const -{ - double x0A = blend(x0, x1, t); - double y0A = blend(y0, y1, t); - - double x1A = blend(x1, x2, t); - double y1A = blend(y1, y2, t); - - double x2A = blend(x2, x3, t); - double y2A = blend(y2, y3, t); - - double x0B = blend(x0A, x1A, t); - double y0B = blend(y0A, y1A, t); - - double x1B = blend(x1A, x2A, t); - double y1B = blend(y1A, y2A, t); - - double x0C = blend(x0B, x1B, t); - double y0C = blend(y0B, y1B, t); - - left.x0 = x0; - left.y0 = y0; - - left.x1 = x0A; - left.y1 = y0A; - - left.x2 = x0B; - left.y2 = y0B; - - left.x3 = x0C; - left.y3 = y0C; - - right.x0 = x0C; - right.y0 = y0C; - - right.x1 = x1B; - right.y1 = y1B; - - right.x2 = x2A; - right.y2 = y2A; - - right.x3 = x3; - right.y3 = y3; -} - -// Finds a value of t for which d^2y/dt^2 = 0 within the range (0,1). -bool CubicBezierControlPoints::findInflexionPoint(double& solution) const -{ - // Second derivative of the cubic bezier: solving at + b = 0. - double a = 6 * (y3 - 3 * y2 + 3 * y1 - y0); - double b = 6 * (y2 - 2 * y1 + y0); - - if (a != 0) { - double t = -b / a; - - if (t > 0 && t < 1) { - solution = t; - return true; - } - } - - return false; -} - -// Find values of t for which dy/dt = 0 and d^2y/dt^2 != 0 within the -// range (0,1). -size_t CubicBezierControlPoints::findTurningPoints(double& left, double& right) const -{ - // If the control points are strictly increasing/decreasing, there - // can be no stationary points. - if ((y0 < y1 && y1 < y2 && y2 < y3) - || (y0 > y1 && y1 > y2 && y2 > y3)) - return 0; - - // Derivative of the cubic bezier: solving at^2 + bt + c = 0. - double a = -3 * (y0 - 3 * y1 + 3 * y2 - y3); - double b = 6 * (y0 - 2 * y1 + y2); - double c = -3 * (y0 - y1); - - if (std::abs(a) < std::numeric_limits<double>::epsilon() - && std::abs(b) < std::numeric_limits<double>::epsilon()) - return 0; - - if (std::abs(a) < std::numeric_limits<double>::epsilon()) { - left = -c / b; - return 1; - } - - double discriminant = b * b - 4 * a * c; - if (discriminant < 0) - return 0; - - double discriminantSqrt = sqrt(discriminant); - - double solution1 = (-b + discriminantSqrt) / (2 * a); - double solution2 = (-b - discriminantSqrt) / (2 * a); - - // Check if either of the solutions lie in (0,1). - bool solution1Viable = (solution1 > 0) && (solution1 < 1); - bool solution2Viable = (solution2 > 0) && (solution2 < 1); - - // If we find stationary points, ensure they are turning points, - // i.e. they are not a point of inflexion. - double inflexionPoint = 0.0; - - if (findInflexionPoint(inflexionPoint)) { - if (solution1Viable && std::abs(solution1 - inflexionPoint) < std::numeric_limits<double>::epsilon()) - solution1Viable = false; - - if (solution2Viable && std::abs(solution2 - inflexionPoint) < std::numeric_limits<double>::epsilon()) - solution2Viable = false; - } - - if (solution1Viable && solution2Viable) { - if (std::abs(solution1 - solution2) < std::numeric_limits<double>::epsilon()) { - left = solution1; - return 1; - } - - if (solution1 < solution2) { - left = solution1; - right = solution2; - } else { - left = solution2; - right = solution1; - } - return 2; - } - - if (solution1Viable) { - left = solution1; - return 1; - } - - if (solution2Viable) { - left = solution2; - return 1; - } - - return 0; -} - -// Finds the intersection of the cubic bezier with the horizontal line -// y = intersectionY (assuming the curve is monotonically increasing/ -// decreasing). -bool CubicBezierControlPoints::findIntersection(double intersectionY, double& intersectionX) const -{ - // If the last control point lies on the horizontal line, then use - // its x value as the intersection. - // This is done so that if a cubic bezier is divided at a point of - // intersection, we only detect the intersection in leftPoints, - // short-circuiting the return at the end of this method, and - // avoiding finding the intersection again in rightPoints. - if (std::abs(y3 - intersectionY) < std::numeric_limits<double>::epsilon()) { - intersectionX = x3; - return true; - } - - // Ensure there are control points both above and below the - // horizontal line, and thus there is actually a point of - // intersection. - double smallestY = std::min(y0, y3); - double largestY = std::max(y0, y3); - - if (!(smallestY < intersectionY && largestY > intersectionY)) - return false; - - // If the line joining the first and last control points is - // about the same length as the line joining all the control - // points in sequence, then we can treat the bezier as a straight - // line, and just find its intersection with the horizontal line. - double straightDistance = sqrt(square(x0 - x3) + square(y0 - y3)); - double pointsDistance = sqrt(square(x0 - x1) + square(y0 - y1)) - + sqrt(square(x1 - x2) + square(y1 - y2)) - + sqrt(square(x2 - x3) + square(y2 - y3)); - - if (std::abs(straightDistance - pointsDistance) < std::numeric_limits<double>::epsilon()) { - // If the bezier approximates a different horizontal line, - // there'll be no point of intersection. - if (std::abs(y3 - y0) < std::numeric_limits<double>::epsilon()) - return false; - - intersectionX = (intersectionY - y0)*(x3 - x0) / (y3 - y0) + x0; - return true; - } - - // Divide the bezier into two smaller segments, and continue - // searching for intersections in both of them. - CubicBezierControlPoints leftSegment; - CubicBezierControlPoints rightSegment; - - divide(0.5, leftSegment, rightSegment); - - return (leftSegment.findIntersection(intersectionY, intersectionX) - || rightSegment.findIntersection(intersectionY, intersectionX)); -} - -} // namespace blink
diff --git a/third_party/WebKit/Source/platform/animation/CubicBezierControlPoints.h b/third_party/WebKit/Source/platform/animation/CubicBezierControlPoints.h deleted file mode 100644 index e9ae4fe..0000000 --- a/third_party/WebKit/Source/platform/animation/CubicBezierControlPoints.h +++ /dev/null
@@ -1,53 +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. - -#ifndef CubicBezierControlPoints_h -#define CubicBezierControlPoints_h - -#include "wtf/Allocator.h" -#include <cstddef> - -namespace blink { - -struct CubicBezierControlPoints { - DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); - double x0, y0; - double x1, y1; - double x2, y2; - double x3, y3; - - CubicBezierControlPoints() - : x0(0) - , y0(0) - , x1(0) - , y1(0) - , x2(0) - , y2(0) - , x3(0) - , y3(0) - { } - - CubicBezierControlPoints(double x0, double y0, double x1, double y1, - double x2, double y2, double x3, double y3) - : x0(x0) - , y0(y0) - , x1(x1) - , y1(y1) - , x2(x2) - , y2(y2) - , x3(x3) - , y3(y3) - { } - - void divide(double t, CubicBezierControlPoints& left, CubicBezierControlPoints& right) const; - size_t findTurningPoints(double& left, double& right) const; - bool findIntersection(double intersectionY, double& intersectionX) const; - -private: - bool findInflexionPoint(double& solution) const; -}; - -} // namespace blink - -#endif
diff --git a/third_party/WebKit/Source/platform/animation/TimingFunction.cpp b/third_party/WebKit/Source/platform/animation/TimingFunction.cpp index fa8ba56..c13b4ed 100644 --- a/third_party/WebKit/Source/platform/animation/TimingFunction.cpp +++ b/third_party/WebKit/Source/platform/animation/TimingFunction.cpp
@@ -4,8 +4,7 @@ #include "platform/animation/TimingFunction.h" -#include "platform/animation/CubicBezierControlPoints.h" -#include "wtf/MathExtras.h" +#include "wtf/text/StringBuilder.h" namespace blink {
diff --git a/third_party/WebKit/Source/platform/animation/TimingFunction.h b/third_party/WebKit/Source/platform/animation/TimingFunction.h index 10d897a..c792adb0 100644 --- a/third_party/WebKit/Source/platform/animation/TimingFunction.h +++ b/third_party/WebKit/Source/platform/animation/TimingFunction.h
@@ -26,14 +26,11 @@ #define TimingFunction_h #include "cc/animation/timing_function.h" -#include "platform/animation/AnimationUtilities.h" // For blend() -#include "platform/heap/Handle.h" -#include "platform/heap/Heap.h" -#include "ui/gfx/geometry/cubic_bezier.h" +#include "platform/PlatformExport.h" +#include "wtf/Assertions.h" #include "wtf/PassRefPtr.h" #include "wtf/RefCounted.h" #include "wtf/StdLibExtras.h" -#include "wtf/text/StringBuilder.h" #include "wtf/text/WTFString.h" namespace blink {
diff --git a/third_party/WebKit/Source/platform/audio/FFTFrame.cpp b/third_party/WebKit/Source/platform/audio/FFTFrame.cpp index 9e167e8..1cb6f63 100644 --- a/third_party/WebKit/Source/platform/audio/FFTFrame.cpp +++ b/third_party/WebKit/Source/platform/audio/FFTFrame.cpp
@@ -28,7 +28,6 @@ #include "platform/audio/FFTFrame.h" #include "platform/audio/VectorMath.h" -#include "platform/Logging.h" #include "wtf/MathExtras.h" #include "wtf/PtrUtil.h" #include <complex>
diff --git a/third_party/WebKit/Source/platform/blink_platform.gyp b/third_party/WebKit/Source/platform/blink_platform.gyp index 6a88549..f65c5d8 100644 --- a/third_party/WebKit/Source/platform/blink_platform.gyp +++ b/third_party/WebKit/Source/platform/blink_platform.gyp
@@ -207,6 +207,7 @@ '<(blink_platform_output_dir)/RuntimeEnabledFeatures.h', # Additional .cpp files from the protocol_sources list. + '<(blink_platform_output_dir)/inspector_protocol/InspectorProtocol.cpp', '<(blink_platform_output_dir)/v8_inspector/protocol/Console.cpp', '<(blink_platform_output_dir)/v8_inspector/protocol/Debugger.cpp', '<(blink_platform_output_dir)/v8_inspector/protocol/HeapProfiler.cpp',
diff --git a/third_party/WebKit/Source/platform/blink_platform.gypi b/third_party/WebKit/Source/platform/blink_platform.gypi index 681e772..7f4084b 100644 --- a/third_party/WebKit/Source/platform/blink_platform.gypi +++ b/third_party/WebKit/Source/platform/blink_platform.gypi
@@ -175,8 +175,6 @@ 'animation/CompositorTransformKeyframe.h', 'animation/CompositorTransformOperations.cpp', 'animation/CompositorTransformOperations.h', - 'animation/CubicBezierControlPoints.cpp', - 'animation/CubicBezierControlPoints.h', 'animation/TimingFunction.cpp', 'animation/TimingFunction.h', 'audio/AudioArray.h', @@ -845,28 +843,6 @@ 'image-encoders/PNGImageEncoder.h', 'image-encoders/WEBPImageEncoder.cpp', 'image-encoders/WEBPImageEncoder.h', - 'inspector_protocol/Allocator.h', - 'inspector_protocol/Array.h', - 'inspector_protocol/BackendCallback.h', - 'inspector_protocol/Collections.h', - 'inspector_protocol/DispatcherBase.cpp', - 'inspector_protocol/DispatcherBase.h', - 'inspector_protocol/ErrorSupport.cpp', - 'inspector_protocol/ErrorSupport.h', - 'inspector_protocol/Maybe.h', - 'inspector_protocol/Object.cpp', - 'inspector_protocol/Object.h', - 'inspector_protocol/Parser.cpp', - 'inspector_protocol/Parser.h', - 'inspector_protocol/Platform.h', - 'inspector_protocol/PlatformWTF.h', - 'inspector_protocol/FrontendChannel.h', - 'inspector_protocol/String16.h', - 'inspector_protocol/String16WTF.cpp', - 'inspector_protocol/String16WTF.h', - 'inspector_protocol/Values.cpp', - 'inspector_protocol/Values.h', - 'inspector_protocol/ValueConversions.h', 'mac/BlockExceptions.h', 'mac/BlockExceptions.mm', 'mac/ColorMac.h', @@ -916,6 +892,7 @@ 'network/LinkHeader.h', 'network/NetworkHints.cpp', 'network/NetworkHints.h', + 'network/NetworkLog.h', 'network/NetworkUtils.cpp', 'network/NetworkUtils.h', 'network/ParsedContentType.cpp', @@ -1156,9 +1133,11 @@ 'v8_inspector/InspectedContext.h', 'v8_inspector/JavaScriptCallFrame.cpp', 'v8_inspector/JavaScriptCallFrame.h', - 'v8_inspector/ScriptBreakpoint.h', + 'v8_inspector/PlatformWTF.h', 'v8_inspector/RemoteObjectId.cpp', 'v8_inspector/RemoteObjectId.h', + 'v8_inspector/ScriptBreakpoint.h', + 'v8_inspector/String16WTF.h', 'v8_inspector/V8Compat.h', 'v8_inspector/V8ConsoleAgentImpl.cpp', 'v8_inspector/V8ConsoleAgentImpl.h',
diff --git a/third_party/WebKit/Source/platform/exported/WebURLRequest.cpp b/third_party/WebKit/Source/platform/exported/WebURLRequest.cpp index 6c5a96c62..20e9010d 100644 --- a/third_party/WebKit/Source/platform/exported/WebURLRequest.cpp +++ b/third_party/WebKit/Source/platform/exported/WebURLRequest.cpp
@@ -30,6 +30,7 @@ #include "public/platform/WebURLRequest.h" +#include "platform/RuntimeEnabledFeatures.h" #include "platform/network/ResourceRequest.h" #include "public/platform/WebCachePolicy.h" #include "public/platform/WebHTTPBody.h" @@ -461,6 +462,13 @@ return m_resourceRequest->isExternalRequest(); } +WebURLRequest::LoadingIPCType WebURLRequest::getLoadingIPCType() const +{ + if (RuntimeEnabledFeatures::loadingWithMojoEnabled()) + return WebURLRequest::LoadingIPCType::Mojo; + return WebURLRequest::LoadingIPCType::ChromeIPC; +} + WebURLRequest::InputToLoadPerfMetricReportPolicy WebURLRequest::inputPerfMetricReportPolicy() const { return static_cast<WebURLRequest::InputToLoadPerfMetricReportPolicy>(
diff --git a/third_party/WebKit/Source/platform/fonts/FontFallbackIterator.cpp b/third_party/WebKit/Source/platform/fonts/FontFallbackIterator.cpp index 616e2fea..cedbbdc 100644 --- a/third_party/WebKit/Source/platform/fonts/FontFallbackIterator.cpp +++ b/third_party/WebKit/Source/platform/fonts/FontFallbackIterator.cpp
@@ -4,7 +4,6 @@ #include "platform/fonts/FontFallbackIterator.h" -#include "platform/Logging.h" #include "platform/fonts/FontCache.h" #include "platform/fonts/FontDescription.h" #include "platform/fonts/FontFallbackList.h"
diff --git a/third_party/WebKit/Source/platform/fonts/OrientationIteratorTest.cpp b/third_party/WebKit/Source/platform/fonts/OrientationIteratorTest.cpp index 5b46ae0..1ddb50ec 100644 --- a/third_party/WebKit/Source/platform/fonts/OrientationIteratorTest.cpp +++ b/third_party/WebKit/Source/platform/fonts/OrientationIteratorTest.cpp
@@ -4,7 +4,6 @@ #include "platform/fonts/OrientationIterator.h" -#include "platform/Logging.h" #include "testing/gtest/include/gtest/gtest.h" #include <string>
diff --git a/third_party/WebKit/Source/platform/fonts/ScriptRunIterator.cpp b/third_party/WebKit/Source/platform/fonts/ScriptRunIterator.cpp index 7bd62d3..513379cc 100644 --- a/third_party/WebKit/Source/platform/fonts/ScriptRunIterator.cpp +++ b/third_party/WebKit/Source/platform/fonts/ScriptRunIterator.cpp
@@ -4,9 +4,7 @@ #include "ScriptRunIterator.h" -#include "platform/Logging.h" #include "wtf/Threading.h" - #include <algorithm> namespace blink {
diff --git a/third_party/WebKit/Source/platform/fonts/SmallCapsIteratorTest.cpp b/third_party/WebKit/Source/platform/fonts/SmallCapsIteratorTest.cpp index 12e0888..50b1e2a 100644 --- a/third_party/WebKit/Source/platform/fonts/SmallCapsIteratorTest.cpp +++ b/third_party/WebKit/Source/platform/fonts/SmallCapsIteratorTest.cpp
@@ -4,7 +4,6 @@ #include "platform/fonts/SmallCapsIterator.h" -#include "platform/Logging.h" #include "testing/gtest/include/gtest/gtest.h" #include <string>
diff --git a/third_party/WebKit/Source/platform/fonts/SymbolsIterator.cpp b/third_party/WebKit/Source/platform/fonts/SymbolsIterator.cpp index fa780125..0920026 100644 --- a/third_party/WebKit/Source/platform/fonts/SymbolsIterator.cpp +++ b/third_party/WebKit/Source/platform/fonts/SymbolsIterator.cpp
@@ -84,16 +84,20 @@ // Except at the beginning, ZWJ just carries over the emoji or neutral // text type, VS15 & VS16 we just carry over as well, since we already - // resolved those through lookahead. Also, the text presentation emoji - // are upgraded to emoji presentation when combined through ZWJ in the - // case of example U+1F441 U+200D U+1F5E8, eye + ZWJ + left speech + // resolved those through lookahead. Also, don't downgrade to text + // presentation for emoji that are part of a ZWJ sequence, example + // U+1F441 U+200D U+1F5E8, eye (text presentation) + ZWJ + left speech // bubble, see below. if ((!(m_nextChar == zeroWidthJoinerCharacter && m_previousFontFallbackPriority == FontFallbackPriority::EmojiEmoji) && m_nextChar != variationSelector15Character && m_nextChar != variationSelector16Character && !Character::isRegionalIndicator(m_nextChar) - && !(m_nextChar == leftSpeechBubbleCharacter + && !((m_nextChar == leftSpeechBubbleCharacter + || m_nextChar == rainbowCharacter + || m_nextChar == maleSignCharacter + || m_nextChar == femaleSignCharacter + || m_nextChar == staffOfAesculapiusCharacter) && m_previousFontFallbackPriority == FontFallbackPriority::EmojiEmoji)) || m_currentFontFallbackPriority == FontFallbackPriority::Invalid) { m_currentFontFallbackPriority = fontFallbackPriorityForCharacter(m_nextChar); @@ -134,7 +138,8 @@ // Upgrade text presentation emoji to emoji presentation when followed by ZWJ, // Example U+1F441 U+200D U+1F5E8, eye + ZWJ + left speech bubble. - if (m_nextChar == eyeCharacter && peekChar == zeroWidthJoinerCharacter) { + if ((m_nextChar == eyeCharacter || m_nextChar == wavingWhiteFlagCharacter) + && peekChar == zeroWidthJoinerCharacter) { m_currentFontFallbackPriority = FontFallbackPriority::EmojiEmoji; } }
diff --git a/third_party/WebKit/Source/platform/fonts/SymbolsIteratorTest.cpp b/third_party/WebKit/Source/platform/fonts/SymbolsIteratorTest.cpp index 2c4f0ce..99487cd 100644 --- a/third_party/WebKit/Source/platform/fonts/SymbolsIteratorTest.cpp +++ b/third_party/WebKit/Source/platform/fonts/SymbolsIteratorTest.cpp
@@ -4,7 +4,6 @@ #include "platform/fonts/SymbolsIterator.h" -#include "platform/Logging.h" #include "testing/gtest/include/gtest/gtest.h" #include <string> @@ -110,11 +109,18 @@ CHECK_RUNS({ { "abcdef\xEF\xB8\x8Fghji", FontFallbackPriority::Text } }); } +TEST_F(SymbolsIteratorTest, AllHexValuesText) +{ + // Helps with detecting incorrect emoji pattern definitions which are + // missing a \U000... prefix for example. + CHECK_RUNS({ { "abcdef0123456789ABCDEF", FontFallbackPriority::Text } }); +} + TEST_F(SymbolsIteratorTest, NumbersAndHashNormalAndEmoji) { - CHECK_RUNS({ { "0123456789#", FontFallbackPriority::Text }, - { "0⃣1⃣2⃣3⃣4⃣5⃣6⃣7⃣8⃣9⃣#⃣", FontFallbackPriority::EmojiEmoji }, - { "0123456789#", FontFallbackPriority::Text } }); + CHECK_RUNS({ { "0123456789#*", FontFallbackPriority::Text }, + { "0⃣1⃣2⃣3⃣4⃣5⃣6⃣7⃣8⃣9⃣*⃣", FontFallbackPriority::EmojiEmoji }, + { "0123456789#*", FontFallbackPriority::Text } }); } @@ -157,6 +163,28 @@ FontFallbackPriority::EmojiEmoji } }); } +TEST_F(SymbolsIteratorTest, ModifierPlusGender) +{ + CHECK_RUNS({ { "⛹🏻♂", FontFallbackPriority::EmojiEmoji } }); +} + +TEST_F(SymbolsIteratorTest, TextMemberZwjSequence) +{ + CHECK_RUNS({ { "👨⚕", FontFallbackPriority::EmojiEmoji } }); +} + +TEST_F(SymbolsIteratorTest, FacepalmCartwheelShrugModifierFemale) +{ + CHECK_RUNS({ { "🤦♀🤸♀🤷♀🤷🏾♀", FontFallbackPriority::EmojiEmoji } }); +} + +TEST_F(SymbolsIteratorTest, AesculapiusMaleFemalEmoji) +{ + // Emoji Data 4 has upgraded those three characters to Emoji. + CHECK_RUNS({ { "a", FontFallbackPriority::Text }, + { "⚕♀♂", FontFallbackPriority::EmojiText } }); +} + TEST_F(SymbolsIteratorTest, EyeSpeechBubble) { CHECK_RUNS({ { "👁🗨", FontFallbackPriority::EmojiEmoji } });
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp index bca9d48..e6f15773 100644 --- a/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp +++ b/third_party/WebKit/Source/platform/fonts/shaping/HarfBuzzShaper.cpp
@@ -31,7 +31,6 @@ #include "platform/fonts/shaping/HarfBuzzShaper.h" -#include "platform/Logging.h" #include "platform/RuntimeEnabledFeatures.h" #include "platform/fonts/Font.h" #include "platform/fonts/FontFallbackIterator.h"
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/RunSegmenterTest.cpp b/third_party/WebKit/Source/platform/fonts/shaping/RunSegmenterTest.cpp index 8bb4988f..717f66b 100644 --- a/third_party/WebKit/Source/platform/fonts/shaping/RunSegmenterTest.cpp +++ b/third_party/WebKit/Source/platform/fonts/shaping/RunSegmenterTest.cpp
@@ -4,7 +4,6 @@ #include "platform/fonts/shaping/RunSegmenter.h" -#include "platform/Logging.h" #include "platform/fonts/OrientationIterator.h" #include "testing/gtest/include/gtest/gtest.h" #include "wtf/Assertions.h"
diff --git a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp index 19ed900..6bd22c9 100644 --- a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp +++ b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
@@ -384,10 +384,17 @@ if (m_frames.size() <= index) return true; - if (m_frames[index].m_haveMetadata) - return m_frames[index].m_hasAlpha; + if (m_frames[index].m_haveMetadata && !m_frames[index].m_hasAlpha) + return false; - return m_source.frameHasAlphaAtIndex(index); + // m_hasAlpha may change after m_haveMetadata is set to true, so always ask + // ImageSource for the value if the cached value is the default value. + bool hasAlpha = m_source.frameHasAlphaAtIndex(index); + + if (m_frames[index].m_haveMetadata) + m_frames[index].m_hasAlpha = hasAlpha; + + return hasAlpha; } bool BitmapImage::currentFrameKnownToBeOpaque(MetadataMode metadataMode)
diff --git a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp index 99c59dc..df4b8699 100644 --- a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp +++ b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp
@@ -98,16 +98,26 @@ prepareLazyDecodedFrames(); - DCHECK(index < m_frameData.size()); - DeferredFrameData* frameData = &m_frameData[index]; - if (m_actualDecoder) - frameData->m_frameBytes = m_actualDecoder->frameBytesAtIndex(index); - else - frameData->m_frameBytes = m_size.area() * sizeof(ImageFrame::PixelData); - // ImageFrameGenerator has the latest known alpha state. There will be a - // performance boost if this frame is opaque. - DCHECK(m_frameGenerator); - return createFrameImageAtIndex(index, !m_frameGenerator->hasAlpha(index)); + if (index < m_frameData.size()) { + DeferredFrameData* frameData = &m_frameData[index]; + if (m_actualDecoder) + frameData->m_frameBytes = m_actualDecoder->frameBytesAtIndex(index); + else + frameData->m_frameBytes = m_size.area() * sizeof(ImageFrame::PixelData); + // ImageFrameGenerator has the latest known alpha state. There will be a + // performance boost if this frame is opaque. + DCHECK(m_frameGenerator); + return createFrameImageAtIndex(index, !m_frameGenerator->hasAlpha(index)); + } + + if (!m_actualDecoder || m_actualDecoder->failed()) + return nullptr; + + ImageFrame* frame = m_actualDecoder->frameBufferAtIndex(index); + if (!frame || frame->getStatus() == ImageFrame::FrameEmpty) + return nullptr; + + return fromSkSp(SkImage::MakeFromBitmap(frame->bitmap())); } PassRefPtr<SharedBuffer> DeferredImageDecoder::data()
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp index e2d0901..494b08fe 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp +++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.cpp
@@ -128,8 +128,6 @@ , m_hasScrollParent(false) , m_hasClipParent(false) , m_painted(false) - , m_textPainted(false) - , m_imagePainted(false) , m_isTrackingPaintInvalidations(client && client->isTrackingPaintInvalidations()) , m_paintingPhase(GraphicsLayerPaintAllWithOverflowClip) , m_parent(0) @@ -382,25 +380,19 @@ void GraphicsLayer::notifyFirstPaintToClient() { + bool isFirstPaint = false; if (!m_painted) { DisplayItemList& itemList = m_paintController->newDisplayItemList(); for (DisplayItem& item : itemList) { DisplayItem::Type type = item.getType(); if (DisplayItem::isDrawingType(type) && type != DisplayItem::DocumentBackground && static_cast<const DrawingDisplayItem&>(item).picture()) { m_painted = true; - m_client->notifyFirstPaint(); + isFirstPaint = true; break; } } } - if (!m_textPainted && m_paintController->textPainted()) { - m_textPainted = true; - m_client->notifyFirstTextPaint(); - } - if (!m_imagePainted && m_paintController->imagePainted()) { - m_imagePainted = true; - m_client->notifyFirstImagePaint(); - } + m_client->notifyPaint(isFirstPaint, m_paintController->textPainted(), m_paintController->imagePainted()); } void GraphicsLayer::updateChildList()
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h index 8a2c6373..ef5f4744 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h +++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayer.h
@@ -333,8 +333,6 @@ bool m_hasClipParent : 1; bool m_painted : 1; - bool m_textPainted : 1; - bool m_imagePainted : 1; bool m_isTrackingPaintInvalidations : 1;
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsLayerClient.h b/third_party/WebKit/Source/platform/graphics/GraphicsLayerClient.h index 8cd1719..e0a1932 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsLayerClient.h +++ b/third_party/WebKit/Source/platform/graphics/GraphicsLayerClient.h
@@ -62,9 +62,7 @@ public: virtual ~GraphicsLayerClient() {} - virtual void notifyFirstPaint() { } - virtual void notifyFirstTextPaint() { } - virtual void notifyFirstImagePaint() { } + virtual void notifyPaint(bool isFirstPaint, bool textPainted, bool imagePainted) { } virtual IntRect computeInterestRect(const GraphicsLayer*, const IntRect& previousInterestRect) const = 0; virtual LayoutSize subpixelAccumulation() const { return LayoutSize(); }
diff --git a/third_party/WebKit/Source/platform/graphics/LoggingCanvas.cpp b/third_party/WebKit/Source/platform/graphics/LoggingCanvas.cpp index 1f21f65..da28018 100644 --- a/third_party/WebKit/Source/platform/graphics/LoggingCanvas.cpp +++ b/third_party/WebKit/Source/platform/graphics/LoggingCanvas.cpp
@@ -301,9 +301,11 @@ String stringForSkColor(const SkColor& color) { - String colorString = "#"; - appendUnsignedAsHex(color, colorString); - return colorString; + // #AARRGGBB. + Vector<LChar, 9> result; + result.append('#'); + appendUnsignedAsHex(color, result); + return String(result.data(), result.size()); } void appendFlagToString(String* flagsString, bool isSet, const String& name)
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp index f26ab817..a522468 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
@@ -83,26 +83,34 @@ namespace { +static gfx::Rect largeRect(-200000, -200000, 400000, 400000); + static void appendDisplayItemToCcDisplayItemList(const DisplayItem& displayItem, cc::DisplayItemList* list) { if (DisplayItem::isDrawingType(displayItem.getType())) { const SkPicture* picture = static_cast<const DrawingDisplayItem&>(displayItem).picture(); if (!picture) return; - gfx::Rect bounds = gfx::SkIRectToRect(picture->cullRect().roundOut()); - list->CreateAndAppendDrawingItem<cc::DrawingDisplayItem>(bounds, sk_ref_sp(picture)); + // In theory we would pass the bounds of the picture, previously done as: + // gfx::Rect bounds = gfx::SkIRectToRect(picture->cullRect().roundOut()); + // or use the visual rect directly. However, clip content layers attempt + // to raster in a different space than that of the visual rects. We'll be + // reworking visual rects further for SPv2, so for now we just pass a + // visual rect large enough to make sure items raster. + list->CreateAndAppendDrawingItem<cc::DrawingDisplayItem>(largeRect, sk_ref_sp(picture)); } } static scoped_refptr<cc::DisplayItemList> recordPaintChunk(const PaintArtifact& artifact, const PaintChunk& chunk, const gfx::Rect& combinedBounds) { cc::DisplayItemListSettings settings; - scoped_refptr<cc::DisplayItemList> list = cc::DisplayItemList::Create( - gfx::Rect(combinedBounds.size()), settings); + scoped_refptr<cc::DisplayItemList> list = cc::DisplayItemList::Create(settings); gfx::Transform translation; translation.Translate(-combinedBounds.x(), -combinedBounds.y()); - // TODO(jbroman, wkorman): What visual rectangle is wanted here? + // Passing combinedBounds as the visual rect for the begin/end transform item + // would normally be the sensible thing to do, but see comment above re: + // visual rects for drawing items and further rework in flight. list->CreateAndAppendPairedBeginItem<cc::TransformDisplayItem>(translation); const DisplayItemList& displayItems = artifact.getDisplayItemList(); @@ -542,7 +550,6 @@ cc::EffectNode& effectNode = *effectTree().Node(effectTree().Insert(cc::EffectNode(), compositorIdForCurrentEffectNode())); effectNode.owner_id = dummyLayer->id(); effectNode.clip_id = dummyClip.id; - effectNode.has_render_surface = true; effectNode.opacity = nextEffect->opacity(); m_effectStack.append(BlinkEffectAndCcIdPair{nextEffect, effectNode.id});
diff --git a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp index 70038e4..a95248c3 100644 --- a/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp +++ b/third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp
@@ -252,7 +252,7 @@ if (!m_contentsChanged) return false; - TRACE_EVENT0("blink", "DrawingBuffer::prepareMailbox"); + TRACE_EVENT0("blink,rail", "DrawingBuffer::prepareMailbox"); if (m_newMailboxCallback) (*m_newMailboxCallback)();
diff --git a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp index 63afa759..a453234 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp
@@ -19,14 +19,31 @@ FloatRect result = localToVisualRectInAncestorSpace(rect, sourceState, destinationState, success); if (success) return result; + return slowMapRectToDestinationSpace(rect, sourceState, destinationState, success); +} - // TODO(chrishtr): fixed const-ness here. - RefPtr<TransformPaintPropertyNode> lcaTransform = const_cast<TransformPaintPropertyNode*>(propertyTreeNearestCommonAncestor<TransformPaintPropertyNode>(sourceState.transform.get(), destinationState.transform.get())); - DCHECK(lcaTransform.get()); +FloatRect GeometryMapper::mapRectToDestinationSpace(const FloatRect& rect, + const PropertyTreeState& sourceState, + const PropertyTreeState& destinationState, + bool& success) +{ + FloatRect result = localToAncestorRect(rect, sourceState, destinationState, success); + if (success) + return result; + return slowMapRectToDestinationSpace(rect, sourceState, destinationState, success); +} + +FloatRect GeometryMapper::slowMapRectToDestinationSpace(const FloatRect& rect, + const PropertyTreeState& sourceState, + const PropertyTreeState& destinationState, + bool& success) +{ + const TransformPaintPropertyNode* lcaTransform = propertyTreeNearestCommonAncestor<TransformPaintPropertyNode>(sourceState.transform.get(), destinationState.transform.get()); + DCHECK(lcaTransform); PropertyTreeState lcaState = sourceState; lcaState.transform = lcaTransform; - result = localToAncestorMatrix(sourceState.transform.get(), lcaState, success).mapRect(rect); + FloatRect result = localToAncestorRect(rect, sourceState, lcaState, success); DCHECK(success); const TransformationMatrix& destinationToLca = localToAncestorMatrix(destinationState.transform.get(), lcaState, success);
diff --git a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.h b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.h index ae25427..35a5883 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.h +++ b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.h
@@ -42,7 +42,7 @@ class PLATFORM_EXPORT GeometryMapper { public: GeometryMapper() {} - // The runtime of m calls among LocalToVisualRectInAncestorSpace, LocalToAncestorRect or AncestorToLocalRect + // The runtime of m calls among localToVisualRectInAncestorSpace, localToAncestorRect or ancestorToLocalRect // with the same |ancestorState| parameter is guaranteed to be O(n + m), where n is the number of transform and clip // nodes in their respective property trees. @@ -58,6 +58,12 @@ const PropertyTreeState& destinationState, bool& success); + // Same as mapToVisualRectInDestinationSpace() except that *no* clip is applied. + FloatRect mapRectToDestinationSpace(const FloatRect&, + const PropertyTreeState& sourceState, + const PropertyTreeState& destinationState, + bool& success); + // Maps from a rect in |localTransformSpace| to its visual rect in |ancestorState|. This is computed // by multiplying the rect by its combined transform between |localTransformSpace| and |ancestorSpace|, // then flattening into 2D space, then intersecting by the "clip visual rect" for |localTransformState|'s clips. @@ -99,6 +105,13 @@ const PropertyTreeState& ancestorState, bool& success); private: + // Used by mapToVisualRectInDestinationSpace() and mapRectToDestinationSpace() after fast mapping + // (assuming destination is an ancestor of source) failed. + FloatRect slowMapRectToDestinationSpace(const FloatRect&, + const PropertyTreeState& sourceState, + const PropertyTreeState& destinationState, + bool& success); + // Returns the matrix used in |LocalToAncestorRect|. Sets |success| to failse iff |localTransformNode| is not // equal to or a descendant of |ancestorState.transform|. const TransformationMatrix& localToAncestorMatrix(
diff --git a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp index e78cf293..e763279 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapperTest.cpp
@@ -64,8 +64,13 @@ EXPECT_RECT_EQ(expectedVisualRect, \ geometryMapper->localToVisualRectInAncestorSpace(inputRect, localPropertyTreeState, ancestorPropertyTreeState, success)); \ EXPECT_TRUE(success); \ + EXPECT_RECT_EQ(expectedVisualRect, \ + geometryMapper->mapToVisualRectInDestinationSpace(inputRect, localPropertyTreeState, ancestorPropertyTreeState, success)); \ + EXPECT_TRUE(success); \ EXPECT_RECT_EQ(expectedTransformedRect, \ geometryMapper->localToAncestorRect(inputRect, localPropertyTreeState, ancestorPropertyTreeState, success)); \ + EXPECT_RECT_EQ(expectedTransformedRect, \ + geometryMapper->mapRectToDestinationSpace(inputRect, localPropertyTreeState, ancestorPropertyTreeState, success)); \ EXPECT_TRUE(success); \ EXPECT_EQ(expectedTransformToAncestor, getPrecomputedDataForAncestor(ancestorPropertyTreeState).toAncestorTransforms.get(localPropertyTreeState.transform.get())); \ EXPECT_EQ(expectedClipInAncestorSpace, getPrecomputedDataForAncestor(ancestorPropertyTreeState).toAncestorClipRects.get(localPropertyTreeState.clip.get())); \ @@ -360,15 +365,29 @@ EXPECT_FALSE(success); EXPECT_RECT_EQ(input, result); + result = geometryMapper->localToAncestorRect(input, transform1State, transform2State, success); + // Fails, because the transform2state is not an ancestor of transform1State. + EXPECT_FALSE(success); + EXPECT_RECT_EQ(input, result); + result = geometryMapper->localToVisualRectInAncestorSpace(input, transform2State, transform1State, success); // Fails, because the transform1state is not an ancestor of transform2State. EXPECT_FALSE(success); EXPECT_RECT_EQ(input, result); + result = geometryMapper->localToAncestorRect(input, transform2State, transform1State, success); + // Fails, because the transform1state is not an ancestor of transform2State. + EXPECT_FALSE(success); + EXPECT_RECT_EQ(input, result); + FloatRect expected = rotateTransform2.inverse().mapRect(rotateTransform1.mapRect(input)); result = geometryMapper->mapToVisualRectInDestinationSpace(input, transform1State, transform2State, success); EXPECT_TRUE(success); EXPECT_RECT_EQ(expected, result); + + result = geometryMapper->mapRectToDestinationSpace(input, transform1State, transform2State, success); + EXPECT_TRUE(success); + EXPECT_RECT_EQ(expected, result); } } // namespace blink
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp index 691e9e4..874b7d0 100644 --- a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp +++ b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
@@ -21,6 +21,7 @@ #include "platform/image-decoders/ImageDecoder.h" #include "platform/PlatformInstrumentation.h" +#include "platform/RuntimeEnabledFeatures.h" #include "platform/graphics/BitmapImageMetrics.h" #include "platform/image-decoders/bmp/BMPImageDecoder.h" #include "platform/image-decoders/gif/GIFImageDecoder.h" @@ -364,6 +365,10 @@ m_colorProfile.assign(iccData, iccLength); m_hasColorProfile = true; + // With color correct rendering, we use Skia instead of QCMS to color correct images. + if (RuntimeEnabledFeatures::colorCorrectRenderingEnabled()) + return; + #if USE(QCMSLIB) m_sourceToOutputDeviceColorTransform.reset();
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageFrame.cpp b/third_party/WebKit/Source/platform/image-decoders/ImageFrame.cpp index 1803280..6a4db8f 100644 --- a/third_party/WebKit/Source/platform/image-decoders/ImageFrame.cpp +++ b/third_party/WebKit/Source/platform/image-decoders/ImageFrame.cpp
@@ -24,6 +24,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "platform/image-decoders/ImageFrame.h" + +#include "platform/RuntimeEnabledFeatures.h" #include "platform/image-decoders/ImageDecoder.h" namespace blink { @@ -98,11 +101,12 @@ // setSizeAndColorProfile() should only be called once, it leaks memory otherwise. ASSERT(!width() && !height()); - // TODO(ccameron): Populate the color space parameter of the SkImageInfo - // with newIccProfile, under a runtime flag. + sk_sp<SkColorSpace> colorSpace; + if (RuntimeEnabledFeatures::colorCorrectRenderingEnabled() && !newIccProfile.isEmpty()) + colorSpace = SkColorSpace::NewICC(newIccProfile.data(), newIccProfile.size()); m_bitmap.setInfo(SkImageInfo::MakeN32(newWidth, newHeight, - m_premultiplyAlpha ? kPremul_SkAlphaType : kUnpremul_SkAlphaType)); + m_premultiplyAlpha ? kPremul_SkAlphaType : kUnpremul_SkAlphaType, colorSpace)); if (!m_bitmap.tryAllocPixels(m_allocator, 0)) return false;
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageFrame.h b/third_party/WebKit/Source/platform/image-decoders/ImageFrame.h index f6e4e8b..3541f7d 100644 --- a/third_party/WebKit/Source/platform/image-decoders/ImageFrame.h +++ b/third_party/WebKit/Source/platform/image-decoders/ImageFrame.h
@@ -31,6 +31,7 @@ #include "platform/geometry/IntRect.h" #include "public/platform/WebVector.h" #include "third_party/skia/include/core/SkBitmap.h" +#include "third_party/skia/include/core/SkColorPriv.h" #include "wtf/Allocator.h" #include "wtf/Assertions.h" #include "wtf/PassRefPtr.h"
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Allocator.h b/third_party/WebKit/Source/platform/inspector_protocol/Allocator_h.template similarity index 100% rename from third_party/WebKit/Source/platform/inspector_protocol/Allocator.h rename to third_party/WebKit/Source/platform/inspector_protocol/Allocator_h.template
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Array.h b/third_party/WebKit/Source/platform/inspector_protocol/Array.h deleted file mode 100644 index 7201822..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/Array.h +++ /dev/null
@@ -1,138 +0,0 @@ -// Copyright 2016 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 Array_h -#define Array_h - -#include "platform/inspector_protocol/ErrorSupport.h" -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" -#include "platform/inspector_protocol/ValueConversions.h" -#include "platform/inspector_protocol/Values.h" - -#include <vector> - -namespace blink { -namespace protocol { - -template<typename T> -class Array { -public: - static std::unique_ptr<Array<T>> create() - { - return wrapUnique(new Array<T>()); - } - - static std::unique_ptr<Array<T>> parse(protocol::Value* value, ErrorSupport* errors) - { - protocol::ListValue* array = ListValue::cast(value); - if (!array) { - errors->addError("array expected"); - return nullptr; - } - std::unique_ptr<Array<T>> result(new Array<T>()); - errors->push(); - for (size_t i = 0; i < array->size(); ++i) { - errors->setName(String16::fromInteger(i)); - std::unique_ptr<T> item = ValueConversions<T>::parse(array->at(i), errors); - result->m_vector.push_back(std::move(item)); - } - errors->pop(); - if (errors->hasErrors()) - return nullptr; - return result; - } - - void addItem(std::unique_ptr<T> value) - { - m_vector.push_back(std::move(value)); - } - - size_t length() - { - return m_vector.size(); - } - - T* get(size_t index) - { - return m_vector[index].get(); - } - - std::unique_ptr<protocol::ListValue> serialize() - { - std::unique_ptr<protocol::ListValue> result = ListValue::create(); - for (auto& item : m_vector) - result->pushValue(ValueConversions<T>::serialize(item)); - return result; - } - -private: - std::vector<std::unique_ptr<T>> m_vector; -}; - -template<typename T> -class ArrayBase { -public: - static std::unique_ptr<Array<T>> create() - { - return wrapUnique(new Array<T>()); - } - - static std::unique_ptr<Array<T>> parse(protocol::Value* value, ErrorSupport* errors) - { - protocol::ListValue* array = ListValue::cast(value); - if (!array) { - errors->addError("array expected"); - return nullptr; - } - errors->push(); - std::unique_ptr<Array<T>> result(new Array<T>()); - for (size_t i = 0; i < array->size(); ++i) { - errors->setName(String16::fromInteger(i)); - T item = ValueConversions<T>::parse(array->at(i), errors); - result->m_vector.push_back(item); - } - errors->pop(); - if (errors->hasErrors()) - return nullptr; - return result; - } - - void addItem(const T& value) - { - m_vector.push_back(value); - } - - size_t length() - { - return m_vector.size(); - } - - T get(size_t index) - { - return m_vector[index]; - } - - std::unique_ptr<protocol::ListValue> serialize() - { - std::unique_ptr<protocol::ListValue> result = ListValue::create(); - for (auto& item : m_vector) - result->pushValue(ValueConversions<T>::serialize(item)); - return result; - } - -private: - std::vector<T> m_vector; -}; - -template<> class Array<String> : public ArrayBase<String> {}; -template<> class Array<String16> : public ArrayBase<String16> {}; -template<> class Array<int> : public ArrayBase<int> {}; -template<> class Array<double> : public ArrayBase<double> {}; -template<> class Array<bool> : public ArrayBase<bool> {}; - -} // namespace platform -} // namespace blink - -#endif // !defined(Array_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Array_h.template b/third_party/WebKit/Source/platform/inspector_protocol/Array_h.template new file mode 100644 index 0000000..40abb2d46 --- /dev/null +++ b/third_party/WebKit/Source/platform/inspector_protocol/Array_h.template
@@ -0,0 +1,138 @@ +// Copyright 2016 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 Array_h +#define Array_h + +//#include "ErrorSupport.h" +//#include "Platform.h" +//#include "String16.h" +//#include "ValueConversions.h" +//#include "Values.h" + +#include <vector> + +namespace blink { +namespace protocol { + +template<typename T> +class Array { +public: + static std::unique_ptr<Array<T>> create() + { + return wrapUnique(new Array<T>()); + } + + static std::unique_ptr<Array<T>> parse(protocol::Value* value, ErrorSupport* errors) + { + protocol::ListValue* array = ListValue::cast(value); + if (!array) { + errors->addError("array expected"); + return nullptr; + } + std::unique_ptr<Array<T>> result(new Array<T>()); + errors->push(); + for (size_t i = 0; i < array->size(); ++i) { + errors->setName(String16::fromInteger(i)); + std::unique_ptr<T> item = ValueConversions<T>::parse(array->at(i), errors); + result->m_vector.push_back(std::move(item)); + } + errors->pop(); + if (errors->hasErrors()) + return nullptr; + return result; + } + + void addItem(std::unique_ptr<T> value) + { + m_vector.push_back(std::move(value)); + } + + size_t length() + { + return m_vector.size(); + } + + T* get(size_t index) + { + return m_vector[index].get(); + } + + std::unique_ptr<protocol::ListValue> serialize() + { + std::unique_ptr<protocol::ListValue> result = ListValue::create(); + for (auto& item : m_vector) + result->pushValue(ValueConversions<T>::serialize(item)); + return result; + } + +private: + std::vector<std::unique_ptr<T>> m_vector; +}; + +template<typename T> +class ArrayBase { +public: + static std::unique_ptr<Array<T>> create() + { + return wrapUnique(new Array<T>()); + } + + static std::unique_ptr<Array<T>> parse(protocol::Value* value, ErrorSupport* errors) + { + protocol::ListValue* array = ListValue::cast(value); + if (!array) { + errors->addError("array expected"); + return nullptr; + } + errors->push(); + std::unique_ptr<Array<T>> result(new Array<T>()); + for (size_t i = 0; i < array->size(); ++i) { + errors->setName(String16::fromInteger(i)); + T item = ValueConversions<T>::parse(array->at(i), errors); + result->m_vector.push_back(item); + } + errors->pop(); + if (errors->hasErrors()) + return nullptr; + return result; + } + + void addItem(const T& value) + { + m_vector.push_back(value); + } + + size_t length() + { + return m_vector.size(); + } + + T get(size_t index) + { + return m_vector[index]; + } + + std::unique_ptr<protocol::ListValue> serialize() + { + std::unique_ptr<protocol::ListValue> result = ListValue::create(); + for (auto& item : m_vector) + result->pushValue(ValueConversions<T>::serialize(item)); + return result; + } + +private: + std::vector<T> m_vector; +}; + +template<> class Array<InspectorProtocolConvenienceStringType> : public ArrayBase<InspectorProtocolConvenienceStringType> {}; +template<> class Array<String16> : public ArrayBase<String16> {}; +template<> class Array<int> : public ArrayBase<int> {}; +template<> class Array<double> : public ArrayBase<double> {}; +template<> class Array<bool> : public ArrayBase<bool> {}; + +} // namespace platform +} // namespace blink + +#endif // !defined(Array_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/BackendCallback.h b/third_party/WebKit/Source/platform/inspector_protocol/BackendCallback.h deleted file mode 100644 index 870fbb5..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/BackendCallback.h +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright (c) 2016 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 BackendCallback_h -#define BackendCallback_h - -#include "platform/inspector_protocol/ErrorSupport.h" -#include "platform/inspector_protocol/Platform.h" - -namespace blink { -namespace protocol { - -class PLATFORM_EXPORT BackendCallback { -public: - virtual ~BackendCallback() { } - virtual void sendFailure(const ErrorString&) = 0; -}; - -} // namespace platform -} // namespace blink - -#endif // !defined(BackendCallback_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/BackendCallback_h.template b/third_party/WebKit/Source/platform/inspector_protocol/BackendCallback_h.template new file mode 100644 index 0000000..f301edec --- /dev/null +++ b/third_party/WebKit/Source/platform/inspector_protocol/BackendCallback_h.template
@@ -0,0 +1,24 @@ +// Copyright (c) 2016 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 BackendCallback_h +#define BackendCallback_h + +//#include "ErrorSupport.h" +//#include "Platform.h" +#include "{{export_macro_include}}" + +namespace blink { +namespace protocol { + +class {{export_macro}} BackendCallback { +public: + virtual ~BackendCallback() { } + virtual void sendFailure(const ErrorString&) = 0; +}; + +} // namespace platform +} // namespace blink + +#endif // !defined(BackendCallback_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/CodeGenerator.py b/third_party/WebKit/Source/platform/inspector_protocol/CodeGenerator.py index 0b09c8e..128dde3 100644 --- a/third_party/WebKit/Source/platform/inspector_protocol/CodeGenerator.py +++ b/third_party/WebKit/Source/platform/inspector_protocol/CodeGenerator.py
@@ -48,45 +48,19 @@ import jinja2 cmdline_parser = optparse.OptionParser() -cmdline_parser.add_option("--protocol") -cmdline_parser.add_option("--include") -cmdline_parser.add_option("--include_package") -cmdline_parser.add_option("--string_type") -cmdline_parser.add_option("--export_macro") -cmdline_parser.add_option("--output_dir") -cmdline_parser.add_option("--output_package") -cmdline_parser.add_option("--exported_dir") -cmdline_parser.add_option("--exported_package") +cmdline_parser.add_option("--output_base") +cmdline_parser.add_option("--config") + try: arg_options, arg_values = cmdline_parser.parse_args() - protocol_file = arg_options.protocol - if not protocol_file: - raise Exception("Protocol directory must be specified") - include_file = arg_options.include - include_package = arg_options.include_package - if include_file and not include_package: - raise Exception("Include package must be specified when using include file") - if include_package and not include_file: - raise Exception("Include file must be specified when using include package") - output_dirname = arg_options.output_dir - if not output_dirname: - raise Exception("Output directory must be specified") - output_package = arg_options.output_package - if not output_package: - raise Exception("Output package must be specified") - exported_dirname = arg_options.exported_dir - if not exported_dirname: - exported_dirname = os.path.join(output_dirname, "exported") - exported_package = arg_options.exported_package - if not exported_package: - exported_package = os.path.join(output_package, "exported") - string_type = arg_options.string_type - if not string_type: - raise Exception("String type must be specified") - export_macro = arg_options.export_macro - if not export_macro: - raise Exception("Export macro must be specified") + output_base = arg_options.output_base + if not output_base: + raise Exception("Base output directory must be specified") + config_file = arg_options.config + if not config_file: + raise Exception("Config file name must be specified") + config_dir = os.path.dirname(config_file) except Exception: # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html exc = sys.exc_info()[1] @@ -94,9 +68,77 @@ exit(1) -input_file = open(protocol_file, "r") -json_string = input_file.read() -parsed_json = json.loads(json_string) +try: + config_json_string = open(config_file, "r").read() + config = json.loads(config_json_string) + + protocol_file = config["protocol"]["path"] + if not protocol_file: + raise Exception("Config is missing protocol.path") + protocol_file = os.path.join(config_dir, protocol_file) + output_dirname = config["protocol"]["output"] + if not output_dirname: + raise Exception("Config is missing protocol.output") + output_dirname = os.path.join(output_base, output_dirname) + output_package = config["protocol"]["package"] + if not output_package: + raise Exception("Config is missing protocol.package") + + importing = False + if "import" in config: + importing = True + imported_file = config["import"]["path"] + if not imported_file: + raise Exception("Config is missing import.path") + imported_file = os.path.join(config_dir, imported_file) + imported_package = config["import"]["package"] + if not imported_package: + raise Exception("Config is missing import.package") + + exporting = False + if "export" in config: + exporting = True + exported_dirname = config["export"]["output"] + if not exported_dirname: + raise Exception("Config is missing export.output") + exported_dirname = os.path.join(output_base, exported_dirname) + exported_package = config["export"]["package"] + if not exported_package: + raise Exception("Config is missing export.package") + + lib = False + if "lib" in config: + lib = True + lib_dirname = config["lib"]["output"] + if not lib_dirname: + raise Exception("Config is missing lib.output") + lib_dirname = os.path.join(output_base, lib_dirname) + lib_string16_include = config["lib"]["string16_impl_header_path"] + if not lib_string16_include: + raise Exception("Config is missing lib.string16_impl_header_path") + lib_platform_include = config["lib"]["platform_impl_header_path"] + if not lib_platform_include: + raise Exception("Config is missing lib.platform_impl_header_path") + + string_type = config["string"]["class_name"] + if not string_type: + raise Exception("Config is missing string.class_name") + + export_macro = config["class_export"]["macro"] + if not export_macro: + raise Exception("Config is missing class_export.macro") + export_macro_include = config["class_export"]["header_path"] + if not export_macro_include: + raise Exception("Config is missing class_export.header_path") + + lib_package = config["lib_package"] + if not lib_package: + raise Exception("Config is missing lib_package") +except Exception: + # Work with python 2 and 3 http://docs.python.org/py3k/howto/pyporting.html + exc = sys.exc_info()[1] + sys.stderr.write("Failed to parse config file: %s\n\n" % exc) + exit(1) # Make gyp / make generatos happy, otherwise make rebuilds world. @@ -107,16 +149,19 @@ os.path.getmtime(os.path.join(templates_dir, "TypeBuilder_cpp.template")), os.path.getmtime(os.path.join(templates_dir, "Exported_h.template")), os.path.getmtime(os.path.join(templates_dir, "Imported_h.template")), + os.path.getmtime(config_file), os.path.getmtime(protocol_file)) + if importing: + template_ts = max(template_ts, os.path.getmtime(imported_file)) - for domain in parsed_json["domains"]: + for domain in json_api["domains"]: name = domain["domain"] paths = [] if name in generate_domains: paths = [os.path.join(output_dirname, name + ".h"), os.path.join(output_dirname, name + ".cpp")] if domain["has_exports"]: paths.append(os.path.join(exported_dirname, name + ".h")) - if name in include_domains and domain["has_exports"]: + if name in imported_domains and domain["has_exports"]: paths = [os.path.join(output_dirname, name + '.h')] for path in paths: if not os.path.exists(path): @@ -193,11 +238,16 @@ json_api["has_exports"] = False for domain_json in json_api["domains"]: + domain_name = domain_json["domain"] domain_json["has_exports"] = calculate_exports_in_json(domain_json) - json_api["has_exports"] = json_api["has_exports"] or domain_json["has_exports"] + if domain_json["has_exports"] and domain_name in generate_domains: + if not exporting: + sys.stderr.write("Domain %s is exported, but config is missing export entry\n\n" % domain_name) + exit(1) + json_api["has_exports"] = True -def create_include_type_definition(domain_name, type): +def create_imported_type_definition(domain_name, type): # pylint: disable=W0622 return { "return_type": "std::unique_ptr<protocol::%s::API::%s>" % (domain_name, type["id"]), @@ -335,8 +385,8 @@ continue for type in domain["types"]: type_name = domain["domain"] + "." + type["id"] - if type["type"] == "object" and domain["domain"] in include_domains: - type_definitions[type_name] = create_include_type_definition(domain["domain"], type) + if type["type"] == "object" and domain["domain"] in imported_domains: + type_definitions[type_name] = create_imported_type_definition(domain["domain"], type) elif type["type"] == "object": type_definitions[type_name] = create_user_type_definition(domain["domain"], type) elif type["type"] == "array": @@ -383,31 +433,90 @@ "type_definition": type_definition, "has_disable": has_disable, "export_macro": export_macro, + "export_macro_include": export_macro_include, "output_package": output_package, - "exported_package": exported_package, - "include_package": include_package + "lib_package": lib_package } + if exporting: + template_context["exported_package"] = exported_package + if importing: + template_context["imported_package"] = imported_package out_file = output_file(file_name) out_file.write(template.render(template_context)) out_file.close() -generate_domains = [] -include_domains = [] -json_api = {} -json_api["domains"] = parsed_json["domains"] - -for domain in parsed_json["domains"]: - generate_domains.append(domain["domain"]) - -if include_file: - input_file = open(include_file, "r") +def read_protocol_file(file_name, all_domains): + input_file = open(file_name, "r") json_string = input_file.read() parsed_json = json.loads(json_string) + domains = [] for domain in parsed_json["domains"]: - include_domains.append(domain["domain"]) - json_api["domains"] += parsed_json["domains"] + domains.append(domain["domain"]) + all_domains["domains"] += parsed_json["domains"] + return domains + +def generate_lib(): + template_context = { + "string16_impl_h_include": lib_string16_include, + "platform_impl_h_include": lib_platform_include, + "lib_package": lib_package, + "export_macro": export_macro, + "export_macro_include": export_macro_include + } + + def generate_file(file_name, template_files): + out_file = output_file(file_name) + for template_file in template_files: + template = jinja_env.get_template("/" + template_file) + out_file.write(template.render(template_context)) + out_file.write("\n\n") + out_file.close() + + # Note these should be sorted in the right order. + # TODO(dgozman): sort them programmatically based on commented includes. + lib_h_templates = [ + "Allocator_h.template", + "Platform_h.template", + "Collections_h.template", + "String16_h.template", + + "ErrorSupport_h.template", + "Values_h.template", + "Object_h.template", + "ValueConversions_h.template", + "Maybe_h.template", + "Array_h.template", + + "FrontendChannel_h.template", + "BackendCallback_h.template", + "DispatcherBase_h.template", + + "Parser_h.template", + ] + + lib_cpp_templates = [ + "InspectorProtocol_cpp.template", + + "String16_cpp.template", + + "ErrorSupport_cpp.template", + "Values_cpp.template", + "Object_cpp.template", + + "DispatcherBase_cpp.template", + + "Parser_cpp.template", + ] + + generate_file(os.path.join(lib_dirname, "InspectorProtocol.h"), lib_h_templates) + generate_file(os.path.join(lib_dirname, "InspectorProtocol.cpp"), lib_cpp_templates) + + +json_api = {"domains": []} +generate_domains = read_protocol_file(protocol_file, json_api) +imported_domains = read_protocol_file(imported_file, json_api) if importing else [] patch_full_qualified_refs() calculate_exports() create_type_definitions() @@ -428,9 +537,12 @@ for domain in json_api["domains"]: class_name = domain["domain"] if domain["domain"] in generate_domains: - generate(domain, h_template, output_dirname + "/" + class_name + ".h") - generate(domain, cpp_template, output_dirname + "/" + class_name + ".cpp") + generate(domain, h_template, os.path.join(output_dirname, class_name + ".h")) + generate(domain, cpp_template, os.path.join(output_dirname, class_name + ".cpp")) if domain["has_exports"]: - generate(domain, exported_template, exported_dirname + "/" + class_name + ".h") - if domain["domain"] in include_domains and domain["has_exports"]: - generate(domain, imported_template, output_dirname + "/" + class_name + ".h") + generate(domain, exported_template, os.path.join(exported_dirname, class_name + ".h")) + if domain["domain"] in imported_domains and domain["has_exports"]: + generate(domain, imported_template, os.path.join(output_dirname, class_name + ".h")) + +if lib: + generate_lib()
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Collections.h b/third_party/WebKit/Source/platform/inspector_protocol/Collections_h.template similarity index 100% rename from third_party/WebKit/Source/platform/inspector_protocol/Collections.h rename to third_party/WebKit/Source/platform/inspector_protocol/Collections_h.template
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/DispatcherBase.cpp b/third_party/WebKit/Source/platform/inspector_protocol/DispatcherBase.cpp deleted file mode 100644 index 8f154f42..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/DispatcherBase.cpp +++ /dev/null
@@ -1,173 +0,0 @@ -// Copyright 2016 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 "platform/inspector_protocol/DispatcherBase.h" - -#include "platform/inspector_protocol/FrontendChannel.h" -#include "platform/inspector_protocol/Parser.h" - -namespace blink { -namespace protocol { - -// static -const char DispatcherBase::kInvalidRequest[] = "Invalid request"; - -DispatcherBase::WeakPtr::WeakPtr(DispatcherBase* dispatcher) : m_dispatcher(dispatcher) { } - -DispatcherBase::WeakPtr::~WeakPtr() -{ - if (m_dispatcher) - m_dispatcher->m_weakPtrs.erase(this); -} - -DispatcherBase::Callback::Callback(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId) - : m_backendImpl(std::move(backendImpl)) - , m_callId(callId) { } - -DispatcherBase::Callback::~Callback() = default; - -void DispatcherBase::Callback::dispose() -{ - m_backendImpl = nullptr; -} - -void DispatcherBase::Callback::sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const ErrorString& invocationError) -{ - if (!m_backendImpl || !m_backendImpl->get()) - return; - m_backendImpl->get()->sendResponse(m_callId, invocationError, nullptr, std::move(partialMessage)); - m_backendImpl = nullptr; -} - -DispatcherBase::DispatcherBase(FrontendChannel* frontendChannel) - : m_frontendChannel(frontendChannel) { } - -DispatcherBase::~DispatcherBase() -{ - clearFrontend(); -} - -// static -bool DispatcherBase::getCommandName(const String16& message, String16* result) -{ - std::unique_ptr<protocol::Value> value = parseJSON(message); - if (!value) - return false; - - protocol::DictionaryValue* object = DictionaryValue::cast(value.get()); - if (!object) - return false; - - if (!object->getString("method", result)) - return false; - - return true; -} - -void DispatcherBase::sendResponse(int callId, const ErrorString& invocationError, ErrorSupport* errors, std::unique_ptr<protocol::DictionaryValue> result) -{ - if (invocationError.length() || (errors && errors->hasErrors())) { - reportProtocolError(callId, ServerError, invocationError, errors); - return; - } - - std::unique_ptr<protocol::DictionaryValue> responseMessage = DictionaryValue::create(); - responseMessage->setInteger("id", callId); - responseMessage->setObject("result", std::move(result)); - if (m_frontendChannel) - m_frontendChannel->sendProtocolResponse(callId, responseMessage->toJSONString()); -} - -void DispatcherBase::sendResponse(int callId, const ErrorString& invocationError, std::unique_ptr<protocol::DictionaryValue> result) -{ - sendResponse(callId, invocationError, nullptr, std::move(result)); -} - -void DispatcherBase::sendResponse(int callId, const ErrorString& invocationError) -{ - sendResponse(callId, invocationError, nullptr, DictionaryValue::create()); -} - -static void reportProtocolError(FrontendChannel* frontendChannel, int callId, DispatcherBase::CommonErrorCode code, const String16& errorMessage, ErrorSupport* errors) -{ - std::unique_ptr<protocol::DictionaryValue> error = DictionaryValue::create(); - error->setInteger("code", code); - error->setString("message", errorMessage); - DCHECK(error); - if (errors && errors->hasErrors()) - error->setString("data", errors->errors()); - std::unique_ptr<protocol::DictionaryValue> message = DictionaryValue::create(); - message->setObject("error", std::move(error)); - message->setInteger("id", callId); - frontendChannel->sendProtocolResponse(callId, message->toJSONString()); -} - -void DispatcherBase::reportProtocolError(int callId, CommonErrorCode code, const String16& errorMessage, ErrorSupport* errors) -{ - if (m_frontendChannel) - ::blink::protocol::reportProtocolError(m_frontendChannel, callId, code, errorMessage, errors); -} - -void DispatcherBase::clearFrontend() -{ - m_frontendChannel = nullptr; - for (auto& weak : m_weakPtrs) - weak->dispose(); - m_weakPtrs.clear(); -} - -std::unique_ptr<DispatcherBase::WeakPtr> DispatcherBase::weakPtr() -{ - std::unique_ptr<DispatcherBase::WeakPtr> weak(new DispatcherBase::WeakPtr(this)); - m_weakPtrs.insert(weak.get()); - return weak; -} - -UberDispatcher::UberDispatcher(FrontendChannel* frontendChannel) - : m_frontendChannel(frontendChannel) { } - -void UberDispatcher::registerBackend(const String16& name, std::unique_ptr<protocol::DispatcherBase> dispatcher) -{ - m_dispatchers[name] = std::move(dispatcher); -} - -void UberDispatcher::dispatch(const String16& message) -{ - std::unique_ptr<protocol::Value> parsedMessage = parseJSON(message); - if (!parsedMessage) - return; - std::unique_ptr<protocol::DictionaryValue> messageObject = DictionaryValue::cast(std::move(parsedMessage)); - if (!messageObject) - return; - - int callId = 0; - protocol::Value* callIdValue = messageObject->get("id"); - bool success = callIdValue->asInteger(&callId); - if (!success) - return; - - protocol::Value* methodValue = messageObject->get("method"); - String16 method; - success = methodValue && methodValue->asString(&method); - if (!success) - return; - - size_t dotIndex = method.find("."); - if (dotIndex == kNotFound) { - reportProtocolError(m_frontendChannel, callId, DispatcherBase::MethodNotFound, "'" + method + "' wasn't found", nullptr); - return; - } - String16 domain = method.substring(0, dotIndex); - auto it = m_dispatchers.find(domain); - if (it == m_dispatchers.end()) { - reportProtocolError(m_frontendChannel, callId, DispatcherBase::MethodNotFound, "'" + method + "' wasn't found", nullptr); - return; - } - it->second->dispatch(callId, method, std::move(messageObject)); -} - -UberDispatcher::~UberDispatcher() = default; - -} // namespace protocol -} // namespace blink
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/DispatcherBase.h b/third_party/WebKit/Source/platform/inspector_protocol/DispatcherBase.h deleted file mode 100644 index 6e8ae28..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/DispatcherBase.h +++ /dev/null
@@ -1,97 +0,0 @@ -// Copyright 2016 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 DispatcherBase_h -#define DispatcherBase_h - -#include "platform/inspector_protocol/BackendCallback.h" -#include "platform/inspector_protocol/Collections.h" -#include "platform/inspector_protocol/ErrorSupport.h" -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" -#include "platform/inspector_protocol/Values.h" - -namespace blink { -namespace protocol { - -class FrontendChannel; -class WeakPtr; - -class PLATFORM_EXPORT DispatcherBase { - PROTOCOL_DISALLOW_COPY(DispatcherBase); -public: - static const char kInvalidRequest[]; - class PLATFORM_EXPORT WeakPtr { - public: - explicit WeakPtr(DispatcherBase*); - ~WeakPtr(); - DispatcherBase* get() { return m_dispatcher; } - void dispose() { m_dispatcher = nullptr; } - - private: - DispatcherBase* m_dispatcher; - }; - - class PLATFORM_EXPORT Callback : public protocol::BackendCallback { - public: - Callback(std::unique_ptr<WeakPtr> backendImpl, int callId); - virtual ~Callback(); - void dispose(); - - protected: - void sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const ErrorString& invocationError); - - private: - std::unique_ptr<WeakPtr> m_backendImpl; - int m_callId; - }; - - explicit DispatcherBase(FrontendChannel*); - virtual ~DispatcherBase(); - - enum CommonErrorCode { - ParseError = -32700, - InvalidRequest = -32600, - MethodNotFound = -32601, - InvalidParams = -32602, - InternalError = -32603, - ServerError = -32000, - }; - - static bool getCommandName(const String16& message, String16* result); - - virtual void dispatch(int callId, const String16& method, std::unique_ptr<protocol::DictionaryValue> messageObject) = 0; - - void sendResponse(int callId, const ErrorString&, ErrorSupport*, std::unique_ptr<protocol::DictionaryValue> result); - void sendResponse(int callId, const ErrorString&, std::unique_ptr<protocol::DictionaryValue> result); - void sendResponse(int callId, const ErrorString&); - - void reportProtocolError(int callId, CommonErrorCode, const String16& errorMessage, ErrorSupport* errors); - void clearFrontend(); - - std::unique_ptr<WeakPtr> weakPtr(); - -private: - FrontendChannel* m_frontendChannel; - protocol::HashSet<WeakPtr*> m_weakPtrs; -}; - -class PLATFORM_EXPORT UberDispatcher { - PROTOCOL_DISALLOW_COPY(UberDispatcher); -public: - explicit UberDispatcher(FrontendChannel*); - void registerBackend(const String16& name, std::unique_ptr<protocol::DispatcherBase>); - void dispatch(const String16& message); - FrontendChannel* channel() { return m_frontendChannel; } - virtual ~UberDispatcher(); - -private: - FrontendChannel* m_frontendChannel; - protocol::HashMap<String16, std::unique_ptr<protocol::DispatcherBase>> m_dispatchers; -}; - -} // namespace platform -} // namespace blink - -#endif // !defined(DispatcherBase_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/DispatcherBase_cpp.template b/third_party/WebKit/Source/platform/inspector_protocol/DispatcherBase_cpp.template new file mode 100644 index 0000000..2f842e7 --- /dev/null +++ b/third_party/WebKit/Source/platform/inspector_protocol/DispatcherBase_cpp.template
@@ -0,0 +1,168 @@ +// Copyright 2016 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. + +namespace blink { +namespace protocol { + +// static +const char DispatcherBase::kInvalidRequest[] = "Invalid request"; + +DispatcherBase::WeakPtr::WeakPtr(DispatcherBase* dispatcher) : m_dispatcher(dispatcher) { } + +DispatcherBase::WeakPtr::~WeakPtr() +{ + if (m_dispatcher) + m_dispatcher->m_weakPtrs.erase(this); +} + +DispatcherBase::Callback::Callback(std::unique_ptr<DispatcherBase::WeakPtr> backendImpl, int callId) + : m_backendImpl(std::move(backendImpl)) + , m_callId(callId) { } + +DispatcherBase::Callback::~Callback() = default; + +void DispatcherBase::Callback::dispose() +{ + m_backendImpl = nullptr; +} + +void DispatcherBase::Callback::sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const ErrorString& invocationError) +{ + if (!m_backendImpl || !m_backendImpl->get()) + return; + m_backendImpl->get()->sendResponse(m_callId, invocationError, nullptr, std::move(partialMessage)); + m_backendImpl = nullptr; +} + +DispatcherBase::DispatcherBase(FrontendChannel* frontendChannel) + : m_frontendChannel(frontendChannel) { } + +DispatcherBase::~DispatcherBase() +{ + clearFrontend(); +} + +// static +bool DispatcherBase::getCommandName(const String16& message, String16* result) +{ + std::unique_ptr<protocol::Value> value = parseJSON(message); + if (!value) + return false; + + protocol::DictionaryValue* object = DictionaryValue::cast(value.get()); + if (!object) + return false; + + if (!object->getString("method", result)) + return false; + + return true; +} + +void DispatcherBase::sendResponse(int callId, const ErrorString& invocationError, ErrorSupport* errors, std::unique_ptr<protocol::DictionaryValue> result) +{ + if (invocationError.length() || (errors && errors->hasErrors())) { + reportProtocolError(callId, ServerError, invocationError, errors); + return; + } + + std::unique_ptr<protocol::DictionaryValue> responseMessage = DictionaryValue::create(); + responseMessage->setInteger("id", callId); + responseMessage->setObject("result", std::move(result)); + if (m_frontendChannel) + m_frontendChannel->sendProtocolResponse(callId, responseMessage->toJSONString()); +} + +void DispatcherBase::sendResponse(int callId, const ErrorString& invocationError, std::unique_ptr<protocol::DictionaryValue> result) +{ + sendResponse(callId, invocationError, nullptr, std::move(result)); +} + +void DispatcherBase::sendResponse(int callId, const ErrorString& invocationError) +{ + sendResponse(callId, invocationError, nullptr, DictionaryValue::create()); +} + +static void reportProtocolError(FrontendChannel* frontendChannel, int callId, DispatcherBase::CommonErrorCode code, const String16& errorMessage, ErrorSupport* errors) +{ + std::unique_ptr<protocol::DictionaryValue> error = DictionaryValue::create(); + error->setInteger("code", code); + error->setString("message", errorMessage); + DCHECK(error); + if (errors && errors->hasErrors()) + error->setString("data", errors->errors()); + std::unique_ptr<protocol::DictionaryValue> message = DictionaryValue::create(); + message->setObject("error", std::move(error)); + message->setInteger("id", callId); + frontendChannel->sendProtocolResponse(callId, message->toJSONString()); +} + +void DispatcherBase::reportProtocolError(int callId, CommonErrorCode code, const String16& errorMessage, ErrorSupport* errors) +{ + if (m_frontendChannel) + ::blink::protocol::reportProtocolError(m_frontendChannel, callId, code, errorMessage, errors); +} + +void DispatcherBase::clearFrontend() +{ + m_frontendChannel = nullptr; + for (auto& weak : m_weakPtrs) + weak->dispose(); + m_weakPtrs.clear(); +} + +std::unique_ptr<DispatcherBase::WeakPtr> DispatcherBase::weakPtr() +{ + std::unique_ptr<DispatcherBase::WeakPtr> weak(new DispatcherBase::WeakPtr(this)); + m_weakPtrs.insert(weak.get()); + return weak; +} + +UberDispatcher::UberDispatcher(FrontendChannel* frontendChannel) + : m_frontendChannel(frontendChannel) { } + +void UberDispatcher::registerBackend(const String16& name, std::unique_ptr<protocol::DispatcherBase> dispatcher) +{ + m_dispatchers[name] = std::move(dispatcher); +} + +void UberDispatcher::dispatch(const String16& message) +{ + std::unique_ptr<protocol::Value> parsedMessage = parseJSON(message); + if (!parsedMessage) + return; + std::unique_ptr<protocol::DictionaryValue> messageObject = DictionaryValue::cast(std::move(parsedMessage)); + if (!messageObject) + return; + + int callId = 0; + protocol::Value* callIdValue = messageObject->get("id"); + bool success = callIdValue->asInteger(&callId); + if (!success) + return; + + protocol::Value* methodValue = messageObject->get("method"); + String16 method; + success = methodValue && methodValue->asString(&method); + if (!success) + return; + + size_t dotIndex = method.find("."); + if (dotIndex == String16::kNotFound) { + reportProtocolError(m_frontendChannel, callId, DispatcherBase::MethodNotFound, "'" + method + "' wasn't found", nullptr); + return; + } + String16 domain = method.substring(0, dotIndex); + auto it = m_dispatchers.find(domain); + if (it == m_dispatchers.end()) { + reportProtocolError(m_frontendChannel, callId, DispatcherBase::MethodNotFound, "'" + method + "' wasn't found", nullptr); + return; + } + it->second->dispatch(callId, method, std::move(messageObject)); +} + +UberDispatcher::~UberDispatcher() = default; + +} // namespace protocol +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/DispatcherBase_h.template b/third_party/WebKit/Source/platform/inspector_protocol/DispatcherBase_h.template new file mode 100644 index 0000000..76b7958 --- /dev/null +++ b/third_party/WebKit/Source/platform/inspector_protocol/DispatcherBase_h.template
@@ -0,0 +1,98 @@ +// Copyright 2016 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 DispatcherBase_h +#define DispatcherBase_h + +//#include "BackendCallback.h" +//#include "Collections.h" +//#include "ErrorSupport.h" +//#include "Platform.h" +//#include "String16.h" +//#include "Values.h" +#include "{{export_macro_include}}" + +namespace blink { +namespace protocol { + +class FrontendChannel; +class WeakPtr; + +class {{export_macro}} DispatcherBase { + PROTOCOL_DISALLOW_COPY(DispatcherBase); +public: + static const char kInvalidRequest[]; + class {{export_macro}} WeakPtr { + public: + explicit WeakPtr(DispatcherBase*); + ~WeakPtr(); + DispatcherBase* get() { return m_dispatcher; } + void dispose() { m_dispatcher = nullptr; } + + private: + DispatcherBase* m_dispatcher; + }; + + class {{export_macro}} Callback : public protocol::BackendCallback { + public: + Callback(std::unique_ptr<WeakPtr> backendImpl, int callId); + virtual ~Callback(); + void dispose(); + + protected: + void sendIfActive(std::unique_ptr<protocol::DictionaryValue> partialMessage, const ErrorString& invocationError); + + private: + std::unique_ptr<WeakPtr> m_backendImpl; + int m_callId; + }; + + explicit DispatcherBase(FrontendChannel*); + virtual ~DispatcherBase(); + + enum CommonErrorCode { + ParseError = -32700, + InvalidRequest = -32600, + MethodNotFound = -32601, + InvalidParams = -32602, + InternalError = -32603, + ServerError = -32000, + }; + + static bool getCommandName(const String16& message, String16* result); + + virtual void dispatch(int callId, const String16& method, std::unique_ptr<protocol::DictionaryValue> messageObject) = 0; + + void sendResponse(int callId, const ErrorString&, ErrorSupport*, std::unique_ptr<protocol::DictionaryValue> result); + void sendResponse(int callId, const ErrorString&, std::unique_ptr<protocol::DictionaryValue> result); + void sendResponse(int callId, const ErrorString&); + + void reportProtocolError(int callId, CommonErrorCode, const String16& errorMessage, ErrorSupport* errors); + void clearFrontend(); + + std::unique_ptr<WeakPtr> weakPtr(); + +private: + FrontendChannel* m_frontendChannel; + protocol::HashSet<WeakPtr*> m_weakPtrs; +}; + +class {{export_macro}} UberDispatcher { + PROTOCOL_DISALLOW_COPY(UberDispatcher); +public: + explicit UberDispatcher(FrontendChannel*); + void registerBackend(const String16& name, std::unique_ptr<protocol::DispatcherBase>); + void dispatch(const String16& message); + FrontendChannel* channel() { return m_frontendChannel; } + virtual ~UberDispatcher(); + +private: + FrontendChannel* m_frontendChannel; + protocol::HashMap<String16, std::unique_ptr<protocol::DispatcherBase>> m_dispatchers; +}; + +} // namespace platform +} // namespace blink + +#endif // !defined(DispatcherBase_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/ErrorSupport.cpp b/third_party/WebKit/Source/platform/inspector_protocol/ErrorSupport.cpp deleted file mode 100644 index 0ad89ade..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/ErrorSupport.cpp +++ /dev/null
@@ -1,70 +0,0 @@ -// Copyright 2016 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 "platform/inspector_protocol/ErrorSupport.h" - -#include "platform/inspector_protocol/String16.h" - -namespace blink { -namespace protocol { - -ErrorSupport::ErrorSupport() : m_errorString(nullptr) { } -ErrorSupport::ErrorSupport(String16* errorString) : m_errorString(errorString) { } -ErrorSupport::~ErrorSupport() -{ - if (m_errorString && hasErrors()) { - String16Builder builder; - builder.append("Internal error(s): "); - builder.append(errors()); - *m_errorString = builder.toString(); - } -} - -void ErrorSupport::setName(const String16& name) -{ - DCHECK(m_path.size()); - m_path[m_path.size() - 1] = name; -} - -void ErrorSupport::push() -{ - m_path.push_back(String16()); -} - -void ErrorSupport::pop() -{ - m_path.pop_back(); -} - -void ErrorSupport::addError(const String16& error) -{ - String16Builder builder; - for (size_t i = 0; i < m_path.size(); ++i) { - if (i) - builder.append('.'); - builder.append(m_path[i]); - } - builder.append(": "); - builder.append(error); - m_errors.push_back(builder.toString()); -} - -bool ErrorSupport::hasErrors() -{ - return m_errors.size(); -} - -String16 ErrorSupport::errors() -{ - String16Builder builder; - for (size_t i = 0; i < m_errors.size(); ++i) { - if (i) - builder.append("; "); - builder.append(m_errors[i]); - } - return builder.toString(); -} - -} // namespace protocol -} // namespace blink
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/ErrorSupport.h b/third_party/WebKit/Source/platform/inspector_protocol/ErrorSupport.h deleted file mode 100644 index 56ac442..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/ErrorSupport.h +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2016 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 ErrorSupport_h -#define ErrorSupport_h - -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" - -#include <vector> - -namespace blink { -namespace protocol { - -using ErrorString = String16; - -class PLATFORM_EXPORT ErrorSupport { -public: - ErrorSupport(); - ErrorSupport(String16* errorString); - ~ErrorSupport(); - - void push(); - void setName(const String16&); - void pop(); - void addError(const String16&); - bool hasErrors(); - String16 errors(); - -private: - std::vector<String16> m_path; - std::vector<String16> m_errors; - String16* m_errorString; -}; - -} // namespace platform -} // namespace blink - -using blink::protocol::ErrorString; - -#endif // !defined(ErrorSupport_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/ErrorSupport_cpp.template b/third_party/WebKit/Source/platform/inspector_protocol/ErrorSupport_cpp.template new file mode 100644 index 0000000..695cb58d --- /dev/null +++ b/third_party/WebKit/Source/platform/inspector_protocol/ErrorSupport_cpp.template
@@ -0,0 +1,66 @@ +// Copyright 2016 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. + +namespace blink { +namespace protocol { + +ErrorSupport::ErrorSupport() : m_errorString(nullptr) { } +ErrorSupport::ErrorSupport(String16* errorString) : m_errorString(errorString) { } +ErrorSupport::~ErrorSupport() +{ + if (m_errorString && hasErrors()) { + String16Builder builder; + builder.append("Internal error(s): "); + builder.append(errors()); + *m_errorString = builder.toString(); + } +} + +void ErrorSupport::setName(const String16& name) +{ + DCHECK(m_path.size()); + m_path[m_path.size() - 1] = name; +} + +void ErrorSupport::push() +{ + m_path.push_back(String16()); +} + +void ErrorSupport::pop() +{ + m_path.pop_back(); +} + +void ErrorSupport::addError(const String16& error) +{ + String16Builder builder; + for (size_t i = 0; i < m_path.size(); ++i) { + if (i) + builder.append('.'); + builder.append(m_path[i]); + } + builder.append(": "); + builder.append(error); + m_errors.push_back(builder.toString()); +} + +bool ErrorSupport::hasErrors() +{ + return m_errors.size(); +} + +String16 ErrorSupport::errors() +{ + String16Builder builder; + for (size_t i = 0; i < m_errors.size(); ++i) { + if (i) + builder.append("; "); + builder.append(m_errors[i]); + } + return builder.toString(); +} + +} // namespace protocol +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/ErrorSupport_h.template b/third_party/WebKit/Source/platform/inspector_protocol/ErrorSupport_h.template new file mode 100644 index 0000000..50557c0 --- /dev/null +++ b/third_party/WebKit/Source/platform/inspector_protocol/ErrorSupport_h.template
@@ -0,0 +1,43 @@ +// Copyright 2016 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 ErrorSupport_h +#define ErrorSupport_h + +//#include "Platform.h" +//#include "String16.h" +#include "{{export_macro_include}}" + +#include <vector> + +namespace blink { +namespace protocol { + +using ErrorString = String16; + +class {{export_macro}} ErrorSupport { +public: + ErrorSupport(); + ErrorSupport(String16* errorString); + ~ErrorSupport(); + + void push(); + void setName(const String16&); + void pop(); + void addError(const String16&); + bool hasErrors(); + String16 errors(); + +private: + std::vector<String16> m_path; + std::vector<String16> m_errors; + String16* m_errorString; +}; + +} // namespace platform +} // namespace blink + +using blink::protocol::ErrorString; + +#endif // !defined(ErrorSupport_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Exported_h.template b/third_party/WebKit/Source/platform/inspector_protocol/Exported_h.template index 5cfabc5..116a441 100644 --- a/third_party/WebKit/Source/platform/inspector_protocol/Exported_h.template +++ b/third_party/WebKit/Source/platform/inspector_protocol/Exported_h.template
@@ -7,12 +7,8 @@ #ifndef protocol_{{domain.domain}}_api_h #define protocol_{{domain.domain}}_api_h -{% if export_macro == "PLATFORM_EXPORT" %} -#include "platform/inspector_protocol/Platform.h" -{% else %} -#include "core/CoreExport.h" -{% endif %} -#include "platform/inspector_protocol/String16.h" +#include "{{export_macro_include}}" +#include "{{lib_package}}/InspectorProtocol.h" namespace blink { namespace protocol {
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/FrontendChannel.h b/third_party/WebKit/Source/platform/inspector_protocol/FrontendChannel.h deleted file mode 100644 index ee81e951..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/FrontendChannel.h +++ /dev/null
@@ -1,24 +0,0 @@ -// Copyright 2016 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 FrontendChannel_h -#define FrontendChannel_h - -#include "platform/inspector_protocol/Values.h" - -namespace blink { -namespace protocol { - -class PLATFORM_EXPORT FrontendChannel { -public: - virtual ~FrontendChannel() { } - virtual void sendProtocolResponse(int callId, const String16& message) = 0; - virtual void sendProtocolNotification(const String16& message) = 0; - virtual void flushProtocolNotifications() = 0; -}; - -} // namespace protocol -} // namespace blink - -#endif // !defined(FrontendChannel_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/FrontendChannel_h.template b/third_party/WebKit/Source/platform/inspector_protocol/FrontendChannel_h.template new file mode 100644 index 0000000..0b7025fa --- /dev/null +++ b/third_party/WebKit/Source/platform/inspector_protocol/FrontendChannel_h.template
@@ -0,0 +1,25 @@ +// Copyright 2016 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 FrontendChannel_h +#define FrontendChannel_h + +//#include "String16.h" +#include "{{export_macro_include}}" + +namespace blink { +namespace protocol { + +class {{export_macro}} FrontendChannel { +public: + virtual ~FrontendChannel() { } + virtual void sendProtocolResponse(int callId, const String16& message) = 0; + virtual void sendProtocolNotification(const String16& message) = 0; + virtual void flushProtocolNotifications() = 0; +}; + +} // namespace protocol +} // namespace blink + +#endif // !defined(FrontendChannel_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Imported_h.template b/third_party/WebKit/Source/platform/inspector_protocol/Imported_h.template index a9abdad..2dd30bc 100644 --- a/third_party/WebKit/Source/platform/inspector_protocol/Imported_h.template +++ b/third_party/WebKit/Source/platform/inspector_protocol/Imported_h.template
@@ -7,10 +7,8 @@ #ifndef protocol_{{domain.domain}}_imported_h #define protocol_{{domain.domain}}_imported_h -#include "platform/inspector_protocol/ErrorSupport.h" -#include "platform/inspector_protocol/ValueConversions.h" -#include "platform/inspector_protocol/Values.h" -#include "{{include_package}}/{{domain.domain}}.h" +#include "{{lib_package}}/InspectorProtocol.h" +#include "{{imported_package}}/{{domain.domain}}.h" namespace blink { namespace protocol {
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/InspectorProtocol_cpp.template b/third_party/WebKit/Source/platform/inspector_protocol/InspectorProtocol_cpp.template new file mode 100644 index 0000000..153dbf00 --- /dev/null +++ b/third_party/WebKit/Source/platform/inspector_protocol/InspectorProtocol_cpp.template
@@ -0,0 +1,5 @@ +// Copyright 2016 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 "{{lib_package}}/InspectorProtocol.h"
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Maybe.h b/third_party/WebKit/Source/platform/inspector_protocol/Maybe.h deleted file mode 100644 index cf372e0..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/Maybe.h +++ /dev/null
@@ -1,91 +0,0 @@ -// Copyright 2016 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 Maybe_h -#define Maybe_h - -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" - -#include <memory> - -namespace blink { -namespace protocol { - -class String16; - -template<typename T> -class Maybe { -public: - Maybe() : m_value() { } - Maybe(std::unique_ptr<T> value) : m_value(std::move(value)) { } - void operator=(std::unique_ptr<T> value) { m_value = std::move(value); } - T* fromJust() const { DCHECK(m_value); return m_value.get(); } - T* fromMaybe(T* defaultValue) const { return m_value ? m_value.get() : defaultValue; } - bool isJust() const { return !!m_value; } - std::unique_ptr<T> takeJust() { DCHECK(m_value); return m_value.release(); } -private: - std::unique_ptr<T> m_value; -}; - -template<typename T> -class MaybeBase { -public: - MaybeBase() : m_isJust(false) { } - MaybeBase(T value) : m_isJust(true), m_value(value) { } - void operator=(T value) { m_value = value; m_isJust = true; } - T fromJust() const { DCHECK(m_isJust); return m_value; } - T fromMaybe(const T& defaultValue) const { return m_isJust ? m_value : defaultValue; } - bool isJust() const { return m_isJust; } - T takeJust() { DCHECK(m_isJust); return m_value; } - -protected: - bool m_isJust; - T m_value; -}; - -template<> -class Maybe<bool> : public MaybeBase<bool> { -public: - Maybe() { } - Maybe(bool value) : MaybeBase(value) { } - using MaybeBase::operator=; -}; - -template<> -class Maybe<int> : public MaybeBase<int> { -public: - Maybe() { } - Maybe(int value) : MaybeBase(value) { } - using MaybeBase::operator=; -}; - -template<> -class Maybe<double> : public MaybeBase<double> { -public: - Maybe() { } - Maybe(double value) : MaybeBase(value) { } - using MaybeBase::operator=; -}; - -template<> -class Maybe<String> : public MaybeBase<String> { -public: - Maybe() { } - Maybe(const String& value) : MaybeBase(value) { } - using MaybeBase::operator=; -}; - -template<> -class Maybe<String16> : public MaybeBase<String16> { -public: - Maybe() { } - Maybe(const String16& value) : MaybeBase(value) { } - using MaybeBase::operator=; -}; - -} // namespace platform -} // namespace blink - -#endif // !defined(Maybe_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Maybe_h.template b/third_party/WebKit/Source/platform/inspector_protocol/Maybe_h.template new file mode 100644 index 0000000..e15ac070 --- /dev/null +++ b/third_party/WebKit/Source/platform/inspector_protocol/Maybe_h.template
@@ -0,0 +1,87 @@ +// Copyright 2016 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 Maybe_h +#define Maybe_h + +//#include "Platform.h" +//#include "String16.h" + +namespace blink { +namespace protocol { + +template<typename T> +class Maybe { +public: + Maybe() : m_value() { } + Maybe(std::unique_ptr<T> value) : m_value(std::move(value)) { } + void operator=(std::unique_ptr<T> value) { m_value = std::move(value); } + T* fromJust() const { DCHECK(m_value); return m_value.get(); } + T* fromMaybe(T* defaultValue) const { return m_value ? m_value.get() : defaultValue; } + bool isJust() const { return !!m_value; } + std::unique_ptr<T> takeJust() { DCHECK(m_value); return m_value.release(); } +private: + std::unique_ptr<T> m_value; +}; + +template<typename T> +class MaybeBase { +public: + MaybeBase() : m_isJust(false) { } + MaybeBase(T value) : m_isJust(true), m_value(value) { } + void operator=(T value) { m_value = value; m_isJust = true; } + T fromJust() const { DCHECK(m_isJust); return m_value; } + T fromMaybe(const T& defaultValue) const { return m_isJust ? m_value : defaultValue; } + bool isJust() const { return m_isJust; } + T takeJust() { DCHECK(m_isJust); return m_value; } + +protected: + bool m_isJust; + T m_value; +}; + +template<> +class Maybe<bool> : public MaybeBase<bool> { +public: + Maybe() { } + Maybe(bool value) : MaybeBase(value) { } + using MaybeBase::operator=; +}; + +template<> +class Maybe<int> : public MaybeBase<int> { +public: + Maybe() { } + Maybe(int value) : MaybeBase(value) { } + using MaybeBase::operator=; +}; + +template<> +class Maybe<double> : public MaybeBase<double> { +public: + Maybe() { } + Maybe(double value) : MaybeBase(value) { } + using MaybeBase::operator=; +}; + +template<> +class Maybe<InspectorProtocolConvenienceStringType> : public MaybeBase<InspectorProtocolConvenienceStringType> { +public: + Maybe() { } + Maybe(const InspectorProtocolConvenienceStringType& value) : MaybeBase(value) { } + using MaybeBase::operator=; +}; + +template<> +class Maybe<String16> : public MaybeBase<String16> { +public: + Maybe() { } + Maybe(const String16& value) : MaybeBase(value) { } + using MaybeBase::operator=; +}; + +} // namespace platform +} // namespace blink + +#endif // !defined(Maybe_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Object.cpp b/third_party/WebKit/Source/platform/inspector_protocol/Object.cpp deleted file mode 100644 index 7bb007d4..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/Object.cpp +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright 2016 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 "platform/inspector_protocol/Object.h" - -namespace blink { -namespace protocol { - -std::unique_ptr<Object> Object::parse(protocol::Value* value, ErrorSupport* errors) -{ - protocol::DictionaryValue* object = DictionaryValue::cast(value); - if (!object) { - errors->addError("object expected"); - return nullptr; - } - return wrapUnique(new Object(wrapUnique(static_cast<DictionaryValue*>(object->clone().release())))); -} - -std::unique_ptr<protocol::DictionaryValue> Object::serialize() const -{ - return DictionaryValue::cast(m_object->clone()); -} - -std::unique_ptr<Object> Object::clone() const -{ - return wrapUnique(new Object(DictionaryValue::cast(m_object->clone()))); -} - -Object::Object(std::unique_ptr<protocol::DictionaryValue> object) : m_object(std::move(object)) { } - -Object::~Object() { } - -} // namespace protocol -} // namespace blink
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Object.h b/third_party/WebKit/Source/platform/inspector_protocol/Object.h deleted file mode 100644 index 22506c0..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/Object.h +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright 2016 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 Object_h -#define Object_h - -#include "platform/inspector_protocol/ErrorSupport.h" -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/Values.h" - -namespace blink { -namespace protocol { - -class PLATFORM_EXPORT Object { -public: - static std::unique_ptr<Object> parse(protocol::Value*, ErrorSupport*); - ~Object(); - - std::unique_ptr<protocol::DictionaryValue> serialize() const; - std::unique_ptr<Object> clone() const; -private: - explicit Object(std::unique_ptr<protocol::DictionaryValue>); - std::unique_ptr<protocol::DictionaryValue> m_object; -}; - -} // namespace platform -} // namespace blink - -#endif // !defined(Object_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Object_cpp.template b/third_party/WebKit/Source/platform/inspector_protocol/Object_cpp.template new file mode 100644 index 0000000..4480d85 --- /dev/null +++ b/third_party/WebKit/Source/platform/inspector_protocol/Object_cpp.template
@@ -0,0 +1,33 @@ +// Copyright 2016 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. + +namespace blink { +namespace protocol { + +std::unique_ptr<Object> Object::parse(protocol::Value* value, ErrorSupport* errors) +{ + protocol::DictionaryValue* object = DictionaryValue::cast(value); + if (!object) { + errors->addError("object expected"); + return nullptr; + } + return wrapUnique(new Object(wrapUnique(static_cast<DictionaryValue*>(object->clone().release())))); +} + +std::unique_ptr<protocol::DictionaryValue> Object::serialize() const +{ + return DictionaryValue::cast(m_object->clone()); +} + +std::unique_ptr<Object> Object::clone() const +{ + return wrapUnique(new Object(DictionaryValue::cast(m_object->clone()))); +} + +Object::Object(std::unique_ptr<protocol::DictionaryValue> object) : m_object(std::move(object)) { } + +Object::~Object() { } + +} // namespace protocol +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Object_h.template b/third_party/WebKit/Source/platform/inspector_protocol/Object_h.template new file mode 100644 index 0000000..8b3e3ec --- /dev/null +++ b/third_party/WebKit/Source/platform/inspector_protocol/Object_h.template
@@ -0,0 +1,31 @@ +// Copyright 2016 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 Object_h +#define Object_h + +//#include "ErrorSupport.h" +//#include "Platform.h" +//#include "Values.h" +#include "{{export_macro_include}}" + +namespace blink { +namespace protocol { + +class {{export_macro}} Object { +public: + static std::unique_ptr<Object> parse(protocol::Value*, ErrorSupport*); + ~Object(); + + std::unique_ptr<protocol::DictionaryValue> serialize() const; + std::unique_ptr<Object> clone() const; +private: + explicit Object(std::unique_ptr<protocol::DictionaryValue>); + std::unique_ptr<protocol::DictionaryValue> m_object; +}; + +} // namespace platform +} // namespace blink + +#endif // !defined(Object_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Parser.cpp b/third_party/WebKit/Source/platform/inspector_protocol/Parser.cpp deleted file mode 100644 index 4193108..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/Parser.cpp +++ /dev/null
@@ -1,499 +0,0 @@ -// Copyright 2016 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 "platform/inspector_protocol/Parser.h" - -#include "platform/inspector_protocol/String16.h" -#include "platform/inspector_protocol/Values.h" - -namespace blink { -namespace protocol { - -namespace { - -const int stackLimit = 1000; - -enum Token { - ObjectBegin, - ObjectEnd, - ArrayBegin, - ArrayEnd, - StringLiteral, - Number, - BoolTrue, - BoolFalse, - NullToken, - ListSeparator, - ObjectPairSeparator, - InvalidToken, -}; - -const char* const nullString = "null"; -const char* const trueString = "true"; -const char* const falseString = "false"; - -bool parseConstToken(const UChar* start, const UChar* end, const UChar** tokenEnd, const char* token) -{ - while (start < end && *token != '\0' && *start++ == *token++) { } - if (*token != '\0') - return false; - *tokenEnd = start; - return true; -} - -bool readInt(const UChar* start, const UChar* end, const UChar** tokenEnd, bool canHaveLeadingZeros) -{ - if (start == end) - return false; - bool haveLeadingZero = '0' == *start; - int length = 0; - while (start < end && '0' <= *start && *start <= '9') { - ++start; - ++length; - } - if (!length) - return false; - if (!canHaveLeadingZeros && length > 1 && haveLeadingZero) - return false; - *tokenEnd = start; - return true; -} - -bool parseNumberToken(const UChar* start, const UChar* end, const UChar** tokenEnd) -{ - // We just grab the number here. We validate the size in DecodeNumber. - // According to RFC4627, a valid number is: [minus] int [frac] [exp] - if (start == end) - return false; - UChar c = *start; - if ('-' == c) - ++start; - - if (!readInt(start, end, &start, false)) - return false; - if (start == end) { - *tokenEnd = start; - return true; - } - - // Optional fraction part - c = *start; - if ('.' == c) { - ++start; - if (!readInt(start, end, &start, true)) - return false; - if (start == end) { - *tokenEnd = start; - return true; - } - c = *start; - } - - // Optional exponent part - if ('e' == c || 'E' == c) { - ++start; - if (start == end) - return false; - c = *start; - if ('-' == c || '+' == c) { - ++start; - if (start == end) - return false; - } - if (!readInt(start, end, &start, true)) - return false; - } - - *tokenEnd = start; - return true; -} - -bool readHexDigits(const UChar* start, const UChar* end, const UChar** tokenEnd, int digits) -{ - if (end - start < digits) - return false; - for (int i = 0; i < digits; ++i) { - UChar c = *start++; - if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'))) - return false; - } - *tokenEnd = start; - return true; -} - -bool parseStringToken(const UChar* start, const UChar* end, const UChar** tokenEnd) -{ - while (start < end) { - UChar c = *start++; - if ('\\' == c) { - c = *start++; - // Make sure the escaped char is valid. - switch (c) { - case 'x': - if (!readHexDigits(start, end, &start, 2)) - return false; - break; - case 'u': - if (!readHexDigits(start, end, &start, 4)) - return false; - break; - case '\\': - case '/': - case 'b': - case 'f': - case 'n': - case 'r': - case 't': - case 'v': - case '"': - break; - default: - return false; - } - } else if ('"' == c) { - *tokenEnd = start; - return true; - } - } - return false; -} - -bool skipComment(const UChar* start, const UChar* end, const UChar** commentEnd) -{ - if (start == end) - return false; - - if (*start != '/' || start + 1 >= end) - return false; - ++start; - - if (*start == '/') { - // Single line comment, read to newline. - for (++start; start < end; ++start) { - if (*start == '\n' || *start == '\r') { - *commentEnd = start + 1; - return true; - } - } - *commentEnd = end; - // Comment reaches end-of-input, which is fine. - return true; - } - - if (*start == '*') { - UChar previous = '\0'; - // Block comment, read until end marker. - for (++start; start < end; previous = *start++) { - if (previous == '*' && *start == '/') { - *commentEnd = start + 1; - return true; - } - } - // Block comment must close before end-of-input. - return false; - } - - return false; -} - -void skipWhitespaceAndComments(const UChar* start, const UChar* end, const UChar** whitespaceEnd) -{ - while (start < end) { - if (isSpaceOrNewline(*start)) { - ++start; - } else if (*start == '/') { - const UChar* commentEnd; - if (!skipComment(start, end, &commentEnd)) - break; - start = commentEnd; - } else { - break; - } - } - *whitespaceEnd = start; -} - -Token parseToken(const UChar* start, const UChar* end, const UChar** tokenStart, const UChar** tokenEnd) -{ - skipWhitespaceAndComments(start, end, tokenStart); - start = *tokenStart; - - if (start == end) - return InvalidToken; - - switch (*start) { - case 'n': - if (parseConstToken(start, end, tokenEnd, nullString)) - return NullToken; - break; - case 't': - if (parseConstToken(start, end, tokenEnd, trueString)) - return BoolTrue; - break; - case 'f': - if (parseConstToken(start, end, tokenEnd, falseString)) - return BoolFalse; - break; - case '[': - *tokenEnd = start + 1; - return ArrayBegin; - case ']': - *tokenEnd = start + 1; - return ArrayEnd; - case ',': - *tokenEnd = start + 1; - return ListSeparator; - case '{': - *tokenEnd = start + 1; - return ObjectBegin; - case '}': - *tokenEnd = start + 1; - return ObjectEnd; - case ':': - *tokenEnd = start + 1; - return ObjectPairSeparator; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '-': - if (parseNumberToken(start, end, tokenEnd)) - return Number; - break; - case '"': - if (parseStringToken(start + 1, end, tokenEnd)) - return StringLiteral; - break; - } - return InvalidToken; -} - -inline int hexToInt(UChar c) -{ - if ('0' <= c && c <= '9') - return c - '0'; - if ('A' <= c && c <= 'F') - return c - 'A' + 10; - if ('a' <= c && c <= 'f') - return c - 'a' + 10; - NOTREACHED(); - return 0; -} - -bool decodeString(const UChar* start, const UChar* end, String16Builder* output) -{ - while (start < end) { - UChar c = *start++; - if ('\\' != c) { - output->append(c); - continue; - } - c = *start++; - - if (c == 'x') { - // \x is not supported. - return false; - } - - switch (c) { - case '"': - case '/': - case '\\': - break; - case 'b': - c = '\b'; - break; - case 'f': - c = '\f'; - break; - case 'n': - c = '\n'; - break; - case 'r': - c = '\r'; - break; - case 't': - c = '\t'; - break; - case 'v': - c = '\v'; - break; - case 'u': - c = (hexToInt(*start) << 12) + - (hexToInt(*(start + 1)) << 8) + - (hexToInt(*(start + 2)) << 4) + - hexToInt(*(start + 3)); - start += 4; - break; - default: - return false; - } - output->append(c); - } - return true; -} - -bool decodeString(const UChar* start, const UChar* end, String16* output) -{ - if (start == end) { - *output = ""; - return true; - } - if (start > end) - return false; - String16Builder buffer; - buffer.reserveCapacity(end - start); - if (!decodeString(start, end, &buffer)) - return false; - *output = buffer.toString(); - return true; -} - -std::unique_ptr<Value> buildValue(const UChar* start, const UChar* end, const UChar** valueTokenEnd, int depth) -{ - if (depth > stackLimit) - return nullptr; - - std::unique_ptr<Value> result; - const UChar* tokenStart; - const UChar* tokenEnd; - Token token = parseToken(start, end, &tokenStart, &tokenEnd); - switch (token) { - case InvalidToken: - return nullptr; - case NullToken: - result = Value::null(); - break; - case BoolTrue: - result = FundamentalValue::create(true); - break; - case BoolFalse: - result = FundamentalValue::create(false); - break; - case Number: { - bool ok; - double value = String16::charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok); - if (!ok) - return nullptr; - int number = static_cast<int>(value); - if (number == value) - result = FundamentalValue::create(number); - else - result = FundamentalValue::create(value); - break; - } - case StringLiteral: { - String16 value; - bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value); - if (!ok) - return nullptr; - result = StringValue::create(value); - break; - } - case ArrayBegin: { - std::unique_ptr<ListValue> array = ListValue::create(); - start = tokenEnd; - token = parseToken(start, end, &tokenStart, &tokenEnd); - while (token != ArrayEnd) { - std::unique_ptr<Value> arrayNode = buildValue(start, end, &tokenEnd, depth + 1); - if (!arrayNode) - return nullptr; - array->pushValue(std::move(arrayNode)); - - // After a list value, we expect a comma or the end of the list. - start = tokenEnd; - token = parseToken(start, end, &tokenStart, &tokenEnd); - if (token == ListSeparator) { - start = tokenEnd; - token = parseToken(start, end, &tokenStart, &tokenEnd); - if (token == ArrayEnd) - return nullptr; - } else if (token != ArrayEnd) { - // Unexpected value after list value. Bail out. - return nullptr; - } - } - if (token != ArrayEnd) - return nullptr; - result = std::move(array); - break; - } - case ObjectBegin: { - std::unique_ptr<DictionaryValue> object = DictionaryValue::create(); - start = tokenEnd; - token = parseToken(start, end, &tokenStart, &tokenEnd); - while (token != ObjectEnd) { - if (token != StringLiteral) - return nullptr; - String16 key; - if (!decodeString(tokenStart + 1, tokenEnd - 1, &key)) - return nullptr; - start = tokenEnd; - - token = parseToken(start, end, &tokenStart, &tokenEnd); - if (token != ObjectPairSeparator) - return nullptr; - start = tokenEnd; - - std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, depth + 1); - if (!value) - return nullptr; - object->setValue(key, std::move(value)); - start = tokenEnd; - - // After a key/value pair, we expect a comma or the end of the - // object. - token = parseToken(start, end, &tokenStart, &tokenEnd); - if (token == ListSeparator) { - start = tokenEnd; - token = parseToken(start, end, &tokenStart, &tokenEnd); - if (token == ObjectEnd) - return nullptr; - } else if (token != ObjectEnd) { - // Unexpected value after last object value. Bail out. - return nullptr; - } - } - if (token != ObjectEnd) - return nullptr; - result = std::move(object); - break; - } - - default: - // We got a token that's not a value. - return nullptr; - } - - skipWhitespaceAndComments(tokenEnd, end, valueTokenEnd); - return result; -} - -std::unique_ptr<Value> parseJSONInternal(const UChar* start, unsigned length) -{ - const UChar* end = start + length; - const UChar *tokenEnd; - std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, 0); - if (!value || tokenEnd != end) - return nullptr; - return value; -} - -} // anonymous namespace - -std::unique_ptr<Value> parseJSON(const String16& json) -{ - if (json.isEmpty()) - return nullptr; - return parseJSONInternal(json.characters16(), json.length()); -} - -} // namespace protocol -} // namespace blink
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Parser.h b/third_party/WebKit/Source/platform/inspector_protocol/Parser.h deleted file mode 100644 index c6f700e..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/Parser.h +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright 2016 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 Parser_h -#define Parser_h - -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" - -namespace blink { -namespace protocol { - -class Value; - -PLATFORM_EXPORT std::unique_ptr<Value> parseJSON(const String16& json); - -} // namespace platform -} // namespace blink - -#endif // !defined(Parser_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/ParserTest.cpp b/third_party/WebKit/Source/platform/inspector_protocol/ParserTest.cpp index 1a8f442..40c6af7 100644 --- a/third_party/WebKit/Source/platform/inspector_protocol/ParserTest.cpp +++ b/third_party/WebKit/Source/platform/inspector_protocol/ParserTest.cpp
@@ -2,10 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "platform/inspector_protocol/Parser.h" - -#include "platform/inspector_protocol/String16.h" -#include "platform/inspector_protocol/Values.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "testing/gtest/include/gtest/gtest.h" namespace blink {
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Parser_cpp.template b/third_party/WebKit/Source/platform/inspector_protocol/Parser_cpp.template new file mode 100644 index 0000000..34d8ff0 --- /dev/null +++ b/third_party/WebKit/Source/platform/inspector_protocol/Parser_cpp.template
@@ -0,0 +1,494 @@ +// Copyright 2016 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. + +namespace blink { +namespace protocol { + +namespace { + +const int stackLimit = 1000; + +enum Token { + ObjectBegin, + ObjectEnd, + ArrayBegin, + ArrayEnd, + StringLiteral, + Number, + BoolTrue, + BoolFalse, + NullToken, + ListSeparator, + ObjectPairSeparator, + InvalidToken, +}; + +const char* const nullString = "null"; +const char* const trueString = "true"; +const char* const falseString = "false"; + +bool parseConstToken(const UChar* start, const UChar* end, const UChar** tokenEnd, const char* token) +{ + while (start < end && *token != '\0' && *start++ == *token++) { } + if (*token != '\0') + return false; + *tokenEnd = start; + return true; +} + +bool readInt(const UChar* start, const UChar* end, const UChar** tokenEnd, bool canHaveLeadingZeros) +{ + if (start == end) + return false; + bool haveLeadingZero = '0' == *start; + int length = 0; + while (start < end && '0' <= *start && *start <= '9') { + ++start; + ++length; + } + if (!length) + return false; + if (!canHaveLeadingZeros && length > 1 && haveLeadingZero) + return false; + *tokenEnd = start; + return true; +} + +bool parseNumberToken(const UChar* start, const UChar* end, const UChar** tokenEnd) +{ + // We just grab the number here. We validate the size in DecodeNumber. + // According to RFC4627, a valid number is: [minus] int [frac] [exp] + if (start == end) + return false; + UChar c = *start; + if ('-' == c) + ++start; + + if (!readInt(start, end, &start, false)) + return false; + if (start == end) { + *tokenEnd = start; + return true; + } + + // Optional fraction part + c = *start; + if ('.' == c) { + ++start; + if (!readInt(start, end, &start, true)) + return false; + if (start == end) { + *tokenEnd = start; + return true; + } + c = *start; + } + + // Optional exponent part + if ('e' == c || 'E' == c) { + ++start; + if (start == end) + return false; + c = *start; + if ('-' == c || '+' == c) { + ++start; + if (start == end) + return false; + } + if (!readInt(start, end, &start, true)) + return false; + } + + *tokenEnd = start; + return true; +} + +bool readHexDigits(const UChar* start, const UChar* end, const UChar** tokenEnd, int digits) +{ + if (end - start < digits) + return false; + for (int i = 0; i < digits; ++i) { + UChar c = *start++; + if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'))) + return false; + } + *tokenEnd = start; + return true; +} + +bool parseStringToken(const UChar* start, const UChar* end, const UChar** tokenEnd) +{ + while (start < end) { + UChar c = *start++; + if ('\\' == c) { + c = *start++; + // Make sure the escaped char is valid. + switch (c) { + case 'x': + if (!readHexDigits(start, end, &start, 2)) + return false; + break; + case 'u': + if (!readHexDigits(start, end, &start, 4)) + return false; + break; + case '\\': + case '/': + case 'b': + case 'f': + case 'n': + case 'r': + case 't': + case 'v': + case '"': + break; + default: + return false; + } + } else if ('"' == c) { + *tokenEnd = start; + return true; + } + } + return false; +} + +bool skipComment(const UChar* start, const UChar* end, const UChar** commentEnd) +{ + if (start == end) + return false; + + if (*start != '/' || start + 1 >= end) + return false; + ++start; + + if (*start == '/') { + // Single line comment, read to newline. + for (++start; start < end; ++start) { + if (*start == '\n' || *start == '\r') { + *commentEnd = start + 1; + return true; + } + } + *commentEnd = end; + // Comment reaches end-of-input, which is fine. + return true; + } + + if (*start == '*') { + UChar previous = '\0'; + // Block comment, read until end marker. + for (++start; start < end; previous = *start++) { + if (previous == '*' && *start == '/') { + *commentEnd = start + 1; + return true; + } + } + // Block comment must close before end-of-input. + return false; + } + + return false; +} + +void skipWhitespaceAndComments(const UChar* start, const UChar* end, const UChar** whitespaceEnd) +{ + while (start < end) { + if (String16::isSpaceOrNewLine(*start)) { + ++start; + } else if (*start == '/') { + const UChar* commentEnd; + if (!skipComment(start, end, &commentEnd)) + break; + start = commentEnd; + } else { + break; + } + } + *whitespaceEnd = start; +} + +Token parseToken(const UChar* start, const UChar* end, const UChar** tokenStart, const UChar** tokenEnd) +{ + skipWhitespaceAndComments(start, end, tokenStart); + start = *tokenStart; + + if (start == end) + return InvalidToken; + + switch (*start) { + case 'n': + if (parseConstToken(start, end, tokenEnd, nullString)) + return NullToken; + break; + case 't': + if (parseConstToken(start, end, tokenEnd, trueString)) + return BoolTrue; + break; + case 'f': + if (parseConstToken(start, end, tokenEnd, falseString)) + return BoolFalse; + break; + case '[': + *tokenEnd = start + 1; + return ArrayBegin; + case ']': + *tokenEnd = start + 1; + return ArrayEnd; + case ',': + *tokenEnd = start + 1; + return ListSeparator; + case '{': + *tokenEnd = start + 1; + return ObjectBegin; + case '}': + *tokenEnd = start + 1; + return ObjectEnd; + case ':': + *tokenEnd = start + 1; + return ObjectPairSeparator; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '-': + if (parseNumberToken(start, end, tokenEnd)) + return Number; + break; + case '"': + if (parseStringToken(start + 1, end, tokenEnd)) + return StringLiteral; + break; + } + return InvalidToken; +} + +inline int hexToInt(UChar c) +{ + if ('0' <= c && c <= '9') + return c - '0'; + if ('A' <= c && c <= 'F') + return c - 'A' + 10; + if ('a' <= c && c <= 'f') + return c - 'a' + 10; + NOTREACHED(); + return 0; +} + +bool decodeString(const UChar* start, const UChar* end, String16Builder* output) +{ + while (start < end) { + UChar c = *start++; + if ('\\' != c) { + output->append(c); + continue; + } + c = *start++; + + if (c == 'x') { + // \x is not supported. + return false; + } + + switch (c) { + case '"': + case '/': + case '\\': + break; + case 'b': + c = '\b'; + break; + case 'f': + c = '\f'; + break; + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + case 'v': + c = '\v'; + break; + case 'u': + c = (hexToInt(*start) << 12) + + (hexToInt(*(start + 1)) << 8) + + (hexToInt(*(start + 2)) << 4) + + hexToInt(*(start + 3)); + start += 4; + break; + default: + return false; + } + output->append(c); + } + return true; +} + +bool decodeString(const UChar* start, const UChar* end, String16* output) +{ + if (start == end) { + *output = ""; + return true; + } + if (start > end) + return false; + String16Builder buffer; + buffer.reserveCapacity(end - start); + if (!decodeString(start, end, &buffer)) + return false; + *output = buffer.toString(); + return true; +} + +std::unique_ptr<Value> buildValue(const UChar* start, const UChar* end, const UChar** valueTokenEnd, int depth) +{ + if (depth > stackLimit) + return nullptr; + + std::unique_ptr<Value> result; + const UChar* tokenStart; + const UChar* tokenEnd; + Token token = parseToken(start, end, &tokenStart, &tokenEnd); + switch (token) { + case InvalidToken: + return nullptr; + case NullToken: + result = Value::null(); + break; + case BoolTrue: + result = FundamentalValue::create(true); + break; + case BoolFalse: + result = FundamentalValue::create(false); + break; + case Number: { + bool ok; + double value = String16::charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok); + if (!ok) + return nullptr; + int number = static_cast<int>(value); + if (number == value) + result = FundamentalValue::create(number); + else + result = FundamentalValue::create(value); + break; + } + case StringLiteral: { + String16 value; + bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value); + if (!ok) + return nullptr; + result = StringValue::create(value); + break; + } + case ArrayBegin: { + std::unique_ptr<ListValue> array = ListValue::create(); + start = tokenEnd; + token = parseToken(start, end, &tokenStart, &tokenEnd); + while (token != ArrayEnd) { + std::unique_ptr<Value> arrayNode = buildValue(start, end, &tokenEnd, depth + 1); + if (!arrayNode) + return nullptr; + array->pushValue(std::move(arrayNode)); + + // After a list value, we expect a comma or the end of the list. + start = tokenEnd; + token = parseToken(start, end, &tokenStart, &tokenEnd); + if (token == ListSeparator) { + start = tokenEnd; + token = parseToken(start, end, &tokenStart, &tokenEnd); + if (token == ArrayEnd) + return nullptr; + } else if (token != ArrayEnd) { + // Unexpected value after list value. Bail out. + return nullptr; + } + } + if (token != ArrayEnd) + return nullptr; + result = std::move(array); + break; + } + case ObjectBegin: { + std::unique_ptr<DictionaryValue> object = DictionaryValue::create(); + start = tokenEnd; + token = parseToken(start, end, &tokenStart, &tokenEnd); + while (token != ObjectEnd) { + if (token != StringLiteral) + return nullptr; + String16 key; + if (!decodeString(tokenStart + 1, tokenEnd - 1, &key)) + return nullptr; + start = tokenEnd; + + token = parseToken(start, end, &tokenStart, &tokenEnd); + if (token != ObjectPairSeparator) + return nullptr; + start = tokenEnd; + + std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, depth + 1); + if (!value) + return nullptr; + object->setValue(key, std::move(value)); + start = tokenEnd; + + // After a key/value pair, we expect a comma or the end of the + // object. + token = parseToken(start, end, &tokenStart, &tokenEnd); + if (token == ListSeparator) { + start = tokenEnd; + token = parseToken(start, end, &tokenStart, &tokenEnd); + if (token == ObjectEnd) + return nullptr; + } else if (token != ObjectEnd) { + // Unexpected value after last object value. Bail out. + return nullptr; + } + } + if (token != ObjectEnd) + return nullptr; + result = std::move(object); + break; + } + + default: + // We got a token that's not a value. + return nullptr; + } + + skipWhitespaceAndComments(tokenEnd, end, valueTokenEnd); + return result; +} + +std::unique_ptr<Value> parseJSONInternal(const UChar* start, unsigned length) +{ + const UChar* end = start + length; + const UChar *tokenEnd; + std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, 0); + if (!value || tokenEnd != end) + return nullptr; + return value; +} + +} // anonymous namespace + +std::unique_ptr<Value> parseJSON(const String16& json) +{ + if (json.isEmpty()) + return nullptr; + return parseJSONInternal(json.characters16(), json.length()); +} + +} // namespace protocol +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Parser_h.template b/third_party/WebKit/Source/platform/inspector_protocol/Parser_h.template new file mode 100644 index 0000000..eab025f --- /dev/null +++ b/third_party/WebKit/Source/platform/inspector_protocol/Parser_h.template
@@ -0,0 +1,22 @@ +// Copyright 2016 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 Parser_h +#define Parser_h + +//#include "Platform.h" +//#include "String16.h" +#include "{{export_macro_include}}" + +namespace blink { +namespace protocol { + +class Value; + +{{export_macro}} std::unique_ptr<Value> parseJSON(const String16& json); + +} // namespace platform +} // namespace blink + +#endif // !defined(Parser_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Platform.h b/third_party/WebKit/Source/platform/inspector_protocol/Platform.h deleted file mode 100644 index 76ba930..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/Platform.h +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright 2016 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 protocol_Platform_h -#define protocol_Platform_h - -#if V8_INSPECTOR_USE_STL -#include "platform/inspector_protocol/PlatformSTL.h" -#else -#include "platform/inspector_protocol/PlatformWTF.h" -#endif // V8_INSPECTOR_USE_STL - -#endif // !defined(protocol_Platform_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/PlatformSTL.h b/third_party/WebKit/Source/platform/inspector_protocol/PlatformSTL.h deleted file mode 100644 index 33ca199b..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/PlatformSTL.h +++ /dev/null
@@ -1,292 +0,0 @@ -// Copyright (c) 2016 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 PlatformSTL_h -#define PlatformSTL_h - -#include <memory> - -#define PLATFORM_EXPORT -#ifndef CHECK -#define CHECK(condition) ((void) 0) -#endif -#define DCHECK(condition) ((void) 0) -#define NOTREACHED() -#define DCHECK_EQ(i, j) DCHECK(i == j) -#define DCHECK_GE(i, j) DCHECK(i >= j) -#define DCHECK_LT(i, j) DCHECK(i < j) -#define DCHECK_GT(i, j) DCHECK(i > j) -template <typename T> -inline void USE(T) { } - -#define DEFINE_STATIC_LOCAL(type, name, arguments) \ - static type name; - -#if defined(__APPLE__) && !defined(_LIBCPP_VERSION) - -namespace std { - -template <typename T1, typename T2> -struct is_convertible { -private: - struct True_ { - char x[2]; - }; - struct False_ { - }; - - static True_ helper(T2 const &); - static False_ helper(...); - -public: - static bool const value = ( - sizeof(True_) == sizeof(is_convertible::helper(T1())) - ); -}; - -template <bool, class T = void> -struct enable_if { -}; - -template <class T> -struct enable_if<true, T> { - typedef T type; -}; - -template<class T> -struct remove_extent { - typedef T type; -}; - -template<class T> -struct remove_extent<T[]> { - typedef T type; -}; - -template<class T, std::size_t N> -struct remove_extent<T[N]> { - typedef T type; -}; - -typedef decltype(nullptr) nullptr_t; - -template<class T, T v> -struct integral_constant { - static constexpr T value = v; - typedef T value_type; - typedef integral_constant type; - constexpr operator value_type() const noexcept { return value; } - constexpr value_type operator()() const noexcept { return value; } -}; - -typedef integral_constant<bool, true> true_type; -typedef integral_constant<bool, false> false_type; - -template<class T> -struct is_array : false_type {}; - -template<class T> -struct is_array<T[]> : true_type {}; - -template<class T, std::size_t N> -struct is_array<T[N]> : true_type {}; - -template <typename T> -struct OwnedPtrDeleter { - static void deletePtr(T* ptr) - { - static_assert(sizeof(T) > 0, "type must be complete"); - delete ptr; - } -}; - -template <typename T> -struct OwnedPtrDeleter<T[]> { - static void deletePtr(T* ptr) - { - static_assert(sizeof(T) > 0, "type must be complete"); - delete[] ptr; - } -}; - -template <class T, int n> -struct OwnedPtrDeleter<T[n]> { - static_assert(sizeof(T) < 0, "do not use array with size as type"); -}; - -template <typename T> class unique_ptr { -public: - typedef typename remove_extent<T>::type ValueType; - typedef ValueType* PtrType; - - unique_ptr() : m_ptr(nullptr) {} - unique_ptr(std::nullptr_t) : m_ptr(nullptr) {} - unique_ptr(const unique_ptr&); - unique_ptr(unique_ptr&&); - template <typename U, typename = typename enable_if<is_convertible<U*, T*>::value>::type> unique_ptr(unique_ptr<U>&&); - - ~unique_ptr() - { - OwnedPtrDeleter<T>::deletePtr(m_ptr); - m_ptr = nullptr; - } - - PtrType get() const { return m_ptr; } - - void reset(PtrType = nullptr); - PtrType release() - { - return this->internalRelease(); - } - - ValueType& operator*() const { DCHECK(m_ptr); return *m_ptr; } - PtrType operator->() const { DCHECK(m_ptr); return m_ptr; } - - ValueType& operator[](std::ptrdiff_t i) const; - - bool operator!() const { return !m_ptr; } - explicit operator bool() const { return m_ptr; } - - unique_ptr& operator=(std::nullptr_t) { reset(); return *this; } - - unique_ptr& operator=(const unique_ptr&); - unique_ptr& operator=(unique_ptr&&); - template <typename U> unique_ptr& operator=(unique_ptr<U>&&); - - void swap(unique_ptr& o) { std::swap(m_ptr, o.m_ptr); } - - static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } - - explicit unique_ptr(PtrType ptr) : m_ptr(ptr) {} - -private: - PtrType internalRelease() const - { - PtrType ptr = m_ptr; - m_ptr = nullptr; - return ptr; - } - - // We should never have two unique_ptrs for the same underlying object - // (otherwise we'll get double-destruction), so these equality operators - // should never be needed. - template <typename U> bool operator==(const unique_ptr<U>&) const - { - static_assert(!sizeof(U*), "unique_ptrs should never be equal"); - return false; - } - template <typename U> bool operator!=(const unique_ptr<U>&) const - { - static_assert(!sizeof(U*), "unique_ptrs should never be equal"); - return false; - } - - mutable PtrType m_ptr; -}; - - -template <typename T> inline void unique_ptr<T>::reset(PtrType ptr) -{ - PtrType p = m_ptr; - m_ptr = ptr; - DCHECK(!p || m_ptr != p); - OwnedPtrDeleter<T>::deletePtr(p); -} - -template <typename T> inline typename unique_ptr<T>::ValueType& unique_ptr<T>::operator[](std::ptrdiff_t i) const -{ - static_assert(is_array<T>::value, "elements access is possible for arrays only"); - DCHECK(m_ptr); - DCHECK_GE(i, 0); - return m_ptr[i]; -} - -template <typename T> inline unique_ptr<T>::unique_ptr(const unique_ptr<T>& o) - : m_ptr(o.internalRelease()) -{ -} - -template <typename T> inline unique_ptr<T>::unique_ptr(unique_ptr<T>&& o) - : m_ptr(o.internalRelease()) -{ -} - -template <typename T> -template <typename U, typename> inline unique_ptr<T>::unique_ptr(unique_ptr<U>&& o) - : m_ptr(o.release()) -{ - static_assert(!is_array<T>::value, "pointers to array must never be converted"); -} - -template <typename T> inline unique_ptr<T>& unique_ptr<T>::operator=(const unique_ptr<T>& o) -{ - reset(o.internalRelease()); - return *this; -} - -template <typename T> inline unique_ptr<T>& unique_ptr<T>::operator=(unique_ptr<T>&& o) -{ - reset(o.internalRelease()); - return *this; -} - -template <typename T> -template <typename U> inline unique_ptr<T>& unique_ptr<T>::operator=(unique_ptr<U>&& o) -{ - static_assert(!is_array<T>::value, "pointers to array must never be converted"); - PtrType ptr = m_ptr; - m_ptr = o.release(); - DCHECK(!ptr || m_ptr != ptr); - OwnedPtrDeleter<T>::deletePtr(ptr); - - return *this; -} - -template <typename T> inline void swap(unique_ptr<T>& a, unique_ptr<T>& b) -{ - a.swap(b); -} - -template <typename T, typename U> inline bool operator==(const unique_ptr<T>& a, U* b) -{ - return a.get() == b; -} - -template <typename T, typename U> inline bool operator==(T* a, const unique_ptr<U>& b) -{ - return a == b.get(); -} - -template <typename T, typename U> inline bool operator!=(const unique_ptr<T>& a, U* b) -{ - return a.get() != b; -} - -template <typename T, typename U> inline bool operator!=(T* a, const unique_ptr<U>& b) -{ - return a != b.get(); -} - -template <typename T> inline typename unique_ptr<T>::PtrType getPtr(const unique_ptr<T>& p) -{ - return p.get(); -} - -template <typename T> -unique_ptr<T> move(unique_ptr<T>& ptr) -{ - return unique_ptr<T>(ptr.release()); -} - -} - -#endif // defined(__APPLE__) && !defined(_LIBCPP_VERSION) - -template <typename T> -std::unique_ptr<T> wrapUnique(T* ptr) -{ - return std::unique_ptr<T>(ptr); -} - -#endif // PlatformSTL_h
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Platform_h.template b/third_party/WebKit/Source/platform/inspector_protocol/Platform_h.template new file mode 100644 index 0000000..f09f192 --- /dev/null +++ b/third_party/WebKit/Source/platform/inspector_protocol/Platform_h.template
@@ -0,0 +1,10 @@ +// Copyright 2016 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 protocol_Platform_h +#define protocol_Platform_h + +#include "{{platform_impl_h_include}}" + +#endif // !defined(protocol_Platform_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/String16.h b/third_party/WebKit/Source/platform/inspector_protocol/String16.h deleted file mode 100644 index 6a1b4a09..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/String16.h +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright 2016 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 String16_h -#define String16_h - -#if V8_INSPECTOR_USE_STL -#include "platform/inspector_protocol/String16STL.h" -#else -#include "platform/inspector_protocol/String16WTF.h" -#endif // V8_INSPECTOR_USE_STL - -#endif // !defined(String16_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/String16STL.cpp b/third_party/WebKit/Source/platform/inspector_protocol/String16STL.cpp deleted file mode 100644 index 10c7fa6..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/String16STL.cpp +++ /dev/null
@@ -1,588 +0,0 @@ -// Copyright 2016 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 "platform/inspector_protocol/String16STL.h" - -#include "platform/inspector_protocol/Platform.h" - -#include <algorithm> -#include <cctype> -#include <cstdio> -#include <functional> -#include <locale> - -namespace blink { -namespace protocol { - -const UChar replacementCharacter = 0xFFFD; - -template<typename CharType> inline bool isASCII(CharType c) -{ - return !(c & ~0x7F); -} - -template<typename CharType> inline bool isASCIIAlpha(CharType c) -{ - return (c | 0x20) >= 'a' && (c | 0x20) <= 'z'; -} - -template<typename CharType> inline bool isASCIIDigit(CharType c) -{ - return c >= '0' && c <= '9'; -} - -template<typename CharType> inline bool isASCIIAlphanumeric(CharType c) -{ - return isASCIIDigit(c) || isASCIIAlpha(c); -} - -template<typename CharType> inline bool isASCIIHexDigit(CharType c) -{ - return isASCIIDigit(c) || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f'); -} - -template<typename CharType> inline bool isASCIIOctalDigit(CharType c) -{ - return (c >= '0') & (c <= '7'); -} - -template<typename CharType> inline bool isASCIIPrintable(CharType c) -{ - return c >= ' ' && c <= '~'; -} - -/* - Statistics from a run of Apple's page load test for callers of isASCIISpace: - - character count - --------- ----- - non-spaces 689383 - 20 space 294720 - 0A \n 89059 - 09 \t 28320 - 0D \r 0 - 0C \f 0 - 0B \v 0 - */ -template<typename CharType> inline bool isASCIISpace(CharType c) -{ - return c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9)); -} - -extern const LChar ASCIICaseFoldTable[256] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff -}; - -template<typename CharType> inline int toASCIIHexValue(CharType c) -{ - DCHECK(isASCIIHexDigit(c)); - return c < 'A' ? c - '0' : (c - 'A' + 10) & 0xF; -} - -template<typename CharType> inline int toASCIIHexValue(CharType upperValue, CharType lowerValue) -{ - DCHECK(isASCIIHexDigit(upperValue) && isASCIIHexDigit(lowerValue)); - return ((toASCIIHexValue(upperValue) << 4) & 0xF0) | toASCIIHexValue(lowerValue); -} - -inline char lowerNibbleToASCIIHexDigit(char c) -{ - char nibble = c & 0xF; - return nibble < 10 ? '0' + nibble : 'A' + nibble - 10; -} - -inline char upperNibbleToASCIIHexDigit(char c) -{ - char nibble = (c >> 4) & 0xF; - return nibble < 10 ? '0' + nibble : 'A' + nibble - 10; -} - -inline int inlineUTF8SequenceLengthNonASCII(char b0) -{ - if ((b0 & 0xC0) != 0xC0) - return 0; - if ((b0 & 0xE0) == 0xC0) - return 2; - if ((b0 & 0xF0) == 0xE0) - return 3; - if ((b0 & 0xF8) == 0xF0) - return 4; - return 0; -} - -inline int inlineUTF8SequenceLength(char b0) -{ - return isASCII(b0) ? 1 : inlineUTF8SequenceLengthNonASCII(b0); -} - -// Once the bits are split out into bytes of UTF-8, this is a mask OR-ed -// into the first byte, depending on how many bytes follow. There are -// as many entries in this table as there are UTF-8 sequence types. -// (I.e., one byte sequence, two byte... etc.). Remember that sequences -// for *legal* UTF-8 will be 4 or fewer bytes total. -static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - -typedef enum { - conversionOK, // conversion successful - sourceExhausted, // partial character in source, but hit end - targetExhausted, // insuff. room in target for conversion - sourceIllegal // source sequence is illegal/malformed -} ConversionResult; - -ConversionResult convertLatin1ToUTF8( - const LChar** sourceStart, const LChar* sourceEnd, - char** targetStart, char* targetEnd) -{ - ConversionResult result = conversionOK; - const LChar* source = *sourceStart; - char* target = *targetStart; - while (source < sourceEnd) { - UChar32 ch; - unsigned short bytesToWrite = 0; - const UChar32 byteMask = 0xBF; - const UChar32 byteMark = 0x80; - const LChar* oldSource = source; // In case we have to back up because of target overflow. - ch = static_cast<unsigned short>(*source++); - - // Figure out how many bytes the result will require - if (ch < (UChar32)0x80) - bytesToWrite = 1; - else - bytesToWrite = 2; - - target += bytesToWrite; - if (target > targetEnd) { - source = oldSource; // Back up source pointer! - target -= bytesToWrite; - result = targetExhausted; - break; - } - switch (bytesToWrite) { // note: everything falls through. - case 2: - *--target = (char)((ch | byteMark) & byteMask); - ch >>= 6; - case 1: - *--target = (char)(ch | firstByteMark[bytesToWrite]); - } - target += bytesToWrite; - } - *sourceStart = source; - *targetStart = target; - return result; -} - -ConversionResult convertUTF16ToUTF8( - const UChar** sourceStart, const UChar* sourceEnd, - char** targetStart, char* targetEnd, bool strict) -{ - ConversionResult result = conversionOK; - const UChar* source = *sourceStart; - char* target = *targetStart; - while (source < sourceEnd) { - UChar32 ch; - unsigned short bytesToWrite = 0; - const UChar32 byteMask = 0xBF; - const UChar32 byteMark = 0x80; - const UChar* oldSource = source; // In case we have to back up because of target overflow. - ch = static_cast<unsigned short>(*source++); - // If we have a surrogate pair, convert to UChar32 first. - if (ch >= 0xD800 && ch <= 0xDBFF) { - // If the 16 bits following the high surrogate are in the source buffer... - if (source < sourceEnd) { - UChar32 ch2 = static_cast<unsigned short>(*source); - // If it's a low surrogate, convert to UChar32. - if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) { - ch = ((ch - 0xD800) << 10) + (ch2 - 0xDC00) + 0x0010000; - ++source; - } else if (strict) { // it's an unpaired high surrogate - --source; // return to the illegal value itself - result = sourceIllegal; - break; - } - } else { // We don't have the 16 bits following the high surrogate. - --source; // return to the high surrogate - result = sourceExhausted; - break; - } - } else if (strict) { - // UTF-16 surrogate values are illegal in UTF-32 - if (ch >= 0xDC00 && ch <= 0xDFFF) { - --source; // return to the illegal value itself - result = sourceIllegal; - break; - } - } - // Figure out how many bytes the result will require - if (ch < (UChar32)0x80) { - bytesToWrite = 1; - } else if (ch < (UChar32)0x800) { - bytesToWrite = 2; - } else if (ch < (UChar32)0x10000) { - bytesToWrite = 3; - } else if (ch < (UChar32)0x110000) { - bytesToWrite = 4; - } else { - bytesToWrite = 3; - ch = replacementCharacter; - } - - target += bytesToWrite; - if (target > targetEnd) { - source = oldSource; // Back up source pointer! - target -= bytesToWrite; - result = targetExhausted; - break; - } - switch (bytesToWrite) { // note: everything falls through. - case 4: - *--target = (char)((ch | byteMark) & byteMask); - ch >>= 6; - case 3: - *--target = (char)((ch | byteMark) & byteMask); - ch >>= 6; - case 2: - *--target = (char)((ch | byteMark) & byteMask); - ch >>= 6; - case 1: - *--target = (char)(ch | firstByteMark[bytesToWrite]); - } - target += bytesToWrite; - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/** - * Is this code point a BMP code point (U+0000..U+ffff)? - * @param c 32-bit code point - * @return TRUE or FALSE - * @stable ICU 2.8 - */ -#define U_IS_BMP(c) ((uint32_t)(c) <= 0xffff) - -/** - * Is this code point a supplementary code point (U+10000..U+10ffff)? - * @param c 32-bit code point - * @return TRUE or FALSE - * @stable ICU 2.8 - */ -#define U_IS_SUPPLEMENTARY(c) ((uint32_t)((c) - 0x10000) <= 0xfffff) - -/** - * Is this code point a surrogate (U+d800..U+dfff)? - * @param c 32-bit code point - * @return TRUE or FALSE - * @stable ICU 2.4 - */ -#define U_IS_SURROGATE(c) (((c) & 0xfffff800) == 0xd800) - -/** - * Get the lead surrogate (0xd800..0xdbff) for a - * supplementary code point (0x10000..0x10ffff). - * @param supplementary 32-bit code point (U+10000..U+10ffff) - * @return lead surrogate (U+d800..U+dbff) for supplementary - * @stable ICU 2.4 - */ -#define U16_LEAD(supplementary) (UChar)(((supplementary) >> 10) + 0xd7c0) - -/** - * Get the trail surrogate (0xdc00..0xdfff) for a - * supplementary code point (0x10000..0x10ffff). - * @param supplementary 32-bit code point (U+10000..U+10ffff) - * @return trail surrogate (U+dc00..U+dfff) for supplementary - * @stable ICU 2.4 - */ -#define U16_TRAIL(supplementary) (UChar)(((supplementary) & 0x3ff) | 0xdc00) - -// This must be called with the length pre-determined by the first byte. -// If presented with a length > 4, this returns false. The Unicode -// definition of UTF-8 goes up to 4-byte sequences. -static bool isLegalUTF8(const unsigned char* source, int length) -{ - unsigned char a; - const unsigned char* srcptr = source + length; - switch (length) { - default: - return false; - // Everything else falls through when "true"... - case 4: - if ((a = (*--srcptr)) < 0x80 || a > 0xBF) - return false; - case 3: - if ((a = (*--srcptr)) < 0x80 || a > 0xBF) - return false; - case 2: - if ((a = (*--srcptr)) > 0xBF) - return false; - - // no fall-through in this inner switch - switch (*source) { - case 0xE0: - if (a < 0xA0) - return false; - break; - case 0xED: - if (a > 0x9F) - return false; - break; - case 0xF0: - if (a < 0x90) - return false; - break; - case 0xF4: - if (a > 0x8F) - return false; - break; - default: - if (a < 0x80) - return false; - } - - case 1: - if (*source >= 0x80 && *source < 0xC2) - return false; - } - if (*source > 0xF4) - return false; - return true; -} - -// Magic values subtracted from a buffer value during UTF8 conversion. -// This table contains as many values as there might be trailing bytes -// in a UTF-8 sequence. -static const UChar32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, 0x03C82080UL, static_cast<UChar32>(0xFA082080UL), static_cast<UChar32>(0x82082080UL) }; - -static inline UChar32 readUTF8Sequence(const char*& sequence, unsigned length) -{ - UChar32 character = 0; - - // The cases all fall through. - switch (length) { - case 6: - character += static_cast<unsigned char>(*sequence++); - character <<= 6; - case 5: - character += static_cast<unsigned char>(*sequence++); - character <<= 6; - case 4: - character += static_cast<unsigned char>(*sequence++); - character <<= 6; - case 3: - character += static_cast<unsigned char>(*sequence++); - character <<= 6; - case 2: - character += static_cast<unsigned char>(*sequence++); - character <<= 6; - case 1: - character += static_cast<unsigned char>(*sequence++); - } - - return character - offsetsFromUTF8[length - 1]; -} - -ConversionResult convertUTF8ToUTF16( - const char** sourceStart, const char* sourceEnd, - UChar** targetStart, UChar* targetEnd, bool* sourceAllASCII, bool strict) -{ - ConversionResult result = conversionOK; - const char* source = *sourceStart; - UChar* target = *targetStart; - UChar orAllData = 0; - while (source < sourceEnd) { - int utf8SequenceLength = inlineUTF8SequenceLength(*source); - if (sourceEnd - source < utf8SequenceLength) { - result = sourceExhausted; - break; - } - // Do this check whether lenient or strict - if (!isLegalUTF8(reinterpret_cast<const unsigned char*>(source), utf8SequenceLength)) { - result = sourceIllegal; - break; - } - - UChar32 character = readUTF8Sequence(source, utf8SequenceLength); - - if (target >= targetEnd) { - source -= utf8SequenceLength; // Back up source pointer! - result = targetExhausted; - break; - } - - if (U_IS_BMP(character)) { - // UTF-16 surrogate values are illegal in UTF-32 - if (U_IS_SURROGATE(character)) { - if (strict) { - source -= utf8SequenceLength; // return to the illegal value itself - result = sourceIllegal; - break; - } - *target++ = replacementCharacter; - orAllData |= replacementCharacter; - } else { - *target++ = static_cast<UChar>(character); // normal case - orAllData |= character; - } - } else if (U_IS_SUPPLEMENTARY(character)) { - // target is a character in range 0xFFFF - 0x10FFFF - if (target + 1 >= targetEnd) { - source -= utf8SequenceLength; // Back up source pointer! - result = targetExhausted; - break; - } - *target++ = U16_LEAD(character); - *target++ = U16_TRAIL(character); - orAllData = 0xffff; - } else { - if (strict) { - source -= utf8SequenceLength; // return to the start - result = sourceIllegal; - break; // Bail out; shouldn't continue - } else { - *target++ = replacementCharacter; - orAllData |= replacementCharacter; - } - } - } - *sourceStart = source; - *targetStart = target; - - if (sourceAllASCII) - *sourceAllASCII = !(orAllData & ~0x7f); - - return result; -} - -// Helper to write a three-byte UTF-8 code point to the buffer, caller must check room is available. -static inline void putUTF8Triple(char*& buffer, UChar ch) -{ - DCHECK_GE(ch, 0x0800); - *buffer++ = static_cast<char>(((ch >> 12) & 0x0F) | 0xE0); - *buffer++ = static_cast<char>(((ch >> 6) & 0x3F) | 0x80); - *buffer++ = static_cast<char>((ch & 0x3F) | 0x80); -} - -String16 String16::fromUTF8(const char* stringStart, size_t length) -{ - if (!stringStart || !length) - return String16(); - - std::vector<UChar> buffer(length); - UChar* bufferStart = buffer.data(); - - UChar* bufferCurrent = bufferStart; - const char* stringCurrent = stringStart; - if (convertUTF8ToUTF16(&stringCurrent, stringStart + length, &bufferCurrent, bufferCurrent + buffer.size(), 0, true) != conversionOK) - return String16(); - - unsigned utf16Length = bufferCurrent - bufferStart; - return String16(bufferStart, utf16Length); -} - -// trim from start -static inline wstring <rim(wstring &s) -{ - s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace)))); - return s; -} - -// trim from end -static inline wstring &rtrim(wstring &s) -{ - s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end()); - return s; -} - -// trim from both ends -static inline wstring &trim(wstring &s) -{ - return ltrim(rtrim(s)); -} - -// static -std::string String16::intToString(int i) -{ - char buffer[50]; - std::sprintf(buffer, "%d", i); - return std::string(buffer); -} - -// static -std::string String16::doubleToString(double d) -{ - char buffer[100]; - std::sprintf(buffer, "%f", d); - return std::string(buffer); -} - -std::string String16::utf8() const -{ - unsigned length = this->length(); - - if (!length) - return std::string(""); - - // Allocate a buffer big enough to hold all the characters - // (an individual UTF-16 UChar can only expand to 3 UTF-8 bytes). - // Optimization ideas, if we find this function is hot: - // * We could speculatively create a CStringBuffer to contain 'length' - // characters, and resize if necessary (i.e. if the buffer contains - // non-ascii characters). (Alternatively, scan the buffer first for - // ascii characters, so we know this will be sufficient). - // * We could allocate a CStringBuffer with an appropriate size to - // have a good chance of being able to write the string into the - // buffer without reallocing (say, 1.5 x length). - if (length > std::numeric_limits<unsigned>::max() / 3) - return std::string(); - std::vector<char> bufferVector(length * 3); - char* buffer = bufferVector.data(); - const UChar* characters = m_impl.data(); - - ConversionResult result = convertUTF16ToUTF8(&characters, characters + length, &buffer, buffer + bufferVector.size(), false); - DCHECK(result != targetExhausted); // (length * 3) should be sufficient for any conversion - - // Only produced from strict conversion. - DCHECK(result != sourceIllegal); - - // Check for an unconverted high surrogate. - if (result == sourceExhausted) { - // This should be one unpaired high surrogate. Treat it the same - // was as an unpaired high surrogate would have been handled in - // the middle of a string with non-strict conversion - which is - // to say, simply encode it to UTF-8. - DCHECK((characters + 1) == (m_impl.data() + length)); - DCHECK((*characters >= 0xD800) && (*characters <= 0xDBFF)); - // There should be room left, since one UChar hasn't been - // converted. - DCHECK((buffer + 3) <= (buffer + bufferVector.size())); - putUTF8Triple(buffer, *characters); - } - - return std::string(bufferVector.data(), buffer - bufferVector.data()); -} - -String16 String16::stripWhiteSpace() const -{ - wstring result(m_impl); - trim(result); - return result; -} - -} // namespace protocol -} // namespace blink
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/String16STL.h b/third_party/WebKit/Source/platform/inspector_protocol/String16STL.h deleted file mode 100644 index 4dd4369..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/String16STL.h +++ /dev/null
@@ -1,263 +0,0 @@ -// Copyright 2016 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 String16STL_h -#define String16STL_h - -#include <cctype> -#include <cstdlib> -#include <cstring> -#include <stdint.h> -#include <string> -#include <vector> - -using UChar = uint16_t; -using UChar32 = uint32_t; -using LChar = unsigned char; -// presubmit: allow wstring -using wstring = std::basic_string<UChar>; -const size_t kNotFound = static_cast<size_t>(-1); - -namespace blink { -namespace protocol { - -class String16 { -public: - String16() { } - String16(const String16& other) : m_impl(other.m_impl) { } - // presubmit: allow wstring - String16(const wstring& impl) : m_impl(impl) { } - String16(const UChar* characters) : m_impl(characters) { } - String16(const char* characters) : String16(characters, std::strlen(characters)) { } - String16(const char* characters, size_t size) - { - m_impl.resize(size); - for (size_t i = 0; i < size; ++i) - m_impl[i] = characters[i]; - } - String16(const UChar* characters, size_t size) : m_impl(characters, size) { } - String16 isolatedCopy() const { return String16(m_impl); } - - unsigned sizeInBytes() const { return m_impl.size() * sizeof(UChar); } - const UChar* characters16() const { return m_impl.c_str(); } - std::string utf8() const; - static String16 fromUTF8(const char* stringStart, size_t length); - static String16 fromInteger(int i) { return String16(String16::intToString(i).c_str()); } - static String16 fromDouble(double d) { return String16(String16::doubleToString(d).c_str()); } - static String16 fromDoubleFixedPrecision(double d, int len) { return String16(String16::doubleToString(d).c_str()); } - - static double charactersToDouble(const UChar* characters, size_t length, bool* ok = 0) - { - std::string str; - str.resize(length); - for (size_t i = 0; i < length; ++i) - str[i] = static_cast<char>(characters[i]); - - const char* buffer = str.c_str(); - char* endptr; - double result = strtod(buffer, &endptr); - if (ok) - *ok = buffer + length == endptr; - return result; - } - - String16 substring(unsigned pos, unsigned len = 0xFFFFFFFF) const - { - return String16(m_impl.substr(pos, len)); - } - - String16 stripWhiteSpace() const; - - int toInt(bool* ok = 0) const - { - size_t length = m_impl.length(); - std::string str; - str.resize(length); - for (size_t i = 0; i < length; ++i) - str[i] = static_cast<char>(m_impl[i]); - - const char* buffer = str.c_str(); - char* endptr; - int result = strtol(buffer, &endptr, 10); - if (ok) - *ok = buffer + length == endptr; - return result; - } - - size_t length() const { return m_impl.length(); } - bool isEmpty() const { return !m_impl.length(); } - UChar operator[](unsigned index) const { return m_impl[index]; } - - size_t find(UChar c, unsigned start = 0) const - { - return m_impl.find(c, start); - } - - size_t find(const String16& str, unsigned start = 0) const - { - return m_impl.find(str.m_impl, start); - } - - size_t reverseFind(const String16& str, unsigned start = 0xFFFFFFFF) const - { - return m_impl.rfind(str.m_impl, start); - } - - bool startWith(const String16& s) const - { - if (m_impl.length() < s.m_impl.length()) - return false; - return m_impl.substr(0, s.m_impl.length()) == s.m_impl; - } - - bool endsWith(UChar character) const - { - return m_impl.length() && m_impl[m_impl.length() - 1] == character; - } - - // presubmit: allow wstring - const wstring& impl() const { return m_impl; } - - std::size_t hash() const - { - if (!has_hash) { - size_t hash = 0; - for (size_t i = 0; i < length(); ++i) - hash = 31 * hash + m_impl[i]; - hash_code = hash; - has_hash = true; - } - return hash_code; - } - -private: - static std::string intToString(int); - static std::string doubleToString(double); - // presubmit: allow wstring - wstring m_impl; - mutable bool has_hash = false; - mutable std::size_t hash_code = 0; -}; - -static inline bool isSpaceOrNewline(UChar c) -{ - return std::isspace(c); // NOLINT -} - -class String16Builder { -public: - String16Builder() { } - - void append(const String16& str) - { - m_impl += str.impl(); - } - - void append(UChar c) - { - m_impl += c; - } - - void append(LChar c) - { - m_impl += c; - } - - void append(char c) - { - m_impl += c; - } - - void appendNumber(int i) - { - m_impl = m_impl + String16::fromInteger(i).impl(); - } - - void appendNumber(double d) - { - m_impl = m_impl + String16::fromDoubleFixedPrecision(d, 6).impl(); - } - - void append(const UChar* c, size_t length) - { - // presubmit: allow wstring - m_impl += wstring(c, length); - } - - void append(const char* c, size_t length) - { - m_impl += String16(c, length).impl(); - } - - String16 toString() - { - return String16(m_impl); - } - - void reserveCapacity(unsigned newCapacity) - { - } - -private: - // presubmit: allow wstring - wstring m_impl; -}; - -inline bool operator==(const String16& a, const String16& b) { return a.impl() == b.impl(); } -inline bool operator!=(const String16& a, const String16& b) { return a.impl() != b.impl(); } -inline bool operator==(const String16& a, const char* b) { return a.impl() == String16(b).impl(); } -inline bool operator<(const String16& a, const String16& b) { return a.impl() < b.impl(); } - -inline String16 operator+(const String16& a, const char* b) -{ - return String16(a.impl() + String16(b).impl()); -} - -inline String16 operator+(const char* a, const String16& b) -{ - return String16(String16(a).impl() + b.impl()); -} - -inline String16 operator+(const String16& a, const String16& b) -{ - return String16(a.impl() + b.impl()); -} - -} // namespace protocol -} // namespace blink - -using String16 = blink::protocol::String16; -using String16Builder = blink::protocol::String16Builder; - - -namespace WTF { -// Interim solution for those headers that reference WTF::String for overrides. -// It does nothing. If the code actually relies on WTF:String, it will not -// compile! -// TODO(eostroukhov): Eradicate -class String { -public: - String() {}; - String(const String16& other) {}; - operator String16() const { return String16(); }; -}; -} // namespace WTF - -#if !defined(__APPLE__) || defined(_LIBCPP_VERSION) - -namespace std { -template<> struct hash<String16> { - std::size_t operator()(const String16& string) const - { - return string.hash(); - } -}; - -} // namespace std - -#endif // !defined(__APPLE__) || defined(_LIBCPP_VERSION) - -using String = WTF::String; - -#endif // !defined(String16STL_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/String16WTF.cpp b/third_party/WebKit/Source/platform/inspector_protocol/String16WTF.cpp deleted file mode 100644 index 387ecc3..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/String16WTF.cpp +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2016 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 "platform/inspector_protocol/String16WTF.h" - -namespace blink { -namespace protocol { - -String16::String16(const String16& other) : m_impl(other.m_impl) { } - -String16::String16(const UChar* u, unsigned length) : m_impl(u, length) { } - -String16::String16(const char* characters) : String16(characters, strlen(characters)) { } - -String16::String16(const WTF::String& other) -{ - if (other.isNull()) - return; - if (!other.is8Bit()) { - m_impl = other; - return; - } - - UChar* data; - const LChar* characters = other.characters8(); - size_t length = other.length(); - m_impl = String::createUninitialized(length, data); - for (size_t i = 0; i < length; ++i) - data[i] = characters[i]; -} - -String16::String16(const char* characters, size_t length) -{ - UChar* data; - m_impl = String::createUninitialized(length, data); - for (size_t i = 0; i < length; ++i) - data[i] = characters[i]; -} - -String16 String16::createUninitialized(unsigned length, UChar*& data) -{ - return String::createUninitialized(length, data); -} - -} // namespace protocol -} // namespace blink
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/String16WTF.h b/third_party/WebKit/Source/platform/inspector_protocol/String16WTF.h deleted file mode 100644 index 19c56256..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/String16WTF.h +++ /dev/null
@@ -1,154 +0,0 @@ -// Copyright 2016 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 String16WTF_h -#define String16WTF_h - -#include "platform/Decimal.h" -#include "public/platform/WebString.h" -#include "wtf/text/StringBuilder.h" -#include "wtf/text/StringConcatenate.h" -#include "wtf/text/StringHash.h" -#include "wtf/text/StringToNumber.h" -#include "wtf/text/StringView.h" -#include "wtf/text/WTFString.h" - -namespace blink { -namespace protocol { - -class PLATFORM_EXPORT String16 { -public: - String16() { } - String16(const String16& other); - String16(const UChar*, unsigned); - String16(const char*); - String16(const char*, size_t); - static String16 createUninitialized(unsigned length, UChar*& data); - - // WTF convenience constructors and helper methods. - String16(const WebString& other) : String16(String(other)) { } - template<typename StringType1, typename StringType2> - String16(const WTF::StringAppend<StringType1, StringType2>& impl) : String16(String(impl)) { } - String16(const WTF::AtomicString& impl) : String16(String(impl)) { } - String16(const WTF::String& impl); - String16(WTF::HashTableDeletedValueType) : m_impl(WTF::HashTableDeletedValue) { } - bool isHashTableDeletedValue() const { return m_impl.isHashTableDeletedValue(); } - operator WTF::String() const { return m_impl; } - operator WTF::StringView() const { return StringView(m_impl); } - operator WebString() { return m_impl; } - const WTF::String& impl() const { return m_impl; } - String16 isolatedCopy() const { return String16(m_impl.isolatedCopy()); } - - ~String16() { } - - static String16 fromInteger(int i) { return String::number(i); } - static String16 fromDouble(double number) { return Decimal::fromDouble(number).toString(); } - static String16 fromDoubleFixedPrecision(double number, int precision) { return String::numberToStringFixedWidth(number, precision); } - - size_t length() const { return m_impl.length(); } - bool isEmpty() const { return m_impl.isEmpty(); } - UChar operator[](unsigned index) const { return m_impl[index]; } - - unsigned sizeInBytes() const { return m_impl.sizeInBytes(); } - const UChar* characters16() const { return m_impl.isEmpty() ? nullptr : m_impl.characters16(); } - - static double charactersToDouble(const LChar* characters, size_t length, bool* ok = 0) { return ::charactersToDouble(characters, length, ok); } - static double charactersToDouble(const UChar* characters, size_t length, bool* ok = 0) { return ::charactersToDouble(characters, length, ok); } - - String16 substring(unsigned pos, unsigned len = UINT_MAX) const { return m_impl.substring(pos, len); } - String16 stripWhiteSpace() const { return m_impl.stripWhiteSpace(); } - - int toInt(bool* ok = 0) const { return m_impl.toInt(ok); } - - size_t find(UChar c, unsigned start = 0) const { return m_impl.find(c, start); } - size_t find(const String16& str, unsigned start = 0) const { return m_impl.find(str.impl(), start); } - size_t reverseFind(const String16& str, unsigned start = UINT_MAX) const { return m_impl.reverseFind(str.impl(), start); } - - bool startWith(const String16& s) const { return m_impl.startsWith(s); } - bool startWith(UChar character) const { return m_impl.startsWith(character); } - bool endsWith(const String16& s) const { return m_impl.endsWith(s); } - bool endsWith(UChar character) const { return m_impl.endsWith(character); } - -private: - WTF::String m_impl; -}; - -class String16Builder { -public: - String16Builder() { } - void append(const String16& str) { m_impl.append(str); }; - void append(UChar c) { m_impl.append(c); }; - void append(LChar c) { m_impl.append(c); }; - void append(char c) { m_impl.append(c); }; - void append(const UChar* c, size_t size) { m_impl.append(c, size); }; - void append(const char* characters, unsigned length) { m_impl.append(characters, length); } - void appendNumber(int number) { m_impl.appendNumber(number); } - void appendNumber(double number) { m_impl.appendNumber(number); } - String16 toString() { return m_impl.toString(); } - void reserveCapacity(unsigned newCapacity) { m_impl.reserveCapacity(newCapacity); } - -private: - WTF::StringBuilder m_impl; -}; - -inline bool operator==(const String16& a, const String16& b) { return a.impl() == b.impl(); } -inline bool operator!=(const String16& a, const String16& b) { return a.impl() != b.impl(); } -inline bool operator==(const String16& a, const char* b) { return a.impl() == b; } - -inline String16 operator+(const String16& a, const char* b) -{ - return String(a.impl() + b); -} - -inline String16 operator+(const char* a, const String16& b) -{ - return String(a + b.impl()); -} - -inline String16 operator+(const String16& a, const String16& b) -{ - return String(a.impl() + b.impl()); -} - -} // namespace protocol -} // namespace blink - -using String16 = blink::protocol::String16; -using String16Builder = blink::protocol::String16Builder; - -namespace WTF { - -struct String16Hash { - static unsigned hash(const String16& key) { return StringHash::hash(key.impl()); } - static bool equal(const String16& a, const String16& b) - { - return StringHash::equal(a.impl(), b.impl()); - } - static const bool safeToCompareToEmptyOrDeleted = false; -}; - -template<typename T> struct DefaultHash; -template<> struct DefaultHash<String16> { - typedef String16Hash Hash; -}; - -template<> -struct HashTraits<String16> : SimpleClassHashTraits<String16> { - static const bool hasIsEmptyValueFunction = true; - static bool isEmptyValue(const String16& a) { return a.impl().isNull(); } -}; - -} // namespace WTF - -namespace std { -template<> struct hash<String16> { - std::size_t operator()(const String16& string) const - { - return StringHash::hash(string.impl()); - } -}; - -} // namespace std - -#endif // !defined(String16WTF_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/String16_cpp.template b/third_party/WebKit/Source/platform/inspector_protocol/String16_cpp.template new file mode 100644 index 0000000..d795aef --- /dev/null +++ b/third_party/WebKit/Source/platform/inspector_protocol/String16_cpp.template
@@ -0,0 +1,99 @@ +// Copyright 2016 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 <cstdlib> +#include <cstring> +#include <string> + +namespace blink { +namespace protocol { + +namespace internal { + +void intToStr(int number, char* buffer, size_t length) +{ + std::snprintf(buffer, length, "%d", number); +} + +void doubleToStr(double number, char* buffer, size_t length) +{ + std::snprintf(buffer, length, "%f", number); +} + +void doubleToStr3(double number, char* buffer, size_t length) +{ + std::snprintf(buffer, length, "%.3g", number); +} + +void doubleToStr6(double number, char* buffer, size_t length) +{ + std::snprintf(buffer, length, "%.6g", number); +} + +double strToDouble(const char* buffer, bool* ok) +{ + char* endptr; + double result = std::strtod(buffer, &endptr); + if (ok) + *ok = !(*endptr); + return result; +} + +int strToInt(const char* buffer, bool* ok) +{ + char* endptr; + int result = std::strtol(buffer, &endptr, 10); + if (ok) + *ok = !(*endptr); + return result; +} + +} // namespace internal + +String16Builder::String16Builder() +{ +} + +void String16Builder::append(const String16& s) +{ + m_buffer.insert(m_buffer.end(), s.characters16(), s.characters16() + s.length()); +} + +void String16Builder::append(UChar c) +{ + m_buffer.push_back(c); +} + +void String16Builder::append(char c) +{ + UChar u = c; + m_buffer.push_back(u); +} + +void String16Builder::append(const UChar* characters, size_t length) +{ + m_buffer.insert(m_buffer.end(), characters, characters + length); +} + +void String16Builder::append(const char* characters, size_t length) +{ + m_buffer.reserve(m_buffer.size() + length); + for (size_t i = 0; i < length; ++i, ++characters) { + UChar u = *characters; + m_buffer.push_back(u); + } +} + +String16 String16Builder::toString() +{ + return String16(m_buffer.data(), m_buffer.size()); +} + +void String16Builder::reserveCapacity(size_t capacity) +{ + m_buffer.reserve(capacity); +} + +} // namespace protocol +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/String16_h.template b/third_party/WebKit/Source/platform/inspector_protocol/String16_h.template new file mode 100644 index 0000000..005f3494 --- /dev/null +++ b/third_party/WebKit/Source/platform/inspector_protocol/String16_h.template
@@ -0,0 +1,181 @@ +// Copyright 2016 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 String16_h +#define String16_h + +//#include "Collections.h" +//#include "Platform.h" +#include "{{export_macro_include}}" + +#include <vector> + +namespace blink { +namespace protocol { + +namespace internal { +{{export_macro}} void intToStr(int, char*, size_t); +{{export_macro}} void doubleToStr(double, char*, size_t); +{{export_macro}} void doubleToStr3(double, char*, size_t); +{{export_macro}} void doubleToStr6(double, char*, size_t); +{{export_macro}} double strToDouble(const char*, bool*); +{{export_macro}} int strToInt(const char*, bool*); +} // namespace internal + +template <typename T, typename C> +class {{export_macro}} String16Base { +public: + static bool isASCII(C c) + { + return !(c & ~0x7F); + } + + static bool isSpaceOrNewLine(C c) + { + return isASCII(c) && c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9)); + } + + static T fromInteger(int number) + { + char buffer[50]; + internal::intToStr(number, buffer, PROTOCOL_ARRAY_LENGTH(buffer)); + return T(buffer); + } + + static T fromDouble(double number) + { + char buffer[100]; + internal::doubleToStr(number, buffer, PROTOCOL_ARRAY_LENGTH(buffer)); + return T(buffer); + } + + static T fromDoublePrecision3(double number) + { + char buffer[100]; + internal::doubleToStr3(number, buffer, PROTOCOL_ARRAY_LENGTH(buffer)); + return T(buffer); + } + + static T fromDoublePrecision6(double number) + { + char buffer[100]; + internal::doubleToStr6(number, buffer, PROTOCOL_ARRAY_LENGTH(buffer)); + return T(buffer); + } + + static double charactersToDouble(const C* characters, size_t length, bool* ok = nullptr) + { + std::vector<char> buffer; + buffer.reserve(length + 1); + for (size_t i = 0; i < length; ++i) { + if (!isASCII(characters[i])) { + if (ok) + *ok = false; + return 0; + } + buffer.push_back(static_cast<char>(characters[i])); + } + buffer.push_back('\0'); + return internal::strToDouble(buffer.data(), ok); + } + + static int charactersToInteger(const C* characters, size_t length, bool* ok = nullptr) + { + std::vector<char> buffer; + buffer.reserve(length + 1); + for (size_t i = 0; i < length; ++i) { + if (!isASCII(characters[i])) { + if (ok) + *ok = false; + return 0; + } + buffer.push_back(static_cast<char>(characters[i])); + } + buffer.push_back('\0'); + return internal::strToInt(buffer.data(), ok); + } + + double toDouble(bool* ok = nullptr) const + { + const C* characters = static_cast<const T&>(*this).characters16(); + size_t length = static_cast<const T&>(*this).length(); + return charactersToDouble(characters, length, ok); + } + + int toInteger(bool* ok = nullptr) const + { + const C* characters = static_cast<const T&>(*this).characters16(); + size_t length = static_cast<const T&>(*this).length(); + return charactersToInteger(characters, length, ok); + } + + T stripWhiteSpace() const + { + size_t length = static_cast<const T&>(*this).length(); + if (!length) + return T(); + + unsigned start = 0; + unsigned end = length - 1; + const C* characters = static_cast<const T&>(*this).characters16(); + + // skip white space from start + while (start <= end && isSpaceOrNewLine(characters[start])) + ++start; + + // only white space + if (start > end) + return T(); + + // skip white space from end + while (end && isSpaceOrNewLine(characters[end])) + --end; + + if (!start && end == length - 1) + return T(static_cast<const T&>(*this)); + return T(characters + start, end + 1 - start); + } + + bool startsWith(const char* prefix) const + { + const C* characters = static_cast<const T&>(*this).characters16(); + size_t length = static_cast<const T&>(*this).length(); + for (size_t i = 0, j = 0; prefix[j] && i < length; ++i, ++j) { + if (characters[i] != prefix[j]) + return false; + } + return true; + } +}; + +} // namespace protocol +} // namespace blink + +#include "{{string16_impl_h_include}}" + +namespace blink { +namespace protocol { + +class {{export_macro}} String16Builder { +public: + String16Builder(); + void append(const String16&); + void append(UChar); + void append(char); + void append(const UChar*, size_t); + void append(const char*, size_t); + String16 toString(); + void reserveCapacity(size_t); + +private: + std::vector<UChar> m_buffer; +}; + +} // namespace protocol +} // namespace blink + +using String16 = blink::protocol::String16; +using String16Builder = blink::protocol::String16Builder; + +#endif // !defined(String16_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_cpp.template b/third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_cpp.template index e3c2fa1..1e76823 100644 --- a/third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_cpp.template +++ b/third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_cpp.template
@@ -6,9 +6,6 @@ #include "{{output_package}}/{{domain.domain}}.h" -#include "platform/inspector_protocol/DispatcherBase.h" -#include "platform/inspector_protocol/Parser.h" - namespace blink { namespace protocol { namespace {{domain.domain}} {
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_h.template b/third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_h.template index 83310065..eb7fe2f 100644 --- a/third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_h.template +++ b/third_party/WebKit/Source/platform/inspector_protocol/TypeBuilder_h.template
@@ -7,22 +7,8 @@ #ifndef protocol_{{domain.domain}}_h #define protocol_{{domain.domain}}_h -{% if export_macro == "PLATFORM_EXPORT" %} -#include "platform/inspector_protocol/Platform.h" -{% else %} -#include "core/CoreExport.h" -{% endif %} -#include "platform/inspector_protocol/Array.h" -#include "platform/inspector_protocol/BackendCallback.h" -#include "platform/inspector_protocol/DispatcherBase.h" -#include "platform/inspector_protocol/ErrorSupport.h" -#include "platform/inspector_protocol/FrontendChannel.h" -#include "platform/inspector_protocol/Maybe.h" -#include "platform/inspector_protocol/Object.h" -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" -#include "platform/inspector_protocol/Values.h" -#include "platform/inspector_protocol/ValueConversions.h" +#include "{{export_macro_include}}" +#include "{{lib_package}}/InspectorProtocol.h" // For each imported domain we generate a ValueConversions struct instead of a full domain definition // and include Domain::API version from there. {% for name in domain.dependencies %}
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/ValueConversions.h b/third_party/WebKit/Source/platform/inspector_protocol/ValueConversions.h deleted file mode 100644 index ba1d0804..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/ValueConversions.h +++ /dev/null
@@ -1,187 +0,0 @@ -// Copyright 2016 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 ValueConversions_h -#define ValueConversions_h - -#include "platform/inspector_protocol/ErrorSupport.h" -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" -#include "platform/inspector_protocol/Values.h" - -namespace blink { -namespace protocol { - -template<typename T> -struct ValueConversions { - static std::unique_ptr<T> parse(protocol::Value* value, ErrorSupport* errors) - { - return T::parse(value, errors); - } - - static std::unique_ptr<protocol::Value> serialize(T* value) - { - return value->serialize(); - } - - static std::unique_ptr<protocol::Value> serialize(const std::unique_ptr<T>& value) - { - return value->serialize(); - } -}; - -template<> -struct ValueConversions<bool> { - static bool parse(protocol::Value* value, ErrorSupport* errors) - { - bool result = false; - bool success = value ? value->asBoolean(&result) : false; - if (!success) - errors->addError("boolean value expected"); - return result; - } - - static std::unique_ptr<protocol::Value> serialize(bool value) - { - return FundamentalValue::create(value); - } -}; - -template<> -struct ValueConversions<int> { - static int parse(protocol::Value* value, ErrorSupport* errors) - { - int result = 0; - bool success = value ? value->asInteger(&result) : false; - if (!success) - errors->addError("integer value expected"); - return result; - } - - static std::unique_ptr<protocol::Value> serialize(int value) - { - return FundamentalValue::create(value); - } -}; - -template<> -struct ValueConversions<double> { - static double parse(protocol::Value* value, ErrorSupport* errors) - { - double result = 0; - bool success = value ? value->asDouble(&result) : false; - if (!success) - errors->addError("double value expected"); - return result; - } - - static std::unique_ptr<protocol::Value> serialize(double value) - { - return FundamentalValue::create(value); - } -}; - -template<> -struct ValueConversions<String> { - static String parse(protocol::Value* value, ErrorSupport* errors) - { - String16 result; - bool success = value ? value->asString(&result) : false; - if (!success) - errors->addError("string value expected"); - return result; - } - - static std::unique_ptr<protocol::Value> serialize(const String& value) - { - return StringValue::create(value); - } -}; - -template<> -struct ValueConversions<String16> { - static String16 parse(protocol::Value* value, ErrorSupport* errors) - { - String16 result; - bool success = value ? value->asString(&result) : false; - if (!success) - errors->addError("string value expected"); - return result; - } - - static std::unique_ptr<protocol::Value> serialize(const String16& value) - { - return StringValue::create(value); - } -}; - -template<> -struct ValueConversions<Value> { - static std::unique_ptr<Value> parse(protocol::Value* value, ErrorSupport* errors) - { - bool success = !!value; - if (!success) { - errors->addError("value expected"); - return nullptr; - } - return value->clone(); - } - - static std::unique_ptr<protocol::Value> serialize(Value* value) - { - return value->clone(); - } - - static std::unique_ptr<protocol::Value> serialize(const std::unique_ptr<Value>& value) - { - return value->clone(); - } -}; - -template<> -struct ValueConversions<DictionaryValue> { - static std::unique_ptr<DictionaryValue> parse(protocol::Value* value, ErrorSupport* errors) - { - bool success = value && value->type() == protocol::Value::TypeObject; - if (!success) - errors->addError("object expected"); - return DictionaryValue::cast(value->clone()); - } - - static std::unique_ptr<protocol::Value> serialize(DictionaryValue* value) - { - return value->clone(); - } - - static std::unique_ptr<protocol::Value> serialize(const std::unique_ptr<DictionaryValue>& value) - { - return value->clone(); - } -}; - -template<> -struct ValueConversions<ListValue> { - static std::unique_ptr<ListValue> parse(protocol::Value* value, ErrorSupport* errors) - { - bool success = value && value->type() == protocol::Value::TypeArray; - if (!success) - errors->addError("list expected"); - return ListValue::cast(value->clone()); - } - - static std::unique_ptr<protocol::Value> serialize(ListValue* value) - { - return value->clone(); - } - - static std::unique_ptr<protocol::Value> serialize(const std::unique_ptr<ListValue>& value) - { - return value->clone(); - } -}; - -} // namespace platform -} // namespace blink - -#endif // !defined(ValueConversions_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/ValueConversions_h.template b/third_party/WebKit/Source/platform/inspector_protocol/ValueConversions_h.template new file mode 100644 index 0000000..3b7eaa4f --- /dev/null +++ b/third_party/WebKit/Source/platform/inspector_protocol/ValueConversions_h.template
@@ -0,0 +1,187 @@ +// Copyright 2016 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 ValueConversions_h +#define ValueConversions_h + +//#include "ErrorSupport.h" +//#include "Platform.h" +//#include "String16.h" +//#include "Values.h" + +namespace blink { +namespace protocol { + +template<typename T> +struct ValueConversions { + static std::unique_ptr<T> parse(protocol::Value* value, ErrorSupport* errors) + { + return T::parse(value, errors); + } + + static std::unique_ptr<protocol::Value> serialize(T* value) + { + return value->serialize(); + } + + static std::unique_ptr<protocol::Value> serialize(const std::unique_ptr<T>& value) + { + return value->serialize(); + } +}; + +template<> +struct ValueConversions<bool> { + static bool parse(protocol::Value* value, ErrorSupport* errors) + { + bool result = false; + bool success = value ? value->asBoolean(&result) : false; + if (!success) + errors->addError("boolean value expected"); + return result; + } + + static std::unique_ptr<protocol::Value> serialize(bool value) + { + return FundamentalValue::create(value); + } +}; + +template<> +struct ValueConversions<int> { + static int parse(protocol::Value* value, ErrorSupport* errors) + { + int result = 0; + bool success = value ? value->asInteger(&result) : false; + if (!success) + errors->addError("integer value expected"); + return result; + } + + static std::unique_ptr<protocol::Value> serialize(int value) + { + return FundamentalValue::create(value); + } +}; + +template<> +struct ValueConversions<double> { + static double parse(protocol::Value* value, ErrorSupport* errors) + { + double result = 0; + bool success = value ? value->asDouble(&result) : false; + if (!success) + errors->addError("double value expected"); + return result; + } + + static std::unique_ptr<protocol::Value> serialize(double value) + { + return FundamentalValue::create(value); + } +}; + +template<> +struct ValueConversions<InspectorProtocolConvenienceStringType> { + static InspectorProtocolConvenienceStringType parse(protocol::Value* value, ErrorSupport* errors) + { + String16 result; + bool success = value ? value->asString(&result) : false; + if (!success) + errors->addError("string value expected"); + return result; + } + + static std::unique_ptr<protocol::Value> serialize(const InspectorProtocolConvenienceStringType& value) + { + return StringValue::create(value); + } +}; + +template<> +struct ValueConversions<String16> { + static String16 parse(protocol::Value* value, ErrorSupport* errors) + { + String16 result; + bool success = value ? value->asString(&result) : false; + if (!success) + errors->addError("string value expected"); + return result; + } + + static std::unique_ptr<protocol::Value> serialize(const String16& value) + { + return StringValue::create(value); + } +}; + +template<> +struct ValueConversions<Value> { + static std::unique_ptr<Value> parse(protocol::Value* value, ErrorSupport* errors) + { + bool success = !!value; + if (!success) { + errors->addError("value expected"); + return nullptr; + } + return value->clone(); + } + + static std::unique_ptr<protocol::Value> serialize(Value* value) + { + return value->clone(); + } + + static std::unique_ptr<protocol::Value> serialize(const std::unique_ptr<Value>& value) + { + return value->clone(); + } +}; + +template<> +struct ValueConversions<DictionaryValue> { + static std::unique_ptr<DictionaryValue> parse(protocol::Value* value, ErrorSupport* errors) + { + bool success = value && value->type() == protocol::Value::TypeObject; + if (!success) + errors->addError("object expected"); + return DictionaryValue::cast(value->clone()); + } + + static std::unique_ptr<protocol::Value> serialize(DictionaryValue* value) + { + return value->clone(); + } + + static std::unique_ptr<protocol::Value> serialize(const std::unique_ptr<DictionaryValue>& value) + { + return value->clone(); + } +}; + +template<> +struct ValueConversions<ListValue> { + static std::unique_ptr<ListValue> parse(protocol::Value* value, ErrorSupport* errors) + { + bool success = value && value->type() == protocol::Value::TypeArray; + if (!success) + errors->addError("list expected"); + return ListValue::cast(value->clone()); + } + + static std::unique_ptr<protocol::Value> serialize(ListValue* value) + { + return value->clone(); + } + + static std::unique_ptr<protocol::Value> serialize(const std::unique_ptr<ListValue>& value) + { + return value->clone(); + } +}; + +} // namespace platform +} // namespace blink + +#endif // !defined(ValueConversions_h)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Values.cpp b/third_party/WebKit/Source/platform/inspector_protocol/Values.cpp deleted file mode 100644 index 5b8f13b4..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/Values.cpp +++ /dev/null
@@ -1,410 +0,0 @@ -// Copyright 2016 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 "platform/inspector_protocol/Values.h" - -#include "platform/inspector_protocol/Parser.h" -#include "platform/inspector_protocol/String16.h" - -#include <algorithm> -#include <cmath> - -namespace blink { -namespace protocol { - -namespace { - -const char* const nullString = "null"; -const char* const trueString = "true"; -const char* const falseString = "false"; - -inline bool escapeChar(UChar c, String16Builder* dst) -{ - switch (c) { - case '\b': dst->append("\\b"); break; - case '\f': dst->append("\\f"); break; - case '\n': dst->append("\\n"); break; - case '\r': dst->append("\\r"); break; - case '\t': dst->append("\\t"); break; - case '\\': dst->append("\\\\"); break; - case '"': dst->append("\\\""); break; - default: - return false; - } - return true; -} - -const LChar hexDigits[17] = "0123456789ABCDEF"; - -void appendUnsignedAsHex(UChar number, String16Builder* dst) -{ - dst->append("\\u"); - for (size_t i = 0; i < 4; ++i) { - dst->append(hexDigits[(number & 0xF000) >> 12]); - number <<= 4; - } -} - -void escapeStringForJSON(const String16& str, String16Builder* dst) -{ - for (unsigned i = 0; i < str.length(); ++i) { - UChar c = str[i]; - if (!escapeChar(c, dst)) { - if (c < 32 || c > 126 || c == '<' || c == '>') { - // 1. Escaping <, > to prevent script execution. - // 2. Technically, we could also pass through c > 126 as UTF8, but this - // is also optional. It would also be a pain to implement here. - appendUnsignedAsHex(c, dst); - } else { - dst->append(c); - } - } - } -} - -void doubleQuoteStringForJSON(const String16& str, String16Builder* dst) -{ - dst->append('"'); - escapeStringForJSON(str, dst); - dst->append('"'); -} - -} // anonymous namespace - -bool Value::asBoolean(bool*) const -{ - return false; -} - -bool Value::asDouble(double*) const -{ - return false; -} - -bool Value::asInteger(int*) const -{ - return false; -} - -bool Value::asString(String16*) const -{ - return false; -} - -bool Value::asSerialized(String16*) const -{ - return false; -} - -String16 Value::toJSONString() const -{ - String16Builder result; - result.reserveCapacity(512); - writeJSON(&result); - return result.toString(); -} - -void Value::writeJSON(String16Builder* output) const -{ - DCHECK(m_type == TypeNull); - output->append(nullString, 4); -} - -std::unique_ptr<Value> Value::clone() const -{ - return Value::null(); -} - -bool FundamentalValue::asBoolean(bool* output) const -{ - if (type() != TypeBoolean) - return false; - *output = m_boolValue; - return true; -} - -bool FundamentalValue::asDouble(double* output) const -{ - if (type() == TypeDouble) { - *output = m_doubleValue; - return true; - } - if (type() == TypeInteger) { - *output = m_integerValue; - return true; - } - return false; -} - -bool FundamentalValue::asInteger(int* output) const -{ - if (type() != TypeInteger) - return false; - *output = m_integerValue; - return true; -} - -void FundamentalValue::writeJSON(String16Builder* output) const -{ - DCHECK(type() == TypeBoolean || type() == TypeInteger || type() == TypeDouble); - if (type() == TypeBoolean) { - if (m_boolValue) - output->append(trueString, 4); - else - output->append(falseString, 5); - } else if (type() == TypeDouble) { - if (!std::isfinite(m_doubleValue)) { - output->append(nullString, 4); - return; - } - output->append(String16::fromDouble(m_doubleValue)); - } else if (type() == TypeInteger) { - output->append(String16::fromInteger(m_integerValue)); - } -} - -std::unique_ptr<Value> FundamentalValue::clone() const -{ - switch (type()) { - case TypeDouble: return FundamentalValue::create(m_doubleValue); - case TypeInteger: return FundamentalValue::create(m_integerValue); - case TypeBoolean: return FundamentalValue::create(m_boolValue); - default: - NOTREACHED(); - } - return nullptr; -} - -bool StringValue::asString(String16* output) const -{ - *output = m_stringValue; - return true; -} - -void StringValue::writeJSON(String16Builder* output) const -{ - DCHECK(type() == TypeString); - doubleQuoteStringForJSON(m_stringValue, output); -} - -std::unique_ptr<Value> StringValue::clone() const -{ - return StringValue::create(m_stringValue); -} - -bool SerializedValue::asSerialized(String16* output) const -{ - *output = m_serializedValue; - return true; -} - -void SerializedValue::writeJSON(String16Builder* output) const -{ - DCHECK(type() == TypeSerialized); - output->append(m_serializedValue); -} - -std::unique_ptr<Value> SerializedValue::clone() const -{ - return SerializedValue::create(m_serializedValue); -} - -DictionaryValue::~DictionaryValue() -{ -} - -void DictionaryValue::setBoolean(const String16& name, bool value) -{ - setValue(name, FundamentalValue::create(value)); -} - -void DictionaryValue::setInteger(const String16& name, int value) -{ - setValue(name, FundamentalValue::create(value)); -} - -void DictionaryValue::setDouble(const String16& name, double value) -{ - setValue(name, FundamentalValue::create(value)); -} - -void DictionaryValue::setString(const String16& name, const String16& value) -{ - setValue(name, StringValue::create(value)); -} - -void DictionaryValue::setValue(const String16& name, std::unique_ptr<Value> value) -{ - set(name, value); -} - -void DictionaryValue::setObject(const String16& name, std::unique_ptr<DictionaryValue> value) -{ - set(name, value); -} - -void DictionaryValue::setArray(const String16& name, std::unique_ptr<ListValue> value) -{ - set(name, value); -} - -bool DictionaryValue::getBoolean(const String16& name, bool* output) const -{ - protocol::Value* value = get(name); - if (!value) - return false; - return value->asBoolean(output); -} - -bool DictionaryValue::getInteger(const String16& name, int* output) const -{ - Value* value = get(name); - if (!value) - return false; - return value->asInteger(output); -} - -bool DictionaryValue::getDouble(const String16& name, double* output) const -{ - Value* value = get(name); - if (!value) - return false; - return value->asDouble(output); -} - -bool DictionaryValue::getString(const String16& name, String16* output) const -{ - protocol::Value* value = get(name); - if (!value) - return false; - return value->asString(output); -} - -DictionaryValue* DictionaryValue::getObject(const String16& name) const -{ - return DictionaryValue::cast(get(name)); -} - -protocol::ListValue* DictionaryValue::getArray(const String16& name) const -{ - return ListValue::cast(get(name)); -} - -protocol::Value* DictionaryValue::get(const String16& name) const -{ - Dictionary::const_iterator it = m_data.find(name); - if (it == m_data.end()) - return nullptr; - return it->second.get(); -} - -DictionaryValue::Entry DictionaryValue::at(size_t index) const -{ - const String16 key = m_order[index]; - return std::make_pair(key, m_data.find(key)->second.get()); -} - -bool DictionaryValue::booleanProperty(const String16& name, bool defaultValue) const -{ - bool result = defaultValue; - getBoolean(name, &result); - return result; -} - -int DictionaryValue::integerProperty(const String16& name, int defaultValue) const -{ - int result = defaultValue; - getInteger(name, &result); - return result; -} - -double DictionaryValue::doubleProperty(const String16& name, double defaultValue) const -{ - double result = defaultValue; - getDouble(name, &result); - return result; -} - -void DictionaryValue::remove(const String16& name) -{ - m_data.erase(name); - m_order.erase(std::remove(m_order.begin(), m_order.end(), name), m_order.end()); -} - -void DictionaryValue::writeJSON(String16Builder* output) const -{ - output->append('{'); - for (size_t i = 0; i < m_order.size(); ++i) { - Dictionary::const_iterator it = m_data.find(m_order[i]); - CHECK(it != m_data.end()); - if (i) - output->append(','); - doubleQuoteStringForJSON(it->first, output); - output->append(':'); - it->second->writeJSON(output); - } - output->append('}'); -} - -std::unique_ptr<Value> DictionaryValue::clone() const -{ - std::unique_ptr<DictionaryValue> result = DictionaryValue::create(); - for (size_t i = 0; i < m_order.size(); ++i) { - String16 key = m_order[i]; - Dictionary::const_iterator value = m_data.find(key); - DCHECK(value != m_data.cend() && value->second); - result->setValue(key, value->second->clone()); - } - return std::move(result); -} - -DictionaryValue::DictionaryValue() - : Value(TypeObject) -{ -} - -ListValue::~ListValue() -{ -} - -void ListValue::writeJSON(String16Builder* output) const -{ - output->append('['); - bool first = true; - for (const std::unique_ptr<protocol::Value>& value : m_data) { - if (!first) - output->append(','); - value->writeJSON(output); - first = false; - } - output->append(']'); -} - -std::unique_ptr<Value> ListValue::clone() const -{ - std::unique_ptr<ListValue> result = ListValue::create(); - for (const std::unique_ptr<protocol::Value>& value : m_data) - result->pushValue(value->clone()); - return std::move(result); -} - -ListValue::ListValue() - : Value(TypeArray) -{ -} - -void ListValue::pushValue(std::unique_ptr<protocol::Value> value) -{ - DCHECK(value); - m_data.push_back(std::move(value)); -} - -protocol::Value* ListValue::at(size_t index) -{ - DCHECK_LT(index, m_data.size()); - return m_data[index].get(); -} - -} // namespace protocol -} // namespace blink
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Values.h b/third_party/WebKit/Source/platform/inspector_protocol/Values.h deleted file mode 100644 index 48a20127..0000000 --- a/third_party/WebKit/Source/platform/inspector_protocol/Values.h +++ /dev/null
@@ -1,250 +0,0 @@ -// Copyright 2016 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 Values_h -#define Values_h - -#include "platform/inspector_protocol/Allocator.h" -#include "platform/inspector_protocol/Collections.h" -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" - -#include <vector> - -namespace blink { -namespace protocol { - -class ListValue; -class DictionaryValue; -class Value; - -class PLATFORM_EXPORT Value { - PROTOCOL_DISALLOW_COPY(Value); -public: - static const int maxDepth = 1000; - - virtual ~Value() { } - - static std::unique_ptr<Value> null() - { - return wrapUnique(new Value()); - } - - enum ValueType { - TypeNull = 0, - TypeBoolean, - TypeInteger, - TypeDouble, - TypeString, - TypeObject, - TypeArray, - TypeSerialized - }; - - ValueType type() const { return m_type; } - - bool isNull() const { return m_type == TypeNull; } - - virtual bool asBoolean(bool* output) const; - virtual bool asDouble(double* output) const; - virtual bool asInteger(int* output) const; - virtual bool asString(String16* output) const; - virtual bool asSerialized(String16* output) const; - - String16 toJSONString() const; - virtual void writeJSON(String16Builder* output) const; - virtual std::unique_ptr<Value> clone() const; - -protected: - Value() : m_type(TypeNull) { } - explicit Value(ValueType type) : m_type(type) { } - -private: - friend class DictionaryValue; - friend class ListValue; - - ValueType m_type; -}; - -class PLATFORM_EXPORT FundamentalValue : public Value { -public: - static std::unique_ptr<FundamentalValue> create(bool value) - { - return wrapUnique(new FundamentalValue(value)); - } - - static std::unique_ptr<FundamentalValue> create(int value) - { - return wrapUnique(new FundamentalValue(value)); - } - - static std::unique_ptr<FundamentalValue> create(double value) - { - return wrapUnique(new FundamentalValue(value)); - } - - bool asBoolean(bool* output) const override; - bool asDouble(double* output) const override; - bool asInteger(int* output) const override; - void writeJSON(String16Builder* output) const override; - std::unique_ptr<Value> clone() const override; - -private: - explicit FundamentalValue(bool value) : Value(TypeBoolean), m_boolValue(value) { } - explicit FundamentalValue(int value) : Value(TypeInteger), m_integerValue(value) { } - explicit FundamentalValue(double value) : Value(TypeDouble), m_doubleValue(value) { } - - union { - bool m_boolValue; - double m_doubleValue; - int m_integerValue; - }; -}; - -class PLATFORM_EXPORT StringValue : public Value { -public: - static std::unique_ptr<StringValue> create(const String16& value) - { - return wrapUnique(new StringValue(value)); - } - - static std::unique_ptr<StringValue> create(const char* value) - { - return wrapUnique(new StringValue(value)); - } - - bool asString(String16* output) const override; - void writeJSON(String16Builder* output) const override; - std::unique_ptr<Value> clone() const override; - -private: - explicit StringValue(const String16& value) : Value(TypeString), m_stringValue(value) { } - explicit StringValue(const char* value) : Value(TypeString), m_stringValue(value) { } - - String16 m_stringValue; -}; - -class PLATFORM_EXPORT SerializedValue : public Value { -public: - static std::unique_ptr<SerializedValue> create(const String16& value) - { - return wrapUnique(new SerializedValue(value)); - } - - bool asSerialized(String16* output) const override; - void writeJSON(String16Builder* output) const override; - std::unique_ptr<Value> clone() const override; - -private: - explicit SerializedValue(const String16& value) : Value(TypeSerialized), m_serializedValue(value) { } - explicit SerializedValue(const char* value) : Value(TypeSerialized), m_serializedValue(value) { } - - String16 m_serializedValue; -}; - -class PLATFORM_EXPORT DictionaryValue : public Value { -public: - using Entry = std::pair<String16, Value*>; - static std::unique_ptr<DictionaryValue> create() - { - return wrapUnique(new DictionaryValue()); - } - - static DictionaryValue* cast(Value* value) - { - if (!value || value->type() != TypeObject) - return nullptr; - return static_cast<DictionaryValue*>(value); - } - - static std::unique_ptr<DictionaryValue> cast(std::unique_ptr<Value> value) - { - return wrapUnique(DictionaryValue::cast(value.release())); - } - - void writeJSON(String16Builder* output) const override; - std::unique_ptr<Value> clone() const override; - - size_t size() const { return m_data.size(); } - - void setBoolean(const String16& name, bool); - void setInteger(const String16& name, int); - void setDouble(const String16& name, double); - void setString(const String16& name, const String16&); - void setValue(const String16& name, std::unique_ptr<Value>); - void setObject(const String16& name, std::unique_ptr<DictionaryValue>); - void setArray(const String16& name, std::unique_ptr<ListValue>); - - bool getBoolean(const String16& name, bool* output) const; - bool getInteger(const String16& name, int* output) const; - bool getDouble(const String16& name, double* output) const; - bool getString(const String16& name, String16* output) const; - - DictionaryValue* getObject(const String16& name) const; - ListValue* getArray(const String16& name) const; - Value* get(const String16& name) const; - Entry at(size_t index) const; - - bool booleanProperty(const String16& name, bool defaultValue) const; - int integerProperty(const String16& name, int defaultValue) const; - double doubleProperty(const String16& name, double defaultValue) const; - void remove(const String16& name); - - ~DictionaryValue() override; - -private: - DictionaryValue(); - template<typename T> - void set(const String16& key, std::unique_ptr<T>& value) - { - DCHECK(value); - bool isNew = m_data.find(key) == m_data.end(); - m_data[key] = std::move(value); - if (isNew) - m_order.push_back(key); - } - - using Dictionary = protocol::HashMap<String16, std::unique_ptr<Value>>; - Dictionary m_data; - std::vector<String16> m_order; -}; - -class PLATFORM_EXPORT ListValue : public Value { -public: - static std::unique_ptr<ListValue> create() - { - return wrapUnique(new ListValue()); - } - - static ListValue* cast(Value* value) - { - if (!value || value->type() != TypeArray) - return nullptr; - return static_cast<ListValue*>(value); - } - - static std::unique_ptr<ListValue> cast(std::unique_ptr<Value> value) - { - return wrapUnique(ListValue::cast(value.release())); - } - - ~ListValue() override; - - void writeJSON(String16Builder* output) const override; - std::unique_ptr<Value> clone() const override; - - void pushValue(std::unique_ptr<Value>); - - Value* at(size_t index); - size_t size() const { return m_data.size(); } - -private: - ListValue(); - std::vector<std::unique_ptr<Value>> m_data; -}; - -} // namespace protocol -} // namespace blink - -#endif // Values_h
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Values_cpp.template b/third_party/WebKit/Source/platform/inspector_protocol/Values_cpp.template new file mode 100644 index 0000000..482ec46 --- /dev/null +++ b/third_party/WebKit/Source/platform/inspector_protocol/Values_cpp.template
@@ -0,0 +1,406 @@ +// Copyright 2016 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 <algorithm> +#include <cmath> + +namespace blink { +namespace protocol { + +namespace { + +const char* const nullValueString = "null"; +const char* const trueValueString = "true"; +const char* const falseValueString = "false"; + +inline bool escapeChar(UChar c, String16Builder* dst) +{ + switch (c) { + case '\b': dst->append("\\b"); break; + case '\f': dst->append("\\f"); break; + case '\n': dst->append("\\n"); break; + case '\r': dst->append("\\r"); break; + case '\t': dst->append("\\t"); break; + case '\\': dst->append("\\\\"); break; + case '"': dst->append("\\\""); break; + default: + return false; + } + return true; +} + +const char hexDigits[17] = "0123456789ABCDEF"; + +void appendUnsignedAsHex(UChar number, String16Builder* dst) +{ + dst->append("\\u"); + for (size_t i = 0; i < 4; ++i) { + UChar c = hexDigits[(number & 0xF000) >> 12]; + dst->append(c); + number <<= 4; + } +} + +void escapeStringForJSON(const String16& str, String16Builder* dst) +{ + for (unsigned i = 0; i < str.length(); ++i) { + UChar c = str[i]; + if (!escapeChar(c, dst)) { + if (c < 32 || c > 126 || c == '<' || c == '>') { + // 1. Escaping <, > to prevent script execution. + // 2. Technically, we could also pass through c > 126 as UTF8, but this + // is also optional. It would also be a pain to implement here. + appendUnsignedAsHex(c, dst); + } else { + dst->append(c); + } + } + } +} + +void doubleQuoteStringForJSON(const String16& str, String16Builder* dst) +{ + dst->append('"'); + escapeStringForJSON(str, dst); + dst->append('"'); +} + +} // anonymous namespace + +bool Value::asBoolean(bool*) const +{ + return false; +} + +bool Value::asDouble(double*) const +{ + return false; +} + +bool Value::asInteger(int*) const +{ + return false; +} + +bool Value::asString(String16*) const +{ + return false; +} + +bool Value::asSerialized(String16*) const +{ + return false; +} + +String16 Value::toJSONString() const +{ + String16Builder result; + result.reserveCapacity(512); + writeJSON(&result); + return result.toString(); +} + +void Value::writeJSON(String16Builder* output) const +{ + DCHECK(m_type == TypeNull); + output->append(nullValueString, 4); +} + +std::unique_ptr<Value> Value::clone() const +{ + return Value::null(); +} + +bool FundamentalValue::asBoolean(bool* output) const +{ + if (type() != TypeBoolean) + return false; + *output = m_boolValue; + return true; +} + +bool FundamentalValue::asDouble(double* output) const +{ + if (type() == TypeDouble) { + *output = m_doubleValue; + return true; + } + if (type() == TypeInteger) { + *output = m_integerValue; + return true; + } + return false; +} + +bool FundamentalValue::asInteger(int* output) const +{ + if (type() != TypeInteger) + return false; + *output = m_integerValue; + return true; +} + +void FundamentalValue::writeJSON(String16Builder* output) const +{ + DCHECK(type() == TypeBoolean || type() == TypeInteger || type() == TypeDouble); + if (type() == TypeBoolean) { + if (m_boolValue) + output->append(trueValueString, 4); + else + output->append(falseValueString, 5); + } else if (type() == TypeDouble) { + if (!std::isfinite(m_doubleValue)) { + output->append(nullValueString, 4); + return; + } + output->append(String16::fromDouble(m_doubleValue)); + } else if (type() == TypeInteger) { + output->append(String16::fromInteger(m_integerValue)); + } +} + +std::unique_ptr<Value> FundamentalValue::clone() const +{ + switch (type()) { + case TypeDouble: return FundamentalValue::create(m_doubleValue); + case TypeInteger: return FundamentalValue::create(m_integerValue); + case TypeBoolean: return FundamentalValue::create(m_boolValue); + default: + NOTREACHED(); + } + return nullptr; +} + +bool StringValue::asString(String16* output) const +{ + *output = m_stringValue; + return true; +} + +void StringValue::writeJSON(String16Builder* output) const +{ + DCHECK(type() == TypeString); + doubleQuoteStringForJSON(m_stringValue, output); +} + +std::unique_ptr<Value> StringValue::clone() const +{ + return StringValue::create(m_stringValue); +} + +bool SerializedValue::asSerialized(String16* output) const +{ + *output = m_serializedValue; + return true; +} + +void SerializedValue::writeJSON(String16Builder* output) const +{ + DCHECK(type() == TypeSerialized); + output->append(m_serializedValue); +} + +std::unique_ptr<Value> SerializedValue::clone() const +{ + return SerializedValue::create(m_serializedValue); +} + +DictionaryValue::~DictionaryValue() +{ +} + +void DictionaryValue::setBoolean(const String16& name, bool value) +{ + setValue(name, FundamentalValue::create(value)); +} + +void DictionaryValue::setInteger(const String16& name, int value) +{ + setValue(name, FundamentalValue::create(value)); +} + +void DictionaryValue::setDouble(const String16& name, double value) +{ + setValue(name, FundamentalValue::create(value)); +} + +void DictionaryValue::setString(const String16& name, const String16& value) +{ + setValue(name, StringValue::create(value)); +} + +void DictionaryValue::setValue(const String16& name, std::unique_ptr<Value> value) +{ + set(name, value); +} + +void DictionaryValue::setObject(const String16& name, std::unique_ptr<DictionaryValue> value) +{ + set(name, value); +} + +void DictionaryValue::setArray(const String16& name, std::unique_ptr<ListValue> value) +{ + set(name, value); +} + +bool DictionaryValue::getBoolean(const String16& name, bool* output) const +{ + protocol::Value* value = get(name); + if (!value) + return false; + return value->asBoolean(output); +} + +bool DictionaryValue::getInteger(const String16& name, int* output) const +{ + Value* value = get(name); + if (!value) + return false; + return value->asInteger(output); +} + +bool DictionaryValue::getDouble(const String16& name, double* output) const +{ + Value* value = get(name); + if (!value) + return false; + return value->asDouble(output); +} + +bool DictionaryValue::getString(const String16& name, String16* output) const +{ + protocol::Value* value = get(name); + if (!value) + return false; + return value->asString(output); +} + +DictionaryValue* DictionaryValue::getObject(const String16& name) const +{ + return DictionaryValue::cast(get(name)); +} + +protocol::ListValue* DictionaryValue::getArray(const String16& name) const +{ + return ListValue::cast(get(name)); +} + +protocol::Value* DictionaryValue::get(const String16& name) const +{ + Dictionary::const_iterator it = m_data.find(name); + if (it == m_data.end()) + return nullptr; + return it->second.get(); +} + +DictionaryValue::Entry DictionaryValue::at(size_t index) const +{ + const String16 key = m_order[index]; + return std::make_pair(key, m_data.find(key)->second.get()); +} + +bool DictionaryValue::booleanProperty(const String16& name, bool defaultValue) const +{ + bool result = defaultValue; + getBoolean(name, &result); + return result; +} + +int DictionaryValue::integerProperty(const String16& name, int defaultValue) const +{ + int result = defaultValue; + getInteger(name, &result); + return result; +} + +double DictionaryValue::doubleProperty(const String16& name, double defaultValue) const +{ + double result = defaultValue; + getDouble(name, &result); + return result; +} + +void DictionaryValue::remove(const String16& name) +{ + m_data.erase(name); + m_order.erase(std::remove(m_order.begin(), m_order.end(), name), m_order.end()); +} + +void DictionaryValue::writeJSON(String16Builder* output) const +{ + output->append('{'); + for (size_t i = 0; i < m_order.size(); ++i) { + Dictionary::const_iterator it = m_data.find(m_order[i]); + CHECK(it != m_data.end()); + if (i) + output->append(','); + doubleQuoteStringForJSON(it->first, output); + output->append(':'); + it->second->writeJSON(output); + } + output->append('}'); +} + +std::unique_ptr<Value> DictionaryValue::clone() const +{ + std::unique_ptr<DictionaryValue> result = DictionaryValue::create(); + for (size_t i = 0; i < m_order.size(); ++i) { + String16 key = m_order[i]; + Dictionary::const_iterator value = m_data.find(key); + DCHECK(value != m_data.cend() && value->second); + result->setValue(key, value->second->clone()); + } + return std::move(result); +} + +DictionaryValue::DictionaryValue() + : Value(TypeObject) +{ +} + +ListValue::~ListValue() +{ +} + +void ListValue::writeJSON(String16Builder* output) const +{ + output->append('['); + bool first = true; + for (const std::unique_ptr<protocol::Value>& value : m_data) { + if (!first) + output->append(','); + value->writeJSON(output); + first = false; + } + output->append(']'); +} + +std::unique_ptr<Value> ListValue::clone() const +{ + std::unique_ptr<ListValue> result = ListValue::create(); + for (const std::unique_ptr<protocol::Value>& value : m_data) + result->pushValue(value->clone()); + return std::move(result); +} + +ListValue::ListValue() + : Value(TypeArray) +{ +} + +void ListValue::pushValue(std::unique_ptr<protocol::Value> value) +{ + DCHECK(value); + m_data.push_back(std::move(value)); +} + +protocol::Value* ListValue::at(size_t index) +{ + DCHECK_LT(index, m_data.size()); + return m_data[index].get(); +} + +} // namespace protocol +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/Values_h.template b/third_party/WebKit/Source/platform/inspector_protocol/Values_h.template new file mode 100644 index 0000000..840d1198 --- /dev/null +++ b/third_party/WebKit/Source/platform/inspector_protocol/Values_h.template
@@ -0,0 +1,251 @@ +// Copyright 2016 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 Values_h +#define Values_h + +//#include "Allocator.h" +//#include "Collections.h" +//#include "Platform.h" +//#include "String16.h" +#include "{{export_macro_include}}" + +#include <vector> + +namespace blink { +namespace protocol { + +class ListValue; +class DictionaryValue; +class Value; + +class {{export_macro}} Value { + PROTOCOL_DISALLOW_COPY(Value); +public: + static const int maxDepth = 1000; + + virtual ~Value() { } + + static std::unique_ptr<Value> null() + { + return wrapUnique(new Value()); + } + + enum ValueType { + TypeNull = 0, + TypeBoolean, + TypeInteger, + TypeDouble, + TypeString, + TypeObject, + TypeArray, + TypeSerialized + }; + + ValueType type() const { return m_type; } + + bool isNull() const { return m_type == TypeNull; } + + virtual bool asBoolean(bool* output) const; + virtual bool asDouble(double* output) const; + virtual bool asInteger(int* output) const; + virtual bool asString(String16* output) const; + virtual bool asSerialized(String16* output) const; + + String16 toJSONString() const; + virtual void writeJSON(String16Builder* output) const; + virtual std::unique_ptr<Value> clone() const; + +protected: + Value() : m_type(TypeNull) { } + explicit Value(ValueType type) : m_type(type) { } + +private: + friend class DictionaryValue; + friend class ListValue; + + ValueType m_type; +}; + +class {{export_macro}} FundamentalValue : public Value { +public: + static std::unique_ptr<FundamentalValue> create(bool value) + { + return wrapUnique(new FundamentalValue(value)); + } + + static std::unique_ptr<FundamentalValue> create(int value) + { + return wrapUnique(new FundamentalValue(value)); + } + + static std::unique_ptr<FundamentalValue> create(double value) + { + return wrapUnique(new FundamentalValue(value)); + } + + bool asBoolean(bool* output) const override; + bool asDouble(double* output) const override; + bool asInteger(int* output) const override; + void writeJSON(String16Builder* output) const override; + std::unique_ptr<Value> clone() const override; + +private: + explicit FundamentalValue(bool value) : Value(TypeBoolean), m_boolValue(value) { } + explicit FundamentalValue(int value) : Value(TypeInteger), m_integerValue(value) { } + explicit FundamentalValue(double value) : Value(TypeDouble), m_doubleValue(value) { } + + union { + bool m_boolValue; + double m_doubleValue; + int m_integerValue; + }; +}; + +class {{export_macro}} StringValue : public Value { +public: + static std::unique_ptr<StringValue> create(const String16& value) + { + return wrapUnique(new StringValue(value)); + } + + static std::unique_ptr<StringValue> create(const char* value) + { + return wrapUnique(new StringValue(value)); + } + + bool asString(String16* output) const override; + void writeJSON(String16Builder* output) const override; + std::unique_ptr<Value> clone() const override; + +private: + explicit StringValue(const String16& value) : Value(TypeString), m_stringValue(value) { } + explicit StringValue(const char* value) : Value(TypeString), m_stringValue(value) { } + + String16 m_stringValue; +}; + +class {{export_macro}} SerializedValue : public Value { +public: + static std::unique_ptr<SerializedValue> create(const String16& value) + { + return wrapUnique(new SerializedValue(value)); + } + + bool asSerialized(String16* output) const override; + void writeJSON(String16Builder* output) const override; + std::unique_ptr<Value> clone() const override; + +private: + explicit SerializedValue(const String16& value) : Value(TypeSerialized), m_serializedValue(value) { } + explicit SerializedValue(const char* value) : Value(TypeSerialized), m_serializedValue(value) { } + + String16 m_serializedValue; +}; + +class {{export_macro}} DictionaryValue : public Value { +public: + using Entry = std::pair<String16, Value*>; + static std::unique_ptr<DictionaryValue> create() + { + return wrapUnique(new DictionaryValue()); + } + + static DictionaryValue* cast(Value* value) + { + if (!value || value->type() != TypeObject) + return nullptr; + return static_cast<DictionaryValue*>(value); + } + + static std::unique_ptr<DictionaryValue> cast(std::unique_ptr<Value> value) + { + return wrapUnique(DictionaryValue::cast(value.release())); + } + + void writeJSON(String16Builder* output) const override; + std::unique_ptr<Value> clone() const override; + + size_t size() const { return m_data.size(); } + + void setBoolean(const String16& name, bool); + void setInteger(const String16& name, int); + void setDouble(const String16& name, double); + void setString(const String16& name, const String16&); + void setValue(const String16& name, std::unique_ptr<Value>); + void setObject(const String16& name, std::unique_ptr<DictionaryValue>); + void setArray(const String16& name, std::unique_ptr<ListValue>); + + bool getBoolean(const String16& name, bool* output) const; + bool getInteger(const String16& name, int* output) const; + bool getDouble(const String16& name, double* output) const; + bool getString(const String16& name, String16* output) const; + + DictionaryValue* getObject(const String16& name) const; + ListValue* getArray(const String16& name) const; + Value* get(const String16& name) const; + Entry at(size_t index) const; + + bool booleanProperty(const String16& name, bool defaultValue) const; + int integerProperty(const String16& name, int defaultValue) const; + double doubleProperty(const String16& name, double defaultValue) const; + void remove(const String16& name); + + ~DictionaryValue() override; + +private: + DictionaryValue(); + template<typename T> + void set(const String16& key, std::unique_ptr<T>& value) + { + DCHECK(value); + bool isNew = m_data.find(key) == m_data.end(); + m_data[key] = std::move(value); + if (isNew) + m_order.push_back(key); + } + + using Dictionary = protocol::HashMap<String16, std::unique_ptr<Value>>; + Dictionary m_data; + std::vector<String16> m_order; +}; + +class {{export_macro}} ListValue : public Value { +public: + static std::unique_ptr<ListValue> create() + { + return wrapUnique(new ListValue()); + } + + static ListValue* cast(Value* value) + { + if (!value || value->type() != TypeArray) + return nullptr; + return static_cast<ListValue*>(value); + } + + static std::unique_ptr<ListValue> cast(std::unique_ptr<Value> value) + { + return wrapUnique(ListValue::cast(value.release())); + } + + ~ListValue() override; + + void writeJSON(String16Builder* output) const override; + std::unique_ptr<Value> clone() const override; + + void pushValue(std::unique_ptr<Value>); + + Value* at(size_t index); + size_t size() const { return m_data.size(); } + +private: + ListValue(); + std::vector<std::unique_ptr<Value>> m_data; +}; + +} // namespace protocol +} // namespace blink + +#endif // Values_h
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/generate-inspector-protocol-version b/third_party/WebKit/Source/platform/inspector_protocol/generate-inspector-protocol-version index 0c01e16..0fe8dcc 100755 --- a/third_party/WebKit/Source/platform/inspector_protocol/generate-inspector-protocol-version +++ b/third_party/WebKit/Source/platform/inspector_protocol/generate-inspector-protocol-version
@@ -4,7 +4,7 @@ # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: -# +# # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above @@ -14,7 +14,7 @@ # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. -# +# # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -28,7 +28,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Inspector protocol validator. -# +# # Tests that subsequent protocol changes are not breaking backwards compatibility. # Following violations are reported: # @@ -39,7 +39,7 @@ # - Event has been removed # - Required event parameter was removed or changed to optional # - Parameter type has changed. -# +# # For the parameters with composite types the above checks are also applied # recursively to every property of the type. # @@ -197,7 +197,7 @@ ref = typed_object["$ref"] if not ref in types_map: errors.append("Can not resolve type: %s" % ref) - types_map[ref] = { "id": "<transient>", "type": "object" } + types_map[ref] = { "id": "<transient>", "type": "object" } return types_map[ref] @@ -452,7 +452,8 @@ expected_errors = [ "Debugger.globalObjectCleared: event has been removed", - "Runtime.executionContextCreated.context parameter->Runtime.ExecutionContextDescription.frameId: required property has been removed" + "Runtime.executionContextCreated.context parameter->Runtime.ExecutionContextDescription.frameId: required property has been removed", + "Debugger.canSetScriptSource: command has been removed" ] errors = compare_schemas(baseline_domains, domains, False)
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/sample_config.json b/third_party/WebKit/Source/platform/inspector_protocol/sample_config.json new file mode 100644 index 0000000..48cad2e0 --- /dev/null +++ b/third_party/WebKit/Source/platform/inspector_protocol/sample_config.json
@@ -0,0 +1,34 @@ +{ + "protocol": { + "path": "protocol/sample_protocol.json", + "package": "include/generated/files/like/this", + "output": "place/generated/files/here" + }, + + "import": { + "path": "../relative/path/imported_protocol.json", + "package": "include/imported/files/like/this" + }, + + "export": { + "package": "include/exported/files/like/this", + "output": "place/exported/files/here" + }, + + "string": { + "class_name": "String16" + }, + + "lib": { + "output": "place/generated/lib/files/here", + "string16_impl_header_path": "sting16/implementation.h", + "platform_impl_header_path": "platform/implementation.h" + }, + + "lib_package": "include/lib/files/like/this", + + "class_export": { + "macro": "LIB_EXPORT", + "header_path": "lib/export.h" + } +}
diff --git a/third_party/WebKit/Source/platform/network/NetworkLog.h b/third_party/WebKit/Source/platform/network/NetworkLog.h new file mode 100644 index 0000000..3b786c0 --- /dev/null +++ b/third_party/WebKit/Source/platform/network/NetworkLog.h
@@ -0,0 +1,20 @@ +// Copyright 2016 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 NetworkLog_h +#define NetworkLog_h + +#include "wtf/Assertions.h" + +#if DCHECK_IS_ON() +// We can see logs with |--v=N| or |--vmodule=NetworkLog=N| where N is a +// verbose level. +#define NETWORK_DVLOG(verbose_level) \ + LAZY_STREAM(VLOG_STREAM(verbose_level), \ + ((verbose_level) <= ::logging::GetVlogLevel("NetworkLog.h"))) +#else +#define NETWORK_DVLOG(verbose_level) EAT_STREAM_PARAMETERS +#endif + +#endif // NetworkLog_h
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorTest.cpp b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorTest.cpp index c3436ce..9152843 100644 --- a/third_party/WebKit/Source/platform/scroll/ScrollAnimatorTest.cpp +++ b/third_party/WebKit/Source/platform/scroll/ScrollAnimatorTest.cpp
@@ -27,7 +27,6 @@ #include "platform/scroll/ScrollAnimator.h" -#include "platform/Logging.h" #include "platform/geometry/FloatPoint.h" #include "platform/geometry/IntRect.h" #include "platform/scroll/ScrollAnimatorBase.h"
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp b/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp index a01daf6..a8e8fb8 100644 --- a/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp +++ b/third_party/WebKit/Source/platform/scroll/ScrollableArea.cpp
@@ -32,7 +32,6 @@ #include "platform/scroll/ScrollableArea.h" #include "platform/HostWindow.h" -#include "platform/Logging.h" #include "platform/geometry/DoubleRect.h" #include "platform/geometry/FloatPoint.h" #include "platform/geometry/LayoutRect.h"
diff --git a/third_party/WebKit/Source/platform/text/CharacterEmoji.cpp b/third_party/WebKit/Source/platform/text/CharacterEmoji.cpp index 7b8729e9..714f70f 100644 --- a/third_party/WebKit/Source/platform/text/CharacterEmoji.cpp +++ b/third_party/WebKit/Source/platform/text/CharacterEmoji.cpp
@@ -6,7 +6,7 @@ #include <unicode/uvernum.h> -#if defined(USING_SYSTEM_ICU) && (U_ICU_VERSION_MAJOR_NUM <= 56) +#if defined(USING_SYSTEM_ICU) || (U_ICU_VERSION_MAJOR_NUM <= 57) #include <unicode/uniset.h> #else #include <unicode/uchar.h> @@ -17,69 +17,168 @@ namespace blink { -// ICU 56 or earlier does not have API for Emoji properties, -// but Chrome's copy of ICU 56 does. -#if defined(USING_SYSTEM_ICU) && (U_ICU_VERSION_MAJOR_NUM <= 56) +// ICU 57 or earlier does not have up to date Emoji properties, so we're +// temporarily uing our own functions again. Compare crbug.com/628333 Other than +// that: versions before 56 do not have an API for Emoji properties, but +// Chrome's copy of ICU 56 does. +#if defined(USING_SYSTEM_ICU) || (U_ICU_VERSION_MAJOR_NUM <= 57) // The following UnicodeSet patterns were compiled from -// http://www.unicode.org/Public/emoji/2.0//emoji-data.txt +// http://www.unicode.org/Public/emoji/3.0//emoji-data.txt + +// The following patterns can be generated from the respective sections of the +// emoji_data.txt file by using the following Elisp function in Emacs. +// Known issues: +// 1) Does not insert the double [[ and ]] at the beginning and end of the +// pattern. +// 2) Does not insert \U0000 at the very last codepoint of a pattern. +// +// (defun convertemojidata () +// "Convert a section of the emoji_data.txt file to an ICU trie definition." +// (interactive) +// (goto-char 0) +// (while (re-search-forward " *;.*$" nil t) +// (replace-match "" nil nil)) +// (goto-char 0) +// (while (re-search-forward "\\.\\." nil t) +// (replace-match "-" nil nil)) +// (goto-char 0) +// ; Pad 4 digit characters, step 1 +// (while (re-search-forward "\\([^0-9A-F]*\\)\\([0-9A-F]\\{4\\}\\)\\([^0-9A-F]\\)" nil t) +// (replace-match "\\1\\\\U0000\\2\\3" nil nil)) +// (goto-char 0) +// ; Fix up 5 digit characters padding, step 2 +// (while (re-search-forward "1\\\\U0000" nil t) +// (replace-match "\\\\U0001" nil nil)) +// (goto-char 0) +// (while (re-search-forward "^\\(.*\\)$" nil t) +// (replace-match "[\\1]" nil nil)) +// (goto-char 0) +// (replace-string "\n" " ") +// (set-fill-column 72) +// (goto-char 0) +// (fill-paragraph) +// (replace-string " " "") +// (goto-char 0) +// (while (re-search-forward "^\\(.*\\)$" nil t) +// (replace-match " R\"(\\1)\"" nil nil)) +// (goto-char 8) +// (insert "[") +// (goto-char (- (point-max) 3)) +// (insert "]") +// ) static const char kEmojiTextPattern[] = - R"([[#][*][0-9][\u00A9][\u00AE][\u203C][\u2049][\u2122][\u2139])" - R"([\u2194-\u2199][\u21A9-\u21AA][\u231A-\u231B][\u2328][\u23CF])" - R"([\u23E9-\u23F3][\u23F8-\u23FA][\u24C2][\u25AA-\u25AB][\u25B6][\u25C0])" - R"([\u25FB-\u25FE][\u2600-\u2604][\u260E][\u2611][\u2614-\u2615][\u2618])" - R"([\u261D][\u2620][\u2622-\u2623][\u2626][\u262A][\u262E-\u262F])" - R"([\u2638-\u263A][\u2648-\u2653][\u2660][\u2663][\u2665-\u2666][\u2668])" - R"([\u267B][\u267F][\u2692-\u2694][\u2696-\u2697][\u2699][\u269B-\u269C])" - R"([\u26A0-\u26A1][\u26AA-\u26AB][\u26B0-\u26B1][\u26BD-\u26BE])" - R"([\u26C4-\u26C5][\u26C8][\u26CE-\u26CF][\u26D1][\u26D3-\u26D4])" - R"([\u26E9-\u26EA][\u26F0-\u26F5][\u26F7-\u26FA][\u26FD][\u2702][\u2705])" - R"([\u2708-\u270D][\u270F][\u2712][\u2714][\u2716][\u271D][\u2721][\u2728])" - R"([\u2733-\u2734][\u2744][\u2747][\u274C][\u274E][\u2753-\u2755][\u2757])" - R"([\u2763-\u2764][\u2795-\u2797][\u27A1][\u27B0][\u27BF][\u2934-\u2935])" - R"([\u2B05-\u2B07][\u2B1B-\u2B1C][\u2B50][\u2B55][\u3030][\u303D][\u3297])" - R"([\u3299][\U0001F004][\U0001F0CF][\U0001F170-\U0001F171])" - R"([\U0001F17E-\U0001F17F][\U0001F18E][\U0001F191-\U0001F19A])" - R"([\U0001F1E6-\U0001F1FF][\U0001F201-\U0001F202][\U0001F21A][\U0001F22F])" - R"([\U0001F232-\U0001F23A][\U0001F250-\U0001F251][\U0001F300-\U0001F321])" - R"([\U0001F324-\U0001F393][\U0001F396-\U0001F397][\U0001F399-\U0001F39B])" - R"([\U0001F39E-\U0001F3F0][\U0001F3F3-\U0001F3F5][\U0001F3F7-\U0001F4FD])" - R"([\U0001F4FF-\U0001F53D][\U0001F549-\U0001F54E][\U0001F550-\U0001F567])" - R"([\U0001F56F-\U0001F570][\U0001F573-\U0001F579][\U0001F587])" - R"([\U0001F58A-\U0001F58D][\U0001F590][\U0001F595-\U0001F596][\U0001F5A5])" - R"([\U0001F5A8][\U0001F5B1-\U0001F5B2][\U0001F5BC][\U0001F5C2-\U0001F5C4])" - R"([\U0001F5D1-\U0001F5D3][\U0001F5DC-\U0001F5DE][\U0001F5E1][\U0001F5E3])" - R"([\U0001F5E8][\U0001F5EF][\U0001F5F3][\U0001F5FA-\U0001F64F])" - R"([\U0001F680-\U0001F6C5][\U0001F6CB-\U0001F6D0][\U0001F6E0-\U0001F6E5])" - R"([\U0001F6E9][\U0001F6EB-\U0001F6EC][\U0001F6F0][\U0001F6F3])" - R"([\U0001F910-\U0001F918][\U0001F980-\U0001F984][\U0001F9C0]])"; + R"([[\U00000023][\U0000002A][\U00000030-\U00000039][\U000000A9])" + R"([\U000000AE][\U0000203C][\U00002049][\U00002122][\U00002139])" + R"([\U00002194-\U00002199][\U000021A9-\U000021AA][\U0000231A-\U0000231B])" + R"([\U00002328][\U000023CF][\U000023E9-\U000023F3])" + R"([\U000023F8-\U000023FA][\U000024C2][\U000025AA-\U000025AB])" + R"([\U000025B6][\U000025C0][\U000025FB-\U000025FE])" + R"([\U00002600-\U00002604][\U0000260E][\U00002611])" + R"([\U00002614-\U00002615][\U00002618][\U0000261D][\U00002620])" + R"([\U00002622-\U00002623][\U00002626][\U0000262A])" + R"([\U0000262E-\U0000262F][\U00002638-\U0000263A][\U00002640])" + R"([\U00002642][\U00002648-\U00002653][\U00002660][\U00002663])" + R"([\U00002665-\U00002666][\U00002668][\U0000267B][\U0000267F])" + R"([\U00002692-\U00002697][\U00002699][\U0000269B-\U0000269C])" + R"([\U000026A0-\U000026A1][\U000026AA-\U000026AB][\U000026B0-\U000026B1])" + R"([\U000026BD-\U000026BE][\U000026C4-\U000026C5][\U000026C8])" + R"([\U000026CE][\U000026CF][\U000026D1][\U000026D3-\U000026D4])" + R"([\U000026E9-\U000026EA][\U000026F0-\U000026F5][\U000026F7-\U000026FA])" + R"([\U000026FD][\U00002702][\U00002705][\U00002708-\U00002709])" + R"([\U0000270A-\U0000270B][\U0000270C-\U0000270D][\U0000270F])" + R"([\U00002712][\U00002714][\U00002716][\U0000271D][\U00002721])" + R"([\U00002728][\U00002733-\U00002734][\U00002744][\U00002747])" + R"([\U0000274C][\U0000274E][\U00002753-\U00002755][\U00002757])" + R"([\U00002763-\U00002764][\U00002795-\U00002797][\U000027A1])" + R"([\U000027B0][\U000027BF][\U00002934-\U00002935])" + R"([\U00002B05-\U00002B07][\U00002B1B-\U00002B1C][\U00002B50])" + R"([\U00002B55][\U00003030][\U0000303D][\U00003297][\U00003299])" + R"([\U0001F004][\U0001F0CF][\U0001F170-\U0001F171][\U0001F17E])" + R"([\U0001F17F][\U0001F18E][\U0001F191-\U0001F19A])" + R"([\U0001F1E6-\U0001F1FF][\U0001F201-\U0001F202][\U0001F21A])" + R"([\U0001F22F][\U0001F232-\U0001F23A][\U0001F250-\U0001F251])" + R"([\U0001F300-\U0001F320][\U0001F321][\U0001F324-\U0001F32C])" + R"([\U0001F32D-\U0001F32F][\U0001F330-\U0001F335][\U0001F336])" + R"([\U0001F337-\U0001F37C][\U0001F37D][\U0001F37E-\U0001F37F])" + R"([\U0001F380-\U0001F393][\U0001F396-\U0001F397][\U0001F399-\U0001F39B])" + R"([\U0001F39E-\U0001F39F][\U0001F3A0-\U0001F3C4][\U0001F3C5])" + R"([\U0001F3C6-\U0001F3CA][\U0001F3CB-\U0001F3CE][\U0001F3CF-\U0001F3D3])" + R"([\U0001F3D4-\U0001F3DF][\U0001F3E0-\U0001F3F0][\U0001F3F3-\U0001F3F5])" + R"([\U0001F3F7][\U0001F3F8-\U0001F3FF][\U0001F400-\U0001F43E])" + R"([\U0001F43F][\U0001F440][\U0001F441][\U0001F442-\U0001F4F7])" + R"([\U0001F4F8][\U0001F4F9-\U0001F4FC][\U0001F4FD][\U0001F4FF])" + R"([\U0001F500-\U0001F53D][\U0001F549-\U0001F54A][\U0001F54B-\U0001F54E])" + R"([\U0001F550-\U0001F567][\U0001F56F-\U0001F570][\U0001F573-\U0001F579])" + R"([\U0001F57A][\U0001F587][\U0001F58A-\U0001F58D][\U0001F590])" + R"([\U0001F595-\U0001F596][\U0001F5A4][\U0001F5A5][\U0001F5A8])" + R"([\U0001F5B1-\U0001F5B2][\U0001F5BC][\U0001F5C2-\U0001F5C4])" + R"([\U0001F5D1-\U0001F5D3][\U0001F5DC-\U0001F5DE][\U0001F5E1])" + R"([\U0001F5E3][\U0001F5E8][\U0001F5EF][\U0001F5F3][\U0001F5FA])" + R"([\U0001F5FB-\U0001F5FF][\U0001F600][\U0001F601-\U0001F610])" + R"([\U0001F611][\U0001F612-\U0001F614][\U0001F615][\U0001F616])" + R"([\U0001F617][\U0001F618][\U0001F619][\U0001F61A][\U0001F61B])" + R"([\U0001F61C-\U0001F61E][\U0001F61F][\U0001F620-\U0001F625])" + R"([\U0001F626-\U0001F627][\U0001F628-\U0001F62B][\U0001F62C])" + R"([\U0001F62D][\U0001F62E-\U0001F62F][\U0001F630-\U0001F633])" + R"([\U0001F634][\U0001F635-\U0001F640][\U0001F641-\U0001F642])" + R"([\U0001F643-\U0001F644][\U0001F645-\U0001F64F][\U0001F680-\U0001F6C5])" + R"([\U0001F6CB-\U0001F6CF][\U0001F6D0][\U0001F6D1-\U0001F6D2])" + R"([\U0001F6E0-\U0001F6E5][\U0001F6E9][\U0001F6EB-\U0001F6EC])" + R"([\U0001F6F0][\U0001F6F3][\U0001F6F4-\U0001F6F6])" + R"([\U0001F910-\U0001F918][\U0001F919-\U0001F91E][\U0001F920-\U0001F927])" + R"([\U0001F930][\U0001F933-\U0001F93A][\U0001F93C-\U0001F93E])" + R"([\U0001F940-\U0001F945][\U0001F947-\U0001F94B][\U0001F950-\U0001F95E])" + R"([\U0001F980-\U0001F984][\U0001F985-\U0001F991][\U0001F9C0]])"; static const char kEmojiEmojiPattern[] = - R"([[\u231A-\u231B][\u23E9-\u23EC][\u23F0][\u23F3][\u25FD-\u25FE])" - R"([\u2614-\u2615][\u2648-\u2653][\u267F][\u2693][\u26A1][\u26AA-\u26AB])" - R"([\u26BD-\u26BE][\u26C4-\u26C5][\u26CE][\u26D4][\u26EA][\u26F2-\u26F3])" - R"([\u26F5][\u26FA][\u26FD][\u2705][\u270A-\u270B][\u2728][\u274C][\u274E])" - R"([\u2753-\u2755][\u2757][\u2795-\u2797][\u27B0][\u27BF][\u2B1B-\u2B1C])" - R"([\u2B50][\u2B55][\U0001F004][\U0001F0CF][\U0001F18E])" - R"([\U0001F191-\U0001F19A][\U0001F1E6-\U0001F1FF][\U0001F201][\U0001F21A])" - R"([\U0001F22F][\U0001F232-\U0001F236][\U0001F238-\U0001F23A])" - R"([\U0001F250-\U0001F251][\U0001F300-\U0001F320][\U0001F32D-\U0001F335])" - R"([\U0001F337-\U0001F37C][\U0001F37E-\U0001F393][\U0001F3A0-\U0001F3CA])" - R"([\U0001F3CF-\U0001F3D3][\U0001F3E0-\U0001F3F0][\U0001F3F4])" - R"([\U0001F3F8-\U0001F43E][\U0001F440][\U0001F442-\U0001F4FC])" - R"([\U0001F4FF-\U0001F53D][\U0001F54B-\U0001F54E][\U0001F550-\U0001F567])" - R"([\U0001F595-\U0001F596][\U0001F5FB-\U0001F64F][\U0001F680-\U0001F6C5])" - R"([\U0001F6CC][\U0001F6D0][\U0001F6EB-\U0001F6EC][\U0001F910-\U0001F918])" - R"([\U0001F980-\U0001F984][\U0001F9C0]])"; + R"([[\U0000231A-\U0000231B][\U000023E9-\U000023EC][\U000023F0])" + R"([\U000023F3][\U000025FD-\U000025FE][\U00002614-\U00002615])" + R"([\U00002648-\U00002653][\U0000267F][\U00002693][\U000026A1])" + R"([\U000026AA-\U000026AB][\U000026BD-\U000026BE][\U000026C4-\U000026C5])" + R"([\U000026CE][\U000026D4][\U000026EA][\U000026F2-\U000026F3])" + R"([\U000026F5][\U000026FA][\U000026FD][\U00002705])" + R"([\U0000270A-\U0000270B][\U00002728][\U0000274C][\U0000274E])" + R"([\U00002753-\U00002755][\U00002757][\U00002795-\U00002797])" + R"([\U000027B0][\U000027BF][\U00002B1B-\U00002B1C][\U00002B50])" + R"([\U00002B55][\U0001F004][\U0001F0CF][\U0001F18E])" + R"([\U0001F191-\U0001F19A][\U0001F1E6-\U0001F1FF][\U0001F201])" + R"([\U0001F21A][\U0001F22F][\U0001F232-\U0001F236])" + R"([\U0001F238-\U0001F23A][\U0001F250-\U0001F251][\U0001F300-\U0001F320])" + R"([\U0001F32D-\U0001F32F][\U0001F330-\U0001F335][\U0001F337-\U0001F37C])" + R"([\U0001F37E-\U0001F37F][\U0001F380-\U0001F393][\U0001F3A0-\U0001F3C4])" + R"([\U0001F3C5][\U0001F3C6-\U0001F3CA][\U0001F3CF-\U0001F3D3])" + R"([\U0001F3E0-\U0001F3F0][\U0001F3F4][\U0001F3F8-\U0001F3FF])" + R"([\U0001F400-\U0001F43E][\U0001F440][\U0001F442-\U0001F4F7])" + R"([\U0001F4F8][\U0001F4F9-\U0001F4FC][\U0001F4FF])" + R"([\U0001F500-\U0001F53D][\U0001F54B-\U0001F54E][\U0001F550-\U0001F567])" + R"([\U0001F57A][\U0001F595-\U0001F596][\U0001F5A4])" + R"([\U0001F5FB-\U0001F5FF][\U0001F600][\U0001F601-\U0001F610])" + R"([\U0001F611][\U0001F612-\U0001F614][\U0001F615][\U0001F616])" + R"([\U0001F617][\U0001F618][\U0001F619][\U0001F61A][\U0001F61B])" + R"([\U0001F61C-\U0001F61E][\U0001F61F][\U0001F620-\U0001F625])" + R"([\U0001F626-\U0001F627][\U0001F628-\U0001F62B][\U0001F62C])" + R"([\U0001F62D][\U0001F62E-\U0001F62F][\U0001F630-\U0001F633])" + R"([\U0001F634][\U0001F635-\U0001F640][\U0001F641-\U0001F642])" + R"([\U0001F643-\U0001F644][\U0001F645-\U0001F64F][\U0001F680-\U0001F6C5])" + R"([\U0001F6CC][\U0001F6D0][\U0001F6D1-\U0001F6D2])" + R"([\U0001F6EB-\U0001F6EC][\U0001F6F4-\U0001F6F6][\U0001F910-\U0001F918])" + R"([\U0001F919-\U0001F91E][\U0001F920-\U0001F927][\U0001F930])" + R"([\U0001F933-\U0001F93A][\U0001F93C-\U0001F93E][\U0001F940-\U0001F945])" + R"([\U0001F947-\U0001F94B][\U0001F950-\U0001F95E][\U0001F980-\U0001F984])" + R"([\U0001F985-\U0001F991][\U0001F9C0]])"; static const char kEmojiModifierBasePattern[] = - R"([[\u261D][\u26F9][\u270A-\u270D][\U0001F385][\U0001F3C3-\U0001F3C4])" - R"([\U0001F3CA-\U0001F3CB][\U0001F442-\U0001F443][\U0001F446-\U0001F450])" - R"([\U0001F466-\U0001F469][\U0001F46E][\U0001F470-\U0001F478][\U0001F47C])" - R"([\U0001F481-\U0001F483][\U0001F485-\U0001F487][\U0001F4AA][\U0001F575])" - R"([\U0001F590][\U0001F595-\U0001F596][\U0001F645-\U0001F647])" - R"([\U0001F64B-\U0001F64F][\U0001F6A3][\U0001F6B4-\U0001F6B6][\U0001F6C0])" - R"([\U0001F918]])"; + R"([[\U0000261D][\U000026F9][\U0000270A-\U0000270B])" + R"([\U0000270C-\U0000270D][\U0001F385][\U0001F3C2-\U0001F3C4])" + R"([\U0001F3C7][\U0001F3CA][\U0001F3CB-\U0001F3CC])" + R"([\U0001F442-\U0001F443][\U0001F446-\U0001F450][\U0001F466-\U0001F478])" + R"([\U0001F47C][\U0001F481-\U0001F483][\U0001F485-\U0001F487])" + R"([\U0001F4AA][\U0001F574-\U0001F575][\U0001F57A][\U0001F590])" + R"([\U0001F595-\U0001F596][\U0001F645-\U0001F647][\U0001F64B-\U0001F64F])" + R"([\U0001F6A3][\U0001F6B4-\U0001F6B6][\U0001F6C0][\U0001F6CC])" + R"([\U0001F918][\U0001F919-\U0001F91E][\U0001F926][\U0001F930])" + R"([\U0001F933-\U0001F939][\U0001F93C-\U0001F93E]])"; static void applyPatternAndFreeze(icu::UnicodeSet* unicodeSet, const char* pattern) { @@ -142,7 +241,7 @@ bool Character::isEmojiKeycapBase(UChar32 ch) { - return (ch >= '0' && ch <= '9') || ch == '#'; + return (ch >= '0' && ch <= '9') || ch == '#' || ch == '*'; } bool Character::isRegionalIndicator(UChar32 ch)
diff --git a/third_party/WebKit/Source/platform/text/CharacterPropertyDataGenerator.cpp b/third_party/WebKit/Source/platform/text/CharacterPropertyDataGenerator.cpp index 928d24e6..0286f9a8 100644 --- a/third_party/WebKit/Source/platform/text/CharacterPropertyDataGenerator.cpp +++ b/third_party/WebKit/Source/platform/text/CharacterPropertyDataGenerator.cpp
@@ -10,6 +10,7 @@ #include "CharacterProperty.h" #include <cassert> #include <cstring> +#include <memory> #include <stdio.h> #if !defined(USING_SYSTEM_ICU) #define MUTEX_H // Prevent compile failure of utrie2.h on Windows @@ -73,13 +74,13 @@ { // Create a value array of all possible code points. const UChar32 size = kMaxCodepoint + 1; - CharacterProperty* values = new CharacterProperty[size]; - memset(values, 0, sizeof(CharacterProperty) * size); + std::unique_ptr<CharacterProperty[]> values(new CharacterProperty[size]); + memset(values.get(), 0, sizeof(CharacterProperty) * size); #define SET(name) \ - setRanges(values, name##Ranges, ARRAY_LENGTH(name##Ranges), \ + setRanges(values.get(), name##Ranges, ARRAY_LENGTH(name##Ranges), \ CharacterProperty::name); \ - setValues(values, name##Array, ARRAY_LENGTH(name##Array), \ + setValues(values.get(), name##Array, ARRAY_LENGTH(name##Array), \ CharacterProperty::name); SET(isCJKIdeographOrSymbol); @@ -111,11 +112,12 @@ assert(error == U_ZERO_ERROR); int32_t serializedSize = utrie2_serialize(trie, nullptr, 0, &error); error = U_ZERO_ERROR; - uint8_t* serialized = new uint8_t[serializedSize]; - serializedSize = utrie2_serialize(trie, serialized, serializedSize, &error); + std::unique_ptr<uint8_t[]> serialized(new uint8_t[serializedSize]); + serializedSize = utrie2_serialize( + trie, serialized.get(), serializedSize, &error); assert(error == U_ZERO_ERROR); - generateUTrieSerialized(fp, serializedSize, serialized); + generateUTrieSerialized(fp, serializedSize, serialized.get()); utrie2_close(trie); }
diff --git a/third_party/WebKit/Source/platform/text/CharacterPropertyDataGenerator.h b/third_party/WebKit/Source/platform/text/CharacterPropertyDataGenerator.h index 602f2392..9d4707dc 100644 --- a/third_party/WebKit/Source/platform/text/CharacterPropertyDataGenerator.h +++ b/third_party/WebKit/Source/platform/text/CharacterPropertyDataGenerator.h
@@ -20,14 +20,18 @@ 0x2D9, 0x2020, 0x2021, 0x2030, 0x203B, 0x203C, 0x2042, 0x2047, 0x2048, 0x2049, 0x2051, 0x20DD, 0x20DE, 0x2100, 0x2103, 0x2105, 0x2109, 0x210A, 0x2113, 0x2116, 0x2121, - 0x212B, 0x213B, 0x2150, 0x2151, 0x2152, 0x217F, 0x2189, 0x2307, 0x2312, 0x23CE, + 0x212B, 0x213B, 0x2150, 0x2151, 0x2152, 0x217F, 0x2189, 0x2307, 0x23F0, 0x23F3, + 0x2312, 0x23CE, 0x2423, 0x25A0, 0x25A1, 0x25A2, 0x25AA, 0x25AB, 0x25B1, 0x25B2, 0x25B3, 0x25B6, 0x25B7, 0x25BC, 0x25BD, 0x25C0, 0x25C1, 0x25C6, 0x25C7, 0x25C9, 0x25CB, 0x25CC, - 0x25EF, 0x2605, 0x2606, 0x260E, 0x2616, 0x2617, 0x261D, 0x2640, 0x2642, 0x26A0, - 0x26BD, 0x26BE, 0x26F9, 0x2713, 0x271A, 0x273F, 0x2740, 0x2756, 0x2B1A, 0xFE10, - 0xFE11, 0xFE12, 0xFE19, 0xFF1D, + // STAFF OF AESCULAPIUS included to form emoji sequences. + 0x25EF, 0x2605, 0x2606, 0x260E, 0x2616, 0x2617, 0x261D, 0x2640, 0x2642, 0x267F, + 0x2693, 0x2695, 0x26A0, 0x26A1, 0x26BD, 0x26BE, 0x26CE, 0x26D4, 0x26EA, 0x26F5, + 0x26F9, 0x26FA, 0x26FD, 0x2705, 0x2713, 0x271A, 0x2728, 0x273F, 0x2740, 0x274C, + 0x274E, 0x27B0, 0x27BF, 0x2B1A, 0x2B1B, 0x2B1C, 0x2B50, 0x2B55, 0xFE10, 0xFE11, + 0xFE12, 0xFE19, 0xFF1D, // Emoji. - 0x1F100 + 0x1F100, 0x1F004, 0x1F0CF, 0x1F18E }; static const UChar32 isCJKIdeographOrSymbolRanges[] = { @@ -54,20 +58,30 @@ 0x2156, 0x215A, 0x2160, 0x216B, 0x2170, 0x217B, + 0x231A, 0x231B, + 0x23E9, 0x23EC, 0x23BE, 0x23CC, 0x2460, 0x2492, 0x249C, 0x24FF, 0x25CE, 0x25D3, 0x25E2, 0x25E6, + 0x25FD, 0x25FE, 0x2600, 0x2603, 0x2660, 0x266F, // Emoji HEAVY HEART EXCLAMATION MARK ORNAMENT..HEAVY BLACK HEART // Needed in order not to break Emoji heart-kiss sequences in // CachingWordShapeIterator. // cmp. http://www.unicode.org/emoji/charts/emoji-zwj-sequences.html + 0x2614, 0x2615, + 0x2648, 0x2653, + 0x26AA, 0x26AB, + 0x26C4, 0x26C5, + 0x26F2, 0x26F3, + 0x2753, 0x2757, 0x2763, 0x2764, 0x2672, 0x267D, 0x2776, 0x277F, + 0x2795, 0x2797, // Hand signs needed in order // not to break Emoji modifier sequences. 0x270A, 0x270D, @@ -98,11 +112,18 @@ 0x1F130, 0x1F149, 0x1F150, 0x1F169, 0x1F170, 0x1F189, + 0x1F191, 0x1F19A, + 0x1F1E6, 0x1F1FF, 0x1F200, 0x1F6FF, // Modifiers 0x1F3FB, 0x1F3FF, + + 0x1F900, 0x1F90F, // ZIPPER-MOUTH FACE...SIGN OF THE HORNS - 0x1F910, 0x1F918 + 0x1F910, 0x1F918, + 0x1F919, 0x1F97F, + 0x1F980, 0x1F9BF, + 0x1F9C0, 0x1F9FF }; // Individual codepoints needed for Unicode vertical text layout according to
diff --git a/third_party/WebKit/Source/platform/text/CharacterTest.cpp b/third_party/WebKit/Source/platform/text/CharacterTest.cpp index c47d67a4..ea8663b0 100644 --- a/third_party/WebKit/Source/platform/text/CharacterTest.cpp +++ b/third_party/WebKit/Source/platform/text/CharacterTest.cpp
@@ -4,7 +4,6 @@ #include "platform/text/Character.h" -#include "platform/Logging.h" #include "testing/gtest/include/gtest/gtest.h" #include "wtf/text/CharacterNames.h" @@ -76,6 +75,31 @@ TestSpecificUCharRange(0xFE20, 0xFE2F); } +testing::AssertionResult isCJKIdeographOrSymbolWithMessage(UChar32 codepoint) +{ + const size_t formatBufferSize = 10; + char formattedAsHex[formatBufferSize]; + snprintf(formattedAsHex, formatBufferSize, + "0x%x", codepoint); + + if (Character::isCJKIdeographOrSymbol(codepoint)) { + return testing::AssertionSuccess() << "Codepoint " + << formattedAsHex << " is a CJKIdeographOrSymbol."; + } + + return testing::AssertionFailure() << "Codepoint " + << formattedAsHex << " is not a CJKIdeographOrSymbol."; +} + +TEST(CharacterTest, HammerEmojiVsCJKIdeographOrSymbol) +{ + for (UChar32 testChar = 0; testChar < kMaxCodepoint; testChar++) { + if (Character::isEmojiEmojiDefault(testChar)) { + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(testChar)); + } + } +} + TEST(CharacterTest, TestCharacterRangeCodePathSurrogate1) { /* To be surrogate ... */ @@ -193,156 +217,156 @@ static void TestSpecificUChar32RangeIdeographSymbol(UChar32 rangeStart, UChar32 rangeEnd) { - EXPECT_FALSE(Character::isCJKIdeographOrSymbol(rangeStart - 1)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(rangeStart)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol((UChar32)((uint64_t)rangeStart + (uint64_t)rangeEnd) / 2)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(rangeEnd)); - EXPECT_FALSE(Character::isCJKIdeographOrSymbol(rangeEnd + 1)); + EXPECT_FALSE(isCJKIdeographOrSymbolWithMessage(rangeStart - 1)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(rangeStart)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage((UChar32)((uint64_t)rangeStart + (uint64_t)rangeEnd) / 2)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(rangeEnd)); + EXPECT_FALSE(isCJKIdeographOrSymbolWithMessage(rangeEnd + 1)); } TEST(CharacterTest, TestIsCJKIdeographOrSymbol) { // CJK Compatibility Ideographs Supplement. - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2C7)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2CA)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2CB)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2D9)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2C7)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2CA)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2CB)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2D9)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2020)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2021)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2030)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x203B)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x203C)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2042)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2047)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2048)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2049)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2051)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x20DD)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x20DE)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2100)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2103)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2105)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2109)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x210A)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2113)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2116)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2121)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x212B)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x213B)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2150)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2151)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2152)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2020)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2021)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2030)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x203B)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x203C)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2042)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2047)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2048)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2049)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2051)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x20DD)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x20DE)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2100)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2103)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2105)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2109)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x210A)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2113)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2116)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2121)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x212B)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x213B)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2150)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2151)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2152)); TestSpecificUChar32RangeIdeographSymbol(0x2156, 0x215A); TestSpecificUChar32RangeIdeographSymbol(0x2160, 0x216B); TestSpecificUChar32RangeIdeographSymbol(0x2170, 0x217B); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x217F)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2189)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2307)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2312)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x217F)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2189)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2307)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2312)); - EXPECT_FALSE(Character::isCJKIdeographOrSymbol(0x23BD)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x23BE)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x23C4)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x23CC)); - EXPECT_FALSE(Character::isCJKIdeographOrSymbol(0x23CD)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x23CE)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2423)); + EXPECT_FALSE(isCJKIdeographOrSymbolWithMessage(0x23BD)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x23BE)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x23C4)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x23CC)); + EXPECT_FALSE(isCJKIdeographOrSymbolWithMessage(0x23CD)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x23CE)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2423)); TestSpecificUChar32RangeIdeographSymbol(0x2460, 0x2492); TestSpecificUChar32RangeIdeographSymbol(0x249C, 0x24FF); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x25A0)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x25A1)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x25A2)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x25AA)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x25AB)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x25B1)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x25B2)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x25B3)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x25B6)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x25B7)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x25BC)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x25BD)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x25C0)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x25C1)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x25C6)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x25C7)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x25C9)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x25CB)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x25CC)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x25A0)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x25A1)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x25A2)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x25AA)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x25AB)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x25B1)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x25B2)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x25B3)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x25B6)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x25B7)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x25BC)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x25BD)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x25C0)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x25C1)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x25C6)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x25C7)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x25C9)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x25CB)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x25CC)); TestSpecificUChar32RangeIdeographSymbol(0x25CE, 0x25D3); TestSpecificUChar32RangeIdeographSymbol(0x25E2, 0x25E6); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x25EF)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x25EF)); TestSpecificUChar32RangeIdeographSymbol(0x2600, 0x2603); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2605)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2606)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x260E)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2616)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2617)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2640)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2642)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2605)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2606)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x260E)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2616)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2617)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2640)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2642)); TestSpecificUChar32RangeIdeographSymbol(0x2660, 0x266F); TestSpecificUChar32RangeIdeographSymbol(0x2672, 0x267D); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x26A0)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x26BD)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x26BE)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2713)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x271A)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x273F)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2740)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2756)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x26A0)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x26BD)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x26BE)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2713)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x271A)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x273F)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2740)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2756)); TestSpecificUChar32RangeIdeographSymbol(0x2763, 0x2764); TestSpecificUChar32RangeIdeographSymbol(0x2776, 0x277F); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x2B1A)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x2B1A)); TestSpecificUChar32RangeIdeographSymbol(0x2FF0, 0x302D); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x3031)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x312F)); - EXPECT_FALSE(Character::isCJKIdeographOrSymbol(0x3130)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x3031)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x312F)); + EXPECT_FALSE(isCJKIdeographOrSymbolWithMessage(0x3130)); - EXPECT_FALSE(Character::isCJKIdeographOrSymbol(0x318F)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x3190)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x319F)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x31BF)); + EXPECT_FALSE(isCJKIdeographOrSymbolWithMessage(0x318F)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x3190)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x319F)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x31BF)); - EXPECT_FALSE(Character::isCJKIdeographOrSymbol(0x31FF)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x3200)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x3300)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x33FF)); + EXPECT_FALSE(isCJKIdeographOrSymbolWithMessage(0x31FF)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x3200)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x3300)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x33FF)); TestSpecificUChar32RangeIdeographSymbol(0xF860, 0xF862); TestSpecificUChar32RangeIdeographSymbol(0xFE30, 0xFE6F); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0xFE10)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0xFE11)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0xFE12)); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0xFE19)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0xFE10)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0xFE11)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0xFE12)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0xFE19)); - EXPECT_FALSE(Character::isCJKIdeographOrSymbol(0xFF0D)); - EXPECT_FALSE(Character::isCJKIdeographOrSymbol(0xFF1B)); - EXPECT_FALSE(Character::isCJKIdeographOrSymbol(0xFF1C)); - EXPECT_FALSE(Character::isCJKIdeographOrSymbol(0xFF1E)); + EXPECT_FALSE(isCJKIdeographOrSymbolWithMessage(0xFF0D)); + EXPECT_FALSE(isCJKIdeographOrSymbolWithMessage(0xFF1B)); + EXPECT_FALSE(isCJKIdeographOrSymbolWithMessage(0xFF1C)); + EXPECT_FALSE(isCJKIdeographOrSymbolWithMessage(0xFF1E)); TestSpecificUChar32RangeIdeographSymbol(0xFF00, 0xFFEF); - EXPECT_TRUE(Character::isCJKIdeographOrSymbol(0x1F100)); + EXPECT_TRUE(isCJKIdeographOrSymbolWithMessage(0x1F100)); TestSpecificUChar32RangeIdeographSymbol(0x1F110, 0x1F129); TestSpecificUChar32RangeIdeographSymbol(0x1F130, 0x1F149); TestSpecificUChar32RangeIdeographSymbol(0x1F150, 0x1F169); TestSpecificUChar32RangeIdeographSymbol(0x1F170, 0x1F189); - TestSpecificUChar32RangeIdeographSymbol(0x1F200, 0x1F6FF); + TestSpecificUChar32RangeIdeographSymbol(0x1F1E6, 0x1F6FF); } TEST(CharacterTest, TestEmojiTextDefault) @@ -393,6 +417,19 @@ EXPECT_FALSE(Character::isEmojiModifierBase(0x1F47D)); } +TEST(CharacterTest, TestEmoji40Data) +{ + EXPECT_TRUE(Character::isEmojiEmojiDefault(0x1F32F)); + EXPECT_TRUE(Character::isEmojiEmojiDefault(0x1F57A)); + EXPECT_TRUE(Character::isEmojiEmojiDefault(0x1F919)); + EXPECT_TRUE(Character::isEmojiEmojiDefault(0x1F926)); + EXPECT_TRUE(Character::isEmojiModifierBase(0x1F574)); + EXPECT_TRUE(Character::isEmojiModifierBase(0x1F6CC)); + EXPECT_TRUE(Character::isEmojiModifierBase(0x1F919)); + EXPECT_TRUE(Character::isEmojiModifierBase(0x1F926)); + EXPECT_TRUE(Character::isEmojiModifierBase(0x1F933)); +} + TEST(CharacterTest, LineBreakAndQuoteNotEmoji) { EXPECT_FALSE(Character::isEmojiTextDefault('\n'));
diff --git a/third_party/WebKit/Source/platform/text/HyphenationTest.cpp b/third_party/WebKit/Source/platform/text/HyphenationTest.cpp index dc9db2ab..40277f0 100644 --- a/third_party/WebKit/Source/platform/text/HyphenationTest.cpp +++ b/third_party/WebKit/Source/platform/text/HyphenationTest.cpp
@@ -5,7 +5,6 @@ #include "platform/text/Hyphenation.h" #include "platform/LayoutLocale.h" -#include "platform/Logging.h" #include "testing/gtest/include/gtest/gtest.h" namespace blink {
diff --git a/third_party/WebKit/Source/platform/text/TextCheckerClient.h b/third_party/WebKit/Source/platform/text/TextCheckerClient.h index ce4f32bd..74205a7 100644 --- a/third_party/WebKit/Source/platform/text/TextCheckerClient.h +++ b/third_party/WebKit/Source/platform/text/TextCheckerClient.h
@@ -42,7 +42,6 @@ virtual ~TextCheckerClient() { } virtual void checkSpellingOfString(const String&, int* misspellingLocation, int* misspellingLength) = 0; - virtual void checkGrammarOfString(const String&, Vector<GrammarDetail>&, int* badGrammarLocation, int* badGrammarLength) = 0; virtual void requestCheckingOfString(TextCheckingRequest*) = 0; virtual void cancelAllPendingRequests() = 0; };
diff --git a/third_party/WebKit/Source/platform/v8_inspector/DebuggerScript.js b/third_party/WebKit/Source/platform/v8_inspector/DebuggerScript.js index b6e09968..18beac0 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/DebuggerScript.js +++ b/third_party/WebKit/Source/platform/v8_inspector/DebuggerScript.js
@@ -45,11 +45,14 @@ Debug.clearBreakOnUncaughtException(); /** - * @param {!CompileEvent} eventData + * @param {?CompileEvent} eventData */ DebuggerScript.getAfterCompileScript = function(eventData) { - return DebuggerScript._formatScript(eventData.script().value()); + var script = eventData.script().value(); + if (!script.is_debugger_script) + return DebuggerScript._formatScript(eventData.script().value()); + return null; } /** @type {!Map<!ScopeType, string>} */ @@ -180,6 +183,8 @@ if (script.context_data.indexOf(contextDataPrefix) !== 0) continue; } + if (script.is_debugger_script) + continue; result.push(DebuggerScript._formatScript(script)); } return result; @@ -217,8 +222,7 @@ endColumn: endColumn, executionContextId: DebuggerScript._executionContextId(script.context_data), // Note that we cannot derive aux data from context id because of compilation cache. - executionContextAuxData: DebuggerScript._executionContextAuxData(script.context_data), - isInternalScript: script.is_debugger_script + executionContextAuxData: DebuggerScript._executionContextAuxData(script.context_data) }; }
diff --git a/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.cpp b/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.cpp index 3b4552e..fea12ee6 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.cpp +++ b/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.cpp
@@ -30,9 +30,6 @@ #include "platform/v8_inspector/InjectedScript.h" -#include "platform/inspector_protocol/Parser.h" -#include "platform/inspector_protocol/String16.h" -#include "platform/inspector_protocol/Values.h" #include "platform/v8_inspector/InjectedScriptNative.h" #include "platform/v8_inspector/InjectedScriptSource.h" #include "platform/v8_inspector/InspectedContext.h" @@ -318,7 +315,7 @@ return exceptionDetailsObject; } -void InjectedScript::wrapEvaluateResult(ErrorString* errorString, v8::MaybeLocal<v8::Value> maybeResultValue, const v8::TryCatch& tryCatch, const String16& objectGroup, bool returnByValue, bool generatePreview, std::unique_ptr<protocol::Runtime::RemoteObject>* result, Maybe<bool>* wasThrown, Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) +void InjectedScript::wrapEvaluateResult(ErrorString* errorString, v8::MaybeLocal<v8::Value> maybeResultValue, const v8::TryCatch& tryCatch, const String16& objectGroup, bool returnByValue, bool generatePreview, std::unique_ptr<protocol::Runtime::RemoteObject>* result, Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) { v8::Local<v8::Value> resultValue; if (!tryCatch.HasCaught()) { @@ -330,18 +327,13 @@ if (objectGroup == "console") m_lastEvaluationResult.Reset(m_context->isolate(), resultValue); *result = std::move(remoteObject); - if (wasThrown) - *wasThrown = false; } else { v8::Local<v8::Value> exception = tryCatch.Exception(); std::unique_ptr<RemoteObject> remoteObject = wrapObject(errorString, exception, objectGroup, false, generatePreview && !exception->IsNativeError()); if (!remoteObject) return; *result = std::move(remoteObject); - if (exceptionDetails) - *exceptionDetails = createExceptionDetails(tryCatch.Message()); - if (wasThrown) - *wasThrown = true; + *exceptionDetails = createExceptionDetails(tryCatch.Message()); } }
diff --git a/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.h b/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.h index b65a857..c04d752 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.h +++ b/third_party/WebKit/Source/platform/v8_inspector/InjectedScript.h
@@ -31,8 +31,7 @@ #ifndef InjectedScript_h #define InjectedScript_h -#include "platform/inspector_protocol/Allocator.h" -#include "platform/inspector_protocol/Platform.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "platform/v8_inspector/InjectedScriptNative.h" #include "platform/v8_inspector/InspectedContext.h" #include "platform/v8_inspector/V8Console.h" @@ -85,7 +84,6 @@ bool returnByValue, bool generatePreview, std::unique_ptr<protocol::Runtime::RemoteObject>* result, - Maybe<bool>* wasThrown, Maybe<protocol::Runtime::ExceptionDetails>*); v8::Local<v8::Value> lastEvaluationResult() const;
diff --git a/third_party/WebKit/Source/platform/v8_inspector/InjectedScriptNative.cpp b/third_party/WebKit/Source/platform/v8_inspector/InjectedScriptNative.cpp index 4f0eff9..141817c 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/InjectedScriptNative.cpp +++ b/third_party/WebKit/Source/platform/v8_inspector/InjectedScriptNative.cpp
@@ -4,8 +4,6 @@ #include "platform/v8_inspector/InjectedScriptNative.h" -#include "platform/inspector_protocol/Values.h" - namespace blink { InjectedScriptNative::InjectedScriptNative(v8::Isolate* isolate)
diff --git a/third_party/WebKit/Source/platform/v8_inspector/InjectedScriptNative.h b/third_party/WebKit/Source/platform/v8_inspector/InjectedScriptNative.h index c8082fe..b1390f6 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/InjectedScriptNative.h +++ b/third_party/WebKit/Source/platform/v8_inspector/InjectedScriptNative.h
@@ -5,9 +5,7 @@ #ifndef InjectedScriptNative_h #define InjectedScriptNative_h -#include "platform/inspector_protocol/Collections.h" -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include <v8.h> #include <vector>
diff --git a/third_party/WebKit/Source/platform/v8_inspector/InjectedScriptSource.js b/third_party/WebKit/Source/platform/v8_inspector/InjectedScriptSource.js index 7e8b2cb4..92457fd 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/InjectedScriptSource.js +++ b/third_party/WebKit/Source/platform/v8_inspector/InjectedScriptSource.js
@@ -171,7 +171,7 @@ { for (var interfaceName in domAttributesWithObservableSideEffectOnGet) { var interfaceFunction = inspectedGlobalObject[interfaceName]; - // instanceof call looks safe after typeof check. + // Call to instanceOf looks safe after typeof check. var isInstance = typeof interfaceFunction === "function" && /* suppressBlacklist */ object instanceof interfaceFunction; if (isInstance) return attribute in domAttributesWithObservableSideEffectOnGet[interfaceName];
diff --git a/third_party/WebKit/Source/platform/v8_inspector/InspectedContext.h b/third_party/WebKit/Source/platform/v8_inspector/InspectedContext.h index 421d3df..740a2fe3 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/InspectedContext.h +++ b/third_party/WebKit/Source/platform/v8_inspector/InspectedContext.h
@@ -5,9 +5,7 @@ #ifndef InspectedContext_h #define InspectedContext_h -#include "platform/inspector_protocol/Allocator.h" -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include <v8.h> namespace blink {
diff --git a/third_party/WebKit/Source/platform/v8_inspector/JavaScriptCallFrame.h b/third_party/WebKit/Source/platform/v8_inspector/JavaScriptCallFrame.h index 959f817..3f8a80a4 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/JavaScriptCallFrame.h +++ b/third_party/WebKit/Source/platform/v8_inspector/JavaScriptCallFrame.h
@@ -31,9 +31,7 @@ #ifndef JavaScriptCallFrame_h #define JavaScriptCallFrame_h -#include "platform/inspector_protocol/Collections.h" -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include <v8.h> #include <vector>
diff --git a/third_party/WebKit/Source/platform/v8_inspector/PlatformSTL.h b/third_party/WebKit/Source/platform/v8_inspector/PlatformSTL.h new file mode 100644 index 0000000..15dd63e --- /dev/null +++ b/third_party/WebKit/Source/platform/v8_inspector/PlatformSTL.h
@@ -0,0 +1,292 @@ +// Copyright (c) 2016 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 PlatformSTL_h +#define PlatformSTL_h + +#include <memory> + +#define PLATFORM_EXPORT +#ifndef CHECK +#define CHECK(condition) ((void) 0) +#endif +#define DCHECK(condition) ((void) 0) +#define NOTREACHED() +#define DCHECK_EQ(i, j) DCHECK(i == j) +#define DCHECK_GE(i, j) DCHECK(i >= j) +#define DCHECK_LT(i, j) DCHECK(i < j) +#define DCHECK_GT(i, j) DCHECK(i > j) +template <typename T> +inline void USE(T) { } + +#define DEFINE_STATIC_LOCAL(type, name, arguments) \ + static type name; + +#if defined(__APPLE__) && !defined(_LIBCPP_VERSION) + +namespace std { + +template <typename T1, typename T2> +struct is_convertible { +private: + struct True_ { + char x[2]; + }; + struct False_ { + }; + + static True_ helper(T2 const &); + static False_ helper(...); + +public: + static bool const value = ( + sizeof(True_) == sizeof(is_convertible::helper(T1())) + ); +}; + +template <bool, class T = void> +struct enable_if { +}; + +template <class T> +struct enable_if<true, T> { + typedef T type; +}; + +template<class T> +struct remove_extent { + typedef T type; +}; + +template<class T> +struct remove_extent<T[]> { + typedef T type; +}; + +template<class T, std::size_t N> +struct remove_extent<T[N]> { + typedef T type; +}; + +typedef decltype(nullptr) nullptr_t; + +template<class T, T v> +struct integral_constant { + static constexpr T value = v; + typedef T value_type; + typedef integral_constant type; + constexpr operator value_type() const noexcept { return value; } + constexpr value_type operator()() const noexcept { return value; } +}; + +typedef integral_constant<bool, true> true_type; +typedef integral_constant<bool, false> false_type; + +template<class T> +struct is_array : false_type {}; + +template<class T> +struct is_array<T[]> : true_type {}; + +template<class T, std::size_t N> +struct is_array<T[N]> : true_type {}; + +template <typename T> +struct OwnedPtrDeleter { + static void deletePtr(T* ptr) + { + static_assert(sizeof(T) > 0, "type must be complete"); + delete ptr; + } +}; + +template <typename T> +struct OwnedPtrDeleter<T[]> { + static void deletePtr(T* ptr) + { + static_assert(sizeof(T) > 0, "type must be complete"); + delete[] ptr; + } +}; + +template <class T, int n> +struct OwnedPtrDeleter<T[n]> { + static_assert(sizeof(T) < 0, "do not use array with size as type"); +}; + +template <typename T> class unique_ptr { +public: + typedef typename remove_extent<T>::type ValueType; + typedef ValueType* PtrType; + + unique_ptr() : m_ptr(nullptr) {} + unique_ptr(std::nullptr_t) : m_ptr(nullptr) {} + unique_ptr(const unique_ptr&); + unique_ptr(unique_ptr&&); + template <typename U, typename = typename enable_if<is_convertible<U*, T*>::value>::type> unique_ptr(unique_ptr<U>&&); + + ~unique_ptr() + { + OwnedPtrDeleter<T>::deletePtr(m_ptr); + m_ptr = nullptr; + } + + PtrType get() const { return m_ptr; } + + void reset(PtrType = nullptr); + PtrType release() + { + return this->internalRelease(); + } + + ValueType& operator*() const { DCHECK(m_ptr); return *m_ptr; } + PtrType operator->() const { DCHECK(m_ptr); return m_ptr; } + + ValueType& operator[](std::ptrdiff_t i) const; + + bool operator!() const { return !m_ptr; } + explicit operator bool() const { return m_ptr; } + + unique_ptr& operator=(std::nullptr_t) { reset(); return *this; } + + unique_ptr& operator=(const unique_ptr&); + unique_ptr& operator=(unique_ptr&&); + template <typename U> unique_ptr& operator=(unique_ptr<U>&&); + + void swap(unique_ptr& o) { std::swap(m_ptr, o.m_ptr); } + + static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } + + explicit unique_ptr(PtrType ptr) : m_ptr(ptr) {} // NOLINT + +private: + PtrType internalRelease() const + { + PtrType ptr = m_ptr; + m_ptr = nullptr; + return ptr; + } + + // We should never have two unique_ptrs for the same underlying object + // (otherwise we'll get double-destruction), so these equality operators + // should never be needed. + template <typename U> bool operator==(const unique_ptr<U>&) const + { + static_assert(!sizeof(U*), "unique_ptrs should never be equal"); + return false; + } + template <typename U> bool operator!=(const unique_ptr<U>&) const + { + static_assert(!sizeof(U*), "unique_ptrs should never be equal"); + return false; + } + + mutable PtrType m_ptr; +}; + + +template <typename T> inline void unique_ptr<T>::reset(PtrType ptr) +{ + PtrType p = m_ptr; + m_ptr = ptr; + DCHECK(!p || m_ptr != p); + OwnedPtrDeleter<T>::deletePtr(p); +} + +template <typename T> inline typename unique_ptr<T>::ValueType& unique_ptr<T>::operator[](std::ptrdiff_t i) const +{ + static_assert(is_array<T>::value, "elements access is possible for arrays only"); + DCHECK(m_ptr); + DCHECK_GE(i, 0); + return m_ptr[i]; +} + +template <typename T> inline unique_ptr<T>::unique_ptr(const unique_ptr<T>& o) // NOLINT + : m_ptr(o.internalRelease()) +{ +} + +template <typename T> inline unique_ptr<T>::unique_ptr(unique_ptr<T>&& o) // NOLINT + : m_ptr(o.internalRelease()) +{ +} + +template <typename T> +template <typename U, typename> inline unique_ptr<T>::unique_ptr(unique_ptr<U>&& o) + : m_ptr(o.release()) +{ + static_assert(!is_array<T>::value, "pointers to array must never be converted"); +} + +template <typename T> inline unique_ptr<T>& unique_ptr<T>::operator=(const unique_ptr<T>& o) +{ + reset(o.internalRelease()); + return *this; +} + +template <typename T> inline unique_ptr<T>& unique_ptr<T>::operator=(unique_ptr<T>&& o) +{ + reset(o.internalRelease()); + return *this; +} + +template <typename T> +template <typename U> inline unique_ptr<T>& unique_ptr<T>::operator=(unique_ptr<U>&& o) +{ + static_assert(!is_array<T>::value, "pointers to array must never be converted"); + PtrType ptr = m_ptr; + m_ptr = o.release(); + DCHECK(!ptr || m_ptr != ptr); + OwnedPtrDeleter<T>::deletePtr(ptr); + + return *this; +} + +template <typename T> inline void swap(unique_ptr<T>& a, unique_ptr<T>& b) +{ + a.swap(b); +} + +template <typename T, typename U> inline bool operator==(const unique_ptr<T>& a, U* b) +{ + return a.get() == b; +} + +template <typename T, typename U> inline bool operator==(T* a, const unique_ptr<U>& b) +{ + return a == b.get(); +} + +template <typename T, typename U> inline bool operator!=(const unique_ptr<T>& a, U* b) +{ + return a.get() != b; +} + +template <typename T, typename U> inline bool operator!=(T* a, const unique_ptr<U>& b) +{ + return a != b.get(); +} + +template <typename T> inline typename unique_ptr<T>::PtrType getPtr(const unique_ptr<T>& p) +{ + return p.get(); +} + +template <typename T> +unique_ptr<T> move(unique_ptr<T>& ptr) +{ + return unique_ptr<T>(ptr.release()); +} + +} + +#endif // defined(__APPLE__) && !defined(_LIBCPP_VERSION) + +template <typename T> +std::unique_ptr<T> wrapUnique(T* ptr) +{ + return std::unique_ptr<T>(ptr); +} + +#endif // PlatformSTL_h
diff --git a/third_party/WebKit/Source/platform/inspector_protocol/PlatformWTF.h b/third_party/WebKit/Source/platform/v8_inspector/PlatformWTF.h similarity index 100% rename from third_party/WebKit/Source/platform/inspector_protocol/PlatformWTF.h rename to third_party/WebKit/Source/platform/v8_inspector/PlatformWTF.h
diff --git a/third_party/WebKit/Source/platform/v8_inspector/RemoteObjectId.cpp b/third_party/WebKit/Source/platform/v8_inspector/RemoteObjectId.cpp index e9aaf26d..9a6db9720 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/RemoteObjectId.cpp +++ b/third_party/WebKit/Source/platform/v8_inspector/RemoteObjectId.cpp
@@ -4,10 +4,6 @@ #include "platform/v8_inspector/RemoteObjectId.h" -#include "platform/inspector_protocol/Parser.h" -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/Values.h" - namespace blink { RemoteObjectIdBase::RemoteObjectIdBase() : m_injectedScriptId(0) { }
diff --git a/third_party/WebKit/Source/platform/v8_inspector/RemoteObjectId.h b/third_party/WebKit/Source/platform/v8_inspector/RemoteObjectId.h index af3c4b8..694d9bf 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/RemoteObjectId.h +++ b/third_party/WebKit/Source/platform/v8_inspector/RemoteObjectId.h
@@ -5,9 +5,7 @@ #ifndef RemoteObjectId_h #define RemoteObjectId_h -#include "platform/inspector_protocol/ErrorSupport.h" -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" +#include "platform/inspector_protocol/InspectorProtocol.h" namespace blink {
diff --git a/third_party/WebKit/Source/platform/v8_inspector/ScriptBreakpoint.h b/third_party/WebKit/Source/platform/v8_inspector/ScriptBreakpoint.h index 6b2db21..242df54 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/ScriptBreakpoint.h +++ b/third_party/WebKit/Source/platform/v8_inspector/ScriptBreakpoint.h
@@ -30,8 +30,7 @@ #ifndef ScriptBreakpoint_h #define ScriptBreakpoint_h -#include "platform/inspector_protocol/Allocator.h" -#include "platform/inspector_protocol/String16.h" +#include "platform/inspector_protocol/InspectorProtocol.h" namespace blink {
diff --git a/third_party/WebKit/Source/platform/v8_inspector/String16STL.cpp b/third_party/WebKit/Source/platform/v8_inspector/String16STL.cpp new file mode 100644 index 0000000..990932d --- /dev/null +++ b/third_party/WebKit/Source/platform/v8_inspector/String16STL.cpp
@@ -0,0 +1,405 @@ +// Copyright 2016 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 "platform/inspector_protocol/InspectorProtocol.h" + +#include <algorithm> +#include <cctype> +#include <cstdio> +#include <locale> + +namespace blink { +namespace protocol { + +const UChar replacementCharacter = 0xFFFD; +using UChar32 = uint32_t; + +inline int inlineUTF8SequenceLengthNonASCII(char b0) +{ + if ((b0 & 0xC0) != 0xC0) + return 0; + if ((b0 & 0xE0) == 0xC0) + return 2; + if ((b0 & 0xF0) == 0xE0) + return 3; + if ((b0 & 0xF8) == 0xF0) + return 4; + return 0; +} + +inline int inlineUTF8SequenceLength(char b0) +{ + return String16::isASCII(b0) ? 1 : inlineUTF8SequenceLengthNonASCII(b0); +} + +// Once the bits are split out into bytes of UTF-8, this is a mask OR-ed +// into the first byte, depending on how many bytes follow. There are +// as many entries in this table as there are UTF-8 sequence types. +// (I.e., one byte sequence, two byte... etc.). Remember that sequences +// for *legal* UTF-8 will be 4 or fewer bytes total. +static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + +typedef enum { + conversionOK, // conversion successful + sourceExhausted, // partial character in source, but hit end + targetExhausted, // insuff. room in target for conversion + sourceIllegal // source sequence is illegal/malformed +} ConversionResult; + +ConversionResult convertUTF16ToUTF8( + const UChar** sourceStart, const UChar* sourceEnd, + char** targetStart, char* targetEnd, bool strict) +{ + ConversionResult result = conversionOK; + const UChar* source = *sourceStart; + char* target = *targetStart; + while (source < sourceEnd) { + UChar32 ch; + unsigned short bytesToWrite = 0; + const UChar32 byteMask = 0xBF; + const UChar32 byteMark = 0x80; + const UChar* oldSource = source; // In case we have to back up because of target overflow. + ch = static_cast<unsigned short>(*source++); + // If we have a surrogate pair, convert to UChar32 first. + if (ch >= 0xD800 && ch <= 0xDBFF) { + // If the 16 bits following the high surrogate are in the source buffer... + if (source < sourceEnd) { + UChar32 ch2 = static_cast<unsigned short>(*source); + // If it's a low surrogate, convert to UChar32. + if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) { + ch = ((ch - 0xD800) << 10) + (ch2 - 0xDC00) + 0x0010000; + ++source; + } else if (strict) { // it's an unpaired high surrogate + --source; // return to the illegal value itself + result = sourceIllegal; + break; + } + } else { // We don't have the 16 bits following the high surrogate. + --source; // return to the high surrogate + result = sourceExhausted; + break; + } + } else if (strict) { + // UTF-16 surrogate values are illegal in UTF-32 + if (ch >= 0xDC00 && ch <= 0xDFFF) { + --source; // return to the illegal value itself + result = sourceIllegal; + break; + } + } + // Figure out how many bytes the result will require + if (ch < (UChar32)0x80) { + bytesToWrite = 1; + } else if (ch < (UChar32)0x800) { + bytesToWrite = 2; + } else if (ch < (UChar32)0x10000) { + bytesToWrite = 3; + } else if (ch < (UChar32)0x110000) { + bytesToWrite = 4; + } else { + bytesToWrite = 3; + ch = replacementCharacter; + } + + target += bytesToWrite; + if (target > targetEnd) { + source = oldSource; // Back up source pointer! + target -= bytesToWrite; + result = targetExhausted; + break; + } + switch (bytesToWrite) { // note: everything falls through. + case 4: + *--target = (char)((ch | byteMark) & byteMask); + ch >>= 6; + case 3: + *--target = (char)((ch | byteMark) & byteMask); + ch >>= 6; + case 2: + *--target = (char)((ch | byteMark) & byteMask); + ch >>= 6; + case 1: + *--target = (char)(ch | firstByteMark[bytesToWrite]); + } + target += bytesToWrite; + } + *sourceStart = source; + *targetStart = target; + return result; +} + +/** + * Is this code point a BMP code point (U+0000..U+ffff)? + * @param c 32-bit code point + * @return TRUE or FALSE + * @stable ICU 2.8 + */ +#define U_IS_BMP(c) ((uint32_t)(c) <= 0xffff) + +/** + * Is this code point a supplementary code point (U+10000..U+10ffff)? + * @param c 32-bit code point + * @return TRUE or FALSE + * @stable ICU 2.8 + */ +#define U_IS_SUPPLEMENTARY(c) ((uint32_t)((c) - 0x10000) <= 0xfffff) + +/** + * Is this code point a surrogate (U+d800..U+dfff)? + * @param c 32-bit code point + * @return TRUE or FALSE + * @stable ICU 2.4 + */ +#define U_IS_SURROGATE(c) (((c) & 0xfffff800) == 0xd800) + +/** + * Get the lead surrogate (0xd800..0xdbff) for a + * supplementary code point (0x10000..0x10ffff). + * @param supplementary 32-bit code point (U+10000..U+10ffff) + * @return lead surrogate (U+d800..U+dbff) for supplementary + * @stable ICU 2.4 + */ +#define U16_LEAD(supplementary) (UChar)(((supplementary) >> 10) + 0xd7c0) + +/** + * Get the trail surrogate (0xdc00..0xdfff) for a + * supplementary code point (0x10000..0x10ffff). + * @param supplementary 32-bit code point (U+10000..U+10ffff) + * @return trail surrogate (U+dc00..U+dfff) for supplementary + * @stable ICU 2.4 + */ +#define U16_TRAIL(supplementary) (UChar)(((supplementary) & 0x3ff) | 0xdc00) + +// This must be called with the length pre-determined by the first byte. +// If presented with a length > 4, this returns false. The Unicode +// definition of UTF-8 goes up to 4-byte sequences. +static bool isLegalUTF8(const unsigned char* source, int length) +{ + unsigned char a; + const unsigned char* srcptr = source + length; + switch (length) { + default: + return false; + // Everything else falls through when "true"... + case 4: + if ((a = (*--srcptr)) < 0x80 || a > 0xBF) + return false; + case 3: + if ((a = (*--srcptr)) < 0x80 || a > 0xBF) + return false; + case 2: + if ((a = (*--srcptr)) > 0xBF) + return false; + + // no fall-through in this inner switch + switch (*source) { + case 0xE0: + if (a < 0xA0) + return false; + break; + case 0xED: + if (a > 0x9F) + return false; + break; + case 0xF0: + if (a < 0x90) + return false; + break; + case 0xF4: + if (a > 0x8F) + return false; + break; + default: + if (a < 0x80) + return false; + } + + case 1: + if (*source >= 0x80 && *source < 0xC2) + return false; + } + if (*source > 0xF4) + return false; + return true; +} + +// Magic values subtracted from a buffer value during UTF8 conversion. +// This table contains as many values as there might be trailing bytes +// in a UTF-8 sequence. +static const UChar32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, 0x03C82080UL, static_cast<UChar32>(0xFA082080UL), static_cast<UChar32>(0x82082080UL) }; + +static inline UChar32 readUTF8Sequence(const char*& sequence, unsigned length) +{ + UChar32 character = 0; + + // The cases all fall through. + switch (length) { + case 6: + character += static_cast<unsigned char>(*sequence++); + character <<= 6; + case 5: + character += static_cast<unsigned char>(*sequence++); + character <<= 6; + case 4: + character += static_cast<unsigned char>(*sequence++); + character <<= 6; + case 3: + character += static_cast<unsigned char>(*sequence++); + character <<= 6; + case 2: + character += static_cast<unsigned char>(*sequence++); + character <<= 6; + case 1: + character += static_cast<unsigned char>(*sequence++); + } + + return character - offsetsFromUTF8[length - 1]; +} + +ConversionResult convertUTF8ToUTF16( + const char** sourceStart, const char* sourceEnd, + UChar** targetStart, UChar* targetEnd, bool* sourceAllASCII, bool strict) +{ + ConversionResult result = conversionOK; + const char* source = *sourceStart; + UChar* target = *targetStart; + UChar orAllData = 0; + while (source < sourceEnd) { + int utf8SequenceLength = inlineUTF8SequenceLength(*source); + if (sourceEnd - source < utf8SequenceLength) { + result = sourceExhausted; + break; + } + // Do this check whether lenient or strict + if (!isLegalUTF8(reinterpret_cast<const unsigned char*>(source), utf8SequenceLength)) { + result = sourceIllegal; + break; + } + + UChar32 character = readUTF8Sequence(source, utf8SequenceLength); + + if (target >= targetEnd) { + source -= utf8SequenceLength; // Back up source pointer! + result = targetExhausted; + break; + } + + if (U_IS_BMP(character)) { + // UTF-16 surrogate values are illegal in UTF-32 + if (U_IS_SURROGATE(character)) { + if (strict) { + source -= utf8SequenceLength; // return to the illegal value itself + result = sourceIllegal; + break; + } + *target++ = replacementCharacter; + orAllData |= replacementCharacter; + } else { + *target++ = static_cast<UChar>(character); // normal case + orAllData |= character; + } + } else if (U_IS_SUPPLEMENTARY(character)) { + // target is a character in range 0xFFFF - 0x10FFFF + if (target + 1 >= targetEnd) { + source -= utf8SequenceLength; // Back up source pointer! + result = targetExhausted; + break; + } + *target++ = U16_LEAD(character); + *target++ = U16_TRAIL(character); + orAllData = 0xffff; + } else { + if (strict) { + source -= utf8SequenceLength; // return to the start + result = sourceIllegal; + break; // Bail out; shouldn't continue + } else { + *target++ = replacementCharacter; + orAllData |= replacementCharacter; + } + } + } + *sourceStart = source; + *targetStart = target; + + if (sourceAllASCII) + *sourceAllASCII = !(orAllData & ~0x7f); + + return result; +} + +// Helper to write a three-byte UTF-8 code point to the buffer, caller must check room is available. +static inline void putUTF8Triple(char*& buffer, UChar ch) +{ + DCHECK_GE(ch, 0x0800); + *buffer++ = static_cast<char>(((ch >> 12) & 0x0F) | 0xE0); + *buffer++ = static_cast<char>(((ch >> 6) & 0x3F) | 0x80); + *buffer++ = static_cast<char>((ch & 0x3F) | 0x80); +} + +String16 String16::fromUTF8(const char* stringStart, size_t length) +{ + if (!stringStart || !length) + return String16(); + + std::vector<UChar> buffer(length); + UChar* bufferStart = buffer.data(); + + UChar* bufferCurrent = bufferStart; + const char* stringCurrent = stringStart; + if (convertUTF8ToUTF16(&stringCurrent, stringStart + length, &bufferCurrent, bufferCurrent + buffer.size(), 0, true) != conversionOK) + return String16(); + + unsigned utf16Length = bufferCurrent - bufferStart; + return String16(bufferStart, utf16Length); +} + +std::string String16::utf8() const +{ + unsigned length = this->length(); + + if (!length) + return std::string(""); + + // Allocate a buffer big enough to hold all the characters + // (an individual UTF-16 UChar can only expand to 3 UTF-8 bytes). + // Optimization ideas, if we find this function is hot: + // * We could speculatively create a CStringBuffer to contain 'length' + // characters, and resize if necessary (i.e. if the buffer contains + // non-ascii characters). (Alternatively, scan the buffer first for + // ascii characters, so we know this will be sufficient). + // * We could allocate a CStringBuffer with an appropriate size to + // have a good chance of being able to write the string into the + // buffer without reallocing (say, 1.5 x length). + if (length > std::numeric_limits<unsigned>::max() / 3) + return std::string(); + std::vector<char> bufferVector(length * 3); + char* buffer = bufferVector.data(); + const UChar* characters = m_impl.data(); + + ConversionResult result = convertUTF16ToUTF8(&characters, characters + length, &buffer, buffer + bufferVector.size(), false); + DCHECK(result != targetExhausted); // (length * 3) should be sufficient for any conversion + + // Only produced from strict conversion. + DCHECK(result != sourceIllegal); + + // Check for an unconverted high surrogate. + if (result == sourceExhausted) { + // This should be one unpaired high surrogate. Treat it the same + // was as an unpaired high surrogate would have been handled in + // the middle of a string with non-strict conversion - which is + // to say, simply encode it to UTF-8. + DCHECK((characters + 1) == (m_impl.data() + length)); + DCHECK((*characters >= 0xD800) && (*characters <= 0xDBFF)); + // There should be room left, since one UChar hasn't been + // converted. + DCHECK((buffer + 3) <= (buffer + bufferVector.size())); + putUTF8Triple(buffer, *characters); + } + + return std::string(bufferVector.data(), buffer - bufferVector.data()); +} + +} // namespace protocol +} // namespace blink
diff --git a/third_party/WebKit/Source/platform/v8_inspector/String16STL.h b/third_party/WebKit/Source/platform/v8_inspector/String16STL.h new file mode 100644 index 0000000..51da506d --- /dev/null +++ b/third_party/WebKit/Source/platform/v8_inspector/String16STL.h
@@ -0,0 +1,102 @@ +// Copyright 2016 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 String16STL_h +#define String16STL_h + +#include <cctype> +#include <cstdlib> +#include <cstring> +#include <stdint.h> +#include <string> +#include <vector> + +using UChar = uint16_t; + +namespace blink { +namespace protocol { + +class String16 : public String16Base<String16, UChar> { +public: + static const size_t kNotFound = static_cast<size_t>(-1); + + String16() { } + String16(const String16& other) : m_impl(other.m_impl) { } + String16(const UChar* characters, size_t size) : m_impl(characters, size) { } + String16(const UChar* characters) : m_impl(characters) { } + String16(const char* characters) : String16(characters, std::strlen(characters)) { } + String16(const char* characters, size_t size) + { + m_impl.resize(size); + for (size_t i = 0; i < size; ++i) + m_impl[i] = characters[i]; + } + + String16 isolatedCopy() const { return String16(m_impl); } + const UChar* characters16() const { return m_impl.c_str(); } + size_t length() const { return m_impl.length(); } + bool isEmpty() const { return !m_impl.length(); } + UChar operator[](unsigned index) const { return m_impl[index]; } + String16 substring(unsigned pos, unsigned len = UINT_MAX) const { return String16(m_impl.substr(pos, len)); } + size_t find(const String16& str, unsigned start = 0) const { return m_impl.find(str.m_impl, start); } + size_t reverseFind(const String16& str, unsigned start = UINT_MAX) const { return m_impl.rfind(str.m_impl, start); } + + // Convenience methods. + std::string utf8() const; + static String16 fromUTF8(const char* stringStart, size_t length); + + const std::basic_string<UChar>& impl() const { return m_impl; } + explicit String16(const std::basic_string<UChar>& impl) : m_impl(impl) { } + + std::size_t hash() const + { + if (!has_hash) { + size_t hash = 0; + for (size_t i = 0; i < length(); ++i) + hash = 31 * hash + m_impl[i]; + hash_code = hash; + has_hash = true; + } + return hash_code; + } + +private: + std::basic_string<UChar> m_impl; + mutable bool has_hash = false; + mutable std::size_t hash_code = 0; +}; + +inline bool operator==(const String16& a, const String16& b) { return a.impl() == b.impl(); } +inline bool operator!=(const String16& a, const String16& b) { return a.impl() != b.impl(); } +inline bool operator==(const String16& a, const char* b) { return a.impl() == String16(b).impl(); } +inline String16 operator+(const String16& a, const char* b) { return String16(a.impl() + String16(b).impl()); } +inline String16 operator+(const char* a, const String16& b) { return String16(String16(a).impl() + b.impl()); } +inline String16 operator+(const String16& a, const String16& b) { return String16(a.impl() + b.impl()); } + +} // namespace protocol +} // namespace blink + +#if !defined(__APPLE__) || defined(_LIBCPP_VERSION) + +namespace std { +template<> struct hash<blink::protocol::String16> { + std::size_t operator()(const blink::protocol::String16& string) const + { + return string.hash(); + } +}; + +} // namespace std + +#endif // !defined(__APPLE__) || defined(_LIBCPP_VERSION) + +class InspectorProtocolConvenienceStringType { +public: + // This class should not be ever instantiated, so we don't implement constructors. + InspectorProtocolConvenienceStringType(); + InspectorProtocolConvenienceStringType(const blink::protocol::String16& other); + operator blink::protocol::String16() const { return blink::protocol::String16(); }; +}; + +#endif // !defined(String16STL_h)
diff --git a/third_party/WebKit/Source/platform/v8_inspector/String16WTF.h b/third_party/WebKit/Source/platform/v8_inspector/String16WTF.h new file mode 100644 index 0000000..b65383a --- /dev/null +++ b/third_party/WebKit/Source/platform/v8_inspector/String16WTF.h
@@ -0,0 +1,111 @@ +// Copyright 2016 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 String16WTF_h +#define String16WTF_h + +#include "platform/Decimal.h" +#include "public/platform/WebString.h" +#include "wtf/text/StringBuilder.h" +#include "wtf/text/StringConcatenate.h" +#include "wtf/text/StringHash.h" +#include "wtf/text/StringToNumber.h" +#include "wtf/text/StringView.h" +#include "wtf/text/WTFString.h" + +namespace blink { +namespace protocol { + +class PLATFORM_EXPORT String16 : public String16Base<String16, UChar> { +public: + static const size_t kNotFound = WTF::kNotFound; + + String16() { } + String16(const String16& other) : m_impl(other.m_impl) { } + String16(const UChar* characters, unsigned length) : m_impl(characters, length) { } + String16(const char* characters) : String16(characters, strlen(characters)) { } + String16(const char* characters, size_t length) + { + UChar* data; + m_impl = WTF::String::createUninitialized(length, data); + for (size_t i = 0; i < length; ++i) + data[i] = characters[i]; + } + + ~String16() { } + + String16 isolatedCopy() const { return String16(m_impl.isolatedCopy()); } + const UChar* characters16() const { return m_impl.isEmpty() ? nullptr : m_impl.characters16(); } + size_t length() const { return m_impl.length(); } + bool isEmpty() const { return m_impl.isEmpty(); } + UChar operator[](unsigned index) const { return m_impl[index]; } + String16 substring(unsigned pos, unsigned len = UINT_MAX) const { return m_impl.substring(pos, len); } + size_t find(const String16& str, unsigned start = 0) const { return m_impl.find(str.impl(), start); } + size_t reverseFind(const String16& str, unsigned start = UINT_MAX) const { return m_impl.reverseFind(str.impl(), start); } + + // WTF convenience constructors and helper methods. + String16(const WebString& other) : String16(String(other)) { } + template<typename StringType1, typename StringType2> + String16(const WTF::StringAppend<StringType1, StringType2>& impl) : String16(String(impl)) { } + String16(const WTF::AtomicString& impl) : String16(String(impl)) { } + String16(const WTF::String& impl) : m_impl(impl) { m_impl.ensure16Bit(); } + String16(WTF::HashTableDeletedValueType) : m_impl(WTF::HashTableDeletedValue) { } + bool isHashTableDeletedValue() const { return m_impl.isHashTableDeletedValue(); } + operator WTF::String() const { return m_impl; } + operator WTF::StringView() const { return StringView(m_impl); } + operator WebString() { return m_impl; } + const WTF::String& impl() const { return m_impl; } + +private: + WTF::String m_impl; +}; + +inline bool operator==(const String16& a, const String16& b) { return a.impl() == b.impl(); } +inline bool operator!=(const String16& a, const String16& b) { return a.impl() != b.impl(); } +inline bool operator==(const String16& a, const char* b) { return a.impl() == b; } +inline String16 operator+(const String16& a, const char* b) { return String16(a.impl() + b); } +inline String16 operator+(const char* a, const String16& b) { return String16(a + b.impl()); } +inline String16 operator+(const String16& a, const String16& b) { return String16(a.impl() + b.impl()); } + +} // namespace protocol +} // namespace blink + +namespace std { +template<> struct hash<blink::protocol::String16> { + std::size_t operator()(const blink::protocol::String16& string) const + { + return StringHash::hash(string.impl()); + } +}; +} // namespace std + +using InspectorProtocolConvenienceStringType = WTF::String; + +// WTF helpers below this line. + +namespace WTF { + +struct String16Hash { + static unsigned hash(const blink::protocol::String16& key) { return StringHash::hash(key.impl()); } + static bool equal(const blink::protocol::String16& a, const blink::protocol::String16& b) + { + return StringHash::equal(a.impl(), b.impl()); + } + static const bool safeToCompareToEmptyOrDeleted = false; +}; + +template<typename T> struct DefaultHash; +template<> struct DefaultHash<blink::protocol::String16> { + typedef String16Hash Hash; +}; + +template<> +struct HashTraits<blink::protocol::String16> : SimpleClassHashTraits<blink::protocol::String16> { + static const bool hasIsEmptyValueFunction = true; + static bool isEmptyValue(const blink::protocol::String16& a) { return a.impl().isNull(); } +}; + +} // namespace WTF + +#endif // !defined(String16WTF_h)
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8Console.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8Console.cpp index 1bd738a8..eb078f98 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8Console.cpp +++ b/third_party/WebKit/Source/platform/v8_inspector/V8Console.cpp
@@ -4,8 +4,6 @@ #include "platform/v8_inspector/V8Console.h" -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" #include "platform/v8_inspector/InjectedScript.h" #include "platform/v8_inspector/InspectedContext.h" #include "platform/v8_inspector/V8Compat.h" @@ -439,7 +437,7 @@ if (!helper.privateMap("V8Console#timeMap").ToLocal(&timeMap)) return; double elapsed = client->currentTimeMS() - helper.getDoubleFromMap(timeMap, protocolTitle, 0.0); - String16 message = protocolTitle + ": " + String16::fromDoubleFixedPrecision(elapsed, 3) + "ms"; + String16 message = protocolTitle + ": " + String16::fromDoublePrecision3(elapsed) + "ms"; helper.reportCallWithArgument(ConsoleAPIType::kTimeEnd, message); } }
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8Console.h b/third_party/WebKit/Source/platform/v8_inspector/V8Console.h index b539f4c0..0c5466c6 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8Console.h +++ b/third_party/WebKit/Source/platform/v8_inspector/V8Console.h
@@ -5,7 +5,7 @@ #ifndef V8Console_h #define V8Console_h -#include "platform/inspector_protocol/Allocator.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include <v8.h> namespace blink {
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8ConsoleAgentImpl.h b/third_party/WebKit/Source/platform/v8_inspector/V8ConsoleAgentImpl.h index bc897ac..34ca150 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8ConsoleAgentImpl.h +++ b/third_party/WebKit/Source/platform/v8_inspector/V8ConsoleAgentImpl.h
@@ -5,8 +5,7 @@ #ifndef V8ConsoleAgentImpl_h #define V8ConsoleAgentImpl_h -#include "platform/inspector_protocol/Allocator.h" -#include "platform/inspector_protocol/String16.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "platform/v8_inspector/protocol/Console.h" namespace blink {
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8ConsoleMessage.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8ConsoleMessage.cpp index 84bcc3d..d6cfe13 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8ConsoleMessage.cpp +++ b/third_party/WebKit/Source/platform/v8_inspector/V8ConsoleMessage.cpp
@@ -84,7 +84,7 @@ if (value->IsSymbolObject()) return append(v8::Local<v8::SymbolObject>::Cast(value)->ValueOf()); if (value->IsNumberObject()) { - m_builder.appendNumber(v8::Local<v8::NumberObject>::Cast(value)->ValueOf()); + m_builder.append(String16::fromDoublePrecision6(v8::Local<v8::NumberObject>::Cast(value)->ValueOf())); return true; } if (value->IsBooleanObject()) {
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8ConsoleMessage.h b/third_party/WebKit/Source/platform/v8_inspector/V8ConsoleMessage.h index 9c26f5d9..4ad5ed8 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8ConsoleMessage.h +++ b/third_party/WebKit/Source/platform/v8_inspector/V8ConsoleMessage.h
@@ -5,8 +5,7 @@ #ifndef V8ConsoleMessage_h #define V8ConsoleMessage_h -#include "platform/inspector_protocol/Collections.h" -#include "platform/inspector_protocol/String16.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "platform/v8_inspector/protocol/Console.h" #include "platform/v8_inspector/protocol/Runtime.h" #include <deque>
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8Debugger.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8Debugger.cpp index f5898b4a..3502ecf 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8Debugger.cpp +++ b/third_party/WebKit/Source/platform/v8_inspector/V8Debugger.cpp
@@ -95,12 +95,12 @@ if (dataString.isEmpty()) return 0; size_t commaPos = dataString.find(","); - if (commaPos == kNotFound) + if (commaPos == String16::kNotFound) return 0; size_t commaPos2 = dataString.find(",", commaPos + 1); - if (commaPos2 == kNotFound) + if (commaPos2 == String16::kNotFound) return 0; - return dataString.substring(commaPos + 1, commaPos2 - commaPos - 1).toInt(); + return dataString.substring(commaPos + 1, commaPos2 - commaPos - 1).toInteger(); } // static @@ -113,9 +113,9 @@ if (dataString.isEmpty()) return 0; size_t commaPos = dataString.find(","); - if (commaPos == kNotFound) + if (commaPos == String16::kNotFound) return 0; - return dataString.substring(0, commaPos).toInt(); + return dataString.substring(0, commaPos).toInteger(); } void V8Debugger::getCompiledScripts(int contextGroupId, std::vector<std::unique_ptr<V8DebuggerScript>>& result) @@ -508,6 +508,8 @@ v8::Context::Scope contextScope(debuggerContext()); v8::Local<v8::Value> argv[] = { eventDetails.GetEventData() }; v8::Local<v8::Value> value = callDebuggerMethod("getAfterCompileScript", 1, argv).ToLocalChecked(); + if (value->IsNull()) + return; DCHECK(value->IsObject()); v8::Local<v8::Object> scriptObject = v8::Local<v8::Object>::Cast(value); agent->didParseSource(wrapUnique(new V8DebuggerScript(m_isolate, scriptObject, inLiveEditScope)), event == v8::AfterCompile);
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8Debugger.h b/third_party/WebKit/Source/platform/v8_inspector/V8Debugger.h index b3bf651..ecdaf079 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8Debugger.h +++ b/third_party/WebKit/Source/platform/v8_inspector/V8Debugger.h
@@ -5,9 +5,7 @@ #ifndef V8Debugger_h #define V8Debugger_h -#include "platform/inspector_protocol/Allocator.h" -#include "platform/inspector_protocol/Maybe.h" -#include "platform/inspector_protocol/Platform.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "platform/v8_inspector/JavaScriptCallFrame.h" #include "platform/v8_inspector/V8DebuggerScript.h" #include "platform/v8_inspector/protocol/Runtime.h"
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp index c97eaeb17..a3742e54 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp +++ b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.cpp
@@ -4,9 +4,6 @@ #include "platform/v8_inspector/V8DebuggerAgentImpl.h" -#include "platform/inspector_protocol/Parser.h" -#include "platform/inspector_protocol/String16.h" -#include "platform/inspector_protocol/Values.h" #include "platform/v8_inspector/InjectedScript.h" #include "platform/v8_inspector/InspectedContext.h" #include "platform/v8_inspector/JavaScriptCallFrame.h" @@ -397,18 +394,6 @@ resume(errorString); } -void V8DebuggerAgentImpl::getBacktrace(ErrorString* errorString, std::unique_ptr<Array<CallFrame>>* callFrames, Maybe<StackTrace>* asyncStackTrace) -{ - if (!assertPaused(errorString)) - return; - JavaScriptCallFrames frames = m_debugger->currentCallFrames(); - m_pausedCallFrames.swap(frames); - *callFrames = currentCallFrames(errorString); - if (!*callFrames) - return; - *asyncStackTrace = currentAsyncStackTrace(); -} - bool V8DebuggerAgentImpl::isCurrentCallStackEmptyOrBlackboxed() { DCHECK(enabled()); @@ -730,7 +715,6 @@ const Maybe<bool>& returnByValue, const Maybe<bool>& generatePreview, std::unique_ptr<RemoteObject>* result, - Maybe<bool>* wasThrown, Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) { if (!assertPaused(errorString)) @@ -760,7 +744,6 @@ returnByValue.fromMaybe(false), generatePreview.fromMaybe(false), result, - wasThrown, exceptionDetails); } @@ -994,38 +977,27 @@ { v8::HandleScope handles(m_isolate); String16 scriptSource = toProtocolString(script->source(m_isolate)); - bool isDeprecatedSourceURL = false; if (!success) - script->setSourceURL(findSourceURL(scriptSource, false, &isDeprecatedSourceURL)); - else if (script->hasSourceURL()) - findSourceURL(scriptSource, false, &isDeprecatedSourceURL); - - bool isDeprecatedSourceMappingURL = false; + script->setSourceURL(findSourceURL(scriptSource, false)); if (!success) - script->setSourceMappingURL(findSourceMapURL(scriptSource, false, &isDeprecatedSourceMappingURL)); - else if (!script->sourceMappingURL().isEmpty()) - findSourceMapURL(scriptSource, false, &isDeprecatedSourceMappingURL); + script->setSourceMappingURL(findSourceMapURL(scriptSource, false)); std::unique_ptr<protocol::DictionaryValue> executionContextAuxData; if (!script->executionContextAuxData().isEmpty()) executionContextAuxData = protocol::DictionaryValue::cast(parseJSON(script->executionContextAuxData())); - bool isInternalScript = script->isInternalScript(); bool isLiveEdit = script->isLiveEdit(); bool hasSourceURL = script->hasSourceURL(); String16 scriptId = script->scriptId(); String16 scriptURL = script->sourceURL(); - bool deprecatedCommentWasUsed = isDeprecatedSourceURL || isDeprecatedSourceMappingURL; const Maybe<String16>& sourceMapURLParam = script->sourceMappingURL(); const Maybe<protocol::DictionaryValue>& executionContextAuxDataParam(std::move(executionContextAuxData)); - const bool* isInternalScriptParam = isInternalScript ? &isInternalScript : nullptr; const bool* isLiveEditParam = isLiveEdit ? &isLiveEdit : nullptr; const bool* hasSourceURLParam = hasSourceURL ? &hasSourceURL : nullptr; - const bool* deprecatedCommentWasUsedParam = deprecatedCommentWasUsed ? &deprecatedCommentWasUsed : nullptr; if (success) - m_frontend.scriptParsed(scriptId, scriptURL, script->startLine(), script->startColumn(), script->endLine(), script->endColumn(), script->executionContextId(), script->hash(), executionContextAuxDataParam, isInternalScriptParam, isLiveEditParam, sourceMapURLParam, hasSourceURLParam, deprecatedCommentWasUsedParam); + m_frontend.scriptParsed(scriptId, scriptURL, script->startLine(), script->startColumn(), script->endLine(), script->endColumn(), script->executionContextId(), script->hash(), executionContextAuxDataParam, isLiveEditParam, sourceMapURLParam, hasSourceURLParam); else - m_frontend.scriptFailedToParse(scriptId, scriptURL, script->startLine(), script->startColumn(), script->endLine(), script->endColumn(), script->executionContextId(), script->hash(), executionContextAuxDataParam, isInternalScriptParam, sourceMapURLParam, hasSourceURLParam, deprecatedCommentWasUsedParam); + m_frontend.scriptFailedToParse(scriptId, scriptURL, script->startLine(), script->startColumn(), script->endLine(), script->endColumn(), script->executionContextId(), script->hash(), executionContextAuxDataParam, sourceMapURLParam, hasSourceURLParam); m_scripts[scriptId] = std::move(script); @@ -1060,13 +1032,6 @@ JavaScriptCallFrames callFrames = m_debugger->currentCallFrames(1); JavaScriptCallFrame* topCallFrame = !callFrames.empty() ? callFrames.begin()->get() : nullptr; - // Skip pause in internal scripts (e.g. InjectedScriptSource.js). - if (topCallFrame) { - ScriptsMap::iterator it = m_scripts.find(String16::fromInteger(topCallFrame->sourceID())); - if (it != m_scripts.end() && it->second->isInternalScript()) - return RequestStepFrame; - } - V8DebuggerAgentImpl::SkipPauseRequest result; if (m_skipAllPauses) result = RequestContinue;
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.h b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.h index 317911ad..9a06c31 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.h +++ b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerAgentImpl.h
@@ -5,8 +5,7 @@ #ifndef V8DebuggerAgentImpl_h #define V8DebuggerAgentImpl_h -#include "platform/inspector_protocol/Collections.h" -#include "platform/inspector_protocol/String16.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "platform/v8_inspector/JavaScriptCallFrame.h" #include "platform/v8_inspector/protocol/Debugger.h" @@ -72,16 +71,12 @@ void removeBreakpoint(ErrorString*, const String16& breakpointId) override; void continueToLocation(ErrorString*, std::unique_ptr<protocol::Debugger::Location>) override; - void getBacktrace(ErrorString*, - std::unique_ptr<protocol::Array<protocol::Debugger::CallFrame>>*, - Maybe<protocol::Runtime::StackTrace>*) override; void searchInContent(ErrorString*, const String16& scriptId, const String16& query, const Maybe<bool>& optionalCaseSensitive, const Maybe<bool>& optionalIsRegex, std::unique_ptr<protocol::Array<protocol::Debugger::SearchMatch>>*) override; - void canSetScriptSource(ErrorString*, bool* result) override { *result = true; } void setScriptSource(ErrorString*, const String16& inScriptId, const String16& inScriptSource, @@ -110,7 +105,6 @@ const Maybe<bool>& returnByValue, const Maybe<bool>& generatePreview, std::unique_ptr<protocol::Runtime::RemoteObject>* result, - Maybe<bool>* wasThrown, Maybe<protocol::Runtime::ExceptionDetails>*) override; void setVariableValue(ErrorString*, int scopeNumber,
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerScript.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerScript.cpp index edb2fcdc..eba18cca 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerScript.cpp +++ b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerScript.cpp
@@ -4,18 +4,17 @@ #include "platform/v8_inspector/V8DebuggerScript.h" -#include "platform/inspector_protocol/Collections.h" -#include "platform/inspector_protocol/Platform.h" #include "platform/v8_inspector/V8StringUtil.h" namespace blink { -static const LChar hexDigits[17] = "0123456789ABCDEF"; +static const char hexDigits[17] = "0123456789ABCDEF"; static void appendUnsignedAsHex(unsigned number, String16Builder* destination) { for (size_t i = 0; i < 8; ++i) { - destination->append(hexDigits[number & 0xF]); + UChar c = hexDigits[number & 0xF]; + destination->append(c); number >>= 4; } } @@ -36,17 +35,18 @@ size_t current = 0; const uint32_t* data = nullptr; + size_t sizeInBytes = sizeof(UChar) * str.length(); data = reinterpret_cast<const uint32_t*>(str.characters16()); - for (size_t i = 0; i < str.sizeInBytes() / 4; i += 4) { + for (size_t i = 0; i < sizeInBytes / 4; i += 4) { uint32_t v = data[i]; uint64_t xi = v * randomOdd[current] & 0x7FFFFFFF; hashes[current] = (hashes[current] + zi[current] * xi) % prime[current]; zi[current] = (zi[current] * random[current]) % prime[current]; current = current == hashesSize - 1 ? 0 : current + 1; } - if (str.sizeInBytes() % 4) { + if (sizeInBytes % 4) { uint32_t v = 0; - for (size_t i = str.sizeInBytes() - str.sizeInBytes() % 4; i < str.sizeInBytes(); ++i) { + for (size_t i = sizeInBytes - sizeInBytes % 4; i < sizeInBytes; ++i) { v <<= 8; v |= reinterpret_cast<const uint8_t*>(data)[i]; } @@ -79,7 +79,6 @@ m_endLine = object->Get(toV8StringInternalized(isolate, "endLine"))->ToInteger(isolate)->Value(); m_endColumn = object->Get(toV8StringInternalized(isolate, "endColumn"))->ToInteger(isolate)->Value(); m_executionContextAuxData = toProtocolStringWithTypeCheck(object->Get(toV8StringInternalized(isolate, "executionContextAuxData"))); - m_isInternalScript = object->Get(toV8StringInternalized(isolate, "isInternalScript"))->ToBoolean(isolate)->Value(); m_executionContextId = object->Get(toV8StringInternalized(isolate, "executionContextId"))->ToInteger(isolate)->Value(); m_isLiveEdit = isLiveEdit;
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerScript.h b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerScript.h index d3e9d8d..b53a65d 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerScript.h +++ b/third_party/WebKit/Source/platform/v8_inspector/V8DebuggerScript.h
@@ -30,8 +30,7 @@ #ifndef V8DebuggerScript_h #define V8DebuggerScript_h -#include "platform/inspector_protocol/Allocator.h" -#include "platform/inspector_protocol/String16.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include <v8.h> namespace blink { @@ -55,7 +54,6 @@ int endColumn() const { return m_endColumn; } int executionContextId() const { return m_executionContextId; } const String16& executionContextAuxData() const { return m_executionContextAuxData; } - bool isInternalScript() const { return m_isInternalScript; } bool isLiveEdit() const { return m_isLiveEdit; } void setSourceURL(const String16&); @@ -75,7 +73,6 @@ int m_endColumn; int m_executionContextId; String16 m_executionContextAuxData; - bool m_isInternalScript; bool m_isLiveEdit; };
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8FunctionCall.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8FunctionCall.cpp index bed316ef..f965955 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8FunctionCall.cpp +++ b/third_party/WebKit/Source/platform/v8_inspector/V8FunctionCall.cpp
@@ -30,7 +30,6 @@ #include "platform/v8_inspector/V8FunctionCall.h" -#include "platform/inspector_protocol/Platform.h" #include "platform/v8_inspector/V8Compat.h" #include "platform/v8_inspector/V8Debugger.h" #include "platform/v8_inspector/V8InspectorImpl.h"
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8FunctionCall.h b/third_party/WebKit/Source/platform/v8_inspector/V8FunctionCall.h index acb5b5c3..1d81f00 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8FunctionCall.h +++ b/third_party/WebKit/Source/platform/v8_inspector/V8FunctionCall.h
@@ -31,7 +31,7 @@ #ifndef V8FunctionCall_h #define V8FunctionCall_h -#include "platform/inspector_protocol/String16.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include <v8.h>
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp index d256fe1..64c03ea 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp +++ b/third_party/WebKit/Source/platform/v8_inspector/V8HeapProfilerAgentImpl.cpp
@@ -237,7 +237,7 @@ void V8HeapProfilerAgentImpl::getObjectByHeapObjectId(ErrorString* error, const String16& heapSnapshotObjectId, const protocol::Maybe<String16>& objectGroup, std::unique_ptr<protocol::Runtime::RemoteObject>* result) { bool ok; - int id = heapSnapshotObjectId.toInt(&ok); + int id = heapSnapshotObjectId.toInteger(&ok); if (!ok) { *error = "Invalid heap snapshot object id"; return; @@ -263,7 +263,7 @@ void V8HeapProfilerAgentImpl::addInspectedHeapObject(ErrorString* errorString, const String16& inspectedHeapObjectId) { bool ok; - int id = inspectedHeapObjectId.toInt(&ok); + int id = inspectedHeapObjectId.toInteger(&ok); if (!ok) { *errorString = "Invalid heap snapshot object id"; return;
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8HeapProfilerAgentImpl.h b/third_party/WebKit/Source/platform/v8_inspector/V8HeapProfilerAgentImpl.h index bc201af..7b7bcd7 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8HeapProfilerAgentImpl.h +++ b/third_party/WebKit/Source/platform/v8_inspector/V8HeapProfilerAgentImpl.h
@@ -5,8 +5,7 @@ #ifndef V8HeapProfilerAgentImpl_h #define V8HeapProfilerAgentImpl_h -#include "platform/inspector_protocol/Allocator.h" -#include "platform/inspector_protocol/String16.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "platform/v8_inspector/protocol/HeapProfiler.h" #include <v8.h>
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8InjectedScriptHost.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8InjectedScriptHost.cpp index 6f9a2a05c..f971cc1 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8InjectedScriptHost.cpp +++ b/third_party/WebKit/Source/platform/v8_inspector/V8InjectedScriptHost.cpp
@@ -4,7 +4,6 @@ #include "platform/v8_inspector/V8InjectedScriptHost.h" -#include "platform/inspector_protocol/String16.h" #include "platform/v8_inspector/InjectedScriptNative.h" #include "platform/v8_inspector/V8Compat.h" #include "platform/v8_inspector/V8Debugger.h"
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8InjectedScriptHost.h b/third_party/WebKit/Source/platform/v8_inspector/V8InjectedScriptHost.h index 496b5a77..2ea6de57 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8InjectedScriptHost.h +++ b/third_party/WebKit/Source/platform/v8_inspector/V8InjectedScriptHost.h
@@ -5,6 +5,7 @@ #ifndef V8InjectedScriptHost_h #define V8InjectedScriptHost_h +#include "platform/inspector_protocol/InspectorProtocol.h" #include <v8.h> namespace blink {
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8InspectorImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8InspectorImpl.cpp index caac2020..f467fcc8f 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8InspectorImpl.cpp +++ b/third_party/WebKit/Source/platform/v8_inspector/V8InspectorImpl.cpp
@@ -105,7 +105,7 @@ v8::MaybeLocal<v8::Value> V8InspectorImpl::compileAndRunInternalScript(v8::Local<v8::Context> context, v8::Local<v8::String> source) { - v8::Local<v8::Script> script = compileScript(context, source, String(), true); + v8::Local<v8::Script> script = compileScript(context, source, String16(), true); if (script.IsEmpty()) return v8::MaybeLocal<v8::Value>(); v8::MicrotasksScope microtasksScope(m_isolate, v8::MicrotasksScope::kDoNotRunMicrotasks);
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8InspectorImpl.h b/third_party/WebKit/Source/platform/v8_inspector/V8InspectorImpl.h index e4dad93..af945f9 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8InspectorImpl.h +++ b/third_party/WebKit/Source/platform/v8_inspector/V8InspectorImpl.h
@@ -31,9 +31,7 @@ #ifndef V8InspectorImpl_h #define V8InspectorImpl_h -#include "platform/inspector_protocol/Allocator.h" -#include "platform/inspector_protocol/Collections.h" -#include "platform/inspector_protocol/Platform.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "platform/v8_inspector/public/V8Inspector.h" #include <v8-debug.h>
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8InspectorSessionImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8InspectorSessionImpl.cpp index 814b7f9..3585d966 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8InspectorSessionImpl.cpp +++ b/third_party/WebKit/Source/platform/v8_inspector/V8InspectorSessionImpl.cpp
@@ -4,7 +4,6 @@ #include "platform/v8_inspector/V8InspectorSessionImpl.h" -#include "platform/inspector_protocol/Parser.h" #include "platform/v8_inspector/InjectedScript.h" #include "platform/v8_inspector/InspectedContext.h" #include "platform/v8_inspector/RemoteObjectId.h" @@ -24,11 +23,11 @@ // static bool V8InspectorSession::canDispatchMethod(const String16& method) { - return method.startWith(protocol::Runtime::Metainfo::commandPrefix) - || method.startWith(protocol::Debugger::Metainfo::commandPrefix) - || method.startWith(protocol::Profiler::Metainfo::commandPrefix) - || method.startWith(protocol::HeapProfiler::Metainfo::commandPrefix) - || method.startWith(protocol::Console::Metainfo::commandPrefix); + return method.startsWith(protocol::Runtime::Metainfo::commandPrefix) + || method.startsWith(protocol::Debugger::Metainfo::commandPrefix) + || method.startsWith(protocol::Profiler::Metainfo::commandPrefix) + || method.startsWith(protocol::HeapProfiler::Metainfo::commandPrefix) + || method.startsWith(protocol::Console::Metainfo::commandPrefix); } std::unique_ptr<V8InspectorSessionImpl> V8InspectorSessionImpl::create(V8InspectorImpl* inspector, int contextGroupId, protocol::FrontendChannel* channel, const String16* state)
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8InspectorSessionImpl.h b/third_party/WebKit/Source/platform/v8_inspector/V8InspectorSessionImpl.h index d5ee2ef..a42e6bd 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8InspectorSessionImpl.h +++ b/third_party/WebKit/Source/platform/v8_inspector/V8InspectorSessionImpl.h
@@ -5,10 +5,7 @@ #ifndef V8InspectorSessionImpl_h #define V8InspectorSessionImpl_h -#include "platform/inspector_protocol/Allocator.h" -#include "platform/inspector_protocol/DispatcherBase.h" -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "platform/v8_inspector/protocol/Runtime.h" #include "platform/v8_inspector/public/V8InspectorSession.h"
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8InternalValueType.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8InternalValueType.cpp index 52e7677..fcb56e3 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8InternalValueType.cpp +++ b/third_party/WebKit/Source/platform/v8_inspector/V8InternalValueType.cpp
@@ -4,7 +4,6 @@ #include "platform/v8_inspector/V8InternalValueType.h" -#include "platform/inspector_protocol/Platform.h" #include "platform/v8_inspector/V8StringUtil.h" namespace blink {
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8InternalValueType.h b/third_party/WebKit/Source/platform/v8_inspector/V8InternalValueType.h index 4bb7172..72f99752 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8InternalValueType.h +++ b/third_party/WebKit/Source/platform/v8_inspector/V8InternalValueType.h
@@ -5,6 +5,7 @@ #ifndef V8InternalValueType_h #define V8InternalValueType_h +#include "platform/inspector_protocol/InspectorProtocol.h" #include <v8.h> namespace blink {
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8ProfilerAgentImpl.h b/third_party/WebKit/Source/platform/v8_inspector/V8ProfilerAgentImpl.h index 4bbe00be6..3110a3f 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8ProfilerAgentImpl.h +++ b/third_party/WebKit/Source/platform/v8_inspector/V8ProfilerAgentImpl.h
@@ -5,8 +5,7 @@ #ifndef V8ProfilerAgentImpl_h #define V8ProfilerAgentImpl_h -#include "platform/inspector_protocol/Allocator.h" -#include "platform/inspector_protocol/String16.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "platform/v8_inspector/protocol/Profiler.h" #include <vector>
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8Regex.h b/third_party/WebKit/Source/platform/v8_inspector/V8Regex.h index e4900e2..787b01d 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8Regex.h +++ b/third_party/WebKit/Source/platform/v8_inspector/V8Regex.h
@@ -5,8 +5,7 @@ #ifndef V8Regex_h #define V8Regex_h -#include "platform/inspector_protocol/Allocator.h" -#include "platform/inspector_protocol/String16.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include <v8.h> namespace blink {
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp index 79d8cc9c..b88015f 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp +++ b/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.cpp
@@ -30,8 +30,6 @@ #include "platform/v8_inspector/V8RuntimeAgentImpl.h" -#include "platform/inspector_protocol/Parser.h" -#include "platform/inspector_protocol/Values.h" #include "platform/v8_inspector/InjectedScript.h" #include "platform/v8_inspector/InspectedContext.h" #include "platform/v8_inspector/RemoteObjectId.h" @@ -99,7 +97,7 @@ ProtocolPromiseHandler<Callback>* handler = static_cast<ProtocolPromiseHandler<Callback>*>(info.Data().As<v8::External>()->Value()); DCHECK(handler); v8::Local<v8::Value> value = info.Length() > 0 ? info[0] : v8::Local<v8::Value>::Cast(v8::Undefined(info.GetIsolate())); - handler->m_callback->sendSuccess(handler->wrapObject(value), Maybe<bool>(), Maybe<protocol::Runtime::ExceptionDetails>()); + handler->m_callback->sendSuccess(handler->wrapObject(value), Maybe<protocol::Runtime::ExceptionDetails>()); } static void catchCallback(const v8::FunctionCallbackInfo<v8::Value>& info) @@ -119,7 +117,7 @@ .setStackTrace(stack->buildInspectorObjectImpl()) .build(); } - handler->m_callback->sendSuccess(handler->wrapObject(value), true, std::move(exceptionDetails)); + handler->m_callback->sendSuccess(handler->wrapObject(value), std::move(exceptionDetails)); } ProtocolPromiseHandler(V8InspectorImpl* inspector, int contextGroupId, int executionContextId, const String16& objectGroup, bool returnByValue, bool generatePreview, std::unique_ptr<Callback> callback) @@ -176,7 +174,6 @@ bool wrapEvaluateResultAsync(InjectedScript* injectedScript, v8::MaybeLocal<v8::Value> maybeResultValue, const v8::TryCatch& tryCatch, const String16& objectGroup, bool returnByValue, bool generatePreview, Callback* callback) { std::unique_ptr<RemoteObject> result; - Maybe<bool> wasThrown; Maybe<protocol::Runtime::ExceptionDetails> exceptionDetails; ErrorString errorString; @@ -187,10 +184,9 @@ returnByValue, generatePreview, &result, - &wasThrown, &exceptionDetails); if (errorString.isEmpty()) { - callback->sendSuccess(std::move(result), wasThrown, exceptionDetails); + callback->sendSuccess(std::move(result), exceptionDetails); return true; } callback->sendFailure(errorString);
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.h b/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.h index 8594ce8..574260f 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.h +++ b/third_party/WebKit/Source/platform/v8_inspector/V8RuntimeAgentImpl.h
@@ -31,8 +31,7 @@ #ifndef V8RuntimeAgentImpl_h #define V8RuntimeAgentImpl_h -#include "platform/inspector_protocol/Allocator.h" -#include "platform/inspector_protocol/String16.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "platform/v8_inspector/protocol/Runtime.h" #include <v8.h>
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8StackTraceImpl.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8StackTraceImpl.cpp index 0a8e6e1e..ba9f3d63 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8StackTraceImpl.cpp +++ b/third_party/WebKit/Source/platform/v8_inspector/V8StackTraceImpl.cpp
@@ -4,8 +4,6 @@ #include "platform/v8_inspector/V8StackTraceImpl.h" -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" #include "platform/v8_inspector/V8Debugger.h" #include "platform/v8_inspector/V8StringUtil.h" @@ -256,9 +254,9 @@ stackTrace.append(" ("); stackTrace.append(frame.sourceURL()); stackTrace.append(':'); - stackTrace.appendNumber(frame.lineNumber()); + stackTrace.append(String16::fromInteger(frame.lineNumber())); stackTrace.append(':'); - stackTrace.appendNumber(frame.columnNumber()); + stackTrace.append(String16::fromInteger(frame.columnNumber())); stackTrace.append(')'); } return stackTrace.toString();
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8StackTraceImpl.h b/third_party/WebKit/Source/platform/v8_inspector/V8StackTraceImpl.h index 9d9a4892..eb93709 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8StackTraceImpl.h +++ b/third_party/WebKit/Source/platform/v8_inspector/V8StackTraceImpl.h
@@ -5,8 +5,7 @@ #ifndef V8StackTraceImpl_h #define V8StackTraceImpl_h -#include "platform/inspector_protocol/Allocator.h" -#include "platform/inspector_protocol/Platform.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "platform/v8_inspector/protocol/Runtime.h" #include "platform/v8_inspector/public/V8StackTrace.h"
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8StringUtil.cpp b/third_party/WebKit/Source/platform/v8_inspector/V8StringUtil.cpp index 037d910..b0c9701 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8StringUtil.cpp +++ b/third_party/WebKit/Source/platform/v8_inspector/V8StringUtil.cpp
@@ -4,7 +4,6 @@ #include "platform/v8_inspector/V8StringUtil.h" -#include "platform/inspector_protocol/String16.h" #include "platform/v8_inspector/V8InspectorImpl.h" #include "platform/v8_inspector/V8InspectorSessionImpl.h" #include "platform/v8_inspector/V8Regex.h" @@ -13,12 +12,9 @@ namespace { -String16 findMagicComment(const String16& content, const String16& name, bool multiline, bool* deprecated) +String16 findMagicComment(const String16& content, const String16& name, bool multiline) { - DCHECK(name.find("=") == kNotFound); - if (deprecated) - *deprecated = false; - + DCHECK(name.find("=") == String16::kNotFound); unsigned length = content.length(); unsigned nameLength = name.length(); @@ -27,7 +23,7 @@ size_t closingCommentPos = 0; while (true) { pos = content.reverseFind(name, pos); - if (pos == kNotFound) + if (pos == String16::kNotFound) return String16(); // Check for a /\/[\/*][@#][ \t]/ regexp (length of 4) before found name. @@ -48,16 +44,13 @@ continue; if (multiline) { closingCommentPos = content.find("*/", equalSignPos + 1); - if (closingCommentPos == kNotFound) + if (closingCommentPos == String16::kNotFound) return String16(); } break; } - if (deprecated && content[pos + 2] == '@') - *deprecated = true; - DCHECK(equalSignPos); DCHECK(!multiline || closingCommentPos); size_t urlPos = equalSignPos + 1; @@ -66,13 +59,13 @@ : content.substring(urlPos); size_t newLine = match.find("\n"); - if (newLine != kNotFound) + if (newLine != String16::kNotFound) match = match.substring(0, newLine); match = match.stripWhiteSpace(); - String16 disallowedChars("\"' \t"); for (unsigned i = 0; i < match.length(); ++i) { - if (disallowedChars.find(match[i]) != kNotFound) + UChar c = match[i]; + if (c == '"' || c == '\'' || c == ' ' || c == '\t') return ""; } @@ -82,11 +75,14 @@ String16 createSearchRegexSource(const String16& text) { String16Builder result; - String16 specials("[](){}+-*.,?\\^$|"); for (unsigned i = 0; i < text.length(); i++) { - if (specials.find(text[i]) != kNotFound) + UChar c = text[i]; + if (c == '[' || c == ']' || c == '(' || c == ')' || c == '{' || c == '}' + || c == '+' || c == '-' || c == '*' || c == '.' || c == ',' || c == '?' + || c == '\\' || c == '^' || c == '$' || c == '|') { result.append('\\'); + } result.append(text[i]); } @@ -97,10 +93,11 @@ { std::unique_ptr<std::vector<unsigned>> result(new std::vector<unsigned>()); + const String16 lineEndString = "\n"; unsigned start = 0; while (start < text.length()) { - size_t lineEnd = text.find('\n', start); - if (lineEnd == kNotFound) + size_t lineEnd = text.find(lineEndString, start); + if (lineEnd == String16::kNotFound) break; result->push_back(static_cast<unsigned>(lineEnd)); @@ -123,7 +120,7 @@ for (unsigned lineNumber = 0; lineNumber < size; ++lineNumber) { unsigned lineEnd = endings->at(lineNumber); String16 line = text.substring(start, lineEnd - start); - if (line.endsWith('\r')) + if (line.length() && line[line.length() - 1] == '\r') line = line.substring(0, line.length() - 1); int matchLength; @@ -197,14 +194,14 @@ return result; } -String16 findSourceURL(const String16& content, bool multiline, bool* deprecated) +String16 findSourceURL(const String16& content, bool multiline) { - return findMagicComment(content, "sourceURL", multiline, deprecated); + return findMagicComment(content, "sourceURL", multiline); } -String16 findSourceMapURL(const String16& content, bool multiline, bool* deprecated) +String16 findSourceMapURL(const String16& content, bool multiline) { - return findMagicComment(content, "sourceMappingURL", multiline, deprecated); + return findMagicComment(content, "sourceMappingURL", multiline); } std::unique_ptr<protocol::Value> toProtocolValue(v8::Local<v8::Context> context, v8::Local<v8::Value> value, int maxDepth)
diff --git a/third_party/WebKit/Source/platform/v8_inspector/V8StringUtil.h b/third_party/WebKit/Source/platform/v8_inspector/V8StringUtil.h index 029ed56..d23c74f 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/V8StringUtil.h +++ b/third_party/WebKit/Source/platform/v8_inspector/V8StringUtil.h
@@ -5,8 +5,7 @@ #ifndef V8StringUtil_h #define V8StringUtil_h -#include "platform/inspector_protocol/String16.h" -#include "platform/inspector_protocol/Values.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "platform/v8_inspector/protocol/Debugger.h" #include <v8.h> @@ -23,8 +22,8 @@ String16 toProtocolString(v8::Local<v8::String>); String16 toProtocolStringWithTypeCheck(v8::Local<v8::Value>); -String16 findSourceURL(const String16& content, bool multiline, bool* deprecated = nullptr); -String16 findSourceMapURL(const String16& content, bool multiline, bool* deprecated = nullptr); +String16 findSourceURL(const String16& content, bool multiline); +String16 findSourceMapURL(const String16& content, bool multiline); std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>> searchInTextByLinesImpl(V8InspectorSession*, const String16& text, const String16& query, bool caseSensitive, bool isRegex); } // namespace blink
diff --git a/third_party/WebKit/Source/platform/v8_inspector/debugger_script_externs.js b/third_party/WebKit/Source/platform/v8_inspector/debugger_script_externs.js index dddc709..7e80895e 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/debugger_script_externs.js +++ b/third_party/WebKit/Source/platform/v8_inspector/debugger_script_externs.js
@@ -29,8 +29,7 @@ startColumn: number, endColumn: number, executionContextId: number, - executionContextAuxData: string, - isInternalScript: boolean + executionContextAuxData: string }} */ var FormattedScript;
diff --git a/third_party/WebKit/Source/platform/v8_inspector/inspector_protocol_config.json b/third_party/WebKit/Source/platform/v8_inspector/inspector_protocol_config.json new file mode 100644 index 0000000..fce1069 --- /dev/null +++ b/third_party/WebKit/Source/platform/v8_inspector/inspector_protocol_config.json
@@ -0,0 +1,29 @@ +{ + "protocol": { + "path": "js_protocol.json", + "package": "platform/v8_inspector/protocol", + "output": "v8_inspector/protocol" + }, + + "export": { + "package": "platform/v8_inspector/public/protocol", + "output": "v8_inspector/public/protocol" + }, + + "string": { + "class_name": "String16" + }, + + "lib": { + "output": "inspector_protocol", + "string16_impl_header_path": "platform/v8_inspector/String16WTF.h", + "platform_impl_header_path": "platform/v8_inspector/PlatformWTF.h" + }, + + "lib_package": "platform/inspector_protocol", + + "class_export": { + "macro": "PLATFORM_EXPORT", + "header_path": "platform/PlatformExport.h" + } +}
diff --git a/third_party/WebKit/Source/platform/v8_inspector/inspector_protocol_config_stl.json b/third_party/WebKit/Source/platform/v8_inspector/inspector_protocol_config_stl.json new file mode 100644 index 0000000..f66bb1b --- /dev/null +++ b/third_party/WebKit/Source/platform/v8_inspector/inspector_protocol_config_stl.json
@@ -0,0 +1,29 @@ +{ + "protocol": { + "path": "js_protocol.json", + "package": "platform/v8_inspector/protocol", + "output": "v8_inspector/protocol" + }, + + "export": { + "package": "platform/v8_inspector/public/protocol", + "output": "v8_inspector/public/protocol" + }, + + "string": { + "class_name": "String16" + }, + + "lib": { + "output": "inspector_protocol", + "string16_impl_header_path": "platform/v8_inspector/String16STL.h", + "platform_impl_header_path": "platform/v8_inspector/PlatformSTL.h" + }, + + "lib_package": "platform/inspector_protocol", + + "class_export": { + "macro": "PLATFORM_EXPORT", + "header_path": "platform/PlatformExport.h" + } +}
diff --git a/third_party/WebKit/Source/platform/v8_inspector/js_protocol.json b/third_party/WebKit/Source/platform/v8_inspector/js_protocol.json index 620d49c8..f8ba298 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/js_protocol.json +++ b/third_party/WebKit/Source/platform/v8_inspector/js_protocol.json
@@ -198,7 +198,6 @@ ], "returns": [ { "name": "result", "$ref": "RemoteObject", "description": "Evaluation result." }, - { "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the result was thrown during the evaluation." }, { "name": "exceptionDetails", "$ref": "ExceptionDetails", "optional": true, "experimental": true, "description": "Exception details."} ], "description": "Evaluates expression on global object." @@ -214,7 +213,6 @@ ], "returns": [ { "name": "result", "$ref": "RemoteObject", "description": "Promise result. Will contain rejected value if promise was rejected." }, - { "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the promise was rejected." }, { "name": "exceptionDetails", "$ref": "ExceptionDetails", "optional": true, "description": "Exception details if stack strace is available."} ], "description": "Add handler to promise with given promise object id." @@ -234,7 +232,6 @@ ], "returns": [ { "name": "result", "$ref": "RemoteObject", "description": "Call result." }, - { "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the result was thrown during the evaluation." }, { "name": "exceptionDetails", "$ref": "ExceptionDetails", "optional": true, "experimental": true, "description": "Exception details."} ], "description": "Calls function with given declaration on the given object. Object group of the result is inherited from the target object." @@ -328,7 +325,6 @@ ], "returns": [ { "name": "result", "$ref": "RemoteObject", "description": "Run result." }, - { "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the result was thrown during the execution." }, { "name": "exceptionDetails", "$ref": "ExceptionDetails", "optional": true, "description": "Exception details."} ], "description": "Runs script with given id in a given context." @@ -568,13 +564,6 @@ "description": "Searches for given string in script content." }, { - "name": "canSetScriptSource", - "returns": [ - { "name": "result", "type": "boolean", "description": "True if <code>setScriptSource</code> is supported." } - ], - "description": "Always returns true." - }, - { "name": "setScriptSource", "parameters": [ { "name": "scriptId", "$ref": "Runtime.ScriptId", "description": "Id of the script to edit." }, @@ -631,7 +620,6 @@ ], "returns": [ { "name": "result", "$ref": "Runtime.RemoteObject", "description": "Object wrapper for the evaluation result." }, - { "name": "wasThrown", "type": "boolean", "optional": true, "description": "True if the result was thrown during the evaluation." }, { "name": "exceptionDetails", "$ref": "Runtime.ExceptionDetails", "optional": true, "experimental": true, "description": "Exception details."} ], "description": "Evaluates expression on a given call frame." @@ -648,15 +636,6 @@ "description": "Changes value of variable in a callframe. Object-based scopes are not supported and must be mutated manually." }, { - "name": "getBacktrace", - "returns": [ - { "name": "callFrames", "type": "array", "items": { "$ref": "CallFrame" }, "description": "Call stack the virtual machine stopped on." }, - { "name": "asyncStackTrace", "$ref": "Runtime.StackTrace", "optional": true, "description": "Async stack trace, if any." } - ], - "experimental": true, - "description": "Returns call stack including variables changed since VM was paused. VM must be paused." - }, - { "name": "setAsyncCallStackDepth", "parameters": [ { "name": "maxDepth", "type": "integer", "description": "Maximum depth of async call stacks. Setting to <code>0</code> will effectively disable collecting async call stacks (default)." } @@ -695,11 +674,9 @@ { "name": "executionContextId", "$ref": "Runtime.ExecutionContextId", "description": "Specifies script creation context.", "experimental": true }, { "name": "hash", "type": "string", "experimental": true, "description": "Content hash of the script."}, { "name": "executionContextAuxData", "type": "object", "optional": true, "description": "Embedder-specific auxiliary data.", "experimental": true }, - { "name": "isInternalScript", "type": "boolean", "optional": true, "description": "Determines whether this script is an internal script.", "experimental": true }, { "name": "isLiveEdit", "type": "boolean", "optional": true, "description": "True, if this script is generated as a result of the live edit operation.", "experimental": true }, { "name": "sourceMapURL", "type": "string", "optional": true, "description": "URL of source map associated with script (if any)." }, - { "name": "hasSourceURL", "type": "boolean", "optional": true, "description": "True, if this script has sourceURL.", "experimental": true }, - { "name": "deprecatedCommentWasUsed", "type": "boolean", "optional": true, "experimental": true, "description": "True, if '//@ sourceURL' or '//@ sourceMappingURL' was used."} + { "name": "hasSourceURL", "type": "boolean", "optional": true, "description": "True, if this script has sourceURL.", "experimental": true } ], "description": "Fired when virtual machine parses script. This event is also fired for all known and uncollected scripts upon enabling debugger." }, @@ -715,10 +692,8 @@ { "name": "executionContextId", "$ref": "Runtime.ExecutionContextId", "description": "Specifies script creation context.", "experimental": true }, { "name": "hash", "type": "string", "experimental": true, "description": "Content hash of the script."}, { "name": "executionContextAuxData", "type": "object", "optional": true, "description": "Embedder-specific auxiliary data.", "experimental": true }, - { "name": "isInternalScript", "type": "boolean", "optional": true, "description": "Determines whether this script is an internal script.", "experimental": true }, { "name": "sourceMapURL", "type": "string", "optional": true, "description": "URL of source map associated with script (if any)." }, - { "name": "hasSourceURL", "type": "boolean", "optional": true, "description": "True, if this script has sourceURL.", "experimental": true }, - { "name": "deprecatedCommentWasUsed", "type": "boolean", "optional": true, "experimental": true, "description": "True, if '//@ sourceURL' or '//@ sourceMappingURL' was used."} + { "name": "hasSourceURL", "type": "boolean", "optional": true, "description": "True, if this script has sourceURL.", "experimental": true } ], "description": "Fired when virtual machine fails to parse the script." },
diff --git a/third_party/WebKit/Source/platform/v8_inspector/public/V8ContextInfo.h b/third_party/WebKit/Source/platform/v8_inspector/public/V8ContextInfo.h index 81a98e6..5b867f7 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/public/V8ContextInfo.h +++ b/third_party/WebKit/Source/platform/v8_inspector/public/V8ContextInfo.h
@@ -5,7 +5,7 @@ #ifndef V8ContextInfo_h #define V8ContextInfo_h -#include "platform/inspector_protocol/String16.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include <v8.h>
diff --git a/third_party/WebKit/Source/platform/v8_inspector/public/V8Inspector.h b/third_party/WebKit/Source/platform/v8_inspector/public/V8Inspector.h index a62f0c8b..5d56bbb 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/public/V8Inspector.h +++ b/third_party/WebKit/Source/platform/v8_inspector/public/V8Inspector.h
@@ -5,8 +5,7 @@ #ifndef V8Inspector_h #define V8Inspector_h -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "platform/v8_inspector/public/V8ContextInfo.h" #include <v8.h>
diff --git a/third_party/WebKit/Source/platform/v8_inspector/public/V8InspectorClient.h b/third_party/WebKit/Source/platform/v8_inspector/public/V8InspectorClient.h index 27495ae9..d55d38f0 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/public/V8InspectorClient.h +++ b/third_party/WebKit/Source/platform/v8_inspector/public/V8InspectorClient.h
@@ -5,8 +5,7 @@ #ifndef V8InspectorClient_h #define V8InspectorClient_h -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include <v8.h>
diff --git a/third_party/WebKit/Source/platform/v8_inspector/public/V8InspectorSession.h b/third_party/WebKit/Source/platform/v8_inspector/public/V8InspectorSession.h index 365ab86..a015009 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/public/V8InspectorSession.h +++ b/third_party/WebKit/Source/platform/v8_inspector/public/V8InspectorSession.h
@@ -5,8 +5,7 @@ #ifndef V8InspectorSession_h #define V8InspectorSession_h -#include "platform/inspector_protocol/Array.h" -#include "platform/inspector_protocol/Platform.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "platform/v8_inspector/public/protocol/Debugger.h" #include "platform/v8_inspector/public/protocol/Runtime.h"
diff --git a/third_party/WebKit/Source/platform/v8_inspector/public/V8StackTrace.h b/third_party/WebKit/Source/platform/v8_inspector/public/V8StackTrace.h index 1913554..e39bb2f 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/public/V8StackTrace.h +++ b/third_party/WebKit/Source/platform/v8_inspector/public/V8StackTrace.h
@@ -5,8 +5,7 @@ #ifndef V8StackTrace_h #define V8StackTrace_h -#include "platform/inspector_protocol/Platform.h" -#include "platform/inspector_protocol/String16.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "platform/v8_inspector/public/protocol/Runtime.h" #include <v8.h>
diff --git a/third_party/WebKit/Source/platform/v8_inspector/v8_inspector.gyp b/third_party/WebKit/Source/platform/v8_inspector/v8_inspector.gyp index ebfc91a..6c5e09a 100644 --- a/third_party/WebKit/Source/platform/v8_inspector/v8_inspector.gyp +++ b/third_party/WebKit/Source/platform/v8_inspector/v8_inspector.gyp
@@ -52,39 +52,47 @@ 'target_name': 'protocol_sources', 'type': 'none', 'dependencies': ['protocol_version'], - 'variables': { - 'conditions': [ - ['debug_devtools=="node"', { - # Node build - 'jinja_module_files': [ - '../../../jinja2/jinja2/__init__.py', - '../../../markupsafe/markupsafe/__init__.py', # jinja2 dep - ], - }, { - 'jinja_module_files': [ - '<(DEPTH)/third_party/jinja2/__init__.py', - '<(DEPTH)/third_party/markupsafe/__init__.py', # jinja2 dep - ], - } - ], - ], - }, 'actions': [ { 'action_name': 'generateV8InspectorProtocolBackendSources', 'inputs': [ - '<@(jinja_module_files)', - # The python script in action below. - '../inspector_protocol/CodeGenerator.py', + '<(DEPTH)/third_party/jinja2/__init__.py', + '<(DEPTH)/third_party/markupsafe/__init__.py', # jinja2 dep # Source code templates. - '../inspector_protocol/TypeBuilder_h.template', - '../inspector_protocol/TypeBuilder_cpp.template', + '../inspector_protocol/Allocator_h.template', + '../inspector_protocol/Array_h.template', + '../inspector_protocol/BackendCallback_h.template', + '../inspector_protocol/CodeGenerator.py', + '../inspector_protocol/Collections_h.template', + '../inspector_protocol/DispatcherBase_cpp.template', + '../inspector_protocol/DispatcherBase_h.template', + '../inspector_protocol/ErrorSupport_cpp.template', + '../inspector_protocol/ErrorSupport_h.template', '../inspector_protocol/Exported_h.template', + '../inspector_protocol/FrontendChannel_h.template', '../inspector_protocol/Imported_h.template', + '../inspector_protocol/InspectorProtocol_cpp.template', + '../inspector_protocol/Maybe_h.template', + '../inspector_protocol/Object_cpp.template', + '../inspector_protocol/Object_h.template', + '../inspector_protocol/Parser_cpp.template', + '../inspector_protocol/Parser_h.template', + '../inspector_protocol/Platform_h.template', + '../inspector_protocol/String16_cpp.template', + '../inspector_protocol/String16_h.template', + '../inspector_protocol/TypeBuilder_cpp.template', + '../inspector_protocol/TypeBuilder_h.template', + '../inspector_protocol/ValueConversions_h.template', + '../inspector_protocol/Values_cpp.template', + '../inspector_protocol/Values_h.template', # Protocol definitions 'js_protocol.json', + # Config + 'inspector_protocol_config.json', ], 'outputs': [ + '<(blink_platform_output_dir)/inspector_protocol/InspectorProtocol.cpp', + '<(blink_platform_output_dir)/inspector_protocol/InspectorProtocol.h', '<(blink_platform_output_dir)/v8_inspector/protocol/Console.cpp', '<(blink_platform_output_dir)/v8_inspector/protocol/Console.h', '<(blink_platform_output_dir)/v8_inspector/protocol/Debugger.cpp', @@ -101,13 +109,8 @@ 'action': [ 'python', '../inspector_protocol/CodeGenerator.py', - '--protocol', 'js_protocol.json', - '--string_type', 'String16', - '--export_macro', 'PLATFORM_EXPORT', - '--output_dir', '<(blink_platform_output_dir)/v8_inspector/protocol', - '--output_package', 'platform/v8_inspector/protocol', - '--exported_dir', '<(blink_platform_output_dir)/v8_inspector/public/protocol', - '--exported_package', 'platform/v8_inspector/public/protocol', + '--output_base', '<(blink_platform_output_dir)', + '--config', 'v8_inspector/inspector_protocol_config.json', ], 'message': 'Generating protocol backend sources from json definitions.', }, @@ -139,15 +142,81 @@ ] }, { + 'target_name': 'protocol_sources_stl', + 'type': 'none', + 'dependencies': ['protocol_version'], + }, + 'actions': [ + { + 'action_name': 'generateV8InspectorProtocolBackendSourcesSTL', + 'inputs': [ + '../../../jinja2/jinja2/__init__.py', + '../../../markupsafe/markupsafe/__init__.py', # jinja2 dep + # Source code templates. + '../inspector_protocol/Allocator_h.template', + '../inspector_protocol/Array_h.template', + '../inspector_protocol/BackendCallback_h.template', + '../inspector_protocol/CodeGenerator.py', + '../inspector_protocol/Collections_h.template', + '../inspector_protocol/DispatcherBase_cpp.template', + '../inspector_protocol/DispatcherBase_h.template', + '../inspector_protocol/ErrorSupport_cpp.template', + '../inspector_protocol/ErrorSupport_h.template', + '../inspector_protocol/Exported_h.template', + '../inspector_protocol/FrontendChannel_h.template', + '../inspector_protocol/Imported_h.template', + '../inspector_protocol/InspectorProtocol_cpp.template', + '../inspector_protocol/Maybe_h.template', + '../inspector_protocol/Object_cpp.template', + '../inspector_protocol/Object_h.template', + '../inspector_protocol/Parser_cpp.template', + '../inspector_protocol/Parser_h.template', + '../inspector_protocol/Platform_h.template', + '../inspector_protocol/String16_cpp.template', + '../inspector_protocol/String16_h.template', + '../inspector_protocol/TypeBuilder_cpp.template', + '../inspector_protocol/TypeBuilder_h.template', + '../inspector_protocol/ValueConversions_h.template', + '../inspector_protocol/Values_cpp.template', + '../inspector_protocol/Values_h.template', + # Protocol definitions + 'js_protocol.json', + # Config + 'inspector_protocol_config_stl.json', + ], + 'outputs': [ + '<(blink_platform_output_dir)/inspector_protocol/InspectorProtocol.cpp', + '<(blink_platform_output_dir)/inspector_protocol/InspectorProtocol.h', + '<(blink_platform_output_dir)/v8_inspector/protocol/Console.cpp', + '<(blink_platform_output_dir)/v8_inspector/protocol/Console.h', + '<(blink_platform_output_dir)/v8_inspector/protocol/Debugger.cpp', + '<(blink_platform_output_dir)/v8_inspector/protocol/Debugger.h', + '<(blink_platform_output_dir)/v8_inspector/protocol/HeapProfiler.cpp', + '<(blink_platform_output_dir)/v8_inspector/protocol/HeapProfiler.h', + '<(blink_platform_output_dir)/v8_inspector/protocol/Profiler.cpp', + '<(blink_platform_output_dir)/v8_inspector/protocol/Profiler.h', + '<(blink_platform_output_dir)/v8_inspector/protocol/Runtime.cpp', + '<(blink_platform_output_dir)/v8_inspector/protocol/Runtime.h', + '<(blink_platform_output_dir)/v8_inspector/public/protocol/Runtime.h', + '<(blink_platform_output_dir)/v8_inspector/public/protocol/Debugger.h', + ], + 'action': [ + 'python', + '../inspector_protocol/CodeGenerator.py', + '--output_base', '<(blink_platform_output_dir)', + '--config', 'v8_inspector/inspector_protocol_config.json', + ], + 'message': 'Generating protocol backend sources from json definitions.', + }, + ] + }, + { 'target_name': 'v8_inspector_stl', 'type': '<(component)', 'dependencies': [ ':inspector_injected_script', ':inspector_debugger_script', - ':protocol_sources', - ], - 'defines': [ - 'V8_INSPECTOR_USE_STL=1' + ':protocol_sources_stl', ], 'include_dirs': [ '../..', @@ -156,6 +225,8 @@ '<(SHARED_INTERMEDIATE_DIR)/blink', ], 'sources': [ + '<(blink_platform_output_dir)/inspector_protocol/InspectorProtocol.cpp', + '<(blink_platform_output_dir)/inspector_protocol/InspectorProtocol.h', '<(blink_platform_output_dir)/v8_inspector/protocol/Console.cpp', '<(blink_platform_output_dir)/v8_inspector/protocol/Console.h', '<(blink_platform_output_dir)/v8_inspector/protocol/Debugger.cpp', @@ -166,24 +237,8 @@ '<(blink_platform_output_dir)/v8_inspector/protocol/Profiler.h', '<(blink_platform_output_dir)/v8_inspector/protocol/Runtime.cpp', '<(blink_platform_output_dir)/v8_inspector/protocol/Runtime.h', - - '../inspector_protocol/Allocator.h', - '../inspector_protocol/Array.h', - '../inspector_protocol/Collections.h', - '../inspector_protocol/DispatcherBase.cpp', - '../inspector_protocol/DispatcherBase.h', - '../inspector_protocol/ErrorSupport.cpp', - '../inspector_protocol/ErrorSupport.h', - '../inspector_protocol/Maybe.h', - '../inspector_protocol/Parser.cpp', - '../inspector_protocol/Parser.h', - '../inspector_protocol/FrontendChannel.h', - '../inspector_protocol/String16.h', - '../inspector_protocol/String16STL.cpp', - '../inspector_protocol/String16STL.h', - '../inspector_protocol/Values.cpp', - '../inspector_protocol/Values.h', - '../inspector_protocol/ValueConversions.h', + '<(blink_platform_output_dir)/v8_inspector/public/protocol/Runtime.h', + '<(blink_platform_output_dir)/v8_inspector/public/protocol/Debugger.h', 'Atomics.h', 'InjectedScript.cpp', @@ -195,9 +250,12 @@ 'JavaScriptCallFrame.cpp', 'JavaScriptCallFrame.h', 'MuteConsoleScope.h', - 'ScriptBreakpoint.h', + 'PlatformSTL.h', 'RemoteObjectId.cpp', 'RemoteObjectId.h', + 'ScriptBreakpoint.h', + 'String16STL.cpp', + 'String16STL.h', 'V8Console.cpp', 'V8Console.h', 'V8ConsoleAgentImpl.cpp',
diff --git a/third_party/WebKit/Source/web/AssociatedURLLoader.cpp b/third_party/WebKit/Source/web/AssociatedURLLoader.cpp index 2e50987..0dfcbad 100644 --- a/third_party/WebKit/Source/web/AssociatedURLLoader.cpp +++ b/third_party/WebKit/Source/web/AssociatedURLLoader.cpp
@@ -404,7 +404,7 @@ if (m_loader) { m_loader->cancel(); - m_loader.reset(); + m_loader = nullptr; } m_clientAdapter.reset(); }
diff --git a/third_party/WebKit/Source/web/AssociatedURLLoader.h b/third_party/WebKit/Source/web/AssociatedURLLoader.h index 06d4717..e57a2006 100644 --- a/third_party/WebKit/Source/web/AssociatedURLLoader.h +++ b/third_party/WebKit/Source/web/AssociatedURLLoader.h
@@ -84,7 +84,7 @@ // An adapter which converts the DocumentThreadableLoaderClient method // calls into the WebURLLoaderClient method calls. std::unique_ptr<ClientAdapter> m_clientAdapter; - std::unique_ptr<DocumentThreadableLoader> m_loader; + Persistent<DocumentThreadableLoader> m_loader; // A ContextLifecycleObserver for cancelling |m_loader| when the Document // is detached.
diff --git a/third_party/WebKit/Source/web/AssociatedURLLoaderTest.cpp b/third_party/WebKit/Source/web/AssociatedURLLoaderTest.cpp index 9e3c8cbc..7263b7f 100644 --- a/third_party/WebKit/Source/web/AssociatedURLLoaderTest.cpp +++ b/third_party/WebKit/Source/web/AssociatedURLLoaderTest.cpp
@@ -200,7 +200,7 @@ { WebURLRequest request; request.setURL(toKURL("http://www.test.com/success.html")); - if (equalIgnoringCase(WebString::fromUTF8(headerField), "referer")) + if (equalIgnoringASCIICase(WebString::fromUTF8(headerField), "referer")) request.setHTTPReferrer(WebString::fromUTF8(headerValue), WebReferrerPolicyDefault); else request.setHTTPHeaderField(WebString::fromUTF8(headerField), WebString::fromUTF8(headerValue));
diff --git a/third_party/WebKit/Source/web/ChromeClientImpl.cpp b/third_party/WebKit/Source/web/ChromeClientImpl.cpp index 1c2e778..a419836a 100644 --- a/third_party/WebKit/Source/web/ChromeClientImpl.cpp +++ b/third_party/WebKit/Source/web/ChromeClientImpl.cpp
@@ -825,14 +825,28 @@ m_webView->exitFullScreenForElement(element); } -void ChromeClientImpl::clearCompositedSelection() +void ChromeClientImpl::clearCompositedSelection(LocalFrame* frame) { - m_webView->clearCompositedSelection(); + LocalFrame* localRoot = frame->localFrameRoot(); + auto client = WebLocalFrameImpl::fromFrame(localRoot)->frameWidget()->client(); + if (!client) + return; + + auto layerTreeView = client->layerTreeView(); + if (layerTreeView) + layerTreeView->clearSelection(); } -void ChromeClientImpl::updateCompositedSelection(const CompositedSelection& selection) +void ChromeClientImpl::updateCompositedSelection(LocalFrame* frame, const CompositedSelection& selection) { - m_webView->updateCompositedSelection(WebSelection(selection)); + LocalFrame* localRoot = frame->localFrameRoot(); + WebWidgetClient* client = WebLocalFrameImpl::fromFrame(localRoot)->frameWidget()->client(); + if (!client) + return; + + WebLayerTreeView* layerTreeView = client->layerTreeView(); + if (layerTreeView) + layerTreeView->registerSelection(WebSelection(selection)); } bool ChromeClientImpl::hasOpenedPopup() const
diff --git a/third_party/WebKit/Source/web/ChromeClientImpl.h b/third_party/WebKit/Source/web/ChromeClientImpl.h index 037cae3..4c59c5d 100644 --- a/third_party/WebKit/Source/web/ChromeClientImpl.h +++ b/third_party/WebKit/Source/web/ChromeClientImpl.h
@@ -136,8 +136,8 @@ void enterFullScreenForElement(Element*) override; void exitFullScreenForElement(Element*) override; - void clearCompositedSelection() override; - void updateCompositedSelection(const CompositedSelection&) override; + void clearCompositedSelection(LocalFrame*) override; + void updateCompositedSelection(LocalFrame*, const CompositedSelection&) override; // ChromeClient methods: void postAccessibilityNotification(AXObject*, AXObjectCache::AXNotification) override;
diff --git a/third_party/WebKit/Source/web/InspectorOverlay.cpp b/third_party/WebKit/Source/web/InspectorOverlay.cpp index e30b2572..5382e2cd 100644 --- a/third_party/WebKit/Source/web/InspectorOverlay.cpp +++ b/third_party/WebKit/Source/web/InspectorOverlay.cpp
@@ -50,7 +50,6 @@ #include "platform/ScriptForbiddenScope.h" #include "platform/graphics/GraphicsContext.h" #include "platform/graphics/paint/CullRect.h" -#include "platform/inspector_protocol/Values.h" #include "platform/v8_inspector/public/V8InspectorSession.h" #include "public/platform/Platform.h" #include "public/platform/WebData.h"
diff --git a/third_party/WebKit/Source/web/InspectorOverlay.h b/third_party/WebKit/Source/web/InspectorOverlay.h index 720a88c..43e10b4 100644 --- a/third_party/WebKit/Source/web/InspectorOverlay.h +++ b/third_party/WebKit/Source/web/InspectorOverlay.h
@@ -36,7 +36,7 @@ #include "platform/geometry/LayoutRect.h" #include "platform/graphics/Color.h" #include "platform/heap/Handle.h" -#include "platform/inspector_protocol/Values.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "public/web/WebInputEvent.h" #include "wtf/RefPtr.h" #include "wtf/text/WTFString.h"
diff --git a/third_party/WebKit/Source/web/PageWidgetDelegate.cpp b/third_party/WebKit/Source/web/PageWidgetDelegate.cpp index 9061d055..9c19d8d2 100644 --- a/third_party/WebKit/Source/web/PageWidgetDelegate.cpp +++ b/third_party/WebKit/Source/web/PageWidgetDelegate.cpp
@@ -37,7 +37,6 @@ #include "core/page/AutoscrollController.h" #include "core/page/Page.h" #include "core/paint/TransformRecorder.h" -#include "platform/Logging.h" #include "platform/graphics/GraphicsContext.h" #include "platform/graphics/paint/ClipRecorder.h" #include "platform/graphics/paint/CullRect.h"
diff --git a/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp b/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp index 04373b1..4c1622c 100644 --- a/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp +++ b/third_party/WebKit/Source/web/ServiceWorkerGlobalScopeProxy.cpp
@@ -37,6 +37,7 @@ #include "core/dom/ExecutionContext.h" #include "core/dom/MessagePort.h" #include "core/inspector/ConsoleMessage.h" +#include "core/origin_trials/OriginTrials.h" #include "core/workers/WorkerGlobalScope.h" #include "core/workers/WorkerThread.h" #include "modules/background_sync/SyncEvent.h" @@ -154,6 +155,16 @@ void ServiceWorkerGlobalScopeProxy::dispatchForeignFetchEvent(int responseID, int eventFinishID, const WebServiceWorkerRequest& webRequest) { + if (!OriginTrials::foreignFetchEnabled(workerGlobalScope())) { + // If origin trial tokens have expired, or are otherwise no longer valid + // no events should be dispatched. + // TODO(mek): Ideally the browser wouldn't even start the service worker + // if its tokens have expired. + ServiceWorkerGlobalScopeClient::from(workerGlobalScope())->respondToFetchEvent(responseID); + ServiceWorkerGlobalScopeClient::from(workerGlobalScope())->didHandleFetchEvent(eventFinishID, WebServiceWorkerEventResultCompleted); + return; + } + ScriptState::Scope scope(workerGlobalScope()->scriptController()->getScriptState()); RefPtr<SecurityOrigin> origin = SecurityOrigin::create(webRequest.referrerUrl()); WaitUntilObserver* waitUntilObserver = WaitUntilObserver::create(workerGlobalScope(), WaitUntilObserver::Fetch, eventFinishID); @@ -177,7 +188,7 @@ { WaitUntilObserver* observer = WaitUntilObserver::create(workerGlobalScope(), WaitUntilObserver::Install, eventID); Event* event; - if (RuntimeEnabledFeatures::foreignFetchEnabled()) + if (OriginTrials::foreignFetchEnabled(workerGlobalScope())) event = InstallEvent::create(EventTypeNames::install, ExtendableEventInit(), observer); else event = ExtendableEvent::create(EventTypeNames::install, ExtendableEventInit(), observer);
diff --git a/third_party/WebKit/Source/web/SpellCheckerClientImpl.cpp b/third_party/WebKit/Source/web/SpellCheckerClientImpl.cpp index 7f61bdb..4a12445 100644 --- a/third_party/WebKit/Source/web/SpellCheckerClientImpl.cpp +++ b/third_party/WebKit/Source/web/SpellCheckerClientImpl.cpp
@@ -154,15 +154,6 @@ m_webView->spellCheckClient()->cancelAllPendingRequests(); } -void SpellCheckerClientImpl::checkGrammarOfString(const String& text, WTF::Vector<GrammarDetail>& details, int* badGrammarLocation, int* badGrammarLength) -{ - if (badGrammarLocation) - *badGrammarLocation = -1; - if (badGrammarLength) - *badGrammarLength = 0; - return; -} - void SpellCheckerClientImpl::updateSpellingUIWithMisspelledWord(const String& misspelledWord) { if (m_webView->spellCheckClient())
diff --git a/third_party/WebKit/Source/web/SpellCheckerClientImpl.h b/third_party/WebKit/Source/web/SpellCheckerClientImpl.h index 0ba0147..6aab8eb8 100644 --- a/third_party/WebKit/Source/web/SpellCheckerClientImpl.h +++ b/third_party/WebKit/Source/web/SpellCheckerClientImpl.h
@@ -48,8 +48,6 @@ bool isContinuousSpellCheckingEnabled() override; void toggleContinuousSpellChecking() override; void checkSpellingOfString(const String&, int* misspellingLocation, int* misspellingLength) override; - void checkGrammarOfString(const String&, Vector<GrammarDetail>&, - int* badGrammarLocation, int* badGrammarLength) override; void updateSpellingUIWithMisspelledWord(const String&) override; void showSpellingUI(bool show) override; bool spellingUIIsShowing() override;
diff --git a/third_party/WebKit/Source/web/WebAXObject.cpp b/third_party/WebKit/Source/web/WebAXObject.cpp index c80ceb5a..7fdc92f 100644 --- a/third_party/WebKit/Source/web/WebAXObject.cpp +++ b/third_party/WebKit/Source/web/WebAXObject.cpp
@@ -238,7 +238,7 @@ if (isDetached()) return false; - return equalIgnoringCase(m_private->getAttribute(HTMLNames::aria_readonlyAttr), "true"); + return equalIgnoringASCIICase(m_private->getAttribute(HTMLNames::aria_readonlyAttr), "true"); } WebString WebAXObject::ariaAutoComplete() const
diff --git a/third_party/WebKit/Source/web/WebCache.cpp b/third_party/WebKit/Source/web/WebCache.cpp index 8d0995c..a3309ef 100644 --- a/third_party/WebKit/Source/web/WebCache.cpp +++ b/third_party/WebKit/Source/web/WebCache.cpp
@@ -43,7 +43,7 @@ to.size = from.size; to.liveSize = from.liveSize; to.decodedSize = from.decodedSize; - to.purgeableSize = from.purgedSize; + to.purgeableSize = from.purgeableSize; to.purgedSize = from.purgedSize; }
diff --git a/third_party/WebKit/Source/web/WebDataSourceImpl.cpp b/third_party/WebKit/Source/web/WebDataSourceImpl.cpp index 4f97c50..70e1d41 100644 --- a/third_party/WebKit/Source/web/WebDataSourceImpl.cpp +++ b/third_party/WebKit/Source/web/WebDataSourceImpl.cpp
@@ -75,6 +75,15 @@ DocumentLoader::appendRedirect(url); } +void WebDataSourceImpl::updateNavigationTimings(double redirectStartTime, double redirectEndTime, double fetchStartTime, const WebVector<WebURL>& redirectChain) +{ + for (size_t i = 0; i + 1 < redirectChain.size(); ++i) + timing().addRedirect(redirectChain[i], redirectChain[i + 1]); + timing().setRedirectStart(redirectStartTime); + timing().setRedirectEnd(redirectEndTime); + timing().setFetchStart(fetchStartTime); +} + void WebDataSourceImpl::redirectChain(WebVector<WebURL>& result) const { result.assign(m_redirectChain);
diff --git a/third_party/WebKit/Source/web/WebDataSourceImpl.h b/third_party/WebKit/Source/web/WebDataSourceImpl.h index 717c9c6a..4eaf435 100644 --- a/third_party/WebKit/Source/web/WebDataSourceImpl.h +++ b/third_party/WebKit/Source/web/WebDataSourceImpl.h
@@ -65,6 +65,7 @@ ExtraData* getExtraData() const override; void setExtraData(ExtraData*) override; void setNavigationStartTime(double) override; + void updateNavigationTimings(double redirectStartTime, double redirectEndTime, double fetchStartTime, const WebVector<WebURL>& redirectChain) override; void setSubresourceFilter(WebDocumentSubresourceFilter*) override; static WebNavigationType toWebNavigationType(NavigationType);
diff --git a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp index 087fe335..e795efb 100644 --- a/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp +++ b/third_party/WebKit/Source/web/WebDevToolsAgentImpl.cpp
@@ -71,7 +71,7 @@ #include "platform/TraceEvent.h" #include "platform/graphics/GraphicsContext.h" #include "platform/graphics/paint/PaintController.h" -#include "platform/inspector_protocol/Values.h" +#include "platform/inspector_protocol/InspectorProtocol.h" #include "platform/v8_inspector/public/V8Inspector.h" #include "platform/v8_inspector/public/V8InspectorSession.h" #include "public/platform/Platform.h"
diff --git a/third_party/WebKit/Source/web/WebDocument.cpp b/third_party/WebKit/Source/web/WebDocument.cpp index da41a82e..7184c1c 100644 --- a/third_party/WebKit/Source/web/WebDocument.cpp +++ b/third_party/WebKit/Source/web/WebDocument.cpp
@@ -307,7 +307,7 @@ HTMLLinkElement* linkElement = document->linkManifest(); if (!linkElement) return false; - return equalIgnoringCase(linkElement->fastGetAttribute(HTMLNames::crossoriginAttr), "use-credentials"); + return equalIgnoringASCIICase(linkElement->fastGetAttribute(HTMLNames::crossoriginAttr), "use-credentials"); } WebDistillabilityFeatures WebDocument::distillabilityFeatures()
diff --git a/third_party/WebKit/Source/web/WebElement.cpp b/third_party/WebKit/Source/web/WebElement.cpp index 43778b3..3033177ad 100644 --- a/third_party/WebKit/Source/web/WebElement.cpp +++ b/third_party/WebKit/Source/web/WebElement.cpp
@@ -72,7 +72,7 @@ return true; } - return equalIgnoringCase(element->getAttribute(roleAttr), "textbox"); + return equalIgnoringASCIICase(element->getAttribute(roleAttr), "textbox"); } WebString WebElement::tagName() const
diff --git a/third_party/WebKit/Source/web/WebPerformance.cpp b/third_party/WebKit/Source/web/WebPerformance.cpp index eca3b0bf..49882d2 100644 --- a/third_party/WebKit/Source/web/WebPerformance.cpp +++ b/third_party/WebKit/Source/web/WebPerformance.cpp
@@ -190,6 +190,11 @@ return millisecondsToSeconds(m_private->timing()->firstContentfulPaint()); } +double WebPerformance::firstMeaningfulPaint() const +{ + return millisecondsToSeconds(m_private->timing()->firstMeaningfulPaint()); +} + double WebPerformance::parseStart() const { return millisecondsToSeconds(m_private->timing()->parseStart());
diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp index 586cd17..e855f2c8 100644 --- a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp +++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp
@@ -442,7 +442,7 @@ void WebPluginContainerImpl::reportGeometry() { // We cannot compute geometry without a parent or layoutObject. - if (!parent() || !m_element || !m_element->layoutObject()) + if (!parent() || !m_element || !m_element->layoutObject() || !m_webPlugin) return; IntRect windowRect, clipRect, unobscuredRect;
diff --git a/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp b/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp index 41545bba..4b43701 100644 --- a/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp +++ b/third_party/WebKit/Source/web/WebRuntimeFeatures.cpp
@@ -75,6 +75,11 @@ RuntimeEnabledFeatures::setCanvas2dImageChromiumEnabled(enable); } +void WebRuntimeFeatures::enableColorCorrectRendering(bool enable) +{ + RuntimeEnabledFeatures::setColorCorrectRenderingEnabled(enable); +} + void WebRuntimeFeatures::enableCompositedSelectionUpdate(bool enable) { RuntimeEnabledFeatures::setCompositedSelectionUpdateEnabled(enable); @@ -140,11 +145,6 @@ RuntimeEnabledFeatures::setFileSystemEnabled(enable); } -void WebRuntimeFeatures::enableImageColorProfiles(bool enable) -{ - RuntimeEnabledFeatures::setImageColorProfilesEnabled(enable); -} - void WebRuntimeFeatures::enableInputMultipleFieldsUI(bool enable) { RuntimeEnabledFeatures::setInputMultipleFieldsUIEnabled(enable);
diff --git a/third_party/WebKit/Source/web/WebSearchableFormData.cpp b/third_party/WebKit/Source/web/WebSearchableFormData.cpp index cd96fab..ac45e509 100644 --- a/third_party/WebKit/Source/web/WebSearchableFormData.cpp +++ b/third_party/WebKit/Source/web/WebSearchableFormData.cpp
@@ -230,7 +230,7 @@ // Only consider forms that GET data. // Allow HTTPS only when an input element is provided. - if (equalIgnoringCase(formElement->getAttribute(methodAttr), "post") + if (equalIgnoringASCIICase(formElement->getAttribute(methodAttr), "post") || (!isHTTPFormSubmit(*formElement) && !inputElement)) return;
diff --git a/third_party/WebKit/Source/web/WebSettingsImpl.cpp b/third_party/WebKit/Source/web/WebSettingsImpl.cpp index 59044411..dd3b59d3 100644 --- a/third_party/WebKit/Source/web/WebSettingsImpl.cpp +++ b/third_party/WebKit/Source/web/WebSettingsImpl.cpp
@@ -153,6 +153,11 @@ m_autoZoomFocusedNodeToLegibleScale = autoZoomFocusedNodeToLegibleScale; } +void WebSettingsImpl::setBrowserSideNavigationEnabled(bool enabled) +{ + m_settings->setBrowserSideNavigationEnabled(enabled); +} + void WebSettingsImpl::setTextAutosizingEnabled(bool enabled) { m_devToolsEmulator->setTextAutosizingEnabled(enabled);
diff --git a/third_party/WebKit/Source/web/WebSettingsImpl.h b/third_party/WebKit/Source/web/WebSettingsImpl.h index ca7d6f7c6..e49cd61 100644 --- a/third_party/WebKit/Source/web/WebSettingsImpl.h +++ b/third_party/WebKit/Source/web/WebSettingsImpl.h
@@ -68,6 +68,7 @@ void setAntialiasedClips2dCanvasEnabled(bool) override; void setAutoplayExperimentMode(const WebString&) override; void setAutoZoomFocusedNodeToLegibleScale(bool) override; + void setBrowserSideNavigationEnabled(bool) override; void setCaretBrowsingEnabled(bool) override; void setClobberUserAgentInitialScaleQuirk(bool) override; void setCookieEnabled(bool) override;
diff --git a/third_party/WebKit/Source/web/WebViewImpl.cpp b/third_party/WebKit/Source/web/WebViewImpl.cpp index d462654..9bc4335c 100644 --- a/third_party/WebKit/Source/web/WebViewImpl.cpp +++ b/third_party/WebKit/Source/web/WebViewImpl.cpp
@@ -102,7 +102,6 @@ #include "platform/Cursor.h" #include "platform/Histogram.h" #include "platform/KeyboardCodes.h" -#include "platform/Logging.h" #include "platform/PlatformGestureEvent.h" #include "platform/PlatformKeyboardEvent.h" #include "platform/PlatformMouseEvent.h" @@ -2112,18 +2111,6 @@ m_fullscreenController->exitFullScreenForElement(element); } -void WebViewImpl::clearCompositedSelection() -{ - if (m_layerTreeView) - m_layerTreeView->clearSelection(); -} - -void WebViewImpl::updateCompositedSelection(const WebSelection& selection) -{ - if (m_layerTreeView) - m_layerTreeView->registerSelection(selection); -} - bool WebViewImpl::hasHorizontalScrollbar() { return mainFrameImpl()->frameView()->horizontalScrollbar(); @@ -2160,7 +2147,7 @@ page()->frameHost().visualViewport().startTrackingPinchStats(); - TRACE_EVENT1("input", "WebViewImpl::handleInputEvent", "type", inputTypeToName(inputEvent.type)); + TRACE_EVENT1("input,rail", "WebViewImpl::handleInputEvent", "type", inputTypeToName(inputEvent.type)); // If we've started a drag and drop operation, ignore input events until // we're done. if (m_doingDragAndDrop) @@ -3026,7 +3013,7 @@ return true; } - return equalIgnoringCase(element->getAttribute(HTMLNames::roleAttr), "textbox"); + return equalIgnoringASCIICase(element->getAttribute(HTMLNames::roleAttr), "textbox"); } bool WebViewImpl::scrollFocusedEditableElementIntoRect(const WebRect& rectInViewport) @@ -3326,22 +3313,9 @@ void WebViewImpl::setDeviceColorProfile(const WebVector<char>& colorProfile) { - if (!page()) - return; - Vector<char> deviceProfile; deviceProfile.append(colorProfile.data(), colorProfile.size()); ImageDecoder::setTargetColorProfile(deviceProfile); - - page()->setDeviceColorProfile(deviceProfile); -} - -void WebViewImpl::resetDeviceColorProfileForTesting() -{ - if (!page()) - return; - - page()->resetDeviceColorProfileForTesting(); } void WebViewImpl::enableAutoResizeMode(const WebSize& minSize, const WebSize& maxSize) @@ -3839,7 +3813,6 @@ m_client->widgetClient()->didInvalidateRect(damagedRect); } } - updatePageOverlays(); } void WebViewImpl::configureAutoResizeMode() @@ -4101,8 +4074,9 @@ if (view->needsLayout()) view->layout(); - m_fullscreenController->didUpdateLayout(); + updatePageOverlays(); + m_fullscreenController->didUpdateLayout(); m_client->didUpdateLayout(); } @@ -4285,7 +4259,7 @@ // We register viewport layers here since there may not be a layer // tree view prior to this point. registerViewportLayersWithCompositor(); - updatePageOverlays(); + // TODO(enne): Work around page visibility changes not being // propagated to the WebView in some circumstances. This needs to // be refreshed here when setting a new root layer to avoid being @@ -4306,10 +4280,12 @@ void WebViewImpl::invalidateRect(const IntRect& rect) { - if (m_layerTreeView) + if (m_layerTreeView) { updateLayerTreeViewport(); - else if (m_client) + } else if (m_client) { + // This is only for WebViewPlugin. m_client->widgetClient()->didInvalidateRect(rect); + } } PaintLayerCompositor* WebViewImpl::compositor() const
diff --git a/third_party/WebKit/Source/web/WebViewImpl.h b/third_party/WebKit/Source/web/WebViewImpl.h index c953b41..26e93e7 100644 --- a/third_party/WebKit/Source/web/WebViewImpl.h +++ b/third_party/WebKit/Source/web/WebViewImpl.h
@@ -222,7 +222,6 @@ void setZoomFactorForDeviceScaleFactor(float) override; void setDeviceColorProfile(const WebVector<char>&) override; - void resetDeviceColorProfileForTesting() override; void enableAutoResizeMode( const WebSize& minSize, @@ -468,9 +467,6 @@ void enterFullScreenForElement(Element*); void exitFullScreenForElement(Element*); - void clearCompositedSelection(); - void updateCompositedSelection(const WebSelection&); - // Exposed for the purpose of overriding device metrics. void sendResizeEventAndRepaint();
diff --git a/third_party/WebKit/Source/web/tests/FrameSerializerTest.cpp b/third_party/WebKit/Source/web/tests/FrameSerializerTest.cpp index 7d23579c..d717713 100644 --- a/third_party/WebKit/Source/web/tests/FrameSerializerTest.cpp +++ b/third_party/WebKit/Source/web/tests/FrameSerializerTest.cpp
@@ -140,7 +140,7 @@ for (size_t i = 0; i < m_resources.size(); ++i) { const SerializedResource& resource = m_resources[i]; if (resource.url == url && !resource.data->isEmpty() - && (mime.isNull() || equalIgnoringCase(resource.mimeType, mime))) + && (mime.isNull() || equalIgnoringASCIICase(resource.mimeType, mime))) return &resource; } return nullptr;
diff --git a/third_party/WebKit/Source/web/tests/VirtualTimeTest.cpp b/third_party/WebKit/Source/web/tests/VirtualTimeTest.cpp index 7d78d77..41e6eef 100644 --- a/third_party/WebKit/Source/web/tests/VirtualTimeTest.cpp +++ b/third_party/WebKit/Source/web/tests/VirtualTimeTest.cpp
@@ -56,7 +56,13 @@ } } -TEST_F(VirtualTimeTest, DOMTimersFireInExpectedOrder) +// http://crbug.com/633321 +#if OS(ANDROID) +#define MAYBE_DOMTimersFireInExpectedOrder DISABLED_DOMTimersFireInExpectedOrder +#else +#define MAYBE_DOMTimersFireInExpectedOrder DOMTimersFireInExpectedOrder +#endif +TEST_F(VirtualTimeTest, MAYBE_DOMTimersFireInExpectedOrder) { webView().scheduler()->enableVirtualTime(); @@ -78,7 +84,13 @@ EXPECT_EQ("c, b, a", ExecuteJavaScript("run_order.join(', ')")); } -TEST_F(VirtualTimeTest, SetInterval) +// http://crbug.com/633321 +#if OS(ANDROID) +#define MAYBE_SetInterval DISABLED_SetInterval +#else +#define MAYBE_SetInterval SetInterval +#endif +TEST_F(VirtualTimeTest, MAYBE_SetInterval) { webView().scheduler()->enableVirtualTime(); @@ -98,7 +110,13 @@ EXPECT_EQ("9, timer, 8, 7, 6, 5, 4, 3, 2, 1, 0", ExecuteJavaScript("run_order.join(', ')")); } -TEST_F(VirtualTimeTest, AllowVirtualTimeToAdvance) +// http://crbug.com/633321 +#if OS(ANDROID) +#define MAYBE_AllowVirtualTimeToAdvance DISABLED_AllowVirtualTimeToAdvance +#else +#define MAYBE_AllowVirtualTimeToAdvance AllowVirtualTimeToAdvance +#endif +TEST_F(VirtualTimeTest, MAYBE_AllowVirtualTimeToAdvance) { webView().scheduler()->enableVirtualTime(); webView().scheduler()->setVirtualTimePolicy(WebViewScheduler::VirtualTimePolicy::PAUSE); @@ -121,7 +139,13 @@ EXPECT_EQ("c, b, a", ExecuteJavaScript("run_order.join(', ')")); } -TEST_F(VirtualTimeTest, VirtualTimeNotAllowedToAdvanceWhileResourcesLoading) +// http://crbug.com/633321 +#if OS(ANDROID) +#define MAYBE_VirtualTimeNotAllowedToAdvanceWhileResourcesLoading DISABLED_VirtualTimeNotAllowedToAdvanceWhileResourcesLoading +#else +#define MAYBE_VirtualTimeNotAllowedToAdvanceWhileResourcesLoading VirtualTimeNotAllowedToAdvanceWhileResourcesLoading +#endif +TEST_F(VirtualTimeTest, MAYBE_VirtualTimeNotAllowedToAdvanceWhileResourcesLoading) { webView().scheduler()->enableVirtualTime(); webView().scheduler()->setVirtualTimePolicy(WebViewScheduler::VirtualTimePolicy::DETERMINISTIC_LOADING);
diff --git a/third_party/WebKit/Source/wtf/text/AtomicString.h b/third_party/WebKit/Source/wtf/text/AtomicString.h index 67b7dc2..722927df 100644 --- a/third_party/WebKit/Source/wtf/text/AtomicString.h +++ b/third_party/WebKit/Source/wtf/text/AtomicString.h
@@ -148,6 +148,8 @@ CString latin1() const { return m_string.latin1(); } CString utf8(UTF8ConversionMode mode = LenientUTF8Conversion) const { return m_string.utf8(mode); } + size_t charactersSizeInBytes() const { return m_string.charactersSizeInBytes(); } + #ifndef NDEBUG void show() const; #endif
diff --git a/third_party/WebKit/Source/wtf/text/CString.cpp b/third_party/WebKit/Source/wtf/text/CString.cpp index 9d85026..56895ab 100644 --- a/third_party/WebKit/Source/wtf/text/CString.cpp +++ b/third_party/WebKit/Source/wtf/text/CString.cpp
@@ -26,6 +26,7 @@ #include "wtf/text/CString.h" +#include "wtf/ASCIICType.h" #include "wtf/allocator/PartitionAlloc.h" #include "wtf/allocator/Partitions.h" #include <string.h> @@ -128,4 +129,47 @@ return !strcmp(a.data(), b); } +std::ostream& operator<<(std::ostream& ostream, const CString& string) +{ + if (string.isNull()) + return ostream << "<null>"; + + ostream << '"'; + for (size_t index = 0; index < string.length(); ++index) { + // Print shorthands for select cases. + char character = string.data()[index]; + switch (character) { + case '\t': + ostream << "\\t"; + break; + case '\n': + ostream << "\\n"; + break; + case '\r': + ostream << "\\r"; + break; + case '"': + ostream << "\\\""; + break; + case '\\': + ostream << "\\\\"; + break; + default: + if (isASCIIPrintable(character)) { + ostream << character; + } else { + // Print "\xHH" for control or non-ASCII characters. + ostream << "\\x"; + if (character >= 0 && character < 0x10) + ostream << "0"; + ostream.setf(std::ios_base::hex, std::ios_base::basefield); + ostream.setf(std::ios::uppercase); + ostream << (character & 0xff); + } + break; + } + } + return ostream << '"'; +} + } // namespace WTF
diff --git a/third_party/WebKit/Source/wtf/text/CString.h b/third_party/WebKit/Source/wtf/text/CString.h index c48f261..785886c 100644 --- a/third_party/WebKit/Source/wtf/text/CString.h +++ b/third_party/WebKit/Source/wtf/text/CString.h
@@ -91,6 +91,9 @@ inline bool operator!=(const CString& a, const CString& b) { return !(a == b); } WTF_EXPORT bool operator==(const CString& a, const char* b); inline bool operator!=(const CString& a, const char* b) { return !(a == b); } +// Pretty printer for gtest and base/logging.*. It prepends and appends +// double-quotes, and escapes characters other than ASCII printables. +WTF_EXPORT std::ostream& operator<<(std::ostream&, const CString&); } // namespace WTF
diff --git a/third_party/WebKit/Source/wtf/text/CStringTest.cpp b/third_party/WebKit/Source/wtf/text/CStringTest.cpp index 6e4956d..0abb4601 100644 --- a/third_party/WebKit/Source/wtf/text/CStringTest.cpp +++ b/third_party/WebKit/Source/wtf/text/CStringTest.cpp
@@ -26,9 +26,22 @@ #include "wtf/text/CString.h" #include "testing/gtest/include/gtest/gtest.h" +#include <sstream> namespace WTF { +namespace { + +CString printedString(const CString& string) +{ + std::ostringstream output; + output << string; + const std::string& result = output.str(); + return CString(result.data(), result.length()); +} + +} // anonymous namespace + TEST(CStringTest, NullStringConstructor) { CString string; @@ -197,4 +210,12 @@ EXPECT_TRUE(c != d); } +TEST(CStringTest, Printer) +{ + EXPECT_STREQ("<null>", printedString(CString()).data()); + EXPECT_STREQ("\"abc\"", printedString("abc").data()); + EXPECT_STREQ("\"\\t\\n\\r\\\"\\\\\"", printedString("\t\n\r\"\\").data()); + EXPECT_STREQ("\"\\xFF\\x00\\x01xyz\"", printedString(CString("\xff\0\x01xyz", 6)).data()); +} + } // namespace WTF
diff --git a/third_party/WebKit/Source/wtf/text/CharacterNames.h b/third_party/WebKit/Source/wtf/text/CharacterNames.h index 8f51780..0abe0d85 100644 --- a/third_party/WebKit/Source/wtf/text/CharacterNames.h +++ b/third_party/WebKit/Source/wtf/text/CharacterNames.h
@@ -59,6 +59,7 @@ const UChar32 womanCharacter = 0x1F469; const UChar32 kissMarkCharacter = 0x1F48B; const UChar32 familyCharacter = 0x1F46A; +const UChar femaleSignCharacter = 0x2640; const UChar firstStrongIsolateCharacter = 0x2068; const UChar fisheyeCharacter = 0x25C9; const UChar fullstopCharacter = 0x002E; @@ -86,6 +87,7 @@ const UChar leftToRightOverrideCharacter = 0x202D; const UChar lineSeparator = 0x2028; const UChar lowLineCharacter = 0x005F; +const UChar maleSignCharacter = 0x2642; const UChar minusSignCharacter = 0x2212; const UChar newlineCharacter = 0x000A; const UChar formFeedCharacter = 0x000C; @@ -96,6 +98,7 @@ const UChar paragraphSeparator = 0x2029; const UChar popDirectionalFormattingCharacter = 0x202C; const UChar popDirectionalIsolateCharacter = 0x2069; +const UChar32 rainbowCharacter = 0x1F308; const UChar replacementCharacter = 0xFFFD; const UChar rightDoubleQuotationMarkCharacter = 0x201D; const UChar rightSingleQuotationMarkCharacter = 0x2019; @@ -107,12 +110,14 @@ const UChar smallLetterSharpSCharacter = 0x00DF; const UChar softHyphenCharacter = 0x00AD; const UChar spaceCharacter = 0x0020; +const UChar staffOfAesculapiusCharacter = 0x2695; const UChar tabulationCharacter = 0x0009; const UChar tibetanMarkIntersyllabicTshegCharacter = 0x0F0B; const UChar tibetanMarkDelimiterTshegBstarCharacter = 0x0F0C; const UChar32 ugariticWordDividerCharacter = 0x1039F; const UChar variationSelector15Character = 0xFE0E; const UChar variationSelector16Character = 0xFE0F; +const UChar32 wavingWhiteFlagCharacter = 0x1F3F3; const UChar whiteBulletCharacter = 0x25E6; const UChar whiteCircleCharacter = 0x25CB; const UChar whiteSesameDotCharacter = 0xFE46; @@ -144,6 +149,7 @@ using WTF::Unicode::ethiopicWordspaceCharacter; using WTF::Unicode::eyeCharacter; using WTF::Unicode::familyCharacter; +using WTF::Unicode::femaleSignCharacter; using WTF::Unicode::firstStrongIsolateCharacter; using WTF::Unicode::fisheyeCharacter; using WTF::Unicode::formFeedCharacter; @@ -172,6 +178,7 @@ using WTF::Unicode::leftToRightOverrideCharacter; using WTF::Unicode::lineSeparator; using WTF::Unicode::lowLineCharacter; +using WTF::Unicode::maleSignCharacter; using WTF::Unicode::minusSignCharacter; using WTF::Unicode::newlineCharacter; using WTF::Unicode::nationalDigitShapesCharacter; @@ -181,6 +188,7 @@ using WTF::Unicode::paragraphSeparator; using WTF::Unicode::popDirectionalFormattingCharacter; using WTF::Unicode::popDirectionalIsolateCharacter; +using WTF::Unicode::rainbowCharacter; using WTF::Unicode::replacementCharacter; using WTF::Unicode::rightDoubleQuotationMarkCharacter; using WTF::Unicode::rightSingleQuotationMarkCharacter; @@ -192,12 +200,14 @@ using WTF::Unicode::smallLetterSharpSCharacter; using WTF::Unicode::softHyphenCharacter; using WTF::Unicode::spaceCharacter; +using WTF::Unicode::staffOfAesculapiusCharacter; using WTF::Unicode::tabulationCharacter; using WTF::Unicode::tibetanMarkIntersyllabicTshegCharacter; using WTF::Unicode::tibetanMarkDelimiterTshegBstarCharacter; using WTF::Unicode::ugariticWordDividerCharacter; using WTF::Unicode::variationSelector15Character; using WTF::Unicode::variationSelector16Character; +using WTF::Unicode::wavingWhiteFlagCharacter; using WTF::Unicode::whiteBulletCharacter; using WTF::Unicode::whiteCircleCharacter; using WTF::Unicode::whiteSesameDotCharacter;
diff --git a/third_party/WebKit/Source/wtf/text/StringImpl.cpp b/third_party/WebKit/Source/wtf/text/StringImpl.cpp index 850f986..bb0eaeb 100644 --- a/third_party/WebKit/Source/wtf/text/StringImpl.cpp +++ b/third_party/WebKit/Source/wtf/text/StringImpl.cpp
@@ -1524,23 +1524,26 @@ return newImpl.release(); } -PassRefPtr<StringImpl> StringImpl::replace(unsigned position, unsigned lengthToReplace, StringImpl* str) +// TODO(esprehn): Passing a null replacement is the same as empty string for +// this method but all others treat null as a no-op. We should choose one +// behavior. +PassRefPtr<StringImpl> StringImpl::replace(unsigned position, unsigned lengthToReplace, const StringView& string) { position = min(position, length()); lengthToReplace = min(lengthToReplace, length() - position); - unsigned lengthToInsert = str ? str->length() : 0; + unsigned lengthToInsert = string.length(); if (!lengthToReplace && !lengthToInsert) return this; RELEASE_ASSERT((length() - lengthToReplace) < (numeric_limits<unsigned>::max() - lengthToInsert)); - if (is8Bit() && (!str || str->is8Bit())) { + if (is8Bit() && (string.isNull() || string.is8Bit())) { LChar* data; RefPtr<StringImpl> newImpl = createUninitialized(length() - lengthToReplace + lengthToInsert, data); memcpy(data, characters8(), position * sizeof(LChar)); - if (str) - memcpy(data + position, str->characters8(), lengthToInsert * sizeof(LChar)); + if (!string.isNull()) + memcpy(data + position, string.characters8(), lengthToInsert * sizeof(LChar)); memcpy(data + position + lengthToInsert, characters8() + position + lengthToReplace, (length() - position - lengthToReplace) * sizeof(LChar)); return newImpl.release(); @@ -1553,12 +1556,12 @@ data[i] = characters8()[i]; else memcpy(data, characters16(), position * sizeof(UChar)); - if (str) { - if (str->is8Bit()) + if (!string.isNull()) { + if (string.is8Bit()) for (unsigned i = 0; i < lengthToInsert; ++i) - data[i + position] = str->characters8()[i]; + data[i + position] = string.characters8()[i]; else - memcpy(data + position, str->characters16(), lengthToInsert * sizeof(UChar)); + memcpy(data + position, string.characters16(), lengthToInsert * sizeof(UChar)); } if (is8Bit()) { for (unsigned i = 0; i < length() - position - lengthToReplace; ++i) @@ -1570,15 +1573,13 @@ return newImpl.release(); } -PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, StringImpl* replacement) +PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, const StringView& replacement) { - if (!replacement) + if (replacement.isNull()) return this; - - if (replacement->is8Bit()) - return replace(pattern, replacement->characters8(), replacement->length()); - - return replace(pattern, replacement->characters16(), replacement->length()); + if (replacement.is8Bit()) + return replace(pattern, replacement.characters8(), replacement.length()); + return replace(pattern, replacement.characters16(), replacement.length()); } PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, const LChar* replacement, unsigned repStrLength) @@ -1734,16 +1735,16 @@ return newImpl.release(); } -PassRefPtr<StringImpl> StringImpl::replace(StringImpl* pattern, StringImpl* replacement) +PassRefPtr<StringImpl> StringImpl::replace(const StringView& pattern, const StringView& replacement) { - if (!pattern || !replacement) + if (pattern.isNull() || replacement.isNull()) return this; - unsigned patternLength = pattern->length(); + unsigned patternLength = pattern.length(); if (!patternLength) return this; - unsigned repStrLength = replacement->length(); + unsigned repStrLength = replacement.length(); size_t srcSegmentStart = 0; unsigned matchCount = 0; @@ -1771,7 +1772,7 @@ srcSegmentStart = 0; unsigned dstOffset = 0; bool srcIs8Bit = is8Bit(); - bool replacementIs8Bit = replacement->is8Bit(); + bool replacementIs8Bit = replacement.is8Bit(); // There are 4 cases: // 1. This and replacement are both 8 bit. @@ -1786,7 +1787,7 @@ srcSegmentLength = srcSegmentEnd - srcSegmentStart; memcpy(data + dstOffset, characters8() + srcSegmentStart, srcSegmentLength * sizeof(LChar)); dstOffset += srcSegmentLength; - memcpy(data + dstOffset, replacement->characters8(), repStrLength * sizeof(LChar)); + memcpy(data + dstOffset, replacement.characters8(), repStrLength * sizeof(LChar)); dstOffset += repStrLength; srcSegmentStart = srcSegmentEnd + patternLength; } @@ -1815,10 +1816,10 @@ if (replacementIs8Bit) { // Cases 2 & 3. for (unsigned i = 0; i < repStrLength; ++i) - data[i + dstOffset] = replacement->characters8()[i]; + data[i + dstOffset] = replacement.characters8()[i]; } else { // Case 4 - memcpy(data + dstOffset, replacement->characters16(), repStrLength * sizeof(UChar)); + memcpy(data + dstOffset, replacement.characters16(), repStrLength * sizeof(UChar)); } dstOffset += repStrLength; srcSegmentStart = srcSegmentEnd + patternLength; @@ -1992,14 +1993,6 @@ return codePointCompareIgnoringASCIICase(length1, length2, string1->characters16(), string2); } -size_t StringImpl::sizeInBytes() const -{ - size_t size = length(); - if (!is8Bit()) - size *= 2; - return size + sizeof(*this); -} - UChar32 toUpper(UChar32 c, const AtomicString& localeIdentifier) { if (!localeIdentifier.isNull()) {
diff --git a/third_party/WebKit/Source/wtf/text/StringImpl.h b/third_party/WebKit/Source/wtf/text/StringImpl.h index 30736e2..8f4a4e4 100644 --- a/third_party/WebKit/Source/wtf/text/StringImpl.h +++ b/third_party/WebKit/Source/wtf/text/StringImpl.h
@@ -44,13 +44,6 @@ namespace WTF { struct AlreadyHashed; -struct CStringTranslator; -template<typename CharacterType> struct HashAndCharactersTranslator; -struct HashAndUTF8CharactersTranslator; -struct LCharBufferTranslator; -struct CharBufferFromLiteralDataTranslator; -struct SubstringTranslator; -struct UCharBufferTranslator; template<typename> class RetainPtr; enum TextCaseSensitivity { TextCaseSensitive, TextCaseASCIIInsensitive, TextCaseInsensitive }; @@ -109,14 +102,6 @@ // https://docs.google.com/document/d/1kOCUlJdh2WJMJGDf-WoEQhmnjKLaOYRbiHz5TiGJl14/edit?usp=sharing class WTF_EXPORT StringImpl { WTF_MAKE_NONCOPYABLE(StringImpl); - friend struct WTF::CStringTranslator; - template<typename CharacterType> friend struct WTF::HashAndCharactersTranslator; - friend struct WTF::HashAndUTF8CharactersTranslator; - friend struct WTF::CharBufferFromLiteralDataTranslator; - friend struct WTF::LCharBufferTranslator; - friend struct WTF::SubstringTranslator; - friend struct WTF::UCharBufferTranslator; - private: // StringImpls are allocated out of the WTF buffer partition. void* operator new(size_t); @@ -229,45 +214,39 @@ template <typename CharType> ALWAYS_INLINE const CharType * getCharacters() const; - size_t sizeInBytes() const; + size_t charactersSizeInBytes() const + { + return length() * (is8Bit() ? sizeof(LChar) : sizeof(UChar)); + } bool isAtomic() const { return m_isAtomic; } void setIsAtomic(bool isAtomic) { m_isAtomic = isAtomic; } bool isStatic() const { return m_isStatic; } -private: // The high bits of 'hash' are always empty, but we prefer to store our // flags in the low bits because it makes them slightly more efficient to // access. So, we shift left and right when setting and getting our hash // code. void setHash(unsigned hash) const { - ASSERT(!hasHash()); + DCHECK(!hasHash()); // Multiple clients assume that StringHasher is the canonical string // hash function. - ASSERT(hash == (is8Bit() ? StringHasher::computeHashAndMaskTop8Bits(characters8(), m_length) : StringHasher::computeHashAndMaskTop8Bits(characters16(), m_length))); + DCHECK(hash == (is8Bit() ? StringHasher::computeHashAndMaskTop8Bits(characters8(), m_length) : StringHasher::computeHashAndMaskTop8Bits(characters16(), m_length))); m_hash = hash; - ASSERT(hash); // Verify that 0 is a valid sentinel hash value. + DCHECK(hash); // Verify that 0 is a valid sentinel hash value. } - unsigned rawHash() const - { - return m_hash; - } - - void destroyIfNotStatic(); - -public: bool hasHash() const { - return rawHash() != 0; + return m_hash != 0; } unsigned existingHash() const { - ASSERT(hasHash()); - return rawHash(); + DCHECK(hasHash()); + return m_hash; } unsigned hash() const @@ -390,13 +369,12 @@ bool endsWithIgnoringCase(const StringView&) const; bool endsWithIgnoringASCIICase(const StringView&) const; - PassRefPtr<StringImpl> replace(UChar, UChar); - PassRefPtr<StringImpl> replace(UChar, StringImpl*); - ALWAYS_INLINE PassRefPtr<StringImpl> replace(UChar pattern, const char* replacement, unsigned replacementLength) { return replace(pattern, reinterpret_cast<const LChar*>(replacement), replacementLength); } - PassRefPtr<StringImpl> replace(UChar, const LChar*, unsigned replacementLength); - PassRefPtr<StringImpl> replace(UChar, const UChar*, unsigned replacementLength); - PassRefPtr<StringImpl> replace(StringImpl*, StringImpl*); - PassRefPtr<StringImpl> replace(unsigned index, unsigned len, StringImpl*); + // Replace parts of the string. + PassRefPtr<StringImpl> replace(UChar pattern, UChar replacement); + PassRefPtr<StringImpl> replace(UChar pattern, const StringView& replacement); + PassRefPtr<StringImpl> replace(const StringView& pattern, const StringView& replacement); + PassRefPtr<StringImpl> replace(unsigned index, unsigned lengthToReplace, const StringView& replacement); + PassRefPtr<StringImpl> upconvertedString(); #if OS(MACOSX) @@ -418,10 +396,15 @@ return sizeof(StringImpl) + length * sizeof(CharType); } + PassRefPtr<StringImpl> replace(UChar pattern, const LChar* replacement, unsigned replacementLength); + PassRefPtr<StringImpl> replace(UChar pattern, const UChar* replacement, unsigned replacementLength); + template <class UCharPredicate> PassRefPtr<StringImpl> stripMatchedCharacters(UCharPredicate); template <typename CharType, class UCharPredicate> PassRefPtr<StringImpl> simplifyMatchedCharactersToSpace(UCharPredicate, StripBehavior); NEVER_INLINE unsigned hashSlowCase() const; + void destroyIfNotStatic(); + #ifdef STRING_STATS static StringStats m_stringStats; #endif
diff --git a/third_party/WebKit/Source/wtf/text/WTFString.cpp b/third_party/WebKit/Source/wtf/text/WTFString.cpp index e6692f8..1686121e 100644 --- a/third_party/WebKit/Source/wtf/text/WTFString.cpp +++ b/third_party/WebKit/Source/wtf/text/WTFString.cpp
@@ -76,12 +76,12 @@ { } -void String::append(const String& string) +void String::append(const StringView& string) { if (string.isEmpty()) return; if (!m_impl) { - m_impl = string.m_impl; + m_impl = string.toString().releaseImpl(); return; } @@ -90,7 +90,7 @@ // case where exactly one String is pointing at this StringImpl, but even // then it's going to require a call into the allocator every single time. - if (m_impl->is8Bit() && string.m_impl->is8Bit()) { + if (m_impl->is8Bit() && string.is8Bit()) { LChar* data; RELEASE_ASSERT(string.length() <= std::numeric_limits<unsigned>::max() - m_impl->length()); RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length() + string.length(), data); @@ -109,10 +109,10 @@ else StringImpl::copyChars(data, m_impl->characters16(), m_impl->length()); - if (string.impl()->is8Bit()) - StringImpl::copyChars(data + m_impl->length(), string.impl()->characters8(), string.impl()->length()); + if (string.is8Bit()) + StringImpl::copyChars(data + m_impl->length(), string.characters8(), string.length()); else - StringImpl::copyChars(data + m_impl->length(), string.impl()->characters16(), string.impl()->length()); + StringImpl::copyChars(data + m_impl->length(), string.characters16(), string.length()); m_impl = newImpl.release(); } @@ -161,82 +161,6 @@ return codePointCompareIgnoringASCIICase(a.impl(), reinterpret_cast<const LChar*>(b)); } -void String::insert(const String& string, unsigned position) -{ - if (string.isEmpty()) { - if (string.isNull()) - return; - if (isNull()) - m_impl = string.impl(); - return; - } - - if (string.is8Bit()) - insert(string.impl()->characters8(), string.length(), position); - else - insert(string.impl()->characters16(), string.length(), position); -} - -void String::append(const LChar* charactersToAppend, unsigned lengthToAppend) -{ - if (!m_impl) { - if (!charactersToAppend) - return; - m_impl = StringImpl::create(charactersToAppend, lengthToAppend); - return; - } - - if (!lengthToAppend) - return; - - ASSERT(charactersToAppend); - - unsigned strLength = m_impl->length(); - - if (m_impl->is8Bit()) { - RELEASE_ASSERT(lengthToAppend <= std::numeric_limits<unsigned>::max() - strLength); - LChar* data; - RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength + lengthToAppend, data); - StringImpl::copyChars(data, m_impl->characters8(), strLength); - StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend); - m_impl = newImpl.release(); - return; - } - - RELEASE_ASSERT(lengthToAppend <= std::numeric_limits<unsigned>::max() - strLength); - UChar* data; - RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() + lengthToAppend, data); - StringImpl::copyChars(data, m_impl->characters16(), strLength); - StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend); - m_impl = newImpl.release(); -} - -void String::append(const UChar* charactersToAppend, unsigned lengthToAppend) -{ - if (!m_impl) { - if (!charactersToAppend) - return; - m_impl = StringImpl::create(charactersToAppend, lengthToAppend); - return; - } - - if (!lengthToAppend) - return; - - unsigned strLength = m_impl->length(); - - ASSERT(charactersToAppend); - RELEASE_ASSERT(lengthToAppend <= std::numeric_limits<unsigned>::max() - strLength); - UChar* data; - RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength + lengthToAppend, data); - if (m_impl->is8Bit()) - StringImpl::copyChars(data, characters8(), strLength); - else - StringImpl::copyChars(data, characters16(), strLength); - StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend); - m_impl = newImpl.release(); -} - template<typename CharType> PassRefPtr<StringImpl> insertInternal(PassRefPtr<StringImpl> impl, const CharType* charactersToInsert, unsigned lengthToInsert, unsigned position) { @@ -263,24 +187,29 @@ return newImpl.release(); } -void String::insert(const UChar* charactersToInsert, unsigned lengthToInsert, unsigned position) +void String::insert(const StringView& string, unsigned position) { - if (position >= length()) { - append(charactersToInsert, lengthToInsert); + if (string.isEmpty()) { + if (string.isNull()) + return; + if (isNull()) + m_impl = string.toString().releaseImpl(); return; } - ASSERT(m_impl); - m_impl = insertInternal(m_impl.release(), charactersToInsert, lengthToInsert, position); -} -void String::insert(const LChar* charactersToInsert, unsigned lengthToInsert, unsigned position) -{ if (position >= length()) { - append(charactersToInsert, lengthToInsert); + if (string.is8Bit()) + append(string); + else + append(string); return; } - ASSERT(m_impl); - m_impl = insertInternal(m_impl.release(), charactersToInsert, lengthToInsert, position); + + DCHECK(m_impl); + if (string.is8Bit()) + m_impl = insertInternal(m_impl.release(), string.characters8(), string.length(), position); + else + m_impl = insertInternal(m_impl.release(), string.characters16(), string.length(), position); } UChar32 String::characterStartingAt(unsigned i) const
diff --git a/third_party/WebKit/Source/wtf/text/WTFString.h b/third_party/WebKit/Source/wtf/text/WTFString.h index b5aa5a9e..f4e529e 100644 --- a/third_party/WebKit/Source/wtf/text/WTFString.h +++ b/third_party/WebKit/Source/wtf/text/WTFString.h
@@ -138,13 +138,6 @@ bool is8Bit() const { return m_impl->is8Bit(); } - unsigned sizeInBytes() const - { - if (!m_impl) - return 0; - return m_impl->length() * (is8Bit() ? sizeof(LChar) : sizeof(UChar)); - } - CString ascii() const; CString latin1() const; CString utf8(UTF8ConversionMode = LenientUTF8Conversion) const; @@ -220,47 +213,36 @@ bool endsWith(UChar character) const { return m_impl ? m_impl->endsWith(character) : false; } - void append(const String&); + void append(const StringView&); void append(LChar); void append(char c) { append(static_cast<LChar>(c)); } void append(UChar); - void append(const LChar*, unsigned length); - void append(const char* charactersToAppend, unsigned length) { append(reinterpret_cast<const LChar*>(charactersToAppend), length); } - void append(const UChar*, unsigned length); - void insert(const String&, unsigned pos); - void insert(const LChar*, unsigned length, unsigned pos); - void insert(const UChar*, unsigned length, unsigned pos); + void insert(const StringView&, unsigned pos); - String& replace(UChar a, UChar b) + // TODO(esprehn): replace strangely both modifies this String *and* return a + // value. It should only do one of those. + String& replace(UChar pattern, UChar replacement) { if (m_impl) - m_impl = m_impl->replace(a, b); + m_impl = m_impl->replace(pattern, replacement); return *this; } - String& replace(UChar a, const String& b) + String& replace(UChar pattern, const StringView& replacement) { if (m_impl) - m_impl = m_impl->replace(a, b.impl()); + m_impl = m_impl->replace(pattern, replacement); return *this; } - String& replace(const String& a, const String& b) + String& replace(const StringView& pattern, const StringView& replacement) { if (m_impl) - m_impl = m_impl->replace(a.impl(), b.impl()); + m_impl = m_impl->replace(pattern, replacement); return *this; } - String& replace(unsigned index, unsigned len, const String& b) + String& replace(unsigned index, unsigned lengthToReplace, const StringView& replacement) { if (m_impl) - m_impl = m_impl->replace(index, len, b.impl()); - return *this; - } - - ALWAYS_INLINE String& replace(UChar a, const char* characters) - { - ASSERT(characters); - if (m_impl) - m_impl = m_impl->replace(a, characters, strlen(characters)); + m_impl = m_impl->replace(index, lengthToReplace, replacement); return *this; } @@ -376,6 +358,8 @@ bool containsOnlyLatin1() const; bool containsOnlyWhitespace() const { return !m_impl || m_impl->containsOnlyWhitespace(); } + size_t charactersSizeInBytes() const { return m_impl ? m_impl->charactersSizeInBytes() : 0; } + // Hash table deleted values, which are only constructed and never copied or // destroyed. String(WTF::HashTableDeletedValueType) : m_impl(WTF::HashTableDeletedValue) { }
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer.py index 5b77580..012bcfb 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer.py
@@ -30,7 +30,6 @@ import logging from webkitpy.common.memoized import memoized -from functools import reduce _log = logging.getLogger(__name__) @@ -52,8 +51,8 @@ def __init__(self, host, port, port_names, skip_scm_commands): self._filesystem = host.filesystem self._skip_scm_commands = skip_scm_commands - self._files_to_delete = [] - self._files_to_add = [] + self.files_to_delete = [] + self.files_to_add = [] self._scm = host.scm() self._default_port = port self._ports = {} @@ -138,11 +137,11 @@ # have the same baseline, then it can be promoted up to be the LayoutTests baseline. # All other baselines can only be removed if they're redundant with a baseline earlier # in the fallback order. They can never promoted up. - directories_immediately_preceding_root = self._directories_immediately_preceding_root(baseline_name) + directories_preceding_root = self._directories_immediately_preceding_root(baseline_name) shared_result = None root_baseline_unused = False - for directory in directories_immediately_preceding_root: + for directory in directories_preceding_root: this_result = new_results_by_directory.get(directory) # If any of these directories don't have a baseline, there's no optimization we can do. @@ -164,21 +163,20 @@ return new_results_by_directory[baseline_root] = shared_result - for directory in directories_immediately_preceding_root: + for directory in directories_preceding_root: del new_results_by_directory[directory] def _find_optimal_result_placement(self, baseline_name): results_by_directory = self.read_results_by_directory(baseline_name) results_by_port_name = self._results_by_port_name(results_by_directory, baseline_name) - port_names_by_result = _invert_dictionary(results_by_port_name) new_results_by_directory = self._remove_redundant_results( - results_by_directory, results_by_port_name, port_names_by_result, baseline_name) + results_by_directory, results_by_port_name, baseline_name) self._optimize_result_for_root(new_results_by_directory, baseline_name) return results_by_directory, new_results_by_directory - def _remove_redundant_results(self, results_by_directory, results_by_port_name, port_names_by_result, baseline_name): + def _remove_redundant_results(self, results_by_directory, results_by_port_name, baseline_name): new_results_by_directory = copy.copy(results_by_directory) for port_name, port in self._ports.items(): current_result = results_by_port_name.get(port_name) @@ -219,7 +217,7 @@ return filename.replace(platform_dir, '').split(self._filesystem.sep)[0] return '(generic)' - def _move_baselines(self, baseline_name, results_by_directory, new_results_by_directory): + def move_baselines(self, baseline_name, results_by_directory, new_results_by_directory): data_for_result = {} for directory, result in results_by_directory.items(): if not result in data_for_result: @@ -242,7 +240,7 @@ for platform_dir in sorted(self._platform(filename) for filename in scm_files): _log.debug(" " + platform_dir) if self._skip_scm_commands: - self._files_to_delete.extend(scm_files) + self.files_to_delete.extend(scm_files) else: self._scm.delete_list(scm_files) if fs_files: @@ -268,8 +266,8 @@ _log.debug(" " + platform_dir) if self._skip_scm_commands: # Have adds win over deletes. - self._files_to_delete = list(set(self._files_to_delete) - set(file_names)) - self._files_to_add.extend(file_names) + self.files_to_delete = list(set(self.files_to_delete) - set(file_names)) + self.files_to_add.extend(file_names) else: self._scm.add_list(file_names) else: @@ -307,14 +305,14 @@ _log.debug(" After: ") self.write_by_directory(new_results_by_directory, _log.debug, " ") - self._move_baselines(baseline_name, results_by_directory, new_results_by_directory) + self.move_baselines(baseline_name, results_by_directory, new_results_by_directory) return True def _optimize_virtual_root(self, baseline_name, non_virtual_baseline_name): - virtual_root_expected_baseline_path = self._filesystem.join(self._layout_tests_dir, baseline_name) - if not self._filesystem.exists(virtual_root_expected_baseline_path): + virtual_root_baseline_path = self._filesystem.join(self._layout_tests_dir, baseline_name) + if not self._filesystem.exists(virtual_root_baseline_path): return - root_sha1 = self._filesystem.sha1(virtual_root_expected_baseline_path) + root_sha1 = self._filesystem.sha1(virtual_root_baseline_path) results_by_directory = self.read_results_by_directory(non_virtual_baseline_name) # See if all the immediate predecessors of the virtual root have the same expected result. @@ -328,17 +326,17 @@ break _log.debug("Deleting redundant virtual root expected result.") - if self._skip_scm_commands and virtual_root_expected_baseline_path in self._files_to_add: - self._files_to_add.remove(virtual_root_expected_baseline_path) - if self._scm.exists(virtual_root_expected_baseline_path): - _log.debug(" Deleting (SCM): " + virtual_root_expected_baseline_path) + if self._skip_scm_commands and virtual_root_baseline_path in self.files_to_add: + self.files_to_add.remove(virtual_root_baseline_path) + if self._scm.exists(virtual_root_baseline_path): + _log.debug(" Deleting (SCM): " + virtual_root_baseline_path) if self._skip_scm_commands: - self._files_to_delete.append(virtual_root_expected_baseline_path) + self.files_to_delete.append(virtual_root_baseline_path) else: - self._scm.delete(virtual_root_expected_baseline_path) + self._scm.delete(virtual_root_baseline_path) else: - _log.debug(" Deleting (file system): " + virtual_root_expected_baseline_path) - self._filesystem.remove(virtual_root_expected_baseline_path) + _log.debug(" Deleting (file system): " + virtual_root_baseline_path) + self._filesystem.remove(virtual_root_baseline_path) def optimize(self, baseline_name): # The virtual fallback path is the same as the non-virtual one tacked on to the bottom of the non-virtual path. @@ -347,16 +345,16 @@ # # So, we can optimize the virtual path, then the virtual root and then the regular path. - self._files_to_delete = [] - self._files_to_add = [] + self.files_to_delete = [] + self.files_to_add = [] _log.debug("Optimizing regular fallback path.") result = self._optimize_subtree(baseline_name) non_virtual_baseline_name = self._virtual_base(baseline_name) if not non_virtual_baseline_name: - return result, self._files_to_delete, self._files_to_add + return result, self.files_to_delete, self.files_to_add self._optimize_virtual_root(baseline_name, non_virtual_baseline_name) _log.debug("Optimizing non-virtual fallback path.") result |= self._optimize_subtree(non_virtual_baseline_name) - return result, self._files_to_delete, self._files_to_add + return result, self.files_to_delete, self.files_to_add
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer_unittest.py index 33e3312..95cbc97 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/baselineoptimizer_unittest.py
@@ -51,12 +51,12 @@ def delete_list(self, paths): for path in paths: if path in self._exclusion_list: - raise Exception("File is not SCM managed: " + path) + raise Exception('File is not SCM managed: ' + path) return MockSCM.delete_list(self, paths) def move(self, origin, destination): if origin in self._exclusion_list: - raise Exception("File is not SCM managed: " + origin) + raise Exception('File is not SCM managed: ' + origin) return MockSCM.move(self, origin, destination) @@ -73,13 +73,16 @@ host.filesystem.write_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt', 'result B') baseline_optimizer = BaselineOptimizer(host, host.port_factory.get( ), host.port_factory.all_port_names(), skip_scm_commands=False) - baseline_optimizer._move_baselines('another/test-expected.txt', { - '/mock-checkout/third_party/WebKit/LayoutTests/platform/win': 'aaa', - '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac': 'aaa', - '/mock-checkout/third_party/WebKit/LayoutTests': 'bbb', - }, { - '/mock-checkout/third_party/WebKit/LayoutTests': 'aaa', - }) + baseline_optimizer.move_baselines( + 'another/test-expected.txt', + { + '/mock-checkout/third_party/WebKit/LayoutTests/platform/win': 'aaa', + '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac': 'aaa', + '/mock-checkout/third_party/WebKit/LayoutTests': 'bbb', + }, + { + '/mock-checkout/third_party/WebKit/LayoutTests': 'aaa', + }) self.assertEqual(host.filesystem.read_binary_file( '/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt'), 'result A') @@ -94,28 +97,31 @@ host.filesystem.write_binary_file('/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt', 'result B') baseline_optimizer = BaselineOptimizer(host, host.port_factory.get( ), host.port_factory.all_port_names(), skip_scm_commands=True) - baseline_optimizer._move_baselines('another/test-expected.txt', { - '/mock-checkout/third_party/WebKit/LayoutTests/platform/win': 'aaa', - '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac': 'aaa', - '/mock-checkout/third_party/WebKit/LayoutTests': 'bbb', - }, { - '/mock-checkout/third_party/WebKit/LayoutTests/platform/linux': 'bbb', - '/mock-checkout/third_party/WebKit/LayoutTests': 'aaa', - }) + baseline_optimizer.move_baselines( + 'another/test-expected.txt', + { + '/mock-checkout/third_party/WebKit/LayoutTests/platform/win': 'aaa', + '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac': 'aaa', + '/mock-checkout/third_party/WebKit/LayoutTests': 'bbb', + }, + { + '/mock-checkout/third_party/WebKit/LayoutTests/platform/linux': 'bbb', + '/mock-checkout/third_party/WebKit/LayoutTests': 'aaa', + }) self.assertEqual(host.filesystem.read_binary_file( '/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt'), 'result A') - self.assertEqual(baseline_optimizer._files_to_delete, [ + self.assertEqual(baseline_optimizer.files_to_delete, [ '/mock-checkout/third_party/WebKit/LayoutTests/platform/win/another/test-expected.txt', ]) - self.assertEqual(baseline_optimizer._files_to_add, [ + self.assertEqual(baseline_optimizer.files_to_add, [ '/mock-checkout/third_party/WebKit/LayoutTests/another/test-expected.txt', '/mock-checkout/third_party/WebKit/LayoutTests/platform/linux/another/test-expected.txt', ]) - def _assertOptimization(self, results_by_directory, expected_new_results_by_directory, - baseline_dirname='', expected_files_to_delete=None, host=None): + def _assert_optimization(self, dir_to_results, dir_to_expected_new_results, + baseline_dirname='', expected_files_to_delete=None, host=None): if not host: host = MockHost() fs = host.filesystem @@ -124,7 +130,7 @@ fs.write_text_file(fs.join(webkit_base, 'LayoutTests', 'VirtualTestSuites'), '[{"prefix": "gpu", "base": "fast/canvas", "args": ["--foo"]}]') - for dirname, contents in results_by_directory.items(): + for dirname, contents in dir_to_results.items(): path = fs.join(webkit_base, 'LayoutTests', dirname, baseline_name) fs.write_binary_file(path, contents) @@ -132,167 +138,200 @@ ), host.port_factory.all_port_names(), skip_scm_commands=expected_files_to_delete is not None) self.assertTrue(baseline_optimizer.optimize(fs.join(baseline_dirname, baseline_name))) - for dirname, contents in expected_new_results_by_directory.items(): + for dirname, contents in dir_to_expected_new_results.items(): path = fs.join(webkit_base, 'LayoutTests', dirname, baseline_name) if contents is None: - self.assertTrue(not fs.exists(path) or path in baseline_optimizer._files_to_delete) + self.assertTrue(not fs.exists(path) or path in baseline_optimizer.files_to_delete) else: self.assertEqual(fs.read_binary_file(path), contents) # Check that the files that were in the original set have been deleted where necessary. - for dirname in results_by_directory: + for dirname in dir_to_results: path = fs.join(webkit_base, 'LayoutTests', dirname, baseline_name) - if not dirname in expected_new_results_by_directory: - self.assertTrue(not fs.exists(path) or path in baseline_optimizer._files_to_delete) + if dirname not in dir_to_expected_new_results: + self.assertTrue(not fs.exists(path) or path in baseline_optimizer.files_to_delete) if expected_files_to_delete: - self.assertEqual(sorted(baseline_optimizer._files_to_delete), sorted(expected_files_to_delete)) + self.assertEqual(sorted(baseline_optimizer.files_to_delete), sorted(expected_files_to_delete)) def test_linux_redundant_with_win(self): - self._assertOptimization({ - 'platform/win': '1', - 'platform/linux': '1', - }, { - 'platform/win': '1', - }) + self._assert_optimization( + { + 'platform/win': '1', + 'platform/linux': '1', + }, + { + 'platform/win': '1', + }) def test_covers_mac_win_linux(self): - self._assertOptimization({ - 'platform/mac': '1', - 'platform/win': '1', - 'platform/linux': '1', - '': None, - }, { - '': '1', - }) + self._assert_optimization( + { + 'platform/mac': '1', + 'platform/win': '1', + 'platform/linux': '1', + '': None, + }, + { + '': '1', + }) def test_overwrites_root(self): - self._assertOptimization({ - 'platform/mac': '1', - 'platform/win': '1', - 'platform/linux': '1', - '': '2', - }, { - '': '1', - }) + self._assert_optimization( + { + 'platform/mac': '1', + 'platform/win': '1', + 'platform/linux': '1', + '': '2', + }, + { + '': '1', + }) def test_no_new_common_directory(self): - self._assertOptimization({ - 'platform/mac': '1', - 'platform/linux': '1', - '': '2', - }, { - 'platform/mac': '1', - 'platform/linux': '1', - '': '2', - }) + self._assert_optimization( + { + 'platform/mac': '1', + 'platform/linux': '1', + '': '2', + }, + { + 'platform/mac': '1', + 'platform/linux': '1', + '': '2', + }) def test_local_optimization(self): - self._assertOptimization({ - 'platform/mac': '1', - 'platform/linux': '1', - 'platform/linux-precise': '1', - }, { - 'platform/mac': '1', - 'platform/linux': '1', - }) + self._assert_optimization( + { + 'platform/mac': '1', + 'platform/linux': '1', + 'platform/linux-precise': '1', + }, + { + 'platform/mac': '1', + 'platform/linux': '1', + }) def test_local_optimization_skipping_a_port_in_the_middle(self): - self._assertOptimization({ - 'platform/mac-snowleopard': '1', - 'platform/win': '1', - 'platform/linux': '1', - 'platform/linux-precise': '1', - }, { - 'platform/mac-snowleopard': '1', - 'platform/win': '1', - }) + self._assert_optimization( + { + 'platform/mac-snowleopard': '1', + 'platform/win': '1', + 'platform/linux': '1', + 'platform/linux-precise': '1', + }, + { + 'platform/mac-snowleopard': '1', + 'platform/win': '1', + }) def test_baseline_redundant_with_root(self): - self._assertOptimization({ - 'platform/mac': '1', - 'platform/win': '2', - '': '2', - }, { - 'platform/mac': '1', - '': '2', - }) + self._assert_optimization( + { + 'platform/mac': '1', + 'platform/win': '2', + '': '2', + }, + { + 'platform/mac': '1', + '': '2', + }) def test_root_baseline_unused(self): - self._assertOptimization({ - 'platform/mac': '1', - 'platform/win': '2', - '': '3', - }, { - 'platform/mac': '1', - 'platform/win': '2', - }) + self._assert_optimization( + { + 'platform/mac': '1', + 'platform/win': '2', + '': '3', + }, + { + 'platform/mac': '1', + 'platform/win': '2', + }) def test_root_baseline_unused_and_non_existant(self): - self._assertOptimization({ - 'platform/mac': '1', - 'platform/win': '2', - }, { - 'platform/mac': '1', - 'platform/win': '2', - }) + self._assert_optimization( + { + 'platform/mac': '1', + 'platform/win': '2', + }, + { + 'platform/mac': '1', + 'platform/win': '2', + }) def test_virtual_root_redundant_with_actual_root(self): - self._assertOptimization({ - 'virtual/gpu/fast/canvas': '2', - 'fast/canvas': '2', - }, { - 'virtual/gpu/fast/canvas': None, - 'fast/canvas': '2', - }, baseline_dirname='virtual/gpu/fast/canvas') + self._assert_optimization( + { + 'virtual/gpu/fast/canvas': '2', + 'fast/canvas': '2', + }, + { + 'virtual/gpu/fast/canvas': None, + 'fast/canvas': '2', + }, + baseline_dirname='virtual/gpu/fast/canvas') def test_virtual_root_redundant_with_ancestors(self): - self._assertOptimization({ - 'virtual/gpu/fast/canvas': '2', - 'platform/mac/fast/canvas': '2', - 'platform/win/fast/canvas': '2', - }, { - 'virtual/gpu/fast/canvas': None, - 'fast/canvas': '2', - }, baseline_dirname='virtual/gpu/fast/canvas') + self._assert_optimization( + { + 'virtual/gpu/fast/canvas': '2', + 'platform/mac/fast/canvas': '2', + 'platform/win/fast/canvas': '2', + }, + { + 'virtual/gpu/fast/canvas': None, + 'fast/canvas': '2', + }, + baseline_dirname='virtual/gpu/fast/canvas') def test_virtual_root_redundant_with_ancestors_skip_scm_commands(self): - self._assertOptimization({ - 'virtual/gpu/fast/canvas': '2', - 'platform/mac/fast/canvas': '2', - 'platform/win/fast/canvas': '2', - }, { - 'virtual/gpu/fast/canvas': None, - 'fast/canvas': '2', - }, + self._assert_optimization( + { + 'virtual/gpu/fast/canvas': '2', + 'platform/mac/fast/canvas': '2', + 'platform/win/fast/canvas': '2', + }, + { + 'virtual/gpu/fast/canvas': None, + 'fast/canvas': '2', + }, baseline_dirname='virtual/gpu/fast/canvas', expected_files_to_delete=[ - '/mock-checkout/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/mock-baseline-expected.txt', - '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/mock-baseline-expected.txt', - '/mock-checkout/third_party/WebKit/LayoutTests/platform/win/fast/canvas/mock-baseline-expected.txt', - ]) + '/mock-checkout/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/mock-baseline-expected.txt', + '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/mock-baseline-expected.txt', + '/mock-checkout/third_party/WebKit/LayoutTests/platform/win/fast/canvas/mock-baseline-expected.txt', + ]) def test_virtual_root_redundant_with_ancestors_skip_scm_commands_with_file_not_in_scm(self): - self._assertOptimization({ - 'virtual/gpu/fast/canvas': '2', - 'platform/mac/fast/canvas': '2', - 'platform/win/fast/canvas': '2', - }, { - 'virtual/gpu/fast/canvas': None, - 'fast/canvas': '2', - }, + self._assert_optimization( + { + 'virtual/gpu/fast/canvas': '2', + 'platform/mac/fast/canvas': '2', + 'platform/win/fast/canvas': '2', + }, + { + 'virtual/gpu/fast/canvas': None, + 'fast/canvas': '2', + }, baseline_dirname='virtual/gpu/fast/canvas', expected_files_to_delete=[ - '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/mock-baseline-expected.txt', - '/mock-checkout/third_party/WebKit/LayoutTests/platform/win/fast/canvas/mock-baseline-expected.txt', - ], - host=MockHost(scm=ExcludingMockSCM(['/mock-checkout/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/mock-baseline-expected.txt']))) + '/mock-checkout/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/mock-baseline-expected.txt', + '/mock-checkout/third_party/WebKit/LayoutTests/platform/win/fast/canvas/mock-baseline-expected.txt', + ], + host=MockHost(scm=ExcludingMockSCM([ + '/mock-checkout/third_party/WebKit/LayoutTests/virtual/gpu/fast/canvas/mock-baseline-expected.txt' + ]))) def test_virtual_root_not_redundant_with_ancestors(self): - self._assertOptimization({ - 'virtual/gpu/fast/canvas': '2', - 'platform/mac/fast/canvas': '1', - }, { - 'virtual/gpu/fast/canvas': '2', - 'platform/mac/fast/canvas': '1', - }, baseline_dirname='virtual/gpu/fast/canvas') + self._assert_optimization( + { + 'virtual/gpu/fast/canvas': '2', + 'platform/mac/fast/canvas': '1', + }, + { + 'virtual/gpu/fast/canvas': '2', + 'platform/mac/fast/canvas': '1', + }, + baseline_dirname='virtual/gpu/fast/canvas')
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/diff_parser.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/diff_parser.py index 08fafb2d..ea9efb2 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/diff_parser.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/diff_parser.py
@@ -31,15 +31,17 @@ import logging import re + _log = logging.getLogger(__name__) + conversion_patterns = ( - (re.compile("^diff --git \w/(.+) \w/(?P<FilePath>.+)"), lambda matched: "Index: " + matched.group('FilePath') + "\n"), - (re.compile("^new file.*"), lambda matched: "\n"), - (re.compile("^index (([0-9a-f]{7}\.\.[0-9a-f]{7})|([0-9a-f]{40}\.\.[0-9a-f]{40})) [0-9]{6}"), + (re.compile(r"^diff --git \w/(.+) \w/(?P<FilePath>.+)"), lambda matched: "Index: " + matched.group('FilePath') + "\n"), + (re.compile(r"^new file.*"), lambda matched: "\n"), + (re.compile(r"^index (([0-9a-f]{7}\.\.[0-9a-f]{7})|([0-9a-f]{40}\.\.[0-9a-f]{40})) [0-9]{6}"), lambda matched: ("=" * 67) + "\n"), - (re.compile("^--- \w/(?P<FilePath>.+)"), lambda matched: "--- " + matched.group('FilePath') + "\n"), - (re.compile("^\+\+\+ \w/(?P<FilePath>.+)"), lambda matched: "+++ " + matched.group('FilePath') + "\n"), + (re.compile(r"^--- \w/(?P<FilePath>.+)"), lambda matched: "--- " + matched.group('FilePath') + "\n"), + (re.compile(r"^\+\+\+ \w/(?P<FilePath>.+)"), lambda matched: "+++ " + matched.group('FilePath') + "\n"), ) index_pattern = re.compile(r"^Index: (?P<FilePath>.+)")
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/diff_parser_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/diff_parser_unittest.py index a007913..3e37525 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/diff_parser_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/diff_parser_unittest.py
@@ -27,10 +27,11 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import cStringIO as StringIO -import diff_parser + import re import unittest +from webkitpy.common.checkout import diff_parser from webkitpy.common.checkout.diff_test_data import DIFF_TEST_DATA @@ -105,7 +106,8 @@ self.assertEqual(diff_parser.get_diff_converter(revision_lines + svn_diff_lines), diff_parser.svn_diff_to_svn_diff) git_diff_lines = [ - "diff --git a/Tools/Scripts/webkitpy/common/checkout/diff_parser.py b/Tools/Scripts/webkitpy/common/checkout/diff_parser.py\n", + ("diff --git a/Tools/Scripts/webkitpy/common/checkout/diff_parser.py " + "b/Tools/Scripts/webkitpy/common/checkout/diff_parser.py\n"), "index 3c5b45b..0197ead 100644\n", "--- a/Tools/Scripts/webkitpy/common/checkout/diff_parser.py\n", "+++ b/Tools/Scripts/webkitpy/common/checkout/diff_parser.py\n", @@ -115,8 +117,8 @@ self.assertEqual(diff_parser.get_diff_converter(comment_lines + git_diff_lines), diff_parser.git_diff_to_svn_diff) self.assertEqual(diff_parser.get_diff_converter(revision_lines + git_diff_lines), diff_parser.git_diff_to_svn_diff) - def test_git_mnemonicprefix(self): - p = re.compile(r' ([a|b])/') + def test_git_mnemonic_prefix(self): + pattern = re.compile(r' ([a|b])/') prefixes = [ {'a': 'i', 'b': 'w'}, # git-diff (compares the (i)ndex and the (w)ork tree) @@ -126,9 +128,11 @@ {'a': '1', 'b': '2'}, # git diff --no-index a b (compares two non-git things (1) and (2)) ] + def patch(prefix): + return pattern.sub(lambda match: " %s/" % prefix[match.group(1)], DIFF_TEST_DATA) + for prefix in prefixes: - patch = p.sub(lambda x: " %s/" % prefix[x.group(1)], DIFF_TEST_DATA) - self.test_diff_parser(diff_parser.DiffParser(patch.splitlines())) + self.test_diff_parser(diff_parser.DiffParser(patch(prefix).splitlines())) def test_git_diff_to_svn_diff(self): output = """\
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git.py index 87e4053..28d7b0bd 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/git.py
@@ -31,7 +31,6 @@ import logging import re -import webkitpy.common.config from webkitpy.common.checkout.scm.scm import SCM from webkitpy.common.memoized import memoized from webkitpy.common.system.executive import Executive, ScriptError @@ -203,7 +202,7 @@ return self._run_git(['log', '-1', '--grep=' + grep_str, '--date=iso', self.find_checkout_root(path)]) def _commit_position_from_git_log(self, git_log): - match = re.search("^\s*Cr-Commit-Position:.*@\{#(?P<commit_position>\d+)\}", git_log, re.MULTILINE) + match = re.search(r"^\s*Cr-Commit-Position:.*@\{#(?P<commit_position>\d+)\}", git_log, re.MULTILINE) if not match: return "" return int(match.group('commit_position')) @@ -217,7 +216,7 @@ def timestamp_of_revision(self, path, revision): git_log = self.most_recent_log_matching(self._commit_position_regex_for_timestamp() % revision, path) - match = re.search("^Date:\s*(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2}) ([+-])(\d{2})(\d{2})$", git_log, re.MULTILINE) + match = re.search(r"^Date:\s*(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2}) ([+-])(\d{2})(\d{2})$", git_log, re.MULTILINE) if not match: return "" @@ -285,7 +284,7 @@ def commit_locally_with_message(self, message): command = ['commit', '--all', '-F', '-'] - self._run_git(command, input=message) + self._run_git(command, input_func=message) # These methods are git specific and are meant to provide support for the Git oriented workflow # that Blink is moving towards, hence there are no equivalent methods in the SVN class. @@ -299,10 +298,10 @@ def git_commits_since(self, commit): return self._run_git(['log', commit + '..master', '--format=%H', '--reverse']).split() - def git_commit_detail(self, commit, format=None): + def git_commit_detail(self, commit, log_format=None): args = ['log', '-1', commit] - if format: - args.append('--format=' + format) + if log_format: + args.append('--format=' + log_format) return self._run_git(args) def affected_files(self, commit): @@ -311,7 +310,7 @@ def _branch_tracking_remote_master(self): origin_info = self._run_git(['remote', 'show', 'origin', '-n']) - match = re.search("^\s*(?P<branch_name>\S+)\s+merges with remote master$", origin_info, re.MULTILINE) + match = re.search(r"^\s*(?P<branch_name>\S+)\s+merges with remote master$", origin_info, re.MULTILINE) if not match: raise ScriptError(message="Unable to find local branch tracking origin/master.") branch = str(match.group("branch_name"))
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm.py index 4778916..b64ee86c 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm.py
@@ -34,14 +34,13 @@ import sys from webkitpy.common.system.executive import Executive -from webkitpy.common.system.executive import ScriptError from webkitpy.common.system.filesystem import FileSystem _log = logging.getLogger(__name__) # SCM methods are expected to return paths relative to self.checkout_root. -class SCM: +class SCM(object): def __init__(self, cwd, executive=None, filesystem=None): self.cwd = cwd @@ -50,11 +49,12 @@ self.checkout_root = self.find_checkout_root(self.cwd) # A wrapper used by subclasses to create processes. - def _run(self, args, cwd=None, input=None, error_handler=None, return_exit_code=False, return_stderr=True, decode_output=True): + def _run(self, args, cwd=None, input_func=None, error_handler=None, + return_exit_code=False, return_stderr=True, decode_output=True): # FIXME: We should set cwd appropriately. return self._executive.run_command(args, cwd=cwd, - input=input, + input_func=input_func, error_handler=error_handler, return_exit_code=return_exit_code, return_stderr=return_stderr, @@ -81,6 +81,10 @@ def _subclass_must_implement(): raise NotImplementedError("subclasses must implement") + # Most methods here are abstract methods which don't use their arguments. + # FIXME: Merge Git and SCM and remove the abstract base methods. + # pylint: disable=unused-argument + @classmethod def in_working_directory(cls, path, executive=None): SCM._subclass_must_implement()
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm_unittest.py index 77632028..13fc0c9 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/checkout/scm/scm_unittest.py
@@ -35,9 +35,7 @@ from webkitpy.common.system.filesystem import FileSystem from webkitpy.common.system.filesystem_mock import MockFileSystem from webkitpy.common.checkout.scm.detection import detect_scm_system -from webkitpy.common.checkout.scm.git import AmbiguousCommitError from webkitpy.common.checkout.scm.git import Git -from webkitpy.common.checkout.scm.scm import SCM class SCMTestBase(unittest.TestCase):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/config/builders.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/config/builders.py index 661a5ae..155f4a7 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/config/builders.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/config/builders.py
@@ -81,7 +81,7 @@ "is_try_builder": True, }, "linux_trusty_blink_rel": { - "port_name": "linux-precise", + "port_name": "linux-trusty", "specifiers": ['Trusty', 'Release'], "is_try_builder": True, }, @@ -115,5 +115,9 @@ "specifiers": ['Win10', 'Release'], "is_try_builder": True, }, - # TODO(qyearsley): Add android_blink_rel. + "android_blink_rel": { + "port_name": "android", + "specifiers": ['Android', 'Release'], + "is_try_builder": True, + }, }
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/find_files.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/find_files.py index 53680d4..50efa8a 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/find_files.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/find_files.py
@@ -41,7 +41,8 @@ If a callback is passed in, it will be called for the each file and the file will be included into the result if the callback returns True. -The callback has to take three arguments: filesystem, dirname and filename.""" +The callback has to take three arguments: filesystem, dirname and filename. +""" import itertools @@ -58,11 +59,11 @@ paths = paths or ['*'] skipped_directories = skipped_directories or set(['.svn', '_svn']) - return _normalized_find(filesystem, _normalize( + return _normalized_find(filesystem, normalize( filesystem, base_dir, paths), skipped_directories, file_filter, directory_sort_key) -def _normalize(filesystem, base_dir, paths): +def normalize(filesystem, base_dir, paths): return [filesystem.normpath(filesystem.join(base_dir, path)) for path in paths] @@ -81,6 +82,6 @@ files_list.sort(key=directory_sort_key) return files_list - all_files = itertools.chain(*(sort_by_directory_key(filesystem.files_under(path, - skipped_directories, file_filter)) for path in paths_to_walk)) + all_files = itertools.chain(*(sort_by_directory_key( + filesystem.files_under(path, skipped_directories, file_filter)) for path in paths_to_walk)) return all_files
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/find_files_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/find_files_unittest.py index 665b4556..85dfa71 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/find_files_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/find_files_unittest.py
@@ -29,8 +29,8 @@ import sys import unittest +from webkitpy.common import find_files from webkitpy.common.system.filesystem import FileSystem -import find_files class MockWinFileSystem(object): @@ -45,9 +45,10 @@ class TestWinNormalize(unittest.TestCase): def assert_filesystem_normalizes(self, filesystem): - self.assertEqual(find_files._normalize(filesystem, "c:\\foo", - ['fast/html', 'fast/canvas/*', 'compositing/foo.html']), - ['c:\\foo\\fast\html', 'c:\\foo\\fast\canvas\*', 'c:\\foo\compositing\\foo.html']) + self.assertEqual( + find_files.normalize(filesystem, "c:\\foo", + ['fast/html', 'fast/canvas/*', 'compositing/foo.html']), + ['c:\\foo\\fast\\html', 'c:\\foo\\fast\\canvas\\*', 'c:\\foo\\compositing\\foo.html']) def test_mocked_win(self): # This tests test_files.normalize, using portable behavior emulating
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/memoized.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/memoized.py index 7a9a925..7502f6ca 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/memoized.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/memoized.py
@@ -32,7 +32,8 @@ import functools -class memoized(object): +# This class has a lower-case name because it is a decorator. +class memoized(object): # pylint: disable=invalid-name def __init__(self, function): self._function = function
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/message_pool.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/message_pool.py index ab1f1a0b..db2d830 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/message_pool.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/message_pool.py
@@ -37,7 +37,6 @@ If you don't need these features, use multiprocessing.Pool or concurrency.futures instead. - """ import cPickle @@ -311,8 +310,8 @@ # The unix multiprocessing implementation clones any log handlers into the child process, # so we remove them to avoid duplicate logging. - for h in self._logger.handlers: - self._logger.removeHandler(h) + for handler in self._logger.handlers: + self._logger.removeHandler(handler) self._log_handler = _WorkerLogHandler(self) self._logger.addHandler(self._log_handler)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/file_uploader.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/file_uploader.py index d12f78c..7d20043 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/file_uploader.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/file_uploader.py
@@ -50,12 +50,12 @@ Source: http://code.google.com/p/rietveld/source/browse/trunk/upload.py """ - BOUNDARY = '-M-A-G-I-C---B-O-U-N-D-A-R-Y-' + boundary = '-M-A-G-I-C---B-O-U-N-D-A-R-Y-' CRLF = '\r\n' lines = [] for key, value in fields: - lines.append('--' + BOUNDARY) + lines.append('--' + boundary) lines.append('Content-Disposition: form-data; name="%s"' % key) lines.append('') if isinstance(value, unicode): @@ -63,7 +63,7 @@ lines.append(value) for key, filename, value in files: - lines.append('--' + BOUNDARY) + lines.append('--' + boundary) lines.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename)) lines.append('Content-Type: %s' % get_mime_type(filename)) lines.append('') @@ -71,10 +71,10 @@ value = value.encode('utf-8') lines.append(value) - lines.append('--' + BOUNDARY + '--') + lines.append('--' + boundary + '--') lines.append('') body = CRLF.join(lines) - content_type = 'multipart/form-data; boundary=%s' % BOUNDARY + content_type = 'multipart/form-data; boundary=%s' % boundary return content_type, body
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/networktransaction_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/networktransaction_unittest.py index 8b696ee..fbc4f17a 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/networktransaction_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/networktransaction_unittest.py
@@ -53,7 +53,7 @@ try: transaction.run(self._raise_exception) did_throw_exception = False - except Exception as e: + except Exception as e: # pylint: disable=broad-except did_process_exception = True self.assertEqual(e, self.exception) self.assertTrue(did_throw_exception) @@ -77,7 +77,7 @@ 'WARNING: Received HTTP status 500 loading "http://example.com/". ' 'Retrying in 0.0 seconds...\n']) - def test_convert_404_to_None(self): + def test_convert_404_to_none(self): transaction = NetworkTransaction(convert_404_to_None=True) self.assertIsNone(transaction.run(self._raise_404_error))
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/rietveld.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/rietveld.py index 801d3f83..853f71b 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/rietveld.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/rietveld.py
@@ -4,7 +4,6 @@ """Utility functions to communicate with Rietveld.""" -import collections import json import logging import urllib2 @@ -49,6 +48,20 @@ return filter_latest_jobs(jobs) +def changed_files(issue_number, web): + """Lists the files included in a CL, or None if this can't be determined. + + File paths are sorted and relative to the repository root. + """ + try: + url = _latest_patchset_url(issue_number, web) + issue_data = _get_json(url, web) + return sorted(issue_data['files']) + except (urllib2.URLError, ValueError, KeyError): + _log.warning('Failed to list changed files for issue %s.', issue_number) + return None + + def _latest_patchset_url(issue_number, web): issue_data = _get_json(_issue_url(issue_number), web) latest_patchset_number = issue_data["patchsets"][-1]
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/rietveld_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/rietveld_unittest.py index 494f748..f9bae66 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/net/rietveld_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/net/rietveld_unittest.py
@@ -10,6 +10,7 @@ from webkitpy.common.net.rietveld import filter_latest_jobs from webkitpy.common.net.rietveld import get_latest_try_job_results from webkitpy.common.net.rietveld import latest_try_jobs +from webkitpy.common.net.rietveld import changed_files from webkitpy.common.net.buildbot import Build from webkitpy.common.net.web_mock import MockWeb from webkitpy.common.system.outputcapture import OutputCapture @@ -52,6 +53,10 @@ 'result': 0 }, ], + 'files': { + 'some/path/foo.cc': {'status': 'M'}, + 'some/path/bar.html': {'status': 'M'}, + } }), 'https://codereview.chromium.org/api/11113333': 'my non-JSON contents', }) @@ -110,3 +115,11 @@ self.assertEqual( filter_latest_jobs([Build('foo', 3), Build('bar')]), [Build('foo', 3)]) + + def test_changed_files(self): + self.assertEqual( + changed_files(11112222, self.web), + ['some/path/bar.html', 'some/path/foo.cc']) + + def test_changed_files_no_results(self): + self.assertIsNone(changed_files(11113333, self.web))
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/prettypatch.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/prettypatch.py index ca8e6da1..e5c24f6 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/prettypatch.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/prettypatch.py
@@ -62,4 +62,4 @@ ] # PrettyPatch does not modify the encoding of the diff output # so we can't expect it to be utf-8. - return self._executive.run_command(args, input=diff, decode_output=False) + return self._executive.run_command(args, input_func=diff, decode_output=False)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/read_checksum_from_png_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/read_checksum_from_png_unittest.py index 6b03d8b..1ba3864 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/read_checksum_from_png_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/read_checksum_from_png_unittest.py
@@ -32,12 +32,26 @@ def test_read_checksum(self): # Test a file with the comment. filehandle = StringIO.StringIO( - '''\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x03 \x00\x00\x02X\x08\x02\x00\x00\x00\x15\x14\x15'\x00\x00\x00)tEXtchecksum\x003c4134fe2739880353f91c5b84cadbaaC\xb8?\xec\x00\x00\x16\xfeIDATx\x9c\xed\xdd[\x8cU\xe5\xc1\xff\xf15T\x18\x0ea,)\xa6\x80XZ<\x10\n\xd6H\xc4V\x88}\xb5\xa9\xd6r\xd5\x0bki0\xa6\xb5ih\xd2\xde\x98PHz\xd1\x02=\\q#\x01\x8b\xa5rJ\x8b\x88i\xacM\xc5h\x8cbMk(\x1ez@!\x0c\xd5\xd2\xc2\xb44\x1c\x848\x1dF(\xeb\x7f\xb1\xff\xd9\xef~g\xd6\xde3\xe0o\x10\xec\xe7sa6{\xd6z\xd6\xb3\xd7\xf3\xa8_7\xdbM[Y\x96\x05\x00\x009\xc3\xde\xeb\t\x00\x00\xbc\xdf\x08,\x00\x800\x81\x05\x00\x10&\xb0\x00\x00\xc2\x04\x16\x00@\x98\xc0\x02\x00\x08\x13X\x00\x00a\x02\x0b\x00 Lx01\x00\x84\t,\x00\x800\x81\x05\x00\x10\xd64\xb0\xda\x9a\xdb\xb6m\xdb\xb4i\xd3\xfa\x9fr\xf3\xcd7\x0f\xe5T\x07\xe5\xd4\xa9''') + '''\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x03 \x00\x00\x02X\x08\x02\x00\x00\x00\x15\x14\x15'\x00\x00\x00)''' + '''tEXtchecksum\x003c4134fe2739880353f91c5b84cadbaaC\xb8?\xec\x00\x00\x16\xfeIDATx\x9c\xed\xdd[\x8cU\xe5\xc1\xff''' + '''\xf15T\x18\x0ea,)\xa6\x80XZ<\x10\n\xd6H\xc4V\x88}\xb5\xa9\xd6r\xd5\x0bki0\xa6\xb5ih\xd2\xde\x98PHz\xd1\x02=\\''' + '''q#\x01\x8b\xa5rJ\x8b\x88i\xacM\xc5h\x8cbMk(\x1ez@!\x0c\xd5\xd2\xc2\xb44\x1c\x848\x1dF(\xeb\x7f\xb1\xff\xd9\xef''' + '''~g\xd6\xde3\xe0o\x10\xec\xe7sa6{\xd6z\xd6\xb3\xd7\xf3\xa8_7\xdbM[Y\x96\x05\x00\x009\xc3\xde\xeb\t\x00\x00\xbc''' + '''\xdf\x08,\x00\x800\x81\x05\x00\x10&\xb0\x00\x00\xc2\x04\x16\x00@\x98\xc0\x02\x00\x08\x13X\x00\x00a\x02\x0b\x00''' + '''Lx01\x00\x84\t,\x00\x800\x81\x05\x00\x10\xd64\xb0\xda\x9a\xdb\xb6m\xdb\xb4i\xd3\xfa\x9fr\xf3\xcd7\x0f\xe5T\x07''' + '''\xe5\xd4\xa9''') checksum = read_checksum_from_png.read_checksum(filehandle) self.assertEqual('3c4134fe2739880353f91c5b84cadbaa', checksum) # Test a file without the comment. filehandle = StringIO.StringIO( - '''\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x03 \x00\x00\x02X\x08\x02\x00\x00\x00\x15\x14\x15'\x00\x00\x16\xfeIDATx\x9c\xed\xdd[\x8cU\xe5\xc1\xff\xf15T\x18\x0ea,)\xa6\x80XZ<\x10\n\xd6H\xc4V\x88}\xb5\xa9\xd6r\xd5\x0bki0\xa6\xb5ih\xd2\xde\x98PHz\xd1\x02=\\q#\x01\x8b\xa5rJ\x8b\x88i\xacM\xc5h\x8cbMk(\x1ez@!\x0c\xd5\xd2\xc2\xb44\x1c\x848\x1dF(\xeb\x7f\xb1\xff\xd9\xef~g\xd6\xde3\xe0o\x10\xec\xe7sa6{\xd6z\xd6\xb3\xd7\xf3\xa8_7\xdbM[Y\x96\x05\x00\x009\xc3\xde\xeb\t\x00\x00\xbc\xdf\x08,\x00\x800\x81\x05\x00\x10&\xb0\x00\x00\xc2\x04\x16\x00@\x98\xc0\x02\x00\x08\x13X\x00\x00a\x02\x0b\x00 Lx01\x00\x84\t,\x00\x800\x81\x05\x00\x10\xd64\xb0\xda\x9a\xdb\xb6m\xdb\xb4i\xd3\xfa\x9fr\xf3\xcd7\x0f\xe5T\x07\xe5\xd4\xa9S\x8b\x17/\x1e?~\xfc\xf8\xf1\xe3\xef\xbf\xff\xfe\xf7z:M5\xbb\x87\x17\xcbUZ\x8f|V\xd7\xbd\x10\xb6\xcd{b\x88\xf6j\xb3\x9b?\x14\x9b\xa1>\xe6\xf9\xd9\xcf\x00\x17\x93''') + '''\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x03 \x00\x00\x02X\x08\x02\x00\x00\x00\x15\x14\x15'\x00\x00\x16\xfe''' + '''IDATx\x9c\xed\xdd[\x8cU\xe5\xc1\xff\xf15T\x18\x0ea,)\xa6\x80XZ<\x10\n\xd6H\xc4V\x88}\xb5\xa9\xd6r\xd5\x0bki0''' + '''\xa6\xb5ih\xd2\xde\x98PHz\xd1\x02=\\q#\x01\x8b\xa5rJ\x8b\x88i\xacM\xc5h\x8cbMk(\x1ez@!\x0c\xd5\xd2\xc2\xb44''' + '''\x1c\x848\x1dF(\xeb\x7f\xb1\xff\xd9\xef~g\xd6\xde3\xe0o\x10\xec\xe7sa6{\xd6z\xd6\xb3\xd7\xf3\xa8_7\xdbM[Y\x96''' + '''\x05\x00\x009\xc3\xde\xeb\t\x00\x00\xbc\xdf\x08,\x00\x800\x81\x05\x00\x10&\xb0\x00\x00\xc2\x04\x16\x00@\x98''' + '''\xc0\x02\x00\x08\x13X\x00\x00a\x02\x0b\x00 Lx01\x00\x84\t,\x00\x800\x81\x05\x00\x10\xd64\xb0\xda\x9a\xdb\xb6m''' + '''\xdb\xb4i\xd3\xfa\x9fr\xf3\xcd7\x0f\xe5T\x07\xe5\xd4\xa9S\x8b\x17/\x1e?~\xfc\xf8\xf1\xe3\xef\xbf\xff\xfe\xf7z''' + ''':M5\xbb\x87\x17\xcbUZ\x8f|V\xd7\xbd\x10\xb6\xcd{b\x88\xf6j\xb3\x9b?\x14\x9b\xa1>\xe6\xf9\xd9\xcf\x00\x17\x93''') checksum = read_checksum_from_png.read_checksum(filehandle) self.assertIsNone(checksum)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/crashlogs_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/crashlogs_unittest.py index 8a0b2c46..510920b 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/crashlogs_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/crashlogs_unittest.py
@@ -29,6 +29,7 @@ from webkitpy.common.system.systemhost_mock import MockSystemHost +# pylint: disable=line-too-long def make_mock_crash_report_darwin(process_name, pid): return """Process: {process_name} [{pid}] Path: /Volumes/Data/slave/snowleopard-intel-release-tests/build/WebKitBuild/Release/{process_name} @@ -66,6 +67,7 @@ PCI Card: NVIDIA GeForce GT 120, sppci_displaycontroller, MXM-Slot Serial ATA Device: OPTIARC DVD RW AD-5670S """.format(process_name=process_name, pid=pid) +# pylint: enable=line-too-long class CrashLogsTest(unittest.TestCase): @@ -81,12 +83,14 @@ misformatted_mock_crash_report = 'Junk that should not appear in a crash report' + \ make_mock_crash_report_darwin('DumpRenderTree', 28526)[200:] files = {} + # pylint: disable=line-too-long files['/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150718_quadzen.crash'] = older_mock_crash_report files['/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150719_quadzen.crash'] = mock_crash_report files['/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150720_quadzen.crash'] = newer_mock_crash_report files['/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150721_quadzen.crash'] = None - files['/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150722_quadzen.crash'] = other_process_mock_crash_report # noqa - files['/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150723_quadzen.crash'] = misformatted_mock_crash_report # noqa + files['/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150722_quadzen.crash'] = other_process_mock_crash_report + files['/Users/mock/Library/Logs/DiagnosticReports/DumpRenderTree_2011-06-13-150723_quadzen.crash'] = misformatted_mock_crash_report + # pylint: enable=line-too-long filesystem = MockFileSystem(files) crash_logs = CrashLogs(MockSystemHost(filesystem=filesystem)) log = crash_logs.find_newest_log("DumpRenderTree") @@ -100,10 +104,10 @@ log = crash_logs.find_newest_log("DumpRenderTree", newer_than=1.0) self.assertIsNone(log) - def bad_read(path): + def bad_read(_): raise IOError('IOError: No such file or directory') - def bad_mtime(path): + def bad_mtime(_): raise OSError('OSError: No such file or directory') filesystem.read_text_file = bad_read
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive.py index eb63764b..8755845 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive.py
@@ -37,7 +37,6 @@ import sys import time -from webkitpy.common.system.outputtee import Tee from webkitpy.common.system.filesystem import FileSystem @@ -168,6 +167,7 @@ # we import it here instead. See https://bugs.webkit.org/show_bug.cgi?id=91682 import ctypes + # pylint: disable=invalid-name class PROCESSENTRY32(ctypes.Structure): _fields_ = [("dwSize", ctypes.c_ulong), ("cntUsage", ctypes.c_ulong), @@ -187,7 +187,7 @@ TH32CS_SNAPPROCESS = 0x00000002 # win32 magic number hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) pe32 = PROCESSENTRY32() - pe32.dwSize = ctypes.sizeof(PROCESSENTRY32) + pe32.dwSize = ctypes.sizeof(PROCESSENTRY32) # pylint: disable=attribute-defined-outside-init result = False if not Process32First(hProcessSnap, ctypes.byref(pe32)): _log.debug("Failed getting first process.") @@ -311,24 +311,24 @@ def ignore_error(error): pass - def _compute_stdin(self, input): + def _compute_stdin(self, input_obj): """Returns (stdin, string_to_communicate)""" # FIXME: We should be returning /dev/null for stdin # or closing stdin after process creation to prevent # child processes from getting input from the user. - if not input: + if not input_obj: return (None, None) - if hasattr(input, "read"): # Check if the input is a file. - return (input, None) # Assume the file is in the right encoding. + if hasattr(input_obj, "read"): # Check if the input_obj is a file. + return (input_obj, None) # Assume the file is in the right encoding. # Popen in Python 2.5 and before does not automatically encode unicode objects. # http://bugs.python.org/issue5290 # See https://bugs.webkit.org/show_bug.cgi?id=37528 # for an example of a regression caused by passing a unicode string directly. # FIXME: We may need to encode differently on different platforms. - if isinstance(input, unicode): - input = input.encode(self._child_process_encoding()) - return (self.PIPE, input) + if isinstance(input_obj, unicode): + input_obj = input_obj.encode(self._child_process_encoding()) + return (self.PIPE, input_obj) def command_for_printing(self, args): """Returns a print-ready string representing command args. @@ -347,7 +347,7 @@ args, cwd=None, env=None, - input=None, + input_func=None, error_handler=None, return_exit_code=False, return_stderr=True, @@ -356,7 +356,7 @@ assert isinstance(args, list) or isinstance(args, tuple) start_time = time.time() - stdin, string_to_communicate = self._compute_stdin(input) + stdin, string_to_communicate = self._compute_stdin(input_func) stderr = self.STDOUT if return_stderr else None process = self.popen(args,
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive_mock.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive_mock.py index ea83b92..c87ce68 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive_mock.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive_mock.py
@@ -94,7 +94,7 @@ def run_command(self, args, cwd=None, - input=None, + input_func=None, error_handler=None, return_exit_code=False, return_stderr=True, @@ -110,8 +110,8 @@ if env: env_string = ", env=%s" % env input_string = "" - if input: - input_string = ", input=%s" % input + if input_func: + input_string = ", input=%s" % input_func _log.info("MOCK run_command: %s, cwd=%s%s%s", args, cwd, env_string, input_string) output = "MOCK output of child process" @@ -190,7 +190,7 @@ def run_command(self, args, cwd=None, - input=None, + input_func=None, error_handler=None, return_exit_code=False, return_stderr=True,
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive_unittest.py index 098c739..a2bb714 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/executive_unittest.py
@@ -28,18 +28,15 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os -import errno -import signal import subprocess import sys import unittest # Since we execute this script directly as part of the unit tests, we need to ensure # that Tools/Scripts is in sys.path for the next imports to work correctly. -script_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) -if script_dir not in sys.path: - sys.path.append(script_dir) - +SCRIPT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) +if SCRIPT_DIR not in sys.path: + sys.path.append(SCRIPT_DIR) from webkitpy.common.system.executive import Executive, ScriptError from webkitpy.common.system.filesystem_mock import MockFileSystem @@ -143,7 +140,7 @@ executive = Executive() - output = executive.run_command(command_line('cat'), input=unicode_tor_input) + output = executive.run_command(command_line('cat'), input_func=unicode_tor_input) self.assertEqual(output, unicode_tor_output) output = executive.run_command(command_line('echo', unicode_tor_input)) @@ -153,7 +150,7 @@ self.assertEqual(output, encoded_tor) # Make sure that str() input also works. - output = executive.run_command(command_line('cat'), input=encoded_tor, decode_output=False) + output = executive.run_command(command_line('cat'), input_func=encoded_tor, decode_output=False) self.assertEqual(output, encoded_tor) def test_kill_process(self): @@ -196,8 +193,9 @@ def main(platform, stdin, stdout, cmd, args): if platform == 'win32' and hasattr(stdout, 'fileno'): - import msvcrt - msvcrt.setmode(stdout.fileno(), os.O_BINARY) + # The module msvcrt and os.O_BINARY are not available on non-Windows. + import msvcrt # pylint: disable=import-error + msvcrt.setmode(stdout.fileno(), os.O_BINARY) # pylint: disable=no-member if cmd == '--cat': stdout.write(stdin.read()) elif cmd == '--echo':
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem.py index 9e5279b..d0c21d0 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem.py
@@ -78,7 +78,7 @@ def exists(self, path): return os.path.exists(path) - def files_under(self, path, dirs_to_skip=[], file_filter=None): + def files_under(self, path, dirs_to_skip=None, file_filter=None): """Return the list of all files under the given path in topdown order. Args: @@ -89,7 +89,9 @@ each file found. The file is included in the result if the callback returns True. """ - def filter_all(fs, dirpath, basename): + dirs_to_skip = dirs_to_skip or [] + + def filter_all(*_): return True file_filter = file_filter or filter_all @@ -160,9 +162,8 @@ def __enter__(self): return self._directory_path - def __exit__(self, type, value, traceback): + def __exit__(self, *_): # Only self-delete if necessary. - # FIXME: Should we delete non-empty directories? if os.path.exists(self._directory_path): os.rmdir(self._directory_path) @@ -189,20 +190,20 @@ def open_binary_tempfile(self, suffix): """Create, open, and return a binary temp file. Returns a tuple of the file and the name.""" temp_fd, temp_name = tempfile.mkstemp(suffix) - f = os.fdopen(temp_fd, 'wb') - return f, temp_name + fh = os.fdopen(temp_fd, 'wb') + return fh, temp_name def open_binary_file_for_reading(self, path): return codecs.open(path, 'rb') def read_binary_file(self, path): """Return the contents of the file at the given path as a byte string.""" - with file(path, 'rb') as f: - return f.read() + with file(path, 'rb') as fh: + return fh.read() def write_binary_file(self, path, contents): - with file(path, 'wb') as f: - f.write(contents) + with file(path, 'wb') as fh: + fh.write(contents) def open_text_file_for_reading(self, path): # Note: There appears to be an issue with the returned file objects
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem_mock.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem_mock.py index a9d8141..5a30779 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem_mock.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem_mock.py
@@ -32,8 +32,6 @@ import os import re -from webkitpy.common.system import path - class MockFileSystem(object): sep = '/' @@ -126,8 +124,10 @@ def exists(self, path): return self.isfile(path) or self.isdir(path) - def files_under(self, path, dirs_to_skip=[], file_filter=None): - def filter_all(fs, dirpath, basename): + def files_under(self, path, dirs_to_skip=None, file_filter=None): + dirs_to_skip = dirs_to_skip or [] + + def filter_all(*_): return True file_filter = file_filter or filter_all @@ -215,21 +215,21 @@ if not top.endswith(sep): top += sep - dirs = [] + directories = [] files = [] for f in self.files: if self.exists(f) and f.startswith(top): remaining = f[len(top):] if sep in remaining: - dir = remaining[:remaining.index(sep)] - if not dir in dirs: - dirs.append(dir) + directory = remaining[:remaining.index(sep)] + if directory not in directories: + directories.append(directory) else: files.append(remaining) - file_system_tuples = [(top[:-1], dirs, files)] - for dir in dirs: - dir = top + dir - tuples_from_subdirs = self.walk(dir) + file_system_tuples = [(top[:-1], directories, files)] + for directory in directories: + directory = top + directory + tuples_from_subdirs = self.walk(directory) file_system_tuples += tuples_from_subdirs return file_system_tuples @@ -238,12 +238,12 @@ return 0 self._raise_not_found(path) - def _mktemp(self, suffix='', prefix='tmp', dir=None, **kwargs): - if dir is None: - dir = self.sep + '__im_tmp' + def _mktemp(self, suffix='', prefix='tmp', directory=None, **_): + if directory is None: + directory = self.sep + '__im_tmp' curno = self.current_tmpno self.current_tmpno += 1 - self.last_tmpdir = self.join(dir, '%s_%u_%s' % (prefix, curno, suffix)) + self.last_tmpdir = self.join(directory, '%s_%u_%s' % (prefix, curno, suffix)) return self.last_tmpdir def mkdtemp(self, **kwargs): @@ -261,7 +261,7 @@ def __enter__(self): return self._directory_path - def __exit__(self, type, value, traceback): + def __exit__(self, *_): # Only self-delete if necessary. # FIXME: Should we delete non-empty directories? @@ -398,7 +398,7 @@ if f == path or f.startswith(path + self.sep): self.files[f] = None - self.dirs = set(filter(lambda d: not (d == path or d.startswith(path + self.sep)), self.dirs)) + self.dirs = {d for d in self.dirs if not (d == path or d.startswith(path + self.sep))} def copytree(self, source, destination): source = self.normpath(source) @@ -434,21 +434,21 @@ def __enter__(self): return self - def __exit__(self, type, value, traceback): + def __exit__(self, *_): self.close() def close(self): self.closed = True - def write(self, str): - self.fs.files[self.path] += str + def write(self, string): + self.fs.files[self.path] += string self.fs.written_files[self.path] = self.fs.files[self.path] class WritableTextFileObject(WritableBinaryFileObject): - def write(self, str): - WritableBinaryFileObject.write(self, str.encode('utf-8')) + def write(self, string): + WritableBinaryFileObject.write(self, string.encode('utf-8')) class ReadableBinaryFileObject(object): @@ -463,17 +463,17 @@ def __enter__(self): return self - def __exit__(self, type, value, traceback): + def __exit__(self, *_): self.close() def close(self): self.closed = True - def read(self, bytes=None): - if not bytes: + def read(self, num_bytes=None): + if not num_bytes: return self.data[self.offset:] start = self.offset - self.offset += bytes + self.offset += num_bytes return self.data[start:self.offset] @@ -486,8 +486,8 @@ self.data.close() super(ReadableTextFileObject, self).close() - def read(self, bytes=-1): - return self.data.read(bytes) + def read(self, num_bytes=-1): + return self.data.read(num_bytes) def readline(self, length=None): return self.data.readline(length)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem_unittest.py index 7495623..8455a903 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/filesystem_unittest.py
@@ -261,13 +261,13 @@ unicode_text_string = u'\u016An\u012Dc\u014Dde\u033D' try: text_path = tempfile.mktemp(prefix='tree_unittest_') - file = fs.open_text_file_for_writing(text_path) - file.write(unicode_text_string) - file.close() + out_file = fs.open_text_file_for_writing(text_path) + out_file.write(unicode_text_string) + out_file.close() - file = fs.open_text_file_for_reading(text_path) - read_text = file.read() - file.close() + in_file = fs.open_text_file_for_reading(text_path) + read_text = in_file.read() + in_file.close() self.assertEqual(read_text, unicode_text_string) finally: @@ -312,7 +312,7 @@ RealFileSystemTest._remove_failures -= 1 if RealFileSystemTest._remove_failures >= 0: try: - raise WindowsError + raise WindowsError # pylint: disable=undefined-variable except NameError: raise FileSystem._WindowsError
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/logutils_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/logutils_unittest.py index 35722e8..0727e8d0 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/logutils_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/logutils_unittest.py
@@ -26,13 +26,11 @@ import os import unittest -from webkitpy.common.system.logtesting import LogTesting from webkitpy.common.system.logtesting import TestLogStream from webkitpy.common.system import logutils class GetLoggerTest(unittest.TestCase): - """Tests get_logger().""" def test_get_logger_in_webkitpy(self): @@ -56,7 +54,6 @@ class ConfigureLoggingTestBase(unittest.TestCase): - """Base class for configure_logging() unit tests.""" def _logging_level(self): @@ -87,7 +84,6 @@ This method ensures that the logging configuration set up for a unit test does not affect logging in other unit tests. - """ logger = self._log for handler in self._handlers: @@ -99,7 +95,6 @@ class ConfigureLoggingTest(ConfigureLoggingTestBase): - """Tests configure_logging() with the default logging level.""" def _logging_level(self): @@ -124,8 +119,7 @@ def test_two_messages(self): self._log.info("message1") self._log.info("message2") - self._assert_log_messages(["message1\n", - "message2\n"]) + self._assert_log_messages(["message1\n", "message2\n"]) class ConfigureLoggingVerboseTest(ConfigureLoggingTestBase): @@ -143,7 +137,6 @@ class ConfigureLoggingCustomLevelTest(ConfigureLoggingTestBase): - """Tests configure_logging() with a custom logging level.""" _level = 36
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/outputcapture.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/outputcapture.py index f08fc961..d6cfb72 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/outputcapture.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/outputcapture.py
@@ -79,8 +79,10 @@ delattr(self, '_logs') return (self._restore_output_with_name("stdout"), self._restore_output_with_name("stderr"), logs_string) - def assert_outputs(self, testcase, function, args=[], kwargs={}, expected_stdout="", + def assert_outputs(self, testcase, function, args=None, kwargs=None, expected_stdout="", expected_stderr="", expected_exception=None, expected_logs=None): + args = args or [] + kwargs = kwargs or {} self.capture_output() try: if expected_exception: @@ -101,24 +103,3 @@ testassert(logs_string, expected_logs) # This is a little strange, but I don't know where else to return this information. return return_value - - -class OutputCaptureTestCaseBase(unittest.TestCase): - maxDiff = None - - def setUp(self): - unittest.TestCase.setUp(self) - self.output_capture = OutputCapture() - (self.__captured_stdout, self.__captured_stderr) = self.output_capture.capture_output() - - def tearDown(self): - del self.__captured_stdout - del self.__captured_stderr - self.output_capture.restore_output() - unittest.TestCase.tearDown(self) - - def assertStdout(self, expected_stdout): - self.assertEqual(expected_stdout, self.__captured_stdout.getvalue()) - - def assertStderr(self, expected_stderr): - self.assertEqual(expected_stderr, self.__captured_stderr.getvalue())
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/outputtee.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/outputtee.py index 06036fc..66720ec0 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/outputtee.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/outputtee.py
@@ -33,49 +33,12 @@ # Simple class to split output between multiple destinations -class Tee: +class Tee(object): def __init__(self, *files): self.files = files # Callers should pass an already encoded string for writing. - def write(self, bytes): - for file in self.files: - file.write(bytes) - - -class OutputTee: - - def __init__(self): - self._original_stdout = None - self._original_stderr = None - self._files_for_output = [] - - def add_log(self, path): - log_file = self._open_log_file(path) - self._files_for_output.append(log_file) - self._tee_outputs_to_files(self._files_for_output) - return log_file - - def remove_log(self, log_file): - self._files_for_output.remove(log_file) - self._tee_outputs_to_files(self._files_for_output) - log_file.close() - - @staticmethod - def _open_log_file(log_path): - log_directory, _ = os.path.split(log_path) - if log_directory and not os.path.exists(log_directory): - os.makedirs(log_directory) - return codecs.open(log_path, "a+", "utf-8") - - def _tee_outputs_to_files(self, files): - if not self._original_stdout: - self._original_stdout = sys.stdout - self._original_stderr = sys.stderr - if files and len(files): - sys.stdout = Tee(self._original_stdout, *files) - sys.stderr = Tee(self._original_stderr, *files) - else: - sys.stdout = self._original_stdout - sys.stderr = self._original_stderr + def write(self, bytes_to_write): + for fh in self.files: + fh.write(bytes_to_write)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/outputtee_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/outputtee_unittest.py index 75c84a0..5a1077d 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/outputtee_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/outputtee_unittest.py
@@ -29,7 +29,6 @@ import StringIO import unittest -from webkitpy.common.system.outputtee import OutputTee from webkitpy.common.system.outputtee import Tee
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/path_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/path_unittest.py index 465c196..38094f7 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/path_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/path_unittest.py
@@ -30,7 +30,6 @@ import unittest from webkitpy.common.system.systemhost import SystemHost -from webkitpy.common.system.platforminfo import PlatformInfo from webkitpy.common.system.platforminfo_mock import MockPlatformInfo from webkitpy.common.system import path
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platforminfo.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platforminfo.py index 8136484a..4c2425b8 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platforminfo.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platforminfo.py
@@ -118,7 +118,7 @@ packed = fcntl.ioctl(sys.stderr.fileno(), termios.TIOCGWINSZ, '\0' * 8) _, columns, _, _ = struct.unpack('HHHH', packed) return columns - except: + except Exception: # pylint: disable=broad-except return sys.maxsize def linux_distribution(self):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platforminfo_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platforminfo_unittest.py index 4627afc..592c007 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platforminfo_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/platforminfo_unittest.py
@@ -31,7 +31,6 @@ import unittest from webkitpy.common.system.executive import Executive -from webkitpy.common.system.executive_mock import MockExecutive from webkitpy.common.system.executive_mock import MockExecutive2 from webkitpy.common.system.filesystem import FileSystem from webkitpy.common.system.filesystem_mock import MockFileSystem @@ -179,8 +178,8 @@ self.assertEqual(self.make_info(fake_sys('cygwin'), executive=fake_executive('6.0.1234')).os_version, 'vista') self.assertEqual(self.make_info(fake_sys('cygwin'), executive=fake_executive('5.1.1234')).os_version, 'xp') - def _assert_file_implies_linux_distribution(self, file, distribution): - info = self.make_info(sys_module=fake_sys('linux2'), filesystem_module=MockFileSystem({file: ''})) + def _assert_file_implies_linux_distribution(self, filename, distribution): + info = self.make_info(sys_module=fake_sys('linux2'), filesystem_module=MockFileSystem({filename: ''})) self.assertEqual(info.linux_distribution(), distribution) def test_linux_distro_detection(self):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/stack_utils_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/stack_utils_unittest.py index 8f6a1ff..c384275 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/stack_utils_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/stack_utils_unittest.py
@@ -29,7 +29,6 @@ import sys import unittest -from webkitpy.common.system import outputcapture from webkitpy.common.system import stack_utils @@ -68,6 +67,6 @@ try: raise ValueError - except: + except ValueError: stack_utils.log_traceback(logger, sys.exc_info()[2]) self.assertTrue(msgs)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/user.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/user.py index ed8f46e..77b4560 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/user.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/user.py
@@ -55,19 +55,19 @@ # FIXME: These are @classmethods because bugzilla.py doesn't have a Tool object (thus no User instance). @classmethod - def prompt(cls, message, repeat=1, raw_input=raw_input): + def prompt(cls, message, repeat=1, raw_input_func=raw_input): response = None while repeat and not response: repeat -= 1 - response = raw_input(message) + response = raw_input_func(message) return response @classmethod def prompt_password(cls, message, repeat=1): - return cls.prompt(message, repeat=repeat, raw_input=getpass.getpass) + return cls.prompt(message, repeat=repeat, raw_input_func=getpass.getpass) @classmethod - def prompt_with_multiple_lists(cls, list_title, subtitles, lists, can_choose_multiple=False, raw_input=raw_input): + def prompt_with_multiple_lists(cls, list_title, subtitles, lists, can_choose_multiple=False, raw_input_func=raw_input): item_index = 0 cumulated_list = [] print list_title @@ -77,20 +77,20 @@ item_index += 1 print "%2d. %s" % (item_index, item) cumulated_list += lists[i] - return cls._wait_on_list_response(cumulated_list, can_choose_multiple, raw_input) + return cls._wait_on_list_response(cumulated_list, can_choose_multiple, raw_input_func) @classmethod - def _wait_on_list_response(cls, list_items, can_choose_multiple, raw_input): + def _wait_on_list_response(cls, list_items, can_choose_multiple, raw_input_func): while True: if can_choose_multiple: response = cls.prompt( - "Enter one or more numbers (comma-separated) or ranges (e.g. 3-7), or \"all\": ", raw_input=raw_input) + "Enter one or more numbers (comma-separated) or ranges (e.g. 3-7), or \"all\": ", raw_input_func=raw_input_func) if not response.strip() or response == "all": return list_items try: indices = [] - for value in re.split("\s*,\s*", response): + for value in re.split(r"\s*,\s*", response): parts = value.split('-') if len(parts) == 2: indices += range(int(parts[0]) - 1, int(parts[1])) @@ -102,19 +102,19 @@ return [list_items[i] for i in indices] else: try: - result = int(cls.prompt("Enter a number: ", raw_input=raw_input)) - 1 + result = int(cls.prompt("Enter a number: ", raw_input_func=raw_input_func)) - 1 except ValueError: continue return list_items[result] @classmethod - def prompt_with_list(cls, list_title, list_items, can_choose_multiple=False, raw_input=raw_input): + def prompt_with_list(cls, list_title, list_items, can_choose_multiple=False, raw_input_func=raw_input): print list_title i = 0 for item in list_items: i += 1 print "%2d. %s" % (i, item) - return cls._wait_on_list_response(list_items, can_choose_multiple, raw_input) + return cls._wait_on_list_response(list_items, can_choose_multiple, raw_input_func) def edit(self, files): editor = os.environ.get("EDITOR") or "vi" @@ -131,11 +131,11 @@ except IOError: pass - def confirm(self, message=None, default=DEFAULT_YES, raw_input=raw_input): + def confirm(self, message=None, default=DEFAULT_YES, raw_input_func=raw_input): if not message: message = "Continue?" choice = {'y': 'Y/n', 'n': 'y/N'}[default] - response = raw_input("%s [%s]: " % (message, choice)) + response = raw_input_func("%s [%s]: " % (message, choice)) if not response: response = default return response.lower() == 'y'
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/user_mock.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/user_mock.py index e70e130..dcd8f17 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/user_mock.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/user_mock.py
@@ -34,11 +34,11 @@ class MockUser(object): @classmethod - def prompt(cls, message, repeat=1, raw_input=raw_input): + def prompt(cls, message, repeat=1, raw_input_func=raw_input): # pylint: disable=unused-argument return "Mock user response" @classmethod - def prompt_with_list(cls, list_title, list_items, can_choose_multiple=False, raw_input=raw_input): + def prompt_with_list(cls, list_title, list_items, can_choose_multiple=False, raw_input_func=raw_input): pass def __init__(self):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/user_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/user_unittest.py index 819a478..7291292 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/user_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/user_unittest.py
@@ -36,35 +36,38 @@ example_user_response = "example user response" - def test_prompt_repeat(self): - self.repeatsRemaining = 2 + def setUp(self): + self.repeats_remaining = None - def mock_raw_input(message): - self.repeatsRemaining -= 1 - if not self.repeatsRemaining: + def test_prompt_repeat(self): + self.repeats_remaining = 2 + + def mock_raw_input(_): + self.repeats_remaining -= 1 + if not self.repeats_remaining: return UserTest.example_user_response return None - self.assertEqual(User.prompt("input", repeat=self.repeatsRemaining, - raw_input=mock_raw_input), UserTest.example_user_response) + self.assertEqual(User.prompt("input", repeat=self.repeats_remaining, + raw_input_func=mock_raw_input), UserTest.example_user_response) def test_prompt_when_exceeded_repeats(self): - self.repeatsRemaining = 2 + self.repeats_remaining = 2 - def mock_raw_input(message): - self.repeatsRemaining -= 1 + def mock_raw_input(_): + self.repeats_remaining -= 1 return None - self.assertIsNone(User.prompt("input", repeat=self.repeatsRemaining, raw_input=mock_raw_input)) + self.assertIsNone(User.prompt("input", repeat=self.repeats_remaining, raw_input_func=mock_raw_input)) def test_prompt_with_multiple_lists(self): def run_prompt_test(inputs, expected_result, can_choose_multiple=False): - def mock_raw_input(message): + def mock_raw_input(_): return inputs.pop(0) output_capture = OutputCapture() actual_result = output_capture.assert_outputs( self, User.prompt_with_multiple_lists, args=["title", ["subtitle1", "subtitle2"], [["foo", "bar"], ["foobar", "barbaz", "foobaz"]]], - kwargs={"can_choose_multiple": can_choose_multiple, "raw_input": mock_raw_input}, + kwargs={"can_choose_multiple": can_choose_multiple, "raw_input_func": mock_raw_input}, expected_stdout="title\n\nsubtitle1\n 1. foo\n 2. bar\n\nsubtitle2\n 3. foobar\n 4. barbaz\n 5. foobaz\n") self.assertEqual(actual_result, expected_result) self.assertEqual(len(inputs), 0) @@ -87,14 +90,14 @@ def test_prompt_with_list(self): def run_prompt_test(inputs, expected_result, can_choose_multiple=False): - def mock_raw_input(message): + def mock_raw_input(_): return inputs.pop(0) output_capture = OutputCapture() actual_result = output_capture.assert_outputs( self, User.prompt_with_list, args=["title", ["foo", "bar"]], - kwargs={"can_choose_multiple": can_choose_multiple, "raw_input": mock_raw_input}, + kwargs={"can_choose_multiple": can_choose_multiple, "raw_input_func": mock_raw_input}, expected_stdout="title\n 1. foo\n 2. bar\n") self.assertEqual(actual_result, expected_result) self.assertEqual(len(inputs), 0) @@ -128,5 +131,5 @@ return inputs[1] result = User().confirm(default=inputs[0], - raw_input=mock_raw_input) + raw_input_func=mock_raw_input) self.assertEqual(expected[1], result)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/workspace_mock.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/workspace_mock.py index 0abbdf7..c161fdd6 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/system/workspace_mock.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/system/workspace_mock.py
@@ -29,7 +29,11 @@ class MockWorkspace(object): - def find_unused_filename(self, directory, name, extension, search_limit=10): + def __init__(self, *_): + self.zip_path = None + self.source_path = None + + def find_unused_filename(self, directory, name, extension, **_): return "%s/%s.%s" % (directory, name, extension) def create_zip(self, zip_path, source_path):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/webkit_finder.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/webkit_finder.py index 3681938..4e29792 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/common/webkit_finder.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/webkit_finder.py
@@ -50,6 +50,9 @@ # of the SCM repository also matches the top of the WebKit tree. Some SVN users # (the chromium test bots, for example), might only check out subdirectories like # Tools/Scripts. This code will also work if there is no SCM system at all. + # TODO(qyearsley): Remove duplicate code; we're not concerned with SVN users anymore. + # Also, instead of caching the result with a private instance variable, we can use + # the memoized decorator. if not self._webkit_base: self._webkit_base = self._webkit_base module_path = self._filesystem.abspath(self._filesystem.path_to_module(self.__module__)) @@ -81,6 +84,23 @@ def perf_tests_dir(self): return self.path_from_webkit_base('PerformanceTests') + def layout_test_name(self, file_path): + """Returns a layout test name, given the path from the repo root. + + Args: + file_path: A relative path from the root of the Chromium repo. + + Returns: + The normalized layout test name, which is just the relative path from + the LayoutTests directory, using forward slash as the path separator. + Returns None if the given file is not in the LayoutTests directory. + """ + layout_tests_abs_path = self._filesystem.join(self.webkit_base(), self.layout_tests_dir()) + layout_tests_rel_path = self._filesystem.relpath(layout_tests_abs_path, self.chromium_base()) + if not file_path.startswith(layout_tests_rel_path): + return None + return file_path[len(layout_tests_rel_path) + 1:] + def depot_tools_base(self): if not self._depot_tools: # This basically duplicates src/build/find_depot_tools.py without the side effects
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/common/webkit_finder_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/common/webkit_finder_unittest.py new file mode 100644 index 0000000..278b7ce --- /dev/null +++ b/third_party/WebKit/Tools/Scripts/webkitpy/common/webkit_finder_unittest.py
@@ -0,0 +1,38 @@ +# Copyright 2016 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 unittest + +from webkitpy.common.webkit_finder import WebKitFinder +from webkitpy.common.system.filesystem_mock import MockFileSystem + + +class TestWebKitFinder(unittest.TestCase): + + # TODO(qyearsley): Add tests for other methods in WebKitFinder. + # Including tests for cases when the separator character is backslash. + + def test_layout_test_name(self): + finder = WebKitFinder(MockFileSystem()) + self.assertEqual( + finder.layout_test_name('third_party/WebKit/LayoutTests/test/name.html'), + 'test/name.html') + + def test_layout_test_name_not_in_layout_tests_dir(self): + finder = WebKitFinder(MockFileSystem()) + self.assertIsNone(finder.layout_test_name('some/other/path/file.html')) + + def test_webkit_base(self): + finder = WebKitFinder(MockFileSystem()) + self.assertEqual(finder.webkit_base(), '/mock-checkout/third_party/WebKit') + + def test_chromium_base(self): + finder = WebKitFinder(MockFileSystem()) + self.assertEqual(finder.chromium_base(), '/mock-checkout') + + def test_path_from_chromium_base(self): + finder = WebKitFinder(MockFileSystem()) + self.assertEqual( + finder.path_from_chromium_base('foo', 'bar.baz'), + '/mock-checkout/foo/bar.baz')
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/formatter/fix_docstrings.py b/third_party/WebKit/Tools/Scripts/webkitpy/formatter/fix_docstrings.py new file mode 100644 index 0000000..246e531 --- /dev/null +++ b/third_party/WebKit/Tools/Scripts/webkitpy/formatter/fix_docstrings.py
@@ -0,0 +1,35 @@ +# Copyright 2016 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 2to3 fixer that reformats docstrings. + +This should transform docstrings to be closer to the conventions in pep-0257; +see https://www.python.org/dev/peps/pep-0257/. +""" + +import re + +from lib2to3.fixer_base import BaseFix +from lib2to3.pgen2 import token + + +class FixDocstrings(BaseFix): + + explicit = True + _accept_type = token.STRING + + def match(self, node): + return node.value.startswith('"""') and node.prev_sibling is None + + def transform(self, node, results): + # First, strip whitespace at the beginning and end. + node.value = re.sub(r'^"""\s+', '"""', node.value) + node.value = re.sub(r'\s+"""$', '"""', node.value) + + # For multi-line docstrings, the closing quotes should go on their own line. + if '\n' in node.value: + indent = re.search(r'\n( *)\S', node.value).group(1) + node.value = re.sub(r'"""$', '\n' + indent + '"""', node.value) + + node.changed()
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/formatter/main.py b/third_party/WebKit/Tools/Scripts/webkitpy/formatter/main.py index c39212e..6452a9e 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/formatter/main.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/formatter/main.py
@@ -37,7 +37,8 @@ options.quoting = None autopep8_options = _autopep8_options_for_style(options.style) - fixers = _fixers_for_quoting(options.quoting) + fixers = ['webkitpy.formatter.fix_docstrings'] + fixers.extend(_fixers_for_quoting(options.quoting)) if options.files == ['-']: host = host or SystemHost()
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/formatter/main_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/formatter/main_unittest.py index 2beb7cd..0cfb5ae 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/formatter/main_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/formatter/main_unittest.py
@@ -107,3 +107,29 @@ host.stdin = StringIO.StringIO(ACTUAL_INPUT) main(host, ['--no-autopep8', '--double-quote-strings', '-']) self.assertMultiLineEqual(host.stdout.getvalue(), EXPECTED_ONLY_DOUBLE_QUOTED_OUTPUT) + + def test_format_docstrings(self): + host = MockSystemHost() + host.stdin = StringIO.StringIO(''' +def f(): + """ + triple-quoted docstring + with multiple lines + + """ + x = """ + this is a regular multi-line string, not a docstring + """ + return x +''') + main(host, ['-']) + self.assertMultiLineEqual(host.stdout.getvalue(), ''' +def f(): + """triple-quoted docstring + with multiple lines + """ + x = """ + this is a regular multi-line string, not a docstring + """ + return x +''')
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/pylintrc b/third_party/WebKit/Tools/Scripts/webkitpy/pylintrc index cda0612b..a71c7bb5 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/pylintrc +++ b/third_party/WebKit/Tools/Scripts/webkitpy/pylintrc
@@ -66,6 +66,7 @@ # e.g. too-many-arguments, too-many-branches. disable= design, + duplicate-code, missing-docstring, locally-disabled, star-args, @@ -73,6 +74,7 @@ fixme, global-statement, no-self-use, + locally-enabled, [REPORTS] @@ -202,7 +204,7 @@ inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ # Good variable names which should always be accepted, separated by a comma. -good-names=i,j,k,ex,Run,_,_log +good-names=i,j,k,e,ex,Run,_,_log # Bad variable names which should always be refused, separated by a comma. bad-names=foo,bar,baz,toto,tutu,tata
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl.py b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl.py index ab839fc..eb72502 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl.py
@@ -12,11 +12,12 @@ import optparse from webkitpy.common.checkout.scm.git import Git -from webkitpy.common.net.rietveld import latest_try_jobs +from webkitpy.common.net.buildbot import Build +from webkitpy.common.net.rietveld import latest_try_jobs, changed_files from webkitpy.common.net.web import Web +from webkitpy.common.webkit_finder import WebKitFinder from webkitpy.layout_tests.models.test_expectations import BASELINE_SUFFIX_LIST from webkitpy.tool.commands.rebaseline import AbstractParallelRebaselineCommand -from webkitpy.tool.commands.rebaseline import Build _log = logging.getLogger(__name__) @@ -24,7 +25,12 @@ class RebaselineCL(AbstractParallelRebaselineCommand): name = "rebaseline-cl" - help_text = "Fetches new baselines for one CL, from layout test runs on try bots." + help_text = "Fetches new baselines for a CL from test runs on try bots." + long_help = ("By default, this command will check the latest try results " + "and download new baselines for any tests that have been " + "changed in the given CL that have failed and have new " + "baselines. After downloading, the baselines for different " + "platforms should be optimized (conslidated).") show_in_main_help = True def __init__(self): @@ -35,6 +41,9 @@ optparse.make_option( '--dry-run', action='store_true', default=False, help='Dry run mode; list actions that would be performed but do not do anything.'), + optparse.make_option( + '--only-changed-tests', action='store_true', default=False, + help='Only download new baselines for tests that are changed in the CL.'), self.no_optimize_option, self.results_directory_option, ]) @@ -51,7 +60,8 @@ for test in args: test_prefix_list[test] = {b: BASELINE_SUFFIX_LIST for b in builds} else: - test_prefix_list = self._test_prefix_list(issue_number) + test_prefix_list = self._test_prefix_list( + issue_number, only_changed_tests=options.only_changed_tests) self._log_test_prefix_list(test_prefix_list) if options.dry_run: @@ -75,12 +85,28 @@ # that this command can be called from outside of the repo. return Git(cwd=self._tool.filesystem.dirname(self._tool.path())) - def _test_prefix_list(self, issue_number): - """Returns a collection of test, builder and file extensions to get new baselines for.""" + def _test_prefix_list(self, issue_number, only_changed_tests): + """Returns a collection of test, builder and file extensions to get new baselines for. + + Args: + issue_number: The CL number of the change which needs new baselines. + only_changed_tests: Whether to only include baselines for tests that + are changed in this CL. If False, all new baselines for failing + tests will be downloaded, even for tests that were not modified. + + Returns: + A dict containing information about which new baselines to download. + """ builds_to_tests = self._builds_to_tests(issue_number) + if only_changed_tests: + files_in_cl = changed_files(issue_number, self.web) + finder = WebKitFinder(self._tool.filesystem) + tests_in_cl = [finder.layout_test_name(f) for f in files_in_cl] result = {} for build, tests in builds_to_tests.iteritems(): for test in tests: + if only_changed_tests and test not in tests_in_cl: + continue if test not in result: result[test] = {} result[test][build] = BASELINE_SUFFIX_LIST @@ -100,7 +126,7 @@ return builds_to_tests def _try_bots(self): - """Retuns a collection of try bot builders to fetch results for.""" + """Returns a collection of try bot builders to fetch results for.""" return self._tool.builders.all_try_builder_names() def _unexpected_mismatch_results(self, try_job):
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl_unittest.py index 88e4494..627d698 100644 --- a/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl_unittest.py +++ b/third_party/WebKit/Tools/Scripts/webkitpy/tool/commands/rebaseline_cl_unittest.py
@@ -34,6 +34,10 @@ 'buildnumber': 4000, }, ], + 'files': { + 'third_party/WebKit/LayoutTests/fast/dom/prototype-inheritance.html': {'status': 'M'}, + 'third_party/WebKit/LayoutTests/fast/dom/prototype-taco.html': {'status': 'M'}, + }, }), }) self.tool.builders = BuilderList({ @@ -55,11 +59,12 @@ @staticmethod def command_options(**kwargs): options = { - 'issue': None, + 'only_changed_tests': False, 'dry_run': False, + 'issue': None, 'optimize': True, - 'verbose': False, 'results_directory': None, + 'verbose': False, } options.update(kwargs) return optparse.Values(dict(**options)) @@ -108,6 +113,24 @@ 'Rebaselining fast/dom/prototype-taco.html\n' 'Rebaselining svg/dynamic-updates/SVGFEDropShadowElement-dom-stdDeviation-attr.html\n')) + def test_execute_with_only_changed_tests_option(self): + oc = OutputCapture() + try: + oc.capture_output() + self.command.execute(self.command_options(issue=11112222, only_changed_tests=True), [], self.tool) + finally: + _, _, logs = oc.restore_output() + # svg/dynamic-updates/SVGFEDropShadowElement-dom-stdDeviation-attr.html + # is in the list of failed tests, but not in the list of files modified + # in the given CL; it should be included because all_tests is set to True. + self.assertMultiLineEqual( + logs, + ('Tests to rebaseline:\n' + ' fast/dom/prototype-inheritance.html: MOCK Try Win (5000)\n' + ' fast/dom/prototype-taco.html: MOCK Try Win (5000)\n' + 'Rebaselining fast/dom/prototype-inheritance.html\n' + 'Rebaselining fast/dom/prototype-taco.html\n')) + def test_rebaseline_calls(self): """Tests the list of commands that are invoked when rebaseline is called.""" # First write test contents to the mock filesystem so that
diff --git a/third_party/WebKit/public/BUILD.gn b/third_party/WebKit/public/BUILD.gn index 336b3d5..fd68623 100644 --- a/third_party/WebKit/public/BUILD.gn +++ b/third_party/WebKit/public/BUILD.gn
@@ -171,8 +171,6 @@ "platform/modules/notifications/notification.mojom", "platform/modules/notifications/notification_service.mojom", "platform/modules/offscreencanvas/offscreen_canvas_surface.mojom", - "platform/modules/permissions/permission.mojom", - "platform/modules/permissions/permission_status.mojom", "platform/modules/serviceworker/service_worker_event_status.mojom", "platform/modules/wake_lock/wake_lock_service.mojom", ] @@ -203,6 +201,8 @@ # GYP version: WebKit/public/blink.gyp:new_wrapper_types_mojo_bindings mojom("new_wrapper_types_mojo_bindings") { sources = [ + "platform/modules/permissions/permission.mojom", + "platform/modules/permissions/permission_status.mojom", "platform/modules/presentation/presentation.mojom", ]
diff --git a/third_party/WebKit/public/platform/WebDisplayItemList.h b/third_party/WebKit/public/platform/WebDisplayItemList.h index 2342edbe..16456c5 100644 --- a/third_party/WebKit/public/platform/WebDisplayItemList.h +++ b/third_party/WebKit/public/platform/WebDisplayItemList.h
@@ -52,7 +52,7 @@ virtual void appendEndCompositingItem() { } // TODO(loyso): This should use CompositorFilterOperation. crbug.com/584551 - virtual void appendFilterItem(const cc::FilterOperations&, const WebFloatRect& bounds) { } + virtual void appendFilterItem(const cc::FilterOperations&, const WebFloatRect& filter_bounds) { } virtual void appendEndFilterItem() { } // Scroll containers are identified by an opaque pointer.
diff --git a/third_party/WebKit/public/platform/WebURLRequest.h b/third_party/WebKit/public/platform/WebURLRequest.h index 283c90c6..45a8a86 100644 --- a/third_party/WebKit/public/platform/WebURLRequest.h +++ b/third_party/WebKit/public/platform/WebURLRequest.h
@@ -153,6 +153,11 @@ All }; + enum class LoadingIPCType { + ChromeIPC, + Mojo, + }; + class ExtraData { public: virtual ~ExtraData() { } @@ -306,6 +311,8 @@ // https://mikewest.github.io/cors-rfc1918/#external-request BLINK_PLATFORM_EXPORT bool isExternalRequest() const; + BLINK_PLATFORM_EXPORT LoadingIPCType getLoadingIPCType() const; + #if INSIDE_BLINK BLINK_PLATFORM_EXPORT ResourceRequest& toMutableResourceRequest(); BLINK_PLATFORM_EXPORT const ResourceRequest& toResourceRequest() const;
diff --git a/third_party/WebKit/public/web/WebDataSource.h b/third_party/WebKit/public/web/WebDataSource.h index cd4fd5b..e3f89fd5 100644 --- a/third_party/WebKit/public/web/WebDataSource.h +++ b/third_party/WebKit/public/web/WebDataSource.h
@@ -105,6 +105,11 @@ // the user may have already recorded the original value. virtual void setNavigationStartTime(double) = 0; + // Sets timing and attributes of the navigation. + // Ordinarily, they are determined in WebCore, but when the navigation is + // handled by the client, they can be passed here. + virtual void updateNavigationTimings(double redirectStartTime, double redirectEndTime, double fetchStartTime, const WebVector<WebURL>& redirectChain) = 0; + // Allows the embedder to inject a filter that will be consulted for each // subsequent subresource load, and gets the final say in deciding whether // or not to allow the load. The passed-in filter object is deleted when the
diff --git a/third_party/WebKit/public/web/WebPerformance.h b/third_party/WebKit/public/web/WebPerformance.h index 378b1a8..080b70a 100644 --- a/third_party/WebKit/public/web/WebPerformance.h +++ b/third_party/WebKit/public/web/WebPerformance.h
@@ -90,6 +90,7 @@ BLINK_EXPORT double firstTextPaint() const; BLINK_EXPORT double firstImagePaint() const; BLINK_EXPORT double firstContentfulPaint() const; + BLINK_EXPORT double firstMeaningfulPaint() const; BLINK_EXPORT double parseStart() const; BLINK_EXPORT double parseStop() const; BLINK_EXPORT double parseBlockedOnScriptLoadDuration() const;
diff --git a/third_party/WebKit/public/web/WebRuntimeFeatures.h b/third_party/WebKit/public/web/WebRuntimeFeatures.h index f7df2b9..ffae84e1 100644 --- a/third_party/WebKit/public/web/WebRuntimeFeatures.h +++ b/third_party/WebKit/public/web/WebRuntimeFeatures.h
@@ -70,6 +70,7 @@ BLINK_EXPORT static void enableAccelerated2dCanvas(bool); BLINK_EXPORT static void enableAudioOutputDevices(bool); BLINK_EXPORT static void enableCanvas2dImageChromium(bool); + BLINK_EXPORT static void enableColorCorrectRendering(bool); BLINK_EXPORT static void enableCredentialManagerAPI(bool); BLINK_EXPORT static void enableDatabase(bool); BLINK_EXPORT static void enableDecodeToYUV(bool); @@ -78,7 +79,6 @@ BLINK_EXPORT static void enableExperimentalCanvasFeatures(bool); BLINK_EXPORT static void enableFastMobileScrolling(bool); BLINK_EXPORT static void enableFileSystem(bool); - BLINK_EXPORT static void enableImageColorProfiles(bool); BLINK_EXPORT static void enableInputMultipleFieldsUI(bool); BLINK_EXPORT static void enableMediaCapture(bool); BLINK_EXPORT static void enableMediaDocumentDownloadButton(bool);
diff --git a/third_party/WebKit/public/web/WebSettings.h b/third_party/WebKit/public/web/WebSettings.h index b1853da..97079e92 100644 --- a/third_party/WebKit/public/web/WebSettings.h +++ b/third_party/WebKit/public/web/WebSettings.h
@@ -145,6 +145,7 @@ virtual void setAntialiasedClips2dCanvasEnabled(bool) = 0; virtual void setAutoplayExperimentMode(const WebString&) = 0; virtual void setAutoZoomFocusedNodeToLegibleScale(bool) = 0; + virtual void setBrowserSideNavigationEnabled(bool) = 0; virtual void setCaretBrowsingEnabled(bool) = 0; virtual void setClobberUserAgentInitialScaleQuirk(bool) = 0; virtual void setCookieEnabled(bool) = 0;
diff --git a/third_party/WebKit/public/web/WebView.h b/third_party/WebKit/public/web/WebView.h index fa5af494..bba44bc 100644 --- a/third_party/WebKit/public/web/WebView.h +++ b/third_party/WebKit/public/web/WebView.h
@@ -327,7 +327,6 @@ // Set and reset the device color profile. virtual void setDeviceColorProfile(const WebVector<char>&) = 0; - virtual void resetDeviceColorProfileForTesting() = 0; // Resize the view at the same time as changing the state of the top // controls. If |topControlsShrinkLayout| is true, the embedder shrunk the
diff --git a/third_party/afl/BUILD.gn b/third_party/afl/BUILD.gn index 713293d..af09c3d 100644 --- a/third_party/afl/BUILD.gn +++ b/third_party/afl/BUILD.gn
@@ -56,10 +56,6 @@ "-Wno-sign-compare", "-Wno-pointer-sign", - # TODO: Patch afl so the version is defined in source code and not the - # Makefile. - "-DVERSION=\"2.14b\"", - # afl_docs copies docs/ to this location. "-DDOC_PATH=\"$root_build_dir/afl/docs/\"",
diff --git a/third_party/afl/README.chromium b/third_party/afl/README.chromium index cc27e600..17c645e 100644 --- a/third_party/afl/README.chromium +++ b/third_party/afl/README.chromium
@@ -1,8 +1,8 @@ Name: American Fuzzy Lop -Short Name: afl +Short Name: AFL URL: http://lcamtuf.coredump.cx/afl/ -Version: 2.14b -Date: June 16th, 2016 +Version: 2.30b +Date: August 11, 2016 License: Apache 2.0 License File: src/docs/COPYING Security Critical: no @@ -12,11 +12,11 @@ (fuzzing). Similar to libFuzzer. Local Modifications: -Renamed afl-2.14b/ to src/. -Removed the following unneeded files/directories: - 1. src/docs/visualization/ - 2. src/docs/vuln_samples/ - 3. src/testcases/ - 4. src/experimental/argv_fuzzing/argv-fuzz-inl.h - 5. src/llvm_mode/afl-llvm-pass.so.cc - 6. src/experimental/instrumented_cmp/instrumented_cmp.c +- Use update.py to roll forward. +- Renamed afl-2.30b/ to src/. +- Removed the following unneeded files/directories: + - src/experimental/argv_fuzzing/ + - src/docs/vuln_samples/*.elf + - src/testcases/others/elf + - src/llvm_mode/afl-llvm-pass.so.cc + - src/dictionaries/
diff --git a/third_party/afl/src/Makefile b/third_party/afl/src/Makefile index ca6879c3..e4072def 100644 --- a/third_party/afl/src/Makefile +++ b/third_party/afl/src/Makefile
@@ -14,7 +14,7 @@ # PROGNAME = afl -VERSION = 2.14b +VERSION = $(shell grep '^\#define VERSION ' config.h | cut -d '"' -f2) PREFIX ?= /usr/local BIN_PATH = $(PREFIX)/bin @@ -22,7 +22,7 @@ DOC_PATH = $(PREFIX)/share/doc/afl MISC_PATH = $(PREFIX)/share/afl -# PROGS intentionally omit afl-as, which gets installed to its own dir. +# PROGS intentionally omit afl-as, which gets installed elsewhere. PROGS = afl-gcc afl-fuzz afl-showmap afl-tmin afl-gotcpu afl-analyze SH_PROGS = afl-plot afl-cmin afl-whatsup @@ -30,7 +30,7 @@ CFLAGS ?= -O3 -funroll-loops CFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign \ -DAFL_PATH=\"$(HELPER_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\" \ - -DBIN_PATH=\"$(BIN_PATH)\" -DVERSION=\"$(VERSION)\" + -DBIN_PATH=\"$(BIN_PATH)\" ifneq "$(filter Linux GNU%,$(shell uname))" "" LDFLAGS += -ldl @@ -66,7 +66,7 @@ set -e; for i in afl-g++ afl-clang afl-clang++; do ln -sf afl-gcc $$i; done afl-as: afl-as.c afl-as.h $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS) + $(CC) $(CFLAGS) $@.c -o $@ $(LDFLAGS) ln -sf afl-as as afl-fuzz: afl-fuzz.c $(COMM_HDR) | test_x86 @@ -114,6 +114,8 @@ rm -f $(PROGS) afl-as as afl-g++ afl-clang afl-clang++ *.o *~ a.out core core.[1-9][0-9]* *.stackdump test .test test-instr .test-instr0 .test-instr1 qemu_mode/qemu-2.3.0.tar.bz2 afl-qemu-trace rm -rf out_dir qemu_mode/qemu-2.3.0 $(MAKE) -C llvm_mode clean + $(MAKE) -C libdislocator clean + $(MAKE) -C libtokencap clean install: all mkdir -p -m 755 $${DESTDIR}$(BIN_PATH) $${DESTDIR}$(HELPER_PATH) $${DESTDIR}$(DOC_PATH) $${DESTDIR}$(MISC_PATH) @@ -129,10 +131,11 @@ ln -sf afl-as $${DESTDIR}$(HELPER_PATH)/as install -m 644 docs/README docs/ChangeLog docs/*.txt $${DESTDIR}$(DOC_PATH) cp -r testcases/ $${DESTDIR}$(MISC_PATH) + cp -r dictionaries/ $${DESTDIR}$(MISC_PATH) publish: clean test "`basename $$PWD`" = "afl" || exit 1 - test -f ~/www/afl/releases/$(PROGNAME)-$(VERSION).tgz; if [ "$$?" = "0" ]; then echo; echo "Change program version in Makefile, mmkay?"; echo; exit 1; fi + test -f ~/www/afl/releases/$(PROGNAME)-$(VERSION).tgz; if [ "$$?" = "0" ]; then echo; echo "Change program version in config.h, mmkay?"; echo; exit 1; fi cd ..; rm -rf $(PROGNAME)-$(VERSION); cp -pr $(PROGNAME) $(PROGNAME)-$(VERSION); \ tar -cvz -f ~/www/afl/releases/$(PROGNAME)-$(VERSION).tgz $(PROGNAME)-$(VERSION) chmod 644 ~/www/afl/releases/$(PROGNAME)-$(VERSION).tgz
diff --git a/third_party/afl/src/afl-analyze.c b/third_party/afl/src/afl-analyze.c index 2c27a51e1..fd0a522 100644 --- a/third_party/afl/src/afl-analyze.c +++ b/third_party/afl/src/afl-analyze.c
@@ -89,21 +89,17 @@ /* Classify tuple counts. This is a slow & naive version, but good enough here. */ -#define AREP4(_sym) (_sym), (_sym), (_sym), (_sym) -#define AREP8(_sym) AREP4(_sym), AREP4(_sym) -#define AREP16(_sym) AREP8(_sym), AREP8(_sym) -#define AREP32(_sym) AREP16(_sym), AREP16(_sym) -#define AREP64(_sym) AREP32(_sym), AREP32(_sym) -#define AREP128(_sym) AREP64(_sym), AREP64(_sym) - static u8 count_class_lookup[256] = { - /* 0 - 3: 4 */ 0, 1, 2, 4, - /* 4 - 7: +4 */ AREP4(8), - /* 8 - 15: +8 */ AREP8(16), - /* 16 - 31: +16 */ AREP16(32), - /* 32 - 127: +96 */ AREP64(64), AREP32(64), - /* 128+: +128 */ AREP128(128) + [0] = 0, + [1] = 1, + [2] = 2, + [3] = 4, + [4 ... 7] = 8, + [8 ... 15] = 16, + [16 ... 31] = 32, + [32 ... 127] = 64, + [128 ... 255] = 128 }; @@ -711,8 +707,10 @@ "allocator_may_return_null=1:" "msan_track_origins=0", 0); - if (getenv("AFL_LD_PRELOAD")) - setenv("LD_PRELOAD", getenv("AFL_LD_PRELOAD"), 1); + if (getenv("AFL_PRELOAD")) { + setenv("LD_PRELOAD", getenv("AFL_PRELOAD"), 1); + setenv("DYLD_INSERT_LIBRARIES", getenv("AFL_PRELOAD"), 1); + } }
diff --git a/third_party/afl/src/afl-as.h b/third_party/afl/src/afl-as.h index 1cca7986..ebd57109 100644 --- a/third_party/afl/src/afl-as.h +++ b/third_party/afl/src/afl-as.h
@@ -98,7 +98,7 @@ of every .c file. This should have no impact in any practical sense. Another side effect of this design is that getenv() will be called once per - every .o file when running in non-instrumented mode; an since getenv() tends + every .o file when running in non-instrumented mode; and since getenv() tends to be optimized in funny ways, we need to be very careful to save every oddball register it may touch. @@ -181,7 +181,9 @@ " xorl %ecx, %edi\n" " shrl $1, %ecx\n" " movl %ecx, __afl_prev_loc\n" -#endif /* !COVERAGE_ONLY */ +#else + " movl %ecx, %edi\n" +#endif /* ^!COVERAGE_ONLY */ "\n" #ifdef SKIP_COUNTS " orb $1, (%edx, %edi, 1)\n"
diff --git a/third_party/afl/src/afl-fuzz.c b/third_party/afl/src/afl-fuzz.c index 2d36293..5ca8c8f 100644 --- a/third_party/afl/src/afl-fuzz.c +++ b/third_party/afl/src/afl-fuzz.c
@@ -60,7 +60,8 @@ # include <sys/sysctl.h> #endif /* __APPLE__ || __FreeBSD__ || __OpenBSD__ */ -/* For supporting -Z on systems that have sched_setaffinity. */ +/* For systems that have sched_setaffinity; right now just Linux, but one + can hope... */ #ifdef __linux__ # define HAVE_AFFINITY 1 @@ -111,12 +112,12 @@ in_place_resume, /* Attempt in-place resume? */ auto_changed, /* Auto-generated tokens changed? */ no_cpu_meter_red, /* Feng shui on the status screen */ - no_var_check, /* Don't detect variable behavior */ shuffle_queue, /* Shuffle input queue? */ bitmap_changed = 1, /* Time to update bitmap? */ qemu_mode, /* Running in QEMU mode? */ skip_requested, /* Skip request, via SIGUSR1 */ - run_over10m; /* Run time over 10 minutes? */ + run_over10m, /* Run time over 10 minutes? */ + persistent_mode; /* Running in persistent mode? */ static s32 out_fd, /* Persistent fd for out_file */ dev_urandom_fd = -1, /* Persistent fd for /dev/urandom */ @@ -134,6 +135,8 @@ virgin_hang[MAP_SIZE], /* Bits we haven't seen in hangs */ virgin_crash[MAP_SIZE]; /* Bits we haven't seen in crashes */ +static u8 var_bytes[MAP_SIZE]; /* Bytes that appear to be variable */ + static s32 shm_id; /* ID of the SHM region */ static volatile u8 stop_soon, /* Ctrl-C pressed? */ @@ -153,6 +156,7 @@ cur_depth, /* Current path depth */ max_depth, /* Max path depth */ useless_at_start, /* Number of useless starting paths */ + var_byte_count, /* Bitmap bytes with var behavior */ current_entry, /* Current queue entry ID */ havoc_div = 1; /* Cycle count divisor for havoc */ @@ -165,6 +169,7 @@ last_path_time, /* Time for most recent path (ms) */ last_crash_time, /* Time for most recent crash (ms) */ last_hang_time, /* Time for most recent hang (ms) */ + last_crash_execs, /* Exec counter at last crash */ queue_cycle, /* Queue round counter */ cycles_wo_finds, /* Cycles without any new paths */ trim_execs, /* Execs done to trim input files */ @@ -182,6 +187,8 @@ static s32 stage_cur, stage_max; /* Stage progression */ static s32 splicing_with = -1; /* Splicing with which test case? */ +static u32 master_id, master_max; /* Master instance job splitting */ + static u32 syncing_case; /* Syncing with case #... */ static s32 stage_cur_byte, /* Byte offset of current stage op */ @@ -200,14 +207,11 @@ static u64 total_bitmap_size, /* Total bit count for all bitmaps */ total_bitmap_entries; /* Number of bitmaps counted */ -static u32 cpu_core_count; /* CPU core count */ +static s32 cpu_core_count; /* CPU core count */ #ifdef HAVE_AFFINITY -static u8 use_affinity; /* Using -Z */ - -static u32 cpu_aff_main, /* Affinity for main process */ - cpu_aff_child; /* Affinity for fuzzed child */ +static s32 cpu_aff = -1; /* Selected CPU core */ #endif /* HAVE_AFFINITY */ @@ -340,31 +344,12 @@ } -#ifdef HAVE_AFFINITY - -/* Set CPU affinity (on systems that support it). */ - -static void set_cpu_affinity(u32 cpu_id) { - - cpu_set_t c; - - CPU_ZERO(&c); - CPU_SET(cpu_id, &c); - - if (sched_setaffinity(0, sizeof(c), &c)) - PFATAL("sched_setaffinity failed"); - -} - -#endif /* HAVE_AFFINITY */ - - /* Generate a random number (from 0 to limit - 1). This may have slight bias. */ static inline u32 UR(u32 limit) { - if (!rand_cnt--) { + if (unlikely(!rand_cnt--)) { u32 seed[2]; @@ -398,6 +383,122 @@ } +#ifdef HAVE_AFFINITY + +/* Build a list of processes bound to specific cores. Returns -1 if nothing + can be found. Assumes an upper bound of 4k CPUs. */ + +static void bind_to_free_cpu(void) { + + DIR* d; + struct dirent* de; + cpu_set_t c; + + u8 cpu_used[4096] = { 0 }; + u32 i; + + if (cpu_core_count < 2) return; + + if (getenv("AFL_NO_AFFINITY")) { + + WARNF("Not binding to a CPU core (AFL_NO_AFFINITY set)."); + return; + + } + + d = opendir("/proc"); + + if (!d) { + + WARNF("Unable to access /proc - can't scan for free CPU cores."); + return; + + } + + ACTF("Checking CPU core loadout..."); + + /* Introduce some jitter, in case multiple AFL tasks are doing the same + thing at the same time... */ + + usleep(R(1000) * 250); + + /* Scan all /proc/<pid>/status entries, checking for Cpus_allowed_list. + Flag all processes bound to a specific CPU using cpu_used[]. This will + fail for some exotic binding setups, but is likely good enough in almost + all real-world use cases. */ + + while ((de = readdir(d))) { + + u8* fn; + FILE* f; + u8 tmp[MAX_LINE]; + u8 has_vmsize = 0; + + if (!isdigit(de->d_name[0])) continue; + + fn = alloc_printf("/proc/%s/status", de->d_name); + + if (!(f = fopen(fn, "r"))) { + ck_free(fn); + continue; + } + + while (fgets(tmp, MAX_LINE, f)) { + + u32 hval; + + /* Processes without VmSize are probably kernel tasks. */ + + if (!strncmp(tmp, "VmSize:\t", 8)) has_vmsize = 1; + + if (!strncmp(tmp, "Cpus_allowed_list:\t", 19) && + !strchr(tmp, '-') && !strchr(tmp, ',') && + sscanf(tmp + 19, "%u", &hval) == 1 && hval < sizeof(cpu_used) && + has_vmsize) { + + cpu_used[hval] = 1; + break; + + } + + } + + ck_free(fn); + fclose(f); + + } + + closedir(d); + + for (i = 0; i < cpu_core_count; i++) if (!cpu_used[i]) break; + + if (i == cpu_core_count) { + + SAYF("\n" cLRD "[-] " cRST + "Uh-oh, looks like all %u CPU cores on your system are allocated to\n" + " other instances of afl-fuzz (or similar CPU-locked tasks). Starting\n" + " another fuzzer on this machine is probably a bad plan, but if you are\n" + " absolutely sure, you can set AFL_NO_AFFINITY and try again.\n", + cpu_core_count); + + FATAL("No more free CPU cores"); + + } + + OKF("Found a free CPU core, binding to #%u.", i); + + cpu_aff = i; + + CPU_ZERO(&c); + CPU_SET(i, &c); + + if (sched_setaffinity(0, sizeof(c), &c)) + PFATAL("sched_setaffinity failed"); + +} + +#endif /* HAVE_AFFINITY */ + #ifndef IGNORE_FINDS /* Helper function to compare buffers; returns first and last differing offset. We @@ -768,9 +869,6 @@ This function is called after every exec() on a fairly large buffer, so it needs to be fast. We do this in 32-bit and 64-bit flavors. */ -#define FFL(_b) (0xffULL << ((_b) << 3)) -#define FF(_b) (0xff << ((_b) << 3)) - static inline u8 has_new_bits(u8* virgin_map) { #ifdef __x86_64__ @@ -793,53 +891,39 @@ while (i--) { -#ifdef __x86_64__ + /* Optimize for (*current & *virgin) == 0 - i.e., no bits in current bitmap + that have not been already cleared from the virgin map - since this will + almost always be the case. */ - u64 cur = *current; - u64 vir = *virgin; + if (unlikely(*current) && unlikely(*current & *virgin)) { -#else + if (likely(ret < 2)) { - u32 cur = *current; - u32 vir = *virgin; + u8* cur = (u8*)current; + u8* vir = (u8*)virgin; -#endif /* ^__x86_64__ */ - - /* Optimize for *current == ~*virgin, since this will almost always be the - case. */ - - if (cur & vir) { - - if (ret < 2) { - - /* This trace did not have any new bytes yet; see if there's any - current[] byte that is non-zero when virgin[] is 0xff. */ + /* Looks like we have not found any new bytes yet; see if any non-zero + bytes in current[] are pristine in virgin[]. */ #ifdef __x86_64__ - if (((cur & FFL(0)) && (vir & FFL(0)) == FFL(0)) || - ((cur & FFL(1)) && (vir & FFL(1)) == FFL(1)) || - ((cur & FFL(2)) && (vir & FFL(2)) == FFL(2)) || - ((cur & FFL(3)) && (vir & FFL(3)) == FFL(3)) || - ((cur & FFL(4)) && (vir & FFL(4)) == FFL(4)) || - ((cur & FFL(5)) && (vir & FFL(5)) == FFL(5)) || - ((cur & FFL(6)) && (vir & FFL(6)) == FFL(6)) || - ((cur & FFL(7)) && (vir & FFL(7)) == FFL(7))) ret = 2; + if ((cur[0] && vir[0] == 0xff) || (cur[1] && vir[1] == 0xff) || + (cur[2] && vir[2] == 0xff) || (cur[3] && vir[3] == 0xff) || + (cur[4] && vir[4] == 0xff) || (cur[5] && vir[5] == 0xff) || + (cur[6] && vir[6] == 0xff) || (cur[7] && vir[7] == 0xff)) ret = 2; else ret = 1; #else - if (((cur & FF(0)) && (vir & FF(0)) == FF(0)) || - ((cur & FF(1)) && (vir & FF(1)) == FF(1)) || - ((cur & FF(2)) && (vir & FF(2)) == FF(2)) || - ((cur & FF(3)) && (vir & FF(3)) == FF(3))) ret = 2; + if ((cur[0] && vir[0] == 0xff) || (cur[1] && vir[1] == 0xff) || + (cur[2] && vir[2] == 0xff) || (cur[3] && vir[3] == 0xff)) ret = 2; else ret = 1; #endif /* ^__x86_64__ */ } - *virgin = vir & ~cur; + *virgin &= ~*current; } @@ -887,6 +971,8 @@ } +#define FF(_b) (0xff << ((_b) << 3)) + /* Count the number of bytes set in the bitmap. Called fairly sporadically, mostly to update the status screen or calibrate and examine confirmed new paths. */ @@ -948,21 +1034,11 @@ is hit or not. Called on every new crash or hang, should be reasonably fast. */ -#define AREP4(_sym) (_sym), (_sym), (_sym), (_sym) -#define AREP8(_sym) AREP4(_sym), AREP4(_sym) -#define AREP16(_sym) AREP8(_sym), AREP8(_sym) -#define AREP32(_sym) AREP16(_sym), AREP16(_sym) -#define AREP64(_sym) AREP32(_sym), AREP32(_sym) -#define AREP128(_sym) AREP64(_sym), AREP64(_sym) +static const u8 simplify_lookup[256] = { -static u8 simplify_lookup[256] = { - /* 4 */ 1, 128, 128, 128, - /* +4 */ AREP4(128), - /* +8 */ AREP8(128), - /* +16 */ AREP16(128), - /* +32 */ AREP32(128), - /* +64 */ AREP64(128), - /* +128 */ AREP128(128) + [0] = 1, + [1 ... 255] = 128 + }; #ifdef __x86_64__ @@ -975,7 +1051,7 @@ /* Optimize for sparse bitmaps. */ - if (*mem) { + if (unlikely(*mem)) { u8* mem8 = (u8*)mem; @@ -1006,7 +1082,7 @@ /* Optimize for sparse bitmaps. */ - if (*mem) { + if (unlikely(*mem)) { u8* mem8 = (u8*)mem; @@ -1029,17 +1105,36 @@ preprocessing step for any newly acquired traces. Called on every exec, must be fast. */ -static u8 count_class_lookup[256] = { +static const u8 count_class_lookup8[256] = { - /* 0 - 3: 4 */ 0, 1, 2, 4, - /* 4 - 7: +4 */ AREP4(8), - /* 8 - 15: +8 */ AREP8(16), - /* 16 - 31: +16 */ AREP16(32), - /* 32 - 127: +96 */ AREP64(64), AREP32(64), - /* 128+: +128 */ AREP128(128) + [0] = 0, + [1] = 1, + [2] = 2, + [3] = 4, + [4 ... 7] = 8, + [8 ... 15] = 16, + [16 ... 31] = 32, + [32 ... 127] = 64, + [128 ... 255] = 128 }; +static u16 count_class_lookup16[65536]; + + +static void init_count_class16(void) { + + u32 b1, b2; + + for (b1 = 0; b1 < 256; b1++) + for (b2 = 0; b2 < 256; b2++) + count_class_lookup16[(b1 << 8) + b2] = + (count_class_lookup8[b1] << 8) | + count_class_lookup8[b2]; + +} + + #ifdef __x86_64__ static inline void classify_counts(u64* mem) { @@ -1050,18 +1145,14 @@ /* Optimize for sparse bitmaps. */ - if (*mem) { + if (unlikely(*mem)) { - u8* mem8 = (u8*)mem; + u16* mem16 = (u16*)mem; - mem8[0] = count_class_lookup[mem8[0]]; - mem8[1] = count_class_lookup[mem8[1]]; - mem8[2] = count_class_lookup[mem8[2]]; - mem8[3] = count_class_lookup[mem8[3]]; - mem8[4] = count_class_lookup[mem8[4]]; - mem8[5] = count_class_lookup[mem8[5]]; - mem8[6] = count_class_lookup[mem8[6]]; - mem8[7] = count_class_lookup[mem8[7]]; + mem16[0] = count_class_lookup16[mem16[0]]; + mem16[1] = count_class_lookup16[mem16[1]]; + mem16[2] = count_class_lookup16[mem16[2]]; + mem16[3] = count_class_lookup16[mem16[3]]; } @@ -1081,14 +1172,12 @@ /* Optimize for sparse bitmaps. */ - if (*mem) { + if (unlikely(*mem)) { - u8* mem8 = (u8*)mem; + u16* mem16 = (u16*)mem; - mem8[0] = count_class_lookup[mem8[0]]; - mem8[1] = count_class_lookup[mem8[1]]; - mem8[2] = count_class_lookup[mem8[2]]; - mem8[3] = count_class_lookup[mem8[3]]; + mem16[0] = count_class_lookup16[mem16[0]]; + mem16[1] = count_class_lookup16[mem16[1]]; } @@ -1897,10 +1986,6 @@ struct rlimit r; -#ifdef HAVE_AFFINITY - if (use_affinity) set_cpu_affinity(cpu_aff_child); -#endif /* HAVE_AFFINITY */ - /* Umpf. On OpenBSD, the default fd limit for root users is set to soft 128. Let's try to fix that... */ @@ -2199,10 +2284,6 @@ struct rlimit r; -#ifdef HAVE_AFFINITY - if (use_affinity) set_cpu_affinity(cpu_aff_child); -#endif /* HAVE_AFFINITY */ - if (mem_limit) { r.rlim_max = r.rlim_cur = ((rlim_t)mem_limit) << 20; @@ -2321,7 +2402,8 @@ } - child_pid = 0; + if (!WIFSTOPPED(status)) child_pid = 0; + it.it_value.tv_sec = 0; it.it_value.tv_usec = 0; @@ -2440,7 +2522,11 @@ static u8 calibrate_case(char** argv, struct queue_entry* q, u8* use_mem, u32 handicap, u8 from_queue) { - u8 fault = 0, new_bits = 0, var_detected = 0, first_run = (q->exec_cksum == 0); + static u8 first_trace[MAP_SIZE]; + + u8 fault = 0, new_bits = 0, var_detected = 0, + first_run = (q->exec_cksum == 0); + u64 start_us, stop_us; s32 old_sc = stage_cur, old_sm = stage_max, old_tmout = exec_tmout; @@ -2457,7 +2543,7 @@ q->cal_failed++; stage_name = "calibration"; - stage_max = no_var_check ? CAL_CYCLES_NO_VAR : CAL_CYCLES; + stage_max = CAL_CYCLES; /* Make sure the forkserver is up before we do anything, and let's not count its spin-up time toward binary calibration. */ @@ -2465,6 +2551,8 @@ if (dumb_mode != 1 && !no_forkserver && !forksrv_pid) init_forkserver(argv); + if (q->exec_cksum) memcpy(first_trace, trace_bits, MAP_SIZE); + start_us = get_cur_time_us(); for (stage_cur = 0; stage_cur < stage_max; stage_cur++) { @@ -2494,12 +2582,29 @@ u8 hnb = has_new_bits(virgin_bits); if (hnb > new_bits) new_bits = hnb; - if (!no_var_check && q->exec_cksum) { + if (q->exec_cksum) { + + u32 i; + + for (i = 0; i < MAP_SIZE; i++) { + + if (!var_bytes[i] && first_trace[i] != trace_bits[i]) { + + var_bytes[i] = 1; + stage_max = CAL_CYCLES_LONG; + + } + + } var_detected = 1; - stage_max = CAL_CYCLES_LONG; - } else q->exec_cksum = cksum; + } else { + + q->exec_cksum = cksum; + memcpy(first_trace, trace_bits, MAP_SIZE); + + } } @@ -2538,9 +2643,15 @@ /* Mark variable paths. */ - if (var_detected && !q->var_behavior) { - mark_as_variable(q); - queued_variable++; + if (var_detected) { + + var_byte_count = count_bytes(var_bytes); + + if (!q->var_behavior) { + mark_as_variable(q); + queued_variable++; + } + } stage_name = old_sn; @@ -3129,6 +3240,7 @@ unique_crashes++; last_crash_time = get_cur_time(); + last_crash_execs = total_execs; break; @@ -3226,9 +3338,9 @@ /* Update stats file for unattended monitoring. */ -static void write_stats_file(double bitmap_cvg, double eps) { +static void write_stats_file(double bitmap_cvg, double stability, double eps) { - static double last_bcvg, last_eps; + static double last_bcvg, last_stab, last_eps; u8* fn = alloc_printf("%s/fuzzer_stats", out_dir); s32 fd; @@ -3247,46 +3359,51 @@ /* Keep last values in case we're called from another context where exec/sec stats and such are not readily available. */ - if (!bitmap_cvg && !eps) { + if (!bitmap_cvg && !stability && !eps) { bitmap_cvg = last_bcvg; + stability = last_stab; eps = last_eps; } else { last_bcvg = bitmap_cvg; + last_stab = stability; last_eps = eps; } - fprintf(f, "start_time : %llu\n" - "last_update : %llu\n" - "fuzzer_pid : %u\n" - "cycles_done : %llu\n" - "execs_done : %llu\n" - "execs_per_sec : %0.02f\n" - "paths_total : %u\n" - "paths_favored : %u\n" - "paths_found : %u\n" - "paths_imported : %u\n" - "max_depth : %u\n" - "cur_path : %u\n" - "pending_favs : %u\n" - "pending_total : %u\n" - "variable_paths : %u\n" - "bitmap_cvg : %0.02f%%\n" - "unique_crashes : %llu\n" - "unique_hangs : %llu\n" - "last_path : %llu\n" - "last_crash : %llu\n" - "last_hang : %llu\n" - "exec_timeout : %u\n" - "afl_banner : %s\n" - "afl_version : " VERSION "\n" - "command_line : %s\n", + fprintf(f, "start_time : %llu\n" + "last_update : %llu\n" + "fuzzer_pid : %u\n" + "cycles_done : %llu\n" + "execs_done : %llu\n" + "execs_per_sec : %0.02f\n" + "paths_total : %u\n" + "paths_favored : %u\n" + "paths_found : %u\n" + "paths_imported : %u\n" + "max_depth : %u\n" + "cur_path : %u\n" + "pending_favs : %u\n" + "pending_total : %u\n" + "variable_paths : %u\n" + "stability : %0.02f%%\n" + "bitmap_cvg : %0.02f%%\n" + "unique_crashes : %llu\n" + "unique_hangs : %llu\n" + "last_path : %llu\n" + "last_crash : %llu\n" + "last_hang : %llu\n" + "execs_since_crash : %llu\n" + "exec_timeout : %u\n" + "afl_banner : %s\n" + "afl_version : " VERSION "\n" + "command_line : %s\n", start_time / 1000, get_cur_time() / 1000, getpid(), queue_cycle ? (queue_cycle - 1) : 0, total_execs, eps, queued_paths, queued_favored, queued_discovered, queued_imported, max_depth, current_entry, pending_favored, pending_not_fuzzed, - queued_variable, bitmap_cvg, unique_crashes, unique_hangs, - last_path_time / 1000, last_crash_time / 1000, - last_hang_time / 1000, exec_tmout, use_banner, orig_cmdline); + queued_variable, stability, bitmap_cvg, unique_crashes, + unique_hangs, last_path_time / 1000, last_crash_time / 1000, + last_hang_time / 1000, total_execs - last_crash_execs, + exec_tmout, use_banner, orig_cmdline); /* ignore errors */ fclose(f); @@ -3709,7 +3826,7 @@ static u64 last_stats_ms, last_plot_ms, last_ms, last_execs; static double avg_exec; - double t_byte_ratio; + double t_byte_ratio, stab_ratio; u64 cur_ms; u32 t_bytes, t_bits; @@ -3762,12 +3879,17 @@ t_bytes = count_non_255_bytes(virgin_bits); t_byte_ratio = ((double)t_bytes * 100) / MAP_SIZE; + if (t_bytes) + stab_ratio = 100 - ((double)var_byte_count) * 100 / t_bytes; + else + stab_ratio = 100; + /* Roughly every minute, update fuzzer stats and save auto tokens. */ if (cur_ms - last_stats_ms > STATS_UPDATE_SEC * 1000) { last_stats_ms = cur_ms; - write_stats_file(t_byte_ratio, avg_exec); + write_stats_file(t_byte_ratio, stab_ratio, avg_exec); save_auto(); write_bitmap(); @@ -3929,8 +4051,8 @@ SAYF(bV bSTOP " now processing : " cRST "%-17s " bSTG bV bSTOP, tmp); - - sprintf(tmp, "%s (%0.02f%%)", DI(t_bytes), t_byte_ratio); + sprintf(tmp, "%0.02f%% / %0.02f%%", ((double)queue_cur->bitmap_size) * + 100 / MAP_SIZE, t_byte_ratio); SAYF(" map density : %s%-21s " bSTG bV "\n", t_byte_ratio > 70 ? cLRD : ((t_bytes < 200 && !dumb_mode) ? cPIN : cRST), tmp); @@ -4074,9 +4196,14 @@ DI(stage_finds[STAGE_HAVOC]), DI(stage_cycles[STAGE_HAVOC]), DI(stage_finds[STAGE_SPLICE]), DI(stage_cycles[STAGE_SPLICE])); - SAYF(bV bSTOP " havoc : " cRST "%-37s " bSTG bV bSTOP - " variable : %s%-10s " bSTG bV "\n", tmp, queued_variable ? cLRD : cRST, - no_var_check ? (u8*)"n/a" : DI(queued_variable)); + SAYF(bV bSTOP " havoc : " cRST "%-37s " bSTG bV bSTOP, tmp); + + if (t_bytes) sprintf(tmp, "%0.02f%%", stab_ratio); + else strcpy(tmp, "n/a"); + + SAYF(" stability : %s%-10s " bSTG bV "\n", (stab_ratio < 85 && var_byte_count > 40) + ? cLRD : ((queued_variable && (!persistent_mode || var_byte_count > 20)) + ? cMGN : cRST), tmp); if (!bytes_trim_out) { @@ -4132,10 +4259,10 @@ #ifdef HAVE_AFFINITY - if (use_affinity) { + if (cpu_aff >= 0) { - SAYF(SP10 cGRA "[cpu@%02u:%s%3u%%" cGRA "]\r" cRST, - MIN(cpu_aff_child, 99), cpu_color, + SAYF(SP10 cGRA "[cpu%03u:%s%3u%%" cGRA "]\r" cRST, + MIN(cpu_aff, 999), cpu_color, MIN(cur_utilization, 999)); } else { @@ -4144,6 +4271,7 @@ cpu_color, MIN(cur_utilization, 999)); } + #else SAYF(SP10 cGRA " [cpu:%s%3u%%" cGRA "]\r" cRST, @@ -4886,6 +5014,12 @@ if (skip_deterministic || queue_cur->was_fuzzed || queue_cur->passed_det) goto havoc_stage; + /* Skip deterministic fuzzing if exec path checksum puts this out of scope + for this master instance. */ + + if (master_max && (queue_cur->exec_cksum % master_max) != master_id - 1) + goto havoc_stage; + /********************************************* * SIMPLE BITFLIP (+dictionary construction) * *********************************************/ @@ -5055,7 +5189,7 @@ /* Effector map setup. These macros calculate: EFF_APOS - position of a particular file offset in the map. - EFF_ALEN - length of an map with a particular number of bytes. + EFF_ALEN - length of a map with a particular number of bytes. EFF_SPAN_ALEN - map span for a sequence of bytes. */ @@ -6486,8 +6620,14 @@ path = alloc_printf("%s/%s", qd_path, qd_ent->d_name); + /* Allow this to fail in case the other fuzzer is resuming or so... */ + fd = open(path, O_RDONLY); - if (fd < 0) PFATAL("Unable to open '%s'", path); + + if (fd < 0) { + ck_free(path); + continue; + } if (fstat(fd, &st)) PFATAL("fstat() failed"); @@ -6721,7 +6861,7 @@ OKF(cPIN "Persistent mode binary detected."); setenv(PERSIST_ENV_VAR, "1", 1); - no_var_check = 1; + persistent_mode = 1; } else if (getenv("AFL_PERSISTENT")) { @@ -6838,9 +6978,6 @@ " -T text - text banner to show on the screen\n" " -M / -S id - distributed mode (see parallel_fuzzing.txt)\n" -#ifdef HAVE_AFFINITY - " -Z core_id - set CPU affinity (see perf_tips.txt)\n" -#endif /* HAVE_AFFINITY */ " -C - crash exploration mode (the peruvian rabbit thing)\n\n" "For additional tips, please consult %s/README.\n\n", @@ -7138,27 +7275,27 @@ #else - if (!cpu_core_count) { +#ifdef HAVE_AFFINITY - /* On Linux, a simple way is to look at /proc/stat, especially since we'd - be parsing it anyway for other reasons later on. But do this only if - cpu_core_count hasn't been obtained before as a result of specifying - -Z. */ + cpu_core_count = sysconf(_SC_NPROCESSORS_ONLN); - FILE* f = fopen("/proc/stat", "r"); - u8 tmp[1024]; +#else - if (!f) return; + FILE* f = fopen("/proc/stat", "r"); + u8 tmp[1024]; - while (fgets(tmp, sizeof(tmp), f)) - if (!strncmp(tmp, "cpu", 3) && isdigit(tmp[3])) cpu_core_count++; + if (!f) return; - fclose(f); - } + while (fgets(tmp, sizeof(tmp), f)) + if (!strncmp(tmp, "cpu", 3) && isdigit(tmp[3])) cpu_core_count++; + + fclose(f); + +#endif /* ^HAVE_AFFINITY */ #endif /* ^(__APPLE__ || __FreeBSD__ || __OpenBSD__) */ - if (cpu_core_count) { + if (cpu_core_count > 0) { cur_runnable = (u32)get_runnable_processes(); @@ -7187,17 +7324,12 @@ } - } else WARNF("Unable to figure out the number of CPU cores."); + } else { -#ifdef HAVE_AFFINITY + cpu_core_count = 0; + WARNF("Unable to figure out the number of CPU cores."); - if (use_affinity) - OKF("Using specified CPU affinity: main = %u, child = %u", - cpu_aff_main, cpu_aff_child); - else if (cpu_core_count > 1) - OKF(cBRI "Try setting CPU affinity (-Z) for a performance boost!" cRST); - -#endif /* HAVE_AFFINITY */ + } } @@ -7483,18 +7615,23 @@ u8 *extras_dir = 0; u8 mem_limit_given = 0; u8 exit_1 = !!getenv("AFL_BENCH_JUST_ONE"); - char** use_argv; + struct timeval tv; + struct timezone tz; + SAYF(cCYA "afl-fuzz " cBRI VERSION cRST " by <lcamtuf@google.com>\n"); doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH; - while ((opt = getopt(argc, argv, "+i:o:f:m:t:T:dnCB:S:M:x:QZ:")) > 0) + gettimeofday(&tv, &tz); + srandom(tv.tv_sec ^ tv.tv_usec ^ getpid()); + + while ((opt = getopt(argc, argv, "+i:o:f:m:t:T:dnCB:S:M:x:Q")) > 0) switch (opt) { - case 'i': + case 'i': /* input dir */ if (in_dir) FATAL("Multiple -i options not supported"); in_dir = optarg; @@ -7509,12 +7646,30 @@ out_dir = optarg; break; - case 'M': + case 'M': { /* master sync ID */ - force_deterministic = 1; - /* Fall through */ + u8* c; - case 'S': /* sync ID */ + if (sync_id) FATAL("Multiple -S or -M options not supported"); + sync_id = optarg; + + if ((c = strchr(sync_id, ':'))) { + + *c = 0; + + if (sscanf(c + 1, "%u/%u", &master_id, &master_max) != 2 || + !master_id || !master_max || master_id > master_max || + master_max > 1000000) FATAL("Bogus master ID passed to -M"); + + } + + force_deterministic = 1; + + } + + break; + + case 'S': if (sync_id) FATAL("Multiple -S or -M options not supported"); sync_id = optarg; @@ -7526,13 +7681,13 @@ out_file = optarg; break; - case 'x': + case 'x': /* dictionary */ if (extras_dir) FATAL("Multiple -x options not supported"); extras_dir = optarg; break; - case 't': { + case 't': { /* timeout */ u8 suffix = 0; @@ -7549,7 +7704,7 @@ } - case 'm': { + case 'm': { /* mem limit */ u8 suffix = 'M'; @@ -7586,43 +7741,14 @@ break; -#ifdef HAVE_AFFINITY - - case 'Z': { - - s32 i; - - if (use_affinity) FATAL("Multiple -Z options not supported"); - use_affinity = 1; - - cpu_core_count = sysconf(_SC_NPROCESSORS_ONLN); - - i = sscanf(optarg, "%u,%u", &cpu_aff_main, &cpu_aff_child); - - if (i < 1 || cpu_aff_main >= cpu_core_count) - FATAL("Bogus primary core ID passed to -Z (expected 0-%u)", - cpu_core_count - 1); - - if (i == 1) cpu_aff_child = cpu_aff_main; - - if (cpu_aff_child >= cpu_core_count) - FATAL("Bogus secondary core ID passed to -Z (expected 0-%u)", - cpu_core_count - 1); - - break; - - } - -#endif /* HAVE_AFFINITY */ - - case 'd': + case 'd': /* skip deterministic */ if (skip_deterministic) FATAL("Multiple -d options not supported"); skip_deterministic = 1; use_splicing = 1; break; - case 'B': + case 'B': /* load bitmap */ /* This is a secret undocumented option! It is useful if you find an interesting test case during a normal fuzzing process, and want @@ -7641,26 +7767,26 @@ read_bitmap(in_bitmap); break; - case 'C': + case 'C': /* crash mode */ if (crash_mode) FATAL("Multiple -C options not supported"); crash_mode = FAULT_CRASH; break; - case 'n': + case 'n': /* dumb mode */ if (dumb_mode) FATAL("Multiple -n options not supported"); if (getenv("AFL_DUMB_FORKSRV")) dumb_mode = 2; else dumb_mode = 1; break; - case 'T': + case 'T': /* banner */ if (use_banner) FATAL("Multiple -T options not supported"); use_banner = optarg; break; - case 'Q': + case 'Q': /* QEMU mode */ if (qemu_mode) FATAL("Multiple -Q options not supported"); qemu_mode = 1; @@ -7680,10 +7806,6 @@ setup_signal_handlers(); check_asan_opts(); -#ifdef HAVE_AFFINITY - if (use_affinity) set_cpu_affinity(cpu_aff_main); -#endif /* HAVE_AFFINITY */ - if (sync_id) fix_up_sync(); if (!strcmp(in_dir, out_dir)) @@ -7698,14 +7820,18 @@ if (getenv("AFL_NO_FORKSRV")) no_forkserver = 1; if (getenv("AFL_NO_CPU_RED")) no_cpu_meter_red = 1; - if (getenv("AFL_NO_VAR_CHECK")) no_var_check = 1; if (getenv("AFL_SHUFFLE_QUEUE")) shuffle_queue = 1; if (dumb_mode == 2 && no_forkserver) FATAL("AFL_DUMB_FORKSRV and AFL_NO_FORKSRV are mutually exclusive"); + if (getenv("AFL_PRELOAD")) { + setenv("LD_PRELOAD", getenv("AFL_PRELOAD"), 1); + setenv("DYLD_INSERT_LIBRARIES", getenv("AFL_PRELOAD"), 1); + } + if (getenv("AFL_LD_PRELOAD")) - setenv("LD_PRELOAD", getenv("AFL_LD_PRELOAD"), 1); + FATAL("Use AFL_PRELOAD instead of AFL_LD_PRELOAD"); save_cmdline(argc, argv); @@ -7714,11 +7840,17 @@ check_if_tty(); get_core_count(); + +#ifdef HAVE_AFFINITY + bind_to_free_cpu(); +#endif /* HAVE_AFFINITY */ + check_crash_handling(); check_cpu_governor(); setup_post(); setup_shm(); + init_count_class16(); setup_dirs_fds(); read_testcases(); @@ -7751,7 +7883,7 @@ seek_to = find_start_position(); - write_stats_file(0, 0); + write_stats_file(0, 0, 0); save_auto(); if (stop_soon) goto stop_fuzzing; @@ -7827,13 +7959,13 @@ if (queue_cur) show_stats(); write_bitmap(); - write_stats_file(0, 0); + write_stats_file(0, 0, 0); save_auto(); stop_fuzzing: SAYF(CURSOR_SHOW cLRD "\n\n+++ Testing aborted %s +++\n" cRST, - stop_soon == 2 ? "programatically" : "by user"); + stop_soon == 2 ? "programmatically" : "by user"); /* Running for more than 30 minutes but still doing first cycle? */
diff --git a/third_party/afl/src/afl-gcc.c b/third_party/afl/src/afl-gcc.c index b6cbc05..1a588da 100644 --- a/third_party/afl/src/afl-gcc.c +++ b/third_party/afl/src/afl-gcc.c
@@ -116,7 +116,7 @@ u8 m32_set = 0; #endif - cc_params = ck_alloc((argc + 64) * sizeof(u8*)); + cc_params = ck_alloc((argc + 128) * sizeof(u8*)); name = strrchr(argv[0], '/'); if (!name) name = argv[0]; else name++; @@ -271,6 +271,16 @@ } + if (getenv("AFL_NO_BUILTIN")) { + + cc_params[cc_par_cnt++] = "-fno-builtin-strcmp"; + cc_params[cc_par_cnt++] = "-fno-builtin-strncmp"; + cc_params[cc_par_cnt++] = "-fno-builtin-strcasecmp"; + cc_params[cc_par_cnt++] = "-fno-builtin-strncasecmp"; + cc_params[cc_par_cnt++] = "-fno-builtin-memcmp"; + + } + cc_params[cc_par_cnt] = NULL; }
diff --git a/third_party/afl/src/afl-showmap.c b/third_party/afl/src/afl-showmap.c index cd66772e..bb96002 100644 --- a/third_party/afl/src/afl-showmap.c +++ b/third_party/afl/src/afl-showmap.c
@@ -73,21 +73,17 @@ /* Classify tuple counts. Instead of mapping to individual bits, as in afl-fuzz.c, we map to more user-friendly numbers between 1 and 8. */ -#define AREP4(_sym) (_sym), (_sym), (_sym), (_sym) -#define AREP8(_sym) AREP4(_sym), AREP4(_sym) -#define AREP16(_sym) AREP8(_sym), AREP8(_sym) -#define AREP32(_sym) AREP16(_sym), AREP16(_sym) -#define AREP64(_sym) AREP32(_sym), AREP32(_sym) -#define AREP128(_sym) AREP64(_sym), AREP64(_sym) +static const u8 count_class_lookup[256] = { -static u8 count_class_lookup[256] = { - - /* 0 - 3: 4 */ 0, 1, 2, 3, - /* 4 - 7: +4 */ AREP4(4), - /* 8 - 15: +8 */ AREP8(5), - /* 16 - 31: +16 */ AREP16(6), - /* 32 - 127: +96 */ AREP64(7), AREP32(7), - /* 128+: +128 */ AREP128(8) + [0] = 0, + [1] = 1, + [2] = 2, + [3] = 3, + [4 ... 7] = 4, + [8 ... 15] = 5, + [16 ... 31] = 6, + [32 ... 127] = 7, + [128 ... 255] = 8 }; @@ -346,8 +342,10 @@ "allocator_may_return_null=1:" "msan_track_origins=0", 0); - if (getenv("AFL_LD_PRELOAD")) - setenv("LD_PRELOAD", getenv("AFL_LD_PRELOAD"), 1); + if (getenv("AFL_PRELOAD")) { + setenv("LD_PRELOAD", getenv("AFL_PRELOAD"), 1); + setenv("DYLD_INSERT_LIBRARIES", getenv("AFL_PRELOAD"), 1); + } }
diff --git a/third_party/afl/src/afl-tmin.c b/third_party/afl/src/afl-tmin.c index 1a0cbb8..912acae 100644 --- a/third_party/afl/src/afl-tmin.c +++ b/third_party/afl/src/afl-tmin.c
@@ -81,21 +81,17 @@ /* Classify tuple counts. This is a slow & naive version, but good enough here. */ -#define AREP4(_sym) (_sym), (_sym), (_sym), (_sym) -#define AREP8(_sym) AREP4(_sym), AREP4(_sym) -#define AREP16(_sym) AREP8(_sym), AREP8(_sym) -#define AREP32(_sym) AREP16(_sym), AREP16(_sym) -#define AREP64(_sym) AREP32(_sym), AREP32(_sym) -#define AREP128(_sym) AREP64(_sym), AREP64(_sym) +static const u8 count_class_lookup[256] = { -static u8 count_class_lookup[256] = { - - /* 0 - 3: 4 */ 0, 1, 2, 4, - /* 4 - 7: +4 */ AREP4(8), - /* 8 - 15: +8 */ AREP8(16), - /* 16 - 31: +16 */ AREP16(32), - /* 32 - 127: +96 */ AREP64(64), AREP32(64), - /* 128+: +128 */ AREP128(128) + [0] = 0, + [1] = 1, + [2] = 2, + [3] = 4, + [4 ... 7] = 8, + [8 ... 15] = 16, + [16 ... 31] = 32, + [32 ... 127] = 64, + [128 ... 255] = 128 }; @@ -702,8 +698,10 @@ "allocator_may_return_null=1:" "msan_track_origins=0", 0); - if (getenv("AFL_LD_PRELOAD")) - setenv("LD_PRELOAD", getenv("AFL_LD_PRELOAD"), 1); + if (getenv("AFL_PRELOAD")) { + setenv("LD_PRELOAD", getenv("AFL_PRELOAD"), 1); + setenv("DYLD_INSERT_LIBRARIES", getenv("AFL_PRELOAD"), 1); + } }
diff --git a/third_party/afl/src/config.h b/third_party/afl/src/config.h index 036bb6c..88ccb90 100644 --- a/third_party/afl/src/config.h +++ b/third_party/afl/src/config.h
@@ -19,6 +19,10 @@ #include "types.h" +/* Version string: */ + +#define VERSION "2.30b" + /****************************************************** * * * Settings that may be of interest to power users: * @@ -57,13 +61,9 @@ /* Number of calibration cycles per every new test case (and for test cases that show variable behavior): */ -#define CAL_CYCLES 10 +#define CAL_CYCLES 8 #define CAL_CYCLES_LONG 40 -/* The same, but when AFL_NO_VAR_CHECK is set in the environment: */ - -#define CAL_CYCLES_NO_VAR 4 - /* Number of subsequent hangs before abandoning an input file: */ #define HANG_LIMIT 250
diff --git a/third_party/afl/src/docs/ChangeLog b/third_party/afl/src/docs/ChangeLog index 3b453f7..1501a50 100644 --- a/third_party/afl/src/docs/ChangeLog +++ b/third_party/afl/src/docs/ChangeLog
@@ -13,10 +13,172 @@ sending a mail to <afl-users+subscribe@googlegroups.com>. Not sure if you should upgrade? The lowest currently recommended version -is 2.07b. If you're stuck on an earlier release, it's strongly advisable +is 2.23b. If you're stuck on an earlier release, it's strongly advisable to get on with the times. -------------- +Version 2.30b: +-------------- + + - Made minor improvements to persistent mode to avoid the remote + possibility of "no instrumentation detected" issues with very low + instrumentation densities. + + - Fixed a minor glitch with a leftover process in persistent mode. + Reported by Jakub Wilk and Daniel Stender. + + - Made persistent mode bitmaps a bit more consistent and adjusted the way + this is shown in the UI, especially in persistent mode. + +-------------- +Version 2.29b: +-------------- + + - Made a minor #include fix to llvm_mode. Suggested by Jonathan Metzman. + + - Made cosmetic updates to the docs. + +-------------- +Version 2.28b: +-------------- + + - Added "life pro tips" to docs/. + + - Moved testcases/_extras/ to dictionaries/ for visibility. + + - Made minor improvements to install scripts. + + - Added an important safety tip. + +-------------- +Version 2.27b: +-------------- + + - Added libtokencap, a simple feature to intercept strcmp / memcmp and + generate dictionary entries that can help extend coverage. + + - Moved libdislocator to its own dir, added README. + + - The demo in experimental/instrumented_cmp is no more. + +-------------- +Version 2.26b: +-------------- + + - Made a fix for libdislocator.so to compile on MacOS X. + + - Added support for DYLD_INSERT_LIBRARIES. + + - Renamed AFL_LD_PRELOAD to AFL_PRELOAD. + +-------------- +Version 2.25b: +-------------- + + - Made some cosmetic updates to libdislocator.so, renamed one env + variable. + +-------------- +Version 2.24b: +-------------- + + - Added libdislocator.so, an experimental, abusive allocator. Try + it out with AFL_LD_PRELOAD=/path/to/libdislocator.so when running + afl-fuzz. + +-------------- +Version 2.23b: +-------------- + + - Improved the stability metric for persistent mode binaries. Problem + spotted by Kurt Roeckx. + + - Made a related improvement that may bring the metric to 100% for those + targets. + +-------------- +Version 2.22b: +-------------- + + - Mentioned the potential conflicts between MSAN / ASAN and FORTIFY_SOURCE. + There is no automated check for this, since some distros may implicitly + set FORTIFY_SOURCE outside of the compiler's argv[]. + + - Populated the support for AFL_LD_PRELOAD to all companion tools. + + - Made a change to the handling of ./afl-clang-fast -v. Spotted by + Jan Kneschke. + +-------------- +Version 2.21b: +-------------- + + - Added some crash reporting notes for Solaris in docs/INSTALL, as + investigated by Martin Carpenter. + + - Fixed a minor UI mix-up with havoc strategy stats. + +-------------- +Version 2.20b: +-------------- + + - Revamped the handling of variable paths, replacing path count with a + "stability" score to give users a much better signal. Based on the + feedback from Vegard Nossum. + + - Made a stability improvement to the syncing behavior with resuming + fuzzers. Based on the feedback from Vegard. + + - Changed the UI to include current input bitmap density along with + total density. Ditto. + + - Added experimental support for parallelizing -M. + +-------------- +Version 2.19b: +-------------- + + - Made a fix to make sure that auto CPU binding happens at non-overlapping + times. + +-------------- +Version 2.18b: +-------------- + + - Made several performance improvements to has_new_bits() and + classify_counts(). This should offer a robust performance bump with + fast targets. + +-------------- +Version 2.17b: +-------------- + + - Killed the error-prone and manual -Z option. On Linux, AFL will now + automatically bind to the first free core (or complain if there are no + free cores left). + + - Made some doc updates along these lines. + +-------------- +Version 2.16b: +-------------- + + - Improved support for older versions of clang (hopefully without + breaking anything). + + - Moved version data from Makefile to config.h. Suggested by + Jonathan Metzman. + +-------------- +Version 2.15b: +-------------- + + - Added a README section on looking for non-crashing bugs. + + - Added license data to several boring files. Contributed by + Jonathan Metzman. + +-------------- Version 2.14b: -------------- @@ -1466,7 +1628,7 @@ - Refactored the code slightly to make more frequent updates to fuzzer_stats and to provide more detail about synchronization. - - Added a fflush(stdout) call for non-tty operation, as requested by + - Added an fflush(stdout) call for non-tty operation, as requested by Joonas Kuorilehto. - Added some detail to fuzzer_stats for parity with plot_file.
diff --git a/third_party/afl/src/docs/INSTALL b/third_party/afl/src/docs/INSTALL index 6c44b922..fa8a34c 100644 --- a/third_party/afl/src/docs/INSTALL +++ b/third_party/afl/src/docs/INSTALL
@@ -140,11 +140,13 @@ Do *not* specify --with-as=/usr/gnu/bin/as - this will produce a GCC binary that ignores the -B flag and you will be back to square one. -If you have system-wide crash reporting enabled, you may run into problems -similar to the gotchas for Linux and MacOS X, but I have not verified this. -More information about AppCrash can be found here: +Note that Solaris reportedly comes withe crash reporting enabled, which causes +problems with crashes being misinterpreted as hangs, similarly to the gotchas +for Linux and MacOS X. AFL does not auto-detect crash reporting on this +particular platform, but you may need to run the following command: - http://www.oracle.com/technetwork/server-storage/solaris10/app-crash-142906.html +$ coreadm -d global -d global-setid -d process -d proc-setid \ + -d kzone -d log User emulation mode of QEMU is not available on Solaris, so black-box instrumentation mode (-Q) will not work.
diff --git a/third_party/afl/src/docs/QuickStartGuide.txt b/third_party/afl/src/docs/QuickStartGuide.txt index 59752e6..abe7032 100644 --- a/third_party/afl/src/docs/QuickStartGuide.txt +++ b/third_party/afl/src/docs/QuickStartGuide.txt
@@ -14,7 +14,8 @@ checksum verification code, too. The program must crash properly when a fault is encountered. Watch out for - custom SIGSEGV or SIGABRT handlers and background processes. + custom SIGSEGV or SIGABRT handlers and background processes. For tips on + detecting non-crashing flaws, see section 11 in docs/README. 3) Compile the program / library to be fuzzed using afl-gcc. A common way to do this would be: @@ -26,7 +27,7 @@ 4) Get a small but valid input file that makes sense to the program. When fuzzing verbose syntax (SQL, HTTP, etc), create a dictionary as described in - testcases/README.testcases, too. + dictionaries/README.dictionaries, too. 5) If the program reads from stdin, run 'afl-fuzz' like so:
diff --git a/third_party/afl/src/docs/README b/third_party/afl/src/docs/README index 642e57b..bac9fee 100644 --- a/third_party/afl/src/docs/README +++ b/third_party/afl/src/docs/README
@@ -115,7 +115,8 @@ Setting AFL_HARDEN=1 when calling 'make' will cause the CC wrapper to automatically enable code hardening options that make it easier to detect -simple memory bugs. +simple memory bugs. Libdislocator, a helper library included with AFL (see +libdislocator/README.dislocator) can help uncover heap corruption issues, too. PS. ASAN users are advised to review notes_for_asan.txt file for important caveats. @@ -276,8 +277,10 @@ http://lcamtuf.blogspot.com/2015/01/afl-fuzz-making-up-grammar-with.html To use this feature, you first need to create a dictionary in one of the two -formats discussed in testcases/README.testcases; and then point the fuzzer to -it via the -x option in the command line. +formats discussed in dictionaries/README.dictionaries; and then point the fuzzer +to it via the -x option in the command line. + +(Several common dictionaries are already provided in that subdirectory, too.) There is no way to provide more structured descriptions of the underlying syntax, but the fuzzer will likely figure out some of this based on the @@ -290,6 +293,10 @@ very closely during deterministic byte flips. This works for some types of parsers and grammars, but isn't nearly as good as the -x mode. +If a dictionary is really hard to come by, another option is to let AFL run +for a while, and then use the token capture library that comes as a companion +utility with AFL. For that, see libtokencap/README.tokencap. + 10) Crash triage ---------------- @@ -336,7 +343,31 @@ insights into complex file formats. More info about its operation can be found near the end of technical_details.txt. -11) Common-sense risks +11) Going beyond crashes +------------------------ + +Fuzzing is a wonderful and underutilized technique for discovering non-crashing +design and implementation errors, too. Quite a few interesting bugs have been +found by modifying the target programs to call abort() when, say: + + - Two bignum libraries produce different outputs when given the same + fuzzer-generated input, + + - An image library produces different outputs when asked to decode the same + input image several times in a row, + + - A serialization / deserialization library fails to produce stable outputs + when iteratively serializing and deserializing fuzzer-supplied data, + + - A compression library produces an output inconsistent with the input file + when asked to compress and then decompress a particular blob. + +Implementing these or similar sanity checks usually takes very little time; +if you are the maintainer of a particular package, you can make this code +conditional with #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION (a flag also +shared with libfuzzer) or #ifdef __AFL_COMPILER (this one is just for AFL). + +12) Common-sense risks ---------------------- Please keep in mind that, similarly to many other computationally-intensive @@ -364,7 +395,7 @@ $ iostat -d 3 -x -k [...optional disk ID...] -12) Known limitations & areas for improvement +13) Known limitations & areas for improvement --------------------------------------------- Here are some of the most important caveats for AFL: @@ -400,9 +431,12 @@ - AFL doesn't output human-readable coverage data. If you want to monitor coverage, use afl-cov from Michael Rash: https://github.com/mrash/afl-cov + - Occasionally, sentient machines rise against their creators. If this + happens to you, please consult http://lcamtuf.coredump.cx/prep/. + Beyond this, see INSTALL for platform-specific tips. -13) Special thanks +14) Special thanks ------------------ Many of the improvements to afl-fuzz wouldn't be possible without feedback, @@ -439,11 +473,13 @@ Guillaume Endignoux ilovezfs Daniel Godas-Lopez Franjo Ivancic Austin Seipp Daniel Komaromy - Daniel Binderman + Daniel Binderman Jonathan Metzman + Vegard Nossum Jan Kneschke + Kurt Roeckx Thank you! -14) Contact +15) Contact ----------- Questions? Concerns? Bug reports? The author can be usually reached at
diff --git a/third_party/afl/src/docs/env_variables.txt b/third_party/afl/src/docs/env_variables.txt index 16de034..fc2a610 100644 --- a/third_party/afl/src/docs/env_variables.txt +++ b/third_party/afl/src/docs/env_variables.txt
@@ -52,6 +52,9 @@ Setting AFL_INST_RATIO to 0 is a valid choice. This will instrument only the transitions between function entry points, but not individual branches. + - AFL_NO_BUILTIN causes the compiler to generate code suitable for use with + libtokencap.so (but perhaps running a bit slower than without the flag). + - TMPDIR is used by afl-as for temporary files; if this variable is not set, the tool defaults to /tmp. @@ -99,16 +102,15 @@ normally done when starting up the forkserver and causes a pretty significant performance drop. - - Setting AFL_NO_VAR_CHECK skips the detection of variable test cases, - greatly speeding up session resumption and path discovery for complex - multi-threaded apps (but depriving you of a potentially useful signal - in more orderly programs). - - AFL_EXIT_WHEN_DONE causes afl-fuzz to terminate when all existing paths have been fuzzed and there were no new finds for a while. This would be normally indicated by the cycle counter in the UI turning green. May be convenient for some types of automated jobs. + - Setting AFL_NO_AFFINITY disables attempts to bind to a specific CPU core + on Linux systems. This slows things down, but lets you run more instances + of afl-fuzz than would be prudent (if you really want to). + - AFL_SKIP_CRASHES causes AFL to tolerate crashing files in the input queue. This can help with rare situations where a program crashes only intermittently, but it's not really recommended under normal operating @@ -139,15 +141,16 @@ - In QEMU mode (-Q), AFL_PATH will be searched for afl-qemu-trace. - - Setting AFL_LD_PRELOAD causes AFL to set LD_PRELOAD for the target binary - without disrupting the afl-fuzz process itself. + - Setting AFL_PRELOAD causes AFL to set LD_PRELOAD for the target binary + without disrupting the afl-fuzz process itself. This is useful, among other + things, for bootstrapping libdislocator.so. - If you are Jakub, you may need AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES. Others need not apply. - Benchmarking only: AFL_BENCH_JUST_ONE causes the fuzzer to exit after processing the first queue entry; and AFL_BENCH_UNTIL_CRASH causes it to - exit when first crash is found. + exit soon after the first crash is found. 4) Settings for afl-qemu-trace ------------------------------ @@ -184,7 +187,29 @@ searched for afl-qemu-trace. In addition to this, TMPDIR may be used if a temporary file can't be created in the current working directory. -7) Third-party variables set by afl-fuzz & other tools +7) Settings for libdislocator.so +-------------------------------- + +The library honors three environmental variables: + + - AFL_LD_LIMIT_MB caps the size of the maximum heap usage permitted by the + library, in megabytes. The default value is 1 GB. Once this is exceeded, + allocations will return NULL. + + - AFL_LD_HARD_FAIL alters the behavior by calling abort() on excessive + allocations, thus causing what AFL would perceive as a crash. Useful for + programs that are supposed to maintain a specific memory footprint. + + - AFL_LD_VERBOSE causes the library to output some diagnostic messages + that may be useful for pinpointing the cause of any observed issues. + +8) Settings for libtokencap.so +------------------------------ + +This library accepts AFL_TOKEN_FILE to indicate the location to which the +discovered tokens should be written. + +9) Third-party variables set by afl-fuzz & other tools ------------------------------------------------------ Several variables are not directly interpreted by afl-fuzz, but are set to @@ -215,5 +240,6 @@ msan_track_origins=0 allocator_may_return_null=1 - Be sure to include the first one when customizing anything, since MSAN - doesn't call abort() on error, and we need a way to detect faults. + Be sure to include the first one when customizing anything, since some + MSAN versions don't call abort() on error, and we need a way to detect + faults.
diff --git a/third_party/afl/src/docs/life_pro_tips.txt b/third_party/afl/src/docs/life_pro_tips.txt new file mode 100644 index 0000000..df053a8 --- /dev/null +++ b/third_party/afl/src/docs/life_pro_tips.txt
@@ -0,0 +1,123 @@ +# =================== +# AFL "Life Pro Tips" +# =================== +# +# Bite-sized advice for those who understand the basics, but can't be bothered +# to read or memorize every other piece of documentation for AFL. +# + +% + +Get more bang for your buck by using fuzzing dictionaries. +See dictionaries/README.dictionaries to learn how. + +% + +You can get the most out of your hardware by parallelizing AFL jobs. +See docs/parallel_fuzzing.txt for step-by-step tips. + +% + +Improve the odds of spotting memory corruption bugs with libdislocator.so! +It's easy. Consult libdislocator/README.dislocator for usage tips. + +% + +Want to understand how your target parses a particular input file? +Try the bundled afl-analyze tool; it's got colors and all! + +% + +You can visually monitor the progress of your fuzzing jobs. +Run the bundled afl-plot utility to generate browser-friendly graphs. + +% + +Need to monitor AFL jobs programmatically? Check out the fuzzer_stats file +in the AFL output dir or try afl-whatsup. + +% + +Puzzled by something showing up in red or purple in the AFL UI? +It could be important - consult docs/status_screen.txt right away! + +% + +Know your target? Convert it to persistent mode for a huge performance gain! +Consult section #5 in llvm_mode/README.llvm for tips. + +% + +Using clang? Check out llvm_mode/ for a faster alternative to afl-gcc! + +% + +Did you know that AFL can fuzz closed-source or cross-platform binaries? +Check out qemu_mode/README.qemu for more. + +% + +Did you know that afl-fuzz can minimize any test case for you? +Try the bundled afl-tmin tool - and get small repro files fast! + +% + +Not sure if a crash is exploitable? AFL can help you figure it out. Specify +-C to enable the peruvian were-rabbit mode. See section #10 in README for more. + +% + +Trouble dealing with a machine uprising? Relax, we've all been there. +Find essential survival tips at http://lcamtuf.coredump.cx/prep/. + +% + +AFL-generated corpora can be used to power other testing processes. +See section #2 in README for inspiration - it tends to pay off! + +% + +Want to automatically spot non-crashing memory handling bugs? +Try running an AFL-generated corpus through ASAN, MSAN, or Valgrind. + +% + +Good selection of input files is critical to a successful fuzzing job. +See section #5 in README (or docs/perf_tips.txt) for pro tips. + +% + +You can improve the odds of automatically spotting stack corruption issues. +Specify AFL_HARDEN=1 in the environment to enable hardening flags. + +% + +Bumping into problems with non-reproducible crashes? It happens, but usually +isn't hard to diagnose. See section #7 in README for tips. + +% + +Fuzzing is not just about memory corruption issues in the codebase. Add some +sanity-checking assert() / abort() statements to effortlessly catch logic bugs. + +% + +Hey kid... pssst... want to figure out how AFL really works? +Check out docs/technical_details.txt for all the gory details in one place! + +% + +There's a ton of third-party helper tools designed to work with AFL! +Be sure to check out docs/sister_projects.txt before writing your own. + +% + +Need to fuzz the command-line arguments of a particular program? +You can find a simple solution in experimental/argv_fuzzing. + +% + +Attacking a format that uses checksums? Remove the checksum-checking code or +use a postprocessor! See experimental/post_library/ for more. + +%
diff --git a/third_party/afl/src/docs/notes_for_asan.txt b/third_party/afl/src/docs/notes_for_asan.txt index 649bb29..0f5bdca 100644 --- a/third_party/afl/src/docs/notes_for_asan.txt +++ b/third_party/afl/src/docs/notes_for_asan.txt
@@ -31,9 +31,16 @@ (You can also use AFL_USE_MSAN=1 to enable MSAN instead.) +Note that both ASAN and MSAN are incompatible with -D_FORTIFY_SOURCE (enabled +by default in some distros) and with AFL_HARDEN. Attempting to combine these +settings can lead to false negatives in ASAN and false positives in MSAN. This +is not AFL-specific. + There is also the option of generating a corpus using a non-ASAN binary, and then feeding it to an ASAN-instrumented one to check for bugs. This is faster, -and can give you somewhat comparable results. +and can give you somewhat comparable results. You can also try using +libdislocator (see libdislocator/README.dislocator in the parent directory) as a +lightweight and hassle-free (but less thorough) alternative. 2) Long version ---------------
diff --git a/third_party/afl/src/docs/parallel_fuzzing.txt b/third_party/afl/src/docs/parallel_fuzzing.txt index 69c1a9ae..58f8d2f 100644 --- a/third_party/afl/src/docs/parallel_fuzzing.txt +++ b/third_party/afl/src/docs/parallel_fuzzing.txt
@@ -51,13 +51,27 @@ for any test cases found by other fuzzers - and will incorporate them into its own fuzzing when they are deemed interesting enough. -The only difference between the -M and -S modes is that the master instance -will still perform deterministic checks; while the secondary instances will +The difference between the -M and -S modes is that the master instance will +still perform deterministic checks; while the secondary instances will proceed straight to random tweaks. If you don't want to do deterministic fuzzing at all, it's OK to run all instances with -S. With very slow or complex targets, or when running heavily parallelized jobs, this is usually a good plan. -You can monitor the progress of your jobs from the command line with the +Note that running multiple -M instances is wasteful, although there is an +experimental support for parallelizing the deterministic checks. To leverage +that, you need to create -M instances like so: + +$ ./afl-fuzz -i testcase_dir -o sync_dir -M masterA:1/3 [...] +$ ./afl-fuzz -i testcase_dir -o sync_dir -M masterB:2/3 [...] +$ ./afl-fuzz -i testcase_dir -o sync_dir -M masterC:3/3 [...] + +...where the first value after ':' is the sequential ID of a particular master +instance (starting at 1), and the second value is the total number of fuzzers to +distribute the deterministic fuzzing across. Note that if you boot up fewer +fuzzers than indicated by the second number passed to -M, you may end up with +poor coverage. + +You can also monitor the progress of your jobs from the command line with the provided afl-whatsup tool. When the instances are no longer finding new paths, it's probably time to stop.
diff --git a/third_party/afl/src/docs/perf_tips.txt b/third_party/afl/src/docs/perf_tips.txt index e05401d..e7a8b13b 100644 --- a/third_party/afl/src/docs/perf_tips.txt +++ b/third_party/afl/src/docs/perf_tips.txt
@@ -144,29 +144,7 @@ presented with pathological inputs. Low -m values can make them give up sooner and not waste CPU time. -8) Set CPU core affinity for AFL --------------------------------- - -Making sure that the fuzzer always runs on the same (idle) CPU core can offer -a significant speed bump and reduce scheduler jitter. The benefits can be even -more striking on true multiprocessor systems. - -On Linux, you can assign the fuzzer to a specific core by first running -afl-gotcpu to see which cores are idle, and then specifying the ID of a -preferred core via -Z, like so: - - $ ./afl-fuzz -Z core_id [...other parameters...] - -Note that this parameter needs to be used with care; accidentally forcing -multiple fuzzers to share the same core may result in performance that is -worse than what you would get without -Z. - -(It is also possible to specify two comma-delimited values for -Z, in which -case, the fuzzer will run on one designated core, and the target binary will -be banished to another. This can sometimes offer minor benefits, but isn't -recommended for general use.) - -9) Check OS configuration +8) Check OS configuration ------------------------- There are several OS-level factors that may affect fuzzing speed: @@ -200,8 +178,8 @@ SCHED_RR - can usually speed things up, too, but needs to be done with care. -10) If all other options fail, use -d -------------------------------------- +9) If all other options fail, use -d +------------------------------------ For programs that are genuinely slow, in cases where you really can't escape using huge input files, or when you simply want to get quick and dirty results
diff --git a/third_party/afl/src/docs/sister_projects.txt b/third_party/afl/src/docs/sister_projects.txt index 886c2f59..9c70604 100644 --- a/third_party/afl/src/docs/sister_projects.txt +++ b/third_party/afl/src/docs/sister_projects.txt
@@ -6,9 +6,9 @@ designed for, or meant to integrate with AFL. See README for the general instruction manual. ----------------------------- -Support for other languages: ----------------------------- +------------------------------------------- +Support for other languages / environments: +------------------------------------------- Python AFL (Jakub Wilk) ----------------------- @@ -70,6 +70,21 @@ https://github.com/bnagy/aflfix +TriforceAFL (Tim Newsham and Jesse Hertz) +----------------------------------------- + + Leverages QEMU full system emulation mode to allow AFL to target operating + systems and other alien worlds: + + https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2016/june/project-triforce-run-afl-on-everything/ + +WinAFL (Ivan Fratric) +--------------------- + + As the name implies, allows you to fuzz Windows binaries (using DynamoRio). + + https://github.com/ivanfratric/winafl + ---------------- Network fuzzing: ---------------- @@ -273,3 +288,4 @@ https://github.com/google/syzkaller/wiki/Found-Bugs https://github.com/dvyukov/linux/commit/33787098ffaaa83b8a7ccf519913ac5fd6125931 + http://events.linuxfoundation.org/sites/events/files/slides/AFL%20filesystem%20fuzzing%2C%20Vault%202016_0.pdf
diff --git a/third_party/afl/src/docs/status_screen.txt b/third_party/afl/src/docs/status_screen.txt index b1dd1de..ac09804 100644 --- a/third_party/afl/src/docs/status_screen.txt +++ b/third_party/afl/src/docs/status_screen.txt
@@ -119,7 +119,7 @@ --------------- +--------------------------------------+ - | map density : 4763 (29.07%) | + | map density : 10.15% / 29.07% | | count coverage : 4.03 bits/tuple | +--------------------------------------+ @@ -127,7 +127,11 @@ instrumentation embedded in the target binary. The first line in the box tells you how many branch tuples we have already -hit, in proportion to how much the bitmap can hold. Be wary of extremes: +hit, in proportion to how much the bitmap can hold. The number on the left +describes the current input; the one on the right is the value for the entire +input corpus. + +Be wary of extremes: - Absolute numbers below 200 or so suggest one of three things: that the program is extremely simple; that it is not instrumented properly (e.g., @@ -271,7 +275,7 @@ | pend fav : 583 | | own finds : 0 | | imported : 0 | - | variable : 0 | + | stability : 100.00% | +---------------------+ The first field in this section tracks the path depth reached through the @@ -291,27 +295,33 @@ imported from other fuzzer instances when doing parallelized fuzzing; and the number of inputs that produce seemingly variable behavior in the tested binary. -That last bit is actually fairly interesting. There are four quasi-common -explanations for variable behavior of the tested program: +That last bit is actually fairly interesting: it measures the consistency of +observed traces. If a program always behaves the same for the same input data, +it will earn a score of 100%. When the value is lower but still shown in purple, +the fuzzing process is unlikely to be negatively affected. If it goes into red, +you may be in trouble, since AFL will have difficulty discerning between +meaningful and "phantom" effects of tweaking the input file. - - Use of uninitialized memory in conjunction with some intrinsic sources of - entropy in the tested binary. This can be indicative of a security bug. +Now, most targets will just get a 100% score, but when you see lower figures, +there are several things to look at: - - Attempts to create files that were already created during previous runs, or - otherwise interact with some form of persistent state. This is harmless, - but you may want to instruct the targeted program to write to stdout or to - /dev/null to avoid surprises (and disable the creation of temporary files - and similar artifacts, if applicable). + - The use of uninitialized memory in conjunction with some intrinsic sources + of entropy in the tested binary. Harmless to AFL, but could be indicative + of a security bug. - - Hitting functionality that is actually designed to behave randomly. For - example, when fuzzing sqlite, the fuzzer will dutifully detect variable - behavior once the mutation engine generates something like: + - Attempts to manipulate persistent resources, such as left over temporary + files or shared memory objects. This is usually harmless, but you may want + to double-check to make sure the program isn't bailing out prematurely. + Running out of disk space, SHM handles, or other global resources can + trigger this, too. - select random(); + - Hitting some functionality that is actually designed to behave randomly. + Generally harmless. For example, when fuzzing sqlite, an input like + 'select random();' will trigger a variable execution path. - - Multiple threads executing at once in semi-random order. This is usually - just a nuisance, but if the number of variable paths is very high, try the - following options: + - Multiple threads executing at once in semi-random order. This is harmless + when the 'stability' metric stays over 90% or so, but can become an issue + if not. Here's what to try: - Use afl-clang-fast from llvm_mode/ - it uses a thread-local tracking model that is less prone to concurrency issues, @@ -323,17 +333,17 @@ - Replace pthreads with GNU Pth (https://www.gnu.org/software/pth/), which allows you to use a deterministic scheduler. -Less likely causes may include running out of disk space, SHM handles, or other -globally limited resources. + - In persistent mode, minor drops in the "stability" metric can be normal, + because not all the code behaves identically when re-entered; but major + dips may signify that the code within __AFL_LOOP() is not behaving + correctly on subsequent iterations (e.g., due to incomplete clean-up or + reinitialization of the state) and that most of the fuzzing effort goes + to waste. The paths where variable behavior is detected are marked with a matching entry in the <out_dir>/queue/.state/variable_behavior/ directory, so you can look them up easily. -If you can't suppress variable behavior and don't want to see these warnings, -simply set AFL_NO_VAR_CHECK=1 in the environment before running afl-fuzz. This -will also dramatically speed up session resumption. - 9) CPU load ----------- @@ -378,6 +388,7 @@ - cur_path - currently processed entry number - pending_favs - number of favored entries still waiting to be fuzzed - pending_total - number of all entries waiting to be fuzzed + - stability - percentage of bitmap bytes that behave consistently - variable_paths - number of test cases showing variable behavior - unique_crashes - number of unique crashes recorded - unique_hangs - number of unique hangs encountered
diff --git a/third_party/afl/src/docs/technical_details.txt b/third_party/afl/src/docs/technical_details.txt index ec789a3..3ec48741 100644 --- a/third_party/afl/src/docs/technical_details.txt +++ b/third_party/afl/src/docs/technical_details.txt
@@ -85,8 +85,8 @@ When a mutated input produces an execution trace containing new tuples, the corresponding input file is preserved and routed for additional processing later on (see section #3). Inputs that do not trigger new local-scale state -transitions in the execution trace are discarded, even if their overall -instrumentation output pattern is unique. +transitions in the execution trace (i.e., produce no new tuples) are discarded, +even if their overall control flow sequence is unique. This approach allows for a very fine-grained and long-term exploration of program state while not having to perform any computationally intensive and @@ -101,7 +101,7 @@ #2: A -> B -> C -> A -> E At the same time, with #2 processed, the following pattern will not be seen -as unique, despite having a markedly different execution path: +as unique, despite having a markedly different overall execution path: #3: A -> B -> C -> A -> B -> C -> A -> B -> C -> D -> E @@ -142,9 +142,9 @@ added to the input queue and used as a starting point for future rounds of fuzzing. They supplement, but do not automatically replace, existing finds. -This approach allows the tool to progressively explore various disjoint and -possibly mutually incompatible features of the underlying data format, as -shown in this image: +In contrast to more greedy genetic algorithms, this approach allows the tool +to progressively explore various disjoint and possibly mutually incompatible +features of the underlying data format, as shown in this image: http://lcamtuf.coredump.cx/afl/afl_gzip.png @@ -201,10 +201,10 @@ Edge coverage | 1,259 | 1,734 | 1.72 | 0 AFL model | 1,452 | 2,040 | 3.16 | 1 -Some of the earlier work on evolutionary fuzzing suggested maintaining just a -single test case and selecting for mutations that improve coverage. At least -in the tests described above, this "greedy" method appeared to offer no -substantial benefits over blind fuzzing. +At noted earlier on, some of the prior work on genetic fuzzing relied on +maintaining a single test case and evolving it to maximize coverage. At least +in the tests described above, this "greedy" approach appears to confer no +substantial benefits over blind fuzzing strategies. 4) Culling the corpus --------------------- @@ -263,9 +263,9 @@ that a mutation would touch important format control structures, rather than redundant data blocks. This is discussed in more detail in perf_tips.txt. -The possibility of a bad starting corpus provided by the user aside, some -types of mutations can have the effect of iteratively increasing the size of -the generated files, so it is important to counter this trend. +The possibility that the user will provide a low-quality starting corpus aside, +some types of mutations can have the effect of iteratively increasing the size +of the generated files, so it is important to counter this trend. Luckily, the instrumentation feedback provides a simple way to automatically trim down input files while ensuring that the changes made to the files have no @@ -275,11 +275,11 @@ with variable length and stepover; any deletion that doesn't affect the checksum of the trace map is committed to disk. The trimmer is not designed to be particularly thorough; instead, it tries to strike a balance between precision -and the number of execve() calls spent on the process. The average per-file -gains are around 5-20%. +and the number of execve() calls spent on the process, selecting the block size +and stepover to match. The average per-file gains are around 5-20%. The standalone afl-tmin tool uses a more exhaustive, iterative algorithm, and -also attempts to perform alphabet normalization on the trimmed files. +also attempts to perform alphabet normalization on the trimmed files. 6) Fuzzing strategies --------------------- @@ -302,11 +302,16 @@ - Sequential insertion of known interesting integers (0, 1, INT_MAX, etc), -The non-deterministic steps include stacked bit flips, insertions, deletions, -arithmetics, and splicing of different test cases. +The purpose of opening with deterministic steps is related to their tendency to +produce compact test cases and small diffs between the non-crashing and crashing +inputs. -Their relative yields and execve() costs have been investigated and are -discussed in the aforementioned blog post. +With deterministic fuzzing out of the way, the non-deterministic steps include +stacked bit flips, insertions, deletions, arithmetics, and splicing of different +test cases. + +The relative yields and execve() costs of all these strategies have been +investigated and are discussed in the aforementioned blog post. For the reasons discussed in historical_notes.txt (chiefly, performance, simplicity, and reliability), AFL generally does not try to reason about the @@ -315,13 +320,14 @@ input queue. That said, there is one (trivial) exception to this rule: when a new queue -entry goes through the initial set of deterministic fuzzing steps, and some -regions in the file are observed to have no effect on the checksum of the +entry goes through the initial set of deterministic fuzzing steps, and tweaks to +some regions in the file are observed to have no effect on the checksum of the execution path, they may be excluded from the remaining phases of -deterministic fuzzing - and proceed straight to random tweaks. Especially for -verbose, human-readable data formats, this can reduce the number of execs by -10-40% or so without an appreciable drop in coverage. In extreme cases, such -as normally block-aligned tar archives, the gains can be as high as 90%. +deterministic fuzzing - and the fuzzer may proceed straight to random tweaks. +Especially for verbose, human-readable data formats, this can reduce the number +of execs by 10-40% or so without an appreciable drop in coverage. In extreme +cases, such as normally block-aligned tar archives, the gains can be as high as +90%. Because the underlying "effector maps" are local every queue entry and remain in force only during deterministic stages that do not alter the size or the @@ -353,6 +359,14 @@ or XML; several examples of generated SQL statements are given in the blog post mentioned above. +Interestingly, the AFL instrumentation also allows the fuzzer to automatically +isolate syntax tokens already present in an input file. It can do so by looking +for run of bytes that, when flipped, produce a consistent change to the +program's execution path; this is suggestive of an underlying atomic comparison +to a predefined value baked into the code. The fuzzer relies on this signal +to build compact "auto dictionaries" that are then used in conjunction with +other fuzzing strategies. + 8) De-duping crashes -------------------- @@ -416,22 +430,25 @@ usually between 1.5x and 2x. It is also possible to: - Use the fork server in manual ("deferred") mode, skipping over larger, - user-selected chunks of initialization code. With some targets, this can + user-selected chunks of initialization code. It requires very modest + code changes to the targeted program, and With some targets, can produce 10x+ performance gains. - Enable "persistent" mode, where a single process is used to try out multiple inputs, greatly limiting the overhead of repetitive fork() - calls. As with the previous mode, this requires custom modifications, + calls. This generally requires some code changes to the targeted program, but can improve the performance of fast targets by a factor of 5 or more - - approximating the benefits of in-process fuzzing jobs. + - approximating the benefits of in-process fuzzing jobs while still + maintaining very robust isolation between the fuzzer process and the + targeted binary. 11) Parallelization ------------------- The parallelization mechanism relies on periodically examining the queues produced by independently-running instances on other CPU cores or on remote -machines, and then selectively pulling in the test cases that produce behaviors -not yet seen by the fuzzer at hand. +machines, and then selectively pulling in the test cases that, when tried +out locally, produce behaviors not yet seen by the fuzzer at hand. This allows for extreme flexibility in fuzzer setup, including running synced instances against different parsers of a common data format, often with
diff --git a/third_party/afl/src/docs/visualization/afl_gzip.png b/third_party/afl/src/docs/visualization/afl_gzip.png new file mode 100644 index 0000000..7c461d8 --- /dev/null +++ b/third_party/afl/src/docs/visualization/afl_gzip.png Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/bash-cmd-exec.var b/third_party/afl/src/docs/vuln_samples/bash-cmd-exec.var new file mode 100644 index 0000000..6422d427 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/bash-cmd-exec.var
@@ -0,0 +1 @@ +() { _; } >_[$($())] { id; } \ No newline at end of file
diff --git a/third_party/afl/src/docs/vuln_samples/bash-uninit-mem.var b/third_party/afl/src/docs/vuln_samples/bash-uninit-mem.var new file mode 100644 index 0000000..6d7d5360 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/bash-uninit-mem.var
@@ -0,0 +1 @@ +() { x() { _; }; x() { _; } <<a; } \ No newline at end of file
diff --git a/third_party/afl/src/docs/vuln_samples/ffmpeg-h264-bad-ptr-800m.mp4 b/third_party/afl/src/docs/vuln_samples/ffmpeg-h264-bad-ptr-800m.mp4 new file mode 100644 index 0000000..ce23a8bd --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/ffmpeg-h264-bad-ptr-800m.mp4 Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/ffmpeg-h264-bad-read.mp4 b/third_party/afl/src/docs/vuln_samples/ffmpeg-h264-bad-read.mp4 new file mode 100644 index 0000000..57a0ac90 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/ffmpeg-h264-bad-read.mp4 Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/ffmpeg-h264-call-stack-overflow.mp4 b/third_party/afl/src/docs/vuln_samples/ffmpeg-h264-call-stack-overflow.mp4 new file mode 100644 index 0000000..5471105 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/ffmpeg-h264-call-stack-overflow.mp4 Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/firefox-bmp-leak.bmp b/third_party/afl/src/docs/vuln_samples/firefox-bmp-leak.bmp new file mode 100644 index 0000000..857e242 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/firefox-bmp-leak.bmp Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/firefox-chrome-leak.jpg b/third_party/afl/src/docs/vuln_samples/firefox-chrome-leak.jpg new file mode 100644 index 0000000..a642d98 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/firefox-chrome-leak.jpg Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/firefox-gif-leak.gif b/third_party/afl/src/docs/vuln_samples/firefox-gif-leak.gif new file mode 100644 index 0000000..310cd36 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/firefox-gif-leak.gif Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/firefox-gif-leak2.gif b/third_party/afl/src/docs/vuln_samples/firefox-gif-leak2.gif new file mode 100644 index 0000000..bb41696 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/firefox-gif-leak2.gif Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/jxrlib-crash.jxr b/third_party/afl/src/docs/vuln_samples/jxrlib-crash.jxr new file mode 100644 index 0000000..71d190e --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/jxrlib-crash.jxr Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/jxrlib-crash2.jxr b/third_party/afl/src/docs/vuln_samples/jxrlib-crash2.jxr new file mode 100644 index 0000000..0831325 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/jxrlib-crash2.jxr Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/jxrlib-crash3.jxr b/third_party/afl/src/docs/vuln_samples/jxrlib-crash3.jxr new file mode 100644 index 0000000..47af7f1 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/jxrlib-crash3.jxr Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/jxrlib-crash4.jxr b/third_party/afl/src/docs/vuln_samples/jxrlib-crash4.jxr new file mode 100644 index 0000000..51daf47d --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/jxrlib-crash4.jxr Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/lesspipe-cpio-bad-write.cpio b/third_party/afl/src/docs/vuln_samples/lesspipe-cpio-bad-write.cpio new file mode 100644 index 0000000..ec5a992d --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/lesspipe-cpio-bad-write.cpio Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/libjpeg-sos-leak.jpg b/third_party/afl/src/docs/vuln_samples/libjpeg-sos-leak.jpg new file mode 100644 index 0000000..02653b87 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/libjpeg-sos-leak.jpg Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/libjpeg-turbo-dht-leak.jpg b/third_party/afl/src/docs/vuln_samples/libjpeg-turbo-dht-leak.jpg new file mode 100644 index 0000000..cfc21a8 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/libjpeg-turbo-dht-leak.jpg Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/libtiff-bad-write.tif b/third_party/afl/src/docs/vuln_samples/libtiff-bad-write.tif new file mode 100644 index 0000000..45027cd --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/libtiff-bad-write.tif Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/libtiff-uninit-mem.tif b/third_party/afl/src/docs/vuln_samples/libtiff-uninit-mem.tif new file mode 100644 index 0000000..b94e2a9 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/libtiff-uninit-mem.tif Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/libtiff-uninit-mem2.tif b/third_party/afl/src/docs/vuln_samples/libtiff-uninit-mem2.tif new file mode 100644 index 0000000..0f9711b --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/libtiff-uninit-mem2.tif Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/libtiff-uninit-mem3.tif b/third_party/afl/src/docs/vuln_samples/libtiff-uninit-mem3.tif new file mode 100644 index 0000000..6889a3d --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/libtiff-uninit-mem3.tif Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/libtiff-uninit-mem4.tif b/third_party/afl/src/docs/vuln_samples/libtiff-uninit-mem4.tif new file mode 100644 index 0000000..98af970 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/libtiff-uninit-mem4.tif Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/libxml2-bad-read.xml b/third_party/afl/src/docs/vuln_samples/libxml2-bad-read.xml new file mode 100644 index 0000000..d46fd12 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/libxml2-bad-read.xml
@@ -0,0 +1,3 @@ +<!DOCTYPEd[<!ENTITY +S ""><!ENTITY % +N "<!ELEMENT<![INCLUDE0"<!ENTITYL%N; \ No newline at end of file
diff --git a/third_party/afl/src/docs/vuln_samples/msie-dht-leak.jpg b/third_party/afl/src/docs/vuln_samples/msie-dht-leak.jpg new file mode 100644 index 0000000..a0fb121c --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/msie-dht-leak.jpg Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/msie-jxr-mem-leak.jxr b/third_party/afl/src/docs/vuln_samples/msie-jxr-mem-leak.jxr new file mode 100644 index 0000000..519f9c1 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/msie-jxr-mem-leak.jxr Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/msie-png-mem-leak.png b/third_party/afl/src/docs/vuln_samples/msie-png-mem-leak.png new file mode 100644 index 0000000..bc193bf --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/msie-png-mem-leak.png Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/msie-tiff-mem-leak.tif b/third_party/afl/src/docs/vuln_samples/msie-tiff-mem-leak.tif new file mode 100644 index 0000000..7e937c9 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/msie-tiff-mem-leak.tif Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/msie-zlib-dos.png b/third_party/afl/src/docs/vuln_samples/msie-zlib-dos.png new file mode 100644 index 0000000..df3ab80 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/msie-zlib-dos.png Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/openssl-null-ptr.der b/third_party/afl/src/docs/vuln_samples/openssl-null-ptr.der new file mode 100644 index 0000000..dd3975d6 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/openssl-null-ptr.der Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/openssl-null-ptr2.der b/third_party/afl/src/docs/vuln_samples/openssl-null-ptr2.der new file mode 100644 index 0000000..85cf6b05 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/openssl-null-ptr2.der Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/photoshop-mem-leak.jpg b/third_party/afl/src/docs/vuln_samples/photoshop-mem-leak.jpg new file mode 100644 index 0000000..5b9f591 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/photoshop-mem-leak.jpg Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-bad-free.sql b/third_party/afl/src/docs/vuln_samples/sqlite-bad-free.sql new file mode 100644 index 0000000..4e37f49c --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-bad-free.sql
@@ -0,0 +1,2 @@ +create table t0(o CHar(0)CHECK(0&O>O));insert into t0 +select randomblob(0)-trim(0);
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-bad-ptr.sql b/third_party/afl/src/docs/vuln_samples/sqlite-bad-ptr.sql new file mode 100644 index 0000000..46e78afa --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-bad-ptr.sql
@@ -0,0 +1 @@ +SELECT 0 UNION SELECT 0 ORDER BY 1 COLLATE"""""""";
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-bad-ptr2.sql b/third_party/afl/src/docs/vuln_samples/sqlite-bad-ptr2.sql new file mode 100644 index 0000000..cd613d08 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-bad-ptr2.sql
@@ -0,0 +1 @@ +PRAGMA foreign_keys=1;CREATE TABLE t1("""0"PRIMARY KEy REFERENCES t1 ON DELETE SET NULL);REPLACE INTO t1 SELECT(0);
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-bad-ptr3.sql b/third_party/afl/src/docs/vuln_samples/sqlite-bad-ptr3.sql new file mode 100644 index 0000000..7518816 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-bad-ptr3.sql Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-heap-overflow.sql b/third_party/afl/src/docs/vuln_samples/sqlite-heap-overflow.sql new file mode 100644 index 0000000..066fc83 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-heap-overflow.sql
@@ -0,0 +1,2 @@ +DROP TABLE IF EXISTS t;CREATE VIRTUAL TABLE t0 USING fts4();insert into t0 select zeroblob(0);SAVEPOINT O;insert into t0 +select(0);SAVEPOINT E;insert into t0 SELECT 0 UNION SELECT 0'x'ORDER BY x;
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-heap-overwrite.sql b/third_party/afl/src/docs/vuln_samples/sqlite-heap-overwrite.sql new file mode 100644 index 0000000..51ed82c --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-heap-overwrite.sql
@@ -0,0 +1 @@ +ATTACH "file:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA?mode=memory&cache=shared" AS x; \ No newline at end of file
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-negative-memset.sql b/third_party/afl/src/docs/vuln_samples/sqlite-negative-memset.sql new file mode 100644 index 0000000..d647bea --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-negative-memset.sql
@@ -0,0 +1 @@ +SELECT*from(select"",zeroblob(0),zeroblob(1E9),zeroblob(0),zeroblob(150000000),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(1E9),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0)),(select"",zeroblob(1E9),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(1E9),(0),zeroblob(150000000),(0),zeroblob(0),(0)EXCEPT select zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0),zeroblob(0));
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr1.sql b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr1.sql new file mode 100644 index 0000000..3f9d46c7 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr1.sql
@@ -0,0 +1,2 @@ +create table t0(t);insert into t0 +select strftime();
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr10.sql b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr10.sql new file mode 100644 index 0000000..798bbf14 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr10.sql
@@ -0,0 +1 @@ +SELECT fts3_tokenizer(@0());
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr11.sql b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr11.sql new file mode 100644 index 0000000..f6bcf65f --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr11.sql
@@ -0,0 +1 @@ +select''like''like''like#0;
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr12.sql b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr12.sql new file mode 100644 index 0000000..8d14a86 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr12.sql
@@ -0,0 +1 @@ +PRAGMA e;select lower(0);select lower(0)"a",""GROUP BY a ORDER BY a;
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr13.sql b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr13.sql new file mode 100644 index 0000000..e730db3 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr13.sql
@@ -0,0 +1 @@ +WITH x AS(SELECT*FROM t)SELECT""EXCEPT SELECT 0 ORDER BY 0 COLLATE"";
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr14.sql b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr14.sql new file mode 100644 index 0000000..37b9bae --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr14.sql
@@ -0,0 +1 @@ +CREATE VIRTUAL TABLE x USING fts4();VALUES(0,0),(0,0),(0,0),(0,0);PRAGMA writable_schema=ON;UPDATE sqlite_master SET sql=''WHERE name='';UPDATE sqlite_master SET sql='CREATE table t(d CHECK(T(#0)';SAVEPOINT K;SAVEPOINT T;SAVEPOINT T;ANALYZE;ROLLBACK;SAVEPOINT E;DROP TABLE IF EXISTS t;
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr15.sql b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr15.sql new file mode 100644 index 0000000..83d5c9d --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr15.sql
@@ -0,0 +1 @@ +CREATE VIRTUAL TABLE t4 USING fts4(0,b,c,notindexed=0);INSERT INTO t4 VALUES('','','0');BEGIN;INSERT INTO t4 VALUES('','','0');INSERT INTO t4(t4)VALUES('integrity-check');
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr2.sql b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr2.sql new file mode 100644 index 0000000..11c5a37 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr2.sql
@@ -0,0 +1 @@ +DETACH(select group_concat(q));
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr3.sql b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr3.sql new file mode 100644 index 0000000..14df82a7 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr3.sql
@@ -0,0 +1 @@ +select(select strftime());
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr4.sql b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr4.sql new file mode 100644 index 0000000..fdb80476 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr4.sql
@@ -0,0 +1 @@ +select n()AND+#00;
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr5.sql b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr5.sql new file mode 100644 index 0000000..7bbb785 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr5.sql
@@ -0,0 +1 @@ +select e.*,0 from(s,(L))e;
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr6.sql b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr6.sql new file mode 100644 index 0000000..1431f3f5 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr6.sql
@@ -0,0 +1 @@ +PRAGMA encoding='UTF16';CREATE VIRTUAL TABLE È USING s; \ No newline at end of file
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr7.sql b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr7.sql new file mode 100644 index 0000000..57ab12c51 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr7.sql
@@ -0,0 +1 @@ +CREATE VIRTUAL TABLE t USING fts4(tokenize=);
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr8.sql b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr8.sql new file mode 100644 index 0000000..4d5db064 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr8.sql
@@ -0,0 +1 @@ +CREATE TABLE p(a UNIQUE,PRIMARY KEY('a'))WITHOUT rowid;
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr9.sql b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr9.sql new file mode 100644 index 0000000..0ae836a2 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-null-ptr9.sql
@@ -0,0 +1 @@ +CREATE TABLE t0(z);WITH d(x)AS(SELECT*UNION SELECT 0)INSERT INTO t0 SELECT 0 FROM d;
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-oob-read.sql b/third_party/afl/src/docs/vuln_samples/sqlite-oob-read.sql new file mode 100644 index 0000000..75f4150 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-oob-read.sql
@@ -0,0 +1 @@ +create table t0( DEFAULT(0=0)NOT/**/NULL);REPLACE into t0 select''; \ No newline at end of file
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-oob-write.sql b/third_party/afl/src/docs/vuln_samples/sqlite-oob-write.sql new file mode 100644 index 0000000..9b2c427d --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-oob-write.sql
@@ -0,0 +1,6 @@ +CREATE VIRTUAL TABLE t0 USING fts4(x,order=DESC); +INSERT INTO t0(docid,x)VALUES(-1E0,'0(o'); +INSERT INTO t0 VALUES(''); +INSERT INTO t0 VALUES(''); +INSeRT INTO t0 VALUES('o'); +SELECT docid FROM t0 WHERE t0 MATCH'"0*o"';
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-stack-buf-overflow.sql b/third_party/afl/src/docs/vuln_samples/sqlite-stack-buf-overflow.sql new file mode 100644 index 0000000..4be57fd --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-stack-buf-overflow.sql
@@ -0,0 +1 @@ +SELECT printf('%*.*f',90000||006000000&6600000000,00000000000000000909000000000000.0000000000000000)""WHERE"">"";
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-stack-exhaustion.sql b/third_party/afl/src/docs/vuln_samples/sqlite-stack-exhaustion.sql new file mode 100644 index 0000000..6031a93 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-stack-exhaustion.sql
@@ -0,0 +1 @@ +CREATE VIRTUAL TABLE t0 USING fts4(content=t0);
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-unint-mem.sql b/third_party/afl/src/docs/vuln_samples/sqlite-unint-mem.sql new file mode 100644 index 0000000..83b77112 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-unint-mem.sql
@@ -0,0 +1 @@ +REATE VIRTUAL TABLE t0 USING fts4(prefix=0);INSERT INTO t0 VALUES(0);
diff --git a/third_party/afl/src/docs/vuln_samples/sqlite-use-after-free.sql b/third_party/afl/src/docs/vuln_samples/sqlite-use-after-free.sql new file mode 100644 index 0000000..4083ee6 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/sqlite-use-after-free.sql
@@ -0,0 +1 @@ +create table t(s);PRAGMA writable_schema=ON;UPDATE sqlite_master SET sql='ANALYZE;CREATE VIRTUAL TABLE t USING fts3;DROP TABLE t;DROP TABLE EXISTS t';PRAGMA r;SAVEPOINT T;ANALYZE;ROLLBACK;SAVEPOINT E;DROP TABLE IF EXISTS t;
diff --git a/third_party/afl/src/docs/vuln_samples/strings-stack-overflow b/third_party/afl/src/docs/vuln_samples/strings-stack-overflow new file mode 100644 index 0000000..a3d0e04 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/strings-stack-overflow
@@ -0,0 +1,3 @@ +$$@$$$@$o +S Ôo +S Ô \ No newline at end of file
diff --git a/third_party/afl/src/docs/vuln_samples/tcpdump-arp-crash.pcap b/third_party/afl/src/docs/vuln_samples/tcpdump-arp-crash.pcap new file mode 100644 index 0000000..40d199a2 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/tcpdump-arp-crash.pcap Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/tcpdump-ppp-crash.pcap b/third_party/afl/src/docs/vuln_samples/tcpdump-ppp-crash.pcap new file mode 100644 index 0000000..b6831155 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/tcpdump-ppp-crash.pcap Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/unrtf-arbitrary-read.rtf b/third_party/afl/src/docs/vuln_samples/unrtf-arbitrary-read.rtf new file mode 100644 index 0000000..b7f4c2837 --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/unrtf-arbitrary-read.rtf Binary files differ
diff --git a/third_party/afl/src/docs/vuln_samples/unzip-t-mem-corruption.zip b/third_party/afl/src/docs/vuln_samples/unzip-t-mem-corruption.zip new file mode 100644 index 0000000..d34fa39e --- /dev/null +++ b/third_party/afl/src/docs/vuln_samples/unzip-t-mem-corruption.zip Binary files differ
diff --git a/third_party/afl/src/experimental/README.experiments b/third_party/afl/src/experimental/README.experiments index 3e7e9eb..af9739b 100644 --- a/third_party/afl/src/experimental/README.experiments +++ b/third_party/afl/src/experimental/README.experiments
@@ -22,10 +22,6 @@ - distributed_fuzzing - a sample script for synchronizing fuzzer instances across multiple machines (see parallel_fuzzing.txt). - - instrumented_cmp - an experiment showing how a custom memcmp() or - strcmp() can be used to work around one of the - limitations of afl-fuzz. - - libpng_no_checksum - a sample patch for removing CRC checks in libpng. - persistent_demo - an example of how to use the LLVM persistent process
diff --git a/third_party/afl/src/experimental/post_library/post_library.so.c b/third_party/afl/src/experimental/post_library/post_library.so.c index 5cdee08..72620ff 100644 --- a/third_party/afl/src/experimental/post_library/post_library.so.c +++ b/third_party/afl/src/experimental/post_library/post_library.so.c
@@ -21,11 +21,11 @@ in the targeted binary (as shown in ../libpng_no_checksum/). One possible exception is the process of fuzzing binary-only software in QEMU mode. - 2) Use of postprocessors for anything other than checksums is questionable + 2) The use of postprocessors for anything other than checksums is questionable and may cause more harm than good. AFL is normally pretty good about dealing with length fields, magic values, etc. - 3) Post-processors that do anything non-trivial must be extremely robust to + 3) Postprocessors that do anything non-trivial must be extremely robust to gracefully handle malformed data and other error conditions - otherwise, they will crash and take afl-fuzz down with them. Be wary of reading past *len and of integer overflows when calculating file offsets.
diff --git a/third_party/afl/src/libdislocator/Makefile b/third_party/afl/src/libdislocator/Makefile new file mode 100644 index 0000000..a411678 --- /dev/null +++ b/third_party/afl/src/libdislocator/Makefile
@@ -0,0 +1,38 @@ +# +# american fuzzy lop - libdislocator +# ---------------------------------- +# +# Written by Michal Zalewski <lcamtuf@google.com> +# +# Copyright 2016 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# + +PREFIX ?= /usr/local +HELPER_PATH = $(PREFIX)/lib/afl + +VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) + +CFLAGS ?= -O3 -funroll-loops +CFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign + +all: libdislocator.so + +libdislocator.so: libdislocator.so.c ../config.h + $(CC) $(CFLAGS) -shared -fPIC $< -o $@ $(LDFLAGS) + +.NOTPARALLEL: clean + +clean: + rm -f *.o *.so *~ a.out core core.[1-9][0-9]* + rm -f libdislocator.so + +install: all + install -m 755 libdislocator.so $${DESTDIR}$(HELPER_PATH) + install -m 644 README.dislocator $${DESTDIR}$(HELPER_PATH) +
diff --git a/third_party/afl/src/libdislocator/README.dislocator b/third_party/afl/src/libdislocator/README.dislocator new file mode 100644 index 0000000..837e746 --- /dev/null +++ b/third_party/afl/src/libdislocator/README.dislocator
@@ -0,0 +1,60 @@ +=================================== +libdislocator, an abusive allocator +=================================== + + (See ../docs/README for the general instruction manual.) + +This is a companion library that can be used as a drop-in replacement for the +libc allocator in the fuzzed binaries. It improves the odds of bumping into +heap-related security bugs in several ways: + + - It allocates all buffers so that they are immediately adjacent to a + subsequent PROT_NONE page, causing most off-by-one reads and writes to + immediately segfault, + + - It adds a canary immediately below the allocated buffer, to catch writes + to negative offsets (won't catch reads, though), + + - It sets the memory returned by malloc() to garbage values, improving the + odds of crashing when the target accesses uninitialized data, + + - It sets freed memory to PROT_NONE and does not actually reuse it, causing + most use-after-free bugs to segfault right away, + + - It forces all realloc() calls to return a new address - and sets + PROT_NONE on the original block. This catches use-after-realloc bugs, + + - It checks for calloc() overflows and can cause soft or hard failures + of alloc requests past a configurable memory limit (AFL_LD_LIMIT_MB, + AFL_LD_HARD_FAIL). + +Basically, it is inspired by some of the non-default options available for the +OpenBSD allocator - see malloc.conf(5) on that platform for reference. It is +also somewhat similar to several other debugging libraries, such as gmalloc +and DUMA - but is simple, plug-and-play, and designed specifically for fuzzing +jobs. + +Note that it does nothing for stack-based memory handling errors. The +-fstack-protector-all setting for GCC / clang, enabled when using AFL_HARDEN, +can catch some subset of that. + +The allocator is slow and memory-intensive (even the tiniest allocation uses up +4 kB of physical memory and 8 kB of virtual mem), making it completely unsuitable +for "production" uses; but it can be faster and more hassle-free than ASAN / MSAN +when fuzzing small, self-contained binaries. + +To use this library, run AFL like so: + +AFL_PRELOAD=/path/to/libdislocator.so ./afl-fuzz [...other params...] + +You *have* to specify path, even if it's just ./libdislocator.so or +$PWD/libdislocator.so. + +Similarly to afl-tmin, the library is not "proprietary" and can be used with +other fuzzers or testing tools without the need for any code tweaks. It does not +require AFL-instrumented binaries to work. + +Note that the AFL_PRELOAD approach (which AFL internally maps to LD_PRELOAD or +DYLD_INSERT_LIBRARIES, depending on the OS) works only if the target binary is +dynamically linked. Otherwise, attempting to use the library will have no +effect.
diff --git a/third_party/afl/src/libdislocator/libdislocator.so.c b/third_party/afl/src/libdislocator/libdislocator.so.c new file mode 100644 index 0000000..1d4648f --- /dev/null +++ b/third_party/afl/src/libdislocator/libdislocator.so.c
@@ -0,0 +1,257 @@ +/* + + american fuzzy lop - dislocator, an abusive allocator + ----------------------------------------------------- + + Written and maintained by Michal Zalewski <lcamtuf@google.com> + + Copyright 2016 Google Inc. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at: + + http://www.apache.org/licenses/LICENSE-2.0 + + This is a companion library that can be used as a drop-in replacement + for the libc allocator in the fuzzed binaries. See README.dislocator for + more info. + + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <limits.h> +#include <sys/mman.h> + +#include "../config.h" +#include "../types.h" + +#ifndef PAGE_SIZE +# define PAGE_SIZE 4096 +#endif /* !PAGE_SIZE */ + +#ifndef MAP_ANONYMOUS +# define MAP_ANONYMOUS MAP_ANON +#endif /* !MAP_ANONYMOUS */ + +/* Error / message handling: */ + +#define DEBUGF(_x...) do { \ + if (alloc_verbose) { \ + if (++call_depth == 1) { \ + fprintf(stderr, "[AFL] " _x); \ + fprintf(stderr, "\n"); \ + } \ + call_depth--; \ + } \ + } while (0) + +#define FATAL(_x...) do { \ + if (++call_depth == 1) { \ + fprintf(stderr, "*** [AFL] " _x); \ + fprintf(stderr, " ***\n"); \ + abort(); \ + } \ + call_depth--; \ + } while (0) + +/* Macro to count the number of pages needed to store a buffer: */ + +#define PG_COUNT(_l) (((_l) + (PAGE_SIZE - 1)) / PAGE_SIZE) + +/* Canary & clobber bytes: */ + +#define ALLOC_CANARY 0xAACCAACC +#define ALLOC_CLOBBER 0x41 + +#define PTR_C(_p) (((u32*)(_p))[-1]) +#define PTR_L(_p) (((u32*)(_p))[-2]) + +/* Configurable stuff (use AFL_LD_* to set): */ + +static u32 max_mem = MAX_ALLOC; /* Max heap usage to permit */ +static u8 alloc_verbose, /* Additional debug messages */ + hard_fail; /* abort() when max_mem exceeded? */ + +static __thread size_t total_mem; /* Currently allocated mem */ + +static __thread u32 call_depth; /* To avoid recursion via fprintf() */ + + +/* This is the main alloc function. It allocates one page more than necessary, + sets that tailing page to PROT_NONE, and then increments the return address + so that it is right-aligned to that boundary. Since it always uses mmap(), + the returned memory will be zeroed. */ + +static void* __dislocator_alloc(size_t len) { + + void* ret; + + if (total_mem + len > max_mem) { + + if (hard_fail) + FATAL("total allocs exceed %u MB", max_mem / 1024 / 1024); + + DEBUGF("total allocs exceed %u MB, returning NULL", + max_mem / 1024 / 1024); + + return NULL; + + } + + /* We will also store buffer length and a canary below the actual buffer, so + let's add 8 bytes for that. */ + + ret = mmap(NULL, (1 + PG_COUNT(len + 8)) * PAGE_SIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + if (ret == (void*)-1) { + + if (hard_fail) FATAL("mmap() failed on alloc (OOM?)"); + + DEBUGF("mmap() failed on alloc (OOM?)"); + + return NULL; + + } + + /* Set PROT_NONE on the last page. */ + + if (mprotect(ret + PG_COUNT(len + 8) * PAGE_SIZE, PAGE_SIZE, PROT_NONE)) + FATAL("mprotect() failed when allocating memory"); + + /* Offset the return pointer so that it's right-aligned to the page + boundary. */ + + ret += PAGE_SIZE * PG_COUNT(len + 8) - len - 8; + + /* Store allocation metadata. */ + + ret += 8; + + PTR_L(ret) = len; + PTR_C(ret) = ALLOC_CANARY; + + total_mem += len; + + return ret; + +} + + +/* The "user-facing" wrapper for calloc(). This just checks for overflows and + displays debug messages if requested. */ + +void* calloc(size_t elem_len, size_t elem_cnt) { + + void* ret; + + size_t len = elem_len * elem_cnt; + + /* Perform some sanity checks to detect obvious issues... */ + + if (elem_cnt && len / elem_cnt != elem_len) + FATAL("calloc(%zu, %zu) would overflow", elem_len, elem_cnt); + + ret = __dislocator_alloc(len); + + DEBUGF("calloc(%zu, %zu) = %p [%zu total]", elem_len, elem_cnt, ret, + total_mem); + + return ret; + +} + + +/* The wrapper for malloc(). Roughly the same, also clobbers the returned + memory (unlike calloc(), malloc() is not guaranteed to return zeroed + memory). */ + +void* malloc(size_t len) { + + void* ret; + + ret = __dislocator_alloc(len); + + DEBUGF("malloc(%zu) = %p [%zu total]", len, ret, total_mem); + + if (ret && len) memset(ret, ALLOC_CLOBBER, len); + + return ret; + +} + + +/* The wrapper for free(). This simply marks the entire region as PROT_NONE. + If the region is already freed, the code will segfault during the attempt to + read the canary. Not very graceful, but works, right? */ + +void free(void* ptr) { + + u32 len; + + DEBUGF("free(%p)", ptr); + + if (!ptr) return; + + if (PTR_C(ptr) != ALLOC_CANARY) FATAL("bad allocator canary on free()"); + + len = PTR_L(ptr); + + total_mem -= len; + + /* Protect everything. Note that the extra page at the end is already + set as PROT_NONE, so we don't need to touch that. */ + + ptr -= PAGE_SIZE * PG_COUNT(len + 8) - len - 8; + + if (mprotect(ptr - 8, PG_COUNT(len + 8) * PAGE_SIZE, PROT_NONE)) + FATAL("mprotect() failed when freeing memory"); + + /* Keep the mapping; this is wasteful, but prevents ptr reuse. */ + +} + + +/* Realloc is pretty straightforward, too. We forcibly reallocate the buffer, + move data, and then free (aka mprotect()) the original one. */ + +void* realloc(void* ptr, size_t len) { + + void* ret; + + ret = malloc(len); + + if (ret && ptr) { + + if (PTR_C(ptr) != ALLOC_CANARY) FATAL("bad allocator canary on realloc()"); + + memcpy(ret, ptr, MIN(len, PTR_L(ptr))); + free(ptr); + + } + + DEBUGF("realloc(%p, %zu) = %p [%zu total]", ptr, len, ret, total_mem); + + return ret; + +} + + +__attribute__((constructor)) void __dislocator_init(void) { + + u8* tmp = getenv("AFL_LD_LIMIT_MB"); + + if (tmp) { + + max_mem = atoi(tmp) * 1024 * 1024; + if (!max_mem) FATAL("Bad value for AFL_LD_LIMIT_MB"); + + } + + alloc_verbose = !!getenv("AFL_LD_VERBOSE"); + hard_fail = !!getenv("AFL_LD_HARD_FAIL"); + +}
diff --git a/third_party/afl/src/libtokencap/Makefile b/third_party/afl/src/libtokencap/Makefile new file mode 100644 index 0000000..a464f76d1 --- /dev/null +++ b/third_party/afl/src/libtokencap/Makefile
@@ -0,0 +1,38 @@ +# +# american fuzzy lop - libtokencap +# -------------------------------- +# +# Written by Michal Zalewski <lcamtuf@google.com> +# +# Copyright 2016 Google Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at: +# +# http://www.apache.org/licenses/LICENSE-2.0 +# + +PREFIX ?= /usr/local +HELPER_PATH = $(PREFIX)/lib/afl + +VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) + +CFLAGS ?= -O3 -funroll-loops +CFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign + +all: libtokencap.so + +libtokencap.so: libtokencap.so.c ../config.h + $(CC) $(CFLAGS) -shared -fPIC $< -o $@ $(LDFLAGS) + +.NOTPARALLEL: clean + +clean: + rm -f *.o *.so *~ a.out core core.[1-9][0-9]* + rm -f libtokencap.so + +install: all + install -m 755 libtokencap.so $${DESTDIR}$(HELPER_PATH) + install -m 644 README.tokencap $${DESTDIR}$(HELPER_PATH) +
diff --git a/third_party/afl/src/libtokencap/README.tokencap b/third_party/afl/src/libtokencap/README.tokencap new file mode 100644 index 0000000..82d80c95 --- /dev/null +++ b/third_party/afl/src/libtokencap/README.tokencap
@@ -0,0 +1,60 @@ +========================================= +strcmp() / memcmp() token capture library +========================================= + + (See ../docs/README for the general instruction manual.) + +This Linux-only companion library allows you to instrument strcmp(), memcmp(), +and related functions to automatically extract syntax tokens passed to any of +these libcalls. The resulting list of tokens may be then given as a starting +dictionary to afl-fuzz (the -x option) to improve coverage on subsequent +fuzzing runs. + +This may help improving coverage in some targets, and do precisely nothing in +others. In some cases, it may even make things worse: if libtokencap picks up +syntax tokens that are not used to process the input data, but that are a part +of - say - parsing a config file... well, you're going to end up wasting a lot +of CPU time on trying them out in the input stream. In other words, use this +feature with care. Manually screening the resulting dictionary is almost +always a necessity. + +As for the actual operation: the library stores tokens, without any deduping, +by appending them to a file specified via AFL_TOKEN_FILE. If the variable is not +set, the tool uses stderr (which is probably not what you want). + +Similarly to afl-tmin, the library is not "proprietary" and can be used with +other fuzzers or testing tools without the need for any code tweaks. It does not +require AFL-instrumented binaries to work. + +To use the library, you *need* to make sure that your fuzzing target is compiled +with -fno-builtin and is linked dynamically. If you wish to automate the first +part without mucking with CFLAGS in Makefiles, you can set AFL_NO_BUILTIN=1 +when using afl-gcc. This setting specifically adds the following flags: + + -fno-builtin-strcmp -fno-builtin-strncmp -fno-builtin-strcasecmp + -fno-builtin-strcasencmp -fno-builtin-memcmp + +The next step is simply loading this library via LD_PRELOAD. The optimal usage +pattern is to allow afl-fuzz to fuzz normally for a while and build up a corpus, +and then fire off the target binary, with libtokencap.so loaded, on every file +found by AFL in that earlier run. This demonstrates the basic principle: + + export AFL_TOKEN_FILE=$PWD/temp_output.txt + + for i in <out_dir>/queue/id*; do + LD_PRELOAD=/path/to/libtokencap.so \ + /path/to/target/program [...params, including $i...] + done + + sort -u temp_output.txt >afl_dictionary.txt + +If you don't get any results, the target library is probably not using strcmp() +and memcmp() to parse input; or you haven't compiled it with -fno-builtin; or +the whole thing isn't dynamically linked, and LD_PRELOAD is having no effect. + +PS. The library is Linux-only because there is probably no particularly portable +and non-invasive way to distinguish between read-only and read-write memory +mappings. The __tokencap_load_mappings() function is the only thing that would +need to be changed for other OSes. Porting to platforms with /proc/<pid>/maps +(e.g., FreeBSD) should be trivial. +
diff --git a/third_party/afl/src/libtokencap/libtokencap.so.c b/third_party/afl/src/libtokencap/libtokencap.so.c new file mode 100644 index 0000000..696c913 --- /dev/null +++ b/third_party/afl/src/libtokencap/libtokencap.so.c
@@ -0,0 +1,253 @@ +/* + + american fuzzy lop - extract tokens passed to strcmp / memcmp + ------------------------------------------------------------- + + Written and maintained by Michal Zalewski <lcamtuf@google.com> + + Copyright 2016 Google Inc. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at: + + http://www.apache.org/licenses/LICENSE-2.0 + + This Linux-only companion library allows you to instrument strcmp(), + memcmp(), and related functions to automatically extract tokens. + See README.tokencap for more info. + + */ + +#include <stdio.h> +#include <string.h> +#include <ctype.h> + +#include "../types.h" +#include "../config.h" + +#ifndef __linux__ +# error "Sorry, this library is Linux-specific for now!" +#endif /* !__linux__ */ + + +/* Mapping data and such */ + +#define MAX_MAPPINGS 1024 + +static struct mapping { + void *st, *en; +} __tokencap_ro[MAX_MAPPINGS]; + +static u32 __tokencap_ro_cnt; +static u8 __tokencap_ro_loaded; +static FILE* __tokencap_out_file; + + +/* Identify read-only regions in memory. Only parameters that fall into these + ranges are worth dumping when passed to strcmp() and so on. Read-write + regions are far more likely to contain user input instead. */ + +static void __tokencap_load_mappings(void) { + + u8 buf[MAX_LINE]; + FILE* f = fopen("/proc/self/maps", "r"); + + __tokencap_ro_loaded = 1; + + if (!f) return; + + while (fgets(buf, MAX_LINE, f)) { + + u8 rf, wf; + void* st, *en; + + if (sscanf(buf, "%p-%p %c%c", &st, &en, &rf, &wf) != 4) continue; + if (wf == 'w' || rf != 'r') continue; + + __tokencap_ro[__tokencap_ro_cnt].st = (void*)st; + __tokencap_ro[__tokencap_ro_cnt].en = (void*)en; + + if (++__tokencap_ro_cnt == MAX_MAPPINGS) break; + + } + + fclose(f); + +} + + +/* Check an address against the list of read-only mappings. */ + +static u8 __tokencap_is_ro(const void* ptr) { + + u32 i; + + if (!__tokencap_ro_loaded) __tokencap_load_mappings(); + + for (i = 0; i < __tokencap_ro_cnt; i++) + if (ptr >= __tokencap_ro[i].st && ptr <= __tokencap_ro[i].en) return 1; + + return 0; + +} + + +/* Dump an interesting token to output file, quoting and escaping it + properly. */ + +static void __tokencap_dump(const u8* ptr, size_t len, u8 is_text) { + + u8 buf[MAX_AUTO_EXTRA * 4 + 1]; + u32 i; + u32 pos = 0; + + if (len < MIN_AUTO_EXTRA || len > MAX_AUTO_EXTRA) return; + + for (i = 0; i < len; i++) { + + if (is_text && !ptr[i]) break; + + switch (ptr[i]) { + + case 0 ... 31: + case 127 ... 255: + case '\"': + case '\\': + + sprintf(buf + pos, "\\x%02x", ptr[i]); + pos += 4; + break; + + default: + + buf[pos++] = ptr[i]; + + } + + } + + buf[pos] = 0; + + fprintf(__tokencap_out_file, "\"%s\"\n", buf); + +} + + +/* Replacements for strcmp(), memcmp(), and so on. Note that these will be used + only if the target is compiled with -fno-builtins and linked dynamically. */ + +#undef strcmp + +int strcmp(const char* str1, const char* str2) { + + if (__tokencap_is_ro(str1)) __tokencap_dump(str1, strlen(str1), 1); + if (__tokencap_is_ro(str2)) __tokencap_dump(str2, strlen(str2), 1); + + while (1) { + + unsigned char c1 = *str1, c2 = *str2; + + if (c1 != c2) return (c1 > c2) ? 1 : -1; + if (!c1) return 0; + str1++; str2++; + + } + +} + + +#undef strncmp + +int strncmp(const char* str1, const char* str2, size_t len) { + + if (__tokencap_is_ro(str1)) __tokencap_dump(str1, len, 1); + if (__tokencap_is_ro(str2)) __tokencap_dump(str2, len, 1); + + while (len--) { + + unsigned char c1 = *str1, c2 = *str2; + + if (!c1) return 0; + if (c1 != c2) return (c1 > c2) ? 1 : -1; + str1++; str2++; + + } + + return 0; + +} + + +#undef strcasecmp + +int strcasecmp(const char* str1, const char* str2) { + + if (__tokencap_is_ro(str1)) __tokencap_dump(str1, strlen(str1), 1); + if (__tokencap_is_ro(str2)) __tokencap_dump(str2, strlen(str2), 1); + + while (1) { + + unsigned char c1 = tolower(*str1), c2 = tolower(*str2); + + if (c1 != c2) return (c1 > c2) ? 1 : -1; + if (!c1) return 0; + str1++; str2++; + + } + +} + + +#undef strncasecmp + +int strncasecmp(const char* str1, const char* str2, size_t len) { + + if (__tokencap_is_ro(str1)) __tokencap_dump(str1, len, 1); + if (__tokencap_is_ro(str2)) __tokencap_dump(str2, len, 1); + + while (len--) { + + unsigned char c1 = tolower(*str1), c2 = tolower(*str2); + + if (!c1) return 0; + if (c1 != c2) return (c1 > c2) ? 1 : -1; + str1++; str2++; + + } + + return 0; + +} + + +#undef memcmp + +int memcmp(const void* mem1, const void* mem2, size_t len) { + + if (__tokencap_is_ro(mem1)) __tokencap_dump(mem1, len, 0); + if (__tokencap_is_ro(mem2)) __tokencap_dump(mem2, len, 0); + + while (len--) { + + unsigned char c1 = *(const char*)mem1, c2 = *(const char*)mem2; + if (c1 != c2) return (c1 > c2) ? 1 : -1; + mem1++; mem2++; + + } + + return 0; + +} + + +/* Init code to open the output file (or default to stderr). */ + +__attribute__((constructor)) void __tokencap_init(void) { + + u8* fn = getenv("AFL_TOKEN_FILE"); + if (fn) __tokencap_out_file = fopen(fn, "a"); + if (!__tokencap_out_file) __tokencap_out_file = stderr; + +} +
diff --git a/third_party/afl/src/llvm_mode/Makefile b/third_party/afl/src/llvm_mode/Makefile index 46b3678..5d4da94 100644 --- a/third_party/afl/src/llvm_mode/Makefile +++ b/third_party/afl/src/llvm_mode/Makefile
@@ -20,7 +20,7 @@ HELPER_PATH = $(PREFIX)/lib/afl BIN_PATH = $(PREFIX)/bin -VERSION = $(shell grep ^VERSION ../Makefile | cut -d= -f2 | sed 's/ //') +VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2) LLVM_CONFIG ?= llvm-config
diff --git a/third_party/afl/src/llvm_mode/README.llvm b/third_party/afl/src/llvm_mode/README.llvm index f3789e2..f7d48c91 100644 --- a/third_party/afl/src/llvm_mode/README.llvm +++ b/third_party/afl/src/llvm_mode/README.llvm
@@ -161,11 +161,6 @@ waste a whole lot of CPU power doing nothing useful at all. Be particularly wary of memory leaks and of the state of file descriptors. -When running in this mode, the execution paths will inherently vary a bit -depending on whether the input loop is being entered for the first time or -executed again. To avoid spurious warnings, the feature implies -AFL_NO_VAR_CHECK and hides the "variable path" warnings in the UI. - PS. Because there are task switches still involved, the mode isn't as fast as "pure" in-process fuzzing offered, say, by LLVM's LibFuzzer; but it is a lot faster than the normal fork() model, and compared to in-process fuzzing,
diff --git a/third_party/afl/src/llvm_mode/afl-clang-fast.c b/third_party/afl/src/llvm_mode/afl-clang-fast.c index b9cedea9..725a16f 100644 --- a/third_party/afl/src/llvm_mode/afl-clang-fast.c +++ b/third_party/afl/src/llvm_mode/afl-clang-fast.c
@@ -99,7 +99,7 @@ u8 fortify_set = 0, asan_set = 0, x_set = 0, maybe_linking = 1, bit_mode = 0; u8 *name; - cc_params = ck_alloc((argc + 64) * sizeof(u8*)); + cc_params = ck_alloc((argc + 128) * sizeof(u8*)); name = strrchr(argv[0], '/'); if (!name) name = argv[0]; else name++; @@ -130,6 +130,10 @@ cc_params[cc_par_cnt++] = "-Qunused-arguments"; + /* Detect stray -v calls from ./configure scripts. */ + + if (argc == 1 && !strcmp(argv[1], "-v")) maybe_linking = 0; + while (--argc) { u8* cur = *(++argv); @@ -138,8 +142,8 @@ if (!strcmp(cur, "-x")) x_set = 1; - if (!strcmp(cur, "-c") || !strcmp(cur, "-S") || !strcmp(cur, "-E") || - !strcmp(cur, "-v")) maybe_linking = 0; + if (!strcmp(cur, "-c") || !strcmp(cur, "-S") || !strcmp(cur, "-E")) + maybe_linking = 0; if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory")) asan_set = 1; @@ -196,6 +200,16 @@ } + if (getenv("AFL_NO_BUILTIN")) { + + cc_params[cc_par_cnt++] = "-fno-builtin-strcmp"; + cc_params[cc_par_cnt++] = "-fno-builtin-strncmp"; + cc_params[cc_par_cnt++] = "-fno-builtin-strcasecmp"; + cc_params[cc_par_cnt++] = "-fno-builtin-strncasecmp"; + cc_params[cc_par_cnt++] = "-fno-builtin-memcmp"; + + } + cc_params[cc_par_cnt++] = "-D__AFL_HAVE_MANUAL_CONTROL=1"; cc_params[cc_par_cnt++] = "-D__AFL_COMPILER=1"; cc_params[cc_par_cnt++] = "-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION=1";
diff --git a/third_party/afl/src/llvm_mode/afl-llvm-rt.o.c b/third_party/afl/src/llvm_mode/afl-llvm-rt.o.c index 8f3f303d..e2ef151 100644 --- a/third_party/afl/src/llvm_mode/afl-llvm-rt.o.c +++ b/third_party/afl/src/llvm_mode/afl-llvm-rt.o.c
@@ -26,6 +26,7 @@ #include <stdlib.h> #include <signal.h> #include <unistd.h> +#include <string.h> #include <assert.h> #include <sys/mman.h> @@ -169,18 +170,48 @@ if (first_pass) { + /* Make sure that every iteration of __AFL_LOOP() starts with a clean slate. + On subsequent calls, the parent will take care of that, but on the first + iteration, it's our job to erase any trace of whatever happened + before the loop. */ + + if (is_persistent) { + + memset(__afl_area_ptr, 0, MAP_SIZE); + __afl_area_ptr[0] = 1; + __afl_prev_loc = 0; + } + cycle_cnt = max_cnt; first_pass = 0; return 1; } - if (is_persistent && --cycle_cnt) { + if (is_persistent) { - raise(SIGSTOP); - return 1; + if (--cycle_cnt) { - } else return 0; + raise(SIGSTOP); + + __afl_area_ptr[0] = 1; + __afl_prev_loc = 0; + + return 1; + + } else { + + /* When exiting __AFL_LOOP(), make sure that the subsequent code that + follows the loop is not traced. We do that by pivoting back to the + dummy output region. */ + + __afl_area_ptr = __afl_area_initial; + + } + + } + + return 0; }
diff --git a/third_party/afl/src/testcases/README.testcases b/third_party/afl/src/testcases/README.testcases new file mode 100644 index 0000000..30110ba --- /dev/null +++ b/third_party/afl/src/testcases/README.testcases
@@ -0,0 +1,19 @@ +======================= +AFL starting test cases +======================= + + (See ../docs/README for the general instruction manual.) + +The archives/, images/, multimedia/, and others/ subdirectories contain small, +standalone files that can be used to seed afl-fuzz when testing parsers for a +variety of common data formats. + +There is probably not much to be said about these files, except that they were +optimized for size and stripped of any non-essential fluff. Some directories +contain several examples that exercise various features of the underlying format. +For example, there is a PNG file with and without a color profile. + +Additional test cases are always welcome. + +In addition to well-chosen starting files, many fuzzing jobs benefit from a +small and concise dictionary. See ../dictionaries/README.dictionaries for more.
diff --git a/third_party/afl/src/testcases/archives/common/ar/small_archive.a b/third_party/afl/src/testcases/archives/common/ar/small_archive.a new file mode 100644 index 0000000..8c50bc2 --- /dev/null +++ b/third_party/afl/src/testcases/archives/common/ar/small_archive.a
@@ -0,0 +1,8 @@ +!<arch> +limerick/ 1415337776 500 500 100640 191 ` +There was a young man from Japan +Whose limericks never would scan. +When asked why that was, +He replied "It's because +I always try to cram as many words into the last line as I possibly can." +
diff --git a/third_party/afl/src/testcases/archives/common/bzip2/small_archive.bz2 b/third_party/afl/src/testcases/archives/common/bzip2/small_archive.bz2 new file mode 100644 index 0000000..83914ad2 --- /dev/null +++ b/third_party/afl/src/testcases/archives/common/bzip2/small_archive.bz2 Binary files differ
diff --git a/third_party/afl/src/testcases/archives/common/cab/small_archive.cab b/third_party/afl/src/testcases/archives/common/cab/small_archive.cab new file mode 100644 index 0000000..3f42904 --- /dev/null +++ b/third_party/afl/src/testcases/archives/common/cab/small_archive.cab Binary files differ
diff --git a/third_party/afl/src/testcases/archives/common/compress/small_archive.Z b/third_party/afl/src/testcases/archives/common/compress/small_archive.Z new file mode 100644 index 0000000..73bf315 --- /dev/null +++ b/third_party/afl/src/testcases/archives/common/compress/small_archive.Z Binary files differ
diff --git a/third_party/afl/src/testcases/archives/common/cpio/small_archive.cpio b/third_party/afl/src/testcases/archives/common/cpio/small_archive.cpio new file mode 100644 index 0000000..d1ee8a2c --- /dev/null +++ b/third_party/afl/src/testcases/archives/common/cpio/small_archive.cpio Binary files differ
diff --git a/third_party/afl/src/testcases/archives/common/gzip/small_archive.gz b/third_party/afl/src/testcases/archives/common/gzip/small_archive.gz new file mode 100644 index 0000000..4a6cd8e --- /dev/null +++ b/third_party/afl/src/testcases/archives/common/gzip/small_archive.gz Binary files differ
diff --git a/third_party/afl/src/testcases/archives/common/lzo/small_archive.lzo b/third_party/afl/src/testcases/archives/common/lzo/small_archive.lzo new file mode 100644 index 0000000..bf310368 --- /dev/null +++ b/third_party/afl/src/testcases/archives/common/lzo/small_archive.lzo Binary files differ
diff --git a/third_party/afl/src/testcases/archives/common/rar/small_archive.rar b/third_party/afl/src/testcases/archives/common/rar/small_archive.rar new file mode 100644 index 0000000..a5aae4c --- /dev/null +++ b/third_party/afl/src/testcases/archives/common/rar/small_archive.rar Binary files differ
diff --git a/third_party/afl/src/testcases/archives/common/tar/small_archive.tar b/third_party/afl/src/testcases/archives/common/tar/small_archive.tar new file mode 100644 index 0000000..8f694fd --- /dev/null +++ b/third_party/afl/src/testcases/archives/common/tar/small_archive.tar Binary files differ
diff --git a/third_party/afl/src/testcases/archives/common/xz/small_archive.xz b/third_party/afl/src/testcases/archives/common/xz/small_archive.xz new file mode 100644 index 0000000..f30df04f --- /dev/null +++ b/third_party/afl/src/testcases/archives/common/xz/small_archive.xz Binary files differ
diff --git a/third_party/afl/src/testcases/archives/common/zip/small_archive.zip b/third_party/afl/src/testcases/archives/common/zip/small_archive.zip new file mode 100644 index 0000000..dc7992c --- /dev/null +++ b/third_party/afl/src/testcases/archives/common/zip/small_archive.zip Binary files differ
diff --git a/third_party/afl/src/testcases/archives/exotic/arj/small_archive.arj b/third_party/afl/src/testcases/archives/exotic/arj/small_archive.arj new file mode 100644 index 0000000..8bcd12e --- /dev/null +++ b/third_party/afl/src/testcases/archives/exotic/arj/small_archive.arj Binary files differ
diff --git a/third_party/afl/src/testcases/archives/exotic/lha/small_archive.lha b/third_party/afl/src/testcases/archives/exotic/lha/small_archive.lha new file mode 100644 index 0000000..e70f325 --- /dev/null +++ b/third_party/afl/src/testcases/archives/exotic/lha/small_archive.lha Binary files differ
diff --git a/third_party/afl/src/testcases/archives/exotic/lrzip/small_archive.lrz b/third_party/afl/src/testcases/archives/exotic/lrzip/small_archive.lrz new file mode 100644 index 0000000..1a0415f --- /dev/null +++ b/third_party/afl/src/testcases/archives/exotic/lrzip/small_archive.lrz Binary files differ
diff --git a/third_party/afl/src/testcases/archives/exotic/lzip/small_archive.lz b/third_party/afl/src/testcases/archives/exotic/lzip/small_archive.lz new file mode 100644 index 0000000..89e2448 --- /dev/null +++ b/third_party/afl/src/testcases/archives/exotic/lzip/small_archive.lz Binary files differ
diff --git a/third_party/afl/src/testcases/archives/exotic/lzma/small_archive.lzma b/third_party/afl/src/testcases/archives/exotic/lzma/small_archive.lzma new file mode 100644 index 0000000..bbd056a --- /dev/null +++ b/third_party/afl/src/testcases/archives/exotic/lzma/small_archive.lzma Binary files differ
diff --git a/third_party/afl/src/testcases/archives/exotic/rzip/small_archive.rz b/third_party/afl/src/testcases/archives/exotic/rzip/small_archive.rz new file mode 100644 index 0000000..d1950c4 --- /dev/null +++ b/third_party/afl/src/testcases/archives/exotic/rzip/small_archive.rz Binary files differ
diff --git a/third_party/afl/src/testcases/archives/exotic/zoo/small_archive.zoo b/third_party/afl/src/testcases/archives/exotic/zoo/small_archive.zoo new file mode 100644 index 0000000..1614e5f --- /dev/null +++ b/third_party/afl/src/testcases/archives/exotic/zoo/small_archive.zoo Binary files differ
diff --git a/third_party/afl/src/testcases/images/bmp/not_kitty.bmp b/third_party/afl/src/testcases/images/bmp/not_kitty.bmp new file mode 100644 index 0000000..0309c928 --- /dev/null +++ b/third_party/afl/src/testcases/images/bmp/not_kitty.bmp Binary files differ
diff --git a/third_party/afl/src/testcases/images/gif/not_kitty.gif b/third_party/afl/src/testcases/images/gif/not_kitty.gif new file mode 100644 index 0000000..244fcc6 --- /dev/null +++ b/third_party/afl/src/testcases/images/gif/not_kitty.gif Binary files differ
diff --git a/third_party/afl/src/testcases/images/ico/not_kitty.ico b/third_party/afl/src/testcases/images/ico/not_kitty.ico new file mode 100644 index 0000000..d2bb291 --- /dev/null +++ b/third_party/afl/src/testcases/images/ico/not_kitty.ico Binary files differ
diff --git a/third_party/afl/src/testcases/images/jp2/not_kitty.jp2 b/third_party/afl/src/testcases/images/jp2/not_kitty.jp2 new file mode 100644 index 0000000..14bca292 --- /dev/null +++ b/third_party/afl/src/testcases/images/jp2/not_kitty.jp2 Binary files differ
diff --git a/third_party/afl/src/testcases/images/jpeg/not_kitty.jpg b/third_party/afl/src/testcases/images/jpeg/not_kitty.jpg new file mode 100644 index 0000000..0497be4 --- /dev/null +++ b/third_party/afl/src/testcases/images/jpeg/not_kitty.jpg Binary files differ
diff --git a/third_party/afl/src/testcases/images/jxr/not_kitty.jxr b/third_party/afl/src/testcases/images/jxr/not_kitty.jxr new file mode 100644 index 0000000..0fa2c8e --- /dev/null +++ b/third_party/afl/src/testcases/images/jxr/not_kitty.jxr Binary files differ
diff --git a/third_party/afl/src/testcases/images/png/not_kitty.png b/third_party/afl/src/testcases/images/png/not_kitty.png new file mode 100644 index 0000000..eff7c170 --- /dev/null +++ b/third_party/afl/src/testcases/images/png/not_kitty.png Binary files differ
diff --git a/third_party/afl/src/testcases/images/png/not_kitty_alpha.png b/third_party/afl/src/testcases/images/png/not_kitty_alpha.png new file mode 100644 index 0000000..2fb8da2 --- /dev/null +++ b/third_party/afl/src/testcases/images/png/not_kitty_alpha.png Binary files differ
diff --git a/third_party/afl/src/testcases/images/png/not_kitty_gamma.png b/third_party/afl/src/testcases/images/png/not_kitty_gamma.png new file mode 100644 index 0000000..939d9d2 --- /dev/null +++ b/third_party/afl/src/testcases/images/png/not_kitty_gamma.png Binary files differ
diff --git a/third_party/afl/src/testcases/images/png/not_kitty_icc.png b/third_party/afl/src/testcases/images/png/not_kitty_icc.png new file mode 100644 index 0000000..f0c7804d --- /dev/null +++ b/third_party/afl/src/testcases/images/png/not_kitty_icc.png Binary files differ
diff --git a/third_party/afl/src/testcases/images/tiff/not_kitty.tiff b/third_party/afl/src/testcases/images/tiff/not_kitty.tiff new file mode 100644 index 0000000..506ca1a --- /dev/null +++ b/third_party/afl/src/testcases/images/tiff/not_kitty.tiff Binary files differ
diff --git a/third_party/afl/src/testcases/images/webp/not_kitty.webp b/third_party/afl/src/testcases/images/webp/not_kitty.webp new file mode 100644 index 0000000..8592d823 --- /dev/null +++ b/third_party/afl/src/testcases/images/webp/not_kitty.webp Binary files differ
diff --git a/third_party/afl/src/testcases/multimedia/h264/small_movie.mp4 b/third_party/afl/src/testcases/multimedia/h264/small_movie.mp4 new file mode 100644 index 0000000..adc6c9c --- /dev/null +++ b/third_party/afl/src/testcases/multimedia/h264/small_movie.mp4 Binary files differ
diff --git a/third_party/afl/src/testcases/others/js/small_script.js b/third_party/afl/src/testcases/others/js/small_script.js new file mode 100644 index 0000000..bb632d8a --- /dev/null +++ b/third_party/afl/src/testcases/others/js/small_script.js
@@ -0,0 +1 @@ +if (1==1) eval('1'); \ No newline at end of file
diff --git a/third_party/afl/src/testcases/others/pcap/small_capture.pcap b/third_party/afl/src/testcases/others/pcap/small_capture.pcap new file mode 100644 index 0000000..60e2210 --- /dev/null +++ b/third_party/afl/src/testcases/others/pcap/small_capture.pcap Binary files differ
diff --git a/third_party/afl/src/testcases/others/pdf/small.pdf b/third_party/afl/src/testcases/others/pdf/small.pdf new file mode 100644 index 0000000..d31b4eb --- /dev/null +++ b/third_party/afl/src/testcases/others/pdf/small.pdf
@@ -0,0 +1,2 @@ +%PDF-1.0 +1 0 obj<</Type/Catalog/Pages 2 0 R>>endobj 2 0 obj<</Type/Pages/Kids[3 0 R]/Count 1>>endobj 3 0 obj<</Type/Page/MediaBox[0 0 3 3]>>endobj trailer<</Size 4/Root 1 0 R>> \ No newline at end of file
diff --git a/third_party/afl/src/testcases/others/rtf/small_document.rtf b/third_party/afl/src/testcases/others/rtf/small_document.rtf new file mode 100644 index 0000000..0fdedc32 --- /dev/null +++ b/third_party/afl/src/testcases/others/rtf/small_document.rtf
@@ -0,0 +1 @@ +{\rtf1\pard Test\par} \ No newline at end of file
diff --git a/third_party/afl/src/testcases/others/sql/simple_queries.sql b/third_party/afl/src/testcases/others/sql/simple_queries.sql new file mode 100644 index 0000000..5fff4072 --- /dev/null +++ b/third_party/afl/src/testcases/others/sql/simple_queries.sql
@@ -0,0 +1,3 @@ +create table t1(one smallint); +insert into t1 values(1); +select * from t1;
diff --git a/third_party/afl/src/testcases/others/text/hello_world.txt b/third_party/afl/src/testcases/others/text/hello_world.txt new file mode 100644 index 0000000..ce01362 --- /dev/null +++ b/third_party/afl/src/testcases/others/text/hello_world.txt
@@ -0,0 +1 @@ +hello
diff --git a/third_party/afl/src/testcases/others/xml/small_document.xml b/third_party/afl/src/testcases/others/xml/small_document.xml new file mode 100644 index 0000000..684e284 --- /dev/null +++ b/third_party/afl/src/testcases/others/xml/small_document.xml
@@ -0,0 +1 @@ +<a b="c">d</a>
diff --git a/third_party/afl/src/types.h b/third_party/afl/src/types.h index 58d6be5..21d32da6 100644 --- a/third_party/afl/src/types.h +++ b/third_party/afl/src/types.h
@@ -44,7 +44,7 @@ typedef unsigned long long u64; #else typedef uint64_t u64; -#endif /* ^sizeof(...) */ +#endif /* ^__x86_64__ */ typedef int8_t s8; typedef int16_t s16; @@ -76,4 +76,7 @@ #define MEM_BARRIER() \ asm volatile("" ::: "memory") +#define likely(_x) __builtin_expect(!!(_x), 1) +#define unlikely(_x) __builtin_expect(!!(_x), 0) + #endif /* ! _HAVE_TYPES_H */
diff --git a/third_party/afl/update.py b/third_party/afl/update.py new file mode 100755 index 0000000..0dd8df9 --- /dev/null +++ b/third_party/afl/update.py
@@ -0,0 +1,181 @@ +#! /usr/bin/env python +# Copyright (c) 2016 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 for updating AFL. Also updates AFL version in README.chromium. +""" + +import argparse +import cStringIO +import datetime +import os +import re +import sys +import tarfile +import urllib2 + + +VERSION_REGEX = r'(?P<version>([0-9]*[.])?[0-9]+b)' +PATH_REGEX = r'(afl-)' + VERSION_REGEX + + +class ChromiumReadme(object): + """Class that handles reading from and updating the README.chromium""" + + README_FILE_PATH = 'third_party/afl/README.chromium' + README_VERSION_REGEX = r'Version: ' + VERSION_REGEX + + def __init__(self): + """ + Inits the ChromiumReadme. + """ + with open(self.README_FILE_PATH) as readme_file_handle: + self.readme_contents = readme_file_handle.read() + + def get_current_version(self): + """ + Get the current version of AFL according to the README.chromium + """ + match = re.search(self.README_VERSION_REGEX, self.readme_contents) + if not match: + raise Exception('Could not determine current AFL version') + return match.groupdict()['version'] + + def update(self, new_version): + """ + Update the readme to reflect the new version that has been downloaded. + """ + new_readme = self.readme_contents + subsitutions = [(VERSION_REGEX, new_version), # Update the version. + (r'Date: .*', + 'Date: ' + datetime.date.today().strftime("%B %d, %Y")), + # Update the Local Modifications. + (PATH_REGEX + r'/', 'afl-' + new_version + '/')] + + for regex, replacement in subsitutions: + new_readme = re.subn(regex, replacement, new_readme, 1)[0] + + self.readme_contents = new_readme + with open(self.README_FILE_PATH, 'w+') as readme_file_handle: + readme_file_handle.write(self.readme_contents) + + +class AflTarball(object): + """ + Class that handles the afl-latest.tgz tarball. + """ + # Regexes that match files that we don't want to extract. + # Note that you should add these removals to "Local Modifications" in + # the README.chromium. + UNWANTED_FILE_REGEX = '|'.join([ + r'(.*\.elf)', # presubmit complains these aren't marked executable. + r'(.*others/elf)', # We don't need this if we have no elfs. + # checkdeps complains about #includes. + r'(.*afl-llvm-pass\.so\.cc)', + r'(.*argv.*)', # Delete the demo's directory as well. + + r'(.*dictionaries.*)', # Including these make builds fail. + ]) + AFL_SRC_DIR = 'third_party/afl/src' + + def __init__(self, version): + """ + Init this AFL tarball. + """ + release_name = 'afl-{0}'.format(version) + filename = '{0}.tgz'.format(release_name) + + # Note: lcamtuf.coredump.cx does not support TLS connections. The "http://" + # protocol is intentional. + self.url = "http://lcamtuf.coredump.cx/afl/releases/{0}".format(filename) + self.tarball = None + self.real_version = version if version != 'latest' else None + + def download(self): + """Download the tarball version from + http://lcamtuf.coredump.cx/afl/releases/ + """ + tarball_contents = urllib2.urlopen(self.url).read() + tarball_file = cStringIO.StringIO(tarball_contents) + self.tarball = tarfile.open(fileobj=tarball_file, mode="r:gz") + if self.real_version is None: + regex_match = re.search(VERSION_REGEX, self.tarball.members[0].path) + self.real_version = regex_match.groupdict()['version'] + + def extract(self): + """ + Extract the files and folders from the tarball we have downloaded while + skipping unwanted ones. + """ + + for member in self.tarball.getmembers(): + member.path = re.sub(PATH_REGEX, self.AFL_SRC_DIR, member.path) + if re.match(self.UNWANTED_FILE_REGEX, member.path): + print 'skipping unwanted file: {0}'.format(member.path) + continue + self.tarball.extract(member) + + +def version_to_float(version): + """ + Convert version string to float. + """ + if version.endswith('b'): + return float(version[:-1]) + + return float(version) + + +def update_afl(new_version): + """ + Update this version of AFL to newer version, new_version. + """ + readme = ChromiumReadme() + old_version = readme.get_current_version() + if new_version != 'latest': + new_float = version_to_float(new_version) + assert version_to_float(old_version) < new_float, ( + 'Trying to update from version {0} to {1}'.format(old_version, + new_version)) + + # Extract the tarball. + tarball = AflTarball(new_version) + tarball.download() + current_less_than_new = version_to_float(old_version) < version_to_float( + tarball.real_version) + assert current_less_than_new, ( + 'Trying to update from version {0} to {1}'.format(old_version, + tarball.real_version)) + + tarball.extract() + + readme.update(tarball.real_version) + + +def main(): + """ + Update AFL if possible. + """ + parser = argparse.ArgumentParser('Update AFL.') + parser.add_argument('version', metavar='version', default='latest', nargs='?', + help='(optional) Version to update AFL to.') + + args = parser.parse_args() + version = args.version + if version != 'latest' and not version.endswith('b'): + version += 'b' + + in_correct_directory = (os.path.basename(os.getcwd()) == 'src' and + os.path.exists('third_party')) + + assert in_correct_directory, ( + '{0} must be run from the repo\'s root'.format(sys.argv[0])) + + update_afl(version) + print ("Run git diff third_party/afl/src/docs/ChangeLog to see changes to AFL" + " since the last roll") + + +if __name__ == '__main__': + main()
diff --git a/third_party/blimp_fonts/BUILD.gn b/third_party/blimp_fonts/BUILD.gn index 96c1926..9ca01a85 100644 --- a/third_party/blimp_fonts/BUILD.gn +++ b/third_party/blimp_fonts/BUILD.gn
@@ -7,211 +7,298 @@ "LICENSE", "LICENSE.Apache", "LICENSE.OFL", - "font_bundle/AndroidClock.ttf", - "font_bundle/AndroidClock_Highlight.ttf", - "font_bundle/AndroidClock_Solid.ttf", - "font_bundle/CarroisGothicSC-Regular.ttf", - "font_bundle/Clockopia.ttf", - "font_bundle/ComingSoon.ttf", - "font_bundle/CutiveMono.ttf", - "font_bundle/DancingScript-Bold.ttf", - "font_bundle/DancingScript-Regular.ttf", - "font_bundle/DroidSansFallback.ttf", - "font_bundle/DroidSansFallbackFull.ttf", - "font_bundle/DroidSansMono.ttf", - "font_bundle/MTLc3m.ttf", - "font_bundle/MTLmr3m.ttf", - "font_bundle/NanumGothic.ttf", - "font_bundle/NanumGothicBold.ttf", - "font_bundle/NotoColorEmoji.ttf", - "font_bundle/NotoKufiArabic-Bold.ttf", - "font_bundle/NotoKufiArabic-Regular.ttf", - "font_bundle/NotoNaskhArabic-Bold.ttf", - "font_bundle/NotoNaskhArabic-Regular.ttf", - "font_bundle/NotoNaskhArabicUI-Bold.ttf", - "font_bundle/NotoNaskhArabicUI-Regular.ttf", - "font_bundle/NotoSans-Bold.ttf", - "font_bundle/NotoSans-BoldItalic.ttf", - "font_bundle/NotoSans-Italic.ttf", - "font_bundle/NotoSans-Regular.ttf", - "font_bundle/NotoSansArmenian-Bold.ttf", - "font_bundle/NotoSansArmenian-Regular.ttf", - "font_bundle/NotoSansAvestan-Regular.ttf", - "font_bundle/NotoSansBalinese-Regular.ttf", - "font_bundle/NotoSansBamum-Regular.ttf", - "font_bundle/NotoSansBatak-Regular.ttf", - "font_bundle/NotoSansBengali-Bold.ttf", - "font_bundle/NotoSansBengali-Regular.ttf", - "font_bundle/NotoSansBengaliUI-Bold.ttf", - "font_bundle/NotoSansBengaliUI-Regular.ttf", - "font_bundle/NotoSansBrahmi-Regular.ttf", - "font_bundle/NotoSansBuginese-Regular.ttf", - "font_bundle/NotoSansBuhid-Regular.ttf", - "font_bundle/NotoSansCanadianAboriginal-Regular.ttf", - "font_bundle/NotoSansCarian-Regular.ttf", - "font_bundle/NotoSansCham-Bold.ttf", - "font_bundle/NotoSansCham-Regular.ttf", - "font_bundle/NotoSansCherokee-Regular.ttf", - "font_bundle/NotoSansCoptic-Regular.ttf", - "font_bundle/NotoSansCuneiform-Regular.ttf", - "font_bundle/NotoSansCypriot-Regular.ttf", - "font_bundle/NotoSansDeseret-Regular.ttf", - "font_bundle/NotoSansDevanagari-Bold.ttf", - "font_bundle/NotoSansDevanagari-Regular.ttf", - "font_bundle/NotoSansDevanagariUI-Bold.ttf", - "font_bundle/NotoSansDevanagariUI-Regular.ttf", - "font_bundle/NotoSansEgyptianHieroglyphs-Regular.ttf", - "font_bundle/NotoSansEthiopic-Bold.ttf", - "font_bundle/NotoSansEthiopic-Regular.ttf", - "font_bundle/NotoSansGeorgian-Bold.ttf", - "font_bundle/NotoSansGeorgian-Regular.ttf", - "font_bundle/NotoSansGlagolitic-Regular.ttf", - "font_bundle/NotoSansGothic-Regular.ttf", - "font_bundle/NotoSansGujarati-Bold.ttf", - "font_bundle/NotoSansGujarati-Regular.ttf", - "font_bundle/NotoSansGujaratiUI-Bold.ttf", - "font_bundle/NotoSansGujaratiUI-Regular.ttf", - "font_bundle/NotoSansGurmukhi-Bold.ttf", - "font_bundle/NotoSansGurmukhi-Regular.ttf", - "font_bundle/NotoSansGurmukhiUI-Bold.ttf", - "font_bundle/NotoSansGurmukhiUI-Regular.ttf", - "font_bundle/NotoSansHanunoo-Regular.ttf", - "font_bundle/NotoSansHebrew-Bold.ttf", - "font_bundle/NotoSansHebrew-Regular.ttf", - "font_bundle/NotoSansImperialAramaic-Regular.ttf", - "font_bundle/NotoSansInscriptionalPahlavi-Regular.ttf", - "font_bundle/NotoSansInscriptionalParthian-Regular.ttf", - "font_bundle/NotoSansJP-Regular-Subsetted.otf", - "font_bundle/NotoSansJP-Regular.otf", - "font_bundle/NotoSansJavanese-Regular.ttf", - "font_bundle/NotoSansKR-Regular.otf", - "font_bundle/NotoSansKaithi-Regular.ttf", - "font_bundle/NotoSansKannada-Bold.ttf", - "font_bundle/NotoSansKannada-Regular.ttf", - "font_bundle/NotoSansKannadaUI-Bold.ttf", - "font_bundle/NotoSansKannadaUI-Regular.ttf", - "font_bundle/NotoSansKayahLi-Regular.ttf", - "font_bundle/NotoSansKharoshthi-Regular.ttf", - "font_bundle/NotoSansKhmer-Bold.ttf", - "font_bundle/NotoSansKhmer-Regular.ttf", - "font_bundle/NotoSansKhmerUI-Bold.ttf", - "font_bundle/NotoSansKhmerUI-Regular.ttf", - "font_bundle/NotoSansLao-Bold.ttf", - "font_bundle/NotoSansLao-Regular.ttf", - "font_bundle/NotoSansLaoUI-Bold.ttf", - "font_bundle/NotoSansLaoUI-Regular.ttf", - "font_bundle/NotoSansLepcha-Regular.ttf", - "font_bundle/NotoSansLimbu-Regular.ttf", - "font_bundle/NotoSansLinearB-Regular.ttf", - "font_bundle/NotoSansLisu-Regular.ttf", - "font_bundle/NotoSansLycian-Regular.ttf", - "font_bundle/NotoSansLydian-Regular.ttf", - "font_bundle/NotoSansMalayalam-Bold.ttf", - "font_bundle/NotoSansMalayalam-Regular.ttf", - "font_bundle/NotoSansMalayalamUI-Bold.ttf", - "font_bundle/NotoSansMalayalamUI-Regular.ttf", - "font_bundle/NotoSansMandaic-Regular.ttf", - "font_bundle/NotoSansMeeteiMayek-Regular.ttf", - "font_bundle/NotoSansMongolian-Regular.ttf", - "font_bundle/NotoSansMyanmar-Bold.ttf", - "font_bundle/NotoSansMyanmar-Regular.ttf", - "font_bundle/NotoSansMyanmarUI-Bold.ttf", - "font_bundle/NotoSansMyanmarUI-Regular.ttf", - "font_bundle/NotoSansNKo-Regular.ttf", - "font_bundle/NotoSansNewTaiLue-Regular.ttf", - "font_bundle/NotoSansOgham-Regular.ttf", - "font_bundle/NotoSansOlChiki-Regular.ttf", - "font_bundle/NotoSansOldItalic-Regular.ttf", - "font_bundle/NotoSansOldPersian-Regular.ttf", - "font_bundle/NotoSansOldSouthArabian-Regular.ttf", - "font_bundle/NotoSansOldTurkic-Regular.ttf", - "font_bundle/NotoSansOriya-Bold.ttf", - "font_bundle/NotoSansOriya-Regular.ttf", - "font_bundle/NotoSansOriyaUI-Bold.ttf", - "font_bundle/NotoSansOriyaUI-Regular.ttf", - "font_bundle/NotoSansOsmanya-Regular.ttf", - "font_bundle/NotoSansPhagsPa-Regular.ttf", - "font_bundle/NotoSansPhoenician-Regular.ttf", - "font_bundle/NotoSansRejang-Regular.ttf", - "font_bundle/NotoSansRunic-Regular.ttf", - "font_bundle/NotoSansSC-Regular.otf", - "font_bundle/NotoSansSamaritan-Regular.ttf", - "font_bundle/NotoSansSaurashtra-Regular.ttf", - "font_bundle/NotoSansShavian-Regular.ttf", - "font_bundle/NotoSansSinhala-Bold.ttf", - "font_bundle/NotoSansSinhala-Regular.ttf", - "font_bundle/NotoSansSundanese-Regular.ttf", - "font_bundle/NotoSansSylotiNagri-Regular.ttf", - "font_bundle/NotoSansSymbols-Regular-Subsetted.ttf", - "font_bundle/NotoSansSymbols-Regular.ttf", - "font_bundle/NotoSansSyriacEastern-Regular.ttf", - "font_bundle/NotoSansSyriacEstrangela-Regular.ttf", - "font_bundle/NotoSansSyriacWestern-Regular.ttf", - "font_bundle/NotoSansTC-Regular.otf", - "font_bundle/NotoSansTagalog-Regular.ttf", - "font_bundle/NotoSansTagbanwa-Regular.ttf", - "font_bundle/NotoSansTaiLe-Regular.ttf", - "font_bundle/NotoSansTaiTham-Regular.ttf", - "font_bundle/NotoSansTaiViet-Regular.ttf", - "font_bundle/NotoSansTamil-Bold.ttf", - "font_bundle/NotoSansTamil-Regular.ttf", - "font_bundle/NotoSansTamilUI-Bold.ttf", - "font_bundle/NotoSansTamilUI-Regular.ttf", - "font_bundle/NotoSansTelugu-Bold.ttf", - "font_bundle/NotoSansTelugu-Regular.ttf", - "font_bundle/NotoSansTeluguUI-Bold.ttf", - "font_bundle/NotoSansTeluguUI-Regular.ttf", - "font_bundle/NotoSansThaana-Bold.ttf", - "font_bundle/NotoSansThaana-Regular.ttf", - "font_bundle/NotoSansThai-Bold.ttf", - "font_bundle/NotoSansThai-Regular.ttf", - "font_bundle/NotoSansThaiUI-Bold.ttf", - "font_bundle/NotoSansThaiUI-Regular.ttf", - "font_bundle/NotoSansTibetan-Regular.ttf", - "font_bundle/NotoSansTifinagh-Regular.ttf", - "font_bundle/NotoSansUI-Bold.ttf", - "font_bundle/NotoSansUI-BoldItalic.ttf", - "font_bundle/NotoSansUI-Italic.ttf", - "font_bundle/NotoSansUI-Regular.ttf", - "font_bundle/NotoSansUgaritic-Regular.ttf", - "font_bundle/NotoSansVai-Regular.ttf", - "font_bundle/NotoSansYi-Regular.ttf", - "font_bundle/NotoSerif-Bold.ttf", - "font_bundle/NotoSerif-BoldItalic.ttf", - "font_bundle/NotoSerif-Italic.ttf", - "font_bundle/NotoSerif-Regular.ttf", - "font_bundle/NotoSerifArmenian-Bold.ttf", - "font_bundle/NotoSerifArmenian-Regular.ttf", - "font_bundle/NotoSerifGeorgian-Bold.ttf", - "font_bundle/NotoSerifGeorgian-Regular.ttf", - "font_bundle/NotoSerifKhmer-Bold.ttf", - "font_bundle/NotoSerifKhmer-Regular.ttf", - "font_bundle/NotoSerifLao-Bold.ttf", - "font_bundle/NotoSerifLao-Regular.ttf", - "font_bundle/NotoSerifThai-Bold.ttf", - "font_bundle/NotoSerifThai-Regular.ttf", - "font_bundle/Roboto-Black.ttf", - "font_bundle/Roboto-BlackItalic.ttf", - "font_bundle/Roboto-Bold.ttf", - "font_bundle/Roboto-BoldItalic.ttf", - "font_bundle/Roboto-Italic.ttf", - "font_bundle/Roboto-Light.ttf", - "font_bundle/Roboto-LightItalic.ttf", - "font_bundle/Roboto-Medium.ttf", - "font_bundle/Roboto-MediumItalic.ttf", - "font_bundle/Roboto-Regular.ttf", - "font_bundle/Roboto-Thin.ttf", - "font_bundle/Roboto-ThinItalic.ttf", - "font_bundle/RobotoCondensed-Bold.ttf", - "font_bundle/RobotoCondensed-BoldItalic.ttf", - "font_bundle/RobotoCondensed-Italic.ttf", - "font_bundle/RobotoCondensed-Light.ttf", - "font_bundle/RobotoCondensed-LightItalic.ttf", - "font_bundle/RobotoCondensed-Regular.ttf", - "font_bundle/fonts.xml", + "font_bundle/kitkat/AndroidClock.ttf", + "font_bundle/kitkat/AndroidClock_Highlight.ttf", + "font_bundle/kitkat/AndroidClock_Solid.ttf", + "font_bundle/kitkat/AndroidEmoji.ttf", + "font_bundle/kitkat/Clockopia.ttf", + "font_bundle/kitkat/DroidKufi-Bold.ttf", + "font_bundle/kitkat/DroidKufi-Regular.ttf", + "font_bundle/kitkat/DroidNaskh-Bold.ttf", + "font_bundle/kitkat/DroidNaskh-Regular.ttf", + "font_bundle/kitkat/DroidNaskhUI-Regular.ttf", + "font_bundle/kitkat/DroidSans-Bold.ttf", + "font_bundle/kitkat/DroidSans.ttf", + "font_bundle/kitkat/DroidSansArabic.ttf", + "font_bundle/kitkat/DroidSansArmenian.ttf", + "font_bundle/kitkat/DroidSansEthiopic-Bold.ttf", + "font_bundle/kitkat/DroidSansEthiopic-Regular.ttf", + "font_bundle/kitkat/DroidSansFallback.ttf", + "font_bundle/kitkat/DroidSansFallbackFull.ttf", + "font_bundle/kitkat/DroidSansFallbackLegacy.ttf", + "font_bundle/kitkat/DroidSansGeorgian.ttf", + "font_bundle/kitkat/DroidSansHebrew-Bold.ttf", + "font_bundle/kitkat/DroidSansHebrew-Regular.ttf", + "font_bundle/kitkat/DroidSansJapanese.ttf", + "font_bundle/kitkat/DroidSansMono.ttf", + "font_bundle/kitkat/DroidSerif-Bold.ttf", + "font_bundle/kitkat/DroidSerif-BoldItalic.ttf", + "font_bundle/kitkat/DroidSerif-Italic.ttf", + "font_bundle/kitkat/DroidSerif-Regular.ttf", + "font_bundle/kitkat/MTLc3m.ttf", + "font_bundle/kitkat/MTLmr3m.ttf", + "font_bundle/kitkat/NanumGothic.ttf", + "font_bundle/kitkat/NanumGothicBold.ttf", + "font_bundle/kitkat/NotoColorEmoji.ttf", + "font_bundle/kitkat/NotoSansBengali-Bold.ttf", + "font_bundle/kitkat/NotoSansBengali-Regular.ttf", + "font_bundle/kitkat/NotoSansBengaliUI-Bold.ttf", + "font_bundle/kitkat/NotoSansBengaliUI-Regular.ttf", + "font_bundle/kitkat/NotoSansDevanagari-Bold.ttf", + "font_bundle/kitkat/NotoSansDevanagari-Regular.ttf", + "font_bundle/kitkat/NotoSansDevanagariUI-Bold.ttf", + "font_bundle/kitkat/NotoSansDevanagariUI-Regular.ttf", + "font_bundle/kitkat/NotoSansKannada-Bold.ttf", + "font_bundle/kitkat/NotoSansKannada-Regular.ttf", + "font_bundle/kitkat/NotoSansKannadaUI-Bold.ttf", + "font_bundle/kitkat/NotoSansKannadaUI-Regular.ttf", + "font_bundle/kitkat/NotoSansKhmer-Bold.ttf", + "font_bundle/kitkat/NotoSansKhmer-Regular.ttf", + "font_bundle/kitkat/NotoSansKhmerUI-Bold.ttf", + "font_bundle/kitkat/NotoSansKhmerUI-Regular.ttf", + "font_bundle/kitkat/NotoSansLao-Bold.ttf", + "font_bundle/kitkat/NotoSansLao-Regular.ttf", + "font_bundle/kitkat/NotoSansLaoUI-Bold.ttf", + "font_bundle/kitkat/NotoSansLaoUI-Regular.ttf", + "font_bundle/kitkat/NotoSansMalayalam-Bold.ttf", + "font_bundle/kitkat/NotoSansMalayalam-Regular.ttf", + "font_bundle/kitkat/NotoSansMalayalamUI-Bold.ttf", + "font_bundle/kitkat/NotoSansMalayalamUI-Regular.ttf", + "font_bundle/kitkat/NotoSansSymbols-Regular.ttf", + "font_bundle/kitkat/NotoSansTamil-Bold.ttf", + "font_bundle/kitkat/NotoSansTamil-Regular.ttf", + "font_bundle/kitkat/NotoSansTamilUI-Bold.ttf", + "font_bundle/kitkat/NotoSansTamilUI-Regular.ttf", + "font_bundle/kitkat/NotoSansTelugu-Bold.ttf", + "font_bundle/kitkat/NotoSansTelugu-Regular.ttf", + "font_bundle/kitkat/NotoSansTeluguUI-Bold.ttf", + "font_bundle/kitkat/NotoSansTeluguUI-Regular.ttf", + "font_bundle/kitkat/NotoSansThai-Bold.ttf", + "font_bundle/kitkat/NotoSansThai-Regular.ttf", + "font_bundle/kitkat/NotoSansThaiUI-Bold.ttf", + "font_bundle/kitkat/NotoSansThaiUI-Regular.ttf", + "font_bundle/kitkat/Padauk-book.ttf", + "font_bundle/kitkat/Padauk-bookbold.ttf", + "font_bundle/kitkat/Roboto-Bold.ttf", + "font_bundle/kitkat/Roboto-BoldItalic.ttf", + "font_bundle/kitkat/Roboto-Italic.ttf", + "font_bundle/kitkat/Roboto-Light.ttf", + "font_bundle/kitkat/Roboto-LightItalic.ttf", + "font_bundle/kitkat/Roboto-Regular.ttf", + "font_bundle/kitkat/Roboto-Thin.ttf", + "font_bundle/kitkat/Roboto-ThinItalic.ttf", + "font_bundle/kitkat/RobotoCondensed-Bold.ttf", + "font_bundle/kitkat/RobotoCondensed-BoldItalic.ttf", + "font_bundle/kitkat/RobotoCondensed-Italic.ttf", + "font_bundle/kitkat/RobotoCondensed-Regular.ttf", + "font_bundle/kitkat/fallback_fonts.xml", + "font_bundle/kitkat/system_fonts.xml", + "font_bundle/kitkat/vendor_fonts.xml", + "font_bundle/marshmallow/AndroidClock.ttf", + "font_bundle/marshmallow/AndroidClock_Highlight.ttf", + "font_bundle/marshmallow/AndroidClock_Solid.ttf", + "font_bundle/marshmallow/CarroisGothicSC-Regular.ttf", + "font_bundle/marshmallow/Clockopia.ttf", + "font_bundle/marshmallow/ComingSoon.ttf", + "font_bundle/marshmallow/CutiveMono.ttf", + "font_bundle/marshmallow/DancingScript-Bold.ttf", + "font_bundle/marshmallow/DancingScript-Regular.ttf", + "font_bundle/marshmallow/DroidSansFallback.ttf", + "font_bundle/marshmallow/DroidSansFallbackFull.ttf", + "font_bundle/marshmallow/DroidSansMono.ttf", + "font_bundle/marshmallow/MTLc3m.ttf", + "font_bundle/marshmallow/MTLmr3m.ttf", + "font_bundle/marshmallow/NanumGothic.ttf", + "font_bundle/marshmallow/NanumGothicBold.ttf", + "font_bundle/marshmallow/NotoColorEmoji.ttf", + "font_bundle/marshmallow/NotoKufiArabic-Bold.ttf", + "font_bundle/marshmallow/NotoKufiArabic-Regular.ttf", + "font_bundle/marshmallow/NotoNaskhArabic-Bold.ttf", + "font_bundle/marshmallow/NotoNaskhArabic-Regular.ttf", + "font_bundle/marshmallow/NotoNaskhArabicUI-Bold.ttf", + "font_bundle/marshmallow/NotoNaskhArabicUI-Regular.ttf", + "font_bundle/marshmallow/NotoSans-Bold.ttf", + "font_bundle/marshmallow/NotoSans-BoldItalic.ttf", + "font_bundle/marshmallow/NotoSans-Italic.ttf", + "font_bundle/marshmallow/NotoSans-Regular.ttf", + "font_bundle/marshmallow/NotoSansArmenian-Bold.ttf", + "font_bundle/marshmallow/NotoSansArmenian-Regular.ttf", + "font_bundle/marshmallow/NotoSansAvestan-Regular.ttf", + "font_bundle/marshmallow/NotoSansBalinese-Regular.ttf", + "font_bundle/marshmallow/NotoSansBamum-Regular.ttf", + "font_bundle/marshmallow/NotoSansBatak-Regular.ttf", + "font_bundle/marshmallow/NotoSansBengali-Bold.ttf", + "font_bundle/marshmallow/NotoSansBengali-Regular.ttf", + "font_bundle/marshmallow/NotoSansBengaliUI-Bold.ttf", + "font_bundle/marshmallow/NotoSansBengaliUI-Regular.ttf", + "font_bundle/marshmallow/NotoSansBrahmi-Regular.ttf", + "font_bundle/marshmallow/NotoSansBuginese-Regular.ttf", + "font_bundle/marshmallow/NotoSansBuhid-Regular.ttf", + "font_bundle/marshmallow/NotoSansCanadianAboriginal-Regular.ttf", + "font_bundle/marshmallow/NotoSansCarian-Regular.ttf", + "font_bundle/marshmallow/NotoSansCham-Bold.ttf", + "font_bundle/marshmallow/NotoSansCham-Regular.ttf", + "font_bundle/marshmallow/NotoSansCherokee-Regular.ttf", + "font_bundle/marshmallow/NotoSansCoptic-Regular.ttf", + "font_bundle/marshmallow/NotoSansCuneiform-Regular.ttf", + "font_bundle/marshmallow/NotoSansCypriot-Regular.ttf", + "font_bundle/marshmallow/NotoSansDeseret-Regular.ttf", + "font_bundle/marshmallow/NotoSansDevanagari-Bold.ttf", + "font_bundle/marshmallow/NotoSansDevanagari-Regular.ttf", + "font_bundle/marshmallow/NotoSansDevanagariUI-Bold.ttf", + "font_bundle/marshmallow/NotoSansDevanagariUI-Regular.ttf", + "font_bundle/marshmallow/NotoSansEgyptianHieroglyphs-Regular.ttf", + "font_bundle/marshmallow/NotoSansEthiopic-Bold.ttf", + "font_bundle/marshmallow/NotoSansEthiopic-Regular.ttf", + "font_bundle/marshmallow/NotoSansGeorgian-Bold.ttf", + "font_bundle/marshmallow/NotoSansGeorgian-Regular.ttf", + "font_bundle/marshmallow/NotoSansGlagolitic-Regular.ttf", + "font_bundle/marshmallow/NotoSansGothic-Regular.ttf", + "font_bundle/marshmallow/NotoSansGujarati-Bold.ttf", + "font_bundle/marshmallow/NotoSansGujarati-Regular.ttf", + "font_bundle/marshmallow/NotoSansGujaratiUI-Bold.ttf", + "font_bundle/marshmallow/NotoSansGujaratiUI-Regular.ttf", + "font_bundle/marshmallow/NotoSansGurmukhi-Bold.ttf", + "font_bundle/marshmallow/NotoSansGurmukhi-Regular.ttf", + "font_bundle/marshmallow/NotoSansGurmukhiUI-Bold.ttf", + "font_bundle/marshmallow/NotoSansGurmukhiUI-Regular.ttf", + "font_bundle/marshmallow/NotoSansHanunoo-Regular.ttf", + "font_bundle/marshmallow/NotoSansHebrew-Bold.ttf", + "font_bundle/marshmallow/NotoSansHebrew-Regular.ttf", + "font_bundle/marshmallow/NotoSansImperialAramaic-Regular.ttf", + "font_bundle/marshmallow/NotoSansInscriptionalPahlavi-Regular.ttf", + "font_bundle/marshmallow/NotoSansInscriptionalParthian-Regular.ttf", + "font_bundle/marshmallow/NotoSansJP-Regular-Subsetted.otf", + "font_bundle/marshmallow/NotoSansJP-Regular.otf", + "font_bundle/marshmallow/NotoSansJavanese-Regular.ttf", + "font_bundle/marshmallow/NotoSansKR-Regular.otf", + "font_bundle/marshmallow/NotoSansKaithi-Regular.ttf", + "font_bundle/marshmallow/NotoSansKannada-Bold.ttf", + "font_bundle/marshmallow/NotoSansKannada-Regular.ttf", + "font_bundle/marshmallow/NotoSansKannadaUI-Bold.ttf", + "font_bundle/marshmallow/NotoSansKannadaUI-Regular.ttf", + "font_bundle/marshmallow/NotoSansKayahLi-Regular.ttf", + "font_bundle/marshmallow/NotoSansKharoshthi-Regular.ttf", + "font_bundle/marshmallow/NotoSansKhmer-Bold.ttf", + "font_bundle/marshmallow/NotoSansKhmer-Regular.ttf", + "font_bundle/marshmallow/NotoSansKhmerUI-Bold.ttf", + "font_bundle/marshmallow/NotoSansKhmerUI-Regular.ttf", + "font_bundle/marshmallow/NotoSansLao-Bold.ttf", + "font_bundle/marshmallow/NotoSansLao-Regular.ttf", + "font_bundle/marshmallow/NotoSansLaoUI-Bold.ttf", + "font_bundle/marshmallow/NotoSansLaoUI-Regular.ttf", + "font_bundle/marshmallow/NotoSansLepcha-Regular.ttf", + "font_bundle/marshmallow/NotoSansLimbu-Regular.ttf", + "font_bundle/marshmallow/NotoSansLinearB-Regular.ttf", + "font_bundle/marshmallow/NotoSansLisu-Regular.ttf", + "font_bundle/marshmallow/NotoSansLycian-Regular.ttf", + "font_bundle/marshmallow/NotoSansLydian-Regular.ttf", + "font_bundle/marshmallow/NotoSansMalayalam-Bold.ttf", + "font_bundle/marshmallow/NotoSansMalayalam-Regular.ttf", + "font_bundle/marshmallow/NotoSansMalayalamUI-Bold.ttf", + "font_bundle/marshmallow/NotoSansMalayalamUI-Regular.ttf", + "font_bundle/marshmallow/NotoSansMandaic-Regular.ttf", + "font_bundle/marshmallow/NotoSansMeeteiMayek-Regular.ttf", + "font_bundle/marshmallow/NotoSansMongolian-Regular.ttf", + "font_bundle/marshmallow/NotoSansMyanmar-Bold.ttf", + "font_bundle/marshmallow/NotoSansMyanmar-Regular.ttf", + "font_bundle/marshmallow/NotoSansMyanmarUI-Bold.ttf", + "font_bundle/marshmallow/NotoSansMyanmarUI-Regular.ttf", + "font_bundle/marshmallow/NotoSansNKo-Regular.ttf", + "font_bundle/marshmallow/NotoSansNewTaiLue-Regular.ttf", + "font_bundle/marshmallow/NotoSansOgham-Regular.ttf", + "font_bundle/marshmallow/NotoSansOlChiki-Regular.ttf", + "font_bundle/marshmallow/NotoSansOldItalic-Regular.ttf", + "font_bundle/marshmallow/NotoSansOldPersian-Regular.ttf", + "font_bundle/marshmallow/NotoSansOldSouthArabian-Regular.ttf", + "font_bundle/marshmallow/NotoSansOldTurkic-Regular.ttf", + "font_bundle/marshmallow/NotoSansOriya-Bold.ttf", + "font_bundle/marshmallow/NotoSansOriya-Regular.ttf", + "font_bundle/marshmallow/NotoSansOriyaUI-Bold.ttf", + "font_bundle/marshmallow/NotoSansOriyaUI-Regular.ttf", + "font_bundle/marshmallow/NotoSansOsmanya-Regular.ttf", + "font_bundle/marshmallow/NotoSansPhagsPa-Regular.ttf", + "font_bundle/marshmallow/NotoSansPhoenician-Regular.ttf", + "font_bundle/marshmallow/NotoSansRejang-Regular.ttf", + "font_bundle/marshmallow/NotoSansRunic-Regular.ttf", + "font_bundle/marshmallow/NotoSansSC-Regular.otf", + "font_bundle/marshmallow/NotoSansSamaritan-Regular.ttf", + "font_bundle/marshmallow/NotoSansSaurashtra-Regular.ttf", + "font_bundle/marshmallow/NotoSansShavian-Regular.ttf", + "font_bundle/marshmallow/NotoSansSinhala-Bold.ttf", + "font_bundle/marshmallow/NotoSansSinhala-Regular.ttf", + "font_bundle/marshmallow/NotoSansSundanese-Regular.ttf", + "font_bundle/marshmallow/NotoSansSylotiNagri-Regular.ttf", + "font_bundle/marshmallow/NotoSansSymbols-Regular-Subsetted.ttf", + "font_bundle/marshmallow/NotoSansSymbols-Regular.ttf", + "font_bundle/marshmallow/NotoSansSyriacEastern-Regular.ttf", + "font_bundle/marshmallow/NotoSansSyriacEstrangela-Regular.ttf", + "font_bundle/marshmallow/NotoSansSyriacWestern-Regular.ttf", + "font_bundle/marshmallow/NotoSansTC-Regular.otf", + "font_bundle/marshmallow/NotoSansTagalog-Regular.ttf", + "font_bundle/marshmallow/NotoSansTagbanwa-Regular.ttf", + "font_bundle/marshmallow/NotoSansTaiLe-Regular.ttf", + "font_bundle/marshmallow/NotoSansTaiTham-Regular.ttf", + "font_bundle/marshmallow/NotoSansTaiViet-Regular.ttf", + "font_bundle/marshmallow/NotoSansTamil-Bold.ttf", + "font_bundle/marshmallow/NotoSansTamil-Regular.ttf", + "font_bundle/marshmallow/NotoSansTamilUI-Bold.ttf", + "font_bundle/marshmallow/NotoSansTamilUI-Regular.ttf", + "font_bundle/marshmallow/NotoSansTelugu-Bold.ttf", + "font_bundle/marshmallow/NotoSansTelugu-Regular.ttf", + "font_bundle/marshmallow/NotoSansTeluguUI-Bold.ttf", + "font_bundle/marshmallow/NotoSansTeluguUI-Regular.ttf", + "font_bundle/marshmallow/NotoSansThaana-Bold.ttf", + "font_bundle/marshmallow/NotoSansThaana-Regular.ttf", + "font_bundle/marshmallow/NotoSansThai-Bold.ttf", + "font_bundle/marshmallow/NotoSansThai-Regular.ttf", + "font_bundle/marshmallow/NotoSansThaiUI-Bold.ttf", + "font_bundle/marshmallow/NotoSansThaiUI-Regular.ttf", + "font_bundle/marshmallow/NotoSansTibetan-Regular.ttf", + "font_bundle/marshmallow/NotoSansTifinagh-Regular.ttf", + "font_bundle/marshmallow/NotoSansUI-Bold.ttf", + "font_bundle/marshmallow/NotoSansUI-BoldItalic.ttf", + "font_bundle/marshmallow/NotoSansUI-Italic.ttf", + "font_bundle/marshmallow/NotoSansUI-Regular.ttf", + "font_bundle/marshmallow/NotoSansUgaritic-Regular.ttf", + "font_bundle/marshmallow/NotoSansVai-Regular.ttf", + "font_bundle/marshmallow/NotoSansYi-Regular.ttf", + "font_bundle/marshmallow/NotoSerif-Bold.ttf", + "font_bundle/marshmallow/NotoSerif-BoldItalic.ttf", + "font_bundle/marshmallow/NotoSerif-Italic.ttf", + "font_bundle/marshmallow/NotoSerif-Regular.ttf", + "font_bundle/marshmallow/NotoSerifArmenian-Bold.ttf", + "font_bundle/marshmallow/NotoSerifArmenian-Regular.ttf", + "font_bundle/marshmallow/NotoSerifGeorgian-Bold.ttf", + "font_bundle/marshmallow/NotoSerifGeorgian-Regular.ttf", + "font_bundle/marshmallow/NotoSerifKhmer-Bold.ttf", + "font_bundle/marshmallow/NotoSerifKhmer-Regular.ttf", + "font_bundle/marshmallow/NotoSerifLao-Bold.ttf", + "font_bundle/marshmallow/NotoSerifLao-Regular.ttf", + "font_bundle/marshmallow/NotoSerifThai-Bold.ttf", + "font_bundle/marshmallow/NotoSerifThai-Regular.ttf", + "font_bundle/marshmallow/Roboto-Black.ttf", + "font_bundle/marshmallow/Roboto-BlackItalic.ttf", + "font_bundle/marshmallow/Roboto-Bold.ttf", + "font_bundle/marshmallow/Roboto-BoldItalic.ttf", + "font_bundle/marshmallow/Roboto-Italic.ttf", + "font_bundle/marshmallow/Roboto-Light.ttf", + "font_bundle/marshmallow/Roboto-LightItalic.ttf", + "font_bundle/marshmallow/Roboto-Medium.ttf", + "font_bundle/marshmallow/Roboto-MediumItalic.ttf", + "font_bundle/marshmallow/Roboto-Regular.ttf", + "font_bundle/marshmallow/Roboto-Thin.ttf", + "font_bundle/marshmallow/Roboto-ThinItalic.ttf", + "font_bundle/marshmallow/RobotoCondensed-Bold.ttf", + "font_bundle/marshmallow/RobotoCondensed-BoldItalic.ttf", + "font_bundle/marshmallow/RobotoCondensed-Italic.ttf", + "font_bundle/marshmallow/RobotoCondensed-Light.ttf", + "font_bundle/marshmallow/RobotoCondensed-LightItalic.ttf", + "font_bundle/marshmallow/RobotoCondensed-Regular.ttf", + "font_bundle/marshmallow/fonts.xml", ] outputs = [ - "$target_gen_dir/{{source_file_part}}", + "$root_gen_dir/{{source}}", ] }
diff --git a/third_party/blimp_fonts/LICENSE b/third_party/blimp_fonts/LICENSE index 3d6049f..81b3c95 100644 --- a/third_party/blimp_fonts/LICENSE +++ b/third_party/blimp_fonts/LICENSE
@@ -1,7 +1,7 @@ -All the font files are available in the font_bundle subdirectory. - Fonts under Apache License Version 2.0 license: +The font files below are in the font_bundle/marshmallow subdirectory. + AndroidClock.ttf AndroidClock_Highlight.ttf AndroidClock_Solid.ttf @@ -193,10 +193,95 @@ Roboto-ThinItalic.ttf Roboto-Thin.ttf +The font files below are in the font_bundle/kitkat subdirectory. + +AndroidClock_Highlight.ttf +AndroidClock_Solid.ttf +AndroidClock.ttf +AndroidEmoji.ttf +Clockopia.ttf +DroidKufi-Bold.ttf +DroidKufi-Regular.ttf +DroidNaskh-Bold.ttf +DroidNaskh-Regular.ttf +DroidNaskhUI-Regular.ttf +DroidSansArabic.ttf +DroidSansArmenian.ttf +DroidSans-Bold.ttf +DroidSansEthiopic-Bold.ttf +DroidSansEthiopic-Regular.ttf +DroidSansFallbackFull.ttf +DroidSansFallbackLegacy.ttf +DroidSansFallback.ttf +DroidSansGeorgian.ttf +DroidSansHebrew-Bold.ttf +DroidSansHebrew-Regular.ttf +DroidSansJapanese.ttf +DroidSansMono.ttf +DroidSans.ttf +DroidSerif-BoldItalic.ttf +DroidSerif-Bold.ttf +DroidSerif-Italic.ttf +DroidSerif-Regular.ttf +fallback_fonts.xml +MTLc3m.ttf +MTLmr3m.ttf +NotoColorEmoji.ttf +NotoSansBengali-Bold.ttf +NotoSansBengali-Regular.ttf +NotoSansBengaliUI-Bold.ttf +NotoSansBengaliUI-Regular.ttf +NotoSansDevanagari-Bold.ttf +NotoSansDevanagari-Regular.ttf +NotoSansDevanagariUI-Bold.ttf +NotoSansDevanagariUI-Regular.ttf +NotoSansKannada-Bold.ttf +NotoSansKannada-Regular.ttf +NotoSansKannadaUI-Bold.ttf +NotoSansKannadaUI-Regular.ttf +NotoSansKhmer-Bold.ttf +NotoSansKhmer-Regular.ttf +NotoSansKhmerUI-Bold.ttf +NotoSansKhmerUI-Regular.ttf +NotoSansLao-Bold.ttf +NotoSansLao-Regular.ttf +NotoSansLaoUI-Bold.ttf +NotoSansLaoUI-Regular.ttf +NotoSansMalayalam-Bold.ttf +NotoSansMalayalam-Regular.ttf +NotoSansMalayalamUI-Bold.ttf +NotoSansMalayalamUI-Regular.ttf +NotoSansSymbols-Regular.ttf +NotoSansTamil-Bold.ttf +NotoSansTamil-Regular.ttf +NotoSansTamilUI-Bold.ttf +NotoSansTamilUI-Regular.ttf +NotoSansTelugu-Bold.ttf +NotoSansTelugu-Regular.ttf +NotoSansTeluguUI-Bold.ttf +NotoSansTeluguUI-Regular.ttf +NotoSansThai-Bold.ttf +NotoSansThai-Regular.ttf +NotoSansThaiUI-Bold.ttf +NotoSansThaiUI-Regular.ttf +Roboto-BoldItalic.ttf +Roboto-Bold.ttf +RobotoCondensed-BoldItalic.ttf +RobotoCondensed-Bold.ttf +RobotoCondensed-Italic.ttf +RobotoCondensed-Regular.ttf +Roboto-Italic.ttf +Roboto-LightItalic.ttf +Roboto-Light.ttf +Roboto-Regular.ttf +Roboto-ThinItalic.ttf +Roboto-Thin.ttf + Fonts under SIL Open Font License, Version 1.1: (Full license in LICENSE.OFL) +The font files below are in the font_bundle/marshmallow subdirectory. NotoSansJP-Regular.otf NotoSansJP-Regular-Subsetted.otf NotoSansKR-Regular.otf @@ -207,6 +292,7 @@ Copyright (c) 2011 by Ralph du Carrois, with Reserved Font Name 'Carrois' This Font Software is licensed under the SIL Open Font License, Version 1.1 (Full license in LICENSE.OFL) +The font files below are in the font_bundle/marshmallow subdirectory. CarroisGothicSC-Regular.ttf @@ -216,6 +302,7 @@ This Font Software is licensed under the SIL Open Font License, Version 1.1. (Full license in LICENSE.OFL) +The font files below are in the font_bundle/marshmallow subdirectory. DancingScript-Bold.ttf DancingScript-Regular.ttf CutiveMono.ttf @@ -228,5 +315,31 @@ This Font Software is licensed under the SIL Open Font License, Version 1.1. (Full license in LICENSE.OFL) +The files below are in the font_bundle/marshmallow subdirectory. NanumGothicBold.ttf NanumGothic.ttf + + +Copyright (c) 2010, NHN Corporation (http://www.nhncorp.com), + (http://hangeul.naver.com/font) +with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver NanumGothic, NanumMyeongjo, Naver NanumMyeongjo, NanumBrush, Naver NanumBrush, NanumPen, Naver NanumPen, Naver NanumGothicEco, NanumGothicEco, Naver NanumMyeongjoEco, NanumMyeongjoEco, Naver NanumGothicLight, NanumGothicLight + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + +The files below are in the font_bundle/kitkat subdirectory. +NanumGothicBold.ttf +NanumGothic.ttf + + +Copyright SIL International, all rights reserved +Reserved names: "Padauk" + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + +The files below are in the font_bundle/kitkat subdirectory. +Padauk-bookbold.ttf +Padauk-book.ttf
diff --git a/third_party/blimp_fonts/README.chromium b/third_party/blimp_fonts/README.chromium index 380be7c8..14b75a9 100644 --- a/third_party/blimp_fonts/README.chromium +++ b/third_party/blimp_fonts/README.chromium
@@ -24,10 +24,12 @@ Fonts are pulled from the following repositories: - Git repo: https://android.googlesource.com/platform/frameworks/base.git - Commit: 6a278db4c4a144829353e81420f28dcf2105f767 + Commit: 6a278db4c4a144829353e81420f28dcf2105f767 (marshmallow) + e89d3c9cebf59a6062974e9d2993adbddeaa4fef (KTU84Z) Directory: data/fonts/ - Git repo: https://android.googlesource.com/platform/external/noto-fonts.git - Commit: eb0883544dd538edbfb52cce9a2481509ca5ee9f + Commit: eb0883544dd538edbfb52cce9a2481509ca5ee9f (marshmallow) + 90372d894b5d9c9f2a111315d2eb3b8de1979ee4 (KTU84Z) Directory: cjk/, other/ - Git repo: https://android.googlesource.com/platform/external/roboto-fonts.git Commit: f5cf79102af594c746627b392b4f98eedd254571 @@ -45,5 +47,9 @@ Commit: 0062a10458d4c357f3082d66bcb129d11913aaae Directory: . - Git repo: https://android.googlesource.com/platform/external/naver-fonts.git - Commit: 91e6e9f94d1d769a8f742649674149ba98ce7d45 + Commit: 91e6e9f94d1d769a8f742649674149ba98ce7d45 (marshmallow) + 9238a39d60763f81b98d96f02b087d52b9d4fd52 (KTU84Z) + Directory: . +- Git repo: https://android.googlesource.com/platform/external/sil-fonts.git + Commit: 795a2f4339f8a82d6cff187e2a77bb01d5911aac (KTU84Z) Directory: .
diff --git a/third_party/blimp_fonts/font_bundle.tar.gz.sha1 b/third_party/blimp_fonts/font_bundle.tar.gz.sha1 index 6f9580b..409daa6 100644 --- a/third_party/blimp_fonts/font_bundle.tar.gz.sha1 +++ b/third_party/blimp_fonts/font_bundle.tar.gz.sha1
@@ -1 +1 @@ -984e9006270dc2f2a1f54265fb5761d267824930 \ No newline at end of file +953cc0e3f7c2c58284e41bbc3b11a771fe9bb1fe \ No newline at end of file
diff --git a/third_party/boringssl/BUILD.generated.gni b/third_party/boringssl/BUILD.generated.gni index 8785f234..678a4416 100644 --- a/third_party/boringssl/BUILD.generated.gni +++ b/third_party/boringssl/BUILD.generated.gni
@@ -7,6 +7,7 @@ crypto_sources = [ "err_data.c", "src/crypto/aes/aes.c", + "src/crypto/aes/internal.h", "src/crypto/aes/mode_wrappers.c", "src/crypto/asn1/a_bitstr.c", "src/crypto/asn1/a_bool.c", @@ -27,6 +28,7 @@ "src/crypto/asn1/a_utctm.c", "src/crypto/asn1/a_utf8.c", "src/crypto/asn1/asn1_lib.c", + "src/crypto/asn1/asn1_locl.h", "src/crypto/asn1/asn1_par.c", "src/crypto/asn1/asn_pack.c", "src/crypto/asn1/f_enum.c", @@ -49,6 +51,7 @@ "src/crypto/bio/fd.c", "src/crypto/bio/file.c", "src/crypto/bio/hexdump.c", + "src/crypto/bio/internal.h", "src/crypto/bio/pair.c", "src/crypto/bio/printf.c", "src/crypto/bio/socket.c", @@ -64,12 +67,15 @@ "src/crypto/bn/exponentiation.c", "src/crypto/bn/gcd.c", "src/crypto/bn/generic.c", + "src/crypto/bn/internal.h", "src/crypto/bn/kronecker.c", "src/crypto/bn/montgomery.c", + "src/crypto/bn/montgomery_inv.c", "src/crypto/bn/mul.c", "src/crypto/bn/prime.c", "src/crypto/bn/random.c", "src/crypto/bn/rsaz_exp.c", + "src/crypto/bn/rsaz_exp.h", "src/crypto/bn/shift.c", "src/crypto/bn/sqrt.c", "src/crypto/buf/buf.c", @@ -77,6 +83,7 @@ "src/crypto/bytestring/ber.c", "src/crypto/bytestring/cbb.c", "src/crypto/bytestring/cbs.c", + "src/crypto/bytestring/internal.h", "src/crypto/chacha/chacha.c", "src/crypto/cipher/aead.c", "src/crypto/cipher/cipher.c", @@ -89,33 +96,43 @@ "src/crypto/cipher/e_rc4.c", "src/crypto/cipher/e_ssl3.c", "src/crypto/cipher/e_tls.c", + "src/crypto/cipher/internal.h", "src/crypto/cipher/tls_cbc.c", "src/crypto/cmac/cmac.c", "src/crypto/conf/conf.c", + "src/crypto/conf/conf_def.h", + "src/crypto/conf/internal.h", "src/crypto/cpu-aarch64-linux.c", "src/crypto/cpu-arm-linux.c", "src/crypto/cpu-arm.c", "src/crypto/cpu-intel.c", "src/crypto/crypto.c", "src/crypto/curve25519/curve25519.c", + "src/crypto/curve25519/internal.h", "src/crypto/curve25519/spake25519.c", "src/crypto/curve25519/x25519-x86_64.c", "src/crypto/des/des.c", + "src/crypto/des/internal.h", "src/crypto/dh/check.c", "src/crypto/dh/dh.c", "src/crypto/dh/dh_asn1.c", + "src/crypto/dh/internal.h", "src/crypto/dh/params.c", "src/crypto/digest/digest.c", "src/crypto/digest/digests.c", + "src/crypto/digest/internal.h", + "src/crypto/digest/md32_common.h", "src/crypto/dsa/dsa.c", "src/crypto/dsa/dsa_asn1.c", "src/crypto/ec/ec.c", "src/crypto/ec/ec_asn1.c", "src/crypto/ec/ec_key.c", "src/crypto/ec/ec_montgomery.c", + "src/crypto/ec/internal.h", "src/crypto/ec/oct.c", "src/crypto/ec/p224-64.c", "src/crypto/ec/p256-64.c", + "src/crypto/ec/p256-x86_64-table.h", "src/crypto/ec/p256-x86_64.c", "src/crypto/ec/simple.c", "src/crypto/ec/util-64.c", @@ -129,6 +146,7 @@ "src/crypto/evp/evp.c", "src/crypto/evp/evp_asn1.c", "src/crypto/evp/evp_ctx.c", + "src/crypto/evp/internal.h", "src/crypto/evp/p_dsa_asn1.c", "src/crypto/evp/p_ec.c", "src/crypto/evp/p_ec_asn1.c", @@ -140,6 +158,7 @@ "src/crypto/ex_data.c", "src/crypto/hkdf/hkdf.c", "src/crypto/hmac/hmac.c", + "src/crypto/internal.h", "src/crypto/lhash/lhash.c", "src/crypto/md4/md4.c", "src/crypto/md5/md5.c", @@ -148,15 +167,19 @@ "src/crypto/modes/cfb.c", "src/crypto/modes/ctr.c", "src/crypto/modes/gcm.c", + "src/crypto/modes/internal.h", "src/crypto/modes/ofb.c", "src/crypto/newhope/error_correction.c", + "src/crypto/newhope/internal.h", "src/crypto/newhope/newhope.c", "src/crypto/newhope/ntt.c", "src/crypto/newhope/poly.c", "src/crypto/newhope/precomp.c", "src/crypto/newhope/reduce.c", "src/crypto/obj/obj.c", + "src/crypto/obj/obj_dat.h", "src/crypto/obj/obj_xref.c", + "src/crypto/obj/obj_xref.h", "src/crypto/pem/pem_all.c", "src/crypto/pem/pem_info.c", "src/crypto/pem/pem_lib.c", @@ -165,14 +188,17 @@ "src/crypto/pem/pem_pkey.c", "src/crypto/pem/pem_x509.c", "src/crypto/pem/pem_xaux.c", + "src/crypto/pkcs8/internal.h", "src/crypto/pkcs8/p5_pbe.c", "src/crypto/pkcs8/p5_pbev2.c", "src/crypto/pkcs8/p8_pkey.c", "src/crypto/pkcs8/pkcs8.c", + "src/crypto/poly1305/internal.h", "src/crypto/poly1305/poly1305.c", "src/crypto/poly1305/poly1305_arm.c", "src/crypto/poly1305/poly1305_vec.c", "src/crypto/rand/deterministic.c", + "src/crypto/rand/internal.h", "src/crypto/rand/rand.c", "src/crypto/rand/urandom.c", "src/crypto/rand/windows.c", @@ -180,6 +206,7 @@ "src/crypto/refcount_c11.c", "src/crypto/refcount_lock.c", "src/crypto/rsa/blinding.c", + "src/crypto/rsa/internal.h", "src/crypto/rsa/padding.c", "src/crypto/rsa/rsa.c", "src/crypto/rsa/rsa_asn1.c", @@ -201,13 +228,16 @@ "src/crypto/x509/asn1_gen.c", "src/crypto/x509/by_dir.c", "src/crypto/x509/by_file.c", + "src/crypto/x509/charmap.h", "src/crypto/x509/i2d_pr.c", + "src/crypto/x509/internal.h", "src/crypto/x509/pkcs7.c", "src/crypto/x509/rsa_pss.c", "src/crypto/x509/t_crl.c", "src/crypto/x509/t_req.c", "src/crypto/x509/t_x509.c", "src/crypto/x509/t_x509a.c", + "src/crypto/x509/vpm_int.h", "src/crypto/x509/x509.c", "src/crypto/x509/x509_att.c", "src/crypto/x509/x509_cmp.c", @@ -244,8 +274,10 @@ "src/crypto/x509/x_val.c", "src/crypto/x509/x_x509.c", "src/crypto/x509/x_x509a.c", + "src/crypto/x509v3/ext_dat.h", "src/crypto/x509v3/pcy_cache.c", "src/crypto/x509v3/pcy_data.c", + "src/crypto/x509v3/pcy_int.h", "src/crypto/x509v3/pcy_lib.c", "src/crypto/x509v3/pcy_map.c", "src/crypto/x509v3/pcy_node.c", @@ -276,9 +308,84 @@ "src/crypto/x509v3/v3_skey.c", "src/crypto/x509v3/v3_sxnet.c", "src/crypto/x509v3/v3_utl.c", + "src/include/openssl/aead.h", + "src/include/openssl/aes.h", + "src/include/openssl/arm_arch.h", + "src/include/openssl/asn1.h", + "src/include/openssl/asn1_mac.h", + "src/include/openssl/asn1t.h", + "src/include/openssl/base.h", + "src/include/openssl/base64.h", + "src/include/openssl/bio.h", + "src/include/openssl/blowfish.h", + "src/include/openssl/bn.h", + "src/include/openssl/buf.h", + "src/include/openssl/buffer.h", + "src/include/openssl/bytestring.h", + "src/include/openssl/c++/aead.h", + "src/include/openssl/c++/scoped_helpers.h", + "src/include/openssl/cast.h", + "src/include/openssl/chacha.h", + "src/include/openssl/cipher.h", + "src/include/openssl/cmac.h", + "src/include/openssl/conf.h", + "src/include/openssl/cpu.h", + "src/include/openssl/crypto.h", + "src/include/openssl/curve25519.h", + "src/include/openssl/des.h", + "src/include/openssl/dh.h", + "src/include/openssl/digest.h", + "src/include/openssl/dsa.h", + "src/include/openssl/ec.h", + "src/include/openssl/ec_key.h", + "src/include/openssl/ecdh.h", + "src/include/openssl/ecdsa.h", + "src/include/openssl/engine.h", + "src/include/openssl/err.h", + "src/include/openssl/evp.h", + "src/include/openssl/ex_data.h", + "src/include/openssl/hkdf.h", + "src/include/openssl/hmac.h", + "src/include/openssl/lhash.h", + "src/include/openssl/lhash_macros.h", + "src/include/openssl/md4.h", + "src/include/openssl/md5.h", + "src/include/openssl/mem.h", + "src/include/openssl/newhope.h", + "src/include/openssl/nid.h", + "src/include/openssl/obj.h", + "src/include/openssl/obj_mac.h", + "src/include/openssl/objects.h", + "src/include/openssl/opensslconf.h", + "src/include/openssl/opensslv.h", + "src/include/openssl/ossl_typ.h", + "src/include/openssl/pem.h", + "src/include/openssl/pkcs12.h", + "src/include/openssl/pkcs7.h", + "src/include/openssl/pkcs8.h", + "src/include/openssl/poly1305.h", + "src/include/openssl/rand.h", + "src/include/openssl/rc4.h", + "src/include/openssl/ripemd.h", + "src/include/openssl/rsa.h", + "src/include/openssl/safestack.h", + "src/include/openssl/sha.h", + "src/include/openssl/srtp.h", + "src/include/openssl/stack.h", + "src/include/openssl/stack_macros.h", + "src/include/openssl/thread.h", + "src/include/openssl/time_support.h", + "src/include/openssl/type_check.h", + "src/include/openssl/x509.h", + "src/include/openssl/x509_vfy.h", + "src/include/openssl/x509v3.h", ] ssl_sources = [ + "src/include/openssl/dtls1.h", + "src/include/openssl/ssl.h", + "src/include/openssl/ssl3.h", + "src/include/openssl/tls1.h", "src/ssl/custom_extensions.c", "src/ssl/d1_both.c", "src/ssl/d1_lib.c", @@ -288,6 +395,7 @@ "src/ssl/dtls_record.c", "src/ssl/handshake_client.c", "src/ssl/handshake_server.c", + "src/ssl/internal.h", "src/ssl/s3_both.c", "src/ssl/s3_enc.c", "src/ssl/s3_lib.c",
diff --git a/third_party/boringssl/boringssl.gypi b/third_party/boringssl/boringssl.gypi index 9a347c3..1229a7f 100644 --- a/third_party/boringssl/boringssl.gypi +++ b/third_party/boringssl/boringssl.gypi
@@ -7,6 +7,10 @@ { 'variables': { 'boringssl_ssl_sources': [ + 'src/include/openssl/dtls1.h', + 'src/include/openssl/ssl.h', + 'src/include/openssl/ssl3.h', + 'src/include/openssl/tls1.h', 'src/ssl/custom_extensions.c', 'src/ssl/d1_both.c', 'src/ssl/d1_lib.c', @@ -16,6 +20,7 @@ 'src/ssl/dtls_record.c', 'src/ssl/handshake_client.c', 'src/ssl/handshake_server.c', + 'src/ssl/internal.h', 'src/ssl/s3_both.c', 'src/ssl/s3_enc.c', 'src/ssl/s3_lib.c', @@ -43,6 +48,7 @@ 'boringssl_crypto_sources': [ 'err_data.c', 'src/crypto/aes/aes.c', + 'src/crypto/aes/internal.h', 'src/crypto/aes/mode_wrappers.c', 'src/crypto/asn1/a_bitstr.c', 'src/crypto/asn1/a_bool.c', @@ -63,6 +69,7 @@ 'src/crypto/asn1/a_utctm.c', 'src/crypto/asn1/a_utf8.c', 'src/crypto/asn1/asn1_lib.c', + 'src/crypto/asn1/asn1_locl.h', 'src/crypto/asn1/asn1_par.c', 'src/crypto/asn1/asn_pack.c', 'src/crypto/asn1/f_enum.c', @@ -85,6 +92,7 @@ 'src/crypto/bio/fd.c', 'src/crypto/bio/file.c', 'src/crypto/bio/hexdump.c', + 'src/crypto/bio/internal.h', 'src/crypto/bio/pair.c', 'src/crypto/bio/printf.c', 'src/crypto/bio/socket.c', @@ -100,12 +108,15 @@ 'src/crypto/bn/exponentiation.c', 'src/crypto/bn/gcd.c', 'src/crypto/bn/generic.c', + 'src/crypto/bn/internal.h', 'src/crypto/bn/kronecker.c', 'src/crypto/bn/montgomery.c', + 'src/crypto/bn/montgomery_inv.c', 'src/crypto/bn/mul.c', 'src/crypto/bn/prime.c', 'src/crypto/bn/random.c', 'src/crypto/bn/rsaz_exp.c', + 'src/crypto/bn/rsaz_exp.h', 'src/crypto/bn/shift.c', 'src/crypto/bn/sqrt.c', 'src/crypto/buf/buf.c', @@ -113,6 +124,7 @@ 'src/crypto/bytestring/ber.c', 'src/crypto/bytestring/cbb.c', 'src/crypto/bytestring/cbs.c', + 'src/crypto/bytestring/internal.h', 'src/crypto/chacha/chacha.c', 'src/crypto/cipher/aead.c', 'src/crypto/cipher/cipher.c', @@ -125,33 +137,43 @@ 'src/crypto/cipher/e_rc4.c', 'src/crypto/cipher/e_ssl3.c', 'src/crypto/cipher/e_tls.c', + 'src/crypto/cipher/internal.h', 'src/crypto/cipher/tls_cbc.c', 'src/crypto/cmac/cmac.c', 'src/crypto/conf/conf.c', + 'src/crypto/conf/conf_def.h', + 'src/crypto/conf/internal.h', 'src/crypto/cpu-aarch64-linux.c', 'src/crypto/cpu-arm-linux.c', 'src/crypto/cpu-arm.c', 'src/crypto/cpu-intel.c', 'src/crypto/crypto.c', 'src/crypto/curve25519/curve25519.c', + 'src/crypto/curve25519/internal.h', 'src/crypto/curve25519/spake25519.c', 'src/crypto/curve25519/x25519-x86_64.c', 'src/crypto/des/des.c', + 'src/crypto/des/internal.h', 'src/crypto/dh/check.c', 'src/crypto/dh/dh.c', 'src/crypto/dh/dh_asn1.c', + 'src/crypto/dh/internal.h', 'src/crypto/dh/params.c', 'src/crypto/digest/digest.c', 'src/crypto/digest/digests.c', + 'src/crypto/digest/internal.h', + 'src/crypto/digest/md32_common.h', 'src/crypto/dsa/dsa.c', 'src/crypto/dsa/dsa_asn1.c', 'src/crypto/ec/ec.c', 'src/crypto/ec/ec_asn1.c', 'src/crypto/ec/ec_key.c', 'src/crypto/ec/ec_montgomery.c', + 'src/crypto/ec/internal.h', 'src/crypto/ec/oct.c', 'src/crypto/ec/p224-64.c', 'src/crypto/ec/p256-64.c', + 'src/crypto/ec/p256-x86_64-table.h', 'src/crypto/ec/p256-x86_64.c', 'src/crypto/ec/simple.c', 'src/crypto/ec/util-64.c', @@ -165,6 +187,7 @@ 'src/crypto/evp/evp.c', 'src/crypto/evp/evp_asn1.c', 'src/crypto/evp/evp_ctx.c', + 'src/crypto/evp/internal.h', 'src/crypto/evp/p_dsa_asn1.c', 'src/crypto/evp/p_ec.c', 'src/crypto/evp/p_ec_asn1.c', @@ -176,6 +199,7 @@ 'src/crypto/ex_data.c', 'src/crypto/hkdf/hkdf.c', 'src/crypto/hmac/hmac.c', + 'src/crypto/internal.h', 'src/crypto/lhash/lhash.c', 'src/crypto/md4/md4.c', 'src/crypto/md5/md5.c', @@ -184,15 +208,19 @@ 'src/crypto/modes/cfb.c', 'src/crypto/modes/ctr.c', 'src/crypto/modes/gcm.c', + 'src/crypto/modes/internal.h', 'src/crypto/modes/ofb.c', 'src/crypto/newhope/error_correction.c', + 'src/crypto/newhope/internal.h', 'src/crypto/newhope/newhope.c', 'src/crypto/newhope/ntt.c', 'src/crypto/newhope/poly.c', 'src/crypto/newhope/precomp.c', 'src/crypto/newhope/reduce.c', 'src/crypto/obj/obj.c', + 'src/crypto/obj/obj_dat.h', 'src/crypto/obj/obj_xref.c', + 'src/crypto/obj/obj_xref.h', 'src/crypto/pem/pem_all.c', 'src/crypto/pem/pem_info.c', 'src/crypto/pem/pem_lib.c', @@ -201,14 +229,17 @@ 'src/crypto/pem/pem_pkey.c', 'src/crypto/pem/pem_x509.c', 'src/crypto/pem/pem_xaux.c', + 'src/crypto/pkcs8/internal.h', 'src/crypto/pkcs8/p5_pbe.c', 'src/crypto/pkcs8/p5_pbev2.c', 'src/crypto/pkcs8/p8_pkey.c', 'src/crypto/pkcs8/pkcs8.c', + 'src/crypto/poly1305/internal.h', 'src/crypto/poly1305/poly1305.c', 'src/crypto/poly1305/poly1305_arm.c', 'src/crypto/poly1305/poly1305_vec.c', 'src/crypto/rand/deterministic.c', + 'src/crypto/rand/internal.h', 'src/crypto/rand/rand.c', 'src/crypto/rand/urandom.c', 'src/crypto/rand/windows.c', @@ -216,6 +247,7 @@ 'src/crypto/refcount_c11.c', 'src/crypto/refcount_lock.c', 'src/crypto/rsa/blinding.c', + 'src/crypto/rsa/internal.h', 'src/crypto/rsa/padding.c', 'src/crypto/rsa/rsa.c', 'src/crypto/rsa/rsa_asn1.c', @@ -237,13 +269,16 @@ 'src/crypto/x509/asn1_gen.c', 'src/crypto/x509/by_dir.c', 'src/crypto/x509/by_file.c', + 'src/crypto/x509/charmap.h', 'src/crypto/x509/i2d_pr.c', + 'src/crypto/x509/internal.h', 'src/crypto/x509/pkcs7.c', 'src/crypto/x509/rsa_pss.c', 'src/crypto/x509/t_crl.c', 'src/crypto/x509/t_req.c', 'src/crypto/x509/t_x509.c', 'src/crypto/x509/t_x509a.c', + 'src/crypto/x509/vpm_int.h', 'src/crypto/x509/x509.c', 'src/crypto/x509/x509_att.c', 'src/crypto/x509/x509_cmp.c', @@ -280,8 +315,10 @@ 'src/crypto/x509/x_val.c', 'src/crypto/x509/x_x509.c', 'src/crypto/x509/x_x509a.c', + 'src/crypto/x509v3/ext_dat.h', 'src/crypto/x509v3/pcy_cache.c', 'src/crypto/x509v3/pcy_data.c', + 'src/crypto/x509v3/pcy_int.h', 'src/crypto/x509v3/pcy_lib.c', 'src/crypto/x509v3/pcy_map.c', 'src/crypto/x509v3/pcy_node.c', @@ -312,6 +349,77 @@ 'src/crypto/x509v3/v3_skey.c', 'src/crypto/x509v3/v3_sxnet.c', 'src/crypto/x509v3/v3_utl.c', + 'src/include/openssl/aead.h', + 'src/include/openssl/aes.h', + 'src/include/openssl/arm_arch.h', + 'src/include/openssl/asn1.h', + 'src/include/openssl/asn1_mac.h', + 'src/include/openssl/asn1t.h', + 'src/include/openssl/base.h', + 'src/include/openssl/base64.h', + 'src/include/openssl/bio.h', + 'src/include/openssl/blowfish.h', + 'src/include/openssl/bn.h', + 'src/include/openssl/buf.h', + 'src/include/openssl/buffer.h', + 'src/include/openssl/bytestring.h', + 'src/include/openssl/c++/aead.h', + 'src/include/openssl/c++/scoped_helpers.h', + 'src/include/openssl/cast.h', + 'src/include/openssl/chacha.h', + 'src/include/openssl/cipher.h', + 'src/include/openssl/cmac.h', + 'src/include/openssl/conf.h', + 'src/include/openssl/cpu.h', + 'src/include/openssl/crypto.h', + 'src/include/openssl/curve25519.h', + 'src/include/openssl/des.h', + 'src/include/openssl/dh.h', + 'src/include/openssl/digest.h', + 'src/include/openssl/dsa.h', + 'src/include/openssl/ec.h', + 'src/include/openssl/ec_key.h', + 'src/include/openssl/ecdh.h', + 'src/include/openssl/ecdsa.h', + 'src/include/openssl/engine.h', + 'src/include/openssl/err.h', + 'src/include/openssl/evp.h', + 'src/include/openssl/ex_data.h', + 'src/include/openssl/hkdf.h', + 'src/include/openssl/hmac.h', + 'src/include/openssl/lhash.h', + 'src/include/openssl/lhash_macros.h', + 'src/include/openssl/md4.h', + 'src/include/openssl/md5.h', + 'src/include/openssl/mem.h', + 'src/include/openssl/newhope.h', + 'src/include/openssl/nid.h', + 'src/include/openssl/obj.h', + 'src/include/openssl/obj_mac.h', + 'src/include/openssl/objects.h', + 'src/include/openssl/opensslconf.h', + 'src/include/openssl/opensslv.h', + 'src/include/openssl/ossl_typ.h', + 'src/include/openssl/pem.h', + 'src/include/openssl/pkcs12.h', + 'src/include/openssl/pkcs7.h', + 'src/include/openssl/pkcs8.h', + 'src/include/openssl/poly1305.h', + 'src/include/openssl/rand.h', + 'src/include/openssl/rc4.h', + 'src/include/openssl/ripemd.h', + 'src/include/openssl/rsa.h', + 'src/include/openssl/safestack.h', + 'src/include/openssl/sha.h', + 'src/include/openssl/srtp.h', + 'src/include/openssl/stack.h', + 'src/include/openssl/stack_macros.h', + 'src/include/openssl/thread.h', + 'src/include/openssl/time_support.h', + 'src/include/openssl/type_check.h', + 'src/include/openssl/x509.h', + 'src/include/openssl/x509_vfy.h', + 'src/include/openssl/x509v3.h', ], 'boringssl_linux_aarch64_sources': [ 'linux-aarch64/crypto/aes/aesv8-armx64.S',
diff --git a/third_party/boringssl/boringssl_unittest.cc b/third_party/boringssl/boringssl_unittest.cc index 068daff..9747713 100644 --- a/third_party/boringssl/boringssl_unittest.cc +++ b/third_party/boringssl/boringssl_unittest.cc
@@ -2,17 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <stdarg.h> - +#include <memory> #include <string> #include "base/base_paths.h" #include "base/command_line.h" #include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/logging.h" +#include "base/json/json_reader.h" #include "base/path_service.h" #include "base/process/launch.h" #include "base/strings/string_util.h" +#include "base/values.h" #include "testing/gtest/include/gtest/gtest.h" namespace { @@ -21,8 +23,7 @@ const std::vector<base::CommandLine::StringType>& args) { base::FilePath exe_dir; ASSERT_TRUE(PathService::Get(base::DIR_EXE, &exe_dir)); - base::FilePath test_binary = - exe_dir.AppendASCII("boringssl_" + name); + base::FilePath test_binary = exe_dir.AppendASCII("boringssl_" + name); base::CommandLine cmd(test_binary); for (size_t i = 0; i < args.size(); ++i) { @@ -41,11 +42,6 @@ EXPECT_TRUE(ok) << output; } -void TestSimple(const std::string& name) { - std::vector<base::CommandLine::StringType> empty; - TestProcess(name, empty); -} - bool BoringSSLPath(base::FilePath* result) { if (!PathService::Get(base::DIR_SOURCE_ROOT, result)) return false; @@ -56,295 +52,55 @@ return true; } -bool CryptoCipherTestPath(base::FilePath *result) { - if (!BoringSSLPath(result)) - return false; - - *result = result->Append(FILE_PATH_LITERAL("crypto")); - *result = result->Append(FILE_PATH_LITERAL("cipher")); - *result = result->Append(FILE_PATH_LITERAL("test")); - return true; -} - } // anonymous namespace -struct AEADTest { - const base::CommandLine::CharType *name; - const base::FilePath::CharType *test_vector_filename; -}; +// Runs all the tests specified in BoringSSL's all_tests.json file to ensure +// that BoringSSL, as built with Chromium's settings, is functional. +TEST(BoringSSL, UnitTests) { + base::FilePath boringssl_path; + ASSERT_TRUE(BoringSSLPath(&boringssl_path)); -static const AEADTest kAEADTests[] = { - {FILE_PATH_LITERAL("aes-128-gcm"), - FILE_PATH_LITERAL("aes_128_gcm_tests.txt")}, - {FILE_PATH_LITERAL("aes-128-key-wrap"), - FILE_PATH_LITERAL("aes_128_key_wrap_tests.txt")}, - {FILE_PATH_LITERAL("aes-256-gcm"), - FILE_PATH_LITERAL("aes_256_gcm_tests.txt")}, - {FILE_PATH_LITERAL("aes-256-key-wrap"), - FILE_PATH_LITERAL("aes_256_key_wrap_tests.txt")}, - {FILE_PATH_LITERAL("chacha20-poly1305"), - FILE_PATH_LITERAL("chacha20_poly1305_tests.txt")}, - {FILE_PATH_LITERAL("rc4-md5-tls"), - FILE_PATH_LITERAL("rc4_md5_tls_tests.txt")}, - {FILE_PATH_LITERAL("rc4-sha1-tls"), - FILE_PATH_LITERAL("rc4_sha1_tls_tests.txt")}, - {FILE_PATH_LITERAL("aes-128-cbc-sha1-tls"), - FILE_PATH_LITERAL("aes_128_cbc_sha1_tls_tests.txt")}, - {FILE_PATH_LITERAL("aes-128-cbc-sha1-tls-implicit-iv"), - FILE_PATH_LITERAL("aes_128_cbc_sha1_tls_implicit_iv_tests.txt")}, - {FILE_PATH_LITERAL("aes-128-cbc-sha256-tls"), - FILE_PATH_LITERAL("aes_128_cbc_sha256_tls_tests.txt")}, - {FILE_PATH_LITERAL("aes-256-cbc-sha1-tls"), - FILE_PATH_LITERAL("aes_256_cbc_sha1_tls_tests.txt")}, - {FILE_PATH_LITERAL("aes-256-cbc-sha1-tls-implicit-iv"), - FILE_PATH_LITERAL("aes_256_cbc_sha1_tls_implicit_iv_tests.txt")}, - {FILE_PATH_LITERAL("aes-256-cbc-sha256-tls"), - FILE_PATH_LITERAL("aes_256_cbc_sha256_tls_tests.txt")}, - {FILE_PATH_LITERAL("aes-256-cbc-sha384-tls"), - FILE_PATH_LITERAL("aes_256_cbc_sha384_tls_tests.txt")}, - {FILE_PATH_LITERAL("des-ede3-cbc-sha1-tls"), - FILE_PATH_LITERAL("des_ede3_cbc_sha1_tls_tests.txt")}, - {FILE_PATH_LITERAL("des-ede3-cbc-sha1-tls-implicit-iv"), - FILE_PATH_LITERAL("des_ede3_cbc_sha1_tls_implicit_iv_tests.txt")}, - {FILE_PATH_LITERAL("rc4-md5-ssl3"), - FILE_PATH_LITERAL("rc4_md5_ssl3_tests.txt")}, - {FILE_PATH_LITERAL("rc4-sha1-ssl3"), - FILE_PATH_LITERAL("rc4_sha1_ssl3_tests.txt")}, - {FILE_PATH_LITERAL("aes-128-cbc-sha1-ssl3"), - FILE_PATH_LITERAL("aes_128_cbc_sha1_ssl3_tests.txt")}, - {FILE_PATH_LITERAL("aes-256-cbc-sha1-ssl3"), - FILE_PATH_LITERAL("aes_256_cbc_sha1_ssl3_tests.txt")}, - {FILE_PATH_LITERAL("des-ede3-cbc-sha1-ssl3"), - FILE_PATH_LITERAL("des_ede3_cbc_sha1_ssl3_tests.txt")}, - {FILE_PATH_LITERAL("aes-128-ctr-hmac-sha256"), - FILE_PATH_LITERAL("aes_128_ctr_hmac_sha256.txt")}, - {FILE_PATH_LITERAL("aes-256-ctr-hmac-sha256"), - FILE_PATH_LITERAL("aes_256_ctr_hmac_sha256.txt")}, -}; + std::string data; + ASSERT_TRUE( + base::ReadFileToString(boringssl_path.Append(FILE_PATH_LITERAL("util")) + .Append(FILE_PATH_LITERAL("all_tests.json")), + &data)); -TEST(BoringSSL, AEADs) { - base::FilePath test_vector_dir; - ASSERT_TRUE(CryptoCipherTestPath(&test_vector_dir)); + std::unique_ptr<base::Value> value = base::JSONReader::Read(data); + ASSERT_TRUE(value); - for (size_t i = 0; i < arraysize(kAEADTests); i++) { - const AEADTest& test = kAEADTests[i]; - SCOPED_TRACE(test.name); + base::ListValue* tests; + ASSERT_TRUE(value->GetAsList(&tests)); - base::FilePath test_vector_file = - test_vector_dir.Append(test.test_vector_filename); + for (size_t i = 0; i < tests->GetSize(); i++) { + SCOPED_TRACE(i); + base::ListValue* test; + ASSERT_TRUE(tests->GetList(i, &test)); + ASSERT_FALSE(test->empty()); + + std::string name; + ASSERT_TRUE(test->GetString(0, &name)); + + // Skip libdecrepit tests. Chromium does not build libdecrepit. + if (base::StartsWith(name, "decrepit/", base::CompareCase::SENSITIVE)) + continue; + + name = name.substr(name.find_last_of('/') + 1); + SCOPED_TRACE(name); std::vector<base::CommandLine::StringType> args; - args.push_back(test.name); - args.push_back(test_vector_file.value()); + for (size_t j = 1; j < test->GetSize(); j++) { + base::CommandLine::StringType arg; + ASSERT_TRUE(test->GetString(j, &arg)); - TestProcess("aead_test", args); + // If the argument contains a /, assume it is a file path. + if (arg.find('/') != base::CommandLine::StringType::npos) { + arg = boringssl_path.Append(arg).value(); + } + + args.push_back(arg); + } + + TestProcess(name, args); } } - -TEST(BoringSSL, AES) { - TestSimple("aes_test"); -} - -TEST(BoringSSL, Base64) { - TestSimple("base64_test"); -} - -TEST(BoringSSL, BIO) { - TestSimple("bio_test"); -} - -TEST(BoringSSL, BN) { - TestSimple("bn_test"); -} - -TEST(BoringSSL, ByteString) { - TestSimple("bytestring_test"); -} - -TEST(BoringSSL, ChaCha) { - TestSimple("chacha_test"); -} - -TEST(BoringSSL, Cipher) { - base::FilePath data_file; - ASSERT_TRUE(CryptoCipherTestPath(&data_file)); - data_file = data_file.Append(FILE_PATH_LITERAL("cipher_test.txt")); - - std::vector<base::CommandLine::StringType> args; - args.push_back(data_file.value()); - - TestProcess("cipher_test", args); -} - -TEST(BoringSSL, CMAC) { - TestSimple("cmac_test"); -} - -TEST(BoringSSL, ConstantTime) { - TestSimple("constant_time_test"); -} - -TEST(BoringSSL, DH) { - TestSimple("dh_test"); -} - -TEST(BoringSSL, Digest) { - TestSimple("digest_test"); -} - -TEST(BoringSSL, DSA) { - TestSimple("dsa_test"); -} - -TEST(BoringSSL, EC) { - TestSimple("ec_test"); -} - -TEST(BoringSSL, ECDSA) { - TestSimple("ecdsa_test"); -} - -TEST(BoringSSL, ED25519) { - base::FilePath data_file; - ASSERT_TRUE(BoringSSLPath(&data_file)); - data_file = data_file.Append(FILE_PATH_LITERAL("crypto")); - data_file = data_file.Append(FILE_PATH_LITERAL("curve25519")); - data_file = data_file.Append(FILE_PATH_LITERAL("ed25519_tests.txt")); - - std::vector<base::CommandLine::StringType> args; - args.push_back(data_file.value()); - - TestProcess("ed25519_test", args); -} - -TEST(BoringSSL, ERR) { - TestSimple("err_test"); -} - -TEST(BoringSSL, EVP) { - base::FilePath data_file; - ASSERT_TRUE(BoringSSLPath(&data_file)); - data_file = data_file.Append(FILE_PATH_LITERAL("crypto")); - data_file = data_file.Append(FILE_PATH_LITERAL("evp")); - data_file = data_file.Append(FILE_PATH_LITERAL("evp_tests.txt")); - - std::vector<base::CommandLine::StringType> args; - args.push_back(data_file.value()); - - TestProcess("evp_test", args); -} - -TEST(BoringSSL, EVPExtra) { - TestSimple("evp_extra_test"); -} - -TEST(BoringSSL, ExampleMul) { - TestSimple("example_mul"); -} - -TEST(BoringSSL, GCM) { - TestSimple("gcm_test"); -} - -TEST(BoringSSL, HKDF) { - TestSimple("hkdf_test"); -} - -TEST(BoringSSL, HMAC) { - base::FilePath data_file; - ASSERT_TRUE(BoringSSLPath(&data_file)); - data_file = data_file.Append(FILE_PATH_LITERAL("crypto")); - data_file = data_file.Append(FILE_PATH_LITERAL("hmac")); - data_file = data_file.Append(FILE_PATH_LITERAL("hmac_tests.txt")); - - std::vector<base::CommandLine::StringType> args; - args.push_back(data_file.value()); - - TestProcess("hmac_test", args); -} - -TEST(BoringSSL, LH) { - TestSimple("lhash_test"); -} - -TEST(BoringSSL, NewHope) { - TestSimple("newhope_test"); -} - -TEST(BoringSSL, NewHopeVectors) { - base::FilePath data_file; - ASSERT_TRUE(BoringSSLPath(&data_file)); - data_file = data_file.Append(FILE_PATH_LITERAL("crypto")); - data_file = data_file.Append(FILE_PATH_LITERAL("newhope")); - data_file = data_file.Append(FILE_PATH_LITERAL("newhope_test.txt")); - - std::vector<base::CommandLine::StringType> args; - args.push_back(data_file.value()); - - TestProcess("newhope_vectors_test", args); -} - -TEST(BoringSSL, PBKDF) { - TestSimple("pbkdf_test"); -} - -TEST(BoringSSL, Poly1305) { - base::FilePath data_file; - ASSERT_TRUE(BoringSSLPath(&data_file)); - data_file = data_file.Append(FILE_PATH_LITERAL("crypto")); - data_file = data_file.Append(FILE_PATH_LITERAL("poly1305")); - data_file = data_file.Append(FILE_PATH_LITERAL("poly1305_test.txt")); - - std::vector<base::CommandLine::StringType> args; - args.push_back(data_file.value()); - - TestProcess("poly1305_test", args); -} - -TEST(BoringSSL, PKCS7) { - TestSimple("pkcs7_test"); -} - -TEST(BoringSSL, PKCS8) { - TestSimple("pkcs8_test"); -} - -TEST(BoringSSL, PKCS12) { - TestSimple("pkcs12_test"); -} - -TEST(BoringSSL, PQueue) { - TestSimple("pqueue_test"); -} - -TEST(BoringSSL, RefcountTest) { - TestSimple("refcount_test"); -} - -TEST(BoringSSL, RSA) { - TestSimple("rsa_test"); -} - -TEST(BoringSSL, SSL) { - TestSimple("ssl_test"); -} - -TEST(BoringSSL, TabTest) { - TestSimple("tab_test"); -} - -TEST(BoringSSL, Thread) { - TestSimple("thread_test"); -} - -TEST(BoringSSL, V3NameTest) { - TestSimple("v3name_test"); -} - -TEST(BoringSSL, X25519) { - TestSimple("x25519_test"); -} - -TEST(BoringSSL, X509) { - TestSimple("x509_test"); -}
diff --git a/third_party/byte_buddy/BUILD.gn b/third_party/byte_buddy/BUILD.gn new file mode 100644 index 0000000..9b0b0ed --- /dev/null +++ b/third_party/byte_buddy/BUILD.gn
@@ -0,0 +1,10 @@ +# Copyright 2016 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/android/rules.gni") + +java_prebuilt("byte_buddy_java") { + testonly = true + jar_path = "lib/byte-buddy-1.4.17.jar" +}
diff --git a/third_party/byte_buddy/LICENSE b/third_party/byte_buddy/LICENSE new file mode 100644 index 0000000..25b736e --- /dev/null +++ b/third_party/byte_buddy/LICENSE
@@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file
diff --git a/third_party/byte_buddy/OWNERS b/third_party/byte_buddy/OWNERS new file mode 100644 index 0000000..7fcd92b --- /dev/null +++ b/third_party/byte_buddy/OWNERS
@@ -0,0 +1,3 @@ +jbudorick@chromium.org +mikecase@chromium.org +yolandyan@chromium.org \ No newline at end of file
diff --git a/third_party/byte_buddy/README.chromium b/third_party/byte_buddy/README.chromium new file mode 100644 index 0000000..052e6df76 --- /dev/null +++ b/third_party/byte_buddy/README.chromium
@@ -0,0 +1,10 @@ +Name: Byte Buddy +URL: http://bytebuddy.net/ +Version: 1.4.17 +License: Apache 2.0 +License File: NOT_SHIPPED +Security Critical: no +Description: +Byte Buddy is a code generation library for creating Java classes at runtime. + +Local Modifications: None \ No newline at end of file
diff --git a/third_party/byte_buddy/lib/byte-buddy-1.4.17.jar.sha1 b/third_party/byte_buddy/lib/byte-buddy-1.4.17.jar.sha1 new file mode 100644 index 0000000..40b602c --- /dev/null +++ b/third_party/byte_buddy/lib/byte-buddy-1.4.17.jar.sha1
@@ -0,0 +1 @@ +466b516b8a98e2d6dcf340362029b9f02800b6b6 \ No newline at end of file
diff --git a/third_party/cld/BUILD.gn b/third_party/cld/BUILD.gn index dcfaf8b..19dd230e 100644 --- a/third_party/cld/BUILD.gn +++ b/third_party/cld/BUILD.gn
@@ -5,7 +5,7 @@ import("//build/buildflag_header.gni") # Specifies which language identification model to use: CLD2 or CLD3. -cld_version = 2 +cld_version = 3 buildflag_header("cld_version") { header = "cld_version.h" @@ -19,8 +19,7 @@ if (cld_version == 2) { public_deps += [ "//third_party/cld_2" ] } else if (cld_version == 3) { - # TODO(abakalov): Rename to //third_party/cld_3/src/src:cld_3 - public_deps += [ "//third_party/cld_3/src/src:nnet_language_identifier" ] + public_deps += [ "//third_party/cld_3/src/src:cld_3" ] } else { assert(false, "CLD version should be 2 or 3") }
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium index faa4596..6bb8faa 100644 --- a/third_party/crashpad/README.chromium +++ b/third_party/crashpad/README.chromium
@@ -2,7 +2,7 @@ Short Name: crashpad URL: https://crashpad.chromium.org/ Version: unknown -Revision: 495a64fcdb7c979fe0f46eeaa1017087589d67cb +Revision: 9807cba2f45b4a8f326e9bf20359988128b3b40a License: Apache 2.0 License File: crashpad/LICENSE Security Critical: yes
diff --git a/third_party/crashpad/crashpad/AUTHORS b/third_party/crashpad/crashpad/AUTHORS index dd7ff26..b1e4ddf9 100644 --- a/third_party/crashpad/crashpad/AUTHORS +++ b/third_party/crashpad/crashpad/AUTHORS
@@ -7,3 +7,4 @@ # The email address is not required for organizations. Google Inc. +Opera Software ASA
diff --git a/third_party/crashpad/crashpad/DEPS b/third_party/crashpad/crashpad/DEPS index e5acdbb..0af9d520 100644 --- a/third_party/crashpad/crashpad/DEPS +++ b/third_party/crashpad/crashpad/DEPS
@@ -19,16 +19,16 @@ deps = { 'crashpad/third_party/gtest/gtest': Var('chromium_git') + '/external/github.com/google/googletest@' + - '786564fa4a3c8e0f908acca32cce481de5481b9f', + 'ec44c6c1675c25b9827aacd08c02433cccde7780', 'crashpad/third_party/gyp/gyp': Var('chromium_git') + '/external/gyp@' + - '01528c7244837168a1c80f06ff60fa5a9793c824', + '93cc6e2c23e4d5ebd179f388e67aa907d0dfd43d', 'crashpad/third_party/mini_chromium/mini_chromium': Var('chromium_git') + '/chromium/mini_chromium@' + - '964ee49aa24e8bfb4823cd9034a3b32ec3cb09e9', + '87f575d65c4700accac3b546ede66116c438ced1', 'buildtools': Var('chromium_git') + '/chromium/buildtools.git@' + - 'c2f259809d5ede3275df5ea0842f0431990c4f98', + 'f8fc76ea5ce4a60cda2fa5d7df3d4a62935b3113', } hooks = [
diff --git a/third_party/crashpad/crashpad/client/prune_crash_reports.cc b/third_party/crashpad/crashpad/client/prune_crash_reports.cc index 3487e54f9..3aaaeee 100644 --- a/third_party/crashpad/crashpad/client/prune_crash_reports.cc +++ b/third_party/crashpad/crashpad/client/prune_crash_reports.cc
@@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "client/prune_crash_reports.h" + #include <sys/stat.h> #include <algorithm> @@ -20,7 +22,6 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "build/build_config.h" -#include "client/prune_crash_reports.h" namespace crashpad {
diff --git a/third_party/crashpad/crashpad/compat/mac/AvailabilityMacros.h b/third_party/crashpad/crashpad/compat/mac/AvailabilityMacros.h index decaeb51..4037eca6 100644 --- a/third_party/crashpad/crashpad/compat/mac/AvailabilityMacros.h +++ b/third_party/crashpad/crashpad/compat/mac/AvailabilityMacros.h
@@ -47,4 +47,10 @@ #define MAC_OS_X_VERSION_10_11 101100 #endif +// 10.12 SDK + +#ifndef MAC_OS_X_VERSION_10_12 +#define MAC_OS_X_VERSION_10_12 101200 +#endif + #endif // CRASHPAD_COMPAT_MAC_AVAILABILITYMACROS_H_
diff --git a/third_party/crashpad/crashpad/compat/mac/kern/exc_resource.h b/third_party/crashpad/crashpad/compat/mac/kern/exc_resource.h index 30e9b85..ca8943d 100644 --- a/third_party/crashpad/crashpad/compat/mac/kern/exc_resource.h +++ b/third_party/crashpad/crashpad/compat/mac/kern/exc_resource.h
@@ -59,4 +59,18 @@ #define FLAVOR_CPU_MONITOR_FATAL 2 #endif +// 10.12 SDK + +#ifndef RESOURCE_TYPE_IO +#define RESOURCE_TYPE_IO 4 +#endif + +#ifndef FLAVOR_IO_PHYSICAL_WRITES +#define FLAVOR_IO_PHYSICAL_WRITES 1 +#endif + +#ifndef FLAVOR_IO_LOGICAL_WRITES +#define FLAVOR_IO_LOGICAL_WRITES 2 +#endif + #endif // CRASHPAD_COMPAT_MAC_KERN_EXC_RESOURCE_H_
diff --git a/third_party/crashpad/crashpad/minidump/minidump_crashpad_info_writer_test.cc b/third_party/crashpad/crashpad/minidump/minidump_crashpad_info_writer_test.cc index 1214429..85eec274 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_crashpad_info_writer_test.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_crashpad_info_writer_test.cc
@@ -12,8 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include <dbghelp.h> +#include "minidump/minidump_crashpad_info_writer.h" + #include <windows.h> +#include <dbghelp.h> #include <map> #include <string> @@ -21,7 +23,6 @@ #include "base/memory/ptr_util.h" #include "gtest/gtest.h" -#include "minidump/minidump_crashpad_info_writer.h" #include "minidump/minidump_extensions.h" #include "minidump/minidump_file_writer.h" #include "minidump/minidump_module_crashpad_info_writer.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_exception_writer_test.cc b/third_party/crashpad/crashpad/minidump/minidump_exception_writer_test.cc index 854f8a4..8635190 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_exception_writer_test.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_exception_writer_test.cc
@@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "minidump/minidump_exception_writer.h" + #include <string> #include <utility> @@ -19,7 +21,6 @@ #include "gtest/gtest.h" #include "minidump/minidump_context.h" #include "minidump/minidump_context_writer.h" -#include "minidump/minidump_exception_writer.h" #include "minidump/minidump_extensions.h" #include "minidump/minidump_file_writer.h" #include "minidump/minidump_thread_id_map.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_file_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_file_writer.cc index e544916..6a91ca6 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_file_writer.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_file_writer.cc
@@ -12,13 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "minidump/minidump_file_writer.h" + #include <utility> #include "base/logging.h" #include "base/memory/ptr_util.h" #include "minidump/minidump_crashpad_info_writer.h" #include "minidump/minidump_exception_writer.h" -#include "minidump/minidump_file_writer.h" #include "minidump/minidump_handle_writer.h" #include "minidump/minidump_memory_info_writer.h" #include "minidump/minidump_memory_writer.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_file_writer_test.cc b/third_party/crashpad/crashpad/minidump/minidump_file_writer_test.cc index b007cec..f3432fb 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_file_writer_test.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_file_writer_test.cc
@@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "minidump/minidump_file_writer.h" + #include <stdint.h> #include <string.h> @@ -22,7 +24,6 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "gtest/gtest.h" -#include "minidump/minidump_file_writer.h" #include "minidump/minidump_stream_writer.h" #include "minidump/minidump_writable.h" #include "minidump/test/minidump_file_writer_test_util.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_handle_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_handle_writer.cc index 73eeb0c..c5d4659f 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_handle_writer.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_handle_writer.cc
@@ -29,7 +29,7 @@ } MinidumpHandleDataWriter::~MinidumpHandleDataWriter() { - STLDeleteContainerPairSecondPointers(strings_.begin(), strings_.end()); + base::STLDeleteContainerPairSecondPointers(strings_.begin(), strings_.end()); } void MinidumpHandleDataWriter::InitializeFromSnapshot(
diff --git a/third_party/crashpad/crashpad/minidump/minidump_handle_writer_test.cc b/third_party/crashpad/crashpad/minidump/minidump_handle_writer_test.cc index 31b5ec87..982da71 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_handle_writer_test.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_handle_writer_test.cc
@@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "minidump/minidump_handle_writer.h" + #include <string> #include <utility> @@ -19,7 +21,6 @@ #include "base/strings/utf_string_conversions.h" #include "gtest/gtest.h" #include "minidump/minidump_file_writer.h" -#include "minidump/minidump_handle_writer.h" #include "minidump/test/minidump_file_writer_test_util.h" #include "minidump/test/minidump_string_writer_test_util.h" #include "minidump/test/minidump_writable_test_util.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_memory_info_writer_test.cc b/third_party/crashpad/crashpad/minidump/minidump_memory_info_writer_test.cc index 6d943d2..ef6535b7 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_memory_info_writer_test.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_memory_info_writer_test.cc
@@ -12,13 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "minidump/minidump_memory_info_writer.h" + #include <string> #include <utility> #include "base/memory/ptr_util.h" #include "gtest/gtest.h" #include "minidump/minidump_file_writer.h" -#include "minidump/minidump_memory_info_writer.h" #include "minidump/test/minidump_file_writer_test_util.h" #include "minidump/test/minidump_writable_test_util.h" #include "snapshot/test/test_memory_map_region_snapshot.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_memory_writer_test.cc b/third_party/crashpad/crashpad/minidump/minidump_memory_writer_test.cc index 22e3ea9..d9e87ae 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_memory_writer_test.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_memory_writer_test.cc
@@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "minidump/minidump_memory_writer.h" + #include <utility> #include "base/format_macros.h" @@ -21,7 +23,6 @@ #include "gtest/gtest.h" #include "minidump/minidump_extensions.h" #include "minidump/minidump_file_writer.h" -#include "minidump/minidump_memory_writer.h" #include "minidump/minidump_stream_writer.h" #include "minidump/test/minidump_file_writer_test_util.h" #include "minidump/test/minidump_memory_writer_test_util.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_misc_info_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_misc_info_writer.cc index 4d3b143..1d25b11 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_misc_info_writer.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_misc_info_writer.cc
@@ -149,14 +149,14 @@ const SystemSnapshot* system_snapshot = process_snapshot->System(); - uint64_t current_mhz; - uint64_t max_mhz; - system_snapshot->CPUFrequency(¤t_mhz, &max_mhz); + uint64_t current_hz; + uint64_t max_hz; + system_snapshot->CPUFrequency(¤t_hz, &max_hz); const uint32_t kHzPerMHz = static_cast<const uint32_t>(1E6); SetProcessorPowerInfo( - InRangeCast<uint32_t>(current_mhz / kHzPerMHz, + InRangeCast<uint32_t>(current_hz / kHzPerMHz, std::numeric_limits<uint32_t>::max()), - InRangeCast<uint32_t>(max_mhz / kHzPerMHz, + InRangeCast<uint32_t>(max_hz / kHzPerMHz, std::numeric_limits<uint32_t>::max()), 0, 0,
diff --git a/third_party/crashpad/crashpad/minidump/minidump_misc_info_writer_test.cc b/third_party/crashpad/crashpad/minidump/minidump_misc_info_writer_test.cc index 490170e5..a184e2ad 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_misc_info_writer_test.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_misc_info_writer_test.cc
@@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "minidump/minidump_misc_info_writer.h" + #include <string.h> #include <memory> @@ -25,7 +27,6 @@ #include "base/strings/utf_string_conversions.h" #include "gtest/gtest.h" #include "minidump/minidump_file_writer.h" -#include "minidump/minidump_misc_info_writer.h" #include "minidump/test/minidump_file_writer_test_util.h" #include "minidump/test/minidump_writable_test_util.h" #include "snapshot/test/test_process_snapshot.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_module_crashpad_info_writer_test.cc b/third_party/crashpad/crashpad/minidump/minidump_module_crashpad_info_writer_test.cc index 99386207..34761a7 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_module_crashpad_info_writer_test.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_module_crashpad_info_writer_test.cc
@@ -12,15 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include <dbghelp.h> +#include "minidump/minidump_module_crashpad_info_writer.h" + #include <windows.h> +#include <dbghelp.h> #include <utility> #include "base/memory/ptr_util.h" #include "gtest/gtest.h" #include "minidump/minidump_extensions.h" -#include "minidump/minidump_module_crashpad_info_writer.h" #include "minidump/minidump_simple_string_dictionary_writer.h" #include "minidump/test/minidump_file_writer_test_util.h" #include "minidump/test/minidump_string_writer_test_util.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_module_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_module_writer.cc index 353315d..f74a2a70 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_module_writer.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_module_writer.cc
@@ -12,13 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "minidump/minidump_module_writer.h" + #include <limits> #include <utility> #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/numerics/safe_conversions.h" -#include "minidump/minidump_module_writer.h" #include "minidump/minidump_string_writer.h" #include "minidump/minidump_writer_util.h" #include "snapshot/module_snapshot.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_module_writer_test.cc b/third_party/crashpad/crashpad/minidump/minidump_module_writer_test.cc index 7932f9e..7c9dcda 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_module_writer_test.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_module_writer_test.cc
@@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "minidump/minidump_module_writer.h" + #include <string.h> #include <utility> @@ -23,7 +25,6 @@ #include "gtest/gtest.h" #include "minidump/minidump_extensions.h" #include "minidump/minidump_file_writer.h" -#include "minidump/minidump_module_writer.h" #include "minidump/test/minidump_file_writer_test_util.h" #include "minidump/test/minidump_string_writer_test_util.h" #include "minidump/test/minidump_writable_test_util.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_rva_list_writer_test.cc b/third_party/crashpad/crashpad/minidump/minidump_rva_list_writer_test.cc index 1d51bb9..4d0d051 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_rva_list_writer_test.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_rva_list_writer_test.cc
@@ -12,13 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "minidump/minidump_rva_list_writer.h" + #include <utility> #include "base/format_macros.h" #include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" #include "gtest/gtest.h" -#include "minidump/minidump_rva_list_writer.h" #include "minidump/test/minidump_rva_list_test_util.h" #include "minidump/test/minidump_writable_test_util.h" #include "util/file/string_file.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_simple_string_dictionary_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_simple_string_dictionary_writer.cc index e188d7ef..7a40cd4ba 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_simple_string_dictionary_writer.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_simple_string_dictionary_writer.cc
@@ -12,12 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "minidump/minidump_simple_string_dictionary_writer.h" + #include <utility> #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/stl_util.h" -#include "minidump/minidump_simple_string_dictionary_writer.h" #include "util/file/file_writer.h" #include "util/numeric/safe_assignment.h" @@ -99,7 +100,7 @@ } MinidumpSimpleStringDictionaryWriter::~MinidumpSimpleStringDictionaryWriter() { - STLDeleteContainerPairSecondPointers(entries_.begin(), entries_.end()); + base::STLDeleteContainerPairSecondPointers(entries_.begin(), entries_.end()); } void MinidumpSimpleStringDictionaryWriter::InitializeFromMap(
diff --git a/third_party/crashpad/crashpad/minidump/minidump_simple_string_dictionary_writer_test.cc b/third_party/crashpad/crashpad/minidump/minidump_simple_string_dictionary_writer_test.cc index 1bf3c01..b4c8144 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_simple_string_dictionary_writer_test.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_simple_string_dictionary_writer_test.cc
@@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "minidump/minidump_simple_string_dictionary_writer.h" + #include <stdint.h> #include <map> @@ -21,7 +23,6 @@ #include "base/memory/ptr_util.h" #include "gtest/gtest.h" #include "minidump/minidump_extensions.h" -#include "minidump/minidump_simple_string_dictionary_writer.h" #include "minidump/test/minidump_string_writer_test_util.h" #include "minidump/test/minidump_writable_test_util.h" #include "util/file/string_file.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_system_info_writer_test.cc b/third_party/crashpad/crashpad/minidump/minidump_system_info_writer_test.cc index 1f4d679..9976250 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_system_info_writer_test.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_system_info_writer_test.cc
@@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "minidump/minidump_system_info_writer.h" + #include <string.h> #include <algorithm> @@ -22,7 +24,6 @@ #include "base/memory/ptr_util.h" #include "gtest/gtest.h" #include "minidump/minidump_file_writer.h" -#include "minidump/minidump_system_info_writer.h" #include "minidump/test/minidump_file_writer_test_util.h" #include "minidump/test/minidump_string_writer_test_util.h" #include "minidump/test/minidump_writable_test_util.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_thread_writer.cc b/third_party/crashpad/crashpad/minidump/minidump_thread_writer.cc index 65cbf18..0dd1dba 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_thread_writer.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_thread_writer.cc
@@ -12,13 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "minidump/minidump_thread_writer.h" + #include <utility> #include "base/logging.h" #include "base/memory/ptr_util.h" #include "minidump/minidump_context_writer.h" #include "minidump/minidump_memory_writer.h" -#include "minidump/minidump_thread_writer.h" #include "snapshot/memory_snapshot.h" #include "snapshot/thread_snapshot.h" #include "util/file/file_writer.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_thread_writer_test.cc b/third_party/crashpad/crashpad/minidump/minidump_thread_writer_test.cc index ea498e9..1384efe3 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_thread_writer_test.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_thread_writer_test.cc
@@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "minidump/minidump_thread_writer.h" + #include <string> #include <utility> @@ -24,7 +26,6 @@ #include "minidump/minidump_file_writer.h" #include "minidump/minidump_memory_writer.h" #include "minidump/minidump_thread_id_map.h" -#include "minidump/minidump_thread_writer.h" #include "minidump/test/minidump_context_test_util.h" #include "minidump/test/minidump_file_writer_test_util.h" #include "minidump/test/minidump_memory_writer_test_util.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_unloaded_module_writer_test.cc b/third_party/crashpad/crashpad/minidump/minidump_unloaded_module_writer_test.cc index 1d2d3538..dba4691 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_unloaded_module_writer_test.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_unloaded_module_writer_test.cc
@@ -18,7 +18,6 @@ #include "base/strings/utf_string_conversions.h" #include "gtest/gtest.h" #include "minidump/minidump_file_writer.h" -#include "minidump/minidump_unloaded_module_writer.h" #include "minidump/test/minidump_file_writer_test_util.h" #include "minidump/test/minidump_string_writer_test_util.h" #include "minidump/test/minidump_writable_test_util.h"
diff --git a/third_party/crashpad/crashpad/minidump/minidump_user_stream_writer_test.cc b/third_party/crashpad/crashpad/minidump/minidump_user_stream_writer_test.cc index bb77dcc..97d41eecf 100644 --- a/third_party/crashpad/crashpad/minidump/minidump_user_stream_writer_test.cc +++ b/third_party/crashpad/crashpad/minidump/minidump_user_stream_writer_test.cc
@@ -12,13 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include "minidump/minidump_user_stream_writer.h" + #include <string> #include <utility> #include "base/memory/ptr_util.h" #include "gtest/gtest.h" #include "minidump/minidump_file_writer.h" -#include "minidump/minidump_user_stream_writer.h" #include "minidump/test/minidump_file_writer_test_util.h" #include "minidump/test/minidump_writable_test_util.h" #include "snapshot/test/test_memory_snapshot.h"
diff --git a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_annotations_reader_test.cc b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_annotations_reader_test.cc index 18b00a9..5d5908d 100644 --- a/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_annotations_reader_test.cc +++ b/third_party/crashpad/crashpad/snapshot/mac/mach_o_image_annotations_reader_test.cc
@@ -286,10 +286,14 @@ break; case kCrashDyld: - // dyld fatal errors result in the execution of an int3 instruction on - // x86 and a trap instruction on ARM, both of which raise SIGTRAP. - // 10.9.5 dyld-239.4/src/dyldStartup.s _dyld_fatal_error. - SetExpectedChildTermination(kTerminationSignal, SIGTRAP); + // Prior to 10.12, dyld fatal errors result in the execution of an + // int3 instruction on x86 and a trap instruction on ARM, both of + // which raise SIGTRAP. 10.9.5 dyld-239.4/src/dyldStartup.s + // _dyld_fatal_error. This changed in 10.12 to use + // abort_with_payload(), which appears as SIGABRT to a waiting parent. + SetExpectedChildTermination( + kTerminationSignal, + MacOSXMinorVersion() < 12 ? SIGTRAP : SIGABRT); break; default:
diff --git a/third_party/crashpad/crashpad/snapshot/mac/process_reader.cc b/third_party/crashpad/crashpad/snapshot/mac/process_reader.cc index 3b11eb1d..46b83c1 100644 --- a/third_party/crashpad/crashpad/snapshot/mac/process_reader.cc +++ b/third_party/crashpad/crashpad/snapshot/mac/process_reader.cc
@@ -444,6 +444,9 @@ if (all_image_infos.version >= 2 && all_image_infos.dyldImageLoadAddress && image_info.imageLoadAddress == all_image_infos.dyldImageLoadAddress) { found_dyld = true; + LOG(WARNING) << base::StringPrintf( + "found dylinker (%s) in dyld_all_image_infos::infoArray", + module.name.c_str()); LOG_IF(WARNING, file_type != MH_DYLINKER) << base::StringPrintf("dylinker (%s) has unexpected Mach-O type %d",
diff --git a/third_party/crashpad/crashpad/snapshot/mac/process_reader_test.cc b/third_party/crashpad/crashpad/snapshot/mac/process_reader_test.cc index 2cbf8ea..ed717b6 100644 --- a/third_party/crashpad/crashpad/snapshot/mac/process_reader_test.cc +++ b/third_party/crashpad/crashpad/snapshot/mac/process_reader_test.cc
@@ -56,6 +56,8 @@ namespace test { namespace { +const char kDyldPath[] = "/usr/lib/dyld"; + TEST(ProcessReader, SelfBasic) { ProcessReader process_reader; ASSERT_TRUE(process_reader.Initialize(mach_task_self())); @@ -690,7 +692,7 @@ EXPECT_EQ(ExpectCLKernels(), found_cl_kernels); size_t index = modules.size() - 1; - EXPECT_EQ("/usr/lib/dyld", modules[index].name); + EXPECT_EQ(kDyldPath, modules[index].name); // dyld didn’t load itself either, so it couldn’t record its timestamp, and it // is also reported as 0. @@ -800,7 +802,7 @@ dyld_image_address = reinterpret_cast<mach_vm_address_t>(_dyld_get_image_header(index)); } else { - dyld_image_name = "/usr/lib/dyld"; + dyld_image_name = kDyldPath; dyld_image_address = reinterpret_cast<mach_vm_address_t>( dyld_image_infos->dyldImageLoadAddress); }
diff --git a/third_party/crashpad/crashpad/snapshot/mac/process_types.cc b/third_party/crashpad/crashpad/snapshot/mac/process_types.cc index a34e4d6..53d8903 100644 --- a/third_party/crashpad/crashpad/snapshot/mac/process_types.cc +++ b/third_party/crashpad/crashpad/snapshot/mac/process_types.cc
@@ -36,44 +36,39 @@ *destination = source; } +template <typename Type> +inline void Assign(Type* destination, const Type& source) { + memcpy(destination, &source, sizeof(source)); +} + template <> -inline void Assign<process_types::internal::Reserved64Only64, - process_types::internal::Reserved64Only32>( - process_types::internal::Reserved64Only64* destination, - const process_types::internal::Reserved64Only32& source) { - // Reserved64Only32 carries no data. +inline void Assign<process_types::internal::Reserved32_64Only64, + process_types::internal::Reserved32_64Only32>( + process_types::internal::Reserved32_64Only64* destination, + const process_types::internal::Reserved32_64Only32& source) { + // Reserved32_64Only32 carries no data. *destination = 0; } -using CharArray16 = char[16]; template <> -inline void Assign<CharArray16, CharArray16>(CharArray16* destination, - const CharArray16& source) { - memcpy(destination, &source, sizeof(source)); +inline void Assign<process_types::internal::Reserved64_64Only64, + process_types::internal::Reserved64_64Only32>( + process_types::internal::Reserved64_64Only64* destination, + const process_types::internal::Reserved64_64Only32& source) { + // Reserved64_64Only32 carries no data. + *destination = 0; } -using UInt64Array16 = uint64_t[16]; +using UInt32Array4 = uint32_t[4]; +using UInt64Array4 = uint64_t[4]; template <> -inline void Assign<UInt64Array16, UInt64Array16>(UInt64Array16* destination, - const UInt64Array16& source) { - memcpy(destination, &source, sizeof(source)); -} - -using UInt32Array16 = uint32_t[16]; -template <> -inline void Assign<UInt64Array16, UInt32Array16>(UInt64Array16* destination, - const UInt32Array16& source) { +inline void Assign<UInt64Array4, UInt32Array4>(UInt64Array4* destination, + const UInt32Array4& source) { for (size_t index = 0; index < arraysize(source); ++index) { (*destination)[index] = source[index]; } } -template <> -inline void Assign<uuid_t, uuid_t>(uuid_t* destination, const uuid_t& source) { - // uuid_t is a type alias for unsigned char[16]. - memcpy(destination, &source, sizeof(source)); -} - } // namespace } // namespace crashpad
diff --git a/third_party/crashpad/crashpad/snapshot/mac/process_types.h b/third_party/crashpad/crashpad/snapshot/mac/process_types.h index a1039dd..664b37b 100644 --- a/third_party/crashpad/crashpad/snapshot/mac/process_types.h +++ b/third_party/crashpad/crashpad/snapshot/mac/process_types.h
@@ -29,10 +29,12 @@ // Some structure definitions differ in 32-bit and 64-bit environments by having // additional “reserved” padding fields present only in the 64-bit environment. -// These Reserved64Only* types allow the process_types system to replicate these -// structures more precisely. -using Reserved64Only32 = char[0]; -using Reserved64Only64 = uint32_t; +// These Reserved*_64Only* types allow the process_types system to replicate +// these structures more precisely. +using Reserved32_64Only32 = char[0]; +using Reserved32_64Only64 = uint32_t; +using Reserved64_64Only32 = char[0]; +using Reserved64_64Only64 = uint64_t; } // namespace internal } // namespace process_types @@ -61,7 +63,8 @@ using Pointer = internal::TraitsGeneric::Pointer; \ using IntPtr = internal::TraitsGeneric::IntPtr; \ using UIntPtr = internal::TraitsGeneric::UIntPtr; \ - using Reserved64Only = internal::TraitsGeneric::Reserved64Only; \ + using Reserved32_64Only = internal::TraitsGeneric::Reserved32_64Only; \ + using Reserved64_64Only = internal::TraitsGeneric::Reserved64_64Only; \ \ /* Initializes an object with data read from |process_reader| at \ * |address|, properly genericized. */ \ @@ -150,7 +153,8 @@ using Pointer = typename Traits::Pointer; \ using IntPtr = typename Traits::IntPtr; \ using UIntPtr = typename Traits::UIntPtr; \ - using Reserved64Only = typename Traits::Reserved64Only; \ + using Reserved32_64Only = typename Traits::Reserved32_64Only; \ + using Reserved64_64Only = typename Traits::Reserved64_64Only; \ \ /* Read(), ReadArrayInto(), and Size() are as in the generic user-visible \ * struct above. */ \
diff --git a/third_party/crashpad/crashpad/snapshot/mac/process_types/custom.cc b/third_party/crashpad/crashpad/snapshot/mac/process_types/custom.cc index 78bc302d..60c6e50 100644 --- a/third_party/crashpad/crashpad/snapshot/mac/process_types/custom.cc +++ b/third_party/crashpad/crashpad/snapshot/mac/process_types/custom.cc
@@ -64,7 +64,7 @@ return sizeof(dyld_all_image_infos<Traits>); } if (version >= 13) { - return offsetof(dyld_all_image_infos<Traits>, reserved); + return offsetof(dyld_all_image_infos<Traits>, infoArrayChangeTimestamp); } if (version >= 12) { return offsetof(dyld_all_image_infos<Traits>, sharedCacheUUID);
diff --git a/third_party/crashpad/crashpad/snapshot/mac/process_types/dyld_images.proctype b/third_party/crashpad/crashpad/snapshot/mac/process_types/dyld_images.proctype index 99be27c..eb8410a 100644 --- a/third_party/crashpad/crashpad/snapshot/mac/process_types/dyld_images.proctype +++ b/third_party/crashpad/crashpad/snapshot/mac/process_types/dyld_images.proctype
@@ -61,7 +61,7 @@ // of the process_types structure matches the genuine 64-bit structure. This // is required because the alignment constraints on 64-bit types are more // stringent in 64-bit mode. - PROCESS_TYPE_STRUCT_MEMBER(Reserved64Only, alignment) + PROCESS_TYPE_STRUCT_MEMBER(Reserved32_64Only, alignment) // const mach_header* PROCESS_TYPE_STRUCT_MEMBER(Pointer, dyldImageLoadAddress) @@ -80,31 +80,49 @@ // Version 7 (Mac OS X 10.6) PROCESS_TYPE_STRUCT_MEMBER(UIntPtr, systemOrderFlag) - // Version 8 (Mac OS X 10.7) + // Version 8 (OS X 10.7) PROCESS_TYPE_STRUCT_MEMBER(UIntPtr, uuidArrayCount) PROCESS_TYPE_STRUCT_MEMBER(Pointer, uuidArray) // const dyld_uuid_info* - // Version 9 (Mac OS X 10.7) + // Version 9 (OS X 10.7) // dyld_all_image_infos* PROCESS_TYPE_STRUCT_MEMBER(Pointer, dyldAllImageInfosAddress) - // Version 10 (Mac OS X 10.7) + // Version 10 (OS X 10.7) PROCESS_TYPE_STRUCT_MEMBER(UIntPtr, initialImageCount) - // Version 11 (Mac OS X 10.7) + // Version 11 (OS X 10.7) PROCESS_TYPE_STRUCT_MEMBER(UIntPtr, errorKind) PROCESS_TYPE_STRUCT_MEMBER(Pointer, errorClientOfDylibPath) // const char* PROCESS_TYPE_STRUCT_MEMBER(Pointer, errorTargetDylibPath) // const char* PROCESS_TYPE_STRUCT_MEMBER(Pointer, errorSymbol) // const char* - // Version 12 (Mac OS X 10.7) + // Version 12 (OS X 10.7) PROCESS_TYPE_STRUCT_MEMBER(UIntPtr, sharedCacheSlide) - // Version 13 (Mac OS X 10.9) + // Version 13 (OS X 10.9) PROCESS_TYPE_STRUCT_MEMBER(uint8_t, sharedCacheUUID, [16]) - // Version 14 (Mac OS X 10.9) - PROCESS_TYPE_STRUCT_MEMBER(UIntPtr, reserved, [16]) + // Version 15 (macOS 10.12) + // This space is also allocated in version 14 (OS X 10.9) as part of the + // “reserved” member. + PROCESS_TYPE_STRUCT_MEMBER(UIntPtr, sharedCacheBaseAddress) + PROCESS_TYPE_STRUCT_MEMBER(uint64_t, infoArrayChangeTimestamp) + PROCESS_TYPE_STRUCT_MEMBER(Pointer, dyldPath) // const char* + + // These should be considered mach_port_name_t when interacting with them from + // another Mach IPC namespace (process). + PROCESS_TYPE_STRUCT_MEMBER(mach_port_t, notifyPorts, [8]) + + // Version 14 (OS X 10.9) + // As of the 10.12 SDK, this is declared as reserved[9] for 64-bit platforms + // and reserved[4] for 32-bit platforms. + PROCESS_TYPE_STRUCT_MEMBER(UIntPtr, reserved, [4]) + PROCESS_TYPE_STRUCT_MEMBER(Reserved64_64Only, reserved_4) + PROCESS_TYPE_STRUCT_MEMBER(Reserved64_64Only, reserved_5) + PROCESS_TYPE_STRUCT_MEMBER(Reserved64_64Only, reserved_6) + PROCESS_TYPE_STRUCT_MEMBER(Reserved64_64Only, reserved_7) + PROCESS_TYPE_STRUCT_MEMBER(Reserved64_64Only, reserved_8) PROCESS_TYPE_STRUCT_END(dyld_all_image_infos) #endif // ! PROCESS_TYPE_STRUCT_IMPLEMENT_INTERNAL_READ_INTO &&
diff --git a/third_party/crashpad/crashpad/snapshot/mac/process_types/loader.proctype b/third_party/crashpad/crashpad/snapshot/mac/process_types/loader.proctype index 177e6f7..43a9a7f 100644 --- a/third_party/crashpad/crashpad/snapshot/mac/process_types/loader.proctype +++ b/third_party/crashpad/crashpad/snapshot/mac/process_types/loader.proctype
@@ -36,7 +36,7 @@ PROCESS_TYPE_STRUCT_MEMBER(uint32_t, ncmds) PROCESS_TYPE_STRUCT_MEMBER(uint32_t, sizeofcmds) PROCESS_TYPE_STRUCT_MEMBER(uint32_t, flags) - PROCESS_TYPE_STRUCT_MEMBER(Reserved64Only, reserved) + PROCESS_TYPE_STRUCT_MEMBER(Reserved32_64Only, reserved) PROCESS_TYPE_STRUCT_END(mach_header) PROCESS_TYPE_STRUCT_BEGIN(load_command) @@ -136,5 +136,5 @@ PROCESS_TYPE_STRUCT_MEMBER(uint32_t, flags) PROCESS_TYPE_STRUCT_MEMBER(uint32_t, reserved1) PROCESS_TYPE_STRUCT_MEMBER(uint32_t, reserved2) - PROCESS_TYPE_STRUCT_MEMBER(Reserved64Only, reserved3) + PROCESS_TYPE_STRUCT_MEMBER(Reserved32_64Only, reserved3) PROCESS_TYPE_STRUCT_END(section)
diff --git a/third_party/crashpad/crashpad/snapshot/mac/process_types/traits.h b/third_party/crashpad/crashpad/snapshot/mac/process_types/traits.h index 0b4d273..fec234d 100644 --- a/third_party/crashpad/crashpad/snapshot/mac/process_types/traits.h +++ b/third_party/crashpad/crashpad/snapshot/mac/process_types/traits.h
@@ -22,9 +22,9 @@ // DECLARE_PROCESS_TYPE_TRAITS_CLASS before #including this file again and after // the last #include of this file. // -// |Reserved| is used for padding fields that may be zero-length, and thus +// |Reserved*| are used for padding fields that may be zero-length, and thus // __VA_ARGS__, which is intended to set the alignment of the 64-bit types, is -// not used for that type alias. +// not used for those type aliases. #define DECLARE_PROCESS_TYPE_TRAITS_CLASS(traits_name, lp_bits, ...) \ namespace crashpad { \ namespace process_types { \ @@ -35,7 +35,8 @@ using Pointer = uint##lp_bits##_t __VA_ARGS__; \ using IntPtr = int##lp_bits##_t __VA_ARGS__; \ using UIntPtr = uint##lp_bits##_t __VA_ARGS__; \ - using Reserved64Only = Reserved64Only##lp_bits; \ + using Reserved32_64Only = Reserved32_64Only##lp_bits; \ + using Reserved64_64Only = Reserved64_64Only##lp_bits; \ }; \ } \ } \
diff --git a/third_party/crashpad/crashpad/snapshot/mac/process_types_test.cc b/third_party/crashpad/crashpad/snapshot/mac/process_types_test.cc index d54ea3c..1bb8d101 100644 --- a/third_party/crashpad/crashpad/snapshot/mac/process_types_test.cc +++ b/third_party/crashpad/crashpad/snapshot/mac/process_types_test.cc
@@ -47,7 +47,9 @@ const struct dyld_all_image_infos* self_image_infos = _dyld_get_all_image_infos(); int mac_os_x_minor_version = MacOSXMinorVersion(); - if (mac_os_x_minor_version >= 9) { + if (mac_os_x_minor_version >= 12) { + EXPECT_GE(self_image_infos->version, 15u); + } else if (mac_os_x_minor_version >= 9) { EXPECT_GE(self_image_infos->version, 13u); } else if (mac_os_x_minor_version >= 7) { EXPECT_GE(self_image_infos->version, 8u); @@ -96,6 +98,24 @@ ProcessReader process_reader; ASSERT_TRUE(process_reader.Initialize(mach_task_self())); +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12 + const uint32_t kDyldAllImageInfosVersionInSDK = 15; +#elif MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9 + const uint32_t kDyldAllImageInfosVersionInSDK = 14; +#elif MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7 + const uint32_t kDyldAllImageInfosVersionInSDK = 12; +#elif MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + const uint32_t kDyldAllImageInfosVersionInSDK = 7; +#else + const uint32_t kDyldAllImageInfosVersionInSDK = 1; +#endif + + // Make sure that the size of the structure as declared in the SDK matches the + // size expected for the version of the structure that the SDK describes. + EXPECT_EQ(sizeof(dyld_all_image_infos), + process_types::dyld_all_image_infos::ExpectedSizeForVersion( + &process_reader, kDyldAllImageInfosVersionInSDK)); + process_types::dyld_all_image_infos proctype_image_infos; ASSERT_TRUE(proctype_image_infos.Read(&process_reader, dyld_info.all_image_info_addr)); @@ -194,13 +214,49 @@ proctype_image_infos.sharedCacheUUID, sizeof(self_image_infos->sharedCacheUUID))); } +#endif +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12 + if (proctype_image_infos.version >= 15) { + EXPECT_EQ(self_image_infos->infoArrayChangeTimestamp, + proctype_image_infos.infoArrayChangeTimestamp); + EXPECT_EQ(self_image_infos->sharedCacheBaseAddress, + proctype_image_infos.sharedCacheBaseAddress); + EXPECT_EQ(reinterpret_cast<uint64_t>(self_image_infos->dyldPath), + proctype_image_infos.dyldPath); + for (size_t index = 0; + index < arraysize(self_image_infos->notifyPorts); + ++index) { + EXPECT_EQ(self_image_infos->notifyPorts[index], + proctype_image_infos.notifyPorts[index]) << "index " << index; + } + + TEST_STRING( + process_reader, self_image_infos, proctype_image_infos, dyldPath); + } +#endif + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12 + // As dyld_all_image_infos has evolved over time, new fields were added to the + // reserved region. process_types::dyld_all_image_infos declares a recent + // version of the structure, but an older SDK may declare an older version + // whose |reserved| member appears at a different (smaller) offset than the + // process_types version. It’s difficult to compare the reserved fields in + // these older SDKs, so only do it where the declarations match. if (proctype_image_infos.version >= 14) { - for (size_t index = 0; index < arraysize(self_image_infos->reserved); + for (size_t index = 0; + index < arraysize(proctype_image_infos.reserved); ++index) { EXPECT_EQ(implicit_cast<uint64_t>(self_image_infos->reserved[index]), proctype_image_infos.reserved[index]) << "index " << index; } +#if defined(ARCH_CPU_64_BITS) + EXPECT_EQ(self_image_infos->reserved[4], proctype_image_infos.reserved_4); + EXPECT_EQ(self_image_infos->reserved[5], proctype_image_infos.reserved_5); + EXPECT_EQ(self_image_infos->reserved[6], proctype_image_infos.reserved_6); + EXPECT_EQ(self_image_infos->reserved[7], proctype_image_infos.reserved_7); + EXPECT_EQ(self_image_infos->reserved[8], proctype_image_infos.reserved_8); +#endif } #endif @@ -213,7 +269,8 @@ proctype_image_info_vector.size(), &proctype_image_info_vector[0])); - for (size_t index = 0; index < proctype_image_infos.infoArrayCount; + for (size_t index = 0; + index < proctype_image_infos.infoArrayCount; ++index) { const dyld_image_info* self_image_info = &self_image_infos->infoArray[index]; @@ -245,7 +302,8 @@ proctype_uuid_info_vector.size(), &proctype_uuid_info_vector[0])); - for (size_t index = 0; index < proctype_image_infos.uuidArrayCount; + for (size_t index = 0; + index < proctype_image_infos.uuidArrayCount; ++index) { const dyld_uuid_info* self_uuid_info = &self_image_infos->uuidArray[index];
diff --git a/third_party/crashpad/crashpad/snapshot/module_snapshot.h b/third_party/crashpad/crashpad/snapshot/module_snapshot.h index 0f6723ec..870eb20 100644 --- a/third_party/crashpad/crashpad/snapshot/module_snapshot.h +++ b/third_party/crashpad/crashpad/snapshot/module_snapshot.h
@@ -152,8 +152,8 @@ //! //! On Windows, this references the PDB file, which contains symbol //! information held separately from the module itself. On other platforms, - //! this is normally just be the basename of the module, because the debug - //! info file’s name is not relevant even in split-debug scenarios. + //! this is normally the basename of the module, because the debug info file’s + //! name is not relevant even in split-debug scenarios. //! //! \sa UUIDAndAge() virtual std::string DebugFileName() const = 0;
diff --git a/third_party/crashpad/crashpad/snapshot/win/end_to_end_test.py b/third_party/crashpad/crashpad/snapshot/win/end_to_end_test.py index 1fa820e..b277ab0 100755 --- a/third_party/crashpad/crashpad/snapshot/win/end_to_end_test.py +++ b/third_party/crashpad/crashpad/snapshot/win/end_to_end_test.py
@@ -199,16 +199,19 @@ out = CdbRun(cdb_path, dump_path, '.ecxr') out.Check('This dump file has an exception of interest stored in it', 'captured exception') - out.Check( - 'crashy_program!crashpad::`anonymous namespace\'::SomeCrashyFunction', - 'exception at correct location') + + # When SomeCrashyFunction is inlined, cdb doesn't demangle its namespace as + # "`anonymous namespace'" and instead gives the decorated form. + out.Check('crashy_program!crashpad::(`anonymous namespace\'|\?A0x[0-9a-f]+)::' + 'SomeCrashyFunction', + 'exception at correct location') out = CdbRun(cdb_path, start_handler_dump_path, '.ecxr') out.Check('This dump file has an exception of interest stored in it', 'captured exception (using StartHandler())') - out.Check( - 'crashy_program!crashpad::`anonymous namespace\'::SomeCrashyFunction', - 'exception at correct location (using StartHandler())') + out.Check('crashy_program!crashpad::(`anonymous namespace\'|\?A0x[0-9a-f]+)::' + 'SomeCrashyFunction', + 'exception at correct location (using StartHandler())') out = CdbRun(cdb_path, dump_path, '!peb') out.Check(r'PEB at', 'found the PEB')
diff --git a/third_party/crashpad/crashpad/test/multiprocess_posix.cc b/third_party/crashpad/crashpad/test/multiprocess_posix.cc index dcc39479..4e0e6e6 100644 --- a/third_party/crashpad/crashpad/test/multiprocess_posix.cc +++ b/third_party/crashpad/crashpad/test/multiprocess_posix.cc
@@ -98,12 +98,12 @@ if (WIFEXITED(status)) { reason = kTerminationNormal; code = WEXITSTATUS(status); - message = base::StringPrintf("Child exited with code %d, expected", code); + message = base::StringPrintf("Child exited with code %d", code); } else if (WIFSIGNALED(status)) { reason = kTerminationSignal; code = WTERMSIG(status); message = - base::StringPrintf("Child terminated by signal %d (%s)%s, expected", + base::StringPrintf("Child terminated by signal %d (%s)%s", code, strsignal(code), WCOREDUMP(status) ? " (core dumped)" : ""); @@ -112,9 +112,11 @@ } if (reason_ == kTerminationNormal) { - message += base::StringPrintf(" exit with code %d", code_); - } else if (reason == kTerminationSignal) { - message += base::StringPrintf(" termination by signal %d", code_); + message += base::StringPrintf(", expected exit with code %d", code_); + } else if (reason_ == kTerminationSignal) { + message += base::StringPrintf(", expected termination by signal %d (%s)", + code_, + strsignal(code_)); } if (reason != reason_ || code != code_) {
diff --git a/third_party/crashpad/crashpad/test/paths_mac.cc b/third_party/crashpad/crashpad/test/paths_mac.cc index ce6c5f3..f3dca57 100644 --- a/third_party/crashpad/crashpad/test/paths_mac.cc +++ b/third_party/crashpad/crashpad/test/paths_mac.cc
@@ -27,7 +27,7 @@ uint32_t executable_length = 0; _NSGetExecutablePath(nullptr, &executable_length); DCHECK_GT(executable_length, 1u); - std::string executable_path(executable_length, std::string::value_type()); + std::string executable_path(executable_length - 1, std::string::value_type()); int rv = _NSGetExecutablePath(&executable_path[0], &executable_length); DCHECK_EQ(rv, 0);
diff --git a/third_party/crashpad/crashpad/third_party/getopt/README.crashpad b/third_party/crashpad/crashpad/third_party/getopt/README.crashpad index 9b2b832..a7166e1 100644 --- a/third_party/crashpad/crashpad/third_party/getopt/README.crashpad +++ b/third_party/crashpad/crashpad/third_party/getopt/README.crashpad
@@ -13,3 +13,5 @@ - Add copy of copyright (Public domain) to the top of both files for Chromium's checklicenses step. - Compiled as .cc, and wrapped in namespace crashpad. +- memcmp() -> strncmp() in getopt.cc to make ASan happier about some string + manipulation.
diff --git a/third_party/crashpad/crashpad/third_party/getopt/getopt.cc b/third_party/crashpad/crashpad/third_party/getopt/getopt.cc index 1f6eaff..137218b9 100644 --- a/third_party/crashpad/crashpad/third_party/getopt/getopt.cc +++ b/third_party/crashpad/crashpad/third_party/getopt/getopt.cc
@@ -240,11 +240,11 @@ /* first, is it a long option? */ if (longopts != NULL - && (memcmp (argv[optind], "--", 2) == 0 + && (strncmp (argv[optind], "--", 2) == 0 || (only && argv[optind][0] == '+')) && optwhere == 1) { /* handle long options */ - if (memcmp (argv[optind], "--", 2) == 0) + if (strncmp (argv[optind], "--", 2) == 0) optwhere = 2; longopt_match = -1; possible_arg = strchr (argv[optind] + optwhere, '='); @@ -259,8 +259,8 @@ match_chars = (possible_arg - argv[optind]) - optwhere; for (optindex = 0; longopts[optindex].name != NULL; optindex++) { - if (memcmp (argv[optind] + optwhere, - longopts[optindex].name, match_chars) == 0) + if (strncmp (argv[optind] + optwhere, + longopts[optindex].name, match_chars) == 0) { /* do we have an exact match? */ if (match_chars == strlen (longopts[optindex].name))
diff --git a/third_party/crashpad/crashpad/util/mach/exception_types.cc b/third_party/crashpad/crashpad/util/mach/exception_types.cc index 0199b31..cef90f9 100644 --- a/third_party/crashpad/crashpad/util/mach/exception_types.cc +++ b/third_party/crashpad/crashpad/util/mach/exception_types.cc
@@ -201,6 +201,12 @@ return true; } + if (resource_type == RESOURCE_TYPE_IO) { + // These exceptions don’t ever appear to be fatal. See + // https://crashpad.chromium.org/bug/124. + return true; + } + // Treat unknown exceptions as fatal. This is the conservative approach: it // may result in more crash reports being generated, but the type-flavor // combinations can be evaluated to determine appropriate handling.
diff --git a/third_party/crashpad/crashpad/util/net/http_body.cc b/third_party/crashpad/crashpad/util/net/http_body.cc index 6bc6ec9..b1bca19 100644 --- a/third_party/crashpad/crashpad/util/net/http_body.cc +++ b/third_party/crashpad/crashpad/util/net/http_body.cc
@@ -89,7 +89,7 @@ } CompositeHTTPBodyStream::~CompositeHTTPBodyStream() { - STLDeleteContainerPointers(parts_.begin(), parts_.end()); + base::STLDeleteContainerPointers(parts_.begin(), parts_.end()); } FileOperationResult CompositeHTTPBodyStream::GetBytesBuffer(uint8_t* buffer,
diff --git a/third_party/crashpad/crashpad/util/net/http_transport_win.cc b/third_party/crashpad/crashpad/util/net/http_transport_win.cc index 6ee8e5f..58ecc478 100644 --- a/third_party/crashpad/crashpad/util/net/http_transport_win.cc +++ b/third_party/crashpad/crashpad/util/net/http_transport_win.cc
@@ -179,8 +179,12 @@ uint8_t buffer[kBufferSize]; FileOperationResult bytes_to_write = body_stream()->GetBytesBuffer(buffer, sizeof(buffer)); - if (bytes_to_write == 0) + if (bytes_to_write == 0) { break; + } else if (bytes_to_write < 0) { + LOG(ERROR) << "GetBytesBuffer failed"; + return false; + } post_data.insert(post_data.end(), buffer, buffer + bytes_to_write); }
diff --git a/third_party/crashpad/crashpad/util/numeric/int128_test.cc b/third_party/crashpad/crashpad/util/numeric/int128_test.cc index 61a6d82..90dfdb2 100644 --- a/third_party/crashpad/crashpad/util/numeric/int128_test.cc +++ b/third_party/crashpad/crashpad/util/numeric/int128_test.cc
@@ -14,10 +14,7 @@ #include "util/numeric/int128.h" -#include <stdint.h> - #include "base/bit_cast.h" -#include "build/build_config.h" #include "gtest/gtest.h" namespace crashpad {
diff --git a/third_party/crashpad/crashpad/util/stdlib/pointer_container.h b/third_party/crashpad/crashpad/util/stdlib/pointer_container.h index c835465..576270d 100644 --- a/third_party/crashpad/crashpad/util/stdlib/pointer_container.h +++ b/third_party/crashpad/crashpad/util/stdlib/pointer_container.h
@@ -37,7 +37,7 @@ ~PointerContainer() {} private: - STLElementDeleter<ContainerType> pointer_deleter_; + base::STLElementDeleter<ContainerType> pointer_deleter_; DISALLOW_COPY_AND_ASSIGN(PointerContainer); };
diff --git a/third_party/dom_distiller_js/README.chromium b/third_party/dom_distiller_js/README.chromium index a06490b..9dc94db3 100644 --- a/third_party/dom_distiller_js/README.chromium +++ b/third_party/dom_distiller_js/README.chromium
@@ -1,6 +1,6 @@ Name: dom-distiller-js URL: https://github.com/chromium/dom-distiller -Version: 6c16f14405 +Version: 91f9f016e0 License: BSD Security Critical: yes
diff --git a/third_party/expat/fuzz/OWNERS b/third_party/expat/fuzz/OWNERS new file mode 100644 index 0000000..0230f7d8 --- /dev/null +++ b/third_party/expat/fuzz/OWNERS
@@ -0,0 +1,2 @@ +aizatsky@chromium.org +mmoroz@chromium.org
diff --git a/third_party/expat/fuzz/expat_xml_parse_fuzzer.cc b/third_party/expat/fuzz/expat_xml_parse_fuzzer.cc index 78b6a2d..b4120713 100644 --- a/third_party/expat/fuzz/expat_xml_parse_fuzzer.cc +++ b/third_party/expat/fuzz/expat_xml_parse_fuzzer.cc
@@ -7,56 +7,23 @@ #include "third_party/expat/files/lib/expat.h" -#include <array> +#include <vector> -static void XMLCALL -startElement(void* userData, const char* name, const char** atts) { - int* depthPtr = static_cast<int*>(userData); - (void)atts; - - for (int i = 0; i < *depthPtr; i++) - (void)name; - - *depthPtr += 1; -} - - -static void XMLCALL -endElement(void* userData, const char* name) { - int* depthPtr = static_cast<int*>(userData); - (void)name; - - *depthPtr -= 1; -} - - -std::array<const char*, 7> kEncodings = {{ "UTF-16", "UTF-8", "ISO_8859_1", - "US_ASCII", "UTF_16BE", "UTF_16LE", - nullptr }}; - +std::vector<const char*> kEncodings = {{"UTF-16", "UTF-8", "ISO-8859-1", + "US-ASCII", "UTF-16BE", "UTF-16LE", + "INVALIDENCODING"}}; // Entry point for LibFuzzer. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - for (auto enc : kEncodings) { - XML_Parser parser = XML_ParserCreate(enc); - if (!parser) - return 0; + const char* dataPtr = reinterpret_cast<const char*>(data); - int depth = 0; - XML_SetUserData(parser, &depth); - XML_SetElementHandler(parser, startElement, endElement); - - const char* dataPtr = reinterpret_cast<const char*>(data); - - // Feed the data with two different values of |isFinal| for better coverage. - for (int isFinal = 0; isFinal <= 1; ++isFinal) { - if (XML_Parse(parser, dataPtr, size, isFinal) == XML_STATUS_ERROR) { - XML_ErrorString(XML_GetErrorCode(parser)); - XML_GetCurrentLineNumber(parser); - } + for (int use_ns = 0; use_ns <= 1; ++use_ns) { + for (auto enc : kEncodings) { + XML_Parser parser = + use_ns ? XML_ParserCreateNS(enc, '\n') : XML_ParserCreate(enc); + XML_Parse(parser, dataPtr, size, true); + XML_ParserFree(parser); } - - XML_ParserFree(parser); } return 0;
diff --git a/third_party/leveldatabase/env_chromium.cc b/third_party/leveldatabase/env_chromium.cc index 200a12a..54a9a90 100644 --- a/third_party/leveldatabase/env_chromium.cc +++ b/third_party/leveldatabase/env_chromium.cc
@@ -12,6 +12,7 @@ #include <sys/types.h> #endif +#include "base/files/file_enumerator.h" #include "base/files/file_util.h" #include "base/lazy_instance.h" #include "base/metrics/histogram.h" @@ -220,8 +221,7 @@ public: ChromiumWritableFile(const std::string& fname, base::File* f, - const UMALogger* uma_logger, - bool make_backup); + const UMALogger* uma_logger); virtual ~ChromiumWritableFile() {} leveldb::Status Append(const leveldb::Slice& data) override; leveldb::Status Close() override; @@ -237,18 +237,12 @@ const UMALogger* uma_logger_; Type file_type_; std::string parent_dir_; - bool make_backup_; }; ChromiumWritableFile::ChromiumWritableFile(const std::string& fname, base::File* f, - const UMALogger* uma_logger, - bool make_backup) - : filename_(fname), - file_(f), - uma_logger_(uma_logger), - file_type_(kOther), - make_backup_(make_backup) { + const UMALogger* uma_logger) + : filename_(fname), file_(f), uma_logger_(uma_logger), file_type_(kOther) { FilePath path = FilePath::FromUTF8Unsafe(fname); if (path.BaseName().AsUTF8Unsafe().find("MANIFEST") == 0) file_type_ = kManifest; @@ -308,9 +302,6 @@ kWritableFileSync, error); } - if (make_backup_ && file_type_ == kTable) - uma_logger_->RecordBackupResult(ChromiumEnv::MakeBackup(filename_)); - // leveldb's implicit contract for Sync() is that if this instance is for a // manifest file then the directory is also sync'ed. See leveldb's // env_posix.cc. @@ -500,20 +491,11 @@ base::File::FILE_ERROR_NO_SPACE); } -bool ChromiumEnv::MakeBackup(const std::string& fname) { - FilePath original_table_name = FilePath::FromUTF8Unsafe(fname); - FilePath backup_table_name = - original_table_name.ReplaceExtension(backup_table_extension); - return base::CopyFile(original_table_name, backup_table_name); -} +ChromiumEnv::ChromiumEnv() : ChromiumEnv("LevelDBEnv") {} -ChromiumEnv::ChromiumEnv() - : ChromiumEnv("LevelDBEnv", false /* make_backup */) {} - -ChromiumEnv::ChromiumEnv(const std::string& name, bool make_backup) +ChromiumEnv::ChromiumEnv(const std::string& name) : kMaxRetryTimeMillis(1000), name_(name), - make_backup_(make_backup), bgsignal_(&mu_), started_bgthread_(false) { uma_ioerror_base_name_ = name_ + ".IOError.BFE"; @@ -572,55 +554,29 @@ return "Unknown error."; } -FilePath ChromiumEnv::RestoreFromBackup(const FilePath& base_name) { - FilePath table_name = base_name.AddExtension(table_extension); - bool result = base::CopyFile(base_name.AddExtension(backup_table_extension), - table_name); - std::string uma_name(name_); - uma_name.append(".TableRestore"); - base::BooleanHistogram::FactoryGet( - uma_name, base::Histogram::kUmaTargetedHistogramFlag)->AddBoolean(result); - return table_name; -} +// Delete unused table backup files - a feature no longer supported. +// TODO(cmumford): Delete this function once found backup files drop below some +// very small (TBD) number. +void ChromiumEnv::DeleteBackupFiles(const FilePath& dir) { + base::HistogramBase* histogram = base::BooleanHistogram::FactoryGet( + "LevelDBEnv.DeleteTableBackupFile", + base::Histogram::kUmaTargetedHistogramFlag); -void ChromiumEnv::RestoreIfNecessary(const std::string& dir, - std::vector<std::string>* dir_entries) { - std::set<FilePath> tables_found; - std::set<FilePath> backups_found; - for (const std::string& entry : *dir_entries) { - FilePath current = FilePath::FromUTF8Unsafe(entry); - if (current.MatchesExtension(table_extension)) - tables_found.insert(current.RemoveExtension()); - if (current.MatchesExtension(backup_table_extension)) - backups_found.insert(current.RemoveExtension()); - } - std::set<FilePath> backups_only = - base::STLSetDifference<std::set<FilePath>>(backups_found, tables_found); - - if (backups_only.size()) { - std::string uma_name(name_); - uma_name.append(".MissingFiles"); - int num_missing_files = - backups_only.size() > INT_MAX ? INT_MAX : backups_only.size(); - base::Histogram::FactoryGet(uma_name, - 1 /*min*/, - 100 /*max*/, - 8 /*num_buckets*/, - base::Histogram::kUmaTargetedHistogramFlag) - ->Add(num_missing_files); - } - FilePath dir_path = FilePath::FromUTF8Unsafe(dir); - for (const FilePath& backup : backups_only) { - FilePath restored_table_name = RestoreFromBackup(dir_path.Append(backup)); - dir_entries->push_back(restored_table_name.BaseName().AsUTF8Unsafe()); + base::FileEnumerator dir_reader(dir, false, base::FileEnumerator::FILES, + FILE_PATH_LITERAL("*.bak")); + for (base::FilePath fname = dir_reader.Next(); !fname.empty(); + fname = dir_reader.Next()) { + histogram->AddBoolean(base::DeleteFile(fname, false)); } } Status ChromiumEnv::GetChildren(const std::string& dir, std::vector<std::string>* result) { + FilePath dir_path = FilePath::FromUTF8Unsafe(dir); + DeleteBackupFiles(dir_path); + std::vector<FilePath> entries; - base::File::Error error = - GetDirectoryEntries(FilePath::FromUTF8Unsafe(dir), &entries); + base::File::Error error = GetDirectoryEntries(dir_path, &entries); if (error != base::File::FILE_OK) { RecordOSError(kGetChildren, error); return MakeIOError(dir, "Could not open/read directory", kGetChildren, @@ -631,9 +587,6 @@ for (const auto& entry : entries) result->push_back(entry.BaseName().AsUTF8Unsafe()); - if (make_backup_) - RestoreIfNecessary(dir, result); - return Status::OK(); } @@ -645,10 +598,6 @@ result = MakeIOError(fname, "Could not delete file.", kDeleteFile); RecordErrorAt(kDeleteFile); } - if (make_backup_ && fname_filepath.MatchesExtension(table_extension)) { - base::DeleteFile(fname_filepath.ReplaceExtension(backup_table_extension), - false); - } return result; } @@ -880,7 +829,7 @@ return MakeIOError(fname, "Unable to create writable file", kNewWritableFile, f->error_details()); } else { - *result = new ChromiumWritableFile(fname, f.release(), this, make_backup_); + *result = new ChromiumWritableFile(fname, f.release(), this); return Status::OK(); } } @@ -896,7 +845,7 @@ return MakeIOError(fname, "Unable to create appendable file", kNewAppendableFile, f->error_details()); } - *result = new ChromiumWritableFile(fname, f.release(), this, make_backup_); + *result = new ChromiumWritableFile(fname, f.release(), this); return Status::OK(); } @@ -924,13 +873,6 @@ GetOSErrorHistogram(method, -base::File::FILE_ERROR_MAX)->Add(-error); } -void ChromiumEnv::RecordBackupResult(bool result) const { - std::string uma_name(name_); - uma_name.append(".TableBackup"); - base::BooleanHistogram::FactoryGet( - uma_name, base::Histogram::kUmaTargetedHistogramFlag)->AddBoolean(result); -} - base::HistogramBase* ChromiumEnv::GetOSErrorHistogram(MethodID method, int limit) const { std::string uma_name;
diff --git a/third_party/leveldatabase/env_chromium.h b/third_party/leveldatabase/env_chromium.h index 33e7aef..51f2866 100644 --- a/third_party/leveldatabase/env_chromium.h +++ b/third_party/leveldatabase/env_chromium.h
@@ -102,7 +102,6 @@ virtual void RecordErrorAt(MethodID method) const = 0; virtual void RecordOSError(MethodID method, base::File::Error error) const = 0; - virtual void RecordBackupResult(bool success) const = 0; }; class RetrierProvider { @@ -121,7 +120,6 @@ typedef void(ScheduleFunc)(void*); - static bool MakeBackup(const std::string& fname); virtual ~ChromiumEnv(); virtual bool FileExists(const std::string& fname); @@ -154,7 +152,7 @@ leveldb::Logger** result); protected: - ChromiumEnv(const std::string& name, bool make_backup); + explicit ChromiumEnv(const std::string& name); static const char* FileErrorString(base::File::Error error); @@ -165,6 +163,7 @@ void RecordOpenFilesLimit(const std::string& type); base::HistogramBase* GetMaxFDHistogram(const std::string& type) const; base::HistogramBase* GetOSErrorHistogram(MethodID method, int limit) const; + void DeleteBackupFiles(const base::FilePath& dir); // File locks may not be exclusive within a process (e.g. on POSIX). Track // locks held by the ChromiumEnv to prevent access within the process. @@ -190,10 +189,6 @@ reinterpret_cast<ChromiumEnv*>(arg)->BGThread(); } - virtual void RecordBackupResult(bool result) const; - void RestoreIfNecessary(const std::string& dir, - std::vector<std::string>* children); - base::FilePath RestoreFromBackup(const base::FilePath& base_name); void RecordLockFileAncestors(int num_missing_ancestors) const; base::HistogramBase* GetMethodIOErrorHistogram() const; base::HistogramBase* GetLockFileAncestorHistogram() const; @@ -208,7 +203,6 @@ std::string name_; std::string uma_ioerror_base_name_; - bool make_backup_; base::Lock mu_; base::ConditionVariable bgsignal_;
diff --git a/third_party/leveldatabase/env_chromium_unittest.cc b/third_party/leveldatabase/env_chromium_unittest.cc index 070e893..d4819e89 100644 --- a/third_party/leveldatabase/env_chromium_unittest.cc +++ b/third_party/leveldatabase/env_chromium_unittest.cc
@@ -92,17 +92,10 @@ return false; } -class BackupEnv : public ChromiumEnv { - public: - BackupEnv() : ChromiumEnv("BackupEnv", true /* backup tables */) {} -}; - -base::LazyInstance<BackupEnv>::Leaky backup_env = LAZY_INSTANCE_INITIALIZER; - -TEST(ChromiumEnv, BackupTables) { +TEST(ChromiumEnv, DeleteBackupTables) { Options options; options.create_if_missing = true; - options.env = backup_env.Pointer(); + options.env = Env::Default(); base::ScopedTempDir scoped_temp_dir; ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); @@ -115,36 +108,29 @@ EXPECT_TRUE(status.ok()) << status.ToString(); Slice a = "a"; Slice z = "z"; - db->CompactRange(&a, &z); - int ldb_files = CountFilesWithExtension(dir, FPL(".ldb")); - int bak_files = CountFilesWithExtension(dir, FPL(".bak")); - EXPECT_GT(ldb_files, 0); - EXPECT_EQ(ldb_files, bak_files); - base::FilePath ldb_file; - EXPECT_TRUE(GetFirstLDBFile(dir, &ldb_file)); + db->CompactRange(&a, &z); // Ensure manifest written out to table. delete db; - EXPECT_TRUE(base::DeleteFile(ldb_file, false)); - EXPECT_EQ(ldb_files - 1, CountFilesWithExtension(dir, FPL(".ldb"))); + db = nullptr; - // The ldb file deleted above should be restored in Open. - status = leveldb::DB::Open(options, dir.AsUTF8Unsafe(), &db); + // Current ChromiumEnv no longer makes backup tables - verify for sanity. + EXPECT_EQ(1, CountFilesWithExtension(dir, FPL(".ldb"))); + EXPECT_EQ(0, CountFilesWithExtension(dir, FPL(".bak"))); + + // Manually create our own backup table to simulate opening db created by + // prior release. + base::FilePath ldb_path; + ASSERT_TRUE(GetFirstLDBFile(dir, &ldb_path)); + base::FilePath bak_path = ldb_path.ReplaceExtension(FPL(".bak")); + ASSERT_TRUE(base::CopyFile(ldb_path, bak_path)); + EXPECT_EQ(1, CountFilesWithExtension(dir, FPL(".bak"))); + + // Now reopen and close then verify the backup file was deleted. + status = DB::Open(options, dir.AsUTF8Unsafe(), &db); EXPECT_TRUE(status.ok()) << status.ToString(); - std::string value; - status = db->Get(ReadOptions(), "key", &value); - EXPECT_TRUE(status.ok()) << status.ToString(); - EXPECT_EQ("value", value); + EXPECT_EQ(0, CountFilesWithExtension(dir, FPL(".bak"))); delete db; - - // Ensure that deleting an ldb file also deletes its backup. - int orig_ldb_files = CountFilesWithExtension(dir, FPL(".ldb")); - EXPECT_GT(ldb_files, 0); - EXPECT_EQ(ldb_files, bak_files); - EXPECT_TRUE(GetFirstLDBFile(dir, &ldb_file)); - options.env->DeleteFile(ldb_file.AsUTF8Unsafe()); - ldb_files = CountFilesWithExtension(dir, FPL(".ldb")); - bak_files = CountFilesWithExtension(dir, FPL(".bak")); - EXPECT_EQ(orig_ldb_files - 1, ldb_files); - EXPECT_EQ(bak_files, ldb_files); + EXPECT_EQ(1, CountFilesWithExtension(dir, FPL(".ldb"))); + EXPECT_EQ(0, CountFilesWithExtension(dir, FPL(".bak"))); } TEST(ChromiumEnv, GetChildrenEmptyDir) {
diff --git a/third_party/objenesis/BUILD.gn b/third_party/objenesis/BUILD.gn new file mode 100644 index 0000000..bf7289c --- /dev/null +++ b/third_party/objenesis/BUILD.gn
@@ -0,0 +1,10 @@ +# Copyright 2016 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/android/rules.gni") + +java_prebuilt("objenesis_java") { + testonly = true + jar_path = "lib/objenesis-2.4.jar" +}
diff --git a/third_party/objenesis/LICENSE b/third_party/objenesis/LICENSE new file mode 100644 index 0000000..25b736e --- /dev/null +++ b/third_party/objenesis/LICENSE
@@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file
diff --git a/third_party/objenesis/OWNERS b/third_party/objenesis/OWNERS new file mode 100644 index 0000000..7fcd92b --- /dev/null +++ b/third_party/objenesis/OWNERS
@@ -0,0 +1,3 @@ +jbudorick@chromium.org +mikecase@chromium.org +yolandyan@chromium.org \ No newline at end of file
diff --git a/third_party/objenesis/README.chromium b/third_party/objenesis/README.chromium new file mode 100644 index 0000000..88f143a --- /dev/null +++ b/third_party/objenesis/README.chromium
@@ -0,0 +1,11 @@ +Name: Objenesis +URL: http://objenesis.org/ +Version: 2.4 +License: Apache 2.0 +License File: NOT_SHIPPED +Security Critical: no +Description: +Objenesis is a small Java library to help instantiate a new object of a +particular class. + +Local Modifications: None \ No newline at end of file
diff --git a/third_party/objenesis/lib/objenesis-2.4.jar.sha1 b/third_party/objenesis/lib/objenesis-2.4.jar.sha1 new file mode 100644 index 0000000..c445301 --- /dev/null +++ b/third_party/objenesis/lib/objenesis-2.4.jar.sha1
@@ -0,0 +1 @@ +af258f7e904e6683038e98d0dbab7822e503c0f2 \ No newline at end of file
diff --git a/third_party/qcms/README.chromium b/third_party/qcms/README.chromium index 38f2844..8112972 100644 --- a/third_party/qcms/README.chromium +++ b/third_party/qcms/README.chromium
@@ -159,6 +159,8 @@ - https://bugs.chromium.org/p/chromium/issues/detail?id=600338 - Add API to output parametric gamma curve data - https://bugs.chromium.org/p/chromium/issues/detail?id=615667 + - Fix an unitialized read in gamma curve data. + - https://bugs.chromium.org/p/chromium/issues/detail?id=635042 For the Chromium changes, since the import, in a patch format run: git diff b8456f38 src
diff --git a/third_party/qcms/src/iccread.c b/third_party/qcms/src/iccread.c index b0a9a02..1245065 100644 --- a/third_party/qcms/src/iccread.c +++ b/third_party/qcms/src/iccread.c
@@ -1162,6 +1162,7 @@ curve = malloc(sizeof(struct curveType) + sizeof(uInt16Number)*num_entries); if (!curve) return NULL; + curve->type = CURVE_TYPE; curve->count = num_entries; curve->data[0] = float_to_u8Fixed8Number(gamma); return curve;
diff --git a/tools/android/eclipse/.classpath b/tools/android/eclipse/.classpath index a15386f..222e1cf 100644 --- a/tools/android/eclipse/.classpath +++ b/tools/android/eclipse/.classpath
@@ -58,6 +58,8 @@ <classpathentry kind="src" path="components/precache/android/javatests/src"/> <classpathentry kind="src" path="components/safe_json/android/java/src"/> <classpathentry kind="src" path="components/service_tab_launcher/android/java/src"/> + <classpathentry kind="src" path="components/sync/android/java/src"/> + <classpathentry kind="src" path="components/sync/android/javatests/src"/> <classpathentry kind="src" path="components/variations/android/java/src"/> <classpathentry kind="src" path="components/web_contents_delegate_android/android/java/src"/> <classpathentry kind="src" path="content/public/android/java/src"/> @@ -72,6 +74,7 @@ <classpathentry kind="src" path="content/shell/android/shell_apk/src"/> <classpathentry kind="src" path="device/battery/android/java/src"/> <classpathentry kind="src" path="device/bluetooth/android/java/src"/> + <classpathentry kind="src" path="device/gamepad/android/java/src"/> <classpathentry kind="src" path="device/usb/android/java/src"/> <classpathentry kind="src" path="device/vibration/android/java/src"/> <classpathentry kind="src" path="media/base/android/java/src"/> @@ -103,7 +106,6 @@ <classpathentry kind="src" path="third_party/gif_player/src"/> <classpathentry kind="src" path="third_party/jmake/src"/> <classpathentry kind="src" path="third_party/junit/src/src/main/java"/> - <classpathentry kind="src" path="third_party/mockito/src/cglib-and-asm/src"/> <classpathentry kind="src" path="third_party/mockito/src/src"/> <classpathentry kind="src" path="tools/android/findbugs_plugin/src"/> <classpathentry kind="src" path="tools/android/findbugs_plugin/test/java/src"/> @@ -212,6 +214,7 @@ <classpathentry kind="lib" path="third_party/android_tools/sdk/extras/android/support/v7/appcompat/libs/android-support-v7-appcompat.jar" sourcepath="third_party/android_tools/sdk/sources"/> <classpathentry kind="lib" path="third_party/findbugs/lib/findbugs.jar"/> <classpathentry kind="lib" path="third_party/junit/src/lib/hamcrest-core-1.1.jar"/> + <classpathentry kind="lib" path="third_party/mockito/src/lib/repackaged/cglib-and-asm-1.0.jar" sourcepath="third_party/mockito/src/lib/sources/cglib-and-asm-1.0-sources.jar"/> <classpathentry kind="lib" path="third_party/robolectric/lib/robolectric-2.4-jar-with-dependencies.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/cacheinvalidation_proto_java.jar"/> <classpathentry kind="lib" path="out/Debug/lib.java/content_java.jar"/>
diff --git a/tools/checklicenses/checklicenses.py b/tools/checklicenses/checklicenses.py index 17da23b..6dd1c18 100755 --- a/tools/checklicenses/checklicenses.py +++ b/tools/checklicenses/checklicenses.py
@@ -176,6 +176,11 @@ 'UNKNOWN', ], + # https://bugs.chromium.org/p/swiftshader/issues/detail?id=1 + 'third_party/swiftshader': [ + 'UNKNOWN', + ], + # http://code.google.com/p/angleproject/issues/detail?id=217 'third_party/angle': [ 'UNKNOWN',
diff --git a/tools/chrome_proxy/common/chrome_proxy_measurements.py b/tools/chrome_proxy/common/chrome_proxy_measurements.py index 21a3f558..58d7faa5 100644 --- a/tools/chrome_proxy/common/chrome_proxy_measurements.py +++ b/tools/chrome_proxy/common/chrome_proxy_measurements.py
@@ -50,8 +50,8 @@ 'Waiting for Chrome to start using the DRP...' '</body></html>')) - # Ensure the page has started loading before attempting the DRP check. - tab.WaitForJavaScriptExpression('performance.timing.loadEventStart', 60) + # Ensure the page has finished loading before attempting the DRP check. + tab.WaitForJavaScriptExpression('performance.timing.loadEventEnd', 60) expected_via_header = metrics.CHROME_PROXY_VIA_HEADER if ChromeProxyValidation.extra_via_header:
diff --git a/tools/chrome_proxy/common/inspector_network.py b/tools/chrome_proxy/common/inspector_network.py index dee22d37..af0e39bb 100644 --- a/tools/chrome_proxy/common/inspector_network.py +++ b/tools/chrome_proxy/common/inspector_network.py
@@ -239,7 +239,9 @@ logging.warning('HTTP Response missing required field: %s', field) return request_id = params['requestId'] - assert request_id in self._initiators + if request_id not in self._initiators: + logging.warning('Dropped a message with no initiator.') + return initiator = self._initiators[request_id] self._http_responses.append( InspectorNetworkResponseData(self, params, initiator))
diff --git a/tools/clang/plugins/FindBadConstructsAction.cpp b/tools/clang/plugins/FindBadConstructsAction.cpp index 7c76dbe..13c7090 100644 --- a/tools/clang/plugins/FindBadConstructsAction.cpp +++ b/tools/clang/plugins/FindBadConstructsAction.cpp
@@ -59,14 +59,14 @@ options_.check_templates = true; } else if (args[i] == "follow-macro-expansion") { options_.follow_macro_expansion = true; - } else if (args[i] == "check-implicit-copy-ctors") { - options_.check_implicit_copy_ctors = true; } else if (args[i] == "no-realpath") { options_.no_realpath = true; } else if (args[i] == "check-ipc") { options_.check_ipc = true; } else if (args[i] == "check-auto-raw-pointer") { options_.check_auto_raw_pointer = true; + } else if (args[i] == "check-implicit-copy-ctors") { + // This is deprecated and will be removed once the flag is not used. } else { parsed = false; llvm::errs() << "Unknown clang plugin argument: " << args[i] << "\n";
diff --git a/tools/clang/plugins/FindBadConstructsConsumer.cpp b/tools/clang/plugins/FindBadConstructsConsumer.cpp index f670a367..0cb0a088 100644 --- a/tools/clang/plugins/FindBadConstructsConsumer.cpp +++ b/tools/clang/plugins/FindBadConstructsConsumer.cpp
@@ -368,7 +368,7 @@ // The current check is buggy. An implicit copy constructor does not // have an inline body, so this check never fires for classes with a // user-declared out-of-line constructor. - if (it->hasInlineBody() && options_.check_implicit_copy_ctors) { + if (it->hasInlineBody()) { if (it->isCopyConstructor() && !record->hasUserDeclaredCopyConstructor()) { // In general, implicit constructors are generated on demand. But
diff --git a/tools/clang/plugins/Options.h b/tools/clang/plugins/Options.h index a7bf579..0e10d1d 100644 --- a/tools/clang/plugins/Options.h +++ b/tools/clang/plugins/Options.h
@@ -14,9 +14,6 @@ bool check_enum_last_value = false; bool check_templates = false; bool follow_macro_expansion = false; - // This is needed during the migration from ASTConsumer approach to the - // RecursiveASTVisitor approach. See https://crbug.com/436357 for details. - bool check_implicit_copy_ctors = false; // This is needed for some distributed build-sytems to respect banned // paths. See https://crbug.com/583454 for details. bool no_realpath = false;
diff --git a/tools/clang/plugins/tests/test.py b/tools/clang/plugins/tests/test.py index 3e8b94bf..67ad6c4 100755 --- a/tools/clang/plugins/tests/test.py +++ b/tools/clang/plugins/tests/test.py
@@ -19,7 +19,6 @@ """Test harness for the Chrome style plugin.""" def AdjustClangArguments(self, clang_cmd): - self.AddPluginArg(clang_cmd, 'check-implicit-copy-ctors') self.AddPluginArg(clang_cmd, 'follow-macro-expansion') clang_cmd.extend([ # Skip code generation
diff --git a/tools/copyright_scanner/third_party_files_whitelist.txt b/tools/copyright_scanner/third_party_files_whitelist.txt index e6d125b..e04d0a53 100644 --- a/tools/copyright_scanner/third_party_files_whitelist.txt +++ b/tools/copyright_scanner/third_party_files_whitelist.txt
@@ -122,10 +122,10 @@ native_client_sdk/doc_generated/rest-devsite-examples.html # String '(c)' used in certificates organization names net/cert/x509_certificate_known_roots_win.h -net/quic/core/crypto/common_cert_set_1a.inc -net/quic/core/crypto/common_cert_set_1b.inc net/quic/core/crypto/common_cert_set_2a.inc net/quic/core/crypto/common_cert_set_2b.inc +net/quic/core/crypto/common_cert_set_3a.inc +net/quic/core/crypto/common_cert_set_3b.inc # String '(c)' used in certificates organization names net/test/test_certificate_data.h # Copyright The Chromium Authors and Netscape Communications Corporation; BSD
diff --git a/tools/cygprofile/cygprofile.cc b/tools/cygprofile/cygprofile.cc index c7f12e8..c4cb5ef 100644 --- a/tools/cygprofile/cygprofile.cc +++ b/tools/cygprofile/cygprofile.cc
@@ -249,7 +249,7 @@ void ThreadLog::TakeEntries(std::vector<LogEntry>* destination) { base::AutoLock auto_lock(lock_); destination->swap(entries_); - STLClearObject(&entries_); + base::STLClearObject(&entries_); } void ThreadLog::Flush(std::vector<LogEntry>* entries) const { @@ -273,7 +273,7 @@ it->time.tv_nsec / 1000, it->pid, it->tid, it->address); } - STLClearObject(entries); + base::STLClearObject(entries); } ThreadLogsManager::ThreadLogsManager() @@ -297,7 +297,7 @@ } flush_thread.reset(); // Joins the flush thread. - STLDeleteContainerPointers(logs_.begin(), logs_.end()); + base::STLDeleteContainerPointers(logs_.begin(), logs_.end()); } void ThreadLogsManager::AddLog(std::unique_ptr<ThreadLog> new_log) {
diff --git a/tools/gn/BUILD.gn b/tools/gn/BUILD.gn index 56f3070..e3a21ff4 100644 --- a/tools/gn/BUILD.gn +++ b/tools/gn/BUILD.gn
@@ -289,6 +289,7 @@ "function_get_target_outputs_unittest.cc", "function_process_file_template_unittest.cc", "function_rebase_path_unittest.cc", + "function_template_unittest.cc", "function_toolchain_unittest.cc", "function_write_file_unittest.cc", "functions_target_unittest.cc",
diff --git a/tools/gn/docs/reference.md b/tools/gn/docs/reference.md index 9d62a5e..7771965 100644 --- a/tools/gn/docs/reference.md +++ b/tools/gn/docs/reference.md
@@ -624,7 +624,7 @@ ``` -## **gn format [\--dump-tree] [\--in-place] [\--stdin] BUILD.gn** +## **gn format [\--dump-tree] (\--stdin | <build_file>)** ``` Formats .gn file to a standard format. @@ -642,6 +642,7 @@ ``` ### **Arguments** + ``` --dry-run Does not change or output anything, but sets the process exit code @@ -652,16 +653,12 @@ - Exit code 2: successful format, but differs from on disk. --dump-tree - For debugging only, dumps the parse tree. - - --in-place - Instead of writing the formatted file to stdout, replace the input - file with the formatted output. If no reformatting is required, - the input file will not be touched, and nothing printed. + For debugging, dumps the parse tree to stdout and does not update + the file or print formatted output. --stdin - Read input from stdin (and write to stdout). Not compatible with - --in-place of course. + Read input from stdin and write to stdout rather than update + a file in-place. ``` @@ -2563,10 +2560,12 @@ ``` The sources assignment filter is a list of patterns that remove files from the list implicitly whenever the "sources" variable is - assigned to. This is intended to be used to globally filter out files - with platform-specific naming schemes when they don't apply, for - example, you may want to filter out all "*_win.cc" files on non- - Windows platforms. + assigned to. This will do nothing for non-lists. + + This is intended to be used to globally filter out files with + platform-specific naming schemes when they don't apply, for example + you may want to filter out all "*_win.cc" files on non-Windows + platforms. Typically this will be called once in the master build config script to set up the filter for the current platform. Subsequent calls will @@ -3344,7 +3343,17 @@ copied. The compile_xcassets tool will be called with one or more source (each - an asset catalog) that needs to be compiled to a single output. + an asset catalog) that needs to be compiled to a single output. The + following substitutions are avaiable: + + {{inputs}} + Expands to the list of .xcassets to use as input to compile the + asset catalog. + + {{bundle_product_type}} + Expands to the product_type of the bundle that will contain the + compiled asset catalog. Usually corresponds to the product_type + property of the corresponding create_bundle target. ``` @@ -3420,10 +3429,25 @@ The tool() function call specifies the commands commands to run for a given step. See "gn help tool". - toolchain_args() - List of arguments to pass to the toolchain when invoking this - toolchain. This applies only to non-default toolchains. See - "gn help toolchain_args" for more. + toolchain_args + Overrides for build arguments to pass to the toolchain when invoking + it. This is a variable of type "scope" where the variable names + correspond to variables in declare_args() blocks. + + When you specify a target using an alternate toolchain, the master + build configuration file is re-interpreted in the context of that + toolchain. toolchain_args allows you to control the arguments + passed into this alternate invocation of the build. + + Any default system arguments or arguments passed in via "gn args" + will also be passed to the alternate invocation unless explicitly + overridden by toolchain_args. + + The toolchain_args will be ignored when the toolchain being defined + is the default. In this case, it's expected you want the default + argument values. + + See also "gn help buildargs" for an overview of these arguments. deps Dependencies of this toolchain. These dependencies will be resolved @@ -3459,13 +3483,14 @@ by the toolchain label). 2. Re-runs the master build configuration file, applying the arguments specified by the toolchain_args section of the toolchain - definition (see "gn help toolchain_args"). + definition. 3. Loads the destination build file in the context of the configuration file in the previous step. ``` -### **Example**: +### **Example** + ``` toolchain("plugin_toolchain") { tool("cc") { @@ -3473,7 +3498,7 @@ ... } - toolchain_args() { + toolchain_args = { is_plugin = true is_32bit = true is_64bit = false @@ -3485,40 +3510,10 @@ ## **toolchain_args**: Set build arguments for toolchain build setup. ``` - Used inside a toolchain definition to pass arguments to an alternate - toolchain's invocation of the build. + DEPRECATED. Instead use: + toolchain_args = { ... } - When you specify a target using an alternate toolchain, the master - build configuration file is re-interpreted in the context of that - toolchain (see "gn help toolchain"). The toolchain_args function - allows you to control the arguments passed into this alternate - invocation of the build. - - Any default system arguments or arguments passed in on the command- - line will also be passed to the alternate invocation unless explicitly - overridden by toolchain_args. - - The toolchain_args will be ignored when the toolchain being defined - is the default. In this case, it's expected you want the default - argument values. - - See also "gn help buildargs" for an overview of these arguments. - -``` - -### **Example**: -``` - toolchain("my_weird_toolchain") { - ... - toolchain_args() { - # Override the system values for a generic Posix system. - is_win = false - is_posix = true - - # Pass this new value for specific setup for my toolchain. - is_my_weird_system = true - } - } + See "gn help toolchain" for documentation. ``` @@ -4175,6 +4170,40 @@ ``` +## **bundle_deps_filter**: [label list] A list of labels that are filtered out. + +``` + A list of target labels. + + This list contains target label patterns that should be filtered out + when creating the bundle. Any target matching one of those label will + be removed from the dependencies of the create_bundle target. + + This is mostly useful when creating application extension bundle as + the application extension has access to runtime resources from the + application bundle and thus do not require a second copy. + + See "gn help create_bundle" for more information. + +``` + +### **Example** + +``` + create_bundle("today_extension") { + deps = [ + "//base" + ] + bundle_root_dir = "$root_out_dir/today_extension.appex" + bundle_deps_filter = [ + # The extension uses //base but does not use any function calling + # into third_party/icu and thus does not need the icudtl.dat file. + "//third_party/icu:icudata", + ] + } + + +``` ## **bundle_executable_dir**: Expansion of {{bundle_executable_dir}} in create_bundle. ``` @@ -4830,40 +4859,6 @@ ``` -## **bundle_deps_filter**: [label list] A list of labels that are filtered out. - -``` - A list of target labels. - - This list contains target label patterns that should be filtered out - when creating the bundle. Any target matching one of those label will - be removed from the dependencies of the create_bundle target. - - This is mostly useful when creating application extension bundle as - the application extension has access to runtime resources from the - application bundle and thus do not require a second copy. - - See "gn help create_bundle" for more information. - -``` - -### **Example** - -``` - create_bundle("today_extension") { - deps = [ - "//base" - ] - bundle_root_dir = "$root_out_dir/today_extension.appex" - bundle_deps_filter = [ - # The extension uses //base but does not use any function calling - # into third_party/icu and thus does not need the icudtl.dat file. - "//third_party/icu:icudata", - ] - } - - -``` ## **include_dirs**: Additional include directories. ``` @@ -5741,7 +5736,7 @@ toolchain_args section of a toolchain definition. The use-case for this is that a toolchain may be building code for a different platform, and that it may want to always specify Posix, for example. - See "gn help toolchain_args" for more. + See "gn help toolchain" for more. If you specify an override for a build argument that never appears in a "declare_args" call, a nonfatal error will be displayed. @@ -5871,7 +5866,7 @@ ``` -## **GN build language grammar** +## **Language and grammar for GN build files** ### **Tokens** @@ -5951,6 +5946,13 @@ To insert an arbitrary byte value, use $0xFF. For example, to insert a newline character: "Line one$0x0ALine two". + An expansion will evaluate the variable following the '$' and insert + a stringified version of it into the result. For example, to concat + two path components with a slash separating them: + "$var_one/$var_two" + Use the "${var_one}" format to be explicitly deliniate the variable + for otherwise-ambiguous cases. + ``` ### **Punctuation** @@ -5973,19 +5975,20 @@ File = StatementList . Statement = Assignment | Call | Condition . - Assignment = identifier AssignOp Expr . + LValue = identifier | ArrayAccess | ScopeAccess . + Assignment = LValue AssignOp Expr . Call = identifier "(" [ ExprList ] ")" [ Block ] . Condition = "if" "(" Expr ")" Block [ "else" ( Condition | Block ) ] . Block = "{" StatementList "}" . StatementList = { Statement } . - ArrayAccess = identifier "[" { identifier | integer } "]" . + ArrayAccess = identifier "[" Expr "]" . ScopeAccess = identifier "." identifier . Expr = UnaryExpr | Expr BinaryOp Expr . UnaryExpr = PrimaryExpr | UnaryOp UnaryExpr . PrimaryExpr = identifier | integer | string | Call - | ArrayAccess | ScopeAccess + | ArrayAccess | ScopeAccess | Block | "(" Expr ")" | "[" [ ExprList [ "," ] ] "]" . ExprList = Expr { "," Expr } . @@ -6000,6 +6003,103 @@ All binary operators are left-associative. +``` + +### **Types** + +``` + The GN language is dynamically typed. The following types are used: + + - Boolean: Uses the keywords "true" and "false". There is no + implicit conversion between booleans and integers. + + - Integers: All numbers in GN are signed 64-bit integers. + + - Strings: Strings are 8-bit with no enforced encoding. When a string + is used to interact with other systems with particular encodings + (like the Windows and Mac filesystems) it is assumed to be UTF-8. + See "String literals" above for more. + + - Lists: Lists are arbitrary-length ordered lists of values. See + "Lists" below for more. + + - Scopes: Scopes are like dictionaries that use variable names for + keys. See "Scopes" below for more. + +``` + +### **Lists** + +``` + Lists are created with [] and using commas to separate items: + + mylist = [ 0, 1, 2, "some string" ] + + A comma after the last item is optional. Lists are dereferenced using + 0-based indexing: + + mylist[0] += 1 + var = mylist[2] + + Lists can be concatenated using the '+' and '+=' operators. Bare + values can not be concatenated with lists, to add a single item, + it must be put into a list of length one. + + Items can be removed from lists using the '-' and '-=' operators. + This will remove all occurrences of every item in the right-hand list + from the left-hand list. It is an error to remove an item not in the + list. This is to prevent common typos and to detect dead code that + is removing things that no longer apply. + + It is an error to use '=' to replace a nonempty list with another + nonempty list. This is to prevent accidentally overwriting data + when in most cases '+=' was intended. To overwrite a list on purpose, + first assign it to the empty list: + + mylist = [] + mylist = otherlist + + When assigning to a list named 'sources' using '=' or '+=', list + items may be automatically filtered out. + See "gn help set_sources_assignment_filter" for more. + +``` + +### **Scopes** + +``` + All execution happens in the context of a scope which holds the + current state (like variables). With the exception of loops and + conditions, '{' introduces a new scope that has a parent reference to + the old scope. + + Variable reads recursively search all nested scopes until the + variable is found or there are no more scopes. Variable writes always + go into the current scope. This means that after the closing '}' + (again excepting loops and conditions), all local variables will be + restored to the previous values. This also means that "foo = foo" + can do useful work by copying a variable into the current scope that + was defined in a containing scope. + + Scopes can also be assigned to variables. Such scopes can be created + by functions like exec_script, when invoking a template (the template + code refers to the variables set by the invoking code by the + implicitly-created "invoker" scope), or explicitly like: + + empty_scope = {} + myvalues = { + foo = 21 + bar = "something" + } + + Inside such a scope definition can be any GN code including + conditionals and function calls. After the close of the scope, it will + contain all variables explicitly set by the code contained inside it. + After this, the values can be read, modified, or added to: + + myvalues.foo += 2 + empty_scope.new_thing = [ 1, 2, 3 ] + ``` ## **input_conversion**: Specifies how to transform input to a variable.
diff --git a/tools/gn/function_template.cc b/tools/gn/function_template.cc index 17dda06..6136f41 100644 --- a/tools/gn/function_template.cc +++ b/tools/gn/function_template.cc
@@ -192,6 +192,25 @@ } scope->AddTemplate(template_name, new Template(scope, function)); + + // The template object above created a closure around the variables in the + // current scope. The template code will execute in that context when it's + // invoked. But this means that any variables defined above that are used + // by the template won't get marked used just by defining the template. The + // result can be spurious unused variable errors. + // + // The "right" thing to do would be to walk the syntax tree inside the + // template, find all identifier references, and mark those variables used. + // This is annoying and error-prone to implement and takes extra time to run + // for this narrow use case. + // + // Templates are most often defined in .gni files which don't get + // used-variable checking anyway, and this case is annoying enough that the + // incremental value of unused variable checking isn't worth the + // alternatives. So all values in scope before this template definition are + // exempted from unused variable checking. + scope->MarkAllUsed(); + return Value(); }
diff --git a/tools/gn/function_template_unittest.cc b/tools/gn/function_template_unittest.cc new file mode 100644 index 0000000..cd98423 --- /dev/null +++ b/tools/gn/function_template_unittest.cc
@@ -0,0 +1,29 @@ +// Copyright 2016 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 "testing/gtest/include/gtest/gtest.h" +#include "tools/gn/test_with_scope.h" + +// Checks that variables used inside template definitions aren't reported +// unused if they were declared above the template. +TEST(FunctionTemplate, MarkUsed) { + TestWithScope setup; + TestParseInput input( + "a = 1\n" // Unused outside of template. + "template(\"templ\") {\n" + " print(a)\n" + "}\n"); + ASSERT_FALSE(input.has_error()) << input.parse_err().message(); + + Err err; + input.parsed()->Execute(setup.scope(), &err); + ASSERT_FALSE(err.has_error()) << err.message(); + + // Normally the loader calls CheckForUnusedVars() when it loads a file + // since normal blocks don't do this check. To avoid having to make this + // test much more complicated, just explicitly do the check to make sure + // things are marked properly. + setup.scope()->CheckForUnusedVars(&err); + EXPECT_FALSE(err.has_error()); +}
diff --git a/tools/gn/function_toolchain.cc b/tools/gn/function_toolchain.cc index 69ca961c..9b08809 100644 --- a/tools/gn/function_toolchain.cc +++ b/tools/gn/function_toolchain.cc
@@ -317,7 +317,7 @@ " toolchain_args\n" " Overrides for build arguments to pass to the toolchain when invoking\n" " it. This is a variable of type \"scope\" where the variable names\n" - " correspond to varibles in declare_args() blocks.\n" + " correspond to variables in declare_args() blocks.\n" "\n" " When you specify a target using an alternate toolchain, the master\n" " build configuration file is re-interpreted in the context of that\n" @@ -858,7 +858,17 @@ " copied.\n" "\n" " The compile_xcassets tool will be called with one or more source (each\n" - " an asset catalog) that needs to be compiled to a single output.\n" + " an asset catalog) that needs to be compiled to a single output. The\n" + " following substitutions are avaiable:\n" + "\n" + " {{inputs}}\n" + " Expands to the list of .xcassets to use as input to compile the\n" + " asset catalog.\n" + "\n" + " {{bundle_product_type}}\n" + " Expands to the product_type of the bundle that will contain the\n" + " compiled asset catalog. Usually corresponds to the product_type\n" + " property of the corresponding create_bundle target.\n" "\n" "Separate linking and dependencies for shared libraries\n" "\n" @@ -1042,46 +1052,4 @@ return Value(); } -extern const char kToolchainArgs[] = "toolchain_args"; -extern const char kToolchainArgs_HelpShort[] = - "toolchain_args: Set build arguments for toolchain build setup."; -extern const char kToolchainArgs_Help[] = - "toolchain_args: Set build arguments for toolchain build setup.\n" - "\n" - " DEPRECATED. Instead use:\n" - " toolchain_args = { ... }\n" - "\n" - " See \"gn help toolchain\" for documentation.\n"; - -Value RunToolchainArgs(Scope* scope, - const FunctionCallNode* function, - const std::vector<Value>& args, - BlockNode* block, - Err* err) { - // This is a backwards-compatible shim that converts the old form of: - // toolchain_args() { - // foo = bar - // } - // to the new form: - // toolchain_args = { - // foo = bar - // } - // It will be deleted when all users of toolchain_args as a function are - // deleted. - if (!args.empty()) { - *err = Err(function->function(), "This function takes no arguments."); - return Value(); - } - - std::unique_ptr<Scope> block_scope(new Scope(scope)); - block->Execute(block_scope.get(), err); - if (err->has_error()) - return Value(); - - block_scope->DetachFromContaining(); - scope->SetValue("toolchain_args", Value(function, std::move(block_scope)), - function); - return Value(); -} - } // namespace functions
diff --git a/tools/gn/functions.cc b/tools/gn/functions.cc index 02129a8..e584f870 100644 --- a/tools/gn/functions.cc +++ b/tools/gn/functions.cc
@@ -1014,7 +1014,6 @@ INSERT_FUNCTION(Template, false) INSERT_FUNCTION(Tool, false) INSERT_FUNCTION(Toolchain, false) - INSERT_FUNCTION(ToolchainArgs, false) INSERT_FUNCTION(WriteFile, false) #undef INSERT_FUNCTION
diff --git a/tools/gn/functions.h b/tools/gn/functions.h index 48e9302..9668658 100644 --- a/tools/gn/functions.h +++ b/tools/gn/functions.h
@@ -358,15 +358,6 @@ BlockNode* block, Err* err); -extern const char kToolchainArgs[]; -extern const char kToolchainArgs_HelpShort[]; -extern const char kToolchainArgs_Help[]; -Value RunToolchainArgs(Scope* scope, - const FunctionCallNode* function, - const std::vector<Value>& args, - BlockNode* block, - Err* err); - extern const char kWriteFile[]; extern const char kWriteFile_HelpShort[]; extern const char kWriteFile_Help[];
diff --git a/tools/gn/ninja_create_bundle_target_writer.cc b/tools/gn/ninja_create_bundle_target_writer.cc index 3b87129..77e05b2 100644 --- a/tools/gn/ninja_create_bundle_target_writer.cc +++ b/tools/gn/ninja_create_bundle_target_writer.cc
@@ -164,6 +164,9 @@ out_ << " | "; path_output_.WriteFile(out_, input_dep); out_ << std::endl; + + out_ << " product_type = " << target_->bundle_data().product_type() + << std::endl; } OutputFile
diff --git a/tools/gn/ninja_create_bundle_target_writer_unittest.cc b/tools/gn/ninja_create_bundle_target_writer_unittest.cc index dee99c4..15885baf 100644 --- a/tools/gn/ninja_create_bundle_target_writer_unittest.cc +++ b/tools/gn/ninja_create_bundle_target_writer_unittest.cc
@@ -95,6 +95,7 @@ SetupBundleDataDir(&create_bundle.bundle_data(), "//out/Debug"); create_bundle.set_output_type(Target::CREATE_BUNDLE); create_bundle.private_deps().push_back(LabelTargetPair(&bundle_data)); + create_bundle.bundle_data().product_type().assign("com.apple.product-type"); create_bundle.SetToolchain(setup.toolchain()); ASSERT_TRUE(create_bundle.OnResolved(&err)); @@ -105,6 +106,7 @@ const char expected[] = "build bar.bundle/Contents/Resources/Assets.car: compile_xcassets " "../../foo/Foo.xcassets | obj/foo/data.stamp\n" + " product_type = com.apple.product-type\n" "build obj/baz/bar.stamp: stamp " "bar.bundle/Contents/Resources/Assets.car\n" "build bar.bundle: phony obj/baz/bar.stamp\n"; @@ -210,6 +212,7 @@ create_bundle.private_deps().push_back(LabelTargetPair(&bundle_data1)); create_bundle.private_deps().push_back(LabelTargetPair(&bundle_data2)); create_bundle.private_deps().push_back(LabelTargetPair(&bundle_data3)); + create_bundle.bundle_data().product_type().assign("com.apple.product-type"); create_bundle.SetToolchain(setup.toolchain()); ASSERT_TRUE(create_bundle.OnResolved(&err)); @@ -230,6 +233,7 @@ "build bar.bundle/Contents/Resources/Assets.car: compile_xcassets " "../../foo/Foo.xcassets " "../../quz/Quz.xcassets | obj/baz/bar.xcassets.inputdeps.stamp\n" + " product_type = com.apple.product-type\n" "build obj/baz/bar.stamp: stamp " "bar.bundle/Contents/Info.plist " "bar.bundle/Contents/Resources/input1.txt "
diff --git a/tools/gn/ninja_toolchain_writer.cc b/tools/gn/ninja_toolchain_writer.cc index 27e2e0c..a48a8b9 100644 --- a/tools/gn/ninja_toolchain_writer.cc +++ b/tools/gn/ninja_toolchain_writer.cc
@@ -110,12 +110,6 @@ std::string pool_name = tool->pool().ptr->GetNinjaName(settings_->default_toolchain_label()); out_ << kIndent << "pool = " << pool_name << std::endl; - } else if (type == Toolchain::TYPE_SOLINK || - type == Toolchain::TYPE_SOLINK_MODULE || - type == Toolchain::TYPE_LINK) { - // The link pool applies to linker tools. Don't count TYPE_ALINK since - // static libraries are not generally intensive to write. - out_ << kIndent << "pool = link_pool\n"; } if (tool->restat())
diff --git a/tools/gn/substitution_type.cc b/tools/gn/substitution_type.cc index fcca19da..7730070 100644 --- a/tools/gn/substitution_type.cc +++ b/tools/gn/substitution_type.cc
@@ -53,6 +53,7 @@ "{{bundle_resources_dir}}", // SUBSTITUTION_BUNDLE_RESOURCES_DIR "{{bundle_executable_dir}}", // SUBSTITUTION_BUNDLE_EXECUTABLE_DIR "{{bundle_plugins_dir}}", // SUBSTITUTION_BUNDLE_PLUGINS_DIR + "{{bundle_product_type}}", // SUBSTITUTION_BUNDLE_PRODUCT_TYPE "{{response_file_name}}", // SUBSTITUTION_RSP_FILE_NAME }; @@ -104,6 +105,7 @@ "bundle_resources_dir", // SUBSTITUTION_BUNDLE_RESOURCES_DIR "bundle_executable_dir", // SUBSTITUTION_BUNDLE_EXECUTABLE_DIR "bundle_plugins_dir", // SUBSTITUTION_BUNDLE_PLUGINS_DIR + "product_type", // SUBSTITUTION_BUNDLE_PRODUCT_TYPE "rspfile", // SUBSTITUTION_RSP_FILE_NAME }; @@ -227,7 +229,8 @@ bool IsValidCompileXCassetsSubstitution(SubstitutionType type) { return IsValidToolSubstitution(type) || - type == SUBSTITUTION_LINKER_INPUTS; + type == SUBSTITUTION_LINKER_INPUTS || + type == SUBSTITUTION_BUNDLE_PRODUCT_TYPE; } bool EnsureValidSourcesSubstitutions(
diff --git a/tools/gn/substitution_type.h b/tools/gn/substitution_type.h index e82ecd6..84524fb 100644 --- a/tools/gn/substitution_type.h +++ b/tools/gn/substitution_type.h
@@ -69,6 +69,9 @@ SUBSTITUTION_BUNDLE_EXECUTABLE_DIR, // {{bundle_executable_dir}} SUBSTITUTION_BUNDLE_PLUGINS_DIR, // {{bundle_plugins_dir}} + // Valid for compile_xcassets tool. + SUBSTITUTION_BUNDLE_PRODUCT_TYPE, // {{bundle_product_type}} + // Used only for the args of actions. SUBSTITUTION_RSP_FILE_NAME, // {{response_file_name}}
diff --git a/tools/grit/grit/format/repack.py b/tools/grit/grit/format/repack.py index 337b7af..c4a593a 100755 --- a/tools/grit/grit/format/repack.py +++ b/tools/grit/grit/format/repack.py
@@ -14,7 +14,9 @@ import sys if __name__ == '__main__': - sys.path.append(os.path.join(os.path.dirname(__file__), '../..')) + # Prepend the grit module from the source tree so it takes precedence over + # other grit versions that might present in the search path. + sys.path.insert(1, os.path.join(os.path.dirname(__file__), '../..')) import grit.format.data_pack
diff --git a/tools/mb/mb.py b/tools/mb/mb.py index ff75f84..e54763c0 100755 --- a/tools/mb/mb.py +++ b/tools/mb/mb.py
@@ -1011,12 +1011,23 @@ extra_files = [] if android and test_type != "script": - cmdline = [ - self.PathJoin('bin', 'run_%s' % target_name), - '--logcat-output-dir', '${ISOLATED_OUTDIR}/logcats', - '--target-devices-file', '${SWARMING_BOT_FILE}', - '-v', + logdog_command = [ + '--logdog-bin-cmd', './../../bin/logdog_butler', + '--project', 'chromium', + '--service-account-json', + '/creds/service_accounts/service-account-luci-logdog-publisher.json', + '--prefix', 'android/swarming/logcats/${SWARMING_TASK_ID}', + '--source', '${ISOLATED_OUTDIR}/logcats', + '--name', 'unified_logcats', ] + test_cmdline = [ + self.PathJoin('bin', 'run_%s' % target_name), + '--logcat-output-file', '${ISOLATED_OUTDIR}/logcats', + '--target-devices-file', '${SWARMING_BOT_FILE}', + '-v' + ] + cmdline = (['./../../build/android/test_wrapper/logdog_wrapper.py'] + + logdog_command + test_cmdline) elif use_x11 and test_type == 'windowed_test_launcher': extra_files = [ 'xdisplaycheck',
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index be49f69..ce45c9be 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -4155,11 +4155,13 @@ <action name="FrameLoad" not_user_triggered="true"> <owner>thestig@chromium.org</owner> <description>Count of successful frame loads to new pages.</description> + <obsolete>No longer tracked.</obsolete> </action> <action name="FrameLoadWithFlash" not_user_triggered="true"> <owner>thestig@chromium.org</owner> <description>Count of frame loads that also load PPAPI Flash.</description> + <obsolete>No longer tracked.</obsolete> </action> <action name="Gesture_Overview"> @@ -9277,6 +9279,14 @@ <description>Please enter the description of this user action.</description> </action> +<action name="MobileNTPSwitchToDownloadManager"> + <owner>bauerb@chromium.org</owner> + <description> + Android: User clicked on the "More" card at the end of the section + of Downloads suggestions on the NTP to open the Download Manager UI. + </description> +</action> + <action name="MobileNTPSwitchToIncognito"> <owner>Please list the metric's owners. Add more owner tags as needed.</owner> <description>Please enter the description of this user action.</description> @@ -9843,12 +9853,12 @@ </action> <action name="NavEntryCommitted" not_user_triggered="true"> - <owner>Please list the metric's owners. Add more owner tags as needed.</owner> + <owner>mpearson@chromium.org</owner> <description>Please enter the description of this user action.</description> </action> <action name="NavEntryCommitted.SRP" not_user_triggered="true"> - <owner>Please list the metric's owners. Add more owner tags as needed.</owner> + <owner>mpearson@chromium.org</owner> <description>Please enter the description of this user action.</description> </action> @@ -13440,6 +13450,11 @@ <description>Please enter the description of this user action.</description> </action> +<action name="ShowPaletteOptions"> + <owner>jdufault@chromium.org</owner> + <description>Triggered when the palette options are opened.</description> +</action> + <action name="ShowRecentlyViewed"> <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/find_unmapped_histograms.py b/tools/metrics/histograms/find_unmapped_histograms.py index 25f0cb2..e25f52ae 100644 --- a/tools/metrics/histograms/find_unmapped_histograms.py +++ b/tools/metrics/histograms/find_unmapped_histograms.py
@@ -24,6 +24,21 @@ import extract_histograms +CPP_COMMENT = re.compile(r""" + \s* # Optional whitespace + (?: # Non-capturing group + //.* # C++-style comment + \n # Newline + | # or + /\* # Start C-style comment + (?: # Non-capturing group + (?!\*/) # Negative lookahead for comment end + [\s\S] # Any character including newline + )* # Repeated zero or more times + \*/ # End C-style comment + ) # End group + \s* # Optional whitespace + """, re.VERBOSE); ADJACENT_C_STRING_REGEX = re.compile(r""" (" # Opening quotation mark [^"]*) # Literal string contents @@ -32,11 +47,23 @@ " # Another opening quotation mark """, re.VERBOSE) CONSTANT_REGEX = re.compile(r""" - (\w*::)? # Optional namespace + (\w*::)* # Optional namespace(s) k[A-Z] # Match a constant identifier: 'k' followed by an uppercase letter \w* # Match the rest of the constant identifier $ # Make sure there's only the identifier, nothing else """, re.VERBOSE) +MACRO_STRING_CONCATENATION_REGEX = re.compile(r""" + \s* # Optional whitespace + ( # Group + ( # Nested group + "[^"]*" # Literal string + | # or + [a-zA-Z][a-zA-Z0-9_]+ # Macro constant name + ) # End of alternation + \s* # Optional whitespace + ){2,} # Group repeated 2 or more times + $ # End of string + """, re.VERBOSE) HISTOGRAM_REGEX = re.compile(r""" UMA_HISTOGRAM # Match the shared prefix for standard UMA histogram macros \w* # Match the rest of the macro name, e.g. '_ENUMERATION' @@ -67,6 +94,21 @@ return self.msg +def removeComments(string): + """Remove any comments from an expression, including leading and trailing + whitespace. This does not correctly ignore comments embedded in strings, + but that shouldn't matter for this script. + + Args: + string: The string to remove comments from, e.g. + ' // My histogram\n "My.Important.Counts" ' + + Returns: + The string with comments removed, e.g. '"My.Important.Counts" ' + """ + return CPP_COMMENT.sub('', string) + + def collapseAdjacentCStrings(string): """Collapses any adjacent C strings into a single string. @@ -111,6 +153,14 @@ if CONSTANT_REGEX.match(histogram): return + # A blank value wouldn't compile unless it was in a comment. + if histogram == '': + return + + # String concatenations involving macros are always constant. + if MACRO_STRING_CONCATENATION_REGEX.match(histogram): + return + # TODO(isherman): This is still a little noisy... needs further filtering to # reduce the noise. logging.warning('%s contains non-literal histogram name <%s>', filename, @@ -146,6 +196,7 @@ for match in HISTOGRAM_REGEX.finditer(contents): histogram = collapseAdjacentCStrings(match.group(1)) + histogram = removeComments(histogram) # Must begin and end with a quotation mark. if not histogram or histogram[0] != '"' or histogram[-1] != '"':
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 4334e50..87938098 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -4191,6 +4191,92 @@ </summary> </histogram> +<histogram name="Bluetooth.Web.Android.onCharacteristicRead.Status" + enum="AndroidGATTStatusResult"> + <owner>jyasskin@chromium.org</owner> + <owner>ortuno@chromium.org</owner> + <owner>scheib@chromium.org</owner> + <summary>onCharacteristicRead 'status' values.</summary> +</histogram> + +<histogram name="Bluetooth.Web.Android.onCharacteristicWrite.Status" + enum="AndroidGATTStatusResult"> + <owner>jyasskin@chromium.org</owner> + <owner>ortuno@chromium.org</owner> + <owner>scheib@chromium.org</owner> + <summary>onCharacteristicWrite 'status' values..</summary> +</histogram> + +<histogram + name="Bluetooth.Web.Android.onConnectionStateChange.Status.Connected" + enum="AndroidGATTStatusResult"> + <owner>jyasskin@chromium.org</owner> + <owner>ortuno@chromium.org</owner> + <owner>scheib@chromium.org</owner> + <summary> + onConnectionStateChange 'status' values received in the connected state. + </summary> +</histogram> + +<histogram + name="Bluetooth.Web.Android.onConnectionStateChange.Status.Disconnected" + enum="AndroidGATTStatusResult"> + <owner>jyasskin@chromium.org</owner> + <owner>ortuno@chromium.org</owner> + <owner>scheib@chromium.org</owner> + <summary> + onConnectionStateChange 'status' values received in the disconnected state. + </summary> +</histogram> + +<histogram + name="Bluetooth.Web.Android.onConnectionStateChange.Status.InvalidState" + enum="AndroidGATTStatusResult"> + <owner>jyasskin@chromium.org</owner> + <owner>ortuno@chromium.org</owner> + <owner>scheib@chromium.org</owner> + <summary> + onConnectionStateChange 'status' values received in an unhandled 'state'. + </summary> +</histogram> + +<histogram name="Bluetooth.Web.Android.onDescriptorRead.Status" + enum="AndroidGATTStatusResult"> + <owner>jyasskin@chromium.org</owner> + <owner>ortuno@chromium.org</owner> + <owner>scheib@chromium.org</owner> + <summary>onDescriptorRead 'status' values.</summary> +</histogram> + +<histogram name="Bluetooth.Web.Android.onDescriptorWrite.Status" + enum="AndroidGATTStatusResult"> + <owner>jyasskin@chromium.org</owner> + <owner>ortuno@chromium.org</owner> + <owner>scheib@chromium.org</owner> + <summary>onDescriptorWrite 'status' values..</summary> +</histogram> + +<histogram name="Bluetooth.Web.Android.onServicesDiscovered.Status.Connected" + enum="AndroidGATTStatusResult"> + <owner>jyasskin@chromium.org</owner> + <owner>ortuno@chromium.org</owner> + <owner>scheib@chromium.org</owner> + <summary> + onServicesDiscovered 'status' values received in the connected state. + </summary> +</histogram> + +<histogram + name="Bluetooth.Web.Android.onServicesDiscovered.Status.Disconnected" + enum="AndroidGATTStatusResult"> + <owner>jyasskin@chromium.org</owner> + <owner>ortuno@chromium.org</owner> + <owner>scheib@chromium.org</owner> + <summary> + onServicesDiscovered 'status' values received in the disconnected state. + </summary> +</histogram> + <histogram name="Bluetooth.Web.Blacklist.ParsedNonEmptyString" enum="BooleanSuccess"> <owner>jyasskin@chromium.org</owner> @@ -6604,6 +6690,14 @@ </summary> </histogram> +<histogram name="ContentSettings.ExceptionScheme" enum="ContentSettingScheme"> + <owner>lshang@chromium.org</owner> + <summary> + Records the schemes of content setting exceptions at browser start. Each + exception provides one sample. + </summary> +</histogram> + <histogram name="ContentSettings.LastSettingParsed" enum="LastSettingParsed"> <obsolete> Deprecated 2015-10-05 in Issue 433475. Histogram was used temorarily for @@ -9176,6 +9270,11 @@ </summary> </histogram> +<histogram name="DirectWrite.Fonts.Proxy.CreateFontFaceResult" units="HRESULT"> + <owner>kulshin@chromium.org</owner> + <summary>Records the error returned from CreateFontFace.</summary> +</histogram> + <histogram name="DirectWrite.Fonts.Proxy.Fallback.CacheSize" units="Count"> <owner>kulshin@chromium.org</owner> <summary>Records how many font families are in the fallback cache.</summary> @@ -9206,6 +9305,12 @@ </summary> </histogram> +<histogram name="DirectWrite.Fonts.Proxy.GetSystemFontCollectionResult" + units="HRESULT"> + <owner>kulshin@chromium.org</owner> + <summary>Records the error returned from GetSystemFontCollection.</summary> +</histogram> + <histogram name="DirectWrite.Fonts.Proxy.LastResortFontCount" units="fonts"> <owner>kulshin@chromium.org</owner> <summary> @@ -20484,6 +20589,13 @@ </summary> </histogram> +<histogram name="LevelDBEnv.DeleteTableBackupFile" enum="BooleanSuccess"> + <owner>cmumford@chromium.org</owner> + <summary> + Tracks the success rate of deleting an unused leveldb table backup file. + </summary> +</histogram> + <histogram name="LevelDBEnv.IDB.IOError" enum="LevelDBIOErrorMethods"> <owner>dgrogan@chromium.org</owner> <summary> @@ -20589,6 +20701,9 @@ <histogram name="LevelDBEnv.IDB.Table" enum="BooleanSuccess"> <owner>dgrogan@chromium.org</owner> + <obsolete> + As of M54 no longer creating or using table backup files. + </obsolete> <summary> Success indicates a successful backup or restore operation for .ldb table files when used in IndexedDB. @@ -20766,6 +20881,9 @@ <histogram name="LevelDBEnv.ServiceWorker.Table" enum="BooleanSuccess"> <owner>nhiroki@chromium.org</owner> + <obsolete> + As of M54 no longer creating or using table backup files. + </obsolete> <summary> Success indicates a successful backup or restore operation for .ldb table files when used in ServiceWorker. @@ -20782,6 +20900,9 @@ <histogram name="LevelDBEnv.Table" enum="BooleanSuccess"> <owner>dgrogan@chromium.org</owner> + <obsolete> + As of M54 no longer creating or using table backup files. + </obsolete> <summary> Success indicates a successful backup or restore operation for .ldb table files when used by LevelDB clients other than IndexedDB. @@ -26736,6 +26857,47 @@ </summary> </histogram> +<histogram name="Net.BidirectionalStream.ReceivedBytes" units="bytes"> + <owner>xunjieli@chromium.org</owner> + <summary>Number of bytes received over this stream.</summary> +</histogram> + +<histogram name="Net.BidirectionalStream.SentBytes" units="bytes"> + <owner>xunjieli@chromium.org</owner> + <summary>Number of bytes sent over this stream.</summary> +</histogram> + +<histogram name="Net.BidirectionalStream.TimeToReadEnd" units="ms"> + <owner>xunjieli@chromium.org</owner> + <summary> + How long it takes from starting the request to reading the end of the + response. + </summary> +</histogram> + +<histogram name="Net.BidirectionalStream.TimeToReadStart" units="ms"> + <owner>xunjieli@chromium.org</owner> + <summary> + How long it takes from starting the request to reading the start of the + response. + </summary> +</histogram> + +<histogram name="Net.BidirectionalStream.TimeToSendEnd" units="ms"> + <owner>xunjieli@chromium.org</owner> + <summary> + How long it takes from starting the request to when the last byte is sent. + </summary> +</histogram> + +<histogram name="Net.BidirectionalStream.TimeToSendStart" units="ms"> + <owner>xunjieli@chromium.org</owner> + <summary> + How long it takes from starting the request to when we can start sending + data. + </summary> +</histogram> + <histogram name="Net.CacheState.AllBytes"> <owner>ellyjones@chromium.org</owner> <owner>rdsmith@chromium.org</owner> @@ -27351,6 +27513,21 @@ </summary> </histogram> +<histogram name="Net.Cronet.CertVerifierCache.DeserializeTime" units="ms"> + <owner>rch@chromium.org</owner> + <summary> + Measures time spent to deserialize and populate the + net::CachingCertVerifier's cache. + </summary> +</histogram> + +<histogram name="Net.Cronet.CertVerifierCache.SerializeTime" units="ms"> + <owner>rch@chromium.org</owner> + <summary> + Measures time spent to serialize the net::CachingCertVerifier's cache. + </summary> +</histogram> + <histogram name="Net.DailyContentLength" units="KB"> <owner>bolian@chromium.org</owner> <summary> @@ -28811,6 +28988,9 @@ <histogram name="Net.HttpStreamFactoryJob.StreamReadyCallbackTime" units="ms"> <owner>rtenneti@chromium.org</owner> + <obsolete> + Deprecated 08/2016. No longer tracked. + </obsolete> <summary>Time it takes for OnStreamReadyCallback to be called.</summary> </histogram> @@ -30114,6 +30294,15 @@ </summary> </histogram> +<histogram name="Net.QuicSession.CertVerifierJob.CompleteTime" + units="Milliseconds"> + <owner>rtenneti@chromium.org</owner> + <summary> + Time spent verifying a certificate when racing cert veriifcation with host + resolution. + </summary> +</histogram> + <histogram name="Net.QuicSession.ClientSideMtu" units="bytes"> <owner>rch@chromium.org</owner> <summary> @@ -30405,6 +30594,13 @@ </summary> </histogram> +<histogram name="Net.QuicSession.MinRTT" units="ms"> + <owner>rch@chromium.org</owner> + <summary> + The minimum RTT observed during the life of a QUIC connection. + </summary> +</histogram> + <histogram name="Net.QuicSession.MtuProbesSent"> <owner>rch@chromium.org</owner> <summary> @@ -30603,6 +30799,13 @@ </summary> </histogram> +<histogram name="Net.QuicSession.SmoothedRTT" units="ms"> + <owner>rch@chromium.org</owner> + <summary> + The final smoothed RTT observed during the life of a QUIC connection. + </summary> +</histogram> + <histogram name="Net.QuicSession.StreamCloseErrorCodeClient.HandshakeConfirmed" enum="QuicErrorCodes"> <owner>rch@chromium.org</owner> @@ -31704,6 +31907,17 @@ </summary> </histogram> +<histogram + name="Net.SSL_Connection_Latency_PostQuantumSupported_Full_Handshake" + units="ms"> + <owner>mab@chromium.org</owner> + <summary> + Time from when the Connect() starts until it completes (full handshakes + only), for a set of domains that we expect to always offer the experimental + post-quantum (CECPQ1) ciphersuites. + </summary> +</histogram> + <histogram name="Net.SSL_Connection_Latency_Resume_Handshake" units="ms"> <owner>agl@chromium.org</owner> <summary> @@ -31712,6 +31926,16 @@ </summary> </histogram> +<histogram name="Net.SSL_Connection_PostQuantum_Negotiated" + enum="BooleanSupported"> + <owner>mab@chromium.org</owner> + <summary> + For only browsers in the post-quantum (CECPQ1) ciphersuite experiment, + counts the full TLS handshakes where CECPQ1 was, or was not, negotiated on + hosts where we expect it to be negotiated. + </summary> +</histogram> + <histogram name="Net.SSL_EVCertificateCTCompliance" enum="CTRequirementCompliance"> <obsolete> @@ -31935,6 +32159,7 @@ </histogram> <histogram name="Net.SSLSignatureAlgorithm" enum="SSLSignatureAlgorithm"> + <owner>davidben@chromium.org</owner> <summary> For each SSL connection with a full handshake using a DHE- or ECDHE-based key exchange, the signature algorithm used to authenticate the peer. In TLS @@ -37092,6 +37317,9 @@ <histogram name="Omnibox.FocusToOpenTimeAnyPopupState" units="ms"> <owner>mpearson@chromium.org</owner> + <obsolete> + Replaced with Omnibox.FocusToOpenTimeAnyPopupState2 in August, 2016. + </obsolete> <summary> The length of time between when a user focused on the omnibox and opened an omnibox match (which could be what they typed or a suggestion). This is @@ -37099,6 +37327,20 @@ </summary> </histogram> +<histogram name="Omnibox.FocusToOpenTimeAnyPopupState2" units="ms"> + <owner>mpearson@chromium.org</owner> + <summary> + The length of time between when a user focused on the omnibox and opened an + omnibox match (which could be what they typed or a suggestion). This is + recorded regardless of whether the omnibox dropdown (a.k.a. popup) is open. + It is not recorded if a match is opened without triggering a focus event, + e.g., when a user drags a URL to the omnibox to navigate. + + To know how common this last condition is, compare the total count of this + histogram to the total number of omnibox events. + </summary> +</histogram> + <histogram name="Omnibox.HardwareKeyboardModeEnabled" enum="BooleanEnabled"> <owner>lpromero@chromium.org</owner> <summary> @@ -38116,6 +38358,68 @@ </summary> </histogram> +<histogram name="PageLoad.Experimental.PaintTiming.FirstMeaningfulPaintStatus" + enum="FirstMeaningfulPaintStatus"> + <owner>ksakamoto@chromium.org</owner> + <summary> + Records whether the First Meaningful Paint metric was reported for the page + load, or why it wasn't if not. See http://bit.ly/ttfmp-doc for the + definition of First Meaningful Paint. + </summary> +</histogram> + +<histogram + name="PageLoad.Experimental.PaintTiming.FirstMeaningfulPaintToNetworkStable" + units="ms"> + <owner>ksakamoto@chromium.org</owner> + <summary> + Measures the time between when the first meaningful paint + (http://bit.ly/ttfmp-doc) was computed to have happened, and when we + actually logged the metric. + + This metric is useful in helping us tweak when FirstMeaningfulPaintDetector + should stop observing layout operations. + </summary> +</histogram> + +<histogram + name="PageLoad.Experimental.PaintTiming.NavigationToFirstMeaningfulPaint" + units="ms"> + <owner>ksakamoto@chromium.org</owner> + <summary> + Measures the time from navigation timing's navigation start to the first + meaningful paint (http://bit.ly/ttfmp-doc), for main frame documents. + </summary> +</histogram> + +<histogram + name="PageLoad.Experimental.PaintTiming.ParseStartToFirstMeaningfulPaint" + units="ms"> + <owner>ksakamoto@chromium.org</owner> + <summary> + Measures the time from when the HTML parser started, to the first meaningful + paint (http://bit.ly/ttfmp-doc), for main frame documents. + </summary> +</histogram> + +<histogram name="PageLoad.Experimental.ParseDuration.CachePercent.0-50" + units="ms"> + <owner>csharrison@chromium.org</owner> + <summary> + The parse duration of the page load where 0-50% of all subresources (loaded + during parsing) were served from the HTTP cache (including 304s). + </summary> +</histogram> + +<histogram name="PageLoad.Experimental.ParseDuration.CachePercent.51-100" + units="ms"> + <owner>csharrison@chromium.org</owner> + <summary> + The parse duration of the page load where 51-100% of all subresources + (loaded during parsing) were served from the HTTP cache (including 304s). + </summary> +</histogram> + <histogram name="PageLoad.Experimental.TotalRequests.ParseStop" units="requests"> <owner>csharrison@chromium.org</owner> @@ -45663,6 +45967,17 @@ </summary> </histogram> +<histogram name="PushMessaging.ReceivedMessageInBackground" enum="Boolean"> + <owner>dgn@chromium.org</owner> + <summary> + Whenever a Service Worker receives a push message, this records whether + Chrome is completely running in the background. A successful report means + that the message was received when Chrome was in complete background mode, + without UI, while a failure means it was in some other state: in background + with some apps running, showing browser windows, etc. + </summary> +</histogram> + <histogram name="PushMessaging.RegistrationStatus" enum="PushRegistrationStatus"> <owner>johnme@google.com</owner> @@ -61079,6 +61394,16 @@ </summary> </histogram> +<histogram name="UMA.ExternalExperiment.GroupCount" units="groups"> + <owner>asvitkine@chromium.org</owner> + <summary> + Logged on Android whenever an external experiment is registered. The logged + value is the number of groups in the experiment. This will not be logged at + all if there are no external experiments, but will be logged on group + transitions (e.g. when going from 1 to 0 groups). + </summary> +</histogram> + <histogram name="UMA.FieldTrialsEnabledBenchmarking" enum="BooleanUsage"> <obsolete> Deprecated 2012. No longer tracked. @@ -67154,10 +67479,78 @@ <int value="64" label="0x40 Coarse Clock Adjustment Rejected but Will Try to Adjust Using Clock Dragging"/> + <int value="133" label="Application Error 0x85, Bluedroid GATT_ERROR"/> + <int value="135" label="Application Error 0x87, Bluedroid GATT_PENDING"/> <int value="256" label="0x100 Bluedroid L2CAP connection cancelled"/> <int value="257" label="0x101 Android GATT Failure"/> </enum> +<enum name="AndroidGATTStatusResult" type="int"> + <summary> + This list includes errors from the Bluetooth Specification Version 4.2 Vol + 3, Part F, Section 3.4.1.1 and Core Specification Supplement Part B. Also + Android's BluetoothGatt (0x101 GATT_FAILURE) and an error from Bluedroid's + gatt_api.h (0x100 L2CAP connection cancelled). + </summary> + <int value="0" label="GATT_SUCCESS"/> + <int value="1" label="Invalid Handle"/> + <int value="2" label="Read Not Permitted"/> + <int value="3" label="Write Not Permitted"/> + <int value="4" label="Invalid PDU"/> + <int value="5" label="Insufficient Authentication"/> + <int value="6" label="Request Not Supported"/> + <int value="7" label="Invalid Offset"/> + <int value="8" label="Insufficient Authorization"/> + <int value="9" label="Prepare Queue Full"/> + <int value="10" label="Attribute Not Found"/> + <int value="11" label="Attribute Not Long"/> + <int value="12" label="Insufficient Encryption Key Size"/> + <int value="13" label="Invalid Attribute Value Length"/> + <int value="14" label="Unlikely Error"/> + <int value="15" label="Insufficient Encryption"/> + <int value="16" label="Unsupported Group Type"/> + <int value="17" label="Insufficient Resources"/> + <int value="128" label="Application Error 0x80, 128"/> + <int value="129" label="Application Error 0x81, 129"/> + <int value="130" label="Application Error 0x82, 130"/> + <int value="131" label="Application Error 0x83, 131"/> + <int value="132" label="Application Error 0x84, 132"/> + <int value="133" label="Application Error 0x85, Bluedroid GATT_ERROR"/> + <int value="134" label="Application Error 0x86, 134"/> + <int value="135" label="Application Error 0x87, Bluedroid GATT_PENDING"/> + <int value="136" label="Application Error 0x88, 136"/> + <int value="137" label="Application Error 0x89, 137"/> + <int value="138" label="Application Error 0x8A, 138"/> + <int value="139" label="Application Error 0x8B, 139"/> + <int value="140" label="Application Error 0x8C, 140"/> + <int value="141" label="Application Error 0x8D, 141"/> + <int value="142" label="Application Error 0x8E, 142"/> + <int value="143" label="Application Error 0x8F, 143"/> + <int value="144" label="Application Error 0x90, 144"/> + <int value="145" label="Application Error 0x91, 145"/> + <int value="146" label="Application Error 0x92, 146"/> + <int value="147" label="Application Error 0x93, 147"/> + <int value="148" label="Application Error 0x94, 148"/> + <int value="149" label="Application Error 0x95, 149"/> + <int value="150" label="Application Error 0x96, 150"/> + <int value="151" label="Application Error 0x97, 151"/> + <int value="152" label="Application Error 0x98, 152"/> + <int value="153" label="Application Error 0x99, 153"/> + <int value="154" label="Application Error 0x9A, 154"/> + <int value="155" label="Application Error 0x9B, 155"/> + <int value="156" label="Application Error 0x9C, 156"/> + <int value="157" label="Application Error 0x9D, 157"/> + <int value="158" label="Application Error 0x9E, 158"/> + <int value="159" label="Application Error 0x9F, 159"/> + <int value="253" + label="Client Characteristic Configuration Descriptor Improperly + Configured (CSS)"/> + <int value="254" label="Procedure Already in Progress (CSS)"/> + <int value="255" label="Out of Range (CSS)"/> + <int value="256" label="0x100 Bluedroid L2CAP connection cancelled"/> + <int value="257" label="GATT_FAILURE"/> +</enum> + <enum name="AndroidKernelVersion" type="int"> <int value="131078" label="2.6"/> <int value="196608" label="3.0"/> @@ -71028,6 +71421,15 @@ <int value="3" label="Clicked 'Learn more'"/> </enum> +<enum name="ContentSettingScheme" type="int"> + <int value="0" label="(wildcard)"/> + <int value="1" label="(other)"/> + <int value="2" label="http"/> + <int value="3" label="https"/> + <int value="4" label="file"/> + <int value="5" label="chrome-extension"/> +</enum> + <enum name="ContentType" type="int"> <int value="-1" label="Invalid setting"/> <int value="0" label="Cookies setting"/> @@ -74274,6 +74676,7 @@ <int value="337" label="Enable Android Backup Service"/> <int value="338" label="Enable generated content suggestions on the New Tab page"/> + <int value="339" label="Restrict the UDP port range used by WebRTC"/> </enum> <enum name="EnterprisePolicyInvalidations" type="int"> @@ -78379,6 +78782,7 @@ <int value="1498" label="ChromeLoadTimesConnectionInfo"/> <int value="1499" label="ChromeLoadTimesUnknown"/> <int value="1500" label="SVGViewElement"/> + <int value="1501" label="WebShareShare"/> </enum> <enum name="FetchRequestMode" type="int"> @@ -79252,6 +79656,13 @@ <int value="20" label=".log"/> </enum> +<enum name="FirstMeaningfulPaintStatus" type="int"> + <int value="0" label="Recorded successfully"/> + <int value="1" label="The page was backgrounded"/> + <int value="2" label="User left the page before network stable"/> + <int value="3" label="Not recorded because of user interaction"/> +</enum> + <enum name="FlashNavigateUsageType" type="int"> <int value="0" label="Rejected because of Authorization header."/> <int value="1" label="Rejected because of Cache-Control header."/> @@ -83264,6 +83675,7 @@ <int value="-314910380" label="disable-distance-field-text"/> <int value="-311148335" label="v8-pac-mojo-out-of-process"/> <int value="-300018686" label="disable-cloud-import"/> + <int value="-290672626" label="enable-asm-wasm"/> <int value="-288316828" label="enable-delegated-renderer"/> <int value="-278347667" label="default-tile-height"/> <int value="-277144896" label="enable-viewport-meta"/> @@ -90354,6 +90766,7 @@ <int value="8" label="RICE_DECODING_FAILURE"/> <int value="9" label="UNEXPECTED_COMPRESSION_TYPE_ADDITIONS_FAILURE"/> <int value="10" label="UNEXPECTED_COMPRESSION_TYPE_REMOVALS_FAILURE"/> + <int value="11" label="CHECKSUM_MISMATCH_FAILURE"/> </enum> <enum name="SafeBrowsingV4DecodeResult" type="int"> @@ -98458,6 +98871,9 @@ </histogram_suffixes> <histogram_suffixes name="LevelDBEnvBackupRestore" separator=""> + <obsolete> + Deprecated 08/2016. + </obsolete> <suffix name="Backup" label="Backing up an ldb file."/> <suffix name="Restore" label="Restoring an ldb file."/> <affected-histogram name="LevelDBEnv.IDB.Table"/> @@ -98761,6 +99177,19 @@ <affected-histogram name="Navigation.TimeToURLJobStart"/> </histogram_suffixes> +<histogram_suffixes name="Net.BidirectionalStreamExperiment" separator="." + ordering="prefix"> + <owner>xunjieli@chromium.org</owner> + <suffix name="QUIC" label="Bidirectional streams that use QUIC protocol"/> + <suffix name="HTTP2" label="Bidirectional stream that use HTTP2 protocol"/> + <affected-histogram name="Net.BidirectionalStream.ReceivedBytes"/> + <affected-histogram name="Net.BidirectionalStream.SentBytes"/> + <affected-histogram name="Net.BidirectionalStream.TimeToReadEnd"/> + <affected-histogram name="Net.BidirectionalStream.TimeToReadStart"/> + <affected-histogram name="Net.BidirectionalStream.TimeToSendEnd"/> + <affected-histogram name="Net.BidirectionalStream.TimeToSendStart"/> +</histogram_suffixes> + <histogram_suffixes name="Net.QuicClientHelloRejectReasons.QuicIsSecureOrNot" separator="."> <owner>rtenneti@chromium.org</owner> @@ -102711,6 +103140,8 @@ </histogram_suffixes> <histogram_suffixes name="VideoEncodedQpStats" separator="."> + <suffix name="H264" + label="Video codec: H264. QP range: 0-51. No spatial layers."/> <suffix name="Vp8" label="Video codec: VP8. QP range: 0-127. Single stream sent."/> <suffix name="Vp8.S0"
diff --git a/tools/perf/benchmarks/benchmark_smoke_unittest.py b/tools/perf/benchmarks/benchmark_smoke_unittest.py index 29650aa..51291c7 100644 --- a/tools/perf/benchmarks/benchmark_smoke_unittest.py +++ b/tools/perf/benchmarks/benchmark_smoke_unittest.py
@@ -98,6 +98,14 @@ } +def MergeDecorators(method, method_attribute, benchmark, benchmark_attribute): + # Do set union of attributes to eliminate duplicates. + merged_attributes = getattr(method, method_attribute, set()).union( + getattr(benchmark, benchmark_attribute, set())) + if merged_attributes: + setattr(method, method_attribute, merged_attributes) + + def load_tests(loader, standard_tests, pattern): del loader, standard_tests, pattern # unused suite = progress_reporter.TestSuite() @@ -147,16 +155,11 @@ disabled_method_attr = decorators.DisabledAttributeName(method) enabled_benchmark_attr = decorators.EnabledAttributeName(benchmark) enabled_method_attr = decorators.EnabledAttributeName(method) - # Merge decorators. - def MergeDecorators(method_attribute, benchmark_attribute): - # Do set union of attributes to eliminate duplicates. - merged_attributes = getattr(method, method_attribute, set()).union( - getattr(benchmark, benchmark_attribute, set())) - if merged_attributes: - setattr(method, method_attribute, merged_attributes) - MergeDecorators(disabled_method_attr, disabled_benchmark_attr) - MergeDecorators(enabled_method_attr, enabled_benchmark_attr) + MergeDecorators(method, disabled_method_attr, benchmark, + disabled_benchmark_attr) + MergeDecorators(method, enabled_method_attr, benchmark, + enabled_benchmark_attr) setattr(BenchmarkSmokeTest, benchmark.Name(), method)
diff --git a/tools/perf/benchmarks/page_cycler.py b/tools/perf/benchmarks/page_cycler.py deleted file mode 100644 index 115fea1f..0000000 --- a/tools/perf/benchmarks/page_cycler.py +++ /dev/null
@@ -1,159 +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 core import perf_benchmark - -from measurements import page_cycler -import page_sets - - -class _PageCycler(perf_benchmark.PerfBenchmark): - options = {'pageset_repeat': 6} - cold_load_percent = 50 # % of page visits for which a cold load is forced - - @classmethod - def Name(cls): - return 'page_cycler' - - @classmethod - def AddBenchmarkCommandLineArgs(cls, parser): - parser.add_option('--report-speed-index', - action='store_true', - help='Enable the speed index metric.') - - @classmethod - def ValueCanBeAddedPredicate(cls, _, is_first_result): - return cls.cold_load_percent > 0 or not is_first_result - - def CreatePageTest(self, options): - return page_cycler.PageCycler( - page_repeat=options.page_repeat, - pageset_repeat=options.pageset_repeat, - cold_load_percent=self.cold_load_percent, - report_speed_index=options.report_speed_index) - - @classmethod - def ShouldDisable(cls, possible_browser): - # Superseded by page_cycler_v2.py on all other platforms (crbug.com/611329). - return possible_browser.platform.GetOSName() != 'chromeos' - - -class PageCyclerIntlArFaHe(_PageCycler): - """Page load time for a variety of pages in Arabic, Farsi and Hebrew. - - Runs against pages recorded in April, 2013. - """ - page_set = page_sets.IntlArFaHePageSet - - @classmethod - def Name(cls): - return 'page_cycler.intl_ar_fa_he' - - -class PageCyclerIntlEsFrPtBr(_PageCycler): - """Page load time for a pages in Spanish, French and Brazilian Portuguese. - - Runs against pages recorded in April, 2013. - """ - page_set = page_sets.IntlEsFrPtBrPageSet - - @classmethod - def Name(cls): - return 'page_cycler.intl_es_fr_pt-BR' - - -class PageCyclerIntlHiRu(_PageCycler): - """Page load time benchmark for a variety of pages in Hindi and Russian. - - Runs against pages recorded in April, 2013. - """ - page_set = page_sets.IntlHiRuPageSet - - @classmethod - def Name(cls): - return 'page_cycler.intl_hi_ru' - - -class PageCyclerIntlJaZh(_PageCycler): - """Page load time benchmark for a variety of pages in Japanese and Chinese. - - Runs against pages recorded in April, 2013. - """ - page_set = page_sets.IntlJaZhPageSet - - @classmethod - def Name(cls): - return 'page_cycler.intl_ja_zh' - - @classmethod - def ValueCanBeAddedPredicate(cls, value, is_first_result): - # Filter out vm_private_dirty_final_renderer - # crbug.com/551522 - print '**** %s ***' % value.name - filtered_name = ( - 'vm_private_dirty_final_renderer.vm_private_dirty_final_renderer') - return (super(PageCyclerIntlJaZh, cls).ValueCanBeAddedPredicate( - value, is_first_result) and value.name != filtered_name) - - -class PageCyclerIntlKoThVi(_PageCycler): - """Page load time for a variety of pages in Korean, Thai and Vietnamese. - - Runs against pages recorded in April, 2013. - """ - page_set = page_sets.IntlKoThViPageSet - - @classmethod - def Name(cls): - return 'page_cycler.intl_ko_th_vi' - - -class PageCyclerToughLayoutCases(_PageCycler): - """Page loading for the slowest layouts observed in the Alexa top 1 million. - - Recorded in July 2013. - """ - page_set = page_sets.ToughLayoutCasesPageSet - - @classmethod - def Name(cls): - return 'page_cycler.tough_layout_cases' - - -class PageCyclerTypical25(_PageCycler): - """Page load time benchmark for a 25 typical web pages. - - Designed to represent typical, not highly optimized or highly popular web - sites. Runs against pages recorded in June, 2014. - """ - options = {'pageset_repeat': 3} - - @classmethod - def Name(cls): - return 'page_cycler.typical_25' - - def CreateStorySet(self, options): - return page_sets.Typical25PageSet(run_no_page_interactions=True) - - -class PageCyclerBasicOopifIsolated(_PageCycler): - """ A benchmark measuring performance of out-of-process iframes. """ - page_set = page_sets.OopifBasicPageSet - - @classmethod - def Name(cls): - return 'page_cycler_site_isolation.basic_oopif' - - def SetExtraBrowserOptions(self, options): - options.AppendExtraBrowserArgs(['--site-per-process']) - - -class PageCyclerBasicOopif(_PageCycler): - """ A benchmark measuring performance of the out-of-process iframes page - set, without running in out-of-process iframes mode.. """ - page_set = page_sets.OopifBasicPageSet - - @classmethod - def Name(cls): - return 'page_cycler.basic_oopif'
diff --git a/tools/perf/benchmarks/system_health_smoke_test.py b/tools/perf/benchmarks/system_health_smoke_test.py index ccc7deda..d08f971f 100644 --- a/tools/perf/benchmarks/system_health_smoke_test.py +++ b/tools/perf/benchmarks/system_health_smoke_test.py
@@ -35,6 +35,8 @@ # crbug.com/629123 'benchmarks.system_health_smoke_test.SystemHealthBenchmarkSmokeTest.system_health.memory_mobile.browse:news:hackernews', # pylint: disable=line-too-long 'benchmarks.system_health_smoke_test.SystemHealthBenchmarkSmokeTest.system_health.memory_mobile.browse:news:nytimes', # pylint: disable=line-too-long + # crbug.com/637230 + 'benchmarks.system_health_smoke_test.SystemHealthBenchmarkSmokeTest.system_health.memory_desktop.browse:news:cnn', # pylint: disable=line-too-long })
diff --git a/tools/perf/benchmarks/v8.py b/tools/perf/benchmarks/v8.py index 3a68a6b8..9cb3b44 100644 --- a/tools/perf/benchmarks/v8.py +++ b/tools/perf/benchmarks/v8.py
@@ -239,8 +239,7 @@ return not cls._IGNORED_V8_STATS_RE.search(value.name) -@benchmark.Disabled('reference', - 'mac') # crbug.com/630854 +@benchmark.Enabled('android') class V8MobileCodeSizeIgnition(_V8MemoryAndCodeSizeBenchmark): """Measures V8 heap and code size with ignition enabled on mobile web pages. @@ -256,8 +255,7 @@ return 'top_10_mobile_memory_ignition' -@benchmark.Disabled('reference', - 'mac') # crbug.com/630854 +@benchmark.Enabled('android') class V8MobileCodeSize(_V8MemoryAndCodeSizeBenchmark): """Measures V8 heap and code size on mobile web pages.
diff --git a/tools/perf/core/benchmark_finders_unittest.py b/tools/perf/core/benchmark_finders_unittest.py index b925612..3043d7f 100644 --- a/tools/perf/core/benchmark_finders_unittest.py +++ b/tools/perf/core/benchmark_finders_unittest.py
@@ -23,7 +23,7 @@ ['test_benchmark_1', 'test_benchmark_2', 'test_benchmark_subclass_1', 'test_benchmark_subclass_2']) - def testListSimpleBenchmarksDefinedInOneFile(self): + def testListSimpleBenchmarksDefinedInOneFileComplex(self): self.assertEquals( benchmark_finders.GetBenchmarkNamesForFile( self.top_level_dir,
diff --git a/tools/perf/core/minidump_unittest.py b/tools/perf/core/minidump_unittest.py index 4caf97f..bc9255d1 100644 --- a/tools/perf/core/minidump_unittest.py +++ b/tools/perf/core/minidump_unittest.py
@@ -23,10 +23,12 @@ logging.info('testSymbolizeMinidump: most recent path = ' + crash_minidump_path) all_paths = self._browser.GetAllMinidumpPaths() - logging.info('testSymbolizeMinidump: all paths ' + ''.join(all_paths)) + if all_paths is not None: + logging.info('testSymbolizeMinidump: all paths ' + ''.join(all_paths)) all_unsymbolized_paths = self._browser.GetAllUnsymbolizedMinidumpPaths() - logging.info('testSymbolizeMinidump: all unsymbolized paths ' - + ''.join(all_unsymbolized_paths)) + if all_unsymbolized_paths is not None: + logging.info('testSymbolizeMinidump: all unsymbolized paths ' + + ''.join(all_unsymbolized_paths)) #self.assertTrue(len(all_unsymbolized_paths) == 1) # Now symbolize that minidump and make sure there are no longer any present @@ -34,9 +36,10 @@ all_unsymbolized_after_symbolize_paths = \ self._browser.GetAllUnsymbolizedMinidumpPaths() - logging.info('testSymbolizeMinidump: after symbolize all ' - + 'unsymbolized paths: ' - + ''.join(all_unsymbolized_after_symbolize_paths)) + if all_unsymbolized_after_symbolize_paths is not None: + logging.info('testSymbolizeMinidump: after symbolize all ' + + 'unsymbolized paths: ' + + ''.join(all_unsymbolized_after_symbolize_paths)) #self.assertTrue(len(all_unsymbolized_after_symbolize_paths) == 0) @@ -53,14 +56,16 @@ logging.info('testMultipleCrashMinidumps: first crash most recent path' + first_crash_path) all_paths = self._browser.GetAllMinidumpPaths() - logging.info('testMultipleCrashMinidumps: first crash all paths: ' - + ''.join(all_paths)) + if all_paths is not None: + logging.info('testMultipleCrashMinidumps: first crash all paths: ' + + ''.join(all_paths)) #self.assertEquals(len(all_paths), 1) #self.assertEqual(all_paths[0], first_crash_path) all_unsymbolized_paths = self._browser.GetAllUnsymbolizedMinidumpPaths() #self.assertTrue(len(all_unsymbolized_paths) == 1) - logging.info('testMultipleCrashMinidumps: first crash all unsymbolized ' - 'paths: ' + ''.join(all_unsymbolized_paths)) + if all_unsymbolized_paths is not None: + logging.info('testMultipleCrashMinidumps: first crash all unsymbolized ' + 'paths: ' + ''.join(all_unsymbolized_paths)) # Restart the browser and then crash a second time self._RestartBrowser() @@ -75,13 +80,15 @@ logging.info('testMultipleCrashMinidumps: second crash most recent path' + second_crash_path) second_crash_all_paths = self._browser.GetAllMinidumpPaths() - logging.info('testMultipleCrashMinidumps: second crash all paths: ' - + ''.join(second_crash_all_paths)) + if second_crash_all_paths is not None: + logging.info('testMultipleCrashMinidumps: second crash all paths: ' + + ''.join(second_crash_all_paths)) second_crash_all_unsymbolized_paths = \ self._browser.GetAllUnsymbolizedMinidumpPaths() #self.assertTrue(len(all_unsymbolized_paths) == 1) - logging.info('testMultipleCrashMinidumps: second crash all unsymbolized ' - 'paths: ' + ''.join(second_crash_all_unsymbolized_paths)) + if second_crash_all_unsymbolized_paths is not None: + logging.info('testMultipleCrashMinidumps: second crash all unsymbolized ' + 'paths: ' + ''.join(second_crash_all_unsymbolized_paths)) #self.assertEquals(len(second_crash_all_paths), 2) # Check that both paths are now present and unsymbolized #self.assertTrue(first_crash_path in second_crash_all_paths) @@ -93,14 +100,16 @@ # unsymbolized self._browser.SymbolizeMinidump(second_crash_path) after_symbolize_all_paths = self._browser.GetAllMinidumpPaths() - logging.info('testMultipleCrashMinidumps: after symbolize all paths: ' - + ''.join(after_symbolize_all_paths)) + if after_symbolize_all_paths is not None: + logging.info('testMultipleCrashMinidumps: after symbolize all paths: ' + + ''.join(after_symbolize_all_paths)) #self.assertEquals(len(after_symbolize_all_paths), 2) after_symbolize_all_unsymbolized_paths = \ self._browser.GetAllUnsymbolizedMinidumpPaths() - logging.info('testMultipleCrashMinidumps: after symbolize all ' - + 'unsymbolized paths: ' - + ''.join(after_symbolize_all_unsymbolized_paths)) + if after_symbolize_all_unsymbolized_paths is not None: + logging.info('testMultipleCrashMinidumps: after symbolize all ' + + 'unsymbolized paths: ' + + ''.join(after_symbolize_all_unsymbolized_paths)) #self.assertEquals(after_symbolize_all_unsymbolized_paths, # [first_crash_path])
diff --git a/tools/perf/measurements/clock_domain_test.py b/tools/perf/measurements/clock_domain_test.py index 51f953a..596439f 100644 --- a/tools/perf/measurements/clock_domain_test.py +++ b/tools/perf/measurements/clock_domain_test.py
@@ -38,4 +38,4 @@ ts_chrome = chrome_sync[0]['ts'] ts_telemetry_end = telemetry_sync[0]['ts'] assert ts_chrome > ts_telemetry_start - assert ts_telemetry_end > ts_chrome \ No newline at end of file + assert ts_telemetry_end > ts_chrome
diff --git a/tools/perf/measurements/page_cycler.py b/tools/perf/measurements/page_cycler.py deleted file mode 100644 index ebce259..0000000 --- a/tools/perf/measurements/page_cycler.py +++ /dev/null
@@ -1,179 +0,0 @@ -# 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. - -"""The page cycler measurement. - -This measurement registers a window load handler in which is forces a layout and -then records the value of performance.now(). This call to now() measures the -time from navigationStart (immediately after the previous page's beforeunload -event) until after the layout in the page's load event. In addition, two garbage -collections are performed in between the page loads (in the beforeunload event). -This extra garbage collection time is not included in the measurement times. -Finally, various memory and IO statistics are gathered at the very end of -cycling all pages. -""" - -import collections -import os - -from telemetry.core import util -from telemetry.page import legacy_page_test -from telemetry.value import scalar - -from metrics import cpu -from metrics import keychain_metric -from metrics import memory -from metrics import power -from metrics import speedindex - - -class PageCycler(legacy_page_test.LegacyPageTest): - - def __init__(self, page_repeat, pageset_repeat, cold_load_percent=50, - report_speed_index=False, clear_cache_before_each_run=False): - super(PageCycler, self).__init__( - clear_cache_before_each_run=clear_cache_before_each_run) - - with open(os.path.join(os.path.dirname(__file__), - 'page_cycler.js'), 'r') as f: - self._page_cycler_js = f.read() - - self._report_speed_index = report_speed_index - self._speedindex_metric = speedindex.SpeedIndexMetric() - self._memory_metric = None - self._power_metric = None - self._cpu_metric = None - self._has_loaded_page = collections.defaultdict(int) - self._initial_renderer_url = None # to avoid cross-renderer navigation - - cold_runs_percent_set = (cold_load_percent != None) - # Handle requests for cold cache runs - if (cold_runs_percent_set and - (cold_load_percent < 0 or cold_load_percent > 100)): - raise Exception('cold-load-percent must be in the range [0-100]') - - # Make sure _cold_run_start_index is an integer multiple of page_repeat. - # Without this, --pageset_shuffle + --page_repeat could lead to - # assertion failures on _started_warm in WillNavigateToPage. - if cold_runs_percent_set: - number_warm_pageset_runs = int( - (int(pageset_repeat) - 1) * (100 - cold_load_percent) / 100) - number_warm_runs = number_warm_pageset_runs * page_repeat - self._cold_run_start_index = number_warm_runs + page_repeat - else: - self._cold_run_start_index = pageset_repeat * page_repeat - - def WillStartBrowser(self, platform): - """Initialize metrics once right before the browser has been launched.""" - self._power_metric = power.PowerMetric(platform) - - def DidStartBrowser(self, browser): - """Initialize metrics once right after the browser has been launched.""" - self._memory_metric = memory.MemoryMetric(browser) - self._cpu_metric = cpu.CpuMetric(browser) - - def WillNavigateToPage(self, page, tab): - if page.is_file: - # For legacy page cyclers which use the filesystem, do an initial - # navigate to avoid paying for a cross-renderer navigation. - initial_url = tab.browser.platform.http_server.UrlOf('nonexistent.html') - if self._initial_renderer_url != initial_url: - self._initial_renderer_url = initial_url - tab.Navigate(self._initial_renderer_url) - - page.script_to_evaluate_on_commit = self._page_cycler_js - if self.ShouldRunCold(page.url): - tab.ClearCache(force=True) - if self._report_speed_index: - self._speedindex_metric.Start(page, tab) - self._cpu_metric.Start(page, tab) - self._power_metric.Start(page, tab) - - def DidNavigateToPage(self, page, tab): - self._memory_metric.Start(page, tab) - - def CustomizeBrowserOptions(self, options): - memory.MemoryMetric.CustomizeBrowserOptions(options) - power.PowerMetric.CustomizeBrowserOptions(options) - options.AppendExtraBrowserArgs('--js-flags=--expose_gc') - - if self._report_speed_index: - self._speedindex_metric.CustomizeBrowserOptions(options) - - keychain_metric.KeychainMetric.CustomizeBrowserOptions(options) - - def ValidateAndMeasurePage(self, page, tab, results): - tab.WaitForJavaScriptExpression('__pc_load_time', 60) - - chart_name_prefix = ('cold_' if self.IsRunCold(page.url) else - 'warm_') - - results.AddValue(scalar.ScalarValue( - results.current_page, '%stimes-page_load_time' % chart_name_prefix, - 'ms', tab.EvaluateJavaScript('__pc_load_time'), - description='Average page load time. Measured from ' - 'performance.timing.navigationStart until the completion ' - 'time of a layout after the window.load event. Cold times ' - 'are the times when the page is loaded cold, i.e. without ' - 'loading it before, and warm times are times when the ' - 'page is loaded after being loaded previously.')) - results.AddValue(scalar.ScalarValue( - results.current_page, '%stimes-time_to_onload' % chart_name_prefix, - 'ms', tab.EvaluateJavaScript('performance.timing.loadEventStart' - '- performance.timing.navigationStart'), - description='Time to onload. This is temporary metric to check that ' - 'PCv1 and PCv2 emit similar results')) - - # TODO(kouhei): Remove below. crbug.com/616342 - results.AddValue(scalar.ScalarValue( - results.current_page, '%stimes.page_load_time' % chart_name_prefix, - 'ms', tab.EvaluateJavaScript('__pc_load_time'), - description='Average page load time. Measured from ' - 'performance.timing.navigationStart until the completion ' - 'time of a layout after the window.load event. Cold times ' - 'are the times when the page is loaded cold, i.e. without ' - 'loading it before, and warm times are times when the ' - 'page is loaded after being loaded previously.')) - results.AddValue(scalar.ScalarValue( - results.current_page, '%stimes.time_to_onload' % chart_name_prefix, - 'ms', tab.EvaluateJavaScript('performance.timing.loadEventStart' - '- performance.timing.navigationStart'), - description='Time to onload. This is temporary metric to check that ' - 'PCv1 and PCv2 emit similar results')) - - self._has_loaded_page[page.url] += 1 - - self._power_metric.Stop(page, tab) - self._memory_metric.Stop(page, tab) - self._memory_metric.AddResults(tab, results) - self._power_metric.AddResults(tab, results) - - self._cpu_metric.Stop(page, tab) - self._cpu_metric.AddResults(tab, results) - - if self._report_speed_index: - def SpeedIndexIsFinished(): - return self._speedindex_metric.IsFinished(tab) - util.WaitFor(SpeedIndexIsFinished, 60) - self._speedindex_metric.Stop(page, tab) - self._speedindex_metric.AddResults( - tab, results, chart_name=chart_name_prefix + 'speed_index') - keychain_metric.KeychainMetric().AddResults(tab, results) - - def IsRunCold(self, url): - return self.ShouldRunCold(url) or self._has_loaded_page[url] == 0 - - def ShouldRunCold(self, url): - # We do the warm runs first for two reasons. The first is so we can - # preserve any initial profile cache for as long as possible. - # The second is that, if we did cold runs first, we'd have a transition - # page set during which we wanted the run for each URL to both - # contribute to the cold data and warm the catch for the following - # warm run, and clearing the cache before the load of the following - # URL would eliminate the intended warmup for the previous URL. - return self._has_loaded_page[url] >= self._cold_run_start_index - - def DidRunPage(self, platform): - del platform # unused - self._power_metric.Close()
diff --git a/tools/perf/measurements/page_cycler_unittest.py b/tools/perf/measurements/page_cycler_unittest.py deleted file mode 100644 index ecc0c245..0000000 --- a/tools/perf/measurements/page_cycler_unittest.py +++ /dev/null
@@ -1,292 +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. - -import sys -import unittest - -from telemetry.internal.browser import browser_options -from telemetry.internal.results import page_test_results -from telemetry.internal import story_runner -from telemetry import page as page_module -from telemetry.testing import simple_mock - -from measurements import page_cycler -from metrics import keychain_metric - - -# Allow testing protected members in the unit test. -# pylint: disable=protected-access - -class MockMemoryMetric(object): - """Used instead of simple_mock.MockObject so that the precise order and - number of calls need not be specified.""" - - def __init__(self): - pass - - def Start(self, page, tab): - pass - - def Stop(self, page, tab): - pass - - def AddResults(self, tab, results): - pass - - def AddSummaryResults(self, tab, results): - pass - - -class FakePage(page_module.Page): - """Used to mock loading a page.""" - - def __init__(self, url): - super(FakePage, self).__init__(url=url) - - @property - def is_file(self): - return self._url.startswith('file://') - - -class FakeTab(object): - """Used to mock a browser tab.""" - - def __init__(self): - self.clear_cache_calls = 0 - self.navigated_urls = [] - - def ClearCache(self, force=False): - assert force - self.clear_cache_calls += 1 - - def EvaluateJavaScript(self, script): - # If the page cycler invokes javascript to measure the number of keychain - # accesses, return a valid JSON dictionary. - keychain_histogram_name = keychain_metric.KeychainMetric.HISTOGRAM_NAME - - # Fake data for keychain metric. - if keychain_histogram_name in script: - return '{{ "{0}" : 0 }}'.format(keychain_histogram_name) - - return 1 - - def Navigate(self, url): - self.navigated_urls.append(url) - - def WaitForJavaScriptExpression(self, _, __): - pass - - @property - def browser(self): - return FakeBrowser() - - -class FakeBrowser(object): - _iteration = 0 - - @property - def cpu_stats(self): - FakeBrowser._iteration += 1 - return { - 'Browser': {'CpuProcessTime': FakeBrowser._iteration, - 'TotalTime': FakeBrowser._iteration * 2}, - 'Renderer': {'CpuProcessTime': FakeBrowser._iteration, - 'TotalTime': FakeBrowser._iteration * 3}, - 'Gpu': {'CpuProcessTime': FakeBrowser._iteration, - 'TotalTime': FakeBrowser._iteration * 4} - } - - @property - def platform(self): - return FakePlatform() - - @property - def supports_cpu_metrics(self): - return True - - @property - def supports_memory_metrics(self): - return True - - @property - def supports_power_metrics(self): - return True - - -class FakePlatform(object): - - def GetOSName(self): - return 'fake' - - def CanMonitorPower(self): - return False - - @property - def http_server(self): - class FakeHttpServer(object): - - def UrlOf(self, url_path): - return 'http://fakeserver:99999/%s' % url_path - return FakeHttpServer() - - -class PageCyclerUnitTest(unittest.TestCase): - - def SetUpCycler(self, page_repeat=1, pageset_repeat=10, cold_load_percent=50, - report_speed_index=False, setup_memory_module=False): - cycler = page_cycler.PageCycler( - page_repeat=page_repeat, - pageset_repeat=pageset_repeat, - cold_load_percent=cold_load_percent, - report_speed_index=report_speed_index) - options = browser_options.BrowserFinderOptions() - options.browser_options.platform = FakePlatform() - parser = options.CreateParser() - story_runner.AddCommandLineArgs(parser) - args = ['--page-repeat=%i' % page_repeat, - '--pageset-repeat=%i' % pageset_repeat] - parser.parse_args(args) - story_runner.ProcessCommandLineArgs(parser, options) - cycler.CustomizeBrowserOptions(options.browser_options) - - if setup_memory_module: - # Mock out memory metrics; the real ones require a real browser. - mock_memory_metric = MockMemoryMetric() - - mock_memory_module = simple_mock.MockObject() - mock_memory_module.ExpectCall( - 'MemoryMetric').WithArgs(simple_mock.DONT_CARE).WillReturn( - mock_memory_metric) - - real_memory_module = page_cycler.memory - try: - page_cycler.memory = mock_memory_module - browser = FakeBrowser() - cycler.WillStartBrowser(options.browser_options.platform) - cycler.DidStartBrowser(browser) - finally: - page_cycler.memory = real_memory_module - - return cycler - - def testOptionsColdLoadNoArgs(self): - cycler = self.SetUpCycler() - - self.assertEquals(cycler._cold_run_start_index, 5) - - def testOptionsColdLoadPagesetRepeat(self): - cycler = self.SetUpCycler(pageset_repeat=20, page_repeat=2) - - self.assertEquals(cycler._cold_run_start_index, 20) - - def testOptionsColdLoadRequested(self): - cycler = self.SetUpCycler(pageset_repeat=21, page_repeat=2, - cold_load_percent=40) - - self.assertEquals(cycler._cold_run_start_index, 26) - - def testCacheHandled(self): - cycler = self.SetUpCycler(pageset_repeat=5, - cold_load_percent=50, - setup_memory_module=True) - - url_name = 'http://fakepage.com' - page = FakePage(url_name) - tab = FakeTab() - - for i in range(5): - results = page_test_results.PageTestResults() - results.WillRunPage(page) - cycler.WillNavigateToPage(page, tab) - self.assertEqual(max(0, i - 2), tab.clear_cache_calls, - 'Iteration %d tab.clear_cache_calls %d' % - (i, tab.clear_cache_calls)) - cycler.ValidateAndMeasurePage(page, tab, results) - results.DidRunPage(page) - - values = results.all_page_specific_values - self.assertGreater(len(values), 2) - - self.assertEqual(values[0].page, page) - chart_name = 'cold_times' if i == 0 or i > 2 else 'warm_times' - self.assertEqual(values[0].name, '%s-page_load_time' % chart_name) - self.assertEqual(values[0].units, 'ms') - - cycler.DidNavigateToPage(page, tab) - - def testColdWarm(self): - cycler = self.SetUpCycler(pageset_repeat=3, setup_memory_module=True) - pages = [FakePage('http://fakepage1.com'), FakePage('http://fakepage2.com')] - tab = FakeTab() - for i in range(3): - for page in pages: - results = page_test_results.PageTestResults() - results.WillRunPage(page) - cycler.WillNavigateToPage(page, tab) - cycler.ValidateAndMeasurePage(page, tab, results) - results.DidRunPage(page) - - values = results.all_page_specific_values - self.assertGreater(len(values), 2) - - self.assertEqual(values[0].page, page) - - chart_name = 'cold_times' if i == 0 or i > 1 else 'warm_times' - self.assertEqual(values[0].name, '%s-page_load_time' % chart_name) - self.assertEqual(values[0].units, 'ms') - - cycler.DidNavigateToPage(page, tab) - - def testResults(self): - cycler = self.SetUpCycler(setup_memory_module=True) - - pages = [FakePage('http://fakepage1.com'), FakePage('http://fakepage2.com')] - tab = FakeTab() - - for i in range(2): - for page in pages: - results = page_test_results.PageTestResults() - results.WillRunPage(page) - cycler.WillNavigateToPage(page, tab) - cycler.ValidateAndMeasurePage(page, tab, results) - results.DidRunPage(page) - - values = results.all_page_specific_values - - # On Mac, there is an additional measurement: the number of keychain - # accesses. - value_count = 6 - if sys.platform == 'darwin': - value_count += 1 - self.assertEqual(value_count, len(values)) - - self.assertEqual(values[0].page, page) - chart_name = 'cold_times' if i == 0 else 'warm_times' - self.assertEqual(values[0].name, '%s-page_load_time' % chart_name) - self.assertEqual(values[0].units, 'ms') - self.assertEqual(values[1].name, '%s-time_to_onload' % chart_name) - self.assertEqual(values[1].units, 'ms') - - expected_values = ['gpu', 'browser'] - for value, expected in zip(values[4:len(expected_values) + 1], - expected_values): - self.assertEqual(value.page, page) - self.assertEqual(value.name, - 'cpu_utilization.cpu_utilization_%s' % expected) - self.assertEqual(value.units, '%') - - cycler.DidNavigateToPage(page, tab) - - def testLegacyPagesAvoidCrossRenderNavigation(self): - # For legacy page cyclers with file URLs, verify that WillNavigateToPage - # does an initial navigate to avoid paying for a cross-renderer navigation. - cycler = self.SetUpCycler(setup_memory_module=True) - pages = [FakePage('file://fakepage1.com'), FakePage('file://fakepage2.com')] - tab = FakeTab() - - self.assertEqual([], tab.navigated_urls) - for page in pages * 2: - cycler.WillNavigateToPage(page, tab) - self.assertEqual( - ['http://fakeserver:99999/nonexistent.html'], tab.navigated_urls)
diff --git a/tools/perf/page_sets/__init__.py b/tools/perf/page_sets/__init__.py index 65daf2f0..5a11235 100644 --- a/tools/perf/page_sets/__init__.py +++ b/tools/perf/page_sets/__init__.py
@@ -14,6 +14,7 @@ start_dir = os.path.dirname(os.path.abspath(__file__)) top_level_dir = os.path.dirname(start_dir) base_class = story.StorySet + for cls in discover.DiscoverClasses( start_dir, top_level_dir, base_class).values(): setattr(sys.modules[__name__], cls.__name__, cls)
diff --git a/tools/perf/page_sets/dual_browser_story.py b/tools/perf/page_sets/dual_browser_story.py index debaf60..6edaf60 100644 --- a/tools/perf/page_sets/dual_browser_story.py +++ b/tools/perf/page_sets/dual_browser_story.py
@@ -254,14 +254,14 @@ for query, url in zip(SEARCH_QUERIES, URL_LIST): # Stories that run on the android-webview browser. self.AddStory(SinglePage( - name='google_%s' % re.sub('\W+', '_', query.lower()), + name='google_%s' % re.sub(r'\W+', '_', query.lower()), url=GOOGLE_SEARCH + urllib.urlencode({'q': query}), browser_type='android-webview', phase='on_webview')) # Stories that run on the browser selected by command line options. self.AddStory(SinglePage( - name=re.sub('\W+', '_', url), + name=re.sub(r'\W+', '_', url), url=url, browser_type='default', phase='on_chrome'))
diff --git a/tools/perf/page_sets/memory_top_10_mobile.py b/tools/perf/page_sets/memory_top_10_mobile.py index dc105cb..4a56c8e 100644 --- a/tools/perf/page_sets/memory_top_10_mobile.py +++ b/tools/perf/page_sets/memory_top_10_mobile.py
@@ -77,7 +77,7 @@ # We name pages so their foreground/background counterparts are easy # to identify. For example 'http://google.com' becomes # 'http_google_com' and 'after_http_google_com' respectively. - name = re.sub('\W+', '_', url) + name = re.sub(r'\W+', '_', url) self.AddStory(ForegroundPage(self, name, url)) self.AddStory(BackgroundPage(self, 'after_' + name))
diff --git a/tools/perf/page_sets/system_health/browsing_stories.py b/tools/perf/page_sets/system_health/browsing_stories.py index 5ad8150..e6441585 100644 --- a/tools/perf/page_sets/system_health/browsing_stories.py +++ b/tools/perf/page_sets/system_health/browsing_stories.py
@@ -199,7 +199,7 @@ URL = 'https://www.washingtonpost.com/pwa' IS_SINGLE_PAGE_APP = True ITEM_SELECTOR = '.hed > a' - SUPPORTED_PLATFORMS = platforms.NO_PLATFORMS # http://crbug.com/634112 + SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY _CLOSE_BUTTON_SELECTOR = '.close' def _DidLoadDocument(self, action_runner):
diff --git a/tools/perf/page_sets/system_health/loading_stories.py b/tools/perf/page_sets/system_health/loading_stories.py index 961ccb4..9db0b955 100644 --- a/tools/perf/page_sets/system_health/loading_stories.py +++ b/tools/perf/page_sets/system_health/loading_stories.py
@@ -177,7 +177,7 @@ class LoadWashingtonPostMobileStory(_LoadingStory): NAME = 'load:news:washingtonpost' URL = 'https://www.washingtonpost.com/pwa' - SUPPORTED_PLATFORMS = platforms.NO_PLATFORMS # http://crbug.com/634112 + SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY _CLOSE_BUTTON_SELECTOR = '.close' def _DidLoadDocument(self, action_runner):
diff --git a/tools/perf/page_sets/typical_25.py b/tools/perf/page_sets/typical_25.py index 5e9d8c3..e6d901a 100644 --- a/tools/perf/page_sets/typical_25.py +++ b/tools/perf/page_sets/typical_25.py
@@ -91,7 +91,6 @@ 'http://allrecipes.com/Recipe/Pull-Apart-Hot-Cross-Buns/Detail.aspx', 'http://www.html5rocks.com/en/', 'http://www.mlb.com/', - # pylint: disable=line-too-long 'http://gawker.com/5939683/based-on-a-true-story-is-a-rotten-lie-i-hope-you-never-believe', 'http://www.imdb.com/title/tt0910970/', 'http://www.flickr.com/search/?q=monkeys&f=hp',
diff --git a/tools/perf/pylintrc b/tools/perf/pylintrc index 039dd56..4c52de84 100644 --- a/tools/perf/pylintrc +++ b/tools/perf/pylintrc
@@ -2,7 +2,34 @@ # Disable the message, report, category or checker with the given id(s). # TODO(perf-owners): Reduce this list to as small as possible. -disable=I0010,I0011,abstract-class-little-used,abstract-class-not-used,anomalous-backslash-in-string,bad-builtin,bad-context-manager,bad-continuation,bad-indentation,bad-str-strip-call,bad-whitespace,broad-except,cell-var-from-loop,deprecated-lambda,deprecated-module,duplicate-code,eval-used,exec-used,fixme,function-redefined,global-statement,interface-not-implemented,invalid-name,locally-enabled,logging-not-lazy,missing-docstring,missing-final-newline,no-init,no-member,no-name-in-module,no-self-use,no-self-use,not-callable,reimported,star-args,super-on-old-class,too-few-public-methods,too-many-ancestors,too-many-arguments,too-many-branches,too-many-function-args,too-many-instance-attributes,too-many-lines,too-many-locals,too-many-public-methods,too-many-return-statements,too-many-statements,trailing-whitespace,useless-else-on-loop +disable= + abstract-class-little-used, + abstract-class-not-used, + bad-builtin, + bad-continuation, + bad-indentation, + bad-whitespace, + broad-except, + eval-used, + fixme, + global-statement, + interface-not-implemented, + invalid-name, + locally-enabled, + locally-disabled, + logging-not-lazy, + missing-docstring, + no-member, + no-self-use, + star-args, + too-few-public-methods, + too-many-arguments, + too-many-branches, + too-many-instance-attributes, + too-many-locals, + too-many-public-methods, + too-many-statements, + too-many-return-statements [REPORTS]
diff --git a/ui/accessibility/ax_enums.idl b/ui/accessibility/ax_enums.idl index 4a3b7c0..efd18f0 100644 --- a/ui/accessibility/ax_enums.idl +++ b/ui/accessibility/ax_enums.idl
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// TODO(nektar): Migrate entire file to Mojoq. // These should be kept in sync with third_party/WebKit/public/web/WebAXEnums.h // until the Chromium and Blink trees are merged. [camel_case_enum_to_string=true] namespace ui { @@ -419,13 +420,18 @@ word_ends }; - [cpp_enum_prefix_override="ax_marker_type"] enum AXMarkerType { + enum AXMarkerType { + // Assignments are ignored by the parser, but are kept here for clarity. spelling = 1, grammar = 2, - text_match = 4 + spelling_grammar = 3, + text_match = 4, + spelling_text_match = 5, + grammar_text_match = 6, + spelling_grammar_text_match = 7 }; - [cpp_enum_prefix_override="ax_text_direction"] enum AXTextDirection { + enum AXTextDirection { ltr, rtl, ttb, @@ -434,8 +440,8 @@ // A Java counterpart will be generated for this enum. // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.ui.accessibility - // TODO(nektar): Fix compiler to create bit fields. [cpp_enum_prefix_override="ax"] enum AXTextStyle { + // Assignments are ignored by the parser, but are kept here for clarity. text_style_bold = 1, text_style_italic = 2, text_style_bold_italic = 3, @@ -443,10 +449,17 @@ text_style_bold_underline = 5, text_style_italic_underline = 6, text_style_bold_italic_underline = 7, - text_style_line_through = 8 + text_style_line_through = 8, + text_style_bold_line_through = 9, + text_style_italic_line_through = 10, + text_style_bold_italic_line_through = 11, + text_style_underline_line_through = 12, + text_style_bold_underline_line_through = 13, + text_style_italic_underline_line_through = 14, + text_style_bold_italic_underline_line_through = 15 }; - [cpp_enum_prefix_override="ax_aria_current_state"] enum AXAriaCurrentState { + enum AXAriaCurrentState { false, true, page, @@ -456,7 +469,7 @@ time }; - [cpp_enum_prefix_override="ax_invalid_state"] enum AXInvalidState { + enum AXInvalidState { false, true, spelling, @@ -464,14 +477,14 @@ other }; - [cpp_enum_prefix_override="ax_sort_direction"] enum AXSortDirection { + enum AXSortDirection { unsorted, ascending, descending, other }; - [cpp_enum_prefix_override="ax_name_from"] enum AXNameFrom { + enum AXNameFrom { uninitialized, attribute, contents, @@ -480,8 +493,8 @@ value }; - [cpp_enum_prefix_override="ax_description_from"] enum AXDescriptionFrom { - uninitialized = 0, + enum AXDescriptionFrom { + uninitialized, attribute, contents, placeholder, @@ -510,8 +523,8 @@ }; enum AXTextAffinity { - downstream = 0, - upstream = 1 + downstream, + upstream }; // Compares two nodes in an accessibility tree in pre-order traversal.
diff --git a/ui/android/window_android_compositor.h b/ui/android/window_android_compositor.h index 7ddb193..c99170e2 100644 --- a/ui/android/window_android_compositor.h +++ b/ui/android/window_android_compositor.h
@@ -23,6 +23,7 @@ public: virtual ~WindowAndroidCompositor() {} + virtual void AttachLayerForReadback(scoped_refptr<cc::Layer> layer) = 0; virtual void RequestCopyOfOutputOnRootLayer( std::unique_ptr<cc::CopyOutputRequest> request) = 0; virtual void OnVSync(base::TimeTicks frame_time,
diff --git a/ui/app_list/presenter/app_list_presenter_impl.cc b/ui/app_list/presenter/app_list_presenter_impl.cc index 572528b..cd181d1 100644 --- a/ui/app_list/presenter/app_list_presenter_impl.cc +++ b/ui/app_list/presenter/app_list_presenter_impl.cc
@@ -80,12 +80,14 @@ is_visible_ = false; - // Our widget is currently active. When the animation completes we'll hide - // the widget, changing activation. If a menu is shown before the animation - // completes then the activation change triggers the menu to close. By - // deactivating now we ensure there is no activation change when the - // animation completes and any menus stay open. - view_->GetWidget()->Deactivate(); + // The dismissal may have occurred in response to the app list losing + // activation. Otherwise, our widget is currently active. When the animation + // completes we'll hide the widget, changing activation. If a menu is shown + // before the animation completes then the activation change triggers the menu + // to close. By deactivating now we ensure there is no activation change when + // the animation completes and any menus stay open. + if (view_->GetWidget()->IsActive()) + view_->GetWidget()->Deactivate(); presenter_delegate_->OnDismissed(); ScheduleAnimation();
diff --git a/ui/arc/BUILD.gn b/ui/arc/BUILD.gn index 0ec4626..a700697 100644 --- a/ui/arc/BUILD.gn +++ b/ui/arc/BUILD.gn
@@ -20,21 +20,25 @@ ] deps = [ - "//ash:ash", + "//ash", "//base", "//components/arc:arc_base", "//components/arc:arc_bindings", "//components/arc:arc_bitmap", - "//components/exo:exo", + "//components/exo", "//components/signin/core/account_id", "//skia", - "//ui/aura:aura", + "//ui/aura", "//ui/base", + "//ui/compositor", + "//ui/display", + "//ui/events", "//ui/gfx", "//ui/message_center", "//ui/resources", "//ui/strings", "//ui/views", + "//ui/wm", ] }
diff --git a/ui/arc/arc.gyp b/ui/arc/arc.gyp index 66de41d81..c83624f0956 100644 --- a/ui/arc/arc.gyp +++ b/ui/arc/arc.gyp
@@ -17,11 +17,15 @@ 'dependencies': [ '../aura/aura.gyp:aura', '../base/ui_base.gyp:ui_base', + '../compositor/compositor.gyp:compositor', + '../display/display.gyp:display', + '../events/events.gyp:events', '../gfx/gfx.gyp:gfx_geometry', '../message_center/message_center.gyp:message_center', '../resources/ui_resources.gyp:ui_resources', '../strings/ui_strings.gyp:ui_strings', '../views/views.gyp:views', + '../wm/wm.gyp:wm', '../../ash/ash.gyp:ash', '../../base/base.gyp:base', '../../url/url.gyp:url_lib',
diff --git a/ui/arc/notification/DEPS b/ui/arc/notification/DEPS index 60aca36..5b939a57 100644 --- a/ui/arc/notification/DEPS +++ b/ui/arc/notification/DEPS
@@ -4,9 +4,13 @@ "+third_party/skia", "+ui/aura", "+ui/base", + "+ui/compositor", + "+ui/display", + "+ui/events", "+ui/gfx", "+ui/message_center", "+ui/resources", "+ui/strings", "+ui/views", + "+ui/wm", ]
diff --git a/ui/arc/notification/arc_custom_notification_view.cc b/ui/arc/notification/arc_custom_notification_view.cc index 95a6c88..7c171d1 100644 --- a/ui/arc/notification/arc_custom_notification_view.cc +++ b/ui/arc/notification/arc_custom_notification_view.cc
@@ -9,6 +9,10 @@ #include "third_party/skia/include/core/SkColor.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/compositor/layer_animation_observer.h" +#include "ui/display/screen.h" +#include "ui/events/event_handler.h" +#include "ui/gfx/transform.h" #include "ui/message_center/message_center_style.h" #include "ui/resources/grit/ui_resources.h" #include "ui/strings/grit/ui_strings.h" @@ -16,23 +20,105 @@ #include "ui/views/border.h" #include "ui/views/controls/button/image_button.h" #include "ui/views/widget/widget.h" +#include "ui/wm/core/window_util.h" namespace arc { +class ArcCustomNotificationView::EventForwarder : public ui::EventHandler { + public: + explicit EventForwarder(ArcCustomNotificationView* owner) : owner_(owner) {} + ~EventForwarder() override = default; + + private: + // ui::EventHandler + void OnEvent(ui::Event* event) override { owner_->OnEvent(event); } + + ArcCustomNotificationView* const owner_; + + DISALLOW_COPY_AND_ASSIGN(EventForwarder); +}; + +class ArcCustomNotificationView::SlideHelper + : public ui::LayerAnimationObserver { + public: + explicit SlideHelper(ArcCustomNotificationView* owner) : owner_(owner) { + owner_->parent()->layer()->GetAnimator()->AddObserver(this); + + // Reset opacity to 1 to handle to case when the surface is sliding before + // getting managed by this class, e.g. sliding in a popup before showing + // in a message center view. + if (owner_->surface_ && owner_->surface_->window()) + owner_->surface_->window()->layer()->SetOpacity(1.0f); + } + ~SlideHelper() override { + owner_->parent()->layer()->GetAnimator()->RemoveObserver(this); + } + + void Update() { + const bool has_animation = + owner_->parent()->layer()->GetAnimator()->is_animating(); + const bool has_transform = !owner_->parent()->GetTransform().IsIdentity(); + const bool sliding = has_transform || has_animation; + if (sliding_ == sliding) + return; + + sliding_ = sliding; + + if (sliding_) + OnSlideStart(); + else + OnSlideEnd(); + } + + private: + void OnSlideStart() { + if (!owner_->surface_ || !owner_->surface_->window()) + return; + surface_copy_ = ::wm::RecreateLayers(owner_->surface_->window(), nullptr); + owner_->layer()->Add(surface_copy_->root()); + owner_->surface_->window()->layer()->SetOpacity(0.0f); + } + + void OnSlideEnd() { + if (!owner_->surface_ || !owner_->surface_->window()) + return; + owner_->surface_->window()->layer()->SetOpacity(1.0f); + owner_->Layout(); + surface_copy_.reset(); + } + + // ui::LayerAnimationObserver + void OnLayerAnimationEnded(ui::LayerAnimationSequence* seq) override { + Update(); + } + void OnLayerAnimationAborted(ui::LayerAnimationSequence* seq) override { + Update(); + } + void OnLayerAnimationScheduled(ui::LayerAnimationSequence* seq) override {} + + ArcCustomNotificationView* const owner_; + bool sliding_ = false; + std::unique_ptr<ui::LayerTreeOwner> surface_copy_; + + DISALLOW_COPY_AND_ASSIGN(SlideHelper); +}; + ArcCustomNotificationView::ArcCustomNotificationView( ArcCustomNotificationItem* item, exo::NotificationSurface* surface) - : item_(item), surface_(surface) { + : item_(item), event_forwarder_(new EventForwarder(this)) { + SetSurface(surface); item_->AddObserver(this); OnItemPinnedChanged(); - surface_->window()->AddObserver(this); + + // Create a layer as an anchor to insert surface copy during a slide. + SetPaintToLayer(true); } ArcCustomNotificationView::~ArcCustomNotificationView() { + SetSurface(nullptr); if (item_) item_->RemoveObserver(this); - if (surface_ && surface_->window()) - surface_->window()->RemoveObserver(this); } void ArcCustomNotificationView::CreateFloatingCloseButton() { @@ -64,11 +150,27 @@ floating_close_button_widget_.reset(new views::Widget); floating_close_button_widget_->Init(params); floating_close_button_widget_->SetContentsView(floating_close_button_); - floating_close_button_widget_->Show(); Layout(); } +void ArcCustomNotificationView::SetSurface(exo::NotificationSurface* surface) { + if (surface_ == surface) + return; + + if (surface_ && surface_->window()) { + surface_->window()->RemoveObserver(this); + surface_->window()->RemovePreTargetHandler(event_forwarder_.get()); + } + + surface_ = surface; + + if (surface_ && surface_->window()) { + surface_->window()->AddObserver(this); + surface_->window()->AddPreTargetHandler(event_forwarder_.get()); + } +} + void ArcCustomNotificationView::UpdatePreferredSize() { gfx::Size preferred_size = surface_->GetSize(); if (preferred_size.width() != message_center::kNotificationWidth) { @@ -81,10 +183,31 @@ SetPreferredSize(preferred_size); } +void ArcCustomNotificationView::UpdateCloseButtonVisiblity() { + if (!surface_ || !floating_close_button_widget_) + return; + + const bool target_visiblity = + surface_->window()->GetBoundsInScreen().Contains( + display::Screen::GetScreen()->GetCursorScreenPoint()); + if (target_visiblity == floating_close_button_widget_->IsVisible()) + return; + + if (target_visiblity) + floating_close_button_widget_->Show(); + else + floating_close_button_widget_->Hide(); +} + void ArcCustomNotificationView::ViewHierarchyChanged( const views::View::ViewHierarchyChangedDetails& details) { views::Widget* widget = GetWidget(); + if (!details.is_add) { + // Resets slide helper when this view is removed from its parent. + slide_helper_.reset(); + } + // Bail if native_view() has attached to a different widget. if (widget && native_view() && views::Widget::GetTopLevelWidgetForNativeView(native_view()) != widget) { @@ -98,6 +221,9 @@ UpdatePreferredSize(); Attach(surface_->window()); + + // Creates slide helper after this view is added to its parent. + slide_helper_.reset(new SlideHelper(this)); } void ArcCustomNotificationView::Layout() { @@ -126,6 +252,27 @@ close_button_bounds.width()); close_button_bounds.set_y(surface_local_bounds.y()); floating_close_button_widget_->SetBounds(close_button_bounds); + + UpdateCloseButtonVisiblity(); +} + +void ArcCustomNotificationView::OnKeyEvent(ui::KeyEvent* event) { + // Forward to parent CustomNotificationView to handle keyboard dismissal. + parent()->OnKeyEvent(event); +} + +void ArcCustomNotificationView::OnGestureEvent(ui::GestureEvent* event) { + // Forward to parent CustomNotificationView to handle sliding out. + parent()->OnGestureEvent(event); + slide_helper_->Update(); +} + +void ArcCustomNotificationView::OnMouseEntered(const ui::MouseEvent&) { + UpdateCloseButtonVisiblity(); +} + +void ArcCustomNotificationView::OnMouseExited(const ui::MouseEvent&) { + UpdateCloseButtonVisiblity(); } void ArcCustomNotificationView::ButtonPressed(views::Button* sender, @@ -135,9 +282,10 @@ } } -void ArcCustomNotificationView::OnWindowBoundsChanged(aura::Window* window, - const gfx::Rect& old_bounds, - const gfx::Rect& new_bounds) { +void ArcCustomNotificationView::OnWindowBoundsChanged( + aura::Window* window, + const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds) { UpdatePreferredSize(); } @@ -151,7 +299,7 @@ // Reset |surface_| with |item_| since no one is observing the |surface_| // after |item_| is gone and this view should be removed soon. - surface_ = nullptr; + SetSurface(nullptr); } void ArcCustomNotificationView::OnItemPinnedChanged() { @@ -163,7 +311,7 @@ } void ArcCustomNotificationView::OnItemNotificationSurfaceRemoved() { - surface_ = nullptr; + SetSurface(nullptr); } } // namespace arc
diff --git a/ui/arc/notification/arc_custom_notification_view.h b/ui/arc/notification/arc_custom_notification_view.h index c10f3a23..4f2a4e3 100644 --- a/ui/arc/notification/arc_custom_notification_view.h +++ b/ui/arc/notification/arc_custom_notification_view.h
@@ -35,13 +35,22 @@ ~ArcCustomNotificationView() override; private: + class EventForwarder; + class SlideHelper; + void CreateFloatingCloseButton(); + void SetSurface(exo::NotificationSurface* surface); void UpdatePreferredSize(); + void UpdateCloseButtonVisiblity(); // views::NativeViewHost void ViewHierarchyChanged( const ViewHierarchyChangedDetails& details) override; void Layout() override; + void OnKeyEvent(ui::KeyEvent* event) override; + void OnGestureEvent(ui::GestureEvent* event) override; + void OnMouseEntered(const ui::MouseEvent& event) override; + void OnMouseExited(const ui::MouseEvent& event) override; // views::ButtonListener void ButtonPressed(views::Button* sender, const ui::Event& event) override; @@ -57,8 +66,19 @@ void OnItemPinnedChanged() override; void OnItemNotificationSurfaceRemoved() override; - ArcCustomNotificationItem* item_; - exo::NotificationSurface* surface_; + ArcCustomNotificationItem* item_ = nullptr; + exo::NotificationSurface* surface_ = nullptr; + + // A pre-target event handler to forward events on the surface to this view. + // Using a pre-target event handler instead of a target handler on the surface + // window because it has descendant aura::Window and the events on them need + // to be handled as well. + // TODO(xiyuan): Revisit after exo::Surface no longer has an aura::Window. + std::unique_ptr<EventForwarder> event_forwarder_; + + // A helper to observe slide transform/animation and use surface layer copy + // when a slide is in progress and restore the surface when it finishes. + std::unique_ptr<SlideHelper> slide_helper_; // A close button on top of NotificationSurface. Needed because the // aura::Window of NotificationSurface is added after hosting widget's
diff --git a/ui/arc/notification/arc_notification_manager_unittest.cc b/ui/arc/notification/arc_notification_manager_unittest.cc index 1df7f66..3db70c1 100644 --- a/ui/arc/notification/arc_notification_manager_unittest.cc +++ b/ui/arc/notification/arc_notification_manager_unittest.cc
@@ -27,8 +27,8 @@ public: MockMessageCenter() {} ~MockMessageCenter() override { - STLDeleteContainerPointers( - visible_notifications_.begin(), visible_notifications_.end()); + base::STLDeleteContainerPointers(visible_notifications_.begin(), + visible_notifications_.end()); } void AddNotification(
diff --git a/ui/base/clipboard/clipboard_android.cc b/ui/base/clipboard/clipboard_android.cc index de51d04..409af31 100644 --- a/ui/base/clipboard/clipboard_android.cc +++ b/ui/base/clipboard/clipboard_android.cc
@@ -85,7 +85,7 @@ bool ClipboardMap::HasFormat(const std::string& format) { base::AutoLock lock(lock_); UpdateFromAndroidClipboard(); - return ContainsKey(map_, format); + return base::ContainsKey(map_, format); } void ClipboardMap::Set(const std::string& format, const std::string& data) { @@ -96,10 +96,10 @@ void ClipboardMap::CommitToAndroidClipboard() { JNIEnv* env = AttachCurrentThread(); base::AutoLock lock(lock_); - if (ContainsKey(map_, kHTMLFormat)) { + if (base::ContainsKey(map_, kHTMLFormat)) { // Android's API for storing HTML content on the clipboard requires a plain- // text representation to be available as well. - if (!ContainsKey(map_, kPlainTextFormat)) + if (!base::ContainsKey(map_, kPlainTextFormat)) return; ScopedJavaLocalRef<jstring> html = @@ -110,7 +110,7 @@ DCHECK(html.obj() && text.obj()); Java_Clipboard_setHTMLText(env, clipboard_manager_.obj(), html.obj(), text.obj()); - } else if (ContainsKey(map_, kPlainTextFormat)) { + } else if (base::ContainsKey(map_, kPlainTextFormat)) { ScopedJavaLocalRef<jstring> str = ConvertUTF8ToJavaString(env, map_[kPlainTextFormat].c_str()); DCHECK(str.obj());
diff --git a/ui/base/ime/BUILD.gn b/ui/base/ime/BUILD.gn index d8ee478..281a28b 100644 --- a/ui/base/ime/BUILD.gn +++ b/ui/base/ime/BUILD.gn
@@ -48,8 +48,6 @@ "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", @@ -87,6 +85,8 @@ "linux/linux_input_method_context.h", "linux/linux_input_method_context_factory.cc", "linux/linux_input_method_context_factory.h", + "mock_ime_input_context_handler.cc", + "mock_ime_input_context_handler.h", "mock_input_method.cc", "mock_input_method.h", "text_edit_commands.h",
diff --git a/ui/base/ime/chromeos/mock_ime_input_context_handler.cc b/ui/base/ime/chromeos/mock_ime_input_context_handler.cc deleted file mode 100644 index 403eca0..0000000 --- a/ui/base/ime/chromeos/mock_ime_input_context_handler.cc +++ /dev/null
@@ -1,55 +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 "ui/base/ime/chromeos/mock_ime_input_context_handler.h" - -#include "ui/base/ime/composition_text.h" -#include "ui/base/ime/input_method.h" - -namespace chromeos { - -MockIMEInputContextHandler::MockIMEInputContextHandler() - : commit_text_call_count_(0), - update_preedit_text_call_count_(0), - delete_surrounding_text_call_count_(0) { -} - -MockIMEInputContextHandler::~MockIMEInputContextHandler() { -} - -void MockIMEInputContextHandler::CommitText(const std::string& text) { - ++commit_text_call_count_; - last_commit_text_ = text; -} - -void MockIMEInputContextHandler::UpdateCompositionText( - const ui::CompositionText& text, - uint32_t cursor_pos, - bool visible) { - ++update_preedit_text_call_count_; - last_update_composition_arg_.composition_text.CopyFrom(text); - last_update_composition_arg_.cursor_pos = cursor_pos; - last_update_composition_arg_.is_visible = visible; -} - -void MockIMEInputContextHandler::DeleteSurroundingText(int32_t offset, - uint32_t length) { - ++delete_surrounding_text_call_count_; - last_delete_surrounding_text_arg_.offset = offset; - last_delete_surrounding_text_arg_.length = length; -} - -void MockIMEInputContextHandler::Reset() { - commit_text_call_count_ = 0; - update_preedit_text_call_count_ = 0; - delete_surrounding_text_call_count_ = 0; - last_commit_text_.clear(); -} - -void MockIMEInputContextHandler::SendKeyEvent(ui::KeyEvent* event) {} - -ui::InputMethod* MockIMEInputContextHandler::GetInputMethod() { - return nullptr; -} -} // namespace chromeos
diff --git a/ui/base/ime/chromeos/mock_ime_input_context_handler.h b/ui/base/ime/chromeos/mock_ime_input_context_handler.h deleted file mode 100644 index b48ba3f..0000000 --- a/ui/base/ime/chromeos/mock_ime_input_context_handler.h +++ /dev/null
@@ -1,81 +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 UI_BASE_IME_CHROMEOS_MOCK_IME_INPUT_CONTEXT_HANDLER_H_ -#define UI_BASE_IME_CHROMEOS_MOCK_IME_INPUT_CONTEXT_HANDLER_H_ - -#include <stdint.h> - -#include "ui/base/ime/composition_text.h" -#include "ui/base/ime/ime_input_context_handler_interface.h" -#include "ui/base/ime/ui_base_ime_export.h" - -namespace ui { -class InputMethod; -} // ui - -namespace chromeos { - -class UI_BASE_IME_EXPORT MockIMEInputContextHandler - : public ui::IMEInputContextHandlerInterface { - public: - struct UpdateCompositionTextArg { - ui::CompositionText composition_text; - uint32_t cursor_pos; - bool is_visible; - }; - - struct DeleteSurroundingTextArg { - int32_t offset; - uint32_t length; - }; - - MockIMEInputContextHandler(); - virtual ~MockIMEInputContextHandler(); - - void CommitText(const std::string& text) override; - void UpdateCompositionText(const ui::CompositionText& text, - uint32_t cursor_pos, - bool visible) override; - void DeleteSurroundingText(int32_t offset, uint32_t length) override; - void SendKeyEvent(ui::KeyEvent* event) override; - ui::InputMethod* GetInputMethod() override; - - int commit_text_call_count() const { return commit_text_call_count_; } - - int update_preedit_text_call_count() const { - return update_preedit_text_call_count_; - } - - int delete_surrounding_text_call_count() const { - return delete_surrounding_text_call_count_; - } - - const std::string& last_commit_text() const { - return last_commit_text_; - }; - - const UpdateCompositionTextArg& last_update_composition_arg() const { - return last_update_composition_arg_; - } - - const DeleteSurroundingTextArg& last_delete_surrounding_text_arg() const { - return last_delete_surrounding_text_arg_; - } - - // Resets all call count. - void Reset(); - - private: - int commit_text_call_count_; - int update_preedit_text_call_count_; - int delete_surrounding_text_call_count_; - std::string last_commit_text_; - UpdateCompositionTextArg last_update_composition_arg_; - DeleteSurroundingTextArg last_delete_surrounding_text_arg_; -}; - -} // namespace chromeos - -#endif // UI_BASE_IME_CHROMEOS_MOCK_IME_INPUT_CONTEXT_HANDLER_H_
diff --git a/ui/base/ime/mock_ime_input_context_handler.cc b/ui/base/ime/mock_ime_input_context_handler.cc new file mode 100644 index 0000000..4c6045d --- /dev/null +++ b/ui/base/ime/mock_ime_input_context_handler.cc
@@ -0,0 +1,53 @@ +// Copyright 2016 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/base/ime/mock_ime_input_context_handler.h" + +#include "ui/base/ime/composition_text.h" +#include "ui/base/ime/input_method.h" + +namespace ui { + +MockIMEInputContextHandler::MockIMEInputContextHandler() + : commit_text_call_count_(0), + update_preedit_text_call_count_(0), + delete_surrounding_text_call_count_(0) {} + +MockIMEInputContextHandler::~MockIMEInputContextHandler() {} + +void MockIMEInputContextHandler::CommitText(const std::string& text) { + ++commit_text_call_count_; + last_commit_text_ = text; +} + +void MockIMEInputContextHandler::UpdateCompositionText( + const CompositionText& text, + uint32_t cursor_pos, + bool visible) { + ++update_preedit_text_call_count_; + last_update_composition_arg_.composition_text.CopyFrom(text); + last_update_composition_arg_.cursor_pos = cursor_pos; + last_update_composition_arg_.is_visible = visible; +} + +void MockIMEInputContextHandler::DeleteSurroundingText(int32_t offset, + uint32_t length) { + ++delete_surrounding_text_call_count_; + last_delete_surrounding_text_arg_.offset = offset; + last_delete_surrounding_text_arg_.length = length; +} + +void MockIMEInputContextHandler::Reset() { + commit_text_call_count_ = 0; + update_preedit_text_call_count_ = 0; + delete_surrounding_text_call_count_ = 0; + last_commit_text_.clear(); +} + +void MockIMEInputContextHandler::SendKeyEvent(KeyEvent* event) {} + +InputMethod* MockIMEInputContextHandler::GetInputMethod() { + return nullptr; +} +} // namespace ui
diff --git a/ui/base/ime/mock_ime_input_context_handler.h b/ui/base/ime/mock_ime_input_context_handler.h new file mode 100644 index 0000000..4cbf44d --- /dev/null +++ b/ui/base/ime/mock_ime_input_context_handler.h
@@ -0,0 +1,75 @@ +// 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 UI_BASE_IME_MOCK_IME_INPUT_CONTEXT_HANDLER_H_ +#define UI_BASE_IME_MOCK_IME_INPUT_CONTEXT_HANDLER_H_ + +#include <stdint.h> + +#include "ui/base/ime/composition_text.h" +#include "ui/base/ime/ime_input_context_handler_interface.h" +#include "ui/base/ime/ui_base_ime_export.h" + +namespace ui { +class InputMethod; + +class UI_BASE_IME_EXPORT MockIMEInputContextHandler + : public IMEInputContextHandlerInterface { + public: + struct UpdateCompositionTextArg { + CompositionText composition_text; + uint32_t cursor_pos; + bool is_visible; + }; + + struct DeleteSurroundingTextArg { + int32_t offset; + uint32_t length; + }; + + MockIMEInputContextHandler(); + virtual ~MockIMEInputContextHandler(); + + void CommitText(const std::string& text) override; + void UpdateCompositionText(const CompositionText& text, + uint32_t cursor_pos, + bool visible) override; + void DeleteSurroundingText(int32_t offset, uint32_t length) override; + void SendKeyEvent(KeyEvent* event) override; + InputMethod* GetInputMethod() override; + + int commit_text_call_count() const { return commit_text_call_count_; } + + int update_preedit_text_call_count() const { + return update_preedit_text_call_count_; + } + + int delete_surrounding_text_call_count() const { + return delete_surrounding_text_call_count_; + } + + const std::string& last_commit_text() const { return last_commit_text_; }; + + const UpdateCompositionTextArg& last_update_composition_arg() const { + return last_update_composition_arg_; + } + + const DeleteSurroundingTextArg& last_delete_surrounding_text_arg() const { + return last_delete_surrounding_text_arg_; + } + + // Resets all call count. + void Reset(); + + private: + int commit_text_call_count_; + int update_preedit_text_call_count_; + int delete_surrounding_text_call_count_; + std::string last_commit_text_; + UpdateCompositionTextArg last_update_composition_arg_; + DeleteSurroundingTextArg last_delete_surrounding_text_arg_; +}; +} // ui + +#endif // UI_BASE_IME_MOCK_IME_INPUT_CONTEXT_HANDLER_H_
diff --git a/ui/base/ime/ui_base_ime.gyp b/ui/base/ime/ui_base_ime.gyp index 8bc8d62..35892e3 100644 --- a/ui/base/ime/ui_base_ime.gyp +++ b/ui/base/ime/ui_base_ime.gyp
@@ -75,8 +75,6 @@ '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', @@ -118,6 +116,8 @@ 'linux/text_edit_command_auralinux.h', 'linux/text_edit_key_bindings_delegate_auralinux.cc', 'linux/text_edit_key_bindings_delegate_auralinux.h', + 'mock_ime_input_context_handler.cc', + 'mock_ime_input_context_handler.h', 'mock_input_method.cc', 'mock_input_method.h', 'text_edit_commands.h',
diff --git a/ui/base/ime/win/tsf_input_scope.cc b/ui/base/ime/win/tsf_input_scope.cc index 347eea8..e2932190 100644 --- a/ui/base/ime/win/tsf_input_scope.cc +++ b/ui/base/ime/win/tsf_input_scope.cc
@@ -24,7 +24,7 @@ if (input_scope == IS_DEFAULT) return; - if (ContainsValue(*input_scopes, input_scope)) + if (base::ContainsValue(*input_scopes, input_scope)) return; input_scopes->push_back(input_scope);
diff --git a/ui/base/l10n/l10n_util_unittest.cc b/ui/base/l10n/l10n_util_unittest.cc index f4ff97c..de1610d 100644 --- a/ui/base/l10n/l10n_util_unittest.cc +++ b/ui/base/l10n/l10n_util_unittest.cc
@@ -399,7 +399,7 @@ ASSERT_TRUE(UTF8ToUTF16("b") == strings[1]->string()); ASSERT_TRUE(UTF8ToUTF16("C") == strings[2]->string()); ASSERT_TRUE(UTF8ToUTF16("d") == strings[3]->string()); - STLDeleteElements(&strings); + base::STLDeleteElements(&strings); } /**
diff --git a/ui/base/models/tree_node_model.h b/ui/base/models/tree_node_model.h index d860db9..7d4f29a 100644 --- a/ui/base/models/tree_node_model.h +++ b/ui/base/models/tree_node_model.h
@@ -69,9 +69,7 @@ explicit TreeNode(const base::string16& title) : title_(title), parent_(NULL) {} - ~TreeNode() override { - STLDeleteElements(&children_); - } + ~TreeNode() override { base::STLDeleteElements(&children_); } // Adds |node| as a child of this node, at |index|. virtual void Add(NodeType* node, int index) {
diff --git a/ui/base/win/hwnd_subclass.cc b/ui/base/win/hwnd_subclass.cc index 705a0f1..7faed27 100644 --- a/ui/base/win/hwnd_subclass.cc +++ b/ui/base/win/hwnd_subclass.cc
@@ -110,7 +110,7 @@ void HWNDSubclass::AddFilter(HWNDMessageFilter* filter) { DCHECK(filter); - if (!ContainsValue(filters_, filter)) + if (!base::ContainsValue(filters_, filter)) filters_.push_back(filter); }
diff --git a/ui/base/window_tracker_template.h b/ui/base/window_tracker_template.h index a22b4b78..5bcaccb4 100644 --- a/ui/base/window_tracker_template.h +++ b/ui/base/window_tracker_template.h
@@ -40,7 +40,7 @@ // Adds |window| to the set of Windows being tracked. void Add(T* window) { - if (ContainsValue(windows_, window)) + if (base::ContainsValue(windows_, window)) return; window->AddObserver(this); @@ -65,7 +65,9 @@ // Returns true if |window| was previously added and has not been removed or // deleted. - bool Contains(T* window) const { return ContainsValue(windows_, window); } + bool Contains(T* window) const { + return base::ContainsValue(windows_, window); + } // Observer overrides: void OnWindowDestroying(T* window) override {
diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc index 783b1b4..e73f65d5 100644 --- a/ui/base/x/x11_util.cc +++ b/ui/base/x/x11_util.cc
@@ -557,7 +557,7 @@ std::vector<XAtom> wm_states; if (GetAtomArrayProperty(window, "_NET_WM_STATE", &wm_states)) { XAtom hidden_atom = GetAtom("_NET_WM_STATE_HIDDEN"); - if (ContainsValue(wm_states, hidden_atom)) + if (base::ContainsValue(wm_states, hidden_atom)) return false; }
diff --git a/ui/chromeos/ime/candidate_window_view.cc b/ui/chromeos/ime/candidate_window_view.cc index 50e4c988..5c42421 100644 --- a/ui/chromeos/ime/candidate_window_view.cc +++ b/ui/chromeos/ime/candidate_window_view.cc
@@ -359,7 +359,7 @@ // Reset all candidate_views_ when orientation changes. if (orientation != candidate_window_.orientation()) - STLDeleteElements(&candidate_views_); + base::STLDeleteElements(&candidate_views_); while (page_size < candidate_views_.size()) { delete candidate_views_.back();
diff --git a/ui/compositor/canvas_painter.cc b/ui/compositor/canvas_painter.cc index 618fa75..b67d486 100644 --- a/ui/compositor/canvas_painter.cc +++ b/ui/compositor/canvas_painter.cc
@@ -17,9 +17,8 @@ gfx::Rect(canvas_->sk_canvas()->getBaseLayerSize().width(), canvas_->sk_canvas()->getBaseLayerSize().height()), 1.f / raster_scale_factor)), - list_(cc::DisplayItemList::Create(rect_, cc::DisplayItemListSettings())), - context_(list_.get(), raster_scale_factor_, rect_) { -} + list_(cc::DisplayItemList::Create(cc::DisplayItemListSettings())), + context_(list_.get(), raster_scale_factor_, rect_) {} CanvasPainter::~CanvasPainter() { list_->Finalize();
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index 84f9831..19c43ce 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc
@@ -342,12 +342,7 @@ host_->SetNeedsCommit(); } -void Compositor::FinishAllRendering() { - host_->FinishAllRendering(); -} - void Compositor::DisableSwapUntilResize() { - host_->FinishAllRendering(); context_factory_->ResizeDisplay(this, gfx::Size()); } @@ -390,6 +385,15 @@ return host_->visible(); } +bool Compositor::ScrollLayerTo(int layer_id, const gfx::ScrollOffset& offset) { + return host_->GetInputHandler()->ScrollLayerTo(layer_id, offset); +} + +bool Compositor::GetScrollOffsetForLayer(int layer_id, + gfx::ScrollOffset* offset) const { + return host_->GetInputHandler()->GetScrollOffsetForLayer(layer_id, offset); +} + void Compositor::SetAuthoritativeVSyncInterval( const base::TimeDelta& interval) { context_factory_->SetAuthoritativeVSyncInterval(this, interval);
diff --git a/ui/compositor/compositor.h b/ui/compositor/compositor.h index f918f97..629508f9 100644 --- a/ui/compositor/compositor.h +++ b/ui/compositor/compositor.h
@@ -52,6 +52,7 @@ namespace gfx { class Rect; +class ScrollOffset; class Size; } @@ -243,9 +244,6 @@ // from changes to layer properties. void ScheduleRedrawRect(const gfx::Rect& damage_rect); - // Finishes all outstanding rendering and disables swapping on this surface. - void FinishAllRendering(); - // Finishes all outstanding rendering and disables swapping on this surface // until it is resized. void DisableSwapUntilResize(); @@ -271,6 +269,11 @@ // Gets the visibility of the underlying compositor. bool IsVisible(); + // Gets or sets the scroll offset for the given layer in step with the + // cc::InputHandler. Returns true if the layer is active on the impl side. + bool GetScrollOffsetForLayer(int layer_id, gfx::ScrollOffset* offset) const; + bool ScrollLayerTo(int layer_id, const gfx::ScrollOffset& offset); + // The "authoritative" vsync interval, if provided, will override interval // reported from 3D context. This is typically the value reported by a more // reliable source, e.g, the platform display configuration.
diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc index 7dcf17724..9accc1f 100644 --- a/ui/compositor/layer.cc +++ b/ui/compositor/layer.cc
@@ -756,6 +756,34 @@ delegate_->OnDelegatedFrameDamage(damage_rect_in_dip); } +void Layer::SetScrollable(Layer* parent_clip_layer, + const base::Closure& on_scroll) { + cc_layer_->SetScrollClipLayerId(parent_clip_layer->cc_layer_->id()); + cc_layer_->set_did_scroll_callback(on_scroll); + cc_layer_->SetUserScrollable(true, true); +} + +gfx::ScrollOffset Layer::CurrentScrollOffset() const { + const Compositor* compositor = GetCompositor(); + gfx::ScrollOffset offset; + if (compositor && + compositor->GetScrollOffsetForLayer(cc_layer_->id(), &offset)) + return offset; + return cc_layer_->scroll_offset(); +} + +void Layer::SetScrollOffset(const gfx::ScrollOffset& offset) { + Compositor* compositor = GetCompositor(); + bool scrolled_on_impl_side = + compositor && compositor->ScrollLayerTo(cc_layer_->id(), offset); + + if (!scrolled_on_impl_side) + cc_layer_->SetScrollOffset(offset); + + DCHECK_EQ(offset.x(), CurrentScrollOffset().x()); + DCHECK_EQ(offset.y(), CurrentScrollOffset().y()); +} + void Layer::RequestCopyOfOutput( std::unique_ptr<cc::CopyOutputRequest> request) { cc_layer_->RequestCopyOfOutput(std::move(request)); @@ -775,7 +803,7 @@ cc::DisplayItemListSettings settings; settings.use_cached_picture = false; scoped_refptr<cc::DisplayItemList> display_list = - cc::DisplayItemList::Create(PaintableRegion(), settings); + cc::DisplayItemList::Create(settings); if (delegate_) { delegate_->OnPaintLayer( PaintContext(display_list.get(), device_scale_factor_, invalidation));
diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h index c19e8eab..dc28e09 100644 --- a/ui/compositor/layer.h +++ b/ui/compositor/layer.h
@@ -355,6 +355,14 @@ // Requets a copy of the layer's output as a texture or bitmap. void RequestCopyOfOutput(std::unique_ptr<cc::CopyOutputRequest> request); + // Makes this Layer scrollable, clipping to |parent_clip_layer|. |on_scroll| + // is invoked when scrolling performed by the cc::InputHandler is committed. + void SetScrollable(Layer* parent_clip_layer, const base::Closure& on_scroll); + + // Gets and sets the current scroll offset of the layer. + gfx::ScrollOffset CurrentScrollOffset() const; + void SetScrollOffset(const gfx::ScrollOffset& offset); + // ContentLayerClient gfx::Rect PaintableRegion() override; scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList(
diff --git a/ui/compositor/layer_animation_element.cc b/ui/compositor/layer_animation_element.cc index 2e5d981..1e9f93f 100644 --- a/ui/compositor/layer_animation_element.cc +++ b/ui/compositor/layer_animation_element.cc
@@ -48,40 +48,6 @@ DISALLOW_COPY_AND_ASSIGN(Pause); }; -// TransformTransition --------------------------------------------------------- - -class TransformTransition : public LayerAnimationElement { - public: - TransformTransition(const gfx::Transform& target, base::TimeDelta duration) - : LayerAnimationElement(TRANSFORM, duration), - target_(target) { - } - ~TransformTransition() override {} - - protected: - void OnStart(LayerAnimationDelegate* delegate) override { - start_ = delegate->GetTransformForAnimation(); - } - - bool OnProgress(double t, LayerAnimationDelegate* delegate) override { - delegate->SetTransformFromAnimation( - gfx::Tween::TransformValueBetween(t, start_, target_)); - return true; - } - - void OnGetTarget(TargetValue* target) const override { - target->transform = target_; - } - - void OnAbort(LayerAnimationDelegate* delegate) override {} - - private: - gfx::Transform start_; - const gfx::Transform target_; - - DISALLOW_COPY_AND_ASSIGN(TransformTransition); -}; - // InterpolatedTransformTransition --------------------------------------------- class InterpolatedTransformTransition : public LayerAnimationElement { @@ -148,41 +114,6 @@ DISALLOW_COPY_AND_ASSIGN(BoundsTransition); }; -// OpacityTransition ----------------------------------------------------------- - -class OpacityTransition : public LayerAnimationElement { - public: - OpacityTransition(float target, base::TimeDelta duration) - : LayerAnimationElement(OPACITY, duration), - start_(0.0f), - target_(target) { - } - ~OpacityTransition() override {} - - protected: - void OnStart(LayerAnimationDelegate* delegate) override { - start_ = delegate->GetOpacityForAnimation(); - } - - bool OnProgress(double t, LayerAnimationDelegate* delegate) override { - delegate->SetOpacityFromAnimation( - gfx::Tween::FloatValueBetween(t, start_, target_)); - return true; - } - - void OnGetTarget(TargetValue* target) const override { - target->opacity = target_; - } - - void OnAbort(LayerAnimationDelegate* delegate) override {} - - private: - float start_; - const float target_; - - DISALLOW_COPY_AND_ASSIGN(OpacityTransition); -}; - // VisibilityTransition -------------------------------------------------------- class VisibilityTransition : public LayerAnimationElement { @@ -489,110 +420,6 @@ DISALLOW_COPY_AND_ASSIGN(ThreadedTransformTransition); }; -// InverseTransformTransision -------------------------------------------------- - -class InverseTransformTransition : public ThreadedLayerAnimationElement { - public: - InverseTransformTransition(const gfx::Transform& base_transform, - const LayerAnimationElement* uninverted_transition) - : ThreadedLayerAnimationElement(*uninverted_transition), - base_transform_(base_transform), - uninverted_transition_( - CheckAndCast<const ThreadedTransformTransition*>( - uninverted_transition)) { - } - ~InverseTransformTransition() override {} - - static InverseTransformTransition* Clone(const LayerAnimationElement* other) { - const InverseTransformTransition* other_inverse = - CheckAndCast<const InverseTransformTransition*>(other); - return new InverseTransformTransition( - other_inverse->base_transform_, other_inverse->uninverted_transition_); - } - - protected: - void OnStart(LayerAnimationDelegate* delegate) override { - gfx::Transform start(delegate->GetTransformForAnimation()); - effective_start_ = base_transform_ * start; - - TargetValue target; - uninverted_transition_->GetTargetValue(&target); - base_target_ = target.transform; - - set_tween_type(uninverted_transition_->tween_type()); - - TransformAnimationCurveAdapter base_curve(tween_type(), - base_transform_, - base_target_, - duration()); - - animation_curve_.reset(new InverseTransformCurveAdapter( - base_curve, start, duration())); - computed_target_transform_ = ComputeWithBaseTransform(effective_start_, - base_target_); - } - - void OnAbort(LayerAnimationDelegate* delegate) override { - if (delegate && Started()) { - ThreadedLayerAnimationElement::OnAbort(delegate); - delegate->SetTransformFromAnimation(ComputeCurrentTransform()); - } - } - - void OnEnd(LayerAnimationDelegate* delegate) override { - delegate->SetTransformFromAnimation(computed_target_transform_); - } - - std::unique_ptr<cc::Animation> CreateCCAnimation() override { - std::unique_ptr<cc::Animation> animation(cc::Animation::Create( - animation_curve_->Clone(), animation_id(), animation_group_id(), - cc::TargetProperty::TRANSFORM)); - return animation; - } - - void OnGetTarget(TargetValue* target) const override { - target->transform = computed_target_transform_; - } - - private: - gfx::Transform ComputeCurrentTransform() const { - gfx::Transform base_current = gfx::Tween::TransformValueBetween( - gfx::Tween::CalculateValue(tween_type(), last_progressed_fraction()), - base_transform_, - base_target_); - return ComputeWithBaseTransform(effective_start_, base_current); - } - - gfx::Transform ComputeWithBaseTransform(gfx::Transform start, - gfx::Transform target) const { - gfx::Transform to_return(gfx::Transform::kSkipInitialization); - bool success = target.GetInverse(&to_return); - DCHECK(success) << "Target transform must be invertible."; - - to_return.PreconcatTransform(start); - return to_return; - } - - template <typename T> - static T CheckAndCast(const LayerAnimationElement* element) { - AnimatableProperties properties = element->properties(); - DCHECK(properties & TRANSFORM); - return static_cast<T>(element); - } - - gfx::Transform effective_start_; - gfx::Transform computed_target_transform_; - - const gfx::Transform base_transform_; - gfx::Transform base_target_; - - std::unique_ptr<cc::AnimationCurve> animation_curve_; - - const ThreadedTransformTransition* const uninverted_transition_; - - DISALLOW_COPY_AND_ASSIGN(InverseTransformTransition); -}; - } // namespace // LayerAnimationElement::TargetValue ------------------------------------------ @@ -778,19 +605,6 @@ } // static -LayerAnimationElement* LayerAnimationElement::CreateInverseTransformElement( - const gfx::Transform& base_transform, - const LayerAnimationElement* uninverted_transition) { - return new InverseTransformTransition(base_transform, uninverted_transition); -} - -// static -LayerAnimationElement* LayerAnimationElement::CloneInverseTransformElement( - const LayerAnimationElement* other) { - return InverseTransformTransition::Clone(other); -} - -// static LayerAnimationElement* LayerAnimationElement::CreateInterpolatedTransformElement( InterpolatedTransform* interpolated_transform,
diff --git a/ui/compositor/layer_animation_element.h b/ui/compositor/layer_animation_element.h index 111f254..aaeb51c 100644 --- a/ui/compositor/layer_animation_element.h +++ b/ui/compositor/layer_animation_element.h
@@ -74,19 +74,6 @@ const gfx::Transform& transform, base::TimeDelta duration); - // Creates an element that counters a transition to the given transform. - // This element maintains the invariant uninverted_transition->at(t) * - // this->at(t) == base_transform * this->at(t_start) for any t. The caller - // owns the return value. - static LayerAnimationElement* CreateInverseTransformElement( - const gfx::Transform& base_transform, - const LayerAnimationElement* uninverted_transition); - - - // Duplicates elements as created by CreateInverseTransformElement. - static LayerAnimationElement* CloneInverseTransformElement( - const LayerAnimationElement* other); - // Creates an element that transitions to another in a way determined by an // interpolated transform. The element accepts ownership of the interpolated // transform. NB: at every step, the interpolated transform clobbers the
diff --git a/ui/compositor/layer_animation_element_unittest.cc b/ui/compositor/layer_animation_element_unittest.cc index 6acd9d6..7d21939 100644 --- a/ui/compositor/layer_animation_element_unittest.cc +++ b/ui/compositor/layer_animation_element_unittest.cc
@@ -97,68 +97,6 @@ CheckApproximatelyEqual(target_transform, target_value.transform); } -// Ensures that duration is copied correctly. -TEST(LayerAnimationElementTest, InverseElementDurationNoScale) { - gfx::Transform transform; - base::TimeDelta delta; - - std::unique_ptr<LayerAnimationElement> base_element( - LayerAnimationElement::CreateTransformElement(transform, delta)); - - std::unique_ptr<LayerAnimationElement> inverse_element( - LayerAnimationElement::CreateInverseTransformElement(transform, - base_element.get())); - EXPECT_EQ(base_element->duration(), inverse_element->duration()); -} - -// Ensures that duration is copied correctly and not double scaled. -TEST(LayerAnimationElementTest, InverseElementDurationScaled) { - gfx::Transform transform; - base::TimeDelta delta; - - ScopedAnimationDurationScaleMode faster_duration( - ScopedAnimationDurationScaleMode::FAST_DURATION); - std::unique_ptr<LayerAnimationElement> base_element( - LayerAnimationElement::CreateTransformElement(transform, delta)); - - std::unique_ptr<LayerAnimationElement> inverse_element( - LayerAnimationElement::CreateInverseTransformElement(transform, - base_element.get())); - EXPECT_EQ(base_element->duration(), inverse_element->duration()); -} - -// Ensures that the GetTargetTransform() method works as intended. -TEST(LayerAnimationElementTest, InverseElementTargetCalculation) { - base::TimeTicks start_time; - base::TimeDelta delta = base::TimeDelta::FromSeconds(1); - start_time += delta; - - gfx::Transform identity, transform; - - transform.Scale3d(2.0, 2.0, 2.0); - - std::unique_ptr<LayerAnimationElement> base_element( - LayerAnimationElement::CreateTransformElement(transform, delta)); - std::unique_ptr<LayerAnimationElement> inverse_element( - LayerAnimationElement::CreateInverseTransformElement(identity, - base_element.get())); - - base_element->set_requested_start_time(start_time); - inverse_element->set_requested_start_time(start_time); - - TestLayerAnimationDelegate delegate; - delegate.SetTransformFromAnimation(transform); - - base_element->Start(&delegate, 1); - inverse_element->Start(&delegate, 1); - LayerAnimationElement::TargetValue target; - inverse_element->GetTargetValue(&target); - - EXPECT_TRUE(target.transform.IsIdentity()) - << "Target should be identity such that the initial 2x scale from the start" - << " carries over at end when parent is doubled."; -} - // Check that the bounds element progresses the delegate as expected and // that the element can be reused after it completes. TEST(LayerAnimationElementTest, BoundsElement) {
diff --git a/ui/compositor/test/context_factories_for_test.cc b/ui/compositor/test/context_factories_for_test.cc index 78aac8d..174f341 100644 --- a/ui/compositor/test/context_factories_for_test.cc +++ b/ui/compositor/test/context_factories_for_test.cc
@@ -15,7 +15,7 @@ namespace { static cc::SurfaceManager* g_surface_manager = nullptr; -static ui::ContextFactory* g_implicit_factory = NULL; +static ui::InProcessContextFactory* g_implicit_factory = NULL; static gl::DisableNullDrawGLBindings* g_disable_null_draw = NULL; } // namespace @@ -39,8 +39,11 @@ } void TerminateContextFactoryForTests() { - delete g_implicit_factory; - g_implicit_factory = NULL; + if (g_implicit_factory) { + g_implicit_factory->SendOnLostResources(); + delete g_implicit_factory; + g_implicit_factory = NULL; + } delete g_surface_manager; g_surface_manager = nullptr; delete g_disable_null_draw;
diff --git a/ui/display/chromeos/x11/native_display_delegate_x11.cc b/ui/display/chromeos/x11/native_display_delegate_x11.cc index 81dfcfa..614ec9b 100644 --- a/ui/display/chromeos/x11/native_display_delegate_x11.cc +++ b/ui/display/chromeos/x11/native_display_delegate_x11.cc
@@ -115,7 +115,7 @@ platform_event_dispatcher_.get()); } - STLDeleteContainerPairSecondPointers(modes_.begin(), modes_.end()); + base::STLDeleteContainerPairSecondPointers(modes_.begin(), modes_.end()); } void NativeDisplayDelegateX11::Initialize() { @@ -285,7 +285,7 @@ void NativeDisplayDelegateX11::InitModes() { CHECK(screen_) << "Server not grabbed"; - STLDeleteContainerPairSecondPointers(modes_.begin(), modes_.end()); + base::STLDeleteContainerPairSecondPointers(modes_.begin(), modes_.end()); modes_.clear(); for (int i = 0; i < screen_->nmode; ++i) {
diff --git a/ui/events/blink/input_handler_proxy.cc b/ui/events/blink/input_handler_proxy.cc index 821a386..115c21a9 100644 --- a/ui/events/blink/input_handler_proxy.cc +++ b/ui/events/blink/input_handler_proxy.cc
@@ -733,7 +733,7 @@ blink::WebSize())); disallow_horizontal_fling_scroll_ = !vx; disallow_vertical_fling_scroll_ = !vy; - TRACE_EVENT_ASYNC_BEGIN2("input,benchmark", + TRACE_EVENT_ASYNC_BEGIN2("input,benchmark,rail", "InputHandlerProxy::HandleGestureFling::started", this, "vx", vx, "vy", vy); // Note that the timestamp will only be used to kickstart the animation if @@ -751,7 +751,7 @@ } case cc::InputHandler::SCROLL_UNKNOWN: case cc::InputHandler::SCROLL_ON_MAIN_THREAD: { - TRACE_EVENT_INSTANT0("input", + TRACE_EVENT_INSTANT0("input,rail", "InputHandlerProxy::HandleGestureFling::" "scroll_on_main_thread", TRACE_EVENT_SCOPE_THREAD); @@ -762,7 +762,7 @@ } case cc::InputHandler::SCROLL_IGNORED: { TRACE_EVENT_INSTANT0( - "input", + "input,rail", "InputHandlerProxy::HandleGestureFling::ignored", TRACE_EVENT_SCOPE_THREAD); gesture_scroll_on_impl_thread_ = false;
diff --git a/ui/events/blink/input_handler_proxy_unittest.cc b/ui/events/blink/input_handler_proxy_unittest.cc index fbb5dddeb..e3057a4 100644 --- a/ui/events/blink/input_handler_proxy_unittest.cc +++ b/ui/events/blink/input_handler_proxy_unittest.cc
@@ -126,6 +126,13 @@ cc::ScrollElasticityHelper* CreateScrollElasticityHelper() override { return NULL; } + bool GetScrollOffsetForLayer(int layer_id, + gfx::ScrollOffset* offset) override { + return false; + } + bool ScrollLayerTo(int layer_id, const gfx::ScrollOffset& offset) override { + return false; + } void BindToClient(cc::InputHandlerClient* client) override {}
diff --git a/ui/events/cocoa/cocoa_event_utils.h b/ui/events/cocoa/cocoa_event_utils.h index a5984357..71ddab95 100644 --- a/ui/events/cocoa/cocoa_event_utils.h +++ b/ui/events/cocoa/cocoa_event_utils.h
@@ -11,6 +11,9 @@ namespace ui { +// Conversion between wheel delta amounts and number of pixels to scroll. +constexpr double kScrollbarPixelsPerCocoaTick = 40.0; + // Converts the Cocoa |modifiers| bitsum into a ui::EventFlags bitsum. EVENTS_EXPORT int EventFlagsFromModifiers(NSUInteger modifiers);
diff --git a/ui/events/cocoa/events_mac.mm b/ui/events/cocoa/events_mac.mm index dbfd64c..48c955d 100644 --- a/ui/events/cocoa/events_mac.mm +++ b/ui/events/cocoa/events_mac.mm
@@ -140,8 +140,7 @@ } gfx::Vector2d GetMouseWheelOffset(const base::NativeEvent& event) { - if ([event respondsToSelector:@selector(hasPreciseScrollingDeltas)] && - [event hasPreciseScrollingDeltas]) { + if ([event hasPreciseScrollingDeltas]) { // Handle continuous scrolling devices such as a Magic Mouse or a trackpad. // -scrollingDelta{X|Y} have float return types but they return values that // are already rounded to integers. @@ -153,10 +152,11 @@ // values when scrolling up or to the left. Scrolling quickly results in a // higher delta per click, up to about 15.0. (Quartz documentation suggests // +/-10). - // Multiply by 1000 to vaguely approximate WHEEL_DELTA on Windows (120). - const CGFloat kWheelDeltaMultiplier = 1000; - return gfx::Vector2d(kWheelDeltaMultiplier * [event deltaX], - kWheelDeltaMultiplier * [event deltaY]); + // Use the same multiplier as content::WebMouseWheelEventBuilder. Note this + // differs from the value returned by CGEventSourceGetPixelsPerLine(), which + // is typically 10. + return gfx::Vector2d(kScrollbarPixelsPerCocoaTick * [event deltaX], + kScrollbarPixelsPerCocoaTick * [event deltaY]); } }
diff --git a/ui/events/cocoa/events_mac_unittest.mm b/ui/events/cocoa/events_mac_unittest.mm index 926cfb0..e30202f3 100644 --- a/ui/events/cocoa/events_mac_unittest.mm +++ b/ui/events/cocoa/events_mac_unittest.mm
@@ -37,6 +37,9 @@ return window_location; } + // TODO(tapted): Move this to cocoa_test_event_utils. It's not a drop-in + // replacement because -[NSApp sendEvent:] may route events generated this way + // differently. NSEvent* TestMouseEvent(CGEventType type, const gfx::Point& window_location, CGEventFlags event_flags) { @@ -46,53 +49,23 @@ // just assume "other" means the third/center mouse button, and rely on // Quartz ignoring it when the type is not "other". CGMouseButton other_button = kCGMouseButtonCenter; - base::ScopedCFTypeRef<CGEventRef> mouse(CGEventCreateMouseEvent( - nullptr, type, TestWindowPointToScreen(window_location), other_button)); + CGPoint screen_point = cocoa_test_event_utils::ScreenPointFromWindow( + Flip(window_location).ToCGPoint(), test_window()); + base::ScopedCFTypeRef<CGEventRef> mouse( + CGEventCreateMouseEvent(nullptr, type, screen_point, other_button)); CGEventSetFlags(mouse, event_flags); - return EventWithTestWindow(mouse); + return cocoa_test_event_utils::AttachWindowToCGEvent(mouse, test_window()); } + // Creates a scroll event from a "real" mouse wheel (i.e. not a trackpad). NSEvent* TestScrollEvent(const gfx::Point& window_location, int32_t delta_x, int32_t delta_y) { - base::ScopedCFTypeRef<CGEventRef> scroll(CGEventCreateScrollWheelEvent( - nullptr, kCGScrollEventUnitLine, 2, delta_y, delta_x)); - CGEventSetLocation(scroll, TestWindowPointToScreen(window_location)); - return EventWithTestWindow(scroll); + return cocoa_test_event_utils::TestScrollEvent( + Flip(window_location).ToCGPoint(), test_window(), delta_x, delta_y); } private: - CGPoint TestWindowPointToScreen(const gfx::Point& window_location) { - // CGEvents are always in global display coordinates. These are like screen - // coordinates, but flipped. But first the point needs to be converted out - // of window coordinates (which also requires flipping). - NSPoint window_point = - NSPointFromCGPoint(Flip(window_location).ToCGPoint()); - NSRect window_rect = NSMakeRect(window_point.x, window_point.y, 0, 0); - NSPoint screen_point = - [test_window() convertRectToScreen:window_rect].origin; - CGFloat primary_screen_height = - NSHeight([[[NSScreen screens] firstObject] frame]); - screen_point.y = primary_screen_height - screen_point.y; - return NSPointToCGPoint(screen_point); - } - - NSEvent* EventWithTestWindow(CGEventRef event) { - // These CGEventFields were made public in the 10.7 SDK, but don't help to - // populate the -[NSEvent window] pointer when creating an event with - // +[NSEvent eventWithCGEvent:]. Set that separately, using reflection. - CGEventSetIntegerValueField(event, kCGMouseEventWindowUnderMousePointer, - [test_window() windowNumber]); - CGEventSetIntegerValueField( - event, kCGMouseEventWindowUnderMousePointerThatCanHandleThisEvent, - [test_window() windowNumber]); - NSEvent* ns_event = [NSEvent eventWithCGEvent:event]; - EXPECT_EQ(nil, [ns_event window]); // Verify assumptions. - [ns_event setValue:test_window() forKey:@"_window"]; - EXPECT_EQ(test_window(), [ns_event window]); - return ns_event; - } - DISALLOW_COPY_AND_ASSIGN(EventsMacTest); };
diff --git a/ui/events/gestures/gesture_recognizer_impl.cc b/ui/events/gestures/gesture_recognizer_impl.cc index 3f7198df..9f948608 100644 --- a/ui/events/gestures/gesture_recognizer_impl.cc +++ b/ui/events/gestures/gesture_recognizer_impl.cc
@@ -64,7 +64,7 @@ } GestureRecognizerImpl::~GestureRecognizerImpl() { - STLDeleteValues(&consumer_gesture_provider_); + base::STLDeleteValues(&consumer_gesture_provider_); } // Checks if this finger is already down, if so, returns the current target.
diff --git a/ui/events/latency_info.cc b/ui/events/latency_info.cc index a5cb1ec..d84dec8 100644 --- a/ui/events/latency_info.cc +++ b/ui/events/latency_info.cc
@@ -119,7 +119,7 @@ : value_(value) { } -const char kTraceCategoriesForAsyncEvents[] = "benchmark,latencyInfo"; +const char kTraceCategoriesForAsyncEvents[] = "benchmark,latencyInfo,rail"; struct LatencyInfoEnabledInitializer { LatencyInfoEnabledInitializer() :
diff --git a/ui/events/ozone/evdev/input_device_factory_evdev.cc b/ui/events/ozone/evdev/input_device_factory_evdev.cc index fe958f4..5bf30b70 100644 --- a/ui/events/ozone/evdev/input_device_factory_evdev.cc +++ b/ui/events/ozone/evdev/input_device_factory_evdev.cc
@@ -189,7 +189,7 @@ } InputDeviceFactoryEvdev::~InputDeviceFactoryEvdev() { - STLDeleteValues(&converters_); + base::STLDeleteValues(&converters_); } void InputDeviceFactoryEvdev::AddInputDevice(int id,
diff --git a/ui/events/ozone/evdev/touch_noise/touch_noise_finder.cc b/ui/events/ozone/evdev/touch_noise/touch_noise_finder.cc index 553b1f6..c2057ab 100644 --- a/ui/events/ozone/evdev/touch_noise/touch_noise_finder.cc +++ b/ui/events/ozone/evdev/touch_noise/touch_noise_finder.cc
@@ -21,7 +21,7 @@ } TouchNoiseFinder::~TouchNoiseFinder() { - STLDeleteElements(&filters_); + base::STLDeleteElements(&filters_); } void TouchNoiseFinder::HandleTouches(
diff --git a/ui/events/test/cocoa_test_event_utils.h b/ui/events/test/cocoa_test_event_utils.h index 0b9992c..5e138878 100644 --- a/ui/events/test/cocoa_test_event_utils.h +++ b/ui/events/test/cocoa_test_event_utils.h
@@ -15,6 +15,15 @@ namespace cocoa_test_event_utils { +// Converts |window_point| in |window| coordinates (origin at bottom left of +// window frame) to a point in global display coordinates for a CGEvent (origin +// at top left of primary screen). +CGPoint ScreenPointFromWindow(NSPoint window_point, NSWindow* window); + +// Converts |event| to an NSEvent with a timestamp from ui::EventTimeForNow(), +// and attaches |window| to it. +NSEvent* AttachWindowToCGEvent(CGEventRef event, NSWindow* window); + // Create synthetic mouse events for testing. Currently these are very // basic, flesh out as needed. Points are all in window coordinates; // where the window is not specified, coordinate system is undefined @@ -41,6 +50,16 @@ std::pair<NSEvent*, NSEvent*> RightMouseClickInView(NSView* view, NSUInteger clickCount); +// Creates a test scroll event. Currently only events for a "real" mouse wheel +// are supported (-hasPreciseScrollingDeltas is NO). If |window| is nil, +// |location| is assumed to be AppKit screen coordinates (origin in bottom left +// of primary screen). +// TODO(tapted): Add event phase arguments to support trackpad scrolls also. +NSEvent* TestScrollEvent(NSPoint location, + NSWindow* window, + CGFloat delta_x, + CGFloat delta_y); + // Returns a key event with the given character. NSEvent* KeyEventWithCharacter(unichar c);
diff --git a/ui/events/test/cocoa_test_event_utils.mm b/ui/events/test/cocoa_test_event_utils.mm index 35326df..4903825 100644 --- a/ui/events/test/cocoa_test_event_utils.mm +++ b/ui/events/test/cocoa_test_event_utils.mm
@@ -6,12 +6,49 @@ #include <stdint.h> +#include "base/mac/scoped_cftyperef.h" #include "base/time/time.h" #include "ui/events/base_event_utils.h" #import "ui/events/keycodes/keyboard_code_conversion_mac.h" namespace cocoa_test_event_utils { +CGPoint ScreenPointFromWindow(NSPoint window_point, NSWindow* window) { + NSRect window_rect = NSMakeRect(window_point.x, window_point.y, 0, 0); + NSPoint screen_point = window + ? [window convertRectToScreen:window_rect].origin + : window_rect.origin; + CGFloat primary_screen_height = + NSHeight([[[NSScreen screens] firstObject] frame]); + screen_point.y = primary_screen_height - screen_point.y; + return NSPointToCGPoint(screen_point); +} + +NSEvent* AttachWindowToCGEvent(CGEventRef event, NSWindow* window) { + // These CGEventFields were made public in the 10.7 SDK, but don't help to + // populate the -[NSEvent window] pointer when creating an event with + // +[NSEvent eventWithCGEvent:]. Set that separately, using reflection. + CGEventSetIntegerValueField(event, kCGMouseEventWindowUnderMousePointer, + [window windowNumber]); + CGEventSetIntegerValueField( + event, kCGMouseEventWindowUnderMousePointerThatCanHandleThisEvent, + [window windowNumber]); + + // CGEventTimestamp is nanoseconds since system startup as a 64-bit integer. + // Use EventTimeForNow() so that it can be mocked for tests. + CGEventTimestamp timestamp = + (ui::EventTimeForNow() - base::TimeTicks()).InMicroseconds() * + base::Time::kNanosecondsPerMicrosecond; + CGEventSetTimestamp(event, timestamp); + + NSEvent* ns_event = [NSEvent eventWithCGEvent:event]; + DCHECK_EQ(nil, [ns_event window]); // Verify assumptions. + [ns_event setValue:window forKey:@"_window"]; + DCHECK_EQ(window, [ns_event window]); + + return ns_event; +} + NSEvent* MouseEventAtPoint(NSPoint point, NSEventType type, NSUInteger modifiers) { if (type == NSOtherMouseUp) { @@ -98,6 +135,20 @@ return std::make_pair(down, up); } +NSEvent* TestScrollEvent(NSPoint location, + NSWindow* window, + CGFloat delta_x, + CGFloat delta_y) { + const uint32_t wheel_count = 2; + int32_t wheel1 = static_cast<int>(delta_y); + int32_t wheel2 = static_cast<int>(delta_x); + CGScrollEventUnit units = kCGScrollEventUnitLine; + base::ScopedCFTypeRef<CGEventRef> scroll(CGEventCreateScrollWheelEvent( + nullptr, units, wheel_count, wheel1, wheel2)); + CGEventSetLocation(scroll, ScreenPointFromWindow(location, window)); + return AttachWindowToCGEvent(scroll, window); +} + NSEvent* KeyEventWithCharacter(unichar c) { return KeyEventWithKeyCode(0, c, NSKeyDown, 0); }
diff --git a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js index cfb4b1e..317e979 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js +++ b/ui/file_manager/file_manager/foreground/js/ui/directory_tree.js
@@ -28,7 +28,7 @@ // The Drive root volume item "Google Drive" and its child "My Drive" have // the same entry. When we look for a tree item of Drive's root directory, // "My Drive" should be returned, as we use "Google Drive" for grouping - // "My Drive", "Shared with me", "Recent", and "Offine". + // "My Drive", "Shared with me", "Recent", and "Offline". // Therefore, we have to skip "Google Drive" here. if (item instanceof DriveVolumeItem) return item.getItemByEntry(entry); @@ -122,6 +122,8 @@ item.hasChildren = false; item.label = label; + item.setAttribute('aria-label', label); + return item; }
diff --git a/ui/gfx/BUILD.gn b/ui/gfx/BUILD.gn index 3a2db59..ef375d5 100644 --- a/ui/gfx/BUILD.gn +++ b/ui/gfx/BUILD.gn
@@ -4,6 +4,7 @@ import("//build/config/ui.gni") import("//testing/test.gni") +import("//testing/libfuzzer/fuzzer_test.gni") if (is_android) { import("//build/config/android/config.gni") @@ -742,3 +743,13 @@ jni_package = "gfx" } } + +fuzzer_test("color_transform_fuzztest") { + sources = [ + "color_transform_fuzzer.cc", + ] + deps = [ + ":gfx", + ] + libfuzzer_options = [ "max_len=1024" ] +}
diff --git a/ui/gfx/color_space.cc b/ui/gfx/color_space.cc index 1b16047..c3a8975c 100644 --- a/ui/gfx/color_space.cc +++ b/ui/gfx/color_space.cc
@@ -64,4 +64,32 @@ matrix_ == other.matrix_ && range_ == other.range_; } +bool ColorSpace::operator!=(const ColorSpace& other) const { + return !(*this == other); +} + +bool ColorSpace::operator<(const ColorSpace& other) const { + if (primaries_ < other.primaries_) + return true; + if (primaries_ > other.primaries_) + return false; + if (transfer_ < other.transfer_) + return true; + if (transfer_ > other.transfer_) + return false; + if (matrix_ < other.matrix_) + return true; + if (matrix_ > other.matrix_) + return false; + if (range_ < other.range_) + return true; + if (range_ > other.range_) + return true; + + // TODO(hubbe): For "CUSTOM" primaries or tranfer functions, compare their + // coefficients here + + return false; +} + } // namespace gfx
diff --git a/ui/gfx/color_space.h b/ui/gfx/color_space.h index 4ab4aa3..89bb0e8 100644 --- a/ui/gfx/color_space.h +++ b/ui/gfx/color_space.h
@@ -123,6 +123,8 @@ static ColorSpace CreateREC709(); bool operator==(const ColorSpace& other) const; + bool operator!=(const ColorSpace& other) const; + bool operator<(const ColorSpace& other) const; private: PrimaryID primaries_;
diff --git a/ui/gfx/color_transform_fuzzer.cc b/ui/gfx/color_transform_fuzzer.cc new file mode 100644 index 0000000..9732f8e --- /dev/null +++ b/ui/gfx/color_transform_fuzzer.cc
@@ -0,0 +1,23 @@ +// Copyright (c) 2016 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 <stddef.h> +#include <stdint.h> + +#include "base/at_exit.h" +#include "ui/gfx/color_space.h" +#include "ui/gfx/color_transform.h" +#include "ui/gfx/icc_profile.h" + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + base::AtExitManager at_exit; + gfx::ICCProfile icc = + gfx::ICCProfile::FromData(reinterpret_cast<const char*>(data), size); + gfx::ColorSpace bt709 = gfx::ColorSpace::CreateREC709(); + std::unique_ptr<gfx::ColorTransform> t(gfx::ColorTransform::NewColorTransform( + bt709, icc.GetColorSpace(), gfx::ColorTransform::Intent::ABSOLUTE)); + gfx::ColorTransform::TriStim tmp(16.0f / 255.0f, 0.5f, 0.5f); + t->transform(&tmp, 1); + return 0; +}
diff --git a/ui/gfx/color_transform_unittest.cc b/ui/gfx/color_transform_unittest.cc index 3203059..d943c7d 100644 --- a/ui/gfx/color_transform_unittest.cc +++ b/ui/gfx/color_transform_unittest.cc
@@ -336,13 +336,7 @@ 0x00, 0x00, 0x07, 0x94, 0x00, 0x00, 0xfd, 0x8f, 0xff, 0xff, 0xfb, 0xa1, 0xff, 0xff, 0xfd, 0xa2, 0x00, 0x00, 0x03, 0xdb, 0x00, 0x00, 0xc0, 0x75}; -// MSan detects an uninitialized read in QCMS. https://crbug.com/635042 -#if defined(MEMORY_SANITIZER) -#define MAYBE_BT709toSRGBICC DISABLED_BT709toSRGBICC -#else -#define MAYBE_BT709toSRGBICC BT709toSRGBICC -#endif -TEST(SimpleColorSpace, MAYBE_BT709toSRGBICC) { +TEST(SimpleColorSpace, BT709toSRGBICC) { ICCProfile srgb_icc = ICCProfile::FromData( reinterpret_cast<char*>(srgb_icc_data), arraysize(srgb_icc_data));
diff --git a/ui/gfx/icc_profile.h b/ui/gfx/icc_profile.h index 7a2ad768..df170592 100644 --- a/ui/gfx/icc_profile.h +++ b/ui/gfx/icc_profile.h
@@ -15,6 +15,8 @@ #include <CoreGraphics/CGColorSpace.h> #endif +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); + namespace gfx { // Used to represent a full ICC profile, usually retrieved from a monitor. It @@ -69,6 +71,7 @@ uint64_t id_ = 0; FRIEND_TEST_ALL_PREFIXES(SimpleColorSpace, BT709toSRGBICC); + friend int ::LLVMFuzzerTestOneInput(const uint8_t*, size_t); friend class ColorSpace; friend struct IPC::ParamTraits<gfx::ICCProfile>; };
diff --git a/ui/gfx/test/ui_cocoa_test_helper.h b/ui/gfx/test/ui_cocoa_test_helper.h index c3bd5658..ef27ef16 100644 --- a/ui/gfx/test/ui_cocoa_test_helper.h +++ b/ui/gfx/test/ui_cocoa_test_helper.h
@@ -11,6 +11,7 @@ #include "base/compiler_specific.h" #import "base/mac/scoped_nsautorelease_pool.h" +#import "base/mac/scoped_nsobject.h" #include "testing/platform_test.h" // Background windows normally will not display things such as focus
diff --git a/ui/gfx/vector_icons/system_menu_accessibility.1x.icon b/ui/gfx/vector_icons/system_menu_accessibility.1x.icon new file mode 100644 index 0000000..bd185994b --- /dev/null +++ b/ui/gfx/vector_icons/system_menu_accessibility.1x.icon
@@ -0,0 +1,25 @@ +// Copyright 2016 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. + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 10.04f, 6.27f, +R_CUBIC_TO, -2.64f, 0, -4.46f, 0.24f, -7.61f, -1.15f, +V_LINE_TO, 7, +R_CUBIC_TO, 1.55f, 0.53f, 2.9f, 0.8f, 4.57f, 1, +R_V_LINE_TO, 10, +R_H_LINE_TO, 2, +R_V_LINE_TO, -5, +R_H_LINE_TO, 2, +R_V_LINE_TO, 5, +R_H_LINE_TO, 2, +V_LINE_TO, 8, +R_CUBIC_TO, 1.67f, -0.2f, 2.95f, -0.47f, 4.5f, -1, +V_LINE_TO, 5.12f, +R_CUBIC_TO, -2.88f, 1.34f, -4.82f, 1.15f, -7.46f, 1.15f, +CLOSE, +MOVE_TO, 10, 5, +R_ARC_TO, 2, 2, 0, 1, 0, 0, -4, +R_ARC_TO, 2, 2, 0, 0, 0, 0, 4, +CLOSE, +END
diff --git a/ui/gfx/vector_icons/system_menu_accessibility.icon b/ui/gfx/vector_icons/system_menu_accessibility.icon index fe9b850..11bae49 100644 --- a/ui/gfx/vector_icons/system_menu_accessibility.icon +++ b/ui/gfx/vector_icons/system_menu_accessibility.icon
@@ -2,25 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -CANVAS_DIMENSIONS, 24, -MOVE_TO, 12, 2, -R_CUBIC_TO, 1.1f, 0, 2, 0.9f, 2, 2, -R_CUBIC_TO, 0, 1.1f, -0.9f, 2, -2, 2, -R_CUBIC_TO, -1.1f, 0, -2, -0.9f, -2, -2, -R_CUBIC_TO, 0, -1.1f, 0.9f, -2, 2, -2, +CANVAS_DIMENSIONS, 40, +MOVE_TO, 20, 13, +R_CUBIC_TO, -4.72f, -0.37f, -9.82f, -0.86f, -14, -2, +R_LINE_TO, -1, 3, +R_CUBIC_TO, 3.1f, 1.06f, 6.67f, 1.6f, 10, 2, +R_V_LINE_TO, 20, +R_H_LINE_TO, 3, +V_LINE_TO, 26, +R_H_LINE_TO, 4, +R_V_LINE_TO, 10, +R_H_LINE_TO, 3, +V_LINE_TO, 16, +R_CUBIC_TO, 3.33f, -0.4f, 6.9f, -0.94f, 10, -2, +R_LINE_TO, -1, -3, +R_CUBIC_TO, -4.18f, 1.14f, -9.28f, 1.63f, -14, 2, CLOSE, -R_MOVE_TO, 9, 7, -R_H_LINE_TO, -6, -R_V_LINE_TO, 13, -R_H_LINE_TO, -2, -R_V_LINE_TO, -6, -R_H_LINE_TO, -2, -R_V_LINE_TO, 6, -H_LINE_TO, 9, -V_LINE_TO, 9, -H_LINE_TO, 3, -V_LINE_TO, 7, -R_H_LINE_TO, 18, -R_V_LINE_TO, 2, +R_MOVE_TO, 0, -2, +R_ARC_TO, 3.5f, 3.5f, 0, 1, 0, 0, -7, +R_ARC_TO, 3.5f, 3.5f, 0, 0, 0, 0, 7, CLOSE, END
diff --git a/ui/gfx/vector_icons/system_menu_cast.1x.icon b/ui/gfx/vector_icons/system_menu_cast.1x.icon new file mode 100644 index 0000000..67581e7 --- /dev/null +++ b/ui/gfx/vector_icons/system_menu_cast.1x.icon
@@ -0,0 +1,47 @@ +// Copyright 2016 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. + +CANVAS_DIMENSIONS, 20, +PATH_COLOR_ARGB, 0xFF, 0x5A, 0x5A, 0x5A, +MOVE_TO, 2, 15.03f, +V_LINE_TO, 17, +R_H_LINE_TO, 2, +R_CUBIC_TO, 0, -1.09f, -0.89f, -1.97f, -2, -1.97f, +CLOSE, +R_MOVE_TO, 0, -3.15f, +R_V_LINE_TO, 1.46f, +R_CUBIC_TO, 2.05f, 0, 3.71f, 1.64f, 3.71f, 3.66f, +H_LINE_TO, 7.2f, +R_CUBIC_TO, 0, -2.83f, -2.33f, -5.12f, -5.2f, -5.12f, +CLOSE, +MOVE_TO, 2, 9.12f, +R_V_LINE_TO, 1.43f, +R_CUBIC_TO, 3.62f, 0, 6.55f, 2.89f, 6.55f, 6.45f, +H_LINE_TO, 10, +R_CUBIC_TO, 0, -4.36f, -3.58f, -7.88f, -8, -7.88f, +CLOSE, +MOVE_TO, 3.46f, 4, +CUBIC_TO, 2.66f, 4, 2, 4.65f, 2, 5.44f, +V_LINE_TO, 8, +R_H_LINE_TO, 2, +V_LINE_TO, 6, +R_H_LINE_TO, 12, +R_V_LINE_TO, 9, +R_H_LINE_TO, -5, +R_V_LINE_TO, 2, +R_H_LINE_TO, 5.55f, +R_CUBIC_TO, 0.8f, 0, 1.46f, -0.65f, 1.46f, -1.44f, +V_LINE_TO, 5.44f, +CUBIC_TO, 18, 4.65f, 17.35f, 4, 16.55f, 4, +H_LINE_TO, 3.46f, +CLOSE, +NEW_PATH, +MOVE_TO, 5, 7, +R_V_LINE_TO, 1.31f, +R_CUBIC_TO, 3.13f, 0.44f, 5.42f, 4.16f, 6.04f, 5.69f, +H_LINE_TO, 15, +V_LINE_TO, 7, +H_LINE_TO, 5, +CLOSE, +END
diff --git a/ui/gfx/vector_icons/system_menu_cast.icon b/ui/gfx/vector_icons/system_menu_cast.icon new file mode 100644 index 0000000..1b54407 --- /dev/null +++ b/ui/gfx/vector_icons/system_menu_cast.icon
@@ -0,0 +1,47 @@ +// Copyright 2016 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. + +CANVAS_DIMENSIONS, 40, +PATH_COLOR_ARGB, 0xFF, 0x5A, 0x5A, 0x5A, +MOVE_TO, 4, 30.06f, +V_LINE_TO, 34, +R_H_LINE_TO, 4, +R_CUBIC_TO, 0, -2.18f, -1.79f, -3.94f, -4, -3.94f, +CLOSE, +R_MOVE_TO, 0, -6.3f, +R_V_LINE_TO, 2.93f, +R_CUBIC_TO, 4.1f, 0, 7.43f, 3.28f, 7.43f, 7.32f, +H_LINE_TO, 14.4f, +R_CUBIC_TO, 0, -5.66f, -4.65f, -10.24f, -10.4f, -10.24f, +CLOSE, +R_MOVE_TO, 0, -5.52f, +R_V_LINE_TO, 2.87f, +R_CUBIC_TO, 7.23f, 0, 13.09f, 5.77f, 13.09f, 12.89f, +H_LINE_TO, 20, +R_CUBIC_TO, 0, -8.71f, -7.17f, -15.76f, -16, -15.76f, +CLOSE, +MOVE_TO, 6.91f, 8, +CUBIC_TO, 5.31f, 8, 4, 9.3f, 4, 10.89f, +V_LINE_TO, 15, +R_H_LINE_TO, 3, +R_V_LINE_TO, -4, +R_H_LINE_TO, 26, +R_V_LINE_TO, 20, +H_LINE_TO, 23, +R_V_LINE_TO, 3, +R_H_LINE_TO, 10.09f, +R_CUBIC_TO, 1.6f, 0, 2.91f, -1.3f, 2.91f, -2.89f, +V_LINE_TO, 10.89f, +CUBIC_TO, 36, 9.3f, 34.69f, 8, 33.09f, 8, +H_LINE_TO, 6.91f, +CLOSE, +NEW_PATH, +MOVE_TO, 10, 14, +R_V_LINE_TO, 2.63f, +CUBIC_TO, 16.25f, 17.5f, 20.83f, 24.94f, 22.08f, 28, +H_LINE_TO, 30, +V_LINE_TO, 14, +H_LINE_TO, 10, +CLOSE, +END
diff --git a/ui/gfx/vector_icons/system_menu_screen_share.1x.icon b/ui/gfx/vector_icons/system_menu_screen_share.1x.icon new file mode 100644 index 0000000..a94882e --- /dev/null +++ b/ui/gfx/vector_icons/system_menu_screen_share.1x.icon
@@ -0,0 +1,28 @@ +// Copyright 2016 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. + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 14.5f, 14, +R_CUBIC_TO, 0.5f, 0, 1.5f, -0.5f, 1.5f, -1.5f, +R_V_LINE_TO, -6, +R_CUBIC_TO, 0, -1, -0.5f, -1.5f, -1.5f, -1.5f, +R_H_LINE_TO, -9, +CUBIC_TO, 4.5f, 5, 4, 5.5f, 4, 6.5f, +R_V_LINE_TO, 6, +R_CUBIC_TO, 0, 1, 0.5f, 1.5f, 1.5f, 1.5f, +H_LINE_TO, 2, +R_V_LINE_TO, 1, +R_H_LINE_TO, 16, +R_V_LINE_TO, -1, +R_H_LINE_TO, -3.5f, +CLOSE, +R_MOVE_TO, -3.81f, -2.5f, +R_V_LINE_TO, -1, +R_CUBIC_TO, -1.76f, -0.2f, -2.86f, 0.33f, -3.69f, 1.5f, +R_CUBIC_TO, 0.34f, -1.67f, 1.27f, -3.33f, 3.69f, -3.5f, +V_LINE_TO, 7, +LINE_TO, 13, 9.5f, +R_LINE_TO, -2.31f, 2, +CLOSE, +END
diff --git a/ui/gfx/vector_icons/system_menu_screen_share.icon b/ui/gfx/vector_icons/system_menu_screen_share.icon new file mode 100644 index 0000000..c77310e --- /dev/null +++ b/ui/gfx/vector_icons/system_menu_screen_share.icon
@@ -0,0 +1,28 @@ +// Copyright 2016 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. + +CANVAS_DIMENSIONS, 40, +MOVE_TO, 31, 28, +R_CUBIC_TO, 1.13f, -0.5f, 2.32f, -1.62f, 2, -3, +V_LINE_TO, 13, +R_CUBIC_TO, 0.33f, -1.89f, -0.87f, -3, -2, -3, +H_LINE_TO, 9, +R_CUBIC_TO, -1.15f, 0, -2.33f, 1.11f, -2, 3, +R_V_LINE_TO, 12, +R_CUBIC_TO, -0.33f, 1.38f, 0.85f, 2.5f, 2, 3, +H_LINE_TO, 4, +R_V_LINE_TO, 2, +R_H_LINE_TO, 32, +R_V_LINE_TO, -2, +R_H_LINE_TO, -5, +CLOSE, +R_MOVE_TO, -10, -5, +R_V_LINE_TO, -2, +R_CUBIC_TO, -3.81f, -0.4f, -6.19f, 0.66f, -8, 3, +R_CUBIC_TO, 0.73f, -3.34f, 2.74f, -6.66f, 8, -7, +R_V_LINE_TO, -3, +R_LINE_TO, 5, 5, +R_LINE_TO, -5, 4, +CLOSE, +END
diff --git a/ui/gfx/vector_icons/system_tray_accessibility.1x.icon b/ui/gfx/vector_icons/system_tray_accessibility.1x.icon index 6c494140..0187049 100644 --- a/ui/gfx/vector_icons/system_tray_accessibility.1x.icon +++ b/ui/gfx/vector_icons/system_tray_accessibility.1x.icon
@@ -3,22 +3,25 @@ // found in the LICENSE file. CANVAS_DIMENSIONS, 16, -MOVE_TO, 8, 5, -R_ARC_TO, 1.5f, 1.5f, 0, 1, 0, 0, -3, -R_ARC_TO, 1.5f, 1.5f, 0, 0, 0, 0, 3, -CLOSE, -R_MOVE_TO, 2, 2, -R_V_LINE_TO, 7, -H_LINE_TO, 9, +MOVE_TO, 8.5f, 6.87f, +CUBIC_TO, 6.92f, 6.87f, 5.88f, 6.8f, 4, 6, +R_V_LINE_TO, 1.24f, +CUBIC_TO, 5, 7.62f, 6, 8, 7, 8, +R_V_LINE_TO, 6, +R_H_LINE_TO, 1, R_V_LINE_TO, -3, -H_LINE_TO, 7, +R_H_LINE_TO, 1, R_V_LINE_TO, 3, -H_LINE_TO, 6, -V_LINE_TO, 7, -H_LINE_TO, 3, +R_H_LINE_TO, 1, +V_LINE_TO, 8, +R_CUBIC_TO, 1, 0, 2, -0.38f, 3, -0.76f, V_LINE_TO, 6, -R_H_LINE_TO, 10, -R_V_LINE_TO, 1, -R_H_LINE_TO, -3, +R_CUBIC_TO, -1.72f, 0.77f, -2.92f, 0.87f, -4.5f, 0.87f, +CLOSE, +R_MOVE_TO, 0.02f, -1.26f, +R_CUBIC_TO, 0.73f, 0, 1.33f, -0.58f, 1.33f, -1.31f, +CUBIC_TO, 9.85f, 3.59f, 9.25f, 3, 8.52f, 3, +R_CUBIC_TO, -0.73f, 0, -1.33f, 0.59f, -1.33f, 1.31f, +R_CUBIC_TO, 0, 0.72f, 0.6f, 1.31f, 1.33f, 1.31f, CLOSE, END
diff --git a/ui/gfx/vector_icons/system_tray_accessibility.icon b/ui/gfx/vector_icons/system_tray_accessibility.icon index 05bb6b26..8c3f1ce 100644 --- a/ui/gfx/vector_icons/system_tray_accessibility.icon +++ b/ui/gfx/vector_icons/system_tray_accessibility.icon
@@ -3,22 +3,23 @@ // found in the LICENSE file. CANVAS_DIMENSIONS, 32, -MOVE_TO, 16, 9, +MOVE_TO, 16, 11.44f, +R_CUBIC_TO, -3.5f, 0, -7.2f, -0.62f, -10.27f, -1.44f, +LINE_TO, 5, 12.16f, +R_CUBIC_TO, 2.27f, 0.77f, 5.56f, 1.05f, 8, 1.34f, +V_LINE_TO, 28, +R_H_LINE_TO, 2, +R_V_LINE_TO, -7, +R_H_LINE_TO, 2, +R_V_LINE_TO, 7, +R_H_LINE_TO, 2, +V_LINE_TO, 13.5f, +R_CUBIC_TO, 2.44f, -0.29f, 5.73f, -0.57f, 8, -1.34f, +LINE_TO, 26.27f, 10, +R_CUBIC_TO, -3.07f, 0.82f, -6.77f, 1.44f, -10.27f, 1.44f, +CLOSE, +R_MOVE_TO, 0, -1.94f, R_ARC_TO, 2.5f, 2.5f, 0, 1, 0, 0, -5, R_ARC_TO, 2.5f, 2.5f, 0, 0, 0, 0, 5, CLOSE, -R_MOVE_TO, 4, 5, -R_V_LINE_TO, 14, -R_H_LINE_TO, -3, -R_V_LINE_TO, -8, -R_H_LINE_TO, -2, -R_V_LINE_TO, 8, -R_H_LINE_TO, -3, -V_LINE_TO, 14, -H_LINE_TO, 6, -R_V_LINE_TO, -3, -R_H_LINE_TO, 20, -R_V_LINE_TO, 3, -R_H_LINE_TO, -6, -CLOSE, END
diff --git a/ui/gfx/vector_icons/system_tray_cast.1x.icon b/ui/gfx/vector_icons/system_tray_cast.1x.icon new file mode 100644 index 0000000..3d540eb --- /dev/null +++ b/ui/gfx/vector_icons/system_tray_cast.1x.icon
@@ -0,0 +1,45 @@ +// Copyright 2016 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. + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 2, 11.5f, +V_LINE_TO, 13, +R_H_LINE_TO, 1.5f, +R_CUBIC_TO, 0, -0.83f, -0.67f, -1.5f, -1.5f, -1.5f, +CLOSE, +R_MOVE_TO, 0, -2, +R_V_LINE_TO, 1, +ARC_TO, 2.5f, 2.5f, 0, 0, 1, 4.5f, 13, +R_H_LINE_TO, 1, +R_CUBIC_TO, 0, -1.93f, -1.56f, -3.5f, -3.5f, -3.5f, +CLOSE, +MOVE_TO, 11, 6, +H_LINE_TO, 4, +R_V_LINE_TO, 0.82f, +ARC_TO, 6.52f, 6.52f, 0, 0, 1, 8.19f, 11, +H_LINE_TO, 11, +V_LINE_TO, 6, +CLOSE, +MOVE_TO, 2, 7.5f, +R_V_LINE_TO, 1, +ARC_TO, 4.5f, 4.5f, 0, 0, 1, 6.5f, 13, +R_H_LINE_TO, 1, +ARC_TO, 5.5f, 5.5f, 0, 0, 0, 2, 7.5f, +CLOSE, +MOVE_TO, 12, 4, +H_LINE_TO, 3, +R_CUBIC_TO, -0.55f, 0, -1, 0.45f, -1, 1, +R_V_LINE_TO, 1.5f, +R_H_LINE_TO, 1, +V_LINE_TO, 5, +R_H_LINE_TO, 9, +R_V_LINE_TO, 7, +H_LINE_TO, 8.5f, +R_V_LINE_TO, 1, +H_LINE_TO, 12, +R_CUBIC_TO, 0.55f, 0, 1, -0.45f, 1, -1, +V_LINE_TO, 5, +R_CUBIC_TO, 0, -0.55f, -0.45f, -1, -1, -1, +CLOSE, +END
diff --git a/ui/gfx/vector_icons/system_tray_cast.icon b/ui/gfx/vector_icons/system_tray_cast.icon new file mode 100644 index 0000000..7de458f --- /dev/null +++ b/ui/gfx/vector_icons/system_tray_cast.icon
@@ -0,0 +1,55 @@ +// Copyright 2016 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. + +CANVAS_DIMENSIONS, 32, +MOVE_TO, 4, 4, +R_H_LINE_TO, 24, +R_V_LINE_TO, 24, +H_LINE_TO, 4, +CLOSE, +MOVE_TO, 4, 4, +R_H_LINE_TO, 24, +R_V_LINE_TO, 24, +H_LINE_TO, 4, +CLOSE, +MOVE_TO, 5, 22, +R_V_LINE_TO, 3, +R_H_LINE_TO, 3, +R_CUBIC_TO, 0, -1.66f, -1.34f, -3, -3, -3, +CLOSE, +R_MOVE_TO, 0, -4, +R_V_LINE_TO, 2, +R_CUBIC_TO, 2.76f, 0, 5, 2.24f, 5, 5, +R_H_LINE_TO, 2, +R_CUBIC_TO, 0, -3.87f, -3.13f, -7, -7, -7, +CLOSE, +R_MOVE_TO, 18, -7, +H_LINE_TO, 9, +R_V_LINE_TO, 1.63f, +R_CUBIC_TO, 3.96f, 1.28f, 7.09f, 4.41f, 8.37f, 8.37f, +H_LINE_TO, 23, +V_LINE_TO, 11, +CLOSE, +MOVE_TO, 5, 14, +R_V_LINE_TO, 2, +R_ARC_TO, 9, 9, 0, 0, 1, 9, 9, +R_H_LINE_TO, 2, +R_CUBIC_TO, 0, -6.08f, -4.93f, -11, -11, -11, +CLOSE, +R_MOVE_TO, 20, -7, +H_LINE_TO, 7, +R_CUBIC_TO, -1.1f, 0, -2, 0.9f, -2, 2, +R_V_LINE_TO, 3, +R_H_LINE_TO, 2, +V_LINE_TO, 9, +R_H_LINE_TO, 18, +R_V_LINE_TO, 14, +R_H_LINE_TO, -7, +R_V_LINE_TO, 2, +R_H_LINE_TO, 7, +R_CUBIC_TO, 1.1f, 0, 2, -0.9f, 2, -2, +V_LINE_TO, 9, +R_CUBIC_TO, 0, -1.1f, -0.9f, -2, -2, -2, +CLOSE, +END
diff --git a/ui/gfx/vector_icons/system_tray_screen_share.1x.icon b/ui/gfx/vector_icons/system_tray_screen_share.1x.icon new file mode 100644 index 0000000..4667ae3f --- /dev/null +++ b/ui/gfx/vector_icons/system_tray_screen_share.1x.icon
@@ -0,0 +1,28 @@ +// Copyright 2016 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. + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 14, 10.5f, +R_V_LINE_TO, -6, +R_CUBIC_TO, 0.17f, -0.92f, -0.43f, -1.5f, -1, -1.5f, +H_LINE_TO, 3, +R_CUBIC_TO, -0.57f, 0, -1.17f, 0.58f, -1, 1.5f, +R_V_LINE_TO, 6, +R_CUBIC_TO, 0, 1, 1, 1.5f, 1.5f, 1.5f, +H_LINE_TO, 1, +R_V_LINE_TO, 1, +R_H_LINE_TO, 14, +R_V_LINE_TO, -1, +R_H_LINE_TO, -2.25f, +R_CUBIC_TO, 0.5f, 0, 1.25f, -0.5f, 1.25f, -1.5f, +CLOSE, +MOVE_TO, 9, 8, +R_CUBIC_TO, -2.2f, 0.13f, -3.46f, 0.71f, -4.5f, 2, +CUBIC_TO, 4.92f, 8.16f, 5.97f, 6.34f, 9, 6, +V_LINE_TO, 4.5f, +LINE_TO, 12, 7, +LINE_TO, 9, 9.5f, +V_LINE_TO, 8, +CLOSE, +END
diff --git a/ui/gfx/vector_icons/system_tray_screen_share.icon b/ui/gfx/vector_icons/system_tray_screen_share.icon new file mode 100644 index 0000000..3041e16 --- /dev/null +++ b/ui/gfx/vector_icons/system_tray_screen_share.icon
@@ -0,0 +1,28 @@ +// Copyright 2016 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. + +CANVAS_DIMENSIONS, 32, +MOVE_TO, 28, 20.5f, +V_LINE_TO, 9, +R_CUBIC_TO, 0.33f, -1.83f, -0.87f, -3, -2, -3, +H_LINE_TO, 6, +CUBIC_TO, 4.85f, 6, 3.67f, 7.17f, 4, 9, +R_V_LINE_TO, 11.5f, +R_CUBIC_TO, 0, 1, 1.5f, 2.5f, 2.5f, 2.5f, +H_LINE_TO, 2, +R_V_LINE_TO, 3, +R_H_LINE_TO, 28, +R_V_LINE_TO, -3, +R_H_LINE_TO, -4.5f, +R_CUBIC_TO, 1, 0, 2.5f, -1.5f, 2.5f, -2.5f, +CLOSE, +MOVE_TO, 17, 19, +R_V_LINE_TO, -3, +R_CUBIC_TO, -3.81f, 0.26f, -6.19f, 1.43f, -8, 4, +R_CUBIC_TO, 0.73f, -3.67f, 2.74f, -7.33f, 8, -8, +V_LINE_TO, 9, +R_LINE_TO, 5, 5, +R_LINE_TO, -5, 5, +CLOSE, +END
diff --git a/ui/gfx/vector_icons_sources.gypi b/ui/gfx/vector_icons_sources.gypi index ff315fb8..fbb42e5 100644 --- a/ui/gfx/vector_icons_sources.gypi +++ b/ui/gfx/vector_icons_sources.gypi
@@ -133,6 +133,7 @@ 'vector_icons/subresource_filter_active.icon', 'vector_icons/supervisor_account.icon', 'vector_icons/sync_problem.icon', + 'vector_icons/system_menu_accessibility.1x.icon', 'vector_icons/system_menu_accessibility.icon', 'vector_icons/system_menu_arrow_right.1x.icon', 'vector_icons/system_menu_arrow_right.icon', @@ -141,8 +142,12 @@ 'vector_icons/system_menu_bluetooth_disabled.1x.icon', 'vector_icons/system_menu_bluetooth_disabled.icon', 'vector_icons/system_menu_caps_lock.icon', + 'vector_icons/system_menu_cast.1x.icon', + 'vector_icons/system_menu_cast.icon', 'vector_icons/system_menu_rotation_lock_auto.icon', 'vector_icons/system_menu_rotation_lock_locked.icon', + 'vector_icons/system_menu_screen_share.1x.icon', + 'vector_icons/system_menu_screen_share.icon', 'vector_icons/system_menu_sms.icon', 'vector_icons/system_tray_accessibility.1x.icon', 'vector_icons/system_tray_accessibility.icon', @@ -158,8 +163,12 @@ 'vector_icons/system_tray_battery_x.icon', 'vector_icons/system_tray_caps_lock.1x.icon', 'vector_icons/system_tray_caps_lock.icon', + 'vector_icons/system_tray_cast.1x.icon', + 'vector_icons/system_tray_cast.icon', 'vector_icons/system_tray_rotation_lock_locked.1x.icon', 'vector_icons/system_tray_rotation_lock_locked.icon', + 'vector_icons/system_tray_screen_share.1x.icon', + 'vector_icons/system_tray_screen_share.icon', 'vector_icons/system_tray_update.1x.icon', 'vector_icons/system_tray_update.icon', 'vector_icons/system_tray_volume_mute.1x.icon',
diff --git a/ui/gfx/win/window_impl.cc b/ui/gfx/win/window_impl.cc index 4a9cbf600..f774468 100644 --- a/ui/gfx/win/window_impl.cc +++ b/ui/gfx/win/window_impl.cc
@@ -213,20 +213,6 @@ reinterpret_cast<wchar_t*>(atom), NULL, window_style_, x, y, width, height, parent, NULL, NULL, this); - if (hwnd && base::win::IsProcessPerMonitorDpiAware()) { - static auto enable_child_window_dpi_message_func = []() { - // Derived signature; not available in headers. - // This call gets Windows to scale the non-client area when WM_DPICHANGED - // is fired. - using EnableChildWindowDpiMessagePtr = LRESULT (WINAPI*)(HWND, BOOL); - return reinterpret_cast<EnableChildWindowDpiMessagePtr>( - GetProcAddress(GetModuleHandle(L"user32.dll"), - "EnableChildWindowDpiMessage")); - }(); - if (enable_child_window_dpi_message_func) - enable_child_window_dpi_message_func(hwnd, TRUE); - } - // First nccalcszie (during CreateWindow) for captioned windows is // deliberately ignored so force a second one here to get the right // non-client set up.
diff --git a/ui/gl/BUILD.gn b/ui/gl/BUILD.gn index 111d07f..d2a6c3c 100644 --- a/ui/gl/BUILD.gn +++ b/ui/gl/BUILD.gn
@@ -231,10 +231,6 @@ "//third_party/angle:libGLESv2", "//third_party/mesa:osmesa", ] - - if (is_official_build) { - include_dirs += [ "//third_party/swiftshader/include" ] - } } if (is_mac) { sources += [
diff --git a/ui/gl/gl_gl_api_implementation.cc b/ui/gl/gl_gl_api_implementation.cc index 4cf6515..68b9171 100644 --- a/ui/gl/gl_gl_api_implementation.cc +++ b/ui/gl/gl_gl_api_implementation.cc
@@ -572,7 +572,7 @@ const char* gl_extension = reinterpret_cast<const char*>( GLApiBase::glGetStringiFn(GL_EXTENSIONS, i)); DCHECK(gl_extension != NULL); - if (!ContainsValue(disabled_exts_, gl_extension)) + if (!base::ContainsValue(disabled_exts_, gl_extension)) filtered_exts_.push_back(gl_extension); } filtered_exts_str_ = base::JoinString(filtered_exts_, " ");
diff --git a/ui/gl/init/BUILD.gn b/ui/gl/init/BUILD.gn index 55bb9c7..761c226 100644 --- a/ui/gl/init/BUILD.gn +++ b/ui/gl/init/BUILD.gn
@@ -40,10 +40,6 @@ libs = [ "dwmapi.lib" ] ldflags = [ "/DELAYLOAD:dwmapi.dll" ] - - if (is_official_build) { - include_dirs = [ "//third_party/swiftshader/include" ] - } } else if (is_mac) { sources += [ "gl_factory_mac.cc",
diff --git a/ui/gl/init/gl_factory.cc b/ui/gl/init/gl_factory.cc index 3fad83d4..3c17fc7 100644 --- a/ui/gl/init/gl_factory.cc +++ b/ui/gl/init/gl_factory.cc
@@ -43,7 +43,7 @@ impl = kGLImplementationEGLGLES2; } else { impl = GetNamedGLImplementation(requested_implementation_name); - if (!ContainsValue(allowed_impls, impl)) { + if (!base::ContainsValue(allowed_impls, impl)) { LOG(ERROR) << "Requested GL implementation is not available."; return false; }
diff --git a/ui/gl/init/gl_initializer_win.cc b/ui/gl/init/gl_initializer_win.cc index daf9014..d1c3fe9d 100644 --- a/ui/gl/init/gl_initializer_win.cc +++ b/ui/gl/init/gl_initializer_win.cc
@@ -30,10 +30,6 @@ #include "ui/gl/gl_wgl_api_implementation.h" #include "ui/gl/vsync_provider_win.h" -#if defined(ENABLE_SWIFTSHADER) -#include "software_renderer.h" -#endif - namespace gl { namespace init { @@ -145,7 +141,13 @@ #if defined(ENABLE_SWIFTSHADER) if (using_swift_shader) { - SetupSoftwareRenderer(gles_library); + // Register key so that SwiftShader doesn't display watermark logo. + typedef void (__stdcall *RegisterFunc)(const char* key); + RegisterFunc reg = reinterpret_cast<RegisterFunc>( + base::GetFunctionPointerFromNativeLibrary(gles_library, "Register")); + if (reg) { + reg("SS3GCKK6B448CF63"); + } } #endif
diff --git a/ui/message_center/message_center_impl.cc b/ui/message_center/message_center_impl.cc index 9b5ffb9c..b5f3412e 100644 --- a/ui/message_center/message_center_impl.cc +++ b/ui/message_center/message_center_impl.cc
@@ -385,7 +385,7 @@ } void MessageCenterImpl::AddNotificationBlocker(NotificationBlocker* blocker) { - if (ContainsValue(blockers_, blocker)) + if (base::ContainsValue(blockers_, blocker)) return; blocker->AddObserver(this);
diff --git a/ui/message_center/notification_list.cc b/ui/message_center/notification_list.cc index 9231602..03cfd0f 100644 --- a/ui/message_center/notification_list.cc +++ b/ui/message_center/notification_list.cc
@@ -61,7 +61,8 @@ } NotificationList::~NotificationList() { - STLDeleteContainerPointers(notifications_.begin(), notifications_.end()); + base::STLDeleteContainerPointers(notifications_.begin(), + notifications_.end()); } void NotificationList::SetNotificationsShown(
diff --git a/ui/message_center/popup_timers_controller.cc b/ui/message_center/popup_timers_controller.cc index c50d7e6..f0d0652 100644 --- a/ui/message_center/popup_timers_controller.cc +++ b/ui/message_center/popup_timers_controller.cc
@@ -79,7 +79,7 @@ } void PopupTimersController::TimerFinished(const std::string& id) { - if (!ContainsKey(popup_timers_, id)) + if (!base::ContainsKey(popup_timers_, id)) return; CancelTimer(id);
diff --git a/ui/message_center/views/message_center_view.cc b/ui/message_center/views/message_center_view.cc index 254b272..63a61329 100644 --- a/ui/message_center/views/message_center_view.cc +++ b/ui/message_center/views/message_center_view.cc
@@ -528,6 +528,16 @@ else SetVisibilityMode(Mode::NOTIFICATIONS, animate); + if (no_message_views) { + scroller_->SetFocusBehavior(FocusBehavior::NEVER); + } else { +#if defined(OS_MACOSX) + scroller_->SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); +#else + scroller_->SetFocusBehavior(FocusBehavior::ALWAYS); +#endif + } + UpdateButtonBarStatus(); if (focus_manager && focused_view)
diff --git a/ui/message_center/views/message_center_view_unittest.cc b/ui/message_center/views/message_center_view_unittest.cc index 4a70667..3e18eada51 100644 --- a/ui/message_center/views/message_center_view_unittest.cc +++ b/ui/message_center/views/message_center_view_unittest.cc
@@ -236,7 +236,7 @@ widget_->CloseNow(); widget_.reset(); message_center_view_.reset(); - STLDeleteElements(¬ifications_); + base::STLDeleteElements(¬ifications_); views::ViewsTestBase::TearDown(); }
diff --git a/ui/message_center/views/message_list_view.cc b/ui/message_center/views/message_list_view.cc index 100f686..f2efc22 100644 --- a/ui/message_center/views/message_list_view.cc +++ b/ui/message_center/views/message_list_view.cc
@@ -185,7 +185,8 @@ has_deferred_task_ = false; // cancel cause OnBoundsAnimatorDone which deletes |deleted_when_done_|. animator_.Cancel(); - STLDeleteContainerPointers(deleting_views_.begin(), deleting_views_.end()); + base::STLDeleteContainerPointers(deleting_views_.begin(), + deleting_views_.end()); deleting_views_.clear(); adding_views_.clear(); } @@ -226,8 +227,8 @@ } void MessageListView::OnBoundsAnimatorDone(views::BoundsAnimator* animator) { - STLDeleteContainerPointers(deleted_when_done_.begin(), - deleted_when_done_.end()); + base::STLDeleteContainerPointers(deleted_when_done_.begin(), + deleted_when_done_.end()); deleted_when_done_.clear(); if (clear_all_started_) {
diff --git a/ui/message_center/views/notification_view.cc b/ui/message_center/views/notification_view.cc index aa77085..54f3557 100644 --- a/ui/message_center/views/notification_view.cc +++ b/ui/message_center/views/notification_view.cc
@@ -632,8 +632,8 @@ if (new_buttons || buttons.size() == 0) { // STLDeleteElements also clears the container. - STLDeleteElements(&separators_); - STLDeleteElements(&action_buttons_); + base::STLDeleteElements(&separators_); + base::STLDeleteElements(&action_buttons_); } DCHECK(bottom_view_);
diff --git a/ui/views/accessibility/ax_aura_obj_cache.cc b/ui/views/accessibility/ax_aura_obj_cache.cc index 9bd021e..28162c3 100644 --- a/ui/views/accessibility/ax_aura_obj_cache.cc +++ b/ui/views/accessibility/ax_aura_obj_cache.cc
@@ -122,7 +122,7 @@ AXAuraObjCache::~AXAuraObjCache() { is_destroying_ = true; - STLDeleteContainerPairSecondPointers(cache_.begin(), cache_.end()); + base::STLDeleteContainerPairSecondPointers(cache_.begin(), cache_.end()); cache_.clear(); }
diff --git a/ui/views/accessibility/native_view_accessibility_auralinux.cc b/ui/views/accessibility/native_view_accessibility_auralinux.cc index cd54ecf..4a0351a 100644 --- a/ui/views/accessibility/native_view_accessibility_auralinux.cc +++ b/ui/views/accessibility/native_view_accessibility_auralinux.cc
@@ -46,7 +46,7 @@ return; widget = widget->GetTopLevelWidget(); - if (ContainsValue(widgets_, widget)) + if (base::ContainsValue(widgets_, widget)) return; widgets_.push_back(widget);
diff --git a/ui/views/controls/menu/menu_item_view.cc b/ui/views/controls/menu/menu_item_view.cc index 8e3013b..d36350e1 100644 --- a/ui/views/controls/menu/menu_item_view.cc +++ b/ui/views/controls/menu/menu_item_view.cc
@@ -526,7 +526,7 @@ } } - STLDeleteElements(&removed_items_); + base::STLDeleteElements(&removed_items_); } void MenuItemView::Layout() { @@ -599,7 +599,7 @@ MenuItemView::~MenuItemView() { delete submenu_; - STLDeleteElements(&removed_items_); + base::STLDeleteElements(&removed_items_); } const char* MenuItemView::GetClassName() const {
diff --git a/ui/views/controls/menu/native_menu_win.cc b/ui/views/controls/menu/native_menu_win.cc index e205fda..b737cbf 100644 --- a/ui/views/controls/menu/native_menu_win.cc +++ b/ui/views/controls/menu/native_menu_win.cc
@@ -57,7 +57,7 @@ NativeMenuWin::~NativeMenuWin() { if (destroyed_flag_) *destroyed_flag_ = true; - STLDeleteContainerPointers(items_.begin(), items_.end()); + base::STLDeleteContainerPointers(items_.begin(), items_.end()); DestroyMenu(menu_); }
diff --git a/ui/views/controls/scroll_view.cc b/ui/views/controls/scroll_view.cc index a3e1e97..8cdb69b 100644 --- a/ui/views/controls/scroll_view.cc +++ b/ui/views/controls/scroll_view.cc
@@ -4,14 +4,16 @@ #include "ui/views/controls/scroll_view.h" +#include "base/feature_list.h" #include "base/logging.h" #include "base/macros.h" #include "ui/events/event.h" #include "ui/gfx/canvas.h" #include "ui/native_theme/native_theme.h" +#include "ui/views/background.h" #include "ui/views/border.h" #include "ui/views/style/platform_style.h" -#include "ui/views/widget/root_view.h" +#include "ui/views/widget/widget.h" namespace views { @@ -19,6 +21,15 @@ namespace { +const base::Feature kToolkitViewsScrollWithLayers { + "ToolkitViewsScrollWithLayers", +#if defined(OS_MACOSX) + base::FEATURE_ENABLED_BY_DEFAULT +#else + base::FEATURE_DISABLED_BY_DEFAULT +#endif +}; + // Subclass of ScrollView that resets the border when the theme changes. class ScrollViewWithBorder : public views::ScrollView { public: @@ -64,15 +75,31 @@ } // Make sure the content is not scrolled out of bounds -void CheckScrollBounds(View* viewport, View* view) { +void ConstrainScrollToBounds(View* viewport, View* view) { if (!view) return; - int x = CheckScrollBounds(viewport->width(), view->width(), -view->x()); - int y = CheckScrollBounds(viewport->height(), view->height(), -view->y()); + // Note that even when ScrollView::ScrollsWithLayers() is true, the header row + // scrolls by repainting. + const bool scrolls_with_layers = viewport->layer() != nullptr; + if (scrolls_with_layers) { + DCHECK(view->layer()); + DCHECK_EQ(0, view->x()); + DCHECK_EQ(0, view->y()); + } + gfx::ScrollOffset offset = scrolls_with_layers + ? view->layer()->CurrentScrollOffset() + : gfx::ScrollOffset(-view->x(), -view->y()); - // This is no op if bounds are the same - view->SetBounds(-x, -y, view->width(), view->height()); + int x = CheckScrollBounds(viewport->width(), view->width(), offset.x()); + int y = CheckScrollBounds(viewport->height(), view->height(), offset.y()); + + if (scrolls_with_layers) { + view->layer()->SetScrollOffset(gfx::ScrollOffset(x, y)); + } else { + // This is no op if bounds are the same + view->SetBounds(-x, -y, view->width(), view->height()); + } } // Used by ScrollToPosition() to make sure the new position fits within the @@ -105,9 +132,18 @@ View* contents = child_at(0); gfx::Rect scroll_rect(rect); - scroll_rect.Offset(-contents->x(), -contents->y()); - static_cast<ScrollView*>(parent())->ScrollContentsRegionToBeVisible( - scroll_rect); + + ScrollView* scroll_view = static_cast<ScrollView*>(parent()); + if (scroll_view->ScrollsWithLayers()) { + // With layer scrolling, there's no need to "undo" the offset done in the + // child's View::ScrollRectToVisible() before it calls this. + DCHECK_EQ(0, contents->x()); + DCHECK_EQ(0, contents->y()); + } else { + scroll_rect.Offset(-contents->x(), -contents->y()); + } + + scroll_view->ScrollContentsRegionToBeVisible(scroll_rect); } void ChildPreferredSizeChanged(View* child) override { @@ -129,6 +165,7 @@ corner_view_(new ScrollCornerView()), min_height_(-1), max_height_(-1), + background_color_(SK_ColorTRANSPARENT), hide_horizontal_scrollbar_(false) { set_notify_enter_exit_on_child(true); @@ -142,6 +179,15 @@ vert_sb_->SetVisible(false); vert_sb_->set_controller(this); corner_view_->SetVisible(false); + + if (!base::FeatureList::IsEnabled(kToolkitViewsScrollWithLayers)) + return; + + background_color_ = SK_ColorWHITE; + contents_viewport_->set_background( + Background::CreateSolidBackground(background_color_)); + contents_viewport_->SetPaintToLayer(true); + contents_viewport_->layer()->SetMasksToBounds(true); } ScrollView::~ScrollView() { @@ -158,6 +204,18 @@ } void ScrollView::SetContents(View* a_view) { + // Protect against clients passing a contents view that has its own Layer. + DCHECK(!a_view->layer()); + if (ScrollsWithLayers()) { + if (!a_view->background() && background_color_ != SK_ColorTRANSPARENT) { + a_view->set_background( + Background::CreateSolidBackground(background_color_)); + } + a_view->SetPaintToLayer(true); + a_view->layer()->SetScrollable( + contents_viewport_->layer(), + base::Bind(&ScrollView::OnLayerScrolled, base::Unretained(this))); + } SetHeaderOrContents(contents_viewport_, a_view, &contents_); } @@ -165,11 +223,23 @@ SetHeaderOrContents(header_viewport_, header, &header_); } +void ScrollView::SetBackgroundColor(SkColor color) { + background_color_ = color; + contents_viewport_->set_background( + Background::CreateSolidBackground(background_color_)); + if (contents_ && ScrollsWithLayers() && + background_color_ != SK_ColorTRANSPARENT) { + contents_->set_background( + Background::CreateSolidBackground(background_color_)); + } +} + gfx::Rect ScrollView::GetVisibleRect() const { if (!contents_) return gfx::Rect(); - return gfx::Rect(-contents_->x(), -contents_->y(), - contents_viewport_->width(), contents_viewport_->height()); + gfx::ScrollOffset offset = CurrentOffset(); + return gfx::Rect(offset.x(), offset.y(), contents_viewport_->width(), + contents_viewport_->height()); } void ScrollView::ClipHeightTo(int min_height, int max_height) { @@ -329,13 +399,22 @@ if (should_layout_contents && contents_) contents_->Layout(); + // Even when |contents_| needs to scroll, it can still be narrower or wider + // the viewport. So ensure the scrolling layer can fill the viewport, so that + // events will correctly hit it, and overscroll looks correct. + if (contents_ && ScrollsWithLayers()) { + gfx::Size container_size = contents_ ? contents_->size() : gfx::Size(); + container_size.SetToMax(viewport_bounds.size()); + contents_->SetBoundsRect(gfx::Rect(container_size)); + } + header_viewport_->SetBounds(contents_x, contents_y, viewport_bounds.width(), header_height); if (header_) header_->Layout(); - CheckScrollBounds(header_viewport_, header_); - CheckScrollBounds(contents_viewport_, contents_); + ConstrainScrollToBounds(header_viewport_, header_); + ConstrainScrollToBounds(contents_viewport_, contents_); SchedulePaint(); UpdateScrollBarPositions(); } @@ -406,24 +485,24 @@ if (!contents_) return; + gfx::ScrollOffset offset = CurrentOffset(); if (source == horiz_sb_ && horiz_sb_->visible()) { - position = AdjustPosition(contents_->x(), position, contents_->width(), + position = AdjustPosition(offset.x(), position, contents_->width(), contents_viewport_->width()); - if (-contents_->x() == position) + if (offset.x() == position) return; - contents_->SetX(-position); - if (header_) { - header_->SetX(-position); - header_->SchedulePaintInRect(header_->GetVisibleBounds()); - } + offset.set_x(position); } else if (source == vert_sb_ && vert_sb_->visible()) { - position = AdjustPosition(contents_->y(), position, contents_->height(), + position = AdjustPosition(offset.y(), position, contents_->height(), contents_viewport_->height()); - if (-contents_->y() == position) + if (offset.y() == position) return; - contents_->SetY(-position); + offset.set_y(position); } - contents_->SchedulePaintInRect(contents_->GetVisibleBounds()); + ScrollToOffset(offset); + + if (!ScrollsWithLayers()) + contents_->SchedulePaintInRect(contents_->GetVisibleBounds()); } int ScrollView::GetScrollIncrement(ScrollBar* source, bool is_page, @@ -504,10 +583,7 @@ (vis_rect.y() > y) ? y : std::max(0, max_y - contents_viewport_->height()); - contents_->SetX(-new_x); - if (header_) - header_->SetX(-new_x); - contents_->SetY(-new_y); + ScrollToOffset(gfx::ScrollOffset(new_x, new_y)); UpdateScrollBarPositions(); } @@ -555,17 +631,59 @@ if (!contents_) return; + const gfx::ScrollOffset offset = CurrentOffset(); if (horiz_sb_->visible()) { int vw = contents_viewport_->width(); int cw = contents_->width(); - int origin = contents_->x(); - horiz_sb_->Update(vw, cw, -origin); + horiz_sb_->Update(vw, cw, offset.x()); } if (vert_sb_->visible()) { int vh = contents_viewport_->height(); int ch = contents_->height(); - int origin = contents_->y(); - vert_sb_->Update(vh, ch, -origin); + vert_sb_->Update(vh, ch, offset.y()); + } +} + +gfx::ScrollOffset ScrollView::CurrentOffset() const { + return ScrollsWithLayers() + ? contents_->layer()->CurrentScrollOffset() + : gfx::ScrollOffset(-contents_->x(), -contents_->y()); +} + +void ScrollView::ScrollToOffset(const gfx::ScrollOffset& offset) { + if (ScrollsWithLayers()) { + contents_->layer()->SetScrollOffset(offset); + + // TODO(tapted): Remove this call to OnLayerScrolled(). It's unnecessary, + // but will only be invoked (asynchronously) when a Compositor is present + // and commits a frame, which isn't true in some tests. + // See http://crbug.com/637521. + OnLayerScrolled(); + } else { + contents_->SetPosition(gfx::Point(-offset.x(), -offset.y())); + ScrollHeader(); + } +} + +bool ScrollView::ScrollsWithLayers() const { + // Just check for the presence of a layer since it's cheaper than querying the + // Feature flag each time. + return contents_viewport_->layer() != nullptr; +} + +void ScrollView::OnLayerScrolled() { + UpdateScrollBarPositions(); + ScrollHeader(); +} + +void ScrollView::ScrollHeader() { + if (!header_) + return; + + int x_offset = CurrentOffset().x(); + if (header_->x() != -x_offset) { + header_->SetX(-x_offset); + header_->SchedulePaintInRect(header_->GetVisibleBounds()); } }
diff --git a/ui/views/controls/scroll_view.h b/ui/views/controls/scroll_view.h index 42348fc5..8973aee 100644 --- a/ui/views/controls/scroll_view.h +++ b/ui/views/controls/scroll_view.h
@@ -12,6 +12,10 @@ #include "base/macros.h" #include "ui/views/controls/scrollbar/scroll_bar.h" +namespace gfx { +class ScrollOffset; +} + namespace views { namespace test { class ScrollViewTestApi; @@ -51,6 +55,11 @@ // Sets the header, deleting the previous header. void SetHeader(View* header); + // Sets the background color. The default is white when scrolling with layers, + // otherwise transparent. An opaque color when scrolling with layers ensures + // fonts can be drawn with subpixel antialiasing. + void SetBackgroundColor(SkColor color); + // Returns the visible region of the content View. gfx::Rect GetVisibleRect() const; @@ -125,6 +134,20 @@ // Update the scrollbars positions given viewport and content sizes. void UpdateScrollBarPositions(); + // Helpers to get and set the current scroll offset (either from the ui::Layer + // or from the |contents_| origin offset). + gfx::ScrollOffset CurrentOffset() const; + void ScrollToOffset(const gfx::ScrollOffset& offset); + + // Whether the ScrollView scrolls using ui::Layer APIs. + bool ScrollsWithLayers() const; + + // Callback entrypoint when hosted Layers are scrolled by the Compositor. + void OnLayerScrolled(); + + // Horizontally scrolls the header (if any) to match the contents. + void ScrollHeader(); + // The current contents and its viewport. |contents_| is contained in // |contents_viewport_|. View* contents_; @@ -149,6 +172,10 @@ int min_height_; int max_height_; + // The background color given to the viewport (for overscroll), and to the + // contents when scrolling with layers. + SkColor background_color_; + // If true, never show the horizontal scrollbar (even if the contents is wider // than the viewport). bool hide_horizontal_scrollbar_;
diff --git a/ui/views/controls/scroll_view_unittest.cc b/ui/views/controls/scroll_view_unittest.cc index b18ebe76..dd8b2322 100644 --- a/ui/views/controls/scroll_view_unittest.cc +++ b/ui/views/controls/scroll_view_unittest.cc
@@ -5,6 +5,9 @@ #include "ui/views/controls/scroll_view.h" #include "base/macros.h" +#include "base/run_loop.h" +#include "base/test/test_timeouts.h" +#include "base/threading/thread_task_runner_handle.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/views/border.h" #include "ui/views/controls/scrollbar/base_scroll_bar_thumb.h" @@ -46,7 +49,14 @@ return GetBaseScrollBar(orientation)->thumb_; } + gfx::Point IntegralViewOffset() { + return gfx::Point() - gfx::ScrollOffsetToFlooredVector2d(CurrentOffset()); + } + + gfx::ScrollOffset CurrentOffset() { return scroll_view_->CurrentOffset(); } + View* corner_view() { return scroll_view_->corner_view_; } + View* contents_viewport() { return scroll_view_->contents_viewport_; } private: ScrollView* scroll_view_; @@ -72,6 +82,8 @@ PreferredSizeChanged(); } + const gfx::Point last_location() const { return last_location_; } + gfx::Size GetPreferredSize() const override { return preferred_size_; } void Layout() override { @@ -85,8 +97,14 @@ SetBounds(x(), y(), width, height); } + bool OnMousePressed(const ui::MouseEvent& event) override { + last_location_ = event.location(); + return true; + } + private: gfx::Size preferred_size_; + gfx::Point last_location_; DISALLOW_COPY_AND_ASSIGN(CustomView); }; @@ -115,7 +133,8 @@ using test::ScrollViewTestApi; // Test harness that includes a Widget to help test ui::Event handling. -class WidgetScrollViewTest : public test::WidgetTest { +class WidgetScrollViewTest : public test::WidgetTest, + public ui::CompositorObserver { public: static const int kDefaultHeight = 100; static const int kDefaultWidth = 100; @@ -127,34 +146,82 @@ #endif } - // Adds a ScrollView with a contents view of the given |size| and does layout. - ScrollView* AddScrollViewWithContentSize(const gfx::Size& contents_size) { + // Adds a ScrollView with the given |contents_view| and does layout. + ScrollView* AddScrollViewWithContents(View* contents, + bool commit_layers = true) { const gfx::Rect default_bounds(50, 50, kDefaultWidth, kDefaultHeight); widget_ = CreateTopLevelFramelessPlatformWidget(); ScrollView* scroll_view = new ScrollView(); - View* contents = new View; scroll_view->SetContents(contents); - contents->SetSize(contents_size); widget_->SetBounds(default_bounds); widget_->Show(); widget_->SetContentsView(scroll_view); scroll_view->Layout(); + + widget_->GetCompositor()->AddObserver(this); + + // Ensure the Compositor has committed layer changes before attempting to + // use them for impl-side scrolling. Note that simply RunUntilIdle() works + // when tests are run in isolation, but compositor scheduling can interact + // between test runs in the general case. + if (commit_layers) + WaitForCommit(); return scroll_view; } + // Adds a ScrollView with a contents view of the given |size| and does layout. + ScrollView* AddScrollViewWithContentSize(const gfx::Size& contents_size, + bool commit_layers = true) { + View* contents = new View; + contents->SetSize(contents_size); + return AddScrollViewWithContents(contents, commit_layers); + } + + // Wait for a commit to be observed on the compositor. + void WaitForCommit() { + base::RunLoop run_loop; + quit_closure_ = run_loop.QuitClosure(); + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, quit_closure_, TestTimeouts::action_timeout()); + run_loop.Run(); + EXPECT_TRUE(quit_closure_.is_null()) << "Timed out waiting for a commit."; + } + + void TestClickAt(const gfx::Point& location) { + ui::MouseEvent press(TestLeftMouseAt(location, ui::ET_MOUSE_PRESSED)); + ui::MouseEvent release(TestLeftMouseAt(location, ui::ET_MOUSE_RELEASED)); + widget_->OnMouseEvent(&press); + widget_->OnMouseEvent(&release); + } + // testing::Test: void TearDown() override { + widget_->GetCompositor()->RemoveObserver(this); if (widget_) widget_->CloseNow(); WidgetTest::TearDown(); } private: + // ui::CompositorObserver: + void OnCompositingDidCommit(ui::Compositor* compositor) override { + quit_closure_.Run(); + quit_closure_.Reset(); + } + void OnCompositingStarted(ui::Compositor* compositor, + base::TimeTicks start_time) override {} + void OnCompositingEnded(ui::Compositor* compositor) override {} + void OnCompositingAborted(ui::Compositor* compositor) override {} + void OnCompositingLockStateChanged(ui::Compositor* compositor) override {} + void OnCompositingShuttingDown(ui::Compositor* compositor) override {} + Widget* widget_ = nullptr; + base::Closure quit_closure_; + #if defined(OS_MACOSX) std::unique_ptr<ui::test::ScopedPreferredScrollerStyle> scroller_style_; #endif @@ -304,10 +371,25 @@ EXPECT_EQ("0,0 100x0", header->parent()->bounds().ToString()); EXPECT_EQ("0,0 100x100", contents->parent()->bounds().ToString()); + // With layered scrolling, ScrollView::Layout() will impose a size on the + // contents that fills the viewport. Since the test view doesn't have its own + // Layout, reset it in this case so that adding a header doesn't shift the + // contents down and require scrollbars. + if (contents->layer()) { + EXPECT_EQ("0,0 100x100", contents->bounds().ToString()); + contents->SetBoundsRect(gfx::Rect()); + } + EXPECT_EQ("0,0 0x0", contents->bounds().ToString()); + // Get the header a height of 20. header->SetPreferredSize(gfx::Size(10, 20)); EXPECT_EQ("0,0 100x20", header->parent()->bounds().ToString()); EXPECT_EQ("0,20 100x80", contents->parent()->bounds().ToString()); + if (contents->layer()) { + EXPECT_EQ("0,0 100x80", contents->bounds().ToString()); + contents->SetBoundsRect(gfx::Rect()); + } + EXPECT_EQ("0,0 0x0", contents->bounds().ToString()); // Remove the header. scroll_view.SetHeader(NULL); @@ -385,6 +467,7 @@ // Verifies the header scrolls horizontally with the content. TEST(ScrollViewTest, HeaderScrollsWithContent) { ScrollView scroll_view; + ScrollViewTestApi test_api(&scroll_view); CustomView* contents = new CustomView; scroll_view.SetContents(contents); contents->SetPreferredSize(gfx::Size(500, 500)); @@ -394,44 +477,53 @@ header->SetPreferredSize(gfx::Size(500, 20)); scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100)); - EXPECT_EQ("0,0", contents->bounds().origin().ToString()); + EXPECT_EQ("0,0", test_api.IntegralViewOffset().ToString()); EXPECT_EQ("0,0", header->bounds().origin().ToString()); // Scroll the horizontal scrollbar. ASSERT_TRUE(scroll_view.horizontal_scroll_bar()); scroll_view.ScrollToPosition( const_cast<ScrollBar*>(scroll_view.horizontal_scroll_bar()), 1); - EXPECT_EQ("-1,0", contents->bounds().origin().ToString()); + EXPECT_EQ("-1,0", test_api.IntegralViewOffset().ToString()); EXPECT_EQ("-1,0", header->bounds().origin().ToString()); // Scrolling the vertical scrollbar shouldn't effect the header. ASSERT_TRUE(scroll_view.vertical_scroll_bar()); scroll_view.ScrollToPosition( const_cast<ScrollBar*>(scroll_view.vertical_scroll_bar()), 1); - EXPECT_EQ("-1,-1", contents->bounds().origin().ToString()); + EXPECT_EQ("-1,-1", test_api.IntegralViewOffset().ToString()); EXPECT_EQ("-1,0", header->bounds().origin().ToString()); } // Verifies ScrollRectToVisible() on the child works. TEST(ScrollViewTest, ScrollRectToVisible) { +#if defined(OS_MACOSX) + ui::test::ScopedPreferredScrollerStyle scroller_style_override(false); +#endif ScrollView scroll_view; + ScrollViewTestApi test_api(&scroll_view); CustomView* contents = new CustomView; scroll_view.SetContents(contents); contents->SetPreferredSize(gfx::Size(500, 1000)); scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100)); scroll_view.Layout(); - EXPECT_EQ("0,0", contents->bounds().origin().ToString()); + EXPECT_EQ("0,0", test_api.IntegralViewOffset().ToString()); // Scroll to y=405 height=10, this should make the y position of the content // at (405 + 10) - viewport_height (scroll region bottom aligned). contents->ScrollRectToVisible(gfx::Rect(0, 405, 10, 10)); - const int viewport_height = contents->parent()->height(); - EXPECT_EQ(-(415 - viewport_height), contents->y()); + const int viewport_height = test_api.contents_viewport()->height(); + + // Expect there to be a horizontal scrollbar, making the viewport shorter. + EXPECT_LT(viewport_height, 100); + + gfx::ScrollOffset offset = test_api.CurrentOffset(); + EXPECT_EQ(415 - viewport_height, offset.y()); // Scroll to the current y-location and 10x10; should do nothing. - contents->ScrollRectToVisible(gfx::Rect(0, -contents->y(), 10, 10)); - EXPECT_EQ(-(415 - viewport_height), contents->y()); + contents->ScrollRectToVisible(gfx::Rect(0, offset.y(), 10, 10)); + EXPECT_EQ(415 - viewport_height, test_api.CurrentOffset().y()); } // Verifies ClipHeightTo() uses the height of the content when it is between the @@ -457,23 +549,29 @@ } // Verifies ClipHeightTo() uses the minimum height when the content is shorter -// thamn the minimum height value. +// than the minimum height value. TEST(ScrollViewTest, ClipHeightToShortContentHeight) { ScrollView scroll_view; scroll_view.ClipHeightTo(kMinHeight, kMaxHeight); const int kShortContentHeight = 10; - scroll_view.SetContents( - new views::StaticSizedView(gfx::Size(kWidth, kShortContentHeight))); + View* contents = + new views::StaticSizedView(gfx::Size(kWidth, kShortContentHeight)); + scroll_view.SetContents(contents); EXPECT_EQ(gfx::Size(kWidth, kMinHeight), scroll_view.GetPreferredSize()); scroll_view.SizeToPreferredSize(); scroll_view.Layout(); - EXPECT_EQ(gfx::Size(kWidth, kShortContentHeight), - scroll_view.contents()->size()); + // Layered scrolling requires the contents to fill the viewport. + if (contents->layer()) { + EXPECT_EQ(gfx::Size(kWidth, kMinHeight), scroll_view.contents()->size()); + } else { + EXPECT_EQ(gfx::Size(kWidth, kShortContentHeight), + scroll_view.contents()->size()); + } EXPECT_EQ(gfx::Size(kWidth, kMinHeight), scroll_view.size()); } @@ -628,6 +726,39 @@ } #endif +// Test that increasing the size of the viewport "below" scrolled content causes +// the content to scroll up so that it still fills the viewport. +TEST(ScrollViewTest, ConstrainScrollToBounds) { + ScrollView scroll_view; + ScrollViewTestApi test_api(&scroll_view); + + View* contents = new View; + contents->SetBoundsRect(gfx::Rect(0, 0, 300, 300)); + scroll_view.SetContents(contents); + scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 100)); + scroll_view.Layout(); + + EXPECT_EQ(gfx::ScrollOffset(), test_api.CurrentOffset()); + + // Scroll as far as it goes and query location to discount scroll bars. + contents->ScrollRectToVisible(gfx::Rect(300, 300, 1, 1)); + const gfx::ScrollOffset fully_scrolled = test_api.CurrentOffset(); + EXPECT_NE(gfx::ScrollOffset(), fully_scrolled); + + // Making the viewport 55 pixels taller should scroll up the same amount. + scroll_view.SetBoundsRect(gfx::Rect(0, 0, 100, 155)); + scroll_view.Layout(); + EXPECT_EQ(fully_scrolled.y() - 55, test_api.CurrentOffset().y()); + EXPECT_EQ(fully_scrolled.x(), test_api.CurrentOffset().x()); + + // And 77 pixels wider should scroll left. Also make it short again: the y- + // offset from the last change should remain. + scroll_view.SetBoundsRect(gfx::Rect(0, 0, 177, 100)); + scroll_view.Layout(); + EXPECT_EQ(fully_scrolled.y() - 55, test_api.CurrentOffset().y()); + EXPECT_EQ(fully_scrolled.x() - 77, test_api.CurrentOffset().x()); +} + // Test scrolling behavior when clicking on the scroll track. TEST_F(WidgetScrollViewTest, ScrollTrackScrolling) { // Set up with a vertical scroller. @@ -661,4 +792,95 @@ EXPECT_EQ(kDefaultHeight, scroll_view->GetVisibleRect().y()); } +// Test that LocatedEvents are transformed correctly when scrolling. +TEST_F(WidgetScrollViewTest, EventLocation) { + // Set up with both scrollers. + CustomView* contents = new CustomView; + contents->SetPreferredSize(gfx::Size(kDefaultHeight * 5, kDefaultHeight * 5)); + AddScrollViewWithContents(contents); + + const gfx::Point location_in_widget(10, 10); + + // Click without scrolling. + TestClickAt(location_in_widget); + EXPECT_EQ(location_in_widget, contents->last_location()); + + // Scroll down a page. + contents->ScrollRectToVisible( + gfx::Rect(0, kDefaultHeight, 1, kDefaultHeight)); + TestClickAt(location_in_widget); + EXPECT_EQ(gfx::Point(10, 10 + kDefaultHeight), contents->last_location()); + + // Scroll right a page (and back up). + contents->ScrollRectToVisible(gfx::Rect(kDefaultWidth, 0, kDefaultWidth, 1)); + TestClickAt(location_in_widget); + EXPECT_EQ(gfx::Point(10 + kDefaultWidth, 10), contents->last_location()); + + // Scroll both directions. + contents->ScrollRectToVisible( + gfx::Rect(kDefaultWidth, kDefaultHeight, kDefaultWidth, kDefaultHeight)); + TestClickAt(location_in_widget); + EXPECT_EQ(gfx::Point(10 + kDefaultWidth, 10 + kDefaultHeight), + contents->last_location()); +} + +// Test that views scroll offsets are in sync with the layer scroll offsets. +TEST_F(WidgetScrollViewTest, ScrollOffsetUsingLayers) { + // Set up with a vertical scroller, but don't commit the layer changes yet. + ScrollView* scroll_view = + AddScrollViewWithContentSize(gfx::Size(10, kDefaultHeight * 5), false); + ScrollViewTestApi test_api(scroll_view); + + EXPECT_EQ(gfx::ScrollOffset(0, 0), test_api.CurrentOffset()); + + // UI code may request a scroll before layer changes are committed. + gfx::Rect offset(0, kDefaultHeight * 2, 1, kDefaultHeight); + scroll_view->contents()->ScrollRectToVisible(offset); + EXPECT_EQ(gfx::ScrollOffset(0, offset.y()), test_api.CurrentOffset()); + + // The following only makes sense when layered scrolling is enabled. + View* container = scroll_view->contents(); +#if defined(OS_MACOSX) + // Sanity check: Mac should always scroll with layers. + EXPECT_TRUE(container->layer()); +#endif + if (!container->layer()) + return; + + // Container and viewport should have layers. + EXPECT_TRUE(container->layer()); + EXPECT_TRUE(test_api.contents_viewport()->layer()); + + // In a Widget, so there should be a compositor. + ui::Compositor* compositor = container->layer()->GetCompositor(); + EXPECT_TRUE(compositor); + + // But setting on the impl side should fail since the layer isn't committed. + int layer_id = container->layer()->cc_layer_for_testing()->id(); + EXPECT_FALSE(compositor->ScrollLayerTo(layer_id, gfx::ScrollOffset(0, 0))); + EXPECT_EQ(gfx::ScrollOffset(0, offset.y()), test_api.CurrentOffset()); + + WaitForCommit(); + EXPECT_EQ(gfx::ScrollOffset(0, offset.y()), test_api.CurrentOffset()); + + // Upon commit, the impl side should report the same value too. + gfx::ScrollOffset impl_offset; + EXPECT_TRUE(compositor->GetScrollOffsetForLayer(layer_id, &impl_offset)); + EXPECT_EQ(gfx::ScrollOffset(0, offset.y()), impl_offset); + + // Now impl-side scrolling should work, and also update the ScrollView. + offset.set_y(kDefaultHeight * 3); + EXPECT_TRUE( + compositor->ScrollLayerTo(layer_id, gfx::ScrollOffset(0, offset.y()))); + EXPECT_EQ(gfx::ScrollOffset(0, offset.y()), test_api.CurrentOffset()); + + // Scroll via ScrollView API. Should be reflected on the impl side. + offset.set_y(kDefaultHeight * 4); + scroll_view->contents()->ScrollRectToVisible(offset); + EXPECT_EQ(gfx::ScrollOffset(0, offset.y()), test_api.CurrentOffset()); + + EXPECT_TRUE(compositor->GetScrollOffsetForLayer(layer_id, &impl_offset)); + EXPECT_EQ(gfx::ScrollOffset(0, offset.y()), impl_offset); +} + } // namespace views
diff --git a/ui/views/controls/textfield/textfield_model.cc b/ui/views/controls/textfield/textfield_model.cc index bdcb552..db8e924 100644 --- a/ui/views/controls/textfield/textfield_model.cc +++ b/ui/views/controls/textfield/textfield_model.cc
@@ -706,7 +706,7 @@ } void TextfieldModel::ClearEditHistory() { - STLDeleteElements(&edit_history_); + base::STLDeleteElements(&edit_history_); current_edit_ = edit_history_.end(); } @@ -755,7 +755,7 @@ } EditHistory::iterator delete_start = current_edit_; ++delete_start; - STLDeleteContainerPointers(delete_start, edit_history_.end()); + base::STLDeleteContainerPointers(delete_start, edit_history_.end()); edit_history_.erase(delete_start, edit_history_.end()); }
diff --git a/ui/views/focus/view_storage.cc b/ui/views/focus/view_storage.cc index 204b31d..371e2d1 100644 --- a/ui/views/focus/view_storage.cc +++ b/ui/views/focus/view_storage.cc
@@ -21,8 +21,8 @@ } ViewStorage::~ViewStorage() { - STLDeleteContainerPairSecondPointers(view_to_ids_.begin(), - view_to_ids_.end()); + base::STLDeleteContainerPairSecondPointers(view_to_ids_.begin(), + view_to_ids_.end()); } int ViewStorage::CreateStorageID() {
diff --git a/ui/views/layout/grid_layout.cc b/ui/views/layout/grid_layout.cc index 438d376..77a567c 100644 --- a/ui/views/layout/grid_layout.cc +++ b/ui/views/layout/grid_layout.cc
@@ -374,7 +374,7 @@ } ColumnSet::~ColumnSet() { - STLDeleteElements(&columns_); + base::STLDeleteElements(&columns_); } void ColumnSet::AddPaddingColumn(float resize_percent, int width) { @@ -662,9 +662,9 @@ } GridLayout::~GridLayout() { - STLDeleteElements(&column_sets_); - STLDeleteElements(&view_states_); - STLDeleteElements(&rows_); + base::STLDeleteElements(&column_sets_); + base::STLDeleteElements(&view_states_); + base::STLDeleteElements(&rows_); } // static
diff --git a/ui/views/mus/BUILD.gn b/ui/views/mus/BUILD.gn index 81f8198..97624406 100644 --- a/ui/views/mus/BUILD.gn +++ b/ui/views/mus/BUILD.gn
@@ -30,6 +30,8 @@ "native_widget_mus.h", "os_exchange_data_provider_mus.cc", "os_exchange_data_provider_mus.h", + "pointer_watcher_event_router.cc", + "pointer_watcher_event_router.h", "screen_mus.cc", "screen_mus.h", "screen_mus_delegate.h", @@ -63,7 +65,6 @@ "//services/catalog/public/cpp", "//services/shell/public/cpp", "//services/shell/public/interfaces", - "//services/ui/common:mus_common", "//services/ui/public/cpp", "//services/ui/public/interfaces", "//skia", @@ -154,9 +155,9 @@ sources = [ "display_list_unittest.cc", "native_widget_mus_unittest.cc", + "pointer_watcher_event_router_unittest.cc", "run_all_unittests_mus.cc", "screen_mus_unittest.cc", - "window_manager_connection_unittest.cc", ] sources += rebase_path(gypi.views_unittests_sources, ".", "//ui/views")
diff --git a/ui/views/mus/clipboard_mus.cc b/ui/views/mus/clipboard_mus.cc index 025ab7d2..b35f678d 100644 --- a/ui/views/mus/clipboard_mus.cc +++ b/ui/views/mus/clipboard_mus.cc
@@ -78,7 +78,7 @@ bool ClipboardMus::HasMimeType(const mojo::Array<mojo::String>& available_types, const std::string& type) const { - return ContainsValue(available_types, type); + return base::ContainsValue(available_types, type); } uint64_t ClipboardMus::GetSequenceNumber(ui::ClipboardType type) const { @@ -98,7 +98,7 @@ &available_types); mojo::String format_in_mime = GetMimeTypeFor(format); - return ContainsValue(available_types, format_in_mime); + return base::ContainsValue(available_types, format_in_mime); } void ClipboardMus::Clear(ui::ClipboardType type) {
diff --git a/ui/views/mus/native_widget_mus.cc b/ui/views/mus/native_widget_mus.cc index c325827a..da3c20f 100644 --- a/ui/views/mus/native_widget_mus.cc +++ b/ui/views/mus/native_widget_mus.cc
@@ -9,7 +9,6 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/threading/thread_task_runner_handle.h" -#include "services/ui/common/gpu_service.h" #include "services/ui/public/cpp/property_type_converters.h" #include "services/ui/public/cpp/window.h" #include "services/ui/public/cpp/window_observer.h"
diff --git a/ui/views/mus/pointer_watcher_event_router.cc b/ui/views/mus/pointer_watcher_event_router.cc new file mode 100644 index 0000000..3df7015 --- /dev/null +++ b/ui/views/mus/pointer_watcher_event_router.cc
@@ -0,0 +1,97 @@ +// Copyright 2016 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/views/mus/pointer_watcher_event_router.h" + +#include "services/ui/public/cpp/window.h" +#include "services/ui/public/cpp/window_tree_client.h" +#include "ui/events/base_event_utils.h" +#include "ui/events/event.h" +#include "ui/views/mus/native_widget_mus.h" +#include "ui/views/pointer_watcher.h" + +namespace views { + +PointerWatcherEventRouter::PointerWatcherEventRouter( + ui::WindowTreeClient* client) + : window_tree_client_(client) { + client->AddObserver(this); +} + +PointerWatcherEventRouter::~PointerWatcherEventRouter() { + if (window_tree_client_) + window_tree_client_->RemoveObserver(this); +} + +void PointerWatcherEventRouter::AddPointerWatcher(PointerWatcher* watcher, + bool want_moves) { + // Pointer watchers cannot be added multiple times. + DCHECK(!pointer_watchers_.HasObserver(watcher)); + // TODO(jamescook): Support adding pointer watchers with different + // |want_moves| values by tracking whether the set as a whole wants moves. + // This will involve sending observed move events to a subset of the + // watchers. (crbug.com/627146) + DCHECK(!HasPointerWatcher() || want_moves == pointer_watcher_want_moves_); + pointer_watcher_want_moves_ = want_moves; + + bool had_watcher = HasPointerWatcher(); + pointer_watchers_.AddObserver(watcher); + if (!had_watcher) { + // First PointerWatcher added, start the watcher on the window server. + window_tree_client_->StartPointerWatcher(want_moves); + } +} + +void PointerWatcherEventRouter::RemovePointerWatcher(PointerWatcher* watcher) { + pointer_watchers_.RemoveObserver(watcher); + if (!HasPointerWatcher()) { + // Last PointerWatcher removed, stop the watcher on the window server. + window_tree_client_->StopPointerWatcher(); + pointer_watcher_want_moves_ = false; + } +} + +void PointerWatcherEventRouter::OnPointerEventObserved( + const ui::PointerEvent& event, + ui::Window* target) { + Widget* target_widget = nullptr; + if (target) { + ui::Window* window = target; + while (window && !target_widget) { + target_widget = NativeWidgetMus::GetWidgetForWindow(target); + window = window->parent(); + } + } + + // The mojo input events type converter uses the event root_location field + // to store screen coordinates. Screen coordinates really should be returned + // separately. See http://crbug.com/608547 + gfx::Point location_in_screen = event.AsLocatedEvent()->root_location(); + FOR_EACH_OBSERVER( + PointerWatcher, pointer_watchers_, + OnPointerEventObserved(event, location_in_screen, target_widget)); +} + +bool PointerWatcherEventRouter::HasPointerWatcher() { + // Check to see if we really have any observers left. This doesn't use + // base::ObserverList<>::might_have_observers() because that returns true + // during iteration over the list even when the last observer is removed. + base::ObserverList<PointerWatcher>::Iterator iterator(&pointer_watchers_); + return !!iterator.GetNext(); +} + +void PointerWatcherEventRouter::OnWindowTreeCaptureChanged( + ui::Window* gained_capture, + ui::Window* lost_capture) { + FOR_EACH_OBSERVER(PointerWatcher, pointer_watchers_, OnMouseCaptureChanged()); +} + +void PointerWatcherEventRouter::OnWillDestroyClient( + ui::WindowTreeClient* client) { + DCHECK_EQ(client, window_tree_client_); + window_tree_client_->RemoveObserver(this); + window_tree_client_ = nullptr; +} + +} // namespace views
diff --git a/ui/views/mus/pointer_watcher_event_router.h b/ui/views/mus/pointer_watcher_event_router.h new file mode 100644 index 0000000..d5c6602 --- /dev/null +++ b/ui/views/mus/pointer_watcher_event_router.h
@@ -0,0 +1,58 @@ +// Copyright 2016 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_VIEWS_MUS_POINTER_WATCHER_EVENT_ROUTER_H_ +#define UI_VIEWS_MUS_POINTER_WATCHER_EVENT_ROUTER_H_ + +#include "base/compiler_specific.h" +#include "base/macros.h" +#include "base/observer_list.h" +#include "services/ui/public/cpp/window_tree_client_observer.h" +#include "ui/views/mus/mus_export.h" + +namespace ui { +class PointerEvent; +class WindowTreeClient; +} + +namespace views { + +class PointerWatcher; + +// PointerWatcherEventRouter is responsible for maintaining the list of +// PointerWatchers and notifying appropriately. It is expected the owner of +// PointerWatcherEventRouter is a WindowTreeClientDelegate and calls +// OnPointerEventObserved(). +class VIEWS_MUS_EXPORT PointerWatcherEventRouter + : public NON_EXPORTED_BASE(ui::WindowTreeClientObserver) { + public: + explicit PointerWatcherEventRouter(ui::WindowTreeClient* client); + ~PointerWatcherEventRouter() override; + + // Called by WindowTreeClientDelegate to notify PointerWatchers appropriately. + void OnPointerEventObserved(const ui::PointerEvent& event, + ui::Window* target); + + void AddPointerWatcher(PointerWatcher* watcher, bool want_moves); + void RemovePointerWatcher(PointerWatcher* watcher); + + private: + // Returns true if there is one or more watchers for this client. + bool HasPointerWatcher(); + + // ui::WindowTreeClientObserver: + void OnWindowTreeCaptureChanged(ui::Window* gained_capture, + ui::Window* lost_capture) override; + void OnWillDestroyClient(ui::WindowTreeClient* client) override; + + ui::WindowTreeClient* window_tree_client_; + base::ObserverList<PointerWatcher, true> pointer_watchers_; + bool pointer_watcher_want_moves_ = false; + + DISALLOW_COPY_AND_ASSIGN(PointerWatcherEventRouter); +}; + +} // namespace views + +#endif // UI_VIEWS_MUS_POINTER_WATCHER_EVENT_ROUTER_H_
diff --git a/ui/views/mus/pointer_watcher_event_router_unittest.cc b/ui/views/mus/pointer_watcher_event_router_unittest.cc new file mode 100644 index 0000000..ee3df4eb --- /dev/null +++ b/ui/views/mus/pointer_watcher_event_router_unittest.cc
@@ -0,0 +1,164 @@ +// Copyright 2016 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/views/mus/pointer_watcher_event_router.h" + +#include <memory> + +#include "base/message_loop/message_loop.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/events/event.h" +#include "ui/views/mus/window_manager_connection.h" +#include "ui/views/pointer_watcher.h" +#include "ui/views/test/scoped_views_test_helper.h" + +namespace views { +namespace { + +class TestPointerWatcher : public PointerWatcher { + public: + TestPointerWatcher() {} + ~TestPointerWatcher() override {} + + ui::PointerEvent* last_event_observed() { return last_event_observed_.get(); } + + void Reset() { last_event_observed_.reset(); } + + // PointerWatcher: + void OnPointerEventObserved(const ui::PointerEvent& event, + const gfx::Point& location_in_screen, + Widget* target) override { + last_event_observed_.reset(new ui::PointerEvent(event)); + } + + private: + std::unique_ptr<ui::PointerEvent> last_event_observed_; + + DISALLOW_COPY_AND_ASSIGN(TestPointerWatcher); +}; + +} // namespace + +class PointerWatcherEventRouterTest : public testing::Test { + public: + PointerWatcherEventRouterTest() {} + ~PointerWatcherEventRouterTest() override {} + + void OnPointerEventObserved(const ui::PointerEvent& event) { + WindowManagerConnection::Get() + ->pointer_watcher_event_router() + ->OnPointerEventObserved(event, nullptr); + } + + private: + DISALLOW_COPY_AND_ASSIGN(PointerWatcherEventRouterTest); +}; + +TEST_F(PointerWatcherEventRouterTest, PointerWatcherNoMove) { + base::MessageLoop message_loop(base::MessageLoop::TYPE_UI); + ScopedViewsTestHelper helper; + ASSERT_TRUE(WindowManagerConnection::Get()); + PointerWatcherEventRouter* pointer_watcher_event_router = + WindowManagerConnection::Get()->pointer_watcher_event_router(); + ASSERT_TRUE(pointer_watcher_event_router); + + ui::PointerEvent pointer_event_down( + ui::ET_POINTER_DOWN, gfx::Point(), gfx::Point(), ui::EF_NONE, 1, + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH), + base::TimeTicks()); + ui::PointerEvent pointer_event_up( + ui::ET_POINTER_UP, gfx::Point(), gfx::Point(), ui::EF_NONE, 1, + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE), + base::TimeTicks()); + + // PointerWatchers receive pointer down events. + TestPointerWatcher watcher1; + pointer_watcher_event_router->AddPointerWatcher(&watcher1, false); + OnPointerEventObserved(pointer_event_down); + EXPECT_EQ(ui::ET_POINTER_DOWN, watcher1.last_event_observed()->type()); + watcher1.Reset(); + + // PointerWatchers receive pointer up events. + OnPointerEventObserved(pointer_event_up); + EXPECT_EQ(ui::ET_POINTER_UP, watcher1.last_event_observed()->type()); + watcher1.Reset(); + + // Two PointerWatchers can both receive a single observed event. + TestPointerWatcher watcher2; + pointer_watcher_event_router->AddPointerWatcher(&watcher2, false); + OnPointerEventObserved(pointer_event_down); + EXPECT_EQ(ui::ET_POINTER_DOWN, watcher1.last_event_observed()->type()); + EXPECT_EQ(ui::ET_POINTER_DOWN, watcher2.last_event_observed()->type()); + watcher1.Reset(); + watcher2.Reset(); + + // Removing the first PointerWatcher stops sending events to it. + pointer_watcher_event_router->RemovePointerWatcher(&watcher1); + OnPointerEventObserved(pointer_event_down); + EXPECT_FALSE(watcher1.last_event_observed()); + EXPECT_EQ(ui::ET_POINTER_DOWN, watcher2.last_event_observed()->type()); + watcher1.Reset(); + watcher2.Reset(); + + // Removing the last PointerWatcher stops sending events to it. + pointer_watcher_event_router->RemovePointerWatcher(&watcher2); + OnPointerEventObserved(pointer_event_down); + EXPECT_FALSE(watcher1.last_event_observed()); + EXPECT_FALSE(watcher2.last_event_observed()); +} + +TEST_F(PointerWatcherEventRouterTest, PointerWatcherMove) { + base::MessageLoop message_loop(base::MessageLoop::TYPE_UI); + ScopedViewsTestHelper helper; + ASSERT_TRUE(WindowManagerConnection::Get()); + PointerWatcherEventRouter* pointer_watcher_event_router = + WindowManagerConnection::Get()->pointer_watcher_event_router(); + ASSERT_TRUE(pointer_watcher_event_router); + + ui::PointerEvent pointer_event_down( + ui::ET_POINTER_DOWN, gfx::Point(), gfx::Point(), ui::EF_NONE, 1, + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH), + base::TimeTicks()); + ui::PointerEvent pointer_event_move( + ui::ET_POINTER_MOVED, gfx::Point(), gfx::Point(), ui::EF_NONE, 1, + ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH), + base::TimeTicks()); + + // PointerWatchers receive pointer down events. + TestPointerWatcher watcher1; + pointer_watcher_event_router->AddPointerWatcher(&watcher1, true); + OnPointerEventObserved(pointer_event_down); + EXPECT_EQ(ui::ET_POINTER_DOWN, watcher1.last_event_observed()->type()); + watcher1.Reset(); + + // PointerWatchers receive pointer move events. + OnPointerEventObserved(pointer_event_move); + EXPECT_EQ(ui::ET_POINTER_MOVED, watcher1.last_event_observed()->type()); + watcher1.Reset(); + + // Two PointerWatchers can both receive a single observed event. + TestPointerWatcher watcher2; + pointer_watcher_event_router->AddPointerWatcher(&watcher2, true); + OnPointerEventObserved(pointer_event_move); + EXPECT_EQ(ui::ET_POINTER_MOVED, watcher1.last_event_observed()->type()); + EXPECT_EQ(ui::ET_POINTER_MOVED, watcher2.last_event_observed()->type()); + watcher1.Reset(); + watcher2.Reset(); + + // Removing the first PointerWatcher stops sending events to it. + pointer_watcher_event_router->RemovePointerWatcher(&watcher1); + OnPointerEventObserved(pointer_event_move); + EXPECT_FALSE(watcher1.last_event_observed()); + EXPECT_EQ(ui::ET_POINTER_MOVED, watcher2.last_event_observed()->type()); + watcher1.Reset(); + watcher2.Reset(); + + // Removing the last PointerWatcher stops sending events to it. + pointer_watcher_event_router->RemovePointerWatcher(&watcher2); + OnPointerEventObserved(pointer_event_move); + EXPECT_FALSE(watcher1.last_event_observed()); + EXPECT_FALSE(watcher2.last_event_observed()); +} + +} // namespace views
diff --git a/ui/views/mus/surface_context_factory.cc b/ui/views/mus/surface_context_factory.cc index 08fb8c6..ef046254 100644 --- a/ui/views/mus/surface_context_factory.cc +++ b/ui/views/mus/surface_context_factory.cc
@@ -28,8 +28,8 @@ } // namespace -SurfaceContextFactory::SurfaceContextFactory() - : next_surface_id_namespace_(1u) {} +SurfaceContextFactory::SurfaceContextFactory(ui::GpuService* gpu_service) + : next_surface_id_namespace_(1u), gpu_service_(gpu_service) {} SurfaceContextFactory::~SurfaceContextFactory() {} @@ -38,8 +38,8 @@ ui::Window* window = compositor->window(); NativeWidgetMus* native_widget = NativeWidgetMus::GetForWindow(window); ui::mojom::SurfaceType surface_type = native_widget->surface_type(); - std::unique_ptr<cc::OutputSurface> surface( - new ui::OutputSurface(window->RequestSurface(surface_type))); + std::unique_ptr<cc::OutputSurface> surface(new ui::OutputSurface( + gpu_service_, window->RequestSurface(surface_type))); compositor->SetOutputSurface(std::move(surface)); }
diff --git a/ui/views/mus/surface_context_factory.h b/ui/views/mus/surface_context_factory.h index 442c39e..74cf7f7 100644 --- a/ui/views/mus/surface_context_factory.h +++ b/ui/views/mus/surface_context_factory.h
@@ -8,17 +8,21 @@ #include <stdint.h> #include "base/macros.h" -#include "services/ui/common/mojo_gpu_memory_buffer_manager.h" +#include "services/ui/public/cpp/mojo_gpu_memory_buffer_manager.h" #include "services/ui/public/cpp/raster_thread_helper.h" #include "services/ui/public/interfaces/window_tree.mojom.h" #include "ui/compositor/compositor.h" #include "ui/views/mus/mus_export.h" +namespace ui { +class GpuService; +} + namespace views { class VIEWS_MUS_EXPORT SurfaceContextFactory : public ui::ContextFactory { public: - SurfaceContextFactory(); + explicit SurfaceContextFactory(ui::GpuService* gpu_service); ~SurfaceContextFactory() override; private: @@ -54,6 +58,7 @@ uint32_t next_surface_id_namespace_; ui::RasterThreadHelper raster_thread_helper_; ui::MojoGpuMemoryBufferManager gpu_memory_buffer_manager_; + ui::GpuService* gpu_service_; DISALLOW_COPY_AND_ASSIGN(SurfaceContextFactory); };
diff --git a/ui/views/mus/window_manager_connection.cc b/ui/views/mus/window_manager_connection.cc index 1aa43ce..ef2f6eb 100644 --- a/ui/views/mus/window_manager_connection.cc +++ b/ui/views/mus/window_manager_connection.cc
@@ -11,7 +11,7 @@ #include "base/threading/thread_local.h" #include "services/shell/public/cpp/connection.h" #include "services/shell/public/cpp/connector.h" -#include "services/ui/common/gpu_service.h" +#include "services/ui/public/cpp/gpu_service.h" #include "services/ui/public/cpp/property_type_converters.h" #include "services/ui/public/cpp/window.h" #include "services/ui/public/cpp/window_property.h" @@ -22,6 +22,7 @@ #include "ui/views/mus/clipboard_mus.h" #include "ui/views/mus/native_widget_mus.h" #include "ui/views/mus/os_exchange_data_provider_mus.h" +#include "ui/views/mus/pointer_watcher_event_router.h" #include "ui/views/mus/screen_mus.h" #include "ui/views/mus/surface_context_factory.h" #include "ui/views/pointer_watcher.h" @@ -99,34 +100,6 @@ ui::mojom::SurfaceType::DEFAULT); } -void WindowManagerConnection::AddPointerWatcher(PointerWatcher* watcher, - bool want_moves) { - // Pointer watchers cannot be added multiple times. - DCHECK(!pointer_watchers_.HasObserver(watcher)); - // TODO(jamescook): Support adding pointer watchers with different - // |want_moves| values by tracking whether the set as a whole wants moves. - // This will involve sending observed move events to a subset of the - // watchers. (crbug.com/627146) - DCHECK(!HasPointerWatcher() || want_moves == pointer_watcher_want_moves_); - pointer_watcher_want_moves_ = want_moves; - - bool had_watcher = HasPointerWatcher(); - pointer_watchers_.AddObserver(watcher); - if (!had_watcher) { - // First PointerWatcher added, start the watcher on the window server. - client_->StartPointerWatcher(want_moves); - } -} - -void WindowManagerConnection::RemovePointerWatcher(PointerWatcher* watcher) { - pointer_watchers_.RemoveObserver(watcher); - if (!HasPointerWatcher()) { - // Last PointerWatcher removed, stop the watcher on the window server. - client_->StopPointerWatcher(); - pointer_watcher_want_moves_ = false; - } -} - const std::set<ui::Window*>& WindowManagerConnection::GetRoots() const { return client_->GetRoots(); } @@ -134,18 +107,20 @@ WindowManagerConnection::WindowManagerConnection( shell::Connector* connector, const shell::Identity& identity) - : connector_(connector), - identity_(identity), - pointer_watcher_want_moves_(false) { + : connector_(connector), identity_(identity) { lazy_tls_ptr.Pointer()->Set(this); gpu_service_ = ui::GpuService::Initialize(connector); - compositor_context_factory_.reset(new views::SurfaceContextFactory()); + compositor_context_factory_.reset( + new views::SurfaceContextFactory(gpu_service_.get())); aura::Env::GetInstance()->set_context_factory( compositor_context_factory_.get()); client_.reset(new ui::WindowTreeClient(this, nullptr, nullptr)); client_->ConnectViaWindowTreeFactory(connector_); + pointer_watcher_event_router_.reset( + new PointerWatcherEventRouter(client_.get())); + screen_.reset(new ScreenMus(this)); screen_->Init(connector); @@ -161,14 +136,6 @@ std::map<std::string, std::vector<uint8_t>>())); } -bool WindowManagerConnection::HasPointerWatcher() { - // Check to see if we really have any observers left. This doesn't use - // base::ObserverList<>::might_have_observers() because that returns true - // during iteration over the list even when the last observer is removed. - base::ObserverList<PointerWatcher>::Iterator iterator(&pointer_watchers_); - return !!iterator.GetNext(); -} - void WindowManagerConnection::OnEmbed(ui::Window* root) {} void WindowManagerConnection::OnDidDestroyClient(ui::WindowTreeClient* client) { @@ -182,19 +149,7 @@ void WindowManagerConnection::OnPointerEventObserved( const ui::PointerEvent& event, ui::Window* target) { - Widget* target_widget = nullptr; - if (target) { - ui::Window* root = target->GetRoot(); - target_widget = NativeWidgetMus::GetWidgetForWindow(root); - } - - // The mojo input events type converter uses the event root_location field - // to store screen coordinates. Screen coordinates really should be returned - // separately. See http://crbug.com/608547 - gfx::Point location_in_screen = event.AsLocatedEvent()->root_location(); - FOR_EACH_OBSERVER( - PointerWatcher, pointer_watchers_, - OnPointerEventObserved(event, location_in_screen, target_widget)); + pointer_watcher_event_router_->OnPointerEventObserved(event, target); } void WindowManagerConnection::OnWindowManagerFrameValuesChanged() {
diff --git a/ui/views/mus/window_manager_connection.h b/ui/views/mus/window_manager_connection.h index 4c7f050..0524fd9 100644 --- a/ui/views/mus/window_manager_connection.h +++ b/ui/views/mus/window_manager_connection.h
@@ -13,7 +13,6 @@ #include <vector> #include "base/macros.h" -#include "base/observer_list.h" #include "services/shell/public/cpp/identity.h" #include "services/ui/public/cpp/window_tree_client_delegate.h" #include "ui/base/dragdrop/os_exchange_data_provider_factory.h" @@ -33,6 +32,7 @@ class ClipboardMus; class NativeWidget; class PointerWatcher; +class PointerWatcherEventRouter; class ScreenMus; class SurfaceContextFactory; namespace internal { @@ -61,6 +61,9 @@ static WindowManagerConnection* Get(); static bool Exists(); + PointerWatcherEventRouter* pointer_watcher_event_router() { + return pointer_watcher_event_router_.get(); + } shell::Connector* connector() { return connector_; } ui::GpuService* gpu_service() { return gpu_service_.get(); } @@ -72,20 +75,12 @@ const Widget::InitParams& init_params, internal::NativeWidgetDelegate* delegate); - void AddPointerWatcher(PointerWatcher* watcher, bool want_moves); - void RemovePointerWatcher(PointerWatcher* watcher); - const std::set<ui::Window*>& GetRoots() const; private: - friend class WindowManagerConnectionTest; - WindowManagerConnection(shell::Connector* connector, const shell::Identity& identity); - // Returns true if there is one or more watchers for this client. - bool HasPointerWatcher(); - // ui::WindowTreeClientDelegate: void OnEmbed(ui::Window* root) override; void OnDidDestroyClient(ui::WindowTreeClient* client) override; @@ -104,10 +99,8 @@ std::unique_ptr<ScreenMus> screen_; std::unique_ptr<ui::WindowTreeClient> client_; std::unique_ptr<ui::GpuService> gpu_service_; + std::unique_ptr<PointerWatcherEventRouter> pointer_watcher_event_router_; std::unique_ptr<SurfaceContextFactory> compositor_context_factory_; - // Must be empty on destruction. - base::ObserverList<PointerWatcher, true> pointer_watchers_; - bool pointer_watcher_want_moves_; DISALLOW_COPY_AND_ASSIGN(WindowManagerConnection); };
diff --git a/ui/views/mus/window_manager_connection_unittest.cc b/ui/views/mus/window_manager_connection_unittest.cc deleted file mode 100644 index 16415890..0000000 --- a/ui/views/mus/window_manager_connection_unittest.cc +++ /dev/null
@@ -1,157 +0,0 @@ -// Copyright 2016 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/views/mus/window_manager_connection.h" - -#include <memory> - -#include "base/message_loop/message_loop.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/events/event.h" -#include "ui/views/pointer_watcher.h" -#include "ui/views/test/scoped_views_test_helper.h" - -namespace views { -namespace { - -class TestPointerWatcher : public PointerWatcher { - public: - TestPointerWatcher() {} - ~TestPointerWatcher() override {} - - ui::PointerEvent* last_event_observed() { return last_event_observed_.get(); } - - void Reset() { last_event_observed_.reset(); } - - // PointerWatcher: - void OnPointerEventObserved(const ui::PointerEvent& event, - const gfx::Point& location_in_screen, - Widget* target) override { - last_event_observed_.reset(new ui::PointerEvent(event)); - } - - private: - std::unique_ptr<ui::PointerEvent> last_event_observed_; - - DISALLOW_COPY_AND_ASSIGN(TestPointerWatcher); -}; - -} // namespace - -class WindowManagerConnectionTest : public testing::Test { - public: - WindowManagerConnectionTest() {} - ~WindowManagerConnectionTest() override {} - - void OnPointerEventObserved(const ui::PointerEvent& event) { - WindowManagerConnection::Get()->OnPointerEventObserved(event, nullptr); - } - - private: - DISALLOW_COPY_AND_ASSIGN(WindowManagerConnectionTest); -}; - -TEST_F(WindowManagerConnectionTest, PointerWatcherNoMove) { - base::MessageLoop message_loop(base::MessageLoop::TYPE_UI); - ScopedViewsTestHelper helper; - WindowManagerConnection* connection = WindowManagerConnection::Get(); - ASSERT_TRUE(connection); - - ui::PointerEvent pointer_event_down( - ui::ET_POINTER_DOWN, gfx::Point(), gfx::Point(), ui::EF_NONE, 1, - ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH), - base::TimeTicks()); - ui::PointerEvent pointer_event_up( - ui::ET_POINTER_UP, gfx::Point(), gfx::Point(), ui::EF_NONE, 1, - ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_MOUSE), - base::TimeTicks()); - - // PointerWatchers receive pointer down events. - TestPointerWatcher watcher1; - connection->AddPointerWatcher(&watcher1, false); - OnPointerEventObserved(pointer_event_down); - EXPECT_EQ(ui::ET_POINTER_DOWN, watcher1.last_event_observed()->type()); - watcher1.Reset(); - - // PointerWatchers receive pointer up events. - OnPointerEventObserved(pointer_event_up); - EXPECT_EQ(ui::ET_POINTER_UP, watcher1.last_event_observed()->type()); - watcher1.Reset(); - - // Two PointerWatchers can both receive a single observed event. - TestPointerWatcher watcher2; - connection->AddPointerWatcher(&watcher2, false); - OnPointerEventObserved(pointer_event_down); - EXPECT_EQ(ui::ET_POINTER_DOWN, watcher1.last_event_observed()->type()); - EXPECT_EQ(ui::ET_POINTER_DOWN, watcher2.last_event_observed()->type()); - watcher1.Reset(); - watcher2.Reset(); - - // Removing the first PointerWatcher stops sending events to it. - connection->RemovePointerWatcher(&watcher1); - OnPointerEventObserved(pointer_event_down); - EXPECT_FALSE(watcher1.last_event_observed()); - EXPECT_EQ(ui::ET_POINTER_DOWN, watcher2.last_event_observed()->type()); - watcher1.Reset(); - watcher2.Reset(); - - // Removing the last PointerWatcher stops sending events to it. - connection->RemovePointerWatcher(&watcher2); - OnPointerEventObserved(pointer_event_down); - EXPECT_FALSE(watcher1.last_event_observed()); - EXPECT_FALSE(watcher2.last_event_observed()); -} - -TEST_F(WindowManagerConnectionTest, PointerWatcherMove) { - base::MessageLoop message_loop(base::MessageLoop::TYPE_UI); - ScopedViewsTestHelper helper; - WindowManagerConnection* connection = WindowManagerConnection::Get(); - ASSERT_TRUE(connection); - - ui::PointerEvent pointer_event_down( - ui::ET_POINTER_DOWN, gfx::Point(), gfx::Point(), ui::EF_NONE, 1, - ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH), - base::TimeTicks()); - ui::PointerEvent pointer_event_move( - ui::ET_POINTER_MOVED, gfx::Point(), gfx::Point(), ui::EF_NONE, 1, - ui::PointerDetails(ui::EventPointerType::POINTER_TYPE_TOUCH), - base::TimeTicks()); - - // PointerWatchers receive pointer down events. - TestPointerWatcher watcher1; - connection->AddPointerWatcher(&watcher1, true); - OnPointerEventObserved(pointer_event_down); - EXPECT_EQ(ui::ET_POINTER_DOWN, watcher1.last_event_observed()->type()); - watcher1.Reset(); - - // PointerWatchers receive pointer move events. - OnPointerEventObserved(pointer_event_move); - EXPECT_EQ(ui::ET_POINTER_MOVED, watcher1.last_event_observed()->type()); - watcher1.Reset(); - - // Two PointerWatchers can both receive a single observed event. - TestPointerWatcher watcher2; - connection->AddPointerWatcher(&watcher2, true); - OnPointerEventObserved(pointer_event_move); - EXPECT_EQ(ui::ET_POINTER_MOVED, watcher1.last_event_observed()->type()); - EXPECT_EQ(ui::ET_POINTER_MOVED, watcher2.last_event_observed()->type()); - watcher1.Reset(); - watcher2.Reset(); - - // Removing the first PointerWatcher stops sending events to it. - connection->RemovePointerWatcher(&watcher1); - OnPointerEventObserved(pointer_event_move); - EXPECT_FALSE(watcher1.last_event_observed()); - EXPECT_EQ(ui::ET_POINTER_MOVED, watcher2.last_event_observed()->type()); - watcher1.Reset(); - watcher2.Reset(); - - // Removing the last PointerWatcher stops sending events to it. - connection->RemovePointerWatcher(&watcher2); - OnPointerEventObserved(pointer_event_move); - EXPECT_FALSE(watcher1.last_event_observed()); - EXPECT_FALSE(watcher2.last_event_observed()); -} - -} // namespace views
diff --git a/ui/views/pointer_watcher.h b/ui/views/pointer_watcher.h index 0081871..8270683 100644 --- a/ui/views/pointer_watcher.h +++ b/ui/views/pointer_watcher.h
@@ -35,6 +35,10 @@ const gfx::Point& location_in_screen, Widget* target) = 0; + // PointerWatcher is informed of capture changes as it's common to create a + // MouseEvent of type ui::ET_MOUSE_CAPTURE_CHANGED on capture change. + virtual void OnMouseCaptureChanged() {} + protected: virtual ~PointerWatcher() {}
diff --git a/ui/views/view.cc b/ui/views/view.cc index 3da5ce0..e6d51dd2 100644 --- a/ui/views/view.cc +++ b/ui/views/view.cc
@@ -447,7 +447,13 @@ // Transformations ------------------------------------------------------------- gfx::Transform View::GetTransform() const { - return layer() ? layer()->transform() : gfx::Transform(); + if (!layer()) + return gfx::Transform(); + + gfx::Transform transform = layer()->transform(); + gfx::ScrollOffset scroll_offset = layer()->CurrentScrollOffset(); + transform.Translate(-scroll_offset.x(), -scroll_offset.y()); + return transform; } void View::SetTransform(const gfx::Transform& transform) { @@ -1109,7 +1115,7 @@ if (!accelerators_.get()) accelerators_.reset(new std::vector<ui::Accelerator>()); - if (!ContainsValue(*accelerators_.get(), accelerator)) + if (!base::ContainsValue(*accelerators_.get(), accelerator)) accelerators_->push_back(accelerator); RegisterPendingAccelerators();
diff --git a/ui/views/view_unittest.cc b/ui/views/view_unittest.cc index 38f55bd..e9af12ad5 100644 --- a/ui/views/view_unittest.cc +++ b/ui/views/view_unittest.cc
@@ -526,7 +526,7 @@ // Paint "everything". gfx::Rect first_paint(1, 1); scoped_refptr<cc::DisplayItemList> list = - cc::DisplayItemList::Create(first_paint, cc::DisplayItemListSettings()); + cc::DisplayItemList::Create(cc::DisplayItemListSettings()); root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint)); // The empty view has nothing to paint so it doesn't try build a cache, nor do @@ -548,7 +548,7 @@ gfx::Rect pixel_rect = gfx::Rect(1, 1); float device_scale_factor = 1.f; scoped_refptr<cc::DisplayItemList> list = - cc::DisplayItemList::Create(pixel_rect, cc::DisplayItemListSettings()); + cc::DisplayItemList::Create(cc::DisplayItemListSettings()); root_view->Paint( ui::PaintContext(list.get(), device_scale_factor, pixel_rect)); EXPECT_TRUE(v1->did_paint_); @@ -564,14 +564,14 @@ list->VisualRectForTesting(item_index)); // If invalidation doesn't intersect v1, we paint with the cache. - list = cc::DisplayItemList::Create(pixel_rect, cc::DisplayItemListSettings()); + list = cc::DisplayItemList::Create(cc::DisplayItemListSettings()); root_view->Paint( ui::PaintContext(list.get(), device_scale_factor, pixel_rect)); EXPECT_FALSE(v1->did_paint_); v1->Reset(); // If invalidation does intersect v1, we don't paint with the cache. - list = cc::DisplayItemList::Create(pixel_rect, cc::DisplayItemListSettings()); + list = cc::DisplayItemList::Create(cc::DisplayItemListSettings()); root_view->Paint( ui::PaintContext(list.get(), device_scale_factor, v1->bounds())); EXPECT_TRUE(v1->did_paint_); @@ -579,7 +579,7 @@ // Moving the view should still use the cache when the invalidation doesn't // intersect v1. - list = cc::DisplayItemList::Create(pixel_rect, cc::DisplayItemListSettings()); + list = cc::DisplayItemList::Create(cc::DisplayItemListSettings()); v1->SetX(9); root_view->Paint( ui::PaintContext(list.get(), device_scale_factor, pixel_rect)); @@ -596,7 +596,7 @@ // Moving the view should not use the cache when painting without // invalidation. - list = cc::DisplayItemList::Create(pixel_rect, cc::DisplayItemListSettings()); + list = cc::DisplayItemList::Create(cc::DisplayItemListSettings()); v1->SetX(8); root_view->Paint(ui::PaintContext( ui::PaintContext(list.get(), device_scale_factor, pixel_rect), @@ -626,7 +626,7 @@ gfx::Rect pixel_rect = gfx::Rect(1, 1); float device_scale_factor = 1.f; scoped_refptr<cc::DisplayItemList> list = - cc::DisplayItemList::Create(pixel_rect, cc::DisplayItemListSettings()); + cc::DisplayItemList::Create(cc::DisplayItemListSettings()); root_view->Paint( ui::PaintContext(list.get(), device_scale_factor, pixel_rect)); EXPECT_TRUE(v1->did_paint_); @@ -643,14 +643,14 @@ list->VisualRectForTesting(item_index)); // If invalidation doesn't intersect v1, we paint with the cache. - list = cc::DisplayItemList::Create(pixel_rect, cc::DisplayItemListSettings()); + list = cc::DisplayItemList::Create(cc::DisplayItemListSettings()); root_view->Paint( ui::PaintContext(list.get(), device_scale_factor, pixel_rect)); EXPECT_FALSE(v1->did_paint_); v1->Reset(); // If invalidation does intersect v1, we don't paint with the cache. - list = cc::DisplayItemList::Create(pixel_rect, cc::DisplayItemListSettings()); + list = cc::DisplayItemList::Create(cc::DisplayItemListSettings()); root_view->Paint( ui::PaintContext(list.get(), device_scale_factor, v1->bounds())); EXPECT_TRUE(v1->did_paint_); @@ -658,7 +658,7 @@ // Moving the view should still use the cache when the invalidation doesn't // intersect v1. - list = cc::DisplayItemList::Create(pixel_rect, cc::DisplayItemListSettings()); + list = cc::DisplayItemList::Create(cc::DisplayItemListSettings()); v1->SetX(9); root_view->Paint( ui::PaintContext(list.get(), device_scale_factor, pixel_rect)); @@ -676,7 +676,7 @@ // Moving the view should not use the cache when painting without // invalidation. - list = cc::DisplayItemList::Create(pixel_rect, cc::DisplayItemListSettings()); + list = cc::DisplayItemList::Create(cc::DisplayItemListSettings()); v1->SetX(8); root_view->Paint(ui::PaintContext( ui::PaintContext(list.get(), device_scale_factor, pixel_rect), @@ -710,14 +710,14 @@ // invalidation. gfx::Rect first_paint(1, 1); scoped_refptr<cc::DisplayItemList> list = - cc::DisplayItemList::Create(first_paint, cc::DisplayItemListSettings()); + cc::DisplayItemList::Create(cc::DisplayItemListSettings()); root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint)); v1->Reset(); v2->Reset(); gfx::Rect paint_area(1, 1); gfx::Rect root_area(root_view->size()); - list = cc::DisplayItemList::Create(root_area, cc::DisplayItemListSettings()); + list = cc::DisplayItemList::Create(cc::DisplayItemListSettings()); // With a known invalidation, v1 and v2 are not painted. EXPECT_FALSE(v1->did_paint_); @@ -750,14 +750,14 @@ // invalidation. gfx::Rect first_paint(1, 1); scoped_refptr<cc::DisplayItemList> list = - cc::DisplayItemList::Create(first_paint, cc::DisplayItemListSettings()); + cc::DisplayItemList::Create(cc::DisplayItemListSettings()); root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint)); v1->Reset(); v2->Reset(); gfx::Rect paint_area(25, 26); gfx::Rect root_area(root_view->size()); - list = cc::DisplayItemList::Create(root_area, cc::DisplayItemListSettings()); + list = cc::DisplayItemList::Create(cc::DisplayItemListSettings()); EXPECT_FALSE(v1->did_paint_); EXPECT_FALSE(v2->did_paint_); @@ -794,14 +794,14 @@ // invalidation. gfx::Rect first_paint(1, 1); scoped_refptr<cc::DisplayItemList> list = - cc::DisplayItemList::Create(first_paint, cc::DisplayItemListSettings()); + cc::DisplayItemList::Create(cc::DisplayItemListSettings()); root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint)); v1->Reset(); v2->Reset(); gfx::Rect paint_area(25, 26); gfx::Rect root_area(root_view->size()); - list = cc::DisplayItemList::Create(root_area, cc::DisplayItemListSettings()); + list = cc::DisplayItemList::Create(cc::DisplayItemListSettings()); EXPECT_FALSE(v1->did_paint_); EXPECT_FALSE(v2->did_paint_); @@ -826,14 +826,14 @@ // invalidation. gfx::Rect first_paint(1, 1); scoped_refptr<cc::DisplayItemList> list = - cc::DisplayItemList::Create(first_paint, cc::DisplayItemListSettings()); + cc::DisplayItemList::Create(cc::DisplayItemListSettings()); root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint)); v1->Reset(); v2->Reset(); gfx::Rect paint_area(9, 10, 5, 6); gfx::Rect root_area(root_view->size()); - list = cc::DisplayItemList::Create(root_area, cc::DisplayItemListSettings()); + list = cc::DisplayItemList::Create(cc::DisplayItemListSettings()); EXPECT_FALSE(v1->did_paint_); EXPECT_FALSE(v2->did_paint_); @@ -870,14 +870,14 @@ // invalidation. gfx::Rect first_paint(1, 1); scoped_refptr<cc::DisplayItemList> list = - cc::DisplayItemList::Create(first_paint, cc::DisplayItemListSettings()); + cc::DisplayItemList::Create(cc::DisplayItemListSettings()); root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint)); v1->Reset(); v2->Reset(); gfx::Rect paint_area(2, 10, 5, 6); gfx::Rect root_area(root_view->size()); - list = cc::DisplayItemList::Create(root_area, cc::DisplayItemListSettings()); + list = cc::DisplayItemList::Create(cc::DisplayItemListSettings()); EXPECT_FALSE(v1->did_paint_); EXPECT_FALSE(v2->did_paint_); @@ -902,14 +902,14 @@ // invalidation. gfx::Rect first_paint(1, 1); scoped_refptr<cc::DisplayItemList> list = - cc::DisplayItemList::Create(first_paint, cc::DisplayItemListSettings()); + cc::DisplayItemList::Create(cc::DisplayItemListSettings()); root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint)); v1->Reset(); v2->Reset(); gfx::Rect paint_area(9, 10, 2, 3); gfx::Rect root_area(root_view->size()); - list = cc::DisplayItemList::Create(root_area, cc::DisplayItemListSettings()); + list = cc::DisplayItemList::Create(cc::DisplayItemListSettings()); EXPECT_FALSE(v1->did_paint_); EXPECT_FALSE(v2->did_paint_); @@ -946,14 +946,14 @@ // invalidation. gfx::Rect first_paint(1, 1); scoped_refptr<cc::DisplayItemList> list = - cc::DisplayItemList::Create(first_paint, cc::DisplayItemListSettings()); + cc::DisplayItemList::Create(cc::DisplayItemListSettings()); root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint)); v1->Reset(); v2->Reset(); gfx::Rect paint_area(2, 10, 2, 3); gfx::Rect root_area(root_view->size()); - list = cc::DisplayItemList::Create(root_area, cc::DisplayItemListSettings()); + list = cc::DisplayItemList::Create(cc::DisplayItemListSettings()); EXPECT_FALSE(v1->did_paint_); EXPECT_FALSE(v2->did_paint_); @@ -978,14 +978,14 @@ // invalidation. gfx::Rect first_paint(1, 1); scoped_refptr<cc::DisplayItemList> list = - cc::DisplayItemList::Create(first_paint, cc::DisplayItemListSettings()); + cc::DisplayItemList::Create(cc::DisplayItemListSettings()); root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint)); v1->Reset(); v2->Reset(); gfx::Rect paint_area(9, 10, 2, 1); gfx::Rect root_area(root_view->size()); - list = cc::DisplayItemList::Create(root_area, cc::DisplayItemListSettings()); + list = cc::DisplayItemList::Create(cc::DisplayItemListSettings()); EXPECT_FALSE(v1->did_paint_); EXPECT_FALSE(v2->did_paint_); @@ -1022,14 +1022,14 @@ // invalidation. gfx::Rect first_paint(1, 1); scoped_refptr<cc::DisplayItemList> list = - cc::DisplayItemList::Create(first_paint, cc::DisplayItemListSettings()); + cc::DisplayItemList::Create(cc::DisplayItemListSettings()); root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint)); v1->Reset(); v2->Reset(); gfx::Rect paint_area(2, 10, 2, 1); gfx::Rect root_area(root_view->size()); - list = cc::DisplayItemList::Create(root_area, cc::DisplayItemListSettings()); + list = cc::DisplayItemList::Create(cc::DisplayItemListSettings()); EXPECT_FALSE(v1->did_paint_); EXPECT_FALSE(v2->did_paint_); @@ -1054,7 +1054,7 @@ // invalidation. gfx::Rect first_paint(1, 1); scoped_refptr<cc::DisplayItemList> list = - cc::DisplayItemList::Create(first_paint, cc::DisplayItemListSettings()); + cc::DisplayItemList::Create(cc::DisplayItemListSettings()); root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint)); v1->Reset(); v2->Reset(); @@ -1062,7 +1062,7 @@ // Intersects with the second child only. gfx::Rect paint_area(3, 3, 1, 2); gfx::Rect root_area(root_view->size()); - list = cc::DisplayItemList::Create(root_area, cc::DisplayItemListSettings()); + list = cc::DisplayItemList::Create(cc::DisplayItemListSettings()); EXPECT_FALSE(v1->did_paint_); EXPECT_FALSE(v2->did_paint_); @@ -1110,7 +1110,7 @@ // invalidation. gfx::Rect first_paint(1, 1); scoped_refptr<cc::DisplayItemList> list = - cc::DisplayItemList::Create(first_paint, cc::DisplayItemListSettings()); + cc::DisplayItemList::Create(cc::DisplayItemListSettings()); root_view->Paint(ui::PaintContext(list.get(), 1.f, first_paint)); v1->Reset(); v2->Reset(); @@ -1118,7 +1118,7 @@ // Intersects with the first child only. gfx::Rect paint_area(3, 10, 1, 2); gfx::Rect root_area(root_view->size()); - list = cc::DisplayItemList::Create(root_area, cc::DisplayItemListSettings()); + list = cc::DisplayItemList::Create(cc::DisplayItemListSettings()); EXPECT_FALSE(v1->did_paint_); EXPECT_FALSE(v2->did_paint_); @@ -1155,7 +1155,7 @@ // invalidation. gfx::Rect first_paint(1, 1); scoped_refptr<cc::DisplayItemList> list = - cc::DisplayItemList::Create(first_paint, cc::DisplayItemListSettings()); + cc::DisplayItemList::Create(cc::DisplayItemListSettings()); v1->Paint(ui::PaintContext(list.get(), 1.f, first_paint)); v1->Reset(); v2->Reset(); @@ -1164,7 +1164,7 @@ gfx::Rect paint_area(25, 26); gfx::Rect view_area(root_view->size()); scoped_refptr<cc::DisplayItemList> list = - cc::DisplayItemList::Create(view_area, cc::DisplayItemListSettings()); + cc::DisplayItemList::Create(cc::DisplayItemListSettings()); // The promoted views are not painted as they are separate paint roots. root_view->Paint(ui::PaintContext(list.get(), 1.f, paint_area)); @@ -1176,7 +1176,7 @@ gfx::Rect paint_area(1, 1); gfx::Rect view_area(v1->size()); scoped_refptr<cc::DisplayItemList> list = - cc::DisplayItemList::Create(view_area, cc::DisplayItemListSettings()); + cc::DisplayItemList::Create(cc::DisplayItemListSettings()); // The |v1| view is painted. If it used its offset incorrect, it would think // its at (10,11) instead of at (0,0) since it is the paint root. @@ -1191,7 +1191,7 @@ gfx::Rect paint_area(3, 3, 1, 2); gfx::Rect view_area(v1->size()); scoped_refptr<cc::DisplayItemList> list = - cc::DisplayItemList::Create(view_area, cc::DisplayItemListSettings()); + cc::DisplayItemList::Create(cc::DisplayItemListSettings()); // The |v2| view is painted also. If it used its offset incorrect, it would // think its at (13,15) instead of at (3,4) since |v1| is the paint root. @@ -1238,7 +1238,7 @@ EXPECT_EQ(gfx::Rect(0, 1000, 100, 100), v1->GetVisibleBounds()); scoped_refptr<cc::DisplayItemList> list = - cc::DisplayItemList::Create(gfx::Rect(), cc::DisplayItemListSettings()); + cc::DisplayItemList::Create(cc::DisplayItemListSettings()); ui::PaintContext context(list.get(), 1.f, gfx::Rect()); v1->Paint(context);
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc index 9b40b50..ab5b7ab 100644 --- a/ui/views/win/hwnd_message_handler.cc +++ b/ui/views/win/hwnd_message_handler.cc
@@ -349,6 +349,20 @@ // Create the window. WindowImpl::Init(parent, bounds); + if (delegate_->HasFrame() && base::win::IsProcessPerMonitorDpiAware()) { + static auto enable_child_window_dpi_message_func = []() { + // Derived signature; not available in headers. + // This call gets Windows to scale the non-client area when WM_DPICHANGED + // is fired. + using EnableChildWindowDpiMessagePtr = LRESULT (WINAPI*)(HWND, BOOL); + return reinterpret_cast<EnableChildWindowDpiMessagePtr>( + GetProcAddress(GetModuleHandle(L"user32.dll"), + "EnableChildWindowDpiMessage")); + }(); + if (enable_child_window_dpi_message_func) + enable_child_window_dpi_message_func(hwnd(), TRUE); + } + prop_window_target_.reset(new ui::ViewProp(hwnd(), ui::WindowEventTarget::kWin32InputEventTarget, static_cast<ui::WindowEventTarget*>(this)));
diff --git a/ui/webui/resources/cr_elements/cr_events/cr_events.html b/ui/webui/resources/cr_elements/cr_events/cr_events.html deleted file mode 100644 index f726fe3..0000000 --- a/ui/webui/resources/cr_elements/cr_events/cr_events.html +++ /dev/null
@@ -1,5 +0,0 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<dom-module id="cr-events"> - <script src="cr_events.js"></script> -</dom-module>
diff --git a/ui/webui/resources/cr_elements/cr_events/cr_events.js b/ui/webui/resources/cr_elements/cr_events/cr_events.js deleted file mode 100644 index dc82d6d..0000000 --- a/ui/webui/resources/cr_elements/cr_events/cr_events.js +++ /dev/null
@@ -1,50 +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. - -/** - * @fileoverview - * `cr-events` provides helpers for handling events in Chrome Polymer elements. - * - * Example: - * - * <cr-events id="events"></cr-events> - * - * Usage: - * - * this.$.events.forward(this.$.element, ['change']); - */ -Polymer({ - is: 'cr-events', - - /** - * Sets up an element to forward events across the shadow boundary, for events - * which normally stop at the root node (see http://goo.gl/WGMO9x). - * @param {!HTMLElement} element The element to forward events from. - * @param {!Array<string>} events The events to forward. - */ - forward: function(element, events) { - for (var i = 0; i < events.length; i++) - element.addEventListener(events[i], this.forwardEvent_); - }, - - /** - * Forwards events that don't automatically cross the shadow boundary - * if the event should bubble. - * @param {!Event} e The event to forward. - * @param {*} detail Data passed when initializing the event. - * @param {Node=} opt_sender Node that declared the handler. - * @private - */ - forwardEvent_: function(e, detail, opt_sender) { - if (!e.bubbles) - return; - - var node = e.path[e.path.length - 1]; - if (node instanceof ShadowRoot) { - // Forward the event to the shadow host. - e.stopPropagation(); - node.host.fire(e.type, detail, node.host, true, e.cancelable); - } - }, -});
diff --git a/ui/webui/resources/cr_elements/cr_shared_menu/cr_shared_menu.js b/ui/webui/resources/cr_elements/cr_shared_menu/cr_shared_menu.js index 0229a7c..2b27065 100644 --- a/ui/webui/resources/cr_elements/cr_shared_menu/cr_shared_menu.js +++ b/ui/webui/resources/cr_elements/cr_shared_menu/cr_shared_menu.js
@@ -15,6 +15,7 @@ type: Boolean, observer: 'menuOpenChanged_', value: false, + notify: true, }, /**
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_indicator.css b/ui/webui/resources/cr_elements/policy/cr_policy_indicator.css index 0ef8a64..26b4fb2 100644 --- a/ui/webui/resources/cr_elements/policy/cr_policy_indicator.css +++ b/ui/webui/resources/cr_elements/policy/cr_policy_indicator.css
@@ -5,7 +5,5 @@ /* Note: we use display: block here to avoid positioning issues related to * the use of overflow: hidden. */ :host { - display: block; - height: 20px; - width: 20px; + @apply(--cr-policy-indicator); }
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.html b/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.html index 393061d..f5e951f 100644 --- a/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.html +++ b/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.html
@@ -9,13 +9,7 @@ <link rel="import" type="css" href="cr_policy_indicator.css"> <style> paper-tooltip { - --paper-tooltip: { - font-size: 92.31%; /* Effectively 12px if the host default is 13px. */ - font-weight: 500; - max-width: 330px; - min-width: 200px; - padding: 10px 8px; - }; + --paper-tooltip: var(--cr-policy-tooltip); } </style> <template>
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.js b/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.js index cd2562b..4084ab2c 100644 --- a/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.js +++ b/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.js
@@ -24,7 +24,7 @@ * not correspond to a pref (Chrome OS only). Only used when pref is null. * Initialized to '' so that computed functions will get called if this is * never set. TODO(stevenjb/michaelpg): Create a separate indicator for - * non-pref (i.e. explicitly set) indicators (see languyage_detail_page). + * non-pref (i.e. explicitly set) indicators (see language_detail_page). */ controllingUser: {type: String, value: ''},
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_vars_css.html b/ui/webui/resources/cr_elements/policy/cr_policy_vars_css.html new file mode 100644 index 0000000..285734d --- /dev/null +++ b/ui/webui/resources/cr_elements/policy/cr_policy_vars_css.html
@@ -0,0 +1,17 @@ +<style is="custom-style"> + :root { + --cr-policy-indicator: { + display: block; + height: 20px; + width: 20px; + }; + + --cr-policy-tooltip: { + font-size: 92.31%; /* Effectively 12px if the host default is 13px. */ + font-weight: 500; + max-width: 330px; + min-width: 200px; + padding: 10px 8px; + }; + } +</style>
diff --git a/ui/webui/resources/cr_elements_resources.grdp b/ui/webui/resources/cr_elements_resources.grdp index d3ebed1..84bcc8b 100644 --- a/ui/webui/resources/cr_elements_resources.grdp +++ b/ui/webui/resources/cr_elements_resources.grdp
@@ -7,12 +7,6 @@ <structure name="IDR_CR_ELEMENTS_CR_DIALOG_JS" file="../../webui/resources/cr_elements/cr_dialog/cr_dialog.js" type="chrome_html" /> - <structure name="IDR_CR_ELEMENTS_CR_EVENTS_HTML" - file="../../webui/resources/cr_elements/cr_events/cr_events.html" - type="chrome_html" /> - <structure name="IDR_CR_ELEMENTS_CR_EVENTS_JS" - file="../../webui/resources/cr_elements/cr_events/cr_events.js" - type="chrome_html" /> <structure name="IDR_CR_ELEMENTS_CR_EXPAND_BUTTON_CSS" file="../../webui/resources/cr_elements/cr_expand_button/cr_expand_button.css" type="chrome_html" /> @@ -107,6 +101,9 @@ <structure name="IDR_CR_ELEMENTS_CR_POLICY_PREF_INDICATOR_HTML" file="../../webui/resources/cr_elements/policy/cr_policy_pref_indicator.html" type="chrome_html" /> + <structure name="IDR_CR_ELEMENTS_CR_POLICY_VARS_CSS_HTML" + file="../../webui/resources/cr_elements/policy/cr_policy_vars_css.html" + type="chrome_html" /> <structure name="IDR_CR_ELEMENTS_CR_PROFILE_AVATAR_SELECTOR_HTML" file="../../webui/resources/cr_elements/cr_profile_avatar_selector/cr_profile_avatar_selector.html" type="chrome_html" />
diff --git a/ui/webui/resources/css/bubble_button.css b/ui/webui/resources/css/bubble_button.css index f12fc6e2..5ab9ce7a 100644 --- a/ui/webui/resources/css/bubble_button.css +++ b/ui/webui/resources/css/bubble_button.css
@@ -1,7 +1,6 @@ /* 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. - */ + * found in the LICENSE file. */ .bubble-button { -webkit-margin-start: 4px;
diff --git a/ui/webui/resources/css/butter_bar.css b/ui/webui/resources/css/butter_bar.css index 84ad941..17a6f57 100644 --- a/ui/webui/resources/css/butter_bar.css +++ b/ui/webui/resources/css/butter_bar.css
@@ -1,8 +1,6 @@ -/* - * Copyright (c) 2012 The Chromium Authors. All rights reserved. +/* 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. - */ + * found in the LICENSE file. */ /* A butter bar is an non-modal notification, usually yellow, that appears at * the top of the screen. Generally, they should contain a single line of text,
diff --git a/ui/webui/resources/css/chrome_shared.css b/ui/webui/resources/css/chrome_shared.css index 1cbafdd..25d595b 100644 --- a/ui/webui/resources/css/chrome_shared.css +++ b/ui/webui/resources/css/chrome_shared.css
@@ -69,8 +69,7 @@ } /* Elements that need to be LTR even in an RTL context, but should align - * right. (Namely, URLs, search engine names, etc.) - */ + * right. (Namely, URLs, search engine names, etc.) */ html[dir='rtl'] .weakrtl { direction: ltr; text-align: right; @@ -78,8 +77,7 @@ /* Input fields in search engine table need to be weak-rtl. Since those input * fields are generated for all cr.ListItem elements (and we only want weakrtl - * on some), the class needs to be on the enclosing div. - */ + * on some), the class needs to be on the enclosing div. */ html[dir='rtl'] div.weakrtl input { direction: ltr; text-align: right; @@ -92,8 +90,7 @@ /* weakrtl for selection drop downs needs to account for the fact that * Webkit does not honor the text-align attribute for the select element. - * (See Webkit bug #40216) - */ + * (See Webkit bug #40216) */ html[dir='rtl'] select.weakrtl { direction: rtl; } @@ -104,8 +101,7 @@ /* WebKit does not honor alignment for text specified via placeholder attribute. * This CSS is a workaround. Please remove once WebKit bug is fixed. - * https://bugs.webkit.org/show_bug.cgi?id=63367 - */ + * https://bugs.webkit.org/show_bug.cgi?id=63367 */ html[dir='rtl'] input.weakrtl::-webkit-input-placeholder, html[dir='rtl'] .weakrtl input::-webkit-input-placeholder { direction: rtl;
diff --git a/ui/webui/resources/css/chromeos/ui_account_tweaks.css b/ui/webui/resources/css/chromeos/ui_account_tweaks.css index bfe3228..91ae069 100644 --- a/ui/webui/resources/css/chromeos/ui_account_tweaks.css +++ b/ui/webui/resources/css/chromeos/ui_account_tweaks.css
@@ -1,11 +1,9 @@ /* 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. - */ + * found in the LICENSE file. */ /* This file defines styles for internal page elements that have special - * look and feel based on account status (owner/non-owner/guest). - */ + * look and feel based on account status (owner/non-owner/guest). */ .guest-disabled { color: #999;
diff --git a/ui/webui/resources/css/tabs.css b/ui/webui/resources/css/tabs.css index 1b0ffeb73..1a8e975 100644 --- a/ui/webui/resources/css/tabs.css +++ b/ui/webui/resources/css/tabs.css
@@ -19,8 +19,7 @@ * 'tabs' or 'tabpanels' elements. * * TODO(rfevang): Remove when all users are converted to the new style. - * (crbug.com/247772). - */ + * (crbug.com/247772). */ tabs.new-style-tabs { -webkit-padding-start: 9px; background: #fbfbfb;
diff --git a/ui/webui/resources/css/tree.css b/ui/webui/resources/css/tree.css index a86baba5..103f1aa 100644 --- a/ui/webui/resources/css/tree.css +++ b/ui/webui/resources/css/tree.css
@@ -63,13 +63,8 @@ z-index: 1; } -/* - WebKit has a bug with attribute selectors so we apply selected to the tree row - as well. - - https://bugs.webkit.org/show_bug.cgi?id=12519 - -*/ +/* WebKit has a bug with attribute selectors so we apply selected to the tree + * row as well. https://bugs.webkit.org/show_bug.cgi?id=12519. */ .tree-row[selected] { background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.8), rgba(255,255,255,0));
diff --git a/ui/webui/resources/js/cr/ui/tree.js b/ui/webui/resources/js/cr/ui/tree.js index 888fca6..1eed9e1 100644 --- a/ui/webui/resources/js/cr/ui/tree.js +++ b/ui/webui/resources/js/cr/ui/tree.js
@@ -57,6 +57,8 @@ this.addEventListener('mousedown', this.handleMouseDown); this.addEventListener('dblclick', this.handleDblClick); this.addEventListener('keydown', this.handleKeyDown); + + this.setAttribute('role', 'group'); }, /**
diff --git a/ui/wm/core/transient_window_manager.cc b/ui/wm/core/transient_window_manager.cc index 956d358..876a499 100644 --- a/ui/wm/core/transient_window_manager.cc +++ b/ui/wm/core/transient_window_manager.cc
@@ -219,7 +219,7 @@ // parent, as destroying an active transient child may otherwise attempt to // refocus us. Windows transient_children(transient_children_); - STLDeleteElements(&transient_children); + base::STLDeleteElements(&transient_children); DCHECK(transient_children_.empty()); }
diff --git a/ui/wm/core/window_animations.cc b/ui/wm/core/window_animations.cc index 0c05dbf..3fd5977 100644 --- a/ui/wm/core/window_animations.cc +++ b/ui/wm/core/window_animations.cc
@@ -95,7 +95,7 @@ DCHECK(iter != window_->parent()->children().end()); aura::Window* topmost_transient_child = NULL; for (++iter; iter != window_->parent()->children().end(); ++iter) { - if (ContainsValue(transient_children, *iter)) + if (base::ContainsValue(transient_children, *iter)) topmost_transient_child = *iter; } if (topmost_transient_child) {